[CLAMP-1] Initial ONAP CLAMP seed code commit 45/5145/2
authorChrisC <cc697w@intl.att.com>
Wed, 21 Jun 2017 09:38:57 +0000 (02:38 -0700)
committerChrisC <cc697w@intl.att.com>
Wed, 21 Jun 2017 09:58:20 +0000 (02:58 -0700)
Change-Id: I2e8070a590618a06070f393d7b2c011029af5e8a
Signed-off-by: ChrisC <cc697w@intl.att.com>
522 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
LICENSE.txt [new file with mode: 0644]
README.md [new file with mode: 0644]
extra/docker/clamp/clamp.env [new file with mode: 0644]
extra/docker/clamp/docker-compose.yml [new file with mode: 0644]
extra/docker/mariadb/conf1/my.cnf [new file with mode: 0644]
extra/docker/mariadb/conf2/my.cnf [new file with mode: 0644]
extra/docker/mariadb/conf3/my.cnf [new file with mode: 0644]
extra/sql/bulkload/clds-create-db-objects.sql [new file with mode: 0644]
extra/sql/bulkload/clds-stored-procedures.sql [new file with mode: 0644]
extra/sql/drop/clds-drop-db-objects.sql [new file with mode: 0644]
extra/sql/load-sql-files-tests-automation.sh [new file with mode: 0755]
pom.xml [new file with mode: 0644]
src/licenses/clamp_apache_v2/header.txt [new file with mode: 0644]
src/licenses/clamp_apache_v2/license.txt [new file with mode: 0644]
src/licenses/licenses.properties [new file with mode: 0644]
src/main/docker/Dockerfile [new file with mode: 0644]
src/main/docker/startService.sh [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/Application.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/Routes.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/WebConfig.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/CldsEventDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/DcaeReqDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/DcaeReqDeleteDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/OperationalPolicyDeleteDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/PolicyClient.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/SdcCatalogServices.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/SdcSendReqDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDeleteDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/TcaPolicyDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/TcaPolicyDeleteDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/DcaeReq.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/JsonUtil.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/OperationalPolicyReq.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/SdcReq.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/StringMatchPolicyReq.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/client/req/TcaMPolicyReq.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/common/LogMessages.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/config/CamundaAuthFilterInitializer.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/config/CamundaEngineConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/config/CldsConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/config/CldsSecurityConfig.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/config/CsiLoggingConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/dao/CldsDao.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/exception/AjscExceptionMapper.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/jsf/JsfExampleBean.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAlarmCondition.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAsdcArtifact.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAsdcResource.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAsdcResourceBasicInfo.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceDetail.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceInfo.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsDBServiceCache.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsEvent.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsModel.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsModelInstance.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsServiceData.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsTemplate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsVfData.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/CldsVfcData.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/DcaeEvent.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/HelloWorld.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/ValueItem.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/Collector.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/Global.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/ModelBpmn.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/ModelBpmnEntry.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/ModelElement.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/ModelProperties.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/Policy.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/PolicyItem.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/ServiceConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/StringMatch.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/Tca.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/TcaItem.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/prop/TcaThreshhold.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/model/refprop/RefProp.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/CldsService.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/CldsTemplateService.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/LogService.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/LogServiceImpl.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/SecureServiceBase.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/SecureServicePermission.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogService.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogServiceImpl.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/transform/TransformUtil.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/transform/XslTransformer.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/workflow/LogMessageDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/workflow/ProcessRequestDelegate.java [new file with mode: 0644]
src/main/java/org/onap/clamp/clds/workflow/RestMessageDelegate.java [new file with mode: 0644]
src/main/resources/META-INF/processes.xml [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/WEB-INF/web.xml [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/authenticate.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/AdminLTE.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/angucomplete.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/app.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap-theme.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap.css.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/bootstrap_custom.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/ajax-loader.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/grabbing.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/owl.carousel.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/owl.theme.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/slick.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/carousel/slick.css.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/dataTables.bootstrap.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/dataTables.fixedColumns.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/dataTables.tableTools.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/diagram-js.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/dialogs.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.pack.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/bg.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/btn-sprite.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/ddn.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/dn.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/fhbg.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/first.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/hl.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/last.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/line.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/magnifier.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/next.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/prev.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/up.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/uup.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/wbg.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/flexigrid/css/style.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/font-awesome.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/icons.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/images/sprite.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/jquery.dataTables.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/jquery.dataTables_themeroller.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/kendo.common-material.core.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/kendo.material.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/loading-bar.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/metisMenu.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/multi-select.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/navmenu.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/normalize.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/dataTables.bootstrap.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/morris.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/social-buttons.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/plugins/timeline.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/simple-sidebar.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/style-gue.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/styles.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/stylesheet.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/table_custom.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/table_theme_1.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-stable.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-stable.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/ui-grid.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/css/utm_custom_style.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/FontAwesome.otf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/FontAwesome.otf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/bordered-pulled.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/core.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/fixed-width.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/font-awesome.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/icons.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/larger.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/list.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/mixins.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/path.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/rotated-flipped.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/spinning.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/stacked.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/variables.less [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_bordered-pulled.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_core.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_fixed-width.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_icons.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_larger.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_list.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_mixins.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_path.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_rotated-flipped.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_spinning.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_stacked.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_variables.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/font-awesome.scss [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/CheckMark.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/DefineDecision.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/DefineModifySchema.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/DefinePID.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/DefinePath.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/DefineServiceAcronym.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/GOC.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/ImportSchema.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/InitialProcess.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/MultiBranchConnector.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/ParentNode.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/ProcessCall.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/SetDefaultValues.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/TrueFalseCondition.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/UpgradeSchema.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/clds-collector-icon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/clds-policy-icon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/clds-prop-icon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/clds-string-match-icon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/clds-tca-icon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/favicon.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/img_ie.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/img_mozila.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/itrack.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/logo_onap_2017.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/page_under_construction.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/preffered.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/sort_asc.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/sort_asc_disabled.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/sort_both.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/sort_desc.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/sort_desc_disabled.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/images/th.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/index.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angucomplete.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-animate.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-cookies.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-highlightjs.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-route.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-sanitize.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-touch.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angular.min.js.map [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-new.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-old.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/bootstrap.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dataTables.bootstrap.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dataTables.fixedColumns.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dataTables.searchHighlight.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dataTables.tableTools.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dialogs-controllers.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dialogs-default-translations.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dialogs-main.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dialogs-services.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/dialogs.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/excanvas.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/excanvas.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.pack.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/index.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/external/jquery/jquery.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_0_aaaaaa_40x100.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_75_ffffff_40x100.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_55_fbf9ee_1x400.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_65_ffffff_1x400.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_dadada_1x400.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_e6e6e6_1x400.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_95_fef1ec_1x400.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_highlight-soft_75_cccccc_1x100.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_222222_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_2e83ff_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_454545_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_888888_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_cd0a0a_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/external/jquery/jquery.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_444444_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_555555_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777620_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777777_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_cc0000_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_ffffff_256x240.png [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.min.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery.highlight.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/jquery.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/loading-bar.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/lodash.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/modal.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/moment.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/multiselect.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/owl.carousel.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/owl.carousel.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/excanvas.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/flot-data.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.pie.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.resize.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.tooltip.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris-data.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/plugins/morris/raphael.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/slick.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/translate-substitution.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-bootstrap-tpls.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/ui-grid.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/lib/xml2json.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/Gruntfile.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/README.md [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/dist/css/app.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/dist/css/diagram-js.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/dist/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/modeler/package.json [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/page_under_construction.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/default-include.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/grid.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/invalid_login.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/menu.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/ng-grid.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/please_wait.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/Collector_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/ConfirmRevertChanges.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/Template_model.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_model_off_Template.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_template.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/clds_modelling.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_model.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_template.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/confirmation_window.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/dashboard.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/global_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/global_template_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/refresh_asdc.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/running_instances.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/save_confirmation.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/stringMatch_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/tca_properties.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/partials/portfolios/text_area_modal.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/ActivityModellingCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/AlertService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/AutosaveProjectCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/CldsOpenModelCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/CldsOpenTemplateCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/CldsTemplateService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/DashboardCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/ExportFileCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/ExportFileService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/FileUploadCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/FileUploadService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/GlobalPropertiesCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/ImportSchemaCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/SetDefaultValueCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/UpgradeSchemaCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/aOnBoot.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/app.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/authcontroller.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/commonService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/common_variables.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/dataFactory.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/importSchemaService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/kendo.custom.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/propertyExplorerCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/query_params_handler_ctrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/route_ctrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/saveConfirmationModalPopUpCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/soapRequestService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/textAreaCtrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/under_construction_ctrl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/scripts/userPreferencesService.js [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/unsupportedbrowser.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/utmdashboard.html [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn-embedded.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn.css [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.eot [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.svg [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.woff [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/css/print.css [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/css/reset.css [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/css/screen.css [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/css/style.css [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/css/typography.css [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/fonts/DroidSans-Bold.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/fonts/DroidSans.ttf [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/collapse.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/expand.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/explorer_icons.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/favicon-16x16.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/favicon-32x32.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/favicon.ico [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/logo_small.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/pet_store_api.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/throbber.gif [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/images/wordnik_api.png [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/en.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/es.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/fr.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/geo.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/it.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/ja.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/pl.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/pt.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/ru.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/tr.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/translator.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lang/zh-cn.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/backbone-min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/handlebars-2.0.0.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack_extended.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/jquery-1.8.0.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/jquery.ba-bbq.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/jquery.slideto.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/jquery.wiggle.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/js-yaml.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/jsoneditor.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/lodash.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/marked.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/lib/swagger-oauth.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/o2c.html [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/swagger-ui.js [new file with mode: 0644]
src/main/resources/META-INF/resources/icd/swagger-ui.min.js [new file with mode: 0644]
src/main/resources/META-INF/resources/index.html [new file with mode: 0644]
src/main/resources/META-INF/resources/login.html [new file with mode: 0644]
src/main/resources/META-INF/securityFilterRules.json [new file with mode: 0644]
src/main/resources/application.properties [new file with mode: 0644]
src/main/resources/bootstrap.properties [new file with mode: 0644]
src/main/resources/bpmn/SampleTestProcessDelegate.bpmn [new file with mode: 0644]
src/main/resources/bpmn/TestHumanTask.bpmn [new file with mode: 0644]
src/main/resources/bpmn/TestHumanTask.png [new file with mode: 0644]
src/main/resources/bpmn/clds-process-action.bpmn [new file with mode: 0644]
src/main/resources/bpmn/dish.dmn [new file with mode: 0644]
src/main/resources/bpmn/log-message.bpmn [new file with mode: 0644]
src/main/resources/bpmn/log-message.png [new file with mode: 0644]
src/main/resources/clds/clds-policy-config.properties [new file with mode: 0644]
src/main/resources/clds/clds-reference.properties [new file with mode: 0644]
src/main/resources/clds/clds-users.properties [new file with mode: 0644]
src/main/resources/clds/globalClds.properties [new file with mode: 0644]
src/main/resources/logback.xml [new file with mode: 0644]
src/main/resources/logmessages.properties [new file with mode: 0644]
src/main/resources/system.properties [new file with mode: 0644]
src/main/resources/xsl/clds-bpmn-transformer.xsl [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/AbstractIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/client/req/SdcReqTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/AsdcIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/DcaeIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/PolicyClientIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/PropJsonBuilderIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/it/RefPropIT.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/model/CldsModelTest.java [new file with mode: 0644]
src/test/java/org/onap/clamp/clds/model/prop/ModelPropertiesTest.java [new file with mode: 0644]
src/test/resources/clds/clds-policy-config.properties [new file with mode: 0644]
src/test/resources/clds/clds-reference.properties [new file with mode: 0644]
src/test/resources/example/modelBpmn.xml [new file with mode: 0644]
src/test/resources/example/modelBpmnProp.json [new file with mode: 0644]
src/test/resources/example/modelProp.json [new file with mode: 0644]
src/test/resources/example/templateProp.json [new file with mode: 0644]
src/test/resources/processes.xml [new file with mode: 0644]
version.properties [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..f70506a
--- /dev/null
@@ -0,0 +1,19 @@
+target
+.settings
+.classpath
+.project
+.buildpath
+.idea
+*.iml
+**/logs/
+**/.evosuite/
+**/debug-logs/
+*.log
+*.tmp
+
+# emacs working files
+.\#*
+\#*\#
+*~
+auto-save-list
+tramp
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..de1803c
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.onap.org
+port=29418
+project=clamp.git
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..9ff3121
--- /dev/null
@@ -0,0 +1,19 @@
+============LICENSE_START==========================================
+===================================================================
+Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+===================================================================
+Licensed under the Apache License, Version 2.0 (the "License"); 
+you may not use this file except in compliance with the License. 
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, 
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+See the License for the specific language governing permissions and 
+limitations under the License.
+============LICENSE_END============================================
+===================================================================
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5aa5cc0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# Summary
+
+CLAMP is a platform for designing and managing control loops. It is used to design a closed loop, configure it with specific parameters for a particular network service, then deploying and undeploying it.  Once deployed, the user can also update the loop with new parameters during runtime, as well as suspending and restarting it.
+
+It interacts with other systems to deploy and execute the closed loop. For example, it pushes the control loop design to the SDC catalog, associating it with the VF resource.  It requests from DCAE the instantiation of microservices to manage the closed loop flow.  Further, it creates and updates multiple policies in the Policy Engine that define the closed loop flow.
+
+The ONAP CLAMP platform abstracts the details of these systems under the concept of a control loop model.  The design of a control loop and its management is represented by a workflow in which all relevant system interactions take place.  This is essential for a self-service model of creating and managing control loops, where no low-level user interaction with other components is required.
+
+At a higher level, CLAMP is about supporting and managing the broad operational life cycle of VNFs/VMs and ultimately ONAP components itself. It will offer the ability to design, test, deploy and update control loop automation - both closed and open. Automating these functions would represent a significant saving on operational costs compared to traditional methods.
+
+# Developer Contact
+Owner: ONAP CLAMP Dev team
+Mailing List : onap-discuss@lists.onap.org
+Add the following prefix to Subject on the mailing list : [CLAMP]
+See here to subscribe : https://wiki.onap.org/display/DW/Mailing+Lists
+
+# Wiki
+https://wiki.onap.org/display/DW/CLAMP+Project
+
+# Build
+Jenkins Job: ${jenkins-joblink}
+
+CLAMP UI: ${cockpit-link}
+
+Logs: ${elk-link}
+
+# Docker image
+
+## Building 
+You can use the following command to build the clamp docker image:
+```
+mvn clean install -P docker
+```
+
+## Deployement
+Currently, the clamp docker image can be deployed with small configuration needs. Though, you might need to make small adjustments to the configuration. As clamp is spring based, you can use the SPRING_APPLICATION_JSON environment variable to update its parameters. 
+
+### Databases
+There are two needed datasource for Clamp. By default, both will try to connect to the localhost server using the credentials available in the example SQL files. If you need to change the default database host and/or credentials, you can do it by using the following json as SPRING_APPLICATION_JSON environment variable :
+```json
+{"spring": 
+    {
+     "datasource": {"url":"jdbc:mysql://anotherDB.onap.org:3306/camunda?autoReconnect=true", "username": "admin", "password": "admin"}, 
+     "cldsdatasource": {"url":"jdbc:mysql://anotherDB.onap.org:3306/clds?autoReconnect=true", "username": "admin", "password": "admin"}
+    }
+}
+
+```
+
+### Docker-compose
+
+A [docker-compose example file](extra/docker/clamp/docker-compose.yml) can be found under the [extra/docker/clamp/ folder](extra/docker/).
+
+Once the image has been built and is available locally, you can use the `docker-compose up` command to deploy a prepopullated database and a clamp instance available on [http://localhost:8080/designer/index.html](http://localhost:8080/designer/index.html).
+
+
+### Logs
+
+Clamp uses logback framework to generate logs. The logback.xml file cand be found under the [src/main/resources/ folder](src/main/resources). 
+
+With the default log settings, all logs will be generated into console and into root.log file under the Clamp root folder. The root.log file is not allowed to be appended, thus restarting the clamp will result in cleaning of the old log files.
diff --git a/extra/docker/clamp/clamp.env b/extra/docker/clamp/clamp.env
new file mode 100644 (file)
index 0000000..c38d29b
--- /dev/null
@@ -0,0 +1 @@
+SPRING_APPLICATION_JSON={"spring": {"datasource": {"url":"jdbc:mysql://db:3306/camundabpm?autoReconnect=true"}, "cldsdatasource": {"url":"jdbc:mysql://db:3306/cldsdb4?autoReconnect=true"}}}
diff --git a/extra/docker/clamp/docker-compose.yml b/extra/docker/clamp/docker-compose.yml
new file mode 100644 (file)
index 0000000..a4a935a
--- /dev/null
@@ -0,0 +1,22 @@
+version: '2'
+
+services:
+  db:
+    image: mariadb:10.1.11
+    volumes:
+      - "/var/lib/mysql"
+      - "../mariadb/conf1:/etc/mysql/conf.d:ro"
+      - "../../sql/:/docker-entrypoint-initdb.d:ro"
+    environment:
+      - MYSQL_ROOT_PASSWORD=strong_pitchou
+    ports:
+      - "3306:3306"
+
+  clamp:
+    image: onap/clamp
+    depends_on:
+      - db
+    env_file:
+      - clamp.env
+    ports:
+      - "8080:8080"
diff --git a/extra/docker/mariadb/conf1/my.cnf b/extra/docker/mariadb/conf1/my.cnf
new file mode 100644 (file)
index 0000000..0be1bd7
--- /dev/null
@@ -0,0 +1,194 @@
+# Example MySQL config file for medium systems.
+#
+# This is for a system with memory 8G where MySQL plays
+# an important part, or systems up to 128M where MySQL is used together with
+# other programs (such as a web server)
+#
+# In this file, you can use all long options that a program supports.
+# If you want to know which options a program supports, run the program
+# with the "--help" option.
+
+# The following options will be passed to all MySQL clients
+##[client]
+##user            = root
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+
+# Here follows entries for some specific programs
+
+# The MySQL server
+[mysqld]
+##performance_schema
+
+slow_query_log =ON
+long_query_time =2
+slow_query_log_file =//var/lib/mysql/slow_query.log
+##basedir         = //opt/app/mysql/product/mariadb-10.1.11-linux-x86_64
+##datadir         = //opt/app/mysql/data
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+skip-external-locking
+explicit_defaults_for_timestamp = true
+skip-symbolic-links
+local-infile = 0
+#ignore_db_dir=lost+found
+key_buffer_size = 16M
+max_allowed_packet = 4M
+table_open_cache = 100
+sort_buffer_size = 512K
+net_buffer_length = 8K
+read_buffer_size = 256K
+read_rnd_buffer_size = 512K
+myisam_sort_buffer_size = 8M
+max_connections = 500
+lower_case_table_names = 1
+thread_stack = 256K
+thread_cache_size = 25
+query_cache_size = 8M
+query_cache_type = 0
+query_prealloc_size = 512K
+query_cache_limit = 1M
+
+# Password validation
+##plugin-load-add=simple_password_check.so
+##simple_password_check_other_characters=0
+
+# Audit Log settings
+plugin-load-add=server_audit.so
+server_audit=FORCE_PLUS_PERMANENT
+server_audit_file_path=//var/lib/mysql/audit.log
+server_audit_file_rotate_size=50M
+server_audit_events=CONNECT,QUERY,TABLE
+server_audit_logging=on
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
+##log-bin=//var/lib/mysql/mysql-bin
+
+# binary logging format - mixed recommended
+binlog_format=row
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
+
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+#    the syntax is:
+#
+#    CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+#    MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+#    where you replace <host>, <user>, <password> by quoted strings and
+#    <port> by the master's port number (3306 by default).
+#
+#    Example:
+#
+#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+#    MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+#    start replication for the first time (even unsuccessfully, for example
+#    if you mistyped the password in master-password and the slave fails to
+#    connect), the slave will create a master.info file, and any later
+#    change in this file to the variables' values below will be ignored and
+#    overridden by the content of the master.info file, unless you shutdown
+#    the slave server, delete master.info and restart the slaver server.
+#    For that reason, you may want to leave the lines below untouched
+#    (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id       = 2
+#
+# The replication master for this slave - required
+#master-host     =   <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user     =   <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password =   <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port     =  <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin=mysql-bin
+
+# Uncomment the following if you are using InnoDB tables
+##innodb_data_home_dir = //opt/app/mysql/data
+##innodb_data_file_path = ibdata1:20M:autoextend:max:32G
+##innodb_log_group_home_dir = //opt/app/mysql/iblogs
+# You can set .._buffer_pool_size up to 50 - 80 %
+# of RAM but beware of setting memory usage too high
+innodb_buffer_pool_size = 6380M
+#innodb_additional_mem_pool_size = 2M
+# Set .._log_file_size to 25 % of buffer pool size
+innodb_log_file_size = 150M
+innodb_log_files_in_group = 3
+innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+innodb_lock_wait_timeout = 50
+innodb_autoextend_increment = 100
+expire_logs_days = 8
+open_files_limit = 2000
+transaction-isolation=READ-COMMITTED
+####### Galera parameters #######
+## Galera Provider configuration
+wsrep_provider=/usr/lib/galera/libgalera_smm.so
+wsrep_provider_options="gcache.size=2G; gcache.page_size=1G"
+## Galera Cluster configuration
+wsrep_cluster_name="MSO-automated-tests-cluster"
+wsrep_cluster_address="gcomm://"
+#wsrep_cluster_address="gcomm://mariadb1,mariadb2,mariadb3"
+##wsrep_cluster_address="gcomm://192.169.3.184,192.169.3.185,192.169.3.186"
+## Galera Synchronization configuration
+wsrep_sst_method=rsync
+#wsrep_sst_method=xtrabackup-v2
+#wsrep_sst_auth="sstuser:Mon#2o!6"
+## Galera Node configuration
+wsrep_node_name="mariadb1"
+##wsrep_node_address="192.169.3.184"
+wsrep_on=ON
+## Status notification
+#wsrep_notify_cmd=/opt/app/mysql/bin/wsrep_notify
+#######
+
+
+[mysqldump]
+quick
+max_allowed_packet = 16M
+
+[mysql]
+no-auto-rehash
+# Remove the next comment character if you are not familiar with SQL
+#safe-updates
+
+[myisamchk]
+key_buffer_size = 20971520
+
+##[mysqlhotcopy]
+##interactive-timeout
+##[mysqld_safe]
+##malloc-lib=//opt/app/mysql/local/lib/libjemalloc.so.1
+##log-error=//opt/app/mysql/log/mysqld.log
\ No newline at end of file
diff --git a/extra/docker/mariadb/conf2/my.cnf b/extra/docker/mariadb/conf2/my.cnf
new file mode 100644 (file)
index 0000000..bf5f9c1
--- /dev/null
@@ -0,0 +1,193 @@
+# Example MySQL config file for medium systems.
+#
+# This is for a system with memory 8G where MySQL plays
+# an important part, or systems up to 128M where MySQL is used together with
+# other programs (such as a web server)
+#
+# In this file, you can use all long options that a program supports.
+# If you want to know which options a program supports, run the program
+# with the "--help" option.
+
+# The following options will be passed to all MySQL clients
+##[client]
+##user            = root
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+
+# Here follows entries for some specific programs
+
+# The MySQL server
+[mysqld]
+##performance_schema
+
+slow_query_log =ON
+long_query_time =2
+slow_query_log_file =//var/lib/mysql/slow_query.log
+##basedir         = //opt/app/mysql/product/mariadb-10.1.11-linux-x86_64
+##datadir         = //opt/app/mysql/data
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+skip-external-locking
+explicit_defaults_for_timestamp = true
+skip-symbolic-links
+local-infile = 0
+#ignore_db_dir=lost+found
+key_buffer_size = 16M
+max_allowed_packet = 4M
+table_open_cache = 100
+sort_buffer_size = 512K
+net_buffer_length = 8K
+read_buffer_size = 256K
+read_rnd_buffer_size = 512K
+myisam_sort_buffer_size = 8M
+max_connections = 500
+lower_case_table_names = 1
+thread_stack = 256K
+thread_cache_size = 25
+query_cache_size = 8M
+query_cache_type = 0
+query_prealloc_size = 512K
+query_cache_limit = 1M
+
+# Password validation
+##plugin-load-add=simple_password_check.so
+##simple_password_check_other_characters=0
+
+# Audit Log settings
+plugin-load-add=server_audit.so
+server_audit=FORCE_PLUS_PERMANENT
+server_audit_file_path=//var/lib/mysql/audit.log
+server_audit_file_rotate_size=50M
+server_audit_events=CONNECT,QUERY,TABLE
+server_audit_logging=on
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
+##log-bin=//var/lib/mysql/mysql-bin
+
+# binary logging format - mixed recommended
+binlog_format=row
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
+
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+#    the syntax is:
+#
+#    CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+#    MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+#    where you replace <host>, <user>, <password> by quoted strings and
+#    <port> by the master's port number (3306 by default).
+#
+#    Example:
+#
+#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+#    MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+#    start replication for the first time (even unsuccessfully, for example
+#    if you mistyped the password in master-password and the slave fails to
+#    connect), the slave will create a master.info file, and any later
+#    change in this file to the variables' values below will be ignored and
+#    overridden by the content of the master.info file, unless you shutdown
+#    the slave server, delete master.info and restart the slaver server.
+#    For that reason, you may want to leave the lines below untouched
+#    (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id       = 2
+#
+# The replication master for this slave - required
+#master-host     =   <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user     =   <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password =   <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port     =  <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin=mysql-bin
+
+# Uncomment the following if you are using InnoDB tables
+##innodb_data_home_dir = //opt/app/mysql/data
+##innodb_data_file_path = ibdata1:20M:autoextend:max:32G
+##innodb_log_group_home_dir = //opt/app/mysql/iblogs
+# You can set .._buffer_pool_size up to 50 - 80 %
+# of RAM but beware of setting memory usage too high
+innodb_buffer_pool_size = 6380M
+#innodb_additional_mem_pool_size = 2M
+# Set .._log_file_size to 25 % of buffer pool size
+innodb_log_file_size = 150M
+innodb_log_files_in_group = 3
+innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+innodb_lock_wait_timeout = 50
+innodb_autoextend_increment = 100
+expire_logs_days = 8
+open_files_limit = 2000
+transaction-isolation=READ-COMMITTED
+####### Galera parameters #######
+## Galera Provider configuration
+wsrep_provider=/usr/lib/galera/libgalera_smm.so
+wsrep_provider_options="gcache.size=2G; gcache.page_size=1G"
+## Galera Cluster configuration
+wsrep_cluster_name="MSO-automated-tests-cluster"
+wsrep_cluster_address="gcomm://mariadb1,mariadb2,mariadb3"
+##wsrep_cluster_address="gcomm://192.169.3.184,192.169.3.185,192.169.3.186"
+## Galera Synchronization configuration
+wsrep_sst_method=rsync
+#wsrep_sst_method=xtrabackup-v2
+#wsrep_sst_auth="sstuser:Mon#2o!6"
+## Galera Node configuration
+wsrep_node_name="mariadb2"
+##wsrep_node_address="192.169.3.184"
+wsrep_on=ON
+## Status notification
+#wsrep_notify_cmd=/opt/app/mysql/bin/wsrep_notify
+#######
+
+
+[mysqldump]
+quick
+max_allowed_packet = 16M
+
+[mysql]
+no-auto-rehash
+# Remove the next comment character if you are not familiar with SQL
+#safe-updates
+
+[myisamchk]
+key_buffer_size = 20971520
+
+##[mysqlhotcopy]
+##interactive-timeout
+##[mysqld_safe]
+##malloc-lib=//opt/app/mysql/local/lib/libjemalloc.so.1
+##log-error=//opt/app/mysql/log/mysqld.log
\ No newline at end of file
diff --git a/extra/docker/mariadb/conf3/my.cnf b/extra/docker/mariadb/conf3/my.cnf
new file mode 100644 (file)
index 0000000..74f7a31
--- /dev/null
@@ -0,0 +1,193 @@
+# Example MySQL config file for medium systems.
+#
+# This is for a system with memory 8G where MySQL plays
+# an important part, or systems up to 128M where MySQL is used together with
+# other programs (such as a web server)
+#
+# In this file, you can use all long options that a program supports.
+# If you want to know which options a program supports, run the program
+# with the "--help" option.
+
+# The following options will be passed to all MySQL clients
+##[client]
+##user            = root
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+
+# Here follows entries for some specific programs
+
+# The MySQL server
+[mysqld]
+##performance_schema
+
+slow_query_log =ON
+long_query_time =2
+slow_query_log_file =//var/lib/mysql/slow_query.log
+##basedir         = //opt/app/mysql/product/mariadb-10.1.11-linux-x86_64
+##datadir         = //opt/app/mysql/data
+##port            = 3306
+##socket          = //opt/app/mysql/mysql.sock
+skip-external-locking
+explicit_defaults_for_timestamp = true
+skip-symbolic-links
+local-infile = 0
+#ignore_db_dir=lost+found
+key_buffer_size = 16M
+max_allowed_packet = 4M
+table_open_cache = 100
+sort_buffer_size = 512K
+net_buffer_length = 8K
+read_buffer_size = 256K
+read_rnd_buffer_size = 512K
+myisam_sort_buffer_size = 8M
+max_connections = 500
+lower_case_table_names = 1
+thread_stack = 256K
+thread_cache_size = 25
+query_cache_size = 8M
+query_cache_type = 0
+query_prealloc_size = 512K
+query_cache_limit = 1M
+
+# Password validation
+##plugin-load-add=simple_password_check.so
+##simple_password_check_other_characters=0
+
+# Audit Log settings
+plugin-load-add=server_audit.so
+server_audit=FORCE_PLUS_PERMANENT
+server_audit_file_path=//var/lib/mysql/audit.log
+server_audit_file_rotate_size=50M
+server_audit_events=CONNECT,QUERY,TABLE
+server_audit_logging=on
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
+##log-bin=//var/lib/mysql/mysql-bin
+
+# binary logging format - mixed recommended
+binlog_format=row
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
+
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+#    the syntax is:
+#
+#    CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+#    MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+#    where you replace <host>, <user>, <password> by quoted strings and
+#    <port> by the master's port number (3306 by default).
+#
+#    Example:
+#
+#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+#    MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+#    start replication for the first time (even unsuccessfully, for example
+#    if you mistyped the password in master-password and the slave fails to
+#    connect), the slave will create a master.info file, and any later
+#    change in this file to the variables' values below will be ignored and
+#    overridden by the content of the master.info file, unless you shutdown
+#    the slave server, delete master.info and restart the slaver server.
+#    For that reason, you may want to leave the lines below untouched
+#    (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id       = 2
+#
+# The replication master for this slave - required
+#master-host     =   <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user     =   <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password =   <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port     =  <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin=mysql-bin
+
+# Uncomment the following if you are using InnoDB tables
+##innodb_data_home_dir = //opt/app/mysql/data
+##innodb_data_file_path = ibdata1:20M:autoextend:max:32G
+##innodb_log_group_home_dir = //opt/app/mysql/iblogs
+# You can set .._buffer_pool_size up to 50 - 80 %
+# of RAM but beware of setting memory usage too high
+innodb_buffer_pool_size = 6380M
+#innodb_additional_mem_pool_size = 2M
+# Set .._log_file_size to 25 % of buffer pool size
+innodb_log_file_size = 150M
+innodb_log_files_in_group = 3
+innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+innodb_lock_wait_timeout = 50
+innodb_autoextend_increment = 100
+expire_logs_days = 8
+open_files_limit = 2000
+transaction-isolation=READ-COMMITTED
+####### Galera parameters #######
+## Galera Provider configuration
+wsrep_provider=/usr/lib/galera/libgalera_smm.so
+wsrep_provider_options="gcache.size=2G; gcache.page_size=1G"
+## Galera Cluster configuration
+wsrep_cluster_name="MSO-automated-tests-cluster"
+wsrep_cluster_address="gcomm://mariadb1,mariadb2,mariadb3"
+##wsrep_cluster_address="gcomm://192.169.3.184,192.169.3.185,192.169.3.186"
+## Galera Synchronization configuration
+wsrep_sst_method=rsync
+#wsrep_sst_method=xtrabackup-v2
+#wsrep_sst_auth="sstuser:Mon#2o!6"
+## Galera Node configuration
+wsrep_node_name="mariadb3"
+##wsrep_node_address="192.169.3.184"
+wsrep_on=ON
+## Status notification
+#wsrep_notify_cmd=/opt/app/mysql/bin/wsrep_notify
+#######
+
+
+[mysqldump]
+quick
+max_allowed_packet = 16M
+
+[mysql]
+no-auto-rehash
+# Remove the next comment character if you are not familiar with SQL
+#safe-updates
+
+[myisamchk]
+key_buffer_size = 20971520
+
+##[mysqlhotcopy]
+##interactive-timeout
+##[mysqld_safe]
+##malloc-lib=//opt/app/mysql/local/lib/libjemalloc.so.1
+##log-error=//opt/app/mysql/log/mysqld.log
\ No newline at end of file
diff --git a/extra/sql/bulkload/clds-create-db-objects.sql b/extra/sql/bulkload/clds-create-db-objects.sql
new file mode 100644 (file)
index 0000000..5cbb7e0
--- /dev/null
@@ -0,0 +1,189 @@
+# 
+# Create CLDS database objects (tables, etc.)
+#
+#
+CREATE DATABASE `camundabpm`;
+USE `camundabpm`; 
+DROP USER 'camunda'; 
+CREATE USER 'camunda'; 
+GRANT ALL on camundabpm.* to 'camunda' identified by 'ndMSpw4CAM' with GRANT OPTION; 
+FLUSH PRIVILEGES; 
+
+CREATE DATABASE `cldsdb4`;
+USE `cldsdb4`; 
+DROP USER 'clds'; 
+CREATE USER 'clds'; 
+GRANT ALL on cldsdb4.* to 'clds' identified by 'sidnnd83K' with GRANT OPTION;
+GRANT SELECT on mysql.proc TO 'clds';
+FLUSH PRIVILEGES;
+
+
+CREATE TABLE template (
+  template_id VARCHAR(36) NOT NULL,
+  template_name VARCHAR(80) NOT NULL,
+  template_bpmn_id VARCHAR(36) NULL,
+  template_image_id VARCHAR(36) NULL,
+  template_doc_id VARCHAR(36) NULL,
+  PRIMARY KEY (template_id),
+  UNIQUE (template_name)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE template_bpmn (
+  template_bpmn_id VARCHAR(36) NOT NULL,
+  template_id VARCHAR(36) NOT NULL,
+  template_bpmn_text MEDIUMTEXT NOT NULL,
+  userid VARCHAR(8),
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (template_bpmn_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE template_image (
+  template_image_id VARCHAR(36) NOT NULL,
+  template_id VARCHAR(36) NOT NULL,
+  template_image_text MEDIUMTEXT NULL,
+  userid VARCHAR(8),
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (template_image_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE template_doc (
+  template_doc_id VARCHAR(36) NOT NULL,
+  template_id VARCHAR(36) NOT NULL,
+  template_doc_text MEDIUMTEXT NULL,
+  userid VARCHAR(8),
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (template_doc_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE model (
+  model_id VARCHAR(36) NOT NULL,
+  model_name VARCHAR(80) NOT NULL,
+  template_id VARCHAR(36) NULL,
+  model_prop_id VARCHAR(36) NULL,
+  model_blueprint_id VARCHAR(36) NULL,
+  event_id VARCHAR(36) NULL,
+  control_name_prefix VARCHAR(80) NULL,
+  control_name_uuid VARCHAR(36) NOT NULL,
+  PRIMARY KEY (model_id),
+  UNIQUE (model_name),
+  UNIQUE (control_name_uuid)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE model_properties (
+  model_prop_id VARCHAR(36) NOT NULL,
+  model_id VARCHAR(36) NOT NULL,
+  model_prop_text MEDIUMTEXT NULL,
+  userid VARCHAR(8),
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (model_prop_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE model_blueprint (
+  model_blueprint_id VARCHAR(36) NOT NULL,
+  model_id VARCHAR(36) NOT NULL,
+  model_blueprint_text MEDIUMTEXT NULL,
+  userid VARCHAR(8),
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (model_blueprint_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE model_instance (
+  model_instance_id VARCHAR(36) NOT NULL,
+  model_id VARCHAR(36) NOT NULL,
+  vm_name VARCHAR(250) NOT NULL,
+  location VARCHAR(250) NULL,
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (model_instance_id),
+  UNIQUE (model_id, vm_name)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE event (
+  event_id VARCHAR(36) NOT NULL,
+  model_id VARCHAR(36) NULL,
+  action_cd VARCHAR(80) NOT NULL,
+  action_state_cd VARCHAR(80) NULL,
+  prev_event_id VARCHAR(36) NULL,
+  process_instance_id VARCHAR(80) NULL,
+  userid VARCHAR(8) NULL,
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (event_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+CREATE TABLE clds_service_cache (
+  invariant_service_id VARCHAR(36) NOT NULL,
+  service_id VARCHAR(36) NULL,
+  timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  object_data MEDIUMBLOB NULL,
+  PRIMARY KEY (invariant_service_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;
+
+ALTER TABLE template
+    ADD CONSTRAINT template_bpmn_id_fkey01
+    FOREIGN KEY (template_bpmn_id)
+    REFERENCES template_bpmn (template_bpmn_id);
+
+ALTER TABLE template
+    ADD CONSTRAINT template_image_id_fkey01
+    FOREIGN KEY (template_image_id)
+    REFERENCES template_image (template_image_id);
+
+ALTER TABLE template
+    ADD CONSTRAINT template_doc_id_fkey01
+    FOREIGN KEY (template_doc_id)
+    REFERENCES template_doc (template_doc_id);
+       
+ALTER TABLE template_bpmn
+    ADD CONSTRAINT template_id_fkey02
+    FOREIGN KEY (template_id)
+    REFERENCES template (template_id);
+
+ALTER TABLE template_image
+    ADD CONSTRAINT template_id_fkey03
+    FOREIGN KEY (template_id)
+    REFERENCES template (template_id);
+
+ALTER TABLE template_doc
+    ADD CONSTRAINT template_id_fkey04
+    FOREIGN KEY (template_id)
+    REFERENCES template (template_id); 
+    
+ALTER TABLE model
+    ADD CONSTRAINT template_id_fkey01
+    FOREIGN KEY (template_id)
+    REFERENCES template (template_id);
+
+ALTER TABLE model
+    ADD CONSTRAINT model_prop_id_fkey01
+    FOREIGN KEY (model_prop_id)
+    REFERENCES model_properties (model_prop_id);
+
+ALTER TABLE model
+    ADD CONSTRAINT model_blueprint_id_fkey01
+    FOREIGN KEY (model_blueprint_id)
+    REFERENCES model_blueprint (model_blueprint_id);
+    
+ALTER TABLE model
+    ADD CONSTRAINT event_id_fkey01
+    FOREIGN KEY (event_id)
+    REFERENCES event (event_id);
+
+ALTER TABLE model_properties
+    ADD CONSTRAINT model_id_fkey01
+    FOREIGN KEY (model_id)
+    REFERENCES model (model_id);       
+
+ALTER TABLE model_blueprint
+    ADD CONSTRAINT model_id_fkey02
+    FOREIGN KEY (model_id)
+    REFERENCES model (model_id);       
+
+ALTER TABLE model_instance
+    ADD CONSTRAINT model_id_fkey04
+    FOREIGN KEY (model_id)
+    REFERENCES model (model_id);       
+    
+ALTER TABLE event
+    ADD CONSTRAINT model_id_fkey03
+    FOREIGN KEY (model_id)
+    REFERENCES model (model_id);       
+       
diff --git a/extra/sql/bulkload/clds-stored-procedures.sql b/extra/sql/bulkload/clds-stored-procedures.sql
new file mode 100644 (file)
index 0000000..41cc75e
--- /dev/null
@@ -0,0 +1,431 @@
+# 
+# CLDS stored procedures
+#
+#
+USE cldsdb4;
+
+DROP PROCEDURE IF EXISTS upd_event;
+DROP PROCEDURE IF EXISTS ins_event;
+DROP PROCEDURE IF EXISTS del_all_model_instances;
+DROP PROCEDURE IF EXISTS del_model_instance;
+DROP PROCEDURE IF EXISTS ins_model_instance;
+DROP PROCEDURE IF EXISTS set_model;
+DROP PROCEDURE IF EXISTS get_model;    
+DROP PROCEDURE IF EXISTS get_model_template;   
+DROP PROCEDURE IF EXISTS set_template;
+DROP PROCEDURE IF EXISTS get_template; 
+DELIMITER //
+CREATE PROCEDURE get_template
+  (IN v_template_name VARCHAR(80),
+   OUT v_template_id VARCHAR(36),
+   OUT v_template_bpmn_id VARCHAR(36),
+   OUT v_template_bpmn_userid VARCHAR(8),
+   OUT v_template_bpmn_text MEDIUMTEXT,
+   OUT v_template_image_id VARCHAR(36),
+   OUT v_template_image_userid VARCHAR(8),
+   OUT v_template_image_text MEDIUMTEXT,
+   OUT v_template_doc_id VARCHAR(36),
+   OUT v_template_doc_userid VARCHAR(8),
+   OUT v_template_doc_text MEDIUMTEXT)
+BEGIN
+  SELECT t.template_id,
+                tb.template_bpmn_id,
+                tb.userid,
+                tb.template_bpmn_text,
+                ti.template_image_id,
+                ti.userid,
+                ti.template_image_text,
+                td.template_doc_id,
+                td.userid,
+                td.template_doc_text
+    INTO v_template_id,
+         v_template_bpmn_id,
+         v_template_bpmn_userid,
+         v_template_bpmn_text,
+         v_template_image_id,
+         v_template_image_userid,
+         v_template_image_text,
+         v_template_doc_id,
+         v_template_doc_userid,
+         v_template_doc_text
+    FROM template t,
+         template_bpmn tb,
+                template_image ti,
+                template_doc td
+    WHERE t.template_bpmn_id = tb.template_bpmn_id
+         AND t.template_image_id = ti.template_image_id
+         AND t.template_doc_id = td.template_doc_id
+      AND t.template_name = v_template_name;
+END;
+CREATE PROCEDURE set_template
+  (IN v_template_name VARCHAR(80),
+   IN v_userid VARCHAR(8),
+   IN v_template_bpmn_text MEDIUMTEXT,
+   IN v_template_image_text MEDIUMTEXT,
+   IN v_template_doc_text MEDIUMTEXT,
+   OUT v_template_id VARCHAR(36),
+   OUT v_template_bpmn_id VARCHAR(36),
+   OUT v_template_bpmn_userid VARCHAR(8),
+   OUT v_template_image_id VARCHAR(36),
+   OUT v_template_image_userid VARCHAR(8),
+   OUT v_template_doc_id VARCHAR(36),
+   OUT v_template_doc_userid VARCHAR(8))
+BEGIN
+  DECLARE v_old_template_bpmn_text MEDIUMTEXT;
+  DECLARE v_old_template_image_text MEDIUMTEXT;
+  DECLARE v_old_template_doc_text MEDIUMTEXT;
+  SET v_template_id = NULL;
+  CALL get_template(
+    v_template_name,
+    v_template_id,
+    v_template_bpmn_id,
+    v_template_bpmn_userid,
+    v_old_template_bpmn_text,
+    v_template_image_id,
+    v_template_image_userid,
+    v_old_template_image_text,
+    v_template_doc_id,
+    v_template_doc_userid,
+    v_old_template_doc_text);
+  IF v_template_id IS NULL THEN
+    BEGIN
+         SET v_template_id = UUID();
+      INSERT INTO template
+           (template_id, template_name)
+           VALUES (v_template_id, v_template_name);
+       END;
+  END IF;
+  IF v_template_bpmn_id IS NULL OR v_template_bpmn_text <> v_old_template_bpmn_text THEN
+       SET v_template_bpmn_id = UUID();
+    INSERT INTO template_bpmn
+         (template_bpmn_id, template_id, template_bpmn_text, userid)
+         VALUES (v_template_bpmn_id, v_template_id, v_template_bpmn_text, v_userid);
+       SET v_template_bpmn_userid = v_userid;
+  END IF;
+  IF v_template_image_id IS NULL OR v_template_image_text <> v_old_template_image_text THEN
+       SET v_template_image_id = UUID();
+    INSERT INTO template_image
+         (template_image_id, template_id, template_image_text, userid)
+         VALUES (v_template_image_id, v_template_id, v_template_image_text, v_userid);
+       SET v_template_image_userid = v_userid;
+  END IF;
+  IF v_template_doc_id IS NULL OR v_template_doc_text <> v_old_template_doc_text THEN
+       SET v_template_doc_id = UUID();
+    INSERT INTO template_doc
+         (template_doc_id, template_id, template_doc_text, userid)
+         VALUES (v_template_doc_id, v_template_id, v_template_doc_text, v_userid);
+       SET v_template_doc_userid = v_userid;
+  END IF;
+  UPDATE template
+    SET template_bpmn_id = v_template_bpmn_id,
+           template_image_id = v_template_image_id,
+           template_doc_id = v_template_doc_id
+    WHERE template_id = v_template_id;
+END;
+CREATE PROCEDURE get_model
+  (IN v_model_name VARCHAR(80),
+   OUT v_control_name_prefix VARCHAR(80),
+   INOUT v_control_name_uuid VARCHAR(36),
+   OUT v_model_id VARCHAR(36),
+   OUT v_template_name VARCHAR(80),
+   OUT v_template_id VARCHAR(36),
+   OUT v_model_prop_id VARCHAR(36),
+   OUT v_model_prop_userid VARCHAR(8),
+   OUT v_model_prop_text MEDIUMTEXT,
+   OUT v_model_blueprint_id VARCHAR(36),
+   OUT v_model_blueprint_userid VARCHAR(8),
+   OUT v_model_blueprint_text MEDIUMTEXT,
+   OUT v_event_id VARCHAR(36),
+   OUT v_action_cd VARCHAR(80),
+   OUT v_action_state_cd VARCHAR(80),
+   OUT v_event_process_instance_id VARCHAR(80),
+   OUT v_event_userid VARCHAR(8))
+BEGIN
+  SELECT m.control_name_prefix,
+                m.control_name_uuid,
+                m.model_id,
+                t.template_name,
+                m.template_id,
+                mp.model_prop_id,
+                mp.userid,
+                mp.model_prop_text,
+                mb.model_blueprint_id,
+                mb.userid,
+                mb.model_blueprint_text,
+                e.event_id,
+                e.action_cd,
+                e.action_state_cd,
+                e.process_instance_id,
+                e.userid
+    INTO v_control_name_prefix,
+         v_control_name_uuid,
+                v_model_id,
+                v_template_name,
+         v_template_id,
+         v_model_prop_id,
+         v_model_prop_userid,
+         v_model_prop_text,
+         v_model_blueprint_id,
+         v_model_blueprint_userid,
+         v_model_blueprint_text,
+         v_event_id,
+         v_action_cd,
+                v_action_state_cd,
+         v_event_process_instance_id,
+         v_event_userid
+    FROM model m,
+                template t,
+                model_properties mp,
+                model_blueprint mb,
+                event e
+    WHERE m.template_id = t.template_id
+         AND m.model_prop_id = mp.model_prop_id
+         AND m.model_blueprint_id = mb.model_blueprint_id
+         AND m.event_id = e.event_id
+      AND (m.model_name = v_model_name
+      OR  m.control_name_uuid = v_control_name_uuid);
+    SELECT model_instance_id,
+           vm_name,
+           location,
+           timestamp
+    FROM model_instance
+    WHERE model_id = v_model_id
+    ORDER BY 2;
+END;
+CREATE PROCEDURE get_model_template
+  (IN v_model_name VARCHAR(80),
+   OUT v_control_name_prefix VARCHAR(80),
+   INOUT v_control_name_uuid VARCHAR(36),
+   OUT v_model_id VARCHAR(36),
+   OUT v_template_name VARCHAR(80),
+   OUT v_template_id VARCHAR(36),
+   OUT v_model_prop_id VARCHAR(36),
+   OUT v_model_prop_userid VARCHAR(8),
+   OUT v_model_prop_text MEDIUMTEXT,
+   OUT v_model_blueprint_id VARCHAR(36),
+   OUT v_model_blueprint_userid VARCHAR(8),
+   OUT v_model_blueprint_text MEDIUMTEXT,
+   OUT v_template_bpmn_id VARCHAR(36),
+   OUT v_template_bpmn_userid VARCHAR(8),
+   OUT v_template_bpmn_text MEDIUMTEXT,
+   OUT v_template_image_id VARCHAR(36),
+   OUT v_template_image_userid VARCHAR(8),
+   OUT v_template_image_text MEDIUMTEXT,
+   OUT v_template_doc_id VARCHAR(36),
+   OUT v_template_doc_userid VARCHAR(8),
+   OUT v_template_doc_text MEDIUMTEXT,
+   OUT v_event_id VARCHAR(36),
+   OUT v_action_cd VARCHAR(80),
+   OUT v_action_state_cd VARCHAR(80),
+   OUT v_event_process_instance_id VARCHAR(80),
+   OUT v_event_userid VARCHAR(8))
+BEGIN
+  CALL get_model(
+    v_model_name,
+    v_control_name_prefix,
+    v_control_name_uuid,
+    v_model_id,
+    v_template_name,
+    v_template_id,
+    v_model_prop_id,
+    v_model_prop_userid,
+    v_model_prop_text,
+    v_model_blueprint_id,
+    v_model_blueprint_userid,
+    v_model_blueprint_text,
+       v_event_id,
+       v_action_cd,
+       v_action_state_cd,
+       v_event_process_instance_id,
+       v_event_userid);
+  CALL get_template(
+    v_template_name,
+    v_template_id,
+    v_template_bpmn_id,
+    v_template_bpmn_userid,
+    v_template_bpmn_text,
+    v_template_image_id,
+    v_template_image_userid,
+    v_template_image_text,
+    v_template_doc_id,
+    v_template_doc_userid,
+    v_template_doc_text);
+  END;
+CREATE PROCEDURE set_model
+  (IN v_model_name VARCHAR(80),
+   IN v_template_id VARCHAR(36),
+   IN v_userid VARCHAR(8),
+   IN v_model_prop_text MEDIUMTEXT,
+   IN v_model_blueprint_text MEDIUMTEXT,
+   INOUT v_control_name_prefix VARCHAR(80),
+   INOUT v_control_name_uuid VARCHAR(36),
+   OUT v_model_id VARCHAR(36),
+   OUT v_model_prop_id VARCHAR(36),
+   OUT v_model_prop_userid VARCHAR(8),
+   OUT v_model_blueprint_id VARCHAR(36),
+   OUT v_model_blueprint_userid VARCHAR(8),
+   OUT v_event_id VARCHAR(36),
+   OUT v_action_cd VARCHAR(80),
+   OUT v_action_state_cd VARCHAR(80),
+   OUT v_event_process_instance_id VARCHAR(80),
+   OUT v_event_userid VARCHAR(8))
+BEGIN
+  DECLARE v_old_template_name VARCHAR(80);
+  DECLARE v_old_template_id VARCHAR(36);
+  DECLARE v_old_control_name_prefix VARCHAR(80);
+  DECLARE v_old_control_name_uuid VARCHAR(36);
+  DECLARE v_old_model_prop_text MEDIUMTEXT;
+  DECLARE v_old_model_blueprint_text MEDIUMTEXT;
+  SET v_model_id = NULL;
+  CALL get_model(
+    v_model_name,
+    v_old_control_name_prefix,
+    v_old_control_name_uuid,
+    v_model_id,
+    v_old_template_name,
+    v_old_template_id,
+    v_model_prop_id,
+    v_model_prop_userid,
+    v_old_model_prop_text,
+    v_model_blueprint_id,
+    v_model_blueprint_userid,
+    v_old_model_blueprint_text,
+       v_event_id,
+       v_action_cd,
+       v_action_state_cd,
+       v_event_process_instance_id,
+       v_event_userid);
+  IF v_model_id IS NULL THEN
+    BEGIN
+      # UUID can be provided initially but cannot be updated
+         # if not provided (this is expected) then it will be set here
+      IF v_control_name_uuid IS NULL THEN
+           SET v_control_name_uuid = UUID();
+         END IF;
+      SET v_model_id = v_control_name_uuid;
+      INSERT INTO model
+           (model_id, model_name, template_id, control_name_prefix, control_name_uuid)
+           VALUES (v_model_id, v_model_name, v_template_id, v_control_name_prefix, v_control_name_uuid);
+         # since just created model, insert CREATED event as initial default event
+         SET v_action_cd = 'CREATE';
+         SET v_action_state_cd = 'COMPLETED';
+         SET v_event_userid = v_userid;
+      SET v_event_id = UUID();
+      INSERT INTO event
+           (event_id, model_id, action_cd, action_state_cd, userid)
+           VALUES (v_event_id, v_model_id, v_action_cd, v_action_state_cd, v_event_userid);
+         UPDATE model
+               SET event_id = v_event_id
+               WHERE model_id = v_model_id;
+       END;
+  ELSE
+    BEGIN
+         # use old control_name_prefix if null value is provided
+      IF v_control_name_prefix IS NULL THEN
+            SET v_control_name_prefix = v_old_control_name_prefix;
+         END IF;
+         # UUID can not be updated after initial insert
+         SET v_control_name_uuid = v_old_control_name_uuid;
+       END;
+  END IF;
+  IF v_model_prop_id IS NULL OR v_model_prop_text <> v_old_model_prop_text THEN
+       SET v_model_prop_id = UUID();
+    INSERT INTO model_properties
+         (model_prop_id, model_id, model_prop_text, userid)
+         VALUES (v_model_prop_id, v_model_id, v_model_prop_text, v_userid);
+       SET v_model_prop_userid = v_userid;
+  END IF;
+  IF v_model_blueprint_id IS NULL OR v_model_blueprint_text <> v_old_model_blueprint_text THEN
+       SET v_model_blueprint_id = UUID();
+    INSERT INTO model_blueprint
+         (model_blueprint_id, model_id, model_blueprint_text, userid)
+         VALUES (v_model_blueprint_id, v_model_id, v_model_blueprint_text, v_userid);
+       SET v_model_blueprint_userid = v_userid;
+  END IF;
+  UPDATE model
+    SET control_name_prefix = v_control_name_prefix,
+           model_prop_id = v_model_prop_id,
+           model_blueprint_id = v_model_blueprint_id
+    WHERE model_id = v_model_id;
+END;
+CREATE PROCEDURE ins_model_instance
+  (IN v_control_name_uuid VARCHAR(36),
+   IN v_vm_name VARCHAR(250),
+   IN v_location VARCHAR(250),
+   OUT v_model_id VARCHAR(36),
+   OUT v_model_instance_id VARCHAR(36))
+BEGIN
+   SELECT m.model_id
+    INTO v_model_id
+    FROM model m
+    WHERE m.control_name_uuid = v_control_name_uuid;
+  SET v_model_instance_id = UUID();
+  INSERT INTO model_instance
+       (model_instance_id, model_id, vm_name, location)
+       VALUES (v_model_instance_id, v_model_id, v_vm_name, v_location);
+END;
+CREATE PROCEDURE del_model_instance
+  (IN v_control_name_uuid VARCHAR(36),
+   IN v_vm_name VARCHAR(250),
+   OUT v_model_id VARCHAR(36),
+   OUT v_model_instance_id VARCHAR(36))
+BEGIN
+   SELECT m.model_id, i.model_instance_id
+    INTO v_model_id,
+         v_model_instance_id
+    FROM model m,
+         model_instance i
+    WHERE m.model_id = i.model_id
+     AND  m.control_name_uuid = v_control_name_uuid
+     AND  i.vm_name = v_vm_name;
+  DELETE FROM model_instance
+  WHERE model_instance_id = v_model_instance_id;
+END;
+CREATE PROCEDURE del_all_model_instances
+  (IN v_control_name_uuid VARCHAR(36),
+   OUT v_model_id VARCHAR(36))
+BEGIN
+  SELECT m.model_id
+    INTO v_model_id
+    FROM model m
+    WHERE m.control_name_uuid = v_control_name_uuid;
+  DELETE FROM model_instance
+  WHERE model_id = v_model_id;
+END;
+CREATE PROCEDURE ins_event
+  (IN v_model_name VARCHAR(80),
+   IN v_control_name_prefix VARCHAR(80),
+   IN v_control_name_uuid VARCHAR(36),
+   IN v_userid VARCHAR(8),
+   IN v_action_cd VARCHAR(80),
+   IN v_action_state_cd VARCHAR(80),
+   IN v_process_instance_id VARCHAR(80),
+   OUT v_model_id VARCHAR(36),
+   OUT v_event_id VARCHAR(36))
+BEGIN
+  DECLARE v_prev_event_id VARCHAR(36);
+  SELECT m.model_id,
+                m.event_id
+    INTO v_model_id,
+         v_prev_event_id
+    FROM model m
+    WHERE m.model_name = v_model_name
+         OR  m.control_name_uuid = v_control_name_uuid;
+  SET v_event_id = UUID();
+  INSERT INTO event
+       (event_id, model_id, action_cd, action_state_cd, prev_event_id, process_instance_id, userid)
+       VALUES (v_event_id, v_model_id, v_action_cd, v_action_state_cd, v_prev_event_id, v_process_instance_id, v_userid);
+  UPDATE model
+       SET event_id = v_event_id
+       WHERE model_id = v_model_id;
+END;
+CREATE PROCEDURE upd_event
+  (IN v_event_id VARCHAR(36),
+   IN v_process_instance_id VARCHAR(80))
+BEGIN
+  UPDATE event
+       SET process_instance_id = v_process_instance_id
+       WHERE event_id = v_event_id;
+END
+//
+DELIMITER ;
diff --git a/extra/sql/drop/clds-drop-db-objects.sql b/extra/sql/drop/clds-drop-db-objects.sql
new file mode 100644 (file)
index 0000000..487aa49
--- /dev/null
@@ -0,0 +1,32 @@
+# 
+# Drop CLDS database objects (tables, etc.)
+#
+#
+
+
+ALTER TABLE template
+    DROP FOREIGN KEY template_image_id_fkey01;
+ALTER TABLE template
+    DROP FOREIGN KEY template_bpmn_id_fkey01;
+ALTER TABLE template
+    DROP FOREIGN KEY template_doc_id_fkey01;
+    
+ALTER TABLE model
+    DROP FOREIGN KEY template_id_fkey01;
+ALTER TABLE model
+    DROP FOREIGN KEY model_prop_id_fkey01;
+ALTER TABLE model
+    DROP FOREIGN KEY model_blueprint_id_fkey01;
+ALTER TABLE model
+    DROP FOREIGN KEY event_id_fkey01;
+
+DROP TABLE model_instance;
+DROP TABLE model_blueprint;
+DROP TABLE model_properties;
+DROP TABLE event;
+DROP TABLE model;
+
+DROP TABLE template_doc;
+DROP TABLE template_image;
+DROP TABLE template_bpmn;
+DROP TABLE template;
diff --git a/extra/sql/load-sql-files-tests-automation.sh b/extra/sql/load-sql-files-tests-automation.sh
new file mode 100755 (executable)
index 0000000..4924922
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+cd /docker-entrypoint-initdb.d/bulkload
+mysql -uroot -p$MYSQL_ROOT_PASSWORD -f < clds-create-db-objects.sql
+mysql -uroot -p$MYSQL_ROOT_PASSWORD -f < clds-stored-procedures.sql
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..ecd9937
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,879 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.onap.clamp</groupId>
+       <artifactId>clds</artifactId>
+       <version>0.0.1-SNAPSHOT</version>
+       <name>ONAP CLAMP</name>
+
+       <properties>
+               <maven.compiler.source>1.8</maven.compiler.source>
+               <maven.compiler.target>1.8</maven.compiler.target>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <docker.mariadb.port.host>3306</docker.mariadb.port.host>
+               <sdk.java.common.logging>0.0.3-oss</sdk.java.common.logging>
+               <project.scm.id>git-server</project.scm.id>
+               <swagger.directory>${basedir}/target/classes/META-INF/resources/icd</swagger.directory>
+               <icd.file>service.json</icd.file>
+               <icd.package>org.onap.clamp.clds.service.rs</icd.package>
+               <java.version>1.8</java.version>
+               <build.number>local</build.number>
+               <service.account>ajsc-svc-account</service.account>
+               <namespace>com.att.ajsc</namespace>
+               <jsf.version>2.2.11</jsf.version>
+               <csi.logging>6.1.0.6-oss</csi.logging>
+               <sdk.camel.rest>6.2.0.6-oss</sdk.camel.rest>
+               <sdk.camunda.core>6.1.0.3-oss</sdk.camunda.core>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+               <sonar.language>java</sonar.language>
+               <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+               <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports</sonar.surefire.reportsPath>
+               <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco.exec</sonar.jacoco.reportPath>
+               <sonar.jacoco.itReportPath>${project.build.directory}/coverage-reports/jacoco-it.exec</sonar.jacoco.itReportPath>
+               <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
+               <sonar.projectVersion>${project.version}</sonar.projectVersion>
+
+               <clamp.registry>localhost:5000</clamp.registry>
+               <skip.docker.build>true</skip.docker.build>
+               <skip.docker.tag>true</skip.docker.tag>
+               <skip.docker.push>true</skip.docker.push>
+               <skip.staging.artifacts>false</skip.staging.artifacts>
+
+               <nexusproxy>https://nexus.onap.org</nexusproxy>
+               <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+               <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
+               <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
+               <sitePath>/content/sites/site/org/onap/clamp/${project.version}</sitePath>
+       </properties>
+
+       <distributionManagement>
+               <repository>
+                       <id>ecomp-releases</id>
+                       <name>Clamp Release Repository</name>
+                       <url>${nexusproxy}/${releaseNexusPath}</url>
+               </repository>
+               <snapshotRepository>
+                       <id>ecomp-snapshots</id>
+                       <name>Clamp Snapshot Repository</name>
+                       <url>${nexusproxy}/${snapshotNexusPath}</url>
+               </snapshotRepository>
+               <site>
+                       <id>ecomp-site</id>
+                       <url>dav:${nexusproxy}${sitePath}</url>
+               </site>
+       </distributionManagement>
+
+       <repositories>
+               <repository>
+                       <id>central</id>
+                       <name>Maven 2 repository 2</name>
+                       <url>http://repo2.maven.org/maven2/</url>
+               </repository>
+               <repository>
+                       <id>JBOSS</id>
+                       <name>JBoss Repository</name>
+                       <url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
+               </repository>
+               <repository>
+                       <id>jboss-deprecated-repository</id>
+                       <name>JBoss Deprecated Maven Repository</name>
+                       <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>
+               </repository>
+               <repository>
+                       <id>ecomp-releases</id>
+                       <name>ONAP Release Repository</name>
+                       <url>${nexusproxy}/${releaseNexusPath}</url>
+               </repository>
+               <repository>
+                       <id>ecomp-staging</id>
+                       <name>ONAP Staging Repository</name>
+                       <url>${nexusproxy}/${stagingNexusPath}</url>
+               </repository>
+               <repository>
+                       <id>ecomp-snapshots</id>
+                       <name>ONAP Snapshot Repository</name>
+                       <url>${nexusproxy}/${snapshotNexusPath}</url>
+                       <snapshots><enabled>true</enabled></snapshots>
+                       <releases><enabled>false</enabled></releases>
+               </repository>
+               <repository>
+                       <id>spring-repo</id>
+                       <name>Spring repo</name>
+                       <url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
+               </repository>
+               <repository>
+                       <id>soapUI</id>
+                       <url>http://www.soapui.org/repository/maven2/</url>
+                       <name>SoapUI plugin</name>
+               </repository>
+       </repositories>
+
+       <description>
+              This project build the ONAP CLAMP JAR that contains AJSC + CLAMP code.
+
+           By Default "mvn clean install" command will execute also the unit tests
+           and the integration tests. The integration tests require a docker engine running.
+
+           If you want to skip the intergation test you can by doing:
+           "mvn clean install -DskipITs=true"
+
+           For Spring it's possible to specify the application.properties location
+           "mvn clean install -Dspring.config.location=classpath:application-test.properties"
+
+           The application.properties contains the location of the CLAMP parameters files:
+           clds-policy-config.properties and clds-reference.properties
+
+           The licenses and headers can be generated by using this maven command:
+           mvn license:update-file-header license:update-project-license
+    </description>
+
+       <dependencyManagement>
+               <dependencies>
+                       <dependency>
+                               <!-- Import dependency management from Spring Boot -->
+                               <groupId>org.springframework.boot</groupId>
+                               <artifactId>spring-boot-dependencies</artifactId>
+                               <version>1.4.1.RELEASE</version>
+                               <type>pom</type>
+                               <scope>import</scope>
+                       </dependency>
+               </dependencies>
+       </dependencyManagement>
+
+       <dependencies>
+           <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-vfs2</artifactId>
+            <version>2.0</version>
+        </dependency>
+               <!-- Dependencies of parent pom start -->
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>sdk-java-common-logging</artifactId>
+                       <version>${sdk.java.common.logging}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-starter-tomcat</artifactId>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-starter-actuator</artifactId>
+               </dependency>
+               <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency> 
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-starter-test</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>joda-time</groupId>
+                       <artifactId>joda-time</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-context</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-api</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>javax.ws.rs</groupId>
+                       <artifactId>javax.ws.rs-api</artifactId>
+                       <version>2.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-test</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-all</artifactId>
+                       <version>1.9.5</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-logging</groupId>
+                       <artifactId>commons-logging</artifactId>
+                       <version>1.1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-aspects</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-core</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-databind</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-webmvc</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-starter-web</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.17</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-autoconfigure</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>javax.transaction</groupId>
+                       <artifactId>jta</artifactId>
+                       <version>1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>javax.persistence</groupId>
+                       <artifactId>persistence-api</artifactId>
+                       <version>1.0.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-annotations</artifactId>
+                       <version>3.5.6-Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.geronimo.specs</groupId>
+                       <artifactId>geronimo-jpa_2.0_spec</artifactId>
+                       <version>1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>dom4j</groupId>
+                       <artifactId>dom4j</artifactId>
+                       <version>1.6.1</version>
+               </dependency>
+               <!-- Dependencies of parent pom end -->
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>sdk-java-camel-rest</artifactId>
+                       <version>${sdk.camel.rest}</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.swagger</groupId>
+                       <artifactId>swagger-core</artifactId>
+                       <version>1.5.8</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.swagger</groupId>
+                       <artifactId>swagger-annotations</artifactId>
+                       <version>1.5.8</version>
+               </dependency>
+               <!-- Camunda Core -->
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>sdk-java-camunda-core</artifactId>
+                       <version>${sdk.camunda.core}</version>
+               </dependency>
+               <!-- Spring Mail -->
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-context-support</artifactId>
+               </dependency>
+               <!-- CSI Logging -->
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>sdk-java-common-interceptors</artifactId>
+                       <version>${csi.logging}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.eclipse.jetty.orbit</groupId>
+                                       <artifactId>javax.servlet</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>com.att.ajsc</groupId>
+                                       <artifactId>ajsc-core</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <!-- CSI Logging End -->
+               <dependency>
+                       <groupId>org.openecomp.policy.engine</groupId>
+                       <artifactId>PolicyEngineAPI</artifactId>
+                       <version>1.1.0-SNAPSHOT</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <artifactId>apache-log4j-extras</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.policy.common</groupId>
+                       <artifactId>ECOMP-Logging</artifactId>
+                       <version>1.1.0-SNAPSHOT</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <artifactId>apache-log4j-extras</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+            <groupId>org.openecomp.policy.engine</groupId>
+            <artifactId>ControlloopPolicy</artifactId>
+            <version>1.1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>apache-log4j-extras</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+               <dependency>
+                       <groupId>com.fasterxml.jackson.dataformat</groupId>
+                       <artifactId>jackson-dataformat-yaml</artifactId>
+                       <!-- >version>2.0.0-RC1</version <version>${fasterxml.jackson.version}</version -->
+                       <version>2.6.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       <artifactId>commons-csv</artifactId>
+                       <version>1.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jboss.resteasy</groupId>
+                       <artifactId>resteasy-client</artifactId>
+                       <version>3.0.8.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.faces</groupId>
+                       <artifactId>jsf-api</artifactId>
+                       <version>2.1.7</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.faces</groupId>
+                       <artifactId>jsf-impl</artifactId>
+                       <version>2.1.7</version>
+               </dependency>
+
+       </dependencies>
+
+       <build>
+               <testResources>
+                   <testResource>
+                <directory>src/test/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+                <filtering>true</filtering>
+            </testResource>
+               </testResources>
+               <resources>
+                       <resource>
+                               <directory>src/main/resources</directory>
+                               <filtering>true</filtering>
+                       </resource>
+                       <resource>
+                               <directory>target/generated-sources/license</directory>
+                               <includes>
+                                       <include>third-party-licenses.txt</include>
+                               </includes>
+                       </resource>
+                       <resource>
+                               <directory>target/generated-resources/licenses</directory>
+                               <includes>
+                                       <include>*.*</include>
+                               </includes>
+                               <targetPath>third-party-licenses</targetPath>
+                       </resource>
+                       <resource>
+                               <directory>${project.basedir}/etc</directory>
+                               <targetPath>${project.build.directory}/etc</targetPath>
+                               <filtering>true</filtering>
+                               <includes>
+                                       <include>**/*</include>
+                               </includes>
+                       </resource>
+                       <resource>
+                               <directory>src/main/docker</directory>
+                               <includes>
+                                       <include>**/*</include>
+                               </includes>
+                               <filtering>true</filtering>
+                       </resource>
+                       <resource>
+                               <directory>src/main/doxygen</directory>
+                               <includes>
+                                       <include>**/*</include>
+                               </includes>
+                               <filtering>true</filtering>
+                       </resource>
+               </resources>
+               <pluginManagement>
+                       <plugins>
+                               <!--This plugin's configuration is used to store Eclipse m2e settings
+                                       only. It has no influence on the Maven build itself. -->
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-release-plugin</artifactId>
+                                       <version>2.5.3</version>
+                                       <configuration>
+                                               <tagBase>${projectTag}</tagBase>
+                                               <scmCommentPrefix>${scm.commit.message}</scmCommentPrefix>
+                                       </configuration>
+                               </plugin>
+                               <plugin>
+                                       <groupId>com.github.kongchen</groupId>
+                                       <artifactId>swagger-maven-plugin</artifactId>
+                                       <version>3.1.3</version>
+                                       <configuration>
+                                               <apiSources>
+                                                       <apiSource>
+                                                               <locations>${icd.package}</locations>
+                                                               <basePath>/</basePath>
+                                                               <info>
+                                                                       <title>${project.artifactId} Service</title>
+                                                                       <version>${project.version}</version>
+                                                               </info>
+                                                               <swaggerDirectory>${swagger.directory}</swaggerDirectory>
+                                                       </apiSource>
+                                               </apiSources>
+                                       </configuration>
+                                       <executions>
+                                               <execution>
+                                                       <phase>compile</phase>
+                                                       <goals>
+                                                               <goal>generate</goal>
+                                                       </goals>
+                                               </execution>
+                                       </executions>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.eclipse.m2e</groupId>
+                                       <artifactId>lifecycle-mapping</artifactId>
+                                       <version>1.0.0</version>
+                                       <configuration>
+                                               <lifecycleMappingMetadata>
+                                                       <pluginExecutions>
+                                                               <pluginExecution>
+                                                                       <pluginExecutionFilter>
+                                                                               <groupId>com.github.kongchen</groupId>
+                                                                               <artifactId>swagger-maven-plugin</artifactId>
+                                                                               <versionRange>3.1.3</versionRange>
+                                                                               <goals>
+                                                                                       <goal>generate</goal>
+                                                                               </goals>
+                                                                       </pluginExecutionFilter>
+                                                                       <action>
+                                                                               <ignore />
+                                                                       </action>
+                                                               </pluginExecution>
+                                                       </pluginExecutions>
+                                               </lifecycleMappingMetadata>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+               <plugins>
+                     <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.0.2</version>
+                <executions>
+                    <execution>
+                        <id>jar-with-only-classes</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <classifier>classes</classifier>
+                            <excludes>
+                                <exclude>META-INF/resources/designer/**</exclude>
+                                <exclude>META-INF/resources/icd/**</exclude>
+                                <exclude>META-INF/resources/index.html</exclude>
+                            </excludes>
+                        </configuration>
+                    </execution>
+               </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                    <goals>
+                        <goal>attach-artifact</goal>
+                    </goals>
+                    <phase>package</phase>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>${project.build.directory}/clds-${project.version}-classes.jar</file>
+                                    <type>jar</type>
+                                    <classifier>classes</classifier>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+                       <plugin>
+                               <groupId>org.springframework.boot</groupId>
+                               <artifactId>spring-boot-maven-plugin</artifactId>
+                               <version>1.5.3.RELEASE</version>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>repackage</goal>
+                                               </goals>
+                                               <phase>package</phase>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <artifactId>maven-release-plugin</artifactId>
+                               <dependencies>
+                                       <dependency>
+                                               <groupId>org.apache.maven.scm</groupId>
+                                               <artifactId>maven-scm-provider-gitexe</artifactId>
+                                               <version>1.9</version>
+                                       </dependency>
+                               </dependencies>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-gpg-plugin</artifactId>
+                               <version>1.5</version>
+                               <configuration>
+                                       <skip>true</skip>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>sign-artifacts</id>
+                                               <phase>verify</phase>
+                                               <goals>
+                                                       <goal>sign</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.sonatype.plugins</groupId>
+                               <artifactId>nexus-staging-maven-plugin</artifactId>
+                               <version>1.6.7</version>
+                               <extensions>true</extensions>
+                               <configuration>
+                                       <serverId>ossrhajsc</serverId>
+                                       <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+                                       <autoReleaseAfterClose>true</autoReleaseAfterClose>
+                                       <skipNexusStagingDeployMojo>${skip.staging.artifacts}</skipNexusStagingDeployMojo>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>com.github.kongchen</groupId>
+                               <artifactId>swagger-maven-plugin</artifactId>
+                               <configuration>
+                                       <apiSources>
+                                               <apiSource>
+                                                       <locations>org.onap.clamp.clds.service.rs</locations>
+                                                       <basePath>//rest</basePath>
+                                                       <info>
+                                                               <title>${project.artifactId} Service</title>
+                                                               <version>${project.version}</version>
+                                                       </info>
+                                                       <swaggerDirectory>${swagger.directory}</swaggerDirectory>
+                                               </apiSource>
+                                       </apiSources>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <phase>compile</phase>
+                                               <goals>
+                                                       <goal>generate</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>com.spotify</groupId>
+                               <artifactId>docker-maven-plugin</artifactId>
+                               <version>0.4.11</version>
+                               <configuration>
+                                       <imageName>onap/clamp</imageName>
+                                       <dockerDirectory>src/main/docker</dockerDirectory>
+                                       <serverId>docker-hub</serverId>
+                                       <imageTags>
+                                               <imageTag>${project.version}</imageTag>
+                                               <imageTag>latest</imageTag>
+                                       </imageTags>
+                                       <forceTags>true</forceTags>
+                                       <resources>
+                                               <resource>
+                                                       <targetPath>/</targetPath>
+                                                       <directory>${project.build.directory}</directory>
+                                                       <include>${project.build.finalName}.jar</include>
+                                               </resource>
+                                               <resource>
+                                                       <targetPath>/</targetPath>
+                                                       <directory>${project.build.directory}</directory>
+                                                       <include>etc/config/**</include>
+                                               </resource>
+                                       </resources>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>build-image</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>build</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <skipDockerBuild>${skip.docker.build}</skipDockerBuild>
+                                                       <buildArgs>
+                                                               <http_proxy>${env.HTTP_PROXY}</http_proxy>
+                                                               <https_proxy>${env.HTTPS_PROXY}</https_proxy>
+                                                       </buildArgs>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>tag-image</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>tag</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <image>onap/clamp</image>
+                                                       <newName>${clamp.registry}/onap/clamp</newName>
+                                                       <pushImage>true</pushImage>
+                                                       <skipDockerTag>${skip.docker.tag}</skipDockerTag>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>push-image</id>
+                                               <phase>deploy</phase>
+                                               <goals>
+                                                       <goal>push</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <skipDockerPush>${skip.docker.push}</skipDockerPush>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <version>2.19.1</version>
+                               <configuration>
+                                       <forkCount>1</forkCount>
+                                       <reuseForks>false</reuseForks>
+                               </configuration>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-failsafe-plugin</artifactId>
+                               <version>2.16</version>
+
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>integration-test</goal>
+                                                       <goal>verify</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <forkCount>1</forkCount>
+                                                       <reuseForks>false</reuseForks>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+
+                       </plugin>
+                       <plugin>
+                               <groupId>io.fabric8</groupId>
+                               <artifactId>docker-maven-plugin</artifactId>
+                               <version>0.16.5</version>
+                               <configuration>
+                                       <verbose>true</verbose>
+                                       <apiVersion>1.23</apiVersion>
+                                       <images>
+                                               <image>
+                                                       <name>mariadb:10.1.11</name>
+                                                       <alias>mariadb</alias>
+                                                       <run>
+                                                               <env>
+                                                                       <MYSQL_ROOT_PASSWORD>strong_pitchou</MYSQL_ROOT_PASSWORD>
+                                                               </env>
+                                                               <hostname>mariadb</hostname>
+                                                               <volumes>
+                                                                       <bind>
+                                                                               <volume>${project.basedir}/extra/sql/:/docker-entrypoint-initdb.d</volume>
+                                                                               <volume>${project.basedir}/extra/docker/mariadb/conf1:/etc/mysql/conf.d</volume>
+                                                                       </bind>
+                                                               </volumes>
+                                                               <wait>
+                                                                       <log>socket: '/var/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution</log>
+                                                                       <time>60000</time>
+                                                               </wait>
+                                                               <ports>
+                                                                       <port>${docker.mariadb.port.host}:3306</port>
+                                                               </ports>
+                                                       </run>
+                                               </image>
+                                       </images>
+                               </configuration>
+
+                               <executions>
+                                       <execution>
+                                               <id>mariadb-start-for-it</id>
+                                               <phase>pre-integration-test</phase>
+                                               <goals>
+                                                       <goal>start</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <skip>${skipITs}</skip>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>mariadb-stop-for-it</id>
+                                               <phase>post-integration-test</phase>
+                                               <goals>
+                                                       <goal>stop</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <skip>${skipITs}</skip>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.jacoco</groupId>
+                               <artifactId>jacoco-maven-plugin</artifactId>
+                               <version>0.7.7.201606060606</version>
+                               <configuration>
+                                       <dumpOnExit>true</dumpOnExit>
+                                       <includes>
+                                               <include>org.onap.clamp.*</include>
+                                       </includes>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>jacoco-unit-tests</id>
+                                               <goals>
+                                                       <goal>prepare-agent</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <destFile>${project.build.directory}/coverage-reports/jacoco.exec</destFile>
+                                                       <!-- <append>true</append> -->
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>jacoco-integration-tests</id>
+                                               <phase>pre-integration-test</phase>
+                                               <goals>
+                                                       <goal>prepare-agent</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
+                                                       <!-- <append>true</append> -->
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+          <!-- license plugin -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>license-maven-plugin</artifactId>
+                <version>1.12</version>
+                <configuration>
+                    <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                    <projectName>ONAP CLAMP</projectName>
+                    <canUpdateCopyright>true</canUpdateCopyright>
+                    <canUpdateDescription>true</canUpdateDescription>
+                    <canUpdateLicense>true</canUpdateLicense>
+
+                    <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                    <processEndTag><![CDATA[ECOMP &nbsp;is &nbsp;a &nbsp;trademark &nbsp;and &nbsp;service &nbsp;mark &nbsp;of &nbsp;AT&amp;T &nbsp;Intellectual &nbsp;Property.]]></processEndTag>
+                    <sectionDelimiter>================================================================================</sectionDelimiter>
+                    <organizationName>AT&amp;T Intellectual Property. All rights
+                            reserved.</organizationName>
+                    <inceptionYear>2017</inceptionYear>
+                    <emptyLineAfterHeader>true</emptyLineAfterHeader>
+
+                    <licenseName>clamp_apache_v2</licenseName>
+                    <licenseResolver>${project.baseUri}/src/licenses</licenseResolver>
+
+                    <excludes>
+                         <exclude>**/*.properties</exclude>
+                         <exclude>**/icd/**</exclude>
+                         <exclude>**/designer/lib/**</exclude>
+                         <exclude>**/*.json</exclude>
+                         <exclude>**/*.yaml</exclude>
+                         <exclude>**/*.yml</exclude>
+                         <exclude>**/licenses/**</exclude>
+                    </excludes>
+                </configuration>
+
+            </plugin>
+
+                       <!-- This plugin will be useful when we will have multi-modules project -->
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>versions-maven-plugin</artifactId>
+                               <version>1.3.1</version>
+                       </plugin>
+               </plugins>
+       </build>
+       <profiles>
+               <profile>
+                       <id>docker</id>
+                       <properties>
+                               <skip.staging.artifacts>true</skip.staging.artifacts>
+                               <skip.docker.build>false</skip.docker.build>
+                       </properties>
+               </profile>
+       </profiles>
+</project>
diff --git a/src/licenses/clamp_apache_v2/header.txt b/src/licenses/clamp_apache_v2/header.txt
new file mode 100644 (file)
index 0000000..578ee1a
--- /dev/null
@@ -0,0 +1,13 @@
+Licensed under the Apache License, Version 2.0 (the "License"); 
+you may not use this file except in compliance with the License. 
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, 
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+See the License for the specific language governing permissions and 
+limitations under the License.
+============LICENSE_END============================================
+===================================================================
\ No newline at end of file
diff --git a/src/licenses/clamp_apache_v2/license.txt b/src/licenses/clamp_apache_v2/license.txt
new file mode 100644 (file)
index 0000000..f7306e6
--- /dev/null
@@ -0,0 +1,19 @@
+============LICENSE_START==========================================
+===================================================================
+Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+===================================================================
+Licensed under the Apache License, Version 2.0 (the "License"); 
+you may not use this file except in compliance with the License. 
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, 
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+See the License for the specific language governing permissions and 
+limitations under the License.
+============LICENSE_END============================================
+===================================================================
+
+ECOMP is a trademark and service mark of AT&T Intellectual Property.
\ No newline at end of file
diff --git a/src/licenses/licenses.properties b/src/licenses/licenses.properties
new file mode 100644 (file)
index 0000000..7add1a4
--- /dev/null
@@ -0,0 +1 @@
+clamp_apache_v2=Clamp License
diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile
new file mode 100644 (file)
index 0000000..7dbd3da
--- /dev/null
@@ -0,0 +1,25 @@
+FROM ubuntu:16.04
+
+MAINTAINER "The Onap Team"
+LABEL Description="This image contains an updated ubuntu 16.04 with the openjdk installed" Version="16.04-8"
+
+ARG http_proxy
+ARG https_proxy
+ENV HTTP_PROXY=$http_proxy
+ENV HTTPS_PROXY=$https_proxy
+ENV http_proxy=$HTTP_PROXY
+ENV https_proxy=$HTTPS_PROXY
+
+RUN test -n "$http_proxy" && echo "Acquire::Proxy \"http://$http_proxy\";" > /etc/apt/apt.conf.d/02proxy || true &&  \
+    apt-get update &&  \
+    apt-get -y dist-upgrade &&  \
+    apt-get install -y openjdk-8-jre-headless
+
+ADD clds-0.0.1-SNAPSHOT.jar /opt/clamp/app.jar
+VOLUME /etc
+ADD /etc/ /etc/
+ADD startService.sh /opt/clamp/startService.sh
+RUN chmod 700 /opt/clamp/startService.sh
+
+WORKDIR /opt/clamp/
+ENTRYPOINT ./startService.sh 
diff --git a/src/main/docker/startService.sh b/src/main/docker/startService.sh
new file mode 100644 (file)
index 0000000..82c9341
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+java -Djava.security.egd=file:/dev/./urandom -Xms1024m -Xmx1024m -jar ./app.jar
+
diff --git a/src/main/java/org/onap/clamp/clds/Application.java b/src/main/java/org/onap/clamp/clds/Application.java
new file mode 100644 (file)
index 0000000..8459027
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds;
+
+import com.att.ajsc.common.utility.SystemPropertiesLoader;
+import org.apache.camel.component.servlet.CamelHttpTransportServlet;
+import org.camunda.bpm.spring.boot.starter.webapp.CamundaBpmWebappAutoConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.ManagementWebSecurityAutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import java.util.ArrayList;
+import java.util.Collection;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"org.onap.clamp.clds","com.att.ajsc"})
+@EnableAutoConfiguration(exclude = {CamundaBpmWebappAutoConfiguration.class, HibernateJpaAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
+@EnableAsync
+public class Application extends SpringBootServletInitializer {
+
+    private static final String CAMEL_SERVLET_NAME = "CamelServlet";
+    private static final String CAMEL_URL_MAPPING = "/restservices/clds/v1/*";
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(Application.class);
+    }
+
+    public static void main(String[] args) throws Exception {
+        SystemPropertiesLoader.addSystemProperties();
+        SpringApplication.run(Application.class, args);
+    }
+
+    @Bean
+    public ServletRegistrationBean servletRegistrationBean() {
+        ServletRegistrationBean registration = new ServletRegistrationBean();
+        registration.setName(CAMEL_SERVLET_NAME);
+        registration.setServlet(new CamelHttpTransportServlet());
+        Collection<String> urlMappings = new ArrayList<>();
+        urlMappings.add(CAMEL_URL_MAPPING);
+        registration.setUrlMappings(urlMappings);
+        return registration;
+    }
+
+    @Bean
+    public Client restClient() {
+        return ClientBuilder.newClient();
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/Routes.java b/src/main/java/org/onap/clamp/clds/Routes.java
new file mode 100644 (file)
index 0000000..6fcb930
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds;
+
+import com.att.ajsc.common.camel.AjscRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Routes extends RouteBuilder {
+    @Autowired
+    private AjscRouteBuilder ajscRoute;
+
+    @Override
+    public void configure() throws Exception {
+        ajscRoute.initialize(this);
+        ajscRoute.setRoute(from("servlet:/?matchOnUriPrefix=true").to("cxfbean:jaxrsServices?providers=jaxrsProviders"));
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/WebConfig.java b/src/main/java/org/onap/clamp/clds/WebConfig.java
new file mode 100644 (file)
index 0000000..38bd62e
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class WebConfig {
+
+    @Bean
+    public WebMvcConfigurerAdapter forwardToIndex() {
+        return new WebMvcConfigurerAdapter() {
+            @Override
+            public void addViewControllers(ViewControllerRegistry registry) {
+                registry.addViewController("/swagger").setViewName("redirect:/icd/index.html");
+                registry.addViewController("/icd/").setViewName("redirect:/icd/index.html");
+                registry.addViewController("/login").setViewName("login.html");
+            }
+        };
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/CldsEventDelegate.java b/src/main/java/org/onap/clamp/clds/client/CldsEventDelegate.java
new file mode 100644 (file)
index 0000000..0f4d30d
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.CldsEvent;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.logging.Logger;
+
+/**
+ * Create CLDS Event.
+ */
+public class CldsEventDelegate implements JavaDelegate {
+    private static final Logger logger = Logger.getLogger(CldsEventDelegate.class.getName());
+    @Autowired
+    private CldsDao cldsDao;
+
+    /**
+     * Insert event using process variables.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String controlName = (String) execution.getVariable("controlName");
+        String actionCd = (String) execution.getVariable("actionCd");
+        String actionStateCd = (String) execution.getVariable("actionStateCd");
+        boolean isTest = (boolean) execution.getVariable("isTest");
+        boolean isInsertTestEvent = (boolean) execution.getVariable("isInsertTestEvent");
+        String userid = (String) execution.getVariable("userid");
+
+        // do not insert events for test actions unless flag set to insert them
+        if (!isTest || isInsertTestEvent) {
+            // won't really have userid here...
+            CldsEvent.insEvent(cldsDao, controlName, userid, actionCd, actionStateCd, execution.getProcessInstanceId());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/DcaeReqDelegate.java b/src/main/java/org/onap/clamp/clds/client/DcaeReqDelegate.java
new file mode 100644 (file)
index 0000000..5583cf9
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.client.req.DcaeReq;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.logging.Logger;
+
+
+/**
+ * Send control loop model to dcae proxy.
+ */
+public class DcaeReqDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(DcaeReqDelegate.class.getName());
+
+    @Autowired
+    private RefProp refProp;
+
+    /**
+     * Perform activity.  Send to dcae proxy.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        ModelProperties prop = ModelProperties.create(execution);
+        String dcaeReq = DcaeReq.format(refProp, prop);
+        if (dcaeReq != null) {
+            execution.setVariable("dcaeReq", dcaeReq.getBytes());
+        }
+        execution.setVariable("dcaeUrl", System.getProperty("CLDS_DCAE_URL") + "/" + prop.getControlName());
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/DcaeReqDeleteDelegate.java b/src/main/java/org/onap/clamp/clds/client/DcaeReqDeleteDelegate.java
new file mode 100644 (file)
index 0000000..28dd6f1
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.logging.Logger;
+
+
+/**
+ * Send control loop model to dcae proxy.
+ */
+public class DcaeReqDeleteDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(DcaeReqDeleteDelegate.class.getName());
+
+    @Autowired
+    private RefProp refProp;
+
+    /**
+     * Perform activity.  Send to dcae proxy.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        ModelProperties prop = ModelProperties.create(execution);
+        execution.setVariable("dcaeUrl", System.getProperty("CLDS_DCAE_URL") + "/" + prop.getControlName());
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java b/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDelegate.java
new file mode 100644 (file)
index 0000000..fc3ea2a
--- /dev/null
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.client.req.OperationalPolicyReq;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.openecomp.policy.api.AttributeType;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+
+/**
+ * Send Operational Policy info to policy api.
+ */
+public class OperationalPolicyDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(OperationalPolicyDelegate.class.getName());
+
+    @Autowired 
+    private PolicyClient policyClient;
+    
+    @Autowired
+    private RefProp refProp;
+
+    /**
+     * Perform activity.  Send Operational Policy info to policy api.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String operationalPolicyRequestUuid = UUID.randomUUID().toString();
+        execution.setVariable("operationalPolicyRequestUuid", operationalPolicyRequestUuid);
+
+        ModelProperties prop = ModelProperties.create(execution);
+        Map<AttributeType, Map<String, String>> attributes = OperationalPolicyReq.formatAttributes(refProp, prop);
+        String responseMessage = policyClient.sendBrms(attributes, prop, operationalPolicyRequestUuid);
+        if (responseMessage != null) {
+            execution.setVariable("operationalPolicyResponseMessage", responseMessage.getBytes());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDeleteDelegate.java b/src/main/java/org/onap/clamp/clds/client/OperationalPolicyDeleteDelegate.java
new file mode 100644 (file)
index 0000000..816b214
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.Policy;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.logging.Logger;
+
+
+/**
+ * Delete Operational Policy via policy api.
+ */
+public class OperationalPolicyDeleteDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(OperationalPolicyDeleteDelegate.class.getName());
+
+    @Autowired
+    private PolicyClient policyClient;
+
+    /**
+     * Perform activity.  Delete Operational Policy via policy api.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        ModelProperties prop = ModelProperties.create(execution);
+        Policy policy = prop.getPolicy();
+        prop.setCurrentModelElementId(policy.getId());
+
+        String responseMessage = policyClient.deleteBrms(prop);
+        if (responseMessage != null) {
+            execution.setVariable("operationalPolicyDeleteResponseMessage", responseMessage.getBytes());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/PolicyClient.java b/src/main/java/org/onap/clamp/clds/client/PolicyClient.java
new file mode 100644 (file)
index 0000000..95e60ea
--- /dev/null
@@ -0,0 +1,342 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.openecomp.policy.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+
+import java.util.*;
+import java.util.logging.Logger;
+
+
+/**
+ * Policy utility methods - specifically, send the policy.
+ */
+public class PolicyClient {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(PolicyClient.class.getName());
+
+    @Value("${org.onap.clamp.config.files.cldsPolicyConfig:'classpath:etc/clds/clds-policy-config.properties'}")
+    private String cldsPolicyConfigFile;
+
+    @Autowired
+    private ApplicationContext appContext;
+    
+    @Autowired
+    private RefProp refProp;
+    
+    public PolicyClient() {
+        
+    }
+
+    /**
+     * Perform send of microservice policy
+     *
+     * @param attributes
+     * @param prop
+     * @param policyRequestUUID
+     * @return
+     * @throws Exception
+     */
+    public String sendBrms(Map<AttributeType, Map<String, String>> attributes, ModelProperties prop, String policyRequestUUID) throws Exception {
+
+        PolicyParameters policyParameters = new PolicyParameters();
+
+        // Set Policy Type(Mandatory)
+        policyParameters.setPolicyConfigType(PolicyConfigType.BRMS_PARAM);
+
+        // Set Policy Name(Mandatory)
+        policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
+        //Set Scope folder where the policy needs to be created(Mandatory)
+        //policyParameters.setPolicyScope(policyScope);
+
+        // documentation says this is options, but when tested, got the following failure: java.lang.Exception: Policy send failed: PE300 - Data Issue: No policyDescription given.
+        policyParameters.setPolicyDescription(refProp.getStringValue("op.policyDescription"));
+
+        policyParameters.setAttributes(attributes);
+
+        //Set a random UUID(Mandatory)
+        policyParameters.setRequestID(UUID.fromString(policyRequestUUID));
+
+        String rtnMsg = send(policyParameters, prop);
+
+        String policyType = refProp.getStringValue("policy.op.type");
+        push(policyType, prop);
+
+        return rtnMsg;
+    }
+
+    /**
+     * Perform send of microservice policy
+     *
+     * @param policyJson
+     * @param prop
+     * @param policyRequestUUID
+     * @return
+     * @throws Exception
+     */
+    public String sendMicroService(String policyJson, ModelProperties prop, String policyRequestUUID) throws Exception {
+
+        PolicyParameters policyParameters = new PolicyParameters();
+
+        // Set Policy Type
+        policyParameters.setPolicyConfigType(PolicyConfigType.MicroService);
+        policyParameters.setEcompName(refProp.getStringValue("policy.ecomp.name"));
+        policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
+
+        policyParameters.setConfigBody(policyJson);
+        policyParameters.setConfigBodyType(PolicyType.JSON);
+
+        policyParameters.setRequestID(UUID.fromString(policyRequestUUID));
+
+        String rtnMsg = send(policyParameters, prop);
+
+        String policyType = refProp.getStringValue("policy.ms.type");
+        push(policyType, prop);
+
+        return rtnMsg;
+    }
+
+    /**
+     * Perform send of policy.
+     *
+     * @param policyParameters
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    private String send(PolicyParameters policyParameters, ModelProperties prop) throws Exception {
+        PolicyEngine policyEngine = new PolicyEngine(appContext.getResource(cldsPolicyConfigFile).getFile().getAbsolutePath());
+
+        // API method to create or update Policy.
+        PolicyChangeResponse response = null;
+        String responseMessage;
+        try {
+            if (prop.isCreateRequest()) {
+                logger.info("Attempting to create policy for action=" + prop.getActionCd());
+                response = policyEngine.createPolicy(policyParameters);
+                responseMessage = response.getResponseMessage();
+            } else {
+                logger.info("Attempting to update policy for action=" + prop.getActionCd());
+                response = policyEngine.updatePolicy(policyParameters);
+                responseMessage = response.getResponseMessage();
+            }
+        } catch (Exception e) {
+            responseMessage = e.toString();
+        }
+        logger.info("response is " + responseMessage);
+
+        if (response != null && response.getResponseCode() == 200) {
+            logger.info("Policy send successful");
+        } else {
+            logger.warning("Policy send failed: " + responseMessage);
+            throw new Exception("Policy send failed: " + responseMessage);
+        }
+
+        return responseMessage;
+    }
+
+    /**
+     * Format and send push of policy.
+     *
+     * @param policyType
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    private String push(String policyType, ModelProperties prop) throws Exception {
+        PushPolicyParameters pushPolicyParameters = new PushPolicyParameters();
+
+        //Parameter arguments
+        pushPolicyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
+        pushPolicyParameters.setPolicyType(policyType);
+        //pushPolicyParameters.setPolicyScope(policyScope);
+        pushPolicyParameters.setPdpGroup(refProp.getStringValue("policy.pdp.group"));
+        pushPolicyParameters.setRequestID(null);
+
+        PolicyEngine policyEngine = new PolicyEngine(appContext.getResource(cldsPolicyConfigFile).getFile().getAbsolutePath());
+
+        // API method to create or update Policy.
+        PolicyChangeResponse response = null;
+        String responseMessage;
+        try {
+            logger.info("Attempting to push policy...");
+            response = policyEngine.pushPolicy(pushPolicyParameters);
+            responseMessage = response.getResponseMessage();
+        } catch (Exception e) {
+            responseMessage = e.toString();
+        }
+        logger.info("response is " + responseMessage);
+
+        if (response != null && (response.getResponseCode() == 200 || response.getResponseCode() == 204)) {
+            logger.info("Policy push successful");
+        } else {
+            logger.warning("Policy push failed: " + responseMessage);
+            throw new Exception("Policy push failed: " + responseMessage);
+        }
+
+        return responseMessage;
+    }
+
+    /**
+     * Use Get Config Policy API to retrieve the versions for a policy.
+     * Return versions in sorted order.
+     * Return empty list if none found.
+     *
+     * @param policyNamePrefix
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    private List<Integer> getVersions(String policyNamePrefix, ModelProperties prop) throws Exception {
+
+        ArrayList<Integer> versions = new ArrayList<>();
+        ConfigRequestParameters configRequestParameters = new ConfigRequestParameters();
+        String policyName = prop.getCurrentPolicyScopeAndFullPolicyName(policyNamePrefix);
+        logger.info("policyName=" + policyName);
+        configRequestParameters.setPolicyName(policyName);
+
+        PolicyEngine policyEngine = new PolicyEngine(appContext.getResource(cldsPolicyConfigFile).getFile().getAbsolutePath());
+
+        Collection<PolicyConfig> response = policyEngine.getConfig(configRequestParameters);
+
+        Iterator<PolicyConfig> itrResp = response.iterator();
+
+        while (itrResp.hasNext()) {
+            PolicyConfig policyConfig = itrResp.next();
+            try {
+                Integer version = new Integer(policyConfig.getPolicyVersion());
+                versions.add(version);
+            } catch (Exception e) {
+                // just print warning - if n;o policies, version may be null
+                logger.warning("warning: failed to parse policyConfig.getPolicyVersion()=" + policyConfig.getPolicyVersion());
+            }
+        }
+        Collections.sort(versions);
+        logger.info("versions.size()=" + versions.size());
+
+        return versions;
+    }
+
+    /**
+     * Format and send delete Micro Service requests to Policy
+     *
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    public String deleteMicrosService(ModelProperties prop) throws Exception {
+        String policyNamePrefix = refProp.getStringValue("policy.ms.policyNamePrefix");
+        return deletePolicy(policyNamePrefix, prop);
+    }
+
+    /**
+     * Format and send delete BRMS requests to Policy
+     *
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    public String deleteBrms(ModelProperties prop) throws Exception {
+        String policyNamePrefix = refProp.getStringValue("policy.op.policyNamePrefix");
+        return deletePolicy(policyNamePrefix, prop);
+    }
+
+    /**
+     * Format and send delete PAP and PDP requests to Policy
+     *
+     * @param policyNamePrefix
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    private String deletePolicy(String policyNamePrefix, ModelProperties prop) throws Exception {
+        String responseMessage = null;
+
+        DeletePolicyParameters deletePolicyParameters = new DeletePolicyParameters();
+
+        List<Integer> versions = getVersions(policyNamePrefix, prop);
+        if (versions.size() > 0) {
+            int maxVersion = Collections.max(versions);
+
+            // format delete all PAP request
+            deletePolicyParameters.setPolicyName(prop.getCurrentPolicyScopeAndFullPolicyNameWithVersion(policyNamePrefix, maxVersion));
+            deletePolicyParameters.setPolicyComponent("PAP");
+            deletePolicyParameters.setDeleteCondition(DeletePolicyCondition.ALL);
+            String policyType = refProp.getStringValue("policy.ms.type");
+            deletePolicyParameters.setPolicyType(policyType);
+
+            //send delete request
+            responseMessage = sendDeletePolicy(deletePolicyParameters, prop);
+        }
+
+        for (Integer version : versions) {
+            // format delete all PDP request
+            deletePolicyParameters.setPolicyName(prop.getCurrentPolicyScopeAndFullPolicyNameWithVersion(policyNamePrefix, version));
+            deletePolicyParameters.setPolicyComponent("PDP");
+            deletePolicyParameters.setPdpGroup(refProp.getStringValue("policy.pdp.group"));
+            //send delete request
+            responseMessage = responseMessage + "; " + sendDeletePolicy(deletePolicyParameters, prop);
+        }
+
+        return responseMessage;
+    }
+
+    /**
+     * Send delete request to Policy
+     *
+     * @param deletePolicyParameters
+     * @param prop
+     * @return
+     * @throws Exception
+     */
+    private String sendDeletePolicy(DeletePolicyParameters deletePolicyParameters, ModelProperties prop) throws Exception {
+        PolicyEngine policyEngine = new PolicyEngine(appContext.getResource(cldsPolicyConfigFile).getFile().getAbsolutePath());
+
+        // API method to create or update Policy.
+        PolicyChangeResponse response = null;
+        String responseMessage;
+        try {
+            logger.info("Attempting to delete policy...");
+            response = policyEngine.deletePolicy(deletePolicyParameters);
+            responseMessage = response.getResponseMessage();
+        } catch (Exception e) {
+            responseMessage = e.toString();
+        }
+        logger.info("response is " + responseMessage);
+
+        if (response != null && response.getResponseCode() == 200) {
+            logger.info("Policy delete successful");
+        } else {
+            logger.warning("Policy delete failed: " + responseMessage);
+            throw new Exception("Policy delete failed: " + responseMessage);
+        }
+
+        return responseMessage;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/client/SdcCatalogServices.java b/src/main/java/org/onap/clamp/clds/client/SdcCatalogServices.java
new file mode 100644 (file)
index 0000000..58bba3c
--- /dev/null
@@ -0,0 +1,864 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import org.onap.clamp.clds.client.req.SdcReq;
+import org.onap.clamp.clds.model.*;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVRecord;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class SdcCatalogServices {
+    private static final Logger logger = LoggerFactory.getLogger(SdcSendReqDelegate.class);
+
+    @Autowired
+    private RefProp refProp;
+
+    public String getAsdcServicesInformation(String uuid) throws Exception {
+        String baseUrl = refProp.getStringValue("asdc.serviceUrl");
+        String basicAuth = SdcReq.getAsdcBasicAuth(refProp);
+        try {
+            String url = baseUrl;
+            if (uuid != null) {
+                url = baseUrl + "/" + uuid + "/metadata";
+            }
+            URL urlObj = new URL(url);
+
+            HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
+
+            conn.setRequestProperty("X-ONAP-InstanceID", "CLAMP-Tool");
+            conn.setRequestProperty("Authorization", basicAuth);
+            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+            conn.setRequestMethod("GET");
+
+            String resp = getResponse(conn);
+            if (resp != null) {
+                logger.info(resp.toString());
+                return resp;
+            }
+        } catch (Exception e) {
+            logger.error("not able to ger any service information from asdc for uuid:" + uuid);
+        }
+        return "";
+    }
+
+    /**
+     * To remove duplicate serviceUUIDs from asdc services List
+     *
+     * @param rawCldsAsdcServiceList
+     * @return
+     */
+    public List<CldsAsdcServiceInfo> removeDuplicateServices(List<CldsAsdcServiceInfo> rawCldsAsdcServiceList) {
+        List<CldsAsdcServiceInfo> cldsAsdcServiceInfoList = null;
+        if (rawCldsAsdcServiceList != null && rawCldsAsdcServiceList.size() > 0) {
+            // sort list
+            Collections.sort(rawCldsAsdcServiceList);
+            // and then take only the services with the max version (last in the list with the same name)
+            cldsAsdcServiceInfoList = new ArrayList<>();
+            for (int i = 1; i < rawCldsAsdcServiceList.size(); i++) {
+                // compare name with previous - if not equal, then keep the previous (it's the last with that name)
+                CldsAsdcServiceInfo prev = rawCldsAsdcServiceList.get(i - 1);
+                if (!rawCldsAsdcServiceList.get(i).getName().equals(prev.getName())) {
+                    cldsAsdcServiceInfoList.add(prev);
+                }
+            }
+            // add the last in the list
+            cldsAsdcServiceInfoList.add(rawCldsAsdcServiceList.get(rawCldsAsdcServiceList.size() - 1));
+        }
+        return cldsAsdcServiceInfoList;
+    }
+
+    /**
+     * To remove duplicate serviceUUIDs from asdc resources List
+     *
+     * @param rawCldsAsdcResourceList
+     * @return
+     */
+    public List<CldsAsdcResource> removeDuplicateAsdcResourceInstances(List<CldsAsdcResource> rawCldsAsdcResourceList) {
+        List<CldsAsdcResource> cldsAsdcResourceList = null;
+        if (rawCldsAsdcResourceList != null && rawCldsAsdcResourceList.size() > 0) {
+            // sort list
+            Collections.sort(rawCldsAsdcResourceList);
+            // and then take only the resources with the max version (last in the list with the same name)
+            cldsAsdcResourceList = new ArrayList<>();
+            for (int i = 1; i < rawCldsAsdcResourceList.size(); i++) {
+                // compare name with previous - if not equal, then keep the previous (it's the last with that name)
+                CldsAsdcResource prev = rawCldsAsdcResourceList.get(i - 1);
+                if (!rawCldsAsdcResourceList.get(i).getResourceInstanceName().equals(prev.getResourceInstanceName())) {
+                    cldsAsdcResourceList.add(prev);
+                }
+            }
+            // add the last in the list
+            cldsAsdcResourceList.add(rawCldsAsdcResourceList.get(rawCldsAsdcResourceList.size() - 1));
+        }
+        return cldsAsdcResourceList;
+    }
+
+
+    /**
+     * To remove duplicate basic resources with same resourceUUIDs
+     *
+     * @param rawCldsAsdcResourceListBasicList
+     * @return
+     */
+    public List<CldsAsdcResourceBasicInfo> removeDuplicateAsdcResourceBasicInfo(List<CldsAsdcResourceBasicInfo> rawCldsAsdcResourceListBasicList) {
+        List<CldsAsdcResourceBasicInfo> cldsAsdcResourceBasicInfoList = null;
+        if (rawCldsAsdcResourceListBasicList != null && rawCldsAsdcResourceListBasicList.size() > 0) {
+            // sort list
+            Collections.sort(rawCldsAsdcResourceListBasicList);
+            // and then take only the resources with the max version (last in the list with the same name)
+            cldsAsdcResourceBasicInfoList = new ArrayList<>();
+            for (int i = 1; i < rawCldsAsdcResourceListBasicList.size(); i++) {
+                // compare name with previous - if not equal, then keep the previous (it's the last with that name)
+                CldsAsdcResourceBasicInfo prev = rawCldsAsdcResourceListBasicList.get(i - 1);
+                if (!rawCldsAsdcResourceListBasicList.get(i).getName().equals(prev.getName())) {
+                    cldsAsdcResourceBasicInfoList.add(prev);
+                }
+            }
+            // add the last in the list
+            cldsAsdcResourceBasicInfoList.add(rawCldsAsdcResourceListBasicList.get(rawCldsAsdcResourceListBasicList.size() - 1));
+        }
+        return cldsAsdcResourceBasicInfoList;
+    }
+
+    /**
+     * To get ServiceUUID by using serviceInvariantUUID
+     *
+     * @param invariantID
+     * @return
+     * @throws Exception
+     */
+    public String getServiceUUIDFromServiceInvariantID(String invariantID) throws Exception {
+        String serviceUUID = "";
+        String responseStr = getAsdcServicesInformation(null);
+        List<CldsAsdcServiceInfo> rawCldsAsdcServicesList = getCldsAsdcServicesListFromJson(responseStr);
+        List<CldsAsdcServiceInfo> cldsAsdcServicesList = removeDuplicateServices(rawCldsAsdcServicesList);
+        if (cldsAsdcServicesList != null && cldsAsdcServicesList.size() > 0) {
+            for (CldsAsdcServiceInfo currCldsAsdcServiceInfo : cldsAsdcServicesList) {
+                if (currCldsAsdcServiceInfo != null && currCldsAsdcServiceInfo.getInvariantUUID() != null
+                        && currCldsAsdcServiceInfo.getInvariantUUID().equalsIgnoreCase(invariantID)) {
+                    serviceUUID = currCldsAsdcServiceInfo.getUuid();
+                    break;
+                }
+            }
+        }
+        return serviceUUID;
+    }
+
+    /**
+     * To get CldsAsdsServiceInfo class by parsing json string
+     *
+     * @param jsonStr
+     * @return
+     * @throws JsonParseException
+     * @throws JsonMappingException
+     * @throws IOException
+     */
+    public List<CldsAsdcServiceInfo> getCldsAsdcServicesListFromJson(String jsonStr) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        if (StringUtils.isBlank(jsonStr)) {
+            return null;
+        }
+        return objectMapper.readValue(jsonStr, objectMapper.getTypeFactory().constructCollectionType(List.class, CldsAsdcServiceInfo.class));
+    }
+
+    /**
+     * To get List<CldsAsdcResourceBasicInfo> class by parsing json string
+     *
+     * @param jsonStr
+     * @return
+     * @throws JsonParseException
+     * @throws JsonMappingException
+     * @throws IOException
+     */
+    public List<CldsAsdcResourceBasicInfo> getAllAsdcResourcesListFromJson(String jsonStr) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        if (StringUtils.isBlank(jsonStr)) {
+            return null;
+        }
+        return objectMapper.readValue(jsonStr, objectMapper.getTypeFactory().constructCollectionType(List.class, CldsAsdcResourceBasicInfo.class));
+    }
+
+    /**
+     * To get CldsAsdsResource class by parsing json string
+     *
+     * @param jsonStr
+     * @return
+     * @throws JsonParseException
+     * @throws JsonMappingException
+     * @throws IOException
+     */
+    public CldsAsdcResource getCldsAsdcResourceFromJson(String jsonStr) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(jsonStr, CldsAsdcResource.class);
+    }
+
+    /**
+     * To get CldsAsdcServiceDetail by parsing json string
+     *
+     * @param jsonStr
+     * @return
+     * @throws JsonParseException
+     * @throws JsonMappingException
+     * @throws IOException
+     */
+    public CldsAsdcServiceDetail getCldsAsdcServiceDetailFromJson(String jsonStr) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(jsonStr, CldsAsdcServiceDetail.class);
+    }
+
+    /**
+     * To upload artifact to asdc based on serviceUUID and resourcename on url
+     * @param prop
+     * @param userid
+     * @param url
+     * @param formatttedAsdcReq
+     * @return
+     * @throws Exception
+     */
+    public String uploadArtifactToAsdc(ModelProperties prop, String userid, String url, String formatttedAsdcReq) throws Exception {
+        logger.info("userid=" + userid);
+        String md5Text = SdcReq.calculateMD5ByString(formatttedAsdcReq);
+        byte[] postData = SdcReq.stringToByteArray(formatttedAsdcReq);
+        int postDataLength = postData.length;
+        HttpURLConnection conn = getAsdcHttpUrlConnection(userid, postDataLength, url, md5Text);
+        try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
+            wr.write(postData);
+        }
+        boolean requestFailed = true;
+        int responseCode = conn.getResponseCode();
+        logger.info("responseCode=" + responseCode);
+        if (responseCode == 200) {
+            requestFailed = false;
+        }
+
+        String responseStr = getResponse(conn);
+        if (responseStr != null) {
+            if (requestFailed) {
+                logger.error("requestFailed - responseStr=" + responseStr);
+                throw new Exception(responseStr);
+            }
+        }
+        return responseStr;
+    }
+
+    private HttpURLConnection getAsdcHttpUrlConnection(String userid, int postDataLength, String url, String md5Text) throws IOException {
+        logger.info("userid=" + userid);
+        String basicAuth = SdcReq.getAsdcBasicAuth(refProp);
+        String asdcXONAPInstanceID = refProp.getStringValue("asdc.asdcX-ONAP-InstanceID");
+        URL urlObj = new URL(url);
+        HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
+        conn.setDoOutput(true);
+        conn.setRequestProperty("X-ONAP-InstanceID", asdcXONAPInstanceID);
+        conn.setRequestProperty("Authorization", basicAuth);
+        conn.setRequestProperty("Content-Type", "application/json");
+        conn.setRequestProperty("Content-MD5", md5Text);
+        conn.setRequestProperty("HTTP_CSP_USERID", userid);
+        conn.setRequestMethod("POST");
+        conn.setRequestProperty("charset", "utf-8");
+        conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
+        conn.setUseCaches(false);
+        return conn;
+    }
+
+    private String getResponse(HttpURLConnection conn) throws IOException {
+        try (InputStream is = getInputStream(conn)) {
+            if (is != null) {
+                try (BufferedReader in = new BufferedReader(new InputStreamReader(is))) {
+                    StringBuffer response = new StringBuffer();
+                    String inputLine;
+                    while ((inputLine = in.readLine()) != null) {
+                        response.append(inputLine);
+                    }
+                    return response.toString();
+                }
+            }
+        }
+        return null;
+    }
+
+    private InputStream getInputStream(HttpURLConnection conn) throws IOException {
+        InputStream inStream = conn.getErrorStream();
+        if (inStream == null) {
+            inStream = conn.getInputStream();
+        }
+        return inStream;
+    }
+
+
+    public CldsDBServiceCache getCldsDBServiceCacheUsingCldsServiceData(CldsServiceData cldsServiceData) throws IOException {
+        CldsDBServiceCache cldsDbServiceCache = new CldsDBServiceCache();
+        cldsDbServiceCache.setCldsDataInstream(cldsServiceData);
+        cldsDbServiceCache.setInvariantId(cldsServiceData.getServiceInvariantUUID());
+        cldsDbServiceCache.setServiceId(cldsServiceData.getServiceUUID());
+        return cldsDbServiceCache;
+    }
+
+    public boolean isCldsAsdcCacheDataExpired(CldsServiceData cldsServiceData) throws Exception {
+        boolean expired = false;
+        if (cldsServiceData != null && cldsServiceData.getServiceUUID() != null) {
+            String cachedServiceUUID = cldsServiceData.getServiceUUID();
+            String latestServiceUUID = getServiceUUIDFromServiceInvariantID(cldsServiceData.getServiceInvariantUUID());
+            String defaultRecordAge = refProp.getStringValue("CLDS_SERVICE_CACHE_MAX_SECONDS");
+            if ((!cachedServiceUUID.equalsIgnoreCase(latestServiceUUID)) ||
+                    (cldsServiceData.getAgeOfRecord() != null && cldsServiceData.getAgeOfRecord() > Long.parseLong(defaultRecordAge))) {
+                expired = true;
+            }
+        } else {
+            expired = true;
+        }
+        return expired;
+    }
+
+    public CldsServiceData getCldsServiceDataWithAlarmConditions(String invariantServiceUUID) throws Exception {
+        String url = refProp.getStringValue("asdc.serviceUrl");
+        String catalogUrl = refProp.getStringValue("asdc.catalog.url");
+        String serviceUUID = getServiceUUIDFromServiceInvariantID(invariantServiceUUID);
+        String serviceDetailUrl = url + "/" + serviceUUID + "/metadata";
+        String responseStr = getCldsServicesOrResourcesBasedOnURL(serviceDetailUrl, false);
+        ObjectMapper objectMapper = new ObjectMapper();
+        CldsServiceData cldsServiceData = new CldsServiceData();
+        if (responseStr != null) {
+            CldsAsdcServiceDetail cldsAsdcServiceDetail = objectMapper.readValue(responseStr, CldsAsdcServiceDetail.class);
+            cldsServiceData.setServiceUUID(cldsAsdcServiceDetail.getUuid());
+            cldsServiceData.setServiceInvariantUUID(cldsAsdcServiceDetail.getInvariantUUID());
+
+            // To remove  duplicate  resources from serviceDetail and add valid vfs to service
+            if (cldsAsdcServiceDetail != null && cldsAsdcServiceDetail.getResources() != null) {
+                List<CldsAsdcResource> cldsAsdcResourceList = removeDuplicateAsdcResourceInstances(cldsAsdcServiceDetail.getResources());
+                if (cldsAsdcResourceList != null && cldsAsdcResourceList.size() > 0) {
+                    List<CldsVfData> cldsVfDataList = new ArrayList<>();
+                    for (CldsAsdcResource currCldsAsdcResource : cldsAsdcResourceList) {
+                        if (currCldsAsdcResource != null && currCldsAsdcResource.getResoucreType() != null && currCldsAsdcResource.getResoucreType().equalsIgnoreCase("VF")) {
+                            CldsVfData currCldsVfData = new CldsVfData();
+                            currCldsVfData.setVfName(currCldsAsdcResource.getResourceInstanceName());
+                            currCldsVfData.setVfInvariantResourceUUID(currCldsAsdcResource.getResourceInvariantUUID());
+                            cldsVfDataList.add(currCldsVfData);
+                        }
+                    }
+                    cldsServiceData.setCldsVfs(cldsVfDataList);
+                    // For each vf in the list , add all vfc's
+                    getAllVfcForVfList(cldsVfDataList, catalogUrl);
+                    logger.info("value of cldsServiceData:" + cldsServiceData);
+                    logger.info("value of cldsServiceData:" + cldsServiceData.getServiceInvariantUUID());
+                }
+            }
+        }
+        return cldsServiceData;
+    }
+
+    /**
+     * @param cldsVfDataList
+     * @throws IOException
+     */
+    private void getAllVfcForVfList(List<CldsVfData> cldsVfDataList, String catalogUrl) throws IOException {
+        // todo : refact this..
+        if (cldsVfDataList != null && cldsVfDataList.size() > 0) {
+            List<CldsAsdcResourceBasicInfo> allAsdcResources = getAllAsdcResources();
+            String resourceVFType = "VF";
+            List<CldsAsdcResourceBasicInfo> allVfResources = getAllAsdcVForVFCResourcesBasedOnResourceType(resourceVFType, allAsdcResources);
+            String resourceVFCType = "VFC";
+            List<CldsAsdcResourceBasicInfo> allVfcResources = getAllAsdcVForVFCResourcesBasedOnResourceType(resourceVFCType, allAsdcResources);
+            for (CldsVfData currCldsVfData : cldsVfDataList) {
+                if (currCldsVfData != null && currCldsVfData.getVfInvariantResourceUUID() != null) {
+                    String resourceUUID = getResourceUUIDFromResourceInvariantUUID(currCldsVfData.getVfInvariantResourceUUID(), allVfResources);
+                    if (resourceUUID != null) {
+                        String vfResourceUUIDUrl = catalogUrl + "resources" + "/" + resourceUUID + "/metadata";
+                        String vfResponse = getCldsServicesOrResourcesBasedOnURL(vfResourceUUIDUrl, false);
+                        if (vfResponse != null) {
+                            List<CldsVfcData> vfcDataListFromVfResponse = getVFCDataListFromVfResponse(vfResponse);
+                            if (vfcDataListFromVfResponse != null) {
+                                currCldsVfData.setCldsVfcs(vfcDataListFromVfResponse);
+                                if (vfcDataListFromVfResponse.size() > 0) {
+                                    // To get artifacts for every VFC and get alarm conditions from artifact
+                                    for (CldsVfcData currCldsVfcData : vfcDataListFromVfResponse) {
+                                        if (currCldsVfcData != null && currCldsVfcData.getVfcInvariantResourceUUID() != null) {
+                                            String resourceVFCUUID = getResourceUUIDFromResourceInvariantUUID(currCldsVfcData.getVfcInvariantResourceUUID(), allVfcResources);
+                                            if (resourceVFCUUID != null) {
+                                                String vfcResourceUUIDUrl = catalogUrl + "resources" + "/" + resourceVFCUUID + "/metadata";
+                                                String vfcResponse = getCldsServicesOrResourcesBasedOnURL(vfcResourceUUIDUrl, false);
+                                                if (vfcResponse != null) {
+                                                    List<CldsAlarmCondition> alarmCondtionsFromVfc = getAlarmCondtionsFromVfc(vfcResponse);
+                                                    currCldsVfcData.setCldsAlarmConditions(alarmCondtionsFromVfc);
+                                                }
+                                            } else {
+                                                logger.info("No resourceVFC UUID found for given invariantID:" + currCldsVfcData.getVfcInvariantResourceUUID());
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    } else {
+                        logger.info("No resourceUUID found for given invariantREsourceUUID:" + currCldsVfData.getVfInvariantResourceUUID());
+                    }
+                }
+            }
+        }
+    }
+
+    private List<CldsVfcData> getVFCDataListFromVfResponse(String vfResponse) throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode vfResponseNode = (ObjectNode) mapper.readTree(vfResponse);
+        ArrayNode vfcArrayNode = (ArrayNode) vfResponseNode.get("resources");
+        List<CldsVfcData> cldsVfcDataList = new ArrayList<>();
+        if (vfcArrayNode != null && vfcArrayNode.size() > 0) {
+            for (int index = 0; index < vfcArrayNode.size(); index++) {
+                CldsVfcData currCldsVfcData = new CldsVfcData();
+                ObjectNode currVfcNode = (ObjectNode) vfcArrayNode.get(index);
+                TextNode resourceTypeNode = (TextNode) currVfcNode.get("resoucreType");
+                if (resourceTypeNode != null && resourceTypeNode.textValue().equalsIgnoreCase("VFC")) {
+                    TextNode vfcResourceName = (TextNode) currVfcNode.get("resourceInstanceName");
+                    TextNode vfcInvariantResourceUUID = (TextNode) currVfcNode.get("resourceInvariantUUID");
+                    currCldsVfcData.setVfcName(vfcResourceName.textValue());
+                    currCldsVfcData.setVfcInvariantResourceUUID(vfcInvariantResourceUUID.textValue());
+                    cldsVfcDataList.add(currCldsVfcData);
+                }
+            }
+        }
+        return cldsVfcDataList;
+    }
+
+    private String removeUnwantedBracesFromString(String id) {
+        if (id != null && id.contains("\"")) {
+            id = id.replaceAll("\"", "");
+        }
+        return id;
+    }
+
+    private List<CldsAlarmCondition> getAlarmCondtionsFromVfc(String vfcResponse) throws IOException {
+        List<CldsAlarmCondition> cldsAlarmConditionList = new ArrayList<>();
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode vfcResponseNode = (ObjectNode) mapper.readTree(vfcResponse);
+        ArrayNode artifactsArrayNode = (ArrayNode) vfcResponseNode.get("artifacts");
+
+        if (artifactsArrayNode != null && artifactsArrayNode.size() > 0) {
+            for (int index = 0; index < artifactsArrayNode.size(); index++) {
+                ObjectNode currArtifactNode = (ObjectNode) artifactsArrayNode.get(index);
+                TextNode artifactUrlNode = (TextNode) currArtifactNode.get("artifactURL");
+                if (artifactUrlNode != null) {
+                    String responsesFromArtifactUrl = getResponsesFromArtifactUrl(artifactUrlNode.textValue());
+                    cldsAlarmConditionList.addAll(parseCsvToGetAlarmConditions(responsesFromArtifactUrl));
+                    logger.info(responsesFromArtifactUrl);
+                }
+            }
+        }
+        return cldsAlarmConditionList;
+    }
+
+    private List<CldsAlarmCondition> parseCsvToGetAlarmConditions(String allAlarmCondsValues) throws IOException {
+        List<CldsAlarmCondition> cldsAlarmConditionList = new ArrayList<>();
+        Reader alarmReader = new StringReader(allAlarmCondsValues);
+        Iterable<CSVRecord> records = CSVFormat.RFC4180.parse(alarmReader);
+        if (records != null) {
+            Iterator<CSVRecord> it = records.iterator();
+            if (it.hasNext()) {
+                it.next();
+            }
+            it.forEachRemaining(record -> processRecord(cldsAlarmConditionList, record));
+        }
+        return cldsAlarmConditionList;
+    }
+
+    private void processRecord(List<CldsAlarmCondition> cldsAlarmConditionList, CSVRecord record) {
+        if (record == null) {
+            return;
+        }
+        if (record.size() < 5) {
+            logger.debug("invalid csv alarm Record,total columns less than 5: " + record);
+            return;
+        }
+        if (StringUtils.isBlank(record.get(1)) || StringUtils.isBlank(record.get(3)) || StringUtils.isBlank(record.get(4))) {
+            logger.debug("invalid csv alarm Record,one of column is having blank value : " + record);
+            return;
+        }
+        CldsAlarmCondition cldsAlarmCondition = new CldsAlarmCondition();
+        cldsAlarmCondition.setEventSourceType(record.get(1));
+        cldsAlarmCondition.setAlarmConditionKey(record.get(3));
+        cldsAlarmCondition.setSeverity(record.get(4));
+        cldsAlarmConditionList.add(cldsAlarmCondition);
+    }
+
+    private String getResponsesFromArtifactUrl(String artifactsUrl) throws IOException {
+        String hostUrl = refProp.getStringValue("asdc.hostUrl");
+        artifactsUrl = artifactsUrl.replaceAll("\"", "");
+        String artifactUrl = hostUrl + artifactsUrl;
+        logger.info("value of artifactURl:" + artifactUrl);
+        String currArtifactResponse = getCldsServicesOrResourcesBasedOnURL(artifactUrl, true);
+        logger.info("value of artifactResponse:" + currArtifactResponse);
+        return currArtifactResponse;
+    }
+
+    /**
+     * Service to services/resources/artifacts from asdc.Pass alarmConditions as true to get alarmconditons from artifact url and else it is false
+     *
+     * @param url
+     * @param alarmConditions
+     * @return
+     * @throws IOException
+     */
+    private String getCldsServicesOrResourcesBasedOnURL(String url, boolean alarmConditions) throws IOException {
+        String responseStr;
+        try {
+            url = removeUnwantedBracesFromString(url);
+            URL urlObj = new URL(url);
+
+            HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
+            String basicAuth = SdcReq.getAsdcBasicAuth(refProp);
+            conn.setRequestProperty("X-ONAP-InstanceID", "CLAMP-Tool");
+            conn.setRequestProperty("Authorization", basicAuth);
+            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+            conn.setRequestMethod("GET");
+
+            int responseCode = conn.getResponseCode();
+            logger.info("responseCode=" + responseCode);
+
+            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            StringBuffer response = new StringBuffer();
+            String inputLine;
+            while ((inputLine = in.readLine()) != null) {
+                response.append(inputLine);
+                if (alarmConditions) {
+                    response.append("\n");
+                }
+            }
+            responseStr = response.toString();
+            in.close();
+        } catch (Exception e) {
+            logger.error("Exception occured :" + e.getMessage());
+            throw e;
+        }
+        return responseStr;
+    }
+
+    /**
+     * To create properties object by using cldsServicedata
+     *
+     * @param globalProps
+     * @param cldsServiceData
+     * @return
+     * @throws IOException
+     */
+    public String createPropertiesObjectByUUID(String globalProps, CldsServiceData cldsServiceData) throws IOException {
+        String totalPropsStr;
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode globalPropsJson;
+        if (cldsServiceData != null && cldsServiceData.getServiceUUID() != null) {
+
+            /**
+             *  Objectnode to save all byservice, byvf , byvfc and byalarm nodes
+             */
+            ObjectNode byIdObjectNode = mapper.createObjectNode();
+            /**
+             * To create vf ResourceUUID node with serviceInvariantUUID
+             *
+             */
+            ObjectNode invariantUUIDObjectNodeWithVF = createVFObjectNodeByServiceInvariantUUID(mapper, cldsServiceData);
+            byIdObjectNode.putPOJO("byService", invariantUUIDObjectNodeWithVF);
+
+            /**
+             *  To create byVf and vfcResourceNode with vfResourceUUID
+             */
+            ObjectNode vfcObjectNodeByVfUUID = createVFCObjectNodeByVfUUID(mapper, cldsServiceData.getCldsVfs());
+            byIdObjectNode.putPOJO("byVf", vfcObjectNodeByVfUUID);
+
+
+            /**
+             *  To create byVfc and alarmCondition with vfcResourceUUID
+             */
+            ObjectNode vfcResourceUUIDObjectNode = mapper.createObjectNode();
+            if (cldsServiceData.getCldsVfs() != null && cldsServiceData.getCldsVfs().size() > 0) {
+                for (CldsVfData currCldsVfData : cldsServiceData.getCldsVfs()) {
+                    if (currCldsVfData != null) {
+                        createAlarmCondObjectNodeByVfcUUID(mapper, vfcResourceUUIDObjectNode, currCldsVfData.getCldsVfcs());
+                    }
+                }
+            }
+            byIdObjectNode.putPOJO("byVfc", vfcResourceUUIDObjectNode);
+
+            /**
+             *  To create byAlarmCondition  with alarmConditionKey
+             */
+            List<CldsAlarmCondition> allAlarmConditions = getAllAlarmConditionsFromCldsServiceData(cldsServiceData);
+            ObjectNode alarmCondObjectNodeByAlarmKey = createAlarmCondObjectNodeByAlarmKey(mapper, allAlarmConditions);
+
+            byIdObjectNode.putPOJO("byAlarmCondition", alarmCondObjectNodeByAlarmKey);
+
+            globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
+
+            globalPropsJson.putPOJO("shared", byIdObjectNode);
+            logger.info("valuie of objNode:" + globalPropsJson);
+        } else {
+            /**
+             *  to create json with total properties when no serviceUUID passed
+             */
+            globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
+        }
+        totalPropsStr = globalPropsJson.toString();
+        return totalPropsStr;
+    }
+
+    private List<CldsAlarmCondition> getAllAlarmConditionsFromCldsServiceData(CldsServiceData cldsServiceData) {
+        List<CldsAlarmCondition> alarmCondList = new ArrayList<>();
+        if (cldsServiceData != null && cldsServiceData.getCldsVfs() != null && cldsServiceData.getCldsVfs().size() > 0) {
+            for (CldsVfData currCldsVfData : cldsServiceData.getCldsVfs()) {
+                if (currCldsVfData != null && currCldsVfData.getCldsVfcs() != null && currCldsVfData.getCldsVfcs().size() > 0) {
+                    for (CldsVfcData currCldsVfcData : currCldsVfData.getCldsVfcs()) {
+                        if (currCldsVfcData != null && currCldsVfcData.getCldsAlarmConditions() != null && currCldsVfcData.getCldsAlarmConditions().size() > 0) {
+                            for (CldsAlarmCondition currCldsAlarmCondition : currCldsVfcData.getCldsAlarmConditions()) {
+                                if (currCldsAlarmCondition != null) {
+                                    alarmCondList.add(currCldsAlarmCondition);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return alarmCondList;
+    }
+
+    private ObjectNode createAlarmCondObjectNodeByAlarmKey(ObjectMapper mapper, List<CldsAlarmCondition> cldsAlarmCondList) {
+        ObjectNode alarmCondKeyNode = mapper.createObjectNode();
+
+        if (cldsAlarmCondList != null && cldsAlarmCondList.size() > 0) {
+            for (CldsAlarmCondition currCldsAlarmCondition : cldsAlarmCondList) {
+                if (currCldsAlarmCondition != null) {
+                    ObjectNode alarmCondNode = mapper.createObjectNode();
+                    alarmCondNode.put("eventSourceType", currCldsAlarmCondition.getEventSourceType());
+                    alarmCondNode.put("eventSeverity", currCldsAlarmCondition.getSeverity());
+                    alarmCondKeyNode.putPOJO(currCldsAlarmCondition.getAlarmConditionKey(), alarmCondNode);
+                }
+            }
+        } else {
+            ObjectNode alarmCondNode = mapper.createObjectNode();
+            alarmCondNode.put("eventSourceType", "");
+            alarmCondNode.put("eventSeverity", "");
+            alarmCondKeyNode.putPOJO("", alarmCondNode);
+        }
+        return alarmCondKeyNode;
+    }
+
+    private ObjectNode createVFObjectNodeByServiceInvariantUUID(ObjectMapper mapper, CldsServiceData cldsServiceData) {
+        ObjectNode invariantUUIDObjectNode = mapper.createObjectNode();
+        ObjectNode vfObjectNode = mapper.createObjectNode();
+        ObjectNode vfUUIDNode = mapper.createObjectNode();
+        List<CldsVfData> cldsVfsList = cldsServiceData.getCldsVfs();
+        if (cldsVfsList != null && cldsVfsList.size() > 0) {
+            for (CldsVfData currCldsVfData : cldsVfsList) {
+                if (currCldsVfData != null) {
+                    vfUUIDNode.put(currCldsVfData.getVfInvariantResourceUUID(), currCldsVfData.getVfName());
+                }
+            }
+        } else {
+            vfUUIDNode.put("", "");
+        }
+        vfObjectNode.putPOJO("vf", vfUUIDNode);
+        invariantUUIDObjectNode.putPOJO(cldsServiceData.getServiceInvariantUUID(), vfObjectNode);
+        return invariantUUIDObjectNode;
+    }
+
+    private void createAlarmCondObjectNodeByVfcUUID(ObjectMapper mapper, ObjectNode vfcResourceUUIDObjectNode, List<CldsVfcData> cldsVfcDataList) {
+        ObjectNode alarmCondContsObjectNode = mapper.createObjectNode();
+        ObjectNode alarmCondNode = mapper.createObjectNode();
+        //     alarmCondNode.put("", "");
+        if (cldsVfcDataList != null && cldsVfcDataList.size() > 0) {
+            for (CldsVfcData currCldsVfcData : cldsVfcDataList) {
+                if (currCldsVfcData != null) {
+                    if (currCldsVfcData.getCldsAlarmConditions() != null && currCldsVfcData.getCldsAlarmConditions().size() > 0) {
+                        for (CldsAlarmCondition currCldsAlarmCondition : currCldsVfcData.getCldsAlarmConditions()) {
+                            alarmCondNode.put(currCldsAlarmCondition.getAlarmConditionKey(), currCldsAlarmCondition.getAlarmConditionKey());
+                        }
+                        alarmCondContsObjectNode.putPOJO("alarmCondition", alarmCondNode);
+                    }
+                    alarmCondContsObjectNode.putPOJO("alarmCondition", alarmCondNode);
+                    vfcResourceUUIDObjectNode.putPOJO(currCldsVfcData.getVfcInvariantResourceUUID(), alarmCondContsObjectNode);
+                }
+            }
+        } else {
+            alarmCondNode.put("", "");
+            alarmCondContsObjectNode.putPOJO("alarmCondition", alarmCondNode);
+            vfcResourceUUIDObjectNode.putPOJO("", alarmCondContsObjectNode);
+        }
+    }
+
+    private ObjectNode createVFCObjectNodeByVfUUID(ObjectMapper mapper, List<CldsVfData> cldsVfDataList) {
+        ObjectNode vfUUIDObjectNode = mapper.createObjectNode();
+
+        if (cldsVfDataList != null && cldsVfDataList.size() > 0) {
+            for (CldsVfData currCldsVfData : cldsVfDataList) {
+                if (currCldsVfData != null) {
+                    ObjectNode vfcObjectNode = mapper.createObjectNode();
+                    ObjectNode vfcUUIDNode = mapper.createObjectNode();
+                    if (currCldsVfData.getCldsVfcs() != null && currCldsVfData.getCldsVfcs().size() > 0) {
+                        for (CldsVfcData currCldsVfcData : currCldsVfData.getCldsVfcs()) {
+                            vfcUUIDNode.put(currCldsVfcData.getVfcInvariantResourceUUID(), currCldsVfcData.getVfcName());
+                        }
+                    } else {
+                        vfcUUIDNode.put("", "");
+                    }
+                    vfcObjectNode.putPOJO("vfc", vfcUUIDNode);
+                    vfUUIDObjectNode.putPOJO(currCldsVfData.getVfInvariantResourceUUID(), vfcObjectNode);
+                }
+            }
+        } else {
+            ObjectNode vfcUUIDNode = mapper.createObjectNode();
+            vfcUUIDNode.put("", "");
+            ObjectNode vfcObjectNode = mapper.createObjectNode();
+            vfcObjectNode.putPOJO("vfc", vfcUUIDNode);
+            vfUUIDObjectNode.putPOJO("", vfcObjectNode);
+        }
+        return vfUUIDObjectNode;
+    }
+
+    public String getArtifactIdIfArtifactAlreadyExists(CldsAsdcServiceDetail cldsAsdcServiceDetail, String artifactName) {
+        String artifactUUId = null;
+        boolean artifactxists = false;
+        if (cldsAsdcServiceDetail != null && cldsAsdcServiceDetail.getResources() != null && cldsAsdcServiceDetail.getResources().size() > 0) {
+            for (CldsAsdcResource currCldsAsdcResource : cldsAsdcServiceDetail.getResources()) {
+                if (artifactxists) {
+                    break;
+                }
+                if (currCldsAsdcResource != null && currCldsAsdcResource.getArtifacts() != null && currCldsAsdcResource.getArtifacts().size() > 0) {
+                    for (CldsAsdcArtifact currCldsAsdcArtifact : currCldsAsdcResource.getArtifacts()) {
+                        if (currCldsAsdcArtifact != null && currCldsAsdcArtifact.getArtifactName() != null) {
+                            if (currCldsAsdcArtifact.getArtifactName().equalsIgnoreCase(artifactName)) {
+                                artifactUUId = currCldsAsdcArtifact.getArtifactUUID();
+                                artifactxists = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return artifactUUId;
+    }
+
+    public String updateControlLoopStatusToDCAE(String dcaeUrl, String invariantResourceUUID, String invariantServiceUUID, String artifactName) {
+        String baseUrl = refProp.getStringValue("asdc.serviceUrl");
+        String basicAuth = SdcReq.getAsdcBasicAuth(refProp);
+        String postStatusData = "{ \n" +
+                "\"event\" : \"" + "Created" + "\",\n" +
+                "\"serviceUUID\" : \"" + invariantServiceUUID + "\",\n" +
+                "\"resourceUUID\" :\"" + invariantResourceUUID + "\",\n" +
+                "\"artifactName\" : \"" + artifactName + "\",\n" +
+                "} \n";
+        try {
+            String url = baseUrl;
+            if (invariantServiceUUID != null) {
+                url = dcaeUrl + "/closed-loops";
+            }
+            URL urlObj = new URL(url);
+
+            HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
+            conn.setRequestProperty("X-ONAP-InstanceID", "CLAMP-Tool");
+            conn.setRequestProperty("Authorization", basicAuth);
+            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+            conn.setRequestMethod("POST");
+
+            byte[] postData = SdcReq.stringToByteArray(postStatusData);
+            try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
+                wr.write(postData);
+            }
+
+            int responseCode = conn.getResponseCode();
+            logger.info("responseCode=" + responseCode);
+
+            String resp = getResponse(conn);
+            if (resp != null) {
+                return resp;
+            }
+        } catch (Exception e) {
+            logger.error("not able to ger any service information from asdc for uuid:" + invariantServiceUUID);
+        }
+        return "";
+    }
+
+    /**
+     * To get all asdc VF/VFC Resources basic info
+     *
+     * @return
+     * @throws IOException
+     */
+    private List<CldsAsdcResourceBasicInfo> getAllAsdcVForVFCResourcesBasedOnResourceType(String resourceType, List<CldsAsdcResourceBasicInfo> allAsdcResources) throws IOException {
+        List<CldsAsdcResourceBasicInfo> allAsdcVFResources = new ArrayList<>();
+        if (allAsdcResources != null && allAsdcResources.size() > 0) {
+            for (CldsAsdcResourceBasicInfo currResource : allAsdcResources) {
+                if (currResource != null && currResource.getResourceType() != null && currResource.getResourceType().equalsIgnoreCase(resourceType)) {
+                    allAsdcVFResources.add(currResource);
+                }
+            }
+        }
+        return allAsdcVFResources;
+    }
+
+    private String getResourceUUIDFromResourceInvariantUUID(String resourceInvariantUUID, List<CldsAsdcResourceBasicInfo> resourceInfoList) throws IOException {
+        String resourceUUID = null;
+        if (resourceInfoList != null && resourceInfoList.size() > 0) {
+            for (CldsAsdcResourceBasicInfo currResource : resourceInfoList) {
+                if (currResource != null && currResource.getInvariantUUID() != null && currResource.getUuid() != null
+                        && currResource.getInvariantUUID().equalsIgnoreCase(resourceInvariantUUID)) {
+                    resourceUUID = currResource.getUuid();
+                    break;
+                }
+            }
+        }
+        return resourceUUID;
+    }
+
+    /**
+     * To get all asdc Resources basic info
+     *
+     * @return
+     * @throws IOException
+     */
+    private List<CldsAsdcResourceBasicInfo> getAllAsdcResources() throws IOException {
+        String catalogUrl = refProp.getStringValue("asdc.catalog.url");
+        String resourceUrl = catalogUrl + "resources";
+        String allAsdcResources = getCldsServicesOrResourcesBasedOnURL(resourceUrl, false);
+        List<CldsAsdcResourceBasicInfo> allAsdcResourceBasicInfo = getAllAsdcResourcesListFromJson(allAsdcResources);
+        return removeDuplicateAsdcResourceBasicInfo(allAsdcResourceBasicInfo);
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/SdcSendReqDelegate.java b/src/main/java/org/onap/clamp/clds/client/SdcSendReqDelegate.java
new file mode 100644 (file)
index 0000000..93b6e95
--- /dev/null
@@ -0,0 +1,138 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.client.req.SdcReq;
+import org.onap.clamp.clds.model.CldsAsdcServiceDetail;
+import org.onap.clamp.clds.model.DcaeEvent;
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * Send control loop model to dcae proxy.
+ */
+public class SdcSendReqDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = LoggerFactory.getLogger(SdcSendReqDelegate.class);
+
+    @Autowired
+    private RefProp refProp;
+
+    @Autowired
+    private SdcCatalogServices asdcCatalogServices;
+
+    private String baseUrl;
+    private String artifactType;
+    private String locationArtifactType;
+    private String artifactLabel;
+    private String locationArtifactLabel;
+
+    /**
+     * Perform activity.  Send to asdc proxy.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String userid = (String) execution.getVariable("userid");
+        logger.info("userid=" + userid);
+        String docText = (String) execution.getVariable("docText");
+        String artifactName = execution.getVariable("controlName") + DcaeEvent.ARTIFACT_NAME_SUFFIX;
+        execution.setVariable("artifactName", artifactName);
+        getAsdcAttributes();
+        ModelProperties prop = ModelProperties.create(execution);
+        String bluprintPayload = SdcReq.formatBlueprint(refProp, prop, docText);
+        String formatttedAsdcReq = SdcReq.formatAsdcReq(bluprintPayload, artifactName, artifactLabel, artifactType);
+        if (formatttedAsdcReq != null) {
+            execution.setVariable("formattedArtifactReq", formatttedAsdcReq.getBytes());
+        }
+        List<String> asdcReqUrlsList = SdcReq.getAsdcReqUrlsList(prop, baseUrl, asdcCatalogServices, execution);
+
+        String asdcLocationsPayload = SdcReq.formatAsdcLocationsReq(prop, artifactName);
+        String locationArtifactName = execution.getVariable("controlName") + "-location.json";
+        String formattedAsdcLocationReq = SdcReq.formatAsdcReq(asdcLocationsPayload, locationArtifactName, locationArtifactLabel, locationArtifactType);
+        if (formattedAsdcLocationReq != null) {
+            execution.setVariable("formattedLocationReq", formattedAsdcLocationReq.getBytes());
+        }
+        String serviceInvariantUUID = getServiceInvariantUUIDFromProps(prop);
+        uploadToAsdc(prop, serviceInvariantUUID, userid, asdcReqUrlsList, formatttedAsdcReq, formattedAsdcLocationReq, artifactName, locationArtifactName);
+    }
+
+    private String getServiceInvariantUUIDFromProps(ModelProperties props) {
+        String invariantUUID = "";
+        Global globalProps = props.getGlobal();
+        if (globalProps != null) {
+            if (globalProps.getService() != null) {
+                invariantUUID = globalProps.getService();
+            }
+        }
+        return invariantUUID;
+    }
+
+    private void uploadToAsdc(ModelProperties prop, String serviceInvariantUUID, String userid, List<String> asdcReqUrlsList, String formatttedAsdcReq, String formattedAsdcLocationReq, String artifactName, String locationArtifactName) throws Exception {
+        logger.info("userid=" + userid);
+        if (asdcReqUrlsList != null && asdcReqUrlsList.size() > 0) {
+            for (String url : asdcReqUrlsList) {
+                if (url != null) {
+                    String originalServiceUUID = asdcCatalogServices.getServiceUUIDFromServiceInvariantID(serviceInvariantUUID);
+                    logger.info("ServiceUUID used before upload in url:" + originalServiceUUID);
+                    String asdcServicesInformation = asdcCatalogServices.getAsdcServicesInformation(originalServiceUUID);
+                    CldsAsdcServiceDetail cldsAsdcServiceDetail = asdcCatalogServices.getCldsAsdcServiceDetailFromJson(asdcServicesInformation);
+                    String uploadedArtifactUUID = asdcCatalogServices.getArtifactIdIfArtifactAlreadyExists(cldsAsdcServiceDetail, artifactName);
+                    // Upload artifacts to asdc
+                    String updateUrl = uploadedArtifactUUID != null ? url + "/" + uploadedArtifactUUID : url;
+                    String responseStr = asdcCatalogServices.uploadArtifactToAsdc(prop, userid, updateUrl, formatttedAsdcReq);
+                    logger.info("value of asdc Response of uploading to asdc :" + responseStr);
+                    String updatedServiceUUID = asdcCatalogServices.getServiceUUIDFromServiceInvariantID(serviceInvariantUUID);
+                    if (!originalServiceUUID.equalsIgnoreCase(updatedServiceUUID)) {
+                        url = url.replace(originalServiceUUID, updatedServiceUUID);
+                    }
+                    logger.info("ServiceUUID used after upload in ulr:" + updatedServiceUUID);
+                    asdcServicesInformation = asdcCatalogServices.getAsdcServicesInformation(updatedServiceUUID);
+                    cldsAsdcServiceDetail = asdcCatalogServices.getCldsAsdcServiceDetailFromJson(asdcServicesInformation);
+                    uploadedArtifactUUID = asdcCatalogServices.getArtifactIdIfArtifactAlreadyExists(cldsAsdcServiceDetail, locationArtifactName);
+                    //  To send location information also to asdc
+                    updateUrl = uploadedArtifactUUID != null ? url + "/" + uploadedArtifactUUID : url;
+                    responseStr = asdcCatalogServices.uploadArtifactToAsdc(prop, userid, updateUrl, formattedAsdcLocationReq);
+                    logger.info("value of asdc Response of uploading location to asdc :" + responseStr);
+                }
+            }
+        }
+    }
+
+    private void getAsdcAttributes() {
+        baseUrl = refProp.getStringValue("asdc.serviceUrl");
+        artifactLabel = refProp.getStringValue("asdc.artifactLabel");
+        locationArtifactLabel = refProp.getStringValue("asdc.locationArtifactLabel");
+        artifactType = refProp.getStringValue("asdc.artifactType");
+        locationArtifactType = refProp.getStringValue("asdc.locationArtifactType");
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDelegate.java b/src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDelegate.java
new file mode 100644 (file)
index 0000000..90e259f
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.client.req.StringMatchPolicyReq;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.UUID;
+import java.util.logging.Logger;
+
+
+/**
+ * Send String Match info to policy api.
+ */
+public class StringMatchPolicyDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(StringMatchPolicyDelegate.class.getName());
+
+    @Autowired
+    private PolicyClient policyClient;
+    
+    @Autowired
+    private RefProp refProp;
+
+    /**
+     * Perform activity.  Send String Match info to policy api.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String stringMatchPolicyRequestUuid = UUID.randomUUID().toString();
+        execution.setVariable("stringMatchPolicyRequestUuid", stringMatchPolicyRequestUuid);
+
+        ModelProperties prop = ModelProperties.create(execution);
+        String policyJson = StringMatchPolicyReq.format(refProp, prop);
+        String responseMessage = policyClient.sendMicroService(policyJson, prop, stringMatchPolicyRequestUuid);
+        if (responseMessage != null) {
+            execution.setVariable("stringMatchPolicyResponseMessage", responseMessage.getBytes());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDeleteDelegate.java b/src/main/java/org/onap/clamp/clds/client/StringMatchPolicyDeleteDelegate.java
new file mode 100644 (file)
index 0000000..9efd358
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client;
+
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.StringMatch;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.logging.Logger;
+
+
+/**
+ * Delete String Match Policy via policy api.
+ */
+public class StringMatchPolicyDeleteDelegate implements JavaDelegate {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(StringMatchPolicyDeleteDelegate.class.getName());
+
+    @Autowired
+    private PolicyClient policyClient;
+
+    /**
+     * Perform activity.  Delete String Match Policy via policy api.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        ModelProperties prop = ModelProperties.create(execution);
+        StringMatch stringMatch = prop.getStringMatch();
+        prop.setCurrentModelElementId(stringMatch.getId());
+
+        policyClient.deleteMicrosService(prop);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/TcaPolicyDelegate.java b/src/main/java/org/onap/clamp/clds/client/TcaPolicyDelegate.java
new file mode 100644 (file)
index 0000000..58843d9
--- /dev/null
@@ -0,0 +1,53 @@
+package org.onap.clamp.clds.client;
+
+import java.util.UUID;
+import java.util.logging.Logger;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.onap.clamp.clds.client.req.TcaMPolicyReq;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.Tca;
+import org.onap.clamp.clds.model.refprop.RefProp;
+
+
+/**
+ * Send Tca info to policy api. 
+ * 
+ *
+ */
+public class TcaPolicyDelegate implements JavaDelegate {
+       // currently uses the java.util.logging.Logger like the Camunda engine
+       private static final Logger logger = Logger.getLogger(TcaPolicyDelegate.class.getName());
+       
+       @Autowired
+       private RefProp refProp;
+       
+       @Autowired PolicyClient policyClient;
+       
+       /**
+        * Perform activity.  Send Tca info to policy api.
+        * 
+        * @param execution
+        */
+       public void execute(DelegateExecution execution) throws Exception {             
+               String tcaPolicyRequestUuid = UUID.randomUUID().toString();
+               execution.setVariable("tcaPolicyRequestUuid", tcaPolicyRequestUuid);
+
+               ModelProperties prop = ModelProperties.create(execution);
+               Tca tca = prop.getTca();
+               if(tca.isFound()){
+                       String policyJson = TcaMPolicyReq.formatTca(refProp, prop);
+                       String responseMessage = policyClient.sendMicroService(policyJson, prop, tcaPolicyRequestUuid);
+                       if(responseMessage != null)
+                       {
+                               execution.setVariable("tcaPolicyResponseMessage", responseMessage.getBytes());          
+                       }
+               }
+       }
+       
+       
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/TcaPolicyDeleteDelegate.java b/src/main/java/org/onap/clamp/clds/client/TcaPolicyDeleteDelegate.java
new file mode 100644 (file)
index 0000000..31e05d7
--- /dev/null
@@ -0,0 +1,48 @@
+package org.onap.clamp.clds.client;
+
+import java.util.logging.Logger;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.Tca;
+import org.onap.clamp.clds.model.refprop.RefProp;
+
+
+/**
+ * Delete Tca Policy via policy api. 
+ * 
+ *
+ */
+public class TcaPolicyDeleteDelegate implements JavaDelegate {
+       // currently uses the java.util.logging.Logger like the Camunda engine
+       private static final Logger logger = Logger.getLogger(TcaPolicyDeleteDelegate.class.getName());
+       
+       @Autowired
+       private PolicyClient policyClient;
+       
+       /**
+        * Perform activity.  Delete Tca Policy via policy api.
+        * 
+        * @param execution
+        */
+       public void execute(DelegateExecution execution) throws Exception {             
+
+               ModelProperties prop = ModelProperties.create(execution);
+               Tca tca = prop.getTca();
+               if(tca.isFound()){
+                       prop.setCurrentModelElementId(tca.getId());
+       
+                       String responseMessage = policyClient.deleteMicrosService(prop); 
+                       if(responseMessage != null)
+                       {
+                               execution.setVariable("tcaPolicyDeleteResponseMessage", responseMessage.getBytes());
+                       }
+               }
+       }
+       
+       
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/req/DcaeReq.java b/src/main/java/org/onap/clamp/clds/client/req/DcaeReq.java
new file mode 100644 (file)
index 0000000..35d6c9f
--- /dev/null
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.StringMatch;
+import org.onap.clamp.clds.model.refprop.RefProp;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Logger;
+
+
+/**
+ * Construct a DCAE request given CLDS objects.
+ */
+public class DcaeReq {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(DcaeReq.class.getName());
+
+    /**
+     * Format DCAE request.
+     *
+     * @param refProp
+     * @param prop
+     * @return
+     * @throws IOException
+     * @throws JsonMappingException
+     * @throws JsonParseException
+     */
+    public static String format(RefProp refProp, ModelProperties prop) throws IOException {
+        Global globalProp = prop.getGlobal();
+        String service = globalProp.getService();
+
+        StringMatch smProp = prop.getStringMatch();
+        prop.setCurrentModelElementId(smProp.getId());
+
+        ObjectNode rootNode = (ObjectNode) refProp.getJsonTemplate("dcae.template");
+
+        //   "properties":{
+        ObjectNode properties = rootNode.with("properties");
+        //     "service_name":
+        properties.put("service_name", globalProp.getService());
+        //     "service_ids":[
+        List<String> service_ids = refProp.decodeToList("dcae.decode.service_ids", globalProp.getService());
+        JsonUtil.addArrayField(properties, "service_ids", service_ids);
+        //     "vnf_ids":[
+        JsonUtil.addArrayField(properties, "vnf_ids", globalProp.getResourceVf());
+        //     "location_ids":[
+        JsonUtil.addArrayField(properties, "location_ids", globalProp.getLocation());
+
+        //   "template":{
+        ObjectNode template = rootNode.with("template");
+        //     "string_matching":{
+        ObjectNode string_matching = template.with("string_matching");
+        //       "dcae":{
+        ObjectNode dcae = string_matching.with("dcae");
+
+        dcae.put("inputTopic", smProp.getTopicSubscribes());
+        dcae.put("outputTopic", smProp.getTopicPublishes());
+        dcae.put("closedLoopControlName", prop.getControlName());
+        dcae.put("policyName", prop.getCurrentPolicyScopeAndPolicyName());
+
+        //         "serviceConfigurations":[
+        StringMatchPolicyReq.appendServiceConfigurations(refProp, service, dcae, smProp);
+
+        String dcaeReq = rootNode.toString();
+        logger.info("dcaeReq=" + dcaeReq);
+        return dcaeReq;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/req/JsonUtil.java b/src/main/java/org/onap/clamp/clds/client/req/JsonUtil.java
new file mode 100644 (file)
index 0000000..6aba683
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Utility methods for formatting json
+ */
+public class JsonUtil {
+
+    /**
+     * Add list of values to json array node
+     *
+     * @param list
+     * @param node
+     */
+    public static void addListToArrayNode(List<String> list, ArrayNode node) {
+        for (String aList : list) {
+            node.add(aList);
+        }
+    }
+
+    /**
+     * Add list of values to json array node
+     *
+     * @param json
+     * @param name
+     * @param list
+     */
+    public static void addArrayField(JsonNode json, String name, List<String> list) {
+        if (list != null) {
+            ArrayNode node = (ArrayNode) json.withArray(name);
+            for (String aList : list) {
+                node.add(aList);
+            }
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/req/OperationalPolicyReq.java b/src/main/java/org/onap/clamp/clds/client/req/OperationalPolicyReq.java
new file mode 100644 (file)
index 0000000..90b9ff8
--- /dev/null
@@ -0,0 +1,299 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.Policy;
+import org.onap.clamp.clds.model.prop.PolicyItem;
+import org.openecomp.policy.controlloop.policy.TargetType;
+import org.openecomp.policy.controlloop.policy.PolicyResult;
+import org.openecomp.policy.controlloop.policy.Target;
+import org.openecomp.policy.controlloop.policy.builder.BuilderException;
+import org.openecomp.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
+import org.openecomp.policy.controlloop.policy.builder.Message;
+import org.openecomp.policy.controlloop.policy.builder.Results;
+import org.openecomp.policy.api.AttributeType;
+import org.openecomp.policy.asdc.Resource;
+import org.openecomp.policy.asdc.ResourceType;
+import org.openecomp.policy.asdc.Service;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.jboss.resteasy.spi.BadRequestException;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.logging.Logger;
+
+
+/**
+ * Construct an Operational Policy request given CLDS objects.
+ */
+public class OperationalPolicyReq {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(OperationalPolicyReq.class.getName());
+
+
+    /**
+     * Format Operational Policy attributes.
+     *
+     * @param refProp
+     * @param prop
+     * @return
+     * @throws BuilderException
+     * @throws UnsupportedEncodingException
+     */
+    public static Map<AttributeType, Map<String, String>> formatAttributes(RefProp refProp, ModelProperties prop) throws BuilderException, UnsupportedEncodingException {
+        Global global = prop.getGlobal();
+        Policy policy = prop.getPolicy();
+        prop.setCurrentModelElementId(policy.getId());
+
+        String templateName = refProp.getStringValue("op.templateName", global.getService());
+        String recipeTopic = refProp.getStringValue("op.recipeTopic", global.getService());
+        String operationTopic = refProp.getStringValue("op.operationTopic", global.getService());
+        String notificationTopic = refProp.getStringValue("op.notificationTopic", global.getService());
+
+        // ruleAttributes
+        Map<String, String> ruleAttributes = new HashMap<>();
+
+        if (operationTopic == null || operationTopic.length() == 0) {
+            logger.info("templateName=" + templateName);
+            logger.info("recipeTopic=" + recipeTopic);
+            logger.info("notificationTopic=" + notificationTopic);
+
+            // if no operationTopic, then don't format yaml - use first policy from list
+            PolicyItem policyItem = policy.getPolicyItems().get(0);
+
+            ruleAttributes.put("templateName", templateName);
+            ruleAttributes.put("ClosedLoopControlName", prop.getControlName());
+            ruleAttributes.put("RecipeTopic", recipeTopic);
+            ruleAttributes.put("NotificationTopic", notificationTopic);
+
+            String recipe = policyItem.getRecipe();
+            String maxRetries = String.valueOf(policyItem.getMaxRetries());
+            String retryTimeLimit = String.valueOf(policyItem.getRetryTimeLimit());
+            logger.info("recipe=" + recipe);
+            logger.info("maxRetries=" + maxRetries);
+            logger.info("retryTimeLimit=" + retryTimeLimit);
+            ruleAttributes.put("Recipe", recipe);
+            ruleAttributes.put("MaxRetries", maxRetries);
+            ruleAttributes.put("RetryTimeLimit", retryTimeLimit);
+        } else {
+            logger.info("templateName=" + templateName);
+            logger.info("operationTopic=" + operationTopic);
+            logger.info("notificationTopic=" + notificationTopic);
+
+            // format yaml
+            String yaml = formatYaml(refProp, prop);
+
+            ruleAttributes.put("templateName", templateName);
+            ruleAttributes.put("ClosedLoopControlName", prop.getControlName());
+            ruleAttributes.put("OperationTopic", operationTopic);
+            ruleAttributes.put("NotificationTopic", notificationTopic);
+
+            ruleAttributes.put("ControlLoopYaml", yaml);
+        }
+
+        // matchingAttributes
+        String controller = refProp.getStringValue("op.controller", global.getService());
+
+        Map<String, String> matchingAttributes = new HashMap<>();
+        matchingAttributes.put("controller", controller);
+
+        Map<AttributeType, Map<String, String>> attributes = new HashMap<>();
+        attributes.put(AttributeType.RULE, ruleAttributes);
+        attributes.put(AttributeType.MATCHING, matchingAttributes);
+
+
+        return attributes;
+    }
+
+
+    /**
+     * Format Operational Policy yaml.
+     *
+     * @param refProp
+     * @param prop
+     * @return
+     * @throws BuilderException
+     * @throws UnsupportedEncodingException
+     */
+    private static String formatYaml(RefProp refProp, ModelProperties prop) throws BuilderException, UnsupportedEncodingException {
+        // get property objects
+        Global global = prop.getGlobal();
+        Policy policy = prop.getPolicy();
+        prop.setCurrentModelElementId(policy.getId());
+
+        // convert values to ASDC objects
+        Service service = new Service(global.getService());
+        Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF);
+        Resource[] vfcResources = convertToResource(global.getResourceVfc(), ResourceType.VFC);
+
+        // create builder
+        ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(), policy.getTimeout(), service, vfResources);
+        builder.addResource(vfcResources);
+
+        // process each policy
+        HashMap<String, org.openecomp.policy.controlloop.policy.Policy> policyObjMap = new HashMap<>();
+        List<PolicyItem> policyItemList = orderParentFirst(policy.getPolicyItems());
+        for (int i = 0; i < policyItemList.size(); i++) {
+            org.openecomp.policy.controlloop.policy.Policy policyObj;
+            PolicyItem policyItem = policyItemList.get(i);
+            String policyName = policyItem.getRecipe() + " Policy";
+            if (i == 0) {
+                String policyDescription = policyItem.getRecipe() + " Policy - the trigger (no parent) policy - created by CLDS";
+                policyObj = builder.setTriggerPolicy(
+                        policyName,
+                        policyDescription,
+                        "APPC",
+                        new Target(TargetType.VM),
+                        policyItem.getRecipe(),
+                        new HashMap<>(), //TODO To verify !
+                        policyItem.getMaxRetries(),
+                        policyItem.getRetryTimeLimit());
+            } else {
+                org.openecomp.policy.controlloop.policy.Policy parentPolicyObj = policyObjMap.get(policyItem.getParentPolicy());
+                String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by " + parentPolicyObj.getName() + " - created by CLDS";
+                policyObj = builder.setPolicyForPolicyResult(
+                        policyName,
+                        policyDescription,
+                        "APPC",
+                        new Target(TargetType.VM),
+                        policyItem.getRecipe(),
+                        new HashMap<>(), //TODO To verify !
+                        policyItem.getMaxRetries(),
+                        policyItem.getRetryTimeLimit(),
+                        parentPolicyObj.getId(),
+                        convertToPolicyResult(policyItem.getParentPolicyConditions()));
+                logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId());
+            }
+            policyObjMap.put(policyItem.getId(), policyObj);
+        }
+
+        //
+        // Build the specification
+        //
+        Results results = builder.buildSpecification();
+        if (results.isValid()) {
+            logger.info("results.getSpecification()=" + results.getSpecification());
+        } else {
+            // throw exception with error info
+            StringBuilder sb = new StringBuilder();
+            sb.append("Operation Policy validation problem: ControlLoopPolicyBuilder failed with following messages: ");
+            for (Message message : results.getMessages()) {
+                sb.append(message.getMessage());
+                sb.append("; ");
+            }
+            throw new BadRequestException(sb.toString());
+        }
+        return URLEncoder.encode(results.getSpecification(), "UTF-8");
+    }
+
+    /**
+     * Order list of PolicyItems so that parents come before any of their children
+     *
+     * @param inOrigList
+     * @return
+     */
+    private static List<PolicyItem> orderParentFirst(List<PolicyItem> inOrigList) {
+        List<PolicyItem> inList = new ArrayList<>();
+        inList.addAll(inOrigList);
+        List<PolicyItem> outList = new ArrayList<>();
+        int prevSize = 0;
+        while (!inList.isEmpty()) {
+            // check if there's a loop in the policy chain (the inList should have been reduced by at least one)
+            if (inList.size() == prevSize) {
+                throw new BadRequestException("Operation Policy validation problem: loop in Operation Policy chain");
+            }
+            prevSize = inList.size();
+            // the following loop should remove at least one PolicyItem from the inList
+            Iterator<PolicyItem> inListItr = inList.iterator();
+            while (inListItr.hasNext()) {
+                PolicyItem inItem = inListItr.next();
+                // check for trigger policy (no parent)
+                String parent = inItem.getParentPolicy();
+                if (parent == null || parent.length() == 0) {
+                    if (outList.size() > 0) {
+                        throw new BadRequestException("Operation Policy validation problem: more than one trigger policy");
+                    } else {
+                        outList.add(inItem);
+                        inListItr.remove();
+                    }
+                } else {
+                    // check if this PolicyItem's parent has been processed
+                    for (PolicyItem outItem : outList) {
+                        if (outItem.getId().equals(parent)) {
+                            // if the inItem parent is already in the outList, then add inItem to outList and remove from inList
+                            outList.add(inItem);
+                            inListItr.remove();
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return outList;
+    }
+
+
+    /**
+     * Convert a List of resource strings to an array of Resource objects.
+     *
+     * @param rList
+     * @param resourceType
+     * @return
+     */
+    private static Resource[] convertToResource(List<String> rList, ResourceType resourceType) {
+        int size = 0;
+        if (rList != null) {
+            size = rList.size();
+        }
+        Resource[] rArray = new Resource[size];
+        for (int i = 0; i < size; i++) {
+            String rString = rList.get(i);
+            rArray[i] = new Resource(rString, resourceType);
+        }
+        return rArray;
+    }
+
+    /**
+     * Convert a List of policy result strings to an array of PolicyResult objects.
+     *
+     * @param prList
+     * @return
+     */
+    private static PolicyResult[] convertToPolicyResult(List<String> prList) {
+        int size = 0;
+        if (prList != null) {
+            size = prList.size();
+        }
+        PolicyResult[] prArray = new PolicyResult[size];
+        for (int i = 0; i < size; i++) {
+            String prString = prList.get(i);
+            prArray[i] = PolicyResult.toResult(prString);
+        }
+        return prArray;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/client/req/SdcReq.java b/src/main/java/org/onap/clamp/clds/client/req/SdcReq.java
new file mode 100644 (file)
index 0000000..45f1716
--- /dev/null
@@ -0,0 +1,360 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.dataformat.yaml.snakeyaml.Yaml;
+import org.onap.clamp.clds.client.SdcCatalogServices;
+import org.onap.clamp.clds.model.CldsAsdcResource;
+import org.onap.clamp.clds.model.CldsAsdcServiceDetail;
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.StringMatch;
+import org.onap.clamp.clds.model.prop.Tca;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+/**
+ * Construct a Asdc request given CLDS objects.
+ */
+public class SdcReq {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(SdcReq.class.getName());
+
+    /**
+     * @param refProp
+     * @param prop
+     * @return
+     * @throws JsonParseException
+     * @throws JsonMappingException
+     * @throws IOException
+     */
+    public static String formatBlueprint(RefProp refProp, ModelProperties prop, String docText)
+            throws JsonParseException, JsonMappingException, IOException {
+
+        Global globalProp = prop.getGlobal();
+        String service = globalProp.getService();
+
+        String yamlvalue = getYamlvalue(docText);
+
+        String updatedBlueprint = "";
+        StringMatch stringMatch = prop.getStringMatch();
+        Tca tca = prop.getTca();
+        if (stringMatch.isFound()) {
+            prop.setCurrentModelElementId(stringMatch.getId());
+            ObjectMapper objectMapper = new ObjectMapper();
+            ObjectNode serviceConfigurations = objectMapper.createObjectNode();
+
+            StringMatchPolicyReq.appendServiceConfigurations(refProp, service, serviceConfigurations, stringMatch);
+            logger.info("Value of serviceConfigurations:" + serviceConfigurations);
+            ObjectNode servConfNode = (ObjectNode) serviceConfigurations.get("serviceConfigurations");
+
+            // get updated blueprint by attaching service Conf from
+            // globalProperties
+            updatedBlueprint = getUpdatedBlueprintWithServiceConf(refProp, prop, yamlvalue, servConfNode);
+        } else if (tca.isFound()) {
+            prop.setCurrentModelElementId(tca.getId());
+            ObjectNode rootNode = (ObjectNode) refProp.getJsonTemplate("tca.template", service);
+            ObjectNode content = rootNode.with("content");
+            TcaMPolicyReq.appendSignatures(refProp, service, content, tca, prop);
+            logger.info("Value of content:" + content);
+            // ObjectNode servConfNode =
+            // (ObjectNode)signatures.get("signatures");
+
+            // get updated blueprint by attaching service Conf from
+            // globalProperties
+            updatedBlueprint = getUpdatedBlueprintWithConfiguration(refProp, prop, yamlvalue, content);
+        }
+
+        logger.info("value of blueprint:" + updatedBlueprint);
+        return updatedBlueprint;
+    }
+
+    private static String getUpdatedBlueprintWithServiceConf(RefProp refProp, ModelProperties prop, String yamlValue,
+            ObjectNode serviceConf) throws IOException {
+        Yaml yaml = new Yaml();
+
+        // Serialiaze Yaml file
+        Map<String, Map> loadedYaml = (Map<String, Map>) yaml.load(yamlValue);
+        // Get node templates information from Yaml
+        Map<String, Map> nodeTemplates = (Map<String, Map>) loadedYaml.get("node_templates");
+        logger.info("value of NodeTemplates:" + nodeTemplates);
+
+        // Get StringMatch Object information from node templates of Yaml
+        Map<String, Map> smObject = (Map<String, Map>) nodeTemplates.get("SM");
+        logger.info("value of StringMatch:" + smObject);
+
+        // Get Properties Object information from stringmatch of Yaml
+        Map<String, String> propsObject = (Map<String, String>) smObject.get("properties");
+        logger.info("value of PropsObject:" + propsObject);
+
+        String deploymentJsonObject = propsObject.get("deployment_JSON");
+        logger.info("value of deploymentJson:" + deploymentJsonObject);
+
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode deployJsonNode = (ObjectNode) mapper.readTree(deploymentJsonObject);
+        ObjectNode configurationObjectNode = (ObjectNode) deployJsonNode.get("configuration");
+
+        // "policyName":"example_model06.ClosedLoop_FRWL_SIG_0538e6f2_8c1b_4656_9999_3501b3c59ad7_StringMatch_",
+        String policyNamePrefix = refProp.getStringValue("policy.ms.policyNamePrefix");
+        String policyName = prop.getCurrentPolicyScopeAndFullPolicyName(policyNamePrefix);
+        configurationObjectNode.put("policyName", policyName);
+
+        // "closedLoopControlName":"ClosedLoop-FRWL-SIG-0538e6f2-8c1b-4656-9999-3501b3c59ad7",
+        configurationObjectNode.put("closedLoopControlName", prop.getControlName());
+        configurationObjectNode.set("serviceConfigurations", serviceConf);
+        propsObject.put("deployment_JSON", deployJsonNode.toString());
+        String blueprint = yaml.dump(loadedYaml);
+        logger.info("value of updated Yaml File:" + blueprint);
+
+        blueprint = yaml.dump(loadedYaml);
+        logger.info("value of updated Yaml File:" + blueprint);
+
+        return blueprint;
+    }
+
+    private static String getUpdatedBlueprintWithConfiguration(RefProp refProp, ModelProperties prop, String yamlValue,
+            ObjectNode serviceConf) throws JsonProcessingException, IOException {
+        String blueprint = "";
+        Yaml yaml = new Yaml();
+        // Serialiaze Yaml file
+        Map<String, Map> loadedYaml = (Map<String, Map>) yaml.load(yamlValue);
+        // Get node templates information from Yaml
+        Map<String, Map> nodeTemplates = (Map<String, Map>) loadedYaml.get("node_templates");
+        logger.info("value of NodeTemplates:" + nodeTemplates);
+        // Get Tca Object information from node templates of Yaml
+        Map<String, Map> tcaObject = (Map<String, Map>) nodeTemplates.get("MTCA");
+        logger.info("value of Tca:" + tcaObject);
+        // Get Properties Object information from tca of Yaml
+        Map<String, String> propsObject = (Map<String, String>) tcaObject.get("properties");
+        logger.info("value of PropsObject:" + propsObject);
+        String deploymentJsonObject = (String) propsObject.get("deployment_JSON");
+        logger.info("value of deploymentJson:" + deploymentJsonObject);
+
+        ObjectMapper mapper = new ObjectMapper();
+
+        ObjectNode deployJsonNode = (ObjectNode) mapper.readTree(deploymentJsonObject);
+
+        // "policyName":"example_model06.ClosedLoop_FRWL_SIG_0538e6f2_8c1b_4656_9999_3501b3c59ad7_Tca_",
+        String policyNamePrefix = refProp.getStringValue("policy.ms.policyNamePrefix");
+        String policyName = prop.getCurrentPolicyScopeAndFullPolicyName(policyNamePrefix);
+        serviceConf.put("policyName", policyName);
+
+        deployJsonNode.set("configuration", serviceConf);
+        propsObject.put("deployment_JSON", deployJsonNode.toString());
+        blueprint = yaml.dump(loadedYaml);
+        logger.info("value of updated Yaml File:" + blueprint);
+
+        return blueprint;
+    }
+
+    public static String formatAsdcLocationsReq(ModelProperties prop, String artifactName) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        Global global = prop.getGlobal();
+        List<String> locationsList = global.getLocation();
+        ArrayNode locationsArrayNode = objectMapper.createArrayNode();
+        ObjectNode locationObject = objectMapper.createObjectNode();
+        for (String currLocation : locationsList) {
+            locationsArrayNode.add(currLocation);
+        }
+        locationObject.put("artifactName", artifactName);
+        locationObject.putPOJO("locations", locationsArrayNode);
+        String locationJsonFormat = locationObject.toString();
+        logger.info("Value of locaation Json Artifact:" + locationsArrayNode);
+        return locationJsonFormat;
+    }
+
+    public static String formatAsdcReq(String payloadData, String artifactName, String artifactLabel,
+            String artifactType) throws IOException {
+        logger.info("artifact=" + payloadData);
+        String base64Artifact = base64Encode(payloadData);
+        return "{ \n" + "\"payloadData\" : \"" + base64Artifact + "\",\n" + "\"artifactLabel\" : \"" + artifactLabel
+                + "\",\n" + "\"artifactName\" :\"" + artifactName + "\",\n" + "\"artifactType\" : \"" + artifactType
+                + "\",\n" + "\"artifactGroupType\" : \"DEPLOYMENT\",\n" + "\"description\" : \"from CLAMP Cockpit\"\n"
+                + "} \n";
+    }
+
+    public static String getAsdcReqUrl(ModelProperties prop, String url) {
+        Global globalProps = prop.getGlobal();
+        String serviceUUID = "";
+        String resourceInstanceName = "";
+        if (globalProps != null) {
+            List<String> resourceVf = globalProps.getResourceVf();
+            if (resourceVf != null && resourceVf.size() > 0) {
+                resourceInstanceName = resourceVf.get(0);
+            }
+            if (globalProps.getService() != null) {
+                serviceUUID = globalProps.getService();
+            }
+        }
+        String normalizedResourceInstanceName = normalizeResourceInstanceName(resourceInstanceName);
+        return url + "/" + serviceUUID + "/resourceInstances/" + normalizedResourceInstanceName + "/artifacts";
+    }
+
+    /**
+     * To get List of urls for all vfresources
+     *
+     * @param prop
+     * @param baseUrl
+     * @param sdcCatalogServices
+     * @return
+     * @throws Exception
+     */
+    public static List<String> getAsdcReqUrlsList(ModelProperties prop, String baseUrl,
+            SdcCatalogServices sdcCatalogServices, DelegateExecution execution) throws Exception {
+        // TODO : refact and regroup with very similar code
+        List<String> urlList = new ArrayList<>();
+        Global globalProps = prop.getGlobal();
+        if (globalProps != null) {
+            if (globalProps.getService() != null) {
+                String serviceInvariantUUID = globalProps.getService();
+                execution.setVariable("serviceInvariantUUID", serviceInvariantUUID);
+                List<String> resourceVfList = globalProps.getResourceVf();
+                String serviceUUID = sdcCatalogServices.getServiceUUIDFromServiceInvariantID(serviceInvariantUUID);
+                String asdcServicesInformation = sdcCatalogServices.getAsdcServicesInformation(serviceUUID);
+                CldsAsdcServiceDetail cldsAsdcServiceDetail = sdcCatalogServices.getCldsAsdcServiceDetailFromJson(asdcServicesInformation);
+                if (cldsAsdcServiceDetail != null && resourceVfList != null) {
+                    List<CldsAsdcResource> cldsAsdcResourcesList = cldsAsdcServiceDetail.getResources();
+                    if (cldsAsdcResourcesList != null && cldsAsdcResourcesList.size() > 0) {
+                        for (CldsAsdcResource cldsAsdcResource : cldsAsdcResourcesList) {
+                            if (cldsAsdcResource != null && cldsAsdcResource.getResoucreType() != null
+                                    && cldsAsdcResource.getResoucreType().equalsIgnoreCase("VF")) {
+                                if (resourceVfList.contains(cldsAsdcResource.getResourceInvariantUUID())) {
+                                    String normalizedResourceInstanceName = normalizeResourceInstanceName(cldsAsdcResource.getResourceInstanceName());
+                                    String svcUrl = baseUrl + "/" + serviceUUID + "/resourceInstances/" + normalizedResourceInstanceName + "/artifacts";
+                                    urlList.add(svcUrl);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return urlList;
+    }
+
+    /**
+     * "Normalize" the resource instance name: - Remove spaces, underscores,
+     * dashes, and periods. - make lower case This is required by ASDC when
+     * using the resource instance name to upload an artifact.
+     *
+     * @param inText
+     * @return
+     */
+    public static String normalizeResourceInstanceName(String inText) {
+        return inText.replace(" ", "").replace("-", "").replace(".", "").toLowerCase();
+    }
+
+    /**
+     * from michael
+     *
+     * @param data
+     * @return
+     */
+    public static String calculateMD5ByString(String data) {
+        String calculatedMd5 = DigestUtils.md5Hex(data);
+        // encode base-64 result
+        return base64Encode(calculatedMd5.getBytes());
+    }
+
+    /**
+     * Base 64 encode a String.
+     *
+     * @param inText
+     * @return
+     */
+    public static String base64Encode(String inText) {
+        return base64Encode(stringToByteArray(inText));
+    }
+
+    /**
+     * Convert String to byte array.
+     *
+     * @param inText
+     * @return
+     */
+    public static byte[] stringToByteArray(String inText) {
+        return inText.getBytes(StandardCharsets.UTF_8);
+    }
+
+    /**
+     * Base 64 encode a byte array.
+     *
+     * @param bytes
+     * @return
+     */
+    public static String base64Encode(byte[] bytes) {
+        Base64.Encoder encoder = Base64.getEncoder();
+        return encoder.encodeToString(bytes);
+    }
+
+    /**
+     * Return ASDC id and pw as a HTTP Basic Auth string (for example: Basic
+     * dGVzdDoxMjM0NTY=).
+     *
+     * @return
+     */
+    public static String getAsdcBasicAuth(RefProp refProp) {
+        String asdcId = refProp.getStringValue("asdc.serviceUsername");
+        String asdcPw = refProp.getStringValue("asdc.servicePassword");
+        String idPw = base64Encode(asdcId + ":" + asdcPw);
+        return "Basic " + idPw;
+    }
+
+    private static String getYamlvalue(String docText) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        String yamlFileValue = "";
+        ObjectNode root = objectMapper.readValue(docText, ObjectNode.class);
+        Iterator<Entry<String, JsonNode>> entryItr = root.fields();
+        while (entryItr.hasNext()) {
+            Entry<String, JsonNode> entry = entryItr.next();
+            String key = entry.getKey();
+            if (key != null && key.equalsIgnoreCase("global")) {
+                ArrayNode arrayNode = (ArrayNode) entry.getValue();
+                for (JsonNode anArrayNode : arrayNode) {
+                    ObjectNode node = (ObjectNode) anArrayNode;
+                    ArrayNode arrayValueNode = (ArrayNode) node.get("value");
+                    JsonNode jsonNode = arrayValueNode.get(0);
+                    yamlFileValue = jsonNode.asText();
+                    logger.info("value:" + yamlFileValue);
+                }
+                break;
+            }
+        }
+        return yamlFileValue;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/req/StringMatchPolicyReq.java b/src/main/java/org/onap/clamp/clds/client/req/StringMatchPolicyReq.java
new file mode 100644 (file)
index 0000000..0f66cd9
--- /dev/null
@@ -0,0 +1,138 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.ServiceConfiguration;
+import org.onap.clamp.clds.model.prop.StringMatch;
+import org.onap.clamp.clds.model.refprop.RefProp;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+
+/**
+ * Construct a Policy for String Match Micro Service request given CLDS objects.
+ */
+public class StringMatchPolicyReq {
+    // currently uses the java.util.logging.Logger like the Camunda engine
+    private static final Logger logger = Logger.getLogger(StringMatchPolicyReq.class.getName());
+
+    /**
+     * Format Policy String Match request.
+     *
+     * @param refProp
+     * @param prop
+     * @return
+     * @throws IOException
+     */
+    public static String format(RefProp refProp, ModelProperties prop) throws IOException {
+        Global global = prop.getGlobal();
+        String service = global.getService();
+
+        StringMatch sm = prop.getStringMatch();
+        prop.setCurrentModelElementId(sm.getId());
+        ObjectNode rootNode = (ObjectNode) refProp.getJsonTemplate("sm.template", service);
+
+        // "policyName":
+        rootNode.put("policyName", prop.getCurrentPolicyScopeAndPolicyName());
+
+        // "content":{
+        ObjectNode content = rootNode.with("content");
+
+        // "closedLoopControlName":
+        content.put("closedLoopControlName", prop.getControlName());
+
+        //             "serviceConfigurations":[
+        appendServiceConfigurations(refProp, service, content, sm);
+
+        String stringMatchPolicyReq = rootNode.toString();
+        logger.info("stringMatchPolicyReq=" + stringMatchPolicyReq);
+        return stringMatchPolicyReq;
+    }
+
+    /**
+     * Add serviceConfigurations to json
+     *
+     * @param appendToNode
+     * @param sm
+     * @throws IOException
+     */
+    public static void appendServiceConfigurations(RefProp refProp, String service, ObjectNode appendToNode, StringMatch sm) throws IOException {
+        //     "serviceConfigurations":{
+        ObjectNode scNodes = appendToNode.with("serviceConfigurations");
+
+        Iterator<ServiceConfiguration> scItr = sm.getServiceConfigurations().iterator();
+        int index = 0;
+        while (scItr.hasNext()) {
+            ServiceConfiguration sc = scItr.next();
+
+            //"ItemX":{
+            index++;
+            String keyValue = "Item" + index;
+            ObjectNode scNode = (ObjectNode) refProp.getJsonTemplate("sm.sc.template", service);
+            scNodes.set(keyValue, scNode);
+
+            // "rulegroup":"abc",
+            String rulegroupInd = refProp.getStringValue("sm.rulegroup", service);
+            String groupNumber = sc.getGroupNumber();
+            if (rulegroupInd != null && rulegroupInd.equalsIgnoreCase("true") && groupNumber != null && groupNumber.length() > 0) {
+
+                //String rulegroup = (sc.getResourceVf() == null ? "" : String.join(" ", sc.getResourceVf())) + " - " + (sc.getResourceVfc() == null ? "" : String.join(" ", sc.getResourceVfc()));
+                scNode.put("rulegroup", groupNumber);
+            }
+
+            // "aaiMatchingFields" : ["VM_NAME"],
+            JsonUtil.addArrayField(scNode, "aaiMatchingFields", sc.getaaiMatchingFields());
+            // "aaiSendFields" : ["VMID", "TenantID"],
+            JsonUtil.addArrayField(scNode, "aaiSendFields", sc.getaaiSendFields());
+
+            // "stringSet": [
+            ArrayNode ssNode = scNode.putArray("stringSet");
+            // ObjectNode ssNode = scNode.with("stringSet");
+            for (Entry<String, String> entry : sc.getStringSet().entrySet()) {
+                // exclude eventSourceType
+                if (!entry.getKey().equals("eventSourceType")) {
+                    ssNode.add(entry.getKey());
+                    ssNode.add(entry.getValue());
+                }
+            }
+
+            // timeWindow": "0",
+            scNode.put("timeWindow", sc.getTimeWindow());
+            // "ageLimit": "3600",
+            scNode.put("ageLimit", sc.getAgeLimit());
+            // "createClosedLoopEventId" : "Initial",
+            scNode.put("createClosedLoopEventId", sc.getCreateClosedLoopEventId());
+            // "outputEventName": "OnSet"
+            scNode.put("outputEventName", sc.getOutputEventName());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/client/req/TcaMPolicyReq.java b/src/main/java/org/onap/clamp/clds/client/req/TcaMPolicyReq.java
new file mode 100644 (file)
index 0000000..f8acb64
--- /dev/null
@@ -0,0 +1,93 @@
+package org.onap.clamp.clds.client.req;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.prop.Tca;
+import org.onap.clamp.clds.model.prop.TcaItem;
+import org.onap.clamp.clds.model.prop.TcaThreshhold;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Construct a Policy for Tca/MTca Service request given CLDS objects. 
+ * 
+ *
+ */
+public class TcaMPolicyReq {
+        private static final Logger logger = Logger.getLogger(StringMatchPolicyReq.class.getName());
+        
+        /**
+         * Format Tca Policy request
+         * 
+         * @param refProp
+         * @param prop
+         * @return
+         * @throws JsonParseException
+         * @throws JsonMappingException
+         * @throws IOException
+         */
+        public static String formatTca(RefProp refProp, ModelProperties prop) throws JsonParseException, JsonMappingException, IOException {
+                Global global = prop.getGlobal();
+                String service = global.getService();
+                
+                Tca tca = prop.getTca();
+                prop.setCurrentModelElementId(tca.getId());
+                ObjectNode rootNode = (ObjectNode)refProp.getJsonTemplate("tca.template", service);
+                rootNode.put("policyName", prop.getCurrentPolicyScopeAndPolicyName());
+                ObjectNode content = rootNode.with("content");
+                appendSignatures(refProp, service, content, tca, prop);
+                
+                String tcaPolicyReq = rootNode.toString();
+                logger.info("tcaPolicyReq=" + tcaPolicyReq);
+                return tcaPolicyReq;
+        }
+        
+        /**
+         * Add appendSignatures to json
+         * 
+         * @param refProp
+         * @param service
+         * @param appendToNode
+         * @param tca
+         * @param prop
+         * @throws JsonParseException
+         * @throws JsonMappingException
+         * @throws IOException
+         */
+        public static void appendSignatures(RefProp refProp, String service, ObjectNode appendToNode, Tca tca, ModelProperties prop) throws JsonParseException, JsonMappingException, IOException {
+                //      "signatures":{
+                ArrayNode tcaNodes = appendToNode.withArray("signatures");
+                for(TcaItem tcaItem : tca.getTcaItems()){
+                        ObjectNode tcaNode = (ObjectNode)refProp.getJsonTemplate("tca.signature.template", service);
+                        tcaNode.put("useCaseName", tcaItem.getTcaName());
+                        tcaNode.put("signatureName", tcaItem.getTcaName()+ "_" + tcaItem.getTcaUuId());
+                        tcaNode.put("signatureUuid", tcaItem.getTcaUuId());
+                        prop.setPolicyUniqueId(tcaItem.getPolicyId());
+                        tcaNode.put("closedLoopControlName", prop.getControlNameAndPolicyUniqueId());
+                        tcaNode.put("severity", tcaItem.getSeverity());
+                        tcaNode.put("maxInterval", tcaItem.getInterval());
+                        tcaNode.put("minMessageViolations", tcaItem.getViolations());
+                        
+                        tcaNodes.add(tcaNode);
+                        Iterator<TcaThreshhold> scItr = tcaItem.getTcaThreshholds().iterator();
+                        while(scItr.hasNext()) {
+                                TcaThreshhold tcaThreshhold = scItr.next();
+                                // "thresholds": [
+                                ArrayNode thNodes = tcaNode.withArray("thresholds");
+                                ObjectNode thNode = thNodes.addObject();
+                                thNode.put("fieldPath", tcaThreshhold.getFieldPath());
+                                thNode.put("thresholdName", tcaThreshhold.getMetric());
+                                thNode.put("thresholdValue", tcaThreshhold.getThreshhold());
+                                thNode.put("direction", tcaThreshhold.getOperator());
+                        }               
+                }
+        }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/common/LogMessages.java b/src/main/java/org/onap/clamp/clds/common/LogMessages.java
new file mode 100644 (file)
index 0000000..cdd4793
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.common;
+
+import com.att.eelf.i18n.EELFResolvableErrorEnum;
+import com.att.eelf.i18n.EELFResourceManager;
+
+public enum LogMessages implements EELFResolvableErrorEnum {
+
+    LOGSERVICE_HELLO_MESSAGE, LOGSERVICE_EMAIL_ERROR, LOGSERVICE_EMAIL_CLASS, LOGSERVICE_EMAIL_CLASS_NULL, PROCESS_INSTANCE_ID;
+
+    static {
+        EELFResourceManager.loadMessageBundle("logmessages");
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/config/CamundaAuthFilterInitializer.java b/src/main/java/org/onap/clamp/clds/config/CamundaAuthFilterInitializer.java
new file mode 100644 (file)
index 0000000..244b40a
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.config;
+
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration;
+import org.camunda.bpm.webapp.impl.security.auth.AuthenticationFilter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnWebApplication
+@AutoConfigureAfter(CamundaBpmAutoConfiguration.class)
+public class CamundaAuthFilterInitializer implements ServletContextInitializer {
+
+       private static final EnumSet<DispatcherType> DISPATCHER_TYPES = EnumSet.of(DispatcherType.REQUEST);
+
+       private static final String AJSC_CADI_PROPS_FILE = "cadi.properties";
+
+       private ServletContext servletContext;
+
+       @Value("${com.att.ajsc.camunda.contextPath:/camunda}")
+       private String CAMUNDA_SUFFIX;
+
+       private static final Logger log = Logger.getLogger(CamundaAuthFilterInitializer.class.getName());
+
+       @Override
+       public void onStartup(ServletContext servletContext) throws ServletException {
+               this.servletContext = servletContext;
+
+               registerFilter("Authentication Filter", AuthenticationFilter.class, CAMUNDA_SUFFIX + "/*");
+       }
+
+       private FilterRegistration registerFilter(final String filterName, final Class<? extends Filter> filterClass,
+                       final String... urlPatterns) {
+               return registerFilter(filterName, filterClass, null, urlPatterns);
+       }
+
+       private FilterRegistration registerFilter(final String filterName, final Class<? extends Filter> filterClass,
+                       final Map<String, String> initParameters, final String... urlPatterns) {
+               FilterRegistration filterRegistration = servletContext.getFilterRegistration(filterName);
+
+               if (filterRegistration == null) {
+                       filterRegistration = servletContext.addFilter(filterName, filterClass);
+                       filterRegistration.addMappingForUrlPatterns(DISPATCHER_TYPES, true, urlPatterns);
+
+                       if (initParameters != null) {
+                               filterRegistration.setInitParameters(initParameters);
+                       }
+               }
+
+               return filterRegistration;
+       }
+}
diff --git a/src/main/java/org/onap/clamp/clds/config/CamundaEngineConfiguration.java b/src/main/java/org/onap/clamp/clds/config/CamundaEngineConfiguration.java
new file mode 100644 (file)
index 0000000..949f4ea
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.config;
+
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class CamundaEngineConfiguration {
+
+    /**
+     * Camunda Identity databse DataSource configuration
+     */
+    @Primary
+    @Bean(name = "camundaBpmDataSource")
+    @ConfigurationProperties(prefix = "spring.datasource")
+    public DataSource dataSource() {
+        return DataSourceBuilder
+                .create()
+                .build();
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/config/CldsConfiguration.java b/src/main/java/org/onap/clamp/clds/config/CldsConfiguration.java
new file mode 100644 (file)
index 0000000..814d2c6
--- /dev/null
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.config;
+
+import com.att.ajsc.common.AjscProvider;
+import com.att.ajsc.common.AjscService;
+import org.onap.clamp.clds.client.*;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.onap.clamp.clds.transform.XslTransformer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+import javax.sql.DataSource;
+import javax.xml.transform.TransformerConfigurationException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@Profile("clamp-default")
+public class CldsConfiguration {
+
+    @Autowired
+    private ApplicationContext context;
+
+    /**
+     * Clds Identity databse DataSource configuration
+     */
+    @Bean(name = "cldsDataSource")
+    @ConfigurationProperties(prefix = "spring.cldsdatasource")
+    public DataSource cldsDataSource() {
+        return DataSourceBuilder
+                .create()
+                .build();
+    }
+
+    @Bean(name = "jaxrsProviders")
+    public List jaxrsProviders() {
+        return new ArrayList(context.getBeansWithAnnotation(AjscProvider.class).values());
+    }
+
+    @Bean(name = "jaxrsServices")
+    public List jaxrsServices() {
+        return new ArrayList(context.getBeansWithAnnotation(AjscService.class).values());
+    }
+
+    @Bean(name = "cldsDao")
+    public CldsDao getCldsDao() {
+        CldsDao cldsDao = new CldsDao();
+        cldsDao.setDataSource(cldsDataSource());
+        return cldsDao;
+    }
+
+    @Bean(name = "cldsBpmnTransformer")
+    public XslTransformer getCldsBpmnXslTransformer() throws TransformerConfigurationException {
+        XslTransformer xslTransformer = new XslTransformer();
+        xslTransformer.setXslResourceName("xsl/clds-bpmn-transformer.xsl");
+        return xslTransformer;
+    }
+
+    @Bean
+    public RefProp getRefProp() throws IOException {
+        return new RefProp();
+    }
+
+    @Bean
+    public PolicyClient getPolicyClient() {
+        return new PolicyClient();
+    }
+
+    @Bean(name = "cldsEventDelegate")
+    public CldsEventDelegate getCldsEventDelegate() {
+        return new CldsEventDelegate();
+    }
+
+    @Bean(name = "dcaeReqDelegate")
+    public DcaeReqDelegate getDcaeReqDelegate() {
+        return new DcaeReqDelegate();
+    }
+
+    @Bean(name = "sdcSendReqDelegate")
+    public SdcSendReqDelegate getSdcSendReqDelegate() {
+        return new SdcSendReqDelegate();
+    }
+
+    @Bean(name = "dcaeReqDeleteDelegate")
+    public DcaeReqDeleteDelegate getDcaeReqDeleteDelegate() {
+        return new DcaeReqDeleteDelegate();
+    }
+
+    @Bean(name = "operationalPolicyDelegate")
+    public OperationalPolicyDelegate getOperationalPolicyDelegate() {
+        return new OperationalPolicyDelegate();
+    }
+
+    @Bean(name = "operationalPolicyDeleteDelegate")
+    public OperationalPolicyDeleteDelegate getOperationalPolicyDeleteDelegate() {
+        return new OperationalPolicyDeleteDelegate();
+    }
+
+    @Bean(name = "stringMatchPolicyDelegate")
+    public StringMatchPolicyDelegate getStringMatchPolicyDelegate() {
+        return new StringMatchPolicyDelegate();
+    }
+
+    @Bean(name = "stringMatchPolicyDeleteDelegate")
+    public StringMatchPolicyDeleteDelegate getStringMatchPolicyDeleteDelegate() {
+        return new StringMatchPolicyDeleteDelegate();
+    }
+
+    @Bean(name = "sdcCatalogServices")
+    public SdcCatalogServices getAsdcCatalogServices() {
+        return new SdcCatalogServices();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/config/CldsSecurityConfig.java b/src/main/java/org/onap/clamp/clds/config/CldsSecurityConfig.java
new file mode 100644 (file)
index 0000000..571ad4b
--- /dev/null
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@Configuration
+@EnableWebSecurity
+public class CldsSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private static final Logger logger = Logger.getLogger(CldsSecurityConfig.class.getName());
+
+    @Autowired
+    private ApplicationContext appContext;
+
+    @Value("${org.onap.clamp.config.files.cldsUsers:'classpath:etc/config/clds/clds-users.properties'}")
+    private String cldsUsers;
+
+    private final static String ROLEPREFIX = "null|null|";
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http
+            .csrf().disable()
+            .authorizeRequests()
+                .anyRequest().authenticated()
+                .and()
+            .formLogin()
+                .loginPage("/login.html")
+                .permitAll()
+                .and()
+            .logout()
+                .permitAll();
+    }
+
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        List<String> userList = loadUsers();
+
+        // no users defined
+        if (null == userList || userList.isEmpty()) {
+            logger.log(Level.SEVERE, "No users defined. Users should be defined under clds/clds-users.properties.");
+            return;
+        }
+
+        for (String user : userList) {
+            String[] userInfo = user.split("[|]");
+            if (userInfo.length != 3) {
+                logger.log(Level.SEVERE, "Defined User(" + user + ") is not in good format.  User format should be:<username>|<password>|<role>. Role should be eiother 'read' or 'all'.");
+                continue;
+            }
+
+            auth
+                .inMemoryAuthentication()
+                .withUser(userInfo[0]).password(userInfo[1]).roles(ROLEPREFIX + ("all".equalsIgnoreCase(userInfo[2]) ? "*" : userInfo[2]));
+
+        }
+    }
+
+    private boolean validUser(String[] userInfo) {
+        return ((userInfo != null) && (userInfo.length == 3) && (("all".equals(userInfo[2])) || ("read".equals(userInfo[2]))));
+    }
+
+    private List<String> loadUsers() throws Exception {
+        logger.info("Load from clds-users.properties");
+
+        Resource resource = appContext.getResource(cldsUsers);
+        BufferedReader input = new BufferedReader(new InputStreamReader(resource.getInputStream()));
+
+        List<String> userList = new LinkedList<>();
+
+        String line;
+        while ((line = input.readLine()) != null) {
+            if (!line.contains("#")) {
+                userList.add(line);
+            }
+            logger.info("line read:" + line);
+        }
+        return userList;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/clamp/clds/config/CsiLoggingConfiguration.java b/src/main/java/org/onap/clamp/clds/config/CsiLoggingConfiguration.java
new file mode 100644 (file)
index 0000000..5c5ba57
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.config;
+
+import com.att.ajsc.csilogging.common.AsyncSupport;
+import com.att.ajsc.csilogging.interceptors.CsiLoggingCamelPostInterceptor;
+import com.att.ajsc.csilogging.interceptors.CsiLoggingCamelPreInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CsiLoggingConfiguration {
+    @Bean
+    public CsiLoggingCamelPreInterceptor csiLoggingCamelPreInterceptor() {
+        return new CsiLoggingCamelPreInterceptor();
+    }
+
+    @Bean
+    public CsiLoggingCamelPostInterceptor csiLoggingCamelPostInterceptor() {
+        return new CsiLoggingCamelPostInterceptor();
+    }
+
+    @Bean
+    public AsyncSupport asyncsupport() {
+        return new AsyncSupport();
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/dao/CldsDao.java b/src/main/java/org/onap/clamp/clds/dao/CldsDao.java
new file mode 100644 (file)
index 0000000..67e4d1b
--- /dev/null
@@ -0,0 +1,485 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.dao;
+
+import org.onap.clamp.clds.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.namedparam.SqlParameterSource;
+import org.springframework.jdbc.core.simple.SimpleJdbcCall;
+import org.springframework.stereotype.Repository;
+
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.sql.Blob;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Data Access for CLDS Model tables.
+ */
+@Repository("cldsDao")
+public class CldsDao {
+
+    private static final Logger logger = LoggerFactory.getLogger(CldsDao.class);
+
+    private JdbcTemplate jdbcTemplateObject;
+    private SimpleJdbcCall procGetModel;
+    private SimpleJdbcCall procGetModelTemplate;
+    private SimpleJdbcCall procSetModel;
+    private SimpleJdbcCall procInsEvent;
+    private SimpleJdbcCall procUpdEvent;
+    private SimpleJdbcCall procSetTemplate;
+    private SimpleJdbcCall procGetTemplate;
+    private SimpleJdbcCall procDelAllModelInstances;
+    private SimpleJdbcCall procInsModelInstance;
+    private SimpleJdbcCall procDelModelInstance;
+
+    /**
+     * Log message when instantiating
+     */
+    public CldsDao() {
+        logger.info("CldsDao instantiating...");
+    }
+
+    /**
+     * When dataSource is provided, instantiate spring jdbc objects.
+     *
+     * @param dataSource
+     */
+    public void setDataSource(DataSource dataSource) {
+        this.jdbcTemplateObject = new JdbcTemplate(dataSource);
+        this.procGetModel = new SimpleJdbcCall(dataSource).withProcedureName("get_model");
+        this.procGetModelTemplate = new SimpleJdbcCall(dataSource).withProcedureName("get_model_template");
+        this.procSetModel = new SimpleJdbcCall(dataSource).withProcedureName("set_model");
+        this.procInsEvent = new SimpleJdbcCall(dataSource).withProcedureName("ins_event");
+        this.procUpdEvent = new SimpleJdbcCall(dataSource).withProcedureName("upd_event");
+        this.procGetTemplate = new SimpleJdbcCall(dataSource).withProcedureName("get_template");
+        this.procSetTemplate = new SimpleJdbcCall(dataSource).withProcedureName("set_template");
+        this.procInsModelInstance = new SimpleJdbcCall(dataSource).withProcedureName("ins_model_instance");
+        this.procDelModelInstance = new SimpleJdbcCall(dataSource).withProcedureName("del_model_instance");
+        this.procDelAllModelInstances = new SimpleJdbcCall(dataSource).withProcedureName("del_all_model_instances");
+    }
+
+    /**
+     * Get a model from the database given the model name.
+     *
+     * @param modelName
+     * @return model
+     */
+    public CldsModel getModel(String modelName) {
+        return getModel(modelName, null);
+    }
+
+    /**
+     * Get a model from the database given the controlNameUuid.
+     *
+     * @param controlNameUuid
+     * @return model
+     */
+    public CldsModel getModelByUuid(String controlNameUuid) {
+        return getModel(null, controlNameUuid);
+    }
+
+    /**
+     * Get a model from the database given the model name or a controlNameUuid.
+     *
+     * @param modelName
+     * @return model
+     */
+    private CldsModel getModel(String modelName, String controlNameUuid) {
+        CldsModel model = new CldsModel();
+        model.setName(modelName);
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_model_name", modelName)
+                .addValue("v_control_name_uuid", controlNameUuid);
+        Map<String, Object> out = logSqlExecution(procGetModel, in);
+        model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
+        model.setControlNameUuid((String) out.get("v_control_name_uuid"));
+        model.setId((String) (out.get("v_model_id")));
+        model.setTemplateId((String) (out.get("v_template_id")));
+        model.setTemplateName((String) (out.get("v_template_name")));
+        model.setBpmnId((String) (out.get("v_template_bpmn_id")));
+        model.setBpmnUserid((String) out.get("v_template_bpmn_userid"));
+        model.setBpmnText((String) out.get("v_template_bpmn_text"));
+        model.setPropId((String) (out.get("v_model_prop_id")));
+        model.setPropUserid((String) out.get("v_model_prop_userid"));
+        model.setPropText((String) out.get("v_model_prop_text"));
+        model.setImageId((String) (out.get("v_template_image_id")));
+        model.setImageUserid((String) out.get("v_template_image_userid"));
+        model.setImageText((String) out.get("v_template_image_text"));
+        model.setDocId((String) (out.get("v_template_doc_id")));
+        model.setDocUserid((String) out.get("v_template_doc_userid"));
+        model.setDocText((String) out.get("v_template_doc_text"));
+        model.setBlueprintText((String) out.get("v_model_blueprint_text"));
+        model.getEvent().setId((String) (out.get("v_event_id")));
+        model.getEvent().setActionCd((String) out.get("v_action_cd"));
+        model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
+        model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
+        model.getEvent().setUserid((String) out.get("v_event_userid"));
+        return model;
+    }
+
+    /**
+     * Get a model and template information from the database given the model name.
+     *
+     * @param modelName
+     * @return model
+     */
+    public CldsModel getModelTemplate(String modelName) {
+        CldsModel model = new CldsModel();
+        model.setName(modelName);
+        SqlParameterSource in = new MapSqlParameterSource().addValue("v_model_name", modelName);
+        Map<String, Object> out = logSqlExecution(procGetModelTemplate, in);
+        // todo : rationalize
+        model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
+        model.setControlNameUuid((String) out.get("v_control_name_uuid"));
+        model.setId((String) (out.get("v_model_id")));
+        model.setTemplateId((String) (out.get("v_template_id")));
+        model.setTemplateName((String) (out.get("v_template_name")));
+        model.setBpmnId((String) (out.get("v_template_bpmn_id")));
+        model.setBpmnUserid((String) out.get("v_template_bpmn_userid"));
+        model.setBpmnText((String) out.get("v_template_bpmn_text"));
+        model.setPropId((String) (out.get("v_model_prop_id")));
+        model.setPropUserid((String) out.get("v_model_prop_userid"));
+        model.setPropText((String) out.get("v_model_prop_text"));
+        model.setImageId((String) (out.get("v_template_image_id")));
+        model.setImageUserid((String) out.get("v_template_image_userid"));
+        model.setImageText((String) out.get("v_template_image_text"));
+        model.setDocId((String) (out.get("v_template_doc_id")));
+        model.setDocUserid((String) out.get("v_template_doc_userid"));
+        model.setDocText((String) out.get("v_template_doc_text"));
+        model.setBlueprintText((String) out.get("v_model_blueprint_text"));
+        model.getEvent().setId((String) (out.get("v_event_id")));
+        model.getEvent().setActionCd((String) out.get("v_action_cd"));
+        model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
+        model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
+        model.getEvent().setUserid((String) out.get("v_event_userid"));
+
+        Map<String, Object> modelResults = logSqlExecution(procGetModel, in);
+        Object modelResultObject = modelResults.get("#result-set-1");
+        if (modelResultObject != null && modelResultObject instanceof ArrayList) {
+            List<Object> modelInstanceRs = (List<Object>) modelResultObject;
+            for (Object currModelInstance : modelInstanceRs) {
+                if (currModelInstance != null && currModelInstance instanceof HashMap) {
+                    HashMap<String, String> modelInstanceMap = (HashMap<String, String>) currModelInstance;
+                    CldsModelInstance modelInstance = new CldsModelInstance();
+                    modelInstance.setModelInstanceId(modelInstanceMap.get("model_instance_id"));
+                    modelInstance.setVmName(modelInstanceMap.get("vm_name"));
+                    modelInstance.setLocation(modelInstanceMap.get("location"));
+                    model.getCldsModelInstanceList().add(modelInstance);
+                    logger.info("value of currModel: {}", currModelInstance);
+                }
+            }
+        }
+        return model;
+    }
+
+    /**
+     * Update model in the database using parameter values and return updated model object.
+     *
+     * @param model
+     * @param userid
+     * @return
+     */
+    public CldsModel setModel(CldsModel model, String userid) {
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_model_name", model.getName())
+                .addValue("v_template_id", model.getTemplateId())
+                .addValue("v_userid", userid)
+                .addValue("v_model_prop_text", model.getPropText())
+                .addValue("v_model_blueprint_text", model.getBlueprintText())
+                .addValue("v_control_name_prefix", model.getControlNamePrefix())
+                .addValue("v_control_name_uuid", model.getControlNameUuid());
+        Map<String, Object> out = logSqlExecution(procSetModel, in);
+        model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
+        model.setControlNameUuid((String) out.get("v_control_name_uuid"));
+        model.setId((String) (out.get("v_model_id")));
+        model.setPropId((String) (out.get("v_model_prop_id")));
+        model.setPropUserid((String) (out.get("v_model_prop_userid")));
+        model.setBlueprintId((String) (out.get("v_model_blueprint_id")));
+        model.setBlueprintUserid((String) out.get("v_model_blueprint_userid"));
+        model.getEvent().setId((String) (out.get("v_event_id")));
+        model.getEvent().setActionCd((String) out.get("v_action_cd"));
+        model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
+        model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
+        model.getEvent().setUserid((String) out.get("v_event_userid"));
+        return model;
+    }
+
+    /**
+     * Inserts new modelInstance in the database using parameter values and return updated model object.
+     *
+     * @param model
+     * @param modelInstancesList
+     * @return
+     */
+    public void insModelInstance(CldsModel model, List<CldsModelInstance> modelInstancesList) {
+        // Delete all existing model instances for given controlNameUUID
+        logger.debug("deleting instances for: {}", model.getControlNameUuid());
+        delAllModelInstances(model.getControlNameUuid());
+
+        if (modelInstancesList == null) {
+            logger.debug("modelInstancesList == null");
+        } else {
+            for (CldsModelInstance currModelInstance : modelInstancesList) {
+                logger.debug("v_control_name_uuid={}", model.getControlNameUuid());
+                logger.debug("v_vm_name={}", currModelInstance.getVmName());
+                logger.debug("v_location={}", currModelInstance.getLocation());
+                SqlParameterSource in = new MapSqlParameterSource()
+                        .addValue("v_control_name_uuid", model.getControlNameUuid())
+                        .addValue("v_vm_name", currModelInstance.getVmName())
+                        .addValue("v_location", currModelInstance.getLocation());
+                Map<String, Object> out = logSqlExecution(procInsModelInstance, in);
+                model.setId((String) (out.get("v_model_id")));
+                CldsModelInstance modelInstance = new CldsModelInstance();
+                modelInstance.setLocation(currModelInstance.getLocation());
+                modelInstance.setVmName(currModelInstance.getVmName());
+                modelInstance.setModelInstanceId((String) (out.get("v_model_instance_id")));
+                model.getCldsModelInstanceList().add(modelInstance);
+            }
+        }
+    }
+
+    /**
+     * Delete a list of modelInstance from the database using parameter values and returns updated model object.
+     * This method is defunct - DCAE Proxy will not undeploy individual instances.  It will send an empty list of
+     * deployed instances to indicate all have been removed.  Or it will send an updated list to indicate those that
+     * are still deployed with any not on the list considered undeployed.
+     *
+     * @param controlNameUUid
+     * @param modelInstancesList
+     * @return
+     */
+    private CldsModel delModelInstance(String controlNameUUid, List<CldsModelInstance> modelInstancesList) {
+        CldsModel model = new CldsModel();
+        for (CldsModelInstance currModelInstance : modelInstancesList) {
+            SqlParameterSource in = new MapSqlParameterSource()
+                    .addValue("v_control_name_uuid", controlNameUUid)
+                    .addValue("v_vm_name", currModelInstance.getVmName());
+            Map<String, Object> out = logSqlExecution(procDelModelInstance, in);
+            model.setId((String) (out.get("v_model_id")));
+        }
+        return model;
+    }
+
+    /**
+     * Insert an event in the database - require either modelName or controlNamePrefix/controlNameUuid.
+     * @param modelName
+     * @param controlNamePrefix
+     * @param controlNameUuid
+     * @param cldsEvent
+     * @return
+     */
+    public CldsEvent insEvent(String modelName, String controlNamePrefix, String controlNameUuid, CldsEvent cldsEvent) {
+        CldsEvent event = new CldsEvent();
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_model_name", modelName)
+                .addValue("v_control_name_prefix", controlNamePrefix)
+                .addValue("v_control_name_uuid", controlNameUuid)
+                .addValue("v_userid", cldsEvent.getUserid())
+                .addValue("v_action_cd", cldsEvent.getActionCd())
+                .addValue("v_action_state_cd", cldsEvent.getActionStateCd())
+                .addValue("v_process_instance_id", cldsEvent.getProcessInstanceId());
+        Map<String, Object> out = logSqlExecution(procInsEvent, in);
+        event.setId((String) (out.get("v_event_id")));
+        return event;
+    }
+
+    /**
+     * Method to delete all model instances based on controlNameUUID
+     *
+     * @param controlNameUUid
+     * @return
+     */
+    private String delAllModelInstances(String controlNameUUid) {
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_control_name_uuid", controlNameUUid);
+        Map<String, Object> out = logSqlExecution(procDelAllModelInstances, in);
+        return (String) (out.get("v_model_id"));
+    }
+
+    /**
+     * Update event with process instance id.
+     *
+     * @param eventId
+     * @param processInstanceId
+     */
+    public void updEvent(String eventId, String processInstanceId) {
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_event_id", eventId)
+                .addValue("v_process_instance_id", processInstanceId);
+        logSqlExecution(procUpdEvent, in);
+    }
+
+    /**
+     * Generic mapper for list of values
+     */
+    private static final class ValueItemMapper implements RowMapper<ValueItem> {
+        public ValueItem mapRow(ResultSet rs, int rowNum) throws SQLException {
+            ValueItem item = new ValueItem();
+            item.setValue(rs.getString(1));
+            return item;
+        }
+    }
+
+    /**
+     * Generic mapper for CldsDBServiceCache
+     */
+    private static final class CldsServiceDataMapper implements RowMapper<CldsServiceData> {
+        public CldsServiceData mapRow(ResultSet rs, int rowNum) throws SQLException {
+            CldsServiceData cldsServiceData = new CldsServiceData();
+            long age;
+            age = rs.getLong(5);
+            Blob blob = rs.getBlob(4);
+            InputStream is = blob.getBinaryStream();
+            ObjectInputStream oip;
+            try {
+                oip = new ObjectInputStream(is);
+                cldsServiceData = (CldsServiceData) oip.readObject();
+                cldsServiceData.setAgeOfRecord(age);
+            } catch (IOException | ClassNotFoundException e) {
+                logger.error("Error caught while retrieving cldsServiceData from database");
+            }
+            return cldsServiceData;
+        }
+    }
+
+    /**
+     * Return list of model names
+     *
+     * @return model names
+     */
+    public List<ValueItem> getBpmnNames() {
+        String SQL = "SELECT model_name FROM model ORDER BY 1;";
+        return jdbcTemplateObject.query(SQL, new ValueItemMapper());
+    }
+
+    /**
+     * Update template  in the database using parameter values and return updated template object.
+     *
+     * @param template
+     * @param userid
+     * @return
+     */
+    public CldsTemplate setTemplate(CldsTemplate template, String userid) {
+        SqlParameterSource in = new MapSqlParameterSource()
+                .addValue("v_template_name", template.getName())
+                .addValue("v_userid", userid)
+                .addValue("v_template_bpmn_text", template.getBpmnText())
+                .addValue("v_template_image_text", template.getImageText())
+                .addValue("v_template_doc_text", template.getPropText());
+        Map<String, Object> out = logSqlExecution(procSetTemplate, in);
+        template.setId((String) (out.get("v_template_id")));
+        template.setBpmnUserid((String) (out.get("v_template_bpmn_userid")));
+        template.setBpmnId((String) (out.get("v_template_bpmn_id")));
+        template.setBpmnText((String) (out.get("v_template_bpmn_text")));
+        template.setImageId((String) (out.get("v_template_image_id")));
+        template.setImageUserid((String) out.get("v_template_image_userid"));
+        template.setImageText((String) out.get("v_template_image_text"));
+        template.setPropId((String) (out.get("v_template_doc_id")));
+        template.setPropUserid((String) out.get("v_template_doc_userid"));
+        template.setPropText((String) out.get("v_template_doc_text"));
+        return template;
+    }
+
+    /**
+     * Return list of template names
+     *
+     * @return template names
+     */
+    public List<ValueItem> getTemplateNames() {
+        String SQL = "SELECT template_name FROM template ORDER BY 1;";
+        return jdbcTemplateObject.query(SQL, new ValueItemMapper());
+    }
+
+    /**
+     * Get a template from the database given the model name.
+     *
+     * @param templateName
+     * @return model
+     */
+    public CldsTemplate getTemplate(String templateName) {
+        CldsTemplate template = new CldsTemplate();
+        template.setName(templateName);
+        SqlParameterSource in = new MapSqlParameterSource().addValue("v_template_name", templateName);
+        Map<String, Object> out = logSqlExecution(procGetTemplate, in);
+        template.setId((String) (out.get("v_template_id")));
+        template.setBpmnUserid((String) (out.get("v_template_bpmn_userid")));
+        template.setBpmnId((String) (out.get("v_template_bpmn_id")));
+        template.setBpmnText((String) (out.get("v_template_bpmn_text")));
+        template.setImageId((String) (out.get("v_template_image_id")));
+        template.setImageUserid((String) out.get("v_template_image_userid"));
+        template.setImageText((String) out.get("v_template_image_text"));
+        template.setPropId((String) (out.get("v_template_doc_id")));
+        template.setPropUserid((String) out.get("v_template_doc_userid"));
+        template.setPropText((String) out.get("v_template_doc_text"));
+        return template;
+    }
+
+    public CldsServiceData getCldsServiceCache(String invariantUUID) throws SQLException, IOException, ClassNotFoundException {
+        CldsServiceData cldsServiceData = null;
+        List<CldsServiceData> cldsServiceDataList = new ArrayList<>();
+        try {
+            String getCldsServiceSQL = "SELECT * , TIMESTAMPDIFF(SECOND, timestamp, CURRENT_TIMESTAMP()) FROM clds_service_cache where invariant_service_id  = ? ";
+            cldsServiceData = jdbcTemplateObject.queryForObject(getCldsServiceSQL, new Object[]{invariantUUID}, new CldsServiceDataMapper());
+            logger.info("value of cldsServiceDataList: {}", cldsServiceDataList);
+        } catch (EmptyResultDataAccessException e) {
+            logger.info("cache row not found for invariantUUID: {}", invariantUUID);
+        }
+        return cldsServiceData;
+    }
+
+    public void setCldsServiceCache(CldsDBServiceCache cldsDBServiceCache) throws SQLException, IOException {
+        if (cldsDBServiceCache != null && cldsDBServiceCache.getInvariantId() != null && cldsDBServiceCache.getServiceId() != null) {
+            String invariantUUID = cldsDBServiceCache.getInvariantId();
+            String serviceUUID = cldsDBServiceCache.getServiceId();
+            InputStream is = cldsDBServiceCache.getCldsDataInstream();
+            String insertCldsServiceCacheSQL = "INSERT INTO clds_service_cache"
+                    + "(invariant_service_id,service_id,timestamp,object_data) VALUES"
+                    + "(?,?,CURRENT_TIMESTAMP,?) ON DUPLICATE KEY UPDATE invariant_service_id = VALUES(invariant_service_id) , timestamp = CURRENT_TIMESTAMP , object_data = VALUES(object_data) ";
+            jdbcTemplateObject.update(insertCldsServiceCacheSQL, invariantUUID, serviceUUID, is);
+        }
+    }
+
+    private static Map<String, Object> logSqlExecution(SimpleJdbcCall call, SqlParameterSource source) {
+       try {
+               return call.execute(source);
+       } catch (Exception e) {
+               logger.error("Exception occured in " + source.getClass().getCanonicalName() + ": " + e);
+               throw e;
+       }
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/exception/AjscExceptionMapper.java b/src/main/java/org/onap/clamp/clds/exception/AjscExceptionMapper.java
new file mode 100644 (file)
index 0000000..41023ac
--- /dev/null
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.exception;
+
+import com.att.ajsc.common.AjscProvider;
+import com.att.ajsc.common.exception.ServerErrorException;
+import com.att.ajsc.common.exception.ServiceException;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+@AjscProvider
+public class AjscExceptionMapper implements ExceptionMapper<Exception> {
+
+    @Override
+    public Response toResponse(final Exception exception) {
+        return exception instanceof ServiceException ? ((ServiceException) exception).toResponse() : new ServerErrorException(exception.getMessage()).toResponse();
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/jsf/JsfExampleBean.java b/src/main/java/org/onap/clamp/clds/jsf/JsfExampleBean.java
new file mode 100644 (file)
index 0000000..5fdcedd
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.jsf;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+import java.io.Serializable;
+import java.util.Date;
+
+@ManagedBean
+@SessionScoped
+public class JsfExampleBean implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String value;
+    private Date dateValue;
+
+    private static final java.text.SimpleDateFormat timestampFormat = new java.text.SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Date getDateValue() {
+        return dateValue;
+    }
+
+    public void setDateValue(Date dateValue) {
+        this.dateValue = dateValue;
+    }
+
+    public String getDateValueText() {
+        return timestampFormat.format(dateValue);
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAlarmCondition.java b/src/main/java/org/onap/clamp/clds/model/CldsAlarmCondition.java
new file mode 100644 (file)
index 0000000..0325478
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import java.io.Serializable;
+
+public class CldsAlarmCondition implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private String eventSourceType;
+    private String alarmConditionKey;
+    private String severity;
+
+    public String getEventSourceType() {
+        return eventSourceType;
+    }
+
+    public void setEventSourceType(String eventSourceType) {
+        this.eventSourceType = eventSourceType;
+    }
+
+    public String getSeverity() {
+        return severity;
+    }
+
+    public void setSeverity(String severity) {
+        this.severity = severity;
+    }
+
+    public String getAlarmConditionKey() {
+        return alarmConditionKey;
+    }
+
+    public void setAlarmConditionKey(String alarmConditionKey) {
+        this.alarmConditionKey = alarmConditionKey;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAsdcArtifact.java b/src/main/java/org/onap/clamp/clds/model/CldsAsdcArtifact.java
new file mode 100644 (file)
index 0000000..43d5ab6
--- /dev/null
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CldsAsdcArtifact {
+
+    private String artifactName;
+    private String artifactType;
+    private String artifactURL;
+    private String artifactDescription;
+    private String artifactTimeout;
+    private String artifactChecksum;
+    private String artifactUUID;
+    private String artifactVersion;
+    private String generatedFromUUID;
+
+    public String getArtifactName() {
+        return artifactName;
+    }
+
+    public void setArtifactName(String artifactName) {
+        this.artifactName = artifactName;
+    }
+
+    public String getArtifactType() {
+        return artifactType;
+    }
+
+    public void setArtifactType(String artifactType) {
+        this.artifactType = artifactType;
+    }
+
+    public String getArtifactURL() {
+        return artifactURL;
+    }
+
+    public void setArtifactURL(String artifactURL) {
+        this.artifactURL = artifactURL;
+    }
+
+    public String getArtifactDescription() {
+        return artifactDescription;
+    }
+
+    public void setArtifactDescription(String artifactDescription) {
+        this.artifactDescription = artifactDescription;
+    }
+
+    public String getArtifactTimeout() {
+        return artifactTimeout;
+    }
+
+    public void setArtifactTimeout(String artifactTimeout) {
+        this.artifactTimeout = artifactTimeout;
+    }
+
+    public String getArtifactChecksum() {
+        return artifactChecksum;
+    }
+
+    public void setArtifactChecksum(String artifactChecksum) {
+        this.artifactChecksum = artifactChecksum;
+    }
+
+    public String getArtifactUUID() {
+        return artifactUUID;
+    }
+
+    public void setArtifactUUID(String artifactUUID) {
+        this.artifactUUID = artifactUUID;
+    }
+
+    public String getArtifactVersion() {
+        return artifactVersion;
+    }
+
+    public void setArtifactVersion(String artifactVersion) {
+        this.artifactVersion = artifactVersion;
+    }
+
+    public String getGeneratedFromUUID() {
+        return generatedFromUUID;
+    }
+
+    public void setGeneratedFromUUID(String generatedFromUUID) {
+        this.generatedFromUUID = generatedFromUUID;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAsdcResource.java b/src/main/java/org/onap/clamp/clds/model/CldsAsdcResource.java
new file mode 100644 (file)
index 0000000..3210b69
--- /dev/null
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.logging.Logger;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CldsAsdcResource implements Comparable<CldsAsdcResource> {
+    private static final Logger logger = Logger.getLogger(CldsAsdcServiceInfo.class.getName());
+
+    private String resourceInstanceName;
+    private String resourceName;
+    private String resourceInvariantUUID;
+    private String resourceVersion;
+    private String resoucreType;
+    private String resourceUUID;
+    private List<CldsAsdcArtifact> artifacts;
+
+    public String getResourceInstanceName() {
+        return resourceInstanceName;
+    }
+
+    public void setResourceInstanceName(String resourceInstanceName) {
+        this.resourceInstanceName = resourceInstanceName;
+    }
+
+    public String getResourceName() {
+        return resourceName;
+    }
+
+    public void setResourceName(String resourceName) {
+        this.resourceName = resourceName;
+    }
+
+    public String getResourceInvariantUUID() {
+        return resourceInvariantUUID;
+    }
+
+    public void setResourceInvariantUUID(String resourceInvariantUUID) {
+        this.resourceInvariantUUID = resourceInvariantUUID;
+    }
+
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+    }
+
+    public String getResoucreType() {
+        return resoucreType;
+    }
+
+    public void setResoucreType(String resoucreType) {
+        this.resoucreType = resoucreType;
+    }
+
+    public String getResourceUUID() {
+        return resourceUUID;
+    }
+
+    public void setResourceUUID(String resourceUUID) {
+        this.resourceUUID = resourceUUID;
+    }
+
+    public List<CldsAsdcArtifact> getArtifacts() {
+        return artifacts;
+    }
+
+    public void setArtifacts(List<CldsAsdcArtifact> artifacts) {
+        this.artifacts = artifacts;
+    }
+
+    @Override
+    public int compareTo(CldsAsdcResource in) {
+        // Compares this object with the specified object for order.
+        // Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
+
+        // first compare based on name
+        int rtn = resourceInstanceName.compareToIgnoreCase(in.resourceInstanceName);
+
+        if (rtn == 0) {
+            BigDecimal myVersion = convertVersion(resourceVersion);
+            BigDecimal inVersion = convertVersion(in.resourceVersion);
+            rtn = myVersion.compareTo(inVersion);
+        }
+        return rtn;
+    }
+
+    /**
+     * Convert version String into a BigDecimal
+     *
+     * @param versionText
+     * @return
+     */
+    private BigDecimal convertVersion(String versionText) {
+        BigDecimal rtn = new BigDecimal(0.0);
+        try {
+            rtn = new BigDecimal(versionText);
+        } catch (NumberFormatException nfe) {
+            logger.warning("ASDC version=" + versionText + " is not decimal for name=" + resourceInstanceName);
+        }
+        return rtn;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAsdcResourceBasicInfo.java b/src/main/java/org/onap/clamp/clds/model/CldsAsdcResourceBasicInfo.java
new file mode 100644 (file)
index 0000000..c66428a
--- /dev/null
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.math.BigDecimal;
+import java.util.logging.Logger;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CldsAsdcResourceBasicInfo implements Comparable<CldsAsdcResourceBasicInfo> {
+    private static final Logger logger = Logger.getLogger(CldsAsdcServiceInfo.class.getName());
+
+    private String uuid;
+    private String invariantUUID;
+    private String name;
+    private String version;
+    private String toscaModelURL;
+    private String category;
+    private String subCategory;
+    private String resourceType;
+    private String lifecycleState;
+    private String lastUpdaterUserId;
+
+    @Override
+    public int compareTo(CldsAsdcResourceBasicInfo in) {
+        // Compares this object with the specified object for order.
+        // Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
+        // first compare based on name
+        int rtn = name.compareToIgnoreCase(in.name);
+
+        if (rtn == 0) {
+            BigDecimal myVersion = convertVersion(version);
+            BigDecimal inVersion = convertVersion(in.version);
+            rtn = myVersion.compareTo(inVersion);
+        }
+        return rtn;
+    }
+
+    /**
+     * Convert version String into a BigDecimal
+     *
+     * @param version
+     * @return
+     */
+    private BigDecimal convertVersion(String version) {
+        BigDecimal rtn = new BigDecimal(0.0);
+        try {
+            rtn = new BigDecimal(version);
+        } catch (NumberFormatException nfe) {
+            logger.warning("ASDC version=" + version + " is not decimal for name=" + name);
+        }
+        return rtn;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getInvariantUUID() {
+        return invariantUUID;
+    }
+
+    public void setInvariantUUID(String invariantUUID) {
+        this.invariantUUID = invariantUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getToscaModelURL() {
+        return toscaModelURL;
+    }
+
+    public void setToscaModelURL(String toscaModelURL) {
+        this.toscaModelURL = toscaModelURL;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public String getSubCategory() {
+        return subCategory;
+    }
+
+    public void setSubCategory(String subCategory) {
+        this.subCategory = subCategory;
+    }
+
+    public String getResourceType() {
+        return resourceType;
+    }
+
+    public void setResourceType(String resourceType) {
+        this.resourceType = resourceType;
+    }
+
+    public String getLifecycleState() {
+        return lifecycleState;
+    }
+
+    public void setLifecycleState(String lifecycleState) {
+        this.lifecycleState = lifecycleState;
+    }
+
+    public String getLastUpdaterUserId() {
+        return lastUpdaterUserId;
+    }
+
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.lastUpdaterUserId = lastUpdaterUserId;
+    }
+
+    public Logger getLOGGER() {
+        return logger;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceDetail.java b/src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceDetail.java
new file mode 100644 (file)
index 0000000..f50e09d
--- /dev/null
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CldsAsdcServiceDetail {
+
+    private String uuid;
+    private String invariantUUID;
+    private String name;
+    private String version;
+    private String toscaModelURL;
+    private String category;
+    private String lifecycleState;
+    private String lastUpdaterUserId;
+    private String distributionStatus;
+    private String lastUpdaterFullName;
+    private List<CldsAsdcResource> resources;
+    private List<CldsAsdcArtifact> artifacts;
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getInvariantUUID() {
+        return invariantUUID;
+    }
+
+    public void setInvariantUUID(String invariantUUID) {
+        this.invariantUUID = invariantUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getToscaModelURL() {
+        return toscaModelURL;
+    }
+
+    public void setToscaModelURL(String toscaModelURL) {
+        this.toscaModelURL = toscaModelURL;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public String getLifecycleState() {
+        return lifecycleState;
+    }
+
+    public void setLifecycleState(String lifecycleState) {
+        this.lifecycleState = lifecycleState;
+    }
+
+    public String getLastUpdaterUserId() {
+        return lastUpdaterUserId;
+    }
+
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.lastUpdaterUserId = lastUpdaterUserId;
+    }
+
+    public String getDistributionStatus() {
+        return distributionStatus;
+    }
+
+    public void setDistributionStatus(String distributionStatus) {
+        this.distributionStatus = distributionStatus;
+    }
+
+    public String getLastUpdaterFullName() {
+        return lastUpdaterFullName;
+    }
+
+    public void setLastUpdaterFullName(String lastUpdaterFullName) {
+        this.lastUpdaterFullName = lastUpdaterFullName;
+    }
+
+    public List<CldsAsdcResource> getResources() {
+        return resources;
+    }
+
+    public void setResources(List<CldsAsdcResource> resources) {
+        this.resources = resources;
+    }
+
+    public List<CldsAsdcArtifact> getArtifacts() {
+        return artifacts;
+    }
+
+    public void setArtifacts(List<CldsAsdcArtifact> artifacts) {
+        this.artifacts = artifacts;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceInfo.java b/src/main/java/org/onap/clamp/clds/model/CldsAsdcServiceInfo.java
new file mode 100644 (file)
index 0000000..3ed5753
--- /dev/null
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import java.math.BigDecimal;
+import java.util.logging.Logger;
+
+public class CldsAsdcServiceInfo implements Comparable<CldsAsdcServiceInfo> {
+    private static final Logger logger = Logger.getLogger(CldsAsdcServiceInfo.class.getName());
+
+    private String uuid;
+    private String invariantUUID;
+    private String name;
+    private String version;
+    private String toscaModelURL;
+    private String category;
+    private String lifecycleState;
+    private String lastUpdaterUserId;
+    private String distributionStatus;
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getInvariantUUID() {
+        return invariantUUID;
+    }
+
+    public void setInvariantUUID(String invariantUUID) {
+        this.invariantUUID = invariantUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getToscaModelURL() {
+        return toscaModelURL;
+    }
+
+    public void setToscaModelURL(String toscaModelURL) {
+        this.toscaModelURL = toscaModelURL;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public String getLifecycleState() {
+        return lifecycleState;
+    }
+
+    public void setLifecycleState(String lifecycleState) {
+        this.lifecycleState = lifecycleState;
+    }
+
+    public String getLastUpdaterUserId() {
+        return lastUpdaterUserId;
+    }
+
+    public void setLastUpdaterUserId(String lastUpdaterUserId) {
+        this.lastUpdaterUserId = lastUpdaterUserId;
+    }
+
+    public String getDistributionStatus() {
+        return distributionStatus;
+    }
+
+    public void setDistributionStatus(String distributionStatus) {
+        this.distributionStatus = distributionStatus;
+    }
+
+    /**
+     * Compare using name and then version.  Version is converted to a decimal.
+     */
+    @Override
+    public int compareTo(CldsAsdcServiceInfo in) {
+        // Compares this object with the specified object for order.
+        // Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
+        // first compare based on name
+        int rtn = name.compareToIgnoreCase(in.name);
+
+        if (rtn == 0) {
+            BigDecimal myVersion = convertVersion(version);
+            BigDecimal inVersion = convertVersion(in.version);
+            rtn = myVersion.compareTo(inVersion);
+        }
+
+        return rtn;
+    }
+
+    /**
+     * Convert version String into a BigDecimal
+     *
+     * @param versionText
+     * @return
+     */
+    private BigDecimal convertVersion(String versionText) {
+        try {
+            return new BigDecimal(versionText);
+        } catch (NumberFormatException nfe) {
+            logger.warning("ASDC version=" + versionText + " is not decimal for name=" + name);
+        }
+        return new BigDecimal(0.0);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsDBServiceCache.java b/src/main/java/org/onap/clamp/clds/model/CldsDBServiceCache.java
new file mode 100644 (file)
index 0000000..658e21f
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import java.io.*;
+
+public class CldsDBServiceCache {
+
+    private String invariantId;
+    private String serviceId;
+    private InputStream cldsDataInstream;
+
+    public String getInvariantId() {
+        return invariantId;
+    }
+
+    public void setInvariantId(String invariantId) {
+        this.invariantId = invariantId;
+    }
+
+    public String getServiceId() {
+        return serviceId;
+    }
+
+    public void setServiceId(String serviceId) {
+        this.serviceId = serviceId;
+    }
+
+    public InputStream getCldsDataInstream() throws IOException {
+        return cldsDataInstream;
+    }
+
+    public void setCldsDataInstream(CldsServiceData cldsServiceData) throws IOException {
+        this.cldsDataInstream = getInstreamFromObject(cldsServiceData);
+    }
+
+    private InputStream getInstreamFromObject(CldsServiceData cldsServiceData) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(cldsServiceData);
+        oos.flush();
+        oos.close();
+        return new ByteArrayInputStream(baos.toByteArray());
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsEvent.java b/src/main/java/org/onap/clamp/clds/model/CldsEvent.java
new file mode 100644 (file)
index 0000000..8379e50
--- /dev/null
@@ -0,0 +1,183 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.onap.clamp.clds.dao.CldsDao;
+
+/**
+ * Represent a CLDS Event.
+ */
+public class CldsEvent {
+    public static final String ACTION_CREATE = "CREATE";
+    public static final String ACTION_SUBMIT = "SUBMIT";
+    public static final String ACTION_RESUBMIT = "RESUBMIT"; // an update before model is active
+    public static final String ACTION_DISTRIBUTE = "DISTRIBUTE"; // only from dcae
+    public static final String ACTION_DEPLOY = "DEPLOY"; // only from dcae
+    public static final String ACTION_UNDEPLOY = "UNDEPLOY"; // only from dcae
+    public static final String ACTION_UPDATE = "UPDATE";
+    public static final String ACTION_DELETE = "DELETE";
+    public static final String ACTION_STOP = "STOP";
+    public static final String ACTION_RESTART = "RESTART";
+
+    public static final String ACTION_STATE_INITIATED = "INITIATED";
+    public static final String ACTION_STATE_SENT = "SENT";
+    public static final String ACTION_STATE_COMPLETED = "COMPLETED";
+    public static final String ACTION_STATE_RECEIVED = "RECEIVED";
+    public static final String ACTION_STATE_ERROR = "ERROR";
+    public static final String ACTION_STATE_ANY = null;
+
+    private String id;
+    private String actionCd;
+    private String actionStateCd;
+    private String processInstanceId;
+    private String userid;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @param cldsDao
+     * @param controlName
+     * @param userid
+     * @param actionCd
+     * @param actionStateCd
+     * @param processInstanceId
+     * @return
+     */
+    public static CldsEvent insEvent(CldsDao cldsDao, String controlName, String userid, String actionCd, String actionStateCd, String processInstanceId) {
+        CldsModel model = CldsModel.createUsingControlName(controlName);
+        return insEvent(cldsDao, model, actionCd, actionStateCd, processInstanceId);
+    }
+
+    /**
+     * Insert event using controlNameUuid to find the model.
+     * This method meant for processing events from dcae.
+     * @param cldsDao
+     * @param model
+     * @param actionCd
+     * @param actionStateCd
+     * @param processInstanceId
+     * @return
+     */
+    public static CldsEvent insEvent(CldsDao cldsDao, CldsModel model, String actionCd, String actionStateCd, String processInstanceId) {
+        CldsEvent event = new CldsEvent();
+        event.setActionCd(actionCd);
+        event.setActionStateCd(actionStateCd);
+        event.setProcessInstanceId(processInstanceId);
+        cldsDao.insEvent(null, model.getControlNamePrefix(), model.getControlNameUuid(), event);
+        return event;
+    }
+
+    /**
+     * Check if actionCd  and actionStateCd are equal to the supplied checkActionCd and checkActionStateCd.
+     * Treat checkActionStateCd == null as a wildcard
+     * checkActionCd should not be null.
+     *
+     * @param checkActionCd
+     * @param checkActionStateCd
+     * @return
+     */
+    public boolean isActionAndStateCd(String checkActionCd, String checkActionStateCd) {
+        if (actionCd == null) {
+            return false;
+        }
+        // treat checkActionStateCd == null as a wildcard (same for actionStateCd, although it shouln't be null...)
+        if (checkActionStateCd == null || actionStateCd == null) {
+            return actionCd.equals(checkActionCd);
+        }
+        return actionCd.equals(checkActionCd) && actionStateCd.equals(checkActionStateCd);
+    }
+
+    /**
+     * Check if actionStateCd is equal to the supplied checkActionStateCd.
+     * checkActionCd should not be null.
+     *
+     * @param checkActionStateCd
+     * @return
+     */
+    public boolean isActionStateCd(String checkActionStateCd) {
+        return !(checkActionStateCd == null || actionStateCd == null) && actionStateCd.equals(checkActionStateCd);
+    }
+
+    /**
+     * @return the actionCd
+     */
+    public String getActionCd() {
+        return actionCd;
+    }
+
+    /**
+     * @param actionCd the actionCd to set
+     */
+    public void setActionCd(String actionCd) {
+        this.actionCd = actionCd;
+    }
+
+    /**
+     * @return the actionStateCd
+     */
+    public String getActionStateCd() {
+        return actionStateCd;
+    }
+
+    /**
+     * @param actionStateCd the actionStateCd to set
+     */
+    public void setActionStateCd(String actionStateCd) {
+        this.actionStateCd = actionStateCd;
+    }
+
+    /**
+     * @return the processInstanceId
+     */
+    public String getProcessInstanceId() {
+        return processInstanceId;
+    }
+
+    /**
+     * @param processInstanceId the processInstanceId to set
+     */
+    public void setProcessInstanceId(String processInstanceId) {
+        this.processInstanceId = processInstanceId;
+    }
+
+    /**
+     * @return the userid
+     */
+    public String getUserid() {
+        return userid;
+    }
+
+    /**
+     * @param userid the userid to set
+     */
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsModel.java b/src/main/java/org/onap/clamp/clds/model/CldsModel.java
new file mode 100644 (file)
index 0000000..4d4f3aa
--- /dev/null
@@ -0,0 +1,570 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.onap.clamp.clds.dao.CldsDao;
+import org.jboss.resteasy.spi.BadRequestException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.NotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represent a CLDS Model.
+ */
+public class CldsModel {
+    private static final Logger logger = LoggerFactory.getLogger(CldsModel.class);
+
+    private static final int UUID_LENGTH = 36;
+
+    public static final String STATUS_DESIGN = "DESIGN";
+    public static final String STATUS_DISTRIBUTED = "DISTRIBUTED";
+    public static final String STATUS_ACTIVE = "ACTIVE";
+    public static final String STATUS_STOPPED = "STOPPED";
+    public static final String STATUS_DELETING = "DELETING";
+    public static final String STATUS_ERROR = "ERROR"; // manual intervention required
+    public static final String STATUS_UNKNOWN = "UNKNOWN";
+
+    private String id;
+    private String templateId;
+    private String templateName;
+    private String name;
+    private String controlNamePrefix;
+    private String controlNameUuid;
+    private String bpmnId;
+    private String bpmnUserid;
+    private String bpmnText;
+    private String propId;
+    private String propUserid;
+    private String propText;
+    private String imageId;
+    private String imageUserid;
+    private String imageText;
+    private String docId;
+    private String docUserid;
+    private String docText;
+    private String blueprintId;
+    private String blueprintUserid;
+    private String blueprintText;
+    private CldsEvent event;
+    private String status;
+    private List<String> permittedActionCd;
+    private List<CldsModelInstance> cldsModelInstanceList;
+
+    /**
+     * Construct empty model.
+     */
+    public CldsModel() {
+        event = new CldsEvent();
+    }
+
+    /**
+     * Retrieve from DB.
+     *
+     * @param cldsDao
+     * @param name
+     * @return
+     */
+    public static CldsModel retrieve(CldsDao cldsDao, String name, boolean okIfNotFound) {
+        // get from db
+        CldsModel model = cldsDao.getModelTemplate(name);
+        if (model.getId() == null && !okIfNotFound) {
+            throw new NotFoundException();
+        }
+        model.determineStatus();
+        model.determinePermittedActionCd();
+        return model;
+    }
+
+    /**
+     * Save model to DB.
+     *
+     * @param cldsDao
+     * @param userid
+     */
+    public void save(CldsDao cldsDao, String userid) {
+        cldsDao.setModel(this, userid);
+        determineStatus();
+        determinePermittedActionCd();
+    }
+
+    /**
+     * Insert a new event for the new action.
+     * Throw IllegalArgumentException if requested actionCd is not permitted.
+     *
+     * @param cldsDao
+     * @param userid
+     * @param actionCd
+     * @param actionStateCd
+     */
+    public void insEvent(CldsDao cldsDao, String userid, String actionCd, String actionStateCd) {
+        validateAction(actionCd);
+        event = CldsEvent.insEvent(cldsDao, this, actionCd, actionStateCd, null);
+        determineStatus();
+        determinePermittedActionCd();
+    }
+
+    /**
+     * Update event with processInstanceId
+     *
+     * @param cldsDao
+     * @param processInstanceId
+     */
+    public void updEvent(CldsDao cldsDao, String processInstanceId) {
+        cldsDao.updEvent(event.getId(), processInstanceId);
+    }
+
+    /**
+     * set the status in the model
+     */
+    private void determineStatus() {
+
+        status = STATUS_UNKNOWN;
+        if (event == null || event.getActionCd() == null) {
+            status = STATUS_DESIGN;
+        } else if (event.isActionStateCd(CldsEvent.ACTION_STATE_ERROR)) {
+            status = STATUS_ERROR;
+        } else if (event.isActionAndStateCd(CldsEvent.ACTION_CREATE, CldsEvent.ACTION_STATE_ANY) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_SUBMIT, CldsEvent.ACTION_STATE_ANY) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_RESUBMIT, CldsEvent.ACTION_STATE_ANY) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_RECEIVED)) {
+            status = STATUS_DESIGN;
+        } else if (event.isActionAndStateCd(CldsEvent.ACTION_DISTRIBUTE, CldsEvent.ACTION_STATE_RECEIVED) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_UNDEPLOY, CldsEvent.ACTION_STATE_RECEIVED)) {
+            status = STATUS_DISTRIBUTED;
+        } else if (event.isActionAndStateCd(CldsEvent.ACTION_DELETE, CldsEvent.ACTION_STATE_SENT)) {
+            status = STATUS_DELETING;
+        } else if (event.isActionAndStateCd(CldsEvent.ACTION_DEPLOY, CldsEvent.ACTION_STATE_RECEIVED) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_RESTART, CldsEvent.ACTION_STATE_ANY) ||
+                event.isActionAndStateCd(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STATE_ANY)) {
+            status = STATUS_ACTIVE;
+        } else if (event.isActionAndStateCd(CldsEvent.ACTION_STOP, CldsEvent.ACTION_STATE_ANY)) {
+            status = STATUS_STOPPED;
+        }
+
+    }
+
+    /**
+     * Get the actionCd from current event.  If none, default value is CldsEvent.ACTION_CREATE
+     *
+     * @return
+     */
+    private String getCurrentActionCd() {
+        // current default actionCd is CREATE
+        String actionCd = CldsEvent.ACTION_CREATE;
+        if (event != null && event.getActionCd() != null) {
+            actionCd = event.getActionCd();
+        }
+        return actionCd;
+    }
+
+    /**
+     * Get the actionStateCd from current event.  If none, default value is CldsEvent.ACTION_STATE_COMPLETED
+     *
+     * @return
+     */
+    private String getCurrentActionStateCd() {
+        // current default actionStateCd is CREATE
+        String actionStateCd = CldsEvent.ACTION_STATE_COMPLETED;
+        if (event != null && event.getActionStateCd() != null) {
+            actionStateCd = event.getActionStateCd();
+        }
+        return actionStateCd;
+    }
+
+    /**
+     * Determine permittedActionCd list using the actionCd from the current event.
+     */
+    private void determinePermittedActionCd() {
+        String actionCd = getCurrentActionCd();
+        switch (actionCd) {
+            case CldsEvent.ACTION_CREATE:
+                permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMIT);
+                break;
+            case CldsEvent.ACTION_SUBMIT:
+            case CldsEvent.ACTION_RESUBMIT:
+                // for 1702 delete is not currently implemented (and resubmit requires manually deleting artifact from asdc
+                permittedActionCd = Arrays.asList(CldsEvent.ACTION_RESUBMIT);
+                break;
+            case CldsEvent.ACTION_DISTRIBUTE:
+            case CldsEvent.ACTION_UNDEPLOY:
+                permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE);
+                break;
+            case CldsEvent.ACTION_DEPLOY:
+            case CldsEvent.ACTION_RESTART:
+            case CldsEvent.ACTION_UPDATE:
+                // for 1702 delete is not currently implemented
+                permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_STOP);
+                break;
+            case CldsEvent.ACTION_DELETE:
+                if (getCurrentActionStateCd().equals(CldsEvent.ACTION_STATE_SENT)) {
+                    permittedActionCd = Arrays.asList();
+                } else {
+                    permittedActionCd = Arrays.asList(CldsEvent.ACTION_SUBMIT);
+                }
+                break;
+            case CldsEvent.ACTION_STOP:
+                // for 1702 delete is not currently implemented
+                permittedActionCd = Arrays.asList(CldsEvent.ACTION_UPDATE, CldsEvent.ACTION_RESTART);
+                break;
+            default:
+                logger.warn("Invalid current actionCd: " + actionCd);
+        }
+    }
+
+    /**
+     * Validate requestedActionCd - determine permittedActionCd and then check if contained in permittedActionCd
+     * Throw IllegalArgumentException if requested actionCd is not permitted.
+     *
+     * @param requestedActionCd
+     */
+    public void validateAction(String requestedActionCd) {
+        determinePermittedActionCd();
+        if (!permittedActionCd.contains(requestedActionCd)) {
+            throw new IllegalArgumentException("Invalid requestedActionCd: " + requestedActionCd + ".  Given current actionCd: " + getCurrentActionCd() + ", the permittedActionCd: " + permittedActionCd);
+        }
+    }
+
+    /**
+     * Extract the UUID portion of a given full control name (controlNamePrefix + controlNameUuid).
+     * No fields are populated other than controlNamePrefix and controlNameUuid.
+     * Throws BadRequestException if length of given control name is less than UUID_LENGTH.
+     *
+     * @param fullControlName
+     * @return
+     */
+    public static CldsModel createUsingControlName(String fullControlName) {
+
+        int len = 0;
+
+        if (fullControlName != null) {
+            len = fullControlName.length();
+        }
+        if (len < UUID_LENGTH) {
+            throw new BadRequestException("closed loop id / control name length, " + len + ", less than the minimum of: " + UUID_LENGTH);
+        }
+        CldsModel model = new CldsModel();
+        model.setControlNamePrefix(fullControlName.substring(0, len - UUID_LENGTH));
+        model.setControlNameUuid(fullControlName.substring(len - UUID_LENGTH));
+        return model;
+    }
+
+    /**
+     * @return the controlName (controlNamePrefix + controlNameUuid)
+     */
+    public String getControlName() {
+        return controlNamePrefix + controlNameUuid;
+    }
+
+    /**
+     * To insert modelInstance to the database
+     *
+     * @param cldsDao
+     * @param dcaeEvent
+     */
+    public static CldsModel insertModelInstance(CldsDao cldsDao, DcaeEvent dcaeEvent, String userid) {
+        String controlName = dcaeEvent.getControlName();
+        CldsModel cldsModel = createUsingControlName(controlName);
+        cldsModel = cldsDao.getModelByUuid(cldsModel.getControlNameUuid());
+        cldsModel.determineStatus();
+        if (dcaeEvent.getCldsActionCd().equals(CldsEvent.ACTION_UNDEPLOY) ||
+                (dcaeEvent.getCldsActionCd().equals(CldsEvent.ACTION_DEPLOY) && (cldsModel.getStatus().equals(STATUS_DISTRIBUTED) || cldsModel.getStatus().equals(STATUS_DESIGN)))) {
+            CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(), CldsEvent.ACTION_STATE_RECEIVED, null);
+        }
+        cldsDao.insModelInstance(cldsModel, dcaeEvent.getInstances());
+        return cldsModel;
+    }
+
+    /**
+     * To remove modelInstance from the database
+     * This method is defunct - DCAE Proxy will not undeploy individual instances.  It will send an empty list of
+     * deployed instances to indicate all have been removed.  Or it will send an updated list to indicate those that
+     * are still deployed with any not on the list considered undeployed.
+     *
+     * @param cldsDao
+     * @param dcaeEvent
+     */
+    @SuppressWarnings("unused")
+    private static CldsModel removeModelInstance(CldsDao cldsDao, DcaeEvent dcaeEvent) {
+        String controlName = dcaeEvent.getControlName();
+        //cldsModel = cldsDao.delModelInstance(cldsModel.getControlNameUuid(), dcaeEvent.getInstances() );
+        return createUsingControlName(controlName);
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(String templateId) {
+        this.templateId = templateId;
+    }
+
+    /**
+     * @return the controlNamePrefix
+     */
+    public String getControlNamePrefix() {
+        return controlNamePrefix;
+    }
+
+    /**
+     * @param controlNamePrefix the controlNamePrefix to set
+     */
+    public void setControlNamePrefix(String controlNamePrefix) {
+        this.controlNamePrefix = controlNamePrefix;
+    }
+
+    /**
+     * @return the controlNameUuid
+     */
+    public String getControlNameUuid() {
+        return controlNameUuid;
+    }
+
+    /**
+     * @param controlNameUuid the controlNameUuid to set
+     */
+    public void setControlNameUuid(String controlNameUuid) {
+        this.controlNameUuid = controlNameUuid;
+    }
+
+
+    /**
+     * @return the propUserid
+     */
+    public String getPropUserid() {
+        return propUserid;
+    }
+
+    /**
+     * @param propUserid the propUserid to set
+     */
+    public void setPropUserid(String propUserid) {
+        this.propUserid = propUserid;
+    }
+
+    /**
+     * @return the propText
+     */
+    public String getPropText() {
+        return propText;
+    }
+
+    /**
+     * @param propText the propText to set
+     */
+    public void setPropText(String propText) {
+        this.propText = propText;
+    }
+
+    /**
+     * @return the event
+     */
+    public CldsEvent getEvent() {
+        return event;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTemplateName() {
+        return templateName;
+    }
+
+    public void setTemplateName(String templateName) {
+        this.templateName = templateName;
+    }
+
+    public String getPropId() {
+        return propId;
+    }
+
+    public void setPropId(String propId) {
+        this.propId = propId;
+    }
+
+    /**
+     * @param event the event to set
+     */
+    public void setEvent(CldsEvent event) {
+        this.event = event;
+    }
+
+    /**
+     * @return the status
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status the status to set
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * @return the permittedActionCd
+     */
+    public List<String> getPermittedActionCd() {
+        return permittedActionCd;
+    }
+
+    /**
+     * @param permittedActionCd the permittedActionCd to set
+     */
+    public void setPermittedActionCd(List<String> permittedActionCd) {
+        this.permittedActionCd = permittedActionCd;
+    }
+
+    public String getBlueprintId() {
+        return blueprintId;
+    }
+
+    public void setBlueprintId(String blueprintId) {
+        this.blueprintId = blueprintId;
+    }
+
+    public String getBlueprintUserid() {
+        return blueprintUserid;
+    }
+
+    public void setBlueprintUserid(String blueprintUserid) {
+        this.blueprintUserid = blueprintUserid;
+    }
+
+    public String getBlueprintText() {
+        return blueprintText;
+    }
+
+    public void setBlueprintText(String blueprintText) {
+        this.blueprintText = blueprintText;
+    }
+
+    public String getBpmnId() {
+        return bpmnId;
+    }
+
+    public void setBpmnId(String bpmnId) {
+        this.bpmnId = bpmnId;
+    }
+
+    public String getBpmnUserid() {
+        return bpmnUserid;
+    }
+
+    public void setBpmnUserid(String bpmnUserid) {
+        this.bpmnUserid = bpmnUserid;
+    }
+
+    public String getBpmnText() {
+        return bpmnText;
+    }
+
+    public void setBpmnText(String bpmnText) {
+        this.bpmnText = bpmnText;
+    }
+
+    public String getImageId() {
+        return imageId;
+    }
+
+    public void setImageId(String imageId) {
+        this.imageId = imageId;
+    }
+
+    public String getImageUserid() {
+        return imageUserid;
+    }
+
+    public void setImageUserid(String imageUserid) {
+        this.imageUserid = imageUserid;
+    }
+
+    public String getImageText() {
+        return imageText;
+    }
+
+    public void setImageText(String imageText) {
+        this.imageText = imageText;
+    }
+
+    public String getDocId() {
+        return docId;
+    }
+
+    public void setDocId(String docId) {
+        this.docId = docId;
+    }
+
+    public String getDocUserid() {
+        return docUserid;
+    }
+
+    public void setDocUserid(String docUserid) {
+        this.docUserid = docUserid;
+    }
+
+    public String getDocText() {
+        return docText;
+    }
+
+    public void setDocText(String docText) {
+        this.docText = docText;
+    }
+
+    public List<CldsModelInstance> getCldsModelInstanceList() {
+        if (cldsModelInstanceList == null) {
+            cldsModelInstanceList = new ArrayList<>();
+        }
+        return cldsModelInstanceList;
+    }
+
+    public void setCldsModelInstanceList(List<CldsModelInstance> cldsModelInstanceList) {
+        this.cldsModelInstanceList = cldsModelInstanceList;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsModelInstance.java b/src/main/java/org/onap/clamp/clds/model/CldsModelInstance.java
new file mode 100644 (file)
index 0000000..4c16aad
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CldsModelInstance {
+
+    private String modelInstanceId;
+    private String location;
+    private String vmName;
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public void setVmName(String vmName) {
+        this.vmName = vmName;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public void setLocation(String location) {
+        this.location = location;
+    }
+
+    public String getModelInstanceId() {
+        return modelInstanceId;
+    }
+
+    public void setModelInstanceId(String modelInstanceId) {
+        this.modelInstanceId = modelInstanceId;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsServiceData.java b/src/main/java/org/onap/clamp/clds/model/CldsServiceData.java
new file mode 100644 (file)
index 0000000..8910839
--- /dev/null
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.service.CldsService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.NotAuthorizedException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CldsServiceData implements Serializable {
+    private static final Logger logger = LoggerFactory.getLogger(CldsServiceData.class);
+
+    private static final long serialVersionUID = 1L;
+
+    private String serviceInvariantUUID;
+    private String serviceUUID;
+    private Long ageOfRecord;
+    private List<CldsVfData> cldsVfs;
+
+    public String getServiceInvariantUUID() {
+        return serviceInvariantUUID;
+    }
+
+    public void setServiceInvariantUUID(String serviceInvariantUUID) {
+        this.serviceInvariantUUID = serviceInvariantUUID;
+    }
+
+    public List<CldsVfData> getCldsVfs() {
+        return cldsVfs;
+    }
+
+    public void setCldsVfs(List<CldsVfData> cldsVfs) {
+        this.cldsVfs = cldsVfs;
+    }
+
+    public String getServiceUUID() {
+        return serviceUUID;
+    }
+
+    public void setServiceUUID(String serviceUUID) {
+        this.serviceUUID = serviceUUID;
+    }
+
+    public CldsServiceData getCldsServiceCache(CldsDao cldsDao, String invariantServiceUUID) throws Exception {
+        return cldsDao.getCldsServiceCache(invariantServiceUUID);
+    }
+
+    public void setCldsServiceCache(CldsDao cldsDao, CldsDBServiceCache cldsDBServiceCache) throws Exception {
+        cldsDao.setCldsServiceCache(cldsDBServiceCache);
+    }
+
+    public Long getAgeOfRecord() {
+        return ageOfRecord;
+    }
+
+    public void setAgeOfRecord(Long ageOfRecord) {
+        this.ageOfRecord = ageOfRecord;
+    }
+
+    /**
+     * Filter out any VFs that the user is not authorized for.
+     * Use the CldsService to determine if the user is authorized for a VF.
+     *
+     * @param svc
+     */
+    public void filterVfs(CldsService svc) {
+        List<CldsVfData> filteredCldsVfs = new ArrayList<>();
+        if (cldsVfs == null) {
+            logger.debug("cldsVfs == null");
+        } else {
+            for (CldsVfData vf : cldsVfs) {
+                // if user is authorized for the VF then add it to the filtered list
+                try {
+                    if (svc.isAuthorizedForVf(vf.getVfInvariantResourceUUID())) {
+                        filteredCldsVfs.add(vf);
+                    }
+                } catch (NotAuthorizedException e) {
+                    logger.debug("user not authorized for {}", vf.getVfInvariantResourceUUID());
+                    // when not NotAuthorizedException - don't add to filteredCldsVfs list
+                }
+            }
+        }
+        // new filtered list replaces the list of VFs for the user
+        cldsVfs = filteredCldsVfs;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsTemplate.java b/src/main/java/org/onap/clamp/clds/model/CldsTemplate.java
new file mode 100644 (file)
index 0000000..6e2c8d7
--- /dev/null
@@ -0,0 +1,186 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.onap.clamp.clds.dao.CldsDao;
+
+import javax.ws.rs.NotFoundException;
+
+/**
+ * Represent a CLDS Model.
+ */
+public class CldsTemplate {
+
+    public static final String STATUS_DESIGN = "DESIGN";
+    public static final String STATUS_ACTIVE = "ACTIVE";
+    public static final String STATUS_STOPPED = "STOPPED";
+    public static final String STATUS_DELETING = "DELETING";
+    public static final String STATUS_ERROR = "ERROR"; // manual intervention required
+    public static final String STATUS_UNKNOWN = "UNKNOWN";
+
+    private String id;
+    private String name;
+    private String controlNamePrefix;
+    private String controlNameUuid;
+    private String bpmnId;
+    private String bpmnUserid;
+    private String bpmnText;
+    private String imageId;
+    private String imageUserid;
+    private String imageText;
+    private String propId;
+    private String propUserid;
+    private String propText;
+
+    /**
+     * Save template to DB.
+     *
+     * @param cldsDao
+     * @param userid
+     */
+    public void save(CldsDao cldsDao, String userid) {
+        cldsDao.setTemplate(this, userid);
+    }
+
+    /**
+     * Retrieve from DB.
+     *
+     * @param cldsDao
+     * @param name
+     * @return
+     */
+    public static CldsTemplate retrieve(CldsDao cldsDao, String name, boolean okIfNotFound) {
+        // get from db
+        CldsTemplate template = cldsDao.getTemplate(name);
+        if (template.getId() == null && !okIfNotFound) {
+            throw new NotFoundException();
+        }
+        return template;
+    }
+
+    public String getBpmnUserid() {
+        return bpmnUserid;
+    }
+
+    public void setBpmnUserid(String bpmnUserid) {
+        this.bpmnUserid = bpmnUserid;
+    }
+
+    public String getBpmnText() {
+        return bpmnText;
+    }
+
+    public void setBpmnText(String bpmnText) {
+        this.bpmnText = bpmnText;
+    }
+
+    public String getImageUserid() {
+        return imageUserid;
+    }
+
+    public void setImageUserid(String imageUserid) {
+        this.imageUserid = imageUserid;
+    }
+
+    public String getImageText() {
+        return imageText;
+    }
+
+    public void setImageText(String imageText) {
+        this.imageText = imageText;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getControlNamePrefix() {
+        return controlNamePrefix;
+    }
+
+    public void setControlNamePrefix(String controlNamePrefix) {
+        this.controlNamePrefix = controlNamePrefix;
+    }
+
+    public String getControlNameUuid() {
+        return controlNameUuid;
+    }
+
+    public void setControlNameUuid(String controlNameUuid) {
+        this.controlNameUuid = controlNameUuid;
+    }
+
+    public String getPropId() {
+        return propId;
+    }
+
+    public void setPropId(String propId) {
+        this.propId = propId;
+    }
+
+    public String getPropUserid() {
+        return propUserid;
+    }
+
+    public void setPropUserid(String propUserid) {
+        this.propUserid = propUserid;
+    }
+
+    public String getPropText() {
+        return propText;
+    }
+
+    public void setPropText(String propText) {
+        this.propText = propText;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getBpmnId() {
+        return bpmnId;
+    }
+
+    public void setBpmnId(String bpmnId) {
+        this.bpmnId = bpmnId;
+    }
+
+    public String getImageId() {
+        return imageId;
+    }
+
+    public void setImageId(String imageId) {
+        this.imageId = imageId;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsVfData.java b/src/main/java/org/onap/clamp/clds/model/CldsVfData.java
new file mode 100644 (file)
index 0000000..dbcfb34
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class CldsVfData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String vfName;
+    private String vfInvariantResourceUUID;
+    private List<CldsVfcData> cldsVfcs;
+
+    public String getVfName() {
+        return vfName;
+    }
+
+    public void setVfName(String vfName) {
+        this.vfName = vfName;
+    }
+
+    public List<CldsVfcData> getCldsVfcs() {
+        return cldsVfcs;
+    }
+
+    public void setCldsVfcs(List<CldsVfcData> cldsVfcs) {
+        this.cldsVfcs = cldsVfcs;
+    }
+
+    public String getVfInvariantResourceUUID() {
+        return vfInvariantResourceUUID;
+    }
+
+    public void setVfInvariantResourceUUID(String vfInvariantResourceUUID) {
+        this.vfInvariantResourceUUID = vfInvariantResourceUUID;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/CldsVfcData.java b/src/main/java/org/onap/clamp/clds/model/CldsVfcData.java
new file mode 100644 (file)
index 0000000..2d56d01
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class CldsVfcData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String vfcName;
+    private String vfcInvariantResourceUUID;
+    private List<CldsAlarmCondition> cldsAlarmConditions;
+
+    public String getVfcName() {
+        return vfcName;
+    }
+
+    public void setVfcName(String vfcName) {
+        this.vfcName = vfcName;
+    }
+
+    public List<CldsAlarmCondition> getCldsAlarmConditions() {
+        return cldsAlarmConditions;
+    }
+
+    public void setCldsAlarmConditions(List<CldsAlarmCondition> cldsAlarmConditions) {
+        this.cldsAlarmConditions = cldsAlarmConditions;
+    }
+
+    public String getVfcInvariantResourceUUID() {
+        return vfcInvariantResourceUUID;
+    }
+
+    public void setVfcInvariantResourceUUID(String vfcInvariantResourceUUID) {
+        this.vfcInvariantResourceUUID = vfcInvariantResourceUUID;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/DcaeEvent.java b/src/main/java/org/onap/clamp/clds/model/DcaeEvent.java
new file mode 100644 (file)
index 0000000..e10971e
--- /dev/null
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.jboss.resteasy.spi.BadRequestException;
+
+import java.util.List;
+
+/**
+ * Represent a DCAE Event.
+ */
+public class DcaeEvent {
+    public static final String EVENT_CREATED = "created";  // this is an event we (clds) sends to dcae
+    public static final String EVENT_DISTRIBUTION = "distribution";
+    public static final String EVENT_DEPLOYMENT = "deployment";
+    public static final String EVENT_UNDEPLOYMENT = "undeployment";
+    public static final String ARTIFACT_NAME_SUFFIX = ".yml";
+
+    private String event;
+    private String serviceUUID;
+    private String resourceUUID;
+    private String artifactName;  // controlName.yml
+    private List<CldsModelInstance> instances;
+
+    /**
+     * Transform a DCAE Event Action to a CldsEvent.actionCd
+     *
+     * @return
+     */
+    public String getCldsActionCd() {
+        if (event == null || event.length() == 0) {
+            throw new BadRequestException("action null or empty");
+        } else if (event.equals(EVENT_CREATED)) {
+            return CldsEvent.ACTION_CREATE;
+        } else if (event.equals(EVENT_DISTRIBUTION)) {
+            return CldsEvent.ACTION_DISTRIBUTE;
+        } else if (event.equals(EVENT_DEPLOYMENT) &&
+                (instances == null || instances.size() == 0)) {
+            return CldsEvent.ACTION_UNDEPLOY;
+        } else if (event.equals(EVENT_DEPLOYMENT)) {
+            return CldsEvent.ACTION_DEPLOY;
+            // EVENT_UNDEPLOYMENT is defunct - DCAE Proxy will not undeploy individual instances.  It will send an empty list of
+            // deployed instances to indicate all have been removed.  Or it will send an updated list to indicate those that
+            // are still deployed with any not on the list considered undeployed.
+            //} else if ( event.equals(EVENT_UNDEPLOYMENT) ) {
+            // return CldsEvent.ACTION_UNDEPLOY;
+        }
+        throw new BadRequestException("event value not valid: " + event);
+    }
+
+    /**
+     * Derive the controlName from the artifactName.
+     *
+     * @return the controlName
+     */
+    public String getControlName() {
+        if (artifactName != null && artifactName.endsWith(ARTIFACT_NAME_SUFFIX)) {
+            return artifactName.substring(0, artifactName.length() - ARTIFACT_NAME_SUFFIX.length());
+        } else {
+            throw new BadRequestException("artifactName value not valid (expecting it to end with " + ARTIFACT_NAME_SUFFIX + "): " + artifactName);
+        }
+    }
+
+    /**
+     * @return the event
+     */
+    public String getEvent() {
+        return event;
+    }
+
+    /**
+     * @param event the event to set
+     */
+    public void setEvent(String event) {
+        this.event = event;
+    }
+
+    /**
+     * @return the serviceUUID
+     */
+    public String getServiceUUID() {
+        return serviceUUID;
+    }
+
+    /**
+     * @param serviceUUID the serviceUUID to set
+     */
+    public void setServiceUUID(String serviceUUID) {
+        this.serviceUUID = serviceUUID;
+    }
+
+    /**
+     * @return the resourceUUID
+     */
+    public String getResourceUUID() {
+        return resourceUUID;
+    }
+
+    /**
+     * @param resourceUUID the resourceUUID to set
+     */
+    public void setResourceUUID(String resourceUUID) {
+        this.resourceUUID = resourceUUID;
+    }
+
+    /**
+     * @return the artifactName
+     */
+    public String getArtifactName() {
+        return artifactName;
+    }
+
+    /**
+     * @param artifactName the artifactName to set
+     */
+    public void setArtifactName(String artifactName) {
+        this.artifactName = artifactName;
+    }
+
+    public List<CldsModelInstance> getInstances() {
+        return instances;
+    }
+
+    public void setInstances(List<CldsModelInstance> instances) {
+        this.instances = instances;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/HelloWorld.java b/src/main/java/org/onap/clamp/clds/model/HelloWorld.java
new file mode 100644 (file)
index 0000000..1165f5d
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+public class HelloWorld {
+
+    private String message;
+
+    public HelloWorld() {
+        // needed for deserializer
+    }
+
+    public HelloWorld(String message) {
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        return "message = " + getMessage();
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/ValueItem.java b/src/main/java/org/onap/clamp/clds/model/ValueItem.java
new file mode 100644 (file)
index 0000000..804d185
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+/**
+ * ValueItem used for value lists.
+ */
+public class ValueItem {
+    private String value;
+
+    /**
+     * Instantiate using value.
+     *
+     * @param value
+     */
+    public ValueItem(String value) {
+        this.value = value;
+    }
+
+    public ValueItem() {
+    }
+
+    /**
+     * @return the value
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/Collector.java b/src/main/java/org/onap/clamp/clds/model/prop/Collector.java
new file mode 100644 (file)
index 0000000..84bc38f
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.logging.Logger;
+
+/**
+ * Parse Collector json properties.
+ */
+public class Collector extends ModelElement {
+    private static final Logger logger = Logger.getLogger(Collector.class.getName());
+
+    /**
+     * Parse Collector given json node.
+     *
+     * @param modelBpmn
+     * @param modelJson
+     */
+    public Collector(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+        super(TYPE_COLLECTOR, modelProp, modelBpmn, modelJson);
+        topicPublishes = getValueByName("topicPublishes");
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/Global.java b/src/main/java/org/onap/clamp/clds/model/prop/Global.java
new file mode 100644 (file)
index 0000000..f8986b3
--- /dev/null
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Parse global json properties.
+ * <p>
+ * Example json: "global":[{"name":"service","value":["vUSP"]},{"name":"vnf","value":["vCTS","v3CDB"]},{"name":"location","value":["san_diego","san_antonio","kansas_city","kings_mountain","Secaucus","lisle","concord","houston","akron"]}]
+ */
+public class Global {
+    private static final Logger logger = Logger.getLogger(Global.class.getName());
+
+    private String service;
+    private List<String> resourceVf;
+    private List<String> resourceVfc;
+    private List<String> location;
+
+    /**
+     * Parse global given json node.
+     *
+     * @param modelJson
+     */
+    public Global(JsonNode modelJson) {
+        JsonNode globalNode = modelJson.get("global");
+        service = ModelElement.getValueByName(globalNode, "service");
+        resourceVf = ModelElement.getValuesByName(globalNode, "vf");
+        resourceVfc = ModelElement.getValuesByName(globalNode, "vfc");
+        location = ModelElement.getValuesByName(globalNode, "location");
+    }
+
+    /**
+     * @return the service
+     */
+    public String getService() {
+        return service;
+    }
+
+    /**
+     * @param service the service to set
+     */
+    public void setService(String service) {
+        this.service = service;
+    }
+
+    /**
+     * @return the resourceVf
+     */
+    public List<String> getResourceVf() {
+        return resourceVf;
+    }
+
+    /**
+     * @param resourceVf the resourceVf to set
+     */
+    public void setResourceVf(List<String> resourceVf) {
+        this.resourceVf = resourceVf;
+    }
+
+    /**
+     * @return the resourceVfc
+     */
+    public List<String> getResourceVfc() {
+        return resourceVfc;
+    }
+
+    /**
+     * @param resourceVfc the resourceVfc to set
+     */
+    public void setResourceVfc(List<String> resourceVfc) {
+        this.resourceVfc = resourceVfc;
+    }
+
+    /**
+     * @return the location
+     */
+    public List<String> getLocation() {
+        return location;
+    }
+
+    /**
+     * @param location the location to set
+     */
+    public void setLocation(List<String> location) {
+        this.location = location;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/ModelBpmn.java b/src/main/java/org/onap/clamp/clds/model/prop/ModelBpmn.java
new file mode 100644 (file)
index 0000000..b4cc11d
--- /dev/null
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+/**
+ * Parse Model BPMN properties.
+ * <p>
+ * Example json: {"collector":[{"id":"Collector_11r50j1", "from":"StartEvent_1"}],"stringMatch":[{"id":"StringMatch_0h6cbdv"}],"policy":[{"id":"Policy_0oxeocn", "from":"StringMatch_0h6cbdv"}]}
+ */
+public class ModelBpmn {
+    private static final Logger logger = Logger.getLogger(ModelBpmn.class.getName());
+
+    // for each type, an array of entries
+    private final Map<String, List<ModelBpmnEntry>> entriesByType = new HashMap<>();
+
+    // for each id, an array of entries
+    private final Map<String, List<ModelBpmnEntry>> entriesById   = new HashMap<>();
+
+    // List of all elementIds
+    private List<String>                            bpmnElementIds;
+
+    /**
+     * Create ModelBpmn and populate maps from json
+     *
+     * @param modelBpmnPropText
+     * @return
+     * @throws IOException
+     * @throws JsonMappingException
+     * @throws JsonParseException
+     */
+    public static ModelBpmn create(String modelBpmnPropText) throws IOException {
+        ModelBpmn modelBpmn = new ModelBpmn();
+        ObjectMapper objectMapper = new ObjectMapper();
+        ObjectNode root = objectMapper.readValue(modelBpmnPropText, ObjectNode.class);
+        // iterate over each entry like: "collector":[{"id":"Collector_11r50j1","from":"StartEvent_1"}]
+        Iterator<Entry<String, JsonNode>> entryItr = root.fields();
+        List<String> bpmnElementIdList = new ArrayList<>();
+        while (entryItr.hasNext()) {
+            // process the entry
+            Entry<String, JsonNode> entry = entryItr.next();
+            String type = entry.getKey();
+            ArrayNode arrayNode = (ArrayNode) entry.getValue();
+            // process each id/from object, like: {"id":"Collector_11r50j1","from":"StartEvent_1"}
+            for (JsonNode anArrayNode : arrayNode) {
+                ObjectNode node = (ObjectNode) anArrayNode;
+                String id = node.get("id").asText();
+                String fromId = node.get("from").asText();
+                ModelBpmnEntry modelBpmnEntry = new ModelBpmnEntry(type, id, fromId);
+                modelBpmn.addEntry(modelBpmnEntry);
+                bpmnElementIdList.add(id);
+            }
+            modelBpmn.setBpmnElementIds(bpmnElementIdList);
+        }
+        return modelBpmn;
+    }
+
+    /**
+     * Add entry to both maps.
+     *
+     * @param entry
+     */
+    private void addEntry(ModelBpmnEntry entry) {
+        addEntry(entriesByType, entry, entry.getType());
+        addEntry(entriesById, entry, entry.getId());
+    }
+
+    /**
+     * Add an entry to provided map with provided key.
+     *
+     * @param map
+     * @param entry
+     * @param key
+     */
+    private static void addEntry(Map<String, List<ModelBpmnEntry>> map, ModelBpmnEntry entry, String key) {
+        List<ModelBpmnEntry> list = map.computeIfAbsent(key, k -> new ArrayList<>());
+        list.add(entry);
+    }
+
+    /**
+     * 
+     * 
+     * @param type
+     * @return true if the element is found or false otherwise
+     */
+    public boolean getModelElementFound(String type) {
+        return entriesByType.get(type) != null;
+    }
+
+    /**
+     * @return the id field given the ModelElement type
+     */
+    public String getId(String type) {
+        return entriesByType.get(type).get(0).getId();
+    }
+
+    /**
+     * @return the fromId field given the ModelElement type
+     */
+    public String getFromId(String type) {
+        return entriesByType.get(type).get(0).getFromId();
+    }
+
+    /**
+     * @return the ModelElement type given the ModelElement id
+     */
+    public String getType(String id) {
+        return entriesById.get(id).get(0).getType();
+    }
+
+    /**
+     * @return list of elementIds from bpmn
+     */
+    public List<String> getBpmnElementIds() {
+        return bpmnElementIds;
+    }
+
+    public void setBpmnElementIds(List<String> bpmnElementIds) {
+        this.bpmnElementIds = bpmnElementIds;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/ModelBpmnEntry.java b/src/main/java/org/onap/clamp/clds/model/prop/ModelBpmnEntry.java
new file mode 100644 (file)
index 0000000..8002f44
--- /dev/null
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import java.util.logging.Logger;
+
+/**
+ * Model BPMN property entry
+ * <p>
+ * Example json: {"collector":[{"id":"Collector_11r50j1", "from":"StartEvent_1"}],"stringMatch":[{"id":"StringMatch_0h6cbdv"],"policy":[{"id":"Policy_0oxeocn", "from":"StringMatch_0h6cbdv"}]}
+ */
+public class ModelBpmnEntry {
+    private static final Logger logger = Logger.getLogger(ModelBpmnEntry.class.getName());
+
+    private String type;
+    private String id;
+    private String fromId;
+
+    /**
+     * Parse the json so that the "id" and "from" fields can be retrieved on demand.
+     *
+     * @param type
+     * @param id
+     * @param fromId
+     */
+    public ModelBpmnEntry(String type, String id, String fromId) {
+        this.type = type;
+        this.id = id;
+        this.fromId = fromId;
+    }
+
+    /**
+     * @return the type
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @param id the id to set
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the fromId
+     */
+    public String getFromId() {
+        return fromId;
+    }
+
+    /**
+     * @param fromId the fromId to set
+     */
+    public void setFromId(String fromId) {
+        this.fromId = fromId;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/ModelElement.java b/src/main/java/org/onap/clamp/clds/model/prop/ModelElement.java
new file mode 100644 (file)
index 0000000..d8e9030
--- /dev/null
@@ -0,0 +1,232 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Provide base ModelElement functionality.
+ */
+public abstract class ModelElement {
+    private final static Logger   sLOGGER           = Logger.getLogger(ModelElement.class.getName());
+    private static final Logger logger = Logger.getLogger(ModelElement.class.getName());
+
+    public static final String    TYPE_COLLECTOR    = "collector";
+    public static final String    TYPE_STRING_MATCH = "stringMatch";
+    public static final String    TYPE_POLICY       = "policy";
+    public static final String    TYPE_TCA          = "tca";
+
+    private final String          type;
+    private final ModelBpmn       modelBpmn;
+    private final String          id;
+    protected String              topicPublishes;
+    protected final JsonNode      meNode;
+    private boolean               isFound;
+
+    private final ModelProperties modelProp;
+
+    /**
+     * Perform base parsing of properties for a ModelElement (such as,
+     * Collector, StringMatch, Policy and Tca)
+     * 
+     * @param type
+     * @param modelProp
+     * @param modelBpmn
+     * @param modelJson
+     */
+    protected ModelElement(String type, ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+        this.type = type;
+        this.modelProp = modelProp;
+        this.modelBpmn = modelBpmn;
+        this.id = modelBpmn.getId(type);
+        this.meNode = modelJson.get(id);
+        this.isFound = modelBpmn.getModelElementFound(type);
+    }
+
+    /**
+     * topicSubscribes is the topicPublishes of the from Model Element
+     *
+     * @return the topicSubscribes
+     */
+    public String getTopicSubscribes() {
+        // get fromId for this type
+        String fromId = modelBpmn.getFromId(type);
+        // find the type of the from model element
+        String fromType = modelBpmn.getType(fromId);
+        // get the model element for the type
+        ModelElement me = modelProp.getModelElementByType(fromType);
+        // get the topic publishes for the model element
+        return me.topicPublishes;
+    }
+
+    /**
+     * @return the topicPublishes
+     */
+    public String getTopicPublishes() {
+        return topicPublishes;
+    }
+
+    /**
+     * Return the value field of the json node element that has a name field
+     * equals to the given name.
+     *
+     * @param nodeIn
+     * @param name
+     * @return
+     */
+    public static String getValueByName(JsonNode nodeIn, String name) {
+        String value = null;
+        if (nodeIn != null) {
+            for (JsonNode node : nodeIn) {
+                if (node.path("name").asText().equals(name)) {
+                    JsonNode vnode = node.path("value");
+                    if (vnode.isArray()) {
+                        // if array, assume value is in first element
+                        value = vnode.path(0).asText();
+                    } else {
+                        // otherwise, just return text
+                        value = vnode.asText();
+                    }
+                }
+            }
+        }
+        if (value == null || value.length() == 0) {
+            sLOGGER.warning(name + "=" + value);
+        } else {
+            sLOGGER.fine(name + "=" + value);
+        }
+        return value;
+    }
+
+    /**
+     * Return the int value field of the json node element that has a name field
+     * equals to the given name.
+     *
+     * @param nodeIn
+     * @param name
+     * @return
+     */
+    public static Integer getIntValueByName(JsonNode nodeIn, String name) {
+        String value = getValueByName(nodeIn, name);
+        return Integer.valueOf(value);
+    }
+
+    /**
+     * Return an array of values for the field of the json node element that has
+     * a name field equals to the given name.
+     *
+     * @param nodeIn
+     * @param name
+     * @return
+     */
+    public static List<String> getValuesByName(JsonNode nodeIn, String name) {
+        List<String> values = null;
+        if (nodeIn != null) {
+            Iterator<JsonNode> i = nodeIn.iterator();
+            while (i.hasNext()) {
+                JsonNode node = i.next();
+                if (node.path("name").asText().equals(name)) {
+                    values = getValuesList(node);
+                }
+            }
+        }
+        if (values == null || values.size() == 0) {
+            sLOGGER.warning(name + "=" + values);
+        } else {
+            sLOGGER.fine(name + "=" + values);
+        }
+        return values;
+    }
+
+    /**
+     * Return an array of String values.
+     *
+     * @param nodeIn
+     * @return
+     */
+    public static List<String> getValuesList(JsonNode nodeIn) {
+        ArrayList<String> al = new ArrayList<>();
+        if (nodeIn != null) {
+            Iterator<JsonNode> itr = nodeIn.path("value").elements();
+            while (itr.hasNext()) {
+                JsonNode node = itr.next();
+                al.add(node.asText());
+            }
+        }
+        return al;
+    }
+
+    /**
+     * Return the value field of the json node element that has a name field
+     * equals to the given name.
+     *
+     * @param name
+     * @return
+     */
+    public String getValueByName(String name) {
+        return getValueByName(meNode, name);
+    }
+
+    /**
+     * Return the int value field of the json node element that has a name field
+     * equals to the given name.
+     *
+     * @param name
+     * @return
+     */
+    public Integer getIntValueByName(String name) {
+        return getIntValueByName(meNode, name);
+    }
+
+    /**
+     * Return an array of values for the field of the json node element that has
+     * a name field equals to the given name.
+     *
+     * @param name
+     * @return
+     */
+    public List<String> getValuesByName(String name) {
+        return getValuesByName(meNode, name);
+    }
+
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @return the isFound
+     */
+    public boolean isFound() {
+        return isFound;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/ModelProperties.java b/src/main/java/org/onap/clamp/clds/model/prop/ModelProperties.java
new file mode 100644 (file)
index 0000000..014b8c7
--- /dev/null
@@ -0,0 +1,320 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.clamp.clds.model.CldsEvent;
+import org.onap.clamp.clds.model.CldsModel;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Parse model properties.
+ */
+public class ModelProperties {
+    private static final Logger logger = Logger.getLogger(ModelProperties.class.getName());
+
+    private ModelBpmn     modelBpmn;
+    private JsonNode      modelJson;
+
+    private final String  modelName;
+    private final String  controlName;
+    private final String  actionCd;
+
+    private Global        global;
+    private Collector     collector;
+    private StringMatch   stringMatch;
+    private Policy        policy;
+    private Tca           tca;
+
+    private String        currentModelElementId;
+    private String        policyUniqueId;
+
+    /**
+     * Retain data required to parse the ModelElement objects. (Rather than
+     * parse them all - parse them on demand if requested.)
+     *
+     * @param modelName
+     * @param controlName
+     * @param actionCd
+     * @param modelBpmnPropText
+     * @param modelPropText
+     * @throws JsonProcessingException
+     * @throws IOException
+     */
+    public ModelProperties(String modelName, String controlName, String actionCd, String modelBpmnPropText, String modelPropText) throws IOException {
+        this.modelName = modelName;
+        this.controlName = controlName;
+        this.actionCd = actionCd;
+        modelBpmn = ModelBpmn.create(modelBpmnPropText);
+        ObjectMapper mapper = new ObjectMapper();
+        modelJson = mapper.readTree(modelPropText);
+    }
+
+    /**
+     * Get the VF for a model. If return null if there is no VF.
+     *
+     * @param model
+     * @return
+     */
+    public static String getVf(CldsModel model) {
+        List<String> vfs = null;
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode modelJson = mapper.readTree(model.getPropText());
+            Global global = new Global(modelJson);
+            vfs = global.getResourceVf();
+        } catch (IOException e) {
+            // VF is null
+        }
+        String vf = null;
+        if (vfs != null && !vfs.isEmpty()) {
+            vf = vfs.get(0);
+        }
+        return vf;
+    }
+
+    /**
+     * Create ModelProperties for Camunda Delegate.
+     *
+     * @param execution
+     * @return
+     * @throws JsonProcessingException
+     * @throws IOException
+     */
+    public static ModelProperties create(DelegateExecution execution) throws IOException {
+        String modelProp = (String) execution.getVariable("modelProp");
+        String modelBpmnProp = (String) execution.getVariable("modelBpmnProp");
+        String modelName = (String) execution.getVariable("modelName");
+        String controlName = (String) execution.getVariable("controlName");
+        String actionCd = (String) execution.getVariable("actionCd");
+
+        return new ModelProperties(modelName, controlName, actionCd, modelBpmnProp, modelProp);
+    }
+
+    /**
+     * return appropriate model element given the type
+     *
+     * @param type
+     * @return
+     */
+    public ModelElement getModelElementByType(String type) {
+        ModelElement me;
+        switch (type) {
+            case ModelElement.TYPE_COLLECTOR:
+                me = getCollector();
+                break;
+            case ModelElement.TYPE_STRING_MATCH:
+                me = getStringMatch();
+                break;
+            case ModelElement.TYPE_POLICY:
+                me = getPolicy();
+                break;
+            case ModelElement.TYPE_TCA:
+                me = getTca();
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid ModelElement type: " + type);
+        }
+        return me;
+    }
+
+    /**
+     * @return the modelName
+     */
+    public String getModelName() {
+        return modelName;
+    }
+
+    /**
+     * @return the controlName
+     */
+    public String getControlName() {
+        return controlName;
+    }
+
+    /**
+     * @return the controlNameAndPolicyUniqueId
+     */
+    public String getControlNameAndPolicyUniqueId() {
+        return controlName + "_" + policyUniqueId;
+    }
+
+    /**
+     * @return the currentPolicyName
+     */
+    private String getCurrentPolicyName() {
+        return normalizePolicyScopeName(controlName + "_" + currentModelElementId);
+    }
+
+    /**
+     * @return the currentPolicyScopeAndPolicyName
+     */
+    public String getCurrentPolicyScopeAndPolicyName() {
+        return normalizePolicyScopeName(modelName + "." + getCurrentPolicyName());
+    }
+
+    /**
+     * @return the currentPolicyScopeAndFullPolicyName
+     */
+    public String getCurrentPolicyScopeAndFullPolicyName(String policyNamePrefix) {
+        return normalizePolicyScopeName(modelName + "." + policyNamePrefix + getCurrentPolicyName());
+    }
+
+    /**
+     * @return the currentPolicyScopeAndFullPolicyNameWithVersion
+     */
+    public String getCurrentPolicyScopeAndFullPolicyNameWithVersion(String policyNamePrefix, int version) {
+        return normalizePolicyScopeName(
+                modelName + "." + policyNamePrefix + getCurrentPolicyName() + "." + version + ".xml");
+    }
+
+    /**
+     * Replace all '-' with '_' within policy scope and name.
+     *
+     * @param inName
+     * @return
+     */
+    private String normalizePolicyScopeName(String inName) {
+        return inName.replaceAll("-", "_");
+    }
+
+    /**
+     * @return the currentModelElementId
+     */
+    public String getCurrentModelElementId() {
+        return currentModelElementId;
+    }
+
+    /**
+     * When generating a policy request for a model element, must set the id of
+     * that model element using this method. Used to generate the policy name.
+     *
+     * @param currentModelElementId
+     *            the currentModelElementId to set
+     */
+    public void setCurrentModelElementId(String currentModelElementId) {
+        this.currentModelElementId = currentModelElementId;
+    }
+
+    /**
+     * @return the policyUniqueId
+     */
+    public String getPolicyUniqueId() {
+        return policyUniqueId;
+    }
+
+    /**
+     * When generating a policy request for a model element, must set the unique
+     * id of that policy using this method. Used to generate the policy name.
+     * 
+     * @param policyUniqueId
+     *            the policyUniqueId to set
+     */
+    public void setPolicyUniqueId(String policyUniqueId) {
+        this.policyUniqueId = policyUniqueId;
+    }
+
+    /**
+     * @return the collector
+     */
+    public Collector getCollector() {
+        if (collector == null) {
+            collector = new Collector(this, modelBpmn, modelJson);
+        }
+        return collector;
+    }
+
+    /**
+     * @return the actionCd
+     */
+    public String getActionCd() {
+        return actionCd;
+    }
+
+    /**
+     * @return the isCreateRequest
+     */
+    public boolean isCreateRequest() {
+        switch (actionCd) {
+            case CldsEvent.ACTION_SUBMIT:
+            case CldsEvent.ACTION_RESTART:
+                return true;
+        }
+        return false;
+    }
+
+    public boolean isStopRequest() {
+        switch (actionCd) {
+            case CldsEvent.ACTION_STOP:
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return the global
+     */
+    public Global getGlobal() {
+        if (global == null) {
+            global = new Global(modelJson);
+        }
+        return global;
+    }
+
+    /**
+     * @return the stringMatch
+     */
+    public StringMatch getStringMatch() {
+        if (stringMatch == null) {
+            stringMatch = new StringMatch(this, modelBpmn, modelJson);
+        }
+        return stringMatch;
+    }
+
+    /**
+     * @return the policy
+     */
+    public Policy getPolicy() {
+        if (policy == null) {
+            policy = new Policy(this, modelBpmn, modelJson);
+        }
+        return policy;
+    }
+
+    /**
+     * @return the tca
+     */
+    public Tca getTca() {
+        if (tca == null) {
+            tca = new Tca(this, modelBpmn, modelJson);
+        }
+        return tca;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/Policy.java b/src/main/java/org/onap/clamp/clds/model/prop/Policy.java
new file mode 100644 (file)
index 0000000..729eb43
--- /dev/null
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Parse Policy json properties.
+ * <p>
+ * Example json: "Policy_005sny1":[[{"name":"timeout","value":"5"}],{"policyConfigurations":[[{"name":"recipe","value":["restart"]},{"name":"maxRetries","value":["3"]},{"name":"retryTimeLimit","value":["180"]},{"name":"_id","value":["vf3RtPi"]},{"name":"location","value":["san_diego"]},{"name":"resource","value":["vCTS"]},{"name":"onMaxRetriesLimit","value":[""]},{"name":"onTimeLimit","value":[""]},{"name":"onOtherFailure","value":[""]},{"name":"policy_parent","value":[""]}],[{"name":"recipe","value":["rebuild"]},{"name":"maxRetries","value":["3"]},{"name":"retryTimeLimit","value":["180"]},{"name":"_id","value":["89z8Ncl"]},{"name":"location","value":["san_diego"]},{"name":"resource","value":["vCTS"]},{"name":"onMaxRetriesLimit","value":[""]},{"name":"onTimeLimit","value":[""]},{"name":"onOtherFailure","value":[""]},{"name":"policy_parent","value":["vf3RtPi"]}]]}]
+ */
+public class Policy extends ModelElement {
+    private static final Logger logger = Logger.getLogger(Policy.class.getName());
+
+    private final Integer timeout;
+    private final List<PolicyItem> policyItems;
+
+    /**
+     * Parse Policy given json node.
+     *
+     * @param modelProp
+     * @param modelBpmn
+     * @param modelJson
+     */
+    public Policy(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+        super(TYPE_POLICY, modelProp, modelBpmn, modelJson);
+        timeout = getIntValueByName(meNode.get(0), "timeout");
+
+        // process policies
+        JsonNode policyNode = meNode.get(1).get("policyConfigurations");
+        Iterator<JsonNode> itr = policyNode.elements();
+        policyItems = new ArrayList<>();
+        while (itr.hasNext()) {
+            policyItems.add(new PolicyItem(itr.next()));
+        }
+    }
+
+    /**
+     * @return the timeout
+     */
+    public Integer getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * @return the policyItems
+     */
+    public List<PolicyItem> getPolicyItems() {
+        return policyItems;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/PolicyItem.java b/src/main/java/org/onap/clamp/clds/model/prop/PolicyItem.java
new file mode 100644 (file)
index 0000000..a943f18
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Parse policyConfigurations from Policy json properties.
+ * <p>
+ * Example json: "Policy_005sny1":[[{"name":"timeout","value":"5"}],{"policyConfigurations":[[{"name":"recipe","value":["restart"]},{"name":"maxRetries","value":["3"]},{"name":"retryTimeLimit","value":["180"]},{"name":"_id","value":["vf3RtPi"]},{"name":"location","value":["san_diego"]},{"name":"resource","value":["vCTS"]},{"name":"onMaxRetriesLimit","value":[""]},{"name":"onTimeLimit","value":[""]},{"name":"onOtherFailure","value":[""]},{"name":"policy_parent","value":[""]}],[{"name":"recipe","value":["rebuild"]},{"name":"maxRetries","value":["3"]},{"name":"retryTimeLimit","value":["180"]},{"name":"_id","value":["89z8Ncl"]},{"name":"location","value":["san_diego"]},{"name":"resource","value":["vCTS"]},{"name":"onMaxRetriesLimit","value":[""]},{"name":"onTimeLimit","value":[""]},{"name":"onOtherFailure","value":[""]},{"name":"policy_parent","value":["vf3RtPi"]}]]}]
+ */
+public class PolicyItem {
+    private static final Logger logger = Logger.getLogger(Policy.class.getName());
+
+    private final String id;
+    private final String recipe;
+    private final int maxRetries;
+    private final int retryTimeLimit;
+    private final String parentPolicy;
+    private final List<String> parentPolicyConditions;
+
+    /**
+     * Parse Policy given json node.
+     *
+     * @param node
+     */
+    public PolicyItem(JsonNode node) {
+        id = ModelElement.getValueByName(node, "_id");
+        recipe = ModelElement.getValueByName(node, "recipe");
+        maxRetries = ModelElement.getIntValueByName(node, "maxRetries");
+        retryTimeLimit = ModelElement.getIntValueByName(node, "retryTimeLimit");
+        parentPolicy = ModelElement.getValueByName(node, "parentPolicy");
+        parentPolicyConditions = ModelElement.getValuesByName(node, "parentPolicyConditions");
+
+    }
+
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @return the recipe
+     */
+    public String getRecipe() {
+        return recipe;
+    }
+
+    /**
+     * @return the maxRetries
+     */
+    public int getMaxRetries() {
+        return maxRetries;
+    }
+
+    /**
+     * @return the retryTimeLimit
+     */
+    public int getRetryTimeLimit() {
+        return retryTimeLimit;
+    }
+
+    /**
+     * @return the parentPolicy
+     */
+    public String getParentPolicy() {
+        return parentPolicy;
+    }
+
+    /**
+     * @return the parentPolicyConditions
+     */
+    public List<String> getParentPolicyConditions() {
+        return parentPolicyConditions;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/ServiceConfiguration.java b/src/main/java/org/onap/clamp/clds/model/prop/ServiceConfiguration.java
new file mode 100644 (file)
index 0000000..498f852
--- /dev/null
@@ -0,0 +1,156 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Parse serviceConfigurations from StringMatch json properties.
+ * <p>
+ * Example json: "StringMatch_0c2cy0c":[[{"name":"topicPublishes","value":"DCAE-CL-EVENT"}],{"serviceConfigurations":[[{"name":"aaiMatchingFields","value":["VMID"]},{"name":"aaiSendFields","value":["VNFNAME","LOCID"]},{"name":"vnf","value":["aSBG"]},{"name":"timeWindow","value":["0"]},{"name":"ageLimit","value":["1600"]},{"name":"createClosedLoopEventId","value":["Initial"]},{"name":"outputEventName","value":["OnSet"]},{"stringSet":[{"name":"alarmCondition","value":["authenticationFailure"]},{"name":"eventSeverity","value":["NORMAL"]},{"name":"eventSourceType","value":["f5BigIP"]}]}],[{"name":"aaiMatchingFields","value":["VMID"]},{"name":"aaiSendFields","value":["VMID","Identiy","VNFNAME"]},{"name":"vnf","value":["aSBG"]},{"name":"timeWindow","value":["0"]},{"name":"ageLimit","value":["1600"]},{"name":"createClosedLoopEventId","value":["Close"]},{"name":"outputEventName","value":["Abatement"]},{"stringSet":[{"name":"alarmCondition","value":["authenticationFailure"]},{"name":"eventSeverity","value":["NORMAL"]},{"name":"eventSourceType","value":["f5BigIP"]}]}]]}]
+ */
+public class ServiceConfiguration {
+
+    private static final Logger logger = Logger.getLogger(ServiceConfiguration.class.getName());
+
+    private final List<String> aaiMatchingFields;
+    private final List<String> aaiSendFields;
+    private final String groupNumber;
+    private final List<String> resourceVf;
+    private final List<String> resourceVfc;
+    private final String timeWindow;
+    private final String ageLimit;
+    private final String createClosedLoopEventId;
+    private final String outputEventName;
+    private final Map<String, String> stringSet;
+
+    /**
+     * Parse serviceConfigurations given json node.
+     *
+     * @param node
+     */
+    public ServiceConfiguration(JsonNode node) {
+        aaiMatchingFields = ModelElement.getValuesByName(node, "aaiMatchingFields");
+        aaiSendFields = ModelElement.getValuesByName(node, "aaiSendFields");
+        groupNumber = ModelElement.getValueByName(node, "groupNumber");
+        resourceVf = ModelElement.getValuesByName(node, "vf");
+        resourceVfc = ModelElement.getValuesByName(node, "vfc");
+        timeWindow = ModelElement.getValueByName(node, "timeWindow");
+        ageLimit = ModelElement.getValueByName(node, "ageLimit");
+        createClosedLoopEventId = ModelElement.getValueByName(node, "createClosedLoopEventId");
+        outputEventName = ModelElement.getValueByName(node, "outputEventName");
+
+        // process the stringSet fields
+        JsonNode ssNodes = node.findPath("stringSet");
+        Iterator<JsonNode> itr = ssNodes.elements();
+        stringSet = new HashMap<>();
+        while (itr.hasNext()) {
+            JsonNode ssNode = itr.next();
+            String key = ssNode.path("name").asText();
+            String value = ssNode.path("value").path(0).asText();
+            if (key.length() != 0 && value.length() != 0) {
+                // only add string set field if not null
+                logger.fine("stringSet: " + key + "=" + value);
+                stringSet.put(key, value);
+            }
+        }
+    }
+
+    /**
+     * @return the aaiMatchingFields
+     */
+    public List<String> getaaiMatchingFields() {
+        return aaiMatchingFields;
+    }
+
+    /**
+     * @return the aaiSendFields
+     */
+    public List<String> getaaiSendFields() {
+        return aaiSendFields;
+    }
+
+    /**
+     * @return the groupNumber
+     */
+    public String getGroupNumber() {
+        return groupNumber;
+    }
+
+    /**
+     * @return the resourceVf
+     */
+    public List<String> getResourceVf() {
+        return resourceVf;
+    }
+
+    /**
+     * @return the resourceVfc
+     */
+    public List<String> getResourceVfc() {
+        return resourceVfc;
+    }
+
+    /**
+     * @return the timeWindow
+     */
+    public String getTimeWindow() {
+        return timeWindow;
+    }
+
+    /**
+     * @return the ageLimit
+     */
+    public String getAgeLimit() {
+        return ageLimit;
+    }
+
+    /**
+     * @return the createClosedLoopEventId
+     */
+    public String getCreateClosedLoopEventId() {
+        return createClosedLoopEventId;
+    }
+
+    /**
+     * @return the outputEventName
+     */
+    public String getOutputEventName() {
+        return outputEventName;
+    }
+
+    /**
+     * @return the stringSet
+     */
+    public Map<String, String> getStringSet() {
+        return stringSet;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/StringMatch.java b/src/main/java/org/onap/clamp/clds/model/prop/StringMatch.java
new file mode 100644 (file)
index 0000000..d7092c4
--- /dev/null
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Parse StringMatch json properties.
+ * <p>
+ * Example json: "StringMatch_0c2cy0c":[[{"name":"topicPublishes","value":"DCAE-CL-EVENT"}],{"serviceConfigurations":[[{"name":"aaiMatchingFields","value":["VMID"]},{"name":"aaiSendFields","value":["VNFNAME","LOCID"]},{"name":"vnf","value":["aSBG"]},{"name":"timeWindow","value":["0"]},{"name":"ageLimit","value":["1600"]},{"name":"createClosedLoopEventId","value":["Initial"]},{"name":"outputEventName","value":["OnSet"]},{"stringSet":[{"name":"alarmCondition","value":["authenticationFailure"]},{"name":"eventSeverity","value":["NORMAL"]},{"name":"eventSourceType","value":["f5BigIP"]}]}],[{"name":"aaiMatchingFields","value":["VMID"]},{"name":"aaiSendFields","value":["VMID","Identiy","VNFNAME"]},{"name":"vnf","value":["aSBG"]},{"name":"timeWindow","value":["0"]},{"name":"ageLimit","value":["1600"]},{"name":"createClosedLoopEventId","value":["Close"]},{"name":"outputEventName","value":["Abatement"]},{"stringSet":[{"name":"alarmCondition","value":["authenticationFailure"]},{"name":"eventSeverity","value":["NORMAL"]},{"name":"eventSourceType","value":["f5BigIP"]}]}]]}]
+ */
+public class StringMatch extends ModelElement {
+    private static final Logger logger = Logger.getLogger(StringMatch.class.getName());
+
+    private final List<ServiceConfiguration> serviceConfigurations;
+
+    /**
+     * Parse StringMatch given json node.
+     *
+     * @param modelBpmn
+     * @param modelJson
+     */
+    public StringMatch(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+        super(ModelElement.TYPE_STRING_MATCH, modelProp, modelBpmn, modelJson);
+
+        topicPublishes = getValueByName(meNode.get(0), "topicPublishes");
+
+        // process Server_Configurations
+        JsonNode serviceConfigurationsNode = meNode.get(1).get("serviceConfigurations");
+        Iterator<JsonNode> itr = serviceConfigurationsNode.elements();
+        serviceConfigurations = new ArrayList<>();
+        while (itr.hasNext()) {
+            serviceConfigurations.add(new ServiceConfiguration(itr.next()));
+        }
+    }
+
+    /**
+     * @return the serviceConfigurations
+     */
+    public List<ServiceConfiguration> getServiceConfigurations() {
+        return serviceConfigurations;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/Tca.java b/src/main/java/org/onap/clamp/clds/model/prop/Tca.java
new file mode 100644 (file)
index 0000000..c7b2360
--- /dev/null
@@ -0,0 +1,47 @@
+package org.onap.clamp.clds.model.prop;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Parse Tca json properties.
+ * 
+ * Example json: {"TCA_0lm6cix":{"Narra":[{"name":"tname","value":"Narra"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Polcicy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Critical"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_1",">","4"],["FIELDPATH_test_1","=","5"]]}],"Srini":[{"name":"tname","value":"Srini"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Policy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Major"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_2","=","3"],["FIELDPATH_test_1",">","2"]]}]}}
+ * 
+ *
+ */
+public class Tca extends ModelElement {
+       
+    private static final Logger logger = Logger.getLogger(StringMatch.class.getName());
+       
+       private List<TcaItem> tcaItems;
+
+       /**
+        * Parse Tca given json node
+        * 
+        * @param modelProp
+        * @param modelBpmn
+        * @param modelJson
+        */
+       public Tca(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+               super(ModelElement.TYPE_TCA, modelProp, modelBpmn, modelJson);
+               
+               // process Server_Configurations
+               if(meNode != null){
+                       Iterator<JsonNode> itr = meNode.elements();
+                       tcaItems = new ArrayList<TcaItem>();
+                       while(itr.hasNext()) {
+                               tcaItems.add(new TcaItem(itr.next()));
+                       }
+               }
+       }
+
+       public List<TcaItem> getTcaItems() {
+               return tcaItems;
+       }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/TcaItem.java b/src/main/java/org/onap/clamp/clds/model/prop/TcaItem.java
new file mode 100644 (file)
index 0000000..5792c05
--- /dev/null
@@ -0,0 +1,128 @@
+package org.onap.clamp.clds.model.prop;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Parse Tca Item json properties.
+ * 
+ * Example json: {"TCA_0lm6cix":{"Narra":[{"name":"tname","value":"Narra"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Polcicy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Critical"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_1",">","4"],["FIELDPATH_test_1","=","5"]]}],"Srini":[{"name":"tname","value":"Srini"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Policy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Major"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_2","=","3"],["FIELDPATH_test_1",">","2"]]}]}}
+ * 
+ *
+ */
+public class TcaItem {
+
+    private static final Logger logger = Logger.getLogger(TcaItem.class.getName());
+       
+       private String tcaName;
+       private String tcaUuId;
+       private String nfNamingCode;
+       private String tcaEnable;
+       private String policyId;
+       private Integer interval;
+       private String severity;
+       private Integer violations;
+       private List<TcaThreshhold> tcaThreshholds;
+       
+       /**
+        * Parse Tca Item given json node
+        * 
+        * @param node
+        */
+       public TcaItem(JsonNode node) {
+               
+               tcaName = ModelElement.getValueByName(node, "tname");
+               tcaUuId = ModelElement.getValueByName(node, "tuuid");
+               nfNamingCode = ModelElement.getValueByName(node, "tnfc");
+               tcaEnable = ModelElement.getValueByName(node, "tcaEnab");
+               policyId = ModelElement.getValueByName(node, "tcaPolId");
+               if(ModelElement.getValueByName(node, "tcaInt") != null){
+                       interval = Integer.valueOf(ModelElement.getValueByName(node, "tcaInt"));
+               }
+               severity = ModelElement.getValueByName(node, "tcaSev");
+               if(ModelElement.getValueByName(node, "tcaVio") != null){
+                       violations = Integer.valueOf(ModelElement.getValueByName(node, "tcaVio"));
+               }
+               
+               // process service Configurations
+               JsonNode serviceConfigurationsNode = node.get(node.size() - 1).get("serviceConfigurations");
+               Iterator<JsonNode> itr = serviceConfigurationsNode.elements();
+               tcaThreshholds = new ArrayList<TcaThreshhold>();
+               while(itr.hasNext()) {
+                       tcaThreshholds.add(new TcaThreshhold(itr.next()));
+               }
+       }
+
+       public String getTcaName() {
+               return tcaName;
+       }
+
+       public void setTcaName(String tcaName) {
+               this.tcaName = tcaName;
+       }
+       
+       public String getTcaUuId() {
+               return tcaUuId;
+       }
+
+       public void setTcaUuId(String tcaUuId) {
+               this.tcaUuId = tcaUuId;
+       }
+
+       public String getNfNamingCode() {
+               return nfNamingCode;
+       }
+
+       public void setNfNamingCode(String nfNamingCode) {
+               this.nfNamingCode = nfNamingCode;
+       }
+
+       public String getTcaEnable() {
+               return tcaEnable;
+       }
+
+       public void setTcaEnable(String tcaEnable) {
+               this.tcaEnable = tcaEnable;
+       }
+       
+       public String getPolicyId() {
+               return policyId;
+       }
+
+       public void setPolicyId(String policyId) {
+               this.policyId = policyId;
+       }
+
+       public Integer getInterval() {
+               return interval;
+       }
+
+       public void setInterval(Integer interval) {
+               this.interval = interval;
+       }
+
+       public String getSeverity() {
+               return severity;
+       }
+
+       public void setSeverity(String severity) {
+               this.severity = severity;
+       }
+
+       public Integer getViolations() {
+               return violations;
+       }
+
+       public void setViolations(Integer violations) {
+               this.violations = violations;
+       }
+
+       public List<TcaThreshhold> getTcaThreshholds() {
+               return tcaThreshholds;
+       }
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/prop/TcaThreshhold.java b/src/main/java/org/onap/clamp/clds/model/prop/TcaThreshhold.java
new file mode 100644 (file)
index 0000000..47f2c6f
--- /dev/null
@@ -0,0 +1,76 @@
+package org.onap.clamp.clds.model.prop;
+
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Parse Tca Threshhold json properties.
+ * 
+ * Example json: {"TCA_0lm6cix":{"Narra":[{"name":"tname","value":"Narra"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Polcicy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Critical"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_1",">","4"],["FIELDPATH_test_1","=","5"]]}],"Srini":[{"name":"tname","value":"Srini"},{"name":"tcaEnab","value":"on"},{"name":"tcaPol","value":"Policy1"},{"name":"tcaPolId","value":"1"},{"name":"tcaInt","value":"1"},{"name":"tcaSev","value":"Major"},{"name":"tcaVio","value":"1"},{"serviceConfigurations":[["FIELDPATH_test_2","=","3"],["FIELDPATH_test_1",">","2"]]}]}}
+ * 
+ *
+ */
+public class TcaThreshhold {
+
+       private static final Logger logger = Logger.getLogger(TcaThreshhold.class.getName());
+       
+       private String metric;
+       private String fieldPath;
+       private String operator;
+       private Integer threshhold;
+       
+       /**
+        * Parse Tca Threshhold given json node
+        * 
+        * @param node
+        */
+       public TcaThreshhold(JsonNode node) {
+               
+               if(node.get(0) != null){
+                       metric = node.get(0).asText();
+               }
+               if(node.get(1) != null){
+                       operator = node.get(1).asText();
+               }
+               if(node.get(2) != null){
+                       threshhold = Integer.valueOf(node.get(2).asText());
+               }
+               if(node.get(3) != null){
+                       fieldPath = node.get(3).asText();
+               }
+       }
+
+       public String getMetric() {
+               return metric;
+       }
+
+       public void setMetric(String metric) {
+               this.metric = metric;
+       }
+
+       public String getFieldPath() {
+               return fieldPath;
+       }
+
+       public void setFieldPath(String fieldPath) {
+               this.fieldPath = fieldPath;
+       }
+
+       public String getOperator() {
+               return operator;
+       }
+
+       public void setOperator(String operator) {
+               this.operator = operator;
+       }
+
+       public Integer getThreshhold() {
+               return threshhold;
+       }
+
+       public void setThreshhold(Integer threshhold) {
+               this.threshhold = threshhold;
+       }
+       
+}
diff --git a/src/main/java/org/onap/clamp/clds/model/refprop/RefProp.java b/src/main/java/org/onap/clamp/clds/model/refprop/RefProp.java
new file mode 100644 (file)
index 0000000..c81b6a7
--- /dev/null
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.refprop;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/**
+ * Holds reference properties.
+ */
+public class RefProp {
+    private static final Logger logger = Logger.getLogger(RefProp.class.getName());
+
+    @Autowired
+    private ApplicationContext appContext;
+    
+    private Properties prop;
+
+    @Value("${org.onap.clamp.config.files.cldsReference:'classpath:/clds/clds-reference.properties'}")
+    private String cldsReferenceValuesFile;
+
+    /**
+     * Load reference properties via null constructor
+     *
+     * @throws IOException
+     */
+    public RefProp() throws IOException {
+    }
+    
+    @PostConstruct
+    public void loadConfig () throws IOException {
+        prop = new Properties();
+        Resource resource = appContext.getResource(cldsReferenceValuesFile);
+        prop.load(resource.getInputStream());
+    }
+
+    /**
+     * get property value
+     *
+     * @param key
+     * @return
+     */
+    public String getStringValue(String key) {
+        return prop.getProperty(key);
+    }
+
+    /**
+     * get property value for a combo key (key1 + "." + key2).  If not found just use key1.
+     *
+     * @param key1
+     * @param key2
+     * @return
+     */
+    public String getStringValue(String key1, String key2) {
+        String value = getStringValue(key1 + "." + key2);
+        if (value == null || value.length() == 0) {
+            value = getStringValue(key1);
+        }
+        return value;
+    }
+
+    /**
+     * Return json as objects that can be updated
+     *
+     * @param key
+     * @return
+     * @throws IOException
+     */
+    public JsonNode getJsonTemplate(String key) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(getStringValue(key), JsonNode.class);
+    }
+
+    /**
+     * Return json as objects that can be updated.  First try with combo key (key1 + "." + key2), otherwise default to just key1.
+     *
+     * @param key1
+     * @param key2
+     * @return
+     * @throws IOException
+     */
+    public JsonNode getJsonTemplate(String key1, String key2) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.readValue(getStringValue(key1, key2), JsonNode.class);
+    }
+
+    /**
+     * Get list of values for a property field containing json and a field/keyword within that json.
+     *
+     * @param fieldName
+     * @param value
+     * @return
+     * @throws IOException
+     */
+    public List<String> decodeToList(String fieldName, String value) throws IOException {
+        JsonNode decode = getJsonTemplate(fieldName);
+        Iterator<JsonNode> itr = decode.path(value).elements();
+        ArrayList<String> al = new ArrayList<>();
+        while (itr.hasNext()) {
+            JsonNode node = itr.next();
+            al.add(node.asText());
+        }
+        return al;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/CldsService.java b/src/main/java/org/onap/clamp/clds/service/CldsService.java
new file mode 100644 (file)
index 0000000..a0aadcc
--- /dev/null
@@ -0,0 +1,646 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+import com.att.ajsc.common.AjscService;
+import com.att.ajsc.filemonitor.AJSCPropertiesMap;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onap.clamp.clds.client.SdcCatalogServices;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.onap.clamp.clds.transform.XslTransformer;
+import org.apache.commons.lang3.StringUtils;
+import org.camunda.bpm.engine.RuntimeService;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.jboss.resteasy.spi.BadRequestException;
+import org.onap.clamp.clds.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Service to save and retrieve the CLDS model attributes.
+ */
+@AjscService
+@Path("/clds")
+public class CldsService extends SecureServiceBase {
+
+    @Autowired
+    private ApplicationContext appContext;
+
+    private static final Logger logger = LoggerFactory.getLogger(CldsService.class);
+
+    @Value("${CLDS_PERMISSION_TYPE_CL:org.onap.clamp.clds.cl}")
+    private static String CLDS_PERMISSION_TYPE_CL;
+
+    @Value("${CLDS_PERMISSION_TYPE_CL_MANAGE:org.onap.clamp.clds.cl.manage}")
+    private static String CLDS_PERMISSION_TYPE_CL_MANAGE;
+
+    @Value("${CLDS_PERMISSION_TYPE_CL_EVENT:/META-INF/securityFilterRules.json}")
+    private static String CLDS_PERMISSION_TYPE_CL_EVENT;
+
+    @Value("${CLDS_PERMISSION_TYPE_FILTER_VF:/META-INF/securityFilterRules.json}")
+    private static String CLDS_PERMISSION_TYPE_FILTER_VF;
+
+    @Value("${CLDS_PERMISSION_INSTANCE:/META-INF/securityFilterRules.json}")
+    private static String CLDS_PERMISSION_INSTANCE;
+
+    private static final SecureServicePermission PERMISSION_READ_CL = SecureServicePermission.create(CLDS_PERMISSION_TYPE_CL, CLDS_PERMISSION_INSTANCE, "read");
+
+    private static final SecureServicePermission PERMISSION_UPDATE_CL = SecureServicePermission.create(CLDS_PERMISSION_TYPE_CL, CLDS_PERMISSION_INSTANCE, "update");
+
+    @Value("${org.onap.clamp.config.files.globalClds:classpath:/clds/globalClds.properties}")
+    private String globalClds;
+    private Properties globalCldsProperties;
+
+    @Autowired
+    private CldsDao cldsDao;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    private XslTransformer cldsBpmnTransformer;
+
+    @Autowired
+    private RefProp refProp;
+
+    @Autowired
+    private SdcCatalogServices asdcCatalogServices;
+    //
+
+    public CldsService() {
+    }
+
+    public CldsService(RefProp refProp) {
+        this.refProp = refProp;
+    }
+
+    /**
+     * REST service that retrieves BPMN for a CLDS model name from the database.
+     * This is subset of the json getModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param modelName
+     * @return bpmn xml text - content of bpmn given name
+     */
+    @GET
+    @Path("/model/bpmn/{modelName}")
+    @Produces(MediaType.TEXT_XML)
+    public String getBpmnXml(@PathParam("modelName") String modelName) {
+        isAuthorized(PERMISSION_READ_CL);
+        logger.info("GET bpmnText for modelName={}", modelName);
+        CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
+        return model.getBpmnText();
+    }
+
+    /**
+     * REST service that saves BPMN for a CLDS model by name in the database.
+     * This is subset of the json putModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param modelName
+     */
+    @PUT
+    @Path("/model/bpmn/{modelName}")
+    @Consumes(MediaType.TEXT_XML)
+    public String putBpmnXml(@PathParam("modelName") String modelName, String bpmnText) {
+        isAuthorized(PERMISSION_UPDATE_CL);
+        logger.info("PUT bpmnText for modelName={}", modelName);
+        logger.info("PUT bpmnText={}", bpmnText);
+        CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
+        cldsModel.setBpmnText(bpmnText);
+        cldsModel.save(cldsDao, getUserid());
+        return "wrote bpmnText for modelName=" + modelName;
+    }
+
+    /**
+     * REST service that retrieves image for a CLDS model name from the database.
+     * This is subset of the json getModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param modelName
+     * @return image xml text - content of image given name
+     */
+    @GET
+    @Path("/model/image/{modelName}")
+    @Produces(MediaType.TEXT_XML)
+    public String getImageXml(@PathParam("modelName") String modelName) {
+        isAuthorized(PERMISSION_READ_CL);
+        logger.info("GET imageText for modelName={}", modelName);
+        CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
+        return model.getImageText();
+    }
+
+    /**
+     * REST service that saves image for a CLDS model by name in the database.
+     * This is subset of the json putModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param modelName
+     */
+    @PUT
+    @Path("/model/image/{modelName}")
+    @Consumes(MediaType.TEXT_XML)
+    public String putImageXml(@PathParam("modelName") String modelName, String imageText) {
+        isAuthorized(PERMISSION_UPDATE_CL);
+        logger.info("PUT iamgeText for modelName={}", modelName);
+        logger.info("PUT imageText={}", imageText);
+        CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
+        cldsModel.setImageText(imageText);
+        cldsModel.save(cldsDao, getUserid());
+        return "wrote imageText for modelName=" + modelName;
+    }
+
+    /**
+     * REST service that retrieves a CLDS model by name from the database.
+     *
+     * @param modelName
+     * @return clds model - clds model for the given model name
+     * @throws NotAuthorizedException
+     */
+    @GET
+    @Path("/model/{modelName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public CldsModel getModel(@PathParam("modelName") String modelName) throws NotAuthorizedException {
+        isAuthorized(PERMISSION_READ_CL);
+        logger.debug("GET model for  modelName={}", modelName);
+        CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, false);
+        isAuthorizedForVf(cldsModel);
+        return cldsModel;
+    }
+
+    /**
+     * REST service that saves a CLDS model by name in the database.
+     *
+     * @param modelName
+     * @throws TransformerException
+     * @throws TransformerConfigurationException
+     */
+    @PUT
+    @Path("/model/{modelName}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public CldsModel putModel(@PathParam("modelName") String modelName, CldsModel cldsModel) throws TransformerException {
+        isAuthorized(PERMISSION_UPDATE_CL);
+        isAuthorizedForVf(cldsModel);
+        logger.info("PUT model for  modelName={}", modelName);
+        logger.info("PUT bpmnText={}", cldsModel.getBpmnText());
+        logger.info("PUT propText={}", cldsModel.getPropText());
+        logger.info("PUT imageText={}", cldsModel.getImageText());
+        cldsModel.setName(modelName);
+
+        if (cldsModel.getTemplateName() != null) {
+            CldsTemplate template = cldsDao.getTemplate(cldsModel.getTemplateName());
+            if (template != null) {
+                cldsModel.setTemplateId(template.getId());
+                cldsModel.setDocText(template.getPropText());
+                cldsModel.setDocId(template.getPropId());
+            }
+        }
+        cldsModel.save(cldsDao, getUserid());
+        return cldsModel;
+    }
+
+    /**
+     * REST service that retrieves a list of CLDS model names.
+     *
+     * @return model names in JSON
+     */
+    @GET
+    @Path("/model-names")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<ValueItem> getModelNames() {
+//             isAuthorized(PERMISSION_READ_CL);
+        logger.info("GET list of model names");
+        return cldsDao.getBpmnNames();
+    }
+
+    /**
+     * REST service that saves and processes an action for a CLDS model by name.
+     *
+     * @param action
+     * @param modelName
+     * @param test
+     * @param model
+     * @return
+     * @throws TransformerConfigurationException
+     * @throws TransformerException
+     * @throws IOException
+     * @throws JsonProcessingException
+     * @throws NotAuthorizedException
+     */
+    @PUT
+    @Path("/action/{action}/{modelName}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public CldsModel putModelAndProcessAction(@PathParam("action") String action, @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model) throws TransformerException, NotAuthorizedException, IOException {
+        String actionCd = action.toUpperCase();
+        SecureServicePermission permisionManage = SecureServicePermission.create(CLDS_PERMISSION_TYPE_CL_MANAGE, CLDS_PERMISSION_INSTANCE, actionCd);
+        isAuthorized(permisionManage);
+        isAuthorizedForVf(model);
+        String userid = getUserid();
+        String actionStateCd = CldsEvent.ACTION_STATE_INITIATED;
+        String processDefinitionKey = "clds-process-action-wf";
+
+        logger.info("PUT actionCd={}", actionCd);
+        logger.info("PUT actionStateCd={}", actionStateCd);
+        logger.info("PUT processDefinitionKey={}", processDefinitionKey);
+        logger.info("PUT modelName={}", modelName);
+        logger.info("PUT test={}", test);
+        logger.info("PUT bpmnText={}", model.getBpmnText());
+        logger.info("PUT propText={}", model.getPropText());
+        logger.info("PUT userid={}", userid);
+
+        if (model.getTemplateName() != null) {
+            CldsTemplate template = cldsDao.getTemplate(model.getTemplateName());
+            if (template != null) {
+                model.setTemplateId(template.getId());
+                model.setDocText(template.getPropText());
+                model.setDocId(template.getPropId());
+            }
+        }
+        // save model to db
+        model.setName(modelName);
+        model.save(cldsDao, getUserid());
+
+        // get vars and format if necessary
+        String prop = model.getPropText();
+        String bpmn = model.getBpmnText();
+        String docText = model.getDocText();
+        String controlName = model.getControlName();
+
+        String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn);
+        logger.info("PUT bpmnJson={}", bpmnJson);
+
+        boolean isTest = false;
+        if (test != null && test.equalsIgnoreCase("true")) {
+            isTest = true;
+        } else {
+            // if action.test.override is true, then any action will be marked as test=true (even if incoming action request had test=false); otherwise, test flag will be unchanged on the action request
+            String actionTestOverride = refProp.getStringValue("action.test.override");
+            if (actionTestOverride != null && actionTestOverride.equalsIgnoreCase("true")) {
+                logger.info("PUT actionTestOverride={}", actionTestOverride);
+                logger.info("PUT override test indicator and setting it to true");
+                isTest = true;
+            }
+        }
+        logger.info("PUT isTest={}", isTest);
+
+
+        boolean isInsertTestEvent = false;
+        String insertTestEvent = refProp.getStringValue("action.insert.test.event");
+        if (insertTestEvent != null && insertTestEvent.equalsIgnoreCase("true")) {
+            isInsertTestEvent = true;
+        }
+        logger.info("PUT isInsertTestEvent={}", isInsertTestEvent);
+
+
+        // determine if requested action is permitted
+        model.validateAction(actionCd);
+
+        // input variables to camunda process
+        Map<String, Object> variables = new HashMap<>();
+        variables.put("actionCd", actionCd);
+        variables.put("modelProp", prop);
+        variables.put("modelBpmnProp", bpmnJson);
+        variables.put("modelName", modelName);
+        variables.put("controlName", controlName);
+        variables.put("docText", docText);
+        variables.put("isTest", isTest);
+        variables.put("userid", userid);
+        variables.put("isInsertTestEvent", isInsertTestEvent);
+
+        // start camunda process
+        ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
+
+        // log process info
+        logger.info("Started processDefinitionId={}, processInstanceId={}", pi.getProcessDefinitionId(), pi.getProcessInstanceId());
+
+        // refresh model info from db (get fresh event info)
+        return CldsModel.retrieve(cldsDao, modelName, false);
+    }
+
+    /**
+     * REST service that accepts events for a model.
+     *
+     * @param test
+     * @param dcaeEvent
+     * @throws BadRequestException
+     */
+    @POST
+    @Path("/dcae/event")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public String postDcaeEvent(@QueryParam("test") String test, DcaeEvent dcaeEvent) throws BadRequestException {
+        String userid = null;
+        // TODO: allow auth checking to be turned off by removing the permission type property
+        if (CLDS_PERMISSION_TYPE_CL_EVENT != null && CLDS_PERMISSION_TYPE_CL_EVENT.length() > 0) {
+            SecureServicePermission permissionEvent = SecureServicePermission.create(CLDS_PERMISSION_TYPE_CL_EVENT, CLDS_PERMISSION_INSTANCE, dcaeEvent.getEvent());
+            isAuthorized(permissionEvent);
+            userid = getUserid();
+        }
+
+        boolean isTest = false;
+        if (test != null && test.equalsIgnoreCase("true")) {
+            isTest = true;
+        }
+
+        int instanceCount = 0;
+        if (dcaeEvent.getInstances() != null) {
+            instanceCount = dcaeEvent.getInstances().size();
+        }
+        String msgInfo = "event=" + dcaeEvent.getEvent() + " serviceUUID=" + dcaeEvent.getServiceUUID() + " resourceUUID=" + dcaeEvent.getResourceUUID() + " artifactName=" + dcaeEvent.getArtifactName() + " instance count=" + instanceCount + " isTest=" + isTest;
+        logger.info("POST dcae event {}", msgInfo);
+
+        if (isTest) {
+            logger.warn("Ignorning test event from DCAE");
+        } else {
+            if (DcaeEvent.EVENT_DEPLOYMENT.equalsIgnoreCase(dcaeEvent.getEvent())) {
+                CldsModel.insertModelInstance(cldsDao, dcaeEvent, userid);
+            } else {
+                CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(), CldsEvent.ACTION_STATE_RECEIVED, null);
+            }
+            // EVENT_UNDEPLOYMENT is defunct - DCAE Proxy will not undeploy individual instances.  It will send an empty list of
+            // deployed instances to indicate all have been removed.  Or it will send an updated list to indicate those that
+            // are still deployed with any not on the list considered undeployed.
+            //else if(DcaeEvent.EVENT_UNDEPLOYMENT.equalsIgnoreCase(dcaeEvent.getEvent()))
+            //{
+            // CldsModel.removeModelInstance(cldsDao, dcaeEvent);
+            //}
+        }
+
+        return msgInfo;
+    }
+
+    /**
+     * REST service that retrieves asdc services
+     *
+     * @throws Exception
+     */
+    @GET
+    @Path("/asdc/services")
+    @Produces(MediaType.APPLICATION_JSON)
+    public String getAsdcServices() throws Exception {
+        String retStr;
+        try {
+            String responseStr = asdcCatalogServices.getAsdcServicesInformation(null);
+            retStr = createUiServiceFormatJson(responseStr);
+        } catch (Exception e) {
+            logger.info("{} {}", e.getClass().getName(), e.getMessage());
+            throw e;
+        }
+        logger.info("value of asdcServices : {}", retStr);
+        return retStr;
+    }
+
+    /**
+     * REST service that retrieves total properties required by UI
+     *
+     * @throws Exception
+     */
+    @GET
+    @Path("/properties")
+    @Produces(MediaType.APPLICATION_JSON)
+    public String getAsdcProperties() throws Exception {
+        return createPropertiesObjectByUUID(getGlobalCldsString(), "{}");
+    }
+
+    /**
+     * REST service that retrieves total properties by using invariantUUID based on refresh and non refresh
+     *
+     * @throws Exception
+     */
+    @GET
+    @Path("/properties/{serviceInvariantUUID}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public String getAsdcPropertiesByServiceUUIDForRefresh(@PathParam("serviceInvariantUUID") String serviceInvariantUUID, @DefaultValue("false") @QueryParam("refresh") String refresh) throws Exception {
+        CldsServiceData cldsServiceData = new CldsServiceData();
+        cldsServiceData.setServiceInvariantUUID(serviceInvariantUUID);
+
+        boolean isCldsAsdcDataExpired = true;
+        //  To getcldsService information from database cache using invariantUUID only when refresh = false
+        if (refresh != null && refresh.equalsIgnoreCase("false")) {
+            cldsServiceData = cldsServiceData.getCldsServiceCache(cldsDao, serviceInvariantUUID);
+            // If cldsService is available in database Cache , verify is data expired or not
+            if (cldsServiceData != null) {
+                isCldsAsdcDataExpired = asdcCatalogServices.isCldsAsdcCacheDataExpired(cldsServiceData);
+            }
+        }
+        // If user Requested for refresh or database cache expired , get all data from asdc api.
+        if ((refresh != null && refresh.equalsIgnoreCase("true")) || isCldsAsdcDataExpired) {
+            cldsServiceData = asdcCatalogServices.getCldsServiceDataWithAlarmConditions(serviceInvariantUUID);
+            CldsDBServiceCache cldsDBServiceCache = asdcCatalogServices.getCldsDBServiceCacheUsingCldsServiceData(cldsServiceData);
+            if (cldsDBServiceCache != null && cldsDBServiceCache.getInvariantId() != null && cldsDBServiceCache.getServiceId() != null) {
+                cldsServiceData.setCldsServiceCache(cldsDao, cldsDBServiceCache);
+            }
+        }
+
+        // filter out VFs the user is not authorized for
+        cldsServiceData.filterVfs(this);
+
+        // format retrieved data into properties json
+        return asdcCatalogServices.createPropertiesObjectByUUID(getGlobalCldsString(), cldsServiceData);
+    }
+
+    /**
+     * Determine if the user is authorized for a particular VF by its invariant UUID.
+     *
+     * @param vfInvariantUuid
+     * @throws NotAuthorizedException
+     * @return
+     */
+    public boolean isAuthorizedForVf(String vfInvariantUuid) throws NotAuthorizedException {
+        if (CLDS_PERMISSION_TYPE_FILTER_VF != null && CLDS_PERMISSION_TYPE_FILTER_VF.length() > 0) {
+            SecureServicePermission permission = SecureServicePermission.create(CLDS_PERMISSION_TYPE_FILTER_VF, CLDS_PERMISSION_INSTANCE, vfInvariantUuid);
+            return isAuthorized(permission);
+        } else {
+            // if CLDS_PERMISSION_TYPE_FILTER_VF property is not provided, then VF filtering is turned off
+            logger.warn("VF filtering turned off");
+            return true;
+        }
+    }
+
+    /**
+     * Determine if the user is authorized for a particular VF by its invariant UUID.
+     * If not authorized, then NotAuthorizedException is thrown.
+     *
+     * @param model
+     * @return
+     */
+    private boolean isAuthorizedForVf(CldsModel model) throws NotAuthorizedException {
+        String vf = ModelProperties.getVf(model);
+        if (vf == null || vf.length() == 0) {
+            logger.info("VF not found in model");
+            return true;
+        } else {
+            return isAuthorizedForVf(vf);
+        }
+    }
+
+    private String createUiServiceFormatJson(String responseStr) throws IOException {
+        if (StringUtils.isBlank(responseStr)) {
+            return "";
+        }
+        ObjectMapper objectMapper = new ObjectMapper();
+        List<CldsAsdcServiceInfo> rawList = objectMapper.readValue(responseStr, objectMapper.getTypeFactory().constructCollectionType(List.class, CldsAsdcServiceInfo.class));
+        ObjectNode invariantIdServiceNode = objectMapper.createObjectNode();
+        ObjectNode serviceNode = objectMapper.createObjectNode();
+        logger.info("value of cldsserviceiNfolist: {}", rawList);
+        if (rawList != null && rawList.size() > 0) {
+            List<CldsAsdcServiceInfo> cldsAsdcServiceInfoList = asdcCatalogServices.removeDuplicateServices(rawList);
+
+            for (CldsAsdcServiceInfo currCldsAsdcServiceInfo : cldsAsdcServiceInfoList) {
+                if (currCldsAsdcServiceInfo != null) {
+                    invariantIdServiceNode.put(currCldsAsdcServiceInfo.getInvariantUUID(), currCldsAsdcServiceInfo.getName());
+                }
+            }
+            serviceNode.putPOJO("service", invariantIdServiceNode);
+        }
+        return serviceNode.toString();
+    }
+
+    private String createPropertiesObjectByUUID(String globalProps, String cldsResponseStr) throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        CldsAsdcServiceDetail cldsAsdcServiceDetail = mapper.readValue(cldsResponseStr, CldsAsdcServiceDetail.class);
+        ObjectNode globalPropsJson = null;
+        if (cldsAsdcServiceDetail != null && cldsAsdcServiceDetail.getUuid() != null) {
+            /**
+             * to create json with vf, alarm and locations
+             */
+            ObjectNode serviceObjectNode = createEmptyVfAlarmObject(mapper);
+            ObjectNode vfObjectNode = mapper.createObjectNode();
+
+            /**
+             * to create json with vf and vfresourceId
+             */
+            createVfObjectNode(vfObjectNode, mapper, cldsAsdcServiceDetail.getResources());
+            serviceObjectNode.putPOJO(cldsAsdcServiceDetail.getInvariantUUID(), vfObjectNode);
+            ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
+            byServiceBasicObjetNode.putPOJO("byService", serviceObjectNode);
+
+            /**
+             * to create json with VFC Node
+             */
+            ObjectNode emptyvfcobjectNode = createByVFCObjectNode(mapper, cldsAsdcServiceDetail.getResources());
+            byServiceBasicObjetNode.putPOJO("byVf", emptyvfcobjectNode);
+            globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
+            globalPropsJson.putPOJO("shared", byServiceBasicObjetNode);
+            logger.info("valuie of objNode: {}", globalPropsJson);
+        } else {
+            /**
+             *  to create json with total properties when no serviceUUID passed
+             */
+            globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
+        }
+        return globalPropsJson.toString();
+    }
+
+    private ObjectNode createEmptyVfAlarmObject(ObjectMapper mapper) {
+        ObjectNode emptyObjectNode = mapper.createObjectNode();
+        emptyObjectNode.put("", "");
+        ObjectNode vfObjectNode = mapper.createObjectNode();
+        vfObjectNode.putPOJO("vf", emptyObjectNode);
+        vfObjectNode.putPOJO("location", emptyObjectNode);
+        vfObjectNode.putPOJO("alarmCondition", emptyObjectNode);
+        ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
+        emptyServiceObjectNode.putPOJO("", vfObjectNode);
+        return emptyServiceObjectNode;
+    }
+
+    private void createVfObjectNode(ObjectNode vfObjectNode2, ObjectMapper mapper, List<CldsAsdcResource> rawCldsAsdcResourceList) throws IOException {
+        ObjectNode vfNode = mapper.createObjectNode();
+        vfNode.put("", "");
+
+        // To remove repeated resource instance name from resourceInstanceList
+        List<CldsAsdcResource> cldsAsdcResourceList = asdcCatalogServices.removeDuplicateAsdcResourceInstances(rawCldsAsdcResourceList);
+        /**
+         * Creating vf resource node using cldsAsdcResource Object
+         */
+        if (cldsAsdcResourceList != null && cldsAsdcResourceList.size() > 0) {
+            for (CldsAsdcResource cldsAsdcResource : cldsAsdcResourceList) {
+                if (cldsAsdcResource != null && cldsAsdcResource.getResoucreType() != null && cldsAsdcResource.getResoucreType().equalsIgnoreCase("VF")) {
+                    vfNode.put(cldsAsdcResource.getResourceUUID(), cldsAsdcResource.getResourceName());
+                }
+            }
+        }
+        vfObjectNode2.putPOJO("vf", vfNode);
+        String locationStringValue = refProp.getStringValue("ui.location.default");
+        String alarmStringValue = refProp.getStringValue("ui.alarm.default");
+
+        /**
+         *  creating location json object using properties file value
+         */
+        ObjectNode locationJsonNode = (ObjectNode) mapper.readValue(locationStringValue, JsonNode.class);
+        vfObjectNode2.putPOJO("location", locationJsonNode);
+
+        /**
+         * creating alarm json object using properties file value
+         */
+        logger.info("value of alarm: {}", alarmStringValue);
+        ObjectNode alarmStringJsonNode = (ObjectNode) mapper.readValue(alarmStringValue, JsonNode.class);
+        vfObjectNode2.putPOJO("alarmCondition", alarmStringJsonNode);
+    }
+
+    private ObjectNode createByVFCObjectNode(ObjectMapper mapper, List<CldsAsdcResource> cldsAsdcResourceList) {
+        ObjectNode emptyObjectNode = mapper.createObjectNode();
+        ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
+        ObjectNode vfCObjectNode = mapper.createObjectNode();
+        vfCObjectNode.putPOJO("vfC", emptyObjectNode);
+        ObjectNode subVfCObjectNode = mapper.createObjectNode();
+        subVfCObjectNode.putPOJO("vfc", emptyObjectNode);
+        if (cldsAsdcResourceList != null && cldsAsdcResourceList.size() > 0) {
+            for (CldsAsdcResource cldsAsdcResource : cldsAsdcResourceList) {
+                if (cldsAsdcResource != null && cldsAsdcResource.getResoucreType() != null && cldsAsdcResource.getResoucreType().equalsIgnoreCase("VF")) {
+                    vfCObjectNode.putPOJO(cldsAsdcResource.getResourceUUID(), subVfCObjectNode);
+                }
+            }
+        }
+        emptyvfcobjectNode.putPOJO("", vfCObjectNode);
+        return emptyvfcobjectNode;
+    }
+    
+    private String getGlobalCldsString() throws Exception {
+       if  (null == globalCldsProperties) {
+            globalCldsProperties = new Properties();
+            globalCldsProperties.load(appContext.getResource(globalClds).getInputStream());
+       }
+       return (String) globalCldsProperties.get("globalCldsProps");
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/CldsTemplateService.java b/src/main/java/org/onap/clamp/clds/service/CldsTemplateService.java
new file mode 100644 (file)
index 0000000..0ffa955
--- /dev/null
@@ -0,0 +1,275 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+import com.att.ajsc.common.AjscService;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.model.CldsTemplate;
+import org.onap.clamp.clds.model.ValueItem;
+import org.onap.clamp.clds.model.prop.ModelBpmn;
+import org.onap.clamp.clds.transform.XslTransformer;
+import org.camunda.bpm.engine.RuntimeService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.xml.transform.TransformerException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Service to save and retrieve the CLDS model attributes.
+ */
+@AjscService
+@Path("/cldsTempate")
+public class CldsTemplateService extends SecureServiceBase {
+
+    private static final Logger logger = LoggerFactory.getLogger(CldsTemplateService.class);
+
+    private static final String collectorKey = "Collector";
+    private static final String stringMatchKey = "StringMatch";
+    private static final String policyKey = "Policy";
+
+    private static final String CLDS_PERMISSION_TYPE_TEMPLATE = System.getProperty("CLDS_PERMISSION_TYPE_TEMPLATE");
+    private static final String CLDS_PERMISSION_INSTANCE = System.getProperty("CLDS_PERMISSION_INSTANCE");
+
+    private static final SecureServicePermission PERMISSION_READ_TEMPLATE = SecureServicePermission.create(CLDS_PERMISSION_TYPE_TEMPLATE, CLDS_PERMISSION_INSTANCE, "read");
+    private static final SecureServicePermission PERMISSION_UPDATE_TEMPLATE = SecureServicePermission.create(CLDS_PERMISSION_TYPE_TEMPLATE, CLDS_PERMISSION_INSTANCE, "update");
+
+    @Autowired
+    private CldsDao cldsDao;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    private XslTransformer cldsBpmnTransformer;
+
+    private static String userid;
+
+    /**
+     * REST service that retrieves BPMN for a CLDS template name from the database.
+     * This is subset of the json getModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param templateName
+     * @return bpmn xml text - content of bpmn given name
+     */
+    @GET
+    @Path("/template/bpmn/{templateName}")
+    @Produces(MediaType.TEXT_XML)
+    public String getBpmnTemplate(@PathParam("templateName") String templateName) {
+        isAuthorized(PERMISSION_READ_TEMPLATE);
+        logger.info("GET bpmnText for templateName=" + templateName);
+        CldsTemplate template = CldsTemplate.retrieve(cldsDao, templateName, false);
+        return template.getBpmnText();
+    }
+
+    /**
+     * REST service that saves BPMN for a CLDS template by name in the database.
+     * This is subset of the json putModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param templateName
+     * @param bpmnText
+     */
+    @PUT
+    @Path("/template/bpmn/{templateName}")
+    @Consumes(MediaType.TEXT_XML)
+    public String putBpmnTemplateXml(@PathParam("templateName") String templateName, String bpmnText) {
+        isAuthorized(PERMISSION_UPDATE_TEMPLATE);
+        logger.info("PUT bpmnText for templateName=" + templateName);
+        logger.info("PUT bpmnText=" + bpmnText);
+        CldsTemplate cldsTemplate = CldsTemplate.retrieve(cldsDao, templateName, true);
+        cldsTemplate.setBpmnText(bpmnText);
+        cldsTemplate.save(cldsDao, userid);
+        return "wrote bpmnText for templateName=" + templateName;
+    }
+
+    /**
+     * REST service that retrieves image for a CLDS template name from the database.
+     * This is subset of the json getModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param templateName
+     * @return image xml text - content of image given name
+     */
+    @GET
+    @Path("/template/image/{templateName}")
+    @Produces(MediaType.TEXT_XML)
+    public String getImageXml(@PathParam("templateName") String templateName) {
+        isAuthorized(PERMISSION_READ_TEMPLATE);
+        logger.info("GET imageText for templateName=" + templateName);
+        CldsTemplate template = CldsTemplate.retrieve(cldsDao, templateName, false);
+        return template.getImageText();
+    }
+
+    /**
+     * REST service that saves image for a CLDS template by name in the database.
+     * This is subset of the json putModel.
+     * This is only expected to be used for testing purposes, not by the UI.
+     *
+     * @param templateName
+     * @param imageText
+     */
+    @PUT
+    @Path("/template/image/{templateName}")
+    @Consumes(MediaType.TEXT_XML)
+    public String putImageXml(@PathParam("templateName") String templateName, String imageText) {
+        isAuthorized(PERMISSION_UPDATE_TEMPLATE);
+        logger.info("PUT iamgeText for modelName=" + templateName);
+        logger.info("PUT imageText=" + imageText);
+        CldsTemplate cldsTemplate = CldsTemplate.retrieve(cldsDao, templateName, true);
+        cldsTemplate.setImageText(imageText);
+        cldsTemplate.save(cldsDao, userid);
+        return "wrote imageText for modelName=" + templateName;
+    }
+
+    /**
+     * REST service that retrieves a CLDS template by name from the database.
+     *
+     * @param templateName
+     * @return clds template - clds template for the given template name
+     */
+    @GET
+    @Path("/template/{templateName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public CldsTemplate getTemplate(@PathParam("templateName") String templateName) {
+        isAuthorized(PERMISSION_READ_TEMPLATE);
+        logger.info("GET model for  templateName=" + templateName);
+        return CldsTemplate.retrieve(cldsDao, templateName, false);
+    }
+
+    /**
+     * REST service that saves a CLDS template by name in the database.
+     *
+     * @param templateName
+     * @throws IOException
+     * @throws JsonMappingException
+     * @throws JsonParseException
+     */
+    @PUT
+    @Path("/template/{templateName}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public CldsTemplate putTemplate(@PathParam("templateName") String templateName, CldsTemplate cldsTemplate) throws TransformerException, IOException {
+        isAuthorized(PERMISSION_UPDATE_TEMPLATE);
+        logger.info("PUT Template for  templateName=" + templateName);
+        logger.info("PUT bpmnText=" + cldsTemplate.getBpmnText());
+        logger.info("PUT propText=" + cldsTemplate.getPropText());
+        logger.info("PUT imageText=" + cldsTemplate.getImageText());
+        cldsTemplate.setName(templateName);
+        String bpmnText = cldsTemplate.getBpmnText();
+        String imageText = cldsTemplate.getImageText();
+        String propText = cldsTemplate.getPropText();
+        Map<String, String> newBpmnIdsMap = getNewBpmnIdsMap(bpmnText, cldsTemplate.getPropText());
+        for (String currBpmnId : newBpmnIdsMap.keySet()) {
+            if (currBpmnId != null && newBpmnIdsMap.get(currBpmnId) != null) {
+                bpmnText = bpmnText.replace(currBpmnId, newBpmnIdsMap.get(currBpmnId));
+                imageText = imageText.replace(currBpmnId, newBpmnIdsMap.get(currBpmnId));
+                propText = propText.replace(currBpmnId, newBpmnIdsMap.get(currBpmnId));
+            }
+        }
+        cldsTemplate.setBpmnText(bpmnText);
+        cldsTemplate.setImageText(imageText);
+        cldsTemplate.setPropText(propText);
+        logger.info(" bpmnText : " + cldsTemplate.getBpmnText());
+        logger.info(" Image Text : " + cldsTemplate.getImageText());
+        logger.info(" Prop Text : " + cldsTemplate.getPropText());
+        cldsTemplate.save(cldsDao, userid);
+        return cldsTemplate;
+    }
+
+    /**
+     * REST service that retrieves a list of CLDS template names.
+     *
+     * @return template names in JSON
+     */
+    @GET
+    @Path("/template-names")
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<ValueItem> getTemplateNames() {
+        isAuthorized(PERMISSION_READ_TEMPLATE);
+        logger.info("GET list of template names");
+        return cldsDao.getTemplateNames();
+    }
+
+
+    private Map<String, String> getNewBpmnIdsMap(String bpmnText, String propText) throws TransformerException, IOException {
+        /**
+         *  Test sample code start
+         */
+        String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmnText);
+        ModelBpmn templateBpmn = ModelBpmn.create(bpmnJson);
+        List<String> bpmnElementIds = templateBpmn.getBpmnElementIds();
+        logger.info("value of elementIds:" + bpmnElementIds);
+        logger.info("value of prop text:" + propText);
+        Map<String, String> bpmnIoIdsMap = new HashMap<>();
+        if (bpmnElementIds != null && bpmnElementIds.size() > 0) {
+            ObjectMapper objectMapper = new ObjectMapper();
+            ObjectNode root = objectMapper.readValue(propText, ObjectNode.class);
+            Iterator<Entry<String, JsonNode>> entryItr = root.fields();
+            while (entryItr.hasNext()) {
+                // process the entry
+                Entry<String, JsonNode> entry = entryItr.next();
+                String keyPropName = entry.getKey();
+                for (String currElementId : bpmnElementIds) {
+                    if (keyPropName != null && keyPropName.equalsIgnoreCase(currElementId)) {
+                        ArrayNode arrayNode = (ArrayNode) entry.getValue();
+                        // process each id/from object, like: {"id":"Collector_11r50j1", "from":"StartEvent_1"}
+                        for (JsonNode anArrayNode : arrayNode) {
+                            ObjectNode node = (ObjectNode) anArrayNode;
+                            String valueNode = node.get("value").asText();
+                            logger.info("value of node:" + valueNode);
+                            if (keyPropName.startsWith(collectorKey)) {
+                                valueNode = collectorKey + "_" + valueNode;
+                            } else if (keyPropName.startsWith(stringMatchKey)) {
+                                valueNode = stringMatchKey + "_" + valueNode;
+                            } else if (keyPropName.startsWith(policyKey)) {
+                                valueNode = policyKey + "_" + valueNode;
+                            }
+                            bpmnIoIdsMap.put(keyPropName, valueNode);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+        logger.info("value of hashmap:" + bpmnIoIdsMap);
+        /**
+         *  Test sample code end
+         */
+        return bpmnIoIdsMap;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/LogService.java b/src/main/java/org/onap/clamp/clds/service/LogService.java
new file mode 100644 (file)
index 0000000..1c3d9dc
--- /dev/null
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+public interface LogService {
+
+    String logMessage(String logMessageText, String javamail, String springmail, String commonsmail);
+
+    String postLogMessage(String histEventList);
+
+    String createLogMessage(String startTime, String endTime, String serviceName);
+
+    String createLogMessageUsingHistory(String procInstId, String histEventList);
+
+    String CreateHistLog(String procInstId);
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/LogServiceImpl.java b/src/main/java/org/onap/clamp/clds/service/LogServiceImpl.java
new file mode 100644 (file)
index 0000000..e7ee93a
--- /dev/null
@@ -0,0 +1,276 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+import com.att.ajsc.camunda.core.AttCamundaHistoryEvent;
+import com.att.ajsc.camunda.core.AttCamundaService;
+import com.att.ajsc.logging.AjscEelfManager;
+import com.att.eelf.configuration.EELFLogger;
+import com.google.gson.Gson;
+import org.onap.clamp.clds.common.LogMessages;
+import org.apache.commons.mail.Email;
+import org.apache.commons.mail.SimpleEmail;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.RuntimeService;
+import org.camunda.bpm.engine.history.HistoricActivityInstance;
+import org.camunda.bpm.engine.impl.history.event.HistoricActivityInstanceEventEntity;
+import org.camunda.bpm.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.MailException;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.stereotype.Service;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.ws.rs.core.Context;
+import java.util.*;
+
+@Service
+public class LogServiceImpl implements LogService {
+    private static final EELFLogger logger = AjscEelfManager.getInstance().getLogger(LogServiceImpl.class);
+
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private HistoryService historyService;
+
+    @Context
+    private MessageContext context;
+
+    public void setRuntimeService(RuntimeService runtimeService) {
+        this.runtimeService = runtimeService;
+    }
+
+    public LogServiceImpl() {
+        // needed for instantiation
+    }
+
+    @Override
+    public String logMessage(String logMessageText, String javamail, String springmail, String commonsmail) {
+        logger.info("Value of contexxt : " + context);
+        String convId = null;
+        if (context != null) {
+            convId = context.getHttpServletRequest().getHeader("X-CSI-ConversationId");
+            if (convId == null) {
+                convId = (String) context.getHttpServletRequest().getAttribute("X-CSI-ConversationId");
+            }
+            context.getHttpServletRequest().setAttribute("CALL_TYPE", "Testing");
+            AttCamundaService.setHttpRequest(context.getHttpServletRequest());
+        }
+        // input variables to example camunda process
+        Map<String, Object> variables = new HashMap<>();
+        variables.put("logMessageText", logMessageText);
+        if (convId != null) {
+            variables.put("conversationId", convId);
+        }
+
+        // BEGIN - added for send mail testing
+        // also added the following to the method signature: , @QueryParam("javamail") String javamail, @QueryParam("springmail") String springmail, @QueryParam("commonsmail") String commonsmail
+        // if javamail parameter provided, assume it contains an email address.
+        // use Java Mail to send an email from that address, to that address
+        if (javamail != null && javamail.length() > 0) {
+            variables.put("javamail", javamail);
+            try {
+                Properties props = new Properties();
+                props.put("mail.smtp.host", "smtp.sbc.com"); // eMail.setHostName
+                Session session = Session.getInstance(props);
+                MimeMessage msg = new MimeMessage(session);
+
+                msg.setFrom(new InternetAddress(javamail)); //eMail.setFrom
+
+                InternetAddress[] fromAddresses = {new InternetAddress(javamail)};
+                msg.setReplyTo(fromAddresses); //eMail.addReplyTo
+                msg.setSubject("test message using javax.mail"); //eMail.setSubject
+                msg.setText(logMessageText); // eMail.setMsg
+
+                msg.addRecipient(Message.RecipientType.TO, new InternetAddress(javamail)); // eMail.addTo
+                Transport.send(msg);
+            } catch (MessagingException e) {
+                logger.error(LogMessages.LOGSERVICE_EMAIL_ERROR, e);
+            }
+        }
+
+        // if springmail parameter provided, assume it contains an email address.
+        // use Spring Mail to send an email from that address, to that address
+        if (springmail != null && springmail.length() > 0) {
+            variables.put("springmail", springmail);
+            JavaMailSenderImpl sender = new JavaMailSenderImpl();
+            SimpleMailMessage smsg = new SimpleMailMessage();
+
+            try {
+                sender.setHost("smtp.sbc.com"); // eMail.setHostName
+                smsg.setFrom(springmail); //eMail.setFrom
+                smsg.setReplyTo(springmail); //eMail.addReplyTo
+                smsg.setSubject("test message using spring mail"); //eMail.setSubject
+                smsg.setText(logMessageText); // eMail.setMsg
+                smsg.setTo(springmail); // eMail.addTo
+                sender.send(smsg);
+            } catch (MailException e) {
+                logger.error(LogMessages.LOGSERVICE_EMAIL_ERROR, e);
+            }
+        }
+
+        // if commonsmail parameter provided, assume it contains an email address.
+        // use Apache Commons Mail to send an email from that address, to that address
+        if (commonsmail != null && commonsmail.length() > 0) {
+            variables.put("commonsmail", commonsmail);
+            Email eMail = new SimpleEmail();
+            try {
+                eMail.setHostName("smtp.sbc.com");
+                eMail.setFrom(commonsmail);
+                eMail.addReplyTo(commonsmail);
+                eMail.setSubject("test message using commons mail");
+                eMail.setMsg(logMessageText);
+                eMail.addTo(commonsmail);
+                java.net.URL classUrl = this.getClass().getResource("com.sun.mail.util.TraceInputStream");
+                if (classUrl != null) {
+                    logger.info(LogMessages.LOGSERVICE_EMAIL_CLASS, classUrl.getFile());
+                } else {
+                    logger.info(LogMessages.LOGSERVICE_EMAIL_CLASS, classUrl.getFile());
+                    logger.info(LogMessages.LOGSERVICE_EMAIL_CLASS_NULL);
+                }
+                eMail.send();
+            } catch (Exception e) {
+                logger.error(LogMessages.LOGSERVICE_EMAIL_ERROR, e);
+            }
+        }
+        // END - added for send mail testing
+
+        // execute example camunda process, log-message-wf
+        ProcessInstance pi = runtimeService.startProcessInstanceByKey("log-message-wf", variables);
+        AttCamundaService.setHttpRequest(null);
+        // return text message of what was done
+        return "Started processDefinitionId=" + pi.getProcessDefinitionId() + ", processInstanceId=" + pi.getProcessInstanceId() + ", to log message: " + logMessageText;
+    }
+
+    @Override
+    public String postLogMessage(String histEventList) {
+        String message = "no logs Created";
+        logger.info("value of history events:" + histEventList);
+        Gson gson = new Gson();
+        AttCamundaHistoryEvent attCamundaHistoryEvent = gson.fromJson(histEventList, AttCamundaHistoryEvent.class);
+        if (attCamundaHistoryEvent != null && attCamundaHistoryEvent.getProcInstId() != null) {
+            logger.info(LogMessages.PROCESS_INSTANCE_ID, attCamundaHistoryEvent.getProcInstId());
+            if (context != null && context.getHttpServletRequest() != null && context.getHttpServletRequest().getAttribute("PERFORMANCE_TRACKER_BEAN") != null) {
+                context.getHttpServletRequest().setAttribute("CALL_TYPE", "Testing");
+                List<HistoricActivityInstance> histActInstList = historyService.createHistoricActivityInstanceQuery().processInstanceId(attCamundaHistoryEvent.getProcInstId()).list();
+
+                if (histActInstList != null && histActInstList.size() > 0) {
+                    for (HistoricActivityInstance currHistoricActivityInstance : histActInstList) {
+                        if (currHistoricActivityInstance != null && currHistoricActivityInstance.getActivityName() != null && currHistoricActivityInstance.getStartTime() != null
+                                && currHistoricActivityInstance.getEndTime() != null) {
+                            logger.info("value of serviceTrack:" + currHistoricActivityInstance);
+                            message = "Log Entry Created";
+                            logger.info(message);
+                        }
+                    }
+                }
+                if (attCamundaHistoryEvent.getHistoryEventList() != null && attCamundaHistoryEvent.getHistoryEventList().size() > 0) {
+                    List<HistoricActivityInstanceEventEntity> historyEventList = attCamundaHistoryEvent.getHistoryEventList();
+                    for (HistoricActivityInstanceEventEntity actiEvent : historyEventList) {
+                        //  resolve null pointer exception if actiEvent.getActivityName()
+                        message = "Log Entry Created";
+                    }
+                }
+            }
+        }
+        return message;
+    }
+
+    @Override
+    public String createLogMessage(String startTime, String endTime, String serviceName) {
+        String message = "no logs Created";
+
+        if (context != null && context.getHttpServletRequest() != null && context.getHttpServletRequest().getAttribute("PERFORMANCE_TRACKER_BEAN") != null) {
+            context.getHttpServletRequest().setAttribute("X-CSI-ClientApp", "AJSC-CSI~sdsds");
+               /*PerformanceTrackingBean trackingBean =(PerformanceTrackingBean) context.getHttpServletRequest().getAttribute("PERFORMANCE_TRACKER_BEAN");
+               PerformanceTracking.addInvokeServiceTrack(trackingBean,
+                                       serviceName, Long.valueOf(startTime), Long.valueOf(endTime), "Completed",
+                                       500, 1000) ;*/
+            message = "Log Entry Created";
+        }
+        // return text message of what was done
+        return message;
+    }
+
+    @Override
+    public String createLogMessageUsingHistory(String procInstId, String histEventList) {
+        String message = "no logs Created";
+        logger.info("value of history events:" + histEventList);
+        logger.info("value of events:" + histEventList + ":" + histEventList);
+        if (context != null && context.getHttpServletRequest() != null && context.getHttpServletRequest().getAttribute("PERFORMANCE_TRACKER_BEAN") != null) {
+            context.getHttpServletRequest().setAttribute("CALL_TYPE", "Testing");
+            List<HistoricActivityInstance> histActInstList = historyService.createHistoricActivityInstanceQuery().processInstanceId(procInstId).list();
+
+            if (histActInstList != null && histActInstList.size() > 0) {
+                for (HistoricActivityInstance currHistoricActivityInstance : histActInstList) {
+                    if (currHistoricActivityInstance != null && currHistoricActivityInstance.getActivityName() != null && currHistoricActivityInstance.getStartTime() != null
+                            && currHistoricActivityInstance.getEndTime() != null) {
+                        logger.info("value of serviceTrack:" + currHistoricActivityInstance);
+                        message = "Log Entry Created";
+                        logger.info(message);
+                    }
+                }
+            }
+        }
+        return message;
+    }
+
+    @Override
+    public String CreateHistLog(String procInstId) {
+        String message = "no logs Created";
+        if (context != null && context.getHttpServletRequest() != null && context.getHttpServletRequest().getAttribute("PERFORMANCE_TRACKER_BEAN") != null) {
+            List<HistoricActivityInstance> histActInstList = historyService.createHistoricActivityInstanceQuery().processInstanceId(procInstId).list();
+
+            if (histActInstList != null && histActInstList.size() > 0) {
+                for (HistoricActivityInstance currHistoricActivityInstance : histActInstList) {
+                    if (currHistoricActivityInstance != null && currHistoricActivityInstance.getActivityName() != null && currHistoricActivityInstance.getStartTime() != null
+                            && currHistoricActivityInstance.getEndTime() != null) {
+                        logger.info("value of serviceTrack:" + currHistoricActivityInstance);
+                        context.getHttpServletRequest().setAttribute("X-CSI-ClientApp", "AJSC-CSI~sdsds");
+                        message = "Log Entry Created";
+                    }
+                }
+            }
+        }
+        return message;
+    }
+
+    private String getActivityInstanceState(int activityInstanceState) {
+        String activityState = "Default";
+        if (activityInstanceState == 1) {
+            activityState = "Complete";
+        } else if (activityInstanceState == 2) {
+            activityState = "Cancelled";
+        }
+        return activityState;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/SecureServiceBase.java b/src/main/java/org/onap/clamp/clds/service/SecureServiceBase.java
new file mode 100644 (file)
index 0000000..c17af97
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.SecurityContext;
+import java.security.Principal;
+
+/**
+ * Base/abstract Service class.
+ * Implements shared security methods.
+ */
+public abstract class SecureServiceBase {
+    private static final Logger logger = LoggerFactory.getLogger(SecureServiceBase.class);
+
+    @Context
+    private SecurityContext securityContext;
+
+    /**
+     * Get the userid
+     *
+     * @return
+     */
+    public String getUserid() {
+        return getPrincipalName();
+    }
+
+    /**
+     * Get the principal name.
+     *
+     * @return
+     */
+    public String getPrincipalName() {
+        Principal p = securityContext.getUserPrincipal();
+        String name = "Not found";
+        if (p != null) {
+            name = p.getName();
+        }
+        logger.debug("userPrincipal.getName()={}", name);
+        return name;
+    }
+
+    /**
+     * Check if user is authorized for the given the permission.
+     * Allow matches if user has a permission with an "*" in permission instance
+     * or permission action even if the permission to check has a specific value
+     * in those fields.  For example:
+     * if the user has this permission: app-perm-type|*|*
+     * it will be authorized if the inPermission to check is: app-perm-type|dev|read
+     *
+     * @param inPermission
+     * @return
+     * @throws NotAuthorizedException
+     */
+    public boolean isAuthorized(SecureServicePermission inPermission) throws NotAuthorizedException {
+        boolean authorized = false;
+        logger.debug("checking if {} has permission: {}", getPrincipalName(), inPermission);
+     // check if the user has the permission key or the permission key with a combination of all instance and/or all action.
+        if (securityContext.isUserInRole(inPermission.getKey())) {
+            logger.info("{} authorized for permission: {}", getPrincipalName(), inPermission.getKey());
+            authorized = true;
+            // the rest of these don't seem to be required - isUserInRole method appears to take * as a wildcard
+        } else if (securityContext.isUserInRole(inPermission.getKeyAllInstance())) {
+            logger.info("{} authorized because user has permission with * for instance: {}", getPrincipalName(), inPermission.getKey());
+            authorized = true;
+        } else if (securityContext.isUserInRole(inPermission.getKeyAllInstanceAction())) {
+            logger.info("{} authorized because user has permission with * for instance and * for action: {}", getPrincipalName(), inPermission.getKey());
+            authorized = true;
+        } else if (securityContext.isUserInRole(inPermission.getKeyAllAction())) {
+            logger.info("{} authorized because user has permission with * for action: {}", getPrincipalName(), inPermission.getKey());
+            authorized = true;
+        } else {
+            String msg = getPrincipalName() + " does not have permission: " + inPermission;
+            logger.warn(msg);
+            throw new NotAuthorizedException(msg);
+        }
+        return authorized;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/SecureServicePermission.java b/src/main/java/org/onap/clamp/clds/service/SecureServicePermission.java
new file mode 100644 (file)
index 0000000..a2213f9
--- /dev/null
@@ -0,0 +1,190 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service;
+
+/**
+ * Permission class that can be instantiated easily using constructor or factory methods.
+ */
+public class SecureServicePermission {
+    public final static String ALL = "*";
+
+    private String type;
+    private String instance;
+    private String action;
+
+    /**
+     * Factory method to create permission given type, instance, and action.
+     *
+     * @param type
+     * @param instance
+     * @param action
+     * @return
+     */
+    public static SecureServicePermission create(String type, String instance, String action) {
+        return new SecureServicePermission(type, instance, action);
+    }
+
+    /**
+     * Factory method to create permission given type and instance.  Default action to ALL/*.
+     *
+     * @param type
+     * @param instance
+     * @return
+     */
+    public static SecureServicePermission create(String type, String instance) {
+        return new SecureServicePermission(type, instance);
+    }
+
+    /**
+     * Factory method to create permission given type.  Default instance and action to ALL/*.
+     *
+     * @param type
+     * @return
+     */
+    public static SecureServicePermission create(String type) {
+        return new SecureServicePermission(type);
+    }
+
+    /**
+     * Instantiate permission given type, instance, and action.
+     *
+     * @param type
+     * @param instance
+     * @param action
+     */
+    public SecureServicePermission(String type, String instance, String action) {
+        this.type = type;
+        this.instance = instance;
+        this.action = action;
+    }
+
+    /**
+     * Instantiate permission given type and instance.  Default action to ALL/*.
+     *
+     * @param type
+     * @param instance
+     */
+    public SecureServicePermission(String type, String instance) {
+        this.type = type;
+        this.instance = instance;
+        this.action = ALL;
+    }
+
+    /**
+     * Instantiate permission given type.  Default instance and action to ALL/*.
+     *
+     * @param type
+     */
+    public SecureServicePermission(String type) {
+        this.type = type;
+        this.instance = ALL;
+        this.action = ALL;
+    }
+
+    /**
+     * Override toString - return permission in key format
+     */
+    public String toString() {
+        return getKey();
+    }
+
+    /**
+     * Return Permission in Key format = type, instance, and action separate by pipe character.
+     *
+     * @return
+     */
+    public String getKey() {
+        return type + "|" + instance + "|" + action;
+    }
+
+    /**
+     * Return Permission in Key format = type, all instance, and action separate by pipe character.
+     *
+     * @return
+     */
+    public String getKeyAllInstance() {
+        return type + "|" + ALL + "|" + action;
+    }
+
+    /**
+     * Return Permission in Key format = type, all instance, and all action separate by pipe character.
+     *
+     * @return
+     */
+    public String getKeyAllInstanceAction() {
+        return type + "|" + ALL + "|" + ALL;
+    }
+
+    /**
+     * Return Permission in Key format = type, instance, and all action separate by pipe character.
+     *
+     * @return
+     */
+    public String getKeyAllAction() {
+        return type + "|" + instance + "|" + ALL;
+    }
+
+    /**
+     * @return the type
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the instance
+     */
+    public String getInstance() {
+        return instance;
+    }
+
+    /**
+     * @param instance the instance to set
+     */
+    public void setInstance(String instance) {
+        this.instance = instance;
+    }
+
+    /**
+     * @return the action
+     */
+    public String getAction() {
+        return action;
+    }
+
+    /**
+     * @param action the action to set
+     */
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogService.java b/src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogService.java
new file mode 100644 (file)
index 0000000..d0ef135
--- /dev/null
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service.rs;
+
+import io.swagger.annotations.Api;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+
+
+/**
+ * Service to invoke example Camunda process.
+ * <p>
+ * Try testing by using:
+ * http://[hostname]:[serverPort]/jaxrsservices/log/log-message/your-message-here
+ */
+@Api(value = "/log")
+@Path("/log")
+@Produces({MediaType.TEXT_PLAIN})
+public interface JaxrsLogService {
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param logMessageText
+     * @return output from service - comment on what was done
+     */
+    @GET
+    @Path("/log-message/{logMessageText}")
+    @Produces(MediaType.TEXT_PLAIN)
+    String logMessage(@PathParam("logMessageText") String logMessageText, @QueryParam("javamail") String javamail, @QueryParam("springmail") String springmail, @QueryParam("commonsmail") String commonsmail);
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @return output from service - comment on what was done
+     */
+    @POST
+    @Path("/postLogHist")
+    @Produces(MediaType.TEXT_PLAIN)
+    @Consumes(MediaType.APPLICATION_JSON)
+    String postLogMessage(String histEventList);
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param startTime
+     * @param endTime
+     * @param serviceName
+     * @return output from service - comment on what was done
+     */
+    @GET
+    @Path("/createLog/{startTime}/{endTime}/{serviceName}")
+    @Produces(MediaType.TEXT_PLAIN)
+    String createLogMessage(@PathParam("startTime") String startTime, @PathParam("endTime") String endTime, @PathParam("serviceName") String serviceName);
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param procInstId
+     * @param histEventList
+     * @return output from service - comment on what was done
+     */
+    @GET
+    @Path("/createLogHist/{procInstId}/{histEventList}")
+    @Produces(MediaType.TEXT_PLAIN)
+    String createLogMessageUsingHistory(@PathParam("procInstId") String procInstId, @PathParam("histEventList") String histEventList);
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param procInstId
+     * @return output from service - comment on what was done
+     */
+    @GET
+    @Path("/histLog/{procInstId}")
+    @Produces(MediaType.TEXT_PLAIN)
+    String CreateHistLog(@PathParam("procInstId") String procInstId);
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogServiceImpl.java b/src/main/java/org/onap/clamp/clds/service/rs/JaxrsLogServiceImpl.java
new file mode 100644 (file)
index 0000000..4ef7d2e
--- /dev/null
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.service.rs;
+
+import com.att.ajsc.common.AjscService;
+import org.onap.clamp.clds.service.LogService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Service to invoke example Camunda process.
+ * <p>
+ * Try testing by using:
+ * http://[hostname]:[serverPort]/services/log/log-message/your-message-here
+ */
+@AjscService
+public class JaxrsLogServiceImpl implements JaxrsLogService {
+
+    @Autowired
+    private LogService logService;
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param logMessageText
+     * @return output from service - comment on what was done
+     */
+    public String logMessage(String logMessageText, String javamail, String springmail, String commonsmail) {
+        return logService.logMessage(logMessageText, javamail, springmail, commonsmail);
+    }
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @return output from service - comment on what was done
+     */
+    public String postLogMessage(String histEventList) {
+        return logService.postLogMessage(histEventList);
+    }
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param startTime
+     * @param endTime
+     * @param serviceName
+     * @return output from service - comment on what was done
+     */
+    public String createLogMessage(String startTime, String endTime, String serviceName) {
+        return logService.createLogMessage(startTime, endTime, serviceName);
+    }
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param procInstId
+     * @param histEventList
+     * @return output from service - comment on what was done
+     */
+    public String createLogMessageUsingHistory(String procInstId, String histEventList) {
+        return logService.createLogMessageUsingHistory(procInstId, histEventList);
+    }
+
+    /**
+     * REST service that executes example camunda process to log input message.
+     *
+     * @param procInstId
+     * @return output from service - comment on what was done
+     */
+    public String CreateHistLog(String procInstId) {
+        return logService.CreateHistLog(procInstId);
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/transform/TransformUtil.java b/src/main/java/org/onap/clamp/clds/transform/TransformUtil.java
new file mode 100644 (file)
index 0000000..2c666db
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.transform;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility methods supporting transforms.
+ */
+public class TransformUtil {
+
+    /**
+     * Return resource as a Stream.
+     *
+     * @param name
+     * @return resource - resource as stream
+     */
+    public static InputStream getResourceAsStream(String name) {
+        InputStream is = Thread.currentThread().getContextClassLoader()
+                .getResourceAsStream(name);
+        if (is == null) {
+            throw new IllegalArgumentException("Unable to find resource: "
+                    + name);
+        }
+        return is;
+    }
+
+    /**
+     * Return resource as a Stream.
+     *
+     * @param name
+     * @throws IOException
+     */
+    public static String getResourceAsString(String name) throws IOException {
+        InputStream is = getResourceAsStream(name);
+        java.util.Scanner scanner = new java.util.Scanner(is);
+        java.util.Scanner s = scanner.useDelimiter("\\A");
+        String text = s.hasNext() ? s.next() : "";
+        s.close();
+        scanner.close();
+        is.close();
+        return text;
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/transform/XslTransformer.java b/src/main/java/org/onap/clamp/clds/transform/XslTransformer.java
new file mode 100644 (file)
index 0000000..7d00316
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.transform;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+/**
+ * XSL Transformer.
+ */
+public class XslTransformer {
+
+    private Templates templates;
+
+    public void setXslResourceName(String xslResourceName) throws TransformerConfigurationException {
+        TransformerFactory tfactory = TransformerFactory.newInstance();
+        templates = tfactory.newTemplates(new StreamSource(TransformUtil.getResourceAsStream(xslResourceName)));
+    }
+
+    /**
+     * Given xml input, return the transformed result.
+     *
+     * @param xml
+     * @throws TransformerException
+     */
+    public String doXslTransformToString(String xml) throws TransformerException {
+        StringWriter output = new StringWriter(4000);
+
+        Transformer transformer = templates.newTransformer();
+        transformer.transform(new StreamSource(new StringReader(xml)),
+                new StreamResult(output));
+        return output.toString();
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/workflow/LogMessageDelegate.java b/src/main/java/org/onap/clamp/clds/workflow/LogMessageDelegate.java
new file mode 100644 (file)
index 0000000..693b334
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.workflow;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+
+/**
+ * Log message.
+ * Invoked by the log-message-wf example Camunda workflow/bpmn.
+ */
+public class LogMessageDelegate implements JavaDelegate {
+
+    /**
+     * Perform activity.  Log message from running process and set a variable in the running process.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String logMessageText = (String) execution.getVariable("logMessageText");
+
+        System.out.println("Invoked from processDefinitionId=" + execution.getProcessDefinitionId() + ", processInstanceId=" + execution.getProcessInstanceId() + ", activityInstanceId=" + execution.getActivityInstanceId() + ": logMessageText=" + logMessageText);
+        execution.setVariable("isMessageLogComplete", true);
+    }
+}
diff --git a/src/main/java/org/onap/clamp/clds/workflow/ProcessRequestDelegate.java b/src/main/java/org/onap/clamp/clds/workflow/ProcessRequestDelegate.java
new file mode 100644 (file)
index 0000000..3244964
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onap.clamp.clds.workflow;
+
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class ProcessRequestDelegate implements JavaDelegate {
+
+    private static final Logger logger = LoggerFactory.getLogger(ProcessRequestDelegate.class);
+
+    //@Override
+    public void execute(DelegateExecution execution) throws Exception {
+        logger.info("Processing request by '" + execution.getVariable("customerId") + "'...");
+        logger.info("Processing request by '" + execution.getVariable("amount") + "'...");
+    }
+
+}
diff --git a/src/main/java/org/onap/clamp/clds/workflow/RestMessageDelegate.java b/src/main/java/org/onap/clamp/clds/workflow/RestMessageDelegate.java
new file mode 100644 (file)
index 0000000..0eda2de
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.workflow;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Log message.
+ * Invoked by the log-message-wf example Camunda workflow/bpmn.
+ */
+public class RestMessageDelegate implements JavaDelegate {
+    private static final Logger logger = Logger.getLogger(RestMessageDelegate.class.getName());
+
+    /**
+     * Perform activity.  Log message from running process and set a variable in the running process.
+     *
+     * @param execution
+     */
+    public void execute(DelegateExecution execution) throws Exception {
+        String logMessageText = (String) execution.getVariable("logMessageText");
+        RestTemplate restTemplate = new RestTemplate();
+        Map<String, String> restValues = new HashMap<>();
+        restValues.put("procInstId", execution.getProcessInstanceId());
+        logger.info("Invoked from processDefinitionId=" + execution.getProcessDefinitionId() + ", processInstanceId=" + execution.getProcessInstanceId() + ", activityInstanceId=" + execution.getActivityInstanceId() + ": logMessageText=" + logMessageText);
+        // TODO: this should be fixed - put in temporary solution with existing sysprop and vars - why are we calling our own service?
+        String port = System.getProperty("server.port");
+        ResponseEntity<String> resp = restTemplate.getForEntity("http://localhost:" + port + "/services/CamundaExample/v1/jaxrsExample/log/histLog/{procInstId}", String.class, restValues);
+        logger.info("value of resp:" + resp);
+        execution.setVariable("isMessageLogComplete", true);
+    }
+}
diff --git a/src/main/resources/META-INF/processes.xml b/src/main/resources/META-INF/processes.xml
new file mode 100644 (file)
index 0000000..fddc60d
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<process-application
+       xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+       <process-archive name="example-process-archive">
+               <process-engine>default</process-engine>
+               <resource>bpmn/log-message.bpmn</resource>              
+               <properties>
+                       <property name="isDeleteUponUndeploy">true</property>
+                       <property name="isScanForProcessDefinitions">false</property>
+               </properties>
+       </process-archive>
+
+</process-application>
diff --git a/src/main/resources/META-INF/resources/designer/WEB-INF/web.xml b/src/main/resources/META-INF/resources/designer/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..b3b47e3
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+  <welcome-file-list>
+    <welcome-file>index.html</welcome-file>
+  </welcome-file-list>
+</web-app>
diff --git a/src/main/resources/META-INF/resources/designer/authenticate.html b/src/main/resources/META-INF/resources/designer/authenticate.html
new file mode 100644 (file)
index 0000000..0db00c3
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<div ng-init="authenticate()"> 
+       <b>Validating Login.... Please wait....</b>
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/css/AdminLTE.css b/src/main/resources/META-INF/resources/designer/css/AdminLTE.css
new file mode 100644 (file)
index 0000000..8821326
--- /dev/null
@@ -0,0 +1,3252 @@
+@import url(//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);
+@import url(//fonts.googleapis.com/css?family=Kaushan+Script);
+/*! 
+ *   AdminLTE v1.2
+ *   Author: AlmsaeedStudio.com
+ *   License: Open source - MIT
+ *           Please visit http://opensource.org/licenses/MIT for more information
+!*/
+/*
+    Core: General style
+----------------------------
+*/
+html,
+body {
+  overflow-x: hidden!important;
+  overflow-y: hidden!important;
+  /*font-family: 'Source Sans Pro', sans-serif;*/
+  font-size:12px;
+  -webkit-font-smoothing: antialiased;
+  min-height: 100%;
+  background: #f9f9f9;
+}
+a {
+  color: #3c8dbc;
+}
+a:hover,
+a:active,
+a:focus {
+  outline: none;
+  text-decoration: none;
+  color: #72afd2;
+}
+/* Layouts */
+.wrapper {
+  min-height: 100%;
+}
+.wrapper:before,
+.wrapper:after {
+  display: table;
+  content: " ";
+}
+.wrapper:after {
+  clear: both;
+}
+/* Header */
+body > .header {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 1030;
+}
+/* Define 2 column template */
+.right-side,
+.left-side {
+  min-height: 100%;
+  display: block;
+}
+/*right side - contins main content*/
+.right-side {
+  background-color: #f9f9f9;
+  margin-left: 220px;
+}
+/*left side - contains sidebar*/
+.left-side {
+  position: absolute;
+  width: 220px;
+  top: 0;
+}
+@media screen and (min-width: 992px) {
+  .left-side {
+    top: 50px;
+  }
+  /*Right side strech mode*/
+  .right-side.strech {
+    margin-left: 0;
+  }
+  .right-side.strech > .content-header {
+    margin-top: 0px;
+  }
+  /* Left side collapse */
+  .left-side.collapse-left {
+    left: -220px;
+  }
+}
+/*Give content full width on xs screens*/
+@media screen and (max-width: 992px) {
+  .right-side {
+    margin-left: 0;
+  }
+}
+/*
+    By default the layout is not fixed but if you add the class .fixed to the body element
+    the sidebar and the navbar will automatically become poisitioned fixed
+*/
+body.fixed > .header,
+body.fixed .left-side,
+
+body.fixed > .header {
+  top: 0;
+  right: 0;
+  left: 0;
+}
+
+body.fixed .wrapper {
+  margin-top: 50px;
+}
+/* Content */
+.content {
+  padding: 20px 15px;
+  /* background: #f9f9f9; */
+}
+/* Utility */
+/* H1 - H6 font */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+  font-family: 'Source Sans Pro', sans-serif;
+}
+/* Page Header */
+.page-header {
+  margin: 10px 0 20px 0;
+  font-size: 22px;
+}
+.page-header > small {
+  color: #666;
+  display: block;
+  margin-top: 5px;
+}
+/* All images should be responsive */
+img {
+  max-width: 100% !important;
+}
+.sort-highlight {
+  background: #f4f4f4;
+  border: 1px dashed #ddd;
+  margin-bottom: 10px;
+}
+/* 10px padding and margins */
+.pad {
+  padding: 10px;
+}
+.margin {
+  margin: 10px;
+}
+/* Display inline */
+.inline {
+  display: inline;
+  width: auto;
+}
+/* Background colors */
+.bg-red,
+.bg-yellow,
+.bg-aqua,
+.bg-blue,
+.bg-light-blue,
+.bg-green,
+.bg-navy,
+.bg-teal,
+.bg-olive,
+.bg-lime,
+.bg-orange,
+.bg-fuchsia,
+.bg-purple,
+.bg-maroon,
+.bg-black {
+  color: #f9f9f9 !important;
+}
+.bg-gray {
+  background-color: #eaeaec !important;
+}
+.bg-black {
+  background-color: #222222 !important;
+}
+.bg-red {
+  background-color: #f56954 !important;
+}
+.bg-yellow {
+  background-color: #f39c12 !important;
+}
+.bg-aqua {
+  background-color: #00c0ef !important;
+}
+.bg-blue {
+  background-color: #0073b7 !important;
+}
+.bg-light-blue {
+  background-color: #3c8dbc !important;
+}
+.bg-green {
+  background-color: #00a65a !important;
+}
+.bg-navy {
+  background-color: #001f3f !important;
+}
+.bg-teal {
+  background-color: #39cccc !important;
+}
+.bg-olive {
+  background-color: #3d9970 !important;
+}
+.bg-lime {
+  background-color: #01ff70 !important;
+}
+.bg-orange {
+  background-color: #ff851b !important;
+}
+.bg-fuchsia {
+  background-color: #f012be !important;
+}
+.bg-purple {
+  background-color: #932ab6 !important;
+}
+.bg-maroon {
+  background-color: #85144b !important;
+}
+/* Text colors */
+.text-red {
+  color: #f56954 !important;
+}
+.text-yellow {
+  color: #f39c12 !important;
+}
+.text-aqua {
+  color: #00c0ef !important;
+}
+.text-blue {
+  color: #0073b7 !important;
+}
+.text-black {
+  color: #222222 !important;
+}
+.text-light-blue {
+  color: #3c8dbc !important;
+}
+.text-green {
+  color: #00a65a !important;
+}
+.text-navy {
+  color: #001f3f !important;
+}
+.text-teal {
+  color: #39cccc !important;
+}
+.text-olive {
+  color: #3d9970 !important;
+}
+.text-lime {
+  color: #01ff70 !important;
+}
+.text-orange {
+  color: #ff851b !important;
+}
+.text-fuchsia {
+  color: #f012be !important;
+}
+.text-purple {
+  color: #932ab6 !important;
+}
+.text-maroon {
+  color: #85144b !important;
+}
+/*Hide elements by display none only*/
+.hide {
+  display: none !important;
+}
+/* Remove borders */
+.no-border {
+  border: 0px !important;
+}
+/* Remove padding */
+.no-padding {
+  padding: 0px !important;
+}
+/* Remove margins */
+.no-margin {
+  margin: 0px !important;
+}
+/* Remove box shadow */
+.no-shadow {
+  box-shadow: none!important;
+}
+/* Don't display when printing */
+@media print {
+  .no-print {
+    display: none;
+  }
+  .left-side,
+  .header,
+  .content-header {
+    display: none;
+  }
+  .right-side {
+    margin: 0;
+  }
+}
+/* Remove border radius */
+.flat {
+  -webkit-border-radius: 0 !important;
+  -moz-border-radius: 0 !important;
+  border-radius: 0 !important;
+}
+/* Change the color of the striped tables */
+.table-striped > tbody > tr:nth-child(odd) > td,
+.table-striped > tbody > tr:nth-child(odd) > th {
+  background-color: #f3f4f5;
+}
+.table.no-border,
+.table.no-border td,
+.table.no-border th {
+  border: 0;
+}
+/* .text-center in tables */
+table.text-center,
+table.text-center td,
+table.text-center th {
+  text-align: center;
+}
+.table.align th {
+  text-align: left;
+}
+.table.align td {
+  text-align: right;
+}
+.text-bold,
+.text-bold.table td,
+.text-bold.table th {
+  font-weight: 700;
+}
+.border-radius-none {
+  -webkit-border-radius: 0 !important;
+  -moz-border-radius: 0 !important;
+  border-radius: 0 !important;
+}
+/* _fix for sparkline tooltip */
+.jqstooltip {
+  padding: 5px!important;
+  width: auto!important;
+  height: auto!important;
+}
+/*
+Gradient Background colors
+*/
+.bg-teal-gradient {
+  background: #39cccc !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;
+  background: -ms-linear-gradient(bottom, #39cccc, #7adddd) !important;
+  background: -moz-linear-gradient(center bottom, #39cccc 0%, #7adddd 100%) !important;
+  background: -o-linear-gradient(#7adddd, #39cccc) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;
+  color: #fff;
+}
+.bg-light-blue-gradient {
+  background: #3c8dbc !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;
+  background: -ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;
+  background: -moz-linear-gradient(center bottom, #3c8dbc 0%, #67a8ce 100%) !important;
+  background: -o-linear-gradient(#67a8ce, #3c8dbc) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;
+  color: #fff;
+}
+.bg-blue-gradient {
+  background: #0073b7 !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;
+  background: -ms-linear-gradient(bottom, #0073b7, #0089db) !important;
+  background: -moz-linear-gradient(center bottom, #0073b7 0%, #0089db 100%) !important;
+  background: -o-linear-gradient(#0089db, #0073b7) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;
+  color: #fff;
+}
+.bg-aqua-gradient {
+  background: #00c0ef !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;
+  background: -ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;
+  background: -moz-linear-gradient(center bottom, #00c0ef 0%, #14d1ff 100%) !important;
+  background: -o-linear-gradient(#14d1ff, #00c0ef) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;
+  color: #fff;
+}
+.bg-yellow-gradient {
+  background: #f39c12 !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;
+  background: -ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;
+  background: -moz-linear-gradient(center bottom, #f39c12 0%, #f7bc60 100%) !important;
+  background: -o-linear-gradient(#f7bc60, #f39c12) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;
+  color: #fff;
+}
+.bg-purple-gradient {
+  background: #932ab6 !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #932ab6), color-stop(1, #b959d9)) !important;
+  background: -ms-linear-gradient(bottom, #932ab6, #b959d9) !important;
+  background: -moz-linear-gradient(center bottom, #932ab6 0%, #b959d9 100%) !important;
+  background: -o-linear-gradient(#b959d9, #932ab6) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b959d9', endColorstr='#932ab6', GradientType=0) !important;
+  color: #fff;
+}
+.bg-green-gradient {
+  background: #00a65a !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;
+  background: -ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;
+  background: -moz-linear-gradient(center bottom, #00a65a 0%, #00ca6d 100%) !important;
+  background: -o-linear-gradient(#00ca6d, #00a65a) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;
+  color: #fff;
+}
+.bg-red-gradient {
+  background: #f56954 !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f56954), color-stop(1, #f89384)) !important;
+  background: -ms-linear-gradient(bottom, #f56954, #f89384) !important;
+  background: -moz-linear-gradient(center bottom, #f56954 0%, #f89384 100%) !important;
+  background: -o-linear-gradient(#f89384, #f56954) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f89384', endColorstr='#f56954', GradientType=0) !important;
+  color: #fff;
+}
+.bg-black-gradient {
+  background: #222222 !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #222222), color-stop(1, #3c3c3c)) !important;
+  background: -ms-linear-gradient(bottom, #222222, #3c3c3c) !important;
+  background: -moz-linear-gradient(center bottom, #222222 0%, #3c3c3c 100%) !important;
+  background: -o-linear-gradient(#3c3c3c, #222222) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3c3c3c', endColorstr='#222222', GradientType=0) !important;
+  color: #fff;
+}
+.bg-maroon-gradient {
+  background: #85144b !important;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #85144b), color-stop(1, #b11b64)) !important;
+  background: -ms-linear-gradient(bottom, #85144b, #b11b64) !important;
+  background: -moz-linear-gradient(center bottom, #85144b 0%, #b11b64 100%) !important;
+  background: -o-linear-gradient(#b11b64, #85144b) !important;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b11b64', endColorstr='#85144b', GradientType=0) !important;
+  color: #fff;
+}
+.connectedSortable {
+  min-height: 100px;
+}
+/*---------------------------------------------------
+    LESS Elements 0.9
+  ---------------------------------------------------
+    A set of useful LESS mixins
+    More info at: http://lesselements.com
+  ---------------------------------------------------*/
+/*
+    Components: navbar, logo and content header
+-------------------------------------------------
+*/
+
+body > .header .logo {
+  float: left;
+  font-size: 20px;
+  line-height: 50px;
+  text-align: center;
+  padding: 0 10px;
+  width: 220px;
+  font-family: 'Kaushan Script', cursive;
+  font-weight: 500;
+  height: 50px;
+  display: block;
+}
+
+.logo {
+  float: left;
+  font-size: 20px;
+  text-align: center;
+  font-family: 'Kaushan Script', cursive;
+  font-weight: 500;
+  height: 50px;
+  display: block;
+}
+
+.logo_name {
+  float: left;
+  font-size: 15px;
+  text-align: center;
+  font-family: 'Kaushan Script', cursive;
+  font-weight: 500;
+  height: 50px;
+  display: block;
+}
+
+
+body > .header .logo .icon {
+  margin-right: 10px;
+}
+.right-side > .content-header {
+  position: relative;
+  padding: 15px 15px 10px 20px;
+}
+.right-side > .content-header > h1 {
+  margin: 0;
+  font-size: 24px;
+}
+.right-side > .content-header > h1 > small {
+  font-size: 15px;
+  display: inline-block;
+  padding-left: 4px;
+  font-weight: 300;
+}
+.right-side > .content-header > .breadcrumb {
+  float: right;
+  background: transparent;
+  margin-top: 0px;
+  margin-bottom: 0;
+  font-size: 12px;
+  padding: 7px 5px;
+  position: absolute;
+  top: 15px;
+  right: 10px;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+.right-side > .content-header > .breadcrumb > li > a {
+  color: #444;
+  text-decoration: none;
+}
+.right-side > .content-header > .breadcrumb > li > a > .fa,
+.right-side > .content-header > .breadcrumb > li > a > .glyphicon,
+.right-side > .content-header > .breadcrumb > li > a > .ion {
+  margin-right: 5px;
+}
+.right-side > .content-header > .breadcrumb > li + li:before {
+  content: '>\00a0';
+}
+@media screen and (max-width: 767px) {
+  .right-side > .content-header > .breadcrumb {
+    position: relative;
+    margin-top: 5px;
+    top: 0;
+    right: 0;
+    float: none;
+    background: #efefef;
+  }
+}
+
+/* 
+    Dropdown menus
+----------------------------
+*/
+/*Dropdowns in general*/
+.dropdown-menu {
+  -webkit-box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
+  box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
+}
+.dropdown-menu > li > a > .glyphicon,
+.dropdown-menu > li > a > .fa,
+.dropdown-menu > li > a > .ion {
+  margin-right: 10px;
+}
+
+.dropdown-menu > li > a:hover {
+  background-color: #3c8dbc;
+  color: #f9f9f9;
+}
+
+.dropdown-menu > div > li >  a:hover {
+  background-color: #3c8dbc;
+  color: #f9f9f9;
+}
+
+.skin-blue .navbar .dropdown-menu > div > li > a {
+  color: #444444;
+}
+
+.dropdown-menu > div > li > a {
+  display: block;
+  padding: 3px 20px;
+  clear: both;
+  font-weight: normal;
+  line-height: 1.42857143;
+  color: #333;
+  white-space: nowrap;
+}
+
+/*Drodown in navbars*/
+.skin-blue .navbar .dropdown-menu > li > a {
+  color: #444444;
+}
+/*
+    Navbar custom dropdown menu
+------------------------------------
+*/
+
+/* Add fade animation to dropdown menus */
+.open:not(.dropup) > .dropdown-menu {
+  animation-name: fadeAnimation;
+  animation-duration: .7s;
+  animation-iteration-count: 1;
+  animation-timing-function: ease;
+  animation-fill-mode: forwards;
+  -webkit-animation-name: fadeAnimation;
+  -webkit-animation-duration: .7s;
+  -webkit-animation-iteration-count: 1;
+  -webkit-animation-timing-function: ease;
+  -webkit-animation-fill-mode: forwards;
+  -moz-animation-name: fadeAnimation;
+  -moz-animation-duration: .7s;
+  -moz-animation-iteration-count: 1;
+  -moz-animation-timing-function: ease;
+  -moz-animation-fill-mode: forwards;
+}
+@keyframes fadeAnimation {
+  from {
+    opacity: 0;
+    top: 120%;
+  }
+  to {
+    opacity: 1;
+    top: 100%;
+  }
+}
+@-webkit-keyframes fadeAnimation {
+  from {
+    opacity: 0;
+    top: 120%;
+  }
+  to {
+    opacity: 1;
+    top: 100%;
+  }
+}
+
+/* 
+   All form elements including input, select, textarea etc.
+-----------------------------------------------------------------
+*/
+.form-control {
+  -webkit-border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+  border-radius: 0px !important;
+  box-shadow: none;
+}
+.form-control:focus {
+  border-color: #3c8dbc !important;
+  box-shadow: none;
+}
+.form-group.has-success label {
+  color: #00a65a;
+}
+.form-group.has-success .form-control {
+  border-color: #00a65a !important;
+  box-shadow: none;
+}
+.form-group.has-warning label {
+  color: #f39c12;
+}
+.form-group.has-warning .form-control {
+  border-color: #f39c12 !important;
+  box-shadow: none;
+}
+.form-group.has-error label {
+  color: #f56954;
+}
+.form-group.has-error .form-control {
+  border-color: #f56954 !important;
+  box-shadow: none;
+}
+/* Input group */
+.input-group .input-group-addon {
+  border-radius: 0;
+  background-color: #f4f4f4;
+}
+/* button groups */
+.btn-group-vertical .btn.btn-flat:first-of-type,
+.btn-group-vertical .btn.btn-flat:last-of-type {
+  border-radius: 0;
+}
+/* Checkbox and radio inputs */
+.checkbox,
+.radio {
+  padding-left: 0;
+}
+/* 
+    Compenent: Progress bars
+--------------------------------
+*/
+/* size variation */
+.progress.sm {
+  height: 10px;
+}
+.progress.xs {
+  height: 7px;
+}
+/* Vertical bars */
+.progress.vertical {
+  position: relative;
+  width: 30px;
+  height: 200px;
+  display: inline-block;
+  margin-right: 10px;
+}
+.progress.vertical > .progress-bar {
+  width: 100%!important;
+  position: absolute;
+  bottom: 0;
+}
+.progress.vertical.sm {
+  width: 20px;
+}
+.progress.vertical.xs {
+  width: 10px;
+}
+/* Remove margins from progress bars when put in a table */
+.table tr > td .progress {
+  margin: 0;
+}
+.progress-bar-light-blue,
+.progress-bar-primary {
+  background-color: #3c8dbc;
+}
+.progress-striped .progress-bar-light-blue,
+.progress-striped .progress-bar-primary {
+  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-green,
+.progress-bar-success {
+  background-color: #00a65a;
+}
+.progress-striped .progress-bar-green,
+.progress-striped .progress-bar-success {
+  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-aqua,
+.progress-bar-info {
+  background-color: #00c0ef;
+}
+.progress-striped .progress-bar-aqua,
+.progress-striped .progress-bar-info {
+  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-yellow,
+.progress-bar-warning {
+  background-color: #f39c12;
+}
+.progress-striped .progress-bar-yellow,
+.progress-striped .progress-bar-warning {
+  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-red,
+.progress-bar-danger {
+  background-color: #f56954;
+}
+.progress-striped .progress-bar-red,
+.progress-striped .progress-bar-danger {
+  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+/*
+    Component: Small boxes
+*/
+.small-box {
+  position: relative;
+  display: block;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  margin-bottom: 15px;
+}
+.small-box > .inner {
+  padding: 10px;
+}
+.small-box > .small-box-footer {
+  position: relative;
+  text-align: center;
+  padding: 3px 0;
+  color: #fff;
+  color: rgba(255, 255, 255, 0.8);
+  display: block;
+  z-index: 10;
+  background: rgba(0, 0, 0, 0.1);
+  text-decoration: none;
+}
+.small-box > .small-box-footer:hover {
+  color: #fff;
+  background: rgba(0, 0, 0, 0.15);
+}
+.small-box h3 {
+  font-size: 38px;
+  font-weight: bold;
+  margin: 0 0 10px 0;
+  white-space: nowrap;
+  padding: 0;
+}
+.small-box p {
+  font-size: 15px;
+}
+.small-box p > small {
+  display: block;
+  color: #f9f9f9;
+  font-size: 13px;
+  margin-top: 5px;
+}
+.small-box h3,
+.small-box p {
+  z-index: 5px;
+}
+.small-box .icon {
+  position: absolute;
+  top: auto;
+  bottom: 5px;
+  right: 5px;
+  z-index: 0;
+  font-size: 90px;
+  color: rgba(0, 0, 0, 0.15);
+}
+.small-box:hover {
+  text-decoration: none;
+  color: #f9f9f9;
+}
+.small-box:hover .icon {
+  animation-name: tansformAnimation;
+  animation-duration: .5s;
+  animation-iteration-count: 1;
+  animation-timing-function: ease;
+  animation-fill-mode: forwards;
+  -webkit-animation-name: tansformAnimation;
+  -webkit-animation-duration: .5s;
+  -webkit-animation-iteration-count: 1;
+  -webkit-animation-timing-function: ease;
+  -webkit-animation-fill-mode: forwards;
+  -moz-animation-name: tansformAnimation;
+  -moz-animation-duration: .5s;
+  -moz-animation-iteration-count: 1;
+  -moz-animation-timing-function: ease;
+  -moz-animation-fill-mode: forwards;
+}
+@keyframes tansformAnimation {
+  from {
+    font-size: 90px;
+  }
+  to {
+    font-size: 100px;
+  }
+}
+@-webkit-keyframes tansformAnimation {
+  from {
+    font-size: 90px;
+  }
+  to {
+    font-size: 100px;
+  }
+}
+@media screen and (max-width: 480px) {
+  .small-box {
+    text-align: center;
+  }
+  .small-box .icon {
+    display: none;
+  }
+  .small-box p {
+    font-size: 12px;
+  }
+}
+/*
+    component: Boxes
+-------------------------
+*/
+.box {
+  position: relative;
+  background: #ffffff;
+  border-top: 2px solid #c1c1c1;
+  margin-bottom: 20px;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  width: 100%;
+  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
+}
+.box.box-primary {
+  border-top-color: #3c8dbc;
+}
+.box.box-info {
+  border-top-color: #00c0ef;
+}
+.box.box-danger {
+  border-top-color: #f56954;
+}
+.box.box-warning {
+  border-top-color: #f39c12;
+}
+.box.box-success {
+  border-top-color: #00a65a;
+}
+.box.height-control .box-body {
+  max-height: 300px;
+  overflow: auto;
+}
+.box .box-header {
+  position: relative;
+  -webkit-border-top-left-radius: 3px;
+  -webkit-border-top-right-radius: 3px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -moz-border-radius-topleft: 3px;
+  -moz-border-radius-topright: 3px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-bottom: 0px solid #f4f4f4;
+  color: #444;
+}
+.box .box-header:before,
+.box .box-header:after {
+  display: table;
+  content: " ";
+}
+.box .box-header:after {
+  clear: both;
+}
+.box .box-header > .fa,
+.box .box-header > .glyphicon,
+.box .box-header > .ion,
+.box .box-header .box-title {
+  display: inline-block;
+  padding: 10px 10px 10px 10px;
+  margin: 0;
+  font-size: 20px;
+  font-weight: 400;
+  float: left;
+  cursor: default;
+}
+.box .box-header a {
+  color: #444;
+}
+.box .box-header > .box-tools {
+  padding: 5px 10px 5px 5px;
+}
+.box .box-body {
+  padding: 10px;
+  -webkit-border-top-left-radius: 0;
+  -webkit-border-top-right-radius: 0;
+  -webkit-border-bottom-right-radius: 3px;
+  -webkit-border-bottom-left-radius: 3px;
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 3px;
+  -moz-border-radius-bottomleft: 3px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.box .box-body > table,
+.box .box-body > .table {
+  margin-bottom: 0;
+}
+.box .box-body.chart-responsive {
+  width: 100%;
+  overflow: hidden;
+}
+.box .box-body > .chart {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+}
+.box .box-body > .chart svg,
+.box .box-body > .chart canvas {
+  width: 100%!important;
+}
+.box .box-body .fc {
+  margin-top: 5px;
+}
+.box .box-body .fc-header-title h2 {
+  font-size: 15px;
+  line-height: 1.6em;
+  color: #666;
+  margin-left: 10px;
+}
+.box .box-body .fc-header-right {
+  padding-right: 10px;
+}
+.box .box-body .fc-header-left {
+  padding-left: 10px;
+}
+.box .box-body .fc-widget-header {
+  background: #fafafa;
+  box-shadow: inset 0px -3px 1px rgba(0, 0, 0, 0.02);
+}
+.box .box-body .fc-grid {
+  width: 100%;
+  border: 0;
+}
+.box .box-body .fc-widget-header:first-of-type,
+.box .box-body .fc-widget-content:first-of-type {
+  border-left: 0;
+  border-right: 0;
+}
+.box .box-body .fc-widget-header:last-of-type,
+.box .box-body .fc-widget-content:last-of-type {
+  border-right: 0;
+}
+.box .box-body .table {
+  margin-bottom: 0;
+}
+.box .box-body .full-width-chart {
+  margin: -19px;
+}
+.box .box-body.no-padding .full-width-chart {
+  margin: -9px;
+}
+.box .box-footer {
+  border-top: 1px solid #f4f4f4;
+  -webkit-border-top-left-radius: 0;
+  -webkit-border-top-right-radius: 0;
+  -webkit-border-bottom-right-radius: 3px;
+  -webkit-border-bottom-left-radius: 3px;
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 3px;
+  -moz-border-radius-bottomleft: 3px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+  padding: 10px;
+  background-color: #ffffff;
+}
+.box.box-solid {
+  border-top: 0px;
+}
+.box.box-solid > .box-header {
+  padding-bottom: 0px!important;
+}
+.box.box-solid > .box-header .btn.btn-default {
+  background: transparent;
+}
+.box.box-solid.box-primary > .box-header {
+  color: #fff;
+  background: #3c8dbc;
+  background-color: #3c8dbc;
+}
+.box.box-solid.box-primary > .box-header a {
+  color: #444;
+}
+.box.box-solid.box-info > .box-header {
+  color: #fff;
+  background: #00c0ef;
+  background-color: #00c0ef;
+}
+.box.box-solid.box-info > .box-header a {
+  color: #444;
+}
+.box.box-solid.box-danger > .box-header {
+  color: #fff;
+  background: #f56954;
+  background-color: #f56954;
+}
+.box.box-solid.box-danger > .box-header a {
+  color: #444;
+}
+.box.box-solid.box-warning > .box-header {
+  color: #fff;
+  background: #f39c12;
+  background-color: #f39c12;
+}
+.box.box-solid.box-warning > .box-header a {
+  color: #444;
+}
+.box.box-solid.box-success > .box-header {
+  color: #fff;
+  background: #00a65a;
+  background-color: #00a65a;
+}
+.box.box-solid.box-success > .box-header a {
+  color: #444;
+}
+.box.box-solid > .box-header > .box-tools .btn {
+  border: 0;
+  box-shadow: none;
+}
+.box.box-solid.collapsed-box .box-header {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+}
+.box.box-solid[class*='bg'] > .box-header {
+  color: #fff;
+}
+.box .box-group > .box {
+  margin-bottom: 5px;
+}
+.box .knob-label {
+  text-align: center;
+  color: #333;
+  font-weight: 100;
+  font-size: 12px;
+  margin-bottom: 0.3em;
+}
+.box .todo-list {
+  margin: 0;
+  padding: 0px 0px;
+  list-style: none;
+}
+.box .todo-list > li {
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  padding: 10px;
+  background: #f3f4f5;
+  margin-bottom: 2px;
+  border-left: 2px solid #e6e7e8;
+  color: #444;
+}
+.box .todo-list > li:last-of-type {
+  margin-bottom: 0;
+}
+.box .todo-list > li.danger {
+  border-left-color: #f56954;
+}
+.box .todo-list > li.warning {
+  border-left-color: #f39c12;
+}
+.box .todo-list > li.info {
+  border-left-color: #00c0ef;
+}
+.box .todo-list > li.success {
+  border-left-color: #00a65a;
+}
+.box .todo-list > li.primary {
+  border-left-color: #3c8dbc;
+}
+.box .todo-list > li > input[type='checkbox'] {
+  margin: 0 10px 0 5px;
+}
+.box .todo-list > li .text {
+  display: inline-block;
+  margin-left: 5px;
+  font-weight: 600;
+}
+.box .todo-list > li .label {
+  margin-left: 10px;
+  font-size: 9px;
+}
+.box .todo-list > li .tools {
+  display: none;
+  float: right;
+  color: #f56954;
+}
+.box .todo-list > li .tools > .fa,
+.box .todo-list > li .tools > .glyphicon,
+.box .todo-list > li .tools > .ion {
+  margin-right: 5px;
+  cursor: pointer;
+}
+.box .todo-list > li:hover .tools {
+  display: inline-block;
+}
+.box .todo-list > li.done {
+  color: #999;
+}
+.box .todo-list > li.done .text {
+  text-decoration: line-through;
+  font-weight: 500;
+}
+.box .todo-list > li.done .label {
+  background: #eaeaec !important;
+}
+.box .todo-list .handle {
+  display: inline-block;
+  cursor: move;
+  margin: 0 5px;
+}
+.box .chat {
+  padding: 5px 20px 5px 10px;
+}
+.box .chat .item {
+  margin-bottom: 10px;
+}
+.box .chat .item:before,
+.box .chat .item:after {
+  display: table;
+  content: " ";
+}
+.box .chat .item:after {
+  clear: both;
+}
+.box .chat .item > img {
+  width: 40px;
+  height: 40px;
+  border: 2px solid transparent;
+  -webkit-border-radius: 50% !important;
+  -moz-border-radius: 50% !important;
+  border-radius: 50% !important;
+}
+.box .chat .item > img.online {
+  border: 2px solid #00a65a;
+}
+.box .chat .item > img.offline {
+  border: 2px solid #f56954;
+}
+.box .chat .item > .message {
+  margin-left: 55px;
+  margin-top: -40px;
+}
+.box .chat .item > .message > .name {
+  display: block;
+  font-weight: 600;
+}
+.box .chat .item > .attachment {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  background: #f0f0f0;
+  margin-left: 65px;
+  margin-right: 15px;
+  padding: 10px;
+}
+.box .chat .item > .attachment > h4 {
+  margin: 0 0 5px 0;
+  font-weight: 600;
+  font-size: 14px;
+}
+.box .chat .item > .attachment > p,
+.box .chat .item > .attachment > .filename {
+  font-weight: 600;
+  font-size: 13px;
+  font-style: italic;
+  margin: 0;
+}
+.box .chat .item > .attachment:before,
+.box .chat .item > .attachment:after {
+  display: table;
+  content: " ";
+}
+.box .chat .item > .attachment:after {
+  clear: both;
+}
+.box > .overlay,
+.box > .loading-img {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.box > .overlay {
+  z-index: 1010;
+  background: rgba(255, 255, 255, 0.7);
+}
+.box > .overlay.dark {
+  background: rgba(0, 0, 0, 0.5);
+}
+.box > .loading-img {
+  z-index: 1020;
+  background: transparent url('../img/ajax-loader1.gif') 50% 50% no-repeat;
+}
+/*
+Component: timeline
+--------------------
+*/
+.timeline {
+  position: relative;
+  margin: 0 0 30px 0;
+  padding: 0;
+  list-style: none;
+}
+.timeline:before {
+  content: '';
+  position: absolute;
+  top: 0px;
+  bottom: 0;
+  width: 5px;
+  background: #ddd;
+  left: 30px;
+  border: 1px solid #eee;
+  margin: 0;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+}
+.timeline > li {
+  position: relative;
+  margin-right: 10px;
+  margin-bottom: 15px;
+}
+.timeline > li:before,
+.timeline > li:after {
+  display: table;
+  content: " ";
+}
+.timeline > li:after {
+  clear: both;
+}
+.timeline > li > .timeline-item {
+  margin-top: 10px;
+  border: 0px solid #dfdfdf;
+  background: #fff;
+  color: #555;
+  margin-left: 60px;
+  margin-right: 15px;
+  padding: 5px;
+  position: relative;
+  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
+}
+.timeline > li > .timeline-item > .time {
+  color: #999;
+  float: right;
+  margin: 2px 0 0 0;
+}
+.timeline > li > .timeline-item > .timeline-header {
+  margin: 0;
+  color: #555;
+  border-bottom: 1px solid #f4f4f4;
+  padding: 5px;
+  font-size: 16px;
+  line-height: 1.1;
+}
+.timeline > li > .timeline-item > .timeline-header > a {
+  font-weight: 600;
+}
+.timeline > li > .timeline-item > .timeline-body,
+.timeline > li > .timeline-item > .timeline-footer {
+  padding: 10px;
+}
+.timeline > li.time-label > span {
+  font-weight: 600;
+  padding: 5px;
+  display: inline-block;
+  background-color: #fff;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.timeline > li > .fa,
+.timeline > li > .glyphicon,
+.timeline > li > .ion {
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+  width: 30px;
+  height: 30px;
+  font-size: 15px;
+  line-height: 30px;
+  position: absolute;
+  color: #666;
+  background: #eee;
+  border-radius: 50%;
+  text-align: center;
+  left: 18px;
+  top: 0;
+}
+
+/* 
+    Component: callout
+------------------------
+*/
+.callout {
+  margin: 0 0 20px 0;
+  padding: 15px 30px 15px 15px;
+  border-left: 5px solid #eee;
+}
+.callout h4 {
+  margin-top: 0;
+}
+.callout p:last-child {
+  margin-bottom: 0;
+}
+.callout code,
+.callout .highlight {
+  background-color: #fff;
+}
+.callout.callout-danger {
+  background-color: #fcf2f2;
+  border-color: #dFb5b4;
+}
+.callout.callout-warning {
+  background-color: #fefbed;
+  border-color: #f1e7bc;
+}
+.callout.callout-info {
+  background-color: #f0f7fd;
+  border-color: #d0e3f0;
+}
+.callout.callout-danger h4 {
+  color: #B94A48;
+}
+.callout.callout-warning h4 {
+  color: #C09853;
+}
+.callout.callout-info h4 {
+  color: #3A87AD;
+}
+/* 
+    Component: alert
+------------------------
+*/
+.alert {
+  padding-left: 30px;
+  margin-left: 15px;
+  position: relative;
+}
+.alert > .fa,
+.alert > .glyphicon {
+  position: absolute;
+  left: -15px;
+  top: -15px;
+  width: 35px;
+  height: 35px;
+  -webkit-border-radius: 50%;
+  -moz-border-radius: 50%;
+  border-radius: 50%;
+  line-height: 35px;
+  text-align: center;
+  background: inherit;
+  border: inherit;
+}
+/*
+    Component: Navs
+*/
+/* NAV PILLS */
+.nav.nav-pills > li > a {
+  border-top: 3px solid transparent;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  color: #444;
+}
+.nav.nav-pills > li > a > .fa,
+.nav.nav-pills > li > a > .glyphicon,
+.nav.nav-pills > li > a > .ion {
+  margin-right: 5px;
+}
+.nav.nav-pills > li.active > a,
+.nav.nav-pills > li.active > a:hover {
+  background-color: #f6f6f6;
+  border-top-color: #3c8dbc;
+  color: #444;
+}
+.nav.nav-pills > li.active > a {
+  font-weight: 600;
+}
+.nav.nav-pills > li > a:hover {
+  background-color: #f6f6f6;
+}
+.nav.nav-pills.nav-stacked > li > a {
+  border-top: 0;
+  border-left: 3px solid transparent;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  color: #444;
+}
+.nav.nav-pills.nav-stacked > li.active > a,
+.nav.nav-pills.nav-stacked > li.active > a:hover {
+  background-color: #f6f6f6;
+  border-left-color: #3c8dbc;
+  color: #444;
+}
+.nav.nav-pills.nav-stacked > li.header {
+  border-bottom: 1px solid #ddd;
+  color: #777;
+  margin-bottom: 10px;
+  padding: 5px 10px;
+  text-transform: uppercase;
+}
+/* NAV TABS */
+.nav-tabs-custom {
+  margin-bottom: 20px;
+  background: #fff;
+  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
+}
+.nav-tabs-custom > .nav-tabs {
+  margin: 0;
+  border-bottom-color: #f4f4f4;
+}
+.nav-tabs-custom > .nav-tabs > li {
+  border-top: 3px solid transparent;
+  margin-bottom: -2px;
+  margin-right: 5px;
+}
+.nav-tabs-custom > .nav-tabs > li > a {
+  -webkit-border-radius: 0 !important;
+  -moz-border-radius: 0 !important;
+  border-radius: 0 !important;
+}
+.nav-tabs-custom > .nav-tabs > li > a,
+.nav-tabs-custom > .nav-tabs > li > a:hover {
+  background: transparent;
+  margin: 0;
+}
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover,
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus,
+.nav-tabs-custom > .nav-tabs > li:not(.active) > a:active {
+  border-color: transparent;
+}
+.nav-tabs-custom > .nav-tabs > li.active {
+  border-top-color: #3c8dbc;
+}
+.nav-tabs-custom > .nav-tabs > li.active > a,
+.nav-tabs-custom > .nav-tabs > li.active:hover > a {
+  background-color: #fff;
+}
+.nav-tabs-custom > .nav-tabs > li.active > a {
+  border-top: 0;
+  border-left-color: #f4f4f4;
+  border-right-color: #f4f4f4;
+}
+.nav-tabs-custom > .nav-tabs > li:first-of-type {
+  margin-left: 0px;
+}
+.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {
+  border-left-width: 0;
+}
+.nav-tabs-custom > .nav-tabs.pull-right {
+  float: none!important;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li {
+  float: right;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type {
+  margin-right: 0px;
+}
+.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
+  border-left-width: 1px;
+  border-right-width: 0px;
+}
+.nav-tabs-custom > .nav-tabs > li.header {
+  font-weight: 400;
+  line-height: 35px;
+  padding: 0 10px;
+  font-size: 20px;
+  color: #444;
+  cursor: default;
+}
+.nav-tabs-custom > .nav-tabs > li.header > .fa,
+.nav-tabs-custom > .nav-tabs > li.header > .glyphicon,
+.nav-tabs-custom > .nav-tabs > li.header > .ion {
+  margin-right: 10px;
+}
+.nav-tabs-custom > .tab-content {
+  background: #fff;
+  padding: 10px;
+}
+/* Nav tabs bottom */
+.tabs-bottom.nav-3 li a {
+  width: 3333.33333333% !important;
+}
+.tabs-bottom li a {
+  border: 0;
+}
+/* PAGINATION */
+.pagination > li > a {
+  background: #fafafa;
+  color: #666;
+  -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09);
+  -moz-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.09);
+  box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.09);
+}
+.pagination > li:first-of-type a,
+.pagination > li:last-of-type a {
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+}
+/*
+    Component: Mailbox
+*/
+.mailbox .table-mailbox {
+  border-left: 1px solid #ddd;
+  border-right: 1px solid #ddd;
+  border-bottom: 1px solid #ddd;
+}
+.mailbox .table-mailbox tr.unread > td {
+  background-color: rgba(0, 0, 0, 0.05);
+  color: #000;
+  font-weight: 600;
+}
+.mailbox .table-mailbox tr > td > .fa.fa-star,
+.mailbox .table-mailbox tr > td > .fa.fa-star-o,
+.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star,
+.mailbox .table-mailbox tr > td > .glyphicon.glyphicon-star-empty {
+  color: #f39c12;
+  cursor: pointer;
+}
+.mailbox .table-mailbox tr > td.small-col {
+  width: 30px;
+}
+.mailbox .table-mailbox tr > td.name {
+  width: 150px;
+  font-weight: 600;
+}
+.mailbox .table-mailbox tr > td.time {
+  text-align: right;
+  width: 100px;
+}
+.mailbox .table-mailbox tr > td {
+  white-space: nowrap;
+}
+.mailbox .table-mailbox tr > td > a {
+  color: #444;
+}
+@media screen and (max-width: 767px) {
+  .mailbox .nav-stacked > li:not(.header) {
+    float: left;
+    width: 50%;
+  }
+  .mailbox .nav-stacked > li:not(.header).header {
+    border: 0!important;
+  }
+  .mailbox .search-form {
+    margin-top: 10px;
+  }
+}
+/*
+    Page: locked screen
+*/
+/* ADD THIS CLASS TO THE <HTML> TAG */
+.lockscreen {
+  background: url(../img/blur-background09.jpg) repeat center center fixed;
+  -webkit-background-size: cover;
+  -moz-background-size: cover;
+  -o-background-size: cover;
+  background-size: cover;
+}
+/* Remove the background from the body element */
+.lockscreen > body {
+  background: transparent;
+}
+/* We will put the dynamically generated digital clock here */
+.lockscreen .headline {
+  color: #fff;
+  text-shadow: 1px 3px 5px rgba(0, 0, 0, 0.5);
+  font-weight: 300;
+  -webkit-font-smoothing: antialiased !important;
+  opacity: 0.8;
+  margin: 10px 0 30px 0;
+  font-size: 90px;
+}
+@media screen and (max-width: 480px) {
+  .lockscreen .headline {
+    font-size: 60px;
+    margin-bottom: 40px;
+  }
+}
+/* User name [optional] */
+.lockscreen .lockscreen-name {
+  text-align: center;
+  font-weight: 600;
+  font-size: 16px;
+}
+/* Will contain the image and the sign in form */
+.lockscreen-item {
+  padding: 0;
+  background: #fff;
+  position: relative;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+  margin: 10px auto;
+  width: 290px;
+}
+.lockscreen-item:before,
+.lockscreen-item:after {
+  display: table;
+  content: " ";
+}
+.lockscreen-item:after {
+  clear: both;
+}
+/* User image */
+.lockscreen-item > .lockscreen-image {
+  position: absolute;
+  left: -10px;
+  top: -30px;
+  background: #fff;
+  padding: 10px;
+  -webkit-border-radius: 50%;
+  -moz-border-radius: 50%;
+  border-radius: 50%;
+  z-index: 10;
+}
+.lockscreen-item > .lockscreen-image > img {
+  width: 70px;
+  height: 70px;
+  -webkit-border-radius: 50%;
+  -moz-border-radius: 50%;
+  border-radius: 50%;
+}
+/* Contains the password input and the login button */
+.lockscreen-item > .lockscreen-credentials {
+  margin-left: 80px;
+}
+.lockscreen-item > .lockscreen-credentials input {
+  border: 0 !important;
+}
+.lockscreen-item > .lockscreen-credentials .btn {
+  background-color: #fff;
+  border: 0;
+}
+/* Extra to give the user an option to navigate the website [optional]*/
+.lockscreen-link {
+  margin-top: 30px;
+  text-align: center;
+}
+/* 
+    Page: register and login
+*/
+.form-box {
+  width: 360px;
+  margin: 90px auto 0 auto;
+}
+.form-box .header {
+  -webkit-border-top-left-radius: 4px;
+  -webkit-border-top-right-radius: 4px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  background: #3d9970;
+  box-shadow: inset 0px -3px 0px rgba(0, 0, 0, 0.2);
+  padding: 20px 10px;
+  text-align: center;
+  font-size: 26px;
+  font-weight: 300;
+  color: #fff;
+}
+.form-box .body,
+.form-box .footer {
+  padding: 10px 20px;
+  background: #fff;
+  color: #444;
+}
+.form-box .body > .form-group,
+.form-box .footer > .form-group {
+  margin-top: 20px;
+}
+.form-box .body > .form-group > input,
+.form-box .footer > .form-group > input {
+  border: #fff;
+}
+.form-box .body > .btn,
+.form-box .footer > .btn {
+  margin-bottom: 10px;
+}
+.form-box .footer {
+  -webkit-border-top-left-radius: 0;
+  -webkit-border-top-right-radius: 0;
+  -webkit-border-bottom-right-radius: 4px;
+  -webkit-border-bottom-left-radius: 4px;
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 4px;
+  -moz-border-radius-bottomleft: 4px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+@media (max-width: 767px) {
+  .form-box {
+    width: 90%;
+  }
+}
+/* 
+    Page: 404 and 500 error pages
+------------------------------------
+*/
+.error-page {
+  width: 600px;
+  margin: 20px auto 0 auto;
+}
+@media screen and (max-width: 767px) {
+  .error-page {
+    width: 100%;
+  }
+}
+.error-page > .headline {
+  float: left;
+  font-size: 100px;
+  font-weight: 300;
+}
+@media screen and (max-width: 767px) {
+  .error-page > .headline {
+    float: none;
+    text-align: center;
+  }
+}
+.error-page > .error-content {
+  margin-left: 190px;
+  display: block;
+}
+@media screen and (max-width: 767px) {
+  .error-page > .error-content {
+    margin-left: 0;
+  }
+}
+.error-page > .error-content > h3 {
+  font-weight: 300;
+  font-size: 25px;
+}
+@media screen and (max-width: 767px) {
+  .error-page > .error-content > h3 {
+    text-align: center;
+  }
+}
+.error-page:before,
+.error-page:after {
+  display: table;
+  content: " ";
+}
+.error-page:after {
+  clear: both;
+}
+/* 
+    Page: Invoice
+*/
+.invoice {
+  position: relative;
+  width: 90%;
+  margin: 10px auto;
+  background: #fff;
+  border: 1px solid #f4f4f4;
+}
+.invoice-title {
+  margin-top: 0;
+}
+/* Enhancement for printing */
+@media print {
+  .invoice {
+    width: 100%;
+    border: 0;
+    margin: 0;
+    padding: 0;
+  }
+  .invoice-col {
+    float: left;
+    width: 33.3333333%;
+  }
+  .table-responsive {
+    overflow: auto;
+  }
+  .table-responsive > .table tr th,
+  .table-responsive > .table tr td {
+    white-space: normal!important;
+  }
+}
+/* 
+    Skins
+    -----
+*/
+/* 
+    Skin Blue 
+    ---------
+*/
+/* skin-blue navbar */
+.skin-blue .navbar {
+  background-color: #3c8dbc;
+}
+.skin-blue .navbar .nav a {
+  color: rgba(255, 255, 255, 0.8);
+}
+.skin-blue .navbar .nav > li > a:hover,
+.skin-blue .navbar .nav > li > a:active,
+.skin-blue .navbar .nav > li > a:focus,
+.skin-blue .navbar .nav .open > a,
+.skin-blue .navbar .nav .open > a:hover,
+.skin-blue .navbar .nav .open > a:focus {
+  background: rgba(0, 0, 0, 0.1);
+  color: #f6f6f6;
+}
+.skin-blue .navbar .navbar-right > .nav {
+  margin-right: 10px;
+}
+.skin-blue .navbar .sidebar-toggle .icon-bar {
+  background: rgba(255, 255, 255, 0.8);
+}
+.skin-blue .navbar .sidebar-toggle:hover .icon-bar {
+  background: #f6f6f6 !important;
+}
+/* skin-blue logo */
+.skin-blue .logo {
+  background-color: #367fa9;
+  color: #f9f9f9;
+}
+.skin-blue .logo > a {
+  color: #f9f9f9;
+}
+.skin-blue .logo:hover {
+  background: #357ca5;
+}
+/* skin-blue content header */
+.skin-blue .right-side > .content-header {
+  background: #fbfbfb;
+  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
+}
+/* Skin-blue user panel */
+.skin-blue .user-panel > .image > img {
+  border: 1px solid #dfdfdf;
+}
+.skin-blue .user-panel > .info,
+.skin-blue .user-panel > .info > a {
+  color: #555555;
+}
+/* skin-blue sidebar */
+.skin-blue .sidebar {
+  border-bottom: 1px solid #fff;
+}
+.skin-blue .sidebar > .sidebar-menu > li {
+  border-top: 1px solid #fff;
+  border-bottom: 1px solid #dbdbdb;
+}
+.skin-blue .sidebar > .sidebar-menu > li:first-of-type {
+  border-top: 1px solid #dbdbdb;
+}
+.skin-blue .sidebar > .sidebar-menu > li:first-of-type > a {
+  border-top: 1px solid #fff;
+}
+.skin-blue .sidebar > .sidebar-menu > li > a {
+  margin-right: 1px;
+}
+.skin-blue .sidebar > .sidebar-menu > li > a:hover,
+.skin-blue .sidebar > .sidebar-menu > li.active > a {
+  color: #222;
+  background: #f9f9f9;
+}
+.skin-blue .sidebar > .sidebar-menu > li > .treeview-menu {
+  margin: 0 1px;
+  background: #f9f9f9;
+}
+.skin-blue .left-side {
+  background: #f4f4f4;
+  -webkit-box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.1);
+  box-shadow: inset -3px 0px 8px -4px rgba(0, 0, 0, 0.07);
+}
+.skin-blue .sidebar a {
+  color: #555555;
+}
+.skin-blue .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-blue .treeview-menu > li > a {
+  color: #777;
+}
+.skin-blue .treeview-menu > li.active > a,
+.skin-blue .treeview-menu > li > a:hover {
+  color: #111;
+}
+.skin-blue .sidebar-form {
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  border: 1px solid #dbdbdb;
+  margin: 10px 10px;
+}
+.skin-blue .sidebar-form input[type="text"],
+.skin-blue .sidebar-form .btn {
+  box-shadow: none;
+  background-color: #fafafa;
+  border: 1px solid #fafafa;
+  height: 35px;
+}
+.skin-blue .sidebar-form input[type="text"] {
+  color: #666;
+  -webkit-border-top-left-radius: 2px !important;
+  -webkit-border-top-right-radius: 0 !important;
+  -webkit-border-bottom-right-radius: 0 !important;
+  -webkit-border-bottom-left-radius: 2px !important;
+  -moz-border-radius-topleft: 2px !important;
+  -moz-border-radius-topright: 0 !important;
+  -moz-border-radius-bottomright: 0 !important;
+  -moz-border-radius-bottomleft: 2px !important;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-blue .sidebar-form input[type="text"]:focus,
+.skin-blue .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #fff;
+  color: #666;
+}
+.skin-blue .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left-color: #fff;
+}
+.skin-blue .sidebar-form .btn {
+  color: #999;
+  -webkit-border-top-left-radius: 0 !important;
+  -webkit-border-top-right-radius: 2px !important;
+  -webkit-border-bottom-right-radius: 2px !important;
+  -webkit-border-bottom-left-radius: 0 !important;
+  -moz-border-radius-topleft: 0 !important;
+  -moz-border-radius-topright: 2px !important;
+  -moz-border-radius-bottomright: 2px !important;
+  -moz-border-radius-bottomleft: 0 !important;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+}
+/*
+    Skin Black
+    --------
+*/
+/* skin-black navbar */
+.skin-black .navbar {
+  background-color: #ffffff;
+  border-bottom: 1px solid #eee;
+}
+.skin-black .navbar .nav a {
+  color: #333333;
+}
+.skin-black .navbar .nav > li > a:hover,
+.skin-black .navbar .nav > li > a:active,
+.skin-black .navbar .nav > li > a:focus,
+.skin-black .navbar .nav .open > a,
+.skin-black .navbar .nav .open > a:hover,
+.skin-black .navbar .nav .open > a:focus {
+  background: #ffffff;
+  color: #999999;
+}
+.skin-black .navbar .navbar-right > .nav {
+  margin-right: 10px;
+}
+.skin-black .navbar .sidebar-toggle .icon-bar {
+  background: #333333;
+}
+.skin-black .navbar .sidebar-toggle:hover .icon-bar {
+  background: #999999 !important;
+}
+/* skin-black logo */
+.skin-black .logo {
+  background-color: #333333;
+  color: #f9f9f9;
+}
+.skin-black .logo > a {
+  color: #f9f9f9;
+}
+.skin-black .logo:hover {
+  background: #303030;
+}
+/* skin-black content header */
+.skin-black .right-side > .content-header {
+  background: transparent;
+  box-shadow: none;
+}
+/* Skin-red user panel */
+.skin-black .user-panel > .image > img {
+  border: 1px solid #444;
+}
+.skin-black .user-panel > .info,
+.skin-black .user-panel > .info > a {
+  color: #eee;
+}
+/* skin-black sidebar */
+.skin-black .sidebar {
+  border-bottom: 1px solid #333;
+}
+.skin-black .sidebar > .sidebar-menu > li {
+  border-top: 1px solid #333;
+  border-bottom: 0px solid #444;
+}
+.skin-black .sidebar > .sidebar-menu > li:first-of-type {
+  border-top: 1px solid #444;
+}
+.skin-black .sidebar > .sidebar-menu > li:first-of-type > a {
+  border-top: 0px solid #333;
+}
+.skin-black .sidebar > .sidebar-menu > li > a {
+  margin-right: 1px;
+}
+.skin-black .sidebar > .sidebar-menu > li > a:hover,
+.skin-black .sidebar > .sidebar-menu > li.active > a {
+  color: #f6f6f6;
+  background: #444;
+}
+.skin-black .sidebar > .sidebar-menu > li > .treeview-menu {
+  margin: 0 1px;
+  background: #444;
+}
+.skin-black .left-side {
+  background: #333;
+}
+.skin-black .sidebar a {
+  color: #eee;
+}
+.skin-black .sidebar a:hover {
+  text-decoration: none;
+}
+.skin-black .treeview-menu > li > a {
+  color: #ccc;
+}
+.skin-black .treeview-menu > li.active > a,
+.skin-black .treeview-menu > li > a:hover {
+  color: #fff;
+}
+.skin-black .sidebar-form {
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  border: 0px solid #555;
+  margin: 10px 10px;
+}
+.skin-black .sidebar-form input[type="text"],
+.skin-black .sidebar-form .btn {
+  box-shadow: none;
+  background-color: rgba(255, 255, 255, 0.1);
+  border: 0 solid rgba(255, 255, 255, 0.1);
+  height: 35px;
+  outline: none;
+}
+.skin-black .sidebar-form input[type="text"] {
+  color: #666;
+  -webkit-border-top-left-radius: 2px !important;
+  -webkit-border-top-right-radius: 0 !important;
+  -webkit-border-bottom-right-radius: 0 !important;
+  -webkit-border-bottom-left-radius: 2px !important;
+  -moz-border-radius-topleft: 2px !important;
+  -moz-border-radius-topright: 0 !important;
+  -moz-border-radius-bottomright: 0 !important;
+  -moz-border-radius-bottomleft: 2px !important;
+  border-top-left-radius: 2px !important;
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 2px !important;
+}
+.skin-black .sidebar-form input[type="text"]:focus,
+.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  background-color: #444;
+  border: 0;
+}
+.skin-black .sidebar-form input[type="text"]:focus + .input-group-btn .btn {
+  border-left: 0;
+}
+.skin-black .sidebar-form .btn {
+  color: #999;
+  -webkit-border-top-left-radius: 0 !important;
+  -webkit-border-top-right-radius: 2px !important;
+  -webkit-border-bottom-right-radius: 2px !important;
+  -webkit-border-bottom-left-radius: 0 !important;
+  -moz-border-radius-topleft: 0 !important;
+  -moz-border-radius-topright: 2px !important;
+  -moz-border-radius-bottomright: 2px !important;
+  -moz-border-radius-bottomleft: 0 !important;
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 2px !important;
+  border-bottom-right-radius: 2px !important;
+  border-bottom-left-radius: 0 !important;
+  border-left: 0;
+}
+/*!
+ * iCheck v1.0.1, http://git.io/arlzeA
+ * =================================
+ * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
+ *
+ * (c) 2013 Damir Sultanov, http://fronteed.com
+ * MIT Licensed
+ */
+/* iCheck plugin Minimal skin, black
+----------------------------------- */
+.icheckbox_minimal,
+.iradio_minimal {
+  display: inline-block;
+  *display: inline;
+  vertical-align: middle;
+  margin: 0;
+  padding: 0;
+  width: 18px;
+  height: 18px;
+  background: rgba(255, 255, 255, 0.7) url(iCheck/minimal/minimal.png) no-repeat;
+  border: none;
+  cursor: pointer;
+}
+.icheckbox_minimal {
+  background-position: 0 0;
+}
+.icheckbox_minimal.hover {
+  background-position: -20px 0;
+}
+.icheckbox_minimal.checked {
+  background-position: -40px 0;
+}
+.icheckbox_minimal.disabled {
+  background-position: -60px 0;
+  cursor: default;
+}
+.icheckbox_minimal.checked.disabled {
+  background-position: -80px 0;
+}
+.iradio_minimal {
+  background-position: -100px 0;
+}
+.iradio_minimal.hover {
+  background-position: -120px 0;
+}
+.iradio_minimal.checked {
+  background-position: -140px 0;
+}
+.iradio_minimal.disabled {
+  background-position: -160px 0;
+  cursor: default;
+}
+.iradio_minimal.checked.disabled {
+  background-position: -180px 0;
+}
+/* Retina support */
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5) {
+  .icheckbox_minimal,
+  .iradio_minimal {
+    background-image: url('iCheck/minimal/minimal@2x.png');
+    -webkit-background-size: 200px 20px;
+    background-size: 200px 20px;
+  }
+}
+.pace .pace-progress {
+  background: #00c0ef;
+  position: fixed;
+  z-index: 2000;
+  top: 0;
+  left: 0;
+  height: 2px;
+  -webkit-transition: width 1s;
+  -moz-transition: width 1s;
+  -o-transition: width 1s;
+  transition: width 1s;
+}
+.pace-inactive {
+  display: none;
+}
+/*
+ * Social Buttons for Bootstrap
+ *
+ * Copyright 2013-2014 Panayiotis Lipiridis
+ * Licensed under the MIT License
+ *
+ * https://github.com/lipis/bootstrap-social
+ *
+ * Note: this file has been altered to work correctly with AdminLTE
+ */
+.btn-social {
+  position: relative;
+  padding-left: 44px !important;
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.btn-social :first-child {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  width: 32px !important;
+  line-height: 34px !important;
+  font-size: 1.6em!important;
+  text-align: center;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+}
+.btn-social.btn-lg {
+  padding-left: 60px !important;
+}
+.btn-social.btn-lg :first-child {
+  line-height: 45px;
+  width: 45px;
+  font-size: 1.8em;
+}
+.btn-social.btn-sm {
+  padding-left: 38px !important;
+}
+.btn-social.btn-sm :first-child {
+  line-height: 28px;
+  width: 28px;
+  font-size: 1.4em;
+}
+.btn-social.btn-xs {
+  padding-left: 30px !important;
+}
+.btn-social.btn-xs :first-child {
+  line-height: 20px;
+  width: 20px;
+  font-size: 1.2em;
+}
+.btn-social-icon {
+  position: relative;
+  padding-left: 44px !important;
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  height: 34px;
+  width: 34px;
+  padding: 0;
+}
+.btn-social-icon :first-child {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  width: 32px !important;
+  line-height: 34px !important;
+  font-size: 1.6em!important;
+  text-align: center;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+}
+.btn-social-icon.btn-lg {
+  padding-left: 60px !important;
+}
+.btn-social-icon.btn-lg :first-child {
+  line-height: 45px;
+  width: 45px;
+  font-size: 1.8em;
+}
+.btn-social-icon.btn-sm {
+  padding-left: 38px !important;
+}
+.btn-social-icon.btn-sm :first-child {
+  line-height: 28px;
+  width: 28px;
+  font-size: 1.4em;
+}
+.btn-social-icon.btn-xs {
+  padding-left: 30px !important;
+}
+.btn-social-icon.btn-xs :first-child {
+  line-height: 20px;
+  width: 20px;
+  font-size: 1.2em;
+}
+.btn-social-icon :first-child {
+  border: none;
+  text-align: center;
+  width: 100%!important;
+}
+.btn-social-icon.btn-lg {
+  height: 45px;
+  width: 45px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-social-icon.btn-sm {
+  height: 30px;
+  width: 30px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-social-icon.btn-xs {
+  height: 22px;
+  width: 22px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.btn-bitbucket {
+  color: #ffffff;
+  background-color: #205081;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket:hover,
+.btn-bitbucket:focus,
+.btn-bitbucket:active,
+.btn-bitbucket.active,
+.open .dropdown-toggle.btn-bitbucket {
+  color: #ffffff;
+  background-color: #183c60;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket:active,
+.btn-bitbucket.active,
+.open .dropdown-toggle.btn-bitbucket {
+  background-image: none;
+}
+.btn-bitbucket.disabled,
+.btn-bitbucket[disabled],
+fieldset[disabled] .btn-bitbucket,
+.btn-bitbucket.disabled:hover,
+.btn-bitbucket[disabled]:hover,
+fieldset[disabled] .btn-bitbucket:hover,
+.btn-bitbucket.disabled:focus,
+.btn-bitbucket[disabled]:focus,
+fieldset[disabled] .btn-bitbucket:focus,
+.btn-bitbucket.disabled:active,
+.btn-bitbucket[disabled]:active,
+fieldset[disabled] .btn-bitbucket:active,
+.btn-bitbucket.disabled.active,
+.btn-bitbucket[disabled].active,
+fieldset[disabled] .btn-bitbucket.active {
+  background-color: #205081;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-bitbucket .badge {
+  color: #205081;
+  background-color: #ffffff;
+}
+.btn-dropbox {
+  color: #ffffff;
+  background-color: #1087dd;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox:hover,
+.btn-dropbox:focus,
+.btn-dropbox:active,
+.btn-dropbox.active,
+.open .dropdown-toggle.btn-dropbox {
+  color: #ffffff;
+  background-color: #0d70b7;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox:active,
+.btn-dropbox.active,
+.open .dropdown-toggle.btn-dropbox {
+  background-image: none;
+}
+.btn-dropbox.disabled,
+.btn-dropbox[disabled],
+fieldset[disabled] .btn-dropbox,
+.btn-dropbox.disabled:hover,
+.btn-dropbox[disabled]:hover,
+fieldset[disabled] .btn-dropbox:hover,
+.btn-dropbox.disabled:focus,
+.btn-dropbox[disabled]:focus,
+fieldset[disabled] .btn-dropbox:focus,
+.btn-dropbox.disabled:active,
+.btn-dropbox[disabled]:active,
+fieldset[disabled] .btn-dropbox:active,
+.btn-dropbox.disabled.active,
+.btn-dropbox[disabled].active,
+fieldset[disabled] .btn-dropbox.active {
+  background-color: #1087dd;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-dropbox .badge {
+  color: #1087dd;
+  background-color: #ffffff;
+}
+.btn-facebook {
+  color: #ffffff;
+  background-color: #3b5998;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook:hover,
+.btn-facebook:focus,
+.btn-facebook:active,
+.btn-facebook.active,
+.open .dropdown-toggle.btn-facebook {
+  color: #ffffff;
+  background-color: #30487b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook:active,
+.btn-facebook.active,
+.open .dropdown-toggle.btn-facebook {
+  background-image: none;
+}
+.btn-facebook.disabled,
+.btn-facebook[disabled],
+fieldset[disabled] .btn-facebook,
+.btn-facebook.disabled:hover,
+.btn-facebook[disabled]:hover,
+fieldset[disabled] .btn-facebook:hover,
+.btn-facebook.disabled:focus,
+.btn-facebook[disabled]:focus,
+fieldset[disabled] .btn-facebook:focus,
+.btn-facebook.disabled:active,
+.btn-facebook[disabled]:active,
+fieldset[disabled] .btn-facebook:active,
+.btn-facebook.disabled.active,
+.btn-facebook[disabled].active,
+fieldset[disabled] .btn-facebook.active {
+  background-color: #3b5998;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-facebook .badge {
+  color: #3b5998;
+  background-color: #ffffff;
+}
+.btn-flickr {
+  color: #ffffff;
+  background-color: #ff0084;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr:hover,
+.btn-flickr:focus,
+.btn-flickr:active,
+.btn-flickr.active,
+.open .dropdown-toggle.btn-flickr {
+  color: #ffffff;
+  background-color: #d6006f;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr:active,
+.btn-flickr.active,
+.open .dropdown-toggle.btn-flickr {
+  background-image: none;
+}
+.btn-flickr.disabled,
+.btn-flickr[disabled],
+fieldset[disabled] .btn-flickr,
+.btn-flickr.disabled:hover,
+.btn-flickr[disabled]:hover,
+fieldset[disabled] .btn-flickr:hover,
+.btn-flickr.disabled:focus,
+.btn-flickr[disabled]:focus,
+fieldset[disabled] .btn-flickr:focus,
+.btn-flickr.disabled:active,
+.btn-flickr[disabled]:active,
+fieldset[disabled] .btn-flickr:active,
+.btn-flickr.disabled.active,
+.btn-flickr[disabled].active,
+fieldset[disabled] .btn-flickr.active {
+  background-color: #ff0084;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-flickr .badge {
+  color: #ff0084;
+  background-color: #ffffff;
+}
+.btn-foursquare {
+  color: #ffffff;
+  background-color: #0072b1;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare:hover,
+.btn-foursquare:focus,
+.btn-foursquare:active,
+.btn-foursquare.active,
+.open .dropdown-toggle.btn-foursquare {
+  color: #ffffff;
+  background-color: #005888;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare:active,
+.btn-foursquare.active,
+.open .dropdown-toggle.btn-foursquare {
+  background-image: none;
+}
+.btn-foursquare.disabled,
+.btn-foursquare[disabled],
+fieldset[disabled] .btn-foursquare,
+.btn-foursquare.disabled:hover,
+.btn-foursquare[disabled]:hover,
+fieldset[disabled] .btn-foursquare:hover,
+.btn-foursquare.disabled:focus,
+.btn-foursquare[disabled]:focus,
+fieldset[disabled] .btn-foursquare:focus,
+.btn-foursquare.disabled:active,
+.btn-foursquare[disabled]:active,
+fieldset[disabled] .btn-foursquare:active,
+.btn-foursquare.disabled.active,
+.btn-foursquare[disabled].active,
+fieldset[disabled] .btn-foursquare.active {
+  background-color: #0072b1;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-foursquare .badge {
+  color: #0072b1;
+  background-color: #ffffff;
+}
+.btn-github {
+  color: #ffffff;
+  background-color: #444444;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github:hover,
+.btn-github:focus,
+.btn-github:active,
+.btn-github.active,
+.open .dropdown-toggle.btn-github {
+  color: #ffffff;
+  background-color: #303030;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github:active,
+.btn-github.active,
+.open .dropdown-toggle.btn-github {
+  background-image: none;
+}
+.btn-github.disabled,
+.btn-github[disabled],
+fieldset[disabled] .btn-github,
+.btn-github.disabled:hover,
+.btn-github[disabled]:hover,
+fieldset[disabled] .btn-github:hover,
+.btn-github.disabled:focus,
+.btn-github[disabled]:focus,
+fieldset[disabled] .btn-github:focus,
+.btn-github.disabled:active,
+.btn-github[disabled]:active,
+fieldset[disabled] .btn-github:active,
+.btn-github.disabled.active,
+.btn-github[disabled].active,
+fieldset[disabled] .btn-github.active {
+  background-color: #444444;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-github .badge {
+  color: #444444;
+  background-color: #ffffff;
+}
+.btn-google-plus {
+  color: #ffffff;
+  background-color: #dd4b39;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus:hover,
+.btn-google-plus:focus,
+.btn-google-plus:active,
+.btn-google-plus.active,
+.open .dropdown-toggle.btn-google-plus {
+  color: #ffffff;
+  background-color: #ca3523;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus:active,
+.btn-google-plus.active,
+.open .dropdown-toggle.btn-google-plus {
+  background-image: none;
+}
+.btn-google-plus.disabled,
+.btn-google-plus[disabled],
+fieldset[disabled] .btn-google-plus,
+.btn-google-plus.disabled:hover,
+.btn-google-plus[disabled]:hover,
+fieldset[disabled] .btn-google-plus:hover,
+.btn-google-plus.disabled:focus,
+.btn-google-plus[disabled]:focus,
+fieldset[disabled] .btn-google-plus:focus,
+.btn-google-plus.disabled:active,
+.btn-google-plus[disabled]:active,
+fieldset[disabled] .btn-google-plus:active,
+.btn-google-plus.disabled.active,
+.btn-google-plus[disabled].active,
+fieldset[disabled] .btn-google-plus.active {
+  background-color: #dd4b39;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-google-plus .badge {
+  color: #dd4b39;
+  background-color: #ffffff;
+}
+.btn-instagram {
+  color: #ffffff;
+  background-color: #3f729b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram:hover,
+.btn-instagram:focus,
+.btn-instagram:active,
+.btn-instagram.active,
+.open .dropdown-toggle.btn-instagram {
+  color: #ffffff;
+  background-color: #335d7e;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram:active,
+.btn-instagram.active,
+.open .dropdown-toggle.btn-instagram {
+  background-image: none;
+}
+.btn-instagram.disabled,
+.btn-instagram[disabled],
+fieldset[disabled] .btn-instagram,
+.btn-instagram.disabled:hover,
+.btn-instagram[disabled]:hover,
+fieldset[disabled] .btn-instagram:hover,
+.btn-instagram.disabled:focus,
+.btn-instagram[disabled]:focus,
+fieldset[disabled] .btn-instagram:focus,
+.btn-instagram.disabled:active,
+.btn-instagram[disabled]:active,
+fieldset[disabled] .btn-instagram:active,
+.btn-instagram.disabled.active,
+.btn-instagram[disabled].active,
+fieldset[disabled] .btn-instagram.active {
+  background-color: #3f729b;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-instagram .badge {
+  color: #3f729b;
+  background-color: #ffffff;
+}
+.btn-linkedin {
+  color: #ffffff;
+  background-color: #007bb6;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin:hover,
+.btn-linkedin:focus,
+.btn-linkedin:active,
+.btn-linkedin.active,
+.open .dropdown-toggle.btn-linkedin {
+  color: #ffffff;
+  background-color: #005f8d;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin:active,
+.btn-linkedin.active,
+.open .dropdown-toggle.btn-linkedin {
+  background-image: none;
+}
+.btn-linkedin.disabled,
+.btn-linkedin[disabled],
+fieldset[disabled] .btn-linkedin,
+.btn-linkedin.disabled:hover,
+.btn-linkedin[disabled]:hover,
+fieldset[disabled] .btn-linkedin:hover,
+.btn-linkedin.disabled:focus,
+.btn-linkedin[disabled]:focus,
+fieldset[disabled] .btn-linkedin:focus,
+.btn-linkedin.disabled:active,
+.btn-linkedin[disabled]:active,
+fieldset[disabled] .btn-linkedin:active,
+.btn-linkedin.disabled.active,
+.btn-linkedin[disabled].active,
+fieldset[disabled] .btn-linkedin.active {
+  background-color: #007bb6;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-linkedin .badge {
+  color: #007bb6;
+  background-color: #ffffff;
+}
+.btn-tumblr {
+  color: #ffffff;
+  background-color: #2c4762;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr:hover,
+.btn-tumblr:focus,
+.btn-tumblr:active,
+.btn-tumblr.active,
+.open .dropdown-toggle.btn-tumblr {
+  color: #ffffff;
+  background-color: #1f3346;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr:active,
+.btn-tumblr.active,
+.open .dropdown-toggle.btn-tumblr {
+  background-image: none;
+}
+.btn-tumblr.disabled,
+.btn-tumblr[disabled],
+fieldset[disabled] .btn-tumblr,
+.btn-tumblr.disabled:hover,
+.btn-tumblr[disabled]:hover,
+fieldset[disabled] .btn-tumblr:hover,
+.btn-tumblr.disabled:focus,
+.btn-tumblr[disabled]:focus,
+fieldset[disabled] .btn-tumblr:focus,
+.btn-tumblr.disabled:active,
+.btn-tumblr[disabled]:active,
+fieldset[disabled] .btn-tumblr:active,
+.btn-tumblr.disabled.active,
+.btn-tumblr[disabled].active,
+fieldset[disabled] .btn-tumblr.active {
+  background-color: #2c4762;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-tumblr .badge {
+  color: #2c4762;
+  background-color: #ffffff;
+}
+.btn-twitter {
+  color: #ffffff;
+  background-color: #55acee;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter:hover,
+.btn-twitter:focus,
+.btn-twitter:active,
+.btn-twitter.active,
+.open .dropdown-toggle.btn-twitter {
+  color: #ffffff;
+  background-color: #309aea;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter:active,
+.btn-twitter.active,
+.open .dropdown-toggle.btn-twitter {
+  background-image: none;
+}
+.btn-twitter.disabled,
+.btn-twitter[disabled],
+fieldset[disabled] .btn-twitter,
+.btn-twitter.disabled:hover,
+.btn-twitter[disabled]:hover,
+fieldset[disabled] .btn-twitter:hover,
+.btn-twitter.disabled:focus,
+.btn-twitter[disabled]:focus,
+fieldset[disabled] .btn-twitter:focus,
+.btn-twitter.disabled:active,
+.btn-twitter[disabled]:active,
+fieldset[disabled] .btn-twitter:active,
+.btn-twitter.disabled.active,
+.btn-twitter[disabled].active,
+fieldset[disabled] .btn-twitter.active {
+  background-color: #55acee;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-twitter .badge {
+  color: #55acee;
+  background-color: #ffffff;
+}
+.btn-vk {
+  color: #ffffff;
+  background-color: #587ea3;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk:hover,
+.btn-vk:focus,
+.btn-vk:active,
+.btn-vk.active,
+.open .dropdown-toggle.btn-vk {
+  color: #ffffff;
+  background-color: #4a6a89;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk:active,
+.btn-vk.active,
+.open .dropdown-toggle.btn-vk {
+  background-image: none;
+}
+.btn-vk.disabled,
+.btn-vk[disabled],
+fieldset[disabled] .btn-vk,
+.btn-vk.disabled:hover,
+.btn-vk[disabled]:hover,
+fieldset[disabled] .btn-vk:hover,
+.btn-vk.disabled:focus,
+.btn-vk[disabled]:focus,
+fieldset[disabled] .btn-vk:focus,
+.btn-vk.disabled:active,
+.btn-vk[disabled]:active,
+fieldset[disabled] .btn-vk:active,
+.btn-vk.disabled.active,
+.btn-vk[disabled].active,
+fieldset[disabled] .btn-vk.active {
+  background-color: #587ea3;
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.btn-vk .badge {
+  color: #587ea3;
+  background-color: #ffffff;
+}
+
+
+
+.header .navbar .nav > li > a > .label {
+  -webkit-border-radius: 50%;
+  -moz-border-radius: 50%;
+  border-radius: 50%;
+  position: absolute;
+  top: 7px;
+  right: 2px;
+  font-size: 10px;
+  font-weight: normal;
+  width: 15px;
+  height: 15px;
+  line-height: 1.0em;
+  text-align: center;
+  padding: 2px;
+}
+.header .navbar .nav > li > a:hover > .label {
+  top: 3px;
+}
+
+
+.label-danger {
+  background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+  background-color: #c9302c;
+}
+
+
+
+
+
+.navbar-nav > .notifications-menu > .dropdown-menu,
+.navbar-nav > .messages-menu > .dropdown-menu,
+.navbar-nav > .tasks-menu > .dropdown-menu {
+  width: 280px;
+  padding: 0 0 0 0!important;
+  margin: 0!important;
+  top: 100%;
+  border: 1px solid #dfdfdf;
+  -webkit-border-radius: 4px !important;
+  -moz-border-radius: 4px !important;
+  border-radius: 4px !important;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.header,
+.navbar-nav > .messages-menu > .dropdown-menu > li.header,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.header {
+  -webkit-border-top-left-radius: 4px;
+  -webkit-border-top-right-radius: 4px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  background-color: #ffffff;
+  padding: 7px 10px;
+  border-bottom: 1px solid #f4f4f4;
+  color: #444444;
+  font-size: 14px;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.header:after,
+.navbar-nav > .messages-menu > .dropdown-menu > li.header:after,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.header:after {
+  bottom: 100%;
+  left: 92%;
+  border: solid transparent;
+  content: " ";
+  height: 0;
+  width: 0;
+  position: absolute;
+  pointer-events: none;
+  border-color: rgba(255, 255, 255, 0);
+  border-bottom-color: #ffffff;
+  border-width: 7px;
+  margin-left: -7px;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
+.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
+  -webkit-border-top-left-radius: 0px;
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 4px;
+  -webkit-border-bottom-left-radius: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 4px;
+  -moz-border-radius-bottomleft: 4px;
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+  font-size: 12px;
+  background-color: #f4f4f4;
+  padding: 7px 10px;
+  border-bottom: 1px solid #eeeeee;
+  color: #444444;
+  text-align: center;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover,
+.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover,
+.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover {
+  background: #f4f4f4;
+  text-decoration: none;
+  font-weight: normal;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  overflow-x: hidden;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
+  display: block;
+  white-space: nowrap;
+  /* Prevent text from breaking */
+  border-bottom: 1px solid #f4f4f4;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover,
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover {
+  background: #f6f6f6;
+  text-decoration: none;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a {
+  font-size: 12px;
+  color: #444444;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion {
+  font-size: 20px;
+  width: 50px;
+  text-align: center;
+  padding: 15px 0px;
+  margin-right: 5px;
+  /* Default background and font colors */
+  background: #00c0ef;
+  color: #f9f9f9;
+  /* Fallback for browsers that doesn't support rgba */
+  color: rgba(255, 255, 255, 0.7);
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.danger,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.danger,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.danger {
+  background: #f56954;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.warning,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.warning,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.warning {
+  background: #f39c12;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.success,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.success,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.success {
+  background: #00a65a;
+}
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon.info,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa.info,
+.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion.info {
+  background: #00c0ef;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a {
+  margin: 0px;
+  line-height: 20px;
+  padding: 10px 5px 10px 5px;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img {
+  margin: auto 10px auto auto;
+  width: 40px;
+  height: 40px;
+  border: 1px solid #dddddd;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 {
+  padding: 0;
+  margin: 0 0 0 45px;
+  color: #444444;
+  font-size: 15px;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small {
+  color: #999999;
+  font-size: 10px;
+  float: right;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p {
+  margin: 0 0 0 45px;
+  font-size: 12px;
+  color: #888888;
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before,
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
+  display: table;
+  content: " ";
+}
+.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {
+  clear: both;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {
+  padding: 10px;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 {
+  font-size: 14px;
+  padding: 0;
+  margin: 0 0 10px 0;
+  color: #666666;
+}
+.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress {
+  padding: 0;
+  margin: 0;
+}
+.navbar-nav > .user-menu > .dropdown-menu {
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+  padding: 1px 0 0 0;
+  border-top-width: 0;
+  width: 280px;
+}
+.navbar-nav > .user-menu > .dropdown-menu:after {
+  bottom: 100%;
+  right: 10px;
+  border: solid transparent;
+  content: " ";
+  height: 0;
+  width: 0;
+  position: absolute;
+  pointer-events: none;
+  border-color: rgba(255, 255, 255, 0);
+  border-bottom-color: #ffffff;
+  border-width: 10px;
+  margin-left: -10px;
+}
+
+
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header {
+  height: 175px;
+  padding: 10px;
+  background: #3c8dbc;
+  text-align: center;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img {
+  z-index: 5;
+  height: 90px;
+  width: 90px;
+  border: 8px solid;
+  border-color: transparent;
+  border-color: rgba(255, 255, 255, 0.2);
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p {
+  z-index: 5;
+  color: #f9f9f9;
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 17px;
+  text-shadow: 2px 2px 3px #333333;
+  margin-top: 10px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small {
+  display: block;
+  font-size: 12px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-body {
+  padding: 15px;
+  border-bottom: 1px solid #f4f4f4;
+  border-top: 1px solid #dddddd;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-body:before,
+.navbar-nav > .user-menu > .dropdown-menu > li.user-body:after {
+  display: table;
+  content: " ";
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-body:after {
+  clear: both;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-body > div > a {
+  color: #0073b7;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-footer {
+  background-color: #f9f9f9;
+  padding: 10px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:before,
+.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:after {
+  display: table;
+  content: " ";
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-footer:after {
+  clear: both;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-footer .btn-default {
+  color: #666666;
+}
+/* Add fade animation to dropdown menus */
+.open:not(.dropup) > .dropdown-menu {
+  animation-name: fadeAnimation;
+  animation-duration: .7s;
+  animation-iteration-count: 1;
+  animation-timing-function: ease;
+  animation-fill-mode: forwards;
+  -webkit-animation-name: fadeAnimation;
+  -webkit-animation-duration: .7s;
+  -webkit-animation-iteration-count: 1;
+  -webkit-animation-timing-function: ease;
+  -webkit-animation-fill-mode: forwards;
+  -moz-animation-name: fadeAnimation;
+  -moz-animation-duration: .7s;
+  -moz-animation-iteration-count: 1;
+  -moz-animation-timing-function: ease;
+  -moz-animation-fill-mode: forwards;
+}
+@keyframes fadeAnimation {
+  from {
+    opacity: 0;
+    top: 120%;
+  }
+  to {
+    opacity: 1;
+    top: 100%;
+  }
+}
+@-webkit-keyframes fadeAnimation {
+  from {
+    opacity: 0;
+    top: 120%;
+  }
+  to {
+    opacity: 1;
+    top: 100%;
+  }
+}
+/* Fix dropdown menu for small screens to display correctly on small screens */
+@media screen and (max-width: 767px) {
+  .navbar-nav > .notifications-menu > .dropdown-menu,
+  .navbar-nav > .user-menu > .dropdown-menu,
+  .navbar-nav > .tasks-menu > .dropdown-menu,
+  .navbar-nav > .messages-menu > .dropdown-menu {
+    position: absolute;
+    top: 100%;
+    right: 0;
+    left: auto;
+    border-right: 1px solid #dddddd;
+    border-bottom: 1px solid #dddddd;
+    border-left: 1px solid #dddddd;
+    background: #ffffff;
+  }
+}
+/* Fix menu positions on xs screens to appear correctly and fully */
+@media screen and (max-width: 480px) {
+  .navbar-nav > .notifications-menu > .dropdown-menu > li.header,
+  .navbar-nav > .tasks-menu > .dropdown-menu > li.header,
+  .navbar-nav > .messages-menu > .dropdown-menu > li.header {
+    /* Remove arrow from the top */
+  }
+  .navbar-nav > .notifications-menu > .dropdown-menu > li.header:after,
+  .navbar-nav > .tasks-menu > .dropdown-menu > li.header:after,
+  .navbar-nav > .messages-menu > .dropdown-menu > li.header:after {
+    border-width: 0px!important;
+  }
+  .navbar-nav > .tasks-menu > .dropdown-menu {
+    position: absolute;
+    right: -120px;
+    left: auto;
+  }
+  .navbar-nav > .notifications-menu > .dropdown-menu {
+    position: absolute;
+    right: -170px;
+    left: auto;
+  }
+  .navbar-nav > .messages-menu > .dropdown-menu {
+    position: absolute;
+    right: -210px;
+    left: auto;
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/angucomplete.css b/src/main/resources/META-INF/resources/designer/css/angucomplete.css
new file mode 100644 (file)
index 0000000..8e48ced
--- /dev/null
@@ -0,0 +1,67 @@
+.angucomplete-holder {
+    position: relative;
+}
+
+.angucomplete-dropdown {
+    border-color: #ececec;
+    border-width: 1px;
+    border-style: solid;
+    border-radius: 2px;
+    width: 400px;
+    padding: 6px;
+    cursor: pointer;
+    z-index: 9999;
+    position: absolute;
+    /*top: 32px;
+    left: 0px;
+    */
+    margin-top: -6px;
+    background-color: #ffffff;
+}
+
+.angucomplete-searching {
+    color: #acacac;
+    font-size: 14px;
+}
+
+.angucomplete-description {
+    font-size: 14px;
+}
+
+.angucomplete-row {
+    padding: 5px;
+    color: #000000;
+    margin-bottom: 4px;
+
+}
+
+.angucomplete-selected-row, .angucomplete-row:hover {
+    background-color: lightblue;
+    color: #ffffff;
+}
+
+.angucomplete-image-holder {
+    padding-top: 2px;
+    float: left;
+    margin-right: 10px;
+    margin-left: 5px;
+}
+
+.angucomplete-image {
+    height: 34px;
+    width: 34px;
+    border-radius: 50%;
+    border-color: #ececec;
+    border-style: solid;
+    border-width: 1px;
+}
+
+.angucomplete-image-default {
+    /* Add your own default image here
+     background-image: url('/assets/default.png');
+    */
+    background-position: center;
+    background-size: contain;
+    height: 34px;
+    width: 34px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/app.css b/src/main/resources/META-INF/resources/designer/css/app.css
new file mode 100644 (file)
index 0000000..95d5d58
--- /dev/null
@@ -0,0 +1,190 @@
+* {
+  box-sizing: border-box;
+}
+
+body, html {
+
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+  font-size: 12px;
+
+  height: 100%;
+  padding: 0;
+  margin: 0;
+}
+
+.fa-2x {
+       font-size: 2em
+}
+
+a:link {
+  text-decoration: none;
+}
+
+.content,
+.content > div {
+  width: 100%;
+  height: 100%;
+}
+
+.content > .message {
+  text-align: center;
+  display: table;
+
+  font-size: 16px;
+  color: #111;
+}
+
+.content > .message .note {
+  vertical-align: middle;
+  text-align: center;
+  display: table-cell;
+}
+
+.content .error .details {
+  max-width: 500px;
+  font-size: 12px;
+  margin: 20px auto;
+  text-align: left;
+}
+
+.content .error pre {
+  border: solid 1px #CCC;
+  background: #EEE;
+  padding: 10px;
+}
+
+.content:not(.with-error) .error,
+.content.with-error .intro,
+.content.with-diagram .intro {
+  display: none;
+}
+
+.canvas{
+       margin-top: -20px;
+}
+.content .canvas,
+.content.with-error .canvas {
+  visibility: hidden;
+}
+
+.content.with-diagram .canvas {
+  visibility: visible;
+}
+
+.buttons {
+  position: fixed;
+  bottom: 20px;
+  left: 20px;
+
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+
+.buttons > li {
+  display: inline-block;
+  margin-right: 10px;
+  visibility: hidden;
+}
+.buttons > li > a {
+  background: #DDD;
+  border: solid 1px #666;
+  display: inline-block;
+  padding: 5px;
+}
+
+.buttons a {
+  opacity: -0.7;
+}
+
+.buttons a.active {
+  opacity: 1.0;
+}
+svg:not(:root) {
+    margin-top: 40px;
+}
+.clds-edit-properties:before{ 
+       content: url('../images/clds-prop-icon.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+} /* '' */
+.import-schema:before{ 
+       content: url('../images/ImportSchema.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+} /* '' */
+.define-modify-schema:before{ 
+       content: url('../images/DefineModifySchema.png');
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+       opacity:0.5;
+} /* '' */
+.define-schema:before{ 
+       content: url('../images/DefineModifySchema.png');
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+       
+} /* '' */
+.upgrade-schema:before{ 
+       content: url('../images/UpgradeSchema.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/     
+       opacity:0.5;
+       cursor: none;
+} /* '' */
+.upgradeSchema:before{ 
+       content: url('../images/UpgradeSchema.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/     
+} /* '' */
+.set-default-values:before{ 
+       content: url('../images/SetDefaultValues.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/     
+       opacity: 0.5;
+       cursor: none;
+} /* '' */
+.set-values:before{ 
+       content: url('../images/SetDefaultValues.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/             
+} /* '' */
+/* .define-service-acronym:before{ 
+       content: url('../images/DefineServiceAcronym.png'); 
+       position:relative; or absolute
+       z-index:100000; a number that's more than the modal box         
+       cursor: none;           
+}  *//* '' */
+/* .define-pid:before{ 
+       content: url('../images/DefinePID.png'); 
+       position:relative; or absolute
+       z-index:100000; a number that's more than the modal box         
+       cursor: none;
+} */ /* '' */
+.true-false-condition:before{ 
+       content: url('../images/TrueFalseCondition.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/     
+       
+} /* '' */
+
+.define-path:before{ 
+       content: url('../images/DefinePath.png'); 
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+} /* '' */
+.define-decision:before{ 
+       content: url('../images/DefineDecision.png');
+       position:relative; /*or absolute*/
+       z-index:100000; /*a number that's more than the modal box*/
+} /* '' */
+.icon-initial-node:before{ content: url('../images/InitialProcess.png'); } /* '' */
+.icon-collector-node:before{ content: url('../images/clds-collector-icon.png'); } /* '' */
+.icon-stringmatch-node:before{ content: url('../images/clds-string-match-icon.png'); } /* '' */
+.icon-tca-node:before{ content: url('../images/clds-tca-icon.png'); } /* '' */
+.icon-policy-node:before{ content: url('../images/clds-policy-icon.png'); } /* '' */
+.icon-goc-node:before{ content: url('../images/GOC.png'); } /* '' */
+.icon-parent-node:before{ content: url('../images/ParentNode.png'); }
+.icon-process-call:before{ content: url('../images/ProcessCall.png'); }
+.icon-multi-branch-connector:before{ content: url('../images/MultiBranchConnector.png'); }
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css b/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css
new file mode 100644 (file)
index 0000000..c4cadf1
--- /dev/null
@@ -0,0 +1,470 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+.btn-default,
+.btn-primary,
+.btn-success,
+.btn-info,
+.btn-warning,
+.btn-danger {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+}
+.btn-default:active,
+.btn-primary:active,
+.btn-success:active,
+.btn-info:active,
+.btn-warning:active,
+.btn-danger:active,
+.btn-default.active,
+.btn-primary.active,
+.btn-success.active,
+.btn-info.active,
+.btn-warning.active,
+.btn-danger.active {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-default .badge,
+.btn-primary .badge,
+.btn-success .badge,
+.btn-info .badge,
+.btn-warning .badge,
+.btn-danger .badge {
+  text-shadow: none;
+}
+.btn:active,
+.btn.active {
+  background-image: none;
+}
+.btn-default {
+  text-shadow: 0 1px 0 #fff;
+  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
+  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #dbdbdb;
+  border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus {
+  background-color: #e0e0e0;
+  background-position: 0 -15px;
+}
+.btn-default:active,
+.btn-default.active {
+  background-color: #e0e0e0;
+  border-color: #dbdbdb;
+}
+.btn-default:disabled,
+.btn-default[disabled] {
+  background-color: #e0e0e0;
+  background-image: none;
+}
+.btn-primary {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #245580;
+}
+.btn-primary:hover,
+.btn-primary:focus {
+  background-color: #265a88;
+  background-position: 0 -15px;
+}
+.btn-primary:active,
+.btn-primary.active {
+  background-color: #265a88;
+  border-color: #245580;
+}
+.btn-primary:disabled,
+.btn-primary[disabled] {
+  background-color: #265a88;
+  background-image: none;
+}
+.btn-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
+  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #3e8f3e;
+}
+.btn-success:hover,
+.btn-success:focus {
+  background-color: #419641;
+  background-position: 0 -15px;
+}
+.btn-success:active,
+.btn-success.active {
+  background-color: #419641;
+  border-color: #3e8f3e;
+}
+.btn-success:disabled,
+.btn-success[disabled] {
+  background-color: #419641;
+  background-image: none;
+}
+.btn-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #28a4c9;
+}
+.btn-info:hover,
+.btn-info:focus {
+  background-color: #2aabd2;
+  background-position: 0 -15px;
+}
+.btn-info:active,
+.btn-info.active {
+  background-color: #2aabd2;
+  border-color: #28a4c9;
+}
+.btn-info:disabled,
+.btn-info[disabled] {
+  background-color: #2aabd2;
+  background-image: none;
+}
+.btn-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #e38d13;
+}
+.btn-warning:hover,
+.btn-warning:focus {
+  background-color: #eb9316;
+  background-position: 0 -15px;
+}
+.btn-warning:active,
+.btn-warning.active {
+  background-color: #eb9316;
+  border-color: #e38d13;
+}
+.btn-warning:disabled,
+.btn-warning[disabled] {
+  background-color: #eb9316;
+  background-image: none;
+}
+.btn-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #b92c28;
+}
+.btn-danger:hover,
+.btn-danger:focus {
+  background-color: #c12e2a;
+  background-position: 0 -15px;
+}
+.btn-danger:active,
+.btn-danger.active {
+  background-color: #c12e2a;
+  border-color: #b92c28;
+}
+.btn-danger:disabled,
+.btn-danger[disabled] {
+  background-color: #c12e2a;
+  background-image: none;
+}
+.thumbnail,
+.img-thumbnail {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  background-color: #e8e8e8;
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  background-color: #2e6da4;
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+  background-repeat: repeat-x;
+}
+.navbar-default {
+  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
+  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
+  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
+  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
+}
+.navbar-brand,
+.navbar-nav > li > a {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
+}
+.navbar-inverse {
+  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
+  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
+  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
+  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
+}
+.navbar-inverse .navbar-brand,
+.navbar-inverse .navbar-nav > li > a {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
+}
+.navbar-static-top,
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+  border-radius: 0;
+}
+@media (max-width: 767px) {
+  .navbar .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #fff;
+    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+    background-repeat: repeat-x;
+  }
+}
+.alert {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+}
+.alert-success {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #b2dba1;
+}
+.alert-info {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #9acfea;
+}
+.alert-warning {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #f5e79e;
+}
+.alert-danger {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dca7a7;
+}
+.progress {
+  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
+  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
+  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
+  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
+  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
+  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-striped {
+  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);
+}
+.list-group {
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+  text-shadow: 0 -1px 0 #286090;
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #2b669a;
+}
+.list-group-item.active .badge,
+.list-group-item.active:hover .badge,
+.list-group-item.active:focus .badge {
+  text-shadow: none;
+}
+.panel {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
+}
+.panel-default > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-primary > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-success > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
+  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-info > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
+  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-warning > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
+  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-danger > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
+  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.well {
+  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
+  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dcdcdc;
+  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+}
+/*# sourceMappingURL=bootstrap-theme.css.map */
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css.map b/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.css.map
new file mode 100644 (file)
index 0000000..016a8da
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAcA;;;;;;EAME,0CAAA;ECgDA,6FAAA;EACQ,qFAAA;EC5DT;AFgBC;;;;;;;;;;;;EC2CA,0DAAA;EACQ,kDAAA;EC7CT;AFVD;;;;;;EAiBI,mBAAA;EECH;AFgCC;;EAEE,wBAAA;EE9BH;AFmCD;EGlDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EA+B2C,2BAAA;EAA2B,oBAAA;EExBvE;AFLC;;EAEE,2BAAA;EACA,8BAAA;EEOH;AFJC;;EAEE,2BAAA;EACA,uBAAA;EEMH;AFHC;;EAEE,2BAAA;EACA,wBAAA;EEKH;AFUD;EGnDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+BD;AF7BC;;EAEE,2BAAA;EACA,8BAAA;EE+BH;AF5BC;;EAEE,2BAAA;EACA,uBAAA;EE8BH;AF3BC;;EAEE,2BAAA;EACA,wBAAA;EE6BH;AFbD;EGpDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEuDD;AFrDC;;EAEE,2BAAA;EACA,8BAAA;EEuDH;AFpDC;;EAEE,2BAAA;EACA,uBAAA;EEsDH;AFnDC;;EAEE,2BAAA;EACA,wBAAA;EEqDH;AFpCD;EGrDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+ED;AF7EC;;EAEE,2BAAA;EACA,8BAAA;EE+EH;AF5EC;;EAEE,2BAAA;EACA,uBAAA;EE8EH;AF3EC;;EAEE,2BAAA;EACA,wBAAA;EE6EH;AF3DD;EGtDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEuGD;AFrGC;;EAEE,2BAAA;EACA,8BAAA;EEuGH;AFpGC;;EAEE,2BAAA;EACA,uBAAA;EEsGH;AFnGC;;EAEE,2BAAA;EACA,wBAAA;EEqGH;AFlFD;EGvDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+HD;AF7HC;;EAEE,2BAAA;EACA,8BAAA;EE+HH;AF5HC;;EAEE,2BAAA;EACA,uBAAA;EE8HH;AF3HC;;EAEE,2BAAA;EACA,wBAAA;EE6HH;AFnGD;;ECfE,oDAAA;EACQ,4CAAA;ECsHT;AF9FD;;EGxEI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHuEF,2BAAA;EEoGD;AFlGD;;;EG7EI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH6EF,2BAAA;EEwGD;AF/FD;EG1FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EJ4GA,oBAAA;EC9CA,6FAAA;EACQ,qFAAA;ECoJT;AF1GD;;EG1FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,0DAAA;EACQ,kDAAA;EC8JT;AFvGD;;EAEE,gDAAA;EEyGD;AFrGD;EG7GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EFyOD;AF7GD;;EG7GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,yDAAA;EACQ,iDAAA;ECoLT;AFvHD;;EAYI,2CAAA;EE+GH;AF1GD;;;EAGE,kBAAA;EE4GD;AF5FD;EAVI;;;IAGE,aAAA;IG1IF,0EAAA;IACA,qEAAA;IACA,+FAAA;IAAA,wEAAA;IACA,6BAAA;IACA,wHAAA;IDoPD;EACF;AFnGD;EACE,+CAAA;ECxGA,4FAAA;EACQ,oFAAA;EC8MT;AF3FD;EGnKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EEuGD;AFlGD;EGpKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EE+GD;AFzGD;EGrKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EEuHD;AFhHD;EGtKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EE+HD;AFhHD;EG9KI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDiSH;AF7GD;EGxLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDwSH;AFnHD;EGzLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED+SH;AFzHD;EG1LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDsTH;AF/HD;EG3LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED6TH;AFrID;EG5LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDoUH;AFxID;EG/JI,+MAAA;EACA,0MAAA;EACA,uMAAA;ED0SH;AFpID;EACE,oBAAA;EC3JA,oDAAA;EACQ,4CAAA;ECkST;AFrID;;;EAGE,+BAAA;EGhNE,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH8MF,uBAAA;EE2ID;AFhJD;;;EAQI,mBAAA;EE6IH;AFnID;EChLE,mDAAA;EACQ,2CAAA;ECsTT;AF7HD;EGzOI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDyWH;AFnID;EG1OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDgXH;AFzID;EG3OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDuXH;AF/ID;EG5OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED8XH;AFrJD;EG7OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDqYH;AF3JD;EG9OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED4YH;AF3JD;EGrPI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHmPF,uBAAA;ECxMA,2FAAA;EACQ,mFAAA;EC0WT","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  // Reset the shadow\n  &:active,\n  &.active {\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n  background-repeat: repeat-x;\n  border-color: darken(@btn-color, 14%);\n\n  &:hover,\n  &:focus  {\n    background-color: darken(@btn-color, 12%);\n    background-position: 0 -15px;\n  }\n\n  &:active,\n  &.active {\n    background-color: darken(@btn-color, 12%);\n    border-color: darken(@btn-color, 14%);\n  }\n\n  &:disabled,\n  &[disabled] {\n    background-color: darken(@btn-color, 12%);\n    background-image: none;\n  }\n}\n\n// Common styles\n.btn {\n  // Remove the gradient for the pressed/active state\n  &:active,\n  &.active {\n    background-image: none;\n  }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info    { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger  { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n  background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n  background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n  border-radius: @navbar-border-radius;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n  }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n  .navbar-nav > .open > a,\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n  }\n\n  .navbar-brand,\n  .navbar-nav > li > a {\n    text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n  }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a {\n    &,\n    &:hover,\n    &:focus {\n      color: #fff;\n      #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n    }\n  }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n  text-shadow: 0 1px 0 rgba(255,255,255,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n  .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n  border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success    { .alert-styles(@alert-success-bg); }\n.alert-info       { .alert-styles(@alert-info-bg); }\n.alert-warning    { .alert-styles(@alert-warning-bg); }\n.alert-danger     { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar            { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n  #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n  border-radius: @border-radius-base;\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n  border-color: darken(@list-group-active-border, 7.5%);\n\n  .badge {\n    text-shadow: none;\n  }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n  .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n  border-color: darken(@well-bg, 10%);\n  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n  text-shadow: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n.btn-default {\n  background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n  background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n  background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  text-shadow: 0 1px 0 #fff;\n  border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n.btn-default:disabled,\n.btn-default[disabled] {\n  background-color: #e0e0e0;\n  background-image: none;\n}\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #265a88;\n  background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #265a88;\n  border-color: #245580;\n}\n.btn-primary:disabled,\n.btn-primary[disabled] {\n  background-color: #265a88;\n  background-image: none;\n}\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n.btn-success:disabled,\n.btn-success[disabled] {\n  background-color: #419641;\n  background-image: none;\n}\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n.btn-info:disabled,\n.btn-info[disabled] {\n  background-color: #2aabd2;\n  background-image: none;\n}\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n.btn-warning:disabled,\n.btn-warning[disabled] {\n  background-color: #eb9316;\n  background-image: none;\n}\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n.btn-danger:disabled,\n.btn-danger[disabled] {\n  background-color: #c12e2a;\n  background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-color: #2e6da4;\n}\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n  background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n  background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n  background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n  background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n@media (max-width: 767px) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  }\n}\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n  border-color: #b2dba1;\n}\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n  border-color: #9acfea;\n}\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n  border-color: #f5e79e;\n}\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n  border-color: #dca7a7;\n}\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #286090;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n  border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n  text-shadow: none;\n}\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  border-color: #dcdcdc;\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.min.css b/src/main/resources/META-INF/resources/designer/css/bootstrap-theme.min.css
new file mode 100644 (file)
index 0000000..dc7c803
--- /dev/null
@@ -0,0 +1,5 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:hover,.btn-primary:focus{background-color:#265a88;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#265a88;border-color:#245580}.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{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)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:hover .badge,.list-group-item.active:focus .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap.css b/src/main/resources/META-INF/resources/designer/css/bootstrap.css
new file mode 100644 (file)
index 0000000..17f4b07
--- /dev/null
@@ -0,0 +1,6342 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+html {
+  font-family: sans-serif;
+  -webkit-text-size-adjust: 100%;
+      -ms-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block;
+}
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  vertical-align: baseline;
+}
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+[hidden],
+template {
+  display: none;
+}
+a {
+  background-color: transparent;
+}
+a:active,
+a:hover {
+  outline: 0;
+}
+abbr[title] {
+  border-bottom: 1px dotted;
+}
+b,
+strong {
+  font-weight: bold;
+}
+dfn {
+  font-style: italic;
+}
+h1 {
+  margin: .67em 0;
+  font-size: 2em;
+}
+mark {
+  color: #000;
+  background: #ff0;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  position: relative;
+  font-size: 75%;
+  line-height: 0;
+  vertical-align: baseline;
+}
+sup {
+  top: -.5em;
+}
+sub {
+  bottom: -.25em;
+}
+img {
+  border: 0;
+}
+svg:not(:root) {
+  overflow: hidden;
+}
+figure {
+  margin: 1em 40px;
+}
+hr {
+  height: 0;
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+}
+pre {
+  overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  margin: 0;
+  font: inherit;
+  color: inherit;
+}
+button {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+  cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  padding: 0;
+  border: 0;
+}
+input {
+  line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+  -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+fieldset {
+  padding: .35em .625em .75em;
+  margin: 0 2px;
+  border: 1px solid #c0c0c0;
+}
+legend {
+  padding: 0;
+  border: 0;
+}
+textarea {
+  overflow: auto;
+}
+optgroup {
+  font-weight: bold;
+}
+table {
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+td,
+th {
+  padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+  *,
+  *:before,
+  *:after {
+    color: #000 !important;
+    text-shadow: none !important;
+    background: transparent !important;
+    -webkit-box-shadow: none !important;
+            box-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  a[href]:after {
+    content: " (" attr(href) ")";
+  }
+  abbr[title]:after {
+    content: " (" attr(title) ")";
+  }
+  a[href^="#"]:after,
+  a[href^="javascript:"]:after {
+    content: "";
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  img {
+    max-width: 100% !important;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  select {
+    background: #fff !important;
+  }
+  .navbar {
+    display: none;
+  }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important;
+  }
+  .label {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    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: normal;
+  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,
+.glyphicon-eur: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;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+html {
+  font-size: 10px;
+
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #333;
+  background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+a {
+  color: #337ab7;
+  text-decoration: none;
+}
+a:hover,
+a:focus {
+  color: #23527c;
+  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;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > 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,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+  font-weight: normal;
+  line-height: 1;
+  color: #777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.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,
+.h4,
+h5,
+.h5,
+h6,
+.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%;
+}
+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: #337ab7;
+}
+a.text-primary:hover {
+  color: #286090;
+}
+.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: #337ab7;
+}
+a.bg-primary:hover {
+  background-color: #286090;
+}
+.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;
+}
+ul,
+ol {
+  margin-top: 0;
+  margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+  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;
+}
+dt,
+dd {
+  line-height: 1.42857143;
+}
+dt {
+  font-weight: bold;
+}
+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[title],
+abbr[data-original-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 p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+  margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+  display: block;
+  font-size: 80%;
+  line-height: 1.42857143;
+  color: #777;
+}
+blockquote footer:before,
+blockquote small: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 footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+  content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+  content: '\00A0 \2014';
+}
+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%;
+  font-weight: bold;
+  -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-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+  position: relative;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+  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-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+    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-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+    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-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+    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;
+}
+caption {
+  padding-top: 8px;
+  padding-bottom: 8px;
+  color: #777;
+  text-align: left;
+}
+th {
+  text-align: left;
+}
+.table {
+  width: 100%;
+  max-width: 100%;
+  margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+  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 > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+  border-top: 0;
+}
+.table > tbody + tbody {
+  border-top: 2px solid #ddd;
+}
+.table .table {
+  background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+  padding: 5px;
+}
+.table-bordered {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+  border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+  border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-child(odd) {
+  background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+  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 > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+  background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+  background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+  background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+  background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+  background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+  background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+  background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+  background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+  background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+  background-color: #ebcccc;
+}
+.table-responsive {
+  min-height: .01%;
+  overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+  .table-responsive {
+    width: 100%;
+    margin-bottom: 15px;
+    overflow-y: hidden;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+    border: 1px solid #ddd;
+  }
+  .table-responsive > .table {
+    margin-bottom: 0;
+  }
+  .table-responsive > .table > thead > tr > th,
+  .table-responsive > .table > tbody > tr > th,
+  .table-responsive > .table > tfoot > tr > th,
+  .table-responsive > .table > thead > tr > td,
+  .table-responsive > .table > tbody > tr > td,
+  .table-responsive > .table > tfoot > tr > td {
+    white-space: nowrap;
+  }
+  .table-responsive > .table-bordered {
+    border: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:first-child,
+  .table-responsive > .table-bordered > tbody > tr > th:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+  .table-responsive > .table-bordered > thead > tr > td:first-child,
+  .table-responsive > .table-bordered > tbody > tr > td:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+    border-left: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:last-child,
+  .table-responsive > .table-bordered > tbody > tr > th:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+  .table-responsive > .table-bordered > thead > tr > td:last-child,
+  .table-responsive > .table-bordered > tbody > tr > td:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+    border-right: 0;
+  }
+  .table-responsive > .table-bordered > tbody > tr:last-child > th,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+  .table-responsive > .table-bordered > tbody > tr:last-child > td,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+    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: bold;
+}
+input[type="search"] {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+  margin: 4px 0 0;
+  margin-top: 1px \9;
+  line-height: normal;
+}
+input[type="file"] {
+  display: block;
+}
+input[type="range"] {
+  display: block;
+  width: 100%;
+}
+select[multiple],
+select[size] {
+  height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]: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: #999;
+  opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+  color: #999;
+}
+.form-control::-webkit-input-placeholder {
+  color: #999;
+}
+.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;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+  input[type="date"],
+  input[type="time"],
+  input[type="datetime-local"],
+  input[type="month"] {
+    line-height: 34px;
+  }
+  input[type="date"].input-sm,
+  input[type="time"].input-sm,
+  input[type="datetime-local"].input-sm,
+  input[type="month"].input-sm {
+    line-height: 30px;
+  }
+  input[type="date"].input-lg,
+  input[type="time"].input-lg,
+  input[type="datetime-local"].input-lg,
+  input[type="month"].input-lg {
+    line-height: 46px;
+  }
+}
+.form-group {
+  margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+  position: relative;
+  display: block;
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+  min-height: 20px;
+  padding-left: 20px;
+  margin-bottom: 0;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+  position: absolute;
+  margin-top: 4px \9;
+  margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+  margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+  display: inline-block;
+  padding-left: 20px;
+  margin-bottom: 0;
+  font-weight: normal;
+  vertical-align: middle;
+  cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+  margin-top: 0;
+  margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+  cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+  cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox 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;
+}
+.input-sm,
+.form-group-sm .form-control {
+  height: 30px;
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+select.input-sm,
+select.form-group-sm .form-control {
+  height: 30px;
+  line-height: 30px;
+}
+textarea.input-sm,
+textarea.form-group-sm .form-control,
+select[multiple].input-sm,
+select[multiple].form-group-sm .form-control {
+  height: auto;
+}
+.input-lg,
+.form-group-lg .form-control {
+  height: 46px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+select.input-lg,
+select.form-group-lg .form-control {
+  height: 46px;
+  line-height: 46px;
+}
+textarea.input-lg,
+textarea.form-group-lg .form-control,
+select[multiple].input-lg,
+select[multiple].form-group-lg .form-control {
+  height: auto;
+}
+.has-feedback {
+  position: relative;
+}
+.has-feedback .form-control {
+  padding-right: 42.5px;
+}
+.form-control-feedback {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 2;
+  display: block;
+  width: 34px;
+  height: 34px;
+  line-height: 34px;
+  text-align: center;
+  pointer-events: none;
+}
+.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 .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+  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 .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+  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 .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+  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 ~ .form-control-feedback {
+  top: 25px;
+}
+.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 .form-control-static {
+    display: inline-block;
+  }
+  .form-inline .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .form-inline .input-group .input-group-addon,
+  .form-inline .input-group .input-group-btn,
+  .form-inline .input-group .form-control {
+    width: auto;
+  }
+  .form-inline .input-group > .form-control {
+    width: 100%;
+  }
+  .form-inline .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio,
+  .form-inline .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio label,
+  .form-inline .checkbox label {
+    padding-left: 0;
+  }
+  .form-inline .radio input[type="radio"],
+  .form-inline .checkbox input[type="checkbox"] {
+    position: relative;
+    margin-left: 0;
+  }
+  .form-inline .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+  padding-top: 7px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+  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 {
+  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: normal;
+  line-height: 1.42857143;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: middle;
+  -ms-touch-action: manipulation;
+      touch-action: manipulation;
+  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:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+  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;
+  filter: alpha(opacity=65);
+  -webkit-box-shadow: none;
+          box-shadow: none;
+  opacity: .65;
+}
+.btn-default {
+  color: #333;
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus,
+.btn-default.focus,
+.btn-default:active,
+.btn-default.active,
+.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],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+  background-color: #fff;
+  border-color: #ccc;
+}
+.btn-default .badge {
+  color: #fff;
+  background-color: #333;
+}
+.btn-primary {
+  color: #fff;
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary.focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  color: #fff;
+  background-color: #286090;
+  border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  background-image: none;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+  background-color: #337ab7;
+  border-color: #2e6da4;
+}
+.btn-primary .badge {
+  color: #337ab7;
+  background-color: #fff;
+}
+.btn-success {
+  color: #fff;
+  background-color: #5cb85c;
+  border-color: #4cae4c;
+}
+.btn-success:hover,
+.btn-success:focus,
+.btn-success.focus,
+.btn-success:active,
+.btn-success.active,
+.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],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+  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:hover,
+.btn-info:focus,
+.btn-info.focus,
+.btn-info:active,
+.btn-info.active,
+.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],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+  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:hover,
+.btn-warning:focus,
+.btn-warning.focus,
+.btn-warning:active,
+.btn-warning.active,
+.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],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+  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:hover,
+.btn-danger:focus,
+.btn-danger.focus,
+.btn-danger:active,
+.btn-danger.active,
+.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],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+  background-color: #d9534f;
+  border-color: #d43f3a;
+}
+.btn-danger .badge {
+  color: #d9534f;
+  background-color: #fff;
+}
+.btn-link {
+  font-weight: normal;
+  color: #337ab7;
+  border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+  background-color: transparent;
+  -webkit-box-shadow: none;
+          box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+  color: #23527c;
+  text-decoration: underline;
+  background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+  color: #777;
+  text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+  padding: 5px 10px;
+  font-size: 12px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+  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="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].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;
+  visibility: hidden;
+}
+.collapse.in {
+  display: block;
+  visibility: visible;
+}
+tr.collapse.in {
+  display: table-row;
+}
+tbody.collapse.in {
+  display: table-row-group;
+}
+.collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  -webkit-transition-timing-function: ease;
+       -o-transition-timing-function: ease;
+          transition-timing-function: ease;
+  -webkit-transition-duration: .35s;
+       -o-transition-duration: .35s;
+          transition-duration: .35s;
+  -webkit-transition-property: height, visibility;
+       -o-transition-property: height, visibility;
+          transition-property: height, visibility;
+}
+.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: normal;
+  line-height: 1.42857143;
+  color: #333;
+  white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  color: #262626;
+  text-decoration: none;
+  background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  color: #fff;
+  text-decoration: none;
+  background-color: #337ab7;
+  outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  color: #777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  text-decoration: none;
+  cursor: not-allowed;
+  background-color: transparent;
+  background-image: none;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.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: 14px;
+  line-height: 1.42857143;
+  color: #777;
+  white-space: nowrap;
+}
+
+.dropdown-header1 {
+  display: block;
+  padding: 3px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #FFFFFF;
+  background-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 > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+  z-index: 2;
+}
+.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="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+  position: absolute;
+  clip: rect(0, 0, 0, 0);
+  pointer-events: none;
+}
+.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;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].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;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+  height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+  display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control: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: normal;
+  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="radio"],
+.input-group-addon input[type="checkbox"] {
+  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:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+  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:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+  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:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+  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:hover,
+.nav > li > a:focus {
+  text-decoration: none;
+  background-color: #eee;
+}
+.nav > li.disabled > a {
+  color: #777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+  color: #777;
+  text-decoration: none;
+  cursor: not-allowed;
+  background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+  background-color: #eee;
+  border-color: #337ab7;
+}
+.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:hover,
+.nav-tabs > li.active > a:focus {
+  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:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+  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:hover,
+  .nav-tabs.nav-justified > .active > a:focus {
+    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:hover,
+.nav-pills > li.active > a:focus {
+  color: #fff;
+  background-color: #337ab7;
+}
+.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:hover,
+.nav-tabs-justified > .active > a:focus {
+  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:hover,
+  .nav-tabs-justified > .active > a:focus {
+    border-bottom-color: #fff;
+  }
+}
+.tab-content > .tab-pane {
+  display: none;
+  visibility: hidden;
+}
+.tab-content > .active {
+  display: block;
+  visibility: visible;
+}
+.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;
+    visibility: visible !important;
+  }
+  .navbar-collapse.in {
+    overflow-y: visible;
+  }
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-static-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+  max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    max-height: 200px;
+  }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+@media (min-width: 768px) {
+  .container > .navbar-header,
+  .container-fluid > .navbar-header,
+  .container > .navbar-collapse,
+  .container-fluid > .navbar-collapse {
+    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-top,
+.navbar-fixed-bottom {
+  position: fixed;
+  right: 0;
+  left: 0;
+  z-index: 1030;
+}
+@media (min-width: 768px) {
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    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:hover,
+.navbar-brand:focus {
+  text-decoration: none;
+}
+.navbar-brand > img {
+  display: block;
+}
+@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 > li > a,
+  .navbar-nav .open .dropdown-menu .dropdown-header {
+    padding: 5px 15px 5px 25px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a {
+    line-height: 20px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-nav .open .dropdown-menu > li > a:focus {
+    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-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 .form-control-static {
+    display: inline-block;
+  }
+  .navbar-form .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .navbar-form .input-group .input-group-addon,
+  .navbar-form .input-group .input-group-btn,
+  .navbar-form .input-group .form-control {
+    width: auto;
+  }
+  .navbar-form .input-group > .form-control {
+    width: 100%;
+  }
+  .navbar-form .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio,
+  .navbar-form .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio label,
+  .navbar-form .checkbox label {
+    padding-left: 0;
+  }
+  .navbar-form .radio input[type="radio"],
+  .navbar-form .checkbox input[type="checkbox"] {
+    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;
+  }
+  .navbar-form .form-group:last-child {
+    margin-bottom: 0;
+  }
+}
+@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-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-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  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;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-left {
+    float: left !important;
+  }
+  .navbar-right {
+    float: right !important;
+    margin-right: -15px;
+  }
+  .navbar-right ~ .navbar-right {
+    margin-right: 0;
+  }
+}
+.navbar-default {
+  background-color: #f8f8f8;
+  border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+  color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+  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:hover,
+.navbar-default .navbar-nav > li > a:focus {
+  color: #333;
+  background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+  color: #ccc;
+  background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+  border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+  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:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+  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:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #333;
+    background-color: transparent;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #555;
+    background-color: #e7e7e7;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    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:hover,
+.navbar-default .btn-link:focus {
+  color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+  color: #ccc;
+}
+.navbar-inverse {
+  background-color: #222;
+  border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+  color: #444;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+  border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+  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:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+  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: #9d9d9d;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #fff;
+    background-color: transparent;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #fff;
+    background-color: #080808;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #444;
+    background-color: transparent;
+  }
+}
+.navbar-inverse .navbar-link {
+  color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+  color: #fff;
+}
+.navbar-inverse .btn-link {
+  color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+  color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+  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: #337ab7;
+  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:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+  color: #23527c;
+  background-color: #eee;
+  border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+  z-index: 2;
+  color: #fff;
+  cursor: default;
+  background-color: #337ab7;
+  border-color: #337ab7;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+  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:hover,
+.pager li > a:focus {
+  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:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+  color: #777;
+  cursor: not-allowed;
+  background-color: #fff;
+}
+.label {
+  display: inline;
+  padding: .2em .6em .3em;
+  font-size: 75%;
+  font-weight: bold;
+  line-height: 1;
+  color: #fff;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+  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]:hover,
+.label-default[href]:focus {
+  background-color: #5e5e5e;
+}
+.label-primary {
+  background-color: #337ab7;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+  background-color: #286090;
+}
+.label-success {
+  background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+  background-color: #449d44;
+}
+.label-info {
+  background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+  background-color: #31b0d5;
+}
+.label-warning {
+  background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+  background-color: #ec971f;
+}
+.label-danger {
+  background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+  background-color: #c9302c;
+}
+.badge {
+  display: inline-block;
+  min-width: 10px;
+  padding: 3px 7px;
+  font-size: 12px;
+  font-weight: bold;
+  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:hover,
+a.badge:focus {
+  color: #fff;
+  text-decoration: none;
+  cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+  color: #337ab7;
+  background-color: #fff;
+}
+.list-group-item > .badge {
+  float: right;
+}
+.list-group-item > .badge + .badge {
+  margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+  margin-left: 3px;
+}
+.jumbotron {
+  padding: 30px 15px;
+  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,
+.container-fluid .jumbotron {
+  border-radius: 6px;
+}
+.jumbotron .container {
+  max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+  .jumbotron {
+    padding: 48px 0;
+  }
+  .container .jumbotron,
+  .container-fluid .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: border .2s ease-in-out;
+       -o-transition: border .2s ease-in-out;
+          transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+  margin-right: auto;
+  margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+  border-color: #337ab7;
+}
+.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: bold;
+}
+.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: #337ab7;
+  -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-striped .progress-bar,
+.progress-bar-striped {
+  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.active .progress-bar,
+.progress-bar.active {
+  -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-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 {
+  margin-top: 15px;
+}
+.media:first-child {
+  margin-top: 0;
+}
+.media-right,
+.media > .pull-right {
+  padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+  padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+  display: table-cell;
+  vertical-align: top;
+}
+.media-middle {
+  vertical-align: middle;
+}
+.media-bottom {
+  vertical-align: bottom;
+}
+.media-heading {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+.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;
+}
+a.list-group-item {
+  color: #555;
+}
+a.list-group-item .list-group-item-heading {
+  color: #333;
+}
+a.list-group-item:hover,
+a.list-group-item:focus {
+  color: #555;
+  text-decoration: none;
+  background-color: #f5f5f5;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+  color: #777;
+  cursor: not-allowed;
+  background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+  color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+  color: #777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+  z-index: 2;
+  color: #fff;
+  background-color: #337ab7;
+  border-color: #337ab7;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+  color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+  color: #c7ddef;
+}
+.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:hover,
+a.list-group-item-success:focus {
+  color: #3c763d;
+  background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+  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:hover,
+a.list-group-item-info:focus {
+  color: #31708f;
+  background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+  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:hover,
+a.list-group-item-warning:focus {
+  color: #8a6d3b;
+  background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+  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:hover,
+a.list-group-item-danger:focus {
+  color: #a94442;
+  background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+  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,
+.panel > .panel-collapse > .list-group {
+  margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+  border-width: 1px 0;
+  border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .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,
+.panel > .panel-collapse > .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 > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+  margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+  padding-right: 15px;
+  padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.panel > .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 td:first-child,
+.panel > .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 td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+  border-top-left-radius: 3px;
+}
+.panel > .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 td:last-child,
+.panel > .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 td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+  border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel > .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 td:first-child,
+.panel > .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 td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+  border-bottom-left-radius: 3px;
+}
+.panel > .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 td:last-child,
+.panel > .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 td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .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,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+  border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+  border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+  border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+  border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+  border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+  border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.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,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+  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: #337ab7;
+}
+.panel-primary > .panel-heading {
+  color: #fff;
+  background-color: #337ab7;
+  border-color: #337ab7;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: #337ab7;
+}
+.panel-primary > .panel-heading .badge {
+  color: #337ab7;
+  background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: #337ab7;
+}
+.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 iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+  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: bold;
+  line-height: 1;
+  color: #000;
+  text-shadow: 0 1px 0 #fff;
+  filter: alpha(opacity=20);
+  opacity: .2;
+}
+.close:hover,
+.close:focus {
+  color: #000;
+  text-decoration: none;
+  cursor: pointer;
+  filter: alpha(opacity=50);
+  opacity: .5;
+}
+button.close {
+  -webkit-appearance: none;
+  padding: 0;
+  cursor: pointer;
+  background: transparent;
+  border: 0;
+}
+.modal-open {
+  overflow: hidden;
+}
+.modal {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1040;
+  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: translate(0, -25%);
+      -ms-transform: translate(0, -25%);
+       -o-transform: translate(0, -25%);
+          transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+  -webkit-transform: translate(0, 0);
+      -ms-transform: translate(0, 0);
+       -o-transform: translate(0, 0);
+          transform: translate(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: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  background-color: #000;
+}
+.modal-backdrop.fade {
+  filter: alpha(opacity=0);
+  opacity: 0;
+}
+.modal-backdrop.in {
+  filter: alpha(opacity=50);
+  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: 750px;
+    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-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 12px;
+  font-weight: normal;
+  line-height: 1.4;
+  visibility: visible;
+  filter: alpha(opacity=0);
+  opacity: 0;
+}
+.tooltip.in {
+  filter: alpha(opacity=90);
+  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 {
+  right: 5px;
+  bottom: 0;
+  margin-bottom: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+  bottom: 0;
+  left: 5px;
+  margin-bottom: -5px;
+  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;
+  right: 5px;
+  margin-top: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+  top: 0;
+  left: 5px;
+  margin-top: -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;
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.42857143;
+  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;
+  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 > img,
+.carousel-inner > .item > a > img {
+  line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+  .carousel-inner > .item {
+    -webkit-transition: -webkit-transform .6s ease-in-out;
+         -o-transition:      -o-transform .6s ease-in-out;
+            transition:         transform .6s ease-in-out;
+
+    -webkit-backface-visibility: hidden;
+            backface-visibility: hidden;
+    -webkit-perspective: 1000;
+            perspective: 1000;
+  }
+  .carousel-inner > .item.next,
+  .carousel-inner > .item.active.right {
+    left: 0;
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+  }
+  .carousel-inner > .item.prev,
+  .carousel-inner > .item.active.left {
+    left: 0;
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+  }
+  .carousel-inner > .item.next.left,
+  .carousel-inner > .item.prev.right,
+  .carousel-inner > .item.active {
+    left: 0;
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+  }
+}
+.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);
+  filter: alpha(opacity=50);
+  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%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+  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%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+  background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+  color: #fff;
+  text-decoration: none;
+  filter: alpha(opacity=90);
+  outline: 0;
+  opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+  position: absolute;
+  top: 50%;
+  z-index: 5;
+  display: inline-block;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+  left: 50%;
+  margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+  right: 50%;
+  margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+  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: #000 \9;
+  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-prev,
+  .carousel-control .icon-next {
+    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;
+  }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+  display: table;
+  content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer: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;
+}
+@-ms-viewport {
+  width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+  display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-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;
+  }
+  th.visible-xs,
+  td.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;
+  }
+  th.visible-sm,
+  td.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;
+  }
+  th.visible-md,
+  td.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;
+  }
+  th.visible-lg,
+  td.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;
+  }
+  th.visible-print,
+  td.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;
+  }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap.css.map b/src/main/resources/META-INF/resources/designer/css/bootstrap.css.map
new file mode 100644 (file)
index 0000000..a02f6ba
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA,6DAA4D;ACQ5D;EACE,yBAAA;EACA,4BAAA;EACA,gCAAA;EDND;ACaD;EACE,WAAA;EDXD;ACwBD;;;;;;;;;;;;;EAaE,gBAAA;EDtBD;AC8BD;;;;EAIE,uBAAA;EACA,0BAAA;ED5BD;ACoCD;EACE,eAAA;EACA,WAAA;EDlCD;AC0CD;;EAEE,eAAA;EDxCD;ACkDD;EACE,+BAAA;EDhDD;ACuDD;;EAEE,YAAA;EDrDD;AC+DD;EACE,2BAAA;ED7DD;ACoED;;EAEE,mBAAA;EDlED;ACyED;EACE,oBAAA;EDvED;AC+ED;EACE,gBAAA;EACA,kBAAA;ED7ED;ACoFD;EACE,kBAAA;EACA,aAAA;EDlFD;ACyFD;EACE,gBAAA;EDvFD;AC8FD;;EAEE,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,0BAAA;ED5FD;AC+FD;EACE,aAAA;ED7FD;ACgGD;EACE,iBAAA;ED9FD;ACwGD;EACE,WAAA;EDtGD;AC6GD;EACE,kBAAA;ED3GD;ACqHD;EACE,kBAAA;EDnHD;AC0HD;EACE,8BAAA;EACA,iCAAA;UAAA,yBAAA;EACA,WAAA;EDxHD;AC+HD;EACE,gBAAA;ED7HD;ACoID;;;;EAIE,mCAAA;EACA,gBAAA;EDlID;ACoJD;;;;;EAKE,gBAAA;EACA,eAAA;EACA,WAAA;EDlJD;ACyJD;EACE,mBAAA;EDvJD;ACiKD;;EAEE,sBAAA;ED/JD;AC0KD;;;;EAIE,4BAAA;EACA,iBAAA;EDxKD;AC+KD;;EAEE,iBAAA;ED7KD;ACoLD;;EAEE,WAAA;EACA,YAAA;EDlLD;AC0LD;EACE,qBAAA;EDxLD;ACmMD;;EAEE,gCAAA;KAAA,6BAAA;UAAA,wBAAA;EACA,YAAA;EDjMD;AC0MD;;EAEE,cAAA;EDxMD;ACiND;EACE,+BAAA;EACA,8BAAA;EACA,iCAAA;EACA,yBAAA;ED/MD;ACwND;;EAEE,0BAAA;EDtND;AC6ND;EACE,2BAAA;EACA,eAAA;EACA,gCAAA;ED3ND;ACmOD;EACE,WAAA;EACA,YAAA;EDjOD;ACwOD;EACE,gBAAA;EDtOD;AC8OD;EACE,mBAAA;ED5OD;ACsPD;EACE,2BAAA;EACA,mBAAA;EDpPD;ACuPD;;EAEE,YAAA;EDrPD;AACD,sFAAqF;AE1ErF;EAnGI;;;IAGI,oCAAA;IACA,wBAAA;IACA,qCAAA;YAAA,6BAAA;IACA,8BAAA;IFgLL;EE7KC;;IAEI,4BAAA;IF+KL;EE5KC;IACI,8BAAA;IF8KL;EE3KC;IACI,+BAAA;IF6KL;EExKC;;IAEI,aAAA;IF0KL;EEvKC;;IAEI,wBAAA;IACA,0BAAA;IFyKL;EEtKC;IACI,6BAAA;IFwKL;EErKC;;IAEI,0BAAA;IFuKL;EEpKC;IACI,4BAAA;IFsKL;EEnKC;;;IAGI,YAAA;IACA,WAAA;IFqKL;EElKC;;IAEI,yBAAA;IFoKL;EE7JC;IACI,6BAAA;IF+JL;EE3JC;IACI,eAAA;IF6JL;EE3JC;;IAGQ,mCAAA;IF4JT;EEzJC;IACI,wBAAA;IF2JL;EExJC;IACI,sCAAA;IF0JL;EE3JC;;IAKQ,mCAAA;IF0JT;EEvJC;;IAGQ,mCAAA;IFwJT;EACF;AGpPD;EACE,qCAAA;EACA,uDAAA;EACA,6TAAA;EHsPD;AG/OD;EACE,oBAAA;EACA,UAAA;EACA,uBAAA;EACA,qCAAA;EACA,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,qCAAA;EACA,oCAAA;EHiPD;AG7OmC;EAAW,gBAAA;EHgP9C;AG/OmC;EAAW,gBAAA;EHkP9C;AGhPmC;;EAAW,kBAAA;EHoP9C;AGnPmC;EAAW,kBAAA;EHsP9C;AGrPmC;EAAW,kBAAA;EHwP9C;AGvPmC;EAAW,kBAAA;EH0P9C;AGzPmC;EAAW,kBAAA;EH4P9C;AG3PmC;EAAW,kBAAA;EH8P9C;AG7PmC;EAAW,kBAAA;EHgQ9C;AG/PmC;EAAW,kBAAA;EHkQ9C;AGjQmC;EAAW,kBAAA;EHoQ9C;AGnQmC;EAAW,kBAAA;EHsQ9C;AGrQmC;EAAW,kBAAA;EHwQ9C;AGvQmC;EAAW,kBAAA;EH0Q9C;AGzQmC;EAAW,kBAAA;EH4Q9C;AG3QmC;EAAW,kBAAA;EH8Q9C;AG7QmC;EAAW,kBAAA;EHgR9C;AG/QmC;EAAW,kBAAA;EHkR9C;AGjRmC;EAAW,kBAAA;EHoR9C;AGnRmC;EAAW,kBAAA;EHsR9C;AGrRmC;EAAW,kBAAA;EHwR9C;AGvRmC;EAAW,kBAAA;EH0R9C;AGzRmC;EAAW,kBAAA;EH4R9C;AG3RmC;EAAW,kBAAA;EH8R9C;AG7RmC;EAAW,kBAAA;EHgS9C;AG/RmC;EAAW,kBAAA;EHkS9C;AGjSmC;EAAW,kBAAA;EHoS9C;AGnSmC;EAAW,kBAAA;EHsS9C;AGrSmC;EAAW,kBAAA;EHwS9C;AGvSmC;EAAW,kBAAA;EH0S9C;AGzSmC;EAAW,kBAAA;EH4S9C;AG3SmC;EAAW,kBAAA;EH8S9C;AG7SmC;EAAW,kBAAA;EHgT9C;AG/SmC;EAAW,kBAAA;EHkT9C;AGjTmC;EAAW,kBAAA;EHoT9C;AGnTmC;EAAW,kBAAA;EHsT9C;AGrTmC;EAAW,kBAAA;EHwT9C;AGvTmC;EAAW,kBAAA;EH0T9C;AGzTmC;EAAW,kBAAA;EH4T9C;AG3TmC;EAAW,kBAAA;EH8T9C;AG7TmC;EAAW,kBAAA;EHgU9C;AG/TmC;EAAW,kBAAA;EHkU9C;AGjUmC;EAAW,kBAAA;EHoU9C;AGnUmC;EAAW,kBAAA;EHsU9C;AGrUmC;EAAW,kBAAA;EHwU9C;AGvUmC;EAAW,kBAAA;EH0U9C;AGzUmC;EAAW,kBAAA;EH4U9C;AG3UmC;EAAW,kBAAA;EH8U9C;AG7UmC;EAAW,kBAAA;EHgV9C;AG/UmC;EAAW,kBAAA;EHkV9C;AGjVmC;EAAW,kBAAA;EHoV9C;AGnVmC;EAAW,kBAAA;EHsV9C;AGrVmC;EAAW,kBAAA;EHwV9C;AGvVmC;EAAW,kBAAA;EH0V9C;AGzVmC;EAAW,kBAAA;EH4V9C;AG3VmC;EAAW,kBAAA;EH8V9C;AG7VmC;EAAW,kBAAA;EHgW9C;AG/VmC;EAAW,kBAAA;EHkW9C;AGjWmC;EAAW,kBAAA;EHoW9C;AGnWmC;EAAW,kBAAA;EHsW9C;AGrWmC;EAAW,kBAAA;EHwW9C;AGvWmC;EAAW,kBAAA;EH0W9C;AGzWmC;EAAW,kBAAA;EH4W9C;AG3WmC;EAAW,kBAAA;EH8W9C;AG7WmC;EAAW,kBAAA;EHgX9C;AG/WmC;EAAW,kBAAA;EHkX9C;AGjXmC;EAAW,kBAAA;EHoX9C;AGnXmC;EAAW,kBAAA;EHsX9C;AGrXmC;EAAW,kBAAA;EHwX9C;AGvXmC;EAAW,kBAAA;EH0X9C;AGzXmC;EAAW,kBAAA;EH4X9C;AG3XmC;EAAW,kBAAA;EH8X9C;AG7XmC;EAAW,kBAAA;EHgY9C;AG/XmC;EAAW,kBAAA;EHkY9C;AGjYmC;EAAW,kBAAA;EHoY9C;AGnYmC;EAAW,kBAAA;EHsY9C;AGrYmC;EAAW,kBAAA;EHwY9C;AGvYmC;EAAW,kBAAA;EH0Y9C;AGzYmC;EAAW,kBAAA;EH4Y9C;AG3YmC;EAAW,kBAAA;EH8Y9C;AG7YmC;EAAW,kBAAA;EHgZ9C;AG/YmC;EAAW,kBAAA;EHkZ9C;AGjZmC;EAAW,kBAAA;EHoZ9C;AGnZmC;EAAW,kBAAA;EHsZ9C;AGrZmC;EAAW,kBAAA;EHwZ9C;AGvZmC;EAAW,kBAAA;EH0Z9C;AGzZmC;EAAW,kBAAA;EH4Z9C;AG3ZmC;EAAW,kBAAA;EH8Z9C;AG7ZmC;EAAW,kBAAA;EHga9C;AG/ZmC;EAAW,kBAAA;EHka9C;AGjamC;EAAW,kBAAA;EHoa9C;AGnamC;EAAW,kBAAA;EHsa9C;AGramC;EAAW,kBAAA;EHwa9C;AGvamC;EAAW,kBAAA;EH0a9C;AGzamC;EAAW,kBAAA;EH4a9C;AG3amC;EAAW,kBAAA;EH8a9C;AG7amC;EAAW,kBAAA;EHgb9C;AG/amC;EAAW,kBAAA;EHkb9C;AGjbmC;EAAW,kBAAA;EHob9C;AGnbmC;EAAW,kBAAA;EHsb9C;AGrbmC;EAAW,kBAAA;EHwb9C;AGvbmC;EAAW,kBAAA;EH0b9C;AGzbmC;EAAW,kBAAA;EH4b9C;AG3bmC;EAAW,kBAAA;EH8b9C;AG7bmC;EAAW,kBAAA;EHgc9C;AG/bmC;EAAW,kBAAA;EHkc9C;AGjcmC;EAAW,kBAAA;EHoc9C;AGncmC;EAAW,kBAAA;EHsc9C;AGrcmC;EAAW,kBAAA;EHwc9C;AGvcmC;EAAW,kBAAA;EH0c9C;AGzcmC;EAAW,kBAAA;EH4c9C;AG3cmC;EAAW,kBAAA;EH8c9C;AG7cmC;EAAW,kBAAA;EHgd9C;AG/cmC;EAAW,kBAAA;EHkd9C;AGjdmC;EAAW,kBAAA;EHod9C;AGndmC;EAAW,kBAAA;EHsd9C;AGrdmC;EAAW,kBAAA;EHwd9C;AGvdmC;EAAW,kBAAA;EH0d9C;AGzdmC;EAAW,kBAAA;EH4d9C;AG3dmC;EAAW,kBAAA;EH8d9C;AG7dmC;EAAW,kBAAA;EHge9C;AG/dmC;EAAW,kBAAA;EHke9C;AGjemC;EAAW,kBAAA;EHoe9C;AGnemC;EAAW,kBAAA;EHse9C;AGremC;EAAW,kBAAA;EHwe9C;AGvemC;EAAW,kBAAA;EH0e9C;AGzemC;EAAW,kBAAA;EH4e9C;AG3emC;EAAW,kBAAA;EH8e9C;AG7emC;EAAW,kBAAA;EHgf9C;AG/emC;EAAW,kBAAA;EHkf9C;AGjfmC;EAAW,kBAAA;EHof9C;AGnfmC;EAAW,kBAAA;EHsf9C;AGrfmC;EAAW,kBAAA;EHwf9C;AGvfmC;EAAW,kBAAA;EH0f9C;AGzfmC;EAAW,kBAAA;EH4f9C;AG3fmC;EAAW,kBAAA;EH8f9C;AG7fmC;EAAW,kBAAA;EHggB9C;AG/fmC;EAAW,kBAAA;EHkgB9C;AGjgBmC;EAAW,kBAAA;EHogB9C;AGngBmC;EAAW,kBAAA;EHsgB9C;AGrgBmC;EAAW,kBAAA;EHwgB9C;AGvgBmC;EAAW,kBAAA;EH0gB9C;AGzgBmC;EAAW,kBAAA;EH4gB9C;AG3gBmC;EAAW,kBAAA;EH8gB9C;AG7gBmC;EAAW,kBAAA;EHghB9C;AG/gBmC;EAAW,kBAAA;EHkhB9C;AGjhBmC;EAAW,kBAAA;EHohB9C;AGnhBmC;EAAW,kBAAA;EHshB9C;AGrhBmC;EAAW,kBAAA;EHwhB9C;AGvhBmC;EAAW,kBAAA;EH0hB9C;AGzhBmC;EAAW,kBAAA;EH4hB9C;AG3hBmC;EAAW,kBAAA;EH8hB9C;AG7hBmC;EAAW,kBAAA;EHgiB9C;AG/hBmC;EAAW,kBAAA;EHkiB9C;AGjiBmC;EAAW,kBAAA;EHoiB9C;AGniBmC;EAAW,kBAAA;EHsiB9C;AGriBmC;EAAW,kBAAA;EHwiB9C;AGviBmC;EAAW,kBAAA;EH0iB9C;AGziBmC;EAAW,kBAAA;EH4iB9C;AG3iBmC;EAAW,kBAAA;EH8iB9C;AG7iBmC;EAAW,kBAAA;EHgjB9C;AG/iBmC;EAAW,kBAAA;EHkjB9C;AGjjBmC;EAAW,kBAAA;EHojB9C;AGnjBmC;EAAW,kBAAA;EHsjB9C;AGrjBmC;EAAW,kBAAA;EHwjB9C;AGvjBmC;EAAW,kBAAA;EH0jB9C;AGzjBmC;EAAW,kBAAA;EH4jB9C;AG3jBmC;EAAW,kBAAA;EH8jB9C;AG7jBmC;EAAW,kBAAA;EHgkB9C;AG/jBmC;EAAW,kBAAA;EHkkB9C;AGjkBmC;EAAW,kBAAA;EHokB9C;AGnkBmC;EAAW,kBAAA;EHskB9C;AGrkBmC;EAAW,kBAAA;EHwkB9C;AGvkBmC;EAAW,kBAAA;EH0kB9C;AGzkBmC;EAAW,kBAAA;EH4kB9C;AG3kBmC;EAAW,kBAAA;EH8kB9C;AG7kBmC;EAAW,kBAAA;EHglB9C;AG/kBmC;EAAW,kBAAA;EHklB9C;AGjlBmC;EAAW,kBAAA;EHolB9C;AGnlBmC;EAAW,kBAAA;EHslB9C;AGrlBmC;EAAW,kBAAA;EHwlB9C;AGvlBmC;EAAW,kBAAA;EH0lB9C;AGzlBmC;EAAW,kBAAA;EH4lB9C;AG3lBmC;EAAW,kBAAA;EH8lB9C;AG7lBmC;EAAW,kBAAA;EHgmB9C;AG/lBmC;EAAW,kBAAA;EHkmB9C;AGjmBmC;EAAW,kBAAA;EHomB9C;AGnmBmC;EAAW,kBAAA;EHsmB9C;AGrmBmC;EAAW,kBAAA;EHwmB9C;AGvmBmC;EAAW,kBAAA;EH0mB9C;AGzmBmC;EAAW,kBAAA;EH4mB9C;AG3mBmC;EAAW,kBAAA;EH8mB9C;AG7mBmC;EAAW,kBAAA;EHgnB9C;AG/mBmC;EAAW,kBAAA;EHknB9C;AGjnBmC;EAAW,kBAAA;EHonB9C;AGnnBmC;EAAW,kBAAA;EHsnB9C;AGrnBmC;EAAW,kBAAA;EHwnB9C;AGvnBmC;EAAW,kBAAA;EH0nB9C;AGznBmC;EAAW,kBAAA;EH4nB9C;AG3nBmC;EAAW,kBAAA;EH8nB9C;AI71BD;ECgEE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELgyBT;AI/1BD;;EC6DE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELsyBT;AI71BD;EACE,iBAAA;EACA,+CAAA;EJ+1BD;AI51BD;EACE,6DAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EJ81BD;AI11BD;;;;EAIE,sBAAA;EACA,oBAAA;EACA,sBAAA;EJ41BD;AIt1BD;EACE,gBAAA;EACA,uBAAA;EJw1BD;AIt1BC;;EAEE,gBAAA;EACA,4BAAA;EJw1BH;AIr1BC;EErDA,sBAAA;EAEA,4CAAA;EACA,sBAAA;EN44BD;AI/0BD;EACE,WAAA;EJi1BD;AI30BD;EACE,wBAAA;EJ60BD;AIz0BD;;;;;EGvEE,gBAAA;EACA,iBAAA;EACA,cAAA;EPu5BD;AI70BD;EACE,oBAAA;EJ+0BD;AIz0BD;EACE,cAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EC6FA,0CAAA;EACK,qCAAA;EACG,kCAAA;EEvLR,uBAAA;EACA,iBAAA;EACA,cAAA;EPu6BD;AIz0BD;EACE,oBAAA;EJ20BD;AIr0BD;EACE,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,+BAAA;EJu0BD;AI/zBD;EACE,oBAAA;EACA,YAAA;EACA,aAAA;EACA,cAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,WAAA;EJi0BD;AIzzBC;;EAEE,kBAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA;EACA,mBAAA;EACA,YAAA;EJ2zBH;AQt8BD;;;;;;;;;;;;EAEE,sBAAA;EACA,kBAAA;EACA,kBAAA;EACA,gBAAA;ERk9BD;AQv9BD;;;;;;;;;;;;;;;;;;;;;;;;EASI,qBAAA;EACA,gBAAA;EACA,gBAAA;ERw+BH;AQp+BD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERy+BD;AQ7+BD;;;;;;;;;;;;EAQI,gBAAA;ERm/BH;AQh/BD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERq/BD;AQz/BD;;;;;;;;;;;;EAQI,gBAAA;ER+/BH;AQ3/BD;;EAAU,iBAAA;ER+/BT;AQ9/BD;;EAAU,iBAAA;ERkgCT;AQjgCD;;EAAU,iBAAA;ERqgCT;AQpgCD;;EAAU,iBAAA;ERwgCT;AQvgCD;;EAAU,iBAAA;ER2gCT;AQ1gCD;;EAAU,iBAAA;ER8gCT;AQxgCD;EACE,kBAAA;ER0gCD;AQvgCD;EACE,qBAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;ERygCD;AQpgCD;EAAA;IAFI,iBAAA;IR0gCD;EACF;AQlgCD;;EAEE,gBAAA;ERogCD;AQjgCD;;EAEE,2BAAA;EACA,eAAA;ERmgCD;AQ//BD;EAAuB,kBAAA;ERkgCtB;AQjgCD;EAAuB,mBAAA;ERogCtB;AQngCD;EAAuB,oBAAA;ERsgCtB;AQrgCD;EAAuB,qBAAA;ERwgCtB;AQvgCD;EAAuB,qBAAA;ER0gCtB;AQvgCD;EAAuB,2BAAA;ER0gCtB;AQzgCD;EAAuB,2BAAA;ER4gCtB;AQ3gCD;EAAuB,4BAAA;ER8gCtB;AQ3gCD;EACE,gBAAA;ER6gCD;AQ3gCD;ECrGE,gBAAA;ETmnCD;ASlnCC;EACE,gBAAA;ETonCH;AQ9gCD;ECxGE,gBAAA;ETynCD;ASxnCC;EACE,gBAAA;ET0nCH;AQjhCD;EC3GE,gBAAA;ET+nCD;AS9nCC;EACE,gBAAA;ETgoCH;AQphCD;EC9GE,gBAAA;ETqoCD;ASpoCC;EACE,gBAAA;ETsoCH;AQvhCD;ECjHE,gBAAA;ET2oCD;AS1oCC;EACE,gBAAA;ET4oCH;AQthCD;EAGE,aAAA;EE3HA,2BAAA;EVkpCD;AUjpCC;EACE,2BAAA;EVmpCH;AQvhCD;EE9HE,2BAAA;EVwpCD;AUvpCC;EACE,2BAAA;EVypCH;AQ1hCD;EEjIE,2BAAA;EV8pCD;AU7pCC;EACE,2BAAA;EV+pCH;AQ7hCD;EEpIE,2BAAA;EVoqCD;AUnqCC;EACE,2BAAA;EVqqCH;AQhiCD;EEvIE,2BAAA;EV0qCD;AUzqCC;EACE,2BAAA;EV2qCH;AQ9hCD;EACE,qBAAA;EACA,qBAAA;EACA,kCAAA;ERgiCD;AQxhCD;;EAEE,eAAA;EACA,qBAAA;ER0hCD;AQ7hCD;;;;EAMI,kBAAA;ER6hCH;AQthCD;EACE,iBAAA;EACA,kBAAA;ERwhCD;AQphCD;EALE,iBAAA;EACA,kBAAA;EAMA,mBAAA;ERuhCD;AQzhCD;EAKI,uBAAA;EACA,mBAAA;EACA,oBAAA;ERuhCH;AQlhCD;EACE,eAAA;EACA,qBAAA;ERohCD;AQlhCD;;EAEE,yBAAA;ERohCD;AQlhCD;EACE,mBAAA;ERohCD;AQlhCD;EACE,gBAAA;ERohCD;AQ3/BD;EAAA;IAVM,aAAA;IACA,cAAA;IACA,aAAA;IACA,mBAAA;IGtNJ,kBAAA;IACA,yBAAA;IACA,qBAAA;IXguCC;EQrgCH;IAHM,oBAAA;IR2gCH;EACF;AQlgCD;;EAGE,cAAA;EACA,mCAAA;ERmgCD;AQjgCD;EACE,gBAAA;EACA,2BAAA;ERmgCD;AQ//BD;EACE,oBAAA;EACA,kBAAA;EACA,mBAAA;EACA,gCAAA;ERigCD;AQ5/BG;;;EACE,kBAAA;ERggCL;AQ1gCD;;;EAmBI,gBAAA;EACA,gBAAA;EACA,yBAAA;EACA,gBAAA;ER4/BH;AQ1/BG;;;EACE,wBAAA;ER8/BL;AQt/BD;;EAEE,qBAAA;EACA,iBAAA;EACA,iCAAA;EACA,gBAAA;EACA,mBAAA;ERw/BD;AQl/BG;;;;;;EAAW,aAAA;ER0/Bd;AQz/BG;;;;;;EACE,wBAAA;ERggCL;AQ1/BD;EACE,qBAAA;EACA,oBAAA;EACA,yBAAA;ER4/BD;AYlyCD;;;;EAIE,gEAAA;EZoyCD;AYhyCD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EZkyCD;AY9xCD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EACA,wDAAA;UAAA,gDAAA;EZgyCD;AYtyCD;EASI,YAAA;EACA,iBAAA;EACA,mBAAA;EACA,0BAAA;UAAA,kBAAA;EZgyCH;AY3xCD;EACE,gBAAA;EACA,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,uBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EZ6xCD;AYxyCD;EAeI,YAAA;EACA,oBAAA;EACA,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,kBAAA;EZ4xCH;AYvxCD;EACE,mBAAA;EACA,oBAAA;EZyxCD;Aan1CD;ECHE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;Edy1CD;Aan1CC;EAAA;IAFE,cAAA;Iby1CD;EACF;Aar1CC;EAAA;IAFE,cAAA;Ib21CD;EACF;Aav1CD;EAAA;IAFI,eAAA;Ib61CD;EACF;Aap1CD;ECvBE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;Ed82CD;Aaj1CD;ECvBE,oBAAA;EACA,qBAAA;Ed22CD;Ae32CG;EACE,oBAAA;EAEA,iBAAA;EAEA,oBAAA;EACA,qBAAA;Ef22CL;Ae31CG;EACE,aAAA;Ef61CL;Aet1CC;EACE,aAAA;Efw1CH;Aez1CC;EACE,qBAAA;Ef21CH;Ae51CC;EACE,qBAAA;Ef81CH;Ae/1CC;EACE,YAAA;Efi2CH;Ael2CC;EACE,qBAAA;Efo2CH;Aer2CC;EACE,qBAAA;Efu2CH;Aex2CC;EACE,YAAA;Ef02CH;Ae32CC;EACE,qBAAA;Ef62CH;Ae92CC;EACE,qBAAA;Efg3CH;Aej3CC;EACE,YAAA;Efm3CH;Aep3CC;EACE,qBAAA;Efs3CH;Aev3CC;EACE,oBAAA;Efy3CH;Ae32CC;EACE,aAAA;Ef62CH;Ae92CC;EACE,qBAAA;Efg3CH;Aej3CC;EACE,qBAAA;Efm3CH;Aep3CC;EACE,YAAA;Efs3CH;Aev3CC;EACE,qBAAA;Efy3CH;Ae13CC;EACE,qBAAA;Ef43CH;Ae73CC;EACE,YAAA;Ef+3CH;Aeh4CC;EACE,qBAAA;Efk4CH;Aen4CC;EACE,qBAAA;Efq4CH;Aet4CC;EACE,YAAA;Efw4CH;Aez4CC;EACE,qBAAA;Ef24CH;Ae54CC;EACE,oBAAA;Ef84CH;Ae14CC;EACE,aAAA;Ef44CH;Ae55CC;EACE,YAAA;Ef85CH;Ae/5CC;EACE,oBAAA;Efi6CH;Ael6CC;EACE,oBAAA;Efo6CH;Aer6CC;EACE,WAAA;Efu6CH;Aex6CC;EACE,oBAAA;Ef06CH;Ae36CC;EACE,oBAAA;Ef66CH;Ae96CC;EACE,WAAA;Efg7CH;Aej7CC;EACE,oBAAA;Efm7CH;Aep7CC;EACE,oBAAA;Efs7CH;Aev7CC;EACE,WAAA;Efy7CH;Ae17CC;EACE,oBAAA;Ef47CH;Ae77CC;EACE,mBAAA;Ef+7CH;Ae37CC;EACE,YAAA;Ef67CH;Ae/6CC;EACE,mBAAA;Efi7CH;Ael7CC;EACE,2BAAA;Efo7CH;Aer7CC;EACE,2BAAA;Efu7CH;Aex7CC;EACE,kBAAA;Ef07CH;Ae37CC;EACE,2BAAA;Ef67CH;Ae97CC;EACE,2BAAA;Efg8CH;Aej8CC;EACE,kBAAA;Efm8CH;Aep8CC;EACE,2BAAA;Efs8CH;Aev8CC;EACE,2BAAA;Efy8CH;Ae18CC;EACE,kBAAA;Ef48CH;Ae78CC;EACE,2BAAA;Ef+8CH;Aeh9CC;EACE,0BAAA;Efk9CH;Aen9CC;EACE,iBAAA;Efq9CH;Aaz9CD;EE9BI;IACE,aAAA;If0/CH;Een/CD;IACE,aAAA;Ifq/CD;Eet/CD;IACE,qBAAA;Ifw/CD;Eez/CD;IACE,qBAAA;If2/CD;Ee5/CD;IACE,YAAA;If8/CD;Ee//CD;IACE,qBAAA;IfigDD;EelgDD;IACE,qBAAA;IfogDD;EergDD;IACE,YAAA;IfugDD;EexgDD;IACE,qBAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,YAAA;IfghDD;EejhDD;IACE,qBAAA;IfmhDD;EephDD;IACE,oBAAA;IfshDD;EexgDD;IACE,aAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,qBAAA;IfghDD;EejhDD;IACE,YAAA;IfmhDD;EephDD;IACE,qBAAA;IfshDD;EevhDD;IACE,qBAAA;IfyhDD;Ee1hDD;IACE,YAAA;If4hDD;Ee7hDD;IACE,qBAAA;If+hDD;EehiDD;IACE,qBAAA;IfkiDD;EeniDD;IACE,YAAA;IfqiDD;EetiDD;IACE,qBAAA;IfwiDD;EeziDD;IACE,oBAAA;If2iDD;EeviDD;IACE,aAAA;IfyiDD;EezjDD;IACE,YAAA;If2jDD;Ee5jDD;IACE,oBAAA;If8jDD;Ee/jDD;IACE,oBAAA;IfikDD;EelkDD;IACE,WAAA;IfokDD;EerkDD;IACE,oBAAA;IfukDD;EexkDD;IACE,oBAAA;If0kDD;Ee3kDD;IACE,WAAA;If6kDD;Ee9kDD;IACE,oBAAA;IfglDD;EejlDD;IACE,oBAAA;IfmlDD;EeplDD;IACE,WAAA;IfslDD;EevlDD;IACE,oBAAA;IfylDD;Ee1lDD;IACE,mBAAA;If4lDD;EexlDD;IACE,YAAA;If0lDD;Ee5kDD;IACE,mBAAA;If8kDD;Ee/kDD;IACE,2BAAA;IfilDD;EellDD;IACE,2BAAA;IfolDD;EerlDD;IACE,kBAAA;IfulDD;EexlDD;IACE,2BAAA;If0lDD;Ee3lDD;IACE,2BAAA;If6lDD;Ee9lDD;IACE,kBAAA;IfgmDD;EejmDD;IACE,2BAAA;IfmmDD;EepmDD;IACE,2BAAA;IfsmDD;EevmDD;IACE,kBAAA;IfymDD;Ee1mDD;IACE,2BAAA;If4mDD;Ee7mDD;IACE,0BAAA;If+mDD;EehnDD;IACE,iBAAA;IfknDD;EACF;Aa9mDD;EEvCI;IACE,aAAA;IfwpDH;EejpDD;IACE,aAAA;IfmpDD;EeppDD;IACE,qBAAA;IfspDD;EevpDD;IACE,qBAAA;IfypDD;Ee1pDD;IACE,YAAA;If4pDD;Ee7pDD;IACE,qBAAA;If+pDD;EehqDD;IACE,qBAAA;IfkqDD;EenqDD;IACE,YAAA;IfqqDD;EetqDD;IACE,qBAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,YAAA;If8qDD;Ee/qDD;IACE,qBAAA;IfirDD;EelrDD;IACE,oBAAA;IforDD;EetqDD;IACE,aAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,qBAAA;If8qDD;Ee/qDD;IACE,YAAA;IfirDD;EelrDD;IACE,qBAAA;IforDD;EerrDD;IACE,qBAAA;IfurDD;EexrDD;IACE,YAAA;If0rDD;Ee3rDD;IACE,qBAAA;If6rDD;Ee9rDD;IACE,qBAAA;IfgsDD;EejsDD;IACE,YAAA;IfmsDD;EepsDD;IACE,qBAAA;IfssDD;EevsDD;IACE,oBAAA;IfysDD;EersDD;IACE,aAAA;IfusDD;EevtDD;IACE,YAAA;IfytDD;Ee1tDD;IACE,oBAAA;If4tDD;Ee7tDD;IACE,oBAAA;If+tDD;EehuDD;IACE,WAAA;IfkuDD;EenuDD;IACE,oBAAA;IfquDD;EetuDD;IACE,oBAAA;IfwuDD;EezuDD;IACE,WAAA;If2uDD;Ee5uDD;IACE,oBAAA;If8uDD;Ee/uDD;IACE,oBAAA;IfivDD;EelvDD;IACE,WAAA;IfovDD;EervDD;IACE,oBAAA;IfuvDD;EexvDD;IACE,mBAAA;If0vDD;EetvDD;IACE,YAAA;IfwvDD;Ee1uDD;IACE,mBAAA;If4uDD;Ee7uDD;IACE,2BAAA;If+uDD;EehvDD;IACE,2BAAA;IfkvDD;EenvDD;IACE,kBAAA;IfqvDD;EetvDD;IACE,2BAAA;IfwvDD;EezvDD;IACE,2BAAA;If2vDD;Ee5vDD;IACE,kBAAA;If8vDD;Ee/vDD;IACE,2BAAA;IfiwDD;EelwDD;IACE,2BAAA;IfowDD;EerwDD;IACE,kBAAA;IfuwDD;EexwDD;IACE,2BAAA;If0wDD;Ee3wDD;IACE,0BAAA;If6wDD;Ee9wDD;IACE,iBAAA;IfgxDD;EACF;AarwDD;EE9CI;IACE,aAAA;IfszDH;Ee/yDD;IACE,aAAA;IfizDD;EelzDD;IACE,qBAAA;IfozDD;EerzDD;IACE,qBAAA;IfuzDD;EexzDD;IACE,YAAA;If0zDD;Ee3zDD;IACE,qBAAA;If6zDD;Ee9zDD;IACE,qBAAA;Ifg0DD;Eej0DD;IACE,YAAA;Ifm0DD;Eep0DD;IACE,qBAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,YAAA;If40DD;Ee70DD;IACE,qBAAA;If+0DD;Eeh1DD;IACE,oBAAA;Ifk1DD;Eep0DD;IACE,aAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,qBAAA;If40DD;Ee70DD;IACE,YAAA;If+0DD;Eeh1DD;IACE,qBAAA;Ifk1DD;Een1DD;IACE,qBAAA;Ifq1DD;Eet1DD;IACE,YAAA;Ifw1DD;Eez1DD;IACE,qBAAA;If21DD;Ee51DD;IACE,qBAAA;If81DD;Ee/1DD;IACE,YAAA;Ifi2DD;Eel2DD;IACE,qBAAA;Ifo2DD;Eer2DD;IACE,oBAAA;Ifu2DD;Een2DD;IACE,aAAA;Ifq2DD;Eer3DD;IACE,YAAA;Ifu3DD;Eex3DD;IACE,oBAAA;If03DD;Ee33DD;IACE,oBAAA;If63DD;Ee93DD;IACE,WAAA;Ifg4DD;Eej4DD;IACE,oBAAA;Ifm4DD;Eep4DD;IACE,oBAAA;Ifs4DD;Eev4DD;IACE,WAAA;Ify4DD;Ee14DD;IACE,oBAAA;If44DD;Ee74DD;IACE,oBAAA;If+4DD;Eeh5DD;IACE,WAAA;Ifk5DD;Een5DD;IACE,oBAAA;Ifq5DD;Eet5DD;IACE,mBAAA;Ifw5DD;Eep5DD;IACE,YAAA;Ifs5DD;Eex4DD;IACE,mBAAA;If04DD;Ee34DD;IACE,2BAAA;If64DD;Ee94DD;IACE,2BAAA;Ifg5DD;Eej5DD;IACE,kBAAA;Ifm5DD;Eep5DD;IACE,2BAAA;Ifs5DD;Eev5DD;IACE,2BAAA;Ify5DD;Ee15DD;IACE,kBAAA;If45DD;Ee75DD;IACE,2BAAA;If+5DD;Eeh6DD;IACE,2BAAA;Ifk6DD;Een6DD;IACE,kBAAA;Ifq6DD;Eet6DD;IACE,2BAAA;Ifw6DD;Eez6DD;IACE,0BAAA;If26DD;Ee56DD;IACE,iBAAA;If86DD;EACF;AgBl/DD;EACE,+BAAA;EhBo/DD;AgBl/DD;EACE,kBAAA;EACA,qBAAA;EACA,gBAAA;EACA,kBAAA;EhBo/DD;AgBl/DD;EACE,kBAAA;EhBo/DD;AgB9+DD;EACE,aAAA;EACA,iBAAA;EACA,qBAAA;EhBg/DD;AgBn/DD;;;;;;EAWQ,cAAA;EACA,yBAAA;EACA,qBAAA;EACA,+BAAA;EhBg/DP;AgB9/DD;EAoBI,wBAAA;EACA,kCAAA;EhB6+DH;AgBlgED;;;;;;EA8BQ,eAAA;EhB4+DP;AgB1gED;EAoCI,+BAAA;EhBy+DH;AgB7gED;EAyCI,2BAAA;EhBu+DH;AgBh+DD;;;;;;EAOQ,cAAA;EhBi+DP;AgBt9DD;EACE,2BAAA;EhBw9DD;AgBz9DD;;;;;;EAQQ,2BAAA;EhBy9DP;AgBj+DD;;EAeM,0BAAA;EhBs9DL;AgB58DD;EAEI,2BAAA;EhB68DH;AgBp8DD;EAEI,2BAAA;EhBq8DH;AgB57DD;EACE,kBAAA;EACA,aAAA;EACA,uBAAA;EhB87DD;AgBz7DG;;EACE,kBAAA;EACA,aAAA;EACA,qBAAA;EhB47DL;AiBxkEC;;;;;;;;;;;;EAOI,2BAAA;EjB+kEL;AiBzkEC;;;;;EAMI,2BAAA;EjB0kEL;AiB7lEC;;;;;;;;;;;;EAOI,2BAAA;EjBomEL;AiB9lEC;;;;;EAMI,2BAAA;EjB+lEL;AiBlnEC;;;;;;;;;;;;EAOI,2BAAA;EjBynEL;AiBnnEC;;;;;EAMI,2BAAA;EjBonEL;AiBvoEC;;;;;;;;;;;;EAOI,2BAAA;EjB8oEL;AiBxoEC;;;;;EAMI,2BAAA;EjByoEL;AiB5pEC;;;;;;;;;;;;EAOI,2BAAA;EjBmqEL;AiB7pEC;;;;;EAMI,2BAAA;EjB8pEL;AgB5gED;EACE,kBAAA;EACA,mBAAA;EhB8gED;AgBj9DD;EAAA;IA1DI,aAAA;IACA,qBAAA;IACA,oBAAA;IACA,8CAAA;IACA,2BAAA;IhB+gED;EgBz9DH;IAlDM,kBAAA;IhB8gEH;EgB59DH;;;;;;IAzCY,qBAAA;IhB6gET;EgBp+DH;IAjCM,WAAA;IhBwgEH;EgBv+DH;;;;;;IAxBY,gBAAA;IhBugET;EgB/+DH;;;;;;IApBY,iBAAA;IhB2gET;EgBv/DH;;;;IAPY,kBAAA;IhBogET;EACF;AkB9tED;EACE,YAAA;EACA,WAAA;EACA,WAAA;EAIA,cAAA;ElB6tED;AkB1tED;EACE,gBAAA;EACA,aAAA;EACA,YAAA;EACA,qBAAA;EACA,iBAAA;EACA,sBAAA;EACA,gBAAA;EACA,WAAA;EACA,kCAAA;ElB4tED;AkBztED;EACE,uBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;ElB2tED;AkBhtED;Eb4BE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELurET;AkBhtED;;EAEE,iBAAA;EACA,oBAAA;EACA,qBAAA;ElBktED;AkB9sED;EACE,gBAAA;ElBgtED;AkB5sED;EACE,gBAAA;EACA,aAAA;ElB8sED;AkB1sED;;EAEE,cAAA;ElB4sED;AkBxsED;;;EZxEE,sBAAA;EAEA,4CAAA;EACA,sBAAA;ENoxED;AkBxsED;EACE,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;ElB0sED;AkBhrED;EACE,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EACA,wBAAA;EACA,2BAAA;EACA,oBAAA;EbzDA,0DAAA;EACQ,kDAAA;EAyHR,wFAAA;EACK,2EAAA;EACG,wEAAA;ELonET;AmB5vEC;EACE,uBAAA;EACA,YAAA;EdUF,wFAAA;EACQ,gFAAA;ELqvET;AKptEC;EACE,gBAAA;EACA,YAAA;ELstEH;AKptEC;EAA0B,gBAAA;ELutE3B;AKttEC;EAAgC,gBAAA;ELytEjC;AkBxrEC;;;EAGE,qBAAA;EACA,2BAAA;EACA,YAAA;ElB0rEH;AkBtrEC;EACE,cAAA;ElBwrEH;AkB5qED;EACE,0BAAA;ElB8qED;AkB7oED;EArBE;;;;IAIE,mBAAA;IlBqqED;EkBnqED;;;;IAIE,mBAAA;IlBqqED;EkBnqED;;;;IAIE,mBAAA;IlBqqED;EACF;AkB5pED;EACE,qBAAA;ElB8pED;AkBtpED;;EAEE,oBAAA;EACA,gBAAA;EACA,kBAAA;EACA,qBAAA;ElBwpED;AkB7pED;;EAQI,kBAAA;EACA,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,iBAAA;ElBypEH;AkBtpED;;;;EAIE,oBAAA;EACA,oBAAA;EACA,oBAAA;ElBwpED;AkBrpED;;EAEE,kBAAA;ElBupED;AkBnpED;;EAEE,uBAAA;EACA,oBAAA;EACA,kBAAA;EACA,wBAAA;EACA,qBAAA;EACA,iBAAA;ElBqpED;AkBnpED;;EAEE,eAAA;EACA,mBAAA;ElBqpED;AkB5oEC;;;;;;EAGE,qBAAA;ElBipEH;AkB3oEC;;;;EAEE,qBAAA;ElB+oEH;AkBzoEC;;;;EAGI,qBAAA;ElB4oEL;AkBjoED;EAEE,kBAAA;EACA,qBAAA;EAEA,kBAAA;ElBioED;AkB/nEC;;EAEE,iBAAA;EACA,kBAAA;ElBioEH;AkBvnED;;ECnPE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnB82ED;AmB52EC;;EACE,cAAA;EACA,mBAAA;EnB+2EH;AmB52EC;;;;EAEE,cAAA;EnBg3EH;AkBroED;;ECxPE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;EnBi4ED;AmB/3EC;;EACE,cAAA;EACA,mBAAA;EnBk4EH;AmB/3EC;;;;EAEE,cAAA;EnBm4EH;AkB9oED;EAEE,oBAAA;ElB+oED;AkBjpED;EAMI,uBAAA;ElB8oEH;AkB1oED;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,YAAA;EACA,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oBAAA;EACA,sBAAA;ElB4oED;AkB1oED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB4oED;AkB1oED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB4oED;AkBxoED;;;;;;;;;;ECxVI,gBAAA;EnB4+EH;AkBppED;ECpVI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;EL67ET;AmB3+EG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELk8ET;AkB9pED;EC1UI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnB2+EH;AkBnqED;ECpUI,gBAAA;EnB0+EH;AkBnqED;;;;;;;;;;EC3VI,gBAAA;EnB0gFH;AkB/qED;ECvVI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;EL29ET;AmBzgFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELg+ET;AkBzrED;EC7UI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBygFH;AkB9rED;ECvUI,gBAAA;EnBwgFH;AkB9rED;;;;;;;;;;EC9VI,gBAAA;EnBwiFH;AkB1sED;EC1VI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;ELy/ET;AmBviFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;EL8/ET;AkBptED;EChVI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBuiFH;AkBztED;EC1UI,gBAAA;EnBsiFH;AkBrtEC;EACG,WAAA;ElButEJ;AkBrtEC;EACG,QAAA;ElButEJ;AkB7sED;EACE,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;ElB+sED;AkB3nED;EAAA;IA/DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlB8rEH;EkBjoEH;IAxDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB4rEH;EkBtoEH;IAjDM,uBAAA;IlB0rEH;EkBzoEH;IA7CM,uBAAA;IACA,wBAAA;IlByrEH;EkB7oEH;;;IAvCQ,aAAA;IlByrEL;EkBlpEH;IAjCM,aAAA;IlBsrEH;EkBrpEH;IA7BM,kBAAA;IACA,wBAAA;IlBqrEH;EkBzpEH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlBirEH;EkBhqEH;;IAdQ,iBAAA;IlBkrEL;EkBpqEH;;IATM,oBAAA;IACA,gBAAA;IlBirEH;EkBzqEH;IAHM,QAAA;IlB+qEH;EACF;AkBrqED;;;;EASI,eAAA;EACA,kBAAA;EACA,kBAAA;ElBkqEH;AkB7qED;;EAiBI,kBAAA;ElBgqEH;AkBjrED;EJrdE,oBAAA;EACA,qBAAA;EdyoFD;AkBlpEC;EAAA;IANI,mBAAA;IACA,kBAAA;IACA,kBAAA;IlB4pEH;EACF;AkB5rED;EAwCI,aAAA;ElBupEH;AkB1oEC;EAAA;IAHM,qBAAA;IlBipEL;EACF;AkBxoEC;EAAA;IAHM,kBAAA;IlB+oEL;EACF;AoBrqFD;EACE,uBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,wBAAA;EACA,gCAAA;MAAA,4BAAA;EACA,iBAAA;EACA,wBAAA;EACA,+BAAA;EACA,qBAAA;EC6BA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,oBAAA;EhB4KA,2BAAA;EACG,wBAAA;EACC,uBAAA;EACI,mBAAA;ELg+ET;AoBxqFG;;;;;;EdrBF,sBAAA;EAEA,4CAAA;EACA,sBAAA;ENosFD;AoB5qFC;;;EAGE,gBAAA;EACA,uBAAA;EpB8qFH;AoB3qFC;;EAEE,YAAA;EACA,wBAAA;Ef2BF,0DAAA;EACQ,kDAAA;ELmpFT;AoB3qFC;;;EAGE,qBAAA;EACA,sBAAA;EE9CF,eAAA;EAGA,2BAAA;EjB8DA,0BAAA;EACQ,kBAAA;EL6pFT;AoBvqFD;ECrDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB+tFD;AqB7tFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB+tFP;AqB7tFC;;;EAGE,wBAAA;ErB+tFH;AqB1tFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBwuFT;AoBhtFD;ECnBI,gBAAA;EACA,2BAAA;ErBsuFH;AoBjtFD;ECxDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB4wFD;AqB1wFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB4wFP;AqB1wFC;;;EAGE,wBAAA;ErB4wFH;AqBvwFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBqxFT;AoB1vFD;ECtBI,gBAAA;EACA,2BAAA;ErBmxFH;AoB1vFD;EC5DE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErByzFD;AqBvzFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErByzFP;AqBvzFC;;;EAGE,wBAAA;ErByzFH;AqBpzFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBk0FT;AoBnyFD;EC1BI,gBAAA;EACA,2BAAA;ErBg0FH;AoBnyFD;EChEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBs2FD;AqBp2FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBs2FP;AqBp2FC;;;EAGE,wBAAA;ErBs2FH;AqBj2FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB+2FT;AoB50FD;EC9BI,gBAAA;EACA,2BAAA;ErB62FH;AoB50FD;ECpEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBm5FD;AqBj5FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBm5FP;AqBj5FC;;;EAGE,wBAAA;ErBm5FH;AqB94FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB45FT;AoBr3FD;EClCI,gBAAA;EACA,2BAAA;ErB05FH;AoBr3FD;ECxEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBg8FD;AqB97FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBg8FP;AqB97FC;;;EAGE,wBAAA;ErBg8FH;AqB37FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBy8FT;AoB95FD;ECtCI,gBAAA;EACA,2BAAA;ErBu8FH;AoBz5FD;EACE,gBAAA;EACA,qBAAA;EACA,kBAAA;EpB25FD;AoBz5FC;;;;;EAKE,+BAAA;Ef7BF,0BAAA;EACQ,kBAAA;ELy7FT;AoB15FC;;;;EAIE,2BAAA;EpB45FH;AoB15FC;;EAEE,gBAAA;EACA,4BAAA;EACA,+BAAA;EpB45FH;AoBx5FG;;;;EAEE,gBAAA;EACA,uBAAA;EpB45FL;AoBn5FD;;EC/EE,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;ErBs+FD;AoBt5FD;;ECnFE,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErB6+FD;AoBz5FD;;ECvFE,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErBo/FD;AoBx5FD;EACE,gBAAA;EACA,aAAA;EpB05FD;AoBt5FD;EACE,iBAAA;EpBw5FD;AoBj5FC;;;EACE,aAAA;EpBq5FH;AuBziGD;EACE,YAAA;ElBoLA,0CAAA;EACK,qCAAA;EACG,kCAAA;ELw3FT;AuB5iGC;EACE,YAAA;EvB8iGH;AuB1iGD;EACE,eAAA;EACA,oBAAA;EvB4iGD;AuB1iGC;EAAY,gBAAA;EAAgB,qBAAA;EvB8iG7B;AuB7iGC;EAAY,oBAAA;EvBgjGb;AuB/iGC;EAAY,0BAAA;EvBkjGb;AuB/iGD;EACE,oBAAA;EACA,WAAA;EACA,kBAAA;ElBsKA,iDAAA;EACQ,4CAAA;KAAA,yCAAA;EAOR,oCAAA;EACQ,+BAAA;KAAA,4BAAA;EAGR,0CAAA;EACQ,qCAAA;KAAA,kCAAA;ELo4FT;AwB9kGD;EACE,uBAAA;EACA,UAAA;EACA,WAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;EACA,qCAAA;EACA,oCAAA;ExBglGD;AwB5kGD;EACE,oBAAA;ExB8kGD;AwB1kGD;EACE,YAAA;ExB4kGD;AwBxkGD;EACE,oBAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,2BAAA;EACA,2BAAA;EACA,uCAAA;EACA,oBAAA;EnBwBA,qDAAA;EACQ,6CAAA;EmBvBR,sCAAA;UAAA,8BAAA;ExB2kGD;AwBtkGC;EACE,UAAA;EACA,YAAA;ExBwkGH;AwBjmGD;ECvBE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzB2nGD;AwBvmGD;EAmCI,gBAAA;EACA,mBAAA;EACA,aAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExBukGH;AwBjkGC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;ExBmkGH;AwB7jGC;;;EAGE,gBAAA;EACA,uBAAA;EACA,YAAA;EACA,2BAAA;ExB+jGH;AwBtjGC;;;EAGE,gBAAA;ExBwjGH;AwBpjGC;;EAEE,uBAAA;EACA,+BAAA;EACA,wBAAA;EEzGF,qEAAA;EF2GE,qBAAA;ExBsjGH;AwBjjGD;EAGI,gBAAA;ExBijGH;AwBpjGD;EAQI,YAAA;ExB+iGH;AwBviGD;EACE,YAAA;EACA,UAAA;ExByiGD;AwBjiGD;EACE,SAAA;EACA,aAAA;ExBmiGD;AwB/hGD;EACE,gBAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExBiiGD;AwB7hGD;EACE,iBAAA;EACA,SAAA;EACA,UAAA;EACA,WAAA;EACA,QAAA;EACA,cAAA;ExB+hGD;AwB3hGD;EACE,UAAA;EACA,YAAA;ExB6hGD;AwBrhGD;;EAII,eAAA;EACA,0BAAA;EACA,aAAA;ExBqhGH;AwB3hGD;;EAUI,WAAA;EACA,cAAA;EACA,oBAAA;ExBqhGH;AwBhgGD;EAXE;IAnEA,YAAA;IACA,UAAA;IxBklGC;EwBhhGD;IAzDA,SAAA;IACA,aAAA;IxB4kGC;EACF;A2B1tGD;;EAEE,oBAAA;EACA,uBAAA;EACA,wBAAA;E3B4tGD;A2BhuGD;;EAMI,oBAAA;EACA,aAAA;E3B8tGH;A2B5tGG;;;;;;;;EAIE,YAAA;E3BkuGL;A2B5tGD;;;;EAKI,mBAAA;E3B6tGH;A2BxtGD;EACE,mBAAA;E3B0tGD;A2B3tGD;;EAMI,aAAA;E3BytGH;A2B/tGD;;;EAWI,kBAAA;E3BytGH;A2BrtGD;EACE,kBAAA;E3ButGD;A2BntGD;EACE,gBAAA;E3BqtGD;A2BptGC;ECjDA,+BAAA;EACG,4BAAA;E5BwwGJ;A2BntGD;;EC9CE,8BAAA;EACG,2BAAA;E5BqwGJ;A2BltGD;EACE,aAAA;E3BotGD;A2BltGD;EACE,kBAAA;E3BotGD;A2BltGD;;EClEE,+BAAA;EACG,4BAAA;E5BwxGJ;A2BjtGD;EChEE,8BAAA;EACG,2BAAA;E5BoxGJ;A2BhtGD;;EAEE,YAAA;E3BktGD;A2BjsGD;EACE,mBAAA;EACA,oBAAA;E3BmsGD;A2BjsGD;EACE,oBAAA;EACA,qBAAA;E3BmsGD;A2B9rGD;EtB9CE,0DAAA;EACQ,kDAAA;EL+uGT;A2B9rGC;EtBlDA,0BAAA;EACQ,kBAAA;ELmvGT;A2B3rGD;EACE,gBAAA;E3B6rGD;A2B1rGD;EACE,yBAAA;EACA,wBAAA;E3B4rGD;A2BzrGD;EACE,yBAAA;E3B2rGD;A2BprGD;;;EAII,gBAAA;EACA,aAAA;EACA,aAAA;EACA,iBAAA;E3BqrGH;A2B5rGD;EAcM,aAAA;E3BirGL;A2B/rGD;;;;EAsBI,kBAAA;EACA,gBAAA;E3B+qGH;A2B1qGC;EACE,kBAAA;E3B4qGH;A2B1qGC;EACE,8BAAA;ECnKF,+BAAA;EACC,8BAAA;E5Bg1GF;A2B3qGC;EACE,gCAAA;EC/KF,4BAAA;EACC,2BAAA;E5B61GF;A2B3qGD;EACE,kBAAA;E3B6qGD;A2B3qGD;;EC9KE,+BAAA;EACC,8BAAA;E5B61GF;A2B1qGD;EC5LE,4BAAA;EACC,2BAAA;E5By2GF;A2BtqGD;EACE,gBAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;E3BwqGD;A2B5qGD;;EAOI,aAAA;EACA,qBAAA;EACA,WAAA;E3ByqGH;A2BlrGD;EAYI,aAAA;E3ByqGH;A2BrrGD;EAgBI,YAAA;E3BwqGH;A2BvpGD;;;;EAKM,oBAAA;EACA,wBAAA;EACA,sBAAA;E3BwpGL;A6Bj4GD;EACE,oBAAA;EACA,gBAAA;EACA,2BAAA;E7Bm4GD;A6Bh4GC;EACE,aAAA;EACA,iBAAA;EACA,kBAAA;E7Bk4GH;A6B34GD;EAeI,oBAAA;EACA,YAAA;EAKA,aAAA;EAEA,aAAA;EACA,kBAAA;E7B03GH;A6Bj3GD;;;EV8BE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;EnBw1GD;AmBt1GC;;;EACE,cAAA;EACA,mBAAA;EnB01GH;AmBv1GC;;;;;;EAEE,cAAA;EnB61GH;A6Bn4GD;;;EVyBE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnB+2GD;AmB72GC;;;EACE,cAAA;EACA,mBAAA;EnBi3GH;AmB92GC;;;;;;EAEE,cAAA;EnBo3GH;A6Bj5GD;;;EAGE,qBAAA;E7Bm5GD;A6Bj5GC;;;EACE,kBAAA;E7Bq5GH;A6Bj5GD;;EAEE,WAAA;EACA,qBAAA;EACA,wBAAA;E7Bm5GD;A6B94GD;EACE,mBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;E7Bg5GD;A6B74GC;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;E7B+4GH;A6B74GC;EACE,oBAAA;EACA,iBAAA;EACA,oBAAA;E7B+4GH;A6Bn6GD;;EA0BI,eAAA;E7B64GH;A6Bx4GD;;;;;;;EDhGE,+BAAA;EACG,4BAAA;E5Bi/GJ;A6Bz4GD;EACE,iBAAA;E7B24GD;A6Bz4GD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;E5Bs/GJ;A6B14GD;EACE,gBAAA;E7B44GD;A6Bv4GD;EACE,oBAAA;EAGA,cAAA;EACA,qBAAA;E7Bu4GD;A6B54GD;EAUI,oBAAA;E7Bq4GH;A6B/4GD;EAYM,mBAAA;E7Bs4GL;A6Bn4GG;;;EAGE,YAAA;E7Bq4GL;A6Bh4GC;;EAGI,oBAAA;E7Bi4GL;A6B93GC;;EAGI,mBAAA;E7B+3GL;A8BzhHD;EACE,kBAAA;EACA,iBAAA;EACA,kBAAA;E9B2hHD;A8B9hHD;EAOI,oBAAA;EACA,gBAAA;E9B0hHH;A8BliHD;EAWM,oBAAA;EACA,gBAAA;EACA,oBAAA;E9B0hHL;A8BzhHK;;EAEE,uBAAA;EACA,2BAAA;E9B2hHP;A8BthHG;EACE,gBAAA;E9BwhHL;A8BthHK;;EAEE,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,qBAAA;E9BwhHP;A8BjhHG;;;EAGE,2BAAA;EACA,uBAAA;E9BmhHL;A8B5jHD;ELHE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzBkkHD;A8BlkHD;EA0DI,iBAAA;E9B2gHH;A8BlgHD;EACE,kCAAA;E9BogHD;A8BrgHD;EAGI,aAAA;EAEA,qBAAA;E9BogHH;A8BzgHD;EASM,mBAAA;EACA,yBAAA;EACA,+BAAA;EACA,4BAAA;E9BmgHL;A8BlgHK;EACE,uCAAA;E9BogHP;A8B9/GK;;;EAGE,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,kCAAA;EACA,iBAAA;E9BggHP;A8B3/GC;EAqDA,aAAA;EA8BA,kBAAA;E9B46GD;A8B//GC;EAwDE,aAAA;E9B08GH;A8BlgHC;EA0DI,oBAAA;EACA,oBAAA;E9B28GL;A8BtgHC;EAgEE,WAAA;EACA,YAAA;E9By8GH;A8B77GD;EAAA;IAPM,qBAAA;IACA,WAAA;I9Bw8GH;E8Bl8GH;IAJQ,kBAAA;I9By8GL;EACF;A8BnhHC;EAuFE,iBAAA;EACA,oBAAA;E9B+7GH;A8BvhHC;;;EA8FE,2BAAA;E9B87GH;A8Bh7GD;EAAA;IATM,kCAAA;IACA,4BAAA;I9B67GH;E8Br7GH;;;IAHM,8BAAA;I9B67GH;EACF;A8B9hHD;EAEI,aAAA;E9B+hHH;A8BjiHD;EAMM,oBAAA;E9B8hHL;A8BpiHD;EASM,kBAAA;E9B8hHL;A8BzhHK;;;EAGE,gBAAA;EACA,2BAAA;E9B2hHP;A8BnhHD;EAEI,aAAA;E9BohHH;A8BthHD;EAIM,iBAAA;EACA,gBAAA;E9BqhHL;A8BzgHD;EACE,aAAA;E9B2gHD;A8B5gHD;EAII,aAAA;E9B2gHH;A8B/gHD;EAMM,oBAAA;EACA,oBAAA;E9B4gHL;A8BnhHD;EAYI,WAAA;EACA,YAAA;E9B0gHH;A8B9/GD;EAAA;IAPM,qBAAA;IACA,WAAA;I9BygHH;E8BngHH;IAJQ,kBAAA;I9B0gHL;EACF;A8BlgHD;EACE,kBAAA;E9BogHD;A8BrgHD;EAKI,iBAAA;EACA,oBAAA;E9BmgHH;A8BzgHD;;;EAYI,2BAAA;E9BkgHH;A8Bp/GD;EAAA;IATM,kCAAA;IACA,4BAAA;I9BigHH;E8Bz/GH;;;IAHM,8BAAA;I9BigHH;EACF;A8Bx/GD;EAEI,eAAA;EACA,oBAAA;E9By/GH;A8B5/GD;EAMI,gBAAA;EACA,qBAAA;E9By/GH;A8Bh/GD;EAEE,kBAAA;EF7OA,4BAAA;EACC,2BAAA;E5B+tHF;A+BztHD;EACE,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,+BAAA;E/B2tHD;A+BntHD;EAAA;IAFI,oBAAA;I/BytHD;EACF;A+B1sHD;EAAA;IAFI,aAAA;I/BgtHD;EACF;A+BlsHD;EACE,qBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,4DAAA;UAAA,oDAAA;EAEA,mCAAA;E/BmsHD;A+BjsHC;EACE,kBAAA;E/BmsHH;A+BtqHD;EAAA;IAzBI,aAAA;IACA,eAAA;IACA,0BAAA;YAAA,kBAAA;I/BmsHD;E+BjsHC;IACE,2BAAA;IACA,gCAAA;IACA,yBAAA;IACA,mBAAA;IACA,8BAAA;I/BmsHH;E+BhsHC;IACE,qBAAA;I/BksHH;E+B7rHC;;;IAGE,iBAAA;IACA,kBAAA;I/B+rHH;EACF;A+B3rHD;;EAGI,mBAAA;E/B4rHH;A+BvrHC;EAAA;;IAFI,mBAAA;I/B8rHH;EACF;A+BrrHD;;;;EAII,qBAAA;EACA,oBAAA;E/BurHH;A+BjrHC;EAAA;;;;IAHI,iBAAA;IACA,gBAAA;I/B2rHH;EACF;A+B/qHD;EACE,eAAA;EACA,uBAAA;E/BirHD;A+B5qHD;EAAA;IAFI,kBAAA;I/BkrHD;EACF;A+B9qHD;;EAEE,iBAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;E/BgrHD;A+B1qHD;EAAA;;IAFI,kBAAA;I/BirHD;EACF;A+B/qHD;EACE,QAAA;EACA,uBAAA;E/BirHD;A+B/qHD;EACE,WAAA;EACA,kBAAA;EACA,uBAAA;E/BirHD;A+B3qHD;EACE,aAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,cAAA;E/B6qHD;A+B3qHC;;EAEE,uBAAA;E/B6qHH;A+BtrHD;EAaI,gBAAA;E/B4qHH;A+BnqHD;EALI;;IAEE,oBAAA;I/B2qHH;EACF;A+BjqHD;EACE,oBAAA;EACA,cAAA;EACA,oBAAA;EACA,mBAAA;EC/LA,iBAAA;EACA,oBAAA;EDgMA,+BAAA;EACA,wBAAA;EACA,+BAAA;EACA,oBAAA;E/BoqHD;A+BhqHC;EACE,YAAA;E/BkqHH;A+BhrHD;EAmBI,gBAAA;EACA,aAAA;EACA,aAAA;EACA,oBAAA;E/BgqHH;A+BtrHD;EAyBI,iBAAA;E/BgqHH;A+B1pHD;EAAA;IAFI,eAAA;I/BgqHD;EACF;A+BvpHD;EACE,qBAAA;E/BypHD;A+B1pHD;EAII,mBAAA;EACA,sBAAA;EACA,mBAAA;E/BypHH;A+B9nHC;EAAA;IArBI,kBAAA;IACA,aAAA;IACA,aAAA;IACA,eAAA;IACA,+BAAA;IACA,WAAA;IACA,0BAAA;YAAA,kBAAA;I/BupHH;E+BxoHD;;IAZM,4BAAA;I/BwpHL;E+B5oHD;IATM,mBAAA;I/BwpHL;E+BvpHK;;IAEE,wBAAA;I/BypHP;EACF;A+BvoHD;EAAA;IAXI,aAAA;IACA,WAAA;I/BspHD;E+B5oHH;IAPM,aAAA;I/BspHH;E+B/oHH;IALQ,mBAAA;IACA,sBAAA;I/BupHL;EACF;A+B5oHD;EACE,oBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,sCAAA;E1B/NA,8FAAA;EACQ,sFAAA;E2B/DR,iBAAA;EACA,oBAAA;EhC86HD;AkBz9GD;EAAA;IA/DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlB4hHH;EkB/9GH;IAxDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB0hHH;EkBp+GH;IAjDM,uBAAA;IlBwhHH;EkBv+GH;IA7CM,uBAAA;IACA,wBAAA;IlBuhHH;EkB3+GH;;;IAvCQ,aAAA;IlBuhHL;EkBh/GH;IAjCM,aAAA;IlBohHH;EkBn/GH;IA7BM,kBAAA;IACA,wBAAA;IlBmhHH;EkBv/GH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlB+gHH;EkB9/GH;;IAdQ,iBAAA;IlBghHL;EkBlgHH;;IATM,oBAAA;IACA,gBAAA;IlB+gHH;EkBvgHH;IAHM,QAAA;IlB6gHH;EACF;A+BrrHC;EAAA;IANI,oBAAA;I/B+rHH;E+B7rHG;IACE,kBAAA;I/B+rHL;EACF;A+B9qHD;EAAA;IARI,aAAA;IACA,WAAA;IACA,gBAAA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;I1B1PF,0BAAA;IACQ,kBAAA;ILq7HP;EACF;A+BprHD;EACE,eAAA;EHrUA,4BAAA;EACC,2BAAA;E5B4/HF;A+BprHD;EHzUE,8BAAA;EACC,6BAAA;EAOD,+BAAA;EACC,8BAAA;E5B0/HF;A+BhrHD;EChVE,iBAAA;EACA,oBAAA;EhCmgID;A+BjrHC;ECnVA,kBAAA;EACA,qBAAA;EhCugID;A+BlrHC;ECtVA,kBAAA;EACA,qBAAA;EhC2gID;A+B5qHD;EChWE,kBAAA;EACA,qBAAA;EhC+gID;A+BxqHD;EAAA;IAJI,aAAA;IACA,mBAAA;IACA,oBAAA;I/BgrHD;EACF;A+BvpHD;EAZE;IExWA,wBAAA;IjC+gIC;E+BtqHD;IE5WA,yBAAA;IF8WE,qBAAA;I/BwqHD;E+B1qHD;IAKI,iBAAA;I/BwqHH;EACF;A+B/pHD;EACE,2BAAA;EACA,uBAAA;E/BiqHD;A+BnqHD;EAKI,gBAAA;E/BiqHH;A+BhqHG;;EAEE,gBAAA;EACA,+BAAA;E/BkqHL;A+B3qHD;EAcI,gBAAA;E/BgqHH;A+B9qHD;EAmBM,gBAAA;E/B8pHL;A+B5pHK;;EAEE,gBAAA;EACA,+BAAA;E/B8pHP;A+B1pHK;;;EAGE,gBAAA;EACA,2BAAA;E/B4pHP;A+BxpHK;;;EAGE,gBAAA;EACA,+BAAA;E/B0pHP;A+BlsHD;EA8CI,uBAAA;E/BupHH;A+BtpHG;;EAEE,2BAAA;E/BwpHL;A+BzsHD;EAoDM,2BAAA;E/BwpHL;A+B5sHD;;EA0DI,uBAAA;E/BspHH;A+B/oHK;;;EAGE,2BAAA;EACA,gBAAA;E/BipHP;A+BhnHC;EAAA;IAzBQ,gBAAA;I/B6oHP;E+B5oHO;;IAEE,gBAAA;IACA,+BAAA;I/B8oHT;E+B1oHO;;;IAGE,gBAAA;IACA,2BAAA;I/B4oHT;E+BxoHO;;;IAGE,gBAAA;IACA,+BAAA;I/B0oHT;EACF;A+B5uHD;EA8GI,gBAAA;E/BioHH;A+BhoHG;EACE,gBAAA;E/BkoHL;A+BlvHD;EAqHI,gBAAA;E/BgoHH;A+B/nHG;;EAEE,gBAAA;E/BioHL;A+B7nHK;;;;EAEE,gBAAA;E/BioHP;A+BznHD;EACE,2BAAA;EACA,uBAAA;E/B2nHD;A+B7nHD;EAKI,gBAAA;E/B2nHH;A+B1nHG;;EAEE,gBAAA;EACA,+BAAA;E/B4nHL;A+BroHD;EAcI,gBAAA;E/B0nHH;A+BxoHD;EAmBM,gBAAA;E/BwnHL;A+BtnHK;;EAEE,gBAAA;EACA,+BAAA;E/BwnHP;A+BpnHK;;;EAGE,gBAAA;EACA,2BAAA;E/BsnHP;A+BlnHK;;;EAGE,gBAAA;EACA,+BAAA;E/BonHP;A+B5pHD;EA+CI,uBAAA;E/BgnHH;A+B/mHG;;EAEE,2BAAA;E/BinHL;A+BnqHD;EAqDM,2BAAA;E/BinHL;A+BtqHD;;EA2DI,uBAAA;E/B+mHH;A+BzmHK;;;EAGE,2BAAA;EACA,gBAAA;E/B2mHP;A+BpkHC;EAAA;IA/BQ,uBAAA;I/BumHP;E+BxkHD;IA5BQ,2BAAA;I/BumHP;E+B3kHD;IAzBQ,gBAAA;I/BumHP;E+BtmHO;;IAEE,gBAAA;IACA,+BAAA;I/BwmHT;E+BpmHO;;;IAGE,gBAAA;IACA,2BAAA;I/BsmHT;E+BlmHO;;;IAGE,gBAAA;IACA,+BAAA;I/BomHT;EACF;A+B5sHD;EA+GI,gBAAA;E/BgmHH;A+B/lHG;EACE,gBAAA;E/BimHL;A+BltHD;EAsHI,gBAAA;E/B+lHH;A+B9lHG;;EAEE,gBAAA;E/BgmHL;A+B5lHK;;;;EAEE,gBAAA;E/BgmHP;AkC1uID;EACE,mBAAA;EACA,qBAAA;EACA,kBAAA;EACA,2BAAA;EACA,oBAAA;ElC4uID;AkCjvID;EAQI,uBAAA;ElC4uIH;AkCpvID;EAWM,mBAAA;EACA,gBAAA;EACA,gBAAA;ElC4uIL;AkCzvID;EAkBI,gBAAA;ElC0uIH;AmC9vID;EACE,uBAAA;EACA,iBAAA;EACA,gBAAA;EACA,oBAAA;EnCgwID;AmCpwID;EAOI,iBAAA;EnCgwIH;AmCvwID;;EAUM,oBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,mBAAA;EnCiwIL;AmC/vIG;;EAGI,gBAAA;EPXN,gCAAA;EACG,6BAAA;E5B4wIJ;AmC9vIG;;EPvBF,iCAAA;EACG,8BAAA;E5ByxIJ;AmCzvIG;;;;EAEE,gBAAA;EACA,2BAAA;EACA,uBAAA;EnC6vIL;AmCvvIG;;;;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,iBAAA;EnC4vIL;AmClzID;;;;;;EAiEM,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,qBAAA;EnCyvIL;AmChvID;;EC1EM,oBAAA;EACA,iBAAA;EpC8zIL;AoC5zIG;;ERMF,gCAAA;EACG,6BAAA;E5B0zIJ;AoC3zIG;;ERRF,iCAAA;EACG,8BAAA;E5Bu0IJ;AmC1vID;;EC/EM,mBAAA;EACA,iBAAA;EpC60IL;AoC30IG;;ERMF,gCAAA;EACG,6BAAA;E5By0IJ;AoC10IG;;ERRF,iCAAA;EACG,8BAAA;E5Bs1IJ;AqCz1ID;EACE,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,oBAAA;ErC21ID;AqC/1ID;EAOI,iBAAA;ErC21IH;AqCl2ID;;EAUM,uBAAA;EACA,mBAAA;EACA,2BAAA;EACA,2BAAA;EACA,qBAAA;ErC41IL;AqC12ID;;EAmBM,uBAAA;EACA,2BAAA;ErC21IL;AqC/2ID;;EA2BM,cAAA;ErCw1IL;AqCn3ID;;EAkCM,aAAA;ErCq1IL;AqCv3ID;;;;EA2CM,gBAAA;EACA,2BAAA;EACA,qBAAA;ErCk1IL;AsCh4ID;EACE,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sBAAA;EtCk4ID;AsC93IG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EtCg4IL;AsC33IC;EACE,eAAA;EtC63IH;AsCz3IC;EACE,oBAAA;EACA,WAAA;EtC23IH;AsCp3ID;ECtCE,2BAAA;EvC65ID;AuC15IG;;EAEE,2BAAA;EvC45IL;AsCv3ID;EC1CE,2BAAA;EvCo6ID;AuCj6IG;;EAEE,2BAAA;EvCm6IL;AsC13ID;EC9CE,2BAAA;EvC26ID;AuCx6IG;;EAEE,2BAAA;EvC06IL;AsC73ID;EClDE,2BAAA;EvCk7ID;AuC/6IG;;EAEE,2BAAA;EvCi7IL;AsCh4ID;ECtDE,2BAAA;EvCy7ID;AuCt7IG;;EAEE,2BAAA;EvCw7IL;AsCn4ID;EC1DE,2BAAA;EvCg8ID;AuC77IG;;EAEE,2BAAA;EvC+7IL;AwCj8ID;EACE,uBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,0BAAA;EACA,qBAAA;EACA,oBAAA;EACA,2BAAA;EACA,qBAAA;ExCm8ID;AwCh8IC;EACE,eAAA;ExCk8IH;AwC97IC;EACE,oBAAA;EACA,WAAA;ExCg8IH;AwC97IC;EACE,QAAA;EACA,kBAAA;ExCg8IH;AwC37IG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;ExC67IL;AwCx7IC;;EAEE,gBAAA;EACA,2BAAA;ExC07IH;AwCx7IC;EACE,cAAA;ExC07IH;AwCx7IC;EACE,mBAAA;ExC07IH;AwCx7IC;EACE,kBAAA;ExC07IH;AyC/+ID;EACE,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,2BAAA;EzCi/ID;AyCr/ID;;EAQI,gBAAA;EzCi/IH;AyCz/ID;EAWI,qBAAA;EACA,iBAAA;EACA,kBAAA;EzCi/IH;AyC9/ID;EAiBI,2BAAA;EzCg/IH;AyC7+IC;;EAEE,oBAAA;EzC++IH;AyCrgJD;EA0BI,iBAAA;EzC8+IH;AyC79ID;EAAA;IAbI,iBAAA;IzC8+ID;EyC5+IC;;IAEE,oBAAA;IACA,qBAAA;IzC8+IH;EyCt+IH;;IAHM,iBAAA;IzC6+IH;EACF;A0CrhJD;EACE,gBAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;ErCiLA,6CAAA;EACK,wCAAA;EACG,qCAAA;ELu2IT;A0CjiJD;;EAaI,mBAAA;EACA,oBAAA;E1CwhJH;A0CphJC;;;EAGE,uBAAA;E1CshJH;A0C3iJD;EA0BI,cAAA;EACA,gBAAA;E1CohJH;A2C7iJD;EACE,eAAA;EACA,qBAAA;EACA,+BAAA;EACA,oBAAA;E3C+iJD;A2CnjJD;EAQI,eAAA;EAEA,gBAAA;E3C6iJH;A2CvjJD;EAcI,mBAAA;E3C4iJH;A2C1jJD;;EAoBI,kBAAA;E3C0iJH;A2C9jJD;EAuBI,iBAAA;E3C0iJH;A2CliJD;;EAEE,qBAAA;E3CoiJD;A2CtiJD;;EAMI,oBAAA;EACA,WAAA;EACA,cAAA;EACA,gBAAA;E3CoiJH;A2C5hJD;ECrDE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5ColJD;A2CjiJD;EChDI,2BAAA;E5ColJH;A2CpiJD;EC7CI,gBAAA;E5ColJH;A2CpiJD;ECxDE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C+lJD;A2CziJD;ECnDI,2BAAA;E5C+lJH;A2C5iJD;EChDI,gBAAA;E5C+lJH;A2C5iJD;EC3DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C0mJD;A2CjjJD;ECtDI,2BAAA;E5C0mJH;A2CpjJD;ECnDI,gBAAA;E5C0mJH;A2CpjJD;EC9DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5CqnJD;A2CzjJD;ECzDI,2BAAA;E5CqnJH;A2C5jJD;ECtDI,gBAAA;E5CqnJH;A6CvnJD;EACE;IAAQ,6BAAA;I7C0nJP;E6CznJD;IAAQ,0BAAA;I7C4nJP;EACF;A6CznJD;EACE;IAAQ,6BAAA;I7C4nJP;E6C3nJD;IAAQ,0BAAA;I7C8nJP;EACF;A6CjoJD;EACE;IAAQ,6BAAA;I7C4nJP;E6C3nJD;IAAQ,0BAAA;I7C8nJP;EACF;A6CvnJD;EACE,kBAAA;EACA,cAAA;EACA,qBAAA;EACA,2BAAA;EACA,oBAAA;ExCsCA,wDAAA;EACQ,gDAAA;ELolJT;A6CtnJD;EACE,aAAA;EACA,WAAA;EACA,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;ExCyBA,wDAAA;EACQ,gDAAA;EAyHR,qCAAA;EACK,gCAAA;EACG,6BAAA;ELw+IT;A6CnnJD;;ECCI,+MAAA;EACA,0MAAA;EACA,uMAAA;EDAF,oCAAA;UAAA,4BAAA;E7CunJD;A6ChnJD;;ExC5CE,4DAAA;EACK,uDAAA;EACG,oDAAA;ELgqJT;A6C7mJD;EErEE,2BAAA;E/CqrJD;A+ClrJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9CqoJH;A6CjnJD;EEzEE,2BAAA;E/C6rJD;A+C1rJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C6oJH;A6CrnJD;EE7EE,2BAAA;E/CqsJD;A+ClsJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9CqpJH;A6CznJD;EEjFE,2BAAA;E/C6sJD;A+C1sJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C6pJH;AgDrtJD;EAEE,kBAAA;EhDstJD;AgDptJC;EACE,eAAA;EhDstJH;AgDltJD;;EAEE,oBAAA;EhDotJD;AgDjtJD;;EAEE,qBAAA;EhDmtJD;AgDhtJD;;;EAGE,qBAAA;EACA,qBAAA;EhDktJD;AgD/sJD;EACE,wBAAA;EhDitJD;AgD9sJD;EACE,wBAAA;EhDgtJD;AgD5sJD;EACE,eAAA;EACA,oBAAA;EhD8sJD;AgDxsJD;EACE,iBAAA;EACA,kBAAA;EhD0sJD;AiD9uJD;EAEE,qBAAA;EACA,iBAAA;EjD+uJD;AiDvuJD;EACE,oBAAA;EACA,gBAAA;EACA,oBAAA;EAEA,qBAAA;EACA,2BAAA;EACA,2BAAA;EjDwuJD;AiDruJC;ErB3BA,8BAAA;EACC,6BAAA;E5BmwJF;AiDtuJC;EACE,kBAAA;ErBvBF,iCAAA;EACC,gCAAA;E5BgwJF;AiD/tJD;EACE,gBAAA;EjDiuJD;AiDluJD;EAII,gBAAA;EjDiuJH;AiD7tJC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;EjD+tJH;AiDztJC;;;EAGE,2BAAA;EACA,gBAAA;EACA,qBAAA;EjD2tJH;AiDhuJC;;;EASI,gBAAA;EjD4tJL;AiDruJC;;;EAYI,gBAAA;EjD8tJL;AiDztJC;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EjD2tJH;AiDjuJC;;;;;;;;;EAYI,gBAAA;EjDguJL;AiD5uJC;;;EAeI,gBAAA;EjDkuJL;AkD9zJC;EACE,gBAAA;EACA,2BAAA;ElDg0JH;AkD9zJG;EACE,gBAAA;ElDg0JL;AkDj0JG;EAII,gBAAA;ElDg0JP;AkD7zJK;;EAEE,gBAAA;EACA,2BAAA;ElD+zJP;AkD7zJK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElD+zJP;AkDp1JC;EACE,gBAAA;EACA,2BAAA;ElDs1JH;AkDp1JG;EACE,gBAAA;ElDs1JL;AkDv1JG;EAII,gBAAA;ElDs1JP;AkDn1JK;;EAEE,gBAAA;EACA,2BAAA;ElDq1JP;AkDn1JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDq1JP;AkD12JC;EACE,gBAAA;EACA,2BAAA;ElD42JH;AkD12JG;EACE,gBAAA;ElD42JL;AkD72JG;EAII,gBAAA;ElD42JP;AkDz2JK;;EAEE,gBAAA;EACA,2BAAA;ElD22JP;AkDz2JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElD22JP;AkDh4JC;EACE,gBAAA;EACA,2BAAA;ElDk4JH;AkDh4JG;EACE,gBAAA;ElDk4JL;AkDn4JG;EAII,gBAAA;ElDk4JP;AkD/3JK;;EAEE,gBAAA;EACA,2BAAA;ElDi4JP;AkD/3JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDi4JP;AiDryJD;EACE,eAAA;EACA,oBAAA;EjDuyJD;AiDryJD;EACE,kBAAA;EACA,kBAAA;EjDuyJD;AmD35JD;EACE,qBAAA;EACA,2BAAA;EACA,+BAAA;EACA,oBAAA;E9C0DA,mDAAA;EACQ,2CAAA;ELo2JT;AmD15JD;EACE,eAAA;EnD45JD;AmDv5JD;EACE,oBAAA;EACA,sCAAA;EvBpBA,8BAAA;EACC,6BAAA;E5B86JF;AmD75JD;EAMI,gBAAA;EnD05JH;AmDr5JD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,gBAAA;EnDu5JD;AmD35JD;EAOI,gBAAA;EnDu5JH;AmDl5JD;EACE,oBAAA;EACA,2BAAA;EACA,+BAAA;EvBpCA,iCAAA;EACC,gCAAA;E5By7JF;AmD54JD;;EAGI,kBAAA;EnD64JH;AmDh5JD;;EAMM,qBAAA;EACA,kBAAA;EnD84JL;AmD14JG;;EAEI,eAAA;EvBnEN,8BAAA;EACC,6BAAA;E5Bg9JF;AmDz4JG;;EAEI,kBAAA;EvBlEN,iCAAA;EACC,gCAAA;E5B88JF;AmDt4JD;EAEI,qBAAA;EnDu4JH;AmDp4JD;EACE,qBAAA;EnDs4JD;AmD93JD;;;EAII,kBAAA;EnD+3JH;AmDn4JD;;;EAOM,oBAAA;EACA,qBAAA;EnDi4JL;AmDz4JD;;EvB/FE,8BAAA;EACC,6BAAA;E5B4+JF;AmD94JD;;;;EAmBQ,6BAAA;EACA,8BAAA;EnDi4JP;AmDr5JD;;;;;;;;EAwBU,6BAAA;EnDu4JT;AmD/5JD;;;;;;;;EA4BU,8BAAA;EnD64JT;AmDz6JD;;EvBvFE,iCAAA;EACC,gCAAA;E5BogKF;AmD96JD;;;;EAyCQ,gCAAA;EACA,iCAAA;EnD24JP;AmDr7JD;;;;;;;;EA8CU,gCAAA;EnDi5JT;AmD/7JD;;;;;;;;EAkDU,iCAAA;EnDu5JT;AmDz8JD;;;;EA2DI,+BAAA;EnDo5JH;AmD/8JD;;EA+DI,eAAA;EnDo5JH;AmDn9JD;;EAmEI,WAAA;EnDo5JH;AmDv9JD;;;;;;;;;;;;EA0EU,gBAAA;EnD25JT;AmDr+JD;;;;;;;;;;;;EA8EU,iBAAA;EnDq6JT;AmDn/JD;;;;;;;;EAuFU,kBAAA;EnDs6JT;AmD7/JD;;;;;;;;EAgGU,kBAAA;EnDu6JT;AmDvgKD;EAsGI,WAAA;EACA,kBAAA;EnDo6JH;AmD15JD;EACE,qBAAA;EnD45JD;AmD75JD;EAKI,kBAAA;EACA,oBAAA;EnD25JH;AmDj6JD;EASM,iBAAA;EnD25JL;AmDp6JD;EAcI,kBAAA;EnDy5JH;AmDv6JD;;EAkBM,+BAAA;EnDy5JL;AmD36JD;EAuBI,eAAA;EnDu5JH;AmD96JD;EAyBM,kCAAA;EnDw5JL;AmDj5JD;EChPE,uBAAA;EpDooKD;AoDloKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDooKH;AoDvoKC;EAMI,2BAAA;EpDooKL;AoD1oKC;EASI,gBAAA;EACA,2BAAA;EpDooKL;AoDjoKC;EAEI,8BAAA;EpDkoKL;AmDh6JD;ECnPE,uBAAA;EpDspKD;AoDppKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDspKH;AoDzpKC;EAMI,2BAAA;EpDspKL;AoD5pKC;EASI,gBAAA;EACA,2BAAA;EpDspKL;AoDnpKC;EAEI,8BAAA;EpDopKL;AmD/6JD;ECtPE,uBAAA;EpDwqKD;AoDtqKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDwqKH;AoD3qKC;EAMI,2BAAA;EpDwqKL;AoD9qKC;EASI,gBAAA;EACA,2BAAA;EpDwqKL;AoDrqKC;EAEI,8BAAA;EpDsqKL;AmD97JD;ECzPE,uBAAA;EpD0rKD;AoDxrKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD0rKH;AoD7rKC;EAMI,2BAAA;EpD0rKL;AoDhsKC;EASI,gBAAA;EACA,2BAAA;EpD0rKL;AoDvrKC;EAEI,8BAAA;EpDwrKL;AmD78JD;EC5PE,uBAAA;EpD4sKD;AoD1sKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD4sKH;AoD/sKC;EAMI,2BAAA;EpD4sKL;AoDltKC;EASI,gBAAA;EACA,2BAAA;EpD4sKL;AoDzsKC;EAEI,8BAAA;EpD0sKL;AmD59JD;EC/PE,uBAAA;EpD8tKD;AoD5tKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD8tKH;AoDjuKC;EAMI,2BAAA;EpD8tKL;AoDpuKC;EASI,gBAAA;EACA,2BAAA;EpD8tKL;AoD3tKC;EAEI,8BAAA;EpD4tKL;AqD5uKD;EACE,oBAAA;EACA,gBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;ErD8uKD;AqDnvKD;;;;;EAYI,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,cAAA;EACA,aAAA;EACA,WAAA;ErD8uKH;AqD1uKC;EACE,wBAAA;ErD4uKH;AqDxuKC;EACE,qBAAA;ErD0uKH;AsDpwKD;EACE,kBAAA;EACA,eAAA;EACA,qBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EjDwDA,yDAAA;EACQ,iDAAA;EL+sKT;AsD9wKD;EASI,oBAAA;EACA,mCAAA;EtDwwKH;AsDnwKD;EACE,eAAA;EACA,oBAAA;EtDqwKD;AsDnwKD;EACE,cAAA;EACA,oBAAA;EtDqwKD;AuD3xKD;EACE,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,8BAAA;EjCRA,cAAA;EAGA,2BAAA;EtBoyKD;AuD5xKC;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EjCfF,cAAA;EAGA,2BAAA;EtB4yKD;AuDzxKC;EACE,YAAA;EACA,iBAAA;EACA,yBAAA;EACA,WAAA;EACA,0BAAA;EvD2xKH;AwD/yKD;EACE,kBAAA;ExDizKD;AwD7yKD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,mCAAA;EAIA,YAAA;ExD4yKD;AwDzyKC;EnD+GA,uCAAA;EACI,mCAAA;EACC,kCAAA;EACG,+BAAA;EAkER,qDAAA;EAEK,2CAAA;EACG,qCAAA;EL4nKT;AwD/yKC;EnD2GA,oCAAA;EACI,gCAAA;EACC,+BAAA;EACG,4BAAA;ELusKT;AwDnzKD;EACE,oBAAA;EACA,kBAAA;ExDqzKD;AwDjzKD;EACE,oBAAA;EACA,aAAA;EACA,cAAA;ExDmzKD;AwD/yKD;EACE,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;EnDaA,kDAAA;EACQ,0CAAA;EmDZR,sCAAA;UAAA,8BAAA;EAEA,YAAA;ExDizKD;AwD7yKD;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,2BAAA;ExD+yKD;AwD7yKC;ElCnEA,YAAA;EAGA,0BAAA;EtBi3KD;AwDhzKC;ElCpEA,cAAA;EAGA,2BAAA;EtBq3KD;AwD/yKD;EACE,eAAA;EACA,kCAAA;EACA,2BAAA;ExDizKD;AwD9yKD;EACE,kBAAA;ExDgzKD;AwD5yKD;EACE,WAAA;EACA,yBAAA;ExD8yKD;AwDzyKD;EACE,oBAAA;EACA,eAAA;ExD2yKD;AwDvyKD;EACE,eAAA;EACA,mBAAA;EACA,+BAAA;ExDyyKD;AwD5yKD;EAQI,kBAAA;EACA,kBAAA;ExDuyKH;AwDhzKD;EAaI,mBAAA;ExDsyKH;AwDnzKD;EAiBI,gBAAA;ExDqyKH;AwDhyKD;EACE,oBAAA;EACA,cAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAA;ExDkyKD;AwDhxKD;EAZE;IACE,cAAA;IACA,mBAAA;IxD+xKD;EwD7xKD;InDrEA,mDAAA;IACQ,2CAAA;ILq2KP;EwD5xKD;IAAY,cAAA;IxD+xKX;EACF;AwD1xKD;EAFE;IAAY,cAAA;IxDgyKX;EACF;AyD76KD;EACE,oBAAA;EACA,eAAA;EACA,gBAAA;EACA,qBAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,kBAAA;EnCZA,YAAA;EAGA,0BAAA;EtBy7KD;AyD76KC;EnCfA,cAAA;EAGA,2BAAA;EtB67KD;AyDh7KC;EAAW,kBAAA;EAAmB,gBAAA;EzDo7K/B;AyDn7KC;EAAW,kBAAA;EAAmB,gBAAA;EzDu7K/B;AyDt7KC;EAAW,iBAAA;EAAmB,gBAAA;EzD07K/B;AyDz7KC;EAAW,mBAAA;EAAmB,gBAAA;EzD67K/B;AyDz7KD;EACE,kBAAA;EACA,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,uBAAA;EACA,2BAAA;EACA,oBAAA;EzD27KD;AyDv7KD;EACE,oBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;EzDy7KD;AyDr7KC;EACE,WAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,WAAA;EACA,YAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,WAAA;EACA,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,UAAA;EACA,SAAA;EACA,kBAAA;EACA,6BAAA;EACA,6BAAA;EzDu7KH;AyDr7KC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,6BAAA;EACA,4BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,YAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;A0DthLD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,kBAAA;EACA,cAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,yBAAA;EACA,kBAAA;EACA,2BAAA;EACA,sCAAA;UAAA,8BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;ErD6CA,mDAAA;EACQ,2CAAA;EqD1CR,qBAAA;E1DshLD;A0DnhLC;EAAY,mBAAA;E1DshLb;A0DrhLC;EAAY,mBAAA;E1DwhLb;A0DvhLC;EAAY,kBAAA;E1D0hLb;A0DzhLC;EAAY,oBAAA;E1D4hLb;A0DzhLD;EACE,WAAA;EACA,mBAAA;EACA,iBAAA;EACA,2BAAA;EACA,kCAAA;EACA,4BAAA;E1D2hLD;A0DxhLD;EACE,mBAAA;E1D0hLD;A0DlhLC;;EAEE,oBAAA;EACA,gBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;E1DohLH;A0DjhLD;EACE,oBAAA;E1DmhLD;A0DjhLD;EACE,oBAAA;EACA,aAAA;E1DmhLD;A0D/gLC;EACE,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;EACA,uCAAA;EACA,eAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;E1DkhLL;A0D/gLC;EACE,UAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,6BAAA;EACA,yCAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,WAAA;EACA,eAAA;EACA,sBAAA;EACA,6BAAA;E1DkhLL;A0D/gLC;EACE,WAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;EACA,0CAAA;EACA,YAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,UAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;E1DkhLL;A0D9gLC;EACE,UAAA;EACA,cAAA;EACA,mBAAA;EACA,uBAAA;EACA,4BAAA;EACA,wCAAA;E1DghLH;A0D/gLG;EACE,cAAA;EACA,YAAA;EACA,uBAAA;EACA,4BAAA;EACA,eAAA;E1DihLL;A2D9oLD;EACE,oBAAA;E3DgpLD;A2D7oLD;EACE,oBAAA;EACA,kBAAA;EACA,aAAA;E3D+oLD;A2DlpLD;EAMI,eAAA;EACA,oBAAA;EtD6KF,2CAAA;EACK,sCAAA;EACG,mCAAA;ELm+KT;A2DzpLD;;EAcM,gBAAA;E3D+oLL;A2DrnLC;EAAA;IArBI,wDAAA;SAAA,8CAAA;YAAA,wCAAA;IACA,qCAAA;YAAA,6BAAA;IACA,2BAAA;YAAA,mBAAA;I3D8oLH;E2D5oLG;;IAEE,4CAAA;YAAA,oCAAA;IACA,SAAA;I3D8oLL;E2D5oLG;;IAEE,6CAAA;YAAA,qCAAA;IACA,SAAA;I3D8oLL;E2D5oLG;;;IAGE,yCAAA;YAAA,iCAAA;IACA,SAAA;I3D8oLL;EACF;A2DprLD;;;EA6CI,gBAAA;E3D4oLH;A2DzrLD;EAiDI,SAAA;E3D2oLH;A2D5rLD;;EAsDI,oBAAA;EACA,QAAA;EACA,aAAA;E3D0oLH;A2DlsLD;EA4DI,YAAA;E3DyoLH;A2DrsLD;EA+DI,aAAA;E3DyoLH;A2DxsLD;;EAmEI,SAAA;E3DyoLH;A2D5sLD;EAuEI,aAAA;E3DwoLH;A2D/sLD;EA0EI,YAAA;E3DwoLH;A2DhoLD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;ErC9FA,cAAA;EAGA,2BAAA;EqC6FA,iBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3DmoLD;A2D9nLC;EblGE,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9CmuLH;A2DloLC;EACE,YAAA;EACA,UAAA;EbvGA,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9C4uLH;A2DpoLC;;EAEE,YAAA;EACA,gBAAA;EACA,uBAAA;ErCtHF,cAAA;EAGA,2BAAA;EtB2vLD;A2DrqLD;;;;EAsCI,oBAAA;EACA,UAAA;EACA,YAAA;EACA,uBAAA;E3DqoLH;A2D9qLD;;EA6CI,WAAA;EACA,oBAAA;E3DqoLH;A2DnrLD;;EAkDI,YAAA;EACA,qBAAA;E3DqoLH;A2DxrLD;;EAuDI,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oBAAA;E3DqoLH;A2DhoLG;EACE,kBAAA;E3DkoLL;A2D9nLG;EACE,kBAAA;E3DgoLL;A2DtnLD;EACE,oBAAA;EACA,cAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;E3DwnLD;A2DjoLD;EAYI,uBAAA;EACA,aAAA;EACA,cAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;EACA,qBAAA;EACA,iBAAA;EAUA,2BAAA;EACA,oCAAA;E3D+mLH;A2D7oLD;EAiCI,WAAA;EACA,aAAA;EACA,cAAA;EACA,2BAAA;E3D+mLH;A2DxmLD;EACE,oBAAA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3D0mLD;A2DzmLC;EACE,mBAAA;E3D2mLH;A2DlkLD;EAhCE;;;;IAKI,aAAA;IACA,cAAA;IACA,mBAAA;IACA,iBAAA;I3DomLH;E2D5mLD;;IAYI,oBAAA;I3DomLH;E2DhnLD;;IAgBI,qBAAA;I3DomLH;E2D/lLD;IACE,WAAA;IACA,YAAA;IACA,sBAAA;I3DimLD;E2D7lLD;IACE,cAAA;I3D+lLD;EACF;A4D31LC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,cAAA;EACA,gBAAA;E5Dy3LH;A4Dv3LC;;;;;;;;;;;;;;;EACE,aAAA;E5Du4LH;AiC/4LD;E4BRE,gBAAA;EACA,mBAAA;EACA,oBAAA;E7D05LD;AiCj5LD;EACE,yBAAA;EjCm5LD;AiCj5LD;EACE,wBAAA;EjCm5LD;AiC34LD;EACE,0BAAA;EjC64LD;AiC34LD;EACE,2BAAA;EjC64LD;AiC34LD;EACE,oBAAA;EjC64LD;AiC34LD;E6BzBE,aAAA;EACA,oBAAA;EACA,mBAAA;EACA,+BAAA;EACA,WAAA;E9Du6LD;AiCz4LD;EACE,0BAAA;EACA,+BAAA;EjC24LD;AiCp4LD;EACE,iBAAA;EjCs4LD;A+Dx6LD;EACE,qBAAA;E/D06LD;A+Dp6LD;;;;ECdE,0BAAA;EhEw7LD;A+Dn6LD;;;;;;;;;;;;EAYE,0BAAA;E/Dq6LD;A+D95LD;EAAA;IChDE,2BAAA;IhEk9LC;EgEj9LD;IAAU,gBAAA;IhEo9LT;EgEn9LD;IAAU,+BAAA;IhEs9LT;EgEr9LD;;IACU,gCAAA;IhEw9LT;EACF;A+Dx6LD;EAAA;IAFI,2BAAA;I/D86LD;EACF;A+Dx6LD;EAAA;IAFI,4BAAA;I/D86LD;EACF;A+Dx6LD;EAAA;IAFI,kCAAA;I/D86LD;EACF;A+Dv6LD;EAAA;ICrEE,2BAAA;IhEg/LC;EgE/+LD;IAAU,gBAAA;IhEk/LT;EgEj/LD;IAAU,+BAAA;IhEo/LT;EgEn/LD;;IACU,gCAAA;IhEs/LT;EACF;A+Dj7LD;EAAA;IAFI,2BAAA;I/Du7LD;EACF;A+Dj7LD;EAAA;IAFI,4BAAA;I/Du7LD;EACF;A+Dj7LD;EAAA;IAFI,kCAAA;I/Du7LD;EACF;A+Dh7LD;EAAA;IC1FE,2BAAA;IhE8gMC;EgE7gMD;IAAU,gBAAA;IhEghMT;EgE/gMD;IAAU,+BAAA;IhEkhMT;EgEjhMD;;IACU,gCAAA;IhEohMT;EACF;A+D17LD;EAAA;IAFI,2BAAA;I/Dg8LD;EACF;A+D17LD;EAAA;IAFI,4BAAA;I/Dg8LD;EACF;A+D17LD;EAAA;IAFI,kCAAA;I/Dg8LD;EACF;A+Dz7LD;EAAA;IC/GE,2BAAA;IhE4iMC;EgE3iMD;IAAU,gBAAA;IhE8iMT;EgE7iMD;IAAU,+BAAA;IhEgjMT;EgE/iMD;;IACU,gCAAA;IhEkjMT;EACF;A+Dn8LD;EAAA;IAFI,2BAAA;I/Dy8LD;EACF;A+Dn8LD;EAAA;IAFI,4BAAA;I/Dy8LD;EACF;A+Dn8LD;EAAA;IAFI,kCAAA;I/Dy8LD;EACF;A+Dl8LD;EAAA;IC5HE,0BAAA;IhEkkMC;EACF;A+Dl8LD;EAAA;ICjIE,0BAAA;IhEukMC;EACF;A+Dl8LD;EAAA;ICtIE,0BAAA;IhE4kMC;EACF;A+Dl8LD;EAAA;IC3IE,0BAAA;IhEilMC;EACF;A+D/7LD;ECnJE,0BAAA;EhEqlMD;A+D57LD;EAAA;ICjKE,2BAAA;IhEimMC;EgEhmMD;IAAU,gBAAA;IhEmmMT;EgElmMD;IAAU,+BAAA;IhEqmMT;EgEpmMD;;IACU,gCAAA;IhEumMT;EACF;A+D18LD;EACE,0BAAA;E/D48LD;A+Dv8LD;EAAA;IAFI,2BAAA;I/D68LD;EACF;A+D38LD;EACE,0BAAA;E/D68LD;A+Dx8LD;EAAA;IAFI,4BAAA;I/D88LD;EACF;A+D58LD;EACE,0BAAA;E/D88LD;A+Dz8LD;EAAA;IAFI,kCAAA;I/D+8LD;EACF;A+Dx8LD;EAAA;ICpLE,0BAAA;IhEgoMC;EACF","file":"bootstrap.css","sourcesContent":["/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml {\n  font-family: sans-serif;\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\nmark {\n  background: #ff0;\n  color: #000;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\nsup {\n  top: -0.5em;\n}\nsub {\n  bottom: -0.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit;\n  font: inherit;\n  margin: 0;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n  border: 0;\n  padding: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    background: transparent !important;\n    color: #000 !important;\n    box-shadow: none !important;\n    text-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  select {\n    background: #fff !important;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  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');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\2a\";\n}\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n* {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333333;\n  background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n  -o-transition: all 0.2s ease-in-out;\n  transition: all 0.2s ease-in-out;\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  background-color: #fcf8e3;\n  padding: .2em;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n  margin-left: -5px;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-left: 5px;\n  padding-right: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    clear: left;\n    text-align: right;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n  text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #ffffff;\n  background-color: #333333;\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: #333333;\n  background-color: #f5f5f5;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.row {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0%;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .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-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .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-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0%;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .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-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0%;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n.table .table {\n  background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-child(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  float: none;\n  display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #dddddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  min-width: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555555;\n  background-color: #ffffff;\n  background-image: none;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n  color: #999999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n  opacity: 1;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"],\n  input[type=\"time\"],\n  input[type=\"datetime-local\"],\n  input[type=\"month\"] {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-sm,\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm,\nselect.form-group-sm .form-control {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\ntextarea.form-group-sm .form-control,\nselect[multiple].input-sm,\nselect[multiple].form-group-sm .form-control {\n  height: auto;\n}\n.input-lg,\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\nselect.input-lg,\nselect.form-group-lg .form-control {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\ntextarea.form-group-lg .form-control,\nselect[multiple].input-lg,\nselect[multiple].form-group-lg .form-control {\n  height: auto;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  border-color: #3c763d;\n  background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  border-color: #8a6d3b;\n  background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  border-color: #a94442;\n  background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  margin-top: 0;\n  margin-bottom: 0;\n  padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-left: -15px;\n  margin-right: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    text-align: right;\n    margin-bottom: 0;\n    padding-top: 7px;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 14.3px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n  }\n}\n.btn {\n  display: inline-block;\n  margin-bottom: 0;\n  font-weight: normal;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none;\n  border: 1px solid transparent;\n  white-space: nowrap;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  border-radius: 4px;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  outline: 0;\n  background-image: none;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  pointer-events: none;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn-default {\n  color: #333333;\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n.btn-default:hover,\n.btn-default:focus,\n.btn-default.focus,\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n.btn-default .badge {\n  color: #ffffff;\n  background-color: #333333;\n}\n.btn-primary {\n  color: #ffffff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #ffffff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #ffffff;\n}\n.btn-success {\n  color: #ffffff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:hover,\n.btn-success:focus,\n.btn-success.focus,\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #ffffff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #ffffff;\n}\n.btn-info {\n  color: #ffffff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:hover,\n.btn-info:focus,\n.btn-info.focus,\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #ffffff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #ffffff;\n}\n.btn-warning {\n  color: #ffffff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #ffffff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #ffffff;\n}\n.btn-danger {\n  color: #ffffff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #ffffff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #ffffff;\n}\n.btn-link {\n  color: #337ab7;\n  font-weight: normal;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n  -o-transition: opacity 0.15s linear;\n  transition: opacity 0.15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n  visibility: hidden;\n}\n.collapse.in {\n  display: block;\n  visibility: visible;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-property: height, visibility;\n  transition-property: height, visibility;\n  -webkit-transition-duration: 0.35s;\n  transition-duration: 0.35s;\n  -webkit-transition-timing-function: ease;\n  transition-timing-function: ease;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px solid;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  font-size: 14px;\n  text-align: left;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  text-decoration: none;\n  color: #262626;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  outline: 0;\n  background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  cursor: not-allowed;\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  left: auto;\n  right: 0;\n}\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px solid;\n  content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    left: auto;\n    right: 0;\n  }\n  .navbar-right .dropdown-menu-left {\n    left: 0;\n    right: auto;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child > .btn:last-child,\n.btn-group > .btn-group:first-child > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-bottom-left-radius: 4px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  float: none;\n  display: table-cell;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555555;\n  text-align: center;\n  background-color: #eeeeee;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  margin-left: -1px;\n}\n.nav {\n  margin-bottom: 0;\n  padding-left: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n  color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777777;\n  text-decoration: none;\n  background-color: transparent;\n  cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eeeeee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-bottom-color: transparent;\n  cursor: default;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #ffffff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  text-align: center;\n  margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n  visibility: hidden;\n}\n.tab-content > .active {\n  display: block;\n  visibility: visible;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: 15px;\n  padding-left: 15px;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n  -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    visibility: visible !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n  height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: 15px;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  margin-left: -15px;\n  margin-right: -15px;\n  padding: 10px 15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-left: 15px;\n    margin-right: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #cccccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  background-color: #e7e7e7;\n  color: #555555;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #cccccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333333;\n}\n.navbar-default .btn-link {\n  color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #cccccc;\n}\n.navbar-inverse {\n  background-color: #222222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  background-color: #080808;\n  color: #ffffff;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #ffffff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #ffffff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #ffffff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  content: \"/\\00a0\";\n  padding: 0 5px;\n  color: #cccccc;\n}\n.breadcrumb > .active {\n  color: #777777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  line-height: 1.42857143;\n  text-decoration: none;\n  color: #337ab7;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-bottom-right-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  color: #23527c;\n  background-color: #eeeeee;\n  border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n  cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777777;\n  background-color: #ffffff;\n  border-color: #dddddd;\n  cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-bottom-right-radius: 6px;\n  border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  list-style: none;\n  text-align: center;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777777;\n  background-color: #ffffff;\n  cursor: not-allowed;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #ffffff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  color: #ffffff;\n  line-height: 1;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: #777777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #ffffff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding: 30px 15px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding: 48px 0;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-left: 60px;\n    padding-right: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: border 0.2s ease-in-out;\n  -o-transition: border 0.2s ease-in-out;\n  transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-left: auto;\n  margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n  color: #3c763d;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n  color: #31708f;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n  color: #8a6d3b;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  background-color: #f2dede;\n  border-color: #ebccd1;\n  color: #a94442;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  overflow: hidden;\n  height: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #ffffff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n  -o-transition: width 0.6s ease;\n  transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n  -o-animation: progress-bar-stripes 2s linear infinite;\n  animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  margin-bottom: 20px;\n  padding-left: 0;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item {\n  color: #555555;\n}\na.list-group-item .list-group-item-heading {\n  color: #333333;\n}\na.list-group-item:hover,\na.list-group-item:focus {\n  text-decoration: none;\n  color: #555555;\n  background-color: #f5f5f5;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  background-color: #eeeeee;\n  color: #777777;\n  cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\na.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\na.list-group-item-success.active:hover,\na.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\na.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\na.list-group-item-info.active:hover,\na.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\na.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\na.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #dddddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-left: 15px;\n  padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-left-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  border: 0;\n  margin-bottom: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n  border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n  color: #333333;\n  background-color: #f5f5f5;\n  border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #dddddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #ffffff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  height: 100%;\n  width: 100%;\n  border: 0;\n}\n.embed-responsive.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n  color: #000000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transform: translate(0, -25%);\n  -ms-transform: translate(0, -25%);\n  -o-transform: translate(0, -25%);\n  transform: translate(0, -25%);\n  -webkit-transition: -webkit-transform 0.3s ease-out;\n  -moz-transition: -moz-transform 0.3s ease-out;\n  -o-transition: -o-transform 0.3s ease-out;\n  transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n  -ms-transform: translate(0, 0);\n  -o-transform: translate(0, 0);\n  transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #ffffff;\n  border: 1px solid #999999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  background-clip: padding-box;\n  outline: 0;\n}\n.modal-backdrop {\n  position: absolute;\n  top: 0;\n  right: 0;\n  left: 0;\n  background-color: #000000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n  min-height: 16.42857143px;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-left: 5px;\n  margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  visibility: visible;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-weight: normal;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.tooltip.in {\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.tooltip.top {\n  margin-top: -3px;\n  padding: 5px 0;\n}\n.tooltip.right {\n  margin-left: 3px;\n  padding: 0 5px;\n}\n.tooltip.bottom {\n  margin-top: 3px;\n  padding: 5px 0;\n}\n.tooltip.left {\n  margin-left: -3px;\n  padding: 0 5px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: #000000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n  bottom: 0;\n  right: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  background-color: #ffffff;\n  background-clip: padding-box;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  white-space: normal;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  margin: 0;\n  padding: 8px 14px;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n.popover.top > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-width: 0;\n  border-top-color: #999999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  bottom: -11px;\n}\n.popover.top > .arrow:after {\n  content: \" \";\n  bottom: 1px;\n  margin-left: -10px;\n  border-bottom-width: 0;\n  border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-left-width: 0;\n  border-right-color: #999999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n  content: \" \";\n  left: 1px;\n  bottom: -10px;\n  border-left-width: 0;\n  border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  top: -11px;\n}\n.popover.bottom > .arrow:after {\n  content: \" \";\n  top: 1px;\n  margin-left: -10px;\n  border-top-width: 0;\n  border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n  content: \" \";\n  right: 1px;\n  border-right-width: 0;\n  border-left-color: #ffffff;\n  bottom: -10px;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n}\n.carousel-inner > .item {\n  display: none;\n  position: relative;\n  -webkit-transition: 0.6s ease-in-out left;\n  -o-transition: 0.6s ease-in-out left;\n  transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    transition: transform 0.6s ease-in-out;\n    backface-visibility: hidden;\n    perspective: 1000;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    transform: translate3d(100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    transform: translate3d(-100%, 0, 0);\n    left: 0;\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    transform: translate3d(0, 0, 0);\n    left: 0;\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: 15%;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n  font-size: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n  left: auto;\n  right: 0;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  outline: 0;\n  color: #ffffff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  font-family: serif;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  border: 1px solid #ffffff;\n  border-radius: 10px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n  margin: 0;\n  width: 12px;\n  height: 12px;\n  background-color: #ffffff;\n}\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -15px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -15px;\n  }\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n  content: \" \";\n  display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n//    user zoom.\n//\n\nhtml {\n  font-family: sans-serif; // 1\n  -ms-text-size-adjust: 100%; // 2\n  -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n  margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; // 1\n  vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n  background-color: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n  outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n  font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n  font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n  border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n  margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n  overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n//    Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; // 1\n  font: inherit; // 2\n  margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n  overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n//    and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n//    `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n  cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n  line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; // 1\n  padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n//    (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; // 1\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; // 2\n  box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n  border: 0; // 1\n  padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n  overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n  font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n    *,\n    *:before,\n    *:after {\n        background: transparent !important;\n        color: #000 !important; // Black prints faster: h5bp.com/s\n        box-shadow: none !important;\n        text-shadow: none !important;\n    }\n\n    a,\n    a:visited {\n        text-decoration: underline;\n    }\n\n    a[href]:after {\n        content: \" (\" attr(href) \")\";\n    }\n\n    abbr[title]:after {\n        content: \" (\" attr(title) \")\";\n    }\n\n    // Don't show links that are fragment identifiers,\n    // or use the `javascript:` pseudo protocol\n    a[href^=\"#\"]:after,\n    a[href^=\"javascript:\"]:after {\n        content: \"\";\n    }\n\n    pre,\n    blockquote {\n        border: 1px solid #999;\n        page-break-inside: avoid;\n    }\n\n    thead {\n        display: table-header-group; // h5bp.com/t\n    }\n\n    tr,\n    img {\n        page-break-inside: avoid;\n    }\n\n    img {\n        max-width: 100% !important;\n    }\n\n    p,\n    h2,\n    h3 {\n        orphans: 3;\n        widows: 3;\n    }\n\n    h2,\n    h3 {\n        page-break-after: avoid;\n    }\n\n    // Bootstrap specific changes start\n    //\n    // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n    // Once fixed, we can just straight up remove this.\n    select {\n        background: #fff !important;\n    }\n\n    // Bootstrap components\n    .navbar {\n        display: none;\n    }\n    .btn,\n    .dropup > .btn {\n        > .caret {\n            border-top-color: #000 !important;\n        }\n    }\n    .label {\n        border: 1px solid #000;\n    }\n\n    .table {\n        border-collapse: collapse !important;\n\n        td,\n        th {\n            background-color: #fff !important;\n        }\n    }\n    .table-bordered {\n        th,\n        td {\n            border: 1px solid #ddd !important;\n        }\n    }\n\n    // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('@{icon-font-path}@{icon-font-name}.eot');\n  src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n       url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n       url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n       url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\2a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur                    { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n  .box-sizing(border-box);\n}\n*:before,\n*:after {\n  .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n  font-size: 10px;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @text-color;\n  background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n\n// Links\n\na {\n  color: @link-color;\n  text-decoration: none;\n\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: @link-hover-decoration;\n  }\n\n  &:focus {\n    .tab-focus();\n  }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n  margin: 0;\n}\n\n\n// Images\n\nimg {\n  vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n  .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n  border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n  padding: @thumbnail-padding;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  // Keep them at most 100% wide\n  .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n  border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n  margin-top:    @line-height-computed;\n  margin-bottom: @line-height-computed;\n  border: 0;\n  border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n       -o-animation: @animation;\n          animation: @animation;\n}\n.animation-name(@name) {\n  -webkit-animation-name: @name;\n          animation-name: @name;\n}\n.animation-duration(@duration) {\n  -webkit-animation-duration: @duration;\n          animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n  -webkit-animation-timing-function: @timing-function;\n          animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n  -webkit-animation-delay: @delay;\n          animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n  -webkit-animation-iteration-count: @iteration-count;\n          animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n  -webkit-animation-direction: @direction;\n          animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n  -webkit-animation-fill-mode: @fill-mode;\n          animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  // Firefox\n  &::-moz-placeholder {\n    color: @color;\n    opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n  }\n  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9 only\n       -o-transform: scale(@ratio);\n          transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n  -webkit-transform: scale(@ratioX, @ratioY);\n      -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n       -o-transform: scale(@ratioX, @ratioY);\n          transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n  -webkit-transform: scaleX(@ratio);\n      -ms-transform: scaleX(@ratio); // IE9 only\n       -o-transform: scaleX(@ratio);\n          transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n  -webkit-transform: scaleY(@ratio);\n      -ms-transform: scaleY(@ratio); // IE9 only\n       -o-transform: scaleY(@ratio);\n          transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n  -webkit-transform: skewX(@x) skewY(@y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n       -o-transform: skewX(@x) skewY(@y);\n          transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9 only\n       -o-transform: translate(@x, @y);\n          transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9 only\n       -o-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9 only\n       -o-transform: rotateX(@degrees);\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9 only\n       -o-transform: rotateY(@degrees);\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n      -ms-transform-origin: @origin; // IE9 only\n          transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n          user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n  // Default\n  outline: thin dotted;\n  // WebKit\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 300;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n  font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n  background-color: @state-warning-bg;\n  padding: .2em;\n}\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n.text-nowrap         { white-space: nowrap; }\n\n// Transformation\n.text-lowercase      { text-transform: lowercase; }\n.text-uppercase      { text-transform: uppercase; }\n.text-capitalize     { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n  margin-left: -5px;\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n  dd {\n    &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    dt {\n      float: left;\n      width: (@dl-horizontal-offset - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @dl-horizontal-offset;\n    }\n  }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: @blockquote-font-size;\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n  color: @color;\n  a&:hover {\n    color: darken(@color, 10%);\n  }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n  background-color: @color;\n  a&:hover {\n    background-color: darken(@color, 10%);\n  }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n  kbd {\n    padding: 0;\n    font-size: 100%;\n    font-weight: bold;\n    box-shadow: none;\n  }\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n  &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  (@gutter / -2);\n  margin-right: (@gutter / -2);\n  &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n  margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n  left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n  right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  min-height: 1px;\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  (@grid-gutter-width / 2);\n      padding-right: (@grid-gutter-width / 2);\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n  .col(@index) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col((@index + 1), ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n  .col-@{class}-push-0 {\n    left: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n  .col-@{class}-pull-0 {\n    right: auto;\n  }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n  .calc-grid-column(@index, @class, @type);\n  // next iteration\n  .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n  .float-grid-columns(@class);\n  .loop-grid-columns(@grid-columns, @class, width);\n  .loop-grid-columns(@grid-columns, @class, pull);\n  .loop-grid-columns(@grid-columns, @class, push);\n  .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  background-color: @table-bg;\n}\ncaption {\n  padding-top: @table-cell-padding;\n  padding-bottom: @table-cell-padding;\n  color: @text-muted;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-child(odd) {\n    background-color: @table-bg-accent;\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    background-color: @table-bg-hover;\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n  overflow-x: auto;\n  min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n  @media screen and (max-width: @screen-xs-max) {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table > thead > tr,\n  .table > tbody > tr,\n  .table > tfoot > tr {\n    > td.@{state},\n    > th.@{state},\n    &.@{state} > td,\n    &.@{state} > th {\n      background-color: @background;\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody > tr {\n    > td.@{state}:hover,\n    > th.@{state}:hover,\n    &.@{state}:hover > td,\n    &:hover > .@{state},\n    &.@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; // IE8-9\n  line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"],\n  input[type=\"time\"],\n  input[type=\"datetime-local\"],\n  input[type=\"month\"] {\n    line-height: @input-height-base;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm {\n    line-height: @input-height-small;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg {\n    line-height: @input-height-large;\n  }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n\n  label {\n    min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n    padding-left: 20px;\n    margin-bottom: 0;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  &[disabled],\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n  &.disabled,\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n  }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n  &.disabled,\n  fieldset[disabled] & {\n    label {\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  // Size it appropriately next to real form controls\n  padding-top: (@padding-base-vertical + 1);\n  padding-bottom: (@padding-base-vertical + 1);\n  // Remove default margin from `p`\n  margin-bottom: 0;\n\n  &.input-lg,\n  &.input-sm {\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm,\n.form-group-sm .form-control {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n\n.input-lg,\n.form-group-lg .form-control {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2; // Ensure icon is above input groups\n  display: block;\n  width: @input-height-base;\n  height: @input-height-base;\n  line-height: @input-height-base;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n  width: @input-height-large;\n  height: @input-height-large;\n  line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback {\n  width: @input-height-small;\n  height: @input-height-small;\n  line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n  & ~ .form-control-feedback {\n     top: (@line-height-computed + 5); // Height of the `label` and its margin\n  }\n  &.sr-only ~ .form-control-feedback {\n     top: 0;\n  }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n\n    // Make static controls behave like regular ones\n    .form-control-static {\n      display: inline-block;\n    }\n\n    .input-group {\n      display: inline-table;\n      vertical-align: middle;\n\n      .input-group-addon,\n      .input-group-btn,\n      .form-control {\n        width: auto;\n      }\n    }\n\n    // Input groups need that 100% width though\n    .input-group > .form-control {\n      width: 100%;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match (which also avoids\n    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      vertical-align: middle;\n\n      label {\n        padding-left: 0;\n      }\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      position: relative;\n      margin-left: 0;\n    }\n\n    // Re-override the feedback icon.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of radios and checkboxes\n  //\n  // Labels also get some reset styles, but that is scoped to a media query below.\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  // Reset spacing and right align labels, but scope to media queries so that\n  // labels on narrow viewports stack the same as a default form example.\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n      margin-bottom: 0;\n      padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    right: (@grid-gutter-width / 2);\n  }\n\n  // Form group sizes\n  //\n  // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n  // inputs and labels within a `.form-group`.\n  .form-group-lg {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: ((@padding-large-vertical * @line-height-large) + 1);\n      }\n    }\n  }\n  .form-group-sm {\n    @media (min-width: @screen-sm-min) {\n      .control-label {\n        padding-top: (@padding-small-vertical + 1);\n      }\n    }\n  }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline,\n  &.radio label,\n  &.checkbox label,\n  &.radio-inline label,\n  &.checkbox-inline label  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n  // Optional feedback icon\n  .form-control-feedback {\n    color: @text-color;\n  }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  touch-action: manipulation;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n  .user-select(none);\n\n  &,\n  &:active,\n  &.active {\n    &:focus,\n    &.focus {\n      .tab-focus();\n    }\n  }\n\n  &:hover,\n  &:focus,\n  &.focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: @cursor-disabled;\n    pointer-events: none; // Future-proof disabling of clicks\n    .opacity(.65);\n    .box-shadow(none);\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &.active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:hover,\n  &:focus,\n  &.focus,\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 10%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open > .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &.focus,\n    &:active,\n    &.active {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: @color;\n  }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n  visibility: hidden;\n\n  &.in      { display: block; visibility: visible; }\n  tr&.in    { display: table-row; }\n  tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition-property(~\"height, visibility\");\n  .transition-duration(.35s);\n  .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base solid;\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n\n  // Nuke hover/focus effects\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: @cursor-disabled;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n  white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base solid;\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 1px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    border-top-right-radius: @border-radius-base;\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    border-bottom-left-radius: @border-radius-base;\n    .border-top-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n\n  > .btn-group .dropdown-menu {\n    left: auto;\n  }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n  > .btn,\n  > .btn-group > .btn {\n    input[type=\"radio\"],\n    input[type=\"checkbox\"] {\n      position: absolute;\n      clip: rect(0,0,0,0);\n      pointer-events: none;\n    }\n  }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // Ensure that the input is always above the *appended* addon button for\n    // proper border colors.\n    position: relative;\n    z-index: 2;\n\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @border-radius-base;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: @cursor-disabled;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n    > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n    visibility: hidden;\n  }\n  > .active {\n    display: block;\n    visibility: visible;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      visibility: visible !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  .navbar-collapse {\n    max-height: @navbar-collapse-max-height;\n\n    @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n      max-height: 200px;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: -@navbar-padding-horizontal;\n    margin-left:  -@navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @navbar-height;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  > img {\n    display: block;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: 0;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n  }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n\n      &:last-child {\n        margin-bottom: 0;\n      }\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  .border-top-radius(@navbar-border-radius);\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right {\n    .pull-right();\n    margin-right: -@navbar-padding-horizontal;\n\n    ~ .navbar-right {\n      margin-right: 0;\n    }\n  }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-default-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n      }\n    }\n  }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n  .btn-link {\n    color: @navbar-inverse-link-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-link-hover-color;\n    }\n    &[disabled],\n    fieldset[disabled] & {\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n      }\n    }\n  }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: @cursor-disabled;\n    }\n  }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n  background-color: @color;\n\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n  .btn-xs & {\n    top: 0;\n    padding: 1px 5px;\n  }\n\n  // Hover state, but only for links\n  a& {\n    &:hover,\n    &:focus {\n      color: @badge-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Account for badges in navs\n  .list-group-item.active > &,\n  .nav-pills > .active > a > & {\n    color: @badge-active-color;\n    background-color: @badge-active-bg;\n  }\n  .list-group-item > & {\n    float: right;\n  }\n  .list-group-item > & + & {\n    margin-right: 5px;\n  }\n  .nav-pills > li > a > & {\n    margin-left: 3px;\n  }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding: @jumbotron-padding (@jumbotron-padding / 2);\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  > hr {\n    border-top-color: darken(@jumbotron-bg, 10%);\n  }\n\n  .container &,\n  .container-fluid & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding: (@jumbotron-padding * 1.6) 0;\n\n    .container &,\n    .container-fluid & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: (@font-size-base * 4.5);\n    }\n  }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(border .2s ease-in-out);\n\n  > img,\n  a > img {\n    &:extend(.img-responsive);\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n  padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @progress-border-radius;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n  background-color: @color;\n\n  // Deprecated parent class requirement as of v3.2.0\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n",".media {\n  // Proper spacing between instances of .media\n  margin-top: 15px;\n\n  &:first-child {\n    margin-top: 0;\n  }\n}\n\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n\n.media-middle {\n  vertical-align: middle;\n}\n\n.media-bottom {\n  vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  // No need to set list-style: none; since .list-group-item is block level\n  margin-bottom: 20px;\n  padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  // Place the border on the list items and negative margin up for better styling\n  margin-bottom: -1px;\n  background-color: @list-group-bg;\n  border: 1px solid @list-group-border;\n\n  // Round the first and last items\n  &:first-child {\n    .border-top-radius(@list-group-border-radius);\n  }\n  &:last-child {\n    margin-bottom: 0;\n    .border-bottom-radius(@list-group-border-radius);\n  }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n  color: @list-group-link-color;\n\n  .list-group-item-heading {\n    color: @list-group-link-heading-color;\n  }\n\n  // Hover state\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @list-group-link-hover-color;\n    background-color: @list-group-hover-bg;\n  }\n}\n\n.list-group-item {\n  // Disabled state\n  &.disabled,\n  &.disabled:hover,\n  &.disabled:focus {\n    background-color: @list-group-disabled-bg;\n    color: @list-group-disabled-color;\n    cursor: @cursor-disabled;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-disabled-text-color;\n    }\n  }\n\n  // Active class on item itself, not parent\n  &.active,\n  &.active:hover,\n  &.active:focus {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: @list-group-active-color;\n    background-color: @list-group-active-bg;\n    border-color: @list-group-active-border;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading,\n    .list-group-item-heading > small,\n    .list-group-item-heading > .small {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: @list-group-active-text-color;\n    }\n  }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n  .list-group-item-@{state} {\n    color: @color;\n    background-color: @background;\n\n    a& {\n      color: @color;\n\n      .list-group-item-heading {\n        color: inherit;\n      }\n\n      &:hover,\n      &:focus {\n        color: @color;\n        background-color: darken(@background, 5%);\n      }\n      &.active,\n      &.active:hover,\n      &.active:focus {\n        color: #fff;\n        background-color: @color;\n        border-color: @color;\n      }\n    }\n  }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: @line-height-computed;\n  background-color: @panel-bg;\n  border: 1px solid transparent;\n  border-radius: @panel-border-radius;\n  .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n  padding: @panel-body-padding;\n  &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n  padding: @panel-heading-padding;\n  border-bottom: 1px solid transparent;\n  .border-top-radius((@panel-border-radius - 1));\n\n  > .dropdown .dropdown-toggle {\n    color: inherit;\n  }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: ceil((@font-size-base * 1.125));\n  color: inherit;\n\n  > a {\n    color: inherit;\n  }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n  padding: @panel-footer-padding;\n  background-color: @panel-footer-bg;\n  border-top: 1px solid @panel-inner-border;\n  .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n  > .list-group,\n  > .panel-collapse > .list-group {\n    margin-bottom: 0;\n\n    .list-group-item {\n      border-width: 1px 0;\n      border-radius: 0;\n    }\n\n    // Add border top radius for first one\n    &:first-child {\n      .list-group-item:first-child {\n        border-top: 0;\n        .border-top-radius((@panel-border-radius - 1));\n      }\n    }\n    // Add border bottom radius for last one\n    &:last-child {\n      .list-group-item:last-child {\n        border-bottom: 0;\n        .border-bottom-radius((@panel-border-radius - 1));\n      }\n    }\n  }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n  .list-group-item:first-child {\n    border-top-width: 0;\n  }\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n  > .table,\n  > .table-responsive > .table,\n  > .panel-collapse > .table {\n    margin-bottom: 0;\n\n    caption {\n      padding-left: @panel-body-padding;\n      padding-right: @panel-body-padding;\n    }\n  }\n  // Add border top radius for first one\n  > .table:first-child,\n  > .table-responsive:first-child > .table:first-child {\n    .border-top-radius((@panel-border-radius - 1));\n\n    > thead:first-child,\n    > tbody:first-child {\n      > tr:first-child {\n        border-top-left-radius: (@panel-border-radius - 1);\n        border-top-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-top-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-top-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  // Add border bottom radius for last one\n  > .table:last-child,\n  > .table-responsive:last-child > .table:last-child {\n    .border-bottom-radius((@panel-border-radius - 1));\n\n    > tbody:last-child,\n    > tfoot:last-child {\n      > tr:last-child {\n        border-bottom-left-radius: (@panel-border-radius - 1);\n        border-bottom-right-radius: (@panel-border-radius - 1);\n\n        td:first-child,\n        th:first-child {\n          border-bottom-left-radius: (@panel-border-radius - 1);\n        }\n        td:last-child,\n        th:last-child {\n          border-bottom-right-radius: (@panel-border-radius - 1);\n        }\n      }\n    }\n  }\n  > .panel-body + .table,\n  > .panel-body + .table-responsive,\n  > .table + .panel-body,\n  > .table-responsive + .panel-body {\n    border-top: 1px solid @table-border-color;\n  }\n  > .table > tbody:first-child > tr:first-child th,\n  > .table > tbody:first-child > tr:first-child td {\n    border-top: 0;\n  }\n  > .table-bordered,\n  > .table-responsive > .table-bordered {\n    border: 0;\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th:first-child,\n        > td:first-child {\n          border-left: 0;\n        }\n        > th:last-child,\n        > td:last-child {\n          border-right: 0;\n        }\n      }\n    }\n    > thead,\n    > tbody {\n      > tr:first-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n    > tbody,\n    > tfoot {\n      > tr:last-child {\n        > td,\n        > th {\n          border-bottom: 0;\n        }\n      }\n    }\n  }\n  > .table-responsive {\n    border: 0;\n    margin-bottom: 0;\n  }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n  margin-bottom: @line-height-computed;\n\n  // Tighten up margin so it's only between panels\n  .panel {\n    margin-bottom: 0;\n    border-radius: @panel-border-radius;\n\n    + .panel {\n      margin-top: 5px;\n    }\n  }\n\n  .panel-heading {\n    border-bottom: 0;\n\n    + .panel-collapse > .panel-body,\n    + .panel-collapse > .list-group {\n      border-top: 1px solid @panel-inner-border;\n    }\n  }\n\n  .panel-footer {\n    border-top: 0;\n    + .panel-collapse .panel-body {\n      border-bottom: 1px solid @panel-inner-border;\n    }\n  }\n}\n\n\n// Contextual variations\n.panel-default {\n  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse > .panel-body {\n      border-top-color: @border;\n    }\n    .badge {\n      color: @heading-bg-color;\n      background-color: @heading-text-color;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse > .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n\n  .embed-responsive-item,\n  iframe,\n  embed,\n  object,\n  video {\n    position: absolute;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    height: 100%;\n    width: 100%;\n    border: 0;\n  }\n\n  // Modifier class for 16:9 aspect ratio\n  &.embed-responsive-16by9 {\n    padding-bottom: 56.25%;\n  }\n\n  // Modifier class for 4:3 aspect ratio\n  &.embed-responsive-4by3 {\n    padding-bottom: 75%;\n  }\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: @well-bg;\n  border: 1px solid @well-border;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n  blockquote {\n    border-color: #ddd;\n    border-color: rgba(0,0,0,.15);\n  }\n}\n\n// Sizes\n.well-lg {\n  padding: 24px;\n  border-radius: @border-radius-large;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: (@font-size-base * 1.5);\n  font-weight: @close-font-weight;\n  line-height: 1;\n  color: @close-color;\n  text-shadow: @close-text-shadow;\n  .opacity(.2);\n\n  &:hover,\n  &:focus {\n    color: @close-color;\n    text-decoration: none;\n    cursor: pointer;\n    .opacity(.5);\n  }\n\n  // Additional properties for button version\n  // iOS requires the button element instead of an anchor tag.\n  // If you want the anchor version, it requires `href=\"#\"`.\n  button& {\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n  }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: hidden;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal;\n  -webkit-overflow-scrolling: touch;\n\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~\"0.3s ease-out\");\n  }\n  &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n  position: absolute;\n  top: 0;\n  right: 0;\n  left: 0;\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  padding: @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-group .btn + .btn {\n    margin-left: -1px;\n  }\n  // and override it for block buttons as well\n  .btn-block + .btn-block {\n    margin-left: 0;\n  }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    width: @modal-md;\n    margin: 30px auto;\n  }\n  .modal-content {\n    .box-shadow(0 5px 15px rgba(0,0,0,.5));\n  }\n\n  // Modal sizes\n  .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n  .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  z-index: @zindex-tooltip;\n  display: block;\n  visibility: visible;\n  // Reset font and text propertes given new insertion method\n  font-family: @font-family-base;\n  font-size: @font-size-small;\n  font-weight: normal;\n  line-height: 1.4;\n  .opacity(0);\n\n  &.in     { .opacity(@tooltip-opacity); }\n  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }\n  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }\n  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }\n  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: @tooltip-max-width;\n  padding: 3px 8px;\n  color: @tooltip-color;\n  text-align: center;\n  text-decoration: none;\n  background-color: @tooltip-bg;\n  border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n  &.top .tooltip-arrow {\n    bottom: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-left .tooltip-arrow {\n    bottom: 0;\n    right: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-right .tooltip-arrow {\n    bottom: 0;\n    left: @tooltip-arrow-width;\n    margin-bottom: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.right .tooltip-arrow {\n    top: 50%;\n    left: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-right-color: @tooltip-arrow-color;\n  }\n  &.left .tooltip-arrow {\n    top: 50%;\n    right: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-left-color: @tooltip-arrow-color;\n  }\n  &.bottom .tooltip-arrow {\n    top: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-left .tooltip-arrow {\n    top: 0;\n    right: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-right .tooltip-arrow {\n    top: 0;\n    left: @tooltip-arrow-width;\n    margin-top: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: @zindex-popover;\n  display: none;\n  max-width: @popover-max-width;\n  padding: 1px;\n  // Reset font and text propertes given new insertion method\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: @line-height-base;\n  text-align: left;\n  background-color: @popover-bg;\n  background-clip: padding-box;\n  border: 1px solid @popover-fallback-border-color;\n  border: 1px solid @popover-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n  // Overrides for proper insertion\n  white-space: normal;\n\n  // Offset the popover to account for the popover arrow\n  &.top     { margin-top: -@popover-arrow-width; }\n  &.right   { margin-left: @popover-arrow-width; }\n  &.bottom  { margin-top: @popover-arrow-width; }\n  &.left    { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n  margin: 0; // reset heading margin\n  padding: 8px 14px;\n  font-size: @font-size-base;\n  background-color: @popover-title-bg;\n  border-bottom: 1px solid darken(@popover-title-bg, 5%);\n  border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n  &,\n  &:after {\n    position: absolute;\n    display: block;\n    width: 0;\n    height: 0;\n    border-color: transparent;\n    border-style: solid;\n  }\n}\n.popover > .arrow {\n  border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n  border-width: @popover-arrow-width;\n  content: \"\";\n}\n\n.popover {\n  &.top > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-bottom-width: 0;\n    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-top-color: @popover-arrow-outer-color;\n    bottom: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      bottom: 1px;\n      margin-left: -@popover-arrow-width;\n      border-bottom-width: 0;\n      border-top-color: @popover-arrow-color;\n    }\n  }\n  &.right > .arrow {\n    top: 50%;\n    left: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-left-width: 0;\n    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-right-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      left: 1px;\n      bottom: -@popover-arrow-width;\n      border-left-width: 0;\n      border-right-color: @popover-arrow-color;\n    }\n  }\n  &.bottom > .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-top-width: 0;\n    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-bottom-color: @popover-arrow-outer-color;\n    top: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      top: 1px;\n      margin-left: -@popover-arrow-width;\n      border-top-width: 0;\n      border-bottom-color: @popover-arrow-color;\n    }\n  }\n\n  &.left > .arrow {\n    top: 50%;\n    right: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-right-width: 0;\n    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-left-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      right: 1px;\n      border-right-width: 0;\n      border-left-color: @popover-arrow-color;\n      bottom: -@popover-arrow-width;\n    }\n  }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      &:extend(.img-responsive);\n      line-height: 1;\n    }\n\n    // WebKit CSS3 transforms for supported devices\n    @media all and (transform-3d), (-webkit-transform-3d) {\n      transition: transform .6s ease-in-out;\n      backface-visibility: hidden;\n      perspective: 1000;\n\n      &.next,\n      &.active.right {\n        transform: translate3d(100%, 0, 0);\n        left: 0;\n      }\n      &.prev,\n      &.active.left {\n        transform: translate3d(-100%, 0, 0);\n        left: 0;\n      }\n      &.next.left,\n      &.prev.right,\n      &.active {\n        transform: translate3d(0, 0, 0);\n        left: 0;\n      }\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev {\n    display: block;\n  }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: 0;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n    margin-left: -10px;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n    margin-right: -10px;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    margin-top: -10px;\n    font-family: serif;\n  }\n\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicon-chevron-left,\n    .glyphicon-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: 30px;\n      height: 30px;\n      margin-top: -15px;\n      font-size: 30px;\n    }\n    .glyphicon-chevron-left,\n    .icon-prev {\n      margin-left: -15px;\n    }\n    .glyphicon-chevron-right,\n    .icon-next {\n      margin-right: -15px;\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n","// Center-align a block level element\n\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n  width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n\n.visible-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-visibility();\n  }\n}\n.visible-xs-block {\n  @media (max-width: @screen-xs-max) {\n    display: block !important;\n  }\n}\n.visible-xs-inline {\n  @media (max-width: @screen-xs-max) {\n    display: inline !important;\n  }\n}\n.visible-xs-inline-block {\n  @media (max-width: @screen-xs-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-visibility();\n  }\n}\n.visible-sm-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: block !important;\n  }\n}\n.visible-sm-inline {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline !important;\n  }\n}\n.visible-sm-inline-block {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-visibility();\n  }\n}\n.visible-md-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: block !important;\n  }\n}\n.visible-md-inline {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline !important;\n  }\n}\n.visible-md-inline-block {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    display: inline-block !important;\n  }\n}\n\n.visible-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-visibility();\n  }\n}\n.visible-lg-block {\n  @media (min-width: @screen-lg-min) {\n    display: block !important;\n  }\n}\n.visible-lg-inline {\n  @media (min-width: @screen-lg-min) {\n    display: inline !important;\n  }\n}\n.visible-lg-inline-block {\n  @media (min-width: @screen-lg-min) {\n    display: inline-block !important;\n  }\n}\n\n.hidden-xs {\n  @media (max-width: @screen-xs-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-sm {\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-md {\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-invisibility();\n  }\n}\n.hidden-lg {\n  @media (min-width: @screen-lg-min) {\n    .responsive-invisibility();\n  }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n  .responsive-invisibility();\n\n  @media print {\n    .responsive-visibility();\n  }\n}\n.visible-print-block {\n  display: none !important;\n\n  @media print {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n\n  @media print {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n\n  @media print {\n    display: inline-block !important;\n  }\n}\n\n.hidden-print {\n  @media print {\n    .responsive-invisibility();\n  }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n  display: none !important;\n}\n"]}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap.min.css b/src/main/resources/META-INF/resources/designer/css/bootstrap.min.css
new file mode 100644 (file)
index 0000000..6b11f49
--- /dev/null
@@ -0,0 +1,5 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{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,.glyphicon-eur: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}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;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}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>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,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.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,.h4,h5,.h5,h6,.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%}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:#337ab7}a.text-primary:hover{color:#286090}.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:#337ab7}a.bg-primary:hover{background-color:#286090}.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}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{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}dt,dd{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[title],abbr[data-original-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 p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small: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 footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}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%;font-weight:700;-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-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{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-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{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-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{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-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{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}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{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>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{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>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{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=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]: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:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.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}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox 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}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.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 .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{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 .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{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 .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{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~.form-control-feedback{top:25px}.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 .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{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{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;-ms-touch-action:manipulation;touch-action:manipulation;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:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{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;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.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],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.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],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{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:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.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],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{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:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.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],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{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:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.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],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{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=submit].btn-block,input[type=reset].btn-block,input[type=button].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;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.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:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.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>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.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=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.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}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].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}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control: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=radio],.input-group-addon input[type=checkbox]{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:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{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:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{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:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{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:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.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:hover,.nav-tabs>li.active>a:focus{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:hover,.nav-tabs.nav-justified>.active>a:focus{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:hover,.nav-tabs.nav-justified>.active>a:focus{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:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.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:hover,.nav-tabs-justified>.active>a:focus{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:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.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;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{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-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{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:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@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>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{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-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 .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{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}.navbar-form .form-group:last-child{margin-bottom:0}}@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-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-top-left-radius:4px;border-top-right-radius:4px;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}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{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:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{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:hover,.navbar-default .navbar-nav>.open>a:focus{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:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{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:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{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:hover,.navbar-inverse .navbar-nav>.open>a:focus{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:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{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:#337ab7;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:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{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:hover,.pager li>a:focus{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:hover,.pager .disabled>a:focus,.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:hover,a.label:focus{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]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{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:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;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,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .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:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.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:#337ab7;-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-striped .progress-bar,.progress-bar-striped{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.active .progress-bar,.progress-bar.active{-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-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{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.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}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.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:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{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:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{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:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{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:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{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,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.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,.panel>.panel-collapse>.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>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.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,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.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,.panel-group .panel-heading+.panel-collapse>.list-group{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:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.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 iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{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;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);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:1040;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:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(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:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;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-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);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{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;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;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-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;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;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;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>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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);filter:alpha(opacity=50);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%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);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%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{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:#000 \9;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-prev,.carousel-control .icon-next{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}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer: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}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-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}th.visible-xs,td.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}th.visible-sm,td.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}th.visible-md,td.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}th.visible-lg,td.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}th.visible-print,td.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}}
diff --git a/src/main/resources/META-INF/resources/designer/css/bootstrap_custom.css b/src/main/resources/META-INF/resources/designer/css/bootstrap_custom.css
new file mode 100644 (file)
index 0000000..1803cde
--- /dev/null
@@ -0,0 +1,6531 @@
+@import url("//fonts.googleapis.com/css?family=Raleway:400,700");
+/*!
+ * bootswatch v3.3.1+1
+ * Homepage: http://bootswatch.com
+ * Copyright 2012-2014 Thomas Park
+ * Licensed under MIT
+ * Based on Bootstrap
+*/
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+html {
+  font-family: sans-serif;
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block;
+}
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  vertical-align: baseline;
+}
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+[hidden],
+template {
+  display: none;
+}
+a {
+  background-color: transparent;
+}
+a:active,
+a:hover {
+  outline: 0;
+}
+abbr[title] {
+  border-bottom: 1px dotted;
+}
+b,
+strong {
+  font-weight: bold;
+}
+dfn {
+  font-style: italic;
+}
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+mark {
+  background: #ff0;
+  color: #000;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+img {
+  border: 0;
+}
+svg:not(:root) {
+  overflow: hidden;
+}
+figure {
+  margin: 1em 40px;
+}
+hr {
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+          box-sizing: content-box;
+  height: 0;
+}
+pre {
+  overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  color: inherit;
+  font: inherit;
+  margin: 0;
+}
+button {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+  cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  border: 0;
+  padding: 0;
+}
+input {
+  line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-appearance: textfield;
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em;
+}
+legend {
+  border: 0;
+  padding: 0;
+}
+textarea {
+  overflow: auto;
+}
+optgroup {
+  font-weight: bold;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+td,
+th {
+  padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+  *,
+  *:before,
+  *:after {
+    background: transparent !important;
+    color: #000 !important;
+    -webkit-box-shadow: none !important;
+            box-shadow: none !important;
+    text-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  a[href]:after {
+    content: " (" attr(href) ")";
+  }
+  abbr[title]:after {
+    content: " (" attr(title) ")";
+  }
+  a[href^="#"]:after,
+  a[href^="javascript:"]:after {
+    content: "";
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  img {
+    max-width: 100% !important;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  select {
+    background: #fff !important;
+  }
+  .navbar {
+    display: none;
+  }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important;
+  }
+  .label {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    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: normal;
+  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,
+.glyphicon-eur: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;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+html {
+  font-size: 10px;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+  font-family: Georgia, "Times New Roman", Times, serif;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #333333;
+  background-color: #ffffff;
+}
+input,
+button,
+select,
+textarea {
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+a {
+  color: #4582ec;
+  text-decoration: none;
+}
+a:hover,
+a:focus {
+  color: #134fb8;
+  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;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+  display: block;
+  max-width: 100%;
+  height: auto;
+}
+.img-rounded {
+  border-radius: 6px;
+}
+.img-thumbnail {
+  padding: 4px;
+  line-height: 1.42857143;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+  -webkit-transition: all 0.2s ease-in-out;
+  -o-transition: all 0.2s ease-in-out;
+  transition: all 0.2s ease-in-out;
+  display: inline-block;
+  max-width: 100%;
+  height: auto;
+}
+.img-circle {
+  border-radius: 50%;
+}
+hr {
+  margin-top: 22px;
+  margin-bottom: 22px;
+  border: 0;
+  border-top: 1px solid #eeeeee;
+}
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  margin: -1px;
+  padding: 0;
+  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: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-weight: bold;
+  line-height: 1.1;
+  color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+  font-weight: normal;
+  line-height: 1;
+  color: #b3b3b3;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+  margin-top: 22px;
+  margin-bottom: 11px;
+}
+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,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+  margin-top: 11px;
+  margin-bottom: 11px;
+}
+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: 41px;
+}
+h2,
+.h2 {
+  font-size: 34px;
+}
+h3,
+.h3 {
+  font-size: 28px;
+}
+h4,
+.h4 {
+  font-size: 20px;
+}
+h5,
+.h5 {
+  font-size: 16px;
+}
+h6,
+.h6 {
+  font-size: 14px;
+}
+p {
+  margin: 0 0 11px;
+}
+.lead {
+  margin-bottom: 22px;
+  font-size: 18px;
+  font-weight: 300;
+  line-height: 1.4;
+}
+@media (min-width: 768px) {
+  .lead {
+    font-size: 24px;
+  }
+}
+small,
+.small {
+  font-size: 87%;
+}
+mark,
+.mark {
+  background-color: #fcf8e3;
+  padding: .2em;
+}
+.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: #b3b3b3;
+}
+.text-primary {
+  color: #4582ec;
+}
+a.text-primary:hover {
+  color: #1863e6;
+}
+.text-success {
+  color: #3fad46;
+}
+a.text-success:hover {
+  color: #318837;
+}
+.text-info {
+  color: #5bc0de;
+}
+a.text-info:hover {
+  color: #31b0d5;
+}
+.text-warning {
+  color: #f0ad4e;
+}
+a.text-warning:hover {
+  color: #ec971f;
+}
+.text-danger {
+  color: #d9534f;
+}
+a.text-danger:hover {
+  color: #c9302c;
+}
+.bg-primary {
+  color: #fff;
+  background-color: #4582ec;
+}
+a.bg-primary:hover {
+  background-color: #1863e6;
+}
+.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: 10px;
+  margin: 44px 0 22px;
+  border-bottom: 1px solid #dddddd;
+}
+ul,
+ol {
+  margin-top: 0;
+  margin-bottom: 11px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+  margin-bottom: 0;
+}
+.list-unstyled {
+  padding-left: 0;
+  list-style: none;
+}
+.list-inline {
+  padding-left: 0;
+  list-style: none;
+  margin-left: -5px;
+}
+.list-inline > li {
+  display: inline-block;
+  padding-left: 5px;
+  padding-right: 5px;
+}
+dl {
+  margin-top: 0;
+  margin-bottom: 22px;
+}
+dt,
+dd {
+  line-height: 1.42857143;
+}
+dt {
+  font-weight: bold;
+}
+dd {
+  margin-left: 0;
+}
+@media (min-width: 768px) {
+  .dl-horizontal dt {
+    float: left;
+    width: 160px;
+    clear: left;
+    text-align: right;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .dl-horizontal dd {
+    margin-left: 180px;
+  }
+}
+abbr[title],
+abbr[data-original-title] {
+  cursor: help;
+  border-bottom: 1px dotted #b3b3b3;
+}
+.initialism {
+  font-size: 90%;
+  text-transform: uppercase;
+}
+blockquote {
+  padding: 11px 22px;
+  margin: 0 0 22px;
+  font-size: 20px;
+  border-left: 5px solid #4582ec;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+  margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+  display: block;
+  font-size: 80%;
+  line-height: 1.42857143;
+  color: #333333;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+  content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+  padding-right: 15px;
+  padding-left: 0;
+  border-right: 5px solid #4582ec;
+  border-left: 0;
+  text-align: right;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+  content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+  content: '\00A0 \2014';
+}
+address {
+  margin-bottom: 22px;
+  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: #ffffff;
+  background-color: #333333;
+  border-radius: 3px;
+  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+kbd kbd {
+  padding: 0;
+  font-size: 100%;
+  font-weight: bold;
+  -webkit-box-shadow: none;
+          box-shadow: none;
+}
+pre {
+  display: block;
+  padding: 10.5px;
+  margin: 0 0 11px;
+  font-size: 15px;
+  line-height: 1.42857143;
+  word-break: break-all;
+  word-wrap: break-word;
+  color: #333333;
+  background-color: #f5f5f5;
+  border: 1px solid #cccccc;
+  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 {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+@media (min-width: 768px) {
+  .container {
+    width: 750px;
+  }
+}
+@media (min-width: 992px) {
+  .container {
+    width: 970px;
+  }
+}
+@media (min-width: 1200px) {
+  .container {
+    width: 1170px;
+  }
+}
+.container-fluid {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.row {
+  margin-left: -15px;
+  margin-right: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+  position: relative;
+  min-height: 1px;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+  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-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+    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-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+    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-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+    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;
+}
+caption {
+  padding-top: 8px;
+  padding-bottom: 8px;
+  color: #b3b3b3;
+  text-align: left;
+}
+th {
+  text-align: left;
+}
+.table {
+  width: 100%;
+  max-width: 100%;
+  margin-bottom: 22px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+  padding: 8px;
+  line-height: 1.42857143;
+  vertical-align: top;
+  border-top: 1px solid #dddddd;
+}
+.table > thead > tr > th {
+  vertical-align: bottom;
+  border-bottom: 2px solid #dddddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+  border-top: 0;
+}
+.table > tbody + tbody {
+  border-top: 2px solid #dddddd;
+}
+.table .table {
+  background-color: #ffffff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+  padding: 5px;
+}
+.table-bordered {
+  border: 1px solid #dddddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+  border: 1px solid #dddddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+  border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-child(odd) {
+  background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+  background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+  position: static;
+  float: none;
+  display: table-column;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+  position: static;
+  float: none;
+  display: table-cell;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+  background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+  background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+  background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+  background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+  background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+  background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+  background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+  background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+  background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+  background-color: #ebcccc;
+}
+.table-responsive {
+  overflow-x: auto;
+  min-height: 0.01%;
+}
+@media screen and (max-width: 767px) {
+  .table-responsive {
+    width: 100%;
+    margin-bottom: 16.5px;
+    overflow-y: hidden;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+    border: 1px solid #dddddd;
+  }
+  .table-responsive > .table {
+    margin-bottom: 0;
+  }
+  .table-responsive > .table > thead > tr > th,
+  .table-responsive > .table > tbody > tr > th,
+  .table-responsive > .table > tfoot > tr > th,
+  .table-responsive > .table > thead > tr > td,
+  .table-responsive > .table > tbody > tr > td,
+  .table-responsive > .table > tfoot > tr > td {
+    white-space: nowrap;
+  }
+  .table-responsive > .table-bordered {
+    border: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:first-child,
+  .table-responsive > .table-bordered > tbody > tr > th:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+  .table-responsive > .table-bordered > thead > tr > td:first-child,
+  .table-responsive > .table-bordered > tbody > tr > td:first-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+    border-left: 0;
+  }
+  .table-responsive > .table-bordered > thead > tr > th:last-child,
+  .table-responsive > .table-bordered > tbody > tr > th:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+  .table-responsive > .table-bordered > thead > tr > td:last-child,
+  .table-responsive > .table-bordered > tbody > tr > td:last-child,
+  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+    border-right: 0;
+  }
+  .table-responsive > .table-bordered > tbody > tr:last-child > th,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+  .table-responsive > .table-bordered > tbody > tr:last-child > td,
+  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+    border-bottom: 0;
+  }
+}
+fieldset {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  min-width: 0;
+}
+legend {
+  display: block;
+  width: 100%;
+  padding: 0;
+  margin-bottom: 22px;
+  font-size: 24px;
+  line-height: inherit;
+  color: #333333;
+  border: 0;
+  border-bottom: 1px solid #e5e5e5;
+}
+label {
+  display: inline-block;
+  max-width: 100%;
+  margin-bottom: 5px;
+  font-weight: bold;
+}
+input[type="search"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+  margin: 4px 0 0;
+  margin-top: 1px \9;
+  line-height: normal;
+}
+input[type="file"] {
+  display: block;
+}
+input[type="range"] {
+  display: block;
+  width: 100%;
+}
+select[multiple],
+select[size] {
+  height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+output {
+  display: block;
+  padding-top: 9px;
+  font-size: 16px;
+  line-height: 1.42857143;
+  color: #333333;
+}
+.form-control {
+  display: block;
+  width: 100%;
+  height: 40px;
+  padding: 8px 12px;
+  font-size: 16px;
+  line-height: 1.42857143;
+  color: #333333;
+  background-color: #ffffff;
+  background-image: none;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-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, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.form-control::-moz-placeholder {
+  color: #b3b3b3;
+  opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+  color: #b3b3b3;
+}
+.form-control::-webkit-input-placeholder {
+  color: #b3b3b3;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+  cursor: not-allowed;
+  background-color: #eeeeee;
+  opacity: 1;
+}
+textarea.form-control {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+  input[type="date"],
+  input[type="time"],
+  input[type="datetime-local"],
+  input[type="month"] {
+    line-height: 40px;
+  }
+  input[type="date"].input-sm,
+  input[type="time"].input-sm,
+  input[type="datetime-local"].input-sm,
+  input[type="month"].input-sm {
+    line-height: 33px;
+  }
+  input[type="date"].input-lg,
+  input[type="time"].input-lg,
+  input[type="datetime-local"].input-lg,
+  input[type="month"].input-lg {
+    line-height: 57px;
+  }
+}
+.form-group {
+  margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+  position: relative;
+  display: block;
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+  min-height: 22px;
+  padding-left: 20px;
+  margin-bottom: 0;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+  position: absolute;
+  margin-left: -20px;
+  margin-top: 4px \9;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+  margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+  display: inline-block;
+  padding-left: 20px;
+  margin-bottom: 0;
+  vertical-align: middle;
+  font-weight: normal;
+  cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+  margin-top: 0;
+  margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+  cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+  cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+  cursor: not-allowed;
+}
+.form-control-static {
+  padding-top: 9px;
+  padding-bottom: 9px;
+  margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+  padding-left: 0;
+  padding-right: 0;
+}
+.input-sm,
+.form-group-sm .form-control {
+  height: 33px;
+  padding: 5px 10px;
+  font-size: 14px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+select.input-sm,
+select.form-group-sm .form-control {
+  height: 33px;
+  line-height: 33px;
+}
+textarea.input-sm,
+textarea.form-group-sm .form-control,
+select[multiple].input-sm,
+select[multiple].form-group-sm .form-control {
+  height: auto;
+}
+.input-lg,
+.form-group-lg .form-control {
+  height: 57px;
+  padding: 14px 16px;
+  font-size: 20px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+select.input-lg,
+select.form-group-lg .form-control {
+  height: 57px;
+  line-height: 57px;
+}
+textarea.input-lg,
+textarea.form-group-lg .form-control,
+select[multiple].input-lg,
+select[multiple].form-group-lg .form-control {
+  height: auto;
+}
+.has-feedback {
+  position: relative;
+}
+.has-feedback .form-control {
+  padding-right: 50px;
+}
+.form-control-feedback {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 2;
+  display: block;
+  width: 40px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  pointer-events: none;
+}
+.input-lg + .form-control-feedback {
+  width: 57px;
+  height: 57px;
+  line-height: 57px;
+}
+.input-sm + .form-control-feedback {
+  width: 33px;
+  height: 33px;
+  line-height: 33px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+  color: #3fad46;
+}
+.has-success .form-control {
+  border-color: #3fad46;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-success .form-control:focus {
+  border-color: #318837;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186;
+}
+.has-success .input-group-addon {
+  color: #3fad46;
+  border-color: #3fad46;
+  background-color: #dff0d8;
+}
+.has-success .form-control-feedback {
+  color: #3fad46;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+  color: #f0ad4e;
+}
+.has-warning .form-control {
+  border-color: #f0ad4e;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-warning .form-control:focus {
+  border-color: #ec971f;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac;
+}
+.has-warning .input-group-addon {
+  color: #f0ad4e;
+  border-color: #f0ad4e;
+  background-color: #fcf8e3;
+}
+.has-warning .form-control-feedback {
+  color: #f0ad4e;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+  color: #d9534f;
+}
+.has-error .form-control {
+  border-color: #d9534f;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.has-error .form-control:focus {
+  border-color: #c9302c;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3;
+}
+.has-error .input-group-addon {
+  color: #d9534f;
+  border-color: #d9534f;
+  background-color: #f2dede;
+}
+.has-error .form-control-feedback {
+  color: #d9534f;
+}
+.has-feedback label ~ .form-control-feedback {
+  top: 27px;
+}
+.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 .form-control-static {
+    display: inline-block;
+  }
+  .form-inline .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .form-inline .input-group .input-group-addon,
+  .form-inline .input-group .input-group-btn,
+  .form-inline .input-group .form-control {
+    width: auto;
+  }
+  .form-inline .input-group > .form-control {
+    width: 100%;
+  }
+  .form-inline .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio,
+  .form-inline .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .form-inline .radio label,
+  .form-inline .checkbox label {
+    padding-left: 0;
+  }
+  .form-inline .radio input[type="radio"],
+  .form-inline .checkbox input[type="checkbox"] {
+    position: relative;
+    margin-left: 0;
+  }
+  .form-inline .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+  padding-top: 9px;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+  min-height: 31px;
+}
+.form-horizontal .form-group {
+  margin-left: -15px;
+  margin-right: -15px;
+}
+@media (min-width: 768px) {
+  .form-horizontal .control-label {
+    text-align: right;
+    margin-bottom: 0;
+    padding-top: 9px;
+  }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+  right: 15px;
+}
+@media (min-width: 768px) {
+  .form-horizontal .form-group-lg .control-label {
+    padding-top: 19.62px;
+  }
+}
+@media (min-width: 768px) {
+  .form-horizontal .form-group-sm .control-label {
+    padding-top: 6px;
+  }
+}
+.btn {
+  display: inline-block;
+  margin-bottom: 0;
+  font-weight: normal;
+  text-align: center;
+  vertical-align: middle;
+  -ms-touch-action: manipulation;
+      touch-action: manipulation;
+  cursor: pointer;
+  background-image: none;
+  border: 1px solid transparent;
+  white-space: nowrap;
+  padding: 8px 12px;
+  font-size: 16px;
+  line-height: 1.42857143;
+  border-radius: 4px;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+  outline: thin dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+  color: #333333;
+  text-decoration: none;
+}
+.btn:active,
+.btn.active {
+  outline: 0;
+  background-image: none;
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+  cursor: not-allowed;
+  pointer-events: none;
+  opacity: 0.65;
+  filter: alpha(opacity=65);
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn-default {
+  color: #333333;
+  background-color: #ffffff;
+  border-color: #dddddd;
+}
+.btn-default:hover,
+.btn-default:focus,
+.btn-default.focus,
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  color: #333333;
+  background-color: #e6e6e6;
+  border-color: #bebebe;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+  background-image: none;
+}
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+  background-color: #ffffff;
+  border-color: #dddddd;
+}
+.btn-default .badge {
+  color: #ffffff;
+  background-color: #333333;
+}
+.btn-primary {
+  color: #ffffff;
+  background-color: #4582ec;
+  border-color: #4582ec;
+}
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary.focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  color: #ffffff;
+  background-color: #1863e6;
+  border-color: #175fdd;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+  background-image: none;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+  background-color: #4582ec;
+  border-color: #4582ec;
+}
+.btn-primary .badge {
+  color: #4582ec;
+  background-color: #ffffff;
+}
+.btn-success {
+  color: #ffffff;
+  background-color: #3fad46;
+  border-color: #3fad46;
+}
+.btn-success:hover,
+.btn-success:focus,
+.btn-success.focus,
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  color: #ffffff;
+  background-color: #318837;
+  border-color: #2f8034;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+  background-image: none;
+}
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+  background-color: #3fad46;
+  border-color: #3fad46;
+}
+.btn-success .badge {
+  color: #3fad46;
+  background-color: #ffffff;
+}
+.btn-info {
+  color: #ffffff;
+  background-color: #5bc0de;
+  border-color: #5bc0de;
+}
+.btn-info:hover,
+.btn-info:focus,
+.btn-info.focus,
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  color: #ffffff;
+  background-color: #31b0d5;
+  border-color: #2aabd2;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+  background-image: none;
+}
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+  background-color: #5bc0de;
+  border-color: #5bc0de;
+}
+.btn-info .badge {
+  color: #5bc0de;
+  background-color: #ffffff;
+}
+.btn-warning {
+  color: #ffffff;
+  background-color: #f0ad4e;
+  border-color: #f0ad4e;
+}
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning.focus,
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  color: #ffffff;
+  background-color: #ec971f;
+  border-color: #eb9316;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+  background-image: none;
+}
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+  background-color: #f0ad4e;
+  border-color: #f0ad4e;
+}
+.btn-warning .badge {
+  color: #f0ad4e;
+  background-color: #ffffff;
+}
+.btn-danger {
+  color: #ffffff;
+  background-color: #d9534f;
+  border-color: #d9534f;
+}
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger.focus,
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  color: #ffffff;
+  background-color: #c9302c;
+  border-color: #c12e2a;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+  background-image: none;
+}
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+  background-color: #d9534f;
+  border-color: #d9534f;
+}
+.btn-danger .badge {
+  color: #d9534f;
+  background-color: #ffffff;
+}
+.btn-link {
+  color: #4582ec;
+  font-weight: normal;
+  border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+  background-color: transparent;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+  border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+  color: #134fb8;
+  text-decoration: underline;
+  background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+  color: #b3b3b3;
+  text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+  padding: 14px 16px;
+  font-size: 20px;
+  line-height: 1.33;
+  border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+  padding: 5px 10px;
+  font-size: 14px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+  padding: 1px 5px;
+  font-size: 14px;
+  line-height: 1.5;
+  border-radius: 3px;
+}
+.btn-block {
+  display: block;
+  width: 100%;
+}
+.btn-block + .btn-block {
+  margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%;
+}
+.fade {
+  opacity: 0;
+  -webkit-transition: opacity 0.15s linear;
+  -o-transition: opacity 0.15s linear;
+  transition: opacity 0.15s linear;
+}
+.fade.in {
+  opacity: 1;
+}
+.collapse {
+  display: none;
+  visibility: hidden;
+}
+.collapse.in {
+  display: block;
+  visibility: visible;
+}
+tr.collapse.in {
+  display: table-row;
+}
+tbody.collapse.in {
+  display: table-row-group;
+}
+.collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  -webkit-transition-property: height, visibility;
+  -o-transition-property: height, visibility;
+     transition-property: height, visibility;
+  -webkit-transition-duration: 0.35s;
+  -o-transition-duration: 0.35s;
+     transition-duration: 0.35s;
+  -webkit-transition-timing-function: ease;
+  -o-transition-timing-function: ease;
+     transition-timing-function: 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;
+  list-style: none;
+  font-size: 16px;
+  text-align: left;
+  background-color: #ffffff;
+  border: 1px solid #cccccc;
+  border: 1px solid rgba(0, 0, 0, 0.15);
+  border-radius: 4px;
+  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+  -webkit-background-clip: padding-box;
+          background-clip: padding-box;
+}
+.dropdown-menu.pull-right {
+  right: 0;
+  left: auto;
+}
+.dropdown-menu .divider {
+  height: 1px;
+  margin: 10px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+  display: block;
+  padding: 3px 20px;
+  clear: both;
+  font-weight: normal;
+  line-height: 1.42857143;
+  color: #333333;
+  white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  text-decoration: none;
+  color: #ffffff;
+  background-color: #4582ec;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  color: #ffffff;
+  text-decoration: none;
+  outline: 0;
+  background-color: #4582ec;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  color: #b3b3b3;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+  text-decoration: none;
+  background-color: transparent;
+  background-image: none;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  cursor: not-allowed;
+}
+.open > .dropdown-menu {
+  display: block;
+}
+.open > a {
+  outline: 0;
+}
+.dropdown-menu-right {
+  left: auto;
+  right: 0;
+}
+.dropdown-menu-left {
+  left: 0;
+  right: auto;
+}
+.dropdown-header {
+  display: block;
+  padding: 3px 20px;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #b3b3b3;
+  white-space: nowrap;
+}
+.dropdown-backdrop {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 0;
+  z-index: 990;
+}
+.pull-right > .dropdown-menu {
+  right: 0;
+  left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+  border-top: 0;
+  border-bottom: 4px solid;
+  content: "";
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+  top: auto;
+  bottom: 100%;
+  margin-bottom: 1px;
+}
+@media (min-width: 768px) {
+  .navbar-right .dropdown-menu {
+    left: auto;
+    right: 0;
+  }
+  .navbar-right .dropdown-menu-left {
+    left: 0;
+    right: auto;
+  }
+}
+.btn-group,
+.btn-group-vertical {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+  z-index: 2;
+}
+.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-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+  border-bottom-left-radius: 0;
+  border-top-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-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+.btn-group > .btn-group:last-child > .btn:first-child {
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+  outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+  padding-left: 8px;
+  padding-right: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+  padding-left: 12px;
+  padding-right: 12px;
+}
+.btn-group.open .dropdown-toggle {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 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-bottom-left-radius: 4px;
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.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-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.btn-group-justified {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
+  border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+  float: none;
+  display: table-cell;
+  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="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+  position: absolute;
+  clip: rect(0, 0, 0, 0);
+  pointer-events: none;
+}
+.input-group {
+  position: relative;
+  display: table;
+  border-collapse: separate;
+}
+.input-group[class*="col-"] {
+  float: none;
+  padding-left: 0;
+  padding-right: 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: 57px;
+  padding: 14px 16px;
+  font-size: 20px;
+  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: 57px;
+  line-height: 57px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].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: 33px;
+  padding: 5px 10px;
+  font-size: 14px;
+  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: 33px;
+  line-height: 33px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+  height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+  display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control: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: 8px 12px;
+  font-size: 16px;
+  font-weight: normal;
+  line-height: 1;
+  color: #333333;
+  text-align: center;
+  background-color: #eeeeee;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+}
+.input-group-addon.input-sm {
+  padding: 5px 10px;
+  font-size: 14px;
+  border-radius: 3px;
+}
+.input-group-addon.input-lg {
+  padding: 14px 16px;
+  font-size: 20px;
+  border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+  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:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+  border-bottom-right-radius: 0;
+  border-top-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:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+  border-bottom-left-radius: 0;
+  border-top-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:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+  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 {
+  margin-bottom: 0;
+  padding-left: 0;
+  list-style: none;
+}
+.nav > li {
+  position: relative;
+  display: block;
+}
+.nav > li > a {
+  position: relative;
+  display: block;
+  padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+  text-decoration: none;
+  background-color: #eeeeee;
+}
+.nav > li.disabled > a {
+  color: #b3b3b3;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+  color: #b3b3b3;
+  text-decoration: none;
+  background-color: transparent;
+  cursor: not-allowed;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+  background-color: #eeeeee;
+  border-color: #4582ec;
+}
+.nav .nav-divider {
+  height: 1px;
+  margin: 10px 0;
+  overflow: hidden;
+  background-color: #e5e5e5;
+}
+.nav > li > a > img {
+  max-width: none;
+}
+.nav-tabs {
+  border-bottom: 1px solid #dddddd;
+}
+.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: #eeeeee #eeeeee #dddddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+  color: #555555;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  border-bottom-color: transparent;
+  cursor: default;
+}
+.nav-tabs.nav-justified {
+  width: 100%;
+  border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+  float: none;
+}
+.nav-tabs.nav-justified > li > a {
+  text-align: center;
+  margin-bottom: 5px;
+}
+.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:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+  border: 1px solid #dddddd;
+}
+@media (min-width: 768px) {
+  .nav-tabs.nav-justified > li > a {
+    border-bottom: 1px solid #dddddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs.nav-justified > .active > a,
+  .nav-tabs.nav-justified > .active > a:hover,
+  .nav-tabs.nav-justified > .active > a:focus {
+    border-bottom-color: #ffffff;
+  }
+}
+.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:hover,
+.nav-pills > li.active > a:focus {
+  color: #ffffff;
+  background-color: #4582ec;
+}
+.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 {
+  text-align: center;
+  margin-bottom: 5px;
+}
+.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:hover,
+.nav-tabs-justified > .active > a:focus {
+  border: 1px solid #dddddd;
+}
+@media (min-width: 768px) {
+  .nav-tabs-justified > li > a {
+    border-bottom: 1px solid #dddddd;
+    border-radius: 4px 4px 0 0;
+  }
+  .nav-tabs-justified > .active > a,
+  .nav-tabs-justified > .active > a:hover,
+  .nav-tabs-justified > .active > a:focus {
+    border-bottom-color: #ffffff;
+  }
+}
+.tab-content > .tab-pane {
+  display: none;
+  visibility: hidden;
+}
+.tab-content > .active {
+  display: block;
+  visibility: visible;
+}
+.nav-tabs .dropdown-menu {
+  margin-top: -1px;
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.navbar {
+  position: relative;
+  min-height: 65px;
+  margin-bottom: 22px;
+  border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+  .navbar {
+    border-radius: 4px;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-header {
+    float: left;
+  }
+}
+.navbar-collapse {
+  overflow-x: visible;
+  padding-right: 15px;
+  padding-left: 15px;
+  border-top: 1px solid transparent;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
+  -webkit-overflow-scrolling: touch;
+}
+.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;
+    visibility: visible !important;
+    height: auto !important;
+    padding-bottom: 0;
+    overflow: visible !important;
+  }
+  .navbar-collapse.in {
+    overflow-y: visible;
+  }
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-static-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    padding-left: 0;
+    padding-right: 0;
+  }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+  max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    max-height: 200px;
+  }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+  margin-right: -15px;
+  margin-left: -15px;
+}
+@media (min-width: 768px) {
+  .container > .navbar-header,
+  .container-fluid > .navbar-header,
+  .container > .navbar-collapse,
+  .container-fluid > .navbar-collapse {
+    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-top,
+.navbar-fixed-bottom {
+  position: fixed;
+  right: 0;
+  left: 0;
+  z-index: 1030;
+}
+@media (min-width: 768px) {
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    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;
+  padding: 21.5px 15px;
+  font-size: 20px;
+  line-height: 22px;
+  height: 65px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+  text-decoration: none;
+}
+.navbar-brand > img {
+  display: block;
+}
+@media (min-width: 768px) {
+  .navbar > .container .navbar-brand,
+  .navbar > .container-fluid .navbar-brand {
+    margin-left: -15px;
+  }
+}
+.navbar-toggle {
+  position: relative;
+  float: right;
+  margin-right: 15px;
+  padding: 9px 10px;
+  margin-top: 15.5px;
+  margin-bottom: 15.5px;
+  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: 10.75px -15px;
+}
+.navbar-nav > li > a {
+  padding-top: 10px;
+  padding-bottom: 10px;
+  line-height: 22px;
+}
+@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 > li > a,
+  .navbar-nav .open .dropdown-menu .dropdown-header {
+    padding: 5px 15px 5px 25px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a {
+    line-height: 22px;
+  }
+  .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-nav .open .dropdown-menu > li > a:focus {
+    background-image: none;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-nav {
+    float: left;
+    margin: 0;
+  }
+  .navbar-nav > li {
+    float: left;
+  }
+  .navbar-nav > li > a {
+    padding-top: 21.5px;
+    padding-bottom: 21.5px;
+  }
+}
+.navbar-form {
+  margin-left: -15px;
+  margin-right: -15px;
+  padding: 10px 15px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+  margin-top: 12.5px;
+  margin-bottom: 12.5px;
+}
+@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 .form-control-static {
+    display: inline-block;
+  }
+  .navbar-form .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .navbar-form .input-group .input-group-addon,
+  .navbar-form .input-group .input-group-btn,
+  .navbar-form .input-group .form-control {
+    width: auto;
+  }
+  .navbar-form .input-group > .form-control {
+    width: 100%;
+  }
+  .navbar-form .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio,
+  .navbar-form .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio label,
+  .navbar-form .checkbox label {
+    padding-left: 0;
+  }
+  .navbar-form .radio input[type="radio"],
+  .navbar-form .checkbox input[type="checkbox"] {
+    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;
+  }
+  .navbar-form .form-group:last-child {
+    margin-bottom: 0;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-form {
+    width: auto;
+    border: 0;
+    margin-left: 0;
+    margin-right: 0;
+    padding-top: 0;
+    padding-bottom: 0;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+}
+.navbar-nav > li > .dropdown-menu {
+  margin-top: 0;
+  border-top-right-radius: 0;
+  border-top-left-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+  border-top-right-radius: 4px;
+  border-top-left-radius: 4px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.navbar-btn {
+  margin-top: 12.5px;
+  margin-bottom: 12.5px;
+}
+.navbar-btn.btn-sm {
+  margin-top: 16px;
+  margin-bottom: 16px;
+}
+.navbar-btn.btn-xs {
+  margin-top: 21.5px;
+  margin-bottom: 21.5px;
+}
+.navbar-text {
+  margin-top: 21.5px;
+  margin-bottom: 21.5px;
+}
+@media (min-width: 768px) {
+  .navbar-text {
+    float: left;
+    margin-left: 15px;
+    margin-right: 15px;
+  }
+}
+@media (min-width: 768px) {
+  .navbar-left {
+    float: left !important;
+  }
+  .navbar-right {
+    float: right !important;
+    margin-right: -15px;
+  }
+  .navbar-right ~ .navbar-right {
+    margin-right: 0;
+  }
+}
+.navbar-default {
+  background-color: #ffffff;
+  border-color: #dddddd;
+}
+.navbar-default .navbar-brand {
+  color: #4582ec;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+  color: #4582ec;
+  background-color: transparent;
+}
+.navbar-default .navbar-text {
+  color: #333333;
+}
+.navbar-default .navbar-nav > li > a {
+  color: #4582ec;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+  color: #4582ec;
+  background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+  color: #4582ec;
+  background-color: transparent;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+  color: #333333;
+  background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+  border-color: #dddddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+  background-color: #dddddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+  background-color: #cccccc;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+  border-color: #dddddd;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+  background-color: transparent;
+  color: #4582ec;
+}
+@media (max-width: 767px) {
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+    color: #4582ec;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #4582ec;
+    background-color: transparent;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #4582ec;
+    background-color: transparent;
+  }
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #333333;
+    background-color: transparent;
+  }
+}
+.navbar-default .navbar-link {
+  color: #4582ec;
+}
+.navbar-default .navbar-link:hover {
+  color: #4582ec;
+}
+.navbar-default .btn-link {
+  color: #4582ec;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+  color: #4582ec;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+  color: #333333;
+}
+.navbar-inverse {
+  background-color: #ffffff;
+  border-color: #dddddd;
+}
+.navbar-inverse .navbar-brand {
+  color: #333333;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+  color: #333333;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+  color: #333333;
+}
+.navbar-inverse .navbar-nav > li > a {
+  color: #333333;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+  color: #333333;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+  color: #333333;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+  color: #cccccc;
+  background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+  border-color: #dddddd;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+  background-color: #dddddd;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+  background-color: #cccccc;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+  border-color: #ededed;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+  background-color: transparent;
+  color: #333333;
+}
+@media (max-width: 767px) {
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+    border-color: #dddddd;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+    background-color: #dddddd;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+    color: #333333;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+    color: #333333;
+    background-color: transparent;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #333333;
+    background-color: transparent;
+  }
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+    color: #cccccc;
+    background-color: transparent;
+  }
+}
+.navbar-inverse .navbar-link {
+  color: #333333;
+}
+.navbar-inverse .navbar-link:hover {
+  color: #333333;
+}
+.navbar-inverse .btn-link {
+  color: #333333;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+  color: #333333;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+  color: #cccccc;
+}
+.breadcrumb {
+  padding: 8px 15px;
+  margin-bottom: 22px;
+  list-style: none;
+  background-color: #f5f5f5;
+  border-radius: 4px;
+}
+.breadcrumb > li {
+  display: inline-block;
+}
+.breadcrumb > li + li:before {
+  content: "/\00a0";
+  padding: 0 5px;
+  color: #cccccc;
+}
+.breadcrumb > .active {
+  color: #b3b3b3;
+}
+.pagination {
+  display: inline-block;
+  padding-left: 0;
+  margin: 22px 0;
+  border-radius: 4px;
+}
+.pagination > li {
+  display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+  position: relative;
+  float: left;
+  padding: 8px 12px;
+  line-height: 1.42857143;
+  text-decoration: none;
+  color: #333333;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  margin-left: -1px;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+  margin-left: 0;
+  border-bottom-left-radius: 4px;
+  border-top-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+  border-bottom-right-radius: 4px;
+  border-top-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+  color: #ffffff;
+  background-color: #4582ec;
+  border-color: #4582ec;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+  z-index: 2;
+  color: #ffffff;
+  background-color: #4582ec;
+  border-color: #4582ec;
+  cursor: default;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+  color: #b3b3b3;
+  background-color: #ffffff;
+  border-color: #dddddd;
+  cursor: not-allowed;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+  padding: 14px 16px;
+  font-size: 20px;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+  border-bottom-left-radius: 6px;
+  border-top-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+  border-bottom-right-radius: 6px;
+  border-top-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+  padding: 5px 10px;
+  font-size: 14px;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+  border-bottom-right-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.pager {
+  padding-left: 0;
+  margin: 22px 0;
+  list-style: none;
+  text-align: center;
+}
+.pager li {
+  display: inline;
+}
+.pager li > a,
+.pager li > span {
+  display: inline-block;
+  padding: 5px 14px;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+  text-decoration: none;
+  background-color: #4582ec;
+}
+.pager .next > a,
+.pager .next > span {
+  float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+  float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+  color: #b3b3b3;
+  background-color: #ffffff;
+  cursor: not-allowed;
+}
+.label {
+  display: inline;
+  padding: .2em .6em .3em;
+  font-size: 75%;
+  font-weight: bold;
+  line-height: 1;
+  color: #ffffff;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+  color: #ffffff;
+  text-decoration: none;
+  cursor: pointer;
+}
+.label:empty {
+  display: none;
+}
+.btn .label {
+  position: relative;
+  top: -1px;
+}
+.label-default {
+  background-color: #ffffff;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+  background-color: #e6e6e6;
+}
+.label-primary {
+  background-color: #4582ec;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+  background-color: #1863e6;
+}
+.label-success {
+  background-color: #3fad46;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+  background-color: #318837;
+}
+.label-info {
+  background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+  background-color: #31b0d5;
+}
+.label-warning {
+  background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+  background-color: #ec971f;
+}
+.label-danger {
+  background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+  background-color: #c9302c;
+}
+.badge {
+  display: inline-block;
+  min-width: 10px;
+  padding: 3px 7px;
+  font-size: 14px;
+  font-weight: bold;
+  color: #ffffff;
+  line-height: 1;
+  vertical-align: baseline;
+  white-space: nowrap;
+  text-align: center;
+  background-color: #4582ec;
+  border-radius: 10px;
+}
+.badge:empty {
+  display: none;
+}
+.btn .badge {
+  position: relative;
+  top: -1px;
+}
+.btn-xs .badge {
+  top: 0;
+  padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+  color: #ffffff;
+  text-decoration: none;
+  cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+  color: #4582ec;
+  background-color: #ffffff;
+}
+.list-group-item > .badge {
+  float: right;
+}
+.list-group-item > .badge + .badge {
+  margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+  margin-left: 3px;
+}
+.jumbotron {
+  padding: 30px 15px;
+  margin-bottom: 30px;
+  color: inherit;
+  background-color: #f7f7f7;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+  color: inherit;
+}
+.jumbotron p {
+  margin-bottom: 15px;
+  font-size: 24px;
+  font-weight: 200;
+}
+.jumbotron > hr {
+  border-top-color: #dedede;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+  border-radius: 6px;
+}
+.jumbotron .container {
+  max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+  .jumbotron {
+    padding: 48px 0;
+  }
+  .container .jumbotron,
+  .container-fluid .jumbotron {
+    padding-left: 60px;
+    padding-right: 60px;
+  }
+  .jumbotron h1,
+  .jumbotron .h1 {
+    font-size: 72px;
+  }
+}
+.thumbnail {
+  display: block;
+  padding: 4px;
+  margin-bottom: 22px;
+  line-height: 1.42857143;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+  -webkit-transition: border 0.2s ease-in-out;
+  -o-transition: border 0.2s ease-in-out;
+  transition: border 0.2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+  margin-left: auto;
+  margin-right: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+  border-color: #4582ec;
+}
+.thumbnail .caption {
+  padding: 9px;
+  color: #333333;
+}
+.alert {
+  padding: 15px;
+  margin-bottom: 22px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.alert h4 {
+  margin-top: 0;
+  color: inherit;
+}
+.alert .alert-link {
+  font-weight: bold;
+}
+.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 {
+  background-color: #3fad46;
+  border-color: #3fad46;
+  color: #ffffff;
+}
+.alert-success hr {
+  border-top-color: #389a3e;
+}
+.alert-success .alert-link {
+  color: #e6e6e6;
+}
+.alert-info {
+  background-color: #5bc0de;
+  border-color: #5bc0de;
+  color: #ffffff;
+}
+.alert-info hr {
+  border-top-color: #46b8da;
+}
+.alert-info .alert-link {
+  color: #e6e6e6;
+}
+.alert-warning {
+  background-color: #f0ad4e;
+  border-color: #f0ad4e;
+  color: #ffffff;
+}
+.alert-warning hr {
+  border-top-color: #eea236;
+}
+.alert-warning .alert-link {
+  color: #e6e6e6;
+}
+.alert-danger {
+  background-color: #d9534f;
+  border-color: #d9534f;
+  color: #ffffff;
+}
+.alert-danger hr {
+  border-top-color: #d43f3a;
+}
+.alert-danger .alert-link {
+  color: #e6e6e6;
+}
+@-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 {
+  overflow: hidden;
+  height: 22px;
+  margin-bottom: 22px;
+  background-color: #f5f5f5;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+.progress-bar {
+  float: left;
+  width: 0%;
+  height: 100%;
+  font-size: 14px;
+  line-height: 22px;
+  color: #ffffff;
+  text-align: center;
+  background-color: #4582ec;
+  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+  -webkit-transition: width 0.6s ease;
+  -o-transition: width 0.6s ease;
+  transition: width 0.6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  -webkit-background-size: 40px 40px;
+          background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+  -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-success {
+  background-color: #3fad46;
+}
+.progress-striped .progress-bar-success {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+  background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+  background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+  background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.media {
+  margin-top: 15px;
+}
+.media:first-child {
+  margin-top: 0;
+}
+.media-right,
+.media > .pull-right {
+  padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+  padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+  display: table-cell;
+  vertical-align: top;
+}
+.media-middle {
+  vertical-align: middle;
+}
+.media-bottom {
+  vertical-align: bottom;
+}
+.media-heading {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+.media-list {
+  padding-left: 0;
+  list-style: none;
+}
+.list-group {
+  margin-bottom: 20px;
+  padding-left: 0;
+}
+.list-group-item {
+  position: relative;
+  display: block;
+  padding: 10px 15px;
+  margin-bottom: -1px;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+}
+.list-group-item:first-child {
+  border-top-right-radius: 4px;
+  border-top-left-radius: 4px;
+}
+.list-group-item:last-child {
+  margin-bottom: 0;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+a.list-group-item {
+  color: #555555;
+}
+a.list-group-item .list-group-item-heading {
+  color: #333333;
+}
+a.list-group-item:hover,
+a.list-group-item:focus {
+  text-decoration: none;
+  color: #555555;
+  background-color: #f5f5f5;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+  background-color: #eeeeee;
+  color: #b3b3b3;
+  cursor: not-allowed;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+  color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+  color: #b3b3b3;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+  z-index: 2;
+  color: #ffffff;
+  background-color: #4582ec;
+  border-color: #4582ec;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+  color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+  color: #fefeff;
+}
+.list-group-item-success {
+  color: #3fad46;
+  background-color: #dff0d8;
+}
+a.list-group-item-success {
+  color: #3fad46;
+}
+a.list-group-item-success .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-success:hover,
+a.list-group-item-success:focus {
+  color: #3fad46;
+  background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus {
+  color: #fff;
+  background-color: #3fad46;
+  border-color: #3fad46;
+}
+.list-group-item-info {
+  color: #5bc0de;
+  background-color: #d9edf7;
+}
+a.list-group-item-info {
+  color: #5bc0de;
+}
+a.list-group-item-info .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-info:hover,
+a.list-group-item-info:focus {
+  color: #5bc0de;
+  background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus {
+  color: #fff;
+  background-color: #5bc0de;
+  border-color: #5bc0de;
+}
+.list-group-item-warning {
+  color: #f0ad4e;
+  background-color: #fcf8e3;
+}
+a.list-group-item-warning {
+  color: #f0ad4e;
+}
+a.list-group-item-warning .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-warning:hover,
+a.list-group-item-warning:focus {
+  color: #f0ad4e;
+  background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus {
+  color: #fff;
+  background-color: #f0ad4e;
+  border-color: #f0ad4e;
+}
+.list-group-item-danger {
+  color: #d9534f;
+  background-color: #f2dede;
+}
+a.list-group-item-danger {
+  color: #d9534f;
+}
+a.list-group-item-danger .list-group-item-heading {
+  color: inherit;
+}
+a.list-group-item-danger:hover,
+a.list-group-item-danger:focus {
+  color: #d9534f;
+  background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus {
+  color: #fff;
+  background-color: #d9534f;
+  border-color: #d9534f;
+}
+.list-group-item-heading {
+  margin-top: 0;
+  margin-bottom: 5px;
+}
+.list-group-item-text {
+  margin-bottom: 0;
+  line-height: 1.3;
+}
+.panel {
+  margin-bottom: 22px;
+  background-color: #ffffff;
+  border: 1px solid transparent;
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+.panel-body {
+  padding: 15px;
+}
+.panel-heading {
+  padding: 10px 15px;
+  border-bottom: 1px solid transparent;
+  border-top-right-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+  color: inherit;
+}
+.panel-title {
+  margin-top: 0;
+  margin-bottom: 0;
+  font-size: 18px;
+  color: inherit;
+}
+.panel-title > a {
+  color: inherit;
+}
+.panel-footer {
+  padding: 10px 15px;
+  background-color: #ffffff;
+  border-top: 1px solid #dddddd;
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+  margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+  border-width: 1px 0;
+  border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+  border-top: 0;
+  border-top-right-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .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 > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+  margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+  border-top-right-radius: 3px;
+  border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.panel > .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 td:first-child,
+.panel > .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 td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+  border-top-left-radius: 3px;
+}
+.panel > .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 td:last-child,
+.panel > .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 td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th: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 th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+  border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+  border-bottom-left-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
+.panel > .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 td:first-child,
+.panel > .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 td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+  border-bottom-left-radius: 3px;
+}
+.panel > .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 td:last-child,
+.panel > .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 td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .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,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+  border-top: 1px solid #dddddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+  border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+  border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+  border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+  border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+  border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+  border-bottom: 0;
+}
+.panel > .table-responsive {
+  border: 0;
+  margin-bottom: 0;
+}
+.panel-group {
+  margin-bottom: 22px;
+}
+.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,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+  border-top: 1px solid #dddddd;
+}
+.panel-group .panel-footer {
+  border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+  border-bottom: 1px solid #dddddd;
+}
+.panel-default {
+  border-color: #dddddd;
+}
+.panel-default > .panel-heading {
+  color: #333333;
+  background-color: #f5f5f5;
+  border-color: #dddddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: #dddddd;
+}
+.panel-default > .panel-heading .badge {
+  color: #f5f5f5;
+  background-color: #333333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: #dddddd;
+}
+.panel-primary {
+  border-color: transparent;
+}
+.panel-primary > .panel-heading {
+  color: #ffffff;
+  background-color: #4582ec;
+  border-color: transparent;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: transparent;
+}
+.panel-primary > .panel-heading .badge {
+  color: #4582ec;
+  background-color: #ffffff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: transparent;
+}
+.panel-success {
+  border-color: transparent;
+}
+.panel-success > .panel-heading {
+  color: #3fad46;
+  background-color: #3fad46;
+  border-color: transparent;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: transparent;
+}
+.panel-success > .panel-heading .badge {
+  color: #3fad46;
+  background-color: #3fad46;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: transparent;
+}
+.panel-info {
+  border-color: transparent;
+}
+.panel-info > .panel-heading {
+  color: #5bc0de;
+  background-color: #5bc0de;
+  border-color: transparent;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: transparent;
+}
+.panel-info > .panel-heading .badge {
+  color: #5bc0de;
+  background-color: #5bc0de;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: transparent;
+}
+.panel-warning {
+  border-color: transparent;
+}
+.panel-warning > .panel-heading {
+  color: #f0ad4e;
+  background-color: #f0ad4e;
+  border-color: transparent;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: transparent;
+}
+.panel-warning > .panel-heading .badge {
+  color: #f0ad4e;
+  background-color: #f0ad4e;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: transparent;
+}
+.panel-danger {
+  border-color: transparent;
+}
+.panel-danger > .panel-heading {
+  color: #d9534f;
+  background-color: #d9534f;
+  border-color: transparent;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+  border-top-color: transparent;
+}
+.panel-danger > .panel-heading .badge {
+  color: #d9534f;
+  background-color: #d9534f;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+  border-bottom-color: transparent;
+}
+.embed-responsive {
+  position: relative;
+  display: block;
+  height: 0;
+  padding: 0;
+  overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  height: 100%;
+  width: 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: #f7f7f7;
+  border: 1px solid #e5e5e5;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+.well blockquote {
+  border-color: #ddd;
+  border-color: rgba(0, 0, 0, 0.15);
+}
+.well-lg {
+  padding: 24px;
+  border-radius: 6px;
+}
+.well-sm {
+  padding: 9px;
+  border-radius: 3px;
+}
+.close {
+  float: right;
+  font-size: 24px;
+  font-weight: bold;
+  line-height: 1;
+  color: #ffffff;
+  text-shadow: 0 1px 0 #ffffff;
+  opacity: 0.2;
+  filter: alpha(opacity=20);
+}
+.close:hover,
+.close:focus {
+  color: #ffffff;
+  text-decoration: none;
+  cursor: pointer;
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+button.close {
+  padding: 0;
+  cursor: pointer;
+  background: transparent;
+  border: 0;
+  -webkit-appearance: none;
+}
+.modal-open {
+  overflow: hidden;
+}
+.modal {
+  display: none;
+  overflow: hidden;
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1040;
+  -webkit-overflow-scrolling: touch;
+  outline: 0;
+}
+.modal.fade .modal-dialog {
+  -webkit-transform: translate(0, -25%);
+  -ms-transform: translate(0, -25%);
+  -o-transform: translate(0, -25%);
+  transform: translate(0, -25%);
+  -webkit-transition: -webkit-transform 0.3s ease-out;
+  -o-transition: -o-transform 0.3s ease-out;
+  transition: transform 0.3s ease-out;
+}
+.modal.in .modal-dialog {
+  -webkit-transform: translate(0, 0);
+  -ms-transform: translate(0, 0);
+  -o-transform: translate(0, 0);
+  transform: translate(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: #ffffff;
+  border: 1px solid #999999;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 6px;
+  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
+  -webkit-background-clip: padding-box;
+          background-clip: padding-box;
+  outline: 0;
+}
+.modal-backdrop {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  background-color: #000000;
+}
+.modal-backdrop.fade {
+  opacity: 0;
+  filter: alpha(opacity=0);
+}
+.modal-backdrop.in {
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+.modal-header {
+  padding: 15px;
+  border-bottom: 1px solid #e5e5e5;
+  min-height: 16.42857143px;
+}
+.modal-header .close {
+  margin-top: -2px;
+}
+.modal-title {
+  margin: 0;
+  line-height: 1.42857143;
+}
+.modal-body {
+  position: relative;
+  padding: 20px;
+}
+.modal-footer {
+  padding: 20px;
+  text-align: right;
+  border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+  margin-left: 5px;
+  margin-bottom: 0;
+}
+.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, 0.5);
+    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
+  }
+  .modal-sm {
+    width: 300px;
+  }
+}
+@media (min-width: 992px) {
+  .modal-lg {
+    width: 900px;
+  }
+}
+.tooltip {
+  position: absolute;
+  z-index: 1070;
+  display: block;
+  visibility: visible;
+  font-family: Georgia, "Times New Roman", Times, serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.4;
+  opacity: 0;
+  filter: alpha(opacity=0);
+}
+.tooltip.in {
+  opacity: 0.9;
+  filter: alpha(opacity=90);
+}
+.tooltip.top {
+  margin-top: -3px;
+  padding: 5px 0;
+}
+.tooltip.right {
+  margin-left: 3px;
+  padding: 0 5px;
+}
+.tooltip.bottom {
+  margin-top: 3px;
+  padding: 5px 0;
+}
+.tooltip.left {
+  margin-left: -3px;
+  padding: 0 5px;
+}
+.tooltip-inner {
+  max-width: 200px;
+  padding: 3px 8px;
+  color: #ffffff;
+  text-align: center;
+  text-decoration: none;
+  background-color: rgba(0, 0, 0, 0.9);
+  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: rgba(0, 0, 0, 0.9);
+}
+.tooltip.top-left .tooltip-arrow {
+  bottom: 0;
+  right: 5px;
+  margin-bottom: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.top-right .tooltip-arrow {
+  bottom: 0;
+  left: 5px;
+  margin-bottom: -5px;
+  border-width: 5px 5px 0;
+  border-top-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.right .tooltip-arrow {
+  top: 50%;
+  left: 0;
+  margin-top: -5px;
+  border-width: 5px 5px 5px 0;
+  border-right-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.left .tooltip-arrow {
+  top: 50%;
+  right: 0;
+  margin-top: -5px;
+  border-width: 5px 0 5px 5px;
+  border-left-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.bottom .tooltip-arrow {
+  top: 0;
+  left: 50%;
+  margin-left: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.bottom-left .tooltip-arrow {
+  top: 0;
+  right: 5px;
+  margin-top: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: rgba(0, 0, 0, 0.9);
+}
+.tooltip.bottom-right .tooltip-arrow {
+  top: 0;
+  left: 5px;
+  margin-top: -5px;
+  border-width: 0 5px 5px;
+  border-bottom-color: rgba(0, 0, 0, 0.9);
+}
+.popover {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 1060;
+  display: none;
+  max-width: 276px;
+  padding: 1px;
+  font-family: Georgia, "Times New Roman", Times, serif;
+  font-size: 16px;
+  font-weight: normal;
+  line-height: 1.42857143;
+  text-align: left;
+  background-color: #ffffff;
+  -webkit-background-clip: padding-box;
+          background-clip: padding-box;
+  border: 1px solid #cccccc;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 6px;
+  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+  white-space: normal;
+}
+.popover.top {
+  margin-top: -10px;
+}
+.popover.right {
+  margin-left: 10px;
+}
+.popover.bottom {
+  margin-top: 10px;
+}
+.popover.left {
+  margin-left: -10px;
+}
+.popover-title {
+  margin: 0;
+  padding: 8px 14px;
+  font-size: 16px;
+  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 {
+  border-width: 10px;
+  content: "";
+}
+.popover.top > .arrow {
+  left: 50%;
+  margin-left: -11px;
+  border-bottom-width: 0;
+  border-top-color: #999999;
+  border-top-color: rgba(0, 0, 0, 0.25);
+  bottom: -11px;
+}
+.popover.top > .arrow:after {
+  content: " ";
+  bottom: 1px;
+  margin-left: -10px;
+  border-bottom-width: 0;
+  border-top-color: #ffffff;
+}
+.popover.right > .arrow {
+  top: 50%;
+  left: -11px;
+  margin-top: -11px;
+  border-left-width: 0;
+  border-right-color: #999999;
+  border-right-color: rgba(0, 0, 0, 0.25);
+}
+.popover.right > .arrow:after {
+  content: " ";
+  left: 1px;
+  bottom: -10px;
+  border-left-width: 0;
+  border-right-color: #ffffff;
+}
+.popover.bottom > .arrow {
+  left: 50%;
+  margin-left: -11px;
+  border-top-width: 0;
+  border-bottom-color: #999999;
+  border-bottom-color: rgba(0, 0, 0, 0.25);
+  top: -11px;
+}
+.popover.bottom > .arrow:after {
+  content: " ";
+  top: 1px;
+  margin-left: -10px;
+  border-top-width: 0;
+  border-bottom-color: #ffffff;
+}
+.popover.left > .arrow {
+  top: 50%;
+  right: -11px;
+  margin-top: -11px;
+  border-right-width: 0;
+  border-left-color: #999999;
+  border-left-color: rgba(0, 0, 0, 0.25);
+}
+.popover.left > .arrow:after {
+  content: " ";
+  right: 1px;
+  border-right-width: 0;
+  border-left-color: #ffffff;
+  bottom: -10px;
+}
+.carousel {
+  position: relative;
+}
+.carousel-inner {
+  position: relative;
+  overflow: hidden;
+  width: 100%;
+}
+.carousel-inner > .item {
+  display: none;
+  position: relative;
+  -webkit-transition: 0.6s ease-in-out left;
+  -o-transition: 0.6s ease-in-out left;
+  transition: 0.6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+  line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+  .carousel-inner > .item {
+    -webkit-transition: -webkit-transform 0.6s ease-in-out;
+         -o-transition: -o-transform 0.6s ease-in-out;
+            transition: transform 0.6s ease-in-out;
+    -webkit-backface-visibility: hidden;
+            backface-visibility: hidden;
+    -webkit-perspective: 1000;
+            perspective: 1000;
+  }
+  .carousel-inner > .item.next,
+  .carousel-inner > .item.active.right {
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+    left: 0;
+  }
+  .carousel-inner > .item.prev,
+  .carousel-inner > .item.active.left {
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+    left: 0;
+  }
+  .carousel-inner > .item.next.left,
+  .carousel-inner > .item.prev.right,
+  .carousel-inner > .item.active {
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+    left: 0;
+  }
+}
+.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;
+  left: 0;
+  bottom: 0;
+  width: 15%;
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+  font-size: 20px;
+  color: #ffffff;
+  text-align: center;
+  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
+}
+.carousel-control.left {
+  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));
+  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+}
+.carousel-control.right {
+  left: auto;
+  right: 0;
+  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));
+  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+}
+.carousel-control:hover,
+.carousel-control:focus {
+  outline: 0;
+  color: #ffffff;
+  text-decoration: none;
+  opacity: 0.9;
+  filter: alpha(opacity=90);
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+  position: absolute;
+  top: 50%;
+  z-index: 5;
+  display: inline-block;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+  left: 50%;
+  margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+  right: 50%;
+  margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+  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%;
+  margin-left: -30%;
+  padding-left: 0;
+  list-style: none;
+  text-align: center;
+}
+.carousel-indicators li {
+  display: inline-block;
+  width: 10px;
+  height: 10px;
+  margin: 1px;
+  text-indent: -999px;
+  border: 1px solid #ffffff;
+  border-radius: 10px;
+  cursor: pointer;
+  background-color: #000 \9;
+  background-color: rgba(0, 0, 0, 0);
+}
+.carousel-indicators .active {
+  margin: 0;
+  width: 12px;
+  height: 12px;
+  background-color: #ffffff;
+}
+.carousel-caption {
+  position: absolute;
+  left: 15%;
+  right: 15%;
+  bottom: 20px;
+  z-index: 10;
+  padding-top: 20px;
+  padding-bottom: 20px;
+  color: #ffffff;
+  text-align: center;
+  text-shadow: 0 1px 2px rgba(0, 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-prev,
+  .carousel-control .icon-next {
+    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 {
+    left: 20%;
+    right: 20%;
+    padding-bottom: 30px;
+  }
+  .carousel-indicators {
+    bottom: 20px;
+  }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-footer:before,
+.modal-footer:after {
+  content: " ";
+  display: table;
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-footer:after {
+  clear: both;
+}
+.center-block {
+  display: block;
+  margin-left: auto;
+  margin-right: 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;
+}
+@-ms-viewport {
+  width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+  display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-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;
+  }
+  th.visible-xs,
+  td.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;
+  }
+  th.visible-sm,
+  td.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;
+  }
+  th.visible-md,
+  td.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;
+  }
+  th.visible-lg,
+  td.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;
+  }
+  th.visible-print,
+  td.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;
+  }
+}
+.navbar {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.navbar-nav,
+.navbar-form {
+  margin-left: 0;
+  margin-right: 0;
+}
+.navbar-nav > li > a {
+  padding: 8px 12px;
+  margin: 12px 6px;
+  border: 1px solid transparent;
+  border-radius: 4px;
+}
+.navbar-nav > li > a:hover {
+  border: 1px solid #ddd;
+}
+.navbar-nav > .active > a,
+.navbar-nav > .active > a:hover {
+  border: 1px solid #ddd;
+}
+.navbar-default .navbar-nav > .active > a:hover {
+  color: #4582ec;
+}
+.navbar-inverse .navbar-nav > .active > a:hover {
+  color: #333333;
+}
+.navbar-brand {
+  padding-top: 20px;
+}
+@media (max-width: 768px) {
+  .navbar .navbar-nav > li > a {
+    margin: 0;
+  }
+}
+.btn {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+legend {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.input-group-addon {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+  border: 1px solid #ddd;
+}
+.pagination {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+  padding: 14px 24px;
+}
+.pager {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.pager a {
+  color: #333333;
+}
+.pager a:hover {
+  border-color: transparent;
+  color: #fff;
+}
+.pager .disabled a {
+  border-color: #dddddd;
+}
+.close {
+  color: #fff;
+  text-decoration: none;
+  text-shadow: none;
+  opacity: 0.4;
+}
+.close:hover,
+.close:focus {
+  color: #fff;
+  opacity: 1;
+}
+.alert .alert-link {
+  color: #ffffff;
+  text-decoration: underline;
+}
+.label {
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-weight: normal;
+}
+.label-default {
+  border: 1px solid #ddd;
+  color: #333333;
+}
+.badge {
+  padding: 1px 7px 5px;
+  vertical-align: 2px;
+  font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-weight: normal;
+}
+.panel {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.panel-default .close {
+  color: #333333;
+}
+.panel-primary .panel-heading,
+.panel-success .panel-heading,
+.panel-warning .panel-heading,
+.panel-danger .panel-heading,
+.panel-info .panel-heading {
+  color: #fff;
+}
+.panel-primary .panel-body,
+.panel-success .panel-body,
+.panel-warning .panel-body,
+.panel-danger .panel-body,
+.panel-info .panel-body {
+  border: 1px solid #ddd;
+  border-top-width: 0;
+  border-radius: 0 0 4px 4px;
+}
+.modal .close {
+  color: #333333;
+}
+
+
+
+
+/*
+       Override above css for navigation menus
+*/
+
+
+
+/* navbar */
+.navbar-default {
+    background-color: #F8F8F8;
+    border-color: #E7E7E7;
+}
+/* title */
+.navbar-default .navbar-brand {
+    color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+    color: #5E5E5E;
+}
+/* link */
+.navbar-default .navbar-nav > li > a {
+    color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+    color: #333;
+}
+.navbar-default .navbar-nav > .active > a, 
+.navbar-default .navbar-nav > .active > a:hover, 
+.navbar-default .navbar-nav > .active > a:focus {
+    color: #555;
+    background-color: #E7E7E7;
+}
+.navbar-default .navbar-nav > .open > a, 
+.navbar-default .navbar-nav > .open > a:hover, 
+.navbar-default .navbar-nav > .open > a:focus {
+    color: #555;
+    background-color: #D5D5D5;
+}
+/* caret */
+.navbar-default .navbar-nav > .dropdown > a .caret {
+    border-top-color: #777;
+    border-bottom-color: #777;
+}
+.navbar-default .navbar-nav > .dropdown > a:hover .caret,
+.navbar-default .navbar-nav > .dropdown > a:focus .caret {
+    border-top-color: #333;
+    border-bottom-color: #333;
+}
+.navbar-default .navbar-nav > .open > a .caret, 
+.navbar-default .navbar-nav > .open > a:hover .caret, 
+.navbar-default .navbar-nav > .open > a:focus .caret {
+    border-top-color: #555;
+    border-bottom-color: #555;
+}
+/* mobile version */
+.navbar-default .navbar-toggle {
+    border-color: #DDD;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+    background-color: #DDD;
+}
+.navbar-default .navbar-toggle .icon-bar {
+    background-color: #CCC;
+}
+@media (max-width: 767px) {
+    .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+        color: #777;
+    }
+    .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+    .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+        color: #333;
+    }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/ajax-loader.gif b/src/main/resources/META-INF/resources/designer/css/carousel/ajax-loader.gif
new file mode 100644 (file)
index 0000000..e0e6e97
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/carousel/ajax-loader.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.eot b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.eot
new file mode 100644 (file)
index 0000000..2cbab9c
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.svg b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.svg
new file mode 100644 (file)
index 0000000..b36a66a
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Generated by Fontastic.me</metadata>
+<defs>
+<font id="slick" horiz-adv-x="512">
+<font-face font-family="slick" units-per-em="512" ascent="480" descent="-32"/>
+<missing-glyph horiz-adv-x="512" />
+
+<glyph unicode="&#8594;" d="M241 113l130 130c4 4 6 8 6 13 0 5-2 9-6 13l-130 130c-3 3-7 5-12 5-5 0-10-2-13-5l-29-30c-4-3-6-7-6-12 0-5 2-10 6-13l87-88-87-88c-4-3-6-8-6-13 0-5 2-9 6-12l29-30c3-3 8-5 13-5 5 0 9 2 12 5z m234 143c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
+<glyph unicode="&#8592;" d="M296 113l29 30c4 3 6 7 6 12 0 5-2 10-6 13l-87 88 87 88c4 3 6 8 6 13 0 5-2 9-6 12l-29 30c-3 3-8 5-13 5-5 0-9-2-12-5l-130-130c-4-4-6-8-6-13 0-5 2-9 6-13l130-130c3-3 7-5 12-5 5 0 10 2 13 5z m179 143c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
+<glyph unicode="&#8226;" d="M475 256c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
+<glyph unicode="&#97;" d="M475 439l0-128c0-5-1-9-5-13-4-4-8-5-13-5l-128 0c-8 0-13 3-17 11-3 7-2 14 4 20l40 39c-28 26-62 39-100 39-20 0-39-4-57-11-18-8-33-18-46-32-14-13-24-28-32-46-7-18-11-37-11-57 0-20 4-39 11-57 8-18 18-33 32-46 13-14 28-24 46-32 18-7 37-11 57-11 23 0 44 5 64 15 20 9 38 23 51 42 2 1 4 3 7 3 3 0 5-1 7-3l39-39c2-2 3-3 3-6 0-2-1-4-2-6-21-25-46-45-76-59-29-14-60-20-93-20-30 0-58 5-85 17-27 12-51 27-70 47-20 19-35 43-47 70-12 27-17 55-17 85 0 30 5 58 17 85 12 27 27 51 47 70 19 20 43 35 70 47 27 12 55 17 85 17 28 0 55-5 81-15 26-11 50-26 70-45l37 37c6 6 12 7 20 4 8-4 11-9 11-17z"/>
+</font></defs></svg>
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.ttf b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.ttf
new file mode 100644 (file)
index 0000000..9d03461
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.woff b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.woff
new file mode 100644 (file)
index 0000000..8ee9972
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/carousel/fonts/slick.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/grabbing.png b/src/main/resources/META-INF/resources/designer/css/carousel/grabbing.png
new file mode 100644 (file)
index 0000000..85491df
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/carousel/grabbing.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/owl.carousel.css b/src/main/resources/META-INF/resources/designer/css/carousel/owl.carousel.css
new file mode 100644 (file)
index 0000000..7cf0f4a
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ *  Owl Carousel - Animate Plugin
+ */
+.owl-carousel .animated {
+  -webkit-animation-duration: 1000ms;
+  animation-duration: 1000ms;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+}
+.owl-carousel .owl-animated-in {
+  z-index: 0;
+}
+.owl-carousel .owl-animated-out {
+  z-index: 1;
+}
+.owl-carousel .fadeOut {
+  -webkit-animation-name: fadeOut;
+  animation-name: fadeOut;
+}
+
+@-webkit-keyframes fadeOut {
+  0% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes fadeOut {
+  0% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+
+/* 
+ *     Owl Carousel - Auto Height Plugin
+ */
+.owl-height {
+  -webkit-transition: height 500ms ease-in-out;
+  -moz-transition: height 500ms ease-in-out;
+  -ms-transition: height 500ms ease-in-out;
+  -o-transition: height 500ms ease-in-out;
+  transition: height 500ms ease-in-out;
+}
+
+/* 
+ *  Core Owl Carousel CSS File
+ */
+.owl-carousel {
+  display: none;
+  width: 100%;
+  -webkit-tap-highlight-color: transparent;
+  /* position relative and z-index fix webkit rendering fonts issue */
+  position: relative;
+  z-index: 1;
+}
+.owl-carousel .owl-stage {
+  position: relative;
+  -ms-touch-action: pan-Y;
+}
+.owl-carousel .owl-stage:after {
+  content: ".";
+  display: block;
+  clear: both;
+  visibility: hidden;
+  line-height: 0;
+  height: 0;
+}
+.owl-carousel .owl-stage-outer {
+  position: relative;
+  overflow: hidden;
+  /* fix for flashing background */
+  -webkit-transform: translate3d(0px, 0px, 0px);
+}
+.owl-carousel .owl-controls .owl-nav .owl-prev,
+.owl-carousel .owl-controls .owl-nav .owl-next,
+.owl-carousel .owl-controls .owl-dot {
+  cursor: pointer;
+  cursor: hand;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.owl-carousel.owl-loaded {
+  display: block;
+}
+.owl-carousel.owl-loading {
+  opacity: 0;
+  display: block;
+}
+.owl-carousel.owl-hidden {
+  opacity: 0;
+}
+.owl-carousel .owl-refresh .owl-item {
+  display: none;
+}
+.owl-carousel .owl-item {
+  position: relative;
+  min-height: 1px;
+  float: left;
+  -webkit-backface-visibility: hidden;
+  -webkit-tap-highlight-color: transparent;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.owl-carousel .owl-item img {
+  display: block;
+  width: 100%;
+  -webkit-transform-style: preserve-3d;
+}
+.owl-carousel.owl-text-select-on .owl-item {
+  -webkit-user-select: auto;
+  -moz-user-select: auto;
+  -ms-user-select: auto;
+  user-select: auto;
+}
+.owl-carousel .owl-grab {
+  cursor: move;
+  cursor: -webkit-grab;
+  cursor: -o-grab;
+  cursor: -ms-grab;
+  cursor: grab;
+}
+.owl-carousel.owl-rtl {
+  direction: rtl;
+}
+.owl-carousel.owl-rtl .owl-item {
+  float: right;
+}
+
+/* No Js */
+.no-js .owl-carousel {
+  display: block;
+}
+
+/* 
+ *     Owl Carousel - Lazy Load Plugin
+ */
+.owl-carousel .owl-item .owl-lazy {
+  opacity: 0;
+  -webkit-transition: opacity 400ms ease;
+  -moz-transition: opacity 400ms ease;
+  -ms-transition: opacity 400ms ease;
+  -o-transition: opacity 400ms ease;
+  transition: opacity 400ms ease;
+}
+.owl-carousel .owl-item img {
+  transform-style: preserve-3d;
+}
+
+/* 
+ *     Owl Carousel - Video Plugin
+ */
+.owl-carousel .owl-video-wrapper {
+  position: relative;
+  height: 100%;
+  background: #000;
+}
+.owl-carousel .owl-video-play-icon {
+  position: absolute;
+  height: 80px;
+  width: 80px;
+  left: 50%;
+  top: 50%;
+  margin-left: -40px;
+  margin-top: -40px;
+  background: url("owl.video.play.png") no-repeat;
+  cursor: pointer;
+  z-index: 1;
+  -webkit-backface-visibility: hidden;
+  -webkit-transition: scale 100ms ease;
+  -moz-transition: scale 100ms ease;
+  -ms-transition: scale 100ms ease;
+  -o-transition: scale 100ms ease;
+  transition: scale 100ms ease;
+}
+.owl-carousel .owl-video-play-icon:hover {
+  -webkit-transition: scale(1.3, 1.3);
+  -moz-transition: scale(1.3, 1.3);
+  -ms-transition: scale(1.3, 1.3);
+  -o-transition: scale(1.3, 1.3);
+  transition: scale(1.3, 1.3);
+}
+.owl-carousel .owl-video-playing .owl-video-tn,
+.owl-carousel .owl-video-playing .owl-video-play-icon {
+  display: none;
+}
+.owl-carousel .owl-video-tn {
+  opacity: 0;
+  height: 100%;
+  background-position: center center;
+  background-repeat: no-repeat;
+  -webkit-background-size: contain;
+  -moz-background-size: contain;
+  -o-background-size: contain;
+  background-size: contain;
+  -webkit-transition: opacity 400ms ease;
+  -moz-transition: opacity 400ms ease;
+  -ms-transition: opacity 400ms ease;
+  -o-transition: opacity 400ms ease;
+  transition: opacity 400ms ease;
+}
+.owl-carousel .owl-video-frame {
+  position: relative;
+  z-index: 1;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/owl.theme.css b/src/main/resources/META-INF/resources/designer/css/carousel/owl.theme.css
new file mode 100644 (file)
index 0000000..f1f24ef
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+*      Owl Carousel Owl Demo Theme 
+*      v1.3.3
+*/
+
+.owl-theme .owl-controls{
+       margin-top: 10px;
+       text-align: center;
+}
+
+/* Styling Next and Prev buttons */
+
+.owl-theme .owl-controls .owl-buttons div{
+       color: #FFF;
+       display: inline-block;
+       zoom: 1;
+       *display: inline;/*IE7 life-saver */
+       margin: 5px;
+       padding: 3px 10px;
+       font-size: 12px;
+       -webkit-border-radius: 30px;
+       -moz-border-radius: 30px;
+       border-radius: 30px;
+       background: #869791;
+       filter: Alpha(Opacity=50);/*IE7 fix*/
+       opacity: 0.5;
+}
+/* Clickable class fix problem with hover on touch devices */
+/* Use it for non-touch hover action */
+.owl-theme .owl-controls.clickable .owl-buttons div:hover{
+       filter: Alpha(Opacity=100);/*IE7 fix*/
+       opacity: 1;
+       text-decoration: none;
+}
+
+/* Styling Pagination*/
+
+.owl-theme .owl-controls .owl-page{
+       display: inline-block;
+       zoom: 1;
+       *display: inline;/*IE7 life-saver */
+}
+.owl-theme .owl-controls .owl-page span{
+       display: block;
+       width: 12px;
+       height: 12px;
+       margin: 5px 7px;
+       filter: Alpha(Opacity=50);/*IE7 fix*/
+       opacity: 0.5;
+       -webkit-border-radius: 20px;
+       -moz-border-radius: 20px;
+       border-radius: 20px;
+       background: #869791;
+}
+
+.owl-theme .owl-controls .owl-page.active span,
+.owl-theme .owl-controls.clickable .owl-page:hover span{
+       filter: Alpha(Opacity=100);/*IE7 fix*/
+       opacity: 1;
+}
+
+/* If PaginationNumbers is true */
+
+.owl-theme .owl-controls .owl-page span.owl-numbers{
+       height: auto;
+       width: auto;
+       color: #FFF;
+       padding: 2px 10px;
+       font-size: 12px;
+       -webkit-border-radius: 30px;
+       -moz-border-radius: 30px;
+       border-radius: 30px;
+}
+
+/* preloading images */
+.owl-item.loading{
+       min-height: 150px;
+       background: url(AjaxLoader.gif) no-repeat center center
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/slick.css b/src/main/resources/META-INF/resources/designer/css/carousel/slick.css
new file mode 100644 (file)
index 0000000..2570f48
--- /dev/null
@@ -0,0 +1,57 @@
+@charset "UTF-8";
+/* Slider */
+.slick-slider { position: relative; display: block; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -ms-touch-action: pan-y; touch-action: pan-y; -webkit-tap-highlight-color: transparent; }
+
+.slick-list { position: relative; overflow: hidden; display: block; margin: 0; padding: 0; }
+.slick-list:focus { outline: none; }
+.slick-loading .slick-list { background: #fff url("./ajax-loader.gif") center center no-repeat; }
+.slick-list.dragging { cursor: pointer; cursor: hand; }
+
+.slick-slider .slick-track { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); }
+
+.slick-track { position: relative; left: 0; top: 0; display: block; }
+.slick-track:before, .slick-track:after { content: ""; display: table; }
+.slick-track:after { clear: both; }
+.slick-loading .slick-track { visibility: hidden; }
+
+.slick-slide { float: left; height: 100%; min-height: 1px; display: none; }
+[dir="rtl"] .slick-slide { float: right; }
+.slick-slide img { display: block; }
+.slick-slide.slick-loading img { display: none; }
+.slick-slide.dragging img { pointer-events: none; }
+.slick-initialized .slick-slide { display: block; }
+.slick-loading .slick-slide { visibility: hidden; }
+.slick-vertical .slick-slide { display: block; height: auto; border: 1px solid transparent; }
+
+/* Icons */
+@font-face { font-family: "slick"; src: url("./fonts/slick.eot"); src: url("./fonts/slick.eot?#iefix") format("embedded-opentype"), url("./fonts/slick.woff") format("woff"), url("./fonts/slick.ttf") format("truetype"), url("./fonts/slick.svg#slick") format("svg"); font-weight: normal; font-style: normal; }
+/* Arrows */
+.slick-prev, .slick-next { position: absolute; display: block; height: 20px; width: 20px; line-height: 0; font-size: 0; cursor: pointer; background: transparent; color: transparent; top: 50%; margin-top: -10px; padding: 0; border: none; outline: none; }
+.slick-prev:hover, .slick-prev:focus, .slick-next:hover, .slick-next:focus { outline: none; background: transparent; color: transparent; }
+.slick-prev:hover:before, .slick-prev:focus:before, .slick-next:hover:before, .slick-next:focus:before { opacity: 1; }
+.slick-prev.slick-disabled:before, .slick-next.slick-disabled:before { opacity: 0.25; }
+
+.slick-prev:before, .slick-next:before { font-family: "slick"; font-size: 20px; line-height: 1; color: white; opacity: 0.75; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
+
+.slick-prev { left: -25px; }
+[dir="rtl"] .slick-prev { left: auto; right: -25px; }
+.slick-prev:before { content: "←"; }
+[dir="rtl"] .slick-prev:before { content: "→"; }
+
+.slick-next { right: -25px; }
+[dir="rtl"] .slick-next { left: -25px; right: auto; }
+.slick-next:before { content: "→"; }
+[dir="rtl"] .slick-next:before { content: "←"; }
+
+/* Dots */
+.slick-slider { margin-bottom: 30px; }
+
+.slick-dots { position: absolute; bottom: -45px; list-style: none; display: block; text-align: center; padding: 0; width: 100%; }
+.slick-dots li { position: relative; display: inline-block; height: 20px; width: 20px; margin: 0 5px; padding: 0; cursor: pointer; }
+.slick-dots li button { border: 0; background: transparent; display: block; height: 20px; width: 20px; outline: none; line-height: 0; font-size: 0; color: transparent; padding: 5px; cursor: pointer; }
+.slick-dots li button:hover, .slick-dots li button:focus { outline: none; }
+.slick-dots li button:hover:before, .slick-dots li button:focus:before { opacity: 1; }
+.slick-dots li button:before { position: absolute; top: 0; left: 0; content: "•"; width: 20px; height: 20px; font-family: "slick"; font-size: 6px; line-height: 20px; text-align: center; color: black; opacity: 0.25; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
+.slick-dots li.slick-active button:before { color: black; opacity: 0.75; }
+
+/*# sourceMappingURL=slick.css.map */
diff --git a/src/main/resources/META-INF/resources/designer/css/carousel/slick.css.map b/src/main/resources/META-INF/resources/designer/css/carousel/slick.css.map
new file mode 100644 (file)
index 0000000..9f0499a
--- /dev/null
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": ";;AAuCA,aAAc,GACV,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,UAAU,EAC3B,qBAAqB,EAAE,IAAI,EAC3B,mBAAmB,EAAE,IAAI,EACzB,kBAAkB,EAAE,IAAI,EACxB,gBAAgB,EAAE,IAAI,EACtB,eAAe,EAAE,IAAI,EACrB,WAAW,EAAE,IAAI,EACjB,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE,KAAK,EACnB,2BAA2B,EAAE,WAAW;;AAE5C,WAAY,GACR,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,CAAC;AAEV,iBAAQ,GACJ,OAAO,EAAE,IAAI;AAGjB,0BAAiB,GACb,UAAU,EAAE,qDAA+D;AAG/E,oBAAW,GACP,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,IAAI;;AAGpB,0BAA2B,GACvB,iBAAiB,EAAE,oBAAoB,EACvC,cAAc,EAAE,oBAAoB,EACpC,aAAa,EAAE,oBAAoB,EACnC,YAAY,EAAE,oBAAoB,EAClC,SAAS,EAAE,oBAAoB;;AAGnC,YAAa,GACT,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,CAAC,EACP,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,KAAK;AAEd,uCACQ,GACJ,OAAO,EAAE,EAAE,EACX,OAAO,EAAE,KAAK;AAGlB,kBAAQ,GACJ,KAAK,EAAE,IAAI;AAGf,2BAAiB,GACb,UAAU,EAAE,MAAM;;AAG1B,YAAa,GACT,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,UAAU,EAAE,GAAG,EAWf,OAAO,EAAE,IAAI;AAVb,wBAAc,GACV,KAAK,EAAE,KAAK;AAEhB,gBAAI,GACA,OAAO,EAAE,KAAK;AAElB,8BAAoB,GAChB,OAAO,EAAE,IAAI;AAKjB,yBAAe,GACX,cAAc,EAAE,IAAI;AAGxB,+BAAqB,GACjB,OAAO,EAAE,KAAK;AAGlB,2BAAiB,GACb,UAAU,EAAE,MAAM;AAGtB,4BAAkB,GACd,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,qBAAqB;;;AAMnC,UASC,GARG,WAAW,EAAC,OAAO,EACnB,GAAG,EAAK,wBAA2B,EACnC,GAAG,EAAK,gMAA8D,EAItE,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM;;AAMxB,wBACY,GACR,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,EACZ,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,KAAK,EACjB,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,IAAI,EACZ,OAAO,EAAE,IAAI;AACb,0EAAiB,GACf,OAAO,EAAE,IAAI,EACb,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,WAAW;AAClB,sGAAS,GACP,OAAO,EA/JI,CAAC;AAkKhB,oEAAwB,GACpB,OAAO,EAlKM,IAAG;;AAqKxB,sCAAuC,GACnC,WAAW,EAjLK,OAAO,EAkLvB,SAAS,EAAE,IAAI,EACf,WAAW,EAAE,CAAC,EACd,KAAK,EAlLW,KAAK,EAmLrB,OAAO,EA5KO,IAAG,EA6KjB,sBAAsB,EAAE,WAAW,EACnC,uBAAuB,EAAE,SAAS;;AAEtC,WAAY,GACR,IAAI,EAAE,KAAK;AACX,uBAAc,GACV,IAAI,EAAG,IAAI,EACX,KAAK,EAAE,KAAK;AAEhB,kBAAS,GACL,OAAO,EA3LQ,GAAO;AA4LtB,8BAAc,GACV,OAAO,EA5LI,GAAO;;AAgM9B,WAAY,GACR,KAAK,EAAE,KAAK;AACZ,uBAAc,GACV,IAAI,EAAG,KAAK,EACZ,KAAK,EAAE,IAAI;AAEf,kBAAS,GACL,OAAO,EAvMQ,GAAO;AAwMtB,8BAAc,GACV,OAAO,EA1MI,GAAO;;;AAiN9B,aAAc,GACV,aAAa,EAAE,IAAI;;AAEvB,WAAY,GACR,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,KAAK,EACb,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,IAAI;AAEX,cAAG,GACC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,KAAK,EACb,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,OAAO;AAEf,qBAAO,GACH,MAAM,EAAE,CAAC,EACT,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,IAAI,EACX,OAAO,EAAE,IAAI,EACb,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,OAAO;AACf,wDAAiB,GACb,OAAO,EAAE,IAAI;AACb,sEAAS,GACP,OAAO,EAhPN,CAAC;AAoPR,4BAAS,GACL,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,EACP,OAAO,EA3PD,GAAO,EA4Pb,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,WAAW,EArQP,OAAO,EAsQX,SAAS,EA9PR,GAAG,EA+PJ,WAAW,EAAE,IAAI,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EArQI,KAAgB,EAsQzB,OAAO,EA/PF,IAAG,EAgQR,sBAAsB,EAAE,WAAW,EACnC,uBAAuB,EAAE,SAAS;AAK1C,yCAA6B,GACzB,KAAK,EA9QQ,KAAgB,EA+Q7B,OAAO,EA1QD,IAAG",
+"sources": ["slick.scss"],
+"names": [],
+"file": "slick.css"
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/dataTables.bootstrap.css b/src/main/resources/META-INF/resources/designer/css/dataTables.bootstrap.css
new file mode 100644 (file)
index 0000000..c07dac9
--- /dev/null
@@ -0,0 +1,233 @@
+div.dataTables_length label {
+    float: left;
+    text-align: left;
+    font-weight: normal;
+}
+
+div.dataTables_length select {
+    width: 75px;
+}
+
+div.dataTables_filter label {
+    float: right;
+    font-weight: normal;
+}
+
+div.dataTables_filter input {
+    width: 16em;
+}
+
+div.dataTables_info {
+    padding-top: 8px;
+}
+
+div.dataTables_paginate {
+    float: right;
+    margin: 0;
+}
+
+div.dataTables_paginate ul.pagination {
+    margin: 2px 0;
+    white-space: nowrap;
+}
+
+table.dataTable,
+table.dataTable td,
+table.dataTable th {
+    -webkit-box-sizing: content-box;
+    -moz-box-sizing: content-box;
+    box-sizing: content-box;
+}
+
+table.dataTable {
+    clear: both;
+    margin-top: 6px !important;
+    margin-bottom: 6px !important;
+    max-width: none !important;
+}
+
+table.dataTable thead .sorting,
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc,
+table.dataTable thead .sorting_asc_disabled,
+table.dataTable thead .sorting_desc_disabled {
+    cursor: pointer;
+}
+
+table.dataTable thead .sorting {
+    background: url('../images/sort_both.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_asc {
+    background: url('../images/sort_asc.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_desc {
+    background: url('../images/sort_desc.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_asc_disabled {
+    background: url('../images/sort_asc_disabled.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_desc_disabled {
+    background: url('../images/sort_desc_disabled.png') no-repeat center right;
+}
+
+table.dataTable th:active {
+    outline: none;
+}
+
+/* Scrolling */
+
+div.dataTables_scrollHead table {
+    margin-bottom: 0 !important;
+    border-bottom-left-radius: 0;
+    border-bottom-right-radius: 0;
+}
+
+div.dataTables_scrollHead table thead tr:last-child th:first-child,
+div.dataTables_scrollHead table thead tr:last-child td:first-child {
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.dataTables_scrollBody table {
+    margin-top: 0 !important;
+    margin-bottom: 0 !important;
+    border-top: none;
+}
+
+div.dataTables_scrollBody tbody tr:first-child th,
+div.dataTables_scrollBody tbody tr:first-child td {
+    border-top: none;
+}
+
+div.dataTables_scrollFoot table {
+    margin-top: 0 !important;
+    border-top: none;
+}
+
+/*
+ * TableTools styles
+ */
+
+.table tbody tr.active td,
+.table tbody tr.active th {
+    color: white;
+    background-color: #08C;
+}
+
+.table tbody tr.active:hover td,
+.table tbody tr.active:hover th {
+    background-color: #0075b0 !important;
+}
+
+.table tbody tr.active a {
+    color: white;
+}
+
+.table-striped tbody tr.active:nth-child(odd) td,
+.table-striped tbody tr.active:nth-child(odd) th {
+    background-color: #017ebc;
+}
+
+table.DTTT_selectable tbody tr {
+    cursor: pointer;
+}
+
+div.DTTT .btn {
+    font-size: 12px;
+    color: #333 !important;
+}
+
+div.DTTT .btn:hover {
+    text-decoration: none !important;
+}
+
+ul.DTTT_dropdown.dropdown-menu {
+    z-index: 2003;
+}
+
+ul.DTTT_dropdown.dropdown-menu a {
+    color: #333 !important; /* needed only when demo_page.css is included */
+}
+
+ul.DTTT_dropdown.dropdown-menu li {
+    position: relative;
+}
+
+ul.DTTT_dropdown.dropdown-menu li:hover a {
+    color: white !important;
+    background-color: #0088cc;
+}
+
+div.DTTT_collection_background {
+    z-index: 2002;
+}
+
+/* TableTools information display */
+
+div.DTTT_print_info.modal {
+    height: 150px;
+    margin-top: -75px;
+    text-align: center;
+}
+
+div.DTTT_print_info h6 {
+    margin: 1em;
+    font-size: 28px;
+    font-weight: normal;
+    line-height: 28px;
+}
+
+div.DTTT_print_info p {
+    font-size: 14px;
+    line-height: 20px;
+}
+
+/*
+ * FixedColumns styles
+ */
+
+div.DTFC_LeftHeadWrapper table,
+div.DTFC_LeftFootWrapper table,
+div.DTFC_RightHeadWrapper table,
+div.DTFC_RightFootWrapper table,
+table.DTFC_Cloned tr.even {
+    background-color: white;
+}
+
+div.DTFC_RightHeadWrapper table,
+div.DTFC_LeftHeadWrapper table {
+    margin-bottom: 0 !important;
+    border-top-right-radius: 0 !important;
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,
+div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,
+div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,
+div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.DTFC_RightBodyWrapper table,
+div.DTFC_LeftBodyWrapper table {
+    margin-bottom: 0 !important;
+    border-top: none;
+}
+
+div.DTFC_RightBodyWrapper tbody tr:first-child th,
+div.DTFC_RightBodyWrapper tbody tr:first-child td,
+div.DTFC_LeftBodyWrapper tbody tr:first-child th,
+div.DTFC_LeftBodyWrapper tbody tr:first-child td {
+    border-top: none;
+}
+
+div.DTFC_RightFootWrapper table,
+div.DTFC_LeftFootWrapper table {
+    border-top: none;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/dataTables.fixedColumns.css b/src/main/resources/META-INF/resources/designer/css/dataTables.fixedColumns.css
new file mode 100644 (file)
index 0000000..ee75c26
--- /dev/null
@@ -0,0 +1,22 @@
+/* Block out what is behind the fixed column's header and footer */
+table.DTFC_Cloned thead,
+table.DTFC_Cloned tfoot {
+       background-color: white;
+}
+
+/* Block out the gap above the scrollbar on the right, when there is a fixed
+ * right column
+ */
+div.DTFC_Blocker {
+       background-color: white;
+}
+
+div.DTFC_LeftWrapper table.dataTable,
+div.DTFC_RightWrapper table.dataTable {
+       margin-bottom: 0;
+}
+
+div.DTFC_LeftWrapper table.dataTable.no-footer,
+div.DTFC_RightWrapper table.dataTable.no-footer {
+       border-bottom: none;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/dataTables.tableTools.css b/src/main/resources/META-INF/resources/designer/css/dataTables.tableTools.css
new file mode 100644 (file)
index 0000000..844ca42
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * File:        TableTools.css
+ * Description: Styles for TableTools 2
+ * Author:      Allan Jardine (www.sprymedia.co.uk)
+ * Language:    Javascript
+ * License:     GPL v2 / 3 point BSD
+ * Project:     DataTables
+ * 
+ * Copyright 2009-2012 Allan Jardine, all rights reserved.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * CSS name space:
+ *   DTTT                  DataTables TableTools
+ *
+ * Style sheet provides:
+ *   CONTAINER             TableTools container element and styles applying to all components
+ *   BUTTON_STYLES         Action specific button styles
+ *   SELECTING             Row selection styles
+ *   COLLECTIONS           Drop down list (collection) styles
+ *   PRINTING              Print display styles
+ */
+
+
+/*
+ * CONTAINER
+ * TableTools container element and styles applying to all components
+ */
+div.DTTT_container {
+       position: relative;
+       float: right;
+       margin-bottom: 1em;
+}
+
+@media screen and (max-width: 640px) {
+       div.DTTT_container {
+               float: none !important;
+               text-align: center;
+       }
+
+       div.DTTT_container:after {
+               visibility: hidden;
+               display: block;
+               content: "";
+               clear: both;
+               height: 0;
+       }
+}
+
+
+button.DTTT_button,
+div.DTTT_button,
+a.DTTT_button {
+       position: relative;
+       display: inline-block;
+       margin-right: 3px;
+       padding: 5px 8px;
+       border: 1px solid #999;
+       cursor: pointer;
+       *cursor: hand;
+       font-size: 0.88em;
+       color: black !important;
+
+       -webkit-border-radius: 2px;
+          -moz-border-radius: 2px;
+           -ms-border-radius: 2px;
+            -o-border-radius: 2px;
+               border-radius: 2px;
+
+       -webkit-box-shadow: 1px 1px 3px #ccc;
+          -moz-box-shadow: 1px 1px 3px #ccc;
+           -ms-box-shadow: 1px 1px 3px #ccc;
+            -o-box-shadow: 1px 1px 3px #ccc;
+               box-shadow: 1px 1px 3px #ccc;
+
+       /* Generated by http://www.colorzilla.com/gradient-editor/ */
+       background: #ffffff; /* Old browsers */
+       background: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */
+       background:    -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */
+       background:     -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */
+       background:      -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */
+       background:         linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */
+}
+
+
+/* Buttons are cunning border-box sizing - we can't just use that for A and DIV due to IE6/7 */
+button.DTTT_button {
+       height: 30px;
+       padding: 3px 8px;
+}
+
+.DTTT_button embed { 
+       outline: none;
+}
+
+button.DTTT_button:hover,
+div.DTTT_button:hover,
+a.DTTT_button:hover {
+       border: 1px solid #666;
+       text-decoration: none !important;
+
+       -webkit-box-shadow: 1px 1px 3px #999;
+          -moz-box-shadow: 1px 1px 3px #999;
+           -ms-box-shadow: 1px 1px 3px #999;
+            -o-box-shadow: 1px 1px 3px #999;
+               box-shadow: 1px 1px 3px #999;
+
+       background: #f3f3f3; /* Old browsers */
+       background: -webkit-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Chrome10+,Safari5.1+ */
+       background:    -moz-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* FF3.6+ */
+       background:     -ms-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* IE10+ */
+       background:      -o-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Opera 11.10+ */
+       background:         linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* W3C */
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f3f3f3', endColorstr='#f4f4f4',GradientType=0 ); /* IE6-9 */
+}
+
+button.DTTT_button:focus,
+div.DTTT_button:focus,
+a.DTTT_button:focus {
+       border: 1px solid #426c9e;
+       text-shadow: 0 1px 0 #c4def1;
+       outline: none;
+
+       background-color: #a3d0ef 100%;
+       background-image: -webkit-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);
+       background-image:    -moz-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);
+       background-image:     -ms-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);
+       background-image:      -o-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);
+       background-image:         linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#a3d0ef', EndColorStr='#a3d0ef');
+}
+
+button.DTTT_button:active,
+div.DTTT_button:active,
+a.DTTT_button:active {
+       -webkit-box-shadow: inset 1px 1px 3px #999999;
+       -moz-box-shadow: inset 1px 1px 3px #999999;
+       box-shadow: inset 1px 1px 3px #999999;
+}
+
+button.DTTT_disabled,
+div.DTTT_disabled,
+a.DTTT_disabled {
+       color: #999;
+       border: 1px solid #d0d0d0;
+       
+       background: #ffffff; /* Old browsers */
+       background: -webkit-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* Chrome10+,Safari5.1+ */
+       background:    -moz-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* FF3.6+ */
+       background:     -ms-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* IE10+ */
+       background:      -o-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* Opera 11.10+ */
+       background:         linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* W3C */
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#fafafa',GradientType=0 ); /* IE6-9 */
+}
+
+
+
+/*
+ * BUTTON_STYLES
+ * Action specific button styles
+ * If you want images - comment this back in
+
+a.DTTT_button_csv,
+a.DTTT_button_xls,
+a.DTTT_button_copy,
+a.DTTT_button_pdf,
+a.DTTT_button_print {
+       padding-right: 0px;
+}
+
+a.DTTT_button_csv span,
+a.DTTT_button_xls span,
+a.DTTT_button_copy span,
+a.DTTT_button_pdf span,
+a.DTTT_button_print span {
+       display: inline-block;
+       height: 24px;
+       line-height: 24px;
+       padding-right: 30px;
+}
+
+
+a.DTTT_button_csv span { background: url(../images/csv.png) no-repeat bottom right; }
+a.DTTT_button_csv:hover span { background: url(../images/csv_hover.png) no-repeat center right; }
+
+a.DTTT_button_xls span { background: url(../images/xls.png) no-repeat center right; }
+a.DTTT_button_xls:hover span { background: #f0f0f0 url(../images/xls_hover.png) no-repeat center right; }
+
+a.DTTT_button_copy span { background: url(../images/copy.png) no-repeat center right; }
+a.DTTT_button_copy:hover span { background: #f0f0f0 url(../images/copy_hover.png) no-repeat center right; }
+
+a.DTTT_button_pdf span { background: url(../images/pdf.png) no-repeat center right; }
+a.DTTT_button_pdf:hover span { background: #f0f0f0 url(../images/pdf_hover.png) no-repeat center right; }
+
+a.DTTT_button_print span { background: url(../images/print.png) no-repeat center right; }
+a.DTTT_button_print:hover span { background: #f0f0f0 url(../images/print_hover.png) no-repeat center right; }
+
+ */
+
+button.DTTT_button_collection span {
+       padding-right: 17px;
+       background: url(../images/collection.png) no-repeat center right;
+}
+
+button.DTTT_button_collection:hover span {
+       padding-right: 17px;
+       background: #f0f0f0 url(../images/collection_hover.png) no-repeat center right;
+}
+
+
+/*
+ * SELECTING
+ * Row selection styles
+ */
+table.DTTT_selectable tbody tr {
+       cursor: pointer;
+       *cursor: hand;
+}
+
+table.dataTable tr.DTTT_selected.odd {
+       background-color: #9FAFD1;
+}
+
+table.dataTable tr.DTTT_selected.odd td.sorting_1 {
+       background-color: #9FAFD1;
+}
+
+table.dataTable tr.DTTT_selected.odd td.sorting_2 {
+       background-color: #9FAFD1;
+}
+
+table.dataTable tr.DTTT_selected.odd td.sorting_3 {
+       background-color: #9FAFD1;
+}
+
+
+table.dataTable tr.DTTT_selected.even {
+       background-color: #B0BED9;
+}
+
+table.dataTable tr.DTTT_selected.even td.sorting_1 {
+       background-color: #B0BED9;
+}
+
+table.dataTable tr.DTTT_selected.even td.sorting_2 {
+       background-color: #B0BED9;
+}
+
+table.dataTable tr.DTTT_selected.even td.sorting_3 {
+       background-color: #B0BED9;
+}
+
+
+/*
+ * COLLECTIONS
+ * Drop down list (collection) styles
+ */
+
+div.DTTT_collection {
+       width: 150px;
+       padding: 8px 8px 4px 8px;
+       border: 1px solid #ccc;
+       border: 1px solid rgba( 0, 0, 0, 0.4 );
+       background-color: #f3f3f3;
+       background-color: rgba( 255, 255, 255, 0.3 );
+       overflow: hidden;
+       z-index: 2002;
+
+       -webkit-border-radius: 5px;
+          -moz-border-radius: 5px;
+           -ms-border-radius: 5px;
+            -o-border-radius: 5px;
+               border-radius: 5px;
+       
+       -webkit-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
+          -moz-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
+           -ms-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
+            -o-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
+               box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
+}
+
+div.DTTT_collection_background {
+       background: transparent url(../images/background.png) repeat top left;
+       z-index: 2001;
+}
+
+div.DTTT_collection button.DTTT_button,
+div.DTTT_collection div.DTTT_button,
+div.DTTT_collection a.DTTT_button {
+       position: relative;
+       left: 0;
+       right: 0;
+
+       display: block;
+       float: none;
+       margin-bottom: 4px;
+       
+       -webkit-box-shadow: 1px 1px 3px #999;
+          -moz-box-shadow: 1px 1px 3px #999;
+           -ms-box-shadow: 1px 1px 3px #999;
+            -o-box-shadow: 1px 1px 3px #999;
+               box-shadow: 1px 1px 3px #999;
+}
+
+
+/*
+ * PRINTING
+ * Print display styles
+ */
+
+.DTTT_print_info {
+       position: fixed;
+       top: 50%;
+       left: 50%;
+       width: 400px;
+       height: 150px;
+       margin-left: -200px;
+       margin-top: -75px;
+       text-align: center;
+       color: #333;
+       padding: 10px 30px;
+
+       background: #ffffff; /* Old browsers */
+       background: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */
+       background:    -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */
+       background:     -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */
+       background:      -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */
+       background:         linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */
+       
+       opacity: 0.95;
+
+       border: 1px solid black;
+       border: 1px solid rgba(0, 0, 0, 0.5);
+       
+       -webkit-border-radius: 6px;
+          -moz-border-radius: 6px;
+           -ms-border-radius: 6px;
+            -o-border-radius: 6px;
+               border-radius: 6px;
+       
+       -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
+          -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
+           -ms-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
+            -o-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
+               box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
+}
+
+.DTTT_print_info h6 {
+       font-weight: normal;
+       font-size: 28px;
+       line-height: 28px;
+       margin: 1em;
+}
+
+.DTTT_print_info p {
+       font-size: 14px;
+       line-height: 20px;
+}
+
diff --git a/src/main/resources/META-INF/resources/designer/css/diagram-js.css b/src/main/resources/META-INF/resources/designer/css/diagram-js.css
new file mode 100644 (file)
index 0000000..8796603
--- /dev/null
@@ -0,0 +1,473 @@
+/**
+ * outline styles
+ */
+
+.djs-outline {
+  fill: none;
+  visibility: hidden;
+}
+
+.djs-element.hover .djs-outline,
+.djs-element.selected .djs-outline {
+  visibility: visible;
+  shape-rendering: crispEdges;
+  stroke-dasharray: 3,3;
+}
+
+.djs-element.selected .djs-outline {
+  stroke: #8888FF;
+  stroke-width: 1px;
+}
+
+.djs-element.hover .djs-outline {
+  stroke: #FF8888;
+  stroke-width: 1px;
+}
+
+.djs-shape.connect-ok .djs-visual > :nth-child(1) {
+  fill: #54FF00 /* light-green */ !important;
+  fill-opacity: 0.2;
+}
+
+.djs-shape.connect-not-ok .djs-visual > :nth-child(1),
+.djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
+  fill: #E56283 /* light-red */ !important;
+  fill-opacity: 0.2;
+}
+
+svg.drop-not-ok {
+  background: rgba(229, 98, 131, 0.2) /* light-red */ !important;
+}
+
+.djs-connection.connect-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-ok .djs-visual > :nth-child(1) {
+  stroke: #90DD5F /* light-green */ !important;
+}
+
+.djs-connection.connect-not-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
+  stroke: #E56283 /* light-red */ !important;
+}
+
+.drop-not-ok,
+.connect-not-ok {
+  cursor: not-allowed;
+}
+
+
+/**
+* Selection box style
+*
+*/
+.djs-lasso-overlay {
+  fill: rgb(255, 116, 0);
+  fill-opacity: 0.1;
+
+  stroke-dasharray: 5 1 3 1;
+  stroke: rgb(255, 116, 0);
+
+  shape-rendering: crispEdges;
+  pointer-events: none;
+}
+
+/**
+ * Resize styles
+ */
+.djs-resize-overlay {
+  fill: white;
+  fill-opacity: 0.8;
+
+  stroke-dasharray: 5 1 3 1;
+  stroke: rgb(255, 116, 0);
+
+  pointer-events: none;
+}
+
+.djs-resizer-hit {
+  fill: none;
+  pointer-events: all;
+}
+
+.djs-resizer-visual {
+  fill: white;
+  stroke-width: 1px;
+  stroke: black;
+  shape-rendering: crispEdges;
+  stroke-opacity: 0.2;
+}
+
+.djs-cursor-resize-nwse,
+.djs-resizer-nw,
+.djs-resizer-se {
+  cursor: nwse-resize;
+}
+
+.djs-cursor-resize-nesw,
+.djs-resizer-ne,
+.djs-resizer-sw {
+  cursor: nesw-resize;
+}
+
+.djs-shape.djs-resizing > .djs-outline {
+  visibility: hidden !important;
+}
+
+.djs-shape.djs-resizing > .djs-resizer {
+  visibility: hidden;
+}
+
+.djs-dragger > .djs-resizer {
+  visibility: hidden;
+}
+
+/**
+ * drag styles
+ */
+.djs-dragger {
+  fill: white;
+  fill-opacity: 0.6;
+  stroke: #333;
+}
+
+.djs-dragger .djs-visual > :first-child {
+  stroke: rgb(255, 116, 0) !important;
+}
+
+.djs-dragging {
+  opacity: 0.3;
+}
+
+.djs-dragging,
+.djs-dragging > * {
+  pointer-events: none !important;
+}
+
+.djs-dragging .djs-context-pad,
+.djs-dragging .djs-outline {
+  display: none !important;
+}
+
+/**
+ * no pointer events for visual
+ */
+.djs-visual,
+.djs-outline {
+  pointer-events: none;
+}
+
+/**
+ * all pointer events for hit shape
+ */
+.djs-shape .djs-hit {
+  pointer-events: all;
+}
+
+.djs-connection .djs-hit {
+  pointer-events: stroke;
+}
+
+/**
+ * shape / connection basic styles
+ */
+.djs-connection .djs-visual {
+  stroke-width: 2px;
+  fill: none;
+}
+
+.djs-cursor-grabbing {
+  cursor: -webkit-grabbing;
+  cursor: -moz-grabbing;
+  cursor: grabbing;
+}
+
+.djs-cursor-crosshair {
+  cursor: crosshair;
+}
+
+.djs-cursor-move {
+  cursor: move;
+}
+
+.djs-cursor-resize-ns {
+  cursor: ns-resize;
+}
+
+.djs-cursor-resize-ew {
+  cursor: ew-resize;
+}
+
+
+/**
+ * snapping
+ */
+.djs-snap-line {
+  stroke: rgb(255, 195, 66);
+  stroke: rgba(255, 195, 66, 0.50);
+  stroke-linecap: round;
+  stroke-width: 2px;
+  pointer-events: none;
+}
+
+/**
+ * snapping
+ */
+.djs-crosshair {
+  stroke: #555;
+  stroke-linecap: round;
+  stroke-width: 1px;
+  pointer-events: none;
+  shape-rendering: crispEdges;
+  stroke-dasharray: 5, 5;
+}
+
+/**
+ * palette
+ */
+
+.djs-palette {
+  position: absolute;
+  left: 20%;
+  top: 4px;
+  x: 400px;
+  y: 10px;
+  height: 50px;
+  width: 326px;
+}
+
+.djs-palette:not(.open) {
+  overflow: hidden;
+}
+
+.djs-palette .entry {
+  width: 46px;
+  height: 50px;
+  line-height: 46px;
+  display:inline;
+  float:left;
+}
+
+
+.djs-palette .djs-palette-toggle {
+  width: 426px;
+  height: 60px;
+  line-height: 46px;
+  display:inline;
+  float:left;  
+}
+
+.djs-palette .separator {
+  margin: 3px 5px 5px 5px;
+  border: solid 1px #DDD;
+  border-radius: 1px;
+};
+
+.djs-palette .entry:before {
+  vertical-align: middle;
+}
+
+.djs-palette .djs-palette-toggle {
+  cursor: pointer;
+}
+
+.djs-palette .entry,
+.djs-palette .djs-palette-toggle {
+  color: #333;
+  font-size: 30px;
+
+  text-align: center;
+}
+
+.djs-palette.open .djs-palette-toggle {
+  height: 14px;
+}
+
+.djs-palette:not(.open) .djs-palette-entries {
+  display: none;
+  border-color:black;
+}
+
+.djs-palette .djs-palette-toggle:hover {
+/*  background: #fff; */
+}
+
+.djs-palette .entry:hover {
+  /* color: rgb(255, 116, 0); */
+}
+
+/**
+ * context-pad
+ */
+.djs-overlay-context-pad {
+  width: 72px;
+}
+
+.djs-context-pad {
+  position: absolute;
+  display: none;
+  pointer-events: none;
+}
+
+.djs-context-pad .entry {
+  width: 22px;
+  height: 22px;
+  text-align: center;
+  display: inline-block;
+  font-size: 22px;
+  margin: 0 2px 2px 0;
+
+  border-radius: 3px;
+
+  cursor: default;
+
+  background-color: rgba(255,255,255, 0.85);
+  box-shadow: 0 0 2px 1px rgba(255,255,255, 0.85);
+
+  pointer-events: all;
+}
+
+.djs-context-pad .entry:before {
+  vertical-align: top;
+}
+
+.djs-context-pad .entry:hover {
+  background: rgb(255, 252, 176);
+}
+
+.djs-context-pad.open {
+  display: block;
+  z-index: 9;
+}
+
+.djs-popup-entry {
+  font-size: 20px;
+  line-height: 20px;
+  padding: 2px 10px 2px 5px;
+  background-color: rgba(255,255,255, 0.85);
+  white-space: nowrap;
+}
+
+.djs-popup-entry:hover {
+  background: rgb(255, 252, 176);
+}
+
+.djs-popup-entry > span {
+  font-size: 14px;
+  margin-left: 5px;
+
+  vertical-align: middle;
+}
+
+.djs-popup-entry:before {
+  vertical-align: middle;
+}
+
+/**
+ * popup / palette styles
+ */
+.djs-popup, .djs-palette {
+  background: #FAFAFA;
+  border: solid 1px #CCC;
+  border-radius: 2px;
+  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
+}
+
+/**
+ * touch
+ */
+
+.djs-shape,
+.djs-connection {
+  touch-action: none;
+}
+
+.djs-bendpoint {
+  display: none;
+}
+
+/**
+ * bendpoints
+ */
+.djs-bendpoint .djs-visual {
+  pointer-events: none;
+  fill: rgba(255, 255, 121, 0.8);
+  stroke-width: 1px;
+  stroke-opacity: 0.5;
+  stroke: black;
+}
+
+.djs-bendpoint:hover,
+.djs-bendpoints.hover .djs-bendpoint,
+.djs-bendpoints.selected .djs-bendpoint {
+  display: block;
+}
+
+.djs-bendpoints:not(.hover) .floating {
+  display: none;
+}
+
+.djs-bendpoint:hover .djs-visual,
+.djs-bendpoint.floating .djs-visual {
+  fill: yellow;
+}
+
+.djs-bendpoint.floating .djs-hit {
+  pointer-events: none;
+}
+
+.djs-bendpoint .djs-hit {
+  pointer-events: all;
+  fill: none;
+}
+
+.djs-updating,
+.djs-updating > * {
+  pointer-events: none !important;
+}
+
+.djs-updating .djs-context-pad,
+.djs-updating .djs-outline,
+.djs-updating .djs-bendpoint,
+.connect-ok .djs-bendpoint,
+.connect-not-ok .djs-bendpoint,
+.drop-ok .djs-bendpoint,
+.drop-not-ok .djs-bendpoint {
+  display: none !important;
+}
+
+.djs-bendpoint.djs-dragging {
+  display: block;
+  opacity: 1.0;
+}
+
+.djs-bendpoint.djs-dragging .djs-visual {
+  fill: yellow;
+}
+
+
+/**
+ * tooltips
+ */
+.djs-tooltip-error {
+  font-size: 11px;
+  line-height: 18px;
+  text-align: left;
+
+  padding: 5px;
+
+  opacity: 0.7;
+}
+
+.djs-tooltip-error > * {
+  width: 160px;
+
+  background: rgb(252, 236, 240);
+  color: rgb(158, 76, 76);
+  padding: 3px 7px;
+  box-shadow: 0 1px 3px rgba(0,0,0, 0.2);
+  border-radius: 5px;
+  border-left: solid 5px rgb(174, 73, 73);
+}
+
+.djs-tooltip-error:hover {
+  opacity: 1;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/dialogs.css b/src/main/resources/META-INF/resources/designer/css/dialogs.css
new file mode 100644 (file)
index 0000000..1a915ef
--- /dev/null
@@ -0,0 +1,15 @@
+/* Custom dialog/modal headers */
+
+.dialog-header-error { background-color: #d2322d; }
+.dialog-header-wait { background-color: #428bca; }
+.dialog-header-notify { background-color: #eeeeee; }
+.dialog-header-confirm { background-color: #333333; }
+       .dialog-header-error span, .dialog-header-error h4,
+       .dialog-header-wait span, .dialog-header-wait h4,
+       .dialog-header-confirm span, .dialog-header-confirm h4 { color: #ffffff; }
+
+       
+
+/*.bjs-powered-by{
+       display:none;
+}*/
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.css b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.css
new file mode 100644 (file)
index 0000000..bd2bd23
--- /dev/null
@@ -0,0 +1,630 @@
+
+@charset "UTF-8";
+/* CSS Document */
+.flexigrid {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+       line-height: normal;
+       position: relative;
+       border: 0px solid #eee;
+       overflow: hidden;
+       color: #000;
+}
+
+.flexigrid.hideBody {
+       height: 26px !important;
+       border-bottom: 1px solid #ccc;
+}
+
+.ie6fullwidthbug {
+       border-right: 0px solid #ccc;
+       padding-right: 2px;
+}
+
+.flexigrid div.nDiv {
+       background: #eee url(images/line.gif) repeat-y -1px top;
+       border: 1px solid #ccc;
+       border-top: 0px;
+       overflow: auto;
+       left: 0px;
+       position: absolute;
+       z-index: 999;
+       float: left;
+}
+
+.flexigrid div.nDiv table {
+       margin: 2px;
+}
+
+.flexigrid div.hDivBox {
+       float: left;
+       padding-right: 40px;
+}
+
+.flexigrid div.bDiv table {
+       margin-bottom: 10px;
+}
+
+.flexigrid div.bDiv table.autoht {
+       border-bottom: 0px;
+       margin-bottom: 0px;
+}
+
+.flexigrid div.nDiv td {
+       padding: 2px 3px;
+       border: 1px solid #eee;
+       cursor: default;
+}
+
+.flexigrid div.nDiv tr:hover td,.flexigrid div.nDiv tr.ndcolover td {
+       background: #d5effc url(images/hl.png) repeat-x top;
+       border: 1px solid #a8d8eb;
+}
+
+.flexigrid div.nDiv td.ndcol1 {
+       border-right: 1px solid #ccc;
+}
+
+.flexigrid div.nDiv td.ndcol2 {
+       border-left: 1px solid #fff;
+       padding-right: 10px;
+}
+
+.flexigrid div.nDiv tr:hover td.ndcol1,.flexigrid div.nDiv tr.ndcolover td.ndcol1
+       {
+       border-right: 1px solid #d2e3ec;
+}
+
+.flexigrid div.nDiv tr:hover td.ndcol2,.flexigrid div.nDiv tr.ndcolover td.ndcol2
+       {
+       border-left: 1px solid #eef8ff;
+}
+
+.flexigrid div.nBtn {
+       position: absolute;
+       height: 24px;
+       width: 14px;
+       z-index: 900;
+       background: #fafafa url(images/fhbg.gif) repeat-x bottom;
+       border: 0px solid #ccc;
+       border-left: 1px solid #ccc;
+       top: 0px;
+       left: 0px;
+       margin-top: 1px;
+       cursor: pointer;
+       display: none;
+}
+
+.flexigrid div.nBtn div {
+       height: 24px;
+       width: 12px;
+       border-left: 1px solid #fff;
+       float: left;
+       background: url(images/ddn.png) no-repeat center;
+}
+
+.flexigrid div.nBtn.srtd {
+       background: url(images/wbg.gif) repeat-x 0px -1px;
+}
+
+.flexigrid div.mDiv {
+       background: url(images/wbg.gif) repeat-x top;
+       border: 1px solid #ccc;
+       border-bottom: 0px;
+       border-top: 0px;
+       font-weight: bold;
+       display: block;
+       overflow: hidden;
+       white-space: nowrap;
+       position: relative;
+}
+
+.flexigrid div.mDiv div {
+       padding: 6px;
+       white-space: nowrap;
+}
+
+.flexigrid div.mDiv div.ptogtitle {
+       position: absolute;
+       top: 4px;
+       right: 3px;
+       padding: 0px;
+       height: 16px;
+       width: 16px;
+       overflow: hidden;
+       border: 1px solid #ccc;
+       cursor: pointer;
+}
+
+.flexigrid div.mDiv div.ptogtitle:hover {
+       background-position: left -2px;
+       border-color: #bbb;
+}
+
+.flexigrid div.mDiv div.ptogtitle span {
+       display: block;
+       border-left: 1px solid #eee;
+       border-top: 1px solid #fff;
+       border-bottom: 1px solid #ddd;
+       width: 14px;
+       height: 14px;
+       background: url(images/uup.png) no-repeat center;
+}
+
+.flexigrid div.mDiv div.ptogtitle.vsble span {
+       background: url(images/ddn.png) no-repeat center;
+}
+
+.flexigrid div.tDiv /*toolbar*/ {
+       background: #fafafa url(images/bg.gif) repeat-x top;
+       position: relative;
+       border: 1px solid #ccc;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.tDiv2 {
+       float: left;
+       clear: both;
+       padding: 1px;
+}
+
+.flexigrid div.sDiv /*toolbar*/ {
+       background: #fafafa url(images/bg.gif) repeat-x top;
+       position: relative;
+       border: 1px solid #ccc;
+       border-top: 0px;
+       overflow: hidden;
+       display: none;
+}
+
+.flexigrid div.sDiv2 {
+       float: left;
+       clear: both;
+       padding: 5px;
+       padding-left: 5px;
+       width: 1024px;
+}
+
+.flexigrid div.sDiv2 input,.flexigrid div.sDiv2 select {
+       vertical-align: middle;
+}
+
+.flexigrid div.btnseparator {
+       float: left;
+       height: 22px;
+       border-left: 1px solid #ccc;
+       border-right: 1px solid #fff;
+       margin: 1px;
+}
+
+.flexigrid div.fbutton {
+       float: left;
+       display: block;
+       cursor: pointer;
+       padding: 1px;
+}
+
+.flexigrid div.fbutton div {
+       float: left;
+       padding: 1px 3px;
+}
+
+.flexigrid div.fbutton span {
+       float: left;
+       display: block;
+       padding: 3px;
+}
+
+.flexigrid div.fbutton:hover,.flexigrid div.fbutton.fbOver {
+       padding: 0px;
+       border: 1px solid #ccc;
+}
+
+.flexigrid div.fbutton:hover div,.flexigrid div.fbutton.fbOver div {
+       padding: 0px 2px;
+       border-left: 1px solid #fff;
+       border-top: 1px solid #fff;
+       border-right: 1px solid #eee;
+       border-bottom: 1px solid #eee;
+}
+
+/* end toolbar*/
+.flexigrid div.hDiv {
+       background: #fafafa url(images/fhbg.gif) repeat-x bottom;
+       position: relative;
+       border: 1px solid #ccc;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.hDiv table {
+       border-right: 1px solid #fff;
+}
+
+.flexigrid div.cDrag {
+       float: left;
+       position: absolute;
+       z-index: 2;
+       overflow: visible;
+}
+
+.flexigrid div.cDrag div {
+       float: left;
+       background: none;
+       display: block;
+       position: absolute;
+       height: 24px;
+       width: 5px;
+       cursor: col-resize;
+}
+
+.flexigrid div.cDrag div:hover,.flexigrid div.cDrag div.dragging {
+       background: url(images/line.gif) repeat-y 2px center;
+}
+
+.flexigrid div.iDiv {
+       border: 1px solid #316ac5;
+       position: absolute;
+       overflow: visible;
+       background: none;
+}
+
+.flexigrid div.iDiv input,.flexigrid div.iDiv select,.flexigrid div.iDiv textarea
+       {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+}
+
+.flexigrid div.iDiv input.tb {
+       border: 0px;
+       padding: 0px;
+       width: 100%;
+       height: 100%;
+       padding: 0px;
+       background: none;
+}
+
+.flexigrid div.bDiv {
+       border: 1px solid #ccc;
+       border-top: 0px;
+       background: #fff;
+       overflow: auto;
+       position: relative;
+}
+
+.flexigrid div.bDiv table {
+       border-bottom: 1px solid #ccc;
+}
+
+.flexigrid div.hGrip {
+       position: absolute;
+       top: 0px;
+       right: 0px;
+       height: 5px;
+       width: 5px;
+       background: url(images/line.gif) repeat-x center;
+       margin-right: 1px;
+       cursor: col-resize;
+}
+
+.flexigrid div.hGrip:hover,.flexigrid div.hGrip.hgOver {
+       border-right: 1px solid #999;
+       margin-right: 0px;
+}
+
+.flexigrid div.vGrip {
+       height: 5px;
+       overflow: hidden;
+       position: relative;
+       background: #fafafa url(images/wbg.gif) repeat-x 0px -1px;
+       border: 1px solid #ccc;
+       border-top: 0px;
+       text-align: center;
+       cursor: row-resize;
+}
+
+.flexigrid div.vGrip span {
+       display: block;
+       margin: 1px auto;
+       width: 20px;
+       height: 1px;
+       overflow: hidden;
+       border-top: 1px solid #aaa;
+       border-bottom: 1px solid #aaa;
+       background: none;
+}
+
+.flexigrid div.hDiv th,.flexigrid  div.bDiv td
+       /* common cell properties*/ {
+       text-align: left;
+       border-right: 1px solid #ddd;
+       border-left: 1px solid #fff;
+       overflow: hidden;
+       vertical-align: top !important;
+       padding-left: 0;
+       padding-right: 0;
+}
+
+.flexigrid div.hDiv th div,.flexigrid  div.bDiv td  div,div.colCopy div
+       /* common inner cell properties*/ {
+       padding: 5px;
+       border-left: 0px solid #fff;
+}
+
+.flexigrid div.hDiv th,div.colCopy {
+       font-weight: normal;
+       height: 24px;
+       cursor: default;
+       white-space: nowrap;
+       overflow: hidden;
+}
+
+div.colCopy {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+       background: #fafafa url(images/fhbg.gif) repeat-x bottom;
+       border: 1px solid #ccc;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.hDiv th.sorted {
+       background: url(images/wbg.gif) repeat-x 0px -1px;
+       border-bottom: 0px solid #ccc;
+}
+
+.flexigrid div.hDiv th.thOver {
+       
+}
+
+.flexigrid div.hDiv th.thOver div,.flexigrid div.hDiv th.sorted.thOver div
+       {
+       border-bottom: 1px solid orange;
+       padding-bottom: 4px;
+}
+
+.flexigrid div.hDiv th.sorted div {
+       border-bottom: 0px solid #ccc;
+       padding-bottom: 5px;
+}
+
+.flexigrid div.hDiv th.thMove {
+       background: #fff;
+       color: #fff;
+}
+
+.flexigrid div.hDiv th.sorted.thMove div {
+       border-bottom: 1px solid #fff;
+       padding-bottom: 4px
+}
+
+.flexigrid div.hDiv th.thMove div {
+       background: #fff !important;
+}
+
+.flexigrid div.hDiv th div.sdesc {
+       background: url(images/dn.png) no-repeat center top;
+}
+
+.flexigrid div.hDiv th div.sasc {
+       background: url(images/up.png) no-repeat center top;
+}
+
+.flexigrid div.bDiv td {
+       border-bottom: 1px solid #fff;
+       vertical-align: top;
+       white-space: nowrap;
+}
+
+.flexigrid div.hDiv th div {
+       
+}
+
+.flexigrid span.cdropleft {
+       display: block;
+       background: url(images/prev.gif) no-repeat -4px center;
+       width: 24px;
+       height: 24px;
+       position: relative;
+       top: -24px;
+       margin-bottom: -24px;
+       z-index: 3;
+}
+
+.flexigrid div.hDiv span.cdropright {
+       display: block;
+       background: url(images/next.gif) no-repeat 12px center;
+       width: 24px;
+       height: 24px;
+       float: right;
+       position: relative;
+       top: -24px;
+       margin-bottom: -24px;
+}
+
+.flexigrid div.bDiv td div {
+       border-top: 0px solid #fff;
+       padding-bottom: 4px;
+}
+
+.flexigrid tr td.sorted {
+       background: #f3f3f3;
+       border-right: 1px solid #ddd;
+       border-bottom: 1px solid #f3f3f3;
+}
+
+.flexigrid tr td.sorted div {
+       
+}
+
+.flexigrid tr.erow td {
+       background: #f7f7f7;
+       border-bottom: 1px solid #f7f7f7;
+}
+
+.flexigrid tr.erow td.sorted {
+       background: #e3e3e3;
+       border-bottom: 1px solid #e3e3e3;
+}
+
+.flexigrid tr.erow td.sorted div {
+       
+}
+
+.flexigrid div.bDiv tr:hover td,.flexigrid div.bDiv tr:hover td.sorted,.flexigrid div.bDiv tr.trOver td.sorted,.flexigrid div.bDiv tr.trOver td
+       {
+       background: #d9ebf5;
+       border-left: 1px solid #eef8ff;
+       border-bottom: 1px dotted #a8d8eb;
+}
+
+.flexigrid div.bDiv tr.trSelected:hover td,.flexigrid div.bDiv tr.trSelected:hover td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td,.flexigrid tr.trSelected td.sorted,.flexigrid tr.trSelected td
+       {
+       background: #d5effc url(images/hl.png) repeat-x top;
+       border-right: 1px solid #d2e3ec;
+       border-left: 1px solid #eef8ff;
+       border-bottom: 1px solid #a8d8eb;
+}
+
+/* novstripe adjustments */
+.flexigrid.novstripe .bDiv table {
+       border-bottom: 1px solid #ccc;
+       border-right: 1px solid #ccc;
+}
+
+.flexigrid.novstripe  div.bDiv td {
+       border-right-color: #fff;
+}
+
+.flexigrid.novstripe div.bDiv tr.erow td.sorted {
+       border-right-color: #e3e3e3;
+}
+
+.flexigrid.novstripe div.bDiv tr td.sorted {
+       border-right-color: #f3f3f3;
+}
+
+.flexigrid.novstripe  div.bDiv tr.erow td {
+       border-right-color: #f7f7f7;
+       border-left-color: #f7f7f7;
+}
+
+.flexigrid.novstripe div.bDiv tr.trSelected:hover td,.flexigrid.novstripe div.bDiv tr.trSelected:hover td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td,.flexigrid.novstripe tr.trSelected td.sorted,.flexigrid.novstripe tr.trSelected td
+       {
+       border-right: 1px solid #0066FF;
+       border-left: 1px solid #0066FF;
+}
+
+.flexigrid.novstripe div.bDiv tr.trOver td,.flexigrid.novstripe div.bDiv tr:hover td
+       {
+       border-left-color: #d9ebf5;
+       border-right-color: #d9ebf5;
+}
+
+/* end novstripe */
+.flexigrid div.pDiv {
+       background: url(images/wbg.gif) repeat-x 0 -1px;
+       border: 1px solid #ccc;
+       border-top: 0px;
+       overflow: hidden;
+       white-space: nowrap;
+       position: relative;
+}
+
+.flexigrid div.pDiv div.pDiv2 {
+       margin: 3px;
+       margin-left: -2px;
+       float: left;
+       width: 1024px;
+}
+
+div.pGroup {
+       float: left;
+       background: none;
+       height: 24px;
+       margin: 0px 5px;
+}
+
+.flexigrid div.pDiv .pPageStat,.flexigrid div.pDiv .pcontrol {
+       position: relative;
+       top: 5px;
+       overflow: visible;
+}
+
+.flexigrid div.pDiv input {
+       vertical-align: text-top;
+       position: relative;
+       top: -5px;
+       margin: 3px;
+}
+
+.flexigrid div.pDiv select {
+       margin: 3px;
+}
+
+.flexigrid div.pDiv  div.pButton {
+       float: left;
+       width: 22px;
+       height: 22px;
+       border: 0px;
+       cursor: pointer;
+       overflow: hidden;
+}
+
+.flexigrid div.pDiv  div.pButton:hover,.flexigrid div.pDiv  div.pButton.pBtnOver
+       {
+       width: 20px;
+       height: 20px;
+       border: 1px solid #ccc;
+       cursor: pointer;
+}
+
+.flexigrid div.pDiv  div.pButton span {
+       width: 20px;
+       height: 20px;
+       display: block;
+       float: left;
+}
+
+.flexigrid div.pDiv  div.pButton:hover span,.flexigrid div.pDiv  div.pButton.pBtnOver span
+       {
+       width: 19px;
+       height: 19px;
+       border-top: 1px solid #fff;
+       border-left: 1px solid #fff;
+}
+
+.flexigrid .pSearch {
+       background: url(images/magnifier.png) no-repeat center;
+}
+
+.flexigrid .pFirst {
+       background: url(images/first.gif) no-repeat center;
+}
+
+.flexigrid .pPrev {
+       background: url(images/prev.gif) no-repeat center;
+}
+
+.flexigrid .pNext {
+       background: url(images/next.gif) no-repeat center;
+}
+
+.flexigrid .pLast {
+       background: url(images/last.gif) no-repeat center;
+}
+
+.flexigrid .pReload {
+       background: url(images/load.png) no-repeat center;
+}
+
+.flexigrid .pReload.loading {
+       background: url(images/load.gif) no-repeat center;
+}
+
+/* ie adjustments */
+.flexigrid.ie div.hDiv th div,.flexigrid.ie  div.bDiv td  div,div.colCopy.ie div
+       /* common inner cell properties*/ {
+       overflow: hidden;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.less b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.less
new file mode 100644 (file)
index 0000000..1fc29fb
--- /dev/null
@@ -0,0 +1,671 @@
+@charset "UTF-8";
+
+@basecolor: #fff;
+@forecolor: #000;
+
+@borderlight1: #fff;
+@borderlight2: #eee;
+@borderlight3: #ddd;
+@borderlight4: #ccc;
+@borderlight5: #bbb;
+@borderlight6: #aaa;
+@borderlight7: #f7f7f7;
+@borderlight8: #f3f3f3;
+@borderlight9: #eef8ff;
+@borderlight10: #e3e3e3;
+@borderlight11: #d9ebf5;
+@borderlight12: #d2e3ec;
+@borderlight13: #a8d8eb;
+@borderlight14: #999;
+@borderlight15: #316ac5;
+@borderlight16: #0066FF;
+
+@back1: #fafafa;
+@back2: #f7f7f7;
+@back3: #f3f3f3;
+@back4: #eee;
+@back5: #e3e3e3;
+@back6: #d5effc;
+
+.background-gradient (@start: #000) {
+       background: @start;
+       background: -moz-linear-gradient(top,  @start 0%, darken(@start,10%) 100%);
+       background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,@start), color-stop(100%,darken(@start,10%)));
+       background: -webkit-linear-gradient(top,  @start 0%,darken(@start,10%) 100%);
+       background: -o-linear-gradient(top,  @start 0%,darken(@start,10%) 100%);
+       background: -ms-linear-gradient(top,  @start 0%,darken(@start,10%) 100%);
+       background: linear-gradient(to bottom,  @start 0%,darken(@start,10%) 100%);
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=@start, endColorstr=darken(@start,10%),GradientType=0 );
+}
+
+/* CSS Document */
+.flexigrid {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+       line-height: normal;
+       position: relative;
+       border: 0px solid @borderlight2;
+       overflow: hidden;
+       color: @forecolor;
+}
+
+.flexigrid.hideBody {
+       height: 26px !important;
+       border-bottom: 1px solid @borderlight4;
+}
+
+.ie6fullwidthbug {
+       border-right: 0px solid @borderlight4;
+       padding-right: 2px;
+}
+
+.flexigrid div.nDiv {
+       background: @back4 url(images/line.gif) repeat-y -1px top;
+       border: 1px solid @borderlight4;
+       border-top: 0px;
+       overflow: auto;
+       left: 0px;
+       position: absolute;
+       z-index: 999;
+       float: left;
+}
+
+.flexigrid div.nDiv table {
+       margin: 2px;
+}
+
+.flexigrid div.hDivBox {
+       float: left;
+       padding-right: 40px;
+}
+
+.flexigrid div.bDiv table {
+       margin-bottom: 10px;
+}
+
+.flexigrid div.bDiv table.autoht {
+       border-bottom: 0px;
+       margin-bottom: 0px;
+}
+
+.flexigrid div.nDiv td {
+       padding: 2px 3px;
+       border: 1px solid @borderlight2;
+       cursor: default;
+}
+
+.flexigrid div.nDiv tr:hover td,.flexigrid div.nDiv tr.ndcolover td {
+       background: @back6 url(images/hl.png) repeat-x top;
+       border: 1px solid @borderlight13;
+}
+
+.flexigrid div.nDiv td.ndcol1 {
+       border-right: 1px solid @borderlight4;
+}
+
+.flexigrid div.nDiv td.ndcol2 {
+       border-left: 1px solid @borderlight1;
+       padding-right: 10px;
+}
+
+.flexigrid div.nDiv tr:hover td.ndcol1,.flexigrid div.nDiv tr.ndcolover td.ndcol1
+       {
+       border-right: 1px solid @borderlight12;
+}
+
+.flexigrid div.nDiv tr:hover td.ndcol2,.flexigrid div.nDiv tr.ndcolover td.ndcol2
+       {
+       border-left: 1px solid @borderlight9;
+}
+
+.flexigrid div.nBtn {
+       position: absolute;
+       height: 24px;
+       width: 14px;
+       z-index: 900;
+       background: @back1 url(images/fhbg.gif) repeat-x bottom;
+       /*.background-gradient(@back1);*/
+       border: 0px solid @borderlight4;
+       border-left: 1px solid @borderlight4;
+       top: 0px;
+       left: 0px;
+       margin-top: 1px;
+       cursor: pointer;
+       display: none;
+}
+
+.flexigrid div.nBtn div {
+       height: 24px;
+       width: 12px;
+       border-left: 1px solid @borderlight1;
+       float: left;
+       background: url(images/ddn.png) no-repeat center;
+}
+
+.flexigrid div.nBtn.srtd {
+       background: url(images/wbg.gif) repeat-x 0px -1px;
+}
+
+.flexigrid div.mDiv {
+       background: url(images/wbg.gif) repeat-x top;
+       border: 1px solid @borderlight4;
+       border-bottom: 0px;
+       border-top: 0px;
+       font-weight: bold;
+       display: block;
+       overflow: hidden;
+       white-space: nowrap;
+       position: relative;
+}
+
+.flexigrid div.mDiv div {
+       padding: 6px;
+       white-space: nowrap;
+}
+
+.flexigrid div.mDiv div.ptogtitle {
+       position: absolute;
+       top: 4px;
+       right: 3px;
+       padding: 0px;
+       height: 16px;
+       width: 16px;
+       overflow: hidden;
+       border: 1px solid @borderlight4;
+       cursor: pointer;
+}
+
+.flexigrid div.mDiv div.ptogtitle:hover {
+       background-position: left -2px;
+       border-color: @borderlight5;
+}
+
+.flexigrid div.mDiv div.ptogtitle span {
+       display: block;
+       border-left: 1px solid @borderlight2;
+       border-top: 1px solid @borderlight1;
+       border-bottom: 1px solid @borderlight3;
+       width: 14px;
+       height: 14px;
+       background: url(images/uup.png) no-repeat center;
+}
+
+.flexigrid div.mDiv div.ptogtitle.vsble span {
+       background: url(images/ddn.png) no-repeat center;
+}
+
+.flexigrid div.tDiv /*toolbar*/ {
+       background: @back1 url(images/bg.gif) repeat-x top;
+       position: relative;
+       border: 1px solid @borderlight4;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.tDiv2 {
+       float: left;
+       clear: both;
+       padding: 1px;
+}
+
+.flexigrid div.sDiv /*toolbar*/ {
+       background: @back1 url(images/bg.gif) repeat-x top;
+       position: relative;
+       border: 1px solid @borderlight4;
+       border-top: 0px;
+       overflow: hidden;
+       display: none;
+}
+
+.flexigrid div.sDiv2 {
+       float: left;
+       clear: both;
+       padding: 5px;
+       padding-left: 5px;
+       width: 1024px;
+}
+
+.flexigrid div.sDiv2 input,.flexigrid div.sDiv2 select {
+       vertical-align: middle;
+}
+
+.flexigrid div.btnseparator {
+       float: left;
+       height: 22px;
+       border-left: 1px solid @borderlight4;
+       border-right: 1px solid @borderlight1;
+       margin: 1px;
+}
+
+.flexigrid div.fbutton {
+       float: left;
+       display: block;
+       cursor: pointer;
+       padding: 1px;
+}
+
+.flexigrid div.fbutton div {
+       float: left;
+       padding: 1px 3px;
+}
+
+.flexigrid div.fbutton span {
+       float: left;
+       display: block;
+       padding: 3px;
+}
+
+.flexigrid div.fbutton:hover,.flexigrid div.fbutton.fbOver {
+       padding: 0px;
+       border: 1px solid @borderlight4;
+}
+
+.flexigrid div.fbutton:hover div,.flexigrid div.fbutton.fbOver div {
+       padding: 0px 2px;
+       border-left: 1px solid @borderlight1;
+       border-top: 1px solid @borderlight1;
+       border-right: 1px solid @borderlight2;
+       border-bottom: 1px solid @borderlight2;
+}
+
+/* end toolbar*/
+.flexigrid div.hDiv {
+       background: @back1 url(images/fhbg.gif) repeat-x bottom;
+       /*.background-gradient(@back1);*/
+       position: relative;
+       border: 1px solid @borderlight4;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.hDiv table {
+       border-right: 1px solid @borderlight1;
+}
+
+.flexigrid div.cDrag {
+       float: left;
+       position: absolute;
+       z-index: 2;
+       overflow: visible;
+}
+
+.flexigrid div.cDrag div {
+       float: left;
+       background: none;
+       display: block;
+       position: absolute;
+       height: 24px;
+       width: 5px;
+       cursor: col-resize;
+}
+
+.flexigrid div.cDrag div:hover,.flexigrid div.cDrag div.dragging {
+       background: url(images/line.gif) repeat-y 2px center;
+}
+
+.flexigrid div.iDiv {
+       border: 1px solid @borderlight15;
+       position: absolute;
+       overflow: visible;
+       background: none;
+}
+
+.flexigrid div.iDiv input,.flexigrid div.iDiv select,.flexigrid div.iDiv textarea
+       {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+}
+
+.flexigrid div.iDiv input.tb {
+       border: 0px;
+       padding: 0px;
+       width: 100%;
+       height: 100%;
+       padding: 0px;
+       background: none;
+}
+
+.flexigrid div.bDiv {
+       border: 1px solid @borderlight4;
+       border-top: 0px;
+       background: @basecolor;
+       overflow: auto;
+       position: relative;
+}
+
+.flexigrid div.bDiv table {
+       border-bottom: 1px solid @borderlight4;
+}
+
+.flexigrid div.hGrip {
+       position: absolute;
+       top: 0px;
+       right: 0px;
+       height: 5px;
+       width: 5px;
+       background: url(images/line.gif) repeat-x center;
+       margin-right: 1px;
+       cursor: col-resize;
+}
+
+.flexigrid div.hGrip:hover,.flexigrid div.hGrip.hgOver {
+       border-right: 1px solid @borderlight14;
+       margin-right: 0px;
+}
+
+.flexigrid div.vGrip {
+       height: 5px;
+       overflow: hidden;
+       position: relative;
+       background: @back1 url(images/wbg.gif) repeat-x 0px -1px;
+       border: 1px solid @borderlight4;
+       border-top: 0px;
+       text-align: center;
+       cursor: row-resize;
+}
+
+.flexigrid div.vGrip span {
+       display: block;
+       margin: 1px auto;
+       width: 20px;
+       height: 1px;
+       overflow: hidden;
+       border-top: 1px solid @borderlight6;
+       border-bottom: 1px solid @borderlight6;
+       background: none;
+}
+
+.flexigrid div.hDiv th,.flexigrid  div.bDiv td
+       /* common cell properties*/ {
+       text-align: left;
+       border-right: 1px solid @borderlight3;
+       border-left: 1px solid @borderlight1;
+       overflow: hidden;
+       vertical-align: top !important;
+       padding-left: 0;
+       padding-right: 0;
+}
+
+.flexigrid div.hDiv th div,.flexigrid  div.bDiv td  div,div.colCopy div
+       /* common inner cell properties*/ {
+       padding: 5px;
+       border-left: 0px solid @borderlight1;
+}
+
+.flexigrid div.hDiv th,div.colCopy {
+       font-weight: normal;
+       height: 24px;
+       cursor: default;
+       white-space: nowrap;
+       overflow: hidden;
+}
+
+div.colCopy {
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 11px;
+       background: @back1 url(images/fhbg.gif) repeat-x bottom;
+       /*.background-gradient(@back1);*/
+       border: 1px solid @borderlight4;
+       border-bottom: 0px;
+       overflow: hidden;
+}
+
+.flexigrid div.hDiv th.sorted {
+       background: url(images/wbg.gif) repeat-x 0px -1px;
+       border-bottom: 0px solid @borderlight4;
+}
+
+.flexigrid div.hDiv th.thOver {
+       
+}
+
+.flexigrid div.hDiv th.thOver div,.flexigrid div.hDiv th.sorted.thOver div
+       {
+       border-bottom: 1px solid orange;
+       padding-bottom: 4px;
+}
+
+.flexigrid div.hDiv th.sorted div {
+       border-bottom: 0px solid @borderlight4;
+       padding-bottom: 5px;
+}
+
+.flexigrid div.hDiv th.thMove {
+       background: @basecolor;
+       color: @basecolor;
+}
+
+.flexigrid div.hDiv th.sorted.thMove div {
+       border-bottom: 1px solid @borderlight1;
+       padding-bottom: 4px
+}
+
+.flexigrid div.hDiv th.thMove div {
+       background: @basecolor !important;
+}
+
+.flexigrid div.hDiv th div.sdesc {
+       background: url(images/dn.png) no-repeat center top;
+}
+
+.flexigrid div.hDiv th div.sasc {
+       background: url(images/up.png) no-repeat center top;
+}
+
+.flexigrid div.bDiv td {
+       border-bottom: 1px solid @borderlight1;
+       vertical-align: top;
+       white-space: nowrap;
+}
+
+.flexigrid div.hDiv th div {
+       
+}
+
+.flexigrid span.cdropleft {
+       display: block;
+       background: url(images/prev.gif) no-repeat -4px center;
+       width: 24px;
+       height: 24px;
+       position: relative;
+       top: -24px;
+       margin-bottom: -24px;
+       z-index: 3;
+}
+
+.flexigrid div.hDiv span.cdropright {
+       display: block;
+       background: url(images/next.gif) no-repeat 12px center;
+       width: 24px;
+       height: 24px;
+       float: right;
+       position: relative;
+       top: -24px;
+       margin-bottom: -24px;
+}
+
+.flexigrid div.bDiv td div {
+       border-top: 0px solid @borderlight1;
+       padding-bottom: 4px;
+}
+
+.flexigrid tr td.sorted {
+       background: @back3;
+       border-right: 1px solid @borderlight3;
+       border-bottom: 1px solid @borderlight8;
+}
+
+.flexigrid tr td.sorted div {
+       
+}
+
+.flexigrid tr.erow td {
+       background: @back2;
+       border-bottom: 1px solid @borderlight7;
+}
+
+.flexigrid tr.erow td.sorted {
+       background: @back5;
+       border-bottom: 1px solid @borderlight10;
+}
+
+.flexigrid tr.erow td.sorted div {
+       
+}
+
+.flexigrid div.bDiv tr:hover td,.flexigrid div.bDiv tr:hover td.sorted,.flexigrid div.bDiv tr.trOver td.sorted,.flexigrid div.bDiv tr.trOver td
+       {
+       background: @borderlight11;
+       border-left: 1px solid @borderlight9;
+       border-bottom: 1px dotted @borderlight13;
+}
+
+.flexigrid div.bDiv tr.trSelected:hover td,.flexigrid div.bDiv tr.trSelected:hover td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td,.flexigrid tr.trSelected td.sorted,.flexigrid tr.trSelected td
+       {
+       background: @back6 url(images/hl.png) repeat-x top;
+       border-right: 1px solid @borderlight12;
+       border-left: 1px solid @borderlight9;
+       border-bottom: 1px solid @borderlight13;
+}
+
+/* novstripe adjustments */
+.flexigrid.novstripe .bDiv table {
+       border-bottom: 1px solid @borderlight4;
+       border-right: 1px solid @borderlight4;
+}
+
+.flexigrid.novstripe  div.bDiv td {
+       border-right-color: @borderlight1;
+}
+
+.flexigrid.novstripe div.bDiv tr.erow td.sorted {
+       border-right-color: @borderlight10;
+}
+
+.flexigrid.novstripe div.bDiv tr td.sorted {
+       border-right-color: @borderlight8;
+}
+
+.flexigrid.novstripe  div.bDiv tr.erow td {
+       border-right-color: @borderlight7;
+       border-left-color: @borderlight7;
+}
+
+.flexigrid.novstripe div.bDiv tr.trSelected:hover td,.flexigrid.novstripe div.bDiv tr.trSelected:hover td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td,.flexigrid.novstripe tr.trSelected td.sorted,.flexigrid.novstripe tr.trSelected td
+       {
+       border-right: 1px solid @borderlight16;
+       border-left: 1px solid @borderlight16;
+}
+
+.flexigrid.novstripe div.bDiv tr.trOver td,.flexigrid.novstripe div.bDiv tr:hover td
+       {
+       border-left-color: @borderlight11;
+       border-right-color: @borderlight11;
+}
+
+/* end novstripe */
+.flexigrid div.pDiv {
+       background: url(images/wbg.gif) repeat-x 0 -1px;
+       border: 1px solid @borderlight4;
+       border-top: 0px;
+       overflow: hidden;
+       white-space: nowrap;
+       position: relative;
+}
+
+.flexigrid div.pDiv div.pDiv2 {
+       margin: 3px;
+       margin-left: -2px;
+       float: left;
+       width: 1024px;
+}
+
+div.pGroup {
+       float: left;
+       background: none;
+       height: 24px;
+       margin: 0px 5px;
+}
+
+.flexigrid div.pDiv .pPageStat,.flexigrid div.pDiv .pcontrol {
+       position: relative;
+       top: 5px;
+       overflow: visible;
+}
+
+.flexigrid div.pDiv input {
+       vertical-align: text-top;
+       position: relative;
+       top: -5px;
+       margin: 3px;
+}
+
+.flexigrid div.pDiv select {
+       margin: 3px;
+}
+
+.flexigrid div.pDiv  div.pButton {
+       float: left;
+       width: 22px;
+       height: 22px;
+       border: 0px;
+       cursor: pointer;
+       overflow: hidden;
+}
+
+.flexigrid div.pDiv  div.pButton:hover,.flexigrid div.pDiv  div.pButton.pBtnOver
+       {
+       width: 20px;
+       height: 20px;
+       border: 1px solid @borderlight4;
+       cursor: pointer;
+}
+
+.flexigrid div.pDiv  div.pButton span {
+       width: 20px;
+       height: 20px;
+       display: block;
+       float: left;
+}
+
+.flexigrid div.pDiv  div.pButton:hover span,.flexigrid div.pDiv  div.pButton.pBtnOver span
+       {
+       width: 19px;
+       height: 19px;
+       border-top: 1px solid @borderlight1;
+       border-left: 1px solid @borderlight1;
+}
+
+.flexigrid .pSearch {
+       background: url(images/magnifier.png) no-repeat center;
+}
+
+.flexigrid .pFirst {
+       background: url(images/first.gif) no-repeat center;
+}
+
+.flexigrid .pPrev {
+       background: url(images/prev.gif) no-repeat center;
+}
+
+.flexigrid .pNext {
+       background: url(images/next.gif) no-repeat center;
+}
+
+.flexigrid .pLast {
+       background: url(images/last.gif) no-repeat center;
+}
+
+.flexigrid .pReload {
+       background: url(images/load.png) no-repeat center;
+}
+
+.flexigrid .pReload.loading {
+       background: url(images/load.gif) no-repeat center;
+}
+
+/* ie adjustments */
+.flexigrid.ie div.hDiv th div,.flexigrid.ie  div.bDiv td  div,div.colCopy.ie div
+       /* common inner cell properties*/ {
+       overflow: hidden;
+}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.pack.css b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/flexigrid.pack.css
new file mode 100644 (file)
index 0000000..cd79960
--- /dev/null
@@ -0,0 +1,96 @@
+@charset UTF-8;
+.flexigrid{font-family:Arial, Helvetica, sans-serif;font-size:11px;position:relative;border:0 solid #eee;overflow:hidden;color:#000}
+.flexigrid.hideBody{height:26px!important;border-bottom:1px solid #ccc}
+.ie6fullwidthbug{border-right:0 solid #ccc;padding-right:2px}
+.flexigrid div.nDiv{background:#eee url(images/line.gif) repeat-y -1px top;border:1px solid #ccc;border-top:0;overflow:auto;left:0;position:absolute;z-index:999;float:left}
+.flexigrid div.nDiv table{margin:2px}
+.flexigrid div.hDivBox{float:left;padding-right:40px}
+.flexigrid div.bDiv table{margin-bottom:10px;border-bottom:1px solid #ccc}
+.flexigrid div.bDiv table.autoht{border-bottom:0;margin-bottom:0}
+.flexigrid div.nDiv td{border:1px solid #eee;cursor:default;padding:2px 3px}
+.flexigrid div.nDiv tr:hover td,.flexigrid div.nDiv tr.ndcolover td{background:#d5effc url(images/hl.png) repeat-x top;border:1px solid #a8d8eb}
+.flexigrid div.nDiv td.ndcol1{border-right:1px solid #ccc}
+.flexigrid div.nDiv td.ndcol2{border-left:1px solid #fff;padding-right:10px}
+.flexigrid div.nDiv tr:hover td.ndcol1,.flexigrid div.nDiv tr.ndcolover td.ndcol1{border-right:1px solid #d2e3ec}
+.flexigrid div.nDiv tr:hover td.ndcol2,.flexigrid div.nDiv tr.ndcolover td.ndcol2{border-left:1px solid #eef8ff}
+.flexigrid div.nBtn{position:absolute;height:24px;width:14px;z-index:900;background:#fafafa url(images/fhbg.gif) repeat-x bottom;border:0 solid #ccc;border-left:1px solid #ccc;top:0;left:0;margin-top:1px;cursor:pointer;display:none}
+.flexigrid div.nBtn div{height:24px;width:12px;border-left:1px solid #fff;float:left;background:url(images/ddn.png) no-repeat center}
+.flexigrid div.nBtn.srtd{background:url(images/wbg.gif) repeat-x 0 -1px}
+.flexigrid div.mDiv{background:url(images/wbg.gif) repeat-x top;border:1px solid #ccc;border-bottom:0;border-top:0;font-weight:700;display:block;overflow:hidden;white-space:nowrap;position:relative}
+.flexigrid div.mDiv div{white-space:nowrap;padding:6px}
+.flexigrid div.mDiv div.ptogtitle{position:absolute;top:4px;right:3px;height:16px;width:16px;overflow:hidden;border:1px solid #ccc;cursor:pointer;padding:0}
+.flexigrid div.mDiv div.ptogtitle:hover{background-position:left -2px;border-color:#bbb}
+.flexigrid div.mDiv div.ptogtitle span{display:block;border-left:1px solid #eee;border-top:1px solid #fff;border-bottom:1px solid #ddd;width:14px;height:14px;background:url(images/uup.png) no-repeat center}
+.flexigrid div.mDiv div.ptogtitle.vsble span{background:url(images/ddn.png) no-repeat center}
+.flexigrid div.tDiv /*toolbar*/{background:#fafafa url(images/bg.gif) repeat-x top;position:relative;border:1px solid #ccc;border-bottom:0;overflow:hidden}
+.flexigrid div.tDiv2{float:left;clear:both;padding:1px}
+.flexigrid div.sDiv /*toolbar*/{background:#fafafa url(images/bg.gif) repeat-x top;position:relative;border:1px solid #ccc;border-top:0;overflow:hidden;display:none}
+.flexigrid div.sDiv2{float:left;clear:both;width:1024px;padding:5px}
+.flexigrid div.sDiv2 input,.flexigrid div.sDiv2 select{vertical-align:middle}
+.flexigrid div.btnseparator{float:left;height:22px;border-left:1px solid #ccc;border-right:1px solid #fff;margin:1px}
+.flexigrid div.fbutton{float:left;display:block;cursor:pointer;padding:1px}
+.flexigrid div.fbutton div{float:left;padding:1px 3px}
+.flexigrid div.fbutton span{float:left;display:block;padding:3px}
+.flexigrid div.fbutton:hover,.flexigrid div.fbutton.fbOver{border:1px solid #ccc;padding:0}
+.flexigrid div.fbutton:hover div,.flexigrid div.fbutton.fbOver div{border-left:1px solid #fff;border-top:1px solid #fff;border-right:1px solid #eee;border-bottom:1px solid #eee;padding:0 2px}
+.flexigrid div.hDiv{background:#fafafa url(images/fhbg.gif) repeat-x bottom;position:relative;border:1px solid #ccc;border-bottom:0;overflow:hidden}
+.flexigrid div.hDiv table{border-right:1px solid #fff}
+.flexigrid div.cDrag{float:left;position:absolute;z-index:2;overflow:visible}
+.flexigrid div.cDrag div{float:left;background:none;display:block;position:absolute;height:24px;width:5px;cursor:col-resize}
+.flexigrid div.cDrag div:hover,.flexigrid div.cDrag div.dragging{background:url(images/line.gif) repeat-y 2px center}
+.flexigrid div.iDiv{border:1px solid #316ac5;position:absolute;overflow:visible;background:none}
+.flexigrid div.iDiv input,.flexigrid div.iDiv select,.flexigrid div.iDiv textarea{font-family:Arial, Helvetica, sans-serif;font-size:11px}
+.flexigrid div.iDiv input.tb{border:0;width:100%;height:100%;background:none;padding:0}
+.flexigrid div.bDiv{border:1px solid #ccc;border-top:0;background:#fff;overflow:auto;position:relative}
+.flexigrid div.hGrip{position:absolute;top:0;right:0;height:5px;width:5px;background:url(images/line.gif) repeat-x center;margin-right:1px;cursor:col-resize}
+.flexigrid div.hGrip:hover,.flexigrid div.hGrip.hgOver{border-right:1px solid #999;margin-right:0}
+.flexigrid div.vGrip{height:5px;overflow:hidden;position:relative;background:#fafafa url(images/wbg.gif) repeat-x 0 -1px;border:1px solid #ccc;border-top:0;text-align:center;cursor:row-resize}
+.flexigrid div.vGrip span{display:block;width:20px;height:1px;overflow:hidden;border-top:1px solid #aaa;border-bottom:1px solid #aaa;background:none;margin:1px auto}
+.flexigrid div.hDiv th,.flexigrid div.bDiv td
+/* common cell properties*/{text-align:left;border-right:1px solid #ddd;border-left:1px solid #fff;overflow:hidden;vertical-align:top!important;padding-left:0;padding-right:0}
+.flexigrid div.hDiv th div,.flexigrid div.bDiv td div,div.colCopy div
+/* common inner cell properties*/{border-left:0 solid #fff;padding:5px}
+.flexigrid div.hDiv th,div.colCopy{font-weight:400;height:24px;cursor:default;white-space:nowrap;overflow:hidden}
+div.colCopy{font-family:Arial, Helvetica, sans-serif;font-size:11px;background:#fafafa url(images/fhbg.gif) repeat-x bottom;border:1px solid #ccc;border-bottom:0;overflow:hidden}
+.flexigrid div.hDiv th.sorted{background:url(images/wbg.gif) repeat-x 0 -1px;border-bottom:0 solid #ccc}
+.flexigrid div.hDiv th.thOver div,.flexigrid div.hDiv th.sorted.thOver div{border-bottom:1px solid orange;padding-bottom:4px}
+.flexigrid div.hDiv th.sorted div{border-bottom:0 solid #ccc;padding-bottom:5px}
+.flexigrid div.hDiv th.thMove{background:#fff;color:#fff}
+.flexigrid div.hDiv th.sorted.thMove div{border-bottom:1px solid #fff;padding-bottom:4px}
+.flexigrid div.hDiv th.thMove div{background:#fff!important}
+.flexigrid div.hDiv th div.sdesc{background:url(images/dn.png) no-repeat center top}
+.flexigrid div.hDiv th div.sasc{background:url(images/up.png) no-repeat center top}
+.flexigrid div.bDiv td{border-bottom:1px solid #fff;vertical-align:top;white-space:nowrap}
+.flexigrid span.cdropleft{display:block;background:url(images/prev.gif) no-repeat -4px center;width:24px;height:24px;position:relative;top:-24px;margin-bottom:-24px;z-index:3}
+.flexigrid div.hDiv span.cdropright{display:block;background:url(images/next.gif) no-repeat 12px center;width:24px;height:24px;float:right;position:relative;top:-24px;margin-bottom:-24px}
+.flexigrid div.bDiv td div{border-top:0 solid #fff;padding-bottom:4px}
+.flexigrid tr td.sorted{background:#f3f3f3;border-right:1px solid #ddd;border-bottom:1px solid #f3f3f3}
+.flexigrid tr.erow td{background:#f7f7f7;border-bottom:1px solid #f7f7f7}
+.flexigrid tr.erow td.sorted{background:#e3e3e3;border-bottom:1px solid #e3e3e3}
+.flexigrid div.bDiv tr:hover td,.flexigrid div.bDiv tr:hover td.sorted,.flexigrid div.bDiv tr.trOver td.sorted,.flexigrid div.bDiv tr.trOver td{background:#d9ebf5;border-left:1px solid #eef8ff;border-bottom:1px dotted #a8d8eb}
+.flexigrid div.bDiv tr.trSelected:hover td,.flexigrid div.bDiv tr.trSelected:hover td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td.sorted,.flexigrid div.bDiv tr.trOver.trSelected td,.flexigrid tr.trSelected td.sorted,.flexigrid tr.trSelected td{background:#d5effc url(images/hl.png) repeat-x top;border-right:1px solid #d2e3ec;border-left:1px solid #eef8ff;border-bottom:1px solid #a8d8eb}
+.flexigrid.novstripe .bDiv table{border-bottom:1px solid #ccc;border-right:1px solid #ccc}
+.flexigrid.novstripe div.bDiv td{border-right-color:#fff}
+.flexigrid.novstripe div.bDiv tr.erow td.sorted{border-right-color:#e3e3e3}
+.flexigrid.novstripe div.bDiv tr td.sorted{border-right-color:#f3f3f3}
+.flexigrid.novstripe div.bDiv tr.erow td{border-right-color:#f7f7f7;border-left-color:#f7f7f7}
+.flexigrid.novstripe div.bDiv tr.trSelected:hover td,.flexigrid.novstripe div.bDiv tr.trSelected:hover td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td.sorted,.flexigrid.novstripe div.bDiv tr.trOver.trSelected td,.flexigrid.novstripe tr.trSelected td.sorted,.flexigrid.novstripe tr.trSelected td{border-right:1px solid #06F;border-left:1px solid #06F}
+.flexigrid.novstripe div.bDiv tr.trOver td,.flexigrid.novstripe div.bDiv tr:hover td{border-left-color:#d9ebf5;border-right-color:#d9ebf5}
+.flexigrid div.pDiv{background:url(images/wbg.gif) repeat-x 0 -1px;border:1px solid #ccc;border-top:0;overflow:hidden;white-space:nowrap;position:relative}
+.flexigrid div.pDiv div.pDiv2{float:left;width:1024px;margin:3px 3px 3px -2px}
+div.pGroup{float:left;background:none;height:24px;margin:0 5px}
+.flexigrid div.pDiv .pPageStat,.flexigrid div.pDiv .pcontrol{position:relative;top:5px;overflow:visible}
+.flexigrid div.pDiv input{vertical-align:text-top;position:relative;top:-5px}
+.flexigrid div.pDiv div.pButton{float:left;width:22px;height:22px;border:0;cursor:pointer;overflow:hidden}
+.flexigrid div.pDiv div.pButton:hover,.flexigrid div.pDiv div.pButton.pBtnOver{width:20px;height:20px;border:1px solid #ccc;cursor:pointer}
+.flexigrid div.pDiv div.pButton span{width:20px;height:20px;display:block;float:left}
+.flexigrid div.pDiv div.pButton:hover span,.flexigrid div.pDiv div.pButton.pBtnOver span{width:19px;height:19px;border-top:1px solid #fff;border-left:1px solid #fff}
+.flexigrid .pSearch{background:url(images/magnifier.png) no-repeat center}
+.flexigrid .pFirst{background:url(images/first.gif) no-repeat center}
+.flexigrid .pPrev{background:url(images/prev.gif) no-repeat center}
+.flexigrid .pNext{background:url(images/next.gif) no-repeat center}
+.flexigrid .pLast{background:url(images/last.gif) no-repeat center}
+.flexigrid .pReload{background:url(images/load.png) no-repeat center}
+.flexigrid .pReload.loading{background:url(images/load.gif) no-repeat center}
+.flexigrid.ie div.hDiv th div,.flexigrid.ie div.bDiv td div,div.colCopy.ie div
+/* common inner cell properties*/{overflow:hidden}
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/bg.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/bg.gif
new file mode 100644 (file)
index 0000000..9ab78a2
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/bg.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/btn-sprite.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/btn-sprite.gif
new file mode 100644 (file)
index 0000000..e827ba3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/btn-sprite.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/ddn.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/ddn.png
new file mode 100644 (file)
index 0000000..2178f11
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/ddn.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/dn.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/dn.png
new file mode 100644 (file)
index 0000000..a19083b
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/dn.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/fhbg.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/fhbg.gif
new file mode 100644 (file)
index 0000000..8d459a3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/fhbg.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/first.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/first.gif
new file mode 100644 (file)
index 0000000..7623e73
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/first.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/hl.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/hl.png
new file mode 100644 (file)
index 0000000..6248e45
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/hl.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/last.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/last.gif
new file mode 100644 (file)
index 0000000..61483e9
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/last.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/line.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/line.gif
new file mode 100644 (file)
index 0000000..c76a16e
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/line.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.gif
new file mode 100644 (file)
index 0000000..68f01d0
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.png
new file mode 100644 (file)
index 0000000..d65defb
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/load.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/magnifier.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/magnifier.png
new file mode 100644 (file)
index 0000000..cf3d97f
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/magnifier.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/next.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/next.gif
new file mode 100644 (file)
index 0000000..2cd62cc
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/next.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/prev.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/prev.gif
new file mode 100644 (file)
index 0000000..b440a29
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/prev.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/up.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/up.png
new file mode 100644 (file)
index 0000000..000c065
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/up.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/uup.png b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/uup.png
new file mode 100644 (file)
index 0000000..660db63
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/uup.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/wbg.gif b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/wbg.gif
new file mode 100644 (file)
index 0000000..8046089
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/images/wbg.gif differ
diff --git a/src/main/resources/META-INF/resources/designer/css/flexigrid/css/style.css b/src/main/resources/META-INF/resources/designer/css/flexigrid/css/style.css
new file mode 100644 (file)
index 0000000..53a941c
--- /dev/null
@@ -0,0 +1,164 @@
+@charset "utf-8";
+/* http://meyerweb.com/eric/tools/css/reset/ 
+   v2.0 | 20110126
+   License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       font-size: 100%;
+       font: inherit;
+       vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure, 
+footer, header, hgroup, menu, nav, section {
+       display: block;
+}
+body {
+       line-height: 1;
+}
+ol, ul {
+       list-style: none;
+}
+blockquote, q {
+       quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+       content: '';
+       content: none;
+}
+table {
+       border-collapse: collapse;
+       border-spacing: 0;
+}
+
+/* CSS Document */
+body {
+       background: #333;
+       width: 960px;
+       margin: 0px;
+       padding: 20px;
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 12px;
+       color: #eee;
+}
+
+ul li {
+       background: url(images/accept.png) no-repeat left;
+       list-style: none;
+       padding: 3px 3px 3px 20px;
+       margin-left:10px;
+}
+
+ul, ol {
+       margin-bottom:10px;
+}
+ol li {
+       list-style: none;
+       padding: 10px 10px 5px;
+}
+ol li div.question {
+       font-weight:bold;
+       color:#ccc;
+       margin-bottom:2px;
+}
+
+a {
+       text-decoration: none;
+       color: #0066FF;
+}
+
+h1 {
+       font-size: 26px;
+       font-weight: normal;
+       margin: 0px;
+       color: #0099FF;
+}
+
+h2 {
+       font-size:15px;
+       font-weight:bold;
+       margin:15px 0 5px;      
+}
+
+.code {
+       background: #555;
+       padding: 10px;
+       margin-bottom: 10px;
+       display: none;
+       color: #eee;
+}
+
+.title {
+       background: #0099FF;
+       color: #fff;
+       padding: 10px;
+}
+
+.bborder {
+       background: #eee;
+       border: 0px solid #ccc;
+       padding: 3px;
+}
+
+.update {
+       border: 1px solid #777;
+       overflow: hidden;
+       margin-top:20px;
+}
+
+.update h3 {
+       margin:5px 0 5px 10px;
+       font-weight:bold;
+       font-size:1.1em;        
+}
+.update.fh {
+       height: auto;
+}
+
+.update p {
+       margin: 10px;
+}
+
+.update h2 {
+       cursor: pointer;
+       display: block;
+       padding: 5px;
+       color: #fff;
+       position: relative;
+       text-transform: uppercase;
+       font-size: 12px;
+       letter-spacing: 2px;
+       border-left: 0px solid #06f;
+       border-bottom: 2px solid #0066FF;
+       font-weight:bold;
+       margin:0 0 3px;
+}
+
+.flexigrid div.fbutton .add {
+       background: url(images/add.png) no-repeat center left;
+}
+
+.flexigrid div.fbutton .delete {
+    background: url(images/close.png) no-repeat center left;
+}
+
+.flexigrid div.fbutton .edit {
+       background: url(images/edit.png) no-repeat center left;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/font-awesome.min.css b/src/main/resources/META-INF/resources/designer/css/font-awesome.min.css
new file mode 100644 (file)
index 0000000..a2e4cc9
--- /dev/null
@@ -0,0 +1,4 @@
+/*!
+ *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}
diff --git a/src/main/resources/META-INF/resources/designer/css/icons.css b/src/main/resources/META-INF/resources/designer/css/icons.css
new file mode 100644 (file)
index 0000000..09daf2a
--- /dev/null
@@ -0,0 +1 @@
+@font-face {   font-family: icomoon;   src:url(../../fonts/icomoon.eot?#iefixhrr1hf) format("embedded-opentype"), url(../../fonts/icomoon.woff?hrr1hf) format("woff"), url(../../fonts/icomoon.ttf?hrr1hf) format("truetype"), url(../../fonts/icomoon.svg?hrr1hf#icomoon) format("svg");}[class^='icon-'] {   LINE-HEIGHT: 1; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; FONT-FAMILY: "icomoon"; FONT-WEIGHT: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; speak: none}[class*=' icon-'] {   LINE-HEIGHT: 1; TEXT-TRANSFORM: none; FONT-VARIANT: normal; FONT-STYLE: normal; FONT-FAMILY: "icomoon"; FONT-WEIGHT: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; speak: none}.icon-briefcase:before {      CONTENT: "\e631"}.icon-up-arrow-circled:before {        CONTENT: "\e632"}.icon-minus:before {   CONTENT: "\e62f"}.icon-plus:before {    CONTENT: "\e630"}.icon-closed-bullet:before {   CONTENT: "\e600"}.icon-design:before {  CONTENT: "\e601"}.icon-open-bullet:before {     CONTENT: "\e602"}.icon-play:before {    CONTENT: "\e603"}.icon-support:before { CONTENT: "\e604"}.icon-test:before {    CONTENT: "\e605"}.icon-page-launch:before {     CONTENT: "\e606"}.icon-alert:before {   CONTENT: "\e607"}.icon-artifacts:before {       CONTENT: "\e608"}.icon-attach:before {  CONTENT: "\e609"}.icon-bookmarks:before {       CONTENT: "\e60a"}.icon-chat:before {    CONTENT: "\e60b"}.icon-claim_slide_left:before {        CONTENT: "\e60c"}.icon-claim_slide_right:before {       CONTENT: "\e60d"}.icon-claim_slider_arrow:before {      CONTENT: "\e60e"}.icon-close:before {   CONTENT: "\e60f"}.icon-collaborate:before {     CONTENT: "\e610"}.icon-content_mapping:before { CONTENT: "\e611"}.icon-dislike:before { CONTENT: "\e612"}.icon-download_document:before {       CONTENT: "\e613"}.icon-download:before {        CONTENT: "\e614"}.icon-favorite:before {        CONTENT: "\e615"}.icon-file:before {    CONTENT: "\e616"}.icon-instructions:before {    CONTENT: "\e617"}.icon-launch:before {  CONTENT: "\e618"}.icon-like:before {    CONTENT: "\e619"}.icon-notification:before {    CONTENT: "\e61a"}.icon-pop-outpage:before {     CONTENT: "\e61b"}.icon-profile:before { CONTENT: "\e61c"}.icon-reference_guides:before {        CONTENT: "\e61d"}.icon-reporting:before {       CONTENT: "\e61e"}.icon-reusable_components:before {     CONTENT: "\e61f"}.icon-search:before {  CONTENT: "\e620"}.icon-team_chat2:before {      CONTENT: "\e621"}.icon-tools:before {   CONTENT: "\e622"}.icon-training:before {        CONTENT: "\e623"}.icon-tTerms:before {  CONTENT: "\e624"}.icon-pop-outpage2:before {    CONTENT: "\e625"}.icon-profile2:before {        CONTENT: "\e626"}.icon-reference_guides2:before {       CONTENT: "\e627"}.icon-reporting2:before {      CONTENT: "\e628"}.icon-reusable_components2:before {    CONTENT: "\e629"}.icon-search2:before { CONTENT: "\e62a"}.icon-team_chat22:before {     CONTENT: "\e62b"}.icon-tools2:before {  CONTENT: "\e62c"}.icon-training2:before {       CONTENT: "\e62d"}.icon-tTerms2:before { CONTENT: "\e62e"}
diff --git a/src/main/resources/META-INF/resources/designer/css/images/sprite.png b/src/main/resources/META-INF/resources/designer/css/images/sprite.png
new file mode 100644 (file)
index 0000000..6aafd99
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/images/sprite.png differ
diff --git a/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css b/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css
new file mode 100644 (file)
index 0000000..e44b43e
--- /dev/null
@@ -0,0 +1,621 @@
+/*!
+ * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
+ * Copyright 2012-2014 Arnold Daniels
+ * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
+ */
+
+.container-smooth {
+  max-width: 1170px;
+}
+@media (min-width: 1px) {
+  .container-smooth {
+    width: auto;
+  }
+}
+.btn-labeled {
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.btn-label {
+  position: relative;
+  left: -12px;
+  display: inline-block;
+  padding: 6px 12px;
+  background: transparent;
+  background: rgba(0, 0, 0, .15);
+  border-radius: 3px 0 0 3px;
+}
+.btn-label.btn-label-right {
+  right: -12px;
+  left: auto;
+  border-radius: 0 3px 3px 0;
+}
+.btn-lg .btn-label {
+  left: -16px;
+  padding: 10px 16px;
+  border-radius: 5px 0 0 5px;
+}
+.btn-lg .btn-label.btn-label-right {
+  right: -16px;
+  left: auto;
+  border-radius: 0 5px 5px 0;
+}
+.btn-sm .btn-label {
+  left: -10px;
+  padding: 5px 10px;
+  border-radius: 2px 0 0 2px;
+}
+.btn-sm .btn-label.btn-label-right {
+  right: -10px;
+  left: auto;
+  border-radius: 0 2px 2px 0;
+}
+.btn-xs .btn-label {
+  left: -5px;
+  padding: 1px 5px;
+  border-radius: 2px 0 0 2px;
+}
+.btn-xs .btn-label.btn-label-right {
+  right: -5px;
+  left: auto;
+  border-radius: 0 2px 2px 0;
+}
+.nav-tabs-bottom {
+  border-top: 1px solid #ddd;
+  border-bottom: 0;
+}
+.nav-tabs-bottom > li {
+  margin-top: -1px;
+  margin-bottom: 0;
+}
+.nav-tabs-bottom > li > a {
+  border-radius: 0 0 4px 4px;
+}
+.nav-tabs-bottom > li > a:hover,
+.nav-tabs-bottom > li > a:focus,
+.nav-tabs-bottom > li.active > a,
+.nav-tabs-bottom > li.active > a:hover,
+.nav-tabs-bottom > li.active > a:focus {
+  border: 1px solid #ddd;
+  border-top-color: transparent;
+}
+.nav-tabs-left {
+  border-right: 1px solid #ddd;
+  border-bottom: 0;
+}
+.nav-tabs-left > li {
+  float: none;
+  margin-right: -1px;
+  margin-bottom: 0;
+}
+.nav-tabs-left > li > a {
+  margin-right: 0;
+  margin-bottom: 2px;
+  border-radius: 4px 0 0 4px;
+}
+.nav-tabs-left > li > a:hover,
+.nav-tabs-left > li > a:focus,
+.nav-tabs-left > li.active > a,
+.nav-tabs-left > li.active > a:hover,
+.nav-tabs-left > li.active > a:focus {
+  border: 1px solid #ddd;
+  border-right-color: transparent;
+}
+.row > .nav-tabs-left {
+  position: relative;
+  z-index: 1;
+  padding-right: 0;
+  padding-left: 15px;
+  margin-right: -1px;
+}
+.row > .nav-tabs-left + .tab-content {
+  border-left: 1px solid #ddd;
+}
+.nav-tabs-right {
+  border-bottom: 0;
+  border-left: 1px solid #ddd;
+}
+.nav-tabs-right > li {
+  float: none;
+  margin-bottom: 0;
+  margin-left: -1px;
+}
+.nav-tabs-right > li > a {
+  margin-bottom: 2px;
+  margin-left: 0;
+  border-radius: 0 4px 4px 0;
+}
+.nav-tabs-right > li > a:hover,
+.nav-tabs-right > li > a:focus,
+.nav-tabs-right > li.active > a,
+.nav-tabs-right > li.active > a:hover,
+.nav-tabs-right > li.active > a:focus {
+  border: 1px solid #ddd;
+  border-left-color: transparent;
+}
+.row > .nav-tabs-right {
+  padding-right: 15px;
+  padding-left: 0;
+}
+.navmenu,
+.navbar-offcanvas {
+  width: 300px;
+  height: auto;
+  border-style: solid;
+  border-width: 1px;
+  border-radius: 4px;
+}
+.navmenu-fixed-left,
+.navmenu-fixed-right,
+.navbar-offcanvas {
+  position: left;
+  top: 0;
+  bottom: 0;
+  z-index: 1030;
+  overflow-y: auto;
+  border-radius: 0;
+}
+.navmenu-fixed-left,
+.navbar-offcanvas.navmenu-fixed-left {
+  right: auto;
+  left: 0;
+  border-width: 0 1px 0 0;
+}
+.navmenu-fixed-right,
+.navbar-offcanvas {
+  right: 0;
+  left: auto;
+  border-width: 0 0 0 1px;
+}
+.navmenu-nav {
+  margin-bottom: 10px;
+}
+.navmenu-nav.dropdown-menu {
+  position: static;
+  float: none;
+  padding-top: 0;
+  margin: 0;
+  border: none;
+  border-radius: 0;
+  -webkit-box-shadow: none;
+          box-shadow: none;
+}
+.navbar-offcanvas .navbar-nav {
+  margin: 0;
+}
+@media (min-width: 768px) {
+  .navbar-offcanvas {
+    width: auto;
+    border-top: 0;
+    box-shadow: none;
+  }
+  .navbar-offcanvas.offcanvas {
+    position: static;
+    display: block !important;
+    height: auto !important;
+    padding-bottom: 0;
+    overflow: visible !important;
+  }
+  .navbar-offcanvas .navbar-nav.navbar-left:first-child {
+    margin-left: -15px;
+  }
+  .navbar-offcanvas .navbar-nav.navbar-right:last-child {
+    margin-right: -15px;
+  }
+  .navbar-offcanvas .navmenu-brand {
+    display: none;
+  }
+}
+.navmenu-brand {
+  display: block;
+  padding: 10px 15px;
+  margin: 10px 0;
+  font-size: 18px;
+  line-height: 20px;
+}
+.navmenu-brand:hover,
+.navmenu-brand:focus {
+  text-decoration: none;
+}
+.navmenu-default,
+.navbar-default .navbar-offcanvas {
+  background-color: #f8f8f8;
+  border-color: #e7e7e7;
+}
+.navmenu-default .navmenu-brand,
+.navbar-default .navbar-offcanvas .navmenu-brand {
+  color: #777;
+}
+.navmenu-default .navmenu-brand:hover,
+.navbar-default .navbar-offcanvas .navmenu-brand:hover,
+.navmenu-default .navmenu-brand:focus,
+.navbar-default .navbar-offcanvas .navmenu-brand:focus {
+  color: #5e5e5e;
+  background-color: transparent;
+}
+.navmenu-default .navmenu-text,
+.navbar-default .navbar-offcanvas .navmenu-text {
+  color: #777;
+}
+.navmenu-default .navmenu-nav > .dropdown > a:hover .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
+.navmenu-default .navmenu-nav > .dropdown > a:focus .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
+  border-top-color: #333;
+  border-bottom-color: #333;
+}
+.navmenu-default .navmenu-nav > .open > a,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a,
+.navmenu-default .navmenu-nav > .open > a:hover,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover,
+.navmenu-default .navmenu-nav > .open > a:focus,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+.navmenu-default .navmenu-nav > .open > a .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a .caret,
+.navmenu-default .navmenu-nav > .open > a:hover .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
+.navmenu-default .navmenu-nav > .open > a:focus .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
+  border-top-color: #555;
+  border-bottom-color: #555;
+}
+.navmenu-default .navmenu-nav > .dropdown > a .caret,
+.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
+  border-top-color: #777;
+  border-bottom-color: #777;
+}
+.navmenu-default .navmenu-nav.dropdown-menu,
+.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu {
+  background-color: #e7e7e7;
+}
+.navmenu-default .navmenu-nav.dropdown-menu > .divider,
+.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
+  background-color: #f8f8f8;
+}
+.navmenu-default .navmenu-nav.dropdown-menu > .active > a,
+.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
+.navmenu-default .navmenu-nav.dropdown-menu > .active > a:hover,
+.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
+.navmenu-default .navmenu-nav.dropdown-menu > .active > a:focus,
+.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
+  background-color: #d7d7d7;
+}
+.navmenu-default .navmenu-nav > li > a,
+.navbar-default .navbar-offcanvas .navmenu-nav > li > a {
+  color: #777;
+}
+.navmenu-default .navmenu-nav > li > a:hover,
+.navbar-default .navbar-offcanvas .navmenu-nav > li > a:hover,
+.navmenu-default .navmenu-nav > li > a:focus,
+.navbar-default .navbar-offcanvas .navmenu-nav > li > a:focus {
+  color: #333;
+  background-color: transparent;
+}
+.navmenu-default .navmenu-nav > .active > a,
+.navbar-default .navbar-offcanvas .navmenu-nav > .active > a,
+.navmenu-default .navmenu-nav > .active > a:hover,
+.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:hover,
+.navmenu-default .navmenu-nav > .active > a:focus,
+.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:focus {
+  color: #555;
+  background-color: #e7e7e7;
+}
+.navmenu-default .navmenu-nav > .disabled > a,
+.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a,
+.navmenu-default .navmenu-nav > .disabled > a:hover,
+.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
+.navmenu-default .navmenu-nav > .disabled > a:focus,
+.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
+  color: #ccc;
+  background-color: transparent;
+}
+.navmenu-inverse,
+.navbar-inverse .navbar-offcanvas {
+  background-color: #222;
+  border-color: #080808;
+}
+.navmenu-inverse .navmenu-brand,
+.navbar-inverse .navbar-offcanvas .navmenu-brand {
+  color: #999;
+}
+.navmenu-inverse .navmenu-brand:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-brand:hover,
+.navmenu-inverse .navmenu-brand:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-brand:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navmenu-inverse .navmenu-text,
+.navbar-inverse .navbar-offcanvas .navmenu-text {
+  color: #999;
+}
+.navmenu-inverse .navmenu-nav > .dropdown > a:hover .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
+.navmenu-inverse .navmenu-nav > .dropdown > a:focus .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.navmenu-inverse .navmenu-nav > .open > a,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a,
+.navmenu-inverse .navmenu-nav > .open > a:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover,
+.navmenu-inverse .navmenu-nav > .open > a:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+.navmenu-inverse .navmenu-nav > .open > a .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a .caret,
+.navmenu-inverse .navmenu-nav > .open > a:hover .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
+.navmenu-inverse .navmenu-nav > .open > a:focus .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
+  border-top-color: #fff;
+  border-bottom-color: #fff;
+}
+.navmenu-inverse .navmenu-nav > .dropdown > a .caret,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
+  border-top-color: #999;
+  border-bottom-color: #999;
+}
+.navmenu-inverse .navmenu-nav.dropdown-menu,
+.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu {
+  background-color: #080808;
+}
+.navmenu-inverse .navmenu-nav.dropdown-menu > .divider,
+.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
+  background-color: #222;
+}
+.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a,
+.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
+.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
+.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
+  background-color: #000;
+}
+.navmenu-inverse .navmenu-nav > li > a,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a {
+  color: #999;
+}
+.navmenu-inverse .navmenu-nav > li > a:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:hover,
+.navmenu-inverse .navmenu-nav > li > a:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:focus {
+  color: #fff;
+  background-color: transparent;
+}
+.navmenu-inverse .navmenu-nav > .active > a,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a,
+.navmenu-inverse .navmenu-nav > .active > a:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:hover,
+.navmenu-inverse .navmenu-nav > .active > a:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:focus {
+  color: #fff;
+  background-color: #080808;
+}
+.navmenu-inverse .navmenu-nav > .disabled > a,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a,
+.navmenu-inverse .navmenu-nav > .disabled > a:hover,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
+.navmenu-inverse .navmenu-nav > .disabled > a:focus,
+.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
+  color: #444;
+  background-color: transparent;
+}
+.alert-fixed-top,
+.alert-fixed-bottom {
+  position: fixed;
+  left: 0;
+  z-index: 1035;
+  width: 100%;
+  margin: 0;
+  border-radius: 0;
+}
+@media (min-width: 992px) {
+  .alert-fixed-top,
+  .alert-fixed-bottom {
+    left: 50%;
+    width: 992px;
+    margin-left: -496px;
+  }
+}
+.alert-fixed-top {
+  top: 0;
+  border-width: 0 0 1px 0;
+}
+@media (min-width: 992px) {
+  .alert-fixed-top {
+    border-width: 0 1px 1px 1px;
+    border-bottom-right-radius: 4px;
+    border-bottom-left-radius: 4px;
+  }
+}
+.alert-fixed-bottom {
+  bottom: 0;
+  border-width: 1px 0 0 0;
+}
+@media (min-width: 992px) {
+  .alert-fixed-bottom {
+    border-width: 1px 1px 0 1px;
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px;
+  }
+}
+.offcanvas {
+  display: none;
+}
+.offcanvas.in {
+  display: block;
+}
+@media (max-width: 767px) {
+  .offcanvas-xs {
+    display: none;
+  }
+  .offcanvas-xs.in {
+    display: block;
+  }
+}
+@media (max-width: 991px) {
+  .offcanvas-sm {
+    display: none;
+  }
+  .offcanvas-sm.in {
+    display: block;
+  }
+}
+@media (max-width: 1199px) {
+  .offcanvas-md {
+    display: none;
+  }
+  .offcanvas-md.in {
+    display: block;
+  }
+}
+.offcanvas-lg {
+  display: none;
+}
+.offcanvas-lg.in {
+  display: block;
+}
+.canvas-sliding {
+  -webkit-transition: top .35s, left .35s, bottom .35s, right .35s;
+          transition: top .35s, left .35s, bottom .35s, right .35s;
+}
+.offcanvas-clone {
+  position: absolute !important;
+  top: auto !important;
+  right: 0 !important;
+  bottom: 0 !important;
+  left: auto !important;
+  width: 0 !important;
+  height: 0 !important;
+  padding: 0 !important;
+  margin: 0 !important;
+  overflow: hidden !important;
+  border: none !important;
+  opacity: 0 !important;
+}
+.table.rowlink td:not(.rowlink-skip),
+.table .rowlink td:not(.rowlink-skip) {
+  cursor: pointer;
+}
+.table.rowlink td:not(.rowlink-skip) a,
+.table .rowlink td:not(.rowlink-skip) a {
+  font: inherit;
+  color: inherit;
+  text-decoration: inherit;
+}
+.table-hover.rowlink tr:hover td,
+.table-hover .rowlink tr:hover td {
+  background-color: #cfcfcf;
+}
+.btn-file {
+  position: relative;
+  overflow: hidden;
+  vertical-align: middle;
+}
+.btn-file > input {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  font-size: 23px;
+  cursor: pointer;
+  filter: alpha(opacity=0);
+  opacity: 0;
+
+  direction: ltr;
+}
+.fileinput {
+  display: inline-block;
+  margin-bottom: 9px;
+}
+.fileinput .form-control {
+  display: inline-block;
+  padding-top: 7px;
+  padding-bottom: 5px;
+  margin-bottom: 0;
+  vertical-align: middle;
+  cursor: text;
+}
+.fileinput .thumbnail {
+  display: inline-block;
+  margin-bottom: 5px;
+  overflow: hidden;
+  text-align: center;
+  vertical-align: middle;
+}
+.fileinput .thumbnail > img {
+  max-height: 100%;
+}
+.fileinput .btn {
+  vertical-align: middle;
+}
+.fileinput-exists .fileinput-new,
+.fileinput-new .fileinput-exists {
+  display: none;
+}
+.fileinput-inline .fileinput-controls {
+  display: inline;
+}
+.fileinput-filename {
+  display: inline-block;
+  overflow: hidden;
+  vertical-align: middle;
+}
+.form-control .fileinput-filename {
+  vertical-align: bottom;
+}
+.fileinput.input-group {
+  display: table;
+}
+.fileinput.input-group > * {
+  position: relative;
+  z-index: 2;
+}
+.fileinput.input-group > .btn-file {
+  z-index: 1;
+}
+.fileinput-new.input-group .btn-file,
+.fileinput-new .input-group .btn-file {
+  border-radius: 0 4px 4px 0;
+}
+.fileinput-new.input-group .btn-file.btn-xs,
+.fileinput-new .input-group .btn-file.btn-xs,
+.fileinput-new.input-group .btn-file.btn-sm,
+.fileinput-new .input-group .btn-file.btn-sm {
+  border-radius: 0 3px 3px 0;
+}
+.fileinput-new.input-group .btn-file.btn-lg,
+.fileinput-new .input-group .btn-file.btn-lg {
+  border-radius: 0 6px 6px 0;
+}
+.form-group.has-warning .fileinput .fileinput-preview {
+  color: #8a6d3b;
+}
+.form-group.has-warning .fileinput .thumbnail {
+  border-color: #faebcc;
+}
+.form-group.has-error .fileinput .fileinput-preview {
+  color: #a94442;
+}
+.form-group.has-error .fileinput .thumbnail {
+  border-color: #ebccd1;
+}
+.form-group.has-success .fileinput .fileinput-preview {
+  color: #3c763d;
+}
+.form-group.has-success .fileinput .thumbnail {
+  border-color: #d6e9c6;
+}
+.input-group-addon:not(:first-child) {
+  border-left: 0;
+}
+/*# sourceMappingURL=jasny-bootstrap.css.map */
diff --git a/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css.map b/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.css.map
new file mode 100644 (file)
index 0000000..0ccf8b7
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["less/grid-container-smooth.less","less/button-labels.less","less/nav-tab-alignment.less","less/navmenu.less","less/build/mixins.less","less/alerts-fixed.less","less/offcanvas.less","less/rowlink.less","less/fileinput.less"],"names":[],"mappings":"AAGA;EACE,iBAAA;;AAKF,QAH0B;EAG1B;IAFI,WAAA;;;ACSJ;EACE,cAAA;EACA,iBAAA;;AAGF;EACE,kBAAA;EACA,uBAAA;EACA,+BAAA;EACA,qBAAA;EArBA,iBAAA;EACA,WAAA;EACA,0BAAA;;AAEA,UAAC;EACC,UAAA;EACA,YAAA;EACA,0BAAA;;AAkBJ,OAAQ;EAzBN,kBAAA;EACA,WAAA;EACA,0BAAA;;AAEA,OAqBM,WArBL;EACC,UAAA;EACA,YAAA;EACA,0BAAA;;AAqBJ,OAAQ;EA5BN,iBAAA;EACA,WAAA;EACA,0BAAA;;AAEA,OAwBM,WAxBL;EACC,UAAA;EACA,YAAA;EACA,0BAAA;;AAwBJ,OAAQ;EA/BN,gBAAA;EACA,UAAA;EACA,0BAAA;;AAEA,OA2BM,WA3BL;EACC,UAAA;EACA,WAAA;EACA,0BAAA;;ACPJ;EACE,gBAAA;EACA,6BAAA;;AAFF,gBAIE;EACE,gBAAA;EACA,gBAAA;;AANJ,gBAIE,KAIE;EACE,0BAAA;;AATN,gBAIE,KAQE,IAAG;AAZP,gBAIE,KASE,IAAG;AACH,gBAVF,KAUG,OAAQ;AACT,gBAXF,KAWG,OAAQ,IAAG;AACZ,gBAZF,KAYG,OAAQ,IAAG;EACV,yBAAA;EACA,6BAAA;;AAMN;EACE,gBAAA;EACA,+BAAA;;AAFF,cAIE;EACE,gBAAA;EACA,kBAAA;EACA,WAAA;;AAPJ,cAIE,KAKE;EACE,0BAAA;EACA,eAAA;EACA,kBAAA;;AAZN,cAIE,KAWE,IAAG;AAfP,cAIE,KAYE,IAAG;AACH,cAbF,KAaG,OAAQ;AACT,cAdF,KAcG,OAAQ,IAAG;AACZ,cAfF,KAeG,OAAQ,IAAG;EACV,yBAAA;EACA,+BAAA;;AAIJ,IAAK;EACH,gBAAA;EACA,kBAAA;EACA,kBAAA;EACA,kBAAA;EACA,UAAA;;AAEA,IAPG,iBAOD;EACA,8BAAA;;AAMN;EACE,gBAAA;EACA,8BAAA;;AAFF,eAIE;EACE,gBAAA;EACA,iBAAA;EACA,WAAA;;AAPJ,eAIE,KAKE;EACE,0BAAA;EACA,cAAA;EACA,kBAAA;;AAZN,eAIE,KAWE,IAAG;AAfP,eAIE,KAYE,IAAG;AACH,eAbF,KAaG,OAAQ;AACT,eAdF,KAcG,OAAQ,IAAG;AACZ,eAfF,KAeG,OAAQ,IAAG;EACV,yBAAA;EACA,8BAAA;;AAIJ,IAAK;EACH,eAAA;EACA,mBAAA;;ACrFJ;AACA;EACE,YAAA;EACA,YAAA;EACA,iBAAA;EACA,mBAAA;EACA,kBAAA;;AAGF;AACA;AACA;EACE,eAAA;EACA,aAAA;EACA,MAAA;EACA,SAAA;EACA,gBAAA;EACA,gBAAA;;AAEF;AACA,iBAAiB;EACf,OAAA;EACA,WAAA;EACA,uBAAA;;AAEF;AACA;EACE,UAAA;EACA,QAAA;EACA,uBAAA;;AAGF;EACE,mBAAA;;AAEA,YAAC;EACC,gBAAA;EACA,SAAA;EACA,cAAA;EACA,WAAA;EACA,YAAA;ECpBF,wBAAA;EACQ,gBAAA;EDqBN,gBAAA;;AAIJ,iBACE;EACE,SAAA;;AA4BJ,QAzB6C;EAyB7C;IAxBI,WAAA;IACA,aAAA;IACA,gBAAA;;EAEA,iBAAC;IACC,gBAAA;IACA,yBAAA;IACA,uBAAA;IACA,iBAAA;IACA,4BAAA;;EAeN,iBAXI,YAAW,YAAY;IACrB,kBAAA;;EAUN,iBARI,YAAW,aAAa;IACtB,mBAAA;;EAON,iBAJI;IACE,aAAA;;;AAON;EACE,cAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;EAKA,cAAA;;AAJA,cAAC;AACD,cAAC;EACC,qBAAA;;AASJ;AACA,eAAgB;EACd,yBAAA;EACA,qBAAA;;AAHF,gBAKE;AAJF,eAAgB,kBAId;EACE,cAAA;;AACA,gBAFF,eAEG;AAAD,eANY,kBAId,eAEG;AACD,gBAHF,eAGG;AAAD,eAPY,kBAId,eAGG;EACC,cAAA;EACA,6BAAA;;AAVN,gBAcE;AAbF,eAAgB,kBAad;EACE,cAAA;;AAfJ,gBAkBE,aAEE,YAAY,IAAG,MAAO;AAnB1B,eAAgB,kBAiBd,aAEE,YAAY,IAAG,MAAO;AApB1B,gBAkBE,aAGE,YAAY,IAAG,MAAO;AApB1B,eAAgB,kBAiBd,aAGE,YAAY,IAAG,MAAO;EACpB,yBAAA;EACA,4BAAA;;AAKA,gBAVJ,aASE,QAAQ;AACN,eA3BU,kBAiBd,aASE,QAAQ;AAEN,gBAXJ,aASE,QAAQ,IAEL;AAAD,eA5BU,kBAiBd,aASE,QAAQ,IAEL;AACD,gBAZJ,aASE,QAAQ,IAGL;AAAD,eA7BU,kBAiBd,aASE,QAAQ,IAGL;EACC,yBAAA;EACA,cAAA;;AAJF,gBAVJ,aASE,QAAQ,IAMJ;AALF,eA3BU,kBAiBd,aASE,QAAQ,IAMJ;AAJF,gBAXJ,aASE,QAAQ,IAEL,MAIC;AAJF,eA5BU,kBAiBd,aASE,QAAQ,IAEL,MAIC;AAHF,gBAZJ,aASE,QAAQ,IAGL,MAGC;AAHF,eA7BU,kBAiBd,aASE,QAAQ,IAGL,MAGC;EACE,yBAAA;EACA,4BAAA;;AAnCV,gBAkBE,aAqBE,YAAY,IAAI;AAtCpB,eAAgB,kBAiBd,aAqBE,YAAY,IAAI;EACd,yBAAA;EACA,4BAAA;;AAEF,gBAzBF,aAyBG;AAAD,eA1CY,kBAiBd,aAyBG;EACC,yBAAA;;AACA,gBA3BJ,aAyBG,cAEG;AAAF,eA5CU,kBAiBd,aAyBG,cAEG;EACA,yBAAA;;AAGA,gBA/BN,aAyBG,cAKC,UAAU;AACR,eAhDQ,kBAiBd,aAyBG,cAKC,UAAU;AAER,gBAhCN,aAyBG,cAKC,UAAU,IAEP;AAAD,eAjDQ,kBAiBd,aAyBG,cAKC,UAAU,IAEP;AACD,gBAjCN,aAyBG,cAKC,UAAU,IAGP;AAAD,eAlDQ,kBAiBd,aAyBG,cAKC,UAAU,IAGP;EACC,yBAAA;;AApDV,gBAkBE,aAuCE,KAAK;AAxDT,eAAgB,kBAiBd,aAuCE,KAAK;EACH,cAAA;;AACA,gBAzCJ,aAuCE,KAAK,IAEF;AAAD,eA1DU,kBAiBd,aAuCE,KAAK,IAEF;AACD,gBA1CJ,aAuCE,KAAK,IAGF;AAAD,eA3DU,kBAiBd,aAuCE,KAAK,IAGF;EACC,cAAA;EACA,6BAAA;;AAIF,gBAhDJ,aA+CE,UAAU;AACR,eAjEU,kBAiBd,aA+CE,UAAU;AAER,gBAjDJ,aA+CE,UAAU,IAEP;AAAD,eAlEU,kBAiBd,aA+CE,UAAU,IAEP;AACD,gBAlDJ,aA+CE,UAAU,IAGP;AAAD,eAnEU,kBAiBd,aA+CE,UAAU,IAGP;EACC,cAAA;EACA,yBAAA;;AAIF,gBAxDJ,aAuDE,YAAY;AACV,eAzEU,kBAiBd,aAuDE,YAAY;AAEV,gBAzDJ,aAuDE,YAAY,IAET;AAAD,eA1EU,kBAiBd,aAuDE,YAAY,IAET;AACD,gBA1DJ,aAuDE,YAAY,IAGT;AAAD,eA3EU,kBAiBd,aAuDE,YAAY,IAGT;EACC,cAAA;EACA,6BAAA;;AAOR;AACA,eAAgB;EACd,yBAAA;EACA,qBAAA;;AAHF,gBAKE;AAJF,eAAgB,kBAId;EACE,cAAA;;AACA,gBAFF,eAEG;AAAD,eANY,kBAId,eAEG;AACD,gBAHF,eAGG;AAAD,eAPY,kBAId,eAGG;EACC,cAAA;EACA,6BAAA;;AAVN,gBAcE;AAbF,eAAgB,kBAad;EACE,cAAA;;AAfJ,gBAkBE,aAEE,YAAY,IAAG,MAAO;AAnB1B,eAAgB,kBAiBd,aAEE,YAAY,IAAG,MAAO;AApB1B,gBAkBE,aAGE,YAAY,IAAG,MAAO;AApB1B,eAAgB,kBAiBd,aAGE,YAAY,IAAG,MAAO;EACpB,yBAAA;EACA,4BAAA;;AAKA,gBAVJ,aASE,QAAQ;AACN,eA3BU,kBAiBd,aASE,QAAQ;AAEN,gBAXJ,aASE,QAAQ,IAEL;AAAD,eA5BU,kBAiBd,aASE,QAAQ,IAEL;AACD,gBAZJ,aASE,QAAQ,IAGL;AAAD,eA7BU,kBAiBd,aASE,QAAQ,IAGL;EACC,yBAAA;EACA,cAAA;;AAJF,gBAVJ,aASE,QAAQ,IAMJ;AALF,eA3BU,kBAiBd,aASE,QAAQ,IAMJ;AAJF,gBAXJ,aASE,QAAQ,IAEL,MAIC;AAJF,eA5BU,kBAiBd,aASE,QAAQ,IAEL,MAIC;AAHF,gBAZJ,aASE,QAAQ,IAGL,MAGC;AAHF,eA7BU,kBAiBd,aASE,QAAQ,IAGL,MAGC;EACE,yBAAA;EACA,4BAAA;;AAnCV,gBAkBE,aAqBE,YAAY,IAAI;AAtCpB,eAAgB,kBAiBd,aAqBE,YAAY,IAAI;EACd,yBAAA;EACA,4BAAA;;AAEF,gBAzBF,aAyBG;AAAD,eA1CY,kBAiBd,aAyBG;EACC,yBAAA;;AACA,gBA3BJ,aAyBG,cAEG;AAAF,eA5CU,kBAiBd,aAyBG,cAEG;EACA,yBAAA;;AAGA,gBA/BN,aAyBG,cAKC,UAAU;AACR,eAhDQ,kBAiBd,aAyBG,cAKC,UAAU;AAER,gBAhCN,aAyBG,cAKC,UAAU,IAEP;AAAD,eAjDQ,kBAiBd,aAyBG,cAKC,UAAU,IAEP;AACD,gBAjCN,aAyBG,cAKC,UAAU,IAGP;AAAD,eAlDQ,kBAiBd,aAyBG,cAKC,UAAU,IAGP;EACC,yBAAA;;AApDV,gBAkBE,aAuCE,KAAK;AAxDT,eAAgB,kBAiBd,aAuCE,KAAK;EACH,cAAA;;AACA,gBAzCJ,aAuCE,KAAK,IAEF;AAAD,eA1DU,kBAiBd,aAuCE,KAAK,IAEF;AACD,gBA1CJ,aAuCE,KAAK,IAGF;AAAD,eA3DU,kBAiBd,aAuCE,KAAK,IAGF;EACC,cAAA;EACA,6BAAA;;AAIF,gBAhDJ,aA+CE,UAAU;AACR,eAjEU,kBAiBd,aA+CE,UAAU;AAER,gBAjDJ,aA+CE,UAAU,IAEP;AAAD,eAlEU,kBAiBd,aA+CE,UAAU,IAEP;AACD,gBAlDJ,aA+CE,UAAU,IAGP;AAAD,eAnEU,kBAiBd,aA+CE,UAAU,IAGP;EACC,cAAA;EACA,yBAAA;;AAIF,gBAxDJ,aAuDE,YAAY;AACV,eAzEU,kBAiBd,aAuDE,YAAY;AAEV,gBAzDJ,aAuDE,YAAY,IAET;AAAD,eA1EU,kBAiBd,aAuDE,YAAY,IAET;AACD,gBA1DJ,aAuDE,YAAY,IAGT;AAAD,eA3EU,kBAiBd,aAuDE,YAAY,IAGT;EACC,cAAA;EACA,6BAAA;;AExQR;AACA;EACE,eAAA;EACA,WAAA;EACA,aAAA;EACA,gBAAA;EACA,SAAA;EACA,OAAA;;AAOF,QALyC;EAKzC;EAAA;IAJI,YAAA;IACA,SAAA;IACA,mBAAA;;;AAIJ;EACE,MAAA;EACA,uBAAA;;AAMF,QAJyC;EAIzC;IDTE,+BAAA;IACC,8BAAA;ICMC,2BAAA;;;AAIJ;EACE,SAAA;EACA,uBAAA;;AAMF,QAJyC;EAIzC;ID3BE,4BAAA;IACC,2BAAA;ICwBC,2BAAA;;;ACjCJ;EACE,aAAA;;AACA,UAAC;EACC,cAAA;;AASJ,QALmC;EACjC;IAPA,aAAA;;EACA,aAAC;IACC,cAAA;;;AAcJ,QALmC;EACjC;IAZA,aAAA;;EACA,aAAC;IACC,cAAA;;;AAmBJ,QALmC;EACjC;IAjBA,aAAA;;EACA,aAAC;IACC,cAAA;;;AAmBJ;EArBE,aAAA;;AACA,aAAC;EACC,cAAA;;AAuBJ;EACE,oEAAA;EACQ,4DAAA;;AAGV;EACE,sBAAA;EACA,qBAAA;EACA,2BAAA;EACA,uBAAA;EACA,sBAAA;EACA,uBAAA;EACA,6BAAA;EACA,oBAAA;EACA,qBAAA;EACA,sBAAA;EACA,qBAAA;EACA,qBAAA;;AC3CF,MAAM,QAEJ,GAAE,IAAI;AADR,MAAO,SACL,GAAE,IAAI;EACJ,eAAA;;AAHJ,MAAM,QAEJ,GAAE,IAAI,eAGJ;AAJJ,MAAO,SACL,GAAE,IAAI,eAGJ;EACE,cAAA;EACA,aAAA;EACA,wBAAA;;AAKN,YAAY,QAEV,GAAE,MAAO;AADX,YAAa,SACX,GAAE,MAAO;EACP,yBAAA;;ACfJ;EACE,gBAAA;EACA,kBAAA;EACA,sBAAA;;AAHF,SAIE;EACE,kBAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,wBAAA;EACA,eAAA;EACA,YAAA;EACA,WAAA;EACA,cAAA;EACA,eAAA;;AAIJ;EACE,kBAAA;EACA,qBAAA;;AAFF,UAGE;EACE,gBAAA;EACA,mBAAA;EACA,qBAAA;EACA,kBAAA;EACA,sBAAA;EACA,YAAA;;AATJ,UAWE;EACE,gBAAA;EACA,qBAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;;AAhBJ,UAWE,WAME;EACE,gBAAA;;AAlBN,UAqBE;EACE,sBAAA;;AAGJ,iBAAkB;AAClB,cAAe;EACb,aAAA;;AAEF,iBAAkB;EAChB,eAAA;;AAGF;EACE,sBAAA;EACA,qBAAA;EACA,gBAAA;;AAEF,aAAc;EACZ,sBAAA;;AAGF,UAAU;EACN,cAAA;;AADJ,UAAU,YAGN;EACI,kBAAA;EACA,UAAA;;AALR,UAAU,YAON;EACI,UAAA;;AAKR,cAAc,YAAa;AAC3B,cAAe,aAAa;EAC1B,0BAAA;;AAEA,cAJY,YAAa,UAIxB;AAAD,cAHa,aAAa,UAGzB;AACD,cALY,YAAa,UAKxB;AAAD,cAJa,aAAa,UAIzB;EACC,0BAAA;;AAEF,cARY,YAAa,UAQxB;AAAD,cAPa,aAAa,UAOzB;EACC,0BAAA;;AAIJ,WAAW,YAAa,WACtB;EACE,cAAA;;AAFJ,WAAW,YAAa,WAItB;EACE,qBAAA;;AAGJ,WAAW,UAAW,WACpB;EACE,cAAA;;AAFJ,WAAW,UAAW,WAIpB;EACE,qBAAA;;AAGJ,WAAW,YAAa,WACtB;EACE,cAAA;;AAFJ,WAAW,YAAa,WAItB;EACE,qBAAA;;AAOJ,kBAAkB,IAAI;EACpB,cAAA","sourcesContent":["// Smooth sizing container\n// -------------------------\n\n.container-smooth {\n  max-width: @container-lg;\n    \n  @media (min-width: 1px) {\n    width: auto;\n  }\n}\n","// Labels for buttons\n// --------------------------------------------------\n\n.button-label-size(@padding-vertical; @padding-horizontal; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  left: (-1 * @padding-horizontal);\n  border-radius: (@border-radius - 1px) 0 0 (@border-radius - 1px);\n\n  &.btn-label-right {\n    left: auto;\n    right: (-1 * @padding-horizontal);\n    border-radius: 0 (@border-radius - 1px) (@border-radius - 1px) 0;\n  }\n}\n\n\n.btn-labeled {\n  padding-top: 0;\n  padding-bottom: 0;\n}\n\n.btn-label {\n  position: relative;\n  background: transparent;\n  background: rgba(0, 0, 0, 0.15);\n  display: inline-block;\n  .button-label-size(@padding-base-vertical; @padding-base-horizontal; @border-radius-base);\n}\n\n.btn-lg .btn-label {\n  .button-label-size(@padding-large-vertical; @padding-large-horizontal; @border-radius-large);\n}\n.btn-sm .btn-label {\n  .button-label-size(@padding-small-vertical; @padding-small-horizontal; @border-radius-small);\n}\n.btn-xs .btn-label {\n  .button-label-size(1px; 5px; @border-radius-small);\n}\n","// Alignment options\n// -------------------------\n\n// bottom\n.nav-tabs-bottom {\n  border-bottom: 0;\n  border-top: 1px solid @nav-tabs-border-color;\n\n  > li {\n    margin-bottom: 0;\n    margin-top: -1px;\n\n    > a {\n      border-radius: 0 0 @border-radius-base @border-radius-base;\n    }\n\n    > a:hover,\n    > a:focus,\n    &.active > a,\n    &.active > a:hover,\n    &.active > a:focus {\n      border: 1px solid @nav-tabs-active-link-hover-border-color;\n      border-top-color: transparent;\n    }\n  }\n}\n\n// left\n.nav-tabs-left {\n  border-bottom: 0;\n  border-right: 1px solid @nav-tabs-border-color;\n\n  > li {\n    margin-bottom: 0;\n    margin-right: -1px;\n    float: none;\n\n    > a {\n      border-radius: @border-radius-base 0 0 @border-radius-base;\n      margin-right: 0;\n      margin-bottom: 2px;\n    }\n\n    > a:hover,\n    > a:focus,\n    &.active > a,\n    &.active > a:hover,\n    &.active > a:focus {\n      border: 1px solid @nav-tabs-active-link-hover-border-color;\n      border-right-color: transparent;\n    }\n  }\n\n  .row > & {\n    padding-right: 0;\n    padding-left: (@grid-gutter-width / 2);\n    margin-right: -1px;\n    position: relative;\n    z-index: 1;\n\n    & + .tab-content {\n      border-left: 1px solid @nav-tabs-active-link-hover-border-color;\n    }\n  }\n}\n\n// right\n.nav-tabs-right {\n  border-bottom: 0;\n  border-left: 1px solid @nav-tabs-border-color;\n\n  > li {\n    margin-bottom: 0;\n    margin-left: -1px;\n    float: none;\n\n    > a {\n      border-radius: 0 @border-radius-base @border-radius-base 0;\n      margin-left: 0;\n      margin-bottom: 2px;\n    }\n\n    > a:hover,\n    > a:focus,\n    &.active > a,\n    &.active > a:hover,\n    &.active > a:focus {\n      border: 1px solid @nav-tabs-active-link-hover-border-color;\n      border-left-color: transparent;\n    }\n  }\n\n  .row > & {\n    padding-left: 0;\n    padding-right: (@grid-gutter-width / 2);\n  }\n}\n","// Navmenu and offcanvas navbar\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navmenu from which we expand to create the fixed navmenu\n// variations.\n\n.navmenu,\n.navbar-offcanvas {\n  width: @navmenu-width;\n  height: auto;\n  border-width: 1px;\n  border-style: solid;\n  border-radius: @border-radius-base;\n}\n\n.navmenu-fixed-left,\n.navmenu-fixed-right,\n.navbar-offcanvas {\n  position: fixed;\n  z-index: @zindex-navmenu-fixed;\n  top: 0;\n  bottom: 0;\n  overflow-y: auto;\n  border-radius: 0;\n}\n.navmenu-fixed-left,\n.navbar-offcanvas.navmenu-fixed-left {\n  left: 0;\n  right: auto;\n  border-width: 0 1px 0 0;\n}\n.navmenu-fixed-right,\n.navbar-offcanvas {\n  left: auto;\n  right: 0;\n  border-width: 0 0 0 1px;\n}\n\n.navmenu-nav {\n  margin-bottom: @navmenu-margin-vertical;\n\n  &.dropdown-menu {\n    position: static;\n    margin: 0;\n    padding-top: 0;\n    float: none;\n    border: none;\n    .box-shadow(none);\n    border-radius: 0;\n  }\n}\n\n.navbar-offcanvas {\n  .navbar-nav {\n    margin: 0;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.offcanvas {\n      position: static;\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    // Account for first and last children spacing\n    .navbar-nav.navbar-left:first-child {\n      margin-left: -@navbar-padding-horizontal;\n    }\n    .navbar-nav.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n\n    .navmenu-brand {\n      display: none;\n    }\n  }\n}\n\n// Brand/project name\n\n.navmenu-brand {\n  display: block;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  padding: @nav-link-padding;\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n  margin: @navmenu-margin-vertical 0;\n}\n\n// Alternate navmenus\n// --------------------------------------------------\n\n// Default navmenu\n.navmenu-default,\n.navbar-default .navbar-offcanvas {\n  background-color: @navmenu-default-bg;\n  border-color: @navmenu-default-border;\n\n  .navmenu-brand {\n    color: @navmenu-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navmenu-default-brand-hover-color;\n      background-color: @navmenu-default-brand-hover-bg;\n    }\n  }\n\n  .navmenu-text {\n    color: @navmenu-default-color;\n  }\n\n  .navmenu-nav {\n    // Caret should match text color on hover\n    > .dropdown > a:hover .caret,\n    > .dropdown > a:focus .caret {\n      border-top-color: @navmenu-default-link-hover-color;\n      border-bottom-color: @navmenu-default-link-hover-color;\n    }\n\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navmenu-default-link-active-bg;\n        color: @navmenu-default-link-active-color;\n        .caret {\n          border-top-color: @navmenu-default-link-active-color;\n          border-bottom-color: @navmenu-default-link-active-color;\n        }\n      }\n    }\n    > .dropdown > a .caret {\n      border-top-color: @navmenu-default-link-color;\n      border-bottom-color: @navmenu-default-link-color;\n    }\n    &.dropdown-menu {\n      background-color: @navmenu-default-link-active-bg;\n      & > .divider {\n        background-color: @navmenu-default-bg;\n      }\n      > .active > a {\n        &,\n        &:hover,\n        &:focus {\n          background-color: darken(@navmenu-default-link-active-bg, 6.5%);\n        }\n      }\n    }\n\n    > li > a {\n      color: @navmenu-default-link-color;\n      &:hover,\n      &:focus {\n        color: @navmenu-default-link-hover-color;\n        background-color: @navmenu-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navmenu-default-link-active-color;\n        background-color: @navmenu-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navmenu-default-link-disabled-color;\n        background-color: @navmenu-default-link-disabled-bg;\n      }\n    }\n  }\n}\n\n// Inverse navmenu\n.navmenu-inverse,\n.navbar-inverse .navbar-offcanvas {\n  background-color: @navmenu-inverse-bg;\n  border-color: @navmenu-inverse-border;\n\n  .navmenu-brand {\n    color: @navmenu-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navmenu-inverse-brand-hover-color;\n      background-color: @navmenu-inverse-brand-hover-bg;\n    }\n  }\n\n  .navmenu-text {\n    color: @navmenu-inverse-color;\n  }\n\n  .navmenu-nav {\n    // Caret should match text color on hover\n    > .dropdown > a:hover .caret,\n    > .dropdown > a:focus .caret {\n      border-top-color: @navmenu-inverse-link-hover-color;\n      border-bottom-color: @navmenu-inverse-link-hover-color;\n    }\n\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navmenu-inverse-link-active-bg;\n        color: @navmenu-inverse-link-active-color;\n        .caret {\n          border-top-color: @navmenu-inverse-link-active-color;\n          border-bottom-color: @navmenu-inverse-link-active-color;\n        }\n      }\n    }\n    > .dropdown > a .caret {\n      border-top-color: @navmenu-inverse-link-color;\n      border-bottom-color: @navmenu-inverse-link-color;\n    }\n    &.dropdown-menu {\n      background-color: @navmenu-inverse-link-active-bg;\n      & > .divider {\n        background-color: @navmenu-inverse-bg;\n      }\n      > .active > a {\n        &,\n        &:hover,\n        &:focus {\n          background-color: darken(@navmenu-inverse-link-active-bg, 6.5%);\n        }\n      }\n    }\n\n    > li > a {\n      color: @navmenu-inverse-link-color;\n      &:hover,\n      &:focus {\n        color: @navmenu-inverse-link-hover-color;\n        background-color: @navmenu-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navmenu-inverse-link-active-color;\n        background-color: @navmenu-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navmenu-inverse-link-disabled-color;\n        background-color: @navmenu-inverse-link-disabled-bg;\n      }\n    }\n  }\n}\n","//\n// These mixins are used when Jasny Bootstrap is\n// built without importing Twitter Bootstrap.\n// --------------------------------------------------\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n\n// Drop shadows\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n.transition(@transition) {\n  -webkit-transition: @transition;\n       -o-transition: @transition;\n          transition: @transition;\n}\n\n// Transition\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n  -webkit-transition-timing-function: @timing-function;\n          transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}","// Fixed alerts\n// Position to the top or bottom.\n// ------------------------------------------------\n\n.alert-fixed-top,\n.alert-fixed-bottom {\n  position: fixed;\n  width: 100%;\n  z-index: @zindex-alert-fixed;\n  border-radius: 0;\n  margin: 0;\n  left: 0;\n\n  @media (min-width: @alert-fixed-width) {\n    width: @alert-fixed-width;\n    left: 50%;\n    margin-left: (-1 * (@alert-fixed-width / 2));\n  }\n}\n\n.alert-fixed-top {\n  top: 0;\n  border-width: 0 0 1px 0;\n  \n  @media (min-width: @alert-fixed-width) {\n    .border-bottom-radius(@alert-border-radius);\n    border-width: 0 1px 1px 1px;\n  }\n}\n\n.alert-fixed-bottom {\n  bottom: 0;\n  border-width: 1px 0 0 0;\n  \n  @media (min-width: @alert-fixed-width) {\n    .border-top-radius(@alert-border-radius);\n    border-width: 1px 1px 0 1px;\n  }\n}\n","// Off canvas navigation\n// --------------------------------------------------\n\n.offcanvas {\n  display: none;\n  &.in {\n    display: block;\n  }\n}\n\n@media (max-width: @screen-xs-max) {\n  .offcanvas-xs {\n    .offcanvas;\n  }\n}\n@media (max-width: @screen-sm-max) {\n  .offcanvas-sm {\n    .offcanvas;\n  }\n}\n@media (max-width: @screen-md-max) {\n  .offcanvas-md {\n    .offcanvas;\n  }\n}\n.offcanvas-lg {\n  .offcanvas;\n}\n\n.canvas-sliding {\n  -webkit-transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s;\n          transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s;\n}\n\n.offcanvas-clone {\n  height: 0px !important;\n  width: 0px !important;\n  overflow: hidden !important;\n  border: none !important;\n  margin: 0px !important;\n  padding: 0px !important;\n  position: absolute !important;\n  top: auto !important;\n  left: auto !important;\n  bottom: 0px !important;\n  right: 0px !important;\n  opacity: 0 !important;\n}\n","// Rowlink\n// --------------------------------------------------\n\n.table.rowlink,\n.table .rowlink {\n  td:not(.rowlink-skip) {\n    cursor: pointer;\n\n    a {\n      color: inherit;\n      font: inherit;\n      text-decoration: inherit;\n    }\n  }\n}\n\n.table-hover.rowlink,\n.table-hover .rowlink {\n  tr:hover td {\n    background-color: darken(@table-bg-hover, 15%);\n  }\n}\n","// Fileinput.less\n// CSS for file upload button and fileinput widget\n// ------------------------------------------------\n\n.btn-file {\n  overflow: hidden;\n  position: relative;\n  vertical-align: middle;\n  > input {\n    position: absolute;\n    top: 0;\n    right: 0;\n    margin: 0;\n    opacity: 0;\n    filter: alpha(opacity=0);\n    font-size: 23px;\n    height: 100%;\n    width: 100%;\n    direction: ltr;\n    cursor: pointer;\n  }\n}\n\n.fileinput {\n  margin-bottom: 9px;\n  display: inline-block;\n  .form-control {\n    padding-top: 7px;\n    padding-bottom: 5px;\n    display: inline-block;\n    margin-bottom: 0px;\n    vertical-align: middle;\n    cursor: text;\n  }\n  .thumbnail {\n    overflow: hidden;\n    display: inline-block;\n    margin-bottom: 5px;\n    vertical-align: middle;\n    text-align: center;\n    > img {\n      max-height: 100%;\n    }\n  }\n  .btn {\n    vertical-align: middle;\n  }\n}\n.fileinput-exists .fileinput-new,\n.fileinput-new .fileinput-exists {\n  display: none;\n}\n.fileinput-inline .fileinput-controls {\n  display: inline;\n}\n\n.fileinput-filename {\n  vertical-align: middle;\n  display: inline-block;\n  overflow: hidden;\n}\n.form-control .fileinput-filename {\n  vertical-align: bottom;\n}\n\n.fileinput.input-group {\n    display: table;\n    \n    > * {\n        position: relative;\n        z-index: 2;\n    }\n    > .btn-file {\n        z-index: 1;\n    }\n}\n\n// Not 100% correct, but helps in typical use case\n.fileinput-new.input-group .btn-file,\n.fileinput-new .input-group .btn-file {\n  border-radius: 0 @border-radius-base @border-radius-base 0;\n\n  &.btn-xs,\n  &.btn-sm {\n    border-radius: 0 @border-radius-small @border-radius-small 0;\n  }\n  &.btn-lg {\n    border-radius: 0 @border-radius-large @border-radius-large 0;\n  }\n}\n\n.form-group.has-warning .fileinput {\n  .fileinput-preview {\n    color: @state-warning-text;\n  }\n  .thumbnail {\n    border-color: @state-warning-border;\n  }\n}\n.form-group.has-error .fileinput {\n  .fileinput-preview {\n    color: @state-danger-text;\n  }\n  .thumbnail {\n    border-color: @state-danger-border;\n  }\n}\n.form-group.has-success .fileinput {\n  .fileinput-preview {\n    color: @state-success-text;\n  }\n  .thumbnail {\n    border-color: @state-success-border;\n  }\n}\n\n\n// Input group fixes\n\n.input-group-addon:not(:first-child) {\n  border-left: 0;\n}\n"]}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.min.css b/src/main/resources/META-INF/resources/designer/css/jasny-bootstrap.min.css
new file mode 100644 (file)
index 0000000..cffc43a
--- /dev/null
@@ -0,0 +1,7 @@
+/*!
+ * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
+ * Copyright 2012-2014 Arnold Daniels
+ * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
+ */
+
+.container-smooth{max-width:1170px}@media (min-width:1px){.container-smooth{width:auto}}.btn-labeled{padding-top:0;padding-bottom:0}.btn-label{position:relative;background:0 0;background:rgba(0,0,0,.15);display:inline-block;padding:6px 12px;left:-12px;border-radius:3px 0 0 3px}.btn-label.btn-label-right{left:auto;right:-12px;border-radius:0 3px 3px 0}.btn-lg .btn-label{padding:10px 16px;left:-16px;border-radius:5px 0 0 5px}.btn-lg .btn-label.btn-label-right{left:auto;right:-16px;border-radius:0 5px 5px 0}.btn-sm .btn-label{padding:5px 10px;left:-10px;border-radius:2px 0 0 2px}.btn-sm .btn-label.btn-label-right{left:auto;right:-10px;border-radius:0 2px 2px 0}.btn-xs .btn-label{padding:1px 5px;left:-5px;border-radius:2px 0 0 2px}.btn-xs .btn-label.btn-label-right{left:auto;right:-5px;border-radius:0 2px 2px 0}.nav-tabs-bottom{border-bottom:0;border-top:1px solid #ddd}.nav-tabs-bottom>li{margin-bottom:0;margin-top:-1px}.nav-tabs-bottom>li>a{border-radius:0 0 4px 4px}.nav-tabs-bottom>li>a:hover,.nav-tabs-bottom>li>a:focus,.nav-tabs-bottom>li.active>a,.nav-tabs-bottom>li.active>a:hover,.nav-tabs-bottom>li.active>a:focus{border:1px solid #ddd;border-top-color:transparent}.nav-tabs-left{border-bottom:0;border-right:1px solid #ddd}.nav-tabs-left>li{margin-bottom:0;margin-right:-1px;float:none}.nav-tabs-left>li>a{border-radius:4px 0 0 4px;margin-right:0;margin-bottom:2px}.nav-tabs-left>li>a:hover,.nav-tabs-left>li>a:focus,.nav-tabs-left>li.active>a,.nav-tabs-left>li.active>a:hover,.nav-tabs-left>li.active>a:focus{border:1px solid #ddd;border-right-color:transparent}.row>.nav-tabs-left{padding-right:0;padding-left:15px;margin-right:-1px;position:relative;z-index:1}.row>.nav-tabs-left+.tab-content{border-left:1px solid #ddd}.nav-tabs-right{border-bottom:0;border-left:1px solid #ddd}.nav-tabs-right>li{margin-bottom:0;margin-left:-1px;float:none}.nav-tabs-right>li>a{border-radius:0 4px 4px 0;margin-left:0;margin-bottom:2px}.nav-tabs-right>li>a:hover,.nav-tabs-right>li>a:focus,.nav-tabs-right>li.active>a,.nav-tabs-right>li.active>a:hover,.nav-tabs-right>li.active>a:focus{border:1px solid #ddd;border-left-color:transparent}.row>.nav-tabs-right{padding-left:0;padding-right:15px}.navmenu,.navbar-offcanvas{width:300px;height:auto;border-width:1px;border-style:solid;border-radius:4px}.navmenu-fixed-left,.navmenu-fixed-right,.navbar-offcanvas{position:fixed;z-index:1030;top:0;bottom:0;overflow-y:auto;border-radius:0}.navmenu-fixed-left,.navbar-offcanvas.navmenu-fixed-left{left:0;right:auto;border-width:0 1px 0 0}.navmenu-fixed-right,.navbar-offcanvas{left:auto;right:0;border-width:0 0 0 1px}.navmenu-nav{margin-bottom:10px}.navmenu-nav.dropdown-menu{position:static;margin:0;padding-top:0;float:none;border:none;-webkit-box-shadow:none;box-shadow:none;border-radius:0}.navbar-offcanvas .navbar-nav{margin:0}@media (min-width:768px){.navbar-offcanvas{width:auto;border-top:0;box-shadow:none}.navbar-offcanvas.offcanvas{position:static;display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-offcanvas .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-offcanvas .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-offcanvas .navmenu-brand{display:none}}.navmenu-brand{display:block;font-size:18px;line-height:20px;padding:10px 15px;margin:10px 0}.navmenu-brand:hover,.navmenu-brand:focus{text-decoration:none}.navmenu-default,.navbar-default .navbar-offcanvas{background-color:#f8f8f8;border-color:#e7e7e7}.navmenu-default .navmenu-brand,.navbar-default .navbar-offcanvas .navmenu-brand{color:#777}.navmenu-default .navmenu-brand:hover,.navbar-default .navbar-offcanvas .navmenu-brand:hover,.navmenu-default .navmenu-brand:focus,.navbar-default .navbar-offcanvas .navmenu-brand:focus{color:#5e5e5e;background-color:transparent}.navmenu-default .navmenu-text,.navbar-default .navbar-offcanvas .navmenu-text{color:#777}.navmenu-default .navmenu-nav>.dropdown>a:hover .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a:hover .caret,.navmenu-default .navmenu-nav>.dropdown>a:focus .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navmenu-default .navmenu-nav>.open>a,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a,.navmenu-default .navmenu-nav>.open>a:hover,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:hover,.navmenu-default .navmenu-nav>.open>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:focus{background-color:#e7e7e7;color:#555}.navmenu-default .navmenu-nav>.open>a .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a .caret,.navmenu-default .navmenu-nav>.open>a:hover .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:hover .caret,.navmenu-default .navmenu-nav>.open>a:focus .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navmenu-default .navmenu-nav>.dropdown>a .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}.navmenu-default .navmenu-nav.dropdown-menu,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu{background-color:#e7e7e7}.navmenu-default .navmenu-nav.dropdown-menu>.divider,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.divider{background-color:#f8f8f8}.navmenu-default .navmenu-nav.dropdown-menu>.active>a,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a,.navmenu-default .navmenu-nav.dropdown-menu>.active>a:hover,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:hover,.navmenu-default .navmenu-nav.dropdown-menu>.active>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:focus{background-color:#d7d7d7}.navmenu-default .navmenu-nav>li>a,.navbar-default .navbar-offcanvas .navmenu-nav>li>a{color:#777}.navmenu-default .navmenu-nav>li>a:hover,.navbar-default .navbar-offcanvas .navmenu-nav>li>a:hover,.navmenu-default .navmenu-nav>li>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>li>a:focus{color:#333;background-color:transparent}.navmenu-default .navmenu-nav>.active>a,.navbar-default .navbar-offcanvas .navmenu-nav>.active>a,.navmenu-default .navmenu-nav>.active>a:hover,.navbar-default .navbar-offcanvas .navmenu-nav>.active>a:hover,.navmenu-default .navmenu-nav>.active>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navmenu-default .navmenu-nav>.disabled>a,.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a,.navmenu-default .navmenu-nav>.disabled>a:hover,.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a:hover,.navmenu-default .navmenu-nav>.disabled>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navmenu-inverse,.navbar-inverse .navbar-offcanvas{background-color:#222;border-color:#080808}.navmenu-inverse .navmenu-brand,.navbar-inverse .navbar-offcanvas .navmenu-brand{color:#999}.navmenu-inverse .navmenu-brand:hover,.navbar-inverse .navbar-offcanvas .navmenu-brand:hover,.navmenu-inverse .navmenu-brand:focus,.navbar-inverse .navbar-offcanvas .navmenu-brand:focus{color:#fff;background-color:transparent}.navmenu-inverse .navmenu-text,.navbar-inverse .navbar-offcanvas .navmenu-text{color:#999}.navmenu-inverse .navmenu-nav>.dropdown>a:hover .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a:hover .caret,.navmenu-inverse .navmenu-nav>.dropdown>a:focus .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navmenu-inverse .navmenu-nav>.open>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a,.navmenu-inverse .navmenu-nav>.open>a:hover,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:hover,.navmenu-inverse .navmenu-nav>.open>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:focus{background-color:#080808;color:#fff}.navmenu-inverse .navmenu-nav>.open>a .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a .caret,.navmenu-inverse .navmenu-nav>.open>a:hover .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:hover .caret,.navmenu-inverse .navmenu-nav>.open>a:focus .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navmenu-inverse .navmenu-nav>.dropdown>a .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navmenu-inverse .navmenu-nav.dropdown-menu,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu{background-color:#080808}.navmenu-inverse .navmenu-nav.dropdown-menu>.divider,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.divider{background-color:#222}.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a,.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a:hover,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:hover,.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:focus{background-color:#000}.navmenu-inverse .navmenu-nav>li>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a{color:#999}.navmenu-inverse .navmenu-nav>li>a:hover,.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a:hover,.navmenu-inverse .navmenu-nav>li>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a:focus{color:#fff;background-color:transparent}.navmenu-inverse .navmenu-nav>.active>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a,.navmenu-inverse .navmenu-nav>.active>a:hover,.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a:hover,.navmenu-inverse .navmenu-nav>.active>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a:focus{color:#fff;background-color:#080808}.navmenu-inverse .navmenu-nav>.disabled>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a,.navmenu-inverse .navmenu-nav>.disabled>a:hover,.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a:hover,.navmenu-inverse .navmenu-nav>.disabled>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a:focus{color:#444;background-color:transparent}.alert-fixed-top,.alert-fixed-bottom{position:fixed;width:100%;z-index:1035;border-radius:0;margin:0;left:0}@media (min-width:992px){.alert-fixed-top,.alert-fixed-bottom{width:992px;left:50%;margin-left:-496px}}.alert-fixed-top{top:0;border-width:0 0 1px}@media (min-width:992px){.alert-fixed-top{border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-width:0 1px 1px}}.alert-fixed-bottom{bottom:0;border-width:1px 0 0}@media (min-width:992px){.alert-fixed-bottom{border-top-right-radius:4px;border-top-left-radius:4px;border-width:1px 1px 0}}.offcanvas{display:none}.offcanvas.in{display:block}@media (max-width:767px){.offcanvas-xs{display:none}.offcanvas-xs.in{display:block}}@media (max-width:991px){.offcanvas-sm{display:none}.offcanvas-sm.in{display:block}}@media (max-width:1199px){.offcanvas-md{display:none}.offcanvas-md.in{display:block}}.offcanvas-lg{display:none}.offcanvas-lg.in{display:block}.canvas-sliding{-webkit-transition:top .35s,left .35s,bottom .35s,right .35s;transition:top .35s,left .35s,bottom .35s,right .35s}.offcanvas-clone{height:0!important;width:0!important;overflow:hidden!important;border:none!important;margin:0!important;padding:0!important;position:absolute!important;top:auto!important;left:auto!important;bottom:0!important;right:0!important;opacity:0!important}.table.rowlink td:not(.rowlink-skip),.table .rowlink td:not(.rowlink-skip){cursor:pointer}.table.rowlink td:not(.rowlink-skip) a,.table .rowlink td:not(.rowlink-skip) a{color:inherit;font:inherit;text-decoration:inherit}.table-hover.rowlink tr:hover td,.table-hover .rowlink tr:hover td{background-color:#cfcfcf}.btn-file{overflow:hidden;position:relative;vertical-align:middle}.btn-file>input{position:absolute;top:0;right:0;margin:0;opacity:0;filter:alpha(opacity=0);font-size:23px;height:100%;width:100%;direction:ltr;cursor:pointer}.fileinput{margin-bottom:9px;display:inline-block}.fileinput .form-control{padding-top:7px;padding-bottom:5px;display:inline-block;margin-bottom:0;vertical-align:middle;cursor:text}.fileinput .thumbnail{overflow:hidden;display:inline-block;margin-bottom:5px;vertical-align:middle;text-align:center}.fileinput .thumbnail>img{max-height:100%}.fileinput .btn{vertical-align:middle}.fileinput-exists .fileinput-new,.fileinput-new .fileinput-exists{display:none}.fileinput-inline .fileinput-controls{display:inline}.fileinput-filename{vertical-align:middle;display:inline-block;overflow:hidden}.form-control .fileinput-filename{vertical-align:bottom}.fileinput.input-group{display:table}.fileinput.input-group>*{position:relative;z-index:2}.fileinput.input-group>.btn-file{z-index:1}.fileinput-new.input-group .btn-file,.fileinput-new .input-group .btn-file{border-radius:0 4px 4px 0}.fileinput-new.input-group .btn-file.btn-xs,.fileinput-new .input-group .btn-file.btn-xs,.fileinput-new.input-group .btn-file.btn-sm,.fileinput-new .input-group .btn-file.btn-sm{border-radius:0 3px 3px 0}.fileinput-new.input-group .btn-file.btn-lg,.fileinput-new .input-group .btn-file.btn-lg{border-radius:0 6px 6px 0}.form-group.has-warning .fileinput .fileinput-preview{color:#8a6d3b}.form-group.has-warning .fileinput .thumbnail{border-color:#faebcc}.form-group.has-error .fileinput .fileinput-preview{color:#a94442}.form-group.has-error .fileinput .thumbnail{border-color:#ebccd1}.form-group.has-success .fileinput .fileinput-preview{color:#3c763d}.form-group.has-success .fileinput .thumbnail{border-color:#d6e9c6}.input-group-addon:not(:first-child){border-left:0}
diff --git a/src/main/resources/META-INF/resources/designer/css/jquery.dataTables.css b/src/main/resources/META-INF/resources/designer/css/jquery.dataTables.css
new file mode 100644 (file)
index 0000000..4e6fbe3
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Table styles
+ */
+table.dataTable {
+  width: 100%;
+  margin: 0 auto;
+  clear: both;
+  border-collapse: separate;
+  border-spacing: 0;
+  /*
+   * Header and footer styles
+   */
+  /*
+   * Body styles
+   */
+}
+table.dataTable thead th,
+table.dataTable tfoot th {
+  font-weight: bold;
+}
+table.dataTable thead th,
+table.dataTable thead td {
+  padding: 10px 18px;
+  border-bottom: 1px solid #111111;
+}
+table.dataTable thead th:active,
+table.dataTable thead td:active {
+  outline: none;
+}
+table.dataTable tfoot th,
+table.dataTable tfoot td {
+  padding: 10px 18px 6px 18px;
+  border-top: 1px solid #111111;
+}
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc,
+table.dataTable thead .sorting {
+  cursor: pointer;
+  *cursor: hand;
+}
+table.dataTable thead .sorting {
+  background: url("../images/sort_both.png") no-repeat center right;
+}
+table.dataTable thead .sorting_asc {
+  background: url("../images/sort_asc.png") no-repeat center right;
+}
+table.dataTable thead .sorting_desc {
+  background: url("../images/sort_desc.png") no-repeat center right;
+}
+table.dataTable thead .sorting_asc_disabled {
+  background: url("../images/sort_asc_disabled.png") no-repeat center right;
+}
+table.dataTable thead .sorting_desc_disabled {
+  background: url("../images/sort_desc_disabled.png") no-repeat center right;
+}
+table.dataTable tbody tr {
+  background-color: white;
+}
+table.dataTable tbody tr.selected {
+  background-color: #b0bed9;
+}
+table.dataTable tbody th,
+table.dataTable tbody td {
+  padding: 8px 10px;
+}
+table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
+  border-top: 1px solid #dddddd;
+}
+table.dataTable.row-border tbody tr:first-child th,
+table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
+table.dataTable.display tbody tr:first-child td {
+  border-top: none;
+}
+table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
+  border-top: 1px solid #dddddd;
+  border-right: 1px solid #dddddd;
+}
+table.dataTable.cell-border tbody tr th:first-child,
+table.dataTable.cell-border tbody tr td:first-child {
+  border-left: 1px solid #dddddd;
+}
+table.dataTable.cell-border tbody tr:first-child th,
+table.dataTable.cell-border tbody tr:first-child td {
+  border-top: none;
+}
+table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
+  background-color: #f9f9f9;
+}
+table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
+  background-color: #abb9d3;
+}
+table.dataTable.hover tbody tr:hover,
+table.dataTable.hover tbody tr.odd:hover,
+table.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,
+table.dataTable.display tbody tr.odd:hover,
+table.dataTable.display tbody tr.even:hover {
+  background-color: whitesmoke;
+}
+table.dataTable.hover tbody tr:hover.selected,
+table.dataTable.hover tbody tr.odd:hover.selected,
+table.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,
+table.dataTable.display tbody tr.odd:hover.selected,
+table.dataTable.display tbody tr.even:hover.selected {
+  background-color: #a9b7d1;
+}
+table.dataTable.order-column tbody tr > .sorting_1,
+table.dataTable.order-column tbody tr > .sorting_2,
+table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
+table.dataTable.display tbody tr > .sorting_2,
+table.dataTable.display tbody tr > .sorting_3 {
+  background-color: #f9f9f9;
+}
+table.dataTable.order-column tbody tr.selected > .sorting_1,
+table.dataTable.order-column tbody tr.selected > .sorting_2,
+table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
+table.dataTable.display tbody tr.selected > .sorting_2,
+table.dataTable.display tbody tr.selected > .sorting_3 {
+  background-color: #acbad4;
+}
+table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
+  background-color: #f1f1f1;
+}
+table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
+  background-color: #f3f3f3;
+}
+table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
+  background-color: whitesmoke;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
+  background-color: #a6b3cd;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
+  background-color: #a7b5ce;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
+  background-color: #a9b6d0;
+}
+table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
+  background-color: #f9f9f9;
+}
+table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
+  background-color: #fbfbfb;
+}
+table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
+  background-color: #fdfdfd;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
+  background-color: #acbad4;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
+  background-color: #adbbd6;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
+  background-color: #afbdd8;
+}
+table.dataTable.display tbody tr:hover > .sorting_1,
+table.dataTable.display tbody tr.odd:hover > .sorting_1,
+table.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {
+  background-color: #eaeaea;
+}
+table.dataTable.display tbody tr:hover > .sorting_2,
+table.dataTable.display tbody tr.odd:hover > .sorting_2,
+table.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {
+  background-color: #ebebeb;
+}
+table.dataTable.display tbody tr:hover > .sorting_3,
+table.dataTable.display tbody tr.odd:hover > .sorting_3,
+table.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {
+  background-color: #eeeeee;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_1,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_1,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {
+  background-color: #a1aec7;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_2,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_2,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {
+  background-color: #a2afc8;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_3,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_3,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {
+  background-color: #a4b2cb;
+}
+table.dataTable.no-footer {
+  border-bottom: 1px solid #111111;
+}
+table.dataTable.nowrap th, table.dataTable.nowrap td {
+  white-space: nowrap;
+}
+table.dataTable.compact thead th,
+table.dataTable.compact thead td {
+  padding: 5px 9px;
+}
+table.dataTable.compact tfoot th,
+table.dataTable.compact tfoot td {
+  padding: 5px 9px 3px 9px;
+}
+table.dataTable.compact tbody th,
+table.dataTable.compact tbody td {
+  padding: 4px 5px;
+}
+table.dataTable th.dt-left,
+table.dataTable td.dt-left {
+  text-align: left;
+}
+table.dataTable th.dt-center,
+table.dataTable td.dt-center,
+table.dataTable td.dataTables_empty {
+  text-align: center;
+}
+table.dataTable th.dt-right,
+table.dataTable td.dt-right {
+  text-align: right;
+}
+table.dataTable th.dt-justify,
+table.dataTable td.dt-justify {
+  text-align: justify;
+}
+table.dataTable th.dt-nowrap,
+table.dataTable td.dt-nowrap {
+  white-space: nowrap;
+}
+table.dataTable thead th.dt-head-left,
+table.dataTable thead td.dt-head-left,
+table.dataTable tfoot th.dt-head-left,
+table.dataTable tfoot td.dt-head-left {
+  text-align: left;
+}
+table.dataTable thead th.dt-head-center,
+table.dataTable thead td.dt-head-center,
+table.dataTable tfoot th.dt-head-center,
+table.dataTable tfoot td.dt-head-center {
+  text-align: center;
+}
+table.dataTable thead th.dt-head-right,
+table.dataTable thead td.dt-head-right,
+table.dataTable tfoot th.dt-head-right,
+table.dataTable tfoot td.dt-head-right {
+  text-align: right;
+}
+table.dataTable thead th.dt-head-justify,
+table.dataTable thead td.dt-head-justify,
+table.dataTable tfoot th.dt-head-justify,
+table.dataTable tfoot td.dt-head-justify {
+  text-align: justify;
+}
+table.dataTable thead th.dt-head-nowrap,
+table.dataTable thead td.dt-head-nowrap,
+table.dataTable tfoot th.dt-head-nowrap,
+table.dataTable tfoot td.dt-head-nowrap {
+  white-space: nowrap;
+}
+table.dataTable tbody th.dt-body-left,
+table.dataTable tbody td.dt-body-left {
+  text-align: left;
+}
+table.dataTable tbody th.dt-body-center,
+table.dataTable tbody td.dt-body-center {
+  text-align: center;
+}
+table.dataTable tbody th.dt-body-right,
+table.dataTable tbody td.dt-body-right {
+  text-align: right;
+}
+table.dataTable tbody th.dt-body-justify,
+table.dataTable tbody td.dt-body-justify {
+  text-align: justify;
+}
+table.dataTable tbody th.dt-body-nowrap,
+table.dataTable tbody td.dt-body-nowrap {
+  white-space: nowrap;
+}
+
+table.dataTable,
+table.dataTable th,
+table.dataTable td {
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+/*
+ * Control feature layout
+ */
+.dataTables_wrapper {
+  position: relative;
+  clear: both;
+  *zoom: 1;
+  zoom: 1;
+}
+.dataTables_wrapper .dataTables_length {
+  float: left;
+}
+.dataTables_wrapper .dataTables_filter {
+  float: right;
+  text-align: right;
+}
+.dataTables_wrapper .dataTables_filter input {
+  margin-left: 0.5em;
+}
+.dataTables_wrapper .dataTables_info {
+  clear: both;
+  float: left;
+  padding-top: 0.755em;
+}
+.dataTables_wrapper .dataTables_paginate {
+  float: right;
+  text-align: right;
+  padding-top: 0.25em;
+}
+.dataTables_wrapper .dataTables_paginate .paginate_button {
+  box-sizing: border-box;
+  display: inline-block;
+  min-width: 1.5em;
+  padding: 0.5em 1em;
+  margin-left: 2px;
+  text-align: center;
+  text-decoration: none !important;
+  cursor: pointer;
+  *cursor: hand;
+  color: #333333 !important;
+  border: 1px solid transparent;
+}
+.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
+  color: #333333 !important;
+  border: 1px solid #cacaca;
+  background-color: white;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro));
+  /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);
+  /* Chrome10+,Safari5.1+ */
+  background: -moz-linear-gradient(top, white 0%, gainsboro 100%);
+  /* FF3.6+ */
+  background: -ms-linear-gradient(top, white 0%, gainsboro 100%);
+  /* IE10+ */
+  background: -o-linear-gradient(top, white 0%, gainsboro 100%);
+  /* Opera 11.10+ */
+  background: linear-gradient(to bottom, white 0%, gainsboro 100%);
+  /* W3C */
+}
+.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
+  cursor: default;
+  color: #666 !important;
+  border: 1px solid transparent;
+  background: transparent;
+  box-shadow: none;
+}
+.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
+  color: white !important;
+  border: 1px solid #111111;
+  background-color: #585858;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111111));
+  /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #585858 0%, #111111 100%);
+  /* Chrome10+,Safari5.1+ */
+  background: -moz-linear-gradient(top, #585858 0%, #111111 100%);
+  /* FF3.6+ */
+  background: -ms-linear-gradient(top, #585858 0%, #111111 100%);
+  /* IE10+ */
+  background: -o-linear-gradient(top, #585858 0%, #111111 100%);
+  /* Opera 11.10+ */
+  background: linear-gradient(to bottom, #585858 0%, #111111 100%);
+  /* W3C */
+}
+.dataTables_wrapper .dataTables_paginate .paginate_button:active {
+  outline: none;
+  background-color: #2b2b2b;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
+  /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
+  /* Chrome10+,Safari5.1+ */
+  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
+  /* FF3.6+ */
+  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
+  /* IE10+ */
+  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
+  /* Opera 11.10+ */
+  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
+  /* W3C */
+  box-shadow: inset 0 0 3px #111;
+}
+.dataTables_wrapper .dataTables_processing {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 40px;
+  margin-left: -50%;
+  margin-top: -25px;
+  padding-top: 20px;
+  text-align: center;
+  font-size: 1.2em;
+  background-color: white;
+  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
+  /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* Chrome10+,Safari5.1+ */
+  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* FF3.6+ */
+  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* IE10+ */
+  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* Opera 11.10+ */
+  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* W3C */
+}
+.dataTables_wrapper .dataTables_length,
+.dataTables_wrapper .dataTables_filter,
+.dataTables_wrapper .dataTables_info,
+.dataTables_wrapper .dataTables_processing,
+.dataTables_wrapper .dataTables_paginate {
+  color: #333333;
+}
+.dataTables_wrapper .dataTables_scroll {
+  clear: both;
+}
+.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
+  *margin-top: -1px;
+  -webkit-overflow-scrolling: touch;
+}
+.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
+.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
+  height: 0;
+  overflow: hidden;
+  margin: 0 !important;
+  padding: 0 !important;
+}
+.dataTables_wrapper.no-footer .dataTables_scrollBody {
+  border-bottom: 1px solid #111111;
+}
+.dataTables_wrapper.no-footer div.dataTables_scrollHead table,
+.dataTables_wrapper.no-footer div.dataTables_scrollBody table {
+  border-bottom: none;
+}
+.dataTables_wrapper:after {
+  visibility: hidden;
+  display: block;
+  content: "";
+  clear: both;
+  height: 0;
+}
+
+@media screen and (max-width: 767px) {
+  .dataTables_wrapper .dataTables_info,
+  .dataTables_wrapper .dataTables_paginate {
+    float: none;
+    text-align: center;
+  }
+  .dataTables_wrapper .dataTables_paginate {
+    margin-top: 0.5em;
+  }
+}
+@media screen and (max-width: 640px) {
+  .dataTables_wrapper .dataTables_length,
+  .dataTables_wrapper .dataTables_filter {
+    float: none;
+    text-align: center;
+  }
+  .dataTables_wrapper .dataTables_filter {
+    margin-top: 0.5em;
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/jquery.dataTables_themeroller.css b/src/main/resources/META-INF/resources/designer/css/jquery.dataTables_themeroller.css
new file mode 100644 (file)
index 0000000..5a56d97
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Table styles
+ */
+table.dataTable {
+  width: 100%;
+  margin: 0 auto;
+  clear: both;
+  border-collapse: separate;
+  border-spacing: 0;
+  /*
+   * Header and footer styles
+   */
+  /*
+   * Body styles
+   */
+}
+table.dataTable thead th,
+table.dataTable thead td,
+table.dataTable tfoot th,
+table.dataTable tfoot td {
+  padding: 4px 10px;
+}
+table.dataTable thead th,
+table.dataTable tfoot th {
+  font-weight: bold;
+}
+table.dataTable thead th:active,
+table.dataTable thead td:active {
+  outline: none;
+}
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc,
+table.dataTable thead .sorting {
+  cursor: pointer;
+  *cursor: hand;
+}
+table.dataTable thead th div.DataTables_sort_wrapper {
+  position: relative;
+  padding-right: 10px;
+}
+table.dataTable thead th div.DataTables_sort_wrapper span {
+  position: absolute;
+  top: 50%;
+  margin-top: -8px;
+  right: -5px;
+}
+table.dataTable thead th.ui-state-default {
+  border-right-width: 0;
+}
+table.dataTable thead th.ui-state-default:last-child {
+  border-right-width: 1px;
+}
+table.dataTable tbody tr {
+  background-color: white;
+}
+table.dataTable tbody tr.selected {
+  background-color: #b0bed9;
+}
+table.dataTable tbody th,
+table.dataTable tbody td {
+  padding: 8px 10px;
+}
+table.dataTable th.center,
+table.dataTable td.center,
+table.dataTable td.dataTables_empty {
+  text-align: center;
+}
+table.dataTable th.right,
+table.dataTable td.right {
+  text-align: right;
+}
+table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
+  border-top: 1px solid #dddddd;
+}
+table.dataTable.row-border tbody tr:first-child th,
+table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
+table.dataTable.display tbody tr:first-child td {
+  border-top: none;
+}
+table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
+  border-top: 1px solid #dddddd;
+  border-right: 1px solid #dddddd;
+}
+table.dataTable.cell-border tbody tr th:first-child,
+table.dataTable.cell-border tbody tr td:first-child {
+  border-left: 1px solid #dddddd;
+}
+table.dataTable.cell-border tbody tr:first-child th,
+table.dataTable.cell-border tbody tr:first-child td {
+  border-top: none;
+}
+table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
+  background-color: #f9f9f9;
+}
+table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
+  background-color: #abb9d3;
+}
+table.dataTable.hover tbody tr:hover,
+table.dataTable.hover tbody tr.odd:hover,
+table.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,
+table.dataTable.display tbody tr.odd:hover,
+table.dataTable.display tbody tr.even:hover {
+  background-color: whitesmoke;
+}
+table.dataTable.hover tbody tr:hover.selected,
+table.dataTable.hover tbody tr.odd:hover.selected,
+table.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,
+table.dataTable.display tbody tr.odd:hover.selected,
+table.dataTable.display tbody tr.even:hover.selected {
+  background-color: #a9b7d1;
+}
+table.dataTable.order-column tbody tr > .sorting_1,
+table.dataTable.order-column tbody tr > .sorting_2,
+table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
+table.dataTable.display tbody tr > .sorting_2,
+table.dataTable.display tbody tr > .sorting_3 {
+  background-color: #f9f9f9;
+}
+table.dataTable.order-column tbody tr.selected > .sorting_1,
+table.dataTable.order-column tbody tr.selected > .sorting_2,
+table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
+table.dataTable.display tbody tr.selected > .sorting_2,
+table.dataTable.display tbody tr.selected > .sorting_3 {
+  background-color: #acbad4;
+}
+table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
+  background-color: #f1f1f1;
+}
+table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
+  background-color: #f3f3f3;
+}
+table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
+  background-color: whitesmoke;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
+  background-color: #a6b3cd;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
+  background-color: #a7b5ce;
+}
+table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
+  background-color: #a9b6d0;
+}
+table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
+  background-color: #f9f9f9;
+}
+table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
+  background-color: #fbfbfb;
+}
+table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
+  background-color: #fdfdfd;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
+  background-color: #acbad4;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
+  background-color: #adbbd6;
+}
+table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
+  background-color: #afbdd8;
+}
+table.dataTable.display tbody tr:hover > .sorting_1,
+table.dataTable.display tbody tr.odd:hover > .sorting_1,
+table.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {
+  background-color: #eaeaea;
+}
+table.dataTable.display tbody tr:hover > .sorting_2,
+table.dataTable.display tbody tr.odd:hover > .sorting_2,
+table.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {
+  background-color: #ebebeb;
+}
+table.dataTable.display tbody tr:hover > .sorting_3,
+table.dataTable.display tbody tr.odd:hover > .sorting_3,
+table.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,
+table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,
+table.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {
+  background-color: #eeeeee;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_1,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_1,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {
+  background-color: #a1aec7;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_2,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_2,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {
+  background-color: #a2afc8;
+}
+table.dataTable.display tbody tr:hover.selected > .sorting_3,
+table.dataTable.display tbody tr.odd:hover.selected > .sorting_3,
+table.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,
+table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,
+table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {
+  background-color: #a4b2cb;
+}
+
+table.dataTable,
+table.dataTable th,
+table.dataTable td {
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+/*
+ * Control feature layout
+ */
+.dataTables_wrapper {
+  position: relative;
+  clear: both;
+  *zoom: 1;
+  zoom: 1;
+}
+.dataTables_wrapper .dataTables_length {
+  float: left;
+}
+.dataTables_wrapper .dataTables_filter {
+  float: right;
+  text-align: right;
+}
+.dataTables_wrapper .dataTables_filter input {
+  margin-left: 0.5em;
+}
+.dataTables_wrapper .dataTables_info {
+  clear: both;
+  float: left;
+  padding-top: 0.55em;
+}
+.dataTables_wrapper .dataTables_paginate {
+  float: right;
+  text-align: right;
+}
+.dataTables_wrapper .dataTables_paginate .fg-button {
+  box-sizing: border-box;
+  display: inline-block;
+  min-width: 1.5em;
+  padding: 0.5em;
+  margin-left: 2px;
+  text-align: center;
+  text-decoration: none !important;
+  cursor: pointer;
+  *cursor: hand;
+  color: #333333 !important;
+  border: 1px solid transparent;
+}
+.dataTables_wrapper .dataTables_paginate .fg-button:active {
+  outline: none;
+}
+.dataTables_wrapper .dataTables_paginate .fg-button:first-child {
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.dataTables_wrapper .dataTables_paginate .fg-button:last-child {
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
+.dataTables_wrapper .dataTables_processing {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 40px;
+  margin-left: -50%;
+  margin-top: -25px;
+  padding-top: 20px;
+  text-align: center;
+  font-size: 1.2em;
+  background-color: white;
+  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
+  /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* Chrome10+,Safari5.1+ */
+  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* FF3.6+ */
+  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* IE10+ */
+  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* Opera 11.10+ */
+  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
+  /* W3C */
+}
+.dataTables_wrapper .dataTables_length,
+.dataTables_wrapper .dataTables_filter,
+.dataTables_wrapper .dataTables_info,
+.dataTables_wrapper .dataTables_processing,
+.dataTables_wrapper .dataTables_paginate {
+  color: #333333;
+}
+.dataTables_wrapper .dataTables_scroll {
+  clear: both;
+}
+.dataTables_wrapper .dataTables_scrollBody {
+  *margin-top: -1px;
+  -webkit-overflow-scrolling: touch;
+}
+.dataTables_wrapper .ui-widget-header {
+  font-weight: normal;
+}
+.dataTables_wrapper .ui-toolbar {
+  padding: 8px;
+}
+.dataTables_wrapper:after {
+  visibility: hidden;
+  display: block;
+  content: "";
+  clear: both;
+  height: 0;
+}
+
+@media screen and (max-width: 767px) {
+  .dataTables_wrapper .dataTables_length,
+  .dataTables_wrapper .dataTables_filter,
+  .dataTables_wrapper .dataTables_info,
+  .dataTables_wrapper .dataTables_paginate {
+    float: none;
+    text-align: center;
+  }
+  .dataTables_wrapper .dataTables_filter,
+  .dataTables_wrapper .dataTables_paginate {
+    margin-top: 0.5em;
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/kendo.common-material.core.css b/src/main/resources/META-INF/resources/designer/css/kendo.common-material.core.css
new file mode 100644 (file)
index 0000000..13d876f
--- /dev/null
@@ -0,0 +1,6456 @@
+/* Kendo base CSS */
+.fake {
+  color: red;
+}
+.k-common-test-class {
+  opacity: 0;
+}
+.k-reset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  outline: 0;
+  text-decoration: none;
+  font-size: 100%;
+  list-style: none;
+}
+.k-floatwrap:after,
+.k-slider-items:after,
+.k-grid-toolbar:after {
+  content: "";
+  display: block;
+  clear: both;
+  visibility: hidden;
+  height: 0;
+  overflow: hidden;
+}
+.k-floatwrap,
+.k-slider-items,
+.k-grid-toolbar {
+  display: inline-block;
+}
+.k-floatwrap,
+.k-slider-items,
+.k-grid-toolbar {
+  display: block;
+}
+/* main gradient */
+.k-block,
+.k-button,
+.k-header,
+.k-grid-header,
+.k-toolbar,
+.k-grouping-header,
+.k-tooltip,
+.k-pager-wrap,
+.k-tabstrip-items .k-item,
+.k-link.k-state-hover,
+.k-textbox,
+.k-textbox:hover,
+.k-autocomplete,
+.k-dropdown-wrap,
+.k-picker-wrap,
+.k-numeric-wrap,
+.k-autocomplete.k-state-hover,
+.k-dropdown-wrap.k-state-hover,
+.k-picker-wrap.k-state-hover,
+.k-numeric-wrap.k-state-hover,
+.k-draghandle {
+  background-repeat: repeat;
+  background-position: 0 center;
+}
+.k-link:hover {
+  text-decoration: none;
+}
+.k-state-highlight > .k-link {
+  color: inherit;
+}
+/* widget */
+.k-textbox > input,
+.k-input[type="text"],
+.k-input[type="number"],
+.k-textbox,
+.k-picker-wrap .k-input,
+.k-button {
+  font-size: 100%;
+  font-family: inherit;
+  border-style: solid;
+  border-width: 1px;
+  -webkit-appearance: none;
+}
+.k-widget,
+.k-block,
+.k-inline-block,
+.k-draghandle {
+  border-style: solid;
+  border-width: 1px;
+  -webkit-appearance: none;
+}
+.k-block,
+.k-widget {
+  line-height: normal;
+  outline: 0;
+}
+.k-widget .k-input::-ms-clear,
+.k-list-filter ::-ms-clear {
+  width: 0;
+  height: 0;
+}
+/* Block */
+.k-block {
+  padding: 2px;
+}
+/* button */
+.k-button {
+  display: inline-block;
+  margin: 0;
+  padding: 10px 14px;
+  font-family: inherit;
+  line-height: 1.72em;
+  text-align: center;
+  cursor: pointer;
+  text-decoration: none;
+}
+.k-button[disabled],
+.k-button.k-state-disabled,
+.k-state-disabled .k-button,
+.k-state-disabled .k-button:hover,
+.k-button.k-state-disabled:hover,
+.k-state-disabled .k-button:active,
+.k-button.k-state-disabled:active {
+  cursor: default;
+}
+a.k-button {
+  user-select: none;
+  text-decoration: none;
+}
+/* Override the important default line-height in Firefox 4+ */
+.k-ff input.k-button {
+  padding-bottom: 0.37em;
+  padding-top: 0.37em;
+}
+button.k-button::-moz-focus-inner,
+input.k-button::-moz-focus-inner {
+  padding: 0;
+  border: 0;
+}
+a.k-button-expand {
+  display: block;
+}
+button.k-button-expand,
+input[type="submit"].k-button-expand,
+input[type="button"].k-button-expand,
+input[type="reset"].k-button-expand {
+  width: 100%;
+}
+body .k-button-icon,
+body .k-split-button-arrow {
+  padding-left: .4em;
+  padding-right: .4em;
+}
+.k-button-icontext {
+  overflow: visible;
+  /*IE9*/
+}
+.k-toolbar .k-button-icontext {
+  padding-right: .8em;
+}
+.k-button-icontext .k-icon,
+.k-button-icontext .k-image,
+.k-button-icontext .k-sprite {
+  margin-right: 3px;
+  margin-right: .3rem;
+  margin-left: -3px;
+  margin-left: -0.3rem;
+}
+.k-button.k-button-icontext .k-icon,
+.k-button.k-button-icontext .k-image {
+  vertical-align: text-top;
+}
+.k-button.k-bare {
+  border-color: transparent !important;
+  color: inherit;
+  background: none !important;
+  box-shadow: none !important;
+  opacity: .7;
+}
+.k-button.k-bare:hover,
+.k-button.k-bare.k-state-hover,
+.k-button.k-bare:active,
+.k-button.k-bare.k-state-active,
+.k-button.k-bare.k-state-active:hover {
+  color: inherit;
+}
+.k-button.k-bare:focus,
+.k-button.k-bare .k-state-focused {
+  opacity: .8;
+}
+.k-button.k-bare:hover,
+.k-button.k-bare.k-state-hover,
+.k-button.k-bare:active,
+.k-button.k-bare.k-state-active {
+  opacity: 1;
+}
+.k-button.k-bare .k-icon,
+.k-button.k-bare .k-font-icon {
+  overflow: visible;
+}
+.k-button.k-bare:focus .k-icon,
+.k-button.k-bare .k-state-focused .k-icon,
+.k-button.k-bare:focus .k-font-icon,
+.k-button.k-bare .k-state-focused .k-font-icon {
+  text-shadow: 0 0 3px currentColor;
+}
+/* link */
+.k-link {
+  cursor: pointer;
+  outline: 0;
+  text-decoration: none;
+}
+.k-grid-header span.k-link {
+  cursor: default;
+}
+/* states */
+.k-state-disabled,
+.k-state-disabled .k-link,
+.k-state-disabled .k-icon,
+.k-state-disabled .k-button,
+.k-state-disabled .k-draghandle,
+.k-state-disabled .k-upload-button input {
+  cursor: default !important;
+  outline: 0;
+}
+@media print {
+  .k-state-disabled,
+  .k-state-disabled .k-input {
+    opacity: 1 !important;
+  }
+}
+.k-state-error {
+  border-style: ridge;
+}
+.k-state-empty {
+  font-style: italic;
+}
+/* icons */
+.k-icon.k-i-none {
+  background-image: none !important;
+  /* should never be a background on these */
+}
+/* In IE7 vertical align: middle can't be overridden */
+.k-ie8 .k-icon,
+.k-ie8 .k-sprite,
+.k-ie8 .k-tool-icon {
+  vertical-align: middle;
+}
+.k-file > .k-icon {
+  background-position: -115px -91px;
+}
+.k-image {
+  border: 0;
+}
+/* Colors */
+html .k-success-colored {
+  color: #507f50;
+  border-color: #d0dfd0;
+  background-color: #f0fff0;
+}
+html .k-info-colored {
+  color: #50607f;
+  border-color: #d0d9df;
+  background-color: #f0f9ff;
+}
+html .k-error-colored {
+  color: #7f5050;
+  border-color: #dfd0d0;
+  background-color: #fff0f0;
+}
+.k-inline-block {
+  padding: 0 2px;
+}
+/* loading */
+.k-loading,
+.k-loading-image {
+  background-color: transparent;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.k-icon.k-i-loading {
+  background-color: transparent;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.k-icon.k-i-loading::before {
+  content: "";
+  display: none;
+}
+.k-loading-mask,
+.k-loading-image,
+.k-loading-text {
+  position: absolute;
+}
+.k-loading-mask {
+  z-index: 100;
+}
+.k-loading-mask .k-loading-progress {
+  margin: auto;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+}
+.k-loading-text {
+  text-indent: -4000px;
+  text-align: center;
+  /*rtl*/
+}
+.k-loading-image,
+.k-loading-color {
+  width: 100%;
+  height: 100%;
+}
+.k-loading-image {
+  top: 0;
+  left: 0;
+  z-index: 2;
+}
+.k-loading-color {
+  filter: alpha(opacity=30);
+  opacity: .3;
+}
+.k-content-frame {
+  border: 0;
+  width: 100%;
+  height: 100%;
+}
+.k-pane > .k-splitter-overlay {
+  filter: alpha(opacity=0);
+  opacity: 0;
+  position: absolute;
+}
+/* drag n drop */
+.k-drag-clue {
+  position: absolute;
+  z-index: 10003;
+  border-style: solid;
+  border-width: 1px;
+  font-size: .9em;
+  padding: .2em .4em;
+  white-space: nowrap;
+  cursor: default;
+}
+/* ListBox Drag Clue */
+.k-item.k-drag-clue {
+  font-size: inherit;
+}
+.k-drag-status {
+  margin-top: -3px;
+  margin-right: 4px;
+  vertical-align: middle;
+}
+.k-reorder-cue {
+  position: absolute;
+  width: 1px;
+  overflow: visible;
+}
+.k-reorder-cue .k-icon {
+  position: absolute;
+  left: -4px;
+  width: 8px;
+  height: 4px;
+}
+.k-reorder-cue .k-i-arrow-60-down {
+  top: -4px;
+  background-position: -4px -166px;
+}
+.k-reorder-cue .k-i-arrow-60-up {
+  bottom: -4px;
+  background-position: -4px -134px;
+}
+/* virtual scrollbar */
+.k-scrollbar {
+  position: absolute;
+  overflow: scroll;
+}
+.k-scrollbar-vertical {
+  top: 0;
+  right: 0;
+  width: 17px;
+  /* scrollbar width */
+  height: 100%;
+  overflow-x: hidden;
+}
+.k-touch-scrollbar {
+  display: none;
+  position: absolute;
+  z-index: 200000;
+  height: 8px;
+  width: 8px;
+  border: 1px solid #8a8a8a;
+  background-color: #858585;
+}
+@media only screen and (-webkit-min-device-pixel-ratio: 2) {
+  body .k-touch-scrollbar {
+    height: 12px;
+    width: 12px;
+    border-radius: 7px;
+  }
+}
+.k-virtual-scrollable-wrap {
+  overflow-x: auto;
+  /*needed by IE8*/
+}
+/* current time indicator */
+.k-current-time {
+  background: #f00;
+  position: absolute;
+}
+.k-current-time-arrow-down {
+  width: 0;
+  height: 0;
+  background: transparent;
+  border-bottom: 4px solid  transparent;
+  border-top: 4px solid #f00;
+  border-left: 4px solid transparent;
+  border-right: 4px solid transparent;
+}
+.k-current-time-arrow-left {
+  width: 0;
+  height: 0;
+  background: transparent;
+  border-bottom: 4px solid  transparent;
+  border-top: 4px solid transparent;
+  border-left: 4px solid transparent;
+  border-right: 4px solid #f00;
+}
+.k-current-time-arrow-right {
+  width: 0;
+  height: 0;
+  background: transparent;
+  border-bottom: 4px solid  transparent;
+  border-top: 4px solid transparent;
+  border-left: 4px solid #f00;
+  border-right: 4px solid transparent;
+}
+/* override box sizing for grid layout framework integration (Bootstrap 3, Foundation 4) */
+.k-animation-container,
+.k-widget,
+.k-widget *,
+.k-animation-container *,
+.k-widget *:before,
+.k-animation-container *:after,
+.k-block .k-header,
+.k-list-container,
+div.k-window-content {
+  box-sizing: content-box;
+}
+.k-button,
+.k-textbox,
+.k-autocomplete,
+.k-tabstrip > .k-content > .km-scroll-container,
+.k-block,
+.k-edit-cell .k-widget,
+.k-grid-edit-row .k-widget,
+.k-grid-edit-row .text-box,
+.km-actionsheet > li,
+.km-shim {
+  box-sizing: border-box;
+}
+/* Fix for Bootstrap 3 */
+.input-group .form-control {
+  box-sizing: border-box;
+}
+.form-control.k-widget {
+  padding: 0;
+}
+a.k-button:hover {
+  text-decoration: none;
+}
+/* override iOS styles in mobile Kendo */
+.km-widget,
+.km-widget * {
+  -moz-background-clip: border-box;
+  -webkit-background-clip: border-box;
+  background-clip: border-box;
+}
+input.k-checkbox,
+.k-radio {
+  display: inline;
+  opacity: 0;
+  width: 0;
+  margin: 0;
+  -webkit-appearance: none;
+  overflow: hidden;
+}
+.k-ff input.k-checkbox,
+.k-ff .k-radio {
+  position: absolute;
+}
+.k-checkbox-label,
+.k-radio-label {
+  display: inline-block;
+  position: relative;
+  padding-left: 20px;
+  vertical-align: text-top;
+  line-height: 16px;
+  cursor: pointer;
+  border-style: solid;
+  border-width: 0;
+}
+.k-checkbox-label:before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  border-width: 1px;
+  border-style: solid;
+  width: 16px;
+  height: 16px;
+  font-size: 16px;
+  line-height: 16px;
+  text-align: center;
+}
+.k-checkbox:indeterminate + .k-checkbox-label:after {
+  content: "";
+  position: absolute;
+  left: 8px;
+  top: 8px;
+  -webkit-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  border-width: 1px;
+  border-style: solid;
+  width: 8px;
+  height: 8px;
+  font-size: 16px;
+  text-align: center;
+  content: " ";
+}
+.k-checkbox:checked + .k-checkbox-label:before {
+  content: "\2713";
+}
+.k-checkbox:disabled + .k-checkbox-label {
+  cursor: auto;
+}
+.k-radio-label:before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 14px;
+  height: 14px;
+  border-style: solid;
+}
+.k-radio:checked + .k-radio-label:after {
+  content: "";
+  width: 10px;
+  height: 10px;
+  position: absolute;
+  top: 3px;
+  left: 3px;
+}
+.k-radio:disabled + .k-radio-label {
+  cursor: auto;
+}
+.k-ie8 input.k-checkbox,
+.k-ie8 .k-radio {
+  display: inline-block;
+  width: auto;
+}
+.k-ie8 .k-checkbox-label,
+.k-ie8 .k-radio-label {
+  padding-left: 0;
+}
+.k-ie8 .k-checkbox-label:before,
+.k-ie8 .k-radio-label:before,
+.k-ie8 .k-radio-label:after {
+  display: none;
+}
+/* RTL for checkboxes and radio buttons */
+.k-rtl .k-checkbox-label,
+.k-rtl .k-radio-label {
+  padding-right: 1.5em;
+}
+.k-rtl .k-checkbox-label:before,
+.k-rtl .k-radio-label:before {
+  right: 0;
+}
+.k-rtl .k-radio:checked + .k-radio-label:after {
+  right: 3px;
+}
+input.k-checkbox + label {
+  -webkit-user-select: none;
+}
+/* Off-screen container used during export */
+.k-pdf-export-shadow {
+  position: absolute;
+  overflow: hidden;
+  left: -15000px;
+  width: 14400px;
+}
+.km-native-scroller {
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+  -ms-touch-action: pan-x pan-y;
+  -ms-overflow-style: -ms-autohiding-scrollbar;
+  -ms-scroll-snap-type: proximity;
+}
+/* Font Icons */
+.k-icon,
+.k-font-icon,
+.k-font-icon.k-icon,
+.k-font-icon.k-tool-icon {
+  position: relative;
+  display: inline-block;
+  overflow: hidden;
+  width: 1em;
+  height: 1em;
+  text-align: center;
+  vertical-align: middle;
+  background-image: none;
+  font: 16px/1 'WebComponentsIcons';
+  speak: none;
+  font-variant: normal;
+  text-transform: none;
+  text-indent: 0;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  overflow: visible;
+  color: inherit;
+}
+.k-icon:before,
+.k-font-icon:before {
+  width: 1em;
+  height: 1em;
+  display: inline-block;
+}
+.k-icon,
+.k-tool-icon,
+.k-i-drag-and-drop,
+.k-column-menu .k-sprite,
+.k-grid-mobile .k-resize-handle-inner:before,
+.k-grid-mobile .k-resize-handle-inner:after,
+.k-pager-numbers .k-current-page .k-link:after,
+.k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link:after,
+.k-gantt-views > .k-current-view > .k-link:after {
+  position: relative;
+  display: inline-block;
+  overflow: hidden;
+  width: 1em;
+  height: 1em;
+  text-align: center;
+  vertical-align: middle;
+  background-image: none;
+  font: 16px/1 'WebComponentsIcons';
+  speak: none;
+  font-variant: normal;
+  text-transform: none;
+  text-indent: 0;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+.k-icon:before {
+  width: initial;
+  height: initial;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  margin: auto;
+  height: 1em;
+  line-height: 1;
+}
+.k-button.k-button-icon .k-icon,
+.k-grid-filter .k-icon,
+.k-header .k-icon {
+  text-indent: -99999px;
+}
+.k-button.k-button-icon .k-icon:before,
+.k-grid-filter .k-icon:before,
+.k-header .k-icon:before {
+  text-indent: 0;
+}
+/* Sprite icons */
+.k-sprite {
+  width: 16px;
+  height: 16px;
+  font-size: 0;
+  line-height: 0;
+  text-align: center;
+  background-repeat: no-repeat;
+  background-color: transparent;
+  display: inline-block;
+  overflow: hidden;
+  -ms-high-contrast-adjust: none;
+}
+/* responsive panel */
+.k-rpanel-left {
+  -webkit-transform: translateX(-100%) translateZ(0);
+  -ms-transform: translateX(-100%) translateZ(0);
+  transform: translateX(-100%) translateZ(0);
+  left: 0;
+}
+.k-rpanel-right {
+  -webkit-transform: translateX(100%) translateZ(0);
+  -ms-transform: translateX(100%) translateZ(0);
+  transform: translateX(100%) translateZ(0);
+  right: 0;
+}
+.k-rpanel-left,
+.k-rpanel-right {
+  position: fixed;
+  display: block;
+  overflow: auto;
+  min-width: 320px;
+  height: 100%;
+  top: 0;
+}
+.k-rpanel-left.k-rpanel-expanded,
+.k-rpanel-right.k-rpanel-expanded {
+  -webkit-transform: translateX(0) translateZ(0);
+  -ms-transform: translateX(0) translateZ(0);
+  transform: translateX(0) translateZ(0);
+}
+.k-rpanel-left + *,
+.k-rpanel-right + * {
+  overflow: auto;
+}
+.k-ie9 .k-rpanel-left {
+  left: -100%;
+}
+.k-ie9 .k-rpanel-left.k-rpanel-expanded {
+  left: 0;
+}
+.k-rpanel-top {
+  position: static;
+  max-height: 0;
+}
+.k-rpanel-top.k-rpanel-expanded {
+  max-height: 568px;
+  overflow: visible !important;
+}
+.k-edit-form {
+  margin: 0;
+  padding: 0;
+}
+.k-window > div.k-popup-edit-form {
+  padding: 1em 0;
+}
+.k-grid-edit-row .k-edit-form td {
+  border-bottom-width: 0;
+}
+.k-edit-form-container {
+  position: relative;
+  width: 400px;
+}
+.k-edit-label,
+.k-edit-form-container .editor-label {
+  float: left;
+  clear: both;
+  width: 30%;
+  padding: .4em 0 1em;
+  margin-left: 2%;
+  text-align: right;
+}
+.k-edit-field,
+.k-edit-form-container .editor-field {
+  float: right;
+  clear: right;
+  width: 60%;
+  margin-right: 2%;
+  padding: 0 0 .6em;
+}
+.k-edit-field > input[type="checkbox"],
+.k-edit-field > input[type="radio"] {
+  margin-top: .4em;
+}
+.k-edit-form-container .k-button {
+  margin: 0 .16em;
+}
+.k-edit-field > input[type="checkbox"]:first-child,
+.k-edit-field > input[type="radio"]:first-child,
+.k-edit-field > label:first-child > input[type="checkbox"],
+.k-edit-field > .k-button:first-child {
+  margin-left: 0;
+}
+.k-edit-form-container .k-edit-buttons {
+  clear: both;
+  text-align: right;
+  border-width: 1px 0 0;
+  border-style: solid;
+  position: relative;
+  bottom: -1em;
+  padding: .6em;
+}
+/* Window */
+div.k-window {
+  display: inline-block;
+  position: absolute;
+  z-index: 10001;
+  border-style: solid;
+  border-width: 1px;
+  padding-top: 2em;
+}
+.k-block > .k-header,
+.k-window-titlebar {
+  position: absolute;
+  width: 100%;
+  height: 1.1em;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  margin-top: -2em;
+  padding: .4em 0;
+  font-size: 1.2em;
+  white-space: nowrap;
+  min-height: 16px;
+  /* icon size */
+}
+.k-block > .k-header {
+  position: relative;
+  margin: -2px 0 10px -2px;
+  padding: .3em 2px;
+}
+.k-window-title {
+  position: absolute;
+  left: .44em;
+  right: .44em;
+  overflow: hidden;
+  cursor: default;
+  text-overflow: ellipsis;
+}
+.k-window-title .k-image {
+  margin: 0 5px 0 0;
+  vertical-align: middle;
+}
+div.k-window-titleless {
+  padding-top: 0;
+}
+div.k-window-content {
+  position: relative;
+  height: 100%;
+  padding: .58em;
+  overflow: auto;
+  outline: 0;
+}
+div.k-window-iframecontent {
+  padding: 0;
+  overflow: visible;
+}
+.k-window-content > .km-scroll-container {
+  height: 100%;
+}
+.k-window-titlebar .k-window-actions {
+  position: absolute;
+  top: 0;
+  right: .3em;
+  padding-top: .3em;
+  white-space: nowrap;
+}
+.k-window-titlebar .k-window-action {
+  width: 22px;
+  height: 22px;
+  padding: 2px;
+}
+.k-window-action .k-icon {
+  margin: 0;
+  vertical-align: top;
+}
+.k-window > .k-resize-handle {
+  position: absolute;
+  z-index: 1;
+  background-color: #fff;
+  font-size: 0;
+  line-height: 6px;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  zoom: 1;
+}
+.k-resize-n {
+  top: -3px;
+  left: 0;
+  width: 100%;
+  height: 6px;
+  cursor: n-resize;
+}
+.k-resize-e {
+  top: 0;
+  right: -3px;
+  width: 6px;
+  height: 100%;
+  cursor: e-resize;
+}
+.k-resize-s {
+  bottom: -3px;
+  left: 0;
+  width: 100%;
+  height: 6px;
+  cursor: s-resize;
+}
+.k-resize-w {
+  top: 0;
+  left: -3px;
+  width: 6px;
+  height: 100%;
+  cursor: w-resize;
+}
+.k-resize-se {
+  bottom: -3px;
+  right: -3px;
+  width: 6px;
+  height: 6px;
+  cursor: se-resize;
+}
+.k-resize-sw {
+  bottom: -3px;
+  left: -3px;
+  width: 6px;
+  height: 6px;
+  cursor: sw-resize;
+}
+.k-resize-ne {
+  top: -3px;
+  right: -3px;
+  width: 6px;
+  height: 6px;
+  cursor: ne-resize;
+}
+.k-resize-nw {
+  top: -3px;
+  left: -3px;
+  width: 6px;
+  height: 6px;
+  cursor: nw-resize;
+}
+.k-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 10001;
+  width: 100%;
+  height: 100%;
+  background-color: #000;
+  filter: alpha(opacity=50);
+  opacity: .5;
+}
+.k-window .k-overlay {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  filter: alpha(opacity=0);
+  opacity: 0;
+}
+.k-action-buttons {
+  clear: both;
+  text-align: right;
+  border-width: 1px 0 0;
+  border-style: solid;
+  position: relative;
+  bottom: -1em;
+  padding: .6em;
+  margin: 0 -1em;
+}
+.k-action-buttons .k-button {
+  display: inline-block;
+  margin: 0 0 0 6px;
+  min-width: 75px;
+}
+/* TabStrip */
+.k-tabstrip {
+  margin: 0;
+  padding: 0;
+  zoom: 1;
+  position: relative;
+}
+.k-tabstrip-items {
+  padding: 0.3em 0.3em 0;
+}
+.k-tabstrip-scrollable .k-tabstrip-items {
+  white-space: nowrap;
+  overflow: hidden;
+}
+.k-tabstrip > .k-button {
+  position: absolute;
+  top: .4em;
+  z-index: 2;
+  user-select: none;
+}
+.k-tabstrip-bottom > .k-button {
+  top: auto;
+  bottom: .4em;
+}
+.k-tabstrip-prev {
+  left: .4em;
+}
+.k-tabstrip-next {
+  right: .4em;
+}
+.k-tabstrip-items .k-item,
+.k-panelbar .k-tabstrip-items .k-item {
+  list-style-type: none;
+  display: inline-block;
+  position: relative;
+  border-style: solid;
+  border-width: 1px 1px 0;
+  margin: 0 -1px 0 0;
+  padding: 0;
+  vertical-align: top;
+}
+.k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-items .k-state-active {
+  margin-bottom: -1px;
+  padding-bottom: 1px;
+}
+.k-tabstrip-top .k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-top .k-tabstrip-items .k-state-active {
+  border-bottom-width: 1px;
+  margin-bottom: -2px;
+  padding-bottom: 0px;
+}
+.k-tabstrip-items .k-tab-on-top {
+  z-index: 1;
+}
+.k-tabstrip-items .k-link,
+.k-panelbar .k-tabstrip-items .k-link {
+  display: inline-block;
+  border-bottom-width: 0;
+  padding: .5em .92em;
+}
+.k-tabstrip-items .k-icon,
+.k-panelbar .k-tabstrip-items .k-icon {
+  margin: -1px 4px 0 -3px;
+  vertical-align: top;
+}
+.k-tabstrip-items .k-item .k-image,
+.k-tabstrip-items .k-item .k-sprite,
+.k-panelbar .k-tabstrip-items .k-item .k-image,
+.k-panelbar .k-tabstrip-items .k-item .k-sprite {
+  margin: -3px 3px 0 -6px;
+  vertical-align: middle;
+}
+/* TabStrip Loading Progress */
+.k-tabstrip-items .k-loading {
+  top: 0;
+  left: 0;
+  height: 0;
+  width: 20%;
+  position: absolute;
+  background: transparent;
+  border-top: 1px solid transparent;
+  border-color: inherit;
+  transition: width 200ms linear;
+  transition: "width 200ms linear";
+  animation: k-tab-loader 1s ease-in-out infinite;
+}
+.k-tabstrip-items .k-progress {
+  animation: none;
+}
+.k-tabstrip-items .k-loading.k-complete {
+  width: 100%;
+  animation: none;
+}
+.k-tabstrip > .k-content,
+.k-panelbar .k-tabstrip > .k-content {
+  position: static;
+  border-style: solid;
+  border-width: 1px;
+  margin: 0 .286em .3em;
+  padding: .92em;
+  zoom: 1;
+}
+.k-tabstrip > .k-content {
+  display: none;
+  overflow: auto;
+}
+.k-tabstrip > .k-content.km-scroll-wrapper {
+  padding: 0;
+}
+.k-tabstrip > .k-content > .km-scroll-container {
+  padding: .3em .92em;
+}
+@keyframes k-tab-loader {
+  0% {
+    left: 0;
+  }
+  50% {
+    left: 80%;
+  }
+  100% {
+    left: 0;
+  }
+}
+/* left and right tabs */
+.k-tabstrip-left > div.k-content,
+.k-tabstrip-right > div.k-content {
+  margin: .286em .3em;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-item,
+.k-tabstrip-right > .k-tabstrip-items .k-item {
+  display: block;
+  margin-bottom: -1px;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-link,
+.k-tabstrip-right > .k-tabstrip-items .k-link {
+  display: block;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-right > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-left > .k-tabstrip-items .k-state-active,
+.k-tabstrip-right > .k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-left > .k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-right > .k-tabstrip-items .k-state-active {
+  margin-bottom: -1px;
+  padding-bottom: 0;
+}
+/* left tabs */
+.k-tabstrip-left > .k-tabstrip-items {
+  float: left;
+  padding: .25em 0 .3em .3em;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-item {
+  border-width: 1px 0 1px 1px;
+  border-radius: 3px 0 0 3px;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-state-active {
+  border-width: 1px 0 1px 1px;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-left > .k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-left > .k-tabstrip-items .k-state-active {
+  margin-right: -2px;
+  padding-right: 1px;
+}
+/* right tabs */
+.k-tabstrip-right > .k-tabstrip-items {
+  float: right;
+  padding: .25em .3em .3em 0;
+}
+.k-tabstrip-right > .k-tabstrip-items .k-item {
+  border-width: 1px 1px 1px 0;
+  border-radius: 0 3px 3px 0;
+}
+.k-tabstrip-right > .k-tabstrip-items .k-state-active {
+  border-width: 1px 1px 1px 0;
+}
+.k-tabstrip-right > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-right > .k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-right > .k-tabstrip-items .k-state-active {
+  margin-left: -1px;
+  padding-left: 1px;
+}
+/* bottom tabs */
+.k-tabstrip-bottom > .k-tabstrip-items {
+  margin-top: -1px;
+  padding: 0 .3em .3em;
+}
+.k-tabstrip-bottom > .k-content,
+.k-panelbar .k-tabstrip-bottom > .k-content {
+  margin: .3em .286em 0;
+  z-index: 1;
+  position: relative;
+}
+.k-tabstrip-bottom > .k-tabstrip-items .k-item {
+  border-width: 0 1px 1px;
+  border-radius: 0 0 4px 4px;
+}
+.k-tabstrip-bottom > .k-tabstrip-items .k-state-active {
+  margin-bottom: 0;
+  padding-bottom: 0;
+}
+.k-tabstrip-bottom > .k-content {
+  min-height: 100px;
+}
+.k-tabstrip-bottom > .k-tabstrip-items .k-loading {
+  top: auto;
+  bottom: 0;
+}
+/* PanelBar */
+.k-panelbar {
+  zoom: 1;
+}
+.k-panelbar > .k-item,
+.k-panel > .k-item {
+  list-style-type: none;
+  display: block;
+  border-width: 0;
+  margin: 0;
+  zoom: 1;
+  border-radius: 0;
+}
+.k-panelbar .k-link > .k-image,
+.k-panelbar .k-link > .k-sprite {
+  float: left;
+  margin-top: 4px;
+  margin-right: 5px;
+  vertical-align: middle;
+}
+.k-panelbar > .k-item > .k-link,
+.k-panel > .k-item > .k-link {
+  display: block;
+  position: relative;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  padding: 0 1em;
+  line-height: 2.34em;
+  text-decoration: none;
+  zoom: 1;
+}
+.k-panelbar-expand.k-icon,
+.k-panelbar-collapse.k-icon {
+  position: absolute;
+  top: 50%;
+  right: 4px;
+  margin-top: -8px;
+}
+.k-panelbar .k-panel,
+.k-panelbar .k-content {
+  position: relative;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  margin: 0;
+  padding: 0;
+  zoom: 1;
+}
+.k-panel > .k-item > .k-link {
+  border-bottom: 0;
+  font-size: .95em;
+  line-height: 2.2;
+}
+.k-panel .k-panel > .k-item > .k-link {
+  padding-left: 2em;
+}
+.k-panelbar .k-i-arrow-end-right .k-link {
+  border-bottom: 0;
+}
+.k-panel .k-panel {
+  border-bottom: 0;
+}
+.k-pager-wrap {
+  clear: both;
+  overflow: hidden;
+  position: relative;
+  border-style: solid;
+  border-width: 1px;
+  line-height: 2.0em;
+  padding: 0.333em 0 0.333em 0.250em;
+}
+.k-pager-numbers .k-link,
+.k-pager-numbers .k-state-selected {
+  display: inline-block;
+  vertical-align: top;
+  margin-right: 1px;
+}
+.k-pager-numbers {
+  margin: 0 2px;
+}
+.k-pager-numbers .k-state-selected {
+  vertical-align: top;
+}
+.k-pager-numbers .k-current-page {
+  display: none;
+}
+.k-pager-numbers li,
+.k-pager-input {
+  float: left;
+}
+.k-pager-info {
+  float: right;
+  padding: 0 1.333em;
+}
+.k-pager-numbers .k-link {
+  text-decoration: none;
+}
+.k-pager-wrap > .k-link,
+.k-pager-numbers .k-link,
+.k-pager-numbers .k-state-selected {
+  min-width: 2em;
+}
+.k-pager-wrap > .k-link {
+  float: left;
+  margin: 0 0.08333em;
+  height: 2em;
+  /*IE7*/
+  line-height: 2em;
+  /*IE7*/
+  border-radius: 1.0833em;
+  cursor: pointer;
+  text-align: center;
+}
+.k-pager-wrap > a.k-state-disabled:hover {
+  background: none;
+  cursor: default;
+}
+.k-pager-numbers .k-link {
+  text-align: center;
+  line-height: 2em;
+  border-style: solid;
+  border-width: 1px;
+  border-radius: 1.0833em;
+}
+.k-pager-wrap > .k-link {
+  border-style: solid;
+  border-width: 1px;
+}
+.k-pager-wrap .k-pager-refresh {
+  float: right;
+  margin-right: 0.5em;
+  border-width: 0;
+  border-radius: 0;
+}
+.k-pager-numbers .k-state-selected {
+  border-style: solid;
+  border-width: 1px;
+  text-align: center;
+  border-radius: 1.0833em;
+}
+.k-pager-wrap .k-textbox {
+  width: 3.333em;
+}
+.k-pager-wrap .k-dropdown {
+  width: 4.500em;
+}
+.k-pager-refresh {
+  float: right;
+}
+.k-pager-input,
+.k-pager-sizes {
+  padding: 0 1.4166em;
+}
+.k-pager-sizes {
+  display: inline-block;
+  padding-top: 1px;
+}
+.k-pager-sizes .k-widget.k-dropdown {
+  margin-top: -2px;
+}
+.k-pager-wrap .k-textbox,
+.k-pager-wrap .k-widget {
+  margin: 0 .4em 0;
+}
+@media only screen and (max-width: 1024px) {
+  .k-webkit .k-pager-wrap,
+  .k-ff .k-pager-wrap,
+  .k-ie11 .k-pager-wrap,
+  .k-edge .k-pager-wrap,
+  .k-safari .k-pager-wrap {
+    overflow: visible;
+    min-height: 2.1em;
+  }
+  .k-webkit .k-pager-wrap .k-pager-nav,
+  .k-ff .k-pager-wrap .k-pager-nav,
+  .k-ie11 .k-pager-wrap .k-pager-nav,
+  .k-edge .k-pager-wrap .k-pager-nav,
+  .k-safari .k-pager-wrap .k-pager-nav,
+  .k-webkit .k-pager-input,
+  .k-ff .k-pager-input,
+  .k-ie11 .k-pager-input,
+  .k-edge .k-pager-input,
+  .k-safari .k-pager-input {
+    display: inline-block;
+    vertical-align: top;
+  }
+  .k-webkit .k-pager-numbers,
+  .k-ff .k-pager-numbers,
+  .k-ie11 .k-pager-numbers,
+  .k-edge .k-pager-numbers,
+  .k-safari .k-pager-numbers {
+    position: absolute;
+    left: 4.8em;
+    display: inline-flex;
+    flex-direction: column-reverse;
+    overflow: visible;
+    height: auto;
+  }
+  .k-webkit .k-pager-numbers:first-child,
+  .k-ff .k-pager-numbers:first-child,
+  .k-ie11 .k-pager-numbers:first-child,
+  .k-edge .k-pager-numbers:first-child,
+  .k-safari .k-pager-numbers:first-child {
+    left: .2em;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded,
+  .k-ff .k-pager-numbers.k-state-expanded,
+  .k-ie11 .k-pager-numbers.k-state-expanded,
+  .k-edge .k-pager-numbers.k-state-expanded,
+  .k-safari .k-pager-numbers.k-state-expanded {
+    transform: translatey(-100%);
+    -webkit-transform: translatey(-100%);
+  }
+  .k-webkit .km-pane-wrapper .k-pager-numbers,
+  .k-ff .km-pane-wrapper .k-pager-numbers,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers,
+  .k-edge .km-pane-wrapper .k-pager-numbers,
+  .k-safari .km-pane-wrapper .k-pager-numbers {
+    position: relative;
+    left: 50%;
+    transform: translate(-50%, -100%);
+    -webkit-transform: translate(-50%, -100%);
+  }
+  .k-webkit .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-ff .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-edge .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-safari .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-webkit .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-ff .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-edge .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-safari .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-webkit .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-ff .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-ie11 .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-edge .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-safari .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-webkit .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-ff .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-ie11 .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-edge .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-safari .km-pane-wrapper .k-pager-wrap > .k-pager-info {
+    padding-top: 0;
+    padding-bottom: 0;
+  }
+  .k-webkit .k-rtl .k-pager-numbers,
+  .k-ff .k-rtl .k-pager-numbers,
+  .k-ie11 .k-rtl .k-pager-numbers,
+  .k-edge .k-rtl .k-pager-numbers,
+  .k-safari .k-rtl .k-pager-numbers {
+    left: auto;
+    right: 4.8em;
+    width: 4.5em;
+  }
+  .k-webkit .k-rtl .k-pager-numbers:first-child,
+  .k-ff .k-rtl .k-pager-numbers:first-child,
+  .k-ie11 .k-rtl .k-pager-numbers:first-child,
+  .k-edge .k-rtl .k-pager-numbers:first-child,
+  .k-safari .k-rtl .k-pager-numbers:first-child {
+    left: auto;
+    right: .2em;
+  }
+  .k-webkit .k-rtl .km-pane-wrapper .k-pager-numbers,
+  .k-ff .k-rtl .km-pane-wrapper .k-pager-numbers,
+  .k-ie11 .k-rtl .km-pane-wrapper .k-pager-numbers,
+  .k-edge .k-rtl .km-pane-wrapper .k-pager-numbers,
+  .k-safari .k-rtl .km-pane-wrapper .k-pager-numbers {
+    right: 5.8em;
+  }
+  .k-webkit .k-pager-numbers .k-current-page,
+  .k-ff .k-pager-numbers .k-current-page,
+  .k-ie11 .k-pager-numbers .k-current-page,
+  .k-edge .k-pager-numbers .k-current-page,
+  .k-safari .k-pager-numbers .k-current-page {
+    display: block;
+    border-left: 0;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ff .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ie11 .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-edge .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-safari .k-pager-numbers.k-state-expanded .k-current-page {
+    transform: translatey(100%);
+    -webkit-transform: translatey(100%);
+  }
+  .k-webkit .k-pager-numbers li:not(.k-current-page),
+  .k-ff .k-pager-numbers li:not(.k-current-page),
+  .k-ie11 .k-pager-numbers li:not(.k-current-page),
+  .k-edge .k-pager-numbers li:not(.k-current-page),
+  .k-safari .k-pager-numbers li:not(.k-current-page) {
+    display: none;
+  }
+  .k-webkit .k-pager-numbers .k-current-page .k-link,
+  .k-ff .k-pager-numbers .k-current-page .k-link,
+  .k-ie11 .k-pager-numbers .k-current-page .k-link,
+  .k-edge .k-pager-numbers .k-current-page .k-link,
+  .k-safari .k-pager-numbers .k-current-page .k-link {
+    width: 3.2em;
+    padding: 0 .429em 0 .714em;
+    border-radius: 1.0833em;
+  }
+  .k-webkit .k-pager-numbers + .k-link,
+  .k-ff .k-pager-numbers + .k-link,
+  .k-ie11 .k-pager-numbers + .k-link,
+  .k-edge .k-pager-numbers + .k-link,
+  .k-safari .k-pager-numbers + .k-link {
+    margin-left: 4.8em;
+  }
+  .k-webkit .k-rtl .k-pager-numbers + .k-link,
+  .k-ff .k-rtl .k-pager-numbers + .k-link,
+  .k-ie11 .k-rtl .k-pager-numbers + .k-link,
+  .k-edge .k-rtl .k-pager-numbers + .k-link,
+  .k-safari .k-rtl .k-pager-numbers + .k-link {
+    margin-right: 5.1em;
+    margin-left: 0;
+  }
+  .k-webkit .k-pager-numbers .k-state-selected,
+  .k-ff .k-pager-numbers .k-state-selected,
+  .k-ie11 .k-pager-numbers .k-state-selected,
+  .k-edge .k-pager-numbers .k-state-selected,
+  .k-safari .k-pager-numbers .k-state-selected,
+  .k-webkit .k-pager-numbers .k-link,
+  .k-ff .k-pager-numbers .k-link,
+  .k-ie11 .k-pager-numbers .k-link,
+  .k-edge .k-pager-numbers .k-link,
+  .k-safari .k-pager-numbers .k-link {
+    display: block;
+    margin-right: 0;
+    padding: 1px 5px 1px 5px;
+    text-align: left;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded,
+  .k-ff .k-pager-numbers.k-state-expanded,
+  .k-ie11 .k-pager-numbers.k-state-expanded,
+  .k-edge .k-pager-numbers.k-state-expanded,
+  .k-safari .k-pager-numbers.k-state-expanded {
+    box-sizing: border-box;
+    padding: 2px 2px 0;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ff .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ie11 .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-edge .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-safari .k-pager-numbers.k-state-expanded .k-current-page {
+    margin: -2em -3px 0;
+    padding: 0;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-ff .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-ie11 .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-edge .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-safari .k-pager-numbers.k-state-expanded .k-current-page .k-link {
+    border-radius: 0 0 1.0833em 1.0833em;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded li,
+  .k-ff .k-pager-numbers.k-state-expanded li,
+  .k-ie11 .k-pager-numbers.k-state-expanded li,
+  .k-edge .k-pager-numbers.k-state-expanded li,
+  .k-safari .k-pager-numbers.k-state-expanded li {
+    display: inline-block;
+  }
+}
+@media only screen and (max-width: 640px) {
+  .k-webkit .k-pager-info,
+  .k-ff .k-pager-info,
+  .k-ie11 .k-pager-info,
+  .k-edge .k-pager-info,
+  .k-safari .k-pager-info {
+    display: none;
+  }
+}
+@media only screen and (max-width: 480px) {
+  .k-webkit .k-pager-sizes,
+  .k-ff .k-pager-sizes,
+  .k-ie11 .k-pager-sizes,
+  .k-edge .k-pager-sizes,
+  .k-safari .k-pager-sizes {
+    display: none;
+  }
+}
+.k-rtl .k-pager-wrap .k-i-seek-e,
+.k-rtl .k-pager-wrap .k-i-seek-w,
+.k-rtl .k-pager-wrap .k-i-arrow-e,
+.k-rtl .k-pager-wrap .k-i-arrow-w {
+  transform: scaleX(-1);
+}
+/* Menu */
+.k-menu {
+  cursor: default;
+}
+.k-menu .k-link {
+  white-space: nowrap;
+}
+.k-menu,
+.k-menu-scroll-wrapper .k-menu-group,
+.k-popups-wrapper .k-menu-group,
+.k-menu .k-menu-group {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  zoom: 1;
+}
+.k-menu:after {
+  content: '';
+  display: block;
+  width: 99%;
+  height: 0;
+  float: inherit;
+  clear: both;
+}
+.k-menu-scroll-wrapper .k-item,
+.k-popups-wrapper .k-item,
+.k-menu .k-item {
+  -webkit-user-select: none;
+  -moz-user-select: -moz-none;
+  user-select: none;
+}
+.k-menu-scroll-wrapper .k-item div,
+.k-popups-wrapper .k-item div,
+.k-menu .k-item div {
+  user-select: default;
+}
+.k-popups-wrapper .k-item .k-item,
+.k-popups-wrapper.vertical > .k-item,
+.k-menu-scroll-wrapper .k-item .k-item,
+.k-menu-scroll-wrapper.vertical > .k-item,
+.k-menu .k-item .k-item,
+ul.k-menu-vertical > .k-item {
+  display: block;
+  float: none;
+  border-width: 0;
+}
+.k-menu-scroll-wrapper .k-item > .k-link > .k-icon,
+.k-menu-scroll-wrapper .k-image,
+.k-menu-scroll-wrapper .k-sprite,
+.k-popups-wrapper .k-item > .k-link > .k-icon,
+.k-popups-wrapper .k-image,
+.k-popups-wrapper .k-sprite,
+.k-menu .k-item > .k-link > .k-icon,
+.k-menu .k-image,
+.k-menu .k-sprite {
+  margin: -2px 4px 0 -4px;
+  vertical-align: middle;
+}
+.k-menu-scroll-wrapper .k-item > .k-link > .k-icon,
+.k-popups-wrapper .k-item > .k-link > .k-icon,
+.k-menu .k-item > .k-link > .k-icon {
+  margin: -2px 0 0;
+}
+.k-menu-scroll-wrapper .k-item > .k-link,
+.k-popups-wrapper .k-item > .k-link,
+.k-menu .k-item > .k-link {
+  display: block;
+  padding: 1.071em;
+  line-height: 1.34em;
+  user-select: none;
+}
+.k-menu-scroll-wrapper .k-menu-group,
+.k-popups-wrapper .k-menu-group,
+.k-menu .k-menu-group {
+  display: none;
+  border-style: solid;
+  border-width: 1px;
+  overflow: visible;
+  white-space: nowrap;
+}
+.k-menu-scroll-wrapper .k-menu-group > .k-item,
+.k-popups-wrapper .k-menu-group > .k-item,
+.k-menu .k-menu-group > .k-item {
+  display: block;
+  border-width: 0;
+}
+.k-menu-scroll-wrapper .k-item,
+.k-menu-scroll-wrapper.horizontal > .k-item,
+.k-popups-wrapper .k-item,
+.k-popups-wrapper.horizontal > .k-item,
+.k-menu .k-item,
+.k-widget.k-menu-horizontal > .k-item {
+  position: relative;
+  float: left;
+  border-style: solid;
+  border-width: 0 1px 0 0;
+  vertical-align: top;
+  zoom: 1;
+  box-sizing: content-box;
+}
+.k-menu-scroll-wrapper .k-menu-group .k-item > .k-link,
+.k-popups-wrapper.vertical > .k-item > .k-link,
+.k-context-menu.k-menu-vertical > .k-item > .k-link,
+.k-menu .k-menu-group .k-item > .k-link {
+  padding: .28em 1.8em .38em .9em;
+}
+.k-popups-wrapper.horizontal > .k-separator,
+.k-context-menu.k-menu-horizontal > .k-separator {
+  display: none;
+}
+.k-popups-wrapper.horizontal > .k-item,
+.k-context-menu.k-menu-horizontal > .k-item {
+  box-sizing: border-box;
+}
+.k-popups-wrapper.horizontal > .k-last,
+.k-context-menu.k-menu-horizontal > .k-last {
+  border: 0;
+}
+.k-menu-scroll-wrapper .k-item > .k-link > .k-i-arrow-60-down,
+.k-popups-wrapper .k-item > .k-link > .k-i-arrow-60-down,
+.k-menu .k-item > .k-link > .k-i-arrow-60-down {
+  margin-right: -8px;
+}
+.k-menu-scroll-wrapper .k-item > .k-link > .k-i-arrow-60-right,
+.k-popups-wrapper .k-item > .k-link > .k-i-arrow-60-right,
+.k-menu .k-item > .k-link > .k-i-arrow-60-right {
+  position: absolute;
+  top: 50%;
+  margin-top: -8px;
+  right: 2px;
+  right: .2rem;
+}
+.k-menu-scroll-wrapper .k-animation-container,
+.k-popups-wrapper .k-animation-container,
+.k-menu .k-animation-container {
+  border: 0;
+}
+.k-menu-scroll-wrapper .k-animation-container,
+.k-menu-scroll-wrapper .k-menu-group,
+.k-popups-wrapper .k-animation-container,
+.k-popups-wrapper .k-menu-group,
+.k-menu .k-animation-container,
+.k-menu .k-menu-group {
+  position: absolute;
+  left: 0;
+}
+.k-menu-scroll-wrapper .k-animation-container .k-animation-container,
+.k-menu-scroll-wrapper .k-menu-group .k-menu-group,
+.k-menu-scroll-wrapper.vertical .k-animation-container,
+.k-menu-scroll-wrapper.vertical .k-menu-group,
+.k-popups-wrapper .k-animation-container .k-animation-container,
+.k-popups-wrapper .k-menu-group .k-menu-group,
+.k-popups-wrapper.vertical .k-animation-container,
+.k-popups-wrapper.vertical .k-menu-group,
+.k-menu .k-animation-container .k-animation-container,
+.k-menu .k-menu-group .k-menu-group,
+.k-menu-vertical .k-animation-container,
+.k-menu-vertical .k-menu-group {
+  top: 0;
+  left: 0;
+}
+.k-menu-scroll-wrapper .k-animation-container .k-menu-group,
+.k-popups-wrapper .k-animation-container .k-menu-group,
+.k-menu .k-animation-container .k-menu-group {
+  top: auto;
+  left: auto;
+  margin-left: -1px;
+}
+.k-menu .k-animation-container,
+.k-menu-scroll-wrapper .k-animation-container,
+.k-popups-wrapper .k-animation-container,
+.k-popup .k-animation-container {
+  margin-top: -1px;
+  padding-left: 1px;
+}
+.k-ie .k-menu .k-animation-container,
+.k-ie .k-menu-scroll-wrapper .k-animation-container,
+.k-ie .k-popups-wrapper .k-animation-container,
+.k-ie .k-popup .k-animation-container {
+  margin-top: -2px;
+}
+.k-popup .k-animation-container .k-popup {
+  margin-left: -1px;
+}
+.k-menu-scroll-wrapper .k-separator,
+.k-popups-wrapper .k-separator,
+ul.k-menu .k-separator {
+  padding: 0.25em 0;
+  height: 100%;
+  width: 1px;
+  font-size: 0;
+  line-height: 0;
+  border-width: 0 1px 0 0;
+}
+.k-menu-scroll-wrapper.vertical .k-separator,
+.k-menu-scroll-wrapper.vertical .k-menu-group .k-separator,
+.k-popups-wrapper.vertical .k-separator,
+.k-popups-wrapper.vertical .k-menu-group .k-separator,
+ul.k-menu-vertical .k-separator,
+.k-menu .k-menu-group .k-separator {
+  padding: 0;
+  height: 1px;
+  width: 100%;
+  border-width: 1px 0 0;
+}
+.k-popups-wrapper .k-widget.k-menu,
+.k-menu-scroll-wrapper .k-widget.k-menu {
+  white-space: nowrap;
+  overflow: hidden;
+}
+.k-popups-wrapper.vertical .k-menu.k-menu-vertical,
+.k-menu-scroll-wrapper.vertical .k-menu.k-menu-vertical {
+  height: 100%;
+  box-sizing: border-box;
+}
+.k-popups-wrapper.horizontal .k-menu.k-menu-horizontal > .k-item,
+.k-menu-scroll-wrapper.horizontal .k-menu.k-menu-horizontal > .k-item {
+  display: inline-block;
+  overflow: hidden;
+  float: none;
+}
+.k-popups-wrapper.vertical .k-menu.k-menu-vertical > .k-item,
+.k-menu-scroll-wrapper.vertical .k-menu.k-menu-vertical > .k-item {
+  overflow: hidden;
+}
+.k-popups-wrapper,
+.k-menu-scroll-wrapper {
+  position: relative;
+  border: 0;
+  margin: 0;
+  padding: 0;
+}
+.k-popups-wrapper.vertical,
+.k-menu-scroll-wrapper.vertical {
+  height: 100%;
+}
+.k-popups-wrapper > .k-animation-container .k-item,
+.k-menu-scroll-wrapper > .k-animation-container .k-item {
+  float: none;
+}
+.k-popups-wrapper .k-menu-scroll-button,
+.k-menu-scroll-wrapper .k-menu-scroll-button {
+  border-radius: 0;
+  position: absolute;
+  display: none;
+}
+.k-popups-wrapper .k-scroll-up,
+.k-menu-scroll-wrapper .k-scroll-up {
+  top: 0;
+  left: 0;
+  width: 100%;
+}
+.k-popups-wrapper .k-scroll-down,
+.k-menu-scroll-wrapper .k-scroll-down {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+}
+.k-popups-wrapper .k-scroll-up,
+.k-menu-scroll-wrapper .k-scroll-up,
+.k-popups-wrapper .k-scroll-down,
+.k-menu-scroll-wrapper .k-scroll-down {
+  padding: 0em 0.7em;
+  line-height: 0.2em;
+}
+.k-popups-wrapper .k-scroll-left,
+.k-menu-scroll-wrapper .k-scroll-left {
+  top: 0;
+  left: 0;
+  height: 100%;
+}
+.k-popups-wrapper .k-scroll-right,
+.k-menu-scroll-wrapper .k-scroll-right {
+  top: 0;
+  right: 0;
+  height: 100%;
+}
+.k-popups-wrapper .k-scroll-left,
+.k-menu-scroll-wrapper .k-scroll-left,
+.k-popups-wrapper .k-scroll-right,
+.k-menu-scroll-wrapper .k-scroll-right {
+  width: 16px;
+  padding-left: 0;
+  padding-right: 0;
+}
+.k-popups-wrapper .k-scroll-left .k-icon,
+.k-menu-scroll-wrapper .k-scroll-left .k-icon,
+.k-popups-wrapper .k-scroll-right .k-icon,
+.k-menu-scroll-wrapper .k-scroll-right .k-icon {
+  margin-top: -0.5em;
+  position: absolute;
+  top: 50%;
+  left: 0;
+}
+/* Context Menu */
+.k-context-menu {
+  border: 0;
+  user-select: none;
+}
+/* Calendar */
+.k-calendar {
+  position: relative;
+  display: inline-block;
+  width: 19em;
+  overflow: hidden;
+}
+.k-week-number {
+  width: 21.71428571em;
+}
+.k-calendar td,
+.k-calendar .k-link {
+  text-decoration: none;
+}
+.k-calendar .k-action-link {
+  text-decoration: underline;
+}
+.k-calendar .k-header,
+.k-calendar .k-footer {
+  position: relative;
+  text-align: center;
+  zoom: 1;
+}
+.k-widget.k-calendar .k-nav-prev,
+.k-widget.k-calendar .k-nav-next {
+  position: absolute;
+  top: 0.16666em;
+  line-height: 1.8333em;
+  height: 1.8333em;
+}
+.k-widget.k-calendar .k-nav-prev {
+  left: 1%;
+}
+.k-widget.k-calendar .k-nav-next {
+  right: 1%;
+}
+.k-calendar .k-content {
+  float: left;
+  border-spacing: 0;
+  width: 100%;
+  height: 14.167em;
+  border-width: 0;
+  margin: 0;
+  table-layout: fixed;
+  outline: 0;
+}
+.k-calendar .k-content,
+.k-calendar .k-content th {
+  text-align: right;
+}
+.k-calendar .k-content .k-alt {
+  border-radius: 0;
+  text-align: center;
+  font-weight: normal;
+  cursor: default;
+  line-height: 1.8333em;
+}
+.k-calendar .k-animation-container .k-content {
+  height: 100%;
+}
+.k-widget.k-calendar .k-nav-fast {
+  display: inline-block;
+  width: 75%;
+  height: 1.8333em;
+  line-height: 1.8333em;
+  margin: 0.16666em -0.08333em 0.3333em 0;
+}
+.k-calendar .k-header .k-icon {
+  vertical-align: middle;
+}
+.k-calendar .k-header .k-link.k-nav-prev,
+.k-calendar .k-header .k-link.k-nav-next {
+  height: 1.8333em;
+  width: 1.8333em;
+}
+.k-calendar th {
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  padding: .4em .45em .4em .1em;
+  font-weight: normal;
+  cursor: default;
+}
+.k-calendar td {
+  padding: 0.08333em;
+  cursor: pointer;
+}
+.k-calendar .k-state-focus {
+  border-style: dotted;
+  border-width: 0.08333em;
+  padding: 0;
+}
+.k-calendar .k-content .k-link {
+  display: block;
+  overflow: hidden;
+  min-height: 1.8333em;
+  line-height: 1.8333em;
+  padding: 0 .45em 0 .1em;
+}
+.k-calendar .k-meta-view .k-link {
+  padding: .25em 0 .3em;
+  text-align: center;
+}
+.k-calendar .k-century .k-link {
+  text-align: left;
+  padding: 0 .45em;
+}
+.k-calendar .k-footer {
+  clear: both;
+}
+.k-calendar .k-footer .k-nav-today,
+.k-calendar .k-footer > .k-state-disabled {
+  display: block;
+  height: 100%;
+  padding: .5em 0;
+}
+.k-calendar .k-nav-today:hover {
+  text-decoration: underline;
+}
+/* ComboBox & DropDownList */
+span.k-datepicker,
+span.k-timepicker,
+span.k-datetimepicker,
+span.k-colorpicker,
+span.k-numerictextbox,
+span.k-combobox,
+span.k-dropdown,
+.k-toolbar .k-split-button {
+  background-image: none;
+}
+.k-autocomplete,
+.k-combobox,
+.k-datepicker,
+.k-timepicker,
+.k-datetimepicker,
+.k-colorpicker,
+.k-numerictextbox,
+.k-dropdown,
+.k-selectbox,
+.k-textbox,
+.k-toolbar .k-split-button,
+.k-listbox {
+  position: relative;
+  display: inline-block;
+  width: 12.4em;
+  overflow: visible;
+  border-width: 0;
+  vertical-align: middle;
+}
+.k-autocomplete > .k-i-close,
+.k-combobox > .k-dropdown-wrap > .k-i-close,
+.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  display: none;
+  position: absolute;
+  right: 0;
+}
+.k-autocomplete > .k-i-close,
+.k-combobox > .k-dropdown-wrap > .k-i-close {
+  bottom: 0;
+  top: 50%;
+  transform: translateY(-50%);
+}
+.k-ie8 .k-autocomplete > .k-i-close,
+.k-ie8 .k-combobox > .k-dropdown-wrap > .k-i-close {
+  margin-top: -8px;
+}
+.k-combobox > .k-dropdown-wrap > .k-i-close {
+  font-size: 100%;
+  right: 2.4em;
+}
+.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  top: 6px;
+}
+.k-autocomplete > .k-i-close,
+.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  margin-right: 6px;
+}
+.k-autocomplete.k-state-hover > .k-i-close,
+.k-combobox > .k-dropdown-wrap.k-state-hover > .k-i-close,
+.k-autocomplete.k-state-focused > .k-i-close,
+.k-combobox > .k-dropdown-wrap.k-state-focused > .k-i-close {
+  display: inline-block;
+  outline: none;
+}
+.k-autocomplete > .k-hidden,
+.k-combobox > .k-dropdown-wrap > .k-hidden,
+.k-multiselect .k-hidden {
+  display: none !important;
+}
+.k-multiselect.k-state-hover > .k-multiselect-wrap > .k-i-close,
+.k-multiselect.k-state-focused > .k-multiselect-wrap > .k-i-close {
+  display: inline-block;
+  outline: none;
+}
+.k-autocomplete.k-state-border-down > .k-i-close,
+.k-combobox > .k-dropdown-wrap.k-state-border-down > .k-i-close {
+  margin-top: -1px;
+}
+.k-filter-menu .k-combobox,
+.k-filter-menu .k-datepicker,
+.k-filter-menu .k-timepicker,
+.k-filter-menu .k-datetimepicker,
+.k-filter-menu .k-numerictextbox,
+.k-filter-menu .k-dropdown,
+.k-filter-menu .k-autocomplete,
+.k-filter-menu .k-textbox {
+  width: 13.2em;
+}
+.k-autocomplete,
+.k-combobox,
+.k-datepicker,
+.k-timepicker,
+.k-datetimepicker,
+.k-colorpicker,
+.k-numerictextbox,
+.k-dropdown,
+.k-selectbox,
+.k-toolbar .k-split-button {
+  white-space: nowrap;
+}
+.k-colorpicker,
+.k-toolbar .k-split-button {
+  width: auto;
+}
+.k-datetimepicker {
+  width: 15em;
+}
+.k-autocomplete,
+.k-picker-wrap,
+.k-numeric-wrap {
+  position: relative;
+  cursor: default;
+}
+.k-dropdown-wrap {
+  position: relative;
+}
+.k-dropdown-wrap,
+.k-picker-wrap,
+.k-numeric-wrap {
+  display: block;
+}
+.k-block,
+.k-widget,
+.k-grid,
+.k-slider,
+.k-splitter,
+.k-treeview,
+.k-panelbar,
+.k-content,
+.k-header-column-menu {
+  outline: 0;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.k-block,
+.k-slider,
+.k-splitbar,
+.k-calendar,
+.k-treeview,
+.k-pager-wrap,
+.k-grid-header .k-i-link-horizontal,
+.k-header-column-menu {
+  -webkit-touch-callout: none;
+}
+.k-list-scroller {
+  position: relative;
+  overflow: auto;
+}
+.k-popup.k-list-container,
+.k-popup.k-calendar-container {
+  -webkit-touch-callout: none;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  padding: 2px;
+  border-width: 1px;
+  border-style: solid;
+}
+.k-list-container.k-state-border-down,
+.k-autocomplete.k-state-border-down,
+.k-dropdown-wrap.k-state-border-down,
+.k-picker-wrap.k-state-border-down,
+.k-numeric-wrap.k-state-border-down {
+  border-bottom-width: 0;
+  padding-bottom: 1px;
+}
+.k-list-container .km-scroll-container {
+  padding-bottom: 6px;
+}
+.k-textbox,
+.k-autocomplete,
+.k-dropdown-wrap,
+.k-picker-wrap,
+.k-numeric-wrap {
+  border-width: 1px;
+  border-style: solid;
+  padding: 0 1.9em 0 0;
+}
+.k-numeric-wrap.k-expand-padding {
+  padding-right: 0;
+}
+.k-textbox,
+.k-autocomplete {
+  padding: 0;
+}
+.k-textbox.k-space-left {
+  padding-left: 1.9em;
+}
+.k-textbox.k-space-right {
+  padding-right: 1.9em;
+}
+.k-textbox .k-icon {
+  top: 50%;
+  margin: -8px 0 0;
+  position: absolute;
+}
+.k-space-left .k-icon {
+  left: 3px;
+}
+.k-space-right .k-icon {
+  right: 3px;
+}
+/*prevent missing bottom border at some zoom levels*/
+span.k-textbox:after {
+  content: "\a0";
+  display: block;
+  height: .4px;
+  overflow: hidden;
+}
+.k-autocomplete,
+.k-dropdown-wrap.k-state-focused,
+.k-dropdown-wrap.k-state-hover,
+.k-picker-wrap.k-state-focused,
+.k-picker-wrap.k-state-hover,
+.k-numeric-wrap.k-state-focused,
+.k-numeric-wrap.k-state-hover {
+  transition: box-shadow .15s ease-out;
+  transition: "box-shadow .15s ease-out";
+}
+.k-textbox > input,
+.k-picker-wrap .k-input,
+.k-numeric-wrap .k-input,
+.k-combobox .k-input {
+  width: 100%;
+  vertical-align: top;
+}
+.k-picker-wrap .k-input,
+.k-numeric-wrap .k-input,
+.k-dropdown-wrap .k-input,
+.k-selectbox .k-input {
+  font-family: inherit;
+  border-width: 0;
+  outline: 0;
+}
+.k-dropdown .k-input,
+.k-selectbox .k-input {
+  background: transparent;
+}
+.k-picker-wrap .k-select,
+.k-numeric-wrap .k-select,
+.k-dropdown-wrap .k-select {
+  position: absolute;
+  /* icon positioning */
+  top: 0;
+  right: 0;
+  display: inline-block;
+  vertical-align: top;
+  text-decoration: none;
+}
+.k-combobox .k-select,
+.k-picker-wrap .k-select,
+.k-numeric-wrap .k-select {
+  border-style: solid;
+  border-width: 0 0 0 1px;
+  border-color: inherit;
+  /* skin-related, inherit does not work in ie7- */
+}
+span.k-datetimepicker .k-select,
+span.k-datetimepicker .k-select + .k-select {
+  right: 0;
+}
+.k-textbox > input,
+.k-autocomplete .k-input {
+  display: block;
+}
+.k-combobox .k-icon {
+  /*margin-top: 1px;*/
+}
+.k-dropdown .k-select,
+.k-selectbox .k-select {
+  overflow: hidden;
+  border: 0;
+  text-decoration: none;
+  font: inherit;
+  color: inherit;
+}
+.k-dropdown .k-input,
+.k-selectbox .k-input {
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.k-textbox > input,
+.k-autocomplete .k-input,
+.k-picker-wrap .k-input,
+.k-numeric-wrap .k-input,
+.k-dropdown-wrap .k-input,
+.k-selectbox .k-input {
+  height: 2.214em;
+  line-height: 2.214em;
+  padding: 0.177em 0;
+  text-indent: 0.8em;
+  border: 0;
+  margin: 0;
+}
+.k-combobox .k-dropdown-wrap:before,
+.k-picker-wrap:before,
+.k-numeric-wrap:before {
+  content: "\a0";
+  display: inline-block;
+  width: 0;
+  height: 2.214em;
+  padding-bottom: 0.3em;
+}
+.k-combobox-clearable .k-input {
+  padding-right: 1.9em;
+  box-sizing: border-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  height: 2.568em;
+}
+/* fix missing bottom border on browser zoom in Chrome */
+.k-webkit .k-combobox .k-dropdown-wrap:before,
+.k-webkit .k-picker-wrap:before,
+.k-webkit .k-numeric-wrap:before {
+  padding-bottom: 0.38em;
+}
+/* above style breaks NumericTextBox layout due display:block style applied to the input */
+.km.root .k-combobox .k-dropdown-wrap:before,
+.km.root .k-picker-wrap:before,
+.km.root .k-numeric-wrap:before {
+  content: none;
+}
+.k-combobox .k-input,
+.k-picker-wrap .k-input,
+.k-numeric-wrap .k-input {
+  display: inline;
+}
+.k-picker-wrap .k-select,
+.k-numeric-wrap .k-select,
+.k-dropdown-wrap .k-select {
+  min-height: 2.214em;
+  line-height: 2.564em;
+  vertical-align: middle;
+  -moz-box-sizing: border-box;
+  text-align: center;
+  width: 1.9em;
+  height: 100%;
+}
+.k-numeric-wrap .k-select {
+  padding: 0;
+}
+body .k-datetimepicker .k-select {
+  border-radius: 0;
+}
+.k-combobox .k-select,
+.k-dropdown,
+.k-selectbox .k-icon {
+  cursor: pointer;
+}
+.k-popup {
+  border-style: solid;
+  border-width: 1px;
+}
+.k-popup .k-item,
+.k-list-optionlabel {
+  cursor: default;
+}
+.k-popup .k-calendar {
+  border: 0;
+}
+.k-list {
+  height: auto;
+}
+.k-nodata {
+  min-height: 138px;
+  width: 100%;
+  display: table;
+  text-transform: uppercase;
+  font-size: 0.85em;
+  font-weight: lighter;
+}
+.k-nodata > div {
+  display: table-cell;
+  text-align: center;
+  vertical-align: middle;
+  padding: 11px;
+}
+.k-popup .k-list .k-item,
+.k-fieldselector .k-list .k-item,
+.k-list-optionlabel,
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header,
+.k-listbox .k-item,
+.k-item.k-drag-clue {
+  padding: 1px 5px 1px 5px;
+  line-height: 1.8em;
+  min-height: 1.8em;
+}
+.k-popup .k-list .k-item,
+.k-listbox .k-item {
+  border-width: 1px;
+  border-style: solid;
+  border-color: transparent;
+  padding: 0 4px;
+}
+.k-popup .k-list .k-item > .k-group {
+  top: -1px;
+}
+.k-group-header + div > .k-list > .k-item.k-first:before {
+  content: " ";
+  display: block;
+  border-top-width: 1px;
+  border-top-style: solid;
+  position: absolute;
+  top: -1px;
+  left: 0;
+  right: 0;
+}
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header {
+  padding-right: 22px;
+}
+.k-overflow-container .k-item {
+  padding: 1px;
+}
+.k-overflow-container > .k-state-disabled .k-button,
+.k-overflow-container .k-button.k-state-disabled,
+.k-overflow-container .k-button.k-state-disabled:hover {
+  border: 0 ;
+  background: none;
+}
+.k-popup .k-list .k-state-hover,
+.k-popup .k-list .k-state-focused,
+.k-popup .k-list .k-state-selected,
+.k-overflow-container .k-state-hover,
+.k-overflow-container .k-state-focused,
+.k-overflow-container .k-state-selected,
+.k-fieldselector .k-list .k-item,
+.k-list-optionlabel.k-state-focused,
+.k-list-optionlabel.k-state-selected,
+.k-listbox .k-item {
+  padding: 0 4px;
+  border-width: 1px;
+  border-style: solid;
+}
+.k-list-filter {
+  position: relative;
+  margin-bottom: 2px;
+}
+.k-list-filter > .k-textbox {
+  padding-right: 20px;
+  width: 100%;
+}
+.k-list-filter > .k-icon {
+  position: absolute;
+  right: 6px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+.km-root .k-list-filter > .k-textbox {
+  padding-left: 0;
+  padding-right: 0;
+  border-left-width: 0;
+  border-right-width: 0;
+}
+/* MultiSelect */
+.k-multiselect-wrap {
+  position: relative;
+  border-width: 0px;
+  border-style: solid;
+  border-radius: 4px;
+  border-color: #C5C5C5;
+  background-color: #FFF;
+  min-height: 2.04em;
+  padding-right: 22px;
+}
+.k-multiselect-wrap .k-input {
+  background-color: transparent;
+  height: 1.31em;
+  line-height: 1.31em;
+  padding: 0.18em 0;
+  text-indent: 0.8em;
+  border: 0;
+  margin: 1px 0 0;
+  float: left;
+}
+.k-multiselect-wrap .k-input::-ms-clear {
+  display: none;
+}
+.k-multiselect-wrap li {
+  margin: 1px 0 1px 1px;
+  padding: .1em 1.6em .1em .4em;
+  line-height: 2.064em;
+  float: left;
+  position: relative;
+}
+.k-autocomplete .k-i-loading,
+.k-multiselect .k-i-loading {
+  position: absolute;
+  right: 3px;
+  bottom: 4px;
+}
+.k-multiselect-wrap .k-select {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  padding: .03em .2em;
+}
+/* Date/Time Pickers */
+.k-datetimepicker .k-picker-wrap {
+  padding-right: 3.8em;
+}
+.k-datetimepicker .k-select {
+  width: 3.8em;
+}
+.k-datetimepicker .k-select .k-link-date {
+  margin-left: -0.285em;
+}
+.k-datetimepicker .k-select .k-link-time {
+  margin-right: -0.285em;
+  margin-left: .428em;
+}
+.k-datetimepicker .k-picker-wrap .k-icon {
+  margin: 0 2px;
+}
+.k-picker-wrap .k-icon {
+  cursor: pointer;
+}
+.k-button,
+.k-textbox,
+.k-timepicker,
+.k-datepicker,
+.k-datetimepicker {
+  display: inline-block;
+  vertical-align: middle;
+}
+.k-picker-wrap .k-input {
+  margin: 0;
+}
+.k-time-popup .k-item {
+  padding: 1px 3px;
+}
+/* inputs */
+.k-input {
+  padding: 0.25em 0;
+}
+.k-input,
+.k-textbox > input {
+  outline: 0;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.k-textbox {
+  outline: 0;
+}
+input.k-textbox,
+textarea.k-textbox {
+  padding: 2px .3em;
+}
+input.k-textbox {
+  height: 2.694em;
+  text-indent: 0.8em;
+  line-height: 1.6em;
+}
+.k-ie input.k-textbox {
+  text-indent: 0.4em;
+}
+.k-ff input.k-textbox {
+  height: 2.17em;
+}
+textarea.k-textbox {
+  height: auto;
+}
+/* NumericTextBox */
+span.k-numerictextbox {
+  background-color: transparent;
+}
+.k-numerictextbox .k-input {
+  margin: 0;
+}
+.k-numerictextbox .k-link {
+  display: block;
+  height: 1em;
+  line-height: 1em;
+  vertical-align: middle;
+  border-width: 0;
+  padding: 0;
+  overflow: hidden;
+}
+.k-numerictextbox .k-icon {
+  display: block;
+  margin: auto;
+  height: 100%;
+}
+.k-numerictextbox .k-i-arrow-60-up {
+  top: 2px;
+}
+.k-numerictextbox .k-i-arrow-60-down {
+  bottom: 2px;
+}
+.k-numeric-wrap .k-input::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+}
+/* ColorPicker */
+.k-colorpicker .k-picker-wrap {
+  line-height: 2em;
+}
+.k-colorpicker .k-selected-color {
+  vertical-align: top;
+  display: inline-block;
+  height: 2em;
+  width: 2em;
+}
+.k-colorpicker .k-selected-color .k-i-line {
+  font-size: 2em;
+  color: #FF525E;
+  display: inline-block;
+  -moz-transform: scaleX(-1);
+  -o-transform: scaleX(-1);
+  -webkit-transform: scaleX(-1);
+  transform: scaleX(-1);
+  filter: FlipH;
+  -ms-filter: "FlipH";
+}
+.k-colorpicker .k-selected-color .k-i-line:before {
+  content: "\e510";
+}
+.k-colorpicker .k-tool-icon {
+  position: relative;
+  top: -2px;
+  display: inline-block;
+  padding: 3px 3px 2px;
+  margin-right: 3px;
+  margin-left: 2px;
+  margin-bottom: 3px;
+  background-repeat: no-repeat;
+  vertical-align: middle;
+  width: 16px;
+  height: 16px;
+  -ms-high-contrast-adjust: none;
+}
+.k-colorpicker .k-tool-icon .k-selected-color {
+  display: block;
+  height: 3px;
+  width: 16px;
+  position: absolute;
+  left: 3px;
+  bottom: -3px;
+  border-radius: 0 !important;
+}
+.k-colorpicker .k-select {
+  cursor: pointer;
+}
+.k-colorpicker .k-picker-wrap .k-icon {
+  overflow: visible;
+}
+.k-disabled-overlay {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  opacity: 0.5;
+  filter: alpha(opacity=50);
+}
+.k-colorpalette {
+  position: relative;
+  line-height: 0;
+  border-width: 0;
+  display: inline-block;
+}
+.k-colorpalette .k-palette {
+  border-collapse: collapse;
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.k-colorpalette .k-item {
+  width: 14px;
+  height: 14px;
+  overflow: hidden;
+  -ms-high-contrast-adjust: none;
+}
+.k-colorpalette .k-item.k-state-selected,
+.k-colorpalette .k-item.k-state-selected:hover {
+  z-index: 100;
+  background: transparent;
+  box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.7), inset 0 0 0 1px rgba(255, 255, 255, 0.45);
+  position: relative;
+}
+.k-colorpalette .k-item:hover {
+  z-index: 101;
+  position: relative;
+  box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.3);
+}
+.k-flatcolorpicker {
+  position: relative;
+  display: inline-block;
+  width: 265px;
+  padding-bottom: 5px;
+}
+div.k-flatcolorpicker {
+  background-color: transparent;
+  background-image: none;
+}
+.k-flatcolorpicker .k-selected-color {
+  background-image: url("../textures/transtexture.png");
+  background-position: 50% 50%;
+  text-align: right;
+}
+.k-flatcolorpicker .k-selected-color input.k-color-value {
+  font-family: Consolas, "Ubuntu Mono", "Lucida Console", "Courier New", monospace;
+  padding: .75em .1em .65em .65em;
+  border: 0;
+  margin: 0;
+  width: 82%;
+}
+.k-flatcolorpicker .k-selected-color .k-color-input {
+  background-color: #fff;
+  display: inline-block;
+  width: 84%;
+  text-align: left;
+}
+.k-flatcolorpicker .k-selected-color .k-clear-color {
+  padding: .4em;
+  line-height: 0;
+}
+.k-flatcolorpicker .k-selected-color .k-clear-color .k-i-reset-color:before {
+  color: #000;
+  opacity: 0.8;
+}
+.k-flatcolorpicker .k-selected-color .k-clear-color .k-i-reset-color:hover,
+.k-flatcolorpicker .k-selected-color .k-clear-color .k-i-reset-color:active {
+  opacity: 1;
+}
+.k-flatcolorpicker .k-clear-color-container .k-clear-color.k-state-focused:active {
+  color: inherit;
+}
+.k-flatcolorpicker .k-clear-color-container .k-clear-color:active {
+  color: #000;
+  opacity: 1;
+}
+.k-flatcolorpicker .k-selected-color .k-clear-color .k-i-reset-color,
+.k-flatcolorpicker .k-clear-color-container .k-clear-color .k-i-reset-color {
+  background-image: none;
+}
+.k-flatcolorpicker .k-clear-color-container {
+  text-align: left;
+}
+.k-flatcolorpicker .k-hsv-rectangle {
+  position: relative;
+  user-select: none;
+  -ms-touch-action: pinch-zoom double-tap-zoom;
+}
+.k-flatcolorpicker .k-hsv-rectangle .k-draghandle {
+  cursor: pointer;
+  position: absolute;
+  z-index: 10;
+  left: 50%;
+  top: 50%;
+  width: 8px;
+  height: 8px;
+  border: 1px solid #eee;
+  margin-left: -5px;
+  margin-top: -5px;
+  border-radius: 6px;
+  box-shadow: 0 1px 2px #444;
+  background: transparent;
+}
+.k-flatcolorpicker .k-hsv-rectangle .k-draghandle:hover,
+.k-flatcolorpicker .k-hsv-rectangle .k-draghandle:focus {
+  background: transparent;
+  border-color: #fff;
+  box-shadow: 0 1px 5px #000;
+}
+.k-flatcolorpicker .k-hsv-rectangle.k-dragging,
+.k-flatcolorpicker .k-hsv-rectangle.k-dragging * {
+  cursor: none;
+}
+.k-flatcolorpicker .k-slider-horizontal {
+  height: 20px;
+  width: 90%;
+  margin: 0 5%;
+}
+.k-flatcolorpicker .k-slider-horizontal .k-slider-track {
+  box-shadow: 0 1px 0 #fff, 0 -1px 0 #999;
+}
+.k-flatcolorpicker .k-hue-slider,
+.k-flatcolorpicker .k-transparency-slider {
+  display: block;
+}
+.k-flatcolorpicker .k-hue-slider .k-slider-selection,
+.k-flatcolorpicker .k-transparency-slider .k-slider-selection {
+  background: transparent;
+}
+.k-flatcolorpicker .k-hue-slider .k-draghandle,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle {
+  background: transparent;
+  border: 3px solid #eee;
+  margin-top: 1px;
+  height: 8px;
+  width: 8px;
+  box-shadow: 0 1px 4px #444;
+}
+.k-flatcolorpicker .k-hue-slider .k-draghandle:hover,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle:hover,
+.k-flatcolorpicker .k-hue-slider .k-draghandle:focus,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle:focus {
+  background: transparent;
+  border-color: #fff;
+  box-shadow: 0 1px 5px #000;
+  border-width: 2px;
+  padding: 1px;
+}
+.k-flatcolorpicker .k-hue-slider .k-slider-track {
+  background: linear-gradient(to right, #ff0000 0%, #ffff00 16%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 84%, #ff0004 100%);
+}
+.k-flatcolorpicker .k-transparency-slider .k-slider-track {
+  background-image: url("../textures/transparency.png");
+  background-size: 100% auto;
+  background-position: 100% 50%;
+  background-repeat: no-repeat;
+}
+.k-flatcolorpicker .k-controls {
+  margin-top: 10px;
+  margin-bottom: 5px;
+  text-align: center;
+  font-size: 90%;
+}
+.k-flatcolorpicker .k-controls .k-button {
+  width: 6em;
+}
+.k-flatcolorpicker .k-hsv-gradient {
+  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000000 100%), linear-gradient(to right, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
+  height: 180px;
+  margin-bottom: 5px;
+}
+.k-ie9 .k-flatcolorpicker .k-hue-slider .k-slider-track {
+  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjE2JSIgc3RvcC1jb2xvcj0iI2ZmZmYwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjMzJSIgc3RvcC1jb2xvcj0iIzAwZmYwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzAwZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjY3JSIgc3RvcC1jb2xvcj0iIzAwMDBmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9Ijg0JSIgc3RvcC1jb2xvcj0iI2ZmMDBmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZjAwMDQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+}
+.k-ie9 .k-flatcolorpicker .k-hsv-gradient {
+  background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+}
+.k-ie8 .k-flatcolorpicker .k-hue-slider .k-slider-track {
+  background: url("../textures/hue.png") repeat 0 50%;
+}
+.k-ie8 .k-flatcolorpicker .k-transparency-slider .k-slider-track {
+  background: url("../textures/transparency.png") repeat 0 50%;
+}
+.k-ie8 .k-flatcolorpicker .k-hsv-gradient {
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#00ffffff',GradientType=1) progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#ff000000',GradientType=0);
+}
+.k-rtl .k-multiselect-wrap {
+  padding-right: 0;
+  padding-left: 22px;
+}
+.k-maskedtextbox {
+  position: relative;
+  display: inline-block;
+  background-color: transparent;
+  border-width: 0;
+}
+.k-maskedtextbox ::-ms-clear {
+  display: none;
+  width: 0;
+  height: 0;
+}
+.k-maskedtextbox .k-i-warning {
+  display: none;
+  position: absolute;
+  width: 1.9em;
+  right: 0;
+  top: 50%;
+  transform: translateY(-50%);
+}
+.k-maskedtextbox.k-state-invalid .k-i-warning {
+  display: inline-block;
+}
+.k-dateinput {
+  position: relative;
+  display: inline-block;
+  border-width: 0;
+}
+.k-dateinput.k-widget {
+  background-color: transparent;
+}
+.k-dateinput ::-ms-clear {
+  display: none;
+  width: 0;
+  height: 0;
+}
+.k-dateinput .k-i-warning {
+  display: none;
+  position: absolute;
+  right: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  overflow: visible;
+}
+.k-dateinput.k-state-invalid .k-i-warning {
+  display: inline-block;
+}
+.k-datepicker .k-picker-wrap .k-i-warning {
+  display: none;
+  position: absolute;
+  right: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  overflow: visible;
+}
+.k-datepicker .k-picker-wrap.k-state-invalid .k-i-warning {
+  display: inline-block;
+}
+.k-listbox {
+  box-sizing: border-box;
+  height: 200px;
+}
+.k-listbox.k-widget {
+  background-color: transparent;
+}
+.k-listbox .k-list-scroller {
+  height: 100%;
+  overflow: auto;
+  border-width: 1px;
+  border-style: solid;
+  box-sizing: border-box;
+}
+.k-listbox .k-list-scroller li {
+  cursor: default;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -khtml-user-select: none;
+  -webkit-user-select: none;
+  -webkit-touch-callout: none;
+}
+.k-listbox .k-listbox-toolbar {
+  box-sizing: border-box;
+}
+.k-listbox.k-listbox-toolbar-top {
+  padding: 15px 0 1.42857143em;
+}
+.k-listbox.k-listbox-toolbar-top .k-listbox-toolbar {
+  margin-top: -15px;
+  margin-bottom: 5px;
+}
+.k-listbox.k-listbox-toolbar-top .k-listbox-toolbar li {
+  display: inline-block;
+}
+.k-listbox.k-listbox-toolbar-top .k-listbox-toolbar li + li {
+  margin-left: 5px;
+}
+.k-listbox.k-listbox-toolbar-left .k-listbox-toolbar {
+  float: left;
+  margin-right: 5px;
+}
+.k-listbox.k-listbox-toolbar-left .k-listbox-toolbar li + li {
+  margin-top: 5px;
+}
+.k-listbox.k-listbox-toolbar-right .k-listbox-toolbar {
+  float: right;
+  margin-left: 5px;
+}
+.k-listbox.k-listbox-toolbar-right .k-listbox-toolbar li:not(:last-child) {
+  margin-bottom: 5px;
+}
+.k-listbox.k-listbox-toolbar-bottom {
+  padding: 15px 0 1.45em;
+}
+.k-listbox.k-listbox-toolbar-bottom .k-list-scroller {
+  margin-top: -15px;
+}
+.k-listbox.k-listbox-toolbar-bottom .k-listbox-toolbar {
+  margin-top: 5px;
+}
+.k-listbox.k-listbox-toolbar-bottom .k-listbox-toolbar li {
+  display: inline-block;
+}
+.k-listbox.k-listbox-toolbar-bottom .k-listbox-toolbar li + li {
+  margin-left: 5px;
+}
+.k-listbox .k-ghost {
+  opacity: .5;
+}
+/* Notification */
+.k-notification-wrap {
+  padding: .6em .5em;
+  cursor: default;
+  position: relative;
+  white-space: nowrap;
+}
+.k-notification-button .k-notification-wrap {
+  padding-right: 20px;
+}
+.k-notification-wrap > .k-i-information,
+.k-notification-wrap > .k-i-information,
+.k-notification-wrap > .k-i-information,
+.k-notification-wrap > .k-i-warning,
+.k-notification-wrap > .k-i-information {
+  vertical-align: text-bottom;
+  margin-right: 4px;
+}
+.k-notification-wrap > .k-i-close {
+  position: absolute;
+  top: 7px;
+  right: 4px;
+  display: none;
+}
+.k-notification-button .k-notification-wrap > .k-i-close {
+  display: block;
+}
+/* Progressbar */
+.k-progressbar {
+  display: inline-block;
+  position: relative;
+  vertical-align: middle;
+}
+.k-progressbar {
+  border-radius: 4px;
+}
+.k-progressbar-horizontal {
+  width: 27em;
+  height: 1.9em;
+}
+.k-progressbar-vertical {
+  width: 1.9em;
+  height: 27em;
+}
+.k-progressbar > .k-state-selected {
+  position: absolute;
+  border-style: solid;
+  border-width: 1px;
+  overflow: hidden;
+}
+.k-progressbar-horizontal > .k-state-selected,
+.k-rtl .k-progressbar-horizontal.k-progressbar-reverse > .k-state-selected {
+  left: -1px;
+  right: auto;
+  top: -1px;
+  height: 100%;
+  border-radius: 4px 0 0 4px;
+}
+.k-progressbar-horizontal.k-progressbar-reverse > .k-state-selected,
+.k-rtl .k-progressbar-horizontal > .k-state-selected {
+  left: auto;
+  right: -1px;
+  border-radius: 0 4px 4px 0;
+}
+.k-progressbar-vertical > .k-state-selected {
+  left: -1px;
+  bottom: -1px;
+  width: 100%;
+  border-radius: 0 0 4px 4px;
+}
+.k-progressbar-vertical.k-progressbar-reverse > .k-state-selected {
+  bottom: auto;
+  top: -1px;
+  border-radius: 4px 4px 0 0;
+}
+.k-progressbar > .k-state-selected.k-complete,
+.k-rtl .k-progressbar > .k-state-selected.k-complete {
+  border-radius: 4px;
+}
+.k-progressbar > .k-reset {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  left: -1px;
+  top: -1px;
+  width: 100%;
+  height: 100%;
+  border-radius: 4px;
+  white-space: nowrap;
+}
+.k-progressbar-horizontal .k-item {
+  display: inline-block;
+  height: 100%;
+  border-style: solid;
+  margin-left: -1px;
+}
+.k-progressbar-horizontal .k-item.k-first {
+  margin-left: 0;
+}
+.k-progressbar-horizontal .k-item.k-last {
+  border-right-width: 0;
+}
+.k-progressbar-horizontal .k-item,
+.k-rtl .k-progressbar-horizontal.k-progressbar-reverse .k-item {
+  border-width: 1px 0 1px 1px;
+}
+.k-progressbar-horizontal.k-progressbar-reverse .k-item,
+.k-rtl .k-progressbar-horizontal .k-item {
+  border-width: 1px 0 1px 1px;
+}
+.k-progressbar-horizontal .k-first,
+.k-rtl .k-progressbar-horizontal .k-last,
+.k-rtl .k-progressbar-horizontal.k-progressbar-reverse .k-last {
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+  border-left-width: 1px;
+}
+.k-progressbar-horizontal .k-last,
+.k-rtl .k-progressbar-horizontal .k-first {
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+.k-progressbar-horizontal.k-progressbar-reverse .k-last,
+.k-rtl .k-progressbar-horizontal .k-first {
+  border-right-width: 1px;
+}
+.k-progressbar-horizontal .k-last.k-state-selected {
+  border-right-width: 1px;
+}
+.k-progressbar-vertical .k-item {
+  width: 100%;
+  border-style: solid;
+  border-width: 1px 1px 0 1px;
+  margin-top: -1px;
+}
+.k-progressbar-vertical .k-item.k-first {
+  margin-top: 0;
+}
+.k-progressbar-vertical li.k-item.k-last {
+  border-bottom-width: 0;
+}
+.k-progressbar-vertical .k-first {
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+}
+.k-progressbar-vertical .k-last {
+  border-bottom-left-radius: 4px;
+  border-bottom-right-radius: 4px;
+  border-bottom-width: 1px;
+}
+.k-progressbar-vertical.k-progressbar-reverse .k-item {
+  border-width: 0 1px 1px 1px;
+}
+.k-progressbar-vertical.k-progressbar-reverse .k-first {
+  border-top-width: 1px;
+}
+.k-progress-status-wrap {
+  position: absolute;
+  top: -1px;
+  border: 1px solid transparent;
+  line-height: 2em;
+  width: 100%;
+  height: 100%;
+}
+.k-progress-status-wrap,
+.k-rtl .k-progressbar-horizontal.k-progressbar-reverse .k-progress-status-wrap {
+  left: -1px;
+  right: auto;
+  text-align: right;
+}
+.k-progressbar-horizontal.k-progressbar-reverse .k-progress-status-wrap,
+.k-rtl .k-progressbar-horizontal .k-progress-status-wrap {
+  left: auto;
+  right: -1px;
+  text-align: left;
+}
+.k-progressbar-vertical .k-progress-status-wrap {
+  top: auto;
+  bottom: -1px;
+}
+.k-progressbar-vertical.k-progressbar-reverse .k-progress-status-wrap {
+  bottom: auto;
+  top: -1px;
+}
+.k-progress-status {
+  display: inline-block;
+  padding: 0 .5em;
+  min-width: 10px;
+  white-space: nowrap;
+}
+.k-progressbar-vertical.k-progressbar-reverse .k-progress-status {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+}
+.k-progressbar-vertical .k-progress-status {
+  transform: rotate(-90deg) translateX(-100%);
+  transform-origin: 0 0;
+}
+.k-progressbar-vertical.k-progressbar-reverse .k-progress-status {
+  transform: rotate(90deg) translateX(-100%);
+  transform-origin: 0 100%;
+}
+.k-ie8 .k-progressbar-vertical .k-progress-status {
+  writing-mode: bt-lr;
+  padding: .5em 0;
+}
+/* Slider */
+div.k-slider {
+  position: relative;
+  border-width: 0;
+  background-color: transparent;
+  user-select: none;
+}
+.k-slider-vertical {
+  width: 26px;
+  height: 200px;
+  /* default height */
+}
+.k-slider-horizontal {
+  display: inline-block;
+  width: 200px;
+  /* default width */
+  height: 26px;
+}
+.k-slider-wrap {
+  width: 100%;
+  height: 100%;
+}
+.k-slider .k-button,
+.k-grid .k-slider .k-button {
+  position: absolute;
+  top: 0;
+  width: 24px;
+  min-width: 0;
+  height: 24px;
+  margin: 0;
+  padding: 0;
+  outline: 0;
+}
+.k-slider .k-button .k-icon {
+  margin-top: 3px;
+  vertical-align: top;
+}
+.k-state-disabled .k-slider-wrap {
+  filter: alpha(opacity=60);
+  opacity: .6;
+}
+.k-state-disabled .k-slider-wrap .k-slider-items {
+  color: #333;
+}
+.k-slider .k-button-decrease {
+  left: 0;
+}
+.k-slider-vertical .k-button-decrease,
+.k-grid .k-slider-vertical .k-button-decrease {
+  top: auto;
+  bottom: 0;
+}
+.k-slider .k-button-increase {
+  right: 0;
+}
+.k-slider .k-icon,
+.k-slider-track,
+.k-slider .k-tick {
+  cursor: pointer;
+}
+.k-slider-track,
+.k-slider-selection {
+  position: absolute;
+  margin: 0;
+  padding: 0;
+}
+.k-slider-horizontal .k-slider-track,
+.k-slider-horizontal .k-slider-selection {
+  top: 50%;
+  left: 0;
+  height: 8px;
+  margin-top: -4px;
+  background-repeat: repeat-x;
+}
+.k-slider-horizontal .k-slider-buttons .k-slider-track {
+  left: 34px;
+}
+.k-slider-vertical .k-slider-track,
+.k-slider-vertical .k-slider-selection {
+  left: 50%;
+  bottom: 0;
+  width: 8px;
+  margin-left: -4px;
+  background-repeat: repeat-y;
+}
+.k-slider-vertical .k-slider-buttons .k-slider-track {
+  bottom: 34px;
+}
+.k-draghandle {
+  position: absolute;
+  background-repeat: no-repeat;
+  background-color: transparent;
+  text-indent: -3333px;
+  overflow: hidden;
+  text-decoration: none;
+  text-align: center;
+  outline: 0;
+}
+.k-slider-horizontal .k-draghandle {
+  top: -4px;
+  width: 13px;
+  height: 14px;
+}
+.k-slider-vertical .k-draghandle {
+  left: -4px;
+  width: 14px;
+  height: 13px;
+}
+.k-slider-buttons .k-slider-items {
+  margin-left: 34px;
+}
+.k-slider-horizontal .k-slider-items {
+  height: 100%;
+}
+.k-slider-vertical .k-slider-items {
+  padding-top: 1px;
+}
+.k-slider-vertical .k-slider-buttons .k-slider-items {
+  padding-top: 0;
+}
+.k-slider-vertical .k-slider-buttons .k-slider-items {
+  margin: 0;
+  padding-top: 35px;
+}
+.k-slider .k-tick {
+  position: relative;
+  margin: 0;
+  padding: 0;
+  background-color: transparent;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.k-slider-horizontal .k-tick {
+  float: left;
+  height: 100%;
+  text-align: center;
+}
+.k-slider-horizontal .k-tick {
+  background-position: center -92px;
+}
+.k-slider-horizontal .k-slider-topleft .k-tick {
+  background-position: center -122px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-tick {
+  background-position: center -152px;
+}
+.k-slider-horizontal .k-tick-large {
+  background-position: center -2px;
+}
+.k-slider-horizontal .k-slider-topleft .k-tick-large {
+  background-position: center -32px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-tick-large {
+  background-position: center -62px;
+}
+.k-slider-vertical .k-tick {
+  background-position: -92px center;
+}
+.k-slider-vertical .k-slider-topleft .k-tick {
+  background-position: -122px center;
+}
+.k-slider-vertical .k-slider-bottomright .k-tick {
+  background-position: -152px center;
+}
+.k-slider-vertical .k-tick-large {
+  background-position: -2px center;
+}
+.k-slider-vertical .k-slider-topleft .k-tick-large {
+  background-position: -32px center;
+}
+.k-slider-vertical .k-slider-bottomright .k-tick-large {
+  background-position: -62px center;
+}
+.k-slider-horizontal .k-first {
+  background-position: 0 -92px;
+}
+.k-slider-horizontal .k-tick-large.k-first {
+  background-position: 0 -2px;
+}
+.k-slider-horizontal .k-slider-topleft .k-first {
+  background-position: 0 -122px;
+}
+.k-slider-horizontal .k-slider-topleft .k-tick-large.k-first {
+  background-position: 0 -32px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-first {
+  background-position: 0 -152px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-tick-large.k-first {
+  background-position: 0 -62px;
+}
+.k-slider-horizontal .k-last {
+  background-position: 100% -92px;
+}
+.k-slider-horizontal .k-tick-large.k-last {
+  background-position: 100% -2px;
+}
+.k-slider-horizontal .k-slider-topleft .k-last {
+  background-position: 100% -122px;
+}
+.k-slider-horizontal .k-slider-topleft .k-tick-large.k-last {
+  background-position: 100% -32px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-last {
+  background-position: 100% -152px;
+}
+.k-slider-horizontal .k-slider-bottomright .k-tick-large.k-last {
+  background-position: 100% -62px;
+}
+.k-slider-vertical .k-first {
+  background-position: -92px 100%;
+}
+.k-slider-vertical .k-tick-large.k-first {
+  background-position: -2px 100%;
+}
+.k-slider-vertical .k-slider-topleft .k-first {
+  background-position: -122px 100%;
+}
+.k-slider-vertical .k-slider-topleft .k-tick-large.k-first {
+  background-position: -32px 100%;
+}
+.k-slider-vertical .k-slider-bottomright .k-first {
+  background-position: -152px 100%;
+}
+.k-slider-vertical .k-slider-bottomright .k-tick-large.k-first {
+  background-position: -62px 100%;
+}
+.k-slider-vertical .k-last {
+  background-position: -92px 0;
+}
+.k-slider-vertical .k-tick-large.k-last {
+  background-position: -2px 0;
+}
+.k-slider-vertical .k-slider-topleft .k-last {
+  background-position: -122px 0;
+}
+.k-slider-vertical .k-slider-topleft .k-tick-large.k-last {
+  background-position: -32px 0;
+}
+.k-slider-vertical .k-slider-bottomright .k-last {
+  background-position: -152px 0;
+}
+.k-slider-vertical .k-slider-bottomright .k-tick-large.k-last {
+  background-position: -62px 0;
+}
+.k-slider-vertical .k-tick {
+  text-align: right;
+}
+.k-slider-vertical .k-slider-topleft .k-tick {
+  text-align: left;
+}
+.k-slider .k-label {
+  position: absolute;
+  white-space: nowrap;
+  font-size: .92em;
+}
+.k-slider-horizontal .k-label {
+  left: 0;
+  width: 100%;
+  line-height: 1;
+}
+.k-slider-horizontal .k-first .k-label {
+  left: -50%;
+}
+.k-slider-horizontal .k-last .k-label {
+  left: auto;
+  right: -50%;
+}
+.k-slider-horizontal .k-label {
+  bottom: -1.2em;
+}
+.k-slider-horizontal .k-slider-topleft .k-label {
+  top: -1.2em;
+}
+.k-slider-vertical .k-label {
+  left: 120%;
+  display: block;
+  text-align: left;
+}
+.k-slider-vertical .k-last .k-label {
+  top: -0.5em;
+}
+.k-slider-vertical .k-first .k-label {
+  bottom: -0.5em;
+}
+.k-slider-vertical .k-slider-topleft .k-label {
+  left: auto;
+  right: 120%;
+}
+.k-slider-tooltip {
+  top: -4444px;
+  /*prevent window resize in IE8 when appending*/
+}
+/* Tooltip */
+.k-tooltip {
+  position: absolute;
+  z-index: 12000;
+  border-style: solid;
+  border-width: 0;
+  padding: 5px 5px 5px 6px;
+  background-repeat: repeat-x;
+  min-width: 20px;
+  /*slider tooltip only*/
+  text-align: center;
+  /*slider tooltip only*/
+}
+.k-tooltip-button {
+  text-align: right;
+  height: 0;
+}
+.k-tooltip-content {
+  height: 100%;
+}
+.k-tooltip-closable .k-tooltip-content {
+  padding-right: 20px;
+}
+span.k-tooltip {
+  position: static;
+  display: inline-block;
+  border-width: 1px;
+  padding: 2px 5px 1px 6px;
+}
+.k-invalid-msg {
+  display: none;
+}
+.k-callout {
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-style: solid;
+  border-width: 6px;
+  border-color: transparent;
+  pointer-events: none;
+}
+.k-callout-n {
+  top: -12px;
+  left: 50%;
+  pointer-events: none;
+}
+.k-callout-w {
+  top: 50%;
+  left: -12px;
+  pointer-events: none;
+}
+.k-callout-s {
+  left: 50%;
+  bottom: -12px;
+  pointer-events: none;
+}
+.k-callout-e {
+  top: 50%;
+  right: -12px;
+  pointer-events: none;
+}
+.k-slider-tooltip .k-callout-n,
+.k-slider-tooltip .k-callout-s {
+  margin-left: -6px;
+}
+.k-slider-tooltip .k-callout-w,
+.k-slider-tooltip .k-callout-e {
+  margin-top: -6px;
+}
+.k-tooltip-validation .k-i-warning {
+  vertical-align: text-top;
+  margin-right: 3px;
+}
+.k-tooltip-validation {
+  z-index: 9999;
+}
+/* Toolbar */
+.k-toolbar {
+  position: relative;
+  display: block;
+  vertical-align: middle;
+  line-height: 2.9em;
+}
+.k-toolbar .k-button .k-icon,
+.k-toolbar .k-button .k-sprite,
+.k-overflow-container .k-button .k-icon,
+.k-overflow-container .k-button .k-sprite {
+  vertical-align: middle;
+  margin-top: -7px;
+  margin-bottom: -5px;
+}
+.k-toolbar .k-input {
+  line-height: inherit;
+  height: inherit;
+  padding-top: 2px;
+  padding-bottom: 2px;
+}
+.k-toolbar .k-input:before {
+  content: "\a0";
+  display: inline-block;
+  width: 0;
+}
+.k-ie .k-toolbar .k-input {
+  height: 1.65em;
+}
+.k-toolbar .k-combobox .k-dropdown-wrap:before,
+.k-toolbar .k-picker-wrap:before,
+.k-toolbar .k-numeric-wrap:before {
+  display: none;
+}
+.k-overflow-container .k-sprite {
+  margin-left: -4px;
+}
+.k-toolbar-resizable {
+  overflow: hidden;
+  white-space: nowrap;
+}
+.k-toolbar > .k-align-left {
+  float: none;
+}
+.k-toolbar > .k-align-right {
+  float: right;
+}
+.k-toolbar > *,
+.k-toolbar .k-button {
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 1.72em;
+}
+.k-toolbar .k-separator {
+  border-width: 0 0 0 1px;
+  border-style: solid;
+  width: 1px;
+  line-height: inherit;
+}
+.k-toolbar .k-button-group {
+  list-style-type: none;
+}
+.k-toolbar .k-button-group > li {
+  display: inline-block;
+}
+.k-toolbar .k-button-group .k-button {
+  margin: 0 0 0 -1px;
+  border-radius: 0;
+}
+.k-toolbar .k-button,
+.k-toolbar .k-split-button,
+.k-toolbar .k-button-group,
+.k-toolbar .k-widget,
+.k-toolbar .k-textbox,
+.k-toolbar label,
+.k-toolbar .k-separator {
+  margin: 0 .2em;
+  line-height: 1.72em;
+  vertical-align: middle;
+}
+.k-toolbar .k-split-button {
+  padding-left: 0;
+}
+.k-toolbar .k-split-button .k-button,
+.k-toolbar .k-button-group .k-group-start {
+  margin: 0;
+}
+.k-toolbar .k-split-button .k-split-button-arrow {
+  margin: 0 0 0 -1px;
+}
+.k-toolbar .k-overflow-anchor {
+  border-width: 0 0 0 1px;
+  border-style: solid;
+  height: 3em;
+  width: 3em;
+  line-height: inherit;
+  padding: 0 .5em;
+  margin: 0;
+  position: relative;
+  float: right;
+  border-radius: 0;
+}
+.k-overflow-container .k-item {
+  float: none;
+  border: 0;
+}
+.k-overflow-container .k-separator {
+  border-width: 0 0 1px;
+  border-style: solid;
+  height: 1px;
+  line-height: 0;
+  font-size: 0;
+  padding: 0;
+}
+.k-overflow-container .k-overflow-button,
+.k-split-container .k-button {
+  text-align: left;
+  display: block;
+  background: none;
+  border-color: transparent;
+  white-space: nowrap;
+}
+.k-split-container {
+  margin-top: -1px;
+}
+.k-overflow-container .k-button-group {
+  padding: 0;
+}
+.k-overflow-container .k-button-group > li {
+  display: block;
+}
+.k-overflow-container .k-overflow-group {
+  border-width: 1px 0;
+  border-style: solid;
+  border-radius: 0;
+  padding: 2px 0;
+  margin: 1px 0;
+}
+.k-overflow-container .k-overflow-hidden {
+  display: none;
+}
+.k-overflow-container .k-toolbar-first-visible,
+.k-overflow-container .k-overflow-group + .k-overflow-group,
+.k-overflow-container .k-separator + .k-overflow-group {
+  border-top: 0;
+  margin-top: 0;
+  padding-top: 1px;
+}
+.k-overflow-container .k-overflow-group + .k-separator {
+  display: none;
+}
+.k-overflow-container .k-toolbar-last-visible {
+  border-bottom: 0;
+  margin-bottom: 0;
+  padding-bottom: 1px;
+}
+/* Splitter */
+.k-splitter {
+  position: relative;
+  height: 300px;
+}
+.k-pane > .k-splitter {
+  border-width: 0;
+  overflow: hidden;
+}
+.k-splitter .k-pane {
+  overflow: hidden;
+}
+.k-splitter .k-scrollable {
+  overflow: auto;
+}
+.k-splitter .k-pane-loading {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  margin: -8px 0 0 -8px;
+}
+.k-ghost-splitbar,
+.k-splitbar {
+  position: absolute;
+  border-style: solid;
+  font-size: 0;
+  outline: 0;
+  user-select: none;
+}
+.k-splitter .k-ghost-splitbar-horizontal,
+.k-splitter .k-splitbar-horizontal {
+  top: 0;
+  width: 5px;
+  border-width: 0 1px;
+  background-repeat: repeat-y;
+}
+.k-ghost-splitbar-vertical,
+.k-splitbar-vertical {
+  left: 0;
+  height: 5px;
+  border-width: 1px 0;
+  background-repeat: repeat-x;
+}
+.k-splitbar-draggable-horizontal {
+  cursor: w-resize;
+}
+.k-splitbar-draggable-vertical {
+  cursor: n-resize;
+}
+.k-splitbar .k-resize-handle {
+  display: none;
+}
+.k-restricted-size-horizontal,
+.k-restricted-size-vertical {
+  background-color: #f00;
+}
+.k-splitbar-horizontal .k-icon {
+  position: absolute;
+  top: 50%;
+  margin-top: -10px;
+}
+.k-splitbar-horizontal .k-i-arrow-60-right {
+  margin-left: -2px;
+}
+.k-splitbar-horizontal.k-splitbar-draggable-horizontal .k-i-arrow-60-right {
+  margin-top: 13px;
+}
+.k-splitbar-horizontal .k-i-arrow-60-left {
+  margin-left: -3px;
+}
+.k-splitbar-horizontal.k-splitbar-draggable-horizontal .k-i-arrow-60-left {
+  margin-top: -28px;
+}
+.k-splitbar-vertical .k-i-arrow-60-up {
+  margin-top: -2px;
+}
+.k-splitbar-vertical .k-i-arrow-60-down {
+  margin-top: -2px;
+}
+.k-splitbar-vertical.k-splitbar-draggable-vertical .k-i-arrow-60-up {
+  margin-left: -17px;
+}
+.k-splitbar-vertical.k-splitbar-draggable-vertical .k-i-arrow-60-down {
+  margin-left: 23px;
+}
+.k-i-arrow-60-up,
+.k-i-arrow-60-right,
+.k-i-arrow-60-down,
+.k-i-arrow-60-left {
+  cursor: pointer;
+}
+.k-splitbar-horizontal .k-icon {
+  position: absolute;
+  top: 50%;
+  width: 7px;
+  height: 20px;
+  margin-top: -10px;
+}
+.k-splitbar-static-horizontal {
+  width: 1px;
+}
+.k-splitbar-static-vertical {
+  height: 1px;
+}
+.k-splitbar-vertical .k-icon {
+  position: absolute;
+  left: 50%;
+}
+.k-splitbar-draggable-vertical .k-resize-handle,
+.k-splitbar-draggable-horizontal .k-resize-handle {
+  display: inline-block;
+  border-radius: 1px;
+}
+.k-splitbar-draggable-horizontal .k-resize-handle {
+  width: 3px;
+  height: 16px;
+  margin-left: 1px;
+}
+.k-splitbar-draggable-vertical .k-resize-handle {
+  width: 16px;
+  height: 3px;
+  margin-top: 1px;
+}
+.k-splitbar .k-i-arrow-60-up,
+.k-splitbar .k-i-arrow-60-right,
+.k-splitbar .k-i-arrow-60-down,
+.k-splitbar .k-i-arrow-60-left {
+  font-size: 10px;
+}
+.k-splitter-resizing {
+  overflow: hidden;
+}
+.k-rtl .k-splitbar-horizontal .k-resize-handle {
+  margin-right: 1px;
+}
+.k-rtl .k-splitbar-horizontal .k-i-arrow-60-right {
+  margin-top: 13px;
+  margin-right: -3px;
+}
+.k-rtl .k-splitbar-horizontal .k-i-arrow-60-left {
+  margin-top: -28px;
+  margin-right: -2px;
+}
+.k-rtl .k-splitbar-vertical .k-i-arrow-60-up {
+  margin-top: -2px;
+  margin-left: -17px;
+}
+.k-rtl .k-splitbar-vertical .k-i-arrow-60-down {
+  margin-top: -2px;
+  margin-left: 23px;
+}
+/* Virtual List */
+.k-virtual-wrap {
+  position: relative;
+}
+.k-virtual-wrap .k-list.k-virtual-list {
+  height: auto;
+}
+.k-virtual-content {
+  overflow-y: scroll;
+  /* has to be scroll, not auto */
+  -webkit-overflow-scrolling: touch;
+  position: relative;
+}
+.k-virtual-list > .k-virtual-content {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+}
+.k-virtual-option-label {
+  width: 100%;
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+}
+.k-virtual-wrap > .k-virtual-header {
+  text-align: right;
+}
+.k-popup .k-item.k-first {
+  position: relative;
+}
+.k-virtual-content > .k-virtual-list > .k-virtual-item {
+  position: absolute;
+  width: 100%;
+  box-sizing: border-box;
+  overflow: hidden;
+  white-space: nowrap;
+}
+.k-popup .k-list .k-item > .k-group,
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header {
+  text-transform: uppercase;
+  font-size: .857em;
+}
+.k-popup .k-list .k-item > .k-group {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 0 .5em;
+  line-height: 1.8;
+}
+.k-popup .k-state-hover > .k-group {
+  right: -1px;
+}
+.k-virtual-item.k-first,
+.k-group-header + .k-list > .k-item.k-first,
+.k-static-header + .k-list > .k-item.k-first {
+  border-top-style: solid;
+  border-top-width: 1px;
+  padding-top: 0;
+}
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header {
+  text-align: right;
+}
+/* Dialog */
+.k-dialog {
+  min-width: 90px;
+  min-height: 3em;
+  max-width: 100%;
+  max-height: 100%;
+}
+.k-window.k-dialog {
+  position: fixed;
+  padding-top: 0;
+}
+.k-dialog .k-dialog-titlebar {
+  position: static;
+  margin: 0;
+  padding: 0.6em 0.8em 1em 0.8em;
+  width: auto;
+}
+.k-dialog .k-dialog-titlebar .k-dialog-title {
+  margin: 0;
+  padding: 0;
+  width: auto;
+  max-width: 98%;
+  display: inline-block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-size: 1.2em;
+  line-height: 1.2em;
+}
+.k-dialog .k-content {
+  margin: 0;
+  padding: 1.8em 1em 1.8em 1em;
+}
+.k-dialog.k-dialog-titleless .k-content {
+  padding: 2.4em;
+}
+.k-dialog .k-dialog-buttongroup {
+  margin: 0;
+  padding: 0;
+}
+.k-dialog a.k-dialog-action.k-dialog-close {
+  position: absolute;
+  top: .35em;
+  right: 0;
+  cursor: pointer;
+  z-index: 10000;
+}
+.k-dialog.k-dialog-titleless a.k-dialog-action.k-dialog-close {
+  right: .5em;
+  top: 1em;
+}
+.k-dialog.k-alert .k-dialog-titlebar,
+.k-dialog.k-confirm .k-dialog-titlebar,
+.k-dialog.k-prompt .k-dialog-titlebar {
+  background: none;
+  border-bottom: none;
+}
+.k-dialog.k-alert .k-content,
+.k-dialog.k-confirm .k-content {
+  padding: 2.4em;
+}
+.k-dialog.k-prompt .k-content {
+  padding: 1.2em 1.2em 0.6em 1.2em;
+}
+.k-dialog .k-prompt-container {
+  width: auto;
+  padding: 0.6em 1.2em 1.8em 1.2em;
+}
+.k-dialog .k-prompt-container .k-textbox {
+  width: 100%;
+}
+.k-dialog .k-button {
+  box-sizing: border-box;
+}
+@font-face {
+  font-family: 'WebComponentsIcons';
+  src: url('../fonts/glyphs/WebComponentsIcons.eot?gedxeo');
+  src: url('../fonts/glyphs/WebComponentsIcons.eot?gedxeo#iefix') format('embedded-opentype'), url('../fonts/glyphs/WebComponentsIcons.ttf?gedxeo') format('truetype'), url('../fonts/glyphs/WebComponentsIcons.woff?gedxeo') format('woff'), url('../fonts/glyphs/WebComponentsIcons.svg?gedxeo#WebComponentsIcons') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+.k-i-arrow-45-up-right:before {
+  content: "\e000";
+}
+.k-i-collapse-ne:before {
+  content: "\e000";
+}
+.k-i-resize-ne:before {
+  content: "\e000";
+}
+.k-i-arrow-45-down-right:before {
+  content: "\e001";
+}
+.k-i-collapse-se:before {
+  content: "\e001";
+}
+.k-i-collapse:before {
+  content: "\e001";
+}
+.k-i-resize-se:before {
+  content: "\e001";
+}
+.k-i-arrow-45-down-left:before {
+  content: "\e002";
+}
+.k-i-collapse-sw:before {
+  content: "\e002";
+}
+.k-i-resize-sw:before {
+  content: "\e002";
+}
+.k-i-arrow-45-up-left:before {
+  content: "\e003";
+}
+.k-i-collapse-nw:before {
+  content: "\e003";
+}
+.k-i-resize-new:before {
+  content: "\e003";
+}
+.k-i-arrow-60-up:before {
+  content: "\e004";
+}
+.k-i-arrow-n:before {
+  content: "\e004";
+}
+.k-i-arrow-60-right:before {
+  content: "\e005";
+}
+.k-i-arrow-e:before {
+  content: "\e005";
+}
+.k-i-expand:before {
+  content: "\e005";
+}
+.k-i-arrow-60-down:before {
+  content: "\e006";
+}
+.k-i-arrow-s:before {
+  content: "\e006";
+}
+.k-i-arrow-60-left:before {
+  content: "\e007";
+}
+.k-i-arrow-w:before {
+  content: "\e007";
+}
+.k-i-arrow-end-up:before {
+  content: "\e008";
+}
+.k-i-seek-n:before {
+  content: "\e008";
+}
+.k-i-arrow-end-right:before {
+  content: "\e009";
+}
+.k-i-seek-e:before {
+  content: "\e009";
+}
+.k-i-arrow-end-down:before {
+  content: "\e00a";
+}
+.k-i-seek-s:before {
+  content: "\e00a";
+}
+.k-i-arrow-end-left:before {
+  content: "\e00b";
+}
+.k-i-seek-w:before {
+  content: "\e00b";
+}
+.k-i-arrow-double-60-up:before {
+  content: "\e00c";
+}
+.k-i-arrow-seek-up:before {
+  content: "\e00c";
+}
+.k-i-arrow-double-60-right:before {
+  content: "\e00d";
+}
+.k-i-arrow-seek-right:before {
+  content: "\e00d";
+}
+.k-i-arrow-double-60-down:before {
+  content: "\e00e";
+}
+.k-i-arrow-seek-down:before {
+  content: "\e00e";
+}
+.k-i-arrow-double-60-left:before {
+  content: "\e00f";
+}
+.k-i-arrow-seek-left:before {
+  content: "\e00f";
+}
+.k-i-arrows-kpi:before {
+  content: "\e010";
+}
+.k-i-kpi:before {
+  content: "\e010";
+}
+.k-i-arrows-no-change:before {
+  content: "\e011";
+}
+.k-i-arrow-overflow-down:before {
+  content: "\e012";
+}
+.k-i-arrow-chevron-up:before {
+  content: "\e013";
+}
+.k-i-arrow-chevron-right:before {
+  content: "\e014";
+}
+.k-i-arrow-chevron-down:before {
+  content: "\e015";
+}
+.k-i-arrow-chevron-left:before {
+  content: "\e016";
+}
+.k-i-arrow-up:before {
+  content: "\e017";
+}
+.k-i-arrow-right:before {
+  content: "\e018";
+}
+.k-i-arrow-down:before {
+  content: "\e019";
+}
+.k-i-arrow-left:before {
+  content: "\e01a";
+}
+.k-i-arrow-drill:before {
+  content: "\e01b";
+}
+.k-i-arrow-parent:before {
+  content: "\e01c";
+}
+.k-i-arrow-root:before {
+  content: "\e01d";
+}
+.k-i-arrows-resizing:before {
+  content: "\e01e";
+}
+.k-i-arrows-dimensions:before {
+  content: "\e01f";
+}
+.k-i-arrows-swap:before {
+  content: "\e020";
+}
+.k-i-drag-and-drop:before {
+  content: "\e021";
+}
+.k-i-categorize:before {
+  content: "\e022";
+}
+.k-i-grid:before {
+  content: "\e023";
+}
+.k-i-grid-layout:before {
+  content: "\e024";
+}
+.k-i-group:before {
+  content: "\e025";
+}
+.k-i-ungroup:before {
+  content: "\e026";
+}
+.k-i-handler-drag:before {
+  content: "\e027";
+}
+.k-i-layout:before {
+  content: "\e028";
+}
+.k-i-layout-1-by-4:before {
+  content: "\e029";
+}
+.k-i-layout-2-by-2:before {
+  content: "\e02a";
+}
+.k-i-layout-side-by-side:before {
+  content: "\e02b";
+}
+.k-i-layout-stacked:before {
+  content: "\e02c";
+}
+.k-i-columns:before {
+  content: "\e02d";
+}
+.k-i-rows:before {
+  content: "\e02e";
+}
+.k-i-reorder:before {
+  content: "\e02f";
+}
+.k-i-menu:before {
+  content: "\e030";
+}
+.k-i-more-vertical:before {
+  content: "\e031";
+}
+.k-i-more-horizontal:before {
+  content: "\e032";
+}
+.k-i-undo:before {
+  content: "\e100";
+}
+.k-i-redo:before {
+  content: "\e101";
+}
+.k-i-reset:before {
+  content: "\e102";
+}
+.k-i-reload:before {
+  content: "\e103";
+}
+.k-i-refresh:before {
+  content: "\e103";
+}
+.k-i-non-recurrence:before {
+  content: "\e104";
+}
+.k-i-reset-sm:before {
+  content: "\e105";
+}
+.k-i-reload-sm:before {
+  content: "\e106";
+}
+.k-i-refresh-sm:before {
+  content: "\e106";
+}
+.k-i-clock:before {
+  content: "\e107";
+}
+.k-i-calendar:before {
+  content: "\e108";
+}
+.k-i-save:before {
+  content: "\e109";
+}
+.k-i-floppy:before {
+  content: "\e109";
+}
+.k-i-print:before {
+  content: "\e10a";
+}
+.k-i-printer:before {
+  content: "\e10a";
+}
+.k-i-edit:before {
+  content: "\e10b";
+}
+.k-i-pencil:before {
+  content: "\e10b";
+}
+.k-i-delete:before {
+  content: "\e10c";
+}
+.k-i-trash:before {
+  content: "\e10c";
+}
+.k-i-attachment:before {
+  content: "\e10d";
+}
+.k-i-clip:before {
+  content: "\e10d";
+}
+.k-i-attachment-45:before {
+  content: "\e10e";
+}
+.k-i-clip-45:before {
+  content: "\e10e";
+}
+.k-i-link-horizontal:before {
+  content: "\e10f";
+}
+.k-i-hyperlink:before {
+  content: "\e10f";
+}
+.k-i-unlink-horizontal:before {
+  content: "\e110";
+}
+.k-i-hyperlink-remove:before {
+  content: "\e110";
+}
+.k-i-link-vertical:before {
+  content: "\e111";
+}
+.k-i-unlink-vertical:before {
+  content: "\e112";
+}
+.k-i-lock:before {
+  content: "\e113";
+}
+.k-i-unlock:before {
+  content: "\e114";
+}
+.k-i-cancel:before {
+  content: "\e115";
+}
+.k-i-cancel-outline:before {
+  content: "\e116";
+}
+.k-i-cancel-circle:before {
+  content: "\e117";
+}
+.k-i-check:before {
+  content: "\e118";
+}
+.k-i-checkmark:before {
+  content: "\e118";
+}
+.k-i-success:before {
+  content: "\e118";
+}
+.k-i-check-outline:before {
+  content: "\e119";
+}
+.k-i-checkmark-outline:before {
+  content: "\e119";
+}
+.k-i-check-circle:before {
+  content: "\e11a";
+}
+.k-i-checkmark-circle:before {
+  content: "\e11a";
+}
+.k-i-close:before {
+  content: "\e11b";
+}
+.k-i-x:before {
+  content: "\e11b";
+}
+.k-i-close-outline:before {
+  content: "\e11c";
+}
+.k-i-x-outline:before {
+  content: "\e11c";
+}
+.k-i-close-circle:before {
+  content: "\e11d";
+}
+.k-i-x-circle:before {
+  content: "\e11d";
+}
+.k-i-plus:before {
+  content: "\e11e";
+}
+.k-i-add:before {
+  content: "\e11e";
+}
+.k-i-plus-outline:before {
+  content: "\e11f";
+}
+.k-i-plus-circle:before {
+  content: "\e120";
+}
+.k-i-minus:before {
+  content: "\e121";
+}
+.k-i-minus-outline:before {
+  content: "\e122";
+}
+.k-i-minus-circle:before {
+  content: "\e123";
+}
+.k-i-sort-asc:before {
+  content: "\e124";
+}
+.k-i-sort-desc:before {
+  content: "\e125";
+}
+.k-i-unsort:before {
+  content: "\e126";
+}
+.k-i-sort-clear:before {
+  content: "\e126";
+}
+.k-i-sort-asc-sm:before {
+  content: "\e127";
+}
+.k-i-sort-desc-sm:before {
+  content: "\e128";
+}
+.k-i-filter:before {
+  content: "\e129";
+}
+.k-i-filter-clear:before {
+  content: "\e12a";
+}
+.k-i-filter-sm:before {
+  content: "\e12b";
+}
+.k-i-filter-sort-asc-sm:before {
+  content: "\e12c";
+}
+.k-i-filter-sort-desc-sm:before {
+  content: "\e12d";
+}
+.k-i-filter-add-expression:before {
+  content: "\e12e";
+}
+.k-i-filter-add-group:before {
+  content: "\e12f";
+}
+.k-i-login:before {
+  content: "\e130";
+}
+.k-i-logout:before {
+  content: "\e131";
+}
+.k-i-download:before {
+  content: "\e132";
+}
+.k-i-upload:before {
+  content: "\e133";
+}
+.k-i-hyperlink-open:before {
+  content: "\e134";
+}
+.k-i-hyperlink-open-sm:before {
+  content: "\e135";
+}
+.k-i-launch:before {
+  content: "\e136";
+}
+.k-i-window:before {
+  content: "\e137";
+}
+.k-i-window-maximize:before {
+  content: "\e137";
+}
+.k-i-windows:before {
+  content: "\e138";
+}
+.k-i-window-restore:before {
+  content: "\e138";
+}
+.k-i-tiles:before {
+  content: "\e138";
+}
+.k-i-window-minimize:before {
+  content: "\e139";
+}
+.k-i-gear:before {
+  content: "\e13a";
+}
+.k-i-cog:before {
+  content: "\e13a";
+}
+.k-i-custom:before {
+  content: "\e13a";
+}
+.k-i-gears:before {
+  content: "\e13b";
+}
+.k-i-cogs:before {
+  content: "\e13b";
+}
+.k-i-wrench:before {
+  content: "\e13c";
+}
+.k-i-settings:before {
+  content: "\e13c";
+}
+.k-i-preview:before {
+  content: "\e13d";
+}
+.k-i-eye:before {
+  content: "\e13d";
+}
+.k-i-zoom:before {
+  content: "\e13e";
+}
+.k-i-search:before {
+  content: "\e13e";
+}
+.k-i-zoom-in:before {
+  content: "\e13f";
+}
+.k-i-zoom-out:before {
+  content: "\e140";
+}
+.k-i-pan:before {
+  content: "\e141";
+}
+.k-i-move:before {
+  content: "\e141";
+}
+.k-i-calculator:before {
+  content: "\e142";
+}
+.k-i-cart:before {
+  content: "\e143";
+}
+.k-i-shopping-cart:before {
+  content: "\e143";
+}
+.k-i-connector:before {
+  content: "\e144";
+}
+.k-i-plus-sm:before {
+  content: "\e145";
+}
+.k-i-minus-sm:before {
+  content: "\e146";
+}
+.k-i-play:before {
+  content: "\e200";
+}
+.k-i-pause:before {
+  content: "\e201";
+}
+.k-i-stop:before {
+  content: "\e202";
+}
+.k-i-rewind:before {
+  content: "\e203";
+}
+.k-i-forward:before {
+  content: "\e204";
+}
+.k-i-volume-down:before {
+  content: "\e205";
+}
+.k-i-volume-up:before {
+  content: "\e206";
+}
+.k-i-volume-off:before {
+  content: "\e207";
+}
+.k-i-hd:before {
+  content: "\e208";
+}
+.k-i-subtitles:before {
+  content: "\e209";
+}
+.k-i-playlist:before {
+  content: "\e20a";
+}
+.k-i-play-sm:before {
+  content: "\e20c";
+}
+.k-i-pause-sm:before {
+  content: "\e20d";
+}
+.k-i-stop-sm:before {
+  content: "\e20e";
+}
+.k-i-audio:before {
+  content: "\e20b";
+}
+.k-i-heart-outline:before {
+  content: "\e300";
+}
+.k-i-fav-outline:before {
+  content: "\e300";
+}
+.k-i-favorite-outline:before {
+  content: "\e300";
+}
+.k-i-heart:before {
+  content: "\e301";
+}
+.k-i-fav:before {
+  content: "\e301";
+}
+.k-i-favorite:before {
+  content: "\e301";
+}
+.k-i-star-outline:before {
+  content: "\e302";
+}
+.k-i-bookmark-outline:before {
+  content: "\e302";
+}
+.k-i-star:before {
+  content: "\e303";
+}
+.k-i-bookmark:before {
+  content: "\e303";
+}
+.k-i-checkbox:before {
+  content: "\e304";
+}
+.k-i-shape-rect:before {
+  content: "\e304";
+}
+.k-i-checkbox-checked:before {
+  content: "\e305";
+}
+.k-i-tri-state-indeterminate:before {
+  content: "\e306";
+}
+.k-i-tri-state-null:before {
+  content: "\e307";
+}
+.k-i-circle:before {
+  content: "\e308";
+}
+.k-i-radiobutton:before {
+  content: "\e309";
+}
+.k-i-shape-circle:before {
+  content: "\e309";
+}
+.k-i-radiobutton-checked:before {
+  content: "\e30a";
+}
+.k-i-notification:before {
+  content: "\e400";
+}
+.k-i-bell:before {
+  content: "\e400";
+}
+.k-i-information:before {
+  content: "\e401";
+}
+.k-i-info:before {
+  content: "\e401";
+}
+.k-i-question:before {
+  content: "\e402";
+}
+.k-i-help:before {
+  content: "\e402";
+}
+.k-i-warning:before {
+  content: "\e403";
+}
+.k-i-exception:before {
+  content: "\e403";
+}
+.k-i-error:before {
+  content: "\e403";
+}
+.k-i-photo-camera:before {
+  content: "\e500";
+}
+.k-i-image:before {
+  content: "\e501";
+}
+.k-i-photo:before {
+  content: "\e501";
+}
+.k-i-image-export:before {
+  content: "\e502";
+}
+.k-i-photo-export:before {
+  content: "\e502";
+}
+.k-i-zoom-actual-size:before {
+  content: "\e503";
+}
+.k-i-zoom-best-fit:before {
+  content: "\e504";
+}
+.k-i-image-resize:before {
+  content: "\e505";
+}
+.k-i-crop:before {
+  content: "\e506";
+}
+.k-i-mirror:before {
+  content: "\e507";
+}
+.k-i-flip-horizontal:before {
+  content: "\e508";
+}
+.k-i-flip-vertical:before {
+  content: "\e509";
+}
+.k-i-rotate:before {
+  content: "\e50a";
+}
+.k-i-rotate-right:before {
+  content: "\e50b";
+}
+.k-i-rotate-left:before {
+  content: "\e50c";
+}
+.k-i-brush:before {
+  content: "\e50d";
+}
+.k-i-palette:before {
+  content: "\e50e";
+}
+.k-i-paint:before {
+  content: "\e50f";
+}
+.k-i-droplet:before {
+  content: "\e50f";
+}
+.k-i-background:before {
+  content: "\e50f";
+}
+.k-i-line:before {
+  content: "\e510";
+}
+.k-i-shape-line:before {
+  content: "\e510";
+}
+.k-i-brightness-contrast:before {
+  content: "\e511";
+}
+.k-i-saturation:before {
+  content: "\e512";
+}
+.k-i-invert-colors:before {
+  content: "\e513";
+}
+.k-i-transperancy:before {
+  content: "\e514";
+}
+.k-i-opacity:before {
+  content: "\e514";
+}
+.k-i-greyscale:before {
+  content: "\e515";
+}
+.k-i-blur:before {
+  content: "\e516";
+}
+.k-i-sharpen:before {
+  content: "\e517";
+}
+.k-i-shape:before {
+  content: "\e518";
+}
+.k-i-round-corners:before {
+  content: "\e519";
+}
+.k-i-front-element:before {
+  content: "\e51a";
+}
+.k-i-back-element:before {
+  content: "\e51b";
+}
+.k-i-forward-element:before {
+  content: "\e51c";
+}
+.k-i-backward-element:before {
+  content: "\e51d";
+}
+.k-i-align-left-element:before {
+  content: "\e51e";
+}
+.k-i-align-center-element:before {
+  content: "\e51f";
+}
+.k-i-align-right-element:before {
+  content: "\e520";
+}
+.k-i-align-top-element:before {
+  content: "\e521";
+}
+.k-i-align-middle-element:before {
+  content: "\e522";
+}
+.k-i-align-bottom-element:before {
+  content: "\e523";
+}
+.k-i-thumbnails-up:before {
+  content: "\e524";
+}
+.k-i-thumbnails-right:before {
+  content: "\e525";
+}
+.k-i-thumbnails-down:before {
+  content: "\e526";
+}
+.k-i-thumbnails-left:before {
+  content: "\e527";
+}
+.k-i-full-screen:before {
+  content: "\e528";
+}
+.k-i-fullscreen:before {
+  content: "\e528";
+}
+.k-i-full-screen-exit:before {
+  content: "\e529";
+}
+.k-i-fullscreen-exit:before {
+  content: "\e529";
+}
+.k-i-reset-color:before {
+  content: "\e52a";
+}
+.k-i-paint-remove:before {
+  content: "\e52a";
+}
+.k-i-background-remove:before {
+  content: "\e52a";
+}
+.k-i-page-properties:before {
+  content: "\e600";
+}
+.k-i-bold:before {
+  content: "\e601";
+}
+.k-i-italic:before {
+  content: "\e602";
+}
+.k-i-underline:before {
+  content: "\e603";
+}
+.k-i-font-family:before {
+  content: "\e604";
+}
+.k-i-foreground-color:before {
+  content: "\e605";
+}
+.k-i-convert-lowercase:before {
+  content: "\e606";
+}
+.k-i-convert-uppercase:before {
+  content: "\e607";
+}
+.k-i-strikethrough:before {
+  content: "\e608";
+}
+.k-i-sub-script:before {
+  content: "\e609";
+}
+.k-i-sup-script:before {
+  content: "\e60a";
+}
+.k-i-div:before {
+  content: "\e60b";
+}
+.k-i-all:before {
+  content: "\e60c";
+}
+.k-i-h1:before {
+  content: "\e60d";
+}
+.k-i-h2:before {
+  content: "\e60e";
+}
+.k-i-h3:before {
+  content: "\e60f";
+}
+.k-i-h4:before {
+  content: "\e610";
+}
+.k-i-h5:before {
+  content: "\e611";
+}
+.k-i-h6:before {
+  content: "\e612";
+}
+.k-i-list-ordered:before {
+  content: "\e613";
+}
+.k-i-list-numbered:before {
+  content: "\e613";
+}
+.k-i-list-unordered:before {
+  content: "\e614";
+}
+.k-i-list-bulleted:before {
+  content: "\e614";
+}
+.k-i-indent-increase:before {
+  content: "\e615";
+}
+.k-i-indent:before {
+  content: "\e615";
+}
+.k-i-indent-decrease:before {
+  content: "\e616";
+}
+.k-i-outdent:before {
+  content: "\e616";
+}
+.k-i-insert-up:before {
+  content: "\e617";
+}
+.k-i-insert-top:before {
+  content: "\e617";
+}
+.k-i-insert-middle:before {
+  content: "\e618";
+}
+.k-i-insert-down:before {
+  content: "\e619";
+}
+.k-i-insert-bottom:before {
+  content: "\e619";
+}
+.k-i-align-top:before {
+  content: "\e61a";
+}
+.k-i-align-middle:before {
+  content: "\e61b";
+}
+.k-i-align-bottom:before {
+  content: "\e61c";
+}
+.k-i-align-left:before {
+  content: "\e61d";
+}
+.k-i-align-center:before {
+  content: "\e61e";
+}
+.k-i-align-right:before {
+  content: "\e61f";
+}
+.k-i-align-justify:before {
+  content: "\e620";
+}
+.k-i-align-remove:before {
+  content: "\e621";
+}
+.k-i-text-wrap:before {
+  content: "\e622";
+}
+.k-i-rule-horizontal:before {
+  content: "\e623";
+}
+.k-i-table-align-top-left:before {
+  content: "\e624";
+}
+.k-i-table-align-top-center:before {
+  content: "\e625";
+}
+.k-i-table-align-top-right:before {
+  content: "\e626";
+}
+.k-i-table-align-middle-left:before {
+  content: "\e627";
+}
+.k-i-table-align-middle-center:before {
+  content: "\e628";
+}
+.k-i-table-align-middle-right:before {
+  content: "\e629";
+}
+.k-i-table-align-bottom-left:before {
+  content: "\e62a";
+}
+.k-i-table-align-bottom-center:before {
+  content: "\e62b";
+}
+.k-i-table-align-bottom-right:before {
+  content: "\e62c";
+}
+.k-i-table-align-remove:before {
+  content: "\e62d";
+}
+.k-i-borders-all:before {
+  content: "\e62e";
+}
+.k-i-all-borders:before {
+  content: "\e62e";
+}
+.k-i-borders-outside:before {
+  content: "\e62f";
+}
+.k-i-outside-borders:before {
+  content: "\e62f";
+}
+.k-i-borders-inside:before {
+  content: "\e630";
+}
+.k-i-inside-borders:before {
+  content: "\e630";
+}
+.k-i-borders-inside-horizontal:before {
+  content: "\e631";
+}
+.k-i-inside-horizontal-borders:before {
+  content: "\e631";
+}
+.k-i-borders-inside-vertical:before {
+  content: "\e632";
+}
+.k-i-inside-vertical-borders:before {
+  content: "\e632";
+}
+.k-i-border-top:before {
+  content: "\e633";
+}
+.k-i-top-border:before {
+  content: "\e633";
+}
+.k-i-border-bottom:before {
+  content: "\e634";
+}
+.k-i-bottom-border:before {
+  content: "\e634";
+}
+.k-i-border-left:before {
+  content: "\e635";
+}
+.k-i-left-border:before {
+  content: "\e635";
+}
+.k-i-border-right:before {
+  content: "\e636";
+}
+.k-i-right-border:before {
+  content: "\e636";
+}
+.k-i-border-no:before {
+  content: "\e637";
+}
+.k-i-no-border:before {
+  content: "\e637";
+}
+.k-i-borders-show-hide:before {
+  content: "\e638";
+}
+.k-i-form:before {
+  content: "\e639";
+}
+.k-i-border:before {
+  content: "\e639";
+}
+.k-i-form-element:before {
+  content: "\e63a";
+}
+.k-i-code-snippet:before {
+  content: "\e63b";
+}
+.k-i-select-all:before {
+  content: "\e63c";
+}
+.k-i-button:before {
+  content: "\e63d";
+}
+.k-i-select-box:before {
+  content: "\e63e";
+}
+.k-i-calendar-date:before {
+  content: "\e63f";
+}
+.k-i-group-box:before {
+  content: "\e640";
+}
+.k-i-textarea:before {
+  content: "\e641";
+}
+.k-i-textbox:before {
+  content: "\e642";
+}
+.k-i-textbox-hidden:before {
+  content: "\e643";
+}
+.k-i-password:before {
+  content: "\e644";
+}
+.k-i-paragraph-add:before {
+  content: "\e645";
+}
+.k-i-edit-tools:before {
+  content: "\e646";
+}
+.k-i-template-manager:before {
+  content: "\e647";
+}
+.k-i-change-manually:before {
+  content: "\e648";
+}
+.k-i-track-changes:before {
+  content: "\e649";
+}
+.k-i-track-changes-enable:before {
+  content: "\e64a";
+}
+.k-i-track-changes-accept:before {
+  content: "\e64b";
+}
+.k-i-track-changes-accept-all:before {
+  content: "\e64c";
+}
+.k-i-track-changes-reject:before {
+  content: "\e64d";
+}
+.k-i-track-changes-reject-all:before {
+  content: "\e64e";
+}
+.k-i-document-manager:before {
+  content: "\e64f";
+}
+.k-i-custom-icon:before {
+  content: "\e650";
+}
+.k-i-dictionary-add:before {
+  content: "\e651";
+}
+.k-i-image-light-dialog:before {
+  content: "\e652";
+}
+.k-i-image-insert:before {
+  content: "\e652";
+}
+.k-i-image-edit:before {
+  content: "\e653";
+}
+.k-i-image-map-editor:before {
+  content: "\e654";
+}
+.k-i-comment:before {
+  content: "\e655";
+}
+.k-i-comment-remove:before {
+  content: "\e656";
+}
+.k-i-comments-remove-all:before {
+  content: "\e657";
+}
+.k-i-silverlight:before {
+  content: "\e658";
+}
+.k-i-media-manager:before {
+  content: "\e659";
+}
+.k-i-video-external:before {
+  content: "\e65a";
+}
+.k-i-flash-manager:before {
+  content: "\e65b";
+}
+.k-i-find-and-replace:before {
+  content: "\e65c";
+}
+.k-i-find:before {
+  content: "\e65c";
+}
+.k-i-copy:before {
+  content: "\e65d";
+}
+.k-i-files:before {
+  content: "\e65d";
+}
+.k-i-cut:before {
+  content: "\e65e";
+}
+.k-i-paste:before {
+  content: "\e65f";
+}
+.k-i-paste-as-html:before {
+  content: "\e660";
+}
+.k-i-paste-from-word:before {
+  content: "\e661";
+}
+.k-i-paste-from-word-strip-file:before {
+  content: "\e662";
+}
+.k-i-paste-html:before {
+  content: "\e663";
+}
+.k-i-paste-markdown:before {
+  content: "\e664";
+}
+.k-i-paste-plain-text:before {
+  content: "\e665";
+}
+.k-i-apply-format:before {
+  content: "\e666";
+}
+.k-i-clear-css:before {
+  content: "\e667";
+}
+.k-i-copy-format:before {
+  content: "\e668";
+}
+.k-i-strip-all-formating:before {
+  content: "\e669";
+}
+.k-i-strip-css-format:before {
+  content: "\e66a";
+}
+.k-i-strip-font-elements:before {
+  content: "\e66b";
+}
+.k-i-strip-span-elements:before {
+  content: "\e66c";
+}
+.k-i-strip-word-formatting:before {
+  content: "\e66d";
+}
+.k-i-format-code-block:before {
+  content: "\e66e";
+}
+.k-i-style-builder:before {
+  content: "\e66f";
+}
+.k-i-module-manager:before {
+  content: "\e670";
+}
+.k-i-hyperlink-light-dialog:before {
+  content: "\e671";
+}
+.k-i-hyperlink-insert:before {
+  content: "\e671";
+}
+.k-i-hyperlink-globe:before {
+  content: "\e672";
+}
+.k-i-hyperlink-globe-remove:before {
+  content: "\e673";
+}
+.k-i-hyperlink-email:before {
+  content: "\e674";
+}
+.k-i-anchor:before {
+  content: "\e675";
+}
+.k-i-table-light-dialog:before {
+  content: "\e676";
+}
+.k-i-table-insert:before {
+  content: "\e676";
+}
+.k-i-table:before {
+  content: "\e677";
+}
+.k-i-table-properties:before {
+  content: "\e678";
+}
+.k-i-table-wizard:before {
+  content: "\e678";
+}
+.k-i-table-cell:before {
+  content: "\e679";
+}
+.k-i-table-cell-properties:before {
+  content: "\e67a";
+}
+.k-i-table-column-insert-left:before {
+  content: "\e67b";
+}
+.k-i-table-column-insert-right:before {
+  content: "\e67c";
+}
+.k-i-table-row-insert-above:before {
+  content: "\e67d";
+}
+.k-i-table-row-insert-below:before {
+  content: "\e67e";
+}
+.k-i-table-column-delete:before {
+  content: "\e67f";
+}
+.k-i-table-row-delete:before {
+  content: "\e680";
+}
+.k-i-table-cell-delete:before {
+  content: "\e681";
+}
+.k-i-table-delete:before {
+  content: "\e682";
+}
+.k-i-cells-merge:before {
+  content: "\e683";
+}
+.k-i-cells-merge-horizontally:before {
+  content: "\e684";
+}
+.k-i-cells-merge-vertically:before {
+  content: "\e685";
+}
+.k-i-cell-split-horizontally:before {
+  content: "\e686";
+}
+.k-i-cell-split-vertically:before {
+  content: "\e687";
+}
+.k-i-table-unmerge:before {
+  content: "\e688";
+}
+.k-i-pane-freeze:before {
+  content: "\e689";
+}
+.k-i-row-freeze:before {
+  content: "\e68a";
+}
+.k-i-column-freeze:before {
+  content: "\e68b";
+}
+.k-i-toolbar-float:before {
+  content: "\e68c";
+}
+.k-i-spell-checker:before {
+  content: "\e68d";
+}
+.k-i-validation-xhtml:before {
+  content: "\e68e";
+}
+.k-i-validation-data:before {
+  content: "\e68f";
+}
+.k-i-toggle-full-screen-mode:before {
+  content: "\e690";
+}
+.k-i-formula-fx:before {
+  content: "\e691";
+}
+.k-i-sum:before {
+  content: "\e692";
+}
+.k-i-symbol:before {
+  content: "\e693";
+}
+.k-i-dollar:before {
+  content: "\e694";
+}
+.k-i-currency:before {
+  content: "\e694";
+}
+.k-i-percent:before {
+  content: "\e695";
+}
+.k-i-custom-format:before {
+  content: "\e696";
+}
+.k-i-decimal-increase:before {
+  content: "\e697";
+}
+.k-i-decimal-decrease:before {
+  content: "\e698";
+}
+.k-i-font-size:before {
+  content: "\e699";
+}
+.k-i-image-absolute-position:before {
+  content: "\e69a";
+}
+.k-i-globe-outline:before {
+  content: "\e700";
+}
+.k-i-globe:before {
+  content: "\e701";
+}
+.k-i-marker-pin:before {
+  content: "\e702";
+}
+.k-i-marker-pin-target:before {
+  content: "\e703";
+}
+.k-i-pin:before {
+  content: "\e704";
+}
+.k-i-unpin:before {
+  content: "\e705";
+}
+.k-i-share:before {
+  content: "\e800";
+}
+.k-i-user:before {
+  content: "\e801";
+}
+.k-i-inbox:before {
+  content: "\e802";
+}
+.k-i-blogger:before {
+  content: "\e803";
+}
+.k-i-blogger-box:before {
+  content: "\e804";
+}
+.k-i-delicious:before {
+  content: "\e805";
+}
+.k-i-delicious-box:before {
+  content: "\e806";
+}
+.k-i-digg:before {
+  content: "\e807";
+}
+.k-i-digg-box:before {
+  content: "\e808";
+}
+.k-i-email:before {
+  content: "\e809";
+}
+.k-i-envelop:before {
+  content: "\e809";
+}
+.k-i-letter:before {
+  content: "\e809";
+}
+.k-i-email-box:before {
+  content: "\e80a";
+}
+.k-i-envelop-box:before {
+  content: "\e80a";
+}
+.k-i-letter-box:before {
+  content: "\e80a";
+}
+.k-i-facebook:before {
+  content: "\e80b";
+}
+.k-i-facebook-box:before {
+  content: "\e80c";
+}
+.k-i-google:before {
+  content: "\e80d";
+}
+.k-i-google-box:before {
+  content: "\e80e";
+}
+.k-i-google-plus:before {
+  content: "\e80f";
+}
+.k-i-google-plus-box:before {
+  content: "\e810";
+}
+.k-i-linkedin:before {
+  content: "\e811";
+}
+.k-i-linkedin-box:before {
+  content: "\e812";
+}
+.k-i-myspace:before {
+  content: "\e813";
+}
+.k-i-myspace-box:before {
+  content: "\e814";
+}
+.k-i-pinterest:before {
+  content: "\e815";
+}
+.k-i-pinterest-box:before {
+  content: "\e816";
+}
+.k-i-reddit:before {
+  content: "\e817";
+}
+.k-i-reddit-box:before {
+  content: "\e818";
+}
+.k-i-stumble-upon:before {
+  content: "\e819";
+}
+.k-i-stumble-upon-box:before {
+  content: "\e81a";
+}
+.k-i-tell-a-friend:before {
+  content: "\e81b";
+}
+.k-i-tell-a-friend-box:before {
+  content: "\e81c";
+}
+.k-i-tumblr:before {
+  content: "\e81d";
+}
+.k-i-tumblr-box:before {
+  content: "\e81e";
+}
+.k-i-twitter:before {
+  content: "\e81f";
+}
+.k-i-twitter-box:before {
+  content: "\e820";
+}
+.k-i-yammer:before {
+  content: "\e821";
+}
+.k-i-yammer-box:before {
+  content: "\e822";
+}
+.k-i-behance:before {
+  content: "\e823";
+}
+.k-i-behance-box:before {
+  content: "\e824";
+}
+.k-i-dribbble:before {
+  content: "\e825";
+}
+.k-i-dribbble-box:before {
+  content: "\e826";
+}
+.k-i-rss:before {
+  content: "\e827";
+}
+.k-i-rss-box:before {
+  content: "\e828";
+}
+.k-i-vimeo:before {
+  content: "\e829";
+}
+.k-i-vimeo-box:before {
+  content: "\e82a";
+}
+.k-i-youtube:before {
+  content: "\e82b";
+}
+.k-i-youtube-box:before {
+  content: "\e82c";
+}
+.k-i-folder:before {
+  content: "\e900";
+}
+.k-i-folder-open:before {
+  content: "\e901";
+}
+.k-i-folder-add:before {
+  content: "\e902";
+}
+.k-i-folder-up:before {
+  content: "\e903";
+}
+.k-i-folder-more:before {
+  content: "\e904";
+}
+.k-i-fields-more:before {
+  content: "\e904";
+}
+.k-i-aggregate-fields:before {
+  content: "\e905";
+}
+.k-i-file:before {
+  content: "\e906";
+}
+.k-i-file-vertical:before {
+  content: "\e906";
+}
+.k-i-file-add:before {
+  content: "\e907";
+}
+.k-i-file-txt:before {
+  content: "\e908";
+}
+.k-i-txt:before {
+  content: "\e908";
+}
+.k-i-file-csv:before {
+  content: "\e909";
+}
+.k-i-csv:before {
+  content: "\e909";
+}
+.k-i-file-excel:before {
+  content: "\e90a";
+}
+.k-i-file-xls:before {
+  content: "\e90a";
+}
+.k-i-excel:before {
+  content: "\e90a";
+}
+.k-i-xls:before {
+  content: "\e90a";
+}
+.k-i-file-word:before {
+  content: "\e90b";
+}
+.k-i-file-doc:before {
+  content: "\e90b";
+}
+.k-i-word:before {
+  content: "\e90b";
+}
+.k-i-doc:before {
+  content: "\e90b";
+}
+.k-i-file-mdb:before {
+  content: "\e90c";
+}
+.k-i-mdb:before {
+  content: "\e90c";
+}
+.k-i-file-ppt:before {
+  content: "\e90d";
+}
+.k-i-ppt:before {
+  content: "\e90d";
+}
+.k-i-file-pdf:before {
+  content: "\e90e";
+}
+.k-i-pdf:before {
+  content: "\e90e";
+}
+.k-i-file-psd:before {
+  content: "\e90f";
+}
+.k-i-psd:before {
+  content: "\e90f";
+}
+.k-i-file-flash:before {
+  content: "\e910";
+}
+.k-i-flash:before {
+  content: "\e910";
+}
+.k-i-file-config:before {
+  content: "\e911";
+}
+.k-i-config:before {
+  content: "\e911";
+}
+.k-i-file-ascx:before {
+  content: "\e912";
+}
+.k-i-ascx:before {
+  content: "\e912";
+}
+.k-i-file-bac:before {
+  content: "\e913";
+}
+.k-i-bac:before {
+  content: "\e913";
+}
+.k-i-file-zip:before {
+  content: "\e914";
+}
+.k-i-zip:before {
+  content: "\e914";
+}
+.k-i-film:before {
+  content: "\e915";
+}
+.k-i-css3:before {
+  content: "\e916";
+}
+.k-i-html5:before {
+  content: "\e917";
+}
+.k-i-html:before {
+  content: "\e918";
+}
+.k-i-source-code:before {
+  content: "\e918";
+}
+.k-i-view-source:before {
+  content: "\e918";
+}
+.k-i-css:before {
+  content: "\e919";
+}
+.k-i-js:before {
+  content: "\e91a";
+}
+.k-i-exe:before {
+  content: "\e91b";
+}
+.k-i-csproj:before {
+  content: "\e91c";
+}
+.k-i-vbproj:before {
+  content: "\e91d";
+}
+.k-i-cs:before {
+  content: "\e91e";
+}
+.k-i-vb:before {
+  content: "\e91f";
+}
+.k-i-sln:before {
+  content: "\e920";
+}
+.k-i-cloud:before {
+  content: "\e921";
+}
+.k-i-file-horizontal:before {
+  content: "\e922";
+}
+/* animation classes */
+.k-fx-end .k-fx-next,
+.k-fx-end .k-fx-current {
+  transition: all 350ms ease-out;
+}
+.k-fx {
+  position: relative;
+}
+.k-fx .k-fx-current {
+  z-index: 0;
+}
+.k-fx .k-fx-next {
+  z-index: 1;
+}
+.k-fx-hidden,
+.k-fx-hidden * {
+  visibility: hidden !important;
+}
+.k-fx-reverse .k-fx-current {
+  z-index: 1;
+}
+.k-fx-reverse .k-fx-next {
+  z-index: 0;
+}
+/* Zoom */
+.k-fx-zoom.k-fx-start .k-fx-next {
+  transform: scale(0) !important;
+}
+.k-fx-zoom.k-fx-end .k-fx-next {
+  transform: scale(1) !important;
+}
+.k-fx-zoom.k-fx-reverse.k-fx-start .k-fx-next,
+.k-fx-zoom.k-fx-reverse.k-fx-end .k-fx-next {
+  transform: scale(1) !important;
+}
+.k-fx-zoom.k-fx-reverse.k-fx-start .k-fx-current {
+  transform: scale(1) !important;
+}
+.k-fx-zoom.k-fx-reverse.k-fx-end .k-fx-current {
+  transform: scale(0) !important;
+}
+/* Fade */
+.k-fx-fade.k-fx-start .k-fx-next {
+  will-change: opacity;
+  opacity: 0;
+}
+.k-fx-fade.k-fx-end .k-fx-next {
+  opacity: 1;
+}
+.k-fx-fade.k-fx-reverse.k-fx-start .k-fx-current {
+  will-change: opacity;
+  opacity: 1;
+}
+.k-fx-fade.k-fx-reverse.k-fx-end .k-fx-current {
+  opacity: 0;
+}
+/* Slide */
+.k-fx-slide {
+  /* left */
+  /* left reverse */
+  /* right */
+}
+.k-fx-slide.k-fx-end .k-fx-next .km-content,
+.k-fx-slide.k-fx-end .k-fx-next .km-header,
+.k-fx-slide.k-fx-end .k-fx-next .km-footer,
+.k-fx-slide.k-fx-end .k-fx-current .km-content,
+.k-fx-slide.k-fx-end .k-fx-current .km-header,
+.k-fx-slide.k-fx-end .k-fx-current .km-footer {
+  transition: all 350ms ease-out;
+}
+.k-fx-slide.k-fx-start .k-fx-next .km-content {
+  will-change: transform;
+  transform: translatex(100%);
+}
+.k-fx-slide.k-fx-start .k-fx-next .km-header,
+.k-fx-slide.k-fx-start .k-fx-next .km-footer {
+  will-change: opacity;
+  opacity: 0;
+}
+.k-fx-slide.k-fx-end .k-fx-current .km-content {
+  transform: translatex(-100%);
+}
+.k-fx-slide.k-fx-end .k-fx-next .km-header,
+.k-fx-slide.k-fx-end .k-fx-next .km-footer {
+  opacity: 1;
+}
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-current .km-content {
+  will-change: transform;
+  transform: translatex(0);
+}
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-current .km-content {
+  transform: translatex(100%);
+}
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-next .km-content {
+  transform: translatex(-100%);
+}
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-next .km-content {
+  transform: translatex(0);
+}
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-current .km-header,
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-current .km-footer {
+  will-change: opacity;
+  opacity: 1;
+}
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-next .km-header,
+.k-fx-slide.k-fx-reverse.k-fx-start .k-fx-next .km-footer {
+  opacity: 1;
+}
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-current .km-header,
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-current .km-footer {
+  opacity: 0;
+}
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-next .km-header,
+.k-fx-slide.k-fx-reverse.k-fx-end .k-fx-next .km-footer {
+  opacity: 1;
+}
+.k-fx-slide.k-fx-right {
+  /* right reverse */
+}
+.k-fx-slide.k-fx-right.k-fx-start .k-fx-next .km-content {
+  transform: translatex(-100%);
+}
+.k-fx-slide.k-fx-right.k-fx-end .k-fx-current .km-content {
+  transform: translatex(100%);
+}
+.k-fx-slide.k-fx-right.k-fx-reverse.k-fx-start .k-fx-current .km-content {
+  transform: translatex(0);
+}
+.k-fx-slide.k-fx-right.k-fx-reverse.k-fx-end .k-fx-current .km-content {
+  transform: translatex(-100%);
+}
+.k-fx-slide.k-fx-right.k-fx-reverse.k-fx-start .k-fx-next .km-content {
+  transform: translatex(100%);
+}
+.k-fx-slide.k-fx-right.k-fx-reverse.k-fx-end .k-fx-next .km-content {
+  transform: translatex(0%);
+}
+/* Tile */
+.k-fx-tile {
+  /* left */
+  /* left reverse */
+  /* right */
+}
+.k-fx-tile.k-fx-start .k-fx-next {
+  will-change: transform;
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-end .k-fx-current {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-start .k-fx-current {
+  will-change: transform;
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-reverse.k-fx-end .k-fx-current {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-start .k-fx-next {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-end .k-fx-next {
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-right {
+  /* right reverse */
+}
+.k-fx-tile.k-fx-right.k-fx-start .k-fx-next {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-right.k-fx-end .k-fx-current {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-start .k-fx-current {
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-end .k-fx-current {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-start .k-fx-next {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-end .k-fx-next {
+  transform: translatex(0%);
+}
+/* Tile */
+.k-fx-tile {
+  /* left */
+  /* left reverse */
+  /* right */
+}
+.k-fx-tile.k-fx-start .k-fx-next {
+  will-change: transform;
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-end .k-fx-current {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-start .k-fx-current {
+  will-change: transform;
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-reverse.k-fx-end .k-fx-current {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-start .k-fx-next {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-reverse.k-fx-end .k-fx-next {
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-right {
+  /* right reverse */
+}
+.k-fx-tile.k-fx-right.k-fx-start .k-fx-next {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-right.k-fx-end .k-fx-current {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-start .k-fx-current {
+  transform: translatex(0);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-end .k-fx-current {
+  transform: translatex(-100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-start .k-fx-next {
+  transform: translatex(100%);
+}
+.k-fx-tile.k-fx-right.k-fx-reverse.k-fx-end .k-fx-next {
+  transform: translatex(0%);
+}
+/* Overlay */
+.k-fx.k-fx-overlay.k-fx-start .k-fx-next,
+.k-fx.k-fx-overlay.k-fx-left.k-fx-start .k-fx-next {
+  will-change: transform;
+  transform: translatex(100%);
+}
+.k-fx.k-fx-overlay.k-fx-right.k-fx-start .k-fx-next {
+  transform: translatex(-100%);
+}
+.k-fx.k-fx-overlay.k-fx-up.k-fx-start .k-fx-next {
+  transform: translatey(100%);
+}
+.k-fx.k-fx-overlay.k-fx-down.k-fx-start .k-fx-next {
+  transform: translatey(-100%);
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-start .k-fx-next {
+  transform: none;
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-start .k-fx-current {
+  will-change: transform;
+  transform: none;
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-end .k-fx-current,
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-left.k-fx-end .k-fx-current {
+  transform: translatex(100%);
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-right.k-fx-end .k-fx-current {
+  transform: translatex(-100%);
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-up.k-fx-end .k-fx-current {
+  transform: translatey(100%);
+}
+.k-fx.k-fx-overlay.k-fx-reverse.k-fx-down.k-fx-end .k-fx-current {
+  transform: translatey(-100%);
+}
+.k-button,
+.k-toolbar .k-button {
+  line-height: 1.143em;
+  padding: 9px 14px;
+}
+.k-widget.k-tabstrip {
+  background-image: none;
+  border-style: none;
+  box-shadow: none;
+}
+.k-tabstrip .k-tabstrip-items {
+  padding: 0;
+}
+.k-tabstrip > div.k-content,
+.k-panelbar .k-tabstrip > div.k-content {
+  margin: 0;
+}
+.k-panelbar > .k-item > .k-link,
+.k-panel > .k-item > .k-link {
+  line-height: 3.5em;
+}
+.k-panelbar .k-image {
+  margin-top: 12px;
+}
+.k-panelbar .k-link > .k-sprite {
+  margin-top: 16px;
+}
+.k-tabstrip > .k-tabstrip-items > .k-item {
+  text-transform: uppercase;
+  border-width: 0;
+  border-style: solid;
+  padding: 0;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-loading,
+.k-tabstrip-right > .k-tabstrip-items .k-loading {
+  display: none;
+}
+.k-tabstrip-top > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-top > .k-tabstrip-items .k-state-active {
+  margin-bottom: -1px;
+}
+.k-tabstrip-top > .k-tabstrip-items > .k-item {
+  border-bottom-width: 2px;
+}
+.k-tabstrip-left > .k-tabstrip-items .k-tab-on-top,
+.k-tabstrip-left > .k-tabstrip-items .k-state-active {
+  margin-right: -2px;
+}
+.k-tabstrip-left > .k-tabstrip-items > .k-item {
+  border-right-width: 2px;
+}
+.k-tabstrip-right > .k-tabstrip-items > .k-item {
+  border-left-width: 2px;
+}
+.k-tabstrip-bottom > .k-tabstrip-items > .k-item {
+  border-top-width: 2px;
+}
+.k-tabstrip .k-tabstrip-items .k-link {
+  padding: 1.071em;
+}
+.k-slider-track {
+  border-width: 1px;
+  border-style: solid;
+}
+.k-pager-numbers .k-state-selected {
+  line-height: 2.429em;
+  cursor: pointer;
+}
+.k-pager-numbers .k-link,
+.k-pager-numbers .k-state-selected {
+  border-width: 2px 0 0;
+  padding-top: .7em;
+}
+.k-pager-wrap {
+  line-height: 1.286em;
+  padding: .429em 0 .429em .25em;
+}
+.k-pager-wrap > .k-link,
+.k-pager-numbers .k-link {
+  height: 2.429em;
+  line-height: 2.429em;
+}
+.k-pager-wrap .k-link,
+.k-pager-sizes {
+  padding: 0;
+  min-width: 2.429em;
+}
+.k-pager-wrap .k-pager-numbers .k-state-selected {
+  margin-top: -0.45em;
+  padding-top: .45em;
+  min-width: 2.429em;
+}
+.k-pager-wrap input.k-textbox {
+  height: 2.571em;
+}
+.k-pager-info {
+  padding: .714em 1.333em .643em 1.333em;
+}
+.k-pager-wrap .k-pager-refresh {
+  margin-right: 1.214em;
+}
+.k-pager-wrap .k-dropdown {
+  width: 5.2em;
+}
+.k-autocomplete .k-i-loading,
+.k-multiselect .k-i-loading {
+  bottom: 10px;
+}
+.k-combobox > .k-dropdown-wrap > .k-i-close {
+  right: 3.3em;
+}
+.k-combobox-clearable .k-input {
+  padding-right: 2.5em;
+}
+.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  top: 10px;
+}
+.k-autocomplete > .k-i-close,
+.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  margin-right: 10px;
+}
+.k-dropdown-wrap,
+.k-picker-wrap,
+.k-numeric-wrap {
+  padding: 0 2.571em 0 0;
+}
+.k-picker-wrap .k-select,
+.k-numeric-wrap .k-select,
+.k-dropdown-wrap .k-select {
+  width: 2.571em;
+}
+.k-datetimepicker {
+  width: 19.5em;
+}
+.k-datetimepicker .k-select {
+  width: 5em;
+}
+.k-datetimepicker .k-picker-wrap {
+  padding-right: 5em;
+}
+.k-datetimepicker .k-picker-wrap .k-icon {
+  margin: 0 6px;
+}
+.k-calendar .k-header {
+  margin: 0 -5px;
+}
+.k-calendar td {
+  padding: 0;
+}
+.k-calendar .k-content .k-link {
+  min-height: 2.571em;
+  line-height: 2.571em;
+  padding: 0;
+  text-align: center;
+}
+.k-calendar .k-century .k-link {
+  text-align: left;
+  padding: 0 .7em;
+  line-height: 1.3em;
+}
+.k-calendar th {
+  border-bottom-width: 0;
+  padding: .714em .45em .714em 0;
+}
+.k-calendar .k-footer {
+  border-top-width: 1px;
+  border-top-style: solid;
+  margin: 0 -5px;
+}
+.k-popup.k-list-container {
+  padding: 0.286em 0;
+}
+.k-popup.k-calendar-containe {
+  padding: 0;
+}
+.k-popup .k-list .k-item,
+.k-popup > .k-group-header,
+.k-fieldselector .k-list .k-item {
+  min-height: 2.143em;
+  line-height: 2.143em;
+}
+.k-popup .k-list .k-item {
+  padding: 1px 11px;
+}
+.k-button,
+.k-calendar .k-header .k-link,
+.k-calendar .k-footer {
+  text-transform: uppercase;
+}
+.k-widget.k-calendar .k-nav-fast {
+  width: 65%;
+  height: 2.571em;
+  line-height: 2.571em;
+  margin: 0.429em -0.08333em 0.429em 0;
+}
+.k-calendar .k-header .k-icon {
+  vertical-align: middle;
+}
+.k-widget.k-calendar .k-nav-prev,
+.k-widget.k-calendar .k-nav-next {
+  position: absolute;
+  top: 0.429em;
+  line-height: 2.571em;
+  height: 2.571em;
+}
+.k-calendar .k-header .k-link.k-nav-prev,
+.k-calendar .k-header .k-link.k-nav-next {
+  height: 2.571em;
+  width: 2.571em;
+}
+.k-widget.k-calendar .k-nav-prev {
+  left: 0.429em;
+}
+.k-widget.k-calendar .k-nav-next {
+  right: 0.429em;
+}
+.k-calendar .k-footer .k-nav-today,
+.k-calendar .k-footer > .k-state-disabled {
+  padding: 1.143em 0 1.071em;
+}
+.k-popup.k-calendar-container {
+  padding: 0;
+  border: 0;
+}
+.k-multiselect-wrap .k-input {
+  height: 2.214em;
+}
+.k-multiselect-wrap li {
+  border-radius: 1.071em;
+  margin: 3px 0 3px 3px;
+  padding: 0 1.6em 0 .857em;
+  line-height: 1.86em;
+}
+.k-multiselect-wrap li span {
+  margin-right: .4em;
+}
+.k-multiselect-wrap .k-select {
+  padding-top: 0;
+}
+.k-numeric-wrap .k-select {
+  vertical-align: baseline;
+}
+.k-numerictextbox .k-link {
+  display: block;
+  height: 1.284em;
+}
+.k-numerictextbox .k-link .k-i-arrow-60-up {
+  vertical-align: bottom;
+}
+.k-numerictextbox .k-link .k-i-arrow-60-down {
+  vertical-align: top;
+}
+.k-menu.k-header,
+.k-menu .k-item,
+.k-widget.k-menu-horizontal > .k-item {
+  border-width: 0;
+}
+.k-popup.k-context-menu {
+  border-width: 1px;
+  border-style: solid;
+}
+.k-context-menu.k-menu-vertical > .k-item > .k-link,
+.k-menu .k-menu-group .k-item > .k-link {
+  padding: 0.5em 4.929em 0.5em 1.714em;
+}
+.k-menu .k-item > .k-link > .k-i-arrow-60-right {
+  right: 2.143rem;
+}
+.k-menu .k-animation-container .k-menu-group {
+  padding: 1.143em 0;
+}
+.k-column-menu .k-menu .k-animation-container .k-menu-group {
+  padding: 0;
+}
+.k-column-menu .k-menu-vertical .k-separator {
+  height: 0;
+}
+.k-toolbar {
+  line-height: 3.42em;
+}
+.k-toolbar > div > label {
+  line-height: 3.42em;
+}
+.k-toolbar .k-overflow-anchor > .k-icon {
+  margin-top: -6px;
+  margin-bottom: -6px;
+}
+.k-toolbar .k-dropdown {
+  margin-top: -1px;
+}
+.k-toolbar .k-split-button .k-button {
+  padding-top: 10px;
+  padding-bottom: 10px;
+}
+.k-toolbar .k-button-group {
+  line-height: 3.286em;
+}
+.k-toolbar .k-button-group .k-button {
+  line-height: inherit;
+  padding: 0 .857em;
+}
+.k-toolbar .k-input {
+  height: 2.214em;
+  line-height: 2.214em;
+  padding: 0.177em 0;
+  text-indent: 0.8em;
+  border: 0;
+  margin: 0;
+}
+.k-toolbar .k-overflow-anchor {
+  border-width: 0;
+  line-height: 3.286em;
+  width: 3.42em;
+  height: 3.42em;
+  padding: 0;
+}
+.k-overflow-container .k-overflow-button,
+.k-split-container .k-button {
+  font-size: 1.2em;
+}
+.k-button-group .k-tool {
+  margin: 6px 0;
+}
+.k-toolbar .k-split-button-arrow {
+  padding-left: .4em;
+  padding-right: .4em;
+}
+.k-filebrowser .k-filebrowser-toolbar {
+  line-height: 3.5em;
+}
+.k-filebrowser .k-filebrowser-toolbar .k-upload {
+  margin-top: 3px;
+}
+.k-filebrowser .k-filebrowser-toolbar .k-button-icon {
+  margin-top: -3px;
+}
+.k-filebrowser .k-upload .k-upload-button {
+  vertical-align: bottom;
+}
+.k-filebrowser .k-search-wrap .k-search {
+  top: 25%;
+  right: 4px;
+}
+.k-filebrowser .k-search-wrap {
+  padding: 2px .3em;
+}
+.k-filebrowser .k-tiles-arrange .k-dropdown {
+  width: 80px;
+}
+.k-draghandle {
+  border-width: 2px;
+}
+span.k-tooltip {
+  padding: 9px 17px;
+}
+.k-block > .k-header,
+.k-window-titlebar {
+  padding: 0.5em 0 0.571em;
+}
+.k-window-titlebar .k-window-actions {
+  right: 0.929em;
+  padding-top: .45em;
+}
+div.k-window {
+  border-width: 0;
+}
+.k-window-title {
+  right: 1.143em;
+  left: 1.143em;
+}
+div.k-window-content {
+  padding: 1.333em;
+}
+.k-file {
+  padding: .643em .17em .643em 1em;
+}
+.k-notification-wrap {
+  padding: 1.786em;
+}
+.k-notification-wrap > .k-i-close {
+  top: 21px;
+}
+.k-slider-track {
+  border-width: 0;
+}
+.k-slider .k-button .k-icon {
+  margin-top: 5px;
+}
+.k-slider-horizontal .k-slider-track,
+.k-slider-horizontal .k-slider-selection {
+  height: 2px;
+  margin-top: -1px;
+}
+.k-slider-vertical .k-slider-track,
+.k-slider-vertical .k-slider-selection {
+  width: 2px;
+  margin-left: -1px;
+}
+.k-slider-horizontal .k-draghandle,
+.k-slider-vertical .k-draghandle,
+.k-flatcolorpicker .k-hue-slider .k-draghandle,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle {
+  width: 6px;
+  height: 6px;
+}
+.k-flatcolorpicker .k-hue-slider .k-draghandle {
+  margin-top: -1px;
+}
+.k-colorpicker .k-picker-wrap {
+  line-height: 2.214em;
+}
+.k-colorpicker .k-selected-color {
+  height: 2.214em;
+  padding: 0.177em 0;
+}
+.k-draghandle.k-state-selected,
+.k-draghandle.k-state-selected:link,
+.k-flatcolorpicker .k-hue-slider .k-draghandle.k-state-selected,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle.k-state-selected {
+  width: 10px;
+  height: 10px;
+}
+.k-draghandle.k-state-focused.k-state-selected {
+  margin-left: -2px;
+}
+.k-slider-horizontal .k-draghandle.k-state-selected,
+.k-flatcolorpicker .k-hue-slider .k-draghandle.k-state-selected {
+  top: -6px;
+}
+.k-slider-vertical .k-draghandle.k-state-selected {
+  left: -4px;
+}
+/* PanelBar */
+.k-panelbar-expand,
+.k-panelbar-collapse {
+  right: 16px;
+}
+.k-popup-edit-form .k-primary {
+  float: right;
+}
+.k-popup-edit-form:after {
+  content: " ";
+  display: block;
+  clear: both;
+}
+.k-drag-clue {
+  font-size: 1em;
+  padding: .65em 1em;
+}
+.k-splitbar-horizontal-hover .k-resize-handle {
+  background-position: -165px -6px;
+}
+.k-splitbar-vertical-hover .k-resize-handle {
+  background-position: -38px -309px;
+}
+.k-splitbar-horizontal.k-state-focused .k-resize-handle {
+  background-position: -181px -6px;
+}
+.k-splitbar-vertical.k-state-focused .k-resize-handle {
+  background-position: -70px -309px;
+}
+.k-checkbox-label,
+.k-radio-label {
+  line-height: 18px;
+}
+.k-checkbox:indeterminate + .k-checkbox-label:before {
+  border-width: 2px;
+}
+.k-checkbox + .k-checkbox-label:before {
+  z-index: 1;
+}
+.k-checkbox:indeterminate + .k-checkbox-label:after {
+  width: 10px;
+  height: 10px;
+  border-width: 0;
+  margin-left: 0;
+  top: 5px;
+  left: 5px;
+  transform: none;
+  z-index: 2;
+}
+.k-radio:checked + .k-radio-label:after {
+  top: 4px;
+  left: 4px;
+}
+.k-rtl .k-widget .k-dropdown-wrap,
+.k-rtl .k-widget .k-picker-wrap,
+.k-rtl .k-widget .k-numeric-wrap {
+  padding-left: 2.5em;
+}
+.k-rtl .k-widget.k-autocomplete > .k-i-close,
+.k-rtl .k-widget.k-multiselect > .k-multiselect-wrap > .k-i-close {
+  left: 0;
+  right: initial;
+  margin-left: 10px;
+  margin-right: 0;
+}
+.k-rtl .k-widget.k-combobox > .k-dropdown-wrap > .k-i-close {
+  left: 3.3em;
+  right: initial;
+}
+.k-rtl .k-widget.k-datetimepicker .k-picker-wrap {
+  padding-left: 5em;
+}
+.k-rtl .k-widget.k-datetimepicker .k-picker-wrap .k-icon {
+  margin: 0 6px;
+}
+.k-rtl .k-checkbox-label:after {
+  right: 0;
+}
+.km-pane-wrapper .k-pager-numbers .k-link,
+.km-pane-wrapper .k-pager-numbers .k-state-selected,
+.km-pane-wrapper .k-pager-wrap > .k-link {
+  border-radius: 0;
+}
+.km-pane-wrapper .k-pager-numbers .k-link,
+.km-pane-wrapper .k-pager-wrap > .k-link,
+.km-pane-wrapper .k-pager-wrap > .k-pager-info {
+  padding: .571em .86em;
+}
+.km-pane-wrapper .k-pager-numbers .k-state-selected {
+  padding: .971em .86em .571em;
+}
+.km-pane-wrapper .k-mobile-list .k-edit-field.k-scheduler-toolbar {
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+  padding-bottom: 0;
+}
+.km-pane-wrapper .k-mobile-list .k-edit-field.k-scheduler-toolbar .k-scheduler-navigation {
+  margin-bottom: -0.6em;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/kendo.material.min.css b/src/main/resources/META-INF/resources/designer/css/kendo.material.min.css
new file mode 100644 (file)
index 0000000..a01bc2f
--- /dev/null
@@ -0,0 +1,3740 @@
+/* Kendo skin */
+.k-theme-test-class,
+.ktb-theme-id-material {
+  opacity: 0;
+}
+.ktb-var-accent {
+  color: #3f51b5;
+}
+.ktb-var-base {
+  color: #fff;
+}
+.ktb-var-background {
+  color: #fff;
+}
+.ktb-var-border-radius {
+  border-radius: 2px;
+}
+.ktb-var-normal-background {
+  color: #fff;
+}
+.ktb-var-normal-gradient {
+  background-image: none;
+}
+.ktb-var-normal-text-color {
+  color: #444444;
+}
+.ktb-var-hover-background {
+  color: #ebebeb;
+}
+.ktb-var-hover-gradient {
+  background-image: none;
+}
+.ktb-var-hover-text-color {
+  color: #444444;
+}
+.ktb-var-selected-background {
+  color: #00b0ff;
+}
+.ktb-var-selected-gradient {
+  background-image: none;
+}
+.ktb-var-selected-text-color {
+  color: #3f51b5;
+}
+.ktb-var-error {
+  color: #ffcdd2;
+}
+.ktb-var-warning {
+  color: #fdefba;
+}
+.ktb-var-success {
+  color: #c8e6c9;
+}
+.ktb-var-info {
+  color: #bbdefb;
+}
+.ktb-var-series-a {
+  color: #3f51b5;
+}
+.ktb-var-series-b {
+  color: #03a9f4;
+}
+.ktb-var-series-c {
+  color: #4caf50;
+}
+.ktb-var-series-d {
+  color: #f9ce1d;
+}
+.ktb-var-series-e {
+  color: #ff9800;
+}
+.ktb-var-series-f {
+  color: #ff5722;
+}
+.k-grid-norecords-template {
+  background-color: #fff;
+  border: 1px solid #e6e6e6;
+}
+.k-in,
+.k-item,
+.k-window-action {
+  border-color: transparent;
+}
+/* main colors */
+.k-header .k-window-actions .k-link {
+  color: inherit;
+}
+a.k-icon {
+  color: #444444;
+}
+a.k-icon:hover {
+  color: #444444;
+}
+.k-button-icon .k-icon {
+  opacity: .8;
+}
+.k-button-icon:hover .k-icon {
+  opacity: 1;
+}
+.k-splitbar .k-resize-handle {
+  background-color: #444444;
+}
+.k-block,
+.k-widget {
+  background-color: #fff;
+}
+.k-block,
+.k-widget,
+.k-input,
+.k-textbox,
+.k-group,
+.k-content,
+.k-header,
+.k-filter-row > th,
+.k-editable-area,
+.k-separator,
+.k-textbox > input,
+.k-autocomplete,
+.k-dropdown-wrap,
+.k-toolbar,
+.k-group-footer td,
+.k-grid-footer,
+.k-footer-template td,
+.k-state-default,
+.k-state-default .k-select,
+.k-state-disabled,
+.k-grid-header,
+.k-grid-header-wrap,
+.k-grid-header-locked,
+.k-grid-footer-locked,
+.k-grid-content-locked,
+.k-grid td,
+.k-grid td.k-state-selected,
+.k-grid-footer-wrap,
+.k-pager-wrap,
+.k-pager-wrap .k-link,
+.k-pager-refresh,
+.k-grouping-header,
+.k-grouping-header .k-group-indicator,
+.k-panelbar > .k-item > .k-link,
+.k-panel > .k-item > .k-link,
+.k-panelbar .k-panel,
+.k-panelbar .k-content,
+.k-treemap-tile,
+.k-calendar th,
+.k-slider-track,
+.k-splitbar,
+.k-dropzone-active,
+.k-tiles,
+.k-toolbar,
+.k-tooltip,
+.k-button-group .k-tool,
+.k-upload-files,
+.k-popup.k-align .k-list .k-item:last-child {
+  border-color: #e6e6e6;
+}
+.k-group,
+.k-toolbar,
+.k-grouping-header,
+.k-pager-wrap,
+.k-group-footer td,
+.k-grid-footer,
+.k-footer-template td,
+.k-widget .k-status,
+.k-calendar th,
+.k-dropzone-hovered,
+.k-widget.k-popup {
+  background-color: #3f51b5;
+}
+.k-grouping-row td,
+td.k-group-cell,
+.k-resize-handle-inner {
+  background-color: #3f51b5;
+}
+.k-list-container {
+  border-color: rgba(0, 0, 0, 0.2);
+  background-color: #ffffff;
+}
+.k-content,
+.k-editable-area,
+.k-panelbar > li.k-item,
+.k-panel > li.k-item,
+.k-tiles {
+  background-color: #fff;
+}
+.k-alt,
+.k-separator,
+.k-resource.k-alt,
+.k-pivot-layout > tbody > tr:first-child > td:first-child {
+  background-color: #f2f2f2;
+}
+.k-pivot-rowheaders .k-alt .k-alt,
+.k-header.k-alt {
+  background-color: #dedede;
+}
+.k-textbox,
+.k-autocomplete.k-header,
+.k-dropdown-wrap.k-state-active,
+.k-picker-wrap.k-state-active,
+.k-numeric-wrap.k-state-active {
+  border-color: #e6e6e6;
+  background-color: #fff;
+}
+.k-textbox > input,
+.k-autocomplete .k-input,
+.k-dropdown-wrap .k-input,
+.k-autocomplete.k-state-focused .k-input,
+.k-dropdown-wrap.k-state-focused .k-input,
+.k-picker-wrap.k-state-focused .k-input,
+.k-numeric-wrap.k-state-focused .k-input {
+  border-color: #e6e6e6;
+}
+input.k-textbox,
+textarea.k-textbox,
+input.k-textbox:hover,
+textarea.k-textbox:hover,
+.k-textbox > input {
+  background: none;
+}
+.k-input,
+input.k-textbox,
+textarea.k-textbox,
+input.k-textbox:hover,
+textarea.k-textbox:hover,
+.k-textbox > input,
+.k-multiselect-wrap {
+  background-color: #fff;
+  color: #444444;
+}
+.k-input[readonly] {
+  background-color: #fff;
+  color: #444444;
+}
+.k-block,
+.k-widget,
+.k-popup,
+.k-content,
+.k-toolbar,
+.k-dropdown .k-input {
+  color: #444444;
+}
+.k-inverse {
+  color: #ffffff;
+}
+.k-block {
+  color: #ffffff;
+}
+.k-link:link,
+.k-link:visited,
+.k-nav-current.k-state-hover .k-link {
+  color: #428bca;
+}
+.k-tabstrip-items .k-link,
+.k-panelbar > li > .k-link {
+  color: #444444;
+}
+.k-header,
+.k-treemap-title,
+.k-grid-header .k-header > .k-link {
+  color: #ffffff;
+}
+.k-header,
+.k-grid-header,
+.k-toolbar,
+.k-dropdown-wrap,
+.k-picker-wrap,
+.k-numeric-wrap,
+.k-grouping-header,
+.k-pager-wrap,
+.k-textbox,
+.k-button,
+.k-progressbar,
+.k-draghandle,
+.k-autocomplete,
+.k-state-highlight,
+.k-tabstrip-items .k-item,
+.k-panelbar .k-tabstrip-items .k-item,
+.km-pane-wrapper > .km-pane > .km-view > .km-content {
+  background-image: none;
+  background-position: 50% 50%;
+  background-color: #3f51b5;
+}
+.k-widget.k-tooltip {
+  background-image: none;
+}
+.k-block,
+.k-header,
+.k-grid-header,
+.k-toolbar,
+.k-grouping-header,
+.k-pager-wrap,
+.k-button,
+.k-draghandle,
+.k-treemap-tile,
+html .km-pane-wrapper .k-header {
+  background-color: #3f51b5;
+}
+/* icons */
+.k-icon:hover,
+.k-state-hover .k-icon,
+.k-state-selected .k-icon,
+.k-state-focused .k-icon,
+.k-column-menu .k-state-hover .k-sprite,
+.k-column-menu .k-state-active .k-sprite,
+.k-pager-numbers .k-current-page .k-link:hover:after,
+.k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view.k-state-hover > .k-link:after {
+  opacity: 1;
+}
+.k-state-disabled .k-icon,
+.k-column-menu .k-sprite,
+.k-pager-numbers .k-current-page .k-link:after,
+.k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link:after {
+  opacity: 0.7;
+}
+.k-mobile-list .k-check:checked,
+.k-mobile-list .k-edit-field [type=checkbox]:checked,
+.k-mobile-list .k-edit-field [type=radio]:checked {
+  opacity: 0.7;
+}
+.k-tool {
+  border-color: transparent;
+}
+/* IE will ignore the above selectors if these are added too */
+.k-mobile-list .k-check:checked,
+.k-mobile-list .k-edit-field [type=checkbox]:checked,
+.k-mobile-list .k-edit-field [type=radio]:checked {
+  background-image: url('Material/sprite.png');
+  border-color: transparent;
+}
+.k-i-loading {
+  background-image: url('Material/loading.gif');
+}
+.k-loading-image {
+  background-image: url('Material/loading-image.gif');
+}
+.k-loading-color {
+  background-color: #ffffff;
+}
+.k-button {
+  color: #444444;
+  border-color: #fafafa;
+  background-color: #fafafa;
+}
+.k-draghandle {
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+  box-shadow: none;
+}
+.k-draghandle:hover {
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+  box-shadow: 0 0 0 8px rgba(63, 81, 181, 0.3);
+}
+/* Scheduler */
+.k-scheduler {
+  color: #ffffff;
+  background-color: #fff;
+}
+.k-scheduler-layout {
+  color: #444444;
+}
+.k-scheduler-datecolumn,
+.k-scheduler-groupcolumn {
+  background-color: #fff;
+  color: #444444;
+}
+.k-scheduler-times tr,
+.k-scheduler-times th,
+.k-scheduler-table td,
+.k-scheduler-header th,
+.k-scheduler-header-wrap,
+.k-scheduler-times {
+  border-color: #e6e6e6;
+}
+.k-nonwork-hour {
+  background-color: #fafafa;
+}
+.k-gantt .k-nonwork-hour {
+  background-color: rgba(0, 0, 0, 0.02);
+}
+.k-gantt .k-header.k-nonwork-hour {
+  background-color: rgba(0, 0, 0, 0.2);
+}
+.k-scheduler-table .k-today,
+.k-today > .k-scheduler-datecolumn,
+.k-today > .k-scheduler-groupcolumn {
+  background-color: #e9e9e9;
+}
+.k-scheduler-now-arrow {
+  border-left-color: #eed3d7;
+}
+.k-scheduler-now-line {
+  background-color: #eed3d7;
+}
+.k-event,
+.k-task-complete {
+  border-color: #606fc7;
+  background: #606fc7 0 -257px none repeat-x;
+  color: #ffffff;
+}
+.k-event-inverse {
+  color: #444444;
+}
+.k-event.k-state-selected {
+  background-position: 0 0;
+  box-shadow: 0 0 0 2px #444444;
+}
+.k-event .k-resize-handle:after,
+.k-task-single .k-resize-handle:after {
+  background-color: #ffffff;
+}
+.k-scheduler-marquee:before,
+.k-scheduler-marquee:after {
+  border-color: #fff;
+}
+.k-panelbar .k-content,
+.k-panelbar .k-panel,
+.k-panelbar .k-item {
+  background-color: #fff;
+  color: #444444;
+  border-color: #cccccc;
+}
+.k-panelbar > li > .k-link {
+  color: #444444;
+}
+.k-panelbar > .k-item > .k-link {
+  border-color: #cccccc;
+}
+.k-panel > li.k-item {
+  background-color: #fff;
+}
+/* states */
+.k-state-active,
+.k-state-active:hover,
+.k-active-filter,
+.k-tabstrip .k-state-active {
+  background-color: #ffffff;
+  border-color: #cccccc;
+  color: #444444;
+}
+.k-fieldselector .k-list-container {
+  background-color: #ffffff;
+}
+.k-button:focus,
+.k-button.k-state-focused {
+  border-color: #dbdbdb;
+}
+.k-button:hover,
+.k-button.k-state-hover {
+  color: #444444;
+  border-color: #ebebeb;
+  background-color: #ebebeb;
+}
+.k-button:active,
+.k-button.k-state-active {
+  color: #3f51b5;
+  background-color: #dbdbdb;
+  border-color: #dbdbdb;
+}
+.k-button:active:hover,
+.k-button.k-state-active:hover {
+  color: #ffffff;
+  border-color: #5c6bc0;
+  background-color: #5c6bc0;
+}
+.k-button:focus:not(.k-state-disabled):not([disabled]) {
+  box-shadow: 0 6px 17px 0 #c4c4c4;
+}
+.k-button:focus:active:not(.k-state-disabled):not([disabled]) {
+  box-shadow: 0 6px 17px 0 rgba(235, 235, 235, 0.3);
+}
+.k-menu .k-state-hover > .k-state-active {
+  background-color: transparent;
+}
+.k-state-highlight {
+  background: #ffffff;
+  color: #444444;
+}
+.k-state-focused,
+.k-grouping-row .k-state-focused {
+  border-color: #67afe9;
+}
+.k-button.k-bare {
+  position: relative;
+}
+.k-button.k-bare:before {
+  content: "";
+  background-color: currentcolor;
+  opacity: 0.12;
+  border-radius: inherit;
+  height: 100%;
+  width: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: -1;
+  display: none;
+}
+.k-button.k-bare.k-state-focused:before,
+.k-button.k-bare:focus:before {
+  display: block;
+}
+.k-mediaplayer-toolbar .k-button.k-bare:active,
+.k-mediaplayer-toolbar .k-button.k-bare.k-state-active,
+.k-mediaplayer-toolbar .k-button.k-bare.k-state-active:hover {
+  color: #3f51b5;
+}
+.k-mediaplayer-toolbar .k-button.k-bare:active:before,
+.k-mediaplayer-toolbar .k-button.k-bare.k-state-active:before,
+.k-mediaplayer-toolbar .k-button.k-bare.k-state-active:hover:before {
+  opacity: 0.24;
+}
+.k-mediaplayer-seekbar {
+  top: -14px;
+}
+.k-quality-list {
+  margin-left: -25px !important;
+}
+.k-calendar .k-link {
+  color: #444444;
+}
+.k-calendar .k-footer {
+  padding: 0;
+}
+.k-calendar .k-footer .k-nav-today {
+  color: #444444;
+  text-decoration: none;
+  background-color: #fff;
+}
+.k-calendar .k-footer .k-nav-today:hover,
+.k-calendar .k-footer .k-nav-today.k-state-hover {
+  background-color: #fff;
+  text-decoration: underline;
+}
+.k-calendar .k-footer .k-nav-today:active {
+  background-color: #fff;
+}
+.k-calendar .k-link.k-nav-fast {
+  color: #444444;
+}
+.k-calendar .k-nav-fast.k-state-hover {
+  text-decoration: none;
+  background-color: #ebebeb;
+  color: #444444;
+}
+.k-calendar .k-link.k-state-hover {
+  border-radius: 50%;
+}
+.k-calendar .k-footer .k-link {
+  border-radius: 0;
+}
+.k-calendar th {
+  background-color: #3f51b5;
+}
+.k-window-titlebar .k-link {
+  border-radius: 50%;
+}
+.k-calendar-container.k-group {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.k-state-selected,
+.k-state-selected:link,
+.k-state-selected:visited,
+.k-list > .k-state-selected,
+.k-list > .k-state-highlight,
+.k-panel > .k-state-selected,
+.k-ghost-splitbar-vertical,
+.k-ghost-splitbar-horizontal,
+.k-draghandle.k-state-selected:hover,
+.k-scheduler .k-scheduler-toolbar .k-state-selected,
+.k-scheduler .k-today.k-state-selected,
+.k-marquee-color,
+.k-drag-clue.k-state-selected {
+  color: #3f51b5;
+  background-color: #fff;
+  border-color: #ffffff;
+}
+.k-virtual-item.k-first,
+.k-group-header + .k-list > .k-item.k-first,
+.k-static-header + .k-list > .k-item.k-first {
+  border-top-color: #ebebeb;
+}
+.k-group-header + div > .k-list > .k-item.k-first:before {
+  border-top-color: #ebebeb;
+}
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header {
+  background: #ebebeb;
+  color: #3f51b5;
+}
+.k-popup .k-list .k-item > .k-group {
+  background: #ebebeb;
+  color: #3f51b5;
+  border-bottom-left-radius: 1px;
+}
+.k-marquee-text {
+  color: #3f51b5;
+}
+.k-state-focused,
+.k-list > .k-state-focused,
+.k-listview > .k-state-focused,
+.k-listview > .k-state-focused.k-state-selected,
+td.k-state-focused,
+.k-button.k-state-focused,
+.k-upload-files .k-button:focus,
+.k-upload-files .k-button:focus:not(.k-state-disabled):not([disabled]) {
+  box-shadow: inset 0 0 0 1px #808080;
+}
+.k-state-focused.k-state-selected,
+.k-list > .k-state-focused.k-state-selected,
+td.k-state-focused.k-state-selected {
+  box-shadow: none;
+}
+.k-ie8 .k-panelbar span.k-state-focused,
+.k-ie8 .k-menu li.k-state-focused,
+.k-ie8 .k-listview > .k-state-focused,
+.k-ie8 .k-grid-header th.k-state-focused,
+.k-ie8 td.k-state-focused,
+.k-ie8 .k-tool.k-state-hover,
+.k-ie8 .k-button:focus,
+.k-ie8 .k-button.k-state-focused,
+.k-list > .k-state-selected.k-state-focused,
+.k-list-optionlabel.k-state-selected.k-state-focused {
+  box-shadow: none;
+}
+.k-state-selected > .k-link,
+.k-panelbar > li > .k-state-selected,
+.k-panelbar > li.k-state-default > .k-link.k-state-selected {
+  color: #3f51b5;
+}
+.k-state-hover,
+.k-state-hover:hover,
+.k-splitbar-horizontal-hover:hover,
+.k-splitbar-vertical-hover:hover,
+.k-list > .k-state-hover,
+.k-scheduler .k-scheduler-toolbar ul li.k-state-hover,
+.k-pager-wrap .k-link:hover,
+.k-dropdown .k-state-focused,
+.k-filebrowser-dropzone,
+.k-mobile-list .k-item > .k-link:active,
+.k-mobile-list .k-item > .k-label:active,
+.k-mobile-list .k-edit-label.k-check:active,
+.k-mobile-list .k-recur-view .k-check:active {
+  color: #444444;
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+/* this selector should be used separately, otherwise old IEs ignore the whole rule */
+.k-mobile-list .k-scheduler-timezones .k-edit-field:nth-child(2):active {
+  color: #444444;
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+.k-ie8 .k-window-titlebar .k-state-hover {
+  border-color: #ebebeb;
+}
+.k-state-hover > .k-select,
+.k-state-focused > .k-select {
+  border-color: #ebebeb;
+}
+.k-button:hover,
+.k-button.k-state-hover,
+.k-button:focus,
+.k-button.k-state-focused,
+.k-textbox:hover,
+.k-state-hover,
+.k-state-hover:hover,
+.k-pager-wrap .k-link:hover,
+.k-other-month.k-state-hover .k-link,
+div.k-filebrowser-dropzone em,
+.k-draghandle:hover,
+.k-listbox .k-item:hover:not(.k-state-disabled) {
+  background-image: none;
+}
+.k-pager-wrap {
+  background-color: #3f51b5;
+  color: #ffffff;
+}
+.k-autocomplete.k-state-active,
+.k-picker-wrap.k-state-active,
+.k-numeric-wrap.k-state-active,
+.k-dropdown-wrap.k-state-active,
+.k-state-active,
+.k-state-active:hover,
+.k-state-active > .k-link,
+.k-button:active,
+.k-panelbar > .k-item > .k-state-focused {
+  background-image: none;
+}
+.k-state-selected,
+.k-button:active,
+.k-button.k-state-active,
+.k-draghandle.k-state-selected:hover {
+  background-image: none;
+}
+.k-button:active,
+.k-button.k-state-active,
+.k-draghandle.k-state-selected:hover {
+  background-position: 50% 50%;
+}
+.k-state-hover > .k-link,
+.k-other-month.k-state-hover .k-link,
+div.k-filebrowser-dropzone em {
+  color: #444444;
+}
+.k-autocomplete.k-state-hover,
+.k-autocomplete.k-state-focused,
+.k-picker-wrap.k-state-hover,
+.k-picker-wrap.k-state-focused,
+.k-numeric-wrap.k-state-hover,
+.k-numeric-wrap.k-state-focused,
+.k-dropdown-wrap.k-state-hover,
+.k-dropdown-wrap.k-state-focused {
+  background-color: #ffffff;
+  background-image: none;
+  background-position: 50% 50%;
+  border-color: #ebebeb;
+}
+.km-pane-wrapper .k-mobile-list input:not([type="checkbox"]):not([type="radio"]),
+.km-pane-wrapper .km-pane .k-mobile-list select:not([multiple]),
+.km-pane-wrapper .k-mobile-list textarea,
+.k-dropdown .k-state-focused .k-input {
+  color: #444444;
+}
+.km-pane-wrapper .km-pane .k-mobile-list.k-filter-menu .k-space-right {
+  background: #fff;
+  border-color: #e6e6e6;
+}
+.km-pane-wrapper .km-pane .k-mobile-list.k-filter-menu .k-space-right > input {
+  background-color: #fff;
+  border-color: #f0f0f0;
+}
+.km-pane-wrapper .km-pane .k-mobile-list.k-filter-menu .k-space-right > input + .k-i-zoom:before {
+  color: #444444;
+}
+.km-pane-wrapper .km-pane .k-mobile-list.k-filter-menu .k-space-right > input:focus {
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-dropdown .k-state-hover .k-input {
+  color: #444444;
+}
+.k-state-error {
+  border-color: #eed3d7;
+  background-color: #f2dede;
+  color: #b94a48;
+}
+.k-state-disabled {
+  opacity: .7;
+}
+.k-ie8 .k-state-disabled {
+  filter: alpha(opacity=70);
+}
+.k-tile-empty.k-state-selected,
+.k-loading-mask.k-state-selected {
+  border-width: 0;
+  background-image: none;
+  background-color: transparent;
+}
+.k-state-disabled,
+.k-state-disabled .k-link,
+.k-state-disabled .k-button,
+.k-other-month,
+.k-other-month .k-link,
+.k-dropzone em,
+.k-dropzone .k-upload-status,
+.k-tile-empty strong,
+.k-slider .k-draghandle {
+  color: #999999;
+}
+.k-file .k-upload-status {
+  color: #444444;
+}
+/* Progressbar */
+.k-progressbar-indeterminate {
+  background: url('Material/indeterminate.gif');
+}
+.k-progressbar-indeterminate .k-progress-status-wrap,
+.k-progressbar-indeterminate .k-state-selected {
+  display: none;
+}
+/* Slider */
+.k-slider-track {
+  background-color: #e6e6e6;
+}
+.k-slider-selection {
+  background-color: #fff;
+}
+.k-slider-horizontal .k-tick {
+  background-image: url('Material/slider-h.gif');
+}
+.k-slider-vertical .k-tick {
+  background-image: url('Material/slider-v.gif');
+}
+/* Tooltip */
+.k-widget.k-tooltip,
+.k-chart-crosshair-tooltip,
+.k-chart-shared-tooltip {
+  border-color: rgba(100, 100, 100, 0.9);
+  background-color: rgba(100, 100, 100, 0.9);
+  color: #ffffff;
+}
+.k-widget.k-tooltip-validation {
+  border-color: #fdefba;
+  background-color: #fdefba;
+  color: #816704;
+}
+/* Bootstrap theme fix */
+.input-prepend .k-tooltip-validation,
+.input-append .k-tooltip-validation {
+  font-size: 12px;
+  position: relative;
+  top: 3px;
+}
+.k-callout-n {
+  border-bottom-color: rgba(100, 100, 100, 0.9);
+}
+.k-callout-w {
+  border-right-color: rgba(100, 100, 100, 0.9);
+}
+.k-callout-s {
+  border-top-color: rgba(100, 100, 100, 0.9);
+}
+.k-callout-e {
+  border-left-color: rgba(100, 100, 100, 0.9);
+}
+.k-tooltip-validation .k-callout-n {
+  border-bottom-color: #fdefba;
+}
+.k-tooltip-validation .k-callout-w {
+  border-right-color: #fdefba;
+}
+.k-tooltip-validation .k-callout-s {
+  border-top-color: #fdefba;
+}
+.k-tooltip-validation .k-callout-e {
+  border-left-color: #fdefba;
+}
+/* Splitter */
+.k-splitbar {
+  background-color: #fafafa;
+}
+.k-restricted-size-vertical,
+.k-restricted-size-horizontal {
+  background-color: #b94a48;
+}
+/* Upload */
+.k-file {
+  background-color: #fff;
+  border-color: #e6e6e6;
+}
+.k-file-progress {
+  color: #2b98f3;
+}
+.k-file-progress .k-progress {
+  background-color: #bbdefb;
+}
+.k-file-success .k-file-name,
+.k-file-success .k-upload-pct {
+  color: #5fb662;
+}
+.k-file-success .k-progress {
+  background-color: #c8e6c9;
+}
+.k-file-error {
+  color: #ff3448;
+}
+.k-file-error .k-file-extension-wrapper,
+.k-file-error .k-multiple-files-extension-wrapper {
+  color: #ff3448;
+  border-color: #ff3448;
+}
+.k-file-error .k-file-extension-wrapper:before,
+.k-file-error .k-multiple-files-extension-wrapper:before {
+  background-color: #fff;
+  border-color: transparent transparent #ff3448 #ff3448;
+}
+.k-file-error .k-progress {
+  background-color: #ffcdd2;
+}
+.k-file-extension-wrapper,
+.k-multiple-files-extension-wrapper {
+  color: #999999;
+  border-color: #999999;
+}
+.k-file-invalid .k-file-name-invalid {
+  color: #ff3448;
+}
+.k-file-invalid-extension-wrapper,
+.k-multiple-files-invalid-extension-wrapper {
+  color: #ff3448;
+  border-color: #ff3448;
+}
+.k-file-extension-wrapper:before,
+.k-multiple-files-extension-wrapper:before {
+  background-color: #fff;
+  border-color: transparent transparent #999999 #999999;
+}
+.k-file-invalid-extension-wrapper:before,
+.k-multiple-files-invalid-extension-wrapper:before {
+  background-color: #fff;
+  border-color: transparent transparent #ff3448 #ff3448;
+}
+.k-multiple-files-extension-wrapper:after {
+  border-top-color: #999999;
+  border-left-color: #999999;
+}
+.k-multiple-files-invalid-extension-wrapper:after {
+  border-top-color: #ff3448;
+  border-left-color: #ff3448;
+}
+.k-file-size,
+.k-file-information,
+.k-file-validation-message {
+  color: #999999;
+}
+.k-upload .k-upload-selected {
+  color: #3f51b5;
+  border-color: #e6e6e6;
+}
+.k-upload .k-upload-selected:hover {
+  color: #fff;
+  background-color: #3f51b5;
+}
+/* ImageBrowser */
+.k-tile {
+  border-color: #fff;
+}
+.k-textbox:hover,
+.k-tiles li.k-state-hover {
+  border-color: #ebebeb;
+}
+.k-tiles li.k-state-selected {
+  border-color: #ffffff;
+}
+/* TreeMap */
+.k-leaf,
+.k-leaf.k-state-hover:hover {
+  color: #fff;
+}
+.k-leaf.k-inverse,
+.k-leaf.k-inverse.k-state-hover:hover {
+  color: #000;
+}
+/* Shadows */
+.k-widget,
+.k-button {
+  box-shadow: none;
+}
+.k-slider,
+.k-treeview,
+.k-upload {
+  box-shadow: none;
+}
+.k-state-hover {
+  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
+}
+.k-textbox:focus,
+.k-autocomplete.k-state-focused,
+.k-dropdown-wrap.k-state-focused,
+.k-picker-wrap.k-state-focused,
+.k-numeric-wrap.k-state-focused {
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-state-selected {
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
+}
+.k-state-active {
+  box-shadow: none;
+}
+.k-grid td.k-state-selected.k-state-focused {
+  background-color: #ffffff;
+}
+.k-popup,
+.k-menu .k-menu-group,
+.k-grid .k-filter-options,
+.k-time-popup,
+.k-datepicker-calendar,
+.k-autocomplete.k-state-border-down,
+.k-autocomplete.k-state-border-up,
+.k-dropdown-wrap.k-state-active,
+.k-picker-wrap.k-state-active,
+.k-multiselect.k-state-focused,
+.k-filebrowser .k-image,
+.k-tooltip {
+  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2);
+}
+.k-calendar-container.k-popup {
+  box-shadow: 0 0px 6px 1px rgba(0, 0, 0, 0.2);
+}
+.k-treemap-tile.k-state-hover {
+  box-shadow: inset 0 0 0 3px #e6e6e6;
+}
+/* Window */
+.k-window {
+  border-color: rgba(0, 0, 0, 0.2);
+  box-shadow: 1px 1px 7px 1px rgba(128, 128, 128, 0.2);
+  background-color: #fff;
+}
+.k-window.k-state-focused {
+  border-color: rgba(0, 0, 0, 0.2);
+  box-shadow: 1px 1px 7px 1px rgba(0, 0, 0, 0.2);
+}
+.k-window.k-window-maximized,
+.k-window-maximized .k-window-titlebar,
+.k-window-maximized .k-window-content {
+  border-radius: 0;
+}
+.k-shadow {
+  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
+}
+.k-inset {
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
+}
+/* Selection */
+.k-editor-inline ::selection {
+  background-color: #3f51b5;
+  text-shadow: none;
+  color: #fff;
+}
+.k-editor-inline ::-moz-selection {
+  background-color: #3f51b5;
+  text-shadow: none;
+  color: #fff;
+}
+/* Notification */
+.k-widget.k-notification.k-notification-info {
+  background-color: #bbdefb;
+  color: #2b98f3;
+  border-color: #bbdefb;
+}
+.k-widget.k-notification.k-notification-success {
+  background-color: #c8e6c9;
+  color: #5fb662;
+  border-color: #c8e6c9;
+}
+.k-widget.k-notification.k-notification-warning {
+  background-color: #fdefba;
+  color: #f8c70d;
+  border-color: #fdefba;
+}
+.k-widget.k-notification.k-notification-error {
+  background-color: #ffcdd2;
+  color: #ff3448;
+  border-color: #ffcdd2;
+}
+/* Gantt */
+.k-gantt .k-treelist {
+  background: #f2f2f2;
+}
+.k-gantt .k-treelist .k-alt {
+  background-color: #d9d9d9;
+}
+.k-gantt .k-treelist tr:hover {
+  background-color: #ebebeb;
+}
+.k-gantt .k-treelist .k-state-selected,
+.k-gantt .k-treelist .k-state-selected td,
+.k-gantt .k-treelist .k-alt.k-state-selected,
+.k-gantt .k-treelist .k-alt.k-state-selected > td {
+  background-color: #fff;
+}
+.k-gantt .k-treelist .k-alt.k-state-selected:hover,
+.k-gantt .k-treelist .k-alt.k-state-selected:hover td {
+  background-color: #00a2eb;
+}
+.k-task-dot:after {
+  background-color: #444444;
+  border-color: #444444;
+}
+.k-task-dot:hover:after {
+  background-color: #ffffff;
+}
+.k-task-summary {
+  border-color: #98a2db;
+  background: #98a2db;
+}
+.k-task-milestone,
+.k-task-summary-complete {
+  border-color: #444444;
+  background: #444444;
+}
+.k-state-selected.k-task-summary {
+  border-color: #98a2db;
+  background: #98a2db;
+}
+.k-state-selected.k-task-milestone,
+.k-state-selected .k-task-summary-complete {
+  border-color: #fff;
+  background: #fff;
+}
+.k-task-single {
+  background-color: #7a87d1;
+  border-color: #606fc7;
+  color: #ffffff;
+}
+.k-state-selected.k-task-single {
+  border-color: #ffffff;
+}
+.k-line {
+  background-color: #444444;
+  color: #444444;
+}
+.k-state-selected.k-line {
+  background-color: #fff;
+  color: #fff;
+}
+.k-resource {
+  background-color: #fff;
+}
+/* Border radius */
+.k-block,
+.k-button,
+.k-textbox,
+.k-drag-clue,
+.k-touch-scrollbar,
+.k-window,
+.k-window-titleless .k-window-content,
+.k-window-action,
+.k-inline-block,
+.k-grid .k-filter-options,
+.k-grouping-header .k-group-indicator,
+.k-autocomplete,
+.k-multiselect,
+.k-combobox,
+.k-dropdown,
+.k-dropdown-wrap,
+.k-datepicker,
+.k-timepicker,
+.k-colorpicker,
+.k-datetimepicker,
+.k-notification,
+.k-numerictextbox,
+.k-picker-wrap,
+.k-numeric-wrap,
+.k-list-container,
+.k-calendar-container,
+.k-calendar td,
+.k-calendar .k-link,
+.k-treeview .k-in,
+.k-editor-inline,
+.k-tooltip,
+.k-tile,
+.k-slider-track,
+.k-slider-selection,
+.k-upload {
+  border-radius: 2px;
+}
+.k-tool {
+  text-align: center;
+  vertical-align: middle;
+}
+.k-toolbar .k-split-button .k-button {
+  border-radius: 2px 0 0 2px;
+}
+.k-rtl .k-tool.k-group-start,
+.k-rtl .k-toolbar .k-split-button .k-button,
+.k-rtl .k-toolbar .k-button-group .k-group-start {
+  border-radius: 0 2px 2px 0;
+}
+.k-toolbar .k-split-button .k-split-button-arrow {
+  border-radius: 0 2px 2px 0;
+}
+.k-rtl .k-tool.k-group-end,
+.k-rtl .k-toolbar .k-button-group .k-group-end,
+.k-rtl .k-toolbar .k-split-button .k-split-button-arrow {
+  border-radius: 2px 0 0 2px;
+}
+.k-calendar-container.k-state-border-up,
+.k-list-container.k-state-border-up,
+.k-autocomplete.k-state-border-up,
+.k-multiselect.k-state-border-up,
+.k-dropdown-wrap.k-state-border-up,
+.k-picker-wrap.k-state-border-up,
+.k-numeric-wrap.k-state-border-up,
+.k-window-content,
+.k-filter-menu {
+  border-radius: 0 0 2px 2px;
+}
+.k-autocomplete.k-state-border-up .k-input,
+.k-dropdown-wrap.k-state-border-up .k-input,
+.k-picker-wrap.k-state-border-up .k-input,
+.k-picker-wrap.k-state-border-up .k-selected-color,
+.k-numeric-wrap.k-state-border-up .k-input {
+  border-radius: 0 0 0 2px;
+}
+.k-multiselect.k-state-border-up .k-multiselect-wrap {
+  border-radius: 0 0 2px 2px;
+}
+.k-window-titlebar,
+.k-block > .k-header,
+.k-tabstrip-items .k-item,
+.k-panelbar .k-tabstrip-items .k-item,
+.k-tabstrip-items .k-link,
+.k-calendar-container.k-state-border-down,
+.k-list-container.k-state-border-down,
+.k-autocomplete.k-state-border-down,
+.k-multiselect.k-state-border-down,
+.k-dropdown-wrap.k-state-border-down,
+.k-picker-wrap.k-state-border-down,
+.k-numeric-wrap.k-state-border-down {
+  border-radius: 2px 2px 0 0;
+}
+.k-split-button.k-state-border-down > .k-button {
+  border-radius: 2px 0 0 0;
+}
+.k-split-button.k-state-border-up > .k-button {
+  border-radius: 0 0 0 2px;
+}
+.k-split-button.k-state-border-down > .k-split-button-arrow {
+  border-radius: 0 2px 0 0;
+}
+.k-split-button.k-state-border-up > .k-split-button-arrow {
+  border-radius: 0 0 2px 0;
+}
+.k-dropdown-wrap .k-input,
+.k-picker-wrap .k-input,
+.k-numeric-wrap .k-input {
+  border-radius: 1px 0 0 1px;
+}
+.k-rtl .k-dropdown-wrap .k-input,
+.k-rtl .k-picker-wrap .k-input,
+.k-rtl .k-numeric-wrap .k-input {
+  border-radius: 0 1px 1px 0;
+}
+.k-numeric-wrap .k-link {
+  border-radius: 0 1px 0 0;
+}
+.k-numeric-wrap .k-link + .k-link {
+  border-radius: 0 0 1px 0;
+}
+.k-colorpicker .k-selected-color {
+  border-radius: 1px 0 0 1px;
+}
+.k-rtl .k-colorpicker .k-selected-color {
+  border-radius: 0 1px 1px 0;
+}
+.k-autocomplete.k-state-border-down .k-input {
+  border-radius: 2px 2px 0 0;
+}
+.k-dropdown-wrap.k-state-border-down .k-input,
+.k-picker-wrap.k-state-border-down .k-input,
+.k-picker-wrap.k-state-border-down .k-selected-color,
+.k-numeric-wrap.k-state-border-down .k-input {
+  border-radius: 2px 0 0 0;
+}
+.k-numeric-wrap .k-link.k-state-selected {
+  background-color: #ebebeb;
+}
+.k-multiselect.k-state-border-down .k-multiselect-wrap {
+  border-radius: 1px 1px 0 0;
+}
+.k-dropdown-wrap .k-select,
+.k-picker-wrap .k-select,
+.k-numeric-wrap .k-select,
+.k-datetimepicker .k-select + .k-select,
+.k-list-container.k-state-border-right {
+  border-radius: 0 2px 2px 0;
+}
+.k-rtl .k-dropdown-wrap .k-select,
+.k-rtl .k-picker-wrap .k-select,
+.k-rtl .k-numeric-wrap .k-select,
+.k-rtl .k-datetimepicker .k-select + .k-select,
+.k-rtl .k-list-container.k-state-border-right {
+  border-radius: 2px 0 0 2px;
+}
+.k-numeric-wrap.k-expand-padding .k-input {
+  border-radius: 2px;
+}
+.k-textbox > input,
+.k-autocomplete .k-input,
+.k-multiselect-wrap {
+  border-radius: 1px;
+}
+.k-list .k-state-hover,
+.k-list .k-state-focused,
+.k-list .k-state-highlight,
+.k-list .k-state-selected,
+.k-fieldselector .k-list .k-item,
+.k-list-optionlabel,
+.k-dropzone,
+.k-listbox .k-item {
+  border-radius: 1px;
+}
+.k-slider .k-button,
+.k-grid .k-slider .k-button {
+  border-radius: 13px;
+}
+.k-draghandle {
+  border-radius: 13px;
+}
+.k-scheduler-toolbar > ul li:first-child,
+.k-scheduler-toolbar > ul li:first-child .k-link,
+.k-scheduler-toolbar > ul.k-scheduler-views li:first-child + li,
+.k-scheduler-toolbar > ul.k-scheduler-views li:first-child + li .k-link {
+  border-radius: 2px 0 0 2px;
+}
+.k-rtl .k-scheduler-toolbar > ul li:first-child,
+.k-rtl .k-scheduler-toolbar > ul li:first-child .k-link,
+.k-rtl .k-scheduler-toolbar > ul.k-scheduler-views li:first-child + li,
+.k-rtl .k-scheduler-toolbar > ul.k-scheduler-views li:first-child + li .k-link,
+.km-view.k-popup-edit-form .k-scheduler-toolbar > ul li:last-child,
+.km-view.k-popup-edit-form .k-scheduler-toolbar > ul li:last-child .k-link {
+  border-radius: 0 2px 2px 0;
+}
+.k-scheduler-phone .k-scheduler-toolbar > ul li.k-nav-today,
+.k-scheduler-phone .k-scheduler-toolbar > ul li.k-nav-today .k-link,
+.k-edit-field > .k-scheduler-navigation {
+  border-radius: 2px;
+}
+.k-scheduler-toolbar .k-nav-next,
+.k-scheduler-toolbar ul + ul li:last-child,
+.k-scheduler-toolbar .k-nav-next .k-link,
+.k-scheduler-toolbar ul + ul li:last-child .k-link {
+  border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+}
+.k-rtl .k-scheduler-toolbar .k-nav-next,
+.k-rtl .k-scheduler-toolbar ul + ul li:last-child,
+.k-rtl .k-scheduler-toolbar .k-nav-next .k-link,
+.k-rtl .k-scheduler-toolbar ul + ul li:last-child .k-link {
+  border-radius: 2px 0 0 2px;
+}
+.k-scheduler div.k-scheduler-footer ul li,
+.k-scheduler div.k-scheduler-footer .k-link {
+  border-radius: 2px;
+}
+.k-more-events,
+.k-event,
+.k-task-single,
+.k-task-complete,
+.k-event .k-link {
+  border-radius: 1px;
+}
+.k-scheduler-mobile .k-event {
+  border-radius: 0px;
+}
+/* Adaptive Grid */
+.k-grid-mobile .k-column-active + th.k-header {
+  border-left-color: #444444;
+}
+html .km-pane-wrapper .km-widget,
+.k-ie .km-pane-wrapper .k-widget,
+.k-ie .km-pane-wrapper .k-group,
+.k-ie .km-pane-wrapper .k-content,
+.k-ie .km-pane-wrapper .k-header,
+.k-ie .km-pane-wrapper .k-popup-edit-form .k-edit-field .k-button,
+.km-pane-wrapper .k-mobile-list .k-item,
+.km-pane-wrapper .k-mobile-list .k-edit-label,
+.km-pane-wrapper .k-mobile-list .k-edit-field {
+  color: #444444;
+}
+@media screen and (-ms-high-contrast: active) and (-ms-high-contrast: none) {
+  div.km-pane-wrapper a {
+    color: #444444;
+  }
+}
+.km-pane-wrapper .k-mobile-list .k-item,
+.km-pane-wrapper .k-mobile-list .k-edit-field,
+.km-pane-wrapper .k-mobile-list .k-recur-view > .k-edit-field .k-check {
+  background-color: #fff;
+  border-top: 1px solid #e7e7e7;
+}
+.km-pane-wrapper .k-mobile-list .k-edit-field textarea {
+  outline-width: 0;
+}
+.km-pane-wrapper .k-mobile-list .k-item.k-state-selected {
+  background-color: #fff;
+  border-top-color: #ffffff;
+}
+.km-pane-wrapper .k-mobile-list .k-recur-view > .k-edit-field .k-check:first-child {
+  border-top-color: transparent;
+}
+.km-pane-wrapper .k-mobile-list .k-item:last-child {
+  box-shadow: inset 0 -1px 0 #e7e7e7;
+}
+.km-pane-wrapper .k-mobile-list > ul > li > .k-link,
+.km-pane-wrapper .k-mobile-list .k-recur-view > .k-edit-label:nth-child(3),
+.km-pane-wrapper #recurrence .km-scroll-container > .k-edit-label:first-child {
+  color: #9b9b9b;
+}
+.km-pane-wrapper .k-mobile-list > ul > li > .k-link {
+  border-bottom: 1px solid #e7e7e7;
+}
+.km-pane-wrapper .k-mobile-list .k-edit-field {
+  box-shadow: 0 1px 1px #e7e7e7;
+}
+.km-actionsheet .k-grid-delete,
+.km-actionsheet .k-scheduler-delete,
+.km-pane-wrapper .k-scheduler-delete,
+.km-pane-wrapper .k-filter-menu .k-button[type=reset] {
+  color: #fff;
+  border-color: #eed3d7;
+  background-color: red;
+  background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.15));
+}
+.km-actionsheet .k-grid-delete:active,
+.km-actionsheet .k-scheduler-delete:active,
+.km-pane-wrapper .k-scheduler-delete:active,
+.km-pane-wrapper .k-filter-menu .k-button[type=reset]:active {
+  background-color: #990000;
+}
+/* /Column Menu */
+.k-autocomplete.k-state-default,
+.k-picker-wrap.k-state-default,
+.k-numeric-wrap.k-state-default,
+.k-dropdown-wrap.k-state-default {
+  background-image: none;
+  background-position: 50% 50%;
+  color: #444444;
+  background-color: #fafafa;
+  border-color: #f0f0f0;
+}
+.k-autocomplete.k-state-hover,
+.k-picker-wrap.k-state-hover,
+.k-numeric-wrap.k-state-hover,
+.k-dropdown-wrap.k-state-hover {
+  background-color: #ffffff;
+  background-image: none;
+  background-position: 50% 50%;
+  border-color: #f5f5f5;
+}
+.k-multiselect.k-header {
+  border-color: #f0f0f0;
+}
+.k-multiselect.k-header.k-state-hover {
+  border-color: #f5f5f5;
+}
+.k-autocomplete.k-state-focused,
+.k-picker-wrap.k-state-focused,
+.k-numeric-wrap.k-state-focused,
+.k-dropdown-wrap.k-state-focused,
+.k-multiselect.k-header.k-state-focused {
+  background-color: #ffffff;
+  background-image: none;
+  background-position: 50% 50%;
+  border-color: #f5f5f5;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-list-container {
+  color: #444444;
+}
+.k-nodata {
+  color: #999999;
+}
+.k-dropdown .k-input,
+.k-dropdown .k-state-focused .k-input,
+.k-menu .k-popup {
+  color: #444444;
+}
+.k-state-default > .k-select {
+  border-color: #f0f0f0;
+}
+.k-state-focused > .k-select {
+  border-color: #f5f5f5;
+}
+.k-state-hover > .k-select {
+  border-color: #f5f5f5;
+}
+.k-tabstrip:focus {
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-tabstrip-items .k-state-default .k-link,
+.k-panelbar > li.k-state-default > .k-link {
+  color: #ffffff;
+}
+.k-tabstrip-items .k-state-hover .k-link,
+.k-panelbar > li.k-state-hover > .k-link,
+.k-panelbar > li.k-state-default > .k-link.k-state-hover {
+  color: #444444;
+}
+.k-panelbar > li > .k-state-focused.k-state-hover {
+  background: #ebebeb;
+  box-shadow: none;
+}
+.k-tabstrip-items .k-state-default,
+.k-panelbar .k-tabstrip-items .k-state-default {
+  border-color: transparent;
+}
+.k-tabstrip-items .k-state-hover {
+  border-color: #ebebeb;
+}
+.k-tabstrip .k-content.k-state-active {
+  background-color: #fff;
+  color: #444444;
+}
+.k-menu.k-header,
+.k-menu .k-item {
+  border-color: #e6e6e6;
+}
+.k-column-menu,
+.k-column-menu .k-item,
+.k-overflow-container .k-overflow-group {
+  border-color: #cccccc;
+}
+.k-overflow-container .k-overflow-group {
+  box-shadow: inset 0 1px 0 #ffffff, 0 1px 0 #ffffff;
+}
+.k-toolbar-first-visible.k-overflow-group,
+.k-overflow-container .k-overflow-group + .k-overflow-group {
+  box-shadow: 0 1px 0 #ffffff;
+}
+.k-toolbar-last-visible.k-overflow-group {
+  box-shadow: inset 0 1px 0 #ffffff;
+}
+.k-column-menu .k-separator {
+  border-color: #cccccc;
+  background-color: transparent;
+}
+.k-menu .k-group {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.k-grid-filter.k-state-active {
+  background-color: #ffffff;
+}
+.k-grouping-row td,
+.k-group-footer td,
+.k-grid-footer td {
+  color: #ffffff;
+  border-color: #cccccc;
+  font-weight: bold;
+}
+.k-grouping-header {
+  color: #ffffff;
+}
+.k-header,
+.k-grid-header-wrap,
+.k-grid .k-grouping-header,
+.k-grid-header,
+.k-pager-wrap,
+.k-pager-wrap .k-textbox,
+.k-pager-wrap .k-link,
+.k-grouping-header .k-group-indicator,
+.k-gantt-toolbar .k-state-default {
+  border-color: #cccccc;
+}
+.k-primary,
+.k-overflow-container .k-primary {
+  color: #ffffff;
+  border-color: #3f51b5;
+  background-image: none;
+  background-position: 50% 50%;
+  background-color: #3f51b5;
+  box-shadow: none;
+}
+.k-primary:focus,
+.k-primary.k-state-focused {
+  color: #ffffff;
+  border-color: #eff8ff;
+  background-image: none;
+  box-shadow: 0 0 8px 0 #cfe6f8;
+}
+.k-primary:hover {
+  color: #ffffff;
+  border-color: #5c6bc0;
+  background-image: none;
+  background-color: #5c6bc0;
+  box-shadow: none;
+}
+.k-primary:focus:active:not(.k-state-disabled):not([disabled]),
+.k-primary:focus:not(.k-state-disabled):not([disabled]) {
+  box-shadow: 0 0 8px 0 #cfe6f8;
+}
+.k-primary:active {
+  color: #ffffff;
+  border-color: #283593;
+  background-image: none;
+  background-color: #283593;
+  box-shadow: 0 6px 17px 0 rgba(0, 0, 0, 0.3);
+}
+.k-primary.k-state-disabled,
+.k-state-disabled .k-primary,
+.k-primary.k-state-disabled:hover,
+.k-state-disabled .k-primary:hover,
+.k-primary.k-state-disabled:hover,
+.k-state-disabled .k-primary:active,
+.k-primary.k-state-disabled:active {
+  color: #a8a8a8;
+  border-color: #eaeaea;
+  background-color: #eaeaea;
+  background-image: none;
+  box-shadow: none;
+}
+.k-pager-numbers .k-link,
+.k-treeview .k-in {
+  border-color: transparent;
+}
+.k-treeview .k-icon,
+.k-scheduler-table .k-icon,
+.k-grid .k-hierarchy-cell .k-icon {
+  background-color: transparent;
+  border-radius: 50%;
+}
+.k-scheduler-table .k-state-hover .k-icon {
+  background-color: transparent;
+}
+.k-button:focus,
+.k-split-button:focus {
+  outline: none;
+}
+.k-split-button:focus {
+  background-color: #dbdbdb;
+}
+.k-split-button:focus > .k-button {
+  background: transparent;
+  border-color: #dbdbdb;
+}
+.k-split-button:focus > .k-button.k-split-button-arrow {
+  border-left-color: #f2f2f2;
+}
+.k-editor .k-tool {
+  color: inherit;
+}
+.k-editor .k-tool:focus {
+  outline: 0;
+  border-color: #dbdbdb;
+  box-shadow: 0 6px 17px 0 #c4c4c4;
+}
+.k-checkbox-label:before {
+  border-color: #7f7f7f;
+  background: #fff;
+  border-radius: 1px;
+}
+.k-checkbox:hover + .k-checkbox-label:before,
+.k-checkbox:checked:hover + .k-checkbox-label:before,
+.k-checkbox-label:hover:before,
+.k-checkbox:checked + .k-checkbox-label:hover:before {
+  border-color: #7f7f7f;
+  box-shadow: none;
+}
+.k-checkbox:checked + .k-checkbox-label:before {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+  color: #ffffff;
+}
+.k-checkbox:active + .k-checkbox-label:before,
+.k-checkbox-label:active:before {
+  box-shadow: none;
+  border-color: #7f7f7f;
+}
+.k-checkbox:checked:active + .k-checkbox-label:before,
+.k-checkbox:checked + .k-checkbox-label:before {
+  box-shadow: none;
+  border-color: #7f7f7f;
+}
+.k-checkbox:disabled + .k-checkbox-label {
+  color: #999999;
+}
+.k-checkbox:disabled + .k-checkbox-label:hover:before {
+  box-shadow: none;
+}
+.k-checkbox:disabled + .k-checkbox-label:before,
+.k-checkbox:checked:disabled + .k-checkbox-label:before,
+.k-checkbox:checked:disabled + .k-checkbox-label:active:before,
+.k-checkbox:checked:disabled + .k-checkbox-label:hover:before {
+  color: #999999;
+  background: #f5f5f5;
+  border-color: #bfbfbf;
+  border-radius: 1px;
+}
+.k-checkbox:focus + .k-checkbox-label:before {
+  border-color: #7f7f7f;
+  box-shadow: none;
+}
+.k-checkbox:indeterminate + .k-checkbox-label:after {
+  background-color: #3f51b5;
+  background-image: none;
+  border-color: #3f51b5;
+  border-radius: 0px;
+}
+.k-checkbox:indeterminate:hover + .k-checkbox-label:after {
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+}
+.k-checkbox + .k-checkbox-label:after {
+  content: "";
+  position: absolute;
+  top: 1px;
+  left: 1px;
+  border-radius: 50%;
+  width: 1em;
+  height: 1em;
+}
+.k-checkbox:focus + .k-checkbox-label:after {
+  box-shadow: 0 0 0 12px rgba(235, 235, 235, 0.3);
+}
+.k-checkbox:active + .k-checkbox-label:after,
+.k-checkbox + .k-checkbox-label:active:after {
+  box-shadow: 0 0 0 12px rgba(235, 235, 235, 0.3);
+}
+.k-checkbox:checked:active + .k-checkbox-label:after,
+.k-checkbox:checked + .k-checkbox-label:active:after {
+  box-shadow: 0 0 0 12px rgba(63, 81, 181, 0.3);
+}
+.k-checkbox:disabled + .k-checkbox-label:active:after {
+  box-shadow: none;
+}
+.k-checkbox:indeterminate + .k-checkbox-label:before {
+  border-color: #3f51b5;
+}
+.k-radio-label:before {
+  border-color: #7f7f7f;
+  border-radius: 50%;
+  background-color: #fff;
+  border-width: 2px;
+}
+.k-radio-label:hover:before,
+.k-radio:checked + .k-radio-label:hover:before {
+  border-color: #7f7f7f;
+  box-shadow: none;
+}
+.k-radio:checked + .k-radio-label:after {
+  background-color: #3f51b5;
+  border-radius: 50%;
+}
+.k-radio-label:active:before {
+  border-color: #6b7acb;
+  box-shadow: 0 0 2px 0 #6b7acb;
+}
+.k-radio:checked + .k-radio-label:active:before {
+  box-shadow: 0 0 2px 0 #6b7acb;
+  border-color: #6b7acb;
+}
+.k-radio:disabled + .k-radio-label {
+  color: #bfbfbf;
+}
+.k-radio:disabled + .k-radio-label:before,
+.k-radio:disabled + .k-radio-label:active:before,
+.k-radio:disabled + .k-radio-label:hover:after,
+.k-radio:disabled + .k-radio-label:hover:before {
+  background: #ffffff;
+  border-color: #bfbfbf;
+  box-shadow: none;
+}
+.k-radio:disabled:checked + .k-radio-label:after {
+  background-color: #3f51b5;
+  opacity: .5;
+}
+.k-radio:focus + .k-radio-label:before {
+  border-color: #6b7acb;
+  box-shadow: 0 0 2px 0 #6b7acb;
+}
+.k-radio:checked + .k-radio-label:before,
+.k-radio:checked + .k-radio-label:hover:before {
+  border-color: #3f51b5;
+}
+.k-radio + .k-radio-label:active:before {
+  border-color: #7f7f7f;
+  box-shadow: 0 0 0 12px rgba(235, 235, 235, 0.3);
+}
+.k-radio:checked + .k-radio-label:active:before {
+  box-shadow: 0 0 0 12px rgba(63, 81, 181, 0.3);
+}
+.k-radio:focus + .k-radio-label:before {
+  border-color: #7f7f7f;
+  box-shadow: 0 0 0 12px rgba(235, 235, 235, 0.3);
+}
+.k-radio:disabled:checked + .k-radio-label:before,
+.k-radio:disabled:checked + .k-radio-label:hover:before {
+  border-color: #bfbfbf;
+}
+.k-radio:disabled:checked + .k-radio-label:active:before {
+  box-shadow: none;
+}
+@media screen and (-ms-high-contrast: active) {
+  .k-editor-toolbar-wrap .k-dropdown-wrap.k-state-focused,
+  .k-editor-toolbar-wrap .k-button-group .k-tool:focus {
+    border-color: #fff;
+  }
+}
+.k-button:hover .k-icon,
+.k-tool-icon:hover,
+.k-state-hover .k-tool-icon,
+.k-state-selected .k-tool-icon,
+.k-state-focused .k-tool-icon,
+.k-button:hover .k-tool-icon,
+.k-splitbar.k-splitbar-horizontal-hover .k-icon,
+.k-splitbar.k-splitbar-vertical-hover .k-icon,
+div.k-splitbar.k-state-focused .k-icon,
+.k-textbox:hover > .k-icon,
+.k-grouping-header .k-i-delete,
+.k-grouping-header .k-button-icon:hover > .k-icon.k-i-delete,
+.k-grouping-header .k-i-delete,
+.k-grouping-header .k-button-icon:hover > .k-icon.k-i-delete,
+.k-grouping-header .k-i-arrow-60-up,
+.k-grouping-header .k-link:hover > .k-icon.k-i-arrow-60-up,
+.k-grouping-header .k-i-arrow-60-up,
+.k-grouping-header .k-link:hover > .k-icon.k-i-arrow-60-up,
+.k-grouping-header .k-i-arrow-60-down,
+.k-grouping-header .k-link:hover > .k-icon.k-i-arrow-60-down,
+.k-grouping-header .k-i-arrow-60-down,
+.k-grouping-header .k-link:hover > .k-icon.k-i-arrow-60-down,
+.k-grid-toolbar .k-i-file-pdf,
+.k-grid-toolbar .k-button:hover > .k-i-file-pdf,
+.k-grid-toolbar .k-i-file-excel,
+.k-grid-toolbar .k-button:hover > .k-i-file-excel,
+.k-grid-toolbar .k-icon,
+.k-scheduler-toolbar .k-icon,
+.k-scheduler-footer .k-icon,
+.k-scheduler-content .k-icon,
+.k-gantt-toolbar .k-icon,
+.k-field-actions .k-icon,
+.k-notification .k-icon,
+.k-pivot-configurator-settings .k-icon:hover,
+.k-window-titlebar .k-icon {
+  opacity: 1;
+}
+.k-splitbar .k-icon,
+.k-pivot-configurator-settings .k-icon {
+  opacity: 0.7;
+}
+.k-pager-wrap .k-link.k-state-disabled .k-icon {
+  opacity: 0.25;
+}
+.k-button,
+.k-button:hover,
+.k-button.k-state-hover,
+.k-button.k-state-focused,
+.k-button:focus,
+.k-button:focus:not(.k-state-disabled):not([disabled]) {
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-button,
+.k-header {
+  font-weight: 500;
+}
+.k-button:active,
+.k-button.k-state-active,
+.k-button:focus,
+.k-button.k-state-focused {
+  color: #444444;
+  background-color: #dbdbdb;
+  border-color: #dbdbdb;
+}
+.k-button:active:hover,
+.k-button.k-state-active:hover {
+  color: #444444;
+  border-color: #dbdbdb;
+  background-color: #dbdbdb;
+  box-shadow: 0 6px 17px 0 rgba(235, 235, 235, 0.3);
+}
+.k-button:hover,
+.k-button.k-state-hover,
+.k-button:active:hover,
+.k-button.k-state-active:hover {
+  color: #444444;
+  border-color: #ebebeb;
+  background-color: #ebebeb;
+}
+.k-primary:active,
+.k-primary.k-state-active,
+.k-primary:focus,
+.k-primary.k-state-focused {
+  color: #ffffff;
+  border-color: #283593;
+  background-image: none;
+  background-color: #283593;
+  box-shadow: 0 6px 17px 0 rgba(0, 0, 0, 0.3);
+}
+.k-primary:hover,
+.k-primary.k-state-hover,
+.k-primary:active:hover,
+.k-primary.k-state-active:hover {
+  color: #ffffff;
+  border-color: #5c6bc0;
+  background-color: #5c6bc0;
+}
+.k-primary:focus:not(.k-state-disabled):not([disabled]),
+.k-primary:focus:active:not(.k-state-disabled):not([disabled]) {
+  box-shadow: 0 6px 17px 0 rgba(0, 0, 0, 0.3);
+}
+.k-primary.k-state-disabled,
+.k-state-disabled .k-primary,
+.k-primary.k-state-disabled:hover,
+.k-state-disabled .k-primary:hover,
+.k-primary.k-state-disabled:hover,
+.k-state-disabled .k-primary:active,
+.k-primary.k-state-disabled:active {
+  color: #a8a8a8;
+  border-color: #eaeaea;
+  background-color: #eaeaea;
+  background-image: none;
+  box-shadow: none;
+}
+.k-widget .k-button:active,
+.k-widget .k-button.k-state-active {
+  color: #444444;
+  background-color: #dbdbdb;
+  border-color: #ebebeb;
+}
+.k-toolbar .k-overflow-anchor.k-state-active,
+.k-toolbar .k-overflow-anchor.k-state-border-down {
+  background-color: #ffffff;
+}
+.k-widget .k-button:active:hover,
+.k-widget .k-button.k-state-active:hover {
+  color: #444444;
+  border-color: #ebebeb;
+  background-color: #ebebeb;
+}
+.k-button[disabled],
+.k-button.k-state-disabled,
+.k-state-disabled .k-button,
+.k-state-disabled .k-button:hover,
+.k-button.k-state-disabled:hover,
+.k-state-disabled .k-button:active,
+.k-button.k-state-disabled:active,
+.k-button.k-state-disabled:active:hover,
+.k-listbox .k-button.k-state-disabled {
+  color: #999999;
+  border-color: #fafafa;
+  background-color: #fafafa;
+  background-image: none;
+  box-shadow: none;
+}
+.k-dropdown .k-state-default {
+  border-color: #fafafa;
+  background-image: none;
+  background-position: 50% 50%;
+  background-color: #fafafa;
+}
+.k-dropdown,
+span.k-colorpicker {
+  background-color: #fafafa;
+}
+.k-textbox {
+  background-color: #fafafa;
+  border-color: #f0f0f0;
+}
+.k-combobox,
+.k-datepicker,
+.k-timepicker,
+.k-datetimepicker {
+  background-color: #fafafa;
+}
+.k-picker-wrap.k-state-default > .k-select {
+  border-color: #fafafa;
+}
+.k-datepicker .k-input,
+.k-timepicker .k-input {
+  background-color: #fafafa;
+}
+.k-autocomplete.k-state-active .k-input,
+.k-picker-wrap.k-state-active .k-input,
+.k-numeric-wrap.k-state-active .k-input {
+  background-color: #fff;
+}
+.k-picker-wrap.k-state-hover > .k-select,
+.k-picker-wrap.k-state-focused > .k-select {
+  border-color: #ffffff;
+}
+.k-picker-wrap.k-state-hover .k-input,
+.k-picker-wrap.k-state-focused .k-input {
+  background-color: #ffffff;
+}
+.k-textbox:hover,
+.k-overflow-anchor:hover,
+.k-autocomplete.k-state-hover,
+.k-picker-wrap.k-state-hover,
+.k-numeric-wrap.k-state-hover,
+.k-dropdown-wrap.k-state-hover {
+  background-color: #fff;
+  border-color: #f5f5f5;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-textbox:focus,
+.k-autocomplete.k-state-focused,
+.k-picker-wrap.k-state-focused,
+.k-numeric-wrap.k-state-focused,
+.k-dropdown-wrap.k-state-focused,
+.k-multiselect.k-header.k-state-focused {
+  background-color: #ebebeb;
+  background-image: none;
+  background-position: 50% 50%;
+  border-color: #ebebeb;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-numeric-wrap.k-state-focused > .k-select {
+  background-color: #ebebeb;
+}
+.k-textbox:focus,
+.k-autocomplete.k-state-active,
+.k-picker-wrap.k-state-active,
+.k-numeric-wrap.k-state-active,
+.k-dropdown-wrap.k-state-active,
+.k-multiselect.k-header.k-state-active {
+  background-color: #fff;
+  background-image: none;
+  background-position: 50% 50%;
+  border-color: #f5f5f5;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-autocomplete.k-state-disabled,
+.k-picker-wrap.k-state-disabled,
+.k-numeric-wrap.k-state-disabled,
+.k-numeric-wrap.k-state-disabled .k-input,
+.k-numeric-wrap.k-state-disabled .k-select,
+.k-dropdown-wrap.k-state-disabled,
+.k-multiselect.k-header.k-state-disabled {
+  background-color: #fafafa;
+}
+.k-numeric-wrap.k-state-disabled .k-select {
+  border-color: #fafafa;
+}
+.k-numerictextbox .k-select {
+  background-color: #fff;
+  border-color: #fff;
+}
+.k-list > .k-state-selected.k-state-focused {
+  box-shadow: none;
+  color: #3f51b5;
+}
+.k-list > .k-state-selected {
+  box-shadow: none;
+}
+.k-list > .k-state-focused {
+  border-color: transparent;
+  box-shadow: none;
+}
+.k-list > .k-state-hover,
+.k-list > .k-state-selected.k-state-hover {
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+.k-list-container {
+  border-color: #ebebeb;
+}
+.k-grid td.k-state-focused.k-state-selected {
+  box-shadow: inset 0 0 0 1px #808080;
+}
+.k-calendar td.k-state-focused,
+.k-calendar td.k-state-selected.k-state-focused {
+  box-shadow: inset 0 0 0 1px #808080;
+}
+.k-calendar td.k-state-selected {
+  background-color: #00b0ff;
+  box-shadow: none;
+}
+.k-calendar td.k-state-selected.k-state-hover {
+  background-color: #00a2eb;
+}
+.k-calendar .k-state-selected > .k-link {
+  color: #fff;
+}
+/* Calendar */
+.k-calendar .k-header .k-link {
+  color: #ffffff;
+}
+.k-calendar .k-footer {
+  border-color: #e6e6e6;
+}
+.k-calendar td {
+  border-radius: 50%;
+}
+.k-calendar .k-content th {
+  background-color: #fff;
+}
+.k-calendar .k-alt {
+  border-radius: 0;
+  background-color: #f2f2f2;
+}
+.k-calendar .k-header .k-state-hover {
+  background-color: #32408f;
+}
+.k-calendar .k-footer .k-nav-today {
+  color: #3f51b5;
+}
+.k-calendar .k-nav-fast.k-state-hover {
+  border-radius: 0;
+}
+.k-calendar .k-today {
+  background-color: #3f51b5;
+}
+.k-calendar .k-today .k-link {
+  color: #fff;
+}
+.k-calendar .k-today.k-state-hover {
+  background-color: #32408f;
+}
+.k-calendar .k-today:active {
+  box-shadow: inset 0 0 0 1px #2b387c;
+}
+.k-calendar .k-link.k-state-hover,
+.k-window-titlebar .k-link {
+  box-shadow: none;
+}
+.k-window-titlebar .k-state-hover {
+  background-color: #5c6dc4;
+  border-color: #5c6dc4;
+}
+/* TabStrip */
+.k-tabstrip > .k-tabstrip-items > .k-item {
+  border-radius: 0;
+}
+.k-tabstrip-items .k-state-active,
+.k-panelbar .k-tabstrip-items .k-state-active {
+  background-color: #3f51b5;
+  background-image: none;
+  border-bottom-color: #00b0ff;
+}
+.k-tabstrip .k-content.k-state-active {
+  border-color: transparent;
+}
+.k-tabstrip-items .k-item.k-state-hover {
+  background: #5c6dc4;
+  border-color: #5c6dc4;
+}
+.k-tabstrip-items .k-state-hover .k-link {
+  color: #ffffff;
+}
+/* Menu */
+.k-group,
+.k-flatcolorpicker.k-group,
+.k-menu,
+.k-menu .k-group,
+.k-popup.k-widget.k-context-menu {
+  color: #444444;
+  background-color: #fff;
+}
+.k-menu .k-group,
+.k-popup.k-context-menu.k-group {
+  border-color: #e6e6e6;
+}
+.k-menu.k-header,
+.k-menu .k-item,
+.k-widget.k-menu-horizontal > .k-item {
+  box-shadow: none;
+}
+.k-menu .k-state-active,
+.k-popup.k-context-menu.k-group .k-state-hover {
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+/* Toolbar */
+.k-toolbar {
+  background-color: #fafafa;
+  border-color: #e6e6e6;
+}
+.k-toolbar .k-toggle-button:focus {
+  background-color: transparent;
+  border-color: #b3b3b3;
+}
+.k-toolbar .k-toggle-button:hover {
+  background-color: #ebebeb;
+}
+.k-toolbar .k-toggle-button.k-state-active {
+  color: #fff;
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+}
+.k-toolbar .k-toggle-button.k-state-active:focus {
+  background-color: #3f51b5;
+  border-color: #2b387c;
+}
+.k-toolbar .k-toggle-button.k-state-active:hover {
+  color: #fff;
+  background-color: #32408f;
+  border-color: #32408f;
+}
+.k-mediaplayer-toolbar {
+  background: rgba(250, 250, 250, 0.85);
+}
+.k-toolbar .k-button {
+  box-shadow: none;
+}
+.k-ie .k-toolbar .k-input {
+  height: 2.2em;
+}
+.k-grid .k-header .k-button,
+.k-scheduler .k-header .k-button,
+.k-scheduler .k-header li,
+.k-scheduler .k-header .k-link,
+.k-gantt > .k-header li,
+.k-gantt > .k-header .k-link,
+.k-gantt-toolbar .k-button,
+.km-pane-wrapper .k-header .k-button {
+  color: #ffffff;
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+  box-shadow: none;
+}
+.k-grid .k-header .k-button:hover,
+.k-scheduler .k-header .k-button:hover,
+.k-scheduler .k-scheduler-toolbar .k-scheduler-views li.k-state-hover,
+.k-scheduler .k-scheduler-toolbar .k-scheduler-views li.k-state-hover .k-link,
+.k-gantt .k-gantt-toolbar .k-gantt-views li.k-state-hover,
+.k-gantt .k-gantt-toolbar .k-gantt-views li.k-state-hover .k-link,
+.k-gantt .k-gantt-toolbar .k-button:hover,
+.km-pane-wrapper .k-header .k-button:hover {
+  background-color: #5c6dc4;
+  border-color: #5c6dc4;
+}
+.km-pane-wrapper .k-header .k-button:active:hover {
+  color: #ffffff;
+}
+.k-scheduler .k-scheduler-toolbar ul li.k-state-hover,
+.k-scheduler .k-scheduler-toolbar .k-state-selected,
+.k-gantt-toolbar .k-button {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+}
+.k-gantt .k-gantt-toolbar .k-button:active {
+  background: #fff;
+  box-shadow: none;
+}
+.k-gantt-toolbar > .k-gantt-views > li.k-state-selected,
+.k-gantt .k-gantt-toolbar .k-gantt-views li.k-state-selected.k-state-hover,
+.k-scheduler .k-scheduler-toolbar .k-scheduler-views li.k-state-selected.k-state-hover,
+.k-scheduler-toolbar > .k-scheduler-views > li.k-state-selected {
+  border-bottom-color: #00b0ff;
+}
+.k-scheduler-mark {
+  border-radius: 50%;
+}
+/* Grid */
+.k-grid .k-alt {
+  background-color: #fff;
+}
+.k-grouping-row td,
+td.k-group-cell,
+.k-resize-handle-inner {
+  color: #444444;
+  background-color: #f2f2f2;
+}
+.k-grouping-header .k-group-indicator,
+.k-pivot-toolbar .k-button {
+  color: #ffffff;
+  background-color: #32408f;
+  border-color: #32408f;
+  box-shadow: none;
+}
+.k-grid-header,
+.k-grid-header .k-header,
+.k-pager-wrap,
+.k-pager-numbers .k-state-selected,
+.k-grid-footer,
+.k-grid-footer td,
+.k-scheduler-header,
+.km-pane-wrapper .k-grid-header .k-header {
+  color: #444444;
+  background-color: #fafafa;
+}
+.k-header.k-scheduler-footer .k-header,
+.k-header.k-scheduler-footer ul.k-header li .k-link {
+  color: #00b0ff;
+  background-color: #fafafa;
+}
+.k-header.k-scheduler-footer ul.k-header li {
+  background-color: #fafafa;
+  border-color: #fafafa;
+}
+.k-header,
+.k-grid-header-wrap,
+.k-grid .k-grouping-header,
+.k-grid-header,
+.k-pager-wrap,
+.k-pager-wrap .k-textbox,
+.k-pager-wrap .k-link,
+.k-gantt-toolbar .k-state-default,
+.k-grouping-row td,
+.k-group-footer td,
+.k-grid-footer td {
+  border-color: #e6e6e6;
+}
+.k-group-footer td,
+.k-footer-template td,
+.k-fieldselector .k-item.k-header {
+  color: #444444;
+  background-color: #f2f2f2;
+}
+.k-grid .k-grouping-header {
+  color: rgba(255, 255, 255, 0.5);
+}
+.k-pager-wrap,
+.k-editor-toolbar {
+  color: #444444;
+}
+.k-grouping-header .k-link,
+.k-grouping-header .k-link:link {
+  color: #ffffff;
+}
+.k-scheduler-layout .k-state-selected,
+.k-scheduler .k-today.k-state-selected,
+.k-grid tr.k-state-selected,
+.k-grid td.k-state-selected,
+.k-grid td.k-state-selected.k-state-focused,
+.k-marquee-color,
+.k-gantt .k-treelist .k-state-selected,
+.k-gantt .k-treelist .k-state-selected td,
+.k-gantt .k-treelist .k-alt.k-state-selected,
+.k-gantt .k-treelist .k-alt.k-state-selected > td,
+.k-listview > .k-state-selected,
+.k-state-selected.k-line {
+  background-color: #00b0ff;
+}
+.k-state-selected.k-line {
+  color: #00b0ff;
+}
+.k-grid tr.k-state-selected,
+.k-grid td.k-state-selected,
+.k-listview > .k-state-selected,
+.k-state-selected .k-progress-status {
+  color: #fff;
+}
+.k-grid tr:hover {
+  background-color: #ebebeb;
+}
+.k-grid .k-filter-row:hover,
+.k-pivot-rowheaders .k-grid tr:hover {
+  background: none;
+}
+.k-grid td.k-state-selected,
+.k-grid tr.k-state-selected > td {
+  border-color: #008dcc;
+}
+.k-grid td.k-state-selected:hover,
+.k-grid tr.k-state-selected:hover td {
+  background-color: #00a2eb;
+}
+.k-grid-header .k-header .k-link,
+.k-grid-header .k-header,
+.k-grid-header .k-link,
+.k-grid-header .k-link:link,
+.k-pager-info,
+.k-scheduler-header,
+.k-scheduler-agendaview .k-scheduler-datecolumn {
+  color: #a8a8a8;
+}
+.k-gantt .k-task-draghandle {
+  border-color: #00b0ff;
+}
+.k-grid-pager .k-link,
+.k-grid-pager .k-link:link {
+  color: #444444;
+}
+.k-pager-numbers .k-link,
+.k-pager-wrap > .k-link {
+  border-radius: 0;
+}
+.k-pager-numbers .k-state-selected {
+  border-color: #3f51b5 transparent transparent;
+  border-radius: 0;
+  box-shadow: none;
+  color: #3f51b5;
+}
+.k-pager-wrap .k-link {
+  border-color: #fafafa;
+  cursor: pointer;
+}
+.k-pager-wrap .k-link:hover {
+  background-color: transparent;
+  border-color: transparent;
+}
+.k-scheduler-toolbar > ul li:first-child,
+.k-scheduler-toolbar > ul li:first-child .k-link,
+.k-scheduler-toolbar .k-nav-next,
+.k-scheduler-toolbar ul + ul li:last-child,
+.k-scheduler-toolbar .k-nav-next .k-link,
+.k-scheduler-toolbar ul + ul li:last-child .k-link,
+.k-gantt-toolbar li:first-child,
+.k-gantt-toolbar li:first-child > .k-link,
+.k-gantt-toolbar li:last-child,
+.k-gantt-toolbar li:last-child > .k-link {
+  border-radius: 0;
+}
+.k-grid,
+.k-panelbar,
+.k-notification,
+.k-popup .k-textbox:focus,
+.k-popup .k-autocomplete.k-state-focused,
+.k-popup .k-picker-wrap.k-state-focused,
+.k-popup .k-numeric-wrap.k-state-focused,
+.k-popup .k-dropdown-wrap.k-state-focused,
+.k-popup .k-multiselect.k-header.k-state-focused,
+.k-popup .k-textbox:hover,
+.k-popup .k-autocomplete.k-state-hover,
+.k-popup .k-picker-wrap.k-state-hover,
+.k-popup .k-numeric-wrap.k-state-hover,
+.k-popup .k-dropdown-wrap.k-state-hover {
+  box-shadow: none;
+}
+/* PanelBar */
+.k-panelbar,
+.k-panelbar .k-header,
+.k-panelbar .k-content,
+.k-panel > li.k-item,
+.k-panelbar .k-state-selected {
+  background-color: #fafafa;
+}
+.k-panelbar .k-grid-toolbar {
+  background-color: #3f51b5;
+}
+.k-panelbar > li.k-state-default > .k-link {
+  color: #444444;
+}
+.k-panelbar > li > .k-state-hover {
+  background-color: #ebebeb;
+}
+.k-panelbar > .k-item > .k-link,
+.k-panelbar.k-header,
+.k-panelbar .k-content,
+.k-panelbar .k-panel,
+.k-panelbar .k-item {
+  border-color: #e6e6e6;
+}
+/* Splitter */
+.k-splitbar {
+  border-color: #fafafa;
+}
+.k-splitbar.k-state-focused {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+  box-shadow: none;
+}
+/* Upload */
+.k-upload {
+  color: #444444;
+  background-color: #fff;
+}
+.k-upload-files .k-button {
+  box-shadow: none;
+}
+/* Gantt */
+.k-task-milestone,
+.k-task-summary-complete,
+.k-state-selected.k-task-milestone,
+.k-state-selected .k-task-summary-complete {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+}
+.k-task-single {
+  background-color: #66d0ff;
+}
+.k-task-complete {
+  background: #00b0ff 0 -257px none repeat-x;
+}
+.k-treelist .k-state-selected,
+.k-treelist .k-state-selected td,
+.k-treelist .k-alt.k-state-selected,
+.k-treelist .k-alt.k-state-selected > td {
+  background-color: #00b0ff;
+  border-color: #00b0ff;
+}
+.k-multiselect .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-toolbar .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-group-indicator .k-button,
+.k-group-indicator .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-group-indicator .k-button:focus:not(.k-state-disabled):not([disabled]),
+.k-gantt-toolbar .k-button:focus:not(.k-state-disabled):not([disabled]),
+.k-gantt-toolbar .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-toolbar .k-button:focus:not(.k-state-disabled):not([disabled]),
+.k-toolbar .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-toolbar .k-button:active:hover,
+.k-toolbar .k-button.k-state-active:hover {
+  box-shadow: none;
+}
+.k-multiselect .k-button:active:hover {
+  color: #444444;
+  background-color: #dbdbdb;
+  border-color: #dbdbdb;
+}
+.k-multiselect-wrap > ul > .k-button {
+  box-shadow: none;
+}
+/* Editor */
+table.k-editor {
+  border-color: #e6e6e6;
+}
+.k-editor.k-header,
+.editorToolbarWindow.k-header,
+.k-filebrowser .k-header {
+  background-color: #f2f2f2;
+  box-shadow: none;
+}
+.k-filebrowser .k-header {
+  color: #444444;
+}
+.k-editor-toolbar .k-tool,
+.k-group-start.k-group-end.k-tool {
+  border-color: #f2f2f2;
+}
+.k-treeview .k-state-selected,
+.k-treeview .k-state-focused,
+.k-editor-toolbar .k-dropdown,
+.k-panelbar > li > .k-state-focused {
+  box-shadow: none;
+}
+.k-treeview .k-state-focused,
+.k-panelbar > li > .k-state-focused {
+  background-color: #ebebeb;
+}
+.k-editor-toolbar .k-dropdown-wrap.k-state-default,
+.k-toolbar .k-dropdown-wrap.k-state-default {
+  border-color: #f2f2f2;
+}
+.k-editor-toolbar .k-tool.k-state-hover,
+.k-editor-toolbar .k-dropdown-wrap.k-state-hover,
+.k-toolbar .k-tool.k-state-hover,
+.k-toolbar .k-dropdown-wrap.k-state-hover {
+  color: #444444;
+  border-color: #ebebeb;
+  box-shadow: none;
+}
+.k-editor-toolbar .k-tool.k-state-selected,
+.k-toolbar .k-button-group .k-button.k-state-active {
+  box-shadow: none;
+  background-color: #dbdbdb;
+  border-color: #dbdbdb;
+}
+.k-editor-toolbar .k-tool.k-state-hover,
+.k-toolbar .k-button-group .k-button:hover {
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+/* Progressbar */
+.k-progressbar {
+  background-color: #fafafa;
+  border-color: #fafafa;
+}
+.k-progressbar .k-item,
+.k-progressbar .k-item.k-state-selected {
+  border-color: #fff;
+}
+.k-progressbar .k-state-selected {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+}
+.k-widget.k-tooltip-validation {
+  box-shadow: none;
+}
+/* Pivot Grid */
+.k-grid.k-alt {
+  background-color: #fafafa;
+}
+.k-gantt .k-treelist .k-alt,
+.k-gantt .k-header.k-nonwork-hour {
+  background-color: #f2f2f2;
+}
+.k-list > .k-state-hover,
+.k-list > .k-state-focused {
+  color: #444444;
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+/* Slider */
+.k-slider-track {
+  background-color: #cccccc;
+  box-shadow: none;
+}
+.k-slider-selection {
+  background-color: #3f51b5;
+  border-color: #3f51b5;
+}
+.k-slider .k-button,
+.k-slider .k-button.k-state-hover,
+.k-slider .k-button:active:hover,
+.k-slider .k-button:focus,
+.k-slider .k-button:active {
+  background: none;
+  border: none;
+  box-shadow: none;
+}
+.k-draghandle,
+.k-flatcolorpicker .k-slider-horizontal .k-slider-track {
+  box-shadow: none;
+}
+.k-flatcolorpicker .k-hue-slider .k-draghandle,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle {
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+  box-shadow: none;
+}
+.k-flatcolorpicker .k-hue-slider .k-draghandle:hover,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle:hover {
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+  box-shadow: 0 0 0 8px rgba(63, 81, 181, 0.3);
+}
+.k-draghandle.k-state-selected,
+.k-draghandle.k-state-selected:link,
+.k-draghandle.k-state-selected:hover,
+.k-flatcolorpicker .k-hue-slider .k-draghandle.k-state-selected,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle.k-state-selected {
+  background-color: #cccccc;
+  border-color: #cccccc;
+}
+.k-draghandle.k-state-focused,
+.k-draghandle.k-state-focused:link,
+.k-flatcolorpicker .k-hue-slider .k-draghandle.k-state-focused,
+.k-flatcolorpicker .k-transparency-slider .k-draghandle.k-state-focused {
+  box-shadow: none;
+  border-color: #3f51b5;
+  background-color: #3f51b5;
+}
+.k-edit-form-container .k-edit-buttons {
+  background-color: #fafafa;
+}
+.k-popup .k-button,
+.k-popup .k-button:active:hover {
+  box-shadow: none;
+}
+.k-edit-form-container .k-button,
+.k-popup .k-button,
+.k-popup .k-primary:active,
+.k-popup .k-primary:active:hover,
+.k-edit-form-container .k-primary:active {
+  color: #444444;
+  background-color: #fafafa;
+  border-color: #fafafa;
+  box-shadow: none;
+}
+.k-popup .k-primary,
+.k-edit-form-container .k-primary {
+  color: #00b0ff;
+  background-color: #fafafa;
+  border-color: #fafafa;
+}
+.k-split-wrapper .k-button,
+.k-overflow-container .k-button,
+.k-filter-menu .k-button {
+  background: transparent;
+  border-color: transparent;
+}
+.k-split-wrapper .k-button,
+.k-overflow-container .k-button {
+  text-transform: none;
+}
+.k-split-wrapper .k-button:hover,
+.k-overflow-container .k-button:hover {
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+}
+.k-split-wrapper .k-button:focus,
+.k-overflow-container .k-button:focus,
+.k-split-wrapper .k-button:focus:not(.k-state-disabled):not([disabled]),
+.k-overflow-container .k-button:focus:not(.k-state-disabled):not([disabled]) {
+  color: #3f51b5;
+  box-shadow: none;
+}
+.k-filter-menu .k-button {
+  background: transparent;
+  border-color: transparent;
+}
+.k-filter-menu .k-primary {
+  border-left-color: #f0f0f0;
+}
+.k-filter-menu > div > div:last-child {
+  border-color: #f0f0f0;
+}
+.k-popup .k-button:focus:active:not(.k-state-disabled):not([disabled]),
+.k-edit-form-container .k-button:focus:active:not(.k-state-disabled):not([disabled]) {
+  box-shadow: none;
+}
+.k-edit-form-container .k-scheduler-delete {
+  color: #00b0ff;
+}
+div.k-scheduler-marquee:before,
+div.k-scheduler-marquee:after {
+  border-color: #00b0ff;
+}
+.km-pane-wrapper > .km-pane > .km-view > .km-content {
+  color: #3f51b5;
+  background-color: #ffffff;
+}
+.km-pane-wrapper > .km-pane .km-content .k-mobile-list > ul > li > .k-link {
+  color: #3f51b5;
+}
+.k-popup.k-context-menu {
+  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2);
+}
+.k-drag-clue {
+  color: #444444;
+  background-color: #ebebeb;
+  border-color: #ebebeb;
+  box-shadow: inset 0 0 0 1px #808080;
+}
+.k-popup > .k-group-header,
+.k-popup > .k-virtual-wrap > .k-group-header {
+  color: #444444;
+}
+.k-popup .k-item > .k-group {
+  color: #444444;
+}
+/* Responsive styles */
+@media only screen and (max-width: 370px) {
+  .k-webkit .k-pager-refresh,
+  .k-ff .k-pager-refresh,
+  .k-ie11 .k-pager-refresh,
+  .k-edge .k-pager-refresh,
+  .k-safari .k-pager-refresh {
+    display: none;
+  }
+}
+@media only screen and (max-width: 590px) {
+  .k-webkit .k-pager-refresh,
+  .k-ff .k-pager-refresh,
+  .k-ie11 .k-pager-refresh,
+  .k-edge .k-pager-refresh,
+  .k-safari .k-pager-refresh {
+    margin-right: 0;
+  }
+}
+@media only screen and (max-width: 530px) {
+  .k-webkit .k-pager-sizes,
+  .k-ff .k-pager-sizes,
+  .k-ie11 .k-pager-sizes,
+  .k-edge .k-pager-sizes,
+  .k-safari .k-pager-sizes {
+    display: none;
+  }
+}
+@media only screen and (max-width: 687px) {
+  .k-webkit .k-pager-info,
+  .k-ff .k-pager-info,
+  .k-ie11 .k-pager-info,
+  .k-edge .k-pager-info,
+  .k-safari .k-pager-info {
+    display: none;
+  }
+}
+@media only screen and (max-width: 1024px) {
+  .k-scheduler-toolbar > ul.k-scheduler-views {
+    right: 13px;
+    top: 0;
+  }
+  .k-webkit,
+  .k-ff,
+  .k-ie11,
+  .k-edge,
+  .k-safari {
+    /* Responsive Scheduler */
+    /* Responsive Pager */
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views {
+    right: 13px;
+    top: 0;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view,
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover {
+    background-image: none;
+    background-position: 50% 50%;
+    background-color: transparent;
+    border-color: transparent;
+    border-radius: 2px;
+    text-align: right;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li {
+    border-radius: 0;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li.k-current-view,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li.k-current-view,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li.k-current-view,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li.k-current-view,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded > li.k-current-view {
+    border-radius: 1px 1px 0 0;
+  }
+  .k-webkit .k-scheduler-toolbar > ul li:first-child,
+  .k-ff .k-scheduler-toolbar > ul li:first-child,
+  .k-ie11 .k-scheduler-toolbar > ul li:first-child,
+  .k-edge .k-scheduler-toolbar > ul li:first-child,
+  .k-safari .k-scheduler-toolbar > ul li:first-child,
+  .k-webkit .k-scheduler-toolbar > ul li:first-child .k-link,
+  .k-ff .k-scheduler-toolbar > ul li:first-child .k-link,
+  .k-ie11 .k-scheduler-toolbar > ul li:first-child .k-link,
+  .k-edge .k-scheduler-toolbar > ul li:first-child .k-link,
+  .k-safari .k-scheduler-toolbar > ul li:first-child .k-link,
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views li,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views li,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views li,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views li,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views li,
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views li .k-link,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views li .k-link,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views li .k-link,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views li .k-link,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views li .k-link {
+    border-radius: 0;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views li:last-child,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views li:last-child,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views li:last-child,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views li:last-child,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views li:last-child,
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views li:last-child .k-link,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views li:last-child .k-link,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views li:last-child .k-link,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views li:last-child .k-link,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views li:last-child .k-link {
+    border-radius: 0 0 1px 1px;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover {
+    border-color: transparent;
+    background-image: none;
+    background-color: transparent;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view > .k-link,
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover > .k-link,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover > .k-link,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover > .k-link,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover > .k-link,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views > li.k-current-view:hover > .k-link {
+    color: #ffffff;
+    min-width: 20px;
+  }
+  .k-webkit .k-scheduler-views > li.k-state-selected > .k-link:after,
+  .k-ff .k-scheduler-views > li.k-state-selected > .k-link:after,
+  .k-ie11 .k-scheduler-views > li.k-state-selected > .k-link:after,
+  .k-edge .k-scheduler-views > li.k-state-selected > .k-link:after,
+  .k-safari .k-scheduler-views > li.k-state-selected > .k-link:after {
+    display: block;
+    content: "";
+    position: absolute;
+    top: 50%;
+    margin-top: -0.5em;
+    right: 0.333em;
+    width: 1.333em;
+    height: 1.333em;
+  }
+  .k-webkit .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded,
+  .k-ff .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded,
+  .k-ie11 .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded,
+  .k-edge .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded,
+  .k-safari .k-scheduler-toolbar > ul.k-scheduler-views.k-state-expanded {
+    border-width: 1px;
+    border-style: solid;
+    border-color: transparent;
+    /*@secondary-border-color*/
+    background-image: none;
+    background-color: #3f51b5;
+    border-radius: 2px;
+    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2);
+  }
+  .k-webkit .k-pager-wrap,
+  .k-ff .k-pager-wrap,
+  .k-ie11 .k-pager-wrap,
+  .k-edge .k-pager-wrap,
+  .k-safari .k-pager-wrap {
+    min-height: 2.56em;
+  }
+  .k-webkit .k-pager-wrap .k-pager-nav,
+  .k-ff .k-pager-wrap .k-pager-nav,
+  .k-ie11 .k-pager-wrap .k-pager-nav,
+  .k-edge .k-pager-wrap .k-pager-nav,
+  .k-safari .k-pager-wrap .k-pager-nav,
+  .k-webkit .k-pager-input,
+  .k-ff .k-pager-input,
+  .k-ie11 .k-pager-input,
+  .k-edge .k-pager-input,
+  .k-safari .k-pager-input {
+    display: inline-block;
+    vertical-align: top;
+  }
+  .k-webkit .k-pager-numbers,
+  .k-ff .k-pager-numbers,
+  .k-ie11 .k-pager-numbers,
+  .k-edge .k-pager-numbers,
+  .k-safari .k-pager-numbers,
+  .k-webkit .k-grid .k-pager-numbers,
+  .k-ff .k-grid .k-pager-numbers,
+  .k-ie11 .k-grid .k-pager-numbers,
+  .k-edge .k-grid .k-pager-numbers,
+  .k-safari .k-grid .k-pager-numbers {
+    position: absolute;
+    left: 5.6em;
+    display: inline-flex;
+    flex-direction: column-reverse;
+    overflow: visible;
+    height: auto;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded,
+  .k-ff .k-pager-numbers.k-state-expanded,
+  .k-ie11 .k-pager-numbers.k-state-expanded,
+  .k-edge .k-pager-numbers.k-state-expanded,
+  .k-safari .k-pager-numbers.k-state-expanded,
+  .k-webkit .k-grid .k-pager-numbers.k-state-expanded,
+  .k-ff .k-grid .k-pager-numbers.k-state-expanded,
+  .k-ie11 .k-grid .k-pager-numbers.k-state-expanded,
+  .k-edge .k-grid .k-pager-numbers.k-state-expanded,
+  .k-safari .k-grid .k-pager-numbers.k-state-expanded {
+    transform: translatey(-100%);
+  }
+  .k-webkit .km-pane-wrapper .k-pager-numbers,
+  .k-ff .km-pane-wrapper .k-pager-numbers,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers,
+  .k-edge .km-pane-wrapper .k-pager-numbers,
+  .k-safari .km-pane-wrapper .k-pager-numbers,
+  .k-webkit .km-pane-wrapper .k-grid .k-pager-numbers,
+  .k-ff .km-pane-wrapper .k-grid .k-pager-numbers,
+  .k-ie11 .km-pane-wrapper .k-grid .k-pager-numbers,
+  .k-edge .km-pane-wrapper .k-grid .k-pager-numbers,
+  .k-safari .km-pane-wrapper .k-grid .k-pager-numbers {
+    position: relative;
+    left: 50%;
+    transform: translate(-50%, 0%);
+    -webkit-transform: translate(-50%, 0%);
+  }
+  .k-webkit .km-pane-wrapper .k-pager-numbers.k-state-expanded,
+  .k-ff .km-pane-wrapper .k-pager-numbers.k-state-expanded,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers.k-state-expanded,
+  .k-edge .km-pane-wrapper .k-pager-numbers.k-state-expanded,
+  .k-safari .km-pane-wrapper .k-pager-numbers.k-state-expanded,
+  .k-webkit .km-pane-wrapper .k-grid .k-pager-numbers.k-state-expanded,
+  .k-ff .km-pane-wrapper .k-grid .k-pager-numbers.k-state-expanded,
+  .k-ie11 .km-pane-wrapper .k-grid .k-pager-numbers.k-state-expanded,
+  .k-edge .km-pane-wrapper .k-grid .k-pager-numbers.k-state-expanded,
+  .k-safari .km-pane-wrapper .k-grid .k-pager-numbers.k-state-expanded {
+    -webkit-transform: translate(-50%, -100%);
+    transform: translate(-50%, -100%);
+  }
+  .k-webkit .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-ff .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-edge .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-safari .km-pane-wrapper .k-pager-numbers .k-link,
+  .k-webkit .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-ff .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-ie11 .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-edge .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-safari .km-pane-wrapper .k-pager-numbers .k-state-selected,
+  .k-webkit .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-ff .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-ie11 .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-edge .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-safari .km-pane-wrapper .k-pager-wrap > .k-link,
+  .k-webkit .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-ff .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-ie11 .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-edge .km-pane-wrapper .k-pager-wrap > .k-pager-info,
+  .k-safari .km-pane-wrapper .k-pager-wrap > .k-pager-info {
+    padding-top: 0;
+    padding-bottom: 0;
+  }
+  .k-webkit .k-rtl .k-pager-numbers,
+  .k-ff .k-rtl .k-pager-numbers,
+  .k-ie11 .k-rtl .k-pager-numbers,
+  .k-edge .k-rtl .k-pager-numbers,
+  .k-safari .k-rtl .k-pager-numbers,
+  .k-webkit .k-rtl .k-grid .k-pager-numbers,
+  .k-ff .k-rtl .k-grid .k-pager-numbers,
+  .k-ie11 .k-rtl .k-grid .k-pager-numbers,
+  .k-edge .k-rtl .k-grid .k-pager-numbers,
+  .k-safari .k-rtl .k-grid .k-pager-numbers {
+    right: 5.6em;
+    width: 5.15em;
+  }
+  .k-webkit .k-pager-numbers .k-current-page,
+  .k-ff .k-pager-numbers .k-current-page,
+  .k-ie11 .k-pager-numbers .k-current-page,
+  .k-edge .k-pager-numbers .k-current-page,
+  .k-safari .k-pager-numbers .k-current-page,
+  .k-webkit .k-grid .k-pager-numbers .k-current-page,
+  .k-ff .k-grid .k-pager-numbers .k-current-page,
+  .k-ie11 .k-grid .k-pager-numbers .k-current-page,
+  .k-edge .k-grid .k-pager-numbers .k-current-page,
+  .k-safari .k-grid .k-pager-numbers .k-current-page {
+    display: block;
+    border-left: 0;
+  }
+  .k-webkit .k-pager-numbers li:not(.k-current-page),
+  .k-ff .k-pager-numbers li:not(.k-current-page),
+  .k-ie11 .k-pager-numbers li:not(.k-current-page),
+  .k-edge .k-pager-numbers li:not(.k-current-page),
+  .k-safari .k-pager-numbers li:not(.k-current-page) {
+    display: none;
+  }
+  .k-webkit .k-pager-numbers .k-current-page .k-link,
+  .k-ff .k-pager-numbers .k-current-page .k-link,
+  .k-ie11 .k-pager-numbers .k-current-page .k-link,
+  .k-edge .k-pager-numbers .k-current-page .k-link,
+  .k-safari .k-pager-numbers .k-current-page .k-link {
+    width: 3.8em;
+    line-height: 2.564em;
+    padding: 0 .429em 0 0.8em;
+    border-radius: 2px;
+    background-image: none;
+    background-position: 50% 50%;
+    background-color: #fafafa;
+    border: 1px solid transparent;
+    border-top: 0;
+    box-shadow: 0 2px 2px 0 #fafafa;
+  }
+  .k-webkit .k-pager-numbers .k-current-page:hover .k-link,
+  .k-ff .k-pager-numbers .k-current-page:hover .k-link,
+  .k-ie11 .k-pager-numbers .k-current-page:hover .k-link,
+  .k-edge .k-pager-numbers .k-current-page:hover .k-link,
+  .k-safari .k-pager-numbers .k-current-page:hover .k-link {
+    border-radius: 2px;
+    background-color: #fff;
+    border: 1px solid #ebebeb;
+    border-top: 0;
+    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+  }
+  .k-webkit .k-pager-numbers .k-current-page .k-link:after,
+  .k-ff .k-pager-numbers .k-current-page .k-link:after,
+  .k-ie11 .k-pager-numbers .k-current-page .k-link:after,
+  .k-edge .k-pager-numbers .k-current-page .k-link:after,
+  .k-safari .k-pager-numbers .k-current-page .k-link:after {
+    display: block;
+    content: "";
+    position: absolute;
+    top: 50%;
+    margin-top: -0.6em;
+    right: 0.6em;
+    width: 1.333em;
+    height: 1.333em;
+    background-position: 0 -30px;
+  }
+  .k-webkit .k-pager-numbers + .k-link,
+  .k-ff .k-pager-numbers + .k-link,
+  .k-ie11 .k-pager-numbers + .k-link,
+  .k-edge .k-pager-numbers + .k-link,
+  .k-safari .k-pager-numbers + .k-link {
+    margin-left: 5.4em;
+  }
+  .k-webkit .k-rtl .k-pager-numbers + .k-link,
+  .k-ff .k-rtl .k-pager-numbers + .k-link,
+  .k-ie11 .k-rtl .k-pager-numbers + .k-link,
+  .k-edge .k-rtl .k-pager-numbers + .k-link,
+  .k-safari .k-rtl .k-pager-numbers + .k-link {
+    margin-right: 5.4em;
+    margin-left: 0;
+  }
+  .k-webkit .k-pager-wrap .k-pager-numbers .k-state-selected,
+  .k-ff .k-pager-wrap .k-pager-numbers .k-state-selected,
+  .k-ie11 .k-pager-wrap .k-pager-numbers .k-state-selected,
+  .k-edge .k-pager-wrap .k-pager-numbers .k-state-selected,
+  .k-safari .k-pager-wrap .k-pager-numbers .k-state-selected,
+  .k-webkit .k-pager-wrap .k-pager-numbers .k-link,
+  .k-ff .k-pager-wrap .k-pager-numbers .k-link,
+  .k-ie11 .k-pager-wrap .k-pager-numbers .k-link,
+  .k-edge .k-pager-wrap .k-pager-numbers .k-link,
+  .k-safari .k-pager-wrap .k-pager-numbers .k-link {
+    display: block;
+    margin-top: 0;
+    margin-right: 0;
+    padding: 1px 5px 1px .8em;
+    text-align: left;
+    border-top: 0;
+    border-radius: 1px;
+  }
+  .k-webkit .k-pager-wrap .k-pager-numbers li:not(.k-current-page) .k-link:hover,
+  .k-ff .k-pager-wrap .k-pager-numbers li:not(.k-current-page) .k-link:hover,
+  .k-ie11 .k-pager-wrap .k-pager-numbers li:not(.k-current-page) .k-link:hover,
+  .k-edge .k-pager-wrap .k-pager-numbers li:not(.k-current-page) .k-link:hover,
+  .k-safari .k-pager-wrap .k-pager-numbers li:not(.k-current-page) .k-link:hover {
+    background-color: #ebebeb;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded,
+  .k-ff .k-pager-numbers.k-state-expanded,
+  .k-ie11 .k-pager-numbers.k-state-expanded,
+  .k-edge .k-pager-numbers.k-state-expanded,
+  .k-safari .k-pager-numbers.k-state-expanded {
+    box-sizing: border-box;
+    padding: 2px 0 0;
+    border-width: 1px 1px 0 1px;
+    border-style: solid;
+    border-color: #ebebeb;
+    /*@secondary-border-color*/
+    background-color: #fff;
+    border-radius: 2px 2px 0 0;
+    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2);
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ff .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-ie11 .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-edge .k-pager-numbers.k-state-expanded .k-current-page,
+  .k-safari .k-pager-numbers.k-state-expanded .k-current-page {
+    margin: -2.2em -1px 0;
+    padding: 0;
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-ff .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-ie11 .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-edge .k-pager-numbers.k-state-expanded .k-current-page .k-link,
+  .k-safari .k-pager-numbers.k-state-expanded .k-current-page .k-link {
+    border-radius: 0 0 2px 2px;
+    background-color: #fff;
+    border: 1px solid #ebebeb;
+    border-top: 0;
+    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2);
+  }
+  .k-webkit .k-pager-numbers.k-state-expanded li,
+  .k-ff .k-pager-numbers.k-state-expanded li,
+  .k-ie11 .k-pager-numbers.k-state-expanded li,
+  .k-edge .k-pager-numbers.k-state-expanded li,
+  .k-safari .k-pager-numbers.k-state-expanded li {
+    display: inline-block;
+  }
+  .k-webkit .k-gantt-toolbar > ul.k-gantt-views,
+  .k-ff .k-gantt-toolbar > ul.k-gantt-views,
+  .k-ie11 .k-gantt-toolbar > ul.k-gantt-views,
+  .k-edge .k-gantt-toolbar > ul.k-gantt-views,
+  .k-safari .k-gantt-toolbar > ul.k-gantt-views {
+    top: 0;
+  }
+}
+@media only screen and (max-width: 755px) {
+  .k-webkit .k-pager-info,
+  .k-ff .k-pager-info,
+  .k-ie11 .k-pager-info,
+  .k-edge .k-pager-info,
+  .k-safari .k-pager-info {
+    display: none;
+  }
+}
+@media only screen and (max-width: 572px) {
+  .k-webkit .k-pager-sizes,
+  .k-ff .k-pager-sizes,
+  .k-ie11 .k-pager-sizes,
+  .k-edge .k-pager-sizes,
+  .k-safari .k-pager-sizes {
+    display: none;
+  }
+}
+/* Default Theme */
+.k-chart .k-mask {
+  background-color: #fff;
+  filter: alpha(opacity=68);
+  opacity: 0.68;
+}
+.k-chart .k-selection {
+  border-color: #e5e5e5;
+}
+.k-chart .k-handle {
+  width: 15px;
+  height: 15px;
+  background-color: #3f51b5;
+  border-radius: 10px;
+}
+.k-chart .k-left-handle {
+  left: -8px;
+}
+.k-chart .k-right-handle {
+  right: -8px;
+}
+.k-chart .k-handle:hover {
+  background-color: #00b0ff;
+  border-color: #00b0ff;
+}
+.k-chart .k-navigator-hint .k-tooltip {
+  border: 3px solid #ffffff;
+  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.2);
+  background: #ffffff;
+  color: #242424;
+}
+.k-chart .k-navigator-hint .k-scroll {
+  background: #3f51b5;
+  height: 4px;
+}
+.k-chart-tooltip {
+  background-image: none;
+}
+/* Map */
+.k-map .k-marker {
+  background-image: url("Material/markers.png");
+}
+@media only screen and (-webkit-min-device-pixel-ratio: 1.2), only screen and (min-device-pixel-ratio: 1.2) {
+  .k-map .k-marker {
+    background-image: url("Material/markers_2x.png");
+  }
+}
+.k-map .k-attribution {
+  color: #666666;
+}
+.k-map .k-shadow {
+  background-color: #f9f9f9;
+  border-color: #f9f9f9;
+}
+.k-map .k-zoom-control {
+  border-color: #fff;
+  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
+  border-radius: 2px;
+}
+.k-map .k-map-controls .k-button {
+  box-shadow: none;
+}
+.k-map .k-map-controls .k-button:focus,
+.k-map .k-map-controls .k-button:active,
+.k-map .k-map-controls .k-button:focus:active {
+  background-color: #d6d6d6;
+  border-color: #d6d6d6;
+  box-shadow: none;
+}
+.k-buttons-horizontal .k-zoom-out {
+  border-radius: 0 2px 2px 0;
+}
+.k-buttons-horizontal :first-child {
+  border-radius: 2px 0 0 2px;
+}
+.k-rtl .k-buttons-horizontal .k-zoom-out {
+  border-radius: 2px 0 0 2px;
+}
+.k-rtl .k-buttons-horizontal :first-child {
+  border-radius: 0 2px 2px 0;
+}
+.k-spreadsheet-row-header,
+.k-spreadsheet-column-header {
+  background-color: #fff;
+}
+.k-spreadsheet-top-corner,
+.k-spreadsheet-row-header,
+.k-spreadsheet-column-header {
+  background-color: #fff;
+  background-image: none;
+  color: #000000;
+  border-color: #cccccc;
+}
+.k-spreadsheet-top-corner {
+  border-color: #cccccc;
+}
+.k-spreadsheet-top-corner:after {
+  border-color: transparent #cccccc #cccccc transparent;
+}
+.k-spreadsheet-pane {
+  border-color: #cccccc;
+}
+.k-spreadsheet-pane .k-spreadsheet-vaxis,
+.k-spreadsheet-pane .k-spreadsheet-haxis {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-pane .k-spreadsheet-column-header,
+.k-spreadsheet-pane .k-spreadsheet-row-header {
+  border-color: #cccccc;
+}
+.k-spreadsheet-pane .k-spreadsheet-merged-cell {
+  background-color: #fff;
+}
+.k-spreadsheet-pane .k-selection-partial,
+.k-spreadsheet-pane .k-selection-full {
+  border-color: rgba(0, 176, 255, 0.2);
+  background-color: rgba(0, 176, 255, 0.2);
+}
+.k-spreadsheet-pane .k-filter-range {
+  border-color: #00b0ff;
+}
+.k-spreadsheet-pane .k-spreadsheet-column-header .k-selection-partial,
+.k-spreadsheet-pane .k-spreadsheet-column-header .k-selection-full {
+  border-bottom-color: #00b0ff;
+}
+.k-spreadsheet-pane .k-spreadsheet-row-header .k-selection-partial,
+.k-spreadsheet-pane .k-spreadsheet-row-header .k-selection-full {
+  border-right-color: #00b0ff;
+}
+.k-auto-fill,
+.k-spreadsheet-selection {
+  border-color: #00b0ff;
+  box-shadow: inset 0 0 0 1px #fff, 0 0 0 1px #00b0ff;
+}
+.k-spreadsheet-selection {
+  background-color: rgba(0, 176, 255, 0.2);
+}
+.k-spreadsheet-active-cell {
+  border-color: #00b0ff !important;
+  background-color: #fff;
+}
+.k-spreadsheet-active-cell.k-single {
+  color: #444444;
+  background-color: #fff;
+}
+.k-spreadsheet .k-spreadsheet-action-bar {
+  background-color: #fff;
+  border-color: #e6e6e6;
+}
+.k-spreadsheet .k-spreadsheet-action-bar .k-spreadsheet-name-editor {
+  border-color: #cccccc;
+}
+.k-spreadsheet .k-spreadsheet-action-bar .k-spreadsheet-formula-bar::before {
+  border-color: #cccccc;
+}
+.k-spreadsheet .k-spreadsheet-formula-input {
+  background-color: #fff;
+  color: #444444;
+}
+.k-spreadsheet .k-resize-handle,
+.k-spreadsheet .k-resize-hint-handle,
+.k-spreadsheet .k-resize-hint-marker {
+  background-color: #00b0ff;
+}
+.k-spreadsheet .k-resize-hint-vertical .k-resize-hint-handle,
+.k-spreadsheet .k-resize-hint-vertical .k-resize-hint-marker {
+  background-color: #00b0ff;
+}
+.k-spreadsheet .k-single-selection::after {
+  background-color: #00b0ff;
+  border-color: #fff;
+}
+.k-spreadsheet .k-auto-fill-punch {
+  background-color: rgba(255, 255, 255, 0.5);
+}
+.k-spreadsheet .k-single-selection.k-dim-auto-fill-handle::after {
+  background-color: rgba(0, 176, 255, 0.5);
+}
+.k-spreadsheet-format-cells .k-spreadsheet-preview {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-filter {
+  border-radius: 2px;
+  background-color: #fff;
+  box-shadow: inset 0 0 0 1px #e6e6e6;
+}
+.k-spreadsheet-filter.k-state-active {
+  color: #3f51b5;
+  background-color: #00b0ff;
+}
+.k-spreadsheet-filter:hover {
+  color: #444444;
+  background: #ebebeb;
+  border-color: #d7d7d7;
+}
+.k-action-window .k-action-buttons {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-sample {
+  color: #919191;
+}
+.k-state-selected .k-spreadsheet-sample {
+  color: inherit;
+}
+.k-spreadsheet-window .k-list-wrapper,
+.k-spreadsheet-window .k-list {
+  border-color: #e6e6e6;
+  border-radius: 2px;
+}
+.k-spreadsheet-window .export-config,
+.k-spreadsheet-window .k-edit-field > .k-orientation-label {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-window .k-edit-field > input[type="radio"]:checked + .k-orientation-label {
+  background-image: none;
+  background-color: #3f51b5;
+  color: #6776ca;
+}
+.k-spreadsheet-window .k-page-orientation {
+  border-color: #e6e6e6;
+  box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.1);
+}
+.k-spreadsheet-window .k-page-orientation:before {
+  background: #fff;
+  border-color: transparent;
+  border-bottom-color: #e6e6e6;
+  border-left-color: #e6e6e6;
+}
+.k-spreadsheet-window .k-margins-horizontal,
+.k-spreadsheet-window .k-margins-vertical {
+  background: transparent;
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-window .hint-wrapper:before {
+  background: #e6e6e6;
+}
+.k-spreadsheet-toolbar.k-toolbar .k-button-group .k-button {
+  border-radius: 2px;
+}
+.k-spreadsheet-toolbar > .k-widget,
+.k-spreadsheet-toolbar > .k-button,
+.k-spreadsheet-toolbar > .k-button-group {
+  border-radius: 2px;
+}
+.k-spreadsheet-toolbar > .k-separator {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-toolbar .k-overflow-anchor {
+  border-radius: 0;
+}
+.k-spreadsheet-popup {
+  border-radius: 2px;
+}
+.k-spreadsheet-popup .k-separator {
+  background-color: #e6e6e6;
+}
+.k-spreadsheet-popup .k-button {
+  background-color: transparent;
+}
+.k-spreadsheet-popup .k-button:hover {
+  background-color: #ebebeb;
+}
+.k-spreadsheet-popup .k-state-active {
+  background-color: #00b0ff;
+  color: #ffffff;
+}
+.k-spreadsheet-popup .k-state-active:hover {
+  background-color: #008dcc;
+}
+.k-spreadsheet-filter-menu .k-details {
+  border-color: #e6e6e6;
+}
+.k-spreadsheet-filter-menu .k-details-content .k-space-right {
+  background-color: #fff;
+}
+.k-spreadsheet-filter-menu .k-spreadsheet-value-treeview-wrapper {
+  background-color: #fff;
+  border-color: #e6e6e6;
+  border-radius: 2px 0 0 2px;
+}
+.k-syntax-ref {
+  color: #ff8822;
+}
+.k-syntax-num {
+  color: #0099ff;
+}
+.k-syntax-func {
+  font-weight: bold;
+}
+.k-syntax-str {
+  color: #38b714;
+}
+.k-syntax-error {
+  color: red;
+}
+.k-syntax-bool {
+  color: #a9169c;
+}
+.k-syntax-startexp {
+  font-weight: bold;
+}
+.k-syntax-paren-match {
+  background-color: #caf200;
+}
+.k-series-a {
+  border-color: #3f51b5;
+  background-color: rgba(63, 81, 181, 0.15);
+}
+.k-series-b {
+  border-color: #03a9f4;
+  background-color: rgba(3, 169, 244, 0.15);
+}
+.k-series-c {
+  border-color: #4caf50;
+  background-color: rgba(76, 175, 80, 0.15);
+}
+.k-series-d {
+  border-color: #f9ce1d;
+  background-color: rgba(249, 206, 29, 0.15);
+}
+.k-series-e {
+  border-color: #ff9800;
+  background-color: rgba(255, 152, 0, 0.15);
+}
+.k-series-f {
+  border-color: #ff5722;
+  background-color: rgba(255, 87, 34, 0.15);
+}
+.k-spreadsheet-sheets-remove:hover .k-icon {
+  color: #cc2222;
+}
+.k-spreadsheet-formula-list .k-state-focused {
+  background-color: #00b0ff;
+  color: #3f51b5;
+}
+.k-spreadsheet .k-spreadsheet-quick-access-toolbar .k-button,
+.k-spreadsheet .k-spreadsheet-sheets-bar .k-button {
+  box-shadow: none;
+  color: #ffffff;
+  border-radius: 0;
+  line-height: 2.6em;
+  width: 3em;
+}
+.k-spreadsheet .k-spreadsheet-quick-access-toolbar .k-button:hover,
+.k-spreadsheet .k-spreadsheet-sheets-bar .k-button:hover {
+  background-color: #324191;
+  border-color: #324191;
+}
+.k-spreadsheet .k-spreadsheet-sheets-bar .k-button {
+  left: 0;
+  bottom: 0;
+  padding-top: .5em;
+  padding-bottom: .5em;
+  line-height: 2.2em;
+}
+.k-spreadsheet .k-spreadsheet-sheets-remove {
+  margin: 0 0 0 -1em;
+}
+.k-spreadsheet-sheets-items .k-state-default .k-link,
+.k-spreadsheet-tabstrip .k-state-default .k-link {
+  color: #9fa8da;
+}
+.k-spreadsheet-sheets-items .k-item.k-state-hover,
+.k-spreadsheet-tabstrip .k-item.k-state-hover,
+.k-spreadsheet-sheets-items .k-item.k-state-active,
+.k-spreadsheet-tabstrip .k-item.k-state-active,
+.k-spreadsheet-sheets-items .k-item.k-state-focused,
+.k-spreadsheet-tabstrip .k-item.k-state-focused {
+  background-color: transparent;
+}
+.k-spreadsheet-sheets-items .k-item.k-state-hover .k-link,
+.k-spreadsheet-tabstrip .k-item.k-state-hover .k-link,
+.k-spreadsheet-sheets-items .k-item.k-state-active .k-link,
+.k-spreadsheet-tabstrip .k-item.k-state-active .k-link,
+.k-spreadsheet-sheets-items .k-item.k-state-focused .k-link,
+.k-spreadsheet-tabstrip .k-item.k-state-focused .k-link {
+  color: #ffffff;
+}
+.k-spreadsheet-sheets-items .k-state-active .k-link,
+.k-spreadsheet-tabstrip .k-state-active .k-link {
+  color: #ffffff;
+}
+.k-spreadsheet-toolbar > .k-button:not(.k-overflow-anchor) {
+  line-height: 2em;
+}
+.k-grid .k-edit-cell input.k-checkbox,
+.k-grid .k-grid-edit-row input.k-checkbox {
+  margin-top: 5px;
+  width: 16px;
+  height: 16px;
+  z-index: 2;
+}
+.k-window .k-popup-edit-form .k-edit-field input.k-checkbox {
+  width: 16px;
+  height: 17px;
+  margin-top: 1.1em;
+  z-index: 2;
+}
+.k-window .k-popup-edit-form .k-edit-field label.k-checkbox-label {
+  margin-top: 0.8em;
+}
+/* Dialog */
+.k-dialog .k-content {
+  border-bottom-right-radius: 2px;
+  border-bottom-left-radius: 2px;
+}
+.k-dialog.k-dialog-titleless .k-content {
+  border-top-right-radius: 2px;
+  border-top-left-radius: 2px;
+}
+.k-dialog .k-window-titlebar {
+  border-width: 0;
+  color: #444444;
+}
+.k-dialog .k-header {
+  background: none;
+}
+.k-dialog.k-alert .k-window-titlebar,
+.k-dialog.k-confirm .k-window-titlebar,
+.k-dialog.k-prompt .k-window-titlebar {
+  border-bottom: none;
+}
+.k-dialog.k-alert .k-window-titlebar .k-dialog-title,
+.k-dialog.k-confirm .k-window-titlebar .k-dialog-title,
+.k-dialog.k-prompt .k-window-titlebar .k-dialog-title {
+  color: #444444;
+}
+.k-dialog a.k-dialog-action.k-dialog-close.k-button.k-bare:before {
+  content: normal;
+}
+.k-dialog a.k-dialog-action.k-dialog-close {
+  top: .3em;
+  right: 0;
+}
+.k-dialog .k-dialog-buttongroup .k-button:active,
+.k-dialog .k-dialog-buttongroup .k-button:focus,
+.k-dialog .k-dialog-buttongroup .k-button:focus:active {
+  box-shadow: none;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched {
+  width: 100%;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched .k-button {
+  display: inline-block;
+  padding: 1.5em 0;
+  border-radius: 0;
+  border-bottom: 0;
+  box-shadow: none;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched .k-button:first-child {
+  border-bottom-left-radius: 2px;
+  border-left: 0;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched .k-button:last-child {
+  border-bottom-right-radius: 2px;
+  border-right: 0;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal {
+  width: auto;
+  margin: 0;
+  padding: 1em;
+  text-align: right;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal .k-button {
+  margin-left: 0.5em;
+  background: none;
+  border: none;
+  border-radius: 0;
+  box-shadow: none;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal .k-button:first-child {
+  margin-left: 0;
+}
+.k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal .k-button.k-primary {
+  color: #00b0ff;
+}
+.k-rtl .k-grid-header .k-header:first-child,
+.k-rtl .k-filter-row th:first-child,
+.k-rtl .k-grid tbody td:first-child,
+.k-rtl .k-grid tfoot td:first-child {
+  border-left-width: 0;
+}
+.k-rtl .k-dialog a.k-dialog-action.k-dialog-close {
+  left: 0;
+}
+.k-rtl .k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched .k-button:first-child {
+  border-bottom-right-radius: 2px;
+}
+.k-rtl .k-dialog .k-dialog-buttongroup.k-dialog-button-layout-stretched .k-button:last-child {
+  border-bottom-left-radius: 2px;
+}
+.k-rtl .k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal {
+  text-align: left;
+}
+.k-rtl .k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal .k-button {
+  margin-left: 0;
+  margin-right: 0.5em;
+}
+.k-rtl .k-dialog .k-dialog-buttongroup.k-dialog-button-layout-normal .k-button:first-child {
+  margin-right: 0;
+}
+.k-numeric-wrap .k-i-warning {
+  color: #ff3448;
+  position: absolute;
+  top: 0;
+  right: 2.2em;
+  width: 2.2em;
+}
+.k-numeric-wrap.k-state-invalid {
+  border-color: #ff3448;
+}
+.k-numeric-wrap.k-state-invalid input {
+  color: #ff3448;
+}
+.k-maskedtextbox.k-state-invalid .k-textbox {
+  border-color: #ff3448;
+  color: #ff3448;
+}
+.k-maskedtextbox.k-state-invalid .k-i-warning {
+  color: #ff3448;
+}
+.k-dateinput.k-state-invalid .k-textbox {
+  color: #ff3448;
+  border-color: #ff3448;
+}
+.k-dateinput.k-state-invalid .k-i-warning {
+  margin-left: 0;
+  margin-right: 0.7em;
+  color: #ff3448;
+}
+.k-rtl .k-dateinput .k-i-warning {
+  margin-right: 0;
+  margin-left: 0.7em;
+}
+.k-datepicker .k-picker-wrap.k-state-invalid {
+  border-color: #ff3448;
+}
+.k-datepicker .k-picker-wrap.k-state-invalid .k-input {
+  color: #ff3448;
+}
+.k-datepicker .k-picker-wrap .k-i-warning {
+  color: #ff3448;
+  margin-left: 0;
+  margin-right: 2.8em;
+}
+.k-rtl .k-datepicker .k-picker-wrap .k-i-warning {
+  margin-right: 0;
+  margin-left: 2.8em;
+}
+.k-listbox .k-list-scroller {
+  border-color: #e6e6e6;
+  background-color: #fff;
+}
+.k-listbox .k-item:hover:not(.k-state-disabled),
+.k-listbox .k-item.k-state-selected {
+  background-color: #ebebeb;
+  border-color: transparent;
+}
+.k-listbox .k-button.k-state-disabled:hover .k-icon {
+  opacity: .7;
+}
+.k-listbox .k-button.k-state-disabled:hover .k-icon {
+  opacity: .7;
+}
+.k-listbox .k-drop-hint {
+  height: 0;
+  border-top: 1px solid #3f51b5;
+}
+.k-item.k-state-selected.k-drag-clue {
+  border-color: transparent;
+  background-color: #ebebeb;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2), 0 2px 3px rgba(0, 0, 0, 0.05);
+}
+.k-grid-header .k-i-sort-asc-sm,
+.k-grid-header .k-i-sort-desc-sm,
+.k-grid-header .k-sort-order {
+  color: inherit;
+  opacity: 1;
+}
+.k-grid-header .k-sort-order {
+  font-size: .7em;
+  vertical-align: text-top;
+  line-height: 1.5em;
+}
+.k-menu-scroll-button {
+  border-width: 0;
+  box-shadow: none;
+  border-color: #e6e6e6;
+  color: #444444;
+  background-color: #fff;
+}
+.k-menu-scroll-wrapper.horizontal .k-scroll-left {
+  border-right-width: 1px;
+}
+.k-menu-scroll-wrapper.horizontal .k-scroll-right {
+  border-left-width: 1px;
+}
+.k-menu-scroll-wrapper.vertical .k-scroll-up {
+  border-bottom-width: 1px;
+}
+.k-menu-scroll-wrapper.vertical .k-scroll-down {
+  border-top-width: 1px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/loading-bar.css b/src/main/resources/META-INF/resources/designer/css/loading-bar.css
new file mode 100644 (file)
index 0000000..98943fc
--- /dev/null
@@ -0,0 +1,103 @@
+/* Make clicks pass-through */
+#loading-bar,
+#loading-bar-spinner {
+  pointer-events: none;
+  -webkit-pointer-events: none;
+  -webkit-transition: 350ms linear all;
+  -moz-transition: 350ms linear all;
+  -o-transition: 350ms linear all;
+  transition: 350ms linear all;
+}
+
+#loading-bar.ng-enter,
+#loading-bar.ng-leave.ng-leave-active,
+#loading-bar-spinner.ng-enter,
+#loading-bar-spinner.ng-leave.ng-leave-active {
+  opacity: 0;
+}
+
+#loading-bar.ng-enter.ng-enter-active,
+#loading-bar.ng-leave,
+#loading-bar-spinner.ng-enter.ng-enter-active,
+#loading-bar-spinner.ng-leave {
+  opacity: 1;
+}
+
+#loading-bar .bar {
+  -webkit-transition: width 350ms;
+  -moz-transition: width 350ms;
+  -o-transition: width 350ms;
+  transition: width 350ms;
+
+  background: #29d;
+  position: fixed;
+  z-index: 10002;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 2px;
+  border-bottom-right-radius: 1px;
+  border-top-right-radius: 1px;
+}
+
+/* Fancy blur effect */
+#loading-bar .peg {
+  position: absolute;
+  width: 70px;
+  right: 0;
+  top: 0;
+  height: 2px;
+  opacity: .45;
+  -moz-box-shadow: #29d 1px 0 6px 1px;
+  -ms-box-shadow: #29d 1px 0 6px 1px;
+  -webkit-box-shadow: #29d 1px 0 6px 1px;
+  box-shadow: #29d 1px 0 6px 1px;
+  -moz-border-radius: 100%;
+  -webkit-border-radius: 100%;
+  border-radius: 100%;
+}
+
+#loading-bar-spinner {
+  display: block;
+  position: fixed;
+  z-index: 10002;
+  top: 10px;
+  left: 10px;
+}
+
+#loading-bar-spinner .spinner-icon {
+  width: 14px;
+  height: 14px;
+
+  border:  solid 2px transparent;
+  border-top-color:  #29d;
+  border-left-color: #29d;
+  border-radius: 10px;
+
+  -webkit-animation: loading-bar-spinner 400ms linear infinite;
+  -moz-animation:    loading-bar-spinner 400ms linear infinite;
+  -ms-animation:     loading-bar-spinner 400ms linear infinite;
+  -o-animation:      loading-bar-spinner 400ms linear infinite;
+  animation:         loading-bar-spinner 400ms linear infinite;
+}
+
+@-webkit-keyframes loading-bar-spinner {
+  0%   { -webkit-transform: rotate(0deg);   transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@-moz-keyframes loading-bar-spinner {
+  0%   { -moz-transform: rotate(0deg);   transform: rotate(0deg); }
+  100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@-o-keyframes loading-bar-spinner {
+  0%   { -o-transform: rotate(0deg);   transform: rotate(0deg); }
+  100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@-ms-keyframes loading-bar-spinner {
+  0%   { -ms-transform: rotate(0deg);   transform: rotate(0deg); }
+  100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@keyframes loading-bar-spinner {
+  0%   { transform: rotate(0deg);   transform: rotate(0deg); }
+  100% { transform: rotate(360deg); transform: rotate(360deg); }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/metisMenu.min.css b/src/main/resources/META-INF/resources/designer/css/metisMenu.min.css
new file mode 100644 (file)
index 0000000..df919cf
--- /dev/null
@@ -0,0 +1 @@
+.arrow{float:right}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"}
diff --git a/src/main/resources/META-INF/resources/designer/css/multi-select.css b/src/main/resources/META-INF/resources/designer/css/multi-select.css
new file mode 100644 (file)
index 0000000..b9f9aa5
--- /dev/null
@@ -0,0 +1,61 @@
+.multiselect-container.dropdown-menu{
+    width: 100%
+}
+span.multiselect-native-select{position:relative}
+span.multiselect-native-select select{border:0!important;
+    clip:rect(0 0 0 0)!important;
+    height:1px!important;
+    margin:-1px -1px -1px -3px!important;
+    overflow:hidden!important;
+    padding:0!important;
+    position:absolute!important;
+    width:1px!important;left:50%;
+    top:30px}
+.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}
+.multiselect-container .input-group{margin:5px}
+.multiselect-container>li{padding:0;min-height: 26px;}
+.multiselect-container>li>a.multiselect-all label{font-weight:700}
+.multiselect-container>li.multiselect-group label{margin:0;
+    padding:3px 20px 3px 20px;height:100%;font-weight:700}
+.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}
+.multiselect-container>li>a{padding:0}
+.multiselect-container>li>a>label{margin:0;
+    height:100%;
+    cursor:pointer;
+    font-weight:400;
+    padding:3px 20px 3px 40px}
+span.multiselect-selected-text {
+    text-align: left;
+    float: left;
+}
+
+.multiselect-container>li>a>label.radio,
+.multiselect-container>li>a>label.checkbox{margin:0;
+text-align: left;}
+.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}
+.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;
+    border-bottom-left-radius:4px}
+.form-inline .multiselect-container label.checkbox,
+.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}
+.form-inline .multiselect-container li a label.checkbox input[type=checkbox],
+.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;
+    margin-right:0}
+button.multiselect.dropdown-toggle.btn.btn-default {
+    width: 100%;
+}
+
+.multiselect-native-select .btn-group {
+    width: 100%;
+    text-align: left !important;
+}
+
+span.multiselect-native-select span not(.input-group-addon) {
+    text-align: left!important;
+    width: 86%;
+    display: block;
+}
+
+button.multiselect.dropdown-toggle.btn.btn-default .caret {
+    float: right;
+    margin-top: 8px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/navmenu.css b/src/main/resources/META-INF/resources/designer/css/navmenu.css
new file mode 100644 (file)
index 0000000..5daf656
--- /dev/null
@@ -0,0 +1,54 @@
+html, body
+{
+  height: 100%;
+}
+
+body 
+{
+  padding: 50px 0 0 0;
+}
+
+.navmenu {
+  padding-top: 50px;
+}
+
+.navbar {
+  display: block;
+  text-align: center;
+}
+.navbar-brand {
+  display: inline-block;
+  float: none;
+}
+.navbar-toggle {
+  position: absolute;
+  float: left;
+  margin-left: 15px;
+}
+
+.container {
+  max-width: 100%;
+}
+
+@media (min-width: 1px) {
+  .navbar-toggle {
+    display: block !important;
+  }
+}
+
+@media (min-width: 992px)
+{
+  body 
+  {
+    padding: 0 0 0 0px;
+  }
+  .navmenu {
+    padding-top: 0;
+  }
+  /*
+  .navbar 
+  {
+    display: none !important; /* IE8 fix */
+  }
+  */
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/normalize.css b/src/main/resources/META-INF/resources/designer/css/normalize.css
new file mode 100644 (file)
index 0000000..57b5d26
--- /dev/null
@@ -0,0 +1,375 @@
+/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
+
+/* ==========================================================================
+   HTML5 display definitions
+   ========================================================================== */
+
+/*
+ * Corrects `block` display not defined in IE 8/9.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section,
+summary {
+    display: block;
+}
+
+/*
+ * Corrects `inline-block` display not defined in IE 8/9.
+ */
+
+audio,
+canvas,
+video {
+    display: inline-block;
+}
+
+/*
+ * Prevents modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+    display: none;
+    height: 0;
+}
+
+/*
+ * Addresses styling for `hidden` attribute not present in IE 8/9.
+ */
+
+[hidden] {
+    display: none;
+}
+
+/* ==========================================================================
+   Base
+   ========================================================================== */
+
+/*
+ * 1. Sets default font family to sans-serif.
+ * 2. Prevents iOS text size adjust after orientation change, without disabling
+ *    user zoom.
+ */
+
+html {
+    font-family: sans-serif; /* 1 */
+    -webkit-text-size-adjust: 100%; /* 2 */
+    -ms-text-size-adjust: 100%; /* 2 */
+}
+
+/*
+ * Removes default margin.
+ */
+
+body {
+    margin: 0;
+}
+
+/* ==========================================================================
+   Links
+   ========================================================================== */
+
+/*
+ * Addresses `outline` inconsistency between Chrome and other browsers.
+ */
+
+a:focus {
+    outline: thin dotted;
+}
+
+/*
+ * Improves readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+    outline: 0;
+}
+
+/* ==========================================================================
+   Typography
+   ========================================================================== */
+
+/*
+ * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
+ * Safari 5, and Chrome.
+ */
+
+h1 {
+    font-size: 2em;
+}
+
+/*
+ * Addresses styling not present in IE 8/9, Safari 5, and Chrome.
+ */
+
+abbr[title] {
+    border-bottom: 1px dotted;
+}
+
+/*
+ * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
+ */
+
+b,
+strong {
+    font-weight: bold;
+}
+
+/*
+ * Addresses styling not present in Safari 5 and Chrome.
+ */
+
+dfn {
+    font-style: italic;
+}
+
+/*
+ * Addresses styling not present in IE 8/9.
+ */
+
+mark {
+    background: #ff0;
+    color: #000;
+}
+
+
+/*
+ * Corrects font family set oddly in Safari 5 and Chrome.
+ */
+
+code,
+kbd,
+pre,
+samp {
+    font-family: monospace, serif;
+    font-size: 1em;
+}
+
+/*
+ * Improves readability of pre-formatted text in all browsers.
+ */
+
+pre {
+    white-space: pre;
+    white-space: pre-wrap;
+    word-wrap: break-word;
+}
+
+/*
+ * Sets consistent quote types.
+ */
+
+q {
+    quotes: "\201C" "\201D" "\2018" "\2019";
+}
+
+/*
+ * Addresses inconsistent and variable font size in all browsers.
+ */
+
+small {
+    font-size: 80%;
+}
+
+/*
+ * Prevents `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+    font-size: 75%;
+    line-height: 0;
+    position: relative;
+    vertical-align: baseline;
+}
+
+sup {
+    top: -0.5em;
+}
+
+sub {
+    bottom: -0.25em;
+}
+
+/* ==========================================================================
+   Embedded content
+   ========================================================================== */
+
+/*
+ * Removes border when inside `a` element in IE 8/9.
+ */
+
+img {
+    border: 0;
+}
+
+/*
+ * Corrects overflow displayed oddly in IE 9.
+ */
+
+svg:not(:root) {
+    overflow: hidden;
+}
+
+/* ==========================================================================
+   Figures
+   ========================================================================== */
+
+/*
+ * Addresses margin not present in IE 8/9 and Safari 5.
+ */
+
+figure {
+    margin: 0;
+}
+
+/* ==========================================================================
+   Forms
+   ========================================================================== */
+
+/*
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+    border: 1px solid #c0c0c0;
+    margin: 0 2px;
+    padding: 0.35em 0.625em 0.75em;
+}
+
+/*
+ * 1. Corrects color not being inherited in IE 8/9.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+
+legend {
+    border: 0; /* 1 */
+    padding: 0; /* 2 */
+}
+
+/*
+ * 1. Corrects font family not being inherited in all browsers.
+ * 2. Corrects font size not being inherited in all browsers.
+ * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
+ */
+
+button,
+input,
+select,
+textarea {
+    font-family: inherit; /* 1 */
+    font-size: 100%; /* 2 */
+    margin: 0; /* 3 */
+}
+
+/*
+ * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+button,
+input {
+    line-height: normal;
+}
+
+/*
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ *    and `video` controls.
+ * 2. Corrects inability to style clickable `input` types in iOS.
+ * 3. Improves usability and consistency of cursor style between image-type
+ *    `input` and others.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+    -webkit-appearance: button; /* 2 */
+    cursor: pointer; /* 3 */
+}
+
+/*
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+input[disabled] {
+    cursor: default;
+}
+
+/*
+ * 1. Addresses box sizing set to `content-box` in IE 8/9.
+ * 2. Removes excess padding in IE 8/9.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+    box-sizing: border-box; /* 1 */
+    padding: 0; /* 2 */
+}
+
+/*
+ * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
+ * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
+ *    (include `-moz` to future-proof).
+ */
+
+input[type="search"] {
+    -webkit-appearance: textfield; /* 1 */
+    -moz-box-sizing: content-box;
+    -webkit-box-sizing: content-box; /* 2 */
+    box-sizing: content-box;
+}
+
+/*
+ * Removes inner padding and search cancel button in Safari 5 and Chrome
+ * on OS X.
+ */
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+    -webkit-appearance: none;
+}
+
+/*
+ * Removes inner padding and border in Firefox 4+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+    border: 0;
+    padding: 0;
+}
+
+/*
+ * 1. Removes default vertical scrollbar in IE 8/9.
+ * 2. Improves readability and alignment in all browsers.
+ */
+
+textarea {
+    overflow: auto; /* 1 */
+    vertical-align: top; /* 2 */
+}
+
+/* ==========================================================================
+   Tables
+   ========================================================================== */
+
+/*
+ * Remove most spacing between table cells.
+ */
+
+table {
+    border-collapse: collapse;
+    border-spacing: 0;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/dataTables.bootstrap.css b/src/main/resources/META-INF/resources/designer/css/plugins/dataTables.bootstrap.css
new file mode 100644 (file)
index 0000000..c07dac9
--- /dev/null
@@ -0,0 +1,233 @@
+div.dataTables_length label {
+    float: left;
+    text-align: left;
+    font-weight: normal;
+}
+
+div.dataTables_length select {
+    width: 75px;
+}
+
+div.dataTables_filter label {
+    float: right;
+    font-weight: normal;
+}
+
+div.dataTables_filter input {
+    width: 16em;
+}
+
+div.dataTables_info {
+    padding-top: 8px;
+}
+
+div.dataTables_paginate {
+    float: right;
+    margin: 0;
+}
+
+div.dataTables_paginate ul.pagination {
+    margin: 2px 0;
+    white-space: nowrap;
+}
+
+table.dataTable,
+table.dataTable td,
+table.dataTable th {
+    -webkit-box-sizing: content-box;
+    -moz-box-sizing: content-box;
+    box-sizing: content-box;
+}
+
+table.dataTable {
+    clear: both;
+    margin-top: 6px !important;
+    margin-bottom: 6px !important;
+    max-width: none !important;
+}
+
+table.dataTable thead .sorting,
+table.dataTable thead .sorting_asc,
+table.dataTable thead .sorting_desc,
+table.dataTable thead .sorting_asc_disabled,
+table.dataTable thead .sorting_desc_disabled {
+    cursor: pointer;
+}
+
+table.dataTable thead .sorting {
+    background: url('../images/sort_both.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_asc {
+    background: url('../images/sort_asc.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_desc {
+    background: url('../images/sort_desc.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_asc_disabled {
+    background: url('../images/sort_asc_disabled.png') no-repeat center right;
+}
+
+table.dataTable thead .sorting_desc_disabled {
+    background: url('../images/sort_desc_disabled.png') no-repeat center right;
+}
+
+table.dataTable th:active {
+    outline: none;
+}
+
+/* Scrolling */
+
+div.dataTables_scrollHead table {
+    margin-bottom: 0 !important;
+    border-bottom-left-radius: 0;
+    border-bottom-right-radius: 0;
+}
+
+div.dataTables_scrollHead table thead tr:last-child th:first-child,
+div.dataTables_scrollHead table thead tr:last-child td:first-child {
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.dataTables_scrollBody table {
+    margin-top: 0 !important;
+    margin-bottom: 0 !important;
+    border-top: none;
+}
+
+div.dataTables_scrollBody tbody tr:first-child th,
+div.dataTables_scrollBody tbody tr:first-child td {
+    border-top: none;
+}
+
+div.dataTables_scrollFoot table {
+    margin-top: 0 !important;
+    border-top: none;
+}
+
+/*
+ * TableTools styles
+ */
+
+.table tbody tr.active td,
+.table tbody tr.active th {
+    color: white;
+    background-color: #08C;
+}
+
+.table tbody tr.active:hover td,
+.table tbody tr.active:hover th {
+    background-color: #0075b0 !important;
+}
+
+.table tbody tr.active a {
+    color: white;
+}
+
+.table-striped tbody tr.active:nth-child(odd) td,
+.table-striped tbody tr.active:nth-child(odd) th {
+    background-color: #017ebc;
+}
+
+table.DTTT_selectable tbody tr {
+    cursor: pointer;
+}
+
+div.DTTT .btn {
+    font-size: 12px;
+    color: #333 !important;
+}
+
+div.DTTT .btn:hover {
+    text-decoration: none !important;
+}
+
+ul.DTTT_dropdown.dropdown-menu {
+    z-index: 2003;
+}
+
+ul.DTTT_dropdown.dropdown-menu a {
+    color: #333 !important; /* needed only when demo_page.css is included */
+}
+
+ul.DTTT_dropdown.dropdown-menu li {
+    position: relative;
+}
+
+ul.DTTT_dropdown.dropdown-menu li:hover a {
+    color: white !important;
+    background-color: #0088cc;
+}
+
+div.DTTT_collection_background {
+    z-index: 2002;
+}
+
+/* TableTools information display */
+
+div.DTTT_print_info.modal {
+    height: 150px;
+    margin-top: -75px;
+    text-align: center;
+}
+
+div.DTTT_print_info h6 {
+    margin: 1em;
+    font-size: 28px;
+    font-weight: normal;
+    line-height: 28px;
+}
+
+div.DTTT_print_info p {
+    font-size: 14px;
+    line-height: 20px;
+}
+
+/*
+ * FixedColumns styles
+ */
+
+div.DTFC_LeftHeadWrapper table,
+div.DTFC_LeftFootWrapper table,
+div.DTFC_RightHeadWrapper table,
+div.DTFC_RightFootWrapper table,
+table.DTFC_Cloned tr.even {
+    background-color: white;
+}
+
+div.DTFC_RightHeadWrapper table,
+div.DTFC_LeftHeadWrapper table {
+    margin-bottom: 0 !important;
+    border-top-right-radius: 0 !important;
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,
+div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,
+div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,
+div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {
+    border-bottom-left-radius: 0 !important;
+    border-bottom-right-radius: 0 !important;
+}
+
+div.DTFC_RightBodyWrapper table,
+div.DTFC_LeftBodyWrapper table {
+    margin-bottom: 0 !important;
+    border-top: none;
+}
+
+div.DTFC_RightBodyWrapper tbody tr:first-child th,
+div.DTFC_RightBodyWrapper tbody tr:first-child td,
+div.DTFC_LeftBodyWrapper tbody tr:first-child th,
+div.DTFC_LeftBodyWrapper tbody tr:first-child td {
+    border-top: none;
+}
+
+div.DTFC_RightFootWrapper table,
+div.DTFC_LeftFootWrapper table {
+    border-top: none;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.css b/src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.css
new file mode 100644 (file)
index 0000000..3832d51
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * metismenu - v1.0.3
+ * Easy menu jQuery plugin for Twitter Bootstrap 3
+ * https://github.com/onokumus/metisMenu
+ *
+ * Made by Osman Nuri Okumuş
+ * Under MIT License
+ */
+.arrow {
+    float: right;
+}
+
+.glyphicon.arrow:before {
+    content: "\e079";
+}
+
+.active > a > .glyphicon.arrow:before {
+    content: "\e114";
+}
+
+
+/*
+ * Require Font-Awesome
+ * http://fortawesome.github.io/Font-Awesome/
+*/
+
+
+.fa.arrow:before {
+    content: "\f104";
+}
+
+.active > a > .fa.arrow:before {
+    content: "\f107";
+}
+
+.plus-times {
+    float: right;
+}
+
+.fa.plus-times:before {
+    content: "\f067";
+}
+
+.active > a > .fa.plus-times {
+    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+    -webkit-transform: rotate(45deg);
+    -moz-transform: rotate(45deg);
+    -ms-transform: rotate(45deg);
+    -o-transform: rotate(45deg);
+    transform: rotate(45deg);
+}
+
+.plus-minus {
+    float: right;
+}
+
+.fa.plus-minus:before {
+    content: "\f067";
+}
+
+.active > a > .fa.plus-minus:before {
+    content: "\f068";
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.min.css b/src/main/resources/META-INF/resources/designer/css/plugins/metisMenu/metisMenu.min.css
new file mode 100644 (file)
index 0000000..df919cf
--- /dev/null
@@ -0,0 +1 @@
+.arrow{float:right}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/morris.css b/src/main/resources/META-INF/resources/designer/css/plugins/morris.css
new file mode 100644 (file)
index 0000000..209f091
--- /dev/null
@@ -0,0 +1,2 @@
+.morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0}
+.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/social-buttons.css b/src/main/resources/META-INF/resources/designer/css/plugins/social-buttons.css
new file mode 100644 (file)
index 0000000..69f27b0
--- /dev/null
@@ -0,0 +1,68 @@
+@import url(//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css);
+/*
+ * Social Buttons for Bootstrap
+ *
+ * Copyright 2013 Panayiotis Lipiridis
+ * Licensed under the MIT License
+ *
+ * https://github.com/lipis/bootstrap-social
+ */
+
+.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social :first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}
+.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg :first-child{line-height:45px;width:45px;font-size:1.8em}
+.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm :first-child{line-height:28px;width:28px;font-size:1.4em}
+.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs :first-child{line-height:20px;width:20px;font-size:1.2em}
+.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding-left:0;padding-right:0}.btn-social-icon :first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}
+.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg :first-child{line-height:45px;width:45px;font-size:1.8em}
+.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm :first-child{line-height:28px;width:28px;font-size:1.4em}
+.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs :first-child{line-height:20px;width:20px;font-size:1.2em}
+.btn-social-icon :first-child{border:none;text-align:center;width:100% !important}
+.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}
+.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}
+.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}
+.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover,.btn-bitbucket:focus,.btn-bitbucket:active,.btn-bitbucket.active,.open .dropdown-toggle.btn-bitbucket{color:#fff;background-color:#183c60;border-color:rgba(0,0,0,0.2)}
+.btn-bitbucket:active,.btn-bitbucket.active,.open .dropdown-toggle.btn-bitbucket{background-image:none}
+.btn-bitbucket.disabled,.btn-bitbucket[disabled],fieldset[disabled] .btn-bitbucket,.btn-bitbucket.disabled:hover,.btn-bitbucket[disabled]:hover,fieldset[disabled] .btn-bitbucket:hover,.btn-bitbucket.disabled:focus,.btn-bitbucket[disabled]:focus,fieldset[disabled] .btn-bitbucket:focus,.btn-bitbucket.disabled:active,.btn-bitbucket[disabled]:active,fieldset[disabled] .btn-bitbucket:active,.btn-bitbucket.disabled.active,.btn-bitbucket[disabled].active,fieldset[disabled] .btn-bitbucket.active{background-color:#205081;border-color:rgba(0,0,0,0.2)}
+.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover,.btn-dropbox:focus,.btn-dropbox:active,.btn-dropbox.active,.open .dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d70b7;border-color:rgba(0,0,0,0.2)}
+.btn-dropbox:active,.btn-dropbox.active,.open .dropdown-toggle.btn-dropbox{background-image:none}
+.btn-dropbox.disabled,.btn-dropbox[disabled],fieldset[disabled] .btn-dropbox,.btn-dropbox.disabled:hover,.btn-dropbox[disabled]:hover,fieldset[disabled] .btn-dropbox:hover,.btn-dropbox.disabled:focus,.btn-dropbox[disabled]:focus,fieldset[disabled] .btn-dropbox:focus,.btn-dropbox.disabled:active,.btn-dropbox[disabled]:active,fieldset[disabled] .btn-dropbox:active,.btn-dropbox.disabled.active,.btn-dropbox[disabled].active,fieldset[disabled] .btn-dropbox.active{background-color:#1087dd;border-color:rgba(0,0,0,0.2)}
+.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover,.btn-facebook:focus,.btn-facebook:active,.btn-facebook.active,.open .dropdown-toggle.btn-facebook{color:#fff;background-color:#30487b;border-color:rgba(0,0,0,0.2)}
+.btn-facebook:active,.btn-facebook.active,.open .dropdown-toggle.btn-facebook{background-image:none}
+.btn-facebook.disabled,.btn-facebook[disabled],fieldset[disabled] .btn-facebook,.btn-facebook.disabled:hover,.btn-facebook[disabled]:hover,fieldset[disabled] .btn-facebook:hover,.btn-facebook.disabled:focus,.btn-facebook[disabled]:focus,fieldset[disabled] .btn-facebook:focus,.btn-facebook.disabled:active,.btn-facebook[disabled]:active,fieldset[disabled] .btn-facebook:active,.btn-facebook.disabled.active,.btn-facebook[disabled].active,fieldset[disabled] .btn-facebook.active{background-color:#3b5998;border-color:rgba(0,0,0,0.2)}
+.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover,.btn-flickr:focus,.btn-flickr:active,.btn-flickr.active,.open .dropdown-toggle.btn-flickr{color:#fff;background-color:#d6006f;border-color:rgba(0,0,0,0.2)}
+.btn-flickr:active,.btn-flickr.active,.open .dropdown-toggle.btn-flickr{background-image:none}
+.btn-flickr.disabled,.btn-flickr[disabled],fieldset[disabled] .btn-flickr,.btn-flickr.disabled:hover,.btn-flickr[disabled]:hover,fieldset[disabled] .btn-flickr:hover,.btn-flickr.disabled:focus,.btn-flickr[disabled]:focus,fieldset[disabled] .btn-flickr:focus,.btn-flickr.disabled:active,.btn-flickr[disabled]:active,fieldset[disabled] .btn-flickr:active,.btn-flickr.disabled.active,.btn-flickr[disabled].active,fieldset[disabled] .btn-flickr.active{background-color:#ff0084;border-color:rgba(0,0,0,0.2)}
+.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:hover,.btn-github:focus,.btn-github:active,.btn-github.active,.open .dropdown-toggle.btn-github{color:#fff;background-color:#303030;border-color:rgba(0,0,0,0.2)}
+.btn-github:active,.btn-github.active,.open .dropdown-toggle.btn-github{background-image:none}
+.btn-github.disabled,.btn-github[disabled],fieldset[disabled] .btn-github,.btn-github.disabled:hover,.btn-github[disabled]:hover,fieldset[disabled] .btn-github:hover,.btn-github.disabled:focus,.btn-github[disabled]:focus,fieldset[disabled] .btn-github:focus,.btn-github.disabled:active,.btn-github[disabled]:active,fieldset[disabled] .btn-github:active,.btn-github.disabled.active,.btn-github[disabled].active,fieldset[disabled] .btn-github.active{background-color:#444;border-color:rgba(0,0,0,0.2)}
+.btn-google-plus{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google-plus:hover,.btn-google-plus:focus,.btn-google-plus:active,.btn-google-plus.active,.open .dropdown-toggle.btn-google-plus{color:#fff;background-color:#ca3523;border-color:rgba(0,0,0,0.2)}
+.btn-google-plus:active,.btn-google-plus.active,.open .dropdown-toggle.btn-google-plus{background-image:none}
+.btn-google-plus.disabled,.btn-google-plus[disabled],fieldset[disabled] .btn-google-plus,.btn-google-plus.disabled:hover,.btn-google-plus[disabled]:hover,fieldset[disabled] .btn-google-plus:hover,.btn-google-plus.disabled:focus,.btn-google-plus[disabled]:focus,fieldset[disabled] .btn-google-plus:focus,.btn-google-plus.disabled:active,.btn-google-plus[disabled]:active,fieldset[disabled] .btn-google-plus:active,.btn-google-plus.disabled.active,.btn-google-plus[disabled].active,fieldset[disabled] .btn-google-plus.active{background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}
+.btn-instagram{color:#fff;background-color:#517fa4;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover,.btn-instagram:focus,.btn-instagram:active,.btn-instagram.active,.open .dropdown-toggle.btn-instagram{color:#fff;background-color:#446a89;border-color:rgba(0,0,0,0.2)}
+.btn-instagram:active,.btn-instagram.active,.open .dropdown-toggle.btn-instagram{background-image:none}
+.btn-instagram.disabled,.btn-instagram[disabled],fieldset[disabled] .btn-instagram,.btn-instagram.disabled:hover,.btn-instagram[disabled]:hover,fieldset[disabled] .btn-instagram:hover,.btn-instagram.disabled:focus,.btn-instagram[disabled]:focus,fieldset[disabled] .btn-instagram:focus,.btn-instagram.disabled:active,.btn-instagram[disabled]:active,fieldset[disabled] .btn-instagram:active,.btn-instagram.disabled.active,.btn-instagram[disabled].active,fieldset[disabled] .btn-instagram.active{background-color:#517fa4;border-color:rgba(0,0,0,0.2)}
+.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover,.btn-linkedin:focus,.btn-linkedin:active,.btn-linkedin.active,.open .dropdown-toggle.btn-linkedin{color:#fff;background-color:#005f8d;border-color:rgba(0,0,0,0.2)}
+.btn-linkedin:active,.btn-linkedin.active,.open .dropdown-toggle.btn-linkedin{background-image:none}
+.btn-linkedin.disabled,.btn-linkedin[disabled],fieldset[disabled] .btn-linkedin,.btn-linkedin.disabled:hover,.btn-linkedin[disabled]:hover,fieldset[disabled] .btn-linkedin:hover,.btn-linkedin.disabled:focus,.btn-linkedin[disabled]:focus,fieldset[disabled] .btn-linkedin:focus,.btn-linkedin.disabled:active,.btn-linkedin[disabled]:active,fieldset[disabled] .btn-linkedin:active,.btn-linkedin.disabled.active,.btn-linkedin[disabled].active,fieldset[disabled] .btn-linkedin.active{background-color:#007bb6;border-color:rgba(0,0,0,0.2)}
+.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover,.btn-pinterest:focus,.btn-pinterest:active,.btn-pinterest.active,.open .dropdown-toggle.btn-pinterest{color:#fff;background-color:#a81a20;border-color:rgba(0,0,0,0.2)}
+.btn-pinterest:active,.btn-pinterest.active,.open .dropdown-toggle.btn-pinterest{background-image:none}
+.btn-pinterest.disabled,.btn-pinterest[disabled],fieldset[disabled] .btn-pinterest,.btn-pinterest.disabled:hover,.btn-pinterest[disabled]:hover,fieldset[disabled] .btn-pinterest:hover,.btn-pinterest.disabled:focus,.btn-pinterest[disabled]:focus,fieldset[disabled] .btn-pinterest:focus,.btn-pinterest.disabled:active,.btn-pinterest[disabled]:active,fieldset[disabled] .btn-pinterest:active,.btn-pinterest.disabled.active,.btn-pinterest[disabled].active,fieldset[disabled] .btn-pinterest.active{background-color:#cb2027;border-color:rgba(0,0,0,0.2)}
+.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover,.btn-tumblr:focus,.btn-tumblr:active,.btn-tumblr.active,.open .dropdown-toggle.btn-tumblr{color:#fff;background-color:#1f3346;border-color:rgba(0,0,0,0.2)}
+.btn-tumblr:active,.btn-tumblr.active,.open .dropdown-toggle.btn-tumblr{background-image:none}
+.btn-tumblr.disabled,.btn-tumblr[disabled],fieldset[disabled] .btn-tumblr,.btn-tumblr.disabled:hover,.btn-tumblr[disabled]:hover,fieldset[disabled] .btn-tumblr:hover,.btn-tumblr.disabled:focus,.btn-tumblr[disabled]:focus,fieldset[disabled] .btn-tumblr:focus,.btn-tumblr.disabled:active,.btn-tumblr[disabled]:active,fieldset[disabled] .btn-tumblr:active,.btn-tumblr.disabled.active,.btn-tumblr[disabled].active,fieldset[disabled] .btn-tumblr.active{background-color:#2c4762;border-color:rgba(0,0,0,0.2)}
+.btn-twitter{color:#fff;background-color:#2ba9e1;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover,.btn-twitter:focus,.btn-twitter:active,.btn-twitter.active,.open .dropdown-toggle.btn-twitter{color:#fff;background-color:#1c92c7;border-color:rgba(0,0,0,0.2)}
+.btn-twitter:active,.btn-twitter.active,.open .dropdown-toggle.btn-twitter{background-image:none}
+.btn-twitter.disabled,.btn-twitter[disabled],fieldset[disabled] .btn-twitter,.btn-twitter.disabled:hover,.btn-twitter[disabled]:hover,fieldset[disabled] .btn-twitter:hover,.btn-twitter.disabled:focus,.btn-twitter[disabled]:focus,fieldset[disabled] .btn-twitter:focus,.btn-twitter.disabled:active,.btn-twitter[disabled]:active,fieldset[disabled] .btn-twitter:active,.btn-twitter.disabled.active,.btn-twitter[disabled].active,fieldset[disabled] .btn-twitter.active{background-color:#2ba9e1;border-color:rgba(0,0,0,0.2)}
+.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:hover,.btn-vk:focus,.btn-vk:active,.btn-vk.active,.open .dropdown-toggle.btn-vk{color:#fff;background-color:#4a6a89;border-color:rgba(0,0,0,0.2)}
+.btn-vk:active,.btn-vk.active,.open .dropdown-toggle.btn-vk{background-image:none}
+.btn-vk.disabled,.btn-vk[disabled],fieldset[disabled] .btn-vk,.btn-vk.disabled:hover,.btn-vk[disabled]:hover,fieldset[disabled] .btn-vk:hover,.btn-vk.disabled:focus,.btn-vk[disabled]:focus,fieldset[disabled] .btn-vk:focus,.btn-vk.disabled:active,.btn-vk[disabled]:active,fieldset[disabled] .btn-vk:active,.btn-vk.disabled.active,.btn-vk[disabled].active,fieldset[disabled] .btn-vk.active{background-color:#587ea3;border-color:rgba(0,0,0,0.2)}
+
+
+/* 
+ * Only for this example - not needed for the buttons
+ * ----------------------------------------------------- */
+.btn-social-icon {margin-bottom: 4px;}
+.social-class .social-hex{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px;opacity:.3;float:right}
+.social-class li{margin-bottom:4px}.social-class li:hover .social-hex{opacity:1}
+.social-class li:hover code{background-color:#e8e8ee}
+.social-class code{cursor:default}
diff --git a/src/main/resources/META-INF/resources/designer/css/plugins/timeline.css b/src/main/resources/META-INF/resources/designer/css/plugins/timeline.css
new file mode 100644 (file)
index 0000000..3925a5b
--- /dev/null
@@ -0,0 +1,180 @@
+.timeline {
+    position: relative;
+    padding: 20px 0 20px;
+    list-style: none;
+}
+
+.timeline:before {
+    content: " ";
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 50%;
+    width: 3px;
+    margin-left: -1.5px;
+    background-color: #eeeeee;
+}
+
+.timeline > li {
+    position: relative;
+    margin-bottom: 20px;
+}
+
+.timeline > li:before,
+.timeline > li:after {
+    content: " ";
+    display: table;
+}
+
+.timeline > li:after {
+    clear: both;
+}
+
+.timeline > li:before,
+.timeline > li:after {
+    content: " ";
+    display: table;
+}
+
+.timeline > li:after {
+    clear: both;
+}
+
+.timeline > li > .timeline-panel {
+    float: left;
+    position: relative;
+    width: 46%;
+    padding: 20px;
+    border: 1px solid #d4d4d4;
+    border-radius: 2px;
+    -webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.175);
+    box-shadow: 0 1px 6px rgba(0,0,0,0.175);
+}
+
+.timeline > li > .timeline-panel:before {
+    content: " ";
+    display: inline-block;
+    position: absolute;
+    top: 26px;
+    right: -15px;
+    border-top: 15px solid transparent;
+    border-right: 0 solid #ccc;
+    border-bottom: 15px solid transparent;
+    border-left: 15px solid #ccc;
+}
+
+.timeline > li > .timeline-panel:after {
+    content: " ";
+    display: inline-block;
+    position: absolute;
+    top: 27px;
+    right: -14px;
+    border-top: 14px solid transparent;
+    border-right: 0 solid #fff;
+    border-bottom: 14px solid transparent;
+    border-left: 14px solid #fff;
+}
+
+.timeline > li > .timeline-badge {
+    z-index: 100;
+    position: absolute;
+    top: 16px;
+    left: 50%;
+    width: 50px;
+    height: 50px;
+    margin-left: -25px;
+    border-radius: 50% 50% 50% 50%;
+    text-align: center;
+    font-size: 1.4em;
+    line-height: 50px;
+    color: #fff;
+    background-color: #999999;
+}
+
+.timeline > li.timeline-inverted > .timeline-panel {
+    float: right;
+}
+
+.timeline > li.timeline-inverted > .timeline-panel:before {
+    right: auto;
+    left: -15px;
+    border-right-width: 15px;
+    border-left-width: 0;
+}
+
+.timeline > li.timeline-inverted > .timeline-panel:after {
+    right: auto;
+    left: -14px;
+    border-right-width: 14px;
+    border-left-width: 0;
+}
+
+.timeline-badge.primary {
+    background-color: #2e6da4 !important;
+}
+
+.timeline-badge.success {
+    background-color: #3f903f !important;
+}
+
+.timeline-badge.warning {
+    background-color: #f0ad4e !important;
+}
+
+.timeline-badge.danger {
+    background-color: #d9534f !important;
+}
+
+.timeline-badge.info {
+    background-color: #5bc0de !important;
+}
+
+.timeline-title {
+    margin-top: 0;
+    color: inherit;
+}
+
+.timeline-body > p,
+.timeline-body > ul {
+    margin-bottom: 0;
+}
+
+.timeline-body > p + p {
+    margin-top: 5px;
+}
+
+@media(max-width:767px) {
+    ul.timeline:before {
+        left: 40px;
+    }
+
+    ul.timeline > li > .timeline-panel {
+        width: calc(100% - 90px);
+        width: -moz-calc(100% - 90px);
+        width: -webkit-calc(100% - 90px);
+    }
+
+    ul.timeline > li > .timeline-badge {
+        top: 16px;
+        left: 15px;
+        margin-left: 0;
+    }
+
+    ul.timeline > li > .timeline-panel {
+        float: right;
+    }
+
+    ul.timeline > li > .timeline-panel:before {
+        right: auto;
+        left: -15px;
+        border-right-width: 15px;
+        border-left-width: 0;
+    }
+
+    ul.timeline > li > .timeline-panel:after {
+        right: auto;
+        left: -14px;
+        border-right-width: 14px;
+        border-left-width: 0;
+    }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/simple-sidebar.css b/src/main/resources/META-INF/resources/designer/css/simple-sidebar.css
new file mode 100644 (file)
index 0000000..d7aceec
--- /dev/null
@@ -0,0 +1,123 @@
+/*!
+ * Start Bootstrap - Simple Sidebar HTML Template (http://startbootstrap.com)
+ * Code licensed under the Apache License v2.0.
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+/* Toggle Styles */
+
+#wrapper {
+    padding-left: 0;
+    -webkit-transition: all 0.5s ease;
+    -moz-transition: all 0.5s ease;
+    -o-transition: all 0.5s ease;
+    transition: all 0.5s ease;
+}
+
+#wrapper.toggled {
+    padding-left: 250px;
+}
+
+#sidebar-wrapper 
+{
+    z-index: 1000;
+    float:left;
+    left: 250px;
+    width: 0;
+    height: 100%;
+    margin-left: -250px;
+    overflow-y: auto;
+    -webkit-transition: all 0.5s ease;
+    -moz-transition: all 0.5s ease;
+    -o-transition: all 0.5s ease;
+    transition: all 0.5s ease;
+}
+
+#wrapper.toggled #sidebar-wrapper {
+    width: 250px;
+}
+
+#page-content-wrapper {
+    width: 100%;
+    padding: 15px;
+}
+
+#wrapper.toggled #page-content-wrapper {
+    position: absolute;
+    margin-right: -250px;
+}
+
+/* Sidebar Styles */
+
+.sidebar-nav {
+    position: absolute;
+    top: 0;
+    width: 250px;
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+
+.sidebar-nav li {
+    text-indent: 20px;
+    line-height: 40px;
+}
+
+.sidebar-nav li a {
+    display: block;
+    text-decoration: none;
+    color: #999999;
+}
+
+.sidebar-nav li a:hover {
+    text-decoration: none;
+    color: #fff;
+    background: rgba(255,255,255,0.2);
+}
+
+.sidebar-nav li a:active,
+.sidebar-nav li a:focus {
+    text-decoration: none;
+}
+
+.sidebar-nav > .sidebar-brand {
+    height: 65px;
+    font-size: 18px;
+    line-height: 60px;
+}
+
+.sidebar-nav > .sidebar-brand a {
+    color: #999999;
+}
+
+.sidebar-nav > .sidebar-brand a:hover {
+    color: #fff;
+    background: none;
+}
+
+@media(min-width:768px) {
+    #wrapper {
+        padding-left: 250px;
+    }
+
+    #wrapper.toggled {
+        padding-left: 0;
+    }
+
+    #sidebar-wrapper {
+        width: 250px;
+    }
+
+    #wrapper.toggled #sidebar-wrapper {
+        width: 0;
+    }
+
+    #page-content-wrapper {
+        padding: 20px;
+    }
+
+    #wrapper.toggled #page-content-wrapper {
+        position: relative;
+        margin-right: 0;
+    }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/style-gue.css b/src/main/resources/META-INF/resources/designer/css/style-gue.css
new file mode 100644 (file)
index 0000000..c61e7cd
--- /dev/null
@@ -0,0 +1,399 @@
+@font-face {
+       font-family: Glyphicons Halflings;
+       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");
+}
+
+@font-face {
+       font-family: Omnes Regular;
+       src: url(../../fonts/omnes-regular-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../../fonts/omnes-regular-webfont.woff) format("woff"),
+               url(../../fonts/omnes-regular-webfont.ttf) format("truetype"),
+               url(../../fonts/omnes-regular-webfont.svg#omnes_regular) format("svg");
+}
+
+@font-face {
+       font-family: Omnes Regular Italic;
+       src: url(../../fonts/omnes-regularitalic-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../../fonts/omnes-regularitalic-webfont.woff) format("woff"),
+               url(../../fonts/omnes-regularitalic-webfont.ttf) format("truetype"),
+               url(../../fonts/omnes-regularitalic-webfont.svg#omnes_regularitalic)
+               format("svg");
+}
+
+@font-face {
+       font-family: Omnes Medium;
+       src: url(../../fonts/omnes-medium-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../../fonts/omnes-medium-webfont.woff) format("woff"),
+               url(../../fonts/omnes-medium-webfont.ttf) format("truetype"),
+               url(../../fonts/omnes-medium-webfont.svg#omnes_medium) format("svg");
+}
+
+.caretup {
+       BORDER-BOTTOM: 4px solid;
+       BORDER-LEFT: transparent 4px solid;
+       WIDTH: 0px;
+       DISPLAY: inline-block;
+       HEIGHT: 0px;
+       MARGIN-LEFT: 2px;
+       VERTICAL-ALIGN: middle;
+       BORDER-RIGHT: transparent 4px solid
+}
+
+.my-activities .row .activityhead .caretup {
+       MARGIN-TOP: -6px
+}
+
+.activity-list .sort .caretup {
+       MARGIN-TOP: -7px;
+       MARGIN-LEFT: 5px
+}
+
+DL {
+       MARGIN-BOTTOM: 0px !important
+}
+
+.dropdown_sourceFilter {
+       MARGIN-TOP: 10px;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif
+}
+
+.dropdown_sourceFilter A {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: medium;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.dropdown_sourceFilter A:visited {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: medium;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.dropdown_sourceFilter DT {
+       HEIGHT: 37px
+}
+
+.dropdown_sourceFilter DT A {
+       Z-INDEX: 9999;
+       BORDER-BOTTOM: #bbbbbb 1px solid;
+       BORDER-LEFT: #bbbbbb 1px solid;
+       WIDTH: 100%;
+       DISPLAY: block;
+       BACKGROUND: white;
+       OVERFLOW: visible;
+       BORDER-TOP: #bbbbbb 1px solid;
+       BORDER-RIGHT: #bbbbbb 1px solid;
+       border-radius: 4px
+}
+
+.dropdown_sourceFilter DT A SPAN {
+       PADDING-BOTTOM: 5px !important;
+       PADDING-LEFT: 5px !important;
+       PADDING-RIGHT: 5px !important;
+       DISPLAY: block;
+       HEIGHT: 32px;
+       CURSOR: pointer;
+       PADDING-TOP: 6px !important
+}
+
+.dropdown_sourceFilter DT A SPAN .glyphicon-chevron-down {
+       MARGIN-TOP: -5px;
+       FLOAT: right;
+       COLOR: #666666
+}
+
+.dropdown_sourceFilter DD {
+       Z-INDEX: 1;
+       POSITION: relative;
+       OVERFLOW: visible
+}
+
+.dropdown_sourceFilter DD UL {
+       BORDER-BOTTOM: #bbbbbb 1px solid;
+       POSITION: absolute;
+       BORDER-LEFT: #bbbbbb 1px solid;
+       LIST-STYLE-TYPE: none;
+       MARGIN-TOP: -5px;
+       WIDTH: 100%;
+       DISPLAY: none;
+       BACKGROUND: #fff;
+       COLOR: #444444;
+       OVERFLOW: hidden;
+       BORDER-TOP: #bbbbbb 1px solid;
+       LIST-STYLE-IMAGE: none;
+       BORDER-RIGHT: #bbbbbb 1px solid;
+       LEFT: 0px;
+       border-radius: 0 0 4px 4px
+}
+
+.dropdown_sourceFilter DD UL LI {
+       BORDER-BOTTOM: #bbbbbb 1px solid
+}
+
+.dropdown_sourceFilter DD UL LI A {
+       PADDING-BOTTOM: 7px;
+       PADDING-LEFT: 7px;
+       PADDING-RIGHT: 7px;
+       DISPLAY: block;
+       PADDING-TOP: 7px
+}
+
+.dropdown_sourceFilter DD UL LI A:hover {
+       BACKGROUND: #ef6f00;
+       COLOR: white
+}
+
+.dropdown_sourceFilter DD {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown_sourceFilter DT {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown_sourceFilter UL {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown_sourceFilter SPAN.value {
+       DISPLAY: none
+}
+
+BODY.modal-open {
+       OVERFLOW: auto !important
+}
+
+header .profile-name .pname {
+       LINE-HEIGHT: 25px !important
+}
+
+.claimed-activities .pt-heading-image {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN: 15px 20px;
+       OVERFLOW: hidden;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 5px
+}
+
+.claimed-activities .pt-heading-image-initial {
+       BORDER-BOTTOM: #fff 1px solid;
+       BORDER-LEFT: #fff 1px solid;
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #fff;
+       BORDER-TOP: #fff 1px solid;
+       BORDER-RIGHT: #fff 1px solid;
+       border-radius: 0px
+}
+
+.claimed-activities .progress-timeline .pt-heading {
+       MARGIN: 3px 20px
+}
+
+.claimed-activities .pt-prism-content {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 3px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN: 0px 20px;
+       PADDING-LEFT: 3px;
+       PADDING-RIGHT: 3px;
+       COLOR: rgb(6, 122, 180);
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 3px;
+       border-radius: 5px
+}
+
+.claimed-activities .pt-prism-content SPAN {
+       COLOR: #067ab4
+}
+
+.claimed-activities .pt-prism-content A:visited {
+       TEXT-DECORATION: none
+}
+
+.claimed-activities .pt-prism-content A:hover {
+       TEXT-DECORATION: none
+}
+
+.claimed-activities .pt-prism-content A:focus {
+       TEXT-DECORATION: none
+}
+
+.claimed-activities .pt-application-content {
+       PADDING-BOTTOM: 3px;
+       MARGIN: 0px 20px;
+       PADDING-LEFT: 3px;
+       PADDING-RIGHT: 3px;
+       COLOR: rgb(76, 76, 76);
+       PADDING-TOP: 3px
+}
+
+.tab-sdc .tab-content .newsitem>DIV {
+       PADDING-TOP: 10px
+}
+
+.tab-sdc .tab-content .headline {
+       OVERFLOW: hidden
+}
+
+.tab-sdc .tab-content .headline H4 {
+       WHITE-SPACE: nowrap
+}
+
+.tab-sdc .tab-content .pic {
+       BACKGROUND-COLOR: #fff !important;
+       PADDING-LEFT: 0px
+}
+
+#modalDisclaimer .modal-body .row-content P {
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       PADDING-TOP: 5px
+}
+
+footer {
+       MARGIN-TOP: 30px
+}
+
+.activity-detail-link-warning {
+       PADDING-LEFT: 10px;
+       DISPLAY: none;
+       COLOR: red
+}
+
+#divLightbox {
+       BACKGROUND-IMAGE: url(../sdcImages/1x1blk50.png);
+       Z-INDEX: 1000;
+       POSITION: absolute;
+       BOTTOM: 0px;
+       DISPLAY: none;
+       TOP: 0px;
+       RIGHT: 0px;
+       LEFT: 0px
+}
+
+#divLightboxContent {
+       Z-INDEX: 1100;
+       BORDER-BOTTOM: black 1px solid;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: black 1px solid;
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: white;
+       MARGIN: auto;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 10px;
+       DISPLAY: none;
+       OVERFLOW: hidden;
+       BORDER-TOP: black 1px solid;
+       RIGHT: 0px;
+       BORDER-RIGHT: black 1px solid;
+       PADDING-TOP: 10px;
+       LEFT: 0px
+}
+
+#divLightboxInstall {
+       DISPLAY: none
+}
+
+#divLightboxUpdate {
+       DISPLAY: none
+}
+
+#arcadeOverview .left INPUT {
+       BORDER-BOTTOM: #808080 1px solid;
+       BORDER-LEFT: #808080 1px solid;
+       BORDER-TOP: #808080 1px solid;
+       BORDER-RIGHT: #808080 1px solid
+}
+
+#arcadeOverview .left TEXTAREA {
+       BORDER-BOTTOM: #808080 1px solid;
+       BORDER-LEFT: #808080 1px solid;
+       BORDER-TOP: #808080 1px solid;
+       BORDER-RIGHT: #808080 1px solid
+}
+
+#arcadeOverview .right INPUT {
+       BORDER-BOTTOM: #808080 1px solid;
+       BORDER-LEFT: #808080 1px solid;
+       BORDER-TOP: #808080 1px solid;
+       BORDER-RIGHT: #808080 1px solid
+}
+
+#arcadeOverview .right TEXTAREA {
+       BORDER-BOTTOM: #808080 1px solid;
+       BORDER-LEFT: #808080 1px solid;
+       BORDER-TOP: #808080 1px solid;
+       BORDER-RIGHT: #808080 1px solid
+}
+
+.unsuppored-browser {
+       BACKGROUND-COLOR: #fff !important;
+       OVERFLOW: hidden
+}
+
+.unsuppored-browser .browswer-support-help-text H2 {
+       TEXT-ALIGN: left;
+       MARGIN-BOTTOM: 0px !important
+}
+
+.unsuppored-browser .browswer-support-help-text P {
+       TEXT-ALIGN: left;
+       PADDING-TOP: 10px
+}
+
+.unsuppored-browser .browswer-support-help-text H2:first-child {
+       TEXT-ALIGN: left;
+       MARGIN-BOTTOM: -15px !important
+}
+
+.unsuppored-browser .browswer-support-help-text {
+       DISPLAY: inline-block
+}
+
+.unsuppored-browser .unsupported-image-bg {
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: rgb(243, 243, 243);
+       MARGIN-TOP: 75px
+}
+
+.unsuppored-browser .container-fluid .unsupported-image-align {
+       TEXT-ALIGN: center
+}
+
+.modal.notifications #notifications_list_div_id .modal-dialog .modal-body .row BUTTON
+       {
+       MARGIN-TOP: 5px !important;
+       MARGIN-BOTTOM: 10px !important
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/styles.css b/src/main/resources/META-INF/resources/designer/css/styles.css
new file mode 100644 (file)
index 0000000..fe73ee4
--- /dev/null
@@ -0,0 +1,5477 @@
+@font-face {
+       font-family: Omnes Regular;
+       src: url(../fonts/omnes-regular-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../fonts/omnes-regular-webfont.woff) format("woff"),
+               url(../fonts/omnes-regular-webfont.ttf) format("truetype"),
+               url(../fonts/omnes-regular-webfont.svg#omnes_regular)
+               format("svg");
+}
+
+@font-face {
+       font-family: Omnes Regular Italic;
+       src: url(../fonts/omnes-regularitalic-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../fonts/omnes-regularitalic-webfont.woff) format("woff"),
+               url(../fonts/omnes-regularitalic-webfont.ttf) format("truetype"),
+               url(../fonts/omnes-regularitalic-webfont.svg#omnes_regularitalic)
+               format("svg");
+}
+
+@font-face {
+       font-family: Omnes Medium;
+       src: url(../fonts/omnes-medium-webfont.eot?#iefix)
+               format("embedded-opentype"),
+               url(../fonts/omnes-medium-webfont.woff) format("woff"),
+               url(../fonts/omnes-medium-webfont.ttf) format("truetype"),
+               url(../fonts/omnes-medium-webfont.svg#omnes_medium)
+               format("svg");
+}
+
+.resourcecenter-toppanel {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN: 0px 15px;
+       DISPLAY: block;
+       BACKGROUND: #fff;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.resourcecenter-toppanel .title {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       PADDING-BOTTOM: 20px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BACKGROUND: #fff;
+       PADDING-TOP: 20px
+}
+
+.resourcecenter-toppanel .title H3 {
+       MARGIN: 0px;
+       WIDTH: 80%;
+       COLOR: #f47b20
+}
+
+.resourcecenter-toppanel .title A.collapse-icon {
+       POSITION: absolute;
+       FONT-SIZE: 24px;
+       TOP: 20px;
+       RIGHT: 30px
+}
+
+.closed.resourcecenter-toppanel .title {
+       BORDER-BOTTOM: 0px
+}
+
+.resourcecenter-toppanel .rolepanel {
+       BORDER-LEFT: #ccc 1px solid;
+       BACKGROUND: #f3f3f3;
+       MARGIN-LEFT: 15px
+}
+
+.resourcecenter-toppanel .rolepanel .rolepanel-cont {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 30px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 10px
+}
+
+.resourcecenter-toppanel .rolepanel .rolepanel-summary {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 30px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 10px
+}
+
+.resourcecenter-toppanel .rolepanel .rolepanel-summary {
+       BORDER-TOP: #ccc 1px solid
+}
+
+.resourcecenter-toppanel .rolepanel .rolepanel-summary P {
+       MARGIN-BOTTOM: 0px
+}
+
+.resourcecenter-toppanel .rolepanel .rc-toppanel-row {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 10px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 10px
+}
+
+.resourcecenter-toppanel .rolepanel .rc-toppanel-row A.btn {
+       WIDTH: 100%;
+       FONT-SIZE: 16px
+}
+
+.resourcecenter-toppanel .rolepanel .rc-toppanel-row A.btn SPAN {
+       PADDING-RIGHT: 15px
+}
+
+.breadcrumbs {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 10px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 10px
+}
+
+.breadcrumbs UL {
+       PADDING-BOTTOM: 10px;
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 10px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 10px;
+       DISPLAY: block;
+       MARGIN-BOTTOM: 0px;
+       HEIGHT: auto;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 10px
+}
+
+.breadcrumbs UL LI {
+       DISPLAY: inline-block
+}
+
+.breadcrumbs UL LI:after {
+       CONTENT: ' / '
+}
+
+.rc-side-panel-content-wrapper {
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN-LEFT: 15px
+}
+
+.rc-side-panel-content-wrapper .claimed-activities .row {
+       MARGIN: 0px -15px
+}
+
+.rc-side-panel-content-wrapper .claimed-activities .article-area {
+       MARGIN: 0px
+}
+
+.rc-side-panel-content-wrapper .activity-detail-right {
+       PADDING-BOTTOM: 150px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px
+}
+
+.rc-side-panel-content-wrapper .sdc-slider {
+       BORDER-LEFT: 0px;
+       MARGIN-LEFT: 0px
+}
+
+.rc-side-panel-content-wrapper .background-open.sdc-slider {
+       
+}
+
+.rc-side-panel-content-wrapper .background-closed.sdc-slider {
+       
+}
+
+.rc-side-panel-content-wrapper .background-closed.sdc-slider .sliderhead
+       {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.iframeWrapper {
+       POSITION: relative;
+       MIN-HEIGHT: 500px;
+       WIDTH: 100%;
+       MARGIN-BOTTOM: 65px;
+       HEIGHT: 500px
+}
+
+.iframeWrapper IFRAME {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       WIDTH: 100%;
+       DISPLAY: block;
+       MARGIN-BOTTOM: 75px;
+       FLOAT: left;
+       HEIGHT: 100%;
+       OVERFLOW: scroll;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       resize: vertical
+}
+
+.iframeWrapper .controls {
+       BORDER-BOTTOM: #b9b9b9 1px solid;
+       POSITION: absolute;
+       BORDER-LEFT: #b9b9b9 1px solid;
+       PADDING-BOTTOM: 3px;
+       LINE-HEIGHT: 30px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       DISPLAY: none;
+       FONT-SIZE: 30px;
+       BORDER-TOP: #b9b9b9 1px solid;
+       TOP: 12px;
+       RIGHT: 12px;
+       BORDER-RIGHT: #b9b9b9 1px solid;
+       PADDING-TOP: 5px;
+       border-radius: 5px 5px
+}
+
+.resourcecenter.content {
+       PADDING-BOTTOM: 20px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 20px
+}
+
+.nosidebar.resourcecenter.content {
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-LEFT: 0px;
+       PADDING-TOP: 15px
+}
+
+.nosidebar.resourcecenter.content .iframeWrapper {
+       MARGIN-LEFT: -15px
+}
+
+.resourcecenter.content H1 {
+       PADDING-BOTTOM: 20px;
+       MARGIN: 0px;
+       PADDING-LEFT: 15px;
+       COLOR: #f47b20
+}
+
+.portlet.resourcecenter.content {
+       PADDING-BOTTOM: 0px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.portlet.resourcecenter.content .portletWrapper {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #fff;
+       MARGIN: 20px 15px 100px 30px;
+       MIN-HEIGHT: 622px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       HEIGHT: 622px;
+       OVERFLOW: auto;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       resize: vertical
+}
+
+.resourcecenter.content .iframeWrapper {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 30px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN: 0px -15px 65px -30px;
+       PADDING-LEFT: 15px;
+       WIDTH: auto;
+       PADDING-RIGHT: 15px;
+       HEIGHT: auto;
+       OVERFLOW: hidden;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 30px
+}
+
+.resourcecenter.content .iframeWrapper IFRAME {
+       MIN-HEIGHT: 506px;
+       MARGIN-BOTTOM: 0px;
+       HEIGHT: 100%;
+       border-radius: 4px
+}
+
+.resourcecenter.content .iframeWrapper .controls {
+       TOP: 42px;
+       RIGHT: 42px
+}
+
+.resourcecenter.content article {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       OVERFLOW: auto;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article .header-box {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.resourcecenter.content article .header-box H1 {
+       PADDING-BOTTOM: 15px;
+       MARGIN: 0px
+}
+
+.resourcecenter.content article .header-box H2 {
+       PADDING-BOTTOM: 15px;
+       MARGIN: 0px
+}
+
+.resourcecenter.content article .body-box {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 0px
+}
+
+.resourcecenter.content article .body-box H4 {
+       MARGIN: 15px 0px
+}
+
+.resourcecenter.content article .body-box P {
+       LINE-HEIGHT: 24px
+}
+
+.resourcecenter.content article .body-box section {
+       PADDING-BOTTOM: 15px;
+       MARGIN: 0px -15px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article .body-box section:first-child {
+       BORDER-TOP: 0px
+}
+
+.resourcecenter.content article .body-box UL LI {
+       LINE-HEIGHT: 24px;
+       MARGIN-TOP: 5px
+}
+
+.resourcecenter.content article .body-box .thumbnail {
+       MARGIN: 10px 0px
+}
+
+.resourcecenter.content article .body-box .lightbox.thumbnail IMG {
+       MIN-HEIGHT: 150px;
+       MAX-HEIGHT: 150px
+}
+
+.resourcecenter.content article .body-box .img-thumbnail {
+       MARGIN: 10px 0px
+}
+
+.resourcecenter.content article.articleOTP {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.resourcecenter.content article.articleOTP .header-box {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 4px 4px 0 0
+}
+
+.resourcecenter.content article.articleOTP .header-box .title {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article.articleOTP .header-box .title H2 {
+       COLOR: #f47b20
+}
+
+.resourcecenter.content article.articleOTP .header-box .summary {
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article.articleOTP .header-box .summary P {
+       LINE-HEIGHT: 24px
+}
+
+.resourcecenter.content article.articleOTP .body-box {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 0 0 4px 4px
+}
+
+.resourcecenter.content article.announcements {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.resourcecenter.content article.announcements .header-box {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 4px 4px 0 0
+}
+
+.resourcecenter.content article.announcements .header-box .title {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article.announcements .header-box .title H2 {
+       COLOR: #f47b20
+}
+
+.resourcecenter.content article.announcements .header-box .summary {
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.resourcecenter.content article.announcements .header-box .summary P {
+       LINE-HEIGHT: 24px
+}
+
+.resourcecenter.content article.announcements .body-box {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 0px;
+       border-radius: 0 0 4px 4px
+}
+
+.resourcecenter.content article.announcements .body-box .row {
+       BORDER-TOP: #ccc 1px solid
+}
+
+.resourcecenter.content article.announcements .body-box .row:first-child
+       {
+       BORDER-TOP: 0px
+}
+
+.resourcecenter.content article.announcements .body-box .info {
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 30px
+}
+
+.resourcecenter.content article.announcements .body-box .info H4 {
+       PADDING-BOTTOM: 15px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.resourcecenter.content article.announcements .body-box .info .details {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.resourcecenter.content article.announcements .body-box .info .details A.cta
+       {
+       DISPLAY: block;
+       PADDING-TOP: 5px
+}
+
+.resourcecenter.content article.announcements .body-box .info .details SPAN
+       {
+       PADDING-BOTTOM: 5px;
+       DISPLAY: block;
+       FONT-FAMILY: "Omnes Regular Italic"
+}
+
+.resourcecenter-useful {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 10px;
+       MARGIN: 0px 15px 40px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       DISPLAY: block;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 10px;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.resourcecenter-useful .useful {
+       FLOAT: left;
+       PADDING-TOP: 6px
+}
+
+.resourcecenter-useful .right-side {
+       TEXT-ALIGN: right
+}
+
+.resourcecenter-useful .right-side A.btn {
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px
+}
+
+.resourcecenter-useful .right-side .close {
+       MARGIN: 7px 10px 0px 25px
+}
+
+.leaving {
+       MIN-HEIGHT: 200px;
+       DISPLAY: block
+}
+
+.leaving H4 {
+       MARGIN: 30px 0px
+}
+
+.leaving .btn-blue {
+       MARGIN: 0px auto;
+       PADDING-LEFT: 20px;
+       WIDTH: 50%;
+       PADDING-RIGHT: 20px;
+       DISPLAY: block
+}
+
+.onThisPage {
+       POSITION: relative;
+       MIN-HEIGHT: 100px
+}
+
+.onThisPage .affix.nav {
+       MARGIN-TOP: 10px;
+       TOP: 0px
+}
+
+.onThisPage .affix-top.nav {
+       POSITION: absolute;
+       MARGIN-TOP: 10px;
+       TOP: 0px
+}
+
+.onThisPage .affix-bottom.nav {
+       POSITION: absolute
+}
+
+.onThisPage .nav LI A {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+.onThisPage .nav LI A:active {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+.onThisPage .nav LI.active A {
+       BORDER-BOTTOM-COLOR: #f47b20;
+       BORDER-TOP-COLOR: #f47b20;
+       COLOR: #f47b20;
+       BORDER-RIGHT-COLOR: #f47b20;
+       BORDER-LEFT-COLOR: #f47b20
+}
+
+.onThisPage .nav LI.active A:hover {
+       BORDER-BOTTOM-COLOR: #fcb314;
+       BORDER-TOP-COLOR: #fcb314;
+       COLOR: #fcb314;
+       BORDER-RIGHT-COLOR: #fcb314;
+       BORDER-LEFT-COLOR: #fcb314
+}
+
+.onThisPage .nav LI.active A:active {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+.onThisPage .nav LI A {
+       BORDER-LEFT: #fff 3px solid;
+       COLOR: #067ab4
+}
+
+.onThisPage .nav LI A:hover {
+       BORDER-BOTTOM-COLOR: #44c8f5;
+       BACKGROUND-COLOR: #fff;
+       BORDER-TOP-COLOR: #44c8f5;
+       COLOR: #44c8f5;
+       BORDER-RIGHT-COLOR: #44c8f5;
+       BORDER-LEFT-COLOR: #44c8f5
+}
+
+.onThisPage .nav LI A [class^='icon-'] {
+       POSITION: relative;
+       LINE-HEIGHT: 1;
+       FONT-SIZE: 24px;
+       VERTICAL-ALIGN: middle;
+       TOP: -2px
+}
+
+.onThisPage .nav LI .returntotop {
+       MARGIN-TOP: 0px;
+       WIDTH: auto
+}
+
+.search.content {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.notabs.search.content {
+       BORDER-TOP: #ccc 1px solid
+}
+
+.article.search.content {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px;
+       border-radius: 4px
+}
+
+.article.search.content article {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MIN-HEIGHT: 650px;
+       MARGIN-BOTTOM: 75px;
+       OVERFLOW: scroll;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 4px;
+       resize: vertical
+}
+
+.article.search.content article .header-box {
+       BORDER-BOTTOM: #ccc 1px solid;
+       LINE-HEIGHT: 62px
+}
+
+.article.search.content article .header-box H2 {
+       LINE-HEIGHT: 62px;
+       MARGIN: 0px;
+       PADDING-LEFT: 30px;
+       FLOAT: left;
+       COLOR: #f47b20
+}
+
+.article.search.content article .header-box .useful {
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       FLOAT: right;
+       FONT-SIZE: 16px;
+       PADDING-TOP: 0px
+}
+
+.article.search.content article .body-box {
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 30px
+}
+
+.article.search.content article .body-box P {
+       LINE-HEIGHT: 1.5
+}
+
+.article.search.content article .body-box .portletWrapper {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #fff;
+       MARGIN: 15px 0px;
+       MIN-HEIGHT: 300px;
+       PADDING-LEFT: 15px;
+       WIDTH: 688px;
+       PADDING-RIGHT: 15px;
+       OVERFLOW: auto;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       resize: none
+}
+
+.search.content .search-pagination {
+       FLOAT: right;
+       PADDING-TOP: 10px
+}
+
+.search.content .search-pagination .pagination {
+       WIDTH: 246px;
+       DISPLAY: block;
+       FLOAT: left;
+       MARGIN-RIGHT: 0px
+}
+
+.search.content .search-pagination .pagination .active {
+       BACKGROUND-COLOR: #f47b20
+}
+
+.search.content .search-pagination .pagination .active A {
+       BORDER-BOTTOM-COLOR: #f47b20;
+       BACKGROUND-COLOR: #f47b20;
+       BORDER-TOP-COLOR: #f47b20;
+       WIDTH: 32px;
+       BORDER-RIGHT-COLOR: #f47b20;
+       BORDER-LEFT-COLOR: #f47b20
+}
+
+.search.content .search-pagination .pagination-text-area {
+       WIDTH: 240px;
+       FLOAT: right
+}
+
+.search.content .search-pagination .pagination-text-area .result-count {
+       MARGIN-TOP: 0px;
+       PADDING-LEFT: 20px;
+       WIDTH: 50%;
+       DISPLAY: block;
+       FLOAT: left;
+       MARGIN-RIGHT: 0px;
+       PADDING-TOP: 27px
+}
+
+.search.content .search-pagination .pagination-text-area .result-count SPAN
+       {
+       FONT-FAMILY: "Omnes Medium"
+}
+
+.search.content .search-pagination .pagination-text-area .view-dropdown
+       {
+       WIDTH: 50%;
+       FLOAT: right;
+       PADDING-TOP: 18px
+}
+
+.search.content .search-pagination .pagination-text-area .view-dropdown .dropdown
+       {
+       MARGIN-TOP: 0px;
+       FLOAT: right
+}
+
+.search.content .search-pagination .pagination-text-area .view-dropdown SPAN.viewlabel
+       {
+       TEXT-ALIGN: right;
+       MARGIN-TOP: 0px;
+       PADDING-LEFT: 25px;
+       WIDTH: 50%;
+       FLOAT: left;
+       MARGIN-RIGHT: 0px;
+       PADDING-TOP: 8px
+}
+
+.search-box {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 18px;
+       PADDING-LEFT: 15px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 15px;
+       DISPLAY: block;
+       PADDING-TOP: 18px
+}
+
+.search-box:first-child {
+       border-radius: 4px 4px 0 0
+}
+
+.search-box .input-group {
+       DISPLAY: block
+}
+
+.search-box INPUT.search-query {
+       PADDING-LEFT: 35px;
+       BORDER-RIGHT: 0px
+}
+
+.search-box FORM.form-search {
+       POSITION: relative
+}
+
+.search-box FORM.form-search .form-control {
+       MAX-WIDTH: 40%;
+       border-top-left-radius: 4px;
+       border-bottom-left-radius: 4px
+}
+
+.search-box FORM.form-search .btn {
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       MARGIN-LEFT: 15px;
+       PADDING-TOP: 5px
+}
+
+.search-box FORM.form-search:before {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       WIDTH: 20px;
+       DISPLAY: block;
+       FONT-FAMILY: "icomoon";
+       BACKGROUND-POSITION: -48px 0px;
+       HEIGHT: 20px;
+       COLOR: #ccc;
+       FONT-SIZE: 23px;
+       CONTENT: '\e624';
+       TOP: 2px;
+       LEFT: 7px
+}
+
+.search-box A[role='button'] {
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 25px;
+       PADDING-RIGHT: 25px;
+       MARGIN-LEFT: 15px;
+       PADDING-TOP: 5px
+}
+
+.search-box .search-button {
+       WIDTH: 20%
+}
+
+.search-box .search-button .dropdown DT A {
+       WIDTH: 100%
+}
+
+.search-box .search-button .dropdown DD UL {
+       WIDTH: 100%
+}
+
+.result-count.search-box {
+       BACKGROUND-COLOR: #f3f3f3
+}
+
+.result-count.search-box SPAN {
+       FONT-FAMILY: "Omnes Medium";
+       FONT-SIZE: 15px
+}
+
+.dym.search-box {
+       FONT-SIZE: 16px
+}
+
+.dym.search-box SPAN {
+       FONT-FAMILY: "Omnes Regular Italic";
+       COLOR: #b30a3c
+}
+
+.dym.search-box A {
+       FONT-FAMILY: "Omnes Medium"
+}
+
+.search-filters {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px
+}
+
+.search-filters H4 {
+       MARGIN-TOP: 0px;
+       MARGIN-BOTTOM: 5px
+}
+
+.search-filters UL {
+       PADDING-BOTTOM: 0px;
+       LIST-STYLE-TYPE: none;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 0px
+}
+
+.search-filters UL LI {
+       DISPLAY: inline-block;
+       MARGIN-BOTTOM: 10px;
+       MARGIN-RIGHT: 10px
+}
+
+.search-filters UL LI A.filter-btn {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       PADDING-TOP: 0px
+}
+
+.search-filters UL LI A.filter-btn SPAN {
+       MARGIN-LEFT: 3px
+}
+
+.search-filters UL LI A.btn-default {
+       BORDER-BOTTOM-COLOR: #067ab4;
+       BORDER-TOP-COLOR: #067ab4;
+       COLOR: #067ab4;
+       BORDER-RIGHT-COLOR: #067ab4;
+       BORDER-LEFT-COLOR: #067ab4
+}
+
+.search-filters UL LI A.btn-default:hover {
+       BACKGROUND-COLOR: #e4f4f9
+}
+
+.search-content-area .search-results-wrapper {
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 30px;
+       FLOAT: left;
+       MARGIN-RIGHT: 400px;
+       PADDING-TOP: 15px
+}
+
+.search-content-area .search-results-wrapper .search-results-panel {
+       BORDER-TOP: #ccc 1px solid;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.search-content-area .search-results-wrapper .search-result {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 10px
+}
+
+.search-content-area .search-results-wrapper .search-result H4 {
+       MARGIN: 10px 0px
+}
+
+.search-content-area .related-results {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.search-content-area .related-results UL {
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px;
+       FLOAT: left;
+       LIST-STYLE-IMAGE: none;
+       MARGIN-RIGHT: 75px
+}
+
+.search-content-area .related-results UL LI {
+       MARGIN-BOTTOM: 10px
+}
+
+.search-content-area .search-right-rail {
+       PADDING-BOTTOM: 150px;
+       PADDING-LEFT: 0px;
+       WIDTH: 400px;
+       PADDING-RIGHT: 15px;
+       FLOAT: left;
+       MARGIN-LEFT: -400px;
+       PADDING-TOP: 15px
+}
+
+.no-results.search-content-area {
+       POSITION: relative
+}
+
+.no-results.search-content-area .search-results-wrapper {
+       FLOAT: none
+}
+
+.no-results.search-content-area .search-results-wrapper .no-results {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px
+}
+
+.no-results.search-content-area .search-results-wrapper .no-results H4 {
+       FONT-FAMILY: "Omnes Regular Italic";
+       COLOR: #b30a3c
+}
+
+.no-results.search-content-area .search-results-wrapper .no-results UL {
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px;
+       FLOAT: left;
+       LIST-STYLE-IMAGE: none;
+       MARGIN-RIGHT: 75px
+}
+
+.no-results.search-content-area .search-results-wrapper .no-results UL LI
+       {
+       MARGIN-BOTTOM: 10px
+}
+
+.no-results.search-content-area .search-right-rail {
+       POSITION: absolute;
+       PADDING-BOTTOM: 150px;
+       PADDING-LEFT: 0px;
+       WIDTH: 400px;
+       PADDING-RIGHT: 15px;
+       FLOAT: none;
+       MARGIN-LEFT: -400px;
+       TOP: 0px;
+       RIGHT: 0px;
+       PADDING-TOP: 15px
+}
+
+.useful .useful-choice {
+       DISPLAY: inline-block
+}
+
+.useful .useful-choice SPAN[class^='icon'] {
+       FONT-SIZE: 18px
+}
+
+.useful .useful-choice SPAN {
+       MARGIN-LEFT: 5px
+}
+
+.useful .useful-choice SPAN:first-child {
+       MARGIN-LEFT: 5px
+}
+
+.useful A {
+       PADDING-RIGHT: 5px;
+       MARGIN-LEFT: 15px
+}
+
+.useful A.selected {
+       COLOR: #0c2577
+}
+
+.useful SPAN:first-child {
+       MARGIN-LEFT: 0px
+}
+
+.search-ask-us {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 25px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 5px;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.search-ask-us H4 {
+       WIDTH: 50%;
+       FLOAT: left
+}
+
+.search-ask-us A.btn {
+       MARGIN-TOP: 15px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       FLOAT: right
+}
+
+.right-rail-coe {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 5px;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.right-rail-coe UL {
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px;
+       MARGIN-BOTTOM: 40px;
+       LIST-STYLE-IMAGE: none
+}
+
+.right-rail-coe UL LI {
+       MARGIN-BOTTOM: 10px
+}
+
+.back-to-search {
+       FLOAT: right;
+       MARGIN-RIGHT: 15px
+}
+
+:focus {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: 0px
+}
+
+A:focus {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: 0px
+}
+
+.form-control:focus {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: 0px
+}
+
+.open.btn-group .dropdown-toggle {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: 0px
+}
+
+.form-control:focus {
+       box-shadow: none
+}
+
+.bootstrap-select .btn:focus {
+       OUTLINE-STYLE: none !important;
+       OUTLINE-COLOR: invert !important;
+       OUTLINE-WIDTH: medium !important
+}
+
+TEXTAREA {
+       OUTLINE-STYLE: none !important;
+       OUTLINE-COLOR: invert !important;
+       OUTLINE-WIDTH: medium !important
+}
+
+.open.btn-group .dropdown-toggle {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       box-shadow: none;
+       -webkit-box-shadow: none
+}
+
+BODY {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+H1 {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+H2 {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+H3 {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+H4 {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+P {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       COLOR: #666666
+}
+
+H2.welcome {
+       PADDING-BOTTOM: 10px
+}
+
+H2.welcome SPAN {
+       PADDING-LEFT: 5px;
+       FONT-SIZE: 16px
+}
+
+H4 {
+       MARGIN-BOTTOM: 20px
+}
+
+H4.whats-new {
+       PADDING-BOTTOM: 7px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FONT-SIZE: 24px;
+       PADDING-TOP: 7px
+}
+
+HTML {
+       MIN-HEIGHT: 100%;
+       HEIGHT: 100%
+}
+
+BODY {
+       MIN-HEIGHT: 100%;
+       HEIGHT: 100%
+}
+
+BODY {
+       OVERFLOW-Y: scroll
+}
+
+.modal-open .container {
+       OVERFLOW-Y: scroll
+}
+
+.modal-open .container .navbar-fixed-top {
+       OVERFLOW-Y: scroll
+}
+
+.modal-open .modal-container {
+       OVERFLOW-Y: scroll
+}
+
+.modal-open .page-container .navbar-fixed-top {
+       OVERFLOW-Y: visible
+}
+
+.padding-adjust {
+       BACKGROUND-COLOR: #00ff00
+}
+
+A {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+A:active {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+A:focus {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+A:hover {
+       COLOR: #44c8f5;
+       TEXT-DECORATION: none
+}
+
+.ico-favorite {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       COLOR: #f3f3f3;
+       MARGIN-LEFT: 8px;
+       FONT-SIZE: 25px;
+       VERTICAL-ALIGN: middle;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 5px;
+       border-radius: 4px
+}
+
+.ico-default {
+       COLOR: #f47b20;
+       FONT-SIZE: 25px;
+       VERTICAL-ALIGN: middle
+}
+
+.ico-tab {
+       PADDING-RIGHT: 5px;
+       MARGIN-LEFT: -8px;
+       FONT-SIZE: 25px;
+       VERTICAL-ALIGN: text-bottom;
+       MARGIN-RIGHT: 5px
+}
+
+.ico-nav {
+       TEXT-ALIGN: center;
+       LINE-HEIGHT: 21px;
+       COLOR: #067ab4;
+       FONT-SIZE: 33px;
+       VERTICAL-ALIGN: middle;
+       CURSOR: pointer
+}
+
+.ico-nav:hover {
+       COLOR: #44c8f5
+}
+
+.ico-btn {
+       TEXT-ALIGN: center;
+       LINE-HEIGHT: 18px;
+       COLOR: #fff;
+       FONT-SIZE: 26px;
+       VERTICAL-ALIGN: middle;
+       MARGIN-RIGHT: 10px
+}
+
+.dropdown-glyphicon-chevron-down:before {
+       POSITION: absolute;
+       LINE-HEIGHT: 1;
+       FONT-STYLE: normal;
+       DISPLAY: inline-block;
+       FONT-FAMILY: "Glyphicons Halflings";
+       COLOR: #666666;
+       CONTENT: "\e114";
+       TOP: 10px;
+       RIGHT: 10px;
+       FONT-WEIGHT: 400;
+       -webkit-font-smoothing: antialiased;
+       -moz-osx-font-smoothing: grayscale
+}
+
+header {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       BACKGROUND: #f3f3f3;
+       HEIGHT: 65px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+header .hamburgertoggle {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px
+}
+
+header .logo IMG {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 16px
+}
+
+header .global-search {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+header .global-search INPUT.search-query {
+       PADDING-LEFT: 35px;
+       WIDTH: 60%;
+       FLOAT: left;
+       BORDER-RIGHT: 0px;
+       border-radius: 4px 0 0 4px
+}
+
+header .global-search FORM.form-search {
+       POSITION: relative;
+       MARGIN-TOP: 15px
+}
+
+header .global-search FORM.form-search .form-control {
+       WIDTH: 60%;
+       FLOAT: left
+}
+
+header .global-search FORM.form-search:before {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       WIDTH: 20px;
+       DISPLAY: block;
+       FONT-FAMILY: "icomoon";
+       BACKGROUND-POSITION: -48px 0px;
+       HEIGHT: 20px;
+       COLOR: #ccc;
+       FONT-SIZE: 23px;
+       CONTENT: "\e620";
+       TOP: 2px;
+       LEFT: 7px
+}
+
+header .favorites {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .notify {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .search-min {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 20px
+}
+
+header .illustrated-profile-pic {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 20px
+}
+
+header .favorites {
+       WIDTH: 65px
+}
+
+header .notify {
+       WIDTH: 65px
+}
+
+header .notify .active {
+       POSITION: absolute;
+       TOP: 6px;
+       RIGHT: 6px
+}
+
+header .favorites A:hover {
+       COLOR: #44c8f5 !important;
+       CURSOR: pointer;
+       TEXT-DECORATION: none
+}
+
+header .notify A:hover {
+       COLOR: #44c8f5 !important;
+       CURSOR: pointer;
+       TEXT-DECORATION: none
+}
+
+header .search-min A:hover {
+       COLOR: #44c8f5 !important;
+       CURSOR: pointer;
+       TEXT-DECORATION: none
+}
+
+header .illustrated-profile-pic A:hover {
+       COLOR: #44c8f5 !important;
+       CURSOR: pointer;
+       TEXT-DECORATION: none
+}
+
+header .favorites A:visited {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+header .notify A:visited {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+header .search-min A:visited {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+header .illustrated-profile-pic A:visited {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+header .profile-pic {
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       MAX-WIDTH: 65px;
+       FLOAT: right;
+       HEIGHT: 65px;
+       OVERFLOW: hidden
+}
+
+header .profile-pic .img-cont {
+       PADDING-LEFT: 0px
+}
+
+header .profile-pic .img-cont .profile-img {
+       BACKGROUND-COLOR: #f47b20;
+       BACKGROUND-REPEAT: no-repeat;
+       BACKGROUND-POSITION: center center;
+       background-size: cover
+}
+
+header .profile-name {
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 6px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 6px;
+       PADDING-RIGHT: 6px;
+       FLOAT: right;
+       HEIGHT: 63px;
+       PADDING-TOP: 6px
+}
+
+header .profile-name .pname {
+       TEXT-ALIGN: left;
+       LINE-HEIGHT: 48px;
+       PADDING-LEFT: 10px;
+       WIDTH: 130px;
+       TEXT-OVERFLOW: ellipsis;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       HEIGHT: 63px;
+       COLOR: #067ab4;
+       FONT-SIZE: 16px;
+       OVERFLOW: hidden
+}
+
+header .globalIndicator .favorites {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .globalIndicator .notify {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .globalIndicator .search-min {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .globalIndicator .illustrated-profile-pic {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FLOAT: right;
+       PADDING-TOP: 20px
+}
+
+header .globalIndicator .search-min {
+       CURSOR: pointer
+}
+
+.date-bookmark {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 30px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 30px;
+       DISPLAY: block;
+       MARGIN-BOTTOM: 38px;
+       FLOAT: left;
+       PADDING-TOP: 0px
+}
+
+.date-bookmark .current-date {
+       FONT-SIZE: 12px;
+       PADDING-TOP: 15px
+}
+
+.date-bookmark .bookmark-it {
+       FONT-SIZE: 12px;
+       PADDING-TOP: 15px
+}
+
+.date-bookmark .current-date {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FLOAT: left
+}
+
+.date-bookmark .bookmark-it {
+       FLOAT: right;
+       CURSOR: pointer
+}
+
+.globalnav {
+       MARGIN: -10px 15px 0px;
+       COLOR: #067ab4;
+       FONT-SIZE: 16px
+}
+
+.globalnav .nav-tabs {
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       box-shadow: inset 0 -13px 10px -15px rgba(0, 0, 0, 0.2);
+       -webkit-box-shadow: inset 0 -1px 10px -15px rgba(0, 0, 0, 0.2);
+       -moz-box-shadow: inset 0 -13px 10px -15px rgba(0, 0, 0, 0.2)
+}
+
+.globalnav UL {
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px
+}
+
+.globalnav UL LI {
+       BORDER-BOTTOM: 0px;
+       POSITION: relative;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       MARGIN-RIGHT: 20px
+}
+
+.globalnav UL LI>A {
+       BORDER-BOTTOM: 0px;
+       POSITION: relative;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       MARGIN-RIGHT: 20px
+}
+
+.globalnav UL LI:visited {
+       COLOR: #067ab4
+}
+
+.globalnav UL LI>A:visited {
+       COLOR: #067ab4
+}
+
+.globalnav UL LI .activity-num {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 10px;
+       LINE-HEIGHT: 1px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       WIDTH: 40px;
+       PADDING-RIGHT: 10px;
+       HEIGHT: 21px;
+       COLOR: #fff;
+       FONT-SIZE: 12px;
+       TOP: -10px;
+       RIGHT: -17px;
+       PADDING-TOP: 10px;
+       border-radius: 80px/40px;
+       -moz-border-radius: 80px/40px;
+       -webkit-border-radius: 80px/40px
+}
+
+.globalnav UL LI .claimed-num {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 10px;
+       LINE-HEIGHT: 1px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       WIDTH: 40px;
+       PADDING-RIGHT: 10px;
+       HEIGHT: 21px;
+       COLOR: #fff;
+       FONT-SIZE: 12px;
+       TOP: -10px;
+       RIGHT: -17px;
+       PADDING-TOP: 10px;
+       border-radius: 80px/40px;
+       -moz-border-radius: 80px/40px;
+       -webkit-border-radius: 80px/40px
+}
+
+.globalnav UL LI>A .activity-num {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 10px;
+       LINE-HEIGHT: 1px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       WIDTH: 40px;
+       PADDING-RIGHT: 10px;
+       HEIGHT: 21px;
+       COLOR: #fff;
+       FONT-SIZE: 12px;
+       TOP: -10px;
+       RIGHT: -17px;
+       PADDING-TOP: 10px;
+       border-radius: 80px/40px;
+       -moz-border-radius: 80px/40px;
+       -webkit-border-radius: 80px/40px
+}
+
+.globalnav UL LI>A .claimed-num {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 10px;
+       LINE-HEIGHT: 1px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       WIDTH: 40px;
+       PADDING-RIGHT: 10px;
+       HEIGHT: 21px;
+       COLOR: #fff;
+       FONT-SIZE: 12px;
+       TOP: -10px;
+       RIGHT: -17px;
+       PADDING-TOP: 10px;
+       border-radius: 80px/40px;
+       -moz-border-radius: 80px/40px;
+       -webkit-border-radius: 80px/40px
+}
+
+.globalnav UL LI>A {
+       PADDING-BOTTOM: 13px;
+       PADDING-LEFT: 26px;
+       PADDING-RIGHT: 26px;
+       MARGIN-RIGHT: 0px;
+       PADDING-TOP: 10px
+}
+
+.globalnav-dropdown {
+       Z-INDEX: 200;
+       POSITION: relative;
+       PADDING-BOTTOM: 0px;
+       BACKGROUND-COLOR: #b9b9b9;
+       PADDING-LEFT: 0px;
+       WIDTH: 110%;
+       PADDING-RIGHT: 0px;
+       MARGIN-LEFT: -15px;
+       PADDING-TOP: 0px
+}
+
+.globalnav-dropdown UL {
+       PADDING-BOTTOM: 0px;
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       MARGIN-BOTTOM: 0px;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 0px
+}
+
+.globalnav-dropdown UL LI {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 25px;
+       PADDING-RIGHT: 25px;
+       TEXT-DECORATION: none;
+       PADDING-TOP: 10px;
+       transition: all 0.2s ease
+}
+
+.globalnav-dropdown UL LI A {
+       WIDTH: 100%;
+       DISPLAY: block;
+       COLOR: #fff;
+       FONT-SIZE: 15px
+}
+
+.globalnav-dropdown UL LI A:hover {
+       TEXT-DECORATION: none
+}
+
+.globalnav-dropdown UL LI:hover {
+       BACKGROUND-COLOR: #f47b20;
+       transition: all 0.3s ease
+}
+
+.globalnav-dropdown UL LI:first-child {
+       PADDING-TOP: 15px
+}
+
+.globalnav-dropdown:after {
+       Z-INDEX: 1;
+       BORDER-BOTTOM: #b9b9b9 15px solid;
+       POSITION: absolute;
+       BORDER-LEFT: transparent 11px solid;
+       WIDTH: 0px;
+       DISPLAY: block;
+       MARGIN-LEFT: -4px;
+       BORDER-TOP: #b9b9b9 0px solid;
+       CONTENT: '';
+       TOP: -15px;
+       BORDER-RIGHT: transparent 11px solid;
+       LEFT: 40px
+}
+
+.dropdown-hidden {
+       DISPLAY: none
+}
+
+.search-dropdown {
+       POSITION: relative;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #b9b9b9
+}
+
+.search-dropdown .form-search {
+       MARGIN-TOP: 15px
+}
+
+.search-dropdown .input-group {
+       DISPLAY: block
+}
+
+.search-dropdown .input-group .form-control {
+       WIDTH: 100%;
+       border-radius: 5px
+}
+
+.search-dropdown .dropdown {
+       POSITION: relative;
+       DISPLAY: inline-block
+}
+
+.search-dropdown .dropdown DD {
+       WIDTH: 250px
+}
+
+.search-dropdown .dropdown DT {
+       WIDTH: 250px
+}
+
+.search-dropdown .dropdown UL {
+       WIDTH: 250px
+}
+
+.search-dropdown .btn-blue {
+       POSITION: absolute;
+       MARGIN-TOP: -5px;
+       MARGIN-LEFT: 10px;
+       TOP: 64px;
+       RIGHT: 15px
+}
+
+.search-dropdown:after {
+       Z-INDEX: 1;
+       BORDER-BOTTOM: #b9b9b9 15px solid;
+       POSITION: absolute;
+       BORDER-LEFT: transparent 11px solid;
+       WIDTH: 0px;
+       DISPLAY: block;
+       BORDER-TOP: #b9b9b9 0px solid;
+       CONTENT: '';
+       TOP: -15px;
+       BORDER-RIGHT: transparent 11px solid;
+       LEFT: 71%
+}
+
+.container {
+       MARGIN-BOTTOM: 22px
+}
+
+.content {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 50px;
+       BACKGROUND-COLOR: #fff;
+       MARGIN: 0px 15px;
+       MIN-HEIGHT: 725px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       OVERFLOW: hidden;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       border-radius: 0 0 4px 4px
+}
+
+.content .leftCol {
+       WIDTH: 32%;
+       FLOAT: left
+}
+
+.content .midCol {
+       WIDTH: 32%;
+       FLOAT: left
+}
+
+.content .rightCol {
+       WIDTH: 32%;
+       FLOAT: left
+}
+
+.content .wideCol {
+       WIDTH: 66%;
+       FLOAT: left;
+       MARGIN-LEFT: 15px
+}
+
+.content .midCol {
+       MARGIN-TOP: 25px;
+       MARGIN-BOTTOM: 15px;
+       FLOAT: left;
+       MARGIN-LEFT: 15px
+}
+
+.content .rightCol {
+       MARGIN-TOP: 25px;
+       MARGIN-BOTTOM: 15px;
+       FLOAT: left;
+       MARGIN-LEFT: 15px
+}
+
+.content .fullCol {
+       WIDTH: 100%;
+       FLOAT: left
+}
+
+.content .fullCol H3 {
+       FONT-SIZE: 26px
+}
+
+.content .fullCol H4 {
+       FONT-SIZE: 26px
+}
+
+.content .fullColClaimed {
+       WIDTH: 88%;
+       FLOAT: left
+}
+
+.content .halfCol {
+       WIDTH: 49.5%;
+       MARGIN-BOTTOM: 25px;
+       FLOAT: left
+}
+
+.content .list.halfCol {
+       WIDTH: 49%;
+       MARGIN-BOTTOM: 25px;
+       FLOAT: left
+}
+
+.content .list H4 {
+       MARGIN-TOP: 25px
+}
+
+.content .list H6 {
+       MARGIN-TOP: 25px;
+       FONT-SIZE: 18px
+}
+
+.content .nogutter.halfCol {
+       MARGIN-RIGHT: 0px
+}
+
+.content .nogutter.halfCol H4 {
+       MARGIN-TOP: 25px
+}
+
+.content .nogutter.halfCol H6 {
+       MARGIN-TOP: 25px;
+       FONT-SIZE: 18px
+}
+
+.content .flexColLg {
+       WIDTH: 38%;
+       FLOAT: right;
+       MARGIN-RIGHT: 10px
+}
+
+.content .flexColLg H4 {
+       MARGIN-TOP: 10px
+}
+
+.content .flexColSm {
+       WIDTH: 35%;
+       FLOAT: right;
+       MARGIN-RIGHT: 0px
+}
+
+.content .flexColSm H4 {
+       MARGIN-TOP: 10px
+}
+
+.noborder.content {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.noborder.notabs.content {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.noborder.content .breadcrumb {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       MARGIN-BOTTOM: 15px;
+       PADDING-TOP: 0px
+}
+
+.noborder.notabs.content .breadcrumb {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       MARGIN-BOTTOM: 15px;
+       PADDING-TOP: 0px
+}
+
+.notabs.content {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.missingpage {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       MARGIN-BOTTOM: 100px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px
+}
+
+.returntotop {
+       MARGIN-TOP: -25px;
+       MARGIN-RIGHT: 25px
+}
+
+footer {
+       Z-INDEX: 100;
+       POSITION: relative;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN-TOP: 0px;
+       WIDTH: 100%;
+       HEIGHT: 325px;
+       BORDER-TOP: #ccc 1px solid
+}
+
+footer .content {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 50px;
+       MIN-HEIGHT: 0px;
+       BACKGROUND: none transparent scroll repeat 0% 0%;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px
+}
+
+footer .footerlinks {
+       MARGIN-TOP: 20px
+}
+
+footer .footerlinks .globe {
+       PADDING-RIGHT: 25px
+}
+
+footer .footerlinks A {
+       LINE-HEIGHT: 15px;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       FONT-SIZE: 13px;
+       MARGIN-RIGHT: 50px;
+       TEXT-DECORATION: none
+}
+
+footer .footerlinks A:hover {
+       LINE-HEIGHT: 15px;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       FONT-SIZE: 13px;
+       MARGIN-RIGHT: 50px;
+       TEXT-DECORATION: none
+}
+
+footer .footerlegal {
+       MARGIN-TOP: 20px
+}
+
+footer .footerlegal P {
+       LINE-HEIGHT: 15px;
+       FONT-SIZE: 10px
+}
+
+.content_container {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN: 20px auto;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 3px
+}
+
+.content-nav-container {
+       BACKGROUND-COLOR: #00ff00
+}
+
+DL {
+       MARGIN-BOTTOM: 0px !important
+}
+
+.dropdown {
+       MARGIN-TOP: 5px;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif
+}
+
+.dropdown A {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: medium;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.dropdown A:visited {
+       OUTLINE-STYLE: none;
+       OUTLINE-COLOR: invert;
+       OUTLINE-WIDTH: medium;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.dropdown DT {
+       HEIGHT: 37px
+}
+
+.dropdown DT A {
+       Z-INDEX: 9999;
+       BORDER-BOTTOM: #bbbbbb 1px solid;
+       BORDER-LEFT: #bbbbbb 1px solid;
+       WIDTH: 100%;
+       DISPLAY: block;
+       BACKGROUND: white;
+       BORDER-TOP: #bbbbbb 1px solid;
+       BORDER-RIGHT: #bbbbbb 1px solid;
+       border-radius: 4px
+}
+
+.dropdown DT A SPAN {
+       PADDING-BOTTOM: 10px !important;
+       PADDING-LEFT: 10px !important;
+       TEXT-OVERFLOW: ellipsis;
+       PADDING-RIGHT: 25px !important;
+       DISPLAY: block;
+       WHITE-SPACE: nowrap;
+       HEIGHT: 32px;
+       OVERFLOW: hidden;
+       CURSOR: pointer;
+       PADDING-TOP: 6px !important
+}
+
+.dropdown DD {
+       Z-INDEX: 1;
+       POSITION: relative;
+       OVERFLOW: visible
+}
+
+.dropdown DD UL {
+       BORDER-BOTTOM: #bbbbbb 1px solid;
+       POSITION: absolute;
+       BORDER-LEFT: #bbbbbb 1px solid;
+       LIST-STYLE-TYPE: none;
+       MARGIN-TOP: -5px;
+       WIDTH: 100%;
+       DISPLAY: none;
+       BACKGROUND: #fff;
+       COLOR: #444444;
+       OVERFLOW: hidden;
+       BORDER-TOP: #bbbbbb 1px solid;
+       LIST-STYLE-IMAGE: none;
+       BORDER-RIGHT: #bbbbbb 1px solid;
+       LEFT: 0px;
+       border-radius: 0 0 4px 4px
+}
+
+.dropdown DD UL LI {
+       BORDER-BOTTOM: #bbbbbb 1px solid
+}
+
+.dropdown DD UL LI A {
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       DISPLAY: block;
+       PADDING-TOP: 5px
+}
+
+.dropdown DD UL LI A:hover {
+       BACKGROUND: #ef6f00;
+       COLOR: white
+}
+
+.dropdown DD {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown DT {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown UL {
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.dropdown SPAN.value {
+       DISPLAY: none
+}
+
+.search-button {
+       WIDTH: 40%;
+       FLOAT: left
+}
+
+.search-button .dropdown {
+       MARGIN-TOP: 0px
+}
+
+.search-button .dropdown DT A {
+       WIDTH: 100%;
+       border-radius: 0px 6px 6px 0px
+}
+
+.search-button .dropdown DD UL {
+       WIDTH: 100%
+}
+
+.introPanel {
+       MARGIN-BOTTOM: 5px
+}
+
+.introPanel H4 {
+       PADDING-BOTTOM: 7px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       FONT-SIZE: 24px;
+       PADDING-TOP: 7px
+}
+
+.introPanel P {
+       FONT-SIZE: 14px
+}
+
+.introPanel .summary-btn {
+       MARGIN-TOP: 24px;
+       FONT-SIZE: 14px
+}
+
+.introPanel .summary {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       WIDTH: 100%;
+       MARGIN-BOTTOM: 13px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 4px
+}
+
+.introPanel .summary .summary-cont {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       PADDING-TOP: 15px
+}
+
+.introPanel .summary .summary-cont H3 {
+       MARGIN-TOP: 5px;
+       MARGIN-BOTTOM: 5px;
+       FONT-SIZE: 26px
+}
+
+.introPanel .summary .footer {
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 10px
+}
+
+.introPanel .summary .footer .title {
+       FONT-SIZE: 14px
+}
+
+.introPanel .summary .footer .title H4 {
+       FONT-SIZE: 18px
+}
+
+.introPanel .summary .footer .descrip {
+       FONT-FAMILY: "Omnes Regular Regular", Arial, Serif;
+       FONT-SIZE: 12px
+}
+
+.introPanel .summary .footer .descrip OL {
+       LIST-STYLE-POSITION: inside;
+       PADDING-LEFT: 0px
+}
+
+.introPanel .summary .footer .descrip OL LI {
+       PADDING-BOTTOM: 15px;
+       FONT-FAMILY: "Omnes Regular Regular", Arial, Serif;
+       FONT-SIZE: 13px
+}
+
+#btn-csi {
+       MARGIN-BOTTOM: 24px
+}
+
+.panel {
+       MARGIN-BOTTOM: 30px
+}
+
+.panel-sdc {
+       POSITION: relative;
+       BORDER-BOTTOM-COLOR: #ccc;
+       BACKGROUND-COLOR: #fff;
+       BORDER-TOP-COLOR: #ccc;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       BORDER-RIGHT-COLOR: #ccc;
+       BORDER-LEFT-COLOR: #ccc
+}
+
+.panel-sdc .panel-heading {
+       BORDER-BOTTOM-COLOR: #ccc;
+       PADDING-BOTTOM: 15px;
+       BORDER-TOP-COLOR: #ccc;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       COLOR: #f47b20;
+       BORDER-RIGHT-COLOR: #ccc;
+       FONT-SIZE: 17px;
+       BORDER-LEFT-COLOR: #ccc;
+       PADDING-TOP: 15px
+}
+
+.panel-sdc .panel-heading .heading-text {
+       MARGIN-LEFT: 5px
+}
+
+.panel-sdc .panel-heading .panel-icon {
+       POSITION: absolute;
+       TOP: 13px
+}
+
+.panel-sdc .panel-heading .active {
+       POSITION: absolute;
+       TOP: 13px
+}
+
+.panel-sdc .panel-heading .inactive {
+       POSITION: absolute;
+       TOP: 13px
+}
+
+.panel-sdc .panel-heading .active {
+       CURSOR: pointer;
+       RIGHT: 15px
+}
+
+.panel-sdc .panel-heading .inactive {
+       CURSOR: pointer;
+       RIGHT: 15px
+}
+
+.panel-sdc .panel-heading .active {
+       COLOR: #fcb314
+}
+
+.panel-sdc .panel-heading .inactive {
+       COLOR: #f3f3f3
+}
+
+.panel-sdc .panel-heading A {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-heading A:hover {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-body .dropdown {
+       MARGIN-BOTTOM: 10px !important
+}
+
+.panel-sdc .panel-body .dropdown DT A SPAN {
+       LINE-HEIGHT: 20px
+}
+
+.panel-sdc .panel-body A {
+       LINE-HEIGHT: 30px;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-body A:hover {
+       LINE-HEIGHT: 30px;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-body A .ico-default {
+       COLOR: #067ab4;
+       MARGIN-RIGHT: 10px
+}
+
+.panel-sdc .panel-body A:hover .ico-default {
+       COLOR: #067ab4;
+       MARGIN-RIGHT: 10px
+}
+
+.panel-sdc .panel-body P {
+       MARGIN-BOTTOM: 10px !important
+}
+
+.panel-sdc .panel-body P.with-icon {
+       MARGIN-LEFT: 37px
+}
+
+.panel-sdc .panel-footer {
+       POSITION: relative;
+       BACKGROUND-COLOR: #fff;
+       HEIGHT: 50px
+}
+
+.panel-sdc .panel-footer A {
+       POSITION: absolute;
+       COLOR: #fff;
+       RIGHT: 15px;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-footer A:hover {
+       POSITION: absolute;
+       COLOR: #fff;
+       RIGHT: 15px;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-footer .btn-blue {
+       POSITION: absolute;
+       COLOR: #fff;
+       RIGHT: 15px;
+       TEXT-DECORATION: none
+}
+
+.panel-sdc .panel-footer .results {
+       MARGIN-TOP: 6px;
+       DISPLAY: block;
+       FLOAT: left;
+       COLOR: #ccc
+}
+
+.panel-sdc .panel-footer .btn-blue {
+       MARGIN-TOP: -3px
+}
+
+.panel-alt {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 10px;
+       COLOR: #f47b20;
+       FONT-SIZE: 16px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 12px;
+       border-radius: 6px
+}
+
+.tab-alt {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 10px;
+       COLOR: #f47b20;
+       FONT-SIZE: 16px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 12px;
+       border-radius: 6px
+}
+
+.panel-alt .heading-text {
+       MARGIN-LEFT: 5px
+}
+
+.tab-alt .heading-text {
+       MARGIN-LEFT: 5px
+}
+
+.panel-alt A {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.panel-alt A:visited {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.panel-alt A:hover {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.tab-alt A {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.tab-alt A:visited {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.tab-alt A:hover {
+       COLOR: #f47b20;
+       TEXT-DECORATION: none
+}
+
+.panel-alt .panel-icon {
+       POSITION: absolute;
+       TOP: 17px
+}
+
+.panel-alt .arrow {
+       POSITION: absolute;
+       TOP: 17px
+}
+
+.tab-alt .panel-icon {
+       POSITION: absolute;
+       TOP: 17px
+}
+
+.tab-alt .arrow {
+       POSITION: absolute;
+       TOP: 17px
+}
+
+.panel-alt .arrow {
+       CURSOR: pointer;
+       RIGHT: 15px
+}
+
+.tab-alt .arrow {
+       CURSOR: pointer;
+       RIGHT: 15px
+}
+
+.my-activities {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-LEFT: 0px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       MARGIN-BOTTOM: 40px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05);
+       border-radius: 5px
+}
+
+.my-activities .header {
+       PADDING-BOTTOM: 7px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 10px;
+       HEIGHT: 50px;
+       COLOR: #fff;
+       FONT-SIZE: 24px;
+       PADDING-TOP: 7px;
+       border-radius: 4px 4px 0 0
+}
+
+.my-activities .total {
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 30px;
+       LINE-HEIGHT: 49px;
+       PADDING-LEFT: 30px;
+       WIDTH: 50%;
+       PADDING-RIGHT: 30px;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FLOAT: left;
+       HEIGHT: 213px;
+       COLOR: #f47b20;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 30px
+}
+
+.my-activities .total .sm-num {
+       DISPLAY: block;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 34px
+}
+
+.my-activities .total .lg-num {
+       DISPLAY: block;
+       FONT-SIZE: 70px
+}
+
+.my-activities .total .btn-view {
+       POSITION: absolute;
+       MARGIN: 20px;
+       BOTTOM: -1px;
+       DISPLAY: block;
+       RIGHT: 0px;
+       LEFT: 0px
+}
+
+.my-activities .claimed {
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 20px;
+       LINE-HEIGHT: 33px;
+       PADDING-LEFT: 0px;
+       WIDTH: 50%;
+       PADDING-RIGHT: 0px;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FLOAT: left;
+       COLOR: #f47b20;
+       PADDING-TOP: 20px
+}
+
+.my-activities .unclaimed {
+       TEXT-ALIGN: center;
+       PADDING-BOTTOM: 20px;
+       LINE-HEIGHT: 33px;
+       PADDING-LEFT: 0px;
+       WIDTH: 50%;
+       PADDING-RIGHT: 0px;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FLOAT: left;
+       COLOR: #f47b20;
+       PADDING-TOP: 20px
+}
+
+.my-activities .claimed .sm-num {
+       DISPLAY: block;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 24px
+}
+
+.my-activities .unclaimed .sm-num {
+       DISPLAY: block;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 24px
+}
+
+.my-activities .claimed .lg-num {
+       DISPLAY: block;
+       FONT-SIZE: 45px;
+       ont-family: "Omnes Regular Italic", Arial, Serif
+}
+
+.my-activities .unclaimed .lg-num {
+       DISPLAY: block;
+       FONT-SIZE: 45px;
+       ont-family: "Omnes Regular Italic", Arial, Serif
+}
+
+.my-activities .claimed {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.my-activities .row {
+       WIDTH: 100%;
+       FLOAT: left;
+       MARGIN-LEFT: 0px;
+       MARGIN-RIGHT: 0px
+}
+
+.my-activities .row .activityhead {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.1);
+       -webkit-box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.1);
+       -moz-box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.1)
+}
+
+.my-activities .row .activityhead .project {
+       WIDTH: 50%;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.my-activities .row .activityhead .project A {
+       BACKGROUND-COLOR: #ff0000;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.my-activities .row .activityhead .project A:hover {
+       BACKGROUND-COLOR: #ff0000;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.my-activities .row .activityhead .project A:visited {
+       BACKGROUND-COLOR: #ff0000;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.my-activities .row .activityhead .duedate {
+       WIDTH: 40%;
+       DISPLAY: inline-block
+}
+
+.my-activities .row .activityhead .caret {
+       MARGIN-TOP: -6px
+}
+
+.my-activities .row .projectcont {
+       OVERFLOW-Y: auto;
+       WIDTH: 100%;
+       FLOAT: left;
+       HEIGHT: 295px
+}
+
+.my-activities .row .projectcont .activity {
+       PADDING-BOTTOM: 8px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 8px
+}
+
+.my-activities .row .projectcont .activity .project {
+       TEXT-ALIGN: left;
+       LINE-HEIGHT: 17px;
+       WIDTH: 50%;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       VERTICAL-ALIGN: middle
+}
+
+.my-activities .row .projectcont .activity .project .pname {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif
+}
+
+.my-activities .row .projectcont .activity .duedate {
+       LINE-HEIGHT: 21px;
+       WIDTH: 40%;
+       DISPLAY: inline-block;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       VERTICAL-ALIGN: middle
+}
+
+.btn-sm {
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 17px;
+       PADDING-RIGHT: 17px;
+       FONT-SIZE: 14px !important;
+       PADDING-TOP: 5px
+}
+
+.btn-blue {
+       FONT-SIZE: 16px
+}
+
+.btn-blue {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.btn-blue:visited {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.btn-blue:hover {
+       BACKGROUND-COLOR: #44c8f5;
+       COLOR: #fff
+}
+
+.btn-orange {
+       BORDER-BOTTOM-COLOR: #f47b20;
+       BACKGROUND-COLOR: #f47b20;
+       BORDER-TOP-COLOR: #f47b20;
+       COLOR: #fff;
+       BORDER-RIGHT-COLOR: #f47b20;
+       BORDER-LEFT-COLOR: #f47b20
+}
+
+.btn-orange:visited {
+       BORDER-BOTTOM-COLOR: #f47b20;
+       BACKGROUND-COLOR: #f47b20;
+       BORDER-TOP-COLOR: #f47b20;
+       COLOR: #fff;
+       BORDER-RIGHT-COLOR: #f47b20;
+       BORDER-LEFT-COLOR: #f47b20
+}
+
+.btn-orange:hover {
+       BORDER-BOTTOM-COLOR: #fcb314;
+       BORDER-TOP-COLOR: #fcb314;
+       BACKGROUND: #fcb314;
+       COLOR: #fff;
+       BORDER-RIGHT-COLOR: #fcb314;
+       BORDER-LEFT-COLOR: #fcb314
+}
+
+.btn-back {
+       POSITION: relative;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 16px;
+       WIDTH: 80px;
+       HEIGHT: 30px;
+       COLOR: #fff;
+       MARGIN-LEFT: 30px;
+       FONT-SIZE: 20px;
+       border-radius: 0 3px 3px 0;
+       -moz-border-radius: 0 3px 3px 0;
+       -webkit-border-radius: 0 3px 3px 0
+}
+
+.btn-back:before {
+       BORDER-BOTTOM: transparent 15px solid;
+       POSITION: absolute;
+       WIDTH: 0px;
+       HEIGHT: 0px;
+       BORDER-TOP: transparent 15px solid;
+       CONTENT: '';
+       TOP: 0px;
+       RIGHT: 100%;
+       BORDER-RIGHT: #067ab4 10px solid;
+       border-radius: 3px;
+       -moz-border-radius: 3px;
+       -webkit-border-radius: 3px
+}
+
+.btn-back:hover {
+       TEXT-DECORATION: none
+}
+
+.modal-title {
+       COLOR: #f47b20;
+       MARGIN-LEFT: 10px;
+       FONT-SIZE: 16px
+}
+
+.modal-title SPAN {
+       MARGIN-LEFT: 25px;
+       MARGIN-RIGHT: 10px
+}
+
+.resource-modal-title {
+       MARGIN: 25px;
+       COLOR: #f47b20
+}
+
+.modal-dd-bg {
+       BORDER-BOTTOM: #e5e5e5 1px solid;
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 15px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 10px;
+       MARGIN-LEFT: 0px;
+       PADDING-TOP: 5px
+}
+
+.modal-dd-bg .dropdown {
+       WIDTH: 50%;
+       MARGIN-LEFT: 25px
+}
+
+.modal.notifications .modal-dialog .notifications-list {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 36px;
+       PADDING-RIGHT: 36px;
+       PADDING-TOP: 10px
+}
+
+.resource {
+       MARGIN: 15px 15px 85px
+}
+
+.tabs {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN-TOP: 15px;
+       WIDTH: 100%;
+       MARGIN-BOTTOM: 37px;
+       OVERFLOW: hidden;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05);
+       border-radius: 6px
+}
+
+.tabs nav {
+       TEXT-ALIGN: left;
+       box-shadow: inset 0px -10px 12px -7px rgba(0, 0, 0, 0.2);
+       -webkit-box-shadow: inset 0px -10px 12px -7px rgba(0, 0, 0, 0.2);
+       -moz-box-shadow: inset 0px -10px 12px -7px rgba(0, 0, 0, 0.2)
+}
+
+.tabs nav A {
+       PADDING-BOTTOM: 0px;
+       LINE-HEIGHT: 42px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       DISPLAY: block;
+       WHITE-SPACE: nowrap;
+       COLOR: #067ab4;
+       FONT-SIZE: 14px;
+       PADDING-TOP: 0px
+}
+
+.tabs nav A :before {
+       DISPLAY: inline-block;
+       VERTICAL-ALIGN: middle;
+       -webkit-font-smoothing: antialiased
+}
+
+.tabs nav UL {
+       PADDING-BOTTOM: 0px;
+       LIST-STYLE-TYPE: none;
+       MARGIN: 0px 0px -5px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       DISPLAY: inline-block;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 0px
+}
+
+.tabs nav UL LI {
+       BORDER-BOTTOM: medium none;
+       POSITION: relative;
+       PADDING-BOTTOM: 1px;
+       OVERFLOW-X: hidden;
+       PADDING-LEFT: 0px;
+       WIDTH: 48px;
+       PADDING-RIGHT: 0px;
+       DISPLAY: block;
+       FLOAT: left;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 1px;
+       transition-property: width;
+       transition-duration: 0.5s;
+       -webkit-transition-property: width;
+       -webkit-transition-duration: 0.5s
+}
+
+.tabs nav UL LI .tab-current {
+       Z-INDEX: 100;
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       box-shadow: inset 0 2px #47a3da
+}
+
+.tabs nav UL LI A {
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.tabs nav UL LI A :hover {
+       COLOR: #067ab4
+}
+
+.tabs nav UL LI:first-child {
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 6px 0 0 0
+}
+
+.tabs nav LI.tab-current {
+       BORDER-BOTTOM: white 1px solid;
+       BACKGROUND-COLOR: #fff;
+       WIDTH: 135px;
+       transition-property: width;
+       transition-duration: 0.5s;
+       -webkit-transition-property: width;
+       -webkit-transition-duration: 0.5s
+}
+
+.tabs nav LI.tab-current:before {
+       POSITION: absolute;
+       BACKGROUND-COLOR: #ccc;
+       WIDTH: 1000px;
+       BOTTOM: 0px;
+       HEIGHT: 1px;
+       CONTENT: '';
+       RIGHT: 100%
+}
+
+.tabs nav LI.tab-current:after {
+       POSITION: absolute;
+       BACKGROUND-COLOR: #ccc;
+       WIDTH: 1000px;
+       BOTTOM: 0px;
+       HEIGHT: 1px;
+       CONTENT: '';
+       RIGHT: 100%
+}
+
+.tabs nav LI.tab-current:after {
+       WIDTH: 4000px;
+       RIGHT: auto;
+       LEFT: 100%
+}
+
+.tabs .content {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       MIN-HEIGHT: 500px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       HEIGHT: 500px;
+       OVERFLOW: auto;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 0px;
+       border-radius: 0;
+       resize: vertical
+}
+
+.tabs .content section {
+       MARGIN: 0px auto;
+       DISPLAY: none
+}
+
+.tabs .content section.content-current {
+       DISPLAY: block
+}
+
+.tabs .content :before {
+       CONTENT: ''
+}
+
+.tabs .content :after {
+       CONTENT: ''
+}
+
+.tabs .content :after {
+       CLEAR: both
+}
+
+.tabs .no-js .content section {
+       BORDER-BOTTOM: #47a3da 1px solid;
+       PADDING-BOTTOM: 2em;
+       DISPLAY: block
+}
+
+.tabs .mediabox {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 25px;
+       PADDING-RIGHT: 25px;
+       FLOAT: left;
+       PADDING-TOP: 0px
+}
+
+.tabs .mediabox P {
+       LINE-HEIGHT: 24px
+}
+
+.tabs .mediabox P H4 {
+       FONT-FAMILY: "Omnes Regular Medium", Arial, Serif;
+       FONT-SIZE: 24px
+}
+
+.tabs .mediabox A {
+       LINE-HEIGHT: 32px;
+       DISPLAY: block;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.tabs .mediabox A:hover {
+       LINE-HEIGHT: 32px;
+       DISPLAY: block;
+       COLOR: #067ab4;
+       TEXT-DECORATION: none
+}
+
+.tabs .mediabox H5 {
+       FONT-SIZE: 20px
+}
+
+.tabs .mediabox UL LI {
+       LINE-HEIGHT: 24px;
+       MARGIN-TOP: 5px
+}
+
+.tabs .mediabox OL LI {
+       LINE-HEIGHT: 24px;
+       MARGIN-TOP: 5px
+}
+
+.tabs .mediabox UL LI:before {
+       CONTENT: none
+}
+
+.tabs .mediabox OL LI:before {
+       CONTENT: none
+}
+
+.activity-list-header {
+       DISPLAY: inline-block
+}
+
+.activity-list-header H4 {
+       FONT-SIZE: 28px
+}
+
+.filter {
+       FLOAT: right !important
+}
+
+.filter .title {
+       DISPLAY: inline-block
+}
+
+.filter .dd {
+       PADDING-LEFT: 15px;
+       WIDTH: 250px;
+       DISPLAY: inline-block
+}
+
+.activity-list {
+       BACKGROUND-COLOR: #fff;
+       COLOR: #666666;
+       CLEAR: both;
+       box-shadow: -2px 0 rgba(0, 0, 0, 0.05), 2px 4px rgba(0, 0, 0, 0.05)
+}
+
+.activity-list .activity-tabs-header {
+       MARGIN-TOP: 15px;
+       WIDTH: 101%
+}
+
+.activity-list .activity-tabs-header .at-header {
+       DISPLAY: inline-block;
+       FLOAT: left;
+       HEIGHT: 58px
+}
+
+.activity-list .activity-tabs-header .at-tabs {
+       DISPLAY: inline-block;
+       FLOAT: left;
+       HEIGHT: 58px
+}
+
+.activity-list .activity-tabs-header .at-header {
+       PADDING-BOTTOM: 18px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 18px;
+       WIDTH: 60%;
+       PADDING-RIGHT: 18px;
+       PADDING-TOP: 18px;
+       border-radius: 5px 0 0 0
+}
+
+.activity-list .activity-tabs-header .at-header H3 {
+       MARGIN-TOP: -3px;
+       COLOR: #fff;
+       FONT-SIZE: 24px
+}
+
+.activity-list .activity-tabs-header .at-tabs {
+       WIDTH: 39%;
+       COLOR: #067ab4;
+       border-radius: 0
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav {
+       BACKGROUND-COLOR: #067ab4;
+       HEIGHT: 58px;
+       border-radius: 0 10px 0 0
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav .nav-tabs {
+       BORDER-LEFT: 0px;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       box-shadow: inset 0 -13px 10px -15px rgba(0, 0, 0, 0.3);
+       border-radius: 0 10px 0 0;
+       -webkit-box-shadow: inset 0 -1px 10px -15px rgba(0, 0, 0, 0.3);
+       -moz-box-shadow: inset 0 -13px 10px -15px rgba(0, 0, 0, 0.3)
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL {
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 0px;
+       FLOAT: right
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI {
+       BORDER-BOTTOM: 0px;
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 9px;
+       PADDING-LEFT: 0px;
+       WIDTH: 140px;
+       PADDING-RIGHT: 10px;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 10px;
+       border-radius: 0
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI>A {
+       BORDER-BOTTOM: 0px;
+       POSITION: relative;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 9px;
+       PADDING-LEFT: 0px;
+       WIDTH: 140px;
+       PADDING-RIGHT: 10px;
+       DISPLAY: inline-block;
+       COLOR: #067ab4;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 10px;
+       border-radius: 0
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI .activity-num
+       {
+       BACKGROUND-IMAGE: url(../images/blue_circle.png);
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       WIDTH: 22px;
+       BACKGROUND-REPEAT: no-repeat;
+       HEIGHT: 22px;
+       COLOR: #fff;
+       FONT-SIZE: 10px;
+       TOP: -8px;
+       RIGHT: -17px
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI .claimed-num
+       {
+       BACKGROUND-IMAGE: url(../images/blue_circle.png);
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       WIDTH: 22px;
+       BACKGROUND-REPEAT: no-repeat;
+       HEIGHT: 22px;
+       COLOR: #fff;
+       FONT-SIZE: 10px;
+       TOP: -8px;
+       RIGHT: -17px
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI>A .activity-num
+       {
+       BACKGROUND-IMAGE: url(../images/blue_circle.png);
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       WIDTH: 22px;
+       BACKGROUND-REPEAT: no-repeat;
+       HEIGHT: 22px;
+       COLOR: #fff;
+       FONT-SIZE: 10px;
+       TOP: -8px;
+       RIGHT: -17px
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI>A .claimed-num
+       {
+       BACKGROUND-IMAGE: url(../images/blue_circle.png);
+       Z-INDEX: 10;
+       POSITION: absolute;
+       TEXT-ALIGN: center;
+       WIDTH: 22px;
+       BACKGROUND-REPEAT: no-repeat;
+       HEIGHT: 22px;
+       COLOR: #fff;
+       FONT-SIZE: 10px;
+       TOP: -8px;
+       RIGHT: -17px
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI {
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI>A:hover {
+       BACKGROUND-COLOR: transparent
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI.active {
+       BACKGROUND-COLOR: #fff
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI.active A {
+       BACKGROUND-COLOR: transparent
+}
+
+.activity-list .activity-tabs-header .at-tabs .at-nav UL LI.active A:hover
+       {
+       BACKGROUND-COLOR: transparent
+}
+
+.activity-list .sort {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       TEXT-TRANSFORM: uppercase;
+       BACKGROUND-COLOR: #fff;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       DISPLAY: block;
+       FONT-SIZE: 12px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.activity-list .sort .caret {
+       MARGIN-TOP: -7px;
+       MARGIN-LEFT: 5px
+}
+
+.activity-list .sort .sortaction {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 20px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 20px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .sort .progr {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 20px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 20px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .sort .due {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 23px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 23px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .sort .actname {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 19px;
+       WIDTH: 15%;
+       PADDING-RIGHT: 19px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .sort .srcname {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 13px;
+       WIDTH: 15%;
+       PADDING-RIGHT: 13px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .sort .status {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 10px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 10px;
+       PADDING-TOP: 10px
+}
+
+.activity-list .activityrow {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.activity-list .activityrow .act-name {
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       WIDTH: 15%;
+       PADDING-RIGHT: 11px;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .act-name .title {
+       WIDTH: 80%;
+       FLOAT: left
+}
+
+.activity-list .activityrow .act-name .title {
+       DISPLAY: block;
+       COLOR: #067ab4;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .act-name .title A {
+       DISPLAY: block;
+       COLOR: #067ab4;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .act-name .title A:hover {
+       DISPLAY: block;
+       COLOR: #067ab4;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .act-name .projectname {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       COLOR: #666666;
+       FONT-SIZE: 14px
+}
+
+.activity-list .activityrow .act-name .projectid {
+       MARGIN-TOP: 5px;
+       DISPLAY: block;
+       FLOAT: left;
+       COLOR: #666666;
+       FONT-SIZE: 14px
+}
+
+.activity-list .activityrow .act-name .icon {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 10px;
+       FLOAT: right;
+       PADDING-TOP: 10px
+}
+
+.activity-list .activityrow .act-name .glyphicon-chevron-down {
+       CURSOR: pointer
+}
+
+.activity-list .activityrow .act-name .glyphicon-chevron-up {
+       CURSOR: pointer
+}
+
+.activity-list .activityrow .act-name .progress {
+       BACKGROUND-COLOR: transparent;
+       MARGIN-TOP: 5px;
+       DISPLAY: block;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FLOAT: left;
+       HEIGHT: auto;
+       COLOR: #666666;
+       OVERFLOW: auto;
+       box-shadow: none;
+       border-radius: 0
+}
+
+.activity-list .activityrow .proj-name {
+       BACKGROUND-COLOR: #fff;
+       WIDTH: 15%
+}
+
+.activity-list .activityrow .proj-name .projectname {
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .proj-name .projectname A {
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .proj-name .projectname A:hover {
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .proj-name .projectid {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .proj-name .projectid A {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .proj-name .projectid A:hover {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 14px;
+       TEXT-DECORATION: none
+}
+
+.activity-list .activityrow .act-descrip {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       BACKGROUND-COLOR: #fff;
+       WIDTH: 100%;
+       FLOAT: left;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.activity-list .activityrow .act-descrip .descrip {
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       LINE-HEIGHT: 22px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       HEIGHT: 110px;
+       FONT-SIZE: 13px;
+       PADDING-TOP: 20px
+}
+
+.activity-list .activityrow .act-descrip .estimate {
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 20px;
+       LINE-HEIGHT: 22px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       HEIGHT: 110px;
+       FONT-SIZE: 13px;
+       PADDING-TOP: 20px
+}
+
+.activity-list .activityrow .act-descrip .gapfill {
+       BACKGROUND-COLOR: #fff;
+       WIDTH: 1%;
+       FLOAT: left
+}
+
+.activity-list .activityrow .act-descrip .descrip {
+       WIDTH: 69%;
+       FLOAT: left
+}
+
+.activity-list .activityrow .act-descrip .estimate {
+       WIDTH: 30%;
+       FLOAT: left;
+       MARGIN-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.activity-list .activityrow .act-descrip .estimate .nnnn {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif
+}
+
+.activity-list .activityrow .act-progress {
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       PADDING-RIGHT: 11px;
+       FLOAT: left;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .act-duedate {
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       PADDING-RIGHT: 11px;
+       FLOAT: left;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .act-status {
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       PADDING-RIGHT: 11px;
+       FLOAT: left;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .act-cta {
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       PADDING-RIGHT: 11px;
+       FLOAT: left;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .proj-name {
+       PADDING-BOTTOM: 11px;
+       PADDING-LEFT: 11px;
+       PADDING-RIGHT: 11px;
+       FLOAT: left;
+       PADDING-TOP: 11px
+}
+
+.activity-list .activityrow .act-duedate {
+       PADDING-BOTTOM: 8px;
+       PADDING-LEFT: 21px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 21px;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       PADDING-TOP: 8px
+}
+
+.activity-list .activityrow .act-duedate .cat {
+       FONT-FAMILY: "Omnes Medium", Arial, Serif
+}
+
+.activity-list .activityrow .act-duedate .cont {
+       LINE-HEIGHT: 22px
+}
+
+.activity-list .activityrow .act-duedate .num {
+       DISPLAY: none
+}
+
+.activity-list .activityrow .act-duedate .due-date {
+       WIDTH: 100%;
+       FLOAT: left
+}
+
+.activity-list .activityrow .act-status {
+       PADDING-BOTTOM: 21px;
+       PADDING-LEFT: 21px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 21px;
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       PADDING-TOP: 21px
+}
+
+.activity-list .activityrow .act-status .cat {
+       FONT-FAMILY: "Omnes Medium", Arial, Serif
+}
+
+.activity-list .activityrow .act-cta {
+       PADDING-BOTTOM: 14px;
+       PADDING-LEFT: 14px;
+       WIDTH: 13%;
+       PADDING-RIGHT: 14px;
+       PADDING-TOP: 14px
+}
+
+.activity-list .activityrow .act-cta .act-btn {
+       PADDING-BOTTOM: 6px;
+       PADDING-LEFT: 0px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       FONT-SIZE: 14px;
+       PADDING-TOP: 6px
+}
+
+.resources H3 {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 10px;
+       MARGIN: 20px -30px 10px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 0px
+}
+
+#actrow4 .act-descrip .descrip {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+#actrow4 .act-descrip .estimate {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.activity-detail-wrapper {
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN-LEFT: 15px
+}
+
+.activity-detail-right {
+       PADDING-BOTTOM: 50px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px
+}
+
+.claimed-arrow {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: absolute;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 5px;
+       WIDTH: 19px;
+       PADDING-RIGHT: 0px;
+       HEIGHT: 35px;
+       BORDER-TOP: #ccc 1px solid;
+       TOP: 16px;
+       CURSOR: pointer;
+       RIGHT: -19px;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 8px;
+       border-radius: 0 4px 4px 0
+}
+
+.sdc-slider {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: 0px;
+       WIDTH: 265px;
+       FLOAT: left;
+       BORDER-TOP: #ccc 1px solid;
+       MARGIN-RIGHT: 0px;
+       BORDER-RIGHT: 0px;
+       border-radius: 2px 0 2px 2px
+}
+
+.resourcecenter.sdc-slider {
+       BORDER-TOP: 0px
+}
+
+.resourcecenter.sdc-slider .claimed-arrow {
+       TOP: 20px
+}
+
+.sdc-slider .btn-toggle {
+       MARGIN: 10px;
+       MIN-HEIGHT: 55px;
+       DISPLAY: block;
+       MAX-HEIGHT: 55px;
+       OVERFLOW: hidden
+}
+
+.sdc-slider .btn-toggle .btn {
+       PADDING-BOTTOM: 5px;
+       LINE-HEIGHT: 20px;
+       PADDING-LEFT: 26px;
+       PADDING-RIGHT: 26px;
+       FONT-SIZE: 15px;
+       PADDING-TOP: 5px
+}
+
+.sdc-slider .btn-toggle .btn .num {
+       FONT-SIZE: 20px
+}
+
+.sdc-slider .btn-toggle .btn-default {
+       BORDER-BOTTOM-COLOR: #ccc;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP-COLOR: #ccc;
+       COLOR: #666666;
+       BORDER-RIGHT-COLOR: #ccc;
+       BORDER-LEFT-COLOR: #ccc
+}
+
+.sdc-slider .btn-toggle .btn-default:hover {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.sdc-slider .btn-toggle .btn-default:focus {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.sdc-slider .btn-toggle .btn-default:active {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.sdc-slider .btn-toggle .active.btn-default {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.sdc-slider .btn-toggle .open .btn-default.dropdown-toggle {
+       BACKGROUND-COLOR: #067ab4;
+       COLOR: #fff
+}
+
+.sdc-slider .icon-claim_slide_left {
+       COLOR: #067ab4 !important;
+       MARGIN-LEFT: -8px !important
+}
+
+.sdc-slider .icon-claim_slide_right {
+       COLOR: #067ab4 !important;
+       MARGIN-LEFT: -8px !important
+}
+
+.sdc-slider .sliderhead {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       PADDING-BOTTOM: 20px;
+       MIN-HEIGHT: 75px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       FONT-SIZE: 13px;
+       OVERFLOW: hidden;
+       PADDING-TOP: 20px
+}
+
+.sdc-slider .sliderhead A.btn {
+       TEXT-ALIGN: center;
+       WIDTH: 100%
+}
+
+.sdc-slider .sliderhead A.btn SPAN {
+       PADDING-RIGHT: 10px
+}
+
+.sdc-slider .dropdown {
+       POSITION: absolute;
+       MIN-WIDTH: 220px;
+       MARGIN-TOP: 0px;
+       BOTTOM: 20px;
+       TOP: 20px;
+       RIGHT: 20px;
+       LEFT: 20px
+}
+
+.sdc-slider .activityrow {
+       BACKGROUND-COLOR: #fff;
+       HEIGHT: 80px;
+       OVERFLOW: hidden;
+       BORDER-TOP: #ccc 1px solid
+}
+
+.sdc-slider .activityrow .activerow {
+       WIDTH: 15px;
+       FLOAT: left;
+       HEIGHT: 100%
+}
+
+.sdc-slider .activityrow .inactiverow {
+       WIDTH: 15px;
+       FLOAT: left;
+       HEIGHT: 100%
+}
+
+.sdc-slider .activityrow .activerow {
+       BACKGROUND-COLOR: #f47b20
+}
+
+.sdc-slider .activityrow .inactiverow {
+       BACKGROUND-COLOR: transparent
+}
+
+.sdc-slider .activityrow .activityinfo {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 10px;
+       FLOAT: left;
+       COLOR: #067ab4;
+       PADDING-TOP: 10px
+}
+
+.sdc-slider .activityrow .activityinfo .actname {
+       FONT-SIZE: 14px
+}
+
+.sdc-slider .activityrow .activityinfo .actprojectid {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 13px
+}
+
+.sdc-slider .activityrow .activityinfo .actprogress {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       COLOR: #666666;
+       FONT-SIZE: 13px
+}
+
+.sdc-slider .resourcerow {
+       BACKGROUND-COLOR: #fff;
+       HEIGHT: 42px;
+       OVERFLOW: hidden;
+       BORDER-TOP: #ccc 1px solid
+}
+
+.sdc-slider .resourcerow .activerow {
+       WIDTH: 15px;
+       FLOAT: left;
+       HEIGHT: 100%
+}
+
+.sdc-slider .resourcerow .inactiverow {
+       WIDTH: 15px;
+       FLOAT: left;
+       HEIGHT: 100%
+}
+
+.sdc-slider .resourcerow .activerow {
+       BACKGROUND-COLOR: #f47b20
+}
+
+.sdc-slider .resourcerow .inactiverow {
+       BACKGROUND-COLOR: transparent
+}
+
+.sdc-slider .resourcerow A.resourcename {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 30px;
+       WIDTH: 100%;
+       PADDING-RIGHT: 0px;
+       DISPLAY: block;
+       COLOR: #067ab4;
+       FONT-SIZE: 14px;
+       PADDING-TOP: 10px
+}
+
+.sdc-slider #activityrow-first {
+       box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08);
+       -webkit-box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08);
+       -moz-box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08)
+}
+
+.sdc-slider #resourcerow-first {
+       box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08);
+       -webkit-box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08);
+       -moz-box-shadow: inset 0px 4px 5px -1px rgba(0, 0, 0, 0.08)
+}
+
+.background-open {
+       
+}
+
+.background-open .sliderhead {
+       OVERFLOW: visible
+}
+
+.background-closed {
+       
+}
+
+.background-closed .sliderhead {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       OVERFLOW: hidden;
+       PADDING-TOP: 0px
+}
+
+.claimed-activities {
+       POSITION: relative;
+       WIDTH: 100%
+}
+
+.claimed-activities .row {
+       MARGIN: 3px 0px 0px
+}
+
+.claimed-activities .row .floatingdate {
+       POSITION: absolute;
+       LINE-HEIGHT: 17px;
+       TOP: 0px;
+       LEFT: 100px
+}
+
+.claimed-activities .row .floatingdate .fldate1 {
+       FONT-SIZE: 14px
+}
+
+.claimed-activities .row .floatingdate .fldate2 {
+       FONT-SIZE: 12px
+}
+
+.claimed-activities .btn-gap {
+       MARGIN-RIGHT: 15px
+}
+
+.claimed-activities .introPanel {
+       WIDTH: 100%
+}
+
+.claimed-activities .progress-timeline {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 20px 0px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 15px;
+       border-radius: 4px
+}
+
+.claimed-activities .progress-timeline .pt-heading {
+       LINE-HEIGHT: 30px;
+       COLOR: #f47b20;
+       FONT-SIZE: 26px
+}
+
+.claimed-activities .progress-timeline .separator {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px -15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 0px
+}
+
+.claimed-activities .progress-timeline .prjname {
+       PADDING-BOTTOM: 20px;
+       FONT-STYLE: italic;
+       COLOR: #067ab4;
+       PADDING-TOP: 10px
+}
+
+.claimed-activities .progress-timeline .timeline {
+       PADDING-BOTTOM: 10px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN: 0px -15px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 5px
+}
+
+.claimed-activities .progress-timeline .timeline .timeline-inner {
+       MAX-WIDTH: 1000px
+}
+
+.claimed-activities .progress-timeline .timeline .phase {
+       TEXT-ALIGN: center;
+       WIDTH: 19%;
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FLOAT: left;
+       COLOR: #b9b9b9;
+       FONT-SIZE: 16px
+}
+
+.claimed-activities .progress-timeline .timeline .phase SPAN {
+       FONT-SIZE: 16px
+}
+
+.claimed-activities .progress-timeline .timeline .phase [class^='icon-']:before
+       {
+       PADDING-RIGHT: 3px;
+       FONT-SIZE: 24px;
+       VERTICAL-ALIGN: middle
+}
+
+.claimed-activities .progress-timeline .timeline .phase .icon-tools:before
+       {
+       FONT-SIZE: 20px
+}
+
+.claimed-activities .progress-timeline .timeline .phase .icon SPAN:before
+       {
+       FONT-SIZE: 45px
+}
+
+.claimed-activities .progress-timeline .timeline .active.phase {
+       COLOR: #f47b20
+}
+
+.claimed-activities .progress-timeline .timeline .complete.phase {
+       COLOR: #666666
+}
+
+.claimed-activities .panel {
+       MARGIN-BOTTOM: 14px
+}
+
+.claimed-activities .panel .panel-body {
+       
+}
+
+.claimed-activities .panel .panel-body FORM P {
+       FONT-FAMILY: "Omnes Regular", Arial, Serif;
+       FONT-SIZE: 16px;
+       FONT-WEIGHT: 400
+}
+
+.claimed-activities .panel H4 {
+       FONT-SIZE: 20px
+}
+
+.claimed-activities .panel H5 {
+       FONT-SIZE: 20px
+}
+
+.claimed-activities .panel .attachment {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 5px;
+       WIDTH: 50%;
+       PADDING-RIGHT: 5px;
+       DISPLAY: inline-block;
+       MARGIN-BOTTOM: 10px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 5px
+}
+
+.claimed-activities .panel .attachment .icon-file {
+       COLOR: #666666;
+       MARGIN-RIGHT: 8px
+}
+
+.claimed-activities .panel .close-icon {
+       DISPLAY: inline-block;
+       COLOR: #666666;
+       MARGIN-LEFT: 5px;
+       FONT-SIZE: 26px;
+       VERTICAL-ALIGN: middle
+}
+
+.claimed-activities .panel .attach-icon {
+       DISPLAY: block;
+       COLOR: #ff0000;
+       MARGIN-LEFT: 5px;
+       FONT-SIZE: 24px;
+       VERTICAL-ALIGN: middle
+}
+
+.claimed-activities .panel .btn-attach {
+       PADDING-BOTTOM: 5px;
+       BACKGROUND-COLOR: #067ab4;
+       PADDING-LEFT: 10px;
+       PADDING-RIGHT: 10px;
+       DISPLAY: inline-block;
+       COLOR: #fff;
+       FONT-SIZE: 24px;
+       VERTICAL-ALIGN: middle;
+       CURSOR: pointer;
+       MARGIN-RIGHT: 10px;
+       PADDING-TOP: 5px;
+       border-radius: 4px
+}
+
+.claimed-activities .panel TEXTAREA.form-control {
+       WIDTH: 100%
+}
+
+.claimed-activities .panel .btn-gap {
+       MARGIN-LEFT: 15px
+}
+
+.claimed-activities .panel .btn {
+       WIDTH: 80px
+}
+
+.content:before {
+       DISPLAY: table;
+       CONTENT: ''
+}
+
+.content:after {
+       DISPLAY: table;
+       CONTENT: ''
+}
+
+.summary-cont:before {
+       DISPLAY: table;
+       CONTENT: ''
+}
+
+.summary-cont:after {
+       DISPLAY: table;
+       CONTENT: ''
+}
+
+.content:after {
+       CLEAR: both
+}
+
+.summary-cont:after {
+       CLEAR: both
+}
+
+INPUT[type='checkbox']+LABEL {
+       PADDING-LEFT: 30px;
+       FONT-FAMILY: "Omnes Medium", Arial, Serif;
+       BACKGROUND: url(../images/checkbox_off.png) no-repeat;
+       HEIGHT: 19px;
+       FONT-WEIGHT: 400
+}
+
+.iframe {
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN-TOP: -8px;
+       WIDTH: 75%;
+       MARGIN-BOTTOM: 50px;
+       FLOAT: right;
+       MAX-HEIGHT: 565px;
+       MARGIN-RIGHT: -15px
+}
+
+.iframe .iframe-content {
+       BORDER-BOTTOM: #ccc 1px solid;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 40px;
+       OVERFLOW-X: hidden;
+       OVERFLOW-Y: scroll;
+       BACKGROUND-COLOR: #fff;
+       MARGIN: 30px;
+       PADDING-LEFT: 40px;
+       PADDING-RIGHT: 40px;
+       COLOR: #666666;
+       MAX-HEIGHT: 87%;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 40px
+}
+
+.breadcrumb {
+       PADDING-BOTTOM: 8px;
+       BACKGROUND-COLOR: transparent;
+       LIST-STYLE-TYPE: none;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 20px;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 8px;
+       border-radius: 0
+}
+
+.error {
+       COLOR: #b30a3c;
+       VERTICAL-ALIGN: middle
+}
+
+.error .glyphicon {
+       MARGIN-RIGHT: 8px
+}
+
+.error .remaining {
+       BORDER-BOTTOM: #b30a3c 1px solid;
+       BORDER-LEFT: #b30a3c 1px solid;
+       PADDING-BOTTOM: 3px;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       FONT-SIZE: 12px;
+       BORDER-TOP: #b30a3c 1px solid;
+       BORDER-RIGHT: #b30a3c 1px solid;
+       PADDING-TOP: 3px;
+       border-radius: 3px
+}
+
+.fair {
+       COLOR: #f47b20;
+       VERTICAL-ALIGN: middle
+}
+
+.fair .glyphicon {
+       MARGIN-RIGHT: 8px
+}
+
+.good {
+       COLOR: #4ca90c;
+       VERTICAL-ALIGN: middle;
+       MARGIN-RIGHT: 10px
+}
+
+.good .glyphicon {
+       MARGIN-RIGHT: 8px
+}
+
+.remaining {
+       BORDER-BOTTOM: #ccc 1px solid;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 3px;
+       PADDING-LEFT: 5px;
+       PADDING-RIGHT: 5px;
+       FONT-SIZE: 12px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 3px;
+       border-radius: 3px
+}
+
+.star-active {
+       COLOR: #fcb314
+}
+
+.star-inactive {
+       COLOR: #f3f3f3
+}
+
+.emphasistext {
+       FONT-FAMILY: "Omnes Regular Medium", Arial, Serif
+}
+
+.notAuth {
+       TEXT-ALIGN: center;
+       BACKGROUND-COLOR: #f3f3f3
+}
+
+.unsuppored-browser {
+       TEXT-ALIGN: center;
+       BACKGROUND-COLOR: #f3f3f3
+}
+
+.notAuth header {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.notAuth .content {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.unsuppored-browser header {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.unsuppored-browser .content {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BACKGROUND-COLOR: #f3f3f3;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.notAuth H2 {
+       MARGIN-BOTTOM: 40px
+}
+
+.unsuppored-browser H2 {
+       MARGIN-BOTTOM: 40px
+}
+
+.notAuth P {
+       MARGIN-BOTTOM: 20px
+}
+
+.unsuppored-browser P {
+       MARGIN-BOTTOM: 20px
+}
+
+.notAuth .linkarea {
+       TEXT-ALIGN: center;
+       MARGIN: 0px auto;
+       WIDTH: 90%
+}
+
+.unsuppored-browser .linkarea {
+       TEXT-ALIGN: center;
+       MARGIN: 0px auto;
+       WIDTH: 90%
+}
+
+.notAuth .linkarea A {
+       DISPLAY: inline-block;
+       MARGIN-RIGHT: 30px
+}
+
+.unsuppored-browser .linkarea A {
+       DISPLAY: inline-block;
+       MARGIN-RIGHT: 30px
+}
+
+.notAuth .linkarea A SPAN {
+       DISPLAY: block
+}
+
+.unsuppored-browser .linkarea A SPAN {
+       DISPLAY: block
+}
+
+.error404 .content {
+       BORDER-BOTTOM: medium none;
+       TEXT-ALIGN: center;
+       BORDER-LEFT: medium none;
+       HEIGHT: 600px;
+       BORDER-TOP: medium none;
+       BORDER-RIGHT: medium none
+}
+
+.error404 H3 {
+       MARGIN-BOTTOM: 40px
+}
+
+.modal.notifications .modal-dialog {
+       WIDTH: 50%
+}
+
+.modal.notifications .modal-dialog .modal-header {
+       PADDING-BOTTOM: 0px;
+       MARGIN-TOP: 20px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       MARGIN-BOTTOM: 0px;
+       HEIGHT: 40px;
+       PADDING-TOP: 0px
+}
+
+.modal.notifications .modal-dialog .modal-header .modal-title {
+       MARGIN-LEFT: 0px
+}
+
+.modal.notifications .modal-dialog .modal-body {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.modal.notifications .modal-dialog .modal-body .row {
+       BORDER-BOTTOM: #b9b9b9 1px solid
+}
+
+.modal.notifications .modal-dialog .modal-body .row .row-inner {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 10px
+}
+
+.modal.notifications .modal-dialog .modal-body .row .row-content {
+       WIDTH: 80%;
+       FLOAT: left
+}
+
+.modal.notifications .modal-dialog .modal-body .row BUTTON {
+       MARGIN-TOP: 20px;
+       FLOAT: right;
+       MARGIN-RIGHT: 20px
+}
+
+.modal.notifications .modal-dialog .notifications-list {
+       OVERFLOW-X: hidden;
+       OVERFLOW-Y: scroll;
+       MAX-HEIGHT: 300px
+}
+
+.modal.notifications .modal-dialog .modal-footer {
+       PADDING-BOTTOM: 20px;
+       MARGIN-TOP: 0px;
+       PADDING-LEFT: 35px;
+       PADDING-RIGHT: 35px;
+       HEIGHT: 40px;
+       PADDING-TOP: 10px;
+       box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2);
+       -webkit-box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2);
+       -moz-box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2)
+}
+
+.modal.notifications .modal-dialog .modal-footer P {
+       FLOAT: left
+}
+
+.modal.feedback .modal-dialog {
+       WIDTH: 50%
+}
+
+.modal.feedback .modal-dialog .modal-header {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.modal.feedback .modal-dialog .modal-header A {
+       PADDING-RIGHT: 15px
+}
+
+.modal.feedback .modal-dialog .modal-header A SPAN {
+       PADDING-RIGHT: 0px
+}
+
+.modal.feedback .modal-dialog .modal-title {
+       COLOR: #666666;
+       MARGIN-LEFT: 11px;
+       FONT-SIZE: 24px
+}
+
+.modal.feedback .modal-dialog H4 {
+       MARGIN-LEFT: 11px
+}
+
+.modal.feedback .modal-dialog H5 {
+       MARGIN-LEFT: 11px
+}
+
+.modal.feedback .modal-dialog .modal-body {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.modal.feedback .modal-dialog .modal-body .dropdown {
+       MARGIN-TOP: 5px;
+       WIDTH: 60%;
+       DISPLAY: inline-block
+}
+
+.modal.feedback .modal-dialog .modal-body .optional.dropdown:after {
+       FONT-STYLE: italic;
+       DISPLAY: inline;
+       CONTENT: 'Optional'
+}
+
+.modal.feedback .modal-dialog .modal-body INPUT {
+       WIDTH: 75%
+}
+
+.modal.feedback .modal-dialog .modal-body TEXTAREA {
+       BORDER-BOTTOM-COLOR: #ccc;
+       BORDER-TOP-COLOR: #ccc;
+       WIDTH: 100%;
+       BORDER-RIGHT-COLOR: #ccc;
+       BORDER-LEFT-COLOR: #ccc;
+       border-radius: 4px
+}
+
+.modal.feedback .modal-dialog .modal-body .optional {
+       MARGIN-LEFT: 15px
+}
+
+.modal.feedback .modal-dialog .modal-body .optional-info INPUT {
+       WIDTH: 50%;
+       FLOAT: left;
+       CLEAR: both
+}
+
+.modal.feedback .modal-dialog .modal-body .optional-info .optional {
+       MARGIN-TOP: 5px;
+       DISPLAY: inline-block;
+       FONT-SIZE: 12px
+}
+
+.modal.feedback .modal-dialog .modal-body .row {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.modal.feedback .modal-dialog .modal-body .row .row-inner {
+       PADDING-BOTTOM: 10px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 10px
+}
+
+.modal.feedback .modal-dialog .modal-body .row .row-content {
+       WIDTH: 80%;
+       FLOAT: left;
+       MARGIN-LEFT: 11px
+}
+
+.modal.feedback .modal-dialog .modal-body .row .row-content H5 {
+       MARGIN-LEFT: 0px
+}
+
+.modal.feedback .modal-dialog .modal-body .row LABEL {
+       MARGIN-TOP: 10px;
+       DISPLAY: block;
+       MARGIN-BOTTOM: 5px;
+       FONT-WEIGHT: normal
+}
+
+.modal.feedback .modal-dialog .modal-body .row BUTTON {
+       MARGIN-TOP: 20px;
+       FLOAT: right;
+       MARGIN-RIGHT: 20px
+}
+
+.modal.feedback .modal-dialog .feedback-form {
+       OVERFLOW-X: hidden;
+       OVERFLOW-Y: scroll;
+       MAX-HEIGHT: 300px
+}
+
+.modal.feedback .modal-dialog .modal-footer {
+       PADDING-BOTTOM: 20px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN-TOP: 0px;
+       PADDING-LEFT: 20px;
+       PADDING-RIGHT: 20px;
+       HEIGHT: 60px;
+       PADDING-TOP: 10px;
+       box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2);
+       -webkit-box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2);
+       -moz-box-shadow: 0 -13px 10px -15px rgba(0, 0, 0, 0.2)
+}
+
+H4.desktop-only {
+       TEXT-ALIGN: center
+}
+
+.activitydetail.sdc-slider .sliderhead {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 15px
+}
+
+.activitydetail.sdc-slider .searcher.sliderhead INPUT {
+       BORDER-BOTTOM: #bbb 1px solid;
+       POSITION: absolute;
+       MIN-WIDTH: 230px;
+       BORDER-LEFT: #bbb 1px solid;
+       MARGIN-TOP: 0px;
+       PADDING-LEFT: 30px;
+       BOTTOM: 20px;
+       HEIGHT: 32px;
+       FONT-SIZE: 14px;
+       BORDER-TOP: #bbb 1px solid;
+       TOP: 20px;
+       RIGHT: 15px;
+       BORDER-RIGHT: #bbb 1px solid;
+       LEFT: 15px;
+       border-radius: 4px
+}
+
+.activitydetail.sdc-slider .searcher.sliderhead SPAN {
+       Z-INDEX: 10;
+       POSITION: absolute;
+       MARGIN-TOP: 0px;
+       WIDTH: 20px;
+       BOTTOM: 20px;
+       DISPLAY: block;
+       HEIGHT: 20px;
+       COLOR: #ccc;
+       FONT-SIZE: 23px;
+       TOP: 24px;
+       LEFT: 20px
+}
+
+.activitydetail.sdc-slider .btn-toggle {
+       MARGIN: 0px
+}
+
+.activitydetail.sdc-slider .btn-toggle-inside {
+       POSITION: absolute;
+       MIN-WIDTH: 220px;
+       MARGIN-TOP: 0px;
+       BOTTOM: 10px;
+       TOP: 10px;
+       RIGHT: 10px;
+       LEFT: 10px
+}
+
+.activitydetail.sdc-slider .btn-toggle-inside INPUT[type='radio'] {
+       DISPLAY: none
+}
+
+.activitydetail.sdc-slider .btn-toggle-inside .btn:first-child {
+       border-radius: 4px 0 0 4px
+}
+
+.background-closed.activitydetail.sdc-slider .btn-toggle {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.background-closed.activitydetail.sdc-slider .sliderhead {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.sdc-hero-images {
+       PADDING-BOTTOM: 15px;
+       MARGIN-RIGHT: -15px
+}
+
+.sdc-hero-images .tab-pane {
+       MIN-HEIGHT: 450px;
+       MAX-HEIGHT: 450px;
+       OVERFLOW: hidden;
+       border-radius: 4px 0 0 4px
+}
+
+.sdc-hero-images .tab-pane .bg {
+       POSITION: relative;
+       BACKGROUND-COLOR: #f47b20;
+       WIDTH: 100%;
+       FLOAT: left;
+       HEIGHT: 100%
+}
+
+.sdc-hero-images .tab-pane .bg .text {
+       Z-INDEX: 200;
+       POSITION: absolute;
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 30px;
+       WIDTH: 40%;
+       PADDING-RIGHT: 90px;
+       FLOAT: left;
+       PADDING-TOP: 30px
+}
+
+.sdc-hero-images .tab-pane .bg .text H2 {
+       PADDING-BOTTOM: 15px;
+       COLOR: #fff
+}
+
+.sdc-hero-images .tab-pane .bg .text P {
+       PADDING-BOTTOM: 15px;
+       COLOR: #fff
+}
+
+.sdc-hero-images .tab-pane .bg .text P {
+       FONT-SIZE: 15px
+}
+
+.sdc-hero-images .tab-pane .bg .text H2 {
+       MARGIN: 0px;
+       FONT-SIZE: 40px
+}
+
+.sdc-hero-images .tab-pane .bg .imgwrap {
+       POSITION: relative;
+       WIDTH: 75%;
+       FLOAT: right;
+       HEIGHT: 450px
+}
+
+.sdc-hero-images .tab-pane .bg .imgwrap IMG.overlay {
+       POSITION: absolute;
+       TOP: 0px;
+       LEFT: 0px
+}
+
+.sdc-hero-images .tab-pane .bg .imgwrap IMG.photo {
+       WIDTH: 100%;
+       DISPLAY: block;
+       HEIGHT: auto;
+       MAX-HEIGHT: none
+}
+
+.sdc-hero-nav {
+       MARGIN-LEFT: -15px
+}
+
+.sdc-hero-nav .nav-pills {
+       DISPLAY: block
+}
+
+.sdc-hero-nav .nav-pills LI {
+       BOX-SIZING: border-box;
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: medium none;
+       LINE-HEIGHT: 90px;
+       MARGIN: 0px;
+       HEIGHT: 90px;
+       FONT-SIZE: 16px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 0
+}
+
+.sdc-hero-nav .nav-pills LI:first-child {
+       BORDER-TOP: #ccc 1px solid
+}
+
+.sdc-hero-nav .nav-pills LI.active {
+       BORDER-BOTTOM: medium none;
+       BORDER-LEFT: medium none;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 0
+}
+
+.sdc-hero-nav .nav-pills LI.active:first-child {
+       BORDER-TOP: #ccc 1px solid
+}
+
+.sdc-hero-nav .nav-pills LI.active A {
+       BACKGROUND: none transparent scroll repeat 0% 0%;
+       COLOR: #f47b20;
+       BORDER-RIGHT: #f47b20 15px solid
+}
+
+.sdc-hero-nav .nav-pills LI A {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 0px;
+       VERTICAL-ALIGN: middle;
+       PADDING-TOP: 0px;
+       border-radius: 0
+}
+
+.sdc-hero-nav .nav-pills LI A:hover {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+.sdc-hero-nav .mobile-menu {
+       DISPLAY: none
+}
+
+.main-page-panel {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN-BOTTOM: 30px;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       border-radius: 4px
+}
+
+.main-page-panel H4 {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       MARGIN: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 15px;
+       COLOR: #f47b20;
+       FONT-SIZE: 24px;
+       PADDING-TOP: 10px
+}
+
+.main-page-panel .content {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       MIN-HEIGHT: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.main-page-panel .content .summary-btn {
+       MARGIN-TOP: 23px
+}
+
+.main-page-panel .content H5 {
+       PADDING-BOTTOM: 10px;
+       FONT-SIZE: 20px
+}
+
+.main-page-panel .content .summary {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       BACKGROUND-COLOR: #f3f3f3;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.main-page-panel .content .block {
+       BORDER-BOTTOM: #ccc 1px solid;
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 30px
+}
+
+.main-page-panel .content .selectors.block {
+       PADDING-BOTTOM: 25px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 20px
+}
+
+.main-page-panel .content .selectors.block H5 {
+       PADDING-BOTTOM: 0px;
+       LINE-HEIGHT: 1;
+       MARGIN-TOP: 0px;
+       MARGIN-BOTTOM: 10px;
+       FONT-SIZE: 14px
+}
+
+.main-page-panel .content .row.block {
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 15px
+}
+
+.main-page-panel .content .block P {
+       MARGIN: 0px 0px 10px
+}
+
+.main-page-panel .content .block IMG {
+       DISPLAY: block;
+       MAX-WIDTH: 100%
+}
+
+.main-page-panel .content .block H3 {
+       LINE-HEIGHT: 1;
+       COLOR: #666666;
+       FONT-SIZE: 17px
+}
+
+.main-page-panel .content .panel .panel-heading {
+       LINE-HEIGHT: 1;
+       FONT-SIZE: 16px
+}
+
+.main-page-panel .content .panel .panel-heading .ico-default {
+       PADDING-BOTTOM: 15px;
+       MARGIN: -15px 5px -15px -15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BACKGROUND: #f47b20;
+       COLOR: #fff;
+       PADDING-TOP: 15px;
+       border-radius: 4px 0 0 0
+}
+
+.main-page-panel .content .tab-sdc {
+       BACKGROUND-COLOR: #fff;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       border-radius: 4px
+}
+
+.main-page-panel .content .tab-sdc .nav {
+       BACKGROUND-COLOR: #f3f3f3
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs {
+       BORDER-BOTTOM: #ccc 1px solid
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs LI.active:first-child A {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs LI.active A {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: #ccc 1px solid;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs LI.active A:hover {
+       BACKGROUND: #fff
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs LI A {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px
+}
+
+.main-page-panel .content .tab-sdc .nav-tabs LI A:hover {
+       BACKGROUND: none transparent scroll repeat 0% 0%;
+       BORDER-TOP: 0px
+}
+
+.main-page-panel .content .tab-sdc .tab-content .tab-pane .newsitem {
+       BORDER-BOTTOM: #b9b9b9 1px solid;
+       PADDING-BOTTOM: 30px;
+       PADDING-LEFT: 30px;
+       PADDING-RIGHT: 30px;
+       PADDING-TOP: 30px
+}
+
+.main-page-panel .content .tab-sdc .tab-content .pic IMG {
+       WIDTH: 50px;
+       FLOAT: left;
+       MARGIN-RIGHT: 10px
+}
+
+.main-page-panel .content .tab-sdc .tab-content .headline {
+       WIDTH: 66%;
+       FLOAT: left
+}
+
+.main-page-panel .content .tab-sdc .tab-content .headline H4 {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 5px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       COLOR: #666666;
+       FONT-SIZE: 16px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.main-page-panel .content .tab-sdc .tab-content .headline .descrip {
+       FONT-FAMILY: "Omnes Regular Italic", Arial, Serif;
+       FONT-SIZE: 13px
+}
+
+.main-page-panel .content .tab-sdc .tab-content .detail P {
+       CLEAR: both;
+       PADDING-TOP: 10px
+}
+
+TABLE.dataTable.sdc_table {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       MARGIN-TOP: 0px !important;
+       BORDER-SPACING: 0;
+       WIDTH: 100%;
+       BORDER-COLLAPSE: collapse;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+TABLE.dataTable.sdc_table THEAD TH {
+       BORDER-BOTTOM: #ccc 1px solid;
+       MIN-WIDTH: 90px;
+       BORDER-LEFT: 0px;
+       TEXT-TRANSFORM: uppercase;
+       BORDER-TOP: 0px;
+       FONT-WEIGHT: normal;
+       BORDER-RIGHT: 0px
+}
+
+TABLE.dataTable.sdc_table TD {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       FLOAT: none;
+       PADDING-TOP: 15px
+}
+
+TABLE.dataTable.sdc_table TH {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       FLOAT: none;
+       PADDING-TOP: 15px
+}
+
+TABLE.dataTable.sdc_table TH.sorting_asc {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+TABLE.dataTable.sdc_table TH.sorting_desc {
+       BACKGROUND: none transparent scroll repeat 0% 0%
+}
+
+TABLE.dataTable.sdc_table TD {
+       BORDER-BOTTOM: #ccc 1px solid;
+       BORDER-LEFT: #ccc 1px solid;
+       WIDTH: auto;
+       VERTICAL-ALIGN: top;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid
+}
+
+TABLE.dataTable.sdc_table .act-cta {
+       WIDTH: auto;
+       FLOAT: none
+}
+
+TABLE.dataTable.sdc_table .act-name {
+       WIDTH: auto;
+       FLOAT: none
+}
+
+TABLE.dataTable.sdc_table .proj-name {
+       WIDTH: auto;
+       FLOAT: none
+}
+
+TABLE.dataTable.sdc_table .act-duedate {
+       WIDTH: auto;
+       FLOAT: none
+}
+
+TABLE.dataTable.sdc_table .act-status {
+       WIDTH: auto;
+       FLOAT: none
+}
+
+TABLE.dataTable.sdc_table .act-cta SPAN.uid {
+       FONT-STYLE: italic
+}
+
+TABLE.dataTable.sdc_table .act-cta .btn {
+       WIDTH: 100%;
+       FONT-SIZE: 16px
+}
+
+TABLE.dataTable.sdc_table .act-name .title {
+       WIDTH: 95%;
+       FLOAT: left
+}
+
+TABLE.dataTable.sdc_table .act-name .title .progress-label {
+       FONT-STYLE: italic;
+       DISPLAY: block;
+       PADDING-TOP: 5px
+}
+
+TABLE.dataTable.sdc_table .act-name .icon {
+       WIDTH: 5%;
+       FLOAT: right
+}
+
+TABLE.dataTable.sdc_table .act-duedate .due-date {
+       DISPLAY: block;
+       PADDING-TOP: 5px
+}
+
+TABLE.dataTable.sdc_table .act-status .error {
+       MARGIN-TOP: 0px
+}
+
+TABLE.dataTable.sdc_table .act-status .fair {
+       MARGIN-TOP: 0px
+}
+
+TABLE.dataTable.sdc_table .act-status .good {
+       MARGIN-TOP: 0px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px
+}
+
+TABLE.dataTable.sdc_table TR.in.act-summary {
+       DISPLAY: table-row
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TD {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       BORDER-SPACING: 0;
+       WIDTH: 100%;
+       BORDER-COLLAPSE: collapse;
+       HEIGHT: auto;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE TR {
+       MARGIN-LEFT: 15px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE TD {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       BACKGROUND: #f3f3f3;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 15px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE TD.spacer {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 0px;
+       WIDTH: 15px;
+       PADDING-RIGHT: 0px;
+       BACKGROUND: #fff;
+       PADDING-TOP: 0px
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE TD.summary {
+       WIDTH: 62%
+}
+
+TABLE.dataTable.sdc_table TR.act-summary TABLE TD.estimate {
+       WIDTH: 38%
+}
+
+.filterDropdown {
+       POSITION: relative;
+       DISPLAY: inline-block
+}
+
+.open.filterDropdown A:first-child .glyphicon {
+       COLOR: #44c8f5
+}
+
+.filter-active.filterDropdown A:first-child .glyphicon {
+       COLOR: #f47b20
+}
+
+.filter-active.filterDropdown A:first-child:hover .glyphicon {
+       COLOR: #fcb314
+}
+
+.open.filter-active.filterDropdown A:first-child .glyphicon {
+       COLOR: #fcb314
+}
+
+.filterDropdown A {
+       TEXT-TRANSFORM: none;
+       COLOR: #067ab4 !important
+}
+
+.filterDropdown A:visited {
+       COLOR: #067ab4 !important
+}
+
+.filterDropdown A:hover {
+       COLOR: #44c8f5 !important
+}
+
+.filterDropdown A .glyphicon {
+       PADDING-BOTTOM: 3px;
+       PADDING-LEFT: 3px;
+       PADDING-RIGHT: 3px;
+       FONT-SIZE: 16px;
+       PADDING-TOP: 3px
+}
+
+.filterDropdown .dropdown-menu {
+       PADDING-BOTTOM: 15px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       PADDING-TOP: 10px
+}
+
+.filterDropdown .dropdown-menu LI {
+       PADDING-BOTTOM: 0px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 0px
+}
+
+.filterDropdown .dropdown-menu LI.separated {
+       MARGIN-TOP: 5px;
+       BORDER-TOP: #ccc 1px solid;
+       PADDING-TOP: 12px
+}
+
+.filterDropdown .dropdown-menu LI.separated .apply-filter {
+       COLOR: #666666
+}
+
+.filterDropdown .dropdown-menu LI A {
+       PADDING-BOTTOM: 5px;
+       MARGIN: 0px -15px;
+       PADDING-LEFT: 15px;
+       PADDING-RIGHT: 15px;
+       PADDING-TOP: 5px
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList {
+       PADDING-BOTTOM: 0px;
+       LIST-STYLE-TYPE: none;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       LIST-STYLE-IMAGE: none;
+       PADDING-TOP: 5px
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList LI {
+       BORDER-BOTTOM: #ccc 1px solid;
+       POSITION: relative;
+       BORDER-LEFT: #ccc 1px solid;
+       PADDING-BOTTOM: 5px;
+       BACKGROUND-COLOR: #f3f3f3;
+       MARGIN: 8px 0px;
+       PADDING-LEFT: 5px;
+       WIDTH: 155px;
+       PADDING-RIGHT: 20px;
+       COLOR: #666666;
+       BORDER-TOP: #ccc 1px solid;
+       BORDER-RIGHT: #ccc 1px solid;
+       PADDING-TOP: 3px;
+       border-radius: 3px
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList LI.resetFilters {
+       BORDER-BOTTOM: 0px;
+       BORDER-LEFT: 0px;
+       PADDING-BOTTOM: 0px;
+       BACKGROUND-COLOR: transparent;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       BORDER-TOP: 0px;
+       BORDER-RIGHT: 0px;
+       PADDING-TOP: 5px;
+       border-radius: 0
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList LI SPAN.filterLabel {
+       TEXT-TRANSFORM: none;
+       DISPLAY: block;
+       MAX-WIDTH: 95%;
+       WORD-WRAP: break-word;
+       FLOAT: none;
+       COLOR: #666666
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList LI A.clearFilter {
+       POSITION: absolute;
+       PADDING-BOTTOM: 0px;
+       MARGIN: 0px;
+       PADDING-LEFT: 0px;
+       PADDING-RIGHT: 0px;
+       DISPLAY: block;
+       TOP: 0px;
+       RIGHT: 0px;
+       PADDING-TOP: 0px
+}
+
+.filterDropdown .dropdown-menu LI UL.filterList LI A.clearFilter SPAN {
+       COLOR: #666666;
+       FONT-SIZE: 28px
+}
+
+.ekko-lightbox-container {
+       POSITION: relative
+}
+
+.ekko-lightbox-nav-overlay {
+       Z-INDEX: 100;
+       POSITION: absolute;
+       WIDTH: 100%;
+       HEIGHT: 100%;
+       TOP: 0px;
+       LEFT: 0px
+}
+
+.ekko-lightbox-nav-overlay A {
+       Z-INDEX: 100;
+       FILTER: dropshadow(color = #000000, offx = 2, offy = 2);
+       WIDTH: 49%;
+       DISPLAY: block;
+       HEIGHT: 100%;
+       COLOR: #fff;
+       FONT-SIZE: 30px;
+       PADDING-TOP: 45%;
+       text-shadow: 2px 2px 4px #000;
+       -webkit-transition: opacity 0.5s;
+       transition: opacity 0.5s;
+       opacity: 0;
+       -moz-transition: opacity 0.5s;
+       -o-transition: opacity 0.5s
+}
+
+.ekko-lightbox A:hover {
+       TEXT-DECORATION: none;
+       opacity: 1
+}
+
+.ekko-lightbox .glyphicon-chevron-left {
+       TEXT-ALIGN: left;
+       PADDING-LEFT: 15px;
+       FLOAT: left;
+       LEFT: 0px
+}
+
+.ekko-lightbox .glyphicon-chevron-right {
+       TEXT-ALIGN: right;
+       PADDING-RIGHT: 15px;
+       FLOAT: right;
+       RIGHT: 0px
+}
+
+.ekko-lightbox .modal-footer {
+       TEXT-ALIGN: left
+}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/css/stylesheet.css b/src/main/resources/META-INF/resources/designer/css/stylesheet.css
new file mode 100644 (file)
index 0000000..c7f307d
--- /dev/null
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+a, a:visited {
+       color: #3fabff;
+       text-decoration: none;
+}
+
+a:hover 
+{
+       color: #008af5;
+}
+
+h1 
+{
+       margin: 0;
+       font-weight: 300;
+       font-size: 35px;
+       letter-spacing: -1px;
+}
+h2 
+{
+       font-size: 15px;
+       color: #a0a0a0;
+       margin: 30px 0;
+}
+label {
+       display: block;
+       font-weight: bold;
+       margin-bottom: 10px;
+}
+p, .control-group {
+       margin: 0 0 10px 0;
+}
+.demo {
+       border-bottom: 1px solid #e8e8e8;
+       padding-top: 5px;
+       padding-bottom: 5px;
+       -webkit-border-radius: 3px;
+       -moz-border-radius: 3px;
+       border-radius: 3px;
+}
+.demo:last-child {
+       border-bottom: 0 none;
+}
+.demo select, .demo input, .demo .selectize-control {
+       width: 100%;
+}
+.demo > *:first-child {
+       margin-top: 0;
+}
+.demo > *:last-child {
+       margin-bottom: 0;
+}
+.demo .value {
+       margin: 0 0 10px 0;
+       font-size: 12px;
+}
+.demo .value span {
+       font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
+}
+.theme-selector {
+       margin-top: 5px;
+       font-size: 13px;
+}
+.theme-selector:before {
+       content: 'Themes: ';
+}
+.theme-selector a {
+       margin: 0 5px;
+}
+.theme-selector a.active {
+       color: #202020;
+       font-weight: bold;
+}
+#wrapper {
+       margin: 0;
+}
+#wrapper > * {
+       padding-left: 5px;
+       padding-right: 5px;
+}
+pre {
+       background: #f8f8f8;
+       border: 1px solid #f2f2f2;
+       padding: 10px;
+       font-size: 12px;
+       font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
+       -webkit-border-radius: 3px;
+       -moz-border-radius: 3px;
+       border-radius: 3px;
+}
+input[type=button] {
+       margin: 0 10px 0 0;
+       padding: 6px 10px;
+       color: #606060;
+       background: #e0e0e0;
+       border: 0 none;
+       width: auto;
+       display: inline-block;
+       -webkit-border-radius: 3px;
+       -moz-border-radius: 3px;
+       border-radius: 3px;
+       -webkit-font-smoothing: antialiased;
+}
+.buttons {
+       margin: 0 0 25px 0;
+}
+input[type=button]:hover {
+       background: #dadada;
+}
+
+@media only screen and (max-width : 320px) {
+       body {
+               margin: 20px 0;
+       }
+       #wrapper {
+               margin: 0;
+       }
+       #wrapper > * {
+               padding-left: 10px;
+               padding-right: 10px;
+       }
+       .demo {
+               padding: 20px;
+               -webkit-border-radius: 0;
+               -moz-border-radius: 0;
+               border-radius: 0;
+       }
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/table_custom.css b/src/main/resources/META-INF/resources/designer/css/table_custom.css
new file mode 100644 (file)
index 0000000..b6729e0
--- /dev/null
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+table a:link {
+       color: #666;
+       font-weight: bold;
+       text-decoration:none;
+}
+table a:visited {
+       color: #999999;
+       font-weight:bold;
+       text-decoration:none;
+}
+table a:active,
+table a:hover {
+       color: #bd5a35;
+       text-decoration:underline;
+}
+table {
+       font-family:Arial, Helvetica, sans-serif;
+       color:#666;
+       font-size:12px;
+       text-shadow: 1px 1px 0px #fff;
+       background:#eaebec;
+       margin:20px;
+       border:#ccc 1px solid;
+
+       -moz-border-radius:3px;
+       -webkit-border-radius:3px;
+       border-radius:3px;
+
+       -moz-box-shadow: 0 1px 2px #d1d1d1;
+       -webkit-box-shadow: 0 1px 2px #d1d1d1;
+       box-shadow: 0 1px 2px #d1d1d1;
+}
+table th {
+       padding:21px 25px 22px 25px;
+       border-top:1px solid #fafafa;
+       border-bottom:1px solid #e0e0e0;
+
+       background: #ededed;
+       background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb));
+       background: -moz-linear-gradient(top,  #ededed,  #ebebeb);
+}
+table th:first-child {
+       text-align: left;
+       padding-left:20px;
+}
+table tr:first-child th:first-child {
+       -moz-border-radius-topleft:3px;
+       -webkit-border-top-left-radius:3px;
+       border-top-left-radius:3px;
+}
+table tr:first-child th:last-child {
+       -moz-border-radius-topright:3px;
+       -webkit-border-top-right-radius:3px;
+       border-top-right-radius:3px;
+}
+table tr {
+       text-align: center;
+       padding-left:20px;
+}
+table td:first-child {
+       text-align: left;
+       padding-left:20px;
+       border-left: 0;
+}
+table td {
+       padding:18px;
+       border-top: 1px solid #ffffff;
+       border-bottom:1px solid #e0e0e0;
+       border-left: 1px solid #e0e0e0;
+
+       background: #fafafa;
+       background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa));
+       background: -moz-linear-gradient(top,  #fbfbfb,  #fafafa);
+}
+table tr.even td {
+       background: #f6f6f6;
+       background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6));
+       background: -moz-linear-gradient(top,  #f8f8f8,  #f6f6f6);
+}
+table tr:last-child td {
+       border-bottom:0;
+}
+table tr:last-child td:first-child {
+       -moz-border-radius-bottomleft:3px;
+       -webkit-border-bottom-left-radius:3px;
+       border-bottom-left-radius:3px;
+}
+table tr:last-child td:last-child {
+       -moz-border-radius-bottomright:3px;
+       -webkit-border-bottom-right-radius:3px;
+       border-bottom-right-radius:3px;
+}
+table tr:hover td {
+       background: #f2f2f2;
+       background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0));
+       background: -moz-linear-gradient(top,  #f2f2f2,  #f0f0f0);      
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/table_theme_1.css b/src/main/resources/META-INF/resources/designer/css/table_theme_1.css
new file mode 100644 (file)
index 0000000..878e859
--- /dev/null
@@ -0,0 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+.datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }.datagrid table td, .datagrid table th { padding: 3px 10px; }.datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00557F; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEf4; color: #00557F; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEf4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot  li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block;  padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #00557F; color: #FFFFFF; background: none; background-color:#006699;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; }
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-stable.css b/src/main/resources/META-INF/resources/designer/css/ui-grid-stable.css
new file mode 100644 (file)
index 0000000..409817b
--- /dev/null
@@ -0,0 +1,1086 @@
+.ui-grid {
+  border: 1px solid #d4d4d4;
+  box-sizing: content-box;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  border-radius: 0px;
+  -webkit-transform: translateZ(0);
+  -moz-transform: translateZ(0);
+  -o-transform: translateZ(0);
+  -ms-transform: translateZ(0);
+  transform: translateZ(0);
+}
+.ui-grid-vertical-bar {
+  position: absolute;
+  right: 0;
+  width: 0;
+}
+.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,
+.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  width: 1px;
+}
+.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-header-cell:last-child .ui-grid-vertical-bar {
+  right: -1px;
+  width: 1px;
+  background-color: #d4d4d4;
+}
+.ui-grid-clearfix:before,
+.ui-grid-clearfix:after {
+  content: "";
+  display: table;
+}
+.ui-grid-clearfix:after {
+  clear: both;
+}
+.ui-grid-invisible {
+  visibility: hidden;
+}
+.ui-grid-top-panel-background {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+}
+.ui-grid-top-panel {
+  position: relative;
+  border-bottom: 1px solid #d4d4d4;
+  overflow: hidden;
+  font-weight: bold;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-group-panel {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  border-bottom: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  min-height: 30px;
+}
+.ui-grid-header-group-panel .hidden {
+  display: none;
+}
+.ui-grid-header-viewport {
+  overflow: hidden;
+}
+.ui-grid-header-canvas {
+  position: relative;
+}
+.ui-grid-header-canvas:before,
+.ui-grid-header-canvas:after {
+  content: "";
+  display: table;
+  line-height: 0;
+}
+.ui-grid-header-canvas:after {
+  clear: both;
+}
+.ui-grid-header-cell {
+  position: relative;
+  float: left;
+  top: 0;
+  bottom: 0;
+  background-color: inherit;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  width: 0;
+}
+.ui-grid-header-cell .sortable {
+  cursor: pointer;
+}
+.ui-grid-header .ui-grid-vertical-bar {
+  top: 0;
+  bottom: 0;
+}
+.ui-grid-column-menu-button {
+  position: absolute;
+  right: 1px;
+  top: 0;
+}
+.ui-grid-column-menu-button .ui-grid-icon-angle-down {
+  vertical-align: sub;
+}
+.ui-grid-column-menu {
+  position: absolute;
+}
+/* Slide up/down animations */
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove {
+  -webkit-transition: all 0.05s linear;
+  -moz-transition: all 0.05s linear;
+  -o-transition: all 0.05s linear;
+  transition: all 0.05s linear;
+  display: block !important;
+}
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add.ng-hide-add-active,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove {
+  -webkit-transform: translateY(-100%);
+  -moz-transform: translateY(-100%);
+  -o-transform: translateY(-100%);
+  -ms-transform: translateY(-100%);
+  transform: translateY(-100%);
+}
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove.ng-hide-remove-active {
+  -webkit-transform: translateY(0);
+  -moz-transform: translateY(0);
+  -o-transform: translateY(0);
+  -ms-transform: translateY(0);
+  transform: translateY(0);
+}
+.ui-grid-filter-container {
+  padding: 4px 10px;
+  position: relative;
+}
+.ui-grid-filter-container .ui-grid-filter-button {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+}
+.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"].right {
+  position: absolute;
+  top: 50%;
+  line-height: 32px;
+  margin-top: -16px;
+  right: 10px;
+  opacity: 0.66;
+}
+.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"].right:hover {
+  opacity: 1;
+}
+input[type="text"].ui-grid-filter-input {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  width: 100%;
+  border: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+input[type="text"].ui-grid-filter-input:hover {
+  border: 1px solid #d4d4d4;
+}
+.ui-grid-render-container {
+  position: relative;
+  -webkit-border-top-right-radius: 0;
+  -webkit-border-bottom-right-radius: 0px;
+  -webkit-border-bottom-left-radius: 0px;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0px;
+  -moz-border-radius-bottomleft: 0px;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 0px;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-viewport {
+  min-height: 20px;
+  position: relative;
+  overflow: hidden;
+}
+.ui-grid-viewport :focus {
+  outline: none;
+}
+.ui-grid-canvas {
+  position: relative;
+}
+.ui-grid-row:nth-child(odd) .ui-grid-cell {
+  background-color: #fdfdfd;
+}
+.ui-grid-row:nth-child(even) .ui-grid-cell {
+  background-color: #f3f3f3;
+}
+.ui-grid-row:last-child .ui-grid-cell {
+  border-bottom-color: #d4d4d4;
+  border-bottom-style: solid;
+}
+.ui-grid-no-row-overlay {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  margin: 10%;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  border: 1px solid #d4d4d4;
+  font-size: 2em;
+  text-align: center;
+}
+.ui-grid-no-row-overlay > * {
+  position: absolute;
+  display: table;
+  margin: auto 0;
+  width: 100%;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  opacity: 0.66;
+}
+.ui-grid-cell {
+  overflow: hidden;
+  float: left;
+  background-color: inherit;
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+  box-sizing: border-box;
+}
+.ui-grid-cell:last-child {
+  border-right: 0;
+}
+.ui-grid-cell-contents {
+  padding: 5px;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  white-space: nowrap;
+  -ms-text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  height: 100%;
+}
+.ui-grid-cell-contents-hidden {
+  visibility: hidden;
+  width: 0;
+  height: 0;
+  display: none;
+}
+.ui-grid-row-header-cell {
+  background-color: #F0F0EE !important;
+  border-bottom: solid 1px #d4d4d4;
+}
+.ui-grid-native-scrollbar {
+  position: absolute;
+  overflow: scroll;
+}
+.ui-grid-native-scrollbar.vertical {
+  top: 0;
+  right: 0;
+  height: 100%;
+  overflow-x: hidden;
+  width: 17px;
+}
+.ui-grid-native-scrollbar.horizontal {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  overflow-y: hidden;
+  height: 17px;
+}
+.ui-grid-footer-panel-background {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+}
+.ui-grid-footer-panel {
+  position: relative;
+  border-bottom: 1px solid #d4d4d4;
+  border-top: 1px solid #d4d4d4;
+  overflow: hidden;
+  font-weight: bold;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-group-panel {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  border-bottom: 1px solid #d4d4d4;
+  border-top: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  min-height: 30px;
+}
+.ui-grid-footer-group-panel .hidden {
+  display: none;
+}
+.ui-grid-footer-viewport {
+  overflow: hidden;
+}
+.ui-grid-footer-canvas {
+  position: relative;
+}
+.ui-grid-footer-canvas:before,
+.ui-grid-footer-canvas:after {
+  content: "";
+  display: table;
+  line-height: 0;
+}
+.ui-grid-footer-canvas:after {
+  clear: both;
+}
+.ui-grid-footer-cell {
+  overflow: hidden;
+  float: left;
+  background-color: inherit;
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+  box-sizing: border-box;
+}
+.ui-grid-footer-cell:last-child {
+  border-right: 0;
+}
+.ui-grid-footer .ui-grid-vertical-bar {
+  top: 0;
+  bottom: 0;
+}
+input[type="text"].ui-grid-filter-input {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  width: 100%;
+  border: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+input[type="text"].ui-grid-filter-input:hover {
+  border: 1px solid #d4d4d4;
+}
+.ui-grid-menu {
+  z-index: 2;
+  position: absolute;
+  overflow: hidden;
+  padding: 0 10px 20px 10px;
+  cursor: default;
+}
+.ui-grid-menu .ui-grid-menu-inner {
+  background: #f3f3f3;
+  border: 1px solid #d4d4d4;
+  position: relative;
+  white-space: nowrap;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  border-radius: 0px;
+  -webkit-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+}
+.ui-grid-menu .ui-grid-menu-inner ul {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li {
+  padding: 8px;
+  cursor: pointer;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li:hover {
+  -webkit-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+}
+.ui-grid-menu .ui-grid-menu-inner ul li.ui-grid-menu-item-active {
+  -webkit-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  background-color: #cecece;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child) {
+  border-bottom: 1px solid #d4d4d4;
+}
+.ui-grid-sortarrow {
+  right: 5px;
+  position: absolute;
+  width: 20px;
+  top: 0;
+  bottom: 0;
+  background-position: center;
+}
+.ui-grid-sortarrow.down {
+  -webkit-transform: rotate(180deg);
+  -moz-transform: rotate(180deg);
+  -o-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+@font-face {
+  font-family: 'ui-grid';
+  src: url('ui-grid.eot');
+  src: url('ui-grid.eot#iefix') format('embedded-opentype'), url('ui-grid.woff') format('woff'), url('ui-grid.ttf?') format('truetype'), url('ui-grid.svg?#ui-grid') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
+/*
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+  @font-face {
+    font-family: 'ui-grid';
+    src: url('../font/ui-grid.svg?12312827#ui-grid') format('svg');
+  }
+}
+*/
+[class^="ui-grid-icon"]:before,
+[class*=" ui-grid-icon"]:before {
+  font-family: "ui-grid";
+  font-style: normal;
+  font-weight: normal;
+  speak: none;
+  display: inline-block;
+  text-decoration: inherit;
+  width: 1em;
+  margin-right: .2em;
+  text-align: center;
+  /* opacity: .8; */
+  /* For safety - reset parent styles, that can break glyph codes*/
+  font-variant: normal;
+  text-transform: none;
+  /* fix buttons height, for twitter bootstrap */
+  line-height: 1em;
+  /* Animation center compensation - margins should be symmetric */
+  /* remove if not needed */
+  margin-left: .2em;
+  /* you can be more comfortable with increased icons size */
+  /* font-size: 120%; */
+  /* Uncomment for 3D effect */
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
+}
+.ui-grid-icon-blank::before {
+  width: 1em;
+  content: ' ';
+}
+/*
+* RTL Styles
+*/
+.ui-grid[dir=rtl] .ui-grid-header-cell,
+.ui-grid[dir=rtl] .ui-grid-footer-cell,
+.ui-grid[dir=rtl] .ui-grid-cell {
+  float: right !important;
+}
+.ui-grid[dir=rtl] .ui-grid-scrollbar-horizontal {
+  left: inherit;
+  right: 0;
+}
+.ui-grid[dir=rtl] .ui-grid-native-scrollbar.vertical {
+  left: 0;
+  right: inherit;
+}
+.ui-grid[dir=rtl] .ui-grid-column-menu-button {
+  position: absolute;
+  left: 1px;
+  top: 0;
+  right: inherit;
+}
+.ui-grid[dir=rtl] .ui-grid-cell:first-child,
+.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,
+.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child {
+  border-right: 0;
+}
+.ui-grid[dir=rtl] .ui-grid-cell:last-child {
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+}
+.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,
+.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,
+.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar {
+  width: 0;
+}
+/*
+   Animation example, for spinners
+*/
+.ui-grid-animate-spin {
+  -moz-animation: ui-grid-spin 2s infinite linear;
+  -o-animation: ui-grid-spin 2s infinite linear;
+  -webkit-animation: ui-grid-spin 2s infinite linear;
+  animation: ui-grid-spin 2s infinite linear;
+  display: inline-block;
+}
+@-moz-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-webkit-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-o-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-ms-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+/*---------------------------------------------------
+    LESS Elements 0.9
+  ---------------------------------------------------
+    A set of useful LESS mixins
+    More info at: http://lesselements.com
+  ---------------------------------------------------*/
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-cell-contents:focus {
+  outline: 0;
+  background-color: #b3c4c7;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+div.ui-grid-cell input {
+  border-radius: inherit;
+  padding: 0;
+  width: 100%;
+  color: inherit;
+  height: auto;
+  font: inherit;
+  outline: none;
+}
+div.ui-grid-cell input:focus {
+  color: inherit;
+  outline: none;
+}
+div.ui-grid-cell input[type="checkbox"] {
+  margin: 9px 0 0 6px;
+  width: auto;
+}
+div.ui-grid-cell input.ng-invalid {
+  border: 1px solid #fc8f8f;
+}
+div.ui-grid-cell input.ng-valid {
+  border: 1px solid #d4d4d4;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell {
+  background-color: #fdfdfd;
+}
+.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell {
+  background-color: #f3f3f3;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-pinned-container {
+  float: left;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child {
+  box-sizing: border-box;
+  border-right: 1px solid;
+  border-width: 1px;
+  border-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child {
+  box-sizing: border-box;
+  border-right: 1px solid;
+  border-width: 1px;
+  border-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,
+.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  width: 1px;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar {
+  right: -1px;
+  width: 1px;
+  background-color: #aeaeae;
+}
+.ui-grid-render-container-body {
+  float: left;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-column-resizer {
+  top: 0;
+  bottom: 0;
+  width: 5px;
+  position: absolute;
+  cursor: col-resize;
+}
+.ui-grid-column-resizer.left {
+  left: 0;
+}
+.ui-grid-column-resizer.right {
+  right: 0;
+}
+.ui-grid.column-resizing {
+  cursor: col-resize;
+}
+.ui-grid.column-resizing .ui-grid-resize-overlay {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  width: 1px;
+  background-color: #aeaeae;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-row-saving .ui-grid-cell {
+  color: #848484 !important;
+}
+.ui-grid-row-error .ui-grid-cell {
+  color: #ff0000 !important;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-row-selected .ui-grid-cell {
+  background-color: #c9dde1 !important;
+}
+.ui-grid-disable-selection {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  cursor: default;
+}
+.ui-grid-selection-row-header-buttons {
+  cursor: pointer;
+  opacity: 0.1;
+}
+.ui-grid-selection-row-header-buttons.ui-grid-row-selected {
+  opacity: 1;
+}
+.ui-grid-selection-row-header-cell {
+  border-bottom: solid 1px #d4d4d4;
+}
+
+.ui-grid-icon-plus-squared:before {
+  content: '\c350';
+}
+/* '썐' */
+.ui-grid-icon-minus-squared:before {
+  content: '\c351';
+}
+/* '썑' */
+.ui-grid-icon-search:before {
+  content: '\c352';
+}
+/* '썒' */
+.ui-grid-icon-cancel:before {
+  content: '\c353';
+}
+/* '썓' */
+.ui-grid-icon-info-circled:before {
+  content: '\c354';
+}
+/* '썔' */
+.ui-grid-icon-lock:before {
+  content: '\c355';
+}
+/* '썕' */
+.ui-grid-icon-lock-open:before {
+  content: '\c356';
+}
+/* '썖' */
+.ui-grid-icon-pencil:before {
+  content: '\c357';
+}
+/* '썗' */
+.ui-grid-icon-down-dir:before {
+  content: '\c358';
+}
+/* '썘' */
+.ui-grid-icon-up-dir:before {
+  content: '\c359';
+}
+/* '썙' */
+.ui-grid-icon-left-dir:before {
+  content: '\c35a';
+}
+/* '썚' */
+.ui-grid-icon-right-dir:before {
+  content: '\c35b';
+}
+/* '썛' */
+.ui-grid-icon-left-open:before {
+  content: '\c35c';
+}
+/* '썜' */
+.ui-grid-icon-right-open:before {
+  content: '\c35d';
+}
+/* '썝' */
+.ui-grid-icon-angle-down:before {
+  content: '\c35e';
+}
+/* '썞' */
+.ui-grid-icon-filter:before {
+  content: '\c35f';
+}
+/* '썟' */
+.ui-grid-icon-sort-alt-up:before {
+  content: '\c360';
+}
+/* '썠' */
+.ui-grid-icon-sort-alt-down:before {
+  content: '\c361';
+}
+/* '썡' */
+.ui-grid-icon-ok:before {
+  content: '\e800';
+}
+/* '' */
+.ui-grid-icon-spin5:before {
+  content: '\ea61';
+}
+/* '' */
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-stable.min.css b/src/main/resources/META-INF/resources/designer/css/ui-grid-stable.min.css
new file mode 100644 (file)
index 0000000..f407483
--- /dev/null
@@ -0,0 +1,10 @@
+.ui-grid{border:1px solid #d4d4d4;box-sizing:content-box;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}.ui-grid-vertical-bar{position:absolute;right:0;width:0}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#d4d4d4}.ui-grid-clearfix:before,.ui-grid-clearfix:after{content:"";display:table}.ui-grid-clearfix:after{clear:both}.ui-grid-invisible{visibility:hidden}.ui-grid-top-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-top-panel{position:relative;border-bottom:1px solid #d4d4d4;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-group-panel{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);border-bottom:1px solid #d4d4d4;-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;min-height:30px}.ui-grid-header-group-panel .hidden{display:none}.ui-grid-header-viewport{overflow:hidden}.ui-grid-header-canvas{position:relative}.ui-grid-header-canvas:before,.ui-grid-header-canvas:after{content:"";display:table;line-height:0}.ui-grid-header-canvas:after{clear:both}.ui-grid-header-cell{position:relative;float:left;top:0;bottom:0;background-color:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:0}.ui-grid-header-cell .sortable{cursor:pointer}.ui-grid-header .ui-grid-vertical-bar{top:0;bottom:0}.ui-grid-column-menu-button{position:absolute;right:1px;top:0}.ui-grid-column-menu-button .ui-grid-icon-angle-down{vertical-align:sub}.ui-grid-column-menu{position:absolute}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add.ng-hide-add-active,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-inner.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-filter-container{padding:4px 10px;position:relative}.ui-grid-filter-container .ui-grid-filter-button{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"].right{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:10px;opacity:0.66}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"].right:hover{opacity:1}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-render-container{position:relative;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-viewport{min-height:20px;position:relative;overflow:hidden}.ui-grid-viewport :focus{outline:none}.ui-grid-canvas{position:relative}.ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-row:last-child .ui-grid-cell{border-bottom-color:#d4d4d4;border-bottom-style:solid}.ui-grid-no-row-overlay{position:absolute;top:0;bottom:0;left:0;right:0;margin:10%;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #d4d4d4;font-size:2em;text-align:center}.ui-grid-no-row-overlay>*{position:absolute;display:table;margin:auto 0;width:100%;top:0;bottom:0;left:0;right:0;opacity:0.66}.ui-grid-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-cell:last-child{border-right:0}.ui-grid-cell-contents{padding:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;height:100%}.ui-grid-cell-contents-hidden{visibility:hidden;width:0;height:0;display:none}.ui-grid-row-header-cell{background-color:#F0F0EE !important;border-bottom:solid 1px #d4d4d4}.ui-grid-native-scrollbar{position:absolute;overflow:scroll}.ui-grid-native-scrollbar.vertical{top:0;right:0;height:100%;overflow-x:hidden;width:17px}.ui-grid-native-scrollbar.horizontal{bottom:0;left:0;width:100%;overflow-y:hidden;height:17px}.ui-grid-footer-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-footer-panel{position:relative;border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-group-panel{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;min-height:30px}.ui-grid-footer-group-panel .hidden{display:none}.ui-grid-footer-viewport{overflow:hidden}.ui-grid-footer-canvas{position:relative}.ui-grid-footer-canvas:before,.ui-grid-footer-canvas:after{content:"";display:table;line-height:0}.ui-grid-footer-canvas:after{clear:both}.ui-grid-footer-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-footer-cell:last-child{border-right:0}.ui-grid-footer .ui-grid-vertical-bar{top:0;bottom:0}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-menu{z-index:2;position:absolute;overflow:hidden;padding:0 10px 20px 10px;cursor:default}.ui-grid-menu .ui-grid-menu-inner{background:#f3f3f3;border:1px solid #d4d4d4;position:relative;white-space:nowrap;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2)}.ui-grid-menu .ui-grid-menu-inner ul{margin:0;padding:0;list-style-type:none}.ui-grid-menu .ui-grid-menu-inner ul li{padding:8px;cursor:pointer}.ui-grid-menu .ui-grid-menu-inner ul li:hover{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.ui-grid-menu .ui-grid-menu-inner ul li.ui-grid-menu-item-active{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2);background-color:#cecece}.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child){border-bottom:1px solid #d4d4d4}.ui-grid-sortarrow{right:5px;position:absolute;width:20px;top:0;bottom:0;background-position:center}.ui-grid-sortarrow.down{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}@font-face{font-family:'ui-grid';src:url('ui-grid.eot');src:url('ui-grid.eot#iefix') format('embedded-opentype'),url('ui-grid.woff') format('woff'),url('ui-grid.ttf?') format('truetype'),url('ui-grid.svg?#ui-grid') format('svg');font-weight:normal;font-style:normal}[class^="ui-grid-icon"]:before,[class*=" ui-grid-icon"]:before{font-family:"ui-grid";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.ui-grid-icon-blank::before{width:1em;content:' '}.ui-grid[dir=rtl] .ui-grid-header-cell,.ui-grid[dir=rtl] .ui-grid-footer-cell,.ui-grid[dir=rtl] .ui-grid-cell{float:right !important}.ui-grid[dir=rtl] .ui-grid-scrollbar-horizontal{left:inherit;right:0}.ui-grid[dir=rtl] .ui-grid-native-scrollbar.vertical{left:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-column-menu-button{position:absolute;left:1px;top:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-cell:first-child,.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child{border-right:0}.ui-grid[dir=rtl] .ui-grid-cell:last-child{border-right:1px solid;border-color:#d4d4d4}.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar{width:0}.ui-grid-animate-spin{-moz-animation:ui-grid-spin 2s infinite linear;-o-animation:ui-grid-spin 2s infinite linear;-webkit-animation:ui-grid-spin 2s infinite linear;animation:ui-grid-spin 2s infinite linear;display:inline-block}@-moz-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}
+.ui-grid-cell-contents:focus{outline:0;background-color:#b3c4c7}
+div.ui-grid-cell input{border-radius:inherit;padding:0;width:100%;color:inherit;height:auto;font:inherit;outline:none}div.ui-grid-cell input:focus{color:inherit;outline:none}div.ui-grid-cell input[type="checkbox"]{margin:9px 0 0 6px;width:auto}div.ui-grid-cell input.ng-invalid{border:1px solid #fc8f8f}div.ui-grid-cell input.ng-valid{border:1px solid #d4d4d4}
+.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}
+
+.ui-grid-pinned-container{float:left}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#aeaeae}.ui-grid-render-container-body{float:left}
+.ui-grid-column-resizer{top:0;bottom:0;width:5px;position:absolute;cursor:col-resize}.ui-grid-column-resizer.left{left:0}.ui-grid-column-resizer.right{right:0}.ui-grid.column-resizing{cursor:col-resize}.ui-grid.column-resizing .ui-grid-resize-overlay{position:absolute;top:0;height:100%;width:1px;background-color:#aeaeae}
+.ui-grid-row-saving .ui-grid-cell{color:#848484 !important}.ui-grid-row-error .ui-grid-cell{color:#f00 !important}
+.ui-grid-row-selected .ui-grid-cell{background-color:#c9dde1 !important}.ui-grid-disable-selection{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.ui-grid-selection-row-header-buttons{cursor:pointer;opacity:0.1}.ui-grid-selection-row-header-buttons.ui-grid-row-selected{opacity:1}.ui-grid-selection-row-header-cell{border-bottom:solid 1px #d4d4d4}
+.ui-grid-icon-plus-squared:before{content:'\c350'}.ui-grid-icon-minus-squared:before{content:'\c351'}.ui-grid-icon-search:before{content:'\c352'}.ui-grid-icon-cancel:before{content:'\c353'}.ui-grid-icon-info-circled:before{content:'\c354'}.ui-grid-icon-lock:before{content:'\c355'}.ui-grid-icon-lock-open:before{content:'\c356'}.ui-grid-icon-pencil:before{content:'\c357'}.ui-grid-icon-down-dir:before{content:'\c358'}.ui-grid-icon-up-dir:before{content:'\c359'}.ui-grid-icon-left-dir:before{content:'\c35a'}.ui-grid-icon-right-dir:before{content:'\c35b'}.ui-grid-icon-left-open:before{content:'\c35c'}.ui-grid-icon-right-open:before{content:'\c35d'}.ui-grid-icon-angle-down:before{content:'\c35e'}.ui-grid-icon-filter:before{content:'\c35f'}.ui-grid-icon-sort-alt-up:before{content:'\c360'}.ui-grid-icon-sort-alt-down:before{content:'\c361'}.ui-grid-icon-ok:before{content:'\e800'}.ui-grid-icon-spin5:before{content:'\ea61'}
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.css b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.css
new file mode 100644 (file)
index 0000000..acb27be
--- /dev/null
@@ -0,0 +1,1330 @@
+.ui-grid {
+  border: 1px solid #d4d4d4;
+  box-sizing: content-box;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  border-radius: 0px;
+  -webkit-transform: translateZ(0);
+  -moz-transform: translateZ(0);
+  -o-transform: translateZ(0);
+  -ms-transform: translateZ(0);
+  transform: translateZ(0);
+}
+.ui-grid-vertical-bar {
+  position: absolute;
+  right: 0;
+  width: 0;
+}
+.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,
+.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  width: 1px;
+}
+.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-header-cell:last-child .ui-grid-vertical-bar {
+  right: -1px;
+  width: 1px;
+  background-color: #d4d4d4;
+}
+.ui-grid-clearfix:before,
+.ui-grid-clearfix:after {
+  content: "";
+  display: table;
+}
+.ui-grid-clearfix:after {
+  clear: both;
+}
+.ui-grid-invisible {
+  visibility: hidden;
+}
+.ui-grid-top-panel-background {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+}
+.ui-grid-header {
+  border-bottom: 1px solid #d4d4d4;
+  box-sizing: content-box;
+}
+.ui-grid-top-panel {
+  position: relative;
+  overflow: hidden;
+  font-weight: bold;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-group-panel {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  border-bottom: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  min-height: 30px;
+}
+.ui-grid-header-group-panel .hidden {
+  display: none;
+}
+.ui-grid-header-viewport {
+  overflow: hidden;
+}
+.ui-grid-header-canvas {
+  position: relative;
+}
+.ui-grid-header-canvas:before,
+.ui-grid-header-canvas:after {
+  content: "";
+  display: table;
+  line-height: 0;
+}
+.ui-grid-header-canvas:after {
+  clear: both;
+}
+.ui-grid-header-cell {
+  position: relative;
+  float: left;
+  top: 0;
+  bottom: 0;
+  background-color: inherit;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  width: 0;
+}
+.ui-grid-header-cell .sortable {
+  cursor: pointer;
+}
+.ui-grid-header .ui-grid-vertical-bar {
+  top: 0;
+  bottom: 0;
+}
+.ui-grid-column-menu-button {
+  position: absolute;
+  right: 1px;
+  top: 0;
+}
+.ui-grid-column-menu-button .ui-grid-icon-angle-down {
+  vertical-align: sub;
+}
+.ui-grid-column-menu {
+  position: absolute;
+}
+/* Slide up/down animations */
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove {
+  -webkit-transition: all 0.05s linear;
+  -moz-transition: all 0.05s linear;
+  -o-transition: all 0.05s linear;
+  transition: all 0.05s linear;
+  display: block !important;
+}
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove {
+  -webkit-transform: translateY(-100%);
+  -moz-transform: translateY(-100%);
+  -o-transform: translateY(-100%);
+  -ms-transform: translateY(-100%);
+  transform: translateY(-100%);
+}
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,
+.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active {
+  -webkit-transform: translateY(0);
+  -moz-transform: translateY(0);
+  -o-transform: translateY(0);
+  -ms-transform: translateY(0);
+  transform: translateY(0);
+}
+/* Slide up/down animations */
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove {
+  -webkit-transition: all 0.05s linear;
+  -moz-transition: all 0.05s linear;
+  -o-transition: all 0.05s linear;
+  transition: all 0.05s linear;
+  display: block !important;
+}
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove {
+  -webkit-transform: translateY(-100%);
+  -moz-transform: translateY(-100%);
+  -o-transform: translateY(-100%);
+  -ms-transform: translateY(-100%);
+  transform: translateY(-100%);
+}
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,
+.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active {
+  -webkit-transform: translateY(0);
+  -moz-transform: translateY(0);
+  -o-transform: translateY(0);
+  -ms-transform: translateY(0);
+  transform: translateY(0);
+}
+.ui-grid-filter-container {
+  padding: 4px 10px;
+  position: relative;
+}
+.ui-grid-filter-container .ui-grid-filter-button {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+}
+.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"] {
+  position: absolute;
+  top: 50%;
+  line-height: 32px;
+  margin-top: -16px;
+  right: 10px;
+  opacity: 0.66;
+}
+.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]:hover {
+  opacity: 1;
+}
+input[type="text"].ui-grid-filter-input {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  width: 100%;
+  border: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+input[type="text"].ui-grid-filter-input:hover {
+  border: 1px solid #d4d4d4;
+}
+.ui-grid-render-container {
+  position: inherit;
+  -webkit-border-top-right-radius: 0;
+  -webkit-border-bottom-right-radius: 0px;
+  -webkit-border-bottom-left-radius: 0px;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0px;
+  -moz-border-radius-bottomleft: 0px;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 0px;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-render-container:focus {
+  outline: none;
+}
+.ui-grid-viewport {
+  min-height: 20px;
+  position: relative;
+  overflow: hidden;
+}
+.ui-grid-viewport :focus {
+  outline: none;
+}
+.ui-grid-canvas {
+  position: relative;
+}
+.ui-grid-row:nth-child(odd) .ui-grid-cell {
+  background-color: #fdfdfd;
+}
+.ui-grid-row:nth-child(even) .ui-grid-cell {
+  background-color: #f3f3f3;
+}
+.ui-grid-row:last-child .ui-grid-cell {
+  border-bottom-color: #d4d4d4;
+  border-bottom-style: solid;
+}
+.ui-grid-no-row-overlay {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  margin: 10%;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  border: 1px solid #d4d4d4;
+  font-size: 2em;
+  text-align: center;
+}
+.ui-grid-no-row-overlay > * {
+  position: absolute;
+  display: table;
+  margin: auto 0;
+  width: 100%;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  opacity: 0.66;
+}
+.ui-grid-cell {
+  overflow: hidden;
+  float: left;
+  background-color: inherit;
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+  box-sizing: border-box;
+}
+.ui-grid-cell:last-child {
+  border-right: 0;
+}
+.ui-grid-cell-contents {
+  padding: 5px;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  white-space: nowrap;
+  -ms-text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  height: 100%;
+}
+.ui-grid-cell-contents-hidden {
+  visibility: hidden;
+  width: 0;
+  height: 0;
+  display: none;
+}
+.ui-grid-row-header-cell {
+  background-color: #F0F0EE !important;
+  border-bottom: solid 1px #d4d4d4;
+}
+.ui-grid-native-scrollbar {
+  position: absolute;
+  overflow: scroll;
+}
+.ui-grid-native-scrollbar.vertical {
+  top: 0;
+  right: 0;
+  height: 100%;
+  overflow-x: hidden;
+  width: 17px;
+}
+.ui-grid-native-scrollbar.horizontal {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  overflow-y: hidden;
+  height: 17px;
+}
+.ui-grid-footer-panel-background {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+}
+.ui-grid-footer-panel {
+  position: relative;
+  border-bottom: 1px solid #d4d4d4;
+  border-top: 1px solid #d4d4d4;
+  overflow: hidden;
+  font-weight: bold;
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+.ui-grid-group-panel {
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
+  background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
+  background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
+  background: -o-linear-gradient(#ffffff, #eeeeee);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+  border-bottom: 1px solid #d4d4d4;
+  border-top: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: -1px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: -1px;
+  -moz-border-radius-topright: -1px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: -1px;
+  border-top-right-radius: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: -1px;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  min-height: 30px;
+}
+.ui-grid-footer-group-panel .hidden {
+  display: none;
+}
+.ui-grid-footer-viewport {
+  overflow: hidden;
+}
+.ui-grid-footer-canvas {
+  position: relative;
+}
+.ui-grid-footer-canvas:before,
+.ui-grid-footer-canvas:after {
+  content: "";
+  display: table;
+  line-height: 0;
+}
+.ui-grid-footer-canvas:after {
+  clear: both;
+}
+.ui-grid-footer-cell {
+  overflow: hidden;
+  float: left;
+  background-color: inherit;
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+  box-sizing: border-box;
+}
+.ui-grid-footer-cell:last-child {
+  border-right: 0;
+}
+.ui-grid-footer .ui-grid-vertical-bar {
+  top: 0;
+  bottom: 0;
+}
+input[type="text"].ui-grid-filter-input {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  width: 100%;
+  border: 1px solid #d4d4d4;
+  -webkit-border-top-right-radius: 0px;
+  -webkit-border-bottom-right-radius: 0;
+  -webkit-border-bottom-left-radius: 0;
+  -webkit-border-top-left-radius: 0;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0;
+  -moz-border-radius-bottomleft: 0;
+  -moz-border-radius-topleft: 0;
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+}
+input[type="text"].ui-grid-filter-input:hover {
+  border: 1px solid #d4d4d4;
+}
+.ui-grid-menu-button {
+  z-index: 2;
+  position: absolute;
+  right: 0;
+  background: #f3f3f3;
+  border: 1px solid #d4d4d4;
+  cursor: pointer;
+  min-height: 27px;
+  font-weight: normal;
+}
+.ui-grid-menu-button .ui-grid-icon-container {
+  margin-top: 3px;
+}
+.ui-grid-menu-button .ui-grid-menu {
+  right: 0;
+}
+.ui-grid-menu {
+  z-index: 2;
+  position: fixed;
+  overflow: hidden;
+  padding: 0 10px 20px 10px;
+  cursor: pointer;
+  box-sizing: content-box;
+}
+.ui-grid-menu .ui-grid-menu-inner {
+  background: #f3f3f3;
+  border: 1px solid #d4d4d4;
+  position: relative;
+  white-space: nowrap;
+  -webkit-border-radius: 0px;
+  -moz-border-radius: 0px;
+  border-radius: 0px;
+  -webkit-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);
+}
+.ui-grid-menu .ui-grid-menu-inner ul {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li {
+  padding: 8px;
+  cursor: pointer;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li:hover {
+  -webkit-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+}
+.ui-grid-menu .ui-grid-menu-inner ul li.ui-grid-menu-item-active {
+  -webkit-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+  background-color: #cecece;
+}
+.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child) {
+  border-bottom: 1px solid #d4d4d4;
+}
+.ui-grid-sortarrow {
+  right: 5px;
+  position: absolute;
+  width: 20px;
+  top: 0;
+  bottom: 0;
+  background-position: center;
+}
+.ui-grid-sortarrow.down {
+  -webkit-transform: rotate(180deg);
+  -moz-transform: rotate(180deg);
+  -o-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+@font-face {
+  font-family: 'ui-grid';
+  src: url('ui-grid.eot');
+  src: url('ui-grid.eot#iefix') format('embedded-opentype'), url('ui-grid.woff') format('woff'), url('ui-grid.ttf?') format('truetype'), url('ui-grid.svg?#ui-grid') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
+/*
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+  @font-face {
+    font-family: 'ui-grid';
+    src: url('../font/ui-grid.svg?12312827#ui-grid') format('svg');
+  }
+}
+*/
+[class^="ui-grid-icon"]:before,
+[class*=" ui-grid-icon"]:before {
+  font-family: "ui-grid";
+  font-style: normal;
+  font-weight: normal;
+  speak: none;
+  display: inline-block;
+  text-decoration: inherit;
+  width: 1em;
+  margin-right: .2em;
+  text-align: center;
+  /* opacity: .8; */
+  /* For safety - reset parent styles, that can break glyph codes*/
+  font-variant: normal;
+  text-transform: none;
+  /* fix buttons height, for twitter bootstrap */
+  line-height: 1em;
+  /* Animation center compensation - margins should be symmetric */
+  /* remove if not needed */
+  margin-left: .2em;
+  /* you can be more comfortable with increased icons size */
+  /* font-size: 120%; */
+  /* Uncomment for 3D effect */
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
+}
+.ui-grid-icon-blank::before {
+  width: 1em;
+  content: ' ';
+}
+/*
+* RTL Styles
+*/
+.ui-grid[dir=rtl] .ui-grid-header-cell,
+.ui-grid[dir=rtl] .ui-grid-footer-cell,
+.ui-grid[dir=rtl] .ui-grid-cell {
+  float: right !important;
+}
+.ui-grid[dir=rtl] .ui-grid-scrollbar-horizontal {
+  left: inherit;
+  right: 0;
+}
+.ui-grid[dir=rtl] .ui-grid-native-scrollbar.vertical {
+  left: 0;
+  right: inherit;
+}
+.ui-grid[dir=rtl] .ui-grid-column-menu-button {
+  position: absolute;
+  left: 1px;
+  top: 0;
+  right: inherit;
+}
+.ui-grid[dir=rtl] .ui-grid-cell:first-child,
+.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,
+.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child {
+  border-right: 0;
+}
+.ui-grid[dir=rtl] .ui-grid-cell:last-child {
+  border-right: 1px solid;
+  border-color: #d4d4d4;
+}
+.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,
+.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,
+.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar {
+  width: 0;
+}
+.ui-grid[dir=rtl] .ui-grid-menu-button {
+  z-index: 2;
+  position: absolute;
+  left: 0;
+  right: auto;
+  background: #f3f3f3;
+  border: 1px solid #d4d4d4;
+  cursor: pointer;
+  min-height: 27px;
+  font-weight: normal;
+}
+.ui-grid[dir=rtl] .ui-grid-menu-button .ui-grid-menu {
+  left: 0;
+  right: auto;
+}
+.ui-grid[dir="rtl"] .ui-grid-filter-container .ui-grid-filter-button {
+  right: initial;
+  left: 0;
+}
+.ui-grid[dir="rtl"] .ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"] {
+  right: initial;
+  left: 10px;
+}
+/*
+   Animation example, for spinners
+*/
+.ui-grid-animate-spin {
+  -moz-animation: ui-grid-spin 2s infinite linear;
+  -o-animation: ui-grid-spin 2s infinite linear;
+  -webkit-animation: ui-grid-spin 2s infinite linear;
+  animation: ui-grid-spin 2s infinite linear;
+  display: inline-block;
+}
+@-moz-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-webkit-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-o-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@-ms-keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+@keyframes ui-grid-spin {
+  0% {
+    -moz-transform: rotate(0deg);
+    -o-transform: rotate(0deg);
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+    -o-transform: rotate(359deg);
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+/*---------------------------------------------------
+    LESS Elements 0.9
+  ---------------------------------------------------
+    A set of useful LESS mixins
+    More info at: http://lesselements.com
+  ---------------------------------------------------*/
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-cell-focus {
+  outline: 0;
+  background-color: #b3c4c7;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+div.ui-grid-cell input {
+  border-radius: inherit;
+  padding: 0;
+  width: 100%;
+  color: inherit;
+  height: auto;
+  font: inherit;
+  outline: none;
+}
+div.ui-grid-cell input:focus {
+  color: inherit;
+  outline: none;
+}
+div.ui-grid-cell input[type="checkbox"] {
+  margin: 9px 0 0 6px;
+  width: auto;
+}
+div.ui-grid-cell input.ng-invalid {
+  border: 1px solid #fc8f8f;
+}
+div.ui-grid-cell input.ng-valid {
+  border: 1px solid #d4d4d4;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell {
+  background-color: #fdfdfd;
+}
+.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell {
+  background-color: #f3f3f3;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.movingColumn {
+  position: fixed;
+  border: 1px solid #d4d4d4;
+  box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.2);
+}
+.movingColumn .ui-grid-icon-angle-down {
+  display: none;
+}
+
+.ui-grid-pager-panel {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  padding-top: 3px;
+  padding-bottom: 3px;
+}
+.ui-grid-pager-container {
+  float: left;
+}
+.ui-grid-pager-control {
+  margin-right: 10px;
+  margin-left: 10px;
+  min-width: 135px;
+  float: left;
+}
+.ui-grid-pager-control button {
+  height: 25px;
+  min-width: 26px;
+}
+.ui-grid-pager-control input {
+  height: 26px;
+  width: 50px;
+  vertical-align: top;
+}
+.ui-grid-pager-control .first-bar {
+  width: 10px;
+  border-left: 2px solid #4d4d4d;
+  margin-top: -6px;
+  height: 12px;
+  margin-left: -3px;
+}
+.ui-grid-pager-control .first-triangle {
+  width: 0;
+  height: 0;
+  border-style: solid;
+  border-width: 5px 8.7px 5px 0;
+  border-color: transparent #4d4d4d transparent transparent;
+  margin-left: 2px;
+}
+.ui-grid-pager-control .next-triangle {
+  margin-left: 1px;
+}
+.ui-grid-pager-control .prev-triangle {
+  margin-left: 0;
+}
+.ui-grid-pager-control .last-triangle {
+  width: 0;
+  height: 0;
+  border-style: solid;
+  border-width: 5px 0 5px 8.7px;
+  border-color: transparent transparent transparent #4d4d4d;
+  margin-left: -1px;
+}
+.ui-grid-pager-control .last-bar {
+  width: 10px;
+  border-left: 2px solid #4d4d4d;
+  margin-top: -6px;
+  height: 12px;
+  margin-left: 1px;
+}
+.ui-grid-pager-row-count-picker {
+  float: left;
+}
+.ui-grid-pager-row-count-picker select {
+  height: 26px;
+  width: 60px;
+}
+.ui-grid-pager-row-count-picker .ui-grid-pager-row-count-label {
+  margin-top: 3px;
+}
+.ui-grid-pager-count-container {
+  float: right;
+  margin-top: 4px;
+  min-width: 50px;
+}
+.ui-grid-pager-count-container .ui-grid-pager-count {
+  margin-right: 10px;
+  margin-left: 10px;
+  float: right;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-pinned-container {
+  float: left;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child {
+  box-sizing: border-box;
+  border-right: 1px solid;
+  border-width: 1px;
+  border-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child {
+  box-sizing: border-box;
+  border-right: 1px solid;
+  border-width: 1px;
+  border-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,
+.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  width: 1px;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #d4d4d4;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar {
+  background-color: #aeaeae;
+}
+.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar {
+  right: -1px;
+  width: 1px;
+  background-color: #aeaeae;
+}
+.ui-grid-render-container-body {
+  float: left;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-column-resizer {
+  top: 0;
+  bottom: 0;
+  width: 5px;
+  position: absolute;
+  cursor: col-resize;
+}
+.ui-grid-column-resizer.left {
+  left: 0;
+}
+.ui-grid-column-resizer.right {
+  right: 0;
+}
+.ui-grid.column-resizing {
+  cursor: col-resize;
+}
+.ui-grid.column-resizing .ui-grid-resize-overlay {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  width: 1px;
+  background-color: #aeaeae;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-row-saving .ui-grid-cell {
+  color: #848484 !important;
+}
+.ui-grid-row-dirty .ui-grid-cell {
+  color: #610b38;
+}
+.ui-grid-row-error .ui-grid-cell {
+  color: #ff0000 !important;
+}
+
+/* This file contains variable declarations (do not remove this line) */
+/*-- VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+/**
+* @section Grid styles
+*/
+/**
+* @section Header styles
+*/
+/** @description Colors for header gradient */
+/**
+* @section Grid body styles
+*/
+/** @description Colors used for row alternation */
+/**
+* @section Sort arrow colors
+*/
+/**
+* @section Scrollbar styles
+*/
+/**
+* @section font library path
+*/
+/*-- END VARIABLES (DO NOT REMOVE THESE COMMENTS) --*/
+.ui-grid-row-selected .ui-grid-cell {
+  background-color: #c9dde1 !important;
+}
+.ui-grid-disable-selection {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  cursor: default;
+}
+.ui-grid-selection-row-header-buttons {
+  cursor: pointer;
+  opacity: 0.1;
+}
+.ui-grid-selection-row-header-buttons.ui-grid-row-selected {
+  opacity: 1;
+}
+.ui-grid-selection-row-header-buttons.ui-grid-all-selected {
+  opacity: 1;
+}
+
+.ui-grid-icon-plus-squared:before {
+  content: '\c350';
+}
+/* '썐' */
+.ui-grid-icon-minus-squared:before {
+  content: '\c351';
+}
+/* '썑' */
+.ui-grid-icon-search:before {
+  content: '\c352';
+}
+/* '썒' */
+.ui-grid-icon-cancel:before {
+  content: '\c353';
+}
+/* '썓' */
+.ui-grid-icon-info-circled:before {
+  content: '\c354';
+}
+/* '썔' */
+.ui-grid-icon-lock:before {
+  content: '\c355';
+}
+/* '썕' */
+.ui-grid-icon-lock-open:before {
+  content: '\c356';
+}
+/* '썖' */
+.ui-grid-icon-pencil:before {
+  content: '\c357';
+}
+/* '썗' */
+.ui-grid-icon-down-dir:before {
+  content: '\c358';
+}
+/* '썘' */
+.ui-grid-icon-up-dir:before {
+  content: '\c359';
+}
+/* '썙' */
+.ui-grid-icon-left-dir:before {
+  content: '\c35a';
+}
+/* '썚' */
+.ui-grid-icon-right-dir:before {
+  content: '\c35b';
+}
+/* '썛' */
+.ui-grid-icon-left-open:before {
+  content: '\c35c';
+}
+/* '썜' */
+.ui-grid-icon-right-open:before {
+  content: '\c35d';
+}
+/* '썝' */
+.ui-grid-icon-angle-down:before {
+  content: '\c35e';
+}
+/* '썞' */
+.ui-grid-icon-filter:before {
+  content: '\c35f';
+}
+/* '썟' */
+.ui-grid-icon-sort-alt-up:before {
+  content: '\c360';
+}
+/* '썠' */
+.ui-grid-icon-sort-alt-down:before {
+  content: '\c361';
+}
+/* '썡' */
+.ui-grid-icon-ok:before {
+  content: '\c362';
+}
+/* '썢' */
+.ui-grid-icon-menu:before {
+  content: '\c363';
+}
+/* '썣' */
+.ui-grid-icon-spin5:before {
+  content: '\ea61';
+}
+/* '' */
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.eot b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.eot
new file mode 100644 (file)
index 0000000..88b133b
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.min.css b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.min.css
new file mode 100644 (file)
index 0000000..cc065e9
--- /dev/null
@@ -0,0 +1,13 @@
+.ui-grid{border:1px solid #d4d4d4;box-sizing:content-box;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}.ui-grid-vertical-bar{position:absolute;right:0;width:0}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#d4d4d4}.ui-grid-clearfix:before,.ui-grid-clearfix:after{content:"";display:table}.ui-grid-clearfix:after{clear:both}.ui-grid-invisible{visibility:hidden}.ui-grid-top-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-header{border-bottom:1px solid #d4d4d4;box-sizing:content-box}.ui-grid-top-panel{position:relative;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-group-panel{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);border-bottom:1px solid #d4d4d4;-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;min-height:30px}.ui-grid-header-group-panel .hidden{display:none}.ui-grid-header-viewport{overflow:hidden}.ui-grid-header-canvas{position:relative}.ui-grid-header-canvas:before,.ui-grid-header-canvas:after{content:"";display:table;line-height:0}.ui-grid-header-canvas:after{clear:both}.ui-grid-header-cell{position:relative;float:left;top:0;bottom:0;background-color:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:0}.ui-grid-header-cell .sortable{cursor:pointer}.ui-grid-header .ui-grid-vertical-bar{top:0;bottom:0}.ui-grid-column-menu-button{position:absolute;right:1px;top:0}.ui-grid-column-menu-button .ui-grid-icon-angle-down{vertical-align:sub}.ui-grid-column-menu{position:absolute}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-column-menu .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transition:all .05s linear;-moz-transition:all .05s linear;-o-transition:all .05s linear;transition:all .05s linear;display:block !important}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add.ng-hide-add-active,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-o-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%)}.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-add,.ui-grid-menu-button .ui-grid-menu .ui-grid-menu-mid.ng-hide-remove.ng-hide-remove-active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.ui-grid-filter-container{padding:4px 10px;position:relative}.ui-grid-filter-container .ui-grid-filter-button{position:absolute;top:0;bottom:0;right:0}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{position:absolute;top:50%;line-height:32px;margin-top:-16px;right:10px;opacity:0.66}.ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]:hover{opacity:1}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-render-container{position:inherit;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-render-container:focus{outline:none}.ui-grid-viewport{min-height:20px;position:relative;overflow:hidden}.ui-grid-viewport :focus{outline:none}.ui-grid-canvas{position:relative}.ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}.ui-grid-row:last-child .ui-grid-cell{border-bottom-color:#d4d4d4;border-bottom-style:solid}.ui-grid-no-row-overlay{position:absolute;top:0;bottom:0;left:0;right:0;margin:10%;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #d4d4d4;font-size:2em;text-align:center}.ui-grid-no-row-overlay>*{position:absolute;display:table;margin:auto 0;width:100%;top:0;bottom:0;left:0;right:0;opacity:0.66}.ui-grid-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-cell:last-child{border-right:0}.ui-grid-cell-contents{padding:5px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;height:100%}.ui-grid-cell-contents-hidden{visibility:hidden;width:0;height:0;display:none}.ui-grid-row-header-cell{background-color:#F0F0EE !important;border-bottom:solid 1px #d4d4d4}.ui-grid-native-scrollbar{position:absolute;overflow:scroll}.ui-grid-native-scrollbar.vertical{top:0;right:0;height:100%;overflow-x:hidden;width:17px}.ui-grid-native-scrollbar.horizontal{bottom:0;left:0;width:100%;overflow-y:hidden;height:17px}.ui-grid-footer-panel-background{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0)}.ui-grid-footer-panel{position:relative;border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;overflow:hidden;font-weight:bold;background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}.ui-grid-group-panel{background:#f3f3f3;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(1, #fff));background:-ms-linear-gradient(bottom, #eee, #fff);background:-moz-linear-gradient(center bottom, #eee 0, #fff 100%);background:-o-linear-gradient(#fff, #eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);border-bottom:1px solid #d4d4d4;border-top:1px solid #d4d4d4;-webkit-border-top-right-radius:-1px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:-1px;-moz-border-radius-topright:-1px;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:-1px;border-top-right-radius:-1px;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:-1px;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;min-height:30px}.ui-grid-footer-group-panel .hidden{display:none}.ui-grid-footer-viewport{overflow:hidden}.ui-grid-footer-canvas{position:relative}.ui-grid-footer-canvas:before,.ui-grid-footer-canvas:after{content:"";display:table;line-height:0}.ui-grid-footer-canvas:after{clear:both}.ui-grid-footer-cell{overflow:hidden;float:left;background-color:inherit;border-right:1px solid;border-color:#d4d4d4;box-sizing:border-box}.ui-grid-footer-cell:last-child{border-right:0}.ui-grid-footer .ui-grid-vertical-bar{top:0;bottom:0}input[type="text"].ui-grid-filter-input{padding:0;margin:0;border:0;width:100%;border:1px solid #d4d4d4;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box}input[type="text"].ui-grid-filter-input:hover{border:1px solid #d4d4d4}.ui-grid-menu-button{z-index:2;position:absolute;right:0;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;min-height:27px;font-weight:normal}.ui-grid-menu-button .ui-grid-icon-container{margin-top:3px}.ui-grid-menu-button .ui-grid-menu{right:0}.ui-grid-menu{z-index:2;position:fixed;overflow:hidden;padding:0 10px 20px 10px;cursor:pointer;box-sizing:content-box}.ui-grid-menu .ui-grid-menu-inner{background:#f3f3f3;border:1px solid #d4d4d4;position:relative;white-space:nowrap;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2);box-shadow:0 10px 20px rgba(0, 0, 0, 0.2), inset 0 12px 12px -14px rgba(0, 0, 0, 0.2)}.ui-grid-menu .ui-grid-menu-inner ul{margin:0;padding:0;list-style-type:none}.ui-grid-menu .ui-grid-menu-inner ul li{padding:8px;cursor:pointer}.ui-grid-menu .ui-grid-menu-inner ul li:hover{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.ui-grid-menu .ui-grid-menu-inner ul li.ui-grid-menu-item-active{-webkit-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0 14px rgba(0,0,0,0.2);box-shadow:inset 0 0 14px rgba(0,0,0,0.2);background-color:#cecece}.ui-grid-menu .ui-grid-menu-inner ul li:not(:last-child){border-bottom:1px solid #d4d4d4}.ui-grid-sortarrow{right:5px;position:absolute;width:20px;top:0;bottom:0;background-position:center}.ui-grid-sortarrow.down{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}@font-face{font-family:'ui-grid';src:url('ui-grid.eot');src:url('ui-grid.eot#iefix') format('embedded-opentype'),url('ui-grid.woff') format('woff'),url('ui-grid.ttf?') format('truetype'),url('ui-grid.svg?#ui-grid') format('svg');font-weight:normal;font-style:normal}[class^="ui-grid-icon"]:before,[class*=" ui-grid-icon"]:before{font-family:"ui-grid";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.ui-grid-icon-blank::before{width:1em;content:' '}.ui-grid[dir=rtl] .ui-grid-header-cell,.ui-grid[dir=rtl] .ui-grid-footer-cell,.ui-grid[dir=rtl] .ui-grid-cell{float:right !important}.ui-grid[dir=rtl] .ui-grid-scrollbar-horizontal{left:inherit;right:0}.ui-grid[dir=rtl] .ui-grid-native-scrollbar.vertical{left:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-column-menu-button{position:absolute;left:1px;top:0;right:inherit}.ui-grid[dir=rtl] .ui-grid-cell:first-child,.ui-grid[dir=rtl] .ui-grid-header-cell:first-child,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child{border-right:0}.ui-grid[dir=rtl] .ui-grid-cell:last-child{border-right:1px solid;border-color:#d4d4d4}.ui-grid[dir=rtl] .ui-grid-header-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-footer-cell:first-child .ui-grid-vertical-bar,.ui-grid[dir=rtl] .ui-grid-cell:first-child .ui-grid-vertical-bar{width:0}.ui-grid[dir=rtl] .ui-grid-menu-button{z-index:2;position:absolute;left:0;right:auto;background:#f3f3f3;border:1px solid #d4d4d4;cursor:pointer;min-height:27px;font-weight:normal}.ui-grid[dir=rtl] .ui-grid-menu-button .ui-grid-menu{left:0;right:auto}.ui-grid[dir="rtl"] .ui-grid-filter-container .ui-grid-filter-button{right:initial;left:0}.ui-grid[dir="rtl"] .ui-grid-filter-container .ui-grid-filter-button [class^="ui-grid-icon"]{right:initial;left:10px}.ui-grid-animate-spin{-moz-animation:ui-grid-spin 2s infinite linear;-o-animation:ui-grid-spin 2s infinite linear;-webkit-animation:ui-grid-spin 2s infinite linear;animation:ui-grid-spin 2s infinite linear;display:inline-block}@-moz-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes ui-grid-spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}
+.ui-grid-cell-focus{outline:0;background-color:#b3c4c7}
+div.ui-grid-cell input{border-radius:inherit;padding:0;width:100%;color:inherit;height:auto;font:inherit;outline:none}div.ui-grid-cell input:focus{color:inherit;outline:none}div.ui-grid-cell input[type="checkbox"]{margin:9px 0 0 6px;width:auto}div.ui-grid-cell input.ng-invalid{border:1px solid #fc8f8f}div.ui-grid-cell input.ng-valid{border:1px solid #d4d4d4}
+.expandableRow .ui-grid-row:nth-child(odd) .ui-grid-cell{background-color:#fdfdfd}.expandableRow .ui-grid-row:nth-child(even) .ui-grid-cell{background-color:#f3f3f3}
+
+
+.movingColumn{position:fixed;border:1px solid #d4d4d4;box-shadow:inset 0 0 14px rgba(0,0,0,0.2)}.movingColumn .ui-grid-icon-angle-down{display:none}
+.ui-grid-pager-panel{position:absolute;left:0;bottom:0;width:100%;padding-top:3px;padding-bottom:3px}.ui-grid-pager-container{float:left}.ui-grid-pager-control{margin-right:10px;margin-left:10px;min-width:135px;float:left}.ui-grid-pager-control button{height:25px;min-width:26px}.ui-grid-pager-control input{height:26px;width:50px;vertical-align:top}.ui-grid-pager-control .first-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:-3px}.ui-grid-pager-control .first-triangle{width:0;height:0;border-style:solid;border-width:5px 8.7px 5px 0;border-color:transparent #4d4d4d transparent transparent;margin-left:2px}.ui-grid-pager-control .next-triangle{margin-left:1px}.ui-grid-pager-control .prev-triangle{margin-left:0}.ui-grid-pager-control .last-triangle{width:0;height:0;border-style:solid;border-width:5px 0 5px 8.7px;border-color:transparent transparent transparent #4d4d4d;margin-left:-1px}.ui-grid-pager-control .last-bar{width:10px;border-left:2px solid #4d4d4d;margin-top:-6px;height:12px;margin-left:1px}.ui-grid-pager-row-count-picker{float:left}.ui-grid-pager-row-count-picker select{height:26px;width:60px}.ui-grid-pager-row-count-picker .ui-grid-pager-row-count-label{margin-top:3px}.ui-grid-pager-count-container{float:right;margin-top:4px;min-width:50px}.ui-grid-pager-count-container .ui-grid-pager-count{margin-right:10px;margin-left:10px;float:right}
+.ui-grid-pinned-container{float:left}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:last-child{box-sizing:border-box;border-right:1px solid;border-width:1px;border-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar,.ui-grid-pinned-container .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{width:1px}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#d4d4d4}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-cell:not(:last-child) .ui-grid-vertical-bar{background-color:#aeaeae}.ui-grid-pinned-container.ui-grid-pinned-container-left .ui-grid-header-cell:last-child .ui-grid-vertical-bar{right:-1px;width:1px;background-color:#aeaeae}.ui-grid-render-container-body{float:left}
+.ui-grid-column-resizer{top:0;bottom:0;width:5px;position:absolute;cursor:col-resize}.ui-grid-column-resizer.left{left:0}.ui-grid-column-resizer.right{right:0}.ui-grid.column-resizing{cursor:col-resize}.ui-grid.column-resizing .ui-grid-resize-overlay{position:absolute;top:0;height:100%;width:1px;background-color:#aeaeae}
+.ui-grid-row-saving .ui-grid-cell{color:#848484 !important}.ui-grid-row-dirty .ui-grid-cell{color:#610b38}.ui-grid-row-error .ui-grid-cell{color:#f00 !important}
+.ui-grid-row-selected .ui-grid-cell{background-color:#c9dde1 !important}.ui-grid-disable-selection{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.ui-grid-selection-row-header-buttons{cursor:pointer;opacity:0.1}.ui-grid-selection-row-header-buttons.ui-grid-row-selected{opacity:1}.ui-grid-selection-row-header-buttons.ui-grid-all-selected{opacity:1}
+.ui-grid-icon-plus-squared:before{content:'\c350'}.ui-grid-icon-minus-squared:before{content:'\c351'}.ui-grid-icon-search:before{content:'\c352'}.ui-grid-icon-cancel:before{content:'\c353'}.ui-grid-icon-info-circled:before{content:'\c354'}.ui-grid-icon-lock:before{content:'\c355'}.ui-grid-icon-lock-open:before{content:'\c356'}.ui-grid-icon-pencil:before{content:'\c357'}.ui-grid-icon-down-dir:before{content:'\c358'}.ui-grid-icon-up-dir:before{content:'\c359'}.ui-grid-icon-left-dir:before{content:'\c35a'}.ui-grid-icon-right-dir:before{content:'\c35b'}.ui-grid-icon-left-open:before{content:'\c35c'}.ui-grid-icon-right-open:before{content:'\c35d'}.ui-grid-icon-angle-down:before{content:'\c35e'}.ui-grid-icon-filter:before{content:'\c35f'}.ui-grid-icon-sort-alt-up:before{content:'\c360'}.ui-grid-icon-sort-alt-down:before{content:'\c361'}.ui-grid-icon-ok:before{content:'\c362'}.ui-grid-icon-menu:before{content:'\c363'}.ui-grid-icon-spin5:before{content:'\ea61'}
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.svg b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.svg
new file mode 100644 (file)
index 0000000..ad8cdc6
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
+<defs>
+<font id="ui-grid" horiz-adv-x="1000" >
+<font-face font-family="ui-grid" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="plus-squared" unicode="&#xc350;" d="m0 82v536q0 66 47 113t114 48h535q67 0 114-48t47-113v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113z m143 232q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-26-10t-10-25v-72z" horiz-adv-x="857.1" />
+<glyph glyph-name="minus-squared" unicode="&#xc351;" d="m0 82v536q0 66 47 113t114 48h535q67 0 114-48t47-113v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113z m143 232q0-14 11-25t25-10h500q14 0 25 10t10 25v72q0 14-10 25t-25 10h-500q-15 0-26-10t-10-25v-72z" horiz-adv-x="857.1" />
+<glyph glyph-name="search" unicode="&#xc352;" d="m0 386q0 80 31 152t84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51 0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 83-84 126-31 153z m143 0q0-103 73-177t177-73 176 73 74 177-74 176-176 74-177-74-73-176z" horiz-adv-x="928.6" />
+<glyph glyph-name="cancel" unicode="&#xc353;" d="m61 112q0 23 16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38t-15-38l-76-76q-16-15-38-15t-38 15l-164 164-164-164q-16-15-38-15t-38 15l-76 76q-16 16-16 38z" horiz-adv-x="785.7" />
+<glyph glyph-name="info-circled" unicode="&#xc354;" d="m0 350q0 117 58 215t155 156 216 58 215-58 156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215z m286-268q0-8 5-13t13-5h250q7 0 12 5t5 13v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89z m71 500q0-8 5-13t13-5h107q8 0 13 5t5 13v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89z" horiz-adv-x="857.1" />
+<glyph glyph-name="lock" unicode="&#xc355;" d="m0 46v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37z m179 375h285v108q0 59-42 101t-101 41-101-41-41-101v-108z" horiz-adv-x="642.9" />
+<glyph glyph-name="lock-open" unicode="&#xc356;" d="m0 46v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37z" horiz-adv-x="928.6" />
+<glyph glyph-name="pencil" unicode="&#xc357;" d="m0-79v233l464 464 232-232-464-465h-232z m71 143h72v-71h60l50 51-131 131-51-51v-60z m95 143q0-12 13-12 5 0 9 4l303 302q3 4 3 10 0 12-12 12-5 0-9-4l-303-302q-4-4-4-10z m334 447l93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51 0-29-20-50l-93-93z" horiz-adv-x="857.1" />
+<glyph glyph-name="down-dir" unicode="&#xc358;" d="m0 457q0 15 11 25t25 11h500q14 0 25-11t10-25-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25z" horiz-adv-x="571.4" />
+<glyph glyph-name="up-dir" unicode="&#xc359;" d="m0 171q0 15 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26t-10-25-25-10h-500q-15 0-25 10t-11 25z" horiz-adv-x="571.4" />
+<glyph glyph-name="left-dir" unicode="&#xc35a;" d="m36 350q0 15 10 25l250 250q11 11 25 11t26-11 10-25v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25z" horiz-adv-x="357.1" />
+<glyph glyph-name="right-dir" unicode="&#xc35b;" d="m0 100v500q0 15 11 25t25 11 25-11l250-250q10-10 10-25t-10-25l-250-250q-11-11-25-11t-25 11-11 25z" horiz-adv-x="357.1" />
+<glyph glyph-name="left-open" unicode="&#xc35c;" d="m86 386q0 14 11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25z" horiz-adv-x="714.3" />
+<glyph glyph-name="right-open" unicode="&#xc35d;" d="m50 64q0 15 11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25l-414-414q-11-11-25-11t-26 11l-92 92q-11 11-11 25z" horiz-adv-x="714.3" />
+<glyph glyph-name="angle-down" unicode="&#xc35e;" d="m43 439q0 8 6 13l27 28q6 6 13 6t13-6l219-219 220 219q5 6 13 6t12-6l28-28q6-5 6-13t-6-13l-260-260q-5-5-13-5t-12 5l-260 260q-6 6-6 13z" horiz-adv-x="642.9" />
+<glyph glyph-name="filter" unicode="&#xc35f;" d="m3 685q9 22 33 22h714q23 0 33-22 9-23-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 10-10 25v271l-275 275q-18 16-8 39z" horiz-adv-x="785.7" />
+<glyph glyph-name="sort-alt-up" unicode="&#xc360;" d="m19 53q4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19z m481-78q0 8 5 13t13 5h464q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107z m0 179v107q0 8 5 13t13 5h357q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13z m0 285v107q0 8 5 13t13 5h250q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13z m0 286v107q0 8 5 13t13 5h143q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13z" horiz-adv-x="1000" />
+<glyph glyph-name="sort-alt-down" unicode="&#xc361;" d="m19 53q4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19z m481-78q0 8 5 13t13 5h143q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107z m0 179v107q0 8 5 13t13 5h250q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13z m0 285v107q0 8 5 13t13 5h357q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13z m0 286v107q0 8 5 13t13 5h464q8 0 13-5t5-13v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13z" horiz-adv-x="1000" />
+<glyph glyph-name="ok" unicode="&#xe800;" d="m68 332q0 22 15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q15-16 15-38t-15-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38z" horiz-adv-x="1000" />
+<glyph glyph-name="spin5" unicode="&#xea61;" d="m462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-35c0 0 0 0 0 0 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 10 4 16l-35 61c-2 3-6 5-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-92 0 0c6-3 13-1 16 5l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-2 16 4l35 61c3 5 1 12-4 15l-158 91 0 0c-2 1-4 2-6 2z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-11-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 5-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-3c-4 1-8-2-10-5l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 34c0 1 0 1 0 1-2 1-4 1-6 1z m149-57c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" />
+</font>
+</defs>
+</svg>
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.ttf b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.ttf
new file mode 100644 (file)
index 0000000..d2dc304
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.woff b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.woff
new file mode 100644 (file)
index 0000000..e11bc65
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid-unstable.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.css b/src/main/resources/META-INF/resources/designer/css/ui-grid.css
new file mode 100644 (file)
index 0000000..b31f2f5
--- /dev/null
@@ -0,0 +1,14 @@
+.ui-grid-header-table {
+  margin-bottom: 0;
+}
+.ui-grid-pinned.left {
+  float: left;
+}
+.ui-grid-pinned.right {
+  float: right;
+}
+.ui-grid-viewport tbody,
+.ui-grid-viewport table tr:first-child,
+.ui-grid-viewport table tr:first-child > td {
+  border-top: none;
+}
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.eot b/src/main/resources/META-INF/resources/designer/css/ui-grid.eot
new file mode 100644 (file)
index 0000000..4d98e71
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.min.css b/src/main/resources/META-INF/resources/designer/css/ui-grid.min.css
new file mode 100644 (file)
index 0000000..0506679
--- /dev/null
@@ -0,0 +1 @@
+.ui-grid-header-table{margin-bottom:0}.ui-grid-pinned.left{float:left}.ui-grid-pinned.right{float:right}.ui-grid-viewport tbody,.ui-grid-viewport table tr:first-child,.ui-grid-viewport table tr:first-child>td{border-top:none}
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.svg b/src/main/resources/META-INF/resources/designer/css/ui-grid.svg
new file mode 100644 (file)
index 0000000..e3138a3
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
+<defs>
+<font id="ui-grid" horiz-adv-x="1000" >
+<font-face font-family="ui-grid" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="plus-squared" unicode="&#xc350;" d="m714 314v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-26-10t-10-25v-72q0-14 10-25t26-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
+<glyph glyph-name="minus-squared" unicode="&#xc351;" d="m714 314v72q0 14-10 25t-25 10h-500q-15 0-26-10t-10-25v-72q0-14 10-25t26-10h500q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
+<glyph glyph-name="search" unicode="&#xc352;" d="m643 386q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
+<glyph glyph-name="cancel" unicode="&#xc353;" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
+<glyph glyph-name="info-circled" unicode="&#xc354;" d="m571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="lock" unicode="&#xc355;" d="m179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
+<glyph glyph-name="lock-open" unicode="&#xc356;" d="m929 529v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176z" horiz-adv-x="928.6" />
+<glyph glyph-name="pencil" unicode="&#xc357;" d="m203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
+<glyph glyph-name="down-dir" unicode="&#xc358;" d="m571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
+<glyph glyph-name="up-dir" unicode="&#xc359;" d="m571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
+<glyph glyph-name="left-dir" unicode="&#xc35a;" d="m357 600v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11 10-25z" horiz-adv-x="357.1" />
+<glyph glyph-name="right-dir" unicode="&#xc35b;" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11-11 25v500q0 15 11 25t25 11 25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
+<glyph glyph-name="left-open" unicode="&#xc35c;" d="m653 682l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25z" horiz-adv-x="714.3" />
+<glyph glyph-name="right-open" unicode="&#xc35d;" d="m618 361l-414-415q-11-10-25-10t-26 10l-92 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
+<glyph glyph-name="angle-down" unicode="&#xc35e;" d="m600 439q0-7-6-13l-260-260q-5-5-13-5t-12 5l-260 260q-6 6-6 13t6 13l27 28q6 6 13 6t13-6l219-219 220 219q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="642.9" />
+<glyph glyph-name="filter" unicode="&#xc35f;" d="m783 685q9-23-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 10-10 25v271l-275 275q-18 16-8 39 9 22 33 22h714q23 0 33-22z" horiz-adv-x="785.7" />
+<glyph glyph-name="sort-alt-up" unicode="&#xc360;" d="m411 46q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m589-71v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m-107 285v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z" horiz-adv-x="1000" />
+<glyph glyph-name="sort-alt-down" unicode="&#xc361;" d="m679-25v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z m-268 71q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m375 215v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m107 285v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m107 286v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z" horiz-adv-x="1000" />
+<glyph glyph-name="ok" unicode="&#xc362;" d="m932 534q0-22-15-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q15-16 15-38z" horiz-adv-x="1000" />
+<glyph glyph-name="menu" unicode="&#xc363;" d="m857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
+<glyph glyph-name="spin5" unicode="&#xea61;" d="m462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-35c0 0 0 0 0 0 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 10 4 16l-35 61c-2 3-6 5-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-92 0 0c6-3 13-1 16 5l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-2 16 4l35 61c3 5 1 12-4 15l-158 91 0 0c-2 1-4 2-6 2z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-11-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 5-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-3c-4 1-8-2-10-5l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 34c0 1 0 1 0 1-2 1-4 1-6 1z m149-57c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" />
+</font>
+</defs>
+</svg>
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.ttf b/src/main/resources/META-INF/resources/designer/css/ui-grid.ttf
new file mode 100644 (file)
index 0000000..838611a
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/css/ui-grid.woff b/src/main/resources/META-INF/resources/designer/css/ui-grid.woff
new file mode 100644 (file)
index 0000000..ca1a9c6
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/css/ui-grid.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/css/utm_custom_style.css b/src/main/resources/META-INF/resources/designer/css/utm_custom_style.css
new file mode 100644 (file)
index 0000000..3dd956f
--- /dev/null
@@ -0,0 +1,572 @@
+/*!
+ * Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
+ * Code licensed under the Apache License v2.0.
+ * For details, see http://www.apache.org/licenses/LICENSE-2.0.
+ */
+
+body {
+    background-color: #f8f8f8;
+}
+
+utm_body {
+    background-color: #f8f8f8;
+}
+
+#wrapper {
+    width: 100%;
+}
+
+#page-wrapper {
+    padding: 0 15px;
+    min-height: 568px;
+    background-color: #fff;
+}
+
+@media(min-width:768px) {
+    #page-wrapper {
+        position: inherit;
+        margin: 0 0 0 250px;
+        padding: 0 30px;
+        border-left: 1px solid #e7e7e7;
+    }
+}
+
+.navbar-top-links {
+    margin-right: 0;
+}
+
+.navbar-top-links li {
+    display: inline-block;
+}
+
+.navbar-top-links li:last-child {
+    margin-right: 15px;
+}
+
+.navbar-top-links li a {
+    padding: 15px;
+    min-height: 50px;
+}
+
+.navbar-top-links .dropdown-menu li {
+    display: block;
+}
+
+.navbar-top-links .dropdown-menu li:last-child {
+    margin-right: 0;
+}
+
+.navbar-top-links .dropdown-menu li a {
+    padding: 3px 20px;
+    min-height: 0;
+}
+
+.navbar-top-links .dropdown-menu li a div {
+    white-space: normal;
+}
+
+.navbar-top-links .dropdown-messages,
+.navbar-top-links .dropdown-tasks,
+.navbar-top-links .dropdown-alerts {
+    width: 310px;
+    min-width: 0;
+}
+
+.navbar-top-links .dropdown-messages {
+    margin-left: 5px;
+}
+
+.navbar-top-links .dropdown-tasks {
+    margin-left: -59px;
+}
+
+.navbar-top-links .dropdown-alerts {
+    margin-left: -123px;
+}
+
+.navbar-top-links .dropdown-user {
+    right: 0;
+    left: auto;
+}
+
+.sidebar .sidebar-nav.navbar-collapse {
+    padding-right: 0;
+    padding-left: 0;
+}
+
+.sidebar .sidebar-search {
+    padding: 15px;
+}
+
+.sidebar ul li {
+    border-bottom: 1px solid #e7e7e7;
+}
+
+.sidebar ul li a.active {
+    background-color: #eee;
+}
+
+.sidebar .arrow {
+    float: right;
+}
+
+.sidebar .fa.arrow:before {
+    content: "\f104";
+}
+
+.sidebar .active>a>.fa.arrow:before {
+    content: "\f107";
+}
+
+.sidebar .nav-second-level li,
+.sidebar .nav-third-level li {
+    border-bottom: 0!important;
+}
+
+.sidebar .nav-second-level li a {
+    padding-left: 37px;
+}
+
+.sidebar .nav-third-level li a {
+    padding-left: 52px;
+}
+
+@media(min-width:768px) {
+    .sidebar {
+        z-index: 1;
+        position: absolute;
+        width: 250px;
+        margin-top: 51px;
+    }
+
+    .navbar-top-links .dropdown-messages,
+    .navbar-top-links .dropdown-tasks,
+    .navbar-top-links .dropdown-alerts {
+        margin-left: auto;
+    }
+}
+
+.btn-outline {
+    color: inherit;
+    background-color: transparent;
+    transition: all .5s;
+}
+
+.btn-primary.btn-outline {
+    color: #428bca;
+}
+
+.btn-success.btn-outline {
+    color: #5cb85c;
+}
+
+.btn-info.btn-outline {
+    color: #5bc0de;
+}
+
+.btn-warning.btn-outline {
+    color: #f0ad4e;
+}
+
+.btn-danger.btn-outline {
+    color: #d9534f;
+}
+
+.btn-primary.btn-outline:hover,
+.btn-success.btn-outline:hover,
+.btn-info.btn-outline:hover,
+.btn-warning.btn-outline:hover,
+.btn-danger.btn-outline:hover {
+    color: #fff;
+}
+
+.chat {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+}
+
+.chat li {
+    margin-bottom: 10px;
+    padding-bottom: 5px;
+    border-bottom: 1px dotted #999;
+}
+
+.chat li.left .chat-body {
+    margin-left: 60px;
+}
+
+.chat li.right .chat-body {
+    margin-right: 60px;
+}
+
+.chat li .chat-body p {
+    margin: 0;
+}
+
+.panel .slidedown .glyphicon,
+.chat .glyphicon {
+    margin-right: 5px;
+}
+
+.chat-panel .panel-body {
+    height: 350px;
+    overflow-y: scroll;
+}
+
+.login-panel {
+    margin-top: 25%;
+}
+
+.flot-chart {
+    display: block;
+    height: 400px;
+}
+
+.flot-chart-content {
+    width: 100%;
+    height: 100%;
+}
+
+
+.btn-circle {
+    width: 30px;
+    height: 30px;
+    padding: 6px 0;
+    border-radius: 15px;
+    text-align: center;
+    font-size: 12px;
+    line-height: 1.428571429;
+}
+
+.btn-circle.btn-lg {
+    width: 50px;
+    height: 50px;
+    padding: 10px 16px;
+    border-radius: 25px;
+    font-size: 18px;
+    line-height: 1.33;
+}
+
+.btn-circle.btn-xl {
+    width: 70px;
+    height: 70px;
+    padding: 10px 16px;
+    border-radius: 35px;
+    font-size: 24px;
+    line-height: 1.33;
+}
+
+.show-grid [class^=col-] {
+    padding-top: 10px;
+    padding-bottom: 10px;
+    border: 1px solid #ddd;
+    background-color: #eee!important;
+}
+
+.show-grid {
+    margin: 15px 0;
+}
+
+.huge {
+    font-size: 30px;
+}
+
+.panel-green {
+    border-color: #5cb85c;
+}
+
+.panel-green .panel-heading {
+    border-color: #5cb85c;
+    color: #fff;
+    background-color: #5cb85c;
+}
+
+.panel-green a {
+    color: #5cb85c;
+}
+
+.panel-green a:hover {
+    color: #3d8b3d;
+}
+
+.panel-red {
+    border-color: #d9534f;
+}
+
+.panel-red .panel-heading {
+    border-color: #d9534f;
+    color: #fff;
+    background-color: #d9534f;
+}
+
+.panel-red a {
+    color: #d9534f;
+}
+
+.panel-red a:hover {
+    color: #b52b27;
+}
+
+.panel-yellow {
+    border-color: #f0ad4e;
+}
+
+.panel-yellow .panel-heading {
+    border-color: #f0ad4e;
+    color: #fff;
+    background-color: #f0ad4e;
+}
+
+.panel-yellow a {
+    color: #f0ad4e;
+}
+
+.panel-yellow a:hover {
+    color: #df8a13;
+}
+
+.panel-primary a:hover {
+    color: #4E9BD6;
+}
+
+
+
+.spacer_left
+{
+       margin-left: 20px;
+}
+
+.spacer {
+                        margin-top: 10px; /* define margin as you see fit */
+               } 
+               
+               .spacer_40 {
+                        margin-top: 40px; /* define margin as you see fit */
+               }
+               
+               .spacer_80 {
+                        margin-top: 80px; /* define margin as you see fit */
+               } 
+               
+               .spacer_100 {
+                        margin-top: 100px; /* define margin as you see fit */
+               }  
+               
+               .spacer_66 {
+                        margin-top: 66px; /* define margin as you see fit */
+               } 
+               
+                               
+               .spacer_5 {
+                        margin-top: 5px; /* define margin as you see fit */
+               }  
+               
+               a{
+                   cursor: pointer;
+               }
+               
+               .cursor{
+                   cursor: pointer;
+               }
+               
+               
+               /*@media screen and (max-height: 700px) 
+               {
+                   #left 
+                   {
+                        height: 700px;
+                   }
+                   
+                   .right_transaction_trace
+                   {
+                        height: 600px;
+                   }
+               }*/
+               
+            *      {margin:0; padding:0;}
+           body   {position:absolute; width:100%; overflow: auto;}
+           #main  {height:100%; padding:60px 0 0px; box-sizing:border-box;background-color: white;overflow: auto;}
+           #head  {position:absolute; width:100%; height:60px;}
+           #left  {float:left; background-color: white; } 
+           #right {background-color: white; overflow:auto;}
+           #foot  {position:absolute; bottom:0; width:100%; height:40px;}
+            
+            
+        .features-table {
+                         width: 100%;
+                         margin: 0 auto;
+                         border-collapse: separate;
+                         border-spacing: 0;
+                         text-shadow: 0 1px 0 #fff;
+                         color: #2a2a2a;
+                         background: #fafafa;  
+                         background-image: linear-gradient(top, #fff, #eaeaea, #fff);
+                       }
+                       
+                       .features-table td {
+                         height: 20px;
+                         line-height: 500px;
+                         padding: 0 200px;
+                         border-bottom: 1px solid #cdcdcd;
+                         box-shadow: 0 1px 0 white;
+                         white-space: nowrap;
+                         text-align: center;
+                         cursor: pointer;
+                       }
+                       
+                       /*Body*/
+                       .features-table tbody td {
+                         text-align: left;
+                         font: normal 12px Verdana, Arial, Helvetica;
+                         width: 150px;                   
+                       }
+                       
+                       
+                       
+                       /*Header*/
+                       .features-table thead th 
+                       {
+                         font: bold 1.3em 'trebuchet MS', 'Lucida Sans', Arial;  
+                         border-radius-topright: 10px;
+                         border-radius-topleft: 10px; 
+                         border-top-right-radius: 10px;
+                         border-top-left-radius: 10px;
+                         border-top: 1px solid #eaeaea; 
+                         text-align: left;                                               
+                       }
+                                       
+                       
+                       /*Footer*/
+                       .features-table tfoot th 
+                       {
+                         font: bold 1.4em Georgia;  
+                         border-radius-bottomright: 10px;
+                         border-radius-bottomleft: 10px; 
+                         border-bottom-right-radius: 10px;
+                         border-bottom-left-radius: 10px;
+                         border-bottom: 1px solid #dadada;
+                       }
+
+
+
+/*
+       neeeeeeeeeeeeeeeeeeeeeeeeeeeeeewwwwwwwwwwwwwwwwwwww
+*/
+
+/*.slick-dots { margin: 0 100px 0 10px; width: auto; height: 20px; display: inline-block; }*/
+.slick-prev:before { 
+    color:blue !important;
+    margin-left: 5px;
+}
+.slick-next:before {
+       color:blue !important;
+       margin-right: 5px;
+}
+
+
+.grid_div div:hover 
+{
+       background: #3c8dbc;
+}
+
+.ui-grid-header-cell
+{
+       height:80px;
+       max-height:80px;
+}
+
+.tooltip
+{
+    position: static;   
+}
+
+span.err { color: #f00; }
+
+
+table.dataTable span.highlight {
+  background-color: #FFFF88;
+}
+
+table thead {
+       background-color: #eee; 
+}
+.modal-header{
+       background-color:#337ab7;
+       color: #FFF;
+       height: 38px;
+       margin-top: -4px;       
+
+}
+.modal {
+/* top:140px; */
+}
+
+.modal-header > h4{
+       margin-top: -2px;       
+       font-size: 12px !important;
+       font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+       color: #fff;
+}
+
+.modal-dialog {
+  padding-top: 7%;
+}
+
+.tab-border{
+border: 1px solid #ddd !important;
+border-top: 0px !important;
+}
+
+.zoom-controls {
+        position: absolute;
+        top: 0;
+ }
+
+ .zoom > span {
+     display: block;
+     margin-top: 3px;
+ }
+
+ .zoom:hover {
+     box-shadow: 0px 0px 6px #333;
+ }
+
+ .zoom {
+     width: 30px;
+     height: 30px;
+     cursor: pointer;
+     display: block;
+     position: absolute;
+     font-size: 20px;
+     font-weight: bold;
+     border: 1px solid #777;
+     background: white;
+     z-index: 100;
+     left: 10px;
+     text-align: center;
+     border-radius: 2px;
+     box-shadow: 0px 0px 4px #777;
+
+     -moz-user-select: none; 
+     -khtml-user-select: none; 
+     -webkit-user-select: none; 
+     -o-user-select: none; 
+     user-select: none;
+ }
+
+ .zoom.zoom-in {
+     top: 10px;
+ }
+ .zoom.zoom-out {
+     top: 45px;
+ }
+ .zoom.zoom-fit {
+     top: 90px;
+ }
+
+ .highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
+  /*fill: blue !important;*/ /* color elements as green */
+  stroke: blue !important;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/FontAwesome.otf b/src/main/resources/META-INF/resources/designer/fonts/FontAwesome.otf
new file mode 100644 (file)
index 0000000..3461e3f
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/FontAwesome.otf differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.css b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.css
new file mode 100644 (file)
index 0000000..eb4127b
--- /dev/null
@@ -0,0 +1,1566 @@
+/*!
+ *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+/* FONT PATH
+ * -------------------------- */
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
+  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+.fa {
+  display: inline-block;
+  font-family: FontAwesome;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+/* makes the font 33% larger relative to the icon container */
+.fa-lg {
+  font-size: 1.33333333em;
+  line-height: 0.75em;
+  vertical-align: -15%;
+}
+.fa-2x {
+  font-size: 2em;
+}
+.fa-3x {
+  font-size: 3em;
+}
+.fa-4x {
+  font-size: 4em;
+}
+.fa-5x {
+  font-size: 5em;
+}
+.fa-fw {
+  width: 1.28571429em;
+  text-align: center;
+}
+.fa-ul {
+  padding-left: 0;
+  margin-left: 2.14285714em;
+  list-style-type: none;
+}
+.fa-ul > li {
+  position: relative;
+}
+.fa-li {
+  position: absolute;
+  left: -2.14285714em;
+  width: 2.14285714em;
+  top: 0.14285714em;
+  text-align: center;
+}
+.fa-li.fa-lg {
+  left: -1.85714286em;
+}
+.fa-border {
+  padding: .2em .25em .15em;
+  border: solid 0.08em #eeeeee;
+  border-radius: .1em;
+}
+.pull-right {
+  float: right;
+}
+.pull-left {
+  float: left;
+}
+.fa.pull-left {
+  margin-right: .3em;
+}
+.fa.pull-right {
+  margin-left: .3em;
+}
+.fa-spin {
+  -webkit-animation: spin 2s infinite linear;
+  -moz-animation: spin 2s infinite linear;
+  -o-animation: spin 2s infinite linear;
+  animation: spin 2s infinite linear;
+}
+@-moz-keyframes spin {
+  0% {
+    -moz-transform: rotate(0deg);
+  }
+  100% {
+    -moz-transform: rotate(359deg);
+  }
+}
+@-webkit-keyframes spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+  }
+}
+@-o-keyframes spin {
+  0% {
+    -o-transform: rotate(0deg);
+  }
+  100% {
+    -o-transform: rotate(359deg);
+  }
+}
+@keyframes spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
+.fa-rotate-90 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
+  -webkit-transform: rotate(90deg);
+  -moz-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  -o-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+.fa-rotate-180 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
+  -webkit-transform: rotate(180deg);
+  -moz-transform: rotate(180deg);
+  -ms-transform: rotate(180deg);
+  -o-transform: rotate(180deg);
+  transform: rotate(180deg);
+}
+.fa-rotate-270 {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
+  -webkit-transform: rotate(270deg);
+  -moz-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  -o-transform: rotate(270deg);
+  transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
+  -webkit-transform: scale(-1, 1);
+  -moz-transform: scale(-1, 1);
+  -ms-transform: scale(-1, 1);
+  -o-transform: scale(-1, 1);
+  transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
+  -webkit-transform: scale(1, -1);
+  -moz-transform: scale(1, -1);
+  -ms-transform: scale(1, -1);
+  -o-transform: scale(1, -1);
+  transform: scale(1, -1);
+}
+.fa-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.fa-stack-1x {
+  line-height: inherit;
+}
+.fa-stack-2x {
+  font-size: 2em;
+}
+.fa-inverse {
+  color: #ffffff;
+}
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+.fa-glass:before {
+  content: "\f000";
+}
+.fa-music:before {
+  content: "\f001";
+}
+.fa-search:before {
+  content: "\f002";
+}
+.fa-envelope-o:before {
+  content: "\f003";
+}
+.fa-heart:before {
+  content: "\f004";
+}
+.fa-star:before {
+  content: "\f005";
+}
+.fa-star-o:before {
+  content: "\f006";
+}
+.fa-user:before {
+  content: "\f007";
+}
+.fa-film:before {
+  content: "\f008";
+}
+.fa-th-large:before {
+  content: "\f009";
+}
+.fa-th:before {
+  content: "\f00a";
+}
+.fa-th-list:before {
+  content: "\f00b";
+}
+.fa-check:before {
+  content: "\f00c";
+}
+.fa-times:before {
+  content: "\f00d";
+}
+.fa-search-plus:before {
+  content: "\f00e";
+}
+.fa-search-minus:before {
+  content: "\f010";
+}
+.fa-power-off:before {
+  content: "\f011";
+}
+.fa-signal:before {
+  content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+  content: "\f013";
+}
+.fa-trash-o:before {
+  content: "\f014";
+}
+.fa-home:before {
+  content: "\f015";
+}
+.fa-file-o:before {
+  content: "\f016";
+}
+.fa-clock-o:before {
+  content: "\f017";
+}
+.fa-road:before {
+  content: "\f018";
+}
+.fa-download:before {
+  content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+  content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+  content: "\f01b";
+}
+.fa-inbox:before {
+  content: "\f01c";
+}
+.fa-play-circle-o:before {
+  content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+  content: "\f01e";
+}
+.fa-refresh:before {
+  content: "\f021";
+}
+.fa-list-alt:before {
+  content: "\f022";
+}
+.fa-lock:before {
+  content: "\f023";
+}
+.fa-flag:before {
+  content: "\f024";
+}
+.fa-headphones:before {
+  content: "\f025";
+}
+.fa-volume-off:before {
+  content: "\f026";
+}
+.fa-volume-down:before {
+  content: "\f027";
+}
+.fa-volume-up:before {
+  content: "\f028";
+}
+.fa-qrcode:before {
+  content: "\f029";
+}
+.fa-barcode:before {
+  content: "\f02a";
+}
+.fa-tag:before {
+  content: "\f02b";
+}
+.fa-tags:before {
+  content: "\f02c";
+}
+.fa-book:before {
+  content: "\f02d";
+}
+.fa-bookmark:before {
+  content: "\f02e";
+}
+.fa-print:before {
+  content: "\f02f";
+}
+.fa-camera:before {
+  content: "\f030";
+}
+.fa-font:before {
+  content: "\f031";
+}
+.fa-bold:before {
+  content: "\f032";
+}
+.fa-italic:before {
+  content: "\f033";
+}
+.fa-text-height:before {
+  content: "\f034";
+}
+.fa-text-width:before {
+  content: "\f035";
+}
+.fa-align-left:before {
+  content: "\f036";
+}
+.fa-align-center:before {
+  content: "\f037";
+}
+.fa-align-right:before {
+  content: "\f038";
+}
+.fa-align-justify:before {
+  content: "\f039";
+}
+.fa-list:before {
+  content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+  content: "\f03b";
+}
+.fa-indent:before {
+  content: "\f03c";
+}
+.fa-video-camera:before {
+  content: "\f03d";
+}
+.fa-photo:before,
+.fa-image:before,
+.fa-picture-o:before {
+  content: "\f03e";
+}
+.fa-pencil:before {
+  content: "\f040";
+}
+.fa-map-marker:before {
+  content: "\f041";
+}
+.fa-adjust:before {
+  content: "\f042";
+}
+.fa-tint:before {
+  content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+  content: "\f044";
+}
+.fa-share-square-o:before {
+  content: "\f045";
+}
+.fa-check-square-o:before {
+  content: "\f046";
+}
+.fa-arrows:before {
+  content: "\f047";
+}
+.fa-step-backward:before {
+  content: "\f048";
+}
+.fa-fast-backward:before {
+  content: "\f049";
+}
+.fa-backward:before {
+  content: "\f04a";
+}
+.fa-play:before {
+  content: "\f04b";
+}
+.fa-pause:before {
+  content: "\f04c";
+}
+.fa-stop:before {
+  content: "\f04d";
+}
+.fa-forward:before {
+  content: "\f04e";
+}
+.fa-fast-forward:before {
+  content: "\f050";
+}
+.fa-step-forward:before {
+  content: "\f051";
+}
+.fa-eject:before {
+  content: "\f052";
+}
+.fa-chevron-left:before {
+  content: "\f053";
+}
+.fa-chevron-right:before {
+  content: "\f054";
+}
+.fa-plus-circle:before {
+  content: "\f055";
+}
+.fa-minus-circle:before {
+  content: "\f056";
+}
+.fa-times-circle:before {
+  content: "\f057";
+}
+.fa-check-circle:before {
+  content: "\f058";
+}
+.fa-question-circle:before {
+  content: "\f059";
+}
+.fa-info-circle:before {
+  content: "\f05a";
+}
+.fa-crosshairs:before {
+  content: "\f05b";
+}
+.fa-times-circle-o:before {
+  content: "\f05c";
+}
+.fa-check-circle-o:before {
+  content: "\f05d";
+}
+.fa-ban:before {
+  content: "\f05e";
+}
+.fa-arrow-left:before {
+  content: "\f060";
+}
+.fa-arrow-right:before {
+  content: "\f061";
+}
+.fa-arrow-up:before {
+  content: "\f062";
+}
+.fa-arrow-down:before {
+  content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+  content: "\f064";
+}
+.fa-expand:before {
+  content: "\f065";
+}
+.fa-compress:before {
+  content: "\f066";
+}
+.fa-plus:before {
+  content: "\f067";
+}
+.fa-minus:before {
+  content: "\f068";
+}
+.fa-asterisk:before {
+  content: "\f069";
+}
+.fa-exclamation-circle:before {
+  content: "\f06a";
+}
+.fa-gift:before {
+  content: "\f06b";
+}
+.fa-leaf:before {
+  content: "\f06c";
+}
+.fa-fire:before {
+  content: "\f06d";
+}
+.fa-eye:before {
+  content: "\f06e";
+}
+.fa-eye-slash:before {
+  content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+  content: "\f071";
+}
+.fa-plane:before {
+  content: "\f072";
+}
+.fa-calendar:before {
+  content: "\f073";
+}
+.fa-random:before {
+  content: "\f074";
+}
+.fa-comment:before {
+  content: "\f075";
+}
+.fa-magnet:before {
+  content: "\f076";
+}
+.fa-chevron-up:before {
+  content: "\f077";
+}
+.fa-chevron-down:before {
+  content: "\f078";
+}
+.fa-retweet:before {
+  content: "\f079";
+}
+.fa-shopping-cart:before {
+  content: "\f07a";
+}
+.fa-folder:before {
+  content: "\f07b";
+}
+.fa-folder-open:before {
+  content: "\f07c";
+}
+.fa-arrows-v:before {
+  content: "\f07d";
+}
+.fa-arrows-h:before {
+  content: "\f07e";
+}
+.fa-bar-chart-o:before {
+  content: "\f080";
+}
+.fa-twitter-square:before {
+  content: "\f081";
+}
+.fa-facebook-square:before {
+  content: "\f082";
+}
+.fa-camera-retro:before {
+  content: "\f083";
+}
+.fa-key:before {
+  content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+  content: "\f085";
+}
+.fa-comments:before {
+  content: "\f086";
+}
+.fa-thumbs-o-up:before {
+  content: "\f087";
+}
+.fa-thumbs-o-down:before {
+  content: "\f088";
+}
+.fa-star-half:before {
+  content: "\f089";
+}
+.fa-heart-o:before {
+  content: "\f08a";
+}
+.fa-sign-out:before {
+  content: "\f08b";
+}
+.fa-linkedin-square:before {
+  content: "\f08c";
+}
+.fa-thumb-tack:before {
+  content: "\f08d";
+}
+.fa-external-link:before {
+  content: "\f08e";
+}
+.fa-sign-in:before {
+  content: "\f090";
+}
+.fa-trophy:before {
+  content: "\f091";
+}
+.fa-github-square:before {
+  content: "\f092";
+}
+.fa-upload:before {
+  content: "\f093";
+}
+.fa-lemon-o:before {
+  content: "\f094";
+}
+.fa-phone:before {
+  content: "\f095";
+}
+.fa-square-o:before {
+  content: "\f096";
+}
+.fa-bookmark-o:before {
+  content: "\f097";
+}
+.fa-phone-square:before {
+  content: "\f098";
+}
+.fa-twitter:before {
+  content: "\f099";
+}
+.fa-facebook:before {
+  content: "\f09a";
+}
+.fa-github:before {
+  content: "\f09b";
+}
+.fa-unlock:before {
+  content: "\f09c";
+}
+.fa-credit-card:before {
+  content: "\f09d";
+}
+.fa-rss:before {
+  content: "\f09e";
+}
+.fa-hdd-o:before {
+  content: "\f0a0";
+}
+.fa-bullhorn:before {
+  content: "\f0a1";
+}
+.fa-bell:before {
+  content: "\f0f3";
+}
+.fa-certificate:before {
+  content: "\f0a3";
+}
+.fa-hand-o-right:before {
+  content: "\f0a4";
+}
+.fa-hand-o-left:before {
+  content: "\f0a5";
+}
+.fa-hand-o-up:before {
+  content: "\f0a6";
+}
+.fa-hand-o-down:before {
+  content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+  content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+  content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+  content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+  content: "\f0ab";
+}
+.fa-globe:before {
+  content: "\f0ac";
+}
+.fa-wrench:before {
+  content: "\f0ad";
+}
+.fa-tasks:before {
+  content: "\f0ae";
+}
+.fa-filter:before {
+  content: "\f0b0";
+}
+.fa-briefcase:before {
+  content: "\f0b1";
+}
+.fa-arrows-alt:before {
+  content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+  content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+  content: "\f0c1";
+}
+.fa-cloud:before {
+  content: "\f0c2";
+}
+.fa-flask:before {
+  content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+  content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+  content: "\f0c5";
+}
+.fa-paperclip:before {
+  content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+  content: "\f0c7";
+}
+.fa-square:before {
+  content: "\f0c8";
+}
+.fa-navicon:before,
+.fa-reorder:before,
+.fa-bars:before {
+  content: "\f0c9";
+}
+.fa-list-ul:before {
+  content: "\f0ca";
+}
+.fa-list-ol:before {
+  content: "\f0cb";
+}
+.fa-strikethrough:before {
+  content: "\f0cc";
+}
+.fa-underline:before {
+  content: "\f0cd";
+}
+.fa-table:before {
+  content: "\f0ce";
+}
+.fa-magic:before {
+  content: "\f0d0";
+}
+.fa-truck:before {
+  content: "\f0d1";
+}
+.fa-pinterest:before {
+  content: "\f0d2";
+}
+.fa-pinterest-square:before {
+  content: "\f0d3";
+}
+.fa-google-plus-square:before {
+  content: "\f0d4";
+}
+.fa-google-plus:before {
+  content: "\f0d5";
+}
+.fa-money:before {
+  content: "\f0d6";
+}
+.fa-caret-down:before {
+  content: "\f0d7";
+}
+.fa-caret-up:before {
+  content: "\f0d8";
+}
+.fa-caret-left:before {
+  content: "\f0d9";
+}
+.fa-caret-right:before {
+  content: "\f0da";
+}
+.fa-columns:before {
+  content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+  content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-desc:before {
+  content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc:before {
+  content: "\f0de";
+}
+.fa-envelope:before {
+  content: "\f0e0";
+}
+.fa-linkedin:before {
+  content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+  content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+  content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+  content: "\f0e4";
+}
+.fa-comment-o:before {
+  content: "\f0e5";
+}
+.fa-comments-o:before {
+  content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+  content: "\f0e7";
+}
+.fa-sitemap:before {
+  content: "\f0e8";
+}
+.fa-umbrella:before {
+  content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+  content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+  content: "\f0eb";
+}
+.fa-exchange:before {
+  content: "\f0ec";
+}
+.fa-cloud-download:before {
+  content: "\f0ed";
+}
+.fa-cloud-upload:before {
+  content: "\f0ee";
+}
+.fa-user-md:before {
+  content: "\f0f0";
+}
+.fa-stethoscope:before {
+  content: "\f0f1";
+}
+.fa-suitcase:before {
+  content: "\f0f2";
+}
+.fa-bell-o:before {
+  content: "\f0a2";
+}
+.fa-coffee:before {
+  content: "\f0f4";
+}
+.fa-cutlery:before {
+  content: "\f0f5";
+}
+.fa-file-text-o:before {
+  content: "\f0f6";
+}
+.fa-building-o:before {
+  content: "\f0f7";
+}
+.fa-hospital-o:before {
+  content: "\f0f8";
+}
+.fa-ambulance:before {
+  content: "\f0f9";
+}
+.fa-medkit:before {
+  content: "\f0fa";
+}
+.fa-fighter-jet:before {
+  content: "\f0fb";
+}
+.fa-beer:before {
+  content: "\f0fc";
+}
+.fa-h-square:before {
+  content: "\f0fd";
+}
+.fa-plus-square:before {
+  content: "\f0fe";
+}
+.fa-angle-double-left:before {
+  content: "\f100";
+}
+.fa-angle-double-right:before {
+  content: "\f101";
+}
+.fa-angle-double-up:before {
+  content: "\f102";
+}
+.fa-angle-double-down:before {
+  content: "\f103";
+}
+.fa-angle-left:before {
+  content: "\f104";
+}
+.fa-angle-right:before {
+  content: "\f105";
+}
+.fa-angle-up:before {
+  content: "\f106";
+}
+.fa-angle-down:before {
+  content: "\f107";
+}
+.fa-desktop:before {
+  content: "\f108";
+}
+.fa-laptop:before {
+  content: "\f109";
+}
+.fa-tablet:before {
+  content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+  content: "\f10b";
+}
+.fa-circle-o:before {
+  content: "\f10c";
+}
+.fa-quote-left:before {
+  content: "\f10d";
+}
+.fa-quote-right:before {
+  content: "\f10e";
+}
+.fa-spinner:before {
+  content: "\f110";
+}
+.fa-circle:before {
+  content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+  content: "\f112";
+}
+.fa-github-alt:before {
+  content: "\f113";
+}
+.fa-folder-o:before {
+  content: "\f114";
+}
+.fa-folder-open-o:before {
+  content: "\f115";
+}
+.fa-smile-o:before {
+  content: "\f118";
+}
+.fa-frown-o:before {
+  content: "\f119";
+}
+.fa-meh-o:before {
+  content: "\f11a";
+}
+.fa-gamepad:before {
+  content: "\f11b";
+}
+.fa-keyboard-o:before {
+  content: "\f11c";
+}
+.fa-flag-o:before {
+  content: "\f11d";
+}
+.fa-flag-checkered:before {
+  content: "\f11e";
+}
+.fa-terminal:before {
+  content: "\f120";
+}
+.fa-code:before {
+  content: "\f121";
+}
+.fa-mail-reply-all:before,
+.fa-reply-all:before {
+  content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+  content: "\f123";
+}
+.fa-location-arrow:before {
+  content: "\f124";
+}
+.fa-crop:before {
+  content: "\f125";
+}
+.fa-code-fork:before {
+  content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+  content: "\f127";
+}
+.fa-question:before {
+  content: "\f128";
+}
+.fa-info:before {
+  content: "\f129";
+}
+.fa-exclamation:before {
+  content: "\f12a";
+}
+.fa-superscript:before {
+  content: "\f12b";
+}
+.fa-subscript:before {
+  content: "\f12c";
+}
+.fa-eraser:before {
+  content: "\f12d";
+}
+.fa-puzzle-piece:before {
+  content: "\f12e";
+}
+.fa-microphone:before {
+  content: "\f130";
+}
+.fa-microphone-slash:before {
+  content: "\f131";
+}
+.fa-shield:before {
+  content: "\f132";
+}
+.fa-calendar-o:before {
+  content: "\f133";
+}
+.fa-fire-extinguisher:before {
+  content: "\f134";
+}
+.fa-rocket:before {
+  content: "\f135";
+}
+.fa-maxcdn:before {
+  content: "\f136";
+}
+.fa-chevron-circle-left:before {
+  content: "\f137";
+}
+.fa-chevron-circle-right:before {
+  content: "\f138";
+}
+.fa-chevron-circle-up:before {
+  content: "\f139";
+}
+.fa-chevron-circle-down:before {
+  content: "\f13a";
+}
+.fa-html5:before {
+  content: "\f13b";
+}
+.fa-css3:before {
+  content: "\f13c";
+}
+.fa-anchor:before {
+  content: "\f13d";
+}
+.fa-unlock-alt:before {
+  content: "\f13e";
+}
+.fa-bullseye:before {
+  content: "\f140";
+}
+.fa-ellipsis-h:before {
+  content: "\f141";
+}
+.fa-ellipsis-v:before {
+  content: "\f142";
+}
+.fa-rss-square:before {
+  content: "\f143";
+}
+.fa-play-circle:before {
+  content: "\f144";
+}
+.fa-ticket:before {
+  content: "\f145";
+}
+.fa-minus-square:before {
+  content: "\f146";
+}
+.fa-minus-square-o:before {
+  content: "\f147";
+}
+.fa-level-up:before {
+  content: "\f148";
+}
+.fa-level-down:before {
+  content: "\f149";
+}
+.fa-check-square:before {
+  content: "\f14a";
+}
+.fa-pencil-square:before {
+  content: "\f14b";
+}
+.fa-external-link-square:before {
+  content: "\f14c";
+}
+.fa-share-square:before {
+  content: "\f14d";
+}
+.fa-compass:before {
+  content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+  content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+  content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+  content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+  content: "\f153";
+}
+.fa-gbp:before {
+  content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+  content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+  content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+  content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+  content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+  content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+  content: "\f15a";
+}
+.fa-file:before {
+  content: "\f15b";
+}
+.fa-file-text:before {
+  content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+  content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+  content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+  content: "\f160";
+}
+.fa-sort-amount-desc:before {
+  content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+  content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+  content: "\f163";
+}
+.fa-thumbs-up:before {
+  content: "\f164";
+}
+.fa-thumbs-down:before {
+  content: "\f165";
+}
+.fa-youtube-square:before {
+  content: "\f166";
+}
+.fa-youtube:before {
+  content: "\f167";
+}
+.fa-xing:before {
+  content: "\f168";
+}
+.fa-xing-square:before {
+  content: "\f169";
+}
+.fa-youtube-play:before {
+  content: "\f16a";
+}
+.fa-dropbox:before {
+  content: "\f16b";
+}
+.fa-stack-overflow:before {
+  content: "\f16c";
+}
+.fa-instagram:before {
+  content: "\f16d";
+}
+.fa-flickr:before {
+  content: "\f16e";
+}
+.fa-adn:before {
+  content: "\f170";
+}
+.fa-bitbucket:before {
+  content: "\f171";
+}
+.fa-bitbucket-square:before {
+  content: "\f172";
+}
+.fa-tumblr:before {
+  content: "\f173";
+}
+.fa-tumblr-square:before {
+  content: "\f174";
+}
+.fa-long-arrow-down:before {
+  content: "\f175";
+}
+.fa-long-arrow-up:before {
+  content: "\f176";
+}
+.fa-long-arrow-left:before {
+  content: "\f177";
+}
+.fa-long-arrow-right:before {
+  content: "\f178";
+}
+.fa-apple:before {
+  content: "\f179";
+}
+.fa-windows:before {
+  content: "\f17a";
+}
+.fa-android:before {
+  content: "\f17b";
+}
+.fa-linux:before {
+  content: "\f17c";
+}
+.fa-dribbble:before {
+  content: "\f17d";
+}
+.fa-skype:before {
+  content: "\f17e";
+}
+.fa-foursquare:before {
+  content: "\f180";
+}
+.fa-trello:before {
+  content: "\f181";
+}
+.fa-female:before {
+  content: "\f182";
+}
+.fa-male:before {
+  content: "\f183";
+}
+.fa-gittip:before {
+  content: "\f184";
+}
+.fa-sun-o:before {
+  content: "\f185";
+}
+.fa-moon-o:before {
+  content: "\f186";
+}
+.fa-archive:before {
+  content: "\f187";
+}
+.fa-bug:before {
+  content: "\f188";
+}
+.fa-vk:before {
+  content: "\f189";
+}
+.fa-weibo:before {
+  content: "\f18a";
+}
+.fa-renren:before {
+  content: "\f18b";
+}
+.fa-pagelines:before {
+  content: "\f18c";
+}
+.fa-stack-exchange:before {
+  content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+  content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+  content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+  content: "\f191";
+}
+.fa-dot-circle-o:before {
+  content: "\f192";
+}
+.fa-wheelchair:before {
+  content: "\f193";
+}
+.fa-vimeo-square:before {
+  content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+  content: "\f195";
+}
+.fa-plus-square-o:before {
+  content: "\f196";
+}
+.fa-space-shuttle:before {
+  content: "\f197";
+}
+.fa-slack:before {
+  content: "\f198";
+}
+.fa-envelope-square:before {
+  content: "\f199";
+}
+.fa-wordpress:before {
+  content: "\f19a";
+}
+.fa-openid:before {
+  content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+  content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+  content: "\f19d";
+}
+.fa-yahoo:before {
+  content: "\f19e";
+}
+.fa-google:before {
+  content: "\f1a0";
+}
+.fa-reddit:before {
+  content: "\f1a1";
+}
+.fa-reddit-square:before {
+  content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+  content: "\f1a3";
+}
+.fa-stumbleupon:before {
+  content: "\f1a4";
+}
+.fa-delicious:before {
+  content: "\f1a5";
+}
+.fa-digg:before {
+  content: "\f1a6";
+}
+.fa-pied-piper-square:before,
+.fa-pied-piper:before {
+  content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+  content: "\f1a8";
+}
+.fa-drupal:before {
+  content: "\f1a9";
+}
+.fa-joomla:before {
+  content: "\f1aa";
+}
+.fa-language:before {
+  content: "\f1ab";
+}
+.fa-fax:before {
+  content: "\f1ac";
+}
+.fa-building:before {
+  content: "\f1ad";
+}
+.fa-child:before {
+  content: "\f1ae";
+}
+.fa-paw:before {
+  content: "\f1b0";
+}
+.fa-spoon:before {
+  content: "\f1b1";
+}
+.fa-cube:before {
+  content: "\f1b2";
+}
+.fa-cubes:before {
+  content: "\f1b3";
+}
+.fa-behance:before {
+  content: "\f1b4";
+}
+.fa-behance-square:before {
+  content: "\f1b5";
+}
+.fa-steam:before {
+  content: "\f1b6";
+}
+.fa-steam-square:before {
+  content: "\f1b7";
+}
+.fa-recycle:before {
+  content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+  content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+  content: "\f1ba";
+}
+.fa-tree:before {
+  content: "\f1bb";
+}
+.fa-spotify:before {
+  content: "\f1bc";
+}
+.fa-deviantart:before {
+  content: "\f1bd";
+}
+.fa-soundcloud:before {
+  content: "\f1be";
+}
+.fa-database:before {
+  content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+  content: "\f1c1";
+}
+.fa-file-word-o:before {
+  content: "\f1c2";
+}
+.fa-file-excel-o:before {
+  content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+  content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+  content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+  content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+  content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+  content: "\f1c8";
+}
+.fa-file-code-o:before {
+  content: "\f1c9";
+}
+.fa-vine:before {
+  content: "\f1ca";
+}
+.fa-codepen:before {
+  content: "\f1cb";
+}
+.fa-jsfiddle:before {
+  content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+  content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+  content: "\f1ce";
+}
+.fa-ra:before,
+.fa-rebel:before {
+  content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+  content: "\f1d1";
+}
+.fa-git-square:before {
+  content: "\f1d2";
+}
+.fa-git:before {
+  content: "\f1d3";
+}
+.fa-hacker-news:before {
+  content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+  content: "\f1d5";
+}
+.fa-qq:before {
+  content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+  content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+  content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+  content: "\f1d9";
+}
+.fa-history:before {
+  content: "\f1da";
+}
+.fa-circle-thin:before {
+  content: "\f1db";
+}
+.fa-header:before {
+  content: "\f1dc";
+}
+.fa-paragraph:before {
+  content: "\f1dd";
+}
+.fa-sliders:before {
+  content: "\f1de";
+}
+.fa-share-alt:before {
+  content: "\f1e0";
+}
+.fa-share-alt-square:before {
+  content: "\f1e1";
+}
+.fa-bomb:before {
+  content: "\f1e2";
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.min.css b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/css/font-awesome.min.css
new file mode 100644 (file)
index 0000000..a2e4cc9
--- /dev/null
@@ -0,0 +1,4 @@
+/*!
+ *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/FontAwesome.otf b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/FontAwesome.otf
new file mode 100644 (file)
index 0000000..3461e3f
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/FontAwesome.otf differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.eot b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.eot
new file mode 100644 (file)
index 0000000..6cfd566
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.svg b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.svg
new file mode 100644 (file)
index 0000000..6347d99
--- /dev/null
@@ -0,0 +1,504 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="fontawesomeregular" horiz-adv-x="1536" >
+<font-face units-per-em="1792" ascent="1536" descent="-256" />
+<missing-glyph horiz-adv-x="448" />
+<glyph unicode=" "  horiz-adv-x="448" />
+<glyph unicode="&#x09;" horiz-adv-x="448" />
+<glyph unicode="&#xa0;" horiz-adv-x="448" />
+<glyph unicode="&#xa8;" horiz-adv-x="1792" />
+<glyph unicode="&#xa9;" horiz-adv-x="1792" />
+<glyph unicode="&#xae;" horiz-adv-x="1792" />
+<glyph unicode="&#xb4;" horiz-adv-x="1792" />
+<glyph unicode="&#xc6;" horiz-adv-x="1792" />
+<glyph unicode="&#xd8;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" horiz-adv-x="1537" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" horiz-adv-x="1537" />
+<glyph unicode="&#x2004;" horiz-adv-x="512" />
+<glyph unicode="&#x2005;" horiz-adv-x="384" />
+<glyph unicode="&#x2006;" horiz-adv-x="256" />
+<glyph unicode="&#x2007;" horiz-adv-x="256" />
+<glyph unicode="&#x2008;" horiz-adv-x="192" />
+<glyph unicode="&#x2009;" horiz-adv-x="307" />
+<glyph unicode="&#x200a;" horiz-adv-x="85" />
+<glyph unicode="&#x202f;" horiz-adv-x="307" />
+<glyph unicode="&#x205f;" horiz-adv-x="384" />
+<glyph unicode="&#x2122;" horiz-adv-x="1792" />
+<glyph unicode="&#x221e;" horiz-adv-x="1792" />
+<glyph unicode="&#x2260;" horiz-adv-x="1792" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M93 1350q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78z" />
+<glyph unicode="&#xf001;" d="M0 -64q0 50 34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5 q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
+<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M0 32v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5 t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768zM128 1120q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317 q54 43 100.5 115.5t46.5 131.5v11v13.5t-0.5 13t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5z" />
+<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z " />
+<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48z" />
+<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354 q-25 27 -25 48zM221 829l306 -297l-73 -421l378 199l377 -199l-72 421l306 297l-422 62l-189 382l-189 -382z" />
+<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M0 131q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5 h-874q-121 0 -194 69.5t-73 189.5zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5z" />
+<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M0 -96v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 64v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM128 320q0 -26 19 -45t45 -19h128 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19 h-128q-26 0 -45 -19t-19 -45v-128zM512 -64q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM512 704q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM1536 64 v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM1536 320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M0 128v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM0 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 128v384q0 52 38 90t90 38h512q52 0 90 -38 t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90z" />
+<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 608v192 q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M121 608q0 40 28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68z" />
+<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M110 214q0 40 28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-294 -294l294 -294q28 -28 28 -68t-28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294 q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68z" />
+<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf011;" d="M0 640q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181 q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298zM640 768v640q0 52 38 90t90 38t90 -38t38 -90v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90z" />
+<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M0 -96v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM384 -96v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM768 -96v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576 q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 -96v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1536 -96v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf013;" d="M0 531v222q0 12 8 23t19 13l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10 q129 -119 165 -170q7 -8 7 -22q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108 q-44 -23 -91 -38q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5z M512 640q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
+<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M0 1056v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23zM256 76q0 -22 7 -40.5 t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5v948h-896v-948zM384 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM640 224v576q0 14 9 23t23 9h64 q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM896 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M26 636.5q1 13.5 11 21.5l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5zM256 64 v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf016;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22 v-376z" />
+<glyph unicode="&#xf017;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 544v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M50 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256 q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73zM809 540q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4z" />
+<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M0 96v320q0 40 28 68t68 28h465l135 -136q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 985q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39q17 -41 -14 -70 l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70zM1152 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf01a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM418 620q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35z" />
+<glyph unicode="&#xf01b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM416 672q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf01c;" d="M0 64v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552q25 -61 25 -123v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM197 576h316l95 -192h320l95 192h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8 t-2.5 -8z" />
+<glyph unicode="&#xf01d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 320v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55t-32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56z" />
+<glyph unicode="&#xf01e;" d="M0 640q0 156 61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5 t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298z" />
+<glyph unicode="&#xf021;" d="M0 0v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129 q-19 -19 -45 -19t-45 19t-19 45zM18 800v7q65 268 270 434.5t480 166.5q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179 q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M0 160v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832z M256 288v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 544v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z M256 800v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 288v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z M512 544v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5zM512 800v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z " />
+<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192z" />
+<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110zM320 320v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19 q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M0 650q0 151 67 291t179 242.5t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32 q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32 q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314z" />
+<glyph unicode="&#xf026;" horiz-adv-x="768" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5z" />
+<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5zM1008 228q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5 q140 -59 225 -188.5t85 -282.5t-85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45zM1109 -7q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19 q13 0 26 -5q211 -91 338 -283.5t127 -422.5t-127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M0 0v640h640v-640h-640zM0 768v640h640v-640h-640zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM256 256v128h128v-128h-128zM256 1024v128h128v-128h-128zM768 0v640h384v-128h128v128h128v-384h-384v128h-128v-384h-128zM768 768v640h640v-640h-640z M896 896h384v384h-384v-384zM1024 0v128h128v-128h-128zM1024 1024v128h128v-128h-128zM1280 0v128h128v-128h-128z" />
+<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M0 0v1408h63v-1408h-63zM94 1v1407h32v-1407h-32zM189 1v1407h31v-1407h-31zM346 1v1407h31v-1407h-31zM472 1v1407h62v-1407h-62zM629 1v1407h31v-1407h-31zM692 1v1407h31v-1407h-31zM755 1v1407h31v-1407h-31zM880 1v1407h63v-1407h-63zM1037 1v1407h63v-1407h-63z M1163 1v1407h63v-1407h-63zM1289 1v1407h63v-1407h-63zM1383 1v1407h63v-1407h-63zM1541 1v1407h94v-1407h-94zM1666 1v1407h32v-1407h-32zM1729 0v1408h63v-1408h-63z" />
+<glyph unicode="&#xf02b;" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5zM704 1408h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5z" />
+<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M10 184q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23 t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57 q38 -15 59 -43q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5zM575 1056 q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62z" />
+<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M0 160v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-224 q-13 0 -22.5 9.5t-9.5 22.5zM384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1408 576q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M0 128v896q0 106 75 181t181 75h224l51 136q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181zM512 576q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM672 576q0 119 84.5 203.5t203.5 84.5t203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8 t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27 q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14zM555 527q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5 t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12zM533 1292q0 -50 4 -151t4 -152q0 -27 -0.5 -80 t-0.5 -79q0 -46 1 -69q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13zM538.5 165q0.5 -37 4.5 -83.5t12 -66.5q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25 t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5 q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9 t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44zM1414 109.5q9 18.5 42 18.5h80v1024 h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5z" />
+<glyph unicode="&#xf035;" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1 t-103 1t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29 t78 27q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44zM5 -64q0 28 26 49q4 3 36 30t59.5 49 t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5q12 0 42 -19.5t57.5 -41.5t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5 t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49z" />
+<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1536 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h896 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h1280 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 416v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5zM0 800v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192 q-13 0 -22.5 9.5t-9.5 22.5zM384 32v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 416v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 800v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 1184v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5 t-9.5 22.5zM32 704q0 14 9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088 q-13 0 -22.5 9.5t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 416v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23t-9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5z M0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5 t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5q39 -17 39 -59v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5 t-84.5 203.5z" />
+<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v192l320 320l160 -160l512 512l416 -416v-448h-1408zM256 960q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136z" />
+<glyph unicode="&#xf040;" d="M0 -128v416l832 832l416 -416l-832 -832h-416zM128 128h128v-128h107l91 91l-235 235l-91 -91v-107zM298 384q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17zM896 1184l166 165q36 38 90 38q53 0 91 -38l235 -234 q37 -39 37 -91q0 -53 -37 -90l-166 -166z" />
+<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M0 896q0 212 150 362t362 150t362 -150t150 -362q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179zM256 896q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
+<glyph unicode="&#xf042;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73v1088q-148 0 -273 -73t-198 -198t-73 -273z" />
+<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M0 512q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275q0 -212 -150 -362t-362 -150t-362 150t-150 362zM256 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69z" />
+<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29v-190 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM640 256v288l672 672l288 -288l-672 -672h-288zM736 448h96v-96h56l116 116l-152 152l-116 -116v-56zM944 688q16 -16 33 1l350 350q17 17 1 33t-33 -1l-350 -350q-17 -17 -1 -33zM1376 1280l92 92 q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68l-92 -92z" />
+<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h255q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29v-259 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM256 704q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45l-384 -384 q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5t-38.5 114t-17.5 122z" />
+<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3 q20 -8 20 -29v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM257 768q0 33 24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110q24 -24 24 -57t-24 -57l-814 -814q-24 -24 -57 -24t-57 24l-430 430 q-24 24 -24 57z" />
+<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256 q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-710q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45 t-45 -19h-128q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M122 640q0 26 19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45z" />
+<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M0 -96v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31l-1328 -738q-23 -13 -39.5 -3t-16.5 36z" />
+<glyph unicode="&#xf04c;" d="M0 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM896 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04d;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32v710 q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M1 64v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM1 525q-6 13 13 32l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13z" />
+<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M154 704q0 26 19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M90 128q0 26 19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45z" />
+<glyph unicode="&#xf055;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19 t19 45v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf056;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19 t-19 -45v-128z" />
+<glyph unicode="&#xf057;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM387 414q0 -27 19 -46l90 -90q19 -19 46 -19q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19 l90 90q19 19 19 46q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45z" />
+<glyph unicode="&#xf058;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 621q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45q0 28 -18 46l-91 90 q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46z" />
+<glyph unicode="&#xf059;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM417 939q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26 t37.5 -59q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213zM640 160q0 -14 9 -23t23 -9 h192q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192z" />
+<glyph unicode="&#xf05a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320 q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160zM640 1056q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160z" />
+<glyph unicode="&#xf05b;" d="M0 576v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143 q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45zM339 512q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5h-109q-26 0 -45 19 t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109z" />
+<glyph unicode="&#xf05c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM429 480q0 13 10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23l-137 -137l137 -137q10 -10 10 -23t-10 -23l-146 -146q-10 -10 -23 -10t-23 10l-137 137 l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23z" />
+<glyph unicode="&#xf05d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM346 640q0 26 19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45z" />
+<glyph unicode="&#xf05e;" d="M0 643q0 157 61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5t-61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61t-245 164t-163.5 246t-61 300zM224 643q0 -162 89 -299l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199 t-73 -274zM471 185q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5q0 161 -87 295z" />
+<glyph unicode="&#xf060;" d="M64 576q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5t32.5 -90.5v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90 z" />
+<glyph unicode="&#xf061;" d="M0 512v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5z" />
+<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M53 565q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651q37 -39 37 -91q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75 q-38 38 -38 90z" />
+<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M53 704q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90z" />
+<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M0 416q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45t-19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123 q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22t-13.5 30t-10.5 24q-127 285 -127 451z" />
+<glyph unicode="&#xf065;" d="M0 -64v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45zM781 800q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448 q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
+<glyph unicode="&#xf066;" d="M13 32q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23zM768 704v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10 t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M122.5 408.5q13.5 51.5 59.5 77.5l266 154l-266 154q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5 l-266 -154l266 -154q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5z" />
+<glyph unicode="&#xf06a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM624 1126l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5l18 621q0 12 -10 18 q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18zM640 161q0 -13 10 -23t23 -10h192q13 0 22 9.5t9 23.5v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190z" />
+<glyph unicode="&#xf06b;" d="M0 544v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68 t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23zM376 1120q0 -40 28 -68t68 -28h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68zM608 180q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5v56v468v192h-320v-192v-468v-56zM870 1024h194q40 0 68 28 t28 68t-28 68t-68 28q-43 0 -69 -31z" />
+<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M0 121q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96 q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5zM384 448q0 -26 19 -45t45 -19q24 0 45 19 q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45t-19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45z" />
+<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M0 -160q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64zM256 640q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100 t113.5 -122.5t72.5 -150.5t27.5 -184q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184z" />
+<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M0 576q0 34 20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69t-20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69zM128 576q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5q-152 236 -381 353 q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5z" />
+<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M0 576q0 38 20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5q16 -10 16 -27q0 -7 -1 -9q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87 q-143 65 -263.5 173t-208.5 245q-20 31 -20 69zM128 576q167 -258 427 -375l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5zM896 0l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69t-20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95zM1056 286l280 502q8 -45 8 -84q0 -139 -79 -253.5t-209 -164.5z" />
+<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M16 61l768 1408q17 31 47 49t65 18t65 -18t47 -49l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126zM752 992l17 -457q0 -10 10 -16.5t24 -6.5h185q14 0 23.5 6.5t10.5 16.5l18 459q0 12 -10 19q-13 11 -24 11h-220 q-11 0 -24 -11q-10 -7 -10 -21zM768 161q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190z" />
+<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M0 477q-1 13 9 25l96 97q9 9 23 9q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16 l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23z" />
+<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h288v288h-288v-288zM128 224 h288v320h-288v-320zM128 608h288v288h-288v-288zM384 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM480 -128h320v288h-320v-288zM480 224h320v320h-320v-320zM480 608h320v288h-320 v-288zM864 -128h320v288h-320v-288zM864 224h320v320h-320v-320zM864 608h320v288h-320v-288zM1152 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM1248 -128h288v288h-288v-288z M1248 224h288v320h-288v-320zM1248 608h288v288h-288v-288z" />
+<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M0 160v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23zM0 1056v192q0 14 9 23t23 9h224q250 0 410 -225q-60 -92 -137 -273q-22 45 -37 72.5 t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23zM743 353q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 q-32 0 -85 -0.5t-81 -1t-73 1t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5z" />
+<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M0 640q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5 t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281z" />
+<glyph unicode="&#xf076;" d="M0 576v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5 t-98.5 362zM0 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45zM1024 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M90 250.5q0 26.5 19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M90 773.5q0 26.5 19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5z" />
+<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M0 704q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45z M640 1120q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20z " />
+<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M0 1216q0 26 19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024 q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45zM384 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1280 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158z" />
+<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5t-0.5 12.5zM73 56q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43 q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43z" />
+<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M64 64q0 26 19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf080;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v384h256v-384h-256zM640 128v896h256v-896h-256zM1024 128v640h256v-640h-256zM1408 128v1024h256v-1024h-256z" />
+<glyph unicode="&#xf081;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 286q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109 q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4q21 -63 74.5 -104 t121.5 -42q-116 -90 -261 -90q-26 0 -50 3z" />
+<glyph unicode="&#xf082;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544 q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M0 0v1280q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5zM128 0h1536v128h-1536v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM256 1216h384v128h-384v-128zM512 574 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM640 574q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM736 576q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9 t9 23t-9 23t-23 9q-66 0 -113 -47t-47 -113z" />
+<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M0 752q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41q0 -17 -49 -66t-66 -49 q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5zM192 768q0 -80 56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56 t56 136t-56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136z" />
+<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M0 549v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8 q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90 q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5zM384 640q0 -106 75 -181t181 -75 t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181zM1152 58v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31 v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1152 1082v140q0 16 149 31q13 29 30 52 q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71 q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1408 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90zM1408 1152q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90z" />
+<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM616 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5 t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
+<glyph unicode="&#xf087;" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5 t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85 t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640z" />
+<glyph unicode="&#xf088;" d="M0 512v640q0 53 37.5 90.5t90.5 37.5h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186 q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5zM128 1088q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 512h32q16 0 35.5 -9 t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5 t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640z" />
+<glyph unicode="&#xf089;" horiz-adv-x="896" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48z" />
+<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z M128 940q0 -168 187 -355l581 -560l580 559q188 188 188 356q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5 t-21.5 -143z" />
+<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5q0 -4 1 -20t0.5 -26.5t-3 -23.5 t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5zM384 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf08c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM223 1030q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86z M237 122h231v694h-231v-694zM595 122h231v388q0 38 7 56q15 35 45 59.5t74 24.5q116 0 116 -157v-371h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694z" />
+<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M0 320q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19 t-19 45zM416 672q0 -14 9 -23t23 -9t23 9t9 23v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448z" />
+<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832 q-119 0 -203.5 84.5t-84.5 203.5zM685 576q0 13 10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
+<glyph unicode="&#xf090;" d="M0 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45zM894.5 78.5q0.5 10.5 3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113 t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5q0 4 -1 20t-0.5 26.5z" />
+<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M0 928v128q0 40 28 68t68 28h288v96q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91t97.5 -37q75 0 133.5 -45.5 t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143zM128 928q0 -78 94.5 -162t235.5 -113q-74 162 -74 371 h-256v-96zM1206 653q141 29 235.5 113t94.5 162v96h-256q0 -209 -74 -371z" />
+<glyph unicode="&#xf092;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204 q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52 t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5h-224q-119 0 -203.5 84.5t-84.5 203.5zM271 315q3 5 13 2 q10 -5 7 -12q-5 -7 -13 -2q-10 5 -7 12zM304 290q6 6 16 -3q9 -11 2 -16q-6 -7 -16 3q-9 11 -2 16zM335 233q-9 13 0 18q9 7 17 -6q9 -12 0 -19q-8 -6 -17 7zM370 206q8 9 20 -3q12 -11 4 -19q-8 -9 -20 3q-13 11 -4 19zM419 168q4 11 19 7q16 -5 13 -16q-4 -12 -19 -6 q-17 4 -13 15zM481 154q0 11 16 11q17 2 17 -11q0 -11 -16 -11q-17 -2 -17 11zM540 158q-2 12 14 15q16 2 18 -9q2 -10 -14 -14t-18 8z" />
+<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M0 -32v320q0 40 28 68t68 28h427q21 -56 70.5 -92t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 936q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69q-17 -40 -59 -40 h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40zM1152 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf094;" d="M0 433q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5q0 -165 -70 -327.5 t-196 -288t-281 -180.5q-124 -44 -326 -44q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5zM128 434q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5 q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24 q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5z" />
+<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M0 1069q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235 t235 -174q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5 t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5z" />
+<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832z" />
+<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62zM128 38l423 406l89 85l89 -85l423 -406 v1242h-1024v-1242z" />
+<glyph unicode="&#xf098;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 905q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5 q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5 t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5z" />
+<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M44 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5 q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145z" />
+<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M95 631v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255z" />
+<glyph unicode="&#xf09b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44 l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3 q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5z" />
+<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M0 96v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v608h-1664v-608zM128 1024h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600 q-13 0 -22.5 -9.5t-9.5 -22.5v-224zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M0 192q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 697v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5t259 -181.5q114 -113 181.5 -259t80.5 -306q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5 t-391.5 184.5q-25 2 -41.5 20t-16.5 43zM0 1201v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294q187 -186 294 -425.5t120 -501.5q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102 q-25 1 -42.5 19.5t-17.5 43.5z" />
+<glyph unicode="&#xf0a0;" d="M0 160v320q0 25 16 75l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-1216 q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM880 320q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1136 320q0 33 23.5 56.5t56.5 23.5 t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5z" />
+<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M0 672v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50 t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113zM768 633q377 -42 768 -341v954q-394 -302 -768 -343v-270z" />
+<glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
+<glyph unicode="&#xf0a3;" d="M2 435q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70l-53 -186l188 -48 q40 -10 52 -51q10 -42 -20 -70l-138 -135l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53 q-41 -12 -70 19q-31 29 -19 70l53 186l-188 48q-40 10 -52 51z" />
+<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179q0 -105 -75.5 -181 t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q72 0 167 -32 t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139 q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106q-69 -57 -140 -57h-32v-640z" />
+<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M0 769q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5v-640 q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181zM128 768q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119 q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5 t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5t-39 -89.5zM1536 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a6;" d="M0 640q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5t-90.5 -37.5h-640 q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5zM128 640q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140 v-32h640v32q0 72 32 167t64 193.5t32 179.5q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576q-20 0 -48.5 15t-55 33t-68 33t-84.5 15 q-67 0 -97.5 -44.5t-30.5 -115.5zM1152 -64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a7;" d="M0 640q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317q0 -142 -77.5 -230t-217.5 -87 l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5zM128 640q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33t55 33t48.5 15v-576q0 -50 38.5 -89 t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112 q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5zM1152 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a8;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM251 640q0 -27 18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0a9;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM256 576q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18 l362 362l91 91q18 18 18 45t-18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf0aa;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 641q0 -27 18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19 t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45t-18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0ab;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 639q0 -27 18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45t-18 45l-91 91 q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0ac;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM226 979q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18 q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13 q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5 t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13 q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25 t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5 t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4 q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5q15 10 -7 16q-17 5 -43 -12q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8 q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5 q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26 q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5 q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14 q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5 q-16 0 -22 -1q-146 -80 -235 -222zM877 26q0 -6 2 -16q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7 t-10 1.5t-11.5 -7q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5z" />
+<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M21 0q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90zM256 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM768 960q0 185 131.5 316.5t316.5 131.5q58 0 121.5 -16.5 t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25q0 -39 -23 -106q-47 -134 -164.5 -217.5t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5z" />
+<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M0 64v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 576v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1088v256q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM640 640h1024v128h-1024v-128zM1024 128h640v128h-640v-128zM1280 1152h384v128h-384v-128z" />
+<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M5 1241q17 39 59 39h1280q42 0 59 -39q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70z" />
+<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M0 160v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 736v384q0 66 47 113t113 47h352v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113v-384h-1792z M640 1280h512v128h-512v-128zM768 512v128h256v-128h-256z" />
+<glyph unicode="&#xf0b2;" d="M0 -64v448q0 42 40 59q39 17 69 -14l144 -144l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45 v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19l-144 144l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19 t-19 45z" />
+<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M0 671q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5zM128 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM256 3q0 53 3.5 103.5 t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5 zM576 896q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5zM1280 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM1327 640q81 117 81 256q0 29 -5 66q66 -23 133 -23 q59 0 119 21.5t97.5 42.5t43.5 21q124 0 124 -353q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128z" />
+<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l206 -207q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204t-85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88 q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204zM208 1088q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15t21.5 -21.5t18.5 -19q33 31 33 73 q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67zM911 383q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26l147 146q28 28 28 67q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5 q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73z" />
+<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M0 448q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z" />
+<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M115.5 -64.5q-34.5 63.5 21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399l503 -793q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5zM476 384h712l-272 429l-20 31v37v399h-128v-399v-37 l-20 -31z" />
+<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M1 157q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148q4 -48 -10 -97q4 -1 12 -5 l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56l-507 -398l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207zM168 176q-25 -66 21 -108q39 -36 113 -36q100 0 192 59q81 51 106 117t-21 108q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117zM168 976q25 -66 106 -117q92 -59 192 -59q74 0 113 36q46 42 21 108t-106 117q-92 59 -192 59 q-74 0 -113 -36q-46 -42 -21 -108zM672 448l9 -8q2 -2 7 -6q4 -4 11 -12t11 -12l26 -26l160 96l96 -32l736 576l-128 64l-768 -431v-113zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 576q0 26 19 45t45 19t45 -19 t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1018 391l582 -327l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
+<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M0 224v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68zM128 256h512v256q0 40 20 88t48 76l316 316v416h-384 v-416q0 -40 -28 -68t-68 -28h-416v-640zM213 1024h299v299zM768 -128h896v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640zM853 640h299v299z" />
+<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M4 1023q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581 q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776 q-113 115 -113 271z" />
+<glyph unicode="&#xf0c7;" d="M0 -32v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 0h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20 t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280zM384 0h768v384h-768v-384zM640 928q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320z" />
+<glyph unicode="&#xf0c8;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf0c9;" d="M0 64v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 576v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 1088v128q0 26 19 45t45 19h1408 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M0 128q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 640q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 1152q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM512 32v192 q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z M512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M15 438q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105v-159h-362q-6 36 -6 54zM19 -190 l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66zM34 1400l136 127h106v-404h108v-99 h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54zM512 32v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M0 544v64q0 14 9 23t23 9h1728q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23zM384 972q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6l-14 2q-50 149 -103 205 q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743q-28 35 -51 80q-48 97 -48 188zM414 154q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22 q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156z" />
+<glyph unicode="&#xf0cd;" d="M0 -32v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-1472q-14 0 -23 -9t-9 -23zM0 1405q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5 t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2 q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195 q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39q-37 2 -45 4z" />
+<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M0 160v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 544q0 -14 9 -23t23 -9h320 q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192zM640 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23 v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192z" />
+<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M27 160q0 27 18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45t-18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45zM128 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM320 1216l196 60l60 196l60 -196l196 -60l-196 -60 l-60 -196l-60 196zM768 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM1083 1062l107 -107l293 293l-107 107zM1408 768l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98z" />
+<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M64 192q0 26 19 45t45 19v320q0 8 -0.5 35t0 38t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45v-1024q0 -15 -4 -26.5t-13.5 -18.5t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5 q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM384 128q0 -52 38 -90t90 -38 t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90zM1280 128q0 -52 38 -90t90 -38t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90z" />
+<glyph unicode="&#xf0d2;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63 q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5 q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423z" />
+<glyph unicode="&#xf0d3;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5 q-104 0 -194.5 -28.5t-153 -76.5t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118 q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf0d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM276 309q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117 q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94 q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95zM395 338q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78z M462 969q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5t-57.5 96.5t-17.5 106zM960 672h128v-160h64v160h128v64h-128v128h-64v-128h-128v-64z" />
+<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M32 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65 t-59.5 -61.5t-24.5 -66q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131zM218 228q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5q58 0 111.5 13t99 39t73 73 t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5zM324 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q38 0 78 16.5t66 43.5q53 57 53 159 q0 58 -17 125t-48.5 129.5t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160zM1084 731v108h212v217h105v-217h213v-108h-213v-219h-105v219h-212z" />
+<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M0 64v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45zM128 384q106 0 181 -75t75 -181h1152q0 106 75 181t181 75v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512zM640 640q0 70 21 142 t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142t-21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142zM762 791l77 -80q42 37 55 57h2v-288h-128v-96h384v96h-128v448h-114z" />
+<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M0 832q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M0 320q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M64 640q0 26 19 45l448 448q19 19 45 19t45 -19t19 -45v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M0 192v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45z" />
+<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M0 32v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h608v1152h-640v-1120zM896 0h608q13 0 22.5 9.5t9.5 22.5v1120h-640v-1152z" />
+<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45zM0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M0 32v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 1098q0 78 41.5 130t118.5 52h1472 q65 0 112.5 -47t47.5 -113q0 -79 -49 -151t-122 -123q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5z" />
+<glyph unicode="&#xf0e1;" d="M0 1217q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122zM19 -80v991h330v-991h-330zM531 -80q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5v-568 h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329z" />
+<glyph unicode="&#xf0e2;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M40 736q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18 q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5 q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5 t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68z" />
+<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M0 384q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29q-141 221 -141 483zM128 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M320 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM710 241q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91l101 382q6 26 -7.5 48.5t-38.5 29.5t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5 t-63 -98.5zM768 1024q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1216 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 384q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M0 640q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5 t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281zM128 640q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5t-381.5 -69.5 t-282 -187.5t-104.5 -255z" />
+<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM128 768q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52t-286 -52t-211.5 -141t-78.5 -191zM616 132 q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22 t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
+<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M1 551l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39z" />
+<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M0 -32v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M0 681q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17 q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5z M384 128q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180zM768 1310v98q0 26 19 45t45 19t45 -19t19 -45v-98q-42 2 -64 2t-64 -2z" />
+<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M0 96v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88v-672q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68zM256 1312q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5v64 q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64zM768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1280 640h299l-299 299v-299z" />
+<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M0 960q0 99 44.5 184.5t117 142t164 89t186.5 32.5t186.5 -32.5t164 -89t117 -142t44.5 -184.5q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47q0 -46 -31.5 -71t-77.5 -25 q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268zM128 960q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228 q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134zM480 1088q0 13 9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5 q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M0 256q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22zM0 800v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23 t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 608q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5z" />
+<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 672q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24z" />
+<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M0 131q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89 q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5 t81 -103t47.5 -132.5t24 -138t5.5 -131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190zM256 192q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5 t-271.5 112.5t-112.5 271.5z" />
+<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M0 768v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48 q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5 t-131.5 271.5v132q-164 20 -274 128t-110 252zM1152 832q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h64v-1280h-64q-92 0 -158 66t-66 158zM384 -128v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128v-1280h-1024zM640 1152h512v128h-512v-128zM1504 -128v1280h64q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-64z " />
+<glyph unicode="&#xf0f3;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
+<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM256 480v736q0 26 19 45t45 19h1152q159 0 271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158zM1408 704h64q80 0 136 56t56 136 t-56 136t-136 56h-64v-384z" />
+<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M0 832v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128 q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111zM768 416v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM384 160v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64 q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 416v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 672v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1536h-1152v-1536zM256 160v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 928v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 1184v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M0 -192v1280q0 26 19 45t45 19h320v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1152h-256 v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152zM256 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1056q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128 v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M64 192q0 26 19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128 q-26 0 -45 19t-19 45zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM384 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM896 800q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192 q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM1280 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h32v-1280h-32q-92 0 -158 66t-66 158zM352 -128v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160v-1280h-1088zM512 416q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192 q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM640 1152h512v128h-512v-128zM1536 -128v1280h32q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-32z" />
+<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M0 512v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93l1 -3q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5 t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8z" />
+<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M64 1152l32 128h480l32 128h960l32 -192l-64 -32v-800l128 -192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320zM384 768q0 -53 37.5 -90.5t90.5 -37.5h128v384h-256v-256z" />
+<glyph unicode="&#xf0fd;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 192q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896z" />
+<glyph unicode="&#xf0fe;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM429 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23 l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM397 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10 l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M77 224q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM77 608q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23 l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M77 672q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM77 1056q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10 l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf104;" horiz-adv-x="640" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf105;" horiz-adv-x="640" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M77 352q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M77 800q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M0 288v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113zM128 544q0 -13 9.5 -22.5 t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832z" />
+<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M0 96v96h160h1600h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68zM256 416v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113zM384 416q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5 t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM864 112q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16z" />
+<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M0 160v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-832q-66 0 -113 47t-47 113zM128 288q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM512 128 q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M0 128v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM96 288q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM288 1136 q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16zM304 128q0 -33 23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5z" />
+<glyph unicode="&#xf10c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273z" />
+<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M0 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z M896 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z" />
+<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M0 832v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136zM896 832v384 q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136z" />
+<glyph unicode="&#xf110;" horiz-adv-x="1568" d="M0 640q0 66 47 113t113 47t113 -47t47 -113t-47 -113t-113 -47t-113 47t-47 113zM176 1088q0 73 51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5t-51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5zM208 192q0 60 42 102t102 42q59 0 101.5 -42t42.5 -102t-42.5 -102 t-101.5 -42q-60 0 -102 42t-42 102zM608 1280q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM672 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1136 192q0 46 33 79t79 33t79 -33t33 -79 t-33 -79t-79 -33t-79 33t-33 79zM1168 1088q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1344 640q0 40 28 68t68 28t68 -28t28 -68t-28 -68t-68 -28t-68 28t-28 68z" />
+<glyph unicode="&#xf111;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5z" />
+<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101 t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19l-512 512q-19 19 -19 45z" />
+<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M0 496q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218q0 -87 -27 -168q136 -160 136 -398q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86t-170 -47.5t-171.5 -22t-167 -4.5 q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331zM224 320q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11 q-152 21 -195 21q-118 0 -187 -84t-69 -204zM384 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82zM1024 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34 t-43 76t-12.5 82z" />
+<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158zM128 224q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64 q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960z" />
+<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158zM128 331l256 315q44 53 116 87.5 t140 34.5h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-853zM171 163q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40z " />
+<glyph unicode="&#xf116;" horiz-adv-x="1792" />
+<glyph unicode="&#xf117;" horiz-adv-x="1792" />
+<glyph unicode="&#xf118;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 461q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38 q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5q-37 -121 -138 -195t-228 -74t-228 74t-138 195zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf119;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 307q37 121 138 195t228 74t228 -74t138 -195q8 -25 -4 -48.5 t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf11a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 448q0 26 19 45t45 19h640q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M0 512q0 212 150 362t362 150h896q212 0 362 -150t150 -362t-150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150t-150 362zM192 448q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23v128 q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128zM1152 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 640q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M0 128v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5zM128 128h1664v896h-1664v-896zM256 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM256 528v96 q0 16 16 16h224q16 0 16 -16v-96q0 -16 -16 -16h-224q-16 0 -16 16zM256 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM512 272v96q0 16 16 16h864q16 0 16 -16v-96q0 -16 -16 -16h-864q-16 0 -16 16zM512 784v96q0 16 16 16h96q16 0 16 -16v-96 q0 -16 -16 -16h-96q-16 0 -16 16zM640 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM768 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM896 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z M1024 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1152 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1280 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1408 528v96q0 16 16 16h112v240 q0 16 16 16h96q16 0 16 -16v-352q0 -16 -16 -16h-224q-16 0 -16 16zM1536 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z" />
+<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599z" />
+<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q205 96 384 110v192q-181 -16 -384 -117v-185zM448 836q215 111 384 118v197q-172 -8 -384 -126v-189zM832 730h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15 t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2q-23 0 -49 -3v-222zM1280 828q148 -42 384 90v189q-169 -91 -306 -91q-45 0 -78 8v-196z" />
+<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM640 32v64q0 14 9 23t23 9h960q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-960 q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM712 -52l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5 l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5zM1293 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45l397 -397v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45zM384 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221 q169 -173 169 -509q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45z" />
+<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M2 900.5q9 27.5 54 34.5l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5z M832 310l59 -31l318 -168l-60 355l-12 66l49 47l257 250l-356 52l-66 10l-30 60l-159 322v-963z" />
+<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M2 561q-5 22 4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5z" />
+<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M0 928v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864 q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23zM512 301l595 595h-595v-595zM557 256h595v595z" />
+<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M0 64q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136 q0 -52 -26 -96.5t-70 -69.5q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136zM96 64q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM96 1216q0 -40 28 -68 t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM736 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
+<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M0 448q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23zM16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56l-239 -18l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68 l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204zM128 32q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23zM544 -96v320q0 14 9 23t23 9t23 -9t9 -23v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23zM633 364 l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56zM1056 1184v320q0 14 9 23t23 9t23 -9t9 -23v-320 q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1216 1120q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23zM1280 960q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M96.5 986q-2.5 15 5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5t-10.5 37.5v45q0 83 65 156.5 t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25zM384 40v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28z" />
+<glyph unicode="&#xf129;" horiz-adv-x="640" d="M0 64v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM128 1152v192q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-192 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M98 1344q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45zM128 64v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf12b;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1013 713q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80h126v-206h-514l-3 27q-4 28 -4 46z " />
+<glyph unicode="&#xf12c;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1015 -183q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126v-206h-514l-4 27q-3 45 -3 46z" />
+<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M1.5 146.5q5.5 37.5 30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5zM128 128h768l336 384h-768z" />
+<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M0 0v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5 q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124 q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89 q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1z" />
+<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M0 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45 t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5zM256 704v512q0 132 94 226t226 94t226 -94t94 -226v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226z" />
+<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M13 64q0 13 10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23t-10 -23l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5 t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23zM128 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113l-101 -101 q-42 103 -42 214zM384 704v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
+<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M0 576v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150t-33.5 170.5zM640 79 q119 63 213 137q235 184 235 360v640h-448v-1137z" />
+<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h1408v1024h-1408v-1024z M384 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288zM1152 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288z" />
+<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M3.5 940q-8.5 25 3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96 q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37 zM384 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M36 464l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85 q-3 -1 -9 -1q-14 0 -23 9l-64 64q-17 19 -5 39zM1248 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
+<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M0 0l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334z" />
+<glyph unicode="&#xf137;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM346 640q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l102 102q19 19 19 45t-19 45l-307 307l307 307 q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
+<glyph unicode="&#xf138;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM506 288q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-454 454 q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45z" />
+<glyph unicode="&#xf139;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 544q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19l102 102 q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
+<glyph unicode="&#xf13a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 736q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-102 102 q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
+<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M0 1408h1408l-128 -1438l-578 -162l-574 162zM262 1114l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674l16 175h-884z" />
+<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M12 75l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208l59 297h1505l-266 -1333l-804 -267z" />
+<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M0 0v352q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5 l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30zM832 1280q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181v-320h736q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28 t-28 68z" />
+<glyph unicode="&#xf140;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM256 640q0 212 150 362t362 150t362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362zM384 640q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
+<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM512 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM1024 608v192q0 40 28 68t68 28h192 q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf142;" horiz-adv-x="384" d="M0 96v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h192q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf143;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 256q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M256 575q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10t9 24q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128zM256 959q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128 q13 0 23 10q11 9 9 23q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128z" />
+<glyph unicode="&#xf144;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 320q0 -37 32 -56q16 -8 32 -8q17 0 32 9l544 320q32 18 32 55t-32 55l-544 320q-31 19 -64 1 q-32 -19 -32 -56v-640z" />
+<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M54 448.5q0 53.5 37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136t-136 56t-136 -56l-125 126q-37 37 -37 90.5z M342 512q0 -26 19 -45l362 -362q18 -18 45 -18t45 18l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45zM452 512l572 572l316 -316l-572 -572z" />
+<glyph unicode="&#xf146;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h896q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128 z" />
+<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M3 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18z" />
+<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M3 1261q9 19 29 19h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34z" />
+<glyph unicode="&#xf14a;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 640q0 -26 19 -45l358 -358q19 -19 45 -19t45 19l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19 t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
+<glyph unicode="&#xf14b;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 128h288l544 544l-288 288l-544 -544v-288zM352 320v56l52 52l152 -152l-52 -52h-56v96h-96zM494 494 q-14 13 3 30l291 291q17 17 30 3q14 -13 -3 -30l-291 -291q-17 -17 -30 -3zM864 1024l288 -288l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28z" />
+<glyph unicode="&#xf14c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM282 320q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59 v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45z" />
+<glyph unicode="&#xf14d;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 448q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5t224 23.5v-160 q0 -42 40 -59q12 -5 24 -5q26 0 45 19l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5z" />
+<glyph unicode="&#xf14e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 241v542l512 256v-542zM640 448l256 128l-256 128v-256z" />
+<glyph unicode="&#xf150;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 861q17 35 57 35h640q40 0 57 -35q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66z" />
+<glyph unicode="&#xf151;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 419q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66q-17 -35 -57 -35h-640q-40 0 -57 35z" />
+<glyph unicode="&#xf152;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -14 9 -23t23 -9h960q14 0 23 9t9 23v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960z M512 320v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52t-27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57z" />
+<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M0 514v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5 t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5 l12 3l5 2q13 5 26 -2q12 -7 15 -21l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M0 32v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215 h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M52 171l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242 t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48 t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50t53 -63.5t31.5 -76.5t13 -94q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5 t-17.5 18q-17 21 -2 41z" />
+<glyph unicode="&#xf156;" horiz-adv-x="898" d="M0 605v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171 q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22z" />
+<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M4 1360q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103 q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214z" />
+<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M0 256v128q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315t-126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9 h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23zM487 747h320q106 0 171 62t65 162t-65 162t-171 62h-320v-448z" />
+<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M0 672v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111 q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23z M373 896l32 -128h225l35 128h-292zM436 640l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5l81 299h-159zM822 768h139l-35 128h-70zM1118 896l34 -128h230l33 128h-297zM1187 640l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3l78 300h-162z" />
+<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M56 0l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89 t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200zM522 182q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30t24.5 40t9.5 51q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1 t-47.5 -1v-338zM522 674q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307z" />
+<glyph unicode="&#xf15b;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
+<glyph unicode="&#xf15c;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM384 160q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 416q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 672q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
+<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 768v106h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106 h-287zM988 -166l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121v-233h-584v90zM1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18 t-7.5 -29z" />
+<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 -150h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287 v106zM988 768v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248v119h121v-233h-584zM1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29 z" />
+<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h256q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf162;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 261q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 1351l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17 v16h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 261q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
+<glyph unicode="&#xf163;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 1285q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 327l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16 h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 1285q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
+<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M0 64v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45zM128 192q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45zM480 64v641q0 25 18 43.5t43 20.5q24 2 76 59 t101 121q68 87 101 120q18 18 31 48t17.5 48.5t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135 q0 -86 -55 -149q15 -44 15 -76q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5z" />
+<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M0 448q0 -26 19 -45t45 -19h288q26 0 45 19t19 45v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640zM128 960q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45zM480 447v641q0 26 19 44.5t45 19.5q35 1 158 44 q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76q55 -61 55 -149q-1 -78 -57.5 -135t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39 t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121t-76 59q-25 2 -43 20.5t-18 43.5z" />
+<glyph unicode="&#xf166;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 366q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73 q20 84 20 260q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5q-20 -87 -20 -260zM300 551v70h232v-70h-80v-423h-74v423h-78zM396 1313l24 -69t23 -69q35 -103 46 -158v-201h74v201l90 296h-75l-51 -195l-53 195 h-78zM542 205v290h66v-270q0 -24 1 -26q1 -15 15 -15q20 0 42 31v280h67v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54zM654 936q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38q-21 -29 -21 -87v-130zM721 923 v156q0 52 32 52t32 -52v-156q0 -51 -32 -51t-32 51zM790 128v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67zM857 200q16 -16 33 -16q29 0 29 49v157q0 50 -29 50q-17 0 -33 -16v-224zM907 893q0 -37 6 -55 q11 -27 43 -27q36 0 77 45v-40h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293zM1037 247v129q0 59 20 86q29 38 80 38t78 -38q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68v-9q0 -29 -2 -43q-3 -22 -15 -40 q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86zM1103 355h66v34q0 51 -33 51t-33 -51v-34z" />
+<glyph unicode="&#xf167;" d="M27 260q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99q-26 112 -26 350zM138 509h105v-569h100v569h107v94h-312 v-94zM266 1536h106l71 -263l68 263h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187zM463 43q0 -49 8 -73q12 -37 58 -37q48 0 102 61v-54h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391zM614 1028v175q0 80 28 117q38 51 105 51 q69 0 106 -51q28 -37 28 -117v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51q-28 38 -28 118zM704 1011q0 -70 43 -70t43 70v210q0 69 -43 69t-43 -69v-210zM798 -60h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89 v-663zM887 36v301q22 22 45 22q39 0 39 -67v-211q0 -67 -39 -67q-23 0 -45 22zM955 971v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75zM1130 100q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54 q2 9 2 58v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51q-28 -37 -28 -116v-173zM1219 245v46q0 68 45 68t45 -68v-46h-90z" />
+<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M5 384q-10 17 0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45l164 -286q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17zM536 539q18 32 531 942q25 45 64 45h241q22 0 31 -15q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37 q-10 -15 -32 -15h-239q-42 0 -66 45z" />
+<glyph unicode="&#xf169;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM227 396q8 -13 24 -13h185q31 0 50 36l199 352q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29 l125 -216v-1l-196 -346q-9 -14 0 -28zM638 516q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1l409 723q8 16 0 28q-7 12 -24 12h-187q-30 0 -49 -35z" />
+<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M0 640q0 96 1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150t-1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58 t-69.5 123q-14 65 -21.5 147.5t-8.5 136.5t-1 150zM640 320q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54t-30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640z" />
+<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M64 558l338 271l494 -305l-342 -285zM64 1099l490 319l342 -285l-494 -304zM407 166v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284l147 96v-108l-490 -293v-1l-1 1l-1 -1v1zM896 524l494 305l338 -271l-489 -319zM896 1133l343 285l489 -319l-338 -270z" />
+<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M0 -255v736h121v-618h928v618h120v-701l-1 -35v-1h-1132l-35 1h-1zM221 -17v151l707 1v-151zM227 243l14 150l704 -65l-13 -150zM270 563l39 146l683 -183l-39 -146zM395 928l77 130l609 -360l-77 -130zM707 1303l125 86l398 -585l-124 -85zM1136 1510l149 26l121 -697 l-149 -26z" />
+<glyph unicode="&#xf16d;" d="M0 69v1142q0 81 58 139t139 58h1142q81 0 139 -58t58 -139v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139zM171 110q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62 q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648zM461 643q0 -124 90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5t-90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5zM1050 1003q0 -29 20 -49t49 -20h174q29 0 49 20t20 49v165q0 28 -20 48.5 t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165z" />
+<glyph unicode="&#xf16e;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM274 640q0 -88 62 -150t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150zM838 640q0 -88 62 -150 t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150z" />
+<glyph unicode="&#xf170;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM309 384h94l104 160h522l104 -160h94l-459 691zM567 608l201 306l201 -306h-402z" />
+<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M0 1222q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34 t-6 39.5t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158zM173 285l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18t-76.5 27 t-73 43.5t-52 61.5q-25 96 -57 292zM243 1240q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5q-20 27 -56 44.5t-58 22t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43zM481 657q4 -91 77.5 -155t165.5 -56q91 8 152 84 t50 168q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5zM599 710q14 41 52 58q36 18 72.5 12t64 -35.5t27.5 -67.5q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82z" />
+<glyph unicode="&#xf172;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM260 1060q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63 q24 13 39.5 23t31 29t19.5 40q48 267 80 473q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54zM385 384q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71q0 7 5.5 26.5t3 32 t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6zM436 1073q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5t-52.5 16t-54.5 32.5zM607 653q-2 49 25.5 93t72.5 64 q70 31 141.5 -10t81.5 -118q8 -66 -36 -121t-110 -61t-119 40t-56 113zM687.5 660.5q0.5 -52.5 43.5 -70.5q39 -23 81 4t36 72q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5z" />
+<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M78 779v217q91 30 155 84q64 55 103 132q39 78 54 196h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170z" />
+<glyph unicode="&#xf174;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM413 744h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49v181 q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163z" />
+<glyph unicode="&#xf175;" horiz-adv-x="768" d="M3 237q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19t-5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35z" />
+<glyph unicode="&#xf176;" horiz-adv-x="768" d="M3 1043q-8 19 5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19z" />
+<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M64 637q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23z" />
+<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M0 544v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M0 634q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32 q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503zM683 1131q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17z" />
+<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M0 -27v557h682v-651zM0 614v565l682 94v-659h-682zM757 -131v661h907v-786zM757 614v669l907 125v-794h-907z" />
+<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M0 337v430q0 42 30 72t73 30q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30t-73 30t-30 73zM241 886q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20l-71 -131q107 -55 171 -153.5t64 -215.5 h-925zM245 184v666h918v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78zM455 1092q0 -16 11 -27.5t27 -11.5t27.5 11.5t11.5 27.5t-11.5 27.5 t-27.5 11.5t-27 -11.5t-11 -27.5zM876 1092q0 -16 11.5 -27.5t27.5 -11.5t27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5zM1203 337v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73z" />
+<glyph unicode="&#xf17c;" d="M11 -115q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5 t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195q-12 112 -16 310q-2 90 24 151.5 t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5 t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13 t16.5 -9.5q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5 q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5zM321 495q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54 t7 -70.5q46 24 7 92q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5 t60 -22.5q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18zM372 630q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12zM603 1190q2 -5 5 -6 q10 0 7 -15q-3 -20 8 -20q3 0 3 3q3 17 -2.5 30t-11.5 15q-9 2 -9 -7zM634 1110q0 12 19 15h10q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5zM721 1122q24 11 32 -2q3 -6 -3 -9q-4 -1 -11.5 6.5t-17.5 4.5zM835 1196l4 -2q14 -4 18 -31q0 -3 8 2l2 3q0 11 -5 19.5t-11 12.5 t-9 3q-14 -1 -7 -7zM851 1381.5q-1 -2.5 3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9zM981 1002q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20q-2 8 -6.5 11.5t-13 5 t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5z" />
+<glyph unicode="&#xf17d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM112 640q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81t99.5 48l37 13 q4 1 13 3.5t13 4.5q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21zM126 775q302 0 606 80q-120 213 -244 378q-138 -65 -234 -186t-128 -272zM350 134q184 -150 418 -150q132 0 256 52q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5 t-103 -148zM609 1276q1 1 2 1q-1 0 -2 -1zM613 1277q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5l12.5 17.5q-185 164 -433 164q-76 0 -155 -19zM909 797q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5 t36.5 -6t25 -4.5l10 -2q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5zM1007 565q87 -239 128 -469q111 75 185 189.5t96 250.5q-210 60 -409 29z" />
+<glyph unicode="&#xf17e;" d="M0 1024q0 159 112.5 271.5t271.5 112.5q130 0 234 -80q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225 t-55.5 273.5q0 73 16 150q-80 104 -80 234zM376 399q0 -92 122 -157.5t291 -65.5q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12 t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5 q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75z" />
+<glyph unicode="&#xf180;" horiz-adv-x="1664" d="M0 640q0 75 53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41l619 619l2 -3q53 -53 53 -128t-53 -128l-587 -587 q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128zM302 660q0 21 14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36z" />
+<glyph unicode="&#xf181;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM160 192q0 -14 9 -23t23 -9h480q14 0 23 9t9 23v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024zM832 576q0 -14 9 -23t23 -9h480q14 0 23 9t9 23 v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640z" />
+<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M0 480q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192 q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43q-40 0 -68 28t-28 68zM416 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M0 416v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68z M288 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf184;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM399.5 766q8.5 -37 24.5 -59l349 -473l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5 t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85z" />
+<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M44 363q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29q-4 -15 -20 -20 l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20zM320 640q0 -117 45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5 t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5z" />
+<glyph unicode="&#xf186;" d="M0 640q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384z" />
+<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M64 1088v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM128 -64v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM704 704q0 -26 19 -45t45 -19h256 q26 0 45 19t19 45t-19 45t-45 19h-256q-26 0 -45 -19t-19 -45z" />
+<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M32 576q0 26 19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19t19 -45t-19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19 t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45z M512 1152q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5h-640z" />
+<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M-1 1004q0 11 3 16l4 6q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24 q17 19 38 30q53 26 239 24q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5 t13 3t20 0.5l288 2q39 5 64 -2.5t31 -16.5l6 -10q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12 q-30 21 -70 64t-68.5 77.5t-61 58t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211 t-130.5 272q-6 16 -6 27z" />
+<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M0 391q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5q0 -68 -37 -139.5 t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5zM181 320q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5zM413.5 230.5 q-40.5 92.5 6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5q-45 -102 -158 -150t-224 -12q-107 34 -147.5 126.5zM495 257.5q9 -34.5 43 -50.5t74.5 -2.5t62.5 47.5q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5zM705 399 q-17 -31 13 -45q14 -5 29 0.5t22 18.5q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5zM1165 1274q-6 28 9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158 q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5zM1224 1047q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5t54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37z" />
+<glyph unicode="&#xf18b;" d="M0 638q0 187 83.5 349.5t229.5 269.5t325 137v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495zM398 -34q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211q-171 -94 -368 -94q-196 0 -367 94zM898 909v485q179 -30 325 -137t229.5 -269.5 t83.5 -349.5q0 -280 -181 -495q-204 99 -330.5 306.5t-126.5 459.5z" />
+<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M0 -211q0 19 13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23 t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89 t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283 q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32z" />
+<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M21 217v66h1238v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5zM21 354v255h1238v-255h-1238zM21 682v255h1238v-255h-1238zM21 1010v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5v-67h-1238z" />
+<glyph unicode="&#xf18e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 544v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf190;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 640q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23z" />
+<glyph unicode="&#xf191;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM448 640q0 33 27 52l448 320q17 12 37 12q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52z" />
+<glyph unicode="&#xf192;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
+<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M0 320q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5zM416 1348q-2 16 6 42 q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455l198 99l58 -114l-256 -128q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5z" />
+<glyph unicode="&#xf194;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 806q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5 q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237q104 139 172.5 292.5t82.5 226.5q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143 q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7z" />
+<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M0 608v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31 l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26z" />
+<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf197;" horiz-adv-x="2176" d="M0 576q0 12 38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113q-110 -64 -268 -64h-128v64 h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5zM323 336h29q157 0 273 64h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96zM323 816l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5 t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64h-29zM1739 484l81 -30q68 48 68 122t-68 122l-81 -30q53 -36 53 -92t-53 -92z" />
+<glyph unicode="&#xf198;" horiz-adv-x="1664" d="M0 796q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5 t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72 l-55 163l-153 -53q-29 -9 -50 -9q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5zM620 811l105 -313l310 105l-105 315z" />
+<glyph unicode="&#xf199;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 352q0 -40 28 -68t68 -28h832q40 0 68 28t28 68v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99 q-98 -69 -164 -69t-164 69q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436zM256 928q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13 t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68z" />
+<glyph unicode="&#xf19a;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM41 640q0 -173 68 -331.5t182.5 -273t273 -182.5t331.5 -68t331.5 68t273 182.5t182.5 273t68 331.5 t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5zM127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM254 1062q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5 q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21t14.5 -24t14 -23q63 -107 63 -212q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15 t-1.5 -18.5t9 -16.5t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5zM679 -97l230 670l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1282 -24l235 678q59 169 59 276q0 42 -6 79 q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5z" />
+<glyph unicode="&#xf19b;" horiz-adv-x="1792" d="M0 455q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360l272 133v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5zM1134 860v172q277 -33 481 -157l140 79l37 -390l-525 114l147 83 q-119 70 -280 99z" />
+<glyph unicode="&#xf19c;" horiz-adv-x="2048" d="M0 -128q0 26 20.5 45t48.5 19h1782q28 0 48.5 -19t20.5 -45v-128h-1920v128zM0 1024v128l960 384l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128zM128 0v64q0 26 20.5 45t48.5 19h59v768h256v-768h128v768h256v-768h128v768h256 v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664z" />
+<glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M0 1024q0 23 22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31t-22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433 q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31zM512 384l18 316l574 -181q22 -7 48 -7t48 7l574 181l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128z" />
+<glyph unicode="&#xf19e;" d="M109 1536q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610l13 -707q-62 11 -105 11 q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287z" />
+<glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M111 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5t-59.5 -93 t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131zM297 228q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13 t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5zM403 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5 q53 56 53 159q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160z" />
+<glyph unicode="&#xf1a1;" horiz-adv-x="1984" d="M0 722q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58 q94 0 160 -66t66 -160q0 -62 -31 -114t-83 -82q5 -33 5 -61q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5zM77 722q0 -67 51 -111 q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM178 465q0 -101 59.5 -194t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5 t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5zM555 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM661 209.5q0 16.5 11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77q11 11 27 11t27 -11t11 -27.5t-11 -27.5 q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5zM1153 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM1555 1350q0 -45 32 -77t77 -32t77 32t32 77t-32 77t-77 32t-77 -32t-32 -77zM1672 843q131 -105 178 -238 q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28z" />
+<glyph unicode="&#xf1a2;" d="M0 193v894q0 133 94 227t226 94h896q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227zM155 709q0 -37 19.5 -67.5t52.5 -45.5q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54 q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43 q-51 0 -87 -36.5t-36 -87.5zM493 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM560 375q0 11 8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18z M882 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM1143 1120q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21q-29 0 -50 21t-21 50z" />
+<glyph unicode="&#xf1a3;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 502q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14 q19 0 32.5 -14t13.5 -33v-54l60 -28l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122zM806 500q0 -80 58 -137t139 -57t138.5 57t57.5 139v122h-150v-126q0 -20 -13.5 -33.5t-33.5 -13.5 q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123z" />
+<glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M0 336v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58l-131 61v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5zM1062 332 v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275h328v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5z" />
+<glyph unicode="&#xf1a5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM64 640h704v-704h480q93 0 158.5 65.5t65.5 158.5v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480z " />
+<glyph unicode="&#xf1a6;" horiz-adv-x="2048" d="M0 271v697h328v286h204v-983h-532zM205 435h123v369h-123v-369zM614 271h205v697h-205v-697zM614 1050h205v204h-205v-204zM901 26v163h328v82h-328v697h533v-942h-533zM1106 435h123v369h-123v-369zM1516 26v163h327v82h-327v697h532v-942h-532zM1720 435h123v369h-123 v-369z" />
+<glyph unicode="&#xf1a7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM293 388l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229t-88.5 229t-213.5 95q-74 0 -141 -36h-186v-840z M504 804v277q28 17 70 17q53 0 91 -45t38 -109t-38 -109.5t-91 -45.5q-43 0 -70 15zM636 -39l211 41v206q51 -19 117 -19q125 0 213 95t88 229t-88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101v-636zM847 377v277q28 17 70 17q53 0 91 -45.5t38 -109.5 t-38 -109t-91 -45q-43 0 -70 15z" />
+<glyph unicode="&#xf1a8;" horiz-adv-x="2038" d="M41 455q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80 t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5l1 -21q75 3 143.5 -20.5 t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14q6 -5 28 -23.5t25.5 -22t19 -18 t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63 t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27zM764 676q10 1 32.5 7t34.5 6q19 0 35 -10l-96 -20zM822 568l48 12l109 -177l-73 -48zM859 884q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1 v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5 t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43zM1061 45h31l10 -83l-41 -12v95zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM1116 29 q21 2 60.5 8.5t72 10t60.5 3.5h14q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13t-54 -9.5t-53.5 -7.5t-32 -4.5zM1947 1528l1 3l2 4l-1 -5zM1950 1535v1v-1zM1950 1535l1 1z" />
+<glyph unicode="&#xf1a9;" d="M0 520q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5 t19.5 -177.5q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302zM333 256q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5zM685.5 -76q-0.5 -10 7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5 q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16zM852 31q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5 t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10q-29 -12 -78 -56q-26 -24 -12 -44z" />
+<glyph unicode="&#xf1aa;" d="M0 78q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160l151 -152l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5 t-60 145.5zM2 1202q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5t149.5 -87.5l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5 q-70 15 -115 71t-45 129zM446 803l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126t135.5 51q85 0 145 -60.5t60 -145.5q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152 l-160 -160zM776 793l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5q76 -11 126.5 -68.5t50.5 -134.5q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30 l-152 152z" />
+<glyph unicode="&#xf1ab;" d="M0 -16v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5q20 0 20 -21v-418l147 -47v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3zM39 15l694 232v1032l-694 -233v-1031zM147 293q6 4 82 92 q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8 t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110 q-4 -2 -19.5 -4t-18.5 0zM268 933l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41zM310 -116q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11q73 -37 159.5 -61.5t157.5 -24.5 q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5l-43 73l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16zM777 1294l573 -184v380zM885 453l102 -31l45 110l211 -65l37 -135l102 -31l-181 657l-100 31z M1071 630l76 185l63 -227z" />
+<glyph unicode="&#xf1ac;" horiz-adv-x="1792" d="M0 -96v1088q0 66 47 113t113 47h128q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113zM512 -96v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-163q58 -34 93 -93t35 -128v-768q0 -106 -75 -181 t-181 -75h-864q-66 0 -113 47t-47 113zM640 896h896v256h-160q-40 0 -68 28t-28 68v160h-640v-512zM736 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM736 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9 h-128q-14 0 -23 -9t-9 -23v-128zM736 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 256q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23 v-128zM1248 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128z" />
+<glyph unicode="&#xf1ad;" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM256 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 1184q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 96v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23zM512 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM512 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 928q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM1024 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64z" />
+<glyph unicode="&#xf1ae;" horiz-adv-x="1280" d="M64 1056q0 40 28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68zM416 1152q0 93 65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf1b0;" horiz-adv-x="1664" d="M0 724q0 80 42 139.5t119 59.5q76 0 141.5 -55.5t100.5 -134t35 -152.5q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152zM256 19q0 86 56 191.5t139.5 192.5t187.5 146t193 59q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45 t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146zM333 1163q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151zM884 1064 q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5q-61 0 -105 39t-63 92.5t-19 113.5zM1226 581q0 74 35 152.5t100.5 134t141.5 55.5q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5 q-77 0 -119 59t-42 139z" />
+<glyph unicode="&#xf1b1;" horiz-adv-x="768" d="M64 1008q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5z" />
+<glyph unicode="&#xf1b2;" horiz-adv-x="1792" d="M0 256v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65zM134 1026l698 -254l698 254l-698 254zM896 -93l640 349v636l-640 -233v-752z" />
+<glyph unicode="&#xf1b3;" horiz-adv-x="2304" d="M0 96v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70v-400l434 -186q36 -16 57 -48t21 -70v-416q0 -36 -19 -67t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4 l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67zM172 531l404 -173l404 173l-404 173zM640 -96l384 192v314l-384 -164v-342zM647 1219l441 -189l441 189l-441 189zM1152 651l384 165v266l-384 -164v-267zM1196 531l404 -173l404 173l-404 173zM1664 -96 l384 192v314l-384 -164v-342z" />
+<glyph unicode="&#xf1b4;" horiz-adv-x="2048" d="M0 22v1260h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5 t45.5 113.5q0 144 -190 144h-260v-294zM1137 477q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658q0 -111 57.5 -171.5t166.5 -60.5q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347zM1337 1073h511v124 h-511v-124zM1388 576h408q-18 195 -200 195q-90 0 -146 -52.5t-62 -142.5z" />
+<glyph unicode="&#xf1b5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 254h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5t-56.5 60.5t-79 29.5 t-97 8.5h-371v-787zM301 388v217h189q124 0 124 -113q0 -104 -128 -104h-185zM301 723v184h163q119 0 119 -90q0 -94 -106 -94h-176zM838 538q0 -135 79 -217t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20q-68 0 -104 38t-36 107h411q1 10 1 30 q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216zM964 911v77h319v-77h-319zM996 600q4 56 39 89t91 33q113 0 124 -122h-254z" />
+<glyph unicode="&#xf1b6;" horiz-adv-x="2048" d="M0 764q0 86 61 146.5t146 60.5q73 0 130 -46t73 -117l783 -315q49 29 106 29q14 0 21 -1l173 248q1 114 82 194.5t195 80.5q115 0 196.5 -81t81.5 -196t-81.5 -196.5t-196.5 -81.5l-265 -194q-8 -80 -67.5 -133.5t-138.5 -53.5q-73 0 -130 46t-73 117l-783 315 q-51 -30 -106 -30q-85 0 -146 61t-61 147zM55 764q0 -64 44.5 -108.5t107.5 -44.5q11 0 33 4l-64 26q-33 14 -52.5 44.5t-19.5 66.5q0 50 35.5 85.5t85.5 35.5q20 0 41 -8v1l76 -31q-20 37 -56.5 59t-78.5 22q-63 0 -107.5 -44.5t-44.5 -107.5zM1164 244q19 -37 55.5 -59 t79.5 -22q63 0 107.5 44.5t44.5 107.5t-44.5 108t-107.5 45q-13 0 -33 -4q2 -1 20 -8t21.5 -8.5t18.5 -8.5t19 -10t16 -11t15.5 -13.5t11 -14.5t10 -18t5 -21t2.5 -25q0 -50 -35.5 -85.5t-85.5 -35.5q-14 0 -31.5 4.5t-29 9t-31.5 13.5t-28 12zM1584 767q0 -77 54.5 -131.5 t131.5 -54.5t132 54.5t55 131.5t-55 131.5t-132 54.5q-76 0 -131 -54.5t-55 -131.5zM1623 767q0 62 43.5 105.5t104.5 43.5t105 -44t44 -105t-43.5 -104.5t-105.5 -43.5q-61 0 -104.5 43.5t-43.5 104.5z" />
+<glyph unicode="&#xf1b7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 693q0 -53 38 -91t92 -38q36 0 66 18l489 -197q10 -44 45.5 -73t81.5 -29q50 0 86.5 34t41.5 83l167 122 q71 0 122 50.5t51 122.5t-51 123t-122 51q-72 0 -122.5 -50.5t-51.5 -121.5l-108 -155q-2 0 -6.5 0.5t-6.5 0.5q-35 0 -67 -19l-489 197q-10 44 -45.5 73t-80.5 29q-54 0 -92 -38t-38 -92zM162 693q0 40 28 68t68 28q27 0 49.5 -14t34.5 -37l-48 19q-29 11 -56.5 -2 t-38.5 -41q-12 -29 -0.5 -57t39.5 -40v-1l40 -16q-14 -2 -20 -2q-40 0 -68 27.5t-28 67.5zM855 369q5 -2 47 -19q29 -12 58 0.5t41 41.5q11 29 -1 57.5t-41 40.5l-40 16q14 2 21 2q39 0 67 -27.5t28 -67.5t-28 -67.5t-67 -27.5q-59 0 -85 51zM1118 695q0 48 34 82t83 34 q48 0 82 -34t34 -82t-34 -82t-82 -34q-49 0 -83 34t-34 82zM1142 696q0 -39 27.5 -66t65.5 -27t65.5 27t27.5 66q0 38 -27.5 65.5t-65.5 27.5t-65.5 -27.5t-27.5 -65.5z" />
+<glyph unicode="&#xf1b8;" horiz-adv-x="1792" d="M16 970l433 -17l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188zM270.5 158q-3.5 28 4 65t12 55t21.5 64t19 53q78 -12 509 -28l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5 q-11 27 -14.5 55zM294 1124l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5t36 -39.5t32 -35q-47 -63 -265 -435l-317 187zM782 1524l405 -1q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190l142 83l-220 -373l-419 20l151 86q-34 89 -75 166 t-75.5 123.5t-64.5 80t-47 46.5zM953 197l211 362l7 -173q170 -16 283 -5t170 33l56 22l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164zM1218 847l313 195l19 11l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22 t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436z" />
+<glyph unicode="&#xf1b9;" horiz-adv-x="1984" d="M0 160v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h704q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-928v-128q0 -80 -56 -136 t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23zM160 448q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 768h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 448q0 -66 47 -113t113 -47t113 47t47 113 t-47 113t-113 47t-113 -47t-47 -113z" />
+<glyph unicode="&#xf1ba;" horiz-adv-x="1984" d="M0 32v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h64q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-64q0 -80 -56 -136t-136 -56 t-136 56t-56 136v64h-928v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23zM160 320q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 640h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 320 q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113z" />
+<glyph unicode="&#xf1bb;" d="M32 64q0 26 19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45t-19 -45t-45 -19 h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf1bc;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM237 886q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37q159 0 309.5 -34t253.5 -95q21 -12 40 -12 q29 0 50.5 20.5t21.5 51.5q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5zM289 637q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5q0 40 -35 61 q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64zM321 406q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52z" />
+<glyph unicode="&#xf1bd;" d="M0 11v1258q0 58 40.5 98.5t98.5 40.5h1258q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5zM71 11q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258z M121 11v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5zM121 709v560q0 7 5.5 12.5 t12.5 5.5h1258q7 0 12.5 -5.5t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137zM246 413q-24 203 166 305l129 -270l-255 -61q-14 -3 -26 4.5t-14 21.5z" />
+<glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M0 405l17 128q2 9 9 9t9 -9l20 -128l-20 -126q-2 -9 -9 -9t-9 9zM79 405l23 207q0 9 9 9q8 0 10 -9l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10zM169 405l21 245q2 12 12 12q11 0 11 -12l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11zM259 405l21 252q0 13 13 13 q12 0 14 -13l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13zM350 405l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5zM401 159zM442 405l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5l21 -380l-21 -246q0 -7 -5 -12.5 t-12 -5.5q-16 0 -18 18zM534 403l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19zM628 405l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5l18 -506l-18 -242q-2 -21 -22 -21q-19 0 -21 21zM723 405l14 -241 q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17zM784 164zM817 405l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18zM913 404l12 492q1 12 9 20t19 8t18.5 -8 t8.5 -20l14 -492l-14 -236q0 -11 -8 -19t-19 -8t-19 8t-9 19zM1010 405q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11q11 0 20 9q9 7 9 20l1 24l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6zM1079 169zM1103 404l12 636v3q2 15 12 24q9 7 20 7 q8 0 15 -5q14 -8 16 -26l14 -639l-14 -231q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114zM1204 174v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22z" />
+<glyph unicode="&#xf1c0;" d="M0 0v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 384v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 768 v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 1152v128q0 69 103 128t280 93.5t385 34.5t385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128z" />
+<glyph unicode="&#xf1c1;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM257 60q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4 q52 85 107 197q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38 q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83z M714 842q1 7 7 44q0 3 7 43q1 4 4 8q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2q-15 -42 -2 -132zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1098 353q76 -28 124 -28q14 0 18 1q0 1 -2 3q-24 24 -140 24z" />
+<glyph unicode="&#xf1c2;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM233 661h70l164 -661h159l128 485q7 20 10 46q2 16 2 24 h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300v-107zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c3;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM429 0h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4 h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107h-290v-107h68l189 -272l-194 -283h-68v-106zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c4;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM416 0h327v106h-93v167h137q76 0 118 15q67 23 106.5 87 t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92v-106zM650 386v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15h-119zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c5;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 0v192l192 192l128 -128l384 384l320 -320v-320 h-1024zM256 704q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536zM384 192q0 25 8 52q21 63 120 396 v128h128v-128h79q22 0 39 -13t23 -34l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5zM512 192q0 -26 37.5 -45t90.5 -19t90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45zM512 896h128v128h-128v-128zM512 1152h128v128h-128v-128 zM640 768h128v128h-128v-128zM640 1024h128v128h-128v-128zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c7;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 288v192q0 14 9 23t23 9h131l166 167q16 15 35 7 q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23zM762 206.5q1 -26.5 20 -44.5q20 -17 44 -17q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5z M973.5 54.5q2.5 -26.5 23.5 -42.5q18 -15 40 -15q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c8;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 256v384q0 52 38 90t90 38h384q52 0 90 -38t38 -90 v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90zM960 403v90l265 266q9 9 23 9q4 0 12 -2q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c9;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM254 429q-14 19 0 38l226 301q8 11 21 12.5t24 -6.5 l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5zM636 43l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5l-63 10q-13 2 -20.5 13t-5.5 24zM947.5 181 q-1.5 13 6.5 24l182 243l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5l226 -301q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1ca;" d="M39 1286h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132 t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390z" />
+<glyph unicode="&#xf1cb;" horiz-adv-x="1792" d="M0 367v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64v-546q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64zM154 511l193 129l-193 129v-258zM216 367l603 -402v359l-334 223zM216 913l269 -180l334 223v359zM624 640 l272 -182l272 182l-272 182zM973 -35l603 402l-269 180l-334 -223v-359zM973 956l334 -223l269 180l-603 402v-359zM1445 640l193 -129v258z" />
+<glyph unicode="&#xf1cc;" horiz-adv-x="2048" d="M0 407q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5 h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55t121.5 -21 q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z " />
+<glyph unicode="&#xf1cd;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM128 640q0 -190 90 -361l194 194q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361zM512 640 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM535 -38q171 -90 361 -90t361 90l-194 194q-82 -28 -167 -28t-167 28zM535 1318l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90t-361 -90z M1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
+<glyph unicode="&#xf1ce;" horiz-adv-x="1792" d="M0 640q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5 q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348z" />
+<glyph unicode="&#xf1d0;" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
+<glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM44 640q0 -173 67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331 t-67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331zM87 640q0 205 98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385zM206 217l58 34q29 -49 73 -99 l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13v-66q-208 6 -385 109.5t-283 275.5zM207 1063q106 172 282 275.5t385 109.5v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98zM415 805q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10 t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162q-67 77 -98 169l232 80q-14 42 -14 85t14 85zM918 -102 q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99l58 -34q-106 -172 -283 -275.5t-385 -109.5v66zM918 1382v66q209 -6 385 -109.5t282 -275.5l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13zM1516 428q36 103 36 212q0 112 -35 212l82 28 q-19 56 -49 112l57 33q98 -180 98 -385t-98 -385l-57 33q27 52 49 112z" />
+<glyph unicode="&#xf1d2;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 218q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5 t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85q0 -53 41 -77v-3q-113 -37 -113 -139zM382 225q0 64 98 64q102 0 102 -61q0 -66 -93 -66 q-107 0 -107 63zM395 693q0 90 77 90q36 0 55 -25.5t19 -63.5q0 -85 -74 -85q-77 0 -77 84zM755 1072q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392q0 -50 -3 -75z M966 771q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117z" />
+<glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M68 7q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47q98 0 218 47v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58q0 -31 22.5 -51.5t58 -32 t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5zM272 18q0 -101 172 -101q151 0 151 105q0 100 -165 100q-158 0 -158 -104zM293 775q0 -135 124 -135q119 0 119 137q0 61 -30 102t-89 41 q-124 0 -124 -145zM875 1389q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5t-39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5zM901 220q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134h-222zM1217 901v190h96v76q0 54 -6 89h227q-6 -41 -6 -165 h171v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6z" />
+<glyph unicode="&#xf1d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM368 1135l323 -589v-435h134v436l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3 q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150z" />
+<glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M57 953q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5t-78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153 t-153 102t-186 38t-186 -38t-153 -102t-102 -153t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265zM113.5 38.5q10.5 121.5 29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5t136.5 -56.5 t56.5 -136.5t-57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5z" />
+<glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M18 264q0 275 252 466q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5 t3.5 -5t2 -3.5q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9 t-98 20t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20 q-18 -41 -54.5 -74.5t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100z" />
+<glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M0 858q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490z M380 1075q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5t-25 66t-66 25q-43 0 -76 -25.5t-33 -65.5zM816 404q0 143 81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109q-150 -37 -218 -37 q-169 0 -311 70.5t-223.5 191.5t-81.5 264zM888 1075q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5t-24.5 66t-65.5 25q-43 0 -76 -25.5t-33 -65.5zM1160 568q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5 t-22.5 -49.5zM1559 568q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5z" />
+<glyph unicode="&#xf1d8;" horiz-adv-x="1792" d="M0 508q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55z" />
+<glyph unicode="&#xf1d9;" horiz-adv-x="1792" d="M0 508q-3 39 32 59l1664 960q35 21 68 -2q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55zM209 522l336 -137l863 639l-478 -797l492 -201 l221 1323z" />
+<glyph unicode="&#xf1da;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45zM512 480v64q0 14 9 23t23 9h224v352 q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf1db;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5z" />
+<glyph unicode="&#xf1dc;" horiz-adv-x="1792" d="M62 1338q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5 t45 -15t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18 q-15 10 -45 12t-53 2t-41 14t-18 45z" />
+<glyph unicode="&#xf1dd;" horiz-adv-x="1280" d="M24 926q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108 q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179q-64 117 -64 259z" />
+<glyph unicode="&#xf1de;" d="M0 736v64q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM128 -96v672h256v-672q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM128 960v416q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-416h-256zM512 224v64q0 40 28 68 t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 64h256v-160q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v160zM640 448v928q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-928h-256zM1024 992v64q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1152 -96v928h256v-928q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 1216v160q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-160h-256z" />
+<glyph unicode="&#xf1e0;" d="M0 640q0 133 93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86q133 0 226.5 -93.5t93.5 -226.5 t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5z" />
+<glyph unicode="&#xf1e1;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 640q0 -88 62.5 -150.5t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5 t150.5 62.5t62.5 150.5t-62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5z" />
+<glyph unicode="&#xf1e2;" horiz-adv-x="1792" d="M0 448q0 143 55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68l243 244l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5 t-225 150t-150 225t-55.5 273.5zM170 615q10 -24 35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49t-34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49zM1376 1472q0 13 9 23q10 9 23 9t23 -9l90 -91q10 -9 10 -22.5t-10 -22.5 q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23zM1536 1408v96q0 14 9 23t23 9t23 -9t9 -23v-96q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1605 1242.5q0 13.5 10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5z M1605 1381.5q0 13.5 10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5zM1632 1312q0 14 9 23t23 9h96q14 0 23 -9t9 -23t-9 -23t-23 -9h-96q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf1e3;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e4;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e5;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e6;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e7;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e8;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e9;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ea;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1eb;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ec;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ed;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ee;" horiz-adv-x="1792" />
+<glyph unicode="&#xf500;" horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+</font>
+</defs></svg> 
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf
new file mode 100644 (file)
index 0000000..5cd6cff
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.woff b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.woff
new file mode 100644 (file)
index 0000000..9eaecb3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/fonts/fontawesome-webfont.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/bordered-pulled.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/bordered-pulled.less
new file mode 100644 (file)
index 0000000..0c90eb5
--- /dev/null
@@ -0,0 +1,16 @@
+// Bordered & Pulled
+// -------------------------
+
+.@{fa-css-prefix}-border {
+  padding: .2em .25em .15em;
+  border: solid .08em @fa-border-color;
+  border-radius: .1em;
+}
+
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.@{fa-css-prefix} {
+  &.pull-left { margin-right: .3em; }
+  &.pull-right { margin-left: .3em; }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/core.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/core.less
new file mode 100644 (file)
index 0000000..6d223bc
--- /dev/null
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.@{fa-css-prefix} {
+  display: inline-block;
+  font-family: FontAwesome;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/fixed-width.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/fixed-width.less
new file mode 100644 (file)
index 0000000..110289f
--- /dev/null
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.@{fa-css-prefix}-fw {
+  width: (18em / 14);
+  text-align: center;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/font-awesome.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/font-awesome.less
new file mode 100644 (file)
index 0000000..50cbcac
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+ *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables.less";
+@import "mixins.less";
+@import "path.less";
+@import "core.less";
+@import "larger.less";
+@import "fixed-width.less";
+@import "list.less";
+@import "bordered-pulled.less";
+@import "spinning.less";
+@import "rotated-flipped.less";
+@import "stacked.less";
+@import "icons.less";
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/icons.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/icons.less
new file mode 100644 (file)
index 0000000..13d8c68
--- /dev/null
@@ -0,0 +1,506 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+
+.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }
+.@{fa-css-prefix}-music:before { content: @fa-var-music; }
+.@{fa-css-prefix}-search:before { content: @fa-var-search; }
+.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }
+.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }
+.@{fa-css-prefix}-star:before { content: @fa-var-star; }
+.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }
+.@{fa-css-prefix}-user:before { content: @fa-var-user; }
+.@{fa-css-prefix}-film:before { content: @fa-var-film; }
+.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }
+.@{fa-css-prefix}-th:before { content: @fa-var-th; }
+.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
+.@{fa-css-prefix}-check:before { content: @fa-var-check; }
+.@{fa-css-prefix}-times:before { content: @fa-var-times; }
+.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
+.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
+.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }
+.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }
+.@{fa-css-prefix}-gear:before,
+.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }
+.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }
+.@{fa-css-prefix}-home:before { content: @fa-var-home; }
+.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }
+.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }
+.@{fa-css-prefix}-road:before { content: @fa-var-road; }
+.@{fa-css-prefix}-download:before { content: @fa-var-download; }
+.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }
+.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }
+.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }
+.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }
+.@{fa-css-prefix}-rotate-right:before,
+.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }
+.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }
+.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }
+.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }
+.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }
+.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }
+.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }
+.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }
+.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }
+.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }
+.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }
+.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }
+.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }
+.@{fa-css-prefix}-book:before { content: @fa-var-book; }
+.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }
+.@{fa-css-prefix}-print:before { content: @fa-var-print; }
+.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }
+.@{fa-css-prefix}-font:before { content: @fa-var-font; }
+.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }
+.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }
+.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }
+.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }
+.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }
+.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }
+.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }
+.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }
+.@{fa-css-prefix}-list:before { content: @fa-var-list; }
+.@{fa-css-prefix}-dedent:before,
+.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }
+.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }
+.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }
+.@{fa-css-prefix}-photo:before,
+.@{fa-css-prefix}-image:before,
+.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }
+.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }
+.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }
+.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }
+.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }
+.@{fa-css-prefix}-edit:before,
+.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }
+.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }
+.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }
+.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }
+.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }
+.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }
+.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }
+.@{fa-css-prefix}-play:before { content: @fa-var-play; }
+.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }
+.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }
+.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }
+.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }
+.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }
+.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }
+.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }
+.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }
+.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }
+.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }
+.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }
+.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }
+.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }
+.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }
+.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }
+.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }
+.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }
+.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }
+.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }
+.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }
+.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }
+.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }
+.@{fa-css-prefix}-mail-forward:before,
+.@{fa-css-prefix}-share:before { content: @fa-var-share; }
+.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }
+.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }
+.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }
+.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }
+.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }
+.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }
+.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }
+.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }
+.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }
+.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }
+.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }
+.@{fa-css-prefix}-warning:before,
+.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }
+.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }
+.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }
+.@{fa-css-prefix}-random:before { content: @fa-var-random; }
+.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }
+.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }
+.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }
+.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }
+.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }
+.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }
+.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }
+.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
+.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
+.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
+.@{fa-css-prefix}-bar-chart-o:before { content: @fa-var-bar-chart-o; }
+.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
+.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
+.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
+.@{fa-css-prefix}-key:before { content: @fa-var-key; }
+.@{fa-css-prefix}-gears:before,
+.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }
+.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }
+.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }
+.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }
+.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }
+.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }
+.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }
+.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }
+.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }
+.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }
+.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }
+.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }
+.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }
+.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }
+.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }
+.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }
+.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
+.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
+.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
+.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
+.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
+.@{fa-css-prefix}-github:before { content: @fa-var-github; }
+.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
+.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
+.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
+.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
+.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
+.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }
+.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }
+.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }
+.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }
+.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }
+.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }
+.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }
+.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }
+.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }
+.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }
+.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }
+.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }
+.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }
+.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }
+.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }
+.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }
+.@{fa-css-prefix}-group:before,
+.@{fa-css-prefix}-users:before { content: @fa-var-users; }
+.@{fa-css-prefix}-chain:before,
+.@{fa-css-prefix}-link:before { content: @fa-var-link; }
+.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }
+.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }
+.@{fa-css-prefix}-cut:before,
+.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }
+.@{fa-css-prefix}-copy:before,
+.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }
+.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }
+.@{fa-css-prefix}-save:before,
+.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }
+.@{fa-css-prefix}-square:before { content: @fa-var-square; }
+.@{fa-css-prefix}-navicon:before,
+.@{fa-css-prefix}-reorder:before,
+.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }
+.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }
+.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }
+.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }
+.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }
+.@{fa-css-prefix}-table:before { content: @fa-var-table; }
+.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }
+.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }
+.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }
+.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }
+.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }
+.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }
+.@{fa-css-prefix}-money:before { content: @fa-var-money; }
+.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }
+.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }
+.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }
+.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }
+.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }
+.@{fa-css-prefix}-unsorted:before,
+.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }
+.@{fa-css-prefix}-sort-down:before,
+.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }
+.@{fa-css-prefix}-sort-up:before,
+.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }
+.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }
+.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }
+.@{fa-css-prefix}-rotate-left:before,
+.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }
+.@{fa-css-prefix}-legal:before,
+.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }
+.@{fa-css-prefix}-dashboard:before,
+.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }
+.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }
+.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }
+.@{fa-css-prefix}-flash:before,
+.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }
+.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }
+.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }
+.@{fa-css-prefix}-paste:before,
+.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }
+.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }
+.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }
+.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }
+.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }
+.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }
+.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }
+.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }
+.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }
+.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }
+.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }
+.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }
+.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }
+.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }
+.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }
+.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }
+.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }
+.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }
+.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }
+.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }
+.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }
+.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }
+.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }
+.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }
+.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }
+.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }
+.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }
+.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }
+.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }
+.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }
+.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }
+.@{fa-css-prefix}-mobile-phone:before,
+.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }
+.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }
+.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }
+.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }
+.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }
+.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }
+.@{fa-css-prefix}-mail-reply:before,
+.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }
+.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }
+.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }
+.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }
+.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }
+.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }
+.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }
+.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }
+.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }
+.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }
+.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }
+.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }
+.@{fa-css-prefix}-code:before { content: @fa-var-code; }
+.@{fa-css-prefix}-mail-reply-all:before,
+.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }
+.@{fa-css-prefix}-star-half-empty:before,
+.@{fa-css-prefix}-star-half-full:before,
+.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }
+.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }
+.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }
+.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }
+.@{fa-css-prefix}-unlink:before,
+.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }
+.@{fa-css-prefix}-question:before { content: @fa-var-question; }
+.@{fa-css-prefix}-info:before { content: @fa-var-info; }
+.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }
+.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }
+.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }
+.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }
+.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }
+.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }
+.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }
+.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }
+.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }
+.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }
+.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }
+.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }
+.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }
+.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }
+.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }
+.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }
+.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }
+.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }
+.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }
+.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }
+.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }
+.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }
+.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }
+.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }
+.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }
+.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }
+.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }
+.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }
+.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }
+.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }
+.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }
+.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }
+.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }
+.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }
+.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }
+.@{fa-css-prefix}-toggle-down:before,
+.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }
+.@{fa-css-prefix}-toggle-up:before,
+.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }
+.@{fa-css-prefix}-toggle-right:before,
+.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }
+.@{fa-css-prefix}-euro:before,
+.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }
+.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }
+.@{fa-css-prefix}-dollar:before,
+.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }
+.@{fa-css-prefix}-rupee:before,
+.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }
+.@{fa-css-prefix}-cny:before,
+.@{fa-css-prefix}-rmb:before,
+.@{fa-css-prefix}-yen:before,
+.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }
+.@{fa-css-prefix}-ruble:before,
+.@{fa-css-prefix}-rouble:before,
+.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }
+.@{fa-css-prefix}-won:before,
+.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }
+.@{fa-css-prefix}-bitcoin:before,
+.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }
+.@{fa-css-prefix}-file:before { content: @fa-var-file; }
+.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }
+.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }
+.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }
+.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }
+.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }
+.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }
+.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }
+.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }
+.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }
+.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }
+.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }
+.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }
+.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }
+.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }
+.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }
+.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }
+.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }
+.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }
+.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }
+.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }
+.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }
+.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }
+.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }
+.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }
+.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }
+.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }
+.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }
+.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }
+.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }
+.@{fa-css-prefix}-android:before { content: @fa-var-android; }
+.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }
+.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }
+.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }
+.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }
+.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
+.@{fa-css-prefix}-female:before { content: @fa-var-female; }
+.@{fa-css-prefix}-male:before { content: @fa-var-male; }
+.@{fa-css-prefix}-gittip:before { content: @fa-var-gittip; }
+.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
+.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
+.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
+.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }
+.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }
+.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }
+.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }
+.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }
+.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }
+.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }
+.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }
+.@{fa-css-prefix}-toggle-left:before,
+.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }
+.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }
+.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }
+.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }
+.@{fa-css-prefix}-turkish-lira:before,
+.@{fa-css-prefix}-try:before { content: @fa-var-try; }
+.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }
+.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }
+.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }
+.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }
+.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }
+.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }
+.@{fa-css-prefix}-institution:before,
+.@{fa-css-prefix}-bank:before,
+.@{fa-css-prefix}-university:before { content: @fa-var-university; }
+.@{fa-css-prefix}-mortar-board:before,
+.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }
+.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }
+.@{fa-css-prefix}-google:before { content: @fa-var-google; }
+.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }
+.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }
+.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }
+.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
+.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
+.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
+.@{fa-css-prefix}-pied-piper-square:before,
+.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
+.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
+.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
+.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }
+.@{fa-css-prefix}-language:before { content: @fa-var-language; }
+.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }
+.@{fa-css-prefix}-building:before { content: @fa-var-building; }
+.@{fa-css-prefix}-child:before { content: @fa-var-child; }
+.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }
+.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }
+.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }
+.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }
+.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }
+.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }
+.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }
+.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }
+.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }
+.@{fa-css-prefix}-automobile:before,
+.@{fa-css-prefix}-car:before { content: @fa-var-car; }
+.@{fa-css-prefix}-cab:before,
+.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }
+.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }
+.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }
+.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }
+.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }
+.@{fa-css-prefix}-database:before { content: @fa-var-database; }
+.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }
+.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }
+.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }
+.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }
+.@{fa-css-prefix}-file-photo-o:before,
+.@{fa-css-prefix}-file-picture-o:before,
+.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }
+.@{fa-css-prefix}-file-zip-o:before,
+.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }
+.@{fa-css-prefix}-file-sound-o:before,
+.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }
+.@{fa-css-prefix}-file-movie-o:before,
+.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }
+.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }
+.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }
+.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
+.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
+.@{fa-css-prefix}-life-bouy:before,
+.@{fa-css-prefix}-life-saver:before,
+.@{fa-css-prefix}-support:before,
+.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
+.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }
+.@{fa-css-prefix}-ra:before,
+.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }
+.@{fa-css-prefix}-ge:before,
+.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
+.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
+.@{fa-css-prefix}-git:before { content: @fa-var-git; }
+.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
+.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
+.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
+.@{fa-css-prefix}-wechat:before,
+.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }
+.@{fa-css-prefix}-send:before,
+.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }
+.@{fa-css-prefix}-send-o:before,
+.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }
+.@{fa-css-prefix}-history:before { content: @fa-var-history; }
+.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }
+.@{fa-css-prefix}-header:before { content: @fa-var-header; }
+.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }
+.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }
+.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
+.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
+.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/larger.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/larger.less
new file mode 100644 (file)
index 0000000..c9d6467
--- /dev/null
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.@{fa-css-prefix}-lg {
+  font-size: (4em / 3);
+  line-height: (3em / 4);
+  vertical-align: -15%;
+}
+.@{fa-css-prefix}-2x { font-size: 2em; }
+.@{fa-css-prefix}-3x { font-size: 3em; }
+.@{fa-css-prefix}-4x { font-size: 4em; }
+.@{fa-css-prefix}-5x { font-size: 5em; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/list.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/list.less
new file mode 100644 (file)
index 0000000..eed9340
--- /dev/null
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.@{fa-css-prefix}-ul {
+  padding-left: 0;
+  margin-left: @fa-li-width;
+  list-style-type: none;
+  > li { position: relative; }
+}
+.@{fa-css-prefix}-li {
+  position: absolute;
+  left: -@fa-li-width;
+  width: @fa-li-width;
+  top: (2em / 14);
+  text-align: center;
+  &.@{fa-css-prefix}-lg {
+    left: -@fa-li-width + (4em / 14);
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/mixins.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/mixins.less
new file mode 100644 (file)
index 0000000..19e5a64
--- /dev/null
@@ -0,0 +1,20 @@
+// Mixins
+// --------------------------
+
+.fa-icon-rotate(@degrees, @rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation);
+  -webkit-transform: rotate(@degrees);
+     -moz-transform: rotate(@degrees);
+      -ms-transform: rotate(@degrees);
+       -o-transform: rotate(@degrees);
+          transform: rotate(@degrees);
+}
+
+.fa-icon-flip(@horiz, @vert, @rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1);
+  -webkit-transform: scale(@horiz, @vert);
+     -moz-transform: scale(@horiz, @vert);
+      -ms-transform: scale(@horiz, @vert);
+       -o-transform: scale(@horiz, @vert);
+          transform: scale(@horiz, @vert);
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/path.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/path.less
new file mode 100644 (file)
index 0000000..d73bff8
--- /dev/null
@@ -0,0 +1,14 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+  font-family: 'FontAwesome';
+  src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')";
+  src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')",
+    ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')",
+    ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')",
+    ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')";
+//  src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+  font-weight: normal;
+  font-style: normal;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/rotated-flipped.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/rotated-flipped.less
new file mode 100644 (file)
index 0000000..8fff3a6
--- /dev/null
@@ -0,0 +1,9 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }
+.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
+.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
+
+.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
+.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/spinning.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/spinning.less
new file mode 100644 (file)
index 0000000..06b71ec
--- /dev/null
@@ -0,0 +1,32 @@
+// Spinning Icons
+// --------------------------
+
+.@{fa-css-prefix}-spin {
+  -webkit-animation: spin 2s infinite linear;
+  -moz-animation: spin 2s infinite linear;
+  -o-animation: spin 2s infinite linear;
+  animation: spin 2s infinite linear;
+}
+
+@-moz-keyframes spin {
+  0% { -moz-transform: rotate(0deg); }
+  100% { -moz-transform: rotate(359deg); }
+}
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(359deg); }
+}
+@-o-keyframes spin {
+  0% { -o-transform: rotate(0deg); }
+  100% { -o-transform: rotate(359deg); }
+}
+@keyframes spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/stacked.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/stacked.less
new file mode 100644 (file)
index 0000000..fc53fb0
--- /dev/null
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.@{fa-css-prefix}-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.@{fa-css-prefix}-stack-1x { line-height: inherit; }
+.@{fa-css-prefix}-stack-2x { font-size: 2em; }
+.@{fa-css-prefix}-inverse { color: @fa-inverse; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/variables.less b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/less/variables.less
new file mode 100644 (file)
index 0000000..d7e8bd7
--- /dev/null
@@ -0,0 +1,515 @@
+// Variables
+// --------------------------
+
+@fa-font-path:        "../fonts";
+//@fa-font-path:        "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts"; // for referencing Bootstrap CDN font files directly
+@fa-css-prefix:       fa;
+@fa-version:          "4.1.0";
+@fa-border-color:     #eee;
+@fa-inverse:          #fff;
+@fa-li-width:         (30em / 14);
+
+@fa-var-adjust: "\f042";
+@fa-var-adn: "\f170";
+@fa-var-align-center: "\f037";
+@fa-var-align-justify: "\f039";
+@fa-var-align-left: "\f036";
+@fa-var-align-right: "\f038";
+@fa-var-ambulance: "\f0f9";
+@fa-var-anchor: "\f13d";
+@fa-var-android: "\f17b";
+@fa-var-angle-double-down: "\f103";
+@fa-var-angle-double-left: "\f100";
+@fa-var-angle-double-right: "\f101";
+@fa-var-angle-double-up: "\f102";
+@fa-var-angle-down: "\f107";
+@fa-var-angle-left: "\f104";
+@fa-var-angle-right: "\f105";
+@fa-var-angle-up: "\f106";
+@fa-var-apple: "\f179";
+@fa-var-archive: "\f187";
+@fa-var-arrow-circle-down: "\f0ab";
+@fa-var-arrow-circle-left: "\f0a8";
+@fa-var-arrow-circle-o-down: "\f01a";
+@fa-var-arrow-circle-o-left: "\f190";
+@fa-var-arrow-circle-o-right: "\f18e";
+@fa-var-arrow-circle-o-up: "\f01b";
+@fa-var-arrow-circle-right: "\f0a9";
+@fa-var-arrow-circle-up: "\f0aa";
+@fa-var-arrow-down: "\f063";
+@fa-var-arrow-left: "\f060";
+@fa-var-arrow-right: "\f061";
+@fa-var-arrow-up: "\f062";
+@fa-var-arrows: "\f047";
+@fa-var-arrows-alt: "\f0b2";
+@fa-var-arrows-h: "\f07e";
+@fa-var-arrows-v: "\f07d";
+@fa-var-asterisk: "\f069";
+@fa-var-automobile: "\f1b9";
+@fa-var-backward: "\f04a";
+@fa-var-ban: "\f05e";
+@fa-var-bank: "\f19c";
+@fa-var-bar-chart-o: "\f080";
+@fa-var-barcode: "\f02a";
+@fa-var-bars: "\f0c9";
+@fa-var-beer: "\f0fc";
+@fa-var-behance: "\f1b4";
+@fa-var-behance-square: "\f1b5";
+@fa-var-bell: "\f0f3";
+@fa-var-bell-o: "\f0a2";
+@fa-var-bitbucket: "\f171";
+@fa-var-bitbucket-square: "\f172";
+@fa-var-bitcoin: "\f15a";
+@fa-var-bold: "\f032";
+@fa-var-bolt: "\f0e7";
+@fa-var-bomb: "\f1e2";
+@fa-var-book: "\f02d";
+@fa-var-bookmark: "\f02e";
+@fa-var-bookmark-o: "\f097";
+@fa-var-briefcase: "\f0b1";
+@fa-var-btc: "\f15a";
+@fa-var-bug: "\f188";
+@fa-var-building: "\f1ad";
+@fa-var-building-o: "\f0f7";
+@fa-var-bullhorn: "\f0a1";
+@fa-var-bullseye: "\f140";
+@fa-var-cab: "\f1ba";
+@fa-var-calendar: "\f073";
+@fa-var-calendar-o: "\f133";
+@fa-var-camera: "\f030";
+@fa-var-camera-retro: "\f083";
+@fa-var-car: "\f1b9";
+@fa-var-caret-down: "\f0d7";
+@fa-var-caret-left: "\f0d9";
+@fa-var-caret-right: "\f0da";
+@fa-var-caret-square-o-down: "\f150";
+@fa-var-caret-square-o-left: "\f191";
+@fa-var-caret-square-o-right: "\f152";
+@fa-var-caret-square-o-up: "\f151";
+@fa-var-caret-up: "\f0d8";
+@fa-var-certificate: "\f0a3";
+@fa-var-chain: "\f0c1";
+@fa-var-chain-broken: "\f127";
+@fa-var-check: "\f00c";
+@fa-var-check-circle: "\f058";
+@fa-var-check-circle-o: "\f05d";
+@fa-var-check-square: "\f14a";
+@fa-var-check-square-o: "\f046";
+@fa-var-chevron-circle-down: "\f13a";
+@fa-var-chevron-circle-left: "\f137";
+@fa-var-chevron-circle-right: "\f138";
+@fa-var-chevron-circle-up: "\f139";
+@fa-var-chevron-down: "\f078";
+@fa-var-chevron-left: "\f053";
+@fa-var-chevron-right: "\f054";
+@fa-var-chevron-up: "\f077";
+@fa-var-child: "\f1ae";
+@fa-var-circle: "\f111";
+@fa-var-circle-o: "\f10c";
+@fa-var-circle-o-notch: "\f1ce";
+@fa-var-circle-thin: "\f1db";
+@fa-var-clipboard: "\f0ea";
+@fa-var-clock-o: "\f017";
+@fa-var-cloud: "\f0c2";
+@fa-var-cloud-download: "\f0ed";
+@fa-var-cloud-upload: "\f0ee";
+@fa-var-cny: "\f157";
+@fa-var-code: "\f121";
+@fa-var-code-fork: "\f126";
+@fa-var-codepen: "\f1cb";
+@fa-var-coffee: "\f0f4";
+@fa-var-cog: "\f013";
+@fa-var-cogs: "\f085";
+@fa-var-columns: "\f0db";
+@fa-var-comment: "\f075";
+@fa-var-comment-o: "\f0e5";
+@fa-var-comments: "\f086";
+@fa-var-comments-o: "\f0e6";
+@fa-var-compass: "\f14e";
+@fa-var-compress: "\f066";
+@fa-var-copy: "\f0c5";
+@fa-var-credit-card: "\f09d";
+@fa-var-crop: "\f125";
+@fa-var-crosshairs: "\f05b";
+@fa-var-css3: "\f13c";
+@fa-var-cube: "\f1b2";
+@fa-var-cubes: "\f1b3";
+@fa-var-cut: "\f0c4";
+@fa-var-cutlery: "\f0f5";
+@fa-var-dashboard: "\f0e4";
+@fa-var-database: "\f1c0";
+@fa-var-dedent: "\f03b";
+@fa-var-delicious: "\f1a5";
+@fa-var-desktop: "\f108";
+@fa-var-deviantart: "\f1bd";
+@fa-var-digg: "\f1a6";
+@fa-var-dollar: "\f155";
+@fa-var-dot-circle-o: "\f192";
+@fa-var-download: "\f019";
+@fa-var-dribbble: "\f17d";
+@fa-var-dropbox: "\f16b";
+@fa-var-drupal: "\f1a9";
+@fa-var-edit: "\f044";
+@fa-var-eject: "\f052";
+@fa-var-ellipsis-h: "\f141";
+@fa-var-ellipsis-v: "\f142";
+@fa-var-empire: "\f1d1";
+@fa-var-envelope: "\f0e0";
+@fa-var-envelope-o: "\f003";
+@fa-var-envelope-square: "\f199";
+@fa-var-eraser: "\f12d";
+@fa-var-eur: "\f153";
+@fa-var-euro: "\f153";
+@fa-var-exchange: "\f0ec";
+@fa-var-exclamation: "\f12a";
+@fa-var-exclamation-circle: "\f06a";
+@fa-var-exclamation-triangle: "\f071";
+@fa-var-expand: "\f065";
+@fa-var-external-link: "\f08e";
+@fa-var-external-link-square: "\f14c";
+@fa-var-eye: "\f06e";
+@fa-var-eye-slash: "\f070";
+@fa-var-facebook: "\f09a";
+@fa-var-facebook-square: "\f082";
+@fa-var-fast-backward: "\f049";
+@fa-var-fast-forward: "\f050";
+@fa-var-fax: "\f1ac";
+@fa-var-female: "\f182";
+@fa-var-fighter-jet: "\f0fb";
+@fa-var-file: "\f15b";
+@fa-var-file-archive-o: "\f1c6";
+@fa-var-file-audio-o: "\f1c7";
+@fa-var-file-code-o: "\f1c9";
+@fa-var-file-excel-o: "\f1c3";
+@fa-var-file-image-o: "\f1c5";
+@fa-var-file-movie-o: "\f1c8";
+@fa-var-file-o: "\f016";
+@fa-var-file-pdf-o: "\f1c1";
+@fa-var-file-photo-o: "\f1c5";
+@fa-var-file-picture-o: "\f1c5";
+@fa-var-file-powerpoint-o: "\f1c4";
+@fa-var-file-sound-o: "\f1c7";
+@fa-var-file-text: "\f15c";
+@fa-var-file-text-o: "\f0f6";
+@fa-var-file-video-o: "\f1c8";
+@fa-var-file-word-o: "\f1c2";
+@fa-var-file-zip-o: "\f1c6";
+@fa-var-files-o: "\f0c5";
+@fa-var-film: "\f008";
+@fa-var-filter: "\f0b0";
+@fa-var-fire: "\f06d";
+@fa-var-fire-extinguisher: "\f134";
+@fa-var-flag: "\f024";
+@fa-var-flag-checkered: "\f11e";
+@fa-var-flag-o: "\f11d";
+@fa-var-flash: "\f0e7";
+@fa-var-flask: "\f0c3";
+@fa-var-flickr: "\f16e";
+@fa-var-floppy-o: "\f0c7";
+@fa-var-folder: "\f07b";
+@fa-var-folder-o: "\f114";
+@fa-var-folder-open: "\f07c";
+@fa-var-folder-open-o: "\f115";
+@fa-var-font: "\f031";
+@fa-var-forward: "\f04e";
+@fa-var-foursquare: "\f180";
+@fa-var-frown-o: "\f119";
+@fa-var-gamepad: "\f11b";
+@fa-var-gavel: "\f0e3";
+@fa-var-gbp: "\f154";
+@fa-var-ge: "\f1d1";
+@fa-var-gear: "\f013";
+@fa-var-gears: "\f085";
+@fa-var-gift: "\f06b";
+@fa-var-git: "\f1d3";
+@fa-var-git-square: "\f1d2";
+@fa-var-github: "\f09b";
+@fa-var-github-alt: "\f113";
+@fa-var-github-square: "\f092";
+@fa-var-gittip: "\f184";
+@fa-var-glass: "\f000";
+@fa-var-globe: "\f0ac";
+@fa-var-google: "\f1a0";
+@fa-var-google-plus: "\f0d5";
+@fa-var-google-plus-square: "\f0d4";
+@fa-var-graduation-cap: "\f19d";
+@fa-var-group: "\f0c0";
+@fa-var-h-square: "\f0fd";
+@fa-var-hacker-news: "\f1d4";
+@fa-var-hand-o-down: "\f0a7";
+@fa-var-hand-o-left: "\f0a5";
+@fa-var-hand-o-right: "\f0a4";
+@fa-var-hand-o-up: "\f0a6";
+@fa-var-hdd-o: "\f0a0";
+@fa-var-header: "\f1dc";
+@fa-var-headphones: "\f025";
+@fa-var-heart: "\f004";
+@fa-var-heart-o: "\f08a";
+@fa-var-history: "\f1da";
+@fa-var-home: "\f015";
+@fa-var-hospital-o: "\f0f8";
+@fa-var-html5: "\f13b";
+@fa-var-image: "\f03e";
+@fa-var-inbox: "\f01c";
+@fa-var-indent: "\f03c";
+@fa-var-info: "\f129";
+@fa-var-info-circle: "\f05a";
+@fa-var-inr: "\f156";
+@fa-var-instagram: "\f16d";
+@fa-var-institution: "\f19c";
+@fa-var-italic: "\f033";
+@fa-var-joomla: "\f1aa";
+@fa-var-jpy: "\f157";
+@fa-var-jsfiddle: "\f1cc";
+@fa-var-key: "\f084";
+@fa-var-keyboard-o: "\f11c";
+@fa-var-krw: "\f159";
+@fa-var-language: "\f1ab";
+@fa-var-laptop: "\f109";
+@fa-var-leaf: "\f06c";
+@fa-var-legal: "\f0e3";
+@fa-var-lemon-o: "\f094";
+@fa-var-level-down: "\f149";
+@fa-var-level-up: "\f148";
+@fa-var-life-bouy: "\f1cd";
+@fa-var-life-ring: "\f1cd";
+@fa-var-life-saver: "\f1cd";
+@fa-var-lightbulb-o: "\f0eb";
+@fa-var-link: "\f0c1";
+@fa-var-linkedin: "\f0e1";
+@fa-var-linkedin-square: "\f08c";
+@fa-var-linux: "\f17c";
+@fa-var-list: "\f03a";
+@fa-var-list-alt: "\f022";
+@fa-var-list-ol: "\f0cb";
+@fa-var-list-ul: "\f0ca";
+@fa-var-location-arrow: "\f124";
+@fa-var-lock: "\f023";
+@fa-var-long-arrow-down: "\f175";
+@fa-var-long-arrow-left: "\f177";
+@fa-var-long-arrow-right: "\f178";
+@fa-var-long-arrow-up: "\f176";
+@fa-var-magic: "\f0d0";
+@fa-var-magnet: "\f076";
+@fa-var-mail-forward: "\f064";
+@fa-var-mail-reply: "\f112";
+@fa-var-mail-reply-all: "\f122";
+@fa-var-male: "\f183";
+@fa-var-map-marker: "\f041";
+@fa-var-maxcdn: "\f136";
+@fa-var-medkit: "\f0fa";
+@fa-var-meh-o: "\f11a";
+@fa-var-microphone: "\f130";
+@fa-var-microphone-slash: "\f131";
+@fa-var-minus: "\f068";
+@fa-var-minus-circle: "\f056";
+@fa-var-minus-square: "\f146";
+@fa-var-minus-square-o: "\f147";
+@fa-var-mobile: "\f10b";
+@fa-var-mobile-phone: "\f10b";
+@fa-var-money: "\f0d6";
+@fa-var-moon-o: "\f186";
+@fa-var-mortar-board: "\f19d";
+@fa-var-music: "\f001";
+@fa-var-navicon: "\f0c9";
+@fa-var-openid: "\f19b";
+@fa-var-outdent: "\f03b";
+@fa-var-pagelines: "\f18c";
+@fa-var-paper-plane: "\f1d8";
+@fa-var-paper-plane-o: "\f1d9";
+@fa-var-paperclip: "\f0c6";
+@fa-var-paragraph: "\f1dd";
+@fa-var-paste: "\f0ea";
+@fa-var-pause: "\f04c";
+@fa-var-paw: "\f1b0";
+@fa-var-pencil: "\f040";
+@fa-var-pencil-square: "\f14b";
+@fa-var-pencil-square-o: "\f044";
+@fa-var-phone: "\f095";
+@fa-var-phone-square: "\f098";
+@fa-var-photo: "\f03e";
+@fa-var-picture-o: "\f03e";
+@fa-var-pied-piper: "\f1a7";
+@fa-var-pied-piper-alt: "\f1a8";
+@fa-var-pied-piper-square: "\f1a7";
+@fa-var-pinterest: "\f0d2";
+@fa-var-pinterest-square: "\f0d3";
+@fa-var-plane: "\f072";
+@fa-var-play: "\f04b";
+@fa-var-play-circle: "\f144";
+@fa-var-play-circle-o: "\f01d";
+@fa-var-plus: "\f067";
+@fa-var-plus-circle: "\f055";
+@fa-var-plus-square: "\f0fe";
+@fa-var-plus-square-o: "\f196";
+@fa-var-power-off: "\f011";
+@fa-var-print: "\f02f";
+@fa-var-puzzle-piece: "\f12e";
+@fa-var-qq: "\f1d6";
+@fa-var-qrcode: "\f029";
+@fa-var-question: "\f128";
+@fa-var-question-circle: "\f059";
+@fa-var-quote-left: "\f10d";
+@fa-var-quote-right: "\f10e";
+@fa-var-ra: "\f1d0";
+@fa-var-random: "\f074";
+@fa-var-rebel: "\f1d0";
+@fa-var-recycle: "\f1b8";
+@fa-var-reddit: "\f1a1";
+@fa-var-reddit-square: "\f1a2";
+@fa-var-refresh: "\f021";
+@fa-var-renren: "\f18b";
+@fa-var-reorder: "\f0c9";
+@fa-var-repeat: "\f01e";
+@fa-var-reply: "\f112";
+@fa-var-reply-all: "\f122";
+@fa-var-retweet: "\f079";
+@fa-var-rmb: "\f157";
+@fa-var-road: "\f018";
+@fa-var-rocket: "\f135";
+@fa-var-rotate-left: "\f0e2";
+@fa-var-rotate-right: "\f01e";
+@fa-var-rouble: "\f158";
+@fa-var-rss: "\f09e";
+@fa-var-rss-square: "\f143";
+@fa-var-rub: "\f158";
+@fa-var-ruble: "\f158";
+@fa-var-rupee: "\f156";
+@fa-var-save: "\f0c7";
+@fa-var-scissors: "\f0c4";
+@fa-var-search: "\f002";
+@fa-var-search-minus: "\f010";
+@fa-var-search-plus: "\f00e";
+@fa-var-send: "\f1d8";
+@fa-var-send-o: "\f1d9";
+@fa-var-share: "\f064";
+@fa-var-share-alt: "\f1e0";
+@fa-var-share-alt-square: "\f1e1";
+@fa-var-share-square: "\f14d";
+@fa-var-share-square-o: "\f045";
+@fa-var-shield: "\f132";
+@fa-var-shopping-cart: "\f07a";
+@fa-var-sign-in: "\f090";
+@fa-var-sign-out: "\f08b";
+@fa-var-signal: "\f012";
+@fa-var-sitemap: "\f0e8";
+@fa-var-skype: "\f17e";
+@fa-var-slack: "\f198";
+@fa-var-sliders: "\f1de";
+@fa-var-smile-o: "\f118";
+@fa-var-sort: "\f0dc";
+@fa-var-sort-alpha-asc: "\f15d";
+@fa-var-sort-alpha-desc: "\f15e";
+@fa-var-sort-amount-asc: "\f160";
+@fa-var-sort-amount-desc: "\f161";
+@fa-var-sort-asc: "\f0de";
+@fa-var-sort-desc: "\f0dd";
+@fa-var-sort-down: "\f0dd";
+@fa-var-sort-numeric-asc: "\f162";
+@fa-var-sort-numeric-desc: "\f163";
+@fa-var-sort-up: "\f0de";
+@fa-var-soundcloud: "\f1be";
+@fa-var-space-shuttle: "\f197";
+@fa-var-spinner: "\f110";
+@fa-var-spoon: "\f1b1";
+@fa-var-spotify: "\f1bc";
+@fa-var-square: "\f0c8";
+@fa-var-square-o: "\f096";
+@fa-var-stack-exchange: "\f18d";
+@fa-var-stack-overflow: "\f16c";
+@fa-var-star: "\f005";
+@fa-var-star-half: "\f089";
+@fa-var-star-half-empty: "\f123";
+@fa-var-star-half-full: "\f123";
+@fa-var-star-half-o: "\f123";
+@fa-var-star-o: "\f006";
+@fa-var-steam: "\f1b6";
+@fa-var-steam-square: "\f1b7";
+@fa-var-step-backward: "\f048";
+@fa-var-step-forward: "\f051";
+@fa-var-stethoscope: "\f0f1";
+@fa-var-stop: "\f04d";
+@fa-var-strikethrough: "\f0cc";
+@fa-var-stumbleupon: "\f1a4";
+@fa-var-stumbleupon-circle: "\f1a3";
+@fa-var-subscript: "\f12c";
+@fa-var-suitcase: "\f0f2";
+@fa-var-sun-o: "\f185";
+@fa-var-superscript: "\f12b";
+@fa-var-support: "\f1cd";
+@fa-var-table: "\f0ce";
+@fa-var-tablet: "\f10a";
+@fa-var-tachometer: "\f0e4";
+@fa-var-tag: "\f02b";
+@fa-var-tags: "\f02c";
+@fa-var-tasks: "\f0ae";
+@fa-var-taxi: "\f1ba";
+@fa-var-tencent-weibo: "\f1d5";
+@fa-var-terminal: "\f120";
+@fa-var-text-height: "\f034";
+@fa-var-text-width: "\f035";
+@fa-var-th: "\f00a";
+@fa-var-th-large: "\f009";
+@fa-var-th-list: "\f00b";
+@fa-var-thumb-tack: "\f08d";
+@fa-var-thumbs-down: "\f165";
+@fa-var-thumbs-o-down: "\f088";
+@fa-var-thumbs-o-up: "\f087";
+@fa-var-thumbs-up: "\f164";
+@fa-var-ticket: "\f145";
+@fa-var-times: "\f00d";
+@fa-var-times-circle: "\f057";
+@fa-var-times-circle-o: "\f05c";
+@fa-var-tint: "\f043";
+@fa-var-toggle-down: "\f150";
+@fa-var-toggle-left: "\f191";
+@fa-var-toggle-right: "\f152";
+@fa-var-toggle-up: "\f151";
+@fa-var-trash-o: "\f014";
+@fa-var-tree: "\f1bb";
+@fa-var-trello: "\f181";
+@fa-var-trophy: "\f091";
+@fa-var-truck: "\f0d1";
+@fa-var-try: "\f195";
+@fa-var-tumblr: "\f173";
+@fa-var-tumblr-square: "\f174";
+@fa-var-turkish-lira: "\f195";
+@fa-var-twitter: "\f099";
+@fa-var-twitter-square: "\f081";
+@fa-var-umbrella: "\f0e9";
+@fa-var-underline: "\f0cd";
+@fa-var-undo: "\f0e2";
+@fa-var-university: "\f19c";
+@fa-var-unlink: "\f127";
+@fa-var-unlock: "\f09c";
+@fa-var-unlock-alt: "\f13e";
+@fa-var-unsorted: "\f0dc";
+@fa-var-upload: "\f093";
+@fa-var-usd: "\f155";
+@fa-var-user: "\f007";
+@fa-var-user-md: "\f0f0";
+@fa-var-users: "\f0c0";
+@fa-var-video-camera: "\f03d";
+@fa-var-vimeo-square: "\f194";
+@fa-var-vine: "\f1ca";
+@fa-var-vk: "\f189";
+@fa-var-volume-down: "\f027";
+@fa-var-volume-off: "\f026";
+@fa-var-volume-up: "\f028";
+@fa-var-warning: "\f071";
+@fa-var-wechat: "\f1d7";
+@fa-var-weibo: "\f18a";
+@fa-var-weixin: "\f1d7";
+@fa-var-wheelchair: "\f193";
+@fa-var-windows: "\f17a";
+@fa-var-won: "\f159";
+@fa-var-wordpress: "\f19a";
+@fa-var-wrench: "\f0ad";
+@fa-var-xing: "\f168";
+@fa-var-xing-square: "\f169";
+@fa-var-yahoo: "\f19e";
+@fa-var-yen: "\f157";
+@fa-var-youtube: "\f167";
+@fa-var-youtube-play: "\f16a";
+@fa-var-youtube-square: "\f166";
+
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_bordered-pulled.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_bordered-pulled.scss
new file mode 100644 (file)
index 0000000..9d3fdf3
--- /dev/null
@@ -0,0 +1,16 @@
+// Bordered & Pulled
+// -------------------------
+
+.#{$fa-css-prefix}-border {
+  padding: .2em .25em .15em;
+  border: solid .08em $fa-border-color;
+  border-radius: .1em;
+}
+
+.pull-right { float: right; }
+.pull-left { float: left; }
+
+.#{$fa-css-prefix} {
+  &.pull-left { margin-right: .3em; }
+  &.pull-right { margin-left: .3em; }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_core.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_core.scss
new file mode 100644 (file)
index 0000000..861ccd9
--- /dev/null
@@ -0,0 +1,12 @@
+// Base Class Definition
+// -------------------------
+
+.#{$fa-css-prefix} {
+  display: inline-block;
+  font-family: FontAwesome;
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_fixed-width.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_fixed-width.scss
new file mode 100644 (file)
index 0000000..b221c98
--- /dev/null
@@ -0,0 +1,6 @@
+// Fixed Width Icons
+// -------------------------
+.#{$fa-css-prefix}-fw {
+  width: (18em / 14);
+  text-align: center;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_icons.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_icons.scss
new file mode 100644 (file)
index 0000000..efb4435
--- /dev/null
@@ -0,0 +1,506 @@
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+   readers do not read off random characters that represent icons */
+
+.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }
+.#{$fa-css-prefix}-music:before { content: $fa-var-music; }
+.#{$fa-css-prefix}-search:before { content: $fa-var-search; }
+.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }
+.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }
+.#{$fa-css-prefix}-star:before { content: $fa-var-star; }
+.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }
+.#{$fa-css-prefix}-user:before { content: $fa-var-user; }
+.#{$fa-css-prefix}-film:before { content: $fa-var-film; }
+.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }
+.#{$fa-css-prefix}-th:before { content: $fa-var-th; }
+.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }
+.#{$fa-css-prefix}-check:before { content: $fa-var-check; }
+.#{$fa-css-prefix}-times:before { content: $fa-var-times; }
+.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }
+.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }
+.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }
+.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }
+.#{$fa-css-prefix}-gear:before,
+.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }
+.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }
+.#{$fa-css-prefix}-home:before { content: $fa-var-home; }
+.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }
+.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }
+.#{$fa-css-prefix}-road:before { content: $fa-var-road; }
+.#{$fa-css-prefix}-download:before { content: $fa-var-download; }
+.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }
+.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }
+.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }
+.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }
+.#{$fa-css-prefix}-rotate-right:before,
+.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }
+.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }
+.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }
+.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }
+.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }
+.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }
+.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }
+.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }
+.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }
+.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }
+.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }
+.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }
+.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }
+.#{$fa-css-prefix}-book:before { content: $fa-var-book; }
+.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }
+.#{$fa-css-prefix}-print:before { content: $fa-var-print; }
+.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }
+.#{$fa-css-prefix}-font:before { content: $fa-var-font; }
+.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }
+.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }
+.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }
+.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }
+.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }
+.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }
+.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }
+.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }
+.#{$fa-css-prefix}-list:before { content: $fa-var-list; }
+.#{$fa-css-prefix}-dedent:before,
+.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }
+.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }
+.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }
+.#{$fa-css-prefix}-photo:before,
+.#{$fa-css-prefix}-image:before,
+.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }
+.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }
+.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }
+.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }
+.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }
+.#{$fa-css-prefix}-edit:before,
+.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }
+.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }
+.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }
+.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }
+.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }
+.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }
+.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }
+.#{$fa-css-prefix}-play:before { content: $fa-var-play; }
+.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }
+.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }
+.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }
+.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }
+.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }
+.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }
+.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }
+.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }
+.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }
+.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }
+.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }
+.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }
+.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }
+.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }
+.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }
+.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }
+.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }
+.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }
+.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }
+.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }
+.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }
+.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }
+.#{$fa-css-prefix}-mail-forward:before,
+.#{$fa-css-prefix}-share:before { content: $fa-var-share; }
+.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }
+.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }
+.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }
+.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }
+.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }
+.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }
+.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }
+.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }
+.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }
+.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }
+.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }
+.#{$fa-css-prefix}-warning:before,
+.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }
+.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }
+.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }
+.#{$fa-css-prefix}-random:before { content: $fa-var-random; }
+.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }
+.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }
+.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }
+.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }
+.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }
+.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }
+.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }
+.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }
+.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }
+.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }
+.#{$fa-css-prefix}-bar-chart-o:before { content: $fa-var-bar-chart-o; }
+.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }
+.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }
+.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }
+.#{$fa-css-prefix}-key:before { content: $fa-var-key; }
+.#{$fa-css-prefix}-gears:before,
+.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }
+.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }
+.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }
+.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }
+.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }
+.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }
+.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }
+.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }
+.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }
+.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }
+.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }
+.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }
+.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }
+.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }
+.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }
+.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }
+.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }
+.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }
+.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }
+.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }
+.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }
+.#{$fa-css-prefix}-github:before { content: $fa-var-github; }
+.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }
+.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }
+.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }
+.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }
+.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }
+.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }
+.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }
+.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }
+.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }
+.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }
+.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }
+.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }
+.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }
+.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }
+.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }
+.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }
+.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }
+.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }
+.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }
+.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }
+.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }
+.#{$fa-css-prefix}-group:before,
+.#{$fa-css-prefix}-users:before { content: $fa-var-users; }
+.#{$fa-css-prefix}-chain:before,
+.#{$fa-css-prefix}-link:before { content: $fa-var-link; }
+.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }
+.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }
+.#{$fa-css-prefix}-cut:before,
+.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }
+.#{$fa-css-prefix}-copy:before,
+.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }
+.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }
+.#{$fa-css-prefix}-save:before,
+.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }
+.#{$fa-css-prefix}-square:before { content: $fa-var-square; }
+.#{$fa-css-prefix}-navicon:before,
+.#{$fa-css-prefix}-reorder:before,
+.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }
+.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }
+.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }
+.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }
+.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }
+.#{$fa-css-prefix}-table:before { content: $fa-var-table; }
+.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }
+.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }
+.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }
+.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }
+.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }
+.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }
+.#{$fa-css-prefix}-money:before { content: $fa-var-money; }
+.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }
+.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }
+.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }
+.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }
+.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }
+.#{$fa-css-prefix}-unsorted:before,
+.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }
+.#{$fa-css-prefix}-sort-down:before,
+.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }
+.#{$fa-css-prefix}-sort-up:before,
+.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
+.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }
+.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }
+.#{$fa-css-prefix}-rotate-left:before,
+.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }
+.#{$fa-css-prefix}-legal:before,
+.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }
+.#{$fa-css-prefix}-dashboard:before,
+.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }
+.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }
+.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }
+.#{$fa-css-prefix}-flash:before,
+.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }
+.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }
+.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }
+.#{$fa-css-prefix}-paste:before,
+.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }
+.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }
+.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }
+.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }
+.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }
+.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }
+.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }
+.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }
+.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }
+.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }
+.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }
+.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }
+.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }
+.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }
+.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }
+.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }
+.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }
+.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }
+.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }
+.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }
+.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }
+.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }
+.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }
+.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }
+.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }
+.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }
+.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }
+.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }
+.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }
+.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }
+.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }
+.#{$fa-css-prefix}-mobile-phone:before,
+.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }
+.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }
+.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }
+.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }
+.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }
+.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }
+.#{$fa-css-prefix}-mail-reply:before,
+.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }
+.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }
+.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }
+.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }
+.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }
+.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }
+.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }
+.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }
+.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }
+.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }
+.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }
+.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }
+.#{$fa-css-prefix}-code:before { content: $fa-var-code; }
+.#{$fa-css-prefix}-mail-reply-all:before,
+.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }
+.#{$fa-css-prefix}-star-half-empty:before,
+.#{$fa-css-prefix}-star-half-full:before,
+.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }
+.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }
+.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }
+.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }
+.#{$fa-css-prefix}-unlink:before,
+.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }
+.#{$fa-css-prefix}-question:before { content: $fa-var-question; }
+.#{$fa-css-prefix}-info:before { content: $fa-var-info; }
+.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }
+.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }
+.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }
+.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }
+.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }
+.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }
+.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }
+.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }
+.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }
+.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }
+.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }
+.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }
+.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }
+.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }
+.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }
+.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }
+.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }
+.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }
+.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }
+.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }
+.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }
+.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }
+.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }
+.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }
+.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }
+.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }
+.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }
+.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }
+.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }
+.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }
+.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }
+.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }
+.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }
+.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }
+.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }
+.#{$fa-css-prefix}-toggle-down:before,
+.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }
+.#{$fa-css-prefix}-toggle-up:before,
+.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }
+.#{$fa-css-prefix}-toggle-right:before,
+.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }
+.#{$fa-css-prefix}-euro:before,
+.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }
+.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }
+.#{$fa-css-prefix}-dollar:before,
+.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }
+.#{$fa-css-prefix}-rupee:before,
+.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }
+.#{$fa-css-prefix}-cny:before,
+.#{$fa-css-prefix}-rmb:before,
+.#{$fa-css-prefix}-yen:before,
+.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }
+.#{$fa-css-prefix}-ruble:before,
+.#{$fa-css-prefix}-rouble:before,
+.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }
+.#{$fa-css-prefix}-won:before,
+.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }
+.#{$fa-css-prefix}-bitcoin:before,
+.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }
+.#{$fa-css-prefix}-file:before { content: $fa-var-file; }
+.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }
+.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }
+.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }
+.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }
+.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }
+.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }
+.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }
+.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }
+.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }
+.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }
+.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }
+.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }
+.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }
+.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }
+.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }
+.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }
+.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }
+.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }
+.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }
+.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }
+.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }
+.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }
+.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }
+.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }
+.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }
+.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }
+.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }
+.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }
+.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }
+.#{$fa-css-prefix}-android:before { content: $fa-var-android; }
+.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }
+.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }
+.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }
+.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }
+.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }
+.#{$fa-css-prefix}-female:before { content: $fa-var-female; }
+.#{$fa-css-prefix}-male:before { content: $fa-var-male; }
+.#{$fa-css-prefix}-gittip:before { content: $fa-var-gittip; }
+.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }
+.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }
+.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }
+.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }
+.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }
+.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }
+.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }
+.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }
+.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }
+.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }
+.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }
+.#{$fa-css-prefix}-toggle-left:before,
+.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }
+.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }
+.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }
+.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }
+.#{$fa-css-prefix}-turkish-lira:before,
+.#{$fa-css-prefix}-try:before { content: $fa-var-try; }
+.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }
+.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }
+.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }
+.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }
+.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }
+.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }
+.#{$fa-css-prefix}-institution:before,
+.#{$fa-css-prefix}-bank:before,
+.#{$fa-css-prefix}-university:before { content: $fa-var-university; }
+.#{$fa-css-prefix}-mortar-board:before,
+.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }
+.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }
+.#{$fa-css-prefix}-google:before { content: $fa-var-google; }
+.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }
+.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }
+.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }
+.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
+.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
+.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
+.#{$fa-css-prefix}-pied-piper-square:before,
+.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
+.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
+.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
+.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }
+.#{$fa-css-prefix}-language:before { content: $fa-var-language; }
+.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }
+.#{$fa-css-prefix}-building:before { content: $fa-var-building; }
+.#{$fa-css-prefix}-child:before { content: $fa-var-child; }
+.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }
+.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }
+.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }
+.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }
+.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }
+.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }
+.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }
+.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }
+.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }
+.#{$fa-css-prefix}-automobile:before,
+.#{$fa-css-prefix}-car:before { content: $fa-var-car; }
+.#{$fa-css-prefix}-cab:before,
+.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }
+.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }
+.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }
+.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }
+.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }
+.#{$fa-css-prefix}-database:before { content: $fa-var-database; }
+.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }
+.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }
+.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }
+.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }
+.#{$fa-css-prefix}-file-photo-o:before,
+.#{$fa-css-prefix}-file-picture-o:before,
+.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }
+.#{$fa-css-prefix}-file-zip-o:before,
+.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }
+.#{$fa-css-prefix}-file-sound-o:before,
+.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }
+.#{$fa-css-prefix}-file-movie-o:before,
+.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }
+.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }
+.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }
+.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
+.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
+.#{$fa-css-prefix}-life-bouy:before,
+.#{$fa-css-prefix}-life-saver:before,
+.#{$fa-css-prefix}-support:before,
+.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
+.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }
+.#{$fa-css-prefix}-ra:before,
+.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }
+.#{$fa-css-prefix}-ge:before,
+.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
+.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
+.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
+.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
+.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
+.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
+.#{$fa-css-prefix}-wechat:before,
+.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }
+.#{$fa-css-prefix}-send:before,
+.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }
+.#{$fa-css-prefix}-send-o:before,
+.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }
+.#{$fa-css-prefix}-history:before { content: $fa-var-history; }
+.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }
+.#{$fa-css-prefix}-header:before { content: $fa-var-header; }
+.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }
+.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }
+.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
+.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
+.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_larger.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_larger.scss
new file mode 100644 (file)
index 0000000..41e9a81
--- /dev/null
@@ -0,0 +1,13 @@
+// Icon Sizes
+// -------------------------
+
+/* makes the font 33% larger relative to the icon container */
+.#{$fa-css-prefix}-lg {
+  font-size: (4em / 3);
+  line-height: (3em / 4);
+  vertical-align: -15%;
+}
+.#{$fa-css-prefix}-2x { font-size: 2em; }
+.#{$fa-css-prefix}-3x { font-size: 3em; }
+.#{$fa-css-prefix}-4x { font-size: 4em; }
+.#{$fa-css-prefix}-5x { font-size: 5em; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_list.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_list.scss
new file mode 100644 (file)
index 0000000..7d1e4d5
--- /dev/null
@@ -0,0 +1,19 @@
+// List Icons
+// -------------------------
+
+.#{$fa-css-prefix}-ul {
+  padding-left: 0;
+  margin-left: $fa-li-width;
+  list-style-type: none;
+  > li { position: relative; }
+}
+.#{$fa-css-prefix}-li {
+  position: absolute;
+  left: -$fa-li-width;
+  width: $fa-li-width;
+  top: (2em / 14);
+  text-align: center;
+  &.#{$fa-css-prefix}-lg {
+    left: -$fa-li-width + (4em / 14);
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_mixins.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_mixins.scss
new file mode 100644 (file)
index 0000000..3354e69
--- /dev/null
@@ -0,0 +1,20 @@
+// Mixins
+// --------------------------
+
+@mixin fa-icon-rotate($degrees, $rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+  -webkit-transform: rotate($degrees);
+     -moz-transform: rotate($degrees);
+      -ms-transform: rotate($degrees);
+       -o-transform: rotate($degrees);
+          transform: rotate($degrees);
+}
+
+@mixin fa-icon-flip($horiz, $vert, $rotation) {
+  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
+  -webkit-transform: scale($horiz, $vert);
+     -moz-transform: scale($horiz, $vert);
+      -ms-transform: scale($horiz, $vert);
+       -o-transform: scale($horiz, $vert);
+          transform: scale($horiz, $vert);
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_path.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_path.scss
new file mode 100644 (file)
index 0000000..fd21c35
--- /dev/null
@@ -0,0 +1,14 @@
+/* FONT PATH
+ * -------------------------- */
+
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
+  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
+    url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
+    url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
+    url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
+  //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
+  font-weight: normal;
+  font-style: normal;
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_rotated-flipped.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_rotated-flipped.scss
new file mode 100644 (file)
index 0000000..343fa55
--- /dev/null
@@ -0,0 +1,9 @@
+// Rotated & Flipped Icons
+// -------------------------
+
+.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }
+.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
+.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
+
+.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
+.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_spinning.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_spinning.scss
new file mode 100644 (file)
index 0000000..c378744
--- /dev/null
@@ -0,0 +1,32 @@
+// Spinning Icons
+// --------------------------
+
+.#{$fa-css-prefix}-spin {
+  -webkit-animation: spin 2s infinite linear;
+  -moz-animation: spin 2s infinite linear;
+  -o-animation: spin 2s infinite linear;
+  animation: spin 2s infinite linear;
+}
+
+@-moz-keyframes spin {
+  0% { -moz-transform: rotate(0deg); }
+  100% { -moz-transform: rotate(359deg); }
+}
+@-webkit-keyframes spin {
+  0% { -webkit-transform: rotate(0deg); }
+  100% { -webkit-transform: rotate(359deg); }
+}
+@-o-keyframes spin {
+  0% { -o-transform: rotate(0deg); }
+  100% { -o-transform: rotate(359deg); }
+}
+@keyframes spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(359deg);
+    transform: rotate(359deg);
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_stacked.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_stacked.scss
new file mode 100644 (file)
index 0000000..aef7403
--- /dev/null
@@ -0,0 +1,20 @@
+// Stacked Icons
+// -------------------------
+
+.#{$fa-css-prefix}-stack {
+  position: relative;
+  display: inline-block;
+  width: 2em;
+  height: 2em;
+  line-height: 2em;
+  vertical-align: middle;
+}
+.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  text-align: center;
+}
+.#{$fa-css-prefix}-stack-1x { line-height: inherit; }
+.#{$fa-css-prefix}-stack-2x { font-size: 2em; }
+.#{$fa-css-prefix}-inverse { color: $fa-inverse; }
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_variables.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/_variables.scss
new file mode 100644 (file)
index 0000000..ac2b505
--- /dev/null
@@ -0,0 +1,515 @@
+// Variables
+// --------------------------
+
+$fa-font-path:        "../fonts" !default;
+//$fa-font-path:        "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly
+$fa-css-prefix:       fa !default;
+$fa-version:          "4.1.0" !default;
+$fa-border-color:     #eee !default;
+$fa-inverse:          #fff !default;
+$fa-li-width:         (30em / 14) !default;
+
+$fa-var-adjust: "\f042";
+$fa-var-adn: "\f170";
+$fa-var-align-center: "\f037";
+$fa-var-align-justify: "\f039";
+$fa-var-align-left: "\f036";
+$fa-var-align-right: "\f038";
+$fa-var-ambulance: "\f0f9";
+$fa-var-anchor: "\f13d";
+$fa-var-android: "\f17b";
+$fa-var-angle-double-down: "\f103";
+$fa-var-angle-double-left: "\f100";
+$fa-var-angle-double-right: "\f101";
+$fa-var-angle-double-up: "\f102";
+$fa-var-angle-down: "\f107";
+$fa-var-angle-left: "\f104";
+$fa-var-angle-right: "\f105";
+$fa-var-angle-up: "\f106";
+$fa-var-apple: "\f179";
+$fa-var-archive: "\f187";
+$fa-var-arrow-circle-down: "\f0ab";
+$fa-var-arrow-circle-left: "\f0a8";
+$fa-var-arrow-circle-o-down: "\f01a";
+$fa-var-arrow-circle-o-left: "\f190";
+$fa-var-arrow-circle-o-right: "\f18e";
+$fa-var-arrow-circle-o-up: "\f01b";
+$fa-var-arrow-circle-right: "\f0a9";
+$fa-var-arrow-circle-up: "\f0aa";
+$fa-var-arrow-down: "\f063";
+$fa-var-arrow-left: "\f060";
+$fa-var-arrow-right: "\f061";
+$fa-var-arrow-up: "\f062";
+$fa-var-arrows: "\f047";
+$fa-var-arrows-alt: "\f0b2";
+$fa-var-arrows-h: "\f07e";
+$fa-var-arrows-v: "\f07d";
+$fa-var-asterisk: "\f069";
+$fa-var-automobile: "\f1b9";
+$fa-var-backward: "\f04a";
+$fa-var-ban: "\f05e";
+$fa-var-bank: "\f19c";
+$fa-var-bar-chart-o: "\f080";
+$fa-var-barcode: "\f02a";
+$fa-var-bars: "\f0c9";
+$fa-var-beer: "\f0fc";
+$fa-var-behance: "\f1b4";
+$fa-var-behance-square: "\f1b5";
+$fa-var-bell: "\f0f3";
+$fa-var-bell-o: "\f0a2";
+$fa-var-bitbucket: "\f171";
+$fa-var-bitbucket-square: "\f172";
+$fa-var-bitcoin: "\f15a";
+$fa-var-bold: "\f032";
+$fa-var-bolt: "\f0e7";
+$fa-var-bomb: "\f1e2";
+$fa-var-book: "\f02d";
+$fa-var-bookmark: "\f02e";
+$fa-var-bookmark-o: "\f097";
+$fa-var-briefcase: "\f0b1";
+$fa-var-btc: "\f15a";
+$fa-var-bug: "\f188";
+$fa-var-building: "\f1ad";
+$fa-var-building-o: "\f0f7";
+$fa-var-bullhorn: "\f0a1";
+$fa-var-bullseye: "\f140";
+$fa-var-cab: "\f1ba";
+$fa-var-calendar: "\f073";
+$fa-var-calendar-o: "\f133";
+$fa-var-camera: "\f030";
+$fa-var-camera-retro: "\f083";
+$fa-var-car: "\f1b9";
+$fa-var-caret-down: "\f0d7";
+$fa-var-caret-left: "\f0d9";
+$fa-var-caret-right: "\f0da";
+$fa-var-caret-square-o-down: "\f150";
+$fa-var-caret-square-o-left: "\f191";
+$fa-var-caret-square-o-right: "\f152";
+$fa-var-caret-square-o-up: "\f151";
+$fa-var-caret-up: "\f0d8";
+$fa-var-certificate: "\f0a3";
+$fa-var-chain: "\f0c1";
+$fa-var-chain-broken: "\f127";
+$fa-var-check: "\f00c";
+$fa-var-check-circle: "\f058";
+$fa-var-check-circle-o: "\f05d";
+$fa-var-check-square: "\f14a";
+$fa-var-check-square-o: "\f046";
+$fa-var-chevron-circle-down: "\f13a";
+$fa-var-chevron-circle-left: "\f137";
+$fa-var-chevron-circle-right: "\f138";
+$fa-var-chevron-circle-up: "\f139";
+$fa-var-chevron-down: "\f078";
+$fa-var-chevron-left: "\f053";
+$fa-var-chevron-right: "\f054";
+$fa-var-chevron-up: "\f077";
+$fa-var-child: "\f1ae";
+$fa-var-circle: "\f111";
+$fa-var-circle-o: "\f10c";
+$fa-var-circle-o-notch: "\f1ce";
+$fa-var-circle-thin: "\f1db";
+$fa-var-clipboard: "\f0ea";
+$fa-var-clock-o: "\f017";
+$fa-var-cloud: "\f0c2";
+$fa-var-cloud-download: "\f0ed";
+$fa-var-cloud-upload: "\f0ee";
+$fa-var-cny: "\f157";
+$fa-var-code: "\f121";
+$fa-var-code-fork: "\f126";
+$fa-var-codepen: "\f1cb";
+$fa-var-coffee: "\f0f4";
+$fa-var-cog: "\f013";
+$fa-var-cogs: "\f085";
+$fa-var-columns: "\f0db";
+$fa-var-comment: "\f075";
+$fa-var-comment-o: "\f0e5";
+$fa-var-comments: "\f086";
+$fa-var-comments-o: "\f0e6";
+$fa-var-compass: "\f14e";
+$fa-var-compress: "\f066";
+$fa-var-copy: "\f0c5";
+$fa-var-credit-card: "\f09d";
+$fa-var-crop: "\f125";
+$fa-var-crosshairs: "\f05b";
+$fa-var-css3: "\f13c";
+$fa-var-cube: "\f1b2";
+$fa-var-cubes: "\f1b3";
+$fa-var-cut: "\f0c4";
+$fa-var-cutlery: "\f0f5";
+$fa-var-dashboard: "\f0e4";
+$fa-var-database: "\f1c0";
+$fa-var-dedent: "\f03b";
+$fa-var-delicious: "\f1a5";
+$fa-var-desktop: "\f108";
+$fa-var-deviantart: "\f1bd";
+$fa-var-digg: "\f1a6";
+$fa-var-dollar: "\f155";
+$fa-var-dot-circle-o: "\f192";
+$fa-var-download: "\f019";
+$fa-var-dribbble: "\f17d";
+$fa-var-dropbox: "\f16b";
+$fa-var-drupal: "\f1a9";
+$fa-var-edit: "\f044";
+$fa-var-eject: "\f052";
+$fa-var-ellipsis-h: "\f141";
+$fa-var-ellipsis-v: "\f142";
+$fa-var-empire: "\f1d1";
+$fa-var-envelope: "\f0e0";
+$fa-var-envelope-o: "\f003";
+$fa-var-envelope-square: "\f199";
+$fa-var-eraser: "\f12d";
+$fa-var-eur: "\f153";
+$fa-var-euro: "\f153";
+$fa-var-exchange: "\f0ec";
+$fa-var-exclamation: "\f12a";
+$fa-var-exclamation-circle: "\f06a";
+$fa-var-exclamation-triangle: "\f071";
+$fa-var-expand: "\f065";
+$fa-var-external-link: "\f08e";
+$fa-var-external-link-square: "\f14c";
+$fa-var-eye: "\f06e";
+$fa-var-eye-slash: "\f070";
+$fa-var-facebook: "\f09a";
+$fa-var-facebook-square: "\f082";
+$fa-var-fast-backward: "\f049";
+$fa-var-fast-forward: "\f050";
+$fa-var-fax: "\f1ac";
+$fa-var-female: "\f182";
+$fa-var-fighter-jet: "\f0fb";
+$fa-var-file: "\f15b";
+$fa-var-file-archive-o: "\f1c6";
+$fa-var-file-audio-o: "\f1c7";
+$fa-var-file-code-o: "\f1c9";
+$fa-var-file-excel-o: "\f1c3";
+$fa-var-file-image-o: "\f1c5";
+$fa-var-file-movie-o: "\f1c8";
+$fa-var-file-o: "\f016";
+$fa-var-file-pdf-o: "\f1c1";
+$fa-var-file-photo-o: "\f1c5";
+$fa-var-file-picture-o: "\f1c5";
+$fa-var-file-powerpoint-o: "\f1c4";
+$fa-var-file-sound-o: "\f1c7";
+$fa-var-file-text: "\f15c";
+$fa-var-file-text-o: "\f0f6";
+$fa-var-file-video-o: "\f1c8";
+$fa-var-file-word-o: "\f1c2";
+$fa-var-file-zip-o: "\f1c6";
+$fa-var-files-o: "\f0c5";
+$fa-var-film: "\f008";
+$fa-var-filter: "\f0b0";
+$fa-var-fire: "\f06d";
+$fa-var-fire-extinguisher: "\f134";
+$fa-var-flag: "\f024";
+$fa-var-flag-checkered: "\f11e";
+$fa-var-flag-o: "\f11d";
+$fa-var-flash: "\f0e7";
+$fa-var-flask: "\f0c3";
+$fa-var-flickr: "\f16e";
+$fa-var-floppy-o: "\f0c7";
+$fa-var-folder: "\f07b";
+$fa-var-folder-o: "\f114";
+$fa-var-folder-open: "\f07c";
+$fa-var-folder-open-o: "\f115";
+$fa-var-font: "\f031";
+$fa-var-forward: "\f04e";
+$fa-var-foursquare: "\f180";
+$fa-var-frown-o: "\f119";
+$fa-var-gamepad: "\f11b";
+$fa-var-gavel: "\f0e3";
+$fa-var-gbp: "\f154";
+$fa-var-ge: "\f1d1";
+$fa-var-gear: "\f013";
+$fa-var-gears: "\f085";
+$fa-var-gift: "\f06b";
+$fa-var-git: "\f1d3";
+$fa-var-git-square: "\f1d2";
+$fa-var-github: "\f09b";
+$fa-var-github-alt: "\f113";
+$fa-var-github-square: "\f092";
+$fa-var-gittip: "\f184";
+$fa-var-glass: "\f000";
+$fa-var-globe: "\f0ac";
+$fa-var-google: "\f1a0";
+$fa-var-google-plus: "\f0d5";
+$fa-var-google-plus-square: "\f0d4";
+$fa-var-graduation-cap: "\f19d";
+$fa-var-group: "\f0c0";
+$fa-var-h-square: "\f0fd";
+$fa-var-hacker-news: "\f1d4";
+$fa-var-hand-o-down: "\f0a7";
+$fa-var-hand-o-left: "\f0a5";
+$fa-var-hand-o-right: "\f0a4";
+$fa-var-hand-o-up: "\f0a6";
+$fa-var-hdd-o: "\f0a0";
+$fa-var-header: "\f1dc";
+$fa-var-headphones: "\f025";
+$fa-var-heart: "\f004";
+$fa-var-heart-o: "\f08a";
+$fa-var-history: "\f1da";
+$fa-var-home: "\f015";
+$fa-var-hospital-o: "\f0f8";
+$fa-var-html5: "\f13b";
+$fa-var-image: "\f03e";
+$fa-var-inbox: "\f01c";
+$fa-var-indent: "\f03c";
+$fa-var-info: "\f129";
+$fa-var-info-circle: "\f05a";
+$fa-var-inr: "\f156";
+$fa-var-instagram: "\f16d";
+$fa-var-institution: "\f19c";
+$fa-var-italic: "\f033";
+$fa-var-joomla: "\f1aa";
+$fa-var-jpy: "\f157";
+$fa-var-jsfiddle: "\f1cc";
+$fa-var-key: "\f084";
+$fa-var-keyboard-o: "\f11c";
+$fa-var-krw: "\f159";
+$fa-var-language: "\f1ab";
+$fa-var-laptop: "\f109";
+$fa-var-leaf: "\f06c";
+$fa-var-legal: "\f0e3";
+$fa-var-lemon-o: "\f094";
+$fa-var-level-down: "\f149";
+$fa-var-level-up: "\f148";
+$fa-var-life-bouy: "\f1cd";
+$fa-var-life-ring: "\f1cd";
+$fa-var-life-saver: "\f1cd";
+$fa-var-lightbulb-o: "\f0eb";
+$fa-var-link: "\f0c1";
+$fa-var-linkedin: "\f0e1";
+$fa-var-linkedin-square: "\f08c";
+$fa-var-linux: "\f17c";
+$fa-var-list: "\f03a";
+$fa-var-list-alt: "\f022";
+$fa-var-list-ol: "\f0cb";
+$fa-var-list-ul: "\f0ca";
+$fa-var-location-arrow: "\f124";
+$fa-var-lock: "\f023";
+$fa-var-long-arrow-down: "\f175";
+$fa-var-long-arrow-left: "\f177";
+$fa-var-long-arrow-right: "\f178";
+$fa-var-long-arrow-up: "\f176";
+$fa-var-magic: "\f0d0";
+$fa-var-magnet: "\f076";
+$fa-var-mail-forward: "\f064";
+$fa-var-mail-reply: "\f112";
+$fa-var-mail-reply-all: "\f122";
+$fa-var-male: "\f183";
+$fa-var-map-marker: "\f041";
+$fa-var-maxcdn: "\f136";
+$fa-var-medkit: "\f0fa";
+$fa-var-meh-o: "\f11a";
+$fa-var-microphone: "\f130";
+$fa-var-microphone-slash: "\f131";
+$fa-var-minus: "\f068";
+$fa-var-minus-circle: "\f056";
+$fa-var-minus-square: "\f146";
+$fa-var-minus-square-o: "\f147";
+$fa-var-mobile: "\f10b";
+$fa-var-mobile-phone: "\f10b";
+$fa-var-money: "\f0d6";
+$fa-var-moon-o: "\f186";
+$fa-var-mortar-board: "\f19d";
+$fa-var-music: "\f001";
+$fa-var-navicon: "\f0c9";
+$fa-var-openid: "\f19b";
+$fa-var-outdent: "\f03b";
+$fa-var-pagelines: "\f18c";
+$fa-var-paper-plane: "\f1d8";
+$fa-var-paper-plane-o: "\f1d9";
+$fa-var-paperclip: "\f0c6";
+$fa-var-paragraph: "\f1dd";
+$fa-var-paste: "\f0ea";
+$fa-var-pause: "\f04c";
+$fa-var-paw: "\f1b0";
+$fa-var-pencil: "\f040";
+$fa-var-pencil-square: "\f14b";
+$fa-var-pencil-square-o: "\f044";
+$fa-var-phone: "\f095";
+$fa-var-phone-square: "\f098";
+$fa-var-photo: "\f03e";
+$fa-var-picture-o: "\f03e";
+$fa-var-pied-piper: "\f1a7";
+$fa-var-pied-piper-alt: "\f1a8";
+$fa-var-pied-piper-square: "\f1a7";
+$fa-var-pinterest: "\f0d2";
+$fa-var-pinterest-square: "\f0d3";
+$fa-var-plane: "\f072";
+$fa-var-play: "\f04b";
+$fa-var-play-circle: "\f144";
+$fa-var-play-circle-o: "\f01d";
+$fa-var-plus: "\f067";
+$fa-var-plus-circle: "\f055";
+$fa-var-plus-square: "\f0fe";
+$fa-var-plus-square-o: "\f196";
+$fa-var-power-off: "\f011";
+$fa-var-print: "\f02f";
+$fa-var-puzzle-piece: "\f12e";
+$fa-var-qq: "\f1d6";
+$fa-var-qrcode: "\f029";
+$fa-var-question: "\f128";
+$fa-var-question-circle: "\f059";
+$fa-var-quote-left: "\f10d";
+$fa-var-quote-right: "\f10e";
+$fa-var-ra: "\f1d0";
+$fa-var-random: "\f074";
+$fa-var-rebel: "\f1d0";
+$fa-var-recycle: "\f1b8";
+$fa-var-reddit: "\f1a1";
+$fa-var-reddit-square: "\f1a2";
+$fa-var-refresh: "\f021";
+$fa-var-renren: "\f18b";
+$fa-var-reorder: "\f0c9";
+$fa-var-repeat: "\f01e";
+$fa-var-reply: "\f112";
+$fa-var-reply-all: "\f122";
+$fa-var-retweet: "\f079";
+$fa-var-rmb: "\f157";
+$fa-var-road: "\f018";
+$fa-var-rocket: "\f135";
+$fa-var-rotate-left: "\f0e2";
+$fa-var-rotate-right: "\f01e";
+$fa-var-rouble: "\f158";
+$fa-var-rss: "\f09e";
+$fa-var-rss-square: "\f143";
+$fa-var-rub: "\f158";
+$fa-var-ruble: "\f158";
+$fa-var-rupee: "\f156";
+$fa-var-save: "\f0c7";
+$fa-var-scissors: "\f0c4";
+$fa-var-search: "\f002";
+$fa-var-search-minus: "\f010";
+$fa-var-search-plus: "\f00e";
+$fa-var-send: "\f1d8";
+$fa-var-send-o: "\f1d9";
+$fa-var-share: "\f064";
+$fa-var-share-alt: "\f1e0";
+$fa-var-share-alt-square: "\f1e1";
+$fa-var-share-square: "\f14d";
+$fa-var-share-square-o: "\f045";
+$fa-var-shield: "\f132";
+$fa-var-shopping-cart: "\f07a";
+$fa-var-sign-in: "\f090";
+$fa-var-sign-out: "\f08b";
+$fa-var-signal: "\f012";
+$fa-var-sitemap: "\f0e8";
+$fa-var-skype: "\f17e";
+$fa-var-slack: "\f198";
+$fa-var-sliders: "\f1de";
+$fa-var-smile-o: "\f118";
+$fa-var-sort: "\f0dc";
+$fa-var-sort-alpha-asc: "\f15d";
+$fa-var-sort-alpha-desc: "\f15e";
+$fa-var-sort-amount-asc: "\f160";
+$fa-var-sort-amount-desc: "\f161";
+$fa-var-sort-asc: "\f0de";
+$fa-var-sort-desc: "\f0dd";
+$fa-var-sort-down: "\f0dd";
+$fa-var-sort-numeric-asc: "\f162";
+$fa-var-sort-numeric-desc: "\f163";
+$fa-var-sort-up: "\f0de";
+$fa-var-soundcloud: "\f1be";
+$fa-var-space-shuttle: "\f197";
+$fa-var-spinner: "\f110";
+$fa-var-spoon: "\f1b1";
+$fa-var-spotify: "\f1bc";
+$fa-var-square: "\f0c8";
+$fa-var-square-o: "\f096";
+$fa-var-stack-exchange: "\f18d";
+$fa-var-stack-overflow: "\f16c";
+$fa-var-star: "\f005";
+$fa-var-star-half: "\f089";
+$fa-var-star-half-empty: "\f123";
+$fa-var-star-half-full: "\f123";
+$fa-var-star-half-o: "\f123";
+$fa-var-star-o: "\f006";
+$fa-var-steam: "\f1b6";
+$fa-var-steam-square: "\f1b7";
+$fa-var-step-backward: "\f048";
+$fa-var-step-forward: "\f051";
+$fa-var-stethoscope: "\f0f1";
+$fa-var-stop: "\f04d";
+$fa-var-strikethrough: "\f0cc";
+$fa-var-stumbleupon: "\f1a4";
+$fa-var-stumbleupon-circle: "\f1a3";
+$fa-var-subscript: "\f12c";
+$fa-var-suitcase: "\f0f2";
+$fa-var-sun-o: "\f185";
+$fa-var-superscript: "\f12b";
+$fa-var-support: "\f1cd";
+$fa-var-table: "\f0ce";
+$fa-var-tablet: "\f10a";
+$fa-var-tachometer: "\f0e4";
+$fa-var-tag: "\f02b";
+$fa-var-tags: "\f02c";
+$fa-var-tasks: "\f0ae";
+$fa-var-taxi: "\f1ba";
+$fa-var-tencent-weibo: "\f1d5";
+$fa-var-terminal: "\f120";
+$fa-var-text-height: "\f034";
+$fa-var-text-width: "\f035";
+$fa-var-th: "\f00a";
+$fa-var-th-large: "\f009";
+$fa-var-th-list: "\f00b";
+$fa-var-thumb-tack: "\f08d";
+$fa-var-thumbs-down: "\f165";
+$fa-var-thumbs-o-down: "\f088";
+$fa-var-thumbs-o-up: "\f087";
+$fa-var-thumbs-up: "\f164";
+$fa-var-ticket: "\f145";
+$fa-var-times: "\f00d";
+$fa-var-times-circle: "\f057";
+$fa-var-times-circle-o: "\f05c";
+$fa-var-tint: "\f043";
+$fa-var-toggle-down: "\f150";
+$fa-var-toggle-left: "\f191";
+$fa-var-toggle-right: "\f152";
+$fa-var-toggle-up: "\f151";
+$fa-var-trash-o: "\f014";
+$fa-var-tree: "\f1bb";
+$fa-var-trello: "\f181";
+$fa-var-trophy: "\f091";
+$fa-var-truck: "\f0d1";
+$fa-var-try: "\f195";
+$fa-var-tumblr: "\f173";
+$fa-var-tumblr-square: "\f174";
+$fa-var-turkish-lira: "\f195";
+$fa-var-twitter: "\f099";
+$fa-var-twitter-square: "\f081";
+$fa-var-umbrella: "\f0e9";
+$fa-var-underline: "\f0cd";
+$fa-var-undo: "\f0e2";
+$fa-var-university: "\f19c";
+$fa-var-unlink: "\f127";
+$fa-var-unlock: "\f09c";
+$fa-var-unlock-alt: "\f13e";
+$fa-var-unsorted: "\f0dc";
+$fa-var-upload: "\f093";
+$fa-var-usd: "\f155";
+$fa-var-user: "\f007";
+$fa-var-user-md: "\f0f0";
+$fa-var-users: "\f0c0";
+$fa-var-video-camera: "\f03d";
+$fa-var-vimeo-square: "\f194";
+$fa-var-vine: "\f1ca";
+$fa-var-vk: "\f189";
+$fa-var-volume-down: "\f027";
+$fa-var-volume-off: "\f026";
+$fa-var-volume-up: "\f028";
+$fa-var-warning: "\f071";
+$fa-var-wechat: "\f1d7";
+$fa-var-weibo: "\f18a";
+$fa-var-weixin: "\f1d7";
+$fa-var-wheelchair: "\f193";
+$fa-var-windows: "\f17a";
+$fa-var-won: "\f159";
+$fa-var-wordpress: "\f19a";
+$fa-var-wrench: "\f0ad";
+$fa-var-xing: "\f168";
+$fa-var-xing-square: "\f169";
+$fa-var-yahoo: "\f19e";
+$fa-var-yen: "\f157";
+$fa-var-youtube: "\f167";
+$fa-var-youtube-play: "\f16a";
+$fa-var-youtube-square: "\f166";
+
diff --git a/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/font-awesome.scss b/src/main/resources/META-INF/resources/designer/fonts/font-awesome-4.1.0/scss/font-awesome.scss
new file mode 100644 (file)
index 0000000..2307dbd
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+ *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+
+@import "variables";
+@import "mixins";
+@import "path";
+@import "core";
+@import "larger";
+@import "fixed-width";
+@import "list";
+@import "bordered-pulled";
+@import "spinning";
+@import "rotated-flipped";
+@import "stacked";
+@import "icons";
diff --git a/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.eot b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.eot
new file mode 100644 (file)
index 0000000..6cfd566
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.svg b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.svg
new file mode 100644 (file)
index 0000000..6347d99
--- /dev/null
@@ -0,0 +1,504 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="fontawesomeregular" horiz-adv-x="1536" >
+<font-face units-per-em="1792" ascent="1536" descent="-256" />
+<missing-glyph horiz-adv-x="448" />
+<glyph unicode=" "  horiz-adv-x="448" />
+<glyph unicode="&#x09;" horiz-adv-x="448" />
+<glyph unicode="&#xa0;" horiz-adv-x="448" />
+<glyph unicode="&#xa8;" horiz-adv-x="1792" />
+<glyph unicode="&#xa9;" horiz-adv-x="1792" />
+<glyph unicode="&#xae;" horiz-adv-x="1792" />
+<glyph unicode="&#xb4;" horiz-adv-x="1792" />
+<glyph unicode="&#xc6;" horiz-adv-x="1792" />
+<glyph unicode="&#xd8;" horiz-adv-x="1792" />
+<glyph unicode="&#x2000;" horiz-adv-x="768" />
+<glyph unicode="&#x2001;" horiz-adv-x="1537" />
+<glyph unicode="&#x2002;" horiz-adv-x="768" />
+<glyph unicode="&#x2003;" horiz-adv-x="1537" />
+<glyph unicode="&#x2004;" horiz-adv-x="512" />
+<glyph unicode="&#x2005;" horiz-adv-x="384" />
+<glyph unicode="&#x2006;" horiz-adv-x="256" />
+<glyph unicode="&#x2007;" horiz-adv-x="256" />
+<glyph unicode="&#x2008;" horiz-adv-x="192" />
+<glyph unicode="&#x2009;" horiz-adv-x="307" />
+<glyph unicode="&#x200a;" horiz-adv-x="85" />
+<glyph unicode="&#x202f;" horiz-adv-x="307" />
+<glyph unicode="&#x205f;" horiz-adv-x="384" />
+<glyph unicode="&#x2122;" horiz-adv-x="1792" />
+<glyph unicode="&#x221e;" horiz-adv-x="1792" />
+<glyph unicode="&#x2260;" horiz-adv-x="1792" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M93 1350q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78z" />
+<glyph unicode="&#xf001;" d="M0 -64q0 50 34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5 q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89z" />
+<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
+<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M0 32v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5 t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768zM128 1120q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317 q54 43 100.5 115.5t46.5 131.5v11v13.5t-0.5 13t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5z" />
+<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z " />
+<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48z" />
+<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354 q-25 27 -25 48zM221 829l306 -297l-73 -421l378 199l377 -199l-72 421l306 297l-422 62l-189 382l-189 -382z" />
+<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M0 131q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5 h-874q-121 0 -194 69.5t-73 189.5zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5z" />
+<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M0 -96v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 64v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM128 320q0 -26 19 -45t45 -19h128 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19 h-128q-26 0 -45 -19t-19 -45v-128zM512 -64q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM512 704q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM1536 64 v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM1536 320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M0 128v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM0 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 128v384q0 52 38 90t90 38h512q52 0 90 -38 t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90z" />
+<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 608v192 q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M121 608q0 40 28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68z" />
+<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M110 214q0 40 28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-294 -294l294 -294q28 -28 28 -68t-28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294 q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68z" />
+<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf011;" d="M0 640q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181 q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298zM640 768v640q0 52 38 90t90 38t90 -38t38 -90v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90z" />
+<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M0 -96v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM384 -96v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM768 -96v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576 q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 -96v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1536 -96v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf013;" d="M0 531v222q0 12 8 23t19 13l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10 q129 -119 165 -170q7 -8 7 -22q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108 q-44 -23 -91 -38q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5z M512 640q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
+<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M0 1056v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23zM256 76q0 -22 7 -40.5 t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5v948h-896v-948zM384 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM640 224v576q0 14 9 23t23 9h64 q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM896 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M26 636.5q1 13.5 11 21.5l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5zM256 64 v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf016;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22 v-376z" />
+<glyph unicode="&#xf017;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 544v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M50 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256 q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73zM809 540q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4z" />
+<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M0 96v320q0 40 28 68t68 28h465l135 -136q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 985q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39q17 -41 -14 -70 l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70zM1152 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf01a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM418 620q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35z" />
+<glyph unicode="&#xf01b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM416 672q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf01c;" d="M0 64v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552q25 -61 25 -123v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM197 576h316l95 -192h320l95 192h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8 t-2.5 -8z" />
+<glyph unicode="&#xf01d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 320v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55t-32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56z" />
+<glyph unicode="&#xf01e;" d="M0 640q0 156 61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5 t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298z" />
+<glyph unicode="&#xf021;" d="M0 0v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129 q-19 -19 -45 -19t-45 19t-19 45zM18 800v7q65 268 270 434.5t480 166.5q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179 q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M0 160v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832z M256 288v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 544v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z M256 800v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 288v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z M512 544v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5zM512 800v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z " />
+<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192z" />
+<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110zM320 320v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19 q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M0 650q0 151 67 291t179 242.5t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32 q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32 q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314z" />
+<glyph unicode="&#xf026;" horiz-adv-x="768" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5z" />
+<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5zM1008 228q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5 q140 -59 225 -188.5t85 -282.5t-85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45zM1109 -7q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19 q13 0 26 -5q211 -91 338 -283.5t127 -422.5t-127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M0 0v640h640v-640h-640zM0 768v640h640v-640h-640zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM256 256v128h128v-128h-128zM256 1024v128h128v-128h-128zM768 0v640h384v-128h128v128h128v-384h-384v128h-128v-384h-128zM768 768v640h640v-640h-640z M896 896h384v384h-384v-384zM1024 0v128h128v-128h-128zM1024 1024v128h128v-128h-128zM1280 0v128h128v-128h-128z" />
+<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M0 0v1408h63v-1408h-63zM94 1v1407h32v-1407h-32zM189 1v1407h31v-1407h-31zM346 1v1407h31v-1407h-31zM472 1v1407h62v-1407h-62zM629 1v1407h31v-1407h-31zM692 1v1407h31v-1407h-31zM755 1v1407h31v-1407h-31zM880 1v1407h63v-1407h-63zM1037 1v1407h63v-1407h-63z M1163 1v1407h63v-1407h-63zM1289 1v1407h63v-1407h-63zM1383 1v1407h63v-1407h-63zM1541 1v1407h94v-1407h-94zM1666 1v1407h32v-1407h-32zM1729 0v1408h63v-1408h-63z" />
+<glyph unicode="&#xf02b;" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5zM704 1408h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5z" />
+<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M10 184q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23 t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57 q38 -15 59 -43q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5zM575 1056 q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
+<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62z" />
+<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M0 160v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-224 q-13 0 -22.5 9.5t-9.5 22.5zM384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1408 576q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M0 128v896q0 106 75 181t181 75h224l51 136q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181zM512 576q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM672 576q0 119 84.5 203.5t203.5 84.5t203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8 t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27 q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14zM555 527q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452z" />
+<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5 t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12zM533 1292q0 -50 4 -151t4 -152q0 -27 -0.5 -80 t-0.5 -79q0 -46 1 -69q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13zM538.5 165q0.5 -37 4.5 -83.5t12 -66.5q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25 t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5z" />
+<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
+<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5 q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9 t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44zM1414 109.5q9 18.5 42 18.5h80v1024 h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5z" />
+<glyph unicode="&#xf035;" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1 t-103 1t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29 t78 27q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44zM5 -64q0 28 26 49q4 3 36 30t59.5 49 t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5q12 0 42 -19.5t57.5 -41.5t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5 t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49z" />
+<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1536 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h896 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h1280 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 416v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5zM0 800v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192 q-13 0 -22.5 9.5t-9.5 22.5zM384 32v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 416v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 800v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 1184v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5 t-9.5 22.5zM32 704q0 14 9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088 q-13 0 -22.5 9.5t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 416v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23t-9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5z M0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5 t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5q39 -17 39 -59v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5 t-84.5 203.5z" />
+<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v192l320 320l160 -160l512 512l416 -416v-448h-1408zM256 960q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136z" />
+<glyph unicode="&#xf040;" d="M0 -128v416l832 832l416 -416l-832 -832h-416zM128 128h128v-128h107l91 91l-235 235l-91 -91v-107zM298 384q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17zM896 1184l166 165q36 38 90 38q53 0 91 -38l235 -234 q37 -39 37 -91q0 -53 -37 -90l-166 -166z" />
+<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M0 896q0 212 150 362t362 150t362 -150t150 -362q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179zM256 896q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" />
+<glyph unicode="&#xf042;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73v1088q-148 0 -273 -73t-198 -198t-73 -273z" />
+<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M0 512q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275q0 -212 -150 -362t-362 -150t-362 150t-150 362zM256 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69z" />
+<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29v-190 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM640 256v288l672 672l288 -288l-672 -672h-288zM736 448h96v-96h56l116 116l-152 152l-116 -116v-56zM944 688q16 -16 33 1l350 350q17 17 1 33t-33 -1l-350 -350q-17 -17 -1 -33zM1376 1280l92 92 q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68l-92 -92z" />
+<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h255q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29v-259 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM256 704q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45l-384 -384 q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5t-38.5 114t-17.5 122z" />
+<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3 q20 -8 20 -29v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM257 768q0 33 24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110q24 -24 24 -57t-24 -57l-814 -814q-24 -24 -57 -24t-57 24l-430 430 q-24 24 -24 57z" />
+<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256 q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-710q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45 t-45 -19h-128q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M122 640q0 26 19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45z" />
+<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M0 -96v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31l-1328 -738q-23 -13 -39.5 -3t-16.5 36z" />
+<glyph unicode="&#xf04c;" d="M0 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM896 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04d;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32v710 q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" />
+<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M1 64v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM1 525q-6 13 13 32l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13z" />
+<glyph unicode="&#xf053;" horiz-adv-x="1280" d="M154 704q0 26 19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45z" />
+<glyph unicode="&#xf054;" horiz-adv-x="1280" d="M90 128q0 26 19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45z" />
+<glyph unicode="&#xf055;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19 t19 45v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf056;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19 t-19 -45v-128z" />
+<glyph unicode="&#xf057;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM387 414q0 -27 19 -46l90 -90q19 -19 46 -19q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19 l90 90q19 19 19 46q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45z" />
+<glyph unicode="&#xf058;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 621q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45q0 28 -18 46l-91 90 q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46z" />
+<glyph unicode="&#xf059;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM417 939q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26 t37.5 -59q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213zM640 160q0 -14 9 -23t23 -9 h192q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192z" />
+<glyph unicode="&#xf05a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320 q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160zM640 1056q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160z" />
+<glyph unicode="&#xf05b;" d="M0 576v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143 q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45zM339 512q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5h-109q-26 0 -45 19 t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109z" />
+<glyph unicode="&#xf05c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM429 480q0 13 10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23l-137 -137l137 -137q10 -10 10 -23t-10 -23l-146 -146q-10 -10 -23 -10t-23 10l-137 137 l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23z" />
+<glyph unicode="&#xf05d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM346 640q0 26 19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45z" />
+<glyph unicode="&#xf05e;" d="M0 643q0 157 61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5t-61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61t-245 164t-163.5 246t-61 300zM224 643q0 -162 89 -299l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199 t-73 -274zM471 185q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5q0 161 -87 295z" />
+<glyph unicode="&#xf060;" d="M64 576q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5t32.5 -90.5v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90 z" />
+<glyph unicode="&#xf061;" d="M0 512v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5z" />
+<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M53 565q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651q37 -39 37 -91q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75 q-38 38 -38 90z" />
+<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M53 704q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90z" />
+<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M0 416q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45t-19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123 q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22t-13.5 30t-10.5 24q-127 285 -127 451z" />
+<glyph unicode="&#xf065;" d="M0 -64v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45zM781 800q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448 q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
+<glyph unicode="&#xf066;" d="M13 32q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23zM768 704v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10 t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M122.5 408.5q13.5 51.5 59.5 77.5l266 154l-266 154q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5 l-266 -154l266 -154q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5z" />
+<glyph unicode="&#xf06a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM624 1126l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5l18 621q0 12 -10 18 q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18zM640 161q0 -13 10 -23t23 -10h192q13 0 22 9.5t9 23.5v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190z" />
+<glyph unicode="&#xf06b;" d="M0 544v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68 t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23zM376 1120q0 -40 28 -68t68 -28h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68zM608 180q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5v56v468v192h-320v-192v-468v-56zM870 1024h194q40 0 68 28 t28 68t-28 68t-68 28q-43 0 -69 -31z" />
+<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M0 121q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96 q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5zM384 448q0 -26 19 -45t45 -19q24 0 45 19 q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45t-19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45z" />
+<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M0 -160q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64zM256 640q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100 t113.5 -122.5t72.5 -150.5t27.5 -184q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184z" />
+<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M0 576q0 34 20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69t-20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69zM128 576q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5q-152 236 -381 353 q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5z" />
+<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M0 576q0 38 20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5q16 -10 16 -27q0 -7 -1 -9q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87 q-143 65 -263.5 173t-208.5 245q-20 31 -20 69zM128 576q167 -258 427 -375l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5zM896 0l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69t-20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95zM1056 286l280 502q8 -45 8 -84q0 -139 -79 -253.5t-209 -164.5z" />
+<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M16 61l768 1408q17 31 47 49t65 18t65 -18t47 -49l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126zM752 992l17 -457q0 -10 10 -16.5t24 -6.5h185q14 0 23.5 6.5t10.5 16.5l18 459q0 12 -10 19q-13 11 -24 11h-220 q-11 0 -24 -11q-10 -7 -10 -21zM768 161q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190z" />
+<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M0 477q-1 13 9 25l96 97q9 9 23 9q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16 l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23z" />
+<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h288v288h-288v-288zM128 224 h288v320h-288v-320zM128 608h288v288h-288v-288zM384 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM480 -128h320v288h-320v-288zM480 224h320v320h-320v-320zM480 608h320v288h-320 v-288zM864 -128h320v288h-320v-288zM864 224h320v320h-320v-320zM864 608h320v288h-320v-288zM1152 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM1248 -128h288v288h-288v-288z M1248 224h288v320h-288v-320zM1248 608h288v288h-288v-288z" />
+<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M0 160v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23zM0 1056v192q0 14 9 23t23 9h224q250 0 410 -225q-60 -92 -137 -273q-22 45 -37 72.5 t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23zM743 353q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 q-32 0 -85 -0.5t-81 -1t-73 1t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5z" />
+<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M0 640q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5 t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281z" />
+<glyph unicode="&#xf076;" d="M0 576v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5 t-98.5 362zM0 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45zM1024 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf077;" horiz-adv-x="1792" d="M90 250.5q0 26.5 19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5z" />
+<glyph unicode="&#xf078;" horiz-adv-x="1792" d="M90 773.5q0 26.5 19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5z" />
+<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M0 704q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45z M640 1120q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20z " />
+<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M0 1216q0 26 19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024 q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45zM384 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1280 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158z" />
+<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5t-0.5 12.5zM73 56q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43 q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43z" />
+<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M64 64q0 26 19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" />
+<glyph unicode="&#xf080;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v384h256v-384h-256zM640 128v896h256v-896h-256zM1024 128v640h256v-640h-256zM1408 128v1024h256v-1024h-256z" />
+<glyph unicode="&#xf081;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 286q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109 q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4q21 -63 74.5 -104 t121.5 -42q-116 -90 -261 -90q-26 0 -50 3z" />
+<glyph unicode="&#xf082;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544 q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M0 0v1280q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5zM128 0h1536v128h-1536v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM256 1216h384v128h-384v-128zM512 574 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM640 574q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM736 576q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9 t9 23t-9 23t-23 9q-66 0 -113 -47t-47 -113z" />
+<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M0 752q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41q0 -17 -49 -66t-66 -49 q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5zM192 768q0 -80 56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56 t56 136t-56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136z" />
+<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M0 549v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8 q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90 q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5zM384 640q0 -106 75 -181t181 -75 t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181zM1152 58v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31 v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1152 1082v140q0 16 149 31q13 29 30 52 q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71 q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1408 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90zM1408 1152q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90z" />
+<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM616 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5 t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
+<glyph unicode="&#xf087;" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5 t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85 t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640z" />
+<glyph unicode="&#xf088;" d="M0 512v640q0 53 37.5 90.5t90.5 37.5h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186 q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5zM128 1088q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 512h32q16 0 35.5 -9 t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5 t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640z" />
+<glyph unicode="&#xf089;" horiz-adv-x="896" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48z" />
+<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z M128 940q0 -168 187 -355l581 -560l580 559q188 188 188 356q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5 t-21.5 -143z" />
+<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5q0 -4 1 -20t0.5 -26.5t-3 -23.5 t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5zM384 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf08c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM223 1030q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86z M237 122h231v694h-231v-694zM595 122h231v388q0 38 7 56q15 35 45 59.5t74 24.5q116 0 116 -157v-371h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694z" />
+<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M0 320q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19 t-19 45zM416 672q0 -14 9 -23t23 -9t23 9t9 23v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448z" />
+<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832 q-119 0 -203.5 84.5t-84.5 203.5zM685 576q0 13 10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" />
+<glyph unicode="&#xf090;" d="M0 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45zM894.5 78.5q0.5 10.5 3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113 t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5q0 4 -1 20t-0.5 26.5z" />
+<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M0 928v128q0 40 28 68t68 28h288v96q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91t97.5 -37q75 0 133.5 -45.5 t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143zM128 928q0 -78 94.5 -162t235.5 -113q-74 162 -74 371 h-256v-96zM1206 653q141 29 235.5 113t94.5 162v96h-256q0 -209 -74 -371z" />
+<glyph unicode="&#xf092;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204 q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52 t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5h-224q-119 0 -203.5 84.5t-84.5 203.5zM271 315q3 5 13 2 q10 -5 7 -12q-5 -7 -13 -2q-10 5 -7 12zM304 290q6 6 16 -3q9 -11 2 -16q-6 -7 -16 3q-9 11 -2 16zM335 233q-9 13 0 18q9 7 17 -6q9 -12 0 -19q-8 -6 -17 7zM370 206q8 9 20 -3q12 -11 4 -19q-8 -9 -20 3q-13 11 -4 19zM419 168q4 11 19 7q16 -5 13 -16q-4 -12 -19 -6 q-17 4 -13 15zM481 154q0 11 16 11q17 2 17 -11q0 -11 -16 -11q-17 -2 -17 11zM540 158q-2 12 14 15q16 2 18 -9q2 -10 -14 -14t-18 8z" />
+<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M0 -32v320q0 40 28 68t68 28h427q21 -56 70.5 -92t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 936q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69q-17 -40 -59 -40 h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40zM1152 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf094;" d="M0 433q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5q0 -165 -70 -327.5 t-196 -288t-281 -180.5q-124 -44 -326 -44q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5zM128 434q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5 q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24 q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5z" />
+<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M0 1069q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235 t235 -174q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5 t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5z" />
+<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832z" />
+<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62zM128 38l423 406l89 85l89 -85l423 -406 v1242h-1024v-1242z" />
+<glyph unicode="&#xf098;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 905q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5 q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5 t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5z" />
+<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M44 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5 q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145z" />
+<glyph unicode="&#xf09a;" horiz-adv-x="1024" d="M95 631v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255z" />
+<glyph unicode="&#xf09b;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44 l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3 q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5z" />
+<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M0 96v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v608h-1664v-608zM128 1024h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600 q-13 0 -22.5 -9.5t-9.5 -22.5v-224zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
+<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M0 192q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 697v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5t259 -181.5q114 -113 181.5 -259t80.5 -306q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5 t-391.5 184.5q-25 2 -41.5 20t-16.5 43zM0 1201v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294q187 -186 294 -425.5t120 -501.5q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102 q-25 1 -42.5 19.5t-17.5 43.5z" />
+<glyph unicode="&#xf0a0;" d="M0 160v320q0 25 16 75l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-1216 q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM880 320q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1136 320q0 33 23.5 56.5t56.5 23.5 t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5z" />
+<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M0 672v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50 t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113zM768 633q377 -42 768 -341v954q-394 -302 -768 -343v-270z" />
+<glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
+<glyph unicode="&#xf0a3;" d="M2 435q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70l-53 -186l188 -48 q40 -10 52 -51q10 -42 -20 -70l-138 -135l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53 q-41 -12 -70 19q-31 29 -19 70l53 186l-188 48q-40 10 -52 51z" />
+<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179q0 -105 -75.5 -181 t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q72 0 167 -32 t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139 q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106q-69 -57 -140 -57h-32v-640z" />
+<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M0 769q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5v-640 q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181zM128 768q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119 q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5 t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5t-39 -89.5zM1536 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a6;" d="M0 640q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5t-90.5 -37.5h-640 q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5zM128 640q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140 v-32h640v32q0 72 32 167t64 193.5t32 179.5q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576q-20 0 -48.5 15t-55 33t-68 33t-84.5 15 q-67 0 -97.5 -44.5t-30.5 -115.5zM1152 -64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a7;" d="M0 640q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317q0 -142 -77.5 -230t-217.5 -87 l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5zM128 640q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33t55 33t48.5 15v-576q0 -50 38.5 -89 t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112 q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5zM1152 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0a8;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM251 640q0 -27 18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0a9;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM256 576q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18 l362 362l91 91q18 18 18 45t-18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf0aa;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 641q0 -27 18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19 t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45t-18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0ab;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 639q0 -27 18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45t-18 45l-91 91 q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45z" />
+<glyph unicode="&#xf0ac;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM226 979q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18 q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13 q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5 t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13 q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25 t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5 t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4 q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5q15 10 -7 16q-17 5 -43 -12q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8 q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5 q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26 q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5 q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14 q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5 q-16 0 -22 -1q-146 -80 -235 -222zM877 26q0 -6 2 -16q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7 t-10 1.5t-11.5 -7q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5z" />
+<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M21 0q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90zM256 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM768 960q0 185 131.5 316.5t316.5 131.5q58 0 121.5 -16.5 t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25q0 -39 -23 -106q-47 -134 -164.5 -217.5t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5z" />
+<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M0 64v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 576v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1088v256q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM640 640h1024v128h-1024v-128zM1024 128h640v128h-640v-128zM1280 1152h384v128h-384v-128z" />
+<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M5 1241q17 39 59 39h1280q42 0 59 -39q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70z" />
+<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M0 160v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 736v384q0 66 47 113t113 47h352v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113v-384h-1792z M640 1280h512v128h-512v-128zM768 512v128h256v-128h-256z" />
+<glyph unicode="&#xf0b2;" d="M0 -64v448q0 42 40 59q39 17 69 -14l144 -144l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45 v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19l-144 144l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19 t-19 45z" />
+<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M0 671q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5zM128 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM256 3q0 53 3.5 103.5 t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5 zM576 896q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5zM1280 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM1327 640q81 117 81 256q0 29 -5 66q66 -23 133 -23 q59 0 119 21.5t97.5 42.5t43.5 21q124 0 124 -353q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128z" />
+<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l206 -207q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204t-85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88 q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204zM208 1088q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15t21.5 -21.5t18.5 -19q33 31 33 73 q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67zM911 383q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26l147 146q28 28 28 67q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5 q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73z" />
+<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M0 448q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z" />
+<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M115.5 -64.5q-34.5 63.5 21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399l503 -793q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5zM476 384h712l-272 429l-20 31v37v399h-128v-399v-37 l-20 -31z" />
+<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M1 157q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148q4 -48 -10 -97q4 -1 12 -5 l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56l-507 -398l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207zM168 176q-25 -66 21 -108q39 -36 113 -36q100 0 192 59q81 51 106 117t-21 108q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117zM168 976q25 -66 106 -117q92 -59 192 -59q74 0 113 36q46 42 21 108t-106 117q-92 59 -192 59 q-74 0 -113 -36q-46 -42 -21 -108zM672 448l9 -8q2 -2 7 -6q4 -4 11 -12t11 -12l26 -26l160 96l96 -32l736 576l-128 64l-768 -431v-113zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 576q0 26 19 45t45 19t45 -19 t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1018 391l582 -327l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
+<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M0 224v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68zM128 256h512v256q0 40 20 88t48 76l316 316v416h-384 v-416q0 -40 -28 -68t-68 -28h-416v-640zM213 1024h299v299zM768 -128h896v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640zM853 640h299v299z" />
+<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M4 1023q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581 q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776 q-113 115 -113 271z" />
+<glyph unicode="&#xf0c7;" d="M0 -32v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 0h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20 t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280zM384 0h768v384h-768v-384zM640 928q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320z" />
+<glyph unicode="&#xf0c8;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf0c9;" d="M0 64v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 576v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 1088v128q0 26 19 45t45 19h1408 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M0 128q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 640q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 1152q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM512 32v192 q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z M512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M15 438q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105v-159h-362q-6 36 -6 54zM19 -190 l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66zM34 1400l136 127h106v-404h108v-99 h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54zM512 32v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M0 544v64q0 14 9 23t23 9h1728q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23zM384 972q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6l-14 2q-50 149 -103 205 q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743q-28 35 -51 80q-48 97 -48 188zM414 154q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22 q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156z" />
+<glyph unicode="&#xf0cd;" d="M0 -32v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-1472q-14 0 -23 -9t-9 -23zM0 1405q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5 t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2 q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195 q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39q-37 2 -45 4z" />
+<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M0 160v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 544q0 -14 9 -23t23 -9h320 q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192zM640 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23 v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192z" />
+<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M27 160q0 27 18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45t-18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45zM128 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM320 1216l196 60l60 196l60 -196l196 -60l-196 -60 l-60 -196l-60 196zM768 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM1083 1062l107 -107l293 293l-107 107zM1408 768l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98z" />
+<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M64 192q0 26 19 45t45 19v320q0 8 -0.5 35t0 38t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45v-1024q0 -15 -4 -26.5t-13.5 -18.5t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5 q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM384 128q0 -52 38 -90t90 -38 t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90zM1280 128q0 -52 38 -90t90 -38t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90z" />
+<glyph unicode="&#xf0d2;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63 q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5 q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423z" />
+<glyph unicode="&#xf0d3;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5 q-104 0 -194.5 -28.5t-153 -76.5t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118 q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5z" />
+<glyph unicode="&#xf0d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM276 309q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117 q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94 q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95zM395 338q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78z M462 969q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5t-57.5 96.5t-17.5 106zM960 672h128v-160h64v160h128v64h-128v128h-64v-128h-128v-64z" />
+<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M32 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65 t-59.5 -61.5t-24.5 -66q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131zM218 228q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5q58 0 111.5 13t99 39t73 73 t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5zM324 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q38 0 78 16.5t66 43.5q53 57 53 159 q0 58 -17 125t-48.5 129.5t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160zM1084 731v108h212v217h105v-217h213v-108h-213v-219h-105v219h-212z" />
+<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M0 64v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45zM128 384q106 0 181 -75t75 -181h1152q0 106 75 181t181 75v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512zM640 640q0 70 21 142 t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142t-21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142zM762 791l77 -80q42 37 55 57h2v-288h-128v-96h384v96h-128v448h-114z" />
+<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M0 832q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M0 320q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M64 640q0 26 19 45l448 448q19 19 45 19t45 -19t19 -45v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M0 192v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45z" />
+<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M0 32v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h608v1152h-640v-1120zM896 0h608q13 0 22.5 9.5t9.5 22.5v1120h-640v-1152z" />
+<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45zM0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" />
+<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M0 32v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 1098q0 78 41.5 130t118.5 52h1472 q65 0 112.5 -47t47.5 -113q0 -79 -49 -151t-122 -123q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5z" />
+<glyph unicode="&#xf0e1;" d="M0 1217q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122zM19 -80v991h330v-991h-330zM531 -80q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5v-568 h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329z" />
+<glyph unicode="&#xf0e2;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M40 736q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18 q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5 q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5 t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68z" />
+<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M0 384q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29q-141 221 -141 483zM128 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M320 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM710 241q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91l101 382q6 26 -7.5 48.5t-38.5 29.5t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5 t-63 -98.5zM768 1024q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1216 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 384q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M0 640q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5 t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281zM128 640q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5t-381.5 -69.5 t-282 -187.5t-104.5 -255z" />
+<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM128 768q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52t-286 -52t-211.5 -141t-78.5 -191zM616 132 q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22 t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" />
+<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M1 551l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39z" />
+<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M0 -32v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M0 681q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17 q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5z M384 128q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180zM768 1310v98q0 26 19 45t45 19t45 -19t19 -45v-98q-42 2 -64 2t-64 -2z" />
+<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M0 96v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88v-672q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68zM256 1312q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5v64 q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64zM768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1280 640h299l-299 299v-299z" />
+<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M0 960q0 99 44.5 184.5t117 142t164 89t186.5 32.5t186.5 -32.5t164 -89t117 -142t44.5 -184.5q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47q0 -46 -31.5 -71t-77.5 -25 q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268zM128 960q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228 q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134zM480 1088q0 13 9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5 q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M0 256q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22zM0 800v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23 t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 608q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5z" />
+<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 672q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24z" />
+<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M0 131q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89 q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5 t81 -103t47.5 -132.5t24 -138t5.5 -131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190zM256 192q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5 t-271.5 112.5t-112.5 271.5z" />
+<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M0 768v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48 q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5 t-131.5 271.5v132q-164 20 -274 128t-110 252zM1152 832q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h64v-1280h-64q-92 0 -158 66t-66 158zM384 -128v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128v-1280h-1024zM640 1152h512v128h-512v-128zM1504 -128v1280h64q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-64z " />
+<glyph unicode="&#xf0f3;" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" />
+<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM256 480v736q0 26 19 45t45 19h1152q159 0 271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158zM1408 704h64q80 0 136 56t56 136 t-56 136t-136 56h-64v-384z" />
+<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M0 832v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128 q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111zM768 416v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM384 160v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64 q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 416v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 672v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1536h-1152v-1536zM256 160v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 928v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 1184v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M0 -192v1280q0 26 19 45t45 19h320v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1152h-256 v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152zM256 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1056q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128 v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M64 192q0 26 19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128 q-26 0 -45 19t-19 45zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM384 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM896 800q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192 q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM1280 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h32v-1280h-32q-92 0 -158 66t-66 158zM352 -128v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160v-1280h-1088zM512 416q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192 q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM640 1152h512v128h-512v-128zM1536 -128v1280h32q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-32z" />
+<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M0 512v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93l1 -3q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5 t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8z" />
+<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M64 1152l32 128h480l32 128h960l32 -192l-64 -32v-800l128 -192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320zM384 768q0 -53 37.5 -90.5t90.5 -37.5h128v384h-256v-256z" />
+<glyph unicode="&#xf0fd;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 192q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896z" />
+<glyph unicode="&#xf0fe;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128z" />
+<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM429 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23 l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM397 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10 l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M77 224q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM77 608q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23 l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M77 672q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM77 1056q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10 l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf104;" horiz-adv-x="640" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf105;" horiz-adv-x="640" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M77 352q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M77 800q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" />
+<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M0 288v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113zM128 544q0 -13 9.5 -22.5 t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832z" />
+<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M0 96v96h160h1600h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68zM256 416v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113zM384 416q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5 t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM864 112q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16z" />
+<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M0 160v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-832q-66 0 -113 47t-47 113zM128 288q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM512 128 q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M0 128v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM96 288q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM288 1136 q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16zM304 128q0 -33 23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5z" />
+<glyph unicode="&#xf10c;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273z" />
+<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M0 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z M896 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z" />
+<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M0 832v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136zM896 832v384 q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136z" />
+<glyph unicode="&#xf110;" horiz-adv-x="1568" d="M0 640q0 66 47 113t113 47t113 -47t47 -113t-47 -113t-113 -47t-113 47t-47 113zM176 1088q0 73 51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5t-51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5zM208 192q0 60 42 102t102 42q59 0 101.5 -42t42.5 -102t-42.5 -102 t-101.5 -42q-60 0 -102 42t-42 102zM608 1280q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM672 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1136 192q0 46 33 79t79 33t79 -33t33 -79 t-33 -79t-79 -33t-79 33t-33 79zM1168 1088q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1344 640q0 40 28 68t68 28t68 -28t28 -68t-28 -68t-68 -28t-68 28t-28 68z" />
+<glyph unicode="&#xf111;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5z" />
+<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101 t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19l-512 512q-19 19 -19 45z" />
+<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M0 496q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218q0 -87 -27 -168q136 -160 136 -398q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86t-170 -47.5t-171.5 -22t-167 -4.5 q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331zM224 320q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11 q-152 21 -195 21q-118 0 -187 -84t-69 -204zM384 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82zM1024 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34 t-43 76t-12.5 82z" />
+<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158zM128 224q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64 q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960z" />
+<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158zM128 331l256 315q44 53 116 87.5 t140 34.5h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-853zM171 163q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40z " />
+<glyph unicode="&#xf116;" horiz-adv-x="1792" />
+<glyph unicode="&#xf117;" horiz-adv-x="1792" />
+<glyph unicode="&#xf118;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 461q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38 q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5q-37 -121 -138 -195t-228 -74t-228 74t-138 195zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf119;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 307q37 121 138 195t228 74t228 -74t138 -195q8 -25 -4 -48.5 t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf11a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 448q0 26 19 45t45 19h640q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" />
+<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M0 512q0 212 150 362t362 150h896q212 0 362 -150t150 -362t-150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150t-150 362zM192 448q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23v128 q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128zM1152 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 640q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" />
+<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M0 128v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5zM128 128h1664v896h-1664v-896zM256 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM256 528v96 q0 16 16 16h224q16 0 16 -16v-96q0 -16 -16 -16h-224q-16 0 -16 16zM256 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM512 272v96q0 16 16 16h864q16 0 16 -16v-96q0 -16 -16 -16h-864q-16 0 -16 16zM512 784v96q0 16 16 16h96q16 0 16 -16v-96 q0 -16 -16 -16h-96q-16 0 -16 16zM640 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM768 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM896 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z M1024 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1152 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1280 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1408 528v96q0 16 16 16h112v240 q0 16 16 16h96q16 0 16 -16v-352q0 -16 -16 -16h-224q-16 0 -16 16zM1536 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z" />
+<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599z" />
+<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q205 96 384 110v192q-181 -16 -384 -117v-185zM448 836q215 111 384 118v197q-172 -8 -384 -126v-189zM832 730h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15 t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2q-23 0 -49 -3v-222zM1280 828q148 -42 384 90v189q-169 -91 -306 -91q-45 0 -78 8v-196z" />
+<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM640 32v64q0 14 9 23t23 9h960q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-960 q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM712 -52l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5 l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5zM1293 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" />
+<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45l397 -397v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45zM384 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221 q169 -173 169 -509q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45z" />
+<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M2 900.5q9 27.5 54 34.5l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5z M832 310l59 -31l318 -168l-60 355l-12 66l49 47l257 250l-356 52l-66 10l-30 60l-159 322v-963z" />
+<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M2 561q-5 22 4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5z" />
+<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M0 928v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864 q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23zM512 301l595 595h-595v-595zM557 256h595v595z" />
+<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M0 64q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136 q0 -52 -26 -96.5t-70 -69.5q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136zM96 64q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM96 1216q0 -40 28 -68 t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM736 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
+<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M0 448q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23zM16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56l-239 -18l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68 l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204zM128 32q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23zM544 -96v320q0 14 9 23t23 9t23 -9t9 -23v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23zM633 364 l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56zM1056 1184v320q0 14 9 23t23 9t23 -9t9 -23v-320 q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1216 1120q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23zM1280 960q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M96.5 986q-2.5 15 5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5t-10.5 37.5v45q0 83 65 156.5 t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25zM384 40v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28z" />
+<glyph unicode="&#xf129;" horiz-adv-x="640" d="M0 64v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM128 1152v192q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-192 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M98 1344q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45zM128 64v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf12b;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1013 713q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80h126v-206h-514l-3 27q-4 28 -4 46z " />
+<glyph unicode="&#xf12c;" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1015 -183q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126v-206h-514l-4 27q-3 45 -3 46z" />
+<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M1.5 146.5q5.5 37.5 30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5zM128 128h768l336 384h-768z" />
+<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M0 0v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5 q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124 q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89 q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1z" />
+<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M0 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45 t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5zM256 704v512q0 132 94 226t226 94t226 -94t94 -226v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226z" />
+<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M13 64q0 13 10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23t-10 -23l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5 t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23zM128 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113l-101 -101 q-42 103 -42 214zM384 704v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
+<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M0 576v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150t-33.5 170.5zM640 79 q119 63 213 137q235 184 235 360v640h-448v-1137z" />
+<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h1408v1024h-1408v-1024z M384 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288zM1152 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288z" />
+<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M3.5 940q-8.5 25 3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96 q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37 zM384 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M36 464l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85 q-3 -1 -9 -1q-14 0 -23 9l-64 64q-17 19 -5 39zM1248 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" />
+<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M0 0l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334z" />
+<glyph unicode="&#xf137;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM346 640q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l102 102q19 19 19 45t-19 45l-307 307l307 307 q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
+<glyph unicode="&#xf138;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM506 288q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-454 454 q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45z" />
+<glyph unicode="&#xf139;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 544q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19l102 102 q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" />
+<glyph unicode="&#xf13a;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 736q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-102 102 q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
+<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M0 1408h1408l-128 -1438l-578 -162l-574 162zM262 1114l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674l16 175h-884z" />
+<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M12 75l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208l59 297h1505l-266 -1333l-804 -267z" />
+<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M0 0v352q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5 l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30zM832 1280q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" />
+<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181v-320h736q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28 t-28 68z" />
+<glyph unicode="&#xf140;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM256 640q0 212 150 362t362 150t362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362zM384 640q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
+<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM512 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM1024 608v192q0 40 28 68t68 28h192 q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf142;" horiz-adv-x="384" d="M0 96v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h192q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" />
+<glyph unicode="&#xf143;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 256q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M256 575q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10t9 24q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128zM256 959q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128 q13 0 23 10q11 9 9 23q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128z" />
+<glyph unicode="&#xf144;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 320q0 -37 32 -56q16 -8 32 -8q17 0 32 9l544 320q32 18 32 55t-32 55l-544 320q-31 19 -64 1 q-32 -19 -32 -56v-640z" />
+<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M54 448.5q0 53.5 37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136t-136 56t-136 -56l-125 126q-37 37 -37 90.5z M342 512q0 -26 19 -45l362 -362q18 -18 45 -18t45 18l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45zM452 512l572 572l316 -316l-572 -572z" />
+<glyph unicode="&#xf146;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h896q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128 z" />
+<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M3 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18z" />
+<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M3 1261q9 19 29 19h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34z" />
+<glyph unicode="&#xf14a;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 640q0 -26 19 -45l358 -358q19 -19 45 -19t45 19l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19 t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" />
+<glyph unicode="&#xf14b;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 128h288l544 544l-288 288l-544 -544v-288zM352 320v56l52 52l152 -152l-52 -52h-56v96h-96zM494 494 q-14 13 3 30l291 291q17 17 30 3q14 -13 -3 -30l-291 -291q-17 -17 -30 -3zM864 1024l288 -288l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28z" />
+<glyph unicode="&#xf14c;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM282 320q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59 v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45z" />
+<glyph unicode="&#xf14d;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 448q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5t224 23.5v-160 q0 -42 40 -59q12 -5 24 -5q26 0 45 19l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5z" />
+<glyph unicode="&#xf14e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 241v542l512 256v-542zM640 448l256 128l-256 128v-256z" />
+<glyph unicode="&#xf150;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 861q17 35 57 35h640q40 0 57 -35q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66z" />
+<glyph unicode="&#xf151;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 419q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66q-17 -35 -57 -35h-640q-40 0 -57 35z" />
+<glyph unicode="&#xf152;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -14 9 -23t23 -9h960q14 0 23 9t9 23v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960z M512 320v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52t-27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57z" />
+<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M0 514v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5 t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5 l12 3l5 2q13 5 26 -2q12 -7 15 -21l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M0 32v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215 h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M52 171l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242 t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48 t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50t53 -63.5t31.5 -76.5t13 -94q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5 t-17.5 18q-17 21 -2 41z" />
+<glyph unicode="&#xf156;" horiz-adv-x="898" d="M0 605v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171 q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22z" />
+<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M4 1360q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103 q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214z" />
+<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M0 256v128q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315t-126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9 h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23zM487 747h320q106 0 171 62t65 162t-65 162t-171 62h-320v-448z" />
+<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M0 672v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111 q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23z M373 896l32 -128h225l35 128h-292zM436 640l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5l81 299h-159zM822 768h139l-35 128h-70zM1118 896l34 -128h230l33 128h-297zM1187 640l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3l78 300h-162z" />
+<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M56 0l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89 t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200zM522 182q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30t24.5 40t9.5 51q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1 t-47.5 -1v-338zM522 674q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307z" />
+<glyph unicode="&#xf15b;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
+<glyph unicode="&#xf15c;" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM384 160q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 416q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 672q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" />
+<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 768v106h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106 h-287zM988 -166l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121v-233h-584v90zM1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18 t-7.5 -29z" />
+<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 -150h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287 v106zM988 768v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248v119h121v-233h-584zM1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29 z" />
+<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h256q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf162;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 261q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 1351l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17 v16h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 261q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
+<glyph unicode="&#xf163;" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 1285q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 327l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16 h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 1285q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" />
+<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M0 64v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45zM128 192q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45zM480 64v641q0 25 18 43.5t43 20.5q24 2 76 59 t101 121q68 87 101 120q18 18 31 48t17.5 48.5t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135 q0 -86 -55 -149q15 -44 15 -76q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5z" />
+<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M0 448q0 -26 19 -45t45 -19h288q26 0 45 19t19 45v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640zM128 960q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45zM480 447v641q0 26 19 44.5t45 19.5q35 1 158 44 q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76q55 -61 55 -149q-1 -78 -57.5 -135t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39 t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121t-76 59q-25 2 -43 20.5t-18 43.5z" />
+<glyph unicode="&#xf166;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 366q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73 q20 84 20 260q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5q-20 -87 -20 -260zM300 551v70h232v-70h-80v-423h-74v423h-78zM396 1313l24 -69t23 -69q35 -103 46 -158v-201h74v201l90 296h-75l-51 -195l-53 195 h-78zM542 205v290h66v-270q0 -24 1 -26q1 -15 15 -15q20 0 42 31v280h67v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54zM654 936q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38q-21 -29 -21 -87v-130zM721 923 v156q0 52 32 52t32 -52v-156q0 -51 -32 -51t-32 51zM790 128v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67zM857 200q16 -16 33 -16q29 0 29 49v157q0 50 -29 50q-17 0 -33 -16v-224zM907 893q0 -37 6 -55 q11 -27 43 -27q36 0 77 45v-40h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293zM1037 247v129q0 59 20 86q29 38 80 38t78 -38q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68v-9q0 -29 -2 -43q-3 -22 -15 -40 q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86zM1103 355h66v34q0 51 -33 51t-33 -51v-34z" />
+<glyph unicode="&#xf167;" d="M27 260q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99q-26 112 -26 350zM138 509h105v-569h100v569h107v94h-312 v-94zM266 1536h106l71 -263l68 263h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187zM463 43q0 -49 8 -73q12 -37 58 -37q48 0 102 61v-54h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391zM614 1028v175q0 80 28 117q38 51 105 51 q69 0 106 -51q28 -37 28 -117v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51q-28 38 -28 118zM704 1011q0 -70 43 -70t43 70v210q0 69 -43 69t-43 -69v-210zM798 -60h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89 v-663zM887 36v301q22 22 45 22q39 0 39 -67v-211q0 -67 -39 -67q-23 0 -45 22zM955 971v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75zM1130 100q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54 q2 9 2 58v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51q-28 -37 -28 -116v-173zM1219 245v46q0 68 45 68t45 -68v-46h-90z" />
+<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M5 384q-10 17 0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45l164 -286q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17zM536 539q18 32 531 942q25 45 64 45h241q22 0 31 -15q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37 q-10 -15 -32 -15h-239q-42 0 -66 45z" />
+<glyph unicode="&#xf169;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM227 396q8 -13 24 -13h185q31 0 50 36l199 352q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29 l125 -216v-1l-196 -346q-9 -14 0 -28zM638 516q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1l409 723q8 16 0 28q-7 12 -24 12h-187q-30 0 -49 -35z" />
+<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M0 640q0 96 1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150t-1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58 t-69.5 123q-14 65 -21.5 147.5t-8.5 136.5t-1 150zM640 320q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54t-30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640z" />
+<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M64 558l338 271l494 -305l-342 -285zM64 1099l490 319l342 -285l-494 -304zM407 166v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284l147 96v-108l-490 -293v-1l-1 1l-1 -1v1zM896 524l494 305l338 -271l-489 -319zM896 1133l343 285l489 -319l-338 -270z" />
+<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M0 -255v736h121v-618h928v618h120v-701l-1 -35v-1h-1132l-35 1h-1zM221 -17v151l707 1v-151zM227 243l14 150l704 -65l-13 -150zM270 563l39 146l683 -183l-39 -146zM395 928l77 130l609 -360l-77 -130zM707 1303l125 86l398 -585l-124 -85zM1136 1510l149 26l121 -697 l-149 -26z" />
+<glyph unicode="&#xf16d;" d="M0 69v1142q0 81 58 139t139 58h1142q81 0 139 -58t58 -139v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139zM171 110q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62 q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648zM461 643q0 -124 90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5t-90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5zM1050 1003q0 -29 20 -49t49 -20h174q29 0 49 20t20 49v165q0 28 -20 48.5 t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165z" />
+<glyph unicode="&#xf16e;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM274 640q0 -88 62 -150t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150zM838 640q0 -88 62 -150 t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150z" />
+<glyph unicode="&#xf170;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM309 384h94l104 160h522l104 -160h94l-459 691zM567 608l201 306l201 -306h-402z" />
+<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M0 1222q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34 t-6 39.5t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158zM173 285l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18t-76.5 27 t-73 43.5t-52 61.5q-25 96 -57 292zM243 1240q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5q-20 27 -56 44.5t-58 22t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43zM481 657q4 -91 77.5 -155t165.5 -56q91 8 152 84 t50 168q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5zM599 710q14 41 52 58q36 18 72.5 12t64 -35.5t27.5 -67.5q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82z" />
+<glyph unicode="&#xf172;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM260 1060q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63 q24 13 39.5 23t31 29t19.5 40q48 267 80 473q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54zM385 384q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71q0 7 5.5 26.5t3 32 t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6zM436 1073q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5t-52.5 16t-54.5 32.5zM607 653q-2 49 25.5 93t72.5 64 q70 31 141.5 -10t81.5 -118q8 -66 -36 -121t-110 -61t-119 40t-56 113zM687.5 660.5q0.5 -52.5 43.5 -70.5q39 -23 81 4t36 72q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5z" />
+<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M78 779v217q91 30 155 84q64 55 103 132q39 78 54 196h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170z" />
+<glyph unicode="&#xf174;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM413 744h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49v181 q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163z" />
+<glyph unicode="&#xf175;" horiz-adv-x="768" d="M3 237q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19t-5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35z" />
+<glyph unicode="&#xf176;" horiz-adv-x="768" d="M3 1043q-8 19 5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19z" />
+<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M64 637q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23z" />
+<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M0 544v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M0 634q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32 q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503zM683 1131q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17z" />
+<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M0 -27v557h682v-651zM0 614v565l682 94v-659h-682zM757 -131v661h907v-786zM757 614v669l907 125v-794h-907z" />
+<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M0 337v430q0 42 30 72t73 30q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30t-73 30t-30 73zM241 886q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20l-71 -131q107 -55 171 -153.5t64 -215.5 h-925zM245 184v666h918v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78zM455 1092q0 -16 11 -27.5t27 -11.5t27.5 11.5t11.5 27.5t-11.5 27.5 t-27.5 11.5t-27 -11.5t-11 -27.5zM876 1092q0 -16 11.5 -27.5t27.5 -11.5t27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5zM1203 337v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73z" />
+<glyph unicode="&#xf17c;" d="M11 -115q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5 t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195q-12 112 -16 310q-2 90 24 151.5 t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5 t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13 t16.5 -9.5q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5 q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5zM321 495q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54 t7 -70.5q46 24 7 92q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5 t60 -22.5q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18zM372 630q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12zM603 1190q2 -5 5 -6 q10 0 7 -15q-3 -20 8 -20q3 0 3 3q3 17 -2.5 30t-11.5 15q-9 2 -9 -7zM634 1110q0 12 19 15h10q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5zM721 1122q24 11 32 -2q3 -6 -3 -9q-4 -1 -11.5 6.5t-17.5 4.5zM835 1196l4 -2q14 -4 18 -31q0 -3 8 2l2 3q0 11 -5 19.5t-11 12.5 t-9 3q-14 -1 -7 -7zM851 1381.5q-1 -2.5 3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9zM981 1002q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20q-2 8 -6.5 11.5t-13 5 t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5z" />
+<glyph unicode="&#xf17d;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM112 640q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81t99.5 48l37 13 q4 1 13 3.5t13 4.5q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21zM126 775q302 0 606 80q-120 213 -244 378q-138 -65 -234 -186t-128 -272zM350 134q184 -150 418 -150q132 0 256 52q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5 t-103 -148zM609 1276q1 1 2 1q-1 0 -2 -1zM613 1277q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5l12.5 17.5q-185 164 -433 164q-76 0 -155 -19zM909 797q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5 t36.5 -6t25 -4.5l10 -2q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5zM1007 565q87 -239 128 -469q111 75 185 189.5t96 250.5q-210 60 -409 29z" />
+<glyph unicode="&#xf17e;" d="M0 1024q0 159 112.5 271.5t271.5 112.5q130 0 234 -80q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225 t-55.5 273.5q0 73 16 150q-80 104 -80 234zM376 399q0 -92 122 -157.5t291 -65.5q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12 t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5 q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75z" />
+<glyph unicode="&#xf180;" horiz-adv-x="1664" d="M0 640q0 75 53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41l619 619l2 -3q53 -53 53 -128t-53 -128l-587 -587 q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128zM302 660q0 21 14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36z" />
+<glyph unicode="&#xf181;" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM160 192q0 -14 9 -23t23 -9h480q14 0 23 9t9 23v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024zM832 576q0 -14 9 -23t23 -9h480q14 0 23 9t9 23 v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640z" />
+<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M0 480q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192 q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43q-40 0 -68 28t-28 68zM416 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M0 416v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68z M288 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf184;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM399.5 766q8.5 -37 24.5 -59l349 -473l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5 t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85z" />
+<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M44 363q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29q-4 -15 -20 -20 l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20zM320 640q0 -117 45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5 t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5z" />
+<glyph unicode="&#xf186;" d="M0 640q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384z" />
+<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M64 1088v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM128 -64v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM704 704q0 -26 19 -45t45 -19h256 q26 0 45 19t19 45t-19 45t-45 19h-256q-26 0 -45 -19t-19 -45z" />
+<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M32 576q0 26 19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19t19 -45t-19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19 t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45z M512 1152q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5h-640z" />
+<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M-1 1004q0 11 3 16l4 6q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24 q17 19 38 30q53 26 239 24q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5 t13 3t20 0.5l288 2q39 5 64 -2.5t31 -16.5l6 -10q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12 q-30 21 -70 64t-68.5 77.5t-61 58t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211 t-130.5 272q-6 16 -6 27z" />
+<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M0 391q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5q0 -68 -37 -139.5 t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5zM181 320q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5zM413.5 230.5 q-40.5 92.5 6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5q-45 -102 -158 -150t-224 -12q-107 34 -147.5 126.5zM495 257.5q9 -34.5 43 -50.5t74.5 -2.5t62.5 47.5q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5zM705 399 q-17 -31 13 -45q14 -5 29 0.5t22 18.5q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5zM1165 1274q-6 28 9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158 q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5zM1224 1047q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5t54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37z" />
+<glyph unicode="&#xf18b;" d="M0 638q0 187 83.5 349.5t229.5 269.5t325 137v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495zM398 -34q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211q-171 -94 -368 -94q-196 0 -367 94zM898 909v485q179 -30 325 -137t229.5 -269.5 t83.5 -349.5q0 -280 -181 -495q-204 99 -330.5 306.5t-126.5 459.5z" />
+<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M0 -211q0 19 13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23 t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89 t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283 q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32z" />
+<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M21 217v66h1238v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5zM21 354v255h1238v-255h-1238zM21 682v255h1238v-255h-1238zM21 1010v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5v-67h-1238z" />
+<glyph unicode="&#xf18e;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 544v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5z" />
+<glyph unicode="&#xf190;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 640q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23z" />
+<glyph unicode="&#xf191;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM448 640q0 33 27 52l448 320q17 12 37 12q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52z" />
+<glyph unicode="&#xf192;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" />
+<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M0 320q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5zM416 1348q-2 16 6 42 q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455l198 99l58 -114l-256 -128q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5z" />
+<glyph unicode="&#xf194;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 806q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5 q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237q104 139 172.5 292.5t82.5 226.5q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143 q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7z" />
+<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M0 608v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31 l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26z" />
+<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf197;" horiz-adv-x="2176" d="M0 576q0 12 38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113q-110 -64 -268 -64h-128v64 h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5zM323 336h29q157 0 273 64h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96zM323 816l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5 t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64h-29zM1739 484l81 -30q68 48 68 122t-68 122l-81 -30q53 -36 53 -92t-53 -92z" />
+<glyph unicode="&#xf198;" horiz-adv-x="1664" d="M0 796q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5 t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72 l-55 163l-153 -53q-29 -9 -50 -9q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5zM620 811l105 -313l310 105l-105 315z" />
+<glyph unicode="&#xf199;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 352q0 -40 28 -68t68 -28h832q40 0 68 28t28 68v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99 q-98 -69 -164 -69t-164 69q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436zM256 928q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13 t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68z" />
+<glyph unicode="&#xf19a;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM41 640q0 -173 68 -331.5t182.5 -273t273 -182.5t331.5 -68t331.5 68t273 182.5t182.5 273t68 331.5 t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5zM127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM254 1062q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5 q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21t14.5 -24t14 -23q63 -107 63 -212q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15 t-1.5 -18.5t9 -16.5t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5zM679 -97l230 670l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1282 -24l235 678q59 169 59 276q0 42 -6 79 q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5z" />
+<glyph unicode="&#xf19b;" horiz-adv-x="1792" d="M0 455q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360l272 133v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5zM1134 860v172q277 -33 481 -157l140 79l37 -390l-525 114l147 83 q-119 70 -280 99z" />
+<glyph unicode="&#xf19c;" horiz-adv-x="2048" d="M0 -128q0 26 20.5 45t48.5 19h1782q28 0 48.5 -19t20.5 -45v-128h-1920v128zM0 1024v128l960 384l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128zM128 0v64q0 26 20.5 45t48.5 19h59v768h256v-768h128v768h256v-768h128v768h256 v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664z" />
+<glyph unicode="&#xf19d;" horiz-adv-x="2304" d="M0 1024q0 23 22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31t-22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433 q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31zM512 384l18 316l574 -181q22 -7 48 -7t48 7l574 181l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128z" />
+<glyph unicode="&#xf19e;" d="M109 1536q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610l13 -707q-62 11 -105 11 q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287z" />
+<glyph unicode="&#xf1a0;" horiz-adv-x="1280" d="M111 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5t-59.5 -93 t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131zM297 228q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13 t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5zM403 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5 q53 56 53 159q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160z" />
+<glyph unicode="&#xf1a1;" horiz-adv-x="1984" d="M0 722q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58 q94 0 160 -66t66 -160q0 -62 -31 -114t-83 -82q5 -33 5 -61q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5zM77 722q0 -67 51 -111 q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM178 465q0 -101 59.5 -194t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5 t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5zM555 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM661 209.5q0 16.5 11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77q11 11 27 11t27 -11t11 -27.5t-11 -27.5 q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5zM1153 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM1555 1350q0 -45 32 -77t77 -32t77 32t32 77t-32 77t-77 32t-77 -32t-32 -77zM1672 843q131 -105 178 -238 q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28z" />
+<glyph unicode="&#xf1a2;" d="M0 193v894q0 133 94 227t226 94h896q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227zM155 709q0 -37 19.5 -67.5t52.5 -45.5q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54 q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43 q-51 0 -87 -36.5t-36 -87.5zM493 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM560 375q0 11 8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18z M882 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM1143 1120q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21q-29 0 -50 21t-21 50z" />
+<glyph unicode="&#xf1a3;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 502q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14 q19 0 32.5 -14t13.5 -33v-54l60 -28l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122zM806 500q0 -80 58 -137t139 -57t138.5 57t57.5 139v122h-150v-126q0 -20 -13.5 -33.5t-33.5 -13.5 q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123z" />
+<glyph unicode="&#xf1a4;" horiz-adv-x="1920" d="M0 336v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58l-131 61v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5zM1062 332 v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275h328v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5z" />
+<glyph unicode="&#xf1a5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM64 640h704v-704h480q93 0 158.5 65.5t65.5 158.5v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480z " />
+<glyph unicode="&#xf1a6;" horiz-adv-x="2048" d="M0 271v697h328v286h204v-983h-532zM205 435h123v369h-123v-369zM614 271h205v697h-205v-697zM614 1050h205v204h-205v-204zM901 26v163h328v82h-328v697h533v-942h-533zM1106 435h123v369h-123v-369zM1516 26v163h327v82h-327v697h532v-942h-532zM1720 435h123v369h-123 v-369z" />
+<glyph unicode="&#xf1a7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM293 388l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229t-88.5 229t-213.5 95q-74 0 -141 -36h-186v-840z M504 804v277q28 17 70 17q53 0 91 -45t38 -109t-38 -109.5t-91 -45.5q-43 0 -70 15zM636 -39l211 41v206q51 -19 117 -19q125 0 213 95t88 229t-88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101v-636zM847 377v277q28 17 70 17q53 0 91 -45.5t38 -109.5 t-38 -109t-91 -45q-43 0 -70 15z" />
+<glyph unicode="&#xf1a8;" horiz-adv-x="2038" d="M41 455q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80 t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5l1 -21q75 3 143.5 -20.5 t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14q6 -5 28 -23.5t25.5 -22t19 -18 t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63 t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27zM764 676q10 1 32.5 7t34.5 6q19 0 35 -10l-96 -20zM822 568l48 12l109 -177l-73 -48zM859 884q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1 v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5 t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43zM1061 45h31l10 -83l-41 -12v95zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM1116 29 q21 2 60.5 8.5t72 10t60.5 3.5h14q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13t-54 -9.5t-53.5 -7.5t-32 -4.5zM1947 1528l1 3l2 4l-1 -5zM1950 1535v1v-1zM1950 1535l1 1z" />
+<glyph unicode="&#xf1a9;" d="M0 520q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5 t19.5 -177.5q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302zM333 256q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5zM685.5 -76q-0.5 -10 7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5 q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16zM852 31q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5 t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10q-29 -12 -78 -56q-26 -24 -12 -44z" />
+<glyph unicode="&#xf1aa;" d="M0 78q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160l151 -152l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5 t-60 145.5zM2 1202q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5t149.5 -87.5l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5 q-70 15 -115 71t-45 129zM446 803l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126t135.5 51q85 0 145 -60.5t60 -145.5q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152 l-160 -160zM776 793l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5q76 -11 126.5 -68.5t50.5 -134.5q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30 l-152 152z" />
+<glyph unicode="&#xf1ab;" d="M0 -16v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5q20 0 20 -21v-418l147 -47v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3zM39 15l694 232v1032l-694 -233v-1031zM147 293q6 4 82 92 q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8 t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110 q-4 -2 -19.5 -4t-18.5 0zM268 933l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41zM310 -116q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11q73 -37 159.5 -61.5t157.5 -24.5 q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5l-43 73l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16zM777 1294l573 -184v380zM885 453l102 -31l45 110l211 -65l37 -135l102 -31l-181 657l-100 31z M1071 630l76 185l63 -227z" />
+<glyph unicode="&#xf1ac;" horiz-adv-x="1792" d="M0 -96v1088q0 66 47 113t113 47h128q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113zM512 -96v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-163q58 -34 93 -93t35 -128v-768q0 -106 -75 -181 t-181 -75h-864q-66 0 -113 47t-47 113zM640 896h896v256h-160q-40 0 -68 28t-28 68v160h-640v-512zM736 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM736 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9 h-128q-14 0 -23 -9t-9 -23v-128zM736 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 256q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23 v-128zM1248 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128z" />
+<glyph unicode="&#xf1ad;" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM256 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 1184q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 96v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23zM512 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM512 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 928q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM1024 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64z" />
+<glyph unicode="&#xf1ae;" horiz-adv-x="1280" d="M64 1056q0 40 28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68zM416 1152q0 93 65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" />
+<glyph unicode="&#xf1b0;" horiz-adv-x="1664" d="M0 724q0 80 42 139.5t119 59.5q76 0 141.5 -55.5t100.5 -134t35 -152.5q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152zM256 19q0 86 56 191.5t139.5 192.5t187.5 146t193 59q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45 t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146zM333 1163q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151zM884 1064 q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5q-61 0 -105 39t-63 92.5t-19 113.5zM1226 581q0 74 35 152.5t100.5 134t141.5 55.5q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5 q-77 0 -119 59t-42 139z" />
+<glyph unicode="&#xf1b1;" horiz-adv-x="768" d="M64 1008q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5z" />
+<glyph unicode="&#xf1b2;" horiz-adv-x="1792" d="M0 256v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65zM134 1026l698 -254l698 254l-698 254zM896 -93l640 349v636l-640 -233v-752z" />
+<glyph unicode="&#xf1b3;" horiz-adv-x="2304" d="M0 96v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70v-400l434 -186q36 -16 57 -48t21 -70v-416q0 -36 -19 -67t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4 l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67zM172 531l404 -173l404 173l-404 173zM640 -96l384 192v314l-384 -164v-342zM647 1219l441 -189l441 189l-441 189zM1152 651l384 165v266l-384 -164v-267zM1196 531l404 -173l404 173l-404 173zM1664 -96 l384 192v314l-384 -164v-342z" />
+<glyph unicode="&#xf1b4;" horiz-adv-x="2048" d="M0 22v1260h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5 t45.5 113.5q0 144 -190 144h-260v-294zM1137 477q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658q0 -111 57.5 -171.5t166.5 -60.5q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347zM1337 1073h511v124 h-511v-124zM1388 576h408q-18 195 -200 195q-90 0 -146 -52.5t-62 -142.5z" />
+<glyph unicode="&#xf1b5;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 254h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5t-56.5 60.5t-79 29.5 t-97 8.5h-371v-787zM301 388v217h189q124 0 124 -113q0 -104 -128 -104h-185zM301 723v184h163q119 0 119 -90q0 -94 -106 -94h-176zM838 538q0 -135 79 -217t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20q-68 0 -104 38t-36 107h411q1 10 1 30 q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216zM964 911v77h319v-77h-319zM996 600q4 56 39 89t91 33q113 0 124 -122h-254z" />
+<glyph unicode="&#xf1b6;" horiz-adv-x="2048" d="M0 764q0 86 61 146.5t146 60.5q73 0 130 -46t73 -117l783 -315q49 29 106 29q14 0 21 -1l173 248q1 114 82 194.5t195 80.5q115 0 196.5 -81t81.5 -196t-81.5 -196.5t-196.5 -81.5l-265 -194q-8 -80 -67.5 -133.5t-138.5 -53.5q-73 0 -130 46t-73 117l-783 315 q-51 -30 -106 -30q-85 0 -146 61t-61 147zM55 764q0 -64 44.5 -108.5t107.5 -44.5q11 0 33 4l-64 26q-33 14 -52.5 44.5t-19.5 66.5q0 50 35.5 85.5t85.5 35.5q20 0 41 -8v1l76 -31q-20 37 -56.5 59t-78.5 22q-63 0 -107.5 -44.5t-44.5 -107.5zM1164 244q19 -37 55.5 -59 t79.5 -22q63 0 107.5 44.5t44.5 107.5t-44.5 108t-107.5 45q-13 0 -33 -4q2 -1 20 -8t21.5 -8.5t18.5 -8.5t19 -10t16 -11t15.5 -13.5t11 -14.5t10 -18t5 -21t2.5 -25q0 -50 -35.5 -85.5t-85.5 -35.5q-14 0 -31.5 4.5t-29 9t-31.5 13.5t-28 12zM1584 767q0 -77 54.5 -131.5 t131.5 -54.5t132 54.5t55 131.5t-55 131.5t-132 54.5q-76 0 -131 -54.5t-55 -131.5zM1623 767q0 62 43.5 105.5t104.5 43.5t105 -44t44 -105t-43.5 -104.5t-105.5 -43.5q-61 0 -104.5 43.5t-43.5 104.5z" />
+<glyph unicode="&#xf1b7;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 693q0 -53 38 -91t92 -38q36 0 66 18l489 -197q10 -44 45.5 -73t81.5 -29q50 0 86.5 34t41.5 83l167 122 q71 0 122 50.5t51 122.5t-51 123t-122 51q-72 0 -122.5 -50.5t-51.5 -121.5l-108 -155q-2 0 -6.5 0.5t-6.5 0.5q-35 0 -67 -19l-489 197q-10 44 -45.5 73t-80.5 29q-54 0 -92 -38t-38 -92zM162 693q0 40 28 68t68 28q27 0 49.5 -14t34.5 -37l-48 19q-29 11 -56.5 -2 t-38.5 -41q-12 -29 -0.5 -57t39.5 -40v-1l40 -16q-14 -2 -20 -2q-40 0 -68 27.5t-28 67.5zM855 369q5 -2 47 -19q29 -12 58 0.5t41 41.5q11 29 -1 57.5t-41 40.5l-40 16q14 2 21 2q39 0 67 -27.5t28 -67.5t-28 -67.5t-67 -27.5q-59 0 -85 51zM1118 695q0 48 34 82t83 34 q48 0 82 -34t34 -82t-34 -82t-82 -34q-49 0 -83 34t-34 82zM1142 696q0 -39 27.5 -66t65.5 -27t65.5 27t27.5 66q0 38 -27.5 65.5t-65.5 27.5t-65.5 -27.5t-27.5 -65.5z" />
+<glyph unicode="&#xf1b8;" horiz-adv-x="1792" d="M16 970l433 -17l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188zM270.5 158q-3.5 28 4 65t12 55t21.5 64t19 53q78 -12 509 -28l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5 q-11 27 -14.5 55zM294 1124l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5t36 -39.5t32 -35q-47 -63 -265 -435l-317 187zM782 1524l405 -1q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190l142 83l-220 -373l-419 20l151 86q-34 89 -75 166 t-75.5 123.5t-64.5 80t-47 46.5zM953 197l211 362l7 -173q170 -16 283 -5t170 33l56 22l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164zM1218 847l313 195l19 11l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22 t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436z" />
+<glyph unicode="&#xf1b9;" horiz-adv-x="1984" d="M0 160v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h704q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-928v-128q0 -80 -56 -136 t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23zM160 448q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 768h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 448q0 -66 47 -113t113 -47t113 47t47 113 t-47 113t-113 47t-113 -47t-47 -113z" />
+<glyph unicode="&#xf1ba;" horiz-adv-x="1984" d="M0 32v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h64q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-64q0 -80 -56 -136t-136 -56 t-136 56t-56 136v64h-928v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23zM160 320q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 640h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 320 q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113z" />
+<glyph unicode="&#xf1bb;" d="M32 64q0 26 19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45t-19 -45t-45 -19 h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45z" />
+<glyph unicode="&#xf1bc;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM237 886q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37q159 0 309.5 -34t253.5 -95q21 -12 40 -12 q29 0 50.5 20.5t21.5 51.5q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5zM289 637q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5q0 40 -35 61 q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64zM321 406q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52z" />
+<glyph unicode="&#xf1bd;" d="M0 11v1258q0 58 40.5 98.5t98.5 40.5h1258q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5zM71 11q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258z M121 11v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5zM121 709v560q0 7 5.5 12.5 t12.5 5.5h1258q7 0 12.5 -5.5t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137zM246 413q-24 203 166 305l129 -270l-255 -61q-14 -3 -26 4.5t-14 21.5z" />
+<glyph unicode="&#xf1be;" horiz-adv-x="2304" d="M0 405l17 128q2 9 9 9t9 -9l20 -128l-20 -126q-2 -9 -9 -9t-9 9zM79 405l23 207q0 9 9 9q8 0 10 -9l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10zM169 405l21 245q2 12 12 12q11 0 11 -12l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11zM259 405l21 252q0 13 13 13 q12 0 14 -13l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13zM350 405l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5zM401 159zM442 405l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5l21 -380l-21 -246q0 -7 -5 -12.5 t-12 -5.5q-16 0 -18 18zM534 403l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19zM628 405l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5l18 -506l-18 -242q-2 -21 -22 -21q-19 0 -21 21zM723 405l14 -241 q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17zM784 164zM817 405l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18zM913 404l12 492q1 12 9 20t19 8t18.5 -8 t8.5 -20l14 -492l-14 -236q0 -11 -8 -19t-19 -8t-19 8t-9 19zM1010 405q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11q11 0 20 9q9 7 9 20l1 24l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6zM1079 169zM1103 404l12 636v3q2 15 12 24q9 7 20 7 q8 0 15 -5q14 -8 16 -26l14 -639l-14 -231q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114zM1204 174v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22z" />
+<glyph unicode="&#xf1c0;" d="M0 0v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 384v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 768 v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 1152v128q0 69 103 128t280 93.5t385 34.5t385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128z" />
+<glyph unicode="&#xf1c1;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM257 60q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4 q52 85 107 197q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38 q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83z M714 842q1 7 7 44q0 3 7 43q1 4 4 8q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2q-15 -42 -2 -132zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1098 353q76 -28 124 -28q14 0 18 1q0 1 -2 3q-24 24 -140 24z" />
+<glyph unicode="&#xf1c2;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM233 661h70l164 -661h159l128 485q7 20 10 46q2 16 2 24 h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300v-107zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c3;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM429 0h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4 h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107h-290v-107h68l189 -272l-194 -283h-68v-106zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c4;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM416 0h327v106h-93v167h137q76 0 118 15q67 23 106.5 87 t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92v-106zM650 386v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15h-119zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c5;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 0v192l192 192l128 -128l384 384l320 -320v-320 h-1024zM256 704q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c6;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536zM384 192q0 25 8 52q21 63 120 396 v128h128v-128h79q22 0 39 -13t23 -34l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5zM512 192q0 -26 37.5 -45t90.5 -19t90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45zM512 896h128v128h-128v-128zM512 1152h128v128h-128v-128 zM640 768h128v128h-128v-128zM640 1024h128v128h-128v-128zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c7;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 288v192q0 14 9 23t23 9h131l166 167q16 15 35 7 q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23zM762 206.5q1 -26.5 20 -44.5q20 -17 44 -17q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5z M973.5 54.5q2.5 -26.5 23.5 -42.5q18 -15 40 -15q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c8;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 256v384q0 52 38 90t90 38h384q52 0 90 -38t38 -90 v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90zM960 403v90l265 266q9 9 23 9q4 0 12 -2q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1c9;" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM254 429q-14 19 0 38l226 301q8 11 21 12.5t24 -6.5 l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5zM636 43l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5l-63 10q-13 2 -20.5 13t-5.5 24zM947.5 181 q-1.5 13 6.5 24l182 243l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5l226 -301q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" />
+<glyph unicode="&#xf1ca;" d="M39 1286h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132 t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390z" />
+<glyph unicode="&#xf1cb;" horiz-adv-x="1792" d="M0 367v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64v-546q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64zM154 511l193 129l-193 129v-258zM216 367l603 -402v359l-334 223zM216 913l269 -180l334 223v359zM624 640 l272 -182l272 182l-272 182zM973 -35l603 402l-269 180l-334 -223v-359zM973 956l334 -223l269 180l-603 402v-359zM1445 640l193 -129v258z" />
+<glyph unicode="&#xf1cc;" horiz-adv-x="2048" d="M0 407q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5 h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55t121.5 -21 q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z " />
+<glyph unicode="&#xf1cd;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM128 640q0 -190 90 -361l194 194q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361zM512 640 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM535 -38q171 -90 361 -90t361 90l-194 194q-82 -28 -167 -28t-167 28zM535 1318l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90t-361 -90z M1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
+<glyph unicode="&#xf1ce;" horiz-adv-x="1792" d="M0 640q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5 q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348z" />
+<glyph unicode="&#xf1d0;" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
+<glyph unicode="&#xf1d1;" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM44 640q0 -173 67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331 t-67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331zM87 640q0 205 98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385zM206 217l58 34q29 -49 73 -99 l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13v-66q-208 6 -385 109.5t-283 275.5zM207 1063q106 172 282 275.5t385 109.5v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98zM415 805q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10 t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162q-67 77 -98 169l232 80q-14 42 -14 85t14 85zM918 -102 q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99l58 -34q-106 -172 -283 -275.5t-385 -109.5v66zM918 1382v66q209 -6 385 -109.5t282 -275.5l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13zM1516 428q36 103 36 212q0 112 -35 212l82 28 q-19 56 -49 112l57 33q98 -180 98 -385t-98 -385l-57 33q27 52 49 112z" />
+<glyph unicode="&#xf1d2;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 218q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5 t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85q0 -53 41 -77v-3q-113 -37 -113 -139zM382 225q0 64 98 64q102 0 102 -61q0 -66 -93 -66 q-107 0 -107 63zM395 693q0 90 77 90q36 0 55 -25.5t19 -63.5q0 -85 -74 -85q-77 0 -77 84zM755 1072q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392q0 -50 -3 -75z M966 771q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117z" />
+<glyph unicode="&#xf1d3;" horiz-adv-x="1792" d="M68 7q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47q98 0 218 47v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58q0 -31 22.5 -51.5t58 -32 t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5zM272 18q0 -101 172 -101q151 0 151 105q0 100 -165 100q-158 0 -158 -104zM293 775q0 -135 124 -135q119 0 119 137q0 61 -30 102t-89 41 q-124 0 -124 -145zM875 1389q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5t-39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5zM901 220q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134h-222zM1217 901v190h96v76q0 54 -6 89h227q-6 -41 -6 -165 h171v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6z" />
+<glyph unicode="&#xf1d4;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM368 1135l323 -589v-435h134v436l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3 q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150z" />
+<glyph unicode="&#xf1d5;" horiz-adv-x="1280" d="M57 953q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5t-78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153 t-153 102t-186 38t-186 -38t-153 -102t-102 -153t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265zM113.5 38.5q10.5 121.5 29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5t136.5 -56.5 t56.5 -136.5t-57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5z" />
+<glyph unicode="&#xf1d6;" horiz-adv-x="1792" d="M18 264q0 275 252 466q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5 t3.5 -5t2 -3.5q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9 t-98 20t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20 q-18 -41 -54.5 -74.5t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100z" />
+<glyph unicode="&#xf1d7;" horiz-adv-x="2048" d="M0 858q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490z M380 1075q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5t-25 66t-66 25q-43 0 -76 -25.5t-33 -65.5zM816 404q0 143 81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109q-150 -37 -218 -37 q-169 0 -311 70.5t-223.5 191.5t-81.5 264zM888 1075q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5t-24.5 66t-65.5 25q-43 0 -76 -25.5t-33 -65.5zM1160 568q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5 t-22.5 -49.5zM1559 568q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5z" />
+<glyph unicode="&#xf1d8;" horiz-adv-x="1792" d="M0 508q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55z" />
+<glyph unicode="&#xf1d9;" horiz-adv-x="1792" d="M0 508q-3 39 32 59l1664 960q35 21 68 -2q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55zM209 522l336 -137l863 639l-478 -797l492 -201 l221 1323z" />
+<glyph unicode="&#xf1da;" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45zM512 480v64q0 14 9 23t23 9h224v352 q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf1db;" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5z" />
+<glyph unicode="&#xf1dc;" horiz-adv-x="1792" d="M62 1338q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5 t45 -15t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18 q-15 10 -45 12t-53 2t-41 14t-18 45z" />
+<glyph unicode="&#xf1dd;" horiz-adv-x="1280" d="M24 926q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108 q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179q-64 117 -64 259z" />
+<glyph unicode="&#xf1de;" d="M0 736v64q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM128 -96v672h256v-672q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM128 960v416q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-416h-256zM512 224v64q0 40 28 68 t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 64h256v-160q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v160zM640 448v928q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-928h-256zM1024 992v64q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1152 -96v928h256v-928q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 1216v160q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-160h-256z" />
+<glyph unicode="&#xf1e0;" d="M0 640q0 133 93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86q133 0 226.5 -93.5t93.5 -226.5 t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5z" />
+<glyph unicode="&#xf1e1;" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 640q0 -88 62.5 -150.5t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5 t150.5 62.5t62.5 150.5t-62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5z" />
+<glyph unicode="&#xf1e2;" horiz-adv-x="1792" d="M0 448q0 143 55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68l243 244l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5 t-225 150t-150 225t-55.5 273.5zM170 615q10 -24 35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49t-34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49zM1376 1472q0 13 9 23q10 9 23 9t23 -9l90 -91q10 -9 10 -22.5t-10 -22.5 q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23zM1536 1408v96q0 14 9 23t23 9t23 -9t9 -23v-96q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1605 1242.5q0 13.5 10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5z M1605 1381.5q0 13.5 10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5zM1632 1312q0 14 9 23t23 9h96q14 0 23 -9t9 -23t-9 -23t-23 -9h-96q-14 0 -23 9t-9 23z" />
+<glyph unicode="&#xf1e3;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e4;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e5;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e6;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e7;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e8;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1e9;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ea;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1eb;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ec;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ed;" horiz-adv-x="1792" />
+<glyph unicode="&#xf1ee;" horiz-adv-x="1792" />
+<glyph unicode="&#xf500;" horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+<glyph horiz-adv-x="1792" />
+</font>
+</defs></svg> 
diff --git a/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.ttf b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.ttf
new file mode 100644 (file)
index 0000000..5cd6cff
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.woff b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.woff
new file mode 100644 (file)
index 0000000..9eaecb3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/fontawesome-webfont.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.eot b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.eot
new file mode 100644 (file)
index 0000000..4a4ca86
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.svg b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.svg
new file mode 100644 (file)
index 0000000..83f74b2
--- /dev/null
@@ -0,0 +1,229 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph />
+<glyph />
+<glyph unicode="&#xd;" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
+<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#x2000;" horiz-adv-x="652" />
+<glyph unicode="&#x2001;" horiz-adv-x="1304" />
+<glyph unicode="&#x2002;" horiz-adv-x="652" />
+<glyph unicode="&#x2003;" horiz-adv-x="1304" />
+<glyph unicode="&#x2004;" horiz-adv-x="434" />
+<glyph unicode="&#x2005;" horiz-adv-x="326" />
+<glyph unicode="&#x2006;" horiz-adv-x="217" />
+<glyph unicode="&#x2007;" horiz-adv-x="217" />
+<glyph unicode="&#x2008;" horiz-adv-x="163" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="326" />
+<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
+<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
+<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
+<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
+<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
+<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
+<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
+<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
+<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
+<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
+<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
+<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
+<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
+<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
+<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
+<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
+<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
+<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
+<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
+<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
+<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
+<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
+<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
+<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
+<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
+<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
+<glyph unicode="&#xe028;" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
+<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
+<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
+<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
+<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
+<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
+<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
+<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
+<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
+<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
+<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
+<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
+<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
+<glyph unicode="&#xe041;" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
+<glyph unicode="&#xe042;" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
+<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
+<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
+<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
+<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
+<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
+<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
+<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
+<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
+<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
+<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
+<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
+<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
+<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
+<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
+<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
+<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
+<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
+<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
+<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
+<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
+<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
+<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
+<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
+<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
+<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
+<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
+<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
+<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
+<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
+<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
+<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
+<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
+<glyph unicode="&#xe087;" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
+<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
+<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
+<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
+<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
+<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
+<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
+<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
+<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
+<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
+<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
+<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
+<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
+<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
+<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
+<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
+<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
+<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
+<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
+<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
+<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
+<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
+<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
+<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
+<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
+<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
+<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
+<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
+<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
+<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
+<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
+<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
+<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
+<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
+<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
+<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
+<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
+<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
+<glyph unicode="&#xe130;" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
+<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
+<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
+<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
+<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
+<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
+<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
+<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
+<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
+<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
+<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
+<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
+<glyph unicode="&#xe143;" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
+<glyph unicode="&#xe144;" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
+<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
+<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
+<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
+<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
+<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
+<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
+<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
+<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
+<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
+<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
+<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
+<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
+<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
+<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
+<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
+<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
+<glyph unicode="&#xe162;" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
+<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
+<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
+<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
+<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
+<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
+<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
+<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
+<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
+<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
+<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
+<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
+<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
+<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
+<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
+<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
+<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
+<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
+<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
+<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
+<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
+<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
+<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
+<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
+<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
+</font>
+</defs></svg> 
diff --git a/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.ttf b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.ttf
new file mode 100644 (file)
index 0000000..67fa00b
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.woff b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.woff
new file mode 100644 (file)
index 0000000..8c54182
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/fonts/glyphicons-halflings-regular.woff differ
diff --git a/src/main/resources/META-INF/resources/designer/images/CheckMark.png b/src/main/resources/META-INF/resources/designer/images/CheckMark.png
new file mode 100644 (file)
index 0000000..abc3b86
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/CheckMark.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/DefineDecision.png b/src/main/resources/META-INF/resources/designer/images/DefineDecision.png
new file mode 100644 (file)
index 0000000..eb65e61
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/DefineDecision.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/DefineModifySchema.png b/src/main/resources/META-INF/resources/designer/images/DefineModifySchema.png
new file mode 100644 (file)
index 0000000..de962c3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/DefineModifySchema.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/DefinePID.png b/src/main/resources/META-INF/resources/designer/images/DefinePID.png
new file mode 100644 (file)
index 0000000..be4e817
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/DefinePID.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/DefinePath.png b/src/main/resources/META-INF/resources/designer/images/DefinePath.png
new file mode 100644 (file)
index 0000000..59d38ce
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/DefinePath.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/DefineServiceAcronym.png b/src/main/resources/META-INF/resources/designer/images/DefineServiceAcronym.png
new file mode 100644 (file)
index 0000000..cf37444
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/DefineServiceAcronym.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/GOC.png b/src/main/resources/META-INF/resources/designer/images/GOC.png
new file mode 100644 (file)
index 0000000..cdd16f3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/GOC.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/ImportSchema.png b/src/main/resources/META-INF/resources/designer/images/ImportSchema.png
new file mode 100644 (file)
index 0000000..6afd1bd
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/ImportSchema.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/InitialProcess.png b/src/main/resources/META-INF/resources/designer/images/InitialProcess.png
new file mode 100644 (file)
index 0000000..9eacb9d
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/InitialProcess.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/MultiBranchConnector.png b/src/main/resources/META-INF/resources/designer/images/MultiBranchConnector.png
new file mode 100644 (file)
index 0000000..3d45112
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/MultiBranchConnector.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/ParentNode.png b/src/main/resources/META-INF/resources/designer/images/ParentNode.png
new file mode 100644 (file)
index 0000000..cc05988
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/ParentNode.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/ProcessCall.png b/src/main/resources/META-INF/resources/designer/images/ProcessCall.png
new file mode 100644 (file)
index 0000000..f0d3044
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/ProcessCall.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/SetDefaultValues.png b/src/main/resources/META-INF/resources/designer/images/SetDefaultValues.png
new file mode 100644 (file)
index 0000000..6435fe9
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/SetDefaultValues.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/TrueFalseCondition.png b/src/main/resources/META-INF/resources/designer/images/TrueFalseCondition.png
new file mode 100644 (file)
index 0000000..0a653b8
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/TrueFalseCondition.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/UpgradeSchema.png b/src/main/resources/META-INF/resources/designer/images/UpgradeSchema.png
new file mode 100644 (file)
index 0000000..0bf4d5c
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/UpgradeSchema.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/clds-collector-icon.png b/src/main/resources/META-INF/resources/designer/images/clds-collector-icon.png
new file mode 100644 (file)
index 0000000..0bd2a5f
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/clds-collector-icon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/clds-policy-icon.png b/src/main/resources/META-INF/resources/designer/images/clds-policy-icon.png
new file mode 100644 (file)
index 0000000..b23a572
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/clds-policy-icon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/clds-prop-icon.png b/src/main/resources/META-INF/resources/designer/images/clds-prop-icon.png
new file mode 100644 (file)
index 0000000..68dd437
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/clds-prop-icon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/clds-string-match-icon.png b/src/main/resources/META-INF/resources/designer/images/clds-string-match-icon.png
new file mode 100644 (file)
index 0000000..6b00414
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/clds-string-match-icon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/clds-tca-icon.png b/src/main/resources/META-INF/resources/designer/images/clds-tca-icon.png
new file mode 100644 (file)
index 0000000..f321ee3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/clds-tca-icon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/favicon.png b/src/main/resources/META-INF/resources/designer/images/favicon.png
new file mode 100644 (file)
index 0000000..415f56c
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/favicon.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/img_ie.png b/src/main/resources/META-INF/resources/designer/images/img_ie.png
new file mode 100644 (file)
index 0000000..af68e25
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/img_ie.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/img_mozila.png b/src/main/resources/META-INF/resources/designer/images/img_mozila.png
new file mode 100644 (file)
index 0000000..abafc02
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/img_mozila.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/itrack.png b/src/main/resources/META-INF/resources/designer/images/itrack.png
new file mode 100644 (file)
index 0000000..c63a4ae
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/itrack.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/logo_onap_2017.png b/src/main/resources/META-INF/resources/designer/images/logo_onap_2017.png
new file mode 100644 (file)
index 0000000..c6f6857
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/logo_onap_2017.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/page_under_construction.png b/src/main/resources/META-INF/resources/designer/images/page_under_construction.png
new file mode 100644 (file)
index 0000000..e4d1cc3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/page_under_construction.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/preffered.png b/src/main/resources/META-INF/resources/designer/images/preffered.png
new file mode 100644 (file)
index 0000000..d5c8b5a
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/preffered.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/sort_asc.png b/src/main/resources/META-INF/resources/designer/images/sort_asc.png
new file mode 100644 (file)
index 0000000..a56d0e2
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/sort_asc.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/sort_asc_disabled.png b/src/main/resources/META-INF/resources/designer/images/sort_asc_disabled.png
new file mode 100644 (file)
index 0000000..b7e621e
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/sort_asc_disabled.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/sort_both.png b/src/main/resources/META-INF/resources/designer/images/sort_both.png
new file mode 100644 (file)
index 0000000..839ac4b
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/sort_both.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/sort_desc.png b/src/main/resources/META-INF/resources/designer/images/sort_desc.png
new file mode 100644 (file)
index 0000000..90b2951
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/sort_desc.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/sort_desc_disabled.png b/src/main/resources/META-INF/resources/designer/images/sort_desc_disabled.png
new file mode 100644 (file)
index 0000000..2409653
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/sort_desc_disabled.png differ
diff --git a/src/main/resources/META-INF/resources/designer/images/th.png b/src/main/resources/META-INF/resources/designer/images/th.png
new file mode 100644 (file)
index 0000000..4892461
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/images/th.png differ
diff --git a/src/main/resources/META-INF/resources/designer/index.html b/src/main/resources/META-INF/resources/designer/index.html
new file mode 100644 (file)
index 0000000..a63bfd6
--- /dev/null
@@ -0,0 +1,226 @@
+
+<!-- Do not delete below line: This code helped to display worning on IE8 -->
+<!--[if lte IE 8 ]>
+         <meta http-equiv="refresh" content="0;url=/utm-ui/unsupportedbrowser.html"/>          
+    <![endif]-->
+
+
+<!DOCTYPE html>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+
+<html lang="en" ng-app="clds-app">
+
+<head>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport"
+       content="width=device-width, initial-scale=1.0, maximum-scale=1">
+<meta name="description" content="">
+<meta name="author" content="">
+<link rel="shortcut icon" href="images/favicon.png">
+
+<title>CLDS</title>
+
+
+<!-- bootstrap css and plugins -->
+<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
+
+<!-- DataTables CSS -->
+<link href="css/dataTables.bootstrap.css" rel="stylesheet">
+<link href="css/jquery.dataTables.css" rel="stylesheet">
+
+<link href="css/dataTables.tableTools.css" rel="stylesheet">
+<link href="css/dataTables.fixedColumns.css" rel="stylesheet">
+
+
+<link href="css/loading-bar.css" rel="stylesheet">
+<link href="css/jasny-bootstrap.css" rel="stylesheet">
+<link href="css/navmenu.css" rel="stylesheet">
+<link href="css/dialogs.css" rel="stylesheet">
+
+
+
+
+<link href="css/plugins/morris.css" rel="stylesheet">
+<link href="fonts/font-awesome-4.1.0/css/font-awesome.min.css"
+       rel="stylesheet" type="text/css">
+
+
+<link href="css/carousel/slick.css" rel="stylesheet">
+<link href="css/utm_custom_style.css" rel="stylesheet">
+<link href="css/AdminLTE.css" rel="stylesheet" type="text/css" />
+<link href="css/angucomplete.css" rel="stylesheet" type="text/css" />
+
+<link href="css/ui-grid.css" rel="stylesheet">
+<link href="css/ui-grid-stable.css" rel="stylesheet">
+<link href="css/ui-grid-unstable.css" rel="stylesheet">
+<link href="css/multi-select.css" rel="stylesheet">
+</head>
+
+
+<body>
+<button id="cldsopendiagrambtn" style="display:none"/>
+<button id="cldsgetdiagrambtn" style="display:none"/>
+
+
+       
+
+
+       <div ng-controller="dialogCtrl" style="display: none;">
+               <div class="row">
+                       <div class="col-md-12">
+                               <button class="btn btn-danger" ng-click="launch('error')" style="display:none">Error
+                                       Dialog</button>
+                               <button class="btn btn-primary" ng-click="launch('wait')" style="display:none">Wait
+                                       Dialog</button>
+                               <button class="btn btn-primary" ng-click="launch('customwait')" style="display:none">"Custom"
+                                       Wait Dialog</button>
+                               <button class="btn btn-default" ng-click="launch('notify')" style="display:none">Notify
+                                       Dialog</button>
+                               <button class="btn btn-success" ng-click="launch('confirm')" style="display:none">Confirm
+                                       Dialog</button>
+                       </div>
+               </div>
+       </div>
+
+
+       <div ng-controller="AuthenticateCtrl" ng-include="getInclude()"
+               style="width: 100%; height: 100%"></div>
+    
+       <script src="lib/jquery.min.js"></script>
+       <script src="lib/angular.min.js"></script>
+       <script src="lib/angular-cookies.js"></script>
+
+       <!--  <script src="lib/angular.min.js"></script>-->
+       <script src="lib/angular-route.js"></script>
+       <script src="lib/angular-resource.min.js"></script>
+
+       <!-- jQuery Include and Bootstrap -->
+
+       
+       <script src="lib/bootstrap.min.js"></script>
+
+       <script type="text/javascript" src="lib/angular-sanitize.js"></script>
+       <script type="text/javascript" src="lib/angular-touch.min.js"></script>
+       <script type="text/javascript" src="lib/angular-animate.js"></script>
+       <script type="text/javascript" src="lib/lodash.min.js"></script>
+       <script type="text/javascript" src="lib/angular-highlightjs.js"></script>
+       <script type="text/javascript" src="lib/ui-bootstrap-tpls.js"></script>
+
+
+       <script src="lib/angular-vs-repeat.js"></script>
+
+       <script src="lib/angularjs-dropdown-multiselect.js"></script>
+       <script src="lib/angularjs-dropdown-multiselect-new.js"></script>
+       <script src="lib/angularjs-dropdown-multiselect-old.js"></script>
+
+       <script src="lib/moment.min.js"></script>
+       <script src="lib/loading-bar.js"></script>
+       <!-- <script src="lib/jasny-bootstrap.js"></script> -->
+
+       <script src="lib/dialogs.js"></script>
+       <script src="lib/ui-grid-stable.js"></script>
+       <script src="lib/ui-grid-unstable.js"></script>
+       <script src="lib/multiselect.js"></script>
+       <script type="text/javascript" src="lib/angucomplete.js"></script>
+
+       <!-- Start Up Files -->
+       <script src="scripts/app.js"></script>
+       <script src="scripts/route_ctrl.js"></script>
+       <script src="scripts/authcontroller.js"></script>
+       
+
+       
+       <script src="scripts/query_params_handler_ctrl.js"></script>
+       
+        <script src="scripts/under_construction_ctrl.js"></script> 
+        
+       
+
+       <script src="scripts/DashboardCtrl.js"></script>
+
+       <!--    File Upload start -->
+       <script src="scripts/FileUploadService.js"></script>
+       <script src="scripts/FileUploadCtrl.js"></script>
+       <!--    File Upload end -->
+
+       
+       <!--    Export File  start -->
+       <script src="scripts/ExportFileService.js"></script>
+       <script src="scripts/ExportFileCtrl.js"></script>
+       <!--    Export File end -->
+       
+       
+       
+       <!--  Activity Modelling start -->
+       <script src="scripts/ActivityModellingCtrl.js"></script>
+       <!--  Activity Modelling end -->
+       
+       <!--  Property Explorer Controller start -->
+       <script src="scripts/propertyExplorerCtrl.js"></script>
+       <!--  Property Explorer Controller end -->
+       
+       
+       
+       <!--    dialog box ctl start -->
+       <script type="text/javascript" src="scripts/common_variables.js"></script>
+       <!-- <script src="scripts/ImportProjectCtrl.js"></script> -->
+     <script src="scripts/CldsOpenModelCtrl.js"></script>
+     <script src="scripts/CldsModelService.js"></script>
+     
+     <script src="scripts/ImportSchemaCtrl.js"></script>
+     
+     <script src="scripts/importSchemaService.js"></script>
+     
+     <script src="scripts/UpgradeSchemaCtrl.js"></script>
+     
+     <script src="scripts/commonService.js"></script>
+     
+     <script src="scripts/soapRequestService.js"></script>
+    
+     <script src="scripts/dataFactory.js"></script>
+     
+     <script src="scripts/textAreaCtrl.js"></script>
+     
+     <script src="scripts/AutosaveProjectCtrl.js"></script>
+     <script src="scripts/userPreferencesService.js"></script>
+     
+     <script src="scripts/saveConfirmationModalPopUpCtrl.js"></script>
+     <script src="scripts/CldsTemplateService.js"></script>
+     <script src="scripts/CldsOpenTemplateCtrl.js"></script>
+     <script src="scripts/GlobalPropertiesCtrl.js"></script>
+     <script src="scripts/AlertService.js"></script>
+
+    <!--    dialog box ctl end -->
+    <link rel="stylesheet" href="css/kendo.material.min.css">
+    <link rel="stylesheet" href="css/kendo.common-material.core.css">
+    <script src="scripts/kendo.custom.min.js"></script>
+    <script src="./index.js"></script>
+    <script src="scripts/aOnBoot.js"></script>
+        
+        
+</body>
diff --git a/src/main/resources/META-INF/resources/designer/index.js b/src/main/resources/META-INF/resources/designer/index.js
new file mode 100644 (file)
index 0000000..15425dd
--- /dev/null
@@ -0,0 +1,67923 @@
+function activateMenu(){
+       isImportSchema = true;  
+}
+var abootDiagram=null;
+
+function cldsOpenDiagram(modelXml)
+{
+       cldsModelXml = modelXml;
+       console.log("cldsOpenDiagram: cldsModelXml=" + cldsModelXml);
+       $("#cldsopendiagrambtn").click();
+}
+function cldsGetDiagram()
+{
+       console.log("cldsGetDiagram: starting...");
+       $("#cldsgetdiagrambtn").click();
+       console.log("cldsGetDiagram: modelXML=" + modelXML);
+       return modelXML;
+}
+function uploaddata(file)
+{
+       uploadfile= file;
+       $("#uploadmodel").click();
+       
+}
+function visibility_model()
+{      
+       $("#openmodel").click();
+       
+}
+(function e(t, n, r) {
+    function s(o, u) {
+        if (!n[o]) {
+            if (!t[o]) {
+                var a = typeof require == "function" && require;
+                if (!u && a) return a(o, !0);
+                if (i) return i(o, !0);
+                var f = new Error("Cannot find module '" + o + "'");
+                throw f.code = "MODULE_NOT_FOUND", f
+            }
+            var l = n[o] = {
+                exports: {}
+            };
+            t[o][0].call(l.exports, function(e) {
+                var n = t[o][1][e];
+                return s(n ? n : e)
+            }, l, l.exports, e, t, n, r)
+        }
+        return n[o].exports
+    }
+    var i = typeof require == "function" && require;
+    for (var o = 0; o < r.length; o++) s(r[o]);
+    return s;
+})
+               
+       ({
+    "\\bpmn-js-examples-master\\modeler\\app\\index.js":
+
+       [function(require, module, exports) {
+
+        'use strict';
+
+
+
+        var $ = require('jquery'),
+            BpmnModeler = require('bpmn-js/lib/Modeler');
+
+        var container = $('#js-drop-zone');
+
+        var canvas = $('#js-canvas');
+
+        var renderer = new BpmnModeler({
+            container: canvas
+        });
+        abootDiagram=renderer;
+
+        var newDiagramXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\" id=\"sample-diagram\" targetNamespace=\"http://bpmn.io/schema/bpmn\">\n  <bpmn2:process id=\"Process_1\" isExecutable=\"false\">\n    <bpmn2:startEvent id=\"StartEvent_1\"/>\n  </bpmn2:process>\n  <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">\n    <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\n      <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">\n        <dc:Bounds height=\"36.0\" width=\"36.0\" x=\"25.0\" y=\"240.0\"/>\n      </bpmndi:BPMNShape>\n    </bpmndi:BPMNPlane>\n  </bpmndi:BPMNDiagram>\n</bpmn2:definitions>";
+        //
+        /*file_generate_test_case.addEventListener('click', function(e) {
+               
+
+        });*/
+
+       
+
+        function createNewDiagram(newDiagramXML) {
+            openDiagram(newDiagramXML);
+            
+        }
+       
+        function openDiagram(xml) {
+            renderer.importXML(xml, function(err) {
+
+                if (err) {
+                    container
+                        .removeClass('with-diagram')
+                        .addClass('with-error');
+
+                    container.find('.error pre').text(err.message);
+
+                    console.error(err);
+                } else {
+                    container
+                        .removeClass('with-error')
+                        .addClass('with-diagram');
+                }
+
+
+            });
+        }
+
+        function saveSVG(done) {
+            renderer.saveSVG(done);
+        }
+
+        function saveDiagram(done) {
+
+            renderer.saveXML({
+                format: true
+            }, function(err, xml) {
+                done(err, xml);
+            });
+        }
+       
+
+        function registerFileDrop(container, callback) {
+
+            function handleFileSelect(e) {
+                e.stopPropagation();
+                e.preventDefault();
+
+                var files = e.dataTransfer.files;
+
+                var file = files[0];
+
+                var reader = new FileReader();
+
+                reader.onload = function(e) {
+
+                    var xml = e.target.result;
+
+                    callback(xml);
+                };
+
+                reader.readAsText(file);
+            }
+
+            function handleDragOver(e) {
+                e.stopPropagation();
+                e.preventDefault();
+
+                e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
+            }
+            if(container.get(0)){
+              container.get(0).addEventListener('dragover', handleDragOver, false);
+              container.get(0).addEventListener('drop', handleFileSelect, false);  
+            }            
+        }
+
+
+        // //// file drag / drop ///////////////////////
+
+        // check file api availability
+        if (!window.FileList || !window.FileReader) {
+            window.alert(
+                'Looks like you use an older browser that does not support drag and drop. ' +
+                'Try using Chrome, Firefox or the Internet Explorer > 10.');
+        } else {
+            registerFileDrop(container, openDiagram);
+        }
+
+        // bootstrap diagram functions
+        function openNewWin(linkURL) {
+               window.open(""+linkURL+"","_self"/*, "", "scrollbars, top="+winTop+", left="+winLeft+", height="+winHeight+", width="+winWidth+""*/);
+               }
+
+        
+        $(document).on('ready', function(e) {
+
+            /* $('#js-create-diagram').click(function(e) {*/
+            e.stopPropagation();
+            e.preventDefault();
+
+            createNewDiagram(newDiagramXML);
+            
+            /*});*/
+            var fileInput = document.getElementById('fileInput');
+            var file_generate_test_case = document.getElementById('file_generate_test_case');
+           
+            var downloadLink = $('#js-download-diagram');
+            var downloadSvgLink = $('#js-download-svg');
+            var readLink = $('#file_generate_test_case');
+            $('.buttons a').click(function(e) {
+                if (!$(this).is('.active')) {
+                    e.preventDefault();
+                    e.stopPropagation();
+                }
+            });
+            $('#openmodel').click(function() {
+               
+               createNewDiagram(modelXML);
+               
+            }
+               );
+               
+            $('#cldsgetdiagrambtn').click(function() {
+                               console.log("cldsgetdiagrambtn: starting...");
+                               exportArtifacts();
+                               console.log("cldsgetdiagrambtn: modelXML=" + modelXML);
+              });
+            $('#cldsopendiagrambtn').click(function() {
+                               console.log("cldsopendiagrambtn: cldsModelXml=" + cldsModelXml);
+                createNewDiagram(cldsModelXml);
+                exportArtifacts();
+              });
+            $('#uploadmodel').click(function() {
+                var file = uploadfile;
+                var textType = /text.*/;
+
+                var reader = new FileReader();
+
+                reader.onload = function(e) {
+                    newDiagramXML = reader.result;
+                    e.stopPropagation();
+                    e.preventDefault();
+                    createNewDiagram(newDiagramXML);
+                    
+                }
+
+                reader.readAsText(file);
+                exportArtifacts();
+              });
+           if(fileInput){
+              fileInput.addEventListener('change', function(e) {
+                  var file = fileInput.files[0];
+                  var textType = /text.*/;
+
+
+                  var reader = new FileReader();
+
+                  reader.onload = function(e) {
+                      newDiagramXML = reader.result;
+                      e.stopPropagation();
+                      e.preventDefault();
+                      createNewDiagram(newDiagramXML);
+                      
+                  }
+
+                  reader.readAsText(file);
+                  exportArtifacts();
+              }); 
+           }
+           
+           function setEncoded(link, name, data) {
+                var encodedData = encodeURIComponent(data);
+               
+                var el=document.getElementById(selected_model);
+               var text = (el.innerText || el.textContent);
+                
+               
+                if (data) {
+                       //var linkURL='data:application/bpmn20-xml;charset=UTF-8,' + encodedData;
+                    link.addClass('active').attr({
+                        'href':'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,/*openNewWin( linkURL )*//*'*/
+                        'download': text.trim()+'.utmxml',
+                        'target':'_blank'
+                    });
+                    
+                } else {
+                    link.removeClass('active');
+                }
+            }
+            function setReadEncoded(link, name, data) {
+                var encodedData = encodeURIComponent(data);
+                
+                if (data) {
+                    link.addClass('active').attr({
+                       'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
+                        'download': name
+                    });
+                    
+                    
+                } else {
+                    link.removeClass('active');
+                }
+            }
+            var _ = require('lodash');
+           /*var model = $( "#modelName" ).val();
+           */
+
+            var exportArtifacts = _.debounce(function() {
+
+                saveSVG(function(err, svg) {
+                    setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg);
+                });
+
+                saveDiagram(function(err, xml) {
+                    setEncoded(downloadLink, "model.utmxml", err ? null : xml);
+                });
+               
+            }, 500);
+
+            renderer.on('commandStack.changed', exportArtifacts);
+        });
+    }, {
+        "bpmn-js/lib/Modeler": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\Modeler.js",
+        "jquery": "\\bpmn-js-examples-master\\modeler\\node_modules\\jquery\\dist\\jquery.js",
+        "lodash": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\Modeler.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var IdSupport = require('bpmn-moddle/lib/id-support'),
+            Ids = require('ids');
+
+        var Viewer = require('./Viewer');
+
+        var initialDiagram =
+            '<?xml version="1.0" encoding="UTF-8"?>' +
+            '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+            'xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" ' +
+            'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" ' +
+            'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' +
+            'targetNamespace="http://bpmn.io/schema/bpmn" ' +
+            'id="Definitions_1">' +
+            '<bpmn:process id="Process_1" isExecutable="false">' +
+            '<bpmn:startEvent id="StartEvent_1"/>' +
+            '</bpmn:process>' +
+            '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' +
+            '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' +
+            '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' +
+            '<dc:Bounds height="36.0" width="36.0" x="50.0" y="102.0"/>' +
+            '</bpmndi:BPMNShape>' +
+            '</bpmndi:BPMNPlane>' +
+            '</bpmndi:BPMNDiagram>' +
+            '</bpmn:definitions>';
+
+
+        /**
+         * A modeler for BPMN 2.0 diagrams.
+         * 
+         *  ## Extending the Modeler
+         * 
+         * In order to extend the viewer pass extension modules to bootstrap via the
+         * `additionalModules` option. An extension module is an object that exposes
+         * named services.
+         * 
+         * The following example depicts the integration of a simple logging component
+         * that integrates with interaction events:
+         * 
+         * 
+         * ```javascript
+         *  // logging component function InteractionLogger(eventBus) {
+         * eventBus.on('element.hover', function(event) { console.log() }) }
+         * 
+         * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
+         *  // extension module var extensionModule = { __init__: [ 'interactionLogger' ],
+         * interactionLogger: [ 'type', InteractionLogger ] };
+         *  // extend the viewer var bpmnModeler = new Modeler({ additionalModules: [
+         * extensionModule ] }); bpmnModeler.importXML(...); ```
+         * 
+         *  ## Customizing / Replacing Components
+         * 
+         * You can replace individual diagram components by redefining them in override
+         * modules. This works for all components, including those defined in the core.
+         * 
+         * Pass in override modules via the `options.additionalModules` flag like this:
+         * 
+         * ```javascript function CustomContextPadProvider(contextPad) {
+         * 
+         * contextPad.registerProvider(this);
+         * 
+         * this.getContextPadEntries = function(element) { // no entries, effectively
+         * disable the context pad return {}; }; }
+         * 
+         * CustomContextPadProvider.$inject = [ 'contextPad' ];
+         * 
+         * var overrideModule = { contextPadProvider: [ 'type', CustomContextPadProvider ] };
+         * 
+         * var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]}); ```
+         * 
+         * @param {Object}
+         *            [options] configuration options to pass to the viewer
+         * @param {DOMElement}
+         *            [options.container] the container to render the viewer in,
+         *            defaults to body.
+         * @param {String|Number}
+         *            [options.width] the width of the viewer
+         * @param {String|Number}
+         *            [options.height] the height of the viewer
+         * @param {Object}
+         *            [options.moddleExtensions] extension packages to provide
+         * @param {Array
+         *            <didi.Module>} [options.modules] a list of modules to override the
+         *            default modules
+         * @param {Array
+         *            <didi.Module>} [options.additionalModules] a list of modules to
+         *            use with the default modules
+         */
+        function Modeler(options) {
+            Viewer.call(this, options);
+        }
+
+        inherits(Modeler, Viewer);
+
+        Modeler.prototype.createDiagram = function(done) {
+            return this.importXML(initialDiagram, done);
+        };
+
+        Modeler.prototype.createModdle = function() {
+            var moddle = Viewer.prototype.createModdle.call(this);
+
+            IdSupport.extend(moddle, new Ids([32, 36, 1]));
+
+            return moddle;
+        };
+
+
+        Modeler.prototype._interactionModules = [
+            // non-modeling components
+            require('./features/label-editing'),
+            require('./features/keyboard'),
+            require('diagram-js/lib/navigation/zoomscroll'),
+            require('diagram-js/lib/navigation/movecanvas'),
+            require('diagram-js/lib/navigation/touch')
+        ];
+
+        Modeler.prototype._modelingModules = [
+            // modeling components
+            require('diagram-js/lib/features/move'),
+            require('diagram-js/lib/features/bendpoints'),
+            require('diagram-js/lib/features/resize'),
+            require('diagram-js/lib/features/space-tool'),
+            require('diagram-js/lib/features/lasso-tool'),
+            //require('./features/keyboard'),
+            require('./features/snapping'),
+            require('./features/modeling'),
+            require('./features/context-pad'),
+            require('./features/palette')
+        ];
+
+
+        // modules the modeler is composed of
+        //
+        // - viewer modules
+        // - interaction modules
+        // - modeling modules
+
+        Modeler.prototype._modules = [].concat(
+            Modeler.prototype._modules,
+            Modeler.prototype._interactionModules,
+            Modeler.prototype._modelingModules);
+
+
+        module.exports = Modeler;
+
+    }, {
+        "./Viewer": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\Viewer.js",
+        "./features/context-pad": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\context-pad\\index.js",
+        "./features/keyboard": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\keyboard\\index.js",
+        "./features/label-editing": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\index.js",
+        "./features/modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\index.js",
+        "./features/palette": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\palette\\index.js",
+        "./features/snapping": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\snapping\\index.js",
+        "bpmn-moddle/lib/id-support": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\id-support.js",
+        "diagram-js/lib/features/bendpoints": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\index.js",
+        "diagram-js/lib/features/lasso-tool": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\lasso-tool\\index.js",
+        "diagram-js/lib/features/move": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\index.js",
+        "diagram-js/lib/features/resize": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\index.js",
+        "diagram-js/lib/features/space-tool": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\index.js",
+        "diagram-js/lib/navigation/movecanvas": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\movecanvas\\index.js",
+        "diagram-js/lib/navigation/touch": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\touch\\index.js",
+        "diagram-js/lib/navigation/zoomscroll": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\zoomscroll\\index.js",
+        "ids": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\ids\\index.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\Viewer.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            omit = require('lodash/object/omit'),
+            isString = require('lodash/lang/isString'),
+            isNumber = require('lodash/lang/isNumber');
+
+        var domify = require('min-dom/lib/domify'),
+            domQuery = require('min-dom/lib/query'),
+            domRemove = require('min-dom/lib/remove');
+
+        var Diagram = require('diagram-js'),
+            BpmnModdle = require('bpmn-moddle');
+
+        var Importer = require('./import/Importer');
+
+
+        function initListeners(diagram, listeners) {
+            var events = diagram.get('eventBus');
+
+            listeners.forEach(function(l) {
+                events.on(l.event, l.handler);
+            });
+        }
+
+        function checkValidationError(err) {
+
+            // check if we can help the user by indicating wrong BPMN 2.0 xml
+            // (in case he or the exporting tool did not get that right)
+
+            var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
+            var match = pattern.exec(err.message);
+
+            if (match) {
+                err.message =
+                    'unparsable content <' + match[1] + '> detected; ' +
+                    'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
+            }
+
+            return err;
+        }
+
+        var DEFAULT_OPTIONS = {
+            width: '100%',
+            height: '100%',
+            position: 'relative',
+            container: 'body'
+        };
+
+
+
+        /**
+         * Ensure the passed argument is a proper unit (defaulting to px)
+         */
+        function ensureUnit(val) {
+            return val + (isNumber(val) ? 'px' : '');
+        }
+
+        /**
+         * A viewer for BPMN 2.0 diagrams.
+         * 
+         * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that
+         * include additional features.
+         * 
+         *  ## Extending the Viewer
+         * 
+         * In order to extend the viewer pass extension modules to bootstrap via the
+         * `additionalModules` option. An extension module is an object that exposes
+         * named services.
+         * 
+         * The following example depicts the integration of a simple logging component
+         * that integrates with interaction events:
+         * 
+         * 
+         * ```javascript
+         *  // logging component function InteractionLogger(eventBus) {
+         * eventBus.on('element.hover', function(event) { console.log() }) }
+         * 
+         * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
+         *  // extension module var extensionModule = { __init__: [ 'interactionLogger' ],
+         * interactionLogger: [ 'type', InteractionLogger ] };
+         *  // extend the viewer var bpmnViewer = new Viewer({ additionalModules: [
+         * extensionModule ] }); bpmnViewer.importXML(...); ```
+         * 
+         * @param {Object}
+         *            [options] configuration options to pass to the viewer
+         * @param {DOMElement}
+         *            [options.container] the container to render the viewer in,
+         *            defaults to body.
+         * @param {String|Number}
+         *            [options.width] the width of the viewer
+         * @param {String|Number}
+         *            [options.height] the height of the viewer
+         * @param {Object}
+         *            [options.moddleExtensions] extension packages to provide
+         * @param {Array
+         *            <didi.Module>} [options.modules] a list of modules to override the
+         *            default modules
+         * @param {Array
+         *            <didi.Module>} [options.additionalModules] a list of modules to
+         *            use with the default modules
+         */
+        function Viewer(options) {
+
+            this.options = options = assign({}, DEFAULT_OPTIONS, options || {});
+
+            var parent = options.container;
+
+            // support jquery element
+            // unwrap it if passed
+            if (parent.get) {
+                parent = parent.get(0);
+            }
+
+            // support selector
+            if (isString(parent)) {
+                parent = domQuery(parent);
+            }
+
+            var container = this.container = domify('<div class="bjs-container"></div>');
+            if(parent && parent.appendChild){
+              parent.appendChild(container);  
+            }
+            
+
+            assign(container.style, {
+                width: ensureUnit(options.width),
+                height: ensureUnit(options.height),
+                position: options.position
+            });
+
+            /**
+             * The code in the <project-logo></project-logo> area must not be changed,
+             * see http://bpmn.io/license for more information
+             * 
+             * <project-logo>
+             */
+
+            /* jshint -W101 */
+
+            // inlined ../resources/bpmnjs.png
+            var logoData = 'iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAMAAADypuvZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBQTFRFiMte9PrwldFwfcZPqtqN0+zEyOe1XLgjvuKncsJAZ70y6fXh3vDT////UrQV////G2zN+AAAABB0Uk5T////////////////////AOAjXRkAAAHDSURBVHjavJZJkoUgDEBJmAX8979tM8u3E6x20VlYJfFFMoL4vBDxATxZcakIOJTWSmxvKWVIkJ8jHvlRv1F2LFrVISCZI+tCtQx+XfewgVTfyY3plPiQEAzI3zWy+kR6NBhFBYeBuscJLOUuA2WVLpCjVIaFzrNQZArxAZKUQm6gsj37L9Cb7dnIBUKxENaaMJQqMpDXvSL+ktxdGRm2IsKgJGGPg7atwUG5CcFUEuSv+CwQqizTrvDTNXdMU2bMiDWZd8d7QIySWVRsb2vBBioxOFt4OinPBapL+neAb5KL5IJ8szOza2/DYoipUCx+CjO0Bpsv0V6mktNZ+k8rlABlWG0FrOpKYVo8DT3dBeLEjUBAj7moDogVii7nSS9QzZnFcOVBp1g2PyBQ3Vr5aIapN91VJy33HTJLC1iX2FY6F8gRdaAeIEfVONgtFCzZTmoLEdOjBDfsIOA6128gw3eu1shAajdZNAORxuQDJN5A5PbEG6gNIu24QJD5iNyRMZIr6bsHbCtCU/OaOaSvgkUyDMdDa1BXGf5HJ1To+/Ym6mCKT02Y+/Sa126ZKyd3jxhzpc1r8zVL6YM1Qy/kR4ABAFJ6iQUnivhAAAAAAElFTkSuQmCC';
+
+            /* jshint +W101 */
+
+            var linkMarkup =
+                  '<a href="http://bpmn.io" ' +
+                     'target="_blank" ' +
+                     'class="bjs-powered-by" ' +
+                     'title="Powered by bpmn.io" ' +
+                     'style="position: absolute; bottom: 15px; right: 15px; z-index: 100">' +
+                      '<img src="data:image/png;base64,' + logoData + '">' +
+                  '</a>';
+                  if(container && container.appendChild){
+                    container.appendChild(domify(linkMarkup));        
+                  }
+            
+
+            /* </project-logo> */
+        }
+
+        Viewer.prototype.importXML = function(xml, done) {
+
+            var self = this;
+
+            this.moddle = this.createModdle();
+
+            this.moddle.fromXML(xml, 'bpmn:Definitions', function(err, definitions, context) {
+
+                if (err) {
+                    err = checkValidationError(err);
+                    return done(err);
+                }
+
+                var parseWarnings = context.warnings;
+
+                self.importDefinitions(definitions, function(err, importWarnings) {
+                    if (err) {
+                        return done(err);
+                    }
+
+                    done(null, parseWarnings.concat(importWarnings || []));
+                });
+            });
+        };
+
+        Viewer.prototype.saveXML = function(options, done) {
+
+            if (!done) {
+                done = options;
+                options = {};
+            }
+
+            var definitions = this.definitions;
+
+            if (!definitions) {
+                return done(new Error('no definitions loaded'));
+            }
+
+            this.moddle.toXML(definitions, options, done);
+        };
+       
+
+        Viewer.prototype.createModdle = function() {
+            return new BpmnModdle(this.options.moddleExtensions);
+        };
+
+        Viewer.prototype.saveSVG = function(options, done) {
+
+            if (!done) {
+                done = options;
+                options = {};
+            }
+
+            var canvas = this.get('canvas');
+
+            var contentNode = canvas.getDefaultLayer(),
+                defsNode = canvas._svg.select('defs');
+
+            var contents = contentNode.innerSVG(),
+                defs = (defsNode && defsNode.outerSVG()) || '';
+
+            var bbox = contentNode.getBBox();
+
+            var svg =
+                '<?xml version="1.0" encoding="utf-8"?>\n' +
+                '<!-- created with bpmn-js / http://bpmn.io -->\n' +
+                '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
+                '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' +
+                'width="' + bbox.width + '" height="' + bbox.height + '" ' +
+                'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' +
+                defs + contents +
+                '</svg>';
+
+            done(null, svg);
+        };
+
+        Viewer.prototype.get = function(name) {
+
+            if (!this.diagram) {
+                throw new Error('no diagram loaded');
+            }
+
+            return this.diagram.get(name);
+        };
+
+        Viewer.prototype.invoke = function(fn) {
+
+            if (!this.diagram) {
+                throw new Error('no diagram loaded');
+            }
+
+            return this.diagram.invoke(fn);
+        };
+
+        Viewer.prototype.importDefinitions = function(definitions, done) {
+
+            // use try/catch to not swallow synchronous exceptions
+            // that may be raised during model parsing
+            try {
+                if (this.diagram) {
+                    this.clear();
+                }
+
+                this.definitions = definitions;
+
+                var diagram = this.diagram = this._createDiagram(this.options);
+
+                this._init(diagram);
+
+                Importer.importBpmnDiagram(diagram, definitions, done);
+            } catch (e) {
+                done(e);
+            }
+        };
+
+        Viewer.prototype._init = function(diagram) {
+            initListeners(diagram, this.__listeners || []);
+        };
+
+        Viewer.prototype._createDiagram = function(options) {
+
+            var modules = [].concat(options.modules || this.getModules(), options.additionalModules || []);
+
+            // add self as an available service
+            modules.unshift({
+                bpmnjs: ['value', this],
+                moddle: ['value', this.moddle]
+            });
+
+            options = omit(options, 'additionalModules');
+
+            options = assign(options, {
+                canvas: {
+                    container: this.container
+                },
+                modules: modules
+            });
+
+            return new Diagram(options);
+        };
+
+
+        Viewer.prototype.getModules = function() {
+            return this._modules;
+        };
+
+        /**
+         * Remove all drawn elements from the viewer.
+         * 
+         * After calling this method the viewer can still be reused for opening another
+         * diagram.
+         */
+        Viewer.prototype.clear = function() {
+            var diagram = this.diagram;
+
+            if (diagram) {
+                diagram.destroy();
+            }
+        };
+
+        /**
+         * Destroy the viewer instance and remove all its remainders from the document
+         * tree.
+         */
+        Viewer.prototype.destroy = function() {
+            // clear underlying diagram
+            this.clear();
+
+            // remove container
+            domRemove(this.container);
+        };
+
+        /**
+         * Register an event listener on the viewer
+         * 
+         * @param {String}
+         *            event
+         * @param {Function}
+         *            handler
+         */
+        Viewer.prototype.on = function(event, handler) {
+            var diagram = this.diagram,
+                listeners = this.__listeners = this.__listeners || [];
+
+            listeners.push({
+                event: event,
+                handler: handler
+            });
+
+            if (diagram) {
+                diagram.get('eventBus').on(event, handler);
+            }
+        };
+
+        // modules the viewer is composed of
+        Viewer.prototype._modules = [
+            require('./core'),
+            require('diagram-js/lib/features/selection'),
+            require('diagram-js/lib/features/overlays')
+        ];
+
+        module.exports = Viewer;
+
+    }, {
+        "./core": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\core\\index.js",
+        "./import/Importer": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\Importer.js",
+        "bpmn-moddle": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\index.js",
+        "diagram-js": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\index.js",
+        "diagram-js/lib/features/overlays": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\overlays\\index.js",
+        "diagram-js/lib/features/selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js",
+        "lodash/lang/isNumber": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNumber.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/omit": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\omit.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/query": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\query.js",
+        "min-dom/lib/remove": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\remove.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\core\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../draw'),
+                require('../import')
+            ]
+        };
+    }, {
+        "../draw": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\index.js",
+        "../import": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\BpmnRenderer.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits'),
+            isArray = require('lodash/lang/isArray'),
+            isObject = require('lodash/lang/isObject'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach'),
+            every = require('lodash/collection/every'),
+            includes = require('lodash/collection/includes'),
+            some = require('lodash/collection/some');
+
+        var DefaultRenderer = require('diagram-js/lib/draw/Renderer'),
+            TextUtil = require('diagram-js/lib/util/Text'),
+            DiUtil = require('../util/DiUtil');
+
+        var createLine = DefaultRenderer.createLine;
+
+
+        function BpmnRenderer(events, styles, pathMap) {
+
+            DefaultRenderer.call(this, styles);
+
+            var TASK_BORDER_RADIUS = 10;
+            var INNER_OUTER_DIST = 3;
+
+            var LABEL_STYLE = {
+                fontFamily: 'Arial, sans-serif',
+                fontSize: '12px'
+            };
+
+            var textUtil = new TextUtil({
+                style: LABEL_STYLE,
+                size: {
+                    width: 100
+                }
+            });
+
+            var markers = {};
+
+            function addMarker(id, element) {
+                markers[id] = element;
+            }
+
+            function marker(id) {
+                return markers[id];
+            }
+
+            function initMarkers(svg) {
+
+                function createMarker(id, options) {
+                    var attrs = assign({
+                        fill: 'black',
+                        strokeWidth: 1,
+                        strokeLinecap: 'round',
+                        strokeDasharray: 'none'
+                    }, options.attrs);
+
+                    var ref = options.ref || {
+                        x: 0,
+                        y: 0
+                    };
+
+                    var scale = options.scale || 1;
+
+                    // fix for safari / chrome / firefox bug not correctly
+                    // resetting stroke dash array
+                    if (attrs.strokeDasharray === 'none') {
+                        attrs.strokeDasharray = [10000, 1];
+                    }
+
+                    var marker = options.element
+                        .attr(attrs)
+                        .marker(0, 0, 20, 20, ref.x, ref.y)
+                        .attr({
+                            markerWidth: 20 * scale,
+                            markerHeight: 20 * scale
+                        });
+
+                    return addMarker(id, marker);
+                }
+
+
+                createMarker('sequenceflow-end', {
+                    element: svg.path('M 1 5 L 11 10 L 1 15 Z'),
+                    ref: {
+                        x: 11,
+                        y: 10
+                    },
+                    scale: 0.5
+                });
+
+                createMarker('messageflow-start', {
+                    element: svg.circle(6, 6, 3.5),
+                    attrs: {
+                        fill: 'white',
+                        stroke: 'black'
+                    },
+                    ref: {
+                        x: 6,
+                        y: 6
+                    }
+                });
+
+                createMarker('messageflow-end', {
+                    element: svg.path('m 1 5 l 0 -3 l 7 3 l -7 3 z'),
+                    attrs: {
+                        fill: 'white',
+                        stroke: 'black',
+                        strokeLinecap: 'butt'
+                    },
+                    ref: {
+                        x: 8.5,
+                        y: 5
+                    }
+                });
+
+                createMarker('data-association-end', {
+                    element: svg.path('M 1 5 L 11 10 L 1 15'),
+                    attrs: {
+                        fill: 'white',
+                        stroke: 'black'
+                    },
+                    ref: {
+                        x: 11,
+                        y: 10
+                    },
+                    scale: 0.5
+                });
+
+                createMarker('conditional-flow-marker', {
+                    element: svg.path('M 0 10 L 8 6 L 16 10 L 8 14 Z'),
+                    attrs: {
+                        fill: 'white',
+                        stroke: 'black'
+                    },
+                    ref: {
+                        x: -1,
+                        y: 10
+                    },
+                    scale: 0.5
+                });
+
+                createMarker('conditional-default-flow-marker', {
+                    element: svg.path('M 1 4 L 5 16'),
+                    attrs: {
+                        stroke: 'black'
+                    },
+                    ref: {
+                        x: -5,
+                        y: 10
+                    },
+                    scale: 0.5
+                });
+            }
+
+            function computeStyle(custom, traits, defaultStyles) {
+                if (!isArray(traits)) {
+                    defaultStyles = traits;
+                    traits = [];
+                }
+
+                return styles.style(traits || [], assign(defaultStyles, custom || {}));
+            }
+
+            function drawCircle(p, width, height, offset, attrs) {
+
+                if (isObject(offset)) {
+                    attrs = offset;
+                    offset = 0;
+                }
+
+                offset = offset || 0;
+
+                attrs = computeStyle(attrs, {
+                    stroke: 'black',
+                    strokeWidth: 2,
+                    fill: 'white'
+                });
+
+                var cx = width / 2,
+                    cy = height / 2;
+
+                return p.circle(cx, cy, Math.round((width + height) / 4 - offset)).attr(attrs);
+            }
+
+            function drawRect(p, width, height, r, offset, attrs) {
+
+                if (isObject(offset)) {
+                    attrs = offset;
+                    offset = 0;
+                }
+
+                offset = offset || 0;
+
+                attrs = computeStyle(attrs, {
+                    stroke: 'black',
+                    strokeWidth: 2,
+                    fill: 'white'
+                });
+
+                return p.rect(offset, offset, width - offset * 2, height - offset * 2, r).attr(attrs);
+            }
+
+            function drawDiamond(p, width, height, attrs) {
+
+                var x_2 = width / 2;
+                var y_2 = height / 2;
+
+                var points = [x_2, 0, width, y_2, x_2, height, 0, y_2];
+
+                attrs = computeStyle(attrs, {
+                    stroke: 'black',
+                    strokeWidth: 2,
+                    fill: 'white'
+                });
+
+                return p.polygon(points).attr(attrs);
+            }
+
+            function drawLine(p, waypoints, attrs) {
+                attrs = computeStyle(attrs, ['no-fill'], {
+                    stroke: 'black',
+                    strokeWidth: 2,
+                    fill: 'none'
+                });
+
+                return createLine(waypoints, attrs).appendTo(p);
+            }
+
+            function drawPath(p, d, attrs) {
+
+                attrs = computeStyle(attrs, ['no-fill'], {
+                    strokeWidth: 2,
+                    stroke: 'black'
+                });
+
+                return p.path(d).attr(attrs);
+            }
+
+            function as(type) {
+                return function(p, element) {
+                    return handlers[type](p, element);
+                };
+            }
+
+            function renderer(type) {
+                return handlers[type];
+            }
+
+            function renderEventContent(element, p) {
+
+                var event = getSemantic(element);
+                var isThrowing = isThrowEvent(event);
+
+                if (isTypedEvent(event, 'bpmn:MessageEventDefinition')) {
+                    return renderer('bpmn:MessageEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:TimerEventDefinition')) {
+                    return renderer('bpmn:TimerEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:ConditionalEventDefinition')) {
+                    return renderer('bpmn:ConditionalEventDefinition')(p, element);
+                }
+
+                if (isTypedEvent(event, 'bpmn:SignalEventDefinition')) {
+                    return renderer('bpmn:SignalEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:CancelEventDefinition') &&
+                    isTypedEvent(event, 'bpmn:TerminateEventDefinition', {
+                        parallelMultiple: false
+                    })) {
+                    return renderer('bpmn:MultipleEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:CancelEventDefinition') &&
+                    isTypedEvent(event, 'bpmn:TerminateEventDefinition', {
+                        parallelMultiple: true
+                    })) {
+                    return renderer('bpmn:ParallelMultipleEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:EscalationEventDefinition')) {
+                    return renderer('bpmn:EscalationEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:LinkEventDefinition')) {
+                    return renderer('bpmn:LinkEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:ErrorEventDefinition')) {
+                    return renderer('bpmn:ErrorEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:CancelEventDefinition')) {
+                    return renderer('bpmn:CancelEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:CompensateEventDefinition')) {
+                    return renderer('bpmn:CompensateEventDefinition')(p, element, isThrowing);
+                }
+
+                if (isTypedEvent(event, 'bpmn:TerminateEventDefinition')) {
+                    return renderer('bpmn:TerminateEventDefinition')(p, element, isThrowing);
+                }
+
+                return null;
+            }
+
+            function renderLabel(p, label, options) {
+                return textUtil.createText(p, label || '', options).addClass('djs-label');
+            }
+
+            function renderEmbeddedLabel(p, element, align) {
+                var semantic = getSemantic(element);
+                return renderLabel(p, semantic.name, {
+                    box: element,
+                    align: align,
+                    padding: 5
+                });
+            }
+
+            function renderExternalLabel(p, element, align) {
+                var semantic = getSemantic(element);
+
+                if (!semantic.name) {
+                    element.hidden = true;
+                }
+
+                return renderLabel(p, semantic.name, {
+                    box: element,
+                    align: align,
+                    style: {
+                        fontSize: '11px'
+                    }
+                });
+            }
+
+            function renderLaneLabel(p, text, element) {
+                var textBox = renderLabel(p, text, {
+                    box: {
+                        height: 30,
+                        width: element.height
+                    },
+                    align: 'center-middle'
+                });
+
+                var top = -1 * element.height;
+                textBox.transform(
+                    'rotate(270) ' +
+                    'translate(' + top + ',' + 0 + ')'
+                );
+            }
+
+            function createPathFromConnection(connection) {
+                var waypoints = connection.waypoints;
+
+                var pathData = 'm  ' + waypoints[0].x + ',' + waypoints[0].y;
+                for (var i = 1; i < waypoints.length; i++) {
+                    pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
+                }
+                return pathData;
+            }
+
+            var handlers = {
+                'bpmn:Event': function(p, element, attrs) {
+                    return drawCircle(p, element.width, element.height, attrs);
+                },
+                'bpmn:StartEvent': function(p, element) {
+                    var attrs = {};
+                    var semantic = getSemantic(element);
+
+                    if (!semantic.isInterrupting) {
+                        attrs = {
+                            strokeDasharray: '6',
+                            strokeLinecap: 'round'
+                        };
+                    }
+
+                    var circle = renderer('bpmn:Event')(p, element, attrs);
+
+                    renderEventContent(element, p);
+
+                    return circle;
+                },
+                
+                'bpmn:MultiBranchConnector': function(p, element) {
+                    var attrs = {};
+                    element.height=80;
+                    element.width=80;
+                    var semantic = getSemantic(element);
+
+                    if (!semantic.isInterrupting) {
+                        attrs = {
+                            strokeDasharray: '6',
+                            strokeLinecap: 'round'
+                        };
+                    }
+
+                    var circle = renderer('bpmn:Event')(p, element, attrs);
+                    var height = element.height/2;
+                    var width = element.width/2;
+                    var value=Math.round((height+width)/4);
+                    drawLine(p, [{
+                        x: 0,
+                        y: Math.round(element.height / 2)
+                    }, {
+                        x: element.width,
+                        y: Math.round(element.height / 2)
+                    }]);
+                   drawLine(p, [{
+                        x: Math.round(element.width / 2),
+                        y: 0
+                    }, {
+                        x: Math.round(element.width / 2),
+                        y: element.height
+                    }]);
+                    renderEventContent(element, p);
+
+                    return circle;
+                },
+                'bpmn:ParentReturn': function(p, element) {
+                    var attrs = {};
+                    var semantic = getSemantic(element);
+
+                    if (!semantic.isInterrupting) {
+                        attrs = {
+                            strokeDasharray: '6',
+                            strokeLinecap: 'round'
+                        };
+                    }
+
+                    // var circle = renderer('bpmn:Event')(p, element, attrs);
+                    drawLine(p, [{
+                        x: 0,
+                        y: 0
+                    }, {
+                        x: 0,
+                        y: element.height / 2
+                    }]);
+                    drawLine(p, [{
+                        x: 0,
+                        y: element.height / 2
+                    }, {
+                        x: element.width / 2,
+                        y: element.height
+                    }]);
+                    drawLine(p, [{
+                        x: 0,
+                        y: 0
+                    }, {
+                        x: element.width,
+                        y: 0
+                    }]);
+                    drawLine(p, [{
+                        x: element.width,
+                        y: 0
+                    }, {
+                        x: element.width,
+                        y: element.height / 2
+                    }]);
+                    drawLine(p, [
+
+                        {
+                            x: element.width,
+                            y: element.height / 2
+                        }, {
+                            x: element.width / 2,
+                            y: element.height
+                        }
+                    ]);
+                    var text2 = getSemantic(element).name;
+                    renderLabel(p, text2, {
+                        box: element,
+                        align: 'center'
+                    });
+                    renderEventContent(element, p);
+
+                    return p;
+                },
+                'bpmn:SubProcessCall': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        drawLine(p, [{
+                            x: 20,
+                            y: 0
+                        }, {
+                            x: 20,
+                            y: element.height
+                        }]);
+
+                        drawLine(p, [{
+                            x: element.width - 20,
+                            y: 0
+                        }, {
+                            x: element.width - 20,
+                            y: element.height
+                        }]);
+
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+
+                        /*
+                         * var text = getSemantic(element).name; renderLaneLabel(p,
+                         * text, element);
+                         */
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                'bpmn:InitiateProcess': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+                                       openDiagram(newDiagramXML);
+                    if (expandedPool) {
+                        drawLine(p, [{
+                             x: 0,
+                             y: 20
+                         }, {
+                             x: element.width,
+                             y: 20
+                         }]);
+
+                         drawLine(p, [{
+                             x: 20,
+                             y: 0
+                         }, {
+                             x: 20,
+                             y: element.height
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                'bpmn:Collector': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        drawLine(p, [{
+                             x: element.width,
+                             y: 80
+                         }, {
+                             x: element.width,
+                             y: 20
+                         }]);
+
+                         drawLine(p, [{
+                             x: 20,
+                             y: 0
+                         }, {
+                             x: 20,
+                             y: element.height
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         if(text2 == undefined )
+                               {
+                                 text2 = 'Collector';
+                               }
+                        
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                                'bpmn:StringMatch': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        
+                        
+
+                         drawLine(p, [{
+                             x: 0,
+                             y: 20
+                         }, {
+                             x: element.width,
+                             y: 20
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         if(text2 == undefined )
+                       {
+                         text2 = 'StringMatch';
+                       }
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                'bpmn:TCA': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        
+
+                         drawLine(p, [{
+                                x: 0,
+                             y: element.height - 20
+                         }, {
+                             x: element.width,
+                             y: element.height - 20
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         if(text2 == undefined )
+                       {
+                         text2 = 'TCA';
+                       }
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                               'bpmn:GOC': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        
+                        
+
+                         drawLine(p, [{
+                             x: element.width/2,
+                             y: element.height
+                         }, {
+                             x: element.width,
+                             y: element.height/2
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         if(text2 == undefined )
+                       {
+                         text2 = 'GOC';
+                       }
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                               'bpmn:Policy': function(p, element) {
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        
+                        
+
+                         drawLine(p, [{
+                             x: 0,
+                             y: element.height/2
+                         }, {
+                             x: element.width/2,
+                             y: 0
+                         }]);
+                         var text2 = getSemantic(element).name;
+                         if(text2 == undefined )
+                       {
+                         text2 = 'Policy';
+                       }
+                         renderLabel(p, text2, {
+                             box: element,
+                             align: 'center-middle'
+                         });
+                         
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+
+
+                },
+                'bpmn:MessageEventDefinition': function(p, element, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
+                        xScaleFactor: 0.9,
+                        yScaleFactor: 0.9,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.235,
+                            my: 0.315
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'white';
+                    var stroke = isThrowing ? 'white' : 'black';
+
+                    var messagePath = drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill,
+                        stroke: stroke
+                    });
+
+                    return messagePath;
+                },
+                'bpmn:TimerEventDefinition': function(p, element) {
+
+                    var circle = drawCircle(p, element.width, element.height, 0.2 * element.height, {
+                        strokeWidth: 2
+                    });
+
+                    var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
+                        xScaleFactor: 0.75,
+                        yScaleFactor: 0.75,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.5,
+                            my: 0.5
+                        }
+                    });
+
+                    drawPath(p, pathData, {
+                        strokeWidth: 2,
+                        strokeLinecap: 'square'
+                    });
+
+                    for (var i = 0; i < 12; i++) {
+
+                        var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
+                            xScaleFactor: 0.75,
+                            yScaleFactor: 0.75,
+                            containerWidth: element.width,
+                            containerHeight: element.height,
+                            position: {
+                                mx: 0.5,
+                                my: 0.5
+                            }
+                        });
+
+                        var width = element.width / 2;
+                        var height = element.height / 2;
+
+                        drawPath(p, linePathData, {
+                            strokeWidth: 1,
+                            strokeLinecap: 'square',
+                            transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')'
+                        });
+                    }
+
+                    return circle;
+                },
+                'bpmn:EscalationEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.5,
+                            my: 0.555
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:ConditionalEventDefinition': function(p, event) {
+                    var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.5,
+                            my: 0.222
+                        }
+                    });
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1
+                    });
+                },
+                'bpmn:LinkEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_LINK', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.57,
+                            my: 0.263
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:ErrorEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_ERROR', {
+                        xScaleFactor: 1.1,
+                        yScaleFactor: 1.1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.2,
+                            my: 0.722
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:CancelEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
+                        xScaleFactor: 1.0,
+                        yScaleFactor: 1.0,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.638,
+                            my: -0.055
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    }).transform('rotate(45)');
+                },
+                'bpmn:CompensateEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.201,
+                            my: 0.472
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:SignalEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
+                        xScaleFactor: 0.9,
+                        yScaleFactor: 0.9,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.5,
+                            my: 0.2
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:MultipleEventDefinition': function(p, event, isThrowing) {
+                    var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
+                        xScaleFactor: 1.1,
+                        yScaleFactor: 1.1,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.222,
+                            my: 0.36
+                        }
+                    });
+
+                    var fill = isThrowing ? 'black' : 'none';
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: fill
+                    });
+                },
+                'bpmn:ParallelMultipleEventDefinition': function(p, event) {
+                    var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
+                        xScaleFactor: 1.2,
+                        yScaleFactor: 1.2,
+                        containerWidth: event.width,
+                        containerHeight: event.height,
+                        position: {
+                            mx: 0.458,
+                            my: 0.194
+                        }
+                    });
+
+                    return drawPath(p, pathData, {
+                        strokeWidth: 1
+                    });
+                },
+                'bpmn:EndEvent': function(p, element) {
+                    var circle = renderer('bpmn:Event')(p, element, {
+                        strokeWidth: 4
+                    });
+
+                    renderEventContent(element, p, true);
+
+                    return circle;
+                },
+                'bpmn:TerminateEventDefinition': function(p, element) {
+                    var circle = drawCircle(p, element.width, element.height, 8, {
+                        strokeWidth: 4,
+                        fill: 'black'
+                    });
+
+                    return circle;
+                },
+                'bpmn:IntermediateEvent': function(p, element) {
+                    var outer = renderer('bpmn:Event')(p, element, {
+                        strokeWidth: 1
+                    });
+                    /* inner */
+                    drawCircle(p, element.width, element.height, INNER_OUTER_DIST, {
+                        strokeWidth: 1,
+                        fill: 'none'
+                    });
+
+                    renderEventContent(element, p);
+
+                    return outer;
+                },
+                'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
+                'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
+
+                'bpmn:Activity': function(p, element, attrs) {
+                    return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, attrs);
+                },
+
+                'bpmn:Task': function(p, element, attrs) {
+                    var rect = renderer('bpmn:Activity')(p, element, attrs);
+                    renderEmbeddedLabel(p, element, 'center-middle');
+                    attachTaskMarkers(p, element);
+                    return rect;
+                },
+                'bpmn:ServiceTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
+                        abspos: {
+                            x: 12,
+                            y: 18
+                        }
+                    });
+
+                    /* service bg */
+                    drawPath(p, pathDataBG, {
+                        strokeWidth: 1,
+                        fill: 'none'
+                    });
+
+                    var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
+                        abspos: {
+                            x: 17.2,
+                            y: 18
+                        }
+                    });
+
+                    /* service fill */
+                    drawPath(p, fillPathData, {
+                        strokeWidth: 0,
+                        stroke: 'none',
+                        fill: 'white'
+                    });
+
+                    var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
+                        abspos: {
+                            x: 17,
+                            y: 22
+                        }
+                    });
+
+                    /* service */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: 'white'
+                    });
+
+                    return task;
+                },
+                'bpmn:UserTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var x = 15;
+                    var y = 12;
+
+                    var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', {
+                        abspos: {
+                            x: x,
+                            y: y
+                        }
+                    });
+
+                    /* user path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 0.5,
+                        fill: 'none'
+                    });
+
+                    var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
+                        abspos: {
+                            x: x,
+                            y: y
+                        }
+                    });
+
+                    /* user2 path */
+                    drawPath(p, pathData2, {
+                        strokeWidth: 0.5,
+                        fill: 'none'
+                    });
+
+                    var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
+                        abspos: {
+                            x: x,
+                            y: y
+                        }
+                    });
+
+                    /* user3 path */
+                    drawPath(p, pathData3, {
+                        strokeWidth: 0.5,
+                        fill: 'black'
+                    });
+
+                    return task;
+                },
+                'bpmn:ManualTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
+                        abspos: {
+                            x: 17,
+                            y: 15
+                        }
+                    });
+
+                    /* manual path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 0.25,
+                        fill: 'white',
+                        stroke: 'black'
+                    });
+
+                    return task;
+                },
+                'bpmn:SendTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: 21,
+                        containerHeight: 14,
+                        position: {
+                            mx: 0.285,
+                            my: 0.357
+                        }
+                    });
+
+                    /* send path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: 'black',
+                        stroke: 'white'
+                    });
+
+                    return task;
+                },
+                'bpmn:ReceiveTask': function(p, element) {
+                    var semantic = getSemantic(element);
+
+                    var task = renderer('bpmn:Task')(p, element);
+                    var pathData;
+
+                    if (semantic.instantiate) {
+                        drawCircle(p, 28, 28, 20 * 0.22, {
+                            strokeWidth: 1
+                        });
+
+                        pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
+                            abspos: {
+                                x: 7.77,
+                                y: 9.52
+                            }
+                        });
+                    } else {
+
+                        pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
+                            xScaleFactor: 0.9,
+                            yScaleFactor: 0.9,
+                            containerWidth: 21,
+                            containerHeight: 14,
+                            position: {
+                                mx: 0.3,
+                                my: 0.4
+                            }
+                        });
+                    }
+
+                    /* receive path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1
+                    });
+
+                    return task;
+                },
+                'bpmn:ScriptTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
+                        abspos: {
+                            x: 15,
+                            y: 20
+                        }
+                    });
+
+                    /* script path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1
+                    });
+
+                    return task;
+                },
+                'bpmn:BusinessRuleTask': function(p, element) {
+                    var task = renderer('bpmn:Task')(p, element);
+
+                    var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
+                        abspos: {
+                            x: 8,
+                            y: 8
+                        }
+                    });
+
+                    var businessHeaderPath = drawPath(p, headerPathData);
+                    businessHeaderPath.attr({
+                        strokeWidth: 1,
+                        fill: 'AAA'
+                    });
+
+                    var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
+                        abspos: {
+                            x: 8,
+                            y: 8
+                        }
+                    });
+
+                    var businessPath = drawPath(p, headerData);
+                    businessPath.attr({
+                        strokeWidth: 1
+                    });
+
+                    return task;
+                },
+                'bpmn:SubProcess': function(p, element, attrs) {
+                    var rect = renderer('bpmn:Activity')(p, element, attrs);
+
+                    var semantic = getSemantic(element);
+
+                    var expanded = DiUtil.isExpanded(semantic);
+
+                    var isEventSubProcess = !!semantic.triggeredByEvent;
+                    if (isEventSubProcess) {
+                        rect.attr({
+                            strokeDasharray: '1,2'
+                        });
+                    }
+
+                    renderEmbeddedLabel(p, element, expanded ? 'center-top' : 'center-middle');
+
+                    if (expanded) {
+                        attachTaskMarkers(p, element);
+                    } else {
+                        attachTaskMarkers(p, element, ['SubProcessMarker']);
+                    }
+
+                    return rect;
+                },
+                'bpmn:AdHocSubProcess': function(p, element) {
+                    return renderer('bpmn:SubProcess')(p, element);
+                },
+                'bpmn:Transaction': function(p, element) {
+                    var outer = renderer('bpmn:SubProcess')(p, element);
+
+                    var innerAttrs = styles.style(['no-fill', 'no-events']);
+
+                    /* inner path */
+                    drawRect(p, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
+
+                    return outer;
+                },
+                'bpmn:CallActivity': function(p, element) {
+                    return renderer('bpmn:Task')(p, element, {
+                        strokeWidth: 5
+                    });
+                },
+                'bpmn:Participant': function(p, element) {
+
+                    var lane = renderer('bpmn:Lane')(p, element, {
+                        fill: 'White'
+                    });
+
+                    var expandedPool = DiUtil.isExpanded(element);
+
+                    if (expandedPool) {
+                        drawLine(p, [{
+                            x: 30,
+                            y: 0
+                        }, {
+                            x: 30,
+                            y: element.height
+                        }]);
+                        var text = getSemantic(element).name;
+                        renderLaneLabel(p, text, element);
+                    } else {
+                        // Collapsed pool draw text inline
+                        var text2 = getSemantic(element).name;
+                        renderLabel(p, text2, {
+                            box: element,
+                            align: 'center-middle'
+                        });
+                    }
+
+                    var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
+
+                    if (participantMultiplicity) {
+                        renderer('ParticipantMultiplicityMarker')(p, element);
+                    }
+
+                    return lane;
+                },
+                'bpmn:Lane': function(p, element, attrs) {
+                    var rect = drawRect(p, element.width, element.height, 0, attrs || {
+                        fill: 'none'
+                    });
+
+                    var semantic = getSemantic(element);
+
+                    if (semantic.$type === 'bpmn:Lane') {
+                        var text = semantic.name;
+                        renderLaneLabel(p, text, element);
+                    }
+
+                    return rect;
+                },
+                'bpmn:InclusiveGateway': function(p, element) {
+                    var diamond = drawDiamond(p, element.width, element.height);
+
+                    /* circle path */
+                    drawCircle(p, element.width, element.height, element.height * 0.24, {
+                        strokeWidth: 2.5,
+                        fill: 'none'
+                    });
+
+                    return diamond;
+                },
+                'bpmn:ExclusiveGateway': function(p, element) {
+                    var diamond = drawDiamond(p, element.width, element.height);
+                    renderEmbeddedLabel(p, element, 'center-middle');
+
+                    var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
+                        xScaleFactor: 0.4,
+                        yScaleFactor: 0.4,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.32,
+                            my: 0.3
+                        }
+                    });
+
+                    if (!!(getDi(element).isMarkerVisible)) {
+                        drawPath(p, pathData, {
+                            strokeWidth: 1,
+                            fill: 'black'
+                        });
+                    }
+
+                    return diamond;
+                },
+                'bpmn:ComplexGateway': function(p, element) {
+                    var diamond = drawDiamond(p, element.width, element.height);
+
+                    var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
+                        xScaleFactor: 0.5,
+                        yScaleFactor: 0.5,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.46,
+                            my: 0.26
+                        }
+                    });
+
+                    /* complex path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: 'black'
+                    });
+
+                    return diamond;
+                },
+                'bpmn:ParallelGateway': function(p, element) {
+                    var diamond = drawDiamond(p, element.width, element.height);
+
+                    var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
+                        xScaleFactor: 0.6,
+                        yScaleFactor: 0.6,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.46,
+                            my: 0.2
+                        }
+                    });
+
+                    /* parallel path */
+                    drawPath(p, pathData, {
+                        strokeWidth: 1,
+                        fill: 'black'
+                    });
+
+                    return diamond;
+                },
+                'bpmn:EventBasedGateway': function(p, element) {
+
+                    var semantic = getSemantic(element);
+
+                    var diamond = drawDiamond(p, element.width, element.height);
+
+                    /* outer circle path */
+                    drawCircle(p, element.width, element.height, element.height * 0.20, {
+                        strokeWidth: 1,
+                        fill: 'none'
+                    });
+
+                    var type = semantic.eventGatewayType;
+                    var instantiate = !!semantic.instantiate;
+
+                    function drawEvent() {
+
+                        var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
+                            xScaleFactor: 0.18,
+                            yScaleFactor: 0.18,
+                            containerWidth: element.width,
+                            containerHeight: element.height,
+                            position: {
+                                mx: 0.36,
+                                my: 0.44
+                            }
+                        });
+
+                        /* event path */
+                        drawPath(p, pathData, {
+                            strokeWidth: 2,
+                            fill: 'none'
+                        });
+                    }
+
+                    if (type === 'Parallel') {
+
+                        var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
+                            xScaleFactor: 0.4,
+                            yScaleFactor: 0.4,
+                            containerWidth: element.width,
+                            containerHeight: element.height,
+                            position: {
+                                mx: 0.474,
+                                my: 0.296
+                            }
+                        });
+
+                        var parallelPath = drawPath(p, pathData);
+                        parallelPath.attr({
+                            strokeWidth: 1,
+                            fill: 'none'
+                        });
+                    } else if (type === 'Exclusive') {
+
+                        if (!instantiate) {
+                            var innerCircle = drawCircle(p, element.width, element.height, element.height * 0.26);
+                            innerCircle.attr({
+                                strokeWidth: 1,
+                                fill: 'none'
+                            });
+                        }
+
+                        drawEvent();
+                    }
+
+
+                    return diamond;
+                },
+                'bpmn:Gateway': function(p, element) {
+                    var diamond = drawDiamond(p, element.width, element.height);
+                    renderEmbeddedLabel(p, element, 'center-middle');
+
+                    return diamond;
+                },
+                'bpmn:SequenceFlow': function(p, element) {
+                    var pathData = createPathFromConnection(element);
+                    var path = drawPath(p, pathData, {
+                        strokeLinejoin: 'round',
+                        markerEnd: marker('sequenceflow-end')
+                    });
+
+                    var sequenceFlow = getSemantic(element);
+                    var source = element.source.businessObject;
+
+                    // conditional flow marker
+                    if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Task')) {
+                        path.attr({
+                            markerStart: marker('conditional-flow-marker')
+                        });
+                    }
+
+                    // default marker
+                    if (source.default && source.$instanceOf('bpmn:Gateway') && source.default === sequenceFlow) {
+                        path.attr({
+                            markerStart: marker('conditional-default-flow-marker')
+                        });
+                    }
+
+                    return path;
+                },
+                'bpmn:Association': function(p, element, attrs) {
+
+                    attrs = assign({
+                        strokeDasharray: '1,6',
+                        strokeLinecap: 'round',
+                        strokeLinejoin: 'round'
+                    }, attrs || {});
+
+                    // TODO(nre): style according to directed state
+                    return drawLine(p, element.waypoints, attrs);
+                },
+                'bpmn:DataInputAssociation': function(p, element) {
+                    return renderer('bpmn:Association')(p, element, {
+                        markerEnd: marker('data-association-end')
+                    });
+                },
+                'bpmn:DataOutputAssociation': function(p, element) {
+                    return renderer('bpmn:Association')(p, element, {
+                        markerEnd: marker('data-association-end')
+                    });
+                },
+                'bpmn:MessageFlow': function(p, element) {
+
+                    var semantic = getSemantic(element),
+                        di = getDi(element);
+
+                    var pathData = createPathFromConnection(element);
+                    var path = drawPath(p, pathData, {
+                        markerEnd: marker('messageflow-end'),
+                        markerStart: marker('messageflow-start'),
+                        strokeDasharray: '10, 12',
+                        strokeLinecap: 'round',
+                        strokeLinejoin: 'round',
+                        strokeWidth: '1.5px'
+                    });
+
+                    if (semantic.messageRef) {
+                        var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
+
+                        var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
+                            abspos: {
+                                x: midPoint.x,
+                                y: midPoint.y
+                            }
+                        });
+
+                        var messageAttrs = {
+                            strokeWidth: 1
+                        };
+
+                        if (di.messageVisibleKind === 'initiating') {
+                            messageAttrs.fill = 'white';
+                            messageAttrs.stroke = 'black';
+                        } else {
+                            messageAttrs.fill = '#888';
+                            messageAttrs.stroke = 'white';
+                        }
+
+                        drawPath(p, markerPathData, messageAttrs);
+                    }
+
+                    return path;
+                },
+                'bpmn:DataObject': function(p, element) {
+                    var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.474,
+                            my: 0.296
+                        }
+                    });
+
+                    var elementObject = drawPath(p, pathData, {
+                        fill: 'white'
+                    });
+
+                    var semantic = getSemantic(element);
+
+                    if (isCollection(semantic)) {
+                        renderDataItemCollection(p, element);
+                    }
+
+                    return elementObject;
+                },
+                'bpmn:DataObjectReference': as('bpmn:DataObject'),
+                'bpmn:DataInput': function(p, element) {
+
+                    var arrowPathData = pathMap.getRawPath('DATA_ARROW');
+
+                    // page
+                    var elementObject = renderer('bpmn:DataObject')(p, element);
+
+                    /* input arrow path */
+                    drawPath(p, arrowPathData, {
+                        strokeWidth: 1
+                    });
+
+                    return elementObject;
+                },
+                'bpmn:DataOutput': function(p, element) {
+                    var arrowPathData = pathMap.getRawPath('DATA_ARROW');
+
+                    // page
+                    var elementObject = renderer('bpmn:DataObject')(p, element);
+
+                    /* output arrow path */
+                    drawPath(p, arrowPathData, {
+                        strokeWidth: 1,
+                        fill: 'black'
+                    });
+
+                    return elementObject;
+                },
+                'bpmn:DataStoreReference': function(p, element) {
+                    var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0,
+                            my: 0.133
+                        }
+                    });
+
+                    var elementStore = drawPath(p, DATA_STORE_PATH, {
+                        strokeWidth: 2,
+                        fill: 'white'
+                    });
+
+                    return elementStore;
+                },
+                'bpmn:BoundaryEvent': function(p, element) {
+
+                    var semantic = getSemantic(element),
+                        cancel = semantic.cancelActivity;
+
+                    var attrs = {
+                        strokeLinecap: 'round',
+                        strokeWidth: 1
+                    };
+
+                    if (!cancel) {
+                        attrs.strokeDasharray = '6';
+                    }
+
+                    var outer = renderer('bpmn:Event')(p, element, attrs);
+                    /* inner path */
+                    drawCircle(p, element.width, element.height, INNER_OUTER_DIST, attrs);
+
+                    renderEventContent(element, p);
+
+                    return outer;
+                },
+                'bpmn:Group': function(p, element) {
+                    return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, {
+                        strokeWidth: 1,
+                        strokeDasharray: '8,3,1,3',
+                        fill: 'none',
+                        pointerEvents: 'none'
+                    });
+                },
+                'label': function(p, element) {
+                    return renderExternalLabel(p, element, '');
+                },
+                'bpmn:TextAnnotation': function(p, element) {
+                    var style = {
+                        'fill': 'none',
+                        'stroke': 'none'
+                    };
+                    var textElement = drawRect(p, element.width, element.height, 0, 0, style);
+                    var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: 0.0,
+                            my: 0.0
+                        }
+                    });
+                    drawPath(p, textPathData);
+
+                    var text = getSemantic(element).text || '';
+                    renderLabel(p, text, {
+                        box: element,
+                        align: 'left-middle',
+                        padding: 5
+                    });
+
+                    return textElement;
+                },
+                'ParticipantMultiplicityMarker': function(p, element) {
+                    var subProcessPath = pathMap.getScaledPath('MARKER_PARALLEL', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2) / element.width),
+                            my: (element.height - 15) / element.height
+                        }
+                    });
+
+                    drawPath(p, subProcessPath);
+                },
+                'SubProcessMarker': function(p, element) {
+                    var markerRect = drawRect(p, 14, 14, 0, {
+                        strokeWidth: 1
+                    });
+
+                    // Process marker is placed in the middle of the box
+                    // therefore fixed values can be used here
+                    markerRect.transform('translate(' + (element.width / 2 - 7.5) + ',' + (element.height - 20) + ')');
+
+                    var subProcessPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
+                        xScaleFactor: 1.5,
+                        yScaleFactor: 1.5,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: (element.width / 2 - 7.5) / element.width,
+                            my: (element.height - 20) / element.height
+                        }
+                    });
+
+                    drawPath(p, subProcessPath);
+                },
+                'ParallelMarker': function(p, element, position) {
+                    var subProcessPath = pathMap.getScaledPath('MARKER_PARALLEL', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2 + position.parallel) / element.width),
+                            my: (element.height - 20) / element.height
+                        }
+                    });
+                    drawPath(p, subProcessPath);
+                },
+                'SequentialMarker': function(p, element, position) {
+                    var sequentialPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2 + position.seq) / element.width),
+                            my: (element.height - 19) / element.height
+                        }
+                    });
+                    drawPath(p, sequentialPath);
+                },
+                'CompensationMarker': function(p, element, position) {
+                    var compensationPath = pathMap.getScaledPath('MARKER_COMPENSATION', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2 + position.compensation) / element.width),
+                            my: (element.height - 13) / element.height
+                        }
+                    });
+                    drawPath(p, compensationPath, {
+                        strokeWidth: 1
+                    });
+                },
+                'LoopMarker': function(p, element, position) {
+                    var loopPath = pathMap.getScaledPath('MARKER_LOOP', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2 + position.loop) / element.width),
+                            my: (element.height - 7) / element.height
+                        }
+                    });
+
+                    drawPath(p, loopPath, {
+                        strokeWidth: 1,
+                        fill: 'none',
+                        strokeLinecap: 'round',
+                        strokeMiterlimit: 0.5
+                    });
+                },
+                'AdhocMarker': function(p, element, position) {
+                    var loopPath = pathMap.getScaledPath('MARKER_ADHOC', {
+                        xScaleFactor: 1,
+                        yScaleFactor: 1,
+                        containerWidth: element.width,
+                        containerHeight: element.height,
+                        position: {
+                            mx: ((element.width / 2 + position.adhoc) / element.width),
+                            my: (element.height - 15) / element.height
+                        }
+                    });
+
+                    drawPath(p, loopPath, {
+                        strokeWidth: 1,
+                        fill: 'black'
+                    });
+                }
+            };
+
+            function attachTaskMarkers(p, element, taskMarkers) {
+                var obj = getSemantic(element);
+
+                var subprocess = includes(taskMarkers, 'SubProcessMarker');
+                var position;
+
+                if (subprocess) {
+                    position = {
+                        seq: -21,
+                        parallel: -22,
+                        compensation: -42,
+                        loop: -18,
+                        adhoc: 10
+                    };
+                } else {
+                    position = {
+                        seq: -3,
+                        parallel: -6,
+                        compensation: -27,
+                        loop: 0,
+                        adhoc: 10
+                    };
+                }
+
+                forEach(taskMarkers, function(marker) {
+                    renderer(marker)(p, element, position);
+                });
+
+                if (obj.$type === 'bpmn:AdHocSubProcess') {
+                    renderer('AdhocMarker')(p, element, position);
+                }
+                if (obj.loopCharacteristics && obj.loopCharacteristics.isSequential === undefined) {
+                    renderer('LoopMarker')(p, element, position);
+                    return;
+                }
+                if (obj.loopCharacteristics &&
+                    obj.loopCharacteristics.isSequential !== undefined &&
+                    !obj.loopCharacteristics.isSequential) {
+                    renderer('ParallelMarker')(p, element, position);
+                }
+                if (obj.loopCharacteristics && !!obj.loopCharacteristics.isSequential) {
+                    renderer('SequentialMarker')(p, element, position);
+                }
+                if (!!obj.isForCompensation) {
+                    renderer('CompensationMarker')(p, element, position);
+                }
+            }
+
+            function drawShape(parent, element) {
+                var type = element.type;
+                var h = handlers[type];
+
+                /* jshint -W040 */
+                if (!h) {
+                    return DefaultRenderer.prototype.drawShape.apply(this, [parent, element]);
+                } else {
+                    return h(parent, element);
+                }
+            }
+
+            function drawConnection(parent, element) {
+                var type = element.type;
+                var h = handlers[type];
+
+                /* jshint -W040 */
+                if (!h) {
+                    return DefaultRenderer.prototype.drawConnection.apply(this, [parent, element]);
+                } else {
+                    return h(parent, element);
+                }
+            }
+
+            function renderDataItemCollection(p, element) {
+
+                var yPosition = (element.height - 16) / element.height;
+
+                var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
+                    xScaleFactor: 1,
+                    yScaleFactor: 1,
+                    containerWidth: element.width,
+                    containerHeight: element.height,
+                    position: {
+                        mx: 0.451,
+                        my: yPosition
+                    }
+                });
+
+                /* collection path */
+                drawPath(p, pathData, {
+                    strokeWidth: 2
+                });
+            }
+
+            function isCollection(element, filter) {
+                return element.isCollection ||
+                    (element.elementObjectRef && element.elementObjectRef.isCollection);
+            }
+
+            function getDi(element) {
+                return element.businessObject.di;
+            }
+
+            function getSemantic(element) {
+                return element.businessObject;
+            }
+
+            /**
+             * Checks if eventDefinition of the given element matches with semantic
+             * type.
+             * 
+             * @return {boolean} true if element is of the given semantic type
+             */
+            function isTypedEvent(event, eventDefinitionType, filter) {
+
+                function matches(definition, filter) {
+                    return every(filter, function(val, key) {
+
+                        // we want a == conversion here, to be able to catch
+                        // undefined == false and friends
+                        /* jshint -W116 */
+                        return definition[key] == val;
+                    });
+                }
+
+                return some(event.eventDefinitions, function(definition) {
+                    return definition.$type === eventDefinitionType && matches(event, filter);
+                });
+            }
+
+            function isThrowEvent(event) {
+                return (event.$type === 'bpmn:IntermediateThrowEvent') || (event.$type === 'bpmn:EndEvent');
+            }
+
+
+            // ///// cropping path customizations /////////////////////////
+
+            function componentsToPath(elements) {
+                return elements.join(',').replace(/,?([A-z]),?/g, '$1');
+            }
+
+            function getCirclePath(shape) {
+
+                var cx = shape.x + shape.width / 2,
+                    cy = shape.y + shape.height / 2,
+                    radius = shape.width / 2;
+
+                var circlePath = [
+                    ['M', cx, cy],
+                    ['m', 0, -radius],
+                    ['a', radius, radius, 0, 1, 1, 0, 2 * radius],
+                    ['a', radius, radius, 0, 1, 1, 0, -2 * radius],
+                    ['z']
+                ];
+
+                return componentsToPath(circlePath);
+            }
+
+            function getRoundRectPath(shape) {
+
+                var radius = TASK_BORDER_RADIUS,
+                    x = shape.x,
+                    y = shape.y,
+                    width = shape.width,
+                    height = shape.height;
+
+                var roundRectPath = [
+                    ['M', x + radius, y],
+                    ['l', width - radius * 2, 0],
+                    ['a', radius, radius, 0, 0, 1, radius, radius],
+                    ['l', 0, height - radius * 2],
+                    ['a', radius, radius, 0, 0, 1, -radius, radius],
+                    ['l', radius * 2 - width, 0],
+                    ['a', radius, radius, 0, 0, 1, -radius, -radius],
+                    ['l', 0, radius * 2 - height],
+                    ['a', radius, radius, 0, 0, 1, radius, -radius],
+                    ['z']
+                ];
+
+                return componentsToPath(roundRectPath);
+            }
+
+            function getDiamondPath(shape) {
+
+                var width = shape.width,
+                    height = shape.height,
+                    x = shape.x,
+                    y = shape.y,
+                    halfWidth = width / 2,
+                    halfHeight = height / 2;
+
+                var diamondPath = [
+                    ['M', x + halfWidth, y],
+                    ['l', halfWidth, halfHeight],
+                    ['l', -halfWidth, halfHeight],
+                    ['l', -halfWidth, -halfHeight],
+                    ['z']
+                ];
+
+                return componentsToPath(diamondPath);
+            }
+
+            function getRectPath(shape) {
+                var x = shape.x,
+                    y = shape.y,
+                    width = shape.width,
+                    height = shape.height;
+
+                var rectPath = [
+                    ['M', x, y],
+                    ['l', width, 0],
+                    ['l', 0, height],
+                    ['l', -width, 0],
+                    ['z']
+                ];
+
+                return componentsToPath(rectPath);
+            }
+
+            function getShapePath(element) {
+                var obj = getSemantic(element);
+
+                if (obj.$instanceOf('bpmn:Event')) {
+                    return getCirclePath(element);
+                }
+
+                if (obj.$instanceOf('bpmn:Activity')) {
+                    return getRoundRectPath(element);
+                }
+
+                if (obj.$instanceOf('bpmn:Gateway')) {
+                    return getDiamondPath(element);
+                }
+
+                return getRectPath(element);
+            }
+
+
+            // hook onto canvas init event to initialize
+            // connection start/end markers on svg
+            events.on('canvas.init', function(event) {
+                initMarkers(event.svg);
+            });
+
+            this.drawShape = drawShape;
+            this.drawConnection = drawConnection;
+
+            this.getShapePath = getShapePath;
+        }
+
+        inherits(BpmnRenderer, DefaultRenderer);
+
+
+        BpmnRenderer.$inject = ['eventBus', 'styles', 'pathMap'];
+
+        module.exports = BpmnRenderer;
+
+    }, {
+        "../util/DiUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\DiUtil.js",
+        "diagram-js/lib/draw/Renderer": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Renderer.js",
+        "diagram-js/lib/util/Text": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Text.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/every": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\every.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/includes": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\includes.js",
+        "lodash/collection/some": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\some.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\PathMap.js": [function(require, module, exports) {
+        'use strict';
+
+        var Snap = require('diagram-js/vendor/snapsvg');
+
+        /**
+         * Map containing SVG paths needed by BpmnRenderer.
+         */
+
+        function PathMap() {
+
+            /**
+             * Contains a map of path elements
+             * 
+             * <h1>Path definition</h1>
+             * A parameterized path is defined like this:
+             * 
+             * <pre>
+             * 'GATEWAY_PARALLEL': {
+             *   d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
+             *           '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
+             *   height: 17.5,
+             *   width:  17.5,
+             *   heightElements: [2.5, 7.5],
+             *   widthElements: [2.5, 7.5]
+             * }
+             * </pre>
+             * 
+             * <p>
+             * It's important to specify a correct <b>height and width</b> for the path
+             * as the scaling is based on the ratio between the specified height and
+             * width in this object and the height and width that is set as scale target
+             * (Note x,y coordinates will be scaled with individual ratios).
+             * </p>
+             * <p>
+             * The '<b>heightElements</b>' and '<b>widthElements</b>' array must
+             * contain the values that will be scaled. The scaling is based on the
+             * computed ratios. Coordinates on the y axis should be in the
+             * <b>heightElement</b>'s array, they will be scaled using the computed
+             * ratio coefficient. In the parameterized path the scaled values can be
+             * accessed through the 'e' object in {} brackets.
+             * <ul>
+             * <li>The values for the y axis can be accessed in the path string using
+             * {e.y0}, {e.y1}, ....</li>
+             * <li>The values for the x axis can be accessed in the path string using
+             * {e.x0}, {e.x1}, ....</li>
+             * </ul>
+             * The numbers x0, x1 respectively y0, y1, ... map to the corresponding
+             * array index.
+             * </p>
+             */
+            this.pathMap = {
+                'EVENT_MESSAGE': {
+                    d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
+                    height: 36,
+                    width: 36,
+                    heightElements: [6, 14],
+                    widthElements: [10.5, 21]
+                },
+                'EVENT_SIGNAL': {
+                    d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [18],
+                    widthElements: [10, 20]
+                },
+                'EVENT_ESCALATION': {
+                    d: 'm {mx},{my} c -{e.x1},{e.y0} -{e.x3},{e.y1} -{e.x5},{e.y4} {e.x1},-{e.y3} {e.x3},-{e.y5} {e.x5},-{e.y6} ' +
+                        '{e.x0},{e.y3} {e.x2},{e.y5} {e.x4},{e.y6} -{e.x0},-{e.y0} -{e.x2},-{e.y1} -{e.x4},-{e.y4} z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [2.382, 4.764, 4.926, 6.589333, 7.146, 13.178667, 19.768],
+                    widthElements: [2.463, 2.808, 4.926, 5.616, 7.389, 8.424]
+                },
+                'EVENT_CONDITIONAL': {
+                    d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' +
+                        'M {e.x2},{e.y3} l {e.x0},0 ' +
+                        'M {e.x2},{e.y4} l {e.x0},0 ' +
+                        'M {e.x2},{e.y5} l {e.x0},0 ' +
+                        'M {e.x2},{e.y6} l {e.x0},0 ' +
+                        'M {e.x2},{e.y7} l {e.x0},0 ' +
+                        'M {e.x2},{e.y8} l {e.x0},0 ',
+                    height: 36,
+                    width: 36,
+                    heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
+                    widthElements: [10.5, 14.5, 12.5]
+                },
+                'EVENT_LINK': {
+                    d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [4.4375, 6.75, 7.8125],
+                    widthElements: [9.84375, 13.5]
+                },
+                'EVENT_ERROR': {
+                    d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
+                    widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
+                },
+                'EVENT_CANCEL_45': {
+                    d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
+                        '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [4.75, 8.5],
+                    widthElements: [4.75, 8.5]
+                },
+                'EVENT_COMPENSATION': {
+                    d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x0},0 {e.x0},-{e.y0} 0,{e.y1} z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [5, 10],
+                    widthElements: [10]
+                },
+                'EVENT_TIMER_WH': {
+                    d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
+                    height: 36,
+                    width: 36,
+                    heightElements: [10, 2],
+                    widthElements: [3, 7]
+                },
+                'EVENT_TIMER_LINE': {
+                    d: 'M {mx},{my} ' +
+                        'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
+                    height: 36,
+                    width: 36,
+                    heightElements: [10, 3],
+                    widthElements: [0, 0]
+                },
+                'EVENT_MULTIPLE': {
+                    d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [6.28099, 12.56199],
+                    widthElements: [3.1405, 9.42149, 12.56198]
+                },
+                'EVENT_PARALLEL_MULTIPLE': {
+                    d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
+                        '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
+                    height: 36,
+                    width: 36,
+                    heightElements: [2.56228, 7.68683],
+                    widthElements: [2.56228, 7.68683]
+                },
+                'GATEWAY_EXCLUSIVE': {
+                    d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' +
+                        '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' +
+                        '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
+                    height: 17.5,
+                    width: 17.5,
+                    heightElements: [8.5, 6.5312, -6.5312, -8.5],
+                    widthElements: [6.5, -6.5, 3, -3, 5, -5]
+                },
+                'GATEWAY_PARALLEL': {
+                    d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
+                        '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
+                    height: 30,
+                    width: 30,
+                    heightElements: [5, 12.5],
+                    widthElements: [5, 12.5]
+                },
+                'GATEWAY_EVENT_BASED': {
+                    d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
+                    height: 11,
+                    width: 11,
+                    heightElements: [-6, 6, 12, -12],
+                    widthElements: [9, -3, -12]
+                },
+                'GATEWAY_COMPLEX': {
+                    d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' +
+                        '{e.x2},0  -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' +
+                        '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' +
+                        '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
+                    height: 17.125,
+                    width: 17.125,
+                    heightElements: [4.875, 3.4375, 2.125, 3],
+                    widthElements: [3.4375, 2.125, 4.875, 3]
+                },
+                'DATA_OBJECT_PATH': {
+                    d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
+                    height: 61,
+                    width: 51,
+                    heightElements: [10, 50, 60],
+                    widthElements: [10, 40, 50, 60]
+                },
+                'DATA_OBJECT_COLLECTION_PATH': {
+                    d: 'm {mx}, {my} ' +
+                        'm  0 15  l 0 -15 ' +
+                        'm  4 15  l 0 -15 ' +
+                        'm  4 15  l 0 -15 ',
+                    height: 61,
+                    width: 51,
+                    heightElements: [12],
+                    widthElements: [1, 6, 12, 15]
+                },
+                'DATA_ARROW': {
+                    d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
+                    height: 61,
+                    width: 51,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'DATA_STORE': {
+                    d: 'm  {mx},{my} ' +
+                        'l  0,{e.y2} ' +
+                        'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0 ' +
+                        'l  0,-{e.y2} ' +
+                        'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' +
+                        'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0 ' +
+                        'm  -{e.x2},{e.y0}' +
+                        'c  {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' +
+                        'm  -{e.x2},{e.y0}' +
+                        'c  {e.x0},{e.y1} {e.x1},{e.y1}  {e.x2},0',
+                    height: 61,
+                    width: 61,
+                    heightElements: [7, 10, 45],
+                    widthElements: [2, 58, 60]
+                },
+                'TEXT_ANNOTATION': {
+                    d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
+                    height: 30,
+                    width: 10,
+                    heightElements: [30],
+                    widthElements: [10]
+                },
+                'MARKER_SUB_PROCESS': {
+                    d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
+                    height: 10,
+                    width: 10,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'MARKER_PARALLEL': {
+                    d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
+                    height: 10,
+                    width: 10,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'MARKER_SEQUENTIAL': {
+                    d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
+                    height: 10,
+                    width: 10,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'MARKER_COMPENSATION': {
+                    d: 'm {mx},{my} 8,-5 0,10 z m 9,0 8,-5 0,10 z',
+                    height: 10,
+                    width: 21,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'MARKER_LOOP': {
+                    d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' +
+                        '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' +
+                        '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' +
+                        'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
+                    height: 13.9,
+                    width: 13.7,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'MARKER_ADHOC': {
+                    d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' +
+                        '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' +
+                        '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' +
+                        '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' +
+                        '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
+                    height: 4,
+                    width: 15,
+                    heightElements: [],
+                    widthElements: []
+                },
+                'TASK_TYPE_SEND': {
+                    d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
+                    height: 14,
+                    width: 21,
+                    heightElements: [6, 14],
+                    widthElements: [10.5, 21]
+                },
+                'TASK_TYPE_SCRIPT': {
+                    d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' +
+                        'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' +
+                        'm -7,-12 l 5,0 ' +
+                        'm -4.5,3 l 4.5,0 ' +
+                        'm -3,3 l 5,0' +
+                        'm -4,3 l 5,0',
+                    height: 15,
+                    width: 12.6,
+                    heightElements: [6, 14],
+                    widthElements: [10.5, 21]
+                },
+                'TASK_TYPE_USER_1': {
+                    d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' +
+                        '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' +
+                        '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' +
+                        'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' +
+                        'm -8,6 l 0,5.5 m 11,0 l 0,-5'
+                },
+                'TASK_TYPE_USER_2': {
+                    d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' +
+                        '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
+                },
+                'TASK_TYPE_USER_3': {
+                    d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' +
+                        '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' +
+                        '-4.20799998,3.36699999 -4.20699998,4.34799999 z'
+                },
+                'TASK_TYPE_MANUAL': {
+                    d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' +
+                        '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' +
+                        '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' +
+                        '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' +
+                        '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' +
+                        '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' +
+                        '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' +
+                        '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' +
+                        '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' +
+                        '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' +
+                        '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' +
+                        '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
+                },
+                'TASK_TYPE_INSTANTIATING_SEND': {
+                    d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
+                },
+                'TASK_TYPE_SERVICE': {
+                    d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' +
+                        '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' +
+                        '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' +
+                        'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' +
+                        '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' +
+                        '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' +
+                        'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' +
+                        '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' +
+                        'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' +
+                        'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' +
+                        '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' +
+                        'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' +
+                        'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
+                        '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
+                        '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
+                },
+                'TASK_TYPE_SERVICE_FILL': {
+                    d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
+                        '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
+                        '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
+                },
+                'TASK_TYPE_BUSINESS_RULE_HEADER': {
+                    d: 'm {mx},{my} 0,4 20,0 0,-4 z'
+                },
+                'TASK_TYPE_BUSINESS_RULE_MAIN': {
+                    d: 'm {mx},{my} 0,12 20,0 0,-12 z' +
+                        'm 0,8 l 20,0 ' +
+                        'm -13,-4 l 0,8'
+                },
+                'MESSAGE_FLOW_MARKER': {
+                    d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
+                }
+            };
+
+            this.getRawPath = function getRawPath(pathId) {
+                return this.pathMap[pathId].d;
+            };
+
+            /**
+             * Scales the path to the given height and width.
+             * <h1>Use case</h1>
+             * <p>
+             * Use case is to scale the content of elements (event, gateways) based on
+             * the element bounding box's size.
+             * </p>
+             * <h1>Why not transform</h1>
+             * <p>
+             * Scaling a path with transform() will also scale the stroke and IE does
+             * not support the option 'non-scaling-stroke' to prevent this. Also there
+             * are use cases where only some parts of a path should be scaled.
+             * </p>
+             * 
+             * @param {String}
+             *            pathId The ID of the path.
+             * @param {Object}
+             *            param
+             *            <p>
+             *            Example param object scales the path to 60% size of the
+             *            container (data.width, data.height).
+             * 
+             * <pre>
+             * {
+             *         xScaleFactor : 0.6,
+             *         yScaleFactor : 0.6,
+             *         containerWidth : data.width,
+             *         containerHeight : data.height,
+             *         position : {
+             *                 mx : 0.46,
+             *                 my : 0.2,
+             *         }
+             * }
+             * </pre>
+             * 
+             * <ul>
+             *            <li>targetpathwidth = xScaleFactor * containerWidth</li>
+             *            <li>targetpathheight = yScaleFactor * containerHeight</li>
+             *            <li>Position is used to set the starting coordinate of the
+             *            path. M is computed:
+             *            <ul>
+             *            <li>position.x * containerWidth</li>
+             *            <li>position.y * containerHeight</li>
+             *            </ul>
+             *            Center of the container
+             * 
+             * <pre>
+             *  position: {
+             *       mx: 0.5,
+             *       my: 0.5,
+             *     }
+             * </pre>
+             * 
+             * Upper left corner of the container
+             * 
+             * <pre>
+             *  position: {
+             *       mx: 0.0,
+             *       my: 0.0,
+             *     }
+             * </pre>
+             * 
+             * </li>
+             *            </ul>
+             *            </p>
+             * 
+             */
+            this.getScaledPath = function getScaledPath(pathId, param) {
+                var rawPath = this.pathMap[pathId];
+
+                // positioning
+                // compute the start point of the path
+                var mx, my;
+
+                if (!!param.abspos) {
+                    mx = param.abspos.x;
+                    my = param.abspos.y;
+                } else {
+                    mx = param.containerWidth * param.position.mx;
+                    my = param.containerHeight * param.position.my;
+                }
+
+                var coordinates = {}; // map for the scaled coordinates
+                if (param.position) {
+
+                    // path
+                    var heightRatio = (param.containerHeight / rawPath.height) * param.yScaleFactor;
+                    var widthRatio = (param.containerWidth / rawPath.width) * param.xScaleFactor;
+
+
+                    // Apply height ratio
+                    for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
+                        coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
+                    }
+
+                    // Apply width ratio
+                    for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
+                        coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
+                    }
+                }
+
+                // Apply value to raw path
+                var path = Snap.format(
+                    rawPath.d, {
+                        mx: mx,
+                        my: my,
+                        e: coordinates
+                    }
+                );
+                return path;
+            };
+        }
+
+        module.exports = PathMap;
+
+    }, {
+        "diagram-js/vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\index.js": [function(require, module, exports) {
+        module.exports = {
+            renderer: ['type', require('./BpmnRenderer')],
+            pathMap: ['type', require('./PathMap')]
+        };
+    }, {
+        "./BpmnRenderer": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\BpmnRenderer.js",
+        "./PathMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\draw\\PathMap.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\context-pad\\ContextPadProvider.js": [function(require, module, exports) {
+        'use strict';
+
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+
+        /**
+         * A provider for BPMN 2.0 elements context pad
+         */
+        function ContextPadProvider(contextPad, modeling, elementFactory,
+            connect, create, bpmnReplace,
+            canvas) {
+
+            contextPad.registerProvider(this);
+
+            this._contextPad = contextPad;
+
+            this._modeling = modeling;
+
+            this._elementFactory = elementFactory;
+            this._connect = connect;
+            this._create = create;
+            this._bpmnReplace = bpmnReplace;
+            this._canvas = canvas;
+        }
+
+        ContextPadProvider.$inject = [
+            'contextPad',
+            'modeling',
+            'elementFactory',
+            'connect',
+            'create',
+            'bpmnReplace',
+            'canvas'
+        ];
+
+        ContextPadProvider.prototype.getContextPadEntries = function(element) {
+
+            var contextPad = this._contextPad,
+                modeling = this._modeling,
+
+                elementFactory = this._elementFactory,
+                connect = this._connect,
+                create = this._create,
+                bpmnReplace = this._bpmnReplace,
+                canvas = this._canvas;
+
+            var actions = {};
+
+            if (element.type === 'label') {
+                return actions;
+            }
+
+            var bpmnElement = element.businessObject;
+
+            function startConnect(event, element, autoActivate) {
+                connect.start(event, element, autoActivate);
+            }
+
+            function removeElement(e) {
+              console.log(e);
+                if (element.waypoints) {
+                    modeling.removeConnection(element);
+                } else {
+                    modeling.removeShape(element);
+                  
+                }
+                if(element.id == selected_decison_element)
+                       {
+                       
+                       invisiblepropertyExplorer();
+                       }
+            }
+
+            function getReplaceMenuPosition(element) {
+
+                var Y_OFFSET = 5;
+
+                var diagramContainer = canvas.getContainer(),
+                    pad = contextPad.getPad(element).html;
+
+                var diagramRect = diagramContainer.getBoundingClientRect(),
+                    padRect = pad.getBoundingClientRect();
+
+                var top = padRect.top - diagramRect.top;
+                var left = padRect.left - diagramRect.left;
+
+                var pos = {
+                    x: left,
+                    y: top + padRect.height + Y_OFFSET
+                };
+
+                return pos;
+            }
+
+           
+            var change_color = function(par1,par2)
+            {
+               if(isImportSchema == true){
+
+                       return par2/*'define-schema'*/;
+               }
+               else
+                       {
+                       return  par1/*'define-modify-schema'*/;
+                       }
+            }
+            function appendAction(type, className, options) {
+
+                function appendListener(event, element) {
+
+                    var shape = elementFactory.createShape(assign({
+                        type: type
+                    }, options));
+                    create.start(event, shape, element);
+                }
+
+                var shortType = type.replace(/^bpmn\:/, '');
+
+                return {
+                    group: 'model',
+                    className: className,
+                    title: 'Append ' + shortType,
+                    action: {
+                        dragstart: appendListener,
+                        click: appendListener
+                    }
+                };
+            }
+
+
+            if (bpmnElement.$instanceOf('bpmn:Gateway') || bpmnElement.$instanceOf('bpmn:MultiBranchConnector')) {
+                assign(actions, {
+                    'define-path': {
+                        group: 'DefinePath',
+                        className: 'define-path',
+                        title: 'Define/View Path',
+                        action: {
+                            click: function(event) {
+                                                
+                               if(bpmnElement.name){
+                                                 var bpmnElementID = bpmnElement.id;
+                                               selected_decison_element = bpmnElementID;
+                                                 var bpmnElementName = bpmnElement.name;
+                                               selected_element_name = bpmnElementName;
+                                                 var pathIdentifiers = [];
+                                                 
+                                                 if (bpmnElement.outgoing) {
+
+                                                         var check_outgoing_names = true; 
+                                                 forEach(bpmnElement.outgoing, function(og) {
+                                                         
+                                                         if(og.name && og.name.length !=0)
+                                                               {
+                                                                 
+                                                                               pathIdentifiers.push(og.name);
+                                                               
+                                                                }
+                                                         else
+                                                                 {
+                                                               
+                                                                               errorProperty(bpmnElement.name+" out going path name was not entered");
+                                                                               check_outgoing_names=false;
+                                                                 }
+                                                         
+                                                 });
+                                                 if(check_outgoing_names)
+                                                 {
+                                                         
+                                                                               pathDetails(bpmnElementID,bpmnElementName,pathIdentifiers);
+                                                 }
+                                                 
+                                                 
+                                                       
+                                                 }
+                                                 else
+                                                 {
+                                                                       errorProperty(bpmnElement.name+' should atleast one output path was required');
+                                                 }
+                                               
+                            }
+                               else
+                                       {
+                                       errorProperty('Enter Valid Decision Name');
+                                       }
+                            }
+                        }
+                    }
+                });
+            }
+
+            
+
+            if (bpmnElement.$instanceOf('bpmn:InitiateProcess')) {
+            }
+
+                       if (bpmnElement.$instanceOf('bpmn:StartEvent')) {
+            }
+                       if (bpmnElement.$instanceOf('bpmn:Collector')) {
+                assign(actions, {
+                    'Properties': {
+                        group: 'clds',
+                        label: 'Edit Properties',
+                        className: 'clds-edit-properties',
+                        title: 'Properties',
+                        action: {
+                            click: function(event) {
+                               lastElementSelected=bpmnElement.id
+                               CollectorsWindow(bpmnElement);
+                            }
+                        }
+                    }
+                });
+                               
+            }
+                       if (bpmnElement.$instanceOf('bpmn:StringMatch')) {
+                assign(actions, {
+                    'Properties': {
+                        group: 'clds',
+                        label: 'Edit Properties',
+                        className: 'clds-edit-properties',
+                        title: 'Properties',
+                        action: {
+                            click: function(event) {
+                               lastElementSelected=bpmnElement.id
+                               StringMatchWindow(bpmnElement);
+                            }
+                        }
+                    }
+                });
+            }
+                       if (bpmnElement.$instanceOf('bpmn:TCA')) {
+                assign(actions, {
+                    'Properties': {
+                        group: 'clds',
+                        label: 'Edit Properties',
+                        className: 'clds-edit-properties',
+                        title: 'Properties',
+                        action: {
+                            click: function(event) {
+                              console.log(event);
+                               lastElementSelected=bpmnElement.id
+                            }
+                        }
+                    }
+                });
+            }
+                       if (bpmnElement.$instanceOf('bpmn:GOC')) {
+                assign(actions, {
+                    'Properties': {
+                        group: 'clds',
+                        label: 'Edit Properties',
+                        className: 'clds-edit-properties',
+                        title: 'Properties',
+                        action: {
+                            click: function(event) {
+                               lastElementSelected=bpmnElement.id
+                               GOCWindow();
+                            }
+                        }
+                    }
+                });
+            }
+                       if (bpmnElement.$instanceOf('bpmn:Policy')) {
+                assign(actions, {
+                    'Properties': {
+                        group: 'clds',
+                        label: 'Edit Properties',
+                        className: 'clds-edit-properties',
+                        title: 'Properties',
+                        action: {
+                            click: function(event) {
+                               lastElementSelected=bpmnElement.id
+                               PolicyWindow(bpmnElement);
+                            }
+                        }
+                    }
+                });
+            }
+
+            if (bpmnElement.$instanceOf('bpmn:FlowNode') ||
+                bpmnElement.$instanceOf('bpmn:InteractionNode')) {
+
+                assign(actions, {
+                    'append.text-annotation': appendAction('bpmn:TextAnnotation', 'icon-text-annotation'),
+
+                    'connect': {
+                        group: 'connect',
+                        className: 'icon-connection',
+                        title: 'Connector',
+                        action: {
+                            click: startConnect,
+                            dragstart: startConnect
+                        }
+                    }
+                });
+            }
+                       
+                       // Delete Element Entry
+            assign(actions, {
+                'delete': {
+                    group: 'edits',
+                    className: 'icon-trash',
+                    title: 'Remove',
+                    action: {
+                        click: removeElement,
+                        dragstart: removeElement
+                    }
+                }
+
+
+
+            });
+
+            return actions;
+        };
+
+        function isEventType(eventBo, type, definition) {
+
+            var isType = eventBo.$instanceOf(type);
+            var isDefinition = false;
+
+            var definitions = eventBo.eventDefinitions || [];
+            forEach(definitions, function(def) {
+                if (def.$type === definition) {
+                    isDefinition = true;
+                }
+            });
+
+            return isType && isDefinition;
+        }
+
+
+        module.exports = ContextPadProvider;
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\context-pad\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js-direct-editing'),
+                require('diagram-js/lib/features/context-pad'),
+                require('diagram-js/lib/features/selection'),
+                require('diagram-js/lib/features/connect'),
+                require('diagram-js/lib/features/create'),
+                require('../replace')
+            ],
+            __init__: ['contextPadProvider'],
+            contextPadProvider: ['type', require('./ContextPadProvider')]
+        };
+    }, {
+        "../replace": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\index.js",
+        "./ContextPadProvider": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\context-pad\\ContextPadProvider.js",
+        "diagram-js-direct-editing": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\index.js",
+        "diagram-js/lib/features/connect": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\connect\\index.js",
+        "diagram-js/lib/features/context-pad": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\context-pad\\index.js",
+        "diagram-js/lib/features/create": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\create\\index.js",
+        "diagram-js/lib/features/selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\keyboard\\BpmnKeyBindings.js": [function(require, module, exports) {
+        'use strict';
+
+
+        function BpmnKeyBindings(keyboard, spaceTool, lassoTool, directEditing, selection) {
+               
+            keyboard.addListener(function(key, modifiers) {
+               
+                if (keyboard.hasModifier(modifiers)) {
+                    return;
+                }
+
+                // S -> activate space tool
+                if (key === 83) {
+                    spaceTool.activateSelection();
+
+                    return true;
+                }
+
+                // L -> activate lasso tool
+                if (key === 108) {
+                    lassoTool.activateSelection();
+
+                    return true;
+                }
+
+                var currentSelection = selection.get();
+
+                // E -> activate direct editing
+                if (key === 69) {
+                    if (currentSelection.length) {
+                        directEditing.activate(currentSelection[0]);
+                    }
+
+                    return true;
+                }
+            });
+        }
+
+        BpmnKeyBindings.$inject = ['keyboard', 'spaceTool', 'lassoTool', 'directEditing', 'selection'];
+
+        module.exports = BpmnKeyBindings;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\keyboard\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js/lib/features/keyboard')
+            ],
+            __init__: ['bpmnKeyBindings'],
+            bpmnKeyBindings: ['type', require('./BpmnKeyBindings')]
+        };
+    }, {
+        "./BpmnKeyBindings": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\keyboard\\BpmnKeyBindings.js",
+        "diagram-js/lib/features/keyboard": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\keyboard\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\LabelEditingProvider.js": [function(require, module, exports) {
+        'use strict';
+
+        var UpdateLabelHandler = require('./cmd/UpdateLabelHandler');
+
+        var LabelUtil = require('./LabelUtil');
+
+        var is = require('../../util/ModelUtil').is,
+            isExpanded = require('../../util/DiUtil').isExpanded;
+
+        var daOriginalLabel = '';
+
+        var MIN_BOUNDS = {
+            width: 150,
+            height: 50
+        };
+
+
+        function LabelEditingProvider(eventBus, canvas, directEditing, commandStack, injector) {
+
+            directEditing.registerProvider(this);
+            commandStack.registerHandler('element.updateLabel', UpdateLabelHandler);
+
+            // listen to dblclick on non-root elements
+            eventBus.on('element.dblclick', function(event) {
+               
+                directEditing.activate(event.element);
+            });
+            
+
+            // complete on followup canvas operation
+            eventBus.on(['element.mousedown', 'drag.activate', 'canvas.viewbox.changed'], function(event) {
+                directEditing.complete();
+            });
+
+            // cancel on command stack changes
+            eventBus.on(['commandStack.changed'], function() {
+                directEditing.cancel();
+            });
+
+
+            // activate direct editing for activities and text annotations
+
+
+            if ('ontouchstart' in document.documentElement) {
+                // we deactivate automatic label editing on mobile devices
+                // as it breaks the user interaction workflow
+
+                // TODO(nre): we should temporarily focus the edited element here
+                // and release the focused viewport after the direct edit operation is
+                // finished
+            } else {
+                eventBus.on('create.end', 500, function(e) {
+
+                    var element = e.shape,
+                        canExecute = e.context.canExecute;
+
+                    if (!canExecute) {
+                        return;
+                    }
+
+                    if (is(element, 'bpmn:Task') || is(element, 'bpmn:TextAnnotation') ||
+                        (is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
+
+                        directEditing.activate(element);
+                    }
+                });
+            }
+
+            this._canvas = canvas;
+            this._commandStack = commandStack;
+        }
+
+        LabelEditingProvider.$inject = ['eventBus', 'canvas', 'directEditing', 'commandStack', 'injector'];
+
+        module.exports = LabelEditingProvider;
+
+
+        LabelEditingProvider.prototype.activate = function(element) {
+
+            var text = LabelUtil.getLabel(element);
+
+            if (text === undefined) {
+                return;
+            }
+
+            daOriginalLabel = text;
+            
+            var bbox = this.getEditingBBox(element);
+
+            // adjust for expanded pools AND lanes
+            if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) {
+
+                bbox.width = MIN_BOUNDS.width;
+                bbox.height = MIN_BOUNDS.height;
+
+                bbox.x = bbox.x + 10 - bbox.width / 2;
+                bbox.y = bbox.mid.y - bbox.height / 2;
+            }
+
+            // adjust for expanded sub processes
+            if (is(element, 'bpmn:SubProcess') && isExpanded(element)) {
+
+                bbox.height = MIN_BOUNDS.height;
+
+                bbox.x = bbox.mid.x - bbox.width / 2;
+                bbox.y = bbox.y + 10 - bbox.height / 2;
+            }
+
+            return {
+                bounds: bbox,
+                text: text
+            };
+        };
+
+
+        LabelEditingProvider.prototype.getEditingBBox = function(element, maxBounds) {
+
+            var target = element.label || element;
+
+            var bbox = this._canvas.getAbsoluteBBox(target);
+
+            var mid = {
+                x: bbox.x + bbox.width / 2,
+                y: bbox.y + bbox.height / 2
+            };
+
+            // external label
+            if (target.labelTarget) {
+                bbox.width = Math.max(bbox.width, MIN_BOUNDS.width);
+                bbox.height = Math.max(bbox.height, MIN_BOUNDS.height);
+
+                bbox.x = mid.x - bbox.width / 2;
+            }
+
+            bbox.mid = mid;
+
+            return bbox;
+        };
+
+
+        LabelEditingProvider.prototype.update = function(element, newLabel) {
+               //update conditional node
+               if (is(element, 'bpmn:ExclusiveGateway') || is(element, 'bpmn:MultiBranchConnector')){
+                       updateDecisionLabel(daOriginalLabel, newLabel);
+               }
+               
+               this._commandStack.execute('element.updateLabel', {
+                element: element,
+                newLabel: newLabel
+            });
+        };
+    }, {
+        "../../util/DiUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\DiUtil.js",
+        "../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "./LabelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\LabelUtil.js",
+        "./cmd/UpdateLabelHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\cmd\\UpdateLabelHandler.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\LabelUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        function getLabelAttr(semantic) {
+            if (semantic.$instanceOf('bpmn:FlowElement') ||
+                semantic.$instanceOf('bpmn:Participant') ||
+                semantic.$instanceOf('bpmn:Lane') ||
+                semantic.$instanceOf('bpmn:SequenceFlow') ||
+                semantic.$instanceOf('bpmn:MessageFlow')) {
+                return 'name';
+            }
+
+            if (semantic.$instanceOf('bpmn:TextAnnotation')) {
+                return 'text';
+            }
+        }
+
+        module.exports.getLabel = function(element) {
+            var semantic = element.businessObject,
+                attr = getLabelAttr(semantic);
+
+            if (attr) {
+                return semantic[attr] || '';
+            }
+        };
+
+
+        module.exports.setLabel = function(element, text) {
+            var semantic = element.businessObject,
+                attr = getLabelAttr(semantic);
+
+            if (attr) {
+                semantic[attr] = text;
+            }
+
+            var label = element.label || element;
+
+            // show label
+            label.hidden = false;
+
+            return label;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\cmd\\UpdateLabelHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var LabelUtil = require('../LabelUtil');
+
+
+        /**
+         * A handler that updates the text of a BPMN element.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         */
+        function UpdateTextHandler(eventBus) {
+
+            function setText(element, text) {
+                var label = LabelUtil.setLabel(element, text);
+
+                eventBus.fire('element.changed', {
+                    element: label
+                });
+            }
+
+            function execute(ctx) {
+                ctx.oldLabel = LabelUtil.getLabel(ctx.element);
+                return setText(ctx.element, ctx.newLabel);
+            }
+
+            function revert(ctx) {
+                return setText(ctx.element, ctx.oldLabel);
+            }
+
+
+            function canExecute(ctx) {
+                return true;
+            }
+
+            // API
+
+            this.execute = execute;
+            this.revert = revert;
+
+            this.canExecute = canExecute;
+        }
+
+
+        UpdateTextHandler.$inject = ['eventBus'];
+
+        module.exports = UpdateTextHandler;
+    }, {
+        "../LabelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\LabelUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js/lib/command'),
+                require('diagram-js/lib/features/change-support'),
+                require('diagram-js-direct-editing')
+            ],
+            __init__: ['labelEditingProvider'],
+            labelEditingProvider: ['type', require('./LabelEditingProvider')]
+        };
+    }, {
+        "./LabelEditingProvider": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\LabelEditingProvider.js",
+        "diagram-js-direct-editing": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\index.js",
+        "diagram-js/lib/command": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\index.js",
+        "diagram-js/lib/features/change-support": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnFactory.js": [function(require, module, exports) {
+        'use strict';
+
+        var map = require('lodash/collection/map'),
+            assign = require('lodash/object/assign'),
+            pick = require('lodash/object/pick');
+
+
+        function BpmnFactory(moddle) {
+            this._model = moddle;
+        }
+
+        BpmnFactory.$inject = ['moddle'];
+
+
+        BpmnFactory.prototype._needsId = function(element) {
+            return element.$instanceOf('bpmn:RootElement') ||
+                element.$instanceOf('bpmn:FlowElement') ||
+                element.$instanceOf('bpmn:MessageFlow') ||
+                element.$instanceOf('bpmn:Artifact') ||
+                element.$instanceOf('bpmn:Participant') ||
+                element.$instanceOf('bpmn:Process') ||
+                element.$instanceOf('bpmn:Collaboration') ||
+                element.$instanceOf('bpmndi:BPMNShape') ||
+                element.$instanceOf('bpmndi:BPMNEdge') ||
+                element.$instanceOf('bpmndi:BPMNDiagram') ||
+                element.$instanceOf('bpmndi:BPMNPlane');
+        };
+
+        BpmnFactory.prototype._ensureId = function(element) {
+
+            // generate semantic ids for elements
+            // bpmn:SequenceFlow -> SequenceFlow_ID
+            var prefix = (element.$type || '').replace(/^[^:]*:/g, '') + '_';
+
+            if (!element.id && this._needsId(element)) {
+                element.id = this._model.ids.nextPrefixed(prefix, element);
+            }
+        };
+
+
+        BpmnFactory.prototype.create = function(type, attrs) {
+            var element = this._model.create(type, attrs || {});
+
+            this._ensureId(element);
+
+            return element;
+        };
+
+
+        BpmnFactory.prototype.createDiLabel = function() {
+            return this.create('bpmndi:BPMNLabel', {
+                bounds: this.createDiBounds()
+            });
+        };
+
+
+        BpmnFactory.prototype.createDiShape = function(semantic, bounds, attrs) {
+
+            return this.create('bpmndi:BPMNShape', assign({
+                bpmnElement: semantic,
+                bounds: this.createDiBounds(bounds)
+            }, attrs));
+        };
+
+
+        BpmnFactory.prototype.createDiBounds = function(bounds) {
+            return this.create('dc:Bounds', bounds);
+        };
+
+
+        BpmnFactory.prototype.createDiWaypoints = function(waypoints) {
+            return map(waypoints, function(pos) {
+                return this.createDiWaypoint(pos);
+            }, this);
+        };
+
+        BpmnFactory.prototype.createDiWaypoint = function(point) {
+            return this.create('dc:Point', pick(point, ['x', 'y']));
+        };
+
+
+        BpmnFactory.prototype.createDiEdge = function(semantic, waypoints, attrs) {
+            return this.create('bpmndi:BPMNEdge', assign({
+                bpmnElement: semantic
+            }, attrs));
+        };
+
+        BpmnFactory.prototype.createDiPlane = function(semantic) {
+            return this.create('bpmndi:BPMNPlane', {
+                bpmnElement: semantic
+            });
+        };
+
+        module.exports = BpmnFactory;
+
+    }, {
+        "lodash/collection/map": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\map.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/pick": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnLayouter.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var assign = require('lodash/object/assign');
+
+        var BaseLayouter = require('diagram-js/lib/layout/BaseLayouter'),
+            LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'),
+            ManhattanLayout = require('diagram-js/lib/layout/ManhattanLayout');
+
+        var is = require('../../util/ModelUtil').is;
+
+
+        function BpmnLayouter() {}
+
+        inherits(BpmnLayouter, BaseLayouter);
+
+        module.exports = BpmnLayouter;
+
+
+        function getAttachment(waypoints, idx, shape) {
+            var point = waypoints && waypoints[idx];
+
+            return point ? (point.original || point) : LayoutUtil.getMidPoint(shape);
+        }
+
+
+        BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
+            var source = connection.source,
+                target = connection.target,
+                waypoints = connection.waypoints,
+                start,
+                end;
+
+            var layoutManhattan,
+                updatedWaypoints;
+
+            start = getAttachment(waypoints, 0, source);
+            end = getAttachment(waypoints, waypoints && waypoints.length - 1, target);
+
+            // manhattan layout sequence / message flows
+            if (is(connection, 'bpmn:MessageFlow')) {
+                layoutManhattan = {
+                    preferStraight: true,
+                    preferVertical: true
+                };
+            }
+
+            if (is(connection, 'bpmn:SequenceFlow')) {
+                layoutManhattan = {};
+            }
+
+            if (layoutManhattan) {
+
+                layoutManhattan = assign(layoutManhattan, hints);
+
+                updatedWaypoints =
+                    ManhattanLayout.repairConnection(
+                        source, target, start, end,
+                        waypoints,
+                        layoutManhattan);
+            }
+
+            return updatedWaypoints || [start, end];
+        };
+    }, {
+        "../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "diagram-js/lib/layout/BaseLayouter": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\BaseLayouter.js",
+        "diagram-js/lib/layout/LayoutUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js",
+        "diagram-js/lib/layout/ManhattanLayout": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\ManhattanLayout.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnUpdater.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach'),
+            inherits = require('inherits');
+
+        var Collections = require('diagram-js/lib/util/Collections'),
+            Model = require('diagram-js/lib/model');
+
+        var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+
+        /**
+         * A handler responsible for updating the underlying BPMN 2.0 XML + DI once
+         * changes on the diagram happen
+         */
+        function BpmnUpdater(eventBus, bpmnFactory, connectionDocking) {
+
+            CommandInterceptor.call(this, eventBus);
+
+            this._bpmnFactory = bpmnFactory;
+
+            var self = this;
+
+
+
+            // //// connection cropping /////////////////////////
+
+            // crop connection ends during create/update
+            function cropConnection(e) {
+                var context = e.context,
+                    connection;
+
+                if (!context.cropped) {
+                    connection = context.connection;
+                    connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
+                    context.cropped = true;
+                }
+            }
+
+            this.executed([
+                'connection.layout',
+                'connection.create',
+                'connection.reconnectEnd',
+                'connection.reconnectStart'
+            ], cropConnection);
+
+            this.reverted(['connection.layout'], function(e) {
+                delete e.context.cropped;
+            });
+
+
+
+            // //// BPMN + DI update /////////////////////////
+
+
+            // update parent
+            function updateParent(e) {
+                self.updateParent(e.context.shape || e.context.connection);
+            }
+
+            this.executed(['shape.move',
+                'shape.create',
+                'shape.delete',
+                'connection.create',
+                'connection.move',
+                'connection.delete'
+            ], updateParent);
+            this.reverted(['shape.move',
+                'shape.create',
+                'shape.delete',
+                'connection.create',
+                'connection.move',
+                'connection.delete'
+            ], updateParent);
+
+            /*
+             * ## Updating Parent
+             * 
+             * When morphing a Process into a Collaboration or vice-versa, make sure
+             * that both the *semantic* and *di* parent of each element is updated.
+             * 
+             */
+            function updateRoot(event) {
+                var context = event.context,
+                    oldRoot = context.oldRoot,
+                    children = oldRoot.children;
+
+                forEach(children, function(child) {
+                    self.updateParent(child);
+                });
+            }
+
+            this.executed(['canvas.updateRoot'], updateRoot);
+            this.reverted(['canvas.updateRoot'], updateRoot);
+
+
+            // update bounds
+            function updateBounds(e) {
+                self.updateBounds(e.context.shape);
+            }
+
+            this.executed(['shape.move', 'shape.create', 'shape.resize'], updateBounds);
+            this.reverted(['shape.move', 'shape.create', 'shape.resize'], updateBounds);
+
+
+            // attach / detach connection
+            function updateConnection(e) {
+                self.updateConnection(e.context.connection);
+            }
+
+            this.executed([
+                'connection.create',
+                'connection.move',
+                'connection.delete',
+                'connection.reconnectEnd',
+                'connection.reconnectStart'
+            ], updateConnection);
+
+            this.reverted([
+                'connection.create',
+                'connection.move',
+                'connection.delete',
+                'connection.reconnectEnd',
+                'connection.reconnectStart'
+            ], updateConnection);
+
+
+            // update waypoints
+            function updateConnectionWaypoints(e) {
+                self.updateConnectionWaypoints(e.context.connection);
+            }
+
+            this.executed([
+                'connection.layout',
+                'connection.move',
+                'connection.updateWaypoints',
+                'connection.reconnectEnd',
+                'connection.reconnectStart'
+            ], updateConnectionWaypoints);
+
+            this.reverted([
+                'connection.layout',
+                'connection.move',
+                'connection.updateWaypoints',
+                'connection.reconnectEnd',
+                'connection.reconnectStart'
+            ], updateConnectionWaypoints);
+        }
+
+        inherits(BpmnUpdater, CommandInterceptor);
+
+        module.exports = BpmnUpdater;
+
+        BpmnUpdater.$inject = ['eventBus', 'bpmnFactory', 'connectionDocking'];
+
+
+        // ///// implementation //////////////////////////////////
+
+
+        BpmnUpdater.prototype.updateParent = function(element) {
+
+            // do not update BPMN 2.0 label parent
+            if (element instanceof Model.Label) {
+                return;
+            }
+
+            var parentShape = element.parent;
+
+            var businessObject = element.businessObject,
+                parentBusinessObject = parentShape && parentShape.businessObject,
+                parentDi = parentBusinessObject && parentBusinessObject.di;
+
+            this.updateSemanticParent(businessObject, parentBusinessObject);
+
+            this.updateDiParent(businessObject.di, parentDi);
+        };
+
+
+        BpmnUpdater.prototype.updateBounds = function(shape) {
+
+            var di = shape.businessObject.di;
+
+            var bounds = (shape instanceof Model.Label) ? this._getLabel(di).bounds : di.bounds;
+
+            assign(bounds, {
+                x: shape.x,
+                y: shape.y,
+                width: shape.width,
+                height: shape.height
+            });
+        };
+
+
+        BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
+
+            if (parentDi && !parentDi.$instanceOf('bpmndi:BPMNPlane')) {
+                parentDi = parentDi.$parent;
+            }
+
+            if (di.$parent === parentDi) {
+                return;
+            }
+
+            var planeElements = (parentDi || di.$parent).get('planeElement');
+
+            if (parentDi) {
+                planeElements.push(di);
+                di.$parent = parentDi;
+            } else {
+                Collections.remove(planeElements, di);
+                di.$parent = null;
+            }
+        };
+
+        function getDefinitions(element) {
+            while (element && !element.$instanceOf('bpmn:Definitions')) {
+                element = element.$parent;
+            }
+
+            return element;
+        }
+
+        BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
+
+            var containment;
+
+            if (businessObject.$parent === newParent) {
+                return;
+            }
+
+            if (businessObject.$instanceOf('bpmn:FlowElement')) {
+
+                if (newParent && newParent.$instanceOf('bpmn:Participant')) {
+                    newParent = newParent.processRef;
+                }
+
+                containment = 'flowElements';
+
+            } else
+
+            if (businessObject.$instanceOf('bpmn:Artifact')) {
+
+                while (newParent &&
+                    !newParent.$instanceOf('bpmn:Process') &&
+                    !newParent.$instanceOf('bpmn:SubProcess') &&
+                    !newParent.$instanceOf('bpmn:Collaboration')) {
+
+                    if (newParent.$instanceOf('bpmn:Participant')) {
+                        newParent = newParent.processRef;
+                        break;
+                    } else {
+                        newParent = newParent.$parent;
+                    }
+                }
+
+                containment = 'artifacts';
+            } else
+
+            if (businessObject.$instanceOf('bpmn:MessageFlow')) {
+                containment = 'messageFlows';
+
+            } else
+
+            if (businessObject.$instanceOf('bpmn:Participant')) {
+                containment = 'participants';
+
+                // make sure the participants process is properly attached / detached
+                // from the XML document
+
+                var process = businessObject.processRef,
+                    definitions;
+
+                if (process) {
+                    definitions = getDefinitions(businessObject.$parent || newParent);
+
+                    if (businessObject.$parent) {
+                        Collections.remove(definitions.get('rootElements'), process);
+                        process.$parent = null;
+                    }
+
+                    if (newParent) {
+                        Collections.add(definitions.get('rootElements'), process);
+                        process.$parent = definitions;
+                    }
+                }
+            }
+
+            if (!containment) {
+                throw new Error('no parent for ', businessObject, newParent);
+            }
+
+            var children;
+
+            if (businessObject.$parent) {
+                // remove from old parent
+                children = businessObject.$parent.get(containment);
+                Collections.remove(children, businessObject);
+            }
+
+            if (!newParent) {
+                businessObject.$parent = null;
+            } else {
+                // add to new parent
+                children = newParent.get(containment);
+                children.push(businessObject);
+                businessObject.$parent = newParent;
+            }
+        };
+
+
+        BpmnUpdater.prototype.updateConnectionWaypoints = function(connection) {
+
+            connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
+        };
+
+
+        BpmnUpdater.prototype.updateConnection = function(connection) {
+
+            var businessObject = connection.businessObject,
+                newSource = connection.source && connection.source.businessObject,
+                newTarget = connection.target && connection.target.businessObject;
+
+            var inverseSet = businessObject.$instanceOf('bpmn:SequenceFlow');
+
+            if (businessObject.sourceRef !== newSource) {
+                if (inverseSet) {
+                    Collections.remove(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject);
+
+                    if (newSource) {
+                        newSource.get('outgoing').push(businessObject);
+                    }
+                }
+
+                businessObject.sourceRef = newSource;
+            }
+            if (businessObject.targetRef !== newTarget) {
+                if (inverseSet) {
+                    Collections.remove(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject);
+
+                    if (newTarget) {
+                        newTarget.get('incoming').push(businessObject);
+                    }
+                }
+
+                businessObject.targetRef = newTarget;
+            }
+
+            businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
+        };
+
+
+        // ///// helpers /////////////////////////////////////////
+
+        BpmnUpdater.prototype._getLabel = function(di) {
+            if (!di.label) {
+                di.label = this._bpmnFactory.createDiLabel();
+            }
+
+            return di.label;
+        };
+    }, {
+        "diagram-js/lib/command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "diagram-js/lib/model": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\model\\index.js",
+        "diagram-js/lib/util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ElementFactory.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            inherits = require('inherits');
+
+        var BaseElementFactory = require('diagram-js/lib/core/ElementFactory'),
+            LabelUtil = require('../../util/LabelUtil');
+
+
+        /**
+         * A bpmn-aware factory for diagram-js shapes
+         */
+        function ElementFactory(bpmnFactory, moddle) {
+            BaseElementFactory.call(this);
+
+            this._bpmnFactory = bpmnFactory;
+            this._moddle = moddle;
+        }
+
+        inherits(ElementFactory, BaseElementFactory);
+
+
+        ElementFactory.$inject = ['bpmnFactory', 'moddle'];
+
+        module.exports = ElementFactory;
+
+        ElementFactory.prototype.baseCreate = BaseElementFactory.prototype.create;
+
+        ElementFactory.prototype.create = function(elementType, attrs) {
+
+            // no special magic for labels,
+            // we assume their businessObjects have already been created
+            // and wired via attrs
+            if (elementType === 'label') {
+                return this.baseCreate(elementType, assign({
+                    type: 'label'
+                }, LabelUtil.DEFAULT_LABEL_SIZE, attrs));
+            }
+
+            attrs = attrs || {};
+
+            var businessObject = attrs.businessObject,
+                size;
+
+            if (!businessObject) {
+                if (!attrs.type) {
+                    throw new Error('no shape type specified');
+                }
+
+                businessObject = this._bpmnFactory.create(attrs.type);
+            }
+
+            if (!businessObject.di) {
+                if (elementType === 'root') {
+                    businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], {
+                        id: businessObject.id + '_di'
+                    });
+                } else
+                if (elementType === 'connection') {
+                    businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
+                        id: businessObject.id + '_di'
+                    });
+                } else {
+                    businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, {
+                        id: businessObject.id + '_di'
+                    });
+                }
+            }
+
+            if (!!attrs.isExpanded) {
+                businessObject.di.isExpanded = attrs.isExpanded;
+            }
+
+            /*
+             * if (businessObject.$instanceOf('bpmn:ExclusiveGateway')) {
+             * businessObject.di.isMarkerVisible = true; }
+             */
+
+            if (attrs._eventDefinitionType) {
+                var eventDefinitions = businessObject.get('eventDefinitions') || [],
+                    newEventDefinition = this._moddle.create(attrs._eventDefinitionType);
+
+                eventDefinitions.push(newEventDefinition);
+                businessObject.eventDefinitions = eventDefinitions;
+            }
+
+            size = this._getDefaultSize(businessObject);
+
+            attrs = assign({
+                businessObject: businessObject,
+                id: businessObject.id
+            }, size, attrs);
+
+            return this.baseCreate(elementType, attrs);
+        };
+
+
+        ElementFactory.prototype._getDefaultSize = function(semantic) {
+
+            if (semantic.$instanceOf('bpmn:SubProcess')) {
+                var isExpanded = semantic.di.isExpanded === true;
+
+                if (isExpanded) {
+                    return {
+                        width: 350,
+                        height: 200
+                    };
+                } else {
+                    return {
+                        width: 100,
+                        height: 80
+                    };
+                }
+            }
+
+            if (semantic.$instanceOf('bpmn:InitiateProcess')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+            if (semantic.$instanceOf('bpmn:Collector')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+        
+                       if (semantic.$instanceOf('bpmn:StringMatch')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+                       
+                       if (semantic.$instanceOf('bpmn:TCA')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+                       
+                       if (semantic.$instanceOf('bpmn:Policy')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+                       
+                       if (semantic.$instanceOf('bpmn:GOC')) {
+                return {
+                    width: 120,
+                    height: 80
+                };
+            }
+            if (semantic.$instanceOf('bpmn:ParentReturn')) {
+                return {
+                    width: 100,
+                    height: 80
+                };
+            }
+            if (semantic.$instanceOf('bpmn:SubProcessCall')) {
+                return {
+                    width: 100,
+                    height: 80
+                };
+            }
+
+            if (semantic.$instanceOf('bpmn:ExclusiveGateway')) {
+                return {
+                    width: 100,
+                    height: 80
+                };
+            }
+
+            if (semantic.$instanceOf('bpmn:Task')) {
+                return {
+                    width: 100,
+                    height: 80
+                };
+            }
+
+            if (semantic.$instanceOf('bpmn:Gateway')) {
+                return {
+                    width: 100,
+                    height: 100
+                };
+            }
+
+            if (semantic.$instanceOf('bpmn:Event')) {
+                return {
+                    width: 36,
+                    height: 36
+                };
+            }
+
+            if (semantic.$instanceOf('bpmn:Participant')) {
+                return {
+                    width: 100,
+                    height: 80
+                };
+            }
+
+            return {
+                width: 100,
+                height: 80
+            };
+        };
+
+
+        ElementFactory.prototype.createParticipantShape = function(collapsed) {
+            // alert("entering createParticipantShape");
+            var participantShape = this.createShape({
+                type: 'bpmn:Participant'
+            });
+
+            if (!collapsed) {
+                participantShape.businessObject.processRef = this._bpmnFactory.create('bpmn:Process');
+            }
+
+            return participantShape;
+        };
+    }, {
+        "../../util/LabelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\LabelUtil.js",
+        "diagram-js/lib/core/ElementFactory": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\ElementFactory.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\LabelSupport.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+        var LabelUtil = require('../../util/LabelUtil');
+
+        var hasExternalLabel = LabelUtil.hasExternalLabel,
+            getExternalLabelMid = LabelUtil.getExternalLabelMid;
+
+
+        function LabelSupport(eventBus, modeling, bpmnFactory) {
+
+            // create external labels on shape creation
+
+            eventBus.on([
+                'commandStack.shape.create.postExecute',
+                'commandStack.connection.create.postExecute'
+            ], function(e) {
+                var context = e.context;
+
+                var element = context.shape || context.connection,
+                    businessObject = element.businessObject;
+
+                var position;
+
+                if (hasExternalLabel(businessObject)) {
+                    position = getExternalLabelMid(element);
+                    modeling.createLabel(element, position, {
+                        id: businessObject.id + '_label',
+                        businessObject: businessObject
+                    });
+                }
+            });
+
+
+            //move label when connection/shape is being moved
+            //if shape is being moved, get connection as element
+            
+            eventBus.on(['commandStack.connection.create.postExecute',
+                         'commandStack.connection.move.postExecute',
+                         //'commandStack.connection.delete.postExecute',
+                         'commandStack.connection.reconnectEnd.postExecute',
+                         'commandStack.connection.reconnectStart.postExecute',
+                         'commandStack.connection.updateWaypoints.postExecute',
+                         'shape.move.end'
+                     ],function(e){
+                               
+                               var context = e.context;
+                               var element;
+                               
+                               if(context.allDraggedElements != null){
+                                       if(context.allDraggedElements.length > 0){
+                                               element = context.allDraggedElements[1];
+                                       }
+                               }else{
+                                       element = context.connection;
+                               }
+                               
+                               if(element==null){
+                                       return;
+                               }
+               
+                               var businessObject = element.businessObject;
+                               
+                               if(businessObject.$type != 'bpmn:SequenceFlow'){
+                                       return;
+                               }
+                               
+                               var position;
+               
+                               if (hasExternalLabel(businessObject)) {
+                                   position = getExternalLabelMid(element);
+                                   modeling.removeShape(element.label);
+                                   modeling.createLabel(element, position, {
+                                       id: businessObject.id + '_label',
+                                       businessObject: businessObject
+                                   });
+                               }
+               
+            });
+            
+            
+            // indicate label is dragged during move
+
+            // we need to add labels to the list of selected
+            // shapes before the visuals get drawn.
+            //
+            // Hence this awesome magic number.
+            //
+            eventBus.on('shape.move.start', function(e) {
+
+                var context = e.context,
+                    shapes = context.shapes;
+
+                var labels = [];
+
+                forEach(shapes, function(element) {
+                    var label = element.label;
+
+                    if (label && !label.hidden && context.shapes.indexOf(label) === -1) {
+                        labels.push(label);
+                    }
+                });
+
+                forEach(labels, function(label) {
+                    shapes.push(label);
+                });
+            });
+
+
+            // move labels with shapes
+
+            eventBus.on([
+                'commandStack.shapes.move.postExecute'
+            ], function(e) {
+
+                var context = e.context,
+                    closure = context.closure,
+                    enclosedElements = closure.enclosedElements;
+
+                // ensure we move all labels with their respective elements
+                // if they have not been moved already
+
+                forEach(enclosedElements, function(e) {
+                    if (e.label && !enclosedElements[e.label.id]) {
+                        modeling.moveShape(e.label, context.delta, e.parent);
+                    }
+                });
+            });
+
+
+            // update di information on label movement and creation
+
+            eventBus.on([
+                'commandStack.label.create.executed',
+                'commandStack.shape.moved.executed'
+            ], function(e) {
+
+                var element = e.context.shape,
+                    businessObject = element.businessObject,
+                    di = businessObject.di;
+
+                // we want to trigger on real labels only
+                if (!element.labelTarget) {
+                    return;
+                }
+
+                if (!di.label) {
+                    di.label = bpmnFactory.create('bpmndi:BPMNLabel', {
+                        bounds: bpmnFactory.create('dc:Bounds')
+                    });
+                }
+
+                assign(di.label.bounds, {
+                    x: element.x,
+                    y: element.y,
+                    width: element.width,
+                    height: element.height
+                });
+            });
+        }
+
+        LabelSupport.$inject = ['eventBus', 'modeling', 'bpmnFactory'];
+
+        module.exports = LabelSupport;
+
+    }, {
+        "../../util/LabelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\LabelUtil.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\Modeling.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var BaseModeling = require('diagram-js/lib/features/modeling/Modeling');
+
+        var UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler'),
+            UpdateCanvasRootHandler = require('./cmd/UpdateCanvasRootHandler');
+
+
+        /**
+         * BPMN 2.0 modeling features activator
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {ElementFactory}
+         *            elementFactory
+         * @param {CommandStack}
+         *            commandStack
+         * @param {BpmnRules}
+         *            bpmnRules
+         */
+        function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
+            BaseModeling.call(this, eventBus, elementFactory, commandStack);
+
+            this._bpmnRules = bpmnRules;
+        }
+
+        inherits(Modeling, BaseModeling);
+
+        Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules'];
+
+        module.exports = Modeling;
+
+
+        Modeling.prototype.getHandlers = function() {
+            var handlers = BaseModeling.prototype.getHandlers.call(this);
+
+            handlers['element.updateProperties'] = UpdatePropertiesHandler;
+            handlers['canvas.updateRoot'] = UpdateCanvasRootHandler;
+
+            return handlers;
+        };
+
+
+        Modeling.prototype.updateLabel = function(element, newLabel) {
+            this._commandStack.execute('element.updateLabel', {
+                element: element,
+                newLabel: newLabel
+            });
+        };
+
+
+        var getSharedParent = require('./ModelingUtil').getSharedParent;
+
+        Modeling.prototype.connect = function(source, target, attrs) {
+
+            var bpmnRules = this._bpmnRules;
+
+            if (!attrs) {
+                if (bpmnRules.canConnectMessageFlow(source, target)) {
+                    attrs = {
+                        type: 'bpmn:MessageFlow'
+                    };
+                } else
+                if (bpmnRules.canConnectSequenceFlow(source, target)) {
+                    attrs = {
+                        type: 'bpmn:SequenceFlow'
+                    };
+                } else {
+                    attrs = {
+                        type: 'bpmn:Association'
+                    };
+                }
+            }
+
+            return this.createConnection(source, target, attrs, getSharedParent(source, target));
+        };
+
+
+        Modeling.prototype.updateProperties = function(element, properties) {
+            this._commandStack.execute('element.updateProperties', {
+                element: element,
+                properties: properties
+            });
+        };
+
+
+        /**
+         * Transform the current diagram into a collaboration.
+         * 
+         * @return {djs.model.Root} the new root element
+         */
+        Modeling.prototype.makeCollaboration = function() {
+
+            var collaborationElement = this._create('root', {
+                type: 'bpmn:Collaboration'
+            });
+
+            var context = {
+                newRoot: collaborationElement
+            };
+
+            this._commandStack.execute('canvas.updateRoot', context);
+
+            return collaborationElement;
+        };
+
+        /**
+         * Transform the current diagram into a process.
+         * 
+         * @return {djs.model.Root} the new root element
+         */
+        Modeling.prototype.makeProcess = function() {
+
+            var processElement = this._create('root', {
+                type: 'bpmn:Process'
+            });
+
+            var context = {
+                newRoot: processElement
+            };
+
+            this._commandStack.execute('canvas.updateRoot', context);
+        };
+    }, {
+        "./ModelingUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ModelingUtil.js",
+        "./cmd/UpdateCanvasRootHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\cmd\\UpdateCanvasRootHandler.js",
+        "./cmd/UpdatePropertiesHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\cmd\\UpdatePropertiesHandler.js",
+        "diagram-js/lib/features/modeling/Modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\Modeling.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ModelingUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        var find = require('lodash/collection/find');
+
+
+        function getParents(element) {
+
+            var parents = [];
+
+            while (element) {
+                element = element.parent;
+
+                if (element) {
+                    parents.push(element);
+                }
+            }
+
+            return parents;
+        }
+
+        module.exports.getParents = getParents;
+
+
+        function getSharedParent(a, b) {
+
+            var parentsA = getParents(a),
+                parentsB = getParents(b);
+
+            return find(parentsA, function(parent) {
+                return parentsB.indexOf(parent) !== -1;
+            });
+        }
+
+        module.exports.getSharedParent = getSharedParent;
+    }, {
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\AppendBehavior.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var is = require('../../../util/ModelUtil').is;
+
+        var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+
+        function AppendBehavior(eventBus, elementFactory, bpmnRules) {
+
+            CommandInterceptor.call(this, eventBus);
+
+            // assign correct shape position unless already set
+
+            this.preExecute('shape.append', function(context) {
+
+                var source = context.source,
+                    shape = context.shape;
+
+                if (!context.position) {
+
+                    if (is(shape, 'bpmn:TextAnnotation')) {
+                        context.position = {
+                            x: source.x + source.width / 2 + 75,
+                            y: source.y - (50) - shape.height / 2
+                        };
+                    } else {
+                        context.position = {
+                            x: source.x + source.width + 80 + shape.width / 2,
+                            y: source.y + source.height / 2
+                        };
+                    }
+                }
+            }, true);
+        }
+
+
+        AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules'];
+
+        inherits(AppendBehavior, CommandInterceptor);
+
+        module.exports = AppendBehavior;
+    }, {
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "diagram-js/lib/command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\CreateBehavior.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+        var is = require('../../../util/ModelUtil').is;
+
+        /**
+         * BPMN specific create behavior
+         */
+        function CreateBehavior(eventBus, modeling) {
+
+            CommandInterceptor.call(this, eventBus);
+
+
+            /**
+             * morph process into collaboration before adding participant onto
+             * collaboration
+             */
+
+            this.preExecute('shape.create', function(context) {
+
+                var parent = context.parent,
+                    shape = context.shape,
+                    position = context.position;
+
+                if (is(parent, 'bpmn:Process') && is(shape, 'bpmn:Participant')) {
+
+                    // this is going to detach the process root
+                    // and set the returned collaboration element
+                    // as the new root element
+                    var collaborationElement = modeling.makeCollaboration();
+
+                    // monkey patch the create context
+                    // so that the participant is being dropped
+                    // onto the new collaboration root instead
+                    context.position = position;
+                    context.parent = collaborationElement;
+
+                    context.processRoot = parent;
+                }
+            }, true);
+
+            this.execute('shape.create', function(context) {
+
+                var processRoot = context.processRoot,
+                    shape = context.shape;
+
+                if (processRoot) {
+                    context.oldProcessRef = shape.businessObject.processRef;
+
+                    // assign the participant processRef
+                    shape.businessObject.processRef = processRoot.businessObject;
+                }
+            }, true);
+
+            this.revert('shape.create', function(context) {
+                var processRoot = context.processRoot,
+                    shape = context.shape;
+
+                if (processRoot) {
+                    // assign the participant processRef
+                    shape.businessObject.processRef = context.oldProcessRef;
+                }
+            }, true);
+
+            this.postExecute('shape.create', function(context) {
+                               
+                var processRoot = context.processRoot,
+                    shape = context.shape;
+
+                if (processRoot) {
+                    // process root is already detached at this point
+                    var processChildren = processRoot.children.slice();
+                    modeling.moveShapes(processChildren, {
+                        x: 0,
+                        y: 0
+                    }, shape);
+                }
+                               //console.log(context.shape.id);
+                               //newElementProcessor(context.shape.id);
+                               //console.log(context)
+            }, true);
+                       
+        }
+
+        CreateBehavior.$inject = ['eventBus', 'modeling'];
+
+        inherits(CreateBehavior, CommandInterceptor);
+
+        module.exports = CreateBehavior;
+    }, {
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "diagram-js/lib/command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\DropBehavior.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            inherits = require('inherits');
+
+        var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+        var is = require('../../../util/ModelUtil').is,
+            getSharedParent = require('../ModelingUtil').getSharedParent;
+
+
+        function DropBehavior(eventBus, modeling, bpmnRules) {
+
+            CommandInterceptor.call(this, eventBus);
+
+            // remove sequence flows that should not be allowed
+            // after a move operation
+
+            this.postExecute('shapes.move', function(context) {
+
+                var closure = context.closure,
+                    allConnections = closure.allConnections;
+
+                forEach(allConnections, function(c) {
+
+                    var source = c.source,
+                        target = c.target;
+
+                    var replacementType,
+                        remove;
+
+                    /**
+                     * Check if incoming or outgoing connections can stay or could be
+                     * substituted with an appropriate replacement.
+                     * 
+                     * This holds true for SequenceFlow <> MessageFlow.
+                     */
+
+                    if (is(c, 'bpmn:SequenceFlow')) {
+                        if (!bpmnRules.canConnectSequenceFlow(source, target)) {
+                            remove = true;
+                        }
+
+                        if (bpmnRules.canConnectMessageFlow(source, target)) {
+                            replacementType = 'bpmn:MessageFlow';
+                        }
+                    }
+
+                    // transform message flows into sequence flows, if possible
+
+                    if (is(c, 'bpmn:MessageFlow')) {
+
+                        if (!bpmnRules.canConnectMessageFlow(source, target)) {
+                            remove = true;
+                        }
+
+                        if (bpmnRules.canConnectSequenceFlow(source, target)) {
+                            replacementType = 'bpmn:SequenceFlow';
+                        }
+                    }
+
+                    if (is(c, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
+                        remove = true;
+                    }
+
+
+                    // remove invalid connection
+                    if (remove) {
+                        modeling.removeConnection(c);
+                    }
+
+                    // replace SequenceFlow <> MessageFlow
+
+                    if (replacementType) {
+                        modeling.createConnection(source, target, {
+                            type: replacementType,
+                            waypoints: c.waypoints.slice()
+                        }, getSharedParent(source, target));
+                    }
+                });
+            }, true);
+        }
+
+        inherits(DropBehavior, CommandInterceptor);
+
+        DropBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules'];
+
+        module.exports = DropBehavior;
+    }, {
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "../ModelingUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ModelingUtil.js",
+        "diagram-js/lib/command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\ModelingFeedback.js": [function(require, module, exports) {
+        'use strict';
+
+        var is = require('../../../util/ModelUtil').is;
+
+
+        function ModelingFeedback(eventBus, tooltips) {
+
+            function showError(position, message) {
+                tooltips.add({
+                    position: {
+                        x: position.x + 5,
+                        y: position.y + 5
+                    },
+                    type: 'error',
+                    timeout: 2000,
+                    html: '<div>' + message + '</div>'
+                });
+            }
+
+            eventBus.on(['shape.move.rejected', 'create.rejected'], function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    target = context.target;
+
+                if (is(target, 'bpmn:Collaboration') && is(shape, 'bpmn:FlowNode')) {
+                    showError(event, 'flow elements must be children of pools/participants');
+                }
+            });
+
+        }
+
+
+        ModelingFeedback.$inject = ['eventBus', 'tooltips'];
+
+        module.exports = ModelingFeedback;
+    }, {
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\RemoveBehavior.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
+
+        var is = require('../../../util/ModelUtil').is;
+
+
+        /**
+         * BPMN specific remove behavior
+         */
+        function RemoveBehavior(eventBus, modeling) {
+
+            CommandInterceptor.call(this, eventBus);
+
+
+            /**
+             * morph collaboration diagram into process diagram after the last
+             * participant has been removed
+             */
+
+            this.preExecute('shape.delete', function(context) {
+                               //delete elementMap[context.shape.id];
+                               //console.log(context.shape.id);
+                var shape = context.shape,
+                    parent = shape.parent;
+
+                // activate the behavior if the shape to be removed
+                // is a participant
+                if (is(shape, 'bpmn:Participant')) {
+                    context.collaborationRoot = parent;
+                }
+            }, true);
+
+            this.postExecute('shape.delete', function(context) {
+
+                var collaborationRoot = context.collaborationRoot;
+
+                if (collaborationRoot && !collaborationRoot.businessObject.participants.length) {
+                    // replace empty collaboration with process diagram
+                    modeling.makeProcess();
+                }
+            }, true);
+
+        }
+
+        RemoveBehavior.$inject = ['eventBus', 'modeling'];
+
+        inherits(RemoveBehavior, CommandInterceptor);
+
+        module.exports = RemoveBehavior;
+    }, {
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "diagram-js/lib/command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: [
+                'appendBehavior',
+                'createBehavior',
+                'dropBehavior',
+                'removeBehavior',
+                'modelingFeedback'
+            ],
+            appendBehavior: ['type', require('./AppendBehavior')],
+            dropBehavior: ['type', require('./DropBehavior')],
+            createBehavior: ['type', require('./CreateBehavior')],
+            removeBehavior: ['type', require('./RemoveBehavior')],
+            modelingFeedback: ['type', require('./ModelingFeedback')]
+        };
+    }, {
+        "./AppendBehavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\AppendBehavior.js",
+        "./CreateBehavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\CreateBehavior.js",
+        "./DropBehavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\DropBehavior.js",
+        "./ModelingFeedback": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\ModelingFeedback.js",
+        "./RemoveBehavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\RemoveBehavior.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\cmd\\UpdateCanvasRootHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var Collections = require('diagram-js/lib/util/Collections');
+
+
+        function UpdateCanvasRootHandler(canvas, modeling) {
+            this._canvas = canvas;
+            this._modeling = modeling;
+        }
+
+        UpdateCanvasRootHandler.$inject = ['canvas', 'modeling'];
+
+        module.exports = UpdateCanvasRootHandler;
+
+
+        UpdateCanvasRootHandler.prototype.execute = function(context) {
+
+            var canvas = this._canvas;
+
+            var newRoot = context.newRoot,
+                newRootBusinessObject = newRoot.businessObject,
+                oldRoot = canvas.getRootElement(),
+                oldRootBusinessObject = oldRoot.businessObject,
+                bpmnDefinitions = oldRootBusinessObject.$parent,
+                diPlane = oldRootBusinessObject.di;
+
+            // (1) replace process old <> new root
+            canvas.setRootElement(newRoot, true);
+
+            // (2) update root elements
+            Collections.add(bpmnDefinitions.rootElements, newRootBusinessObject);
+            newRootBusinessObject.$parent = bpmnDefinitions;
+
+            Collections.remove(bpmnDefinitions.rootElements, oldRootBusinessObject);
+            oldRootBusinessObject.$parent = null;
+
+            // (3) wire di
+            oldRootBusinessObject.di = null;
+
+            diPlane.bpmnElement = newRootBusinessObject;
+            newRootBusinessObject.di = diPlane;
+
+            context.oldRoot = oldRoot;
+        };
+
+
+        UpdateCanvasRootHandler.prototype.revert = function(context) {
+
+            var canvas = this._canvas;
+
+            var newRoot = context.newRoot,
+                newRootBusinessObject = newRoot.businessObject,
+                oldRoot = context.oldRoot,
+                oldRootBusinessObject = oldRoot.businessObject,
+                bpmnDefinitions = newRootBusinessObject.$parent,
+                diPlane = newRootBusinessObject.di;
+
+            // (1) replace process old <> new root
+            canvas.setRootElement(oldRoot, true);
+
+            // (2) update root elements
+            Collections.remove(bpmnDefinitions.rootElements, newRootBusinessObject);
+            newRootBusinessObject.$parent = null;
+
+            Collections.add(bpmnDefinitions.rootElements, oldRootBusinessObject);
+            oldRootBusinessObject.$parent = bpmnDefinitions;
+
+            // (3) wire di
+            newRootBusinessObject.di = null;
+
+            diPlane.bpmnElement = oldRootBusinessObject;
+            oldRootBusinessObject.di = diPlane;
+        };
+    }, {
+        "diagram-js/lib/util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\cmd\\UpdatePropertiesHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            pick = require('lodash/object/pick'),
+            keys = require('lodash/object/keys');
+
+        var DEFAULT_FLOW = 'default',
+            NAME = 'name',
+            ID = 'id';
+
+
+        /**
+         * A handler that implements a BPMN 2.0 property update.
+         * 
+         * This should be used to set simple properties on elements with an underlying
+         * BPMN business object.
+         * 
+         * Use respective diagram-js provided handlers if you would like to perform
+         * automated modeling.
+         */
+        function UpdatePropertiesHandler(elementRegistry) {
+            this._elementRegistry = elementRegistry;
+        }
+
+        UpdatePropertiesHandler.$inject = ['elementRegistry'];
+
+        module.exports = UpdatePropertiesHandler;
+
+
+        // //// api /////////////////////////////////////////////
+
+        /**
+         * Updates a BPMN element with a list of new properties
+         * 
+         * @param {Object}
+         *            context
+         * @param {djs.model.Base}
+         *            context.element the element to update
+         * @param {Object}
+         *            context.properties a list of properties to set on the element's
+         *            businessObject (the BPMN model element)
+         * 
+         * @return {Array<djs.mode.Base>} the updated element
+         */
+        UpdatePropertiesHandler.prototype.execute = function(context) {
+
+            var element = context.element,
+                changed = [element];
+
+            if (!element) {
+                throw new Error('element required');
+            }
+
+            var elementRegistry = this._elementRegistry;
+
+            var businessObject = element.businessObject,
+                properties = context.properties,
+                oldProperties = context.oldProperties || pick(businessObject, keys(properties));
+
+            if (ID in properties) {
+                elementRegistry.updateId(element, properties[ID]);
+            }
+
+            // correctly indicate visual changes on default flow updates
+            if (DEFAULT_FLOW in properties) {
+
+                if (properties[DEFAULT_FLOW]) {
+                    changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id));
+                }
+
+                if (businessObject[DEFAULT_FLOW]) {
+                    changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id));
+                }
+            }
+
+            if (NAME in properties && element.label) {
+                changed.push(element.label);
+            }
+
+            // update properties
+            assign(businessObject, properties);
+
+
+            // store old values
+            context.oldProperties = oldProperties;
+            context.changed = changed;
+
+            // indicate changed on objects affected by the update
+            return changed;
+        };
+
+        /**
+         * Reverts the update on a BPMN elements properties.
+         * 
+         * @param {Object}
+         *            context
+         * 
+         * @return {djs.mode.Base} the updated element
+         */
+        UpdatePropertiesHandler.prototype.revert = function(context) {
+
+            var element = context.element,
+                oldProperties = context.oldProperties,
+                businessObject = element.businessObject,
+                elementRegistry = this._elementRegistry;
+
+            assign(businessObject, context.oldProperties);
+
+            if (ID in oldProperties) {
+                elementRegistry.updateId(element, oldProperties[ID]);
+            }
+
+            return context.changed;
+        };
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js",
+        "lodash/object/pick": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['modeling', 'bpmnUpdater', 'labelSupport'],
+            __depends__: [
+                require('../label-editing'),
+                require('./rules'),
+                require('./behavior'),
+                require('diagram-js/lib/command'),
+                require('diagram-js/lib/features/tooltips'),
+                require('diagram-js/lib/features/change-support')
+            ],
+            bpmnFactory: ['type', require('./BpmnFactory')],
+            bpmnUpdater: ['type', require('./BpmnUpdater')],
+            elementFactory: ['type', require('./ElementFactory')],
+            modeling: ['type', require('./Modeling')],
+            labelSupport: ['type', require('./LabelSupport')],
+            layouter: ['type', require('./BpmnLayouter')],
+            connectionDocking: ['type', require('diagram-js/lib/layout/CroppingConnectionDocking')]
+        };
+
+    }, {
+        "../label-editing": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\label-editing\\index.js",
+        "./BpmnFactory": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnFactory.js",
+        "./BpmnLayouter": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnLayouter.js",
+        "./BpmnUpdater": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\BpmnUpdater.js",
+        "./ElementFactory": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ElementFactory.js",
+        "./LabelSupport": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\LabelSupport.js",
+        "./Modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\Modeling.js",
+        "./behavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\behavior\\index.js",
+        "./rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\rules\\index.js",
+        "diagram-js/lib/command": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\index.js",
+        "diagram-js/lib/features/change-support": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\index.js",
+        "diagram-js/lib/features/tooltips": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\tooltips\\index.js",
+        "diagram-js/lib/layout/CroppingConnectionDocking": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\CroppingConnectionDocking.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\rules\\BpmnRules.js": [function(require, module, exports) {
+        'use strict';
+
+        var groupBy = require('lodash/collection/groupBy'),
+            size = require('lodash/collection/size'),
+            find = require('lodash/collection/find'),
+            inherits = require('inherits');
+
+        var getParents = require('../ModelingUtil').getParents,
+            is = require('../../../util/ModelUtil').is,
+            getBusinessObject = require('../../../util/ModelUtil').getBusinessObject,
+            isExpanded = require('../../../util/DiUtil').isExpanded;
+
+
+        var RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
+
+        /**
+         * BPMN specific modeling rule
+         */
+        function BpmnRules(eventBus) {
+            RuleProvider.call(this, eventBus);
+        }
+
+        inherits(BpmnRules, RuleProvider);
+
+        BpmnRules.$inject = ['eventBus'];
+
+        module.exports = BpmnRules;
+
+        BpmnRules.prototype.init = function() {
+
+            this.addRule('connection.create', function(context) {
+                var source = context.source,
+                    target = context.target;
+
+                return canConnect(source, target);
+            });
+
+            this.addRule('connection.reconnectStart', function(context) {
+
+                var connection = context.connection,
+                    source = context.hover || context.source,
+                    target = connection.target;
+
+                return canConnect(source, target, connection);
+            });
+
+            this.addRule('connection.reconnectEnd', function(context) {
+
+                var connection = context.connection,
+                    source = connection.source,
+                    target = context.hover || context.target;
+
+                return canConnect(source, target, connection);
+            });
+
+            this.addRule('connection.updateWaypoints', function(context) {
+                // OK! but visually ignore
+                return null;
+            });
+
+            this.addRule('shape.resize', function(context) {
+
+                var shape = context.shape,
+                    newBounds = context.newBounds;
+
+                return canResize(shape, newBounds);
+            });
+
+            this.addRule('shapes.move', function(context) {
+
+                var target = context.newParent,
+                    shapes = context.shapes;
+
+                return canMove(shapes, target);
+            });
+
+            this.addRule(['shape.create', 'shape.append'], function(context) {
+                var target = context.parent,
+                    shape = context.shape,
+                    source = context.source;
+
+                return canCreate(shape, target, source);
+            });
+
+        };
+
+        BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow;
+
+        BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow;
+
+        BpmnRules.prototype.canConnectAssociation = canConnectAssociation;
+
+        BpmnRules.prototype.canMove = canMove;
+
+        BpmnRules.prototype.canDrop = canDrop;
+
+        BpmnRules.prototype.canCreate = canCreate;
+
+        BpmnRules.prototype.canConnect = canConnect;
+
+        BpmnRules.prototype.canResize = canResize;
+
+        /**
+         * Utility functions for rule checking
+         */
+
+        function nonExistantOrLabel(element) {
+            return !element || isLabel(element);
+        }
+
+        function isSame(a, b) {
+            return a === b;
+        }
+
+        function getOrganizationalParent(element) {
+
+            var bo = getBusinessObject(element);
+
+            while (bo && !is(bo, 'bpmn:Process')) {
+                if (is(bo, 'bpmn:Participant')) {
+                    return bo.processRef || bo;
+                }
+
+                bo = bo.$parent;
+            }
+
+            return bo;
+        }
+
+        function isSameOrganization(a, b) {
+            var parentA = getOrganizationalParent(a),
+                parentB = getOrganizationalParent(b);
+
+            return parentA === parentB;
+        }
+
+        function isMessageFlowSource(element) {
+            return is(element, 'bpmn:InteractionNode') && (!is(element, 'bpmn:Event') || (
+                is(element, 'bpmn:ThrowEvent') &&
+                hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')
+            ));
+        }
+
+        function isMessageFlowTarget(element) {
+            return is(element, 'bpmn:InteractionNode') && (!is(element, 'bpmn:Event') || (
+                is(element, 'bpmn:CatchEvent') &&
+                hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')
+            ));
+        }
+
+        function getScopeParent(element) {
+
+            var bo = getBusinessObject(element);
+
+            if (is(bo, 'bpmn:Participant')) {
+                return null;
+            }
+
+            while (bo) {
+                bo = bo.$parent;
+
+                if (is(bo, 'bpmn:FlowElementsContainer')) {
+                    return bo;
+                }
+            }
+
+            return bo;
+        }
+
+        function isSameScope(a, b) {
+            var scopeParentA = getScopeParent(a),
+                scopeParentB = getScopeParent(b);
+
+            return scopeParentA && (scopeParentA === scopeParentB);
+        }
+
+        function hasEventDefinition(element, eventDefinition) {
+            var bo = getBusinessObject(element);
+
+            return !!find(bo.eventDefinitions || [], function(definition) {
+                return is(definition, eventDefinition);
+            });
+        }
+
+        function hasEventDefinitionOrNone(element, eventDefinition) {
+            var bo = getBusinessObject(element);
+
+            return (bo.eventDefinitions || []).every(function(definition) {
+                return is(definition, eventDefinition);
+            });
+        }
+
+        function isSequenceFlowSource(element) {
+            return is(element, 'bpmn:FlowNode') && !is(element, 'bpmn:EndEvent') && !(
+                is(element, 'bpmn:IntermediateThrowEvent') &&
+                hasEventDefinition(element, 'bpmn:LinkEventDefinition')
+            );
+        }
+
+        function isSequenceFlowTarget(element) {
+            return is(element, 'bpmn:FlowNode') && !is(element, 'bpmn:StartEvent') && !(
+                is(element, 'bpmn:IntermediateCatchEvent') &&
+                hasEventDefinition(element, 'bpmn:LinkEventDefinition')
+            );
+        }
+
+        function isEventBasedTarget(element) {
+            return is(element, 'bpmn:ReceiveTask') || (
+                is(element, 'bpmn:IntermediateCatchEvent') && (
+                    hasEventDefinition(element, 'bpmn:MessageEventDefinition') ||
+                    hasEventDefinition(element, 'bpmn:TimerEventDefinition') ||
+                    hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') ||
+                    hasEventDefinition(element, 'bpmn:SignalEventDefinition')
+                )
+            );
+        }
+
+        function isLabel(element) {
+            return element.labelTarget;
+        }
+
+        function isConnection(element) {
+            return element.waypoints;
+        }
+
+        function isParent(possibleParent, element) {
+            var allParents = getParents(element);
+            return allParents.indexOf(possibleParent) !== -1;
+        }
+
+        function canConnect(source, target, connection) {
+
+            if (nonExistantOrLabel(source) || nonExistantOrLabel(target)) {
+                return null;
+            }
+
+            // See https://github.com/bpmn-io/bpmn-js/issues/178
+            // as a workround we disallow connections with same
+            // target and source element.
+            // This rule must be removed if a auto layout for this
+            // connections is implemented.
+            if (isSame(source, target)) {
+                return false;
+            }
+
+            if (canConnectMessageFlow(source, target) ||
+                canConnectSequenceFlow(source, target)) {
+
+                return true;
+            }
+
+            if (is(connection, 'bpmn:Association')) {
+                return canConnectAssociation(source, target);
+            }
+
+            return false;
+        }
+
+        /**
+         * Can an element be dropped into the target element
+         * 
+         * @return {Boolean}
+         */
+        function canDrop(element, target) {
+
+            // can move labels everywhere
+            if (isLabel(element) && !isConnection(target)) {
+                return true;
+            }
+
+            // allow to create new participants on
+            // on existing collaboration and process diagrams
+            if (is(element, 'bpmn:Participant')) {
+                return is(target, 'bpmn:Process') || is(target, 'bpmn:Collaboration');
+            }
+
+            // drop flow elements onto flow element containers
+            // and participants
+            if (is(element, 'bpmn:FlowElement')) {
+                if (is(target, 'bpmn:FlowElementsContainer')) {
+                    return isExpanded(target) !== false;
+                }
+
+                return is(target, 'bpmn:Participant');
+            }
+
+            if (is(element, 'bpmn:Artifact')) {
+                return is(target, 'bpmn:Collaboration') ||
+                    is(target, 'bpmn:Participant') ||
+                    is(target, 'bpmn:Process');
+            }
+
+            if (is(element, 'bpmn:MessageFlow')) {
+                return is(target, 'bpmn:Collaboration');
+            }
+
+            return false;
+        }
+
+        function canMove(elements, target) {
+
+            // only move if they have the same parent
+            var sameParent = size(groupBy(elements, function(s) {
+                return s.parent && s.parent.id;
+            })) === 1;
+
+            if (!sameParent) {
+                return false;
+            }
+
+            if (!target) {
+                return true;
+            }
+
+            return elements.every(function(element) {
+                return canDrop(element, target);
+            });
+        }
+
+        function canCreate(shape, target, source) {
+
+            if (!target) {
+                return false;
+            }
+
+            if (isLabel(target)) {
+                return null;
+            }
+
+            if (isSame(source, target)) {
+                return false;
+            }
+
+            // ensure we do not drop the element
+            // into source
+            if (source && isParent(source, target)) {
+                return false;
+            }
+
+            return canDrop(shape, target);
+        }
+
+        function canResize(shape, newBounds) {
+            if (is(shape, 'bpmn:SubProcess')) {
+                return isExpanded(shape) && (!newBounds || (newBounds.width >= 100 && newBounds.height >= 80));
+            }
+
+            if (is(shape, 'bpmn:Participant')) {
+                return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
+            }
+
+            if (is(shape, 'bpmn:TextAnnotation')) {
+                return true;
+            }
+            if (is(shape, 'bpmn:MultiBranchConnector')) {
+                return false;
+            }
+
+            return true;
+        }
+
+        function canConnectAssociation(source, target) {
+
+            // do not connect connections
+            if (isConnection(source) || isConnection(target)) {
+                return false;
+            }
+
+            // connect if different parent
+            return !isParent(target, source) &&
+                !isParent(source, target);
+        }
+
+        function canConnectMessageFlow(source, target) {
+
+            return isMessageFlowSource(source) &&
+                isMessageFlowTarget(target) &&
+                !isSameOrganization(source, target);
+        }
+
+        function canConnectSequenceFlow(source, target) {
+
+            return isSequenceFlowSource(source) &&
+                isSequenceFlowTarget(target) &&
+                isSameScope(source, target) &&
+                !(is(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target));
+        }
+    }, {
+        "../../../util/DiUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\DiUtil.js",
+        "../../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "../ModelingUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ModelingUtil.js",
+        "diagram-js/lib/features/rules/RuleProvider": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\RuleProvider.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/collection/groupBy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\groupBy.js",
+        "lodash/collection/size": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\size.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\rules\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js/lib/features/rules')
+            ],
+            __init__: ['bpmnRules'],
+            bpmnRules: ['type', require('./BpmnRules')]
+        };
+
+    }, {
+        "./BpmnRules": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\rules\\BpmnRules.js",
+        "diagram-js/lib/features/rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\palette\\PaletteProvider.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+        /**
+         * A palette provider for BPMN 2.0 elements.
+         */
+        function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool) {
+
+            this._create = create;
+            this._elementFactory = elementFactory;
+            this._spaceTool = spaceTool;
+            this._lassoTool = lassoTool;
+
+            palette.registerProvider(this);
+        }
+
+        module.exports = PaletteProvider;
+
+        PaletteProvider.$inject = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool'];
+
+
+        PaletteProvider.prototype.getPaletteEntries = function(element) {
+
+            var actions = {},
+                create = this._create,
+                elementFactory = this._elementFactory,
+                spaceTool = this._spaceTool,
+                lassoTool = this._lassoTool;
+
+
+            function createAction(type, group, className, title, options) {
+               function createListener(event) {
+                    var shape = elementFactory.createShape(assign({
+                        type: type
+                    }, options));
+
+                    if (options) {
+                        shape.businessObject.di.isExpanded = options.isExpanded;
+                    }
+
+                    create.start(event, shape);
+                }
+
+                var shortType = type.replace(/^bpmn\:/, '');
+
+                return {
+                    group: group,
+                    className: className,
+                    title: title || 'Create ' + shortType,
+                    action: {
+                        dragstart: createListener,
+                        click: createListener
+                    }
+                };
+            }
+
+            function createParticipant(event, collapsed) {
+                create.start(event, elementFactory.createParticipantShape(collapsed));
+            }
+
+            assign(actions, {
+                'create.start-event': createAction(
+                    'bpmn:StartEvent', 'event', 'icon-start-event-none', "Start"
+                ),
+                'create.collector': createAction(
+                        'bpmn:Collector', 'event', 'icon-collector-node', 'Collector'
+                    ),
+                                       'create.String-Match': createAction(
+                        'bpmn:StringMatch', 'event', 'icon-stringmatch-node', 'String Match'
+                    ),
+                    'create.TCA': createAction(
+                       'bpmn:TCA', 'event', 'icon-tca-node', 'TCA'
+                    ),
+                                       'create.Aand-AI': createAction(
+                        'bpmn:Policy', 'event', 'icon-policy-node', 'Policy'
+                    ),
+                'create.end-event': createAction(
+                    'bpmn:EndEvent', 'event', 'icon-end-event-none', "End"
+                )
+            });
+
+            return actions;
+        };
+
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\palette\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js/lib/features/palette'),
+                require('diagram-js/lib/features/create')
+            ],
+            __init__: ['paletteProvider'],
+            paletteProvider: ['type', require('./PaletteProvider')]
+        };
+
+    }, {
+        "./PaletteProvider": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\palette\\PaletteProvider.js",
+        "diagram-js/lib/features/create": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\create\\index.js",
+        "diagram-js/lib/features/palette": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\palette\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\BpmnReplace.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            filter = require('lodash/collection/filter');
+
+        var REPLACE_OPTIONS = require('./ReplaceOptions');
+
+        var startEventReplace = REPLACE_OPTIONS.START_EVENT,
+            intermediateEventReplace = REPLACE_OPTIONS.INTERMEDIATE_EVENT,
+            endEventReplace = REPLACE_OPTIONS.END_EVENT,
+            gatewayReplace = REPLACE_OPTIONS.GATEWAY,
+            taskReplace = REPLACE_OPTIONS.TASK;
+
+
+        /**
+         * A replace menu provider that gives users the controls to choose and replace
+         * BPMN elements with each other.
+         * 
+         * @param {BpmnFactory}
+         *            bpmnFactory
+         * @param {Moddle}
+         *            moddle
+         * @param {PopupMenu}
+         *            popupMenu
+         * @param {Replace}
+         *            replace
+         */
+        function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection) {
+
+            /**
+             * Prepares a new business object for the replacement element and triggers
+             * the replace operation.
+             * 
+             * @param {djs.model.Base}
+             *            element
+             * @param {Object}
+             *            target
+             * @return {djs.model.Base} the newly created element
+             */
+            function replaceElement(element, target) {
+
+                var type = target.type,
+                    oldBusinessObject = element.businessObject,
+                    businessObject = bpmnFactory.create(type);
+
+                var newElement = {
+                    type: type,
+                    businessObject: businessObject
+                };
+
+                // initialize custom BPMN extensions
+
+                if (target.eventDefinition) {
+                    var eventDefinitions = businessObject.get('eventDefinitions'),
+                        eventDefinition = moddle.create(target.eventDefinition);
+
+                    eventDefinitions.push(eventDefinition);
+                }
+
+                if (target.instantiate !== undefined) {
+                    businessObject.instantiate = target.instantiate;
+                }
+
+                if (target.eventGatewayType !== undefined) {
+                    businessObject.eventGatewayType = target.eventGatewayType;
+                }
+
+                // copy size (for activities only)
+                if (oldBusinessObject.$instanceOf('bpmn:Activity')) {
+
+                    // TODO: need also to respect min/max Size
+
+                    newElement.width = element.width;
+                    newElement.height = element.height;
+                }
+
+                // TODO: copy other elligable properties from old business object
+                businessObject.name = oldBusinessObject.name;
+
+                newElement = replace.replaceElement(element, newElement);
+
+                selection.select(newElement);
+
+                return newElement;
+            }
+
+
+            function getReplaceOptions(element) {
+
+                var menuEntries = [];
+                var businessObject = element.businessObject;
+
+                if (businessObject.$instanceOf('bpmn:StartEvent')) {
+                    addEntries(startEventReplace, filterEvents);
+                } else
+
+                if (businessObject.$instanceOf('bpmn:IntermediateCatchEvent') ||
+                    businessObject.$instanceOf('bpmn:IntermediateThrowEvent')) {
+
+                    addEntries(intermediateEventReplace, filterEvents);
+                } else
+
+                if (businessObject.$instanceOf('bpmn:EndEvent')) {
+
+                    addEntries(endEventReplace, filterEvents);
+                } else
+
+                if (businessObject.$instanceOf('bpmn:Gateway')) {
+
+                    addEntries(gatewayReplace, function(entry) {
+
+                        return entry.target.type !== businessObject.$type;
+                    });
+                } else
+
+                if (businessObject.$instanceOf('bpmn:FlowNode')) {
+                    addEntries(taskReplace, function(entry) {
+                        return entry.target.type !== businessObject.$type;
+                    });
+                }
+
+                function filterEvents(entry) {
+
+                    var target = entry.target;
+
+                    var eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0].$type;
+                    var isEventDefinitionEqual = target.eventDefinition == eventDefinition;
+                    var isEventTypeEqual = businessObject.$type == target.type;
+
+                    return ((!isEventDefinitionEqual && isEventTypeEqual) ||
+                            !isEventTypeEqual) ||
+                        !(isEventDefinitionEqual && isEventTypeEqual);
+                }
+
+                function addEntries(entries, filterFun) {
+                    // Filter selected type from the array
+                    var filteredEntries = filter(entries, filterFun);
+
+                    // Add entries to replace menu
+                    forEach(filteredEntries, function(definition) {
+
+                        var entry = addMenuEntry(definition);
+                        menuEntries.push(entry);
+                    });
+                }
+
+                function addMenuEntry(definition) {
+
+                    return {
+                        label: definition.label,
+                        className: definition.className,
+                        action: {
+                            name: definition.actionName,
+                            handler: function() {
+                                replaceElement(element, definition.target);
+                            }
+                        }
+                    };
+                }
+
+                return menuEntries;
+            }
+
+
+            // API
+
+            this.openChooser = function(position, element) {
+                var entries = this.getReplaceOptions(element);
+
+                popupMenu.open('replace-menu', position, entries);
+            };
+
+            this.getReplaceOptions = getReplaceOptions;
+
+            this.replaceElement = replaceElement;
+        }
+
+        BpmnReplace.$inject = ['bpmnFactory', 'moddle', 'popupMenu', 'replace', 'selection'];
+
+        module.exports = BpmnReplace;
+    }, {
+        "./ReplaceOptions": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\ReplaceOptions.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\ReplaceOptions.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports.START_EVENT = [{
+            label: 'Start Event',
+            actionName: 'replace-with-none-start',
+            className: 'icon-start-event-none',
+            target: {
+                type: 'bpmn:StartEvent'
+            }
+        }, {
+            label: 'Intermediate Throw Event',
+            actionName: 'replace-with-intermediate-throwing',
+            className: 'icon-intermediate-event-none',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent'
+            }
+        }, {
+            label: 'End Event',
+            actionName: 'replace-with-message-end',
+            className: 'icon-end-event-none',
+            target: {
+                type: 'bpmn:EndEvent'
+            }
+        }, {
+            label: 'Message Start Event',
+            actionName: 'replace-with-message-start',
+            className: 'icon-start-event-message',
+            target: {
+                type: 'bpmn:StartEvent',
+                eventDefinition: 'bpmn:MessageEventDefinition'
+            }
+        }, {
+            label: 'Timer Start Event',
+            actionName: 'replace-with-timer-start',
+            className: 'icon-start-event-timer',
+            target: {
+                type: 'bpmn:StartEvent',
+                eventDefinition: 'bpmn:TimerEventDefinition'
+            }
+        }, {
+            label: 'Conditional Start Event',
+            actionName: 'replace-with-conditional-start',
+            className: 'icon-start-event-condition',
+            target: {
+                type: 'bpmn:StartEvent',
+                eventDefinition: 'bpmn:ConditionalEventDefinition'
+            }
+        }, {
+            label: 'Signal Start Event',
+            actionName: 'replace-with-signal-start',
+            className: 'icon-start-event-signal',
+            target: {
+                type: 'bpmn:StartEvent',
+                eventDefinition: 'bpmn:SignalEventDefinition'
+            }
+        }];
+
+        module.exports.INTERMEDIATE_EVENT = [{
+            label: 'Start Event',
+            actionName: 'replace-with-none-start',
+            className: 'icon-start-event-none',
+            target: {
+                type: 'bpmn:StartEvent'
+            }
+        }, {
+            label: 'Intermediate Throw Event',
+            actionName: 'replace-with-message-intermediate-throw',
+            className: 'icon-intermediate-event-none',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent'
+            }
+        }, {
+            label: 'End Event',
+            actionName: 'replace-with-message-end',
+            className: 'icon-end-event-none',
+            target: {
+                type: 'bpmn:EndEvent'
+            }
+        }, {
+            label: 'Message Intermediate Catch Event',
+            actionName: 'replace-with-intermediate-catch',
+            className: 'icon-intermediate-event-catch-message',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:MessageEventDefinition'
+            }
+        }, {
+            label: 'Message Intermediate Throw Event',
+            actionName: 'replace-with-intermediate-throw',
+            className: 'icon-intermediate-event-throw-message',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent',
+                eventDefinition: 'bpmn:MessageEventDefinition'
+            }
+        }, {
+            label: 'Timer Intermediate Catch Event',
+            actionName: 'replace-with-timer-intermediate-catch',
+            className: 'icon-intermediate-event-catch-timer',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:TimerEventDefinition'
+            }
+        }, {
+            label: 'Escalation Intermediate Catch Event',
+            actionName: 'replace-with-escalation-catch',
+            className: 'icon-intermediate-event-catch-escalation',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:EscalationEventDefinition'
+            }
+        }, {
+            label: 'Conditional Intermediate Catch Event',
+            actionName: 'replace-with-conditional-intermediate-catch',
+            className: 'icon-intermediate-event-catch-condition',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:ConditionalEventDefinition'
+            }
+        }, {
+            label: 'Link Intermediate Catch Event',
+            actionName: 'replace-with-link-intermediate-catch',
+            className: 'icon-intermediate-event-catch-link',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:LinkEventDefinition'
+            }
+        }, {
+            label: 'Link Intermediate Throw Event',
+            actionName: 'replace-with-link-intermediate-throw',
+            className: 'icon-intermediate-event-throw-link',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent',
+                eventDefinition: 'bpmn:LinkEventDefinition'
+            }
+        }, {
+            label: 'Compensation Intermediate Throw Event',
+            actionName: 'replace-with-compensation-intermediate-throw',
+            className: 'icon-intermediate-event-throw-compensation',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent',
+                eventDefinition: 'bpmn:CompensateEventDefinition'
+            }
+        }, {
+            label: 'Signal Throw Catch Event',
+            actionName: 'replace-with-throw-intermediate-catch',
+            className: 'icon-intermediate-event-catch-signal',
+            target: {
+                type: 'bpmn:IntermediateCatchEvent',
+                eventDefinition: 'bpmn:SignalEventDefinition'
+            }
+        }, {
+            label: 'Signal Intermediate Throw Event',
+            actionName: 'replace-with-signal-intermediate-throw',
+            className: 'icon-intermediate-event-throw-signal',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent',
+                eventDefinition: 'bpmn:SignalEventDefinition'
+            }
+        }];
+
+        module.exports.END_EVENT = [{
+            label: 'Start Event',
+            actionName: 'replace-with-none-start',
+            className: 'icon-start-event-none',
+            target: {
+                type: 'bpmn:StartEvent'
+            }
+        }, {
+            label: 'Intermediate Throw Event',
+            actionName: 'replace-with-message-intermediate-throw',
+            className: 'icon-intermediate-event-none',
+            target: {
+                type: 'bpmn:IntermediateThrowEvent'
+            }
+        }, {
+            label: 'End Event',
+            actionName: 'replace-with-none-end',
+            className: 'icon-end-event-none',
+            target: {
+                type: 'bpmn:EndEvent'
+            }
+        }, {
+            label: 'Message End Event',
+            actionName: 'replace-with-message-end',
+            className: 'icon-end-event-message',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:MessageEventDefinition'
+            }
+        }, {
+            label: 'Escalation End Event',
+            actionName: 'replace-with-escalation-end',
+            className: 'icon-end-event-escalation',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:EscalationEventDefinition'
+            }
+        }, {
+            label: 'Error End Event',
+            actionName: 'replace-with-error-end',
+            className: 'icon-end-event-error',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:ErrorEventDefinition'
+            }
+        }, {
+            label: 'Cancel End Event',
+            actionName: 'replace-with-cancel-end',
+            className: 'icon-end-event-cancel',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:CancelEventDefinition'
+            }
+        }, {
+            label: 'Compensation End Event',
+            actionName: 'replace-with-compensation-end',
+            className: 'icon-end-event-compensation',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:CompensateEventDefinition'
+            }
+        }, {
+            label: 'Signal End Event',
+            actionName: 'replace-with-signal-end',
+            className: 'icon-end-event-signal',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:SignalEventDefinition'
+            }
+        }, {
+            label: 'Terminate End Event',
+            actionName: 'replace-with-terminate-end',
+            className: 'icon-end-event-terminate',
+            target: {
+                type: 'bpmn:EndEvent',
+                eventDefinition: 'bpmn:TerminateEventDefinition'
+            }
+        }];
+
+        module.exports.GATEWAY = [{
+                label: 'Exclusive Gateway',
+                actionName: 'replace-with-exclusive-gateway',
+                className: 'icon-gateway-xor',
+                target: {
+                    type: 'bpmn:ExclusiveGateway'
+                }
+            }, {
+                label: 'Parallel Gateway',
+                actionName: 'replace-with-parallel-gateway',
+                className: 'icon-gateway-parallel',
+                target: {
+                    type: 'bpmn:ParallelGateway'
+                }
+            }, {
+                label: 'Inclusive Gateway',
+                actionName: 'replace-with-inclusive-gateway',
+                className: 'icon-gateway-or',
+                target: {
+                    type: 'bpmn:InclusiveGateway'
+                }
+            }, {
+                label: 'Complex Gateway',
+                actionName: 'replace-with-complex-gateway',
+                className: 'icon-gateway-complex',
+                target: {
+                    type: 'bpmn:ComplexGateway'
+                }
+            }, {
+                label: 'Event based Gateway',
+                actionName: 'replace-with-event-based-gateway',
+                className: 'icon-gateway-eventbased',
+                target: {
+                    type: 'bpmn:EventBasedGateway',
+                    instantiate: false,
+                    eventGatewayType: 'Exclusive'
+                }
+            }
+            // Gateways deactivated until https://github.com/bpmn-io/bpmn-js/issues/194
+            // {
+            // label: 'Event based instantiating Gateway',
+            // actionName: 'replace-with-exclusive-event-based-gateway',
+            // className: 'icon-exclusive-event-based',
+            // target: {
+            // type: 'bpmn:EventBasedGateway'
+            // },
+            // options: {
+            // businessObject: { instantiate: true, eventGatewayType: 'Exclusive' }
+            // }
+            // },
+            // {
+            // label: 'Parallel Event based instantiating Gateway',
+            // actionName: 'replace-with-parallel-event-based-instantiate-gateway',
+            // className: 'icon-parallel-event-based-instantiate-gateway',
+            // target: {
+            // type: 'bpmn:EventBasedGateway'
+            // },
+            // options: {
+            // businessObject: { instantiate: true, eventGatewayType: 'Parallel' }
+            // }
+            // }
+        ];
+
+
+        module.exports.TASK = [{
+            label: 'Task',
+            actionName: 'replace-with-task',
+            className: 'icon-task',
+            target: {
+                type: 'bpmn:Task'
+            }
+        }, {
+            label: 'Send Task',
+            actionName: 'replace-with-send-task',
+            className: 'icon-send',
+            target: {
+                type: 'bpmn:SendTask'
+            }
+        }, {
+            label: 'Receive Task',
+            actionName: 'replace-with-receive-task',
+            className: 'icon-receive',
+            target: {
+                type: 'bpmn:ReceiveTask'
+            }
+        }, {
+            label: 'User Task',
+            actionName: 'replace-with-user-task',
+            className: 'icon-user',
+            target: {
+                type: 'bpmn:UserTask'
+            }
+        }, {
+            label: 'Manual Task',
+            actionName: 'replace-with-manual-task',
+            className: 'icon-manual',
+            target: {
+                type: 'bpmn:ManualTask'
+            }
+        }, {
+            label: 'Business Rule Task',
+            actionName: 'replace-with-rule-task',
+            className: 'icon-business-rule',
+            target: {
+                type: 'bpmn:BusinessRuleTask'
+            }
+        }, {
+            label: 'Service Task',
+            actionName: 'replace-with-service-task',
+            className: 'icon-service',
+            target: {
+                type: 'bpmn:ServiceTask'
+            }
+        }, {
+            label: 'Script Task',
+            actionName: 'replace-with-script-task',
+            className: 'icon-script',
+            target: {
+                type: 'bpmn:ScriptTask'
+            }
+        }];
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('diagram-js/lib/features/popup-menu'),
+                require('diagram-js/lib/features/replace'),
+                require('diagram-js/lib/features/selection')
+            ],
+            bpmnReplace: ['type', require('./BpmnReplace')]
+        };
+    }, {
+        "./BpmnReplace": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\replace\\BpmnReplace.js",
+        "diagram-js/lib/features/popup-menu": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\popup-menu\\index.js",
+        "diagram-js/lib/features/replace": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\replace\\index.js",
+        "diagram-js/lib/features/selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\snapping\\BpmnSnapping.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var forEach = require('lodash/collection/forEach');
+
+        var getBoundingBox = require('diagram-js/lib/util/Elements').getBBox;
+        var is = require('../modeling/ModelingUtil').is;
+
+        var Snapping = require('diagram-js/lib/features/snapping/Snapping'),
+            SnapUtil = require('diagram-js/lib/features/snapping/SnapUtil');
+
+        var is = require('../../util/ModelUtil').is;
+
+        var mid = SnapUtil.mid,
+            topLeft = SnapUtil.topLeft,
+            bottomRight = SnapUtil.bottomRight;
+
+        var round = Math.round;
+
+
+        /**
+         * BPMN specific snapping functionality
+         *  * snap on process elements if a pool is created inside a process diagram
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Canvas}
+         *            canvas
+         */
+        function BpmnSnapping(eventBus, canvas) {
+
+            // instantiate super
+            Snapping.call(this, eventBus, canvas);
+
+
+            /**
+             * Drop participant on process <> process elements snapping
+             */
+
+            function initParticipantSnapping(context, shape, elements) {
+
+                if (!elements.length) {
+                    return;
+                }
+
+                var snapBox = getBoundingBox(elements.filter(function(e) {
+                    return !e.labelTarget && !e.waypoints;
+                }));
+
+                snapBox.x -= 50;
+                snapBox.y -= 20;
+                snapBox.width += 70;
+                snapBox.height += 40;
+
+                // adjust shape height to include bounding box
+                shape.width = Math.max(shape.width, snapBox.width);
+                shape.height = Math.max(shape.height, snapBox.height);
+
+                context.participantSnapBox = snapBox;
+            }
+
+            function snapParticipant(snapBox, shape, event) {
+
+                var shapeHalfWidth = shape.width / 2 - 30,
+                    shapeHalfHeight = shape.height / 2;
+
+                var currentTopLeft = {
+                    x: event.x - shapeHalfWidth - 30,
+                    y: event.y - shapeHalfHeight
+                };
+
+                var currentBottomRight = {
+                    x: event.x + shapeHalfWidth + 30,
+                    y: event.y + shapeHalfHeight
+                };
+
+                var snapTopLeft = snapBox,
+                    snapBottomRight = bottomRight(snapBox);
+
+                if (currentTopLeft.x >= snapTopLeft.x) {
+                    event.x = snapTopLeft.x + 30 + shapeHalfWidth;
+                    event.snapped = true;
+                } else
+                if (currentBottomRight.x <= snapBottomRight.x) {
+                    event.x = snapBottomRight.x - 30 - shapeHalfWidth;
+                    event.snapped = true;
+                }
+
+                if (currentTopLeft.y >= snapTopLeft.y) {
+                    event.y = snapTopLeft.y + shapeHalfHeight;
+                    event.snapped = true;
+                } else
+                if (currentBottomRight.y <= snapBottomRight.y) {
+                    event.y = snapBottomRight.y - shapeHalfHeight;
+                    event.snapped = true;
+                }
+            }
+
+            eventBus.on('create.start', function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    rootElement = canvas.getRootElement();
+
+                // snap participant around existing elements (if any)
+                if (is(shape, 'bpmn:Participant') && is(rootElement, 'bpmn:Process')) {
+
+                    initParticipantSnapping(context, shape, rootElement.children);
+                }
+            });
+
+            eventBus.on(['create.move', 'create.end'], 1500, function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    participantSnapBox = context.participantSnapBox;
+
+                if (!event.snapped && participantSnapBox) {
+                    snapParticipant(participantSnapBox, shape, event);
+                }
+            });
+
+            eventBus.on('resize.start', 1500, function(event) {
+                var context = event.context,
+                    shape = context.shape;
+
+                if (is(shape, 'bpmn:SubProcess')) {
+                    context.minDimensions = {
+                        width: 140,
+                        height: 120
+                    };
+                }
+
+                if (is(shape, 'bpmn:Participant')) {
+                    context.minDimensions = {
+                        width: 400,
+                        height: 200
+                    };
+                }
+
+                if (is(shape, 'bpmn:TextAnnotation')) {
+                    context.minDimensions = {
+                        width: 50,
+                        height: 50
+                    };
+                }
+            });
+
+        }
+
+        inherits(BpmnSnapping, Snapping);
+
+        BpmnSnapping.$inject = ['eventBus', 'canvas'];
+
+        module.exports = BpmnSnapping;
+
+
+        BpmnSnapping.prototype.initSnap = function(event) {
+
+            var context = event.context,
+                shape = context.shape,
+                shapeMid,
+                shapeBounds,
+                shapeTopLeft,
+                shapeBottomRight,
+                snapContext;
+
+
+            snapContext = Snapping.prototype.initSnap.call(this, event);
+
+            if (is(shape, 'bpmn:Participant')) {
+                // assign higher priority for outer snaps on participants
+                snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']);
+            }
+
+
+            if (shape) {
+
+                shapeMid = mid(shape, event);
+
+                shapeBounds = {
+                    width: shape.width,
+                    height: shape.height,
+                    x: isNaN(shape.x) ? round(shapeMid.x - shape.width / 2) : shape.x,
+                    y: isNaN(shape.y) ? round(shapeMid.y - shape.height / 2) : shape.y,
+                };
+
+                shapeTopLeft = topLeft(shapeBounds);
+                shapeBottomRight = bottomRight(shapeBounds);
+
+                snapContext.setSnapOrigin('top-left', {
+                    x: shapeTopLeft.x - event.x,
+                    y: shapeTopLeft.y - event.y
+                });
+
+                snapContext.setSnapOrigin('bottom-right', {
+                    x: shapeBottomRight.x - event.x,
+                    y: shapeBottomRight.y - event.y
+                });
+
+
+                forEach(shape.outgoing, function(c) {
+                    var docking = c.waypoints[0];
+
+                    docking = docking.original || docking;
+
+                    snapContext.setSnapOrigin(c.id + '-docking', {
+                        x: docking.x - event.x,
+                        y: docking.y - event.y
+                    });
+                });
+
+                forEach(shape.incoming, function(c) {
+                    var docking = c.waypoints[c.waypoints.length - 1];
+
+                    docking = docking.original || docking;
+
+                    snapContext.setSnapOrigin(c.id + '-docking', {
+                        x: docking.x - event.x,
+                        y: docking.y - event.y
+                    });
+                });
+
+            }
+
+            var source = context.source;
+
+            if (source) {
+                snapContext.addDefaultSnap('mid', mid(source));
+            }
+        };
+
+
+        BpmnSnapping.prototype.addTargetSnaps = function(snapPoints, shape, target) {
+
+            var siblings = this.getSiblings(shape, target);
+
+
+            forEach(siblings, function(s) {
+                snapPoints.add('mid', mid(s));
+
+                if (is(s, 'bpmn:Participant')) {
+                    snapPoints.add('top-left', topLeft(s));
+                    snapPoints.add('bottom-right', bottomRight(s));
+                }
+            });
+
+            forEach(shape.incoming, function(c) {
+
+                if (siblings.indexOf(c.source) === -1) {
+                    snapPoints.add('mid', mid(c.source));
+
+                    var docking = c.waypoints[0];
+                    snapPoints.add(c.id + '-docking', docking.original || docking);
+                }
+            });
+
+
+            forEach(shape.outgoing, function(c) {
+
+                if (siblings.indexOf(c.target) === -1) {
+                    snapPoints.add('mid', mid(c.target));
+
+                    var docking = c.waypoints[c.waypoints.length - 1];
+                    snapPoints.add(c.id + '-docking', docking.original || docking);
+                }
+            });
+
+        };
+    }, {
+        "../../util/ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js",
+        "../modeling/ModelingUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\modeling\\ModelingUtil.js",
+        "diagram-js/lib/features/snapping/SnapUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapUtil.js",
+        "diagram-js/lib/features/snapping/Snapping": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\Snapping.js",
+        "diagram-js/lib/util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\snapping\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['snapping'],
+            snapping: ['type', require('./BpmnSnapping')]
+        };
+    }, {
+        "./BpmnSnapping": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\features\\snapping\\BpmnSnapping.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\BpmnImporter.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            map = require('lodash/collection/map');
+
+        var LabelUtil = require('../util/LabelUtil');
+
+        var hasExternalLabel = LabelUtil.hasExternalLabel,
+            getExternalLabelBounds = LabelUtil.getExternalLabelBounds,
+            isExpanded = require('../util/DiUtil').isExpanded,
+            elementToString = require('./Util').elementToString;
+
+
+        function elementData(semantic, attrs) {
+            return assign({
+                id: semantic.id,
+                type: semantic.$type,
+                businessObject: semantic
+            }, attrs);
+        }
+
+        function collectWaypoints(waypoints) {
+            return map(waypoints, function(p) {
+                return {
+                    x: p.x,
+                    y: p.y
+                };
+            });
+        }
+
+
+        /**
+         * An importer that adds bpmn elements to the canvas
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Canvas}
+         *            canvas
+         * @param {ElementFactory}
+         *            elementFactory
+         * @param {ElementRegistry}
+         *            elementRegistry
+         */
+        function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry) {
+            this._eventBus = eventBus;
+            this._canvas = canvas;
+
+            this._elementFactory = elementFactory;
+            this._elementRegistry = elementRegistry;
+        }
+
+        BpmnImporter.$inject = ['eventBus', 'canvas', 'elementFactory', 'elementRegistry'];
+
+        module.exports = BpmnImporter;
+
+
+        /**
+         * Add bpmn element (semantic) to the canvas onto the specified parent shape.
+         */
+        BpmnImporter.prototype.add = function(semantic, parentElement) {
+
+            var di = semantic.di,
+                element;
+
+            // ROOT ELEMENT
+            // handle the special case that we deal with a
+            // invisible root element (process or collaboration)
+            if (di.$instanceOf('bpmndi:BPMNPlane')) {
+
+                // add a virtual element (not being drawn)
+                element = this._elementFactory.createRoot(elementData(semantic));
+
+                this._canvas.setRootElement(element);
+            }
+
+            // SHAPE
+            else if (di.$instanceOf('bpmndi:BPMNShape')) {
+
+                var collapsed = !isExpanded(semantic);
+                var hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
+
+                var bounds = semantic.di.bounds;
+
+                element = this._elementFactory.createShape(elementData(semantic, {
+                    collapsed: collapsed,
+                    hidden: hidden,
+                    x: Math.round(bounds.x),
+                    y: Math.round(bounds.y),
+                    width: Math.round(bounds.width),
+                    height: Math.round(bounds.height)
+                }));
+
+                this._canvas.addShape(element, parentElement);
+            }
+
+            // CONNECTION
+            else if (di.$instanceOf('bpmndi:BPMNEdge')) {
+
+                var source = this._getSource(semantic),
+                    target = this._getTarget(semantic);
+
+                element = this._elementFactory.createConnection(elementData(semantic, {
+                    source: source,
+                    target: target,
+                    waypoints: collectWaypoints(semantic.di.waypoint)
+                }));
+
+                this._canvas.addConnection(element, parentElement);
+            } else {
+                throw new Error('unknown di ' + elementToString(di) + ' for element ' + elementToString(semantic));
+            }
+
+            // (optional) LABEL
+            if (hasExternalLabel(semantic)) {
+                this.addLabel(semantic, element);
+            }
+
+
+            this._eventBus.fire('bpmnElement.added', {
+                element: element
+            });
+
+            return element;
+        };
+
+
+        /**
+         * add label for an element
+         */
+        BpmnImporter.prototype.addLabel = function(semantic, element) {
+            var bounds = getExternalLabelBounds(semantic, element);
+
+            var label = this._elementFactory.createLabel(elementData(semantic, {
+                id: semantic.id + '_label',
+                labelTarget: element,
+                type: 'label',
+                hidden: element.hidden,
+                x: Math.round(bounds.x),
+                y: Math.round(bounds.y),
+                width: Math.round(bounds.width),
+                height: Math.round(bounds.height)
+            }));
+
+            return this._canvas.addShape(label, element.parent);
+        };
+
+        /**
+         * Return the drawn connection end based on the given side.
+         * 
+         * @throws {Error}
+         *             if the end is not yet drawn
+         */
+        BpmnImporter.prototype._getEnd = function(semantic, side) {
+
+            var element,
+                refSemantic,
+                type = semantic.$type;
+
+            refSemantic = semantic[side + 'Ref'];
+
+            // handle mysterious isMany DataAssociation#sourceRef
+            if (side === 'source' && type === 'bpmn:DataInputAssociation') {
+                refSemantic = refSemantic && refSemantic[0];
+            }
+
+            // fix source / target for DataInputAssociation / DataOutputAssociation
+            if (side === 'source' && type === 'bpmn:DataOutputAssociation' ||
+                side === 'target' && type === 'bpmn:DataInputAssociation') {
+
+                refSemantic = semantic.$parent;
+            }
+
+            element = refSemantic && this._getElement(refSemantic);
+
+            if (element) {
+                return element;
+            }
+
+            if (refSemantic) {
+                throw new Error(
+                    'element ' + elementToString(refSemantic) + ' referenced by ' +
+                    elementToString(semantic) + '#' + side + 'Ref not yet drawn');
+            } else {
+                throw new Error(elementToString(semantic) + '#' + side + 'Ref not specified');
+            }
+        };
+
+        BpmnImporter.prototype._getSource = function(semantic) {
+            return this._getEnd(semantic, 'source');
+        };
+
+        BpmnImporter.prototype._getTarget = function(semantic) {
+            return this._getEnd(semantic, 'target');
+        };
+
+
+        BpmnImporter.prototype._getElement = function(semantic) {
+            return this._elementRegistry.get(semantic.id);
+        };
+
+    }, {
+        "../util/DiUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\DiUtil.js",
+        "../util/LabelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\LabelUtil.js",
+        "./Util": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\Util.js",
+        "lodash/collection/map": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\map.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\BpmnTreeWalker.js": [function(require, module, exports) {
+        'use strict';
+
+        var filter = require('lodash/collection/filter'),
+            find = require('lodash/collection/find'),
+            forEach = require('lodash/collection/forEach');
+
+        var Refs = require('object-refs');
+
+        var elementToString = require('./Util').elementToString;
+
+        var diRefs = new Refs({
+            name: 'bpmnElement',
+            enumerable: true
+        }, {
+            name: 'di'
+        });
+
+        /**
+         * Returns true if an element has the given meta-model type
+         * 
+         * @param {ModdleElement}
+         *            element
+         * @param {String}
+         *            type
+         * 
+         * @return {Boolean}
+         */
+        function is(element, type) {
+            return element.$instanceOf(type);
+        }
+
+
+        /**
+         * Find a suitable display candidate for definitions where the DI does not
+         * correctly specify one.
+         */
+        function findDisplayCandidate(definitions) {
+            return find(definitions.rootElements, function(e) {
+                return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration');
+            });
+        }
+
+
+        function BpmnTreeWalker(handler) {
+
+            // list of containers already walked
+            var handledProcesses = [];
+
+            // list of elements to handle deferred to ensure
+            // prerequisites are drawn
+            var deferred = [];
+
+            // /// Helpers /////////////////////////////////
+
+            function contextual(fn, ctx) {
+                return function(e) {
+                    fn(e, ctx);
+                };
+            }
+
+            function visit(element, ctx) {
+
+                var gfx = element.gfx;
+
+                // avoid multiple rendering of elements
+                if (gfx) {
+                    throw new Error('already rendered ' + elementToString(element));
+                }
+
+                // call handler
+                return handler.element(element, ctx);
+            }
+
+            function visitRoot(element, diagram) {
+                return handler.root(element, diagram);
+            }
+
+            function visitIfDi(element, ctx) {
+                try {
+                    return element.di && visit(element, ctx);
+                } catch (e) {
+                    logError(e.message, {
+                        element: element,
+                        error: e
+                    });
+
+                    console.error('failed to import ' + elementToString(element));
+                    console.error(e);
+                }
+            }
+
+            function logError(message, context) {
+                handler.error(message, context);
+            }
+
+            // //// DI handling ////////////////////////////
+
+            function registerDi(di) {
+                var bpmnElement = di.bpmnElement;
+
+                if (bpmnElement) {
+                    if (bpmnElement.di) {
+                        logError('multiple DI elements defined for ' + elementToString(bpmnElement), {
+                            element: bpmnElement
+                        });
+                    } else {
+                        diRefs.bind(bpmnElement, 'di');
+                        bpmnElement.di = di;
+                    }
+                } else {
+                    logError('no bpmnElement referenced in ' + elementToString(di), {
+                        element: di
+                    });
+                }
+            }
+
+            function handleDiagram(diagram) {
+                handlePlane(diagram.plane);
+            }
+
+            function handlePlane(plane) {
+                registerDi(plane);
+
+                forEach(plane.planeElement, handlePlaneElement);
+            }
+
+            function handlePlaneElement(planeElement) {
+                registerDi(planeElement);
+            }
+
+
+            // //// Semantic handling //////////////////////
+
+            function handleDefinitions(definitions, diagram) {
+                // make sure we walk the correct bpmnElement
+
+                var diagrams = definitions.diagrams;
+
+                if (diagram && diagrams.indexOf(diagram) === -1) {
+                    throw new Error('diagram not part of bpmn:Definitions');
+                }
+
+                if (!diagram && diagrams && diagrams.length) {
+                    diagram = diagrams[0];
+                }
+
+                // no diagram -> nothing to import
+                if (!diagram) {
+                    return;
+                }
+
+                // load DI from selected diagram only
+                handleDiagram(diagram);
+
+
+                var plane = diagram.plane;
+
+                if (!plane) {
+                    throw new Error('no plane for ' + elementToString(diagram));
+                }
+
+
+                var rootElement = plane.bpmnElement;
+
+                // ensure we default to a suitable display candidate (process or
+                // collaboration),
+                // even if non is specified in DI
+                if (!rootElement) {
+                    rootElement = findDisplayCandidate(definitions);
+
+                    if (!rootElement) {
+                        return logError('no process or collaboration present to display');
+                    } else {
+
+                        logError('correcting missing bpmnElement on ' + elementToString(plane) + ' to ' + elementToString(rootElement));
+
+                        // correct DI on the fly
+                        plane.bpmnElement = rootElement;
+                        registerDi(plane);
+                    }
+                }
+
+
+                var ctx = visitRoot(rootElement, plane);
+
+                if (is(rootElement, 'bpmn:Process')) {
+                    handleProcess(rootElement, ctx);
+                } else if (is(rootElement, 'bpmn:Collaboration')) {
+                    handleCollaboration(rootElement, ctx);
+
+                    // force drawing of everything not yet drawn that is part of the target
+                    // DI
+                    handleUnhandledProcesses(definitions.rootElements, ctx);
+                } else {
+                    throw new Error('unsupported bpmnElement for ' + elementToString(plane) + ' : ' + elementToString(rootElement));
+                }
+
+                // handle all deferred elements
+                handleDeferred(deferred);
+            }
+
+            function handleDeferred(deferred) {
+                forEach(deferred, function(d) {
+                    d();
+                });
+            }
+
+            function handleProcess(process, context) {
+                handleFlowElementsContainer(process, context);
+                handleIoSpecification(process.ioSpecification, context);
+
+                handleArtifacts(process.artifacts, context);
+
+                // log process handled
+                handledProcesses.push(process);
+            }
+
+            function handleUnhandledProcesses(rootElements) {
+
+                // walk through all processes that have not yet been drawn and draw them
+                // if they contain lanes with DI information.
+                // we do this to pass the free-floating lane test cases in the MIWG test
+                // suite
+                var processes = filter(rootElements, function(e) {
+                    return is(e, 'bpmn:Process') && e.laneSets && handledProcesses.indexOf(e) === -1;
+                });
+
+                processes.forEach(contextual(handleProcess));
+            }
+
+            function handleMessageFlow(messageFlow, context) {
+                visitIfDi(messageFlow, context);
+            }
+
+            function handleMessageFlows(messageFlows, context) {
+                forEach(messageFlows, contextual(handleMessageFlow, context));
+            }
+
+            function handleDataAssociation(association, context) {
+                visitIfDi(association, context);
+            }
+
+            function handleDataInput(dataInput, context) {
+                visitIfDi(dataInput, context);
+            }
+
+            function handleDataOutput(dataOutput, context) {
+                visitIfDi(dataOutput, context);
+            }
+
+            function handleArtifact(artifact, context) {
+
+                // bpmn:TextAnnotation
+                // bpmn:Group
+                // bpmn:Association
+
+                visitIfDi(artifact, context);
+            }
+
+            function handleArtifacts(artifacts, context) {
+
+                forEach(artifacts, function(e) {
+                    if (is(e, 'bpmn:Association')) {
+                        deferred.push(function() {
+                            handleArtifact(e, context);
+                        });
+                    } else {
+                        handleArtifact(e, context);
+                    }
+                });
+            }
+
+            function handleIoSpecification(ioSpecification, context) {
+
+                if (!ioSpecification) {
+                    return;
+                }
+
+                forEach(ioSpecification.dataInputs, contextual(handleDataInput, context));
+                forEach(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
+            }
+
+            function handleSubProcess(subProcess, context) {
+                handleFlowElementsContainer(subProcess, context);
+                handleArtifacts(subProcess.artifacts, context);
+            }
+
+            function handleFlowNode(flowNode, context) {
+                var childCtx = visitIfDi(flowNode, context);
+
+                if (is(flowNode, 'bpmn:SubProcess')) {
+                    handleSubProcess(flowNode, childCtx || context);
+                }
+            }
+
+            function handleSequenceFlow(sequenceFlow, context) {
+                visitIfDi(sequenceFlow, context);
+            }
+
+            function handleDataElement(dataObject, context) {
+                visitIfDi(dataObject, context);
+            }
+
+            function handleBoundaryEvent(dataObject, context) {
+                visitIfDi(dataObject, context);
+            }
+
+            function handleLane(lane, context) {
+                var newContext = visitIfDi(lane, context);
+
+                if (lane.childLaneSet) {
+                    handleLaneSet(lane.childLaneSet, newContext || context);
+                } else {
+                    var filterList = filter(lane.flowNodeRef, function(e) {
+                        return e.$type !== 'bpmn:BoundaryEvent';
+                    });
+                    handleFlowElements(filterList, newContext || context);
+                }
+            }
+
+            function handleLaneSet(laneSet, context) {
+                forEach(laneSet.lanes, contextual(handleLane, context));
+            }
+
+            function handleLaneSets(laneSets, context) {
+                forEach(laneSets, contextual(handleLaneSet, context));
+            }
+
+            function handleFlowElementsContainer(container, context) {
+
+                if (container.laneSets) {
+                    handleLaneSets(container.laneSets, context);
+                    handleNonFlowNodes(container.flowElements);
+                } else {
+                    handleFlowElements(container.flowElements, context);
+                }
+            }
+
+            function handleNonFlowNodes(flowElements, context) {
+                forEach(flowElements, function(e) {
+                    if (is(e, 'bpmn:SequenceFlow')) {
+                        deferred.push(function() {
+                            handleSequenceFlow(e, context);
+                        });
+                    } else if (is(e, 'bpmn:BoundaryEvent')) {
+                        deferred.unshift(function() {
+                            handleBoundaryEvent(e, context);
+                        });
+                    } else if (is(e, 'bpmn:DataObject')) {
+                        // SKIP (assume correct referencing via DataObjectReference)
+                    } else if (is(e, 'bpmn:DataStoreReference')) {
+                        handleDataElement(e, context);
+                    } else if (is(e, 'bpmn:DataObjectReference')) {
+                        handleDataElement(e, context);
+                    }
+                });
+            }
+
+            function handleFlowElements(flowElements, context) {
+                forEach(flowElements, function(e) {
+                    if (is(e, 'bpmn:SequenceFlow')) {
+                        deferred.push(function() {
+                            handleSequenceFlow(e, context);
+                        });
+                    } else if (is(e, 'bpmn:BoundaryEvent')) {
+                        deferred.unshift(function() {
+                            handleBoundaryEvent(e, context);
+                        });
+                    } else if (is(e, 'bpmn:FlowNode')) {
+                        handleFlowNode(e, context);
+
+                        if (is(e, 'bpmn:Activity')) {
+
+                            handleIoSpecification(e.ioSpecification, context);
+
+                            // defer handling of associations
+                            deferred.push(function() {
+                                forEach(e.dataInputAssociations, contextual(handleDataAssociation, context));
+                                forEach(e.dataOutputAssociations, contextual(handleDataAssociation, context));
+                            });
+                        }
+                    } else if (is(e, 'bpmn:DataObject')) {
+                        // SKIP (assume correct referencing via DataObjectReference)
+                    } else if (is(e, 'bpmn:DataStoreReference')) {
+                        handleDataElement(e, context);
+                    } else if (is(e, 'bpmn:DataObjectReference')) {
+                        handleDataElement(e, context);
+                    } else {
+                        logError(
+                            'unrecognized flowElement ' + elementToString(e) + ' in context ' +
+                            (context ? elementToString(context.businessObject) : null), {
+                                element: e,
+                                context: context
+                            });
+                    }
+                });
+            }
+
+            function handleParticipant(participant, context) {
+                var newCtx = visitIfDi(participant, context);
+
+                var process = participant.processRef;
+                if (process) {
+                    handleProcess(process, newCtx || context);
+                }
+            }
+
+            function handleCollaboration(collaboration) {
+
+                forEach(collaboration.participants, contextual(handleParticipant));
+
+                handleArtifacts(collaboration.artifacts);
+
+                // handle message flows latest in the process
+                deferred.push(function() {
+                    handleMessageFlows(collaboration.messageFlows);
+                });
+            }
+
+
+            // /// API ////////////////////////////////
+
+            return {
+                handleDefinitions: handleDefinitions
+            };
+        }
+
+        module.exports = BpmnTreeWalker;
+    }, {
+        "./Util": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\Util.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "object-refs": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\Importer.js": [function(require, module, exports) {
+        'use strict';
+
+        var BpmnTreeWalker = require('./BpmnTreeWalker');
+
+
+        /**
+         * Import the definitions into a diagram.
+         * 
+         * Errors and warnings are reported through the specified callback.
+         * 
+         * @param {Diagram}
+         *            diagram
+         * @param {ModdleElement}
+         *            definitions
+         * @param {Function}
+         *            done the callback, invoked with (err, [ warning ]) once the import
+         *            is done
+         */
+        function importBpmnDiagram(diagram, definitions, done) {
+
+            var importer = diagram.get('bpmnImporter'),
+                eventBus = diagram.get('eventBus');
+
+            var error,
+                warnings = [];
+
+            function parse(definitions) {
+
+                var visitor = {
+
+                    root: function(element) {
+                        return importer.add(element);
+                    },
+
+                    element: function(element, parentShape) {
+                        return importer.add(element, parentShape);
+                    },
+
+                    error: function(message, context) {
+                        warnings.push({
+                            message: message,
+                            context: context
+                        });
+                    }
+                };
+
+                var walker = new BpmnTreeWalker(visitor);
+
+                // import
+                walker.handleDefinitions(definitions);
+            }
+
+            eventBus.fire('import.start');
+
+            try {
+                parse(definitions);
+            } catch (e) {
+                error = e;
+            }
+
+            eventBus.fire(error ? 'import.error' : 'import.success', {
+                error: error,
+                warnings: warnings
+            });
+            done(error, warnings);
+        }
+
+        module.exports.importBpmnDiagram = importBpmnDiagram;
+    }, {
+        "./BpmnTreeWalker": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\BpmnTreeWalker.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\Util.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports.elementToString = function(e) {
+            if (!e) {
+                return '<null>';
+            }
+
+            return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\index.js": [function(require, module, exports) {
+        module.exports = {
+            bpmnImporter: ['type', require('./BpmnImporter')]
+        };
+    }, {
+        "./BpmnImporter": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\import\\BpmnImporter.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\DiUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        var is = require('./ModelUtil').is,
+            getBusinessObject = require('./ModelUtil').getBusinessObject;
+
+        module.exports.isExpanded = function(element) {
+
+            if (is(element, 'bpmn:CallActivity')) {
+                return false;
+            }
+
+            if (is(element, 'bpmn:SubProcess')) {
+                return getBusinessObject(element).di.isExpanded;
+            }
+
+            if (is(element, 'bpmn:Participant')) {
+                return !!getBusinessObject(element).processRef;
+            }
+
+            return true;
+        };
+
+    }, {
+        "./ModelUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\LabelUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+
+        var DEFAULT_LABEL_SIZE = module.exports.DEFAULT_LABEL_SIZE = {
+            width: 90,
+            height: 20
+        };
+
+
+        /**
+         * Returns true if the given semantic has an external label
+         * 
+         * @param {BpmnElement}
+         *            semantic
+         * @return {Boolean} true if has label
+         */
+        module.exports.hasExternalLabel = function(semantic) {
+
+            return semantic.$instanceOf('bpmn:Event') ||
+                // semantic.$instanceOf('bpmn:Gateway') ||
+                semantic.$instanceOf('bpmn:DataStoreReference') ||
+                semantic.$instanceOf('bpmn:DataObjectReference') ||
+                semantic.$instanceOf('bpmn:SequenceFlow') ||
+                semantic.$instanceOf('bpmn:MessageFlow');
+        };
+
+
+        /**
+         * Get the middle of a number of waypoints
+         * 
+         * @param {Array
+         *            <Point>} waypoints
+         * @return {Point} the mid point
+         */
+        var getWaypointsMid = module.exports.getWaypointsMid = function(waypoints) {
+
+            var mid = waypoints.length / 2 - 1;
+
+            var first = waypoints[Math.floor(mid)];
+            var second = waypoints[Math.ceil(mid + 0.01)];
+
+            return {
+                x: first.x + (second.x - first.x) / 2,
+                y: first.y + (second.y - first.y) / 2
+            };
+        };
+
+
+        var getExternalLabelMid = module.exports.getExternalLabelMid = function(element) {
+
+            if (element.waypoints) {
+                return getWaypointsMid(element.waypoints);
+            } else {
+                return {
+                    x: element.x + element.width / 2,
+                    y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2
+                };
+            }
+        };
+
+        /**
+         * Returns the bounds of an elements label, parsed from the elements DI or
+         * generated from its bounds.
+         * 
+         * @param {BpmnElement}
+         *            semantic
+         * @param {djs.model.Base}
+         *            element
+         */
+        module.exports.getExternalLabelBounds = function(semantic, element) {
+
+            var mid,
+                size,
+                bounds,
+                di = semantic.di,
+                label = di.label;
+
+            if (label && label.bounds) {
+                bounds = label.bounds;
+
+                size = {
+                    width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width),
+                    height: bounds.height
+                };
+
+                mid = {
+                    x: bounds.x + bounds.width / 2,
+                    y: bounds.y + bounds.height / 2
+                };
+            } else {
+
+                mid = getExternalLabelMid(element);
+
+                size = DEFAULT_LABEL_SIZE;
+            }
+
+            return assign({
+                x: mid.x - size.width / 2,
+                y: mid.y - size.height / 2
+            }, size);
+        };
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\lib\\util\\ModelUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Is an element of the given BPMN type?
+         * 
+         * @param {djs.model.Base|ModdleElement}
+         *            element
+         * @param {String}
+         *            type
+         * 
+         * @return {Boolean}
+         */
+        function is(element, type) {
+            var bo = getBusinessObject(element);
+
+            return bo && bo.$instanceOf(type);
+        }
+
+        module.exports.is = is;
+
+
+        /**
+         * Return the business object for a given element.
+         * 
+         * @param {djs.model.Base|ModdleElement}
+         *            element
+         * 
+         * @return {ModdleElement}
+         */
+        function getBusinessObject(element) {
+            return (element && element.businessObject) || element;
+        }
+
+        module.exports.getBusinessObject = getBusinessObject;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\index.js": [function(require, module, exports) {
+        module.exports = require('./lib/simple');
+    }, {
+        "./lib/simple": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\simple.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\bpmn-moddle.js": [function(require, module, exports) {
+        'use strict';
+
+        var isString = require('lodash/lang/isString'),
+            isFunction = require('lodash/lang/isFunction'),
+            assign = require('lodash/object/assign');
+
+        var Moddle = require('moddle'),
+            XmlReader = require('moddle-xml/lib/reader'),
+            XmlWriter = require('moddle-xml/lib/writer');
+
+        /**
+         * A sub class of {@link Moddle} with support for import and export of BPMN 2.0
+         * xml files.
+         * 
+         * @class BpmnModdle
+         * @extends Moddle
+         * 
+         * @param {Object|Array}
+         *            packages to use for instantiating the model
+         * @param {Object}
+         *            [options] additional options to pass over
+         */
+        function BpmnModdle(packages, options) {
+            Moddle.call(this, packages, options);
+        }
+
+        BpmnModdle.prototype = Object.create(Moddle.prototype);
+
+        module.exports = BpmnModdle;
+
+
+        /**
+         * Instantiates a BPMN model tree from a given xml string.
+         * 
+         * @param {String}
+         *            xmlStr
+         * @param {String}
+         *            [typeName='bpmn:Definitions'] name of the root element
+         * @param {Object}
+         *            [options] options to pass to the underlying reader
+         * @param {Function}
+         *            done callback that is invoked with (err, result, parseContext)
+         *            once the import completes
+         */
+        BpmnModdle.prototype.fromXML = function(xmlStr, typeName, options, done) {
+
+            if (!isString(typeName)) {
+                done = options;
+                options = typeName;
+                typeName = 'bpmn:Definitions';
+            }
+
+            if (isFunction(options)) {
+                done = options;
+                options = {};
+            }
+
+            var reader = new XmlReader(assign({
+                model: this,
+                lax: true
+            }, options));
+            var rootHandler = reader.handler(typeName);
+
+            reader.fromXML(xmlStr, rootHandler, done);
+        };
+
+
+        /**
+         * Serializes a BPMN 2.0 object tree to XML.
+         * 
+         * @param {String}
+         *            element the root element, typically an instance of
+         *            `bpmn:Definitions`
+         * @param {Object}
+         *            [options] to pass to the underlying writer
+         * @param {Function}
+         *            done callback invoked with (err, xmlStr) once the import completes
+         */
+        
+      
+        
+        
+        BpmnModdle.prototype.toXML = function(element, options, done) {
+
+            if (isFunction(options)) {
+                done = options;
+                options = {};
+            }
+
+            var writer = new XmlWriter(options);
+            try {
+                var result = writer.toXML(element);
+                modelXML = result;
+                list_models[selected_model]=result;
+                done(null, result);
+            } catch (e) {
+                done(e);
+            }
+        };
+
+    }, {
+        "lodash/lang/isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "moddle": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\index.js",
+        "moddle-xml/lib/reader": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\reader.js",
+        "moddle-xml/lib/writer": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\writer.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\id-support.js": [function(require, module, exports) {
+        'use strict';
+
+        var ID_PATTERN = /^(.*:)?id$/;
+
+        /**
+         * Extends the bpmn instance with id support.
+         * 
+         * @example
+         * 
+         * var moddle, ids;
+         * 
+         * require('id-support').extend(moddle, ids);
+         * 
+         * moddle.ids.next(); // create a next id moddle.ids; // ids instance
+         *  // claims id as used moddle.create('foo:Bar', { id: 'fooobar1' });
+         * 
+         * 
+         * @param {Moddle}
+         *            model
+         * @param {Ids}
+         *            ids
+         * 
+         * @return {Moddle} the extended moddle instance
+         */
+        module.exports.extend = function(model, ids) {
+
+            var set = model.properties.set;
+
+            // do not reinitialize setter
+            // unless it is already initialized
+            if (!model.ids) {
+
+                model.properties.set = function(target, property, value) {
+
+                    // ensure we log used ids once they are assigned
+                    // to model elements
+                    if (ID_PATTERN.test(property)) {
+
+                        var assigned = model.ids.assigned(value);
+                        if (assigned && assigned !== target) {
+                            throw new Error('id <' + value + '> already used');
+                        }
+
+                        model.ids.claim(value, target);
+                    }
+
+                    set.call(this, target, property, value);
+                };
+            }
+
+            model.ids = ids;
+
+            return model;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\simple.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+        var BpmnModdle = require('./bpmn-moddle');
+
+        var packages = {
+            bpmn: require('../resources/bpmn/json/bpmn.json'),
+            bpmndi: require('../resources/bpmn/json/bpmndi.json'),
+            dc: require('../resources/bpmn/json/dc.json'),
+            di: require('../resources/bpmn/json/di.json')
+        };
+
+        module.exports = function(additionalPackages, options) {
+            return new BpmnModdle(assign({}, packages, additionalPackages), options);
+        };
+    }, {
+        "../resources/bpmn/json/bpmn.json": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\bpmn.json",
+        "../resources/bpmn/json/bpmndi.json": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\bpmndi.json",
+        "../resources/bpmn/json/dc.json": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\dc.json",
+        "../resources/bpmn/json/di.json": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\di.json",
+        "./bpmn-moddle": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\lib\\bpmn-moddle.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\common.js": [function(require, module, exports) {
+        'use strict';
+
+        function capitalize(string) {
+            return string.charAt(0).toUpperCase() + string.slice(1);
+        }
+
+        function lower(string) {
+            return string.charAt(0).toLowerCase() + string.slice(1);
+        }
+
+        function hasLowerCaseAlias(pkg) {
+            return pkg.xml && pkg.xml.tagAlias === 'lowerCase';
+        }
+
+
+        module.exports.aliasToName = function(alias, pkg) {
+            if (hasLowerCaseAlias(pkg)) {
+                return capitalize(alias);
+            } else {
+                return alias;
+            }
+        };
+
+        module.exports.nameToAlias = function(name, pkg) {
+            if (hasLowerCaseAlias(pkg)) {
+                return lower(name);
+            } else {
+                return name;
+            }
+        };
+
+        module.exports.DEFAULT_NS_MAP = {
+            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
+        };
+
+        module.exports.XSI_TYPE = 'xsi:type';
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\reader.js": [function(require, module, exports) {
+        'use strict';
+
+        var reduce = require('lodash/collection/reduce'),
+            forEach = require('lodash/collection/forEach'),
+            find = require('lodash/collection/find'),
+            assign = require('lodash/object/assign'),
+            defer = require('lodash/function/defer');
+
+        var Stack = require('tiny-stack'),
+            SaxParser = require('sax').parser,
+            Moddle = require('moddle'),
+            parseNameNs = require('moddle/lib/ns').parseName,
+            Types = require('moddle/lib/types'),
+            coerceType = Types.coerceType,
+            isSimpleType = Types.isSimple,
+            common = require('./common'),
+            XSI_TYPE = common.XSI_TYPE,
+            XSI_URI = common.DEFAULT_NS_MAP.xsi,
+            aliasToName = common.aliasToName;
+
+        function parseNodeAttributes(node) {
+            var nodeAttrs = node.attributes;
+
+            return reduce(nodeAttrs, function(result, v, k) {
+                var name, ns;
+
+                if (!v.local) {
+                    name = v.prefix;
+                } else {
+                    ns = parseNameNs(v.name, v.prefix);
+                    name = ns.name;
+                }
+
+                result[name] = v.value;
+                return result;
+            }, {});
+        }
+
+        function normalizeType(node, attr, model) {
+            var nameNs = parseNameNs(attr.value);
+
+            var uri = node.ns[nameNs.prefix || ''],
+                localName = nameNs.localName,
+                pkg = uri && model.getPackage(uri),
+                typePrefix;
+
+            if (pkg) {
+                typePrefix = pkg.xml && pkg.xml.typePrefix;
+
+                if (typePrefix && localName.indexOf(typePrefix) === 0) {
+                    localName = localName.slice(typePrefix.length);
+                }
+
+                attr.value = pkg.prefix + ':' + localName;
+            }
+        }
+
+        /**
+         * Normalizes namespaces for a node given an optional default namespace and a
+         * number of mappings from uris to default prefixes.
+         * 
+         * @param {XmlNode}
+         *            node
+         * @param {Model}
+         *            model the model containing all registered namespaces
+         * @param {Uri}
+         *            defaultNsUri
+         */
+        function normalizeNamespaces(node, model, defaultNsUri) {
+            var uri, prefix;
+
+            uri = node.uri || defaultNsUri;
+
+            if (uri) {
+                var pkg = model.getPackage(uri);
+
+                if (pkg) {
+                    prefix = pkg.prefix;
+                } else {
+                    prefix = node.prefix;
+                }
+
+                node.prefix = prefix;
+                node.uri = uri;
+            }
+
+            forEach(node.attributes, function(attr) {
+
+                // normalize xsi:type attributes because the
+                // assigned type may or may not be namespace prefixed
+                if (attr.uri === XSI_URI && attr.local === 'type') {
+                    normalizeType(node, attr, model);
+                }
+
+                normalizeNamespaces(attr, model, null);
+            });
+        }
+
+
+        /**
+         * A parse context.
+         * 
+         * @class
+         * 
+         * @param {Object}
+         *            options
+         * @param {ElementHandler}
+         *            options.parseRoot the root handler for parsing a document
+         * @param {boolean}
+         *            [options.lax=false] whether or not to ignore invalid elements
+         */
+        function Context(options) {
+
+            /**
+             * @property {ElementHandler} parseRoot
+             */
+
+            /**
+             * @property {Boolean} lax
+             */
+
+            assign(this, options);
+
+            var elementsById = this.elementsById = {};
+            var references = this.references = [];
+            var warnings = this.warnings = [];
+
+            this.addReference = function(reference) {
+                references.push(reference);
+            };
+
+            this.addElement = function(id, element) {
+
+                if (!id || !element) {
+                    throw new Error('[xml-reader] id or ctx must not be null');
+                }
+
+                elementsById[id] = element;
+            };
+
+            this.addWarning = function(w) {
+                warnings.push(w);
+            };
+        }
+
+        function BaseHandler() {}
+
+        BaseHandler.prototype.handleEnd = function() {};
+        BaseHandler.prototype.handleText = function() {};
+        BaseHandler.prototype.handleNode = function() {};
+
+
+        /**
+         * A simple pass through handler that does nothing except for ignoring all input
+         * it receives.
+         * 
+         * This is used to ignore unknown elements and attributes.
+         */
+        function NoopHandler() {}
+
+        NoopHandler.prototype = new BaseHandler();
+
+        NoopHandler.prototype.handleNode = function() {
+            return this;
+        };
+
+        function BodyHandler() {}
+
+        BodyHandler.prototype = new BaseHandler();
+
+        BodyHandler.prototype.handleText = function(text) {
+            this.body = (this.body || '') + text;
+        };
+
+        function ReferenceHandler(property, context) {
+            this.property = property;
+            this.context = context;
+        }
+
+        ReferenceHandler.prototype = new BodyHandler();
+
+        ReferenceHandler.prototype.handleNode = function(node) {
+
+            if (this.element) {
+                throw new Error('expected no sub nodes');
+            } else {
+                this.element = this.createReference(node);
+            }
+
+            return this;
+        };
+
+        ReferenceHandler.prototype.handleEnd = function() {
+            this.element.id = this.body;
+        };
+
+        ReferenceHandler.prototype.createReference = function() {
+            return {
+                property: this.property.ns.name,
+                id: ''
+            };
+        };
+
+        function ValueHandler(propertyDesc, element) {
+            this.element = element;
+            this.propertyDesc = propertyDesc;
+        }
+
+        ValueHandler.prototype = new BodyHandler();
+
+        ValueHandler.prototype.handleEnd = function() {
+
+            var value = this.body,
+                element = this.element,
+                propertyDesc = this.propertyDesc;
+
+            value = coerceType(propertyDesc.type, value);
+
+            if (propertyDesc.isMany) {
+                element.get(propertyDesc.name).push(value);
+            } else {
+                element.set(propertyDesc.name, value);
+            }
+        };
+
+
+        function BaseElementHandler() {}
+
+        BaseElementHandler.prototype = Object.create(BodyHandler.prototype);
+
+        BaseElementHandler.prototype.handleNode = function(node) {
+            var parser = this,
+                element = this.element,
+                id;
+
+            if (!element) {
+                element = this.element = this.createElement(node);
+                id = element.id;
+
+                if (id) {
+                    this.context.addElement(id, element);
+                }
+            } else {
+                parser = this.handleChild(node);
+            }
+
+            return parser;
+        };
+
+        /**
+         * @class XMLReader.ElementHandler
+         * 
+         */
+        function ElementHandler(model, type, context) {
+            this.model = model;
+            this.type = model.getType(type);
+            this.context = context;
+        }
+
+        ElementHandler.prototype = new BaseElementHandler();
+
+        ElementHandler.prototype.addReference = function(reference) {
+            this.context.addReference(reference);
+        };
+
+        ElementHandler.prototype.handleEnd = function() {
+
+            var value = this.body,
+                element = this.element,
+                descriptor = element.$descriptor,
+                bodyProperty = descriptor.bodyProperty;
+
+            if (bodyProperty && value !== undefined) {
+                value = coerceType(bodyProperty.type, value);
+                element.set(bodyProperty.name, value);
+            }
+        };
+
+        /**
+         * Create an instance of the model from the given node.
+         * 
+         * @param {Element}
+         *            node the xml node
+         */
+        ElementHandler.prototype.createElement = function(node) {
+            var attributes = parseNodeAttributes(node),
+                Type = this.type,
+                descriptor = Type.$descriptor,
+                context = this.context,
+                instance = new Type({});
+
+            forEach(attributes, function(value, name) {
+
+                var prop = descriptor.propertiesByName[name];
+
+                if (prop && prop.isReference) {
+                    context.addReference({
+                        element: instance,
+                        property: prop.ns.name,
+                        id: value
+                    });
+                } else {
+                    if (prop) {
+                        value = coerceType(prop.type, value);
+                    }
+
+                    instance.set(name, value);
+                }
+            });
+
+            return instance;
+        };
+
+        ElementHandler.prototype.getPropertyForNode = function(node) {
+
+            var nameNs = parseNameNs(node.local, node.prefix);
+
+            var type = this.type,
+                model = this.model,
+                descriptor = type.$descriptor;
+
+            var propertyName = nameNs.name,
+                property = descriptor.propertiesByName[propertyName],
+                elementTypeName,
+                elementType,
+                typeAnnotation;
+
+            // search for properties by name first
+
+            if (property) {
+
+                if (property.serialize === XSI_TYPE) {
+                    typeAnnotation = node.attributes[XSI_TYPE];
+
+                    // xsi type is optional, if it does not exists the
+                    // default type is assumed
+                    if (typeAnnotation) {
+
+                        elementTypeName = typeAnnotation.value;
+
+                        // TODO: extract real name from attribute
+                        elementType = model.getType(elementTypeName);
+
+                        return assign({}, property, {
+                            effectiveType: elementType.$descriptor.name
+                        });
+                    }
+                }
+
+                // search for properties by name first
+                return property;
+            }
+
+
+            var pkg = model.getPackage(nameNs.prefix);
+
+            if (pkg) {
+                elementTypeName = nameNs.prefix + ':' + aliasToName(nameNs.localName, descriptor.$pkg);
+                elementType = model.getType(elementTypeName);
+
+                // search for collection members later
+                property = find(descriptor.properties, function(p) {
+                    return !p.isVirtual && !p.isReference && !p.isAttribute && elementType.hasType(p.type);
+                });
+
+                if (property) {
+                    return assign({}, property, {
+                        effectiveType: elementType.$descriptor.name
+                    });
+                }
+            } else {
+                // parse unknown element (maybe extension)
+                property = find(descriptor.properties, function(p) {
+                    return !p.isReference && !p.isAttribute && p.type === 'Element';
+                });
+
+                if (property) {
+                    return property;
+                }
+            }
+
+            throw new Error('unrecognized element <' + nameNs.name + '>');
+        };
+
+        ElementHandler.prototype.toString = function() {
+            return 'ElementDescriptor[' + this.type.$descriptor.name + ']';
+        };
+
+        ElementHandler.prototype.valueHandler = function(propertyDesc, element) {
+            return new ValueHandler(propertyDesc, element);
+        };
+
+        ElementHandler.prototype.referenceHandler = function(propertyDesc) {
+            return new ReferenceHandler(propertyDesc, this.context);
+        };
+
+        ElementHandler.prototype.handler = function(type) {
+            if (type === 'Element') {
+                return new GenericElementHandler(this.model, type, this.context);
+            } else {
+                return new ElementHandler(this.model, type, this.context);
+            }
+        };
+
+        /**
+         * Handle the child element parsing
+         * 
+         * @param {Element}
+         *            node the xml node
+         */
+        ElementHandler.prototype.handleChild = function(node) {
+            var propertyDesc, type, element, childHandler;
+
+            propertyDesc = this.getPropertyForNode(node);
+            element = this.element;
+
+            type = propertyDesc.effectiveType || propertyDesc.type;
+
+            if (isSimpleType(type)) {
+                return this.valueHandler(propertyDesc, element);
+            }
+
+            if (propertyDesc.isReference) {
+                childHandler = this.referenceHandler(propertyDesc).handleNode(node);
+            } else {
+                childHandler = this.handler(type).handleNode(node);
+            }
+
+            var newElement = childHandler.element;
+
+            // child handles may decide to skip elements
+            // by not returning anything
+            if (newElement !== undefined) {
+
+                if (propertyDesc.isMany) {
+                    element.get(propertyDesc.name).push(newElement);
+                } else {
+                    element.set(propertyDesc.name, newElement);
+                }
+
+                if (propertyDesc.isReference) {
+                    assign(newElement, {
+                        element: element
+                    });
+
+                    this.context.addReference(newElement);
+                } else {
+                    // establish child -> parent relationship
+                    newElement.$parent = element;
+                }
+            }
+
+            return childHandler;
+        };
+
+
+        function GenericElementHandler(model, type, context) {
+            this.model = model;
+            this.context = context;
+        }
+
+        GenericElementHandler.prototype = Object.create(BaseElementHandler.prototype);
+
+        GenericElementHandler.prototype.createElement = function(node) {
+
+            var name = node.name,
+                prefix = node.prefix,
+                uri = node.ns[prefix],
+                attributes = node.attributes;
+
+            return this.model.createAny(name, uri, attributes);
+        };
+
+        GenericElementHandler.prototype.handleChild = function(node) {
+
+            var handler = new GenericElementHandler(this.model, 'Element', this.context).handleNode(node),
+                element = this.element;
+
+            var newElement = handler.element,
+                children;
+
+            if (newElement !== undefined) {
+                children = element.$children = element.$children || [];
+                children.push(newElement);
+
+                // establish child -> parent relationship
+                newElement.$parent = element;
+            }
+
+            return handler;
+        };
+
+        GenericElementHandler.prototype.handleText = function(text) {
+            this.body = this.body || '' + text;
+        };
+
+        GenericElementHandler.prototype.handleEnd = function() {
+            if (this.body) {
+                this.element.$body = this.body;
+            }
+        };
+
+        /**
+         * A reader for a meta-model
+         * 
+         * @param {Object}
+         *            options
+         * @param {Model}
+         *            options.model used to read xml files
+         * @param {Boolean}
+         *            options.lax whether to make parse errors warnings
+         */
+        function XMLReader(options) {
+
+            if (options instanceof Moddle) {
+                options = {
+                    model: options
+                };
+            }
+
+            assign(this, {
+                lax: false
+            }, options);
+        }
+
+
+        XMLReader.prototype.fromXML = function(xml, rootHandler, done) {
+
+            var model = this.model,
+                lax = this.lax,
+                context = new Context({
+                    parseRoot: rootHandler
+                });
+
+            var parser = new SaxParser(true, {
+                    xmlns: true,
+                    trim: true
+                }),
+                stack = new Stack();
+
+            rootHandler.context = context;
+
+            // push root handler
+            stack.push(rootHandler);
+
+
+            function resolveReferences() {
+
+                var elementsById = context.elementsById;
+                var references = context.references;
+
+                var i, r;
+
+                for (i = 0; !!(r = references[i]); i++) {
+                    var element = r.element;
+                    var reference = elementsById[r.id];
+                    var property = element.$descriptor.propertiesByName[r.property];
+
+                    if (!reference) {
+                        context.addWarning({
+                            message: 'unresolved reference <' + r.id + '>',
+                            element: r.element,
+                            property: r.property,
+                            value: r.id
+                        });
+                    }
+
+                    if (property.isMany) {
+                        var collection = element.get(property.name),
+                            idx = collection.indexOf(r);
+
+                        if (!reference) {
+                            // remove unresolvable reference
+                            collection.splice(idx, 1);
+                        } else {
+                            // update reference
+                            collection[idx] = reference;
+                        }
+                    } else {
+                        element.set(property.name, reference);
+                    }
+                }
+            }
+
+            function handleClose(tagName) {
+                stack.pop().handleEnd();
+            }
+
+            function handleOpen(node) {
+                var handler = stack.peek();
+
+                normalizeNamespaces(node, model);
+
+                try {
+                    stack.push(handler.handleNode(node));
+                } catch (e) {
+
+                    var line = this.line,
+                        column = this.column;
+
+                    var message =
+                        'unparsable content <' + node.name + '> detected\n\t' +
+                        'line: ' + line + '\n\t' +
+                        'column: ' + column + '\n\t' +
+                        'nested error: ' + e.message;
+
+                    if (lax) {
+                        context.addWarning({
+                            message: message,
+                            error: e
+                        });
+
+                        console.warn('could not parse node');
+                        console.warn(e);
+
+                        stack.push(new NoopHandler());
+                    } else {
+                        console.error('could not parse document');
+                        console.error(e);
+
+                        throw new Error(message);
+                    }
+                }
+            }
+
+            function handleText(text) {
+                stack.peek().handleText(text);
+            }
+
+            parser.onopentag = handleOpen;
+            parser.oncdata = parser.ontext = handleText;
+            parser.onclosetag = handleClose;
+            parser.onend = resolveReferences;
+
+            // deferred parse XML to make loading really ascnchronous
+            // this ensures the execution environment (node or browser)
+            // is kept responsive and that certain optimization strategies
+            // can kick in
+            defer(function() {
+                var error;
+
+                try {
+                    parser.write(xml).close();
+                } catch (e) {
+                    error = e;
+                }
+
+                done(error, error ? undefined : rootHandler.element, context);
+            });
+        };
+
+        XMLReader.prototype.handler = function(name) {
+            return new ElementHandler(this.model, name);
+        };
+
+        module.exports = XMLReader;
+        module.exports.ElementHandler = ElementHandler;
+    }, {
+        "./common": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\common.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/reduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\reduce.js",
+        "lodash/function/defer": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\defer.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "moddle": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\index.js",
+        "moddle/lib/ns": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js",
+        "moddle/lib/types": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\types.js",
+        "sax": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\node_modules\\sax\\lib\\sax.js",
+        "tiny-stack": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\node_modules\\tiny-stack\\lib\\tiny-stack.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\writer.js": [function(require, module, exports) {
+        'use strict';
+
+        var map = require('lodash/collection/map'),
+            forEach = require('lodash/collection/forEach'),
+            isString = require('lodash/lang/isString'),
+            filter = require('lodash/collection/filter'),
+            assign = require('lodash/object/assign');
+
+        var Types = require('moddle/lib/types'),
+            parseNameNs = require('moddle/lib/ns').parseName,
+            common = require('./common'),
+            nameToAlias = common.nameToAlias;
+
+        var XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>\n',
+            ESCAPE_CHARS = /(<|>|'|"|&|\n\r|\n)/g,
+            DEFAULT_NS_MAP = common.DEFAULT_NS_MAP,
+            XSI_TYPE = common.XSI_TYPE;
+
+
+        function nsName(ns) {
+            if (isString(ns)) {
+                return ns;
+            } else {
+                return (ns.prefix ? ns.prefix + ':' : '') + ns.localName;
+            }
+        }
+
+        function getElementNs(ns, descriptor) {
+            if (descriptor.isGeneric) {
+                return descriptor.name;
+            } else {
+                return assign({
+                    localName: nameToAlias(descriptor.ns.localName, descriptor.$pkg)
+                }, ns);
+            }
+        }
+
+        function getPropertyNs(ns, descriptor) {
+            return assign({
+                localName: descriptor.ns.localName
+            }, ns);
+        }
+
+        function getSerializableProperties(element) {
+            var descriptor = element.$descriptor;
+
+            return filter(descriptor.properties, function(p) {
+                var name = p.name;
+
+                // do not serialize defaults
+                if (!element.hasOwnProperty(name)) {
+                    return false;
+                }
+
+                var value = element[name];
+
+                // do not serialize default equals
+                if (value === p.default) {
+                    return false;
+                }
+
+                return p.isMany ? value.length : true;
+            });
+        }
+
+        var ESCAPE_MAP = {
+            '\n': '10',
+            '\n\r': '10',
+            '"': '34',
+            '\'': '39',
+            '<': '60',
+            '>': '62',
+            '&': '38'
+        };
+
+        /**
+         * Escape a string attribute to not contain any bad values (line breaks, '"',
+         * ...)
+         * 
+         * @param {String}
+         *            str the string to escape
+         * @return {String} the escaped string
+         */
+        function escapeAttr(str) {
+
+            // ensure we are handling strings here
+            str = isString(str) ? str : '' + str;
+
+            return str.replace(ESCAPE_CHARS, function(str) {
+                return '&#' + ESCAPE_MAP[str] + ';';
+            });
+        }
+
+        function filterAttributes(props) {
+            return filter(props, function(p) {
+                return p.isAttr;
+            });
+        }
+
+        function filterContained(props) {
+            return filter(props, function(p) {
+                return !p.isAttr;
+            });
+        }
+
+
+        function ReferenceSerializer(parent, ns) {
+            this.ns = ns;
+        }
+
+        ReferenceSerializer.prototype.build = function(element) {
+            this.element = element;
+            return this;
+        };
+
+        ReferenceSerializer.prototype.serializeTo = function(writer) {
+            writer
+                .appendIndent()
+                .append('<' + nsName(this.ns) + '>' + this.element.id + '</' + nsName(this.ns) + '>')
+                .appendNewLine();
+        };
+
+        function BodySerializer() {}
+
+        BodySerializer.prototype.serializeValue = BodySerializer.prototype.serializeTo = function(writer) {
+            var escape = this.escape;
+
+            if (escape) {
+                writer.append('<![CDATA[');
+            }
+
+            writer.append(this.value);
+
+            if (escape) {
+                writer.append(']]>');
+            }
+        };
+
+        BodySerializer.prototype.build = function(prop, value) {
+            this.value = value;
+
+            if (prop.type === 'String' && ESCAPE_CHARS.test(value)) {
+                this.escape = true;
+            }
+
+            return this;
+        };
+
+        function ValueSerializer(ns) {
+            this.ns = ns;
+        }
+
+        ValueSerializer.prototype = new BodySerializer();
+
+        ValueSerializer.prototype.serializeTo = function(writer) {
+
+            writer
+                .appendIndent()
+                .append('<' + nsName(this.ns) + '>');
+
+            this.serializeValue(writer);
+
+            writer
+                .append('</' + nsName(this.ns) + '>')
+                .appendNewLine();
+        };
+
+        function ElementSerializer(parent, ns) {
+            this.body = [];
+            this.attrs = [];
+
+            this.parent = parent;
+            this.ns = ns;
+        }
+
+        ElementSerializer.prototype.build = function(element) {
+            this.element = element;
+
+            var otherAttrs = this.parseNsAttributes(element);
+
+            if (!this.ns) {
+                this.ns = this.nsTagName(element.$descriptor);
+            }
+
+            if (element.$descriptor.isGeneric) {
+                this.parseGeneric(element);
+            } else {
+                var properties = getSerializableProperties(element);
+
+                this.parseAttributes(filterAttributes(properties));
+                this.parseContainments(filterContained(properties));
+
+                this.parseGenericAttributes(element, otherAttrs);
+            }
+
+            return this;
+        };
+
+        ElementSerializer.prototype.nsTagName = function(descriptor) {
+            var effectiveNs = this.logNamespaceUsed(descriptor.ns);
+            return getElementNs(effectiveNs, descriptor);
+        };
+
+        ElementSerializer.prototype.nsPropertyTagName = function(descriptor) {
+            var effectiveNs = this.logNamespaceUsed(descriptor.ns);
+            return getPropertyNs(effectiveNs, descriptor);
+        };
+
+        ElementSerializer.prototype.isLocalNs = function(ns) {
+            return ns.uri === this.ns.uri;
+        };
+
+        ElementSerializer.prototype.nsAttributeName = function(element) {
+
+            var ns;
+
+            if (isString(element)) {
+                ns = parseNameNs(element);
+            } else
+            if (element.ns) {
+                ns = element.ns;
+            }
+
+            var effectiveNs = this.logNamespaceUsed(ns);
+
+            // strip prefix if same namespace like parent
+            if (this.isLocalNs(effectiveNs)) {
+                return {
+                    localName: ns.localName
+                };
+            } else {
+                return assign({
+                    localName: ns.localName
+                }, effectiveNs);
+            }
+        };
+
+        ElementSerializer.prototype.parseGeneric = function(element) {
+
+            var self = this,
+                body = this.body,
+                attrs = this.attrs;
+
+            forEach(element, function(val, key) {
+
+                if (key === '$body') {
+                    body.push(new BodySerializer().build({
+                        type: 'String'
+                    }, val));
+                } else
+                if (key === '$children') {
+                    forEach(val, function(child) {
+                        body.push(new ElementSerializer(self).build(child));
+                    });
+                } else
+                if (key.indexOf('$') !== 0) {
+                    attrs.push({
+                        name: key,
+                        value: escapeAttr(val)
+                    });
+                }
+            });
+        };
+
+        /**
+         * Parse namespaces and return a list of left over generic attributes
+         * 
+         * @param {Object}
+         *            element
+         * @return {Array<Object>}
+         */
+        ElementSerializer.prototype.parseNsAttributes = function(element) {
+            var self = this;
+
+            var genericAttrs = element.$attrs;
+
+            var attributes = [];
+
+            // parse namespace attributes first
+            // and log them. push non namespace attributes to a list
+            // and process them later
+            forEach(genericAttrs, function(value, name) {
+                var nameNs = parseNameNs(name);
+
+                if (nameNs.prefix === 'xmlns') {
+                    self.logNamespace({
+                        prefix: nameNs.localName,
+                        uri: value
+                    });
+                } else
+                if (!nameNs.prefix && nameNs.localName === 'xmlns') {
+                    self.logNamespace({
+                        uri: value
+                    });
+                } else {
+                    attributes.push({
+                        name: name,
+                        value: value
+                    });
+                }
+            });
+
+            return attributes;
+        };
+
+        ElementSerializer.prototype.parseGenericAttributes = function(element, attributes) {
+
+            var self = this;
+
+            forEach(attributes, function(attr) {
+
+                // do not serialize xsi:type attribute
+                // it is set manually based on the actual implementation type
+                if (attr.name === XSI_TYPE) {
+                    return;
+                }
+
+                try {
+                    self.addAttribute(self.nsAttributeName(attr.name), attr.value);
+                } catch (e) {
+                    console.warn('[writer] missing namespace information for ', attr.name, '=', attr.value, 'on', element, e);
+                }
+            });
+        };
+
+        ElementSerializer.prototype.parseContainments = function(properties) {
+
+            var self = this,
+                body = this.body,
+                element = this.element;
+
+            forEach(properties, function(p) {
+                var value = element.get(p.name),
+                    isReference = p.isReference,
+                    isMany = p.isMany;
+
+                var ns = self.nsPropertyTagName(p);
+
+                if (!isMany) {
+                    value = [value];
+                }
+
+                if (p.isBody) {
+                    body.push(new BodySerializer().build(p, value[0]));
+                } else
+                if (Types.isSimple(p.type)) {
+                    forEach(value, function(v) {
+                        body.push(new ValueSerializer(ns).build(p, v));
+                    });
+                } else
+                if (isReference) {
+                    forEach(value, function(v) {
+                        body.push(new ReferenceSerializer(self, ns).build(v));
+                    });
+                } else {
+                    // allow serialization via type
+                    // rather than element name
+                    var asType = p.serialize === XSI_TYPE;
+
+                    forEach(value, function(v) {
+                        var serializer;
+
+                        if (asType) {
+                            serializer = new TypeSerializer(self, ns);
+                        } else {
+                            serializer = new ElementSerializer(self);
+                        }
+
+                        body.push(serializer.build(v));
+                    });
+                }
+            });
+        };
+
+        ElementSerializer.prototype.getNamespaces = function() {
+            if (!this.parent) {
+                if (!this.namespaces) {
+                    this.namespaces = {
+                        prefixMap: {},
+                        uriMap: {},
+                        used: {}
+                    };
+                }
+            } else {
+                this.namespaces = this.parent.getNamespaces();
+            }
+
+            return this.namespaces;
+        };
+
+        ElementSerializer.prototype.logNamespace = function(ns) {
+            var namespaces = this.getNamespaces();
+
+            var existing = namespaces.uriMap[ns.uri];
+
+            if (!existing) {
+                namespaces.uriMap[ns.uri] = ns;
+            }
+
+            namespaces.prefixMap[ns.prefix] = ns.uri;
+
+            return ns;
+        };
+
+        ElementSerializer.prototype.logNamespaceUsed = function(ns) {
+            var element = this.element,
+                model = element.$model,
+                namespaces = this.getNamespaces();
+
+            // ns may be
+            //
+            // * prefix only
+            // * prefix:uri
+
+            var prefix = ns.prefix;
+            var uri = ns.uri || DEFAULT_NS_MAP[prefix] ||
+                namespaces.prefixMap[prefix] || (model ? (model.getPackage(prefix) || {}).uri : null);
+
+            if (!uri) {
+                throw new Error('no namespace uri given for prefix <' + ns.prefix + '>');
+            }
+
+            ns = namespaces.uriMap[uri];
+
+            if (!ns) {
+                ns = this.logNamespace({
+                    prefix: prefix,
+                    uri: uri
+                });
+            }
+
+            if (!namespaces.used[ns.uri]) {
+                namespaces.used[ns.uri] = ns;
+            }
+
+            return ns;
+        };
+
+        ElementSerializer.prototype.parseAttributes = function(properties) {
+            var self = this,
+                element = this.element;
+
+            forEach(properties, function(p) {
+                self.logNamespaceUsed(p.ns);
+
+                var value = element.get(p.name);
+
+                if (p.isReference) {
+                    value = value.id;
+                }
+
+                self.addAttribute(self.nsAttributeName(p), value);
+            });
+        };
+
+        ElementSerializer.prototype.addAttribute = function(name, value) {
+            var attrs = this.attrs;
+
+            if (isString(value)) {
+                value = escapeAttr(value);
+            }
+
+            attrs.push({
+                name: name,
+                value: value
+            });
+        };
+
+        ElementSerializer.prototype.serializeAttributes = function(writer) {
+            var attrs = this.attrs,
+                root = !this.parent,
+                namespaces = this.namespaces;
+
+            function collectNsAttrs() {
+                return map(namespaces.used, function(ns) {
+                    var name = 'xmlns' + (ns.prefix ? ':' + ns.prefix : '');
+                    return {
+                        name: name,
+                        value: ns.uri
+                    };
+                });
+            }
+
+            if (root) {
+                attrs = collectNsAttrs().concat(attrs);
+            }
+
+            forEach(attrs, function(a) {
+                writer
+                    .append(' ')
+                    .append(nsName(a.name)).append('="').append(a.value).append('"');
+            });
+        };
+
+        ElementSerializer.prototype.serializeTo = function(writer) {
+            var hasBody = this.body.length,
+                indent = !(this.body.length === 1 && this.body[0] instanceof BodySerializer);
+
+            writer
+                .appendIndent()
+                .append('<' + nsName(this.ns));
+
+            this.serializeAttributes(writer);
+
+            writer.append(hasBody ? '>' : ' />');
+
+            if (hasBody) {
+
+                if (indent) {
+                    writer
+                        .appendNewLine()
+                        .indent();
+                }
+
+                forEach(this.body, function(b) {
+                    b.serializeTo(writer);
+                });
+
+                if (indent) {
+                    writer
+                        .unindent()
+                        .appendIndent();
+                }
+
+                writer.append('</' + nsName(this.ns) + '>');
+            }
+
+            writer.appendNewLine();
+        };
+
+        /**
+         * A serializer for types that handles serialization of data types
+         */
+        function TypeSerializer(parent, ns) {
+            ElementSerializer.call(this, parent, ns);
+        }
+
+        TypeSerializer.prototype = new ElementSerializer();
+
+        TypeSerializer.prototype.build = function(element) {
+            var descriptor = element.$descriptor;
+
+            this.element = element;
+
+            this.typeNs = this.nsTagName(descriptor);
+
+            // add xsi:type attribute to represent the elements
+            // actual type
+
+            var typeNs = this.typeNs,
+                pkg = element.$model.getPackage(typeNs.uri),
+                typePrefix = (pkg.xml && pkg.xml.typePrefix) || '';
+
+            this.addAttribute(this.nsAttributeName(XSI_TYPE), (typeNs.prefix ? typeNs.prefix + ':' : '') +
+                typePrefix + descriptor.ns.localName);
+
+            // do the usual stuff
+            return ElementSerializer.prototype.build.call(this, element);
+        };
+
+        TypeSerializer.prototype.isLocalNs = function(ns) {
+            return ns.uri === this.typeNs.uri;
+        };
+
+        function SavingWriter() {
+            this.value = '';
+
+            this.write = function(str) {
+                this.value += str;
+            };
+        }
+
+        function FormatingWriter(out, format) {
+
+            var indent = [''];
+
+            this.append = function(str) {
+                out.write(str);
+
+                return this;
+            };
+
+            this.appendNewLine = function() {
+                if (format) {
+                    out.write('\n');
+                }
+
+                return this;
+            };
+
+            this.appendIndent = function() {
+                if (format) {
+                    out.write(indent.join('  '));
+                }
+
+                return this;
+            };
+
+            this.indent = function() {
+                indent.push('');
+                return this;
+            };
+
+            this.unindent = function() {
+                indent.pop();
+                return this;
+            };
+        }
+
+        /**
+         * A writer for meta-model backed document trees
+         * 
+         * @param {Object}
+         *            options output options to pass into the writer
+         */
+        function XMLWriter(options) {
+
+            options = assign({
+                format: false,
+                preamble: true
+            }, options || {});
+
+            function toXML(tree, writer) {
+                var internalWriter = writer || new SavingWriter();
+                var formatingWriter = new FormatingWriter(internalWriter, options.format);
+
+                if (options.preamble) {
+                    formatingWriter.append(XML_PREAMBLE);
+                }
+
+                new ElementSerializer().build(tree).serializeTo(formatingWriter);
+
+                if (!writer) {
+                    return internalWriter.value;
+                }
+            }
+
+            return {
+                toXML: toXML
+            };
+        }
+
+        module.exports = XMLWriter;
+    }, {
+        "./common": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\lib\\common.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/map": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\map.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "moddle/lib/ns": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js",
+        "moddle/lib/types": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\types.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\node_modules\\sax\\lib\\sax.js": [function(require, module, exports) {
+        (function(Buffer) {
+            // wrapper for non-node envs
+            ;
+            (function(sax) {
+
+                sax.parser = function(strict, opt) {
+                    return new SAXParser(strict, opt)
+                }
+                sax.SAXParser = SAXParser
+                sax.SAXStream = SAXStream
+                sax.createStream = createStream
+
+                // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer
+                // overruns.
+                // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer
+                // lengths)),
+                // since that's the earliest that a buffer overrun could occur. This way, checks
+                // are
+                // as rare as required, but as often as necessary to ensure never crossing this
+                // bound.
+                // Furthermore, buffers are only tested at most once per write(), so passing a
+                // very
+                // large string into write() might have undesirable effects, but this is
+                // manageable by
+                // the caller, so it is assumed to be safe. Thus, a call to write() may, in the
+                // extreme
+                // edge case, result in creating at most one complete copy of the string passed
+                // in.
+                // Set to Infinity to have unlimited buffers.
+                sax.MAX_BUFFER_LENGTH = 64 * 1024
+
+                var buffers = [
+                    "comment", "sgmlDecl", "textNode", "tagName", "doctype",
+                    "procInstName", "procInstBody", "entity", "attribName",
+                    "attribValue", "cdata", "script"
+                ]
+
+                sax.EVENTS = // for discoverability.
+                    ["text", "processinginstruction", "sgmldeclaration", "doctype", "comment", "attribute", "opentag", "closetag", "opencdata", "cdata", "closecdata", "error", "end", "ready", "script", "opennamespace", "closenamespace"]
+
+                function SAXParser(strict, opt) {
+                    if (!(this instanceof SAXParser)) return new SAXParser(strict, opt)
+
+                    var parser = this
+                    clearBuffers(parser)
+                    parser.q = parser.c = ""
+                    parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH
+                    parser.opt = opt || {}
+                    parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags
+                    parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase"
+                    parser.tags = []
+                    parser.closed = parser.closedRoot = parser.sawRoot = false
+                    parser.tag = parser.error = null
+                    parser.strict = !!strict
+                    parser.noscript = !!(strict || parser.opt.noscript)
+                    parser.state = S.BEGIN
+                    parser.ENTITIES = Object.create(sax.ENTITIES)
+                    parser.attribList = []
+
+                    // namespaces form a prototype chain.
+                    // it always points at the current tag,
+                    // which protos to its parent tag.
+                    if (parser.opt.xmlns) parser.ns = Object.create(rootNS)
+
+                    // mostly just for error reporting
+                    parser.trackPosition = parser.opt.position !== false
+                    if (parser.trackPosition) {
+                        parser.position = parser.line = parser.column = 0
+                    }
+                    emit(parser, "onready")
+                }
+
+                if (!Object.create) Object.create = function(o) {
+                    function f() {
+                        this.__proto__ = o
+                    }
+                    f.prototype = o
+                    return new f
+                }
+
+                if (!Object.getPrototypeOf) Object.getPrototypeOf = function(o) {
+                    return o.__proto__
+                }
+
+                if (!Object.keys) Object.keys = function(o) {
+                    var a = []
+                    for (var i in o)
+                        if (o.hasOwnProperty(i)) a.push(i)
+                    return a
+                }
+
+                function checkBufferLength(parser) {
+                    var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10),
+                        maxActual = 0
+                    for (var i = 0, l = buffers.length; i < l; i++) {
+                        var len = parser[buffers[i]].length
+                        if (len > maxAllowed) {
+                            // Text/cdata nodes can get big, and since they're buffered,
+                            // we can get here under normal conditions.
+                            // Avoid issues by emitting the text node now,
+                            // so at least it won't get any bigger.
+                            switch (buffers[i]) {
+                                case "textNode":
+                                    closeText(parser)
+                                    break
+
+                                case "cdata":
+                                    emitNode(parser, "oncdata", parser.cdata)
+                                    parser.cdata = ""
+                                    break
+
+                                case "script":
+                                    emitNode(parser, "onscript", parser.script)
+                                    parser.script = ""
+                                    break
+
+                                default:
+                                    error(parser, "Max buffer length exceeded: " + buffers[i])
+                            }
+                        }
+                        maxActual = Math.max(maxActual, len)
+                    }
+                    // schedule the next check for the earliest possible buffer overrun.
+                    parser.bufferCheckPosition = (sax.MAX_BUFFER_LENGTH - maxActual) + parser.position
+                }
+
+                function clearBuffers(parser) {
+                    for (var i = 0, l = buffers.length; i < l; i++) {
+                        parser[buffers[i]] = ""
+                    }
+                }
+
+                function flushBuffers(parser) {
+                    closeText(parser)
+                    if (parser.cdata !== "") {
+                        emitNode(parser, "oncdata", parser.cdata)
+                        parser.cdata = ""
+                    }
+                    if (parser.script !== "") {
+                        emitNode(parser, "onscript", parser.script)
+                        parser.script = ""
+                    }
+                }
+
+                SAXParser.prototype = {
+                    end: function() {
+                        end(this)
+                    },
+                    write: write,
+                    resume: function() {
+                        this.error = null;
+                        return this
+                    },
+                    close: function() {
+                        return this.write(null)
+                    },
+                    flush: function() {
+                        flushBuffers(this)
+                    }
+                }
+
+                try {
+                    var Stream = require("stream").Stream
+                } catch (ex) {
+                    var Stream = function() {}
+                }
+
+
+                var streamWraps = sax.EVENTS.filter(function(ev) {
+                    return ev !== "error" && ev !== "end"
+                })
+
+                function createStream(strict, opt) {
+                    return new SAXStream(strict, opt)
+                }
+
+                function SAXStream(strict, opt) {
+                    if (!(this instanceof SAXStream)) return new SAXStream(strict, opt)
+
+                    Stream.apply(this)
+
+                    this._parser = new SAXParser(strict, opt)
+                    this.writable = true
+                    this.readable = true
+
+
+                    var me = this
+
+                    this._parser.onend = function() {
+                        me.emit("end")
+                    }
+
+                    this._parser.onerror = function(er) {
+                        me.emit("error", er)
+
+                        // if didn't throw, then means error was handled.
+                        // go ahead and clear error, so we can write again.
+                        me._parser.error = null
+                    }
+
+                    this._decoder = null;
+
+                    streamWraps.forEach(function(ev) {
+                        Object.defineProperty(me, "on" + ev, {
+                            get: function() {
+                                return me._parser["on" + ev]
+                            },
+                            set: function(h) {
+                                if (!h) {
+                                    me.removeAllListeners(ev)
+                                    return me._parser["on" + ev] = h
+                                }
+                                me.on(ev, h)
+                            },
+                            enumerable: true,
+                            configurable: false
+                        })
+                    })
+                }
+
+                SAXStream.prototype = Object.create(Stream.prototype, {
+                    constructor: {
+                        value: SAXStream
+                    }
+                })
+
+                SAXStream.prototype.write = function(data) {
+                    if (typeof Buffer === 'function' &&
+                        typeof Buffer.isBuffer === 'function' &&
+                        Buffer.isBuffer(data)) {
+                        if (!this._decoder) {
+                            var SD = require('string_decoder').StringDecoder
+                            this._decoder = new SD('utf8')
+                        }
+                        data = this._decoder.write(data);
+                    }
+
+                    this._parser.write(data.toString())
+                    this.emit("data", data)
+                    return true
+                }
+
+                SAXStream.prototype.end = function(chunk) {
+                    if (chunk && chunk.length) this.write(chunk)
+                    this._parser.end()
+                    return true
+                }
+
+                SAXStream.prototype.on = function(ev, handler) {
+                    var me = this
+                    if (!me._parser["on" + ev] && streamWraps.indexOf(ev) !== -1) {
+                        me._parser["on" + ev] = function() {
+                            var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)
+                            args.splice(0, 0, ev)
+                            me.emit.apply(me, args)
+                        }
+                    }
+
+                    return Stream.prototype.on.call(me, ev, handler)
+                }
+
+
+
+                // character classes and tokens
+                var whitespace = "\r\n\t "
+                    // this really needs to be replaced with character classes.
+                    // XML allows all manner of ridiculous numbers and digits.
+                    ,
+                    number = "0124356789",
+                    letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                    // (Letter | "_" | ":")
+                    ,
+                    quote = "'\"",
+                    entity = number + letter + "#",
+                    attribEnd = whitespace + ">",
+                    CDATA = "[CDATA[",
+                    DOCTYPE = "DOCTYPE",
+                    XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace",
+                    XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/",
+                    rootNS = {
+                        xml: XML_NAMESPACE,
+                        xmlns: XMLNS_NAMESPACE
+                    }
+
+                // turn all the string character sets into character class objects.
+                whitespace = charClass(whitespace)
+                number = charClass(number)
+                letter = charClass(letter)
+
+                // http://www.w3.org/TR/REC-xml/#NT-NameStartChar
+                // This implementation works on strings, a single character at a time
+                // as such, it cannot ever support astral-plane characters (10000-EFFFF)
+                // without a significant breaking change to either this parser, or the
+                // JavaScript language. Implementation of an emoji-capable xml parser
+                // is left as an exercise for the reader.
+                var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
+
+                var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/
+
+                quote = charClass(quote)
+                entity = charClass(entity)
+                attribEnd = charClass(attribEnd)
+
+                function charClass(str) {
+                    return str.split("").reduce(function(s, c) {
+                        s[c] = true
+                        return s
+                    }, {})
+                }
+
+                function isRegExp(c) {
+                    return Object.prototype.toString.call(c) === '[object RegExp]'
+                }
+
+                function is(charclass, c) {
+                    return isRegExp(charclass) ? !!c.match(charclass) : charclass[c]
+                }
+
+                function not(charclass, c) {
+                    return !is(charclass, c)
+                }
+
+                var S = 0
+                sax.STATE = {
+                    BEGIN: S++,
+                    TEXT: S++ // general stuff
+                        ,
+                    TEXT_ENTITY: S++ // &amp and such.
+                        ,
+                    OPEN_WAKA: S++ // <
+                        ,
+                    SGML_DECL: S++ // <!BLARG
+                        ,
+                    SGML_DECL_QUOTED: S++ // <!BLARG foo "bar
+                        ,
+                    DOCTYPE: S++ // <!DOCTYPE
+                        ,
+                    DOCTYPE_QUOTED: S++ // <!DOCTYPE "//blah
+                        ,
+                    DOCTYPE_DTD: S++ // <!DOCTYPE "//blah" [ ...
+                        ,
+                    DOCTYPE_DTD_QUOTED: S++ // <!DOCTYPE "//blah" [ "foo
+                        ,
+                    COMMENT_STARTING: S++ // <!-
+                        ,
+                    COMMENT: S++ // <!--
+                        ,
+                    COMMENT_ENDING: S++ // <!-- blah -
+                        ,
+                    COMMENT_ENDED: S++ // <!-- blah --
+                        ,
+                    CDATA: S++ // <![CDATA[ something
+                        ,
+                    CDATA_ENDING: S++ // ]
+                        ,
+                    CDATA_ENDING_2: S++ // ]]
+                        ,
+                    PROC_INST: S++ // <?hi
+                        ,
+                    PROC_INST_BODY: S++ // <?hi there
+                        ,
+                    PROC_INST_ENDING: S++ // <?hi "there" ?
+                        ,
+                    OPEN_TAG: S++ // <strong
+                        ,
+                    OPEN_TAG_SLASH: S++ // <strong /
+                        ,
+                    ATTRIB: S++ // <a
+                        ,
+                    ATTRIB_NAME: S++ // <a foo
+                        ,
+                    ATTRIB_NAME_SAW_WHITE: S++ // <a foo _
+                        ,
+                    ATTRIB_VALUE: S++ // <a foo=
+                        ,
+                    ATTRIB_VALUE_QUOTED: S++ // <a foo="bar
+                        ,
+                    ATTRIB_VALUE_CLOSED: S++ // <a foo="bar"
+                        ,
+                    ATTRIB_VALUE_UNQUOTED: S++ // <a foo=bar
+                        ,
+                    ATTRIB_VALUE_ENTITY_Q: S++ // <foo bar="&quot;"
+                        ,
+                    ATTRIB_VALUE_ENTITY_U: S++ // <foo bar=&quot;
+                        ,
+                    CLOSE_TAG: S++ // </a
+                        ,
+                    CLOSE_TAG_SAW_WHITE: S++ // </a >
+                        ,
+                    SCRIPT: S++ // <script> ...
+                        ,
+                    SCRIPT_ENDING: S++ // <script> ... <
+                }
+
+                sax.ENTITIES = {
+                    "amp": "&",
+                    "gt": ">",
+                    "lt": "<",
+                    "quot": "\"",
+                    "apos": "'",
+                    "AElig": 198,
+                    "Aacute": 193,
+                    "Acirc": 194,
+                    "Agrave": 192,
+                    "Aring": 197,
+                    "Atilde": 195,
+                    "Auml": 196,
+                    "Ccedil": 199,
+                    "ETH": 208,
+                    "Eacute": 201,
+                    "Ecirc": 202,
+                    "Egrave": 200,
+                    "Euml": 203,
+                    "Iacute": 205,
+                    "Icirc": 206,
+                    "Igrave": 204,
+                    "Iuml": 207,
+                    "Ntilde": 209,
+                    "Oacute": 211,
+                    "Ocirc": 212,
+                    "Ograve": 210,
+                    "Oslash": 216,
+                    "Otilde": 213,
+                    "Ouml": 214,
+                    "THORN": 222,
+                    "Uacute": 218,
+                    "Ucirc": 219,
+                    "Ugrave": 217,
+                    "Uuml": 220,
+                    "Yacute": 221,
+                    "aacute": 225,
+                    "acirc": 226,
+                    "aelig": 230,
+                    "agrave": 224,
+                    "aring": 229,
+                    "atilde": 227,
+                    "auml": 228,
+                    "ccedil": 231,
+                    "eacute": 233,
+                    "ecirc": 234,
+                    "egrave": 232,
+                    "eth": 240,
+                    "euml": 235,
+                    "iacute": 237,
+                    "icirc": 238,
+                    "igrave": 236,
+                    "iuml": 239,
+                    "ntilde": 241,
+                    "oacute": 243,
+                    "ocirc": 244,
+                    "ograve": 242,
+                    "oslash": 248,
+                    "otilde": 245,
+                    "ouml": 246,
+                    "szlig": 223,
+                    "thorn": 254,
+                    "uacute": 250,
+                    "ucirc": 251,
+                    "ugrave": 249,
+                    "uuml": 252,
+                    "yacute": 253,
+                    "yuml": 255,
+                    "copy": 169,
+                    "reg": 174,
+                    "nbsp": 160,
+                    "iexcl": 161,
+                    "cent": 162,
+                    "pound": 163,
+                    "curren": 164,
+                    "yen": 165,
+                    "brvbar": 166,
+                    "sect": 167,
+                    "uml": 168,
+                    "ordf": 170,
+                    "laquo": 171,
+                    "not": 172,
+                    "shy": 173,
+                    "macr": 175,
+                    "deg": 176,
+                    "plusmn": 177,
+                    "sup1": 185,
+                    "sup2": 178,
+                    "sup3": 179,
+                    "acute": 180,
+                    "micro": 181,
+                    "para": 182,
+                    "middot": 183,
+                    "cedil": 184,
+                    "ordm": 186,
+                    "raquo": 187,
+                    "frac14": 188,
+                    "frac12": 189,
+                    "frac34": 190,
+                    "iquest": 191,
+                    "times": 215,
+                    "divide": 247,
+                    "OElig": 338,
+                    "oelig": 339,
+                    "Scaron": 352,
+                    "scaron": 353,
+                    "Yuml": 376,
+                    "fnof": 402,
+                    "circ": 710,
+                    "tilde": 732,
+                    "Alpha": 913,
+                    "Beta": 914,
+                    "Gamma": 915,
+                    "Delta": 916,
+                    "Epsilon": 917,
+                    "Zeta": 918,
+                    "Eta": 919,
+                    "Theta": 920,
+                    "Iota": 921,
+                    "Kappa": 922,
+                    "Lambda": 923,
+                    "Mu": 924,
+                    "Nu": 925,
+                    "Xi": 926,
+                    "Omicron": 927,
+                    "Pi": 928,
+                    "Rho": 929,
+                    "Sigma": 931,
+                    "Tau": 932,
+                    "Upsilon": 933,
+                    "Phi": 934,
+                    "Chi": 935,
+                    "Psi": 936,
+                    "Omega": 937,
+                    "alpha": 945,
+                    "beta": 946,
+                    "gamma": 947,
+                    "delta": 948,
+                    "epsilon": 949,
+                    "zeta": 950,
+                    "eta": 951,
+                    "theta": 952,
+                    "iota": 953,
+                    "kappa": 954,
+                    "lambda": 955,
+                    "mu": 956,
+                    "nu": 957,
+                    "xi": 958,
+                    "omicron": 959,
+                    "pi": 960,
+                    "rho": 961,
+                    "sigmaf": 962,
+                    "sigma": 963,
+                    "tau": 964,
+                    "upsilon": 965,
+                    "phi": 966,
+                    "chi": 967,
+                    "psi": 968,
+                    "omega": 969,
+                    "thetasym": 977,
+                    "upsih": 978,
+                    "piv": 982,
+                    "ensp": 8194,
+                    "emsp": 8195,
+                    "thinsp": 8201,
+                    "zwnj": 8204,
+                    "zwj": 8205,
+                    "lrm": 8206,
+                    "rlm": 8207,
+                    "ndash": 8211,
+                    "mdash": 8212,
+                    "lsquo": 8216,
+                    "rsquo": 8217,
+                    "sbquo": 8218,
+                    "ldquo": 8220,
+                    "rdquo": 8221,
+                    "bdquo": 8222,
+                    "dagger": 8224,
+                    "Dagger": 8225,
+                    "bull": 8226,
+                    "hellip": 8230,
+                    "permil": 8240,
+                    "prime": 8242,
+                    "Prime": 8243,
+                    "lsaquo": 8249,
+                    "rsaquo": 8250,
+                    "oline": 8254,
+                    "frasl": 8260,
+                    "euro": 8364,
+                    "image": 8465,
+                    "weierp": 8472,
+                    "real": 8476,
+                    "trade": 8482,
+                    "alefsym": 8501,
+                    "larr": 8592,
+                    "uarr": 8593,
+                    "rarr": 8594,
+                    "darr": 8595,
+                    "harr": 8596,
+                    "crarr": 8629,
+                    "lArr": 8656,
+                    "uArr": 8657,
+                    "rArr": 8658,
+                    "dArr": 8659,
+                    "hArr": 8660,
+                    "forall": 8704,
+                    "part": 8706,
+                    "exist": 8707,
+                    "empty": 8709,
+                    "nabla": 8711,
+                    "isin": 8712,
+                    "notin": 8713,
+                    "ni": 8715,
+                    "prod": 8719,
+                    "sum": 8721,
+                    "minus": 8722,
+                    "lowast": 8727,
+                    "radic": 8730,
+                    "prop": 8733,
+                    "infin": 8734,
+                    "ang": 8736,
+                    "and": 8743,
+                    "or": 8744,
+                    "cap": 8745,
+                    "cup": 8746,
+                    "int": 8747,
+                    "there4": 8756,
+                    "sim": 8764,
+                    "cong": 8773,
+                    "asymp": 8776,
+                    "ne": 8800,
+                    "equiv": 8801,
+                    "le": 8804,
+                    "ge": 8805,
+                    "sub": 8834,
+                    "sup": 8835,
+                    "nsub": 8836,
+                    "sube": 8838,
+                    "supe": 8839,
+                    "oplus": 8853,
+                    "otimes": 8855,
+                    "perp": 8869,
+                    "sdot": 8901,
+                    "lceil": 8968,
+                    "rceil": 8969,
+                    "lfloor": 8970,
+                    "rfloor": 8971,
+                    "lang": 9001,
+                    "rang": 9002,
+                    "loz": 9674,
+                    "spades": 9824,
+                    "clubs": 9827,
+                    "hearts": 9829,
+                    "diams": 9830
+                }
+
+                Object.keys(sax.ENTITIES).forEach(function(key) {
+                    var e = sax.ENTITIES[key]
+                    var s = typeof e === 'number' ? String.fromCharCode(e) : e
+                    sax.ENTITIES[key] = s
+                })
+
+                for (var S in sax.STATE) sax.STATE[sax.STATE[S]] = S
+
+                // shorthand
+                S = sax.STATE
+
+                function emit(parser, event, data) {
+                    parser[event] && parser[event](data)
+                }
+
+                function emitNode(parser, nodeType, data) {
+                    if (parser.textNode) closeText(parser)
+                    emit(parser, nodeType, data)
+                }
+
+                function closeText(parser) {
+                    parser.textNode = textopts(parser.opt, parser.textNode)
+                    if (parser.textNode) emit(parser, "ontext", parser.textNode)
+                    parser.textNode = ""
+                }
+
+                function textopts(opt, text) {
+                    if (opt.trim) text = text.trim()
+                    if (opt.normalize) text = text.replace(/\s+/g, " ")
+                    return text
+                }
+
+                function error(parser, er) {
+                    closeText(parser)
+                    if (parser.trackPosition) {
+                        er += "\nLine: " + parser.line +
+                            "\nColumn: " + parser.column +
+                            "\nChar: " + parser.c
+                    }
+                    er = new Error(er)
+                    parser.error = er
+                    emit(parser, "onerror", er)
+                    return parser
+                }
+
+                function end(parser) {
+                    if (!parser.closedRoot) strictFail(parser, "Unclosed root tag")
+                    if ((parser.state !== S.BEGIN) && (parser.state !== S.TEXT)) error(parser, "Unexpected end")
+                    closeText(parser)
+                    parser.c = ""
+                    parser.closed = true
+                    emit(parser, "onend")
+                    SAXParser.call(parser, parser.strict, parser.opt)
+                    return parser
+                }
+
+                function strictFail(parser, message) {
+                    if (typeof parser !== 'object' || !(parser instanceof SAXParser))
+                        throw new Error('bad call to strictFail');
+                    if (parser.strict) error(parser, message)
+                }
+
+                function newTag(parser) {
+                    if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]()
+                    var parent = parser.tags[parser.tags.length - 1] || parser,
+                        tag = parser.tag = {
+                            name: parser.tagName,
+                            attributes: {}
+                        }
+
+                    // will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar"
+                    if (parser.opt.xmlns) tag.ns = parent.ns
+                    parser.attribList.length = 0
+                }
+
+                function qname(name, attribute) {
+                    var i = name.indexOf(":"),
+                        qualName = i < 0 ? ["", name] : name.split(":"),
+                        prefix = qualName[0],
+                        local = qualName[1]
+
+                    // <x "xmlns"="http://foo">
+                    if (attribute && name === "xmlns") {
+                        prefix = "xmlns"
+                        local = ""
+                    }
+
+                    return {
+                        prefix: prefix,
+                        local: local
+                    }
+                }
+
+                function attrib(parser) {
+                    if (!parser.strict) parser.attribName = parser.attribName[parser.looseCase]()
+
+                    if (parser.attribList.indexOf(parser.attribName) !== -1 ||
+                        parser.tag.attributes.hasOwnProperty(parser.attribName)) {
+                        return parser.attribName = parser.attribValue = ""
+                    }
+
+                    if (parser.opt.xmlns) {
+                        var qn = qname(parser.attribName, true),
+                            prefix = qn.prefix,
+                            local = qn.local
+
+                        if (prefix === "xmlns") {
+                            // namespace binding attribute; push the binding into scope
+                            if (local === "xml" && parser.attribValue !== XML_NAMESPACE) {
+                                strictFail(parser, "xml: prefix must be bound to " + XML_NAMESPACE + "\n" + "Actual: " + parser.attribValue)
+                            } else if (local === "xmlns" && parser.attribValue !== XMLNS_NAMESPACE) {
+                                strictFail(parser, "xmlns: prefix must be bound to " + XMLNS_NAMESPACE + "\n" + "Actual: " + parser.attribValue)
+                            } else {
+                                var tag = parser.tag,
+                                    parent = parser.tags[parser.tags.length - 1] || parser
+                                if (tag.ns === parent.ns) {
+                                    tag.ns = Object.create(parent.ns)
+                                }
+                                tag.ns[local] = parser.attribValue
+                            }
+                        }
+
+                        // defer onattribute events until all attributes have been seen
+                        // so any new bindings can take effect; preserve attribute order
+                        // so deferred events can be emitted in document order
+                        parser.attribList.push([parser.attribName, parser.attribValue])
+                    } else {
+                        // in non-xmlns mode, we can emit the event right away
+                        parser.tag.attributes[parser.attribName] = parser.attribValue
+                        emitNode(parser, "onattribute", {
+                            name: parser.attribName,
+                            value: parser.attribValue
+                        })
+                    }
+
+                    parser.attribName = parser.attribValue = ""
+                }
+
+                function openTag(parser, selfClosing) {
+                    if (parser.opt.xmlns) {
+                        // emit namespace binding events
+                        var tag = parser.tag
+
+                        // add namespace info to tag
+                        var qn = qname(parser.tagName)
+                        tag.prefix = qn.prefix
+                        tag.local = qn.local
+                        tag.uri = tag.ns[qn.prefix] || ""
+
+                        if (tag.prefix && !tag.uri) {
+                            strictFail(parser, "Unbound namespace prefix: " + JSON.stringify(parser.tagName))
+                            tag.uri = qn.prefix
+                        }
+
+                        var parent = parser.tags[parser.tags.length - 1] || parser
+                        if (tag.ns && parent.ns !== tag.ns) {
+                            Object.keys(tag.ns).forEach(function(p) {
+                                emitNode(parser, "onopennamespace", {
+                                    prefix: p,
+                                    uri: tag.ns[p]
+                                })
+                            })
+                        }
+
+                        // handle deferred onattribute events
+                        // Note: do not apply default ns to attributes:
+                        // http://www.w3.org/TR/REC-xml-names/#defaulting
+                        for (var i = 0, l = parser.attribList.length; i < l; i++) {
+                            var nv = parser.attribList[i]
+                            var name = nv[0],
+                                value = nv[1],
+                                qualName = qname(name, true),
+                                prefix = qualName.prefix,
+                                local = qualName.local,
+                                uri = prefix == "" ? "" : (tag.ns[prefix] || ""),
+                                a = {
+                                    name: name,
+                                    value: value,
+                                    prefix: prefix,
+                                    local: local,
+                                    uri: uri
+                                }
+
+                            // if there's any attributes with an undefined namespace,
+                            // then fail on them now.
+                            if (prefix && prefix != "xmlns" && !uri) {
+                                strictFail(parser, "Unbound namespace prefix: " + JSON.stringify(prefix))
+                                a.uri = prefix
+                            }
+                            parser.tag.attributes[name] = a
+                            emitNode(parser, "onattribute", a)
+                        }
+                        parser.attribList.length = 0
+                    }
+
+                    parser.tag.isSelfClosing = !!selfClosing
+
+                    // process the tag
+                    parser.sawRoot = true
+                    parser.tags.push(parser.tag)
+                    emitNode(parser, "onopentag", parser.tag)
+                    if (!selfClosing) {
+                        // special case for <script> in non-strict mode.
+                        if (!parser.noscript && parser.tagName.toLowerCase() === "script") {
+                            parser.state = S.SCRIPT
+                        } else {
+                            parser.state = S.TEXT
+                        }
+                        parser.tag = null
+                        parser.tagName = ""
+                    }
+                    parser.attribName = parser.attribValue = ""
+                    parser.attribList.length = 0
+                }
+
+                function closeTag(parser) {
+                    if (!parser.tagName) {
+                        strictFail(parser, "Weird empty close tag.")
+                        parser.textNode += "</>"
+                        parser.state = S.TEXT
+                        return
+                    }
+
+                    if (parser.script) {
+                        if (parser.tagName !== "script") {
+                            parser.script += "</" + parser.tagName + ">"
+                            parser.tagName = ""
+                            parser.state = S.SCRIPT
+                            return
+                        }
+                        emitNode(parser, "onscript", parser.script)
+                        parser.script = ""
+                    }
+
+                    // first make sure that the closing tag actually exists.
+                    // <a><b></c></b></a> will close everything, otherwise.
+                    var t = parser.tags.length
+                    var tagName = parser.tagName
+                    if (!parser.strict) tagName = tagName[parser.looseCase]()
+                    var closeTo = tagName
+                    while (t--) {
+                        var close = parser.tags[t]
+                        if (close.name !== closeTo) {
+                            // fail the first time in strict mode
+                            strictFail(parser, "Unexpected close tag")
+                        } else break
+                    }
+
+                    // didn't find it. we already failed for strict, so just abort.
+                    if (t < 0) {
+                        strictFail(parser, "Unmatched closing tag: " + parser.tagName)
+                        parser.textNode += "</" + parser.tagName + ">"
+                        parser.state = S.TEXT
+                        return
+                    }
+                    parser.tagName = tagName
+                    var s = parser.tags.length
+                    while (s-- > t) {
+                        var tag = parser.tag = parser.tags.pop()
+                        parser.tagName = parser.tag.name
+                        emitNode(parser, "onclosetag", parser.tagName)
+
+                        var x = {}
+                        for (var i in tag.ns) x[i] = tag.ns[i]
+
+                        var parent = parser.tags[parser.tags.length - 1] || parser
+                        if (parser.opt.xmlns && tag.ns !== parent.ns) {
+                            // remove namespace bindings introduced by tag
+                            Object.keys(tag.ns).forEach(function(p) {
+                                var n = tag.ns[p]
+                                emitNode(parser, "onclosenamespace", {
+                                    prefix: p,
+                                    uri: n
+                                })
+                            })
+                        }
+                    }
+                    if (t === 0) parser.closedRoot = true
+                    parser.tagName = parser.attribValue = parser.attribName = ""
+                    parser.attribList.length = 0
+                    parser.state = S.TEXT
+                }
+
+                function parseEntity(parser) {
+                    var entity = parser.entity,
+                        entityLC = entity.toLowerCase(),
+                        num, numStr = ""
+                    if (parser.ENTITIES[entity])
+                        return parser.ENTITIES[entity]
+                    if (parser.ENTITIES[entityLC])
+                        return parser.ENTITIES[entityLC]
+                    entity = entityLC
+                    if (entity.charAt(0) === "#") {
+                        if (entity.charAt(1) === "x") {
+                            entity = entity.slice(2)
+                            num = parseInt(entity, 16)
+                            numStr = num.toString(16)
+                        } else {
+                            entity = entity.slice(1)
+                            num = parseInt(entity, 10)
+                            numStr = num.toString(10)
+                        }
+                    }
+                    entity = entity.replace(/^0+/, "")
+                    if (numStr.toLowerCase() !== entity) {
+                        strictFail(parser, "Invalid character entity")
+                        return "&" + parser.entity + ";"
+                    }
+
+                    return String.fromCodePoint(num)
+                }
+
+                function write(chunk) {
+                    var parser = this
+                    if (this.error) throw this.error
+                    if (parser.closed) return error(parser,
+                        "Cannot write after close. Assign an onready handler.")
+                    if (chunk === null) return end(parser)
+                    var i = 0,
+                        c = ""
+                    while (parser.c = c = chunk.charAt(i++)) {
+                        if (parser.trackPosition) {
+                            parser.position++
+                                if (c === "\n") {
+                                    parser.line++
+                                        parser.column = 0
+                                } else parser.column++
+                        }
+                        switch (parser.state) {
+
+                            case S.BEGIN:
+                                if (c === "<") {
+                                    parser.state = S.OPEN_WAKA
+                                    parser.startTagPosition = parser.position
+                                } else if (not(whitespace, c)) {
+                                    // have to process this as a text node.
+                                    // weird, but happens.
+                                    strictFail(parser, "Non-whitespace before first tag.")
+                                    parser.textNode = c
+                                    parser.state = S.TEXT
+                                }
+                                continue
+
+                            case S.TEXT:
+                                if (parser.sawRoot && !parser.closedRoot) {
+                                    var starti = i - 1
+                                    while (c && c !== "<" && c !== "&") {
+                                        c = chunk.charAt(i++)
+                                        if (c && parser.trackPosition) {
+                                            parser.position++
+                                                if (c === "\n") {
+                                                    parser.line++
+                                                        parser.column = 0
+                                                } else parser.column++
+                                        }
+                                    }
+                                    parser.textNode += chunk.substring(starti, i - 1)
+                                }
+                                if (c === "<") {
+                                    parser.state = S.OPEN_WAKA
+                                    parser.startTagPosition = parser.position
+                                } else {
+                                    if (not(whitespace, c) && (!parser.sawRoot || parser.closedRoot))
+                                        strictFail(parser, "Text data outside of root node.")
+                                    if (c === "&") parser.state = S.TEXT_ENTITY
+                                    else parser.textNode += c
+                                }
+                                continue
+
+                            case S.SCRIPT:
+                                // only non-strict
+                                if (c === "<") {
+                                    parser.state = S.SCRIPT_ENDING
+                                } else parser.script += c
+                                continue
+
+                            case S.SCRIPT_ENDING:
+                                if (c === "/") {
+                                    parser.state = S.CLOSE_TAG
+                                } else {
+                                    parser.script += "<" + c
+                                    parser.state = S.SCRIPT
+                                }
+                                continue
+
+                            case S.OPEN_WAKA:
+                                // either a /, ?, !, or text is coming next.
+                                if (c === "!") {
+                                    parser.state = S.SGML_DECL
+                                    parser.sgmlDecl = ""
+                                } else if (is(whitespace, c)) {
+                                    // wait for it...
+                                } else if (is(nameStart, c)) {
+                                    parser.state = S.OPEN_TAG
+                                    parser.tagName = c
+                                } else if (c === "/") {
+                                    parser.state = S.CLOSE_TAG
+                                    parser.tagName = ""
+                                } else if (c === "?") {
+                                    parser.state = S.PROC_INST
+                                    parser.procInstName = parser.procInstBody = ""
+                                } else {
+                                    strictFail(parser, "Unencoded <")
+                                        // if there was some whitespace, then add that in.
+                                    if (parser.startTagPosition + 1 < parser.position) {
+                                        var pad = parser.position - parser.startTagPosition
+                                        c = new Array(pad).join(" ") + c
+                                    }
+                                    parser.textNode += "<" + c
+                                    parser.state = S.TEXT
+                                }
+                                continue
+
+                            case S.SGML_DECL:
+                                if ((parser.sgmlDecl + c).toUpperCase() === CDATA) {
+                                    emitNode(parser, "onopencdata")
+                                    parser.state = S.CDATA
+                                    parser.sgmlDecl = ""
+                                    parser.cdata = ""
+                                } else if (parser.sgmlDecl + c === "--") {
+                                    parser.state = S.COMMENT
+                                    parser.comment = ""
+                                    parser.sgmlDecl = ""
+                                } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) {
+                                    parser.state = S.DOCTYPE
+                                    if (parser.doctype || parser.sawRoot) strictFail(parser,
+                                        "Inappropriately located doctype declaration")
+                                    parser.doctype = ""
+                                    parser.sgmlDecl = ""
+                                } else if (c === ">") {
+                                    emitNode(parser, "onsgmldeclaration", parser.sgmlDecl)
+                                    parser.sgmlDecl = ""
+                                    parser.state = S.TEXT
+                                } else if (is(quote, c)) {
+                                    parser.state = S.SGML_DECL_QUOTED
+                                    parser.sgmlDecl += c
+                                } else parser.sgmlDecl += c
+                                continue
+
+                            case S.SGML_DECL_QUOTED:
+                                if (c === parser.q) {
+                                    parser.state = S.SGML_DECL
+                                    parser.q = ""
+                                }
+                                parser.sgmlDecl += c
+                                continue
+
+                            case S.DOCTYPE:
+                                if (c === ">") {
+                                    parser.state = S.TEXT
+                                    emitNode(parser, "ondoctype", parser.doctype)
+                                    parser.doctype = true // just remember that we saw it.
+                                } else {
+                                    parser.doctype += c
+                                    if (c === "[") parser.state = S.DOCTYPE_DTD
+                                    else if (is(quote, c)) {
+                                        parser.state = S.DOCTYPE_QUOTED
+                                        parser.q = c
+                                    }
+                                }
+                                continue
+
+                            case S.DOCTYPE_QUOTED:
+                                parser.doctype += c
+                                if (c === parser.q) {
+                                    parser.q = ""
+                                    parser.state = S.DOCTYPE
+                                }
+                                continue
+
+                            case S.DOCTYPE_DTD:
+                                parser.doctype += c
+                                if (c === "]") parser.state = S.DOCTYPE
+                                else if (is(quote, c)) {
+                                    parser.state = S.DOCTYPE_DTD_QUOTED
+                                    parser.q = c
+                                }
+                                continue
+
+                            case S.DOCTYPE_DTD_QUOTED:
+                                parser.doctype += c
+                                if (c === parser.q) {
+                                    parser.state = S.DOCTYPE_DTD
+                                    parser.q = ""
+                                }
+                                continue
+
+                            case S.COMMENT:
+                                if (c === "-") parser.state = S.COMMENT_ENDING
+                                else parser.comment += c
+                                continue
+
+                            case S.COMMENT_ENDING:
+                                if (c === "-") {
+                                    parser.state = S.COMMENT_ENDED
+                                    parser.comment = textopts(parser.opt, parser.comment)
+                                    if (parser.comment) emitNode(parser, "oncomment", parser.comment)
+                                    parser.comment = ""
+                                } else {
+                                    parser.comment += "-" + c
+                                    parser.state = S.COMMENT
+                                }
+                                continue
+
+                            case S.COMMENT_ENDED:
+                                if (c !== ">") {
+                                    strictFail(parser, "Malformed comment")
+                                        // allow <!-- blah -- bloo --> in non-strict mode,
+                                        // which is a comment of " blah -- bloo "
+                                    parser.comment += "--" + c
+                                    parser.state = S.COMMENT
+                                } else parser.state = S.TEXT
+                                continue
+
+                            case S.CDATA:
+                                if (c === "]") parser.state = S.CDATA_ENDING
+                                else parser.cdata += c
+                                continue
+
+                            case S.CDATA_ENDING:
+                                if (c === "]") parser.state = S.CDATA_ENDING_2
+                                else {
+                                    parser.cdata += "]" + c
+                                    parser.state = S.CDATA
+                                }
+                                continue
+
+                            case S.CDATA_ENDING_2:
+                                if (c === ">") {
+                                    if (parser.cdata) emitNode(parser, "oncdata", parser.cdata)
+                                    emitNode(parser, "onclosecdata")
+                                    parser.cdata = ""
+                                    parser.state = S.TEXT
+                                } else if (c === "]") {
+                                    parser.cdata += "]"
+                                } else {
+                                    parser.cdata += "]]" + c
+                                    parser.state = S.CDATA
+                                }
+                                continue
+
+                            case S.PROC_INST:
+                                if (c === "?") parser.state = S.PROC_INST_ENDING
+                                else if (is(whitespace, c)) parser.state = S.PROC_INST_BODY
+                                else parser.procInstName += c
+                                continue
+
+                            case S.PROC_INST_BODY:
+                                if (!parser.procInstBody && is(whitespace, c)) continue
+                                else if (c === "?") parser.state = S.PROC_INST_ENDING
+                                else parser.procInstBody += c
+                                continue
+
+                            case S.PROC_INST_ENDING:
+                                if (c === ">") {
+                                    emitNode(parser, "onprocessinginstruction", {
+                                        name: parser.procInstName,
+                                        body: parser.procInstBody
+                                    })
+                                    parser.procInstName = parser.procInstBody = ""
+                                    parser.state = S.TEXT
+                                } else {
+                                    parser.procInstBody += "?" + c
+                                    parser.state = S.PROC_INST_BODY
+                                }
+                                continue
+
+                            case S.OPEN_TAG:
+                                if (is(nameBody, c)) parser.tagName += c
+                                else {
+                                    newTag(parser)
+                                    if (c === ">") openTag(parser)
+                                    else if (c === "/") parser.state = S.OPEN_TAG_SLASH
+                                    else {
+                                        if (not(whitespace, c)) strictFail(
+                                            parser, "Invalid character in tag name")
+                                        parser.state = S.ATTRIB
+                                    }
+                                }
+                                continue
+
+                            case S.OPEN_TAG_SLASH:
+                                if (c === ">") {
+                                    openTag(parser, true)
+                                    closeTag(parser)
+                                } else {
+                                    strictFail(parser, "Forward-slash in opening tag not followed by >")
+                                    parser.state = S.ATTRIB
+                                }
+                                continue
+
+                            case S.ATTRIB:
+                                // haven't read the attribute name yet.
+                                if (is(whitespace, c)) continue
+                                else if (c === ">") openTag(parser)
+                                else if (c === "/") parser.state = S.OPEN_TAG_SLASH
+                                else if (is(nameStart, c)) {
+                                    parser.attribName = c
+                                    parser.attribValue = ""
+                                    parser.state = S.ATTRIB_NAME
+                                } else strictFail(parser, "Invalid attribute name")
+                                continue
+
+                            case S.ATTRIB_NAME:
+                                if (c === "=") parser.state = S.ATTRIB_VALUE
+                                else if (c === ">") {
+                                    strictFail(parser, "Attribute without value")
+                                    parser.attribValue = parser.attribName
+                                    attrib(parser)
+                                    openTag(parser)
+                                } else if (is(whitespace, c)) parser.state = S.ATTRIB_NAME_SAW_WHITE
+                                else if (is(nameBody, c)) parser.attribName += c
+                                else strictFail(parser, "Invalid attribute name")
+                                continue
+
+                            case S.ATTRIB_NAME_SAW_WHITE:
+                                if (c === "=") parser.state = S.ATTRIB_VALUE
+                                else if (is(whitespace, c)) continue
+                                else {
+                                    strictFail(parser, "Attribute without value")
+                                    parser.tag.attributes[parser.attribName] = ""
+                                    parser.attribValue = ""
+                                    emitNode(parser, "onattribute", {
+                                        name: parser.attribName,
+                                        value: ""
+                                    })
+                                    parser.attribName = ""
+                                    if (c === ">") openTag(parser)
+                                    else if (is(nameStart, c)) {
+                                        parser.attribName = c
+                                        parser.state = S.ATTRIB_NAME
+                                    } else {
+                                        strictFail(parser, "Invalid attribute name")
+                                        parser.state = S.ATTRIB
+                                    }
+                                }
+                                continue
+
+                            case S.ATTRIB_VALUE:
+                                if (is(whitespace, c)) continue
+                                else if (is(quote, c)) {
+                                    parser.q = c
+                                    parser.state = S.ATTRIB_VALUE_QUOTED
+                                } else {
+                                    strictFail(parser, "Unquoted attribute value")
+                                    parser.state = S.ATTRIB_VALUE_UNQUOTED
+                                    parser.attribValue = c
+                                }
+                                continue
+
+                            case S.ATTRIB_VALUE_QUOTED:
+                                if (c !== parser.q) {
+                                    if (c === "&") parser.state = S.ATTRIB_VALUE_ENTITY_Q
+                                    else parser.attribValue += c
+                                    continue
+                                }
+                                attrib(parser)
+                                parser.q = ""
+                                parser.state = S.ATTRIB_VALUE_CLOSED
+                                continue
+
+                            case S.ATTRIB_VALUE_CLOSED:
+                                if (is(whitespace, c)) {
+                                    parser.state = S.ATTRIB
+                                } else if (c === ">") openTag(parser)
+                                else if (c === "/") parser.state = S.OPEN_TAG_SLASH
+                                else if (is(nameStart, c)) {
+                                    strictFail(parser, "No whitespace between attributes")
+                                    parser.attribName = c
+                                    parser.attribValue = ""
+                                    parser.state = S.ATTRIB_NAME
+                                } else strictFail(parser, "Invalid attribute name")
+                                continue
+
+                            case S.ATTRIB_VALUE_UNQUOTED:
+                                if (not(attribEnd, c)) {
+                                    if (c === "&") parser.state = S.ATTRIB_VALUE_ENTITY_U
+                                    else parser.attribValue += c
+                                    continue
+                                }
+                                attrib(parser)
+                                if (c === ">") openTag(parser)
+                                else parser.state = S.ATTRIB
+                                continue
+
+                            case S.CLOSE_TAG:
+                                if (!parser.tagName) {
+                                    if (is(whitespace, c)) continue
+                                    else if (not(nameStart, c)) {
+                                        if (parser.script) {
+                                            parser.script += "</" + c
+                                            parser.state = S.SCRIPT
+                                        } else {
+                                            strictFail(parser, "Invalid tagname in closing tag.")
+                                        }
+                                    } else parser.tagName = c
+                                } else if (c === ">") closeTag(parser)
+                                else if (is(nameBody, c)) parser.tagName += c
+                                else if (parser.script) {
+                                    parser.script += "</" + parser.tagName
+                                    parser.tagName = ""
+                                    parser.state = S.SCRIPT
+                                } else {
+                                    if (not(whitespace, c)) strictFail(parser,
+                                        "Invalid tagname in closing tag")
+                                    parser.state = S.CLOSE_TAG_SAW_WHITE
+                                }
+                                continue
+
+                            case S.CLOSE_TAG_SAW_WHITE:
+                                if (is(whitespace, c)) continue
+                                if (c === ">") closeTag(parser)
+                                else strictFail(parser, "Invalid characters in closing tag")
+                                continue
+
+                            case S.TEXT_ENTITY:
+                            case S.ATTRIB_VALUE_ENTITY_Q:
+                            case S.ATTRIB_VALUE_ENTITY_U:
+                                switch (parser.state) {
+                                    case S.TEXT_ENTITY:
+                                        var returnState = S.TEXT,
+                                            buffer = "textNode"
+                                        break
+
+                                    case S.ATTRIB_VALUE_ENTITY_Q:
+                                        var returnState = S.ATTRIB_VALUE_QUOTED,
+                                            buffer = "attribValue"
+                                        break
+
+                                    case S.ATTRIB_VALUE_ENTITY_U:
+                                        var returnState = S.ATTRIB_VALUE_UNQUOTED,
+                                            buffer = "attribValue"
+                                        break
+                                }
+                                if (c === ";") {
+                                    parser[buffer] += parseEntity(parser)
+                                    parser.entity = ""
+                                    parser.state = returnState
+                                } else if (is(entity, c)) parser.entity += c
+                                else {
+                                    strictFail(parser, "Invalid character entity")
+                                    parser[buffer] += "&" + parser.entity + c
+                                    parser.entity = ""
+                                    parser.state = returnState
+                                }
+                                continue
+
+                            default:
+                                throw new Error(parser, "Unknown state: " + parser.state)
+                        }
+                    } // while
+                    // cdata blocks can get very big under normal conditions. emit and move on.
+                    // if (parser.state === S.CDATA && parser.cdata) {
+                    // emitNode(parser, "oncdata", parser.cdata)
+                    // parser.cdata = ""
+                    // }
+                    if (parser.position >= parser.bufferCheckPosition) checkBufferLength(parser)
+                    return parser
+                }
+
+                /* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
+                if (!String.fromCodePoint) {
+                    (function() {
+                        var stringFromCharCode = String.fromCharCode;
+                        var floor = Math.floor;
+                        var fromCodePoint = function() {
+                            var MAX_SIZE = 0x4000;
+                            var codeUnits = [];
+                            var highSurrogate;
+                            var lowSurrogate;
+                            var index = -1;
+                            var length = arguments.length;
+                            if (!length) {
+                                return '';
+                            }
+                            var result = '';
+                            while (++index < length) {
+                                var codePoint = Number(arguments[index]);
+                                if (!isFinite(codePoint) || // `NaN`,
+                                    // `+Infinity`,
+                                    // or
+                                    // `-Infinity`
+                                    codePoint < 0 || // not a valid
+                                    // Unicode code
+                                    // point
+                                    codePoint > 0x10FFFF || // not a valid
+                                    // Unicode code
+                                    // point
+                                    floor(codePoint) != codePoint // not
+                                    // an
+                                    // integer
+                                ) {
+                                    throw RangeError('Invalid code point: ' + codePoint);
+                                }
+                                if (codePoint <= 0xFFFF) { // BMP code point
+                                    codeUnits.push(codePoint);
+                                } else { // Astral code point; split in
+                                    // surrogate halves
+                                    // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+                                    codePoint -= 0x10000;
+                                    highSurrogate = (codePoint >> 10) + 0xD800;
+                                    lowSurrogate = (codePoint % 0x400) + 0xDC00;
+                                    codeUnits.push(highSurrogate, lowSurrogate);
+                                }
+                                if (index + 1 == length || codeUnits.length > MAX_SIZE) {
+                                    result += stringFromCharCode.apply(null, codeUnits);
+                                    codeUnits.length = 0;
+                                }
+                            }
+                            return result;
+                        };
+                        if (Object.defineProperty) {
+                            Object.defineProperty(String, 'fromCodePoint', {
+                                'value': fromCodePoint,
+                                'configurable': true,
+                                'writable': true
+                            });
+                        } else {
+                            String.fromCodePoint = fromCodePoint;
+                        }
+                    }());
+                }
+
+            })(typeof exports === "undefined" ? sax = {} : exports);
+
+        }).call(this, undefined)
+    }, {
+        "stream": false,
+        "string_decoder": false
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle-xml\\node_modules\\tiny-stack\\lib\\tiny-stack.js": [function(require, module, exports) {
+        /**
+         * Tiny stack for browser or server
+         * 
+         * @author Jason Mulligan <jason.mulligan@avoidwork.com>
+         * @copyright 2014 Jason Mulligan
+         * @license BSD-3 <https://raw.github.com/avoidwork/tiny-stack/master/LICENSE>
+         * @link http://avoidwork.github.io/tiny-stack
+         * @module tiny-stack
+         * @version 0.1.0
+         */
+
+        (function(global) {
+
+            "use strict";
+
+            /**
+             * TinyStack
+             * 
+             * @constructor
+             */
+            function TinyStack() {
+                this.data = [null];
+                this.top = 0;
+            }
+
+            /**
+             * Clears the stack
+             * 
+             * @method clear
+             * @memberOf TinyStack
+             * @return {Object} {@link TinyStack}
+             */
+            TinyStack.prototype.clear = function clear() {
+                this.data = [null];
+                this.top = 0;
+
+                return this;
+            };
+
+            /**
+             * Gets the size of the stack
+             * 
+             * @method length
+             * @memberOf TinyStack
+             * @return {Number} Size of stack
+             */
+            TinyStack.prototype.length = function length() {
+                return this.top;
+            };
+
+            /**
+             * Gets the item at the top of the stack
+             * 
+             * @method peek
+             * @memberOf TinyStack
+             * @return {Mixed} Item at the top of the stack
+             */
+            TinyStack.prototype.peek = function peek() {
+                return this.data[this.top];
+            };
+
+            /**
+             * Gets & removes the item at the top of the stack
+             * 
+             * @method pop
+             * @memberOf TinyStack
+             * @return {Mixed} Item at the top of the stack
+             */
+            TinyStack.prototype.pop = function pop() {
+                if (this.top > 0) {
+                    this.top--;
+
+                    return this.data.pop();
+                } else {
+                    return undefined;
+                }
+            };
+
+            /**
+             * Pushes an item onto the stack
+             * 
+             * @method push
+             * @memberOf TinyStack
+             * @return {Object} {@link TinyStack}
+             */
+            TinyStack.prototype.push = function push(arg) {
+                this.data[++this.top] = arg;
+
+                return this;
+            };
+
+            /**
+             * TinyStack factory
+             * 
+             * @method factory
+             * @return {Object} {@link TinyStack}
+             */
+            function factory() {
+                return new TinyStack();
+            }
+
+            // Node, AMD & window supported
+            if (typeof exports != "undefined") {
+                module.exports = factory;
+            } else if (typeof define == "function") {
+                define(function() {
+                    return factory;
+                });
+            } else {
+                global.stack = factory;
+            }
+        })(this);
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\index.js": [function(require, module, exports) {
+        module.exports = require('./lib/moddle');
+    }, {
+        "./lib/moddle": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\moddle.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\base.js": [function(require, module, exports) {
+        'use strict';
+
+        function Base() {}
+
+        Base.prototype.get = function(name) {
+            return this.$model.properties.get(this, name);
+        };
+
+        Base.prototype.set = function(name, value) {
+            this.$model.properties.set(this, name, value);
+        };
+
+
+        module.exports = Base;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\descriptor-builder.js": [function(require, module, exports) {
+        'use strict';
+
+        var pick = require('lodash/object/pick'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+        var parseNameNs = require('./ns').parseName;
+
+
+        function DescriptorBuilder(nameNs) {
+            this.ns = nameNs;
+            this.name = nameNs.name;
+            this.allTypes = [];
+            this.properties = [];
+            this.propertiesByName = {};
+        }
+
+        module.exports = DescriptorBuilder;
+
+
+        DescriptorBuilder.prototype.build = function() {
+            return pick(this, ['ns', 'name', 'allTypes', 'properties', 'propertiesByName', 'bodyProperty']);
+        };
+
+        DescriptorBuilder.prototype.addProperty = function(p, idx) {
+            this.addNamedProperty(p, true);
+
+            var properties = this.properties;
+
+            if (idx !== undefined) {
+                properties.splice(idx, 0, p);
+            } else {
+                properties.push(p);
+            }
+        };
+
+
+        DescriptorBuilder.prototype.replaceProperty = function(oldProperty, newProperty) {
+            var oldNameNs = oldProperty.ns;
+
+            var props = this.properties,
+                propertiesByName = this.propertiesByName,
+                rename = oldProperty.name !== newProperty.name;
+
+            if (oldProperty.isBody) {
+
+                if (!newProperty.isBody) {
+                    throw new Error(
+                        'property <' + newProperty.ns.name + '> must be body property ' +
+                        'to refine <' + oldProperty.ns.name + '>');
+                }
+
+                // TODO: Check compatibility
+                this.setBodyProperty(newProperty, false);
+            }
+
+            // replacing the named property is intentional
+            // thus, validate only if this is a "rename" operation
+            this.addNamedProperty(newProperty, rename);
+
+            // replace old property at index with new one
+            var idx = props.indexOf(oldProperty);
+            if (idx === -1) {
+                throw new Error('property <' + oldNameNs.name + '> not found in property list');
+            }
+
+            props[idx] = newProperty;
+
+            // replace propertiesByName entry with new property
+            propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty;
+        };
+
+
+        DescriptorBuilder.prototype.redefineProperty = function(p) {
+
+            var nsPrefix = p.ns.prefix;
+            var parts = p.redefines.split('#');
+
+            var name = parseNameNs(parts[0], nsPrefix);
+            var attrName = parseNameNs(parts[1], name.prefix).name;
+
+            var redefinedProperty = this.propertiesByName[attrName];
+            if (!redefinedProperty) {
+                throw new Error('refined property <' + attrName + '> not found');
+            } else {
+                this.replaceProperty(redefinedProperty, p);
+            }
+
+            delete p.redefines;
+        };
+
+        DescriptorBuilder.prototype.addNamedProperty = function(p, validate) {
+            var ns = p.ns,
+                propsByName = this.propertiesByName;
+
+            if (validate) {
+                this.assertNotDefined(p, ns.name);
+                this.assertNotDefined(p, ns.localName);
+            }
+
+            propsByName[ns.name] = propsByName[ns.localName] = p;
+        };
+
+        DescriptorBuilder.prototype.removeNamedProperty = function(p) {
+            var ns = p.ns,
+                propsByName = this.propertiesByName;
+
+            delete propsByName[ns.name];
+            delete propsByName[ns.localName];
+        };
+
+        DescriptorBuilder.prototype.setBodyProperty = function(p, validate) {
+
+            if (validate && this.bodyProperty) {
+                throw new Error(
+                    'body property defined multiple times ' +
+                    '(<' + this.bodyProperty.ns.name + '>, <' + p.ns.name + '>)');
+            }
+
+            this.bodyProperty = p;
+        };
+
+        DescriptorBuilder.prototype.addIdProperty = function(name) {
+            var nameNs = parseNameNs(name, this.ns.prefix);
+
+            var p = {
+                name: nameNs.localName,
+                type: 'String',
+                isAttr: true,
+                ns: nameNs
+            };
+
+            // ensure that id is always the first attribute (if present)
+            this.addProperty(p, 0);
+        };
+
+        DescriptorBuilder.prototype.assertNotDefined = function(p, name) {
+            var propertyName = p.name,
+                definedProperty = this.propertiesByName[propertyName];
+
+            if (definedProperty) {
+                throw new Error(
+                    'property <' + propertyName + '> already defined; ' +
+                    'override of <' + definedProperty.definedBy.ns.name + '#' + definedProperty.ns.name + '> by ' +
+                    '<' + p.definedBy.ns.name + '#' + p.ns.name + '> not allowed without redefines');
+            }
+        };
+
+        DescriptorBuilder.prototype.hasProperty = function(name) {
+            return this.propertiesByName[name];
+        };
+
+        DescriptorBuilder.prototype.addTrait = function(t) {
+
+            var allTypes = this.allTypes;
+
+            if (allTypes.indexOf(t) !== -1) {
+                return;
+            }
+
+            forEach(t.properties, function(p) {
+
+                // clone property to allow extensions
+                p = assign({}, p, {
+                    name: p.ns.localName
+                });
+
+                Object.defineProperty(p, 'definedBy', {
+                    value: t
+                });
+
+                // add redefine support
+                if (p.redefines) {
+                    this.redefineProperty(p);
+                } else {
+                    if (p.isBody) {
+                        this.setBodyProperty(p);
+                    }
+                    this.addProperty(p);
+                }
+            }, this);
+
+            allTypes.push(t);
+        };
+
+    }, {
+        "./ns": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/pick": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\factory.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var Base = require('./base');
+
+
+        function Factory(model, properties) {
+            this.model = model;
+            this.properties = properties;
+        }
+
+        module.exports = Factory;
+
+
+        Factory.prototype.createType = function(descriptor) {
+
+            var model = this.model;
+
+            var props = this.properties,
+                prototype = Object.create(Base.prototype);
+
+            // initialize default values
+            forEach(descriptor.properties, function(p) {
+                if (!p.isMany && p.default !== undefined) {
+                    prototype[p.name] = p.default;
+                }
+            });
+
+            props.defineModel(prototype, model);
+            props.defineDescriptor(prototype, descriptor);
+
+            var name = descriptor.ns.name;
+
+            /**
+             * The new type constructor
+             */
+            function ModdleElement(attrs) {
+                props.define(this, '$type', {
+                    value: name,
+                    enumerable: true
+                });
+                props.define(this, '$attrs', {
+                    value: {}
+                });
+                props.define(this, '$parent', {
+                    writable: true
+                });
+
+                forEach(attrs, function(val, key) {
+                    this.set(key, val);
+                }, this);
+            }
+
+            ModdleElement.prototype = prototype;
+
+            ModdleElement.hasType = prototype.$instanceOf = this.model.hasType;
+
+            // static links
+            props.defineModel(ModdleElement, model);
+            props.defineDescriptor(ModdleElement, descriptor);
+
+            return ModdleElement;
+        };
+    }, {
+        "./base": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\base.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\moddle.js": [function(require, module, exports) {
+        'use strict';
+
+        var isString = require('lodash/lang/isString'),
+            isObject = require('lodash/lang/isObject'),
+            forEach = require('lodash/collection/forEach'),
+            find = require('lodash/collection/find');
+
+
+        var Factory = require('./factory'),
+            Registry = require('./registry'),
+            Properties = require('./properties');
+
+        var parseNameNs = require('./ns').parseName;
+
+
+        // // Moddle implementation /////////////////////////////////////////////////
+
+        /**
+         * @class Moddle
+         * 
+         * A model that can be used to create elements of a specific type.
+         * 
+         * @example
+         * 
+         * var Moddle = require('moddle');
+         * 
+         * var pkg = { name: 'mypackage', prefix: 'my', types: [ { name: 'Root' } ] };
+         * 
+         * var moddle = new Moddle([pkg]);
+         * 
+         * @param {Array
+         *            <Package>} packages the packages to contain
+         * @param {Object}
+         *            options additional options to pass to the model
+         */
+        function Moddle(packages, options) {
+
+            options = options || {};
+
+            this.properties = new Properties(this);
+
+            this.factory = new Factory(this, this.properties);
+            this.registry = new Registry(packages, this.properties, options);
+
+            this.typeCache = {};
+        }
+
+        module.exports = Moddle;
+
+
+        /**
+         * Create an instance of the specified type.
+         * 
+         * @method Moddle#create
+         * 
+         * @example
+         * 
+         * var foo = moddle.create('my:Foo'); var bar = moddle.create('my:Bar', { id:
+         * 'BAR_1' });
+         * 
+         * @param {String|Object}
+         *            descriptor the type descriptor or name know to the model
+         * @param {Object}
+         *            attrs a number of attributes to initialize the model instance with
+         * @return {Object} model instance
+         */
+        Moddle.prototype.create = function(descriptor, attrs) {
+            var Type = this.getType(descriptor);
+
+            if (!Type) {
+                throw new Error('unknown type <' + descriptor + '>');
+            }
+
+            return new Type(attrs);
+        };
+
+
+        /**
+         * Returns the type representing a given descriptor
+         * 
+         * @method Moddle#getType
+         * 
+         * @example
+         * 
+         * var Foo = moddle.getType('my:Foo'); var foo = new Foo({ 'id' : 'FOO_1' });
+         * 
+         * @param {String|Object}
+         *            descriptor the type descriptor or name know to the model
+         * @return {Object} the type representing the descriptor
+         */
+        Moddle.prototype.getType = function(descriptor) {
+
+            var cache = this.typeCache;
+
+            var name = isString(descriptor) ? descriptor : descriptor.ns.name;
+
+            var type = cache[name];
+
+            if (!type) {
+                descriptor = this.registry.getEffectiveDescriptor(name);
+                type = cache[name] = this.factory.createType(descriptor);
+            }
+
+            return type;
+        };
+
+
+        /**
+         * Creates an any-element type to be used within model instances.
+         * 
+         * This can be used to create custom elements that lie outside the meta-model.
+         * The created element contains all the meta-data required to serialize it as
+         * part of meta-model elements.
+         * 
+         * @method Moddle#createAny
+         * 
+         * @example
+         * 
+         * var foo = moddle.createAny('vendor:Foo', 'http://vendor', { value: 'bar' });
+         * 
+         * var container = moddle.create('my:Container', 'http://my', { any: [ foo ] });
+         *  // go ahead and serialize the stuff
+         * 
+         * 
+         * @param {String}
+         *            name the name of the element
+         * @param {String}
+         *            nsUri the namespace uri of the element
+         * @param {Object}
+         *            [properties] a map of properties to initialize the instance with
+         * @return {Object} the any type instance
+         */
+        Moddle.prototype.createAny = function(name, nsUri, properties) {
+
+            var nameNs = parseNameNs(name);
+
+            var element = {
+                $type: name
+            };
+
+            var descriptor = {
+                name: name,
+                isGeneric: true,
+                ns: {
+                    prefix: nameNs.prefix,
+                    localName: nameNs.localName,
+                    uri: nsUri
+                }
+            };
+
+            this.properties.defineDescriptor(element, descriptor);
+            this.properties.defineModel(element, this);
+            this.properties.define(element, '$parent', {
+                enumerable: false,
+                writable: true
+            });
+
+            forEach(properties, function(a, key) {
+                if (isObject(a) && a.value !== undefined) {
+                    element[a.name] = a.value;
+                } else {
+                    element[key] = a;
+                }
+            });
+
+            return element;
+        };
+
+        /**
+         * Returns a registered package by uri or prefix
+         * 
+         * @return {Object} the package
+         */
+        Moddle.prototype.getPackage = function(uriOrPrefix) {
+            return this.registry.getPackage(uriOrPrefix);
+        };
+
+        /**
+         * Returns a snapshot of all known packages
+         * 
+         * @return {Object} the package
+         */
+        Moddle.prototype.getPackages = function() {
+            return this.registry.getPackages();
+        };
+
+        /**
+         * Returns the descriptor for an element
+         */
+        Moddle.prototype.getElementDescriptor = function(element) {
+            return element.$descriptor;
+        };
+
+        /**
+         * Returns true if the given descriptor or instance represents the given type.
+         * 
+         * May be applied to this, if element is omitted.
+         */
+        Moddle.prototype.hasType = function(element, type) {
+            if (type === undefined) {
+                type = element;
+                element = this;
+            }
+
+            var descriptor = element.$model.getElementDescriptor(element);
+
+            return !!find(descriptor.allTypes, function(t) {
+                return t.name === type;
+            });
+        };
+
+
+        /**
+         * Returns the descriptor of an elements named property
+         */
+        Moddle.prototype.getPropertyDescriptor = function(element, property) {
+            return this.getElementDescriptor(element).propertiesByName[property];
+        };
+
+    }, {
+        "./factory": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\factory.js",
+        "./ns": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js",
+        "./properties": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\properties.js",
+        "./registry": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\registry.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Parses a namespaced attribute name of the form (ns:)localName to an object,
+         * given a default prefix to assume in case no explicit namespace is given.
+         * 
+         * @param {String}
+         *            name
+         * @param {String}
+         *            [defaultPrefix] the default prefix to take, if none is present.
+         * 
+         * @return {Object} the parsed name
+         */
+        module.exports.parseName = function(name, defaultPrefix) {
+            var parts = name.split(/:/),
+                localName, prefix;
+
+            // no prefix (i.e. only local name)
+            if (parts.length === 1) {
+                localName = name;
+                prefix = defaultPrefix;
+            } else
+            // prefix + local name
+            if (parts.length === 2) {
+                localName = parts[1];
+                prefix = parts[0];
+            } else {
+                throw new Error('expected <prefix:localName> or <localName>, got ' + name);
+            }
+
+            name = (prefix ? prefix + ':' : '') + localName;
+
+            return {
+                name: name,
+                prefix: prefix,
+                localName: localName
+            };
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\properties.js": [function(require, module, exports) {
+        'use strict';
+
+
+        /**
+         * A utility that gets and sets properties of model elements.
+         * 
+         * @param {Model}
+         *            model
+         */
+        function Properties(model) {
+            this.model = model;
+        }
+
+        module.exports = Properties;
+
+
+        /**
+         * Sets a named property on the target element
+         * 
+         * @param {Object}
+         *            target
+         * @param {String}
+         *            name
+         * @param {Object}
+         *            value
+         */
+        Properties.prototype.set = function(target, name, value) {
+
+            var property = this.model.getPropertyDescriptor(target, name);
+
+            if (!property) {
+                target.$attrs[name] = value;
+            } else {
+                Object.defineProperty(target, property.name, {
+                    enumerable: !property.isReference,
+                    writable: true,
+                    value: value
+                });
+            }
+        };
+
+        /**
+         * Returns the named property of the given element
+         * 
+         * @param {Object}
+         *            target
+         * @param {String}
+         *            name
+         * 
+         * @return {Object}
+         */
+        Properties.prototype.get = function(target, name) {
+
+            var property = this.model.getPropertyDescriptor(target, name);
+
+            if (!property) {
+                return target.$attrs[name];
+            }
+
+            var propertyName = property.name;
+
+            // check if access to collection property and lazily initialize it
+            if (!target[propertyName] && property.isMany) {
+                Object.defineProperty(target, propertyName, {
+                    enumerable: !property.isReference,
+                    writable: true,
+                    value: []
+                });
+            }
+
+            return target[propertyName];
+        };
+
+
+        /**
+         * Define a property on the target element
+         * 
+         * @param {Object}
+         *            target
+         * @param {String}
+         *            name
+         * @param {Object}
+         *            options
+         */
+        Properties.prototype.define = function(target, name, options) {
+            Object.defineProperty(target, name, options);
+        };
+
+
+        /**
+         * Define the descriptor for an element
+         */
+        Properties.prototype.defineDescriptor = function(target, descriptor) {
+            this.define(target, '$descriptor', {
+                value: descriptor
+            });
+        };
+
+        /**
+         * Define the model for an element
+         */
+        Properties.prototype.defineModel = function(target, model) {
+            this.define(target, '$model', {
+                value: model
+            });
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\registry.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+        var Types = require('./types'),
+            DescriptorBuilder = require('./descriptor-builder');
+
+        var parseNameNs = require('./ns').parseName,
+            isBuiltInType = Types.isBuiltIn;
+
+
+        function Registry(packages, properties, options) {
+
+            this.options = assign({
+                generateId: 'id'
+            }, options || {});
+
+            this.packageMap = {};
+            this.typeMap = {};
+
+            this.packages = [];
+
+            this.properties = properties;
+
+            forEach(packages, this.registerPackage, this);
+        }
+
+        module.exports = Registry;
+
+
+        Registry.prototype.getPackage = function(uriOrPrefix) {
+            return this.packageMap[uriOrPrefix];
+        };
+
+        Registry.prototype.getPackages = function() {
+            return this.packages;
+        };
+
+
+        Registry.prototype.registerPackage = function(pkg) {
+            // alert("pkg :: " + pkg);
+            // copy package
+            pkg = assign({}, pkg);
+
+            // register types
+            forEach(pkg.types, function(descriptor) {
+                this.registerType(descriptor, pkg);
+            }, this);
+
+            this.packageMap[pkg.uri] = this.packageMap[pkg.prefix] = pkg;
+            this.packages.push(pkg);
+        };
+
+
+        /**
+         * Register a type from a specific package with us
+         */
+        Registry.prototype.registerType = function(type, pkg) {
+
+            type = assign({}, type, {
+                superClass: (type.superClass || []).slice(),
+                extends: (type.extends || []).slice(),
+                properties: (type.properties || []).slice()
+            });
+
+            var ns = parseNameNs(type.name, pkg.prefix),
+                name = ns.name,
+                propertiesByName = {};
+
+            // parse properties
+            forEach(type.properties, function(p) {
+
+                // namespace property names
+                var propertyNs = parseNameNs(p.name, ns.prefix),
+                    propertyName = propertyNs.name;
+
+                // namespace property types
+                if (!isBuiltInType(p.type)) {
+                    p.type = parseNameNs(p.type, propertyNs.prefix).name;
+                }
+
+                assign(p, {
+                    ns: propertyNs,
+                    name: propertyName
+                });
+
+                propertiesByName[propertyName] = p;
+            });
+
+            // update ns + name
+            assign(type, {
+                ns: ns,
+                name: name,
+                propertiesByName: propertiesByName
+            });
+
+            forEach(type.extends, function(extendsName) {
+                var extended = this.typeMap[extendsName];
+
+                extended.traits = extended.traits || [];
+                extended.traits.push(name);
+            }, this);
+
+            // link to package
+            this.definePackage(type, pkg);
+
+            // register
+            this.typeMap[name] = type;
+        };
+
+
+        /**
+         * Traverse the type hierarchy from bottom to top.
+         */
+        Registry.prototype.mapTypes = function(nsName, iterator) {
+
+            // alert("nsName :: " + nsName.name);
+            var type = isBuiltInType(nsName.name) ? {
+                name: nsName.name
+            } : this.typeMap[nsName.name];
+            // alert("Type :: " + type);
+
+            var self = this;
+
+            /**
+             * Traverse the selected super type or trait
+             * 
+             * @param {String}
+             *            cls
+             */
+            function traverseSuper(cls) {
+                var parentNs = parseNameNs(cls, isBuiltInType(cls) ? '' : nsName.prefix);
+                self.mapTypes(parentNs, iterator);
+            }
+
+            if (!type) {
+                throw new Error('unknown type <' + nsName.name + '>');
+            }
+
+            forEach(type.superClass, traverseSuper);
+
+            iterator(type);
+
+            forEach(type.traits, traverseSuper);
+        };
+
+
+        /**
+         * Returns the effective descriptor for a type.
+         * 
+         * @param {String}
+         *            type the namespaced name (ns:localName) of the type
+         * 
+         * @return {Descriptor} the resulting effective descriptor
+         */
+        Registry.prototype.getEffectiveDescriptor = function(name) {
+
+            var nsName = parseNameNs(name);
+
+            var builder = new DescriptorBuilder(nsName);
+
+            this.mapTypes(nsName, function(type) {
+                builder.addTrait(type);
+            });
+
+            // check we have an id assigned
+            var id = this.options.generateId;
+            if (id && !builder.hasProperty(id)) {
+                builder.addIdProperty(id);
+            }
+
+            var descriptor = builder.build();
+
+            // define package link
+            this.definePackage(descriptor, descriptor.allTypes[descriptor.allTypes.length - 1].$pkg);
+
+            return descriptor;
+        };
+
+
+        Registry.prototype.definePackage = function(target, pkg) {
+            this.properties.define(target, '$pkg', {
+                value: pkg
+            });
+        };
+    }, {
+        "./descriptor-builder": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\descriptor-builder.js",
+        "./ns": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\ns.js",
+        "./types": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\types.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\node_modules\\moddle\\lib\\types.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Built-in moddle types
+         */
+        var BUILTINS = {
+            String: true,
+            Boolean: true,
+            Integer: true,
+            Real: true,
+            Element: true
+        };
+
+        /**
+         * Converters for built in types from string representations
+         */
+        var TYPE_CONVERTERS = {
+            String: function(s) {
+                return s;
+            },
+            Boolean: function(s) {
+                return s === 'true';
+            },
+            Integer: function(s) {
+                return parseInt(s, 10);
+            },
+            Real: function(s) {
+                return parseFloat(s, 10);
+            }
+        };
+
+        /**
+         * Convert a type to its real representation
+         */
+        module.exports.coerceType = function(type, value) {
+
+            var converter = TYPE_CONVERTERS[type];
+
+            if (converter) {
+                return converter(value);
+            } else {
+                return value;
+            }
+        };
+
+        /**
+         * Return whether the given type is built-in
+         */
+        module.exports.isBuiltIn = function(type) {
+            return !!BUILTINS[type];
+        };
+
+        /**
+         * Return whether the given type is simple
+         */
+        module.exports.isSimple = function(type) {
+            return !!TYPE_CONVERTERS[type];
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\bpmn.json": [function(require, module, exports) {
+        module.exports = {
+            "name": "BPMN20",
+            "uri": "http://www.omg.org/spec/BPMN/20100524/MODEL",
+            "associations": [],
+            "types": [{
+                "name": "Interface",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "operations",
+                    "type": "Operation",
+                    "isMany": true
+                }, {
+                    "name": "implementationRef",
+                    "type": "String",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "Operation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "inMessageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "outMessageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "errorRefs",
+                    "type": "Error",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "implementationRef",
+                    "type": "String",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "EndPoint",
+                "superClass": [
+                    "RootElement"
+                ]
+            }, {
+                "name": "Auditing",
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "GlobalTask",
+                "superClass": [
+                    "CallableElement"
+                ],
+                "properties": [{
+                    "name": "resources",
+                    "type": "ResourceRole",
+                    "isMany": true
+                }]
+            }, {
+                "name": "Monitoring",
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "Performer",
+                "superClass": [
+                    "ResourceRole"
+                ]
+            }, {
+                "name": "Process",
+                "superClass": [
+                    "FlowElementsContainer",
+                    "CallableElement"
+                ],
+                "properties": [{
+                    "name": "processType",
+                    "type": "ProcessType",
+                    "isAttr": true
+                }, {
+                    "name": "isClosed",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "auditing",
+                    "type": "Auditing"
+                }, {
+                    "name": "monitoring",
+                    "type": "Monitoring"
+                }, {
+                    "name": "properties",
+                    "type": "Property",
+                    "isMany": true
+                }, {
+                    "name": "supports",
+                    "type": "Process",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "definitionalCollaborationRef",
+                    "type": "Collaboration",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "isExecutable",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "resources",
+                    "type": "ResourceRole",
+                    "isMany": true
+                }, {
+                    "name": "artifacts",
+                    "type": "Artifact",
+                    "isMany": true
+                }, {
+                    "name": "correlationSubscriptions",
+                    "type": "CorrelationSubscription",
+                    "isMany": true
+                }]
+            }, {
+                "name": "LaneSet",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "lanes",
+                    "type": "Lane",
+                    "isMany": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Lane",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "childLaneSet",
+                    "type": "LaneSet",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "partitionElementRef",
+                    "type": "BaseElement",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "flowNodeRef",
+                    "type": "FlowNode",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "partitionElement",
+                    "type": "BaseElement"
+                }]
+            }, {
+                "name": "GlobalManualTask",
+                "superClass": [
+                    "GlobalTask"
+                ]
+            }, {
+                "name": "ManualTask",
+                "superClass": [
+                    "Task"
+                ]
+            }, {
+                "name": "UserTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "renderings",
+                    "type": "Rendering",
+                    "isMany": true
+                }, {
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Rendering",
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "HumanPerformer",
+                "superClass": [
+                    "Performer"
+                ]
+            }, {
+                "name": "PotentialOwner",
+                "superClass": [
+                    "HumanPerformer"
+                ]
+            }, {
+                "name": "GlobalUserTask",
+                "superClass": [
+                    "GlobalTask"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "renderings",
+                    "type": "Rendering",
+                    "isMany": true
+                }]
+            }, {
+                "name": "Gateway",
+                "isAbstract": true,
+                "superClass": [
+                    "FlowNode"
+                ],
+                "properties": [{
+                    "name": "gatewayDirection",
+                    "type": "GatewayDirection",
+                    "default": "Unspecified",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "EventBasedGateway",
+                "superClass": [
+                    "Gateway"
+                ],
+                "properties": [{
+                    "name": "instantiate",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "eventGatewayType",
+                    "type": "EventBasedGatewayType",
+                    "isAttr": true,
+                    "default": "Exclusive"
+                }]
+            }, {
+                "name": "ComplexGateway",
+                "superClass": [
+                    "Gateway"
+                ],
+                "properties": [{
+                    "name": "activationCondition",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "default",
+                    "type": "SequenceFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ExclusiveGateway",
+                "superClass": [
+                    "Gateway"
+                ],
+                "properties": [{
+                    "name": "default",
+                    "type": "SequenceFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "InclusiveGateway",
+                "superClass": [
+                    "Gateway"
+                ],
+                "properties": [{
+                    "name": "default",
+                    "type": "SequenceFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ParallelGateway",
+                "superClass": [
+                    "Gateway"
+                ]
+            }, {
+                "name": "RootElement",
+                "isAbstract": true,
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "Relationship",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "type",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "direction",
+                    "type": "RelationshipDirection",
+                    "isAttr": true
+                }, {
+                    "name": "source",
+                    "isMany": true,
+                    "isReference": true,
+                    "type": "Element"
+                }, {
+                    "name": "target",
+                    "isMany": true,
+                    "isReference": true,
+                    "type": "Element"
+                }]
+            }, {
+                "name": "BaseElement",
+                "isAbstract": true,
+                "properties": [{
+                    "name": "id",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "documentation",
+                    "type": "Documentation",
+                    "isMany": true
+                }, {
+                    "name": "extensionDefinitions",
+                    "type": "ExtensionDefinition",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "extensionElements",
+                    "type": "ExtensionElements"
+                }]
+            }, {
+                "name": "Extension",
+                "properties": [{
+                    "name": "mustUnderstand",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "definition",
+                    "type": "ExtensionDefinition"
+                }]
+            }, {
+                "name": "ExtensionDefinition",
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "extensionAttributeDefinitions",
+                    "type": "ExtensionAttributeDefinition",
+                    "isMany": true
+                }]
+            }, {
+                "name": "ExtensionAttributeDefinition",
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "type",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "isReference",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "extensionDefinition",
+                    "type": "ExtensionDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ExtensionElements",
+                "properties": [{
+                    "name": "valueRef",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "Element"
+                }, {
+                    "name": "values",
+                    "type": "Element",
+                    "isMany": true
+                }, {
+                    "name": "extensionAttributeDefinition",
+                    "type": "ExtensionAttributeDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Documentation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "text",
+                    "type": "String",
+                    "isBody": true
+                }, {
+                    "name": "textFormat",
+                    "default": "text/plain",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Event",
+                "isAbstract": true,
+                "superClass": [
+                    "FlowNode",
+                    "InteractionNode"
+                ],
+                "properties": [{
+                    "name": "properties",
+                    "type": "Property",
+                    "isMany": true
+                }]
+            }, {
+                "name": "IntermediateCatchEvent",
+                "superClass": [
+                    "CatchEvent"
+                ]
+            }, {
+                "name": "IntermediateThrowEvent",
+                "superClass": [
+                    "ThrowEvent"
+                ]
+            }, {
+                "name": "EndEvent",
+                "superClass": [
+                    "ThrowEvent"
+                ]
+            }, {
+                "name": "StartEvent",
+                "superClass": [
+                    "CatchEvent"
+                ],
+                "properties": [{
+                    "name": "isInterrupting",
+                    "default": true,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }]
+            }, {
+                "name": "MultiBranchConnector",
+                "superClass": [
+                    "CatchEvent"
+                ],
+                "properties": [{
+                    "name": "isInterrupting",
+                    "default": true,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }]
+            }, {
+                "name": "ParentReturn",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            }, {
+                "name": "SubProcessCall",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            }, {
+                "name": "ThrowEvent",
+                "isAbstract": true,
+                "superClass": [
+                    "Event"
+                ],
+                "properties": [{
+                    "name": "inputSet",
+                    "type": "InputSet"
+                }, {
+                    "name": "eventDefinitionRefs",
+                    "type": "EventDefinition",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "dataInputAssociation",
+                    "type": "DataInputAssociation",
+                    "isMany": true
+                }, {
+                    "name": "dataInputs",
+                    "type": "DataInput",
+                    "isMany": true
+                }, {
+                    "name": "eventDefinitions",
+                    "type": "EventDefinition",
+                    "isMany": true
+                }]
+            }, {
+                "name": "CatchEvent",
+                "isAbstract": true,
+                "superClass": [
+                    "Event"
+                ],
+                "properties": [{
+                    "name": "parallelMultiple",
+                    "isAttr": true,
+                    "type": "Boolean",
+                    "default": false
+                }, {
+                    "name": "outputSet",
+                    "type": "OutputSet"
+                }, {
+                    "name": "eventDefinitionRefs",
+                    "type": "EventDefinition",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "dataOutputAssociation",
+                    "type": "DataOutputAssociation",
+                    "isMany": true
+                }, {
+                    "name": "dataOutputs",
+                    "type": "DataOutput",
+                    "isMany": true
+                }, {
+                    "name": "eventDefinitions",
+                    "type": "EventDefinition",
+                    "isMany": true
+                }]
+            }, {
+                "name": "BoundaryEvent",
+                "superClass": [
+                    "CatchEvent"
+                ],
+                "properties": [{
+                    "name": "cancelActivity",
+                    "default": true,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "attachedToRef",
+                    "type": "Activity",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "EventDefinition",
+                "isAbstract": true,
+                "superClass": [
+                    "RootElement"
+                ]
+            }, {
+                "name": "CancelEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ]
+            }, {
+                "name": "ErrorEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "errorRef",
+                    "type": "Error",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "TerminateEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ]
+            }, {
+                "name": "EscalationEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "escalationRef",
+                    "type": "Escalation",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Escalation",
+                "properties": [{
+                    "name": "structureRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "escalationCode",
+                    "isAttr": true,
+                    "type": "String"
+                }],
+                "superClass": [
+                    "RootElement"
+                ]
+            }, {
+                "name": "CompensateEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "waitForCompletion",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "activityRef",
+                    "type": "Activity",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "TimerEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "timeDate",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "timeCycle",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "timeDuration",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "LinkEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "target",
+                    "type": "LinkEventDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "source",
+                    "type": "LinkEventDefinition",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "MessageEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "messageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "operationRef",
+                    "type": "Operation",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ConditionalEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "condition",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "SignalEventDefinition",
+                "superClass": [
+                    "EventDefinition"
+                ],
+                "properties": [{
+                    "name": "signalRef",
+                    "type": "Signal",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Signal",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "structureRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "ImplicitThrowEvent",
+                "superClass": [
+                    "ThrowEvent"
+                ]
+            }, {
+                "name": "DataState",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "ItemAwareElement",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "itemSubjectRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "dataState",
+                    "type": "DataState"
+                }]
+            }, {
+                "name": "DataAssociation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "transformation",
+                    "type": "FormalExpression"
+                }, {
+                    "name": "assignment",
+                    "type": "Assignment",
+                    "isMany": true
+                }, {
+                    "name": "sourceRef",
+                    "type": "ItemAwareElement",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "targetRef",
+                    "type": "ItemAwareElement",
+                    "isReference": true
+                }]
+            }, {
+                "name": "DataInput",
+                "superClass": [
+                    "ItemAwareElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "isCollection",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "inputSetRefs",
+                    "type": "InputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "inputSetWithOptional",
+                    "type": "InputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "inputSetWithWhileExecuting",
+                    "type": "InputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "DataOutput",
+                "superClass": [
+                    "ItemAwareElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "isCollection",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "outputSetRefs",
+                    "type": "OutputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "outputSetWithOptional",
+                    "type": "OutputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "outputSetWithWhileExecuting",
+                    "type": "OutputSet",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "InputSet",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "dataInputRefs",
+                    "type": "DataInput",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "optionalInputRefs",
+                    "type": "DataInput",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "whileExecutingInputRefs",
+                    "type": "DataInput",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "outputSetRefs",
+                    "type": "OutputSet",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "OutputSet",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "dataOutputRefs",
+                    "type": "DataOutput",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "inputSetRefs",
+                    "type": "InputSet",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "optionalOutputRefs",
+                    "type": "DataOutput",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "whileExecutingOutputRefs",
+                    "type": "DataOutput",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Property",
+                "superClass": [
+                    "ItemAwareElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "DataInputAssociation",
+                "superClass": [
+                    "DataAssociation"
+                ]
+            }, {
+                "name": "DataOutputAssociation",
+                "superClass": [
+                    "DataAssociation"
+                ]
+            }, {
+                "name": "InputOutputSpecification",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "inputSets",
+                    "type": "InputSet",
+                    "isMany": true
+                }, {
+                    "name": "outputSets",
+                    "type": "OutputSet",
+                    "isMany": true
+                }, {
+                    "name": "dataInputs",
+                    "type": "DataInput",
+                    "isMany": true
+                }, {
+                    "name": "dataOutputs",
+                    "type": "DataOutput",
+                    "isMany": true
+                }]
+            }, {
+                "name": "DataObject",
+                "superClass": [
+                    "FlowElement",
+                    "ItemAwareElement"
+                ],
+                "properties": [{
+                    "name": "isCollection",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }]
+            }, {
+                "name": "InputOutputBinding",
+                "properties": [{
+                    "name": "inputDataRef",
+                    "type": "InputSet",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "outputDataRef",
+                    "type": "OutputSet",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "operationRef",
+                    "type": "Operation",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Assignment",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "from",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "to",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "DataStore",
+                "superClass": [
+                    "RootElement",
+                    "ItemAwareElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "capacity",
+                    "isAttr": true,
+                    "type": "Integer"
+                }, {
+                    "name": "isUnlimited",
+                    "default": true,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }]
+            }, {
+                "name": "DataStoreReference",
+                "superClass": [
+                    "ItemAwareElement",
+                    "FlowElement"
+                ],
+                "properties": [{
+                    "name": "dataStoreRef",
+                    "type": "DataStore",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "DataObjectReference",
+                "superClass": [
+                    "ItemAwareElement",
+                    "FlowElement"
+                ],
+                "properties": [{
+                    "name": "dataObjectRef",
+                    "type": "DataObject",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ConversationLink",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "sourceRef",
+                    "type": "InteractionNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "targetRef",
+                    "type": "InteractionNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "ConversationAssociation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "innerConversationNodeRef",
+                    "type": "ConversationNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "outerConversationNodeRef",
+                    "type": "ConversationNode",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "CallConversation",
+                "superClass": [
+                    "ConversationNode"
+                ],
+                "properties": [{
+                    "name": "calledCollaborationRef",
+                    "type": "Collaboration",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "participantAssociations",
+                    "type": "ParticipantAssociation",
+                    "isMany": true
+                }]
+            }, {
+                "name": "Conversation",
+                "superClass": [
+                    "ConversationNode"
+                ]
+            }, {
+                "name": "SubConversation",
+                "superClass": [
+                    "ConversationNode"
+                ],
+                "properties": [{
+                    "name": "conversationNodes",
+                    "type": "ConversationNode",
+                    "isMany": true
+                }]
+            }, {
+                "name": "ConversationNode",
+                "isAbstract": true,
+                "superClass": [
+                    "InteractionNode",
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "participantRefs",
+                    "type": "Participant",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "messageFlowRefs",
+                    "type": "MessageFlow",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "correlationKeys",
+                    "type": "CorrelationKey",
+                    "isMany": true
+                }]
+            }, {
+                "name": "GlobalConversation",
+                "superClass": [
+                    "Collaboration"
+                ]
+            }, {
+                "name": "PartnerEntity",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "participantRef",
+                    "type": "Participant",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "PartnerRole",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "participantRef",
+                    "type": "Participant",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "CorrelationProperty",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "correlationPropertyRetrievalExpression",
+                    "type": "CorrelationPropertyRetrievalExpression",
+                    "isMany": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "type",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Error",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "structureRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "errorCode",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "CorrelationKey",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "correlationPropertyRef",
+                    "type": "CorrelationProperty",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Expression",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "isAbstract": true
+            }, {
+                "name": "FormalExpression",
+                "superClass": [
+                    "Expression"
+                ],
+                "properties": [{
+                    "name": "language",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "body",
+                    "type": "String",
+                    "isBody": true
+                }, {
+                    "name": "evaluatesToTypeRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Message",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "itemRef",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ItemDefinition",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "itemKind",
+                    "type": "ItemKind",
+                    "isAttr": true
+                }, {
+                    "name": "structureRef",
+                    "type": "String",
+                    "isAttr": true
+                }, {
+                    "name": "isCollection",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "import",
+                    "type": "Import",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "FlowElement",
+                "isAbstract": true,
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "auditing",
+                    "type": "Auditing"
+                }, {
+                    "name": "monitoring",
+                    "type": "Monitoring"
+                }, {
+                    "name": "categoryValueRef",
+                    "type": "CategoryValue",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "SequenceFlow",
+                "superClass": [
+                    "FlowElement"
+                ],
+                "properties": [{
+                    "name": "isImmediate",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "conditionExpression",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "sourceRef",
+                    "type": "FlowNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "targetRef",
+                    "type": "FlowNode",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "FlowElementsContainer",
+                "isAbstract": true,
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "laneSets",
+                    "type": "LaneSet",
+                    "isMany": true
+                }, {
+                    "name": "flowElements",
+                    "type": "FlowElement",
+                    "isMany": true
+                }]
+            }, {
+                "name": "CallableElement",
+                "isAbstract": true,
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "ioSpecification",
+                    "type": "InputOutputSpecification"
+                }, {
+                    "name": "supportedInterfaceRefs",
+                    "type": "Interface",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "ioBinding",
+                    "type": "InputOutputBinding",
+                    "isMany": true
+                }]
+            }, {
+                "name": "FlowNode",
+                "isAbstract": true,
+                "superClass": [
+                    "FlowElement"
+                ],
+                "properties": [{
+                    "name": "incoming",
+                    "type": "SequenceFlow",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "outgoing",
+                    "type": "SequenceFlow",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "lanes",
+                    "type": "Lane",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "CorrelationPropertyRetrievalExpression",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "messagePath",
+                    "type": "FormalExpression"
+                }, {
+                    "name": "messageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "CorrelationPropertyBinding",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "dataPath",
+                    "type": "FormalExpression"
+                }, {
+                    "name": "correlationPropertyRef",
+                    "type": "CorrelationProperty",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Resource",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "resourceParameters",
+                    "type": "ResourceParameter",
+                    "isMany": true
+                }]
+            }, {
+                "name": "ResourceParameter",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "isRequired",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "type",
+                    "type": "ItemDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "CorrelationSubscription",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "correlationKeyRef",
+                    "type": "CorrelationKey",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "correlationPropertyBinding",
+                    "type": "CorrelationPropertyBinding",
+                    "isMany": true
+                }]
+            }, {
+                "name": "MessageFlow",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "sourceRef",
+                    "type": "InteractionNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "targetRef",
+                    "type": "InteractionNode",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "messageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "MessageFlowAssociation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "innerMessageFlowRef",
+                    "type": "MessageFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "outerMessageFlowRef",
+                    "type": "MessageFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "InteractionNode",
+                "isAbstract": true,
+                "properties": [{
+                    "name": "incomingConversationLinks",
+                    "type": "ConversationLink",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "outgoingConversationLinks",
+                    "type": "ConversationLink",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Participant",
+                "superClass": [
+                    "InteractionNode",
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "interfaceRefs",
+                    "type": "Interface",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "participantMultiplicity",
+                    "type": "ParticipantMultiplicity"
+                }, {
+                    "name": "endPointRefs",
+                    "type": "EndPoint",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "processRef",
+                    "type": "Process",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ParticipantAssociation",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "innerParticipantRef",
+                    "type": "Participant",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "outerParticipantRef",
+                    "type": "Participant",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ParticipantMultiplicity",
+                "properties": [{
+                    "name": "minimum",
+                    "default": 0,
+                    "isAttr": true,
+                    "type": "Integer"
+                }, {
+                    "name": "maximum",
+                    "default": 1,
+                    "isAttr": true,
+                    "type": "Integer"
+                }]
+            }, {
+                "name": "Collaboration",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "isClosed",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "choreographyRef",
+                    "type": "Choreography",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "artifacts",
+                    "type": "Artifact",
+                    "isMany": true
+                }, {
+                    "name": "participantAssociations",
+                    "type": "ParticipantAssociation",
+                    "isMany": true
+                }, {
+                    "name": "messageFlowAssociations",
+                    "type": "MessageFlowAssociation",
+                    "isMany": true
+                }, {
+                    "name": "conversationAssociations",
+                    "type": "ConversationAssociation"
+                }, {
+                    "name": "participants",
+                    "type": "Participant",
+                    "isMany": true
+                }, {
+                    "name": "messageFlows",
+                    "type": "MessageFlow",
+                    "isMany": true
+                }, {
+                    "name": "correlationKeys",
+                    "type": "CorrelationKey",
+                    "isMany": true
+                }, {
+                    "name": "conversations",
+                    "type": "ConversationNode",
+                    "isMany": true
+                }, {
+                    "name": "conversationLinks",
+                    "type": "ConversationLink",
+                    "isMany": true
+                }]
+            }, {
+                "name": "ChoreographyActivity",
+                "isAbstract": true,
+                "superClass": [
+                    "FlowNode"
+                ],
+                "properties": [{
+                    "name": "participantRefs",
+                    "type": "Participant",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "initiatingParticipantRef",
+                    "type": "Participant",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "correlationKeys",
+                    "type": "CorrelationKey",
+                    "isMany": true
+                }, {
+                    "name": "loopType",
+                    "type": "ChoreographyLoopType",
+                    "default": "None",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "CallChoreography",
+                "superClass": [
+                    "ChoreographyActivity"
+                ],
+                "properties": [{
+                    "name": "calledChoreographyRef",
+                    "type": "Choreography",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "participantAssociations",
+                    "type": "ParticipantAssociation",
+                    "isMany": true
+                }]
+            }, {
+                "name": "SubChoreography",
+                "superClass": [
+                    "ChoreographyActivity",
+                    "FlowElementsContainer"
+                ],
+                "properties": [{
+                    "name": "artifacts",
+                    "type": "Artifact",
+                    "isMany": true
+                }]
+            }, {
+                "name": "ChoreographyTask",
+                "superClass": [
+                    "ChoreographyActivity"
+                ],
+                "properties": [{
+                    "name": "messageFlowRef",
+                    "type": "MessageFlow",
+                    "isMany": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Choreography",
+                "superClass": [
+                    "FlowElementsContainer",
+                    "Collaboration"
+                ]
+            }, {
+                "name": "GlobalChoreographyTask",
+                "superClass": [
+                    "Choreography"
+                ],
+                "properties": [{
+                    "name": "initiatingParticipantRef",
+                    "type": "Participant",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "TextAnnotation",
+                "superClass": [
+                    "Artifact"
+                ],
+                "properties": [{
+                    "name": "text",
+                    "type": "String"
+                }, {
+                    "name": "textFormat",
+                    "default": "text/plain",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Group",
+                "superClass": [
+                    "Artifact"
+                ],
+                "properties": [{
+                    "name": "categoryValueRef",
+                    "type": "CategoryValue",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Association",
+                "superClass": [
+                    "Artifact"
+                ],
+                "properties": [{
+                    "name": "associationDirection",
+                    "type": "AssociationDirection",
+                    "isAttr": true
+                }, {
+                    "name": "sourceRef",
+                    "type": "BaseElement",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "targetRef",
+                    "type": "BaseElement",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "Category",
+                "superClass": [
+                    "RootElement"
+                ],
+                "properties": [{
+                    "name": "categoryValue",
+                    "type": "CategoryValue",
+                    "isMany": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Artifact",
+                "isAbstract": true,
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "CategoryValue",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "categorizedFlowElements",
+                    "type": "FlowElement",
+                    "isVirtual": true,
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "value",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Activity",
+                "isAbstract": true,
+                "superClass": [
+                    "FlowNode"
+                ],
+                "properties": [{
+                    "name": "isForCompensation",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "loopCharacteristics",
+                    "type": "LoopCharacteristics"
+                }, {
+                    "name": "resources",
+                    "type": "ResourceRole",
+                    "isMany": true
+                }, {
+                    "name": "default",
+                    "type": "SequenceFlow",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "properties",
+                    "type": "Property",
+                    "isMany": true
+                }, {
+                    "name": "ioSpecification",
+                    "type": "InputOutputSpecification"
+                }, {
+                    "name": "boundaryEventRefs",
+                    "type": "BoundaryEvent",
+                    "isMany": true,
+                    "isReference": true
+                }, {
+                    "name": "dataInputAssociations",
+                    "type": "DataInputAssociation",
+                    "isMany": true
+                }, {
+                    "name": "dataOutputAssociations",
+                    "type": "DataOutputAssociation",
+                    "isMany": true
+                }, {
+                    "name": "startQuantity",
+                    "default": 1,
+                    "isAttr": true,
+                    "type": "Integer"
+                }, {
+                    "name": "completionQuantity",
+                    "default": 1,
+                    "isAttr": true,
+                    "type": "Integer"
+                }]
+            }, {
+                "name": "ServiceTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "operationRef",
+                    "type": "Operation",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "SubProcess",
+                "superClass": [
+                    "Activity",
+                    "FlowElementsContainer",
+                    "InteractionNode"
+                ],
+                "properties": [{
+                    "name": "triggeredByEvent",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "artifacts",
+                    "type": "Artifact",
+                    "isMany": true
+                }]
+            }, {
+                "name": "LoopCharacteristics",
+                "isAbstract": true,
+                "superClass": [
+                    "BaseElement"
+                ]
+            }, {
+                "name": "MultiInstanceLoopCharacteristics",
+                "superClass": [
+                    "LoopCharacteristics"
+                ],
+                "properties": [{
+                    "name": "isSequential",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "behavior",
+                    "type": "MultiInstanceBehavior",
+                    "default": "All",
+                    "isAttr": true
+                }, {
+                    "name": "loopCardinality",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "loopDataInputRef",
+                    "type": "ItemAwareElement",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "loopDataOutputRef",
+                    "type": "ItemAwareElement",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "inputDataItem",
+                    "type": "DataInput"
+                }, {
+                    "name": "outputDataItem",
+                    "type": "DataOutput"
+                }, {
+                    "name": "completionCondition",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "complexBehaviorDefinition",
+                    "type": "ComplexBehaviorDefinition",
+                    "isMany": true
+                }, {
+                    "name": "oneBehaviorEventRef",
+                    "type": "EventDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "noneBehaviorEventRef",
+                    "type": "EventDefinition",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "StandardLoopCharacteristics",
+                "superClass": [
+                    "LoopCharacteristics"
+                ],
+                "properties": [{
+                    "name": "testBefore",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "loopCondition",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "loopMaximum",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "CallActivity",
+                "superClass": [
+                    "Activity"
+                ],
+                "properties": [{
+                    "name": "calledElement",
+                    "type": "String",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "Task",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            }, {
+                "name": "InitiateProcess",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            }, {
+                "name": "Collector",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            },
+                       {
+                "name": "StringMatch",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            },
+            {
+                "name": "TCA",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            },
+                       {
+                "name": "GOC",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            },
+                       {
+                "name": "Policy",
+                "superClass": [
+                    "Activity",
+                    "InteractionNode"
+                ]
+            },
+                       {
+                "name": "SendTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "operationRef",
+                    "type": "Operation",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "messageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ReceiveTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "instantiate",
+                    "default": false,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "operationRef",
+                    "type": "Operation",
+                    "isAttr": true,
+                    "isReference": true
+                }, {
+                    "name": "messageRef",
+                    "type": "Message",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ScriptTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "scriptFormat",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "script",
+                    "type": "String"
+                }]
+            }, {
+                "name": "BusinessRuleTask",
+                "superClass": [
+                    "Task"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "AdHocSubProcess",
+                "superClass": [
+                    "SubProcess"
+                ],
+                "properties": [{
+                    "name": "completionCondition",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "ordering",
+                    "type": "AdHocOrdering",
+                    "isAttr": true
+                }, {
+                    "name": "cancelRemainingInstances",
+                    "default": true,
+                    "isAttr": true,
+                    "type": "Boolean"
+                }]
+            }, {
+                "name": "Transaction",
+                "superClass": [
+                    "SubProcess"
+                ],
+                "properties": [{
+                    "name": "protocol",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "method",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "GlobalScriptTask",
+                "superClass": [
+                    "GlobalTask"
+                ],
+                "properties": [{
+                    "name": "scriptLanguage",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "script",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "GlobalBusinessRuleTask",
+                "superClass": [
+                    "GlobalTask"
+                ],
+                "properties": [{
+                    "name": "implementation",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "ComplexBehaviorDefinition",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "condition",
+                    "type": "FormalExpression"
+                }, {
+                    "name": "event",
+                    "type": "ImplicitThrowEvent"
+                }]
+            }, {
+                "name": "ResourceRole",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "resourceRef",
+                    "type": "Resource",
+                    "isReference": true
+                }, {
+                    "name": "resourceParameterBindings",
+                    "type": "ResourceParameterBinding",
+                    "isMany": true
+                }, {
+                    "name": "resourceAssignmentExpression",
+                    "type": "ResourceAssignmentExpression"
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "ResourceParameterBinding",
+                "properties": [{
+                    "name": "expression",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }, {
+                    "name": "parameterRef",
+                    "type": "ResourceParameter",
+                    "isAttr": true,
+                    "isReference": true
+                }]
+            }, {
+                "name": "ResourceAssignmentExpression",
+                "properties": [{
+                    "name": "expression",
+                    "type": "Expression",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "Import",
+                "properties": [{
+                    "name": "importType",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "location",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "namespace",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }, {
+                "name": "Definitions",
+                "superClass": [
+                    "BaseElement"
+                ],
+                "properties": [{
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "targetNamespace",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "expressionLanguage",
+                    "default": "http://www.w3.org/1999/XPath",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "typeLanguage",
+                    "default": "http://www.w3.org/2001/XMLSchema",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "imports",
+                    "type": "Import",
+                    "isMany": true
+                }, {
+                    "name": "extensions",
+                    "type": "Extension",
+                    "isMany": true
+                }, {
+                    "name": "rootElements",
+                    "type": "RootElement",
+                    "isMany": true
+                }, {
+                    "name": "diagrams",
+                    "isMany": true,
+                    "type": "bpmndi:BPMNDiagram"
+                }, {
+                    "name": "exporter",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "relationships",
+                    "type": "Relationship",
+                    "isMany": true
+                }, {
+                    "name": "exporterVersion",
+                    "isAttr": true,
+                    "type": "String"
+                }]
+            }],
+            "emumerations": [{
+                "name": "ProcessType",
+                "literalValues": [{
+                    "name": "None"
+                }, {
+                    "name": "Public"
+                }, {
+                    "name": "Private"
+                }]
+            }, {
+                "name": "GatewayDirection",
+                "literalValues": [{
+                    "name": "Unspecified"
+                }, {
+                    "name": "Converging"
+                }, {
+                    "name": "Diverging"
+                }, {
+                    "name": "Mixed"
+                }]
+            }, {
+                "name": "EventBasedGatewayType",
+                "literalValues": [{
+                    "name": "Parallel"
+                }, {
+                    "name": "Exclusive"
+                }]
+            }, {
+                "name": "RelationshipDirection",
+                "literalValues": [{
+                    "name": "None"
+                }, {
+                    "name": "Forward"
+                }, {
+                    "name": "Backward"
+                }, {
+                    "name": "Both"
+                }]
+            }, {
+                "name": "ItemKind",
+                "literalValues": [{
+                    "name": "Physical"
+                }, {
+                    "name": "Information"
+                }]
+            }, {
+                "name": "ChoreographyLoopType",
+                "literalValues": [{
+                    "name": "None"
+                }, {
+                    "name": "Standard"
+                }, {
+                    "name": "MultiInstanceSequential"
+                }, {
+                    "name": "MultiInstanceParallel"
+                }]
+            }, {
+                "name": "AssociationDirection",
+                "literalValues": [{
+                    "name": "None"
+                }, {
+                    "name": "One"
+                }, {
+                    "name": "Both"
+                }]
+            }, {
+                "name": "MultiInstanceBehavior",
+                "literalValues": [{
+                    "name": "None"
+                }, {
+                    "name": "One"
+                }, {
+                    "name": "All"
+                }, {
+                    "name": "Complex"
+                }]
+            }, {
+                "name": "AdHocOrdering",
+                "literalValues": [{
+                    "name": "Parallel"
+                }, {
+                    "name": "Sequential"
+                }]
+            }],
+            "prefix": "bpmn",
+            "xml": {
+                "tagAlias": "lowerCase",
+                "typePrefix": "t"
+            }
+        }
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\bpmndi.json": [function(require, module, exports) {
+        module.exports = {
+            "name": "BPMNDI",
+            "uri": "http://www.omg.org/spec/BPMN/20100524/DI",
+            "types": [{
+                "name": "BPMNDiagram",
+                "properties": [{
+                    "name": "plane",
+                    "type": "BPMNPlane",
+                    "redefines": "di:Diagram#rootElement"
+                }, {
+                    "name": "labelStyle",
+                    "type": "BPMNLabelStyle",
+                    "isMany": true
+                }],
+                "superClass": [
+                    "di:Diagram"
+                ]
+            }, {
+                "name": "BPMNPlane",
+                "properties": [{
+                    "name": "bpmnElement",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "bpmn:BaseElement",
+                    "redefines": "di:DiagramElement#modelElement"
+                }],
+                "superClass": [
+                    "di:Plane"
+                ]
+            }, {
+                "name": "BPMNShape",
+                "properties": [{
+                    "name": "bpmnElement",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "bpmn:BaseElement",
+                    "redefines": "di:DiagramElement#modelElement"
+                }, {
+                    "name": "isHorizontal",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "isExpanded",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "isMarkerVisible",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "label",
+                    "type": "BPMNLabel"
+                }, {
+                    "name": "isMessageVisible",
+                    "isAttr": true,
+                    "type": "Boolean"
+                }, {
+                    "name": "participantBandKind",
+                    "type": "ParticipantBandKind",
+                    "isAttr": true
+                }, {
+                    "name": "choreographyActivityShape",
+                    "type": "BPMNShape",
+                    "isAttr": true,
+                    "isReference": true
+                }],
+                "superClass": [
+                    "di:LabeledShape"
+                ]
+            }, {
+                "name": "BPMNEdge",
+                "properties": [{
+                    "name": "label",
+                    "type": "BPMNLabel"
+                }, {
+                    "name": "bpmnElement",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "bpmn:BaseElement",
+                    "redefines": "di:DiagramElement#modelElement"
+                }, {
+                    "name": "sourceElement",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "di:DiagramElement",
+                    "redefines": "di:Edge#source"
+                }, {
+                    "name": "targetElement",
+                    "isAttr": true,
+                    "isReference": true,
+                    "type": "di:DiagramElement",
+                    "redefines": "di:Edge#target"
+                }, {
+                    "name": "messageVisibleKind",
+                    "type": "MessageVisibleKind",
+                    "isAttr": true,
+                    "default": "initiating"
+                }],
+                "superClass": [
+                    "di:LabeledEdge"
+                ]
+            }, {
+                "name": "BPMNLabel",
+                "properties": [{
+                    "name": "labelStyle",
+                    "type": "BPMNLabelStyle",
+                    "isAttr": true,
+                    "isReference": true,
+                    "redefines": "di:DiagramElement#style"
+                }],
+                "superClass": [
+                    "di:Label"
+                ]
+            }, {
+                "name": "BPMNLabelStyle",
+                "properties": [{
+                    "name": "font",
+                    "type": "dc:Font"
+                }],
+                "superClass": [
+                    "di:Style"
+                ]
+            }],
+            "emumerations": [{
+                "name": "ParticipantBandKind",
+                "literalValues": [{
+                    "name": "top_initiating"
+                }, {
+                    "name": "middle_initiating"
+                }, {
+                    "name": "bottom_initiating"
+                }, {
+                    "name": "top_non_initiating"
+                }, {
+                    "name": "middle_non_initiating"
+                }, {
+                    "name": "bottom_non_initiating"
+                }]
+            }, {
+                "name": "MessageVisibleKind",
+                "literalValues": [{
+                    "name": "initiating"
+                }, {
+                    "name": "non_initiating"
+                }]
+            }],
+            "associations": [],
+            "prefix": "bpmndi"
+        }
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\dc.json": [function(require, module, exports) {
+        module.exports = {
+            "name": "DC",
+            "uri": "http://www.omg.org/spec/DD/20100524/DC",
+            "types": [{
+                "name": "Boolean"
+            }, {
+                "name": "Integer"
+            }, {
+                "name": "Real"
+            }, {
+                "name": "String"
+            }, {
+                "name": "Font",
+                "properties": [{
+                    "name": "name",
+                    "type": "String",
+                    "isAttr": true
+                }, {
+                    "name": "size",
+                    "type": "Real",
+                    "isAttr": true
+                }, {
+                    "name": "isBold",
+                    "type": "Boolean",
+                    "isAttr": true
+                }, {
+                    "name": "isItalic",
+                    "type": "Boolean",
+                    "isAttr": true
+                }, {
+                    "name": "isUnderline",
+                    "type": "Boolean",
+                    "isAttr": true
+                }, {
+                    "name": "isStrikeThrough",
+                    "type": "Boolean",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "Point",
+                "properties": [{
+                    "name": "x",
+                    "type": "Real",
+                    "default": "0",
+                    "isAttr": true
+                }, {
+                    "name": "y",
+                    "type": "Real",
+                    "default": "0",
+                    "isAttr": true
+                }]
+            }, {
+                "name": "Bounds",
+                "properties": [{
+                    "name": "x",
+                    "type": "Real",
+                    "default": "0",
+                    "isAttr": true
+                }, {
+                    "name": "y",
+                    "type": "Real",
+                    "default": "0",
+                    "isAttr": true
+                }, {
+                    "name": "width",
+                    "type": "Real",
+                    "isAttr": true
+                }, {
+                    "name": "height",
+                    "type": "Real",
+                    "isAttr": true
+                }]
+            }],
+            "prefix": "dc",
+            "associations": []
+        }
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\bpmn-moddle\\resources\\bpmn\\json\\di.json": [function(require, module, exports) {
+        module.exports = {
+            "name": "DI",
+            "uri": "http://www.omg.org/spec/DD/20100524/DI",
+            "types": [{
+                "name": "DiagramElement",
+                "isAbstract": true,
+                "properties": [{
+                    "name": "extension",
+                    "type": "Extension"
+                }, {
+                    "name": "owningDiagram",
+                    "type": "Diagram",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true
+                }, {
+                    "name": "owningElement",
+                    "type": "DiagramElement",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true
+                }, {
+                    "name": "modelElement",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true,
+                    "type": "Element"
+                }, {
+                    "name": "style",
+                    "type": "Style",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true
+                }, {
+                    "name": "ownedElement",
+                    "type": "DiagramElement",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isMany": true
+                }]
+            }, {
+                "name": "Node",
+                "isAbstract": true,
+                "superClass": [
+                    "DiagramElement"
+                ]
+            }, {
+                "name": "Edge",
+                "isAbstract": true,
+                "superClass": [
+                    "DiagramElement"
+                ],
+                "properties": [{
+                    "name": "source",
+                    "type": "DiagramElement",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true
+                }, {
+                    "name": "target",
+                    "type": "DiagramElement",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isReference": true
+                }, {
+                    "name": "waypoint",
+                    "isUnique": false,
+                    "isMany": true,
+                    "type": "dc:Point",
+                    "serialize": "xsi:type"
+                }]
+            }, {
+                "name": "Diagram",
+                "isAbstract": true,
+                "properties": [{
+                    "name": "rootElement",
+                    "type": "DiagramElement",
+                    "isReadOnly": true,
+                    "isVirtual": true
+                }, {
+                    "name": "name",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "documentation",
+                    "isAttr": true,
+                    "type": "String"
+                }, {
+                    "name": "resolution",
+                    "isAttr": true,
+                    "type": "Real"
+                }, {
+                    "name": "ownedStyle",
+                    "type": "Style",
+                    "isReadOnly": true,
+                    "isVirtual": true,
+                    "isMany": true
+                }]
+            }, {
+                "name": "Shape",
+                "isAbstract": true,
+                "superClass": [
+                    "Node"
+                ],
+                "properties": [{
+                    "name": "bounds",
+                    "type": "dc:Bounds"
+                }]
+            }, {
+                "name": "Plane",
+                "isAbstract": true,
+                "superClass": [
+                    "Node"
+                ],
+                "properties": [{
+                    "name": "planeElement",
+                    "type": "DiagramElement",
+                    "subsettedProperty": "DiagramElement-ownedElement",
+                    "isMany": true
+                }]
+            }, {
+                "name": "LabeledEdge",
+                "isAbstract": true,
+                "superClass": [
+                    "Edge"
+                ],
+                "properties": [{
+                    "name": "ownedLabel",
+                    "type": "Label",
+                    "isReadOnly": true,
+                    "subsettedProperty": "DiagramElement-ownedElement",
+                    "isVirtual": true,
+                    "isMany": true
+                }]
+            }, {
+                "name": "LabeledShape",
+                "isAbstract": true,
+                "superClass": [
+                    "Shape"
+                ],
+                "properties": [{
+                    "name": "ownedLabel",
+                    "type": "Label",
+                    "isReadOnly": true,
+                    "subsettedProperty": "DiagramElement-ownedElement",
+                    "isVirtual": true,
+                    "isMany": true
+                }]
+            }, {
+                "name": "Label",
+                "isAbstract": true,
+                "superClass": [
+                    "Node"
+                ],
+                "properties": [{
+                    "name": "bounds",
+                    "type": "dc:Bounds"
+                }]
+            }, {
+                "name": "Style",
+                "isAbstract": true
+            }, {
+                "name": "Extension",
+                "properties": [{
+                    "name": "values",
+                    "type": "Element",
+                    "isMany": true
+                }]
+            }],
+            "associations": [],
+            "prefix": "di",
+            "xml": {
+                "tagAlias": "lowerCase"
+            }
+        }
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('diagram-js/lib/features/interaction-events')],
+            __init__: ['directEditing'],
+            directEditing: ['type', require('./lib/DirectEditing')]
+        };
+    }, {
+        "./lib/DirectEditing": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\lib\\DirectEditing.js",
+        "diagram-js/lib/features/interaction-events": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\lib\\DirectEditing.js": [function(require, module, exports) {
+        'use strict';
+
+        var bind = require('lodash/function/bind'),
+            find = require('lodash/collection/find');
+
+        var TextBox = require('./TextBox');
+
+
+        /**
+         * A direct editing component that allows users to edit an elements text
+         * directly in the diagram
+         * 
+         * @param {EventBus}
+         *            eventBus the event bus
+         */
+        function DirectEditing(eventBus, canvas) {
+
+            this._eventBus = eventBus;
+
+            this._providers = [];
+            this._textbox = new TextBox({
+                container: canvas.getContainer(),
+                keyHandler: bind(this._handleKey, this)
+            });
+        }
+
+        DirectEditing.$inject = ['eventBus', 'canvas'];
+
+
+        /**
+         * Register a direct editing provider
+         * 
+         * @param {Object}
+         *            provider the provider, must expose an #activate(element) method
+         *            that returns an activation context ({ bounds: {x, y, width, height },
+         *            text }) if direct editing is available for the given element.
+         *            Additionally the provider must expose a #update(element, value)
+         *            method to receive direct editing updates.
+         */
+        DirectEditing.prototype.registerProvider = function(provider) {
+            this._providers.push(provider);
+        };
+
+
+        /**
+         * Returns true if direct editing is currently active
+         * 
+         * @return {Boolean}
+         */
+        DirectEditing.prototype.isActive = function() {
+            return !!this._active;
+        };
+
+
+        /**
+         * Cancel direct editing, if it is currently active
+         */
+        DirectEditing.prototype.cancel = function() {
+            if (!this._active) {
+                return;
+            }
+
+            this._fire('cancel');
+            this.close();
+        };
+
+
+        DirectEditing.prototype._fire = function(event) {
+            this._eventBus.fire('directEditing.' + event, {
+                active: this._active
+            });
+        };
+
+        DirectEditing.prototype.close = function() {
+            this._textbox.destroy();
+
+            this._fire('deactivate');
+
+            this._active = null;
+        };
+
+
+        DirectEditing.prototype.complete = function() {
+
+            var active = this._active;
+
+            if (!active) {
+                return;
+            }
+
+            var text = this.getValue();
+
+            if (text !== active.context.text) {
+                active.provider.update(active.element, text, active.context.text);
+            }
+
+            this._fire('complete');
+
+            this.close();
+        };
+
+
+        DirectEditing.prototype.getValue = function() {
+            return this._textbox.getValue();
+        };
+
+
+        DirectEditing.prototype._handleKey = function(e) {
+
+            // stop bubble
+            e.stopPropagation();
+
+            var key = e.keyCode || e.charCode;
+
+            // ESC
+            if (key === 27) {
+                e.preventDefault();
+                return this.cancel();
+            }
+
+            // Enter
+            if (key === 13 && !e.shiftKey) {
+                e.preventDefault();
+                return this.complete();
+            }
+        };
+
+
+        /**
+         * Activate direct editing on the given element
+         * 
+         * @param {Object}
+         *            ElementDescriptor the descriptor for a shape or connection
+         * @return {Boolean} true if the activation was possible
+         */
+        DirectEditing.prototype.activate = function(element) {
+
+            if (this.isActive()) {
+                this.cancel();
+            }
+
+            // the direct editing context
+            var context;
+
+            var provider = find(this._providers, function(p) {
+                return !!(context = p.activate(element)) ? p : null;
+            });
+
+            // check if activation took place
+            if (context) {
+                this._textbox.create(context.bounds, context.style, context.text);
+
+                this._active = {
+                    element: element,
+                    context: context,
+                    provider: provider
+                };
+
+                this._fire('activate');
+            }
+
+            return !!context;
+        };
+
+
+        module.exports = DirectEditing;
+    }, {
+        "./TextBox": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\lib\\TextBox.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/function/bind": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\bind.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\diagram-js-direct-editing\\lib\\TextBox.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            domEvent = require('min-dom/lib/event'),
+            domRemove = require('min-dom/lib/remove');
+
+        function stopPropagation(event) {
+            event.stopPropagation();
+        }
+
+        function TextBox(options) {
+
+            this.container = options.container;
+            this.textarea = document.createElement('textarea');
+
+            this.keyHandler = options.keyHandler || function() {};
+        }
+
+        module.exports = TextBox;
+
+
+        TextBox.prototype.create = function(bounds, style, value) {
+
+            var textarea = this.textarea,
+                container = this.container;
+
+            assign(textarea.style, {
+                width: bounds.width + 'px',
+                height: bounds.height + 'px',
+                left: bounds.x + 'px',
+                top: bounds.y + 'px',
+                position: 'absolute',
+                textAlign: 'center',
+                boxSizing: 'border-box'
+            }, style || {});
+
+            textarea.value = value;
+            textarea.title = 'Press SHIFT+Enter for line feed';
+
+            domEvent.bind(textarea, 'keydown', this.keyHandler);
+            domEvent.bind(textarea, 'mousedown', stopPropagation);
+
+            container.appendChild(textarea);
+
+            setTimeout(function() {
+                if (textarea.parent) {
+                    textarea.select();
+                }
+                textarea.focus();
+            }, 100);
+        };
+
+        TextBox.prototype.destroy = function() {
+            var textarea = this.textarea;
+
+            textarea.value = '';
+
+            domEvent.unbind(textarea, 'keydown', this.keyHandler);
+            domEvent.unbind(textarea, 'mousedown', stopPropagation);
+
+            domRemove(textarea);
+        };
+
+        TextBox.prototype.getValue = function() {
+            return this.textarea.value;
+        };
+
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\event.js",
+        "min-dom/lib/remove": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\remove.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\ids\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        var hat = require('hat');
+
+
+        /**
+         * Create a new id generator / cache instance.
+         * 
+         * You may optionally provide a seed that is used internally.
+         * 
+         * @param {Seed}
+         *            seed
+         */
+        function Ids(seed) {
+            seed = seed || [128, 36, 1];
+            this._seed = seed.length ? hat.rack(seed[0], seed[1], seed[2]) : seed;
+        }
+
+        module.exports = Ids;
+
+        /**
+         * Generate a next id.
+         * 
+         * @param {Object}
+         *            [element] element to bind the id to
+         * 
+         * @return {String} id
+         */
+        Ids.prototype.next = function(element) {
+            return this._seed(element || true);
+        };
+
+        /**
+         * Generate a next id with a given prefix.
+         * 
+         * @param {Object}
+         *            [element] element to bind the id to
+         * 
+         * @return {String} id
+         */
+        Ids.prototype.nextPrefixed = function(prefix, element) {
+            var id;
+
+            do {
+                id = prefix + this.next(true);
+            } while (this.assigned(id));
+
+            // claim {prefix}{random}
+            this.claim(id, element);
+
+            // return
+            return id;
+        };
+
+        /**
+         * Manually claim an existing id.
+         * 
+         * @param {String}
+         *            id
+         * @param {String}
+         *            [element] element the id is claimed by
+         */
+        Ids.prototype.claim = function(id, element) {
+            this._seed.set(id, element || true);
+        };
+
+        /**
+         * Returns true if the given id has already been assigned.
+         * 
+         * @param {String}
+         *            id
+         * @return {Boolean}
+         */
+        Ids.prototype.assigned = function(id) {
+            return this._seed.get(id) || false;
+        };
+    }, {
+        "hat": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\ids\\node_modules\\hat\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\ids\\node_modules\\hat\\index.js": [function(require, module, exports) {
+        var hat = module.exports = function(bits, base) {
+            if (!base) base = 16;
+            if (bits === undefined) bits = 128;
+            if (bits <= 0) return '0';
+
+            var digits = Math.log(Math.pow(2, bits)) / Math.log(base);
+            for (var i = 2; digits === Infinity; i *= 2) {
+                digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
+            }
+
+            var rem = digits - Math.floor(digits);
+
+            var res = '';
+
+            for (var i = 0; i < Math.floor(digits); i++) {
+                var x = Math.floor(Math.random() * base).toString(base);
+                res = x + res;
+            }
+
+            if (rem) {
+                var b = Math.pow(base, rem);
+                var x = Math.floor(Math.random() * b).toString(base);
+                res = x + res;
+            }
+
+            var parsed = parseInt(res, base);
+            if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
+                return hat(bits, base)
+            } else return res;
+        };
+
+        hat.rack = function(bits, base, expandBy) {
+            var fn = function(data) {
+                var iters = 0;
+                do {
+                    if (iters++ > 10) {
+                        if (expandBy) bits += expandBy;
+                        else throw new Error('too many ID collisions, use more bits')
+                    }
+
+                    var id = hat(bits, base);
+                } while (Object.hasOwnProperty.call(hats, id));
+
+                hats[id] = data;
+                return id;
+            };
+            var hats = fn.hats = {};
+
+            fn.get = function(id) {
+                return fn.hats[id];
+            };
+
+            fn.set = function(id, value) {
+                fn.hats[id] = value;
+                return fn;
+            };
+
+            fn.bits = bits || 128;
+            fn.base = base || 16;
+            return fn;
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js": [function(require, module, exports) {
+        if (typeof Object.create === 'function') {
+            // implementation from standard node.js 'util' module
+            module.exports = function inherits(ctor, superCtor) {
+                ctor.super_ = superCtor
+                ctor.prototype = Object.create(superCtor.prototype, {
+                    constructor: {
+                        value: ctor,
+                        enumerable: false,
+                        writable: true,
+                        configurable: true
+                    }
+                });
+            };
+        } else {
+            // old school shim for old browsers
+            module.exports = function inherits(ctor, superCtor) {
+                ctor.super_ = superCtor
+                var TempCtor = function() {}
+                TempCtor.prototype = superCtor.prototype
+                ctor.prototype = new TempCtor()
+                ctor.prototype.constructor = ctor
+            }
+        }
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\domify.js": [function(require, module, exports) {
+        module.exports = require('domify');
+    }, {
+        "domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\domify\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\event.js": [function(require, module, exports) {
+        module.exports = require('component-event');
+    }, {
+        "component-event": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\query.js": [function(require, module, exports) {
+        module.exports = require('component-query');
+    }, {
+        "component-query": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\remove.js": [function(require, module, exports) {
+        module.exports = function(el) {
+            el.parentNode && el.parentNode.removeChild(el);
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js": [function(require, module, exports) {
+        var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
+            unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
+            prefix = bind !== 'addEventListener' ? 'on' : '';
+
+        /**
+         * Bind `el` event `type` to `fn`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            type
+         * @param {Function}
+         *            fn
+         * @param {Boolean}
+         *            capture
+         * @return {Function}
+         * @api public
+         */
+
+        exports.bind = function(el, type, fn, capture) {
+            el[bind](prefix + type, fn, capture || false);
+            return fn;
+        };
+
+        /**
+         * Unbind `el` event `type`'s callback `fn`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            type
+         * @param {Function}
+         *            fn
+         * @param {Boolean}
+         *            capture
+         * @return {Function}
+         * @api public
+         */
+
+        exports.unbind = function(el, type, fn, capture) {
+            el[unbind](prefix + type, fn, capture || false);
+            return fn;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js": [function(require, module, exports) {
+        function one(selector, el) {
+            return el.querySelector(selector);
+        }
+
+        exports = module.exports = function(selector, el) {
+            el = el || document;
+            return one(selector, el);
+        };
+
+        exports.all = function(selector, el) {
+            el = el || document;
+            return el.querySelectorAll(selector);
+        };
+
+        exports.engine = function(obj) {
+            if (!obj.one) throw new Error('.one callback required');
+            if (!obj.all) throw new Error('.all callback required');
+            one = obj.one;
+            exports.all = obj.all;
+            return exports;
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\domify\\index.js": [function(require, module, exports) {
+
+        /**
+         * Expose `parse`.
+         */
+
+        module.exports = parse;
+
+        /**
+         * Tests for browser support.
+         */
+
+        var div = document.createElement('div');
+        // Setup
+        div.innerHTML = '  <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
+        // Make sure that link elements get serialized correctly by innerHTML
+        // This requires a wrapper element in IE
+        var innerHTMLBug = !div.getElementsByTagName('link').length;
+        div = undefined;
+
+        /**
+         * Wrap map from jquery.
+         */
+
+        var map = {
+            legend: [1, '<fieldset>', '</fieldset>'],
+            tr: [2, '<table><tbody>', '</tbody></table>'],
+            col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
+            // for script/link/style tags to work in IE6-8, you have to wrap
+            // in a div with a non-whitespace character in front, ha!
+            _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
+        };
+
+        map.td =
+            map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
+
+        map.option =
+            map.optgroup = [1, '<select multiple="multiple">', '</select>'];
+
+        map.thead =
+            map.tbody =
+            map.colgroup =
+            map.caption =
+            map.tfoot = [1, '<table>', '</table>'];
+
+        map.polyline =
+            map.ellipse =
+            map.polygon =
+            map.circle =
+            map.text =
+            map.line =
+            map.path =
+            map.rect =
+            map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>'];
+
+        /**
+         * Parse `html` and return a DOM Node instance, which could be a TextNode, HTML
+         * DOM Node of some kind (<div> for example), or a DocumentFragment instance,
+         * depending on the contents of the `html` string.
+         * 
+         * @param {String}
+         *            html - HTML string to "domify"
+         * @param {Document}
+         *            doc - The `document` instance to create the Node for
+         * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
+         * @api private
+         */
+
+        function parse(html, doc) {
+            if ('string' != typeof html) throw new TypeError('String expected');
+
+            // default to the global `document` object
+            if (!doc) doc = document;
+
+            // tag name
+            var m = /<([\w:]+)/.exec(html);
+            if (!m) return doc.createTextNode(html);
+
+            html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing
+            // whitespace
+
+            var tag = m[1];
+
+            // body support
+            if (tag == 'body') {
+                var el = doc.createElement('html');
+                el.innerHTML = html;
+                return el.removeChild(el.lastChild);
+            }
+
+            // wrap map
+            var wrap = map[tag] || map._default;
+            var depth = wrap[0];
+            var prefix = wrap[1];
+            var suffix = wrap[2];
+            var el = doc.createElement('div');
+            el.innerHTML = prefix + html + suffix;
+            while (depth--) el = el.lastChild;
+
+            // one element
+            if (el.firstChild == el.lastChild) {
+                return el.removeChild(el.firstChild);
+            }
+
+            // several elements
+            var fragment = doc.createDocumentFragment();
+            while (el.firstChild) {
+                fragment.appendChild(el.removeChild(el.firstChild));
+            }
+
+            return fragment;
+        }
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\index.js": [function(require, module, exports) {
+        module.exports = require('./lib/refs');
+
+        module.exports.Collection = require('./lib/collection');
+    }, {
+        "./lib/collection": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\collection.js",
+        "./lib/refs": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\refs.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\collection.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * An empty collection stub. Use {@link RefsCollection.extend} to extend a
+         * collection with ref semantics.
+         * 
+         * @classdesc A change and inverse-reference aware collection with set
+         *            semantics.
+         * 
+         * @class RefsCollection
+         */
+        function RefsCollection() {}
+
+        /**
+         * Extends a collection with {@link Refs} aware methods
+         * 
+         * @memberof RefsCollection
+         * @static
+         * 
+         * @param {Array
+         *            <Object>} collection
+         * @param {Refs}
+         *            refs instance
+         * @param {Object}
+         *            property represented by the collection
+         * @param {Object}
+         *            target object the collection is attached to
+         * 
+         * @return {RefsCollection<Object>} the extended array
+         */
+        function extend(collection, refs, property, target) {
+
+            var inverseProperty = property.inverse;
+
+            /**
+             * Removes the given element from the array and returns it.
+             * 
+             * @method RefsCollection#remove
+             * 
+             * @param {Object}
+             *            element the element to remove
+             */
+            collection.remove = function(element) {
+                var idx = this.indexOf(element);
+                if (idx !== -1) {
+                    this.splice(idx, 1);
+
+                    // unset inverse
+                    refs.unset(element, inverseProperty, target);
+                }
+
+                return element;
+            };
+
+            /**
+             * Returns true if the collection contains the given element
+             * 
+             * @method RefsCollection#contains
+             * 
+             * @param {Object}
+             *            element the element to check for
+             */
+            collection.contains = function(element) {
+                return this.indexOf(element) !== -1;
+            };
+
+            /**
+             * Adds an element to the array, unless it exists already (set semantics).
+             * 
+             * @method RefsCollection#add
+             * 
+             * @param {Object}
+             *            element the element to add
+             */
+            collection.add = function(element) {
+
+                if (!this.contains(element)) {
+                    this.push(element);
+
+                    // set inverse
+                    refs.set(element, inverseProperty, target);
+                }
+            };
+
+            return collection;
+        }
+
+
+        module.exports.extend = extend;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\refs.js": [function(require, module, exports) {
+        'use strict';
+
+        var Collection = require('./collection');
+
+        function hasOwnProperty(e, property) {
+            return Object.prototype.hasOwnProperty.call(e, property.name || property);
+        }
+
+
+        function defineCollectionProperty(ref, property, target) {
+            Object.defineProperty(target, property.name, {
+                enumerable: property.enumerable,
+                value: Collection.extend(target[property.name] || [], ref, property, target)
+            });
+        }
+
+
+        function defineProperty(ref, property, target) {
+
+            var inverseProperty = property.inverse;
+
+            var _value = target[property.name];
+
+            Object.defineProperty(target, property.name, {
+                enumerable: property.enumerable,
+
+                get: function() {
+                    return _value;
+                },
+
+                set: function(value) {
+
+                    // return if we already performed all changes
+                    if (value === _value) {
+                        return;
+                    }
+
+                    var old = _value;
+
+                    // temporary set null
+                    _value = null;
+
+                    if (old) {
+                        ref.unset(old, inverseProperty, target);
+                    }
+
+                    // set new value
+                    _value = value;
+
+                    // set inverse value
+                    ref.set(_value, inverseProperty, target);
+                }
+            });
+
+        }
+
+        /**
+         * Creates a new references object defining two inversly related attribute
+         * descriptors a and b.
+         * 
+         * <p>
+         * When bound to an object using {@link Refs#bind} the references get activated
+         * and ensure that add and remove operations are applied reversely, too.
+         * </p>
+         * 
+         * <p>
+         * For attributes represented as collections {@link Refs} provides the
+         * {@link RefsCollection#add}, {@link RefsCollection#remove} and
+         * {@link RefsCollection#contains} extensions that must be used to properly hook
+         * into the inverse change mechanism.
+         * </p>
+         * 
+         * @class Refs
+         * 
+         * @classdesc A bi-directional reference between two attributes.
+         * 
+         * @param {Refs.AttributeDescriptor}
+         *            a property descriptor
+         * @param {Refs.AttributeDescriptor}
+         *            b property descriptor
+         * 
+         * @example
+         * 
+         * var refs = Refs({ name: 'wheels', collection: true, enumerable: true }, {
+         * name: 'car' });
+         * 
+         * var car = { name: 'toyota' }; var wheels = [{ pos: 'front-left' }, { pos:
+         * 'front-right' }];
+         * 
+         * refs.bind(car, 'wheels');
+         * 
+         * car.wheels // [] car.wheels.add(wheels[0]); car.wheels.add(wheels[1]);
+         * 
+         * car.wheels // [{ pos: 'front-left' }, { pos: 'front-right' }]
+         * 
+         * wheels[0].car // { name: 'toyota' }; car.wheels.remove(wheels[0]);
+         * 
+         * wheels[0].car // undefined
+         */
+        function Refs(a, b) {
+
+            if (!(this instanceof Refs)) {
+                return new Refs(a, b);
+            }
+
+            // link
+            a.inverse = b;
+            b.inverse = a;
+
+            this.props = {};
+            this.props[a.name] = a;
+            this.props[b.name] = b;
+        }
+
+        /**
+         * Binds one side of a bi-directional reference to a target object.
+         * 
+         * @memberOf Refs
+         * 
+         * @param {Object}
+         *            target
+         * @param {String}
+         *            property
+         */
+        Refs.prototype.bind = function(target, property) {
+            if (typeof property === 'string') {
+                if (!this.props[property]) {
+                    throw new Error('no property <' + property + '> in ref');
+                }
+                property = this.props[property];
+            }
+
+            if (property.collection) {
+                defineCollectionProperty(this, property, target);
+            } else {
+                defineProperty(this, property, target);
+            }
+        };
+
+        Refs.prototype.ensureBound = function(target, property) {
+            if (!hasOwnProperty(target, property)) {
+                this.bind(target, property);
+            }
+        };
+
+        Refs.prototype.unset = function(target, property, value) {
+
+            if (target) {
+                this.ensureBound(target, property);
+
+                if (property.collection) {
+                    target[property.name].remove(value);
+                } else {
+                    target[property.name] = undefined;
+                }
+            }
+        };
+
+        Refs.prototype.set = function(target, property, value) {
+
+            if (target) {
+                this.ensureBound(target, property);
+
+                if (property.collection) {
+                    target[property.name].add(value);
+                } else {
+                    target[property.name] = value;
+                }
+            }
+        };
+
+        module.exports = Refs;
+
+
+        /**
+         * An attribute descriptor to be used specify an attribute in a {@link Refs}
+         * instance
+         * 
+         * @typedef {Object} Refs.AttributeDescriptor
+         * @property {String} name
+         * @property {boolean} [collection=false]
+         * @property {boolean} [enumerable=false]
+         */
+    }, {
+        "./collection": "\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\collection.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\index.js": [function(require, module, exports) {
+        module.exports = require('./lib/Diagram');
+    }, {
+        "./lib/Diagram": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\Diagram.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\Diagram.js": [function(require, module, exports) {
+        'use strict';
+
+        var di = require('didi');
+
+
+        /**
+         * Bootstrap an injector from a list of modules, instantiating a number of
+         * default components
+         * 
+         * @ignore
+         * @param {Array
+         *            <didi.Module>} bootstrapModules
+         * 
+         * @return {didi.Injector} a injector to use to access the components
+         */
+        function bootstrap(bootstrapModules) {
+
+            var modules = [],
+                components = [];
+
+            function hasModule(m) {
+                return modules.indexOf(m) >= 0;
+            }
+
+            function addModule(m) {
+                modules.push(m);
+            }
+
+            function visit(m) {
+                if (hasModule(m)) {
+                    return;
+                }
+
+                (m.__depends__ || []).forEach(visit);
+
+                if (hasModule(m)) {
+                    return;
+                }
+
+                addModule(m);
+
+                (m.__init__ || []).forEach(function(c) {
+                    components.push(c);
+                });
+            }
+
+            bootstrapModules.forEach(visit);
+
+            var injector = new di.Injector(modules);
+
+            components.forEach(function(c) {
+
+                try {
+                    // eagerly resolve component (fn or string)
+                    injector[typeof c === 'string' ? 'get' : 'invoke'](c);
+                } catch (e) {
+                    console.error('Failed to instantiate component');
+                    console.error(e.stack);
+
+                    throw e;
+                }
+            });
+
+            return injector;
+        }
+
+        /**
+         * Creates an injector from passed options.
+         * 
+         * @ignore
+         * @param {Object}
+         *            options
+         * @return {didi.Injector}
+         */
+        function createInjector(options) {
+
+            options = options || {};
+
+            var configModule = {
+                'config': ['value', options]
+            };
+
+            var coreModule = require('./core');
+
+            var modules = [configModule, coreModule].concat(options.modules || []);
+
+            return bootstrap(modules);
+        }
+
+
+        /**
+         * The main diagram-js entry point that bootstraps the diagram with the given
+         * configuration.
+         * 
+         * To register extensions with the diagram, pass them as Array<didi.Module> to
+         * the constructor.
+         * 
+         * @class djs.Diagram
+         * @memberOf djs
+         * @constructor
+         * 
+         * @example
+         * 
+         * <caption>Creating a plug-in that logs whenever a shape is added to the
+         * canvas.</caption>
+         *  // plug-in implemenentation function MyLoggingPlugin(eventBus) {
+         * eventBus.on('shape.added', function(event) { console.log('shape ',
+         * event.shape, ' was added to the diagram'); }); }
+         *  // export as module module.exports = { __init__: [ 'myLoggingPlugin' ],
+         * myLoggingPlugin: [ 'type', MyLoggingPlugin ] };
+         * 
+         *  // instantiate the diagram with the new plug-in
+         * 
+         * var diagram = new Diagram({ modules: [ require('path-to-my-logging-plugin') ]
+         * });
+         * 
+         * diagram.invoke([ 'canvas', function(canvas) { // add shape to drawing canvas
+         * canvas.addShape({ x: 10, y: 10 }); });
+         *  // 'shape ... was added to the diagram' logged to console
+         * 
+         * @param {Object}
+         *            options
+         * @param {Array
+         *            <didi.Module>} [options.modules] external modules to instantiate
+         *            with the diagram
+         * @param {didi.Injector}
+         *            [injector] an (optional) injector to bootstrap the diagram with
+         */
+        function Diagram(options, injector) {
+
+            // create injector unless explicitly specified
+            this.injector = injector = injector || createInjector(options);
+
+            // API
+
+            /**
+             * Resolves a diagram service
+             * 
+             * @method Diagram#get
+             * 
+             * @param {String}
+             *            name the name of the diagram service to be retrieved
+             * @param {Object}
+             *            [locals] a number of locals to use to resolve certain
+             *            dependencies
+             */
+            this.get = injector.get;
+
+            /**
+             * Executes a function into which diagram services are injected
+             * 
+             * @method Diagram#invoke
+             * 
+             * @param {Function|Object[]}
+             *            fn the function to resolve
+             * @param {Object}
+             *            locals a number of locals to use to resolve certain
+             *            dependencies
+             */
+            this.invoke = injector.invoke;
+
+            // init
+
+            // indicate via event
+
+
+            /**
+             * An event indicating that all plug-ins are loaded.
+             * 
+             * Use this event to fire other events to interested plug-ins
+             * 
+             * @memberOf Diagram
+             * 
+             * @event diagram.init
+             * 
+             * @example
+             * 
+             * eventBus.on('diagram.init', function() { eventBus.fire('my-custom-event', {
+             * foo: 'BAR' }); });
+             * 
+             * @type {Object}
+             */
+            this.get('eventBus').fire('diagram.init');
+        }
+
+        module.exports = Diagram;
+
+
+        /**
+         * Destroys the diagram
+         * 
+         * @method Diagram#destroy
+         */
+        Diagram.prototype.destroy = function() {
+            this.get('eventBus').fire('diagram.destroy');
+        };
+    }, {
+        "./core": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\index.js",
+        "didi": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            isFunction = require('lodash/lang/isFunction'),
+            isArray = require('lodash/lang/isArray');
+
+
+        /**
+         * A utility that can be used to plug-in into the command execution for
+         * extension and/or validation.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * 
+         * @example
+         * 
+         * var inherits = require('inherits');
+         * 
+         * var CommandInterceptor =
+         * require('diagram-js/lib/command/CommandInterceptor');
+         * 
+         * function CommandLogger(eventBus) { CommandInterceptor.call(this, eventBus);
+         * 
+         * this.preExecute(function(event) { console.log('command pre-execute', event);
+         * }); }
+         * 
+         * inherits(CommandLogger, CommandInterceptor);
+         * 
+         */
+        function CommandInterceptor(eventBus) {
+            this._eventBus = eventBus;
+        }
+
+        CommandInterceptor.$inject = ['eventBus'];
+
+        module.exports = CommandInterceptor;
+
+        function unwrapEvent(fn) {
+            return function(event) {
+                return fn(event.context, event.command, event);
+            };
+        }
+
+        /**
+         * Register an interceptor for a command execution
+         * 
+         * @param {String|Array
+         *            <String>} [events] list of commands to register on
+         * @param {String}
+         *            [hook] command hook, i.e. preExecute, executed to listen on
+         * @param {Function}
+         *            handlerFn interceptor to be invoked with (event)
+         * @param {Boolean}
+         *            unwrap if true, unwrap the event and pass (context, command,
+         *            event) to the listener instead
+         */
+        CommandInterceptor.prototype.on = function(events, hook, handlerFn, unwrap) {
+
+            if (isFunction(hook)) {
+                unwrap = handlerFn;
+                handlerFn = hook;
+                hook = null;
+            }
+
+            if (!isFunction(handlerFn)) {
+                throw new Error('handlerFn must be a function');
+            }
+
+            if (!isArray(events)) {
+                events = [events];
+            }
+
+            var eventBus = this._eventBus;
+
+            forEach(events, function(event) {
+                // concat commandStack(.event)?(.hook)?
+                var fullEvent = ['commandStack', event, hook].filter(function(e) {
+                    return e;
+                }).join('.');
+
+                eventBus.on(fullEvent, unwrap ? unwrapEvent(handlerFn) : handlerFn);
+            });
+        };
+
+
+        var hooks = [
+            'canExecute',
+            'preExecute',
+            'execute',
+            'executed',
+            'postExecute',
+            'revert',
+            'reverted'
+        ];
+
+        /*
+         * Install hook shortcuts
+         * 
+         * This will generate the CommandInterceptor#(preExecute|...|reverted) methods
+         * which will in term forward to CommandInterceptor#on.
+         */
+        forEach(hooks, function(hook) {
+            CommandInterceptor.prototype[hook] = function(events, fn, unwrap) {
+                if (isFunction(events)) {
+                    unwrap = fn;
+                    fn = events;
+                    events = null;
+                }
+
+                this.on(events, hook, fn, unwrap);
+            };
+        });
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/lang/isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandStack.js": [function(require, module, exports) {
+        'use strict';
+
+        var unique = require('lodash/array/unique'),
+            isArray = require('lodash/lang/isArray'),
+            assign = require('lodash/object/assign');
+
+        var InternalEvent = require('../core/EventBus').Event;
+
+
+        /**
+         * A service that offers un- and redoable execution of commands.
+         * 
+         * The command stack is responsible for executing modeling actions in a un- and
+         * redoable manner. To do this it delegates the actual command execution to
+         * {@link CommandHandler}s.
+         * 
+         * Command handlers provide {@link CommandHandler#execute(ctx)} and
+         * {@link CommandHandler#revert(ctx)} methods to un- and redo a command
+         * identified by a command context.
+         * 
+         *  ## Life-Cycle events
+         * 
+         * In the process the command stack fires a number of life-cycle events that
+         * other components to participate in the command execution.
+         *  * preExecute * execute * executed * postExecute * revert * reverted
+         * 
+         * A special event is used for validating, whether a command can be performed
+         * prior to its execution.
+         *  * canExecute
+         * 
+         * Each of the events is fired as `commandStack.{eventName}` and
+         * `commandStack.{commandName}.{eventName}`, respectively. This gives components
+         * fine grained control on where to hook into.
+         * 
+         * The event object fired transports `command`, the name of the command and
+         * `context`, the command context.
+         * 
+         *  ## Creating Command Handlers
+         * 
+         * Command handlers should provide the {@link CommandHandler#execute(ctx)} and
+         * {@link CommandHandler#revert(ctx)} methods to implement redoing and undoing
+         * of a command. They must ensure undo is performed properly in order not to
+         * break the undo chain.
+         * 
+         * Command handlers may execute other modeling operations (and thus commands) in
+         * their `preExecute` and `postExecute` phases. The command stack will properly
+         * group all commands together into a logical unit that may be re- and undone
+         * atomically.
+         * 
+         * Command handlers must not execute other commands from within their core
+         * implementation (`execute`, `revert`).
+         * 
+         *  ## Change Tracking
+         * 
+         * During the execution of the CommandStack it will keep track of all elements
+         * that have been touched during the command's execution.
+         * 
+         * At the end of the CommandStack execution it will notify interested components
+         * via an 'elements.changed' event with all the dirty elements.
+         * 
+         * The event can be picked up by components that are interested in the fact that
+         * elements have been changed. One use case for this is updating their graphical
+         * representation after moving / resizing or deletion.
+         * 
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Injector}
+         *            injector
+         */
+        function CommandStack(eventBus, injector) {
+            /**
+             * A map of all registered command handlers.
+             * 
+             * @type {Object}
+             */
+            this._handlerMap = {};
+
+            /**
+             * A stack containing all re/undoable actions on the diagram
+             * 
+             * @type {Array<Object>}
+             */
+            this._stack = [];
+
+            /**
+             * The current index on the stack
+             * 
+             * @type {Number}
+             */
+            this._stackIdx = -1;
+
+            /**
+             * Current active commandStack execution
+             * 
+             * @type {Object}
+             */
+            this._currentExecution = {
+                actions: [],
+                dirty: []
+            };
+
+
+            this._injector = injector;
+            this._eventBus = eventBus;
+
+            this._uid = 1;
+            this._selectedModel = selected_model;
+            
+            commandStackList.push(this);
+        }
+
+        CommandStack.$inject = ['eventBus', 'injector'];
+        
+        module.exports = CommandStack;
+
+
+        /**
+         * Execute a command
+         * 
+         * @param {String}
+         *            command the command to execute
+         * @param {Object}
+         *            context the environment to execute the command in
+         */
+        CommandStack.prototype.execute = function(command, context) {
+            if (!command) {
+                throw new Error('command required');
+            }
+
+            var action = {
+                command: command,
+                context: context
+            };
+
+            this._pushAction(action);
+            this._internalExecute(action);
+            this._popAction(action);
+        };
+
+
+        /**
+         * Ask whether a given command can be executed.
+         * 
+         * Implementors may hook into the mechanism on two ways:
+         *  * in event listeners:
+         * 
+         * Users may prevent the execution via an event listener. It must prevent the
+         * default action for `commandStack.(<command>.)canExecute` events.
+         *  * in command handlers:
+         * 
+         * If the method {@link CommandHandler#canExecute} is implemented in a handler
+         * it will be called to figure out whether the execution is allowed.
+         * 
+         * @param {String}
+         *            command the command to execute
+         * @param {Object}
+         *            context the environment to execute the command in
+         * 
+         * @return {Boolean} true if the command can be executed
+         */
+        CommandStack.prototype.canExecute = function(command, context) {
+
+            var action = {
+                command: command,
+                context: context
+            };
+
+            var handler = this._getHandler(command);
+
+            if (!handler) {
+                return false;
+            }
+
+            var result = this._fire(command, 'canExecute', action);
+
+            // handler#canExecute will only be called if no listener
+            // decided on a result already
+            if (result === undefined && handler.canExecute) {
+                result = handler.canExecute(context);
+            }
+
+            return result;
+        };
+
+
+        /**
+         * Clear the command stack, erasing all undo / redo history
+         */
+        CommandStack.prototype.clear = function() {
+            this._stack.length = 0;
+            this._stackIdx = -1;
+
+            this._fire('changed');
+        };
+
+
+        /**
+         * Undo last command(s)
+         */
+        CommandStack.prototype.undo = function() {
+            var action = this._getUndoAction(),
+                next;
+            if (action) {
+                this._pushAction(action);
+
+                while (action) {
+                    this._internalUndo(action);
+                    next = this._getUndoAction();
+
+                    if (!next || next.id !== action.id) {
+                        break;
+                    }
+
+                    action = next;
+                }
+
+                this._popAction();
+            }
+        };
+
+
+        /**
+         * Redo last command(s)
+         */
+        CommandStack.prototype.redo = function() {
+            var action = this._getRedoAction(),
+                next;
+
+            if (action) {
+                this._pushAction(action);
+
+                while (action) {
+                    this._internalExecute(action, true);
+                    next = this._getRedoAction();
+
+                    if (!next || next.id !== action.id) {
+                        break;
+                    }
+
+                    action = next;
+                }
+
+                this._popAction();
+            }
+        };
+
+
+        /**
+         * Register a handler instance with the command stack
+         * 
+         * @param {String}
+         *            command
+         * @param {CommandHandler}
+         *            handler
+         */
+        CommandStack.prototype.register = function(command, handler) {
+            this._setHandler(command, handler);
+        };
+
+
+        /**
+         * Register a handler type with the command stack by instantiating it and
+         * injecting its dependencies.
+         * 
+         * @param {String}
+         *            command
+         * @param {Function}
+         *            a constructor for a {@link CommandHandler}
+         */
+        CommandStack.prototype.registerHandler = function(command, handlerCls) {
+
+            if (!command || !handlerCls) {
+                throw new Error('command and handlerCls must be defined');
+            }
+
+            var handler = this._injector.instantiate(handlerCls);
+            this.register(command, handler);
+        };
+
+        CommandStack.prototype.canUndo = function() {
+            return !!this._getUndoAction();
+        };
+
+        CommandStack.prototype.canRedo = function() {
+            return !!this._getRedoAction();
+        };
+
+        // //// stack access //////////////////////////////////////
+
+        CommandStack.prototype._getRedoAction = function() {
+            return this._stack[this._stackIdx + 1];
+        };
+
+
+        CommandStack.prototype._getUndoAction = function() {
+            return this._stack[this._stackIdx];
+        };
+
+
+        // //// internal functionality /////////////////////////////
+
+        CommandStack.prototype._internalUndo = function(action) {
+            var command = action.command,
+                context = action.context;
+
+            var handler = this._getHandler(command);
+
+            this._fire(command, 'revert', action);
+
+            this._markDirty(handler.revert(context));
+
+            this._revertedAction(action);
+
+            this._fire(command, 'reverted', action);
+        };
+
+
+        CommandStack.prototype._fire = function(command, qualifier, event) {
+            if (arguments.length < 3) {
+                event = qualifier;
+                qualifier = null;
+            }
+
+            var names = qualifier ? [command + '.' + qualifier, qualifier] : [command],
+                i, name, result;
+
+            event = assign(new InternalEvent(), event);
+
+            for (i = 0; !!(name = names[i]); i++) {
+                result = this._eventBus.fire('commandStack.' + name, event);
+
+                if (event.cancelBubble) {
+                    break;
+                }
+            }
+
+            return result;
+        };
+
+        CommandStack.prototype._createId = function() {
+            return this._uid++;
+        };
+
+
+        CommandStack.prototype._internalExecute = function(action, redo) {
+            var command = action.command,
+                context = action.context;
+
+            var handler = this._getHandler(command);
+
+            if (!handler) {
+                throw new Error('no command handler registered for <' + command + '>');
+            }
+
+            this._pushAction(action);
+
+            if (!redo) {
+                this._fire(command, 'preExecute', action);
+
+                if (handler.preExecute) {
+                    handler.preExecute(context);
+                }
+            }
+
+            this._fire(command, 'execute', action);
+
+            // execute
+            this._markDirty(handler.execute(context));
+
+            // log to stack
+            this._executedAction(action, redo);
+
+            this._fire(command, 'executed', action);
+
+            if (!redo) {
+                if (handler.postExecute) {
+                    handler.postExecute(context);
+                }
+
+                this._fire(command, 'postExecute', action);
+            }
+
+            this._popAction(action);
+        };
+
+
+        CommandStack.prototype._pushAction = function(action) {
+
+            var execution = this._currentExecution,
+                actions = execution.actions;
+
+            var baseAction = actions[0];
+
+            if (!action.id) {
+                action.id = (baseAction && baseAction.id) || this._createId();
+            }
+
+            actions.push(action);
+        };
+
+
+        CommandStack.prototype._popAction = function() {
+            var execution = this._currentExecution,
+                actions = execution.actions,
+                dirty = execution.dirty;
+
+            actions.pop();
+
+            if (!actions.length) {
+                this._eventBus.fire('elements.changed', {
+                    elements: unique(dirty)
+                });
+
+                dirty.length = 0;
+
+                this._fire('changed');
+            }
+        };
+
+
+        CommandStack.prototype._markDirty = function(elements) {
+            var execution = this._currentExecution;
+
+            if (!elements) {
+                return;
+            }
+
+            elements = isArray(elements) ? elements : [elements];
+
+            execution.dirty = execution.dirty.concat(elements);
+        };
+
+
+        CommandStack.prototype._executedAction = function(action, redo) {
+            var stackIdx = ++this._stackIdx;
+
+            if (!redo) {
+                this._stack.splice(stackIdx, this._stack.length, action);
+            }
+        };
+
+
+        CommandStack.prototype._revertedAction = function(action) {
+            this._stackIdx--;
+        };
+
+
+        CommandStack.prototype._getHandler = function(command) {
+            return this._handlerMap[command];
+        };
+
+        CommandStack.prototype._setHandler = function(command, handler) {
+            if (!command || !handler) {
+                throw new Error('command and handler required');
+            }
+
+            if (this._handlerMap[command]) {
+                throw new Error('overriding handler for command <' + command + '>');
+            }
+
+            this._handlerMap[command] = handler;
+        };
+
+    }, {
+        "../core/EventBus": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\EventBus.js",
+        "lodash/array/unique": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\unique.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../core')],
+            commandStack: ['type', require('./CommandStack')]
+        };
+    }, {
+        "../core": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\index.js",
+        "./CommandStack": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandStack.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\Canvas.js": [function(require, module, exports) {
+        'use strict';
+
+        var isNumber = require('lodash/lang/isNumber'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+        var Collections = require('../util/Collections');
+
+        var Snap = require('../../vendor/snapsvg');
+
+        function round(number, resolution) {
+            return Math.round(number * resolution) / resolution;
+        }
+
+        function ensurePx(number) {
+            return isNumber(number) ? number + 'px' : number;
+        }
+
+        /**
+         * Creates a HTML container element for a SVG element with the given
+         * configuration
+         * 
+         * @param {Object}
+         *            options
+         * @return {HTMLElement} the container element
+         */
+        function createContainer(options) {
+
+            options = assign({}, {
+                width: '100%',
+                height: '100%'
+            }, options);
+
+            var container = options.container || document.body;
+
+            // create a <div> around the svg element with the respective size
+            // this way we can always get the correct container size
+            // (this is impossible for <svg> elements at the moment)
+            var parent = document.createElement('div');
+            parent.setAttribute('class', 'djs-container');
+
+            assign(parent.style, {
+                position: 'relative',
+                overflow: 'hidden',
+                width: ensurePx(options.width),
+                height: ensurePx(options.height)
+            });
+
+            container.appendChild(parent);
+
+            return parent;
+        }
+
+        function createGroup(parent, cls) {
+            return parent.group().attr({
+                'class': cls
+            });
+        }
+
+        var BASE_LAYER = 'base';
+
+
+        /**
+         * The main drawing canvas.
+         * 
+         * @class
+         * @constructor
+         * 
+         * @emits Canvas#canvas.init
+         * 
+         * @param {Object}
+         *            config
+         * @param {EventBus}
+         *            eventBus
+         * @param {GraphicsFactory}
+         *            graphicsFactory
+         * @param {ElementRegistry}
+         *            elementRegistry
+         */
+        function Canvas(config, eventBus, graphicsFactory, elementRegistry) {
+            this._eventBus = eventBus;
+            this._elementRegistry = elementRegistry;
+            this._graphicsFactory = graphicsFactory;
+
+            this._init(config || {});
+        }
+
+        Canvas.$inject = ['config.canvas', 'eventBus', 'graphicsFactory', 'elementRegistry'];
+
+        module.exports = Canvas;
+
+
+        Canvas.prototype._init = function(config) {
+
+            // Creates a <svg> element that is wrapped into a <div>.
+            // This way we are always able to correctly figure out the size of the svg
+            // element
+            // by querying the parent node.
+            //
+            // (It is not possible to get the size of a svg element cross browser @
+            // 2014-04-01)
+            //
+            // <div class="djs-container" style="width: {desired-width}, height:
+            // {desired-height}">
+            // <svg width="100%" height="100%">
+            // ...
+            // </svg>
+            // </div>
+
+            // html container
+            var eventBus = this._eventBus,
+
+                container = createContainer(config),
+                svg = Snap.createSnapAt('100%', '100%', container),
+                viewport = createGroup(svg, 'viewport'),
+
+                self = this;
+
+            this._container = container;
+            this._svg = svg;
+            this._viewport = viewport;
+            this._layers = {};
+
+            eventBus.on('diagram.init', function(event) {
+
+                /**
+                 * An event indicating that the canvas is ready to be drawn on.
+                 * 
+                 * @memberOf Canvas
+                 * 
+                 * @event canvas.init
+                 * 
+                 * @type {Object}
+                 * @property {Snap<SVGSVGElement>} svg the created svg element
+                 * @property {Snap<SVGGroup>} viewport the direct parent of diagram
+                 *           elements and shapes
+                 */
+                eventBus.fire('canvas.init', {
+                    svg: svg,
+                    viewport: viewport
+                });
+            });
+
+            eventBus.on('diagram.destroy', function() {
+
+                var parent = self._container.parentNode;
+
+                if (parent) {
+                    parent.removeChild(container);
+                }
+
+                eventBus.fire('canvas.destroy', {
+                    svg: self._svg,
+                    viewport: self._viewport
+                });
+
+                self._svg.remove();
+
+                self._svg = self._container = self._layers = self._viewport = null;
+            });
+
+        };
+
+        /**
+         * Returns the default layer on which all elements are drawn.
+         * 
+         * @returns {Snap<SVGGroup>}
+         */
+        Canvas.prototype.getDefaultLayer = function() {
+            return this.getLayer(BASE_LAYER);
+        };
+
+        /**
+         * Returns a layer that is used to draw elements or annotations on it.
+         * 
+         * @param {String}
+         *            name
+         * 
+         * @returns {Snap<SVGGroup>}
+         */
+        Canvas.prototype.getLayer = function(name) {
+
+            if (!name) {
+                throw new Error('must specify a name');
+            }
+
+            var layer = this._layers[name];
+            if (!layer) {
+                layer = this._layers[name] = createGroup(this._viewport, 'layer-' + name);
+            }
+
+            return layer;
+        };
+
+
+        /**
+         * Returns the html element that encloses the drawing canvas.
+         * 
+         * @return {DOMNode}
+         */
+        Canvas.prototype.getContainer = function() {
+            return this._container;
+        };
+
+
+        // ///////////// markers ///////////////////////////////////
+
+        Canvas.prototype._updateMarker = function(element, marker, add) {
+            var container;
+
+            if (!element.id) {
+                element = this._elementRegistry.get(element);
+            }
+
+            // we need to access all
+            container = this._elementRegistry._elements[element.id];
+
+            if (!container) {
+                return;
+            }
+
+            forEach([container.gfx, container.secondaryGfx], function(gfx) {
+                if (gfx) {
+                    // invoke either addClass or removeClass based on mode
+                    gfx[add ? 'addClass' : 'removeClass'](marker);
+                }
+            });
+
+            /**
+             * An event indicating that a marker has been updated for an element
+             * 
+             * @event element.marker.update
+             * @type {Object}
+             * @property {djs.model.Element} element the shape
+             * @property {Object} gfx the graphical representation of the shape
+             * @property {String} marker
+             * @property {Boolean} add true if the marker was added, false if it got
+             *           removed
+             */
+            this._eventBus.fire('element.marker.update', {
+                element: element,
+                gfx: container.gfx,
+                marker: marker,
+                add: !!add
+            });
+        };
+
+
+        /**
+         * Adds a marker to an element (basically a css class).
+         * 
+         * Fires the element.marker.update event, making it possible to integrate
+         * extension into the marker life-cycle, too.
+         * 
+         * @example canvas.addMarker('foo', 'some-marker');
+         * 
+         * var fooGfx = canvas.getGraphics('foo');
+         * 
+         * fooGfx; // <g class="... some-marker"> ... </g>
+         * 
+         * @param {String|djs.model.Base}
+         *            element
+         * @param {String}
+         *            marker
+         */
+        Canvas.prototype.addMarker = function(element, marker) {
+            this._updateMarker(element, marker, true);
+        };
+
+
+        /**
+         * Remove a marker from an element.
+         * 
+         * Fires the element.marker.update event, making it possible to integrate
+         * extension into the marker life-cycle, too.
+         * 
+         * @param {String|djs.model.Base}
+         *            element
+         * @param {String}
+         *            marker
+         */
+        Canvas.prototype.removeMarker = function(element, marker) {
+            this._updateMarker(element, marker, false);
+        };
+
+        /**
+         * Check the existence of a marker on element.
+         * 
+         * @param {String|djs.model.Base}
+         *            element
+         * @param {String}
+         *            marker
+         */
+        Canvas.prototype.hasMarker = function(element, marker) {
+            if (!element.id) {
+                element = this._elementRegistry.get(element);
+            }
+
+            var gfx = this.getGraphics(element);
+
+            return gfx && gfx.hasClass(marker);
+        };
+
+        /**
+         * Toggles a marker on an element.
+         * 
+         * Fires the element.marker.update event, making it possible to integrate
+         * extension into the marker life-cycle, too.
+         * 
+         * @param {String|djs.model.Base}
+         *            element
+         * @param {String}
+         *            marker
+         */
+        Canvas.prototype.toggleMarker = function(element, marker) {
+            if (this.hasMarker(element, marker)) {
+                this.removeMarker(element, marker);
+            } else {
+                this.addMarker(element, marker);
+            }
+        };
+
+        Canvas.prototype.getRootElement = function() {
+            if (!this._rootElement) {
+                this.setRootElement({
+                    id: '__implicitroot'
+                });
+            }
+
+            return this._rootElement;
+        };
+
+
+
+        // ////////////// root element handling ///////////////////////////
+
+        /**
+         * Sets a given element as the new root element for the canvas and returns the
+         * new root element.
+         * 
+         * @param {Object|djs.model.Root}
+         *            element
+         * @param {Boolean}
+         *            [override] whether to override the current root element, if any
+         * 
+         * @return {Object|djs.model.Root} new root element
+         */
+        Canvas.prototype.setRootElement = function(element, override) {
+
+            this._ensureValidId(element);
+
+            var oldRoot = this._rootElement,
+                elementRegistry = this._elementRegistry,
+                eventBus = this._eventBus;
+
+            if (oldRoot) {
+                if (!override) {
+                    throw new Error('rootElement already set, need to specify override');
+                }
+
+                // simulate element remove event sequence
+                eventBus.fire('root.remove', {
+                    element: oldRoot
+                });
+                eventBus.fire('root.removed', {
+                    element: oldRoot
+                });
+
+                elementRegistry.remove(oldRoot);
+            }
+
+            var gfx = this.getDefaultLayer();
+
+            // resemble element add event sequence
+            eventBus.fire('root.add', {
+                element: element
+            });
+
+            elementRegistry.add(element, gfx, this._svg);
+
+            eventBus.fire('root.added', {
+                element: element,
+                gfx: gfx
+            });
+
+            this._rootElement = element;
+
+            return element;
+        };
+
+
+
+        // /////////// add functionality ///////////////////////////////
+
+        Canvas.prototype._ensureValidId = function(element) {
+            if (!element.id) {
+                throw new Error('element must have an id');
+            }
+
+            if (this._elementRegistry.get(element.id)) {
+                throw new Error('element with id ' + element.id + ' already exists');
+            }
+        };
+
+        Canvas.prototype._setParent = function(element, parent) {
+            Collections.add(parent.children, element);
+            element.parent = parent;
+        };
+
+        /**
+         * Adds an element to the canvas.
+         * 
+         * This wires the parent <-> child relationship between the element and a
+         * explicitly specified parent or an implicit root element.
+         * 
+         * During add it emits the events
+         *  * <{type}.add> (element, parent) * <{type}.added> (element, gfx)
+         * 
+         * Extensions may hook into these events to perform their magic.
+         * 
+         * @param {String}
+         *            type
+         * @param {Object|djs.model.Base}
+         *            element
+         * @param {Object|djs.model.Base}
+         *            [parent]
+         * 
+         * @return {Object|djs.model.Base} the added element
+         */
+        Canvas.prototype._addElement = function(type, element, parent) {
+
+            parent = parent || this.getRootElement();
+
+            var eventBus = this._eventBus,
+                graphicsFactory = this._graphicsFactory;
+
+            this._ensureValidId(element);
+
+            eventBus.fire(type + '.add', {
+                element: element,
+                parent: parent
+            });
+
+            this._setParent(element, parent);
+
+            // create graphics
+            var gfx = graphicsFactory.create(type, element);
+
+            this._elementRegistry.add(element, gfx);
+
+            // update its visual
+            graphicsFactory.update(type, element, gfx);
+
+            eventBus.fire(type + '.added', {
+                element: element,
+                gfx: gfx
+            });
+
+            return element;
+        };
+
+        /**
+         * Adds a shape to the canvas
+         * 
+         * @param {Object|djs.model.Shape}
+         *            shape to add to the diagram
+         * @param {djs.model.Base}
+         *            [parent]
+         * 
+         * @return {djs.model.Shape} the added shape
+         */
+        Canvas.prototype.addShape = function(shape, parent) {
+            return this._addElement('shape', shape, parent);
+        };
+
+        /**
+         * Adds a connection to the canvas
+         * 
+         * @param {Object|djs.model.Connection}
+         *            connection to add to the diagram
+         * @param {djs.model.Base}
+         *            [parent]
+         * 
+         * @return {djs.model.Connection} the added connection
+         */
+        Canvas.prototype.addConnection = function(connection, parent) {
+            return this._addElement('connection', connection, parent);
+        };
+
+
+        /**
+         * Internal remove element
+         */
+        Canvas.prototype._removeElement = function(element, type) {
+            console.log(element);
+            var elementRegistry = this._elementRegistry,
+                graphicsFactory = this._graphicsFactory,
+                eventBus = this._eventBus;
+
+            element = elementRegistry.get(element.id || element);
+
+            if (!element) {
+                // element was removed already
+                return;
+            }
+
+            eventBus.fire(type + '.remove', {
+                element: element
+            });
+
+            graphicsFactory.remove(element);
+
+            // unset parent <-> child relationship
+            Collections.remove(element.parent && element.parent.children, element);
+            element.parent = null;
+
+            eventBus.fire(type + '.removed', {
+                element: element
+            });
+
+            elementRegistry.remove(element);
+
+            return element;
+        };
+
+
+        /**
+         * Removes a shape from the canvas
+         * 
+         * @param {String|djs.model.Shape}
+         *            shape or shape id to be removed
+         * 
+         * @return {djs.model.Shape} the removed shape
+         */
+        Canvas.prototype.removeShape = function(shape) {
+
+            /**
+             * An event indicating that a shape is about to be removed from the canvas.
+             * 
+             * @memberOf Canvas
+             * 
+             * @event shape.remove
+             * @type {Object}
+             * @property {djs.model.Shape} element the shape descriptor
+             * @property {Object} gfx the graphical representation of the shape
+             */
+
+            /**
+             * An event indicating that a shape has been removed from the canvas.
+             * 
+             * @memberOf Canvas
+             * 
+             * @event shape.removed
+             * @type {Object}
+             * @property {djs.model.Shape} element the shape descriptor
+             * @property {Object} gfx the graphical representation of the shape
+             */
+            return this._removeElement(shape, 'shape');
+        };
+
+
+        /**
+         * Removes a connection from the canvas
+         * 
+         * @param {String|djs.model.Connection}
+         *            connection or connection id to be removed
+         * 
+         * @return {djs.model.Connection} the removed connection
+         */
+        Canvas.prototype.removeConnection = function(connection) {
+
+            /**
+             * An event indicating that a connection is about to be removed from the
+             * canvas.
+             * 
+             * @memberOf Canvas
+             * 
+             * @event connection.remove
+             * @type {Object}
+             * @property {djs.model.Connection} element the connection descriptor
+             * @property {Object} gfx the graphical representation of the connection
+             */
+
+            /**
+             * An event indicating that a connection has been removed from the canvas.
+             * 
+             * @memberOf Canvas
+             * 
+             * @event connection.removed
+             * @type {Object}
+             * @property {djs.model.Connection} element the connection descriptor
+             * @property {Object} gfx the graphical representation of the connection
+             */
+            return this._removeElement(connection, 'connection');
+        };
+
+
+        /**
+         * Sends a shape to the front.
+         * 
+         * This method takes parent / child relationships between shapes into account
+         * and makes sure that children are properly handled, too.
+         * 
+         * @param {djs.model.Shape}
+         *            shape descriptor of the shape to be sent to front
+         * @param {boolean}
+         *            [bubble=true] whether to send parent shapes to front, too
+         */
+        Canvas.prototype.sendToFront = function(shape, bubble) {
+
+            if (bubble !== false) {
+                bubble = true;
+            }
+
+            if (bubble && shape.parent) {
+                this.sendToFront(shape.parent);
+            }
+
+            forEach(shape.children, function(child) {
+                this.sendToFront(child, false);
+            }, this);
+
+            var gfx = this.getGraphics(shape),
+                gfxParent = gfx.parent();
+
+            gfx.remove().appendTo(gfxParent);
+        };
+
+
+        /**
+         * Return the graphical object underlaying a certain diagram element
+         * 
+         * @param {String|djs.model.Base}
+         *            element descriptor of the element
+         * @param {Boolean}
+         *            [secondary=false] whether to return the secondary connected
+         *            element
+         * 
+         * @return {SVGElement}
+         */
+        Canvas.prototype.getGraphics = function(element, secondary) {
+            return this._elementRegistry.getGraphics(element, secondary);
+        };
+
+
+        Canvas.prototype._fireViewboxChange = function() {
+            this._eventBus.fire('canvas.viewbox.changed', {
+                viewbox: this.viewbox(false)
+            });
+        };
+
+
+        /**
+         * Gets or sets the view box of the canvas, i.e. the area that is currently
+         * displayed
+         * 
+         * @param {Object}
+         *            [box] the new view box to set
+         * @param {Number}
+         *            box.x the top left X coordinate of the canvas visible in view box
+         * @param {Number}
+         *            box.y the top left Y coordinate of the canvas visible in view box
+         * @param {Number}
+         *            box.width the visible width
+         * @param {Number}
+         *            box.height
+         * 
+         * @example
+         * 
+         * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 })
+         *  // sets the visible area of the diagram to (100|100) -> (600|100) // and and
+         * scales it according to the diagram width
+         * 
+         * @return {Object} the current view box
+         */
+        Canvas.prototype.viewbox = function(box) {
+
+            if (box === undefined && this._cachedViewbox) {
+                return this._cachedViewbox;
+            }
+
+            var viewport = this._viewport,
+                innerBox,
+                outerBox = this.getSize(),
+                matrix,
+                scale,
+                x, y;
+
+            if (!box) {
+                // compute the inner box based on the
+                // diagrams default layer. This allows us to exclude
+                // external components, such as overlays
+                innerBox = this.getDefaultLayer().getBBox(true);
+
+                matrix = viewport.transform().localMatrix;
+                scale = round(matrix.a, 1000);
+
+                x = round(-matrix.e || 0, 1000);
+                y = round(-matrix.f || 0, 1000);
+
+                box = this._cachedViewbox = {
+                    x: x ? x / scale : 0,
+                    y: y ? y / scale : 0,
+                    width: outerBox.width / scale,
+                    height: outerBox.height / scale,
+                    scale: scale,
+                    inner: {
+                        width: innerBox.width,
+                        height: innerBox.height,
+                        x: innerBox.x,
+                        y: innerBox.y
+                    },
+                    outer: outerBox
+                };
+
+                return box;
+            } else {
+                scale = Math.min(outerBox.width / box.width, outerBox.height / box.height);
+
+                matrix = new Snap.Matrix().scale(scale).translate(-box.x, -box.y);
+                viewport.transform(matrix);
+
+                this._fireViewboxChange();
+            }
+
+            return box;
+        };
+
+
+        /**
+         * Gets or sets the scroll of the canvas.
+         * 
+         * @param {Object}
+         *            [delta] the new scroll to apply.
+         * 
+         * @param {Number}
+         *            [delta.dx]
+         * @param {Number}
+         *            [delta.dy]
+         */
+        Canvas.prototype.scroll = function(delta) {
+            var node = this._viewport.node;
+            var matrix = node.getCTM();
+
+            if (delta) {
+                delta = assign({
+                    dx: 0,
+                    dy: 0
+                }, delta || {});
+
+                matrix = this._svg.node.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);
+
+                setCTM(node, matrix);
+
+                this._fireViewboxChange();
+            }
+
+            return {
+                x: matrix.e,
+                y: matrix.f
+            };
+        };
+
+
+        /**
+         * Gets or sets the current zoom of the canvas, optionally zooming to the
+         * specified position.
+         * 
+         * @param {String|Number}
+         *            [newScale] the new zoom level, either a number, i.e. 0.9, or
+         *            `fit-viewport` to adjust the size to fit the current viewport
+         * @param {String|Point}
+         *            [center] the reference point { x: .., y: ..} to zoom to, 'auto' to
+         *            zoom into mid or null
+         * 
+         * @return {Number} the current scale
+         */
+        Canvas.prototype.zoom = function(newScale, center) {
+
+            if (newScale === 'fit-viewport') {
+                return this._fitViewport(center);
+            }
+
+            var vbox = this.viewbox();
+
+            if (newScale === undefined) {
+                return vbox.scale;
+            }
+
+            var outer = vbox.outer;
+
+            if (center === 'auto') {
+                center = {
+                    x: outer.width / 2,
+                    y: outer.height / 2
+                };
+            }
+
+            var matrix = this._setZoom(newScale, center);
+
+            this._fireViewboxChange();
+
+            return round(matrix.a, 1000);
+        };
+
+        function setCTM(node, m) {
+            var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';
+            node.setAttribute('transform', mstr);
+        }
+
+        Canvas.prototype._fitViewport = function(center) {
+
+            var vbox = this.viewbox(),
+                outer = vbox.outer,
+                inner = vbox.inner,
+                newScale,
+                newViewbox;
+
+            // display the complete diagram without zooming in.
+            // instead of relying on internal zoom, we perform a
+            // hard reset on the canvas viewbox to realize this
+            //
+            // if diagram does not need to be zoomed in, we focus it around
+            // the diagram origin instead
+
+            if (inner.x >= 0 &&
+                inner.y >= 0 &&
+                inner.x + inner.width <= outer.width &&
+                inner.y + inner.height <= outer.height &&
+                !center) {
+
+                newViewbox = {
+                    x: 0,
+                    y: 0,
+                    width: Math.max(inner.width + inner.x, outer.width),
+                    height: Math.max(inner.height + inner.y, outer.height)
+                };
+            } else {
+
+                newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);
+                newViewbox = {
+                    x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
+                    y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
+                    width: outer.width / newScale,
+                    height: outer.height / newScale
+                };
+            }
+
+            this.viewbox(newViewbox);
+
+            return this.viewbox().scale;
+        };
+
+
+        Canvas.prototype._setZoom = function(scale, center) {
+
+            var svg = this._svg.node,
+                viewport = this._viewport.node;
+
+            var matrix = svg.createSVGMatrix();
+            var point = svg.createSVGPoint();
+
+            var centerPoint,
+                originalPoint,
+                currentMatrix,
+                scaleMatrix,
+                newMatrix;
+
+            currentMatrix = viewport.getCTM();
+
+
+            var currentScale = currentMatrix.a;
+
+            if (center) {
+                centerPoint = assign(point, center);
+
+                // revert applied viewport transformations
+                originalPoint = centerPoint.matrixTransform(currentMatrix.inverse());
+
+                // create scale matrix
+                scaleMatrix = matrix
+                    .translate(originalPoint.x, originalPoint.y)
+                    .scale(1 / currentScale * scale)
+                    .translate(-originalPoint.x, -originalPoint.y);
+
+                newMatrix = currentMatrix.multiply(scaleMatrix);
+            } else {
+                newMatrix = matrix.scale(scale);
+            }
+
+            setCTM(this._viewport.node, newMatrix);
+
+            return newMatrix;
+        };
+
+
+        /**
+         * Returns the size of the canvas
+         * 
+         * @return {Dimensions}
+         */
+        Canvas.prototype.getSize = function() {
+            return {
+                width: this._container.clientWidth,
+                height: this._container.clientHeight
+            };
+        };
+
+
+        /**
+         * Return the absolute bounding box for the given element
+         * 
+         * The absolute bounding box may be used to display overlays in the callers
+         * (browser) coordinate system rather than the zoomed in/out canvas coordinates.
+         * 
+         * @param {ElementDescriptor}
+         *            element
+         * @return {Bounds} the absolute bounding box
+         */
+        Canvas.prototype.getAbsoluteBBox = function(element) {
+            var vbox = this.viewbox();
+            var bbox;
+
+            // connection
+            // use svg bbox
+            if (element.waypoints) {
+                var gfx = this.getGraphics(element);
+
+                var transformBBox = gfx.getBBox(true);
+                bbox = gfx.getBBox();
+
+                bbox.x -= transformBBox.x;
+                bbox.y -= transformBBox.y;
+
+                bbox.width += 2 * transformBBox.x;
+                bbox.height += 2 * transformBBox.y;
+            }
+            // shapes
+            // use data
+            else {
+                bbox = element;
+            }
+
+            var x = bbox.x * vbox.scale - vbox.x * vbox.scale;
+            var y = bbox.y * vbox.scale - vbox.y * vbox.scale;
+
+            var width = bbox.width * vbox.scale;
+            var height = bbox.height * vbox.scale;
+
+            return {
+                x: x,
+                y: y,
+                width: width,
+                height: height
+            };
+        };
+
+    }, {
+        "../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isNumber": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNumber.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\ElementFactory.js": [function(require, module, exports) {
+        'use strict';
+
+        var Model = require('../model');
+
+
+        /**
+         * A factory for diagram-js shapes
+         */
+        function ElementFactory() {
+            this._uid = 12;
+        }
+
+        module.exports = ElementFactory;
+
+
+        ElementFactory.prototype.createRoot = function(attrs) {
+            return this.create('root', attrs);
+        };
+
+        ElementFactory.prototype.createLabel = function(attrs) {
+            return this.create('label', attrs);
+        };
+
+        ElementFactory.prototype.createShape = function(attrs) {
+            // alert("In createShape");
+            return this.create('shape', attrs);
+        };
+
+        ElementFactory.prototype.createConnection = function(attrs) {
+            return this.create('connection', attrs);
+        };
+
+        /**
+         * Create a model element with the given type and a number of pre-set
+         * attributes.
+         * 
+         * @param {String}
+         *            type
+         * @param {Object}
+         *            attrs
+         * @return {djs.model.Base} the newly created model instance
+         */
+        ElementFactory.prototype.create = function(type, attrs) {
+            // alert("In create");
+
+            attrs = attrs || {};
+
+            if (!attrs.id) {
+                attrs.id = type + '_' + (this._uid++);
+            }
+
+            return Model.create(type, attrs);
+        };
+    }, {
+        "../model": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\model\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\ElementRegistry.js": [function(require, module, exports) {
+        'use strict';
+
+        var ELEMENT_ID = 'data-element-id';
+
+
+        /**
+         * @class
+         * 
+         * A registry that keeps track of all shapes in the diagram.
+         */
+        function ElementRegistry() {
+            this._elements = {};
+        }
+
+        module.exports = ElementRegistry;
+
+        /**
+         * Register a pair of (element, gfx, (secondaryGfx)).
+         * 
+         * @param {djs.model.Base}
+         *            element
+         * @param {Snap
+         *            <SVGElement>} gfx
+         * @param {Snap
+         *            <SVGElement>} [secondaryGfx] optional other element to register,
+         *            too
+         */
+        ElementRegistry.prototype.add = function(element, gfx, secondaryGfx) {
+
+            var id = element.id;
+
+            this._validateId(id);
+
+            // associate dom node with element
+            gfx.attr(ELEMENT_ID, id);
+
+            if (secondaryGfx) {
+                secondaryGfx.attr(ELEMENT_ID, id);
+            }
+
+            this._elements[id] = {
+                element: element,
+                gfx: gfx,
+                secondaryGfx: secondaryGfx
+            };
+        };
+
+        /**
+         * Removes an element from the registry.
+         * 
+         * @param {djs.model.Base}
+         *            element
+         */
+        ElementRegistry.prototype.remove = function(element) {
+            var elements = this._elements,
+                id = element.id || element,
+                container = id && elements[id];
+
+            if (container) {
+
+                // unset element id on gfx
+                container.gfx.attr(ELEMENT_ID, null);
+
+                if (container.secondaryGfx) {
+                    container.secondaryGfx.attr(ELEMENT_ID, null);
+                }
+
+                delete elements[id];
+            }
+        };
+
+        /**
+         * Update the id of an element
+         * 
+         * @param {djs.model.Base}
+         *            element
+         * @param {String}
+         *            newId
+         */
+        ElementRegistry.prototype.updateId = function(element, newId) {
+
+            this._validateId(newId);
+
+            if (typeof element === 'string') {
+                element = this.get(element);
+            }
+
+            var gfx = this.getGraphics(element),
+                secondaryGfx = this.getGraphics(element, true);
+
+            this.remove(element);
+
+            element.id = newId;
+
+            this.add(element, gfx, secondaryGfx);
+        };
+
+        /**
+         * Return the model element for a given id or graphics.
+         * 
+         * @example
+         * 
+         * elementRegistry.get('SomeElementId_1'); elementRegistry.get(gfx);
+         * 
+         * 
+         * @param {String|SVGElement}
+         *            filter for selecting the element
+         * 
+         * @return {djs.model.Base}
+         */
+        ElementRegistry.prototype.get = function(filter) {
+            var id;
+
+            if (typeof filter === 'string') {
+                id = filter;
+            } else {
+                id = filter && filter.attr(ELEMENT_ID);
+            }
+
+            var container = this._elements[id];
+            return container && container.element;
+        };
+
+        /**
+         * Return all elements that match a given filter function.
+         * 
+         * @param {Function}
+         *            fn
+         * 
+         * @return {Array<djs.model.Base>}
+         */
+        ElementRegistry.prototype.filter = function(fn) {
+
+            var filtered = [];
+
+            this.forEach(function(element, gfx) {
+                if (fn(element, gfx)) {
+                    filtered.push(element);
+                }
+            });
+
+            return filtered;
+        };
+
+        /**
+         * Iterate over all diagram elements.
+         * 
+         * @param {Function}
+         *            fn
+         */
+        ElementRegistry.prototype.forEach = function(fn) {
+
+            var map = this._elements;
+
+            Object.keys(map).forEach(function(id) {
+                var container = map[id],
+                    element = container.element,
+                    gfx = container.gfx;
+
+                return fn(element, gfx);
+            });
+        };
+
+        /**
+         * Return the graphical representation of an element or its id.
+         * 
+         * @example elementRegistry.getGraphics('SomeElementId_1');
+         *          elementRegistry.getGraphics(rootElement); // <g ...>
+         * 
+         * elementRegistry.getGraphics(rootElement, true); // <svg ...>
+         * 
+         * 
+         * @param {String|djs.model.Base}
+         *            filter
+         * @param {Boolean}
+         *            [secondary=false] whether to return the secondary connected
+         *            element
+         * 
+         * @return {SVGElement}
+         */
+        ElementRegistry.prototype.getGraphics = function(filter, secondary) {
+            var id = filter.id || filter;
+
+            var container = this._elements[id];
+            return container && (secondary ? container.secondaryGfx : container.gfx);
+        };
+
+        /**
+         * Validate the suitability of the given id and signals a problem with an
+         * exception.
+         * 
+         * @param {String}
+         *            id
+         * 
+         * @throws {Error}
+         *             if id is empty or already assigned
+         */
+        ElementRegistry.prototype._validateId = function(id) {
+            if (!id) {
+                throw new Error('element must have an id');
+            }
+
+            if (this._elements[id]) {
+                throw new Error('element with id ' + id + ' already added');
+            }
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\EventBus.js": [function(require, module, exports) {
+        'use strict';
+
+        var isFunction = require('lodash/lang/isFunction'),
+            isArray = require('lodash/lang/isArray'),
+            isNumber = require('lodash/lang/isNumber'),
+            assign = require('lodash/object/assign');
+
+        var DEFAULT_PRIORITY = 1000;
+
+
+        /**
+         * A general purpose event bus.
+         * 
+         * This component is used to communicate across a diagram instance. Other parts
+         * of a diagram can use it to listen to and broadcast events.
+         * 
+         *  ## Registering for Events
+         * 
+         * The event bus provides the {@link EventBus#on} and {@link EventBus#once}
+         * methods to register for events. {@link EventBus#off} can be used to remove
+         * event registrations. Listeners receive an instance of {@link Event} as the
+         * first argument. It allows them to hook into the event execution.
+         * 
+         * ```javascript
+         *  // listen for event eventBus.on('foo', function(event) {
+         *  // access event type event.type; // 'foo'
+         *  // stop propagation to other listeners event.stopPropagation();
+         *  // prevent event default event.preventDefault(); });
+         *  // listen for event with custom payload eventBus.on('bar', function(event,
+         * payload) { console.log(payload); });
+         *  // listen for event returning value eventBus.on('foobar', function(event) {
+         *  // stop event propagation + prevent default return false;
+         *  // stop event propagation + return custom result return { complex:
+         * 'listening result' }; });
+         * 
+         *  // listen with custom priority (default=1000, higher is better)
+         * eventBus.on('priorityfoo', 1500, function(event) { console.log('invoked
+         * first!'); }); ```
+         * 
+         *  ## Emitting Events
+         * 
+         * Events can be emitted via the event bus using {@link EventBus#fire}.
+         * 
+         * ```javascript
+         *  // false indicates that the default action // was prevented by listeners if
+         * (eventBus.fire('foo') === false) { console.log('default has been
+         * prevented!'); };
+         * 
+         *  // custom args + return value listener eventBus.on('sum', function(event, a,
+         * b) { return a + b; });
+         *  // you can pass custom arguments + retrieve result values. var sum =
+         * eventBus.fire('sum', 1, 2); console.log(sum); // 3 ```
+         */
+        function EventBus() {
+            this._listeners = {};
+
+            // cleanup on destroy
+
+            var self = this;
+
+            // destroy on lowest priority to allow
+            // message passing until the bitter end
+            this.on('diagram.destroy', 1, function() {
+                self._listeners = null;
+            });
+        }
+
+        module.exports = EventBus;
+
+
+        /**
+         * Register an event listener for events with the given name.
+         * 
+         * The callback will be invoked with `event, ...additionalArguments` that have
+         * been passed to {@link EventBus#fire}.
+         * 
+         * Returning false from a listener will prevent the events default action (if
+         * any is specified). To stop an event from being processed further in other
+         * listeners execute {@link Event#stopPropagation}.
+         * 
+         * Returning anything but `undefined` from a listener will stop the listener
+         * propagation.
+         * 
+         * @param {String|Array
+         *            <String>} events
+         * @param {Number}
+         *            [priority=1000] the priority in which this listener is called,
+         *            larger is higher
+         * @param {Function}
+         *            callback
+         */
+        EventBus.prototype.on = function(events, priority, callback) {
+
+            events = isArray(events) ? events : [events];
+
+            if (isFunction(priority)) {
+                callback = priority;
+                priority = DEFAULT_PRIORITY;
+            }
+
+            if (!isNumber(priority)) {
+                throw new Error('priority must be a number');
+            }
+
+            var self = this,
+                listener = {
+                    priority: priority,
+                    callback: callback
+                };
+
+            events.forEach(function(e) {
+                self._addListener(e, listener);
+            });
+        };
+
+
+        /**
+         * Register an event listener that is executed only once.
+         * 
+         * @param {String}
+         *            event the event name to register for
+         * @param {Function}
+         *            callback the callback to execute
+         */
+        EventBus.prototype.once = function(event, callback) {
+
+            var self = this;
+
+            function wrappedCallback() {
+                callback.apply(self, arguments);
+                self.off(event, wrappedCallback);
+            }
+
+            this.on(event, wrappedCallback);
+        };
+
+
+        /**
+         * Removes event listeners by event and callback.
+         * 
+         * If no callback is given, all listeners for a given event name are being
+         * removed.
+         * 
+         * @param {String}
+         *            event
+         * @param {Function}
+         *            [callback]
+         */
+        EventBus.prototype.off = function(event, callback) {
+            var listeners = this._getListeners(event),
+                listener, idx;
+
+            if (callback) {
+
+                // move through listeners from back to front
+                // and remove matching listeners
+                for (idx = listeners.length - 1; !!(listener = listeners[idx]); idx--) {
+                    if (listener.callback === callback) {
+                        listeners.splice(idx, 1);
+                    }
+                }
+            } else {
+                // clear listeners
+                listeners.length = 0;
+            }
+        };
+
+
+        /**
+         * Fires a named event.
+         * 
+         * @example
+         *  // fire event by name events.fire('foo');
+         *  // fire event object with nested type var event = { type: 'foo' };
+         * events.fire(event);
+         *  // fire event with explicit type var event = { x: 10, y: 20 };
+         * events.fire('element.moved', event);
+         *  // pass additional arguments to the event events.on('foo', function(event,
+         * bar) { alert(bar); });
+         * 
+         * events.fire({ type: 'foo' }, 'I am bar!');
+         * 
+         * @param {String}
+         *            [name] the optional event name
+         * @param {Object}
+         *            [event] the event object
+         * @param {...Object}
+         *            additional arguments to be passed to the callback functions
+         * 
+         * @return {Boolean} the events return value, if specified or false if the
+         *         default action was prevented by listeners
+         */
+        EventBus.prototype.fire = function(type, data) {
+
+            var event,
+                originalType,
+                listeners, idx, listener,
+                returnValue,
+                args;
+
+            args = Array.prototype.slice.call(arguments);
+
+            if (typeof type === 'object') {
+                event = type;
+                type = event.type;
+            }
+
+            if (!type) {
+                throw new Error('no event type specified');
+            }
+
+            listeners = this._listeners[type];
+
+            if (!listeners) {
+                return;
+            }
+
+            // we make sure we fire instances of our home made
+            // events here. We wrap them only once, though
+            if (data instanceof Event) {
+                // we are fine, we alread have an event
+                event = data;
+            } else {
+                event = new Event();
+                event.init(data);
+            }
+
+            // ensure we pass the event as the first parameter
+            args[0] = event;
+
+            // original event type (in case we delegate)
+            originalType = event.type;
+
+            try {
+
+                // update event type before delegation
+                if (type !== originalType) {
+                    event.type = type;
+                }
+
+                for (idx = 0; !!(listener = listeners[idx]); idx++) {
+
+                    // handle stopped propagation
+                    if (event.cancelBubble) {
+                        break;
+                    }
+
+                    try {
+                        // returning false prevents the default action
+                        returnValue = event.returnValue = listener.callback.apply(null, args);
+
+                        // stop propagation on return value
+                        if (returnValue !== undefined) {
+                            event.stopPropagation();
+                        }
+
+                        // prevent default on return false
+                        if (returnValue === false) {
+                            event.preventDefault();
+                        }
+                    } catch (e) {
+                        if (!this.handleError(e)) {
+                            console.error('unhandled error in event listener');
+                            console.error(e.stack);
+
+                            throw e;
+                        }
+                    }
+                }
+            } finally {
+                // reset event type after delegation
+                if (type !== originalType) {
+                    event.type = originalType;
+                }
+            }
+
+            // set the return value to false if the event default
+            // got prevented and no other return value exists
+            if (returnValue === undefined && event.defaultPrevented) {
+                returnValue = false;
+            }
+
+            return returnValue;
+        };
+
+
+        EventBus.prototype.handleError = function(error) {
+            return this.fire('error', {
+                error: error
+            }) === false;
+        };
+
+
+        /*
+         * Add new listener with a certain priority to the list of listeners (for the
+         * given event).
+         * 
+         * The semantics of listener registration / listener execution are first
+         * register, first serve: New listeners will always be inserted after existing
+         * listeners with the same priority.
+         * 
+         * Example: Inserting two listeners with priority 1000 and 1300
+         *  * before: [ 1500, 1500, 1000, 1000 ] * after: [ 1500, 1500, (new=1300),
+         * 1000, 1000, (new=1000) ]
+         * 
+         * @param {String} event @param {Object} listener { priority, callback }
+         */
+        EventBus.prototype._addListener = function(event, newListener) {
+
+            var listeners = this._getListeners(event),
+                existingListener,
+                idx;
+
+            // ensure we order listeners by priority from
+            // 0 (high) to n > 0 (low)
+            for (idx = 0; !!(existingListener = listeners[idx]); idx++) {
+                if (existingListener.priority < newListener.priority) {
+
+                    // prepend newListener at before existingListener
+                    listeners.splice(idx, 0, newListener);
+                    return;
+                }
+            }
+
+            listeners.push(newListener);
+        };
+
+
+        EventBus.prototype._getListeners = function(name) {
+            var listeners = this._listeners[name];
+
+            if (!listeners) {
+                this._listeners[name] = listeners = [];
+            }
+
+            return listeners;
+        };
+
+
+        /**
+         * A event that is emitted via the event bus.
+         */
+        function Event() {}
+
+        module.exports.Event = Event;
+
+        Event.prototype.stopPropagation = function() {
+            this.cancelBubble = true;
+        };
+
+        Event.prototype.preventDefault = function() {
+            this.defaultPrevented = true;
+        };
+
+        Event.prototype.init = function(data) {
+            assign(this, data || {});
+        };
+
+    }, {
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/lang/isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js",
+        "lodash/lang/isNumber": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNumber.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\GraphicsFactory.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            reduce = require('lodash/collection/reduce');
+
+        var GraphicsUtil = require('../util/GraphicsUtil'),
+            domClear = require('min-dom/lib/clear');
+
+        /**
+         * A factory that creates graphical elements
+         * 
+         * @param {Renderer}
+         *            renderer
+         */
+        function GraphicsFactory(renderer, elementRegistry) {
+            this._renderer = renderer;
+            this._elementRegistry = elementRegistry;
+        }
+
+        GraphicsFactory.$inject = ['renderer', 'elementRegistry'];
+
+        module.exports = GraphicsFactory;
+
+
+        GraphicsFactory.prototype._getChildren = function(element) {
+
+            var gfx = this._elementRegistry.getGraphics(element);
+
+            var childrenGfx;
+
+            // root element
+            if (!element.parent) {
+                childrenGfx = gfx;
+            } else {
+                childrenGfx = GraphicsUtil.getChildren(gfx);
+                if (!childrenGfx) {
+                    childrenGfx = gfx.parent().group().attr('class', 'djs-children');
+                }
+            }
+
+            return childrenGfx;
+        };
+
+        /**
+         * Clears the graphical representation of the element and returns the cleared
+         * visual (the <g class="djs-visual" /> element).
+         */
+        GraphicsFactory.prototype._clear = function(gfx) {
+            var visual = GraphicsUtil.getVisual(gfx);
+
+            domClear(visual.node);
+
+            return visual;
+        };
+
+        /**
+         * Creates a gfx container for shapes and connections
+         * 
+         * The layout is as follows:
+         * 
+         * <g class="djs-group">
+         * 
+         * <!-- the gfx --> <g class="djs-element djs-(shape|connection)"> <g
+         * class="djs-visual"> <!-- the renderer draws in here --> </g>
+         * 
+         * <!-- extensions (overlays, click box, ...) goes here </g>
+         * 
+         * <!-- the gfx child nodes --> <g class="djs-children"></g> </g>
+         * 
+         * @param {Object}
+         *            parent
+         * @param {String}
+         *            type the type of the element, i.e. shape | connection
+         */
+        GraphicsFactory.prototype._createContainer = function(type, parentGfx) {
+            var outerGfx = parentGfx.group().attr('class', 'djs-group'),
+                gfx = outerGfx.group().attr('class', 'djs-element djs-' + type);
+
+            // create visual
+            gfx.group().attr('class', 'djs-visual');
+
+            return gfx;
+        };
+
+        GraphicsFactory.prototype.create = function(type, element) {
+            var childrenGfx = this._getChildren(element.parent);
+            return this._createContainer(type, childrenGfx);
+        };
+
+
+        GraphicsFactory.prototype.updateContainments = function(elements) {
+
+            var self = this,
+                elementRegistry = this._elementRegistry,
+                parents;
+
+
+            parents = reduce(elements, function(map, e) {
+
+                if (e.parent) {
+                    map[e.parent.id] = e.parent;
+                }
+
+                return map;
+            }, {});
+
+            // update all parents of changed and reorganized their children
+            // in the correct order (as indicated in our model)
+            forEach(parents, function(parent) {
+
+                var childGfx = self._getChildren(parent),
+                    children = parent.children;
+
+                if (!children) {
+                    return;
+                }
+
+                forEach(children.slice().reverse(), function(c) {
+                    var gfx = elementRegistry.getGraphics(c);
+                    gfx.parent().prependTo(childGfx);
+                });
+            });
+
+        };
+
+        GraphicsFactory.prototype.update = function(type, element, gfx) {
+
+            // Do not update root element
+            if (!element.parent) {
+                return;
+            }
+
+            var visual = this._clear(gfx);
+
+            // redraw
+            if (type === 'shape') {
+                this._renderer.drawShape(visual, element);
+
+                // update positioning
+                gfx.translate(element.x, element.y);
+            } else
+            if (type === 'connection') {
+                this._renderer.drawConnection(visual, element);
+            } else {
+                throw new Error('unknown type: ' + type);
+            }
+
+            gfx.attr('display', element.hidden ? 'none' : 'block');
+        };
+
+
+        GraphicsFactory.prototype.remove = function(element) {
+            var gfx = this._elementRegistry.getGraphics(element);
+
+            // remove
+            gfx.parent().remove();
+        };
+
+    }, {
+        "../util/GraphicsUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\GraphicsUtil.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/reduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\reduce.js",
+        "min-dom/lib/clear": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\clear.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../draw')],
+            __init__: ['canvas'],
+            canvas: ['type', require('./Canvas')],
+            elementRegistry: ['type', require('./ElementRegistry')],
+            elementFactory: ['type', require('./ElementFactory')],
+            eventBus: ['type', require('./EventBus')],
+            graphicsFactory: ['type', require('./GraphicsFactory')]
+        };
+    }, {
+        "../draw": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\index.js",
+        "./Canvas": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\Canvas.js",
+        "./ElementFactory": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\ElementFactory.js",
+        "./ElementRegistry": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\ElementRegistry.js",
+        "./EventBus": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\EventBus.js",
+        "./GraphicsFactory": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\GraphicsFactory.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Renderer.js": [function(require, module, exports) {
+        'use strict';
+
+        var Snap = require('../../vendor/snapsvg');
+
+
+        /**
+         * The default renderer used for shapes and connections.
+         * 
+         * @param {Styles}
+         *            styles
+         */
+        function Renderer(styles) {
+            this.CONNECTION_STYLE = styles.style(['no-fill'], {
+                strokeWidth: 5,
+                stroke: 'fuchsia'
+            });
+            this.SHAPE_STYLE = styles.style({
+                fill: 'white',
+                stroke: 'fuchsia',
+                strokeWidth: 2
+            });
+        }
+
+        module.exports = Renderer;
+
+        Renderer.$inject = ['styles'];
+
+
+        Renderer.prototype.drawShape = function drawShape(gfxGroup, data) {
+            return gfxGroup.rect(0, 0, data.width || 0, data.height || 0).attr(this.SHAPE_STYLE);
+        };
+
+        Renderer.prototype.drawConnection = function drawConnection(gfxGroup, data) {
+            return createLine(data.waypoints, this.CONNECTION_STYLE).appendTo(gfxGroup);
+        };
+
+        function componentsToPath(components) {
+            return components.join(',').replace(/,?([A-z]),?/g, '$1');
+        }
+
+        /**
+         * Gets the default SVG path of a shape that represents it's visual bounds.
+         * 
+         * @param {djs.model.Shape}
+         *            shape
+         * @return {string} svg path
+         */
+        Renderer.prototype.getShapePath = function getShapePath(shape) {
+
+            var x = shape.x,
+                y = shape.y,
+                width = shape.width,
+                height = shape.height;
+
+            var shapePath = [
+                ['M', x, y],
+                ['l', width, 0],
+                ['l', 0, height],
+                ['l', -width, 0],
+                ['z']
+            ];
+
+            return componentsToPath(shapePath);
+        };
+
+        /**
+         * Gets the default SVG path of a connection that represents it's visual bounds.
+         * 
+         * @param {djs.model.Connection}
+         *            connection
+         * @return {string} svg path
+         */
+        Renderer.prototype.getConnectionPath = function getConnectionPath(connection) {
+            var waypoints = connection.waypoints;
+
+            var idx, point, connectionPath = [];
+
+            for (idx = 0; !!(point = waypoints[idx]); idx++) {
+
+                // take invisible docking into account
+                // when creating the path
+                point = point.original || point;
+
+                connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]);
+            }
+
+            return componentsToPath(connectionPath);
+        };
+
+
+        function toSVGPoints(points) {
+            var result = '';
+
+            for (var i = 0, p; !!(p = points[i]); i++) {
+                result += p.x + ',' + p.y + ' ';
+            }
+
+            return result;
+        }
+
+        function createLine(points, attrs) {
+            return Snap.create('polyline', {
+                points: toSVGPoints(points)
+            }).attr(attrs || {});
+        }
+
+        function updateLine(gfx, points) {
+            return gfx.attr({
+                points: toSVGPoints(points)
+            });
+        }
+
+        module.exports.createLine = createLine;
+        module.exports.updateLine = updateLine;
+    }, {
+        "../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Styles.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            assign = require('lodash/object/assign'),
+            reduce = require('lodash/collection/reduce');
+
+
+        /**
+         * A component that manages shape styles
+         */
+        function Styles() {
+
+            var defaultTraits = {
+
+                'no-fill': {
+                    fill: 'none'
+                },
+                'no-border': {
+                    strokeOpacity: 0.0
+                },
+                'no-events': {
+                    pointerEvents: 'none'
+                }
+            };
+
+            /**
+             * Builds a style definition from a className, a list of traits and an
+             * object of additional attributes.
+             * 
+             * @param {String}
+             *            className
+             * @param {Array
+             *            <String>} traits
+             * @param {Object}
+             *            additionalAttrs
+             * 
+             * @return {Object} the style defintion
+             */
+            this.cls = function(className, traits, additionalAttrs) {
+                var attrs = this.style(traits, additionalAttrs);
+
+                return assign(attrs, {
+                    'class': className
+                });
+            };
+
+            /**
+             * Builds a style definition from a list of traits and an object of
+             * additional attributes.
+             * 
+             * @param {Array
+             *            <String>} traits
+             * @param {Object}
+             *            additionalAttrs
+             * 
+             * @return {Object} the style defintion
+             */
+            this.style = function(traits, additionalAttrs) {
+
+                if (!isArray(traits) && !additionalAttrs) {
+                    additionalAttrs = traits;
+                    traits = [];
+                }
+
+                var attrs = reduce(traits, function(attrs, t) {
+                    return assign(attrs, defaultTraits[t] || {});
+                }, {});
+
+                return additionalAttrs ? assign(attrs, additionalAttrs) : attrs;
+            };
+        }
+
+        module.exports = Styles;
+    }, {
+        "lodash/collection/reduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\reduce.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\index.js": [function(require, module, exports) {
+        module.exports = {
+            renderer: ['type', require('./Renderer')],
+            styles: ['type', require('./Styles')]
+        };
+    }, {
+        "./Renderer": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Renderer.js",
+        "./Styles": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Styles.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\BendpointMove.js": [function(require, module, exports) {
+        'use strict';
+
+        var Geometry = require('../../util/Geometry'),
+            Util = require('./Util');
+
+        var MARKER_OK = 'connect-ok',
+            MARKER_NOT_OK = 'connect-not-ok',
+            MARKER_CONNECT_HOVER = 'connect-hover',
+            MARKER_CONNECT_UPDATING = 'djs-updating';
+
+        var COMMAND_BENDPOINT_UPDATE = 'connection.updateWaypoints',
+            COMMAND_RECONNECT_START = 'connection.reconnectStart',
+            COMMAND_RECONNECT_END = 'connection.reconnectEnd';
+
+        var round = Math.round;
+
+
+        /**
+         * A component that implements moving of bendpoints
+         */
+        function BendpointMove(injector, eventBus, canvas, dragging, graphicsFactory, rules, modeling) {
+
+            var connectionDocking;
+
+            // optional connection docking integration
+            try {
+                connectionDocking = injector.get('connectionDocking');
+            } catch (e) {}
+
+
+            // API
+
+            this.start = function(event, connection, bendpointIndex, insert) {
+
+                var type,
+                    context,
+                    waypoints = connection.waypoints,
+                    gfx = canvas.getGraphics(connection);
+
+                if (!insert && bendpointIndex === 0) {
+                    type = COMMAND_RECONNECT_START;
+                } else
+                if (!insert && bendpointIndex === waypoints.length - 1) {
+                    type = COMMAND_RECONNECT_END;
+                } else {
+                    type = COMMAND_BENDPOINT_UPDATE;
+                }
+
+                context = {
+                    connection: connection,
+                    bendpointIndex: bendpointIndex,
+                    insert: insert,
+                    type: type
+                };
+
+                dragging.activate(event, 'bendpoint.move', {
+                    data: {
+                        connection: connection,
+                        connectionGfx: gfx,
+                        context: context
+                    }
+                });
+            };
+
+
+            // DRAGGING IMPLEMENTATION
+
+
+            function redrawConnection(data) {
+                graphicsFactory.update('connection', data.connection, data.connectionGfx);
+            }
+
+            function filterRedundantWaypoints(waypoints) {
+                return waypoints.filter(function(r, idx) {
+                    return !Geometry.pointsOnLine(waypoints[idx - 1], waypoints[idx + 1], r);
+                });
+            }
+
+            eventBus.on('bendpoint.move.start', function(e) {
+
+                var context = e.context,
+                    connection = context.connection,
+                    originalWaypoints = connection.waypoints,
+                    waypoints = originalWaypoints.slice(),
+                    insert = context.insert,
+                    idx = context.bendpointIndex;
+
+                context.originalWaypoints = originalWaypoints;
+
+                if (insert) {
+                    // insert placeholder for bendpoint to-be-added
+                    waypoints.splice(idx, 0, null);
+                }
+
+                connection.waypoints = waypoints;
+
+                // add dragger gfx
+                context.draggerGfx = Util.addBendpoint(canvas.getLayer('overlays'));
+                context.draggerGfx.addClass('djs-dragging');
+
+                canvas.addMarker(connection, MARKER_CONNECT_UPDATING);
+            });
+
+            eventBus.on('bendpoint.move.hover', function(e) {
+                e.context.hover = e.hover;
+
+                canvas.addMarker(e.hover, MARKER_CONNECT_HOVER);
+            });
+
+            eventBus.on([
+                'bendpoint.move.out',
+                'bendpoint.move.cleanup'
+            ], function(e) {
+
+                // remove connect marker
+                // if it was added
+                var hover = e.context.hover;
+
+                if (hover) {
+                    canvas.removeMarker(hover, MARKER_CONNECT_HOVER);
+                    canvas.removeMarker(hover, e.context.target ? MARKER_OK : MARKER_NOT_OK);
+                }
+            });
+
+            eventBus.on('bendpoint.move.move', function(e) {
+
+                var context = e.context,
+                    moveType = context.type,
+                    connection = e.connection,
+                    source, target;
+
+                connection.waypoints[context.bendpointIndex] = {
+                    x: e.x,
+                    y: e.y
+                };
+
+                if (connectionDocking) {
+
+                    if (context.hover) {
+                        if (moveType === COMMAND_RECONNECT_START) {
+                            source = context.hover;
+                        }
+
+                        if (moveType === COMMAND_RECONNECT_END) {
+                            target = context.hover;
+                        }
+                    }
+
+                    connection.waypoints = connectionDocking.getCroppedWaypoints(connection, source, target);
+                }
+
+                // asks whether reconnect / bendpoint move / bendpoint add
+                // is allowed at the given position
+                var allowed = context.allowed = rules.allowed(context.type, context);
+
+                if (allowed) {
+
+                    if (context.hover) {
+                        canvas.removeMarker(context.hover, MARKER_NOT_OK);
+                        canvas.addMarker(context.hover, MARKER_OK);
+
+                        context.target = context.hover;
+                    }
+                } else
+                if (allowed === false) {
+                    if (context.hover) {
+                        canvas.removeMarker(context.hover, MARKER_OK);
+                        canvas.addMarker(context.hover, MARKER_NOT_OK);
+
+                        context.target = null;
+                    }
+                }
+
+                // add dragger gfx
+                context.draggerGfx.translate(e.x, e.y);
+
+                redrawConnection(e);
+            });
+
+            eventBus.on([
+                'bendpoint.move.end',
+                'bendpoint.move.cancel'
+            ], function(e) {
+
+                var context = e.context,
+                    connection = context.connection;
+
+                // remove dragger gfx
+                context.draggerGfx.remove();
+
+                context.newWaypoints = connection.waypoints.slice();
+
+                connection.waypoints = context.originalWaypoints;
+
+                canvas.removeMarker(connection, MARKER_CONNECT_UPDATING);
+            });
+
+            eventBus.on('bendpoint.move.end', function(e) {
+
+                var context = e.context,
+                    waypoints = context.newWaypoints,
+                    bendpointIndex = context.bendpointIndex,
+                    bendpoint = waypoints[bendpointIndex],
+                    allowed = context.allowed;
+
+                // ensure we have actual pixel values bendpoint
+                // coordinates (important when zoom level was > 1 during move)
+                bendpoint.x = round(bendpoint.x);
+                bendpoint.y = round(bendpoint.y);
+
+                if (allowed === true && context.type === COMMAND_RECONNECT_START) {
+                    modeling.reconnectStart(context.connection, context.target, bendpoint);
+                } else
+                if (allowed === true && context.type === COMMAND_RECONNECT_END) {
+                    modeling.reconnectEnd(context.connection, context.target, bendpoint);
+                } else
+                if (allowed !== false && context.type === COMMAND_BENDPOINT_UPDATE) {
+                    modeling.updateWaypoints(context.connection, filterRedundantWaypoints(waypoints));
+                } else {
+                    redrawConnection(e);
+
+                    return false;
+                }
+            });
+
+            eventBus.on('bendpoint.move.cancel', function(e) {
+                redrawConnection(e);
+            });
+        }
+
+        BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'rules', 'modeling'];
+
+        module.exports = BendpointMove;
+    }, {
+        "../../util/Geometry": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Geometry.js",
+        "./Util": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\Util.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\BendpointSnapping.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            pick = require('lodash/object/pick'),
+            forEach = require('lodash/collection/forEach');
+
+        var Snap = require('../../../vendor/snapsvg');
+
+        var round = Math.round;
+
+
+        function BendpointSnapping(eventBus) {
+
+            function snapTo(candidates, point) {
+                return Snap.snapTo(candidates, point);
+            }
+
+            function toPoint(e) {
+                return pick(e, ['x', 'y']);
+            }
+
+            function mid(element) {
+                if (element.width) {
+                    return {
+                        x: round(element.width / 2 + element.x),
+                        y: round(element.height / 2 + element.y)
+                    };
+                }
+            }
+
+            function getSnapPoints(context) {
+
+                var snapPoints = context.snapPoints,
+                    waypoints = context.connection.waypoints,
+                    bendpointIndex = context.bendpointIndex,
+                    referenceWaypoints = [waypoints[bendpointIndex - 1], waypoints[bendpointIndex + 1]];
+
+                if (!snapPoints) {
+                    context.snapPoints = snapPoints = {
+                        horizontal: [],
+                        vertical: []
+                    };
+
+                    forEach(referenceWaypoints, function(p) {
+                        // we snap on existing bendpoints only,
+                        // not placeholders that are inserted during add
+                        if (p) {
+                            p = p.original || p;
+
+                            snapPoints.horizontal.push(p.y);
+                            snapPoints.vertical.push(p.x);
+                        }
+                    });
+                }
+
+                return snapPoints;
+            }
+
+            eventBus.on('bendpoint.move.start', function(event) {
+                event.context.snapStart = toPoint(event);
+            });
+
+            eventBus.on('bendpoint.move.move', 1500, function(event) {
+
+                var context = event.context,
+                    snapPoints = getSnapPoints(context),
+                    start = context.snapStart,
+                    target = context.target,
+                    targetMid = target && mid(target),
+                    x = start.x + event.dx,
+                    y = start.y + event.dy,
+                    sx, sy;
+
+                if (!snapPoints) {
+                    return;
+                }
+
+                // snap
+                sx = snapTo(targetMid ? snapPoints.vertical.concat([targetMid.x]) : snapPoints.vertical, x);
+                sy = snapTo(targetMid ? snapPoints.horizontal.concat([targetMid.y]) : snapPoints.horizontal, y);
+
+
+                // correction x/y
+                var cx = (x - sx),
+                    cy = (y - sy);
+
+                // update delta
+                assign(event, {
+                    dx: event.dx - cx,
+                    dy: event.dy - cy,
+                    x: event.x - cx,
+                    y: event.y - cy
+                });
+            });
+        }
+
+
+        BendpointSnapping.$inject = ['eventBus'];
+
+        module.exports = BendpointSnapping;
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/pick": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\Bendpoints.js": [function(require, module, exports) {
+        'use strict';
+
+        var domEvent = require('min-dom/lib/event'),
+            Util = require('./Util');
+
+        var BENDPOINT_CLS = Util.BENDPOINT_CLS;
+
+
+        /**
+         * A service that adds editable bendpoints to connections.
+         */
+        function Bendpoints(injector, eventBus, canvas, interactionEvents, bendpointMove) {
+
+            function getConnectionIntersection(waypoints, event) {
+                var localPosition = Util.toCanvasCoordinates(canvas, event);
+                return Util.getApproxIntersection(waypoints, localPosition);
+            }
+
+            function activateBendpointMove(event, connection) {
+                var waypoints = connection.waypoints,
+                    intersection = getConnectionIntersection(waypoints, event);
+
+                if (!intersection) {
+                    return;
+                }
+
+                bendpointMove.start(event, connection, intersection.index, !intersection.bendpoint);
+            }
+
+            function getBendpointsContainer(element, create) {
+
+                var layer = canvas.getLayer('overlays'),
+                    gfx = layer.select('.djs-bendpoints[data-element-id=' + element.id + ']');
+
+                if (!gfx && create) {
+                    gfx = layer.group().addClass('djs-bendpoints').attr('data-element-id', element.id);
+
+                    domEvent.bind(gfx.node, 'mousedown', function(event) {
+                        activateBendpointMove(event, element);
+                    });
+                }
+
+                return gfx;
+            }
+
+            function createBendpoints(gfx, connection) {
+                connection.waypoints.forEach(function(p, idx) {
+                    Util.addBendpoint(gfx).translate(p.x, p.y);
+                });
+
+                // add floating bendpoint
+                Util.addBendpoint(gfx).addClass('floating');
+            }
+
+            function clearBendpoints(gfx) {
+                gfx.selectAll('.' + BENDPOINT_CLS).forEach(function(s) {
+                    s.remove();
+                });
+            }
+
+            function addBendpoints(connection) {
+                var gfx = getBendpointsContainer(connection);
+
+                if (!gfx) {
+                    gfx = getBendpointsContainer(connection, true);
+                    createBendpoints(gfx, connection);
+                }
+
+                return gfx;
+            }
+
+            function updateBendpoints(connection) {
+
+                var gfx = getBendpointsContainer(connection);
+
+                if (gfx) {
+                    clearBendpoints(gfx);
+                    createBendpoints(gfx, connection);
+                }
+            }
+
+            eventBus.on('connection.changed', function(event) {
+                updateBendpoints(event.element);
+            });
+
+            eventBus.on('connection.remove', function(event) {
+                var gfx = getBendpointsContainer(event.element);
+                if (gfx) {
+                    gfx.remove();
+                }
+            });
+
+            eventBus.on('element.marker.update', function(event) {
+
+                var element = event.element,
+                    bendpointsGfx;
+
+                if (!element.waypoints) {
+                    return;
+                }
+
+                bendpointsGfx = addBendpoints(element);
+                bendpointsGfx[event.add ? 'addClass' : 'removeClass'](event.marker);
+            });
+
+            eventBus.on('element.mousemove', function(event) {
+
+                var element = event.element,
+                    waypoints = element.waypoints,
+                    bendpointsGfx,
+                    floating,
+                    intersection;
+
+                if (waypoints) {
+
+                    bendpointsGfx = getBendpointsContainer(element, true);
+                    floating = bendpointsGfx.select('.floating');
+
+                    if (!floating) {
+                        return;
+                    }
+
+                    intersection = getConnectionIntersection(waypoints, event.originalEvent);
+
+                    if (intersection) {
+                        floating.translate(intersection.point.x, intersection.point.y);
+                    }
+                }
+            });
+
+            eventBus.on('element.mousedown', function(event) {
+
+                var originalEvent = event.originalEvent,
+                    element = event.element,
+                    waypoints = element.waypoints;
+
+                if (!waypoints) {
+                    return;
+                }
+
+                activateBendpointMove(originalEvent, element, waypoints);
+            });
+
+            eventBus.on('selection.changed', function(event) {
+                var newSelection = event.newSelection,
+                    primary = newSelection[0];
+
+                if (primary && primary.waypoints) {
+                    addBendpoints(primary);
+                }
+            });
+
+            eventBus.on('element.hover', function(event) {
+                var element = event.element;
+
+                if (element.waypoints) {
+                    addBendpoints(element);
+
+                    interactionEvents.registerEvent(event.gfx.node, 'mousemove', 'element.mousemove');
+                }
+            });
+
+            eventBus.on('element.out', function(event) {
+                interactionEvents.unregisterEvent(event.gfx.node, 'mousemove', 'element.mousemove');
+            });
+        }
+
+        Bendpoints.$inject = ['injector', 'eventBus', 'canvas', 'interactionEvents', 'bendpointMove'];
+
+        module.exports = Bendpoints;
+    }, {
+        "./Util": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\Util.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\Util.js": [function(require, module, exports) {
+        'use strict';
+
+        var Snap = require('../../../vendor/snapsvg');
+
+        var Events = require('../../util/Event'),
+            Geometry = require('../../util/Geometry');
+
+        var BENDPOINT_CLS = module.exports.BENDPOINT_CLS = 'djs-bendpoint';
+
+        module.exports.toCanvasCoordinates = function(canvas, event) {
+
+            var position = Events.toPoint(event),
+                clientRect = canvas._container.getBoundingClientRect(),
+                offset;
+
+            // canvas relative position
+
+            offset = {
+                x: clientRect.left,
+                y: clientRect.top
+            };
+
+            // update actual event payload with canvas relative measures
+
+            var viewbox = canvas.viewbox();
+
+            return {
+                x: viewbox.x + (position.x - offset.x) / viewbox.scale,
+                y: viewbox.y + (position.y - offset.y) / viewbox.scale
+            };
+        };
+
+        module.exports.addBendpoint = function(parentGfx) {
+            var groupGfx = parentGfx.group().addClass(BENDPOINT_CLS);
+
+            groupGfx.circle(0, 0, 4).addClass('djs-visual');
+            groupGfx.circle(0, 0, 10).addClass('djs-hit');
+
+            return groupGfx;
+        };
+
+
+        function circlePath(center, r) {
+            var x = center.x,
+                y = center.y;
+
+            return [
+                ['M', x, y],
+                ['m', 0, -r],
+                ['a', r, r, 0, 1, 1, 0, 2 * r],
+                ['a', r, r, 0, 1, 1, 0, -2 * r],
+                ['z']
+            ];
+        }
+
+        function linePath(points) {
+            var segments = [];
+
+            points.forEach(function(p, idx) {
+                segments.push([idx === 0 ? 'M' : 'L', p.x, p.y]);
+            });
+
+            return segments;
+        }
+
+
+        var INTERSECTION_THRESHOLD = 10;
+
+        function getBendpointIntersection(waypoints, reference) {
+
+            var i, w;
+
+            for (i = 0; !!(w = waypoints[i]); i++) {
+
+                if (Geometry.distance(w, reference) <= INTERSECTION_THRESHOLD) {
+                    return {
+                        point: waypoints[i],
+                        bendpoint: true,
+                        index: i
+                    };
+                }
+            }
+
+            return null;
+        }
+
+        function getPathIntersection(waypoints, reference) {
+
+            var intersections = Snap.path.intersection(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints));
+
+            var a = intersections[0],
+                b = intersections[intersections.length - 1],
+                idx;
+
+            if (!a) {
+                // no intersection
+                return null;
+            }
+
+            if (a !== b) {
+
+                if (a.segment2 !== b.segment2) {
+                    // we use the bendpoint in between both segments
+                    // as the intersection point
+
+                    idx = Math.max(a.segment2, b.segment2) - 1;
+
+                    return {
+                        point: waypoints[idx],
+                        bendpoint: true,
+                        index: idx
+                    };
+                }
+
+                return {
+                    point: {
+                        x: (Math.round(a.x + b.x) / 2),
+                        y: (Math.round(a.y + b.y) / 2)
+                    },
+                    index: a.segment2
+                };
+            }
+
+            return {
+                point: {
+                    x: Math.round(a.x),
+                    y: Math.round(a.y)
+                },
+                index: a.segment2
+            };
+        }
+
+        /**
+         * Returns the closest point on the connection towards a given reference point.
+         * 
+         * @param {Array
+         *            <Point>} waypoints
+         * @param {Point}
+         *            reference
+         * 
+         * @return {Object} intersection data (segment, point)
+         */
+        module.exports.getApproxIntersection = function(waypoints, reference) {
+            return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference);
+        };
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../util/Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "../../util/Geometry": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Geometry.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../dragging'), require('../rules')],
+            __init__: ['bendpoints', 'bendpointSnapping'],
+            bendpoints: ['type', require('./Bendpoints')],
+            bendpointMove: ['type', require('./BendpointMove')],
+            bendpointSnapping: ['type', require('./BendpointSnapping')]
+        };
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "./BendpointMove": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\BendpointMove.js",
+        "./BendpointSnapping": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\BendpointSnapping.js",
+        "./Bendpoints": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\bendpoints\\Bendpoints.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\ChangeSupport.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Adds change support to the diagram, including
+         * 
+         * <ul>
+         * <li>redrawing shapes and connections on change</li>
+         * </ul>
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {ElementRegistry}
+         *            elementRegistry
+         * @param {GraphicsFactory}
+         *            graphicsFactory
+         */
+        function ChangeSupport(eventBus, elementRegistry, graphicsFactory) {
+
+            // redraw shapes / connections on change
+
+            eventBus.on('element.changed', function(event) {
+
+                var element = event.element;
+
+                if (!event.gfx) {
+                    event.gfx = elementRegistry.getGraphics(element);
+                }
+
+                // shape + gfx may have been deleted
+                if (!event.gfx) {
+                    return;
+                }
+
+                if (element.waypoints) {
+                    eventBus.fire('connection.changed', event);
+                } else {
+                    eventBus.fire('shape.changed', event);
+                }
+            });
+
+            eventBus.on('elements.changed', function(event) {
+
+                var elements = event.elements;
+
+                elements.forEach(function(e) {
+                    eventBus.fire('element.changed', {
+                        element: e
+                    });
+                });
+
+                graphicsFactory.updateContainments(elements);
+            });
+
+            eventBus.on('shape.changed', function(event) {
+                graphicsFactory.update('shape', event.element, event.gfx);
+            });
+
+            eventBus.on('connection.changed', function(event) {
+                graphicsFactory.update('connection', event.element, event.gfx);
+            });
+        }
+
+        ChangeSupport.$inject = ['eventBus', 'elementRegistry', 'graphicsFactory'];
+
+        module.exports = ChangeSupport;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['changeSupport'],
+            changeSupport: ['type', require('./ChangeSupport')]
+        };
+    }, {
+        "./ChangeSupport": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\ChangeSupport.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\connect\\Connect.js": [function(require, module, exports) {
+        'use strict';
+
+        var LayoutUtil = require('../../layout/LayoutUtil');
+
+        var MARKER_OK = 'connect-ok',
+            MARKER_NOT_OK = 'connect-not-ok';
+
+
+        function Connect(eventBus, dragging, modeling, rules, canvas, renderer) {
+
+            // TODO(nre): separate UI and events
+
+            // rules
+
+            function canConnect(source, target) {
+                return rules.allowed('connection.create', {
+                    source: source,
+                    target: target
+                });
+            }
+
+
+            // layouting
+
+            function crop(start, end, source, target) {
+
+                var sourcePath = renderer.getShapePath(source),
+                    targetPath = target && renderer.getShapePath(target),
+                    connectionPath = renderer.getConnectionPath({
+                        waypoints: [start, end]
+                    });
+
+                start = LayoutUtil.getElementLineIntersection(sourcePath, connectionPath, true) || start;
+                end = (target && LayoutUtil.getElementLineIntersection(targetPath, connectionPath, false)) || end;
+
+                return [start, end];
+            }
+
+
+            // event handlers
+
+            eventBus.on('connect.move', function(event) {
+
+                var context = event.context,
+                    source = context.source,
+                    target = context.target,
+                    visual = context.visual,
+                    start, end, waypoints;
+
+                // update connection visuals during drag
+
+                start = LayoutUtil.getMidPoint(source);
+
+                end = {
+                    x: event.x,
+                    y: event.y
+                };
+
+                waypoints = crop(start, end, source, target);
+
+                visual.attr('points', [waypoints[0].x, waypoints[0].y, waypoints[1].x, waypoints[1].y]);
+            });
+
+            eventBus.on('connect.hover', function(event) {
+                var context = event.context,
+                    source = context.source,
+                    hover = event.hover,
+                    canExecute;
+
+                canExecute = context.canExecute = canConnect(source, hover);
+
+                // simply ignore hover
+                if (canExecute === null) {
+                    return;
+                }
+
+                context.target = hover;
+
+                canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK);
+            });
+
+            eventBus.on(['connect.out', 'connect.cleanup'], function(event) {
+                var context = event.context;
+
+                if (context.target) {
+                    canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+                }
+
+                context.target = null;
+            });
+
+            eventBus.on('connect.cleanup', function(event) {
+                var context = event.context;
+
+                if (context.visual) {
+                    context.visual.remove();
+                }
+            });
+
+            eventBus.on('connect.start', function(event) {
+                var context = event.context,
+                    visual;
+
+                visual = canvas.getDefaultLayer().polyline().attr({
+                    'stroke': '#333',
+                    'strokeDasharray': [1],
+                    'strokeWidth': 2,
+                    'pointer-events': 'none'
+                });
+
+                context.visual = visual;
+            });
+
+            eventBus.on('connect.end', function(event) {
+
+                var context = event.context,
+                    source = context.source,
+                    target = context.target,
+                    canExecute = context.canExecute || canConnect(source, target);
+
+                if (!canExecute) {
+                    return false;
+                }
+
+                modeling.connect(source, target);
+            });
+
+
+            // API
+
+            this.start = function(event, source, autoActivate) {
+
+                dragging.activate(event, 'connect', {
+                    autoActivate: autoActivate,
+                    data: {
+                        shape: source,
+                        context: {
+                            source: source
+                        }
+                    }
+                });
+            };
+        }
+
+        Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules', 'canvas', 'renderer'];
+
+        module.exports = Connect;
+    }, {
+        "../../layout/LayoutUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\connect\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../selection'),
+                require('../rules'),
+                require('../dragging')
+            ],
+            connect: ['type', require('./Connect')]
+        };
+
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "../selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js",
+        "./Connect": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\connect\\Connect.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\context-pad\\ContextPad.js": [function(require, module, exports) {
+        'use strict';
+
+        var isFunction = require('lodash/lang/isFunction'),
+            forEach = require('lodash/collection/forEach'),
+
+            domDelegate = require('min-dom/lib/delegate'),
+            domClear = require('min-dom/lib/clear'),
+            domEvent = require('min-dom/lib/event'),
+            domAttr = require('min-dom/lib/attr'),
+            domQuery = require('min-dom/lib/query'),
+            domClasses = require('min-dom/lib/classes'),
+            domify = require('min-dom/lib/domify');
+
+
+        var entrySelector = '.entry';
+
+
+        /**
+         * A context pad that displays element specific, contextual actions next to a
+         * diagram element.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Overlays}
+         *            overlays
+         */
+        function ContextPad(eventBus, overlays) {
+
+            this._providers = [];
+
+            this._eventBus = eventBus;
+            this._overlays = overlays;
+
+            this._current = null;
+
+            this._init();
+        }
+
+        ContextPad.$inject = ['eventBus', 'overlays'];
+
+        /**
+         * Registers events needed for interaction with other components
+         */
+        ContextPad.prototype._init = function() {
+
+            var eventBus = this._eventBus;
+
+            var self = this;
+
+            eventBus.on('selection.changed', function(e) {
+
+                var selection = e.newSelection;
+
+                if (selection.length === 1) {
+                    self.open(selection[0]);
+                } else {
+                    self.close();
+                }
+            });
+        };
+
+
+        /**
+         * Register a provider with the context pad
+         * 
+         * @param {ContextPadProvider}
+         *            provider
+         */
+        ContextPad.prototype.registerProvider = function(provider) {
+            this._providers.push(provider);
+        };
+
+
+        /**
+         * Returns the context pad entries for a given element
+         * 
+         * @param {djs.element.Base}
+         *            element
+         * 
+         * @return {Array<ContextPadEntryDescriptor>} list of entries
+         */
+        ContextPad.prototype.getEntries = function(element) {
+            var entries = {};
+
+            // loop through all providers and their entries.
+            // group entries by id so that overriding an entry is possible
+            forEach(this._providers, function(provider) {
+                var e = provider.getContextPadEntries(element);
+
+                forEach(e, function(entry, id) {
+                    entries[id] = entry;
+                });
+            });
+
+            return entries;
+        };
+
+
+        /**
+         * Trigger an action available on the opened context pad
+         * 
+         * @param {String}
+         *            action
+         * @param {Event}
+         *            event
+         */
+        ContextPad.prototype.trigger = function(action, event, autoActivate) {
+
+            var current = this._current,
+                element = current.element,
+                entries = current.entries,
+                entry,
+                handler,
+                originalEvent,
+                button = event.delegateTarget || event.target;
+
+            if (!button) {
+                return event.preventDefault();
+            }
+
+            entry = entries[domAttr(button, 'data-action')];
+            handler = entry.action;
+
+            originalEvent = event.originalEvent || event;
+
+            // simple action (via callback function)
+            if (isFunction(handler)) {
+                if (action === 'click') {
+                    return handler(originalEvent, element, autoActivate);
+                }
+            } else {
+                if (handler[action]) {
+                    return handler[action](originalEvent, element, autoActivate);
+                }
+            }
+
+            // silence other actions
+            event.preventDefault();
+        };
+
+
+        /**
+         * Open the context pad for the given element
+         * 
+         * @param {djs.model.Base}
+         *            element
+         */
+        ContextPad.prototype.open = function(element) {
+
+            if (this._current && this._current.open) {
+
+                if (this._current.element === element) {
+                    // no change needed
+                    return;
+                }
+
+                this.close();
+            }
+
+            this._updateAndOpen(element);
+        };
+
+
+        ContextPad.prototype._updateAndOpen = function(element) {
+
+            var entries = this.getEntries(element),
+                pad = this.getPad(element),
+                html = pad.html;
+
+            domClear(html);
+
+            forEach(entries, function(entry, id) {
+                var grouping = entry.group || 'default',
+                    control = domify(entry.html || '<div class="entry" draggable="true"></div>'),
+                    container;
+
+                domAttr(control, 'data-action', id);
+
+                container = domQuery('[data-group=' + grouping + ']', html);
+                if (!container) {
+                    container = domify('<div class="group" data-group="' + grouping + '"></div>');
+                    html.appendChild(container);
+                }
+
+                container.appendChild(control);
+
+                if (entry.className) {
+                    domClasses(control).add(entry.className);
+                }
+
+                if (entry.title) {
+                    domAttr(control, 'title', entry.title);
+                }
+
+                if (entry.imageUrl) {
+                    control.appendChild(domify('<img src="' + entry.imageUrl + '">'));
+                }
+            });
+
+            domClasses(html).add('open');
+
+            this._current = {
+                element: element,
+                pad: pad,
+                entries: entries,
+                open: true
+            };
+
+            this._eventBus.fire('contextPad.open', {
+                current: this._current
+            });
+        };
+
+        ContextPad.prototype.getPad = function(element) {
+
+            var self = this;
+
+            var overlays = this._overlays,
+                pads = overlays.get({
+                    element: element,
+                    type: 'context-pad'
+                });
+
+            // create context pad on demand if needed
+            if (!pads.length) {
+
+                var html = domify('<div class="djs-context-pad"></div>');
+
+                domDelegate.bind(html, entrySelector, 'click', function(event) {
+                    self.trigger('click', event);
+                });
+
+                domDelegate.bind(html, entrySelector, 'dragstart', function(event) {
+                    self.trigger('dragstart', event);
+                });
+
+                // stop propagation of mouse events
+                domEvent.bind(html, 'mousedown', function(event) {
+                    event.stopPropagation();
+                });
+
+
+                overlays.add(element, 'context-pad', {
+                    position: {
+                        right: -9,
+                        top: -6
+                    },
+                    html: html
+                });
+
+                pads = overlays.get({
+                    element: element,
+                    type: 'context-pad'
+                });
+
+                this._eventBus.fire('contextPad.create', {
+                    element: element,
+                    pad: pads[0]
+                });
+            }
+
+            return pads[0];
+        };
+
+
+        /**
+         * Close the context pad
+         */
+        ContextPad.prototype.close = function() {
+
+            var html;
+
+            if (this._current) {
+                if (this._current.open) {
+                    html = this._current.pad.html;
+                    domClasses(html).remove('open');
+                }
+
+                this._current.open = false;
+
+                this._eventBus.fire('contextPad.close', {
+                    current: this._current
+                });
+            }
+        };
+
+
+        /**
+         * Return the element the context pad is currently opened for, if it is opened.
+         * 
+         * @example
+         * 
+         * contextPad.open(shape1);
+         * 
+         * if (contextPad.isOpen()) { // yes, we are open }
+         * 
+         * @return {djs.model.Base} element
+         */
+        ContextPad.prototype.isOpen = function() {
+            return this._current && this._current.open;
+        };
+
+        module.exports = ContextPad;
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js",
+        "min-dom/lib/attr": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\attr.js",
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js",
+        "min-dom/lib/clear": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\clear.js",
+        "min-dom/lib/delegate": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\delegate.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js",
+        "min-dom/lib/query": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\query.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\context-pad\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../interaction-events'),
+                require('../overlays')
+            ],
+            contextPad: ['type', require('./ContextPad')]
+        };
+    }, {
+        "../interaction-events": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js",
+        "../overlays": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\overlays\\index.js",
+        "./ContextPad": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\context-pad\\ContextPad.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\create\\Create.js": [function(require, module, exports) {
+        'use strict';
+
+        var MARKER_OK = 'drop-ok',
+            MARKER_NOT_OK = 'drop-not-ok';
+
+
+        function Create(eventBus, dragging, rules, modeling, canvas, elementFactory, renderer, styles) {
+
+            // rules
+
+            function canCreate(shape, target, source) {
+
+                if (source) {
+                    return rules.allowed('shape.append', {
+                        source: source,
+                        shape: shape,
+                        parent: target
+                    });
+                } else {
+                    return rules.allowed('shape.create', {
+                        shape: shape,
+                        parent: target
+                    });
+                }
+            }
+
+
+            // visual helpers
+
+            function createVisual(shape) {
+                var group, preview, visual;
+
+                group = canvas.getDefaultLayer().group().attr(styles.cls('djs-drag-group', ['no-events']));
+
+                preview = group.group().addClass('djs-dragger');
+
+                preview.translate(shape.width / -2, shape.height / -2);
+
+                visual = preview.group().addClass('djs-visual');
+
+                // hijack renderer to draw preview
+                renderer.drawShape(visual, shape);
+
+                return group;
+            }
+
+
+            // event handlers
+
+            eventBus.on('create.move', function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    visual = context.visual;
+
+                // lazy init drag visual once we received the first real
+                // drag move event (this allows us to get the proper canvas local
+                // coordinates)
+                if (!visual) {
+                    visual = context.visual = createVisual(shape);
+                }
+
+                visual.translate(event.x, event.y);
+
+                var hover = event.hover,
+                    canExecute;
+
+                canExecute = context.canExecute = hover && canCreate(context.shape, hover, context.source);
+
+                // ignore hover visually if canExecute is null
+                if (hover && canExecute !== null) {
+                    context.target = hover;
+                    canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK);
+                }
+            });
+
+            eventBus.on(['create.end', 'create.out', 'create.cleanup'], function(event) {
+                var context = event.context;
+
+                if (context.target) {
+                    canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+                }
+            });
+
+            eventBus.on('create.end', function(event) {
+                var context = event.context,
+                    source = context.source,
+                    shape = context.shape,
+                    target = context.target,
+                    canExecute = context.canExecute,
+                    position = {
+                        x: event.x,
+                        y: event.y
+                    };
+
+                if (!canExecute) {
+                    return false;
+                }
+
+                if (source) {
+                    modeling.appendShape(source, shape, position, target);
+                } else {
+                    modeling.createShape(shape, position, target);
+                }
+            });
+
+
+            eventBus.on('create.cleanup', function(event) {
+                var context = event.context;
+
+                if (context.visual) {
+                    context.visual.remove();
+                }
+            });
+
+            // API
+
+            this.start = function(event, shape, source) {
+
+                dragging.activate(event, 'create', {
+                    cursor: 'grabbing',
+                    autoActivate: true,
+                    data: {
+                        shape: shape,
+                        context: {
+                            shape: shape,
+                            source: source
+                        }
+                    }
+                });
+            };
+        }
+
+        Create.$inject = ['eventBus', 'dragging', 'rules', 'modeling', 'canvas', 'elementFactory', 'renderer', 'styles'];
+
+        module.exports = Create;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\create\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../dragging'),
+                require('../selection')
+            ],
+            create: ['type', require('./Create')]
+        };
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js",
+        "./Create": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\create\\Create.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\Dragging.js": [function(require, module, exports) {
+        'use strict';
+
+        /* global TouchEvent */
+
+        var assign = require('lodash/object/assign');
+
+        var domEvent = require('min-dom/lib/event'),
+            Event = require('../../util/Event'),
+            ClickTrap = require('../../util/ClickTrap'),
+            Cursor = require('../../util/Cursor');
+
+        function suppressEvent(event) {
+            if (event instanceof MouseEvent) {
+                Event.stopEvent(event, true);
+            } else {
+                Event.preventDefault(event);
+            }
+        }
+
+        function getLength(point) {
+            return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
+        }
+
+        function substract(p1, p2) {
+            return {
+                x: p1.x - p2.x,
+                y: p1.y - p2.y
+            };
+        }
+
+        /**
+         * A helper that fires canvas localized drag events and realizes the general
+         * "drag-and-drop" look and feel.
+         * 
+         * Calling {@link Dragging#activate} activates dragging on a canvas.
+         * 
+         * It provides the following:
+         *  * emits the events `start`, `move`, `end`, `cancel` and `cleanup` via the
+         * {@link EventBus}. Each of the events is prefixed with a prefix that is
+         * assigned during activate. * sets and restores the cursor * sets and restores
+         * the selection * ensures there can be only one drag operation active at a time
+         * 
+         * Dragging may be canceled manually by calling {@link Dragging#cancel} or by
+         * pressing ESC.
+         * 
+         * @example
+         * 
+         * function MyDragComponent(eventBus, dragging) {
+         * 
+         * eventBus.on('mydrag.start', function(event) { console.log('yes, we start
+         * dragging'); });
+         * 
+         * eventBus.on('mydrag.move', function(event) { console.log('canvas local
+         * coordinates', event.x, event.y, event.dx, event.dy);
+         *  // local drag data is passed with the event event.context.foo; // "BAR"
+         *  // the original mouse event, too event.originalEvent; // MouseEvent(...) });
+         * 
+         * eventBus.on('element.click', function(event) { dragging.activate(event,
+         * 'mydrag', { cursor: 'grabbing', data: { context: { foo: "BAR" } } }); }); }
+         */
+        function Dragging(eventBus, canvas, selection) {
+
+            var defaultOptions = {
+                threshold: 5
+            };
+
+            // the currently active drag operation
+            // dragging is active as soon as this context exists.
+            //
+            // it is visually _active_ only when a context.active flag is set to true.
+            var context;
+
+
+            // helpers
+
+            function fire(type) {
+
+                var ActualEvent = require('../../core/EventBus').Event;
+
+                var event = assign(new ActualEvent(), context.payload, context.data);
+
+                // default integration
+                if (eventBus.fire('drag.' + type, event) === false) {
+                    return false;
+                }
+
+                return eventBus.fire(context.prefix + '.' + type, event);
+            }
+
+            // event listeners
+
+            function move(event, activate) {
+
+                var payload = context.payload,
+                    start = context.start,
+                    position = Event.toPoint(event),
+                    delta = substract(position, start),
+                    clientRect = canvas._container.getBoundingClientRect(),
+                    offset;
+
+                // canvas relative position
+
+                offset = {
+                    x: clientRect.left,
+                    y: clientRect.top
+                };
+
+                // update actual event payload with canvas relative measures
+
+                var viewbox = canvas.viewbox();
+
+                var movement = {
+                    x: viewbox.x + (position.x - offset.x) / viewbox.scale,
+                    y: viewbox.y + (position.y - offset.y) / viewbox.scale,
+                    dx: delta.x / viewbox.scale,
+                    dy: delta.y / viewbox.scale
+                };
+
+                // activate context explicitly or once threshold is reached
+
+                if (!context.active && (activate || getLength(delta) > context.threshold)) {
+
+                    // fire start event with original
+                    // starting coordinates
+
+                    assign(payload, {
+                        x: movement.x - movement.dx,
+                        y: movement.y - movement.dy,
+                        dx: 0,
+                        dy: 0
+                    }, {
+                        originalEvent: event
+                    });
+
+                    if (false === fire('start')) {
+                        return cancel();
+                    }
+
+                    context.active = true;
+
+                    // unset selection
+                    if (!context.keepSelection) {
+                        context.previousSelection = selection.get();
+                        selection.select(null);
+                    }
+
+                    // allow custom cursor
+                    if (context.cursor) {
+                        Cursor.set(context.cursor);
+                    }
+                }
+
+                suppressEvent(event);
+
+                if (context.active) {
+
+                    // fire move event with actual coordinates
+                    assign(payload, movement, {
+                        originalEvent: event
+                    });
+
+                    fire('move');
+                }
+            }
+
+            function end(event) {
+
+                var returnValue = true;
+
+                if (context.active) {
+
+                    if (event) {
+                        context.payload.originalEvent = event;
+
+                        // suppress original event (click, ...)
+                        // because we just ended a drag operation
+                        suppressEvent(event);
+                    }
+
+                    // implementations may stop restoring the
+                    // original state (selections, ...) by preventing the
+                    // end events default action
+                    returnValue = fire('end');
+                }
+
+                if (returnValue === false) {
+                    fire('rejected');
+                }
+
+                cleanup(returnValue !== true);
+            }
+
+
+            // cancel active drag operation if the user presses
+            // the ESC key on the keyboard
+
+            function checkCancel(event) {
+
+                if (event.which === 27) {
+                    event.preventDefault();
+
+                    cancel();
+                }
+            }
+
+
+            // prevent ghost click that might occur after a finished
+            // drag and drop session
+
+            function trapClickAndEnd(event) {
+
+                var untrap;
+
+                // trap the click in case we are part of an active
+                // drag operation. This will effectively prevent
+                // the ghost click that cannot be canceled otherwise.
+                if (context.active) {
+                    untrap = ClickTrap.install();
+                    setTimeout(untrap, 400);
+                }
+
+                end(event);
+            }
+
+            function trapTouch(event) {
+                move(event);
+            }
+
+            // update the drag events hover (djs.model.Base) and hoverGfx
+            // (Snap<SVGElement>)
+            // properties during hover and out and fire {prefix}.hover and {prefix}.out
+            // properties
+            // respectively
+
+            function hover(event) {
+                var payload = context.payload;
+
+                payload.hoverGfx = event.gfx;
+                payload.hover = event.element;
+
+                fire('hover');
+            }
+
+            function out(event) {
+                fire('out');
+
+                var payload = context.payload;
+
+                payload.hoverGfx = null;
+                payload.hover = null;
+            }
+
+
+            // life-cycle methods
+
+            function cancel(restore) {
+
+                if (!context) {
+                    return;
+                }
+
+                if (context.active) {
+                    fire('cancel');
+                }
+
+                cleanup(restore);
+            }
+
+            function cleanup(restore) {
+
+                fire('cleanup');
+
+                // reset cursor
+                Cursor.unset();
+
+                // reset dom listeners
+                domEvent.unbind(document, 'mousemove', move);
+
+                domEvent.unbind(document, 'mousedown', trapClickAndEnd, true);
+                domEvent.unbind(document, 'mouseup', trapClickAndEnd, true);
+
+                domEvent.unbind(document, 'keyup', checkCancel);
+
+                domEvent.unbind(document, 'touchstart', trapTouch, true);
+                domEvent.unbind(document, 'touchcancel', cancel, true);
+                domEvent.unbind(document, 'touchmove', move, true);
+                domEvent.unbind(document, 'touchend', end, true);
+
+                eventBus.off('element.hover', hover);
+                eventBus.off('element.out', out);
+
+                // restore selection, unless it has changed
+                if (restore !== false && context.previousSelection && !selection.get().length) {
+                    selection.select(context.previousSelection);
+                }
+
+                context = null;
+            }
+
+            /**
+             * Activate a drag operation
+             * 
+             * @param {MouseEvent|TouchEvent}
+             *            [event]
+             * @param {String}
+             *            prefix
+             * @param {Object}
+             *            [options]
+             */
+            function activate(event, prefix, options) {
+
+                // only one drag operation may be active, at a time
+                if (context) {
+                    cancel(false);
+                }
+
+                options = assign({}, defaultOptions, options || {});
+
+                var data = options.data || {},
+                    originalEvent,
+                    start;
+
+                if (event) {
+                    originalEvent = Event.getOriginal(event) || event;
+                    start = Event.toPoint(event);
+
+                    suppressEvent(event);
+                } else {
+                    originalEvent = null;
+                    start = {
+                        x: 0,
+                        y: 0
+                    };
+                }
+
+                context = assign({
+                    prefix: prefix,
+                    data: data,
+                    payload: {},
+                    start: start
+                }, options);
+
+                // skip dom registration if trigger
+                // is set to manual (during testing)
+                if (!options.manual) {
+
+                    // add dom listeners
+
+                    // fixes TouchEvent not being available on desktop Firefox
+                    if (typeof TouchEvent !== 'undefined' && originalEvent instanceof TouchEvent) {
+                        domEvent.bind(document, 'touchstart', trapTouch, true);
+                        domEvent.bind(document, 'touchcancel', cancel, true);
+                        domEvent.bind(document, 'touchmove', move, true);
+                        domEvent.bind(document, 'touchend', end, true);
+                    } else {
+                        // assume we use the mouse to interact per default
+                        domEvent.bind(document, 'mousemove', move);
+
+                        domEvent.bind(document, 'mousedown', trapClickAndEnd, true);
+                        domEvent.bind(document, 'mouseup', trapClickAndEnd, true);
+                    }
+
+                    domEvent.bind(document, 'keyup', checkCancel);
+
+                    eventBus.on('element.hover', hover);
+                    eventBus.on('element.out', out);
+                }
+
+                fire('activate');
+
+                if (options.autoActivate) {
+                    move(event, true);
+                }
+            }
+
+            // cancel on diagram destruction
+            eventBus.on('diagram.destroy', cancel);
+
+
+            // API
+
+            this.activate = activate;
+            this.move = move;
+            this.hover = hover;
+            this.out = out;
+            this.end = end;
+
+            this.cancel = cancel;
+
+            // for introspection
+
+            this.active = function() {
+                return context;
+            };
+
+            this.setOptions = function(options) {
+                assign(defaultOptions, options);
+            };
+        }
+
+        Dragging.$inject = ['eventBus', 'canvas', 'selection'];
+
+        module.exports = Dragging;
+    }, {
+        "../../core/EventBus": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\core\\EventBus.js",
+        "../../util/ClickTrap": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\ClickTrap.js",
+        "../../util/Cursor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Cursor.js",
+        "../../util/Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../selection')
+            ],
+            dragging: ['type', require('./Dragging')]
+        };
+    }, {
+        "../selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js",
+        "./Dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\Dragging.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\InteractionEvents.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            domDelegate = require('min-dom/lib/delegate'),
+            Renderer = require('../../draw/Renderer'),
+            createLine = Renderer.createLine,
+            updateLine = Renderer.updateLine;
+
+
+        var isPrimaryButton = require('../../util/Mouse').isPrimaryButton;
+
+        var Snap = require('../../../vendor/snapsvg');
+
+        /**
+         * A plugin that provides interaction events for diagram elements.
+         * 
+         * It emits the following events:
+         *  * element.hover * element.out * element.click * element.dblclick *
+         * element.mousedown
+         * 
+         * Each event is a tuple { element, gfx, originalEvent }.
+         * 
+         * Canceling the event via Event#preventDefault() prevents the original DOM
+         * operation.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         */
+        function InteractionEvents(eventBus, elementRegistry, styles) {
+
+            var HIT_STYLE = styles.cls('djs-hit', ['no-fill', 'no-border'], {
+                stroke: 'white',
+                strokeWidth: 15
+            });
+
+            function fire(type, event) {
+                var target = event.delegateTarget || event.target,
+                    gfx = target && new Snap(target),
+                    element = elementRegistry.get(gfx),
+                    returnValue;
+
+                if (!gfx || !element) {
+                    return;
+                }
+
+                returnValue = eventBus.fire(type, {
+                    element: element,
+                    gfx: gfx,
+                    originalEvent: event
+                });
+
+                if (returnValue === false) {
+                    event.stopPropagation();
+                    event.preventDefault();
+                }
+            }
+
+            var handlers = {};
+
+            function mouseHandler(type) {
+
+                var fn = handlers[type];
+
+                if (!fn) {
+                    fn = handlers[type] = function(event) {
+                        // only indicate left mouse button interactions
+                        if (isPrimaryButton(event)) {
+                            fire(type, event);
+                        }
+                    };
+                }
+
+                return fn;
+            }
+
+            var bindings = {
+                mouseover: 'element.hover',
+                mouseout: 'element.out',
+                click: 'element.click',
+                dblclick: 'element.dblclick',
+                mousedown: 'element.mousedown',
+                mouseup: 'element.mouseup',
+                keydown: 'element.keyup'
+
+            };
+
+            var elementSelector = 'svg, .djs-element';
+
+            // /// event registration
+
+            function registerEvent(node, event, localEvent) {
+                var handler = mouseHandler(localEvent);
+                handler.$delegate = domDelegate.bind(node, elementSelector, event, handler);
+            }
+
+            function unregisterEvent(node, event, localEvent) {
+                domDelegate.unbind(node, event, mouseHandler(localEvent).$delegate);
+            }
+
+            function registerEvents(svg) {
+                forEach(bindings, function(val, key) {
+                    registerEvent(svg.node, key, val);
+                });
+            }
+
+            function unregisterEvents(svg) {
+                forEach(bindings, function(val, key) {
+                    unregisterEvent(svg.node, key, val);
+                });
+            }
+
+            eventBus.on('canvas.destroy', function(event) {
+                unregisterEvents(event.svg);
+            });
+
+            eventBus.on('canvas.init', function(event) {
+                registerEvents(event.svg);
+            });
+
+
+            eventBus.on(['shape.added', 'connection.added'], function(event) {
+                var element = event.element,
+                    gfx = event.gfx,
+                    hit,
+                    type;
+
+                if (element.waypoints) {
+                    hit = createLine(element.waypoints);
+                    type = 'connection';
+                } else {
+                    hit = Snap.create('rect', {
+                        x: 0,
+                        y: 0,
+                        width: element.width,
+                        height: element.height
+                    });
+                    type = 'shape';
+                }
+
+                hit.attr(HIT_STYLE).appendTo(gfx.node);
+            });
+
+            // update djs-hit on change
+
+            eventBus.on('shape.changed', function(event) {
+
+                var element = event.element,
+                    gfx = event.gfx,
+                    hit = gfx.select('.djs-hit');
+
+                hit.attr({
+                    width: element.width,
+                    height: element.height
+                });
+            });
+
+            eventBus.on('connection.changed', function(event) {
+
+                var element = event.element,
+                    gfx = event.gfx,
+                    hit = gfx.select('.djs-hit');
+
+                updateLine(hit, element.waypoints);
+            });
+
+
+            // API
+
+            this.fire = fire;
+
+            this.mouseHandler = mouseHandler;
+
+            this.registerEvent = registerEvent;
+            this.unregisterEvent = unregisterEvent;
+        }
+
+
+        InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles'];
+
+        module.exports = InteractionEvents;
+
+
+        /**
+         * An event indicating that the mouse hovered over an element
+         * 
+         * @event element.hover
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+
+        /**
+         * An event indicating that the mouse has left an element
+         * 
+         * @event element.out
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+
+        /**
+         * An event indicating that the mouse has clicked an element
+         * 
+         * @event element.click
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+
+        /**
+         * An event indicating that the mouse has double clicked an element
+         * 
+         * @event element.dblclick
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+
+        /**
+         * An event indicating that the mouse has gone down on an element.
+         * 
+         * @event element.mousedown
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+
+        /**
+         * An event indicating that the mouse has gone up on an element.
+         * 
+         * @event element.mouseup
+         * 
+         * @type {Object}
+         * @property {djs.model.Base} element
+         * @property {Snap<Element>} gfx
+         * @property {Event} originalEvent
+         */
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../draw/Renderer": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\draw\\Renderer.js",
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "min-dom/lib/delegate": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\delegate.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['interactionEvents'],
+            interactionEvents: ['type', require('./InteractionEvents')]
+        };
+    }, {
+        "./InteractionEvents": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\InteractionEvents.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\keyboard\\Keyboard.js": [function(require, module, exports) {
+        'use strict';
+
+        var domEvent = require('min-dom/lib/event'),
+            domMatches = require('min-dom/lib/matches');
+        //keyboard.bindTo=DOMElement;
+       // var $ = require('jquery'),
+       
+       
+        
+        
+        /**
+         * A keyboard abstraction that may be activated and
+         * deactivated by users at will, consuming key events
+         * and triggering diagram actions.
+         *
+         * The implementation fires the following key events that allow
+         * other components to hook into key handling:
+         *
+         *  - keyboard.bind
+         *  - keyboard.unbind
+         *  - keyboard.init
+         *  - keyboard.destroy
+         *
+         * All events contain the fields (node, listeners).
+         *
+         * A default binding for the keyboard may be specified via the
+         * `keyboard.bindTo` configuration option.
+         *
+         * @param {EventBus} eventBus
+         * @param {CommandStack} commandStack
+         * @param {Modeling} modeling
+         * @param {Selection} selection
+         * 
+         */
+        
+        function Keyboard(config, eventBus, commandStack, modeling, selection, zoomScroll, canvas) {
+          
+          $(document).keydown(function(e){
+                 if(commandStack._selectedModel == selected_model){
+                         if(commandStack._eventBus._listeners != null){
+                                 
+                                 var model_commandStack = [];
+                                 for(var i = 0; i < commandStackList.length; i++){
+                                         if(commandStackList[i]._selectedModel == selected_model){
+                                                 if(commandStackList[i]._stack.length > 0){
+                                                         model_commandStack.push(commandStackList[i]); 
+                                                 }
+                                         }
+                                 }
+                                 
+                                 var selected_commandStack;
+                                 for(var i = model_commandStack.length-1; i >= 0; i--){
+                                         if(model_commandStack[i]._stackIdx > -1){
+                                                 selected_commandStack = model_commandStack[i];
+                                                 break;
+                                         }
+                                 }
+                                 
+                              if(e.which == 90 && e.ctrlKey){
+                                  if(commandStack == selected_commandStack){
+                                                  commandStack.undo();
+                                                  return true;
+                                  }
+                                  } else if(e.which == 89 && e.ctrlKey){
+                                          commandStack.redo();
+                                          return true;
+                                  } 
+                         }
+                       
+                       
+                 }
+                       
+
+               });
+               
+          var self = this;
+
+          this._commandStack = commandStack;
+          this._modeling = modeling;
+          this._selection = selection;
+          this._eventBus = eventBus;
+          this._zoomScroll = zoomScroll;
+          this._canvas = canvas;
+
+          this._listeners = [];
+
+          // our key handler is a singleton that passes
+          // (keycode, modifiers) to each listener.
+          //
+          // listeners must indicate that they handled a key event
+          // by returning true. This stops the event propagation.
+          //
+          this._keyHandler = function(event) {
+
+            var i, l,
+                target = event.target,
+                listeners = self._listeners,
+                code = event.keyCode || event.charCode || -1;
+
+            if (domMatches(target, 'input, textarea')) {
+              return;
+            }
+
+            for (i = 0; !!(l = listeners[i]); i++) {
+              if (l(code, event)) {
+                event.preventDefault();
+                event.stopPropagation();
+              }
+            }
+          };
+
+          // properly clean dom registrations
+          eventBus.on('diagram.destroy', function() {
+            self._fire('destroy');
+
+            self.unbind();
+            self._listeners = null;
+          });
+
+          eventBus.on('diagram.init', function() {
+            self._fire('init');
+
+            if (config && config.bindTo) {
+              self.bind(config.bindTo);
+            }
+          });
+
+          this._init();
+        }
+
+        Keyboard.$inject = [
+          'config.keyboard',
+          'eventBus',
+          'commandStack',
+          'modeling',
+          'selection',
+          'zoomScroll',
+          'canvas'];
+
+        module.exports = Keyboard;
+
+
+        Keyboard.prototype.bind = function(node) {
+          this._node = node;
+
+          // bind key events
+          domEvent.bind(node, 'keydown', this._keyHandler, true);
+
+          this._fire('bind');
+        };
+
+        Keyboard.prototype.getBinding = function() {
+          return this._node;
+        };
+
+        Keyboard.prototype.unbind = function() {
+          var node = this._node;
+
+          if (node) {
+            this._fire('unbind');
+
+            // unbind key events
+            domEvent.unbind(node, 'keydown', this._keyHandler, true);
+          }
+
+          this._node = null;
+        };
+
+
+        Keyboard.prototype._fire = function(event) {
+          this._eventBus.fire('keyboard.' + event, { node: this._node, listeners: this._listeners });
+          
+          
+        };
+      
+
+        
+        Keyboard.prototype._init = function() {
+
+          var listeners = this._listeners,
+              commandStack = this._commandStack,
+              modeling = this._modeling,
+              selection = this._selection,
+              zoomScroll = this._zoomScroll,
+              canvas = this._canvas;
+          
+          // init default listeners
+
+          // undo
+          // (CTRL|CMD) + Z
+          function undo(key, modifiers) {
+                 
+            if (isCmd(modifiers) && !isShift(modifiers) && key === 90) {
+              commandStack.undo();
+
+              return true;
+            }
+          }
+
+          // redo
+          // CTRL + Y
+          // CMD + SHIFT + Z
+          function redo(key, modifiers) {
+
+            if (isCmd(modifiers) && (key === 89 || (key === 90 && isShift(modifiers)))) {
+              commandStack.redo();
+
+              return true;
+            }
+          }
+
+          /**
+           * zoom in one step
+           * CTRL + +
+           *
+           * 107 = numpad plus
+           * 187 = regular plus
+           * 171 = regular plus in Firefox (german keyboard layout)
+           *  61 = regular plus in Firefox (US keyboard layout)
+           */
+          function zoomIn(key, modifiers) {
+
+            if ((key === 107 || key === 187 || key === 171 || key === 61) && isCmd(modifiers)) {
+
+              zoomScroll.stepZoom(1);
+
+              return true;
+            }
+          }
+
+          /**
+           * zoom out one step
+           * CTRL + -
+           *
+           * 109 = numpad minus
+           * 189 = regular minus
+           * 173 = regular minus in Firefox (US and german keyboard layout)
+           */
+          function zoomOut(key, modifiers) {
+
+            if ((key === 109 || key === 189 || key === 173)  && isCmd(modifiers)) {
+
+              zoomScroll.stepZoom(-1);
+
+              return true;
+            }
+          }
+
+          /**
+           * zoom to the default level
+           * CTRL + 0
+           *
+           * 96 = numpad zero
+           * 48 = regular zero
+           */
+          function zoomDefault(key, modifiers) {
+
+            if ((key === 96 || key === 48) && isCmd(modifiers)) {
+
+              canvas.zoom(1);
+
+              return true;
+            }
+          }
+
+          // delete selected element
+          // DEL
+          function remove(key, modifiers) {
+
+            if (key === 46) {
+
+              var selectedElements = selection.get();
+              console.log(selectedElements);
+              if (selectedElements.length) {
+                modeling.removeElements(selectedElements.slice());
+              }
+
+              return true;
+            }
+          }
+
+          listeners.push(undo);
+          listeners.push(redo);
+          listeners.push(remove);
+          listeners.push(zoomIn);
+          listeners.push(zoomOut);
+          listeners.push(zoomDefault);
+        };
+
+
+        /**
+         * Add a listener function that is notified with (key, modifiers) whenever
+         * the keyboard is bound and the user presses a key.
+         *
+         * @param {Function} listenerFn
+         */
+        Keyboard.prototype.addListener = function(listenerFn) {
+               
+          this._listeners.push(listenerFn);
+        };
+
+        Keyboard.prototype.hasModifier = hasModifier;
+        Keyboard.prototype.isCmd = isCmd;
+        Keyboard.prototype.isShift = isShift;
+
+
+        function hasModifier(modifiers) {
+          return (modifiers.ctrlKey || modifiers.metaKey || modifiers.shiftKey || modifiers.altKey);
+        }
+
+        function isCmd(modifiers) {
+          return modifiers.ctrlKey || modifiers.metaKey;
+        }
+
+        function isShift(modifiers) {
+          return modifiers.shiftKey;
+        }
+
+    }, {
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js",
+        "min-dom/lib/matches": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\matches.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\keyboard\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['keyboard'],
+            keyboard: ['type', require('./Keyboard')]
+        };
+
+    }, {
+        "./Keyboard": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\keyboard\\Keyboard.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\lasso-tool\\LassoTool.js": [function(require, module, exports) {
+        'use strict';
+
+        var values = require('lodash/object/values');
+
+        var getEnclosedElements = require('../../util/Elements').getEnclosedElements;
+
+        var hasPrimaryModifier = require('../../util/Mouse').hasPrimaryModifier;
+
+        var Snap = require('../../../vendor/snapsvg');
+
+
+        function LassoTool(eventBus, canvas, dragging, elementRegistry, selection) {
+
+            this._selection = selection;
+            this._dragging = dragging;
+
+            var self = this;
+
+            // lasso visuals implementation
+
+            /**
+             * A helper that realizes the selection box visual
+             */
+            var visuals = {
+
+                create: function(context) {
+                    var container = canvas.getDefaultLayer(),
+                        frame;
+
+                    frame = context.frame = Snap.create('rect', {
+                        class: 'djs-lasso-overlay',
+                        width: 1,
+                        height: 1,
+                        x: 0,
+                        y: 0
+                    });
+
+                    frame.appendTo(container);
+                },
+
+                update: function(context) {
+                    var frame = context.frame,
+                        bbox = context.bbox;
+
+                    frame.attr({
+                        x: bbox.x,
+                        y: bbox.y,
+                        width: bbox.width,
+                        height: bbox.height
+                    });
+                },
+
+                remove: function(context) {
+
+                    if (context.frame) {
+                        context.frame.remove();
+                    }
+                }
+            };
+
+
+            eventBus.on('lasso.selection.end', function(event) {
+
+                setTimeout(function() {
+                    self.activateLasso(event.originalEvent, true);
+                });
+            });
+
+            // lasso interaction implementation
+
+            eventBus.on('lasso.end', function(event) {
+
+                var bbox = toBBox(event);
+
+                var elements = elementRegistry.filter(function(element) {
+                    return element;
+                });
+
+                self.select(elements, bbox);
+            });
+
+            eventBus.on('lasso.start', function(event) {
+
+                var context = event.context;
+
+                context.bbox = toBBox(event);
+                visuals.create(context);
+            });
+
+            eventBus.on('lasso.move', function(event) {
+
+                var context = event.context;
+
+                context.bbox = toBBox(event);
+                visuals.update(context);
+            });
+
+            eventBus.on('lasso.end', function(event) {
+
+                var context = event.context;
+
+                visuals.remove(context);
+            });
+
+            eventBus.on('lasso.cleanup', function(event) {
+
+                var context = event.context;
+
+                visuals.remove(context);
+            });
+
+
+            // event integration
+
+            eventBus.on('element.mousedown', 1500, function(event) {
+
+                if (hasPrimaryModifier(event)) {
+                    self.activateLasso(event.originalEvent);
+
+                    event.stopPropagation();
+                }
+            });
+        }
+
+        LassoTool.$inject = [
+            'eventBus',
+            'canvas',
+            'dragging',
+            'elementRegistry',
+            'selection'
+        ];
+
+        module.exports = LassoTool;
+
+
+        LassoTool.prototype.activateLasso = function(event, autoActivate) {
+
+            this._dragging.activate(event, 'lasso', {
+                autoActivate: autoActivate,
+                cursor: 'crosshair',
+                data: {
+                    context: {}
+                }
+            });
+        };
+
+        LassoTool.prototype.activateSelection = function(event) {
+
+            this._dragging.activate(event, 'lasso.selection', {
+                cursor: 'crosshair'
+            });
+        };
+
+        LassoTool.prototype.select = function(elements, bbox) {
+            var selectedElements = getEnclosedElements(elements, bbox);
+
+            this._selection.select(values(selectedElements));
+        };
+
+
+        function toBBox(event) {
+
+            var start = {
+
+                x: event.x - event.dx,
+                y: event.y - event.dy
+            };
+
+            var end = {
+                x: event.x,
+                y: event.y
+            };
+
+            var bbox;
+
+            if ((start.x <= end.x && start.y < end.y) ||
+                (start.x < end.x && start.y <= end.y)) {
+
+                bbox = {
+                    x: start.x,
+                    y: start.y,
+                    width: end.x - start.x,
+                    height: end.y - start.y
+                };
+            } else if ((start.x >= end.x && start.y < end.y) ||
+                (start.x > end.x && start.y <= end.y)) {
+
+                bbox = {
+                    x: end.x,
+                    y: start.y,
+                    width: start.x - end.x,
+                    height: end.y - start.y
+                };
+            } else if ((start.x <= end.x && start.y > end.y) ||
+                (start.x < end.x && start.y >= end.y)) {
+
+                bbox = {
+                    x: start.x,
+                    y: end.y,
+                    width: end.x - start.x,
+                    height: start.y - end.y
+                };
+            } else if ((start.x >= end.x && start.y > end.y) ||
+                (start.x > end.x && start.y >= end.y)) {
+
+                bbox = {
+                    x: end.x,
+                    y: end.y,
+                    width: start.x - end.x,
+                    height: start.y - end.y
+                };
+            } else {
+
+                bbox = {
+                    x: end.x,
+                    y: end.y,
+                    width: 0,
+                    height: 0
+                };
+            }
+            return bbox;
+        }
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js",
+        "lodash/object/values": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\values.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\lasso-tool\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports = {
+            __init__: ['lassoTool'],
+            lassoTool: ['type', require('./LassoTool')]
+        };
+
+    }, {
+        "./LassoTool": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\lasso-tool\\LassoTool.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\Modeling.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var model = require('../../model');
+
+
+        /**
+         * The basic modeling entry point.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {ElementFactory}
+         *            elementFactory
+         * @param {CommandStack}
+         *            commandStack
+         */
+        function Modeling(eventBus, elementFactory, commandStack) {
+            this._eventBus = eventBus;
+            this._elementFactory = elementFactory;
+            this._commandStack = commandStack;
+            var self = this;
+
+            eventBus.on('diagram.init', function() {
+                // register modeling handlers
+                self.registerHandlers(commandStack);
+            });
+        }
+
+        Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack'];
+
+        module.exports = Modeling;
+
+
+        Modeling.prototype.getHandlers = function() {
+            return {
+                'shape.append': require('./cmd/AppendShapeHandler'),
+                'shape.create': require('./cmd/CreateShapeHandler'),
+                'shape.delete': require('./cmd/DeleteShapeHandler'),
+                'shape.move': require('./cmd/MoveShapeHandler'),
+                'shapes.move': require('./cmd/MoveShapesHandler'),
+                'shape.resize': require('./cmd/ResizeShapeHandler'),
+                'shape.replace': require('./cmd/ReplaceShapeHandler'),
+
+                'spaceTool': require('./cmd/SpaceToolHandler'),
+
+                'label.create': require('./cmd/CreateLabelHandler'),
+
+                'connection.create': require('./cmd/CreateConnectionHandler'),
+                'connection.delete': require('./cmd/DeleteConnectionHandler'),
+                'connection.move': require('./cmd/MoveConnectionHandler'),
+                'connection.layout': require('./cmd/LayoutConnectionHandler'),
+
+                'connection.updateWaypoints': require('./cmd/UpdateWaypointsHandler'),
+
+                'connection.reconnectStart': require('./cmd/ReconnectConnectionHandler'),
+                'connection.reconnectEnd': require('./cmd/ReconnectConnectionHandler'),
+
+                'elements.delete': require('./cmd/DeleteElementsHandler'),
+                'element.updateAnchors': require('./cmd/UpdateAnchorsHandler')
+            };
+        };
+
+        /**
+         * Register handlers with the command stack
+         * 
+         * @param {CommandStack}
+         *            commandStack
+         */
+        Modeling.prototype.registerHandlers = function(commandStack) {
+            forEach(this.getHandlers(), function(handler, id) {
+                commandStack.registerHandler(id, handler);
+            });
+        };
+
+
+        // /// modeling helpers /////////////////////////////////////////
+
+
+        Modeling.prototype.moveShape = function(shape, delta, newParent, hints) {
+
+            var context = {
+                shape: shape,
+                delta: delta,
+                newParent: newParent,
+                hints: hints || {}
+            };
+
+            this._commandStack.execute('shape.move', context);
+        };
+
+
+        Modeling.prototype.moveShapes = function(shapes, delta, newParent, hints) {
+
+            var context = {
+                shapes: shapes,
+                delta: delta,
+                newParent: newParent,
+                hints: hints || {}
+            };
+
+            this._commandStack.execute('shapes.move', context);
+        };
+
+        /**
+         * Update the anchors on the element with the given delta movement
+         * 
+         * @param {djs.model.Element}
+         *            element
+         * @param {Point}
+         *            delta
+         */
+        Modeling.prototype.updateAnchors = function(element, delta) {
+            var context = {
+                element: element,
+                delta: delta
+            };
+
+            this._commandStack.execute('element.updateAnchors', context);
+        };
+
+        Modeling.prototype.moveConnection = function(connection, delta, newParent, hints) {
+
+            var context = {
+                connection: connection,
+                delta: delta,
+                newParent: newParent,
+                hints: hints || {}
+            };
+
+            this._commandStack.execute('connection.move', context);
+        };
+
+
+        Modeling.prototype.layoutConnection = function(connection, hints) {
+
+            var context = {
+                connection: connection,
+                hints: hints || {}
+            };
+
+            this._commandStack.execute('connection.layout', context);
+        };
+
+
+        Modeling.prototype.createConnection = function(source, target, connection, parent) {
+
+            connection = this._create('connection', connection);
+
+            var context = {
+                source: source,
+                target: target,
+                parent: parent,
+                connection: connection
+            };
+
+            this._commandStack.execute('connection.create', context);
+
+            return context.connection;
+        };
+
+        Modeling.prototype.createShape = function(shape, position, parent) {
+
+            shape = this._create('shape', shape);
+
+            var context = {
+                position: position,
+                parent: parent,
+                shape: shape
+            };
+
+            this._commandStack.execute('shape.create', context);
+
+            return context.shape;
+        };
+
+
+        Modeling.prototype.createLabel = function(labelTarget, position, label, parent) {
+
+            label = this._create('label', label);
+
+            var context = {
+                labelTarget: labelTarget,
+                position: position,
+                parent: parent,
+                shape: label
+            };
+
+            this._commandStack.execute('label.create', context);
+
+            return context.shape;
+        };
+
+
+        Modeling.prototype.appendShape = function(source, shape, position, parent, connection, connectionParent) {
+
+            shape = this._create('shape', shape);
+
+            var context = {
+                source: source,
+                position: position,
+                parent: parent,
+                shape: shape,
+                connection: connection,
+                connectionParent: connectionParent
+            };
+
+            this._commandStack.execute('shape.append', context);
+
+            return context.shape;
+        };
+
+
+        Modeling.prototype.removeElements = function(elements) {
+          console.log(elements);
+            var context = {
+                elements: elements
+            };
+
+            this._commandStack.execute('elements.delete', context);
+        };
+
+
+        Modeling.prototype.removeShape = function(shape) {
+            var context = {
+                shape: shape
+            };
+
+            this._commandStack.execute('shape.delete', context);
+        };
+
+
+        Modeling.prototype.removeConnection = function(connection) {
+            var context = {
+                connection: connection
+            };
+
+            this._commandStack.execute('connection.delete', context);
+        };
+
+        Modeling.prototype.replaceShape = function(oldShape, newShape, options) {
+            var context = {
+                oldShape: oldShape,
+                newData: newShape,
+                options: options
+            };
+
+            this._commandStack.execute('shape.replace', context);
+
+            return context.newShape;
+        };
+
+        Modeling.prototype.resizeShape = function(shape, newBounds) {
+            var context = {
+                shape: shape,
+                newBounds: newBounds
+            };
+
+            this._commandStack.execute('shape.resize', context);
+        };
+
+        Modeling.prototype.createSpace = function(movingShapes, resizingShapes, delta, direction) {
+            var context = {
+                movingShapes: movingShapes,
+                resizingShapes: resizingShapes,
+                delta: delta,
+                direction: direction
+            };
+
+            this._commandStack.execute('spaceTool', context);
+        };
+
+        Modeling.prototype.updateWaypoints = function(connection, newWaypoints) {
+            var context = {
+                connection: connection,
+                newWaypoints: newWaypoints
+            };
+
+            this._commandStack.execute('connection.updateWaypoints', context);
+        };
+
+        Modeling.prototype.reconnectStart = function(connection, newSource, dockingPoint) {
+            var context = {
+                connection: connection,
+                newSource: newSource,
+                dockingPoint: dockingPoint
+            };
+
+            this._commandStack.execute('connection.reconnectStart', context);
+        };
+
+        Modeling.prototype.reconnectEnd = function(connection, newTarget, dockingPoint) {
+            var context = {
+                connection: connection,
+                newTarget: newTarget,
+                dockingPoint: dockingPoint
+            };
+
+            this._commandStack.execute('connection.reconnectEnd', context);
+        };
+
+        Modeling.prototype.connect = function(source, target, attrs) {
+            return this.createConnection(source, target, attrs || {}, source.parent);
+        };
+
+
+        Modeling.prototype._create = function(type, attrs) {
+            if (attrs instanceof model.Base) {
+                return attrs;
+            } else {
+                return this._elementFactory.create(type, attrs);
+            }
+        };
+
+    }, {
+        "../../model": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\model\\index.js",
+        "./cmd/AppendShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\AppendShapeHandler.js",
+        "./cmd/CreateConnectionHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateConnectionHandler.js",
+        "./cmd/CreateLabelHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateLabelHandler.js",
+        "./cmd/CreateShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateShapeHandler.js",
+        "./cmd/DeleteConnectionHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteConnectionHandler.js",
+        "./cmd/DeleteElementsHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteElementsHandler.js",
+        "./cmd/DeleteShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteShapeHandler.js",
+        "./cmd/LayoutConnectionHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\LayoutConnectionHandler.js",
+        "./cmd/MoveConnectionHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveConnectionHandler.js",
+        "./cmd/MoveShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveShapeHandler.js",
+        "./cmd/MoveShapesHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveShapesHandler.js",
+        "./cmd/ReconnectConnectionHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ReconnectConnectionHandler.js",
+        "./cmd/ReplaceShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ReplaceShapeHandler.js",
+        "./cmd/ResizeShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ResizeShapeHandler.js",
+        "./cmd/SpaceToolHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\SpaceToolHandler.js",
+        "./cmd/UpdateAnchorsHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\UpdateAnchorsHandler.js",
+        "./cmd/UpdateWaypointsHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\UpdateWaypointsHandler.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\AppendShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+
+        /**
+         * A handler that implements reversible appending of shapes to a source shape.
+         * 
+         * @param {canvas}
+         *            Canvas
+         * @param {elementFactory}
+         *            ElementFactory
+         * @param {modeling}
+         *            Modeling
+         */
+        function AppendShapeHandler(modeling) {
+            this._modeling = modeling;
+        }
+
+        inherits(AppendShapeHandler, require('./NoopHandler'));
+
+
+        AppendShapeHandler.$inject = ['modeling'];
+
+        module.exports = AppendShapeHandler;
+
+
+        // //// api /////////////////////////////////////////////
+
+        /**
+         * Creates a new shape
+         * 
+         * @param {Object}
+         *            context
+         * @param {ElementDescriptor}
+         *            context.shape the new shape
+         * @param {ElementDescriptor}
+         *            context.source the source object
+         * @param {ElementDescriptor}
+         *            context.parent the parent object
+         * @param {Point}
+         *            context.position position of the new element
+         */
+        AppendShapeHandler.prototype.preExecute = function(context) {
+
+            if (!context.source) {
+                throw new Error('source required');
+            }
+
+            var parent = context.parent || context.source.parent,
+                shape = this._modeling.createShape(context.shape, context.position, parent);
+
+            context.shape = shape;
+        };
+
+        AppendShapeHandler.prototype.postExecute = function(context) {
+            var parent = context.connectionParent || context.shape.parent;
+
+            // create connection
+            this._modeling.connect(context.source, context.shape, context.connection, parent);
+        };
+    }, {
+        "./NoopHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\NoopHandler.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateConnectionHandler.js": [function(require, module, exports) {
+        'use strict';
+
+
+        function CreateConnectionHandler(canvas, layouter) {
+            this._canvas = canvas;
+            this._layouter = layouter;
+        }
+
+        CreateConnectionHandler.$inject = ['canvas', 'layouter'];
+
+        module.exports = CreateConnectionHandler;
+
+
+
+        // //// api /////////////////////////////////////////
+
+        /**
+         * Appends a shape to a target shape
+         * 
+         * @param {Object}
+         *            context
+         * @param {djs.element.Base}
+         *            context.source the source object
+         * @param {djs.element.Base}
+         *            context.target the parent object
+         * @param {Point}
+         *            context.position position of the new element
+         */
+        CreateConnectionHandler.prototype.execute = function(context) {
+
+            var source = context.source,
+                target = context.target,
+                parent = context.parent;
+
+            if (!source || !target) {
+                throw new Error('source and target required');
+            }
+
+            if (!parent) {
+                throw new Error('parent required');
+            }
+
+            var connection = context.connection;
+
+            connection.source = source;
+            connection.target = target;
+
+            if (!connection.waypoints) {
+                connection.waypoints = this._layouter.layoutConnection(connection);
+            }
+
+            // add connection
+            this._canvas.addConnection(connection, parent);
+
+            return connection;
+        };
+
+        CreateConnectionHandler.prototype.revert = function(context) {
+            var connection = context.connection;
+
+            this._canvas.removeConnection(connection);
+
+            connection.source = null;
+            connection.target = null;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateLabelHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var CreateShapeHandler = require('./CreateShapeHandler');
+
+
+        /**
+         * A handler that attaches a label to a given target shape.
+         * 
+         * @param {canvas}
+         *            Canvas
+         */
+        function CreateLabelHandler(canvas) {
+            CreateShapeHandler.call(this, canvas);
+        }
+
+        inherits(CreateLabelHandler, CreateShapeHandler);
+
+        CreateLabelHandler.$inject = ['canvas'];
+
+        module.exports = CreateLabelHandler;
+
+
+
+        // //// api /////////////////////////////////////////
+
+
+        /**
+         * Appends a label to a target shape.
+         * 
+         * @method CreateLabelHandler#execute
+         * 
+         * @param {Object}
+         *            context
+         * @param {ElementDescriptor}
+         *            context.target the element the label is attached to
+         * @param {ElementDescriptor}
+         *            context.parent the parent object
+         * @param {Point}
+         *            context.position position of the new element
+         */
+
+        /**
+         * Undo append by removing the shape
+         */
+        CreateLabelHandler.prototype.revert = function(context) {
+            context.shape.labelTarget = null;
+            this._canvas.removeShape(context.shape);
+        };
+
+
+        // //// helpers /////////////////////////////////////////
+
+        CreateLabelHandler.prototype.getParent = function(context) {
+            return context.parent || context.labelTarget && context.labelTarget.parent;
+        };
+
+        CreateLabelHandler.prototype.addElement = function(shape, parent, context) {
+            shape.labelTarget = context.labelTarget;
+            this._canvas.addShape(shape, parent, true);
+        };
+    }, {
+        "./CreateShapeHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateShapeHandler.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\CreateShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+
+        /**
+         * A handler that implements reversible addition of shapes.
+         * 
+         * @param {canvas}
+         *            Canvas
+         */
+        function CreateShapeHandler(canvas) {
+            this._canvas = canvas;
+        }
+
+        CreateShapeHandler.$inject = ['canvas'];
+
+        module.exports = CreateShapeHandler;
+
+
+
+        // //// api /////////////////////////////////////////
+
+
+        /**
+         * Appends a shape to a target shape
+         * 
+         * @param {Object}
+         *            context
+         * @param {djs.model.Base}
+         *            context.parent the parent object
+         * @param {Point}
+         *            context.position position of the new element
+         */
+        CreateShapeHandler.prototype.execute = function(context) {
+
+            var parent = this.getParent(context);
+
+            var shape = context.shape;
+
+            this.setPosition(shape, context);
+
+            this.addElement(shape, parent, context);
+
+            return shape;
+        };
+
+
+        /**
+         * Undo append by removing the shape
+         */
+        CreateShapeHandler.prototype.revert = function(context) {
+            this._canvas.removeShape(context.shape);
+        };
+
+
+        // //// helpers /////////////////////////////////////////
+
+        CreateShapeHandler.prototype.getParent = function(context) {
+            var parent = context.parent;
+
+            if (!parent) {
+                throw new Error('parent required');
+            }
+
+            return parent;
+        };
+
+        CreateShapeHandler.prototype.getPosition = function(context) {
+            if (!context.position) {
+                throw new Error('no position given');
+            }
+
+            return context.position;
+        };
+
+        CreateShapeHandler.prototype.addElement = function(shape, parent) {
+            this._canvas.addShape(shape, parent);
+        };
+
+        CreateShapeHandler.prototype.setPosition = function(shape, context) {
+            var position = this.getPosition(context);
+
+            // update to center position
+            // specified in create context
+            assign(shape, {
+                x: position.x - shape.width / 2,
+                y: position.y - shape.height / 2
+            });
+        };
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteConnectionHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var Collections = require('../../../util/Collections');
+
+
+        /**
+         * A handler that implements reversible deletion of Connections.
+         * 
+         */
+        function DeleteConnectionHandler(canvas, modeling) {
+            this._canvas = canvas;
+            this._modeling = modeling;
+        }
+
+        DeleteConnectionHandler.$inject = ['canvas', 'modeling'];
+
+        module.exports = DeleteConnectionHandler;
+
+
+        /**
+         * - Remove attached label
+         */
+        DeleteConnectionHandler.prototype.preExecute = function(context) {
+
+            var connection = context.connection;
+
+            // Remove label
+            if (connection.label) {
+                this._modeling.removeShape(connection.label);
+            }
+        };
+
+        DeleteConnectionHandler.prototype.execute = function(context) {
+
+            var connection = context.connection,
+                parent = connection.parent;
+
+            context.parent = parent;
+            context.parentIndex = Collections.indexOf(parent.children, connection);
+
+            context.source = connection.source;
+            context.target = connection.target;
+
+            this._canvas.removeConnection(connection);
+
+            connection.source = null;
+            connection.target = null;
+            connection.label = null;
+        };
+
+        /**
+         * Command revert implementation.
+         */
+        DeleteConnectionHandler.prototype.revert = function(context) {
+
+            var connection = context.connection,
+                parent = context.parent,
+                parentIndex = context.parentIndex;
+
+            connection.source = context.source;
+            connection.target = context.target;
+
+            // restore previous location in old parent
+            Collections.add(parent.children, connection, parentIndex);
+
+            this._canvas.addConnection(connection, parent);
+        };
+
+    }, {
+        "../../../util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteElementsHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            inherits = require('inherits');
+
+
+        function DeleteElementsHandler(modeling, elementRegistry) {
+            this._modeling = modeling;
+            this._elementRegistry = elementRegistry;
+        }
+
+        inherits(DeleteElementsHandler, require('./NoopHandler'));
+
+        DeleteElementsHandler.$inject = ['modeling', 'elementRegistry'];
+
+        module.exports = DeleteElementsHandler;
+
+
+        DeleteElementsHandler.prototype.postExecute = function(context) {
+
+            var modeling = this._modeling,
+                elementRegistry = this._elementRegistry,
+                elements = context.elements;
+
+            forEach(elements, function(element) {
+
+                // element may have been removed with previous
+                // remove operations already (e.g. in case of nesting)
+                if (!elementRegistry.get(element.id)) {
+                    return;
+                }
+
+                if (element.waypoints) {
+                    modeling.removeConnection(element);
+                } else {
+                    modeling.removeShape(element);
+                }
+            });
+        };
+    }, {
+        "./NoopHandler": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\NoopHandler.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\DeleteShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var Collections = require('../../../util/Collections');
+
+
+        /**
+         * A handler that implements reversible deletion of shapes.
+         * 
+         */
+        function DeleteShapeHandler(canvas, modeling) {
+            this._canvas = canvas;
+            this._modeling = modeling;
+        }
+
+        DeleteShapeHandler.$inject = ['canvas', 'modeling'];
+
+        module.exports = DeleteShapeHandler;
+
+
+        /**
+         * - Remove connections - Remove all direct children
+         */
+        DeleteShapeHandler.prototype.preExecute = function(context) {
+
+            var shape = context.shape,
+                label = shape.label,
+                modeling = this._modeling;
+
+            // Clean up on removeShape(label)
+            if (shape.labelTarget) {
+                context.labelTarget = shape.labelTarget;
+                shape.labelTarget = null;
+            }
+
+            // Remove label
+            if (label) {
+                this._modeling.removeShape(label);
+            }
+
+            // remove connections
+            this._saveClear(shape.incoming, function(connection) {
+                // To make sure that the connection isn't removed twice
+                // For example if a container is removed
+                modeling.removeConnection(connection);
+            });
+
+            this._saveClear(shape.outgoing, function(connection) {
+                modeling.removeConnection(connection);
+            });
+
+
+            // remove children
+            this._saveClear(shape.children, function(e) {
+                modeling.removeShape(e);
+            });
+        };
+
+
+        DeleteShapeHandler.prototype._saveClear = function(collection, remove) {
+
+            var e;
+
+            while (!!(e = collection[0])) {
+                remove(e);
+            }
+        };
+
+
+        /**
+         * Remove shape and remember the parent
+         */
+        DeleteShapeHandler.prototype.execute = function(context) {
+
+            var shape = context.shape,
+                parent = shape.parent;
+
+            context.parent = parent;
+            context.parentIndex = Collections.indexOf(parent.children, shape);
+
+            shape.label = null;
+
+            this._canvas.removeShape(shape);
+        };
+
+
+        /**
+         * Command revert implementation
+         */
+        DeleteShapeHandler.prototype.revert = function(context) {
+
+            var shape = context.shape,
+                parent = context.parent,
+                parentIndex = context.parentIndex,
+                labelTarget = context.labelTarget;
+
+            // restore previous location in old parent
+            Collections.add(parent.children, shape, parentIndex);
+
+            if (labelTarget) {
+                labelTarget.label = shape;
+            }
+
+            this._canvas.addShape(shape, parent);
+        };
+
+    }, {
+        "../../../util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\LayoutConnectionHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+
+        /**
+         * A handler that implements reversible moving of shapes.
+         */
+        function LayoutConnectionHandler(layouter, canvas) {
+            this._layouter = layouter;
+            this._canvas = canvas;
+        }
+
+        LayoutConnectionHandler.$inject = ['layouter', 'canvas'];
+
+        module.exports = LayoutConnectionHandler;
+
+        LayoutConnectionHandler.prototype.execute = function(context) {
+
+            var connection = context.connection,
+                parent = connection.parent,
+                connectionSiblings = parent.children;
+
+            var oldIndex = connectionSiblings.indexOf(connection);
+
+            assign(context, {
+                oldWaypoints: connection.waypoints,
+                oldIndex: oldIndex
+            });
+
+            sendToFront(connection);
+
+            connection.waypoints = this._layouter.layoutConnection(connection, context.hints);
+
+            return connection;
+        };
+
+        LayoutConnectionHandler.prototype.revert = function(context) {
+
+            var connection = context.connection,
+                parent = connection.parent,
+                connectionSiblings = parent.children,
+                currentIndex = connectionSiblings.indexOf(connection),
+                oldIndex = context.oldIndex;
+
+            connection.waypoints = context.oldWaypoints;
+
+            if (oldIndex !== currentIndex) {
+
+                // change position of connection in shape
+                connectionSiblings.splice(currentIndex, 1);
+                connectionSiblings.splice(oldIndex, 0, connection);
+            }
+
+            return connection;
+        };
+
+        // connections should have a higher z-order as there source and targets
+        function sendToFront(connection) {
+
+            var connectionSiblings = connection.parent.children;
+
+            var connectionIdx = connectionSiblings.indexOf(connection),
+                sourceIdx = findIndex(connectionSiblings, connection.source),
+                targetIdx = findIndex(connectionSiblings, connection.target),
+
+                // ensure we do not send the connection back
+                // if it is already in front
+                insertIndex = Math.max(sourceIdx + 1, targetIdx + 1, connectionIdx);
+
+            if (connectionIdx < insertIndex) {
+                connectionSiblings.splice(insertIndex, 0, connection); // add to new
+                // position
+                connectionSiblings.splice(connectionIdx, 1); // remove from old position
+            }
+
+            function findIndex(array, obj) {
+
+                var index = array.indexOf(obj);
+                if (index < 0 && obj) {
+                    var parent = obj.parent;
+                    index = findIndex(array, parent);
+                }
+                return index;
+            }
+
+            return insertIndex;
+        }
+
+    }, {
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveConnectionHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var Collections = require('../../../util/Collections');
+
+
+        /**
+         * A handler that implements reversible moving of connections.
+         * 
+         * The handler differs from the layout connection handler in a sense that it
+         * preserves the connection layout.
+         */
+        function MoveConnectionHandler() {}
+
+        module.exports = MoveConnectionHandler;
+
+
+        MoveConnectionHandler.prototype.execute = function(context) {
+
+            var updateAnchors = (context.hints.updateAnchors !== false);
+
+            var connection = context.connection,
+                delta = context.delta;
+
+            var newParent = this.getNewParent(connection, context),
+                oldParent = connection.parent;
+
+            // save old position + parent in context
+            context.oldParent = oldParent;
+            context.oldParentIndex = Collections.indexOf(oldParent.children, connection);
+
+            // update waypoint positions
+            forEach(connection.waypoints, function(p) {
+                p.x += delta.x;
+                p.y += delta.y;
+
+                if (updateAnchors && p.original) {
+                    p.original.x += delta.x;
+                    p.original.y += delta.y;
+                }
+            });
+
+            // update parent
+            connection.parent = newParent;
+
+            return connection;
+        };
+
+        MoveConnectionHandler.prototype.revert = function(context) {
+
+            var updateAnchors = (context.hints.updateAnchors !== false);
+
+            var connection = context.connection,
+                oldParent = context.oldParent,
+                oldParentIndex = context.oldParentIndex,
+                delta = context.delta;
+
+            // restore previous location in old parent
+            Collections.add(oldParent.children, connection, oldParentIndex);
+
+            // restore parent
+            connection.parent = oldParent;
+
+            // revert to old waypoint positions
+            forEach(connection.waypoints, function(p) {
+                p.x -= delta.x;
+                p.y -= delta.y;
+
+                if (updateAnchors && p.original) {
+                    p.original.x -= delta.x;
+                    p.original.y -= delta.y;
+                }
+            });
+
+            return connection;
+        };
+
+
+        MoveConnectionHandler.prototype.getNewParent = function(connection, context) {
+            return context.newParent || connection.parent;
+        };
+
+    }, {
+        "../../../util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+        var MoveHelper = require('./helper/MoveHelper'),
+            Collections = require('../../../util/Collections');
+
+
+        /**
+         * A handler that implements reversible moving of shapes.
+         */
+        function MoveShapeHandler(modeling) {
+            this._modeling = modeling;
+
+            this._helper = new MoveHelper(modeling);
+        }
+
+        MoveShapeHandler.$inject = ['modeling'];
+
+        module.exports = MoveShapeHandler;
+
+
+        MoveShapeHandler.prototype.execute = function(context) {
+
+            var shape = context.shape,
+                delta = context.delta,
+                newParent = this.getNewParent(context),
+                oldParent = shape.parent;
+
+            // save old parent in context
+            context.oldParent = oldParent;
+            context.oldParentIndex = Collections.indexOf(oldParent.children, shape);
+
+            // update shape parent + position
+            assign(shape, {
+                parent: newParent,
+                x: shape.x + delta.x,
+                y: shape.y + delta.y
+            });
+
+            return shape;
+        };
+
+        MoveShapeHandler.prototype.postExecute = function(context) {
+
+            var shape = context.shape,
+                delta = context.delta;
+
+            var modeling = this._modeling;
+
+            if (context.hints.updateAnchors !== false) {
+                modeling.updateAnchors(shape, delta);
+            }
+
+            if (context.hints.layout !== false) {
+                forEach(shape.incoming, function(c) {
+                    modeling.layoutConnection(c, {
+                        endChanged: true
+                    });
+                });
+
+                forEach(shape.outgoing, function(c) {
+                    modeling.layoutConnection(c, {
+                        startChanged: true
+                    });
+                });
+            }
+
+            if (context.hints.recurse !== false) {
+                this.moveChildren(context);
+            }
+        };
+
+        MoveShapeHandler.prototype.revert = function(context) {
+
+            var shape = context.shape,
+                oldParent = context.oldParent,
+                oldParentIndex = context.oldParentIndex,
+                delta = context.delta;
+
+            // restore previous location in old parent
+            Collections.add(oldParent.children, shape, oldParentIndex);
+
+            // revert to old position and parent
+            assign(shape, {
+                parent: oldParent,
+                x: shape.x - delta.x,
+                y: shape.y - delta.y
+            });
+
+            return shape;
+        };
+
+        MoveShapeHandler.prototype.moveChildren = function(context) {
+
+            var delta = context.delta,
+                shape = context.shape;
+
+            this._helper.moveRecursive(shape.children, delta, null);
+        };
+
+        MoveShapeHandler.prototype.getNewParent = function(context) {
+            return context.newParent || context.shape.parent;
+        };
+    }, {
+        "../../../util/Collections": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js",
+        "./helper/MoveHelper": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\helper\\MoveHelper.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\MoveShapesHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var MoveHelper = require('./helper/MoveHelper');
+
+
+        /**
+         * A handler that implements reversible moving of shapes.
+         */
+        function MoveShapesHandler(modeling) {
+            this._helper = new MoveHelper(modeling);
+        }
+
+        MoveShapesHandler.$inject = ['modeling'];
+
+        module.exports = MoveShapesHandler;
+
+        MoveShapesHandler.prototype.preExecute = function(context) {
+            context.closure = this._helper.getClosure(context.shapes);
+        };
+
+        MoveShapesHandler.prototype.postExecute = function(context) {
+            this._helper.moveClosure(context.closure, context.delta, context.newParent);
+        };
+
+
+        MoveShapesHandler.prototype.execute = function(context) {};
+        MoveShapesHandler.prototype.revert = function(context) {};
+
+    }, {
+        "./helper/MoveHelper": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\helper\\MoveHelper.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\NoopHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        function NoopHandler() {}
+
+        module.exports = NoopHandler;
+
+        NoopHandler.prototype.execute = function() {};
+        NoopHandler.prototype.revert = function() {};
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ReconnectConnectionHandler.js": [function(require, module, exports) {
+        'use strict';
+
+
+        function ReconnectConnectionHandler(layouter) {}
+
+        ReconnectConnectionHandler.$inject = ['layouter'];
+
+        module.exports = ReconnectConnectionHandler;
+
+        ReconnectConnectionHandler.prototype.execute = function(context) {
+
+            var newSource = context.newSource,
+                newTarget = context.newTarget,
+                connection = context.connection;
+
+            if (!newSource && !newTarget) {
+                throw new Error('newSource or newTarget are required');
+            }
+
+            if (newSource && newTarget) {
+                throw new Error('must specify either newSource or newTarget');
+            }
+
+            if (newSource) {
+                context.oldSource = connection.source;
+                connection.source = newSource;
+
+                context.oldDockingPoint = connection.waypoints[0];
+                connection.waypoints[0] = context.dockingPoint;
+            }
+
+            if (newTarget) {
+                context.oldTarget = connection.target;
+                connection.target = newTarget;
+
+                context.oldDockingPoint = connection.waypoints[connection.waypoints.length - 1];
+                connection.waypoints[connection.waypoints.length - 1] = context.dockingPoint;
+            }
+
+            return connection;
+        };
+
+        ReconnectConnectionHandler.prototype.revert = function(context) {
+
+            var newSource = context.newSource,
+                newTarget = context.newTarget,
+                connection = context.connection;
+
+            if (newSource) {
+                connection.source = context.oldSource;
+                connection.waypoints[0] = context.oldDockingPoint;
+            }
+
+            if (newTarget) {
+                connection.target = context.oldTarget;
+                connection.waypoints[connection.waypoints.length - 1] = context.oldDockingPoint;
+            }
+
+            return connection;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ReplaceShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+
+        /**
+         * A handler that implements reversible replacing of shapes. Internally the old
+         * shape will be removed and the new shape will be added.
+         * 
+         * 
+         * @class
+         * @constructor
+         * 
+         * @param {canvas}
+         *            Canvas
+         */
+        function ReplaceShapeHandler(modeling, rules) {
+            this._modeling = modeling;
+            this._rules = rules;
+        }
+
+        ReplaceShapeHandler.$inject = ['modeling', 'rules'];
+
+        module.exports = ReplaceShapeHandler;
+
+
+
+        // //// api /////////////////////////////////////////
+
+
+        /**
+         * Replaces a shape with an replacement Element.
+         * 
+         * The newData object should contain type, x, y.
+         * 
+         * If possible also the incoming/outgoing connection will be restored.
+         * 
+         * @param {Object}
+         *            context
+         */
+        ReplaceShapeHandler.prototype.preExecute = function(context) {
+
+            var modeling = this._modeling,
+                rules = this._rules;
+
+            var oldShape = context.oldShape,
+                newData = context.newData,
+                newShape;
+
+
+            // (1) place a new shape at the given position
+
+            var position = {
+                x: newData.x,
+                y: newData.y
+            };
+
+            newShape = context.newShape = context.newShape || modeling.createShape(newData, position, oldShape.parent);
+
+
+            // (2) reconnect connections to the new shape (where allowed)
+
+            var incoming = oldShape.incoming.slice(),
+                outgoing = oldShape.outgoing.slice();
+
+            forEach(incoming, function(connection) {
+                var waypoints = connection.waypoints,
+                    docking = waypoints[waypoints.length - 1],
+                    allowed = rules.allowed('connection.reconnectEnd', {
+                        source: connection.source,
+                        target: newShape,
+                        connection: connection
+                    });
+
+                if (allowed) {
+                    modeling.reconnectEnd(connection, newShape, docking);
+                }
+            });
+
+            forEach(outgoing, function(connection) {
+                var waypoints = connection.waypoints,
+                    docking = waypoints[0],
+                    allowed = rules.allowed('connection.reconnectStart', {
+                        source: newShape,
+                        target: connection.target,
+                        connection: connection
+                    });
+
+                if (allowed) {
+                    modeling.reconnectStart(connection, newShape, docking);
+                }
+            });
+        };
+
+
+        ReplaceShapeHandler.prototype.postExecute = function(context) {
+            var modeling = this._modeling;
+
+            var oldShape = context.oldShape;
+
+            modeling.removeShape(oldShape);
+        };
+
+
+        ReplaceShapeHandler.prototype.execute = function(context) {};
+
+        ReplaceShapeHandler.prototype.revert = function(context) {};
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\ResizeShapeHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach');
+
+
+        /**
+         * A handler that implements reversible resizing of shapes.
+         * 
+         */
+        function ResizeShapeHandler(modeling) {
+            this._modeling = modeling;
+        }
+
+        ResizeShapeHandler.$inject = ['modeling'];
+
+        module.exports = ResizeShapeHandler;
+
+        /**
+         * { shape: {....} newBounds: { width: 20, height: 40, x: 5, y: 10 }
+         *  }
+         */
+        ResizeShapeHandler.prototype.execute = function(context) {
+
+            var shape = context.shape,
+                newBounds = context.newBounds;
+
+            if (newBounds.x === undefined || newBounds.y === undefined ||
+                newBounds.width === undefined || newBounds.height === undefined) {
+                throw new Error('newBounds must have {x, y, width, height} properties');
+            }
+
+            if (newBounds.width < 10 || newBounds.height < 10) {
+                throw new Error('width and height cannot be less than 10px');
+            }
+
+            // save old bbox in context
+            context.oldBounds = {
+                width: shape.width,
+                height: shape.height,
+                x: shape.x,
+                y: shape.y
+            };
+
+            // update shape
+            assign(shape, {
+                width: newBounds.width,
+                height: newBounds.height,
+                x: newBounds.x,
+                y: newBounds.y
+            });
+
+            return shape;
+        };
+
+        ResizeShapeHandler.prototype.postExecute = function(context) {
+
+            var shape = context.shape;
+
+            var modeling = this._modeling;
+
+            forEach(shape.incoming, function(c) {
+                modeling.layoutConnection(c, {
+                    endChanged: true
+                });
+            });
+
+            forEach(shape.outgoing, function(c) {
+                modeling.layoutConnection(c, {
+                    startChanged: true
+                });
+            });
+
+        };
+
+        ResizeShapeHandler.prototype.revert = function(context) {
+
+            var shape = context.shape,
+                oldBounds = context.oldBounds;
+
+            // restore previous bbox
+            assign(shape, {
+                width: oldBounds.width,
+                height: oldBounds.height,
+                x: oldBounds.x,
+                y: oldBounds.y
+            });
+
+            return shape;
+        };
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\SpaceToolHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var SpaceUtil = require('../../space-tool/SpaceUtil');
+
+        /**
+         * A handler that implements reversible creating and removing of space.
+         * 
+         * It executes in two phases:
+         * 
+         * (1) resize all affected resizeShapes (2) move all affected moveShapes
+         */
+        function SpaceToolHandler(modeling) {
+            this._modeling = modeling;
+        }
+
+        SpaceToolHandler.$inject = ['modeling'];
+
+        module.exports = SpaceToolHandler;
+
+
+        SpaceToolHandler.prototype.preExecute = function(context) {
+
+            // resize
+            var modeling = this._modeling,
+                resizingShapes = context.resizingShapes,
+                delta = context.delta,
+                direction = context.direction;
+
+            forEach(resizingShapes, function(shape) {
+                var newBounds = SpaceUtil.resizeBounds(shape, direction, delta);
+
+                modeling.resizeShape(shape, newBounds);
+            });
+        };
+
+        SpaceToolHandler.prototype.postExecute = function(context) {
+            // move
+            var modeling = this._modeling,
+                movingShapes = context.movingShapes,
+                delta = context.delta;
+
+            modeling.moveShapes(movingShapes, delta);
+        };
+
+        SpaceToolHandler.prototype.execute = function(context) {};
+        SpaceToolHandler.prototype.revert = function(context) {};
+
+    }, {
+        "../../space-tool/SpaceUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceUtil.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\UpdateAnchorsHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            assign = require('lodash/object/assign');
+
+
+        /**
+         * Update the anchors of
+         */
+        function UpdateAnchorsHandler() {}
+
+        module.exports = UpdateAnchorsHandler;
+
+
+        UpdateAnchorsHandler.prototype.execute = function(context) {
+
+            // update connection anchors
+            return this.updateAnchors(context.element, context.delta);
+        };
+
+        UpdateAnchorsHandler.prototype.revert = function(context) {
+
+            var delta = context.delta,
+                revertedDelta = {
+                    x: -1 * delta.x,
+                    y: -1 * delta.y
+                };
+
+            // revert update connection anchors
+            return this.updateAnchors(context.element, revertedDelta);
+        };
+
+        /**
+         * Update anchors on the element according to the delta movement.
+         * 
+         * @param {djs.model.Element}
+         *            element
+         * @param {Point}
+         *            delta
+         * 
+         * @return Array<djs.model.Connection>
+         */
+        UpdateAnchorsHandler.prototype.updateAnchors = function(element, delta) {
+
+            function add(point, delta) {
+                return {
+                    x: point.x + delta.x,
+                    y: point.y + delta.y
+                };
+            }
+
+            function updateAnchor(waypoint) {
+                var original = waypoint.original;
+
+                waypoint.original = assign(original || {}, add(original || waypoint, delta));
+            }
+
+            var changed = [];
+
+            forEach(element.incoming, function(c) {
+                var waypoints = c.waypoints;
+                updateAnchor(waypoints[waypoints.length - 1]);
+
+                changed.push(c);
+            });
+
+            forEach(element.outgoing, function(c) {
+                var waypoints = c.waypoints;
+                updateAnchor(waypoints[0]);
+
+                changed.push(c);
+            });
+
+            return changed;
+        };
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\UpdateWaypointsHandler.js": [function(require, module, exports) {
+        'use strict';
+
+        function UpdateWaypointsHandler() {}
+
+        module.exports = UpdateWaypointsHandler;
+
+        UpdateWaypointsHandler.prototype.execute = function(context) {
+
+            var connection = context.connection,
+                newWaypoints = context.newWaypoints;
+
+            context.oldWaypoints = connection.waypoints;
+
+            connection.waypoints = newWaypoints;
+
+            return connection;
+        };
+
+        UpdateWaypointsHandler.prototype.revert = function(context) {
+
+            var connection = context.connection,
+                oldWaypoints = context.oldWaypoints;
+
+            connection.waypoints = oldWaypoints;
+
+            return connection;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\cmd\\helper\\MoveHelper.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var Elements = require('../../../../util/Elements');
+
+
+        /**
+         * A helper that is able to carry out serialized move operations on multiple
+         * elements.
+         * 
+         * @param {Modeling}
+         *            modeling
+         */
+        function MoveHelper(modeling) {
+            this._modeling = modeling;
+        }
+
+        module.exports = MoveHelper;
+
+        /**
+         * Move the specified elements and all children by the given delta.
+         * 
+         * This moves all enclosed connections, too and layouts all affected external
+         * connections.
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements
+         * @param {Point}
+         *            delta
+         * @param {djs.model.Base}
+         *            newParent applied to the first level of shapes
+         * 
+         * @return {Array<djs.model.Base>} list of touched elements
+         */
+        MoveHelper.prototype.moveRecursive = function(elements, delta, newParent) {
+            return this.moveClosure(this.getClosure(elements), delta, newParent);
+        };
+
+        /**
+         * Move the given closure of elmements
+         */
+        MoveHelper.prototype.moveClosure = function(closure, delta, newParent) {
+
+            var modeling = this._modeling;
+
+            var allShapes = closure.allShapes,
+                allConnections = closure.allConnections,
+                enclosedConnections = closure.enclosedConnections,
+                topLevel = closure.topLevel;
+
+            // move all shapes
+            forEach(allShapes, function(s) {
+
+                modeling.moveShape(s, delta, topLevel[s.id] && newParent, {
+                    recurse: false,
+                    layout: false
+                });
+            });
+
+            // move all child connections / layout external connections
+            forEach(allConnections, function(c) {
+
+                var startMoved = !!allShapes[c.source.id],
+                    endMoved = !!allShapes[c.target.id];
+
+                if (enclosedConnections[c.id] &&
+                    startMoved && endMoved) {
+                    modeling.moveConnection(c, delta, topLevel[c.id] && newParent, {
+                        updateAnchors: false
+                    });
+                } else {
+                    modeling.layoutConnection(c, {
+                        startChanged: startMoved,
+                        endChanged: endMoved
+                    });
+                }
+            });
+        };
+
+        /**
+         * Returns the closure for the selected elements
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements
+         * @return {Object} closure
+         */
+        MoveHelper.prototype.getClosure = function(elements) {
+            return Elements.getClosure(elements);
+        };
+
+    }, {
+        "../../../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../../command'),
+                require('../change-support'),
+                require('../rules')
+            ],
+            __init__: ['modeling'],
+            modeling: ['type', require('./Modeling')],
+            layouter: ['type', require('../../layout/BaseLayouter')]
+        };
+
+    }, {
+        "../../command": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\index.js",
+        "../../layout/BaseLayouter": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\BaseLayouter.js",
+        "../change-support": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\change-support\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "./Modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\Modeling.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\Move.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            filter = require('lodash/collection/filter'),
+            groupBy = require('lodash/collection/groupBy');
+
+
+        var LOW_PRIORITY = 500,
+            HIGH_PRIORITY = 1500;
+
+        var getOriginalEvent = require('../../util/Event').getOriginal;
+
+        var round = Math.round;
+
+
+        /**
+         * Return a filtered list of elements that do not contain those nested into
+         * others.
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements
+         * 
+         * @return {Array<djs.model.Base>} filtered
+         */
+        function removeNested(elements) {
+
+            var ids = groupBy(elements, 'id');
+
+            return filter(elements, function(element) {
+                while (!!(element = element.parent)) {
+                    if (ids[element.id]) {
+                        return false;
+                    }
+                }
+
+                return true;
+            });
+        }
+
+
+
+        /**
+         * A plugin that makes shapes draggable / droppable.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Dragging}
+         *            dragging
+         * @param {Modeling}
+         *            modeling
+         * @param {Selection}
+         *            selection
+         * @param {Rules}
+         *            rules
+         */
+        function MoveEvents(eventBus, dragging, modeling, selection, rules) {
+
+            // rules
+
+            function canMove(shapes, delta, target) {
+
+                return rules.allowed('shapes.move', {
+                    shapes: shapes,
+                    delta: delta,
+                    newParent: target
+                });
+            }
+
+
+            // move events
+
+            // assign a high priority to this handler to setup the environment
+            // others may hook up later, e.g. at default priority and modify
+            // the move environment
+            //
+            eventBus.on('shape.move.start', HIGH_PRIORITY, function(event) {
+               
+                var context = event.context,
+                    shape = event.shape,
+                    shapes = selection.get().slice();
+
+                // move only single shape shape if the dragged element
+                // is not part of the current selection
+                if (shapes.indexOf(shape) === -1) {
+                    shapes = [shape];
+                }
+
+                // ensure we remove nested elements in the collection
+                shapes = removeNested(shapes);
+
+                // attach shapes to drag context
+                assign(context, {
+                    shapes: shapes,
+                    shape: shape
+                });
+
+                // check if we can move the elements
+                if (!canMove(shapes)) {
+                    // suppress move operation
+                    event.stopPropagation();
+
+                    return false;
+                }
+            });
+
+            // assign a low priority to this handler
+            // to let others modify the move event before we update
+            // the context
+            //
+            eventBus.on('shape.move.move', LOW_PRIORITY, function(event) {
+
+                var context = event.context,
+                    shapes = context.shapes,
+                    hover = event.hover,
+                    delta = {
+                        x: event.dx,
+                        y: event.dy
+                    },
+                    canExecute;
+
+                // check if we can move the elements
+                canExecute = canMove(shapes, delta, hover);
+
+                context.delta = delta;
+                context.canExecute = canExecute;
+
+                // simply ignore move over
+                if (canExecute === null) {
+                    context.target = null;
+
+                    return;
+                }
+
+                context.target = hover;
+            });
+
+            eventBus.on('shape.move.end', function(event) {
+
+                var context = event.context;
+
+                var delta = context.delta,
+                    canExecute = context.canExecute;
+
+                if (!canExecute) {
+                    return false;
+                }
+
+                // ensure we have actual pixel values deltas
+                // (important when zoom level was > 1 during move)
+                delta.x = round(delta.x);
+                delta.y = round(delta.y);
+
+                modeling.moveShapes(context.shapes, delta, context.target);
+            });
+
+
+            // move activation
+
+            eventBus.on('element.mousedown', function(event) {
+
+                var originalEvent = getOriginalEvent(event);
+
+                if (!originalEvent) {
+                    throw new Error('must supply DOM mousedown event');
+                }
+
+                start(originalEvent, event.element);
+            });
+
+
+            function start(event, element, activate) {
+
+                // do not move connections or the root element
+                if (element.waypoints || !element.parent) {
+                    return;
+                }
+
+                dragging.activate(event, 'shape.move', {
+                    cursor: 'grabbing',
+                    autoActivate: activate,
+                    data: {
+                        shape: element,
+                        context: {}
+                    }
+                });
+            }
+
+            // API
+
+            this.start = start;
+        }
+
+        MoveEvents.$inject = ['eventBus', 'dragging', 'modeling', 'selection', 'rules'];
+
+        module.exports = MoveEvents;
+
+    }, {
+        "../../util/Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/groupBy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\groupBy.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\MoveVisuals.js": [function(require, module, exports) {
+        'use strict';
+
+        var flatten = require('lodash/array/flatten'),
+            forEach = require('lodash/collection/forEach'),
+            filter = require('lodash/collection/filter'),
+            find = require('lodash/collection/find'),
+            map = require('lodash/collection/map');
+
+        var Elements = require('../../util/Elements');
+
+        var LOW_PRIORITY = 500;
+
+        var MARKER_DRAGGING = 'djs-dragging',
+            MARKER_OK = 'drop-ok',
+            MARKER_NOT_OK = 'drop-not-ok';
+
+
+        /**
+         * A plugin that makes shapes draggable / droppable.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {ElementRegistry}
+         *            elementRegistry
+         * @param {Canvas}
+         *            canvas
+         * @param {Styles}
+         *            styles
+         */
+        function MoveVisuals(eventBus, elementRegistry, canvas, styles) {
+
+            function getGfx(e) {
+                return elementRegistry.getGraphics(e);
+            }
+
+            function getVisualDragShapes(shapes) {
+
+                var elements = Elements.selfAndDirectChildren(shapes, true);
+                var filteredElements = removeEdges(elements);
+
+                return filteredElements;
+            }
+
+            function getAllDraggedElements(shapes) {
+                var allShapes = Elements.selfAndAllChildren(shapes, true);
+
+                var allConnections = map(allShapes, function(shape) {
+                    return (shape.incoming || []).concat(shape.outgoing || []);
+                });
+
+                return flatten(allShapes.concat(allConnections), true);
+            }
+
+            function addDragger(shape, dragGroup) {
+                var gfx = getGfx(shape);
+                var dragger = gfx.clone();
+                var bbox = gfx.getBBox();
+
+                dragger.attr(styles.cls('djs-dragger', [], {
+                    x: bbox.x,
+                    y: bbox.y
+                }));
+
+                dragGroup.add(dragger);
+            }
+
+            // assign a low priority to this handler
+            // to let others modify the move context before
+            // we draw things
+            //
+            eventBus.on('shape.move.start', LOW_PRIORITY, function(event) {
+
+                var context = event.context,
+                    dragShapes = context.shapes;
+
+                var dragGroup = canvas.getDefaultLayer().group().attr(styles.cls('djs-drag-group', ['no-events']));
+
+                var visuallyDraggedShapes = getVisualDragShapes(dragShapes);
+
+                visuallyDraggedShapes.forEach(function(shape) {
+                    addDragger(shape, dragGroup);
+                });
+
+
+                // cache all dragged elements / gfx
+                // so that we can quickly undo their state changes later
+                var allDraggedElements = context.allDraggedElements = getAllDraggedElements(dragShapes);
+
+                // add dragging marker
+                forEach(allDraggedElements, function(e) {
+                    canvas.addMarker(e, MARKER_DRAGGING);
+                });
+
+                context.dragGroup = dragGroup;
+            });
+
+            // assign a low priority to this handler
+            // to let others modify the move context before
+            // we draw things
+            //
+            eventBus.on('shape.move.move', LOW_PRIORITY, function(event) {
+
+                var context = event.context,
+                    dragGroup = context.dragGroup,
+                    target = context.target;
+
+                if (target) {
+                    canvas.addMarker(target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+                }
+
+                dragGroup.translate(event.dx, event.dy);
+            });
+
+            eventBus.on(['shape.move.out', 'shape.move.cleanup'], function(event) {
+                var context = event.context;
+
+                if (context.target) {
+                    canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
+                }
+            });
+
+            eventBus.on('shape.move.cleanup', function(event) {
+
+                var context = event.context,
+                    allDraggedElements = context.allDraggedElements,
+                    dragGroup = context.dragGroup;
+
+
+                // remove dragging marker
+                forEach(allDraggedElements, function(e) {
+                    canvas.removeMarker(e, MARKER_DRAGGING);
+                });
+
+                if (dragGroup) {
+                    dragGroup.remove();
+                }
+            });
+        }
+
+        // returns elements minus all connections
+        // where source or target is not elements
+        function removeEdges(elements) {
+
+            var filteredElements = filter(elements, function(element) {
+
+                if (!element.waypoints) { // shapes
+                    return true;
+                } else { // connections
+                    var srcFound = find(elements, element.source);
+                    var targetFound = find(elements, element.target);
+
+                    return srcFound && targetFound;
+                }
+            });
+
+            return filteredElements;
+        }
+
+        MoveVisuals.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles'];
+
+        module.exports = MoveVisuals;
+
+    }, {
+        "../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "lodash/array/flatten": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\flatten.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/map": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\map.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../interaction-events'),
+                require('../selection'),
+                require('../outline'),
+                require('../rules'),
+                require('../dragging')
+            ],
+            __init__: ['move', 'moveVisuals'],
+            move: ['type', require('./Move')],
+            moveVisuals: ['type', require('./MoveVisuals')]
+        };
+
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../interaction-events": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js",
+        "../outline": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\outline\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "../selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js",
+        "./Move": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\Move.js",
+        "./MoveVisuals": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\move\\MoveVisuals.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\outline\\Outline.js": [function(require, module, exports) {
+        'use strict';
+
+        var Snap = require('../../../vendor/snapsvg');
+        var getBBox = require('../../util/Elements').getBBox;
+
+
+        /**
+         * @class
+         * 
+         * A plugin that adds an outline to shapes and connections that may be activated
+         * and styled via CSS classes.
+         * 
+         * @param {EventBus}
+         *            events the event bus
+         */
+        function Outline(eventBus, styles, elementRegistry) {
+
+            var OUTLINE_OFFSET = 6;
+
+            var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']);
+
+            function createOutline(gfx, bounds) {
+                return Snap.create('rect', OUTLINE_STYLE).prependTo(gfx);
+            }
+
+            function updateShapeOutline(outline, bounds) {
+
+                outline.attr({
+                    x: -OUTLINE_OFFSET,
+                    y: -OUTLINE_OFFSET,
+                    width: bounds.width + OUTLINE_OFFSET * 2,
+                    height: bounds.height + OUTLINE_OFFSET * 2
+                });
+            }
+
+            function updateConnectionOutline(outline, connection) {
+
+                var bbox = getBBox(connection);
+
+                outline.attr({
+                    x: bbox.x - OUTLINE_OFFSET,
+                    y: bbox.y - OUTLINE_OFFSET,
+                    width: bbox.width + OUTLINE_OFFSET * 2,
+                    height: bbox.height + OUTLINE_OFFSET * 2
+                });
+            }
+
+            eventBus.on(['shape.added', 'shape.changed'], function(event) {
+                var element = event.element,
+                    gfx = event.gfx;
+
+                var outline = gfx.select('.djs-outline');
+
+                if (!outline) {
+                    outline = createOutline(gfx, element);
+                }
+
+                updateShapeOutline(outline, element);
+            });
+
+            eventBus.on(['connection.added', 'connection.changed'], function(event) {
+                var element = event.element,
+                    gfx = event.gfx;
+
+                var outline = gfx.select('.djs-outline');
+
+                if (!outline) {
+                    outline = createOutline(gfx, element);
+                }
+
+                updateConnectionOutline(outline, element);
+            });
+
+
+        }
+
+
+        Outline.$inject = ['eventBus', 'styles', 'elementRegistry'];
+
+        module.exports = Outline;
+
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\outline\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports = {
+            __init__: ['outline'],
+            outline: ['type', require('./Outline')]
+        };
+    }, {
+        "./Outline": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\outline\\Outline.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\overlays\\Overlays.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            isString = require('lodash/lang/isString'),
+            isObject = require('lodash/lang/isObject'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach'),
+            filter = require('lodash/collection/filter'),
+            debounce = require('lodash/function/debounce');
+
+        var domify = require('min-dom/lib/domify'),
+            domClasses = require('min-dom/lib/classes'),
+            domRemove = require('min-dom/lib/remove');
+
+        var getBBox = require('../../util/Elements').getBBox;
+
+        // document wide unique overlay ids
+        var ids = new(require('../../util/IdGenerator'))('ov');
+
+
+        function createRoot(parent) {
+            var root = domify('<div class="djs-overlay-container" style="position: absolute; width: 0; height: 0;" />');
+            parent.insertBefore(root, parent.firstChild);
+
+            return root;
+        }
+
+
+        function setPosition(el, x, y) {
+            assign(el.style, {
+                left: x + 'px',
+                top: y + 'px'
+            });
+        }
+
+        function setVisible(el, visible) {
+            el.style.display = visible === false ? 'none' : '';
+        }
+
+        /**
+         * A service that allows users to attach overlays to diagram elements.
+         * 
+         * The overlay service will take care of overlay positioning during updates.
+         * 
+         * @example
+         *  // add a pink badge on the top left of the shape overlays.add(someShape, {
+         * position: { top: -5, left: -5 }, html: '<div style="width: 10px; background:
+         * fuchsia; color: white;">0</div>' });
+         *  // or add via shape id
+         * 
+         * overlays.add('some-element-id', { position: { top: -5, left: -5 } html: '<div
+         * style="width: 10px; background: fuchsia; color: white;">0</div>' });
+         *  // or add with optional type
+         * 
+         * overlays.add(someShape, 'badge', { position: { top: -5, left: -5 } html: '<div
+         * style="width: 10px; background: fuchsia; color: white;">0</div>' });
+         * 
+         *  // remove an overlay
+         * 
+         * var id = overlays.add(...); overlays.remove(id);
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Canvas}
+         *            canvas
+         * @param {ElementRegistry}
+         *            elementRegistry
+         */
+        function Overlays(config, eventBus, canvas, elementRegistry) {
+
+            this._eventBus = eventBus;
+            this._canvas = canvas;
+            this._elementRegistry = elementRegistry;
+
+            this._ids = ids;
+
+            this._overlayDefaults = {
+                show: {
+                    minZoom: 0.7,
+                    maxZoom: 5.0
+                }
+            };
+
+            /**
+             * Mapping overlayId -> overlay
+             */
+            this._overlays = {};
+
+            /**
+             * Mapping elementId -> overlay container
+             */
+            this._overlayContainers = {};
+
+            // root html element for all overlays
+            this._overlayRoot = createRoot(canvas.getContainer());
+
+            this._init(config);
+        }
+
+
+        Overlays.$inject = ['config.overlays', 'eventBus', 'canvas', 'elementRegistry'];
+
+        module.exports = Overlays;
+
+
+        /**
+         * Returns the overlay with the specified id or a list of overlays for an
+         * element with a given type.
+         * 
+         * @example
+         *  // return the single overlay with the given id overlays.get('some-id');
+         *  // return all overlays for the shape overlays.get({ element: someShape });
+         *  // return all overlays on shape with type 'badge' overlays.get({ element:
+         * someShape, type: 'badge' });
+         *  // shape can also be specified as id overlays.get({ element: 'element-id',
+         * type: 'badge' });
+         * 
+         * 
+         * @param {Object}
+         *            search
+         * @param {String}
+         *            [search.id]
+         * @param {String|djs.model.Base}
+         *            [search.element]
+         * @param {String}
+         *            [search.type]
+         * 
+         * @return {Object|Array<Object>} the overlay(s)
+         */
+        Overlays.prototype.get = function(search) {
+
+            if (isString(search)) {
+                search = {
+                    id: search
+                };
+            }
+
+            if (search.element) {
+                var container = this._getOverlayContainer(search.element, true);
+
+                // return a list of overlays when searching by element (+type)
+                if (container) {
+                    return search.type ? filter(container.overlays, {
+                        type: search.type
+                    }) : container.overlays.slice();
+                } else {
+                    return [];
+                }
+            } else
+            if (search.type) {
+                return filter(this._overlays, {
+                    type: search.type
+                });
+            } else {
+                // return single element when searching by id
+                return search.id ? this._overlays[search.id] : null;
+            }
+        };
+
+        /**
+         * Adds a HTML overlay to an element.
+         * 
+         * @param {String|djs.model.Base}
+         *            element attach overlay to this shape
+         * @param {String}
+         *            [type] optional type to assign to the overlay
+         * @param {Object}
+         *            overlay the overlay configuration
+         * 
+         * @param {String|DOMElement}
+         *            overlay.html html element to use as an overlay
+         * @param {Object}
+         *            [overlay.show] show configuration
+         * @param {Number}
+         *            [overlay.show.minZoom] minimal zoom level to show the overlay
+         * @param {Number}
+         *            [overlay.show.maxZoom] maximum zoom level to show the overlay
+         * @param {Object}
+         *            overlay.position where to attach the overlay
+         * @param {Number}
+         *            [overlay.position.left] relative to element bbox left attachment
+         * @param {Number}
+         *            [overlay.position.top] relative to element bbox top attachment
+         * @param {Number}
+         *            [overlay.position.bottom] relative to element bbox bottom
+         *            attachment
+         * @param {Number}
+         *            [overlay.position.right] relative to element bbox right attachment
+         * 
+         * @return {String} id that may be used to reference the overlay for update or
+         *         removal
+         */
+        Overlays.prototype.add = function(element, type, overlay) {
+
+            if (isObject(type)) {
+                overlay = type;
+                type = null;
+            }
+
+            if (!element.id) {
+                element = this._elementRegistry.get(element);
+            }
+
+            if (!overlay.position) {
+                throw new Error('must specifiy overlay position');
+            }
+
+            if (!overlay.html) {
+                throw new Error('must specifiy overlay html');
+            }
+
+            if (!element) {
+                throw new Error('invalid element specified');
+            }
+
+            var id = this._ids.next();
+
+            overlay = assign({}, this._overlayDefaults, overlay, {
+                id: id,
+                type: type,
+                element: element,
+                html: overlay.html
+            });
+
+            this._addOverlay(overlay);
+
+            return id;
+        };
+
+
+        /**
+         * Remove an overlay with the given id or all overlays matching the given
+         * filter.
+         * 
+         * @see Overlays#get for filter options.
+         * 
+         * @param {String}
+         *            [id]
+         * @param {Object}
+         *            [filter]
+         */
+        Overlays.prototype.remove = function(filter) {
+
+            var overlays = this.get(filter) || [];
+
+            if (!isArray(overlays)) {
+                overlays = [overlays];
+            }
+
+            var self = this;
+
+            forEach(overlays, function(overlay) {
+
+                var container = self._getOverlayContainer(overlay.element, true);
+
+                if (overlay) {
+                    domRemove(overlay.html);
+                    domRemove(overlay.htmlContainer);
+
+                    delete overlay.htmlContainer;
+                    delete overlay.element;
+
+                    delete self._overlays[overlay.id];
+                }
+
+                if (container) {
+                    var idx = container.overlays.indexOf(overlay);
+                    if (idx !== -1) {
+                        container.overlays.splice(idx, 1);
+                    }
+                }
+            });
+
+        };
+
+
+        Overlays.prototype.show = function() {
+            setVisible(this._overlayRoot);
+        };
+
+
+        Overlays.prototype.hide = function() {
+            setVisible(this._overlayRoot, false);
+        };
+
+
+        Overlays.prototype._updateOverlayContainer = function(container) {
+            var element = container.element,
+                html = container.html;
+
+            // update container left,top according to the elements x,y coordinates
+            // this ensures we can attach child elements relative to this container
+
+            var x = element.x,
+                y = element.y;
+
+            if (element.waypoints) {
+                var bbox = getBBox(element);
+                x = bbox.x;
+                y = bbox.y;
+            }
+
+            setPosition(html, x, y);
+        };
+
+
+        Overlays.prototype._updateOverlay = function(overlay) {
+
+            var position = overlay.position,
+                htmlContainer = overlay.htmlContainer,
+                element = overlay.element;
+
+            // update overlay html relative to shape because
+            // it is already positioned on the element
+
+            // update relative
+            var left = position.left,
+                top = position.top;
+
+            if (position.right !== undefined) {
+
+                var width;
+
+                if (element.waypoints) {
+                    width = getBBox(element).width;
+                } else {
+                    width = element.width;
+                }
+
+                left = position.right * -1 + width;
+            }
+
+            if (position.bottom !== undefined) {
+
+                var height;
+
+                if (element.waypoints) {
+                    height = getBBox(element).height;
+                } else {
+                    height = element.height;
+                }
+
+                top = position.bottom * -1 + height;
+            }
+
+            setPosition(htmlContainer, left || 0, top || 0);
+        };
+
+
+        Overlays.prototype._createOverlayContainer = function(element) {
+            var html = domify('<div class="djs-overlays djs-overlays-' + element.id + '" style="position: absolute" />');
+
+            this._overlayRoot.appendChild(html);
+
+            var container = {
+                html: html,
+                element: element,
+                overlays: []
+            };
+
+            this._updateOverlayContainer(container);
+
+            return container;
+        };
+
+
+        Overlays.prototype._updateRoot = function(viewbox) {
+            var a = viewbox.scale || 1;
+            var d = viewbox.scale || 1;
+
+            var matrix = 'matrix(' + a + ',0,0,' + d + ',' + (-1 * viewbox.x * a) + ',' + (-1 * viewbox.y * d) + ')';
+
+            this._overlayRoot.style.transform = matrix;
+            this._overlayRoot.style['-ms-transform'] = matrix;
+        };
+
+
+        Overlays.prototype._getOverlayContainer = function(element, raw) {
+            var id = (element && element.id) || element;
+
+            var container = this._overlayContainers[id];
+            if (!container && !raw) {
+                container = this._overlayContainers[id] = this._createOverlayContainer(element);
+            }
+
+            return container;
+        };
+
+
+        Overlays.prototype._addOverlay = function(overlay) {
+
+            var id = overlay.id,
+                element = overlay.element,
+                html = overlay.html,
+                htmlContainer,
+                overlayContainer;
+
+            // unwrap jquery (for those who need it)
+            if (html.get) {
+                html = html.get(0);
+            }
+
+            // create proper html elements from
+            // overlay HTML strings
+            if (isString(html)) {
+                html = domify(html);
+            }
+
+            overlayContainer = this._getOverlayContainer(element);
+
+            htmlContainer = domify('<div class="djs-overlay" data-overlay-id="' + id + '" style="position: absolute">');
+
+            htmlContainer.appendChild(html);
+
+            if (overlay.type) {
+                domClasses(htmlContainer).add('djs-overlay-' + overlay.type);
+            }
+
+            overlay.htmlContainer = htmlContainer;
+
+            overlayContainer.overlays.push(overlay);
+            overlayContainer.html.appendChild(htmlContainer);
+
+            this._overlays[id] = overlay;
+
+            this._updateOverlay(overlay);
+        };
+
+        Overlays.prototype._updateOverlayVisibilty = function(viewbox) {
+
+            forEach(this._overlays, function(overlay) {
+                var show = overlay.show,
+                    htmlContainer = overlay.htmlContainer,
+                    visible = true;
+
+                if (show) {
+                    if (show.minZoom > viewbox.scale ||
+                        show.maxZoom < viewbox.scale) {
+                        visible = false;
+                    }
+
+                    setVisible(htmlContainer, visible);
+                }
+            });
+        };
+
+        Overlays.prototype._init = function(config) {
+
+            var eventBus = this._eventBus;
+
+            var self = this;
+
+
+            // scroll/zoom integration
+
+            var updateViewbox = function(viewbox) {
+                self._updateRoot(viewbox);
+                self._updateOverlayVisibilty(viewbox);
+
+                self.show();
+            };
+
+            if (!config || config.deferUpdate !== false) {
+                updateViewbox = debounce(updateViewbox, 300);
+            }
+
+            eventBus.on('canvas.viewbox.changed', function(event) {
+                self.hide();
+                updateViewbox(event.viewbox);
+            });
+
+
+            // remove integration
+
+            eventBus.on(['shape.remove', 'connection.remove'], function(e) {
+                var overlays = self.get({
+                    element: e.element
+                });
+
+                forEach(overlays, function(o) {
+                    self.remove(o.id);
+                });
+            });
+
+
+            // move integration
+
+            eventBus.on([
+                'element.changed'
+            ], function(e) {
+                var element = e.element;
+
+                var container = self._getOverlayContainer(element, true);
+
+                if (container) {
+                    forEach(container.overlays, function(overlay) {
+                        self._updateOverlay(overlay);
+                    });
+
+                    self._updateOverlayContainer(container);
+                }
+            });
+
+
+            // marker integration, simply add them on the overlays as classes, too.
+
+            eventBus.on('element.marker.update', function(e) {
+                var container = self._getOverlayContainer(e.element, true);
+                if (container) {
+                    domClasses(container.html)[e.add ? 'add' : 'remove'](e.marker);
+                }
+            });
+        };
+
+    }, {
+        "../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "../../util/IdGenerator": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\IdGenerator.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/function/debounce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\debounce.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/remove": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\remove.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\overlays\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['overlays'],
+            overlays: ['type', require('./Overlays')]
+        };
+    }, {
+        "./Overlays": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\overlays\\Overlays.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\palette\\Palette.js": [function(require, module, exports) {
+        'use strict';
+
+        var isFunction = require('lodash/lang/isFunction'),
+            forEach = require('lodash/collection/forEach');
+
+        var domify = require('min-dom/lib/domify'),
+            domQuery = require('min-dom/lib/query'),
+            domAttr = require('min-dom/lib/attr'),
+            domClear = require('min-dom/lib/clear'),
+            domClasses = require('min-dom/lib/classes'),
+            domMatches = require('min-dom/lib/matches'),
+            domDelegate = require('min-dom/lib/delegate'),
+            domEvent = require('min-dom/lib/event');
+
+
+        var toggleSelector = '.djs-palette-toggle',
+            entrySelector = '.entry',
+            elementSelector = toggleSelector + ', ' + entrySelector;
+
+
+        /**
+         * A palette containing modeling elements.
+         */
+        function Palette(eventBus, canvas) {
+
+            this._eventBus = eventBus;
+            this._canvas = canvas;
+
+            this._providers = [];
+        }
+
+        Palette.$inject = ['eventBus', 'canvas'];
+
+        module.exports = Palette;
+
+
+        /**
+         * Register a provider with the palette
+         * 
+         * @param {PaletteProvider}
+         *            provider
+         */
+        Palette.prototype.registerProvider = function(provider) {
+            this._providers.push(provider);
+
+            if (!this._container) {
+                this._init();
+            }
+
+            this._update();
+        };
+
+
+        /**
+         * Returns the palette entries for a given element
+         * 
+         * @return {Array<PaletteEntryDescriptor>} list of entries
+         */
+        Palette.prototype.getEntries = function() {
+
+            var entries = {};
+
+            // loop through all providers and their entries.
+            // group entries by id so that overriding an entry is possible
+            forEach(this._providers, function(provider) {
+                var e = provider.getPaletteEntries();
+
+                forEach(e, function(entry, id) {
+                    entries[id] = entry;
+                });
+            });
+
+            return entries;
+        };
+
+
+        /**
+         * Initialize
+         */
+        Palette.prototype._init = function() {
+            var parent = this._canvas.getContainer(),
+                container = this._container = domify(Palette.HTML_MARKUP),
+                self = this;
+
+            parent.appendChild(container);
+
+            domDelegate.bind(container, elementSelector, 'click', function(event) {
+
+                var target = event.delegateTarget;
+
+                if (domMatches(target, toggleSelector)) {
+                    return self.toggle();
+                }
+
+                self.trigger('click', event);
+            });
+
+            // prevent drag propagation
+            domEvent.bind(container, 'mousedown', function(event) {
+                event.stopPropagation();
+            });
+
+            // prevent drag propagation
+            domDelegate.bind(container, entrySelector, 'dragstart', function(event) {
+                self.trigger('dragstart', event);
+            });
+
+            this._eventBus.fire('palette.create', {
+                html: container
+            });
+        };
+
+
+        Palette.prototype._update = function() {
+
+            var entriesContainer = domQuery('.djs-palette-entries', this._container),
+                entries = this._entries = this.getEntries();
+
+            domClear(entriesContainer);
+
+            forEach(entries, function(entry, id) {
+
+                var grouping = entry.group || 'default';
+
+                var container = domQuery('[data-group=' + grouping + ']', entriesContainer);
+                if (!container) {
+                    container = domify('<div class="group" data-group="' + grouping + '"></div>');
+                    entriesContainer.appendChild(container);
+                }
+
+                var html = entry.html || (
+                    entry.separator ?
+                    '<hr class="separator" />' :
+                    '<div class="entry" draggable="true"></div>');
+
+
+                var control = domify(html);
+                // alert("Control ::" + control + " HTML :: " + html);
+
+                container.appendChild(control);
+
+                if (!entry.separator) {
+                    domAttr(control, 'data-action', id);
+
+                    if (entry.title) {
+                        domAttr(control, 'title', entry.title);
+                    }
+
+
+
+                    if (entry.className) {
+                        domClasses(control).add(entry.className);
+                    }
+
+                    if (entry.imageUrl) {
+                        control.appendChild(domify('<img src="' + entry.imageUrl + '">'));
+                    }
+                }
+
+                // alert("Entry Title :: " + entry.title + " Entry HTML :: " + html);
+            });
+
+            // open after update
+            this.open(true);
+        };
+
+
+        /**
+         * Trigger an action available on the palette
+         * 
+         * @param {String}
+         *            action
+         * @param {Event}
+         *            event
+         */
+        Palette.prototype.trigger = function(action, event, autoActivate) {
+
+            var entries = this._entries,
+                entry,
+                handler,
+                originalEvent,
+                button = event.delegateTarget || event.target;
+
+            if (!button) {
+                return event.preventDefault();
+            }
+
+
+            entry = entries[domAttr(button, 'data-action')];
+            handler = entry.action;
+
+            originalEvent = event.originalEvent || event;
+
+            // simple action (via callback function)
+            if (isFunction(handler)) {
+                if (action === 'click') {
+                    return handler(originalEvent, autoActivate);
+                }
+            } else {
+                if (handler[action]) {
+                    return handler[action](originalEvent, autoActivate);
+                }
+            }
+
+            // silence other actions
+            event.preventDefault();
+        };
+
+
+        /**
+         * Close the palette
+         */
+        Palette.prototype.close = function() {
+            domClasses(this._container).remove('open');
+        };
+
+
+        /**
+         * Open the palette
+         */
+        Palette.prototype.open = function() {
+            domClasses(this._container).add('open');
+        };
+
+
+        Palette.prototype.toggle = function(open) {
+            if (this.isOpen()) {
+                this.close();
+            } else {
+                this.open();
+            }
+        };
+
+
+        /**
+         * Return true if the palette is opened.
+         * 
+         * @example
+         * 
+         * palette.open();
+         * 
+         * if (palette.isOpen()) { // yes, we are open }
+         * 
+         * @return {boolean} true if palette is opened
+         */
+        Palette.prototype.isOpen = function() {
+            return this._container && domClasses(this._container).has('open');
+        };
+
+
+        /* markup definition */
+
+        Palette.HTML_MARKUP =
+            '<div class="djs-palette">' +
+            '<div class="djs-palette-entries"></div>' +
+            '<div class="djs-palette-toggle"></div>' +
+            '</div>';
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js",
+        "min-dom/lib/attr": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\attr.js",
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js",
+        "min-dom/lib/clear": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\clear.js",
+        "min-dom/lib/delegate": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\delegate.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js",
+        "min-dom/lib/matches": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\matches.js",
+        "min-dom/lib/query": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\query.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\palette\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['palette'],
+            palette: ['type', require('./Palette')]
+        };
+
+    }, {
+        "./Palette": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\palette\\Palette.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\popup-menu\\PopupMenu.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            assign = require('lodash/object/assign'),
+            domEvent = require('min-dom/lib/event'),
+            domify = require('min-dom/lib/domify'),
+            domClasses = require('min-dom/lib/classes'),
+            domAttr = require('min-dom/lib/attr'),
+            domRemove = require('min-dom/lib/remove');
+
+
+        function PopupMenu(eventBus, canvas) {
+
+            this._eventBus = eventBus;
+            this._canvas = canvas;
+            this._instances = {};
+        }
+
+        PopupMenu.$inject = ['eventBus', 'canvas'];
+
+        module.exports = PopupMenu;
+
+        PopupMenu.prototype.open = function(name, position, entries, options) {
+
+            var outer = this,
+                canvas = this._canvas,
+                instances = outer._instances;
+
+            // return existing instance
+            if (instances[name]) {
+                return instances[name];
+            }
+
+            var parent = canvas.getContainer();
+
+            // ------------------------
+            function PopupMenuInstance() {
+
+                var self = this;
+
+                self._actions = {};
+                self.name = name || 'popup-menu';
+
+                var _options = {
+                    entryClassName: 'entry'
+                };
+                assign(_options, options);
+
+                // Container setup
+                var container = this._container = domify('<div class="djs-popup">');
+
+                assign(container.style, {
+                    position: 'absolute',
+                    left: position.x + 'px',
+                    top: position.y + 'px'
+                });
+                domClasses(container).add(name);
+
+                // Add entries
+                forEach(entries, function(entry) {
+
+                    var entryContainer = domify('<div>');
+                    domClasses(entryContainer).add(entry.className || _options.entryClassName);
+                    domClasses(entryContainer).add('djs-popup-entry');
+
+                    if (entry.style) {
+                        domAttr(entryContainer, 'style', entry.style);
+                    }
+
+                    if (entry.action) {
+                        domAttr(entryContainer, 'data-action', entry.action.name);
+                        self._actions[entry.action.name] = entry.action.handler;
+                    }
+
+                    var title = domify('<span>');
+                    title.textContent = entry.label;
+                    entryContainer.appendChild(title);
+
+                    container.appendChild(entryContainer);
+                });
+
+                // Event handler
+                domEvent.bind(container, 'click', function(event) {
+                    self.trigger(event);
+                });
+
+
+
+                // apply canvas zoom level
+                var zoom = canvas.zoom();
+
+                container.style.transformOrigin = 'top left';
+                container.style.transform = 'scale(' + zoom + ')';
+
+                // Attach to DOM
+                parent.appendChild(container);
+
+                // Add Handler
+                this.bindHandlers();
+            }
+
+            PopupMenuInstance.prototype.close = function() {
+                this.unbindHandlers();
+                domRemove(this._container);
+                delete outer._instances[this.name];
+            };
+
+            PopupMenuInstance.prototype.bindHandlers = function() {
+
+                var self = this,
+                    eventBus = outer._eventBus;
+
+                this._closeHandler = function() {
+                    self.close();
+                };
+
+                eventBus.once('contextPad.close', this._closeHandler);
+                eventBus.once('canvas.viewbox.changed', this._closeHandler);
+            };
+
+            PopupMenuInstance.prototype.unbindHandlers = function() {
+
+                var eventBus = outer._eventBus;
+
+                eventBus.off('contextPad.close', this._closeHandler);
+                eventBus.off('canvas.viewbox.changed', this._closeHandler);
+            };
+
+            PopupMenuInstance.prototype.trigger = function(event) {
+
+                var element = event.target,
+                    actionName = element.getAttribute('data-action') ||
+                    element.parentNode.getAttribute('data-action');
+
+                var action = this._actions[actionName];
+
+
+                if (action) {
+                    action();
+                }
+
+                // silence other actions
+                event.preventDefault();
+            };
+
+            var instance = outer._instances[name] = new PopupMenuInstance(position, entries, parent, options);
+
+            return instance;
+        };
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "min-dom/lib/attr": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\attr.js",
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js",
+        "min-dom/lib/remove": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\remove.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\popup-menu\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports = {
+            __init__: ['popupMenu'],
+            popupMenu: ['type', require('./PopupMenu')]
+        };
+
+    }, {
+        "./PopupMenu": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\popup-menu\\PopupMenu.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\replace\\Replace.js": [function(require, module, exports) {
+        'use strict';
+
+
+        /**
+         * Service that allow replacing of elements.
+         * 
+         * 
+         * @class
+         * @constructor
+         */
+        function Replace(modeling) {
+
+            this._modeling = modeling;
+        }
+
+        module.exports = Replace;
+
+        Replace.$inject = ['modeling'];
+
+        /**
+         * @param {Element}
+         *            oldElement - Element to be replaced
+         * @param {Object}
+         *            newElementData - Containing information about the new Element, for
+         *            example height, width, type.
+         * @param {Object}
+         *            options - Custom options that will be attached to the context. It
+         *            can be used to inject data that is needed in the command chain.
+         *            For example it could be used in
+         *            eventbus.on('commandStack.shape.replace.postExecute') to change
+         *            shape attributes after shape creation.
+         */
+        Replace.prototype.replaceElement = function(oldElement, newElementData, options) {
+
+            var modeling = this._modeling;
+
+            var newElement = null;
+
+            if (oldElement.waypoints) {
+                // TODO
+                // modeling.replaceConnection
+            } else {
+                // set center of element for modeling API
+                // if no new width / height is given use old elements size
+                newElementData.x = oldElement.x + (newElementData.width || oldElement.width) / 2;
+                newElementData.y = oldElement.y + (newElementData.height || oldElement.height) / 2;
+
+                newElement = modeling.replaceShape(oldElement, newElementData, options);
+            }
+
+            return newElement;
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\replace\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports = {
+            __init__: ['replace'],
+            replace: ['type', require('./Replace')]
+        };
+
+    }, {
+        "./Replace": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\replace\\Replace.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\Resize.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            filter = require('lodash/collection/filter'),
+            pick = require('lodash/object/pick');
+
+        var ResizeUtil = require('./ResizeUtil'),
+            domEvent = require('min-dom/lib/event'),
+            Elements = require('../../util/Elements');
+
+        var isPrimaryButton = require('../../util/Mouse').isPrimaryButton;
+
+        var round = Math.round;
+
+        var Snap = require('../../../vendor/snapsvg');
+
+        var HANDLE_OFFSET = -2,
+            HANDLE_SIZE = 5,
+            HANDLE_HIT_SIZE = 20;
+
+        var MARKER_RESIZING = 'djs-resizing',
+            MARKER_RESIZE_NOT_OK = 'resize-not-ok',
+            CLS_RESIZER = 'djs-resizer';
+
+
+        /**
+         * Implements resize on shapes by
+         *  * adding resize handles, * creating a visual during resize * checking resize
+         * rules * committing a change once finished
+         * 
+         *  ## Customizing
+         * 
+         * It's possible to customize the resizing behaviour by intercepting
+         * 'resize.start' and providing the following parameters through the 'context':
+         *  * minDimensions ({ width, height }) - Minimum shape dimensions *
+         * childrenBoxPadding (number) - Gap between the minimum bounding box and the
+         * container
+         * 
+         * f.ex:
+         * 
+         * eventBus.on('resize.start', 1500, function(event) { var context =
+         * event.context,
+         * 
+         * context.minDimensions = { width: 140, height: 120 };
+         * context.childrenBoxPadding = 30; });
+         */
+
+        function Resize(eventBus, elementRegistry, rules, modeling, canvas, selection, dragging) {
+
+            function canResize(context) {
+                var ctx = pick(context, ['newBounds', 'shape', 'delta', 'direction']);
+                return rules.allowed('shape.resize', ctx);
+            }
+
+
+            // resizing implementation //////////////////////////////////
+
+            /**
+             * A helper that realizes the resize visuals
+             */
+            var visuals = {
+                create: function(context) {
+                    var container = canvas.getDefaultLayer(),
+                        shape = context.shape,
+                        frame;
+
+                    frame = context.frame = Snap.create('rect', {
+                        class: 'djs-resize-overlay',
+                        width: shape.width + 10,
+                        height: shape.height + 10,
+                        x: shape.x - 5,
+                        y: shape.y - 5
+                    });
+
+                    frame.appendTo(container);
+                },
+
+                update: function(context) {
+                    var frame = context.frame,
+                        bounds = context.newBounds;
+
+                    if (bounds.width > 5) {
+                        frame.attr({
+                            x: bounds.x,
+                            width: bounds.width
+                        });
+                    }
+
+                    if (bounds.height > 5) {
+                        frame.attr({
+                            y: bounds.y,
+                            height: bounds.height
+                        });
+                    }
+
+                    frame[context.canExecute ? 'removeClass' : 'addClass'](MARKER_RESIZE_NOT_OK);
+                },
+
+                remove: function(context) {
+                    if (context.frame) {
+                        context.frame.remove();
+                    }
+                }
+            };
+
+            function computeMinBoundaryBox(context) {
+
+                var shape = context.shape,
+                    direction = context.direction,
+                    minDimensions = context.minDimensions || {},
+                    childrenBoxPadding = context.childrenBoxPadding || 20,
+                    children,
+                    minBoundaryBox;
+
+                // grab all the shapes that are NOT labels or connections
+                children = filter(shape.children, function(child) {
+                    // connections
+                    if (child.waypoints) {
+                        return false;
+                    }
+
+                    // labels
+                    if (child.type === 'label') {
+                        return false;
+                    }
+
+                    return true;
+                });
+
+                // compute a minimum bounding box
+                // around the existing children
+                if (children.length) {
+                    minBoundaryBox = Elements.getBBox(children);
+
+                    // add a gap between the minBoundaryBox and the resizable container
+                    minBoundaryBox.width += childrenBoxPadding * 2;
+                    minBoundaryBox.height += childrenBoxPadding * 2;
+                    minBoundaryBox.x -= childrenBoxPadding;
+                    minBoundaryBox.y -= childrenBoxPadding;
+                } else {
+                    minBoundaryBox = ResizeUtil.getMinResizeBounds(direction, shape, {
+                        width: minDimensions.width || 10,
+                        height: minDimensions.height || 10
+                    });
+                }
+
+                return minBoundaryBox;
+            }
+
+            eventBus.on('resize.start', function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    minBoundaryBox = context.minBoundaryBox;
+
+                if (minBoundaryBox === undefined) {
+                    context.minBoundaryBox = computeMinBoundaryBox(context);
+                }
+
+                // add resizable indicator
+                canvas.addMarker(shape, MARKER_RESIZING);
+
+                visuals.create(context);
+            });
+
+            eventBus.on('resize.move', function(event) {
+
+                var context = event.context,
+                    shape = context.shape,
+                    direction = context.direction,
+                    minBoundaryBox = context.minBoundaryBox,
+                    delta;
+
+                delta = {
+                    x: event.dx,
+                    y: event.dy
+                };
+
+                context.delta = delta;
+
+                context.newBounds = ResizeUtil.resizeBounds(shape, direction, delta);
+
+                if (minBoundaryBox) {
+                    context.newBounds = ResizeUtil.ensureMinBounds(context.newBounds, minBoundaryBox);
+                }
+
+                // update + cache executable state
+                context.canExecute = canResize(context);
+
+                // update resize frame visuals
+                visuals.update(context);
+            });
+
+            eventBus.on('resize.end', function(event) {
+                var context = event.context,
+                    shape = context.shape;
+
+                var newBounds = context.newBounds;
+
+
+                // ensure we have actual pixel values for new bounds
+                // (important when zoom level was > 1 during move)
+                newBounds.x = round(newBounds.x);
+                newBounds.y = round(newBounds.y);
+                newBounds.width = round(newBounds.width);
+                newBounds.height = round(newBounds.height);
+
+                // perform the actual resize
+                if (context.canExecute) {
+                    modeling.resizeShape(shape, context.newBounds);
+                }
+            });
+
+            eventBus.on('resize.cleanup', function(event) {
+
+                var context = event.context,
+                    shape = context.shape;
+
+                // remove resizable indicator
+                canvas.removeMarker(shape, MARKER_RESIZING);
+
+                // remove frame + destroy context
+                visuals.remove(context);
+            });
+
+
+            function activate(event, shape, direction) {
+
+                dragging.activate(event, 'resize', {
+                    autoActivate: true,
+                    cursor: 'resize-' + (/nw|se/.test(direction) ? 'nwse' : 'nesw'),
+                    data: {
+                        shape: shape,
+                        context: {
+                            direction: direction,
+                            shape: shape
+                        }
+                    }
+                });
+            }
+
+            function makeDraggable(element, gfx, direction) {
+
+                function listener(event) {
+                    // only trigger on left mouse button
+                    if (isPrimaryButton(event)) {
+                        activate(event, element, direction);
+                    }
+                }
+
+                domEvent.bind(gfx.node, 'mousedown', listener);
+                domEvent.bind(gfx.node, 'touchstart', listener);
+            }
+
+            function __createResizer(gfx, x, y, rotation, direction) {
+
+                var group = gfx.group().addClass(CLS_RESIZER).addClass(CLS_RESIZER + '-' + direction);
+
+                var origin = -HANDLE_SIZE + HANDLE_OFFSET;
+
+                // Create four drag indicators on the outline
+                group.rect(origin, origin, HANDLE_SIZE, HANDLE_SIZE).addClass(CLS_RESIZER + '-visual');
+                group.rect(origin, origin, HANDLE_HIT_SIZE, HANDLE_HIT_SIZE).addClass(CLS_RESIZER + '-hit');
+
+                var matrix = new Snap.Matrix().translate(x, y).rotate(rotation, 0, 0);
+                group.transform(matrix);
+
+                return group;
+            }
+
+            function createResizer(element, gfx, direction) {
+
+                var resizer;
+
+                if (direction === 'nw') {
+                    resizer = __createResizer(gfx, 0, 0, 0, direction);
+                } else if (direction === 'ne') {
+                    resizer = __createResizer(gfx, element.width, 0, 90, direction);
+                } else if (direction === 'se') {
+                    resizer = __createResizer(gfx, element.width, element.height, 180, direction);
+                } else {
+                    resizer = __createResizer(gfx, 0, element.height, 270, direction);
+                }
+
+                makeDraggable(element, resizer, direction);
+            }
+
+            // resize handles implementation ///////////////////////////////
+
+            function addResize(shape) {
+
+                if (!canResize({
+                        shape: shape
+                    })) {
+                    return;
+                }
+
+                var gfx = elementRegistry.getGraphics(shape);
+
+                createResizer(shape, gfx, 'nw');
+                createResizer(shape, gfx, 'ne');
+                createResizer(shape, gfx, 'se');
+                createResizer(shape, gfx, 'sw');
+            }
+
+            function removeResize(shape) {
+
+                var gfx = elementRegistry.getGraphics(shape);
+                var resizers = gfx.selectAll('.' + CLS_RESIZER);
+
+                forEach(resizers, function(resizer) {
+                    resizer.remove();
+                });
+            }
+
+            eventBus.on('selection.changed', function(e) {
+
+                var oldSelection = e.oldSelection,
+                    newSelection = e.newSelection;
+
+                // remove old selection markers
+                forEach(oldSelection, removeResize);
+
+                // add new selection markers ONLY if single selection
+                if (newSelection.length === 1) {
+                    forEach(newSelection, addResize);
+                }
+            });
+
+            eventBus.on('shape.changed', function(e) {
+                var shape = e.element;
+
+                removeResize(shape);
+
+                if (selection.isSelected(shape)) {
+                    addResize(shape);
+                }
+            });
+
+
+            // API
+
+            this.activate = activate;
+        }
+
+        Resize.$inject = ['eventBus', 'elementRegistry', 'rules', 'modeling', 'canvas', 'selection', 'dragging'];
+
+        module.exports = Resize;
+
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../util/Elements": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js",
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js",
+        "./ResizeUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\ResizeUtil.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/object/pick": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\ResizeUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Resize the given bounds by the specified delta from a given anchor point.
+         * 
+         * @param {Bounds}
+         *            bounds the bounding box that should be resized
+         * @param {String}
+         *            direction in which the element is resized (nw, ne, se, sw)
+         * @param {Point}
+         *            delta of the resize operation
+         * 
+         * @return {Bounds} resized bounding box
+         */
+        module.exports.resizeBounds = function(bounds, direction, delta) {
+
+            var dx = delta.x,
+                dy = delta.y;
+
+            switch (direction) {
+
+                case 'nw':
+                    return {
+                        x: bounds.x + dx,
+                        y: bounds.y + dy,
+                        width: bounds.width - dx,
+                        height: bounds.height - dy
+                    };
+
+                case 'sw':
+                    return {
+                        x: bounds.x + dx,
+                        y: bounds.y,
+                        width: bounds.width - dx,
+                        height: bounds.height + dy
+                    };
+
+                case 'ne':
+                    return {
+                        x: bounds.x,
+                        y: bounds.y + dy,
+                        width: bounds.width + dx,
+                        height: bounds.height - dy
+                    };
+
+                case 'se':
+                    return {
+                        x: bounds.x,
+                        y: bounds.y,
+                        width: bounds.width + dx,
+                        height: bounds.height + dy
+                    };
+
+                default:
+                    throw new Error('unrecognized direction: ' + direction);
+            }
+        };
+
+        module.exports.reattachPoint = function(bounds, newBounds, point) {
+
+            var sx = bounds.width / newBounds.width,
+                sy = bounds.height / newBounds.height;
+
+            return {
+                x: Math.round((newBounds.x + newBounds.width / 2)) - Math.floor(((bounds.x + bounds.width / 2) - point.x) / sx),
+                y: Math.round((newBounds.y + newBounds.height / 2)) - Math.floor(((bounds.y + bounds.height / 2) - point.y) / sy)
+            };
+        };
+
+
+        module.exports.ensureMinBounds = function(currentBounds, minBounds) {
+            var topLeft = {
+                x: Math.min(currentBounds.x, minBounds.x),
+                y: Math.min(currentBounds.y, minBounds.y)
+            };
+
+            var bottomRight = {
+                x: Math.max(currentBounds.x + currentBounds.width, minBounds.x + minBounds.width),
+                y: Math.max(currentBounds.y + currentBounds.height, minBounds.y + minBounds.height)
+            };
+
+            return {
+                x: topLeft.x,
+                y: topLeft.y,
+                width: bottomRight.x - topLeft.x,
+                height: bottomRight.y - topLeft.y
+            };
+        };
+
+
+        module.exports.getMinResizeBounds = function(direction, currentBounds, minDimensions) {
+
+            switch (direction) {
+                case 'nw':
+                    return {
+                        x: currentBounds.x + currentBounds.width - minDimensions.width,
+                        y: currentBounds.y + currentBounds.height - minDimensions.height,
+                        width: minDimensions.width,
+                        height: minDimensions.height
+                    };
+                case 'sw':
+                    return {
+                        x: currentBounds.x + currentBounds.width - minDimensions.width,
+                        y: currentBounds.y,
+                        width: minDimensions.width,
+                        height: minDimensions.height
+                    };
+                case 'ne':
+                    return {
+                        x: currentBounds.x,
+                        y: currentBounds.y + currentBounds.height - minDimensions.height,
+                        width: minDimensions.width,
+                        height: minDimensions.height
+                    };
+                case 'se':
+                    return {
+                        x: currentBounds.x,
+                        y: currentBounds.y,
+                        width: minDimensions.width,
+                        height: minDimensions.height
+                    };
+                default:
+                    throw new Error('unrecognized direction: ' + direction);
+            }
+        };
+
+
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [
+                require('../modeling'),
+                require('../rules'),
+                require('../dragging')
+            ],
+            __init__: ['resize'],
+            resize: ['type', require('./Resize')]
+        };
+
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "./Resize": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\resize\\Resize.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\RuleProvider.js": [function(require, module, exports) {
+        'use strict';
+
+        var inherits = require('inherits');
+
+        var CommandInterceptor = require('../../command/CommandInterceptor');
+
+        /**
+         * A basic provider that may be extended to implement modeling rules.
+         * 
+         * Extensions should implement the init method to actually add their custom
+         * modeling checks. Checks may be added via the #addRule(action, fn) method.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         */
+        function RuleProvider(eventBus) {
+            CommandInterceptor.call(this, eventBus);
+
+            this.init();
+        }
+
+        RuleProvider.$inject = ['eventBus'];
+
+        inherits(RuleProvider, CommandInterceptor);
+
+        module.exports = RuleProvider;
+
+
+        /**
+         * Adds a modeling rule for the given action, implemented through a callback
+         * function.
+         * 
+         * The function will receive the modeling specific action context to perform its
+         * check. It must return false or null to disallow the action from happening.
+         * 
+         * Returning <code>null</code> may encode simply ignoring the action.
+         * 
+         * @example
+         * 
+         * ResizableRules.prototype.init = function() {
+         * 
+         * this.addRule('shape.resize', function(context) {
+         * 
+         * var shape = context.shape;
+         * 
+         * if (!context.newBounds) { // check general resizability if (!shape.resizable) {
+         * return false; } } else { // element must have minimum size of 10*10 points
+         * return context.newBounds.width > 10 && context.newBounds.height > 10; } }); };
+         * 
+         * @param {String|Array
+         *            <String>} actions the identifier for the modeling action to check
+         * @param {Function}
+         *            fn the callback function that performs the actual check
+         */
+        RuleProvider.prototype.addRule = function(actions, fn) {
+
+            var self = this;
+
+            if (typeof actions === 'string') {
+                actions = [actions];
+            }
+
+            actions.forEach(function(action) {
+
+                self.canExecute(action, function(context, action, event) {
+                    return fn(context);
+                }, true);
+            });
+        };
+    }, {
+        "../../command/CommandInterceptor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\CommandInterceptor.js",
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\Rules.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * A service that provides rules for certain diagram actions.
+         * 
+         * @param {CommandStack}
+         *            commandStack
+         */
+        function Rules(commandStack) {
+            this._commandStack = commandStack;
+        }
+
+        Rules.$inject = ['commandStack'];
+
+        module.exports = Rules;
+
+
+        /**
+         * This method can be queried to ask whether certain modeling actions are
+         * allowed or not.
+         * 
+         * @param {String}
+         *            action the action to be checked
+         * @param {Object}
+         *            [context] the context to check the action in
+         * 
+         * @return {Boolean} returns true, false or null depending on whether the
+         *         operation is allowed, not allowed or should be ignored.
+         */
+        Rules.prototype.allowed = function(action, context) {
+            var allowed = this._commandStack.canExecute(action, context);
+
+            // map undefined to true, i.e. no rules
+            return allowed === undefined ? true : allowed;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../../command')],
+            __init__: ['rules'],
+            rules: ['type', require('./Rules')]
+        };
+
+    }, {
+        "../../command": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\command\\index.js",
+        "./Rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\Rules.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\Selection.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            forEach = require('lodash/collection/forEach');
+
+
+        /**
+         * A service that offers the current selection in a diagram. Offers the api to
+         * control the selection, too.
+         * 
+         * @class
+         * 
+         * @param {EventBus}
+         *            eventBus the event bus
+         */
+        function Selection(eventBus) {
+
+            this._eventBus = eventBus;
+
+            this._selectedElements = [];
+
+            var self = this;
+
+            eventBus.on(['shape.remove', 'connection.remove'], function(e) {
+                var element = e.element;
+                self.deselect(element);
+            });
+        }
+
+        Selection.$inject = ['eventBus'];
+
+        module.exports = Selection;
+
+
+        Selection.prototype.deselect = function(element) {
+            var selectedElements = this._selectedElements;
+
+            var idx = selectedElements.indexOf(element);
+
+            if (idx !== -1) {
+                var oldSelection = selectedElements.slice();
+
+                selectedElements.splice(idx, 1);
+
+                this._eventBus.fire('selection.changed', {
+                    oldSelection: oldSelection,
+                    newSelection: selectedElements
+                });
+            }
+        };
+
+
+        Selection.prototype.get = function() {
+            return this._selectedElements;
+        };
+
+        Selection.prototype.isSelected = function(element) {
+            return this._selectedElements.indexOf(element) !== -1;
+        };
+
+
+        /**
+         * This method selects one or more elements on the diagram.
+         * 
+         * By passing an additional add parameter you can decide whether or not the
+         * element(s) should be added to the already existing selection or not.
+         * 
+         * @method Selection#select
+         * 
+         * @param {Object|Object[]}
+         *            elements element or array of elements to be selected
+         * @param {boolean}
+         *            [add] whether the element(s) should be appended to the current
+         *            selection, defaults to false
+         */
+        Selection.prototype.select = function(elements, add) {
+            var selectedElements = this._selectedElements,
+                oldSelection = selectedElements.slice();
+
+            if (!isArray(elements)) {
+                elements = elements ? [elements] : [];
+            }
+
+            // selection may be cleared by passing an empty array or null
+            // to the method
+            if (add) {
+                forEach(elements, function(element) {
+                    if (selectedElements.indexOf(element) !== -1) {
+                        // already selected
+                        return;
+                    } else {
+                        selectedElements.push(element);
+                    }
+                });
+            } else {
+                this._selectedElements = selectedElements = elements.slice();
+            }
+            this._eventBus.fire('selection.changed', {
+                oldSelection: oldSelection,
+                newSelection: selectedElements
+            });
+        };
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\SelectionBehavior.js": [function(require, module, exports) {
+        'use strict';
+
+        var hasPrimaryModifier = require('../../util/Mouse').hasPrimaryModifier;
+
+
+        function SelectionBehavior(eventBus, selection, canvas) {
+
+            eventBus.on('create.end', 500, function(e) {
+                if (e.context.canExecute) {
+                    selection.select(e.shape);
+                }
+            });
+
+            eventBus.on('connect.end', 500, function(e) {
+                if (e.context.canExecute && e.context.target) {
+                    selection.select(e.context.target);
+                }
+            });
+
+            eventBus.on('shape.move.end', 500, function(e) {
+                selection.select(e.context.shapes);
+            });
+
+            eventBus.on('element.keydown', function(event) {
+                alert("Key Down Elements ");
+            });
+            // Shift + click selection
+            eventBus.on('element.click', function(event) {
+
+                var element = event.element;
+
+                // do not select the root element
+                // or connections
+                if (element === canvas.getRootElement()) {
+                    element = null;
+                }
+
+                var isSelected = selection.isSelected(element),
+                    isMultiSelect = selection.get().length > 1;
+
+                // mouse-event: SELECTION_KEY
+                var add = hasPrimaryModifier(event);
+
+                // select OR deselect element in multi selection
+                if (isSelected && isMultiSelect) {
+                    if (add) {
+                        return selection.deselect(element);
+                    } else {
+                        return selection.select(element);
+                    }
+                } else
+                if (!isSelected) {
+                    selection.select(element, add);
+                } else {
+                    selection.deselect(element);
+                }
+            });
+
+        }
+
+        SelectionBehavior.$inject = ['eventBus', 'selection', 'canvas'];
+
+        module.exports = SelectionBehavior;
+
+    }, {
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\SelectionVisuals.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var MARKER_HOVER = 'hover',
+            MARKER_SELECTED = 'selected';
+
+
+        /**
+         * A plugin that adds a visible selection UI to shapes and connections by
+         * appending the <code>hover</code> and <code>selected</code> classes to
+         * them.
+         * 
+         * @class
+         * 
+         * Makes elements selectable, too.
+         * 
+         * @param {EventBus}
+         *            events
+         * @param {SelectionService}
+         *            selection
+         * @param {Canvas}
+         *            canvas
+         */
+        function SelectionVisuals(events, canvas, selection, graphicsFactory, styles) {
+
+            this._multiSelectionBox = null;
+
+            function addMarker(e, cls) {
+                canvas.addMarker(e, cls);
+            }
+
+            function removeMarker(e, cls) {
+                canvas.removeMarker(e, cls);
+            }
+
+            events.on('element.hover', function(event) {
+                addMarker(event.element, MARKER_HOVER);
+            });
+
+            events.on('element.out', function(event) {
+                removeMarker(event.element, MARKER_HOVER);
+            });
+
+            events.on('selection.changed', function(event) {
+
+                function deselect(s) {
+                    removeMarker(s, MARKER_SELECTED);
+                }
+
+                function select(s) {
+                    addMarker(s, MARKER_SELECTED);
+                }
+
+                var oldSelection = event.oldSelection,
+                    newSelection = event.newSelection;
+
+                forEach(oldSelection, function(e) {
+                    if (newSelection.indexOf(e) === -1) {
+                        deselect(e);
+                    }
+                });
+
+                forEach(newSelection, function(e) {
+                    if (oldSelection.indexOf(e) === -1) {
+                        select(e);
+                    }
+                });
+            });
+        }
+
+        SelectionVisuals.$inject = [
+            'eventBus',
+            'canvas',
+            'selection',
+            'graphicsFactory',
+            'styles'
+        ];
+
+        module.exports = SelectionVisuals;
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['selectionVisuals', 'selectionBehavior'],
+            __depends__: [
+                require('../interaction-events'),
+                require('../outline')
+            ],
+            selection: ['type', require('./Selection')],
+            selectionVisuals: ['type', require('./SelectionVisuals')],
+            selectionBehavior: ['type', require('./SelectionBehavior')]
+        };
+
+    }, {
+        "../interaction-events": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js",
+        "../outline": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\outline\\index.js",
+        "./Selection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\Selection.js",
+        "./SelectionBehavior": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\SelectionBehavior.js",
+        "./SelectionVisuals": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\selection\\SelectionVisuals.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapContext.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+        var snapTo = require('./SnapUtil').snapTo;
+
+
+        /**
+         * A snap context, containing the (possibly incomplete) mappings of drop targets
+         * (to identify the snapping) to computed snap points.
+         */
+        function SnapContext() {
+
+            /**
+             * Map<String, SnapPoints> mapping drop targets to a list of possible
+             * snappings.
+             * 
+             * @type {Object}
+             */
+            this._targets = {};
+
+            /**
+             * Map<String, Point> initial positioning of element regarding various snap
+             * directions.
+             * 
+             * @type {Object}
+             */
+            this._snapOrigins = {};
+
+            /**
+             * List of snap locations
+             * 
+             * @type {Array<String>}
+             */
+            this._snapLocations = [];
+
+            /**
+             * Map<String, Array<Point>> of default snapping locations
+             * 
+             * @type {Object}
+             */
+            this._defaultSnaps = {};
+        }
+
+
+        SnapContext.prototype.getSnapOrigin = function(snapLocation) {
+            return this._snapOrigins[snapLocation];
+        };
+
+
+        SnapContext.prototype.setSnapOrigin = function(snapLocation, initialValue) {
+            this._snapOrigins[snapLocation] = initialValue;
+
+            if (this._snapLocations.indexOf(snapLocation) === -1) {
+                this._snapLocations.push(snapLocation);
+            }
+        };
+
+
+        SnapContext.prototype.addDefaultSnap = function(type, point) {
+
+            var snapValues = this._defaultSnaps[type];
+
+            if (!snapValues) {
+                snapValues = this._defaultSnaps[type] = [];
+            }
+
+            snapValues.push(point);
+        };
+
+        /**
+         * Return a number of initialized snaps, i.e. snap locations such as top-left,
+         * mid, bottom-right and so forth.
+         * 
+         * @return {Array<String>} snapLocations
+         */
+        SnapContext.prototype.getSnapLocations = function() {
+            return this._snapLocations;
+        };
+
+        /**
+         * Set the snap locations for this context.
+         * 
+         * The order of locations determines precedence.
+         * 
+         * @param {Array
+         *            <String>} snapLocations
+         */
+        SnapContext.prototype.setSnapLocations = function(snapLocations) {
+            this._snapLocations = snapLocations;
+        };
+
+        /**
+         * Get snap points for a given target
+         * 
+         * @param {Element|String}
+         *            target
+         */
+        SnapContext.prototype.pointsForTarget = function(target) {
+
+            var targetId = target.id || target;
+
+            var snapPoints = this._targets[targetId];
+
+            if (!snapPoints) {
+                snapPoints = this._targets[targetId] = new SnapPoints();
+                snapPoints.initDefaults(this._defaultSnaps);
+            }
+
+            return snapPoints;
+        };
+
+        module.exports = SnapContext;
+
+
+        /**
+         * Creates the snap points and initializes them with the given default values.
+         * 
+         * @param {Object
+         *            <String, Array<Point>>} [defaultPoints]
+         */
+        function SnapPoints(defaultSnaps) {
+
+            /**
+             * Map<String, Map<(x|y), Array<Number>>> mapping snap locations, i.e.
+             * top-left, bottom-right, center to actual snap values.
+             * 
+             * @type {Object}
+             */
+            this._snapValues = {};
+        }
+
+        SnapPoints.prototype.add = function(snapLocation, point) {
+
+            var snapValues = this._snapValues[snapLocation];
+
+            if (!snapValues) {
+                snapValues = this._snapValues[snapLocation] = {
+                    x: [],
+                    y: []
+                };
+            }
+
+            if (snapValues.x.indexOf(point.x) === -1) {
+                snapValues.x.push(point.x);
+            }
+
+            if (snapValues.y.indexOf(point.y) === -1) {
+                snapValues.y.push(point.y);
+            }
+        };
+
+
+        SnapPoints.prototype.snap = function(point, snapLocation, axis, tolerance) {
+            var snappingValues = this._snapValues[snapLocation];
+
+            return snappingValues && snapTo(point[axis], snappingValues[axis], tolerance);
+        };
+
+        /**
+         * Initialize a number of default snapping points.
+         * 
+         * @param {Object}
+         *            defaultSnaps
+         */
+        SnapPoints.prototype.initDefaults = function(defaultSnaps) {
+
+            var self = this;
+
+            forEach(defaultSnaps || {}, function(snapPoints, snapLocation) {
+                forEach(snapPoints, function(point) {
+                    self.add(snapLocation, point);
+                });
+            });
+        };
+    }, {
+        "./SnapUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapUtil.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        var abs = Math.abs,
+            round = Math.round;
+
+
+        /**
+         * Snap value to a collection of reference values.
+         * 
+         * @param {Number}
+         *            value
+         * @param {Array
+         *            <Number>} values
+         * @param {Number}
+         *            [tolerance=10]
+         * 
+         * @return {Number} the value we snapped to or null, if none snapped
+         */
+        function snapTo(value, values, tolerance) {
+            tolerance = tolerance === undefined ? 10 : tolerance;
+
+            var idx, snapValue;
+
+            for (idx = 0; idx < values.length; idx++) {
+                snapValue = values[idx];
+
+                if (abs(snapValue - value) <= tolerance) {
+                    return snapValue;
+                }
+            }
+        }
+
+
+        module.exports.snapTo = snapTo;
+
+
+        function topLeft(bounds) {
+            return {
+                x: bounds.x,
+                y: bounds.y
+            };
+        }
+
+        module.exports.topLeft = topLeft;
+
+
+        function mid(bounds, defaultValue) {
+
+            if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) {
+                return defaultValue;
+            }
+
+            return {
+                x: round(bounds.x + bounds.width / 2),
+                y: round(bounds.y + bounds.height / 2)
+            };
+        }
+
+        module.exports.mid = mid;
+
+
+        function bottomRight(bounds) {
+            return {
+                x: bounds.x + bounds.width,
+                y: bounds.y + bounds.height
+            };
+        }
+
+        module.exports.bottomRight = bottomRight;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\Snapping.js": [function(require, module, exports) {
+        'use strict';
+
+        var filter = require('lodash/collection/filter'),
+            forEach = require('lodash/collection/forEach'),
+            debounce = require('lodash/function/debounce');
+
+
+        var mid = require('./SnapUtil').mid;
+
+        var SnapContext = require('./SnapContext');
+
+        /**
+         * A general purpose snapping component for diagram elements.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {Canvas}
+         *            canvas
+         */
+        function Snapping(eventBus, canvas) {
+
+            this._canvas = canvas;
+
+            var self = this;
+
+            eventBus.on(['shape.move.start', 'create.start'], function(event) {
+                self.initSnap(event);
+            });
+
+            eventBus.on(['shape.move.move', 'shape.move.end', 'create.move', 'create.end'], function(event) {
+                if (event.snapped) {
+                    return;
+                }
+
+                self.snap(event);
+            });
+
+            eventBus.on(['shape.move.cleanup', 'create.cleanup'], function(event) {
+                self.hide();
+            });
+
+            // delay hide by 1000 seconds since last match
+            this._asyncHide = debounce(this.hide, 1000);
+        }
+
+        Snapping.$inject = ['eventBus', 'canvas'];
+
+        module.exports = Snapping;
+
+
+        Snapping.prototype.initSnap = function(event) {
+
+            var context = event.context,
+                shape = context.shape,
+                snapContext = context.snapContext;
+
+            if (!snapContext) {
+                snapContext = context.snapContext = new SnapContext();
+            }
+
+            var snapMid = mid(shape, event);
+
+            snapContext.setSnapOrigin('mid', {
+                x: snapMid.x - event.x,
+                y: snapMid.y - event.y
+            });
+
+            return snapContext;
+        };
+
+
+        Snapping.prototype.snap = function(event) {
+
+            var context = event.context,
+                snapContext = context.snapContext,
+                shape = context.shape,
+                target = context.target,
+                snapLocations = snapContext.getSnapLocations();
+
+            if (!target) {
+                return;
+            }
+
+            var snapPoints = snapContext.pointsForTarget(target);
+
+            if (!snapPoints.initialized) {
+                this.addTargetSnaps(snapPoints, shape, target);
+
+                snapPoints.initialized = true;
+            }
+
+
+            var snapping = {};
+
+            forEach(snapLocations, function(location) {
+
+                var snapOrigin = snapContext.getSnapOrigin(location);
+
+                var snapCurrent = {
+                    x: event.x + snapOrigin.x,
+                    y: event.y + snapOrigin.y
+                };
+
+                // snap on both axis, if not snapped already
+                forEach(['x', 'y'], function(axis) {
+                    var locationSnapping;
+
+                    if (!snapping[axis]) {
+                        locationSnapping = snapPoints.snap(snapCurrent, location, axis, 7);
+
+                        if (locationSnapping !== undefined) {
+                            snapping[axis] = {
+                                value: locationSnapping,
+                                originValue: locationSnapping - snapOrigin[axis]
+                            };
+                        }
+                    }
+                });
+
+                // no more need to snap, drop out of interation
+                if (snapping.x && snapping.y) {
+                    return false;
+                }
+            });
+
+
+            // show snap visuals
+
+            this.showSnapLine('vertical', snapping.x && snapping.x.value);
+            this.showSnapLine('horizontal', snapping.y && snapping.y.value);
+
+
+            // adjust event { x, y, dx, dy } and mark as snapping
+            var cx, cy;
+
+            if (snapping.x) {
+
+                cx = event.x - snapping.x.originValue;
+
+                event.x = snapping.x.originValue;
+                event.dx = event.dx - cx;
+
+                event.snapped = true;
+            }
+
+            if (snapping.y) {
+                cy = event.y - snapping.y.originValue;
+
+                event.y = snapping.y.originValue;
+                event.dy = event.dy - cy;
+
+                event.snapped = true;
+            }
+        };
+
+
+        Snapping.prototype._createLine = function(orientation) {
+
+            var root = this._canvas.getLayer('snap');
+
+            var line = root.path('M0,0 L0,0').addClass('djs-snap-line');
+
+            return {
+                update: function(position) {
+
+                    if (position === undefined) {
+                        line.attr({
+                            display: 'none'
+                        });
+                    } else {
+                        if (orientation === 'horizontal') {
+                            line.attr({
+                                path: 'M-100000,' + position + ' L+100000,' + position,
+                                display: ''
+                            });
+                        } else {
+                            line.attr({
+                                path: 'M ' + position + ',-100000 L ' + position + ', +100000',
+                                display: ''
+                            });
+                        }
+                    }
+                }
+            };
+        };
+
+
+        Snapping.prototype._createSnapLines = function() {
+
+            this._snapLines = {
+                horizontal: this._createLine('horizontal'),
+                vertical: this._createLine('vertical')
+            };
+        };
+
+        Snapping.prototype.showSnapLine = function(orientation, position) {
+
+            var line = this.getSnapLine(orientation);
+
+            if (line) {
+                line.update(position);
+            }
+
+            this._asyncHide();
+        };
+
+        Snapping.prototype.getSnapLine = function(orientation) {
+            if (!this._snapLines) {
+                this._createSnapLines();
+            }
+
+            return this._snapLines[orientation];
+        };
+
+        Snapping.prototype.hide = function() {
+            forEach(this._snapLines, function(l) {
+                l.update();
+            });
+        };
+
+        Snapping.prototype.addTargetSnaps = function(snapPoints, shape, target) {
+
+            var siblings = this.getSiblings(shape, target);
+
+            forEach(siblings, function(s) {
+                snapPoints.add('mid', mid(s));
+            });
+
+        };
+
+        Snapping.prototype.getSiblings = function(element, target) {
+
+            // snap to all non connection siblings
+            return target && filter(target.children, function(e) {
+                return !e.hidden && !e.labelTarget && !e.waypoints && e !== element;
+            });
+        };
+    }, {
+        "./SnapContext": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapContext.js",
+        "./SnapUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\snapping\\SnapUtil.js",
+        "lodash/collection/filter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/function/debounce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\debounce.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceTool.js": [function(require, module, exports) {
+        'use strict';
+
+        var SpaceUtil = require('./SpaceUtil');
+
+        var Cursor = require('../../util/Cursor');
+
+        var hasPrimaryModifier = require('../../util/Mouse').hasPrimaryModifier;
+
+        var abs = Math.abs,
+            round = Math.round;
+
+        var HIGH_PRIORITY = 1500;
+
+        /**
+         * A tool that allows users to create and remove space in a diagram.
+         * 
+         * The tool needs to be activated manually via
+         * {@link SpaceTool#activate(MouseEvent)}.
+         */
+        function SpaceTool(eventBus, dragging, elementRegistry, modeling, rules) {
+
+            function canResize(shape) {
+                var ctx = {
+                    shape: shape
+                };
+                return rules.allowed('shape.resize', ctx);
+            }
+
+            function activateSelection(event, autoActivate) {
+                dragging.activate(event, 'spaceTool.selection', {
+                    cursor: 'crosshair',
+                    autoActivate: autoActivate,
+                    data: {
+                        context: {
+                            crosshair: {}
+                        }
+                    }
+                });
+            }
+
+            function activateMakeSpace(event) {
+                dragging.activate(event, 'spaceTool', {
+                    autoActivate: true,
+                    cursor: 'crosshair',
+                    data: {
+                        context: {}
+                    }
+                });
+            }
+
+
+            eventBus.on('spaceTool.selection.end', function(event) {
+                setTimeout(function() {
+                    activateMakeSpace(event.originalEvent);
+                });
+            });
+
+
+            var AXIS_TO_DIMENSION = {
+                    x: 'width',
+                    y: 'height'
+                },
+                AXIS_INVERTED = {
+                    x: 'y',
+                    y: 'x'
+                };
+
+
+            function initializeMakeSpace(event, context) {
+
+                var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y',
+                    offset = event['d' + axis],
+                    // start point of create space operation
+                    spacePos = event[axis] - offset,
+                    // list of moving shapes
+                    movingShapes = [],
+                    // list of resizing shapes
+                    resizingShapes = [];
+
+                if (abs(offset) < 5) {
+                    return false;
+                }
+
+                // inverts the offset to choose the shapes
+                // on the opposite side of the resizer if
+                // a key modifier is pressed
+                if (hasPrimaryModifier(event)) {
+                    offset *= -1;
+                }
+
+                // collect all elements that need to be moved _AND_
+                // resized given on the initial create space position
+                elementRegistry.forEach(function(shape) {
+                    var shapeStart = shape[[axis]],
+                        shapeEnd = shapeStart + shape[AXIS_TO_DIMENSION[axis]];
+
+                    // checking if it's root
+                    if (!shape.parent) {
+                        return;
+                    }
+
+                    // checking if it's a shape
+                    if (shape.waypoints) {
+                        return;
+                    }
+
+                    // shape after spacePos
+                    if (offset > 0 && shapeStart > spacePos) {
+                        return movingShapes.push(shape);
+                    }
+
+                    // shape before spacePos
+                    if (offset < 0 && shapeEnd < spacePos) {
+                        return movingShapes.push(shape);
+                    }
+
+                    // shape on top of spacePos, resize only if allowed
+                    if (shapeStart < spacePos && shapeEnd > spacePos && canResize(shape)) {
+                        return resizingShapes.push(shape);
+                    }
+                });
+
+                // store data in context
+                context.axis = axis;
+                context.direction = SpaceUtil.getDirection(axis, offset);
+                context.movingShapes = movingShapes;
+                context.resizingShapes = resizingShapes;
+
+                Cursor.set('resize-' + (axis === 'x' ? 'ew' : 'ns'));
+
+                return true;
+            }
+
+
+            eventBus.on('spaceTool.move', HIGH_PRIORITY, function(event) {
+
+                var context = event.context;
+
+                if (!context.initialized) {
+                    context.initialized = initializeMakeSpace(event, context);
+                }
+            });
+
+
+            eventBus.on('spaceTool.end', function(event) {
+
+                var context = event.context,
+                    axis = context.axis,
+                    direction = context.direction,
+                    movingShapes = context.movingShapes,
+                    resizingShapes = context.resizingShapes;
+
+                // skip if create space has not been initialized yet
+                if (!context.initialized) {
+                    return;
+                }
+
+                var delta = {
+                    x: round(event.dx),
+                    y: round(event.dy)
+                };
+                delta[AXIS_INVERTED[axis]] = 0;
+
+                return modeling.createSpace(movingShapes, resizingShapes, delta, direction);
+            });
+
+            // API
+            this.activateSelection = activateSelection;
+            this.activateMakeSpace = activateMakeSpace;
+        }
+
+        SpaceTool.$inject = ['eventBus', 'dragging', 'elementRegistry', 'modeling', 'rules'];
+
+        module.exports = SpaceTool;
+
+    }, {
+        "../../util/Cursor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Cursor.js",
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js",
+        "./SpaceUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceToolVisuals.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach');
+
+
+        var MARKER_DRAGGING = 'djs-dragging';
+
+
+        /**
+         * A plugin that makes shapes draggable / droppable.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {ElementRegistry}
+         *            elementRegistry
+         * @param {Canvas}
+         *            canvas
+         * @param {Styles}
+         *            styles
+         */
+
+        function SpaceToolVisuals(eventBus, elementRegistry, canvas, styles) {
+
+            function getGfx(e) {
+                return elementRegistry.getGraphics(e);
+            }
+
+            function addDragger(shape, dragGroup) {
+                var gfx = getGfx(shape);
+                var dragger = gfx.clone();
+                var bbox = gfx.getBBox();
+
+                dragger.attr(styles.cls('djs-dragger', [], {
+                    x: bbox.x,
+                    y: bbox.y
+                }));
+
+                dragGroup.add(dragger);
+            }
+
+            eventBus.on('spaceTool.selection.start', function(event) {
+                var space = canvas.getLayer('space'),
+                    context = event.context;
+
+                var orientation = {
+                    x: 'M 0,-10000 L 0,10000',
+                    y: 'M -10000,0 L 10000,0'
+                };
+
+                var crosshairGroup = space.group().attr(styles.cls('djs-crosshair-group', ['no-events']));
+
+                crosshairGroup.path(orientation.x).addClass('djs-crosshair');
+                crosshairGroup.path(orientation.y).addClass('djs-crosshair');
+
+                context.crosshairGroup = crosshairGroup;
+            });
+
+            eventBus.on('spaceTool.selection.move', function(event) {
+                var crosshairGroup = event.context.crosshairGroup;
+
+                crosshairGroup.translate(event.x, event.y);
+            });
+
+            eventBus.on('spaceTool.selection.cleanup', function(event) {
+                var context = event.context,
+                    crosshairGroup = context.crosshairGroup;
+
+                if (crosshairGroup) {
+                    crosshairGroup.remove();
+                }
+            });
+
+
+            // assign a low priority to this handler
+            // to let others modify the move context before
+            // we draw things
+            eventBus.on('spaceTool.move', function(event) {
+                /*
+                 * TODO (Ricardo): extend connections while adding space
+                 */
+
+                var context = event.context,
+                    line = context.line,
+                    axis = context.axis,
+                    dragShapes = context.movingShapes;
+
+                if (!context.initialized) {
+                    return;
+                }
+
+                if (!context.dragGroup) {
+                    var spaceLayer = canvas.getLayer('space');
+                    line = spaceLayer.path('M0,0 L0,0').addClass('djs-crosshair');
+
+                    context.line = line;
+                    var dragGroup = canvas.getDefaultLayer().group().attr(styles.cls('djs-drag-group', ['no-events']));
+
+
+                    forEach(dragShapes, function(shape) {
+                        addDragger(shape, dragGroup);
+                        canvas.addMarker(shape, MARKER_DRAGGING);
+                    });
+
+                    context.dragGroup = dragGroup;
+                }
+
+                var orientation = {
+                    x: 'M' + event.x + ', -10000 L' + event.x + ', 10000',
+                    y: 'M -10000, ' + event.y + ' L 10000, ' + event.y
+                };
+
+                line.attr({
+                    path: orientation[axis],
+                    display: ''
+                });
+
+                var opposite = {
+                    x: 'y',
+                    y: 'x'
+                };
+                var delta = {
+                    x: event.dx,
+                    y: event.dy
+                };
+                delta[opposite[context.axis]] = 0;
+
+                context.dragGroup.translate(delta.x, delta.y);
+            });
+
+            eventBus.on('spaceTool.cleanup', function(event) {
+
+                var context = event.context,
+                    shapes = context.movingShapes,
+                    line = context.line,
+                    dragGroup = context.dragGroup;
+
+                // remove dragging marker
+                forEach(shapes, function(e) {
+                    canvas.removeMarker(e, MARKER_DRAGGING);
+                });
+
+                if (dragGroup) {
+                    line.remove();
+                    dragGroup.remove();
+                }
+            });
+        }
+
+        SpaceToolVisuals.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles'];
+
+        module.exports = SpaceToolVisuals;
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Get Resize direction given axis + offset
+         * 
+         * @param {String}
+         *            axis (x|y)
+         * @param {Number}
+         *            offset
+         * 
+         * @return {String} (e|w|n|s)
+         */
+        function getDirection(axis, offset) {
+
+            if (axis === 'x') {
+                if (offset > 0) {
+                    return 'e';
+                }
+
+                if (offset < 0) {
+                    return 'w';
+                }
+            }
+
+            if (axis === 'y') {
+                if (offset > 0) {
+                    return 's';
+                }
+
+                if (offset < 0) {
+                    return 'n';
+                }
+            }
+
+            return null;
+        }
+
+        module.exports.getDirection = getDirection;
+
+        /**
+         * Resize the given bounds by the specified delta from a given anchor point.
+         * 
+         * @param {Bounds}
+         *            bounds the bounding box that should be resized
+         * @param {String}
+         *            direction in which the element is resized (n, s, e, w)
+         * @param {Point}
+         *            delta of the resize operation
+         * 
+         * @return {Bounds} resized bounding box
+         */
+        module.exports.resizeBounds = function(bounds, direction, delta) {
+
+            var dx = delta.x,
+                dy = delta.y;
+
+            switch (direction) {
+
+                case 'n':
+                    return {
+                        x: bounds.x,
+                        y: bounds.y + dy,
+                        width: bounds.width,
+                        height: bounds.height - dy
+                    };
+
+                case 's':
+                    return {
+                        x: bounds.x,
+                        y: bounds.y,
+                        width: bounds.width,
+                        height: bounds.height + dy
+                    };
+
+                case 'w':
+                    return {
+                        x: bounds.x + dx,
+                        y: bounds.y,
+                        width: bounds.width - dx,
+                        height: bounds.height
+                    };
+
+                case 'e':
+                    return {
+                        x: bounds.x,
+                        y: bounds.y,
+                        width: bounds.width + dx,
+                        height: bounds.height
+                    };
+
+                default:
+                    throw new Error('unrecognized direction: ' + direction);
+            }
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['spaceToolVisuals'],
+            __depends__: [require('../dragging'), require('../modeling'), require('../rules')],
+            spaceTool: ['type', require('./SpaceTool')],
+            spaceToolVisuals: ['type', require('./SpaceToolVisuals')]
+        };
+
+    }, {
+        "../dragging": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\dragging\\index.js",
+        "../modeling": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\modeling\\index.js",
+        "../rules": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\rules\\index.js",
+        "./SpaceTool": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceTool.js",
+        "./SpaceToolVisuals": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\space-tool\\SpaceToolVisuals.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\tooltips\\Tooltips.js": [function(require, module, exports) {
+        'use strict';
+
+        var isString = require('lodash/lang/isString'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach'),
+            debounce = require('lodash/function/debounce');
+
+        var domify = require('min-dom/lib/domify'),
+            domAttr = require('min-dom/lib/attr'),
+            domClasses = require('min-dom/lib/classes'),
+            domRemove = require('min-dom/lib/remove'),
+            domDelegate = require('min-dom/lib/delegate');
+
+
+        // document wide unique tooltip ids
+        var ids = new(require('../../util/IdGenerator'))('tt');
+
+
+        function createRoot(parent) {
+            var root = domify('<div class="djs-tooltip-container" style="position: absolute; width: 0; height: 0;" />');
+            parent.insertBefore(root, parent.firstChild);
+
+            return root;
+        }
+
+
+        function setPosition(el, x, y) {
+            assign(el.style, {
+                left: x + 'px',
+                top: y + 'px'
+            });
+        }
+
+        function setVisible(el, visible) {
+            el.style.display = visible === false ? 'none' : '';
+        }
+
+
+        var tooltipClass = 'djs-tooltip',
+            tooltipSelector = '.' + tooltipClass;
+
+        /**
+         * A service that allows users to render tool tips on the diagram.
+         * 
+         * The tooltip service will take care of updating the tooltip positioning during
+         * navigation + zooming.
+         * 
+         * @example
+         * 
+         * ```javascript
+         *  // add a pink badge on the top left of the shape tooltips.add({ position: {
+         * x: 50, y: 100 }, html: '<div style="width: 10px; background: fuchsia; color:
+         * white;">0</div>' });
+         *  // or with optional life span tooltips.add({ position: { top: -5, left: -5 },
+         * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>',
+         * ttl: 2000 });
+         *  // remove a tool tip var id = tooltips.add(...); tooltips.remove(id); ```
+         * 
+         * @param {Object}
+         *            config
+         * @param {EventBus}
+         *            eventBus
+         * @param {Canvas}
+         *            canvas
+         */
+        function Tooltips(config, eventBus, canvas) {
+
+            this._eventBus = eventBus;
+            this._canvas = canvas;
+
+            this._ids = ids;
+
+            this._tooltipDefaults = {
+                show: {
+                    minZoom: 0.7,
+                    maxZoom: 5.0
+                }
+            };
+
+            /**
+             * Mapping tooltipId -> tooltip
+             */
+            this._tooltips = {};
+
+            // root html element for all tooltips
+            this._tooltipRoot = createRoot(canvas.getContainer());
+
+
+            var self = this;
+
+            domDelegate.bind(this._tooltipRoot, tooltipSelector, 'mousedown', function(event) {
+                event.stopPropagation();
+            });
+
+            domDelegate.bind(this._tooltipRoot, tooltipSelector, 'mouseover', function(event) {
+                self.trigger('mouseover', event);
+            });
+
+            domDelegate.bind(this._tooltipRoot, tooltipSelector, 'mouseout', function(event) {
+                self.trigger('mouseout', event);
+            });
+
+            this._init(config);
+        }
+
+
+        Tooltips.$inject = ['config.tooltips', 'eventBus', 'canvas'];
+
+        module.exports = Tooltips;
+
+
+        /**
+         * Adds a HTML tooltip to the diagram
+         * 
+         * @param {Object}
+         *            tooltip the tooltip configuration
+         * 
+         * @param {String|DOMElement}
+         *            tooltip.html html element to use as an tooltip
+         * @param {Object}
+         *            [tooltip.show] show configuration
+         * @param {Number}
+         *            [tooltip.show.minZoom] minimal zoom level to show the tooltip
+         * @param {Number}
+         *            [tooltip.show.maxZoom] maximum zoom level to show the tooltip
+         * @param {Object}
+         *            tooltip.position where to attach the tooltip
+         * @param {Number}
+         *            [tooltip.position.left] relative to element bbox left attachment
+         * @param {Number}
+         *            [tooltip.position.top] relative to element bbox top attachment
+         * @param {Number}
+         *            [tooltip.position.bottom] relative to element bbox bottom
+         *            attachment
+         * @param {Number}
+         *            [tooltip.position.right] relative to element bbox right attachment
+         * @param {Number}
+         *            [tooltip.timeout=-1]
+         * 
+         * @return {String} id that may be used to reference the tooltip for update or
+         *         removal
+         */
+        Tooltips.prototype.add = function(tooltip) {
+
+            if (!tooltip.position) {
+                throw new Error('must specifiy tooltip position');
+            }
+
+            if (!tooltip.html) {
+                throw new Error('must specifiy tooltip html');
+            }
+
+            var id = this._ids.next();
+
+            tooltip = assign({}, this._tooltipDefaults, tooltip, {
+                id: id
+            });
+
+            this._addTooltip(tooltip);
+
+            if (tooltip.timeout) {
+                this.setTimeout(tooltip);
+            }
+
+            return id;
+        };
+
+        Tooltips.prototype.trigger = function(action, event) {
+
+            var node = event.delegateTarget || event.target;
+
+            var tooltip = this.get(domAttr(node, 'data-tooltip-id'));
+
+            if (!tooltip) {
+                return;
+            }
+
+            if (action === 'mouseover' && tooltip.timeout) {
+                this.clearTimeout(tooltip);
+            }
+
+            if (action === 'mouseout' && tooltip.timeout) {
+                // cut timeout after mouse out
+                tooltip.timeout = 1000;
+
+                this.setTimeout(tooltip);
+            }
+
+            console.log('mouse leave', event);
+        };
+
+        /**
+         * Get a tooltip with the given id
+         * 
+         * @param {String}
+         *            id
+         */
+        Tooltips.prototype.get = function(id) {
+
+            if (typeof id !== 'string') {
+                id = id.id;
+            }
+
+            return this._tooltips[id];
+        };
+
+        Tooltips.prototype.clearTimeout = function(tooltip) {
+
+            tooltip = this.get(tooltip);
+
+            if (!tooltip) {
+                return;
+            }
+
+            var removeTimer = tooltip.removeTimer;
+
+            if (removeTimer) {
+                clearTimeout(removeTimer);
+                tooltip.removeTimer = null;
+            }
+        };
+
+        Tooltips.prototype.setTimeout = function(tooltip) {
+
+            tooltip = this.get(tooltip);
+
+            if (!tooltip) {
+                return;
+            }
+
+            this.clearTimeout(tooltip);
+
+            var self = this;
+
+            tooltip.removeTimer = setTimeout(function() {
+                self.remove(tooltip);
+            }, tooltip.timeout);
+        };
+
+        /**
+         * Remove an tooltip with the given id
+         * 
+         * @param {String}
+         *            id
+         */
+        Tooltips.prototype.remove = function(id) {
+
+            var tooltip = this.get(id);
+
+            if (tooltip) {
+                domRemove(tooltip.html);
+                domRemove(tooltip.htmlContainer);
+
+                delete tooltip.htmlContainer;
+
+                delete this._tooltips[tooltip.id];
+            }
+        };
+
+
+        Tooltips.prototype.show = function() {
+            setVisible(this._tooltipRoot);
+        };
+
+
+        Tooltips.prototype.hide = function() {
+            setVisible(this._tooltipRoot, false);
+        };
+
+
+        Tooltips.prototype._updateRoot = function(viewbox) {
+            var a = viewbox.scale || 1;
+            var d = viewbox.scale || 1;
+
+            var matrix = 'matrix(' + a + ',0,0,' + d + ',' + (-1 * viewbox.x * a) + ',' + (-1 * viewbox.y * d) + ')';
+
+            this._tooltipRoot.style.transform = matrix;
+            this._tooltipRoot.style['-ms-transform'] = matrix;
+        };
+
+
+        Tooltips.prototype._addTooltip = function(tooltip) {
+
+            var id = tooltip.id,
+                html = tooltip.html,
+                htmlContainer,
+                tooltipRoot = this._tooltipRoot;
+
+            // unwrap jquery (for those who need it)
+            if (html.get) {
+                html = html.get(0);
+            }
+
+            // create proper html elements from
+            // tooltip HTML strings
+            if (isString(html)) {
+                html = domify(html);
+            }
+
+            htmlContainer = domify('<div data-tooltip-id="' + id + '" class="' + tooltipClass + '" style="position: absolute">');
+
+            htmlContainer.appendChild(html);
+
+            if (tooltip.type) {
+                domClasses(htmlContainer).add('djs-tooltip-' + tooltip.type);
+            }
+
+            if (tooltip.className) {
+                domClasses(htmlContainer).add(tooltip.className);
+            }
+
+            tooltip.htmlContainer = htmlContainer;
+
+            tooltipRoot.appendChild(htmlContainer);
+
+            this._tooltips[id] = tooltip;
+
+            this._updateTooltip(tooltip);
+        };
+
+
+        Tooltips.prototype._updateTooltip = function(tooltip) {
+
+            var position = tooltip.position,
+                htmlContainer = tooltip.htmlContainer;
+
+            // update overlay html based on tooltip x, y
+
+            setPosition(htmlContainer, position.x, position.y);
+        };
+
+
+        Tooltips.prototype._updateTooltipVisibilty = function(viewbox) {
+
+            forEach(this._tooltips, function(tooltip) {
+                var show = tooltip.show,
+                    htmlContainer = tooltip.htmlContainer,
+                    visible = true;
+
+                if (show) {
+                    if (show.minZoom > viewbox.scale ||
+                        show.maxZoom < viewbox.scale) {
+                        visible = false;
+                    }
+
+                    setVisible(htmlContainer, visible);
+                }
+            });
+        };
+
+        Tooltips.prototype._init = function(config) {
+
+            var self = this;
+
+
+            // scroll/zoom integration
+
+            var updateViewbox = function(viewbox) {
+                self._updateRoot(viewbox);
+                self._updateTooltipVisibilty(viewbox);
+
+                self.show();
+            };
+
+            if (!config || config.deferUpdate !== false) {
+                updateViewbox = debounce(updateViewbox, 300);
+            }
+
+            this._eventBus.on('canvas.viewbox.changed', function(event) {
+                self.hide();
+                updateViewbox(event.viewbox);
+            });
+        };
+
+    }, {
+        "../../util/IdGenerator": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\IdGenerator.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/function/debounce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\debounce.js",
+        "lodash/lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "min-dom/lib/attr": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\attr.js",
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js",
+        "min-dom/lib/delegate": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\delegate.js",
+        "min-dom/lib/domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js",
+        "min-dom/lib/remove": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\remove.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\tooltips\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['tooltips'],
+            tooltips: ['type', require('./Tooltips')]
+        };
+    }, {
+        "./Tooltips": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\tooltips\\Tooltips.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\TouchFix.js": [function(require, module, exports) {
+        'use strict';
+
+        function TouchFix(canvas, eventBus) {
+
+            var self = this;
+
+            eventBus.on('canvas.init', function(e) {
+                self.addBBoxMarker(e.svg);
+            });
+        }
+
+        TouchFix.$inject = ['canvas', 'eventBus'];
+
+        module.exports = TouchFix;
+
+
+        /**
+         * Safari mobile (iOS 7) does not fire touchstart event in <SVG> element if
+         * there is no shape between 0,0 and viewport elements origin.
+         * 
+         * So touchstart event is only fired when the <g class="viewport"> element was
+         * hit. Putting an element over and below the 'viewport' fixes that behavior.
+         */
+        TouchFix.prototype.addBBoxMarker = function(paper) {
+
+            var markerStyle = {
+                fill: 'none',
+                class: 'outer-bound-marker'
+            };
+
+            paper.rect(-10000, -10000, 10, 10).attr(markerStyle);
+            paper.rect(10000, 10000, 10, 10).attr(markerStyle);
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\TouchInteractionEvents.js": [function(require, module, exports) {
+        'use strict';
+
+        var forEach = require('lodash/collection/forEach'),
+            domEvent = require('min-dom/lib/event'),
+            domClosest = require('min-dom/lib/closest'),
+            Hammer = require('hammerjs'),
+            Snap = require('../../../vendor/snapsvg'),
+            Event = require('../../util/Event');
+
+        var MIN_ZOOM = 0.2,
+            MAX_ZOOM = 4;
+
+        var mouseEvents = [
+            'mousedown',
+            'mouseup',
+            'mouseover',
+            'mouseout',
+            'click',
+            'dblclick'
+        ];
+
+        function log() {
+            if (false) {
+                console.log.apply(console, arguments);
+            }
+        }
+
+        function get(service, injector) {
+            try {
+                return injector.get(service);
+            } catch (e) {
+                return null;
+            }
+        }
+
+        function createTouchRecognizer(node) {
+
+            function stopEvent(event) {
+                Event.stopEvent(event, true);
+            }
+
+            function stopMouse(event) {
+
+                forEach(mouseEvents, function(e) {
+                    domEvent.bind(node, e, stopEvent, true);
+                });
+            }
+
+            function allowMouse(event) {
+                setTimeout(function() {
+                    forEach(mouseEvents, function(e) {
+                        domEvent.unbind(node, e, stopEvent, true);
+                    });
+                }, 500);
+            }
+
+            domEvent.bind(node, 'touchstart', stopMouse, true);
+            domEvent.bind(node, 'touchend', allowMouse, true);
+            domEvent.bind(node, 'touchcancel', allowMouse, true);
+
+            // A touch event recognizer that handles
+            // touch events only (we know, we can already handle
+            // mouse events out of the box)
+
+            var recognizer = new Hammer.Manager(node, {
+                inputClass: Hammer.TouchInput,
+                recognizers: []
+            });
+
+
+            var tap = new Hammer.Tap();
+            var pan = new Hammer.Pan({
+                threshold: 10
+            });
+            var press = new Hammer.Press();
+            var pinch = new Hammer.Pinch();
+
+            var doubleTap = new Hammer.Tap({
+                event: 'doubletap',
+                taps: 2
+            });
+
+            pinch.requireFailure(pan);
+            pinch.requireFailure(press);
+
+            recognizer.add([pan, press, pinch, doubleTap, tap]);
+
+            recognizer.reset = function(force) {
+                var recognizers = this.recognizers,
+                    session = this.session;
+
+                if (session.stopped) {
+                    return;
+                }
+
+                log('recognizer', 'stop');
+
+                recognizer.stop(force);
+
+                setTimeout(function() {
+                    var i, r;
+
+                    log('recognizer', 'reset');
+                    for (i = 0; !!(r = recognizers[i]); i++) {
+                        r.reset();
+                        r.state = 8; // FAILED STATE
+                    }
+
+                    session.curRecognizer = null;
+                }, 0);
+            };
+
+            recognizer.on('hammer.input', function(event) {
+                if (event.srcEvent.defaultPrevented) {
+                    recognizer.reset(true);
+                }
+            });
+
+            return recognizer;
+        }
+
+        /**
+         * A plugin that provides touch events for elements.
+         * 
+         * @param {EventBus}
+         *            eventBus
+         * @param {InteractionEvents}
+         *            interactionEvents
+         */
+        function TouchInteractionEvents(injector, canvas, eventBus, elementRegistry, interactionEvents, snap) {
+
+            // optional integrations
+            var dragging = get('dragging', injector),
+                move = get('move', injector),
+                contextPad = get('contextPad', injector),
+                palette = get('palette', injector);
+
+            // the touch recognizer
+            var recognizer;
+
+            function handler(type) {
+
+                return function(event) {
+                    log('element', type, event);
+
+                    interactionEvents.fire(type, event);
+                };
+            }
+
+            function getGfx(target) {
+                var node = domClosest(target, 'svg, .djs-element', true);
+                return node && new Snap(node);
+            }
+
+            function initEvents(svg) {
+
+                // touch recognizer
+                recognizer = createTouchRecognizer(svg);
+
+                recognizer.on('doubletap', handler('element.dblclick'));
+
+                recognizer.on('tap', handler('element.click'));
+
+                function startGrabCanvas(event) {
+
+                    log('canvas', 'grab start');
+
+                    var lx = 0,
+                        ly = 0;
+
+                    function update(e) {
+
+                        var dx = e.deltaX - lx,
+                            dy = e.deltaY - ly;
+
+                        canvas.scroll({
+                            dx: dx,
+                            dy: dy
+                        });
+
+                        lx = e.deltaX;
+                        ly = e.deltaY;
+                    }
+
+                    function end(e) {
+                        recognizer.off('panmove', update);
+                        recognizer.off('panend', end);
+                        recognizer.off('pancancel', end);
+
+                        log('canvas', 'grab end');
+                    }
+
+                    recognizer.on('panmove', update);
+                    recognizer.on('panend', end);
+                    recognizer.on('pancancel', end);
+                }
+
+                function startGrab(event) {
+
+                    var gfx = getGfx(event.target),
+                        element = gfx && elementRegistry.get(gfx);
+
+                    // recognizer
+                    if (move && canvas.getRootElement() !== element) {
+                        log('element', 'move start', element, event, true);
+                        return move.start(event, element, true);
+                    } else {
+                        startGrabCanvas(event);
+                    }
+                }
+
+                function startZoom(e) {
+
+                    log('canvas', 'zoom start');
+
+                    var zoom = canvas.zoom(),
+                        mid = e.center;
+
+                    function update(e) {
+
+                        var ratio = 1 - (1 - e.scale) / 1.50,
+                            newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ratio * zoom));
+
+                        canvas.zoom(newZoom, mid);
+
+                        Event.stopEvent(e, true);
+                    }
+
+                    function end(e) {
+                        recognizer.off('pinchmove', update);
+                        recognizer.off('pinchend', end);
+                        recognizer.off('pinchcancel', end);
+
+                        recognizer.reset(true);
+
+                        log('canvas', 'zoom end');
+                    }
+
+                    recognizer.on('pinchmove', update);
+                    recognizer.on('pinchend', end);
+                    recognizer.on('pinchcancel', end);
+                }
+
+                recognizer.on('panstart', startGrab);
+                recognizer.on('press', startGrab);
+
+                recognizer.on('pinchstart', startZoom);
+            }
+
+            if (dragging) {
+
+                // simulate hover during dragging
+                eventBus.on('drag.move', function(event) {
+
+                    var position = Event.toPoint(event.originalEvent);
+
+                    var node = document.elementFromPoint(position.x, position.y),
+                        gfx = getGfx(node),
+                        element = gfx && elementRegistry.get(gfx);
+
+                    if (element !== event.hover) {
+                        if (event.hover) {
+                            dragging.out(event);
+                        }
+
+                        if (element) {
+                            dragging.hover({
+                                element: element,
+                                gfx: gfx
+                            });
+
+                            event.hover = element;
+                            event.hoverGfx = gfx;
+                        }
+                    }
+                });
+            }
+
+            if (contextPad) {
+
+                eventBus.on('contextPad.create', function(event) {
+                    var node = event.pad.html;
+
+                    // touch recognizer
+                    var padRecognizer = createTouchRecognizer(node);
+
+                    padRecognizer.on('panstart', function(event) {
+                        log('context-pad', 'panstart', event);
+                        contextPad.trigger('dragstart', event, true);
+                    });
+
+                    padRecognizer.on('press', function(event) {
+                        log('context-pad', 'press', event);
+                        contextPad.trigger('dragstart', event, true);
+                    });
+
+                    padRecognizer.on('tap', function(event) {
+                        log('context-pad', 'tap', event);
+                        contextPad.trigger('click', event);
+                    });
+                });
+            }
+
+            if (palette) {
+                eventBus.on('palette.create', function(event) {
+                    var node = event.html;
+
+                    // touch recognizer
+                    var padRecognizer = createTouchRecognizer(node);
+
+                    padRecognizer.on('panstart', function(event) {
+                        log('palette', 'panstart', event);
+                        palette.trigger('dragstart', event, true);
+                    });
+
+                    padRecognizer.on('press', function(event) {
+                        log('palette', 'press', event);
+                        palette.trigger('dragstart', event, true);
+                    });
+
+                    padRecognizer.on('tap', function(event) {
+                        log('palette', 'tap', event);
+                        palette.trigger('click', event);
+                    });
+                });
+            }
+
+            eventBus.on('canvas.init', function(event) {
+                initEvents(event.svg.node);
+            });
+        }
+
+
+        TouchInteractionEvents.$inject = [
+            'injector',
+            'canvas',
+            'eventBus',
+            'elementRegistry',
+            'interactionEvents',
+            'touchFix'
+        ];
+
+        module.exports = TouchInteractionEvents;
+    }, {
+        "../../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "../../util/Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "hammerjs": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\hammerjs\\hammer.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "min-dom/lib/closest": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\closest.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../interaction-events')],
+            __init__: ['touchInteractionEvents'],
+            touchInteractionEvents: ['type', require('./TouchInteractionEvents')],
+            touchFix: ['type', require('./TouchFix')]
+        };
+    }, {
+        "../interaction-events": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\interaction-events\\index.js",
+        "./TouchFix": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\TouchFix.js",
+        "./TouchInteractionEvents": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\TouchInteractionEvents.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\BaseLayouter.js": [function(require, module, exports) {
+        'use strict';
+
+        var LayoutUtil = require('./LayoutUtil');
+
+
+        /**
+         * A base connection layouter implementation that layouts the connection by
+         * directly connecting mid(source) + mid(target).
+         */
+        function BaseLayouter() {}
+
+        module.exports = BaseLayouter;
+
+
+        /**
+         * Return the new layouted waypoints for the given connection.
+         * 
+         * @param {djs.model.Connection}
+         *            connection
+         * @param {Object}
+         *            hints
+         * @param {Boolean}
+         *            [hints.movedStart=false]
+         * @param {Boolean}
+         *            [hints.movedEnd=false]
+         * 
+         * @return {Array<Point>} the layouted connection waypoints
+         */
+        BaseLayouter.prototype.layoutConnection = function(connection, hints) {
+            return [
+                LayoutUtil.getMidPoint(connection.source),
+                LayoutUtil.getMidPoint(connection.target)
+            ];
+        };
+
+    }, {
+        "./LayoutUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\CroppingConnectionDocking.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign');
+
+        var LayoutUtil = require('./LayoutUtil');
+
+
+        function dockingToPoint(docking) {
+            // use the dockings actual point and
+            // retain the original docking
+            return assign({
+                original: docking.point.original || docking.point
+            }, docking.actual);
+        }
+
+
+        /**
+         * A {@link ConnectionDocking} that crops connection waypoints based on the
+         * path(s) of the connection source and target.
+         * 
+         * @param {djs.core.ElementRegistry}
+         *            elementRegistry
+         */
+        function CroppingConnectionDocking(elementRegistry, renderer) {
+            this._elementRegistry = elementRegistry;
+            this._renderer = renderer;
+        }
+
+        CroppingConnectionDocking.$inject = ['elementRegistry', 'renderer'];
+
+        module.exports = CroppingConnectionDocking;
+
+
+        /**
+         * @inheritDoc ConnectionDocking#getCroppedWaypoints
+         */
+        CroppingConnectionDocking.prototype.getCroppedWaypoints = function(connection, source, target) {
+
+            source = source || connection.source;
+            target = target || connection.target;
+
+            var sourceDocking = this.getDockingPoint(connection, source, true),
+                targetDocking = this.getDockingPoint(connection, target);
+
+            var croppedWaypoints = connection.waypoints.slice(sourceDocking.idx + 1, targetDocking.idx);
+
+            croppedWaypoints.unshift(dockingToPoint(sourceDocking));
+            croppedWaypoints.push(dockingToPoint(targetDocking));
+
+            return croppedWaypoints;
+        };
+
+        /**
+         * Return the connection docking point on the specified shape
+         * 
+         * @inheritDoc ConnectionDocking#getDockingPoint
+         */
+        CroppingConnectionDocking.prototype.getDockingPoint = function(connection, shape, dockStart) {
+
+            var waypoints = connection.waypoints,
+                dockingIdx,
+                dockingPoint,
+                croppedPoint;
+
+            dockingIdx = dockStart ? 0 : waypoints.length - 1;
+            dockingPoint = waypoints[dockingIdx];
+
+            croppedPoint = this._getIntersection(shape, connection, dockStart);
+
+            return {
+                point: dockingPoint,
+                actual: croppedPoint || dockingPoint,
+                idx: dockingIdx
+            };
+        };
+
+
+        // //// helper methods ///////////////////////////////////////////////////
+
+        CroppingConnectionDocking.prototype._getIntersection = function(shape, connection, takeFirst) {
+
+            var shapePath = this._getShapePath(shape),
+                connectionPath = this._getConnectionPath(connection);
+
+            return LayoutUtil.getElementLineIntersection(shapePath, connectionPath, takeFirst);
+        };
+
+        CroppingConnectionDocking.prototype._getConnectionPath = function(connection) {
+            return this._renderer.getConnectionPath(connection);
+        };
+
+        CroppingConnectionDocking.prototype._getShapePath = function(shape) {
+            return this._renderer.getShapePath(shape);
+        };
+
+        CroppingConnectionDocking.prototype._getGfx = function(element) {
+            return this._elementRegistry.getGraphics(element);
+        };
+    }, {
+        "./LayoutUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            sortBy = require('lodash/collection/sortBy');
+
+        var Snap = require('../../vendor/snapsvg');
+
+        /**
+         * Returns whether two points are in a horizontal or vertical line.
+         * 
+         * @param {Point}
+         *            a
+         * @param {Point}
+         *            b
+         * 
+         * @return {String|Boolean} returns false if the points are not aligned or 'h|v'
+         *         if they are aligned horizontally / vertically.
+         */
+        function pointsAligned(a, b) {
+            switch (true) {
+                case a.x === b.x:
+                    return 'h';
+                case a.y === b.y:
+                    return 'v';
+            }
+
+            return false;
+        }
+
+        module.exports.pointsAligned = pointsAligned;
+
+
+        function roundPoint(point) {
+
+            return {
+                x: Math.round(point.x),
+                y: Math.round(point.y)
+            };
+        }
+
+        module.exports.roundPoint = roundPoint;
+
+
+        function pointsEqual(a, b) {
+            return a.x === b.x && a.y === b.y;
+        }
+
+        module.exports.pointsEqual = pointsEqual;
+
+
+        function pointDistance(a, b) {
+            return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
+        }
+
+        module.exports.pointDistance = pointDistance;
+
+
+        function asTRBL(bounds) {
+            return {
+                top: bounds.y,
+                right: bounds.x + (bounds.width || 0),
+                bottom: bounds.y + (bounds.height || 0),
+                left: bounds.x
+            };
+        }
+
+        module.exports.asTRBL = asTRBL;
+
+
+        function getMidPoint(bounds) {
+            return roundPoint({
+                x: bounds.x + bounds.width / 2,
+                y: bounds.y + bounds.height / 2
+            });
+        }
+
+        module.exports.getMidPoint = getMidPoint;
+
+
+        // //// orientation utils //////////////////////////////
+
+        function getOrientation(rect, reference, pointDistance) {
+
+            pointDistance = pointDistance || 0;
+
+            var rectOrientation = asTRBL(rect),
+                referenceOrientation = asTRBL(reference);
+
+            var top = rectOrientation.bottom + pointDistance <= referenceOrientation.top,
+                right = rectOrientation.left - pointDistance >= referenceOrientation.right,
+                bottom = rectOrientation.top - pointDistance >= referenceOrientation.bottom,
+                left = rectOrientation.right + pointDistance <= referenceOrientation.left;
+
+            var vertical = top ? 'top' : (bottom ? 'bottom' : null),
+                horizontal = left ? 'left' : (right ? 'right' : null);
+
+            if (horizontal && vertical) {
+                return vertical + '-' + horizontal;
+            } else
+            if (horizontal || vertical) {
+                return horizontal || vertical;
+            } else {
+                return 'intersect';
+            }
+        }
+
+        module.exports.getOrientation = getOrientation;
+
+
+        function hasAnyOrientation(rect, reference, pointDistance, locations) {
+
+            if (isArray(pointDistance)) {
+                locations = pointDistance;
+                pointDistance = 0;
+            }
+
+            var orientation = getOrientation(rect, reference, pointDistance);
+
+            return locations.indexOf(orientation) !== -1;
+        }
+
+        module.exports.hasAnyOrientation = hasAnyOrientation;
+
+
+        // //// intersection utils //////////////////////////////
+
+        function getElementLineIntersection(elementPath, linePath, cropStart) {
+
+            var intersections = getIntersections(elementPath, linePath);
+
+            // recognize intersections
+            // only one -> choose
+            // two close together -> choose first
+            // two or more distinct -> pull out appropriate one
+            // none -> ok (fallback to point itself)
+            if (intersections.length === 1) {
+                return roundPoint(intersections[0]);
+            } else if (intersections.length === 2 && pointDistance(intersections[0], intersections[1]) < 1) {
+                return roundPoint(intersections[0]);
+            } else if (intersections.length > 1) {
+
+                // sort by intersections based on connection segment +
+                // distance from start
+                intersections = sortBy(intersections, function(i) {
+                    var distance = Math.floor(i.t2 * 100) || 1;
+
+                    distance = 100 - distance;
+
+                    distance = (distance < 10 ? '0' : '') + distance;
+
+                    // create a sort string that makes sure we sort
+                    // line segment ASC + line segment position DESC (for cropStart)
+                    // line segment ASC + line segment position ASC (for cropEnd)
+                    return i.segment2 + '#' + distance;
+                });
+
+                return roundPoint(intersections[cropStart ? 0 : intersections.length - 1]);
+            }
+
+            return null;
+        }
+
+        module.exports.getElementLineIntersection = getElementLineIntersection;
+
+
+        function getIntersections(a, b) {
+            return Snap.path.intersection(a, b);
+        }
+
+        module.exports.getIntersections = getIntersections;
+    }, {
+        "../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "lodash/collection/sortBy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\sortBy.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\ManhattanLayout.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            find = require('lodash/collection/find');
+
+        var LayoutUtil = require('./LayoutUtil'),
+            Geometry = require('../util/Geometry');
+
+        var MIN_DISTANCE = 20;
+
+
+        /**
+         * Returns the mid points for a manhattan connection between two points.
+         * 
+         * @example
+         * 
+         * [a]----[x] | [x]--->[b]
+         * 
+         * @param {Point}
+         *            a
+         * @param {Point}
+         *            b
+         * @param {String}
+         *            directions
+         * 
+         * @return {Array<Point>}
+         */
+        module.exports.getMidPoints = function(a, b, directions) {
+
+            directions = directions || 'h:h';
+
+            var xmid, ymid;
+
+            // one point, next to a
+            if (directions === 'h:v') {
+                return [{
+                    x: b.x,
+                    y: a.y
+                }];
+            } else
+            // one point, above a
+            if (directions === 'v:h') {
+                return [{
+                    x: a.x,
+                    y: b.y
+                }];
+            } else
+            // vertical edge xmid
+            if (directions === 'h:h') {
+                xmid = Math.round((b.x - a.x) / 2 + a.x);
+
+                return [{
+                    x: xmid,
+                    y: a.y
+                }, {
+                    x: xmid,
+                    y: b.y
+                }];
+            } else
+            // horizontal edge ymid
+            if (directions === 'v:v') {
+                ymid = Math.round((b.y - a.y) / 2 + a.y);
+
+                return [{
+                    x: a.x,
+                    y: ymid
+                }, {
+                    x: b.x,
+                    y: ymid
+                }];
+            } else {
+                throw new Error(
+                    'unknown directions: <' + directions + '>: ' +
+                    'directions must be specified as {a direction}:{b direction} (direction in h|v)');
+            }
+        };
+
+
+        /**
+         * Create a connection between the two points according to the manhattan layout
+         * (only horizontal and vertical) edges.
+         * 
+         * @param {Point}
+         *            a
+         * @param {Point}
+         *            b
+         * 
+         * @param {String}
+         *            [directions='h:h'] specifies manhattan directions for each point
+         *            as {adirection}:{bdirection}. A directionfor a point is either `h`
+         *            (horizontal) or `v` (vertical)
+         * 
+         * @return {Array<Point>}
+         */
+        module.exports.connectPoints = function(a, b, directions) {
+
+            var points = [];
+
+            if (!LayoutUtil.pointsAligned(a, b)) {
+                points = this.getMidPoints(a, b, directions);
+            }
+
+            points.unshift(a);
+            points.push(b);
+
+            return points;
+        };
+
+
+        /**
+         * Connect two rectangles using a manhattan layouted connection.
+         * 
+         * @param {Bounds}
+         *            source source rectangle
+         * @param {Bounds}
+         *            target target rectangle
+         * @param {Point}
+         *            [start] source docking
+         * @param {Point}
+         *            [end] target docking
+         * 
+         * @return {Array<Point>} connection points
+         */
+        module.exports.connectRectangles = function(source, target, start, end, options) {
+
+            options = options || {};
+
+            var orientation = LayoutUtil.getOrientation(source, target, MIN_DISTANCE);
+
+            var directions = this.getDirections(source, target, options.preferVertical);
+
+            start = start || LayoutUtil.getMidPoint(source);
+            end = end || LayoutUtil.getMidPoint(target);
+
+            // overlapping elements
+            if (!directions) {
+                return;
+            }
+
+            if (directions === 'h:h') {
+
+                switch (orientation) {
+                    case 'top-right':
+                    case 'right':
+                    case 'bottom-right':
+                        start = {
+                            original: start,
+                            x: source.x,
+                            y: start.y
+                        };
+                        end = {
+                            original: end,
+                            x: target.x + target.width,
+                            y: end.y
+                        };
+                        break;
+                    case 'top-left':
+                    case 'left':
+                    case 'bottom-left':
+                        start = {
+                            original: start,
+                            x: source.x + source.width,
+                            y: start.y
+                        };
+                        end = {
+                            original: end,
+                            x: target.x,
+                            y: end.y
+                        };
+                        break;
+                }
+            }
+
+            if (directions === 'v:v') {
+
+                switch (orientation) {
+                    case 'top-left':
+                    case 'top':
+                    case 'top-right':
+                        start = {
+                            original: start,
+                            x: start.x,
+                            y: source.y + source.height
+                        };
+                        end = {
+                            original: end,
+                            x: end.x,
+                            y: target.y
+                        };
+                        break;
+                    case 'bottom-left':
+                    case 'bottom':
+                    case 'bottom-right':
+                        start = {
+                            original: start,
+                            x: start.x,
+                            y: source.y
+                        };
+                        end = {
+                            original: end,
+                            x: end.x,
+                            y: target.y + target.height
+                        };
+                        break;
+                }
+            }
+
+            return this.connectPoints(start, end, directions);
+        };
+
+        /**
+         * Repair the connection between two rectangles, of which one has been updated.
+         * 
+         * @param {Bounds}
+         *            source
+         * @param {Bounds}
+         *            target
+         * @param {Point}
+         *            [start]
+         * @param {Point}
+         *            [end]
+         * @param {Array
+         *            <Point>} waypoints
+         * @param {Object}
+         *            [hints]
+         * @param {Boolean}
+         *            hints.preferStraight
+         * @param {Boolean}
+         *            hints.preferVertical
+         * @param {Boolean}
+         *            hints.startChanged
+         * @param {Boolean}
+         *            hints.endChanged
+         * 
+         * @return {Array<Point>} repaired waypoints
+         */
+        module.exports.repairConnection = function(source, target, start, end, waypoints, hints) {
+
+            if (isArray(start)) {
+                waypoints = start;
+                hints = end;
+
+                start = LayoutUtil.getMidPoint(source);
+                end = LayoutUtil.getMidPoint(target);
+            }
+
+            hints = hints || {};
+
+
+            var repairedWaypoints;
+
+            // just layout non-existing or simple connections
+            // attempt to render straight lines, if required
+            if (!waypoints || waypoints.length < 3) {
+
+                if (hints.preferStraight) {
+                    // attempt to layout a straight line
+                    repairedWaypoints = this.layoutStraight(source, target, start, end, hints);
+                }
+            } else {
+                // check if we layout from start or end
+                if (hints.endChanged) {
+                    repairedWaypoints = this._repairConnectionSide(target, source, end, waypoints.slice().reverse());
+                    repairedWaypoints = repairedWaypoints && repairedWaypoints.reverse();
+                } else
+                if (hints.startChanged) {
+                    repairedWaypoints = this._repairConnectionSide(source, target, start, waypoints);
+                }
+                // or whether nothing seems to have changed
+                else {
+                    repairedWaypoints = waypoints;
+                }
+            }
+
+            // simply reconnect if nothing else worked
+            if (!repairedWaypoints) {
+                return this.connectRectangles(source, target, start, end, hints);
+            }
+
+            return repairedWaypoints;
+        };
+
+        function max(a, b) {
+            return Math.max(a, b);
+        }
+
+        function min(a, b) {
+            return Math.min(a, b);
+        }
+
+        function inRange(a, start, end) {
+            return a >= start && a <= end;
+        }
+
+        module.exports.layoutStraight = function(source, target, start, end, hints) {
+
+            var startX, endX, x,
+                startY, endY, y;
+
+            startX = max(source.x + 10, target.x + 10);
+            endX = min(source.x + source.width - 10, target.x + target.width - 10);
+
+            if (startX < endX) {
+
+                if (source.width === target.width) {
+
+                    if (hints.endChanged && inRange(end.x, startX, endX)) {
+                        x = end.x;
+                    } else
+                    if (inRange(start.x, startX, endX)) {
+                        x = start.x;
+                    }
+                }
+
+                if (x === undefined) {
+                    if (source.width < target.width && inRange(start.x, startX, endX)) {
+                        x = start.x;
+                    } else
+                    if (source.width > target.width && inRange(end.x, startX, endX)) {
+                        x = end.x;
+                    } else {
+                        x = (startX + endX) / 2;
+                    }
+                }
+            }
+
+            startY = max(source.y + 10, target.y + 10);
+            endY = min(source.y + source.height - 10, target.y + target.height - 10);
+
+            if (startY < endY) {
+
+                if (source.height === target.height) {
+                    if (hints.endChanged && inRange(end.y, startY, endY)) {
+                        y = end.y;
+                    } else
+                    if (inRange(start.y, startY, endY)) {
+                        y = start.y;
+                    }
+                }
+
+                if (y === undefined) {
+                    if (source.height <= target.height && inRange(start.y, startY, endY)) {
+                        y = start.y;
+                    } else
+                    if (target.height <= source.height && inRange(end.y, startY, endY)) {
+                        y = end.y;
+                    } else {
+                        y = (startY + endY) / 2;
+                    }
+                }
+            }
+
+            // cannot layout straight
+            if (x === undefined && y === undefined) {
+                return null;
+            }
+
+            return [{
+                x: x !== undefined ? x : start.x,
+                y: y !== undefined ? y : start.y
+            }, {
+                x: x !== undefined ? x : end.x,
+                y: y !== undefined ? y : end.y
+            }];
+        };
+
+
+        /**
+         * Repair a connection from one side that moved.
+         * 
+         * @param {Bounds}
+         *            moved
+         * @param {Bounds}
+         *            other
+         * @param {Point}
+         *            newDocking
+         * @param {Array
+         *            <Point>} points originalPoints from moved to other
+         * 
+         * @return {Array<Point>} the repaired points between the two rectangles
+         */
+        module.exports._repairConnectionSide = function(moved, other, newDocking, points) {
+
+            function needsRelayout(moved, other, points) {
+
+                if (points.length < 3) {
+                    return true;
+                }
+
+                if (points.length > 4) {
+                    return false;
+                }
+
+                // relayout if two points overlap
+                // this is most likely due to
+                return !!find(points, function(p, idx) {
+                    var q = points[idx - 1];
+
+                    return q && Geometry.distance(p, q) < 3;
+                });
+            }
+
+            function repairBendpoint(candidate, oldPeer, newPeer) {
+
+                var alignment = LayoutUtil.pointsAligned(oldPeer, candidate);
+
+                switch (alignment) {
+                    case 'v':
+                        // repair vertical alignment
+                        return {
+                            x: candidate.x,
+                            y: newPeer.y
+                        };
+                    case 'h':
+                        // repair horizontal alignment
+                        return {
+                            x: newPeer.x,
+                            y: candidate.y
+                        };
+                }
+
+                return {
+                    x: candidate.x,
+                    y: candidate.y
+                };
+            }
+
+            function removeOverlapping(points, a, b) {
+                var i;
+
+                for (i = points.length - 2; i !== 0; i--) {
+
+                    // intersects (?) break, remove all bendpoints up to this one and
+                    // relayout
+                    if (Geometry.pointInRect(points[i], a, MIN_DISTANCE) ||
+                        Geometry.pointInRect(points[i], b, MIN_DISTANCE)) {
+
+                        // return sliced old connection
+                        return points.slice(i);
+                    }
+                }
+
+                return points;
+            }
+
+
+            // (0) only repair what has layoutable bendpoints
+
+            // (1) if only one bendpoint and on shape moved onto other shapes axis
+            // (horizontally / vertically), relayout
+
+            if (needsRelayout(moved, other, points)) {
+                return null;
+            }
+
+            var oldDocking = points[0],
+                newPoints = points.slice(),
+                slicedPoints;
+
+            // (2) repair only last line segment and only if it was layouted before
+
+            newPoints[0] = newDocking;
+            newPoints[1] = repairBendpoint(newPoints[1], oldDocking, newDocking);
+
+
+            // (3) if shape intersects with any bendpoint after repair,
+            // remove all segments up to this bendpoint and repair from there
+
+            slicedPoints = removeOverlapping(newPoints, moved, other);
+            if (slicedPoints !== newPoints) {
+                return this._repairConnectionSide(moved, other, newDocking, slicedPoints);
+            }
+
+            return newPoints;
+        };
+
+        /**
+         * Returns the default manhattan directions connecting two rectangles.
+         * 
+         * @param {Bounds}
+         *            source
+         * @param {Bounds}
+         *            target
+         * @param {Boolean}
+         *            preferVertical
+         * 
+         * @return {String}
+         */
+        module.exports.getDirections = function(source, target, preferVertical) {
+            var orientation = LayoutUtil.getOrientation(source, target, MIN_DISTANCE);
+
+            switch (orientation) {
+                case 'intersect':
+                    return null;
+
+                case 'top':
+                case 'bottom':
+                    return 'v:v';
+
+                case 'left':
+                case 'right':
+                    return 'h:h';
+
+                default:
+                    return preferVertical ? 'v:v' : 'h:h';
+            }
+        };
+    }, {
+        "../util/Geometry": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Geometry.js",
+        "./LayoutUtil": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\layout\\LayoutUtil.js",
+        "lodash/collection/find": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\model\\index.js": [function(require, module, exports) {
+        'use strict';
+
+        var assign = require('lodash/object/assign'),
+            inherits = require('inherits');
+
+        var Refs = require('object-refs');
+
+        var parentRefs = new Refs({
+                name: 'children',
+                enumerable: true,
+                collection: true
+            }, {
+                name: 'parent'
+            }),
+            labelRefs = new Refs({
+                name: 'label',
+                enumerable: true
+            }, {
+                name: 'labelTarget'
+            }),
+            outgoingRefs = new Refs({
+                name: 'outgoing',
+                collection: true
+            }, {
+                name: 'source'
+            }),
+            incomingRefs = new Refs({
+                name: 'incoming',
+                collection: true
+            }, {
+                name: 'target'
+            });
+
+        /**
+         * @namespace djs.model
+         */
+
+        /**
+         * @memberOf djs.model
+         */
+
+        /**
+         * The basic graphical representation
+         * 
+         * @class
+         * 
+         * @abstract
+         */
+        function Base() {
+
+            /**
+             * The object that backs up the shape
+             * 
+             * @name Base#businessObject
+             * @type Object
+             */
+            Object.defineProperty(this, 'businessObject', {
+                writable: true
+            });
+
+            /**
+             * The parent shape
+             * 
+             * @name Base#parent
+             * @type Shape
+             */
+            parentRefs.bind(this, 'parent');
+
+            /**
+             * @name Base#label
+             * @type Label
+             */
+            labelRefs.bind(this, 'label');
+
+            /**
+             * The list of outgoing connections
+             * 
+             * @name Base#outgoing
+             * @type Array<Connection>
+             */
+            outgoingRefs.bind(this, 'outgoing');
+
+            /**
+             * The list of outgoing connections
+             * 
+             * @name Base#incoming
+             * @type Array<Connection>
+             */
+            incomingRefs.bind(this, 'incoming');
+        }
+
+
+        /**
+         * A graphical object
+         * 
+         * @class
+         * @constructor
+         * 
+         * @extends Base
+         */
+        function Shape() {
+            Base.call(this);
+
+            /**
+             * The list of children
+             * 
+             * @name Shape#children
+             * @type Array<Base>
+             */
+            parentRefs.bind(this, 'children');
+        }
+
+        inherits(Shape, Base);
+
+
+        /**
+         * A root graphical object
+         * 
+         * @class
+         * @constructor
+         * 
+         * @extends Shape
+         */
+        function Root() {
+            Shape.call(this);
+        }
+
+        inherits(Root, Shape);
+
+
+        /**
+         * A label for an element
+         * 
+         * @class
+         * @constructor
+         * 
+         * @extends Shape
+         */
+        function Label() {
+            Shape.call(this);
+
+            /**
+             * The labeled element
+             * 
+             * @name Label#labelTarget
+             * @type Base
+             */
+            labelRefs.bind(this, 'labelTarget');
+        }
+
+        inherits(Label, Shape);
+
+
+        /**
+         * A connection between two elements
+         * 
+         * @class
+         * @constructor
+         * 
+         * @extends Base
+         */
+        function Connection() {
+            Base.call(this);
+
+            /**
+             * The element this connection originates from
+             * 
+             * @name Connection#source
+             * @type Base
+             */
+            outgoingRefs.bind(this, 'source');
+
+            /**
+             * The element this connection points to
+             * 
+             * @name Connection#target
+             * @type Base
+             */
+            incomingRefs.bind(this, 'target');
+        }
+
+        inherits(Connection, Base);
+
+
+        var types = {
+            connection: Connection,
+            shape: Shape,
+            label: Label,
+            root: Root
+        };
+
+        /**
+         * Creates a new model element of the specified type
+         * 
+         * @method create
+         * 
+         * @example
+         * 
+         * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100
+         * }); var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height:
+         * 100 });
+         * 
+         * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 },
+         * {x: 210, y: 55 } ] });
+         * 
+         * @param {String}
+         *            type lower-cased model name
+         * @param {Object}
+         *            attrs attributes to initialize the new model instance with
+         * 
+         * @return {Base} the new model instance
+         */
+        module.exports.create = function(type, attrs) {
+            var Type = types[type];
+            if (!Type) {
+                throw new Error('unknown type: <' + type + '>');
+            }
+            return assign(new Type(), attrs);
+        };
+
+
+        module.exports.Base = Base;
+        module.exports.Root = Root;
+        module.exports.Shape = Shape;
+        module.exports.Connection = Connection;
+        module.exports.Label = Label;
+    }, {
+        "inherits": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "object-refs": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\movecanvas\\MoveCanvas.js": [function(require, module, exports) {
+        'use strict';
+
+        var Cursor = require('../../util/Cursor'),
+            ClickTrap = require('../../util/ClickTrap'),
+            domEvent = require('min-dom/lib/event'),
+            Event = require('../../util/Event');
+
+        function substract(p1, p2) {
+            return {
+                x: p1.x - p2.x,
+                y: p1.y - p2.y
+            };
+        }
+
+        function length(point) {
+            return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));
+        }
+
+
+        var THRESHOLD = 15;
+
+
+        function MoveCanvas(eventBus, canvas) {
+
+            var container = canvas._container,
+                context;
+
+
+            function handleMove(event) {
+
+                var start = context.start,
+                    position = Event.toPoint(event),
+                    delta = substract(position, start);
+
+                if (!context.dragging && length(delta) > THRESHOLD) {
+                    context.dragging = true;
+
+                    // prevent mouse click in this
+                    // interaction sequence
+                    ClickTrap.install();
+
+                    Cursor.set('move');
+                }
+
+                if (context.dragging) {
+
+                    var lastPosition = context.last || context.start;
+
+                    delta = substract(position, lastPosition);
+
+                    canvas.scroll({
+                        dx: delta.x,
+                        dy: delta.y
+                    });
+
+                    context.last = position;
+                }
+
+                // prevent select
+                event.preventDefault();
+            }
+
+
+            function handleEnd(event) {
+                domEvent.unbind(document, 'mousemove', handleMove);
+                domEvent.unbind(document, 'mouseup', handleEnd);
+
+                context = null;
+
+                Cursor.unset();
+
+                // prevent select
+                Event.stopEvent(event);
+            }
+
+            function handleStart(event) {
+
+                // reject non-left left mouse button or modifier key
+                if (event.button || event.ctrlKey || event.shiftKey || event.altKey) {
+                    return;
+                }
+
+                context = {
+                    start: Event.toPoint(event)
+                };
+
+                domEvent.bind(document, 'mousemove', handleMove);
+                domEvent.bind(document, 'mouseup', handleEnd);
+
+                // prevent select
+                Event.stopEvent(event);
+            }
+
+            domEvent.bind(container, 'mousedown', handleStart);
+        }
+
+
+        MoveCanvas.$inject = ['eventBus', 'canvas'];
+
+        module.exports = MoveCanvas;
+
+    }, {
+        "../../util/ClickTrap": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\ClickTrap.js",
+        "../../util/Cursor": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Cursor.js",
+        "../../util/Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\movecanvas\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['moveCanvas'],
+            moveCanvas: ['type', require('./MoveCanvas')]
+        };
+    }, {
+        "./MoveCanvas": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\movecanvas\\MoveCanvas.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\touch\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __depends__: [require('../../features/touch')]
+        };
+    }, {
+        "../../features/touch": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\features\\touch\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\zoomscroll\\ZoomScroll.js": [function(require, module, exports) {
+        'use strict';
+
+        var domEvent = require('min-dom/lib/event');
+
+        var hasPrimaryModifier = require('../../util/Mouse').hasPrimaryModifier,
+            hasSecondaryModifier = require('../../util/Mouse').hasSecondaryModifier;
+
+        var isMac = require('../../util/Platform').isMac;
+
+
+        function ZoomScroll(events, canvas) {
+               var $canvas = $( canvas.getContainer() ), //canvas.getContainer() 
+            $controls = $( '<div></div>' ),
+            $zoomOut = $( '<div><span class="glyphicon glyphicon-zoom-out"></span></div>' ),
+            $zoomIn = $( '<div><span class="glyphicon glyphicon-zoom-in"></span></div>' ),
+            $zoomFit= $( '<div><span class="glyphicon glyphicon-fullscreen"></span></div>' ),
+            zlevel = 1,
+            zstep = 0.2;
+
+        $canvas.append( $controls );
+        $controls.append( $zoomIn );
+        $controls.append( $zoomOut );
+        $controls.append( $zoomFit );
+
+        $controls.addClass( 'zoom-controls' );
+        $zoomOut.addClass( 'zoom zoom-out' );
+        $zoomIn.addClass( 'zoom zoom-in' );
+        $zoomFit.addClass( 'zoom zoom-fit' );
+
+        $zoomOut.attr( 'title', 'Zoom out' );
+        $zoomIn.attr( 'title', 'Zoom in' );
+        $zoomFit.attr( 'title', 'Fit to viewport' );
+
+        // set initial zoom level
+        //canvas.zoom( zlevel, 'auto' );
+
+        // update our zoom level on viewbox change
+        events.on( 'canvas.viewbox.changed', function( evt ) {
+            zlevel = evt.viewbox.scale;
+        });
+
+        // define click handlers for controls
+        $zoomFit.on( 'click', function() {
+            canvas.zoom( 'fit-viewport', 'auto' );
+        });
+
+        $zoomOut.on( 'click', function() {
+            zlevel = Math.max( zlevel - zstep, zstep );
+            canvas.zoom( zlevel, 'auto' );
+        });
+        
+        $zoomIn.on( 'click', function() {
+            zlevel = Math.min( zlevel + zstep, 7 );
+            canvas.zoom( zlevel, 'auto' );
+        });
+        
+        $(".TCS").click(function() {
+               console.log($(this).data("stuff"));
+               var modelElements = $(this).data("stuff").modelElements;
+               var modelName = $(this).data("model").name;
+               var hElements = [];
+               modelElements.forEach(function(mElement){
+                       if(hElements.indexOf(mElement.elementID)==-1){
+                               hElements.push(mElement.elementID);
+                       }
+               });
+               highlightPath(hElements);
+        });
+        
+        function highlightPath(hElements){
+               clear();
+            var elementRegistry = canvas._elementRegistry;
+            //console.log(elementRegistry);
+            hElements.forEach(function(hElement){
+               try{
+               //console.log(hElement);
+               var activityShape = elementRegistry.get(hElement);
+                var outgoing = activityShape.incoming;
+                
+                if (canvas.hasMarker(hElement, 'highlight')) {
+                       canvas.removeMarker(hElement, 'highlight');
+                       outgoing.forEach(function(flow){
+                        var outgoingGfx = elementRegistry.getGraphics(flow.id);
+                        if(hElements.indexOf(flow.id)!=-1){
+                               outgoingGfx.select('path').attr({stroke: 'black'});
+                        }
+                    });
+                } else {
+                       canvas.addMarker(hElement, 'highlight');
+                       outgoing.forEach(function(flow){
+                        var outgoingGfx = elementRegistry.getGraphics(flow.id);
+                        if(hElements.indexOf(flow.id)!=-1){
+                               outgoingGfx.select('path').attr({stroke: 'blue'});
+                        }
+                    });
+                }
+               }catch(err){
+                       //console.log(err);
+               }
+                
+            });
+        }
+        
+        function clear() {
+               var elementRegistry = canvas._elementRegistry;
+               elementRegistry.forEach(function(hElement){
+                       try {
+                               canvas.removeMarker(hElement, 'highlight');
+                               var outgoing = hElement.incoming;
+                               outgoing.forEach(function(flow){
+                           var outgoingGfx = elementRegistry.getGraphics(flow.id);
+                           outgoingGfx.select('path').attr({stroke: 'black'});
+                       });
+                       }catch(err){
+                               
+                       }
+               });
+        }
+        
+        //console.log('endzoom');
+               
+               
+            var RANGE = {
+                min: 0.2,
+                max: 4
+            };
+
+            function cap(scale) {
+                return Math.max(RANGE.min, Math.min(RANGE.max, scale));
+            }
+
+            function reset() {
+                canvas.zoom('fit-viewport');
+            }
+
+            function zoom(direction, position) {
+
+                var currentZoom = canvas.zoom();
+                var factor = Math.pow(1 + Math.abs(direction), direction > 0 ? 1 : -1);
+
+                canvas.zoom(cap(currentZoom * factor), position);
+            }
+
+            function scroll(delta) {
+                canvas.scroll(delta);
+            }
+
+            function init(element) {
+
+                domEvent.bind(element, 'wheel', function(event) {/*
+
+                    event.preventDefault();
+
+                    // mouse-event: SELECTION_KEY
+                    // mouse-event: AND_KEY
+                    var isVerticalScroll = hasPrimaryModifier(event),
+                        isHorizontalScroll = hasSecondaryModifier(event);
+
+                    var factor;
+
+                    if (isVerticalScroll || isHorizontalScroll) {
+
+                        if (isMac) {
+                            factor = event.deltaMode === 0 ? 1.25 : 50;
+                        } else {
+                            factor = event.deltaMode === 0 ? 1 / 40 : 1 / 2;
+                        }
+
+                        var delta = {};
+
+                        if (isHorizontalScroll) {
+                            delta.dx = (factor * (event.deltaX || event.deltaY));
+                        } else {
+                            delta.dy = (factor * event.deltaY);
+                        }
+
+                        scroll(delta);
+                    } else {
+                        factor = (event.deltaMode === 0 ? 1 / 40 : 1 / 2);
+
+                        var elementRect = element.getBoundingClientRect();
+
+                        var offset = {
+                            x: event.clientX - elementRect.left,
+                            y: event.clientY - elementRect.top
+                        };
+
+                        // zoom in relative to diagram {x,y} coordinates
+                        zoom(event.deltaY * factor / (-5), offset);
+                    }
+                */});
+            }
+
+            events.on('canvas.init', function(e) {
+                init(canvas._container);
+            });
+
+            // API
+            this.zoom = zoom;
+            this.reset = reset;
+        }
+
+
+        ZoomScroll.$inject = ['eventBus', 'canvas'];
+
+        module.exports = ZoomScroll;
+
+
+    }, {
+        "../../util/Mouse": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js",
+        "../../util/Platform": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Platform.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\zoomscroll\\index.js": [function(require, module, exports) {
+        module.exports = {
+            __init__: ['zoomScroll'],
+            zoomScroll: ['type', require('./ZoomScroll')]
+        };
+    }, {
+        "./ZoomScroll": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\navigation\\zoomscroll\\ZoomScroll.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\ClickTrap.js": [function(require, module, exports) {
+        'use strict';
+
+        var domEvent = require('min-dom/lib/event'),
+            stopEvent = require('./Event').stopEvent;
+
+        function trap(event) {
+            stopEvent(event);
+
+            toggle(false);
+        }
+
+        function toggle(active) {
+            domEvent[active ? 'bind' : 'unbind'](document.body, 'click', trap, true);
+        }
+
+        /**
+         * Installs a click trap that prevents a ghost click following a dragging
+         * operation.
+         * 
+         * @return {Function} a function to immediately remove the installed trap.
+         */
+        function install() {
+
+            toggle(true);
+
+            return function() {
+                toggle(false);
+            };
+        }
+
+        module.exports.install = install;
+    }, {
+        "./Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "min-dom/lib/event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Collections.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Failsafe remove an element from a collection
+         * 
+         * @param {Array
+         *            <Object>} [collection]
+         * @param {Object}
+         *            [element]
+         * 
+         * @return {Object} the element that got removed or undefined
+         */
+        module.exports.remove = function(collection, element) {
+
+            if (!collection || !element) {
+                return;
+            }
+
+            var idx = collection.indexOf(element);
+            if (idx === -1) {
+                return;
+            }
+
+            collection.splice(idx, 1);
+
+            return element;
+        };
+
+        /**
+         * Fail save add an element to the given connection, ensuring it does not yet
+         * exist.
+         * 
+         * @param {Array
+         *            <Object>} collection
+         * @param {Object}
+         *            element
+         * @param {Number}
+         *            idx
+         */
+        module.exports.add = function(collection, element, idx) {
+
+            if (!collection || !element) {
+                return;
+            }
+
+            if (isNaN(idx)) {
+                idx = -1;
+            }
+
+            var currentIdx = collection.indexOf(element);
+
+            if (currentIdx !== -1) {
+
+                if (currentIdx === idx) {
+                    // nothing to do, position has not changed
+                    return;
+                } else {
+
+                    if (idx !== -1) {
+                        // remove from current position
+                        collection.splice(currentIdx, 1);
+                    } else {
+                        // already exists in collection
+                        return;
+                    }
+                }
+            }
+
+            if (idx !== -1) {
+                // insert at specified position
+                collection.splice(idx, 0, element);
+            } else {
+                // push to end
+                collection.push(element);
+            }
+        };
+
+
+        /**
+         * Fail get the index of an element in a collection.
+         * 
+         * @param {Array
+         *            <Object>} collection
+         * @param {Object}
+         *            element
+         * 
+         * @return {Number} the index or -1 if collection or element do not exist or the
+         *         element is not contained.
+         */
+        module.exports.indexOf = function(collection, element) {
+
+            if (!collection || !element) {
+                return -1;
+            }
+
+            return collection.indexOf(element);
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Cursor.js": [function(require, module, exports) {
+        'use strict';
+
+        var domClasses = require('min-dom/lib/classes');
+
+        var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/;
+
+
+        module.exports.set = function(mode) {
+            var classes = domClasses(document.body);
+
+            classes.removeMatching(CURSOR_CLS_PATTERN);
+
+            if (mode) {
+                classes.add('djs-cursor-' + mode);
+            }
+        };
+
+        module.exports.unset = function() {
+            this.set(null);
+        };
+    }, {
+        "min-dom/lib/classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Elements.js": [function(require, module, exports) {
+        'use strict';
+
+        var isArray = require('lodash/lang/isArray'),
+            isNumber = require('lodash/lang/isNumber'),
+            groupBy = require('lodash/collection/groupBy'),
+            forEach = require('lodash/collection/forEach');
+
+        /**
+         * Adds an element to a collection and returns true if the element was added.
+         * 
+         * @param {Array
+         *            <Object>} elements
+         * @param {Object}
+         *            e
+         * @param {Boolean}
+         *            unique
+         */
+        function add(elements, e, unique) {
+            var canAdd = !unique || elements.indexOf(e) === -1;
+
+            if (canAdd) {
+                elements.push(e);
+            }
+
+            return canAdd;
+        }
+
+        function eachElement(elements, fn, depth) {
+
+            depth = depth || 0;
+
+            forEach(elements, function(s, i) {
+                var filter = fn(s, i, depth);
+
+                if (isArray(filter) && filter.length) {
+                    eachElement(filter, fn, depth + 1);
+                }
+            });
+        }
+
+        /**
+         * Collects self + child elements up to a given depth from a list of elements.
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements the elements to select the children
+         *            from
+         * @param {Boolean}
+         *            unique whether to return a unique result set (no duplicates)
+         * @param {Number}
+         *            maxDepth the depth to search through or -1 for infinite
+         * 
+         * @return {Array<djs.model.Base>} found elements
+         */
+        function selfAndChildren(elements, unique, maxDepth) {
+            var result = [],
+                processedChildren = [];
+
+            eachElement(elements, function(element, i, depth) {
+                add(result, element, unique);
+
+                var children = element.children;
+
+                // max traversal depth not reached yet
+                if (maxDepth === -1 || depth < maxDepth) {
+
+                    // children exist && children not yet processed
+                    if (children && add(processedChildren, children, unique)) {
+                        return children;
+                    }
+                }
+            });
+
+            return result;
+        }
+
+        /**
+         * Return self + direct children for a number of elements
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements to query
+         * @param {Boolean}
+         *            allowDuplicates to allow duplicates in the result set
+         * 
+         * @return {Array<djs.model.Base>} the collected elements
+         */
+        function selfAndDirectChildren(elements, allowDuplicates) {
+            return selfAndChildren(elements, !allowDuplicates, 1);
+        }
+
+        /**
+         * Return self + ALL children for a number of elements
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements to query
+         * @param {Boolean}
+         *            allowDuplicates to allow duplicates in the result set
+         * 
+         * @return {Array<djs.model.Base>} the collected elements
+         */
+        function selfAndAllChildren(elements, allowDuplicates) {
+            return selfAndChildren(elements, !allowDuplicates, -1);
+        }
+
+        /**
+         * Gets the the closure fo all selected elements, their connections and
+         * 
+         * @param {Array
+         *            <djs.model.Base>} elements
+         * @return {Object} enclosure
+         */
+        function getClosure(elements) {
+
+            // original elements passed to this function
+            var topLevel = groupBy(elements, function(e) {
+                return e.id;
+            });
+
+            var allShapes = {},
+                allConnections = {},
+                enclosedElements = {},
+                enclosedConnections = {};
+
+            function handleConnection(c) {
+                if (topLevel[c.source.id] && topLevel[c.target.id]) {
+                    topLevel[c.id] = c;
+                }
+
+                // not enclosed as a child, but maybe logically
+                // (connecting two moved elements?)
+                if (allShapes[c.source.id] && allShapes[c.target.id]) {
+                    enclosedConnections[c.id] = enclosedElements[c.id] = c;
+                }
+
+                allConnections[c.id] = c;
+            }
+
+            function handleElement(element) {
+
+                enclosedElements[element.id] = element;
+
+                if (element.waypoints) {
+                    // remember connection
+                    enclosedConnections[element.id] = allConnections[element.id] = element;
+                } else {
+                    // remember shape
+                    allShapes[element.id] = element;
+
+                    // remember all connections
+                    forEach(element.incoming, handleConnection);
+
+                    forEach(element.outgoing, handleConnection);
+
+                    // recurse into children
+                    return element.children;
+                }
+            }
+
+            eachElement(elements, handleElement);
+
+            return {
+                allShapes: allShapes,
+                allConnections: allConnections,
+                topLevel: topLevel,
+                enclosedConnections: enclosedConnections,
+                enclosedElements: enclosedElements
+            };
+        }
+
+        /**
+         * Returns the surrounding bbox for all elements in the array or the element
+         * primitive.
+         */
+        function getBBox(elements, stopRecursion) {
+
+            stopRecursion = !!stopRecursion;
+            if (!isArray(elements)) {
+                elements = [elements];
+            }
+
+            var minX,
+                minY,
+                maxX,
+                maxY;
+
+            forEach(elements, function(element) {
+
+                // If element is a connection the bbox must be computed first
+                var bbox = element;
+                if (element.waypoints && !stopRecursion) {
+                    bbox = getBBox(element.waypoints, true);
+                }
+
+                var x = bbox.x,
+                    y = bbox.y,
+                    height = bbox.height || 0,
+                    width = bbox.width || 0;
+
+                if (x < minX || minX === undefined) {
+                    minX = x;
+                }
+                if (y < minY || minY === undefined) {
+                    minY = y;
+                }
+
+                if ((x + width) > maxX || maxX === undefined) {
+                    maxX = x + width;
+                }
+                if ((y + height) > maxY || maxY === undefined) {
+                    maxY = y + height;
+                }
+            });
+
+            return {
+                x: minX,
+                y: minY,
+                height: maxY - minY,
+                width: maxX - minX
+            };
+        }
+
+
+        /**
+         * Returns all elements that are enclosed from the bounding box.
+         * 
+         * @param {Array
+         *            <Object>} elements List of Elements to search through
+         * @param {Object}
+         *            bbox the enclosing bbox.
+         *            <ul>
+         *            <li>If bbox.(width|height) is not specified the method returns
+         *            all elements with element.x/y &gt; bbox.x/y </li>
+         *            <li>If only bbox.x or bbox.y is specified, method return all
+         *            elements with e.x &gt; bbox.x or e.y &gt; bbox.y.</li>
+         *            </ul>
+         * 
+         */
+        function getEnclosedElements(elements, bbox) {
+
+            var filteredElements = {};
+
+            forEach(elements, function(element) {
+
+                var e = element;
+
+                if (e.waypoints) {
+                    e = getBBox(e);
+                }
+
+                if (!isNumber(bbox.y) && (e.x > bbox.x)) {
+                    filteredElements[element.id] = element;
+                }
+                if (!isNumber(bbox.x) && (e.y > bbox.y)) {
+                    filteredElements[element.id] = element;
+                }
+                if (e.x > bbox.x && e.y > bbox.y) {
+                    if (isNumber(bbox.width) && isNumber(bbox.height) &&
+                        e.width + e.x < bbox.width + bbox.x &&
+                        e.height + e.y < bbox.height + bbox.y) {
+
+                        filteredElements[element.id] = element;
+                    } else if (!isNumber(bbox.width) || !isNumber(bbox.height)) {
+                        filteredElements[element.id] = element;
+                    }
+                }
+            });
+
+            return filteredElements;
+        }
+
+
+
+        module.exports.eachElement = eachElement;
+        module.exports.selfAndDirectChildren = selfAndDirectChildren;
+        module.exports.selfAndAllChildren = selfAndAllChildren;
+        module.exports.getBBox = getBBox;
+        module.exports.getEnclosedElements = getEnclosedElements;
+
+        module.exports.getClosure = getClosure;
+
+    }, {
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/groupBy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\groupBy.js",
+        "lodash/lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "lodash/lang/isNumber": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNumber.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js": [function(require, module, exports) {
+        'use strict';
+
+        function __preventDefault(event) {
+            return event && event.preventDefault();
+        }
+
+        function __stopPropagation(event, immediate) {
+            if (!event) {
+                return;
+            }
+
+            if (event.stopPropagation) {
+                event.stopPropagation();
+            }
+
+            if (immediate && event.stopImmediatePropagation) {
+                event.stopImmediatePropagation();
+            }
+        }
+
+
+        function getOriginal(event) {
+            return event.originalEvent || event.srcEvent;
+        }
+
+        module.exports.getOriginal = getOriginal;
+
+
+        function stopEvent(event, immediate) {
+            stopPropagation(event, immediate);
+            preventDefault(event);
+        }
+
+        module.exports.stopEvent = stopEvent;
+
+
+        function preventDefault(event) {
+            __preventDefault(event);
+            __preventDefault(getOriginal(event));
+        }
+
+        module.exports.preventDefault = preventDefault;
+
+
+        function stopPropagation(event, immediate) {
+            __stopPropagation(event, immediate);
+            __stopPropagation(getOriginal(event), immediate);
+        }
+
+        module.exports.stopPropagation = stopPropagation;
+
+
+        function toPoint(event) {
+
+            if (event.pointers && event.pointers.length) {
+                event = event.pointers[0];
+            }
+
+            if (event.touches && event.touches.length) {
+                event = event.touches[0];
+            }
+
+            return event ? {
+                x: event.clientX,
+                y: event.clientY
+            } : null;
+        }
+
+        module.exports.toPoint = toPoint;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Geometry.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Computes the distance between two points
+         * 
+         * @param {Point}
+         *            p
+         * @param {Point}
+         *            q
+         * 
+         * @return {Number} distance
+         */
+        var distance = module.exports.distance = function(p, q) {
+            return Math.sqrt(Math.pow(q.x - p.x, 2) + Math.pow(q.y - p.y, 2));
+        };
+
+        /**
+         * Returns true if the point r is on the line between p and y
+         * 
+         * @param {Point}
+         *            p
+         * @param {Point}
+         *            q
+         * @param {Point}
+         *            r
+         * 
+         * @return {Boolean}
+         */
+        module.exports.pointsOnLine = function(p, q, r) {
+
+            if (!p || !q || !r) {
+                return false;
+            }
+
+            var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x),
+                dist = distance(p, q);
+
+            // @see http://stackoverflow.com/a/907491/412190
+            return Math.abs(val / dist) < 5;
+        };
+
+        module.exports.pointInRect = function(p, rect, tolerance) {
+            tolerance = tolerance || 0;
+
+            return p.x > rect.x - tolerance &&
+                p.y > rect.y - tolerance &&
+                p.x < rect.x + rect.width + tolerance &&
+                p.y < rect.y + rect.height + tolerance;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\GraphicsUtil.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * SVGs for elements are generated by the {@link GraphicsFactory}.
+         * 
+         * This utility gives quick access to the important semantic parts of an
+         * element.
+         */
+
+        /**
+         * Returns the visual part of a diagram element
+         * 
+         * @param {Snap
+         *            <SVGElement>} gfx
+         * 
+         * @return {Snap<SVGElement>}
+         */
+        function getVisual(gfx) {
+            return gfx.select('.djs-visual');
+        }
+
+        /**
+         * Returns the children for a given diagram element.
+         * 
+         * @param {Snap
+         *            <SVGElement>} gfx
+         * @return {Snap<SVGElement>}
+         */
+        function getChildren(gfx) {
+            return gfx.parent().children()[1];
+        }
+
+        /**
+         * Returns the visual bbox of an element
+         * 
+         * @param {Snap
+         *            <SVGElement>} gfx
+         * 
+         * @return {Bounds}
+         */
+        function getBBox(gfx) {
+            return getVisual(gfx).select('*').getBBox();
+        }
+
+
+        module.exports.getVisual = getVisual;
+        module.exports.getChildren = getChildren;
+        module.exports.getBBox = getBBox;
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\IdGenerator.js": [function(require, module, exports) {
+        'use strict';
+
+        /**
+         * Util that provides unique IDs.
+         * 
+         * @class djs.util.IdGenerator
+         * @constructor
+         * @memberOf djs.util
+         * 
+         * The ids can be customized via a given prefix and contain a random value to
+         * avoid collisions.
+         * 
+         * @param {String}
+         *            prefix a prefix to prepend to generated ids (for better
+         *            readability)
+         */
+        function IdGenerator(prefix) {
+
+            this._counter = 0;
+            this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-';
+        }
+
+        module.exports = IdGenerator;
+
+        /**
+         * Returns a next unique ID.
+         * 
+         * @method djs.util.IdGenerator#next
+         * 
+         * @returns {String} the id
+         */
+        IdGenerator.prototype.next = function() {
+            return this._prefix + (++this._counter);
+        };
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Mouse.js": [function(require, module, exports) {
+        'use strict';
+
+        var getOriginalEvent = require('./Event').getOriginal;
+
+        var isMac = require('./Platform').isMac;
+
+
+        function isPrimaryButton(event) {
+            // button === 0 -> left ÃƒÆ’¡ka primary mouse button
+            return !(getOriginalEvent(event) || event).button;
+        }
+
+        module.exports.isPrimaryButton = isPrimaryButton;
+
+        module.exports.isMac = isMac;
+
+        module.exports.hasPrimaryModifier = function(event) {
+            var originalEvent = getOriginalEvent(event) || event;
+
+            if (!isPrimaryButton(event)) {
+                return false;
+            }
+
+            // Use alt as primary modifier key for mac OS
+            if (isMac()) {
+                return originalEvent.altKey;
+            } else {
+                return originalEvent.ctrlKey;
+            }
+        };
+
+
+        module.exports.hasSecondaryModifier = function(event) {
+            var originalEvent = getOriginalEvent(event) || event;
+
+            return isPrimaryButton(event) && originalEvent.shiftKey;
+        };
+
+    }, {
+        "./Event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Event.js",
+        "./Platform": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Platform.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Platform.js": [function(require, module, exports) {
+        'use strict';
+
+        module.exports.isMac = function isMac() {
+            return (/mac/i).test(navigator.platform);
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\lib\\util\\Text.js": [function(require, module, exports) {
+        'use strict';
+
+        var isObject = require('lodash/lang/isObject'),
+            assign = require('lodash/object/assign'),
+            forEach = require('lodash/collection/forEach'),
+            reduce = require('lodash/collection/reduce'),
+            merge = require('lodash/object/merge');
+
+        var Snap = require('../../vendor/snapsvg');
+
+        var DEFAULT_BOX_PADDING = 0;
+
+        var DEFAULT_LABEL_SIZE = {
+            width: 150,
+            height: 50
+        };
+
+
+        function parseAlign(align) {
+
+            var parts = align.split('-');
+
+            return {
+                horizontal: parts[0] || 'center',
+                vertical: parts[1] || 'top'
+            };
+        }
+
+        function parsePadding(padding) {
+
+            if (isObject(padding)) {
+                return assign({
+                    top: 0,
+                    left: 0,
+                    right: 0,
+                    bottom: 0
+                }, padding);
+            } else {
+                return {
+                    top: padding,
+                    left: padding,
+                    right: padding,
+                    bottom: padding
+                };
+            }
+        }
+
+        function getTextBBox(text, fakeText) {
+            fakeText.textContent = text;
+            return fakeText.getBBox();
+        }
+
+
+        /**
+         * Layout the next line and return the layouted element.
+         * 
+         * Alters the lines passed.
+         * 
+         * @param {Array
+         *            <String>} lines
+         * @return {Object} the line descriptor, an object { width, height, text }
+         */
+        function layoutNext(lines, maxWidth, fakeText) {
+
+            var originalLine = lines.shift(),
+                fitLine = originalLine;
+
+            var textBBox;
+
+            while (true) {
+                textBBox = getTextBBox(fitLine, fakeText);
+
+                textBBox.width = fitLine ? textBBox.width : 0;
+
+                // try to fit
+                if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 4) {
+                    return fit(lines, fitLine, originalLine, textBBox);
+                }
+
+
+                fitLine = shortenLine(fitLine, textBBox.width, maxWidth);
+            }
+        }
+
+        function fit(lines, fitLine, originalLine, textBBox) {
+            if (fitLine.length < originalLine.length) {
+                var nextLine = lines[0] || '',
+                    remainder = originalLine.slice(fitLine.length).trim();
+
+                if (/-\s*$/.test(remainder)) {
+                    nextLine = remainder.replace(/-\s*$/, '') + nextLine.replace(/^\s+/, '');
+                } else {
+                    nextLine = remainder + ' ' + nextLine;
+                }
+
+                lines[0] = nextLine;
+            }
+            return {
+                width: textBBox.width,
+                height: textBBox.height,
+                text: fitLine
+            };
+        }
+
+
+        /**
+         * Shortens a line based on spacing and hyphens. Returns the shortened result on
+         * success.
+         * 
+         * @param {String}
+         *            line
+         * @param {Number}
+         *            maxLength the maximum characters of the string
+         * @return {String} the shortened string
+         */
+        function semanticShorten(line, maxLength) {
+            var parts = line.split(/(\s|-)/g),
+                part,
+                shortenedParts = [],
+                length = 0;
+
+            // try to shorten via spaces + hyphens
+            if (parts.length > 1) {
+                while ((part = parts.shift())) {
+                    if (part.length + length < maxLength) {
+                        shortenedParts.push(part);
+                        length += part.length;
+                    } else {
+                        // remove previous part, too if hyphen does not fit anymore
+                        if (part === '-') {
+                            shortenedParts.pop();
+                        }
+
+                        break;
+                    }
+                }
+            }
+
+            return shortenedParts.join('');
+        }
+
+
+        function shortenLine(line, width, maxWidth) {
+            var length = Math.max(line.length * (maxWidth / width), 1);
+
+            // try to shorten semantically (i.e. based on spaces and hyphens)
+            var shortenedLine = semanticShorten(line, length);
+
+            if (!shortenedLine) {
+
+                // force shorten by cutting the long word
+                shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1));
+            }
+
+            return shortenedLine;
+        }
+
+
+        /**
+         * Creates a new label utility
+         * 
+         * @param {Object}
+         *            config
+         * @param {Dimensions}
+         *            config.size
+         * @param {Number}
+         *            config.padding
+         * @param {Object}
+         *            config.style
+         * @param {String}
+         *            config.align
+         */
+        function Text(config) {
+
+            this._config = assign({}, {
+                size: DEFAULT_LABEL_SIZE,
+                padding: DEFAULT_BOX_PADDING,
+                style: {},
+                align: 'center-top'
+            }, config || {});
+        }
+
+
+        /**
+         * Create a label in the parent node.
+         * 
+         * @method Text#createText
+         * 
+         * @param {SVGElement}
+         *            parent the parent to draw the label on
+         * @param {String}
+         *            text the text to render on the label
+         * @param {Object}
+         *            options
+         * @param {String}
+         *            options.align how to align in the bounding box. Any of {
+         *            'center-middle', 'center-top' }, defaults to 'center-top'.
+         * @param {String}
+         *            options.style style to be applied to the text
+         * 
+         * @return {SVGText} the text element created
+         */
+        Text.prototype.createText = function(parent, text, options) {
+
+            var box = merge({}, this._config.size, options.box || {}),
+                style = merge({}, this._config.style, options.style || {}),
+                align = parseAlign(options.align || this._config.align),
+                padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding);
+
+            var lines = text.split(/\r?\n/g),
+                layouted = [];
+
+            var maxWidth = box.width - padding.left - padding.right;
+
+            // FF regression: ensure text is shown during rendering
+            // by attaching it directly to the body
+            var fakeText = parent.paper.text(0, 0, '').attr(style).node;
+
+            while (lines.length) {
+                layouted.push(layoutNext(lines, maxWidth, fakeText));
+            }
+
+            var totalHeight = reduce(layouted, function(sum, line, idx) {
+                return sum + line.height;
+            }, 0);
+
+            // the y position of the next line
+            var y, x;
+
+            switch (align.vertical) {
+                case 'middle':
+                    y = (box.height - totalHeight) / 2 - layouted[0].height / 4;
+                    break;
+
+                default:
+                    y = padding.top;
+            }
+
+            var textElement = parent.text().attr(style);
+
+            forEach(layouted, function(line) {
+                y += line.height;
+
+                switch (align.horizontal) {
+                    case 'left':
+                        x = padding.left;
+                        break;
+
+                    case 'right':
+                        x = (maxWidth - padding.right - line.width);
+                        break;
+
+                    default:
+                        // aka center
+                        x = Math.max(((maxWidth - line.width) / 2 + padding.left), 0);
+                }
+
+
+                var tspan = Snap.create('tspan', {
+                    x: x,
+                    y: y
+                }).node;
+                tspan.textContent = line.text;
+
+                textElement.append(tspan);
+            });
+
+            // remove fake text
+            fakeText.parentNode.removeChild(fakeText);
+
+            return textElement;
+        };
+
+
+        module.exports = Text;
+    }, {
+        "../../vendor/snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js",
+        "lodash/collection/forEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js",
+        "lodash/collection/reduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\reduce.js",
+        "lodash/lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "lodash/object/assign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js",
+        "lodash/object/merge": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\merge.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\annotation.js": [function(require, module, exports) {
+
+        var isArray = function(obj) {
+            return Object.prototype.toString.call(obj) === '[object Array]';
+        };
+
+        var annotate = function() {
+            var args = Array.prototype.slice.call(arguments);
+
+            if (args.length === 1 && isArray(args[0])) {
+                args = args[0];
+            }
+
+            var fn = args.pop();
+
+            fn.$inject = args;
+
+            return fn;
+        };
+
+
+        // Current limitations:
+        // - can't put into "function arg" comments
+        // function /* (no parenthesis like this) */ (){}
+        // function abc( /* xx (no parenthesis like this) */ a, b) {}
+        //
+        // Just put the comment before function or inside:
+        // /* (((this is fine))) */ function(a, b) {}
+        // function abc(a) { /* (((this is fine))) */}
+
+        var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
+        var FN_ARG = /\/\*([^\*]*)\*\//m;
+
+        var parse = function(fn) {
+            if (typeof fn !== 'function') {
+                throw new Error('Cannot annotate "' + fn + '". Expected a function!');
+            }
+
+            var match = fn.toString().match(FN_ARGS);
+            return match[1] && match[1].split(',').map(function(arg) {
+                match = arg.match(FN_ARG);
+                return match ? match[1].trim() : arg.trim();
+            }) || [];
+        };
+
+
+        exports.annotate = annotate;
+        exports.parse = parse;
+        exports.isArray = isArray;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\index.js": [function(require, module, exports) {
+        module.exports = {
+            annotate: require('./annotation').annotate,
+            Module: require('./module'),
+            Injector: require('./injector')
+        };
+
+    }, {
+        "./annotation": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\annotation.js",
+        "./injector": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\injector.js",
+        "./module": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\module.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\injector.js": [function(require, module, exports) {
+        var Module = require('./module');
+        var autoAnnotate = require('./annotation').parse;
+        var annotate = require('./annotation').annotate;
+        var isArray = require('./annotation').isArray;
+
+
+        var Injector = function(modules, parent) {
+            parent = parent || {
+                get: function(name) {
+                    currentlyResolving.push(name);
+                    throw error('No provider for "' + name + '"!');
+                }
+            };
+
+            var currentlyResolving = [];
+            var providers = this._providers = Object.create(parent._providers || null);
+            var instances = this._instances = Object.create(null);
+
+            var self = instances.injector = this;
+
+            var error = function(msg) {
+                var stack = currentlyResolving.join(' -> ');
+                currentlyResolving.length = 0;
+                return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg);
+            };
+
+            var get = function(name) {
+                if (!providers[name] && name.indexOf('.') !== -1) {
+                    var parts = name.split('.');
+                    var pivot = get(parts.shift());
+
+                    while (parts.length) {
+                        pivot = pivot[parts.shift()];
+                    }
+
+                    return pivot;
+                }
+
+                if (Object.hasOwnProperty.call(instances, name)) {
+                    return instances[name];
+                }
+
+                if (Object.hasOwnProperty.call(providers, name)) {
+                    if (currentlyResolving.indexOf(name) !== -1) {
+                        currentlyResolving.push(name);
+                        throw error('Cannot resolve circular dependency!');
+                    }
+
+                    currentlyResolving.push(name);
+                    instances[name] = providers[name][0](providers[name][1]);
+                    currentlyResolving.pop();
+
+                    return instances[name];
+                }
+
+                return parent.get(name);
+            };
+
+            var instantiate = function(Type) {
+                var instance = Object.create(Type.prototype);
+                var returned = invoke(Type, instance);
+
+                return typeof returned === 'object' ? returned : instance;
+            };
+
+            var invoke = function(fn, context) {
+                if (typeof fn !== 'function') {
+                    if (isArray(fn)) {
+                        fn = annotate(fn.slice());
+                    } else {
+                        throw new Error('Cannot invoke "' + fn + '". Expected a function!');
+                    }
+                }
+
+                var inject = fn.$inject && fn.$inject || autoAnnotate(fn);
+                var dependencies = inject.map(function(dep) {
+                    return get(dep);
+                });
+
+                // TODO(vojta): optimize without apply
+                return fn.apply(context, dependencies);
+            };
+
+
+            var createPrivateInjectorFactory = function(privateChildInjector) {
+                return annotate(function(key) {
+                    return privateChildInjector.get(key);
+                });
+            };
+
+            var createChild = function(modules, forceNewInstances) {
+                if (forceNewInstances && forceNewInstances.length) {
+                    var fromParentModule = Object.create(null);
+                    var matchedScopes = Object.create(null);
+
+                    var privateInjectorsCache = [];
+                    var privateChildInjectors = [];
+                    var privateChildFactories = [];
+
+                    var provider;
+                    var cacheIdx;
+                    var privateChildInjector;
+                    var privateChildInjectorFactory;
+                    for (var name in providers) {
+                        provider = providers[name];
+
+                        if (forceNewInstances.indexOf(name) !== -1) {
+                            if (provider[2] === 'private') {
+                                cacheIdx = privateInjectorsCache.indexOf(provider[3]);
+                                if (cacheIdx === -1) {
+                                    privateChildInjector = provider[3].createChild([], forceNewInstances);
+                                    privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector);
+                                    privateInjectorsCache.push(provider[3]);
+                                    privateChildInjectors.push(privateChildInjector);
+                                    privateChildFactories.push(privateChildInjectorFactory);
+                                    fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector];
+                                } else {
+                                    fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]];
+                                }
+                            } else {
+                                fromParentModule[name] = [provider[2], provider[1]];
+                            }
+                            matchedScopes[name] = true;
+                        }
+
+                        if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) {
+                            forceNewInstances.forEach(function(scope) {
+                                if (provider[1].$scope.indexOf(scope) !== -1) {
+                                    fromParentModule[name] = [provider[2], provider[1]];
+                                    matchedScopes[scope] = true;
+                                }
+                            });
+                        }
+                    }
+
+                    forceNewInstances.forEach(function(scope) {
+                        if (!matchedScopes[scope]) {
+                            throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!');
+                        }
+                    });
+
+                    modules.unshift(fromParentModule);
+                }
+
+                return new Injector(modules, self);
+            };
+
+            var factoryMap = {
+                factory: invoke,
+                type: instantiate,
+                value: function(value) {
+                    return value;
+                }
+            };
+
+            modules.forEach(function(module) {
+
+                function arrayUnwrap(type, value) {
+                    if (type !== 'value' && isArray(value)) {
+                        value = annotate(value.slice());
+                    }
+
+                    return value;
+                }
+
+                // TODO(vojta): handle wrong inputs (modules)
+                if (module instanceof Module) {
+                    module.forEach(function(provider) {
+                        var name = provider[0];
+                        var type = provider[1];
+                        var value = provider[2];
+
+                        providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
+                    });
+                } else if (typeof module === 'object') {
+                    if (module.__exports__) {
+                        var clonedModule = Object.keys(module).reduce(function(m, key) {
+                            if (key.substring(0, 2) !== '__') {
+                                m[key] = module[key];
+                            }
+                            return m;
+                        }, Object.create(null));
+
+                        var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self);
+                        var getFromPrivateInjector = annotate(function(key) {
+                            return privateInjector.get(key);
+                        });
+                        module.__exports__.forEach(function(key) {
+                            providers[key] = [getFromPrivateInjector, key, 'private', privateInjector];
+                        });
+                    } else {
+                        Object.keys(module).forEach(function(name) {
+                            if (module[name][2] === 'private') {
+                                providers[name] = module[name];
+                                return;
+                            }
+
+                            var type = module[name][0];
+                            var value = module[name][1];
+
+                            providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
+                        });
+                    }
+                }
+            });
+
+            // public API
+            this.get = get;
+            this.invoke = invoke;
+            this.instantiate = instantiate;
+            this.createChild = createChild;
+        };
+
+        module.exports = Injector;
+
+    }, {
+        "./annotation": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\annotation.js",
+        "./module": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\module.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\didi\\lib\\module.js": [function(require, module, exports) {
+        var Module = function() {
+            var providers = [];
+
+            this.factory = function(name, factory) {
+                providers.push([name, 'factory', factory]);
+                return this;
+            };
+
+            this.value = function(name, value) {
+                providers.push([name, 'value', value]);
+                return this;
+            };
+
+            this.type = function(name, type) {
+                providers.push([name, 'type', type]);
+                return this;
+            };
+
+            this.forEach = function(iterator) {
+                providers.forEach(iterator);
+            };
+        };
+
+        module.exports = Module;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\eve\\eve.js": [function(require, module, exports) {
+        // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+        // 
+        // Licensed under the Apache License, Version 2.0 (the "License");
+        // you may not use this file except in compliance with the License.
+        // You may obtain a copy of the License at
+        // 
+        // http://www.apache.org/licenses/LICENSE-2.0
+        // 
+        // Unless required by applicable law or agreed to in writing, software
+        // distributed under the License is distributed on an "AS IS" BASIS,
+        // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        // See the License for the specific language governing permissions and
+        // limitations under the License.
+        // ÃƒÂ¢Ã¢â‚¬ï¿½Ã…’ââ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�Â�
+        // \\
+        // ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â‚¬Å¡ Eve 0.4.2 - JavaScript Events Library ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â‚¬Å¡ \\
+        // ÃƒÂ¢Ã¢â‚¬ï¿½Ã…“ââ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�ۉâ€�¤
+        // \\
+        // ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â‚¬Å¡ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â‚¬Å¡
+        // \\
+        // ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â‚¬ï¿½ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã¢â€šÂ¬ÃƒÂ¢Ã¢â‚¬ï¿½Ã‹Å“
+        // \\
+
+        (function(glob) {
+            var version = "0.4.2",
+                has = "hasOwnProperty",
+                separator = /[\.\/]/,
+                comaseparator = /\s*,\s*/,
+                wildcard = "*",
+                fun = function() {},
+                numsort = function(a, b) {
+                    return a - b;
+                },
+                current_event,
+                stop,
+                events = {
+                    n: {}
+                },
+                firstDefined = function() {
+                    for (var i = 0, ii = this.length; i < ii; i++) {
+                        if (typeof this[i] != "undefined") {
+                            return this[i];
+                        }
+                    }
+                },
+                lastDefined = function() {
+                    var i = this.length;
+                    while (--i) {
+                        if (typeof this[i] != "undefined") {
+                            return this[i];
+                        }
+                    }
+                },
+                /*
+                 * \ eve [ method ]
+                 * 
+                 * Fires event with given `name`, given scope and other parameters.
+                 *  > Arguments
+                 *  - name (string) name of the *event*, dot (`.`) or slash (`/`) separated -
+                 * scope (object) context for the event handlers - varargs (...) the rest of
+                 * arguments will be sent to event handlers
+                 *  = (object) array of returned values from the listeners. Array has two
+                 * methods `.firstDefined()` and `.lastDefined()` to get first or last not
+                 * `undefined` value. \
+                 */
+                eve = function(name, scope) {
+                    name = String(name);
+                    var e = events,
+                        oldstop = stop,
+                        args = Array.prototype.slice.call(arguments, 2),
+                        listeners = eve.listeners(name),
+                        z = 0,
+                        f = false,
+                        l,
+                        indexed = [],
+                        queue = {},
+                        out = [],
+                        ce = current_event,
+                        errors = [];
+                    out.firstDefined = firstDefined;
+                    out.lastDefined = lastDefined;
+                    current_event = name;
+                    stop = 0;
+                    for (var i = 0, ii = listeners.length; i < ii; i++)
+                        if ("zIndex" in listeners[i]) {
+                            indexed.push(listeners[i].zIndex);
+                            if (listeners[i].zIndex < 0) {
+                                queue[listeners[i].zIndex] = listeners[i];
+                            }
+                        }
+                    indexed.sort(numsort);
+                    while (indexed[z] < 0) {
+                        l = queue[indexed[z++]];
+                        out.push(l.apply(scope, args));
+                        if (stop) {
+                            stop = oldstop;
+                            return out;
+                        }
+                    }
+                    for (i = 0; i < ii; i++) {
+                        l = listeners[i];
+                        if ("zIndex" in l) {
+                            if (l.zIndex == indexed[z]) {
+                                out.push(l.apply(scope, args));
+                                if (stop) {
+                                    break;
+                                }
+                                do {
+                                    z++;
+                                    l = queue[indexed[z]];
+                                    l && out.push(l.apply(scope, args));
+                                    if (stop) {
+                                        break;
+                                    }
+                                } while (l)
+                            } else {
+                                queue[l.zIndex] = l;
+                            }
+                        } else {
+                            out.push(l.apply(scope, args));
+                            if (stop) {
+                                break;
+                            }
+                        }
+                    }
+                    stop = oldstop;
+                    current_event = ce;
+                    return out;
+                };
+            // Undocumented. Debug only.
+            eve._events = events;
+            /*
+             * \ eve.listeners [ method ]
+             * 
+             * Internal method which gives you array of all event handlers that will be
+             * triggered by the given `name`.
+             *  > Arguments
+             *  - name (string) name of the event, dot (`.`) or slash (`/`) separated
+             *  = (array) array of event handlers \
+             */
+            eve.listeners = function(name) {
+                var names = name.split(separator),
+                    e = events,
+                    item,
+                    items,
+                    k,
+                    i,
+                    ii,
+                    j,
+                    jj,
+                    nes,
+                    es = [e],
+                    out = [];
+                for (i = 0, ii = names.length; i < ii; i++) {
+                    nes = [];
+                    for (j = 0, jj = es.length; j < jj; j++) {
+                        e = es[j].n;
+                        items = [e[names[i]], e[wildcard]];
+                        k = 2;
+                        while (k--) {
+                            item = items[k];
+                            if (item) {
+                                nes.push(item);
+                                out = out.concat(item.f || []);
+                            }
+                        }
+                    }
+                    es = nes;
+                }
+                return out;
+            };
+
+            /*
+             * \ eve.on [ method ] * Binds given event handler with a given name. You
+             * can use wildcards ÃƒÂ¢Ã¢â€šÂ¬Ã…“`*`� for the names: | eve.on("*.under.*",
+             * f); | eve("mouse.under.floor"); // triggers f Use @eve to trigger the
+             * listener. * > Arguments * - name (string) name of the event, dot (`.`) or
+             * slash (`/`) separated, with optional wildcards - f (function) event
+             * handler function * = (function) returned function accepts a single
+             * numeric parameter that represents z-index of the handler. It is an
+             * optional feature and only used when you need to ensure that some subset
+             * of handlers will be invoked in a given order, despite of the order of
+             * assignment. > Example: | eve.on("mouse", eatIt)(2); | eve.on("mouse",
+             * scream); | eve.on("mouse", catchIt)(1); This will ensure that `catchIt`
+             * function will be called before `eatIt`.
+             * 
+             * If you want to put your handler before non-indexed handlers, specify a
+             * negative value. Note: I assume most of the time you don’t need to
+             * worry about z-index, but it’s nice to have this feature
+             * ÃƒÂ¢Ã¢â€šÂ¬Ã…“just in case�. \
+             */
+            eve.on = function(name, f) {
+                name = String(name);
+                if (typeof f != "function") {
+                    return function() {};
+                }
+                var names = name.split(comaseparator);
+                for (var i = 0, ii = names.length; i < ii; i++) {
+                    (function(name) {
+                        var names = name.split(separator),
+                            e = events,
+                            exist;
+                        for (var i = 0, ii = names.length; i < ii; i++) {
+                            e = e.n;
+                            e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {
+                                n: {}
+                            });
+                        }
+                        e.f = e.f || [];
+                        for (i = 0, ii = e.f.length; i < ii; i++)
+                            if (e.f[i] == f) {
+                                exist = true;
+                                break;
+                            }!exist && e.f.push(f);
+                    }(names[i]));
+                }
+                return function(zIndex) {
+                    if (+zIndex == +zIndex) {
+                        f.zIndex = +zIndex;
+                    }
+                };
+            };
+            /*
+             * \ eve.f [ method ] * Returns function that will fire given event with
+             * optional arguments. Arguments that will be passed to the result function
+             * will be also concated to the list of final arguments. | el.onclick =
+             * eve.f("click", 1, 2); | eve.on("click", function (a, b, c) { |
+             * console.log(a, b, c); // 1, 2, [event object] | }); > Arguments - event
+             * (string) event name - varargs (…) and any other arguments =
+             * (function) possible event handler function \
+             */
+            eve.f = function(event) {
+                var attrs = [].slice.call(arguments, 1);
+                return function() {
+                    eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
+                };
+            };
+            /*
+             * \ eve.stop [ method ] * Is used inside an event handler to stop the
+             * event, preventing any subsequent listeners from firing. \
+             */
+            eve.stop = function() {
+                stop = 1;
+            };
+            /*
+             * \ eve.nt [ method ] * Could be used inside event handler to figure out
+             * actual name of the event. * > Arguments * - subname (string) #optional
+             * subname of the event * = (string) name of the event, if `subname` is not
+             * specified or = (boolean) `true`, if current event’s name contains
+             * `subname` \
+             */
+            eve.nt = function(subname) {
+                if (subname) {
+                    return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
+                }
+                return current_event;
+            };
+            /*
+             * \ eve.nts [ method ] * Could be used inside event handler to figure out
+             * actual name of the event. * * = (array) names of the event \
+             */
+            eve.nts = function() {
+                return current_event.split(separator);
+            };
+            /*
+             * \ eve.off [ method ] * Removes given function from the list of event
+             * listeners assigned to given name. If no arguments specified all the
+             * events will be cleared. * > Arguments * - name (string) name of the
+             * event, dot (`.`) or slash (`/`) separated, with optional wildcards - f
+             * (function) event handler function \
+             */
+            /*
+             * \ eve.unbind [ method ] * See @eve.off \
+             */
+            eve.off = eve.unbind = function(name, f) {
+                if (!name) {
+                    eve._events = events = {
+                        n: {}
+                    };
+                    return;
+                }
+                var names = name.split(comaseparator);
+                if (names.length > 1) {
+                    for (var i = 0, ii = names.length; i < ii; i++) {
+                        eve.off(names[i], f);
+                    }
+                    return;
+                }
+                names = name.split(separator);
+                var e,
+                    key,
+                    splice,
+                    i, ii, j, jj,
+                    cur = [events];
+                for (i = 0, ii = names.length; i < ii; i++) {
+                    for (j = 0; j < cur.length; j += splice.length - 2) {
+                        splice = [j, 1];
+                        e = cur[j].n;
+                        if (names[i] != wildcard) {
+                            if (e[names[i]]) {
+                                splice.push(e[names[i]]);
+                            }
+                        } else {
+                            for (key in e)
+                                if (e[has](key)) {
+                                    splice.push(e[key]);
+                                }
+                        }
+                        cur.splice.apply(cur, splice);
+                    }
+                }
+                for (i = 0, ii = cur.length; i < ii; i++) {
+                    e = cur[i];
+                    while (e.n) {
+                        if (f) {
+                            if (e.f) {
+                                for (j = 0, jj = e.f.length; j < jj; j++)
+                                    if (e.f[j] == f) {
+                                        e.f.splice(j, 1);
+                                        break;
+                                    }!e.f.length && delete e.f;
+                            }
+                            for (key in e.n)
+                                if (e.n[has](key) && e.n[key].f) {
+                                    var funcs = e.n[key].f;
+                                    for (j = 0, jj = funcs.length; j < jj; j++)
+                                        if (funcs[j] == f) {
+                                            funcs.splice(j, 1);
+                                            break;
+                                        }!funcs.length && delete e.n[key].f;
+                                }
+                        } else {
+                            delete e.f;
+                            for (key in e.n)
+                                if (e.n[has](key) && e.n[key].f) {
+                                    delete e.n[key].f;
+                                }
+                        }
+                        e = e.n;
+                    }
+                }
+            };
+            /*
+             * \ eve.once [ method ] * Binds given event handler with a given name to
+             * only run once then unbind itself. | eve.once("login", f); | eve("login"); //
+             * triggers f | eve("login"); // no listeners Use @eve to trigger the
+             * listener. * > Arguments * - name (string) name of the event, dot (`.`) or
+             * slash (`/`) separated, with optional wildcards - f (function) event
+             * handler function * = (function) same return function as @eve.on \
+             */
+            eve.once = function(name, f) {
+                var f2 = function() {
+                    eve.unbind(name, f2);
+                    return f.apply(this, arguments);
+                };
+                return eve.on(name, f2);
+            };
+            /*
+             * \ eve.version [ property (string) ] * Current version of the library. \
+             */
+            eve.version = version;
+            eve.toString = function() {
+                return "You are running Eve " + version;
+            };
+            (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define === "function" && define.amd ? (define("eve", [], function() {
+                return eve;
+            })) : (glob.eve = eve));
+        })(this);
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\hammerjs\\hammer.js": [function(require, module, exports) {
+        /*
+         * ! Hammer.JS - v2.0.4 - 2014-09-28 http://hammerjs.github.io/
+         * 
+         * Copyright (c) 2014 Jorik Tangelder; Licensed under the MIT license
+         */
+        (function(window, document, exportName, undefined) {
+            'use strict';
+
+            var VENDOR_PREFIXES = ['', 'webkit', 'moz', 'MS', 'ms', 'o'];
+            var TEST_ELEMENT = document.createElement('div');
+
+            var TYPE_FUNCTION = 'function';
+
+            var round = Math.round;
+            var abs = Math.abs;
+            var now = Date.now;
+
+            /**
+             * set a timeout with a given scope
+             * 
+             * @param {Function}
+             *            fn
+             * @param {Number}
+             *            timeout
+             * @param {Object}
+             *            context
+             * @returns {number}
+             */
+            function setTimeoutContext(fn, timeout, context) {
+                return setTimeout(bindFn(fn, context), timeout);
+            }
+
+            /**
+             * if the argument is an array, we want to execute the fn on each entry if it
+             * aint an array we don't want to do a thing. this is used by all the methods
+             * that accept a single and array argument.
+             * 
+             * @param {*|Array}
+             *            arg
+             * @param {String}
+             *            fn
+             * @param {Object}
+             *            [context]
+             * @returns {Boolean}
+             */
+            function invokeArrayArg(arg, fn, context) {
+                if (Array.isArray(arg)) {
+                    each(arg, context[fn], context);
+                    return true;
+                }
+                return false;
+            }
+
+            /**
+             * walk objects and arrays
+             * 
+             * @param {Object}
+             *            obj
+             * @param {Function}
+             *            iterator
+             * @param {Object}
+             *            context
+             */
+            function each(obj, iterator, context) {
+                var i;
+
+                if (!obj) {
+                    return;
+                }
+
+                if (obj.forEach) {
+                    obj.forEach(iterator, context);
+                } else if (obj.length !== undefined) {
+                    i = 0;
+                    while (i < obj.length) {
+                        iterator.call(context, obj[i], i, obj);
+                        i++;
+                    }
+                } else {
+                    for (i in obj) {
+                        obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
+                    }
+                }
+            }
+
+            /**
+             * extend object. means that properties in dest will be overwritten by the ones
+             * in src.
+             * 
+             * @param {Object}
+             *            dest
+             * @param {Object}
+             *            src
+             * @param {Boolean}
+             *            [merge]
+             * @returns {Object} dest
+             */
+            function extend(dest, src, merge) {
+                var keys = Object.keys(src);
+                var i = 0;
+                while (i < keys.length) {
+                    if (!merge || (merge && dest[keys[i]] === undefined)) {
+                        dest[keys[i]] = src[keys[i]];
+                    }
+                    i++;
+                }
+                return dest;
+            }
+
+            /**
+             * merge the values from src in the dest. means that properties that exist in
+             * dest will not be overwritten by src
+             * 
+             * @param {Object}
+             *            dest
+             * @param {Object}
+             *            src
+             * @returns {Object} dest
+             */
+            function merge(dest, src) {
+                return extend(dest, src, true);
+            }
+
+            /**
+             * simple class inheritance
+             * 
+             * @param {Function}
+             *            child
+             * @param {Function}
+             *            base
+             * @param {Object}
+             *            [properties]
+             */
+            function inherit(child, base, properties) {
+                var baseP = base.prototype,
+                    childP;
+
+                childP = child.prototype = Object.create(baseP);
+                childP.constructor = child;
+                childP._super = baseP;
+
+                if (properties) {
+                    extend(childP, properties);
+                }
+            }
+
+            /**
+             * simple function bind
+             * 
+             * @param {Function}
+             *            fn
+             * @param {Object}
+             *            context
+             * @returns {Function}
+             */
+            function bindFn(fn, context) {
+                return function boundFn() {
+                    return fn.apply(context, arguments);
+                };
+            }
+
+            /**
+             * let a boolean value also be a function that must return a boolean this first
+             * item in args will be used as the context
+             * 
+             * @param {Boolean|Function}
+             *            val
+             * @param {Array}
+             *            [args]
+             * @returns {Boolean}
+             */
+            function boolOrFn(val, args) {
+                if (typeof val == TYPE_FUNCTION) {
+                    return val.apply(args ? args[0] || undefined : undefined, args);
+                }
+                return val;
+            }
+
+            /**
+             * use the val2 when val1 is undefined
+             * 
+             * @param {*}
+             *            val1
+             * @param {*}
+             *            val2
+             * @returns {*}
+             */
+            function ifUndefined(val1, val2) {
+                return (val1 === undefined) ? val2 : val1;
+            }
+
+            /**
+             * addEventListener with multiple events at once
+             * 
+             * @param {EventTarget}
+             *            target
+             * @param {String}
+             *            types
+             * @param {Function}
+             *            handler
+             */
+            function addEventListeners(target, types, handler) {
+                each(splitStr(types), function(type) {
+                    target.addEventListener(type, handler, false);
+                });
+            }
+
+            /**
+             * removeEventListener with multiple events at once
+             * 
+             * @param {EventTarget}
+             *            target
+             * @param {String}
+             *            types
+             * @param {Function}
+             *            handler
+             */
+            function removeEventListeners(target, types, handler) {
+                each(splitStr(types), function(type) {
+                    target.removeEventListener(type, handler, false);
+                });
+            }
+
+            /**
+             * find if a node is in the given parent
+             * 
+             * @method hasParent
+             * @param {HTMLElement}
+             *            node
+             * @param {HTMLElement}
+             *            parent
+             * @return {Boolean} found
+             */
+            function hasParent(node, parent) {
+                while (node) {
+                    if (node == parent) {
+                        return true;
+                    }
+                    node = node.parentNode;
+                }
+                return false;
+            }
+
+            /**
+             * small indexOf wrapper
+             * 
+             * @param {String}
+             *            str
+             * @param {String}
+             *            find
+             * @returns {Boolean} found
+             */
+            function inStr(str, find) {
+                return str.indexOf(find) > -1;
+            }
+
+            /**
+             * split string on whitespace
+             * 
+             * @param {String}
+             *            str
+             * @returns {Array} words
+             */
+            function splitStr(str) {
+                return str.trim().split(/\s+/g);
+            }
+
+            /**
+             * find if a array contains the object using indexOf or a simple polyFill
+             * 
+             * @param {Array}
+             *            src
+             * @param {String}
+             *            find
+             * @param {String}
+             *            [findByKey]
+             * @return {Boolean|Number} false when not found, or the index
+             */
+            function inArray(src, find, findByKey) {
+                if (src.indexOf && !findByKey) {
+                    return src.indexOf(find);
+                } else {
+                    var i = 0;
+                    while (i < src.length) {
+                        if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
+                            return i;
+                        }
+                        i++;
+                    }
+                    return -1;
+                }
+            }
+
+            /**
+             * convert array-like objects to real arrays
+             * 
+             * @param {Object}
+             *            obj
+             * @returns {Array}
+             */
+            function toArray(obj) {
+                return Array.prototype.slice.call(obj, 0);
+            }
+
+            /**
+             * unique array with objects based on a key (like 'id') or just by the array's
+             * value
+             * 
+             * @param {Array}
+             *            src [{id:1},{id:2},{id:1}]
+             * @param {String}
+             *            [key]
+             * @param {Boolean}
+             *            [sort=False]
+             * @returns {Array} [{id:1},{id:2}]
+             */
+            function uniqueArray(src, key, sort) {
+                var results = [];
+                var values = [];
+                var i = 0;
+
+                while (i < src.length) {
+                    var val = key ? src[i][key] : src[i];
+                    if (inArray(values, val) < 0) {
+                        results.push(src[i]);
+                    }
+                    values[i] = val;
+                    i++;
+                }
+
+                if (sort) {
+                    if (!key) {
+                        results = results.sort();
+                    } else {
+                        results = results.sort(function sortUniqueArray(a, b) {
+                            return a[key] > b[key];
+                        });
+                    }
+                }
+
+                return results;
+            }
+
+            /**
+             * get the prefixed property
+             * 
+             * @param {Object}
+             *            obj
+             * @param {String}
+             *            property
+             * @returns {String|Undefined} prefixed
+             */
+            function prefixed(obj, property) {
+                var prefix, prop;
+                var camelProp = property[0].toUpperCase() + property.slice(1);
+
+                var i = 0;
+                while (i < VENDOR_PREFIXES.length) {
+                    prefix = VENDOR_PREFIXES[i];
+                    prop = (prefix) ? prefix + camelProp : property;
+
+                    if (prop in obj) {
+                        return prop;
+                    }
+                    i++;
+                }
+                return undefined;
+            }
+
+            /**
+             * get a unique id
+             * 
+             * @returns {number} uniqueId
+             */
+            var _uniqueId = 1;
+
+            function uniqueId() {
+                return _uniqueId++;
+            }
+
+            /**
+             * get the window object of an element
+             * 
+             * @param {HTMLElement}
+             *            element
+             * @returns {DocumentView|Window}
+             */
+            function getWindowForElement(element) {
+                var doc = element.ownerDocument;
+                return (doc.defaultView || doc.parentWindow);
+            }
+
+            var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
+
+            var SUPPORT_TOUCH = ('ontouchstart' in window);
+            var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
+            var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
+
+            var INPUT_TYPE_TOUCH = 'touch';
+            var INPUT_TYPE_PEN = 'pen';
+            var INPUT_TYPE_MOUSE = 'mouse';
+            var INPUT_TYPE_KINECT = 'kinect';
+
+            var COMPUTE_INTERVAL = 25;
+
+            var INPUT_START = 1;
+            var INPUT_MOVE = 2;
+            var INPUT_END = 4;
+            var INPUT_CANCEL = 8;
+
+            var DIRECTION_NONE = 1;
+            var DIRECTION_LEFT = 2;
+            var DIRECTION_RIGHT = 4;
+            var DIRECTION_UP = 8;
+            var DIRECTION_DOWN = 16;
+
+            var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
+            var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
+            var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
+
+            var PROPS_XY = ['x', 'y'];
+            var PROPS_CLIENT_XY = ['clientX', 'clientY'];
+
+            /**
+             * create new input type manager
+             * 
+             * @param {Manager}
+             *            manager
+             * @param {Function}
+             *            callback
+             * @returns {Input}
+             * @constructor
+             */
+            function Input(manager, callback) {
+                var self = this;
+                this.manager = manager;
+                this.callback = callback;
+                this.element = manager.element;
+                this.target = manager.options.inputTarget;
+
+                // smaller wrapper around the handler, for the scope and the enabled state
+                // of the manager,
+                // so when disabled the input events are completely bypassed.
+                this.domHandler = function(ev) {
+                    if (boolOrFn(manager.options.enable, [manager])) {
+                        self.handler(ev);
+                    }
+                };
+
+                this.init();
+
+            }
+
+            Input.prototype = {
+                /**
+                 * should handle the inputEvent data and trigger the callback
+                 * 
+                 * @virtual
+                 */
+                handler: function() {},
+
+                /**
+                 * bind the events
+                 */
+                init: function() {
+                    this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
+                    this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
+                    this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
+                },
+
+                /**
+                 * unbind the events
+                 */
+                destroy: function() {
+                    this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
+                    this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
+                    this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
+                }
+            };
+
+            /**
+             * create new input type manager called by the Manager constructor
+             * 
+             * @param {Hammer}
+             *            manager
+             * @returns {Input}
+             */
+            function createInputInstance(manager) {
+                var Type;
+                var inputClass = manager.options.inputClass;
+
+                if (inputClass) {
+                    Type = inputClass;
+                } else if (SUPPORT_POINTER_EVENTS) {
+                    Type = PointerEventInput;
+                } else if (SUPPORT_ONLY_TOUCH) {
+                    Type = TouchInput;
+                } else if (!SUPPORT_TOUCH) {
+                    Type = MouseInput;
+                } else {
+                    Type = TouchMouseInput;
+                }
+                return new(Type)(manager, inputHandler);
+            }
+
+            /**
+             * handle input events
+             * 
+             * @param {Manager}
+             *            manager
+             * @param {String}
+             *            eventType
+             * @param {Object}
+             *            input
+             */
+            function inputHandler(manager, eventType, input) {
+                var pointersLen = input.pointers.length;
+                var changedPointersLen = input.changedPointers.length;
+                var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
+                var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
+
+                input.isFirst = !!isFirst;
+                input.isFinal = !!isFinal;
+
+                if (isFirst) {
+                    manager.session = {};
+                }
+
+                // source event is the normalized value of the domEvents
+                // like 'touchstart, mouseup, pointerdown'
+                input.eventType = eventType;
+
+                // compute scale, rotation etc
+                computeInputData(manager, input);
+
+                // emit secret event
+                manager.emit('hammer.input', input);
+
+                manager.recognize(input);
+                manager.session.prevInput = input;
+            }
+
+            /**
+             * extend the data with some usable properties like scale, rotate, velocity etc
+             * 
+             * @param {Object}
+             *            manager
+             * @param {Object}
+             *            input
+             */
+            function computeInputData(manager, input) {
+                var session = manager.session;
+                var pointers = input.pointers;
+                var pointersLength = pointers.length;
+
+                // store the first input to calculate the distance and direction
+                if (!session.firstInput) {
+                    session.firstInput = simpleCloneInputData(input);
+                }
+
+                // to compute scale and rotation we need to store the multiple touches
+                if (pointersLength > 1 && !session.firstMultiple) {
+                    session.firstMultiple = simpleCloneInputData(input);
+                } else if (pointersLength === 1) {
+                    session.firstMultiple = false;
+                }
+
+                var firstInput = session.firstInput;
+                var firstMultiple = session.firstMultiple;
+                var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
+
+                var center = input.center = getCenter(pointers);
+                input.timeStamp = now();
+                input.deltaTime = input.timeStamp - firstInput.timeStamp;
+
+                input.angle = getAngle(offsetCenter, center);
+                input.distance = getDistance(offsetCenter, center);
+
+                computeDeltaXY(session, input);
+                input.offsetDirection = getDirection(input.deltaX, input.deltaY);
+
+                input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
+                input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
+
+                computeIntervalInputData(session, input);
+
+                // find the correct target
+                var target = manager.element;
+                if (hasParent(input.srcEvent.target, target)) {
+                    target = input.srcEvent.target;
+                }
+                input.target = target;
+            }
+
+            function computeDeltaXY(session, input) {
+                var center = input.center;
+                var offset = session.offsetDelta || {};
+                var prevDelta = session.prevDelta || {};
+                var prevInput = session.prevInput || {};
+
+                if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
+                    prevDelta = session.prevDelta = {
+                        x: prevInput.deltaX || 0,
+                        y: prevInput.deltaY || 0
+                    };
+
+                    offset = session.offsetDelta = {
+                        x: center.x,
+                        y: center.y
+                    };
+                }
+
+                input.deltaX = prevDelta.x + (center.x - offset.x);
+                input.deltaY = prevDelta.y + (center.y - offset.y);
+            }
+
+            /**
+             * velocity is calculated every x ms
+             * 
+             * @param {Object}
+             *            session
+             * @param {Object}
+             *            input
+             */
+            function computeIntervalInputData(session, input) {
+                var last = session.lastInterval || input,
+                    deltaTime = input.timeStamp - last.timeStamp,
+                    velocity, velocityX, velocityY, direction;
+
+                if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
+                    var deltaX = last.deltaX - input.deltaX;
+                    var deltaY = last.deltaY - input.deltaY;
+
+                    var v = getVelocity(deltaTime, deltaX, deltaY);
+                    velocityX = v.x;
+                    velocityY = v.y;
+                    velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
+                    direction = getDirection(deltaX, deltaY);
+
+                    session.lastInterval = input;
+                } else {
+                    // use latest velocity info if it doesn't overtake a minimum period
+                    velocity = last.velocity;
+                    velocityX = last.velocityX;
+                    velocityY = last.velocityY;
+                    direction = last.direction;
+                }
+
+                input.velocity = velocity;
+                input.velocityX = velocityX;
+                input.velocityY = velocityY;
+                input.direction = direction;
+            }
+
+            /**
+             * create a simple clone from the input used for storage of firstInput and
+             * firstMultiple
+             * 
+             * @param {Object}
+             *            input
+             * @returns {Object} clonedInputData
+             */
+            function simpleCloneInputData(input) {
+                // make a simple copy of the pointers because we will get a reference if we
+                // don't
+                // we only need clientXY for the calculations
+                var pointers = [];
+                var i = 0;
+                while (i < input.pointers.length) {
+                    pointers[i] = {
+                        clientX: round(input.pointers[i].clientX),
+                        clientY: round(input.pointers[i].clientY)
+                    };
+                    i++;
+                }
+
+                return {
+                    timeStamp: now(),
+                    pointers: pointers,
+                    center: getCenter(pointers),
+                    deltaX: input.deltaX,
+                    deltaY: input.deltaY
+                };
+            }
+
+            /**
+             * get the center of all the pointers
+             * 
+             * @param {Array}
+             *            pointers
+             * @return {Object} center contains `x` and `y` properties
+             */
+            function getCenter(pointers) {
+                var pointersLength = pointers.length;
+
+                // no need to loop when only one touch
+                if (pointersLength === 1) {
+                    return {
+                        x: round(pointers[0].clientX),
+                        y: round(pointers[0].clientY)
+                    };
+                }
+
+                var x = 0,
+                    y = 0,
+                    i = 0;
+                while (i < pointersLength) {
+                    x += pointers[i].clientX;
+                    y += pointers[i].clientY;
+                    i++;
+                }
+
+                return {
+                    x: round(x / pointersLength),
+                    y: round(y / pointersLength)
+                };
+            }
+
+            /**
+             * calculate the velocity between two points. unit is in px per ms.
+             * 
+             * @param {Number}
+             *            deltaTime
+             * @param {Number}
+             *            x
+             * @param {Number}
+             *            y
+             * @return {Object} velocity `x` and `y`
+             */
+            function getVelocity(deltaTime, x, y) {
+                return {
+                    x: x / deltaTime || 0,
+                    y: y / deltaTime || 0
+                };
+            }
+
+            /**
+             * get the direction between two points
+             * 
+             * @param {Number}
+             *            x
+             * @param {Number}
+             *            y
+             * @return {Number} direction
+             */
+            function getDirection(x, y) {
+                if (x === y) {
+                    return DIRECTION_NONE;
+                }
+
+                if (abs(x) >= abs(y)) {
+                    return x > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
+                }
+                return y > 0 ? DIRECTION_UP : DIRECTION_DOWN;
+            }
+
+            /**
+             * calculate the absolute distance between two points
+             * 
+             * @param {Object}
+             *            p1 {x, y}
+             * @param {Object}
+             *            p2 {x, y}
+             * @param {Array}
+             *            [props] containing x and y keys
+             * @return {Number} distance
+             */
+            function getDistance(p1, p2, props) {
+                if (!props) {
+                    props = PROPS_XY;
+                }
+                var x = p2[props[0]] - p1[props[0]],
+                    y = p2[props[1]] - p1[props[1]];
+
+                return Math.sqrt((x * x) + (y * y));
+            }
+
+            /**
+             * calculate the angle between two coordinates
+             * 
+             * @param {Object}
+             *            p1
+             * @param {Object}
+             *            p2
+             * @param {Array}
+             *            [props] containing x and y keys
+             * @return {Number} angle
+             */
+            function getAngle(p1, p2, props) {
+                if (!props) {
+                    props = PROPS_XY;
+                }
+                var x = p2[props[0]] - p1[props[0]],
+                    y = p2[props[1]] - p1[props[1]];
+                return Math.atan2(y, x) * 180 / Math.PI;
+            }
+
+            /**
+             * calculate the rotation degrees between two pointersets
+             * 
+             * @param {Array}
+             *            start array of pointers
+             * @param {Array}
+             *            end array of pointers
+             * @return {Number} rotation
+             */
+            function getRotation(start, end) {
+                return getAngle(end[1], end[0], PROPS_CLIENT_XY) - getAngle(start[1], start[0], PROPS_CLIENT_XY);
+            }
+
+            /**
+             * calculate the scale factor between two pointersets no scale is 1, and goes
+             * down to 0 when pinched together, and bigger when pinched out
+             * 
+             * @param {Array}
+             *            start array of pointers
+             * @param {Array}
+             *            end array of pointers
+             * @return {Number} scale
+             */
+            function getScale(start, end) {
+                return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
+            }
+
+            var MOUSE_INPUT_MAP = {
+                mousedown: INPUT_START,
+                mousemove: INPUT_MOVE,
+                mouseup: INPUT_END
+            };
+
+            var MOUSE_ELEMENT_EVENTS = 'mousedown';
+            var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
+
+            /**
+             * Mouse events input
+             * 
+             * @constructor
+             * @extends Input
+             */
+            function MouseInput() {
+                this.evEl = MOUSE_ELEMENT_EVENTS;
+                this.evWin = MOUSE_WINDOW_EVENTS;
+
+                this.allow = true; // used by Input.TouchMouse to disable mouse events
+                this.pressed = false; // mousedown state
+
+                Input.apply(this, arguments);
+            }
+
+            inherit(MouseInput, Input, {
+                /**
+                 * handle mouse events
+                 * 
+                 * @param {Object}
+                 *            ev
+                 */
+                handler: function MEhandler(ev) {
+                    var eventType = MOUSE_INPUT_MAP[ev.type];
+
+                    // on start we want to have the left mouse button down
+                    if (eventType & INPUT_START && ev.button === 0) {
+                        this.pressed = true;
+                    }
+
+                    if (eventType & INPUT_MOVE && ev.which !== 1) {
+                        eventType = INPUT_END;
+                    }
+
+                    // mouse must be down, and mouse events are allowed (see the TouchMouse
+                    // input)
+                    if (!this.pressed || !this.allow) {
+                        return;
+                    }
+
+                    if (eventType & INPUT_END) {
+                        this.pressed = false;
+                    }
+
+                    this.callback(this.manager, eventType, {
+                        pointers: [ev],
+                        changedPointers: [ev],
+                        pointerType: INPUT_TYPE_MOUSE,
+                        srcEvent: ev
+                    });
+                }
+            });
+
+            var POINTER_INPUT_MAP = {
+                pointerdown: INPUT_START,
+                pointermove: INPUT_MOVE,
+                pointerup: INPUT_END,
+                pointercancel: INPUT_CANCEL,
+                pointerout: INPUT_CANCEL
+            };
+
+            // in IE10 the pointer types is defined as an enum
+            var IE10_POINTER_TYPE_ENUM = {
+                2: INPUT_TYPE_TOUCH,
+                3: INPUT_TYPE_PEN,
+                4: INPUT_TYPE_MOUSE,
+                5: INPUT_TYPE_KINECT // see
+                    // https://twitter.com/jacobrossi/status/480596438489890816
+            };
+
+            var POINTER_ELEMENT_EVENTS = 'pointerdown';
+            var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
+
+            // IE10 has prefixed support, and case-sensitive
+            if (window.MSPointerEvent) {
+                POINTER_ELEMENT_EVENTS = 'MSPointerDown';
+                POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
+            }
+
+            /**
+             * Pointer events input
+             * 
+             * @constructor
+             * @extends Input
+             */
+            function PointerEventInput() {
+                this.evEl = POINTER_ELEMENT_EVENTS;
+                this.evWin = POINTER_WINDOW_EVENTS;
+
+                Input.apply(this, arguments);
+
+                this.store = (this.manager.session.pointerEvents = []);
+            }
+
+            inherit(PointerEventInput, Input, {
+                /**
+                 * handle mouse events
+                 * 
+                 * @param {Object}
+                 *            ev
+                 */
+                handler: function PEhandler(ev) {
+                    var store = this.store;
+                    var removePointer = false;
+
+                    var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
+                    var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
+                    var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
+
+                    var isTouch = (pointerType == INPUT_TYPE_TOUCH);
+
+                    // get index of the event in the store
+                    var storeIndex = inArray(store, ev.pointerId, 'pointerId');
+
+                    // start and mouse must be down
+                    if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
+                        if (storeIndex < 0) {
+                            store.push(ev);
+                            storeIndex = store.length - 1;
+                        }
+                    } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
+                        removePointer = true;
+                    }
+
+                    // it not found, so the pointer hasn't been down (so it's probably a
+                    // hover)
+                    if (storeIndex < 0) {
+                        return;
+                    }
+
+                    // update the event in the store
+                    store[storeIndex] = ev;
+
+                    this.callback(this.manager, eventType, {
+                        pointers: store,
+                        changedPointers: [ev],
+                        pointerType: pointerType,
+                        srcEvent: ev
+                    });
+
+                    if (removePointer) {
+                        // remove from the store
+                        store.splice(storeIndex, 1);
+                    }
+                }
+            });
+
+            var SINGLE_TOUCH_INPUT_MAP = {
+                touchstart: INPUT_START,
+                touchmove: INPUT_MOVE,
+                touchend: INPUT_END,
+                touchcancel: INPUT_CANCEL
+            };
+
+            var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
+            var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
+
+            /**
+             * Touch events input
+             * 
+             * @constructor
+             * @extends Input
+             */
+            function SingleTouchInput() {
+                this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
+                this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
+                this.started = false;
+
+                Input.apply(this, arguments);
+            }
+
+            inherit(SingleTouchInput, Input, {
+                handler: function TEhandler(ev) {
+                    var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
+
+                    // should we handle the touch events?
+                    if (type === INPUT_START) {
+                        this.started = true;
+                    }
+
+                    if (!this.started) {
+                        return;
+                    }
+
+                    var touches = normalizeSingleTouches.call(this, ev, type);
+
+                    // when done, reset the started state
+                    if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
+                        this.started = false;
+                    }
+
+                    this.callback(this.manager, type, {
+                        pointers: touches[0],
+                        changedPointers: touches[1],
+                        pointerType: INPUT_TYPE_TOUCH,
+                        srcEvent: ev
+                    });
+                }
+            });
+
+            /**
+             * @this {TouchInput}
+             * @param {Object}
+             *            ev
+             * @param {Number}
+             *            type flag
+             * @returns {undefined|Array} [all, changed]
+             */
+            function normalizeSingleTouches(ev, type) {
+                var all = toArray(ev.touches);
+                var changed = toArray(ev.changedTouches);
+
+                if (type & (INPUT_END | INPUT_CANCEL)) {
+                    all = uniqueArray(all.concat(changed), 'identifier', true);
+                }
+
+                return [all, changed];
+            }
+
+            var TOUCH_INPUT_MAP = {
+                touchstart: INPUT_START,
+                touchmove: INPUT_MOVE,
+                touchend: INPUT_END,
+                touchcancel: INPUT_CANCEL
+            };
+
+            var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
+
+            /**
+             * Multi-user touch events input
+             * 
+             * @constructor
+             * @extends Input
+             */
+            function TouchInput() {
+                this.evTarget = TOUCH_TARGET_EVENTS;
+                this.targetIds = {};
+
+                Input.apply(this, arguments);
+            }
+
+            inherit(TouchInput, Input, {
+                handler: function MTEhandler(ev) {
+                    var type = TOUCH_INPUT_MAP[ev.type];
+                    var touches = getTouches.call(this, ev, type);
+                    if (!touches) {
+                        return;
+                    }
+
+                    this.callback(this.manager, type, {
+                        pointers: touches[0],
+                        changedPointers: touches[1],
+                        pointerType: INPUT_TYPE_TOUCH,
+                        srcEvent: ev
+                    });
+                }
+            });
+
+            /**
+             * @this {TouchInput}
+             * @param {Object}
+             *            ev
+             * @param {Number}
+             *            type flag
+             * @returns {undefined|Array} [all, changed]
+             */
+            function getTouches(ev, type) {
+                var allTouches = toArray(ev.touches);
+                var targetIds = this.targetIds;
+
+                // when there is only one touch, the process can be simplified
+                if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
+                    targetIds[allTouches[0].identifier] = true;
+                    return [allTouches, allTouches];
+                }
+
+                var i,
+                    targetTouches,
+                    changedTouches = toArray(ev.changedTouches),
+                    changedTargetTouches = [],
+                    target = this.target;
+
+                // get target touches from touches
+                targetTouches = allTouches.filter(function(touch) {
+                    return hasParent(touch.target, target);
+                });
+
+                // collect touches
+                if (type === INPUT_START) {
+                    i = 0;
+                    while (i < targetTouches.length) {
+                        targetIds[targetTouches[i].identifier] = true;
+                        i++;
+                    }
+                }
+
+                // filter changed touches to only contain touches that exist in the
+                // collected target ids
+                i = 0;
+                while (i < changedTouches.length) {
+                    if (targetIds[changedTouches[i].identifier]) {
+                        changedTargetTouches.push(changedTouches[i]);
+                    }
+
+                    // cleanup removed touches
+                    if (type & (INPUT_END | INPUT_CANCEL)) {
+                        delete targetIds[changedTouches[i].identifier];
+                    }
+                    i++;
+                }
+
+                if (!changedTargetTouches.length) {
+                    return;
+                }
+
+                return [
+                    // merge targetTouches with changedTargetTouches so it contains ALL
+                    // touches, including 'end' and 'cancel'
+                    uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
+                    changedTargetTouches
+                ];
+            }
+
+            /**
+             * Combined touch and mouse input
+             * 
+             * Touch has a higher priority then mouse, and while touching no mouse events
+             * are allowed. This because touch devices also emit mouse events while doing a
+             * touch.
+             * 
+             * @constructor
+             * @extends Input
+             */
+            function TouchMouseInput() {
+                Input.apply(this, arguments);
+
+                var handler = bindFn(this.handler, this);
+                this.touch = new TouchInput(this.manager, handler);
+                this.mouse = new MouseInput(this.manager, handler);
+            }
+
+            inherit(TouchMouseInput, Input, {
+                /**
+                 * handle mouse and touch events
+                 * 
+                 * @param {Hammer}
+                 *            manager
+                 * @param {String}
+                 *            inputEvent
+                 * @param {Object}
+                 *            inputData
+                 */
+                handler: function TMEhandler(manager, inputEvent, inputData) {
+                    var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),
+                        isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
+
+                    // when we're in a touch event, so block all upcoming mouse events
+                    // most mobile browser also emit mouseevents, right after touchstart
+                    if (isTouch) {
+                        this.mouse.allow = false;
+                    } else if (isMouse && !this.mouse.allow) {
+                        return;
+                    }
+
+                    // reset the allowMouse when we're done
+                    if (inputEvent & (INPUT_END | INPUT_CANCEL)) {
+                        this.mouse.allow = true;
+                    }
+
+                    this.callback(manager, inputEvent, inputData);
+                },
+
+                /**
+                 * remove the event listeners
+                 */
+                destroy: function destroy() {
+                    this.touch.destroy();
+                    this.mouse.destroy();
+                }
+            });
+
+            var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
+            var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
+
+            // magical touchAction value
+            var TOUCH_ACTION_COMPUTE = 'compute';
+            var TOUCH_ACTION_AUTO = 'auto';
+            var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
+            var TOUCH_ACTION_NONE = 'none';
+            var TOUCH_ACTION_PAN_X = 'pan-x';
+            var TOUCH_ACTION_PAN_Y = 'pan-y';
+
+            /**
+             * Touch Action sets the touchAction property or uses the js alternative
+             * 
+             * @param {Manager}
+             *            manager
+             * @param {String}
+             *            value
+             * @constructor
+             */
+            function TouchAction(manager, value) {
+                this.manager = manager;
+                this.set(value);
+            }
+
+            TouchAction.prototype = {
+                /**
+                 * set the touchAction value on the element or enable the polyfill
+                 * 
+                 * @param {String}
+                 *            value
+                 */
+                set: function(value) {
+                    // find out the touch-action by the event handlers
+                    if (value == TOUCH_ACTION_COMPUTE) {
+                        value = this.compute();
+                    }
+
+                    if (NATIVE_TOUCH_ACTION) {
+                        this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
+                    }
+                    this.actions = value.toLowerCase().trim();
+                },
+
+                /**
+                 * just re-set the touchAction value
+                 */
+                update: function() {
+                    this.set(this.manager.options.touchAction);
+                },
+
+                /**
+                 * compute the value for the touchAction property based on the recognizer's
+                 * settings
+                 * 
+                 * @returns {String} value
+                 */
+                compute: function() {
+                    var actions = [];
+                    each(this.manager.recognizers, function(recognizer) {
+                        if (boolOrFn(recognizer.options.enable, [recognizer])) {
+                            actions = actions.concat(recognizer.getTouchAction());
+                        }
+                    });
+                    return cleanTouchActions(actions.join(' '));
+                },
+
+                /**
+                 * this method is called on each input cycle and provides the preventing of
+                 * the browser behavior
+                 * 
+                 * @param {Object}
+                 *            input
+                 */
+                preventDefaults: function(input) {
+                    // not needed with native support for the touchAction property
+                    if (NATIVE_TOUCH_ACTION) {
+                        return;
+                    }
+
+                    var srcEvent = input.srcEvent;
+                    var direction = input.offsetDirection;
+
+                    // if the touch action did prevented once this session
+                    if (this.manager.session.prevented) {
+                        srcEvent.preventDefault();
+                        return;
+                    }
+
+                    var actions = this.actions;
+                    var hasNone = inStr(actions, TOUCH_ACTION_NONE);
+                    var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
+                    var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
+
+                    if (hasNone ||
+                        (hasPanY && direction & DIRECTION_HORIZONTAL) ||
+                        (hasPanX && direction & DIRECTION_VERTICAL)) {
+                        return this.preventSrc(srcEvent);
+                    }
+                },
+
+                /**
+                 * call preventDefault to prevent the browser's default behavior (scrolling
+                 * in most cases)
+                 * 
+                 * @param {Object}
+                 *            srcEvent
+                 */
+                preventSrc: function(srcEvent) {
+                    this.manager.session.prevented = true;
+                    srcEvent.preventDefault();
+                }
+            };
+
+            /**
+             * when the touchActions are collected they are not a valid value, so we need to
+             * clean things up. *
+             * 
+             * @param {String}
+             *            actions
+             * @returns {*}
+             */
+            function cleanTouchActions(actions) {
+                // none
+                if (inStr(actions, TOUCH_ACTION_NONE)) {
+                    return TOUCH_ACTION_NONE;
+                }
+
+                var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
+                var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
+
+                // pan-x and pan-y can be combined
+                if (hasPanX && hasPanY) {
+                    return TOUCH_ACTION_PAN_X + ' ' + TOUCH_ACTION_PAN_Y;
+                }
+
+                // pan-x OR pan-y
+                if (hasPanX || hasPanY) {
+                    return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
+                }
+
+                // manipulation
+                if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
+                    return TOUCH_ACTION_MANIPULATION;
+                }
+
+                return TOUCH_ACTION_AUTO;
+            }
+
+            /**
+             * Recognizer flow explained; * All recognizers have the initial state of
+             * POSSIBLE when a input session starts. The definition of a input session is
+             * from the first input until the last input, with all it's movement in it. *
+             * Example session for mouse-input: mousedown -> mousemove -> mouseup
+             * 
+             * On each recognizing cycle (see Manager.recognize) the .recognize() method is
+             * executed which determines with state it should be.
+             * 
+             * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals
+             * ENDED), it is reset to POSSIBLE to give it another change on the next cycle.
+             * 
+             * Possible | +-----+---------------+ | | +-----+-----+ | | | | Failed Cancelled |
+             * +-------+------+ | | Recognized Began | Changed | Ended/Recognized
+             */
+            var STATE_POSSIBLE = 1;
+            var STATE_BEGAN = 2;
+            var STATE_CHANGED = 4;
+            var STATE_ENDED = 8;
+            var STATE_RECOGNIZED = STATE_ENDED;
+            var STATE_CANCELLED = 16;
+            var STATE_FAILED = 32;
+
+            /**
+             * Recognizer Every recognizer needs to extend from this class.
+             * 
+             * @constructor
+             * @param {Object}
+             *            options
+             */
+            function Recognizer(options) {
+                this.id = uniqueId();
+
+                this.manager = null;
+                this.options = merge(options || {}, this.defaults);
+
+                // default is enable true
+                this.options.enable = ifUndefined(this.options.enable, true);
+
+                this.state = STATE_POSSIBLE;
+
+                this.simultaneous = {};
+                this.requireFail = [];
+            }
+
+            Recognizer.prototype = {
+                /**
+                 * @virtual
+                 * @type {Object}
+                 */
+                defaults: {},
+
+                /**
+                 * set options
+                 * 
+                 * @param {Object}
+                 *            options
+                 * @return {Recognizer}
+                 */
+                set: function(options) {
+                    extend(this.options, options);
+
+                    // also update the touchAction, in case something changed about the
+                    // directions/enabled state
+                    this.manager && this.manager.touchAction.update();
+                    return this;
+                },
+
+                /**
+                 * recognize simultaneous with an other recognizer.
+                 * 
+                 * @param {Recognizer}
+                 *            otherRecognizer
+                 * @returns {Recognizer} this
+                 */
+                recognizeWith: function(otherRecognizer) {
+                    if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
+                        return this;
+                    }
+
+                    var simultaneous = this.simultaneous;
+                    otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
+                    if (!simultaneous[otherRecognizer.id]) {
+                        simultaneous[otherRecognizer.id] = otherRecognizer;
+                        otherRecognizer.recognizeWith(this);
+                    }
+                    return this;
+                },
+
+                /**
+                 * drop the simultaneous link. it doesnt remove the link on the other
+                 * recognizer.
+                 * 
+                 * @param {Recognizer}
+                 *            otherRecognizer
+                 * @returns {Recognizer} this
+                 */
+                dropRecognizeWith: function(otherRecognizer) {
+                    if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
+                        return this;
+                    }
+
+                    otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
+                    delete this.simultaneous[otherRecognizer.id];
+                    return this;
+                },
+
+                /**
+                 * recognizer can only run when an other is failing
+                 * 
+                 * @param {Recognizer}
+                 *            otherRecognizer
+                 * @returns {Recognizer} this
+                 */
+                requireFailure: function(otherRecognizer) {
+                    if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
+                        return this;
+                    }
+
+                    var requireFail = this.requireFail;
+                    otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
+                    if (inArray(requireFail, otherRecognizer) === -1) {
+                        requireFail.push(otherRecognizer);
+                        otherRecognizer.requireFailure(this);
+                    }
+                    return this;
+                },
+
+                /**
+                 * drop the requireFailure link. it does not remove the link on the other
+                 * recognizer.
+                 * 
+                 * @param {Recognizer}
+                 *            otherRecognizer
+                 * @returns {Recognizer} this
+                 */
+                dropRequireFailure: function(otherRecognizer) {
+                    if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
+                        return this;
+                    }
+
+                    otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
+                    var index = inArray(this.requireFail, otherRecognizer);
+                    if (index > -1) {
+                        this.requireFail.splice(index, 1);
+                    }
+                    return this;
+                },
+
+                /**
+                 * has require failures boolean
+                 * 
+                 * @returns {boolean}
+                 */
+                hasRequireFailures: function() {
+                    return this.requireFail.length > 0;
+                },
+
+                /**
+                 * if the recognizer can recognize simultaneous with an other recognizer
+                 * 
+                 * @param {Recognizer}
+                 *            otherRecognizer
+                 * @returns {Boolean}
+                 */
+                canRecognizeWith: function(otherRecognizer) {
+                    return !!this.simultaneous[otherRecognizer.id];
+                },
+
+                /**
+                 * You should use `tryEmit` instead of `emit` directly to check that all the
+                 * needed recognizers has failed before emitting.
+                 * 
+                 * @param {Object}
+                 *            input
+                 */
+                emit: function(input) {
+                    var self = this;
+                    var state = this.state;
+
+                    function emit(withState) {
+                        self.manager.emit(self.options.event + (withState ? stateStr(state) : ''), input);
+                    }
+
+                    // 'panstart' and 'panmove'
+                    if (state < STATE_ENDED) {
+                        emit(true);
+                    }
+
+                    emit(); // simple 'eventName' events
+
+                    // panend and pancancel
+                    if (state >= STATE_ENDED) {
+                        emit(true);
+                    }
+                },
+
+                /**
+                 * Check that all the require failure recognizers has failed, if true, it
+                 * emits a gesture event, otherwise, setup the state to FAILED.
+                 * 
+                 * @param {Object}
+                 *            input
+                 */
+                tryEmit: function(input) {
+                    if (this.canEmit()) {
+                        return this.emit(input);
+                    }
+                    // it's failing anyway
+                    this.state = STATE_FAILED;
+                },
+
+                /**
+                 * can we emit?
+                 * 
+                 * @returns {boolean}
+                 */
+                canEmit: function() {
+                    var i = 0;
+                    while (i < this.requireFail.length) {
+                        if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
+                            return false;
+                        }
+                        i++;
+                    }
+                    return true;
+                },
+
+                /**
+                 * update the recognizer
+                 * 
+                 * @param {Object}
+                 *            inputData
+                 */
+                recognize: function(inputData) {
+                    // make a new copy of the inputData
+                    // so we can change the inputData without messing up the other
+                    // recognizers
+                    var inputDataClone = extend({}, inputData);
+
+                    // is is enabled and allow recognizing?
+                    if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
+                        this.reset();
+                        this.state = STATE_FAILED;
+                        return;
+                    }
+
+                    // reset when we've reached the end
+                    if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
+                        this.state = STATE_POSSIBLE;
+                    }
+
+                    this.state = this.process(inputDataClone);
+
+                    // the recognizer has recognized a gesture
+                    // so trigger an event
+                    if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
+                        this.tryEmit(inputDataClone);
+                    }
+                },
+
+                /**
+                 * return the state of the recognizer the actual recognizing happens in this
+                 * method
+                 * 
+                 * @virtual
+                 * @param {Object}
+                 *            inputData
+                 * @returns {Const} STATE
+                 */
+                process: function(inputData) {}, // jshint ignore:line
+
+                /**
+                 * return the preferred touch-action
+                 * 
+                 * @virtual
+                 * @returns {Array}
+                 */
+                getTouchAction: function() {},
+
+                /**
+                 * called when the gesture isn't allowed to recognize like when another is
+                 * being recognized or it is disabled
+                 * 
+                 * @virtual
+                 */
+                reset: function() {}
+            };
+
+            /**
+             * get a usable string, used as event postfix
+             * 
+             * @param {Const}
+             *            state
+             * @returns {String} state
+             */
+            function stateStr(state) {
+                if (state & STATE_CANCELLED) {
+                    return 'cancel';
+                } else if (state & STATE_ENDED) {
+                    return 'end';
+                } else if (state & STATE_CHANGED) {
+                    return 'move';
+                } else if (state & STATE_BEGAN) {
+                    return 'start';
+                }
+                return '';
+            }
+
+            /**
+             * direction cons to string
+             * 
+             * @param {Const}
+             *            direction
+             * @returns {String}
+             */
+            function directionStr(direction) {
+                if (direction == DIRECTION_DOWN) {
+                    return 'down';
+                } else if (direction == DIRECTION_UP) {
+                    return 'up';
+                } else if (direction == DIRECTION_LEFT) {
+                    return 'left';
+                } else if (direction == DIRECTION_RIGHT) {
+                    return 'right';
+                }
+                return '';
+            }
+
+            /**
+             * get a recognizer by name if it is bound to a manager
+             * 
+             * @param {Recognizer|String}
+             *            otherRecognizer
+             * @param {Recognizer}
+             *            recognizer
+             * @returns {Recognizer}
+             */
+            function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
+                var manager = recognizer.manager;
+                if (manager) {
+                    return manager.get(otherRecognizer);
+                }
+                return otherRecognizer;
+            }
+
+            /**
+             * This recognizer is just used as a base for the simple attribute recognizers.
+             * 
+             * @constructor
+             * @extends Recognizer
+             */
+            function AttrRecognizer() {
+                Recognizer.apply(this, arguments);
+            }
+
+            inherit(AttrRecognizer, Recognizer, {
+                /**
+                 * @namespace
+                 * @memberof AttrRecognizer
+                 */
+                defaults: {
+                    /**
+                     * @type {Number}
+                     * @default 1
+                     */
+                    pointers: 1
+                },
+
+                /**
+                 * Used to check if it the recognizer receives valid input, like
+                 * input.distance > 10.
+                 * 
+                 * @memberof AttrRecognizer
+                 * @param {Object}
+                 *            input
+                 * @returns {Boolean} recognized
+                 */
+                attrTest: function(input) {
+                    var optionPointers = this.options.pointers;
+                    return optionPointers === 0 || input.pointers.length === optionPointers;
+                },
+
+                /**
+                 * Process the input and return the state for the recognizer
+                 * 
+                 * @memberof AttrRecognizer
+                 * @param {Object}
+                 *            input
+                 * @returns {*} State
+                 */
+                process: function(input) {
+                    var state = this.state;
+                    var eventType = input.eventType;
+
+                    var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
+                    var isValid = this.attrTest(input);
+
+                    // on cancel input and we've recognized before, return STATE_CANCELLED
+                    if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
+                        return state | STATE_CANCELLED;
+                    } else if (isRecognized || isValid) {
+                        if (eventType & INPUT_END) {
+                            return state | STATE_ENDED;
+                        } else if (!(state & STATE_BEGAN)) {
+                            return STATE_BEGAN;
+                        }
+                        return state | STATE_CHANGED;
+                    }
+                    return STATE_FAILED;
+                }
+            });
+
+            /**
+             * Pan Recognized when the pointer is down and moved in the allowed direction.
+             * 
+             * @constructor
+             * @extends AttrRecognizer
+             */
+            function PanRecognizer() {
+                AttrRecognizer.apply(this, arguments);
+
+                this.pX = null;
+                this.pY = null;
+            }
+
+            inherit(PanRecognizer, AttrRecognizer, {
+                /**
+                 * @namespace
+                 * @memberof PanRecognizer
+                 */
+                defaults: {
+                    event: 'pan',
+                    threshold: 10,
+                    pointers: 1,
+                    direction: DIRECTION_ALL
+                },
+
+                getTouchAction: function() {
+                    var direction = this.options.direction;
+                    var actions = [];
+                    if (direction & DIRECTION_HORIZONTAL) {
+                        actions.push(TOUCH_ACTION_PAN_Y);
+                    }
+                    if (direction & DIRECTION_VERTICAL) {
+                        actions.push(TOUCH_ACTION_PAN_X);
+                    }
+                    return actions;
+                },
+
+                directionTest: function(input) {
+                    var options = this.options;
+                    var hasMoved = true;
+                    var distance = input.distance;
+                    var direction = input.direction;
+                    var x = input.deltaX;
+                    var y = input.deltaY;
+
+                    // lock to axis?
+                    if (!(direction & options.direction)) {
+                        if (options.direction & DIRECTION_HORIZONTAL) {
+                            direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
+                            hasMoved = x != this.pX;
+                            distance = Math.abs(input.deltaX);
+                        } else {
+                            direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
+                            hasMoved = y != this.pY;
+                            distance = Math.abs(input.deltaY);
+                        }
+                    }
+                    input.direction = direction;
+                    return hasMoved && distance > options.threshold && direction & options.direction;
+                },
+
+                attrTest: function(input) {
+                    return AttrRecognizer.prototype.attrTest.call(this, input) &&
+                        (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
+                },
+
+                emit: function(input) {
+                    this.pX = input.deltaX;
+                    this.pY = input.deltaY;
+
+                    var direction = directionStr(input.direction);
+                    if (direction) {
+                        this.manager.emit(this.options.event + direction, input);
+                    }
+
+                    this._super.emit.call(this, input);
+                }
+            });
+
+            /**
+             * Pinch Recognized when two or more pointers are moving toward (zoom-in) or
+             * away from each other (zoom-out).
+             * 
+             * @constructor
+             * @extends AttrRecognizer
+             */
+            function PinchRecognizer() {
+                AttrRecognizer.apply(this, arguments);
+            }
+
+            inherit(PinchRecognizer, AttrRecognizer, {
+                /**
+                 * @namespace
+                 * @memberof PinchRecognizer
+                 */
+                defaults: {
+                    event: 'pinch',
+                    threshold: 0,
+                    pointers: 2
+                },
+
+                getTouchAction: function() {
+                    return [TOUCH_ACTION_NONE];
+                },
+
+                attrTest: function(input) {
+                    return this._super.attrTest.call(this, input) &&
+                        (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
+                },
+
+                emit: function(input) {
+                    this._super.emit.call(this, input);
+                    if (input.scale !== 1) {
+                        var inOut = input.scale < 1 ? 'in' : 'out';
+                        this.manager.emit(this.options.event + inOut, input);
+                    }
+                }
+            });
+
+            /**
+             * Press Recognized when the pointer is down for x ms without any movement.
+             * 
+             * @constructor
+             * @extends Recognizer
+             */
+            function PressRecognizer() {
+                Recognizer.apply(this, arguments);
+
+                this._timer = null;
+                this._input = null;
+            }
+
+            inherit(PressRecognizer, Recognizer, {
+                /**
+                 * @namespace
+                 * @memberof PressRecognizer
+                 */
+                defaults: {
+                    event: 'press',
+                    pointers: 1,
+                    time: 500, // minimal time of the pointer to be pressed
+                    threshold: 5 // a minimal movement is ok, but keep it low
+                },
+
+                getTouchAction: function() {
+                    return [TOUCH_ACTION_AUTO];
+                },
+
+                process: function(input) {
+                    var options = this.options;
+                    var validPointers = input.pointers.length === options.pointers;
+                    var validMovement = input.distance < options.threshold;
+                    var validTime = input.deltaTime > options.time;
+
+                    this._input = input;
+
+                    // we only allow little movement
+                    // and we've reached an end event, so a tap is possible
+                    if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
+                        this.reset();
+                    } else if (input.eventType & INPUT_START) {
+                        this.reset();
+                        this._timer = setTimeoutContext(function() {
+                            this.state = STATE_RECOGNIZED;
+                            this.tryEmit();
+                        }, options.time, this);
+                    } else if (input.eventType & INPUT_END) {
+                        return STATE_RECOGNIZED;
+                    }
+                    return STATE_FAILED;
+                },
+
+                reset: function() {
+                    clearTimeout(this._timer);
+                },
+
+                emit: function(input) {
+                    if (this.state !== STATE_RECOGNIZED) {
+                        return;
+                    }
+
+                    if (input && (input.eventType & INPUT_END)) {
+                        this.manager.emit(this.options.event + 'up', input);
+                    } else {
+                        this._input.timeStamp = now();
+                        this.manager.emit(this.options.event, this._input);
+                    }
+                }
+            });
+
+            /**
+             * Rotate Recognized when two or more pointer are moving in a circular motion.
+             * 
+             * @constructor
+             * @extends AttrRecognizer
+             */
+            function RotateRecognizer() {
+                AttrRecognizer.apply(this, arguments);
+            }
+
+            inherit(RotateRecognizer, AttrRecognizer, {
+                /**
+                 * @namespace
+                 * @memberof RotateRecognizer
+                 */
+                defaults: {
+                    event: 'rotate',
+                    threshold: 0,
+                    pointers: 2
+                },
+
+                getTouchAction: function() {
+                    return [TOUCH_ACTION_NONE];
+                },
+
+                attrTest: function(input) {
+                    return this._super.attrTest.call(this, input) &&
+                        (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
+                }
+            });
+
+            /**
+             * Swipe Recognized when the pointer is moving fast (velocity), with enough
+             * distance in the allowed direction.
+             * 
+             * @constructor
+             * @extends AttrRecognizer
+             */
+            function SwipeRecognizer() {
+                AttrRecognizer.apply(this, arguments);
+            }
+
+            inherit(SwipeRecognizer, AttrRecognizer, {
+                /**
+                 * @namespace
+                 * @memberof SwipeRecognizer
+                 */
+                defaults: {
+                    event: 'swipe',
+                    threshold: 10,
+                    velocity: 0.65,
+                    direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
+                    pointers: 1
+                },
+
+                getTouchAction: function() {
+                    return PanRecognizer.prototype.getTouchAction.call(this);
+                },
+
+                attrTest: function(input) {
+                    var direction = this.options.direction;
+                    var velocity;
+
+                    if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
+                        velocity = input.velocity;
+                    } else if (direction & DIRECTION_HORIZONTAL) {
+                        velocity = input.velocityX;
+                    } else if (direction & DIRECTION_VERTICAL) {
+                        velocity = input.velocityY;
+                    }
+
+                    return this._super.attrTest.call(this, input) &&
+                        direction & input.direction &&
+                        input.distance > this.options.threshold &&
+                        abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
+                },
+
+                emit: function(input) {
+                    var direction = directionStr(input.direction);
+                    if (direction) {
+                        this.manager.emit(this.options.event + direction, input);
+                    }
+
+                    this.manager.emit(this.options.event, input);
+                }
+            });
+
+            /**
+             * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps
+             * are recognized if they occur between the given interval and position. The
+             * delay option can be used to recognize multi-taps without firing a single tap.
+             * 
+             * The eventData from the emitted event contains the property `tapCount`, which
+             * contains the amount of multi-taps being recognized.
+             * 
+             * @constructor
+             * @extends Recognizer
+             */
+            function TapRecognizer() {
+                Recognizer.apply(this, arguments);
+
+                // previous time and center,
+                // used for tap counting
+                this.pTime = false;
+                this.pCenter = false;
+
+                this._timer = null;
+                this._input = null;
+                this.count = 0;
+            }
+
+            inherit(TapRecognizer, Recognizer, {
+                /**
+                 * @namespace
+                 * @memberof PinchRecognizer
+                 */
+                defaults: {
+                    event: 'tap',
+                    pointers: 1,
+                    taps: 1,
+                    interval: 300, // max time between the multi-tap taps
+                    time: 250, // max time of the pointer to be down (like finger on the
+                    // screen)
+                    threshold: 2, // a minimal movement is ok, but keep it low
+                    posThreshold: 10 // a multi-tap can be a bit off the initial position
+                },
+
+                getTouchAction: function() {
+                    return [TOUCH_ACTION_MANIPULATION];
+                },
+
+                process: function(input) {
+                    var options = this.options;
+
+                    var validPointers = input.pointers.length === options.pointers;
+                    var validMovement = input.distance < options.threshold;
+                    var validTouchTime = input.deltaTime < options.time;
+
+                    this.reset();
+
+                    if ((input.eventType & INPUT_START) && (this.count === 0)) {
+                        return this.failTimeout();
+                    }
+
+                    // we only allow little movement
+                    // and we've reached an end event, so a tap is possible
+                    if (validMovement && validTouchTime && validPointers) {
+                        if (input.eventType != INPUT_END) {
+                            return this.failTimeout();
+                        }
+
+                        var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
+                        var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
+
+                        this.pTime = input.timeStamp;
+                        this.pCenter = input.center;
+
+                        if (!validMultiTap || !validInterval) {
+                            this.count = 1;
+                        } else {
+                            this.count += 1;
+                        }
+
+                        this._input = input;
+
+                        // if tap count matches we have recognized it,
+                        // else it has began recognizing...
+                        var tapCount = this.count % options.taps;
+                        if (tapCount === 0) {
+                            // no failing requirements, immediately trigger the tap event
+                            // or wait as long as the multitap interval to trigger
+                            if (!this.hasRequireFailures()) {
+                                return STATE_RECOGNIZED;
+                            } else {
+                                this._timer = setTimeoutContext(function() {
+                                    this.state = STATE_RECOGNIZED;
+                                    this.tryEmit();
+                                }, options.interval, this);
+                                return STATE_BEGAN;
+                            }
+                        }
+                    }
+                    return STATE_FAILED;
+                },
+
+                failTimeout: function() {
+                    this._timer = setTimeoutContext(function() {
+                        this.state = STATE_FAILED;
+                    }, this.options.interval, this);
+                    return STATE_FAILED;
+                },
+
+                reset: function() {
+                    clearTimeout(this._timer);
+                },
+
+                emit: function() {
+                    if (this.state == STATE_RECOGNIZED) {
+                        this._input.tapCount = this.count;
+                        this.manager.emit(this.options.event, this._input);
+                    }
+                }
+            });
+
+            /**
+             * Simple way to create an manager with a default set of recognizers.
+             * 
+             * @param {HTMLElement}
+             *            element
+             * @param {Object}
+             *            [options]
+             * @constructor
+             */
+            function Hammer(element, options) {
+                options = options || {};
+                options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
+                return new Manager(element, options);
+            }
+
+            /**
+             * @const {string}
+             */
+            Hammer.VERSION = '2.0.4';
+
+            /**
+             * default settings
+             * 
+             * @namespace
+             */
+            Hammer.defaults = {
+                /**
+                 * set if DOM events are being triggered. But this is slower and unused by
+                 * simple implementations, so disabled by default.
+                 * 
+                 * @type {Boolean}
+                 * @default false
+                 */
+                domEvents: false,
+
+                /**
+                 * The value for the touchAction property/fallback. When set to `compute` it
+                 * will magically set the correct value based on the added recognizers.
+                 * 
+                 * @type {String}
+                 * @default compute
+                 */
+                touchAction: TOUCH_ACTION_COMPUTE,
+
+                /**
+                 * @type {Boolean}
+                 * @default true
+                 */
+                enable: true,
+
+                /**
+                 * EXPERIMENTAL FEATURE -- can be removed/changed Change the parent input
+                 * target element. If Null, then it is being set the to main element.
+                 * 
+                 * @type {Null|EventTarget}
+                 * @default null
+                 */
+                inputTarget: null,
+
+                /**
+                 * force an input class
+                 * 
+                 * @type {Null|Function}
+                 * @default null
+                 */
+                inputClass: null,
+
+                /**
+                 * Default recognizer setup when calling `Hammer()` When creating a new
+                 * Manager these will be skipped.
+                 * 
+                 * @type {Array}
+                 */
+                preset: [
+                    // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
+                    [RotateRecognizer, {
+                        enable: false
+                    }],
+                    [PinchRecognizer, {
+                            enable: false
+                        },
+                        ['rotate']
+                    ],
+                    [SwipeRecognizer, {
+                        direction: DIRECTION_HORIZONTAL
+                    }],
+                    [PanRecognizer, {
+                            direction: DIRECTION_HORIZONTAL
+                        },
+                        ['swipe']
+                    ],
+                    [TapRecognizer],
+                    [TapRecognizer, {
+                            event: 'doubletap',
+                            taps: 2
+                        },
+                        ['tap']
+                    ],
+                    [PressRecognizer]
+                ],
+
+                /**
+                 * Some CSS properties can be used to improve the working of Hammer. Add
+                 * them to this method and they will be set when creating a new Manager.
+                 * 
+                 * @namespace
+                 */
+                cssProps: {
+                    /**
+                     * Disables text selection to improve the dragging gesture. Mainly for
+                     * desktop browsers.
+                     * 
+                     * @type {String}
+                     * @default 'none'
+                     */
+                    userSelect: 'none',
+
+                    /**
+                     * Disable the Windows Phone grippers when pressing an element.
+                     * 
+                     * @type {String}
+                     * @default 'none'
+                     */
+                    touchSelect: 'none',
+
+                    /**
+                     * Disables the default callout shown when you touch and hold a touch
+                     * target. On iOS, when you touch and hold a touch target such as a
+                     * link, Safari displays a callout containing information about the
+                     * link. This property allows you to disable that callout.
+                     * 
+                     * @type {String}
+                     * @default 'none'
+                     */
+                    touchCallout: 'none',
+
+                    /**
+                     * Specifies whether zooming is enabled. Used by IE10>
+                     * 
+                     * @type {String}
+                     * @default 'none'
+                     */
+                    contentZooming: 'none',
+
+                    /**
+                     * Specifies that an entire element should be draggable instead of its
+                     * contents. Mainly for desktop browsers.
+                     * 
+                     * @type {String}
+                     * @default 'none'
+                     */
+                    userDrag: 'none',
+
+                    /**
+                     * Overrides the highlight color shown when the user taps a link or a
+                     * JavaScript clickable element in iOS. This property obeys the alpha
+                     * value, if specified.
+                     * 
+                     * @type {String}
+                     * @default 'rgba(0,0,0,0)'
+                     */
+                    tapHighlightColor: 'rgba(0,0,0,0)'
+                }
+            };
+
+            var STOP = 1;
+            var FORCED_STOP = 2;
+
+            /**
+             * Manager
+             * 
+             * @param {HTMLElement}
+             *            element
+             * @param {Object}
+             *            [options]
+             * @constructor
+             */
+            function Manager(element, options) {
+                options = options || {};
+
+                this.options = merge(options, Hammer.defaults);
+                this.options.inputTarget = this.options.inputTarget || element;
+
+                this.handlers = {};
+                this.session = {};
+                this.recognizers = [];
+
+                this.element = element;
+                this.input = createInputInstance(this);
+                this.touchAction = new TouchAction(this, this.options.touchAction);
+
+                toggleCssProps(this, true);
+
+                each(options.recognizers, function(item) {
+                    var recognizer = this.add(new(item[0])(item[1]));
+                    item[2] && recognizer.recognizeWith(item[2]);
+                    item[3] && recognizer.requireFailure(item[3]);
+                }, this);
+            }
+
+            Manager.prototype = {
+                /**
+                 * set options
+                 * 
+                 * @param {Object}
+                 *            options
+                 * @returns {Manager}
+                 */
+                set: function(options) {
+                    extend(this.options, options);
+
+                    // Options that need a little more setup
+                    if (options.touchAction) {
+                        this.touchAction.update();
+                    }
+                    if (options.inputTarget) {
+                        // Clean up existing event listeners and reinitialize
+                        this.input.destroy();
+                        this.input.target = options.inputTarget;
+                        this.input.init();
+                    }
+                    return this;
+                },
+
+                /**
+                 * stop recognizing for this session. This session will be discarded, when a
+                 * new [input]start event is fired. When forced, the recognizer cycle is
+                 * stopped immediately.
+                 * 
+                 * @param {Boolean}
+                 *            [force]
+                 */
+                stop: function(force) {
+                    this.session.stopped = force ? FORCED_STOP : STOP;
+                },
+
+                /**
+                 * run the recognizers! called by the inputHandler function on every
+                 * movement of the pointers (touches) it walks through all the recognizers
+                 * and tries to detect the gesture that is being made
+                 * 
+                 * @param {Object}
+                 *            inputData
+                 */
+                recognize: function(inputData) {
+                    var session = this.session;
+                    if (session.stopped) {
+                        return;
+                    }
+
+                    // run the touch-action polyfill
+                    this.touchAction.preventDefaults(inputData);
+
+                    var recognizer;
+                    var recognizers = this.recognizers;
+
+                    // this holds the recognizer that is being recognized.
+                    // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or
+                    // RECOGNIZED
+                    // if no recognizer is detecting a thing, it is set to `null`
+                    var curRecognizer = session.curRecognizer;
+
+                    // reset when the last recognizer is recognized
+                    // or when we're in a new session
+                    if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
+                        curRecognizer = session.curRecognizer = null;
+                    }
+
+                    var i = 0;
+                    while (i < recognizers.length) {
+                        recognizer = recognizers[i];
+
+                        // find out if we are allowed try to recognize the input for this
+                        // one.
+                        // 1. allow if the session is NOT forced stopped (see the .stop()
+                        // method)
+                        // 2. allow if we still haven't recognized a gesture in this
+                        // session, or the this recognizer is the one
+                        // that is being recognized.
+                        // 3. allow if the recognizer is allowed to run simultaneous with
+                        // the current recognized recognizer.
+                        // this can be setup with the `recognizeWith()` method on the
+                        // recognizer.
+                        if (session.stopped !== FORCED_STOP && ( // 1
+                                !curRecognizer || recognizer == curRecognizer || // 2
+                                recognizer.canRecognizeWith(curRecognizer))) { // 3
+                            recognizer.recognize(inputData);
+                        } else {
+                            recognizer.reset();
+                        }
+
+                        // if the recognizer has been recognizing the input as a valid
+                        // gesture, we want to store this one as the
+                        // current active recognizer. but only if we don't already have an
+                        // active recognizer
+                        if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
+                            curRecognizer = session.curRecognizer = recognizer;
+                        }
+                        i++;
+                    }
+                },
+
+                /**
+                 * get a recognizer by its event name.
+                 * 
+                 * @param {Recognizer|String}
+                 *            recognizer
+                 * @returns {Recognizer|Null}
+                 */
+                get: function(recognizer) {
+                    if (recognizer instanceof Recognizer) {
+                        return recognizer;
+                    }
+
+                    var recognizers = this.recognizers;
+                    for (var i = 0; i < recognizers.length; i++) {
+                        if (recognizers[i].options.event == recognizer) {
+                            return recognizers[i];
+                        }
+                    }
+                    return null;
+                },
+
+                /**
+                 * add a recognizer to the manager existing recognizers with the same event
+                 * name will be removed
+                 * 
+                 * @param {Recognizer}
+                 *            recognizer
+                 * @returns {Recognizer|Manager}
+                 */
+                add: function(recognizer) {
+                    if (invokeArrayArg(recognizer, 'add', this)) {
+                        return this;
+                    }
+
+                    // remove existing
+                    var existing = this.get(recognizer.options.event);
+                    if (existing) {
+                        this.remove(existing);
+                    }
+
+                    this.recognizers.push(recognizer);
+                    recognizer.manager = this;
+
+                    this.touchAction.update();
+                    return recognizer;
+                },
+
+                /**
+                 * remove a recognizer by name or instance
+                 * 
+                 * @param {Recognizer|String}
+                 *            recognizer
+                 * @returns {Manager}
+                 */
+                remove: function(recognizer) {
+                    if (invokeArrayArg(recognizer, 'remove', this)) {
+                        return this;
+                    }
+
+                    var recognizers = this.recognizers;
+                    recognizer = this.get(recognizer);
+                    recognizers.splice(inArray(recognizers, recognizer), 1);
+
+                    this.touchAction.update();
+                    return this;
+                },
+
+                /**
+                 * bind event
+                 * 
+                 * @param {String}
+                 *            events
+                 * @param {Function}
+                 *            handler
+                 * @returns {EventEmitter} this
+                 */
+                on: function(events, handler) {
+                    var handlers = this.handlers;
+                    each(splitStr(events), function(event) {
+                        handlers[event] = handlers[event] || [];
+                        handlers[event].push(handler);
+                    });
+                    return this;
+                },
+
+                /**
+                 * unbind event, leave emit blank to remove all handlers
+                 * 
+                 * @param {String}
+                 *            events
+                 * @param {Function}
+                 *            [handler]
+                 * @returns {EventEmitter} this
+                 */
+                off: function(events, handler) {
+                    var handlers = this.handlers;
+                    each(splitStr(events), function(event) {
+                        if (!handler) {
+                            delete handlers[event];
+                        } else {
+                            handlers[event].splice(inArray(handlers[event], handler), 1);
+                        }
+                    });
+                    return this;
+                },
+
+                /**
+                 * emit event to the listeners
+                 * 
+                 * @param {String}
+                 *            event
+                 * @param {Object}
+                 *            data
+                 */
+                emit: function(event, data) {
+                    // we also want to trigger dom events
+                    if (this.options.domEvents) {
+                        triggerDomEvent(event, data);
+                    }
+
+                    // no handlers, so skip it all
+                    var handlers = this.handlers[event] && this.handlers[event].slice();
+                    if (!handlers || !handlers.length) {
+                        return;
+                    }
+
+                    data.type = event;
+                    data.preventDefault = function() {
+                        data.srcEvent.preventDefault();
+                    };
+
+                    var i = 0;
+                    while (i < handlers.length) {
+                        handlers[i](data);
+                        i++;
+                    }
+                },
+
+                /**
+                 * destroy the manager and unbinds all events it doesn't unbind dom events,
+                 * that is the user own responsibility
+                 */
+                destroy: function() {
+                    this.element && toggleCssProps(this, false);
+
+                    this.handlers = {};
+                    this.session = {};
+                    this.input.destroy();
+                    this.element = null;
+                }
+            };
+
+            /**
+             * add/remove the css properties as defined in manager.options.cssProps
+             * 
+             * @param {Manager}
+             *            manager
+             * @param {Boolean}
+             *            add
+             */
+            function toggleCssProps(manager, add) {
+                var element = manager.element;
+                each(manager.options.cssProps, function(value, name) {
+                    element.style[prefixed(element.style, name)] = add ? value : '';
+                });
+            }
+
+            /**
+             * trigger dom event
+             * 
+             * @param {String}
+             *            event
+             * @param {Object}
+             *            data
+             */
+            function triggerDomEvent(event, data) {
+                var gestureEvent = document.createEvent('Event');
+                gestureEvent.initEvent(event, true, true);
+                gestureEvent.gesture = data;
+                data.target.dispatchEvent(gestureEvent);
+            }
+
+            extend(Hammer, {
+                INPUT_START: INPUT_START,
+                INPUT_MOVE: INPUT_MOVE,
+                INPUT_END: INPUT_END,
+                INPUT_CANCEL: INPUT_CANCEL,
+
+                STATE_POSSIBLE: STATE_POSSIBLE,
+                STATE_BEGAN: STATE_BEGAN,
+                STATE_CHANGED: STATE_CHANGED,
+                STATE_ENDED: STATE_ENDED,
+                STATE_RECOGNIZED: STATE_RECOGNIZED,
+                STATE_CANCELLED: STATE_CANCELLED,
+                STATE_FAILED: STATE_FAILED,
+
+                DIRECTION_NONE: DIRECTION_NONE,
+                DIRECTION_LEFT: DIRECTION_LEFT,
+                DIRECTION_RIGHT: DIRECTION_RIGHT,
+                DIRECTION_UP: DIRECTION_UP,
+                DIRECTION_DOWN: DIRECTION_DOWN,
+                DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
+                DIRECTION_VERTICAL: DIRECTION_VERTICAL,
+                DIRECTION_ALL: DIRECTION_ALL,
+
+                Manager: Manager,
+                Input: Input,
+                TouchAction: TouchAction,
+
+                TouchInput: TouchInput,
+                MouseInput: MouseInput,
+                PointerEventInput: PointerEventInput,
+                TouchMouseInput: TouchMouseInput,
+                SingleTouchInput: SingleTouchInput,
+
+                Recognizer: Recognizer,
+                AttrRecognizer: AttrRecognizer,
+                Tap: TapRecognizer,
+                Pan: PanRecognizer,
+                Swipe: SwipeRecognizer,
+                Pinch: PinchRecognizer,
+                Rotate: RotateRecognizer,
+                Press: PressRecognizer,
+
+                on: addEventListeners,
+                off: removeEventListeners,
+                each: each,
+                merge: merge,
+                extend: extend,
+                inherit: inherit,
+                bindFn: bindFn,
+                prefixed: prefixed
+            });
+
+            if (typeof define == TYPE_FUNCTION && define.amd) {
+                define(function() {
+                    return Hammer;
+                });
+            } else if (typeof module != 'undefined' && module.exports) {
+                module.exports = Hammer;
+            } else {
+                window[exportName] = Hammer;
+            }
+
+        })(window, document, 'Hammer');
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\inherits\\inherits_browser.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\inherits\\inherits_browser.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\attr.js": [function(require, module, exports) {
+        /**
+         * Set attribute `name` to `val`, or get attr `name`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            name
+         * @param {String}
+         *            [val]
+         * @api public
+         */
+
+        module.exports = function(el, name, val) {
+            // get
+            if (arguments.length == 2) {
+                return el.getAttribute(name);
+            }
+
+            // remove
+            if (val === null) {
+                return el.removeAttribute(name);
+            }
+
+            // set
+            el.setAttribute(name, val);
+
+            return el;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\classes.js": [function(require, module, exports) {
+        module.exports = require('component-classes');
+    }, {
+        "component-classes": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-classes\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\clear.js": [function(require, module, exports) {
+        module.exports = function(el) {
+
+            var c;
+
+            while (el.childNodes.length) {
+                c = el.childNodes[0];
+                el.removeChild(c);
+            }
+
+            return el;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\closest.js": [function(require, module, exports) {
+        module.exports = require('component-closest');
+    }, {
+        "component-closest": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-closest\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\delegate.js": [function(require, module, exports) {
+        module.exports = require('component-delegate');
+    }, {
+        "component-delegate": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-delegate\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\domify.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\domify.js"][0].apply(exports, arguments)
+    }, {
+        "domify": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\domify\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\event.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\event.js"][0].apply(exports, arguments)
+    }, {
+        "component-event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\matches.js": [function(require, module, exports) {
+        module.exports = require('component-matches-selector');
+    }, {
+        "component-matches-selector": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-matches-selector\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\query.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\query.js"][0].apply(exports, arguments)
+    }, {
+        "component-query": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\lib\\remove.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\lib\\remove.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-classes\\index.js": [function(require, module, exports) {
+        /**
+         * Module dependencies.
+         */
+
+        var index = require('indexof');
+
+        /**
+         * Whitespace regexp.
+         */
+
+        var re = /\s+/;
+
+        /**
+         * toString reference.
+         */
+
+        var toString = Object.prototype.toString;
+
+        /**
+         * Wrap `el` in a `ClassList`.
+         * 
+         * @param {Element}
+         *            el
+         * @return {ClassList}
+         * @api public
+         */
+
+        module.exports = function(el) {
+            return new ClassList(el);
+        };
+
+        /**
+         * Initialize a new ClassList for `el`.
+         * 
+         * @param {Element}
+         *            el
+         * @api private
+         */
+
+        function ClassList(el) {
+            if (!el || !el.nodeType) {
+                throw new Error('A DOM element reference is required');
+            }
+            this.el = el;
+            this.list = el.classList;
+        }
+
+        /**
+         * Add class `name` if not already present.
+         * 
+         * @param {String}
+         *            name
+         * @return {ClassList}
+         * @api public
+         */
+
+        ClassList.prototype.add = function(name) {
+            // classList
+            if (this.list) {
+                this.list.add(name);
+                return this;
+            }
+
+            // fallback
+            var arr = this.array();
+            var i = index(arr, name);
+            if (!~i) arr.push(name);
+            this.el.className = arr.join(' ');
+            return this;
+        };
+
+        /**
+         * Remove class `name` when present, or pass a regular expression to remove any
+         * which match.
+         * 
+         * @param {String|RegExp}
+         *            name
+         * @return {ClassList}
+         * @api public
+         */
+
+        ClassList.prototype.remove = function(name) {
+            if ('[object RegExp]' == toString.call(name)) {
+                return this.removeMatching(name);
+            }
+
+            // classList
+            if (this.list) {
+                this.list.remove(name);
+                return this;
+            }
+
+            // fallback
+            var arr = this.array();
+            var i = index(arr, name);
+            if (~i) arr.splice(i, 1);
+            this.el.className = arr.join(' ');
+            return this;
+        };
+
+        /**
+         * Remove all classes matching `re`.
+         * 
+         * @param {RegExp}
+         *            re
+         * @return {ClassList}
+         * @api private
+         */
+
+        ClassList.prototype.removeMatching = function(re) {
+            var arr = this.array();
+            for (var i = 0; i < arr.length; i++) {
+                if (re.test(arr[i])) {
+                    this.remove(arr[i]);
+                }
+            }
+            return this;
+        };
+
+        /**
+         * Toggle class `name`, can force state via `force`.
+         * 
+         * For browsers that support classList, but do not support `force` yet, the
+         * mistake will be detected and corrected.
+         * 
+         * @param {String}
+         *            name
+         * @param {Boolean}
+         *            force
+         * @return {ClassList}
+         * @api public
+         */
+
+        ClassList.prototype.toggle = function(name, force) {
+            // classList
+            if (this.list) {
+                if ("undefined" !== typeof force) {
+                    if (force !== this.list.toggle(name, force)) {
+                        this.list.toggle(name); // toggle again to correct
+                    }
+                } else {
+                    this.list.toggle(name);
+                }
+                return this;
+            }
+
+            // fallback
+            if ("undefined" !== typeof force) {
+                if (!force) {
+                    this.remove(name);
+                } else {
+                    this.add(name);
+                }
+            } else {
+                if (this.has(name)) {
+                    this.remove(name);
+                } else {
+                    this.add(name);
+                }
+            }
+
+            return this;
+        };
+
+        /**
+         * Return an array of classes.
+         * 
+         * @return {Array}
+         * @api public
+         */
+
+        ClassList.prototype.array = function() {
+            var className = this.el.getAttribute('class') || '';
+            var str = className.replace(/^\s+|\s+$/g, '');
+            var arr = str.split(re);
+            if ('' === arr[0]) arr.shift();
+            return arr;
+        };
+
+        /**
+         * Check if class `name` is present.
+         * 
+         * @param {String}
+         *            name
+         * @return {ClassList}
+         * @api public
+         */
+
+        ClassList.prototype.has =
+            ClassList.prototype.contains = function(name) {
+                return this.list ? this.list.contains(name) : !!~index(this.array(), name);
+            };
+
+    }, {
+        "indexof": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-classes\\node_modules\\component-indexof\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-classes\\node_modules\\component-indexof\\index.js": [function(require, module, exports) {
+        module.exports = function(arr, obj) {
+            if (arr.indexOf) return arr.indexOf(obj);
+            for (var i = 0; i < arr.length; ++i) {
+                if (arr[i] === obj) return i;
+            }
+            return -1;
+        };
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-closest\\index.js": [function(require, module, exports) {
+        var matches = require('matches-selector')
+
+        module.exports = function(element, selector, checkYoSelf, root) {
+            element = checkYoSelf ? {
+                parentNode: element
+            } : element
+
+            root = root || document
+
+            // Make sure `element !== document` and `element != null`
+            // otherwise we get an illegal invocation
+            while ((element = element.parentNode) && element !== document) {
+                if (matches(element, selector))
+                    return element
+                        // After `matches` on the edge case that
+                        // the selector matches the root
+                        // (when the root is not the document)
+                if (element === root)
+                    return
+            }
+        }
+
+    }, {
+        "matches-selector": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-matches-selector\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-delegate\\index.js": [function(require, module, exports) {
+        /**
+         * Module dependencies.
+         */
+
+        var closest = require('closest'),
+            event = require('event');
+
+        /**
+         * Delegate event `type` to `selector` and invoke `fn(e)`. A callback function
+         * is returned which may be passed to `.unbind()`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            selector
+         * @param {String}
+         *            type
+         * @param {Function}
+         *            fn
+         * @param {Boolean}
+         *            capture
+         * @return {Function}
+         * @api public
+         */
+
+        exports.bind = function(el, selector, type, fn, capture) {
+            return event.bind(el, type, function(e) {
+                var target = e.target || e.srcElement;
+                e.delegateTarget = closest(target, selector, true, el);
+                if (e.delegateTarget) fn.call(el, e);
+            }, capture);
+        };
+
+        /**
+         * Unbind event `type`'s callback `fn`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            type
+         * @param {Function}
+         *            fn
+         * @param {Boolean}
+         *            capture
+         * @api public
+         */
+
+        exports.unbind = function(el, type, fn, capture) {
+            event.unbind(el, type, fn, capture);
+        };
+
+    }, {
+        "closest": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-closest\\index.js",
+        "event": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-event\\index.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-matches-selector\\index.js": [function(require, module, exports) {
+        /**
+         * Module dependencies.
+         */
+
+        var query = require('query');
+
+        /**
+         * Element prototype.
+         */
+
+        var proto = Element.prototype;
+
+        /**
+         * Vendor function.
+         */
+
+        var vendor = proto.matches || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector;
+
+        /**
+         * Expose `match()`.
+         */
+
+        module.exports = match;
+
+        /**
+         * Match `el` to `selector`.
+         * 
+         * @param {Element}
+         *            el
+         * @param {String}
+         *            selector
+         * @return {Boolean}
+         * @api public
+         */
+
+        function match(el, selector) {
+            if (!el || el.nodeType !== 1) return false;
+            if (vendor) return vendor.call(el, selector);
+            var nodes = query.all(selector, el.parentNode);
+            for (var i = 0; i < nodes.length; ++i) {
+                if (nodes[i] == el) return true;
+            }
+            return false;
+        }
+
+    }, {
+        "query": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\component-query\\index.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\min-dom\\node_modules\\domify\\index.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\min-dom\\node_modules\\domify\\index.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\index.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\index.js"][0].apply(exports, arguments)
+    }, {
+        "./lib/collection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\lib\\collection.js",
+        "./lib/refs": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\lib\\refs.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\lib\\collection.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\collection.js"][0].apply(exports, arguments)
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\lib\\refs.js": [function(require, module, exports) {
+        arguments[4]["\\bpmn-js-examples-master\\modeler\\node_modules\\bpmn-js\\node_modules\\object-refs\\lib\\refs.js"][0].apply(exports, arguments)
+    }, {
+        "./collection": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\object-refs\\lib\\collection.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\snapsvg\\dist\\snap.svg.js": [function(require, module, exports) {
+        // Snap.svg 0.3.0
+        // 
+        // Copyright (c) 2013 ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬Å“ 2014 Adobe Systems Incorporated. All rights
+        // reserved.
+        // 
+        // Licensed under the Apache License, Version 2.0 (the "License");
+        // you may not use this file except in compliance with the License.
+        // You may obtain a copy of the License at
+        // 
+        // http://www.apache.org/licenses/LICENSE-2.0
+        // 
+        // Unless required by applicable law or agreed to in writing, software
+        // distributed under the License is distributed on an "AS IS" BASIS,
+        // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        // See the License for the specific language governing permissions and
+        // limitations under the License.
+        // 
+        // build: 2014-09-08
+
+        (function(glob, factory) {
+            // AMD support
+            if (typeof define === "function" && define.amd) {
+                // Define as an anonymous module
+                define(["eve"], function(eve) {
+                    return factory(glob, eve);
+                });
+            } else if (typeof exports !== 'undefined') {
+                // Next for Node.js or CommonJS
+                var eve = require('eve');
+                module.exports = factory(glob, eve);
+            } else {
+                // Browser globals (glob is window)
+                // Snap adds itself to window
+                factory(glob, glob.eve);
+            }
+        }(window || this, function(window, eve) {
+
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            var mina = (function(eve) {
+                var animations = {},
+                    requestAnimFrame = window.requestAnimationFrame ||
+                    window.webkitRequestAnimationFrame ||
+                    window.mozRequestAnimationFrame ||
+                    window.oRequestAnimationFrame ||
+                    window.msRequestAnimationFrame ||
+                    function(callback) {
+                        setTimeout(callback, 16);
+                    },
+                    isArray = Array.isArray || function(a) {
+                        return a instanceof Array ||
+                            Object.prototype.toString.call(a) == "[object Array]";
+                    },
+                    idgen = 0,
+                    idprefix = "M" + (+new Date).toString(36),
+                    ID = function() {
+                        return idprefix + (idgen++).toString(36);
+                    },
+                    diff = function(a, b, A, B) {
+                        if (isArray(a)) {
+                            res = [];
+                            for (var i = 0, ii = a.length; i < ii; i++) {
+                                res[i] = diff(a[i], b, A[i], B);
+                            }
+                            return res;
+                        }
+                        var dif = (A - a) / (B - b);
+                        return function(bb) {
+                            return a + dif * (bb - b);
+                        };
+                    },
+                    timer = Date.now || function() {
+                        return +new Date;
+                    },
+                    sta = function(val) {
+                        var a = this;
+                        if (val == null) {
+                            return a.s;
+                        }
+                        var ds = a.s - val;
+                        a.b += a.dur * ds;
+                        a.B += a.dur * ds;
+                        a.s = val;
+                    },
+                    speed = function(val) {
+                        var a = this;
+                        if (val == null) {
+                            return a.spd;
+                        }
+                        a.spd = val;
+                    },
+                    duration = function(val) {
+                        var a = this;
+                        if (val == null) {
+                            return a.dur;
+                        }
+                        a.s = a.s * val / a.dur;
+                        a.dur = val;
+                    },
+                    stopit = function() {
+                        var a = this;
+                        delete animations[a.id];
+                        a.update();
+                        eve("mina.stop." + a.id, a);
+                    },
+                    pause = function() {
+                        var a = this;
+                        if (a.pdif) {
+                            return;
+                        }
+                        delete animations[a.id];
+                        a.update();
+                        a.pdif = a.get() - a.b;
+                    },
+                    resume = function() {
+                        var a = this;
+                        if (!a.pdif) {
+                            return;
+                        }
+                        a.b = a.get() - a.pdif;
+                        delete a.pdif;
+                        animations[a.id] = a;
+                    },
+                    update = function() {
+                        var a = this,
+                            res;
+                        if (isArray(a.start)) {
+                            res = [];
+                            for (var j = 0, jj = a.start.length; j < jj; j++) {
+                                res[j] = +a.start[j] +
+                                    (a.end[j] - a.start[j]) * a.easing(a.s);
+                            }
+                        } else {
+                            res = +a.start + (a.end - a.start) * a.easing(a.s);
+                        }
+                        a.set(res);
+                    },
+                    frame = function() {
+                        var len = 0;
+                        for (var i in animations)
+                            if (animations.hasOwnProperty(i)) {
+                                var a = animations[i],
+                                    b = a.get(),
+                                    res;
+                                len++;
+                                a.s = (b - a.b) / (a.dur / a.spd);
+                                if (a.s >= 1) {
+                                    delete animations[i];
+                                    a.s = 1;
+                                    len--;
+                                    (function(a) {
+                                        setTimeout(function() {
+                                            eve("mina.finish." + a.id, a);
+                                        });
+                                    }(a));
+                                }
+                                a.update();
+                            }
+                        len && requestAnimFrame(frame);
+                    },
+                    /*
+                     * \ mina [ method ] * Generic animation of numbers * - a (number) start
+                     * _slave_ number - A (number) end _slave_ number - b (number) start
+                     * _master_ number (start time in general case) - B (number) end _master_
+                     * number (end time in gereal case) - get (function) getter of _master_
+                     * number (see @mina.time) - set (function) setter of _slave_ number -
+                     * easing (function) #optional easing function, default is @mina.linear =
+                     * (object) animation descriptor o { o id (string) animation id, o start
+                     * (number) start _slave_ number, o end (number) end _slave_ number, o b
+                     * (number) start _master_ number, o s (number) animation status (0..1), o
+                     * dur (number) animation duration, o spd (number) animation speed, o get
+                     * (function) getter of _master_ number (see @mina.time), o set (function)
+                     * setter of _slave_ number, o easing (function) easing function, default is
+                     * @mina.linear, o status (function) status getter/setter, o speed
+                     * (function) speed getter/setter, o duration (function) duration
+                     * getter/setter, o stop (function) animation stopper o pause (function)
+                     * pauses the animation o resume (function) resumes the animation o update
+                     * (function) calles setter with the right value of the animation o } \
+                     */
+                    mina = function(a, A, b, B, get, set, easing) {
+                        var anim = {
+                            id: ID(),
+                            start: a,
+                            end: A,
+                            b: b,
+                            s: 0,
+                            dur: B - b,
+                            spd: 1,
+                            get: get,
+                            set: set,
+                            easing: easing || mina.linear,
+                            status: sta,
+                            speed: speed,
+                            duration: duration,
+                            stop: stopit,
+                            pause: pause,
+                            resume: resume,
+                            update: update
+                        };
+                        animations[anim.id] = anim;
+                        var len = 0,
+                            i;
+                        for (i in animations)
+                            if (animations.hasOwnProperty(i)) {
+                                len++;
+                                if (len == 2) {
+                                    break;
+                                }
+                            }
+                        len == 1 && requestAnimFrame(frame);
+                        return anim;
+                    };
+                /*
+                 * \ mina.time [ method ] * Returns the current time. Equivalent to: |
+                 * function () { | return (new Date).getTime(); | } \
+                 */
+                mina.time = timer;
+                /*
+                 * \ mina.getById [ method ] * Returns an animation by its id - id (string)
+                 * animation's id = (object) See @mina \
+                 */
+                mina.getById = function(id) {
+                    return animations[id] || null;
+                };
+
+                /*
+                 * \ mina.linear [ method ] * Default linear easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.linear = function(n) {
+                    return n;
+                };
+                /*
+                 * \ mina.easeout [ method ] * Easeout easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.easeout = function(n) {
+                    return Math.pow(n, 1.7);
+                };
+                /*
+                 * \ mina.easein [ method ] * Easein easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.easein = function(n) {
+                    return Math.pow(n, .48);
+                };
+                /*
+                 * \ mina.easeinout [ method ] * Easeinout easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.easeinout = function(n) {
+                    if (n == 1) {
+                        return 1;
+                    }
+                    if (n == 0) {
+                        return 0;
+                    }
+                    var q = .48 - n / 1.04,
+                        Q = Math.sqrt(.1734 + q * q),
+                        x = Q - q,
+                        X = Math.pow(Math.abs(x), 1 / 3) * (x < 0 ? -1 : 1),
+                        y = -Q - q,
+                        Y = Math.pow(Math.abs(y), 1 / 3) * (y < 0 ? -1 : 1),
+                        t = X + Y + .5;
+                    return (1 - t) * 3 * t * t + t * t * t;
+                };
+                /*
+                 * \ mina.backin [ method ] * Backin easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.backin = function(n) {
+                    if (n == 1) {
+                        return 1;
+                    }
+                    var s = 1.70158;
+                    return n * n * ((s + 1) * n - s);
+                };
+                /*
+                 * \ mina.backout [ method ] * Backout easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.backout = function(n) {
+                    if (n == 0) {
+                        return 0;
+                    }
+                    n = n - 1;
+                    var s = 1.70158;
+                    return n * n * ((s + 1) * n + s) + 1;
+                };
+                /*
+                 * \ mina.elastic [ method ] * Elastic easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.elastic = function(n) {
+                    if (n == !!n) {
+                        return n;
+                    }
+                    return Math.pow(2, -10 * n) * Math.sin((n - .075) *
+                        (2 * Math.PI) / .3) + 1;
+                };
+                /*
+                 * \ mina.bounce [ method ] * Bounce easing - n (number) input 0..1 =
+                 * (number) output 0..1 \
+                 */
+                mina.bounce = function(n) {
+                    var s = 7.5625,
+                        p = 2.75,
+                        l;
+                    if (n < (1 / p)) {
+                        l = s * n * n;
+                    } else {
+                        if (n < (2 / p)) {
+                            n -= (1.5 / p);
+                            l = s * n * n + .75;
+                        } else {
+                            if (n < (2.5 / p)) {
+                                n -= (2.25 / p);
+                                l = s * n * n + .9375;
+                            } else {
+                                n -= (2.625 / p);
+                                l = s * n * n + .984375;
+                            }
+                        }
+                    }
+                    return l;
+                };
+                window.mina = mina;
+                return mina;
+            })(typeof eve == "undefined" ? function() {} : eve);
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            //
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            //
+            // http://www.apache.org/licenses/LICENSE-2.0
+            //
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+
+            var Snap = (function(root) {
+                Snap.version = "0.3.0";
+                /*
+                 * \ Snap [ method ] * Creates a drawing surface or wraps existing SVG element. * -
+                 * width (number|string) width of surface - height (number|string) height of
+                 * surface or - DOM (SVGElement) element to be wrapped into Snap structure or -
+                 * array (array) array of elements (will return set of elements) or - query
+                 * (string) CSS query selector = (object) @Element \
+                 */
+                function Snap(w, h) {
+                    if (w) {
+                        if (w.tagName) {
+                            return wrap(w);
+                        }
+                        if (is(w, "array") && Snap.set) {
+                            return Snap.set.apply(Snap, w);
+                        }
+                        if (w instanceof Element) {
+                            return w;
+                        }
+                        if (h == null) {
+                            w = glob.doc.querySelector(w);
+                            return wrap(w);
+                        }
+                    }
+                    w = w == null ? "100%" : w;
+                    h = h == null ? "100%" : h;
+                    return new Paper(w, h);
+                }
+                Snap.toString = function() {
+                    return "Snap v" + this.version;
+                };
+                Snap._ = {};
+                var glob = {
+                    win: root.window,
+                    doc: root.window.document
+                };
+                Snap._.glob = glob;
+                var has = "hasOwnProperty",
+                    Str = String,
+                    toFloat = parseFloat,
+                    toInt = parseInt,
+                    math = Math,
+                    mmax = math.max,
+                    mmin = math.min,
+                    abs = math.abs,
+                    pow = math.pow,
+                    PI = math.PI,
+                    round = math.round,
+                    E = "",
+                    S = " ",
+                    objectToString = Object.prototype.toString,
+                    ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
+                    colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,
+                    bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
+                    reURLValue = /^url\(#?([^)]+)\)$/,
+                    separator = Snap._.separator = /[,\s]+/,
+                    whitespace = /[\s]/g,
+                    commaSpaces = /[\s]*,[\s]*/,
+                    hsrg = {
+                        hs: 1,
+                        rg: 1
+                    },
+                    pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
+                    tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/ig,
+                    pathValues = /(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/ig,
+                    idgen = 0,
+                    idprefix = "S" + (+new Date).toString(36),
+                    ID = function(el) {
+                        return (el && el.type ? el.type : E) + idprefix + (idgen++).toString(36);
+                    },
+                    xlink = "http://www.w3.org/1999/xlink",
+                    xmlns = "http://www.w3.org/2000/svg",
+                    hub = {},
+                    URL = Snap.url = function(url) {
+                        return "url('#" + url + "')";
+                    };
+
+                function $(el, attr) {
+                    if (attr) {
+                        if (el == "#text") {
+                            el = glob.doc.createTextNode(attr.text || "");
+                        }
+                        if (typeof el == "string") {
+                            el = $(el);
+                        }
+                        if (typeof attr == "string") {
+                            if (attr.substring(0, 6) == "xlink:") {
+                                return el.getAttributeNS(xlink, attr.substring(6));
+                            }
+                            if (attr.substring(0, 4) == "xml:") {
+                                return el.getAttributeNS(xmlns, attr.substring(4));
+                            }
+                            return el.getAttribute(attr);
+                        }
+                        for (var key in attr)
+                            if (attr[has](key)) {
+                                var val = Str(attr[key]);
+                                if (val) {
+                                    if (key.substring(0, 6) == "xlink:") {
+                                        el.setAttributeNS(xlink, key.substring(6), val);
+                                    } else if (key.substring(0, 4) == "xml:") {
+                                        el.setAttributeNS(xmlns, key.substring(4), val);
+                                    } else {
+                                        el.setAttribute(key, val);
+                                    }
+                                } else {
+                                    el.removeAttribute(key);
+                                }
+                            }
+                    } else {
+                        el = glob.doc.createElementNS(xmlns, el);
+                    }
+                    return el;
+                }
+                Snap._.$ = $;
+                Snap._.id = ID;
+
+                function getAttrs(el) {
+                    var attrs = el.attributes,
+                        name,
+                        out = {};
+                    for (var i = 0; i < attrs.length; i++) {
+                        if (attrs[i].namespaceURI == xlink) {
+                            name = "xlink:";
+                        } else {
+                            name = "";
+                        }
+                        name += attrs[i].name;
+                        out[name] = attrs[i].textContent;
+                    }
+                    return out;
+                }
+
+                function is(o, type) {
+                    type = Str.prototype.toLowerCase.call(type);
+                    if (type == "finite") {
+                        return isFinite(o);
+                    }
+                    if (type == "array" &&
+                        (o instanceof Array || Array.isArray && Array.isArray(o))) {
+                        return true;
+                    }
+                    return (type == "null" && o === null) ||
+                        (type == typeof o && o !== null) ||
+                        (type == "object" && o === Object(o)) ||
+                        objectToString.call(o).slice(8, -1).toLowerCase() == type;
+                }
+                /*
+                 * \ Snap.format [ method ] * Replaces construction of type `{<name>}` to the
+                 * corresponding argument * - token (string) string to format - json (object)
+                 * object which properties are used as a replacement = (string) formatted string >
+                 * Usage | // this draws a rectangular shape equivalent to "M10,20h40v50h-40z" |
+                 * paper.path(Snap.format("M{x},{y}h{dim.width}v{dim.height}h{dim['negative
+                 * width']}z", { | x: 10, | y: 20, | dim: { | width: 40, | height: 50, |
+                 * "negative width": -40 | } | })); \
+                 */
+                Snap.format = (function() {
+                    var tokenRegex = /\{([^\}]+)\}/g,
+                        objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches
+                        // .xxxxx
+                        // or
+                        // ["xxxxx"]
+                        // to
+                        // run
+                        // over
+                        // object
+                        // properties
+                        replacer = function(all, key, obj) {
+                            var res = obj;
+                            key.replace(objNotationRegex, function(all, name, quote, quotedName, isFunc) {
+                                name = name || quotedName;
+                                if (res) {
+                                    if (name in res) {
+                                        res = res[name];
+                                    }
+                                    typeof res == "function" && isFunc && (res = res());
+                                }
+                            });
+                            res = (res == null || res == obj ? all : res) + "";
+                            return res;
+                        };
+                    return function(str, obj) {
+                        return Str(str).replace(tokenRegex, function(all, key) {
+                            return replacer(all, key, obj);
+                        });
+                    };
+                })();
+
+                function clone(obj) {
+                    if (typeof obj == "function" || Object(obj) !== obj) {
+                        return obj;
+                    }
+                    var res = new obj.constructor;
+                    for (var key in obj)
+                        if (obj[has](key)) {
+                            res[key] = clone(obj[key]);
+                        }
+                    return res;
+                }
+                Snap._.clone = clone;
+
+                function repush(array, item) {
+                    for (var i = 0, ii = array.length; i < ii; i++)
+                        if (array[i] === item) {
+                            return array.push(array.splice(i, 1)[0]);
+                        }
+                }
+
+                function cacher(f, scope, postprocessor) {
+                    function newf() {
+                        var arg = Array.prototype.slice.call(arguments, 0),
+                            args = arg.join("\u2400"),
+                            cache = newf.cache = newf.cache || {},
+                            count = newf.count = newf.count || [];
+                        if (cache[has](args)) {
+                            repush(count, args);
+                            return postprocessor ? postprocessor(cache[args]) : cache[args];
+                        }
+                        count.length >= 1e3 && delete cache[count.shift()];
+                        count.push(args);
+                        cache[args] = f.apply(scope, arg);
+                        return postprocessor ? postprocessor(cache[args]) : cache[args];
+                    }
+                    return newf;
+                }
+                Snap._.cacher = cacher;
+
+                function angle(x1, y1, x2, y2, x3, y3) {
+                    if (x3 == null) {
+                        var x = x1 - x2,
+                            y = y1 - y2;
+                        if (!x && !y) {
+                            return 0;
+                        }
+                        return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
+                    } else {
+                        return angle(x1, y1, x3, y3) - angle(x2, y2, x3, y3);
+                    }
+                }
+
+                function rad(deg) {
+                    return deg % 360 * PI / 180;
+                }
+
+                function deg(rad) {
+                    return rad * 180 / PI % 360;
+                }
+
+                function x_y() {
+                    return this.x + S + this.y;
+                }
+
+                function x_y_w_h() {
+                    return this.x + S + this.y + S + this.width + " \xd7 " + this.height;
+                }
+
+                /*
+                 * \ Snap.rad [ method ] * Transform angle to radians - deg (number) angle in
+                 * degrees = (number) angle in radians \
+                 */
+                Snap.rad = rad;
+                /*
+                 * \ Snap.deg [ method ] * Transform angle to degrees - rad (number) angle in
+                 * radians = (number) angle in degrees \
+                 */
+                Snap.deg = deg;
+                /*
+                 * \ Snap.angle [ method ] * Returns an angle between two or three points >
+                 * Parameters - x1 (number) x coord of first point - y1 (number) y coord of
+                 * first point - x2 (number) x coord of second point - y2 (number) y coord of
+                 * second point - x3 (number) #optional x coord of third point - y3 (number)
+                 * #optional y coord of third point = (number) angle in degrees \
+                 */
+                Snap.angle = angle;
+                /*
+                 * \ Snap.is [ method ] * Handy replacement for the `typeof` operator - o
+                 * (…) any object or primitive - type (string) name of the type, e.g.,
+                 * `string`, `function`, `number`, etc. = (boolean) `true` if given value is of
+                 * given type \
+                 */
+                Snap.is = is;
+                /*
+                 * \ Snap.snapTo [ method ] * Snaps given value to given grid - values
+                 * (array|number) given array of values or step of the grid - value (number)
+                 * value to adjust - tolerance (number) #optional maximum distance to the target
+                 * value that would trigger the snap. Default is `10`. = (number) adjusted value \
+                 */
+                Snap.snapTo = function(values, value, tolerance) {
+                    tolerance = is(tolerance, "finite") ? tolerance : 10;
+                    if (is(values, "array")) {
+                        var i = values.length;
+                        while (i--)
+                            if (abs(values[i] - value) <= tolerance) {
+                                return values[i];
+                            }
+                    } else {
+                        values = +values;
+                        var rem = value % values;
+                        if (rem < tolerance) {
+                            return value - rem;
+                        }
+                        if (rem > values - tolerance) {
+                            return value - rem + values;
+                        }
+                    }
+                    return value;
+                };
+                // Colour
+                /*
+                 * \ Snap.getRGB [ method ] * Parses color string as RGB object - color (string)
+                 * color string in one of the following formats: # <ul> # <li>Color name (<code>red</code>,
+                 * <code>green</code>, <code>cornflowerblue</code>, etc)</li> # <li>#•••
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ shortened HTML color: (<code>#000</code>, <code>#fc0</code>,
+                 * etc.)</li> # <li>#•••••• ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ full
+                 * length HTML color: (<code>#000000</code>, <code>#bd2300</code>)</li> #
+                 * <li>rgb(•••, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢)
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ red, green and blue channels values: (<code>rgb(200,&nbsp;100,&nbsp;0)</code>)</li> #
+                 * <li>rgba(•••, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> #
+                 * <li>rgb(•••%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ same as above, but in %: (<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>)</li> #
+                 * <li>rgba(•••%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> #
+                 * <li>hsb(•••, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢)
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ hue, saturation and brightness values: (<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>)</li> #
+                 * <li>hsba(•••, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> #
+                 * <li>hsb(•••%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ same as above, but in %</li> # <li>hsba(•••%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%)
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> # <li>hsl(•••,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ hue, saturation and
+                 * luminosity values: (<code>hsb(0.5,&nbsp;0.25,&nbsp;0.5)</code>)</li> #
+                 * <li>hsla(•••, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> #
+                 * <li>hsl(•••%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%) ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ same as above, but in %</li> # <li>hsla(•••%,
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%, ÃƒÂ¢Ã¢â€šÂ¬Ã‚¢Ã¢â‚¬Â¢Ã¢â‚¬Â¢%)
+                 * ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ also with opacity</li> # </ul> Note that `%` can be used any time:
+                 * `rgb(20%, 255, 50%)`. = (object) RGB object in the following format: o { o r
+                 * (number) red, o g (number) green, o b (number) blue, o hex (string) color in
+                 * HTML/CSS format: #••••••, o error
+                 * (boolean) true if string can't be parsed o } \
+                 */
+                Snap.getRGB = cacher(function(colour) {
+                    if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
+                        return {
+                            r: -1,
+                            g: -1,
+                            b: -1,
+                            hex: "none",
+                            error: 1,
+                            toString: rgbtoString
+                        };
+                    }
+                    if (colour == "none") {
+                        return {
+                            r: -1,
+                            g: -1,
+                            b: -1,
+                            hex: "none",
+                            toString: rgbtoString
+                        };
+                    }!(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
+                    if (!colour) {
+                        return {
+                            r: -1,
+                            g: -1,
+                            b: -1,
+                            hex: "none",
+                            error: 1,
+                            toString: rgbtoString
+                        };
+                    }
+                    var res,
+                        red,
+                        green,
+                        blue,
+                        opacity,
+                        t,
+                        values,
+                        rgb = colour.match(colourRegExp);
+                    if (rgb) {
+                        if (rgb[2]) {
+                            blue = toInt(rgb[2].substring(5), 16);
+                            green = toInt(rgb[2].substring(3, 5), 16);
+                            red = toInt(rgb[2].substring(1, 3), 16);
+                        }
+                        if (rgb[3]) {
+                            blue = toInt((t = rgb[3].charAt(3)) + t, 16);
+                            green = toInt((t = rgb[3].charAt(2)) + t, 16);
+                            red = toInt((t = rgb[3].charAt(1)) + t, 16);
+                        }
+                        if (rgb[4]) {
+                            values = rgb[4].split(commaSpaces);
+                            red = toFloat(values[0]);
+                            values[0].slice(-1) == "%" && (red *= 2.55);
+                            green = toFloat(values[1]);
+                            values[1].slice(-1) == "%" && (green *= 2.55);
+                            blue = toFloat(values[2]);
+                            values[2].slice(-1) == "%" && (blue *= 2.55);
+                            rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
+                            values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
+                        }
+                        if (rgb[5]) {
+                            values = rgb[5].split(commaSpaces);
+                            red = toFloat(values[0]);
+                            values[0].slice(-1) == "%" && (red /= 100);
+                            green = toFloat(values[1]);
+                            values[1].slice(-1) == "%" && (green /= 100);
+                            blue = toFloat(values[2]);
+                            values[2].slice(-1) == "%" && (blue /= 100);
+                            (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
+                            rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
+                            values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
+                            return Snap.hsb2rgb(red, green, blue, opacity);
+                        }
+                        if (rgb[6]) {
+                            values = rgb[6].split(commaSpaces);
+                            red = toFloat(values[0]);
+                            values[0].slice(-1) == "%" && (red /= 100);
+                            green = toFloat(values[1]);
+                            values[1].slice(-1) == "%" && (green /= 100);
+                            blue = toFloat(values[2]);
+                            values[2].slice(-1) == "%" && (blue /= 100);
+                            (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
+                            rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
+                            values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
+                            return Snap.hsl2rgb(red, green, blue, opacity);
+                        }
+                        red = mmin(math.round(red), 255);
+                        green = mmin(math.round(green), 255);
+                        blue = mmin(math.round(blue), 255);
+                        opacity = mmin(mmax(opacity, 0), 1);
+                        rgb = {
+                            r: red,
+                            g: green,
+                            b: blue,
+                            toString: rgbtoString
+                        };
+                        rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
+                        rgb.opacity = is(opacity, "finite") ? opacity : 1;
+                        return rgb;
+                    }
+                    return {
+                        r: -1,
+                        g: -1,
+                        b: -1,
+                        hex: "none",
+                        error: 1,
+                        toString: rgbtoString
+                    };
+                }, Snap);
+                // SIERRA It seems odd that the following 3 conversion methods are not expressed
+                // as .this2that(), like the others.
+                /*
+                 * \ Snap.hsb [ method ] * Converts HSB values to a hex representation of the
+                 * color - h (number) hue - s (number) saturation - b (number) value or
+                 * brightness = (string) hex representation of the color \
+                 */
+                Snap.hsb = cacher(function(h, s, b) {
+                    return Snap.hsb2rgb(h, s, b).hex;
+                });
+                /*
+                 * \ Snap.hsl [ method ] * Converts HSL values to a hex representation of the
+                 * color - h (number) hue - s (number) saturation - l (number) luminosity =
+                 * (string) hex representation of the color \
+                 */
+                Snap.hsl = cacher(function(h, s, l) {
+                    return Snap.hsl2rgb(h, s, l).hex;
+                });
+                /*
+                 * \ Snap.rgb [ method ] * Converts RGB values to a hex representation of the
+                 * color - r (number) red - g (number) green - b (number) blue = (string) hex
+                 * representation of the color \
+                 */
+                Snap.rgb = cacher(function(r, g, b, o) {
+                    if (is(o, "finite")) {
+                        var round = math.round;
+                        return "rgba(" + [round(r), round(g), round(b), +o.toFixed(2)] + ")";
+                    }
+                    return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
+                });
+                var toHex = function(color) {
+                        var i = glob.doc.getElementsByTagName("head")[0] || glob.doc.getElementsByTagName("svg")[0],
+                            red = "rgb(255, 0, 0)";
+                        toHex = cacher(function(color) {
+                            if (color.toLowerCase() == "red") {
+                                return red;
+                            }
+                            i.style.color = red;
+                            i.style.color = color;
+                            var out = glob.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
+                            return out == red ? null : out;
+                        });
+                        return toHex(color);
+                    },
+                    hsbtoString = function() {
+                        return "hsb(" + [this.h, this.s, this.b] + ")";
+                    },
+                    hsltoString = function() {
+                        return "hsl(" + [this.h, this.s, this.l] + ")";
+                    },
+                    rgbtoString = function() {
+                        return this.opacity == 1 || this.opacity == null ?
+                            this.hex :
+                            "rgba(" + [this.r, this.g, this.b, this.opacity] + ")";
+                    },
+                    prepareRGB = function(r, g, b) {
+                        if (g == null && is(r, "object") && "r" in r && "g" in r && "b" in r) {
+                            b = r.b;
+                            g = r.g;
+                            r = r.r;
+                        }
+                        if (g == null && is(r, string)) {
+                            var clr = Snap.getRGB(r);
+                            r = clr.r;
+                            g = clr.g;
+                            b = clr.b;
+                        }
+                        if (r > 1 || g > 1 || b > 1) {
+                            r /= 255;
+                            g /= 255;
+                            b /= 255;
+                        }
+
+                        return [r, g, b];
+                    },
+                    packageRGB = function(r, g, b, o) {
+                        r = math.round(r * 255);
+                        g = math.round(g * 255);
+                        b = math.round(b * 255);
+                        var rgb = {
+                            r: r,
+                            g: g,
+                            b: b,
+                            opacity: is(o, "finite") ? o : 1,
+                            hex: Snap.rgb(r, g, b),
+                            toString: rgbtoString
+                        };
+                        is(o, "finite") && (rgb.opacity = o);
+                        return rgb;
+                    };
+                // SIERRA Clarify if Snap does not support consolidated HSLA/RGBA colors. E.g.,
+                // can you specify a semi-transparent value for Snap.filter.shadow()?
+                /*
+                 * \ Snap.color [ method ] * Parses the color string and returns an object
+                 * featuring the color's component values - clr (string) color string in one of
+                 * the supported formats (see @Snap.getRGB) = (object) Combined RGB/HSB object
+                 * in the following format: o { o r (number) red, o g (number) green, o b
+                 * (number) blue, o hex (string) color in HTML/CSS format:
+                 * #••••••, o error (boolean) `true` if
+                 * string can't be parsed, o h (number) hue, o s (number) saturation, o v
+                 * (number) value (brightness), o l (number) lightness o } \
+                 */
+                Snap.color = function(clr) {
+                    var rgb;
+                    if (is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
+                        rgb = Snap.hsb2rgb(clr);
+                        clr.r = rgb.r;
+                        clr.g = rgb.g;
+                        clr.b = rgb.b;
+                        clr.opacity = 1;
+                        clr.hex = rgb.hex;
+                    } else if (is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
+                        rgb = Snap.hsl2rgb(clr);
+                        clr.r = rgb.r;
+                        clr.g = rgb.g;
+                        clr.b = rgb.b;
+                        clr.opacity = 1;
+                        clr.hex = rgb.hex;
+                    } else {
+                        if (is(clr, "string")) {
+                            clr = Snap.getRGB(clr);
+                        }
+                        if (is(clr, "object") && "r" in clr && "g" in clr && "b" in clr && !("error" in clr)) {
+                            rgb = Snap.rgb2hsl(clr);
+                            clr.h = rgb.h;
+                            clr.s = rgb.s;
+                            clr.l = rgb.l;
+                            rgb = Snap.rgb2hsb(clr);
+                            clr.v = rgb.b;
+                        } else {
+                            clr = {
+                                hex: "none"
+                            };
+                            clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
+                            clr.error = 1;
+                        }
+                    }
+                    clr.toString = rgbtoString;
+                    return clr;
+                };
+                /*
+                 * \ Snap.hsb2rgb [ method ] * Converts HSB values to an RGB object - h (number)
+                 * hue - s (number) saturation - v (number) value or brightness = (object) RGB
+                 * object in the following format: o { o r (number) red, o g (number) green, o b
+                 * (number) blue, o hex (string) color in HTML/CSS format:
+                 * #•••••• o } \
+                 */
+                Snap.hsb2rgb = function(h, s, v, o) {
+                    if (is(h, "object") && "h" in h && "s" in h && "b" in h) {
+                        v = h.b;
+                        s = h.s;
+                        h = h.h;
+                        o = h.o;
+                    }
+                    h *= 360;
+                    var R, G, B, X, C;
+                    h = (h % 360) / 60;
+                    C = v * s;
+                    X = C * (1 - abs(h % 2 - 1));
+                    R = G = B = v - C;
+
+                    h = ~~h;
+                    R += [C, X, 0, 0, X, C][h];
+                    G += [X, C, C, X, 0, 0][h];
+                    B += [0, 0, X, C, C, X][h];
+                    return packageRGB(R, G, B, o);
+                };
+                /*
+                 * \ Snap.hsl2rgb [ method ] * Converts HSL values to an RGB object - h (number)
+                 * hue - s (number) saturation - l (number) luminosity = (object) RGB object in
+                 * the following format: o { o r (number) red, o g (number) green, o b (number)
+                 * blue, o hex (string) color in HTML/CSS format:
+                 * #•••••• o } \
+                 */
+                Snap.hsl2rgb = function(h, s, l, o) {
+                    if (is(h, "object") && "h" in h && "s" in h && "l" in h) {
+                        l = h.l;
+                        s = h.s;
+                        h = h.h;
+                    }
+                    if (h > 1 || s > 1 || l > 1) {
+                        h /= 360;
+                        s /= 100;
+                        l /= 100;
+                    }
+                    h *= 360;
+                    var R, G, B, X, C;
+                    h = (h % 360) / 60;
+                    C = 2 * s * (l < .5 ? l : 1 - l);
+                    X = C * (1 - abs(h % 2 - 1));
+                    R = G = B = l - C / 2;
+
+                    h = ~~h;
+                    R += [C, X, 0, 0, X, C][h];
+                    G += [X, C, C, X, 0, 0][h];
+                    B += [0, 0, X, C, C, X][h];
+                    return packageRGB(R, G, B, o);
+                };
+                /*
+                 * \ Snap.rgb2hsb [ method ] * Converts RGB values to an HSB object - r (number)
+                 * red - g (number) green - b (number) blue = (object) HSB object in the
+                 * following format: o { o h (number) hue, o s (number) saturation, o b (number)
+                 * brightness o } \
+                 */
+                Snap.rgb2hsb = function(r, g, b) {
+                    b = prepareRGB(r, g, b);
+                    r = b[0];
+                    g = b[1];
+                    b = b[2];
+
+                    var H, S, V, C;
+                    V = mmax(r, g, b);
+                    C = V - mmin(r, g, b);
+                    H = (C == 0 ? null :
+                        V == r ? (g - b) / C :
+                        V == g ? (b - r) / C + 2 :
+                        (r - g) / C + 4
+                    );
+                    H = ((H + 360) % 6) * 60 / 360;
+                    S = C == 0 ? 0 : C / V;
+                    return {
+                        h: H,
+                        s: S,
+                        b: V,
+                        toString: hsbtoString
+                    };
+                };
+                /*
+                 * \ Snap.rgb2hsl [ method ] * Converts RGB values to an HSL object - r (number)
+                 * red - g (number) green - b (number) blue = (object) HSL object in the
+                 * following format: o { o h (number) hue, o s (number) saturation, o l (number)
+                 * luminosity o } \
+                 */
+                Snap.rgb2hsl = function(r, g, b) {
+                    b = prepareRGB(r, g, b);
+                    r = b[0];
+                    g = b[1];
+                    b = b[2];
+
+                    var H, S, L, M, m, C;
+                    M = mmax(r, g, b);
+                    m = mmin(r, g, b);
+                    C = M - m;
+                    H = (C == 0 ? null :
+                        M == r ? (g - b) / C :
+                        M == g ? (b - r) / C + 2 :
+                        (r - g) / C + 4);
+                    H = ((H + 360) % 6) * 60 / 360;
+                    L = (M + m) / 2;
+                    S = (C == 0 ? 0 :
+                        L < .5 ? C / (2 * L) :
+                        C / (2 - 2 * L));
+                    return {
+                        h: H,
+                        s: S,
+                        l: L,
+                        toString: hsltoString
+                    };
+                };
+
+                // Transformations
+                // SIERRA Snap.parsePathString(): By _array of arrays,_ I assume you mean a
+                // format like this for two separate segments? [ ["M10,10","L90,90"],
+                // ["M90,10","L10,90"] ] Otherwise how is each command structured?
+                /*
+                 * \ Snap.parsePathString [ method ] * Utility method * Parses given path string
+                 * into an array of arrays of path segments - pathString (string|array) path
+                 * string or array of segments (in the last case it is returned straight away) =
+                 * (array) array of segments \
+                 */
+                Snap.parsePathString = function(pathString) {
+                    if (!pathString) {
+                        return null;
+                    }
+                    var pth = Snap.path(pathString);
+                    if (pth.arr) {
+                        return Snap.path.clone(pth.arr);
+                    }
+
+                    var paramCounts = {
+                            a: 7,
+                            c: 6,
+                            o: 2,
+                            h: 1,
+                            l: 2,
+                            m: 2,
+                            r: 4,
+                            q: 4,
+                            s: 4,
+                            t: 2,
+                            v: 1,
+                            u: 3,
+                            z: 0
+                        },
+                        data = [];
+                    if (is(pathString, "array") && is(pathString[0], "array")) { // rough
+                        // assumption
+                        data = Snap.path.clone(pathString);
+                    }
+                    if (!data.length) {
+                        Str(pathString).replace(pathCommand, function(a, b, c) {
+                            var params = [],
+                                name = b.toLowerCase();
+                            c.replace(pathValues, function(a, b) {
+                                b && params.push(+b);
+                            });
+                            if (name == "m" && params.length > 2) {
+                                data.push([b].concat(params.splice(0, 2)));
+                                name = "l";
+                                b = b == "m" ? "l" : "L";
+                            }
+                            if (name == "o" && params.length == 1) {
+                                data.push([b, params[0]]);
+                            }
+                            if (name == "r") {
+                                data.push([b].concat(params));
+                            } else
+                                while (params.length >= paramCounts[name]) {
+                                    data.push([b].concat(params.splice(0, paramCounts[name])));
+                                    if (!paramCounts[name]) {
+                                        break;
+                                    }
+                                }
+                        });
+                    }
+                    data.toString = Snap.path.toString;
+                    pth.arr = Snap.path.clone(data);
+                    return data;
+                };
+                /*
+                 * \ Snap.parseTransformString [ method ] * Utility method * Parses given
+                 * transform string into an array of transformations - TString (string|array)
+                 * transform string or array of transformations (in the last case it is returned
+                 * straight away) = (array) array of transformations \
+                 */
+                var parseTransformString = Snap.parseTransformString = function(TString) {
+                    if (!TString) {
+                        return null;
+                    }
+                    var paramCounts = {
+                            r: 3,
+                            s: 4,
+                            t: 2,
+                            m: 6
+                        },
+                        data = [];
+                    if (is(TString, "array") && is(TString[0], "array")) { // rough assumption
+                        data = Snap.path.clone(TString);
+                    }
+                    if (!data.length) {
+                        Str(TString).replace(tCommand, function(a, b, c) {
+                            var params = [],
+                                name = b.toLowerCase();
+                            c.replace(pathValues, function(a, b) {
+                                b && params.push(+b);
+                            });
+                            data.push([b].concat(params));
+                        });
+                    }
+                    data.toString = Snap.path.toString;
+                    return data;
+                };
+
+                function svgTransform2string(tstr) {
+                    var res = [];
+                    tstr = tstr.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g, function(all, name, params) {
+                        params = params.split(/\s*,\s*|\s+/);
+                        if (name == "rotate" && params.length == 1) {
+                            params.push(0, 0);
+                        }
+                        if (name == "scale") {
+                            if (params.length > 2) {
+                                params = params.slice(0, 2);
+                            } else if (params.length == 2) {
+                                params.push(0, 0);
+                            }
+                            if (params.length == 1) {
+                                params.push(params[0], 0, 0);
+                            }
+                        }
+                        if (name == "skewX") {
+                            res.push(["m", 1, 0, math.tan(rad(params[0])), 1, 0, 0]);
+                        } else if (name == "skewY") {
+                            res.push(["m", 1, math.tan(rad(params[0])), 0, 1, 0, 0]);
+                        } else {
+                            res.push([name.charAt(0)].concat(params));
+                        }
+                        return all;
+                    });
+                    return res;
+                }
+                Snap._.svgTransform2string = svgTransform2string;
+                Snap._.rgTransform = /^[a-z][\s]*-?\.?\d/i;
+
+                function transform2matrix(tstr, bbox) {
+                    var tdata = parseTransformString(tstr),
+                        m = new Snap.Matrix;
+                    if (tdata) {
+                        for (var i = 0, ii = tdata.length; i < ii; i++) {
+                            var t = tdata[i],
+                                tlen = t.length,
+                                command = Str(t[0]).toLowerCase(),
+                                absolute = t[0] != command,
+                                inver = absolute ? m.invert() : 0,
+                                x1,
+                                y1,
+                                x2,
+                                y2,
+                                bb;
+                            if (command == "t" && tlen == 2) {
+                                m.translate(t[1], 0);
+                            } else if (command == "t" && tlen == 3) {
+                                if (absolute) {
+                                    x1 = inver.x(0, 0);
+                                    y1 = inver.y(0, 0);
+                                    x2 = inver.x(t[1], t[2]);
+                                    y2 = inver.y(t[1], t[2]);
+                                    m.translate(x2 - x1, y2 - y1);
+                                } else {
+                                    m.translate(t[1], t[2]);
+                                }
+                            } else if (command == "r") {
+                                if (tlen == 2) {
+                                    bb = bb || bbox;
+                                    m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);
+                                } else if (tlen == 4) {
+                                    if (absolute) {
+                                        x2 = inver.x(t[2], t[3]);
+                                        y2 = inver.y(t[2], t[3]);
+                                        m.rotate(t[1], x2, y2);
+                                    } else {
+                                        m.rotate(t[1], t[2], t[3]);
+                                    }
+                                }
+                            } else if (command == "s") {
+                                if (tlen == 2 || tlen == 3) {
+                                    bb = bb || bbox;
+                                    m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);
+                                } else if (tlen == 4) {
+                                    if (absolute) {
+                                        x2 = inver.x(t[2], t[3]);
+                                        y2 = inver.y(t[2], t[3]);
+                                        m.scale(t[1], t[1], x2, y2);
+                                    } else {
+                                        m.scale(t[1], t[1], t[2], t[3]);
+                                    }
+                                } else if (tlen == 5) {
+                                    if (absolute) {
+                                        x2 = inver.x(t[3], t[4]);
+                                        y2 = inver.y(t[3], t[4]);
+                                        m.scale(t[1], t[2], x2, y2);
+                                    } else {
+                                        m.scale(t[1], t[2], t[3], t[4]);
+                                    }
+                                }
+                            } else if (command == "m" && tlen == 7) {
+                                m.add(t[1], t[2], t[3], t[4], t[5], t[6]);
+                            }
+                        }
+                    }
+                    return m;
+                }
+                Snap._.transform2matrix = transform2matrix;
+                Snap._unit2px = unit2px;
+                var contains = glob.doc.contains || glob.doc.compareDocumentPosition ?
+                    function(a, b) {
+                        var adown = a.nodeType == 9 ? a.documentElement : a,
+                            bup = b && b.parentNode;
+                        return a == bup || !!(bup && bup.nodeType == 1 && (
+                            adown.contains ?
+                            adown.contains(bup) :
+                            a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
+                        ));
+                    } :
+                    function(a, b) {
+                        if (b) {
+                            while (b) {
+                                b = b.parentNode;
+                                if (b == a) {
+                                    return true;
+                                }
+                            }
+                        }
+                        return false;
+                    };
+
+                function getSomeDefs(el) {
+                    var p = (el.node.ownerSVGElement && wrap(el.node.ownerSVGElement)) ||
+                        (el.node.parentNode && wrap(el.node.parentNode)) ||
+                        Snap.select("svg") ||
+                        Snap(0, 0),
+                        pdefs = p.select("defs"),
+                        defs = pdefs == null ? false : pdefs.node;
+                    if (!defs) {
+                        defs = make("defs", p.node).node;
+                    }
+                    return defs;
+                }
+
+                function getSomeSVG(el) {
+                    return el.node.ownerSVGElement && wrap(el.node.ownerSVGElement) || Snap.select("svg");
+                }
+                Snap._.getSomeDefs = getSomeDefs;
+                Snap._.getSomeSVG = getSomeSVG;
+
+                function unit2px(el, name, value) {
+                    var svg = getSomeSVG(el).node,
+                        out = {},
+                        mgr = svg.querySelector(".svg---mgr");
+                    if (!mgr) {
+                        mgr = $("rect");
+                        $(mgr, {
+                            x: -9e9,
+                            y: -9e9,
+                            width: 10,
+                            height: 10,
+                            "class": "svg---mgr",
+                            fill: "none"
+                        });
+                        svg.appendChild(mgr);
+                    }
+
+                    function getW(val) {
+                        if (val == null) {
+                            return E;
+                        }
+                        if (val == +val) {
+                            return val;
+                        }
+                        $(mgr, {
+                            width: val
+                        });
+                        try {
+                            return mgr.getBBox().width;
+                        } catch (e) {
+                            return 0;
+                        }
+                    }
+
+                    function getH(val) {
+                        if (val == null) {
+                            return E;
+                        }
+                        if (val == +val) {
+                            return val;
+                        }
+                        $(mgr, {
+                            height: val
+                        });
+                        try {
+                            return mgr.getBBox().height;
+                        } catch (e) {
+                            return 0;
+                        }
+                    }
+
+                    function set(nam, f) {
+                        if (name == null) {
+                            out[nam] = f(el.attr(nam) || 0);
+                        } else if (nam == name) {
+                            out = f(value == null ? el.attr(nam) || 0 : value);
+                        }
+                    }
+                    switch (el.type) {
+                        case "rect":
+                            set("rx", getW);
+                            set("ry", getH);
+                        case "image":
+                            set("width", getW);
+                            set("height", getH);
+                        case "text":
+                            set("x", getW);
+                            set("y", getH);
+                            break;
+                        case "circle":
+                            set("cx", getW);
+                            set("cy", getH);
+                            set("r", getW);
+                            break;
+                        case "ellipse":
+                            set("cx", getW);
+                            set("cy", getH);
+                            set("rx", getW);
+                            set("ry", getH);
+                            break;
+                        case "line":
+                            set("x1", getW);
+                            set("x2", getW);
+                            set("y1", getH);
+                            set("y2", getH);
+                            break;
+                        case "marker":
+                            set("refX", getW);
+                            set("markerWidth", getW);
+                            set("refY", getH);
+                            set("markerHeight", getH);
+                            break;
+                        case "radialGradient":
+                            set("fx", getW);
+                            set("fy", getH);
+                            break;
+                        case "tspan":
+                            set("dx", getW);
+                            set("dy", getH);
+                            break;
+                        default:
+                            set(name, getW);
+                    }
+                    svg.removeChild(mgr);
+                    return out;
+                }
+                /*
+                 * \ Snap.select [ method ] * Wraps a DOM element specified by CSS selector as
+                 * @Element - query (string) CSS selector of the element = (Element) the current
+                 * element \
+                 */
+                Snap.select = function(query) {
+                    query = Str(query).replace(/([^\\]):/g, "$1\\:");
+                    return wrap(glob.doc.querySelector(query));
+                };
+                /*
+                 * \ Snap.selectAll [ method ] * Wraps DOM elements specified by CSS selector as
+                 * set or array of @Element - query (string) CSS selector of the element =
+                 * (Element) the current element \
+                 */
+                Snap.selectAll = function(query) {
+                    var nodelist = glob.doc.querySelectorAll(query),
+                        set = (Snap.set || Array)();
+                    for (var i = 0; i < nodelist.length; i++) {
+                        set.push(wrap(nodelist[i]));
+                    }
+                    return set;
+                };
+
+                function add2group(list) {
+                    if (!is(list, "array")) {
+                        list = Array.prototype.slice.call(arguments, 0);
+                    }
+                    var i = 0,
+                        j = 0,
+                        node = this.node;
+                    while (this[i]) delete this[i++];
+                    for (i = 0; i < list.length; i++) {
+                        if (list[i].type == "set") {
+                            list[i].forEach(function(el) {
+                                node.appendChild(el.node);
+                            });
+                        } else {
+                            node.appendChild(list[i].node);
+                        }
+                    }
+                    var children = node.childNodes;
+                    for (i = 0; i < children.length; i++) {
+                        this[j++] = wrap(children[i]);
+                    }
+                    return this;
+                }
+                // Hub garbage collector every 10s
+                setInterval(function() {
+                    for (var key in hub)
+                        if (hub[has](key)) {
+                            var el = hub[key],
+                                node = el.node;
+                            if (el.type != "svg" && !node.ownerSVGElement || el.type == "svg" && (!node.parentNode || "ownerSVGElement" in node.parentNode && !node.ownerSVGElement)) {
+                                delete hub[key];
+                            }
+                        }
+                }, 1e4);
+
+                function Element(el) {
+                    if (el.snap in hub) {
+                        return hub[el.snap];
+                    }
+                    var svg;
+                    try {
+                        svg = el.ownerSVGElement;
+                    } catch (e) {}
+                    /*
+                     * \ Element.node [ property (object) ] * Gives you a reference to the DOM
+                     * object, so you can assign event handlers or just mess around. > Usage | //
+                     * draw a circle at coordinate 10,10 with radius of 10 | var c =
+                     * paper.circle(10, 10, 10); | c.node.onclick = function () { |
+                     * c.attr("fill", "red"); | }; \
+                     */
+                    this.node = el;
+                    if (svg) {
+                        this.paper = new Paper(svg);
+                    }
+                    /*
+                     * \ Element.type [ property (string) ] * SVG tag name of the given element. \
+                     */
+                    this.type = el.tagName;
+                    var id = this.id = ID(this);
+                    this.anims = {};
+                    this._ = {
+                        transform: []
+                    };
+                    el.snap = id;
+                    hub[id] = this;
+                    if (this.type == "g") {
+                        this.add = add2group;
+                    }
+                    if (this.type in {
+                            g: 1,
+                            mask: 1,
+                            pattern: 1,
+                            symbol: 1
+                        }) {
+                        for (var method in Paper.prototype)
+                            if (Paper.prototype[has](method)) {
+                                this[method] = Paper.prototype[method];
+                            }
+                    }
+                }
+                /*
+                 * \ Element.attr [ method ] * Gets or sets given attributes of the element. * -
+                 * params (object) contains key-value pairs of attributes you want to set or -
+                 * param (string) name of the attribute = (Element) the current element or =
+                 * (string) value of attribute > Usage | el.attr({ | fill: "#fc0", | stroke:
+                 * "#000", | strokeWidth: 2, // CamelCase... | "fill-opacity": 0.5, // or
+                 * dash-separated names | width: "*=2" // prefixed values | }); |
+                 * console.log(el.attr("fill")); // #fc0 Prefixed values in format `"+=10"`
+                 * supported. All four operations (`+`, `-`, `*` and `/`) could be used.
+                 * Optionally you can use units for `+` and `-`: `"+=2em"`. \
+                 */
+                Element.prototype.attr = function(params, value) {
+                    var el = this,
+                        node = el.node;
+                    if (!params) {
+                        return el;
+                    }
+                    if (is(params, "string")) {
+                        if (arguments.length > 1) {
+                            var json = {};
+                            json[params] = value;
+                            params = json;
+                        } else {
+                            return eve("snap.util.getattr." + params, el).firstDefined();
+                        }
+                    }
+                    for (var att in params) {
+                        if (params[has](att)) {
+                            eve("snap.util.attr." + att, el, params[att]);
+                        }
+                    }
+                    return el;
+                };
+                /*
+                 * \ Snap.parse [ method ] * Parses SVG fragment and converts it into a
+                 * @Fragment * - svg (string) SVG string = (Fragment) the @Fragment \
+                 */
+                Snap.parse = function(svg) {
+                    var f = glob.doc.createDocumentFragment(),
+                        full = true,
+                        div = glob.doc.createElement("div");
+                    svg = Str(svg);
+                    if (!svg.match(/^\s*<\s*svg(?:\s|>)/)) {
+                        svg = "<svg>" + svg + "</svg>";
+                        full = false;
+                    }
+                    div.innerHTML = svg;
+                    svg = div.getElementsByTagName("svg")[0];
+                    if (svg) {
+                        if (full) {
+                            f = svg;
+                        } else {
+                            while (svg.firstChild) {
+                                f.appendChild(svg.firstChild);
+                            }
+                            div.innerHTML = E;
+                        }
+                    }
+                    return new Fragment(f);
+                };
+
+                function Fragment(frag) {
+                    this.node = frag;
+                }
+                // SIERRA Snap.fragment() could especially use a code example
+                /*
+                 * \ Snap.fragment [ method ] * Creates a DOM fragment from a given list of
+                 * elements or strings * - varargs (…) SVG string = (Fragment) the
+                 * @Fragment \
+                 */
+                Snap.fragment = function() {
+                    var args = Array.prototype.slice.call(arguments, 0),
+                        f = glob.doc.createDocumentFragment();
+                    for (var i = 0, ii = args.length; i < ii; i++) {
+                        var item = args[i];
+                        if (item.node && item.node.nodeType) {
+                            f.appendChild(item.node);
+                        }
+                        if (item.nodeType) {
+                            f.appendChild(item);
+                        }
+                        if (typeof item == "string") {
+                            f.appendChild(Snap.parse(item).node);
+                        }
+                    }
+                    return new Fragment(f);
+                };
+
+                function make(name, parent) {
+                    var res = $(name);
+                    parent.appendChild(res);
+                    var el = wrap(res);
+                    return el;
+                }
+
+                function Paper(w, h) {
+                    var res,
+                        desc,
+                        defs,
+                        proto = Paper.prototype;
+                    if (w && w.tagName == "svg") {
+                        if (w.snap in hub) {
+                            return hub[w.snap];
+                        }
+                        var doc = w.ownerDocument;
+                        res = new Element(w);
+                        desc = w.getElementsByTagName("desc")[0];
+                        defs = w.getElementsByTagName("defs")[0];
+                        if (!desc) {
+                            desc = $("desc");
+                            desc.appendChild(doc.createTextNode("Created with Snap"));
+                            res.node.appendChild(desc);
+                        }
+                        if (!defs) {
+                            defs = $("defs");
+                            res.node.appendChild(defs);
+                        }
+                        res.defs = defs;
+                        for (var key in proto)
+                            if (proto[has](key)) {
+                                res[key] = proto[key];
+                            }
+                        res.paper = res.root = res;
+                    } else {
+                        res = make("svg", glob.doc.body);
+                        $(res.node, {
+                            height: h,
+                            version: 1.1,
+                            width: w,
+                            xmlns: xmlns
+                        });
+                    }
+                    return res;
+                }
+
+                function wrap(dom) {
+                    if (!dom) {
+                        return dom;
+                    }
+                    if (dom instanceof Element || dom instanceof Fragment) {
+                        return dom;
+                    }
+                    if (dom.tagName && dom.tagName.toLowerCase() == "svg") {
+                        return new Paper(dom);
+                    }
+                    if (dom.tagName && dom.tagName.toLowerCase() == "object" && dom.type == "image/svg+xml") {
+                        return new Paper(dom.contentDocument.getElementsByTagName("svg")[0]);
+                    }
+                    return new Element(dom);
+                }
+
+                Snap._.make = make;
+                Snap._.wrap = wrap;
+                /*
+                 * \ Paper.el [ method ] * Creates an element on paper with a given name and no
+                 * attributes * - name (string) tag name - attr (object) attributes = (Element)
+                 * the current element > Usage | var c = paper.circle(10, 10, 10); // is the
+                 * same as... | var c = paper.el("circle").attr({ | cx: 10, | cy: 10, | r: 10 |
+                 * }); | // and the same as | var c = paper.el("circle", { | cx: 10, | cy: 10, |
+                 * r: 10 | }); \
+                 */
+                Paper.prototype.el = function(name, attr) {
+                    var el = make(name, this.node);
+                    attr && el.attr(attr);
+                    return el;
+                };
+                // default
+                eve.on("snap.util.getattr", function() {
+                    var att = eve.nt();
+                    att = att.substring(att.lastIndexOf(".") + 1);
+                    var css = att.replace(/[A-Z]/g, function(letter) {
+                        return "-" + letter.toLowerCase();
+                    });
+                    if (cssAttr[has](css)) {
+                        return this.node.ownerDocument.defaultView.getComputedStyle(this.node, null).getPropertyValue(css);
+                    } else {
+                        return $(this.node, att);
+                    }
+                });
+                var cssAttr = {
+                    "alignment-baseline": 0,
+                    "baseline-shift": 0,
+                    "clip": 0,
+                    "clip-path": 0,
+                    "clip-rule": 0,
+                    "color": 0,
+                    "color-interpolation": 0,
+                    "color-interpolation-filters": 0,
+                    "color-profile": 0,
+                    "color-rendering": 0,
+                    "cursor": 0,
+                    "direction": 0,
+                    "display": 0,
+                    "dominant-baseline": 0,
+                    "enable-background": 0,
+                    "fill": 0,
+                    "fill-opacity": 0,
+                    "fill-rule": 0,
+                    "filter": 0,
+                    "flood-color": 0,
+                    "flood-opacity": 0,
+                    "font": 0,
+                    "font-family": 0,
+                    "font-size": 0,
+                    "font-size-adjust": 0,
+                    "font-stretch": 0,
+                    "font-style": 0,
+                    "font-variant": 0,
+                    "font-weight": 0,
+                    "glyph-orientation-horizontal": 0,
+                    "glyph-orientation-vertical": 0,
+                    "image-rendering": 0,
+                    "kerning": 0,
+                    "letter-spacing": 0,
+                    "lighting-color": 0,
+                    "marker": 0,
+                    "marker-end": 0,
+                    "marker-mid": 0,
+                    "marker-start": 0,
+                    "mask": 0,
+                    "opacity": 0,
+                    "overflow": 0,
+                    "pointer-events": 0,
+                    "shape-rendering": 0,
+                    "stop-color": 0,
+                    "stop-opacity": 0,
+                    "stroke": 0,
+                    "stroke-dasharray": 0,
+                    "stroke-dashoffset": 0,
+                    "stroke-linecap": 0,
+                    "stroke-linejoin": 0,
+                    "stroke-miterlimit": 0,
+                    "stroke-opacity": 0,
+                    "stroke-width": 0,
+                    "text-anchor": 0,
+                    "text-decoration": 0,
+                    "text-rendering": 0,
+                    "unicode-bidi": 0,
+                    "visibility": 0,
+                    "word-spacing": 0,
+                    "writing-mode": 0
+                };
+
+                eve.on("snap.util.attr", function(value) {
+                    var att = eve.nt(),
+                        attr = {};
+                    att = att.substring(att.lastIndexOf(".") + 1);
+                    attr[att] = value;
+                    var style = att.replace(/-(\w)/gi, function(all, letter) {
+                            return letter.toUpperCase();
+                        }),
+                        css = att.replace(/[A-Z]/g, function(letter) {
+                            return "-" + letter.toLowerCase();
+                        });
+                    if (cssAttr[has](css)) {
+                        this.node.style[style] = value == null ? E : value;
+                    } else {
+                        $(this.node, attr);
+                    }
+                });
+                (function(proto) {}(Paper.prototype));
+
+                // simple ajax
+                /*
+                 * \ Snap.ajax [ method ] * Simple implementation of Ajax * - url (string) URL -
+                 * postData (object|string) data for post request - callback (function) callback -
+                 * scope (object) #optional scope of callback or - url (string) URL - callback
+                 * (function) callback - scope (object) #optional scope of callback =
+                 * (XMLHttpRequest) the XMLHttpRequest object, just in case \
+                 */
+                Snap.ajax = function(url, postData, callback, scope) {
+                    var req = new XMLHttpRequest,
+                        id = ID();
+                    if (req) {
+                        if (is(postData, "function")) {
+                            scope = callback;
+                            callback = postData;
+                            postData = null;
+                        } else if (is(postData, "object")) {
+                            var pd = [];
+                            for (var key in postData)
+                                if (postData.hasOwnProperty(key)) {
+                                    pd.push(encodeURIComponent(key) + "=" + encodeURIComponent(postData[key]));
+                                }
+                            postData = pd.join("&");
+                        }
+                        req.open((postData ? "POST" : "GET"), url, true);
+                        if (postData) {
+                            req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+                            req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+                        }
+                        if (callback) {
+                            eve.once("snap.ajax." + id + ".0", callback);
+                            eve.once("snap.ajax." + id + ".200", callback);
+                            eve.once("snap.ajax." + id + ".304", callback);
+                        }
+                        req.onreadystatechange = function() {
+                            if (req.readyState != 4) return;
+                            eve("snap.ajax." + id + "." + req.status, scope, req);
+                        };
+                        if (req.readyState == 4) {
+                            return req;
+                        }
+                        req.send(postData);
+                        return req;
+                    }
+                };
+                /*
+                 * \ Snap.load [ method ] * Loads external SVG file as a @Fragment (see
+                 * @Snap.ajax for more advanced AJAX) * - url (string) URL - callback (function)
+                 * callback - scope (object) #optional scope of callback \
+                 */
+                Snap.load = function(url, callback, scope) {
+                    Snap.ajax(url, function(req) {
+                        var f = Snap.parse(req.responseText);
+                        scope ? callback.call(scope, f) : callback(f);
+                    });
+                };
+                var getOffset = function(elem) {
+                    var box = elem.getBoundingClientRect(),
+                        doc = elem.ownerDocument,
+                        body = doc.body,
+                        docElem = doc.documentElement,
+                        clientTop = docElem.clientTop || body.clientTop || 0,
+                        clientLeft = docElem.clientLeft || body.clientLeft || 0,
+                        top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop) - clientTop,
+                        left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;
+                    return {
+                        y: top,
+                        x: left
+                    };
+                };
+                /*
+                 * \ Snap.getElementByPoint [ method ] * Returns you topmost element under given
+                 * point. * = (object) Snap element object - x (number) x coordinate from the
+                 * top left corner of the window - y (number) y coordinate from the top left
+                 * corner of the window > Usage | Snap.getElementByPoint(mouseX,
+                 * mouseY).attr({stroke: "#f00"}); \
+                 */
+                Snap.getElementByPoint = function(x, y) {
+                    var paper = this,
+                        svg = paper.canvas,
+                        target = glob.doc.elementFromPoint(x, y);
+                    if (glob.win.opera && target.tagName == "svg") {
+                        var so = getOffset(target),
+                            sr = target.createSVGRect();
+                        sr.x = x - so.x;
+                        sr.y = y - so.y;
+                        sr.width = sr.height = 1;
+                        var hits = target.getIntersectionList(sr, null);
+                        if (hits.length) {
+                            target = hits[hits.length - 1];
+                        }
+                    }
+                    if (!target) {
+                        return null;
+                    }
+                    return wrap(target);
+                };
+                /*
+                 * \ Snap.plugin [ method ] * Let you write plugins. You pass in a function with
+                 * four arguments, like this: | Snap.plugin(function (Snap, Element, Paper,
+                 * global, Fragment) { | Snap.newmethod = function () {}; |
+                 * Element.prototype.newmethod = function () {}; | Paper.prototype.newmethod =
+                 * function () {}; | }); Inside the function you have access to all main objects
+                 * (and their prototypes). This allow you to extend anything you want. * - f
+                 * (function) your plugin body \
+                 */
+                Snap.plugin = function(f) {
+                    f(Snap, Element, Paper, glob, Fragment);
+                };
+                glob.win.Snap = Snap;
+                return Snap;
+            }(window || this));
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            //
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            //
+            // http://www.apache.org/licenses/LICENSE-2.0
+            //
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob, Fragment) {
+                var elproto = Element.prototype,
+                    is = Snap.is,
+                    Str = String,
+                    unit2px = Snap._unit2px,
+                    $ = Snap._.$,
+                    make = Snap._.make,
+                    getSomeDefs = Snap._.getSomeDefs,
+                    has = "hasOwnProperty",
+                    wrap = Snap._.wrap;
+                /*
+                 * \ Element.getBBox [ method ] * Returns the bounding box descriptor for
+                 * the given element * = (object) bounding box descriptor: o { o cx:
+                 * (number) x of the center, o cy: (number) x of the center, o h: (number)
+                 * height, o height: (number) height, o path: (string) path command for the
+                 * box, o r0: (number) radius of a circle that fully encloses the box, o r1:
+                 * (number) radius of the smallest circle that can be enclosed, o r2:
+                 * (number) radius of the largest circle that can be enclosed, o vb:
+                 * (string) box as a viewbox command, o w: (number) width, o width: (number)
+                 * width, o x2: (number) x of the right side, o x: (number) x of the left
+                 * side, o y2: (number) y of the bottom edge, o y: (number) y of the top
+                 * edge o } \
+                 */
+                elproto.getBBox = function(isWithoutTransform) {
+                    if (!Snap.Matrix || !Snap.path) {
+                        return this.node.getBBox();
+                    }
+                    var el = this,
+                        m = new Snap.Matrix;
+                    if (el.removed) {
+                        return Snap._.box();
+                    }
+                    while (el.type == "use") {
+                        if (!isWithoutTransform) {
+                            m = m.add(el.transform().localMatrix.translate(el.attr("x") || 0, el.attr("y") || 0));
+                        }
+                        if (el.original) {
+                            el = el.original;
+                        } else {
+                            var href = el.attr("xlink:href");
+                            el = el.original = el.node.ownerDocument.getElementById(href.substring(href.indexOf("#") + 1));
+                        }
+                    }
+                    var _ = el._,
+                        pathfinder = Snap.path.get[el.type] || Snap.path.get.deflt;
+                    try {
+                        if (isWithoutTransform) {
+                            _.bboxwt = pathfinder ? Snap.path.getBBox(el.realPath = pathfinder(el)) : Snap._.box(el.node.getBBox());
+                            return Snap._.box(_.bboxwt);
+                        } else {
+                            el.realPath = pathfinder(el);
+                            el.matrix = el.transform().localMatrix;
+                            _.bbox = Snap.path.getBBox(Snap.path.map(el.realPath, m.add(el.matrix)));
+                            return Snap._.box(_.bbox);
+                        }
+                    } catch (e) {
+                        // Firefox doesn’t give you bbox of hidden element
+                        return Snap._.box();
+                    }
+                };
+                var propString = function() {
+                    return this.string;
+                };
+
+                function extractTransform(el, tstr) {
+                    if (tstr == null) {
+                        var doReturn = true;
+                        if (el.type == "linearGradient" || el.type == "radialGradient") {
+                            tstr = el.node.getAttribute("gradientTransform");
+                        } else if (el.type == "pattern") {
+                            tstr = el.node.getAttribute("patternTransform");
+                        } else {
+                            tstr = el.node.getAttribute("transform");
+                        }
+                        if (!tstr) {
+                            return new Snap.Matrix;
+                        }
+                        tstr = Snap._.svgTransform2string(tstr);
+                    } else {
+                        if (!Snap._.rgTransform.test(tstr)) {
+                            tstr = Snap._.svgTransform2string(tstr);
+                        } else {
+                            tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
+                        }
+                        if (is(tstr, "array")) {
+                            tstr = Snap.path ? Snap.path.toString.call(tstr) : Str(tstr);
+                        }
+                        el._.transform = tstr;
+                    }
+                    var m = Snap._.transform2matrix(tstr, el.getBBox(1));
+                    if (doReturn) {
+                        return m;
+                    } else {
+                        el.matrix = m;
+                    }
+                }
+                /*
+                 * \ Element.transform [ method ] * Gets or sets transformation of the
+                 * element * - tstr (string) transform string in Snap or SVG format =
+                 * (Element) the current element or = (object) transformation descriptor: o {
+                 * o string (string) transform string, o globalMatrix (Matrix) matrix of all
+                 * transformations applied to element or its parents, o localMatrix (Matrix)
+                 * matrix of transformations applied only to the element, o diffMatrix
+                 * (Matrix) matrix of difference between global and local transformations, o
+                 * global (string) global transformation as string, o local (string) local
+                 * transformation as string, o toString (function) returns `string` property
+                 * o } \
+                 */
+                elproto.transform = function(tstr) {
+                    var _ = this._;
+                    if (tstr == null) {
+                        var papa = this,
+                            global = new Snap.Matrix(this.node.getCTM()),
+                            local = extractTransform(this),
+                            ms = [local],
+                            m = new Snap.Matrix,
+                            i,
+                            localString = local.toTransformString(),
+                            string = Str(local) == Str(this.matrix) ?
+                            Str(_.transform) : localString;
+                        while (papa.type != "svg" && (papa = papa.parent())) {
+                            ms.push(extractTransform(papa));
+                        }
+                        i = ms.length;
+                        while (i--) {
+                            m.add(ms[i]);
+                        }
+                        return {
+                            string: string,
+                            globalMatrix: global,
+                            totalMatrix: m,
+                            localMatrix: local,
+                            diffMatrix: global.clone().add(local.invert()),
+                            global: global.toTransformString(),
+                            total: m.toTransformString(),
+                            local: localString,
+                            toString: propString
+                        };
+                    }
+                    if (tstr instanceof Snap.Matrix) {
+                        this.matrix = tstr;
+                        this._.transform = tstr.toTransformString();
+                    } else {
+                        extractTransform(this, tstr);
+                    }
+
+                    if (this.node) {
+                        if (this.type == "linearGradient" || this.type == "radialGradient") {
+                            $(this.node, {
+                                gradientTransform: this.matrix
+                            });
+                        } else if (this.type == "pattern") {
+                            $(this.node, {
+                                patternTransform: this.matrix
+                            });
+                        } else {
+                            $(this.node, {
+                                transform: this.matrix
+                            });
+                        }
+                    }
+
+                    return this;
+                };
+                /*
+                 * \ Element.parent [ method ] * Returns the element's parent * = (Element)
+                 * the parent element \
+                 */
+                elproto.parent = function() {
+                    return wrap(this.node.parentNode);
+                };
+                /*
+                 * \ Element.append [ method ] * Appends the given element to current one * -
+                 * el (Element|Set) element to append = (Element) the parent element \
+                 */
+                /*
+                 * \ Element.add [ method ] * See @Element.append \
+                 */
+                elproto.append = elproto.add = function(el) {
+                    if (el) {
+                        if (el.type == "set") {
+                            var it = this;
+                            el.forEach(function(el) {
+                                it.add(el);
+                            });
+                            return this;
+                        }
+                        el = wrap(el);
+                        this.node.appendChild(el.node);
+                        el.paper = this.paper;
+                    }
+                    return this;
+                };
+                /*
+                 * \ Element.appendTo [ method ] * Appends the current element to the given
+                 * one * - el (Element) parent element to append to = (Element) the child
+                 * element \
+                 */
+                elproto.appendTo = function(el) {
+                    if (el) {
+                        el = wrap(el);
+                        el.append(this);
+                    }
+                    return this;
+                };
+                /*
+                 * \ Element.prepend [ method ] * Prepends the given element to the current
+                 * one * - el (Element) element to prepend = (Element) the parent element \
+                 */
+                elproto.prepend = function(el) {
+                    if (el) {
+                        if (el.type == "set") {
+                            var it = this,
+                                first;
+                            el.forEach(function(el) {
+                                if (first) {
+                                    first.after(el);
+                                } else {
+                                    it.prepend(el);
+                                }
+                                first = el;
+                            });
+                            return this;
+                        }
+                        el = wrap(el);
+                        var parent = el.parent();
+                        this.node.insertBefore(el.node, this.node.firstChild);
+                        this.add && this.add();
+                        el.paper = this.paper;
+                        this.parent() && this.parent().add();
+                        parent && parent.add();
+                    }
+                    return this;
+                };
+                /*
+                 * \ Element.prependTo [ method ] * Prepends the current element to the
+                 * given one * - el (Element) parent element to prepend to = (Element) the
+                 * child element \
+                 */
+                elproto.prependTo = function(el) {
+                    el = wrap(el);
+                    el.prepend(this);
+                    return this;
+                };
+                /*
+                 * \ Element.before [ method ] * Inserts given element before the current
+                 * one * - el (Element) element to insert = (Element) the parent element \
+                 */
+                elproto.before = function(el) {
+                    if (el.type == "set") {
+                        var it = this;
+                        el.forEach(function(el) {
+                            var parent = el.parent();
+                            it.node.parentNode.insertBefore(el.node, it.node);
+                            parent && parent.add();
+                        });
+                        this.parent().add();
+                        return this;
+                    }
+                    el = wrap(el);
+                    var parent = el.parent();
+                    this.node.parentNode.insertBefore(el.node, this.node);
+                    this.parent() && this.parent().add();
+                    parent && parent.add();
+                    el.paper = this.paper;
+                    return this;
+                };
+                /*
+                 * \ Element.after [ method ] * Inserts given element after the current one * -
+                 * el (Element) element to insert = (Element) the parent element \
+                 */
+                elproto.after = function(el) {
+                    el = wrap(el);
+                    var parent = el.parent();
+                    if (this.node.nextSibling) {
+                        this.node.parentNode.insertBefore(el.node, this.node.nextSibling);
+                    } else {
+                        this.node.parentNode.appendChild(el.node);
+                    }
+                    this.parent() && this.parent().add();
+                    parent && parent.add();
+                    el.paper = this.paper;
+                    return this;
+                };
+                /*
+                 * \ Element.insertBefore [ method ] * Inserts the element after the given
+                 * one * - el (Element) element next to whom insert to = (Element) the
+                 * parent element \
+                 */
+                elproto.insertBefore = function(el) {
+                    el = wrap(el);
+                    var parent = this.parent();
+                    el.node.parentNode.insertBefore(this.node, el.node);
+                    this.paper = el.paper;
+                    parent && parent.add();
+                    el.parent() && el.parent().add();
+                    return this;
+                };
+                /*
+                 * \ Element.insertAfter [ method ] * Inserts the element after the given
+                 * one * - el (Element) element next to whom insert to = (Element) the
+                 * parent element \
+                 */
+                elproto.insertAfter = function(el) {
+                    el = wrap(el);
+                    var parent = this.parent();
+                    el.node.parentNode.insertBefore(this.node, el.node.nextSibling);
+                    this.paper = el.paper;
+                    parent && parent.add();
+                    el.parent() && el.parent().add();
+                    return this;
+                };
+                /*
+                 * \ Element.remove [ method ] * Removes element from the DOM = (Element)
+                 * the detached element \
+                 */
+                elproto.remove = function() {
+                    var parent = this.parent();
+                    this.node.parentNode && this.node.parentNode.removeChild(this.node);
+                    delete this.paper;
+                    this.removed = true;
+                    parent && parent.add();
+                    return this;
+                };
+                /*
+                 * \ Element.select [ method ] * Gathers the nested @Element matching the
+                 * given set of CSS selectors * - query (string) CSS selector = (Element)
+                 * result of query selection \
+                 */
+                elproto.select = function(query) {
+                    query = Str(query).replace(/([^\\]):/g, "$1\\:");
+                    return wrap(this.node.querySelector(query));
+                };
+                /*
+                 * \ Element.selectAll [ method ] * Gathers nested @Element objects matching
+                 * the given set of CSS selectors * - query (string) CSS selector =
+                 * (Set|array) result of query selection \
+                 */
+                elproto.selectAll = function(query) {
+                    var nodelist = this.node.querySelectorAll(query),
+                        set = (Snap.set || Array)();
+                    for (var i = 0; i < nodelist.length; i++) {
+                        set.push(wrap(nodelist[i]));
+                    }
+                    return set;
+                };
+                /*
+                 * \ Element.asPX [ method ] * Returns given attribute of the element as a
+                 * `px` value (not %, em, etc.) * - attr (string) attribute name - value
+                 * (string) #optional attribute value = (Element) result of query selection \
+                 */
+                elproto.asPX = function(attr, value) {
+                    if (value == null) {
+                        value = this.attr(attr);
+                    }
+                    return +unit2px(this, attr, value);
+                };
+                // SIERRA Element.use(): I suggest adding a note about how to access the
+                // original element the returned <use> instantiates. It's a part of SVG with
+                // which ordinary web developers may be least familiar.
+                /*
+                 * \ Element.use [ method ] * Creates a `<use>` element linked to the
+                 * current element * = (Element) the `<use>` element \
+                 */
+                elproto.use = function() {
+                    var use,
+                        id = this.node.id;
+                    if (!id) {
+                        id = this.id;
+                        $(this.node, {
+                            id: id
+                        });
+                    }
+                    if (this.type == "linearGradient" || this.type == "radialGradient" ||
+                        this.type == "pattern") {
+                        use = make(this.type, this.node.parentNode);
+                    } else {
+                        use = make("use", this.node.parentNode);
+                    }
+                    $(use.node, {
+                        "xlink:href": "#" + id
+                    });
+                    use.original = this;
+                    return use;
+                };
+
+                function fixids(el) {
+                    var els = el.selectAll("*"),
+                        it,
+                        url = /^\s*url\(("|'|)(.*)\1\)\s*$/,
+                        ids = [],
+                        uses = {};
+
+                    function urltest(it, name) {
+                        var val = $(it.node, name);
+                        val = val && val.match(url);
+                        val = val && val[2];
+                        if (val && val.charAt() == "#") {
+                            val = val.substring(1);
+                        } else {
+                            return;
+                        }
+                        if (val) {
+                            uses[val] = (uses[val] || []).concat(function(id) {
+                                var attr = {};
+                                attr[name] = URL(id);
+                                $(it.node, attr);
+                            });
+                        }
+                    }
+
+                    function linktest(it) {
+                        var val = $(it.node, "xlink:href");
+                        if (val && val.charAt() == "#") {
+                            val = val.substring(1);
+                        } else {
+                            return;
+                        }
+                        if (val) {
+                            uses[val] = (uses[val] || []).concat(function(id) {
+                                it.attr("xlink:href", "#" + id);
+                            });
+                        }
+                    }
+                    for (var i = 0, ii = els.length; i < ii; i++) {
+                        it = els[i];
+                        urltest(it, "fill");
+                        urltest(it, "stroke");
+                        urltest(it, "filter");
+                        urltest(it, "mask");
+                        urltest(it, "clip-path");
+                        linktest(it);
+                        var oldid = $(it.node, "id");
+                        if (oldid) {
+                            $(it.node, {
+                                id: it.id
+                            });
+                            ids.push({
+                                old: oldid,
+                                id: it.id
+                            });
+                        }
+                    }
+                    for (i = 0, ii = ids.length; i < ii; i++) {
+                        var fs = uses[ids[i].old];
+                        if (fs) {
+                            for (var j = 0, jj = fs.length; j < jj; j++) {
+                                fs[j](ids[i].id);
+                            }
+                        }
+                    }
+                }
+                /*
+                 * \ Element.clone [ method ] * Creates a clone of the element and inserts
+                 * it after the element * = (Element) the clone \
+                 */
+                elproto.clone = function() {
+                    var clone = wrap(this.node.cloneNode(true));
+                    if ($(clone.node, "id")) {
+                        $(clone.node, {
+                            id: clone.id
+                        });
+                    }
+                    fixids(clone);
+                    clone.insertAfter(this);
+                    return clone;
+                };
+                /*
+                 * \ Element.toDefs [ method ] * Moves element to the shared `<defs>` area * =
+                 * (Element) the element \
+                 */
+                elproto.toDefs = function() {
+                    var defs = getSomeDefs(this);
+                    defs.appendChild(this.node);
+                    return this;
+                };
+                /*
+                 * \ Element.toPattern [ method ] * Creates a `<pattern>` element from the
+                 * current element * To create a pattern you have to specify the pattern
+                 * rect: - x (string|number) - y (string|number) - width (string|number) -
+                 * height (string|number) = (Element) the `<pattern>` element You can use
+                 * pattern later on as an argument for `fill` attribute: | var p =
+                 * paper.path("M10-5-10,15M15,0,0,15M0-5-20,15").attr({ | fill: "none", |
+                 * stroke: "#bada55", | strokeWidth: 5 | }).pattern(0, 0, 10, 10), | c =
+                 * paper.circle(200, 200, 100); | c.attr({ | fill: p | }); \
+                 */
+                elproto.pattern = elproto.toPattern = function(x, y, width, height) {
+                    var p = make("pattern", getSomeDefs(this));
+                    if (x == null) {
+                        x = this.getBBox();
+                    }
+                    if (is(x, "object") && "x" in x) {
+                        y = x.y;
+                        width = x.width;
+                        height = x.height;
+                        x = x.x;
+                    }
+                    $(p.node, {
+                        x: x,
+                        y: y,
+                        width: width,
+                        height: height,
+                        patternUnits: "userSpaceOnUse",
+                        id: p.id,
+                        viewBox: [x, y, width, height].join(" ")
+                    });
+                    p.node.appendChild(this.node);
+                    return p;
+                };
+                // SIERRA Element.marker(): clarify what a reference point is. E.g., helps you
+                // offset the object from its edge such as when centering it over a path.
+                // SIERRA Element.marker(): I suggest the method should accept default reference
+                // point values. Perhaps centered with (refX = width/2) and (refY = height/2)?
+                // Also, couldn't it assume the element's current _width_ and _height_? And
+                // please specify what _x_ and _y_ mean: offsets? If so, from where? Couldn't
+                // they also be assigned default values?
+                /*
+                 * \ Element.marker [ method ] * Creates a `<marker>` element from the
+                 * current element * To create a marker you have to specify the bounding
+                 * rect and reference point: - x (number) - y (number) - width (number) -
+                 * height (number) - refX (number) - refY (number) = (Element) the `<marker>`
+                 * element You can specify the marker later as an argument for
+                 * `marker-start`, `marker-end`, `marker-mid`, and `marker` attributes. The
+                 * `marker` attribute places the marker at every point along the path, and
+                 * `marker-mid` places them at every point except the start and end. \
+                 */
+                // TODO add usage for markers
+                elproto.marker = function(x, y, width, height, refX, refY) {
+                    var p = make("marker", getSomeDefs(this));
+                    if (x == null) {
+                        x = this.getBBox();
+                    }
+                    if (is(x, "object") && "x" in x) {
+                        y = x.y;
+                        width = x.width;
+                        height = x.height;
+                        refX = x.refX || x.cx;
+                        refY = x.refY || x.cy;
+                        x = x.x;
+                    }
+                    $(p.node, {
+                        viewBox: [x, y, width, height].join(" "),
+                        markerWidth: width,
+                        markerHeight: height,
+                        orient: "auto",
+                        refX: refX || 0,
+                        refY: refY || 0,
+                        id: p.id
+                    });
+                    p.node.appendChild(this.node);
+                    return p;
+                };
+                // animation
+                function slice(from, to, f) {
+                    return function(arr) {
+                        var res = arr.slice(from, to);
+                        if (res.length == 1) {
+                            res = res[0];
+                        }
+                        return f ? f(res) : res;
+                    };
+                }
+                var Animation = function(attr, ms, easing, callback) {
+                    if (typeof easing == "function" && !easing.length) {
+                        callback = easing;
+                        easing = mina.linear;
+                    }
+                    this.attr = attr;
+                    this.dur = ms;
+                    easing && (this.easing = easing);
+                    callback && (this.callback = callback);
+                };
+                Snap._.Animation = Animation;
+                /*
+                 * \ Snap.animation [ method ] * Creates an animation object * - attr
+                 * (object) attributes of final destination - duration (number) duration of
+                 * the animation, in milliseconds - easing (function) #optional one of
+                 * easing functions of @mina or custom one - callback (function) #optional
+                 * callback function that fires when animation ends = (object) animation
+                 * object \
+                 */
+                Snap.animation = function(attr, ms, easing, callback) {
+                    return new Animation(attr, ms, easing, callback);
+                };
+                /*
+                 * \ Element.inAnim [ method ] * Returns a set of animations that may be
+                 * able to manipulate the current element * = (object) in format: o { o anim
+                 * (object) animation object, o mina (object) @mina object, o curStatus
+                 * (number) 0..1 ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ status of the animation: 0 ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ just started,
+                 * 1 ÃƒÂ¢Ã¢â€šÂ¬Ã¢â‚¬ï¿½ just finished, o status (function) gets or sets the status of
+                 * the animation, o stop (function) stops the animation o } \
+                 */
+                elproto.inAnim = function() {
+                    var el = this,
+                        res = [];
+                    for (var id in el.anims)
+                        if (el.anims[has](id)) {
+                            (function(a) {
+                                res.push({
+                                    anim: new Animation(a._attrs, a.dur, a.easing, a._callback),
+                                    mina: a,
+                                    curStatus: a.status(),
+                                    status: function(val) {
+                                        return a.status(val);
+                                    },
+                                    stop: function() {
+                                        a.stop();
+                                    }
+                                });
+                            }(el.anims[id]));
+                        }
+                    return res;
+                };
+                /*
+                 * \ Snap.animate [ method ] * Runs generic animation of one number into
+                 * another with a caring function * - from (number|array) number or array of
+                 * numbers - to (number|array) number or array of numbers - setter
+                 * (function) caring function that accepts one number argument - duration
+                 * (number) duration, in milliseconds - easing (function) #optional easing
+                 * function from @mina or custom - callback (function) #optional callback
+                 * function to execute when animation ends = (object) animation object in
+                 * @mina format o { o id (string) animation id, consider it read-only, o
+                 * duration (function) gets or sets the duration of the animation, o easing
+                 * (function) easing, o speed (function) gets or sets the speed of the
+                 * animation, o status (function) gets or sets the status of the animation,
+                 * o stop (function) stops the animation o } | var rect = Snap().rect(0, 0,
+                 * 10, 10); | Snap.animate(0, 10, function (val) { | rect.attr({ | x: val |
+                 * }); | }, 1000); | // in given context is equivalent to | rect.animate({x:
+                 * 10}, 1000); \
+                 */
+                Snap.animate = function(from, to, setter, ms, easing, callback) {
+                    if (typeof easing == "function" && !easing.length) {
+                        callback = easing;
+                        easing = mina.linear;
+                    }
+                    var now = mina.time(),
+                        anim = mina(from, to, now, now + ms, mina.time, setter, easing);
+                    callback && eve.once("mina.finish." + anim.id, callback);
+                    return anim;
+                };
+                /*
+                 * \ Element.stop [ method ] * Stops all the animations for the current
+                 * element * = (Element) the current element \
+                 */
+                elproto.stop = function() {
+                    var anims = this.inAnim();
+                    for (var i = 0, ii = anims.length; i < ii; i++) {
+                        anims[i].stop();
+                    }
+                    return this;
+                };
+                /*
+                 * \ Element.animate [ method ] * Animates the given attributes of the
+                 * element * - attrs (object) key-value pairs of destination attributes -
+                 * duration (number) duration of the animation in milliseconds - easing
+                 * (function) #optional easing function from @mina or custom - callback
+                 * (function) #optional callback function that executes when the animation
+                 * ends = (Element) the current element \
+                 */
+                elproto.animate = function(attrs, ms, easing, callback) {
+                    if (typeof easing == "function" && !easing.length) {
+                        callback = easing;
+                        easing = mina.linear;
+                    }
+                    if (attrs instanceof Animation) {
+                        callback = attrs.callback;
+                        easing = attrs.easing;
+                        ms = easing.dur;
+                        attrs = attrs.attr;
+                    }
+                    var fkeys = [],
+                        tkeys = [],
+                        keys = {},
+                        from, to, f, eq,
+                        el = this;
+                    for (var key in attrs)
+                        if (attrs[has](key)) {
+                            if (el.equal) {
+                                eq = el.equal(key, Str(attrs[key]));
+                                from = eq.from;
+                                to = eq.to;
+                                f = eq.f;
+                            } else {
+                                from = +el.attr(key);
+                                to = +attrs[key];
+                            }
+                            var len = is(from, "array") ? from.length : 1;
+                            keys[key] = slice(fkeys.length, fkeys.length + len, f);
+                            fkeys = fkeys.concat(from);
+                            tkeys = tkeys.concat(to);
+                        }
+                    var now = mina.time(),
+                        anim = mina(fkeys, tkeys, now, now + ms, mina.time, function(val) {
+                            var attr = {};
+                            for (var key in keys)
+                                if (keys[has](key)) {
+                                    attr[key] = keys[key](val);
+                                }
+                            el.attr(attr);
+                        }, easing);
+                    el.anims[anim.id] = anim;
+                    anim._attrs = attrs;
+                    anim._callback = callback;
+                    eve("snap.animcreated." + el.id, anim);
+                    eve.once("mina.finish." + anim.id, function() {
+                        delete el.anims[anim.id];
+                        callback && callback.call(el);
+                    });
+                    eve.once("mina.stop." + anim.id, function() {
+                        delete el.anims[anim.id];
+                    });
+                    return el;
+                };
+                var eldata = {};
+                /*
+                 * \ Element.data [ method ] * Adds or retrieves given value associated with
+                 * given key. (Don’t confuse with `data-` attributes)
+                 * 
+                 * See also @Element.removeData - key (string) key to store data - value
+                 * (any) #optional value to store = (object) @Element or, if value is not
+                 * specified: = (any) value > Usage | for (var i = 0, i < 5, i++) { |
+                 * paper.circle(10 + 15 * i, 10, 10) | .attr({fill: "#000"}) | .data("i", i) |
+                 * .click(function () { | alert(this.data("i")); | }); | } \
+                 */
+                elproto.data = function(key, value) {
+                    var data = eldata[this.id] = eldata[this.id] || {};
+                    if (arguments.length == 0) {
+                        eve("snap.data.get." + this.id, this, data, null);
+                        return data;
+                    }
+                    if (arguments.length == 1) {
+                        if (Snap.is(key, "object")) {
+                            for (var i in key)
+                                if (key[has](i)) {
+                                    this.data(i, key[i]);
+                                }
+                            return this;
+                        }
+                        eve("snap.data.get." + this.id, this, data[key], key);
+                        return data[key];
+                    }
+                    data[key] = value;
+                    eve("snap.data.set." + this.id, this, value, key);
+                    return this;
+                };
+                /*
+                 * \ Element.removeData [ method ] * Removes value associated with an
+                 * element by given key. If key is not provided, removes all the data of the
+                 * element. - key (string) #optional key = (object) @Element \
+                 */
+                elproto.removeData = function(key) {
+                    if (key == null) {
+                        eldata[this.id] = {};
+                    } else {
+                        eldata[this.id] && delete eldata[this.id][key];
+                    }
+                    return this;
+                };
+                /*
+                 * \ Element.outerSVG [ method ] * Returns SVG code for the element,
+                 * equivalent to HTML's `outerHTML`.
+                 * 
+                 * See also @Element.innerSVG = (string) SVG code for the element \
+                 */
+                /*
+                 * \ Element.toString [ method ] * See @Element.outerSVG \
+                 */
+                elproto.outerSVG = elproto.toString = toString(1);
+                /*
+                 * \ Element.innerSVG [ method ] * Returns SVG code for the element's
+                 * contents, equivalent to HTML's `innerHTML` = (string) SVG code for the
+                 * element \
+                 */
+                elproto.innerSVG = toString();
+
+                function toString(type) {
+                    return function() {
+                        var res = type ? "<" + this.type : "",
+                            attr = this.node.attributes,
+                            chld = this.node.childNodes;
+                        if (type) {
+                            for (var i = 0, ii = attr.length; i < ii; i++) {
+                                res += " " + attr[i].name + '="' +
+                                    attr[i].value.replace(/"/g, '\\"') + '"';
+                            }
+                        }
+                        if (chld.length) {
+                            type && (res += ">");
+                            for (i = 0, ii = chld.length; i < ii; i++) {
+                                if (chld[i].nodeType == 3) {
+                                    res += chld[i].nodeValue;
+                                } else if (chld[i].nodeType == 1) {
+                                    res += wrap(chld[i]).toString();
+                                }
+                            }
+                            type && (res += "</" + this.type + ">");
+                        } else {
+                            type && (res += "/>");
+                        }
+                        return res;
+                    };
+                }
+                elproto.toDataURL = function() {
+                    if (window && window.btoa) {
+                        var bb = this.getBBox(),
+                            svg = Snap.format('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}" viewBox="{x} {y} {width} {height}">{contents}</svg>', {
+                                x: +bb.x.toFixed(3),
+                                y: +bb.y.toFixed(3),
+                                width: +bb.width.toFixed(3),
+                                height: +bb.height.toFixed(3),
+                                contents: this.outerSVG()
+                            });
+                        return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svg)));
+                    }
+                };
+                /*
+                 * \ Fragment.select [ method ] * See @Element.select \
+                 */
+                Fragment.prototype.select = elproto.select;
+                /*
+                 * \ Fragment.selectAll [ method ] * See @Element.selectAll \
+                 */
+                Fragment.prototype.selectAll = elproto.selectAll;
+            });
+
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob, Fragment) {
+                var objectToString = Object.prototype.toString,
+                    Str = String,
+                    math = Math,
+                    E = "";
+
+                function Matrix(a, b, c, d, e, f) {
+                    if (b == null && objectToString.call(a) == "[object SVGMatrix]") {
+                        this.a = a.a;
+                        this.b = a.b;
+                        this.c = a.c;
+                        this.d = a.d;
+                        this.e = a.e;
+                        this.f = a.f;
+                        return;
+                    }
+                    if (a != null) {
+                        this.a = +a;
+                        this.b = +b;
+                        this.c = +c;
+                        this.d = +d;
+                        this.e = +e;
+                        this.f = +f;
+                    } else {
+                        this.a = 1;
+                        this.b = 0;
+                        this.c = 0;
+                        this.d = 1;
+                        this.e = 0;
+                        this.f = 0;
+                    }
+                }
+                (function(matrixproto) {
+                    /*
+                     * \ Matrix.add [ method ] * Adds the given matrix to existing one - a
+                     * (number) - b (number) - c (number) - d (number) - e (number) - f
+                     * (number) or - matrix (object) @Matrix \
+                     */
+                    matrixproto.add = function(a, b, c, d, e, f) {
+                        var out = [
+                                [],
+                                [],
+                                []
+                            ],
+                            m = [
+                                [this.a, this.c, this.e],
+                                [this.b, this.d, this.f],
+                                [0, 0, 1]
+                            ],
+                            matrix = [
+                                [a, c, e],
+                                [b, d, f],
+                                [0, 0, 1]
+                            ],
+                            x, y, z, res;
+
+                        if (a && a instanceof Matrix) {
+                            matrix = [
+                                [a.a, a.c, a.e],
+                                [a.b, a.d, a.f],
+                                [0, 0, 1]
+                            ];
+                        }
+
+                        for (x = 0; x < 3; x++) {
+                            for (y = 0; y < 3; y++) {
+                                res = 0;
+                                for (z = 0; z < 3; z++) {
+                                    res += m[x][z] * matrix[z][y];
+                                }
+                                out[x][y] = res;
+                            }
+                        }
+                        this.a = out[0][0];
+                        this.b = out[1][0];
+                        this.c = out[0][1];
+                        this.d = out[1][1];
+                        this.e = out[0][2];
+                        this.f = out[1][2];
+                        return this;
+                    };
+                    /*
+                     * \ Matrix.invert [ method ] * Returns an inverted version of the
+                     * matrix = (object) @Matrix \
+                     */
+                    matrixproto.invert = function() {
+                        var me = this,
+                            x = me.a * me.d - me.b * me.c;
+                        return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
+                    };
+                    /*
+                     * \ Matrix.clone [ method ] * Returns a copy of the matrix = (object)
+                     * @Matrix \
+                     */
+                    matrixproto.clone = function() {
+                        return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
+                    };
+                    /*
+                     * \ Matrix.translate [ method ] * Translate the matrix - x (number)
+                     * horizontal offset distance - y (number) vertical offset distance \
+                     */
+                    matrixproto.translate = function(x, y) {
+                        return this.add(1, 0, 0, 1, x, y);
+                    };
+                    /*
+                     * \ Matrix.scale [ method ] * Scales the matrix - x (number) amount to
+                     * be scaled, with `1` resulting in no change - y (number) #optional
+                     * amount to scale along the vertical axis. (Otherwise `x` applies to
+                     * both axes.) - cx (number) #optional horizontal origin point from
+                     * which to scale - cy (number) #optional vertical origin point from
+                     * which to scale Default cx, cy is the middle point of the element. \
+                     */
+                    matrixproto.scale = function(x, y, cx, cy) {
+                        y == null && (y = x);
+                        (cx || cy) && this.add(1, 0, 0, 1, cx, cy);
+                        this.add(x, 0, 0, y, 0, 0);
+                        (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
+                        return this;
+                    };
+                    /*
+                     * \ Matrix.rotate [ method ] * Rotates the matrix - a (number) angle of
+                     * rotation, in degrees - x (number) horizontal origin point from which
+                     * to rotate - y (number) vertical origin point from which to rotate \
+                     */
+                    matrixproto.rotate = function(a, x, y) {
+                        a = Snap.rad(a);
+                        x = x || 0;
+                        y = y || 0;
+                        var cos = +math.cos(a).toFixed(9),
+                            sin = +math.sin(a).toFixed(9);
+                        this.add(cos, sin, -sin, cos, x, y);
+                        return this.add(1, 0, 0, 1, -x, -y);
+                    };
+                    /*
+                     * \ Matrix.x [ method ] * Returns x coordinate for given point after
+                     * transformation described by the matrix. See also @Matrix.y - x
+                     * (number) - y (number) = (number) x \
+                     */
+                    matrixproto.x = function(x, y) {
+                        return x * this.a + y * this.c + this.e;
+                    };
+                    /*
+                     * \ Matrix.y [ method ] * Returns y coordinate for given point after
+                     * transformation described by the matrix. See also @Matrix.x - x
+                     * (number) - y (number) = (number) y \
+                     */
+                    matrixproto.y = function(x, y) {
+                        return x * this.b + y * this.d + this.f;
+                    };
+                    matrixproto.get = function(i) {
+                        return +this[Str.fromCharCode(97 + i)].toFixed(4);
+                    };
+                    matrixproto.toString = function() {
+                        return "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")";
+                    };
+                    matrixproto.offset = function() {
+                        return [this.e.toFixed(4), this.f.toFixed(4)];
+                    };
+
+                    function norm(a) {
+                        return a[0] * a[0] + a[1] * a[1];
+                    }
+
+                    function normalize(a) {
+                        var mag = math.sqrt(norm(a));
+                        a[0] && (a[0] /= mag);
+                        a[1] && (a[1] /= mag);
+                    }
+                    /*
+                     * \ Matrix.determinant [ method ] * Finds determinant of the given
+                     * matrix. = (number) determinant \
+                     */
+                    matrixproto.determinant = function() {
+                        return this.a * this.d - this.b * this.c;
+                    };
+                    /*
+                     * \ Matrix.split [ method ] * Splits matrix into primitive
+                     * transformations = (object) in format: o dx (number) translation by x
+                     * o dy (number) translation by y o scalex (number) scale by x o scaley
+                     * (number) scale by y o shear (number) shear o rotate (number) rotation
+                     * in deg o isSimple (boolean) could it be represented via simple
+                     * transformations \
+                     */
+                    matrixproto.split = function() {
+                        var out = {};
+                        // translation
+                        out.dx = this.e;
+                        out.dy = this.f;
+
+                        // scale and shear
+                        var row = [
+                            [this.a, this.c],
+                            [this.b, this.d]
+                        ];
+                        out.scalex = math.sqrt(norm(row[0]));
+                        normalize(row[0]);
+
+                        out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
+                        row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
+
+                        out.scaley = math.sqrt(norm(row[1]));
+                        normalize(row[1]);
+                        out.shear /= out.scaley;
+
+                        if (this.determinant() < 0) {
+                            out.scalex = -out.scalex;
+                        }
+
+                        // rotation
+                        var sin = -row[0][1],
+                            cos = row[1][1];
+                        if (cos < 0) {
+                            out.rotate = Snap.deg(math.acos(cos));
+                            if (sin < 0) {
+                                out.rotate = 360 - out.rotate;
+                            }
+                        } else {
+                            out.rotate = Snap.deg(math.asin(sin));
+                        }
+
+                        out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
+                        out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;
+                        out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
+                        return out;
+                    };
+                    /*
+                     * \ Matrix.toTransformString [ method ] * Returns transform string that
+                     * represents given matrix = (string) transform string \
+                     */
+                    matrixproto.toTransformString = function(shorter) {
+                        var s = shorter || this.split();
+                        if (!+s.shear.toFixed(9)) {
+                            s.scalex = +s.scalex.toFixed(4);
+                            s.scaley = +s.scaley.toFixed(4);
+                            s.rotate = +s.rotate.toFixed(4);
+                            return (s.dx || s.dy ? "t" + [+s.dx.toFixed(4), +s.dy.toFixed(4)] : E) +
+                                (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) +
+                                (s.rotate ? "r" + [+s.rotate.toFixed(4), 0, 0] : E);
+                        } else {
+                            return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
+                        }
+                    };
+                })(Matrix.prototype);
+                /*
+                 * \ Snap.Matrix [ method ] * Matrix constructor, extend on your own risk.
+                 * To create matrices use @Snap.matrix. \
+                 */
+                Snap.Matrix = Matrix;
+                /*
+                 * \ Snap.matrix [ method ] * Utility method * Returns a matrix based on the
+                 * given parameters - a (number) - b (number) - c (number) - d (number) - e
+                 * (number) - f (number) or - svgMatrix (SVGMatrix) = (object) @Matrix \
+                 */
+                Snap.matrix = function(a, b, c, d, e, f) {
+                    return new Matrix(a, b, c, d, e, f);
+                };
+            });
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob, Fragment) {
+                var has = "hasOwnProperty",
+                    make = Snap._.make,
+                    wrap = Snap._.wrap,
+                    is = Snap.is,
+                    getSomeDefs = Snap._.getSomeDefs,
+                    reURLValue = /^url\(#?([^)]+)\)$/,
+                    $ = Snap._.$,
+                    URL = Snap.url,
+                    Str = String,
+                    separator = Snap._.separator,
+                    E = "";
+                // Attributes event handlers
+                eve.on("snap.util.attr.mask", function(value) {
+                    if (value instanceof Element || value instanceof Fragment) {
+                        eve.stop();
+                        if (value instanceof Fragment && value.node.childNodes.length == 1) {
+                            value = value.node.firstChild;
+                            getSomeDefs(this).appendChild(value);
+                            value = wrap(value);
+                        }
+                        if (value.type == "mask") {
+                            var mask = value;
+                        } else {
+                            mask = make("mask", getSomeDefs(this));
+                            mask.node.appendChild(value.node);
+                        }!mask.node.id && $(mask.node, {
+                            id: mask.id
+                        });
+                        $(this.node, {
+                            mask: URL(mask.id)
+                        });
+                    }
+                });
+                (function(clipIt) {
+                    eve.on("snap.util.attr.clip", clipIt);
+                    eve.on("snap.util.attr.clip-path", clipIt);
+                    eve.on("snap.util.attr.clipPath", clipIt);
+                }(function(value) {
+                    if (value instanceof Element || value instanceof Fragment) {
+                        eve.stop();
+                        if (value.type == "clipPath") {
+                            var clip = value;
+                        } else {
+                            clip = make("clipPath", getSomeDefs(this));
+                            clip.node.appendChild(value.node);
+                            !clip.node.id && $(clip.node, {
+                                id: clip.id
+                            });
+                        }
+                        $(this.node, {
+                            "clip-path": URL(clip.node.id || clip.id)
+                        });
+                    }
+                }));
+
+                function fillStroke(name) {
+                    return function(value) {
+                        eve.stop();
+                        if (value instanceof Fragment && value.node.childNodes.length == 1 &&
+                            (value.node.firstChild.tagName == "radialGradient" ||
+                                value.node.firstChild.tagName == "linearGradient" ||
+                                value.node.firstChild.tagName == "pattern")) {
+                            value = value.node.firstChild;
+                            getSomeDefs(this).appendChild(value);
+                            value = wrap(value);
+                        }
+                        if (value instanceof Element) {
+                            if (value.type == "radialGradient" || value.type == "linearGradient" || value.type == "pattern") {
+                                if (!value.node.id) {
+                                    $(value.node, {
+                                        id: value.id
+                                    });
+                                }
+                                var fill = URL(value.node.id);
+                            } else {
+                                fill = value.attr(name);
+                            }
+                        } else {
+                            fill = Snap.color(value);
+                            if (fill.error) {
+                                var grad = Snap(getSomeDefs(this).ownerSVGElement).gradient(value);
+                                if (grad) {
+                                    if (!grad.node.id) {
+                                        $(grad.node, {
+                                            id: grad.id
+                                        });
+                                    }
+                                    fill = URL(grad.node.id);
+                                } else {
+                                    fill = value;
+                                }
+                            } else {
+                                fill = Str(fill);
+                            }
+                        }
+                        var attrs = {};
+                        attrs[name] = fill;
+                        $(this.node, attrs);
+                        this.node.style[name] = E;
+                    };
+                }
+                eve.on("snap.util.attr.fill", fillStroke("fill"));
+                eve.on("snap.util.attr.stroke", fillStroke("stroke"));
+                var gradrg = /^([lr])(?:\(([^)]*)\))?(.*)$/i;
+                eve.on("snap.util.grad.parse", function parseGrad(string) {
+                    string = Str(string);
+                    var tokens = string.match(gradrg);
+                    if (!tokens) {
+                        return null;
+                    }
+                    var type = tokens[1],
+                        params = tokens[2],
+                        stops = tokens[3];
+                    params = params.split(/\s*,\s*/).map(function(el) {
+                        return +el == el ? +el : el;
+                    });
+                    if (params.length == 1 && params[0] == 0) {
+                        params = [];
+                    }
+                    stops = stops.split("-");
+                    stops = stops.map(function(el) {
+                        el = el.split(":");
+                        var out = {
+                            color: el[0]
+                        };
+                        if (el[1]) {
+                            out.offset = parseFloat(el[1]);
+                        }
+                        return out;
+                    });
+                    return {
+                        type: type,
+                        params: params,
+                        stops: stops
+                    };
+                });
+
+                eve.on("snap.util.attr.d", function(value) {
+                    eve.stop();
+                    if (is(value, "array") && is(value[0], "array")) {
+                        value = Snap.path.toString.call(value);
+                    }
+                    value = Str(value);
+                    if (value.match(/[ruo]/i)) {
+                        value = Snap.path.toAbsolute(value);
+                    }
+                    $(this.node, {
+                        d: value
+                    });
+                })(-1);
+                eve.on("snap.util.attr.#text", function(value) {
+                    eve.stop();
+                    value = Str(value);
+                    var txt = glob.doc.createTextNode(value);
+                    while (this.node.firstChild) {
+                        this.node.removeChild(this.node.firstChild);
+                    }
+                    this.node.appendChild(txt);
+                })(-1);
+                eve.on("snap.util.attr.path", function(value) {
+                    eve.stop();
+                    this.attr({
+                        d: value
+                    });
+                })(-1);
+                eve.on("snap.util.attr.class", function(value) {
+                    eve.stop();
+                    this.node.className.baseVal = value;
+                })(-1);
+                eve.on("snap.util.attr.viewBox", function(value) {
+                    var vb;
+                    if (is(value, "object") && "x" in value) {
+                        vb = [value.x, value.y, value.width, value.height].join(" ");
+                    } else if (is(value, "array")) {
+                        vb = value.join(" ");
+                    } else {
+                        vb = value;
+                    }
+                    $(this.node, {
+                        viewBox: vb
+                    });
+                    eve.stop();
+                })(-1);
+                eve.on("snap.util.attr.transform", function(value) {
+                    this.transform(value);
+                    eve.stop();
+                })(-1);
+                eve.on("snap.util.attr.r", function(value) {
+                    if (this.type == "rect") {
+                        eve.stop();
+                        $(this.node, {
+                            rx: value,
+                            ry: value
+                        });
+                    }
+                })(-1);
+                eve.on("snap.util.attr.textpath", function(value) {
+                    eve.stop();
+                    if (this.type == "text") {
+                        var id, tp, node;
+                        if (!value && this.textPath) {
+                            tp = this.textPath;
+                            while (tp.node.firstChild) {
+                                this.node.appendChild(tp.node.firstChild);
+                            }
+                            tp.remove();
+                            delete this.textPath;
+                            return;
+                        }
+                        if (is(value, "string")) {
+                            var defs = getSomeDefs(this),
+                                path = wrap(defs.parentNode).path(value);
+                            defs.appendChild(path.node);
+                            id = path.id;
+                            path.attr({
+                                id: id
+                            });
+                        } else {
+                            value = wrap(value);
+                            if (value instanceof Element) {
+                                id = value.attr("id");
+                                if (!id) {
+                                    id = value.id;
+                                    value.attr({
+                                        id: id
+                                    });
+                                }
+                            }
+                        }
+                        if (id) {
+                            tp = this.textPath;
+                            node = this.node;
+                            if (tp) {
+                                tp.attr({
+                                    "xlink:href": "#" + id
+                                });
+                            } else {
+                                tp = $("textPath", {
+                                    "xlink:href": "#" + id
+                                });
+                                while (node.firstChild) {
+                                    tp.appendChild(node.firstChild);
+                                }
+                                node.appendChild(tp);
+                                this.textPath = wrap(tp);
+                            }
+                        }
+                    }
+                })(-1);
+                eve.on("snap.util.attr.text", function(value) {
+                    if (this.type == "text") {
+                        var i = 0,
+                            node = this.node,
+                            tuner = function(chunk) {
+                                var out = $("tspan");
+                                if (is(chunk, "array")) {
+                                    for (var i = 0; i < chunk.length; i++) {
+                                        out.appendChild(tuner(chunk[i]));
+                                    }
+                                } else {
+                                    out.appendChild(glob.doc.createTextNode(chunk));
+                                }
+                                out.normalize && out.normalize();
+                                return out;
+                            };
+                        while (node.firstChild) {
+                            node.removeChild(node.firstChild);
+                        }
+                        var tuned = tuner(value);
+                        while (tuned.firstChild) {
+                            node.appendChild(tuned.firstChild);
+                        }
+                    }
+                    eve.stop();
+                })(-1);
+
+                function setFontSize(value) {
+                    eve.stop();
+                    if (value == +value) {
+                        value += "px";
+                    }
+                    this.node.style.fontSize = value;
+                }
+                eve.on("snap.util.attr.fontSize", setFontSize)(-1);
+                eve.on("snap.util.attr.font-size", setFontSize)(-1);
+
+
+                eve.on("snap.util.getattr.transform", function() {
+                    eve.stop();
+                    return this.transform();
+                })(-1);
+                eve.on("snap.util.getattr.textpath", function() {
+                    eve.stop();
+                    return this.textPath;
+                })(-1);
+                // Markers
+                (function() {
+                    function getter(end) {
+                        return function() {
+                            eve.stop();
+                            var style = glob.doc.defaultView.getComputedStyle(this.node, null).getPropertyValue("marker-" + end);
+                            if (style == "none") {
+                                return style;
+                            } else {
+                                return Snap(glob.doc.getElementById(style.match(reURLValue)[1]));
+                            }
+                        };
+                    }
+
+                    function setter(end) {
+                        return function(value) {
+                            eve.stop();
+                            var name = "marker" + end.charAt(0).toUpperCase() + end.substring(1);
+                            if (value == "" || !value) {
+                                this.node.style[name] = "none";
+                                return;
+                            }
+                            if (value.type == "marker") {
+                                var id = value.node.id;
+                                if (!id) {
+                                    $(value.node, {
+                                        id: value.id
+                                    });
+                                }
+                                this.node.style[name] = URL(id);
+                                return;
+                            }
+                        };
+                    }
+                    eve.on("snap.util.getattr.marker-end", getter("end"))(-1);
+                    eve.on("snap.util.getattr.markerEnd", getter("end"))(-1);
+                    eve.on("snap.util.getattr.marker-start", getter("start"))(-1);
+                    eve.on("snap.util.getattr.markerStart", getter("start"))(-1);
+                    eve.on("snap.util.getattr.marker-mid", getter("mid"))(-1);
+                    eve.on("snap.util.getattr.markerMid", getter("mid"))(-1);
+                    eve.on("snap.util.attr.marker-end", setter("end"))(-1);
+                    eve.on("snap.util.attr.markerEnd", setter("end"))(-1);
+                    eve.on("snap.util.attr.marker-start", setter("start"))(-1);
+                    eve.on("snap.util.attr.markerStart", setter("start"))(-1);
+                    eve.on("snap.util.attr.marker-mid", setter("mid"))(-1);
+                    eve.on("snap.util.attr.markerMid", setter("mid"))(-1);
+                }());
+                eve.on("snap.util.getattr.r", function() {
+                    if (this.type == "rect" && $(this.node, "rx") == $(this.node, "ry")) {
+                        eve.stop();
+                        return $(this.node, "rx");
+                    }
+                })(-1);
+
+                function textExtract(node) {
+                    var out = [];
+                    var children = node.childNodes;
+                    for (var i = 0, ii = children.length; i < ii; i++) {
+                        var chi = children[i];
+                        if (chi.nodeType == 3) {
+                            out.push(chi.nodeValue);
+                        }
+                        if (chi.tagName == "tspan") {
+                            if (chi.childNodes.length == 1 && chi.firstChild.nodeType == 3) {
+                                out.push(chi.firstChild.nodeValue);
+                            } else {
+                                out.push(textExtract(chi));
+                            }
+                        }
+                    }
+                    return out;
+                }
+                eve.on("snap.util.getattr.text", function() {
+                    if (this.type == "text" || this.type == "tspan") {
+                        eve.stop();
+                        var out = textExtract(this.node);
+                        return out.length == 1 ? out[0] : out;
+                    }
+                })(-1);
+                eve.on("snap.util.getattr.#text", function() {
+                    return this.node.textContent;
+                })(-1);
+                eve.on("snap.util.getattr.viewBox", function() {
+                    eve.stop();
+                    var vb = $(this.node, "viewBox");
+                    if (vb) {
+                        vb = vb.split(separator);
+                        return Snap._.box(+vb[0], +vb[1], +vb[2], +vb[3]);
+                    } else {
+                        return;
+                    }
+                })(-1);
+                eve.on("snap.util.getattr.points", function() {
+                    var p = $(this.node, "points");
+                    eve.stop();
+                    if (p) {
+                        return p.split(separator);
+                    } else {
+                        return;
+                    }
+                })(-1);
+                eve.on("snap.util.getattr.path", function() {
+                    var p = $(this.node, "d");
+                    eve.stop();
+                    return p;
+                })(-1);
+                eve.on("snap.util.getattr.class", function() {
+                    return this.node.className.baseVal;
+                })(-1);
+
+                function getFontSize() {
+                    eve.stop();
+                    return this.node.style.fontSize;
+                }
+                eve.on("snap.util.getattr.fontSize", getFontSize)(-1);
+                eve.on("snap.util.getattr.font-size", getFontSize)(-1);
+            });
+
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob, Fragment) {
+                var proto = Paper.prototype,
+                    is = Snap.is;
+                /*
+                 * \ Paper.rect [ method ]
+                 * 
+                 * Draws a rectangle * - x (number) x coordinate of the top left corner - y
+                 * (number) y coordinate of the top left corner - width (number) width -
+                 * height (number) height - rx (number) #optional horizontal radius for
+                 * rounded corners, default is 0 - ry (number) #optional vertical radius for
+                 * rounded corners, default is rx or 0 = (object) the `rect` element * >
+                 * Usage | // regular rectangle | var c = paper.rect(10, 10, 50, 50); | //
+                 * rectangle with rounded corners | var c = paper.rect(40, 40, 50, 50, 10); \
+                 */
+                proto.rect = function(x, y, w, h, rx, ry) {
+                    var attr;
+                    if (ry == null) {
+                        ry = rx;
+                    }
+                    if (is(x, "object") && x == "[object Object]") {
+                        attr = x;
+                    } else if (x != null) {
+                        attr = {
+                            x: x,
+                            y: y,
+                            width: w,
+                            height: h
+                        };
+                        if (rx != null) {
+                            attr.rx = rx;
+                            attr.ry = ry;
+                        }
+                    }
+                    return this.el("rect", attr);
+                };
+                /*
+                 * \ Paper.circle [ method ] * Draws a circle * - x (number) x coordinate of
+                 * the centre - y (number) y coordinate of the centre - r (number) radius =
+                 * (object) the `circle` element * > Usage | var c = paper.circle(50, 50,
+                 * 40); \
+                 */
+                proto.circle = function(cx, cy, r) {
+                    var attr;
+                    if (is(cx, "object") && cx == "[object Object]") {
+                        attr = cx;
+                    } else if (cx != null) {
+                        attr = {
+                            cx: cx,
+                            cy: cy,
+                            r: r
+                        };
+                    }
+                    return this.el("circle", attr);
+                };
+
+                var preload = (function() {
+                    function onerror() {
+                        this.parentNode.removeChild(this);
+                    }
+                    return function(src, f) {
+                        var img = glob.doc.createElement("img"),
+                            body = glob.doc.body;
+                        img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
+                        img.onload = function() {
+                            f.call(img);
+                            img.onload = img.onerror = null;
+                            body.removeChild(img);
+                        };
+                        img.onerror = onerror;
+                        body.appendChild(img);
+                        img.src = src;
+                    };
+                }());
+
+                /*
+                 * \ Paper.image [ method ] * Places an image on the surface * - src
+                 * (string) URI of the source image - x (number) x offset position - y
+                 * (number) y offset position - width (number) width of the image - height
+                 * (number) height of the image = (object) the `image` element or = (object)
+                 * Snap element object with type `image` * > Usage | var c =
+                 * paper.image("apple.png", 10, 10, 80, 80); \
+                 */
+                proto.image = function(src, x, y, width, height) {
+                    var el = this.el("image");
+                    if (is(src, "object") && "src" in src) {
+                        el.attr(src);
+                    } else if (src != null) {
+                        var set = {
+                            "xlink:href": src,
+                            preserveAspectRatio: "none"
+                        };
+                        if (x != null && y != null) {
+                            set.x = x;
+                            set.y = y;
+                        }
+                        if (width != null && height != null) {
+                            set.width = width;
+                            set.height = height;
+                        } else {
+                            preload(src, function() {
+                                Snap._.$(el.node, {
+                                    width: this.offsetWidth,
+                                    height: this.offsetHeight
+                                });
+                            });
+                        }
+                        Snap._.$(el.node, set);
+                    }
+                    return el;
+                };
+                /*
+                 * \ Paper.ellipse [ method ] * Draws an ellipse * - x (number) x coordinate
+                 * of the centre - y (number) y coordinate of the centre - rx (number)
+                 * horizontal radius - ry (number) vertical radius = (object) the `ellipse`
+                 * element * > Usage | var c = paper.ellipse(50, 50, 40, 20); \
+                 */
+                proto.ellipse = function(cx, cy, rx, ry) {
+                    var attr;
+                    if (is(cx, "object") && cx == "[object Object]") {
+                        attr = cx;
+                    } else if (cx != null) {
+                        attr = {
+                            cx: cx,
+                            cy: cy,
+                            rx: rx,
+                            ry: ry
+                        };
+                    }
+                    return this.el("ellipse", attr);
+                };
+                // SIERRA Paper.path(): Unclear from the link what a Catmull-Rom curveto is,
+                // and why it would make life any easier.
+                /*
+                 * \ Paper.path [ method ] * Creates a `<path>` element using the given
+                 * string as the path's definition - pathString (string) #optional path
+                 * string in SVG format Path string consists of one-letter commands,
+                 * followed by comma seprarated arguments in numerical form. Example: |
+                 * "M10,20L30,40" This example features two commands: `M`, with arguments
+                 * `(10, 20)` and `L` with arguments `(30, 40)`. Uppercase letter commands
+                 * express coordinates in absolute terms, while lowercase commands express
+                 * them in relative terms from the most recently declared coordinates.
+                 *  # <p>Here is short list of commands available, for more details see <a
+                 * href="http://www.w3.org/TR/SVG/paths.html#PathData" title="Details of a
+                 * path's data attribute's format are described in the SVG
+                 * specification.">SVG path string format</a> or <a
+                 * href="https://developer.mozilla.org/en/SVG/Tutorial/Paths">article about
+                 * path strings at MDN</a>.</p> # <table><thead><tr><th>Command</th><th>Name</th><th>Parameters</th></tr></thead><tbody> #
+                 * <tr><td>M</td><td>moveto</td><td>(x y)+</td></tr> # <tr><td>Z</td><td>closepath</td><td>(none)</td></tr> #
+                 * <tr><td>L</td><td>lineto</td><td>(x y)+</td></tr> # <tr><td>H</td><td>horizontal
+                 * lineto</td><td>x+</td></tr> # <tr><td>V</td><td>vertical lineto</td><td>y+</td></tr> #
+                 * <tr><td>C</td><td>curveto</td><td>(x1 y1 x2 y2 x y)+</td></tr> #
+                 * <tr><td>S</td><td>smooth curveto</td><td>(x2 y2 x y)+</td></tr> #
+                 * <tr><td>Q</td><td>quadratic Bézier curveto</td><td>(x1 y1 x
+                 * y)+</td></tr> # <tr><td>T</td><td>smooth quadratic Bézier
+                 * curveto</td><td>(x y)+</td></tr> # <tr><td>A</td><td>elliptical
+                 * arc</td><td>(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+</td></tr> #
+                 * <tr><td>R</td><td><a
+                 * href="http://en.wikipedia.org/wiki/Catmull–Rom_spline#Catmull.E2.80.93Rom_spline">Catmull-Rom
+                 * curveto</a>*</td><td>x1 y1 (x y)+</td></tr></tbody></table> *
+                 * _Catmull-Rom curveto_ is a not standard SVG command and added to make
+                 * life easier. Note: there is a special case when a path consists of only
+                 * three commands: `M10,10R…z`. In this case the path connects back to
+                 * its starting point. > Usage | var c = paper.path("M10 10L90 90"); | //
+                 * draw a diagonal line: | // move to 10,10, line to 90,90 \
+                 */
+                proto.path = function(d) {
+                    var attr;
+                    if (is(d, "object") && !is(d, "array")) {
+                        attr = d;
+                    } else if (d) {
+                        attr = {
+                            d: d
+                        };
+                    }
+                    return this.el("path", attr);
+                };
+                /*
+                 * \ Paper.g [ method ] * Creates a group element * - varargs (…)
+                 * #optional elements to nest within the group = (object) the `g` element * >
+                 * Usage | var c1 = paper.circle(), | c2 = paper.rect(), | g = paper.g(c2,
+                 * c1); // note that the order of elements is different or | var c1 =
+                 * paper.circle(), | c2 = paper.rect(), | g = paper.g(); | g.add(c2, c1); \
+                 */
+                /*
+                 * \ Paper.group [ method ] * See @Paper.g \
+                 */
+                proto.group = proto.g = function(first) {
+                    var attr,
+                        el = this.el("g");
+                    if (arguments.length == 1 && first && !first.type) {
+                        el.attr(first);
+                    } else if (arguments.length) {
+                        el.add(Array.prototype.slice.call(arguments, 0));
+                    }
+                    return el;
+                };
+                /*
+                 * \ Paper.svg [ method ] * Creates a nested SVG element. - x (number)
+                 * @optional X of the element - y (number) @optional Y of the element -
+                 * width (number) @optional width of the element - height (number) @optional
+                 * height of the element - vbx (number) @optional viewbox X - vby (number)
+                 * @optional viewbox Y - vbw (number) @optional viewbox width - vbh (number)
+                 * @optional viewbox height * = (object) the `svg` element * \
+                 */
+                proto.svg = function(x, y, width, height, vbx, vby, vbw, vbh) {
+                    var attrs = {};
+                    if (is(x, "object") && y == null) {
+                        attrs = x;
+                    } else {
+                        if (x != null) {
+                            attrs.x = x;
+                        }
+                        if (y != null) {
+                            attrs.y = y;
+                        }
+                        if (width != null) {
+                            attrs.width = width;
+                        }
+                        if (height != null) {
+                            attrs.height = height;
+                        }
+                        if (vbx != null && vby != null && vbw != null && vbh != null) {
+                            attrs.viewBox = [vbx, vby, vbw, vbh];
+                        }
+                    }
+                    return this.el("svg", attrs);
+                };
+                /*
+                 * \ Paper.mask [ method ] * Equivalent in behaviour to @Paper.g, except
+                 * it’s a mask. * = (object) the `mask` element * \
+                 */
+                proto.mask = function(first) {
+                    var attr,
+                        el = this.el("mask");
+                    if (arguments.length == 1 && first && !first.type) {
+                        el.attr(first);
+                    } else if (arguments.length) {
+                        el.add(Array.prototype.slice.call(arguments, 0));
+                    }
+                    return el;
+                };
+                /*
+                 * \ Paper.ptrn [ method ] * Equivalent in behaviour to @Paper.g, except
+                 * it’s a pattern. - x (number) @optional X of the element - y
+                 * (number) @optional Y of the element - width (number) @optional width of
+                 * the element - height (number) @optional height of the element - vbx
+                 * (number) @optional viewbox X - vby (number) @optional viewbox Y - vbw
+                 * (number) @optional viewbox width - vbh (number) @optional viewbox height * =
+                 * (object) the `pattern` element * \
+                 */
+                proto.ptrn = function(x, y, width, height, vx, vy, vw, vh) {
+                    if (is(x, "object")) {
+                        var attr = x;
+                    } else {
+                        attr = {
+                            patternUnits: "userSpaceOnUse"
+                        };
+                        if (x) {
+                            attr.x = x;
+                        }
+                        if (y) {
+                            attr.y = y;
+                        }
+                        if (width != null) {
+                            attr.width = width;
+                        }
+                        if (height != null) {
+                            attr.height = height;
+                        }
+                        if (vx != null && vy != null && vw != null && vh != null) {
+                            attr.viewBox = [vx, vy, vw, vh];
+                        }
+                    }
+                    return this.el("pattern", attr);
+                };
+                /*
+                 * \ Paper.use [ method ] * Creates a <use> element. - id (string) @optional
+                 * id of element to link or - id (Element) @optional element to link * =
+                 * (object) the `use` element * \
+                 */
+                proto.use = function(id) {
+                    if (id != null) {
+                        if (id instanceof Element) {
+                            if (!id.attr("id")) {
+                                id.attr({
+                                    id: Snap._.id(id)
+                                });
+                            }
+                            id = id.attr("id");
+                        }
+                        if (String(id).charAt() == "#") {
+                            id = id.substring(1);
+                        }
+                        return this.el("use", {
+                            "xlink:href": "#" + id
+                        });
+                    } else {
+                        return Element.prototype.use.call(this);
+                    }
+                };
+                /*
+                 * \ Paper.symbol [ method ] * Creates a <symbol> element. - vbx (number)
+                 * @optional viewbox X - vby (number) @optional viewbox Y - vbw (number)
+                 * @optional viewbox width - vbh (number) @optional viewbox height =
+                 * (object) the `symbol` element * \
+                 */
+                proto.symbol = function(vx, vy, vw, vh) {
+                    var attr = {};
+                    if (vx != null && vy != null && vw != null && vh != null) {
+                        attr.viewBox = [vx, vy, vw, vh];
+                    }
+
+                    return this.el("symbol", attr);
+                };
+                /*
+                 * \ Paper.text [ method ] * Draws a text string * - x (number) x coordinate
+                 * position - y (number) y coordinate position - text (string|array) The
+                 * text string to draw or array of strings to nest within separate `<tspan>`
+                 * elements = (object) the `text` element * > Usage | var t1 =
+                 * paper.text(50, 50, "Snap"); | var t2 = paper.text(50, 50,
+                 * ["S","n","a","p"]); | // Text path usage | t1.attr({textpath:
+                 * "M10,10L100,100"}); | // or | var pth = paper.path("M10,10L100,100"); |
+                 * t1.attr({textpath: pth}); \
+                 */
+                proto.text = function(x, y, text) {
+                    var attr = {};
+                    if (is(x, "object")) {
+                        attr = x;
+                    } else if (x != null) {
+                        attr = {
+                            x: x,
+                            y: y,
+                            text: text || ""
+                        };
+                    }
+                    return this.el("text", attr);
+                };
+                /*
+                 * \ Paper.line [ method ] * Draws a line * - x1 (number) x coordinate
+                 * position of the start - y1 (number) y coordinate position of the start -
+                 * x2 (number) x coordinate position of the end - y2 (number) y coordinate
+                 * position of the end = (object) the `line` element * > Usage | var t1 =
+                 * paper.line(50, 50, 100, 100); \
+                 */
+                proto.line = function(x1, y1, x2, y2) {
+                    var attr = {};
+                    if (is(x1, "object")) {
+                        attr = x1;
+                    } else if (x1 != null) {
+                        attr = {
+                            x1: x1,
+                            x2: x2,
+                            y1: y1,
+                            y2: y2
+                        };
+                    }
+                    return this.el("line", attr);
+                };
+                /*
+                 * \ Paper.polyline [ method ] * Draws a polyline * - points (array) array
+                 * of points or - varargs (…) points = (object) the `polyline` element * >
+                 * Usage | var p1 = paper.polyline([10, 10, 100, 100]); | var p2 =
+                 * paper.polyline(10, 10, 100, 100); \
+                 */
+                proto.polyline = function(points) {
+                    if (arguments.length > 1) {
+                        points = Array.prototype.slice.call(arguments, 0);
+                    }
+                    var attr = {};
+                    if (is(points, "object") && !is(points, "array")) {
+                        attr = points;
+                    } else if (points != null) {
+                        attr = {
+                            points: points
+                        };
+                    }
+                    return this.el("polyline", attr);
+                };
+                /*
+                 * \ Paper.polygon [ method ] * Draws a polygon. See @Paper.polyline \
+                 */
+                proto.polygon = function(points) {
+                    if (arguments.length > 1) {
+                        points = Array.prototype.slice.call(arguments, 0);
+                    }
+                    var attr = {};
+                    if (is(points, "object") && !is(points, "array")) {
+                        attr = points;
+                    } else if (points != null) {
+                        attr = {
+                            points: points
+                        };
+                    }
+                    return this.el("polygon", attr);
+                };
+                // gradients
+                (function() {
+                    var $ = Snap._.$;
+                    // gradients' helpers
+                    function Gstops() {
+                        return this.selectAll("stop");
+                    }
+
+                    function GaddStop(color, offset) {
+                        var stop = $("stop"),
+                            attr = {
+                                offset: +offset + "%"
+                            };
+                        color = Snap.color(color);
+                        attr["stop-color"] = color.hex;
+                        if (color.opacity < 1) {
+                            attr["stop-opacity"] = color.opacity;
+                        }
+                        $(stop, attr);
+                        this.node.appendChild(stop);
+                        return this;
+                    }
+
+                    function GgetBBox() {
+                        if (this.type == "linearGradient") {
+                            var x1 = $(this.node, "x1") || 0,
+                                x2 = $(this.node, "x2") || 1,
+                                y1 = $(this.node, "y1") || 0,
+                                y2 = $(this.node, "y2") || 0;
+                            return Snap._.box(x1, y1, math.abs(x2 - x1), math.abs(y2 - y1));
+                        } else {
+                            var cx = this.node.cx || .5,
+                                cy = this.node.cy || .5,
+                                r = this.node.r || 0;
+                            return Snap._.box(cx - r, cy - r, r * 2, r * 2);
+                        }
+                    }
+
+                    function gradient(defs, str) {
+                        var grad = eve("snap.util.grad.parse", null, str).firstDefined(),
+                            el;
+                        if (!grad) {
+                            return null;
+                        }
+                        grad.params.unshift(defs);
+                        if (grad.type.toLowerCase() == "l") {
+                            el = gradientLinear.apply(0, grad.params);
+                        } else {
+                            el = gradientRadial.apply(0, grad.params);
+                        }
+                        if (grad.type != grad.type.toLowerCase()) {
+                            $(el.node, {
+                                gradientUnits: "userSpaceOnUse"
+                            });
+                        }
+                        var stops = grad.stops,
+                            len = stops.length,
+                            start = 0,
+                            j = 0;
+
+                        function seed(i, end) {
+                            var step = (end - start) / (i - j);
+                            for (var k = j; k < i; k++) {
+                                stops[k].offset = +(+start + step * (k - j)).toFixed(2);
+                            }
+                            j = i;
+                            start = end;
+                        }
+                        len--;
+                        for (var i = 0; i < len; i++)
+                            if ("offset" in stops[i]) {
+                                seed(i, stops[i].offset);
+                            }
+                        stops[len].offset = stops[len].offset || 100;
+                        seed(len, stops[len].offset);
+                        for (i = 0; i <= len; i++) {
+                            var stop = stops[i];
+                            el.addStop(stop.color, stop.offset);
+                        }
+                        return el;
+                    }
+
+                    function gradientLinear(defs, x1, y1, x2, y2) {
+                        var el = Snap._.make("linearGradient", defs);
+                        el.stops = Gstops;
+                        el.addStop = GaddStop;
+                        el.getBBox = GgetBBox;
+                        if (x1 != null) {
+                            $(el.node, {
+                                x1: x1,
+                                y1: y1,
+                                x2: x2,
+                                y2: y2
+                            });
+                        }
+                        return el;
+                    }
+
+                    function gradientRadial(defs, cx, cy, r, fx, fy) {
+                        var el = Snap._.make("radialGradient", defs);
+                        el.stops = Gstops;
+                        el.addStop = GaddStop;
+                        el.getBBox = GgetBBox;
+                        if (cx != null) {
+                            $(el.node, {
+                                cx: cx,
+                                cy: cy,
+                                r: r
+                            });
+                        }
+                        if (fx != null && fy != null) {
+                            $(el.node, {
+                                fx: fx,
+                                fy: fy
+                            });
+                        }
+                        return el;
+                    }
+                    /*
+                     * \ Paper.gradient [ method ] * Creates a gradient element * - gradient
+                     * (string) gradient descriptor > Gradient Descriptor The gradient
+                     * descriptor is an expression formatted as follows: `<type>(<coords>)<colors>`.
+                     * The `<type>` can be either linear or radial. The uppercase `L` or
+                     * `R` letters indicate absolute coordinates offset from the SVG
+                     * surface. Lowercase `l` or `r` letters indicate coordinates calculated
+                     * relative to the element to which the gradient is applied. Coordinates
+                     * specify a linear gradient vector as `x1`, `y1`, `x2`, `y2`, or a
+                     * radial gradient as `cx`, `cy`, `r` and optional `fx`, `fy` specifying
+                     * a focal point away from the center of the circle. Specify `<colors>`
+                     * as a list of dash-separated CSS color values. Each color may be
+                     * followed by a custom offset value, separated with a colon character. >
+                     * Examples Linear gradient, relative from top-left corner to
+                     * bottom-right corner, from black through red to white: | var g =
+                     * paper.gradient("l(0, 0, 1, 1)#000-#f00-#fff"); Linear gradient,
+                     * absolute from (0, 0) to (100, 100), from black through red at 25% to
+                     * white: | var g = paper.gradient("L(0, 0, 100,
+                     * 100)#000-#f00:25-#fff"); Radial gradient, relative from the center of
+                     * the element with radius half the width, from black to white: | var g =
+                     * paper.gradient("r(0.5, 0.5, 0.5)#000-#fff"); To apply the gradient: |
+                     * paper.circle(50, 50, 40).attr({ | fill: g | }); = (object) the
+                     * `gradient` element \
+                     */
+                    proto.gradient = function(str) {
+                        return gradient(this.defs, str);
+                    };
+                    proto.gradientLinear = function(x1, y1, x2, y2) {
+                        return gradientLinear(this.defs, x1, y1, x2, y2);
+                    };
+                    proto.gradientRadial = function(cx, cy, r, fx, fy) {
+                        return gradientRadial(this.defs, cx, cy, r, fx, fy);
+                    };
+                    /*
+                     * \ Paper.toString [ method ] * Returns SVG code for the @Paper =
+                     * (string) SVG code for the @Paper \
+                     */
+                    proto.toString = function() {
+                        var doc = this.node.ownerDocument,
+                            f = doc.createDocumentFragment(),
+                            d = doc.createElement("div"),
+                            svg = this.node.cloneNode(true),
+                            res;
+                        f.appendChild(d);
+                        d.appendChild(svg);
+                        Snap._.$(svg, {
+                            xmlns: "http://www.w3.org/2000/svg"
+                        });
+                        res = d.innerHTML;
+                        f.removeChild(f.firstChild);
+                        return res;
+                    };
+                    /*
+                     * \ Paper.toDataURL [ method ] * Returns SVG code for the @Paper as
+                     * Data URI string. = (string) Data URI string \
+                     */
+                    proto.toDataURL = function() {
+                        if (window && window.btoa) {
+                            return "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(this)));
+                        }
+                    };
+                    /*
+                     * \ Paper.clear [ method ] * Removes all child nodes of the paper,
+                     * except <defs>. \
+                     */
+                    proto.clear = function() {
+                        var node = this.node.firstChild,
+                            next;
+                        while (node) {
+                            next = node.nextSibling;
+                            if (node.tagName != "defs") {
+                                node.parentNode.removeChild(node);
+                            } else {
+                                proto.clear.call({
+                                    node: node
+                                });
+                            }
+                            node = next;
+                        }
+                    };
+                }());
+            });
+
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob) {
+                var elproto = Element.prototype,
+                    is = Snap.is,
+                    clone = Snap._.clone,
+                    has = "hasOwnProperty",
+                    p2s = /,?([a-z]),?/gi,
+                    toFloat = parseFloat,
+                    math = Math,
+                    PI = math.PI,
+                    mmin = math.min,
+                    mmax = math.max,
+                    pow = math.pow,
+                    abs = math.abs;
+
+                function paths(ps) {
+                    var p = paths.ps = paths.ps || {};
+                    if (p[ps]) {
+                        p[ps].sleep = 100;
+                    } else {
+                        p[ps] = {
+                            sleep: 100
+                        };
+                    }
+                    setTimeout(function() {
+                        for (var key in p)
+                            if (p[has](key) && key != ps) {
+                                p[key].sleep--;
+                                !p[key].sleep && delete p[key];
+                            }
+                    });
+                    return p[ps];
+                }
+
+                function box(x, y, width, height) {
+                    if (x == null) {
+                        x = y = width = height = 0;
+                    }
+                    if (y == null) {
+                        y = x.y;
+                        width = x.width;
+                        height = x.height;
+                        x = x.x;
+                    }
+                    return {
+                        x: x,
+                        y: y,
+                        width: width,
+                        w: width,
+                        height: height,
+                        h: height,
+                        x2: x + width,
+                        y2: y + height,
+                        cx: x + width / 2,
+                        cy: y + height / 2,
+                        r1: math.min(width, height) / 2,
+                        r2: math.max(width, height) / 2,
+                        r0: math.sqrt(width * width + height * height) / 2,
+                        path: rectPath(x, y, width, height),
+                        vb: [x, y, width, height].join(" ")
+                    };
+                }
+
+                function toString() {
+                    return this.join(",").replace(p2s, "$1");
+                }
+
+                function pathClone(pathArray) {
+                    var res = clone(pathArray);
+                    res.toString = toString;
+                    return res;
+                }
+
+                function getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
+                    if (length == null) {
+                        return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
+                    } else {
+                        return findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y,
+                            getTotLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));
+                    }
+                }
+
+                function getLengthFactory(istotal, subpath) {
+                    function O(val) {
+                        return +(+val).toFixed(3);
+                    }
+                    return Snap._.cacher(function(path, length, onlystart) {
+                        if (path instanceof Element) {
+                            path = path.attr("d");
+                        }
+                        path = path2curve(path);
+                        var x, y, p, l, sp = "",
+                            subpaths = {},
+                            point,
+                            len = 0;
+                        for (var i = 0, ii = path.length; i < ii; i++) {
+                            p = path[i];
+                            if (p[0] == "M") {
+                                x = +p[1];
+                                y = +p[2];
+                            } else {
+                                l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
+                                if (len + l > length) {
+                                    if (subpath && !subpaths.start) {
+                                        point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
+                                        sp += [
+                                            "C" + O(point.start.x),
+                                            O(point.start.y),
+                                            O(point.m.x),
+                                            O(point.m.y),
+                                            O(point.x),
+                                            O(point.y)
+                                        ];
+                                        if (onlystart) {
+                                            return sp;
+                                        }
+                                        subpaths.start = sp;
+                                        sp = [
+                                            "M" + O(point.x),
+                                            O(point.y) + "C" + O(point.n.x),
+                                            O(point.n.y),
+                                            O(point.end.x),
+                                            O(point.end.y),
+                                            O(p[5]),
+                                            O(p[6])
+                                        ].join();
+                                        len += l;
+                                        x = +p[5];
+                                        y = +p[6];
+                                        continue;
+                                    }
+                                    if (!istotal && !subpath) {
+                                        point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
+                                        return point;
+                                    }
+                                }
+                                len += l;
+                                x = +p[5];
+                                y = +p[6];
+                            }
+                            sp += p.shift() + p;
+                        }
+                        subpaths.end = sp;
+                        point = istotal ? len : subpath ? subpaths : findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
+                        return point;
+                    }, null, Snap._.clone);
+                }
+                var getTotalLength = getLengthFactory(1),
+                    getPointAtLength = getLengthFactory(),
+                    getSubpathsAtLength = getLengthFactory(0, 1);
+
+                function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
+                    var t1 = 1 - t,
+                        t13 = pow(t1, 3),
+                        t12 = pow(t1, 2),
+                        t2 = t * t,
+                        t3 = t2 * t,
+                        x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
+                        y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,
+                        mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),
+                        my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),
+                        nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),
+                        ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),
+                        ax = t1 * p1x + t * c1x,
+                        ay = t1 * p1y + t * c1y,
+                        cx = t1 * c2x + t * p2x,
+                        cy = t1 * c2y + t * p2y,
+                        alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);
+                    // (mx > nx || my < ny) && (alpha += 180);
+                    return {
+                        x: x,
+                        y: y,
+                        m: {
+                            x: mx,
+                            y: my
+                        },
+                        n: {
+                            x: nx,
+                            y: ny
+                        },
+                        start: {
+                            x: ax,
+                            y: ay
+                        },
+                        end: {
+                            x: cx,
+                            y: cy
+                        },
+                        alpha: alpha
+                    };
+                }
+
+                function bezierBBox(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
+                    if (!Snap.is(p1x, "array")) {
+                        p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];
+                    }
+                    var bbox = curveDim.apply(null, p1x);
+                    return box(
+                        bbox.min.x,
+                        bbox.min.y,
+                        bbox.max.x - bbox.min.x,
+                        bbox.max.y - bbox.min.y
+                    );
+                }
+
+                function isPointInsideBBox(bbox, x, y) {
+                    return x >= bbox.x &&
+                        x <= bbox.x + bbox.width &&
+                        y >= bbox.y &&
+                        y <= bbox.y + bbox.height;
+                }
+
+                function isBBoxIntersect(bbox1, bbox2) {
+                    bbox1 = box(bbox1);
+                    bbox2 = box(bbox2);
+                    return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);
+                }
+
+                function base3(t, p1, p2, p3, p4) {
+                    var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
+                        t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
+                    return t * t2 - 3 * p1 + 3 * p2;
+                }
+
+                function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {
+                    if (z == null) {
+                        z = 1;
+                    }
+                    z = z > 1 ? 1 : z < 0 ? 0 : z;
+                    var z2 = z / 2,
+                        n = 12,
+                        Tvalues = [-.1252, .1252, -.3678, .3678, -.5873, .5873, -.7699, .7699, -.9041, .9041, -.9816, .9816],
+                        Cvalues = [0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472],
+                        sum = 0;
+                    for (var i = 0; i < n; i++) {
+                        var ct = z2 * Tvalues[i] + z2,
+                            xbase = base3(ct, x1, x2, x3, x4),
+                            ybase = base3(ct, y1, y2, y3, y4),
+                            comb = xbase * xbase + ybase * ybase;
+                        sum += Cvalues[i] * math.sqrt(comb);
+                    }
+                    return z2 * sum;
+                }
+
+                function getTotLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {
+                    if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {
+                        return;
+                    }
+                    var t = 1,
+                        step = t / 2,
+                        t2 = t - step,
+                        l,
+                        e = .01;
+                    l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
+                    while (abs(l - ll) > e) {
+                        step /= 2;
+                        t2 += (l < ll ? 1 : -1) * step;
+                        l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);
+                    }
+                    return t2;
+                }
+
+                function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
+                    if (
+                        mmax(x1, x2) < mmin(x3, x4) ||
+                        mmin(x1, x2) > mmax(x3, x4) ||
+                        mmax(y1, y2) < mmin(y3, y4) ||
+                        mmin(y1, y2) > mmax(y3, y4)
+                    ) {
+                        return;
+                    }
+                    var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),
+                        ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),
+                        denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
+
+                    if (!denominator) {
+                        return;
+                    }
+                    var px = nx / denominator,
+                        py = ny / denominator,
+                        px2 = +px.toFixed(2),
+                        py2 = +py.toFixed(2);
+                    if (
+                        px2 < +mmin(x1, x2).toFixed(2) ||
+                        px2 > +mmax(x1, x2).toFixed(2) ||
+                        px2 < +mmin(x3, x4).toFixed(2) ||
+                        px2 > +mmax(x3, x4).toFixed(2) ||
+                        py2 < +mmin(y1, y2).toFixed(2) ||
+                        py2 > +mmax(y1, y2).toFixed(2) ||
+                        py2 < +mmin(y3, y4).toFixed(2) ||
+                        py2 > +mmax(y3, y4).toFixed(2)
+                    ) {
+                        return;
+                    }
+                    return {
+                        x: px,
+                        y: py
+                    };
+                }
+
+                function inter(bez1, bez2) {
+                    return interHelper(bez1, bez2);
+                }
+
+                function interCount(bez1, bez2) {
+                    return interHelper(bez1, bez2, 1);
+                }
+
+                function interHelper(bez1, bez2, justCount) {
+                    var bbox1 = bezierBBox(bez1),
+                        bbox2 = bezierBBox(bez2);
+                    if (!isBBoxIntersect(bbox1, bbox2)) {
+                        return justCount ? 0 : [];
+                    }
+                    var l1 = bezlen.apply(0, bez1),
+                        l2 = bezlen.apply(0, bez2),
+                        n1 = ~~(l1 / 8),
+                        n2 = ~~(l2 / 8),
+                        dots1 = [],
+                        dots2 = [],
+                        xy = {},
+                        res = justCount ? 0 : [];
+                    for (var i = 0; i < n1 + 1; i++) {
+                        var p = findDotsAtSegment.apply(0, bez1.concat(i / n1));
+                        dots1.push({
+                            x: p.x,
+                            y: p.y,
+                            t: i / n1
+                        });
+                    }
+                    for (i = 0; i < n2 + 1; i++) {
+                        p = findDotsAtSegment.apply(0, bez2.concat(i / n2));
+                        dots2.push({
+                            x: p.x,
+                            y: p.y,
+                            t: i / n2
+                        });
+                    }
+                    for (i = 0; i < n1; i++) {
+                        for (var j = 0; j < n2; j++) {
+                            var di = dots1[i],
+                                di1 = dots1[i + 1],
+                                dj = dots2[j],
+                                dj1 = dots2[j + 1],
+                                ci = abs(di1.x - di.x) < .001 ? "y" : "x",
+                                cj = abs(dj1.x - dj.x) < .001 ? "y" : "x",
+                                is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);
+                            if (is) {
+                                if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) {
+                                    continue;
+                                }
+                                xy[is.x.toFixed(4)] = is.y.toFixed(4);
+                                var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),
+                                    t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);
+                                if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
+                                    if (justCount) {
+                                        res++;
+                                    } else {
+                                        res.push({
+                                            x: is.x,
+                                            y: is.y,
+                                            t1: t1,
+                                            t2: t2
+                                        });
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    return res;
+                }
+
+                function pathIntersection(path1, path2) {
+                    return interPathHelper(path1, path2);
+                }
+
+                function pathIntersectionNumber(path1, path2) {
+                    return interPathHelper(path1, path2, 1);
+                }
+
+                function interPathHelper(path1, path2, justCount) {
+                    path1 = path2curve(path1);
+                    path2 = path2curve(path2);
+                    var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,
+                        res = justCount ? 0 : [];
+                    for (var i = 0, ii = path1.length; i < ii; i++) {
+                        var pi = path1[i];
+                        if (pi[0] == "M") {
+                            x1 = x1m = pi[1];
+                            y1 = y1m = pi[2];
+                        } else {
+                            if (pi[0] == "C") {
+                                bez1 = [x1, y1].concat(pi.slice(1));
+                                x1 = bez1[6];
+                                y1 = bez1[7];
+                            } else {
+                                bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];
+                                x1 = x1m;
+                                y1 = y1m;
+                            }
+                            for (var j = 0, jj = path2.length; j < jj; j++) {
+                                var pj = path2[j];
+                                if (pj[0] == "M") {
+                                    x2 = x2m = pj[1];
+                                    y2 = y2m = pj[2];
+                                } else {
+                                    if (pj[0] == "C") {
+                                        bez2 = [x2, y2].concat(pj.slice(1));
+                                        x2 = bez2[6];
+                                        y2 = bez2[7];
+                                    } else {
+                                        bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];
+                                        x2 = x2m;
+                                        y2 = y2m;
+                                    }
+                                    var intr = interHelper(bez1, bez2, justCount);
+                                    if (justCount) {
+                                        res += intr;
+                                    } else {
+                                        for (var k = 0, kk = intr.length; k < kk; k++) {
+                                            intr[k].segment1 = i;
+                                            intr[k].segment2 = j;
+                                            intr[k].bez1 = bez1;
+                                            intr[k].bez2 = bez2;
+                                        }
+                                        res = res.concat(intr);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    return res;
+                }
+
+                function isPointInsidePath(path, x, y) {
+                    var bbox = pathBBox(path);
+                    return isPointInsideBBox(bbox, x, y) &&
+                        interPathHelper(path, [
+                            ["M", x, y],
+                            ["H", bbox.x2 + 10]
+                        ], 1) % 2 == 1;
+                }
+
+                function pathBBox(path) {
+                    var pth = paths(path);
+                    if (pth.bbox) {
+                        return clone(pth.bbox);
+                    }
+                    if (!path) {
+                        return box();
+                    }
+                    path = path2curve(path);
+                    var x = 0,
+                        y = 0,
+                        X = [],
+                        Y = [],
+                        p;
+                    for (var i = 0, ii = path.length; i < ii; i++) {
+                        p = path[i];
+                        if (p[0] == "M") {
+                            x = p[1];
+                            y = p[2];
+                            X.push(x);
+                            Y.push(y);
+                        } else {
+                            var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
+                            X = X.concat(dim.min.x, dim.max.x);
+                            Y = Y.concat(dim.min.y, dim.max.y);
+                            x = p[5];
+                            y = p[6];
+                        }
+                    }
+                    var xmin = mmin.apply(0, X),
+                        ymin = mmin.apply(0, Y),
+                        xmax = mmax.apply(0, X),
+                        ymax = mmax.apply(0, Y),
+                        bb = box(xmin, ymin, xmax - xmin, ymax - ymin);
+                    pth.bbox = clone(bb);
+                    return bb;
+                }
+
+                function rectPath(x, y, w, h, r) {
+                    if (r) {
+                        return [
+                            ["M", +x + (+r), y],
+                            ["l", w - r * 2, 0],
+                            ["a", r, r, 0, 0, 1, r, r],
+                            ["l", 0, h - r * 2],
+                            ["a", r, r, 0, 0, 1, -r, r],
+                            ["l", r * 2 - w, 0],
+                            ["a", r, r, 0, 0, 1, -r, -r],
+                            ["l", 0, r * 2 - h],
+                            ["a", r, r, 0, 0, 1, r, -r],
+                            ["z"]
+                        ];
+                    }
+                    var res = [
+                        ["M", x, y],
+                        ["l", w, 0],
+                        ["l", 0, h],
+                        ["l", -w, 0],
+                        ["z"]
+                    ];
+                    res.toString = toString;
+                    return res;
+                }
+
+                function ellipsePath(x, y, rx, ry, a) {
+                    if (a == null && ry == null) {
+                        ry = rx;
+                    }
+                    x = +x;
+                    y = +y;
+                    rx = +rx;
+                    ry = +ry;
+                    if (a != null) {
+                        var rad = Math.PI / 180,
+                            x1 = x + rx * Math.cos(-ry * rad),
+                            x2 = x + rx * Math.cos(-a * rad),
+                            y1 = y + rx * Math.sin(-ry * rad),
+                            y2 = y + rx * Math.sin(-a * rad),
+                            res = [
+                                ["M", x1, y1],
+                                ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]
+                            ];
+                    } else {
+                        res = [
+                            ["M", x, y],
+                            ["m", 0, -ry],
+                            ["a", rx, ry, 0, 1, 1, 0, 2 * ry],
+                            ["a", rx, ry, 0, 1, 1, 0, -2 * ry],
+                            ["z"]
+                        ];
+                    }
+                    res.toString = toString;
+                    return res;
+                }
+                var unit2px = Snap._unit2px,
+                    getPath = {
+                        path: function(el) {
+                            return el.attr("path");
+                        },
+                        circle: function(el) {
+                            var attr = unit2px(el);
+                            return ellipsePath(attr.cx, attr.cy, attr.r);
+                        },
+                        ellipse: function(el) {
+                            var attr = unit2px(el);
+                            return ellipsePath(attr.cx || 0, attr.cy || 0, attr.rx, attr.ry);
+                        },
+                        rect: function(el) {
+                            var attr = unit2px(el);
+                            return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height, attr.rx, attr.ry);
+                        },
+                        image: function(el) {
+                            var attr = unit2px(el);
+                            return rectPath(attr.x || 0, attr.y || 0, attr.width, attr.height);
+                        },
+                        line: function(el) {
+                            return "M" + [el.attr("x1") || 0, el.attr("y1") || 0, el.attr("x2"), el.attr("y2")];
+                        },
+                        polyline: function(el) {
+                            return "M" + el.attr("points");
+                        },
+                        polygon: function(el) {
+                            return "M" + el.attr("points") + "z";
+                        },
+                        deflt: function(el) {
+                            var bbox = el.node.getBBox();
+                            return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
+                        }
+                    };
+
+                function pathToRelative(pathArray) {
+                    var pth = paths(pathArray),
+                        lowerCase = String.prototype.toLowerCase;
+                    if (pth.rel) {
+                        return pathClone(pth.rel);
+                    }
+                    if (!Snap.is(pathArray, "array") || !Snap.is(pathArray && pathArray[0], "array")) {
+                        pathArray = Snap.parsePathString(pathArray);
+                    }
+                    var res = [],
+                        x = 0,
+                        y = 0,
+                        mx = 0,
+                        my = 0,
+                        start = 0;
+                    if (pathArray[0][0] == "M") {
+                        x = pathArray[0][1];
+                        y = pathArray[0][2];
+                        mx = x;
+                        my = y;
+                        start++;
+                        res.push(["M", x, y]);
+                    }
+                    for (var i = start, ii = pathArray.length; i < ii; i++) {
+                        var r = res[i] = [],
+                            pa = pathArray[i];
+                        if (pa[0] != lowerCase.call(pa[0])) {
+                            r[0] = lowerCase.call(pa[0]);
+                            switch (r[0]) {
+                                case "a":
+                                    r[1] = pa[1];
+                                    r[2] = pa[2];
+                                    r[3] = pa[3];
+                                    r[4] = pa[4];
+                                    r[5] = pa[5];
+                                    r[6] = +(pa[6] - x).toFixed(3);
+                                    r[7] = +(pa[7] - y).toFixed(3);
+                                    break;
+                                case "v":
+                                    r[1] = +(pa[1] - y).toFixed(3);
+                                    break;
+                                case "m":
+                                    mx = pa[1];
+                                    my = pa[2];
+                                default:
+                                    for (var j = 1, jj = pa.length; j < jj; j++) {
+                                        r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
+                                    }
+                            }
+                        } else {
+                            r = res[i] = [];
+                            if (pa[0] == "m") {
+                                mx = pa[1] + x;
+                                my = pa[2] + y;
+                            }
+                            for (var k = 0, kk = pa.length; k < kk; k++) {
+                                res[i][k] = pa[k];
+                            }
+                        }
+                        var len = res[i].length;
+                        switch (res[i][0]) {
+                            case "z":
+                                x = mx;
+                                y = my;
+                                break;
+                            case "h":
+                                x += +res[i][len - 1];
+                                break;
+                            case "v":
+                                y += +res[i][len - 1];
+                                break;
+                            default:
+                                x += +res[i][len - 2];
+                                y += +res[i][len - 1];
+                        }
+                    }
+                    res.toString = toString;
+                    pth.rel = pathClone(res);
+                    return res;
+                }
+
+                function pathToAbsolute(pathArray) {
+                    var pth = paths(pathArray);
+                    if (pth.abs) {
+                        return pathClone(pth.abs);
+                    }
+                    if (!is(pathArray, "array") || !is(pathArray && pathArray[0], "array")) { // rough
+                        // assumption
+                        pathArray = Snap.parsePathString(pathArray);
+                    }
+                    if (!pathArray || !pathArray.length) {
+                        return [
+                            ["M", 0, 0]
+                        ];
+                    }
+                    var res = [],
+                        x = 0,
+                        y = 0,
+                        mx = 0,
+                        my = 0,
+                        start = 0,
+                        pa0;
+                    if (pathArray[0][0] == "M") {
+                        x = +pathArray[0][1];
+                        y = +pathArray[0][2];
+                        mx = x;
+                        my = y;
+                        start++;
+                        res[0] = ["M", x, y];
+                    }
+                    var crz = pathArray.length == 3 &&
+                        pathArray[0][0] == "M" &&
+                        pathArray[1][0].toUpperCase() == "R" &&
+                        pathArray[2][0].toUpperCase() == "Z";
+                    for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
+                        res.push(r = []);
+                        pa = pathArray[i];
+                        pa0 = pa[0];
+                        if (pa0 != pa0.toUpperCase()) {
+                            r[0] = pa0.toUpperCase();
+                            switch (r[0]) {
+                                case "A":
+                                    r[1] = pa[1];
+                                    r[2] = pa[2];
+                                    r[3] = pa[3];
+                                    r[4] = pa[4];
+                                    r[5] = pa[5];
+                                    r[6] = +pa[6] + x;
+                                    r[7] = +pa[7] + y;
+                                    break;
+                                case "V":
+                                    r[1] = +pa[1] + y;
+                                    break;
+                                case "H":
+                                    r[1] = +pa[1] + x;
+                                    break;
+                                case "R":
+                                    var dots = [x, y].concat(pa.slice(1));
+                                    for (var j = 2, jj = dots.length; j < jj; j++) {
+                                        dots[j] = +dots[j] + x;
+                                        dots[++j] = +dots[j] + y;
+                                    }
+                                    res.pop();
+                                    res = res.concat(catmullRom2bezier(dots, crz));
+                                    break;
+                                case "O":
+                                    res.pop();
+                                    dots = ellipsePath(x, y, pa[1], pa[2]);
+                                    dots.push(dots[0]);
+                                    res = res.concat(dots);
+                                    break;
+                                case "U":
+                                    res.pop();
+                                    res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
+                                    r = ["U"].concat(res[res.length - 1].slice(-2));
+                                    break;
+                                case "M":
+                                    mx = +pa[1] + x;
+                                    my = +pa[2] + y;
+                                default:
+                                    for (j = 1, jj = pa.length; j < jj; j++) {
+                                        r[j] = +pa[j] + ((j % 2) ? x : y);
+                                    }
+                            }
+                        } else if (pa0 == "R") {
+                            dots = [x, y].concat(pa.slice(1));
+                            res.pop();
+                            res = res.concat(catmullRom2bezier(dots, crz));
+                            r = ["R"].concat(pa.slice(-2));
+                        } else if (pa0 == "O") {
+                            res.pop();
+                            dots = ellipsePath(x, y, pa[1], pa[2]);
+                            dots.push(dots[0]);
+                            res = res.concat(dots);
+                        } else if (pa0 == "U") {
+                            res.pop();
+                            res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3]));
+                            r = ["U"].concat(res[res.length - 1].slice(-2));
+                        } else {
+                            for (var k = 0, kk = pa.length; k < kk; k++) {
+                                r[k] = pa[k];
+                            }
+                        }
+                        pa0 = pa0.toUpperCase();
+                        if (pa0 != "O") {
+                            switch (r[0]) {
+                                case "Z":
+                                    x = +mx;
+                                    y = +my;
+                                    break;
+                                case "H":
+                                    x = r[1];
+                                    break;
+                                case "V":
+                                    y = r[1];
+                                    break;
+                                case "M":
+                                    mx = r[r.length - 2];
+                                    my = r[r.length - 1];
+                                default:
+                                    x = r[r.length - 2];
+                                    y = r[r.length - 1];
+                            }
+                        }
+                    }
+                    res.toString = toString;
+                    pth.abs = pathClone(res);
+                    return res;
+                }
+
+                function l2c(x1, y1, x2, y2) {
+                    return [x1, y1, x2, y2, x2, y2];
+                }
+
+                function q2c(x1, y1, ax, ay, x2, y2) {
+                    var _13 = 1 / 3,
+                        _23 = 2 / 3;
+                    return [
+                        _13 * x1 + _23 * ax,
+                        _13 * y1 + _23 * ay,
+                        _13 * x2 + _23 * ax,
+                        _13 * y2 + _23 * ay,
+                        x2,
+                        y2
+                    ];
+                }
+
+                function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
+                    // for more information of where this math came from visit:
+                    // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
+                    var _120 = PI * 120 / 180,
+                        rad = PI / 180 * (+angle || 0),
+                        res = [],
+                        xy,
+                        rotate = Snap._.cacher(function(x, y, rad) {
+                            var X = x * math.cos(rad) - y * math.sin(rad),
+                                Y = x * math.sin(rad) + y * math.cos(rad);
+                            return {
+                                x: X,
+                                y: Y
+                            };
+                        });
+                    if (!recursive) {
+                        xy = rotate(x1, y1, -rad);
+                        x1 = xy.x;
+                        y1 = xy.y;
+                        xy = rotate(x2, y2, -rad);
+                        x2 = xy.x;
+                        y2 = xy.y;
+                        var cos = math.cos(PI / 180 * angle),
+                            sin = math.sin(PI / 180 * angle),
+                            x = (x1 - x2) / 2,
+                            y = (y1 - y2) / 2;
+                        var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
+                        if (h > 1) {
+                            h = math.sqrt(h);
+                            rx = h * rx;
+                            ry = h * ry;
+                        }
+                        var rx2 = rx * rx,
+                            ry2 = ry * ry,
+                            k = (large_arc_flag == sweep_flag ? -1 : 1) *
+                            math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
+                            cx = k * rx * y / ry + (x1 + x2) / 2,
+                            cy = k * -ry * x / rx + (y1 + y2) / 2,
+                            f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
+                            f2 = math.asin(((y2 - cy) / ry).toFixed(9));
+
+                        f1 = x1 < cx ? PI - f1 : f1;
+                        f2 = x2 < cx ? PI - f2 : f2;
+                        f1 < 0 && (f1 = PI * 2 + f1);
+                        f2 < 0 && (f2 = PI * 2 + f2);
+                        if (sweep_flag && f1 > f2) {
+                            f1 = f1 - PI * 2;
+                        }
+                        if (!sweep_flag && f2 > f1) {
+                            f2 = f2 - PI * 2;
+                        }
+                    } else {
+                        f1 = recursive[0];
+                        f2 = recursive[1];
+                        cx = recursive[2];
+                        cy = recursive[3];
+                    }
+                    var df = f2 - f1;
+                    if (abs(df) > _120) {
+                        var f2old = f2,
+                            x2old = x2,
+                            y2old = y2;
+                        f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
+                        x2 = cx + rx * math.cos(f2);
+                        y2 = cy + ry * math.sin(f2);
+                        res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
+                    }
+                    df = f2 - f1;
+                    var c1 = math.cos(f1),
+                        s1 = math.sin(f1),
+                        c2 = math.cos(f2),
+                        s2 = math.sin(f2),
+                        t = math.tan(df / 4),
+                        hx = 4 / 3 * rx * t,
+                        hy = 4 / 3 * ry * t,
+                        m1 = [x1, y1],
+                        m2 = [x1 + hx * s1, y1 - hy * c1],
+                        m3 = [x2 + hx * s2, y2 - hy * c2],
+                        m4 = [x2, y2];
+                    m2[0] = 2 * m1[0] - m2[0];
+                    m2[1] = 2 * m1[1] - m2[1];
+                    if (recursive) {
+                        return [m2, m3, m4].concat(res);
+                    } else {
+                        res = [m2, m3, m4].concat(res).join().split(",");
+                        var newres = [];
+                        for (var i = 0, ii = res.length; i < ii; i++) {
+                            newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
+                        }
+                        return newres;
+                    }
+                }
+
+                function findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
+                    var t1 = 1 - t;
+                    return {
+                        x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
+                        y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
+                    };
+                }
+
+                // Returns bounding box of cubic bezier curve.
+                // Source:
+                // http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
+                // Original version: NISHIO Hirokazu
+                // Modifications: https://github.com/timo22345
+                function curveDim(x0, y0, x1, y1, x2, y2, x3, y3) {
+                    var tvalues = [],
+                        bounds = [
+                            [],
+                            []
+                        ],
+                        a, b, c, t, t1, t2, b2ac, sqrtb2ac;
+                    for (var i = 0; i < 2; ++i) {
+                        if (i == 0) {
+                            b = 6 * x0 - 12 * x1 + 6 * x2;
+                            a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
+                            c = 3 * x1 - 3 * x0;
+                        } else {
+                            b = 6 * y0 - 12 * y1 + 6 * y2;
+                            a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
+                            c = 3 * y1 - 3 * y0;
+                        }
+                        if (abs(a) < 1e-12) {
+                            if (abs(b) < 1e-12) {
+                                continue;
+                            }
+                            t = -c / b;
+                            if (0 < t && t < 1) {
+                                tvalues.push(t);
+                            }
+                            continue;
+                        }
+                        b2ac = b * b - 4 * c * a;
+                        sqrtb2ac = math.sqrt(b2ac);
+                        if (b2ac < 0) {
+                            continue;
+                        }
+                        t1 = (-b + sqrtb2ac) / (2 * a);
+                        if (0 < t1 && t1 < 1) {
+                            tvalues.push(t1);
+                        }
+                        t2 = (-b - sqrtb2ac) / (2 * a);
+                        if (0 < t2 && t2 < 1) {
+                            tvalues.push(t2);
+                        }
+                    }
+
+                    var x, y, j = tvalues.length,
+                        jlen = j,
+                        mt;
+                    while (j--) {
+                        t = tvalues[j];
+                        mt = 1 - t;
+                        bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
+                        bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
+                    }
+
+                    bounds[0][jlen] = x0;
+                    bounds[1][jlen] = y0;
+                    bounds[0][jlen + 1] = x3;
+                    bounds[1][jlen + 1] = y3;
+                    bounds[0].length = bounds[1].length = jlen + 2;
+
+
+                    return {
+                        min: {
+                            x: mmin.apply(0, bounds[0]),
+                            y: mmin.apply(0, bounds[1])
+                        },
+                        max: {
+                            x: mmax.apply(0, bounds[0]),
+                            y: mmax.apply(0, bounds[1])
+                        }
+                    };
+                }
+
+                function path2curve(path, path2) {
+                    var pth = !path2 && paths(path);
+                    if (!path2 && pth.curve) {
+                        return pathClone(pth.curve);
+                    }
+                    var p = pathToAbsolute(path),
+                        p2 = path2 && pathToAbsolute(path2),
+                        attrs = {
+                            x: 0,
+                            y: 0,
+                            bx: 0,
+                            by: 0,
+                            X: 0,
+                            Y: 0,
+                            qx: null,
+                            qy: null
+                        },
+                        attrs2 = {
+                            x: 0,
+                            y: 0,
+                            bx: 0,
+                            by: 0,
+                            X: 0,
+                            Y: 0,
+                            qx: null,
+                            qy: null
+                        },
+                        processPath = function(path, d, pcom) {
+                            var nx, ny;
+                            if (!path) {
+                                return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
+                            }!(path[0] in {
+                                T: 1,
+                                Q: 1
+                            }) && (d.qx = d.qy = null);
+                            switch (path[0]) {
+                                case "M":
+                                    d.X = path[1];
+                                    d.Y = path[2];
+                                    break;
+                                case "A":
+                                    path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1))));
+                                    break;
+                                case "S":
+                                    if (pcom == "C" || pcom == "S") { // In "S" case we
+                                        // have to take into
+                                        // account, if the
+                                        // previous command
+                                        // is C/S.
+                                        nx = d.x * 2 - d.bx; // And reflect the
+                                        // previous
+                                        ny = d.y * 2 - d.by; // command's control
+                                        // point relative to
+                                        // the current
+                                        // point.
+                                    } else { // or some else or
+                                        // nothing
+                                        nx = d.x;
+                                        ny = d.y;
+                                    }
+                                    path = ["C", nx, ny].concat(path.slice(1));
+                                    break;
+                                case "T":
+                                    if (pcom == "Q" || pcom == "T") { // In "T" case we
+                                        // have to take into
+                                        // account, if the
+                                        // previous command
+                                        // is Q/T.
+                                        d.qx = d.x * 2 - d.qx; // And make a
+                                        // reflection
+                                        // similar
+                                        d.qy = d.y * 2 - d.qy; // to case "S".
+                                    } else { // or something else
+                                        // or nothing
+                                        d.qx = d.x;
+                                        d.qy = d.y;
+                                    }
+                                    path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
+                                    break;
+                                case "Q":
+                                    d.qx = path[1];
+                                    d.qy = path[2];
+                                    path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
+                                    break;
+                                case "L":
+                                    path = ["C"].concat(l2c(d.x, d.y, path[1], path[2]));
+                                    break;
+                                case "H":
+                                    path = ["C"].concat(l2c(d.x, d.y, path[1], d.y));
+                                    break;
+                                case "V":
+                                    path = ["C"].concat(l2c(d.x, d.y, d.x, path[1]));
+                                    break;
+                                case "Z":
+                                    path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y));
+                                    break;
+                            }
+                            return path;
+                        },
+                        fixArc = function(pp, i) {
+                            if (pp[i].length > 7) {
+                                pp[i].shift();
+                                var pi = pp[i];
+                                while (pi.length) {
+                                    pcoms1[i] = "A"; // if created multiple C:s, their
+                                    // original seg is saved
+                                    p2 && (pcoms2[i] = "A"); // the same as above
+                                    pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
+                                }
+                                pp.splice(i, 1);
+                                ii = mmax(p.length, p2 && p2.length || 0);
+                            }
+                        },
+                        fixM = function(path1, path2, a1, a2, i) {
+                            if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
+                                path2.splice(i, 0, ["M", a2.x, a2.y]);
+                                a1.bx = 0;
+                                a1.by = 0;
+                                a1.x = path1[i][1];
+                                a1.y = path1[i][2];
+                                ii = mmax(p.length, p2 && p2.length || 0);
+                            }
+                        },
+                        pcoms1 = [], // path commands of original path p
+                        pcoms2 = [], // path commands of original path p2
+                        pfirst = "", // temporary holder for original path command
+                        pcom = ""; // holder for previous path command of original path
+                    for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {
+                        p[i] && (pfirst = p[i][0]); // save current path command
+
+                        if (pfirst != "C") // C is not saved yet, because it may be result
+                        // of conversion
+                        {
+                            pcoms1[i] = pfirst; // Save current path command
+                            i && (pcom = pcoms1[i - 1]); // Get previous path command
+                            // pcom
+                        }
+                        p[i] = processPath(p[i], attrs, pcom); // Previous path command is
+                        // inputted to processPath
+
+                        if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the
+                        // only
+                        // command
+                        // which may produce multiple C:s
+                        // so we have to make sure that C is also C in original path
+
+                        fixArc(p, i); // fixArc adds also the right amount of A:s to
+                        // pcoms1
+
+                        if (p2) { // the same procedures is done to p2
+                            p2[i] && (pfirst = p2[i][0]);
+                            if (pfirst != "C") {
+                                pcoms2[i] = pfirst;
+                                i && (pcom = pcoms2[i - 1]);
+                            }
+                            p2[i] = processPath(p2[i], attrs2, pcom);
+
+                            if (pcoms2[i] != "A" && pfirst == "C") {
+                                pcoms2[i] = "C";
+                            }
+
+                            fixArc(p2, i);
+                        }
+                        fixM(p, p2, attrs, attrs2, i);
+                        fixM(p2, p, attrs2, attrs, i);
+                        var seg = p[i],
+                            seg2 = p2 && p2[i],
+                            seglen = seg.length,
+                            seg2len = p2 && seg2.length;
+                        attrs.x = seg[seglen - 2];
+                        attrs.y = seg[seglen - 1];
+                        attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
+                        attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
+                        attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
+                        attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
+                        attrs2.x = p2 && seg2[seg2len - 2];
+                        attrs2.y = p2 && seg2[seg2len - 1];
+                    }
+                    if (!p2) {
+                        pth.curve = pathClone(p);
+                    }
+                    return p2 ? [p, p2] : p;
+                }
+
+                function mapPath(path, matrix) {
+                    if (!matrix) {
+                        return path;
+                    }
+                    var x, y, i, j, ii, jj, pathi;
+                    path = path2curve(path);
+                    for (i = 0, ii = path.length; i < ii; i++) {
+                        pathi = path[i];
+                        for (j = 1, jj = pathi.length; j < jj; j += 2) {
+                            x = matrix.x(pathi[j], pathi[j + 1]);
+                            y = matrix.y(pathi[j], pathi[j + 1]);
+                            pathi[j] = x;
+                            pathi[j + 1] = y;
+                        }
+                    }
+                    return path;
+                }
+
+                // http://schepers.cc/getting-to-the-point
+                function catmullRom2bezier(crp, z) {
+                    var d = [];
+                    for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
+                        var p = [{
+                            x: +crp[i - 2],
+                            y: +crp[i - 1]
+                        }, {
+                            x: +crp[i],
+                            y: +crp[i + 1]
+                        }, {
+                            x: +crp[i + 2],
+                            y: +crp[i + 3]
+                        }, {
+                            x: +crp[i + 4],
+                            y: +crp[i + 5]
+                        }];
+                        if (z) {
+                            if (!i) {
+                                p[0] = {
+                                    x: +crp[iLen - 2],
+                                    y: +crp[iLen - 1]
+                                };
+                            } else if (iLen - 4 == i) {
+                                p[3] = {
+                                    x: +crp[0],
+                                    y: +crp[1]
+                                };
+                            } else if (iLen - 2 == i) {
+                                p[2] = {
+                                    x: +crp[0],
+                                    y: +crp[1]
+                                };
+                                p[3] = {
+                                    x: +crp[2],
+                                    y: +crp[3]
+                                };
+                            }
+                        } else {
+                            if (iLen - 4 == i) {
+                                p[3] = p[2];
+                            } else if (!i) {
+                                p[0] = {
+                                    x: +crp[i],
+                                    y: +crp[i + 1]
+                                };
+                            }
+                        }
+                        d.push(["C", (-p[0].x + 6 * p[1].x + p[2].x) / 6, (-p[0].y + 6 * p[1].y + p[2].y) / 6, (p[1].x + 6 * p[2].x - p[3].x) / 6, (p[1].y + 6 * p[2].y - p[3].y) / 6,
+                            p[2].x,
+                            p[2].y
+                        ]);
+                    }
+
+                    return d;
+                }
+
+                // export
+                Snap.path = paths;
+
+                /*
+                 * \ Snap.path.getTotalLength [ method ] * Returns the length of the given
+                 * path in pixels * - path (string) SVG path string * = (number) length \
+                 */
+                Snap.path.getTotalLength = getTotalLength;
+                /*
+                 * \ Snap.path.getPointAtLength [ method ] * Returns the coordinates of the
+                 * point located at the given length along the given path * - path (string)
+                 * SVG path string - length (number) length, in pixels, from the start of
+                 * the path, excluding non-rendering jumps * = (object) representation of
+                 * the point: o { o x: (number) x coordinate, o y: (number) y coordinate, o
+                 * alpha: (number) angle of derivative o } \
+                 */
+                Snap.path.getPointAtLength = getPointAtLength;
+                /*
+                 * \ Snap.path.getSubpath [ method ] * Returns the subpath of a given path
+                 * between given start and end lengths * - path (string) SVG path string -
+                 * from (number) length, in pixels, from the start of the path to the start
+                 * of the segment - to (number) length, in pixels, from the start of the
+                 * path to the end of the segment * = (string) path string definition for
+                 * the segment \
+                 */
+                Snap.path.getSubpath = function(path, from, to) {
+                    if (this.getTotalLength(path) - to < 1e-6) {
+                        return getSubpathsAtLength(path, from).end;
+                    }
+                    var a = getSubpathsAtLength(path, to, 1);
+                    return from ? getSubpathsAtLength(a, from).end : a;
+                };
+                /*
+                 * \ Element.getTotalLength [ method ] * Returns the length of the path in
+                 * pixels (only works for `path` elements) = (number) length \
+                 */
+                elproto.getTotalLength = function() {
+                    if (this.node.getTotalLength) {
+                        return this.node.getTotalLength();
+                    }
+                };
+                // SIERRA Element.getPointAtLength()/Element.getTotalLength(): If a <path>
+                // is broken into different segments, is the jump distance to the new
+                // coordinates set by the _M_ or _m_ commands calculated as part of the
+                // path's total length?
+                /*
+                 * \ Element.getPointAtLength [ method ] * Returns coordinates of the point
+                 * located at the given length on the given path (only works for `path`
+                 * elements) * - length (number) length, in pixels, from the start of the
+                 * path, excluding non-rendering jumps * = (object) representation of the
+                 * point: o { o x: (number) x coordinate, o y: (number) y coordinate, o
+                 * alpha: (number) angle of derivative o } \
+                 */
+                elproto.getPointAtLength = function(length) {
+                    return getPointAtLength(this.attr("d"), length);
+                };
+                // SIERRA Element.getSubpath(): Similar to the problem for
+                // Element.getPointAtLength(). Unclear how this would work for a segmented
+                // path. Overall, the concept of _subpath_ and what I'm calling a _segment_
+                // (series of non-_M_ or _Z_ commands) is unclear.
+                /*
+                 * \ Element.getSubpath [ method ] * Returns subpath of a given element from
+                 * given start and end lengths (only works for `path` elements) * - from
+                 * (number) length, in pixels, from the start of the path to the start of
+                 * the segment - to (number) length, in pixels, from the start of the path
+                 * to the end of the segment * = (string) path string definition for the
+                 * segment \
+                 */
+                elproto.getSubpath = function(from, to) {
+                    return Snap.path.getSubpath(this.attr("d"), from, to);
+                };
+                Snap._.box = box;
+                /*
+                 * \ Snap.path.findDotsAtSegment [ method ] * Utility method * Finds dot
+                 * coordinates on the given cubic beziér curve at the given t - p1x
+                 * (number) x of the first point of the curve - p1y (number) y of the first
+                 * point of the curve - c1x (number) x of the first anchor of the curve -
+                 * c1y (number) y of the first anchor of the curve - c2x (number) x of the
+                 * second anchor of the curve - c2y (number) y of the second anchor of the
+                 * curve - p2x (number) x of the second point of the curve - p2y (number) y
+                 * of the second point of the curve - t (number) position on the curve
+                 * (0..1) = (object) point information in format: o { o x: (number) x
+                 * coordinate of the point, o y: (number) y coordinate of the point, o m: {
+                 * o x: (number) x coordinate of the left anchor, o y: (number) y coordinate
+                 * of the left anchor o }, o n: { o x: (number) x coordinate of the right
+                 * anchor, o y: (number) y coordinate of the right anchor o }, o start: { o
+                 * x: (number) x coordinate of the start of the curve, o y: (number) y
+                 * coordinate of the start of the curve o }, o end: { o x: (number) x
+                 * coordinate of the end of the curve, o y: (number) y coordinate of the end
+                 * of the curve o }, o alpha: (number) angle of the curve derivative at the
+                 * point o } \
+                 */
+                Snap.path.findDotsAtSegment = findDotsAtSegment;
+                /*
+                 * \ Snap.path.bezierBBox [ method ] * Utility method * Returns the bounding
+                 * box of a given cubic beziér curve - p1x (number) x of the first point
+                 * of the curve - p1y (number) y of the first point of the curve - c1x
+                 * (number) x of the first anchor of the curve - c1y (number) y of the first
+                 * anchor of the curve - c2x (number) x of the second anchor of the curve -
+                 * c2y (number) y of the second anchor of the curve - p2x (number) x of the
+                 * second point of the curve - p2y (number) y of the second point of the
+                 * curve or - bez (array) array of six points for beziér curve = (object)
+                 * bounding box o { o x: (number) x coordinate of the left top point of the
+                 * box, o y: (number) y coordinate of the left top point of the box, o x2:
+                 * (number) x coordinate of the right bottom point of the box, o y2:
+                 * (number) y coordinate of the right bottom point of the box, o width:
+                 * (number) width of the box, o height: (number) height of the box o } \
+                 */
+                Snap.path.bezierBBox = bezierBBox;
+                /*
+                 * \ Snap.path.isPointInsideBBox [ method ] * Utility method * Returns
+                 * `true` if given point is inside bounding box - bbox (string) bounding box -
+                 * x (string) x coordinate of the point - y (string) y coordinate of the
+                 * point = (boolean) `true` if point is inside \
+                 */
+                Snap.path.isPointInsideBBox = isPointInsideBBox;
+                /*
+                 * \ Snap.path.isBBoxIntersect [ method ] * Utility method * Returns `true`
+                 * if two bounding boxes intersect - bbox1 (string) first bounding box -
+                 * bbox2 (string) second bounding box = (boolean) `true` if bounding boxes
+                 * intersect \
+                 */
+                Snap.path.isBBoxIntersect = isBBoxIntersect;
+                /*
+                 * \ Snap.path.intersection [ method ] * Utility method * Finds
+                 * intersections of two paths - path1 (string) path string - path2 (string)
+                 * path string = (array) dots of intersection o [ o { o x: (number) x
+                 * coordinate of the point, o y: (number) y coordinate of the point, o t1:
+                 * (number) t value for segment of path1, o t2: (number) t value for segment
+                 * of path2, o segment1: (number) order number for segment of path1, o
+                 * segment2: (number) order number for segment of path2, o bez1: (array)
+                 * eight coordinates representing beziér curve for the segment of path1,
+                 * o bez2: (array) eight coordinates representing beziér curve for the
+                 * segment of path2 o } o ] \
+                 */
+                Snap.path.intersection = pathIntersection;
+                Snap.path.intersectionNumber = pathIntersectionNumber;
+                /*
+                 * \ Snap.path.isPointInside [ method ] * Utility method * Returns `true` if
+                 * given point is inside a given closed path.
+                 * 
+                 * Note: fill mode doesn’t affect the result of this method. - path
+                 * (string) path string - x (number) x of the point - y (number) y of the
+                 * point = (boolean) `true` if point is inside the path \
+                 */
+                Snap.path.isPointInside = isPointInsidePath;
+                /*
+                 * \ Snap.path.getBBox [ method ] * Utility method * Returns the bounding
+                 * box of a given path - path (string) path string = (object) bounding box o {
+                 * o x: (number) x coordinate of the left top point of the box, o y:
+                 * (number) y coordinate of the left top point of the box, o x2: (number) x
+                 * coordinate of the right bottom point of the box, o y2: (number) y
+                 * coordinate of the right bottom point of the box, o width: (number) width
+                 * of the box, o height: (number) height of the box o } \
+                 */
+                Snap.path.getBBox = pathBBox;
+                Snap.path.get = getPath;
+                /*
+                 * \ Snap.path.toRelative [ method ] * Utility method * Converts path
+                 * coordinates into relative values - path (string) path string = (array)
+                 * path string \
+                 */
+                Snap.path.toRelative = pathToRelative;
+                /*
+                 * \ Snap.path.toAbsolute [ method ] * Utility method * Converts path
+                 * coordinates into absolute values - path (string) path string = (array)
+                 * path string \
+                 */
+                Snap.path.toAbsolute = pathToAbsolute;
+                /*
+                 * \ Snap.path.toCubic [ method ] * Utility method * Converts path to a new
+                 * path where all segments are cubic beziér curves - pathString
+                 * (string|array) path string or array of segments = (array) array of
+                 * segments \
+                 */
+                Snap.path.toCubic = path2curve;
+                /*
+                 * \ Snap.path.map [ method ] * Transform the path string with the given
+                 * matrix - path (string) path string - matrix (object) see @Matrix =
+                 * (string) transformed path string \
+                 */
+                Snap.path.map = mapPath;
+                Snap.path.toString = toString;
+                Snap.path.clone = pathClone;
+            });
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob) {
+                var elproto = Element.prototype,
+                    has = "hasOwnProperty",
+                    supportsTouch = "createTouch" in glob.doc,
+                    events = [
+                        "click", "dblclick", "mousedown", "mousemove", "mouseout",
+                        "mouseover", "mouseup", "touchstart", "touchmove", "touchend",
+                        "touchcancel", "keyup"
+                    ],
+                    touchMap = {
+                        mousedown: "touchstart",
+                        mousemove: "touchmove",
+                        mouseup: "touchend"
+                    },
+                    getScroll = function(xy, el) {
+                        var name = xy == "y" ? "scrollTop" : "scrollLeft",
+                            doc = el && el.node ? el.node.ownerDocument : glob.doc;
+                        return doc[name in doc.documentElement ? "documentElement" : "body"][name];
+                    },
+                    preventDefault = function() {
+                        this.returnValue = false;
+                    },
+                    preventTouch = function() {
+                        return this.originalEvent.preventDefault();
+                    },
+                    stopPropagation = function() {
+                        this.cancelBubble = true;
+                    },
+                    stopTouch = function() {
+                        return this.originalEvent.stopPropagation();
+                    },
+                    addEvent = (function() {
+                        if (glob.doc.addEventListener) {
+                            return function(obj, type, fn, element) {
+                                var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
+                                    f = function(e) {
+                                        var scrollY = getScroll("y", element),
+                                            scrollX = getScroll("x", element);
+                                        if (supportsTouch && touchMap[has](type)) {
+                                            for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
+                                                if (e.targetTouches[i].target == obj || obj.contains(e.targetTouches[i].target)) {
+                                                    var olde = e;
+                                                    e = e.targetTouches[i];
+                                                    e.originalEvent = olde;
+                                                    e.preventDefault = preventTouch;
+                                                    e.stopPropagation = stopTouch;
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                        var x = e.clientX + scrollX,
+                                            y = e.clientY + scrollY;
+                                        return fn.call(element, e, x, y);
+                                    };
+
+                                if (type !== realName) {
+                                    obj.addEventListener(type, f, false);
+                                }
+
+                                obj.addEventListener(realName, f, false);
+
+                                return function() {
+                                    if (type !== realName) {
+                                        obj.removeEventListener(type, f, false);
+                                    }
+
+                                    obj.removeEventListener(realName, f, false);
+                                    return true;
+                                };
+                            };
+                        } else if (glob.doc.attachEvent) {
+                            return function(obj, type, fn, element) {
+                                var f = function(e) {
+                                    e = e || element.node.ownerDocument.window.event;
+                                    var scrollY = getScroll("y", element),
+                                        scrollX = getScroll("x", element),
+                                        x = e.clientX + scrollX,
+                                        y = e.clientY + scrollY;
+                                    e.preventDefault = e.preventDefault || preventDefault;
+                                    e.stopPropagation = e.stopPropagation || stopPropagation;
+                                    return fn.call(element, e, x, y);
+                                };
+                                obj.attachEvent("on" + type, f);
+                                var detacher = function() {
+                                    obj.detachEvent("on" + type, f);
+                                    return true;
+                                };
+                                return detacher;
+                            };
+                        }
+                    })(),
+                    drag = [],
+                    dragMove = function(e) {
+                        var x = e.clientX,
+                            y = e.clientY,
+                            scrollY = getScroll("y"),
+                            scrollX = getScroll("x"),
+                            dragi,
+                            j = drag.length;
+                        while (j--) {
+                            dragi = drag[j];
+                            if (supportsTouch) {
+                                var i = e.touches && e.touches.length,
+                                    touch;
+                                while (i--) {
+                                    touch = e.touches[i];
+                                    if (touch.identifier == dragi.el._drag.id || dragi.el.node.contains(touch.target)) {
+                                        x = touch.clientX;
+                                        y = touch.clientY;
+                                        (e.originalEvent ? e.originalEvent : e).preventDefault();
+                                        break;
+                                    }
+                                }
+                            } else {
+                                e.preventDefault();
+                            }
+                            var node = dragi.el.node,
+                                o,
+                                next = node.nextSibling,
+                                parent = node.parentNode,
+                                display = node.style.display;
+                            // glob.win.opera && parent.removeChild(node);
+                            // node.style.display = "none";
+                            // o = dragi.el.paper.getElementByPoint(x, y);
+                            // node.style.display = display;
+                            // glob.win.opera && (next ? parent.insertBefore(node, next) :
+                            // parent.appendChild(node));
+                            // o && eve("snap.drag.over." + dragi.el.id, dragi.el, o);
+                            x += scrollX;
+                            y += scrollY;
+                            eve("snap.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);
+                        }
+                    },
+                    dragUp = function(e) {
+                        Snap.unmousemove(dragMove).unmouseup(dragUp);
+                        var i = drag.length,
+                            dragi;
+                        while (i--) {
+                            dragi = drag[i];
+                            dragi.el._drag = {};
+                            eve("snap.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);
+                        }
+                        drag = [];
+                    };
+                /*
+                 * \ Element.click [ method ] * Adds a click event handler to the element -
+                 * handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unclick [ method ] * Removes a click event handler from the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+
+                /*
+                 * \ Element.dblclick [ method ] * Adds a double click event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.undblclick [ method ] * Removes a double click event handler
+                 * from the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.mousedown [ method ] * Adds a mousedown event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unmousedown [ method ] * Removes a mousedown event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.mousemove [ method ] * Adds a mousemove event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unmousemove [ method ] * Removes a mousemove event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.mouseout [ method ] * Adds a mouseout event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unmouseout [ method ] * Removes a mouseout event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.mouseover [ method ] * Adds a mouseover event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unmouseover [ method ] * Removes a mouseover event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.mouseup [ method ] * Adds a mouseup event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.unmouseup [ method ] * Removes a mouseup event handler from the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+
+                /*
+                 * \ Element.touchstart [ method ] * Adds a touchstart event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.untouchstart [ method ] * Removes a touchstart event handler
+                 * from the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.touchmove [ method ] * Adds a touchmove event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.untouchmove [ method ] * Removes a touchmove event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.touchend [ method ] * Adds a touchend event handler to the
+                 * element - handler (function) handler for the event = (object) @Element \
+                 */
+                /*
+                 * \ Element.untouchend [ method ] * Removes a touchend event handler from
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+
+                /*
+                 * \ Element.touchcancel [ method ] * Adds a touchcancel event handler to
+                 * the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+                /*
+                 * \ Element.untouchcancel [ method ] * Removes a touchcancel event handler
+                 * from the element - handler (function) handler for the event = (object)
+                 * @Element \
+                 */
+                for (var i = events.length; i--;) {
+                    (function(eventName) {
+                        Snap[eventName] = elproto[eventName] = function(fn, scope) {
+                            if (Snap.is(fn, "function")) {
+                                this.events = this.events || [];
+                                this.events.push({
+                                    name: eventName,
+                                    f: fn,
+                                    unbind: addEvent(this.node || document, eventName, fn, scope || this)
+                                });
+                            }
+                            return this;
+                        };
+                        Snap["un" + eventName] =
+                            elproto["un" + eventName] = function(fn) {
+                                var events = this.events || [],
+                                    l = events.length;
+                                while (l--)
+                                    if (events[l].name == eventName &&
+                                        (events[l].f == fn || !fn)) {
+                                        events[l].unbind();
+                                        events.splice(l, 1);
+                                        !events.length && delete this.events;
+                                        return this;
+                                    }
+                                return this;
+                            };
+                    })(events[i]);
+                }
+                /*
+                 * \ Element.hover [ method ] * Adds hover event handlers to the element -
+                 * f_in (function) handler for hover in - f_out (function) handler for hover
+                 * out - icontext (object) #optional context for hover in handler - ocontext
+                 * (object) #optional context for hover out handler = (object) @Element \
+                 */
+                elproto.hover = function(f_in, f_out, scope_in, scope_out) {
+                    return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);
+                };
+                /*
+                 * \ Element.unhover [ method ] * Removes hover event handlers from the
+                 * element - f_in (function) handler for hover in - f_out (function) handler
+                 * for hover out = (object) @Element \
+                 */
+                elproto.unhover = function(f_in, f_out) {
+                    return this.unmouseover(f_in).unmouseout(f_out);
+                };
+                var draggable = [];
+                // SIERRA unclear what _context_ refers to for starting, ending, moving the
+                // drag gesture.
+                // SIERRA Element.drag(): _x position of the mouse_: Where are the x/y
+                // values offset from?
+                // SIERRA Element.drag(): much of this member's doc appears to be duplicated
+                // for some reason.
+                // SIERRA Unclear about this sentence: _Additionally following drag events
+                // will be triggered: drag.start.<id> on start, drag.end.<id> on end and
+                // drag.move.<id> on every move._ Is there a global _drag_ object to which
+                // you can assign handlers keyed by an element's ID?
+                /*
+                 * \ Element.drag [ method ] * Adds event handlers for an element's drag
+                 * gesture * - onmove (function) handler for moving - onstart (function)
+                 * handler for drag start - onend (function) handler for drag end - mcontext
+                 * (object) #optional context for moving handler - scontext (object)
+                 * #optional context for drag start handler - econtext (object) #optional
+                 * context for drag end handler Additionaly following `drag` events are
+                 * triggered: `drag.start.<id>` on start, `drag.end.<id>` on end and
+                 * `drag.move.<id>` on every move. When element is dragged over another
+                 * element `drag.over.<id>` fires as well.
+                 * 
+                 * Start event and start handler are called in specified context or in
+                 * context of the element with following parameters: o x (number) x position
+                 * of the mouse o y (number) y position of the mouse o event (object) DOM
+                 * event object Move event and move handler are called in specified context
+                 * or in context of the element with following parameters: o dx (number)
+                 * shift by x from the start point o dy (number) shift by y from the start
+                 * point o x (number) x position of the mouse o y (number) y position of the
+                 * mouse o event (object) DOM event object End event and end handler are
+                 * called in specified context or in context of the element with following
+                 * parameters: o event (object) DOM event object = (object) @Element \
+                 */
+                elproto.drag = function(onmove, onstart, onend, move_scope, start_scope, end_scope) {
+                    if (!arguments.length) {
+                        var origTransform;
+                        return this.drag(function(dx, dy) {
+                            this.attr({
+                                transform: origTransform + (origTransform ? "T" : "t") + [dx, dy]
+                            });
+                        }, function() {
+                            origTransform = this.transform().local;
+                        });
+                    }
+
+                    function start(e, x, y) {
+                        (e.originalEvent || e).preventDefault();
+                        this._drag.x = x;
+                        this._drag.y = y;
+                        this._drag.id = e.identifier;
+                        !drag.length && Snap.mousemove(dragMove).mouseup(dragUp);
+                        drag.push({
+                            el: this,
+                            move_scope: move_scope,
+                            start_scope: start_scope,
+                            end_scope: end_scope
+                        });
+                        onstart && eve.on("snap.drag.start." + this.id, onstart);
+                        onmove && eve.on("snap.drag.move." + this.id, onmove);
+                        onend && eve.on("snap.drag.end." + this.id, onend);
+                        eve("snap.drag.start." + this.id, start_scope || move_scope || this, x, y, e);
+                    }
+                    this._drag = {};
+                    draggable.push({
+                        el: this,
+                        start: start
+                    });
+                    this.mousedown(start);
+                    return this;
+                };
+                /*
+                 * Element.onDragOver [ method ] * Shortcut to assign event handler for
+                 * `drag.over.<id>` event, where `id` is the element's `id` (see
+                 * @Element.id) - f (function) handler for event, first argument would be
+                 * the element you are dragging over \
+                 */
+                // elproto.onDragOver = function (f) {
+                // f ? eve.on("snap.drag.over." + this.id, f) : eve.unbind("snap.drag.over."
+                // + this.id);
+                // };
+                /*
+                 * \ Element.undrag [ method ] * Removes all drag event handlers from the
+                 * given element \
+                 */
+                elproto.undrag = function() {
+                    var i = draggable.length;
+                    while (i--)
+                        if (draggable[i].el == this) {
+                            this.unmousedown(draggable[i].start);
+                            draggable.splice(i, 1);
+                            eve.unbind("snap.drag.*." + this.id);
+                        }!draggable.length && Snap.unmousemove(dragMove).unmouseup(dragUp);
+                    return this;
+                };
+            });
+            // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
+            // 
+            // Licensed under the Apache License, Version 2.0 (the "License");
+            // you may not use this file except in compliance with the License.
+            // You may obtain a copy of the License at
+            // 
+            // http://www.apache.org/licenses/LICENSE-2.0
+            // 
+            // Unless required by applicable law or agreed to in writing, software
+            // distributed under the License is distributed on an "AS IS" BASIS,
+            // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+            // See the License for the specific language governing permissions and
+            // limitations under the License.
+            Snap.plugin(function(Snap, Element, Paper, glob) {
+                var elproto = Element.prototype,
+                    pproto = Paper.prototype,
+                    rgurl = /^\s*url\((.+)\)/,
+                    Str = String,
+                    $ = Snap._.$;
+                Snap.filter = {};
+                /*
+                 * \ Paper.filter [ method ] * Creates a `<filter>` element * - filstr
+                 * (string) SVG fragment of filter provided as a string = (object) @Element
+                 * Note: It is recommended to use filters embedded into the page inside an
+                 * empty SVG element. > Usage | var f = paper.filter('<feGaussianBlur
+                 * stdDeviation="2"/>'), | c = paper.circle(10, 10, 10).attr({ | filter: f |
+                 * }); \
+                 */
+                pproto.filter = function(filstr) {
+                    var paper = this;
+                    if (paper.type != "svg") {
+                        paper = paper.paper;
+                    }
+                    var f = Snap.parse(Str(filstr)),
+                        id = Snap._.id(),
+                        width = paper.node.offsetWidth,
+                        height = paper.node.offsetHeight,
+                        filter = $("filter");
+                    $(filter, {
+                        id: id,
+                        filterUnits: "userSpaceOnUse"
+                    });
+                    filter.appendChild(f.node);
+                    paper.defs.appendChild(filter);
+                    return new Element(filter);
+                };
+
+                eve.on("snap.util.getattr.filter", function() {
+                    eve.stop();
+                    var p = $(this.node, "filter");
+                    if (p) {
+                        var match = Str(p).match(rgurl);
+                        return match && Snap.select(match[1]);
+                    }
+                });
+                eve.on("snap.util.attr.filter", function(value) {
+                    if (value instanceof Element && value.type == "filter") {
+                        eve.stop();
+                        var id = value.node.id;
+                        if (!id) {
+                            $(value.node, {
+                                id: value.id
+                            });
+                            id = value.id;
+                        }
+                        $(this.node, {
+                            filter: Snap.url(id)
+                        });
+                    }
+                    if (!value || value == "none") {
+                        eve.stop();
+                        this.node.removeAttribute("filter");
+                    }
+                });
+                /*
+                 * \ Snap.filter.blur [ method ] * Returns an SVG markup string for the blur
+                 * filter * - x (number) amount of horizontal blur, in pixels - y (number)
+                 * #optional amount of vertical blur, in pixels = (string) filter
+                 * representation > Usage | var f = paper.filter(Snap.filter.blur(5, 10)), |
+                 * c = paper.circle(10, 10, 10).attr({ | filter: f | }); \
+                 */
+                Snap.filter.blur = function(x, y) {
+                    if (x == null) {
+                        x = 2;
+                    }
+                    var def = y == null ? x : [x, y];
+                    return Snap.format('\<feGaussianBlur stdDeviation="{def}"/>', {
+                        def: def
+                    });
+                };
+                Snap.filter.blur.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.shadow [ method ] * Returns an SVG markup string for the
+                 * shadow filter * - dx (number) #optional horizontal shift of the shadow,
+                 * in pixels - dy (number) #optional vertical shift of the shadow, in pixels -
+                 * blur (number) #optional amount of blur - color (string) #optional color
+                 * of the shadow - opacity (number) #optional `0..1` opacity of the shadow
+                 * or - dx (number) #optional horizontal shift of the shadow, in pixels - dy
+                 * (number) #optional vertical shift of the shadow, in pixels - color
+                 * (string) #optional color of the shadow - opacity (number) #optional
+                 * `0..1` opacity of the shadow which makes blur default to `4`. Or - dx
+                 * (number) #optional horizontal shift of the shadow, in pixels - dy
+                 * (number) #optional vertical shift of the shadow, in pixels - opacity
+                 * (number) #optional `0..1` opacity of the shadow = (string) filter
+                 * representation > Usage | var f = paper.filter(Snap.filter.shadow(0, 2,
+                 * 3)), | c = paper.circle(10, 10, 10).attr({ | filter: f | }); \
+                 */
+                Snap.filter.shadow = function(dx, dy, blur, color, opacity) {
+                    if (typeof blur == "string") {
+                        color = blur;
+                        opacity = color;
+                        blur = 4;
+                    }
+                    if (typeof color != "string") {
+                        opacity = color;
+                        color = "#000";
+                    }
+                    color = color || "#000";
+                    if (blur == null) {
+                        blur = 4;
+                    }
+                    if (opacity == null) {
+                        opacity = 1;
+                    }
+                    if (dx == null) {
+                        dx = 0;
+                        dy = 2;
+                    }
+                    if (dy == null) {
+                        dy = dx;
+                    }
+                    color = Snap.color(color);
+                    return Snap.format('<feGaussianBlur in="SourceAlpha" stdDeviation="{blur}"/><feOffset dx="{dx}" dy="{dy}" result="offsetblur"/><feFlood flood-color="{color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="{opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge>', {
+                        color: color,
+                        dx: dx,
+                        dy: dy,
+                        blur: blur,
+                        opacity: opacity
+                    });
+                };
+                Snap.filter.shadow.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.grayscale [ method ] * Returns an SVG markup string for the
+                 * grayscale filter * - amount (number) amount of filter (`0..1`) = (string)
+                 * filter representation \
+                 */
+                Snap.filter.grayscale = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {b} {h} 0 0 0 0 0 1 0"/>', {
+                        a: 0.2126 + 0.7874 * (1 - amount),
+                        b: 0.7152 - 0.7152 * (1 - amount),
+                        c: 0.0722 - 0.0722 * (1 - amount),
+                        d: 0.2126 - 0.2126 * (1 - amount),
+                        e: 0.7152 + 0.2848 * (1 - amount),
+                        f: 0.0722 - 0.0722 * (1 - amount),
+                        g: 0.2126 - 0.2126 * (1 - amount),
+                        h: 0.0722 + 0.9278 * (1 - amount)
+                    });
+                };
+                Snap.filter.grayscale.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.sepia [ method ] * Returns an SVG markup string for the
+                 * sepia filter * - amount (number) amount of filter (`0..1`) = (string)
+                 * filter representation \
+                 */
+                Snap.filter.sepia = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feColorMatrix type="matrix" values="{a} {b} {c} 0 0 {d} {e} {f} 0 0 {g} {h} {i} 0 0 0 0 0 1 0"/>', {
+                        a: 0.393 + 0.607 * (1 - amount),
+                        b: 0.769 - 0.769 * (1 - amount),
+                        c: 0.189 - 0.189 * (1 - amount),
+                        d: 0.349 - 0.349 * (1 - amount),
+                        e: 0.686 + 0.314 * (1 - amount),
+                        f: 0.168 - 0.168 * (1 - amount),
+                        g: 0.272 - 0.272 * (1 - amount),
+                        h: 0.534 - 0.534 * (1 - amount),
+                        i: 0.131 + 0.869 * (1 - amount)
+                    });
+                };
+                Snap.filter.sepia.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.saturate [ method ] * Returns an SVG markup string for the
+                 * saturate filter * - amount (number) amount of filter (`0..1`) = (string)
+                 * filter representation \
+                 */
+                Snap.filter.saturate = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feColorMatrix type="saturate" values="{amount}"/>', {
+                        amount: 1 - amount
+                    });
+                };
+                Snap.filter.saturate.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.hueRotate [ method ] * Returns an SVG markup string for the
+                 * hue-rotate filter * - angle (number) angle of rotation = (string) filter
+                 * representation \
+                 */
+                Snap.filter.hueRotate = function(angle) {
+                    angle = angle || 0;
+                    return Snap.format('<feColorMatrix type="hueRotate" values="{angle}"/>', {
+                        angle: angle
+                    });
+                };
+                Snap.filter.hueRotate.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.invert [ method ] * Returns an SVG markup string for the
+                 * invert filter * - amount (number) amount of filter (`0..1`) = (string)
+                 * filter representation \
+                 */
+                Snap.filter.invert = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feComponentTransfer><feFuncR type="table" tableValues="{amount} {amount2}"/><feFuncG type="table" tableValues="{amount} {amount2}"/><feFuncB type="table" tableValues="{amount} {amount2}"/></feComponentTransfer>', {
+                        amount: amount,
+                        amount2: 1 - amount
+                    });
+                };
+                Snap.filter.invert.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.brightness [ method ] * Returns an SVG markup string for
+                 * the brightness filter * - amount (number) amount of filter (`0..1`) =
+                 * (string) filter representation \
+                 */
+                Snap.filter.brightness = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}"/><feFuncG type="linear" slope="{amount}"/><feFuncB type="linear" slope="{amount}"/></feComponentTransfer>', {
+                        amount: amount
+                    });
+                };
+                Snap.filter.brightness.toString = function() {
+                    return this();
+                };
+                /*
+                 * \ Snap.filter.contrast [ method ] * Returns an SVG markup string for the
+                 * contrast filter * - amount (number) amount of filter (`0..1`) = (string)
+                 * filter representation \
+                 */
+                Snap.filter.contrast = function(amount) {
+                    if (amount == null) {
+                        amount = 1;
+                    }
+                    return Snap.format('<feComponentTransfer><feFuncR type="linear" slope="{amount}" intercept="{amount2}"/><feFuncG type="linear" slope="{amount}" intercept="{amount2}"/><feFuncB type="linear" slope="{amount}" intercept="{amount2}"/></feComponentTransfer>', {
+                        amount: amount,
+                        amount2: .5 - amount / 2
+                    });
+                };
+                Snap.filter.contrast.toString = function() {
+                    return this();
+                };
+            });
+
+            return Snap;
+        }));
+    }, {
+        "eve": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\eve\\eve.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\vendor\\snapsvg.js": [function(require, module, exports) {
+        'use strict';
+
+        var snapsvg = module.exports = require('snapsvg');
+
+        snapsvg.plugin(function(Snap, Element) {
+
+            /*
+             * \ Element.children [ method ] * Returns array of all the children of the
+             * element. = (array) array of Elements \
+             */
+            Element.prototype.children = function() {
+                var out = [],
+                    ch = this.node.childNodes;
+                for (var i = 0, ii = ch.length; i < ii; i++) {
+                    out[i] = new Snap(ch[i]);
+                }
+                return out;
+            };
+        });
+
+
+        /**
+         * @class ClassPlugin
+         * 
+         * Extends snapsvg with methods to add and remove classes
+         */
+        snapsvg.plugin(function(Snap, Element, Paper, global) {
+
+            function split(str) {
+                return str.split(/\s+/);
+            }
+
+            function join(array) {
+                return array.join(' ');
+            }
+
+            function getClasses(e) {
+                return split(e.attr('class') || '');
+            }
+
+            function setClasses(e, classes) {
+                e.attr('class', join(classes));
+            }
+
+            /**
+             * @method snapsvg.Element#addClass
+             * 
+             * @example
+             * 
+             * e.attr('class', 'selector');
+             * 
+             * e.addClass('foo bar'); // adds classes foo and bar e.attr('class'); // ->
+             * 'selector foo bar'
+             * 
+             * e.addClass('fooBar'); e.attr('class'); // -> 'selector foo bar fooBar'
+             * 
+             * @param {String}
+             *            cls classes to be added to the element
+             * 
+             * @return {snapsvg.Element} the element (this)
+             */
+            Element.prototype.addClass = function(cls) {
+                var current = getClasses(this),
+                    add = split(cls),
+                    i, e;
+
+                for (i = 0, e; !!(e = add[i]); i++) {
+                    if (current.indexOf(e) === -1) {
+                        current.push(e);
+                    }
+                }
+
+                setClasses(this, current);
+
+                return this;
+            };
+
+            /**
+             * @method snapsvg.Element#hasClass
+             * 
+             * @param {String}
+             *            cls the class to query for
+             * @return {Boolean} returns true if the element has the given class
+             */
+            Element.prototype.hasClass = function(cls) {
+                if (!cls) {
+                    throw new Error('[snapsvg] syntax: hasClass(clsStr)');
+                }
+
+                return getClasses(this).indexOf(cls) !== -1;
+            };
+
+            /**
+             * @method snapsvg.Element#removeClass
+             * 
+             * @example
+             * 
+             * e.attr('class', 'foo bar');
+             * 
+             * e.removeClass('foo'); e.attr('class'); // -> 'bar'
+             * 
+             * e.removeClass('foo bar'); // removes classes foo and bar e.attr('class'); // -> ''
+             * 
+             * @param {String}
+             *            cls classes to be removed from element
+             * 
+             * @return {snapsvg.Element} the element (this)
+             */
+            Element.prototype.removeClass = function(cls) {
+                var current = getClasses(this),
+                    remove = split(cls),
+                    i, e, idx;
+
+                for (i = 0, e; !!(e = remove[i]); i++) {
+                    idx = current.indexOf(e);
+
+                    if (idx !== -1) {
+                        // remove element from array
+                        current.splice(idx, 1);
+                    }
+                }
+
+                setClasses(this, current);
+
+                return this;
+            };
+
+        });
+
+        /**
+         * @class TranslatePlugin
+         * 
+         * Extends snapsvg with methods to translate elements
+         */
+        snapsvg.plugin(function(Snap, Element, Paper, global) {
+
+            /*
+             * @method snapsvg.Element#translate
+             * 
+             * @example
+             * 
+             * e.translate(10, 20);
+             *  // sets transform matrix to translate(10, 20)
+             * 
+             * @param {Number} x translation @param {Number} y translation
+             * 
+             * @return {snapsvg.Element} the element (this)
+             */
+            Element.prototype.translate = function(x, y) {
+                var matrix = new Snap.Matrix();
+                matrix.translate(x, y);
+                return this.transform(matrix);
+            };
+        });
+
+
+        /**
+         * @class CreatePlugin
+         * 
+         * Create an svg element without attaching it to the dom
+         */
+        snapsvg.plugin(function(Snap) {
+
+            Snap.create = function(name, attrs) {
+                return Snap._.wrap(Snap._.$(name, attrs));
+            };
+        });
+
+
+        /**
+         * @class CreatSnapAtPlugin
+         * 
+         * Extends snap.svg with a method to create a SVG element at a specific position
+         * in the DOM.
+         */
+        snapsvg.plugin(function(Snap, Element, Paper, global) {
+
+            /*
+             * @method snapsvg.createSnapAt
+             * 
+             * @example
+             * 
+             * snapsvg.createSnapAt(parentNode, 200, 200);
+             * 
+             * @param {Number} width of svg @param {Number} height of svg @param
+             * {Object} parentNode svg Element will be child of this
+             * 
+             * @return {snapsvg.Element} the newly created wrapped SVG element instance
+             */
+            Snap.createSnapAt = function(width, height, parentNode) {
+
+                var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+                svg.setAttribute('width', width);
+                svg.setAttribute('height', height);
+                if (!parentNode) {
+                    parentNode = document.body;
+                }
+                parentNode.appendChild(svg);
+
+                return new Snap(svg);
+            };
+        });
+    }, {
+        "snapsvg": "\\bpmn-js-examples-master\\modeler\\node_modules\\diagram-js\\node_modules\\snapsvg\\dist\\snap.svg.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\jquery\\dist\\jquery.js": [function(require, module, exports) {
+        /*
+         * ! jQuery JavaScript Library v2.1.4 http://jquery.com/
+         * 
+         * Includes Sizzle.js http://sizzlejs.com/
+         * 
+         * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors Released
+         * under the MIT license http://jquery.org/license
+         * 
+         * Date: 2015-04-28T16:01Z
+         */
+
+        (function(global, factory) {
+
+            if (typeof module === "object" && typeof module.exports === "object") {
+                // For CommonJS and CommonJS-like environments where a proper `window`
+                // is present, execute the factory and get jQuery.
+                // For environments that do not have a `window` with a `document`
+                // (such as Node.js), expose a factory as module.exports.
+                // This accentuates the need for the creation of a real `window`.
+                // e.g. var jQuery = require("jquery")(window);
+                // See ticket #14549 for more info.
+                module.exports = global.document ?
+                    factory(global, true) :
+                    function(w) {
+                        if (!w.document) {
+                            throw new Error("jQuery requires a window with a document");
+                        }
+                        return factory(w);
+                    };
+            } else {
+                factory(global);
+            }
+
+            // Pass this if window is not defined yet
+        }(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
+
+            // Support: Firefox 18+
+            // Can't be in strict mode, several libs including ASP.NET trace
+            // the stack via arguments.caller.callee and Firefox dies if
+            // you try to trace through "use strict" call chains. (#13335)
+            //
+
+            var arr = [];
+
+            var slice = arr.slice;
+
+            var concat = arr.concat;
+
+            var push = arr.push;
+
+            var indexOf = arr.indexOf;
+
+            var class2type = {};
+
+            var toString = class2type.toString;
+
+            var hasOwn = class2type.hasOwnProperty;
+
+            var support = {};
+
+
+
+            var
+            // Use the correct document accordingly with window argument (sandbox)
+                document = window.document,
+
+                version = "2.1.4",
+
+                // Define a local copy of jQuery
+                jQuery = function(selector, context) {
+                    // The jQuery object is actually just the init constructor 'enhanced'
+                    // Need init if jQuery is called (just allow error to be thrown if not
+                    // included)
+                    return new jQuery.fn.init(selector, context);
+                },
+
+                // Support: Android<4.1
+                // Make sure we trim BOM and NBSP
+                rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+                // Matches dashed string for camelizing
+                rmsPrefix = /^-ms-/,
+                rdashAlpha = /-([\da-z])/gi,
+
+                // Used by jQuery.camelCase as callback to replace()
+                fcamelCase = function(all, letter) {
+                    return letter.toUpperCase();
+                };
+
+            jQuery.fn = jQuery.prototype = {
+                // The current version of jQuery being used
+                jquery: version,
+
+                constructor: jQuery,
+
+                // Start with an empty selector
+                selector: "",
+
+                // The default length of a jQuery object is 0
+                length: 0,
+
+                toArray: function() {
+                    return slice.call(this);
+                },
+
+                // Get the Nth element in the matched element set OR
+                // Get the whole matched element set as a clean array
+                get: function(num) {
+                    return num != null ?
+
+                        // Return just the one element from the set
+                        (num < 0 ? this[num + this.length] : this[num]) :
+
+                        // Return all the elements in a clean array
+                        slice.call(this);
+                },
+
+                // Take an array of elements and push it onto the stack
+                // (returning the new matched element set)
+                pushStack: function(elems) {
+
+                    // Build a new jQuery matched element set
+                    var ret = jQuery.merge(this.constructor(), elems);
+
+                    // Add the old object onto the stack (as a reference)
+                    ret.prevObject = this;
+                    ret.context = this.context;
+
+                    // Return the newly-formed element set
+                    return ret;
+                },
+
+                // Execute a callback for every element in the matched set.
+                // (You can seed the arguments with an array of args, but this is
+                // only used internally.)
+                each: function(callback, args) {
+                    return jQuery.each(this, callback, args);
+                },
+
+                map: function(callback) {
+                    return this.pushStack(jQuery.map(this, function(elem, i) {
+                        return callback.call(elem, i, elem);
+                    }));
+                },
+
+                slice: function() {
+                    return this.pushStack(slice.apply(this, arguments));
+                },
+
+                first: function() {
+                    return this.eq(0);
+                },
+
+                last: function() {
+                    return this.eq(-1);
+                },
+
+                eq: function(i) {
+                    var len = this.length,
+                        j = +i + (i < 0 ? len : 0);
+                    return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
+                },
+
+                end: function() {
+                    return this.prevObject || this.constructor(null);
+                },
+
+                // For internal use only.
+                // Behaves like an Array's method, not like a jQuery method.
+                push: push,
+                sort: arr.sort,
+                splice: arr.splice
+            };
+
+            jQuery.extend = jQuery.fn.extend = function() {
+                var options, name, src, copy, copyIsArray, clone,
+                    target = arguments[0] || {},
+                    i = 1,
+                    length = arguments.length,
+                    deep = false;
+
+                // Handle a deep copy situation
+                if (typeof target === "boolean") {
+                    deep = target;
+
+                    // Skip the boolean and the target
+                    target = arguments[i] || {};
+                    i++;
+                }
+
+                // Handle case when target is a string or something (possible in deep copy)
+                if (typeof target !== "object" && !jQuery.isFunction(target)) {
+                    target = {};
+                }
+
+                // Extend jQuery itself if only one argument is passed
+                if (i === length) {
+                    target = this;
+                    i--;
+                }
+
+                for (; i < length; i++) {
+                    // Only deal with non-null/undefined values
+                    if ((options = arguments[i]) != null) {
+                        // Extend the base object
+                        for (name in options) {
+                            src = target[name];
+                            copy = options[name];
+
+                            // Prevent never-ending loop
+                            if (target === copy) {
+                                continue;
+                            }
+
+                            // Recurse if we're merging plain objects or arrays
+                            if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
+                                if (copyIsArray) {
+                                    copyIsArray = false;
+                                    clone = src && jQuery.isArray(src) ? src : [];
+
+                                } else {
+                                    clone = src && jQuery.isPlainObject(src) ? src : {};
+                                }
+
+                                // Never move original objects, clone them
+                                target[name] = jQuery.extend(deep, clone, copy);
+
+                                // Don't bring in undefined values
+                            } else if (copy !== undefined) {
+                                target[name] = copy;
+                            }
+                        }
+                    }
+                }
+
+                // Return the modified object
+                return target;
+            };
+
+            jQuery.extend({
+                // Unique for each copy of jQuery on the page
+                expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
+
+                // Assume jQuery is ready without the ready module
+                isReady: true,
+
+                error: function(msg) {
+                    throw new Error(msg);
+                },
+
+                noop: function() {},
+
+                isFunction: function(obj) {
+                    return jQuery.type(obj) === "function";
+                },
+
+                isArray: Array.isArray,
+
+                isWindow: function(obj) {
+                    return obj != null && obj === obj.window;
+                },
+
+                isNumeric: function(obj) {
+                    // parseFloat NaNs numeric-cast false positives (null|true|false|"")
+                    // ...but misinterprets leading-number strings, particularly hex
+                    // literals ("0x...")
+                    // subtraction forces infinities to NaN
+                    // adding 1 corrects loss of precision from parseFloat (#15100)
+                    return !jQuery.isArray(obj) && (obj - parseFloat(obj) + 1) >= 0;
+                },
+
+                isPlainObject: function(obj) {
+                    // Not plain objects:
+                    // - Any object or value whose internal [[Class]] property is not
+                    // "[object Object]"
+                    // - DOM nodes
+                    // - window
+                    if (jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
+                        return false;
+                    }
+
+                    if (obj.constructor &&
+                        !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
+                        return false;
+                    }
+
+                    // If the function hasn't returned already, we're confident that
+                    // |obj| is a plain object, created by {} or constructed with new Object
+                    return true;
+                },
+
+                isEmptyObject: function(obj) {
+                    var name;
+                    for (name in obj) {
+                        return false;
+                    }
+                    return true;
+                },
+
+                type: function(obj) {
+                    if (obj == null) {
+                        return obj + "";
+                    }
+                    // Support: Android<4.0, iOS<6 (functionish RegExp)
+                    return typeof obj === "object" || typeof obj === "function" ?
+                        class2type[toString.call(obj)] || "object" :
+                        typeof obj;
+                },
+
+                // Evaluates a script in a global context
+                globalEval: function(code) {
+                    var script,
+                        indirect = eval;
+
+                    code = jQuery.trim(code);
+
+                    if (code) {
+                        // If the code includes a valid, prologue position
+                        // strict mode pragma, execute code by injecting a
+                        // script tag into the document.
+                        if (code.indexOf("use strict") === 1) {
+                            script = document.createElement("script");
+                            script.text = code;
+                            document.head.appendChild(script).parentNode.removeChild(script);
+                        } else {
+                            // Otherwise, avoid the DOM node creation, insertion
+                            // and removal by using an indirect global eval
+                            indirect(code);
+                        }
+                    }
+                },
+
+                // Convert dashed to camelCase; used by the css and data modules
+                // Support: IE9-11+
+                // Microsoft forgot to hump their vendor prefix (#9572)
+                camelCase: function(string) {
+                    return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
+                },
+
+                nodeName: function(elem, name) {
+                    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+                },
+
+                // args is for internal usage only
+                each: function(obj, callback, args) {
+                    var value,
+                        i = 0,
+                        length = obj.length,
+                        isArray = isArraylike(obj);
+
+                    if (args) {
+                        if (isArray) {
+                            for (; i < length; i++) {
+                                value = callback.apply(obj[i], args);
+
+                                if (value === false) {
+                                    break;
+                                }
+                            }
+                        } else {
+                            for (i in obj) {
+                                value = callback.apply(obj[i], args);
+
+                                if (value === false) {
+                                    break;
+                                }
+                            }
+                        }
+
+                        // A special, fast, case for the most common use of each
+                    } else {
+                        if (isArray) {
+                            for (; i < length; i++) {
+                                value = callback.call(obj[i], i, obj[i]);
+
+                                if (value === false) {
+                                    break;
+                                }
+                            }
+                        } else {
+                            for (i in obj) {
+                                value = callback.call(obj[i], i, obj[i]);
+
+                                if (value === false) {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    return obj;
+                },
+
+                // Support: Android<4.1
+                trim: function(text) {
+                    return text == null ?
+                        "" :
+                        (text + "").replace(rtrim, "");
+                },
+
+                // results is for internal usage only
+                makeArray: function(arr, results) {
+                    var ret = results || [];
+
+                    if (arr != null) {
+                        if (isArraylike(Object(arr))) {
+                            jQuery.merge(ret,
+                                typeof arr === "string" ? [arr] : arr
+                            );
+                        } else {
+                            push.call(ret, arr);
+                        }
+                    }
+
+                    return ret;
+                },
+
+                inArray: function(elem, arr, i) {
+                    return arr == null ? -1 : indexOf.call(arr, elem, i);
+                },
+
+                merge: function(first, second) {
+                    var len = +second.length,
+                        j = 0,
+                        i = first.length;
+
+                    for (; j < len; j++) {
+                        first[i++] = second[j];
+                    }
+
+                    first.length = i;
+
+                    return first;
+                },
+
+                grep: function(elems, callback, invert) {
+                    var callbackInverse,
+                        matches = [],
+                        i = 0,
+                        length = elems.length,
+                        callbackExpect = !invert;
+
+                    // Go through the array, only saving the items
+                    // that pass the validator function
+                    for (; i < length; i++) {
+                        callbackInverse = !callback(elems[i], i);
+                        if (callbackInverse !== callbackExpect) {
+                            matches.push(elems[i]);
+                        }
+                    }
+
+                    return matches;
+                },
+
+                // arg is for internal usage only
+                map: function(elems, callback, arg) {
+                    var value,
+                        i = 0,
+                        length = elems.length,
+                        isArray = isArraylike(elems),
+                        ret = [];
+
+                    // Go through the array, translating each of the items to their new
+                    // values
+                    if (isArray) {
+                        for (; i < length; i++) {
+                            value = callback(elems[i], i, arg);
+
+                            if (value != null) {
+                                ret.push(value);
+                            }
+                        }
+
+                        // Go through every key on the object,
+                    } else {
+                        for (i in elems) {
+                            value = callback(elems[i], i, arg);
+
+                            if (value != null) {
+                                ret.push(value);
+                            }
+                        }
+                    }
+
+                    // Flatten any nested arrays
+                    return concat.apply([], ret);
+                },
+
+                // A global GUID counter for objects
+                guid: 1,
+
+                // Bind a function to a context, optionally partially applying any
+                // arguments.
+                proxy: function(fn, context) {
+                    var tmp, args, proxy;
+
+                    if (typeof context === "string") {
+                        tmp = fn[context];
+                        context = fn;
+                        fn = tmp;
+                    }
+
+                    // Quick check to determine if target is callable, in the spec
+                    // this throws a TypeError, but we will just return undefined.
+                    if (!jQuery.isFunction(fn)) {
+                        return undefined;
+                    }
+
+                    // Simulated bind
+                    args = slice.call(arguments, 2);
+                    proxy = function() {
+                        return fn.apply(context || this, args.concat(slice.call(arguments)));
+                    };
+
+                    // Set the guid of unique handler to the same of original handler, so it
+                    // can be removed
+                    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+                    return proxy;
+                },
+
+                now: Date.now,
+
+                // jQuery.support is not used in Core but other projects attach their
+                // properties to it so it needs to exist.
+                support: support
+            });
+
+            // Populate the class2type map
+            jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+                class2type["[object " + name + "]"] = name.toLowerCase();
+            });
+
+            function isArraylike(obj) {
+
+                // Support: iOS 8.2 (not reproducible in simulator)
+                // `in` check used to prevent JIT error (gh-2145)
+                // hasOwn isn't used here due to false negatives
+                // regarding Nodelist length in IE
+                var length = "length" in obj && obj.length,
+                    type = jQuery.type(obj);
+
+                if (type === "function" || jQuery.isWindow(obj)) {
+                    return false;
+                }
+
+                if (obj.nodeType === 1 && length) {
+                    return true;
+                }
+
+                return type === "array" || length === 0 ||
+                    typeof length === "number" && length > 0 && (length - 1) in obj;
+            }
+            var Sizzle =
+                /*
+                 * ! Sizzle CSS Selector Engine v2.2.0-pre http://sizzlejs.com/
+                 * 
+                 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors Released
+                 * under the MIT license http://jquery.org/license
+                 * 
+                 * Date: 2014-12-16
+                 */
+                (function(window) {
+
+                    var i,
+                        support,
+                        Expr,
+                        getText,
+                        isXML,
+                        tokenize,
+                        compile,
+                        select,
+                        outermostContext,
+                        sortInput,
+                        hasDuplicate,
+
+                        // Local document vars
+                        setDocument,
+                        document,
+                        docElem,
+                        documentIsHTML,
+                        rbuggyQSA,
+                        rbuggyMatches,
+                        matches,
+                        contains,
+
+                        // Instance-specific data
+                        expando = "sizzle" + 1 * new Date(),
+                        preferredDoc = window.document,
+                        dirruns = 0,
+                        done = 0,
+                        classCache = createCache(),
+                        tokenCache = createCache(),
+                        compilerCache = createCache(),
+                        sortOrder = function(a, b) {
+                            if (a === b) {
+                                hasDuplicate = true;
+                            }
+                            return 0;
+                        },
+
+                        // General-purpose constants
+                        MAX_NEGATIVE = 1 << 31,
+
+                        // Instance methods
+                        hasOwn = ({}).hasOwnProperty,
+                        arr = [],
+                        pop = arr.pop,
+                        push_native = arr.push,
+                        push = arr.push,
+                        slice = arr.slice,
+                        // Use a stripped-down indexOf as it's faster than native
+                        // http://jsperf.com/thor-indexof-vs-for/5
+                        indexOf = function(list, elem) {
+                            var i = 0,
+                                len = list.length;
+                            for (; i < len; i++) {
+                                if (list[i] === elem) {
+                                    return i;
+                                }
+                            }
+                            return -1;
+                        },
+
+                        booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+                        // Regular expressions
+
+                        // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+                        whitespace = "[\\x20\\t\\r\\n\\f]",
+                        // http://www.w3.org/TR/css3-syntax/#characters
+                        characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+                        // Loosely modeled on CSS identifier characters
+                        // An unquoted value should be a CSS identifier
+                        // http://www.w3.org/TR/css3-selectors/#attribute-selectors
+                        // Proper syntax:
+                        // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+                        identifier = characterEncoding.replace("w", "w#"),
+
+                        // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+                        attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
+                        // Operator (capture 2)
+                        "*([*^$|!~]?=)" + whitespace +
+                        // "Attribute values must be CSS identifiers [capture 5] or strings
+                        // [capture 3 or capture 4]"
+                        "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+                        "*\\]",
+
+                        pseudos = ":(" + characterEncoding + ")(?:\\((" +
+                        // To reduce the number of selectors needing tokenize in the preFilter,
+                        // prefer arguments:
+                        // 1. quoted (capture 3; capture 4 or capture 5)
+                        "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+                        // 2. simple (capture 6)
+                        "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+                        // 3. anything else (capture 2)
+                        ".*" +
+                        ")\\)|)",
+
+                        // Leading and non-escaped trailing whitespace, capturing some
+                        // non-whitespace characters preceding the latter
+                        rwhitespace = new RegExp(whitespace + "+", "g"),
+                        rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
+
+                        rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
+                        rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
+
+                        rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
+
+                        rpseudo = new RegExp(pseudos),
+                        ridentifier = new RegExp("^" + identifier + "$"),
+
+                        matchExpr = {
+                            "ID": new RegExp("^#(" + characterEncoding + ")"),
+                            "CLASS": new RegExp("^\\.(" + characterEncoding + ")"),
+                            "TAG": new RegExp("^(" + characterEncoding.replace("w", "w*") + ")"),
+                            "ATTR": new RegExp("^" + attributes),
+                            "PSEUDO": new RegExp("^" + pseudos),
+                            "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                                "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                                "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
+                            "bool": new RegExp("^(?:" + booleans + ")$", "i"),
+                            // For use in libraries implementing .is()
+                            // We use this for POS matching in `select`
+                            "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                                whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
+                        },
+
+                        rinputs = /^(?:input|select|textarea|button)$/i,
+                        rheader = /^h\d$/i,
+
+                        rnative = /^[^{]+\{\s*\[native \w/,
+
+                        // Easily-parseable/retrievable ID or TAG or CLASS selectors
+                        rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+                        rsibling = /[+~]/,
+                        rescape = /'|\\/g,
+
+                        // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+                        runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
+                        funescape = function(_, escaped, escapedWhitespace) {
+                            var high = "0x" + escaped - 0x10000;
+                            // NaN means non-codepoint
+                            // Support: Firefox<24
+                            // Workaround erroneous numeric interpretation of +"0x"
+                            return high !== high || escapedWhitespace ?
+                                escaped :
+                                high < 0 ?
+                                // BMP codepoint
+                                String.fromCharCode(high + 0x10000) :
+                                // Supplemental Plane codepoint (surrogate pair)
+                                String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
+                        },
+
+                        // Used for iframes
+                        // See setDocument()
+                        // Removing the function wrapper causes a "Permission Denied"
+                        // error in IE
+                        unloadHandler = function() {
+                            setDocument();
+                        };
+
+                    // Optimize for push.apply( _, NodeList )
+                    try {
+                        push.apply(
+                            (arr = slice.call(preferredDoc.childNodes)),
+                            preferredDoc.childNodes
+                        );
+                        // Support: Android<4.0
+                        // Detect silently failing push.apply
+                        arr[preferredDoc.childNodes.length].nodeType;
+                    } catch (e) {
+                        push = {
+                            apply: arr.length ?
+
+                                // Leverage slice if possible
+                                function(target, els) {
+                                    push_native.apply(target, slice.call(els));
+                                } :
+
+                                // Support: IE<9
+                                // Otherwise append directly
+                                function(target, els) {
+                                    var j = target.length,
+                                        i = 0;
+                                    // Can't trust NodeList.length
+                                    while ((target[j++] = els[i++])) {}
+                                    target.length = j - 1;
+                                }
+                        };
+                    }
+
+                    function Sizzle(selector, context, results, seed) {
+                        var match, elem, m, nodeType,
+                            // QSA vars
+                            i, groups, old, nid, newContext, newSelector;
+
+                        if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
+                            setDocument(context);
+                        }
+
+                        context = context || document;
+                        results = results || [];
+                        nodeType = context.nodeType;
+
+                        if (typeof selector !== "string" || !selector ||
+                            nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
+
+                            return results;
+                        }
+
+                        if (!seed && documentIsHTML) {
+
+                            // Try to shortcut find operations when possible (e.g., not under
+                            // DocumentFragment)
+                            if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
+                                // Speed-up: Sizzle("#ID")
+                                if ((m = match[1])) {
+                                    if (nodeType === 9) {
+                                        elem = context.getElementById(m);
+                                        // Check parentNode to catch when Blackberry 4.6 returns
+                                        // nodes that are no longer in the document (jQuery #6963)
+                                        if (elem && elem.parentNode) {
+                                            // Handle the case where IE, Opera, and Webkit return
+                                            // items
+                                            // by name instead of ID
+                                            if (elem.id === m) {
+                                                results.push(elem);
+                                                return results;
+                                            }
+                                        } else {
+                                            return results;
+                                        }
+                                    } else {
+                                        // Context is not a document
+                                        if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) &&
+                                            contains(context, elem) && elem.id === m) {
+                                            results.push(elem);
+                                            return results;
+                                        }
+                                    }
+
+                                    // Speed-up: Sizzle("TAG")
+                                } else if (match[2]) {
+                                    push.apply(results, context.getElementsByTagName(selector));
+                                    return results;
+
+                                    // Speed-up: Sizzle(".CLASS")
+                                } else if ((m = match[3]) && support.getElementsByClassName) {
+                                    push.apply(results, context.getElementsByClassName(m));
+                                    return results;
+                                }
+                            }
+
+                            // QSA path
+                            if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
+                                nid = old = expando;
+                                newContext = context;
+                                newSelector = nodeType !== 1 && selector;
+
+                                // qSA works strangely on Element-rooted queries
+                                // We can work around this by specifying an extra ID on the root
+                                // and working up from there (Thanks to Andrew Dupont for the
+                                // technique)
+                                // IE 8 doesn't work on object elements
+                                if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
+                                    groups = tokenize(selector);
+
+                                    if ((old = context.getAttribute("id"))) {
+                                        nid = old.replace(rescape, "\\$&");
+                                    } else {
+                                        context.setAttribute("id", nid);
+                                    }
+                                    nid = "[id='" + nid + "'] ";
+
+                                    i = groups.length;
+                                    while (i--) {
+                                        groups[i] = nid + toSelector(groups[i]);
+                                    }
+                                    newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
+                                    newSelector = groups.join(",");
+                                }
+
+                                if (newSelector) {
+                                    try {
+                                        push.apply(results,
+                                            newContext.querySelectorAll(newSelector)
+                                        );
+                                        return results;
+                                    } catch (qsaError) {} finally {
+                                        if (!old) {
+                                            context.removeAttribute("id");
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        // All others
+                        return select(selector.replace(rtrim, "$1"), context, results, seed);
+                    }
+
+                    /**
+                     * Create key-value caches of limited size
+                     * 
+                     * @returns {Function(string, Object)} Returns the Object data after storing it
+                     *          on itself with property name the (space-suffixed) string and (if the
+                     *          cache is larger than Expr.cacheLength) deleting the oldest entry
+                     */
+                    function createCache() {
+                        var keys = [];
+
+                        function cache(key, value) {
+                            // Use (key + " ") to avoid collision with native prototype properties
+                            // (see Issue #157)
+                            if (keys.push(key + " ") > Expr.cacheLength) {
+                                // Only keep the most recent entries
+                                delete cache[keys.shift()];
+                            }
+                            return (cache[key + " "] = value);
+                        }
+                        return cache;
+                    }
+
+                    /**
+                     * Mark a function for special use by Sizzle
+                     * 
+                     * @param {Function}
+                     *            fn The function to mark
+                     */
+                    function markFunction(fn) {
+                        fn[expando] = true;
+                        return fn;
+                    }
+
+                    /**
+                     * Support testing using an element
+                     * 
+                     * @param {Function}
+                     *            fn Passed the created div and expects a boolean result
+                     */
+                    function assert(fn) {
+                        var div = document.createElement("div");
+
+                        try {
+                            return !!fn(div);
+                        } catch (e) {
+                            return false;
+                        } finally {
+                            // Remove from its parent by default
+                            if (div.parentNode) {
+                                div.parentNode.removeChild(div);
+                            }
+                            // release memory in IE
+                            div = null;
+                        }
+                    }
+
+                    /**
+                     * Adds the same handler for all of the specified attrs
+                     * 
+                     * @param {String}
+                     *            attrs Pipe-separated list of attributes
+                     * @param {Function}
+                     *            handler The method that will be applied
+                     */
+                    function addHandle(attrs, handler) {
+                        var arr = attrs.split("|"),
+                            i = attrs.length;
+
+                        while (i--) {
+                            Expr.attrHandle[arr[i]] = handler;
+                        }
+                    }
+
+                    /**
+                     * Checks document order of two siblings
+                     * 
+                     * @param {Element}
+                     *            a
+                     * @param {Element}
+                     *            b
+                     * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a
+                     *          follows b
+                     */
+                    function siblingCheck(a, b) {
+                        var cur = b && a,
+                            diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                            (~b.sourceIndex || MAX_NEGATIVE) -
+                            (~a.sourceIndex || MAX_NEGATIVE);
+
+                        // Use IE sourceIndex if available on both nodes
+                        if (diff) {
+                            return diff;
+                        }
+
+                        // Check if b follows a
+                        if (cur) {
+                            while ((cur = cur.nextSibling)) {
+                                if (cur === b) {
+                                    return -1;
+                                }
+                            }
+                        }
+
+                        return a ? 1 : -1;
+                    }
+
+                    /**
+                     * Returns a function to use in pseudos for input types
+                     * 
+                     * @param {String}
+                     *            type
+                     */
+                    function createInputPseudo(type) {
+                        return function(elem) {
+                            var name = elem.nodeName.toLowerCase();
+                            return name === "input" && elem.type === type;
+                        };
+                    }
+
+                    /**
+                     * Returns a function to use in pseudos for buttons
+                     * 
+                     * @param {String}
+                     *            type
+                     */
+                    function createButtonPseudo(type) {
+                        return function(elem) {
+                            var name = elem.nodeName.toLowerCase();
+                            return (name === "input" || name === "button") && elem.type === type;
+                        };
+                    }
+
+                    /**
+                     * Returns a function to use in pseudos for positionals
+                     * 
+                     * @param {Function}
+                     *            fn
+                     */
+                    function createPositionalPseudo(fn) {
+                        return markFunction(function(argument) {
+                            argument = +argument;
+                            return markFunction(function(seed, matches) {
+                                var j,
+                                    matchIndexes = fn([], seed.length, argument),
+                                    i = matchIndexes.length;
+
+                                // Match elements found at the specified indexes
+                                while (i--) {
+                                    if (seed[(j = matchIndexes[i])]) {
+                                        seed[j] = !(matches[j] = seed[j]);
+                                    }
+                                }
+                            });
+                        });
+                    }
+
+                    /**
+                     * Checks a node for validity as a Sizzle context
+                     * 
+                     * @param {Element|Object=}
+                     *            context
+                     * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a
+                     *          falsy value
+                     */
+                    function testContext(context) {
+                        return context && typeof context.getElementsByTagName !== "undefined" && context;
+                    }
+
+                    // Expose support vars for convenience
+                    support = Sizzle.support = {};
+
+                    /**
+                     * Detects XML nodes
+                     * 
+                     * @param {Element|Object}
+                     *            elem An element or a document
+                     * @returns {Boolean} True iff elem is a non-HTML XML node
+                     */
+                    isXML = Sizzle.isXML = function(elem) {
+                        // documentElement is verified for cases where it doesn't yet exist
+                        // (such as loading iframes in IE - #4833)
+                        var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+                        return documentElement ? documentElement.nodeName !== "HTML" : false;
+                    };
+
+                    /**
+                     * Sets document-related variables once based on the current document
+                     * 
+                     * @param {Element|Object}
+                     *            [doc] An element or document object to use to set the document
+                     * @returns {Object} Returns the current document
+                     */
+                    setDocument = Sizzle.setDocument = function(node) {
+                        var hasCompare, parent,
+                            doc = node ? node.ownerDocument || node : preferredDoc;
+
+                        // If no document and documentElement is available, return
+                        if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
+                            return document;
+                        }
+
+                        // Set our document
+                        document = doc;
+                        docElem = doc.documentElement;
+                        parent = doc.defaultView;
+
+                        // Support: IE>8
+                        // If iframe document is assigned to "document" variable and if iframe has
+                        // been reloaded,
+                        // IE will throw "permission denied" error when accessing "document"
+                        // variable, see jQuery #13936
+                        // IE6-8 do not support the defaultView property so parent will be undefined
+                        if (parent && parent !== parent.top) {
+                            // IE11 does not have attachEvent, so all must suffer
+                            if (parent.addEventListener) {
+                                parent.addEventListener("unload", unloadHandler, false);
+                            } else if (parent.attachEvent) {
+                                parent.attachEvent("onunload", unloadHandler);
+                            }
+                        }
+
+                        /*
+                         * Support tests
+                         * ----------------------------------------------------------------------
+                         */
+                        documentIsHTML = !isXML(doc);
+
+                        /*
+                         * Attributes
+                         * ----------------------------------------------------------------------
+                         */
+
+                        // Support: IE<8
+                        // Verify that getAttribute really returns attributes and not properties
+                        // (excepting IE8 booleans)
+                        support.attributes = assert(function(div) {
+                            div.className = "i";
+                            return !div.getAttribute("className");
+                        });
+
+                        /***************************************************************************
+                         * getElement(s)By
+                         * ----------------------------------------------------------------------
+                         */
+
+                        // Check if getElementsByTagName("*") returns only elements
+                        support.getElementsByTagName = assert(function(div) {
+                            div.appendChild(doc.createComment(""));
+                            return !div.getElementsByTagName("*").length;
+                        });
+
+                        // Support: IE<9
+                        support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
+
+                        // Support: IE<10
+                        // Check if getElementById returns elements by name
+                        // The broken getElementById methods don't pick up programatically-set
+                        // names,
+                        // so use a roundabout getElementsByName test
+                        support.getById = assert(function(div) {
+                            docElem.appendChild(div).id = expando;
+                            return !doc.getElementsByName || !doc.getElementsByName(expando).length;
+                        });
+
+                        // ID find and filter
+                        if (support.getById) {
+                            Expr.find["ID"] = function(id, context) {
+                                if (typeof context.getElementById !== "undefined" && documentIsHTML) {
+                                    var m = context.getElementById(id);
+                                    // Check parentNode to catch when Blackberry 4.6 returns
+                                    // nodes that are no longer in the document #6963
+                                    return m && m.parentNode ? [m] : [];
+                                }
+                            };
+                            Expr.filter["ID"] = function(id) {
+                                var attrId = id.replace(runescape, funescape);
+                                return function(elem) {
+                                    return elem.getAttribute("id") === attrId;
+                                };
+                            };
+                        } else {
+                            // Support: IE6/7
+                            // getElementById is not reliable as a find shortcut
+                            delete Expr.find["ID"];
+
+                            Expr.filter["ID"] = function(id) {
+                                var attrId = id.replace(runescape, funescape);
+                                return function(elem) {
+                                    var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+                                    return node && node.value === attrId;
+                                };
+                            };
+                        }
+
+                        // Tag
+                        Expr.find["TAG"] = support.getElementsByTagName ?
+                            function(tag, context) {
+                                if (typeof context.getElementsByTagName !== "undefined") {
+                                    return context.getElementsByTagName(tag);
+
+                                    // DocumentFragment nodes don't have gEBTN
+                                } else if (support.qsa) {
+                                    return context.querySelectorAll(tag);
+                                }
+                            } :
+
+                            function(tag, context) {
+                                var elem,
+                                    tmp = [],
+                                    i = 0,
+                                    // By happy coincidence, a (broken) gEBTN appears on
+                                    // DocumentFragment nodes too
+                                    results = context.getElementsByTagName(tag);
+
+                                // Filter out possible comments
+                                if (tag === "*") {
+                                    while ((elem = results[i++])) {
+                                        if (elem.nodeType === 1) {
+                                            tmp.push(elem);
+                                        }
+                                    }
+
+                                    return tmp;
+                                }
+                                return results;
+                            };
+
+                        // Class
+                        Expr.find["CLASS"] = support.getElementsByClassName && function(className, context) {
+                            if (documentIsHTML) {
+                                return context.getElementsByClassName(className);
+                            }
+                        };
+
+                        /*
+                         * QSA/matchesSelector
+                         * ----------------------------------------------------------------------
+                         */
+
+                        // QSA and matchesSelector support
+
+                        // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+                        rbuggyMatches = [];
+
+                        // qSa(:focus) reports false when true (Chrome 21)
+                        // We allow this because of a bug in IE8/9 that throws an error
+                        // whenever `document.activeElement` is accessed on an iframe
+                        // So, we allow :focus to pass through QSA all the time to avoid the IE
+                        // error
+                        // See http://bugs.jquery.com/ticket/13378
+                        rbuggyQSA = [];
+
+                        if ((support.qsa = rnative.test(doc.querySelectorAll))) {
+                            // Build QSA regex
+                            // Regex strategy adopted from Diego Perini
+                            assert(function(div) {
+                                // Select is set to empty string on purpose
+                                // This is to test IE's treatment of not explicitly
+                                // setting a boolean content attribute,
+                                // since its presence should be enough
+                                // http://bugs.jquery.com/ticket/12359
+                                docElem.appendChild(div).innerHTML = "<a id='" + expando + "'></a>" +
+                                    "<select id='" + expando + "-\f]' msallowcapture=''>" +
+                                    "<option selected=''></option></select>";
+
+                                // Support: IE8, Opera 11-12.16
+                                // Nothing should be selected when empty strings follow ^= or $= or
+                                // *=
+                                // The test attribute must be unknown in Opera but "safe" for WinRT
+                                // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+                                if (div.querySelectorAll("[msallowcapture^='']").length) {
+                                    rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
+                                }
+
+                                // Support: IE8
+                                // Boolean attributes and "value" are not treated correctly
+                                if (!div.querySelectorAll("[selected]").length) {
+                                    rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
+                                }
+
+                                // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+,
+                                // PhantomJS<1.9.7+
+                                if (!div.querySelectorAll("[id~=" + expando + "-]").length) {
+                                    rbuggyQSA.push("~=");
+                                }
+
+                                // Webkit/Opera - :checked should return selected option elements
+                                // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                                // IE8 throws error here and will not see later tests
+                                if (!div.querySelectorAll(":checked").length) {
+                                    rbuggyQSA.push(":checked");
+                                }
+
+                                // Support: Safari 8+, iOS 8+
+                                // https://bugs.webkit.org/show_bug.cgi?id=136851
+                                // In-page `selector#id sibing-combinator selector` fails
+                                if (!div.querySelectorAll("a#" + expando + "+*").length) {
+                                    rbuggyQSA.push(".#.+[+~]");
+                                }
+                            });
+
+                            assert(function(div) {
+                                // Support: Windows 8 Native Apps
+                                // The type and name attributes are restricted during .innerHTML
+                                // assignment
+                                var input = doc.createElement("input");
+                                input.setAttribute("type", "hidden");
+                                div.appendChild(input).setAttribute("name", "D");
+
+                                // Support: IE8
+                                // Enforce case-sensitivity of name attribute
+                                if (div.querySelectorAll("[name=d]").length) {
+                                    rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
+                                }
+
+                                // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements
+                                // are still enabled)
+                                // IE8 throws error here and will not see later tests
+                                if (!div.querySelectorAll(":enabled").length) {
+                                    rbuggyQSA.push(":enabled", ":disabled");
+                                }
+
+                                // Opera 10-11 does not throw on post-comma invalid pseudos
+                                div.querySelectorAll("*,:x");
+                                rbuggyQSA.push(",.*:");
+                            });
+                        }
+
+                        if ((support.matchesSelector = rnative.test((matches = docElem.matches ||
+                                docElem.webkitMatchesSelector ||
+                                docElem.mozMatchesSelector ||
+                                docElem.oMatchesSelector ||
+                                docElem.msMatchesSelector)))) {
+
+                            assert(function(div) {
+                                // Check to see if it's possible to do matchesSelector
+                                // on a disconnected node (IE 9)
+                                support.disconnectedMatch = matches.call(div, "div");
+
+                                // This should fail with an exception
+                                // Gecko does not error, returns false instead
+                                matches.call(div, "[s!='']:x");
+                                rbuggyMatches.push("!=", pseudos);
+                            });
+                        }
+
+                        rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
+                        rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
+
+                        /*
+                         * Contains
+                         * ----------------------------------------------------------------------
+                         */
+                        hasCompare = rnative.test(docElem.compareDocumentPosition);
+
+                        // Element contains another
+                        // Purposefully does not implement inclusive descendent
+                        // As in, an element does not contain itself
+                        contains = hasCompare || rnative.test(docElem.contains) ?
+                            function(a, b) {
+                                var adown = a.nodeType === 9 ? a.documentElement : a,
+                                    bup = b && b.parentNode;
+                                return a === bup || !!(bup && bup.nodeType === 1 && (
+                                    adown.contains ?
+                                    adown.contains(bup) :
+                                    a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
+                                ));
+                            } :
+                            function(a, b) {
+                                if (b) {
+                                    while ((b = b.parentNode)) {
+                                        if (b === a) {
+                                            return true;
+                                        }
+                                    }
+                                }
+                                return false;
+                            };
+
+                        /*
+                         * Sorting
+                         * ----------------------------------------------------------------------
+                         */
+
+                        // Document order sorting
+                        sortOrder = hasCompare ?
+                            function(a, b) {
+
+                                // Flag for duplicate removal
+                                if (a === b) {
+                                    hasDuplicate = true;
+                                    return 0;
+                                }
+
+                                // Sort on method existence if only one input has
+                                // compareDocumentPosition
+                                var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+                                if (compare) {
+                                    return compare;
+                                }
+
+                                // Calculate position if both inputs belong to the same document
+                                compare = (a.ownerDocument || a) === (b.ownerDocument || b) ?
+                                    a.compareDocumentPosition(b) :
+
+                                    // Otherwise we know they are disconnected
+                                    1;
+
+                                // Disconnected nodes
+                                if (compare & 1 ||
+                                    (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {
+
+                                    // Choose the first element that is related to our preferred
+                                    // document
+                                    if (a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
+                                        return -1;
+                                    }
+                                    if (b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
+                                        return 1;
+                                    }
+
+                                    // Maintain original order
+                                    return sortInput ?
+                                        (indexOf(sortInput, a) - indexOf(sortInput, b)) :
+                                        0;
+                                }
+
+                                return compare & 4 ? -1 : 1;
+                            } :
+                            function(a, b) {
+                                // Exit early if the nodes are identical
+                                if (a === b) {
+                                    hasDuplicate = true;
+                                    return 0;
+                                }
+
+                                var cur,
+                                    i = 0,
+                                    aup = a.parentNode,
+                                    bup = b.parentNode,
+                                    ap = [a],
+                                    bp = [b];
+
+                                // Parentless nodes are either documents or disconnected
+                                if (!aup || !bup) {
+                                    return a === doc ? -1 :
+                                        b === doc ? 1 :
+                                        aup ? -1 :
+                                        bup ? 1 :
+                                        sortInput ?
+                                        (indexOf(sortInput, a) - indexOf(sortInput, b)) :
+                                        0;
+
+                                    // If the nodes are siblings, we can do a quick check
+                                } else if (aup === bup) {
+                                    return siblingCheck(a, b);
+                                }
+
+                                // Otherwise we need full lists of their ancestors for comparison
+                                cur = a;
+                                while ((cur = cur.parentNode)) {
+                                    ap.unshift(cur);
+                                }
+                                cur = b;
+                                while ((cur = cur.parentNode)) {
+                                    bp.unshift(cur);
+                                }
+
+                                // Walk down the tree looking for a discrepancy
+                                while (ap[i] === bp[i]) {
+                                    i++;
+                                }
+
+                                return i ?
+                                    // Do a sibling check if the nodes have a common ancestor
+                                    siblingCheck(ap[i], bp[i]) :
+
+                                    // Otherwise nodes in our document sort first
+                                    ap[i] === preferredDoc ? -1 :
+                                    bp[i] === preferredDoc ? 1 :
+                                    0;
+                            };
+
+                        return doc;
+                    };
+
+                    Sizzle.matches = function(expr, elements) {
+                        return Sizzle(expr, null, null, elements);
+                    };
+
+                    Sizzle.matchesSelector = function(elem, expr) {
+                        // Set document vars if needed
+                        if ((elem.ownerDocument || elem) !== document) {
+                            setDocument(elem);
+                        }
+
+                        // Make sure that attribute selectors are quoted
+                        expr = expr.replace(rattributeQuotes, "='$1']");
+
+                        if (support.matchesSelector && documentIsHTML &&
+                            (!rbuggyMatches || !rbuggyMatches.test(expr)) &&
+                            (!rbuggyQSA || !rbuggyQSA.test(expr))) {
+
+                            try {
+                                var ret = matches.call(elem, expr);
+
+                                // IE 9's matchesSelector returns false on disconnected nodes
+                                if (ret || support.disconnectedMatch ||
+                                    // As well, disconnected nodes are said to be in a document
+                                    // fragment in IE 9
+                                    elem.document && elem.document.nodeType !== 11) {
+                                    return ret;
+                                }
+                            } catch (e) {}
+                        }
+
+                        return Sizzle(expr, document, null, [elem]).length > 0;
+                    };
+
+                    Sizzle.contains = function(context, elem) {
+                        // Set document vars if needed
+                        if ((context.ownerDocument || context) !== document) {
+                            setDocument(context);
+                        }
+                        return contains(context, elem);
+                    };
+
+                    Sizzle.attr = function(elem, name) {
+                        // Set document vars if needed
+                        if ((elem.ownerDocument || elem) !== document) {
+                            setDocument(elem);
+                        }
+
+                        var fn = Expr.attrHandle[name.toLowerCase()],
+                            // Don't get fooled by Object.prototype properties (jQuery #13807)
+                            val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?
+                            fn(elem, name, !documentIsHTML) :
+                            undefined;
+
+                        return val !== undefined ?
+                            val :
+                            support.attributes || !documentIsHTML ?
+                            elem.getAttribute(name) :
+                            (val = elem.getAttributeNode(name)) && val.specified ?
+                            val.value :
+                            null;
+                    };
+
+                    Sizzle.error = function(msg) {
+                        throw new Error("Syntax error, unrecognized expression: " + msg);
+                    };
+
+                    /**
+                     * Document sorting and removing duplicates
+                     * 
+                     * @param {ArrayLike}
+                     *            results
+                     */
+                    Sizzle.uniqueSort = function(results) {
+                        var elem,
+                            duplicates = [],
+                            j = 0,
+                            i = 0;
+
+                        // Unless we *know* we can detect duplicates, assume their presence
+                        hasDuplicate = !support.detectDuplicates;
+                        sortInput = !support.sortStable && results.slice(0);
+                        results.sort(sortOrder);
+
+                        if (hasDuplicate) {
+                            while ((elem = results[i++])) {
+                                if (elem === results[i]) {
+                                    j = duplicates.push(i);
+                                }
+                            }
+                            while (j--) {
+                                results.splice(duplicates[j], 1);
+                            }
+                        }
+
+                        // Clear input after sorting to release objects
+                        // See https://github.com/jquery/sizzle/pull/225
+                        sortInput = null;
+
+                        return results;
+                    };
+
+                    /**
+                     * Utility function for retrieving the text value of an array of DOM nodes
+                     * 
+                     * @param {Array|Element}
+                     *            elem
+                     */
+                    getText = Sizzle.getText = function(elem) {
+                        var node,
+                            ret = "",
+                            i = 0,
+                            nodeType = elem.nodeType;
+
+                        if (!nodeType) {
+                            // If no nodeType, this is expected to be an array
+                            while ((node = elem[i++])) {
+                                // Do not traverse comment nodes
+                                ret += getText(node);
+                            }
+                        } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
+                            // Use textContent for elements
+                            // innerText usage removed for consistency of new lines (jQuery #11153)
+                            if (typeof elem.textContent === "string") {
+                                return elem.textContent;
+                            } else {
+                                // Traverse its children
+                                for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+                                    ret += getText(elem);
+                                }
+                            }
+                        } else if (nodeType === 3 || nodeType === 4) {
+                            return elem.nodeValue;
+                        }
+                        // Do not include comment or processing instruction nodes
+
+                        return ret;
+                    };
+
+                    Expr = Sizzle.selectors = {
+
+                        // Can be adjusted by the user
+                        cacheLength: 50,
+
+                        createPseudo: markFunction,
+
+                        match: matchExpr,
+
+                        attrHandle: {},
+
+                        find: {},
+
+                        relative: {
+                            ">": {
+                                dir: "parentNode",
+                                first: true
+                            },
+                            " ": {
+                                dir: "parentNode"
+                            },
+                            "+": {
+                                dir: "previousSibling",
+                                first: true
+                            },
+                            "~": {
+                                dir: "previousSibling"
+                            }
+                        },
+
+                        preFilter: {
+                            "ATTR": function(match) {
+                                match[1] = match[1].replace(runescape, funescape);
+
+                                // Move the given value to match[3] whether quoted or unquoted
+                                match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
+
+                                if (match[2] === "~=") {
+                                    match[3] = " " + match[3] + " ";
+                                }
+
+                                return match.slice(0, 4);
+                            },
+
+                            "CHILD": function(match) {
+                                /*
+                                 * matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what
+                                 * (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4
+                                 * xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component
+                                 * 6 x of xn-component 7 sign of y-component 8 y of y-component
+                                 */
+                                match[1] = match[1].toLowerCase();
+
+                                if (match[1].slice(0, 3) === "nth") {
+                                    // nth-* requires argument
+                                    if (!match[3]) {
+                                        Sizzle.error(match[0]);
+                                    }
+
+                                    // numeric x and y parameters for Expr.filter.CHILD
+                                    // remember that false/true cast respectively to 0/1
+                                    match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
+                                    match[5] = +((match[7] + match[8]) || match[3] === "odd");
+
+                                    // other types prohibit arguments
+                                } else if (match[3]) {
+                                    Sizzle.error(match[0]);
+                                }
+
+                                return match;
+                            },
+
+                            "PSEUDO": function(match) {
+                                var excess,
+                                    unquoted = !match[6] && match[2];
+
+                                if (matchExpr["CHILD"].test(match[0])) {
+                                    return null;
+                                }
+
+                                // Accept quoted arguments as-is
+                                if (match[3]) {
+                                    match[2] = match[4] || match[5] || "";
+
+                                    // Strip excess characters from unquoted arguments
+                                } else if (unquoted && rpseudo.test(unquoted) &&
+                                    // Get excess from tokenize (recursively)
+                                    (excess = tokenize(unquoted, true)) &&
+                                    // advance to the next closing parenthesis
+                                    (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
+
+                                    // excess is a negative index
+                                    match[0] = match[0].slice(0, excess);
+                                    match[2] = unquoted.slice(0, excess);
+                                }
+
+                                // Return only captures needed by the pseudo filter method (type and
+                                // argument)
+                                return match.slice(0, 3);
+                            }
+                        },
+
+                        filter: {
+
+                            "TAG": function(nodeNameSelector) {
+                                var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
+                                return nodeNameSelector === "*" ?
+                                    function() {
+                                        return true;
+                                    } :
+                                    function(elem) {
+                                        return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                                    };
+                            },
+
+                            "CLASS": function(className) {
+                                var pattern = classCache[className + " "];
+
+                                return pattern ||
+                                    (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) &&
+                                    classCache(className, function(elem) {
+                                        return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
+                                    });
+                            },
+
+                            "ATTR": function(name, operator, check) {
+                                return function(elem) {
+                                    var result = Sizzle.attr(elem, name);
+
+                                    if (result == null) {
+                                        return operator === "!=";
+                                    }
+                                    if (!operator) {
+                                        return true;
+                                    }
+
+                                    result += "";
+
+                                    return operator === "=" ? result === check :
+                                        operator === "!=" ? result !== check :
+                                        operator === "^=" ? check && result.indexOf(check) === 0 :
+                                        operator === "*=" ? check && result.indexOf(check) > -1 :
+                                        operator === "$=" ? check && result.slice(-check.length) === check :
+                                        operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 :
+                                        operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" :
+                                        false;
+                                };
+                            },
+
+                            "CHILD": function(type, what, argument, first, last) {
+                                var simple = type.slice(0, 3) !== "nth",
+                                    forward = type.slice(-4) !== "last",
+                                    ofType = what === "of-type";
+
+                                return first === 1 && last === 0 ?
+
+                                    // Shortcut for :nth-*(n)
+                                    function(elem) {
+                                        return !!elem.parentNode;
+                                    } :
+
+                                    function(elem, context, xml) {
+                                        var cache, outerCache, node, diff, nodeIndex, start,
+                                            dir = simple !== forward ? "nextSibling" : "previousSibling",
+                                            parent = elem.parentNode,
+                                            name = ofType && elem.nodeName.toLowerCase(),
+                                            useCache = !xml && !ofType;
+
+                                        if (parent) {
+
+                                            // :(first|last|only)-(child|of-type)
+                                            if (simple) {
+                                                while (dir) {
+                                                    node = elem;
+                                                    while ((node = node[dir])) {
+                                                        if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
+                                                            return false;
+                                                        }
+                                                    }
+                                                    // Reverse direction for :only-* (if we haven't
+                                                    // yet done so)
+                                                    start = dir = type === "only" && !start && "nextSibling";
+                                                }
+                                                return true;
+                                            }
+
+                                            start = [forward ? parent.firstChild : parent.lastChild];
+
+                                            // non-xml :nth-child(...) stores cache data on `parent`
+                                            if (forward && useCache) {
+                                                // Seek `elem` from a previously-cached index
+                                                outerCache = parent[expando] || (parent[expando] = {});
+                                                cache = outerCache[type] || [];
+                                                nodeIndex = cache[0] === dirruns && cache[1];
+                                                diff = cache[0] === dirruns && cache[2];
+                                                node = nodeIndex && parent.childNodes[nodeIndex];
+
+                                                while ((node = ++nodeIndex && node && node[dir] ||
+
+                                                        // Fallback to seeking `elem` from the start
+                                                        (diff = nodeIndex = 0) || start.pop())) {
+
+                                                    // When found, cache indexes on `parent` and
+                                                    // break
+                                                    if (node.nodeType === 1 && ++diff && node === elem) {
+                                                        outerCache[type] = [dirruns, nodeIndex, diff];
+                                                        break;
+                                                    }
+                                                }
+
+                                                // Use previously-cached element index if available
+                                            } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
+                                                diff = cache[1];
+
+                                                // xml :nth-child(...) or :nth-last-child(...) or
+                                                // :nth(-last)?-of-type(...)
+                                            } else {
+                                                // Use the same loop as above to seek `elem` from
+                                                // the start
+                                                while ((node = ++nodeIndex && node && node[dir] ||
+                                                        (diff = nodeIndex = 0) || start.pop())) {
+
+                                                    if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
+                                                        // Cache the index of each encountered
+                                                        // element
+                                                        if (useCache) {
+                                                            (node[expando] || (node[expando] = {}))[type] = [dirruns, diff];
+                                                        }
+
+                                                        if (node === elem) {
+                                                            break;
+                                                        }
+                                                    }
+                                                }
+                                            }
+
+                                            // Incorporate the offset, then check against cycle size
+                                            diff -= last;
+                                            return diff === first || (diff % first === 0 && diff / first >= 0);
+                                        }
+                                    };
+                            },
+
+                            "PSEUDO": function(pseudo, argument) {
+                                // pseudo-class names are case-insensitive
+                                // http://www.w3.org/TR/selectors/#pseudo-classes
+                                // Prioritize by case sensitivity in case custom pseudos are added
+                                // with uppercase letters
+                                // Remember that setFilters inherits from pseudos
+                                var args,
+                                    fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||
+                                    Sizzle.error("unsupported pseudo: " + pseudo);
+
+                                // The user may use createPseudo to indicate that
+                                // arguments are needed to create the filter function
+                                // just as Sizzle does
+                                if (fn[expando]) {
+                                    return fn(argument);
+                                }
+
+                                // But maintain support for old signatures
+                                if (fn.length > 1) {
+                                    args = [pseudo, pseudo, "", argument];
+                                    return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?
+                                        markFunction(function(seed, matches) {
+                                            var idx,
+                                                matched = fn(seed, argument),
+                                                i = matched.length;
+                                            while (i--) {
+                                                idx = indexOf(seed, matched[i]);
+                                                seed[idx] = !(matches[idx] = matched[i]);
+                                            }
+                                        }) :
+                                        function(elem) {
+                                            return fn(elem, 0, args);
+                                        };
+                                }
+
+                                return fn;
+                            }
+                        },
+
+                        pseudos: {
+                            // Potentially complex pseudos
+                            "not": markFunction(function(selector) {
+                                // Trim the selector passed to compile
+                                // to avoid treating leading and trailing
+                                // spaces as combinators
+                                var input = [],
+                                    results = [],
+                                    matcher = compile(selector.replace(rtrim, "$1"));
+
+                                return matcher[expando] ?
+                                    markFunction(function(seed, matches, context, xml) {
+                                        var elem,
+                                            unmatched = matcher(seed, null, xml, []),
+                                            i = seed.length;
+
+                                        // Match elements unmatched by `matcher`
+                                        while (i--) {
+                                            if ((elem = unmatched[i])) {
+                                                seed[i] = !(matches[i] = elem);
+                                            }
+                                        }
+                                    }) :
+                                    function(elem, context, xml) {
+                                        input[0] = elem;
+                                        matcher(input, null, xml, results);
+                                        // Don't keep the element (issue #299)
+                                        input[0] = null;
+                                        return !results.pop();
+                                    };
+                            }),
+
+                            "has": markFunction(function(selector) {
+                                return function(elem) {
+                                    return Sizzle(selector, elem).length > 0;
+                                };
+                            }),
+
+                            "contains": markFunction(function(text) {
+                                text = text.replace(runescape, funescape);
+                                return function(elem) {
+                                    return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
+                                };
+                            }),
+
+                            // "Whether an element is represented by a :lang() selector
+                            // is based solely on the element's language value
+                            // being equal to the identifier C,
+                            // or beginning with the identifier C immediately followed by "-".
+                            // The matching of C against the element's language value is performed
+                            // case-insensitively.
+                            // The identifier C does not have to be a valid language name."
+                            // http://www.w3.org/TR/selectors/#lang-pseudo
+                            "lang": markFunction(function(lang) {
+                                // lang value must be a valid identifier
+                                if (!ridentifier.test(lang || "")) {
+                                    Sizzle.error("unsupported lang: " + lang);
+                                }
+                                lang = lang.replace(runescape, funescape).toLowerCase();
+                                return function(elem) {
+                                    var elemLang;
+                                    do {
+                                        if ((elemLang = documentIsHTML ?
+                                                elem.lang :
+                                                elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) {
+
+                                            elemLang = elemLang.toLowerCase();
+                                            return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
+                                        }
+                                    } while ((elem = elem.parentNode) && elem.nodeType === 1);
+                                    return false;
+                                };
+                            }),
+
+                            // Miscellaneous
+                            "target": function(elem) {
+                                var hash = window.location && window.location.hash;
+                                return hash && hash.slice(1) === elem.id;
+                            },
+
+                            "root": function(elem) {
+                                return elem === docElem;
+                            },
+
+                            "focus": function(elem) {
+                                return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+                            },
+
+                            // Boolean properties
+                            "enabled": function(elem) {
+                                return elem.disabled === false;
+                            },
+
+                            "disabled": function(elem) {
+                                return elem.disabled === true;
+                            },
+
+                            "checked": function(elem) {
+                                // In CSS3, :checked should return both checked and selected
+                                // elements
+                                // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                                var nodeName = elem.nodeName.toLowerCase();
+                                return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+                            },
+
+                            "selected": function(elem) {
+                                // Accessing this property makes selected-by-default
+                                // options in Safari work properly
+                                if (elem.parentNode) {
+                                    elem.parentNode.selectedIndex;
+                                }
+
+                                return elem.selected === true;
+                            },
+
+                            // Contents
+                            "empty": function(elem) {
+                                // http://www.w3.org/TR/selectors/#empty-pseudo
+                                // :empty is negated by element (1) or content nodes (text: 3;
+                                // cdata: 4; entity ref: 5),
+                                // but not by others (comment: 8; processing instruction: 7; etc.)
+                                // nodeType < 6 works because attributes (2) do not appear as
+                                // children
+                                for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+                                    if (elem.nodeType < 6) {
+                                        return false;
+                                    }
+                                }
+                                return true;
+                            },
+
+                            "parent": function(elem) {
+                                return !Expr.pseudos["empty"](elem);
+                            },
+
+                            // Element/input types
+                            "header": function(elem) {
+                                return rheader.test(elem.nodeName);
+                            },
+
+                            "input": function(elem) {
+                                return rinputs.test(elem.nodeName);
+                            },
+
+                            "button": function(elem) {
+                                var name = elem.nodeName.toLowerCase();
+                                return name === "input" && elem.type === "button" || name === "button";
+                            },
+
+                            "text": function(elem) {
+                                var attr;
+                                return elem.nodeName.toLowerCase() === "input" &&
+                                    elem.type === "text" &&
+
+                                    // Support: IE<8
+                                    // New HTML5 attribute values (e.g., "search") appear with
+                                    // elem.type === "text"
+                                    ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
+                            },
+
+                            // Position-in-collection
+                            "first": createPositionalPseudo(function() {
+                                return [0];
+                            }),
+
+                            "last": createPositionalPseudo(function(matchIndexes, length) {
+                                return [length - 1];
+                            }),
+
+                            "eq": createPositionalPseudo(function(matchIndexes, length, argument) {
+                                return [argument < 0 ? argument + length : argument];
+                            }),
+
+                            "even": createPositionalPseudo(function(matchIndexes, length) {
+                                var i = 0;
+                                for (; i < length; i += 2) {
+                                    matchIndexes.push(i);
+                                }
+                                return matchIndexes;
+                            }),
+
+                            "odd": createPositionalPseudo(function(matchIndexes, length) {
+                                var i = 1;
+                                for (; i < length; i += 2) {
+                                    matchIndexes.push(i);
+                                }
+                                return matchIndexes;
+                            }),
+
+                            "lt": createPositionalPseudo(function(matchIndexes, length, argument) {
+                                var i = argument < 0 ? argument + length : argument;
+                                for (; --i >= 0;) {
+                                    matchIndexes.push(i);
+                                }
+                                return matchIndexes;
+                            }),
+
+                            "gt": createPositionalPseudo(function(matchIndexes, length, argument) {
+                                var i = argument < 0 ? argument + length : argument;
+                                for (; ++i < length;) {
+                                    matchIndexes.push(i);
+                                }
+                                return matchIndexes;
+                            })
+                        }
+                    };
+
+                    Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+                    // Add button/input type pseudos
+                    for (i in {
+                            radio: true,
+                            checkbox: true,
+                            file: true,
+                            password: true,
+                            image: true
+                        }) {
+                        Expr.pseudos[i] = createInputPseudo(i);
+                    }
+                    for (i in {
+                            submit: true,
+                            reset: true
+                        }) {
+                        Expr.pseudos[i] = createButtonPseudo(i);
+                    }
+
+                    // Easy API for creating new setFilters
+                    function setFilters() {}
+                    setFilters.prototype = Expr.filters = Expr.pseudos;
+                    Expr.setFilters = new setFilters();
+
+                    tokenize = Sizzle.tokenize = function(selector, parseOnly) {
+                        var matched, match, tokens, type,
+                            soFar, groups, preFilters,
+                            cached = tokenCache[selector + " "];
+
+                        if (cached) {
+                            return parseOnly ? 0 : cached.slice(0);
+                        }
+
+                        soFar = selector;
+                        groups = [];
+                        preFilters = Expr.preFilter;
+
+                        while (soFar) {
+
+                            // Comma and first run
+                            if (!matched || (match = rcomma.exec(soFar))) {
+                                if (match) {
+                                    // Don't consume trailing commas as valid
+                                    soFar = soFar.slice(match[0].length) || soFar;
+                                }
+                                groups.push((tokens = []));
+                            }
+
+                            matched = false;
+
+                            // Combinators
+                            if ((match = rcombinators.exec(soFar))) {
+                                matched = match.shift();
+                                tokens.push({
+                                    value: matched,
+                                    // Cast descendant combinators to space
+                                    type: match[0].replace(rtrim, " ")
+                                });
+                                soFar = soFar.slice(matched.length);
+                            }
+
+                            // Filters
+                            for (type in Expr.filter) {
+                                if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||
+                                        (match = preFilters[type](match)))) {
+                                    matched = match.shift();
+                                    tokens.push({
+                                        value: matched,
+                                        type: type,
+                                        matches: match
+                                    });
+                                    soFar = soFar.slice(matched.length);
+                                }
+                            }
+
+                            if (!matched) {
+                                break;
+                            }
+                        }
+
+                        // Return the length of the invalid excess
+                        // if we're just parsing
+                        // Otherwise, throw an error or return tokens
+                        return parseOnly ?
+                            soFar.length :
+                            soFar ?
+                            Sizzle.error(selector) :
+                            // Cache the tokens
+                            tokenCache(selector, groups).slice(0);
+                    };
+
+                    function toSelector(tokens) {
+                        var i = 0,
+                            len = tokens.length,
+                            selector = "";
+                        for (; i < len; i++) {
+                            selector += tokens[i].value;
+                        }
+                        return selector;
+                    }
+
+                    function addCombinator(matcher, combinator, base) {
+                        var dir = combinator.dir,
+                            checkNonElements = base && dir === "parentNode",
+                            doneName = done++;
+
+                        return combinator.first ?
+                            // Check against closest ancestor/preceding element
+                            function(elem, context, xml) {
+                                while ((elem = elem[dir])) {
+                                    if (elem.nodeType === 1 || checkNonElements) {
+                                        return matcher(elem, context, xml);
+                                    }
+                                }
+                            } :
+
+                            // Check against all ancestor/preceding elements
+                            function(elem, context, xml) {
+                                var oldCache, outerCache,
+                                    newCache = [dirruns, doneName];
+
+                                // We can't set arbitrary data on XML nodes, so they don't benefit
+                                // from dir caching
+                                if (xml) {
+                                    while ((elem = elem[dir])) {
+                                        if (elem.nodeType === 1 || checkNonElements) {
+                                            if (matcher(elem, context, xml)) {
+                                                return true;
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    while ((elem = elem[dir])) {
+                                        if (elem.nodeType === 1 || checkNonElements) {
+                                            outerCache = elem[expando] || (elem[expando] = {});
+                                            if ((oldCache = outerCache[dir]) &&
+                                                oldCache[0] === dirruns && oldCache[1] === doneName) {
+
+                                                // Assign to newCache so results back-propagate to
+                                                // previous elements
+                                                return (newCache[2] = oldCache[2]);
+                                            } else {
+                                                // Reuse newcache so results back-propagate to
+                                                // previous elements
+                                                outerCache[dir] = newCache;
+
+                                                // A match means we're done; a fail means we have to
+                                                // keep checking
+                                                if ((newCache[2] = matcher(elem, context, xml))) {
+                                                    return true;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            };
+                    }
+
+                    function elementMatcher(matchers) {
+                        return matchers.length > 1 ?
+                            function(elem, context, xml) {
+                                var i = matchers.length;
+                                while (i--) {
+                                    if (!matchers[i](elem, context, xml)) {
+                                        return false;
+                                    }
+                                }
+                                return true;
+                            } :
+                            matchers[0];
+                    }
+
+                    function multipleContexts(selector, contexts, results) {
+                        var i = 0,
+                            len = contexts.length;
+                        for (; i < len; i++) {
+                            Sizzle(selector, contexts[i], results);
+                        }
+                        return results;
+                    }
+
+                    function condense(unmatched, map, filter, context, xml) {
+                        var elem,
+                            newUnmatched = [],
+                            i = 0,
+                            len = unmatched.length,
+                            mapped = map != null;
+
+                        for (; i < len; i++) {
+                            if ((elem = unmatched[i])) {
+                                if (!filter || filter(elem, context, xml)) {
+                                    newUnmatched.push(elem);
+                                    if (mapped) {
+                                        map.push(i);
+                                    }
+                                }
+                            }
+                        }
+
+                        return newUnmatched;
+                    }
+
+                    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
+                        if (postFilter && !postFilter[expando]) {
+                            postFilter = setMatcher(postFilter);
+                        }
+                        if (postFinder && !postFinder[expando]) {
+                            postFinder = setMatcher(postFinder, postSelector);
+                        }
+                        return markFunction(function(seed, results, context, xml) {
+                            var temp, i, elem,
+                                preMap = [],
+                                postMap = [],
+                                preexisting = results.length,
+
+                                // Get initial elements from seed or context
+                                elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
+
+                                // Prefilter to get matcher input, preserving a map for seed-results
+                                // synchronization
+                                matcherIn = preFilter && (seed || !selector) ?
+                                condense(elems, preMap, preFilter, context, xml) :
+                                elems,
+
+                                matcherOut = matcher ?
+                                // If we have a postFinder, or filtered seed, or non-seed
+                                // postFilter or preexisting results,
+                                postFinder || (seed ? preFilter : preexisting || postFilter) ?
+
+                                // ...intermediate processing is necessary
+                                [] :
+
+                                // ...otherwise use results directly
+                                results :
+                                matcherIn;
+
+                            // Find primary matches
+                            if (matcher) {
+                                matcher(matcherIn, matcherOut, context, xml);
+                            }
+
+                            // Apply postFilter
+                            if (postFilter) {
+                                temp = condense(matcherOut, postMap);
+                                postFilter(temp, [], context, xml);
+
+                                // Un-match failing elements by moving them back to matcherIn
+                                i = temp.length;
+                                while (i--) {
+                                    if ((elem = temp[i])) {
+                                        matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
+                                    }
+                                }
+                            }
+
+                            if (seed) {
+                                if (postFinder || preFilter) {
+                                    if (postFinder) {
+                                        // Get the final matcherOut by condensing this intermediate
+                                        // into postFinder contexts
+                                        temp = [];
+                                        i = matcherOut.length;
+                                        while (i--) {
+                                            if ((elem = matcherOut[i])) {
+                                                // Restore matcherIn since elem is not yet a final
+                                                // match
+                                                temp.push((matcherIn[i] = elem));
+                                            }
+                                        }
+                                        postFinder(null, (matcherOut = []), temp, xml);
+                                    }
+
+                                    // Move matched elements from seed to results to keep them
+                                    // synchronized
+                                    i = matcherOut.length;
+                                    while (i--) {
+                                        if ((elem = matcherOut[i]) &&
+                                            (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
+
+                                            seed[temp] = !(results[temp] = elem);
+                                        }
+                                    }
+                                }
+
+                                // Add elements to results, through postFinder if defined
+                            } else {
+                                matcherOut = condense(
+                                    matcherOut === results ?
+                                    matcherOut.splice(preexisting, matcherOut.length) :
+                                    matcherOut
+                                );
+                                if (postFinder) {
+                                    postFinder(null, results, matcherOut, xml);
+                                } else {
+                                    push.apply(results, matcherOut);
+                                }
+                            }
+                        });
+                    }
+
+                    function matcherFromTokens(tokens) {
+                        var checkContext, matcher, j,
+                            len = tokens.length,
+                            leadingRelative = Expr.relative[tokens[0].type],
+                            implicitRelative = leadingRelative || Expr.relative[" "],
+                            i = leadingRelative ? 1 : 0,
+
+                            // The foundational matcher ensures that elements are reachable from
+                            // top-level context(s)
+                            matchContext = addCombinator(function(elem) {
+                                return elem === checkContext;
+                            }, implicitRelative, true),
+                            matchAnyContext = addCombinator(function(elem) {
+                                return indexOf(checkContext, elem) > -1;
+                            }, implicitRelative, true),
+                            matchers = [function(elem, context, xml) {
+                                var ret = (!leadingRelative && (xml || context !== outermostContext)) || (
+                                    (checkContext = context).nodeType ?
+                                    matchContext(elem, context, xml) :
+                                    matchAnyContext(elem, context, xml));
+                                // Avoid hanging onto element (issue #299)
+                                checkContext = null;
+                                return ret;
+                            }];
+
+                        for (; i < len; i++) {
+                            if ((matcher = Expr.relative[tokens[i].type])) {
+                                matchers = [addCombinator(elementMatcher(matchers), matcher)];
+                            } else {
+                                matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
+
+                                // Return special upon seeing a positional matcher
+                                if (matcher[expando]) {
+                                    // Find the next relative operator (if any) for proper handling
+                                    j = ++i;
+                                    for (; j < len; j++) {
+                                        if (Expr.relative[tokens[j].type]) {
+                                            break;
+                                        }
+                                    }
+                                    return setMatcher(
+                                        i > 1 && elementMatcher(matchers),
+                                        i > 1 && toSelector(
+                                            // If the preceding token was a descendant combinator,
+                                            // insert an implicit any-element `*`
+                                            tokens.slice(0, i - 1).concat({
+                                                value: tokens[i - 2].type === " " ? "*" : ""
+                                            })
+                                        ).replace(rtrim, "$1"),
+                                        matcher,
+                                        i < j && matcherFromTokens(tokens.slice(i, j)),
+                                        j < len && matcherFromTokens((tokens = tokens.slice(j))),
+                                        j < len && toSelector(tokens)
+                                    );
+                                }
+                                matchers.push(matcher);
+                            }
+                        }
+
+                        return elementMatcher(matchers);
+                    }
+
+                    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
+                        var bySet = setMatchers.length > 0,
+                            byElement = elementMatchers.length > 0,
+                            superMatcher = function(seed, context, xml, results, outermost) {
+                                var elem, j, matcher,
+                                    matchedCount = 0,
+                                    i = "0",
+                                    unmatched = seed && [],
+                                    setMatched = [],
+                                    contextBackup = outermostContext,
+                                    // We must always have either seed elements or outermost context
+                                    elems = seed || byElement && Expr.find["TAG"]("*", outermost),
+                                    // Use integer dirruns iff this is the outermost matcher
+                                    dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+                                    len = elems.length;
+
+                                if (outermost) {
+                                    outermostContext = context !== document && context;
+                                }
+
+                                // Add elements passing elementMatchers directly to results
+                                // Keep `i` a string if there are no elements so `matchedCount` will
+                                // be "00" below
+                                // Support: IE<9, Safari
+                                // Tolerate NodeList properties (IE: "length"; Safari: <number>)
+                                // matching elements by id
+                                for (; i !== len && (elem = elems[i]) != null; i++) {
+                                    if (byElement && elem) {
+                                        j = 0;
+                                        while ((matcher = elementMatchers[j++])) {
+                                            if (matcher(elem, context, xml)) {
+                                                results.push(elem);
+                                                break;
+                                            }
+                                        }
+                                        if (outermost) {
+                                            dirruns = dirrunsUnique;
+                                        }
+                                    }
+
+                                    // Track unmatched elements for set filters
+                                    if (bySet) {
+                                        // They will have gone through all possible matchers
+                                        if ((elem = !matcher && elem)) {
+                                            matchedCount--;
+                                        }
+
+                                        // Lengthen the array for every element, matched or not
+                                        if (seed) {
+                                            unmatched.push(elem);
+                                        }
+                                    }
+                                }
+
+                                // Apply set filters to unmatched elements
+                                matchedCount += i;
+                                if (bySet && i !== matchedCount) {
+                                    j = 0;
+                                    while ((matcher = setMatchers[j++])) {
+                                        matcher(unmatched, setMatched, context, xml);
+                                    }
+
+                                    if (seed) {
+                                        // Reintegrate element matches to eliminate the need for
+                                        // sorting
+                                        if (matchedCount > 0) {
+                                            while (i--) {
+                                                if (!(unmatched[i] || setMatched[i])) {
+                                                    setMatched[i] = pop.call(results);
+                                                }
+                                            }
+                                        }
+
+                                        // Discard index placeholder values to get only actual
+                                        // matches
+                                        setMatched = condense(setMatched);
+                                    }
+
+                                    // Add matches to results
+                                    push.apply(results, setMatched);
+
+                                    // Seedless set matches succeeding multiple successful matchers
+                                    // stipulate sorting
+                                    if (outermost && !seed && setMatched.length > 0 &&
+                                        (matchedCount + setMatchers.length) > 1) {
+
+                                        Sizzle.uniqueSort(results);
+                                    }
+                                }
+
+                                // Override manipulation of globals by nested matchers
+                                if (outermost) {
+                                    dirruns = dirrunsUnique;
+                                    outermostContext = contextBackup;
+                                }
+
+                                return unmatched;
+                            };
+
+                        return bySet ?
+                            markFunction(superMatcher) :
+                            superMatcher;
+                    }
+
+                    compile = Sizzle.compile = function(selector, match /* Internal Use Only */ ) {
+                        var i,
+                            setMatchers = [],
+                            elementMatchers = [],
+                            cached = compilerCache[selector + " "];
+
+                        if (!cached) {
+                            // Generate a function of recursive functions that can be used to check
+                            // each element
+                            if (!match) {
+                                match = tokenize(selector);
+                            }
+                            i = match.length;
+                            while (i--) {
+                                cached = matcherFromTokens(match[i]);
+                                if (cached[expando]) {
+                                    setMatchers.push(cached);
+                                } else {
+                                    elementMatchers.push(cached);
+                                }
+                            }
+
+                            // Cache the compiled function
+                            cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
+
+                            // Save selector and tokenization
+                            cached.selector = selector;
+                        }
+                        return cached;
+                    };
+
+                    /**
+                     * A low-level selection function that works with Sizzle's compiled selector
+                     * functions
+                     * 
+                     * @param {String|Function}
+                     *            selector A selector or a pre-compiled selector function built with
+                     *            Sizzle.compile
+                     * @param {Element}
+                     *            context
+                     * @param {Array}
+                     *            [results]
+                     * @param {Array}
+                     *            [seed] A set of elements to match against
+                     */
+                    select = Sizzle.select = function(selector, context, results, seed) {
+                        var i, tokens, token, type, find,
+                            compiled = typeof selector === "function" && selector,
+                            match = !seed && tokenize((selector = compiled.selector || selector));
+
+                        results = results || [];
+
+                        // Try to minimize operations if there is no seed and only one group
+                        if (match.length === 1) {
+
+                            // Take a shortcut and set the context if the root selector is an ID
+                            tokens = match[0] = match[0].slice(0);
+                            if (tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                                support.getById && context.nodeType === 9 && documentIsHTML &&
+                                Expr.relative[tokens[1].type]) {
+
+                                context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
+                                if (!context) {
+                                    return results;
+
+                                    // Precompiled matchers will still verify ancestry, so step up a
+                                    // level
+                                } else if (compiled) {
+                                    context = context.parentNode;
+                                }
+
+                                selector = selector.slice(tokens.shift().value.length);
+                            }
+
+                            // Fetch a seed set for right-to-left matching
+                            i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
+                            while (i--) {
+                                token = tokens[i];
+
+                                // Abort if we hit a combinator
+                                if (Expr.relative[(type = token.type)]) {
+                                    break;
+                                }
+                                if ((find = Expr.find[type])) {
+                                    // Search, expanding context for leading sibling combinators
+                                    if ((seed = find(
+                                            token.matches[0].replace(runescape, funescape),
+                                            rsibling.test(tokens[0].type) && testContext(context.parentNode) || context
+                                        ))) {
+
+                                        // If seed is empty or no tokens remain, we can return early
+                                        tokens.splice(i, 1);
+                                        selector = seed.length && toSelector(tokens);
+                                        if (!selector) {
+                                            push.apply(results, seed);
+                                            return results;
+                                        }
+
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                        // Compile and execute a filtering function if one is not provided
+                        // Provide `match` to avoid retokenization if we modified the selector above
+                        (compiled || compile(selector, match))(
+                            seed,
+                            context, !documentIsHTML,
+                            results,
+                            rsibling.test(selector) && testContext(context.parentNode) || context
+                        );
+                        return results;
+                    };
+
+                    // One-time assignments
+
+                    // Sort stability
+                    support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
+
+                    // Support: Chrome 14-35+
+                    // Always assume duplicates if they aren't passed to the comparison function
+                    support.detectDuplicates = !!hasDuplicate;
+
+                    // Initialize against the default document
+                    setDocument();
+
+                    // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+                    // Detached nodes confoundingly follow *each other*
+                    support.sortDetached = assert(function(div1) {
+                        // Should return 1, but returns 4 (following)
+                        return div1.compareDocumentPosition(document.createElement("div")) & 1;
+                    });
+
+                    // Support: IE<8
+                    // Prevent attribute/property "interpolation"
+                    // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+                    if (!assert(function(div) {
+                            div.innerHTML = "<a href='#'></a>";
+                            return div.firstChild.getAttribute("href") === "#";
+                        })) {
+                        addHandle("type|href|height|width", function(elem, name, isXML) {
+                            if (!isXML) {
+                                return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
+                            }
+                        });
+                    }
+
+                    // Support: IE<9
+                    // Use defaultValue in place of getAttribute("value")
+                    if (!support.attributes || !assert(function(div) {
+                            div.innerHTML = "<input/>";
+                            div.firstChild.setAttribute("value", "");
+                            return div.firstChild.getAttribute("value") === "";
+                        })) {
+                        addHandle("value", function(elem, name, isXML) {
+                            if (!isXML && elem.nodeName.toLowerCase() === "input") {
+                                return elem.defaultValue;
+                            }
+                        });
+                    }
+
+                    // Support: IE<9
+                    // Use getAttributeNode to fetch booleans when getAttribute lies
+                    if (!assert(function(div) {
+                            return div.getAttribute("disabled") == null;
+                        })) {
+                        addHandle(booleans, function(elem, name, isXML) {
+                            var val;
+                            if (!isXML) {
+                                return elem[name] === true ? name.toLowerCase() :
+                                    (val = elem.getAttributeNode(name)) && val.specified ?
+                                    val.value :
+                                    null;
+                            }
+                        });
+                    }
+
+                    return Sizzle;
+
+                })(window);
+
+
+
+            jQuery.find = Sizzle;
+            jQuery.expr = Sizzle.selectors;
+            jQuery.expr[":"] = jQuery.expr.pseudos;
+            jQuery.unique = Sizzle.uniqueSort;
+            jQuery.text = Sizzle.getText;
+            jQuery.isXMLDoc = Sizzle.isXML;
+            jQuery.contains = Sizzle.contains;
+
+
+
+            var rneedsContext = jQuery.expr.match.needsContext;
+
+            var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
+
+
+
+            var risSimple = /^.[^:#\[\.,]*$/;
+
+            // Implement the identical functionality for filter and not
+            function winnow(elements, qualifier, not) {
+                if (jQuery.isFunction(qualifier)) {
+                    return jQuery.grep(elements, function(elem, i) {
+                        /* jshint -W018 */
+                        return !!qualifier.call(elem, i, elem) !== not;
+                    });
+
+                }
+
+                if (qualifier.nodeType) {
+                    return jQuery.grep(elements, function(elem) {
+                        return (elem === qualifier) !== not;
+                    });
+
+                }
+
+                if (typeof qualifier === "string") {
+                    if (risSimple.test(qualifier)) {
+                        return jQuery.filter(qualifier, elements, not);
+                    }
+
+                    qualifier = jQuery.filter(qualifier, elements);
+                }
+
+                return jQuery.grep(elements, function(elem) {
+                    return (indexOf.call(qualifier, elem) >= 0) !== not;
+                });
+            }
+
+            jQuery.filter = function(expr, elems, not) {
+                var elem = elems[0];
+
+                if (not) {
+                    expr = ":not(" + expr + ")";
+                }
+
+                return elems.length === 1 && elem.nodeType === 1 ?
+                    jQuery.find.matchesSelector(elem, expr) ? [elem] : [] :
+                    jQuery.find.matches(expr, jQuery.grep(elems, function(elem) {
+                        return elem.nodeType === 1;
+                    }));
+            };
+
+            jQuery.fn.extend({
+                find: function(selector) {
+                    var i,
+                        len = this.length,
+                        ret = [],
+                        self = this;
+
+                    if (typeof selector !== "string") {
+                        return this.pushStack(jQuery(selector).filter(function() {
+                            for (i = 0; i < len; i++) {
+                                if (jQuery.contains(self[i], this)) {
+                                    return true;
+                                }
+                            }
+                        }));
+                    }
+
+                    for (i = 0; i < len; i++) {
+                        jQuery.find(selector, self[i], ret);
+                    }
+
+                    // Needed because $( selector, context ) becomes $( context ).find(
+                    // selector )
+                    ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
+                    ret.selector = this.selector ? this.selector + " " + selector : selector;
+                    return ret;
+                },
+                filter: function(selector) {
+                    return this.pushStack(winnow(this, selector || [], false));
+                },
+                not: function(selector) {
+                    return this.pushStack(winnow(this, selector || [], true));
+                },
+                is: function(selector) {
+                    return !!winnow(
+                        this,
+
+                        // If this is a positional/relative selector, check membership in
+                        // the returned set
+                        // so $("p:first").is("p:last") won't return true for a doc with two
+                        // "p".
+                        typeof selector === "string" && rneedsContext.test(selector) ?
+                        jQuery(selector) :
+                        selector || [],
+                        false
+                    ).length;
+                }
+            });
+
+
+            // Initialize a jQuery object
+
+
+            // A central reference to the root jQuery(document)
+            var rootjQuery,
+
+                // A simple way to check for HTML strings
+                // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+                // Strict HTML recognition (#11290: must start with <)
+                rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+                init = jQuery.fn.init = function(selector, context) {
+                    var match, elem;
+
+                    // HANDLE: $(""), $(null), $(undefined), $(false)
+                    if (!selector) {
+                        return this;
+                    }
+
+                    // Handle HTML strings
+                    if (typeof selector === "string") {
+                        if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
+                            // Assume that strings that start and end with <> are HTML and
+                            // skip the regex check
+                            match = [null, selector, null];
+
+                        } else {
+                            match = rquickExpr.exec(selector);
+                        }
+
+                        // Match html or make sure no context is specified for #id
+                        if (match && (match[1] || !context)) {
+
+                            // HANDLE: $(html) -> $(array)
+                            if (match[1]) {
+                                context = context instanceof jQuery ? context[0] : context;
+
+                                // Option to run scripts is true for back-compat
+                                // Intentionally let the error be thrown if parseHTML is not
+                                // present
+                                jQuery.merge(this, jQuery.parseHTML(
+                                    match[1],
+                                    context && context.nodeType ? context.ownerDocument || context : document,
+                                    true
+                                ));
+
+                                // HANDLE: $(html, props)
+                                if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
+                                    for (match in context) {
+                                        // Properties of context are called as methods if
+                                        // possible
+                                        if (jQuery.isFunction(this[match])) {
+                                            this[match](context[match]);
+
+                                            // ...and otherwise set as attributes
+                                        } else {
+                                            this.attr(match, context[match]);
+                                        }
+                                    }
+                                }
+
+                                return this;
+
+                                // HANDLE: $(#id)
+                            } else {
+                                elem = document.getElementById(match[2]);
+
+                                // Support: Blackberry 4.6
+                                // gEBID returns nodes no longer in the document (#6963)
+                                if (elem && elem.parentNode) {
+                                    // Inject the element directly into the jQuery object
+                                    this.length = 1;
+                                    this[0] = elem;
+                                }
+
+                                this.context = document;
+                                this.selector = selector;
+                                return this;
+                            }
+
+                            // HANDLE: $(expr, $(...))
+                        } else if (!context || context.jquery) {
+                            return (context || rootjQuery).find(selector);
+
+                            // HANDLE: $(expr, context)
+                            // (which is just equivalent to: $(context).find(expr)
+                        } else {
+                            return this.constructor(context).find(selector);
+                        }
+
+                        // HANDLE: $(DOMElement)
+                    } else if (selector.nodeType) {
+                        this.context = this[0] = selector;
+                        this.length = 1;
+                        return this;
+
+                        // HANDLE: $(function)
+                        // Shortcut for document ready
+                    } else if (jQuery.isFunction(selector)) {
+                        return typeof rootjQuery.ready !== "undefined" ?
+                            rootjQuery.ready(selector) :
+                            // Execute immediately if ready is not present
+                            selector(jQuery);
+                    }
+
+                    if (selector.selector !== undefined) {
+                        this.selector = selector.selector;
+                        this.context = selector.context;
+                    }
+
+                    return jQuery.makeArray(selector, this);
+                };
+
+            // Give the init function the jQuery prototype for later instantiation
+            init.prototype = jQuery.fn;
+
+            // Initialize central reference
+            rootjQuery = jQuery(document);
+
+
+            var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+                // Methods guaranteed to produce a unique set when starting from a unique
+                // set
+                guaranteedUnique = {
+                    children: true,
+                    contents: true,
+                    next: true,
+                    prev: true
+                };
+
+            jQuery.extend({
+                dir: function(elem, dir, until) {
+                    var matched = [],
+                        truncate = until !== undefined;
+
+                    while ((elem = elem[dir]) && elem.nodeType !== 9) {
+                        if (elem.nodeType === 1) {
+                            if (truncate && jQuery(elem).is(until)) {
+                                break;
+                            }
+                            matched.push(elem);
+                        }
+                    }
+                    return matched;
+                },
+
+                sibling: function(n, elem) {
+                    var matched = [];
+
+                    for (; n; n = n.nextSibling) {
+                        if (n.nodeType === 1 && n !== elem) {
+                            matched.push(n);
+                        }
+                    }
+
+                    return matched;
+                }
+            });
+
+            jQuery.fn.extend({
+                has: function(target) {
+                    var targets = jQuery(target, this),
+                        l = targets.length;
+
+                    return this.filter(function() {
+                        var i = 0;
+                        for (; i < l; i++) {
+                            if (jQuery.contains(this, targets[i])) {
+                                return true;
+                            }
+                        }
+                    });
+                },
+
+                closest: function(selectors, context) {
+                    var cur,
+                        i = 0,
+                        l = this.length,
+                        matched = [],
+                        pos = rneedsContext.test(selectors) || typeof selectors !== "string" ?
+                        jQuery(selectors, context || this.context) :
+                        0;
+
+                    for (; i < l; i++) {
+                        for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
+                            // Always skip document fragments
+                            if (cur.nodeType < 11 && (pos ?
+                                    pos.index(cur) > -1 :
+
+                                    // Don't pass non-elements to Sizzle
+                                    cur.nodeType === 1 &&
+                                    jQuery.find.matchesSelector(cur, selectors))) {
+
+                                matched.push(cur);
+                                break;
+                            }
+                        }
+                    }
+
+                    return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched);
+                },
+
+                // Determine the position of an element within the set
+                index: function(elem) {
+
+                    // No argument, return index in parent
+                    if (!elem) {
+                        return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1;
+                    }
+
+                    // Index in selector
+                    if (typeof elem === "string") {
+                        return indexOf.call(jQuery(elem), this[0]);
+                    }
+
+                    // Locate the position of the desired element
+                    return indexOf.call(this,
+
+                        // If it receives a jQuery object, the first element is used
+                        elem.jquery ? elem[0] : elem
+                    );
+                },
+
+                add: function(selector, context) {
+                    return this.pushStack(
+                        jQuery.unique(
+                            jQuery.merge(this.get(), jQuery(selector, context))
+                        )
+                    );
+                },
+
+                addBack: function(selector) {
+                    return this.add(selector == null ?
+                        this.prevObject : this.prevObject.filter(selector)
+                    );
+                }
+            });
+
+            function sibling(cur, dir) {
+                while ((cur = cur[dir]) && cur.nodeType !== 1) {}
+                return cur;
+            }
+
+            jQuery.each({
+                parent: function(elem) {
+                    var parent = elem.parentNode;
+                    return parent && parent.nodeType !== 11 ? parent : null;
+                },
+                parents: function(elem) {
+                    return jQuery.dir(elem, "parentNode");
+                },
+                parentsUntil: function(elem, i, until) {
+                    return jQuery.dir(elem, "parentNode", until);
+                },
+                next: function(elem) {
+                    return sibling(elem, "nextSibling");
+                },
+                prev: function(elem) {
+                    return sibling(elem, "previousSibling");
+                },
+                nextAll: function(elem) {
+                    return jQuery.dir(elem, "nextSibling");
+                },
+                prevAll: function(elem) {
+                    return jQuery.dir(elem, "previousSibling");
+                },
+                nextUntil: function(elem, i, until) {
+                    return jQuery.dir(elem, "nextSibling", until);
+                },
+                prevUntil: function(elem, i, until) {
+                    return jQuery.dir(elem, "previousSibling", until);
+                },
+                siblings: function(elem) {
+                    return jQuery.sibling((elem.parentNode || {}).firstChild, elem);
+                },
+                children: function(elem) {
+                    return jQuery.sibling(elem.firstChild);
+                },
+                contents: function(elem) {
+                    return elem.contentDocument || jQuery.merge([], elem.childNodes);
+                }
+            }, function(name, fn) {
+                jQuery.fn[name] = function(until, selector) {
+                    var matched = jQuery.map(this, fn, until);
+
+                    if (name.slice(-5) !== "Until") {
+                        selector = until;
+                    }
+
+                    if (selector && typeof selector === "string") {
+                        matched = jQuery.filter(selector, matched);
+                    }
+
+                    if (this.length > 1) {
+                        // Remove duplicates
+                        if (!guaranteedUnique[name]) {
+                            jQuery.unique(matched);
+                        }
+
+                        // Reverse order for parents* and prev-derivatives
+                        if (rparentsprev.test(name)) {
+                            matched.reverse();
+                        }
+                    }
+
+                    return this.pushStack(matched);
+                };
+            });
+            var rnotwhite = (/\S+/g);
+
+
+
+            // String to Object options format cache
+            var optionsCache = {};
+
+            // Convert String-formatted options into Object-formatted ones and store in
+            // cache
+            function createOptions(options) {
+                var object = optionsCache[options] = {};
+                jQuery.each(options.match(rnotwhite) || [], function(_, flag) {
+                    object[flag] = true;
+                });
+                return object;
+            }
+
+            /*
+             * Create a callback list using the following parameters:
+             * 
+             * options: an optional list of space-separated options that will change how the
+             * callback list behaves or a more traditional option object
+             * 
+             * By default a callback list will act like an event callback list and can be
+             * "fired" multiple times.
+             * 
+             * Possible options:
+             * 
+             * once: will ensure the callback list can only be fired once (like a Deferred)
+             * 
+             * memory: will keep track of previous values and will call any callback added
+             * after the list has been fired right away with the latest "memorized" values
+             * (like a Deferred)
+             * 
+             * unique: will ensure a callback can only be added once (no duplicate in the
+             * list)
+             * 
+             * stopOnFalse: interrupt callings when a callback returns false
+             * 
+             */
+            jQuery.Callbacks = function(options) {
+
+                // Convert options from String-formatted to Object-formatted if needed
+                // (we check in cache first)
+                options = typeof options === "string" ?
+                    (optionsCache[options] || createOptions(options)) :
+                    jQuery.extend({}, options);
+
+                var // Last fire value (for non-forgettable lists)
+                    memory,
+                    // Flag to know if list was already fired
+                    fired,
+                    // Flag to know if list is currently firing
+                    firing,
+                    // First callback to fire (used internally by add and fireWith)
+                    firingStart,
+                    // End of the loop when firing
+                    firingLength,
+                    // Index of currently firing callback (modified by remove if needed)
+                    firingIndex,
+                    // Actual callback list
+                    list = [],
+                    // Stack of fire calls for repeatable lists
+                    stack = !options.once && [],
+                    // Fire callbacks
+                    fire = function(data) {
+                        memory = options.memory && data;
+                        fired = true;
+                        firingIndex = firingStart || 0;
+                        firingStart = 0;
+                        firingLength = list.length;
+                        firing = true;
+                        for (; list && firingIndex < firingLength; firingIndex++) {
+                            if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
+                                memory = false; // To prevent further calls using add
+                                break;
+                            }
+                        }
+                        firing = false;
+                        if (list) {
+                            if (stack) {
+                                if (stack.length) {
+                                    fire(stack.shift());
+                                }
+                            } else if (memory) {
+                                list = [];
+                            } else {
+                                self.disable();
+                            }
+                        }
+                    },
+                    // Actual Callbacks object
+                    self = {
+                        // Add a callback or a collection of callbacks to the list
+                        add: function() {
+                            if (list) {
+                                // First, we save the current length
+                                var start = list.length;
+                                (function add(args) {
+                                    jQuery.each(args, function(_, arg) {
+                                        var type = jQuery.type(arg);
+                                        if (type === "function") {
+                                            if (!options.unique || !self.has(arg)) {
+                                                list.push(arg);
+                                            }
+                                        } else if (arg && arg.length && type !== "string") {
+                                            // Inspect recursively
+                                            add(arg);
+                                        }
+                                    });
+                                })(arguments);
+                                // Do we need to add the callbacks to the
+                                // current firing batch?
+                                if (firing) {
+                                    firingLength = list.length;
+                                    // With memory, if we're not firing then
+                                    // we should call right away
+                                } else if (memory) {
+                                    firingStart = start;
+                                    fire(memory);
+                                }
+                            }
+                            return this;
+                        },
+                        // Remove a callback from the list
+                        remove: function() {
+                            if (list) {
+                                jQuery.each(arguments, function(_, arg) {
+                                    var index;
+                                    while ((index = jQuery.inArray(arg, list, index)) > -1) {
+                                        list.splice(index, 1);
+                                        // Handle firing indexes
+                                        if (firing) {
+                                            if (index <= firingLength) {
+                                                firingLength--;
+                                            }
+                                            if (index <= firingIndex) {
+                                                firingIndex--;
+                                            }
+                                        }
+                                    }
+                                });
+                            }
+                            return this;
+                        },
+                        // Check if a given callback is in the list.
+                        // If no argument is given, return whether or not list has callbacks
+                        // attached.
+                        has: function(fn) {
+                            return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length);
+                        },
+                        // Remove all callbacks from the list
+                        empty: function() {
+                            list = [];
+                            firingLength = 0;
+                            return this;
+                        },
+                        // Have the list do nothing anymore
+                        disable: function() {
+                            list = stack = memory = undefined;
+                            return this;
+                        },
+                        // Is it disabled?
+                        disabled: function() {
+                            return !list;
+                        },
+                        // Lock the list in its current state
+                        lock: function() {
+                            stack = undefined;
+                            if (!memory) {
+                                self.disable();
+                            }
+                            return this;
+                        },
+                        // Is it locked?
+                        locked: function() {
+                            return !stack;
+                        },
+                        // Call all callbacks with the given context and arguments
+                        fireWith: function(context, args) {
+                            if (list && (!fired || stack)) {
+                                args = args || [];
+                                args = [context, args.slice ? args.slice() : args];
+                                if (firing) {
+                                    stack.push(args);
+                                } else {
+                                    fire(args);
+                                }
+                            }
+                            return this;
+                        },
+                        // Call all the callbacks with the given arguments
+                        fire: function() {
+                            self.fireWith(this, arguments);
+                            return this;
+                        },
+                        // To know if the callbacks have already been called at least once
+                        fired: function() {
+                            return !!fired;
+                        }
+                    };
+
+                return self;
+            };
+
+
+            jQuery.extend({
+
+                Deferred: function(func) {
+                    var tuples = [
+                            // action, add listener, listener list, final state
+                            ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"],
+                            ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"],
+                            ["notify", "progress", jQuery.Callbacks("memory")]
+                        ],
+                        state = "pending",
+                        promise = {
+                            state: function() {
+                                return state;
+                            },
+                            always: function() {
+                                deferred.done(arguments).fail(arguments);
+                                return this;
+                            },
+                            then: function( /* fnDone, fnFail, fnProgress */ ) {
+                                var fns = arguments;
+                                return jQuery.Deferred(function(newDefer) {
+                                    jQuery.each(tuples, function(i, tuple) {
+                                        var fn = jQuery.isFunction(fns[i]) && fns[i];
+                                        // deferred[ done | fail | progress ] for forwarding
+                                        // actions to newDefer
+                                        deferred[tuple[1]](function() {
+                                            var returned = fn && fn.apply(this, arguments);
+                                            if (returned && jQuery.isFunction(returned.promise)) {
+                                                returned.promise()
+                                                    .done(newDefer.resolve)
+                                                    .fail(newDefer.reject)
+                                                    .progress(newDefer.notify);
+                                            } else {
+                                                newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
+                                            }
+                                        });
+                                    });
+                                    fns = null;
+                                }).promise();
+                            },
+                            // Get a promise for this deferred
+                            // If obj is provided, the promise aspect is added to the object
+                            promise: function(obj) {
+                                return obj != null ? jQuery.extend(obj, promise) : promise;
+                            }
+                        },
+                        deferred = {};
+
+                    // Keep pipe for back-compat
+                    promise.pipe = promise.then;
+
+                    // Add list-specific methods
+                    jQuery.each(tuples, function(i, tuple) {
+                        var list = tuple[2],
+                            stateString = tuple[3];
+
+                        // promise[ done | fail | progress ] = list.add
+                        promise[tuple[1]] = list.add;
+
+                        // Handle state
+                        if (stateString) {
+                            list.add(function() {
+                                // state = [ resolved | rejected ]
+                                state = stateString;
+
+                                // [ reject_list | resolve_list ].disable; progress_list.lock
+                            }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
+                        }
+
+                        // deferred[ resolve | reject | notify ]
+                        deferred[tuple[0]] = function() {
+                            deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
+                            return this;
+                        };
+                        deferred[tuple[0] + "With"] = list.fireWith;
+                    });
+
+                    // Make the deferred a promise
+                    promise.promise(deferred);
+
+                    // Call given func if any
+                    if (func) {
+                        func.call(deferred, deferred);
+                    }
+
+                    // All done!
+                    return deferred;
+                },
+
+                // Deferred helper
+                when: function(subordinate /* , ..., subordinateN */ ) {
+                    var i = 0,
+                        resolveValues = slice.call(arguments),
+                        length = resolveValues.length,
+
+                        // the count of uncompleted subordinates
+                        remaining = length !== 1 || (subordinate && jQuery.isFunction(subordinate.promise)) ? length : 0,
+
+                        // the master Deferred. If resolveValues consist of only a single
+                        // Deferred, just use that.
+                        deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+                        // Update function for both resolve and progress values
+                        updateFunc = function(i, contexts, values) {
+                            return function(value) {
+                                contexts[i] = this;
+                                values[i] = arguments.length > 1 ? slice.call(arguments) : value;
+                                if (values === progressValues) {
+                                    deferred.notifyWith(contexts, values);
+                                } else if (!(--remaining)) {
+                                    deferred.resolveWith(contexts, values);
+                                }
+                            };
+                        },
+
+                        progressValues, progressContexts, resolveContexts;
+
+                    // Add listeners to Deferred subordinates; treat others as resolved
+                    if (length > 1) {
+                        progressValues = new Array(length);
+                        progressContexts = new Array(length);
+                        resolveContexts = new Array(length);
+                        for (; i < length; i++) {
+                            if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
+                                resolveValues[i].promise()
+                                    .done(updateFunc(i, resolveContexts, resolveValues))
+                                    .fail(deferred.reject)
+                                    .progress(updateFunc(i, progressContexts, progressValues));
+                            } else {
+                                --remaining;
+                            }
+                        }
+                    }
+
+                    // If we're not waiting on anything, resolve the master
+                    if (!remaining) {
+                        deferred.resolveWith(resolveContexts, resolveValues);
+                    }
+
+                    return deferred.promise();
+                }
+            });
+
+
+            // The deferred used on DOM ready
+            var readyList;
+
+            jQuery.fn.ready = function(fn) {
+                // Add the callback
+                jQuery.ready.promise().done(fn);
+
+                return this;
+            };
+
+            jQuery.extend({
+                // Is the DOM ready to be used? Set to true once it occurs.
+                isReady: false,
+
+                // A counter to track how many items to wait for before
+                // the ready event fires. See #6781
+                readyWait: 1,
+
+                // Hold (or release) the ready event
+                holdReady: function(hold) {
+                    if (hold) {
+                        jQuery.readyWait++;
+                    } else {
+                        jQuery.ready(true);
+                    }
+                },
+
+                // Handle when the DOM is ready
+                ready: function(wait) {
+
+                    // Abort if there are pending holds or we're already ready
+                    if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
+                        return;
+                    }
+
+                    // Remember that the DOM is ready
+                    jQuery.isReady = true;
+
+                    // If a normal DOM Ready event fired, decrement, and wait if need be
+                    if (wait !== true && --jQuery.readyWait > 0) {
+                        return;
+                    }
+
+                    // If there are functions bound, to execute
+                    readyList.resolveWith(document, [jQuery]);
+
+                    // Trigger any bound ready events
+                    if (jQuery.fn.triggerHandler) {
+                        jQuery(document).triggerHandler("ready");
+                        jQuery(document).off("ready");
+                    }
+                }
+            });
+
+            /**
+             * The ready event handler and self cleanup method
+             */
+            function completed() {
+                document.removeEventListener("DOMContentLoaded", completed, false);
+                window.removeEventListener("load", completed, false);
+                jQuery.ready();
+            }
+
+            jQuery.ready.promise = function(obj) {
+                if (!readyList) {
+
+                    readyList = jQuery.Deferred();
+
+                    // Catch cases where $(document).ready() is called after the browser
+                    // event has already occurred.
+                    // We once tried to use readyState "interactive" here, but it caused
+                    // issues like the one
+                    // discovered by ChrisS here:
+                    // http://bugs.jquery.com/ticket/12282#comment:15
+                    if (document.readyState === "complete") {
+                        // Handle it asynchronously to allow scripts the opportunity to
+                        // delay ready
+                        setTimeout(jQuery.ready);
+
+                    } else {
+
+                        // Use the handy event callback
+                        document.addEventListener("DOMContentLoaded", completed, false);
+
+                        // A fallback to window.onload, that will always work
+                        window.addEventListener("load", completed, false);
+                    }
+                }
+                return readyList.promise(obj);
+            };
+
+            // Kick off the DOM ready check even if the user does not
+            jQuery.ready.promise();
+
+
+
+
+            // Multifunctional method to get and set values of a collection
+            // The value/s can optionally be executed if it's a function
+            var access = jQuery.access = function(elems, fn, key, value, chainable, emptyGet, raw) {
+                var i = 0,
+                    len = elems.length,
+                    bulk = key == null;
+
+                // Sets many values
+                if (jQuery.type(key) === "object") {
+                    chainable = true;
+                    for (i in key) {
+                        jQuery.access(elems, fn, i, key[i], true, emptyGet, raw);
+                    }
+
+                    // Sets one value
+                } else if (value !== undefined) {
+                    chainable = true;
+
+                    if (!jQuery.isFunction(value)) {
+                        raw = true;
+                    }
+
+                    if (bulk) {
+                        // Bulk operations run against the entire set
+                        if (raw) {
+                            fn.call(elems, value);
+                            fn = null;
+
+                            // ...except when executing function values
+                        } else {
+                            bulk = fn;
+                            fn = function(elem, key, value) {
+                                return bulk.call(jQuery(elem), value);
+                            };
+                        }
+                    }
+
+                    if (fn) {
+                        for (; i < len; i++) {
+                            fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
+                        }
+                    }
+                }
+
+                return chainable ?
+                    elems :
+
+                    // Gets
+                    bulk ?
+                    fn.call(elems) :
+                    len ? fn(elems[0], key) : emptyGet;
+            };
+
+
+            /**
+             * Determines whether an object can have data
+             */
+            jQuery.acceptData = function(owner) {
+                // Accepts only:
+                // - Node
+                // - Node.ELEMENT_NODE
+                // - Node.DOCUMENT_NODE
+                // - Object
+                // - Any
+                /* jshint -W018 */
+                return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType);
+            };
+
+
+            function Data() {
+                // Support: Android<4,
+                // Old WebKit does not have Object.preventExtensions/freeze method,
+                // return new empty object instead with no [[set]] accessor
+                Object.defineProperty(this.cache = {}, 0, {
+                    get: function() {
+                        return {};
+                    }
+                });
+
+                this.expando = jQuery.expando + Data.uid++;
+            }
+
+            Data.uid = 1;
+            Data.accepts = jQuery.acceptData;
+
+            Data.prototype = {
+                key: function(owner) {
+                    // We can accept data for non-element nodes in modern browsers,
+                    // but we should not, see #8335.
+                    // Always return the key for a frozen object.
+                    if (!Data.accepts(owner)) {
+                        return 0;
+                    }
+
+                    var descriptor = {},
+                        // Check if the owner object already has a cache key
+                        unlock = owner[this.expando];
+
+                    // If not, create one
+                    if (!unlock) {
+                        unlock = Data.uid++;
+
+                        // Secure it in a non-enumerable, non-writable property
+                        try {
+                            descriptor[this.expando] = {
+                                value: unlock
+                            };
+                            Object.defineProperties(owner, descriptor);
+
+                            // Support: Android<4
+                            // Fallback to a less secure definition
+                        } catch (e) {
+                            descriptor[this.expando] = unlock;
+                            jQuery.extend(owner, descriptor);
+                        }
+                    }
+
+                    // Ensure the cache object
+                    if (!this.cache[unlock]) {
+                        this.cache[unlock] = {};
+                    }
+
+                    return unlock;
+                },
+                set: function(owner, data, value) {
+                    var prop,
+                        // There may be an unlock assigned to this node,
+                        // if there is no entry for this "owner", create one inline
+                        // and set the unlock as though an owner entry had always existed
+                        unlock = this.key(owner),
+                        cache = this.cache[unlock];
+
+                    // Handle: [ owner, key, value ] args
+                    if (typeof data === "string") {
+                        cache[data] = value;
+
+                        // Handle: [ owner, { properties } ] args
+                    } else {
+                        // Fresh assignments by object are shallow copied
+                        if (jQuery.isEmptyObject(cache)) {
+                            jQuery.extend(this.cache[unlock], data);
+                            // Otherwise, copy the properties one-by-one to the cache object
+                        } else {
+                            for (prop in data) {
+                                cache[prop] = data[prop];
+                            }
+                        }
+                    }
+                    return cache;
+                },
+                get: function(owner, key) {
+                    // Either a valid cache is found, or will be created.
+                    // New caches will be created and the unlock returned,
+                    // allowing direct access to the newly created
+                    // empty data object. A valid owner object must be provided.
+                    var cache = this.cache[this.key(owner)];
+
+                    return key === undefined ?
+                        cache : cache[key];
+                },
+                access: function(owner, key, value) {
+                    var stored;
+                    // In cases where either:
+                    //
+                    // 1. No key was specified
+                    // 2. A string key was specified, but no value provided
+                    //
+                    // Take the "read" path and allow the get method to determine
+                    // which value to return, respectively either:
+                    //
+                    // 1. The entire cache object
+                    // 2. The data stored at the key
+                    //
+                    if (key === undefined ||
+                        ((key && typeof key === "string") && value === undefined)) {
+
+                        stored = this.get(owner, key);
+
+                        return stored !== undefined ?
+                            stored : this.get(owner, jQuery.camelCase(key));
+                    }
+
+                    // [*]When the key is not a string, or both a key and value
+                    // are specified, set or extend (existing objects) with either:
+                    //
+                    // 1. An object of properties
+                    // 2. A key and value
+                    //
+                    this.set(owner, key, value);
+
+                    // Since the "set" path can have two possible entry points
+                    // return the expected data based on which path was taken[*]
+                    return value !== undefined ? value : key;
+                },
+                remove: function(owner, key) {
+                    var i, name, camel,
+                        unlock = this.key(owner),
+                        cache = this.cache[unlock];
+
+                    if (key === undefined) {
+                        this.cache[unlock] = {};
+
+                    } else {
+                        // Support array or space separated string of keys
+                        if (jQuery.isArray(key)) {
+                            // If "name" is an array of keys...
+                            // When data is initially created, via ("key", "val") signature,
+                            // keys will be converted to camelCase.
+                            // Since there is no way to tell _how_ a key was added, remove
+                            // both plain key and camelCase key. #12786
+                            // This will only penalize the array argument path.
+                            name = key.concat(key.map(jQuery.camelCase));
+                        } else {
+                            camel = jQuery.camelCase(key);
+                            // Try the string as a key before any manipulation
+                            if (key in cache) {
+                                name = [key, camel];
+                            } else {
+                                // If a key with the spaces exists, use it.
+                                // Otherwise, create an array by matching non-whitespace
+                                name = camel;
+                                name = name in cache ? [name] : (name.match(rnotwhite) || []);
+                            }
+                        }
+
+                        i = name.length;
+                        while (i--) {
+                            delete cache[name[i]];
+                        }
+                    }
+                },
+                hasData: function(owner) {
+                    return !jQuery.isEmptyObject(
+                        this.cache[owner[this.expando]] || {}
+                    );
+                },
+                discard: function(owner) {
+                    if (owner[this.expando]) {
+                        delete this.cache[owner[this.expando]];
+                    }
+                }
+            };
+            var data_priv = new Data();
+
+            var data_user = new Data();
+
+
+
+            // Implementation Summary
+            //
+            // 1. Enforce API surface and semantic compatibility with 1.9.x branch
+            // 2. Improve the module's maintainability by reducing the storage
+            // paths to a single mechanism.
+            // 3. Use the same single mechanism to support "private" and "user" data.
+            // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+            // 5. Avoid exposing implementation details on user objects (eg. expando
+            // properties)
+            // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+            var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+                rmultiDash = /([A-Z])/g;
+
+            function dataAttr(elem, key, data) {
+                var name;
+
+                // If nothing was found internally, try to fetch any
+                // data from the HTML5 data-* attribute
+                if (data === undefined && elem.nodeType === 1) {
+                    name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
+                    data = elem.getAttribute(name);
+
+                    if (typeof data === "string") {
+                        try {
+                            data = data === "true" ? true :
+                                data === "false" ? false :
+                                data === "null" ? null :
+                                // Only convert to a number if it doesn't change the string
+                                +data + "" === data ? +data :
+                                rbrace.test(data) ? jQuery.parseJSON(data) :
+                                data;
+                        } catch (e) {}
+
+                        // Make sure we set the data so it isn't changed later
+                        data_user.set(elem, key, data);
+                    } else {
+                        data = undefined;
+                    }
+                }
+                return data;
+            }
+
+            jQuery.extend({
+                hasData: function(elem) {
+                    return data_user.hasData(elem) || data_priv.hasData(elem);
+                },
+
+                data: function(elem, name, data) {
+                    return data_user.access(elem, name, data);
+                },
+
+                removeData: function(elem, name) {
+                    data_user.remove(elem, name);
+                },
+
+                // TODO: Now that all calls to _data and _removeData have been replaced
+                // with direct calls to data_priv methods, these can be deprecated.
+                _data: function(elem, name, data) {
+                    return data_priv.access(elem, name, data);
+                },
+
+                _removeData: function(elem, name) {
+                    data_priv.remove(elem, name);
+                }
+            });
+
+            jQuery.fn.extend({
+                data: function(key, value) {
+                    var i, name, data,
+                        elem = this[0],
+                        attrs = elem && elem.attributes;
+
+                    // Gets all values
+                    if (key === undefined) {
+                        if (this.length) {
+                            data = data_user.get(elem);
+
+                            if (elem.nodeType === 1 && !data_priv.get(elem, "hasDataAttrs")) {
+                                i = attrs.length;
+                                while (i--) {
+
+                                    // Support: IE11+
+                                    // The attrs elements can be null (#14894)
+                                    if (attrs[i]) {
+                                        name = attrs[i].name;
+                                        if (name.indexOf("data-") === 0) {
+                                            name = jQuery.camelCase(name.slice(5));
+                                            dataAttr(elem, name, data[name]);
+                                        }
+                                    }
+                                }
+                                data_priv.set(elem, "hasDataAttrs", true);
+                            }
+                        }
+
+                        return data;
+                    }
+
+                    // Sets multiple values
+                    if (typeof key === "object") {
+                        return this.each(function() {
+                            data_user.set(this, key);
+                        });
+                    }
+
+                    return access(this, function(value) {
+                        var data,
+                            camelKey = jQuery.camelCase(key);
+
+                        // The calling jQuery object (element matches) is not empty
+                        // (and therefore has an element appears at this[ 0 ]) and the
+                        // `value` parameter was not undefined. An empty jQuery object
+                        // will result in `undefined` for elem = this[ 0 ] which will
+                        // throw an exception if an attempt to read a data cache is made.
+                        if (elem && value === undefined) {
+                            // Attempt to get data from the cache
+                            // with the key as-is
+                            data = data_user.get(elem, key);
+                            if (data !== undefined) {
+                                return data;
+                            }
+
+                            // Attempt to get data from the cache
+                            // with the key camelized
+                            data = data_user.get(elem, camelKey);
+                            if (data !== undefined) {
+                                return data;
+                            }
+
+                            // Attempt to "discover" the data in
+                            // HTML5 custom data-* attrs
+                            data = dataAttr(elem, camelKey, undefined);
+                            if (data !== undefined) {
+                                return data;
+                            }
+
+                            // We tried really hard, but the data doesn't exist.
+                            return;
+                        }
+
+                        // Set the data...
+                        this.each(function() {
+                            // First, attempt to store a copy or reference of any
+                            // data that might've been store with a camelCased key.
+                            var data = data_user.get(this, camelKey);
+
+                            // For HTML5 data-* attribute interop, we have to
+                            // store property names with dashes in a camelCase form.
+                            // This might not apply to all properties...*
+                            data_user.set(this, camelKey, value);
+
+                            // *... In the case of properties that might _actually_
+                            // have dashes, we need to also store a copy of that
+                            // unchanged property.
+                            if (key.indexOf("-") !== -1 && data !== undefined) {
+                                data_user.set(this, key, value);
+                            }
+                        });
+                    }, null, value, arguments.length > 1, null, true);
+                },
+
+                removeData: function(key) {
+                    return this.each(function() {
+                        data_user.remove(this, key);
+                    });
+                }
+            });
+
+
+            jQuery.extend({
+                queue: function(elem, type, data) {
+                    var queue;
+
+                    if (elem) {
+                        type = (type || "fx") + "queue";
+                        queue = data_priv.get(elem, type);
+
+                        // Speed up dequeue by getting out quickly if this is just a lookup
+                        if (data) {
+                            if (!queue || jQuery.isArray(data)) {
+                                queue = data_priv.access(elem, type, jQuery.makeArray(data));
+                            } else {
+                                queue.push(data);
+                            }
+                        }
+                        return queue || [];
+                    }
+                },
+
+                dequeue: function(elem, type) {
+                    type = type || "fx";
+
+                    var queue = jQuery.queue(elem, type),
+                        startLength = queue.length,
+                        fn = queue.shift(),
+                        hooks = jQuery._queueHooks(elem, type),
+                        next = function() {
+                            jQuery.dequeue(elem, type);
+                        };
+
+                    // If the fx queue is dequeued, always remove the progress sentinel
+                    if (fn === "inprogress") {
+                        fn = queue.shift();
+                        startLength--;
+                    }
+
+                    if (fn) {
+
+                        // Add a progress sentinel to prevent the fx queue from being
+                        // automatically dequeued
+                        if (type === "fx") {
+                            queue.unshift("inprogress");
+                        }
+
+                        // Clear up the last queue stop function
+                        delete hooks.stop;
+                        fn.call(elem, next, hooks);
+                    }
+
+                    if (!startLength && hooks) {
+                        hooks.empty.fire();
+                    }
+                },
+
+                // Not public - generate a queueHooks object, or return the current one
+                _queueHooks: function(elem, type) {
+                    var key = type + "queueHooks";
+                    return data_priv.get(elem, key) || data_priv.access(elem, key, {
+                        empty: jQuery.Callbacks("once memory").add(function() {
+                            data_priv.remove(elem, [type + "queue", key]);
+                        })
+                    });
+                }
+            });
+
+            jQuery.fn.extend({
+                queue: function(type, data) {
+                    var setter = 2;
+
+                    if (typeof type !== "string") {
+                        data = type;
+                        type = "fx";
+                        setter--;
+                    }
+
+                    if (arguments.length < setter) {
+                        return jQuery.queue(this[0], type);
+                    }
+
+                    return data === undefined ?
+                        this :
+                        this.each(function() {
+                            var queue = jQuery.queue(this, type, data);
+
+                            // Ensure a hooks for this queue
+                            jQuery._queueHooks(this, type);
+
+                            if (type === "fx" && queue[0] !== "inprogress") {
+                                jQuery.dequeue(this, type);
+                            }
+                        });
+                },
+                dequeue: function(type) {
+                    return this.each(function() {
+                        jQuery.dequeue(this, type);
+                    });
+                },
+                clearQueue: function(type) {
+                    return this.queue(type || "fx", []);
+                },
+                // Get a promise resolved when queues of a certain type
+                // are emptied (fx is the type by default)
+                promise: function(type, obj) {
+                    var tmp,
+                        count = 1,
+                        defer = jQuery.Deferred(),
+                        elements = this,
+                        i = this.length,
+                        resolve = function() {
+                            if (!(--count)) {
+                                defer.resolveWith(elements, [elements]);
+                            }
+                        };
+
+                    if (typeof type !== "string") {
+                        obj = type;
+                        type = undefined;
+                    }
+                    type = type || "fx";
+
+                    while (i--) {
+                        tmp = data_priv.get(elements[i], type + "queueHooks");
+                        if (tmp && tmp.empty) {
+                            count++;
+                            tmp.empty.add(resolve);
+                        }
+                    }
+                    resolve();
+                    return defer.promise(obj);
+                }
+            });
+            var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+
+            var cssExpand = ["Top", "Right", "Bottom", "Left"];
+
+            var isHidden = function(elem, el) {
+                // isHidden might be called from jQuery#filter function;
+                // in that case, element will be second argument
+                elem = el || elem;
+                return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem);
+            };
+
+            var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+
+
+            (function() {
+                var fragment = document.createDocumentFragment(),
+                    div = fragment.appendChild(document.createElement("div")),
+                    input = document.createElement("input");
+
+                // Support: Safari<=5.1
+                // Check state lost if the name is set (#11217)
+                // Support: Windows Web Apps (WWA)
+                // `name` and `type` must use .setAttribute for WWA (#14901)
+                input.setAttribute("type", "radio");
+                input.setAttribute("checked", "checked");
+                input.setAttribute("name", "t");
+
+                div.appendChild(input);
+
+                // Support: Safari<=5.1, Android<4.2
+                // Older WebKit doesn't clone checked state correctly in fragments
+                support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
+
+                // Support: IE<=11+
+                // Make sure textarea (and checkbox) defaultValue is properly cloned
+                div.innerHTML = "<textarea>x</textarea>";
+                support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
+            })();
+            var strundefined = typeof undefined;
+
+
+
+            support.focusinBubbles = "onfocusin" in window;
+
+
+            var
+                rkeyEvent = /^key/,
+                rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
+                rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+                rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+            function returnTrue() {
+                return true;
+            }
+
+            function returnFalse() {
+                return false;
+            }
+
+            function safeActiveElement() {
+                try {
+                    return document.activeElement;
+                } catch (err) {}
+            }
+
+            /*
+             * Helper functions for managing events -- not part of the public interface.
+             * Props to Dean Edwards' addEvent library for many of the ideas.
+             */
+            jQuery.event = {
+
+                global: {},
+
+                add: function(elem, types, handler, data, selector) {
+
+                    var handleObjIn, eventHandle, tmp,
+                        events, t, handleObj,
+                        special, handlers, type, namespaces, origType,
+                        elemData = data_priv.get(elem);
+
+                    // Don't attach events to noData or text/comment nodes (but allow plain
+                    // objects)
+                    if (!elemData) {
+                        return;
+                    }
+
+                    // Caller can pass in an object of custom data in lieu of the handler
+                    if (handler.handler) {
+                        handleObjIn = handler;
+                        handler = handleObjIn.handler;
+                        selector = handleObjIn.selector;
+                    }
+
+                    // Make sure that the handler has a unique ID, used to find/remove it
+                    // later
+                    if (!handler.guid) {
+                        handler.guid = jQuery.guid++;
+                    }
+
+                    // Init the element's event structure and main handler, if this is the
+                    // first
+                    if (!(events = elemData.events)) {
+                        events = elemData.events = {};
+                    }
+                    if (!(eventHandle = elemData.handle)) {
+                        eventHandle = elemData.handle = function(e) {
+                            // Discard the second event of a jQuery.event.trigger() and
+                            // when an event is called after a page has unloaded
+                            return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
+                                jQuery.event.dispatch.apply(elem, arguments) : undefined;
+                        };
+                    }
+
+                    // Handle multiple events separated by a space
+                    types = (types || "").match(rnotwhite) || [""];
+                    t = types.length;
+                    while (t--) {
+                        tmp = rtypenamespace.exec(types[t]) || [];
+                        type = origType = tmp[1];
+                        namespaces = (tmp[2] || "").split(".").sort();
+
+                        // There *must* be a type, no attaching namespace-only handlers
+                        if (!type) {
+                            continue;
+                        }
+
+                        // If event changes its type, use the special event handlers for the
+                        // changed type
+                        special = jQuery.event.special[type] || {};
+
+                        // If selector defined, determine special event api type, otherwise
+                        // given type
+                        type = (selector ? special.delegateType : special.bindType) || type;
+
+                        // Update special based on newly reset type
+                        special = jQuery.event.special[type] || {};
+
+                        // handleObj is passed to all event handlers
+                        handleObj = jQuery.extend({
+                            type: type,
+                            origType: origType,
+                            data: data,
+                            handler: handler,
+                            guid: handler.guid,
+                            selector: selector,
+                            needsContext: selector && jQuery.expr.match.needsContext.test(selector),
+                            namespace: namespaces.join(".")
+                        }, handleObjIn);
+
+                        // Init the event handler queue if we're the first
+                        if (!(handlers = events[type])) {
+                            handlers = events[type] = [];
+                            handlers.delegateCount = 0;
+
+                            // Only use addEventListener if the special events handler
+                            // returns false
+                            if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
+                                if (elem.addEventListener) {
+                                    elem.addEventListener(type, eventHandle, false);
+                                }
+                            }
+                        }
+
+                        if (special.add) {
+                            special.add.call(elem, handleObj);
+
+                            if (!handleObj.handler.guid) {
+                                handleObj.handler.guid = handler.guid;
+                            }
+                        }
+
+                        // Add to the element's handler list, delegates in front
+                        if (selector) {
+                            handlers.splice(handlers.delegateCount++, 0, handleObj);
+                        } else {
+                            handlers.push(handleObj);
+                        }
+
+                        // Keep track of which events have ever been used, for event
+                        // optimization
+                        jQuery.event.global[type] = true;
+                    }
+
+                },
+
+                // Detach an event or set of events from an element
+                remove: function(elem, types, handler, selector, mappedTypes) {
+
+                    var j, origCount, tmp,
+                        events, t, handleObj,
+                        special, handlers, type, namespaces, origType,
+                        elemData = data_priv.hasData(elem) && data_priv.get(elem);
+
+                    if (!elemData || !(events = elemData.events)) {
+                        return;
+                    }
+
+                    // Once for each type.namespace in types; type may be omitted
+                    types = (types || "").match(rnotwhite) || [""];
+                    t = types.length;
+                    while (t--) {
+                        tmp = rtypenamespace.exec(types[t]) || [];
+                        type = origType = tmp[1];
+                        namespaces = (tmp[2] || "").split(".").sort();
+
+                        // Unbind all events (on this namespace, if provided) for the
+                        // element
+                        if (!type) {
+                            for (type in events) {
+                                jQuery.event.remove(elem, type + types[t], handler, selector, true);
+                            }
+                            continue;
+                        }
+
+                        special = jQuery.event.special[type] || {};
+                        type = (selector ? special.delegateType : special.bindType) || type;
+                        handlers = events[type] || [];
+                        tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
+
+                        // Remove matching events
+                        origCount = j = handlers.length;
+                        while (j--) {
+                            handleObj = handlers[j];
+
+                            if ((mappedTypes || origType === handleObj.origType) &&
+                                (!handler || handler.guid === handleObj.guid) &&
+                                (!tmp || tmp.test(handleObj.namespace)) &&
+                                (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
+                                handlers.splice(j, 1);
+
+                                if (handleObj.selector) {
+                                    handlers.delegateCount--;
+                                }
+                                if (special.remove) {
+                                    special.remove.call(elem, handleObj);
+                                }
+                            }
+                        }
+
+                        // Remove generic event handler if we removed something and no more
+                        // handlers exist
+                        // (avoids potential for endless recursion during removal of special
+                        // event handlers)
+                        if (origCount && !handlers.length) {
+                            if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
+                                jQuery.removeEvent(elem, type, elemData.handle);
+                            }
+
+                            delete events[type];
+                        }
+                    }
+
+                    // Remove the expando if it's no longer used
+                    if (jQuery.isEmptyObject(events)) {
+                        delete elemData.handle;
+                        data_priv.remove(elem, "events");
+                    }
+                },
+
+                trigger: function(event, data, elem, onlyHandlers) {
+
+                    var i, cur, tmp, bubbleType, ontype, handle, special,
+                        eventPath = [elem || document],
+                        type = hasOwn.call(event, "type") ? event.type : event,
+                        namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
+
+                    cur = tmp = elem = elem || document;
+
+                    // Don't do events on text and comment nodes
+                    if (elem.nodeType === 3 || elem.nodeType === 8) {
+                        return;
+                    }
+
+                    // focus/blur morphs to focusin/out; ensure we're not firing them right
+                    // now
+                    if (rfocusMorph.test(type + jQuery.event.triggered)) {
+                        return;
+                    }
+
+                    if (type.indexOf(".") >= 0) {
+                        // Namespaced trigger; create a regexp to match event type in
+                        // handle()
+                        namespaces = type.split(".");
+                        type = namespaces.shift();
+                        namespaces.sort();
+                    }
+                    ontype = type.indexOf(":") < 0 && "on" + type;
+
+                    // Caller can pass in a jQuery.Event object, Object, or just an event
+                    // type string
+                    event = event[jQuery.expando] ?
+                        event :
+                        new jQuery.Event(type, typeof event === "object" && event);
+
+                    // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always
+                    // true)
+                    event.isTrigger = onlyHandlers ? 2 : 3;
+                    event.namespace = namespaces.join(".");
+                    event.namespace_re = event.namespace ?
+                        new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
+                        null;
+
+                    // Clean up the event in case it is being reused
+                    event.result = undefined;
+                    if (!event.target) {
+                        event.target = elem;
+                    }
+
+                    // Clone any incoming data and prepend the event, creating the handler
+                    // arg list
+                    data = data == null ? [event] :
+                        jQuery.makeArray(data, [event]);
+
+                    // Allow special events to draw outside the lines
+                    special = jQuery.event.special[type] || {};
+                    if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
+                        return;
+                    }
+
+                    // Determine event propagation path in advance, per W3C events spec
+                    // (#9951)
+                    // Bubble up to document, then to window; watch for a global
+                    // ownerDocument var (#9724)
+                    if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
+
+                        bubbleType = special.delegateType || type;
+                        if (!rfocusMorph.test(bubbleType + type)) {
+                            cur = cur.parentNode;
+                        }
+                        for (; cur; cur = cur.parentNode) {
+                            eventPath.push(cur);
+                            tmp = cur;
+                        }
+
+                        // Only add window if we got to document (e.g., not plain obj or
+                        // detached DOM)
+                        if (tmp === (elem.ownerDocument || document)) {
+                            eventPath.push(tmp.defaultView || tmp.parentWindow || window);
+                        }
+                    }
+
+                    // Fire handlers on the event path
+                    i = 0;
+                    while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
+
+                        event.type = i > 1 ?
+                            bubbleType :
+                            special.bindType || type;
+
+                        // jQuery handler
+                        handle = (data_priv.get(cur, "events") || {})[event.type] && data_priv.get(cur, "handle");
+                        if (handle) {
+                            handle.apply(cur, data);
+                        }
+
+                        // Native handler
+                        handle = ontype && cur[ontype];
+                        if (handle && handle.apply && jQuery.acceptData(cur)) {
+                            event.result = handle.apply(cur, data);
+                            if (event.result === false) {
+                                event.preventDefault();
+                            }
+                        }
+                    }
+                    event.type = type;
+
+                    // If nobody prevented the default action, do it now
+                    if (!onlyHandlers && !event.isDefaultPrevented()) {
+
+                        if ((!special._default || special._default.apply(eventPath.pop(), data) === false) &&
+                            jQuery.acceptData(elem)) {
+
+                            // Call a native DOM method on the target with the same name
+                            // name as the event.
+                            // Don't do default actions on window, that's where global
+                            // variables be (#6170)
+                            if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {
+
+                                // Don't re-trigger an onFOO event when we call its FOO()
+                                // method
+                                tmp = elem[ontype];
+
+                                if (tmp) {
+                                    elem[ontype] = null;
+                                }
+
+                                // Prevent re-triggering of the same event, since we already
+                                // bubbled it above
+                                jQuery.event.triggered = type;
+                                elem[type]();
+                                jQuery.event.triggered = undefined;
+
+                                if (tmp) {
+                                    elem[ontype] = tmp;
+                                }
+                            }
+                        }
+                    }
+
+                    return event.result;
+                },
+
+                dispatch: function(event) {
+
+                    // Make a writable jQuery.Event from the native event object
+                    event = jQuery.event.fix(event);
+
+                    var i, j, ret, matched, handleObj,
+                        handlerQueue = [],
+                        args = slice.call(arguments),
+                        handlers = (data_priv.get(this, "events") || {})[event.type] || [],
+                        special = jQuery.event.special[event.type] || {};
+
+                    // Use the fix-ed jQuery.Event rather than the (read-only) native event
+                    args[0] = event;
+                    event.delegateTarget = this;
+
+                    // Call the preDispatch hook for the mapped type, and let it bail if
+                    // desired
+                    if (special.preDispatch && special.preDispatch.call(this, event) === false) {
+                        return;
+                    }
+
+                    // Determine handlers
+                    handlerQueue = jQuery.event.handlers.call(this, event, handlers);
+
+                    // Run delegates first; they may want to stop propagation beneath us
+                    i = 0;
+                    while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
+                        event.currentTarget = matched.elem;
+
+                        j = 0;
+                        while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
+
+                            // Triggered event must either 1) have no namespace, or 2) have
+                            // namespace(s)
+                            // a subset or equal to those in the bound event (both can have
+                            // no namespace).
+                            if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
+
+                                event.handleObj = handleObj;
+                                event.data = handleObj.data;
+
+                                ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
+                                    .apply(matched.elem, args);
+
+                                if (ret !== undefined) {
+                                    if ((event.result = ret) === false) {
+                                        event.preventDefault();
+                                        event.stopPropagation();
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    // Call the postDispatch hook for the mapped type
+                    if (special.postDispatch) {
+                        special.postDispatch.call(this, event);
+                    }
+
+                    return event.result;
+                },
+
+                handlers: function(event, handlers) {
+                    var i, matches, sel, handleObj,
+                        handlerQueue = [],
+                        delegateCount = handlers.delegateCount,
+                        cur = event.target;
+
+                    // Find delegate handlers
+                    // Black-hole SVG <use> instance trees (#13180)
+                    // Avoid non-left-click bubbling in Firefox (#3861)
+                    if (delegateCount && cur.nodeType && (!event.button || event.type !== "click")) {
+
+                        for (; cur !== this; cur = cur.parentNode || this) {
+
+                            // Don't process clicks on disabled elements (#6911, #8165,
+                            // #11382, #11764)
+                            if (cur.disabled !== true || event.type !== "click") {
+                                matches = [];
+                                for (i = 0; i < delegateCount; i++) {
+                                    handleObj = handlers[i];
+
+                                    // Don't conflict with Object.prototype properties
+                                    // (#13203)
+                                    sel = handleObj.selector + " ";
+
+                                    if (matches[sel] === undefined) {
+                                        matches[sel] = handleObj.needsContext ?
+                                            jQuery(sel, this).index(cur) >= 0 :
+                                            jQuery.find(sel, this, null, [cur]).length;
+                                    }
+                                    if (matches[sel]) {
+                                        matches.push(handleObj);
+                                    }
+                                }
+                                if (matches.length) {
+                                    handlerQueue.push({
+                                        elem: cur,
+                                        handlers: matches
+                                    });
+                                }
+                            }
+                        }
+                    }
+
+                    // Add the remaining (directly-bound) handlers
+                    if (delegateCount < handlers.length) {
+                        handlerQueue.push({
+                            elem: this,
+                            handlers: handlers.slice(delegateCount)
+                        });
+                    }
+
+                    return handlerQueue;
+                },
+
+                // Includes some event props shared by KeyEvent and MouseEvent
+                props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+                fixHooks: {},
+
+                keyHooks: {
+                    props: "char charCode key keyCode".split(" "),
+                    filter: function(event, original) {
+
+                        // Add which for key events
+                        if (event.which == null) {
+                            event.which = original.charCode != null ? original.charCode : original.keyCode;
+                        }
+
+                        return event;
+                    }
+                },
+
+                mouseHooks: {
+                    props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+                    filter: function(event, original) {
+                        var eventDoc, doc, body,
+                            button = original.button;
+
+                        // Calculate pageX/Y if missing and clientX/Y available
+                        if (event.pageX == null && original.clientX != null) {
+                            eventDoc = event.target.ownerDocument || document;
+                            doc = eventDoc.documentElement;
+                            body = eventDoc.body;
+
+                            event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+                            event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+                        }
+
+                        // Add which for click: 1 === left; 2 === middle; 3 === right
+                        // Note: button is not normalized, so don't use it
+                        if (!event.which && button !== undefined) {
+                            event.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
+                        }
+
+                        return event;
+                    }
+                },
+
+                fix: function(event) {
+                    if (event[jQuery.expando]) {
+                        return event;
+                    }
+
+                    // Create a writable copy of the event object and normalize some
+                    // properties
+                    var i, prop, copy,
+                        type = event.type,
+                        originalEvent = event,
+                        fixHook = this.fixHooks[type];
+
+                    if (!fixHook) {
+                        this.fixHooks[type] = fixHook =
+                            rmouseEvent.test(type) ? this.mouseHooks :
+                            rkeyEvent.test(type) ? this.keyHooks : {};
+                    }
+                    copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
+
+                    event = new jQuery.Event(originalEvent);
+
+                    i = copy.length;
+                    while (i--) {
+                        prop = copy[i];
+                        event[prop] = originalEvent[prop];
+                    }
+
+                    // Support: Cordova 2.5 (WebKit) (#13255)
+                    // All events should have a target; Cordova deviceready doesn't
+                    if (!event.target) {
+                        event.target = document;
+                    }
+
+                    // Support: Safari 6.0+, Chrome<28
+                    // Target should not be a text node (#504, #13143)
+                    if (event.target.nodeType === 3) {
+                        event.target = event.target.parentNode;
+                    }
+
+                    return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
+                },
+
+                special: {
+                    load: {
+                        // Prevent triggered image.load events from bubbling to window.load
+                        noBubble: true
+                    },
+                    focus: {
+                        // Fire native event if possible so blur/focus sequence is correct
+                        trigger: function() {
+                            if (this !== safeActiveElement() && this.focus) {
+                                this.focus();
+                                return false;
+                            }
+                        },
+                        delegateType: "focusin"
+                    },
+                    blur: {
+                        trigger: function() {
+                            if (this === safeActiveElement() && this.blur) {
+                                this.blur();
+                                return false;
+                            }
+                        },
+                        delegateType: "focusout"
+                    },
+                    click: {
+                        // For checkbox, fire native event so checked state will be right
+                        trigger: function() {
+                            if (this.type === "checkbox" && this.click && jQuery.nodeName(this, "input")) {
+                                this.click();
+                                return false;
+                            }
+                        },
+
+                        // For cross-browser consistency, don't fire native .click() on
+                        // links
+                        _default: function(event) {
+                            return jQuery.nodeName(event.target, "a");
+                        }
+                    },
+
+                    beforeunload: {
+                        postDispatch: function(event) {
+
+                            // Support: Firefox 20+
+                            // Firefox doesn't alert if the returnValue field is not set.
+                            if (event.result !== undefined && event.originalEvent) {
+                                event.originalEvent.returnValue = event.result;
+                            }
+                        }
+                    }
+                },
+
+                simulate: function(type, elem, event, bubble) {
+                    // Piggyback on a donor event to simulate a different one.
+                    // Fake originalEvent to avoid donor's stopPropagation, but if the
+                    // simulated event prevents default then we do the same on the donor.
+                    var e = jQuery.extend(
+                        new jQuery.Event(),
+                        event, {
+                            type: type,
+                            isSimulated: true,
+                            originalEvent: {}
+                        }
+                    );
+                    if (bubble) {
+                        jQuery.event.trigger(e, null, elem);
+                    } else {
+                        jQuery.event.dispatch.call(elem, e);
+                    }
+                    if (e.isDefaultPrevented()) {
+                        event.preventDefault();
+                    }
+                }
+            };
+
+            jQuery.removeEvent = function(elem, type, handle) {
+                if (elem.removeEventListener) {
+                    elem.removeEventListener(type, handle, false);
+                }
+            };
+
+            jQuery.Event = function(src, props) {
+                // Allow instantiation without the 'new' keyword
+                if (!(this instanceof jQuery.Event)) {
+                    return new jQuery.Event(src, props);
+                }
+
+                // Event object
+                if (src && src.type) {
+                    this.originalEvent = src;
+                    this.type = src.type;
+
+                    // Events bubbling up the document may have been marked as prevented
+                    // by a handler lower down the tree; reflect the correct value.
+                    this.isDefaultPrevented = src.defaultPrevented ||
+                        src.defaultPrevented === undefined &&
+                        // Support: Android<4.0
+                        src.returnValue === false ?
+                        returnTrue :
+                        returnFalse;
+
+                    // Event type
+                } else {
+                    this.type = src;
+                }
+
+                // Put explicitly provided properties onto the event object
+                if (props) {
+                    jQuery.extend(this, props);
+                }
+
+                // Create a timestamp if incoming event doesn't have one
+                this.timeStamp = src && src.timeStamp || jQuery.now();
+
+                // Mark it as fixed
+                this[jQuery.expando] = true;
+            };
+
+            // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language
+            // Binding
+            // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+            jQuery.Event.prototype = {
+                isDefaultPrevented: returnFalse,
+                isPropagationStopped: returnFalse,
+                isImmediatePropagationStopped: returnFalse,
+
+                preventDefault: function() {
+                    var e = this.originalEvent;
+
+                    this.isDefaultPrevented = returnTrue;
+
+                    if (e && e.preventDefault) {
+                        e.preventDefault();
+                    }
+                },
+                stopPropagation: function() {
+                    var e = this.originalEvent;
+
+                    this.isPropagationStopped = returnTrue;
+
+                    if (e && e.stopPropagation) {
+                        e.stopPropagation();
+                    }
+                },
+                stopImmediatePropagation: function() {
+                    var e = this.originalEvent;
+
+                    this.isImmediatePropagationStopped = returnTrue;
+
+                    if (e && e.stopImmediatePropagation) {
+                        e.stopImmediatePropagation();
+                    }
+
+                    this.stopPropagation();
+                }
+            };
+
+            // Create mouseenter/leave events using mouseover/out and event-time checks
+            // Support: Chrome 15+
+            jQuery.each({
+                mouseenter: "mouseover",
+                mouseleave: "mouseout",
+                pointerenter: "pointerover",
+                pointerleave: "pointerout"
+            }, function(orig, fix) {
+                jQuery.event.special[orig] = {
+                    delegateType: fix,
+                    bindType: fix,
+
+                    handle: function(event) {
+                        var ret,
+                            target = this,
+                            related = event.relatedTarget,
+                            handleObj = event.handleObj;
+
+                        // For mousenter/leave call the handler if related is outside the
+                        // target.
+                        // NB: No relatedTarget if the mouse left/entered the browser window
+                        if (!related || (related !== target && !jQuery.contains(target, related))) {
+                            event.type = handleObj.origType;
+                            ret = handleObj.handler.apply(this, arguments);
+                            event.type = fix;
+                        }
+                        return ret;
+                    }
+                };
+            });
+
+            // Support: Firefox, Chrome, Safari
+            // Create "bubbling" focus and blur events
+            if (!support.focusinBubbles) {
+                jQuery.each({
+                    focus: "focusin",
+                    blur: "focusout"
+                }, function(orig, fix) {
+
+                    // Attach a single capturing handler on the document while someone wants
+                    // focusin/focusout
+                    var handler = function(event) {
+                        jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);
+                    };
+
+                    jQuery.event.special[fix] = {
+                        setup: function() {
+                            var doc = this.ownerDocument || this,
+                                attaches = data_priv.access(doc, fix);
+
+                            if (!attaches) {
+                                doc.addEventListener(orig, handler, true);
+                            }
+                            data_priv.access(doc, fix, (attaches || 0) + 1);
+                        },
+                        teardown: function() {
+                            var doc = this.ownerDocument || this,
+                                attaches = data_priv.access(doc, fix) - 1;
+
+                            if (!attaches) {
+                                doc.removeEventListener(orig, handler, true);
+                                data_priv.remove(doc, fix);
+
+                            } else {
+                                data_priv.access(doc, fix, attaches);
+                            }
+                        }
+                    };
+                });
+            }
+
+            jQuery.fn.extend({
+
+                on: function(types, selector, data, fn, /* INTERNAL */ one) {
+                    var origFn, type;
+
+                    // Types can be a map of types/handlers
+                    if (typeof types === "object") {
+                        // ( types-Object, selector, data )
+                        if (typeof selector !== "string") {
+                            // ( types-Object, data )
+                            data = data || selector;
+                            selector = undefined;
+                        }
+                        for (type in types) {
+                            this.on(type, selector, data, types[type], one);
+                        }
+                        return this;
+                    }
+
+                    if (data == null && fn == null) {
+                        // ( types, fn )
+                        fn = selector;
+                        data = selector = undefined;
+                    } else if (fn == null) {
+                        if (typeof selector === "string") {
+                            // ( types, selector, fn )
+                            fn = data;
+                            data = undefined;
+                        } else {
+                            // ( types, data, fn )
+                            fn = data;
+                            data = selector;
+                            selector = undefined;
+                        }
+                    }
+                    if (fn === false) {
+                        fn = returnFalse;
+                    } else if (!fn) {
+                        return this;
+                    }
+
+                    if (one === 1) {
+                        origFn = fn;
+                        fn = function(event) {
+                            // Can use an empty set, since event contains the info
+                            jQuery().off(event);
+                            return origFn.apply(this, arguments);
+                        };
+                        // Use same guid so caller can remove using origFn
+                        fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
+                    }
+                    return this.each(function() {
+                        jQuery.event.add(this, types, fn, data, selector);
+                    });
+                },
+                one: function(types, selector, data, fn) {
+                    return this.on(types, selector, data, fn, 1);
+                },
+                off: function(types, selector, fn) {
+                    var handleObj, type;
+                    if (types && types.preventDefault && types.handleObj) {
+                        // ( event ) dispatched jQuery.Event
+                        handleObj = types.handleObj;
+                        jQuery(types.delegateTarget).off(
+                            handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+                            handleObj.selector,
+                            handleObj.handler
+                        );
+                        return this;
+                    }
+                    if (typeof types === "object") {
+                        // ( types-object [, selector] )
+                        for (type in types) {
+                            this.off(type, selector, types[type]);
+                        }
+                        return this;
+                    }
+                    if (selector === false || typeof selector === "function") {
+                        // ( types [, fn] )
+                        fn = selector;
+                        selector = undefined;
+                    }
+                    if (fn === false) {
+                        fn = returnFalse;
+                    }
+                    return this.each(function() {
+                        jQuery.event.remove(this, types, fn, selector);
+                    });
+                },
+
+                trigger: function(type, data) {
+                    return this.each(function() {
+                        jQuery.event.trigger(type, data, this);
+                    });
+                },
+                triggerHandler: function(type, data) {
+                    var elem = this[0];
+                    if (elem) {
+                        return jQuery.event.trigger(type, data, elem, true);
+                    }
+                }
+            });
+
+
+            var
+                rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+                rtagName = /<([\w:]+)/,
+                rhtml = /<|&#?\w+;/,
+                rnoInnerhtml = /<(?:script|style|link)/i,
+                // checked="checked" or checked
+                rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+                rscriptType = /^$|\/(?:java|ecma)script/i,
+                rscriptTypeMasked = /^true\/(.*)/,
+                rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+                // We have to close these tags to support XHTML (#13200)
+                wrapMap = {
+
+                    // Support: IE9
+                    option: [1, "<select multiple='multiple'>", "</select>"],
+
+                    thead: [1, "<table>", "</table>"],
+                    col: [2, "<table><colgroup>", "</colgroup></table>"],
+                    tr: [2, "<table><tbody>", "</tbody></table>"],
+                    td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
+
+                    _default: [0, "", ""]
+                };
+
+            // Support: IE9
+            wrapMap.optgroup = wrapMap.option;
+
+            wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+            wrapMap.th = wrapMap.td;
+
+            // Support: 1.x compatibility
+            // Manipulating tables requires a tbody
+            function manipulationTarget(elem, content) {
+                return jQuery.nodeName(elem, "table") &&
+                    jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr") ?
+
+                    elem.getElementsByTagName("tbody")[0] ||
+                    elem.appendChild(elem.ownerDocument.createElement("tbody")) :
+                    elem;
+            }
+
+            // Replace/restore the type attribute of script elements for safe DOM
+            // manipulation
+            function disableScript(elem) {
+                elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
+                return elem;
+            }
+
+            function restoreScript(elem) {
+                var match = rscriptTypeMasked.exec(elem.type);
+
+                if (match) {
+                    elem.type = match[1];
+                } else {
+                    elem.removeAttribute("type");
+                }
+
+                return elem;
+            }
+
+            // Mark scripts as having already been evaluated
+            function setGlobalEval(elems, refElements) {
+                var i = 0,
+                    l = elems.length;
+
+                for (; i < l; i++) {
+                    data_priv.set(
+                        elems[i], "globalEval", !refElements || data_priv.get(refElements[i], "globalEval")
+                    );
+                }
+            }
+
+            function cloneCopyEvent(src, dest) {
+                var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+                if (dest.nodeType !== 1) {
+                    return;
+                }
+
+                // 1. Copy private data: events, handlers, etc.
+                if (data_priv.hasData(src)) {
+                    pdataOld = data_priv.access(src);
+                    pdataCur = data_priv.set(dest, pdataOld);
+                    events = pdataOld.events;
+
+                    if (events) {
+                        delete pdataCur.handle;
+                        pdataCur.events = {};
+
+                        for (type in events) {
+                            for (i = 0, l = events[type].length; i < l; i++) {
+                                jQuery.event.add(dest, type, events[type][i]);
+                            }
+                        }
+                    }
+                }
+
+                // 2. Copy user data
+                if (data_user.hasData(src)) {
+                    udataOld = data_user.access(src);
+                    udataCur = jQuery.extend({}, udataOld);
+
+                    data_user.set(dest, udataCur);
+                }
+            }
+
+            function getAll(context, tag) {
+                var ret = context.getElementsByTagName ? context.getElementsByTagName(tag || "*") :
+                    context.querySelectorAll ? context.querySelectorAll(tag || "*") : [];
+
+                return tag === undefined || tag && jQuery.nodeName(context, tag) ?
+                    jQuery.merge([context], ret) :
+                    ret;
+            }
+
+            // Fix IE bugs, see support tests
+            function fixInput(src, dest) {
+                var nodeName = dest.nodeName.toLowerCase();
+
+                // Fails to persist the checked state of a cloned checkbox or radio button.
+                if (nodeName === "input" && rcheckableType.test(src.type)) {
+                    dest.checked = src.checked;
+
+                    // Fails to return the selected option to the default selected state when
+                    // cloning options
+                } else if (nodeName === "input" || nodeName === "textarea") {
+                    dest.defaultValue = src.defaultValue;
+                }
+            }
+
+            jQuery.extend({
+                clone: function(elem, dataAndEvents, deepDataAndEvents) {
+                    var i, l, srcElements, destElements,
+                        clone = elem.cloneNode(true),
+                        inPage = jQuery.contains(elem.ownerDocument, elem);
+
+                    // Fix IE cloning issues
+                    if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&
+                        !jQuery.isXMLDoc(elem)) {
+
+                        // We eschew Sizzle here for performance reasons:
+                        // http://jsperf.com/getall-vs-sizzle/2
+                        destElements = getAll(clone);
+                        srcElements = getAll(elem);
+
+                        for (i = 0, l = srcElements.length; i < l; i++) {
+                            fixInput(srcElements[i], destElements[i]);
+                        }
+                    }
+
+                    // Copy the events from the original to the clone
+                    if (dataAndEvents) {
+                        if (deepDataAndEvents) {
+                            srcElements = srcElements || getAll(elem);
+                            destElements = destElements || getAll(clone);
+
+                            for (i = 0, l = srcElements.length; i < l; i++) {
+                                cloneCopyEvent(srcElements[i], destElements[i]);
+                            }
+                        } else {
+                            cloneCopyEvent(elem, clone);
+                        }
+                    }
+
+                    // Preserve script evaluation history
+                    destElements = getAll(clone, "script");
+                    if (destElements.length > 0) {
+                        setGlobalEval(destElements, !inPage && getAll(elem, "script"));
+                    }
+
+                    // Return the cloned set
+                    return clone;
+                },
+
+                buildFragment: function(elems, context, scripts, selection) {
+                    var elem, tmp, tag, wrap, contains, j,
+                        fragment = context.createDocumentFragment(),
+                        nodes = [],
+                        i = 0,
+                        l = elems.length;
+
+                    for (; i < l; i++) {
+                        elem = elems[i];
+
+                        if (elem || elem === 0) {
+
+                            // Add nodes directly
+                            if (jQuery.type(elem) === "object") {
+                                // Support: QtWebKit, PhantomJS
+                                // push.apply(_, arraylike) throws on ancient WebKit
+                                jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
+
+                                // Convert non-html into a text node
+                            } else if (!rhtml.test(elem)) {
+                                nodes.push(context.createTextNode(elem));
+
+                                // Convert html into DOM nodes
+                            } else {
+                                tmp = tmp || fragment.appendChild(context.createElement("div"));
+
+                                // Deserialize a standard representation
+                                tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
+                                wrap = wrapMap[tag] || wrapMap._default;
+                                tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, "<$1></$2>") + wrap[2];
+
+                                // Descend through wrappers to the right content
+                                j = wrap[0];
+                                while (j--) {
+                                    tmp = tmp.lastChild;
+                                }
+
+                                // Support: QtWebKit, PhantomJS
+                                // push.apply(_, arraylike) throws on ancient WebKit
+                                jQuery.merge(nodes, tmp.childNodes);
+
+                                // Remember the top-level container
+                                tmp = fragment.firstChild;
+
+                                // Ensure the created nodes are orphaned (#12392)
+                                tmp.textContent = "";
+                            }
+                        }
+                    }
+
+                    // Remove wrapper from fragment
+                    fragment.textContent = "";
+
+                    i = 0;
+                    while ((elem = nodes[i++])) {
+
+                        // #4087 - If origin and destination elements are the same, and this
+                        // is
+                        // that element, do not do anything
+                        if (selection && jQuery.inArray(elem, selection) !== -1) {
+                            continue;
+                        }
+
+                        contains = jQuery.contains(elem.ownerDocument, elem);
+
+                        // Append to fragment
+                        tmp = getAll(fragment.appendChild(elem), "script");
+
+                        // Preserve script evaluation history
+                        if (contains) {
+                            setGlobalEval(tmp);
+                        }
+
+                        // Capture executables
+                        if (scripts) {
+                            j = 0;
+                            while ((elem = tmp[j++])) {
+                                if (rscriptType.test(elem.type || "")) {
+                                    scripts.push(elem);
+                                }
+                            }
+                        }
+                    }
+
+                    return fragment;
+                },
+
+                cleanData: function(elems) {
+                    var data, elem, type, key,
+                        special = jQuery.event.special,
+                        i = 0;
+
+                    for (;
+                        (elem = elems[i]) !== undefined; i++) {
+                        if (jQuery.acceptData(elem)) {
+                            key = elem[data_priv.expando];
+
+                            if (key && (data = data_priv.cache[key])) {
+                                if (data.events) {
+                                    for (type in data.events) {
+                                        if (special[type]) {
+                                            jQuery.event.remove(elem, type);
+
+                                            // This is a shortcut to avoid jQuery.event.remove's
+                                            // overhead
+                                        } else {
+                                            jQuery.removeEvent(elem, type, data.handle);
+                                        }
+                                    }
+                                }
+                                if (data_priv.cache[key]) {
+                                    // Discard any remaining `private` data
+                                    delete data_priv.cache[key];
+                                }
+                            }
+                        }
+                        // Discard any remaining `user` data
+                        delete data_user.cache[elem[data_user.expando]];
+                    }
+                }
+            });
+
+            jQuery.fn.extend({
+                text: function(value) {
+                    return access(this, function(value) {
+                        return value === undefined ?
+                            jQuery.text(this) :
+                            this.empty().each(function() {
+                                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
+                                    this.textContent = value;
+                                }
+                            });
+                    }, null, value, arguments.length);
+                },
+
+                append: function() {
+                    return this.domManip(arguments, function(elem) {
+                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
+                            var target = manipulationTarget(this, elem);
+                            target.appendChild(elem);
+                        }
+                    });
+                },
+
+                prepend: function() {
+                    return this.domManip(arguments, function(elem) {
+                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
+                            var target = manipulationTarget(this, elem);
+                            target.insertBefore(elem, target.firstChild);
+                        }
+                    });
+                },
+
+                before: function() {
+                    return this.domManip(arguments, function(elem) {
+                        if (this.parentNode) {
+                            this.parentNode.insertBefore(elem, this);
+                        }
+                    });
+                },
+
+                after: function() {
+                    return this.domManip(arguments, function(elem) {
+                        if (this.parentNode) {
+                            this.parentNode.insertBefore(elem, this.nextSibling);
+                        }
+                    });
+                },
+
+                remove: function(selector, keepData /* Internal Use Only */ ) {
+                    var elem,
+                        elems = selector ? jQuery.filter(selector, this) : this,
+                        i = 0;
+
+                    for (;
+                        (elem = elems[i]) != null; i++) {
+                        if (!keepData && elem.nodeType === 1) {
+                            jQuery.cleanData(getAll(elem));
+                        }
+
+                        if (elem.parentNode) {
+                            if (keepData && jQuery.contains(elem.ownerDocument, elem)) {
+                                setGlobalEval(getAll(elem, "script"));
+                            }
+                            elem.parentNode.removeChild(elem);
+                        }
+                    }
+
+                    return this;
+                },
+
+                empty: function() {
+                    var elem,
+                        i = 0;
+
+                    for (;
+                        (elem = this[i]) != null; i++) {
+                        if (elem.nodeType === 1) {
+
+                            // Prevent memory leaks
+                            jQuery.cleanData(getAll(elem, false));
+
+                            // Remove any remaining nodes
+                            elem.textContent = "";
+                        }
+                    }
+
+                    return this;
+                },
+
+                clone: function(dataAndEvents, deepDataAndEvents) {
+                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+                    return this.map(function() {
+                        return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
+                    });
+                },
+
+                html: function(value) {
+                    return access(this, function(value) {
+                        var elem = this[0] || {},
+                            i = 0,
+                            l = this.length;
+
+                        if (value === undefined && elem.nodeType === 1) {
+                            return elem.innerHTML;
+                        }
+
+                        // See if we can take a shortcut and just use innerHTML
+                        if (typeof value === "string" && !rnoInnerhtml.test(value) &&
+                            !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
+
+                            value = value.replace(rxhtmlTag, "<$1></$2>");
+
+                            try {
+                                for (; i < l; i++) {
+                                    elem = this[i] || {};
+
+                                    // Remove element nodes and prevent memory leaks
+                                    if (elem.nodeType === 1) {
+                                        jQuery.cleanData(getAll(elem, false));
+                                        elem.innerHTML = value;
+                                    }
+                                }
+
+                                elem = 0;
+
+                                // If using innerHTML throws an exception, use the fallback
+                                // method
+                            } catch (e) {}
+                        }
+
+                        if (elem) {
+                            this.empty().append(value);
+                        }
+                    }, null, value, arguments.length);
+                },
+
+                replaceWith: function() {
+                    var arg = arguments[0];
+
+                    // Make the changes, replacing each context element with the new content
+                    this.domManip(arguments, function(elem) {
+                        arg = this.parentNode;
+
+                        jQuery.cleanData(getAll(this));
+
+                        if (arg) {
+                            arg.replaceChild(elem, this);
+                        }
+                    });
+
+                    // Force removal if there was no new content (e.g., from empty
+                    // arguments)
+                    return arg && (arg.length || arg.nodeType) ? this : this.remove();
+                },
+
+                detach: function(selector) {
+                    return this.remove(selector, true);
+                },
+
+                domManip: function(args, callback) {
+
+                    // Flatten any nested arrays
+                    args = concat.apply([], args);
+
+                    var fragment, first, scripts, hasScripts, node, doc,
+                        i = 0,
+                        l = this.length,
+                        set = this,
+                        iNoClone = l - 1,
+                        value = args[0],
+                        isFunction = jQuery.isFunction(value);
+
+                    // We can't cloneNode fragments that contain checked, in WebKit
+                    if (isFunction ||
+                        (l > 1 && typeof value === "string" &&
+                            !support.checkClone && rchecked.test(value))) {
+                        return this.each(function(index) {
+                            var self = set.eq(index);
+                            if (isFunction) {
+                                args[0] = value.call(this, index, self.html());
+                            }
+                            self.domManip(args, callback);
+                        });
+                    }
+
+                    if (l) {
+                        fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, this);
+                        first = fragment.firstChild;
+
+                        if (fragment.childNodes.length === 1) {
+                            fragment = first;
+                        }
+
+                        if (first) {
+                            scripts = jQuery.map(getAll(fragment, "script"), disableScript);
+                            hasScripts = scripts.length;
+
+                            // Use the original fragment for the last item instead of the
+                            // first because it can end up
+                            // being emptied incorrectly in certain situations (#8070).
+                            for (; i < l; i++) {
+                                node = fragment;
+
+                                if (i !== iNoClone) {
+                                    node = jQuery.clone(node, true, true);
+
+                                    // Keep references to cloned scripts for later
+                                    // restoration
+                                    if (hasScripts) {
+                                        // Support: QtWebKit
+                                        // jQuery.merge because push.apply(_, arraylike)
+                                        // throws
+                                        jQuery.merge(scripts, getAll(node, "script"));
+                                    }
+                                }
+
+                                callback.call(this[i], node, i);
+                            }
+
+                            if (hasScripts) {
+                                doc = scripts[scripts.length - 1].ownerDocument;
+
+                                // Reenable scripts
+                                jQuery.map(scripts, restoreScript);
+
+                                // Evaluate executable scripts on first document insertion
+                                for (i = 0; i < hasScripts; i++) {
+                                    node = scripts[i];
+                                    if (rscriptType.test(node.type || "") &&
+                                        !data_priv.access(node, "globalEval") && jQuery.contains(doc, node)) {
+
+                                        if (node.src) {
+                                            // Optional AJAX dependency, but won't run
+                                            // scripts if not present
+                                            if (jQuery._evalUrl) {
+                                                jQuery._evalUrl(node.src);
+                                            }
+                                        } else {
+                                            jQuery.globalEval(node.textContent.replace(rcleanScript, ""));
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    return this;
+                }
+            });
+
+            jQuery.each({
+                appendTo: "append",
+                prependTo: "prepend",
+                insertBefore: "before",
+                insertAfter: "after",
+                replaceAll: "replaceWith"
+            }, function(name, original) {
+                jQuery.fn[name] = function(selector) {
+                    var elems,
+                        ret = [],
+                        insert = jQuery(selector),
+                        last = insert.length - 1,
+                        i = 0;
+
+                    for (; i <= last; i++) {
+                        elems = i === last ? this : this.clone(true);
+                        jQuery(insert[i])[original](elems);
+
+                        // Support: QtWebKit
+                        // .get() because push.apply(_, arraylike) throws
+                        push.apply(ret, elems.get());
+                    }
+
+                    return this.pushStack(ret);
+                };
+            });
+
+
+            var iframe,
+                elemdisplay = {};
+
+            /**
+             * Retrieve the actual display of a element
+             * 
+             * @param {String}
+             *            name nodeName of the element
+             * @param {Object}
+             *            doc Document object
+             */
+            // Called only from within defaultDisplay
+            function actualDisplay(name, doc) {
+                var style,
+                    elem = jQuery(doc.createElement(name)).appendTo(doc.body),
+
+                    // getDefaultComputedStyle might be reliably used only on attached
+                    // element
+                    display = window.getDefaultComputedStyle && (style = window.getDefaultComputedStyle(elem[0])) ?
+
+                    // Use of this method is a temporary fix (more like optimization)
+                    // until something better comes along,
+                    // since it was removed from specification and supported only in FF
+                    style.display : jQuery.css(elem[0], "display");
+
+                // We don't have any data stored on the element,
+                // so use "detach" method as fast way to get rid of the element
+                elem.detach();
+
+                return display;
+            }
+
+            /**
+             * Try to determine the default display value of an element
+             * 
+             * @param {String}
+             *            nodeName
+             */
+            function defaultDisplay(nodeName) {
+                var doc = document,
+                    display = elemdisplay[nodeName];
+
+                if (!display) {
+                    display = actualDisplay(nodeName, doc);
+
+                    // If the simple way fails, read from inside an iframe
+                    if (display === "none" || !display) {
+
+                        // Use the already-created iframe if possible
+                        iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")).appendTo(doc.documentElement);
+
+                        // Always write a new HTML skeleton so Webkit and Firefox don't
+                        // choke on reuse
+                        doc = iframe[0].contentDocument;
+
+                        // Support: IE
+                        doc.write();
+                        doc.close();
+
+                        display = actualDisplay(nodeName, doc);
+                        iframe.detach();
+                    }
+
+                    // Store the correct default display
+                    elemdisplay[nodeName] = display;
+                }
+
+                return display;
+            }
+            var rmargin = (/^margin/);
+
+            var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
+
+            var getStyles = function(elem) {
+                // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+                // IE throws on elements created in popups
+                // FF meanwhile throws on frame elements through
+                // "defaultView.getComputedStyle"
+                if (elem.ownerDocument.defaultView.opener) {
+                    return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
+                }
+
+                return window.getComputedStyle(elem, null);
+            };
+
+
+
+            function curCSS(elem, name, computed) {
+                var width, minWidth, maxWidth, ret,
+                    style = elem.style;
+
+                computed = computed || getStyles(elem);
+
+                // Support: IE9
+                // getPropertyValue is only needed for .css('filter') (#12537)
+                if (computed) {
+                    ret = computed.getPropertyValue(name) || computed[name];
+                }
+
+                if (computed) {
+
+                    if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
+                        ret = jQuery.style(elem, name);
+                    }
+
+                    // Support: iOS < 6
+                    // A tribute to the "awesome hack by Dean Edwards"
+                    // iOS < 6 (at least) returns percentage for a larger set of values, but
+                    // width seems to be reliably pixels
+                    // this is against the CSSOM draft spec:
+                    // http://dev.w3.org/csswg/cssom/#resolved-values
+                    if (rnumnonpx.test(ret) && rmargin.test(name)) {
+
+                        // Remember the original values
+                        width = style.width;
+                        minWidth = style.minWidth;
+                        maxWidth = style.maxWidth;
+
+                        // Put in the new values to get a computed value out
+                        style.minWidth = style.maxWidth = style.width = ret;
+                        ret = computed.width;
+
+                        // Revert the changed values
+                        style.width = width;
+                        style.minWidth = minWidth;
+                        style.maxWidth = maxWidth;
+                    }
+                }
+
+                return ret !== undefined ?
+                    // Support: IE
+                    // IE returns zIndex value as an integer.
+                    ret + "" :
+                    ret;
+            }
+
+
+            function addGetHookIf(conditionFn, hookFn) {
+                // Define the hook, we'll check on the first run if it's really needed.
+                return {
+                    get: function() {
+                        if (conditionFn()) {
+                            // Hook not needed (or it's not possible to use it due
+                            // to missing dependency), remove it.
+                            delete this.get;
+                            return;
+                        }
+
+                        // Hook needed; redefine it so that the support test is not executed
+                        // again.
+                        return (this.get = hookFn).apply(this, arguments);
+                    }
+                };
+            }
+
+
+            (function() {
+                var pixelPositionVal, boxSizingReliableVal,
+                    docElem = document.documentElement,
+                    container = document.createElement("div"),
+                    div = document.createElement("div");
+
+                if (!div.style) {
+                    return;
+                }
+
+                // Support: IE9-11+
+                // Style of cloned element affects source element cloned (#8908)
+                div.style.backgroundClip = "content-box";
+                div.cloneNode(true).style.backgroundClip = "";
+                support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+                container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
+                    "position:absolute";
+                container.appendChild(div);
+
+                // Executing both pixelPosition & boxSizingReliable tests require only one
+                // layout
+                // so they're executed at the same time to save the second computation.
+                function computePixelPositionAndBoxSizingReliable() {
+                    div.style.cssText =
+                        // Support: Firefox<29, Android 2.3
+                        // Vendor-prefix box-sizing
+                        "-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";
+                    div.innerHTML = "";
+                    docElem.appendChild(container);
+
+                    var divStyle = window.getComputedStyle(div, null);
+                    pixelPositionVal = divStyle.top !== "1%";
+                    boxSizingReliableVal = divStyle.width === "4px";
+
+                    docElem.removeChild(container);
+                }
+
+                // Support: node.js jsdom
+                // Don't assume that getComputedStyle is a property of the global object
+                if (window.getComputedStyle) {
+                    jQuery.extend(support, {
+                        pixelPosition: function() {
+
+                            // This test is executed only once but we still do memoizing
+                            // since we can use the boxSizingReliable pre-computing.
+                            // No need to check if the test was already performed, though.
+                            computePixelPositionAndBoxSizingReliable();
+                            return pixelPositionVal;
+                        },
+                        boxSizingReliable: function() {
+                            if (boxSizingReliableVal == null) {
+                                computePixelPositionAndBoxSizingReliable();
+                            }
+                            return boxSizingReliableVal;
+                        },
+                        reliableMarginRight: function() {
+
+                            // Support: Android 2.3
+                            // Check if div with explicit width and no margin-right
+                            // incorrectly
+                            // gets computed margin-right based on width of container.
+                            // (#3333)
+                            // WebKit Bug 13343 - getComputedStyle returns wrong value for
+                            // margin-right
+                            // This support function is only executed once so no memoizing
+                            // is needed.
+                            var ret,
+                                marginDiv = div.appendChild(document.createElement("div"));
+
+                            // Reset CSS: box-sizing; display; margin; border; padding
+                            marginDiv.style.cssText = div.style.cssText =
+                                // Support: Firefox<29, Android 2.3
+                                // Vendor-prefix box-sizing
+                                "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
+                                "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
+                            marginDiv.style.marginRight = marginDiv.style.width = "0";
+                            div.style.width = "1px";
+                            docElem.appendChild(container);
+
+                            ret = !parseFloat(window.getComputedStyle(marginDiv, null).marginRight);
+
+                            docElem.removeChild(container);
+                            div.removeChild(marginDiv);
+
+                            return ret;
+                        }
+                    });
+                }
+            })();
+
+
+            // A method for quickly swapping in/out CSS properties to get correct
+            // calculations.
+            jQuery.swap = function(elem, options, callback, args) {
+                var ret, name,
+                    old = {};
+
+                // Remember the old values, and insert the new ones
+                for (name in options) {
+                    old[name] = elem.style[name];
+                    elem.style[name] = options[name];
+                }
+
+                ret = callback.apply(elem, args || []);
+
+                // Revert the old values
+                for (name in options) {
+                    elem.style[name] = old[name];
+                }
+
+                return ret;
+            };
+
+
+            var
+            // Swappable if display is none or starts with table except "table",
+            // "table-cell", or "table-caption"
+            // See here for display values:
+            // https://developer.mozilla.org/en-US/docs/CSS/display
+                rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+                rnumsplit = new RegExp("^(" + pnum + ")(.*)$", "i"),
+                rrelNum = new RegExp("^([+-])=(" + pnum + ")", "i"),
+
+                cssShow = {
+                    position: "absolute",
+                    visibility: "hidden",
+                    display: "block"
+                },
+                cssNormalTransform = {
+                    letterSpacing: "0",
+                    fontWeight: "400"
+                },
+
+                cssPrefixes = ["Webkit", "O", "Moz", "ms"];
+
+            // Return a css property mapped to a potentially vendor prefixed property
+            function vendorPropName(style, name) {
+
+                // Shortcut for names that are not vendor prefixed
+                if (name in style) {
+                    return name;
+                }
+
+                // Check for vendor prefixed names
+                var capName = name[0].toUpperCase() + name.slice(1),
+                    origName = name,
+                    i = cssPrefixes.length;
+
+                while (i--) {
+                    name = cssPrefixes[i] + capName;
+                    if (name in style) {
+                        return name;
+                    }
+                }
+
+                return origName;
+            }
+
+            function setPositiveNumber(elem, value, subtract) {
+                var matches = rnumsplit.exec(value);
+                return matches ?
+                    // Guard against undefined "subtract", e.g., when used as in cssHooks
+                    Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") :
+                    value;
+            }
+
+            function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
+                var i = extra === (isBorderBox ? "border" : "content") ?
+                    // If we already have the right measurement, avoid augmentation
+                    4 :
+                    // Otherwise initialize for horizontal or vertical properties
+                    name === "width" ? 1 : 0,
+
+                    val = 0;
+
+                for (; i < 4; i += 2) {
+                    // Both box models exclude margin, so add it if we want it
+                    if (extra === "margin") {
+                        val += jQuery.css(elem, extra + cssExpand[i], true, styles);
+                    }
+
+                    if (isBorderBox) {
+                        // border-box includes padding, so remove it if we want content
+                        if (extra === "content") {
+                            val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
+                        }
+
+                        // At this point, extra isn't border nor margin, so remove border
+                        if (extra !== "margin") {
+                            val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
+                        }
+                    } else {
+                        // At this point, extra isn't content, so add padding
+                        val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
+
+                        // At this point, extra isn't content nor padding, so add border
+                        if (extra !== "padding") {
+                            val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
+                        }
+                    }
+                }
+
+                return val;
+            }
+
+            function getWidthOrHeight(elem, name, extra) {
+
+                // Start with offset property, which is equivalent to the border-box value
+                var valueIsBorderBox = true,
+                    val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+                    styles = getStyles(elem),
+                    isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";
+
+                // Some non-html elements return undefined for offsetWidth, so check for
+                // null/undefined
+                // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+                // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+                if (val <= 0 || val == null) {
+                    // Fall back to computed then uncomputed css if necessary
+                    val = curCSS(elem, name, styles);
+                    if (val < 0 || val == null) {
+                        val = elem.style[name];
+                    }
+
+                    // Computed unit is not pixels. Stop here and return.
+                    if (rnumnonpx.test(val)) {
+                        return val;
+                    }
+
+                    // Check for style in case a browser which returns unreliable values
+                    // for getComputedStyle silently falls back to the reliable elem.style
+                    valueIsBorderBox = isBorderBox &&
+                        (support.boxSizingReliable() || val === elem.style[name]);
+
+                    // Normalize "", auto, and prepare for extra
+                    val = parseFloat(val) || 0;
+                }
+
+                // Use the active box-sizing model to add/subtract irrelevant styles
+                return (val +
+                    augmentWidthOrHeight(
+                        elem,
+                        name,
+                        extra || (isBorderBox ? "border" : "content"),
+                        valueIsBorderBox,
+                        styles
+                    )
+                ) + "px";
+            }
+
+            function showHide(elements, show) {
+                var display, elem, hidden,
+                    values = [],
+                    index = 0,
+                    length = elements.length;
+
+                for (; index < length; index++) {
+                    elem = elements[index];
+                    if (!elem.style) {
+                        continue;
+                    }
+
+                    values[index] = data_priv.get(elem, "olddisplay");
+                    display = elem.style.display;
+                    if (show) {
+                        // Reset the inline display of this element to learn if it is
+                        // being hidden by cascaded rules or not
+                        if (!values[index] && display === "none") {
+                            elem.style.display = "";
+                        }
+
+                        // Set elements which have been overridden with display: none
+                        // in a stylesheet to whatever the default browser style is
+                        // for such an element
+                        if (elem.style.display === "" && isHidden(elem)) {
+                            values[index] = data_priv.access(elem, "olddisplay", defaultDisplay(elem.nodeName));
+                        }
+                    } else {
+                        hidden = isHidden(elem);
+
+                        if (display !== "none" || !hidden) {
+                            data_priv.set(elem, "olddisplay", hidden ? display : jQuery.css(elem, "display"));
+                        }
+                    }
+                }
+
+                // Set the display of most of the elements in a second loop
+                // to avoid the constant reflow
+                for (index = 0; index < length; index++) {
+                    elem = elements[index];
+                    if (!elem.style) {
+                        continue;
+                    }
+                    if (!show || elem.style.display === "none" || elem.style.display === "") {
+                        elem.style.display = show ? values[index] || "" : "none";
+                    }
+                }
+
+                return elements;
+            }
+
+            jQuery.extend({
+
+                // Add in style property hooks for overriding the default
+                // behavior of getting and setting a style property
+                cssHooks: {
+                    opacity: {
+                        get: function(elem, computed) {
+                            if (computed) {
+
+                                // We should always get a number back from opacity
+                                var ret = curCSS(elem, "opacity");
+                                return ret === "" ? "1" : ret;
+                            }
+                        }
+                    }
+                },
+
+                // Don't automatically add "px" to these possibly-unitless properties
+                cssNumber: {
+                    "columnCount": true,
+                    "fillOpacity": true,
+                    "flexGrow": true,
+                    "flexShrink": true,
+                    "fontWeight": true,
+                    "lineHeight": true,
+                    "opacity": true,
+                    "order": true,
+                    "orphans": true,
+                    "widows": true,
+                    "zIndex": true,
+                    "zoom": true
+                },
+
+                // Add in properties whose names you wish to fix before
+                // setting or getting the value
+                cssProps: {
+                    "float": "cssFloat"
+                },
+
+                // Get and set the style property on a DOM Node
+                style: function(elem, name, value, extra) {
+
+                    // Don't set styles on text and comment nodes
+                    if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
+                        return;
+                    }
+
+                    // Make sure that we're working with the right name
+                    var ret, type, hooks,
+                        origName = jQuery.camelCase(name),
+                        style = elem.style;
+
+                    name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName));
+
+                    // Gets hook for the prefixed version, then unprefixed version
+                    hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
+
+                    // Check if we're setting a value
+                    if (value !== undefined) {
+                        type = typeof value;
+
+                        // Convert "+=" or "-=" to relative numbers (#7345)
+                        if (type === "string" && (ret = rrelNum.exec(value))) {
+                            value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name));
+                            // Fixes bug #9237
+                            type = "number";
+                        }
+
+                        // Make sure that null and NaN values aren't set (#7116)
+                        if (value == null || value !== value) {
+                            return;
+                        }
+
+                        // If a number, add 'px' to the (except for certain CSS properties)
+                        if (type === "number" && !jQuery.cssNumber[origName]) {
+                            value += "px";
+                        }
+
+                        // Support: IE9-11+
+                        // background-* props affect original clone's values
+                        if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
+                            style[name] = "inherit";
+                        }
+
+                        // If a hook was provided, use that value, otherwise just set the
+                        // specified value
+                        if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
+                            style[name] = value;
+                        }
+
+                    } else {
+                        // If a hook was provided get the non-computed value from there
+                        if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
+                            return ret;
+                        }
+
+                        // Otherwise just get the value from the style object
+                        return style[name];
+                    }
+                },
+
+                css: function(elem, name, extra, styles) {
+                    var val, num, hooks,
+                        origName = jQuery.camelCase(name);
+
+                    // Make sure that we're working with the right name
+                    name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName));
+
+                    // Try prefixed name followed by the unprefixed name
+                    hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
+
+                    // If a hook was provided get the computed value from there
+                    if (hooks && "get" in hooks) {
+                        val = hooks.get(elem, true, extra);
+                    }
+
+                    // Otherwise, if a way to get the computed value exists, use that
+                    if (val === undefined) {
+                        val = curCSS(elem, name, styles);
+                    }
+
+                    // Convert "normal" to computed value
+                    if (val === "normal" && name in cssNormalTransform) {
+                        val = cssNormalTransform[name];
+                    }
+
+                    // Make numeric if forced or a qualifier was provided and val looks
+                    // numeric
+                    if (extra === "" || extra) {
+                        num = parseFloat(val);
+                        return extra === true || jQuery.isNumeric(num) ? num || 0 : val;
+                    }
+                    return val;
+                }
+            });
+
+            jQuery.each(["height", "width"], function(i, name) {
+                jQuery.cssHooks[name] = {
+                    get: function(elem, computed, extra) {
+                        if (computed) {
+
+                            // Certain elements can have dimension info if we invisibly show
+                            // them
+                            // but it must have a current display style that would benefit
+                            return rdisplayswap.test(jQuery.css(elem, "display")) && elem.offsetWidth === 0 ?
+                                jQuery.swap(elem, cssShow, function() {
+                                    return getWidthOrHeight(elem, name, extra);
+                                }) :
+                                getWidthOrHeight(elem, name, extra);
+                        }
+                    },
+
+                    set: function(elem, value, extra) {
+                        var styles = extra && getStyles(elem);
+                        return setPositiveNumber(elem, value, extra ?
+                            augmentWidthOrHeight(
+                                elem,
+                                name,
+                                extra,
+                                jQuery.css(elem, "boxSizing", false, styles) === "border-box",
+                                styles
+                            ) : 0
+                        );
+                    }
+                };
+            });
+
+            // Support: Android 2.3
+            jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight,
+                function(elem, computed) {
+                    if (computed) {
+                        return jQuery.swap(elem, {
+                                "display": "inline-block"
+                            },
+                            curCSS, [elem, "marginRight"]);
+                    }
+                }
+            );
+
+            // These hooks are used by animate to expand properties
+            jQuery.each({
+                margin: "",
+                padding: "",
+                border: "Width"
+            }, function(prefix, suffix) {
+                jQuery.cssHooks[prefix + suffix] = {
+                    expand: function(value) {
+                        var i = 0,
+                            expanded = {},
+
+                            // Assumes a single number if not a string
+                            parts = typeof value === "string" ? value.split(" ") : [value];
+
+                        for (; i < 4; i++) {
+                            expanded[prefix + cssExpand[i] + suffix] =
+                                parts[i] || parts[i - 2] || parts[0];
+                        }
+
+                        return expanded;
+                    }
+                };
+
+                if (!rmargin.test(prefix)) {
+                    jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
+                }
+            });
+
+            jQuery.fn.extend({
+                css: function(name, value) {
+                    return access(this, function(elem, name, value) {
+                        var styles, len,
+                            map = {},
+                            i = 0;
+
+                        if (jQuery.isArray(name)) {
+                            styles = getStyles(elem);
+                            len = name.length;
+
+                            for (; i < len; i++) {
+                                map[name[i]] = jQuery.css(elem, name[i], false, styles);
+                            }
+
+                            return map;
+                        }
+
+                        return value !== undefined ?
+                            jQuery.style(elem, name, value) :
+                            jQuery.css(elem, name);
+                    }, name, value, arguments.length > 1);
+                },
+                show: function() {
+                    return showHide(this, true);
+                },
+                hide: function() {
+                    return showHide(this);
+                },
+                toggle: function(state) {
+                    if (typeof state === "boolean") {
+                        return state ? this.show() : this.hide();
+                    }
+
+                    return this.each(function() {
+                        if (isHidden(this)) {
+                            jQuery(this).show();
+                        } else {
+                            jQuery(this).hide();
+                        }
+                    });
+                }
+            });
+
+
+            function Tween(elem, options, prop, end, easing) {
+                return new Tween.prototype.init(elem, options, prop, end, easing);
+            }
+            jQuery.Tween = Tween;
+
+            Tween.prototype = {
+                constructor: Tween,
+                init: function(elem, options, prop, end, easing, unit) {
+                    this.elem = elem;
+                    this.prop = prop;
+                    this.easing = easing || "swing";
+                    this.options = options;
+                    this.start = this.now = this.cur();
+                    this.end = end;
+                    this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
+                },
+                cur: function() {
+                    var hooks = Tween.propHooks[this.prop];
+
+                    return hooks && hooks.get ?
+                        hooks.get(this) :
+                        Tween.propHooks._default.get(this);
+                },
+                run: function(percent) {
+                    var eased,
+                        hooks = Tween.propHooks[this.prop];
+
+                    if (this.options.duration) {
+                        this.pos = eased = jQuery.easing[this.easing](
+                            percent, this.options.duration * percent, 0, 1, this.options.duration
+                        );
+                    } else {
+                        this.pos = eased = percent;
+                    }
+                    this.now = (this.end - this.start) * eased + this.start;
+
+                    if (this.options.step) {
+                        this.options.step.call(this.elem, this.now, this);
+                    }
+
+                    if (hooks && hooks.set) {
+                        hooks.set(this);
+                    } else {
+                        Tween.propHooks._default.set(this);
+                    }
+                    return this;
+                }
+            };
+
+            Tween.prototype.init.prototype = Tween.prototype;
+
+            Tween.propHooks = {
+                _default: {
+                    get: function(tween) {
+                        var result;
+
+                        if (tween.elem[tween.prop] != null &&
+                            (!tween.elem.style || tween.elem.style[tween.prop] == null)) {
+                            return tween.elem[tween.prop];
+                        }
+
+                        // Passing an empty string as a 3rd parameter to .css will
+                        // automatically
+                        // attempt a parseFloat and fallback to a string if the parse fails.
+                        // Simple values such as "10px" are parsed to Float;
+                        // complex values such as "rotate(1rad)" are returned as-is.
+                        result = jQuery.css(tween.elem, tween.prop, "");
+                        // Empty strings, null, undefined and "auto" are converted to 0.
+                        return !result || result === "auto" ? 0 : result;
+                    },
+                    set: function(tween) {
+                        // Use step hook for back compat.
+                        // Use cssHook if its there.
+                        // Use .style if available and use plain properties where available.
+                        if (jQuery.fx.step[tween.prop]) {
+                            jQuery.fx.step[tween.prop](tween);
+                        } else if (tween.elem.style && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
+                            jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
+                        } else {
+                            tween.elem[tween.prop] = tween.now;
+                        }
+                    }
+                }
+            };
+
+            // Support: IE9
+            // Panic based approach to setting things on disconnected nodes
+            Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+                set: function(tween) {
+                    if (tween.elem.nodeType && tween.elem.parentNode) {
+                        tween.elem[tween.prop] = tween.now;
+                    }
+                }
+            };
+
+            jQuery.easing = {
+                linear: function(p) {
+                    return p;
+                },
+                swing: function(p) {
+                    return 0.5 - Math.cos(p * Math.PI) / 2;
+                }
+            };
+
+            jQuery.fx = Tween.prototype.init;
+
+            // Back Compat <1.8 extension point
+            jQuery.fx.step = {};
+
+
+
+
+            var
+                fxNow, timerId,
+                rfxtypes = /^(?:toggle|show|hide)$/,
+                rfxnum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"),
+                rrun = /queueHooks$/,
+                animationPrefilters = [defaultPrefilter],
+                tweeners = {
+                    "*": [function(prop, value) {
+                        var tween = this.createTween(prop, value),
+                            target = tween.cur(),
+                            parts = rfxnum.exec(value),
+                            unit = parts && parts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
+
+                            // Starting value computation is required for potential unit
+                            // mismatches
+                            start = (jQuery.cssNumber[prop] || unit !== "px" && +target) &&
+                            rfxnum.exec(jQuery.css(tween.elem, prop)),
+                            scale = 1,
+                            maxIterations = 20;
+
+                        if (start && start[3] !== unit) {
+                            // Trust units reported by jQuery.css
+                            unit = unit || start[3];
+
+                            // Make sure we update the tween properties later on
+                            parts = parts || [];
+
+                            // Iteratively approximate from a nonzero starting point
+                            start = +target || 1;
+
+                            do {
+                                // If previous iteration zeroed out, double until we get
+                                // *something*.
+                                // Use string for doubling so we don't accidentally see
+                                // scale as unchanged below
+                                scale = scale || ".5";
+
+                                // Adjust and apply
+                                start = start / scale;
+                                jQuery.style(tween.elem, prop, start + unit);
+
+                                // Update scale, tolerating zero or NaN from tween.cur(),
+                                // break the loop if scale is unchanged or perfect, or if we've
+                                // just had enough
+                            } while (scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations);
+                        }
+
+                        // Update tween properties
+                        if (parts) {
+                            start = tween.start = +start || +target || 0;
+                            tween.unit = unit;
+                            // If a +=/-= token was provided, we're doing a relative
+                            // animation
+                            tween.end = parts[1] ?
+                                start + (parts[1] + 1) * parts[2] :
+                                +parts[2];
+                        }
+
+                        return tween;
+                    }]
+                };
+
+            // Animations created synchronously will run synchronously
+            function createFxNow() {
+                setTimeout(function() {
+                    fxNow = undefined;
+                });
+                return (fxNow = jQuery.now());
+            }
+
+            // Generate parameters to create a standard animation
+            function genFx(type, includeWidth) {
+                var which,
+                    i = 0,
+                    attrs = {
+                        height: type
+                    };
+
+                // If we include width, step value is 1 to do all cssExpand values,
+                // otherwise step value is 2 to skip over Left and Right
+                includeWidth = includeWidth ? 1 : 0;
+                for (; i < 4; i += 2 - includeWidth) {
+                    which = cssExpand[i];
+                    attrs["margin" + which] = attrs["padding" + which] = type;
+                }
+
+                if (includeWidth) {
+                    attrs.opacity = attrs.width = type;
+                }
+
+                return attrs;
+            }
+
+            function createTween(value, prop, animation) {
+                var tween,
+                    collection = (tweeners[prop] || []).concat(tweeners["*"]),
+                    index = 0,
+                    length = collection.length;
+                for (; index < length; index++) {
+                    if ((tween = collection[index].call(animation, prop, value))) {
+
+                        // We're done with this property
+                        return tween;
+                    }
+                }
+            }
+
+            function defaultPrefilter(elem, props, opts) {
+                /* jshint validthis: true */
+                var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
+                    anim = this,
+                    orig = {},
+                    style = elem.style,
+                    hidden = elem.nodeType && isHidden(elem),
+                    dataShow = data_priv.get(elem, "fxshow");
+
+                // Handle queue: false promises
+                if (!opts.queue) {
+                    hooks = jQuery._queueHooks(elem, "fx");
+                    if (hooks.unqueued == null) {
+                        hooks.unqueued = 0;
+                        oldfire = hooks.empty.fire;
+                        hooks.empty.fire = function() {
+                            if (!hooks.unqueued) {
+                                oldfire();
+                            }
+                        };
+                    }
+                    hooks.unqueued++;
+
+                    anim.always(function() {
+                        // Ensure the complete handler is called before this completes
+                        anim.always(function() {
+                            hooks.unqueued--;
+                            if (!jQuery.queue(elem, "fx").length) {
+                                hooks.empty.fire();
+                            }
+                        });
+                    });
+                }
+
+                // Height/width overflow pass
+                if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
+                    // Make sure that nothing sneaks out
+                    // Record all 3 overflow attributes because IE9-10 do not
+                    // change the overflow attribute when overflowX and
+                    // overflowY are set to the same value
+                    opts.overflow = [style.overflow, style.overflowX, style.overflowY];
+
+                    // Set display property to inline-block for height/width
+                    // animations on inline elements that are having width/height animated
+                    display = jQuery.css(elem, "display");
+
+                    // Test default display if display is currently "none"
+                    checkDisplay = display === "none" ?
+                        data_priv.get(elem, "olddisplay") || defaultDisplay(elem.nodeName) : display;
+
+                    if (checkDisplay === "inline" && jQuery.css(elem, "float") === "none") {
+                        style.display = "inline-block";
+                    }
+                }
+
+                if (opts.overflow) {
+                    style.overflow = "hidden";
+                    anim.always(function() {
+                        style.overflow = opts.overflow[0];
+                        style.overflowX = opts.overflow[1];
+                        style.overflowY = opts.overflow[2];
+                    });
+                }
+
+                // show/hide pass
+                for (prop in props) {
+                    value = props[prop];
+                    if (rfxtypes.exec(value)) {
+                        delete props[prop];
+                        toggle = toggle || value === "toggle";
+                        if (value === (hidden ? "hide" : "show")) {
+
+                            // If there is dataShow left over from a stopped hide or show
+                            // and we are going to proceed with show, we should pretend to
+                            // be hidden
+                            if (value === "show" && dataShow && dataShow[prop] !== undefined) {
+                                hidden = true;
+                            } else {
+                                continue;
+                            }
+                        }
+                        orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
+
+                        // Any non-fx value stops us from restoring the original display value
+                    } else {
+                        display = undefined;
+                    }
+                }
+
+                if (!jQuery.isEmptyObject(orig)) {
+                    if (dataShow) {
+                        if ("hidden" in dataShow) {
+                            hidden = dataShow.hidden;
+                        }
+                    } else {
+                        dataShow = data_priv.access(elem, "fxshow", {});
+                    }
+
+                    // Store state if its toggle - enables .stop().toggle() to "reverse"
+                    if (toggle) {
+                        dataShow.hidden = !hidden;
+                    }
+                    if (hidden) {
+                        jQuery(elem).show();
+                    } else {
+                        anim.done(function() {
+                            jQuery(elem).hide();
+                        });
+                    }
+                    anim.done(function() {
+                        var prop;
+
+                        data_priv.remove(elem, "fxshow");
+                        for (prop in orig) {
+                            jQuery.style(elem, prop, orig[prop]);
+                        }
+                    });
+                    for (prop in orig) {
+                        tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
+
+                        if (!(prop in dataShow)) {
+                            dataShow[prop] = tween.start;
+                            if (hidden) {
+                                tween.end = tween.start;
+                                tween.start = prop === "width" || prop === "height" ? 1 : 0;
+                            }
+                        }
+                    }
+
+                    // If this is a noop like .hide().hide(), restore an overwritten display
+                    // value
+                } else if ((display === "none" ? defaultDisplay(elem.nodeName) : display) === "inline") {
+                    style.display = display;
+                }
+            }
+
+            function propFilter(props, specialEasing) {
+                var index, name, easing, value, hooks;
+
+                // camelCase, specialEasing and expand cssHook pass
+                for (index in props) {
+                    name = jQuery.camelCase(index);
+                    easing = specialEasing[name];
+                    value = props[index];
+                    if (jQuery.isArray(value)) {
+                        easing = value[1];
+                        value = props[index] = value[0];
+                    }
+
+                    if (index !== name) {
+                        props[name] = value;
+                        delete props[index];
+                    }
+
+                    hooks = jQuery.cssHooks[name];
+                    if (hooks && "expand" in hooks) {
+                        value = hooks.expand(value);
+                        delete props[name];
+
+                        // Not quite $.extend, this won't overwrite existing keys.
+                        // Reusing 'index' because we have the correct "name"
+                        for (index in value) {
+                            if (!(index in props)) {
+                                props[index] = value[index];
+                                specialEasing[index] = easing;
+                            }
+                        }
+                    } else {
+                        specialEasing[name] = easing;
+                    }
+                }
+            }
+
+            function Animation(elem, properties, options) {
+                var result,
+                    stopped,
+                    index = 0,
+                    length = animationPrefilters.length,
+                    deferred = jQuery.Deferred().always(function() {
+                        // Don't match elem in the :animated selector
+                        delete tick.elem;
+                    }),
+                    tick = function() {
+                        if (stopped) {
+                            return false;
+                        }
+                        var currentTime = fxNow || createFxNow(),
+                            remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
+                            // Support: Android 2.3
+                            // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )`
+                            // (#12497)
+                            temp = remaining / animation.duration || 0,
+                            percent = 1 - temp,
+                            index = 0,
+                            length = animation.tweens.length;
+
+                        for (; index < length; index++) {
+                            animation.tweens[index].run(percent);
+                        }
+
+                        deferred.notifyWith(elem, [animation, percent, remaining]);
+
+                        if (percent < 1 && length) {
+                            return remaining;
+                        } else {
+                            deferred.resolveWith(elem, [animation]);
+                            return false;
+                        }
+                    },
+                    animation = deferred.promise({
+                        elem: elem,
+                        props: jQuery.extend({}, properties),
+                        opts: jQuery.extend(true, {
+                            specialEasing: {}
+                        }, options),
+                        originalProperties: properties,
+                        originalOptions: options,
+                        startTime: fxNow || createFxNow(),
+                        duration: options.duration,
+                        tweens: [],
+                        createTween: function(prop, end) {
+                            var tween = jQuery.Tween(elem, animation.opts, prop, end,
+                                animation.opts.specialEasing[prop] || animation.opts.easing);
+                            animation.tweens.push(tween);
+                            return tween;
+                        },
+                        stop: function(gotoEnd) {
+                            var index = 0,
+                                // If we are going to the end, we want to run all the tweens
+                                // otherwise we skip this part
+                                length = gotoEnd ? animation.tweens.length : 0;
+                            if (stopped) {
+                                return this;
+                            }
+                            stopped = true;
+                            for (; index < length; index++) {
+                                animation.tweens[index].run(1);
+                            }
+
+                            // Resolve when we played the last frame; otherwise, reject
+                            if (gotoEnd) {
+                                deferred.resolveWith(elem, [animation, gotoEnd]);
+                            } else {
+                                deferred.rejectWith(elem, [animation, gotoEnd]);
+                            }
+                            return this;
+                        }
+                    }),
+                    props = animation.props;
+
+                propFilter(props, animation.opts.specialEasing);
+
+                for (; index < length; index++) {
+                    result = animationPrefilters[index].call(animation, elem, props, animation.opts);
+                    if (result) {
+                        return result;
+                    }
+                }
+
+                jQuery.map(props, createTween, animation);
+
+                if (jQuery.isFunction(animation.opts.start)) {
+                    animation.opts.start.call(elem, animation);
+                }
+
+                jQuery.fx.timer(
+                    jQuery.extend(tick, {
+                        elem: elem,
+                        anim: animation,
+                        queue: animation.opts.queue
+                    })
+                );
+
+                // attach callbacks from options
+                return animation.progress(animation.opts.progress)
+                    .done(animation.opts.done, animation.opts.complete)
+                    .fail(animation.opts.fail)
+                    .always(animation.opts.always);
+            }
+
+            jQuery.Animation = jQuery.extend(Animation, {
+
+                tweener: function(props, callback) {
+                    if (jQuery.isFunction(props)) {
+                        callback = props;
+                        props = ["*"];
+                    } else {
+                        props = props.split(" ");
+                    }
+
+                    var prop,
+                        index = 0,
+                        length = props.length;
+
+                    for (; index < length; index++) {
+                        prop = props[index];
+                        tweeners[prop] = tweeners[prop] || [];
+                        tweeners[prop].unshift(callback);
+                    }
+                },
+
+                prefilter: function(callback, prepend) {
+                    if (prepend) {
+                        animationPrefilters.unshift(callback);
+                    } else {
+                        animationPrefilters.push(callback);
+                    }
+                }
+            });
+
+            jQuery.speed = function(speed, easing, fn) {
+                var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+                    complete: fn || !fn && easing ||
+                        jQuery.isFunction(speed) && speed,
+                    duration: speed,
+                    easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+                };
+
+                opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+                    opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+                // Normalize opt.queue - true/undefined/null -> "fx"
+                if (opt.queue == null || opt.queue === true) {
+                    opt.queue = "fx";
+                }
+
+                // Queueing
+                opt.old = opt.complete;
+
+                opt.complete = function() {
+                    if (jQuery.isFunction(opt.old)) {
+                        opt.old.call(this);
+                    }
+
+                    if (opt.queue) {
+                        jQuery.dequeue(this, opt.queue);
+                    }
+                };
+
+                return opt;
+            };
+
+            jQuery.fn.extend({
+                fadeTo: function(speed, to, easing, callback) {
+
+                    // Show any hidden elements after setting opacity to 0
+                    return this.filter(isHidden).css("opacity", 0).show()
+
+                    // Animate to the value specified
+                    .end().animate({
+                        opacity: to
+                    }, speed, easing, callback);
+                },
+                animate: function(prop, speed, easing, callback) {
+                    var empty = jQuery.isEmptyObject(prop),
+                        optall = jQuery.speed(speed, easing, callback),
+                        doAnimation = function() {
+                            // Operate on a copy of prop so per-property easing won't be
+                            // lost
+                            var anim = Animation(this, jQuery.extend({}, prop), optall);
+
+                            // Empty animations, or finishing resolves immediately
+                            if (empty || data_priv.get(this, "finish")) {
+                                anim.stop(true);
+                            }
+                        };
+                    doAnimation.finish = doAnimation;
+
+                    return empty || optall.queue === false ?
+                        this.each(doAnimation) :
+                        this.queue(optall.queue, doAnimation);
+                },
+                stop: function(type, clearQueue, gotoEnd) {
+                    var stopQueue = function(hooks) {
+                        var stop = hooks.stop;
+                        delete hooks.stop;
+                        stop(gotoEnd);
+                    };
+
+                    if (typeof type !== "string") {
+                        gotoEnd = clearQueue;
+                        clearQueue = type;
+                        type = undefined;
+                    }
+                    if (clearQueue && type !== false) {
+                        this.queue(type || "fx", []);
+                    }
+
+                    return this.each(function() {
+                        var dequeue = true,
+                            index = type != null && type + "queueHooks",
+                            timers = jQuery.timers,
+                            data = data_priv.get(this);
+
+                        if (index) {
+                            if (data[index] && data[index].stop) {
+                                stopQueue(data[index]);
+                            }
+                        } else {
+                            for (index in data) {
+                                if (data[index] && data[index].stop && rrun.test(index)) {
+                                    stopQueue(data[index]);
+                                }
+                            }
+                        }
+
+                        for (index = timers.length; index--;) {
+                            if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
+                                timers[index].anim.stop(gotoEnd);
+                                dequeue = false;
+                                timers.splice(index, 1);
+                            }
+                        }
+
+                        // Start the next in the queue if the last step wasn't forced.
+                        // Timers currently will call their complete callbacks, which
+                        // will dequeue but only if they were gotoEnd.
+                        if (dequeue || !gotoEnd) {
+                            jQuery.dequeue(this, type);
+                        }
+                    });
+                },
+                finish: function(type) {
+                    if (type !== false) {
+                        type = type || "fx";
+                    }
+                    return this.each(function() {
+                        var index,
+                            data = data_priv.get(this),
+                            queue = data[type + "queue"],
+                            hooks = data[type + "queueHooks"],
+                            timers = jQuery.timers,
+                            length = queue ? queue.length : 0;
+
+                        // Enable finishing flag on private data
+                        data.finish = true;
+
+                        // Empty the queue first
+                        jQuery.queue(this, type, []);
+
+                        if (hooks && hooks.stop) {
+                            hooks.stop.call(this, true);
+                        }
+
+                        // Look for any active animations, and finish them
+                        for (index = timers.length; index--;) {
+                            if (timers[index].elem === this && timers[index].queue === type) {
+                                timers[index].anim.stop(true);
+                                timers.splice(index, 1);
+                            }
+                        }
+
+                        // Look for any animations in the old queue and finish them
+                        for (index = 0; index < length; index++) {
+                            if (queue[index] && queue[index].finish) {
+                                queue[index].finish.call(this);
+                            }
+                        }
+
+                        // Turn off finishing flag
+                        delete data.finish;
+                    });
+                }
+            });
+
+            jQuery.each(["toggle", "show", "hide"], function(i, name) {
+                var cssFn = jQuery.fn[name];
+                jQuery.fn[name] = function(speed, easing, callback) {
+                    return speed == null || typeof speed === "boolean" ?
+                        cssFn.apply(this, arguments) :
+                        this.animate(genFx(name, true), speed, easing, callback);
+                };
+            });
+
+            // Generate shortcuts for custom animations
+            jQuery.each({
+                slideDown: genFx("show"),
+                slideUp: genFx("hide"),
+                slideToggle: genFx("toggle"),
+                fadeIn: {
+                    opacity: "show"
+                },
+                fadeOut: {
+                    opacity: "hide"
+                },
+                fadeToggle: {
+                    opacity: "toggle"
+                }
+            }, function(name, props) {
+                jQuery.fn[name] = function(speed, easing, callback) {
+                    return this.animate(props, speed, easing, callback);
+                };
+            });
+
+            jQuery.timers = [];
+            jQuery.fx.tick = function() {
+                var timer,
+                    i = 0,
+                    timers = jQuery.timers;
+
+                fxNow = jQuery.now();
+
+                for (; i < timers.length; i++) {
+                    timer = timers[i];
+                    // Checks the timer has not already been removed
+                    if (!timer() && timers[i] === timer) {
+                        timers.splice(i--, 1);
+                    }
+                }
+
+                if (!timers.length) {
+                    jQuery.fx.stop();
+                }
+                fxNow = undefined;
+            };
+
+            jQuery.fx.timer = function(timer) {
+                jQuery.timers.push(timer);
+                if (timer()) {
+                    jQuery.fx.start();
+                } else {
+                    jQuery.timers.pop();
+                }
+            };
+
+            jQuery.fx.interval = 13;
+
+            jQuery.fx.start = function() {
+                if (!timerId) {
+                    timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval);
+                }
+            };
+
+            jQuery.fx.stop = function() {
+                clearInterval(timerId);
+                timerId = null;
+            };
+
+            jQuery.fx.speeds = {
+                slow: 600,
+                fast: 200,
+                // Default speed
+                _default: 400
+            };
+
+
+            // Based off of the plugin by Clint Helfers, with permission.
+            // http://blindsignals.com/index.php/2009/07/jquery-delay/
+            jQuery.fn.delay = function(time, type) {
+                time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+                type = type || "fx";
+
+                return this.queue(type, function(next, hooks) {
+                    var timeout = setTimeout(next, time);
+                    hooks.stop = function() {
+                        clearTimeout(timeout);
+                    };
+                });
+            };
+
+
+            (function() {
+                var input = document.createElement("input"),
+                    select = document.createElement("select"),
+                    opt = select.appendChild(document.createElement("option"));
+
+                input.type = "checkbox";
+
+                // Support: iOS<=5.1, Android<=4.2+
+                // Default value for a checkbox should be "on"
+                support.checkOn = input.value !== "";
+
+                // Support: IE<=11+
+                // Must access selectedIndex to make default options select
+                support.optSelected = opt.selected;
+
+                // Support: Android<=2.3
+                // Options inside disabled selects are incorrectly marked as disabled
+                select.disabled = true;
+                support.optDisabled = !opt.disabled;
+
+                // Support: IE<=11+
+                // An input loses its value after becoming a radio
+                input = document.createElement("input");
+                input.value = "t";
+                input.type = "radio";
+                support.radioValue = input.value === "t";
+            })();
+
+
+            var nodeHook, boolHook,
+                attrHandle = jQuery.expr.attrHandle;
+
+            jQuery.fn.extend({
+                attr: function(name, value) {
+                    return access(this, jQuery.attr, name, value, arguments.length > 1);
+                },
+
+                removeAttr: function(name) {
+                    return this.each(function() {
+                        jQuery.removeAttr(this, name);
+                    });
+                }
+            });
+
+            jQuery.extend({
+                attr: function(elem, name, value) {
+                    var hooks, ret,
+                        nType = elem.nodeType;
+
+                    // don't get/set attributes on text, comment and attribute nodes
+                    if (!elem || nType === 3 || nType === 8 || nType === 2) {
+                        return;
+                    }
+
+                    // Fallback to prop when attributes are not supported
+                    if (typeof elem.getAttribute === strundefined) {
+                        return jQuery.prop(elem, name, value);
+                    }
+
+                    // All attributes are lowercase
+                    // Grab necessary hook if one is defined
+                    if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
+                        name = name.toLowerCase();
+                        hooks = jQuery.attrHooks[name] ||
+                            (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook);
+                    }
+
+                    if (value !== undefined) {
+
+                        if (value === null) {
+                            jQuery.removeAttr(elem, name);
+
+                        } else if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
+                            return ret;
+
+                        } else {
+                            elem.setAttribute(name, value + "");
+                            return value;
+                        }
+
+                    } else if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
+                        return ret;
+
+                    } else {
+                        ret = jQuery.find.attr(elem, name);
+
+                        // Non-existent attributes return null, we normalize to undefined
+                        return ret == null ?
+                            undefined :
+                            ret;
+                    }
+                },
+
+                removeAttr: function(elem, value) {
+                    var name, propName,
+                        i = 0,
+                        attrNames = value && value.match(rnotwhite);
+
+                    if (attrNames && elem.nodeType === 1) {
+                        while ((name = attrNames[i++])) {
+                            propName = jQuery.propFix[name] || name;
+
+                            // Boolean attributes get special treatment (#10870)
+                            if (jQuery.expr.match.bool.test(name)) {
+                                // Set corresponding property to false
+                                elem[propName] = false;
+                            }
+
+                            elem.removeAttribute(name);
+                        }
+                    }
+                },
+
+                attrHooks: {
+                    type: {
+                        set: function(elem, value) {
+                            if (!support.radioValue && value === "radio" &&
+                                jQuery.nodeName(elem, "input")) {
+                                var val = elem.value;
+                                elem.setAttribute("type", value);
+                                if (val) {
+                                    elem.value = val;
+                                }
+                                return value;
+                            }
+                        }
+                    }
+                }
+            });
+
+            // Hooks for boolean attributes
+            boolHook = {
+                set: function(elem, value, name) {
+                    if (value === false) {
+                        // Remove boolean attributes when set to false
+                        jQuery.removeAttr(elem, name);
+                    } else {
+                        elem.setAttribute(name, name);
+                    }
+                    return name;
+                }
+            };
+            jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function(i, name) {
+                var getter = attrHandle[name] || jQuery.find.attr;
+
+                attrHandle[name] = function(elem, name, isXML) {
+                    var ret, handle;
+                    if (!isXML) {
+                        // Avoid an infinite loop by temporarily removing this function from
+                        // the getter
+                        handle = attrHandle[name];
+                        attrHandle[name] = ret;
+                        ret = getter(elem, name, isXML) != null ?
+                            name.toLowerCase() :
+                            null;
+                        attrHandle[name] = handle;
+                    }
+                    return ret;
+                };
+            });
+
+
+
+
+            var rfocusable = /^(?:input|select|textarea|button)$/i;
+
+            jQuery.fn.extend({
+                prop: function(name, value) {
+                    return access(this, jQuery.prop, name, value, arguments.length > 1);
+                },
+
+                removeProp: function(name) {
+                    return this.each(function() {
+                        delete this[jQuery.propFix[name] || name];
+                    });
+                }
+            });
+
+            jQuery.extend({
+                propFix: {
+                    "for": "htmlFor",
+                    "class": "className"
+                },
+
+                prop: function(elem, name, value) {
+                    var ret, hooks, notxml,
+                        nType = elem.nodeType;
+
+                    // Don't get/set properties on text, comment and attribute nodes
+                    if (!elem || nType === 3 || nType === 8 || nType === 2) {
+                        return;
+                    }
+
+                    notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
+
+                    if (notxml) {
+                        // Fix name and attach hooks
+                        name = jQuery.propFix[name] || name;
+                        hooks = jQuery.propHooks[name];
+                    }
+
+                    if (value !== undefined) {
+                        return hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined ?
+                            ret :
+                            (elem[name] = value);
+
+                    } else {
+                        return hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null ?
+                            ret :
+                            elem[name];
+                    }
+                },
+
+                propHooks: {
+                    tabIndex: {
+                        get: function(elem) {
+                            return elem.hasAttribute("tabindex") || rfocusable.test(elem.nodeName) || elem.href ?
+                                elem.tabIndex :
+                                -1;
+                        }
+                    }
+                }
+            });
+
+            if (!support.optSelected) {
+                jQuery.propHooks.selected = {
+                    get: function(elem) {
+                        var parent = elem.parentNode;
+                        if (parent && parent.parentNode) {
+                            parent.parentNode.selectedIndex;
+                        }
+                        return null;
+                    }
+                };
+            }
+
+            jQuery.each([
+                "tabIndex",
+                "readOnly",
+                "maxLength",
+                "cellSpacing",
+                "cellPadding",
+                "rowSpan",
+                "colSpan",
+                "useMap",
+                "frameBorder",
+                "contentEditable"
+            ], function() {
+                jQuery.propFix[this.toLowerCase()] = this;
+            });
+
+
+
+
+            var rclass = /[\t\r\n\f]/g;
+
+            jQuery.fn.extend({
+                addClass: function(value) {
+                    var classes, elem, cur, clazz, j, finalValue,
+                        proceed = typeof value === "string" && value,
+                        i = 0,
+                        len = this.length;
+
+                    if (jQuery.isFunction(value)) {
+                        return this.each(function(j) {
+                            jQuery(this).addClass(value.call(this, j, this.className));
+                        });
+                    }
+
+                    if (proceed) {
+                        // The disjunction here is for better compressibility (see
+                        // removeClass)
+                        classes = (value || "").match(rnotwhite) || [];
+
+                        for (; i < len; i++) {
+                            elem = this[i];
+                            cur = elem.nodeType === 1 && (elem.className ?
+                                (" " + elem.className + " ").replace(rclass, " ") :
+                                " "
+                            );
+
+                            if (cur) {
+                                j = 0;
+                                while ((clazz = classes[j++])) {
+                                    if (cur.indexOf(" " + clazz + " ") < 0) {
+                                        cur += clazz + " ";
+                                    }
+                                }
+
+                                // only assign if different to avoid unneeded rendering.
+                                finalValue = jQuery.trim(cur);
+                                if (elem.className !== finalValue) {
+                                    elem.className = finalValue;
+                                }
+                            }
+                        }
+                    }
+
+                    return this;
+                },
+
+                removeClass: function(value) {
+                    var classes, elem, cur, clazz, j, finalValue,
+                        proceed = arguments.length === 0 || typeof value === "string" && value,
+                        i = 0,
+                        len = this.length;
+
+                    if (jQuery.isFunction(value)) {
+                        return this.each(function(j) {
+                            jQuery(this).removeClass(value.call(this, j, this.className));
+                        });
+                    }
+                    if (proceed) {
+                        classes = (value || "").match(rnotwhite) || [];
+
+                        for (; i < len; i++) {
+                            elem = this[i];
+                            // This expression is here for better compressibility (see
+                            // addClass)
+                            cur = elem.nodeType === 1 && (elem.className ?
+                                (" " + elem.className + " ").replace(rclass, " ") :
+                                ""
+                            );
+
+                            if (cur) {
+                                j = 0;
+                                while ((clazz = classes[j++])) {
+                                    // Remove *all* instances
+                                    while (cur.indexOf(" " + clazz + " ") >= 0) {
+                                        cur = cur.replace(" " + clazz + " ", " ");
+                                    }
+                                }
+
+                                // Only assign if different to avoid unneeded rendering.
+                                finalValue = value ? jQuery.trim(cur) : "";
+                                if (elem.className !== finalValue) {
+                                    elem.className = finalValue;
+                                }
+                            }
+                        }
+                    }
+
+                    return this;
+                },
+
+                toggleClass: function(value, stateVal) {
+                    var type = typeof value;
+
+                    if (typeof stateVal === "boolean" && type === "string") {
+                        return stateVal ? this.addClass(value) : this.removeClass(value);
+                    }
+
+                    if (jQuery.isFunction(value)) {
+                        return this.each(function(i) {
+                            jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal);
+                        });
+                    }
+
+                    return this.each(function() {
+                        if (type === "string") {
+                            // Toggle individual class names
+                            var className,
+                                i = 0,
+                                self = jQuery(this),
+                                classNames = value.match(rnotwhite) || [];
+
+                            while ((className = classNames[i++])) {
+                                // Check each className given, space separated list
+                                if (self.hasClass(className)) {
+                                    self.removeClass(className);
+                                } else {
+                                    self.addClass(className);
+                                }
+                            }
+
+                            // Toggle whole class name
+                        } else if (type === strundefined || type === "boolean") {
+                            if (this.className) {
+                                // store className if set
+                                data_priv.set(this, "__className__", this.className);
+                            }
+
+                            // If the element has a class name or if we're passed `false`,
+                            // then remove the whole classname (if there was one, the above
+                            // saved it).
+                            // Otherwise bring back whatever was previously saved (if
+                            // anything),
+                            // falling back to the empty string if nothing was stored.
+                            this.className = this.className || value === false ? "" : data_priv.get(this, "__className__") || "";
+                        }
+                    });
+                },
+
+                hasClass: function(selector) {
+                    var className = " " + selector + " ",
+                        i = 0,
+                        l = this.length;
+                    for (; i < l; i++) {
+                        if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+            });
+
+
+
+
+            var rreturn = /\r/g;
+
+            jQuery.fn.extend({
+                val: function(value) {
+                    var hooks, ret, isFunction,
+                        elem = this[0];
+
+                    if (!arguments.length) {
+                        if (elem) {
+                            hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
+
+                            if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
+                                return ret;
+                            }
+
+                            ret = elem.value;
+
+                            return typeof ret === "string" ?
+                                // Handle most common string cases
+                                ret.replace(rreturn, "") :
+                                // Handle cases where value is null/undef or number
+                                ret == null ? "" : ret;
+                        }
+
+                        return;
+                    }
+
+                    isFunction = jQuery.isFunction(value);
+
+                    return this.each(function(i) {
+                        var val;
+
+                        if (this.nodeType !== 1) {
+                            return;
+                        }
+
+                        if (isFunction) {
+                            val = value.call(this, i, jQuery(this).val());
+                        } else {
+                            val = value;
+                        }
+
+                        // Treat null/undefined as ""; convert numbers to string
+                        if (val == null) {
+                            val = "";
+
+                        } else if (typeof val === "number") {
+                            val += "";
+
+                        } else if (jQuery.isArray(val)) {
+                            val = jQuery.map(val, function(value) {
+                                return value == null ? "" : value + "";
+                            });
+                        }
+
+                        hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
+
+                        // If set returns undefined, fall back to normal setting
+                        if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
+                            this.value = val;
+                        }
+                    });
+                }
+            });
+
+            jQuery.extend({
+                valHooks: {
+                    option: {
+                        get: function(elem) {
+                            var val = jQuery.find.attr(elem, "value");
+                            return val != null ?
+                                val :
+                                // Support: IE10-11+
+                                // option.text throws exceptions (#14686, #14858)
+                                jQuery.trim(jQuery.text(elem));
+                        }
+                    },
+                    select: {
+                        get: function(elem) {
+                            var value, option,
+                                options = elem.options,
+                                index = elem.selectedIndex,
+                                one = elem.type === "select-one" || index < 0,
+                                values = one ? null : [],
+                                max = one ? index + 1 : options.length,
+                                i = index < 0 ?
+                                max :
+                                one ? index : 0;
+
+                            // Loop through all the selected options
+                            for (; i < max; i++) {
+                                option = options[i];
+
+                                // IE6-9 doesn't update selected after form reset (#2551)
+                                if ((option.selected || i === index) &&
+                                    // Don't return options that are disabled or in a
+                                    // disabled optgroup
+                                    (support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+                                    (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
+
+                                    // Get the specific value for the option
+                                    value = jQuery(option).val();
+
+                                    // We don't need an array for one selects
+                                    if (one) {
+                                        return value;
+                                    }
+
+                                    // Multi-Selects return an array
+                                    values.push(value);
+                                }
+                            }
+
+                            return values;
+                        },
+
+                        set: function(elem, value) {
+                            var optionSet, option,
+                                options = elem.options,
+                                values = jQuery.makeArray(value),
+                                i = options.length;
+
+                            while (i--) {
+                                option = options[i];
+                                if ((option.selected = jQuery.inArray(option.value, values) >= 0)) {
+                                    optionSet = true;
+                                }
+                            }
+
+                            // Force browsers to behave consistently when non-matching value
+                            // is set
+                            if (!optionSet) {
+                                elem.selectedIndex = -1;
+                            }
+                            return values;
+                        }
+                    }
+                }
+            });
+
+            // Radios and checkboxes getter/setter
+            jQuery.each(["radio", "checkbox"], function() {
+                jQuery.valHooks[this] = {
+                    set: function(elem, value) {
+                        if (jQuery.isArray(value)) {
+                            return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0);
+                        }
+                    }
+                };
+                if (!support.checkOn) {
+                    jQuery.valHooks[this].get = function(elem) {
+                        return elem.getAttribute("value") === null ? "on" : elem.value;
+                    };
+                }
+            });
+
+
+
+
+            // Return jQuery for attributes-only inclusion
+
+
+            jQuery.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(i, name) {
+
+                // Handle event binding
+                jQuery.fn[name] = function(data, fn) {
+                    return arguments.length > 0 ?
+                        this.on(name, null, data, fn) :
+                        this.trigger(name);
+                };
+            });
+
+            jQuery.fn.extend({
+                hover: function(fnOver, fnOut) {
+                    return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
+                },
+
+                bind: function(types, data, fn) {
+                    return this.on(types, null, data, fn);
+                },
+                unbind: function(types, fn) {
+                    return this.off(types, null, fn);
+                },
+
+                delegate: function(selector, types, data, fn) {
+                    return this.on(types, selector, data, fn);
+                },
+                undelegate: function(selector, types, fn) {
+                    // ( namespace ) or ( selector, types [, fn] )
+                    return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
+                }
+            });
+
+
+            var nonce = jQuery.now();
+
+            var rquery = (/\?/);
+
+
+
+            // Support: Android 2.3
+            // Workaround failure to string-cast null input
+            jQuery.parseJSON = function(data) {
+                return JSON.parse(data + "");
+            };
+
+
+            // Cross-browser xml parsing
+            jQuery.parseXML = function(data) {
+                var xml, tmp;
+                if (!data || typeof data !== "string") {
+                    return null;
+                }
+
+                // Support: IE9
+                try {
+                    tmp = new DOMParser();
+                    xml = tmp.parseFromString(data, "text/xml");
+                } catch (e) {
+                    xml = undefined;
+                }
+
+                if (!xml || xml.getElementsByTagName("parsererror").length) {
+                    jQuery.error("Invalid XML: " + data);
+                }
+                return xml;
+            };
+
+
+            var
+                rhash = /#.*$/,
+                rts = /([?&])_=[^&]*/,
+                rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
+                // #7653, #8125, #8152: local protocol detection
+                rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+                rnoContent = /^(?:GET|HEAD)$/,
+                rprotocol = /^\/\//,
+                rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
+
+                /*
+                 * Prefilters 1) They are useful to introduce custom dataTypes (see
+                 * ajax/jsonp.js for an example) 2) These are called: - BEFORE asking for a
+                 * transport - AFTER param serialization (s.data is a string if
+                 * s.processData is true) 3) key is the dataType 4) the catchall symbol "*"
+                 * can be used 5) execution will start with transport dataType and THEN
+                 * continue down to "*" if needed
+                 */
+                prefilters = {},
+
+                /*
+                 * Transports bindings 1) key is the dataType 2) the catchall symbol "*" can
+                 * be used 3) selection will start with transport dataType and THEN go to
+                 * "*" if needed
+                 */
+                transports = {},
+
+                // Avoid comment-prolog char sequence (#10098); must appease lint and evade
+                // compression
+                allTypes = "*/".concat("*"),
+
+                // Document location
+                ajaxLocation = window.location.href,
+
+                // Segment location into parts
+                ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
+
+            // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+            function addToPrefiltersOrTransports(structure) {
+
+                // dataTypeExpression is optional and defaults to "*"
+                return function(dataTypeExpression, func) {
+
+                    if (typeof dataTypeExpression !== "string") {
+                        func = dataTypeExpression;
+                        dataTypeExpression = "*";
+                    }
+
+                    var dataType,
+                        i = 0,
+                        dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];
+
+                    if (jQuery.isFunction(func)) {
+                        // For each dataType in the dataTypeExpression
+                        while ((dataType = dataTypes[i++])) {
+                            // Prepend if requested
+                            if (dataType[0] === "+") {
+                                dataType = dataType.slice(1) || "*";
+                                (structure[dataType] = structure[dataType] || []).unshift(func);
+
+                                // Otherwise append
+                            } else {
+                                (structure[dataType] = structure[dataType] || []).push(func);
+                            }
+                        }
+                    }
+                };
+            }
+
+            // Base inspection function for prefilters and transports
+            function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
+
+                var inspected = {},
+                    seekingTransport = (structure === transports);
+
+                function inspect(dataType) {
+                    var selected;
+                    inspected[dataType] = true;
+                    jQuery.each(structure[dataType] || [], function(_, prefilterOrFactory) {
+                        var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
+                        if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
+                            options.dataTypes.unshift(dataTypeOrTransport);
+                            inspect(dataTypeOrTransport);
+                            return false;
+                        } else if (seekingTransport) {
+                            return !(selected = dataTypeOrTransport);
+                        }
+                    });
+                    return selected;
+                }
+
+                return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
+            }
+
+            // A special extend for ajax options
+            // that takes "flat" options (not to be deep extended)
+            // Fixes #9887
+            function ajaxExtend(target, src) {
+                var key, deep,
+                    flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+                for (key in src) {
+                    if (src[key] !== undefined) {
+                        (flatOptions[key] ? target : (deep || (deep = {})))[key] = src[key];
+                    }
+                }
+                if (deep) {
+                    jQuery.extend(true, target, deep);
+                }
+
+                return target;
+            }
+
+            /*
+             * Handles responses to an ajax request: - finds the right dataType (mediates
+             * between content-type and expected dataType) - returns the corresponding
+             * response
+             */
+            function ajaxHandleResponses(s, jqXHR, responses) {
+
+                var ct, type, finalDataType, firstDataType,
+                    contents = s.contents,
+                    dataTypes = s.dataTypes;
+
+                // Remove auto dataType and get content-type in the process
+                while (dataTypes[0] === "*") {
+                    dataTypes.shift();
+                    if (ct === undefined) {
+                        ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+                    }
+                }
+
+                // Check if we're dealing with a known content-type
+                if (ct) {
+                    for (type in contents) {
+                        if (contents[type] && contents[type].test(ct)) {
+                            dataTypes.unshift(type);
+                            break;
+                        }
+                    }
+                }
+
+                // Check to see if we have a response for the expected dataType
+                if (dataTypes[0] in responses) {
+                    finalDataType = dataTypes[0];
+                } else {
+                    // Try convertible dataTypes
+                    for (type in responses) {
+                        if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
+                            finalDataType = type;
+                            break;
+                        }
+                        if (!firstDataType) {
+                            firstDataType = type;
+                        }
+                    }
+                    // Or just use first one
+                    finalDataType = finalDataType || firstDataType;
+                }
+
+                // If we found a dataType
+                // We add the dataType to the list if needed
+                // and return the corresponding response
+                if (finalDataType) {
+                    if (finalDataType !== dataTypes[0]) {
+                        dataTypes.unshift(finalDataType);
+                    }
+                    return responses[finalDataType];
+                }
+            }
+
+            /*
+             * Chain conversions given the request and the original response Also sets the
+             * responseXXX fields on the jqXHR instance
+             */
+            function ajaxConvert(s, response, jqXHR, isSuccess) {
+                var conv2, current, conv, tmp, prev,
+                    converters = {},
+                    // Work with a copy of dataTypes in case we need to modify it for
+                    // conversion
+                    dataTypes = s.dataTypes.slice();
+
+                // Create converters map with lowercased keys
+                if (dataTypes[1]) {
+                    for (conv in s.converters) {
+                        converters[conv.toLowerCase()] = s.converters[conv];
+                    }
+                }
+
+                current = dataTypes.shift();
+
+                // Convert to each sequential dataType
+                while (current) {
+
+                    if (s.responseFields[current]) {
+                        jqXHR[s.responseFields[current]] = response;
+                    }
+
+                    // Apply the dataFilter if provided
+                    if (!prev && isSuccess && s.dataFilter) {
+                        response = s.dataFilter(response, s.dataType);
+                    }
+
+                    prev = current;
+                    current = dataTypes.shift();
+
+                    if (current) {
+
+                        // There's only work to do if current dataType is non-auto
+                        if (current === "*") {
+
+                            current = prev;
+
+                            // Convert response if prev dataType is non-auto and differs from
+                            // current
+                        } else if (prev !== "*" && prev !== current) {
+
+                            // Seek a direct converter
+                            conv = converters[prev + " " + current] || converters["* " + current];
+
+                            // If none found, seek a pair
+                            if (!conv) {
+                                for (conv2 in converters) {
+
+                                    // If conv2 outputs current
+                                    tmp = conv2.split(" ");
+                                    if (tmp[1] === current) {
+
+                                        // If prev can be converted to accepted input
+                                        conv = converters[prev + " " + tmp[0]] ||
+                                            converters["* " + tmp[0]];
+                                        if (conv) {
+                                            // Condense equivalence converters
+                                            if (conv === true) {
+                                                conv = converters[conv2];
+
+                                                // Otherwise, insert the intermediate dataType
+                                            } else if (converters[conv2] !== true) {
+                                                current = tmp[0];
+                                                dataTypes.unshift(tmp[1]);
+                                            }
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+
+                            // Apply converter (if not an equivalence)
+                            if (conv !== true) {
+
+                                // Unless errors are allowed to bubble, catch and return
+                                // them
+                                if (conv && s["throws"]) {
+                                    response = conv(response);
+                                } else {
+                                    try {
+                                        response = conv(response);
+                                    } catch (e) {
+                                        return {
+                                            state: "parsererror",
+                                            error: conv ? e : "No conversion from " + prev + " to " + current
+                                        };
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                return {
+                    state: "success",
+                    data: response
+                };
+            }
+
+            jQuery.extend({
+
+                // Counter for holding the number of active queries
+                active: 0,
+
+                // Last-Modified header cache for next request
+                lastModified: {},
+                etag: {},
+
+                ajaxSettings: {
+                    url: ajaxLocation,
+                    type: "GET",
+                    isLocal: rlocalProtocol.test(ajaxLocParts[1]),
+                    global: true,
+                    processData: true,
+                    async: true,
+                    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+                    /*
+                     * timeout: 0, data: null, dataType: null, username: null, password:
+                     * null, cache: null, throws: false, traditional: false, headers: {},
+                     */
+
+                    accepts: {
+                        "*": allTypes,
+                        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"
+                    },
+
+                    // Data converters
+                    // Keys separate source (or catchall "*") and destination types with a
+                    // single space
+                    converters: {
+
+                        // Convert anything to text
+                        "* text": String,
+
+                        // Text to html (true = no transformation)
+                        "text html": true,
+
+                        // Evaluate text as a json expression
+                        "text json": jQuery.parseJSON,
+
+                        // Parse text as xml
+                        "text xml": jQuery.parseXML
+                    },
+
+                    // For options that shouldn't be deep extended:
+                    // you can add your own custom options here if
+                    // and when you create one that shouldn't be
+                    // deep extended (see ajaxExtend)
+                    flatOptions: {
+                        url: true,
+                        context: true
+                    }
+                },
+
+                // Creates a full fledged settings object into target
+                // with both ajaxSettings and settings fields.
+                // If target is omitted, writes into ajaxSettings.
+                ajaxSetup: function(target, settings) {
+                    return settings ?
+
+                        // Building a settings object
+                        ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
+
+                        // Extending ajaxSettings
+                        ajaxExtend(jQuery.ajaxSettings, target);
+                },
+
+                ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
+                ajaxTransport: addToPrefiltersOrTransports(transports),
+
+                // Main method
+                ajax: function(url, options) {
+
+                    // If url is an object, simulate pre-1.5 signature
+                    if (typeof url === "object") {
+                        options = url;
+                        url = undefined;
+                    }
+
+                    // Force options to be an object
+                    options = options || {};
+
+                    var transport,
+                        // URL without anti-cache param
+                        cacheURL,
+                        // Response headers
+                        responseHeadersString,
+                        responseHeaders,
+                        // timeout handle
+                        timeoutTimer,
+                        // Cross-domain detection vars
+                        parts,
+                        // To know if global events are to be dispatched
+                        fireGlobals,
+                        // Loop variable
+                        i,
+                        // Create the final options object
+                        s = jQuery.ajaxSetup({}, options),
+                        // Callbacks context
+                        callbackContext = s.context || s,
+                        // Context for global events is callbackContext if it is a DOM node
+                        // or jQuery collection
+                        globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ?
+                        jQuery(callbackContext) :
+                        jQuery.event,
+                        // Deferreds
+                        deferred = jQuery.Deferred(),
+                        completeDeferred = jQuery.Callbacks("once memory"),
+                        // Status-dependent callbacks
+                        statusCode = s.statusCode || {},
+                        // Headers (they are sent all at once)
+                        requestHeaders = {},
+                        requestHeadersNames = {},
+                        // The jqXHR state
+                        state = 0,
+                        // Default abort message
+                        strAbort = "canceled",
+                        // Fake xhr
+                        jqXHR = {
+                            readyState: 0,
+
+                            // Builds headers hashtable if needed
+                            getResponseHeader: function(key) {
+                                var match;
+                                if (state === 2) {
+                                    if (!responseHeaders) {
+                                        responseHeaders = {};
+                                        while ((match = rheaders.exec(responseHeadersString))) {
+                                            responseHeaders[match[1].toLowerCase()] = match[2];
+                                        }
+                                    }
+                                    match = responseHeaders[key.toLowerCase()];
+                                }
+                                return match == null ? null : match;
+                            },
+
+                            // Raw string
+                            getAllResponseHeaders: function() {
+                                return state === 2 ? responseHeadersString : null;
+                            },
+
+                            // Caches the header
+                            setRequestHeader: function(name, value) {
+                                var lname = name.toLowerCase();
+                                if (!state) {
+                                    name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
+                                    requestHeaders[name] = value;
+                                }
+                                return this;
+                            },
+
+                            // Overrides response content-type header
+                            overrideMimeType: function(type) {
+                                if (!state) {
+                                    s.mimeType = type;
+                                }
+                                return this;
+                            },
+
+                            // Status-dependent callbacks
+                            statusCode: function(map) {
+                                var code;
+                                if (map) {
+                                    if (state < 2) {
+                                        for (code in map) {
+                                            // Lazy-add the new callback in a way that
+                                            // preserves old ones
+                                            statusCode[code] = [statusCode[code], map[code]];
+                                        }
+                                    } else {
+                                        // Execute the appropriate callbacks
+                                        jqXHR.always(map[jqXHR.status]);
+                                    }
+                                }
+                                return this;
+                            },
+
+                            // Cancel the request
+                            abort: function(statusText) {
+                                var finalText = statusText || strAbort;
+                                if (transport) {
+                                    transport.abort(finalText);
+                                }
+                                done(0, finalText);
+                                return this;
+                            }
+                        };
+
+                    // Attach deferreds
+                    deferred.promise(jqXHR).complete = completeDeferred.add;
+                    jqXHR.success = jqXHR.done;
+                    jqXHR.error = jqXHR.fail;
+
+                    // Remove hash character (#7531: and string promotion)
+                    // Add protocol if not provided (prefilters might expect it)
+                    // Handle falsy url in the settings object (#10093: consistency with old
+                    // signature)
+                    // We also use the url parameter if available
+                    s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "")
+                        .replace(rprotocol, ajaxLocParts[1] + "//");
+
+                    // Alias method option to type as per ticket #12004
+                    s.type = options.method || options.type || s.method || s.type;
+
+                    // Extract dataTypes list
+                    s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""];
+
+                    // A cross-domain request is in order when we have a protocol:host:port
+                    // mismatch
+                    if (s.crossDomain == null) {
+                        parts = rurl.exec(s.url.toLowerCase());
+                        s.crossDomain = !!(parts &&
+                            (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] ||
+                                (parts[3] || (parts[1] === "http:" ? "80" : "443")) !==
+                                (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443")))
+                        );
+                    }
+
+                    // Convert data if not already a string
+                    if (s.data && s.processData && typeof s.data !== "string") {
+                        s.data = jQuery.param(s.data, s.traditional);
+                    }
+
+                    // Apply prefilters
+                    inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
+
+                    // If request was aborted inside a prefilter, stop there
+                    if (state === 2) {
+                        return jqXHR;
+                    }
+
+                    // We can fire global events as of now if asked to
+                    // Don't fire events if jQuery.event is undefined in an AMD-usage
+                    // scenario (#15118)
+                    fireGlobals = jQuery.event && s.global;
+
+                    // Watch for a new set of requests
+                    if (fireGlobals && jQuery.active++ === 0) {
+                        jQuery.event.trigger("ajaxStart");
+                    }
+
+                    // Uppercase the type
+                    s.type = s.type.toUpperCase();
+
+                    // Determine if request has content
+                    s.hasContent = !rnoContent.test(s.type);
+
+                    // Save the URL in case we're toying with the If-Modified-Since
+                    // and/or If-None-Match header later on
+                    cacheURL = s.url;
+
+                    // More options handling for requests with no content
+                    if (!s.hasContent) {
+
+                        // If data is available, append data to url
+                        if (s.data) {
+                            cacheURL = (s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data);
+                            // #9682: remove data so that it's not used in an eventual retry
+                            delete s.data;
+                        }
+
+                        // Add anti-cache in url if needed
+                        if (s.cache === false) {
+                            s.url = rts.test(cacheURL) ?
+
+                                // If there is already a '_' parameter, set its value
+                                cacheURL.replace(rts, "$1_=" + nonce++) :
+
+                                // Otherwise add one to the end
+                                cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++;
+                        }
+                    }
+
+                    // Set the If-Modified-Since and/or If-None-Match header, if in
+                    // ifModified mode.
+                    if (s.ifModified) {
+                        if (jQuery.lastModified[cacheURL]) {
+                            jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
+                        }
+                        if (jQuery.etag[cacheURL]) {
+                            jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
+                        }
+                    }
+
+                    // Set the correct header, if data is being sent
+                    if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
+                        jqXHR.setRequestHeader("Content-Type", s.contentType);
+                    }
+
+                    // Set the Accepts header for the server, depending on the dataType
+                    jqXHR.setRequestHeader(
+                        "Accept",
+                        s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
+                        s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") :
+                        s.accepts["*"]
+                    );
+
+                    // Check for headers option
+                    for (i in s.headers) {
+                        jqXHR.setRequestHeader(i, s.headers[i]);
+                    }
+
+                    // Allow custom headers/mimetypes and early abort
+                    if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
+                        // Abort if not done already and return
+                        return jqXHR.abort();
+                    }
+
+                    // Aborting is no longer a cancellation
+                    strAbort = "abort";
+
+                    // Install callbacks on deferreds
+                    for (i in {
+                            success: 1,
+                            error: 1,
+                            complete: 1
+                        }) {
+                        jqXHR[i](s[i]);
+                    }
+
+                    // Get transport
+                    transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
+
+                    // If no transport, we auto-abort
+                    if (!transport) {
+                        done(-1, "No Transport");
+                    } else {
+                        jqXHR.readyState = 1;
+
+                        // Send global event
+                        if (fireGlobals) {
+                            globalEventContext.trigger("ajaxSend", [jqXHR, s]);
+                        }
+                        // Timeout
+                        if (s.async && s.timeout > 0) {
+                            timeoutTimer = setTimeout(function() {
+                                jqXHR.abort("timeout");
+                            }, s.timeout);
+                        }
+
+                        try {
+                            state = 1;
+                            transport.send(requestHeaders, done);
+                        } catch (e) {
+                            // Propagate exception as error if not done
+                            if (state < 2) {
+                                done(-1, e);
+                                // Simply rethrow otherwise
+                            } else {
+                                throw e;
+                            }
+                        }
+                    }
+
+                    // Callback for when everything is done
+                    function done(status, nativeStatusText, responses, headers) {
+                        var isSuccess, success, error, response, modified,
+                            statusText = nativeStatusText;
+
+                        // Called once
+                        if (state === 2) {
+                            return;
+                        }
+
+                        // State is "done" now
+                        state = 2;
+
+                        // Clear timeout if it exists
+                        if (timeoutTimer) {
+                            clearTimeout(timeoutTimer);
+                        }
+
+                        // Dereference transport for early garbage collection
+                        // (no matter how long the jqXHR object will be used)
+                        transport = undefined;
+
+                        // Cache response headers
+                        responseHeadersString = headers || "";
+
+                        // Set readyState
+                        jqXHR.readyState = status > 0 ? 4 : 0;
+
+                        // Determine if successful
+                        isSuccess = status >= 200 && status < 300 || status === 304;
+
+                        // Get response data
+                        if (responses) {
+                            response = ajaxHandleResponses(s, jqXHR, responses);
+                        }
+
+                        // Convert no matter what (that way responseXXX fields are always
+                        // set)
+                        response = ajaxConvert(s, response, jqXHR, isSuccess);
+
+                        // If successful, handle type chaining
+                        if (isSuccess) {
+
+                            // Set the If-Modified-Since and/or If-None-Match header, if in
+                            // ifModified mode.
+                            if (s.ifModified) {
+                                modified = jqXHR.getResponseHeader("Last-Modified");
+                                if (modified) {
+                                    jQuery.lastModified[cacheURL] = modified;
+                                }
+                                modified = jqXHR.getResponseHeader("etag");
+                                if (modified) {
+                                    jQuery.etag[cacheURL] = modified;
+                                }
+                            }
+
+                            // if no content
+                            if (status === 204 || s.type === "HEAD") {
+                                statusText = "nocontent";
+
+                                // if not modified
+                            } else if (status === 304) {
+                                statusText = "notmodified";
+
+                                // If we have data, let's convert it
+                            } else {
+                                statusText = response.state;
+                                success = response.data;
+                                error = response.error;
+                                isSuccess = !error;
+                            }
+                        } else {
+                            // Extract error from statusText and normalize for non-aborts
+                            error = statusText;
+                            if (status || !statusText) {
+                                statusText = "error";
+                                if (status < 0) {
+                                    status = 0;
+                                }
+                            }
+                        }
+
+                        // Set data for the fake xhr object
+                        jqXHR.status = status;
+                        jqXHR.statusText = (nativeStatusText || statusText) + "";
+
+                        // Success/Error
+                        if (isSuccess) {
+                            deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
+                        } else {
+                            deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
+                        }
+
+                        // Status-dependent callbacks
+                        jqXHR.statusCode(statusCode);
+                        statusCode = undefined;
+
+                        if (fireGlobals) {
+                            globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
+                        }
+
+                        // Complete
+                        completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
+
+                        if (fireGlobals) {
+                            globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
+                            // Handle the global AJAX counter
+                            if (!(--jQuery.active)) {
+                                jQuery.event.trigger("ajaxStop");
+                            }
+                        }
+                    }
+
+                    return jqXHR;
+                },
+
+                getJSON: function(url, data, callback) {
+                    return jQuery.get(url, data, callback, "json");
+                },
+
+                getScript: function(url, callback) {
+                    return jQuery.get(url, undefined, callback, "script");
+                }
+            });
+
+            jQuery.each(["get", "post"], function(i, method) {
+                jQuery[method] = function(url, data, callback, type) {
+                    // Shift arguments if data argument was omitted
+                    if (jQuery.isFunction(data)) {
+                        type = type || callback;
+                        callback = data;
+                        data = undefined;
+                    }
+
+                    return jQuery.ajax({
+                        url: url,
+                        type: method,
+                        dataType: type,
+                        data: data,
+                        success: callback
+                    });
+                };
+            });
+
+
+            jQuery._evalUrl = function(url) {
+                return jQuery.ajax({
+                    url: url,
+                    type: "GET",
+                    dataType: "script",
+                    async: false,
+                    global: false,
+                    "throws": true
+                });
+            };
+
+
+            jQuery.fn.extend({
+                wrapAll: function(html) {
+                    var wrap;
+
+                    if (jQuery.isFunction(html)) {
+                        return this.each(function(i) {
+                            jQuery(this).wrapAll(html.call(this, i));
+                        });
+                    }
+
+                    if (this[0]) {
+
+                        // The elements to wrap the target around
+                        wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
+
+                        if (this[0].parentNode) {
+                            wrap.insertBefore(this[0]);
+                        }
+
+                        wrap.map(function() {
+                            var elem = this;
+
+                            while (elem.firstElementChild) {
+                                elem = elem.firstElementChild;
+                            }
+
+                            return elem;
+                        }).append(this);
+                    }
+
+                    return this;
+                },
+
+                wrapInner: function(html) {
+                    if (jQuery.isFunction(html)) {
+                        return this.each(function(i) {
+                            jQuery(this).wrapInner(html.call(this, i));
+                        });
+                    }
+
+                    return this.each(function() {
+                        var self = jQuery(this),
+                            contents = self.contents();
+
+                        if (contents.length) {
+                            contents.wrapAll(html);
+
+                        } else {
+                            self.append(html);
+                        }
+                    });
+                },
+
+                wrap: function(html) {
+                    var isFunction = jQuery.isFunction(html);
+
+                    return this.each(function(i) {
+                        jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
+                    });
+                },
+
+                unwrap: function() {
+                    return this.parent().each(function() {
+                        if (!jQuery.nodeName(this, "body")) {
+                            jQuery(this).replaceWith(this.childNodes);
+                        }
+                    }).end();
+                }
+            });
+
+
+            jQuery.expr.filters.hidden = function(elem) {
+                // Support: Opera <= 12.12
+                // Opera reports offsetWidths and offsetHeights less than zero on some
+                // elements
+                return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
+            };
+            jQuery.expr.filters.visible = function(elem) {
+                return !jQuery.expr.filters.hidden(elem);
+            };
+
+
+
+
+            var r20 = /%20/g,
+                rbracket = /\[\]$/,
+                rCRLF = /\r?\n/g,
+                rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+                rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+            function buildParams(prefix, obj, traditional, add) {
+                var name;
+
+                if (jQuery.isArray(obj)) {
+                    // Serialize array item.
+                    jQuery.each(obj, function(i, v) {
+                        if (traditional || rbracket.test(prefix)) {
+                            // Treat each array item as a scalar.
+                            add(prefix, v);
+
+                        } else {
+                            // Item is non-scalar (array or object), encode its numeric
+                            // index.
+                            buildParams(prefix + "[" + (typeof v === "object" ? i : "") + "]", v, traditional, add);
+                        }
+                    });
+
+                } else if (!traditional && jQuery.type(obj) === "object") {
+                    // Serialize object item.
+                    for (name in obj) {
+                        buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
+                    }
+
+                } else {
+                    // Serialize scalar item.
+                    add(prefix, obj);
+                }
+            }
+
+            // Serialize an array of form elements or a set of
+            // key/values into a query string
+            jQuery.param = function(a, traditional) {
+                var prefix,
+                    s = [],
+                    add = function(key, value) {
+                        // If value is a function, invoke it and return its value
+                        value = jQuery.isFunction(value) ? value() : (value == null ? "" : value);
+                        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+                    };
+
+                // Set traditional to true for jQuery <= 1.3.2 behavior.
+                if (traditional === undefined) {
+                    traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+                }
+
+                // If an array was passed in, assume that it is an array of form elements.
+                if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
+                    // Serialize the form elements
+                    jQuery.each(a, function() {
+                        add(this.name, this.value);
+                    });
+
+                } else {
+                    // If traditional, encode the "old" way (the way 1.3.2 or older
+                    // did it), otherwise encode params recursively.
+                    for (prefix in a) {
+                        buildParams(prefix, a[prefix], traditional, add);
+                    }
+                }
+
+                // Return the resulting serialization
+                return s.join("&").replace(r20, "+");
+            };
+
+            jQuery.fn.extend({
+                serialize: function() {
+                    return jQuery.param(this.serializeArray());
+                },
+                serializeArray: function() {
+                    return this.map(function() {
+                            // Can add propHook for "elements" to filter or add form elements
+                            var elements = jQuery.prop(this, "elements");
+                            return elements ? jQuery.makeArray(elements) : this;
+                        })
+                        .filter(function() {
+                            var type = this.type;
+
+                            // Use .is( ":disabled" ) so that fieldset[disabled] works
+                            return this.name && !jQuery(this).is(":disabled") &&
+                                rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&
+                                (this.checked || !rcheckableType.test(type));
+                        })
+                        .map(function(i, elem) {
+                            var val = jQuery(this).val();
+
+                            return val == null ?
+                                null :
+                                jQuery.isArray(val) ?
+                                jQuery.map(val, function(val) {
+                                    return {
+                                        name: elem.name,
+                                        value: val.replace(rCRLF, "\r\n")
+                                    };
+                                }) : {
+                                    name: elem.name,
+                                    value: val.replace(rCRLF, "\r\n")
+                                };
+                        }).get();
+                }
+            });
+
+
+            jQuery.ajaxSettings.xhr = function() {
+                try {
+                    return new XMLHttpRequest();
+                } catch (e) {}
+            };
+
+            var xhrId = 0,
+                xhrCallbacks = {},
+                xhrSuccessStatus = {
+                    // file protocol always yields status code 0, assume 200
+                    0: 200,
+                    // Support: IE9
+                    // #1450: sometimes IE returns 1223 when it should be 204
+                    1223: 204
+                },
+                xhrSupported = jQuery.ajaxSettings.xhr();
+
+            // Support: IE9
+            // Open requests must be manually aborted on unload (#5280)
+            // See https://support.microsoft.com/kb/2856746 for more info
+            if (window.attachEvent) {
+                window.attachEvent("onunload", function() {
+                    for (var key in xhrCallbacks) {
+                        xhrCallbacks[key]();
+                    }
+                });
+            }
+
+            support.cors = !!xhrSupported && ("withCredentials" in xhrSupported);
+            support.ajax = xhrSupported = !!xhrSupported;
+
+            jQuery.ajaxTransport(function(options) {
+                var callback;
+
+                // Cross domain only allowed if supported through XMLHttpRequest
+                if (support.cors || xhrSupported && !options.crossDomain) {
+                    return {
+                        send: function(headers, complete) {
+                            var i,
+                                xhr = options.xhr(),
+                                id = ++xhrId;
+
+                            xhr.open(options.type, options.url, options.async, options.username, options.password);
+
+                            // Apply custom fields if provided
+                            if (options.xhrFields) {
+                                for (i in options.xhrFields) {
+                                    xhr[i] = options.xhrFields[i];
+                                }
+                            }
+
+                            // Override mime type if needed
+                            if (options.mimeType && xhr.overrideMimeType) {
+                                xhr.overrideMimeType(options.mimeType);
+                            }
+
+                            // X-Requested-With header
+                            // For cross-domain requests, seeing as conditions for a
+                            // preflight are
+                            // akin to a jigsaw puzzle, we simply never set it to be sure.
+                            // (it can always be set on a per-request basis or even using
+                            // ajaxSetup)
+                            // For same-domain requests, won't change header if already
+                            // provided.
+                            if (!options.crossDomain && !headers["X-Requested-With"]) {
+                                headers["X-Requested-With"] = "XMLHttpRequest";
+                            }
+
+                            // Set headers
+                            for (i in headers) {
+                                xhr.setRequestHeader(i, headers[i]);
+                            }
+
+                            // Callback
+                            callback = function(type) {
+                                return function() {
+                                    if (callback) {
+                                        delete xhrCallbacks[id];
+                                        callback = xhr.onload = xhr.onerror = null;
+
+                                        if (type === "abort") {
+                                            xhr.abort();
+                                        } else if (type === "error") {
+                                            complete(
+                                                // file: protocol always yields status 0;
+                                                // see #8605, #14207
+                                                xhr.status,
+                                                xhr.statusText
+                                            );
+                                        } else {
+                                            complete(
+                                                xhrSuccessStatus[xhr.status] || xhr.status,
+                                                xhr.statusText,
+                                                // Support: IE9
+                                                // Accessing binary-data responseText throws
+                                                // an exception
+                                                // (#11426)
+                                                typeof xhr.responseText === "string" ? {
+                                                    text: xhr.responseText
+                                                } : undefined,
+                                                xhr.getAllResponseHeaders()
+                                            );
+                                        }
+                                    }
+                                };
+                            };
+
+                            // Listen to events
+                            xhr.onload = callback();
+                            xhr.onerror = callback("error");
+
+                            // Create the abort callback
+                            callback = xhrCallbacks[id] = callback("abort");
+
+                            try {
+                                // Do send the request (this may raise an exception)
+                                xhr.send(options.hasContent && options.data || null);
+                            } catch (e) {
+                                // #14683: Only rethrow if this hasn't been notified as an
+                                // error yet
+                                if (callback) {
+                                    throw e;
+                                }
+                            }
+                        },
+
+                        abort: function() {
+                            if (callback) {
+                                callback();
+                            }
+                        }
+                    };
+                }
+            });
+
+
+
+
+            // Install script dataType
+            jQuery.ajaxSetup({
+                accepts: {
+                    script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+                },
+                contents: {
+                    script: /(?:java|ecma)script/
+                },
+                converters: {
+                    "text script": function(text) {
+                        jQuery.globalEval(text);
+                        return text;
+                    }
+                }
+            });
+
+            // Handle cache's special case and crossDomain
+            jQuery.ajaxPrefilter("script", function(s) {
+                if (s.cache === undefined) {
+                    s.cache = false;
+                }
+                if (s.crossDomain) {
+                    s.type = "GET";
+                }
+            });
+
+            // Bind script tag hack transport
+            jQuery.ajaxTransport("script", function(s) {
+                // This transport only deals with cross domain requests
+                if (s.crossDomain) {
+                    var script, callback;
+                    return {
+                        send: function(_, complete) {
+                            script = jQuery("<script>").prop({
+                                async: true,
+                                charset: s.scriptCharset,
+                                src: s.url
+                            }).on(
+                                "load error",
+                                callback = function(evt) {
+                                    script.remove();
+                                    callback = null;
+                                    if (evt) {
+                                        complete(evt.type === "error" ? 404 : 200, evt.type);
+                                    }
+                                }
+                            );
+                            document.head.appendChild(script[0]);
+                        },
+                        abort: function() {
+                            if (callback) {
+                                callback();
+                            }
+                        }
+                    };
+                }
+            });
+
+
+
+
+            var oldCallbacks = [],
+                rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+            // Default jsonp settings
+            jQuery.ajaxSetup({
+                jsonp: "callback",
+                jsonpCallback: function() {
+                    var callback = oldCallbacks.pop() || (jQuery.expando + "_" + (nonce++));
+                    this[callback] = true;
+                    return callback;
+                }
+            });
+
+            // Detect, normalize options and install callbacks for jsonp requests
+            jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, jqXHR) {
+
+                var callbackName, overwritten, responseContainer,
+                    jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ?
+                        "url" :
+                        typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data"
+                    );
+
+                // Handle iff the expected data type is "jsonp" or we have a parameter to
+                // set
+                if (jsonProp || s.dataTypes[0] === "jsonp") {
+
+                    // Get callback name, remembering preexisting value associated with it
+                    callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?
+                        s.jsonpCallback() :
+                        s.jsonpCallback;
+
+                    // Insert callback into url or form data
+                    if (jsonProp) {
+                        s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
+                    } else if (s.jsonp !== false) {
+                        s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
+                    }
+
+                    // Use data converter to retrieve json after script execution
+                    s.converters["script json"] = function() {
+                        if (!responseContainer) {
+                            jQuery.error(callbackName + " was not called");
+                        }
+                        return responseContainer[0];
+                    };
+
+                    // force json dataType
+                    s.dataTypes[0] = "json";
+
+                    // Install callback
+                    overwritten = window[callbackName];
+                    window[callbackName] = function() {
+                        responseContainer = arguments;
+                    };
+
+                    // Clean-up function (fires after converters)
+                    jqXHR.always(function() {
+                        // Restore preexisting value
+                        window[callbackName] = overwritten;
+
+                        // Save back as free
+                        if (s[callbackName]) {
+                            // make sure that re-using the options doesn't screw things
+                            // around
+                            s.jsonpCallback = originalSettings.jsonpCallback;
+
+                            // save the callback name for future use
+                            oldCallbacks.push(callbackName);
+                        }
+
+                        // Call if it was a function and we have a response
+                        if (responseContainer && jQuery.isFunction(overwritten)) {
+                            overwritten(responseContainer[0]);
+                        }
+
+                        responseContainer = overwritten = undefined;
+                    });
+
+                    // Delegate to script
+                    return "script";
+                }
+            });
+
+
+
+
+            // data: string of html
+            // context (optional): If specified, the fragment will be created in this
+            // context, defaults to document
+            // keepScripts (optional): If true, will include scripts passed in the html
+            // string
+            jQuery.parseHTML = function(data, context, keepScripts) {
+                if (!data || typeof data !== "string") {
+                    return null;
+                }
+                if (typeof context === "boolean") {
+                    keepScripts = context;
+                    context = false;
+                }
+                context = context || document;
+
+                var parsed = rsingleTag.exec(data),
+                    scripts = !keepScripts && [];
+
+                // Single tag
+                if (parsed) {
+                    return [context.createElement(parsed[1])];
+                }
+
+                parsed = jQuery.buildFragment([data], context, scripts);
+
+                if (scripts && scripts.length) {
+                    jQuery(scripts).remove();
+                }
+
+                return jQuery.merge([], parsed.childNodes);
+            };
+
+
+            // Keep a copy of the old load method
+            var _load = jQuery.fn.load;
+
+            /**
+             * Load a url into a page
+             */
+            jQuery.fn.load = function(url, params, callback) {
+                if (typeof url !== "string" && _load) {
+                    return _load.apply(this, arguments);
+                }
+
+                var selector, type, response,
+                    self = this,
+                    off = url.indexOf(" ");
+
+                if (off >= 0) {
+                    selector = jQuery.trim(url.slice(off));
+                    url = url.slice(0, off);
+                }
+
+                // If it's a function
+                if (jQuery.isFunction(params)) {
+
+                    // We assume that it's the callback
+                    callback = params;
+                    params = undefined;
+
+                    // Otherwise, build a param string
+                } else if (params && typeof params === "object") {
+                    type = "POST";
+                }
+
+                // If we have elements to modify, make the request
+                if (self.length > 0) {
+                    jQuery.ajax({
+                        url: url,
+
+                        // if "type" variable is undefined, then "GET" method will be used
+                        type: type,
+                        dataType: "html",
+                        data: params
+                    }).done(function(responseText) {
+
+                        // Save response for use in complete callback
+                        response = arguments;
+
+                        self.html(selector ?
+
+                            // If a selector was specified, locate the right elements in a
+                            // dummy div
+                            // Exclude scripts to avoid IE 'Permission Denied' errors
+                            jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
+
+                            // Otherwise use the full result
+                            responseText);
+
+                    }).complete(callback && function(jqXHR, status) {
+                        self.each(callback, response || [jqXHR.responseText, status, jqXHR]);
+                    });
+                }
+
+                return this;
+            };
+
+
+
+
+            // Attach a bunch of functions for handling common AJAX events
+            jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(i, type) {
+                jQuery.fn[type] = function(fn) {
+                    return this.on(type, fn);
+                };
+            });
+
+
+
+
+            jQuery.expr.filters.animated = function(elem) {
+                return jQuery.grep(jQuery.timers, function(fn) {
+                    return elem === fn.elem;
+                }).length;
+            };
+
+
+
+
+            var docElem = window.document.documentElement;
+
+            /**
+             * Gets a window from an element
+             */
+            function getWindow(elem) {
+                return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
+            }
+
+            jQuery.offset = {
+                setOffset: function(elem, options, i) {
+                    var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+                        position = jQuery.css(elem, "position"),
+                        curElem = jQuery(elem),
+                        props = {};
+
+                    // Set position first, in-case top/left are set even on static elem
+                    if (position === "static") {
+                        elem.style.position = "relative";
+                    }
+
+                    curOffset = curElem.offset();
+                    curCSSTop = jQuery.css(elem, "top");
+                    curCSSLeft = jQuery.css(elem, "left");
+                    calculatePosition = (position === "absolute" || position === "fixed") &&
+                        (curCSSTop + curCSSLeft).indexOf("auto") > -1;
+
+                    // Need to be able to calculate position if either
+                    // top or left is auto and position is either absolute or fixed
+                    if (calculatePosition) {
+                        curPosition = curElem.position();
+                        curTop = curPosition.top;
+                        curLeft = curPosition.left;
+
+                    } else {
+                        curTop = parseFloat(curCSSTop) || 0;
+                        curLeft = parseFloat(curCSSLeft) || 0;
+                    }
+
+                    if (jQuery.isFunction(options)) {
+                        options = options.call(elem, i, curOffset);
+                    }
+
+                    if (options.top != null) {
+                        props.top = (options.top - curOffset.top) + curTop;
+                    }
+                    if (options.left != null) {
+                        props.left = (options.left - curOffset.left) + curLeft;
+                    }
+
+                    if ("using" in options) {
+                        options.using.call(elem, props);
+
+                    } else {
+                        curElem.css(props);
+                    }
+                }
+            };
+
+            jQuery.fn.extend({
+                offset: function(options) {
+                    if (arguments.length) {
+                        return options === undefined ?
+                            this :
+                            this.each(function(i) {
+                                jQuery.offset.setOffset(this, options, i);
+                            });
+                    }
+
+                    var docElem, win,
+                        elem = this[0],
+                        box = {
+                            top: 0,
+                            left: 0
+                        },
+                        doc = elem && elem.ownerDocument;
+
+                    if (!doc) {
+                        return;
+                    }
+
+                    docElem = doc.documentElement;
+
+                    // Make sure it's not a disconnected DOM node
+                    if (!jQuery.contains(docElem, elem)) {
+                        return box;
+                    }
+
+                    // Support: BlackBerry 5, iOS 3 (original iPhone)
+                    // If we don't have gBCR, just use 0,0 rather than error
+                    if (typeof elem.getBoundingClientRect !== strundefined) {
+                        box = elem.getBoundingClientRect();
+                    }
+                    win = getWindow(doc);
+                    return {
+                        top: box.top + win.pageYOffset - docElem.clientTop,
+                        left: box.left + win.pageXOffset - docElem.clientLeft
+                    };
+                },
+
+                position: function() {
+                    if (!this[0]) {
+                        return;
+                    }
+
+                    var offsetParent, offset,
+                        elem = this[0],
+                        parentOffset = {
+                            top: 0,
+                            left: 0
+                        };
+
+                    // Fixed elements are offset from window (parentOffset = {top:0, left:
+                    // 0}, because it is its only offset parent
+                    if (jQuery.css(elem, "position") === "fixed") {
+                        // Assume getBoundingClientRect is there when computed position is
+                        // fixed
+                        offset = elem.getBoundingClientRect();
+
+                    } else {
+                        // Get *real* offsetParent
+                        offsetParent = this.offsetParent();
+
+                        // Get correct offsets
+                        offset = this.offset();
+                        if (!jQuery.nodeName(offsetParent[0], "html")) {
+                            parentOffset = offsetParent.offset();
+                        }
+
+                        // Add offsetParent borders
+                        parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
+                        parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true);
+                    }
+
+                    // Subtract parent offsets and element margins
+                    return {
+                        top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
+                        left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
+                    };
+                },
+
+                offsetParent: function() {
+                    return this.map(function() {
+                        var offsetParent = this.offsetParent || docElem;
+
+                        while (offsetParent && (!jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static")) {
+                            offsetParent = offsetParent.offsetParent;
+                        }
+
+                        return offsetParent || docElem;
+                    });
+                }
+            });
+
+            // Create scrollLeft and scrollTop methods
+            jQuery.each({
+                scrollLeft: "pageXOffset",
+                scrollTop: "pageYOffset"
+            }, function(method, prop) {
+                var top = "pageYOffset" === prop;
+
+                jQuery.fn[method] = function(val) {
+                    return access(this, function(elem, method, val) {
+                        var win = getWindow(elem);
+
+                        if (val === undefined) {
+                            return win ? win[prop] : elem[method];
+                        }
+
+                        if (win) {
+                            win.scrollTo(!top ? val : window.pageXOffset,
+                                top ? val : window.pageYOffset
+                            );
+
+                        } else {
+                            elem[method] = val;
+                        }
+                    }, method, val, arguments.length, null);
+                };
+            });
+
+            // Support: Safari<7+, Chrome<37+
+            // Add the top/left cssHooks using jQuery.fn.position
+            // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+            // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
+            // getComputedStyle returns percent when specified for top/left/bottom/right;
+            // rather than make the css module depend on the offset module, just check for
+            // it here
+            jQuery.each(["top", "left"], function(i, prop) {
+                jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,
+                    function(elem, computed) {
+                        if (computed) {
+                            computed = curCSS(elem, prop);
+                            // If curCSS returns percentage, fallback to offset
+                            return rnumnonpx.test(computed) ?
+                                jQuery(elem).position()[prop] + "px" :
+                                computed;
+                        }
+                    }
+                );
+            });
+
+
+            // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth
+            // methods
+            jQuery.each({
+                Height: "height",
+                Width: "width"
+            }, function(name, type) {
+                jQuery.each({
+                    padding: "inner" + name,
+                    content: type,
+                    "": "outer" + name
+                }, function(defaultExtra, funcName) {
+                    // Margin is only for outerHeight, outerWidth
+                    jQuery.fn[funcName] = function(margin, value) {
+                        var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
+                            extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
+
+                        return access(this, function(elem, type, value) {
+                            var doc;
+
+                            if (jQuery.isWindow(elem)) {
+                                // As of 5/8/2012 this will yield incorrect results for
+                                // Mobile Safari, but there
+                                // isn't a whole lot we can do. See pull request at this URL
+                                // for discussion:
+                                // https://github.com/jquery/jquery/pull/764
+                                return elem.document.documentElement["client" + name];
+                            }
+
+                            // Get document width or height
+                            if (elem.nodeType === 9) {
+                                doc = elem.documentElement;
+
+                                // Either scroll[Width/Height] or offset[Width/Height] or
+                                // client[Width/Height],
+                                // whichever is greatest
+                                return Math.max(
+                                    elem.body["scroll" + name], doc["scroll" + name],
+                                    elem.body["offset" + name], doc["offset" + name],
+                                    doc["client" + name]
+                                );
+                            }
+
+                            return value === undefined ?
+                                // Get width or height on the element, requesting but not
+                                // forcing parseFloat
+                                jQuery.css(elem, type, extra) :
+
+                                // Set width or height on the element
+                                jQuery.style(elem, type, value, extra);
+                        }, type, chainable ? margin : undefined, chainable, null);
+                    };
+                });
+            });
+
+
+            // The number of elements contained in the matched element set
+            jQuery.fn.size = function() {
+                return this.length;
+            };
+
+            jQuery.fn.andSelf = jQuery.fn.addBack;
+
+
+
+
+            // Register as a named AMD module, since jQuery can be concatenated with other
+            // files that may use define, but not via a proper concatenation script that
+            // understands anonymous AMD modules. A named AMD is safest and most robust
+            // way to register. Lowercase jquery is used because AMD module names are
+            // derived from file names, and jQuery is normally delivered in a lowercase
+            // file name. Do this after creating the global so that if an AMD module wants
+            // to call noConflict to hide this version of jQuery, it will work.
+
+            // Note that for maximum portability, libraries that are not jQuery should
+            // declare themselves as anonymous modules, and avoid setting a global if an
+            // AMD loader is present. jQuery is a special case. For more information, see
+            // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+            if (typeof define === "function" && define.amd) {
+                define("jquery", [], function() {
+                    return jQuery;
+                });
+            }
+
+
+
+
+            var
+            // Map over jQuery in case of overwrite
+                _jQuery = window.jQuery,
+
+                // Map over the $ in case of overwrite
+                _$ = window.$;
+
+            jQuery.noConflict = function(deep) {
+                if (window.$ === jQuery) {
+                    window.$ = _$;
+                }
+
+                if (deep && window.jQuery === jQuery) {
+                    window.jQuery = _jQuery;
+                }
+
+                return jQuery;
+            };
+
+            // Expose jQuery and $ identifiers, even in AMD
+            // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+            // and CommonJS for browser emulators (#13566)
+            if (typeof noGlobal === strundefined) {
+                window.jQuery = window.$ = jQuery;
+            }
+
+
+
+
+            return jQuery;
+
+        }));
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\flatten.js": [function(require, module, exports) {
+        var baseFlatten = require('../internal/baseFlatten'),
+            isIterateeCall = require('../internal/isIterateeCall');
+
+        /**
+         * Flattens a nested array. If `isDeep` is `true` the array is recursively
+         * flattened, otherwise it's only flattened a single level.
+         * 
+         * @static
+         * @memberOf _
+         * @category Array
+         * @param {Array}
+         *            array The array to flatten.
+         * @param {boolean}
+         *            [isDeep] Specify a deep flatten.
+         * @param- {Object} [guard] Enables use as a callback for functions like
+         *         `_.map`.
+         * @returns {Array} Returns the new flattened array.
+         * @example
+         * 
+         * _.flatten([1, [2, 3, [4]]]); // => [1, 2, 3, [4]]
+         *  // using `isDeep` _.flatten([1, [2, 3, [4]]], true); // => [1, 2, 3, 4]
+         */
+        function flatten(array, isDeep, guard) {
+            var length = array ? array.length : 0;
+            if (guard && isIterateeCall(array, isDeep, guard)) {
+                isDeep = false;
+            }
+            return length ? baseFlatten(array, isDeep) : [];
+        }
+
+        module.exports = flatten;
+
+    }, {
+        "../internal/baseFlatten": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFlatten.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\last.js": [function(require, module, exports) {
+        /**
+         * Gets the last element of `array`.
+         * 
+         * @static
+         * @memberOf _
+         * @category Array
+         * @param {Array}
+         *            array The array to query.
+         * @returns {*} Returns the last element of `array`.
+         * @example
+         * 
+         * _.last([1, 2, 3]); // => 3
+         */
+        function last(array) {
+            var length = array ? array.length : 0;
+            return length ? array[length - 1] : undefined;
+        }
+
+        module.exports = last;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\uniq.js": [function(require, module, exports) {
+        var baseCallback = require('../internal/baseCallback'),
+            baseUniq = require('../internal/baseUniq'),
+            isIterateeCall = require('../internal/isIterateeCall'),
+            sortedUniq = require('../internal/sortedUniq');
+
+        /**
+         * Creates a duplicate-free version of an array, using
+         * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+         * for equality comparisons, in which only the first occurence of each element
+         * is kept. Providing `true` for `isSorted` performs a faster search algorithm
+         * for sorted arrays. If an iteratee function is provided it's invoked for each
+         * element in the array to generate the criterion by which uniqueness is
+         * computed. The `iteratee` is bound to `thisArg` and invoked with three
+         * arguments: (value, index, array).
+         * 
+         * If a property name is provided for `iteratee` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `iteratee` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias unique
+         * @category Array
+         * @param {Array}
+         *            array The array to inspect.
+         * @param {boolean}
+         *            [isSorted] Specify the array is sorted.
+         * @param {Function|Object|string}
+         *            [iteratee] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {Array} Returns the new duplicate-value-free array.
+         * @example
+         * 
+         * _.uniq([2, 1, 2]); // => [2, 1]
+         *  // using `isSorted` _.uniq([1, 1, 2], true); // => [1, 2]
+         *  // using an iteratee function _.uniq([1, 2.5, 1.5, 2], function(n) { return
+         * this.floor(n); }, Math); // => [1, 2.5]
+         *  // using the `_.property` callback shorthand _.uniq([{ 'x': 1 }, { 'x': 2 }, {
+         * 'x': 1 }], 'x'); // => [{ 'x': 1 }, { 'x': 2 }]
+         */
+        function uniq(array, isSorted, iteratee, thisArg) {
+            var length = array ? array.length : 0;
+            if (!length) {
+                return [];
+            }
+            if (isSorted != null && typeof isSorted != 'boolean') {
+                thisArg = iteratee;
+                iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
+                isSorted = false;
+            }
+            iteratee = iteratee == null ? iteratee : baseCallback(iteratee, thisArg, 3);
+            return (isSorted) ? sortedUniq(array, iteratee) : baseUniq(array, iteratee);
+        }
+
+        module.exports = uniq;
+
+    }, {
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseUniq": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseUniq.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js",
+        "../internal/sortedUniq": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\sortedUniq.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\unique.js": [function(require, module, exports) {
+        module.exports = require('./uniq');
+
+    }, {
+        "./uniq": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\uniq.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\chain\\lodash.js": [function(require, module, exports) {
+        var LazyWrapper = require('../internal/LazyWrapper'),
+            LodashWrapper = require('../internal/LodashWrapper'),
+            baseLodash = require('../internal/baseLodash'),
+            isArray = require('../lang/isArray'),
+            isObjectLike = require('../internal/isObjectLike'),
+            wrapperClone = require('../internal/wrapperClone');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * Creates a `lodash` object which wraps `value` to enable implicit chaining.
+         * Methods that operate on and return arrays, collections, and functions can be
+         * chained together. Methods that retrieve a single value or may return a
+         * primitive value will automatically end the chain returning the unwrapped
+         * value. Explicit chaining may be enabled using `_.chain`. The execution of
+         * chained methods is lazy, that is, execution is deferred until `_#value` is
+         * implicitly or explicitly called.
+         * 
+         * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+         * fusion is an optimization strategy which merge iteratee calls; this can help
+         * to avoid the creation of intermediate data structures and greatly reduce the
+         * number of iteratee executions.
+         * 
+         * Chaining is supported in custom builds as long as the `_#value` method is
+         * directly or indirectly included in the build.
+         * 
+         * In addition to lodash methods, wrappers have `Array` and `String` methods.
+         * 
+         * The wrapper `Array` methods are: `concat`, `join`, `pop`, `push`, `reverse`,
+         * `shift`, `slice`, `sort`, `splice`, and `unshift`
+         * 
+         * The wrapper `String` methods are: `replace` and `split`
+         * 
+         * The wrapper methods that support shortcut fusion are: `compact`, `drop`,
+         * `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `first`, `initial`,
+         * `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, `slice`, `take`,
+         * `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, and `where`
+         * 
+         * The chainable wrapper methods are: `after`, `ary`, `assign`, `at`, `before`,
+         * `bind`, `bindAll`, `bindKey`, `callback`, `chain`, `chunk`, `commit`,
+         * `compact`, `concat`, `constant`, `countBy`, `create`, `curry`, `debounce`,
+         * `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, `drop`,
+         * `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, `filter`, `flatten`,
+         * `flattenDeep`, `flow`, `flowRight`, `forEach`, `forEachRight`, `forIn`,
+         * `forInRight`, `forOwn`, `forOwnRight`, `functions`, `groupBy`, `indexBy`,
+         * `initial`, `intersection`, `invert`, `invoke`, `keys`, `keysIn`, `map`,
+         * `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`,
+         * `method`, `methodOf`, `mixin`, `modArgs`, `negate`, `omit`, `once`, `pairs`,
+         * `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`, `property`,
+         * `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`,
+         * `rest`, `restParam`, `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`,
+         * `sortByAll`, `sortByOrder`, `splice`, `spread`, `take`, `takeRight`,
+         * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`,
+         * `toPlainObject`, `transform`, `union`, `uniq`, `unshift`, `unzip`,
+         * `unzipWith`, `values`, `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`,
+         * `zipObject`, `zipWith`
+         * 
+         * The wrapper methods that are **not** chainable by default are: `add`,
+         * `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, `deburr`,
+         * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
+         * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
+         * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
+         * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+         * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
+         * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
+         * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
+         * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
+         * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
+         * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
+         * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
+         * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+         * `unescape`, `uniqueId`, `value`, and `words`
+         * 
+         * The wrapper method `sample` will return a wrapped value when `n` is provided,
+         * otherwise an unwrapped value is returned.
+         * 
+         * @name _
+         * @constructor
+         * @category Chain
+         * @param {*}
+         *            value The value to wrap in a `lodash` instance.
+         * @returns {Object} Returns the new `lodash` wrapper instance.
+         * @example
+         * 
+         * var wrapped = _([1, 2, 3]);
+         *  // returns an unwrapped value wrapped.reduce(function(total, n) { return
+         * total + n; }); // => 6
+         *  // returns a wrapped value var squares = wrapped.map(function(n) { return n *
+         * n; });
+         * 
+         * _.isArray(squares); // => false
+         * 
+         * _.isArray(squares.value()); // => true
+         */
+        function lodash(value) {
+            if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+                if (value instanceof LodashWrapper) {
+                    return value;
+                }
+                if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
+                    return wrapperClone(value);
+                }
+            }
+            return new LodashWrapper(value);
+        }
+
+        // Ensure wrappers are instances of `baseLodash`.
+        lodash.prototype = baseLodash.prototype;
+
+        module.exports = lodash;
+
+    }, {
+        "../internal/LazyWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LazyWrapper.js",
+        "../internal/LodashWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LodashWrapper.js",
+        "../internal/baseLodash": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseLodash.js",
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js",
+        "../internal/wrapperClone": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\wrapperClone.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\every.js": [function(require, module, exports) {
+        var arrayEvery = require('../internal/arrayEvery'),
+            baseCallback = require('../internal/baseCallback'),
+            baseEvery = require('../internal/baseEvery'),
+            isArray = require('../lang/isArray'),
+            isIterateeCall = require('../internal/isIterateeCall');
+
+        /**
+         * Checks if `predicate` returns truthy for **all** elements of `collection`.
+         * The predicate is bound to `thisArg` and invoked with three arguments: (value,
+         * index|key, collection).
+         * 
+         * If a property name is provided for `predicate` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `predicate` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias all
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [predicate=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {boolean} Returns `true` if all elements pass the predicate check,
+         *          else `false`.
+         * @example
+         * 
+         * _.every([true, 1, null, 'yes'], Boolean); // => false
+         * 
+         * var users = [ { 'user': 'barney', 'active': false }, { 'user': 'fred',
+         * 'active': false } ];
+         *  // using the `_.matches` callback shorthand _.every(users, { 'user':
+         * 'barney', 'active': false }); // => false
+         *  // using the `_.matchesProperty` callback shorthand _.every(users, 'active',
+         * false); // => true
+         *  // using the `_.property` callback shorthand _.every(users, 'active'); // =>
+         * false
+         */
+        function every(collection, predicate, thisArg) {
+            var func = isArray(collection) ? arrayEvery : baseEvery;
+            if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+                predicate = undefined;
+            }
+            if (typeof predicate != 'function' || thisArg !== undefined) {
+                predicate = baseCallback(predicate, thisArg, 3);
+            }
+            return func(collection, predicate);
+        }
+
+        module.exports = every;
+
+    }, {
+        "../internal/arrayEvery": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayEvery.js",
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseEvery": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEvery.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\filter.js": [function(require, module, exports) {
+        var arrayFilter = require('../internal/arrayFilter'),
+            baseCallback = require('../internal/baseCallback'),
+            baseFilter = require('../internal/baseFilter'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Iterates over elements of `collection`, returning an array of all elements
+         * `predicate` returns truthy for. The predicate is bound to `thisArg` and
+         * invoked with three arguments: (value, index|key, collection).
+         * 
+         * If a property name is provided for `predicate` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `predicate` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias select
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [predicate=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {Array} Returns the new filtered array.
+         * @example
+         * 
+         * _.filter([4, 5, 6], function(n) { return n % 2 == 0; }); // => [4, 6]
+         * 
+         * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+         * 'fred', 'age': 40, 'active': false } ];
+         *  // using the `_.matches` callback shorthand _.pluck(_.filter(users, { 'age':
+         * 36, 'active': true }), 'user'); // => ['barney']
+         *  // using the `_.matchesProperty` callback shorthand _.pluck(_.filter(users,
+         * 'active', false), 'user'); // => ['fred']
+         *  // using the `_.property` callback shorthand _.pluck(_.filter(users,
+         * 'active'), 'user'); // => ['barney']
+         */
+        function filter(collection, predicate, thisArg) {
+            var func = isArray(collection) ? arrayFilter : baseFilter;
+            predicate = baseCallback(predicate, thisArg, 3);
+            return func(collection, predicate);
+        }
+
+        module.exports = filter;
+
+    }, {
+        "../internal/arrayFilter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayFilter.js",
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseFilter": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFilter.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\find.js": [function(require, module, exports) {
+        var baseEach = require('../internal/baseEach'),
+            createFind = require('../internal/createFind');
+
+        /**
+         * Iterates over elements of `collection`, returning the first element
+         * `predicate` returns truthy for. The predicate is bound to `thisArg` and
+         * invoked with three arguments: (value, index|key, collection).
+         * 
+         * If a property name is provided for `predicate` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `predicate` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias detect
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to search.
+         * @param {Function|Object|string}
+         *            [predicate=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {*} Returns the matched element, else `undefined`.
+         * @example
+         * 
+         * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+         * 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1,
+         * 'active': true } ];
+         * 
+         * _.result(_.find(users, function(chr) { return chr.age < 40; }), 'user'); // =>
+         * 'barney'
+         *  // using the `_.matches` callback shorthand _.result(_.find(users, { 'age':
+         * 1, 'active': true }), 'user'); // => 'pebbles'
+         *  // using the `_.matchesProperty` callback shorthand _.result(_.find(users,
+         * 'active', false), 'user'); // => 'fred'
+         *  // using the `_.property` callback shorthand _.result(_.find(users,
+         * 'active'), 'user'); // => 'barney'
+         */
+        var find = createFind(baseEach);
+
+        module.exports = find;
+
+    }, {
+        "../internal/baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js",
+        "../internal/createFind": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createFind.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\forEach.js": [function(require, module, exports) {
+        var arrayEach = require('../internal/arrayEach'),
+            baseEach = require('../internal/baseEach'),
+            createForEach = require('../internal/createForEach');
+
+        /**
+         * Iterates over elements of `collection` invoking `iteratee` for each element.
+         * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+         * (value, index|key, collection). Iteratee functions may exit iteration early
+         * by explicitly returning `false`.
+         * 
+         * **Note:** As with other "Collections" methods, objects with a "length"
+         * property are iterated like arrays. To avoid this behavior `_.forIn` or
+         * `_.forOwn` may be used for object iteration.
+         * 
+         * @static
+         * @memberOf _
+         * @alias each
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            [iteratee=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {Array|Object|string} Returns `collection`.
+         * @example
+         * 
+         * _([1, 2]).forEach(function(n) { console.log(n); }).value(); // => logs each
+         * value from left to right and returns the array
+         * 
+         * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { console.log(n, key); }); // =>
+         * logs each value-key pair and returns the object (iteration order is not
+         * guaranteed)
+         */
+        var forEach = createForEach(arrayEach, baseEach);
+
+        module.exports = forEach;
+
+    }, {
+        "../internal/arrayEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayEach.js",
+        "../internal/baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js",
+        "../internal/createForEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createForEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\groupBy.js": [function(require, module, exports) {
+        var createAggregator = require('../internal/createAggregator');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * Creates an object composed of keys generated from the results of running each
+         * element of `collection` through `iteratee`. The corresponding value of each
+         * key is an array of the elements responsible for generating the key. The
+         * `iteratee` is bound to `thisArg` and invoked with three arguments: (value,
+         * index|key, collection).
+         * 
+         * If a property name is provided for `iteratee` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `iteratee` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [iteratee=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {Object} Returns the composed aggregate object.
+         * @example
+         * 
+         * _.groupBy([4.2, 6.1, 6.4], function(n) { return Math.floor(n); }); // => {
+         * '4': [4.2], '6': [6.1, 6.4] }
+         * 
+         * _.groupBy([4.2, 6.1, 6.4], function(n) { return this.floor(n); }, Math); // => {
+         * '4': [4.2], '6': [6.1, 6.4] }
+         *  // using the `_.property` callback shorthand _.groupBy(['one', 'two',
+         * 'three'], 'length'); // => { '3': ['one', 'two'], '5': ['three'] }
+         */
+        var groupBy = createAggregator(function(result, value, key) {
+            if (hasOwnProperty.call(result, key)) {
+                result[key].push(value);
+            } else {
+                result[key] = [value];
+            }
+        });
+
+        module.exports = groupBy;
+
+    }, {
+        "../internal/createAggregator": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createAggregator.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\includes.js": [function(require, module, exports) {
+        var baseIndexOf = require('../internal/baseIndexOf'),
+            getLength = require('../internal/getLength'),
+            isArray = require('../lang/isArray'),
+            isIterateeCall = require('../internal/isIterateeCall'),
+            isLength = require('../internal/isLength'),
+            isString = require('../lang/isString'),
+            values = require('../object/values');
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * Checks if `target` is in `collection` using
+         * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+         * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+         * from the end of `collection`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias contains, include
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to search.
+         * @param {*}
+         *            target The value to search for.
+         * @param {number}
+         *            [fromIndex=0] The index to search from.
+         * @param- {Object} [guard] Enables use as a callback for functions like
+         *         `_.reduce`.
+         * @returns {boolean} Returns `true` if a matching element is found, else
+         *          `false`.
+         * @example
+         * 
+         * _.includes([1, 2, 3], 1); // => true
+         * 
+         * _.includes([1, 2, 3], 1, 2); // => false
+         * 
+         * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); // => true
+         * 
+         * _.includes('pebbles', 'eb'); // => true
+         */
+        function includes(collection, target, fromIndex, guard) {
+            var length = collection ? getLength(collection) : 0;
+            if (!isLength(length)) {
+                collection = values(collection);
+                length = collection.length;
+            }
+            if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
+                fromIndex = 0;
+            } else {
+                fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
+            }
+            return (typeof collection == 'string' || !isArray(collection) && isString(collection)) ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
+        }
+
+        module.exports = includes;
+
+    }, {
+        "../internal/baseIndexOf": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIndexOf.js",
+        "../internal/getLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getLength.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js",
+        "../internal/isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../lang/isString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js",
+        "../object/values": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\values.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\map.js": [function(require, module, exports) {
+        var arrayMap = require('../internal/arrayMap'),
+            baseCallback = require('../internal/baseCallback'),
+            baseMap = require('../internal/baseMap'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Creates an array of values by running each element in `collection` through
+         * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
+         * arguments: (value, index|key, collection).
+         * 
+         * If a property name is provided for `iteratee` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `iteratee` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * Many lodash methods are guarded to work as iteratees for methods like
+         * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+         * 
+         * The guarded methods are: `ary`, `callback`, `chunk`, `clone`, `create`,
+         * `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, `flatten`,
+         * `invert`, `max`, `min`, `parseInt`, `slice`, `sortBy`, `take`, `takeRight`,
+         * `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `random`, `range`,
+         * `sample`, `some`, `sum`, `uniq`, and `words`
+         * 
+         * @static
+         * @memberOf _
+         * @alias collect
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [iteratee=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {Array} Returns the new mapped array.
+         * @example
+         * 
+         * function timesThree(n) { return n * 3; }
+         * 
+         * _.map([1, 2], timesThree); // => [3, 6]
+         * 
+         * _.map({ 'a': 1, 'b': 2 }, timesThree); // => [3, 6] (iteration order is not
+         * guaranteed)
+         * 
+         * var users = [ { 'user': 'barney' }, { 'user': 'fred' } ];
+         *  // using the `_.property` callback shorthand _.map(users, 'user'); // =>
+         * ['barney', 'fred']
+         */
+        function map(collection, iteratee, thisArg) {
+            var func = isArray(collection) ? arrayMap : baseMap;
+            iteratee = baseCallback(iteratee, thisArg, 3);
+            return func(collection, iteratee);
+        }
+
+        module.exports = map;
+
+    }, {
+        "../internal/arrayMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayMap.js",
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMap.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\reduce.js": [function(require, module, exports) {
+        var arrayReduce = require('../internal/arrayReduce'),
+            baseEach = require('../internal/baseEach'),
+            createReduce = require('../internal/createReduce');
+
+        /**
+         * Reduces `collection` to a value which is the accumulated result of running
+         * each element in `collection` through `iteratee`, where each successive
+         * invocation is supplied the return value of the previous. If `accumulator` is
+         * not provided the first element of `collection` is used as the initial value.
+         * The `iteratee` is bound to `thisArg` and invoked with four arguments:
+         * (accumulator, value, index|key, collection).
+         * 
+         * Many lodash methods are guarded to work as iteratees for methods like
+         * `_.reduce`, `_.reduceRight`, and `_.transform`.
+         * 
+         * The guarded methods are: `assign`, `defaults`, `defaultsDeep`, `includes`,
+         * `merge`, `sortByAll`, and `sortByOrder`
+         * 
+         * @static
+         * @memberOf _
+         * @alias foldl, inject
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            [iteratee=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [accumulator] The initial value.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {*} Returns the accumulated value.
+         * @example
+         * 
+         * _.reduce([1, 2], function(total, n) { return total + n; }); // => 3
+         * 
+         * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { result[key] = n * 3;
+         * return result; }, {}); // => { 'a': 3, 'b': 6 } (iteration order is not
+         * guaranteed)
+         */
+        var reduce = createReduce(arrayReduce, baseEach);
+
+        module.exports = reduce;
+
+    }, {
+        "../internal/arrayReduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayReduce.js",
+        "../internal/baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js",
+        "../internal/createReduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createReduce.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\size.js": [function(require, module, exports) {
+        var getLength = require('../internal/getLength'),
+            isLength = require('../internal/isLength'),
+            keys = require('../object/keys');
+
+        /**
+         * Gets the size of `collection` by returning its length for array-like values
+         * or the number of own enumerable properties for objects.
+         * 
+         * @static
+         * @memberOf _
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to inspect.
+         * @returns {number} Returns the size of `collection`.
+         * @example
+         * 
+         * _.size([1, 2, 3]); // => 3
+         * 
+         * _.size({ 'a': 1, 'b': 2 }); // => 2
+         * 
+         * _.size('pebbles'); // => 7
+         */
+        function size(collection) {
+            var length = collection ? getLength(collection) : 0;
+            return isLength(length) ? length : keys(collection).length;
+        }
+
+        module.exports = size;
+
+    }, {
+        "../internal/getLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getLength.js",
+        "../internal/isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\some.js": [function(require, module, exports) {
+        var arraySome = require('../internal/arraySome'),
+            baseCallback = require('../internal/baseCallback'),
+            baseSome = require('../internal/baseSome'),
+            isArray = require('../lang/isArray'),
+            isIterateeCall = require('../internal/isIterateeCall');
+
+        /**
+         * Checks if `predicate` returns truthy for **any** element of `collection`. The
+         * function returns as soon as it finds a passing value and does not iterate
+         * over the entire collection. The predicate is bound to `thisArg` and invoked
+         * with three arguments: (value, index|key, collection).
+         * 
+         * If a property name is provided for `predicate` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `predicate` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @alias any
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [predicate=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {boolean} Returns `true` if any element passes the predicate check,
+         *          else `false`.
+         * @example
+         * 
+         * _.some([null, 0, 'yes', false], Boolean); // => true
+         * 
+         * var users = [ { 'user': 'barney', 'active': true }, { 'user': 'fred',
+         * 'active': false } ];
+         *  // using the `_.matches` callback shorthand _.some(users, { 'user':
+         * 'barney', 'active': false }); // => false
+         *  // using the `_.matchesProperty` callback shorthand _.some(users, 'active',
+         * false); // => true
+         *  // using the `_.property` callback shorthand _.some(users, 'active'); // =>
+         * true
+         */
+        function some(collection, predicate, thisArg) {
+            var func = isArray(collection) ? arraySome : baseSome;
+            if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+                predicate = undefined;
+            }
+            if (typeof predicate != 'function' || thisArg !== undefined) {
+                predicate = baseCallback(predicate, thisArg, 3);
+            }
+            return func(collection, predicate);
+        }
+
+        module.exports = some;
+
+    }, {
+        "../internal/arraySome": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arraySome.js",
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseSome": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSome.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\collection\\sortBy.js": [function(require, module, exports) {
+        var baseCallback = require('../internal/baseCallback'),
+            baseMap = require('../internal/baseMap'),
+            baseSortBy = require('../internal/baseSortBy'),
+            compareAscending = require('../internal/compareAscending'),
+            isIterateeCall = require('../internal/isIterateeCall');
+
+        /**
+         * Creates an array of elements, sorted in ascending order by the results of
+         * running each element in a collection through `iteratee`. This method performs
+         * a stable sort, that is, it preserves the original sort order of equal
+         * elements. The `iteratee` is bound to `thisArg` and invoked with three
+         * arguments: (value, index|key, collection).
+         * 
+         * If a property name is provided for `iteratee` the created `_.property` style
+         * callback returns the property value of the given element.
+         * 
+         * If a value is also provided for `thisArg` the created `_.matchesProperty`
+         * style callback returns `true` for elements that have a matching property
+         * value, else `false`.
+         * 
+         * If an object is provided for `iteratee` the created `_.matches` style
+         * callback returns `true` for elements that have the properties of the given
+         * object, else `false`.
+         * 
+         * @static
+         * @memberOf _
+         * @category Collection
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function|Object|string}
+         *            [iteratee=_.identity] The function invoked per iteration.
+         * @param {*}
+         *            [thisArg] The `this` binding of `iteratee`.
+         * @returns {Array} Returns the new sorted array.
+         * @example
+         * 
+         * _.sortBy([1, 2, 3], function(n) { return Math.sin(n); }); // => [3, 1, 2]
+         * 
+         * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); // => [3, 1,
+         * 2]
+         * 
+         * var users = [ { 'user': 'fred' }, { 'user': 'pebbles' }, { 'user': 'barney' } ];
+         *  // using the `_.property` callback shorthand _.pluck(_.sortBy(users,
+         * 'user'), 'user'); // => ['barney', 'fred', 'pebbles']
+         */
+        function sortBy(collection, iteratee, thisArg) {
+            if (collection == null) {
+                return [];
+            }
+            if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
+                iteratee = undefined;
+            }
+            var index = -1;
+            iteratee = baseCallback(iteratee, thisArg, 3);
+
+            var result = baseMap(collection, function(value, key, collection) {
+                return {
+                    'criteria': iteratee(value, key, collection),
+                    'index': ++index,
+                    'value': value
+                };
+            });
+            return baseSortBy(result, compareAscending);
+        }
+
+        module.exports = sortBy;
+
+    }, {
+        "../internal/baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "../internal/baseMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMap.js",
+        "../internal/baseSortBy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSortBy.js",
+        "../internal/compareAscending": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\compareAscending.js",
+        "../internal/isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\date\\now.js": [function(require, module, exports) {
+        var getNative = require('../internal/getNative');
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeNow = getNative(Date, 'now');
+
+        /**
+         * Gets the number of milliseconds that have elapsed since the Unix epoch (1
+         * January 1970 00:00:00 UTC).
+         * 
+         * @static
+         * @memberOf _
+         * @category Date
+         * @example
+         * 
+         * _.defer(function(stamp) { console.log(_.now() - stamp); }, _.now()); // =>
+         * logs the number of milliseconds it took for the deferred function to be
+         * invoked
+         */
+        var now = nativeNow || function() {
+            return new Date().getTime();
+        };
+
+        module.exports = now;
+
+    }, {
+        "../internal/getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\bind.js": [function(require, module, exports) {
+        var createWrapper = require('../internal/createWrapper'),
+            replaceHolders = require('../internal/replaceHolders'),
+            restParam = require('./restParam');
+
+        /** Used to compose bitmasks for wrapper metadata. */
+        var BIND_FLAG = 1,
+            PARTIAL_FLAG = 32;
+
+        /**
+         * Creates a function that invokes `func` with the `this` binding of `thisArg`
+         * and prepends any additional `_.bind` arguments to those provided to the bound
+         * function.
+         * 
+         * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+         * may be used as a placeholder for partially applied arguments.
+         * 
+         * **Note:** Unlike native `Function#bind` this method does not set the "length"
+         * property of bound functions.
+         * 
+         * @static
+         * @memberOf _
+         * @category Function
+         * @param {Function}
+         *            func The function to bind.
+         * @param {*}
+         *            thisArg The `this` binding of `func`.
+         * @param {...*}
+         *            [partials] The arguments to be partially applied.
+         * @returns {Function} Returns the new bound function.
+         * @example
+         * 
+         * var greet = function(greeting, punctuation) { return greeting + ' ' +
+         * this.user + punctuation; };
+         * 
+         * var object = { 'user': 'fred' };
+         * 
+         * var bound = _.bind(greet, object, 'hi'); bound('!'); // => 'hi fred!'
+         *  // using placeholders var bound = _.bind(greet, object, _, '!');
+         * bound('hi'); // => 'hi fred!'
+         */
+        var bind = restParam(function(func, thisArg, partials) {
+            var bitmask = BIND_FLAG;
+            if (partials.length) {
+                var holders = replaceHolders(partials, bind.placeholder);
+                bitmask |= PARTIAL_FLAG;
+            }
+            return createWrapper(func, bitmask, thisArg, partials, holders);
+        });
+
+        // Assign default placeholders.
+        bind.placeholder = {};
+
+        module.exports = bind;
+
+    }, {
+        "../internal/createWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createWrapper.js",
+        "../internal/replaceHolders": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\replaceHolders.js",
+        "./restParam": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\debounce.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject'),
+            now = require('../date/now');
+
+        /** Used as the `TypeError` message for "Functions" methods. */
+        var FUNC_ERROR_TEXT = 'Expected a function';
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * Creates a debounced function that delays invoking `func` until after `wait`
+         * milliseconds have elapsed since the last time the debounced function was
+         * invoked. The debounced function comes with a `cancel` method to cancel
+         * delayed invocations. Provide an options object to indicate that `func` should
+         * be invoked on the leading and/or trailing edge of the `wait` timeout.
+         * Subsequent calls to the debounced function return the result of the last
+         * `func` invocation.
+         * 
+         * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
+         * on the trailing edge of the timeout only if the the debounced function is
+         * invoked more than once during the `wait` timeout.
+         * 
+         * See [David Corbacho's
+         * article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
+         * for details over the differences between `_.debounce` and `_.throttle`.
+         * 
+         * @static
+         * @memberOf _
+         * @category Function
+         * @param {Function}
+         *            func The function to debounce.
+         * @param {number}
+         *            [wait=0] The number of milliseconds to delay.
+         * @param {Object}
+         *            [options] The options object.
+         * @param {boolean}
+         *            [options.leading=false] Specify invoking on the leading edge of
+         *            the timeout.
+         * @param {number}
+         *            [options.maxWait] The maximum time `func` is allowed to be delayed
+         *            before it's invoked.
+         * @param {boolean}
+         *            [options.trailing=true] Specify invoking on the trailing edge of
+         *            the timeout.
+         * @returns {Function} Returns the new debounced function.
+         * @example
+         *  // avoid costly calculations while the window size is in flux
+         * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+         *  // invoke `sendMail` when the click event is fired, debouncing subsequent
+         * calls jQuery('#postbox').on('click', _.debounce(sendMail, 300, { 'leading':
+         * true, 'trailing': false }));
+         *  // ensure `batchLog` is invoked once after 1 second of debounced calls var
+         * source = new EventSource('/stream'); jQuery(source).on('message',
+         * _.debounce(batchLog, 250, { 'maxWait': 1000 }));
+         *  // cancel a debounced call var todoChanges = _.debounce(batchLog, 1000);
+         * Object.observe(models.todo, todoChanges);
+         * 
+         * Object.observe(models, function(changes) { if (_.find(changes, { 'user':
+         * 'todo', 'type': 'delete'})) { todoChanges.cancel(); } }, ['delete']);
+         *  // ...at some point `models.todo` is changed models.todo.completed = true;
+         *  // ...before 1 second has passed `models.todo` is deleted // which cancels
+         * the debounced `todoChanges` call delete models.todo;
+         */
+        function debounce(func, wait, options) {
+            var args,
+                maxTimeoutId,
+                result,
+                stamp,
+                thisArg,
+                timeoutId,
+                trailingCall,
+                lastCalled = 0,
+                maxWait = false,
+                trailing = true;
+
+            if (typeof func != 'function') {
+                throw new TypeError(FUNC_ERROR_TEXT);
+            }
+            wait = wait < 0 ? 0 : (+wait || 0);
+            if (options === true) {
+                var leading = true;
+                trailing = false;
+            } else if (isObject(options)) {
+                leading = !!options.leading;
+                maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
+                trailing = 'trailing' in options ? !!options.trailing : trailing;
+            }
+
+            function cancel() {
+                if (timeoutId) {
+                    clearTimeout(timeoutId);
+                }
+                if (maxTimeoutId) {
+                    clearTimeout(maxTimeoutId);
+                }
+                lastCalled = 0;
+                maxTimeoutId = timeoutId = trailingCall = undefined;
+            }
+
+            function complete(isCalled, id) {
+                if (id) {
+                    clearTimeout(id);
+                }
+                maxTimeoutId = timeoutId = trailingCall = undefined;
+                if (isCalled) {
+                    lastCalled = now();
+                    result = func.apply(thisArg, args);
+                    if (!timeoutId && !maxTimeoutId) {
+                        args = thisArg = undefined;
+                    }
+                }
+            }
+
+            function delayed() {
+                var remaining = wait - (now() - stamp);
+                if (remaining <= 0 || remaining > wait) {
+                    complete(trailingCall, maxTimeoutId);
+                } else {
+                    timeoutId = setTimeout(delayed, remaining);
+                }
+            }
+
+            function maxDelayed() {
+                complete(trailing, timeoutId);
+            }
+
+            function debounced() {
+                args = arguments;
+                stamp = now();
+                thisArg = this;
+                trailingCall = trailing && (timeoutId || !leading);
+
+                if (maxWait === false) {
+                    var leadingCall = leading && !timeoutId;
+                } else {
+                    if (!maxTimeoutId && !leading) {
+                        lastCalled = stamp;
+                    }
+                    var remaining = maxWait - (stamp - lastCalled),
+                        isCalled = remaining <= 0 || remaining > maxWait;
+
+                    if (isCalled) {
+                        if (maxTimeoutId) {
+                            maxTimeoutId = clearTimeout(maxTimeoutId);
+                        }
+                        lastCalled = stamp;
+                        result = func.apply(thisArg, args);
+                    } else if (!maxTimeoutId) {
+                        maxTimeoutId = setTimeout(maxDelayed, remaining);
+                    }
+                }
+                if (isCalled && timeoutId) {
+                    timeoutId = clearTimeout(timeoutId);
+                } else if (!timeoutId && wait !== maxWait) {
+                    timeoutId = setTimeout(delayed, wait);
+                }
+                if (leadingCall) {
+                    isCalled = true;
+                    result = func.apply(thisArg, args);
+                }
+                if (isCalled && !timeoutId && !maxTimeoutId) {
+                    args = thisArg = undefined;
+                }
+                return result;
+            }
+            debounced.cancel = cancel;
+            return debounced;
+        }
+
+        module.exports = debounce;
+
+    }, {
+        "../date/now": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\date\\now.js",
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\defer.js": [function(require, module, exports) {
+        var baseDelay = require('../internal/baseDelay'),
+            restParam = require('./restParam');
+
+        /**
+         * Defers invoking the `func` until the current call stack has cleared. Any
+         * additional arguments are provided to `func` when it's invoked.
+         * 
+         * @static
+         * @memberOf _
+         * @category Function
+         * @param {Function}
+         *            func The function to defer.
+         * @param {...*}
+         *            [args] The arguments to invoke the function with.
+         * @returns {number} Returns the timer id.
+         * @example
+         * 
+         * _.defer(function(text) { console.log(text); }, 'deferred'); // logs
+         * 'deferred' after one or more milliseconds
+         */
+        var defer = restParam(function(func, args) {
+            return baseDelay(func, 1, args);
+        });
+
+        module.exports = defer;
+
+    }, {
+        "../internal/baseDelay": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseDelay.js",
+        "./restParam": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js": [function(require, module, exports) {
+        /** Used as the `TypeError` message for "Functions" methods. */
+        var FUNC_ERROR_TEXT = 'Expected a function';
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * Creates a function that invokes `func` with the `this` binding of the created
+         * function and arguments from `start` and beyond provided as an array.
+         * 
+         * **Note:** This method is based on the [rest
+         * parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
+         * 
+         * @static
+         * @memberOf _
+         * @category Function
+         * @param {Function}
+         *            func The function to apply a rest parameter to.
+         * @param {number}
+         *            [start=func.length-1] The start position of the rest parameter.
+         * @returns {Function} Returns the new function.
+         * @example
+         * 
+         * var say = _.restParam(function(what, names) { return what + ' ' +
+         * _.initial(names).join(', ') + (_.size(names) > 1 ? ', & ' : '') +
+         * _.last(names); });
+         * 
+         * say('hello', 'fred', 'barney', 'pebbles'); // => 'hello fred, barney, &
+         * pebbles'
+         */
+        function restParam(func, start) {
+            if (typeof func != 'function') {
+                throw new TypeError(FUNC_ERROR_TEXT);
+            }
+            start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+            return function() {
+                var args = arguments,
+                    index = -1,
+                    length = nativeMax(args.length - start, 0),
+                    rest = Array(length);
+
+                while (++index < length) {
+                    rest[index] = args[start + index];
+                }
+                switch (start) {
+                    case 0:
+                        return func.call(this, rest);
+                    case 1:
+                        return func.call(this, args[0], rest);
+                    case 2:
+                        return func.call(this, args[0], args[1], rest);
+                }
+                var otherArgs = Array(start + 1);
+                index = -1;
+                while (++index < start) {
+                    otherArgs[index] = args[index];
+                }
+                otherArgs[start] = rest;
+                return func.apply(this, otherArgs);
+            };
+        }
+
+        module.exports = restParam;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\index.js": [function(require, module, exports) {
+        (function(global) {
+            /**
+             * @license lodash 3.10.1 (Custom Build) <https://lodash.com/> Build: `lodash
+             *          modern -d -o ./index.js` Copyright 2012-2015 The Dojo Foundation
+             *          <http://dojofoundation.org/> Based on Underscore.js 1.8.3
+             *          <http://underscorejs.org/LICENSE> Copyright 2009-2015 Jeremy
+             *          Ashkenas, DocumentCloud and Investigative Reporters & Editors
+             *          Available under MIT license <https://lodash.com/license>
+             */
+            ;
+            (function() {
+
+                /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+                var undefined;
+
+                /** Used as the semantic version number. */
+                var VERSION = '3.10.1';
+
+                /** Used to compose bitmasks for wrapper metadata. */
+                var BIND_FLAG = 1,
+                    BIND_KEY_FLAG = 2,
+                    CURRY_BOUND_FLAG = 4,
+                    CURRY_FLAG = 8,
+                    CURRY_RIGHT_FLAG = 16,
+                    PARTIAL_FLAG = 32,
+                    PARTIAL_RIGHT_FLAG = 64,
+                    ARY_FLAG = 128,
+                    REARG_FLAG = 256;
+
+                /** Used as default options for `_.trunc`. */
+                var DEFAULT_TRUNC_LENGTH = 30,
+                    DEFAULT_TRUNC_OMISSION = '...';
+
+                /** Used to detect when a function becomes hot. */
+                var HOT_COUNT = 150,
+                    HOT_SPAN = 16;
+
+                /** Used as the size to enable large array optimizations. */
+                var LARGE_ARRAY_SIZE = 200;
+
+                /** Used to indicate the type of lazy iteratees. */
+                var LAZY_FILTER_FLAG = 1,
+                    LAZY_MAP_FLAG = 2;
+
+                /** Used as the `TypeError` message for "Functions" methods. */
+                var FUNC_ERROR_TEXT = 'Expected a function';
+
+                /** Used as the internal argument placeholder. */
+                var PLACEHOLDER = '__lodash_placeholder__';
+
+                /** `Object#toString` result references. */
+                var argsTag = '[object Arguments]',
+                    arrayTag = '[object Array]',
+                    boolTag = '[object Boolean]',
+                    dateTag = '[object Date]',
+                    errorTag = '[object Error]',
+                    funcTag = '[object Function]',
+                    mapTag = '[object Map]',
+                    numberTag = '[object Number]',
+                    objectTag = '[object Object]',
+                    regexpTag = '[object RegExp]',
+                    setTag = '[object Set]',
+                    stringTag = '[object String]',
+                    weakMapTag = '[object WeakMap]';
+
+                var arrayBufferTag = '[object ArrayBuffer]',
+                    float32Tag = '[object Float32Array]',
+                    float64Tag = '[object Float64Array]',
+                    int8Tag = '[object Int8Array]',
+                    int16Tag = '[object Int16Array]',
+                    int32Tag = '[object Int32Array]',
+                    uint8Tag = '[object Uint8Array]',
+                    uint8ClampedTag = '[object Uint8ClampedArray]',
+                    uint16Tag = '[object Uint16Array]',
+                    uint32Tag = '[object Uint32Array]';
+
+                /** Used to match empty string literals in compiled template source. */
+                var reEmptyStringLeading = /\b__p \+= '';/g,
+                    reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
+                    reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
+
+                /** Used to match HTML entities and HTML characters. */
+                var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
+                    reUnescapedHtml = /[&<>"'`]/g,
+                    reHasEscapedHtml = RegExp(reEscapedHtml.source),
+                    reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+                /** Used to match template delimiters. */
+                var reEscape = /<%-([\s\S]+?)%>/g,
+                    reEvaluate = /<%([\s\S]+?)%>/g,
+                    reInterpolate = /<%=([\s\S]+?)%>/g;
+
+                /** Used to match property names within property paths. */
+                var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+                    reIsPlainProp = /^\w*$/,
+                    rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+
+                /**
+                 * Used to match `RegExp` [syntax
+                 * characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) and
+                 * those outlined by
+                 * [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern).
+                 */
+                var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,
+                    reHasRegExpChars = RegExp(reRegExpChars.source);
+
+                /**
+                 * Used to match [combining diacritical
+                 * marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+                 */
+                var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g;
+
+                /** Used to match backslashes in property paths. */
+                var reEscapeChar = /\\(\\)?/g;
+
+                /**
+                 * Used to match [ES template
+                 * delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components).
+                 */
+                var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
+
+                /** Used to match `RegExp` flags from their coerced string values. */
+                var reFlags = /\w*$/;
+
+                /** Used to detect hexadecimal string values. */
+                var reHasHexPrefix = /^0[xX]/;
+
+                /** Used to detect host constructors (Safari > 5). */
+                var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+                /** Used to detect unsigned integer values. */
+                var reIsUint = /^\d+$/;
+
+                /**
+                 * Used to match latin-1 supplementary letters (excluding mathematical
+                 * operators).
+                 */
+                var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
+
+                /** Used to ensure capturing order of template delimiters. */
+                var reNoMatch = /($^)/;
+
+                /** Used to match unescaped characters in compiled string literals. */
+                var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
+
+                /** Used to match words to create compound words. */
+                var reWords = (function() {
+                    var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]',
+                        lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+';
+
+                    return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g');
+                }());
+
+                /** Used to assign default `context` object properties. */
+                var contextProps = [
+                    'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
+                    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number',
+                    'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite',
+                    'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array',
+                    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap'
+                ];
+
+                /** Used to make template sourceURLs easier to identify. */
+                var templateCounter = -1;
+
+                /** Used to identify `toStringTag` values of typed arrays. */
+                var typedArrayTags = {};
+                typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+                    typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+                    typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+                    typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+                    typedArrayTags[uint32Tag] = true;
+                typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+                    typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+                    typedArrayTags[dateTag] = typedArrayTags[errorTag] =
+                    typedArrayTags[funcTag] = typedArrayTags[mapTag] =
+                    typedArrayTags[numberTag] = typedArrayTags[objectTag] =
+                    typedArrayTags[regexpTag] = typedArrayTags[setTag] =
+                    typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
+
+                /** Used to identify `toStringTag` values supported by `_.clone`. */
+                var cloneableTags = {};
+                cloneableTags[argsTag] = cloneableTags[arrayTag] =
+                    cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+                    cloneableTags[dateTag] = cloneableTags[float32Tag] =
+                    cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+                    cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+                    cloneableTags[numberTag] = cloneableTags[objectTag] =
+                    cloneableTags[regexpTag] = cloneableTags[stringTag] =
+                    cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+                    cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+                cloneableTags[errorTag] = cloneableTags[funcTag] =
+                    cloneableTags[mapTag] = cloneableTags[setTag] =
+                    cloneableTags[weakMapTag] = false;
+
+                /** Used to map latin-1 supplementary letters to basic latin letters. */
+                var deburredLetters = {
+                    '\xc0': 'A',
+                    '\xc1': 'A',
+                    '\xc2': 'A',
+                    '\xc3': 'A',
+                    '\xc4': 'A',
+                    '\xc5': 'A',
+                    '\xe0': 'a',
+                    '\xe1': 'a',
+                    '\xe2': 'a',
+                    '\xe3': 'a',
+                    '\xe4': 'a',
+                    '\xe5': 'a',
+                    '\xc7': 'C',
+                    '\xe7': 'c',
+                    '\xd0': 'D',
+                    '\xf0': 'd',
+                    '\xc8': 'E',
+                    '\xc9': 'E',
+                    '\xca': 'E',
+                    '\xcb': 'E',
+                    '\xe8': 'e',
+                    '\xe9': 'e',
+                    '\xea': 'e',
+                    '\xeb': 'e',
+                    '\xcC': 'I',
+                    '\xcd': 'I',
+                    '\xce': 'I',
+                    '\xcf': 'I',
+                    '\xeC': 'i',
+                    '\xed': 'i',
+                    '\xee': 'i',
+                    '\xef': 'i',
+                    '\xd1': 'N',
+                    '\xf1': 'n',
+                    '\xd2': 'O',
+                    '\xd3': 'O',
+                    '\xd4': 'O',
+                    '\xd5': 'O',
+                    '\xd6': 'O',
+                    '\xd8': 'O',
+                    '\xf2': 'o',
+                    '\xf3': 'o',
+                    '\xf4': 'o',
+                    '\xf5': 'o',
+                    '\xf6': 'o',
+                    '\xf8': 'o',
+                    '\xd9': 'U',
+                    '\xda': 'U',
+                    '\xdb': 'U',
+                    '\xdc': 'U',
+                    '\xf9': 'u',
+                    '\xfa': 'u',
+                    '\xfb': 'u',
+                    '\xfc': 'u',
+                    '\xdd': 'Y',
+                    '\xfd': 'y',
+                    '\xff': 'y',
+                    '\xc6': 'Ae',
+                    '\xe6': 'ae',
+                    '\xde': 'Th',
+                    '\xfe': 'th',
+                    '\xdf': 'ss'
+                };
+
+                /** Used to map characters to HTML entities. */
+                var htmlEscapes = {
+                    '&': '&amp;',
+                    '<': '&lt;',
+                    '>': '&gt;',
+                    '"': '&quot;',
+                    "'": '&#39;',
+                    '`': '&#96;'
+                };
+
+                /** Used to map HTML entities to characters. */
+                var htmlUnescapes = {
+                    '&amp;': '&',
+                    '&lt;': '<',
+                    '&gt;': '>',
+                    '&quot;': '"',
+                    '&#39;': "'",
+                    '&#96;': '`'
+                };
+
+                /** Used to determine if values are of the language type `Object`. */
+                var objectTypes = {
+                    'function': true,
+                    'object': true
+                };
+
+                /** Used to escape characters for inclusion in compiled regexes. */
+                var regexpEscapes = {
+                    '0': 'x30',
+                    '1': 'x31',
+                    '2': 'x32',
+                    '3': 'x33',
+                    '4': 'x34',
+                    '5': 'x35',
+                    '6': 'x36',
+                    '7': 'x37',
+                    '8': 'x38',
+                    '9': 'x39',
+                    'A': 'x41',
+                    'B': 'x42',
+                    'C': 'x43',
+                    'D': 'x44',
+                    'E': 'x45',
+                    'F': 'x46',
+                    'a': 'x61',
+                    'b': 'x62',
+                    'c': 'x63',
+                    'd': 'x64',
+                    'e': 'x65',
+                    'f': 'x66',
+                    'n': 'x6e',
+                    'r': 'x72',
+                    't': 'x74',
+                    'u': 'x75',
+                    'v': 'x76',
+                    'x': 'x78'
+                };
+
+                /** Used to escape characters for inclusion in compiled string literals. */
+                var stringEscapes = {
+                    '\\': '\\',
+                    "'": "'",
+                    '\n': 'n',
+                    '\r': 'r',
+                    '\u2028': 'u2028',
+                    '\u2029': 'u2029'
+                };
+
+                /** Detect free variable `exports`. */
+                var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
+
+                /** Detect free variable `module`. */
+                var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
+
+                /** Detect free variable `global` from Node.js. */
+                var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
+
+                /** Detect free variable `self`. */
+                var freeSelf = objectTypes[typeof self] && self && self.Object && self;
+
+                /** Detect free variable `window`. */
+                var freeWindow = objectTypes[typeof window] && window && window.Object && window;
+
+                /** Detect the popular CommonJS extension `module.exports`. */
+                var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
+
+                /**
+                 * Used as a reference to the global object.
+                 * 
+                 * The `this` value is used if it's the global object to avoid
+                 * Greasemonkey's restricted `window` object, otherwise the `window` object
+                 * is used.
+                 */
+                var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
+
+                /*--------------------------------------------------------------------------*/
+
+                /**
+                 * The base implementation of `compareAscending` which compares values and
+                 * sorts them in ascending order without guaranteeing a stable sort.
+                 * 
+                 * @private
+                 * @param {*}
+                 *            value The value to compare.
+                 * @param {*}
+                 *            other The other value to compare.
+                 * @returns {number} Returns the sort order indicator for `value`.
+                 */
+                function baseCompareAscending(value, other) {
+                    if (value !== other) {
+                        var valIsNull = value === null,
+                            valIsUndef = value === undefined,
+                            valIsReflexive = value === value;
+
+                        var othIsNull = other === null,
+                            othIsUndef = other === undefined,
+                            othIsReflexive = other === other;
+
+                        if ((value > other && !othIsNull) || !valIsReflexive ||
+                            (valIsNull && !othIsUndef && othIsReflexive) ||
+                            (valIsUndef && othIsReflexive)) {
+                            return 1;
+                        }
+                        if ((value < other && !valIsNull) || !othIsReflexive ||
+                            (othIsNull && !valIsUndef && valIsReflexive) ||
+                            (othIsUndef && valIsReflexive)) {
+                            return -1;
+                        }
+                    }
+                    return 0;
+                }
+
+                /**
+                 * The base implementation of `_.findIndex` and `_.findLastIndex` without
+                 * support for callback shorthands and `this` binding.
+                 * 
+                 * @private
+                 * @param {Array}
+                 *            array The array to search.
+                 * @param {Function}
+                 *            predicate The function invoked per iteration.
+                 * @param {boolean}
+                 *            [fromRight] Specify iterating from right to left.
+                 * @returns {number} Returns the index of the matched value, else `-1`.
+                 */
+                function baseFindIndex(array, predicate, fromRight) {
+                    var length = array.length,
+                        index = fromRight ? length : -1;
+
+                    while ((fromRight ? index-- : ++index < length)) {
+                        if (predicate(array[index], index, array)) {
+                            return index;
+                        }
+                    }
+                    return -1;
+                }
+
+                /**
+                 * The base implementation of `_.indexOf` without support for binary
+                 * searches.
+                 * 
+                 * @private
+                 * @param {Array}
+                 *            array The array to search.
+                 * @param {*}
+                 *            value The value to search for.
+                 * @param {number}
+                 *            fromIndex The index to search from.
+                 * @returns {number} Returns the index of the matched value, else `-1`.
+                 */
+                function baseIndexOf(array, value, fromIndex) {
+                    if (value !== value) {
+                        return indexOfNaN(array, fromIndex);
+                    }
+                    var index = fromIndex - 1,
+                        length = array.length;
+
+                    while (++index < length) {
+                        if (array[index] === value) {
+                            return index;
+                        }
+                    }
+                    return -1;
+                }
+
+                /**
+                 * The base implementation of `_.isFunction` without support for
+                 * environments with incorrect `typeof` results.
+                 * 
+                 * @private
+                 * @param {*}
+                 *            value The value to check.
+                 * @returns {boolean} Returns `true` if `value` is correctly classified,
+                 *          else `false`.
+                 */
+                function baseIsFunction(value) {
+                    // Avoid a Chakra JIT bug in compatibility modes of IE 11.
+                    // See https://github.com/jashkenas/underscore/issues/1621 for more details.
+                    return typeof value == 'function' || false;
+                }
+
+                /**
+                 * Converts `value` to a string if it's not one. An empty string is returned
+                 * for `null` or `undefined` values.
+                 * 
+                 * @private
+                 * @param {*}
+                 *            value The value to process.
+                 * @returns {string} Returns the string.
+                 */
+                function baseToString(value) {
+                    return value == null ? '' : (value + '');
+                }
+
+                /**
+                 * Used by `_.trim` and `_.trimLeft` to get the index of the first character
+                 * of `string` that is not found in `chars`.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            string The string to inspect.
+                 * @param {string}
+                 *            chars The characters to find.
+                 * @returns {number} Returns the index of the first character not found in
+                 *          `chars`.
+                 */
+                function charsLeftIndex(string, chars) {
+                    var index = -1,
+                        length = string.length;
+
+                    while (++index < length && chars.indexOf(string.charAt(index)) > -1) {}
+                    return index;
+                }
+
+                /**
+                 * Used by `_.trim` and `_.trimRight` to get the index of the last character
+                 * of `string` that is not found in `chars`.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            string The string to inspect.
+                 * @param {string}
+                 *            chars The characters to find.
+                 * @returns {number} Returns the index of the last character not found in
+                 *          `chars`.
+                 */
+                function charsRightIndex(string, chars) {
+                    var index = string.length;
+
+                    while (index-- && chars.indexOf(string.charAt(index)) > -1) {}
+                    return index;
+                }
+
+                /**
+                 * Used by `_.sortBy` to compare transformed elements of a collection and
+                 * stable sort them in ascending order.
+                 * 
+                 * @private
+                 * @param {Object}
+                 *            object The object to compare.
+                 * @param {Object}
+                 *            other The other object to compare.
+                 * @returns {number} Returns the sort order indicator for `object`.
+                 */
+                function compareAscending(object, other) {
+                    return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
+                }
+
+                /**
+                 * Used by `_.sortByOrder` to compare multiple properties of a value to
+                 * another and stable sort them.
+                 * 
+                 * If `orders` is unspecified, all valuess are sorted in ascending order.
+                 * Otherwise, a value is sorted in ascending order if its corresponding
+                 * order is "asc", and descending if "desc".
+                 * 
+                 * @private
+                 * @param {Object}
+                 *            object The object to compare.
+                 * @param {Object}
+                 *            other The other object to compare.
+                 * @param {boolean[]}
+                 *            orders The order to sort by for each property.
+                 * @returns {number} Returns the sort order indicator for `object`.
+                 */
+                function compareMultiple(object, other, orders) {
+                    var index = -1,
+                        objCriteria = object.criteria,
+                        othCriteria = other.criteria,
+                        length = objCriteria.length,
+                        ordersLength = orders.length;
+
+                    while (++index < length) {
+                        var result = baseCompareAscending(objCriteria[index], othCriteria[index]);
+                        if (result) {
+                            if (index >= ordersLength) {
+                                return result;
+                            }
+                            var order = orders[index];
+                            return result * ((order === 'asc' || order === true) ? 1 : -1);
+                        }
+                    }
+                    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
+                    // that causes it, under certain circumstances, to provide the same value
+                    // for
+                    // `object` and `other`. See
+                    // https://github.com/jashkenas/underscore/pull/1247
+                    // for more details.
+                    //
+                    // This also ensures a stable sort in V8 and other engines.
+                    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
+                    return object.index - other.index;
+                }
+
+                /**
+                 * Used by `_.deburr` to convert latin-1 supplementary letters to basic
+                 * latin letters.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            letter The matched letter to deburr.
+                 * @returns {string} Returns the deburred letter.
+                 */
+                function deburrLetter(letter) {
+                    return deburredLetters[letter];
+                }
+
+                /**
+                 * Used by `_.escape` to convert characters to HTML entities.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            chr The matched character to escape.
+                 * @returns {string} Returns the escaped character.
+                 */
+                function escapeHtmlChar(chr) {
+                    return htmlEscapes[chr];
+                }
+
+                /**
+                 * Used by `_.escapeRegExp` to escape characters for inclusion in compiled
+                 * regexes.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            chr The matched character to escape.
+                 * @param {string}
+                 *            leadingChar The capture group for a leading character.
+                 * @param {string}
+                 *            whitespaceChar The capture group for a whitespace character.
+                 * @returns {string} Returns the escaped character.
+                 */
+                function escapeRegExpChar(chr, leadingChar, whitespaceChar) {
+                    if (leadingChar) {
+                        chr = regexpEscapes[chr];
+                    } else if (whitespaceChar) {
+                        chr = stringEscapes[chr];
+                    }
+                    return '\\' + chr;
+                }
+
+                /**
+                 * Used by `_.template` to escape characters for inclusion in compiled
+                 * string literals.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            chr The matched character to escape.
+                 * @returns {string} Returns the escaped character.
+                 */
+                function escapeStringChar(chr) {
+                    return '\\' + stringEscapes[chr];
+                }
+
+                /**
+                 * Gets the index at which the first occurrence of `NaN` is found in
+                 * `array`.
+                 * 
+                 * @private
+                 * @param {Array}
+                 *            array The array to search.
+                 * @param {number}
+                 *            fromIndex The index to search from.
+                 * @param {boolean}
+                 *            [fromRight] Specify iterating from right to left.
+                 * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+                 */
+                function indexOfNaN(array, fromIndex, fromRight) {
+                    var length = array.length,
+                        index = fromIndex + (fromRight ? 0 : -1);
+
+                    while ((fromRight ? index-- : ++index < length)) {
+                        var other = array[index];
+                        if (other !== other) {
+                            return index;
+                        }
+                    }
+                    return -1;
+                }
+
+                /**
+                 * Checks if `value` is object-like.
+                 * 
+                 * @private
+                 * @param {*}
+                 *            value The value to check.
+                 * @returns {boolean} Returns `true` if `value` is object-like, else
+                 *          `false`.
+                 */
+                function isObjectLike(value) {
+                    return !!value && typeof value == 'object';
+                }
+
+                /**
+                 * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a
+                 * character code is whitespace.
+                 * 
+                 * @private
+                 * @param {number}
+                 *            charCode The character code to inspect.
+                 * @returns {boolean} Returns `true` if `charCode` is whitespace, else
+                 *          `false`.
+                 */
+                function isSpace(charCode) {
+                    return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 ||
+                        (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279)));
+                }
+
+                /**
+                 * Replaces all `placeholder` elements in `array` with an internal
+                 * placeholder and returns an array of their indexes.
+                 * 
+                 * @private
+                 * @param {Array}
+                 *            array The array to modify.
+                 * @param {*}
+                 *            placeholder The placeholder to replace.
+                 * @returns {Array} Returns the new array of placeholder indexes.
+                 */
+                function replaceHolders(array, placeholder) {
+                    var index = -1,
+                        length = array.length,
+                        resIndex = -1,
+                        result = [];
+
+                    while (++index < length) {
+                        if (array[index] === placeholder) {
+                            array[index] = PLACEHOLDER;
+                            result[++resIndex] = index;
+                        }
+                    }
+                    return result;
+                }
+
+                /**
+                 * An implementation of `_.uniq` optimized for sorted arrays without support
+                 * for callback shorthands and `this` binding.
+                 * 
+                 * @private
+                 * @param {Array}
+                 *            array The array to inspect.
+                 * @param {Function}
+                 *            [iteratee] The function invoked per iteration.
+                 * @returns {Array} Returns the new duplicate-value-free array.
+                 */
+                function sortedUniq(array, iteratee) {
+                    var seen,
+                        index = -1,
+                        length = array.length,
+                        resIndex = -1,
+                        result = [];
+
+                    while (++index < length) {
+                        var value = array[index],
+                            computed = iteratee ? iteratee(value, index, array) : value;
+
+                        if (!index || seen !== computed) {
+                            seen = computed;
+                            result[++resIndex] = value;
+                        }
+                    }
+                    return result;
+                }
+
+                /**
+                 * Used by `_.trim` and `_.trimLeft` to get the index of the first
+                 * non-whitespace character of `string`.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            string The string to inspect.
+                 * @returns {number} Returns the index of the first non-whitespace
+                 *          character.
+                 */
+                function trimmedLeftIndex(string) {
+                    var index = -1,
+                        length = string.length;
+
+                    while (++index < length && isSpace(string.charCodeAt(index))) {}
+                    return index;
+                }
+
+                /**
+                 * Used by `_.trim` and `_.trimRight` to get the index of the last
+                 * non-whitespace character of `string`.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            string The string to inspect.
+                 * @returns {number} Returns the index of the last non-whitespace character.
+                 */
+                function trimmedRightIndex(string) {
+                    var index = string.length;
+
+                    while (index-- && isSpace(string.charCodeAt(index))) {}
+                    return index;
+                }
+
+                /**
+                 * Used by `_.unescape` to convert HTML entities to characters.
+                 * 
+                 * @private
+                 * @param {string}
+                 *            chr The matched character to unescape.
+                 * @returns {string} Returns the unescaped character.
+                 */
+                function unescapeHtmlChar(chr) {
+                    return htmlUnescapes[chr];
+                }
+
+                /*--------------------------------------------------------------------------*/
+
+                /**
+                 * Create a new pristine `lodash` function using the given `context` object.
+                 * 
+                 * @static
+                 * @memberOf _
+                 * @category Utility
+                 * @param {Object}
+                 *            [context=root] The context object.
+                 * @returns {Function} Returns a new `lodash` function.
+                 * @example
+                 * 
+                 * _.mixin({ 'foo': _.constant('foo') });
+                 * 
+                 * var lodash = _.runInContext(); lodash.mixin({ 'bar':
+                 * lodash.constant('bar') });
+                 * 
+                 * _.isFunction(_.foo); // => true _.isFunction(_.bar); // => false
+                 * 
+                 * lodash.isFunction(lodash.foo); // => false lodash.isFunction(lodash.bar); // =>
+                 * true
+                 *  // using `context` to mock `Date#getTime` use in `_.now` var mock =
+                 * _.runInContext({ 'Date': function() { return { 'getTime': getTimeMock }; }
+                 * });
+                 *  // or creating a suped-up `defer` in Node.js var defer =
+                 * _.runInContext({ 'setTimeout': setImmediate }).defer;
+                 */
+                function runInContext(context) {
+                    // Avoid issues with some ES3 environments that attempt to use values, named
+                    // after built-in constructors like `Object`, for the creation of literals.
+                    // ES5 clears this up by stating that literals must use built-in
+                    // constructors.
+                    // See https://es5.github.io/#x11.1.5 for more details.
+                    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
+
+                    /** Native constructor references. */
+                    var Array = context.Array,
+                        Date = context.Date,
+                        Error = context.Error,
+                        Function = context.Function,
+                        Math = context.Math,
+                        Number = context.Number,
+                        Object = context.Object,
+                        RegExp = context.RegExp,
+                        String = context.String,
+                        TypeError = context.TypeError;
+
+                    /** Used for native method references. */
+                    var arrayProto = Array.prototype,
+                        objectProto = Object.prototype,
+                        stringProto = String.prototype;
+
+                    /** Used to resolve the decompiled source of functions. */
+                    var fnToString = Function.prototype.toString;
+
+                    /** Used to check objects for own properties. */
+                    var hasOwnProperty = objectProto.hasOwnProperty;
+
+                    /** Used to generate unique IDs. */
+                    var idCounter = 0;
+
+                    /**
+                     * Used to resolve the
+                     * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+                     * of values.
+                     */
+                    var objToString = objectProto.toString;
+
+                    /** Used to restore the original `_` reference in `_.noConflict`. */
+                    var oldDash = root._;
+
+                    /** Used to detect if a method is native. */
+                    var reIsNative = RegExp('^' +
+                        fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+                        .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+                    );
+
+                    /** Native method references. */
+                    var ArrayBuffer = context.ArrayBuffer,
+                        clearTimeout = context.clearTimeout,
+                        parseFloat = context.parseFloat,
+                        pow = Math.pow,
+                        propertyIsEnumerable = objectProto.propertyIsEnumerable,
+                        Set = getNative(context, 'Set'),
+                        setTimeout = context.setTimeout,
+                        splice = arrayProto.splice,
+                        Uint8Array = context.Uint8Array,
+                        WeakMap = getNative(context, 'WeakMap');
+
+                    /*
+                     * Native method references for those with the same name as other `lodash`
+                     * methods.
+                     */
+                    var nativeCeil = Math.ceil,
+                        nativeCreate = getNative(Object, 'create'),
+                        nativeFloor = Math.floor,
+                        nativeIsArray = getNative(Array, 'isArray'),
+                        nativeIsFinite = context.isFinite,
+                        nativeKeys = getNative(Object, 'keys'),
+                        nativeMax = Math.max,
+                        nativeMin = Math.min,
+                        nativeNow = getNative(Date, 'now'),
+                        nativeParseInt = context.parseInt,
+                        nativeRandom = Math.random;
+
+                    /** Used as references for `-Infinity` and `Infinity`. */
+                    var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,
+                        POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+
+                    /** Used as references for the maximum length and index of an array. */
+                    var MAX_ARRAY_LENGTH = 4294967295,
+                        MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
+                        HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
+                    /**
+                     * Used as the [maximum
+                     * length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+                     * of an array-like value.
+                     */
+                    var MAX_SAFE_INTEGER = 9007199254740991;
+
+                    /** Used to store function metadata. */
+                    var metaMap = WeakMap && new WeakMap;
+
+                    /** Used to lookup unminified function names. */
+                    var realNames = {};
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a `lodash` object which wraps `value` to enable implicit
+                     * chaining. Methods that operate on and return arrays, collections, and
+                     * functions can be chained together. Methods that retrieve a single value
+                     * or may return a primitive value will automatically end the chain
+                     * returning the unwrapped value. Explicit chaining may be enabled using
+                     * `_.chain`. The execution of chained methods is lazy, that is, execution
+                     * is deferred until `_#value` is implicitly or explicitly called.
+                     * 
+                     * Lazy evaluation allows several methods to support shortcut fusion.
+                     * Shortcut fusion is an optimization strategy which merge iteratee calls;
+                     * this can help to avoid the creation of intermediate data structures and
+                     * greatly reduce the number of iteratee executions.
+                     * 
+                     * Chaining is supported in custom builds as long as the `_#value` method is
+                     * directly or indirectly included in the build.
+                     * 
+                     * In addition to lodash methods, wrappers have `Array` and `String`
+                     * methods.
+                     * 
+                     * The wrapper `Array` methods are: `concat`, `join`, `pop`, `push`,
+                     * `reverse`, `shift`, `slice`, `sort`, `splice`, and `unshift`
+                     * 
+                     * The wrapper `String` methods are: `replace` and `split`
+                     * 
+                     * The wrapper methods that support shortcut fusion are: `compact`, `drop`,
+                     * `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `first`, `initial`,
+                     * `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, `slice`, `take`,
+                     * `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, and `where`
+                     * 
+                     * The chainable wrapper methods are: `after`, `ary`, `assign`, `at`,
+                     * `before`, `bind`, `bindAll`, `bindKey`, `callback`, `chain`, `chunk`,
+                     * `commit`, `compact`, `concat`, `constant`, `countBy`, `create`, `curry`,
+                     * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
+                     * `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, `filter`,
+                     * `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, `forEachRight`,
+                     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, `groupBy`,
+                     * `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
+                     * `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
+                     * `memoize`, `merge`, `method`, `methodOf`, `mixin`, `modArgs`, `negate`,
+                     * `omit`, `once`, `pairs`, `partial`, `partialRight`, `partition`, `pick`,
+                     * `plant`, `pluck`, `property`, `propertyOf`, `pull`, `pullAt`, `push`,
+                     * `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, `reverse`,
+                     * `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`,
+                     * `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`,
+                     * `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
+                     * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
+                     * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`,
+                     * `zipWith`
+                     * 
+                     * The wrapper methods that are **not** chainable by default are: `add`,
+                     * `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
+                     * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`,
+                     * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`,
+                     * `findWhere`, `first`, `floor`, `get`, `gt`, `gte`, `has`, `identity`,
+                     * `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`, `isBoolean`,
+                     * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`
+                     * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
+                     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
+                     * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`,
+                     * `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`,
+                     * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`,
+                     * `round`, `runInContext`, `shift`, `size`, `snakeCase`, `some`,
+                     * `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`, `sum`,
+                     * `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`,
+                     * `uniqueId`, `value`, and `words`
+                     * 
+                     * The wrapper method `sample` will return a wrapped value when `n` is
+                     * provided, otherwise an unwrapped value is returned.
+                     * 
+                     * @name _
+                     * @constructor
+                     * @category Chain
+                     * @param {*}
+                     *            value The value to wrap in a `lodash` instance.
+                     * @returns {Object} Returns the new `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var wrapped = _([1, 2, 3]);
+                     *  // returns an unwrapped value wrapped.reduce(function(total, n) { return
+                     * total + n; }); // => 6
+                     *  // returns a wrapped value var squares = wrapped.map(function(n) {
+                     * return n * n; });
+                     * 
+                     * _.isArray(squares); // => false
+                     * 
+                     * _.isArray(squares.value()); // => true
+                     */
+                    function lodash(value) {
+                        if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+                            if (value instanceof LodashWrapper) {
+                                return value;
+                            }
+                            if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
+                                return wrapperClone(value);
+                            }
+                        }
+                        return new LodashWrapper(value);
+                    }
+
+                    /**
+                     * The function whose prototype all chaining wrappers inherit from.
+                     * 
+                     * @private
+                     */
+                    function baseLodash() {
+                        // No operation performed.
+                    }
+
+                    /**
+                     * The base constructor for creating `lodash` wrapper objects.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to wrap.
+                     * @param {boolean}
+                     *            [chainAll] Enable chaining for all wrapper methods.
+                     * @param {Array}
+                     *            [actions=[]] Actions to peform to resolve the unwrapped value.
+                     */
+                    function LodashWrapper(value, chainAll, actions) {
+                        this.__wrapped__ = value;
+                        this.__actions__ = actions || [];
+                        this.__chain__ = !!chainAll;
+                    }
+
+                    /**
+                     * An object environment feature flags.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @type Object
+                     */
+                    var support = lodash.support = {};
+
+                    /**
+                     * By default, the template delimiters used by lodash are like those in
+                     * embedded Ruby (ERB). Change the following template settings to use
+                     * alternative delimiters.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @type Object
+                     */
+                    lodash.templateSettings = {
+
+                        /**
+                         * Used to detect `data` property values to be HTML-escaped.
+                         * 
+                         * @memberOf _.templateSettings
+                         * @type RegExp
+                         */
+                        'escape': reEscape,
+
+                        /**
+                         * Used to detect code to be evaluated.
+                         * 
+                         * @memberOf _.templateSettings
+                         * @type RegExp
+                         */
+                        'evaluate': reEvaluate,
+
+                        /**
+                         * Used to detect `data` property values to inject.
+                         * 
+                         * @memberOf _.templateSettings
+                         * @type RegExp
+                         */
+                        'interpolate': reInterpolate,
+
+                        /**
+                         * Used to reference the data object in the template text.
+                         * 
+                         * @memberOf _.templateSettings
+                         * @type string
+                         */
+                        'variable': '',
+
+                        /**
+                         * Used to import variables into the compiled template.
+                         * 
+                         * @memberOf _.templateSettings
+                         * @type Object
+                         */
+                        'imports': {
+
+                            /**
+                             * A reference to the `lodash` function.
+                             * 
+                             * @memberOf _.templateSettings.imports
+                             * @type Function
+                             */
+                            '_': lodash
+                        }
+                    };
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a lazy wrapper object which wraps `value` to enable lazy
+                     * evaluation.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to wrap.
+                     */
+                    function LazyWrapper(value) {
+                        this.__wrapped__ = value;
+                        this.__actions__ = [];
+                        this.__dir__ = 1;
+                        this.__filtered__ = false;
+                        this.__iteratees__ = [];
+                        this.__takeCount__ = POSITIVE_INFINITY;
+                        this.__views__ = [];
+                    }
+
+                    /**
+                     * Creates a clone of the lazy wrapper object.
+                     * 
+                     * @private
+                     * @name clone
+                     * @memberOf LazyWrapper
+                     * @returns {Object} Returns the cloned `LazyWrapper` object.
+                     */
+                    function lazyClone() {
+                        var result = new LazyWrapper(this.__wrapped__);
+                        result.__actions__ = arrayCopy(this.__actions__);
+                        result.__dir__ = this.__dir__;
+                        result.__filtered__ = this.__filtered__;
+                        result.__iteratees__ = arrayCopy(this.__iteratees__);
+                        result.__takeCount__ = this.__takeCount__;
+                        result.__views__ = arrayCopy(this.__views__);
+                        return result;
+                    }
+
+                    /**
+                     * Reverses the direction of lazy iteration.
+                     * 
+                     * @private
+                     * @name reverse
+                     * @memberOf LazyWrapper
+                     * @returns {Object} Returns the new reversed `LazyWrapper` object.
+                     */
+                    function lazyReverse() {
+                        if (this.__filtered__) {
+                            var result = new LazyWrapper(this);
+                            result.__dir__ = -1;
+                            result.__filtered__ = true;
+                        } else {
+                            result = this.clone();
+                            result.__dir__ *= -1;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Extracts the unwrapped value from its lazy wrapper.
+                     * 
+                     * @private
+                     * @name value
+                     * @memberOf LazyWrapper
+                     * @returns {*} Returns the unwrapped value.
+                     */
+                    function lazyValue() {
+                        var array = this.__wrapped__.value(),
+                            dir = this.__dir__,
+                            isArr = isArray(array),
+                            isRight = dir < 0,
+                            arrLength = isArr ? array.length : 0,
+                            view = getView(0, arrLength, this.__views__),
+                            start = view.start,
+                            end = view.end,
+                            length = end - start,
+                            index = isRight ? end : (start - 1),
+                            iteratees = this.__iteratees__,
+                            iterLength = iteratees.length,
+                            resIndex = 0,
+                            takeCount = nativeMin(length, this.__takeCount__);
+
+                        if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
+                            return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__);
+                        }
+                        var result = [];
+
+                        outer:
+                            while (length-- && resIndex < takeCount) {
+                                index += dir;
+
+                                var iterIndex = -1,
+                                    value = array[index];
+
+                                while (++iterIndex < iterLength) {
+                                    var data = iteratees[iterIndex],
+                                        iteratee = data.iteratee,
+                                        type = data.type,
+                                        computed = iteratee(value);
+
+                                    if (type == LAZY_MAP_FLAG) {
+                                        value = computed;
+                                    } else if (!computed) {
+                                        if (type == LAZY_FILTER_FLAG) {
+                                            continue outer;
+                                        } else {
+                                            break outer;
+                                        }
+                                    }
+                                }
+                                result[resIndex++] = value;
+                            }
+                        return result;
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a cache object to store key/value pairs.
+                     * 
+                     * @private
+                     * @static
+                     * @name Cache
+                     * @memberOf _.memoize
+                     */
+                    function MapCache() {
+                        this.__data__ = {};
+                    }
+
+                    /**
+                     * Removes `key` and its value from the cache.
+                     * 
+                     * @private
+                     * @name delete
+                     * @memberOf _.memoize.Cache
+                     * @param {string}
+                     *            key The key of the value to remove.
+                     * @returns {boolean} Returns `true` if the entry was removed successfully,
+                     *          else `false`.
+                     */
+                    function mapDelete(key) {
+                        return this.has(key) && delete this.__data__[key];
+                    }
+
+                    /**
+                     * Gets the cached value for `key`.
+                     * 
+                     * @private
+                     * @name get
+                     * @memberOf _.memoize.Cache
+                     * @param {string}
+                     *            key The key of the value to get.
+                     * @returns {*} Returns the cached value.
+                     */
+                    function mapGet(key) {
+                        return key == '__proto__' ? undefined : this.__data__[key];
+                    }
+
+                    /**
+                     * Checks if a cached value for `key` exists.
+                     * 
+                     * @private
+                     * @name has
+                     * @memberOf _.memoize.Cache
+                     * @param {string}
+                     *            key The key of the entry to check.
+                     * @returns {boolean} Returns `true` if an entry for `key` exists, else
+                     *          `false`.
+                     */
+                    function mapHas(key) {
+                        return key != '__proto__' && hasOwnProperty.call(this.__data__, key);
+                    }
+
+                    /**
+                     * Sets `value` to `key` of the cache.
+                     * 
+                     * @private
+                     * @name set
+                     * @memberOf _.memoize.Cache
+                     * @param {string}
+                     *            key The key of the value to cache.
+                     * @param {*}
+                     *            value The value to cache.
+                     * @returns {Object} Returns the cache object.
+                     */
+                    function mapSet(key, value) {
+                        if (key != '__proto__') {
+                            this.__data__[key] = value;
+                        }
+                        return this;
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * 
+                     * Creates a cache object to store unique values.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            [values] The values to cache.
+                     */
+                    function SetCache(values) {
+                        var length = values ? values.length : 0;
+
+                        this.data = {
+                            'hash': nativeCreate(null),
+                            'set': new Set
+                        };
+                        while (length--) {
+                            this.push(values[length]);
+                        }
+                    }
+
+                    /**
+                     * Checks if `value` is in `cache` mimicking the return signature of
+                     * `_.indexOf` by returning `0` if the value is found, else `-1`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            cache The cache to search.
+                     * @param {*}
+                     *            value The value to search for.
+                     * @returns {number} Returns `0` if `value` is found, else `-1`.
+                     */
+                    function cacheIndexOf(cache, value) {
+                        var data = cache.data,
+                            result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
+
+                        return result ? 0 : -1;
+                    }
+
+                    /**
+                     * Adds `value` to the cache.
+                     * 
+                     * @private
+                     * @name push
+                     * @memberOf SetCache
+                     * @param {*}
+                     *            value The value to cache.
+                     */
+                    function cachePush(value) {
+                        var data = this.data;
+                        if (typeof value == 'string' || isObject(value)) {
+                            data.set.add(value);
+                        } else {
+                            data.hash[value] = true;
+                        }
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a new array joining `array` with `other`.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to join.
+                     * @param {Array}
+                     *            other The other array to join.
+                     * @returns {Array} Returns the new concatenated array.
+                     */
+                    function arrayConcat(array, other) {
+                        var index = -1,
+                            length = array.length,
+                            othIndex = -1,
+                            othLength = other.length,
+                            result = Array(length + othLength);
+
+                        while (++index < length) {
+                            result[index] = array[index];
+                        }
+                        while (++othIndex < othLength) {
+                            result[index++] = other[othIndex];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Copies the values of `source` to `array`.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            source The array to copy values from.
+                     * @param {Array}
+                     *            [array=[]] The array to copy values to.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function arrayCopy(source, array) {
+                        var index = -1,
+                            length = source.length;
+
+                        array || (array = Array(length));
+                        while (++index < length) {
+                            array[index] = source[index];
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * A specialized version of `_.forEach` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function arrayEach(array, iteratee) {
+                        var index = -1,
+                            length = array.length;
+
+                        while (++index < length) {
+                            if (iteratee(array[index], index, array) === false) {
+                                break;
+                            }
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * A specialized version of `_.forEachRight` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function arrayEachRight(array, iteratee) {
+                        var length = array.length;
+
+                        while (length--) {
+                            if (iteratee(array[length], length, array) === false) {
+                                break;
+                            }
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * A specialized version of `_.every` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {boolean} Returns `true` if all elements pass the predicate
+                     *          check, else `false`.
+                     */
+                    function arrayEvery(array, predicate) {
+                        var index = -1,
+                            length = array.length;
+
+                        while (++index < length) {
+                            if (!predicate(array[index], index, array)) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+
+                    /**
+                     * A specialized version of `baseExtremum` for arrays which invokes
+                     * `iteratee` with one argument: (value).
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {Function}
+                     *            comparator The function used to compare values.
+                     * @param {*}
+                     *            exValue The initial extremum value.
+                     * @returns {*} Returns the extremum value.
+                     */
+                    function arrayExtremum(array, iteratee, comparator, exValue) {
+                        var index = -1,
+                            length = array.length,
+                            computed = exValue,
+                            result = computed;
+
+                        while (++index < length) {
+                            var value = array[index],
+                                current = +iteratee(value);
+
+                            if (comparator(current, computed)) {
+                                computed = current;
+                                result = value;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * A specialized version of `_.filter` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {Array} Returns the new filtered array.
+                     */
+                    function arrayFilter(array, predicate) {
+                        var index = -1,
+                            length = array.length,
+                            resIndex = -1,
+                            result = [];
+
+                        while (++index < length) {
+                            var value = array[index];
+                            if (predicate(value, index, array)) {
+                                result[++resIndex] = value;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * A specialized version of `_.map` for arrays without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array} Returns the new mapped array.
+                     */
+                    function arrayMap(array, iteratee) {
+                        var index = -1,
+                            length = array.length,
+                            result = Array(length);
+
+                        while (++index < length) {
+                            result[index] = iteratee(array[index], index, array);
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Appends the elements of `values` to `array`.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to modify.
+                     * @param {Array}
+                     *            values The values to append.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function arrayPush(array, values) {
+                        var index = -1,
+                            length = values.length,
+                            offset = array.length;
+
+                        while (++index < length) {
+                            array[offset + index] = values[index];
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * A specialized version of `_.reduce` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {*}
+                     *            [accumulator] The initial value.
+                     * @param {boolean}
+                     *            [initFromArray] Specify using the first element of `array` as
+                     *            the initial value.
+                     * @returns {*} Returns the accumulated value.
+                     */
+                    function arrayReduce(array, iteratee, accumulator, initFromArray) {
+                        var index = -1,
+                            length = array.length;
+
+                        if (initFromArray && length) {
+                            accumulator = array[++index];
+                        }
+                        while (++index < length) {
+                            accumulator = iteratee(accumulator, array[index], index, array);
+                        }
+                        return accumulator;
+                    }
+
+                    /**
+                     * A specialized version of `_.reduceRight` for arrays without support for
+                     * callback shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {*}
+                     *            [accumulator] The initial value.
+                     * @param {boolean}
+                     *            [initFromArray] Specify using the last element of `array` as
+                     *            the initial value.
+                     * @returns {*} Returns the accumulated value.
+                     */
+                    function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
+                        var length = array.length;
+                        if (initFromArray && length) {
+                            accumulator = array[--length];
+                        }
+                        while (length--) {
+                            accumulator = iteratee(accumulator, array[length], length, array);
+                        }
+                        return accumulator;
+                    }
+
+                    /**
+                     * A specialized version of `_.some` for arrays without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {boolean} Returns `true` if any element passes the predicate
+                     *          check, else `false`.
+                     */
+                    function arraySome(array, predicate) {
+                        var index = -1,
+                            length = array.length;
+
+                        while (++index < length) {
+                            if (predicate(array[index], index, array)) {
+                                return true;
+                            }
+                        }
+                        return false;
+                    }
+
+                    /**
+                     * A specialized version of `_.sum` for arrays without support for callback
+                     * shorthands and `this` binding..
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {number} Returns the sum.
+                     */
+                    function arraySum(array, iteratee) {
+                        var length = array.length,
+                            result = 0;
+
+                        while (length--) {
+                            result += +iteratee(array[length]) || 0;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Used by `_.defaults` to customize its `_.assign` use.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            objectValue The destination object property value.
+                     * @param {*}
+                     *            sourceValue The source object property value.
+                     * @returns {*} Returns the value to assign to the destination object.
+                     */
+                    function assignDefaults(objectValue, sourceValue) {
+                        return objectValue === undefined ? sourceValue : objectValue;
+                    }
+
+                    /**
+                     * Used by `_.template` to customize its `_.assign` use.
+                     * 
+                     * **Note:** This function is like `assignDefaults` except that it ignores
+                     * inherited property values when checking if a property is `undefined`.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            objectValue The destination object property value.
+                     * @param {*}
+                     *            sourceValue The source object property value.
+                     * @param {string}
+                     *            key The key associated with the object and source values.
+                     * @param {Object}
+                     *            object The destination object.
+                     * @returns {*} Returns the value to assign to the destination object.
+                     */
+                    function assignOwnDefaults(objectValue, sourceValue, key, object) {
+                        return (objectValue === undefined || !hasOwnProperty.call(object, key)) ? sourceValue : objectValue;
+                    }
+
+                    /**
+                     * A specialized version of `_.assign` for customizing assigned values
+                     * without support for argument juggling, multiple sources, and `this`
+                     * binding `customizer` functions.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {Object}
+                     *            source The source object.
+                     * @param {Function}
+                     *            customizer The function to customize assigned values.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function assignWith(object, source, customizer) {
+                        var index = -1,
+                            props = keys(source),
+                            length = props.length;
+
+                        while (++index < length) {
+                            var key = props[index],
+                                value = object[key],
+                                result = customizer(value, source[key], key, object, source);
+
+                            if ((result === result ? (result !== value) : (value === value)) ||
+                                (value === undefined && !(key in object))) {
+                                object[key] = result;
+                            }
+                        }
+                        return object;
+                    }
+
+                    /**
+                     * The base implementation of `_.assign` without support for argument
+                     * juggling, multiple sources, and `customizer` functions.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {Object}
+                     *            source The source object.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseAssign(object, source) {
+                        return source == null ? object : baseCopy(source, keys(source), object);
+                    }
+
+                    /**
+                     * The base implementation of `_.at` without support for string collections
+                     * and individual key arguments.
+                     * 
+                     * @private
+                     * @param {Array|Object}
+                     *            collection The collection to iterate over.
+                     * @param {number[]|string[]}
+                     *            props The property names or indexes of elements to pick.
+                     * @returns {Array} Returns the new array of picked elements.
+                     */
+                    function baseAt(collection, props) {
+                        var index = -1,
+                            isNil = collection == null,
+                            isArr = !isNil && isArrayLike(collection),
+                            length = isArr ? collection.length : 0,
+                            propsLength = props.length,
+                            result = Array(propsLength);
+
+                        while (++index < propsLength) {
+                            var key = props[index];
+                            if (isArr) {
+                                result[index] = isIndex(key, length) ? collection[key] : undefined;
+                            } else {
+                                result[index] = isNil ? undefined : collection[key];
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Copies properties of `source` to `object`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            source The object to copy properties from.
+                     * @param {Array}
+                     *            props The property names to copy.
+                     * @param {Object}
+                     *            [object={}] The object to copy properties to.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseCopy(source, props, object) {
+                        object || (object = {});
+
+                        var index = -1,
+                            length = props.length;
+
+                        while (++index < length) {
+                            var key = props[index];
+                            object[key] = source[key];
+                        }
+                        return object;
+                    }
+
+                    /**
+                     * The base implementation of `_.callback` which supports specifying the
+                     * number of arguments to provide to `func`.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            [func=_.identity] The value to convert to a callback.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `func`.
+                     * @param {number}
+                     *            [argCount] The number of arguments to provide to `func`.
+                     * @returns {Function} Returns the callback.
+                     */
+                    function baseCallback(func, thisArg, argCount) {
+                        var type = typeof func;
+                        if (type == 'function') {
+                            return thisArg === undefined ? func : bindCallback(func, thisArg, argCount);
+                        }
+                        if (func == null) {
+                            return identity;
+                        }
+                        if (type == 'object') {
+                            return baseMatches(func);
+                        }
+                        return thisArg === undefined ? property(func) : baseMatchesProperty(func, thisArg);
+                    }
+
+                    /**
+                     * The base implementation of `_.clone` without support for argument
+                     * juggling and `this` binding `customizer` functions.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to clone.
+                     * @param {boolean}
+                     *            [isDeep] Specify a deep clone.
+                     * @param {Function}
+                     *            [customizer] The function to customize cloning values.
+                     * @param {string}
+                     *            [key] The key of `value`.
+                     * @param {Object}
+                     *            [object] The object `value` belongs to.
+                     * @param {Array}
+                     *            [stackA=[]] Tracks traversed source objects.
+                     * @param {Array}
+                     *            [stackB=[]] Associates clones with source counterparts.
+                     * @returns {*} Returns the cloned value.
+                     */
+                    function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+                        var result;
+                        if (customizer) {
+                            result = object ? customizer(value, key, object) : customizer(value);
+                        }
+                        if (result !== undefined) {
+                            return result;
+                        }
+                        if (!isObject(value)) {
+                            return value;
+                        }
+                        var isArr = isArray(value);
+                        if (isArr) {
+                            result = initCloneArray(value);
+                            if (!isDeep) {
+                                return arrayCopy(value, result);
+                            }
+                        } else {
+                            var tag = objToString.call(value),
+                                isFunc = tag == funcTag;
+
+                            if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+                                result = initCloneObject(isFunc ? {} : value);
+                                if (!isDeep) {
+                                    return baseAssign(result, value);
+                                }
+                            } else {
+                                return cloneableTags[tag] ? initCloneByTag(value, tag, isDeep) : (object ? value : {});
+                            }
+                        }
+                        // Check for circular references and return its corresponding clone.
+                        stackA || (stackA = []);
+                        stackB || (stackB = []);
+
+                        var length = stackA.length;
+                        while (length--) {
+                            if (stackA[length] == value) {
+                                return stackB[length];
+                            }
+                        }
+                        // Add the source value to the stack of traversed objects and associate
+                        // it with its clone.
+                        stackA.push(value);
+                        stackB.push(result);
+
+                        // Recursively populate clone (susceptible to call stack limits).
+                        (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+                            result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.create` without support for assigning
+                     * properties to the created object.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            prototype The object to inherit from.
+                     * @returns {Object} Returns the new object.
+                     */
+                    var baseCreate = (function() {
+                        function object() {}
+                        return function(prototype) {
+                            if (isObject(prototype)) {
+                                object.prototype = prototype;
+                                var result = new object;
+                                object.prototype = undefined;
+                            }
+                            return result || {};
+                        };
+                    }());
+
+                    /**
+                     * The base implementation of `_.delay` and `_.defer` which accepts an index
+                     * of where to slice the arguments to provide to `func`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to delay.
+                     * @param {number}
+                     *            wait The number of milliseconds to delay invocation.
+                     * @param {Object}
+                     *            args The arguments provide to `func`.
+                     * @returns {number} Returns the timer id.
+                     */
+                    function baseDelay(func, wait, args) {
+                        if (typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        return setTimeout(function() {
+                            func.apply(undefined, args);
+                        }, wait);
+                    }
+
+                    /**
+                     * The base implementation of `_.difference` which accepts a single array of
+                     * values to exclude.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to inspect.
+                     * @param {Array}
+                     *            values The values to exclude.
+                     * @returns {Array} Returns the new array of filtered values.
+                     */
+                    function baseDifference(array, values) {
+                        var length = array ? array.length : 0,
+                            result = [];
+
+                        if (!length) {
+                            return result;
+                        }
+                        var index = -1,
+                            indexOf = getIndexOf(),
+                            isCommon = indexOf == baseIndexOf,
+                            cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
+                            valuesLength = values.length;
+
+                        if (cache) {
+                            indexOf = cacheIndexOf;
+                            isCommon = false;
+                            values = cache;
+                        }
+                        outer:
+                            while (++index < length) {
+                                var value = array[index];
+
+                                if (isCommon && value === value) {
+                                    var valuesIndex = valuesLength;
+                                    while (valuesIndex--) {
+                                        if (values[valuesIndex] === value) {
+                                            continue outer;
+                                        }
+                                    }
+                                    result.push(value);
+                                } else if (indexOf(values, value, 0) < 0) {
+                                    result.push(value);
+                                }
+                            }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.forEach` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array|Object|string} Returns `collection`.
+                     */
+                    var baseEach = createBaseEach(baseForOwn);
+
+                    /**
+                     * The base implementation of `_.forEachRight` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array|Object|string} Returns `collection`.
+                     */
+                    var baseEachRight = createBaseEach(baseForOwnRight, true);
+
+                    /**
+                     * The base implementation of `_.every` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {boolean} Returns `true` if all elements pass the predicate
+                     *          check, else `false`
+                     */
+                    function baseEvery(collection, predicate) {
+                        var result = true;
+                        baseEach(collection, function(value, index, collection) {
+                            result = !!predicate(value, index, collection);
+                            return result;
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * Gets the extremum value of `collection` invoking `iteratee` for each
+                     * value in `collection` to generate the criterion by which the value is
+                     * ranked. The `iteratee` is invoked with three arguments: (value,
+                     * index|key, collection).
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {Function}
+                     *            comparator The function used to compare values.
+                     * @param {*}
+                     *            exValue The initial extremum value.
+                     * @returns {*} Returns the extremum value.
+                     */
+                    function baseExtremum(collection, iteratee, comparator, exValue) {
+                        var computed = exValue,
+                            result = computed;
+
+                        baseEach(collection, function(value, index, collection) {
+                            var current = +iteratee(value, index, collection);
+                            if (comparator(current, computed) || (current === exValue && current === result)) {
+                                computed = current;
+                                result = value;
+                            }
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.fill` without an iteratee call guard.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to fill.
+                     * @param {*}
+                     *            value The value to fill `array` with.
+                     * @param {number}
+                     *            [start=0] The start position.
+                     * @param {number}
+                     *            [end=array.length] The end position.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function baseFill(array, value, start, end) {
+                        var length = array.length;
+
+                        start = start == null ? 0 : (+start || 0);
+                        if (start < 0) {
+                            start = -start > length ? 0 : (length + start);
+                        }
+                        end = (end === undefined || end > length) ? length : (+end || 0);
+                        if (end < 0) {
+                            end += length;
+                        }
+                        length = start > end ? 0 : (end >>> 0);
+                        start >>>= 0;
+
+                        while (start < length) {
+                            array[start++] = value;
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * The base implementation of `_.filter` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {Array} Returns the new filtered array.
+                     */
+                    function baseFilter(collection, predicate) {
+                        var result = [];
+                        baseEach(collection, function(value, index, collection) {
+                            if (predicate(value, index, collection)) {
+                                result.push(value);
+                            }
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and
+                     * `_.findLastKey`, without support for callback shorthands and `this`
+                     * binding, which iterates over `collection` using the provided `eachFunc`.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @param {Function}
+                     *            eachFunc The function to iterate over `collection`.
+                     * @param {boolean}
+                     *            [retKey] Specify returning the key of the found element
+                     *            instead of the element itself.
+                     * @returns {*} Returns the found element or its key, else `undefined`.
+                     */
+                    function baseFind(collection, predicate, eachFunc, retKey) {
+                        var result;
+                        eachFunc(collection, function(value, key, collection) {
+                            if (predicate(value, key, collection)) {
+                                result = retKey ? key : value;
+                                return false;
+                            }
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.flatten` with added support for restricting
+                     * flattening and specifying the start index.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to flatten.
+                     * @param {boolean}
+                     *            [isDeep] Specify a deep flatten.
+                     * @param {boolean}
+                     *            [isStrict] Restrict flattening to arrays-like objects.
+                     * @param {Array}
+                     *            [result=[]] The initial result value.
+                     * @returns {Array} Returns the new flattened array.
+                     */
+                    function baseFlatten(array, isDeep, isStrict, result) {
+                        result || (result = []);
+
+                        var index = -1,
+                            length = array.length;
+
+                        while (++index < length) {
+                            var value = array[index];
+                            if (isObjectLike(value) && isArrayLike(value) &&
+                                (isStrict || isArray(value) || isArguments(value))) {
+                                if (isDeep) {
+                                    // Recursively flatten arrays (susceptible to call stack limits).
+                                    baseFlatten(value, isDeep, isStrict, result);
+                                } else {
+                                    arrayPush(result, value);
+                                }
+                            } else if (!isStrict) {
+                                result[result.length] = value;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `baseForIn` and `baseForOwn` which iterates
+                     * over `object` properties returned by `keysFunc` invoking `iteratee` for
+                     * each property. Iteratee functions may exit iteration early by explicitly
+                     * returning `false`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {Function}
+                     *            keysFunc The function to get the keys of `object`.
+                     * @returns {Object} Returns `object`.
+                     */
+                    var baseFor = createBaseFor();
+
+                    /**
+                     * This function is like `baseFor` except that it iterates over properties
+                     * in the opposite order.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {Function}
+                     *            keysFunc The function to get the keys of `object`.
+                     * @returns {Object} Returns `object`.
+                     */
+                    var baseForRight = createBaseFor(true);
+
+                    /**
+                     * The base implementation of `_.forIn` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseForIn(object, iteratee) {
+                        return baseFor(object, iteratee, keysIn);
+                    }
+
+                    /**
+                     * The base implementation of `_.forOwn` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseForOwn(object, iteratee) {
+                        return baseFor(object, iteratee, keys);
+                    }
+
+                    /**
+                     * The base implementation of `_.forOwnRight` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseForOwnRight(object, iteratee) {
+                        return baseForRight(object, iteratee, keys);
+                    }
+
+                    /**
+                     * The base implementation of `_.functions` which creates an array of
+                     * `object` function property names filtered from those provided.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to inspect.
+                     * @param {Array}
+                     *            props The property names to filter.
+                     * @returns {Array} Returns the new array of filtered property names.
+                     */
+                    function baseFunctions(object, props) {
+                        var index = -1,
+                            length = props.length,
+                            resIndex = -1,
+                            result = [];
+
+                        while (++index < length) {
+                            var key = props[index];
+                            if (isFunction(object[key])) {
+                                result[++resIndex] = key;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `get` without support for string paths and
+                     * default values.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array}
+                     *            path The path of the property to get.
+                     * @param {string}
+                     *            [pathKey] The key representation of path.
+                     * @returns {*} Returns the resolved value.
+                     */
+                    function baseGet(object, path, pathKey) {
+                        if (object == null) {
+                            return;
+                        }
+                        if (pathKey !== undefined && pathKey in toObject(object)) {
+                            path = [pathKey];
+                        }
+                        var index = 0,
+                            length = path.length;
+
+                        while (object != null && index < length) {
+                            object = object[path[index++]];
+                        }
+                        return (index && index == length) ? object : undefined;
+                    }
+
+                    /**
+                     * The base implementation of `_.isEqual` without support for `this` binding
+                     * `customizer` functions.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @param {Function}
+                     *            [customizer] The function to customize comparing values.
+                     * @param {boolean}
+                     *            [isLoose] Specify performing partial comparisons.
+                     * @param {Array}
+                     *            [stackA] Tracks traversed `value` objects.
+                     * @param {Array}
+                     *            [stackB] Tracks traversed `other` objects.
+                     * @returns {boolean} Returns `true` if the values are equivalent, else
+                     *          `false`.
+                     */
+                    function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+                        if (value === other) {
+                            return true;
+                        }
+                        if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+                            return value !== value && other !== other;
+                        }
+                        return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+                    }
+
+                    /**
+                     * A specialized version of `baseIsEqual` for arrays and objects which
+                     * performs deep comparisons and tracks traversed objects enabling objects
+                     * with circular references to be compared.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to compare.
+                     * @param {Object}
+                     *            other The other object to compare.
+                     * @param {Function}
+                     *            equalFunc The function to determine equivalents of values.
+                     * @param {Function}
+                     *            [customizer] The function to customize comparing objects.
+                     * @param {boolean}
+                     *            [isLoose] Specify performing partial comparisons.
+                     * @param {Array}
+                     *            [stackA=[]] Tracks traversed `value` objects.
+                     * @param {Array}
+                     *            [stackB=[]] Tracks traversed `other` objects.
+                     * @returns {boolean} Returns `true` if the objects are equivalent, else
+                     *          `false`.
+                     */
+                    function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+                        var objIsArr = isArray(object),
+                            othIsArr = isArray(other),
+                            objTag = arrayTag,
+                            othTag = arrayTag;
+
+                        if (!objIsArr) {
+                            objTag = objToString.call(object);
+                            if (objTag == argsTag) {
+                                objTag = objectTag;
+                            } else if (objTag != objectTag) {
+                                objIsArr = isTypedArray(object);
+                            }
+                        }
+                        if (!othIsArr) {
+                            othTag = objToString.call(other);
+                            if (othTag == argsTag) {
+                                othTag = objectTag;
+                            } else if (othTag != objectTag) {
+                                othIsArr = isTypedArray(other);
+                            }
+                        }
+                        var objIsObj = objTag == objectTag,
+                            othIsObj = othTag == objectTag,
+                            isSameTag = objTag == othTag;
+
+                        if (isSameTag && !(objIsArr || objIsObj)) {
+                            return equalByTag(object, other, objTag);
+                        }
+                        if (!isLoose) {
+                            var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+                                othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+                            if (objIsWrapped || othIsWrapped) {
+                                return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+                            }
+                        }
+                        if (!isSameTag) {
+                            return false;
+                        }
+                        // Assume cyclic values are equal.
+                        // For more information on detecting circular references see
+                        // https://es5.github.io/#JO.
+                        stackA || (stackA = []);
+                        stackB || (stackB = []);
+
+                        var length = stackA.length;
+                        while (length--) {
+                            if (stackA[length] == object) {
+                                return stackB[length] == other;
+                            }
+                        }
+                        // Add `object` and `other` to the stack of traversed objects.
+                        stackA.push(object);
+                        stackB.push(other);
+
+                        var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
+
+                        stackA.pop();
+                        stackB.pop();
+
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.isMatch` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to inspect.
+                     * @param {Array}
+                     *            matchData The propery names, values, and compare flags to
+                     *            match.
+                     * @param {Function}
+                     *            [customizer] The function to customize comparing objects.
+                     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+                     */
+                    function baseIsMatch(object, matchData, customizer) {
+                        var index = matchData.length,
+                            length = index,
+                            noCustomizer = !customizer;
+
+                        if (object == null) {
+                            return !length;
+                        }
+                        object = toObject(object);
+                        while (index--) {
+                            var data = matchData[index];
+                            if ((noCustomizer && data[2]) ? data[1] !== object[data[0]] : !(data[0] in object)) {
+                                return false;
+                            }
+                        }
+                        while (++index < length) {
+                            data = matchData[index];
+                            var key = data[0],
+                                objValue = object[key],
+                                srcValue = data[1];
+
+                            if (noCustomizer && data[2]) {
+                                if (objValue === undefined && !(key in object)) {
+                                    return false;
+                                }
+                            } else {
+                                var result = customizer ? customizer(objValue, srcValue, key) : undefined;
+                                if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+                                    return false;
+                                }
+                            }
+                        }
+                        return true;
+                    }
+
+                    /**
+                     * The base implementation of `_.map` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {Array} Returns the new mapped array.
+                     */
+                    function baseMap(collection, iteratee) {
+                        var index = -1,
+                            result = isArrayLike(collection) ? Array(collection.length) : [];
+
+                        baseEach(collection, function(value, key, collection) {
+                            result[++index] = iteratee(value, key, collection);
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.matches` which does not clone `source`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            source The object of property values to match.
+                     * @returns {Function} Returns the new function.
+                     */
+                    function baseMatches(source) {
+                        var matchData = getMatchData(source);
+                        if (matchData.length == 1 && matchData[0][2]) {
+                            var key = matchData[0][0],
+                                value = matchData[0][1];
+
+                            return function(object) {
+                                if (object == null) {
+                                    return false;
+                                }
+                                return object[key] === value && (value !== undefined || (key in toObject(object)));
+                            };
+                        }
+                        return function(object) {
+                            return baseIsMatch(object, matchData);
+                        };
+                    }
+
+                    /**
+                     * The base implementation of `_.matchesProperty` which does not clone
+                     * `srcValue`.
+                     * 
+                     * @private
+                     * @param {string}
+                     *            path The path of the property to get.
+                     * @param {*}
+                     *            srcValue The value to compare.
+                     * @returns {Function} Returns the new function.
+                     */
+                    function baseMatchesProperty(path, srcValue) {
+                        var isArr = isArray(path),
+                            isCommon = isKey(path) && isStrictComparable(srcValue),
+                            pathKey = (path + '');
+
+                        path = toPath(path);
+                        return function(object) {
+                            if (object == null) {
+                                return false;
+                            }
+                            var key = pathKey;
+                            object = toObject(object);
+                            if ((isArr || !isCommon) && !(key in object)) {
+                                object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+                                if (object == null) {
+                                    return false;
+                                }
+                                key = last(path);
+                                object = toObject(object);
+                            }
+                            return object[key] === srcValue ? (srcValue !== undefined || (key in object)) : baseIsEqual(srcValue, object[key], undefined, true);
+                        };
+                    }
+
+                    /**
+                     * The base implementation of `_.merge` without support for argument
+                     * juggling, multiple sources, and `this` binding `customizer` functions.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {Object}
+                     *            source The source object.
+                     * @param {Function}
+                     *            [customizer] The function to customize merged values.
+                     * @param {Array}
+                     *            [stackA=[]] Tracks traversed source objects.
+                     * @param {Array}
+                     *            [stackB=[]] Associates values with source counterparts.
+                     * @returns {Object} Returns `object`.
+                     */
+                    function baseMerge(object, source, customizer, stackA, stackB) {
+                        if (!isObject(object)) {
+                            return object;
+                        }
+                        var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
+                            props = isSrcArr ? undefined : keys(source);
+
+                        arrayEach(props || source, function(srcValue, key) {
+                            if (props) {
+                                key = srcValue;
+                                srcValue = source[key];
+                            }
+                            if (isObjectLike(srcValue)) {
+                                stackA || (stackA = []);
+                                stackB || (stackB = []);
+                                baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
+                            } else {
+                                var value = object[key],
+                                    result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
+                                    isCommon = result === undefined;
+
+                                if (isCommon) {
+                                    result = srcValue;
+                                }
+                                if ((result !== undefined || (isSrcArr && !(key in object))) &&
+                                    (isCommon || (result === result ? (result !== value) : (value === value)))) {
+                                    object[key] = result;
+                                }
+                            }
+                        });
+                        return object;
+                    }
+
+                    /**
+                     * A specialized version of `baseMerge` for arrays and objects which
+                     * performs deep merges and tracks traversed objects enabling objects with
+                     * circular references to be merged.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {Object}
+                     *            source The source object.
+                     * @param {string}
+                     *            key The key of the value to merge.
+                     * @param {Function}
+                     *            mergeFunc The function to merge values.
+                     * @param {Function}
+                     *            [customizer] The function to customize merged values.
+                     * @param {Array}
+                     *            [stackA=[]] Tracks traversed source objects.
+                     * @param {Array}
+                     *            [stackB=[]] Associates values with source counterparts.
+                     * @returns {boolean} Returns `true` if the objects are equivalent, else
+                     *          `false`.
+                     */
+                    function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
+                        var length = stackA.length,
+                            srcValue = source[key];
+
+                        while (length--) {
+                            if (stackA[length] == srcValue) {
+                                object[key] = stackB[length];
+                                return;
+                            }
+                        }
+                        var value = object[key],
+                            result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
+                            isCommon = result === undefined;
+
+                        if (isCommon) {
+                            result = srcValue;
+                            if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
+                                result = isArray(value) ? value : (isArrayLike(value) ? arrayCopy(value) : []);
+                            } else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+                                result = isArguments(value) ? toPlainObject(value) : (isPlainObject(value) ? value : {});
+                            } else {
+                                isCommon = false;
+                            }
+                        }
+                        // Add the source value to the stack of traversed objects and associate
+                        // it with its merged value.
+                        stackA.push(srcValue);
+                        stackB.push(result);
+
+                        if (isCommon) {
+                            // Recursively merge objects and arrays (susceptible to call stack
+                            // limits).
+                            object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
+                        } else if (result === result ? (result !== value) : (value === value)) {
+                            object[key] = result;
+                        }
+                    }
+
+                    /**
+                     * The base implementation of `_.property` without support for deep paths.
+                     * 
+                     * @private
+                     * @param {string}
+                     *            key The key of the property to get.
+                     * @returns {Function} Returns the new function.
+                     */
+                    function baseProperty(key) {
+                        return function(object) {
+                            return object == null ? undefined : object[key];
+                        };
+                    }
+
+                    /**
+                     * A specialized version of `baseProperty` which supports deep paths.
+                     * 
+                     * @private
+                     * @param {Array|string}
+                     *            path The path of the property to get.
+                     * @returns {Function} Returns the new function.
+                     */
+                    function basePropertyDeep(path) {
+                        var pathKey = (path + '');
+                        path = toPath(path);
+                        return function(object) {
+                            return baseGet(object, path, pathKey);
+                        };
+                    }
+
+                    /**
+                     * The base implementation of `_.pullAt` without support for individual
+                     * index arguments and capturing the removed elements.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to modify.
+                     * @param {number[]}
+                     *            indexes The indexes of elements to remove.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function basePullAt(array, indexes) {
+                        var length = array ? indexes.length : 0;
+                        while (length--) {
+                            var index = indexes[length];
+                            if (index != previous && isIndex(index)) {
+                                var previous = index;
+                                splice.call(array, index, 1);
+                            }
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * The base implementation of `_.random` without support for argument
+                     * juggling and returning floating-point numbers.
+                     * 
+                     * @private
+                     * @param {number}
+                     *            min The minimum possible value.
+                     * @param {number}
+                     *            max The maximum possible value.
+                     * @returns {number} Returns the random number.
+                     */
+                    function baseRandom(min, max) {
+                        return min + nativeFloor(nativeRandom() * (max - min + 1));
+                    }
+
+                    /**
+                     * The base implementation of `_.reduce` and `_.reduceRight` without support
+                     * for callback shorthands and `this` binding, which iterates over
+                     * `collection` using the provided `eachFunc`.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {*}
+                     *            accumulator The initial value.
+                     * @param {boolean}
+                     *            initFromCollection Specify using the first or last element of
+                     *            `collection` as the initial value.
+                     * @param {Function}
+                     *            eachFunc The function to iterate over `collection`.
+                     * @returns {*} Returns the accumulated value.
+                     */
+                    function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
+                        eachFunc(collection, function(value, index, collection) {
+                            accumulator = initFromCollection ? (initFromCollection = false, value) : iteratee(accumulator, value, index, collection);
+                        });
+                        return accumulator;
+                    }
+
+                    /**
+                     * The base implementation of `setData` without support for hot loop
+                     * detection.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to associate metadata with.
+                     * @param {*}
+                     *            data The metadata.
+                     * @returns {Function} Returns `func`.
+                     */
+                    var baseSetData = !metaMap ? identity : function(func, data) {
+                        metaMap.set(func, data);
+                        return func;
+                    };
+
+                    /**
+                     * The base implementation of `_.slice` without an iteratee call guard.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to slice.
+                     * @param {number}
+                     *            [start=0] The start position.
+                     * @param {number}
+                     *            [end=array.length] The end position.
+                     * @returns {Array} Returns the slice of `array`.
+                     */
+                    function baseSlice(array, start, end) {
+                        var index = -1,
+                            length = array.length;
+
+                        start = start == null ? 0 : (+start || 0);
+                        if (start < 0) {
+                            start = -start > length ? 0 : (length + start);
+                        }
+                        end = (end === undefined || end > length) ? length : (+end || 0);
+                        if (end < 0) {
+                            end += length;
+                        }
+                        length = start > end ? 0 : ((end - start) >>> 0);
+                        start >>>= 0;
+
+                        var result = Array(length);
+                        while (++index < length) {
+                            result[index] = array[index + start];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.some` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {boolean} Returns `true` if any element passes the predicate
+                     *          check, else `false`.
+                     */
+                    function baseSome(collection, predicate) {
+                        var result;
+
+                        baseEach(collection, function(value, index, collection) {
+                            result = predicate(value, index, collection);
+                            return !result;
+                        });
+                        return !!result;
+                    }
+
+                    /**
+                     * The base implementation of `_.sortBy` which uses `comparer` to define the
+                     * sort order of `array` and replaces criteria objects with their
+                     * corresponding values.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to sort.
+                     * @param {Function}
+                     *            comparer The function to define sort order.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function baseSortBy(array, comparer) {
+                        var length = array.length;
+
+                        array.sort(comparer);
+                        while (length--) {
+                            array[length] = array[length].value;
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * The base implementation of `_.sortByOrder` without param guards.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function[]|Object[]|string[]}
+                     *            iteratees The iteratees to sort by.
+                     * @param {boolean[]}
+                     *            orders The sort orders of `iteratees`.
+                     * @returns {Array} Returns the new sorted array.
+                     */
+                    function baseSortByOrder(collection, iteratees, orders) {
+                        var callback = getCallback(),
+                            index = -1;
+
+                        iteratees = arrayMap(iteratees, function(iteratee) {
+                            return callback(iteratee);
+                        });
+
+                        var result = baseMap(collection, function(value) {
+                            var criteria = arrayMap(iteratees, function(iteratee) {
+                                return iteratee(value);
+                            });
+                            return {
+                                'criteria': criteria,
+                                'index': ++index,
+                                'value': value
+                            };
+                        });
+
+                        return baseSortBy(result, function(object, other) {
+                            return compareMultiple(object, other, orders);
+                        });
+                    }
+
+                    /**
+                     * The base implementation of `_.sum` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @returns {number} Returns the sum.
+                     */
+                    function baseSum(collection, iteratee) {
+                        var result = 0;
+                        baseEach(collection, function(value, index, collection) {
+                            result += +iteratee(value, index, collection) || 0;
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.uniq` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to inspect.
+                     * @param {Function}
+                     *            [iteratee] The function invoked per iteration.
+                     * @returns {Array} Returns the new duplicate-value-free array.
+                     */
+                    function baseUniq(array, iteratee) {
+                        var index = -1,
+                            indexOf = getIndexOf(),
+                            length = array.length,
+                            isCommon = indexOf == baseIndexOf,
+                            isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
+                            seen = isLarge ? createCache() : null,
+                            result = [];
+
+                        if (seen) {
+                            indexOf = cacheIndexOf;
+                            isCommon = false;
+                        } else {
+                            isLarge = false;
+                            seen = iteratee ? [] : result;
+                        }
+                        outer:
+                            while (++index < length) {
+                                var value = array[index],
+                                    computed = iteratee ? iteratee(value, index, array) : value;
+
+                                if (isCommon && value === value) {
+                                    var seenIndex = seen.length;
+                                    while (seenIndex--) {
+                                        if (seen[seenIndex] === computed) {
+                                            continue outer;
+                                        }
+                                    }
+                                    if (iteratee) {
+                                        seen.push(computed);
+                                    }
+                                    result.push(value);
+                                } else if (indexOf(seen, computed, 0) < 0) {
+                                    if (iteratee || isLarge) {
+                                        seen.push(computed);
+                                    }
+                                    result.push(value);
+                                }
+                            }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.values` and `_.valuesIn` which creates an
+                     * array of `object` property values corresponding to the property names of
+                     * `props`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array}
+                     *            props The property names to get values for.
+                     * @returns {Object} Returns the array of property values.
+                     */
+                    function baseValues(object, props) {
+                        var index = -1,
+                            length = props.length,
+                            result = Array(length);
+
+                        while (++index < length) {
+                            result[index] = object[props[index]];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * The base implementation of `_.dropRightWhile`, `_.dropWhile`,
+                     * `_.takeRightWhile`, and `_.takeWhile` without support for callback
+                     * shorthands and `this` binding.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @param {boolean}
+                     *            [isDrop] Specify dropping elements instead of taking them.
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Array} Returns the slice of `array`.
+                     */
+                    function baseWhile(array, predicate, isDrop, fromRight) {
+                        var length = array.length,
+                            index = fromRight ? length : -1;
+
+                        while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {}
+                        return isDrop ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
+                    }
+
+                    /**
+                     * The base implementation of `wrapperValue` which returns the result of
+                     * performing a sequence of actions on the unwrapped `value`, where each
+                     * successive action is supplied the return value of the previous.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The unwrapped value.
+                     * @param {Array}
+                     *            actions Actions to peform to resolve the unwrapped value.
+                     * @returns {*} Returns the resolved value.
+                     */
+                    function baseWrapperValue(value, actions) {
+                        var result = value;
+                        if (result instanceof LazyWrapper) {
+                            result = result.value();
+                        }
+                        var index = -1,
+                            length = actions.length;
+
+                        while (++index < length) {
+                            var action = actions[index];
+                            result = action.func.apply(action.thisArg, arrayPush([result], action.args));
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Performs a binary search of `array` to determine the index at which
+                     * `value` should be inserted into `array` in order to maintain its sort
+                     * order.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The sorted array to inspect.
+                     * @param {*}
+                     *            value The value to evaluate.
+                     * @param {boolean}
+                     *            [retHighest] Specify returning the highest qualified index.
+                     * @returns {number} Returns the index at which `value` should be inserted
+                     *          into `array`.
+                     */
+                    function binaryIndex(array, value, retHighest) {
+                        var low = 0,
+                            high = array ? array.length : low;
+
+                        if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
+                            while (low < high) {
+                                var mid = (low + high) >>> 1,
+                                    computed = array[mid];
+
+                                if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
+                                    low = mid + 1;
+                                } else {
+                                    high = mid;
+                                }
+                            }
+                            return high;
+                        }
+                        return binaryIndexBy(array, value, identity, retHighest);
+                    }
+
+                    /**
+                     * This function is like `binaryIndex` except that it invokes `iteratee` for
+                     * `value` and each element of `array` to compute their sort ranking. The
+                     * iteratee is invoked with one argument; (value).
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The sorted array to inspect.
+                     * @param {*}
+                     *            value The value to evaluate.
+                     * @param {Function}
+                     *            iteratee The function invoked per iteration.
+                     * @param {boolean}
+                     *            [retHighest] Specify returning the highest qualified index.
+                     * @returns {number} Returns the index at which `value` should be inserted
+                     *          into `array`.
+                     */
+                    function binaryIndexBy(array, value, iteratee, retHighest) {
+                        value = iteratee(value);
+
+                        var low = 0,
+                            high = array ? array.length : 0,
+                            valIsNaN = value !== value,
+                            valIsNull = value === null,
+                            valIsUndef = value === undefined;
+
+                        while (low < high) {
+                            var mid = nativeFloor((low + high) / 2),
+                                computed = iteratee(array[mid]),
+                                isDef = computed !== undefined,
+                                isReflexive = computed === computed;
+
+                            if (valIsNaN) {
+                                var setLow = isReflexive || retHighest;
+                            } else if (valIsNull) {
+                                setLow = isReflexive && isDef && (retHighest || computed != null);
+                            } else if (valIsUndef) {
+                                setLow = isReflexive && (retHighest || isDef);
+                            } else if (computed == null) {
+                                setLow = false;
+                            } else {
+                                setLow = retHighest ? (computed <= value) : (computed < value);
+                            }
+                            if (setLow) {
+                                low = mid + 1;
+                            } else {
+                                high = mid;
+                            }
+                        }
+                        return nativeMin(high, MAX_ARRAY_INDEX);
+                    }
+
+                    /**
+                     * A specialized version of `baseCallback` which only supports `this`
+                     * binding and specifying the number of arguments to provide to `func`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to bind.
+                     * @param {*}
+                     *            thisArg The `this` binding of `func`.
+                     * @param {number}
+                     *            [argCount] The number of arguments to provide to `func`.
+                     * @returns {Function} Returns the callback.
+                     */
+                    function bindCallback(func, thisArg, argCount) {
+                        if (typeof func != 'function') {
+                            return identity;
+                        }
+                        if (thisArg === undefined) {
+                            return func;
+                        }
+                        switch (argCount) {
+                            case 1:
+                                return function(value) {
+                                    return func.call(thisArg, value);
+                                };
+                            case 3:
+                                return function(value, index, collection) {
+                                    return func.call(thisArg, value, index, collection);
+                                };
+                            case 4:
+                                return function(accumulator, value, index, collection) {
+                                    return func.call(thisArg, accumulator, value, index, collection);
+                                };
+                            case 5:
+                                return function(value, other, key, object, source) {
+                                    return func.call(thisArg, value, other, key, object, source);
+                                };
+                        }
+                        return function() {
+                            return func.apply(thisArg, arguments);
+                        };
+                    }
+
+                    /**
+                     * Creates a clone of the given array buffer.
+                     * 
+                     * @private
+                     * @param {ArrayBuffer}
+                     *            buffer The array buffer to clone.
+                     * @returns {ArrayBuffer} Returns the cloned array buffer.
+                     */
+                    function bufferClone(buffer) {
+                        var result = new ArrayBuffer(buffer.byteLength),
+                            view = new Uint8Array(result);
+
+                        view.set(new Uint8Array(buffer));
+                        return result;
+                    }
+
+                    /**
+                     * Creates an array that is the composition of partially applied arguments,
+                     * placeholders, and provided arguments into a single array of arguments.
+                     * 
+                     * @private
+                     * @param {Array|Object}
+                     *            args The provided arguments.
+                     * @param {Array}
+                     *            partials The arguments to prepend to those provided.
+                     * @param {Array}
+                     *            holders The `partials` placeholder indexes.
+                     * @returns {Array} Returns the new array of composed arguments.
+                     */
+                    function composeArgs(args, partials, holders) {
+                        var holdersLength = holders.length,
+                            argsIndex = -1,
+                            argsLength = nativeMax(args.length - holdersLength, 0),
+                            leftIndex = -1,
+                            leftLength = partials.length,
+                            result = Array(leftLength + argsLength);
+
+                        while (++leftIndex < leftLength) {
+                            result[leftIndex] = partials[leftIndex];
+                        }
+                        while (++argsIndex < holdersLength) {
+                            result[holders[argsIndex]] = args[argsIndex];
+                        }
+                        while (argsLength--) {
+                            result[leftIndex++] = args[argsIndex++];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * This function is like `composeArgs` except that the arguments composition
+                     * is tailored for `_.partialRight`.
+                     * 
+                     * @private
+                     * @param {Array|Object}
+                     *            args The provided arguments.
+                     * @param {Array}
+                     *            partials The arguments to append to those provided.
+                     * @param {Array}
+                     *            holders The `partials` placeholder indexes.
+                     * @returns {Array} Returns the new array of composed arguments.
+                     */
+                    function composeArgsRight(args, partials, holders) {
+                        var holdersIndex = -1,
+                            holdersLength = holders.length,
+                            argsIndex = -1,
+                            argsLength = nativeMax(args.length - holdersLength, 0),
+                            rightIndex = -1,
+                            rightLength = partials.length,
+                            result = Array(argsLength + rightLength);
+
+                        while (++argsIndex < argsLength) {
+                            result[argsIndex] = args[argsIndex];
+                        }
+                        var offset = argsIndex;
+                        while (++rightIndex < rightLength) {
+                            result[offset + rightIndex] = partials[rightIndex];
+                        }
+                        while (++holdersIndex < holdersLength) {
+                            result[offset + holders[holdersIndex]] = args[argsIndex++];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition`
+                     * function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            setter The function to set keys and values of the accumulator
+                     *            object.
+                     * @param {Function}
+                     *            [initializer] The function to initialize the accumulator
+                     *            object.
+                     * @returns {Function} Returns the new aggregator function.
+                     */
+                    function createAggregator(setter, initializer) {
+                        return function(collection, iteratee, thisArg) {
+                            var result = initializer ? initializer() : {};
+                            iteratee = getCallback(iteratee, thisArg, 3);
+
+                            if (isArray(collection)) {
+                                var index = -1,
+                                    length = collection.length;
+
+                                while (++index < length) {
+                                    var value = collection[index];
+                                    setter(result, value, iteratee(value, index, collection), collection);
+                                }
+                            } else {
+                                baseEach(collection, function(value, key, collection) {
+                                    setter(result, value, iteratee(value, key, collection), collection);
+                                });
+                            }
+                            return result;
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            assigner The function to assign values.
+                     * @returns {Function} Returns the new assigner function.
+                     */
+                    function createAssigner(assigner) {
+                        return restParam(function(object, sources) {
+                            var index = -1,
+                                length = object == null ? 0 : sources.length,
+                                customizer = length > 2 ? sources[length - 2] : undefined,
+                                guard = length > 2 ? sources[2] : undefined,
+                                thisArg = length > 1 ? sources[length - 1] : undefined;
+
+                            if (typeof customizer == 'function') {
+                                customizer = bindCallback(customizer, thisArg, 5);
+                                length -= 2;
+                            } else {
+                                customizer = typeof thisArg == 'function' ? thisArg : undefined;
+                                length -= (customizer ? 1 : 0);
+                            }
+                            if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+                                customizer = length < 3 ? undefined : customizer;
+                                length = 1;
+                            }
+                            while (++index < length) {
+                                var source = sources[index];
+                                if (source) {
+                                    assigner(object, source, customizer);
+                                }
+                            }
+                            return object;
+                        });
+                    }
+
+                    /**
+                     * Creates a `baseEach` or `baseEachRight` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            eachFunc The function to iterate over a collection.
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Function} Returns the new base function.
+                     */
+                    function createBaseEach(eachFunc, fromRight) {
+                        return function(collection, iteratee) {
+                            var length = collection ? getLength(collection) : 0;
+                            if (!isLength(length)) {
+                                return eachFunc(collection, iteratee);
+                            }
+                            var index = fromRight ? length : -1,
+                                iterable = toObject(collection);
+
+                            while ((fromRight ? index-- : ++index < length)) {
+                                if (iteratee(iterable[index], index, iterable) === false) {
+                                    break;
+                                }
+                            }
+                            return collection;
+                        };
+                    }
+
+                    /**
+                     * Creates a base function for `_.forIn` or `_.forInRight`.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Function} Returns the new base function.
+                     */
+                    function createBaseFor(fromRight) {
+                        return function(object, iteratee, keysFunc) {
+                            var iterable = toObject(object),
+                                props = keysFunc(object),
+                                length = props.length,
+                                index = fromRight ? length : -1;
+
+                            while ((fromRight ? index-- : ++index < length)) {
+                                var key = props[index];
+                                if (iteratee(iterable[key], key, iterable) === false) {
+                                    break;
+                                }
+                            }
+                            return object;
+                        };
+                    }
+
+                    /**
+                     * Creates a function that wraps `func` and invokes it with the `this`
+                     * binding of `thisArg`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to bind.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `func`.
+                     * @returns {Function} Returns the new bound function.
+                     */
+                    function createBindWrapper(func, thisArg) {
+                        var Ctor = createCtorWrapper(func);
+
+                        function wrapper() {
+                            var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+                            return fn.apply(thisArg, arguments);
+                        }
+                        return wrapper;
+                    }
+
+                    /**
+                     * Creates a `Set` cache object to optimize linear searches of large arrays.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            [values] The values to cache.
+                     * @returns {null|Object} Returns the new cache object if `Set` is
+                     *          supported, else `null`.
+                     */
+                    function createCache(values) {
+                        return (nativeCreate && Set) ? new SetCache(values) : null;
+                    }
+
+                    /**
+                     * Creates a function that produces compound words out of the words in a
+                     * given string.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            callback The function to combine each word.
+                     * @returns {Function} Returns the new compounder function.
+                     */
+                    function createCompounder(callback) {
+                        return function(string) {
+                            var index = -1,
+                                array = words(deburr(string)),
+                                length = array.length,
+                                result = '';
+
+                            while (++index < length) {
+                                result = callback(result, array[index], index);
+                            }
+                            return result;
+                        };
+                    }
+
+                    /**
+                     * Creates a function that produces an instance of `Ctor` regardless of
+                     * whether it was invoked as part of a `new` expression or by `call` or
+                     * `apply`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            Ctor The constructor to wrap.
+                     * @returns {Function} Returns the new wrapped function.
+                     */
+                    function createCtorWrapper(Ctor) {
+                        return function() {
+                            // Use a `switch` statement to work with class constructors.
+                            // See
+                            // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+                            // for more details.
+                            var args = arguments;
+                            switch (args.length) {
+                                case 0:
+                                    return new Ctor;
+                                case 1:
+                                    return new Ctor(args[0]);
+                                case 2:
+                                    return new Ctor(args[0], args[1]);
+                                case 3:
+                                    return new Ctor(args[0], args[1], args[2]);
+                                case 4:
+                                    return new Ctor(args[0], args[1], args[2], args[3]);
+                                case 5:
+                                    return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+                                case 6:
+                                    return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+                                case 7:
+                                    return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+                            }
+                            var thisBinding = baseCreate(Ctor.prototype),
+                                result = Ctor.apply(thisBinding, args);
+
+                            // Mimic the constructor's `return` behavior.
+                            // See https://es5.github.io/#x13.2.2 for more details.
+                            return isObject(result) ? result : thisBinding;
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.curry` or `_.curryRight` function.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            flag The curry bit flag.
+                     * @returns {Function} Returns the new curry function.
+                     */
+                    function createCurry(flag) {
+                        function curryFunc(func, arity, guard) {
+                            if (guard && isIterateeCall(func, arity, guard)) {
+                                arity = undefined;
+                            }
+                            var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity);
+                            result.placeholder = curryFunc.placeholder;
+                            return result;
+                        }
+                        return curryFunc;
+                    }
+
+                    /**
+                     * Creates a `_.defaults` or `_.defaultsDeep` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            assigner The function to assign values.
+                     * @param {Function}
+                     *            customizer The function to customize assigned values.
+                     * @returns {Function} Returns the new defaults function.
+                     */
+                    function createDefaults(assigner, customizer) {
+                        return restParam(function(args) {
+                            var object = args[0];
+                            if (object == null) {
+                                return object;
+                            }
+                            args.push(customizer);
+                            return assigner.apply(undefined, args);
+                        });
+                    }
+
+                    /**
+                     * Creates a `_.max` or `_.min` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            comparator The function used to compare values.
+                     * @param {*}
+                     *            exValue The initial extremum value.
+                     * @returns {Function} Returns the new extremum function.
+                     */
+                    function createExtremum(comparator, exValue) {
+                        return function(collection, iteratee, thisArg) {
+                            if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
+                                iteratee = undefined;
+                            }
+                            iteratee = getCallback(iteratee, thisArg, 3);
+                            if (iteratee.length == 1) {
+                                collection = isArray(collection) ? collection : toIterable(collection);
+                                var result = arrayExtremum(collection, iteratee, comparator, exValue);
+                                if (!(collection.length && result === exValue)) {
+                                    return result;
+                                }
+                            }
+                            return baseExtremum(collection, iteratee, comparator, exValue);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.find` or `_.findLast` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            eachFunc The function to iterate over a collection.
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Function} Returns the new find function.
+                     */
+                    function createFind(eachFunc, fromRight) {
+                        return function(collection, predicate, thisArg) {
+                            predicate = getCallback(predicate, thisArg, 3);
+                            if (isArray(collection)) {
+                                var index = baseFindIndex(collection, predicate, fromRight);
+                                return index > -1 ? collection[index] : undefined;
+                            }
+                            return baseFind(collection, predicate, eachFunc);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.findIndex` or `_.findLastIndex` function.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Function} Returns the new find function.
+                     */
+                    function createFindIndex(fromRight) {
+                        return function(array, predicate, thisArg) {
+                            if (!(array && array.length)) {
+                                return -1;
+                            }
+                            predicate = getCallback(predicate, thisArg, 3);
+                            return baseFindIndex(array, predicate, fromRight);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.findKey` or `_.findLastKey` function.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            objectFunc The function to iterate over an object.
+                     * @returns {Function} Returns the new find function.
+                     */
+                    function createFindKey(objectFunc) {
+                        return function(object, predicate, thisArg) {
+                            predicate = getCallback(predicate, thisArg, 3);
+                            return baseFind(object, predicate, objectFunc, true);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.flow` or `_.flowRight` function.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [fromRight] Specify iterating from right to left.
+                     * @returns {Function} Returns the new flow function.
+                     */
+                    function createFlow(fromRight) {
+                        return function() {
+                            var wrapper,
+                                length = arguments.length,
+                                index = fromRight ? length : -1,
+                                leftIndex = 0,
+                                funcs = Array(length);
+
+                            while ((fromRight ? index-- : ++index < length)) {
+                                var func = funcs[leftIndex++] = arguments[index];
+                                if (typeof func != 'function') {
+                                    throw new TypeError(FUNC_ERROR_TEXT);
+                                }
+                                if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') {
+                                    wrapper = new LodashWrapper([], true);
+                                }
+                            }
+                            index = wrapper ? -1 : length;
+                            while (++index < length) {
+                                func = funcs[index];
+
+                                var funcName = getFuncName(func),
+                                    data = funcName == 'wrapper' ? getData(func) : undefined;
+
+                                if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
+                                    wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
+                                } else {
+                                    wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
+                                }
+                            }
+                            return function() {
+                                var args = arguments,
+                                    value = args[0];
+
+                                if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
+                                    return wrapper.plant(value).value();
+                                }
+                                var index = 0,
+                                    result = length ? funcs[index].apply(this, args) : value;
+
+                                while (++index < length) {
+                                    result = funcs[index].call(this, result);
+                                }
+                                return result;
+                            };
+                        };
+                    }
+
+                    /**
+                     * Creates a function for `_.forEach` or `_.forEachRight`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            arrayFunc The function to iterate over an array.
+                     * @param {Function}
+                     *            eachFunc The function to iterate over a collection.
+                     * @returns {Function} Returns the new each function.
+                     */
+                    function createForEach(arrayFunc, eachFunc) {
+                        return function(collection, iteratee, thisArg) {
+                            return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) ? arrayFunc(collection, iteratee) : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
+                        };
+                    }
+
+                    /**
+                     * Creates a function for `_.forIn` or `_.forInRight`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            objectFunc The function to iterate over an object.
+                     * @returns {Function} Returns the new each function.
+                     */
+                    function createForIn(objectFunc) {
+                        return function(object, iteratee, thisArg) {
+                            if (typeof iteratee != 'function' || thisArg !== undefined) {
+                                iteratee = bindCallback(iteratee, thisArg, 3);
+                            }
+                            return objectFunc(object, iteratee, keysIn);
+                        };
+                    }
+
+                    /**
+                     * Creates a function for `_.forOwn` or `_.forOwnRight`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            objectFunc The function to iterate over an object.
+                     * @returns {Function} Returns the new each function.
+                     */
+                    function createForOwn(objectFunc) {
+                        return function(object, iteratee, thisArg) {
+                            if (typeof iteratee != 'function' || thisArg !== undefined) {
+                                iteratee = bindCallback(iteratee, thisArg, 3);
+                            }
+                            return objectFunc(object, iteratee);
+                        };
+                    }
+
+                    /**
+                     * Creates a function for `_.mapKeys` or `_.mapValues`.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [isMapKeys] Specify mapping keys instead of values.
+                     * @returns {Function} Returns the new map function.
+                     */
+                    function createObjectMapper(isMapKeys) {
+                        return function(object, iteratee, thisArg) {
+                            var result = {};
+                            iteratee = getCallback(iteratee, thisArg, 3);
+
+                            baseForOwn(object, function(value, key, object) {
+                                var mapped = iteratee(value, key, object);
+                                key = isMapKeys ? mapped : key;
+                                value = isMapKeys ? value : mapped;
+                                result[key] = value;
+                            });
+                            return result;
+                        };
+                    }
+
+                    /**
+                     * Creates a function for `_.padLeft` or `_.padRight`.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [fromRight] Specify padding from the right.
+                     * @returns {Function} Returns the new pad function.
+                     */
+                    function createPadDir(fromRight) {
+                        return function(string, length, chars) {
+                            string = baseToString(string);
+                            return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.partial` or `_.partialRight` function.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            flag The partial bit flag.
+                     * @returns {Function} Returns the new partial function.
+                     */
+                    function createPartial(flag) {
+                        var partialFunc = restParam(function(func, partials) {
+                            var holders = replaceHolders(partials, partialFunc.placeholder);
+                            return createWrapper(func, flag, undefined, partials, holders);
+                        });
+                        return partialFunc;
+                    }
+
+                    /**
+                     * Creates a function for `_.reduce` or `_.reduceRight`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            arrayFunc The function to iterate over an array.
+                     * @param {Function}
+                     *            eachFunc The function to iterate over a collection.
+                     * @returns {Function} Returns the new each function.
+                     */
+                    function createReduce(arrayFunc, eachFunc) {
+                        return function(collection, iteratee, accumulator, thisArg) {
+                            var initFromArray = arguments.length < 3;
+                            return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) ? arrayFunc(collection, iteratee, accumulator, initFromArray) : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
+                        };
+                    }
+
+                    /**
+                     * Creates a function that wraps `func` and invokes it with optional `this`
+                     * binding of, partial application, and currying.
+                     * 
+                     * @private
+                     * @param {Function|string}
+                     *            func The function or method name to reference.
+                     * @param {number}
+                     *            bitmask The bitmask of flags. See `createWrapper` for more
+                     *            details.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `func`.
+                     * @param {Array}
+                     *            [partials] The arguments to prepend to those provided to the
+                     *            new function.
+                     * @param {Array}
+                     *            [holders] The `partials` placeholder indexes.
+                     * @param {Array}
+                     *            [partialsRight] The arguments to append to those provided to
+                     *            the new function.
+                     * @param {Array}
+                     *            [holdersRight] The `partialsRight` placeholder indexes.
+                     * @param {Array}
+                     *            [argPos] The argument positions of the new function.
+                     * @param {number}
+                     *            [ary] The arity cap of `func`.
+                     * @param {number}
+                     *            [arity] The arity of `func`.
+                     * @returns {Function} Returns the new wrapped function.
+                     */
+                    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+                        var isAry = bitmask & ARY_FLAG,
+                            isBind = bitmask & BIND_FLAG,
+                            isBindKey = bitmask & BIND_KEY_FLAG,
+                            isCurry = bitmask & CURRY_FLAG,
+                            isCurryBound = bitmask & CURRY_BOUND_FLAG,
+                            isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+                            Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+                        function wrapper() {
+                            // Avoid `arguments` object use disqualifying optimizations by
+                            // converting it to an array before providing it to other functions.
+                            var length = arguments.length,
+                                index = length,
+                                args = Array(length);
+
+                            while (index--) {
+                                args[index] = arguments[index];
+                            }
+                            if (partials) {
+                                args = composeArgs(args, partials, holders);
+                            }
+                            if (partialsRight) {
+                                args = composeArgsRight(args, partialsRight, holdersRight);
+                            }
+                            if (isCurry || isCurryRight) {
+                                var placeholder = wrapper.placeholder,
+                                    argsHolders = replaceHolders(args, placeholder);
+
+                                length -= argsHolders.length;
+                                if (length < arity) {
+                                    var newArgPos = argPos ? arrayCopy(argPos) : undefined,
+                                        newArity = nativeMax(arity - length, 0),
+                                        newsHolders = isCurry ? argsHolders : undefined,
+                                        newHoldersRight = isCurry ? undefined : argsHolders,
+                                        newPartials = isCurry ? args : undefined,
+                                        newPartialsRight = isCurry ? undefined : args;
+
+                                    bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+                                    bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+                                    if (!isCurryBound) {
+                                        bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+                                    }
+                                    var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
+                                        result = createHybridWrapper.apply(undefined, newData);
+
+                                    if (isLaziable(func)) {
+                                        setData(result, newData);
+                                    }
+                                    result.placeholder = placeholder;
+                                    return result;
+                                }
+                            }
+                            var thisBinding = isBind ? thisArg : this,
+                                fn = isBindKey ? thisBinding[func] : func;
+
+                            if (argPos) {
+                                args = reorder(args, argPos);
+                            }
+                            if (isAry && ary < args.length) {
+                                args.length = ary;
+                            }
+                            if (this && this !== root && this instanceof wrapper) {
+                                fn = Ctor || createCtorWrapper(func);
+                            }
+                            return fn.apply(thisBinding, args);
+                        }
+                        return wrapper;
+                    }
+
+                    /**
+                     * Creates the padding required for `string` based on the given `length`.
+                     * The `chars` string is truncated if the number of characters exceeds
+                     * `length`.
+                     * 
+                     * @private
+                     * @param {string}
+                     *            string The string to create padding for.
+                     * @param {number}
+                     *            [length=0] The padding length.
+                     * @param {string}
+                     *            [chars=' '] The string used as padding.
+                     * @returns {string} Returns the pad for `string`.
+                     */
+                    function createPadding(string, length, chars) {
+                        var strLength = string.length;
+                        length = +length;
+
+                        if (strLength >= length || !nativeIsFinite(length)) {
+                            return '';
+                        }
+                        var padLength = length - strLength;
+                        chars = chars == null ? ' ' : (chars + '');
+                        return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength);
+                    }
+
+                    /**
+                     * Creates a function that wraps `func` and invokes it with the optional
+                     * `this` binding of `thisArg` and the `partials` prepended to those
+                     * provided to the wrapper.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to partially apply arguments to.
+                     * @param {number}
+                     *            bitmask The bitmask of flags. See `createWrapper` for more
+                     *            details.
+                     * @param {*}
+                     *            thisArg The `this` binding of `func`.
+                     * @param {Array}
+                     *            partials The arguments to prepend to those provided to the new
+                     *            function.
+                     * @returns {Function} Returns the new bound function.
+                     */
+                    function createPartialWrapper(func, bitmask, thisArg, partials) {
+                        var isBind = bitmask & BIND_FLAG,
+                            Ctor = createCtorWrapper(func);
+
+                        function wrapper() {
+                            // Avoid `arguments` object use disqualifying optimizations by
+                            // converting it to an array before providing it `func`.
+                            var argsIndex = -1,
+                                argsLength = arguments.length,
+                                leftIndex = -1,
+                                leftLength = partials.length,
+                                args = Array(leftLength + argsLength);
+
+                            while (++leftIndex < leftLength) {
+                                args[leftIndex] = partials[leftIndex];
+                            }
+                            while (argsLength--) {
+                                args[leftIndex++] = arguments[++argsIndex];
+                            }
+                            var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+                            return fn.apply(isBind ? thisArg : this, args);
+                        }
+                        return wrapper;
+                    }
+
+                    /**
+                     * Creates a `_.ceil`, `_.floor`, or `_.round` function.
+                     * 
+                     * @private
+                     * @param {string}
+                     *            methodName The name of the `Math` method to use when rounding.
+                     * @returns {Function} Returns the new round function.
+                     */
+                    function createRound(methodName) {
+                        var func = Math[methodName];
+                        return function(number, precision) {
+                            precision = precision === undefined ? 0 : (+precision || 0);
+                            if (precision) {
+                                precision = pow(10, precision);
+                                return func(number * precision) / precision;
+                            }
+                            return func(number);
+                        };
+                    }
+
+                    /**
+                     * Creates a `_.sortedIndex` or `_.sortedLastIndex` function.
+                     * 
+                     * @private
+                     * @param {boolean}
+                     *            [retHighest] Specify returning the highest qualified index.
+                     * @returns {Function} Returns the new index function.
+                     */
+                    function createSortedIndex(retHighest) {
+                        return function(array, value, iteratee, thisArg) {
+                            var callback = getCallback(iteratee);
+                            return (iteratee == null && callback === baseCallback) ? binaryIndex(array, value, retHighest) : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest);
+                        };
+                    }
+
+                    /**
+                     * Creates a function that either curries or invokes `func` with optional
+                     * `this` binding and partially applied arguments.
+                     * 
+                     * @private
+                     * @param {Function|string}
+                     *            func The function or method name to reference.
+                     * @param {number}
+                     *            bitmask The bitmask of flags. The bitmask may be composed of
+                     *            the following flags: 1 - `_.bind` 2 - `_.bindKey` 4 -
+                     *            `_.curry` or `_.curryRight` of a bound function 8 - `_.curry`
+                     *            16 - `_.curryRight` 32 - `_.partial` 64 - `_.partialRight` 128 -
+                     *            `_.rearg` 256 - `_.ary`
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `func`.
+                     * @param {Array}
+                     *            [partials] The arguments to be partially applied.
+                     * @param {Array}
+                     *            [holders] The `partials` placeholder indexes.
+                     * @param {Array}
+                     *            [argPos] The argument positions of the new function.
+                     * @param {number}
+                     *            [ary] The arity cap of `func`.
+                     * @param {number}
+                     *            [arity] The arity of `func`.
+                     * @returns {Function} Returns the new wrapped function.
+                     */
+                    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+                        var isBindKey = bitmask & BIND_KEY_FLAG;
+                        if (!isBindKey && typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        var length = partials ? partials.length : 0;
+                        if (!length) {
+                            bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
+                            partials = holders = undefined;
+                        }
+                        length -= (holders ? holders.length : 0);
+                        if (bitmask & PARTIAL_RIGHT_FLAG) {
+                            var partialsRight = partials,
+                                holdersRight = holders;
+
+                            partials = holders = undefined;
+                        }
+                        var data = isBindKey ? undefined : getData(func),
+                            newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
+
+                        if (data) {
+                            mergeData(newData, data);
+                            bitmask = newData[1];
+                            arity = newData[9];
+                        }
+                        newData[9] = arity == null ? (isBindKey ? 0 : func.length) : (nativeMax(arity - length, 0) || 0);
+
+                        if (bitmask == BIND_FLAG) {
+                            var result = createBindWrapper(newData[0], newData[2]);
+                        } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
+                            result = createPartialWrapper.apply(undefined, newData);
+                        } else {
+                            result = createHybridWrapper.apply(undefined, newData);
+                        }
+                        var setter = data ? baseSetData : setData;
+                        return setter(result, newData);
+                    }
+
+                    /**
+                     * A specialized version of `baseIsEqualDeep` for arrays with support for
+                     * partial deep comparisons.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to compare.
+                     * @param {Array}
+                     *            other The other array to compare.
+                     * @param {Function}
+                     *            equalFunc The function to determine equivalents of values.
+                     * @param {Function}
+                     *            [customizer] The function to customize comparing arrays.
+                     * @param {boolean}
+                     *            [isLoose] Specify performing partial comparisons.
+                     * @param {Array}
+                     *            [stackA] Tracks traversed `value` objects.
+                     * @param {Array}
+                     *            [stackB] Tracks traversed `other` objects.
+                     * @returns {boolean} Returns `true` if the arrays are equivalent, else
+                     *          `false`.
+                     */
+                    function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+                        var index = -1,
+                            arrLength = array.length,
+                            othLength = other.length;
+
+                        if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+                            return false;
+                        }
+                        // Ignore non-index properties.
+                        while (++index < arrLength) {
+                            var arrValue = array[index],
+                                othValue = other[index],
+                                result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+
+                            if (result !== undefined) {
+                                if (result) {
+                                    continue;
+                                }
+                                return false;
+                            }
+                            // Recursively compare arrays (susceptible to call stack limits).
+                            if (isLoose) {
+                                if (!arraySome(other, function(othValue) {
+                                        return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+                                    })) {
+                                    return false;
+                                }
+                            } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+
+                    /**
+                     * A specialized version of `baseIsEqualDeep` for comparing objects of the
+                     * same `toStringTag`.
+                     * 
+                     * **Note:** This function only supports comparing values with tags of
+                     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to compare.
+                     * @param {Object}
+                     *            other The other object to compare.
+                     * @param {string}
+                     *            tag The `toStringTag` of the objects to compare.
+                     * @returns {boolean} Returns `true` if the objects are equivalent, else
+                     *          `false`.
+                     */
+                    function equalByTag(object, other, tag) {
+                        switch (tag) {
+                            case boolTag:
+                            case dateTag:
+                                // Coerce dates and booleans to numbers, dates to milliseconds and
+                                // booleans
+                                // to `1` or `0` treating invalid dates coerced to `NaN` as not
+                                // equal.
+                                return +object == +other;
+
+                            case errorTag:
+                                return object.name == other.name && object.message == other.message;
+
+                            case numberTag:
+                                // Treat `NaN` vs. `NaN` as equal.
+                                return (object != +object) ? other != +other : object == +other;
+
+                            case regexpTag:
+                            case stringTag:
+                                // Coerce regexes to strings and treat strings primitives and string
+                                // objects as equal. See https://es5.github.io/#x15.10.6.4 for more
+                                // details.
+                                return object == (other + '');
+                        }
+                        return false;
+                    }
+
+                    /**
+                     * A specialized version of `baseIsEqualDeep` for objects with support for
+                     * partial deep comparisons.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to compare.
+                     * @param {Object}
+                     *            other The other object to compare.
+                     * @param {Function}
+                     *            equalFunc The function to determine equivalents of values.
+                     * @param {Function}
+                     *            [customizer] The function to customize comparing values.
+                     * @param {boolean}
+                     *            [isLoose] Specify performing partial comparisons.
+                     * @param {Array}
+                     *            [stackA] Tracks traversed `value` objects.
+                     * @param {Array}
+                     *            [stackB] Tracks traversed `other` objects.
+                     * @returns {boolean} Returns `true` if the objects are equivalent, else
+                     *          `false`.
+                     */
+                    function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+                        var objProps = keys(object),
+                            objLength = objProps.length,
+                            othProps = keys(other),
+                            othLength = othProps.length;
+
+                        if (objLength != othLength && !isLoose) {
+                            return false;
+                        }
+                        var index = objLength;
+                        while (index--) {
+                            var key = objProps[index];
+                            if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+                                return false;
+                            }
+                        }
+                        var skipCtor = isLoose;
+                        while (++index < objLength) {
+                            key = objProps[index];
+                            var objValue = object[key],
+                                othValue = other[key],
+                                result = customizer ? customizer(isLoose ? othValue : objValue, isLoose ? objValue : othValue, key) : undefined;
+
+                            // Recursively compare objects (susceptible to call stack limits).
+                            if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
+                                return false;
+                            }
+                            skipCtor || (skipCtor = key == 'constructor');
+                        }
+                        if (!skipCtor) {
+                            var objCtor = object.constructor,
+                                othCtor = other.constructor;
+
+                            // Non `Object` object instances with different constructors are not
+                            // equal.
+                            if (objCtor != othCtor &&
+                                ('constructor' in object && 'constructor' in other) &&
+                                !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+                                    typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+
+                    /**
+                     * Gets the appropriate "callback" function. If the `_.callback` method is
+                     * customized this function returns the custom method, otherwise it returns
+                     * the `baseCallback` function. If arguments are provided the chosen
+                     * function is invoked with them and its result is returned.
+                     * 
+                     * @private
+                     * @returns {Function} Returns the chosen function or its result.
+                     */
+                    function getCallback(func, thisArg, argCount) {
+                        var result = lodash.callback || callback;
+                        result = result === callback ? baseCallback : result;
+                        return argCount ? result(func, thisArg, argCount) : result;
+                    }
+
+                    /**
+                     * Gets metadata for `func`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to query.
+                     * @returns {*} Returns the metadata for `func`.
+                     */
+                    var getData = !metaMap ? noop : function(func) {
+                        return metaMap.get(func);
+                    };
+
+                    /**
+                     * Gets the name of `func`.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to query.
+                     * @returns {string} Returns the function name.
+                     */
+                    function getFuncName(func) {
+                        var result = func.name,
+                            array = realNames[result],
+                            length = array ? array.length : 0;
+
+                        while (length--) {
+                            var data = array[length],
+                                otherFunc = data.func;
+                            if (otherFunc == null || otherFunc == func) {
+                                return data.name;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
+                     * customized this function returns the custom method, otherwise it returns
+                     * the `baseIndexOf` function. If arguments are provided the chosen function
+                     * is invoked with them and its result is returned.
+                     * 
+                     * @private
+                     * @returns {Function|number} Returns the chosen function or its result.
+                     */
+                    function getIndexOf(collection, target, fromIndex) {
+                        var result = lodash.indexOf || indexOf;
+                        result = result === indexOf ? baseIndexOf : result;
+                        return collection ? result(collection, target, fromIndex) : result;
+                    }
+
+                    /**
+                     * Gets the "length" property value of `object`.
+                     * 
+                     * **Note:** This function is used to avoid a [JIT
+                     * bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects Safari
+                     * on at least iOS 8.1-8.3 ARM64.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {*} Returns the "length" value.
+                     */
+                    var getLength = baseProperty('length');
+
+                    /**
+                     * Gets the propery names, values, and compare flags of `object`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the match data of `object`.
+                     */
+                    function getMatchData(object) {
+                        var result = pairs(object),
+                            length = result.length;
+
+                        while (length--) {
+                            result[length][2] = isStrictComparable(result[length][1]);
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Gets the native function at `key` of `object`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {string}
+                     *            key The key of the method to get.
+                     * @returns {*} Returns the function if it's native, else `undefined`.
+                     */
+                    function getNative(object, key) {
+                        var value = object == null ? undefined : object[key];
+                        return isNative(value) ? value : undefined;
+                    }
+
+                    /**
+                     * Gets the view, applying any `transforms` to the `start` and `end`
+                     * positions.
+                     * 
+                     * @private
+                     * @param {number}
+                     *            start The start of the view.
+                     * @param {number}
+                     *            end The end of the view.
+                     * @param {Array}
+                     *            transforms The transformations to apply to the view.
+                     * @returns {Object} Returns an object containing the `start` and `end`
+                     *          positions of the view.
+                     */
+                    function getView(start, end, transforms) {
+                        var index = -1,
+                            length = transforms.length;
+
+                        while (++index < length) {
+                            var data = transforms[index],
+                                size = data.size;
+
+                            switch (data.type) {
+                                case 'drop':
+                                    start += size;
+                                    break;
+                                case 'dropRight':
+                                    end -= size;
+                                    break;
+                                case 'take':
+                                    end = nativeMin(end, start + size);
+                                    break;
+                                case 'takeRight':
+                                    start = nativeMax(start, end - size);
+                                    break;
+                            }
+                        }
+                        return {
+                            'start': start,
+                            'end': end
+                        };
+                    }
+
+                    /**
+                     * Initializes an array clone.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to clone.
+                     * @returns {Array} Returns the initialized clone.
+                     */
+                    function initCloneArray(array) {
+                        var length = array.length,
+                            result = new array.constructor(length);
+
+                        // Add array properties assigned by `RegExp#exec`.
+                        if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+                            result.index = array.index;
+                            result.input = array.input;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Initializes an object clone.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to clone.
+                     * @returns {Object} Returns the initialized clone.
+                     */
+                    function initCloneObject(object) {
+                        var Ctor = object.constructor;
+                        if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
+                            Ctor = Object;
+                        }
+                        return new Ctor;
+                    }
+
+                    /**
+                     * Initializes an object clone based on its `toStringTag`.
+                     * 
+                     * **Note:** This function only supports cloning values with tags of
+                     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to clone.
+                     * @param {string}
+                     *            tag The `toStringTag` of the object to clone.
+                     * @param {boolean}
+                     *            [isDeep] Specify a deep clone.
+                     * @returns {Object} Returns the initialized clone.
+                     */
+                    function initCloneByTag(object, tag, isDeep) {
+                        var Ctor = object.constructor;
+                        switch (tag) {
+                            case arrayBufferTag:
+                                return bufferClone(object);
+
+                            case boolTag:
+                            case dateTag:
+                                return new Ctor(+object);
+
+                            case float32Tag:
+                            case float64Tag:
+                            case int8Tag:
+                            case int16Tag:
+                            case int32Tag:
+                            case uint8Tag:
+                            case uint8ClampedTag:
+                            case uint16Tag:
+                            case uint32Tag:
+                                var buffer = object.buffer;
+                                return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+
+                            case numberTag:
+                            case stringTag:
+                                return new Ctor(object);
+
+                            case regexpTag:
+                                var result = new Ctor(object.source, reFlags.exec(object));
+                                result.lastIndex = object.lastIndex;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Invokes the method at `path` on `object`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array|string}
+                     *            path The path of the method to invoke.
+                     * @param {Array}
+                     *            args The arguments to invoke the method with.
+                     * @returns {*} Returns the result of the invoked method.
+                     */
+                    function invokePath(object, path, args) {
+                        if (object != null && !isKey(path, object)) {
+                            path = toPath(path);
+                            object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+                            path = last(path);
+                        }
+                        var func = object == null ? object : object[path];
+                        return func == null ? undefined : func.apply(object, args);
+                    }
+
+                    /**
+                     * Checks if `value` is array-like.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+                     */
+                    function isArrayLike(value) {
+                        return value != null && isLength(getLength(value));
+                    }
+
+                    /**
+                     * Checks if `value` is a valid array-like index.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to check.
+                     * @param {number}
+                     *            [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+                     * @returns {boolean} Returns `true` if `value` is a valid index, else
+                     *          `false`.
+                     */
+                    function isIndex(value, length) {
+                        value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+                        length = length == null ? MAX_SAFE_INTEGER : length;
+                        return value > -1 && value % 1 == 0 && value < length;
+                    }
+
+                    /**
+                     * Checks if the provided arguments are from an iteratee call.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The potential iteratee value argument.
+                     * @param {*}
+                     *            index The potential iteratee index or key argument.
+                     * @param {*}
+                     *            object The potential iteratee object argument.
+                     * @returns {boolean} Returns `true` if the arguments are from an iteratee
+                     *          call, else `false`.
+                     */
+                    function isIterateeCall(value, index, object) {
+                        if (!isObject(object)) {
+                            return false;
+                        }
+                        var type = typeof index;
+                        if (type == 'number' ? (isArrayLike(object) && isIndex(index, object.length)) : (type == 'string' && index in object)) {
+                            var other = object[index];
+                            return value === value ? (value === other) : (other !== other);
+                        }
+                        return false;
+                    }
+
+                    /**
+                     * Checks if `value` is a property name and not a property path.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to check.
+                     * @param {Object}
+                     *            [object] The object to query keys on.
+                     * @returns {boolean} Returns `true` if `value` is a property name, else
+                     *          `false`.
+                     */
+                    function isKey(value, object) {
+                        var type = typeof value;
+                        if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+                            return true;
+                        }
+                        if (isArray(value)) {
+                            return false;
+                        }
+                        var result = !reIsDeepProp.test(value);
+                        return result || (object != null && value in toObject(object));
+                    }
+
+                    /**
+                     * Checks if `func` has a lazy counterpart.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to check.
+                     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else
+                     *          `false`.
+                     */
+                    function isLaziable(func) {
+                        var funcName = getFuncName(func);
+                        if (!(funcName in LazyWrapper.prototype)) {
+                            return false;
+                        }
+                        var other = lodash[funcName];
+                        if (func === other) {
+                            return true;
+                        }
+                        var data = getData(other);
+                        return !!data && func === data[0];
+                    }
+
+                    /**
+                     * Checks if `value` is a valid array-like length.
+                     * 
+                     * **Note:** This function is based on
+                     * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is a valid length, else
+                     *          `false`.
+                     */
+                    function isLength(value) {
+                        return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+                    }
+
+                    /**
+                     * Checks if `value` is suitable for strict equality comparisons, i.e.
+                     * `===`.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` if suitable for strict
+                     *          equality comparisons, else `false`.
+                     */
+                    function isStrictComparable(value) {
+                        return value === value && !isObject(value);
+                    }
+
+                    /**
+                     * Merges the function metadata of `source` into `data`.
+                     * 
+                     * Merging metadata reduces the number of wrappers required to invoke a
+                     * function. This is possible because methods like `_.bind`, `_.curry`, and
+                     * `_.partial` may be applied regardless of execution order. Methods like
+                     * `_.ary` and `_.rearg` augment function arguments, making the order in
+                     * which they are executed important, preventing the merging of metadata.
+                     * However, we make an exception for a safe common case where curried
+                     * functions have `_.ary` and or `_.rearg` applied.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            data The destination metadata.
+                     * @param {Array}
+                     *            source The source metadata.
+                     * @returns {Array} Returns `data`.
+                     */
+                    function mergeData(data, source) {
+                        var bitmask = data[1],
+                            srcBitmask = source[1],
+                            newBitmask = bitmask | srcBitmask,
+                            isCommon = newBitmask < ARY_FLAG;
+
+                        var isCombo =
+                            (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
+                            (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
+                            (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+
+                        // Exit early if metadata can't be merged.
+                        if (!(isCommon || isCombo)) {
+                            return data;
+                        }
+                        // Use source `thisArg` if available.
+                        if (srcBitmask & BIND_FLAG) {
+                            data[2] = source[2];
+                            // Set when currying a bound function.
+                            newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
+                        }
+                        // Compose partial arguments.
+                        var value = source[3];
+                        if (value) {
+                            var partials = data[3];
+                            data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
+                            data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+                        }
+                        // Compose partial right arguments.
+                        value = source[5];
+                        if (value) {
+                            partials = data[5];
+                            data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
+                            data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+                        }
+                        // Use source `argPos` if available.
+                        value = source[7];
+                        if (value) {
+                            data[7] = arrayCopy(value);
+                        }
+                        // Use source `ary` if it's smaller.
+                        if (srcBitmask & ARY_FLAG) {
+                            data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+                        }
+                        // Use source `arity` if one is not provided.
+                        if (data[9] == null) {
+                            data[9] = source[9];
+                        }
+                        // Use source `func` and merge bitmasks.
+                        data[0] = source[0];
+                        data[1] = newBitmask;
+
+                        return data;
+                    }
+
+                    /**
+                     * Used by `_.defaultsDeep` to customize its `_.merge` use.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            objectValue The destination object property value.
+                     * @param {*}
+                     *            sourceValue The source object property value.
+                     * @returns {*} Returns the value to assign to the destination object.
+                     */
+                    function mergeDefaults(objectValue, sourceValue) {
+                        return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults);
+                    }
+
+                    /**
+                     * A specialized version of `_.pick` which picks `object` properties
+                     * specified by `props`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The source object.
+                     * @param {string[]}
+                     *            props The property names to pick.
+                     * @returns {Object} Returns the new object.
+                     */
+                    function pickByArray(object, props) {
+                        object = toObject(object);
+
+                        var index = -1,
+                            length = props.length,
+                            result = {};
+
+                        while (++index < length) {
+                            var key = props[index];
+                            if (key in object) {
+                                result[key] = object[key];
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * A specialized version of `_.pick` which picks `object` properties
+                     * `predicate` returns truthy for.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The source object.
+                     * @param {Function}
+                     *            predicate The function invoked per iteration.
+                     * @returns {Object} Returns the new object.
+                     */
+                    function pickByCallback(object, predicate) {
+                        var result = {};
+                        baseForIn(object, function(value, key, object) {
+                            if (predicate(value, key, object)) {
+                                result[key] = value;
+                            }
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * Reorder `array` according to the specified indexes where the element at
+                     * the first index is assigned as the first element, the element at the
+                     * second index is assigned as the second element, and so on.
+                     * 
+                     * @private
+                     * @param {Array}
+                     *            array The array to reorder.
+                     * @param {Array}
+                     *            indexes The arranged array indexes.
+                     * @returns {Array} Returns `array`.
+                     */
+                    function reorder(array, indexes) {
+                        var arrLength = array.length,
+                            length = nativeMin(indexes.length, arrLength),
+                            oldArray = arrayCopy(array);
+
+                        while (length--) {
+                            var index = indexes[length];
+                            array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * Sets metadata for `func`.
+                     * 
+                     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+                     * period of time, it will trip its breaker and transition to an identity
+                     * function to avoid garbage collection pauses in V8. See [V8 issue
+                     * 2070](https://code.google.com/p/v8/issues/detail?id=2070) for more
+                     * details.
+                     * 
+                     * @private
+                     * @param {Function}
+                     *            func The function to associate metadata with.
+                     * @param {*}
+                     *            data The metadata.
+                     * @returns {Function} Returns `func`.
+                     */
+                    var setData = (function() {
+                        var count = 0,
+                            lastCalled = 0;
+
+                        return function(key, value) {
+                            var stamp = now(),
+                                remaining = HOT_SPAN - (stamp - lastCalled);
+
+                            lastCalled = stamp;
+                            if (remaining > 0) {
+                                if (++count >= HOT_COUNT) {
+                                    return key;
+                                }
+                            } else {
+                                count = 0;
+                            }
+                            return baseSetData(key, value);
+                        };
+                    }());
+
+                    /**
+                     * A fallback implementation of `Object.keys` which creates an array of the
+                     * own enumerable property names of `object`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the array of property names.
+                     */
+                    function shimKeys(object) {
+                        var props = keysIn(object),
+                            propsLength = props.length,
+                            length = propsLength && object.length;
+
+                        var allowIndexes = !!length && isLength(length) &&
+                            (isArray(object) || isArguments(object));
+
+                        var index = -1,
+                            result = [];
+
+                        while (++index < propsLength) {
+                            var key = props[index];
+                            if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+                                result.push(key);
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Converts `value` to an array-like object if it's not one.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to process.
+                     * @returns {Array|Object} Returns the array-like object.
+                     */
+                    function toIterable(value) {
+                        if (value == null) {
+                            return [];
+                        }
+                        if (!isArrayLike(value)) {
+                            return values(value);
+                        }
+                        return isObject(value) ? value : Object(value);
+                    }
+
+                    /**
+                     * Converts `value` to an object if it's not one.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to process.
+                     * @returns {Object} Returns the object.
+                     */
+                    function toObject(value) {
+                        return isObject(value) ? value : Object(value);
+                    }
+
+                    /**
+                     * Converts `value` to property path array if it's not one.
+                     * 
+                     * @private
+                     * @param {*}
+                     *            value The value to process.
+                     * @returns {Array} Returns the property path array.
+                     */
+                    function toPath(value) {
+                        if (isArray(value)) {
+                            return value;
+                        }
+                        var result = [];
+                        baseToString(value).replace(rePropName, function(match, number, quote, string) {
+                            result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+                        });
+                        return result;
+                    }
+
+                    /**
+                     * Creates a clone of `wrapper`.
+                     * 
+                     * @private
+                     * @param {Object}
+                     *            wrapper The wrapper to clone.
+                     * @returns {Object} Returns the cloned wrapper.
+                     */
+                    function wrapperClone(wrapper) {
+                        return wrapper instanceof LazyWrapper ? wrapper.clone() : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates an array of elements split into groups the length of `size`. If
+                     * `collection` can't be split evenly, the final chunk will be the remaining
+                     * elements.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to process.
+                     * @param {number}
+                     *            [size=1] The length of each chunk.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the new array containing chunks.
+                     * @example
+                     * 
+                     * _.chunk(['a', 'b', 'c', 'd'], 2); // => [['a', 'b'], ['c', 'd']]
+                     * 
+                     * _.chunk(['a', 'b', 'c', 'd'], 3); // => [['a', 'b', 'c'], ['d']]
+                     */
+                    function chunk(array, size, guard) {
+                        if (guard ? isIterateeCall(array, size, guard) : size == null) {
+                            size = 1;
+                        } else {
+                            size = nativeMax(nativeFloor(size) || 1, 1);
+                        }
+                        var index = 0,
+                            length = array ? array.length : 0,
+                            resIndex = -1,
+                            result = Array(nativeCeil(length / size));
+
+                        while (index < length) {
+                            result[++resIndex] = baseSlice(array, index, (index += size));
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Creates an array with all falsey values removed. The values `false`,
+                     * `null`, `0`, `""`, `undefined`, and `NaN` are falsey.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to compact.
+                     * @returns {Array} Returns the new array of filtered values.
+                     * @example
+                     * 
+                     * _.compact([0, 1, false, 2, '', 3]); // => [1, 2, 3]
+                     */
+                    function compact(array) {
+                        var index = -1,
+                            length = array ? array.length : 0,
+                            resIndex = -1,
+                            result = [];
+
+                        while (++index < length) {
+                            var value = array[index];
+                            if (value) {
+                                result[++resIndex] = value;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Creates an array of unique `array` values not included in the other
+                     * provided arrays using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to inspect.
+                     * @param {...Array}
+                     *            [values] The arrays of values to exclude.
+                     * @returns {Array} Returns the new array of filtered values.
+                     * @example
+                     * 
+                     * _.difference([1, 2, 3], [4, 2]); // => [1, 3]
+                     */
+                    var difference = restParam(function(array, values) {
+                        return (isObjectLike(array) && isArrayLike(array)) ? baseDifference(array, baseFlatten(values, false, true)) : [];
+                    });
+
+                    /**
+                     * Creates a slice of `array` with `n` elements dropped from the beginning.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {number}
+                     *            [n=1] The number of elements to drop.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.drop([1, 2, 3]); // => [2, 3]
+                     * 
+                     * _.drop([1, 2, 3], 2); // => [3]
+                     * 
+                     * _.drop([1, 2, 3], 5); // => []
+                     * 
+                     * _.drop([1, 2, 3], 0); // => [1, 2, 3]
+                     */
+                    function drop(array, n, guard) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (guard ? isIterateeCall(array, n, guard) : n == null) {
+                            n = 1;
+                        }
+                        return baseSlice(array, n < 0 ? 0 : n);
+                    }
+
+                    /**
+                     * Creates a slice of `array` with `n` elements dropped from the end.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {number}
+                     *            [n=1] The number of elements to drop.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.dropRight([1, 2, 3]); // => [1, 2]
+                     * 
+                     * _.dropRight([1, 2, 3], 2); // => [1]
+                     * 
+                     * _.dropRight([1, 2, 3], 5); // => []
+                     * 
+                     * _.dropRight([1, 2, 3], 0); // => [1, 2, 3]
+                     */
+                    function dropRight(array, n, guard) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (guard ? isIterateeCall(array, n, guard) : n == null) {
+                            n = 1;
+                        }
+                        n = length - (+n || 0);
+                        return baseSlice(array, 0, n < 0 ? 0 : n);
+                    }
+
+                    /**
+                     * Creates a slice of `array` excluding elements dropped from the end.
+                     * Elements are dropped until `predicate` returns falsey. The predicate is
+                     * bound to `thisArg` and invoked with three arguments: (value, index,
+                     * array).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that match the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.dropRightWhile([1, 2, 3], function(n) { return n > 1; }); // => [1]
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': true }, { 'user': 'fred',
+                     * 'active': false }, { 'user': 'pebbles', 'active': false } ];
+                     *  // using the `_.matches` callback shorthand
+                     * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }),
+                     * 'user'); // => ['barney', 'fred']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); // =>
+                     * ['barney']
+                     *  // using the `_.property` callback shorthand
+                     * _.pluck(_.dropRightWhile(users, 'active'), 'user'); // => ['barney',
+                     * 'fred', 'pebbles']
+                     */
+                    function dropRightWhile(array, predicate, thisArg) {
+                        return (array && array.length) ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) : [];
+                    }
+
+                    /**
+                     * Creates a slice of `array` excluding elements dropped from the beginning.
+                     * Elements are dropped until `predicate` returns falsey. The predicate is
+                     * bound to `thisArg` and invoked with three arguments: (value, index,
+                     * array).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.dropWhile([1, 2, 3], function(n) { return n < 3; }); // => [3]
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': false }, { 'user': 'fred',
+                     * 'active': false }, { 'user': 'pebbles', 'active': true } ];
+                     *  // using the `_.matches` callback shorthand _.pluck(_.dropWhile(users, {
+                     * 'user': 'barney', 'active': false }), 'user'); // => ['fred', 'pebbles']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.dropWhile(users, 'active', false), 'user'); // => ['pebbles']
+                     *  // using the `_.property` callback shorthand _.pluck(_.dropWhile(users,
+                     * 'active'), 'user'); // => ['barney', 'fred', 'pebbles']
+                     */
+                    function dropWhile(array, predicate, thisArg) {
+                        return (array && array.length) ? baseWhile(array, getCallback(predicate, thisArg, 3), true) : [];
+                    }
+
+                    /**
+                     * Fills elements of `array` with `value` from `start` up to, but not
+                     * including, `end`.
+                     * 
+                     * **Note:** This method mutates `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to fill.
+                     * @param {*}
+                     *            value The value to fill `array` with.
+                     * @param {number}
+                     *            [start=0] The start position.
+                     * @param {number}
+                     *            [end=array.length] The end position.
+                     * @returns {Array} Returns `array`.
+                     * @example
+                     * 
+                     * var array = [1, 2, 3];
+                     * 
+                     * _.fill(array, 'a'); console.log(array); // => ['a', 'a', 'a']
+                     * 
+                     * _.fill(Array(3), 2); // => [2, 2, 2]
+                     * 
+                     * _.fill([4, 6, 8], '*', 1, 2); // => [4, '*', 8]
+                     */
+                    function fill(array, value, start, end) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
+                            start = 0;
+                            end = length;
+                        }
+                        return baseFill(array, value, start, end);
+                    }
+
+                    /**
+                     * This method is like `_.find` except that it returns the index of the
+                     * first element `predicate` returns truthy for instead of the element
+                     * itself.
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {number} Returns the index of the found element, else `-1`.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': false }, { 'user': 'fred',
+                     * 'active': false }, { 'user': 'pebbles', 'active': true } ];
+                     * 
+                     * _.findIndex(users, function(chr) { return chr.user == 'barney'; }); // =>
+                     * 0
+                     *  // using the `_.matches` callback shorthand _.findIndex(users, { 'user':
+                     * 'fred', 'active': false }); // => 1
+                     *  // using the `_.matchesProperty` callback shorthand _.findIndex(users,
+                     * 'active', false); // => 0
+                     *  // using the `_.property` callback shorthand _.findIndex(users,
+                     * 'active'); // => 2
+                     */
+                    var findIndex = createFindIndex();
+
+                    /**
+                     * This method is like `_.findIndex` except that it iterates over elements
+                     * of `collection` from right to left.
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {number} Returns the index of the found element, else `-1`.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': true }, { 'user': 'fred',
+                     * 'active': false }, { 'user': 'pebbles', 'active': false } ];
+                     * 
+                     * _.findLastIndex(users, function(chr) { return chr.user == 'pebbles'; }); // =>
+                     * 2
+                     *  // using the `_.matches` callback shorthand _.findLastIndex(users, {
+                     * 'user': 'barney', 'active': true }); // => 0
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.findLastIndex(users, 'active', false); // => 2
+                     *  // using the `_.property` callback shorthand _.findLastIndex(users,
+                     * 'active'); // => 0
+                     */
+                    var findLastIndex = createFindIndex(true);
+
+                    /**
+                     * Gets the first element of `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias head
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @returns {*} Returns the first element of `array`.
+                     * @example
+                     * 
+                     * _.first([1, 2, 3]); // => 1
+                     * 
+                     * _.first([]); // => undefined
+                     */
+                    function first(array) {
+                        return array ? array[0] : undefined;
+                    }
+
+                    /**
+                     * Flattens a nested array. If `isDeep` is `true` the array is recursively
+                     * flattened, otherwise it is only flattened a single level.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to flatten.
+                     * @param {boolean}
+                     *            [isDeep] Specify a deep flatten.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the new flattened array.
+                     * @example
+                     * 
+                     * _.flatten([1, [2, 3, [4]]]); // => [1, 2, 3, [4]]
+                     *  // using `isDeep` _.flatten([1, [2, 3, [4]]], true); // => [1, 2, 3, 4]
+                     */
+                    function flatten(array, isDeep, guard) {
+                        var length = array ? array.length : 0;
+                        if (guard && isIterateeCall(array, isDeep, guard)) {
+                            isDeep = false;
+                        }
+                        return length ? baseFlatten(array, isDeep) : [];
+                    }
+
+                    /**
+                     * Recursively flattens a nested array.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to recursively flatten.
+                     * @returns {Array} Returns the new flattened array.
+                     * @example
+                     * 
+                     * _.flattenDeep([1, [2, 3, [4]]]); // => [1, 2, 3, 4]
+                     */
+                    function flattenDeep(array) {
+                        var length = array ? array.length : 0;
+                        return length ? baseFlatten(array, true) : [];
+                    }
+
+                    /**
+                     * Gets the index at which the first occurrence of `value` is found in
+                     * `array` using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons. If `fromIndex` is negative, it is used as the
+                     * offset from the end of `array`. If `array` is sorted providing `true` for
+                     * `fromIndex` performs a faster binary search.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to search.
+                     * @param {*}
+                     *            value The value to search for.
+                     * @param {boolean|number}
+                     *            [fromIndex=0] The index to search from or `true` to perform a
+                     *            binary search on a sorted array.
+                     * @returns {number} Returns the index of the matched value, else `-1`.
+                     * @example
+                     * 
+                     * _.indexOf([1, 2, 1, 2], 2); // => 1
+                     *  // using `fromIndex` _.indexOf([1, 2, 1, 2], 2, 2); // => 3
+                     *  // performing a binary search _.indexOf([1, 1, 2, 2], 2, true); // => 2
+                     */
+                    function indexOf(array, value, fromIndex) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return -1;
+                        }
+                        if (typeof fromIndex == 'number') {
+                            fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
+                        } else if (fromIndex) {
+                            var index = binaryIndex(array, value);
+                            if (index < length &&
+                                (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
+                                return index;
+                            }
+                            return -1;
+                        }
+                        return baseIndexOf(array, value, fromIndex || 0);
+                    }
+
+                    /**
+                     * Gets all but the last element of `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.initial([1, 2, 3]); // => [1, 2]
+                     */
+                    function initial(array) {
+                        return dropRight(array, 1);
+                    }
+
+                    /**
+                     * Creates an array of unique values that are included in all of the
+                     * provided arrays using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {...Array}
+                     *            [arrays] The arrays to inspect.
+                     * @returns {Array} Returns the new array of shared values.
+                     * @example _.intersection([1, 2], [4, 2], [2, 1]); // => [2]
+                     */
+                    var intersection = restParam(function(arrays) {
+                        var othLength = arrays.length,
+                            othIndex = othLength,
+                            caches = Array(length),
+                            indexOf = getIndexOf(),
+                            isCommon = indexOf == baseIndexOf,
+                            result = [];
+
+                        while (othIndex--) {
+                            var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : [];
+                            caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null;
+                        }
+                        var array = arrays[0],
+                            index = -1,
+                            length = array ? array.length : 0,
+                            seen = caches[0];
+
+                        outer:
+                            while (++index < length) {
+                                value = array[index];
+                                if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) {
+                                    var othIndex = othLength;
+                                    while (--othIndex) {
+                                        var cache = caches[othIndex];
+                                        if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) {
+                                            continue outer;
+                                        }
+                                    }
+                                    if (seen) {
+                                        seen.push(value);
+                                    }
+                                    result.push(value);
+                                }
+                            }
+                        return result;
+                    });
+
+                    /**
+                     * Gets the last element of `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @returns {*} Returns the last element of `array`.
+                     * @example
+                     * 
+                     * _.last([1, 2, 3]); // => 3
+                     */
+                    function last(array) {
+                        var length = array ? array.length : 0;
+                        return length ? array[length - 1] : undefined;
+                    }
+
+                    /**
+                     * This method is like `_.indexOf` except that it iterates over elements of
+                     * `array` from right to left.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to search.
+                     * @param {*}
+                     *            value The value to search for.
+                     * @param {boolean|number}
+                     *            [fromIndex=array.length-1] The index to search from or `true`
+                     *            to perform a binary search on a sorted array.
+                     * @returns {number} Returns the index of the matched value, else `-1`.
+                     * @example
+                     * 
+                     * _.lastIndexOf([1, 2, 1, 2], 2); // => 3
+                     *  // using `fromIndex` _.lastIndexOf([1, 2, 1, 2], 2, 2); // => 1
+                     *  // performing a binary search _.lastIndexOf([1, 1, 2, 2], 2, true); // =>
+                     * 3
+                     */
+                    function lastIndexOf(array, value, fromIndex) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return -1;
+                        }
+                        var index = length;
+                        if (typeof fromIndex == 'number') {
+                            index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1;
+                        } else if (fromIndex) {
+                            index = binaryIndex(array, value, true) - 1;
+                            var other = array[index];
+                            if (value === value ? (value === other) : (other !== other)) {
+                                return index;
+                            }
+                            return -1;
+                        }
+                        if (value !== value) {
+                            return indexOfNaN(array, index, true);
+                        }
+                        while (index--) {
+                            if (array[index] === value) {
+                                return index;
+                            }
+                        }
+                        return -1;
+                    }
+
+                    /**
+                     * Removes all provided values from `array` using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons.
+                     * 
+                     * **Note:** Unlike `_.without`, this method mutates `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to modify.
+                     * @param {...*}
+                     *            [values] The values to remove.
+                     * @returns {Array} Returns `array`.
+                     * @example
+                     * 
+                     * var array = [1, 2, 3, 1, 2, 3];
+                     * 
+                     * _.pull(array, 2, 3); console.log(array); // => [1, 1]
+                     */
+                    function pull() {
+                        var args = arguments,
+                            array = args[0];
+
+                        if (!(array && array.length)) {
+                            return array;
+                        }
+                        var index = 0,
+                            indexOf = getIndexOf(),
+                            length = args.length;
+
+                        while (++index < length) {
+                            var fromIndex = 0,
+                                value = args[index];
+
+                            while ((fromIndex = indexOf(array, value, fromIndex)) > -1) {
+                                splice.call(array, fromIndex, 1);
+                            }
+                        }
+                        return array;
+                    }
+
+                    /**
+                     * Removes elements from `array` corresponding to the given indexes and
+                     * returns an array of the removed elements. Indexes may be specified as an
+                     * array of indexes or as individual arguments.
+                     * 
+                     * **Note:** Unlike `_.at`, this method mutates `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to modify.
+                     * @param {...(number|number[])}
+                     *            [indexes] The indexes of elements to remove, specified as
+                     *            individual indexes or arrays of indexes.
+                     * @returns {Array} Returns the new array of removed elements.
+                     * @example
+                     * 
+                     * var array = [5, 10, 15, 20]; var evens = _.pullAt(array, 1, 3);
+                     * 
+                     * console.log(array); // => [5, 15]
+                     * 
+                     * console.log(evens); // => [10, 20]
+                     */
+                    var pullAt = restParam(function(array, indexes) {
+                        indexes = baseFlatten(indexes);
+
+                        var result = baseAt(array, indexes);
+                        basePullAt(array, indexes.sort(baseCompareAscending));
+                        return result;
+                    });
+
+                    /**
+                     * Removes all elements from `array` that `predicate` returns truthy for and
+                     * returns an array of the removed elements. The predicate is bound to
+                     * `thisArg` and invoked with three arguments: (value, index, array).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * **Note:** Unlike `_.filter`, this method mutates `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to modify.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the new array of removed elements.
+                     * @example
+                     * 
+                     * var array = [1, 2, 3, 4]; var evens = _.remove(array, function(n) {
+                     * return n % 2 == 0; });
+                     * 
+                     * console.log(array); // => [1, 3]
+                     * 
+                     * console.log(evens); // => [2, 4]
+                     */
+                    function remove(array, predicate, thisArg) {
+                        var result = [];
+                        if (!(array && array.length)) {
+                            return result;
+                        }
+                        var index = -1,
+                            indexes = [],
+                            length = array.length;
+
+                        predicate = getCallback(predicate, thisArg, 3);
+                        while (++index < length) {
+                            var value = array[index];
+                            if (predicate(value, index, array)) {
+                                result.push(value);
+                                indexes.push(index);
+                            }
+                        }
+                        basePullAt(array, indexes);
+                        return result;
+                    }
+
+                    /**
+                     * Gets all but the first element of `array`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias tail
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.rest([1, 2, 3]); // => [2, 3]
+                     */
+                    function rest(array) {
+                        return drop(array, 1);
+                    }
+
+                    /**
+                     * Creates a slice of `array` from `start` up to, but not including, `end`.
+                     * 
+                     * **Note:** This method is used instead of `Array#slice` to support node
+                     * lists in IE < 9 and to ensure dense arrays are returned.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to slice.
+                     * @param {number}
+                     *            [start=0] The start position.
+                     * @param {number}
+                     *            [end=array.length] The end position.
+                     * @returns {Array} Returns the slice of `array`.
+                     */
+                    function slice(array, start, end) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
+                            start = 0;
+                            end = length;
+                        }
+                        return baseSlice(array, start, end);
+                    }
+
+                    /**
+                     * Uses a binary search to determine the lowest index at which `value`
+                     * should be inserted into `array` in order to maintain its sort order. If
+                     * an iteratee function is provided it is invoked for `value` and each
+                     * element of `array` to compute their sort ranking. The iteratee is bound
+                     * to `thisArg` and invoked with one argument; (value).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The sorted array to inspect.
+                     * @param {*}
+                     *            value The value to evaluate.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {number} Returns the index at which `value` should be inserted
+                     *          into `array`.
+                     * @example
+                     * 
+                     * _.sortedIndex([30, 50], 40); // => 1
+                     * 
+                     * _.sortedIndex([4, 4, 5, 5], 5); // => 2
+                     * 
+                     * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } };
+                     *  // using an iteratee function _.sortedIndex(['thirty', 'fifty'],
+                     * 'forty', function(word) { return this.data[word]; }, dict); // => 1
+                     *  // using the `_.property` callback shorthand _.sortedIndex([{ 'x': 30 }, {
+                     * 'x': 50 }], { 'x': 40 }, 'x'); // => 1
+                     */
+                    var sortedIndex = createSortedIndex();
+
+                    /**
+                     * This method is like `_.sortedIndex` except that it returns the highest
+                     * index at which `value` should be inserted into `array` in order to
+                     * maintain its sort order.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The sorted array to inspect.
+                     * @param {*}
+                     *            value The value to evaluate.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {number} Returns the index at which `value` should be inserted
+                     *          into `array`.
+                     * @example
+                     * 
+                     * _.sortedLastIndex([4, 4, 5, 5], 5); // => 4
+                     */
+                    var sortedLastIndex = createSortedIndex(true);
+
+                    /**
+                     * Creates a slice of `array` with `n` elements taken from the beginning.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {number}
+                     *            [n=1] The number of elements to take.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.take([1, 2, 3]); // => [1]
+                     * 
+                     * _.take([1, 2, 3], 2); // => [1, 2]
+                     * 
+                     * _.take([1, 2, 3], 5); // => [1, 2, 3]
+                     * 
+                     * _.take([1, 2, 3], 0); // => []
+                     */
+                    function take(array, n, guard) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (guard ? isIterateeCall(array, n, guard) : n == null) {
+                            n = 1;
+                        }
+                        return baseSlice(array, 0, n < 0 ? 0 : n);
+                    }
+
+                    /**
+                     * Creates a slice of `array` with `n` elements taken from the end.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {number}
+                     *            [n=1] The number of elements to take.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.takeRight([1, 2, 3]); // => [3]
+                     * 
+                     * _.takeRight([1, 2, 3], 2); // => [2, 3]
+                     * 
+                     * _.takeRight([1, 2, 3], 5); // => [1, 2, 3]
+                     * 
+                     * _.takeRight([1, 2, 3], 0); // => []
+                     */
+                    function takeRight(array, n, guard) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (guard ? isIterateeCall(array, n, guard) : n == null) {
+                            n = 1;
+                        }
+                        n = length - (+n || 0);
+                        return baseSlice(array, n < 0 ? 0 : n);
+                    }
+
+                    /**
+                     * Creates a slice of `array` with elements taken from the end. Elements are
+                     * taken until `predicate` returns falsey. The predicate is bound to
+                     * `thisArg` and invoked with three arguments: (value, index, array).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.takeRightWhile([1, 2, 3], function(n) { return n > 1; }); // => [2, 3]
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': true }, { 'user': 'fred',
+                     * 'active': false }, { 'user': 'pebbles', 'active': false } ];
+                     *  // using the `_.matches` callback shorthand
+                     * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }),
+                     * 'user'); // => ['pebbles']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); // => ['fred',
+                     * 'pebbles']
+                     *  // using the `_.property` callback shorthand
+                     * _.pluck(_.takeRightWhile(users, 'active'), 'user'); // => []
+                     */
+                    function takeRightWhile(array, predicate, thisArg) {
+                        return (array && array.length) ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) : [];
+                    }
+
+                    /**
+                     * Creates a slice of `array` with elements taken from the beginning.
+                     * Elements are taken until `predicate` returns falsey. The predicate is
+                     * bound to `thisArg` and invoked with three arguments: (value, index,
+                     * array).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to query.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the slice of `array`.
+                     * @example
+                     * 
+                     * _.takeWhile([1, 2, 3], function(n) { return n < 3; }); // => [1, 2]
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': false }, { 'user': 'fred',
+                     * 'active': false}, { 'user': 'pebbles', 'active': true } ];
+                     *  // using the `_.matches` callback shorthand _.pluck(_.takeWhile(users, {
+                     * 'user': 'barney', 'active': false }), 'user'); // => ['barney']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.takeWhile(users, 'active', false), 'user'); // => ['barney',
+                     * 'fred']
+                     *  // using the `_.property` callback shorthand _.pluck(_.takeWhile(users,
+                     * 'active'), 'user'); // => []
+                     */
+                    function takeWhile(array, predicate, thisArg) {
+                        return (array && array.length) ? baseWhile(array, getCallback(predicate, thisArg, 3)) : [];
+                    }
+
+                    /**
+                     * Creates an array of unique values, in order, from all of the provided
+                     * arrays using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {...Array}
+                     *            [arrays] The arrays to inspect.
+                     * @returns {Array} Returns the new array of combined values.
+                     * @example
+                     * 
+                     * _.union([1, 2], [4, 2], [2, 1]); // => [1, 2, 4]
+                     */
+                    var union = restParam(function(arrays) {
+                        return baseUniq(baseFlatten(arrays, false, true));
+                    });
+
+                    /**
+                     * Creates a duplicate-free version of an array, using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons, in which only the first occurence of each
+                     * element is kept. Providing `true` for `isSorted` performs a faster search
+                     * algorithm for sorted arrays. If an iteratee function is provided it is
+                     * invoked for each element in the array to generate the criterion by which
+                     * uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked
+                     * with three arguments: (value, index, array).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias unique
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to inspect.
+                     * @param {boolean}
+                     *            [isSorted] Specify the array is sorted.
+                     * @param {Function|Object|string}
+                     *            [iteratee] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the new duplicate-value-free array.
+                     * @example
+                     * 
+                     * _.uniq([2, 1, 2]); // => [2, 1]
+                     *  // using `isSorted` _.uniq([1, 1, 2], true); // => [1, 2]
+                     *  // using an iteratee function _.uniq([1, 2.5, 1.5, 2], function(n) {
+                     * return this.floor(n); }, Math); // => [1, 2.5]
+                     *  // using the `_.property` callback shorthand _.uniq([{ 'x': 1 }, { 'x':
+                     * 2 }, { 'x': 1 }], 'x'); // => [{ 'x': 1 }, { 'x': 2 }]
+                     */
+                    function uniq(array, isSorted, iteratee, thisArg) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        if (isSorted != null && typeof isSorted != 'boolean') {
+                            thisArg = iteratee;
+                            iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted;
+                            isSorted = false;
+                        }
+                        var callback = getCallback();
+                        if (!(iteratee == null && callback === baseCallback)) {
+                            iteratee = callback(iteratee, thisArg, 3);
+                        }
+                        return (isSorted && getIndexOf() == baseIndexOf) ? sortedUniq(array, iteratee) : baseUniq(array, iteratee);
+                    }
+
+                    /**
+                     * This method is like `_.zip` except that it accepts an array of grouped
+                     * elements and creates an array regrouping the elements to their pre-zip
+                     * configuration.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array of grouped elements to process.
+                     * @returns {Array} Returns the new array of regrouped elements.
+                     * @example
+                     * 
+                     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); // =>
+                     * [['fred', 30, true], ['barney', 40, false]]
+                     * 
+                     * _.unzip(zipped); // => [['fred', 'barney'], [30, 40], [true, false]]
+                     */
+                    function unzip(array) {
+                        if (!(array && array.length)) {
+                            return [];
+                        }
+                        var index = -1,
+                            length = 0;
+
+                        array = arrayFilter(array, function(group) {
+                            if (isArrayLike(group)) {
+                                length = nativeMax(group.length, length);
+                                return true;
+                            }
+                        });
+                        var result = Array(length);
+                        while (++index < length) {
+                            result[index] = arrayMap(array, baseProperty(index));
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * This method is like `_.unzip` except that it accepts an iteratee to
+                     * specify how regrouped values should be combined. The `iteratee` is bound
+                     * to `thisArg` and invoked with four arguments: (accumulator, value, index,
+                     * group).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array of grouped elements to process.
+                     * @param {Function}
+                     *            [iteratee] The function to combine regrouped values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the new array of regrouped elements.
+                     * @example
+                     * 
+                     * var zipped = _.zip([1, 2], [10, 20], [100, 200]); // => [[1, 10, 100],
+                     * [2, 20, 200]]
+                     * 
+                     * _.unzipWith(zipped, _.add); // => [3, 30, 300]
+                     */
+                    function unzipWith(array, iteratee, thisArg) {
+                        var length = array ? array.length : 0;
+                        if (!length) {
+                            return [];
+                        }
+                        var result = unzip(array);
+                        if (iteratee == null) {
+                            return result;
+                        }
+                        iteratee = bindCallback(iteratee, thisArg, 4);
+                        return arrayMap(result, function(group) {
+                            return arrayReduce(group, iteratee, undefined, true);
+                        });
+                    }
+
+                    /**
+                     * Creates an array excluding all provided values using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {Array}
+                     *            array The array to filter.
+                     * @param {...*}
+                     *            [values] The values to exclude.
+                     * @returns {Array} Returns the new array of filtered values.
+                     * @example
+                     * 
+                     * _.without([1, 2, 1, 3], 1, 2); // => [3]
+                     */
+                    var without = restParam(function(array, values) {
+                        return isArrayLike(array) ? baseDifference(array, values) : [];
+                    });
+
+                    /**
+                     * Creates an array of unique values that is the [symmetric
+                     * difference](https://en.wikipedia.org/wiki/Symmetric_difference) of the
+                     * provided arrays.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {...Array}
+                     *            [arrays] The arrays to inspect.
+                     * @returns {Array} Returns the new array of values.
+                     * @example
+                     * 
+                     * _.xor([1, 2], [4, 2]); // => [1, 4]
+                     */
+                    function xor() {
+                        var index = -1,
+                            length = arguments.length;
+
+                        while (++index < length) {
+                            var array = arguments[index];
+                            if (isArrayLike(array)) {
+                                var result = result ? arrayPush(baseDifference(result, array), baseDifference(array, result)) : array;
+                            }
+                        }
+                        return result ? baseUniq(result) : [];
+                    }
+
+                    /**
+                     * Creates an array of grouped elements, the first of which contains the
+                     * first elements of the given arrays, the second of which contains the
+                     * second elements of the given arrays, and so on.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {...Array}
+                     *            [arrays] The arrays to process.
+                     * @returns {Array} Returns the new array of grouped elements.
+                     * @example
+                     * 
+                     * _.zip(['fred', 'barney'], [30, 40], [true, false]); // => [['fred', 30,
+                     * true], ['barney', 40, false]]
+                     */
+                    var zip = restParam(unzip);
+
+                    /**
+                     * The inverse of `_.pairs`; this method returns an object composed from
+                     * arrays of property names and values. Provide either a single two
+                     * dimensional array, e.g. `[[key1, value1], [key2, value2]]` or two arrays,
+                     * one of property names and one of corresponding values.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias object
+                     * @category Array
+                     * @param {Array}
+                     *            props The property names.
+                     * @param {Array}
+                     *            [values=[]] The property values.
+                     * @returns {Object} Returns the new object.
+                     * @example
+                     * 
+                     * _.zipObject([['fred', 30], ['barney', 40]]); // => { 'fred': 30,
+                     * 'barney': 40 }
+                     * 
+                     * _.zipObject(['fred', 'barney'], [30, 40]); // => { 'fred': 30, 'barney':
+                     * 40 }
+                     */
+                    function zipObject(props, values) {
+                        var index = -1,
+                            length = props ? props.length : 0,
+                            result = {};
+
+                        if (length && !values && !isArray(props[0])) {
+                            values = [];
+                        }
+                        while (++index < length) {
+                            var key = props[index];
+                            if (values) {
+                                result[key] = values[index];
+                            } else if (key) {
+                                result[key[0]] = key[1];
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * This method is like `_.zip` except that it accepts an iteratee to specify
+                     * how grouped values should be combined. The `iteratee` is bound to
+                     * `thisArg` and invoked with four arguments: (accumulator, value, index,
+                     * group).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Array
+                     * @param {...Array}
+                     *            [arrays] The arrays to process.
+                     * @param {Function}
+                     *            [iteratee] The function to combine grouped values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the new array of grouped elements.
+                     * @example
+                     * 
+                     * _.zipWith([1, 2], [10, 20], [100, 200], _.add); // => [111, 222]
+                     */
+                    var zipWith = restParam(function(arrays) {
+                        var length = arrays.length,
+                            iteratee = length > 2 ? arrays[length - 2] : undefined,
+                            thisArg = length > 1 ? arrays[length - 1] : undefined;
+
+                        if (length > 2 && typeof iteratee == 'function') {
+                            length -= 2;
+                        } else {
+                            iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined;
+                            thisArg = undefined;
+                        }
+                        arrays.length = length;
+                        return unzipWith(arrays, iteratee, thisArg);
+                    });
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a `lodash` object that wraps `value` with explicit method
+                     * chaining enabled.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Chain
+                     * @param {*}
+                     *            value The value to wrap.
+                     * @returns {Object} Returns the new `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 }, { 'user': 'pebbles', 'age': 1 } ];
+                     * 
+                     * var youngest = _.chain(users) .sortBy('age') .map(function(chr) { return
+                     * chr.user + ' is ' + chr.age; }) .first() .value(); // => 'pebbles is 1'
+                     */
+                    function chain(value) {
+                        var result = lodash(value);
+                        result.__chain__ = true;
+                        return result;
+                    }
+
+                    /**
+                     * This method invokes `interceptor` and returns `value`. The interceptor is
+                     * bound to `thisArg` and invoked with one argument; (value). The purpose of
+                     * this method is to "tap into" a method chain in order to perform
+                     * operations on intermediate results within the chain.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Chain
+                     * @param {*}
+                     *            value The value to provide to `interceptor`.
+                     * @param {Function}
+                     *            interceptor The function to invoke.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `interceptor`.
+                     * @returns {*} Returns `value`.
+                     * @example
+                     * 
+                     * _([1, 2, 3]) .tap(function(array) { array.pop(); }) .reverse() .value(); // =>
+                     * [2, 1]
+                     */
+                    function tap(value, interceptor, thisArg) {
+                        interceptor.call(thisArg, value);
+                        return value;
+                    }
+
+                    /**
+                     * This method is like `_.tap` except that it returns the result of
+                     * `interceptor`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Chain
+                     * @param {*}
+                     *            value The value to provide to `interceptor`.
+                     * @param {Function}
+                     *            interceptor The function to invoke.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `interceptor`.
+                     * @returns {*} Returns the result of `interceptor`.
+                     * @example
+                     * 
+                     * _(' abc ') .chain() .trim() .thru(function(value) { return [value]; })
+                     * .value(); // => ['abc']
+                     */
+                    function thru(value, interceptor, thisArg) {
+                        return interceptor.call(thisArg, value);
+                    }
+
+                    /**
+                     * Enables explicit method chaining on the wrapper object.
+                     * 
+                     * @name chain
+                     * @memberOf _
+                     * @category Chain
+                     * @returns {Object} Returns the new `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 } ];
+                     *  // without explicit chaining _(users).first(); // => { 'user': 'barney',
+                     * 'age': 36 }
+                     *  // with explicit chaining _(users).chain() .first() .pick('user')
+                     * .value(); // => { 'user': 'barney' }
+                     */
+                    function wrapperChain() {
+                        return chain(this);
+                    }
+
+                    /**
+                     * Executes the chained sequence and returns the wrapped result.
+                     * 
+                     * @name commit
+                     * @memberOf _
+                     * @category Chain
+                     * @returns {Object} Returns the new `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var array = [1, 2]; var wrapped = _(array).push(3);
+                     * 
+                     * console.log(array); // => [1, 2]
+                     * 
+                     * wrapped = wrapped.commit(); console.log(array); // => [1, 2, 3]
+                     * 
+                     * wrapped.last(); // => 3
+                     * 
+                     * console.log(array); // => [1, 2, 3]
+                     */
+                    function wrapperCommit() {
+                        return new LodashWrapper(this.value(), this.__chain__);
+                    }
+
+                    /**
+                     * Creates a new array joining a wrapped array with any additional arrays
+                     * and/or values.
+                     * 
+                     * @name concat
+                     * @memberOf _
+                     * @category Chain
+                     * @param {...*}
+                     *            [values] The values to concatenate.
+                     * @returns {Array} Returns the new concatenated array.
+                     * @example
+                     * 
+                     * var array = [1]; var wrapped = _(array).concat(2, [3], [[4]]);
+                     * 
+                     * console.log(wrapped.value()); // => [1, 2, 3, [4]]
+                     * 
+                     * console.log(array); // => [1]
+                     */
+                    var wrapperConcat = restParam(function(values) {
+                        values = baseFlatten(values);
+                        return this.thru(function(array) {
+                            return arrayConcat(isArray(array) ? array : [toObject(array)], values);
+                        });
+                    });
+
+                    /**
+                     * Creates a clone of the chained sequence planting `value` as the wrapped
+                     * value.
+                     * 
+                     * @name plant
+                     * @memberOf _
+                     * @category Chain
+                     * @returns {Object} Returns the new `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var array = [1, 2]; var wrapped = _(array).map(function(value) { return
+                     * Math.pow(value, 2); });
+                     * 
+                     * var other = [3, 4]; var otherWrapped = wrapped.plant(other);
+                     * 
+                     * otherWrapped.value(); // => [9, 16]
+                     * 
+                     * wrapped.value(); // => [1, 4]
+                     */
+                    function wrapperPlant(value) {
+                        var result,
+                            parent = this;
+
+                        while (parent instanceof baseLodash) {
+                            var clone = wrapperClone(parent);
+                            if (result) {
+                                previous.__wrapped__ = clone;
+                            } else {
+                                result = clone;
+                            }
+                            var previous = clone;
+                            parent = parent.__wrapped__;
+                        }
+                        previous.__wrapped__ = value;
+                        return result;
+                    }
+
+                    /**
+                     * Reverses the wrapped array so the first element becomes the last, the
+                     * second element becomes the second to last, and so on.
+                     * 
+                     * **Note:** This method mutates the wrapped array.
+                     * 
+                     * @name reverse
+                     * @memberOf _
+                     * @category Chain
+                     * @returns {Object} Returns the new reversed `lodash` wrapper instance.
+                     * @example
+                     * 
+                     * var array = [1, 2, 3];
+                     * 
+                     * _(array).reverse().value() // => [3, 2, 1]
+                     * 
+                     * console.log(array); // => [3, 2, 1]
+                     */
+                    function wrapperReverse() {
+                        var value = this.__wrapped__;
+
+                        var interceptor = function(value) {
+                            return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse();
+                        };
+                        if (value instanceof LazyWrapper) {
+                            var wrapped = value;
+                            if (this.__actions__.length) {
+                                wrapped = new LazyWrapper(this);
+                            }
+                            wrapped = wrapped.reverse();
+                            wrapped.__actions__.push({
+                                'func': thru,
+                                'args': [interceptor],
+                                'thisArg': undefined
+                            });
+                            return new LodashWrapper(wrapped, this.__chain__);
+                        }
+                        return this.thru(interceptor);
+                    }
+
+                    /**
+                     * Produces the result of coercing the unwrapped value to a string.
+                     * 
+                     * @name toString
+                     * @memberOf _
+                     * @category Chain
+                     * @returns {string} Returns the coerced string value.
+                     * @example
+                     * 
+                     * _([1, 2, 3]).toString(); // => '1,2,3'
+                     */
+                    function wrapperToString() {
+                        return (this.value() + '');
+                    }
+
+                    /**
+                     * Executes the chained sequence to extract the unwrapped value.
+                     * 
+                     * @name value
+                     * @memberOf _
+                     * @alias run, toJSON, valueOf
+                     * @category Chain
+                     * @returns {*} Returns the resolved unwrapped value.
+                     * @example
+                     * 
+                     * _([1, 2, 3]).value(); // => [1, 2, 3]
+                     */
+                    function wrapperValue() {
+                        return baseWrapperValue(this.__wrapped__, this.__actions__);
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates an array of elements corresponding to the given keys, or indexes,
+                     * of `collection`. Keys may be specified as individual arguments or as
+                     * arrays of keys.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {...(number|number[]|string|string[])}
+                     *            [props] The property names or indexes of elements to pick,
+                     *            specified individually or in arrays.
+                     * @returns {Array} Returns the new array of picked elements.
+                     * @example
+                     * 
+                     * _.at(['a', 'b', 'c'], [0, 2]); // => ['a', 'c']
+                     * 
+                     * _.at(['barney', 'fred', 'pebbles'], 0, 2); // => ['barney', 'pebbles']
+                     */
+                    var at = restParam(function(collection, props) {
+                        return baseAt(collection, baseFlatten(props));
+                    });
+
+                    /**
+                     * Creates an object composed of keys generated from the results of running
+                     * each element of `collection` through `iteratee`. The corresponding value
+                     * of each key is the number of times the key was returned by `iteratee`.
+                     * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+                     * (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns the composed aggregate object.
+                     * @example
+                     * 
+                     * _.countBy([4.3, 6.1, 6.4], function(n) { return Math.floor(n); }); // => {
+                     * '4': 1, '6': 2 }
+                     * 
+                     * _.countBy([4.3, 6.1, 6.4], function(n) { return this.floor(n); }, Math); // => {
+                     * '4': 1, '6': 2 }
+                     * 
+                     * _.countBy(['one', 'two', 'three'], 'length'); // => { '3': 2, '5': 1 }
+                     */
+                    var countBy = createAggregator(function(result, value, key) {
+                        hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
+                    });
+
+                    /**
+                     * Checks if `predicate` returns truthy for **all** elements of
+                     * `collection`. The predicate is bound to `thisArg` and invoked with three
+                     * arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias all
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {boolean} Returns `true` if all elements pass the predicate
+                     *          check, else `false`.
+                     * @example
+                     * 
+                     * _.every([true, 1, null, 'yes'], Boolean); // => false
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': false }, { 'user': 'fred',
+                     * 'active': false } ];
+                     *  // using the `_.matches` callback shorthand _.every(users, { 'user':
+                     * 'barney', 'active': false }); // => false
+                     *  // using the `_.matchesProperty` callback shorthand _.every(users,
+                     * 'active', false); // => true
+                     *  // using the `_.property` callback shorthand _.every(users, 'active'); // =>
+                     * false
+                     */
+                    function every(collection, predicate, thisArg) {
+                        var func = isArray(collection) ? arrayEvery : baseEvery;
+                        if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+                            predicate = undefined;
+                        }
+                        if (typeof predicate != 'function' || thisArg !== undefined) {
+                            predicate = getCallback(predicate, thisArg, 3);
+                        }
+                        return func(collection, predicate);
+                    }
+
+                    /**
+                     * Iterates over elements of `collection`, returning an array of all
+                     * elements `predicate` returns truthy for. The predicate is bound to
+                     * `thisArg` and invoked with three arguments: (value, index|key,
+                     * collection).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias select
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the new filtered array.
+                     * @example
+                     * 
+                     * _.filter([4, 5, 6], function(n) { return n % 2 == 0; }); // => [4, 6]
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+                     * 'fred', 'age': 40, 'active': false } ];
+                     *  // using the `_.matches` callback shorthand _.pluck(_.filter(users, {
+                     * 'age': 36, 'active': true }), 'user'); // => ['barney']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.filter(users, 'active', false), 'user'); // => ['fred']
+                     *  // using the `_.property` callback shorthand _.pluck(_.filter(users,
+                     * 'active'), 'user'); // => ['barney']
+                     */
+                    function filter(collection, predicate, thisArg) {
+                        var func = isArray(collection) ? arrayFilter : baseFilter;
+                        predicate = getCallback(predicate, thisArg, 3);
+                        return func(collection, predicate);
+                    }
+
+                    /**
+                     * Iterates over elements of `collection`, returning the first element
+                     * `predicate` returns truthy for. The predicate is bound to `thisArg` and
+                     * invoked with three arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias detect
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {*} Returns the matched element, else `undefined`.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+                     * 'fred', 'age': 40, 'active': false }, { 'user': 'pebbles', 'age': 1,
+                     * 'active': true } ];
+                     * 
+                     * _.result(_.find(users, function(chr) { return chr.age < 40; }), 'user'); // =>
+                     * 'barney'
+                     *  // using the `_.matches` callback shorthand _.result(_.find(users, {
+                     * 'age': 1, 'active': true }), 'user'); // => 'pebbles'
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.result(_.find(users, 'active', false), 'user'); // => 'fred'
+                     *  // using the `_.property` callback shorthand _.result(_.find(users,
+                     * 'active'), 'user'); // => 'barney'
+                     */
+                    var find = createFind(baseEach);
+
+                    /**
+                     * This method is like `_.find` except that it iterates over elements of
+                     * `collection` from right to left.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {*} Returns the matched element, else `undefined`.
+                     * @example
+                     * 
+                     * _.findLast([1, 2, 3, 4], function(n) { return n % 2 == 1; }); // => 3
+                     */
+                    var findLast = createFind(baseEachRight, true);
+
+                    /**
+                     * Performs a deep comparison between each element in `collection` and the
+                     * source object, returning the first element that has equivalent property
+                     * values.
+                     * 
+                     * **Note:** This method supports comparing arrays, booleans, `Date`
+                     * objects, numbers, `Object` objects, regexes, and strings. Objects are
+                     * compared by their own, not inherited, enumerable properties. For
+                     * comparing a single own or inherited property value see
+                     * `_.matchesProperty`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {Object}
+                     *            source The object of property values to match.
+                     * @returns {*} Returns the matched element, else `undefined`.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+                     * 'fred', 'age': 40, 'active': false } ];
+                     * 
+                     * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); // =>
+                     * 'barney'
+                     * 
+                     * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); // =>
+                     * 'fred'
+                     */
+                    function findWhere(collection, source) {
+                        return find(collection, baseMatches(source));
+                    }
+
+                    /**
+                     * Iterates over elements of `collection` invoking `iteratee` for each
+                     * element. The `iteratee` is bound to `thisArg` and invoked with three
+                     * arguments: (value, index|key, collection). Iteratee functions may exit
+                     * iteration early by explicitly returning `false`.
+                     * 
+                     * **Note:** As with other "Collections" methods, objects with a "length"
+                     * property are iterated like arrays. To avoid this behavior `_.forIn` or
+                     * `_.forOwn` may be used for object iteration.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias each
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array|Object|string} Returns `collection`.
+                     * @example
+                     * 
+                     * _([1, 2]).forEach(function(n) { console.log(n); }).value(); // => logs
+                     * each value from left to right and returns the array
+                     * 
+                     * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { console.log(n, key); }); // =>
+                     * logs each value-key pair and returns the object (iteration order is not
+                     * guaranteed)
+                     */
+                    var forEach = createForEach(arrayEach, baseEach);
+
+                    /**
+                     * This method is like `_.forEach` except that it iterates over elements of
+                     * `collection` from right to left.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias eachRight
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array|Object|string} Returns `collection`.
+                     * @example
+                     * 
+                     * _([1, 2]).forEachRight(function(n) { console.log(n); }).value(); // =>
+                     * logs each value from right to left and returns the array
+                     */
+                    var forEachRight = createForEach(arrayEachRight, baseEachRight);
+
+                    /**
+                     * Creates an object composed of keys generated from the results of running
+                     * each element of `collection` through `iteratee`. The corresponding value
+                     * of each key is an array of the elements responsible for generating the
+                     * key. The `iteratee` is bound to `thisArg` and invoked with three
+                     * arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns the composed aggregate object.
+                     * @example
+                     * 
+                     * _.groupBy([4.2, 6.1, 6.4], function(n) { return Math.floor(n); }); // => {
+                     * '4': [4.2], '6': [6.1, 6.4] }
+                     * 
+                     * _.groupBy([4.2, 6.1, 6.4], function(n) { return this.floor(n); }, Math); // => {
+                     * '4': [4.2], '6': [6.1, 6.4] }
+                     *  // using the `_.property` callback shorthand _.groupBy(['one', 'two',
+                     * 'three'], 'length'); // => { '3': ['one', 'two'], '5': ['three'] }
+                     */
+                    var groupBy = createAggregator(function(result, value, key) {
+                        if (hasOwnProperty.call(result, key)) {
+                            result[key].push(value);
+                        } else {
+                            result[key] = [value];
+                        }
+                    });
+
+                    /**
+                     * Checks if `value` is in `collection` using
+                     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+                     * for equality comparisons. If `fromIndex` is negative, it is used as the
+                     * offset from the end of `collection`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias contains, include
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {*}
+                     *            target The value to search for.
+                     * @param {number}
+                     *            [fromIndex=0] The index to search from.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.reduce`.
+                     * @returns {boolean} Returns `true` if a matching element is found, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.includes([1, 2, 3], 1); // => true
+                     * 
+                     * _.includes([1, 2, 3], 1, 2); // => false
+                     * 
+                     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); // => true
+                     * 
+                     * _.includes('pebbles', 'eb'); // => true
+                     */
+                    function includes(collection, target, fromIndex, guard) {
+                        var length = collection ? getLength(collection) : 0;
+                        if (!isLength(length)) {
+                            collection = values(collection);
+                            length = collection.length;
+                        }
+                        if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
+                            fromIndex = 0;
+                        } else {
+                            fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
+                        }
+                        return (typeof collection == 'string' || !isArray(collection) && isString(collection)) ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) : (!!length && getIndexOf(collection, target, fromIndex) > -1);
+                    }
+
+                    /**
+                     * Creates an object composed of keys generated from the results of running
+                     * each element of `collection` through `iteratee`. The corresponding value
+                     * of each key is the last element responsible for generating the key. The
+                     * iteratee function is bound to `thisArg` and invoked with three arguments:
+                     * (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns the composed aggregate object.
+                     * @example
+                     * 
+                     * var keyData = [ { 'dir': 'left', 'code': 97 }, { 'dir': 'right', 'code':
+                     * 100 } ];
+                     * 
+                     * _.indexBy(keyData, 'dir'); // => { 'left': { 'dir': 'left', 'code': 97 },
+                     * 'right': { 'dir': 'right', 'code': 100 } }
+                     * 
+                     * _.indexBy(keyData, function(object) { return
+                     * String.fromCharCode(object.code); }); // => { 'a': { 'dir': 'left',
+                     * 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+                     * 
+                     * _.indexBy(keyData, function(object) { return
+                     * this.fromCharCode(object.code); }, String); // => { 'a': { 'dir': 'left',
+                     * 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+                     */
+                    var indexBy = createAggregator(function(result, value, key) {
+                        result[key] = value;
+                    });
+
+                    /**
+                     * Invokes the method at `path` of each element in `collection`, returning
+                     * an array of the results of each invoked method. Any additional arguments
+                     * are provided to each invoked method. If `methodName` is a function it is
+                     * invoked for, and `this` bound to, each element in `collection`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Array|Function|string}
+                     *            path The path of the method to invoke or the function invoked
+                     *            per iteration.
+                     * @param {...*}
+                     *            [args] The arguments to invoke the method with.
+                     * @returns {Array} Returns the array of results.
+                     * @example
+                     * 
+                     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); // => [[1, 5, 7], [1, 2, 3]]
+                     * 
+                     * _.invoke([123, 456], String.prototype.split, ''); // => [['1', '2', '3'],
+                     * ['4', '5', '6']]
+                     */
+                    var invoke = restParam(function(collection, path, args) {
+                        var index = -1,
+                            isFunc = typeof path == 'function',
+                            isProp = isKey(path),
+                            result = isArrayLike(collection) ? Array(collection.length) : [];
+
+                        baseEach(collection, function(value) {
+                            var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
+                            result[++index] = func ? func.apply(value, args) : invokePath(value, path, args);
+                        });
+                        return result;
+                    });
+
+                    /**
+                     * Creates an array of values by running each element in `collection`
+                     * through `iteratee`. The `iteratee` is bound to `thisArg` and invoked with
+                     * three arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * Many lodash methods are guarded to work as iteratees for methods like
+                     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+                     * 
+                     * The guarded methods are: `ary`, `callback`, `chunk`, `clone`, `create`,
+                     * `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, `flatten`,
+                     * `invert`, `max`, `min`, `parseInt`, `slice`, `sortBy`, `take`,
+                     * `takeRight`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+                     * `random`, `range`, `sample`, `some`, `sum`, `uniq`, and `words`
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias collect
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the new mapped array.
+                     * @example
+                     * 
+                     * function timesThree(n) { return n * 3; }
+                     * 
+                     * _.map([1, 2], timesThree); // => [3, 6]
+                     * 
+                     * _.map({ 'a': 1, 'b': 2 }, timesThree); // => [3, 6] (iteration order is
+                     * not guaranteed)
+                     * 
+                     * var users = [ { 'user': 'barney' }, { 'user': 'fred' } ];
+                     *  // using the `_.property` callback shorthand _.map(users, 'user'); // =>
+                     * ['barney', 'fred']
+                     */
+                    function map(collection, iteratee, thisArg) {
+                        var func = isArray(collection) ? arrayMap : baseMap;
+                        iteratee = getCallback(iteratee, thisArg, 3);
+                        return func(collection, iteratee);
+                    }
+
+                    /**
+                     * Creates an array of elements split into two groups, the first of which
+                     * contains elements `predicate` returns truthy for, while the second of
+                     * which contains elements `predicate` returns falsey for. The predicate is
+                     * bound to `thisArg` and invoked with three arguments: (value, index|key,
+                     * collection).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the array of grouped elements.
+                     * @example
+                     * 
+                     * _.partition([1, 2, 3], function(n) { return n % 2; }); // => [[1, 3],
+                     * [2]]
+                     * 
+                     * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; },
+                     * Math); // => [[1.2, 3.4], [2.3]]
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': false }, { 'user':
+                     * 'fred', 'age': 40, 'active': true }, { 'user': 'pebbles', 'age': 1,
+                     * 'active': false } ];
+                     * 
+                     * var mapper = function(array) { return _.pluck(array, 'user'); };
+                     *  // using the `_.matches` callback shorthand _.map(_.partition(users, {
+                     * 'age': 1, 'active': false }), mapper); // => [['pebbles'], ['barney',
+                     * 'fred']]
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.map(_.partition(users, 'active', false), mapper); // => [['barney',
+                     * 'pebbles'], ['fred']]
+                     *  // using the `_.property` callback shorthand _.map(_.partition(users,
+                     * 'active'), mapper); // => [['fred'], ['barney', 'pebbles']]
+                     */
+                    var partition = createAggregator(function(result, value, key) {
+                        result[key ? 0 : 1].push(value);
+                    }, function() {
+                        return [
+                            [],
+                            []
+                        ];
+                    });
+
+                    /**
+                     * Gets the property value of `path` from all elements in `collection`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Array|string}
+                     *            path The path of the property to pluck.
+                     * @returns {Array} Returns the property values.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 } ];
+                     * 
+                     * _.pluck(users, 'user'); // => ['barney', 'fred']
+                     * 
+                     * var userIndex = _.indexBy(users, 'user'); _.pluck(userIndex, 'age'); // =>
+                     * [36, 40] (iteration order is not guaranteed)
+                     */
+                    function pluck(collection, path) {
+                        return map(collection, property(path));
+                    }
+
+                    /**
+                     * Reduces `collection` to a value which is the accumulated result of
+                     * running each element in `collection` through `iteratee`, where each
+                     * successive invocation is supplied the return value of the previous. If
+                     * `accumulator` is not provided the first element of `collection` is used
+                     * as the initial value. The `iteratee` is bound to `thisArg` and invoked
+                     * with four arguments: (accumulator, value, index|key, collection).
+                     * 
+                     * Many lodash methods are guarded to work as iteratees for methods like
+                     * `_.reduce`, `_.reduceRight`, and `_.transform`.
+                     * 
+                     * The guarded methods are: `assign`, `defaults`, `defaultsDeep`,
+                     * `includes`, `merge`, `sortByAll`, and `sortByOrder`
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias foldl, inject
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [accumulator] The initial value.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {*} Returns the accumulated value.
+                     * @example
+                     * 
+                     * _.reduce([1, 2], function(total, n) { return total + n; }); // => 3
+                     * 
+                     * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { result[key] = n *
+                     * 3; return result; }, {}); // => { 'a': 3, 'b': 6 } (iteration order is
+                     * not guaranteed)
+                     */
+                    var reduce = createReduce(arrayReduce, baseEach);
+
+                    /**
+                     * This method is like `_.reduce` except that it iterates over elements of
+                     * `collection` from right to left.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias foldr
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [accumulator] The initial value.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {*} Returns the accumulated value.
+                     * @example
+                     * 
+                     * var array = [[0, 1], [2, 3], [4, 5]];
+                     * 
+                     * _.reduceRight(array, function(flattened, other) { return
+                     * flattened.concat(other); }, []); // => [4, 5, 2, 3, 0, 1]
+                     */
+                    var reduceRight = createReduce(arrayReduceRight, baseEachRight);
+
+                    /**
+                     * The opposite of `_.filter`; this method returns the elements of
+                     * `collection` that `predicate` does **not** return truthy for.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Array} Returns the new filtered array.
+                     * @example
+                     * 
+                     * _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); // => [1, 3]
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': false }, { 'user':
+                     * 'fred', 'age': 40, 'active': true } ];
+                     *  // using the `_.matches` callback shorthand _.pluck(_.reject(users, {
+                     * 'age': 40, 'active': true }), 'user'); // => ['barney']
+                     *  // using the `_.matchesProperty` callback shorthand
+                     * _.pluck(_.reject(users, 'active', false), 'user'); // => ['fred']
+                     *  // using the `_.property` callback shorthand _.pluck(_.reject(users,
+                     * 'active'), 'user'); // => ['barney']
+                     */
+                    function reject(collection, predicate, thisArg) {
+                        var func = isArray(collection) ? arrayFilter : baseFilter;
+                        predicate = getCallback(predicate, thisArg, 3);
+                        return func(collection, function(value, index, collection) {
+                            return !predicate(value, index, collection);
+                        });
+                    }
+
+                    /**
+                     * Gets a random element or `n` random elements from a collection.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to sample.
+                     * @param {number}
+                     *            [n] The number of elements to sample.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {*} Returns the random sample(s).
+                     * @example
+                     * 
+                     * _.sample([1, 2, 3, 4]); // => 2
+                     * 
+                     * _.sample([1, 2, 3, 4], 2); // => [3, 1]
+                     */
+                    function sample(collection, n, guard) {
+                        if (guard ? isIterateeCall(collection, n, guard) : n == null) {
+                            collection = toIterable(collection);
+                            var length = collection.length;
+                            return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
+                        }
+                        var index = -1,
+                            result = toArray(collection),
+                            length = result.length,
+                            lastIndex = length - 1;
+
+                        n = nativeMin(n < 0 ? 0 : (+n || 0), length);
+                        while (++index < n) {
+                            var rand = baseRandom(index, lastIndex),
+                                value = result[rand];
+
+                            result[rand] = result[index];
+                            result[index] = value;
+                        }
+                        result.length = n;
+                        return result;
+                    }
+
+                    /**
+                     * Creates an array of shuffled values, using a version of the [Fisher-Yates
+                     * shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to shuffle.
+                     * @returns {Array} Returns the new shuffled array.
+                     * @example
+                     * 
+                     * _.shuffle([1, 2, 3, 4]); // => [4, 1, 3, 2]
+                     */
+                    function shuffle(collection) {
+                        return sample(collection, POSITIVE_INFINITY);
+                    }
+
+                    /**
+                     * Gets the size of `collection` by returning its length for array-like
+                     * values or the number of own enumerable properties for objects.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to inspect.
+                     * @returns {number} Returns the size of `collection`.
+                     * @example
+                     * 
+                     * _.size([1, 2, 3]); // => 3
+                     * 
+                     * _.size({ 'a': 1, 'b': 2 }); // => 2
+                     * 
+                     * _.size('pebbles'); // => 7
+                     */
+                    function size(collection) {
+                        var length = collection ? getLength(collection) : 0;
+                        return isLength(length) ? length : keys(collection).length;
+                    }
+
+                    /**
+                     * Checks if `predicate` returns truthy for **any** element of `collection`.
+                     * The function returns as soon as it finds a passing value and does not
+                     * iterate over the entire collection. The predicate is bound to `thisArg`
+                     * and invoked with three arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias any
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {boolean} Returns `true` if any element passes the predicate
+                     *          check, else `false`.
+                     * @example
+                     * 
+                     * _.some([null, 0, 'yes', false], Boolean); // => true
+                     * 
+                     * var users = [ { 'user': 'barney', 'active': true }, { 'user': 'fred',
+                     * 'active': false } ];
+                     *  // using the `_.matches` callback shorthand _.some(users, { 'user':
+                     * 'barney', 'active': false }); // => false
+                     *  // using the `_.matchesProperty` callback shorthand _.some(users,
+                     * 'active', false); // => true
+                     *  // using the `_.property` callback shorthand _.some(users, 'active'); // =>
+                     * true
+                     */
+                    function some(collection, predicate, thisArg) {
+                        var func = isArray(collection) ? arraySome : baseSome;
+                        if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
+                            predicate = undefined;
+                        }
+                        if (typeof predicate != 'function' || thisArg !== undefined) {
+                            predicate = getCallback(predicate, thisArg, 3);
+                        }
+                        return func(collection, predicate);
+                    }
+
+                    /**
+                     * Creates an array of elements, sorted in ascending order by the results of
+                     * running each element in a collection through `iteratee`. This method
+                     * performs a stable sort, that is, it preserves the original sort order of
+                     * equal elements. The `iteratee` is bound to `thisArg` and invoked with
+                     * three arguments: (value, index|key, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the new sorted array.
+                     * @example
+                     * 
+                     * _.sortBy([1, 2, 3], function(n) { return Math.sin(n); }); // => [3, 1, 2]
+                     * 
+                     * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); // => [3,
+                     * 1, 2]
+                     * 
+                     * var users = [ { 'user': 'fred' }, { 'user': 'pebbles' }, { 'user':
+                     * 'barney' } ];
+                     *  // using the `_.property` callback shorthand _.pluck(_.sortBy(users,
+                     * 'user'), 'user'); // => ['barney', 'fred', 'pebbles']
+                     */
+                    function sortBy(collection, iteratee, thisArg) {
+                        if (collection == null) {
+                            return [];
+                        }
+                        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
+                            iteratee = undefined;
+                        }
+                        var index = -1;
+                        iteratee = getCallback(iteratee, thisArg, 3);
+
+                        var result = baseMap(collection, function(value, key, collection) {
+                            return {
+                                'criteria': iteratee(value, key, collection),
+                                'index': ++index,
+                                'value': value
+                            };
+                        });
+                        return baseSortBy(result, compareAscending);
+                    }
+
+                    /**
+                     * This method is like `_.sortBy` except that it can sort by multiple
+                     * iteratees or property names.
+                     * 
+                     * If a property name is provided for an iteratee the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If an object is provided for an iteratee the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {...(Function|Function[]|Object|Object[]|string|string[])}
+                     *            iteratees The iteratees to sort by, specified as individual
+                     *            values or arrays of values.
+                     * @returns {Array} Returns the new sorted array.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'fred', 'age': 48 }, { 'user': 'barney', 'age':
+                     * 36 }, { 'user': 'fred', 'age': 42 }, { 'user': 'barney', 'age': 34 } ];
+                     * 
+                     * _.map(_.sortByAll(users, ['user', 'age']), _.values); // => [['barney',
+                     * 34], ['barney', 36], ['fred', 42], ['fred', 48]]
+                     * 
+                     * _.map(_.sortByAll(users, 'user', function(chr) { return
+                     * Math.floor(chr.age / 10); }), _.values); // => [['barney', 36],
+                     * ['barney', 34], ['fred', 48], ['fred', 42]]
+                     */
+                    var sortByAll = restParam(function(collection, iteratees) {
+                        if (collection == null) {
+                            return [];
+                        }
+                        var guard = iteratees[2];
+                        if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) {
+                            iteratees.length = 1;
+                        }
+                        return baseSortByOrder(collection, baseFlatten(iteratees), []);
+                    });
+
+                    /**
+                     * This method is like `_.sortByAll` except that it allows specifying the
+                     * sort orders of the iteratees to sort by. If `orders` is unspecified, all
+                     * values are sorted in ascending order. Otherwise, a value is sorted in
+                     * ascending order if its corresponding order is "asc", and descending if
+                     * "desc".
+                     * 
+                     * If a property name is provided for an iteratee the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If an object is provided for an iteratee the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function[]|Object[]|string[]}
+                     *            iteratees The iteratees to sort by.
+                     * @param {boolean[]}
+                     *            [orders] The sort orders of `iteratees`.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.reduce`.
+                     * @returns {Array} Returns the new sorted array.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'fred', 'age': 48 }, { 'user': 'barney', 'age':
+                     * 34 }, { 'user': 'fred', 'age': 42 }, { 'user': 'barney', 'age': 36 } ];
+                     *  // sort by `user` in ascending order and by `age` in descending order
+                     * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); // =>
+                     * [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+                     */
+                    function sortByOrder(collection, iteratees, orders, guard) {
+                        if (collection == null) {
+                            return [];
+                        }
+                        if (guard && isIterateeCall(iteratees, orders, guard)) {
+                            orders = undefined;
+                        }
+                        if (!isArray(iteratees)) {
+                            iteratees = iteratees == null ? [] : [iteratees];
+                        }
+                        if (!isArray(orders)) {
+                            orders = orders == null ? [] : [orders];
+                        }
+                        return baseSortByOrder(collection, iteratees, orders);
+                    }
+
+                    /**
+                     * Performs a deep comparison between each element in `collection` and the
+                     * source object, returning an array of all elements that have equivalent
+                     * property values.
+                     * 
+                     * **Note:** This method supports comparing arrays, booleans, `Date`
+                     * objects, numbers, `Object` objects, regexes, and strings. Objects are
+                     * compared by their own, not inherited, enumerable properties. For
+                     * comparing a single own or inherited property value see
+                     * `_.matchesProperty`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Collection
+                     * @param {Array|Object|string}
+                     *            collection The collection to search.
+                     * @param {Object}
+                     *            source The object of property values to match.
+                     * @returns {Array} Returns the new filtered array.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': false, 'pets':
+                     * ['hoppy'] }, { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby
+                     * puss', 'dino'] } ];
+                     * 
+                     * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); // =>
+                     * ['barney']
+                     * 
+                     * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); // => ['fred']
+                     */
+                    function where(collection, source) {
+                        return filter(collection, baseMatches(source));
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Gets the number of milliseconds that have elapsed since the Unix epoch (1
+                     * January 1970 00:00:00 UTC).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Date
+                     * @example
+                     * 
+                     * _.defer(function(stamp) { console.log(_.now() - stamp); }, _.now()); // =>
+                     * logs the number of milliseconds it took for the deferred function to be
+                     * invoked
+                     */
+                    var now = nativeNow || function() {
+                        return new Date().getTime();
+                    };
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * The opposite of `_.before`; this method creates a function that invokes
+                     * `func` once it is called `n` or more times.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {number}
+                     *            n The number of calls before `func` is invoked.
+                     * @param {Function}
+                     *            func The function to restrict.
+                     * @returns {Function} Returns the new restricted function.
+                     * @example
+                     * 
+                     * var saves = ['profile', 'settings'];
+                     * 
+                     * var done = _.after(saves.length, function() { console.log('done
+                     * saving!'); });
+                     * 
+                     * _.forEach(saves, function(type) { asyncSave({ 'type': type, 'complete':
+                     * done }); }); // => logs 'done saving!' after the two async saves have
+                     * completed
+                     */
+                    function after(n, func) {
+                        if (typeof func != 'function') {
+                            if (typeof n == 'function') {
+                                var temp = n;
+                                n = func;
+                                func = temp;
+                            } else {
+                                throw new TypeError(FUNC_ERROR_TEXT);
+                            }
+                        }
+                        n = nativeIsFinite(n = +n) ? n : 0;
+                        return function() {
+                            if (--n < 1) {
+                                return func.apply(this, arguments);
+                            }
+                        };
+                    }
+
+                    /**
+                     * Creates a function that accepts up to `n` arguments ignoring any
+                     * additional arguments.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to cap arguments for.
+                     * @param {number}
+                     *            [n=func.length] The arity cap.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * _.map(['6', '8', '10'], _.ary(parseInt, 1)); // => [6, 8, 10]
+                     */
+                    function ary(func, n, guard) {
+                        if (guard && isIterateeCall(func, n, guard)) {
+                            n = undefined;
+                        }
+                        n = (func && n == null) ? func.length : nativeMax(+n || 0, 0);
+                        return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
+                    }
+
+                    /**
+                     * Creates a function that invokes `func`, with the `this` binding and
+                     * arguments of the created function, while it is called less than `n`
+                     * times. Subsequent calls to the created function return the result of the
+                     * last `func` invocation.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {number}
+                     *            n The number of calls at which `func` is no longer invoked.
+                     * @param {Function}
+                     *            func The function to restrict.
+                     * @returns {Function} Returns the new restricted function.
+                     * @example
+                     * 
+                     * jQuery('#add').on('click', _.before(5, addContactToList)); // => allows
+                     * adding up to 4 contacts to the list
+                     */
+                    function before(n, func) {
+                        var result;
+                        if (typeof func != 'function') {
+                            if (typeof n == 'function') {
+                                var temp = n;
+                                n = func;
+                                func = temp;
+                            } else {
+                                throw new TypeError(FUNC_ERROR_TEXT);
+                            }
+                        }
+                        return function() {
+                            if (--n > 0) {
+                                result = func.apply(this, arguments);
+                            }
+                            if (n <= 1) {
+                                func = undefined;
+                            }
+                            return result;
+                        };
+                    }
+
+                    /**
+                     * Creates a function that invokes `func` with the `this` binding of
+                     * `thisArg` and prepends any additional `_.bind` arguments to those
+                     * provided to the bound function.
+                     * 
+                     * The `_.bind.placeholder` value, which defaults to `_` in monolithic
+                     * builds, may be used as a placeholder for partially applied arguments.
+                     * 
+                     * **Note:** Unlike native `Function#bind` this method does not set the
+                     * "length" property of bound functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to bind.
+                     * @param {*}
+                     *            thisArg The `this` binding of `func`.
+                     * @param {...*}
+                     *            [partials] The arguments to be partially applied.
+                     * @returns {Function} Returns the new bound function.
+                     * @example
+                     * 
+                     * var greet = function(greeting, punctuation) { return greeting + ' ' +
+                     * this.user + punctuation; };
+                     * 
+                     * var object = { 'user': 'fred' };
+                     * 
+                     * var bound = _.bind(greet, object, 'hi'); bound('!'); // => 'hi fred!'
+                     *  // using placeholders var bound = _.bind(greet, object, _, '!');
+                     * bound('hi'); // => 'hi fred!'
+                     */
+                    var bind = restParam(function(func, thisArg, partials) {
+                        var bitmask = BIND_FLAG;
+                        if (partials.length) {
+                            var holders = replaceHolders(partials, bind.placeholder);
+                            bitmask |= PARTIAL_FLAG;
+                        }
+                        return createWrapper(func, bitmask, thisArg, partials, holders);
+                    });
+
+                    /**
+                     * Binds methods of an object to the object itself, overwriting the existing
+                     * method. Method names may be specified as individual arguments or as
+                     * arrays of method names. If no method names are provided all enumerable
+                     * function properties, own and inherited, of `object` are bound.
+                     * 
+                     * **Note:** This method does not set the "length" property of bound
+                     * functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Object}
+                     *            object The object to bind and assign the bound methods to.
+                     * @param {...(string|string[])}
+                     *            [methodNames] The object method names to bind, specified as
+                     *            individual method names or arrays of method names.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * var view = { 'label': 'docs', 'onClick': function() {
+                     * console.log('clicked ' + this.label); } };
+                     * 
+                     * _.bindAll(view); jQuery('#docs').on('click', view.onClick); // => logs
+                     * 'clicked docs' when the element is clicked
+                     */
+                    var bindAll = restParam(function(object, methodNames) {
+                        methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object);
+
+                        var index = -1,
+                            length = methodNames.length;
+
+                        while (++index < length) {
+                            var key = methodNames[index];
+                            object[key] = createWrapper(object[key], BIND_FLAG, object);
+                        }
+                        return object;
+                    });
+
+                    /**
+                     * Creates a function that invokes the method at `object[key]` and prepends
+                     * any additional `_.bindKey` arguments to those provided to the bound
+                     * function.
+                     * 
+                     * This method differs from `_.bind` by allowing bound functions to
+                     * reference methods that may be redefined or don't yet exist. See [Peter
+                     * Michaux's
+                     * article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
+                     * for more details.
+                     * 
+                     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
+                     * builds, may be used as a placeholder for partially applied arguments.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Object}
+                     *            object The object the method belongs to.
+                     * @param {string}
+                     *            key The key of the method.
+                     * @param {...*}
+                     *            [partials] The arguments to be partially applied.
+                     * @returns {Function} Returns the new bound function.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred', 'greet': function(greeting, punctuation) {
+                     * return greeting + ' ' + this.user + punctuation; } };
+                     * 
+                     * var bound = _.bindKey(object, 'greet', 'hi'); bound('!'); // => 'hi
+                     * fred!'
+                     * 
+                     * object.greet = function(greeting, punctuation) { return greeting + 'ya ' +
+                     * this.user + punctuation; };
+                     * 
+                     * bound('!'); // => 'hiya fred!'
+                     *  // using placeholders var bound = _.bindKey(object, 'greet', _, '!');
+                     * bound('hi'); // => 'hiya fred!'
+                     */
+                    var bindKey = restParam(function(object, key, partials) {
+                        var bitmask = BIND_FLAG | BIND_KEY_FLAG;
+                        if (partials.length) {
+                            var holders = replaceHolders(partials, bindKey.placeholder);
+                            bitmask |= PARTIAL_FLAG;
+                        }
+                        return createWrapper(key, bitmask, object, partials, holders);
+                    });
+
+                    /**
+                     * Creates a function that accepts one or more arguments of `func` that when
+                     * called either invokes `func` returning its result, if all `func`
+                     * arguments have been provided, or returns a function that accepts one or
+                     * more of the remaining `func` arguments, and so on. The arity of `func`
+                     * may be specified if `func.length` is not sufficient.
+                     * 
+                     * The `_.curry.placeholder` value, which defaults to `_` in monolithic
+                     * builds, may be used as a placeholder for provided arguments.
+                     * 
+                     * **Note:** This method does not set the "length" property of curried
+                     * functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to curry.
+                     * @param {number}
+                     *            [arity=func.length] The arity of `func`.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Function} Returns the new curried function.
+                     * @example
+                     * 
+                     * var abc = function(a, b, c) { return [a, b, c]; };
+                     * 
+                     * var curried = _.curry(abc);
+                     * 
+                     * curried(1)(2)(3); // => [1, 2, 3]
+                     * 
+                     * curried(1, 2)(3); // => [1, 2, 3]
+                     * 
+                     * curried(1, 2, 3); // => [1, 2, 3]
+                     *  // using placeholders curried(1)(_, 3)(2); // => [1, 2, 3]
+                     */
+                    var curry = createCurry(CURRY_FLAG);
+
+                    /**
+                     * This method is like `_.curry` except that arguments are applied to `func`
+                     * in the manner of `_.partialRight` instead of `_.partial`.
+                     * 
+                     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
+                     * builds, may be used as a placeholder for provided arguments.
+                     * 
+                     * **Note:** This method does not set the "length" property of curried
+                     * functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to curry.
+                     * @param {number}
+                     *            [arity=func.length] The arity of `func`.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Function} Returns the new curried function.
+                     * @example
+                     * 
+                     * var abc = function(a, b, c) { return [a, b, c]; };
+                     * 
+                     * var curried = _.curryRight(abc);
+                     * 
+                     * curried(3)(2)(1); // => [1, 2, 3]
+                     * 
+                     * curried(2, 3)(1); // => [1, 2, 3]
+                     * 
+                     * curried(1, 2, 3); // => [1, 2, 3]
+                     *  // using placeholders curried(3)(1, _)(2); // => [1, 2, 3]
+                     */
+                    var curryRight = createCurry(CURRY_RIGHT_FLAG);
+
+                    /**
+                     * Creates a debounced function that delays invoking `func` until after
+                     * `wait` milliseconds have elapsed since the last time the debounced
+                     * function was invoked. The debounced function comes with a `cancel` method
+                     * to cancel delayed invocations. Provide an options object to indicate that
+                     * `func` should be invoked on the leading and/or trailing edge of the
+                     * `wait` timeout. Subsequent calls to the debounced function return the
+                     * result of the last `func` invocation.
+                     * 
+                     * **Note:** If `leading` and `trailing` options are `true`, `func` is
+                     * invoked on the trailing edge of the timeout only if the the debounced
+                     * function is invoked more than once during the `wait` timeout.
+                     * 
+                     * See [David Corbacho's
+                     * article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
+                     * for details over the differences between `_.debounce` and `_.throttle`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to debounce.
+                     * @param {number}
+                     *            [wait=0] The number of milliseconds to delay.
+                     * @param {Object}
+                     *            [options] The options object.
+                     * @param {boolean}
+                     *            [options.leading=false] Specify invoking on the leading edge
+                     *            of the timeout.
+                     * @param {number}
+                     *            [options.maxWait] The maximum time `func` is allowed to be
+                     *            delayed before it is invoked.
+                     * @param {boolean}
+                     *            [options.trailing=true] Specify invoking on the trailing edge
+                     *            of the timeout.
+                     * @returns {Function} Returns the new debounced function.
+                     * @example
+                     *  // avoid costly calculations while the window size is in flux
+                     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+                     *  // invoke `sendMail` when the click event is fired, debouncing
+                     * subsequent calls jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
+                     * 'leading': true, 'trailing': false }));
+                     *  // ensure `batchLog` is invoked once after 1 second of debounced calls
+                     * var source = new EventSource('/stream'); jQuery(source).on('message',
+                     * _.debounce(batchLog, 250, { 'maxWait': 1000 }));
+                     *  // cancel a debounced call var todoChanges = _.debounce(batchLog, 1000);
+                     * Object.observe(models.todo, todoChanges);
+                     * 
+                     * Object.observe(models, function(changes) { if (_.find(changes, { 'user':
+                     * 'todo', 'type': 'delete'})) { todoChanges.cancel(); } }, ['delete']);
+                     *  // ...at some point `models.todo` is changed models.todo.completed =
+                     * true;
+                     *  // ...before 1 second has passed `models.todo` is deleted // which
+                     * cancels the debounced `todoChanges` call delete models.todo;
+                     */
+                    function debounce(func, wait, options) {
+                        var args,
+                            maxTimeoutId,
+                            result,
+                            stamp,
+                            thisArg,
+                            timeoutId,
+                            trailingCall,
+                            lastCalled = 0,
+                            maxWait = false,
+                            trailing = true;
+
+                        if (typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        wait = wait < 0 ? 0 : (+wait || 0);
+                        if (options === true) {
+                            var leading = true;
+                            trailing = false;
+                        } else if (isObject(options)) {
+                            leading = !!options.leading;
+                            maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
+                            trailing = 'trailing' in options ? !!options.trailing : trailing;
+                        }
+
+                        function cancel() {
+                            if (timeoutId) {
+                                clearTimeout(timeoutId);
+                            }
+                            if (maxTimeoutId) {
+                                clearTimeout(maxTimeoutId);
+                            }
+                            lastCalled = 0;
+                            maxTimeoutId = timeoutId = trailingCall = undefined;
+                        }
+
+                        function complete(isCalled, id) {
+                            if (id) {
+                                clearTimeout(id);
+                            }
+                            maxTimeoutId = timeoutId = trailingCall = undefined;
+                            if (isCalled) {
+                                lastCalled = now();
+                                result = func.apply(thisArg, args);
+                                if (!timeoutId && !maxTimeoutId) {
+                                    args = thisArg = undefined;
+                                }
+                            }
+                        }
+
+                        function delayed() {
+                            var remaining = wait - (now() - stamp);
+                            if (remaining <= 0 || remaining > wait) {
+                                complete(trailingCall, maxTimeoutId);
+                            } else {
+                                timeoutId = setTimeout(delayed, remaining);
+                            }
+                        }
+
+                        function maxDelayed() {
+                            complete(trailing, timeoutId);
+                        }
+
+                        function debounced() {
+                            args = arguments;
+                            stamp = now();
+                            thisArg = this;
+                            trailingCall = trailing && (timeoutId || !leading);
+
+                            if (maxWait === false) {
+                                var leadingCall = leading && !timeoutId;
+                            } else {
+                                if (!maxTimeoutId && !leading) {
+                                    lastCalled = stamp;
+                                }
+                                var remaining = maxWait - (stamp - lastCalled),
+                                    isCalled = remaining <= 0 || remaining > maxWait;
+
+                                if (isCalled) {
+                                    if (maxTimeoutId) {
+                                        maxTimeoutId = clearTimeout(maxTimeoutId);
+                                    }
+                                    lastCalled = stamp;
+                                    result = func.apply(thisArg, args);
+                                } else if (!maxTimeoutId) {
+                                    maxTimeoutId = setTimeout(maxDelayed, remaining);
+                                }
+                            }
+                            if (isCalled && timeoutId) {
+                                timeoutId = clearTimeout(timeoutId);
+                            } else if (!timeoutId && wait !== maxWait) {
+                                timeoutId = setTimeout(delayed, wait);
+                            }
+                            if (leadingCall) {
+                                isCalled = true;
+                                result = func.apply(thisArg, args);
+                            }
+                            if (isCalled && !timeoutId && !maxTimeoutId) {
+                                args = thisArg = undefined;
+                            }
+                            return result;
+                        }
+                        debounced.cancel = cancel;
+                        return debounced;
+                    }
+
+                    /**
+                     * Defers invoking the `func` until the current call stack has cleared. Any
+                     * additional arguments are provided to `func` when it is invoked.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to defer.
+                     * @param {...*}
+                     *            [args] The arguments to invoke the function with.
+                     * @returns {number} Returns the timer id.
+                     * @example
+                     * 
+                     * _.defer(function(text) { console.log(text); }, 'deferred'); // logs
+                     * 'deferred' after one or more milliseconds
+                     */
+                    var defer = restParam(function(func, args) {
+                        return baseDelay(func, 1, args);
+                    });
+
+                    /**
+                     * Invokes `func` after `wait` milliseconds. Any additional arguments are
+                     * provided to `func` when it is invoked.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to delay.
+                     * @param {number}
+                     *            wait The number of milliseconds to delay invocation.
+                     * @param {...*}
+                     *            [args] The arguments to invoke the function with.
+                     * @returns {number} Returns the timer id.
+                     * @example
+                     * 
+                     * _.delay(function(text) { console.log(text); }, 1000, 'later'); // => logs
+                     * 'later' after one second
+                     */
+                    var delay = restParam(function(func, wait, args) {
+                        return baseDelay(func, wait, args);
+                    });
+
+                    /**
+                     * Creates a function that returns the result of invoking the provided
+                     * functions with the `this` binding of the created function, where each
+                     * successive invocation is supplied the return value of the previous.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {...Function}
+                     *            [funcs] Functions to invoke.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * function square(n) { return n * n; }
+                     * 
+                     * var addSquare = _.flow(_.add, square); addSquare(1, 2); // => 9
+                     */
+                    var flow = createFlow();
+
+                    /**
+                     * This method is like `_.flow` except that it creates a function that
+                     * invokes the provided functions from right to left.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias backflow, compose
+                     * @category Function
+                     * @param {...Function}
+                     *            [funcs] Functions to invoke.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * function square(n) { return n * n; }
+                     * 
+                     * var addSquare = _.flowRight(square, _.add); addSquare(1, 2); // => 9
+                     */
+                    var flowRight = createFlow(true);
+
+                    /**
+                     * Creates a function that memoizes the result of `func`. If `resolver` is
+                     * provided it determines the cache key for storing the result based on the
+                     * arguments provided to the memoized function. By default, the first
+                     * argument provided to the memoized function is coerced to a string and
+                     * used as the cache key. The `func` is invoked with the `this` binding of
+                     * the memoized function.
+                     * 
+                     * **Note:** The cache is exposed as the `cache` property on the memoized
+                     * function. Its creation may be customized by replacing the
+                     * `_.memoize.Cache` constructor with one whose instances implement the
+                     * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
+                     * method interface of `get`, `has`, and `set`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to have its output memoized.
+                     * @param {Function}
+                     *            [resolver] The function to resolve the cache key.
+                     * @returns {Function} Returns the new memoizing function.
+                     * @example
+                     * 
+                     * var upperCase = _.memoize(function(string) { return string.toUpperCase();
+                     * });
+                     * 
+                     * upperCase('fred'); // => 'FRED'
+                     *  // modifying the result cache upperCase.cache.set('fred', 'BARNEY');
+                     * upperCase('fred'); // => 'BARNEY'
+                     *  // replacing `_.memoize.Cache` var object = { 'user': 'fred' }; var
+                     * other = { 'user': 'barney' }; var identity = _.memoize(_.identity);
+                     * 
+                     * identity(object); // => { 'user': 'fred' } identity(other); // => {
+                     * 'user': 'fred' }
+                     * 
+                     * _.memoize.Cache = WeakMap; var identity = _.memoize(_.identity);
+                     * 
+                     * identity(object); // => { 'user': 'fred' } identity(other); // => {
+                     * 'user': 'barney' }
+                     */
+                    function memoize(func, resolver) {
+                        if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        var memoized = function() {
+                            var args = arguments,
+                                key = resolver ? resolver.apply(this, args) : args[0],
+                                cache = memoized.cache;
+
+                            if (cache.has(key)) {
+                                return cache.get(key);
+                            }
+                            var result = func.apply(this, args);
+                            memoized.cache = cache.set(key, result);
+                            return result;
+                        };
+                        memoized.cache = new memoize.Cache;
+                        return memoized;
+                    }
+
+                    /**
+                     * Creates a function that runs each argument through a corresponding
+                     * transform function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to wrap.
+                     * @param {...(Function|Function[])}
+                     *            [transforms] The functions to transform arguments, specified
+                     *            as individual functions or arrays of functions.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * function doubled(n) { return n * 2; }
+                     * 
+                     * function square(n) { return n * n; }
+                     * 
+                     * var modded = _.modArgs(function(x, y) { return [x, y]; }, square,
+                     * doubled);
+                     * 
+                     * modded(1, 2); // => [1, 4]
+                     * 
+                     * modded(5, 10); // => [25, 20]
+                     */
+                    var modArgs = restParam(function(func, transforms) {
+                        transforms = baseFlatten(transforms);
+                        if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        var length = transforms.length;
+                        return restParam(function(args) {
+                            var index = nativeMin(args.length, length);
+                            while (index--) {
+                                args[index] = transforms[index](args[index]);
+                            }
+                            return func.apply(this, args);
+                        });
+                    });
+
+                    /**
+                     * Creates a function that negates the result of the predicate `func`. The
+                     * `func` predicate is invoked with the `this` binding and arguments of the
+                     * created function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            predicate The predicate to negate.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * function isEven(n) { return n % 2 == 0; }
+                     * 
+                     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); // => [1, 3, 5]
+                     */
+                    function negate(predicate) {
+                        if (typeof predicate != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        return function() {
+                            return !predicate.apply(this, arguments);
+                        };
+                    }
+
+                    /**
+                     * Creates a function that is restricted to invoking `func` once. Repeat
+                     * calls to the function return the value of the first call. The `func` is
+                     * invoked with the `this` binding and arguments of the created function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to restrict.
+                     * @returns {Function} Returns the new restricted function.
+                     * @example
+                     * 
+                     * var initialize = _.once(createApplication); initialize(); initialize(); //
+                     * `initialize` invokes `createApplication` once
+                     */
+                    function once(func) {
+                        return before(2, func);
+                    }
+
+                    /**
+                     * Creates a function that invokes `func` with `partial` arguments prepended
+                     * to those provided to the new function. This method is like `_.bind`
+                     * except it does **not** alter the `this` binding.
+                     * 
+                     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
+                     * builds, may be used as a placeholder for partially applied arguments.
+                     * 
+                     * **Note:** This method does not set the "length" property of partially
+                     * applied functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to partially apply arguments to.
+                     * @param {...*}
+                     *            [partials] The arguments to be partially applied.
+                     * @returns {Function} Returns the new partially applied function.
+                     * @example
+                     * 
+                     * var greet = function(greeting, name) { return greeting + ' ' + name; };
+                     * 
+                     * var sayHelloTo = _.partial(greet, 'hello'); sayHelloTo('fred'); // =>
+                     * 'hello fred'
+                     *  // using placeholders var greetFred = _.partial(greet, _, 'fred');
+                     * greetFred('hi'); // => 'hi fred'
+                     */
+                    var partial = createPartial(PARTIAL_FLAG);
+
+                    /**
+                     * This method is like `_.partial` except that partially applied arguments
+                     * are appended to those provided to the new function.
+                     * 
+                     * The `_.partialRight.placeholder` value, which defaults to `_` in
+                     * monolithic builds, may be used as a placeholder for partially applied
+                     * arguments.
+                     * 
+                     * **Note:** This method does not set the "length" property of partially
+                     * applied functions.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to partially apply arguments to.
+                     * @param {...*}
+                     *            [partials] The arguments to be partially applied.
+                     * @returns {Function} Returns the new partially applied function.
+                     * @example
+                     * 
+                     * var greet = function(greeting, name) { return greeting + ' ' + name; };
+                     * 
+                     * var greetFred = _.partialRight(greet, 'fred'); greetFred('hi'); // => 'hi
+                     * fred'
+                     *  // using placeholders var sayHelloTo = _.partialRight(greet, 'hello',
+                     * _); sayHelloTo('fred'); // => 'hello fred'
+                     */
+                    var partialRight = createPartial(PARTIAL_RIGHT_FLAG);
+
+                    /**
+                     * Creates a function that invokes `func` with arguments arranged according
+                     * to the specified indexes where the argument value at the first index is
+                     * provided as the first argument, the argument value at the second index is
+                     * provided as the second argument, and so on.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to rearrange arguments for.
+                     * @param {...(number|number[])}
+                     *            indexes The arranged argument indexes, specified as individual
+                     *            indexes or arrays of indexes.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var rearged = _.rearg(function(a, b, c) { return [a, b, c]; }, 2, 0, 1);
+                     * 
+                     * rearged('b', 'c', 'a') // => ['a', 'b', 'c']
+                     * 
+                     * var map = _.rearg(_.map, [1, 0]); map(function(n) { return n * 3; }, [1,
+                     * 2, 3]); // => [3, 6, 9]
+                     */
+                    var rearg = restParam(function(func, indexes) {
+                        return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
+                    });
+
+                    /**
+                     * Creates a function that invokes `func` with the `this` binding of the
+                     * created function and arguments from `start` and beyond provided as an
+                     * array.
+                     * 
+                     * **Note:** This method is based on the [rest
+                     * parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to apply a rest parameter to.
+                     * @param {number}
+                     *            [start=func.length-1] The start position of the rest
+                     *            parameter.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var say = _.restParam(function(what, names) { return what + ' ' +
+                     * _.initial(names).join(', ') + (_.size(names) > 1 ? ', & ' : '') +
+                     * _.last(names); });
+                     * 
+                     * say('hello', 'fred', 'barney', 'pebbles'); // => 'hello fred, barney, &
+                     * pebbles'
+                     */
+                    function restParam(func, start) {
+                        if (typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+                        return function() {
+                            var args = arguments,
+                                index = -1,
+                                length = nativeMax(args.length - start, 0),
+                                rest = Array(length);
+
+                            while (++index < length) {
+                                rest[index] = args[start + index];
+                            }
+                            switch (start) {
+                                case 0:
+                                    return func.call(this, rest);
+                                case 1:
+                                    return func.call(this, args[0], rest);
+                                case 2:
+                                    return func.call(this, args[0], args[1], rest);
+                            }
+                            var otherArgs = Array(start + 1);
+                            index = -1;
+                            while (++index < start) {
+                                otherArgs[index] = args[index];
+                            }
+                            otherArgs[start] = rest;
+                            return func.apply(this, otherArgs);
+                        };
+                    }
+
+                    /**
+                     * Creates a function that invokes `func` with the `this` binding of the
+                     * created function and an array of arguments much like
+                     * [`Function#apply`](https://es5.github.io/#x15.3.4.3).
+                     * 
+                     * **Note:** This method is based on the [spread
+                     * operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to spread arguments over.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var say = _.spread(function(who, what) { return who + ' says ' + what;
+                     * });
+                     * 
+                     * say(['fred', 'hello']); // => 'fred says hello'
+                     *  // with a Promise var numbers = Promise.all([ Promise.resolve(40),
+                     * Promise.resolve(36) ]);
+                     * 
+                     * numbers.then(_.spread(function(x, y) { return x + y; })); // => a Promise
+                     * of 76
+                     */
+                    function spread(func) {
+                        if (typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        return function(array) {
+                            return func.apply(this, array);
+                        };
+                    }
+
+                    /**
+                     * Creates a throttled function that only invokes `func` at most once per
+                     * every `wait` milliseconds. The throttled function comes with a `cancel`
+                     * method to cancel delayed invocations. Provide an options object to
+                     * indicate that `func` should be invoked on the leading and/or trailing
+                     * edge of the `wait` timeout. Subsequent calls to the throttled function
+                     * return the result of the last `func` call.
+                     * 
+                     * **Note:** If `leading` and `trailing` options are `true`, `func` is
+                     * invoked on the trailing edge of the timeout only if the the throttled
+                     * function is invoked more than once during the `wait` timeout.
+                     * 
+                     * See [David Corbacho's
+                     * article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
+                     * for details over the differences between `_.throttle` and `_.debounce`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {Function}
+                     *            func The function to throttle.
+                     * @param {number}
+                     *            [wait=0] The number of milliseconds to throttle invocations
+                     *            to.
+                     * @param {Object}
+                     *            [options] The options object.
+                     * @param {boolean}
+                     *            [options.leading=true] Specify invoking on the leading edge of
+                     *            the timeout.
+                     * @param {boolean}
+                     *            [options.trailing=true] Specify invoking on the trailing edge
+                     *            of the timeout.
+                     * @returns {Function} Returns the new throttled function.
+                     * @example
+                     *  // avoid excessively updating the position while scrolling
+                     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
+                     *  // invoke `renewToken` when the click event is fired, but not more than
+                     * once every 5 minutes jQuery('.interactive').on('click',
+                     * _.throttle(renewToken, 300000, { 'trailing': false }));
+                     *  // cancel a trailing throttled call jQuery(window).on('popstate',
+                     * throttled.cancel);
+                     */
+                    function throttle(func, wait, options) {
+                        var leading = true,
+                            trailing = true;
+
+                        if (typeof func != 'function') {
+                            throw new TypeError(FUNC_ERROR_TEXT);
+                        }
+                        if (options === false) {
+                            leading = false;
+                        } else if (isObject(options)) {
+                            leading = 'leading' in options ? !!options.leading : leading;
+                            trailing = 'trailing' in options ? !!options.trailing : trailing;
+                        }
+                        return debounce(func, wait, {
+                            'leading': leading,
+                            'maxWait': +wait,
+                            'trailing': trailing
+                        });
+                    }
+
+                    /**
+                     * Creates a function that provides `value` to the wrapper function as its
+                     * first argument. Any additional arguments provided to the function are
+                     * appended to those provided to the wrapper function. The wrapper is
+                     * invoked with the `this` binding of the created function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Function
+                     * @param {*}
+                     *            value The value to wrap.
+                     * @param {Function}
+                     *            wrapper The wrapper function.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var p = _.wrap(_.escape, function(func, text) { return '
+                     * <p>' + func(text) + '
+                     * </p>'; });
+                     * 
+                     * p('fred, barney, & pebbles'); // => '
+                     * <p>
+                     * fred, barney, &amp; pebbles
+                     * </p>'
+                     */
+                    function wrap(value, wrapper) {
+                        wrapper = wrapper == null ? identity : wrapper;
+                        return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []);
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Creates a clone of `value`. If `isDeep` is `true` nested objects are
+                     * cloned, otherwise they are assigned by reference. If `customizer` is
+                     * provided it is invoked to produce the cloned values. If `customizer`
+                     * returns `undefined` cloning is handled by the method instead. The
+                     * `customizer` is bound to `thisArg` and invoked with two argument; (value [,
+                     * index|key, object]).
+                     * 
+                     * **Note:** This method is loosely based on the [structured clone
+                     * algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+                     * The enumerable properties of `arguments` objects and objects created by
+                     * constructors other than `Object` are cloned to plain `Object` objects. An
+                     * empty object is returned for uncloneable values such as functions, DOM
+                     * nodes, Maps, Sets, and WeakMaps.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to clone.
+                     * @param {boolean}
+                     *            [isDeep] Specify a deep clone.
+                     * @param {Function}
+                     *            [customizer] The function to customize cloning values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {*} Returns the cloned value.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney' }, { 'user': 'fred' } ];
+                     * 
+                     * var shallow = _.clone(users); shallow[0] === users[0]; // => true
+                     * 
+                     * var deep = _.clone(users, true); deep[0] === users[0]; // => false
+                     *  // using a customizer callback var el = _.clone(document.body,
+                     * function(value) { if (_.isElement(value)) { return
+                     * value.cloneNode(false); } });
+                     * 
+                     * el === document.body // => false el.nodeName // => BODY
+                     * el.childNodes.length; // => 0
+                     */
+                    function clone(value, isDeep, customizer, thisArg) {
+                        if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
+                            isDeep = false;
+                        } else if (typeof isDeep == 'function') {
+                            thisArg = customizer;
+                            customizer = isDeep;
+                            isDeep = false;
+                        }
+                        return typeof customizer == 'function' ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) : baseClone(value, isDeep);
+                    }
+
+                    /**
+                     * Creates a deep clone of `value`. If `customizer` is provided it is
+                     * invoked to produce the cloned values. If `customizer` returns `undefined`
+                     * cloning is handled by the method instead. The `customizer` is bound to
+                     * `thisArg` and invoked with two argument; (value [, index|key, object]).
+                     * 
+                     * **Note:** This method is loosely based on the [structured clone
+                     * algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+                     * The enumerable properties of `arguments` objects and objects created by
+                     * constructors other than `Object` are cloned to plain `Object` objects. An
+                     * empty object is returned for uncloneable values such as functions, DOM
+                     * nodes, Maps, Sets, and WeakMaps.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to deep clone.
+                     * @param {Function}
+                     *            [customizer] The function to customize cloning values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {*} Returns the deep cloned value.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney' }, { 'user': 'fred' } ];
+                     * 
+                     * var deep = _.cloneDeep(users); deep[0] === users[0]; // => false
+                     *  // using a customizer callback var el = _.cloneDeep(document.body,
+                     * function(value) { if (_.isElement(value)) { return value.cloneNode(true); }
+                     * });
+                     * 
+                     * el === document.body // => false el.nodeName // => BODY
+                     * el.childNodes.length; // => 20
+                     */
+                    function cloneDeep(value, customizer, thisArg) {
+                        return typeof customizer == 'function' ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) : baseClone(value, true);
+                    }
+
+                    /**
+                     * Checks if `value` is greater than `other`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @returns {boolean} Returns `true` if `value` is greater than `other`,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.gt(3, 1); // => true
+                     * 
+                     * _.gt(3, 3); // => false
+                     * 
+                     * _.gt(1, 3); // => false
+                     */
+                    function gt(value, other) {
+                        return value > other;
+                    }
+
+                    /**
+                     * Checks if `value` is greater than or equal to `other`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @returns {boolean} Returns `true` if `value` is greater than or equal to
+                     *          `other`, else `false`.
+                     * @example
+                     * 
+                     * _.gte(3, 1); // => true
+                     * 
+                     * _.gte(3, 3); // => true
+                     * 
+                     * _.gte(1, 3); // => false
+                     */
+                    function gte(value, other) {
+                        return value >= other;
+                    }
+
+                    /**
+                     * Checks if `value` is classified as an `arguments` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isArguments(function() { return arguments; }()); // => true
+                     * 
+                     * _.isArguments([1, 2, 3]); // => false
+                     */
+                    function isArguments(value) {
+                        return isObjectLike(value) && isArrayLike(value) &&
+                            hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
+                    }
+
+                    /**
+                     * Checks if `value` is classified as an `Array` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isArray([1, 2, 3]); // => true
+                     * 
+                     * _.isArray(function() { return arguments; }()); // => false
+                     */
+                    var isArray = nativeIsArray || function(value) {
+                        return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+                    };
+
+                    /**
+                     * Checks if `value` is classified as a boolean primitive or object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isBoolean(false); // => true
+                     * 
+                     * _.isBoolean(null); // => false
+                     */
+                    function isBoolean(value) {
+                        return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag);
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a `Date` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isDate(new Date); // => true
+                     * 
+                     * _.isDate('Mon April 23 2012'); // => false
+                     */
+                    function isDate(value) {
+                        return isObjectLike(value) && objToString.call(value) == dateTag;
+                    }
+
+                    /**
+                     * Checks if `value` is a DOM element.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is a DOM element, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.isElement(document.body); // => true
+                     * 
+                     * _.isElement('<body>'); // => false
+                     */
+                    function isElement(value) {
+                        return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
+                    }
+
+                    /**
+                     * Checks if `value` is empty. A value is considered empty unless it is an
+                     * `arguments` object, array, string, or jQuery-like collection with a
+                     * length greater than `0` or an object with own enumerable properties.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {Array|Object|string}
+                     *            value The value to inspect.
+                     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+                     * @example
+                     * 
+                     * _.isEmpty(null); // => true
+                     * 
+                     * _.isEmpty(true); // => true
+                     * 
+                     * _.isEmpty(1); // => true
+                     * 
+                     * _.isEmpty([1, 2, 3]); // => false
+                     * 
+                     * _.isEmpty({ 'a': 1 }); // => false
+                     */
+                    function isEmpty(value) {
+                        if (value == null) {
+                            return true;
+                        }
+                        if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
+                                (isObjectLike(value) && isFunction(value.splice)))) {
+                            return !value.length;
+                        }
+                        return !keys(value).length;
+                    }
+
+                    /**
+                     * Performs a deep comparison between two values to determine if they are
+                     * equivalent. If `customizer` is provided it is invoked to compare values.
+                     * If `customizer` returns `undefined` comparisons are handled by the method
+                     * instead. The `customizer` is bound to `thisArg` and invoked with three
+                     * arguments: (value, other [, index|key]).
+                     * 
+                     * **Note:** This method supports comparing arrays, booleans, `Date`
+                     * objects, numbers, `Object` objects, regexes, and strings. Objects are
+                     * compared by their own, not inherited, enumerable properties. Functions
+                     * and DOM nodes are **not** supported. Provide a customizer function to
+                     * extend support for comparing other values.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias eq
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @param {Function}
+                     *            [customizer] The function to customize value comparisons.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {boolean} Returns `true` if the values are equivalent, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred' }; var other = { 'user': 'fred' };
+                     * 
+                     * object == other; // => false
+                     * 
+                     * _.isEqual(object, other); // => true
+                     *  // using a customizer callback var array = ['hello', 'goodbye']; var
+                     * other = ['hi', 'goodbye'];
+                     * 
+                     * _.isEqual(array, other, function(value, other) { if (_.every([value,
+                     * other], RegExp.prototype.test, /^h(?:i|ello)$/)) { return true; } }); // =>
+                     * true
+                     */
+                    function isEqual(value, other, customizer, thisArg) {
+                        customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
+                        var result = customizer ? customizer(value, other) : undefined;
+                        return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
+                    }
+
+                    /**
+                     * Checks if `value` is an `Error`, `EvalError`, `RangeError`,
+                     * `ReferenceError`, `SyntaxError`, `TypeError`, or `URIError` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is an error object, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.isError(new Error); // => true
+                     * 
+                     * _.isError(Error); // => false
+                     */
+                    function isError(value) {
+                        return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag;
+                    }
+
+                    /**
+                     * Checks if `value` is a finite primitive number.
+                     * 
+                     * **Note:** This method is based on
+                     * [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is a finite number, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.isFinite(10); // => true
+                     * 
+                     * _.isFinite('10'); // => false
+                     * 
+                     * _.isFinite(true); // => false
+                     * 
+                     * _.isFinite(Object(10)); // => false
+                     * 
+                     * _.isFinite(Infinity); // => false
+                     */
+                    function isFinite(value) {
+                        return typeof value == 'number' && nativeIsFinite(value);
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a `Function` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isFunction(_); // => true
+                     * 
+                     * _.isFunction(/abc/); // => false
+                     */
+                    function isFunction(value) {
+                        // The use of `Object#toString` avoids issues with the `typeof` operator
+                        // in older versions of Chrome and Safari which return 'function' for
+                        // regexes
+                        // and Safari 8 equivalents which return 'object' for typed array
+                        // constructors.
+                        return isObject(value) && objToString.call(value) == funcTag;
+                    }
+
+                    /**
+                     * Checks if `value` is the [language type](https://es5.github.io/#x8) of
+                     * `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and
+                     * `new String('')`)
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+                     * @example
+                     * 
+                     * _.isObject({}); // => true
+                     * 
+                     * _.isObject([1, 2, 3]); // => true
+                     * 
+                     * _.isObject(1); // => false
+                     */
+                    function isObject(value) {
+                        // Avoid a V8 JIT bug in Chrome 19-20.
+                        // See https://code.google.com/p/v8/issues/detail?id=2291 for more
+                        // details.
+                        var type = typeof value;
+                        return !!value && (type == 'object' || type == 'function');
+                    }
+
+                    /**
+                     * Performs a deep comparison between `object` and `source` to determine if
+                     * `object` contains equivalent property values. If `customizer` is provided
+                     * it is invoked to compare values. If `customizer` returns `undefined`
+                     * comparisons are handled by the method instead. The `customizer` is bound
+                     * to `thisArg` and invoked with three arguments: (value, other, index|key).
+                     * 
+                     * **Note:** This method supports comparing properties of arrays, booleans,
+                     * `Date` objects, numbers, `Object` objects, regexes, and strings.
+                     * Functions and DOM nodes are **not** supported. Provide a customizer
+                     * function to extend support for comparing other values.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {Object}
+                     *            object The object to inspect.
+                     * @param {Object}
+                     *            source The object of property values to match.
+                     * @param {Function}
+                     *            [customizer] The function to customize value comparisons.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred', 'age': 40 };
+                     * 
+                     * _.isMatch(object, { 'age': 40 }); // => true
+                     * 
+                     * _.isMatch(object, { 'age': 36 }); // => false
+                     *  // using a customizer callback var object = { 'greeting': 'hello' }; var
+                     * source = { 'greeting': 'hi' };
+                     * 
+                     * _.isMatch(object, source, function(value, other) { return _.every([value,
+                     * other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; }); // =>
+                     * true
+                     */
+                    function isMatch(object, source, customizer, thisArg) {
+                        customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
+                        return baseIsMatch(object, getMatchData(source), customizer);
+                    }
+
+                    /**
+                     * Checks if `value` is `NaN`.
+                     * 
+                     * **Note:** This method is not the same as
+                     * [`isNaN`](https://es5.github.io/#x15.1.2.4) which returns `true` for
+                     * `undefined` and other non-numeric values.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+                     * @example
+                     * 
+                     * _.isNaN(NaN); // => true
+                     * 
+                     * _.isNaN(new Number(NaN)); // => true
+                     * 
+                     * isNaN(undefined); // => true
+                     * 
+                     * _.isNaN(undefined); // => false
+                     */
+                    function isNaN(value) {
+                        // An `NaN` primitive is the only value that is not equal to itself.
+                        // Perform the `toStringTag` check first to avoid errors with some host
+                        // objects in IE.
+                        return isNumber(value) && value != +value;
+                    }
+
+                    /**
+                     * Checks if `value` is a native function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is a native function, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.isNative(Array.prototype.push); // => true
+                     * 
+                     * _.isNative(_); // => false
+                     */
+                    function isNative(value) {
+                        if (value == null) {
+                            return false;
+                        }
+                        if (isFunction(value)) {
+                            return reIsNative.test(fnToString.call(value));
+                        }
+                        return isObjectLike(value) && reIsHostCtor.test(value);
+                    }
+
+                    /**
+                     * Checks if `value` is `null`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
+                     * @example
+                     * 
+                     * _.isNull(null); // => true
+                     * 
+                     * _.isNull(void 0); // => false
+                     */
+                    function isNull(value) {
+                        return value === null;
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a `Number` primitive or object.
+                     * 
+                     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
+                     * classified as numbers, use the `_.isFinite` method.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isNumber(8.4); // => true
+                     * 
+                     * _.isNumber(NaN); // => true
+                     * 
+                     * _.isNumber('8.4'); // => false
+                     */
+                    function isNumber(value) {
+                        return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+                    }
+
+                    /**
+                     * Checks if `value` is a plain object, that is, an object created by the
+                     * `Object` constructor or one with a `[[Prototype]]` of `null`.
+                     * 
+                     * **Note:** This method assumes objects created by the `Object` constructor
+                     * have no inherited enumerable properties.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is a plain object, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; }
+                     * 
+                     * _.isPlainObject(new Foo); // => false
+                     * 
+                     * _.isPlainObject([1, 2, 3]); // => false
+                     * 
+                     * _.isPlainObject({ 'x': 0, 'y': 0 }); // => true
+                     * 
+                     * _.isPlainObject(Object.create(null)); // => true
+                     */
+                    function isPlainObject(value) {
+                        var Ctor;
+
+                        // Exit early for non `Object` objects.
+                        if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
+                            (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
+                            return false;
+                        }
+                        // IE < 9 iterates inherited properties before own properties. If the
+                        // first
+                        // iterated property is an object's own property then there are no
+                        // inherited
+                        // enumerable properties.
+                        var result;
+                        // In most environments an object's own properties are iterated before
+                        // its inherited properties. If the last iterated property is an
+                        // object's
+                        // own property then there are no inherited enumerable properties.
+                        baseForIn(value, function(subValue, key) {
+                            result = key;
+                        });
+                        return result === undefined || hasOwnProperty.call(value, result);
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a `RegExp` object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isRegExp(/abc/); // => true
+                     * 
+                     * _.isRegExp('/abc/'); // => false
+                     */
+                    function isRegExp(value) {
+                        return isObject(value) && objToString.call(value) == regexpTag;
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a `String` primitive or object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isString('abc'); // => true
+                     * 
+                     * _.isString(1); // => false
+                     */
+                    function isString(value) {
+                        return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+                    }
+
+                    /**
+                     * Checks if `value` is classified as a typed array.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is correctly classified,
+                     *          else `false`.
+                     * @example
+                     * 
+                     * _.isTypedArray(new Uint8Array); // => true
+                     * 
+                     * _.isTypedArray([]); // => false
+                     */
+                    function isTypedArray(value) {
+                        return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+                    }
+
+                    /**
+                     * Checks if `value` is `undefined`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to check.
+                     * @returns {boolean} Returns `true` if `value` is `undefined`, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.isUndefined(void 0); // => true
+                     * 
+                     * _.isUndefined(null); // => false
+                     */
+                    function isUndefined(value) {
+                        return value === undefined;
+                    }
+
+                    /**
+                     * Checks if `value` is less than `other`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @returns {boolean} Returns `true` if `value` is less than `other`, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.lt(1, 3); // => true
+                     * 
+                     * _.lt(3, 3); // => false
+                     * 
+                     * _.lt(3, 1); // => false
+                     */
+                    function lt(value, other) {
+                        return value < other;
+                    }
+
+                    /**
+                     * Checks if `value` is less than or equal to `other`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to compare.
+                     * @param {*}
+                     *            other The other value to compare.
+                     * @returns {boolean} Returns `true` if `value` is less than or equal to
+                     *          `other`, else `false`.
+                     * @example
+                     * 
+                     * _.lte(1, 3); // => true
+                     * 
+                     * _.lte(3, 3); // => true
+                     * 
+                     * _.lte(3, 1); // => false
+                     */
+                    function lte(value, other) {
+                        return value <= other;
+                    }
+
+                    /**
+                     * Converts `value` to an array.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to convert.
+                     * @returns {Array} Returns the converted array.
+                     * @example
+                     * 
+                     * (function() { return _.toArray(arguments).slice(1); }(1, 2, 3)); // =>
+                     * [2, 3]
+                     */
+                    function toArray(value) {
+                        var length = value ? getLength(value) : 0;
+                        if (!isLength(length)) {
+                            return values(value);
+                        }
+                        if (!length) {
+                            return [];
+                        }
+                        return arrayCopy(value);
+                    }
+
+                    /**
+                     * Converts `value` to a plain object flattening inherited enumerable
+                     * properties of `value` to own properties of the plain object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Lang
+                     * @param {*}
+                     *            value The value to convert.
+                     * @returns {Object} Returns the converted plain object.
+                     * @example
+                     * 
+                     * function Foo() { this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.assign({ 'a': 1 }, new Foo); // => { 'a': 1, 'b': 2 }
+                     * 
+                     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); // => { 'a': 1, 'b': 2,
+                     * 'c': 3 }
+                     */
+                    function toPlainObject(value) {
+                        return baseCopy(value, keysIn(value));
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Recursively merges own enumerable properties of the source object(s),
+                     * that don't resolve to `undefined` into the destination object. Subsequent
+                     * sources overwrite property assignments of previous sources. If
+                     * `customizer` is provided it is invoked to produce the merged values of
+                     * the destination and source properties. If `customizer` returns
+                     * `undefined` merging is handled by the method instead. The `customizer` is
+                     * bound to `thisArg` and invoked with five arguments: (objectValue,
+                     * sourceValue, key, object, source).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {...Object}
+                     *            [sources] The source objects.
+                     * @param {Function}
+                     *            [customizer] The function to customize assigned values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * var users = { 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] };
+                     * 
+                     * var ages = { 'data': [{ 'age': 36 }, { 'age': 40 }] };
+                     * 
+                     * _.merge(users, ages); // => { 'data': [{ 'user': 'barney', 'age': 36 }, {
+                     * 'user': 'fred', 'age': 40 }] }
+                     *  // using a customizer callback var object = { 'fruits': ['apple'],
+                     * 'vegetables': ['beet'] };
+                     * 
+                     * var other = { 'fruits': ['banana'], 'vegetables': ['carrot'] };
+                     * 
+                     * _.merge(object, other, function(a, b) { if (_.isArray(a)) { return
+                     * a.concat(b); } }); // => { 'fruits': ['apple', 'banana'], 'vegetables':
+                     * ['beet', 'carrot'] }
+                     */
+                    var merge = createAssigner(baseMerge);
+
+                    /**
+                     * Assigns own enumerable properties of source object(s) to the destination
+                     * object. Subsequent sources overwrite property assignments of previous
+                     * sources. If `customizer` is provided it is invoked to produce the
+                     * assigned values. The `customizer` is bound to `thisArg` and invoked with
+                     * five arguments: (objectValue, sourceValue, key, object, source).
+                     * 
+                     * **Note:** This method mutates `object` and is based on
+                     * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias extend
+                     * @category Object
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {...Object}
+                     *            [sources] The source objects.
+                     * @param {Function}
+                     *            [customizer] The function to customize assigned values.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `customizer`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); // => {
+                     * 'user': 'fred', 'age': 40 }
+                     *  // using a customizer callback var defaults = _.partialRight(_.assign,
+                     * function(value, other) { return _.isUndefined(value) ? other : value; });
+                     * 
+                     * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); // => {
+                     * 'user': 'barney', 'age': 36 }
+                     */
+                    var assign = createAssigner(function(object, source, customizer) {
+                        return customizer ? assignWith(object, source, customizer) : baseAssign(object, source);
+                    });
+
+                    /**
+                     * Creates an object that inherits from the given `prototype` object. If a
+                     * `properties` object is provided its own enumerable properties are
+                     * assigned to the created object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            prototype The object to inherit from.
+                     * @param {Object}
+                     *            [properties] The properties to assign to the object.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Object} Returns the new object.
+                     * @example
+                     * 
+                     * function Shape() { this.x = 0; this.y = 0; }
+                     * 
+                     * function Circle() { Shape.call(this); }
+                     * 
+                     * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
+                     * 
+                     * var circle = new Circle; circle instanceof Circle; // => true
+                     * 
+                     * circle instanceof Shape; // => true
+                     */
+                    function create(prototype, properties, guard) {
+                        var result = baseCreate(prototype);
+                        if (guard && isIterateeCall(prototype, properties, guard)) {
+                            properties = undefined;
+                        }
+                        return properties ? baseAssign(result, properties) : result;
+                    }
+
+                    /**
+                     * Assigns own enumerable properties of source object(s) to the destination
+                     * object for all destination properties that resolve to `undefined`. Once a
+                     * property is set, additional values of the same property are ignored.
+                     * 
+                     * **Note:** This method mutates `object`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {...Object}
+                     *            [sources] The source objects.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); // => {
+                     * 'user': 'barney', 'age': 36 }
+                     */
+                    var defaults = createDefaults(assign, assignDefaults);
+
+                    /**
+                     * This method is like `_.defaults` except that it recursively assigns
+                     * default properties.
+                     * 
+                     * **Note:** This method mutates `object`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The destination object.
+                     * @param {...Object}
+                     *            [sources] The source objects.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name':
+                     * 'fred', 'age': 36 } }); // => { 'user': { 'name': 'barney', 'age': 36 } }
+                     * 
+                     */
+                    var defaultsDeep = createDefaults(merge, mergeDefaults);
+
+                    /**
+                     * This method is like `_.find` except that it returns the key of the first
+                     * element `predicate` returns truthy for instead of the element itself.
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {string|undefined} Returns the key of the matched element, else
+                     *          `undefined`.
+                     * @example
+                     * 
+                     * var users = { 'barney': { 'age': 36, 'active': true }, 'fred': { 'age':
+                     * 40, 'active': false }, 'pebbles': { 'age': 1, 'active': true } };
+                     * 
+                     * _.findKey(users, function(chr) { return chr.age < 40; }); // => 'barney'
+                     * (iteration order is not guaranteed)
+                     *  // using the `_.matches` callback shorthand _.findKey(users, { 'age': 1,
+                     * 'active': true }); // => 'pebbles'
+                     *  // using the `_.matchesProperty` callback shorthand _.findKey(users,
+                     * 'active', false); // => 'fred'
+                     *  // using the `_.property` callback shorthand _.findKey(users, 'active'); // =>
+                     * 'barney'
+                     */
+                    var findKey = createFindKey(baseForOwn);
+
+                    /**
+                     * This method is like `_.findKey` except that it iterates over elements of
+                     * a collection in the opposite order.
+                     * 
+                     * If a property name is provided for `predicate` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `predicate` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to search.
+                     * @param {Function|Object|string}
+                     *            [predicate=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {string|undefined} Returns the key of the matched element, else
+                     *          `undefined`.
+                     * @example
+                     * 
+                     * var users = { 'barney': { 'age': 36, 'active': true }, 'fred': { 'age':
+                     * 40, 'active': false }, 'pebbles': { 'age': 1, 'active': true } };
+                     * 
+                     * _.findLastKey(users, function(chr) { return chr.age < 40; }); // =>
+                     * returns `pebbles` assuming `_.findKey` returns `barney`
+                     *  // using the `_.matches` callback shorthand _.findLastKey(users, {
+                     * 'age': 36, 'active': true }); // => 'barney'
+                     *  // using the `_.matchesProperty` callback shorthand _.findLastKey(users,
+                     * 'active', false); // => 'fred'
+                     *  // using the `_.property` callback shorthand _.findLastKey(users,
+                     * 'active'); // => 'pebbles'
+                     */
+                    var findLastKey = createFindKey(baseForOwnRight);
+
+                    /**
+                     * Iterates over own and inherited enumerable properties of an object
+                     * invoking `iteratee` for each property. The `iteratee` is bound to
+                     * `thisArg` and invoked with three arguments: (value, key, object).
+                     * Iteratee functions may exit iteration early by explicitly returning
+                     * `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.forIn(new Foo, function(value, key) { console.log(key); }); // => logs
+                     * 'a', 'b', and 'c' (iteration order is not guaranteed)
+                     */
+                    var forIn = createForIn(baseFor);
+
+                    /**
+                     * This method is like `_.forIn` except that it iterates over properties of
+                     * `object` in the opposite order.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.forInRight(new Foo, function(value, key) { console.log(key); }); // =>
+                     * logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c'
+                     */
+                    var forInRight = createForIn(baseForRight);
+
+                    /**
+                     * Iterates over own enumerable properties of an object invoking `iteratee`
+                     * for each property. The `iteratee` is bound to `thisArg` and invoked with
+                     * three arguments: (value, key, object). Iteratee functions may exit
+                     * iteration early by explicitly returning `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.forOwn(new Foo, function(value, key) { console.log(key); }); // => logs
+                     * 'a' and 'b' (iteration order is not guaranteed)
+                     */
+                    var forOwn = createForOwn(baseForOwn);
+
+                    /**
+                     * This method is like `_.forOwn` except that it iterates over properties of
+                     * `object` in the opposite order.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.forOwnRight(new Foo, function(value, key) { console.log(key); }); // =>
+                     * logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b'
+                     */
+                    var forOwnRight = createForOwn(baseForOwnRight);
+
+                    /**
+                     * Creates an array of function property names from all enumerable
+                     * properties, own and inherited, of `object`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias methods
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to inspect.
+                     * @returns {Array} Returns the new array of property names.
+                     * @example
+                     * 
+                     * _.functions(_); // => ['after', 'ary', 'assign', ...]
+                     */
+                    function functions(object) {
+                        return baseFunctions(object, keysIn(object));
+                    }
+
+                    /**
+                     * Gets the property value at `path` of `object`. If the resolved value is
+                     * `undefined` the `defaultValue` is used in its place.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array|string}
+                     *            path The path of the property to get.
+                     * @param {*}
+                     *            [defaultValue] The value returned if the resolved value is
+                     *            `undefined`.
+                     * @returns {*} Returns the resolved value.
+                     * @example
+                     * 
+                     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+                     * 
+                     * _.get(object, 'a[0].b.c'); // => 3
+                     * 
+                     * _.get(object, ['a', '0', 'b', 'c']); // => 3
+                     * 
+                     * _.get(object, 'a.b.c', 'default'); // => 'default'
+                     */
+                    function get(object, path, defaultValue) {
+                        var result = object == null ? undefined : baseGet(object, toPath(path), path + '');
+                        return result === undefined ? defaultValue : result;
+                    }
+
+                    /**
+                     * Checks if `path` is a direct property.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array|string}
+                     *            path The path to check.
+                     * @returns {boolean} Returns `true` if `path` is a direct property, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * var object = { 'a': { 'b': { 'c': 3 } } };
+                     * 
+                     * _.has(object, 'a'); // => true
+                     * 
+                     * _.has(object, 'a.b.c'); // => true
+                     * 
+                     * _.has(object, ['a', 'b', 'c']); // => true
+                     */
+                    function has(object, path) {
+                        if (object == null) {
+                            return false;
+                        }
+                        var result = hasOwnProperty.call(object, path);
+                        if (!result && !isKey(path)) {
+                            path = toPath(path);
+                            object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+                            if (object == null) {
+                                return false;
+                            }
+                            path = last(path);
+                            result = hasOwnProperty.call(object, path);
+                        }
+                        return result || (isLength(object.length) && isIndex(path, object.length) &&
+                            (isArray(object) || isArguments(object)));
+                    }
+
+                    /**
+                     * Creates an object composed of the inverted keys and values of `object`.
+                     * If `object` contains duplicate values, subsequent values overwrite
+                     * property assignments of previous values unless `multiValue` is `true`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to invert.
+                     * @param {boolean}
+                     *            [multiValue] Allow multiple values per key.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Object} Returns the new inverted object.
+                     * @example
+                     * 
+                     * var object = { 'a': 1, 'b': 2, 'c': 1 };
+                     * 
+                     * _.invert(object); // => { '1': 'c', '2': 'b' }
+                     *  // with `multiValue` _.invert(object, true); // => { '1': ['a', 'c'],
+                     * '2': ['b'] }
+                     */
+                    function invert(object, multiValue, guard) {
+                        if (guard && isIterateeCall(object, multiValue, guard)) {
+                            multiValue = undefined;
+                        }
+                        var index = -1,
+                            props = keys(object),
+                            length = props.length,
+                            result = {};
+
+                        while (++index < length) {
+                            var key = props[index],
+                                value = object[key];
+
+                            if (multiValue) {
+                                if (hasOwnProperty.call(result, value)) {
+                                    result[value].push(key);
+                                } else {
+                                    result[value] = [key];
+                                }
+                            } else {
+                                result[value] = key;
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Creates an array of the own enumerable property names of `object`.
+                     * 
+                     * **Note:** Non-object values are coerced to objects. See the [ES
+                     * spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) for
+                     * more details.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the array of property names.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.keys(new Foo); // => ['a', 'b'] (iteration order is not guaranteed)
+                     * 
+                     * _.keys('hi'); // => ['0', '1']
+                     */
+                    var keys = !nativeKeys ? shimKeys : function(object) {
+                        var Ctor = object == null ? undefined : object.constructor;
+                        if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+                            (typeof object != 'function' && isArrayLike(object))) {
+                            return shimKeys(object);
+                        }
+                        return isObject(object) ? nativeKeys(object) : [];
+                    };
+
+                    /**
+                     * Creates an array of the own and inherited enumerable property names of
+                     * `object`.
+                     * 
+                     * **Note:** Non-object values are coerced to objects.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the array of property names.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.keysIn(new Foo); // => ['a', 'b', 'c'] (iteration order is not
+                     * guaranteed)
+                     */
+                    function keysIn(object) {
+                        if (object == null) {
+                            return [];
+                        }
+                        if (!isObject(object)) {
+                            object = Object(object);
+                        }
+                        var length = object.length;
+                        length = (length && isLength(length) &&
+                            (isArray(object) || isArguments(object)) && length) || 0;
+
+                        var Ctor = object.constructor,
+                            index = -1,
+                            isProto = typeof Ctor == 'function' && Ctor.prototype === object,
+                            result = Array(length),
+                            skipIndexes = length > 0;
+
+                        while (++index < length) {
+                            result[index] = (index + '');
+                        }
+                        for (var key in object) {
+                            if (!(skipIndexes && isIndex(key, length)) &&
+                                !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+                                result.push(key);
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * The opposite of `_.mapValues`; this method creates an object with the
+                     * same values as `object` and keys generated by running each own enumerable
+                     * property of `object` through `iteratee`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns the new mapped object.
+                     * @example
+                     * 
+                     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { return key + value;
+                     * }); // => { 'a1': 1, 'b2': 2 }
+                     */
+                    var mapKeys = createObjectMapper(true);
+
+                    /**
+                     * Creates an object with the same keys as `object` and values generated by
+                     * running each own enumerable property of `object` through `iteratee`. The
+                     * iteratee function is bound to `thisArg` and invoked with three arguments:
+                     * (value, key, object).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Object} Returns the new mapped object.
+                     * @example
+                     * 
+                     * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { return n * 3; }); // => {
+                     * 'a': 3, 'b': 6 }
+                     * 
+                     * var users = { 'fred': { 'user': 'fred', 'age': 40 }, 'pebbles': { 'user':
+                     * 'pebbles', 'age': 1 } };
+                     *  // using the `_.property` callback shorthand _.mapValues(users, 'age'); // => {
+                     * 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
+                     */
+                    var mapValues = createObjectMapper();
+
+                    /**
+                     * The opposite of `_.pick`; this method creates an object composed of the
+                     * own and inherited enumerable properties of `object` that are not omitted.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The source object.
+                     * @param {Function|...(string|string[])}
+                     *            [predicate] The function invoked per iteration or property
+                     *            names to omit, specified as individual property names or
+                     *            arrays of property names.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Object} Returns the new object.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred', 'age': 40 };
+                     * 
+                     * _.omit(object, 'age'); // => { 'user': 'fred' }
+                     * 
+                     * _.omit(object, _.isNumber); // => { 'user': 'fred' }
+                     */
+                    var omit = restParam(function(object, props) {
+                        if (object == null) {
+                            return {};
+                        }
+                        if (typeof props[0] != 'function') {
+                            var props = arrayMap(baseFlatten(props), String);
+                            return pickByArray(object, baseDifference(keysIn(object), props));
+                        }
+                        var predicate = bindCallback(props[0], props[1], 3);
+                        return pickByCallback(object, function(value, key, object) {
+                            return !predicate(value, key, object);
+                        });
+                    });
+
+                    /**
+                     * Creates a two dimensional array of the key-value pairs for `object`, e.g.
+                     * `[[key1, value1], [key2, value2]]`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the new array of key-value pairs.
+                     * @example
+                     * 
+                     * _.pairs({ 'barney': 36, 'fred': 40 }); // => [['barney', 36], ['fred',
+                     * 40]] (iteration order is not guaranteed)
+                     */
+                    function pairs(object) {
+                        object = toObject(object);
+
+                        var index = -1,
+                            props = keys(object),
+                            length = props.length,
+                            result = Array(length);
+
+                        while (++index < length) {
+                            var key = props[index];
+                            result[index] = [key, object[key]];
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Creates an object composed of the picked `object` properties. Property
+                     * names may be specified as individual arguments or as arrays of property
+                     * names. If `predicate` is provided it is invoked for each property of
+                     * `object` picking the properties `predicate` returns truthy for. The
+                     * predicate is bound to `thisArg` and invoked with three arguments: (value,
+                     * key, object).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The source object.
+                     * @param {Function|...(string|string[])}
+                     *            [predicate] The function invoked per iteration or property
+                     *            names to pick, specified as individual property names or
+                     *            arrays of property names.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `predicate`.
+                     * @returns {Object} Returns the new object.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred', 'age': 40 };
+                     * 
+                     * _.pick(object, 'user'); // => { 'user': 'fred' }
+                     * 
+                     * _.pick(object, _.isString); // => { 'user': 'fred' }
+                     */
+                    var pick = restParam(function(object, props) {
+                        if (object == null) {
+                            return {};
+                        }
+                        return typeof props[0] == 'function' ? pickByCallback(object, bindCallback(props[0], props[1], 3)) : pickByArray(object, baseFlatten(props));
+                    });
+
+                    /**
+                     * This method is like `_.get` except that if the resolved value is a
+                     * function it is invoked with the `this` binding of its parent object and
+                     * its result is returned.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {Array|string}
+                     *            path The path of the property to resolve.
+                     * @param {*}
+                     *            [defaultValue] The value returned if the resolved value is
+                     *            `undefined`.
+                     * @returns {*} Returns the resolved value.
+                     * @example
+                     * 
+                     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
+                     * 
+                     * _.result(object, 'a[0].b.c1'); // => 3
+                     * 
+                     * _.result(object, 'a[0].b.c2'); // => 4
+                     * 
+                     * _.result(object, 'a.b.c', 'default'); // => 'default'
+                     * 
+                     * _.result(object, 'a.b.c', _.constant('default')); // => 'default'
+                     */
+                    function result(object, path, defaultValue) {
+                        var result = object == null ? undefined : object[path];
+                        if (result === undefined) {
+                            if (object != null && !isKey(path, object)) {
+                                path = toPath(path);
+                                object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+                                result = object == null ? undefined : object[last(path)];
+                            }
+                            result = result === undefined ? defaultValue : result;
+                        }
+                        return isFunction(result) ? result.call(object) : result;
+                    }
+
+                    /**
+                     * Sets the property value of `path` on `object`. If a portion of `path`
+                     * does not exist it is created.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to augment.
+                     * @param {Array|string}
+                     *            path The path of the property to set.
+                     * @param {*}
+                     *            value The value to set.
+                     * @returns {Object} Returns `object`.
+                     * @example
+                     * 
+                     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+                     * 
+                     * _.set(object, 'a[0].b.c', 4); console.log(object.a[0].b.c); // => 4
+                     * 
+                     * _.set(object, 'x[0].y.z', 5); console.log(object.x[0].y.z); // => 5
+                     */
+                    function set(object, path, value) {
+                        if (object == null) {
+                            return object;
+                        }
+                        var pathKey = (path + '');
+                        path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path);
+
+                        var index = -1,
+                            length = path.length,
+                            lastIndex = length - 1,
+                            nested = object;
+
+                        while (nested != null && ++index < length) {
+                            var key = path[index];
+                            if (isObject(nested)) {
+                                if (index == lastIndex) {
+                                    nested[key] = value;
+                                } else if (nested[key] == null) {
+                                    nested[key] = isIndex(path[index + 1]) ? [] : {};
+                                }
+                            }
+                            nested = nested[key];
+                        }
+                        return object;
+                    }
+
+                    /**
+                     * An alternative to `_.reduce`; this method transforms `object` to a new
+                     * `accumulator` object which is the result of running each of its own
+                     * enumerable properties through `iteratee`, with each invocation
+                     * potentially mutating the `accumulator` object. The `iteratee` is bound to
+                     * `thisArg` and invoked with four arguments: (accumulator, value, key,
+                     * object). Iteratee functions may exit iteration early by explicitly
+                     * returning `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Array|Object}
+                     *            object The object to iterate over.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [accumulator] The custom accumulator value.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {*} Returns the accumulated value.
+                     * @example
+                     * 
+                     * _.transform([2, 3, 4], function(result, n) { result.push(n *= n); return
+                     * n % 2 == 0; }); // => [4, 9]
+                     * 
+                     * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { result[key] =
+                     * n * 3; }); // => { 'a': 3, 'b': 6 }
+                     */
+                    function transform(object, iteratee, accumulator, thisArg) {
+                        var isArr = isArray(object) || isTypedArray(object);
+                        iteratee = getCallback(iteratee, thisArg, 4);
+
+                        if (accumulator == null) {
+                            if (isArr || isObject(object)) {
+                                var Ctor = object.constructor;
+                                if (isArr) {
+                                    accumulator = isArray(object) ? new Ctor : [];
+                                } else {
+                                    accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
+                                }
+                            } else {
+                                accumulator = {};
+                            }
+                        }
+                        (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
+                            return iteratee(accumulator, value, index, object);
+                        });
+                        return accumulator;
+                    }
+
+                    /**
+                     * Creates an array of the own enumerable property values of `object`.
+                     * 
+                     * **Note:** Non-object values are coerced to objects.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the array of property values.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.values(new Foo); // => [1, 2] (iteration order is not guaranteed)
+                     * 
+                     * _.values('hi'); // => ['h', 'i']
+                     */
+                    function values(object) {
+                        return baseValues(object, keys(object));
+                    }
+
+                    /**
+                     * Creates an array of the own and inherited enumerable property values of
+                     * `object`.
+                     * 
+                     * **Note:** Non-object values are coerced to objects.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Object
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Array} Returns the array of property values.
+                     * @example
+                     * 
+                     * function Foo() { this.a = 1; this.b = 2; }
+                     * 
+                     * Foo.prototype.c = 3;
+                     * 
+                     * _.valuesIn(new Foo); // => [1, 2, 3] (iteration order is not guaranteed)
+                     */
+                    function valuesIn(object) {
+                        return baseValues(object, keysIn(object));
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Checks if `n` is between `start` and up to but not including, `end`. If
+                     * `end` is not specified it is set to `start` with `start` then set to `0`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Number
+                     * @param {number}
+                     *            n The number to check.
+                     * @param {number}
+                     *            [start=0] The start of the range.
+                     * @param {number}
+                     *            end The end of the range.
+                     * @returns {boolean} Returns `true` if `n` is in the range, else `false`.
+                     * @example
+                     * 
+                     * _.inRange(3, 2, 4); // => true
+                     * 
+                     * _.inRange(4, 8); // => true
+                     * 
+                     * _.inRange(4, 2); // => false
+                     * 
+                     * _.inRange(2, 2); // => false
+                     * 
+                     * _.inRange(1.2, 2); // => true
+                     * 
+                     * _.inRange(5.2, 4); // => false
+                     */
+                    function inRange(value, start, end) {
+                        start = +start || 0;
+                        if (end === undefined) {
+                            end = start;
+                            start = 0;
+                        } else {
+                            end = +end || 0;
+                        }
+                        return value >= nativeMin(start, end) && value < nativeMax(start, end);
+                    }
+
+                    /**
+                     * Produces a random number between `min` and `max` (inclusive). If only one
+                     * argument is provided a number between `0` and the given number is
+                     * returned. If `floating` is `true`, or either `min` or `max` are floats, a
+                     * floating-point number is returned instead of an integer.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Number
+                     * @param {number}
+                     *            [min=0] The minimum possible value.
+                     * @param {number}
+                     *            [max=1] The maximum possible value.
+                     * @param {boolean}
+                     *            [floating] Specify returning a floating-point number.
+                     * @returns {number} Returns the random number.
+                     * @example
+                     * 
+                     * _.random(0, 5); // => an integer between 0 and 5
+                     * 
+                     * _.random(5); // => also an integer between 0 and 5
+                     * 
+                     * _.random(5, true); // => a floating-point number between 0 and 5
+                     * 
+                     * _.random(1.2, 5.2); // => a floating-point number between 1.2 and 5.2
+                     */
+                    function random(min, max, floating) {
+                        if (floating && isIterateeCall(min, max, floating)) {
+                            max = floating = undefined;
+                        }
+                        var noMin = min == null,
+                            noMax = max == null;
+
+                        if (floating == null) {
+                            if (noMax && typeof min == 'boolean') {
+                                floating = min;
+                                min = 1;
+                            } else if (typeof max == 'boolean') {
+                                floating = max;
+                                noMax = true;
+                            }
+                        }
+                        if (noMin && noMax) {
+                            max = 1;
+                            noMax = false;
+                        }
+                        min = +min || 0;
+                        if (noMax) {
+                            max = min;
+                            min = 0;
+                        } else {
+                            max = +max || 0;
+                        }
+                        if (floating || min % 1 || max % 1) {
+                            var rand = nativeRandom();
+                            return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max);
+                        }
+                        return baseRandom(min, max);
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Converts `string` to [camel
+                     * case](https://en.wikipedia.org/wiki/CamelCase).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to convert.
+                     * @returns {string} Returns the camel cased string.
+                     * @example
+                     * 
+                     * _.camelCase('Foo Bar'); // => 'fooBar'
+                     * 
+                     * _.camelCase('--foo-bar'); // => 'fooBar'
+                     * 
+                     * _.camelCase('__foo_bar__'); // => 'fooBar'
+                     */
+                    var camelCase = createCompounder(function(result, word, index) {
+                        word = word.toLowerCase();
+                        return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
+                    });
+
+                    /**
+                     * Capitalizes the first character of `string`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to capitalize.
+                     * @returns {string} Returns the capitalized string.
+                     * @example
+                     * 
+                     * _.capitalize('fred'); // => 'Fred'
+                     */
+                    function capitalize(string) {
+                        string = baseToString(string);
+                        return string && (string.charAt(0).toUpperCase() + string.slice(1));
+                    }
+
+                    /**
+                     * Deburrs `string` by converting [latin-1 supplementary
+                     * letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+                     * to basic latin letters and removing [combining diacritical
+                     * marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to deburr.
+                     * @returns {string} Returns the deburred string.
+                     * @example
+                     * 
+                     * _.deburr('déjà vu'); // => 'deja vu'
+                     */
+                    function deburr(string) {
+                        string = baseToString(string);
+                        return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
+                    }
+
+                    /**
+                     * Checks if `string` ends with the given target string.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to search.
+                     * @param {string}
+                     *            [target] The string to search for.
+                     * @param {number}
+                     *            [position=string.length] The position to search from.
+                     * @returns {boolean} Returns `true` if `string` ends with `target`, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.endsWith('abc', 'c'); // => true
+                     * 
+                     * _.endsWith('abc', 'b'); // => false
+                     * 
+                     * _.endsWith('abc', 'b', 2); // => true
+                     */
+                    function endsWith(string, target, position) {
+                        string = baseToString(string);
+                        target = (target + '');
+
+                        var length = string.length;
+                        position = position === undefined ? length : nativeMin(position < 0 ? 0 : (+position || 0), length);
+
+                        position -= target.length;
+                        return position >= 0 && string.indexOf(target, position) == position;
+                    }
+
+                    /**
+                     * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string`
+                     * to their corresponding HTML entities.
+                     * 
+                     * **Note:** No other characters are escaped. To escape additional
+                     * characters use a third-party library like [_he_](https://mths.be/he).
+                     * 
+                     * Though the ">" character is escaped for symmetry, characters like ">" and
+                     * "/" don't need escaping in HTML and have no special meaning unless
+                     * they're part of a tag or unquoted attribute value. See [Mathias Bynens's
+                     * article](https://mathiasbynens.be/notes/ambiguous-ampersands) (under
+                     * "semi-related fun fact") for more details.
+                     * 
+                     * Backticks are escaped because in Internet Explorer < 9, they can break
+                     * out of attribute values or HTML comments. See
+                     * [#59](https://html5sec.org/#59), [#102](https://html5sec.org/#102),
+                     * [#108](https://html5sec.org/#108), and [#133](https://html5sec.org/#133)
+                     * of the [HTML5 Security Cheatsheet](https://html5sec.org/) for more
+                     * details.
+                     * 
+                     * When working with HTML you should always [quote attribute
+                     * values](http://wonko.com/post/html-escaping) to reduce XSS vectors.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to escape.
+                     * @returns {string} Returns the escaped string.
+                     * @example
+                     * 
+                     * _.escape('fred, barney, & pebbles'); // => 'fred, barney, &amp; pebbles'
+                     */
+                    function escape(string) {
+                        // Reset `lastIndex` because in IE < 9 `String#replace` does not.
+                        string = baseToString(string);
+                        return (string && reHasUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string;
+                    }
+
+                    /**
+                     * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|",
+                     * "?", "*", "+", "(", ")", "[", "]", "{" and "}" in `string`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to escape.
+                     * @returns {string} Returns the escaped string.
+                     * @example
+                     * 
+                     * _.escapeRegExp('[lodash](https://lodash.com/)'); // =>
+                     * '\[lodash\]\(https:\/\/lodash\.com\/\)'
+                     */
+                    function escapeRegExp(string) {
+                        string = baseToString(string);
+                        return (string && reHasRegExpChars.test(string)) ? string.replace(reRegExpChars, escapeRegExpChar) : (string || '(?:)');
+                    }
+
+                    /**
+                     * Converts `string` to [kebab
+                     * case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to convert.
+                     * @returns {string} Returns the kebab cased string.
+                     * @example
+                     * 
+                     * _.kebabCase('Foo Bar'); // => 'foo-bar'
+                     * 
+                     * _.kebabCase('fooBar'); // => 'foo-bar'
+                     * 
+                     * _.kebabCase('__foo_bar__'); // => 'foo-bar'
+                     */
+                    var kebabCase = createCompounder(function(result, word, index) {
+                        return result + (index ? '-' : '') + word.toLowerCase();
+                    });
+
+                    /**
+                     * Pads `string` on the left and right sides if it's shorter than `length`.
+                     * Padding characters are truncated if they can't be evenly divided by
+                     * `length`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to pad.
+                     * @param {number}
+                     *            [length=0] The padding length.
+                     * @param {string}
+                     *            [chars=' '] The string used as padding.
+                     * @returns {string} Returns the padded string.
+                     * @example
+                     * 
+                     * _.pad('abc', 8); // => ' abc '
+                     * 
+                     * _.pad('abc', 8, '_-'); // => '_-abc_-_'
+                     * 
+                     * _.pad('abc', 3); // => 'abc'
+                     */
+                    function pad(string, length, chars) {
+                        string = baseToString(string);
+                        length = +length;
+
+                        var strLength = string.length;
+                        if (strLength >= length || !nativeIsFinite(length)) {
+                            return string;
+                        }
+                        var mid = (length - strLength) / 2,
+                            leftLength = nativeFloor(mid),
+                            rightLength = nativeCeil(mid);
+
+                        chars = createPadding('', rightLength, chars);
+                        return chars.slice(0, leftLength) + string + chars;
+                    }
+
+                    /**
+                     * Pads `string` on the left side if it's shorter than `length`. Padding
+                     * characters are truncated if they exceed `length`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to pad.
+                     * @param {number}
+                     *            [length=0] The padding length.
+                     * @param {string}
+                     *            [chars=' '] The string used as padding.
+                     * @returns {string} Returns the padded string.
+                     * @example
+                     * 
+                     * _.padLeft('abc', 6); // => ' abc'
+                     * 
+                     * _.padLeft('abc', 6, '_-'); // => '_-_abc'
+                     * 
+                     * _.padLeft('abc', 3); // => 'abc'
+                     */
+                    var padLeft = createPadDir();
+
+                    /**
+                     * Pads `string` on the right side if it's shorter than `length`. Padding
+                     * characters are truncated if they exceed `length`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to pad.
+                     * @param {number}
+                     *            [length=0] The padding length.
+                     * @param {string}
+                     *            [chars=' '] The string used as padding.
+                     * @returns {string} Returns the padded string.
+                     * @example
+                     * 
+                     * _.padRight('abc', 6); // => 'abc '
+                     * 
+                     * _.padRight('abc', 6, '_-'); // => 'abc_-_'
+                     * 
+                     * _.padRight('abc', 3); // => 'abc'
+                     */
+                    var padRight = createPadDir(true);
+
+                    /**
+                     * Converts `string` to an integer of the specified radix. If `radix` is
+                     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
+                     * hexadecimal, in which case a `radix` of `16` is used.
+                     * 
+                     * **Note:** This method aligns with the [ES5
+                     * implementation](https://es5.github.io/#E) of `parseInt`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            string The string to convert.
+                     * @param {number}
+                     *            [radix] The radix to interpret `value` by.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {number} Returns the converted integer.
+                     * @example
+                     * 
+                     * _.parseInt('08'); // => 8
+                     * 
+                     * _.map(['6', '08', '10'], _.parseInt); // => [6, 8, 10]
+                     */
+                    function parseInt(string, radix, guard) {
+                        // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`.
+                        // Chrome fails to trim leading <BOM> whitespace characters.
+                        // See https://code.google.com/p/v8/issues/detail?id=3109 for more
+                        // details.
+                        if (guard ? isIterateeCall(string, radix, guard) : radix == null) {
+                            radix = 0;
+                        } else if (radix) {
+                            radix = +radix;
+                        }
+                        string = trim(string);
+                        return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
+                    }
+
+                    /**
+                     * Repeats the given string `n` times.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to repeat.
+                     * @param {number}
+                     *            [n=0] The number of times to repeat the string.
+                     * @returns {string} Returns the repeated string.
+                     * @example
+                     * 
+                     * _.repeat('*', 3); // => '***'
+                     * 
+                     * _.repeat('abc', 2); // => 'abcabc'
+                     * 
+                     * _.repeat('abc', 0); // => ''
+                     */
+                    function repeat(string, n) {
+                        var result = '';
+                        string = baseToString(string);
+                        n = +n;
+                        if (n < 1 || !string || !nativeIsFinite(n)) {
+                            return result;
+                        }
+                        // Leverage the exponentiation by squaring algorithm for a faster
+                        // repeat.
+                        // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more
+                        // details.
+                        do {
+                            if (n % 2) {
+                                result += string;
+                            }
+                            n = nativeFloor(n / 2);
+                            string += string;
+                        } while (n);
+
+                        return result;
+                    }
+
+                    /**
+                     * Converts `string` to [snake
+                     * case](https://en.wikipedia.org/wiki/Snake_case).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to convert.
+                     * @returns {string} Returns the snake cased string.
+                     * @example
+                     * 
+                     * _.snakeCase('Foo Bar'); // => 'foo_bar'
+                     * 
+                     * _.snakeCase('fooBar'); // => 'foo_bar'
+                     * 
+                     * _.snakeCase('--foo-bar'); // => 'foo_bar'
+                     */
+                    var snakeCase = createCompounder(function(result, word, index) {
+                        return result + (index ? '_' : '') + word.toLowerCase();
+                    });
+
+                    /**
+                     * Converts `string` to [start
+                     * case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to convert.
+                     * @returns {string} Returns the start cased string.
+                     * @example
+                     * 
+                     * _.startCase('--foo-bar'); // => 'Foo Bar'
+                     * 
+                     * _.startCase('fooBar'); // => 'Foo Bar'
+                     * 
+                     * _.startCase('__foo_bar__'); // => 'Foo Bar'
+                     */
+                    var startCase = createCompounder(function(result, word, index) {
+                        return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
+                    });
+
+                    /**
+                     * Checks if `string` starts with the given target string.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to search.
+                     * @param {string}
+                     *            [target] The string to search for.
+                     * @param {number}
+                     *            [position=0] The position to search from.
+                     * @returns {boolean} Returns `true` if `string` starts with `target`, else
+                     *          `false`.
+                     * @example
+                     * 
+                     * _.startsWith('abc', 'a'); // => true
+                     * 
+                     * _.startsWith('abc', 'b'); // => false
+                     * 
+                     * _.startsWith('abc', 'b', 1); // => true
+                     */
+                    function startsWith(string, target, position) {
+                        string = baseToString(string);
+                        position = position == null ? 0 : nativeMin(position < 0 ? 0 : (+position || 0), string.length);
+
+                        return string.lastIndexOf(target, position) == position;
+                    }
+
+                    /**
+                     * Creates a compiled template function that can interpolate data properties
+                     * in "interpolate" delimiters, HTML-escape interpolated data properties in
+                     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters.
+                     * Data properties may be accessed as free variables in the template. If a
+                     * setting object is provided it takes precedence over `_.templateSettings`
+                     * values.
+                     * 
+                     * **Note:** In the development build `_.template` utilizes
+                     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+                     * for easier debugging.
+                     * 
+                     * For more information on precompiling templates see [lodash's custom
+                     * builds documentation](https://lodash.com/custom-builds).
+                     * 
+                     * For more information on Chrome extension sandboxes see [Chrome's
+                     * extensions
+                     * documentation](https://developer.chrome.com/extensions/sandboxingEval).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The template string.
+                     * @param {Object}
+                     *            [options] The options object.
+                     * @param {RegExp}
+                     *            [options.escape] The HTML "escape" delimiter.
+                     * @param {RegExp}
+                     *            [options.evaluate] The "evaluate" delimiter.
+                     * @param {Object}
+                     *            [options.imports] An object to import into the template as
+                     *            free variables.
+                     * @param {RegExp}
+                     *            [options.interpolate] The "interpolate" delimiter.
+                     * @param {string}
+                     *            [options.sourceURL] The sourceURL of the template's compiled
+                     *            source.
+                     * @param {string}
+                     *            [options.variable] The data object variable name.
+                     * @param- {Object} [otherOptions] Enables the legacy `options` param
+                     *         signature.
+                     * @returns {Function} Returns the compiled template function.
+                     * @example
+                     *  // using the "interpolate" delimiter to create a compiled
+                     * template var compiled = _.template('hello <%= user %>!'); compiled({
+                     * 'user': 'fred' }); // => 'hello fred!'
+                     *  // using the HTML "escape" delimiter to escape data property values var
+                     * compiled = _.template('<b><%- value %></b>'); compiled({ 'value': '<script>'
+                     * }); // => '<b>&lt;script&gt;</b>'
+                     *  // using the "evaluate" delimiter to execute JavaScript and generate
+                     * HTML var compiled = _.template('<% _.forEach(users, function(user) { %>
+                     * <li><%- user %></li><% }); %>'); compiled({ 'users': ['fred',
+                     * 'barney'] }); // => '
+                     * <li>fred</li>
+                     * <li>barney</li>'
+                     *  // using the internal `print` function in "evaluate" delimiters var
+                     * compiled = _.template('<% print("hello " + user); %>!'); compiled({
+                     * 'user': 'barney' }); // => 'hello barney!'
+                     *  // using the ES delimiter as an alternative to the default "interpolate"
+                     * delimiter var compiled = _.template('hello ${ user }!'); compiled({
+                     * 'user': 'pebbles' }); // => 'hello pebbles!'
+                     *  // using custom template delimiters _.templateSettings.interpolate =
+                     * /{{([\s\S]+?)}}/g; var compiled = _.template('hello {{ user }}!');
+                     * compiled({ 'user': 'mustache' }); // => 'hello mustache!'
+                     *  // using backslashes to treat delimiters as plain text var compiled =
+                     * _.template('<%= "\\<%- value %\\>" %>'); compiled({ 'value': 'ignored'
+                     * }); // => '<%- value %>'
+                     *  // using the `imports` option to import `jQuery` as `jq` var text = '<%
+                     * jq.each(users, function(user) { %>
+                     * <li><%- user %></li><% }); %>'; var compiled = _.template(text, {
+                     * 'imports': { 'jq': jQuery } }); compiled({ 'users': ['fred', 'barney']
+                     * }); // => '
+                     * <li>fred</li>
+                     * <li>barney</li>'
+                     *  // using the `sourceURL` option to specify a custom sourceURL for the
+                     * template var compiled = _.template('hello <%= user %>!', { 'sourceURL':
+                     * '/basic/greeting.jst' }); compiled(data); // => find the source of
+                     * "greeting.jst" under the Sources tab or Resources panel of the web
+                     * inspector
+                     *  // using the `variable` option to ensure a with-statement isn't used in
+                     * the compiled template var compiled = _.template('hi <%= data.user %>!', {
+                     * 'variable': 'data' }); compiled.source; // => function(data) { // var
+                     * __t, __p = ''; // __p += 'hi ' + ((__t = ( data.user )) == null ? '' :
+                     * __t) + '!'; // return __p; // }
+                     *  // using the `source` property to inline compiled templates for
+                     * meaningful // line numbers in error messages and a stack trace
+                     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ var JST = {\ "main": ' +
+                     * _.template(mainText).source + '\ };\ ');
+                     */
+                    function template(string, options, otherOptions) {
+                        // Based on John Resig's `tmpl` implementation
+                        // (http://ejohn.org/blog/javascript-micro-templating/)
+                        // and Laura Doktorova's doT.js (https://github.com/olado/doT).
+                        var settings = lodash.templateSettings;
+
+                        if (otherOptions && isIterateeCall(string, options, otherOptions)) {
+                            options = otherOptions = undefined;
+                        }
+                        string = baseToString(string);
+                        options = assignWith(baseAssign({}, otherOptions || options), settings, assignOwnDefaults);
+
+                        var imports = assignWith(baseAssign({}, options.imports), settings.imports, assignOwnDefaults),
+                            importsKeys = keys(imports),
+                            importsValues = baseValues(imports, importsKeys);
+
+                        var isEscaping,
+                            isEvaluating,
+                            index = 0,
+                            interpolate = options.interpolate || reNoMatch,
+                            source = "__p += '";
+
+                        // Compile the regexp to match each delimiter.
+                        var reDelimiters = RegExp(
+                            (options.escape || reNoMatch).source + '|' +
+                            interpolate.source + '|' +
+                            (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
+                            (options.evaluate || reNoMatch).source + '|$', 'g');
+
+                        // Use a sourceURL for easier debugging.
+                        var sourceURL = '//# sourceURL=' +
+                            ('sourceURL' in options ? options.sourceURL : ('lodash.templateSources[' + (++templateCounter) + ']')) + '\n';
+
+                        string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
+                            interpolateValue || (interpolateValue = esTemplateValue);
+
+                            // Escape characters that can't be included in string literals.
+                            source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
+
+                            // Replace delimiters with snippets.
+                            if (escapeValue) {
+                                isEscaping = true;
+                                source += "' +\n__e(" + escapeValue + ") +\n'";
+                            }
+                            if (evaluateValue) {
+                                isEvaluating = true;
+                                source += "';\n" + evaluateValue + ";\n__p += '";
+                            }
+                            if (interpolateValue) {
+                                source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
+                            }
+                            index = offset + match.length;
+
+                            // The JS engine embedded in Adobe products requires returning the
+                            // `match`
+                            // string in order to produce the correct `offset` value.
+                            return match;
+                        });
+
+                        source += "';\n";
+
+                        // If `variable` is not specified wrap a with-statement around the
+                        // generated
+                        // code to add the data object to the top of the scope chain.
+                        var variable = options.variable;
+                        if (!variable) {
+                            source = 'with (obj) {\n' + source + '\n}\n';
+                        }
+                        // Cleanup code by stripping empty strings.
+                        source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
+                            .replace(reEmptyStringMiddle, '$1')
+                            .replace(reEmptyStringTrailing, '$1;');
+
+                        // Frame code as the function body.
+                        source = 'function(' + (variable || 'obj') + ') {\n' +
+                            (variable ? '' : 'obj || (obj = {});\n') +
+                            "var __t, __p = ''" +
+                            (isEscaping ? ', __e = _.escape' : '') +
+                            (isEvaluating ? ', __j = Array.prototype.join;\n' +
+                                "function print() { __p += __j.call(arguments, '') }\n" : ';\n'
+                            ) +
+                            source +
+                            'return __p\n}';
+
+                        var result = attempt(function() {
+                            return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
+                        });
+
+                        // Provide the compiled function's source by its `toString` method or
+                        // the `source` property as a convenience for inlining compiled
+                        // templates.
+                        result.source = source;
+                        if (isError(result)) {
+                            throw result;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Removes leading and trailing whitespace or specified characters from
+                     * `string`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to trim.
+                     * @param {string}
+                     *            [chars=whitespace] The characters to trim.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {string} Returns the trimmed string.
+                     * @example
+                     * 
+                     * _.trim(' abc '); // => 'abc'
+                     * 
+                     * _.trim('-_-abc-_-', '_-'); // => 'abc'
+                     * 
+                     * _.map([' foo ', ' bar '], _.trim); // => ['foo', 'bar']
+                     */
+                    function trim(string, chars, guard) {
+                        var value = string;
+                        string = baseToString(string);
+                        if (!string) {
+                            return string;
+                        }
+                        if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
+                            return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
+                        }
+                        chars = (chars + '');
+                        return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
+                    }
+
+                    /**
+                     * Removes leading whitespace or specified characters from `string`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to trim.
+                     * @param {string}
+                     *            [chars=whitespace] The characters to trim.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {string} Returns the trimmed string.
+                     * @example
+                     * 
+                     * _.trimLeft(' abc '); // => 'abc '
+                     * 
+                     * _.trimLeft('-_-abc-_-', '_-'); // => 'abc-_-'
+                     */
+                    function trimLeft(string, chars, guard) {
+                        var value = string;
+                        string = baseToString(string);
+                        if (!string) {
+                            return string;
+                        }
+                        if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
+                            return string.slice(trimmedLeftIndex(string));
+                        }
+                        return string.slice(charsLeftIndex(string, (chars + '')));
+                    }
+
+                    /**
+                     * Removes trailing whitespace or specified characters from `string`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to trim.
+                     * @param {string}
+                     *            [chars=whitespace] The characters to trim.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {string} Returns the trimmed string.
+                     * @example
+                     * 
+                     * _.trimRight(' abc '); // => ' abc'
+                     * 
+                     * _.trimRight('-_-abc-_-', '_-'); // => '-_-abc'
+                     */
+                    function trimRight(string, chars, guard) {
+                        var value = string;
+                        string = baseToString(string);
+                        if (!string) {
+                            return string;
+                        }
+                        if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
+                            return string.slice(0, trimmedRightIndex(string) + 1);
+                        }
+                        return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
+                    }
+
+                    /**
+                     * Truncates `string` if it's longer than the given maximum string length.
+                     * The last characters of the truncated string are replaced with the
+                     * omission string which defaults to "...".
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to truncate.
+                     * @param {Object|number}
+                     *            [options] The options object or maximum string length.
+                     * @param {number}
+                     *            [options.length=30] The maximum string length.
+                     * @param {string}
+                     *            [options.omission='...'] The string to indicate text is
+                     *            omitted.
+                     * @param {RegExp|string}
+                     *            [options.separator] The separator pattern to truncate to.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {string} Returns the truncated string.
+                     * @example
+                     * 
+                     * _.trunc('hi-diddly-ho there, neighborino'); // => 'hi-diddly-ho there,
+                     * neighbo...'
+                     * 
+                     * _.trunc('hi-diddly-ho there, neighborino', 24); // => 'hi-diddly-ho
+                     * there, n...'
+                     * 
+                     * _.trunc('hi-diddly-ho there, neighborino', { 'length': 24, 'separator': ' '
+                     * }); // => 'hi-diddly-ho there,...'
+                     * 
+                     * _.trunc('hi-diddly-ho there, neighborino', { 'length': 24, 'separator':
+                     * /,? +/ }); // => 'hi-diddly-ho there...'
+                     * 
+                     * _.trunc('hi-diddly-ho there, neighborino', { 'omission': ' [...]' }); // =>
+                     * 'hi-diddly-ho there, neig [...]'
+                     */
+                    function trunc(string, options, guard) {
+                        if (guard && isIterateeCall(string, options, guard)) {
+                            options = undefined;
+                        }
+                        var length = DEFAULT_TRUNC_LENGTH,
+                            omission = DEFAULT_TRUNC_OMISSION;
+
+                        if (options != null) {
+                            if (isObject(options)) {
+                                var separator = 'separator' in options ? options.separator : separator;
+                                length = 'length' in options ? (+options.length || 0) : length;
+                                omission = 'omission' in options ? baseToString(options.omission) : omission;
+                            } else {
+                                length = +options || 0;
+                            }
+                        }
+                        string = baseToString(string);
+                        if (length >= string.length) {
+                            return string;
+                        }
+                        var end = length - omission.length;
+                        if (end < 1) {
+                            return omission;
+                        }
+                        var result = string.slice(0, end);
+                        if (separator == null) {
+                            return result + omission;
+                        }
+                        if (isRegExp(separator)) {
+                            if (string.slice(end).search(separator)) {
+                                var match,
+                                    newEnd,
+                                    substring = string.slice(0, end);
+
+                                if (!separator.global) {
+                                    separator = RegExp(separator.source, (reFlags.exec(separator) || '') + 'g');
+                                }
+                                separator.lastIndex = 0;
+                                while ((match = separator.exec(substring))) {
+                                    newEnd = match.index;
+                                }
+                                result = result.slice(0, newEnd == null ? end : newEnd);
+                            }
+                        } else if (string.indexOf(separator, end) != end) {
+                            var index = result.lastIndexOf(separator);
+                            if (index > -1) {
+                                result = result.slice(0, index);
+                            }
+                        }
+                        return result + omission;
+                    }
+
+                    /**
+                     * The inverse of `_.escape`; this method converts the HTML entities
+                     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to
+                     * their corresponding characters.
+                     * 
+                     * **Note:** No other HTML entities are unescaped. To unescape additional
+                     * HTML entities use a third-party library like [_he_](https://mths.be/he).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to unescape.
+                     * @returns {string} Returns the unescaped string.
+                     * @example
+                     * 
+                     * _.unescape('fred, barney, &amp; pebbles'); // => 'fred, barney, &
+                     * pebbles'
+                     */
+                    function unescape(string) {
+                        string = baseToString(string);
+                        return (string && reHasEscapedHtml.test(string)) ? string.replace(reEscapedHtml, unescapeHtmlChar) : string;
+                    }
+
+                    /**
+                     * Splits `string` into an array of its words.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category String
+                     * @param {string}
+                     *            [string=''] The string to inspect.
+                     * @param {RegExp|string}
+                     *            [pattern] The pattern to match words.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Array} Returns the words of `string`.
+                     * @example
+                     * 
+                     * _.words('fred, barney, & pebbles'); // => ['fred', 'barney', 'pebbles']
+                     * 
+                     * _.words('fred, barney, & pebbles', /[^, ]+/g); // => ['fred', 'barney',
+                     * '&', 'pebbles']
+                     */
+                    function words(string, pattern, guard) {
+                        if (guard && isIterateeCall(string, pattern, guard)) {
+                            pattern = undefined;
+                        }
+                        string = baseToString(string);
+                        return string.match(pattern || reWords) || [];
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Attempts to invoke `func`, returning either the result or the caught
+                     * error object. Any additional arguments are provided to `func` when it is
+                     * invoked.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Function}
+                     *            func The function to attempt.
+                     * @returns {*} Returns the `func` result or error object.
+                     * @example
+                     *  // avoid throwing errors for invalid selectors var elements =
+                     * _.attempt(function(selector) { return
+                     * document.querySelectorAll(selector); }, '>_>');
+                     * 
+                     * if (_.isError(elements)) { elements = []; }
+                     */
+                    var attempt = restParam(function(func, args) {
+                        try {
+                            return func.apply(undefined, args);
+                        } catch (e) {
+                            return isError(e) ? e : new Error(e);
+                        }
+                    });
+
+                    /**
+                     * Creates a function that invokes `func` with the `this` binding of
+                     * `thisArg` and arguments of the created function. If `func` is a property
+                     * name the created callback returns the property value for a given element.
+                     * If `func` is an object the created callback returns `true` for elements
+                     * that contain the equivalent object properties, otherwise it returns
+                     * `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @alias iteratee
+                     * @category Utility
+                     * @param {*}
+                     *            [func=_.identity] The value to convert to a callback.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `func`.
+                     * @param- {Object} [guard] Enables use as a callback for functions like
+                     *         `_.map`.
+                     * @returns {Function} Returns the callback.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 } ];
+                     *  // wrap to create custom callback shorthands _.callback =
+                     * _.wrap(_.callback, function(callback, func, thisArg) { var match =
+                     * /^(.+?)__([gl]t)(.+)$/.exec(func); if (!match) { return callback(func,
+                     * thisArg); } return function(object) { return match[2] == 'gt' ?
+                     * object[match[1]] > match[3] : object[match[1]] < match[3]; }; });
+                     * 
+                     * _.filter(users, 'age__gt36'); // => [{ 'user': 'fred', 'age': 40 }]
+                     */
+                    function callback(func, thisArg, guard) {
+                        if (guard && isIterateeCall(func, thisArg, guard)) {
+                            thisArg = undefined;
+                        }
+                        return isObjectLike(func) ? matches(func) : baseCallback(func, thisArg);
+                    }
+
+                    /**
+                     * Creates a function that returns `value`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {*}
+                     *            value The value to return from the new function.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred' }; var getter = _.constant(object);
+                     * 
+                     * getter() === object; // => true
+                     */
+                    function constant(value) {
+                        return function() {
+                            return value;
+                        };
+                    }
+
+                    /**
+                     * This method returns the first argument provided to it.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {*}
+                     *            value Any value.
+                     * @returns {*} Returns `value`.
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred' };
+                     * 
+                     * _.identity(object) === object; // => true
+                     */
+                    function identity(value) {
+                        return value;
+                    }
+
+                    /**
+                     * Creates a function that performs a deep comparison between a given object
+                     * and `source`, returning `true` if the given object has equivalent
+                     * property values, else `false`.
+                     * 
+                     * **Note:** This method supports comparing arrays, booleans, `Date`
+                     * objects, numbers, `Object` objects, regexes, and strings. Objects are
+                     * compared by their own, not inherited, enumerable properties. For
+                     * comparing a single own or inherited property value see
+                     * `_.matchesProperty`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Object}
+                     *            source The object of property values to match.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36, 'active': true }, { 'user':
+                     * 'fred', 'age': 40, 'active': false } ];
+                     * 
+                     * _.filter(users, _.matches({ 'age': 40, 'active': false })); // => [{
+                     * 'user': 'fred', 'age': 40, 'active': false }]
+                     */
+                    function matches(source) {
+                        return baseMatches(baseClone(source, true));
+                    }
+
+                    /**
+                     * Creates a function that compares the property value of `path` on a given
+                     * object to `value`.
+                     * 
+                     * **Note:** This method supports comparing arrays, booleans, `Date`
+                     * objects, numbers, `Object` objects, regexes, and strings. Objects are
+                     * compared by their own, not inherited, enumerable properties.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Array|string}
+                     *            path The path of the property to get.
+                     * @param {*}
+                     *            srcValue The value to match.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var users = [ { 'user': 'barney' }, { 'user': 'fred' } ];
+                     * 
+                     * _.find(users, _.matchesProperty('user', 'fred')); // => { 'user': 'fred' }
+                     */
+                    function matchesProperty(path, srcValue) {
+                        return baseMatchesProperty(path, baseClone(srcValue, true));
+                    }
+
+                    /**
+                     * Creates a function that invokes the method at `path` on a given object.
+                     * Any additional arguments are provided to the invoked method.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Array|string}
+                     *            path The path of the method to invoke.
+                     * @param {...*}
+                     *            [args] The arguments to invoke the method with.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var objects = [ { 'a': { 'b': { 'c': _.constant(2) } } }, { 'a': { 'b': {
+                     * 'c': _.constant(1) } } } ];
+                     * 
+                     * _.map(objects, _.method('a.b.c')); // => [2, 1]
+                     * 
+                     * _.invoke(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); // =>
+                     * [1, 2]
+                     */
+                    var method = restParam(function(path, args) {
+                        return function(object) {
+                            return invokePath(object, path, args);
+                        };
+                    });
+
+                    /**
+                     * The opposite of `_.method`; this method creates a function that invokes
+                     * the method at a given path on `object`. Any additional arguments are
+                     * provided to the invoked method.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Object}
+                     *            object The object to query.
+                     * @param {...*}
+                     *            [args] The arguments to invoke the method with.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var array = _.times(3, _.constant), object = { 'a': array, 'b': array,
+                     * 'c': array };
+                     * 
+                     * _.map(['a[2]', 'c[0]'], _.methodOf(object)); // => [2, 0]
+                     * 
+                     * _.map([['a', '2'], ['c', '0']], _.methodOf(object)); // => [2, 0]
+                     */
+                    var methodOf = restParam(function(object, args) {
+                        return function(path) {
+                            return invokePath(object, path, args);
+                        };
+                    });
+
+                    /**
+                     * Adds all own enumerable function properties of a source object to the
+                     * destination object. If `object` is a function then methods are added to
+                     * its prototype as well.
+                     * 
+                     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
+                     * avoid conflicts caused by modifying the original.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Function|Object}
+                     *            [object=lodash] The destination object.
+                     * @param {Object}
+                     *            source The object of functions to add.
+                     * @param {Object}
+                     *            [options] The options object.
+                     * @param {boolean}
+                     *            [options.chain=true] Specify whether the functions added are
+                     *            chainable.
+                     * @returns {Function|Object} Returns `object`.
+                     * @example
+                     * 
+                     * function vowels(string) { return _.filter(string, function(v) { return
+                     * /[aeiou]/i.test(v); }); }
+                     * 
+                     * _.mixin({ 'vowels': vowels }); _.vowels('fred'); // => ['e']
+                     * 
+                     * _('fred').vowels().value(); // => ['e']
+                     * 
+                     * _.mixin({ 'vowels': vowels }, { 'chain': false }); _('fred').vowels(); // =>
+                     * ['e']
+                     */
+                    function mixin(object, source, options) {
+                        if (options == null) {
+                            var isObj = isObject(source),
+                                props = isObj ? keys(source) : undefined,
+                                methodNames = (props && props.length) ? baseFunctions(source, props) : undefined;
+
+                            if (!(methodNames ? methodNames.length : isObj)) {
+                                methodNames = false;
+                                options = source;
+                                source = object;
+                                object = this;
+                            }
+                        }
+                        if (!methodNames) {
+                            methodNames = baseFunctions(source, keys(source));
+                        }
+                        var chain = true,
+                            index = -1,
+                            isFunc = isFunction(object),
+                            length = methodNames.length;
+
+                        if (options === false) {
+                            chain = false;
+                        } else if (isObject(options) && 'chain' in options) {
+                            chain = options.chain;
+                        }
+                        while (++index < length) {
+                            var methodName = methodNames[index],
+                                func = source[methodName];
+
+                            object[methodName] = func;
+                            if (isFunc) {
+                                object.prototype[methodName] = (function(func) {
+                                    return function() {
+                                        var chainAll = this.__chain__;
+                                        if (chain || chainAll) {
+                                            var result = object(this.__wrapped__),
+                                                actions = result.__actions__ = arrayCopy(this.__actions__);
+
+                                            actions.push({
+                                                'func': func,
+                                                'args': arguments,
+                                                'thisArg': object
+                                            });
+                                            result.__chain__ = chainAll;
+                                            return result;
+                                        }
+                                        return func.apply(object, arrayPush([this.value()], arguments));
+                                    };
+                                }(func));
+                            }
+                        }
+                        return object;
+                    }
+
+                    /**
+                     * Reverts the `_` variable to its previous value and returns a reference to
+                     * the `lodash` function.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @returns {Function} Returns the `lodash` function.
+                     * @example
+                     * 
+                     * var lodash = _.noConflict();
+                     */
+                    function noConflict() {
+                        root._ = oldDash;
+                        return this;
+                    }
+
+                    /**
+                     * A no-operation function that returns `undefined` regardless of the
+                     * arguments it receives.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @example
+                     * 
+                     * var object = { 'user': 'fred' };
+                     * 
+                     * _.noop(object) === undefined; // => true
+                     */
+                    function noop() {
+                        // No operation performed.
+                    }
+
+                    /**
+                     * Creates a function that returns the property value at `path` on a given
+                     * object.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Array|string}
+                     *            path The path of the property to get.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var objects = [ { 'a': { 'b': { 'c': 2 } } }, { 'a': { 'b': { 'c': 1 } } } ];
+                     * 
+                     * _.map(objects, _.property('a.b.c')); // => [2, 1]
+                     * 
+                     * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); // =>
+                     * [1, 2]
+                     */
+                    function property(path) {
+                        return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
+                    }
+
+                    /**
+                     * The opposite of `_.property`; this method creates a function that returns
+                     * the property value at a given path on `object`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {Object}
+                     *            object The object to query.
+                     * @returns {Function} Returns the new function.
+                     * @example
+                     * 
+                     * var array = [0, 1, 2], object = { 'a': array, 'b': array, 'c': array };
+                     * 
+                     * _.map(['a[2]', 'c[0]'], _.propertyOf(object)); // => [2, 0]
+                     * 
+                     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); // => [2, 0]
+                     */
+                    function propertyOf(object) {
+                        return function(path) {
+                            return baseGet(object, toPath(path), path + '');
+                        };
+                    }
+
+                    /**
+                     * Creates an array of numbers (positive and/or negative) progressing from
+                     * `start` up to, but not including, `end`. If `end` is not specified it is
+                     * set to `start` with `start` then set to `0`. If `end` is less than
+                     * `start` a zero-length range is created unless a negative `step` is
+                     * specified.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {number}
+                     *            [start=0] The start of the range.
+                     * @param {number}
+                     *            end The end of the range.
+                     * @param {number}
+                     *            [step=1] The value to increment or decrement by.
+                     * @returns {Array} Returns the new array of numbers.
+                     * @example
+                     * 
+                     * _.range(4); // => [0, 1, 2, 3]
+                     * 
+                     * _.range(1, 5); // => [1, 2, 3, 4]
+                     * 
+                     * _.range(0, 20, 5); // => [0, 5, 10, 15]
+                     * 
+                     * _.range(0, -4, -1); // => [0, -1, -2, -3]
+                     * 
+                     * _.range(1, 4, 0); // => [1, 1, 1]
+                     * 
+                     * _.range(0); // => []
+                     */
+                    function range(start, end, step) {
+                        if (step && isIterateeCall(start, end, step)) {
+                            end = step = undefined;
+                        }
+                        start = +start || 0;
+                        step = step == null ? 1 : (+step || 0);
+
+                        if (end == null) {
+                            end = start;
+                            start = 0;
+                        } else {
+                            end = +end || 0;
+                        }
+                        // Use `Array(length)` so engines like Chakra and V8 avoid slower modes.
+                        // See https://youtu.be/XAqIpGU8ZZk#t=17m25s for more details.
+                        var index = -1,
+                            length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
+                            result = Array(length);
+
+                        while (++index < length) {
+                            result[index] = start;
+                            start += step;
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Invokes the iteratee function `n` times, returning an array of the
+                     * results of each invocation. The `iteratee` is bound to `thisArg` and
+                     * invoked with one argument; (index).
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {number}
+                     *            n The number of times to invoke `iteratee`.
+                     * @param {Function}
+                     *            [iteratee=_.identity] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {Array} Returns the array of results.
+                     * @example
+                     * 
+                     * var diceRolls = _.times(3, _.partial(_.random, 1, 6, false)); // => [3,
+                     * 6, 4]
+                     * 
+                     * _.times(3, function(n) { mage.castSpell(n); }); // => invokes
+                     * `mage.castSpell(n)` three times with `n` of `0`, `1`, and `2`
+                     * 
+                     * _.times(3, function(n) { this.cast(n); }, mage); // => also invokes
+                     * `mage.castSpell(n)` three times
+                     */
+                    function times(n, iteratee, thisArg) {
+                        n = nativeFloor(n);
+
+                        // Exit early to avoid a JSC JIT bug in Safari 8
+                        // where `Array(0)` is treated as `Array(1)`.
+                        if (n < 1 || !nativeIsFinite(n)) {
+                            return [];
+                        }
+                        var index = -1,
+                            result = Array(nativeMin(n, MAX_ARRAY_LENGTH));
+
+                        iteratee = bindCallback(iteratee, thisArg, 1);
+                        while (++index < n) {
+                            if (index < MAX_ARRAY_LENGTH) {
+                                result[index] = iteratee(index);
+                            } else {
+                                iteratee(index);
+                            }
+                        }
+                        return result;
+                    }
+
+                    /**
+                     * Generates a unique ID. If `prefix` is provided the ID is appended to it.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Utility
+                     * @param {string}
+                     *            [prefix] The value to prefix the ID with.
+                     * @returns {string} Returns the unique ID.
+                     * @example
+                     * 
+                     * _.uniqueId('contact_'); // => 'contact_104'
+                     * 
+                     * _.uniqueId(); // => '105'
+                     */
+                    function uniqueId(prefix) {
+                        var id = ++idCounter;
+                        return baseToString(prefix) + id;
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * Adds two numbers.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {number}
+                     *            augend The first number to add.
+                     * @param {number}
+                     *            addend The second number to add.
+                     * @returns {number} Returns the sum.
+                     * @example
+                     * 
+                     * _.add(6, 4); // => 10
+                     */
+                    function add(augend, addend) {
+                        return (+augend || 0) + (+addend || 0);
+                    }
+
+                    /**
+                     * Calculates `n` rounded up to `precision`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {number}
+                     *            n The number to round up.
+                     * @param {number}
+                     *            [precision=0] The precision to round up to.
+                     * @returns {number} Returns the rounded up number.
+                     * @example
+                     * 
+                     * _.ceil(4.006); // => 5
+                     * 
+                     * _.ceil(6.004, 2); // => 6.01
+                     * 
+                     * _.ceil(6040, -2); // => 6100
+                     */
+                    var ceil = createRound('ceil');
+
+                    /**
+                     * Calculates `n` rounded down to `precision`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {number}
+                     *            n The number to round down.
+                     * @param {number}
+                     *            [precision=0] The precision to round down to.
+                     * @returns {number} Returns the rounded down number.
+                     * @example
+                     * 
+                     * _.floor(4.006); // => 4
+                     * 
+                     * _.floor(0.046, 2); // => 0.04
+                     * 
+                     * _.floor(4060, -2); // => 4000
+                     */
+                    var floor = createRound('floor');
+
+                    /**
+                     * Gets the maximum value of `collection`. If `collection` is empty or
+                     * falsey `-Infinity` is returned. If an iteratee function is provided it is
+                     * invoked for each value in `collection` to generate the criterion by which
+                     * the value is ranked. The `iteratee` is bound to `thisArg` and invoked
+                     * with three arguments: (value, index, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {*} Returns the maximum value.
+                     * @example
+                     * 
+                     * _.max([4, 2, 8, 6]); // => 8
+                     * 
+                     * _.max([]); // => -Infinity
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 } ];
+                     * 
+                     * _.max(users, function(chr) { return chr.age; }); // => { 'user': 'fred',
+                     * 'age': 40 }
+                     *  // using the `_.property` callback shorthand _.max(users, 'age'); // => {
+                     * 'user': 'fred', 'age': 40 }
+                     */
+                    var max = createExtremum(gt, NEGATIVE_INFINITY);
+
+                    /**
+                     * Gets the minimum value of `collection`. If `collection` is empty or
+                     * falsey `Infinity` is returned. If an iteratee function is provided it is
+                     * invoked for each value in `collection` to generate the criterion by which
+                     * the value is ranked. The `iteratee` is bound to `thisArg` and invoked
+                     * with three arguments: (value, index, collection).
+                     * 
+                     * If a property name is provided for `iteratee` the created `_.property`
+                     * style callback returns the property value of the given element.
+                     * 
+                     * If a value is also provided for `thisArg` the created `_.matchesProperty`
+                     * style callback returns `true` for elements that have a matching property
+                     * value, else `false`.
+                     * 
+                     * If an object is provided for `iteratee` the created `_.matches` style
+                     * callback returns `true` for elements that have the properties of the
+                     * given object, else `false`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {*} Returns the minimum value.
+                     * @example
+                     * 
+                     * _.min([4, 2, 8, 6]); // => 2
+                     * 
+                     * _.min([]); // => Infinity
+                     * 
+                     * var users = [ { 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age':
+                     * 40 } ];
+                     * 
+                     * _.min(users, function(chr) { return chr.age; }); // => { 'user':
+                     * 'barney', 'age': 36 }
+                     *  // using the `_.property` callback shorthand _.min(users, 'age'); // => {
+                     * 'user': 'barney', 'age': 36 }
+                     */
+                    var min = createExtremum(lt, POSITIVE_INFINITY);
+
+                    /**
+                     * Calculates `n` rounded to `precision`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {number}
+                     *            n The number to round.
+                     * @param {number}
+                     *            [precision=0] The precision to round to.
+                     * @returns {number} Returns the rounded number.
+                     * @example
+                     * 
+                     * _.round(4.006); // => 4
+                     * 
+                     * _.round(4.006, 2); // => 4.01
+                     * 
+                     * _.round(4060, -2); // => 4100
+                     */
+                    var round = createRound('round');
+
+                    /**
+                     * Gets the sum of the values in `collection`.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @category Math
+                     * @param {Array|Object|string}
+                     *            collection The collection to iterate over.
+                     * @param {Function|Object|string}
+                     *            [iteratee] The function invoked per iteration.
+                     * @param {*}
+                     *            [thisArg] The `this` binding of `iteratee`.
+                     * @returns {number} Returns the sum.
+                     * @example
+                     * 
+                     * _.sum([4, 6]); // => 10
+                     * 
+                     * _.sum({ 'a': 4, 'b': 6 }); // => 10
+                     * 
+                     * var objects = [ { 'n': 4 }, { 'n': 6 } ];
+                     * 
+                     * _.sum(objects, function(object) { return object.n; }); // => 10
+                     *  // using the `_.property` callback shorthand _.sum(objects, 'n'); // =>
+                     * 10
+                     */
+                    function sum(collection, iteratee, thisArg) {
+                        if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
+                            iteratee = undefined;
+                        }
+                        iteratee = getCallback(iteratee, thisArg, 3);
+                        return iteratee.length == 1 ? arraySum(isArray(collection) ? collection : toIterable(collection), iteratee) : baseSum(collection, iteratee);
+                    }
+
+                    /*------------------------------------------------------------------------*/
+
+                    // Ensure wrappers are instances of `baseLodash`.
+                    lodash.prototype = baseLodash.prototype;
+
+                    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+                    LodashWrapper.prototype.constructor = LodashWrapper;
+
+                    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+                    LazyWrapper.prototype.constructor = LazyWrapper;
+
+                    // Add functions to the `Map` cache.
+                    MapCache.prototype['delete'] = mapDelete;
+                    MapCache.prototype.get = mapGet;
+                    MapCache.prototype.has = mapHas;
+                    MapCache.prototype.set = mapSet;
+
+                    // Add functions to the `Set` cache.
+                    SetCache.prototype.push = cachePush;
+
+                    // Assign cache to `_.memoize`.
+                    memoize.Cache = MapCache;
+
+                    // Add functions that return wrapped values when chaining.
+                    lodash.after = after;
+                    lodash.ary = ary;
+                    lodash.assign = assign;
+                    lodash.at = at;
+                    lodash.before = before;
+                    lodash.bind = bind;
+                    lodash.bindAll = bindAll;
+                    lodash.bindKey = bindKey;
+                    lodash.callback = callback;
+                    lodash.chain = chain;
+                    lodash.chunk = chunk;
+                    lodash.compact = compact;
+                    lodash.constant = constant;
+                    lodash.countBy = countBy;
+                    lodash.create = create;
+                    lodash.curry = curry;
+                    lodash.curryRight = curryRight;
+                    lodash.debounce = debounce;
+                    lodash.defaults = defaults;
+                    lodash.defaultsDeep = defaultsDeep;
+                    lodash.defer = defer;
+                    lodash.delay = delay;
+                    lodash.difference = difference;
+                    lodash.drop = drop;
+                    lodash.dropRight = dropRight;
+                    lodash.dropRightWhile = dropRightWhile;
+                    lodash.dropWhile = dropWhile;
+                    lodash.fill = fill;
+                    lodash.filter = filter;
+                    lodash.flatten = flatten;
+                    lodash.flattenDeep = flattenDeep;
+                    lodash.flow = flow;
+                    lodash.flowRight = flowRight;
+                    lodash.forEach = forEach;
+                    lodash.forEachRight = forEachRight;
+                    lodash.forIn = forIn;
+                    lodash.forInRight = forInRight;
+                    lodash.forOwn = forOwn;
+                    lodash.forOwnRight = forOwnRight;
+                    lodash.functions = functions;
+                    lodash.groupBy = groupBy;
+                    lodash.indexBy = indexBy;
+                    lodash.initial = initial;
+                    lodash.intersection = intersection;
+                    lodash.invert = invert;
+                    lodash.invoke = invoke;
+                    lodash.keys = keys;
+                    lodash.keysIn = keysIn;
+                    lodash.map = map;
+                    lodash.mapKeys = mapKeys;
+                    lodash.mapValues = mapValues;
+                    lodash.matches = matches;
+                    lodash.matchesProperty = matchesProperty;
+                    lodash.memoize = memoize;
+                    lodash.merge = merge;
+                    lodash.method = method;
+                    lodash.methodOf = methodOf;
+                    lodash.mixin = mixin;
+                    lodash.modArgs = modArgs;
+                    lodash.negate = negate;
+                    lodash.omit = omit;
+                    lodash.once = once;
+                    lodash.pairs = pairs;
+                    lodash.partial = partial;
+                    lodash.partialRight = partialRight;
+                    lodash.partition = partition;
+                    lodash.pick = pick;
+                    lodash.pluck = pluck;
+                    lodash.property = property;
+                    lodash.propertyOf = propertyOf;
+                    lodash.pull = pull;
+                    lodash.pullAt = pullAt;
+                    lodash.range = range;
+                    lodash.rearg = rearg;
+                    lodash.reject = reject;
+                    lodash.remove = remove;
+                    lodash.rest = rest;
+                    lodash.restParam = restParam;
+                    lodash.set = set;
+                    lodash.shuffle = shuffle;
+                    lodash.slice = slice;
+                    lodash.sortBy = sortBy;
+                    lodash.sortByAll = sortByAll;
+                    lodash.sortByOrder = sortByOrder;
+                    lodash.spread = spread;
+                    lodash.take = take;
+                    lodash.takeRight = takeRight;
+                    lodash.takeRightWhile = takeRightWhile;
+                    lodash.takeWhile = takeWhile;
+                    lodash.tap = tap;
+                    lodash.throttle = throttle;
+                    lodash.thru = thru;
+                    lodash.times = times;
+                    lodash.toArray = toArray;
+                    lodash.toPlainObject = toPlainObject;
+                    lodash.transform = transform;
+                    lodash.union = union;
+                    lodash.uniq = uniq;
+                    lodash.unzip = unzip;
+                    lodash.unzipWith = unzipWith;
+                    lodash.values = values;
+                    lodash.valuesIn = valuesIn;
+                    lodash.where = where;
+                    lodash.without = without;
+                    lodash.wrap = wrap;
+                    lodash.xor = xor;
+                    lodash.zip = zip;
+                    lodash.zipObject = zipObject;
+                    lodash.zipWith = zipWith;
+
+                    // Add aliases.
+                    lodash.backflow = flowRight;
+                    lodash.collect = map;
+                    lodash.compose = flowRight;
+                    lodash.each = forEach;
+                    lodash.eachRight = forEachRight;
+                    lodash.extend = assign;
+                    lodash.iteratee = callback;
+                    lodash.methods = functions;
+                    lodash.object = zipObject;
+                    lodash.select = filter;
+                    lodash.tail = rest;
+                    lodash.unique = uniq;
+
+                    // Add functions to `lodash.prototype`.
+                    mixin(lodash, lodash);
+
+                    /*------------------------------------------------------------------------*/
+
+                    // Add functions that return unwrapped values when chaining.
+                    lodash.add = add;
+                    lodash.attempt = attempt;
+                    lodash.camelCase = camelCase;
+                    lodash.capitalize = capitalize;
+                    lodash.ceil = ceil;
+                    lodash.clone = clone;
+                    lodash.cloneDeep = cloneDeep;
+                    lodash.deburr = deburr;
+                    lodash.endsWith = endsWith;
+                    lodash.escape = escape;
+                    lodash.escapeRegExp = escapeRegExp;
+                    lodash.every = every;
+                    lodash.find = find;
+                    lodash.findIndex = findIndex;
+                    lodash.findKey = findKey;
+                    lodash.findLast = findLast;
+                    lodash.findLastIndex = findLastIndex;
+                    lodash.findLastKey = findLastKey;
+                    lodash.findWhere = findWhere;
+                    lodash.first = first;
+                    lodash.floor = floor;
+                    lodash.get = get;
+                    lodash.gt = gt;
+                    lodash.gte = gte;
+                    lodash.has = has;
+                    lodash.identity = identity;
+                    lodash.includes = includes;
+                    lodash.indexOf = indexOf;
+                    lodash.inRange = inRange;
+                    lodash.isArguments = isArguments;
+                    lodash.isArray = isArray;
+                    lodash.isBoolean = isBoolean;
+                    lodash.isDate = isDate;
+                    lodash.isElement = isElement;
+                    lodash.isEmpty = isEmpty;
+                    lodash.isEqual = isEqual;
+                    lodash.isError = isError;
+                    lodash.isFinite = isFinite;
+                    lodash.isFunction = isFunction;
+                    lodash.isMatch = isMatch;
+                    lodash.isNaN = isNaN;
+                    lodash.isNative = isNative;
+                    lodash.isNull = isNull;
+                    lodash.isNumber = isNumber;
+                    lodash.isObject = isObject;
+                    lodash.isPlainObject = isPlainObject;
+                    lodash.isRegExp = isRegExp;
+                    lodash.isString = isString;
+                    lodash.isTypedArray = isTypedArray;
+                    lodash.isUndefined = isUndefined;
+                    lodash.kebabCase = kebabCase;
+                    lodash.last = last;
+                    lodash.lastIndexOf = lastIndexOf;
+                    lodash.lt = lt;
+                    lodash.lte = lte;
+                    lodash.max = max;
+                    lodash.min = min;
+                    lodash.noConflict = noConflict;
+                    lodash.noop = noop;
+                    lodash.now = now;
+                    lodash.pad = pad;
+                    lodash.padLeft = padLeft;
+                    lodash.padRight = padRight;
+                    lodash.parseInt = parseInt;
+                    lodash.random = random;
+                    lodash.reduce = reduce;
+                    lodash.reduceRight = reduceRight;
+                    lodash.repeat = repeat;
+                    lodash.result = result;
+                    lodash.round = round;
+                    lodash.runInContext = runInContext;
+                    lodash.size = size;
+                    lodash.snakeCase = snakeCase;
+                    lodash.some = some;
+                    lodash.sortedIndex = sortedIndex;
+                    lodash.sortedLastIndex = sortedLastIndex;
+                    lodash.startCase = startCase;
+                    lodash.startsWith = startsWith;
+                    lodash.sum = sum;
+                    lodash.template = template;
+                    lodash.trim = trim;
+                    lodash.trimLeft = trimLeft;
+                    lodash.trimRight = trimRight;
+                    lodash.trunc = trunc;
+                    lodash.unescape = unescape;
+                    lodash.uniqueId = uniqueId;
+                    lodash.words = words;
+
+                    // Add aliases.
+                    lodash.all = every;
+                    lodash.any = some;
+                    lodash.contains = includes;
+                    lodash.eq = isEqual;
+                    lodash.detect = find;
+                    lodash.foldl = reduce;
+                    lodash.foldr = reduceRight;
+                    lodash.head = first;
+                    lodash.include = includes;
+                    lodash.inject = reduce;
+
+                    mixin(lodash, (function() {
+                        var source = {};
+                        baseForOwn(lodash, function(func, methodName) {
+                            if (!lodash.prototype[methodName]) {
+                                source[methodName] = func;
+                            }
+                        });
+                        return source;
+                    }()), false);
+
+                    /*------------------------------------------------------------------------*/
+
+                    // Add functions capable of returning wrapped and unwrapped values when
+                    // chaining.
+                    lodash.sample = sample;
+
+                    lodash.prototype.sample = function(n) {
+                        if (!this.__chain__ && n == null) {
+                            return sample(this.value());
+                        }
+                        return this.thru(function(value) {
+                            return sample(value, n);
+                        });
+                    };
+
+                    /*------------------------------------------------------------------------*/
+
+                    /**
+                     * The semantic version number.
+                     * 
+                     * @static
+                     * @memberOf _
+                     * @type string
+                     */
+                    lodash.VERSION = VERSION;
+
+                    // Assign default placeholders.
+                    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
+                        lodash[methodName].placeholder = lodash;
+                    });
+
+                    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
+                    arrayEach(['drop', 'take'], function(methodName, index) {
+                        LazyWrapper.prototype[methodName] = function(n) {
+                            var filtered = this.__filtered__;
+                            if (filtered && !index) {
+                                return new LazyWrapper(this);
+                            }
+                            n = n == null ? 1 : nativeMax(nativeFloor(n) || 0, 0);
+
+                            var result = this.clone();
+                            if (filtered) {
+                                result.__takeCount__ = nativeMin(result.__takeCount__, n);
+                            } else {
+                                result.__views__.push({
+                                    'size': n,
+                                    'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
+                                });
+                            }
+                            return result;
+                        };
+
+                        LazyWrapper.prototype[methodName + 'Right'] = function(n) {
+                            return this.reverse()[methodName](n).reverse();
+                        };
+                    });
+
+                    // Add `LazyWrapper` methods that accept an `iteratee` value.
+                    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
+                        var type = index + 1,
+                            isFilter = type != LAZY_MAP_FLAG;
+
+                        LazyWrapper.prototype[methodName] = function(iteratee, thisArg) {
+                            var result = this.clone();
+                            result.__iteratees__.push({
+                                'iteratee': getCallback(iteratee, thisArg, 1),
+                                'type': type
+                            });
+                            result.__filtered__ = result.__filtered__ || isFilter;
+                            return result;
+                        };
+                    });
+
+                    // Add `LazyWrapper` methods for `_.first` and `_.last`.
+                    arrayEach(['first', 'last'], function(methodName, index) {
+                        var takeName = 'take' + (index ? 'Right' : '');
+
+                        LazyWrapper.prototype[methodName] = function() {
+                            return this[takeName](1).value()[0];
+                        };
+                    });
+
+                    // Add `LazyWrapper` methods for `_.initial` and `_.rest`.
+                    arrayEach(['initial', 'rest'], function(methodName, index) {
+                        var dropName = 'drop' + (index ? '' : 'Right');
+
+                        LazyWrapper.prototype[methodName] = function() {
+                            return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
+                        };
+                    });
+
+                    // Add `LazyWrapper` methods for `_.pluck` and `_.where`.
+                    arrayEach(['pluck', 'where'], function(methodName, index) {
+                        var operationName = index ? 'filter' : 'map',
+                            createCallback = index ? baseMatches : property;
+
+                        LazyWrapper.prototype[methodName] = function(value) {
+                            return this[operationName](createCallback(value));
+                        };
+                    });
+
+                    LazyWrapper.prototype.compact = function() {
+                        return this.filter(identity);
+                    };
+
+                    LazyWrapper.prototype.reject = function(predicate, thisArg) {
+                        predicate = getCallback(predicate, thisArg, 1);
+                        return this.filter(function(value) {
+                            return !predicate(value);
+                        });
+                    };
+
+                    LazyWrapper.prototype.slice = function(start, end) {
+                        start = start == null ? 0 : (+start || 0);
+
+                        var result = this;
+                        if (result.__filtered__ && (start > 0 || end < 0)) {
+                            return new LazyWrapper(result);
+                        }
+                        if (start < 0) {
+                            result = result.takeRight(-start);
+                        } else if (start) {
+                            result = result.drop(start);
+                        }
+                        if (end !== undefined) {
+                            end = (+end || 0);
+                            result = end < 0 ? result.dropRight(-end) : result.take(end - start);
+                        }
+                        return result;
+                    };
+
+                    LazyWrapper.prototype.takeRightWhile = function(predicate, thisArg) {
+                        return this.reverse().takeWhile(predicate, thisArg).reverse();
+                    };
+
+                    LazyWrapper.prototype.toArray = function() {
+                        return this.take(POSITIVE_INFINITY);
+                    };
+
+                    // Add `LazyWrapper` methods to `lodash.prototype`.
+                    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
+                        var checkIteratee = /^(?:filter|map|reject)|While$/.test(methodName),
+                            retUnwrapped = /^(?:first|last)$/.test(methodName),
+                            lodashFunc = lodash[retUnwrapped ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName];
+
+                        if (!lodashFunc) {
+                            return;
+                        }
+                        lodash.prototype[methodName] = function() {
+                            var args = retUnwrapped ? [1] : arguments,
+                                chainAll = this.__chain__,
+                                value = this.__wrapped__,
+                                isHybrid = !!this.__actions__.length,
+                                isLazy = value instanceof LazyWrapper,
+                                iteratee = args[0],
+                                useLazy = isLazy || isArray(value);
+
+                            if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
+                                // Avoid lazy use if the iteratee has a "length" value other than
+                                // `1`.
+                                isLazy = useLazy = false;
+                            }
+                            var interceptor = function(value) {
+                                return (retUnwrapped && chainAll) ? lodashFunc(value, 1)[0] : lodashFunc.apply(undefined, arrayPush([value], args));
+                            };
+
+                            var action = {
+                                    'func': thru,
+                                    'args': [interceptor],
+                                    'thisArg': undefined
+                                },
+                                onlyLazy = isLazy && !isHybrid;
+
+                            if (retUnwrapped && !chainAll) {
+                                if (onlyLazy) {
+                                    value = value.clone();
+                                    value.__actions__.push(action);
+                                    return func.call(value);
+                                }
+                                return lodashFunc.call(undefined, this.value())[0];
+                            }
+                            if (!retUnwrapped && useLazy) {
+                                value = onlyLazy ? value : new LazyWrapper(this);
+                                var result = func.apply(value, args);
+                                result.__actions__.push(action);
+                                return new LodashWrapper(result, chainAll);
+                            }
+                            return this.thru(interceptor);
+                        };
+                    });
+
+                    // Add `Array` and `String` methods to `lodash.prototype`.
+                    arrayEach(['join', 'pop', 'push', 'replace', 'shift', 'sort', 'splice', 'split', 'unshift'], function(methodName) {
+                        var func = (/^(?:replace|split)$/.test(methodName) ? stringProto : arrayProto)[methodName],
+                            chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
+                            retUnwrapped = /^(?:join|pop|replace|shift)$/.test(methodName);
+
+                        lodash.prototype[methodName] = function() {
+                            var args = arguments;
+                            if (retUnwrapped && !this.__chain__) {
+                                return func.apply(this.value(), args);
+                            }
+                            return this[chainName](function(value) {
+                                return func.apply(value, args);
+                            });
+                        };
+                    });
+
+                    // Map minified function names to their real names.
+                    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
+                        var lodashFunc = lodash[methodName];
+                        if (lodashFunc) {
+                            var key = lodashFunc.name,
+                                names = realNames[key] || (realNames[key] = []);
+
+                            names.push({
+                                'name': methodName,
+                                'func': lodashFunc
+                            });
+                        }
+                    });
+
+                    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
+                        'name': 'wrapper',
+                        'func': undefined
+                    }];
+
+                    // Add functions to the lazy wrapper.
+                    LazyWrapper.prototype.clone = lazyClone;
+                    LazyWrapper.prototype.reverse = lazyReverse;
+                    LazyWrapper.prototype.value = lazyValue;
+
+                    // Add chaining functions to the `lodash` wrapper.
+                    lodash.prototype.chain = wrapperChain;
+                    lodash.prototype.commit = wrapperCommit;
+                    lodash.prototype.concat = wrapperConcat;
+                    lodash.prototype.plant = wrapperPlant;
+                    lodash.prototype.reverse = wrapperReverse;
+                    lodash.prototype.toString = wrapperToString;
+                    lodash.prototype.run = lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
+
+                    // Add function aliases to the `lodash` wrapper.
+                    lodash.prototype.collect = lodash.prototype.map;
+                    lodash.prototype.head = lodash.prototype.first;
+                    lodash.prototype.select = lodash.prototype.filter;
+                    lodash.prototype.tail = lodash.prototype.rest;
+
+                    return lodash;
+                }
+
+                /*--------------------------------------------------------------------------*/
+
+                // Export lodash.
+                var _ = runInContext();
+
+                // Some AMD build optimizers like r.js check for condition patterns like the
+                // following:
+                if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+                    // Expose lodash to the global object when an AMD loader is present to avoid
+                    // errors in cases where lodash is loaded by a script tag and not intended
+                    // as an AMD module. See http://requirejs.org/docs/errors.html#mismatch for
+                    // more details.
+                    root._ = _;
+
+                    // Define as an anonymous module so, through path mapping, it can be
+                    // referenced as the "underscore" module.
+                    define(function() {
+                        return _;
+                    });
+                }
+                // Check for `exports` after `define` in case a build optimizer adds an
+                // `exports` object.
+                else if (freeExports && freeModule) {
+                    // Export for Node.js or RingoJS.
+                    if (moduleExports) {
+                        (freeModule.exports = _)._ = _;
+                    }
+                    // Export for Rhino with CommonJS support.
+                    else {
+                        freeExports._ = _;
+                    }
+                } else {
+                    // Export for a browser or Rhino.
+                    root._ = _;
+                }
+            }.call(this));
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LazyWrapper.js": [function(require, module, exports) {
+        var baseCreate = require('./baseCreate'),
+            baseLodash = require('./baseLodash');
+
+        /** Used as references for `-Infinity` and `Infinity`. */
+        var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+
+        /**
+         * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to wrap.
+         */
+        function LazyWrapper(value) {
+            this.__wrapped__ = value;
+            this.__actions__ = [];
+            this.__dir__ = 1;
+            this.__filtered__ = false;
+            this.__iteratees__ = [];
+            this.__takeCount__ = POSITIVE_INFINITY;
+            this.__views__ = [];
+        }
+
+        LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+        LazyWrapper.prototype.constructor = LazyWrapper;
+
+        module.exports = LazyWrapper;
+
+    }, {
+        "./baseCreate": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCreate.js",
+        "./baseLodash": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseLodash.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LodashWrapper.js": [function(require, module, exports) {
+        var baseCreate = require('./baseCreate'),
+            baseLodash = require('./baseLodash');
+
+        /**
+         * The base constructor for creating `lodash` wrapper objects.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to wrap.
+         * @param {boolean}
+         *            [chainAll] Enable chaining for all wrapper methods.
+         * @param {Array}
+         *            [actions=[]] Actions to peform to resolve the unwrapped value.
+         */
+        function LodashWrapper(value, chainAll, actions) {
+            this.__wrapped__ = value;
+            this.__actions__ = actions || [];
+            this.__chain__ = !!chainAll;
+        }
+
+        LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+        LodashWrapper.prototype.constructor = LodashWrapper;
+
+        module.exports = LodashWrapper;
+
+    }, {
+        "./baseCreate": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCreate.js",
+        "./baseLodash": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseLodash.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\SetCache.js": [function(require, module, exports) {
+        (function(global) {
+            var cachePush = require('./cachePush'),
+                getNative = require('./getNative');
+
+            /** Native method references. */
+            var Set = getNative(global, 'Set');
+
+            /*
+             * Native method references for those with the same name as other `lodash`
+             * methods.
+             */
+            var nativeCreate = getNative(Object, 'create');
+
+            /**
+             * 
+             * Creates a cache object to store unique values.
+             * 
+             * @private
+             * @param {Array}
+             *            [values] The values to cache.
+             */
+            function SetCache(values) {
+                var length = values ? values.length : 0;
+
+                this.data = {
+                    'hash': nativeCreate(null),
+                    'set': new Set
+                };
+                while (length--) {
+                    this.push(values[length]);
+                }
+            }
+
+            // Add functions to the `Set` cache.
+            SetCache.prototype.push = cachePush;
+
+            module.exports = SetCache;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./cachePush": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\cachePush.js",
+        "./getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js": [function(require, module, exports) {
+        /**
+         * Copies the values of `source` to `array`.
+         * 
+         * @private
+         * @param {Array}
+         *            source The array to copy values from.
+         * @param {Array}
+         *            [array=[]] The array to copy values to.
+         * @returns {Array} Returns `array`.
+         */
+        function arrayCopy(source, array) {
+            var index = -1,
+                length = source.length;
+
+            array || (array = Array(length));
+            while (++index < length) {
+                array[index] = source[index];
+            }
+            return array;
+        }
+
+        module.exports = arrayCopy;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayEach.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.forEach` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Array} Returns `array`.
+         */
+        function arrayEach(array, iteratee) {
+            var index = -1,
+                length = array.length;
+
+            while (++index < length) {
+                if (iteratee(array[index], index, array) === false) {
+                    break;
+                }
+            }
+            return array;
+        }
+
+        module.exports = arrayEach;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayEvery.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.every` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {boolean} Returns `true` if all elements pass the predicate check,
+         *          else `false`.
+         */
+        function arrayEvery(array, predicate) {
+            var index = -1,
+                length = array.length;
+
+            while (++index < length) {
+                if (!predicate(array[index], index, array)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        module.exports = arrayEvery;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayFilter.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.filter` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {Array} Returns the new filtered array.
+         */
+        function arrayFilter(array, predicate) {
+            var index = -1,
+                length = array.length,
+                resIndex = -1,
+                result = [];
+
+            while (++index < length) {
+                var value = array[index];
+                if (predicate(value, index, array)) {
+                    result[++resIndex] = value;
+                }
+            }
+            return result;
+        }
+
+        module.exports = arrayFilter;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayMap.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.map` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Array} Returns the new mapped array.
+         */
+        function arrayMap(array, iteratee) {
+            var index = -1,
+                length = array.length,
+                result = Array(length);
+
+            while (++index < length) {
+                result[index] = iteratee(array[index], index, array);
+            }
+            return result;
+        }
+
+        module.exports = arrayMap;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayPush.js": [function(require, module, exports) {
+        /**
+         * Appends the elements of `values` to `array`.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to modify.
+         * @param {Array}
+         *            values The values to append.
+         * @returns {Array} Returns `array`.
+         */
+        function arrayPush(array, values) {
+            var index = -1,
+                length = values.length,
+                offset = array.length;
+
+            while (++index < length) {
+                array[offset + index] = values[index];
+            }
+            return array;
+        }
+
+        module.exports = arrayPush;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayReduce.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.reduce` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @param {*}
+         *            [accumulator] The initial value.
+         * @param {boolean}
+         *            [initFromArray] Specify using the first element of `array` as the
+         *            initial value.
+         * @returns {*} Returns the accumulated value.
+         */
+        function arrayReduce(array, iteratee, accumulator, initFromArray) {
+            var index = -1,
+                length = array.length;
+
+            if (initFromArray && length) {
+                accumulator = array[++index];
+            }
+            while (++index < length) {
+                accumulator = iteratee(accumulator, array[index], index, array);
+            }
+            return accumulator;
+        }
+
+        module.exports = arrayReduce;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arraySome.js": [function(require, module, exports) {
+        /**
+         * A specialized version of `_.some` for arrays without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {boolean} Returns `true` if any element passes the predicate check,
+         *          else `false`.
+         */
+        function arraySome(array, predicate) {
+            var index = -1,
+                length = array.length;
+
+            while (++index < length) {
+                if (predicate(array[index], index, array)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        module.exports = arraySome;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\assignWith.js": [function(require, module, exports) {
+        var keys = require('../object/keys');
+
+        /**
+         * A specialized version of `_.assign` for customizing assigned values without
+         * support for argument juggling, multiple sources, and `this` binding
+         * `customizer` functions.
+         * 
+         * @private
+         * @param {Object}
+         *            object The destination object.
+         * @param {Object}
+         *            source The source object.
+         * @param {Function}
+         *            customizer The function to customize assigned values.
+         * @returns {Object} Returns `object`.
+         */
+        function assignWith(object, source, customizer) {
+            var index = -1,
+                props = keys(source),
+                length = props.length;
+
+            while (++index < length) {
+                var key = props[index],
+                    value = object[key],
+                    result = customizer(value, source[key], key, object, source);
+
+                if ((result === result ? (result !== value) : (value === value)) ||
+                    (value === undefined && !(key in object))) {
+                    object[key] = result;
+                }
+            }
+            return object;
+        }
+
+        module.exports = assignWith;
+
+    }, {
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseAssign.js": [function(require, module, exports) {
+        var baseCopy = require('./baseCopy'),
+            keys = require('../object/keys');
+
+        /**
+         * The base implementation of `_.assign` without support for argument juggling,
+         * multiple sources, and `customizer` functions.
+         * 
+         * @private
+         * @param {Object}
+         *            object The destination object.
+         * @param {Object}
+         *            source The source object.
+         * @returns {Object} Returns `object`.
+         */
+        function baseAssign(object, source) {
+            return source == null ? object : baseCopy(source, keys(source), object);
+        }
+
+        module.exports = baseAssign;
+
+    }, {
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js",
+        "./baseCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCopy.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js": [function(require, module, exports) {
+        var baseMatches = require('./baseMatches'),
+            baseMatchesProperty = require('./baseMatchesProperty'),
+            bindCallback = require('./bindCallback'),
+            identity = require('../utility/identity'),
+            property = require('../utility/property');
+
+        /**
+         * The base implementation of `_.callback` which supports specifying the number
+         * of arguments to provide to `func`.
+         * 
+         * @private
+         * @param {*}
+         *            [func=_.identity] The value to convert to a callback.
+         * @param {*}
+         *            [thisArg] The `this` binding of `func`.
+         * @param {number}
+         *            [argCount] The number of arguments to provide to `func`.
+         * @returns {Function} Returns the callback.
+         */
+        function baseCallback(func, thisArg, argCount) {
+            var type = typeof func;
+            if (type == 'function') {
+                return thisArg === undefined ? func : bindCallback(func, thisArg, argCount);
+            }
+            if (func == null) {
+                return identity;
+            }
+            if (type == 'object') {
+                return baseMatches(func);
+            }
+            return thisArg === undefined ? property(func) : baseMatchesProperty(func, thisArg);
+        }
+
+        module.exports = baseCallback;
+
+    }, {
+        "../utility/identity": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\identity.js",
+        "../utility/property": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\property.js",
+        "./baseMatches": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMatches.js",
+        "./baseMatchesProperty": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMatchesProperty.js",
+        "./bindCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCompareAscending.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `compareAscending` which compares values and sorts
+         * them in ascending order without guaranteeing a stable sort.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to compare.
+         * @param {*}
+         *            other The other value to compare.
+         * @returns {number} Returns the sort order indicator for `value`.
+         */
+        function baseCompareAscending(value, other) {
+            if (value !== other) {
+                var valIsNull = value === null,
+                    valIsUndef = value === undefined,
+                    valIsReflexive = value === value;
+
+                var othIsNull = other === null,
+                    othIsUndef = other === undefined,
+                    othIsReflexive = other === other;
+
+                if ((value > other && !othIsNull) || !valIsReflexive ||
+                    (valIsNull && !othIsUndef && othIsReflexive) ||
+                    (valIsUndef && othIsReflexive)) {
+                    return 1;
+                }
+                if ((value < other && !valIsNull) || !othIsReflexive ||
+                    (othIsNull && !valIsUndef && valIsReflexive) ||
+                    (othIsUndef && valIsReflexive)) {
+                    return -1;
+                }
+            }
+            return 0;
+        }
+
+        module.exports = baseCompareAscending;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCopy.js": [function(require, module, exports) {
+        /**
+         * Copies properties of `source` to `object`.
+         * 
+         * @private
+         * @param {Object}
+         *            source The object to copy properties from.
+         * @param {Array}
+         *            props The property names to copy.
+         * @param {Object}
+         *            [object={}] The object to copy properties to.
+         * @returns {Object} Returns `object`.
+         */
+        function baseCopy(source, props, object) {
+            object || (object = {});
+
+            var index = -1,
+                length = props.length;
+
+            while (++index < length) {
+                var key = props[index];
+                object[key] = source[key];
+            }
+            return object;
+        }
+
+        module.exports = baseCopy;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCreate.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject');
+
+        /**
+         * The base implementation of `_.create` without support for assigning
+         * properties to the created object.
+         * 
+         * @private
+         * @param {Object}
+         *            prototype The object to inherit from.
+         * @returns {Object} Returns the new object.
+         */
+        var baseCreate = (function() {
+            function object() {}
+            return function(prototype) {
+                if (isObject(prototype)) {
+                    object.prototype = prototype;
+                    var result = new object;
+                    object.prototype = undefined;
+                }
+                return result || {};
+            };
+        }());
+
+        module.exports = baseCreate;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseDelay.js": [function(require, module, exports) {
+        /** Used as the `TypeError` message for "Functions" methods. */
+        var FUNC_ERROR_TEXT = 'Expected a function';
+
+        /**
+         * The base implementation of `_.delay` and `_.defer` which accepts an index of
+         * where to slice the arguments to provide to `func`.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to delay.
+         * @param {number}
+         *            wait The number of milliseconds to delay invocation.
+         * @param {Object}
+         *            args The arguments provide to `func`.
+         * @returns {number} Returns the timer id.
+         */
+        function baseDelay(func, wait, args) {
+            if (typeof func != 'function') {
+                throw new TypeError(FUNC_ERROR_TEXT);
+            }
+            return setTimeout(function() {
+                func.apply(undefined, args);
+            }, wait);
+        }
+
+        module.exports = baseDelay;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseDifference.js": [function(require, module, exports) {
+        var baseIndexOf = require('./baseIndexOf'),
+            cacheIndexOf = require('./cacheIndexOf'),
+            createCache = require('./createCache');
+
+        /** Used as the size to enable large array optimizations. */
+        var LARGE_ARRAY_SIZE = 200;
+
+        /**
+         * The base implementation of `_.difference` which accepts a single array of
+         * values to exclude.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to inspect.
+         * @param {Array}
+         *            values The values to exclude.
+         * @returns {Array} Returns the new array of filtered values.
+         */
+        function baseDifference(array, values) {
+            var length = array ? array.length : 0,
+                result = [];
+
+            if (!length) {
+                return result;
+            }
+            var index = -1,
+                indexOf = baseIndexOf,
+                isCommon = true,
+                cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null,
+                valuesLength = values.length;
+
+            if (cache) {
+                indexOf = cacheIndexOf;
+                isCommon = false;
+                values = cache;
+            }
+            outer:
+                while (++index < length) {
+                    var value = array[index];
+
+                    if (isCommon && value === value) {
+                        var valuesIndex = valuesLength;
+                        while (valuesIndex--) {
+                            if (values[valuesIndex] === value) {
+                                continue outer;
+                            }
+                        }
+                        result.push(value);
+                    } else if (indexOf(values, value, 0) < 0) {
+                        result.push(value);
+                    }
+                }
+            return result;
+        }
+
+        module.exports = baseDifference;
+
+    }, {
+        "./baseIndexOf": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIndexOf.js",
+        "./cacheIndexOf": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\cacheIndexOf.js",
+        "./createCache": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCache.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js": [function(require, module, exports) {
+        var baseForOwn = require('./baseForOwn'),
+            createBaseEach = require('./createBaseEach');
+
+        /**
+         * The base implementation of `_.forEach` without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Array|Object|string} Returns `collection`.
+         */
+        var baseEach = createBaseEach(baseForOwn);
+
+        module.exports = baseEach;
+
+    }, {
+        "./baseForOwn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseForOwn.js",
+        "./createBaseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBaseEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEvery.js": [function(require, module, exports) {
+        var baseEach = require('./baseEach');
+
+        /**
+         * The base implementation of `_.every` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {boolean} Returns `true` if all elements pass the predicate check,
+         *          else `false`
+         */
+        function baseEvery(collection, predicate) {
+            var result = true;
+            baseEach(collection, function(value, index, collection) {
+                result = !!predicate(value, index, collection);
+                return result;
+            });
+            return result;
+        }
+
+        module.exports = baseEvery;
+
+    }, {
+        "./baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFilter.js": [function(require, module, exports) {
+        var baseEach = require('./baseEach');
+
+        /**
+         * The base implementation of `_.filter` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {Array} Returns the new filtered array.
+         */
+        function baseFilter(collection, predicate) {
+            var result = [];
+            baseEach(collection, function(value, index, collection) {
+                if (predicate(value, index, collection)) {
+                    result.push(value);
+                }
+            });
+            return result;
+        }
+
+        module.exports = baseFilter;
+
+    }, {
+        "./baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFind.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and
+         * `_.findLastKey`, without support for callback shorthands and `this` binding,
+         * which iterates over `collection` using the provided `eachFunc`.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to search.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @param {Function}
+         *            eachFunc The function to iterate over `collection`.
+         * @param {boolean}
+         *            [retKey] Specify returning the key of the found element instead of
+         *            the element itself.
+         * @returns {*} Returns the found element or its key, else `undefined`.
+         */
+        function baseFind(collection, predicate, eachFunc, retKey) {
+            var result;
+            eachFunc(collection, function(value, key, collection) {
+                if (predicate(value, key, collection)) {
+                    result = retKey ? key : value;
+                    return false;
+                }
+            });
+            return result;
+        }
+
+        module.exports = baseFind;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFindIndex.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.findIndex` and `_.findLastIndex` without
+         * support for callback shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to search.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @param {boolean}
+         *            [fromRight] Specify iterating from right to left.
+         * @returns {number} Returns the index of the matched value, else `-1`.
+         */
+        function baseFindIndex(array, predicate, fromRight) {
+            var length = array.length,
+                index = fromRight ? length : -1;
+
+            while ((fromRight ? index-- : ++index < length)) {
+                if (predicate(array[index], index, array)) {
+                    return index;
+                }
+            }
+            return -1;
+        }
+
+        module.exports = baseFindIndex;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFlatten.js": [function(require, module, exports) {
+        var arrayPush = require('./arrayPush'),
+            isArguments = require('../lang/isArguments'),
+            isArray = require('../lang/isArray'),
+            isArrayLike = require('./isArrayLike'),
+            isObjectLike = require('./isObjectLike');
+
+        /**
+         * The base implementation of `_.flatten` with added support for restricting
+         * flattening and specifying the start index.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to flatten.
+         * @param {boolean}
+         *            [isDeep] Specify a deep flatten.
+         * @param {boolean}
+         *            [isStrict] Restrict flattening to arrays-like objects.
+         * @param {Array}
+         *            [result=[]] The initial result value.
+         * @returns {Array} Returns the new flattened array.
+         */
+        function baseFlatten(array, isDeep, isStrict, result) {
+            result || (result = []);
+
+            var index = -1,
+                length = array.length;
+
+            while (++index < length) {
+                var value = array[index];
+                if (isObjectLike(value) && isArrayLike(value) &&
+                    (isStrict || isArray(value) || isArguments(value))) {
+                    if (isDeep) {
+                        // Recursively flatten arrays (susceptible to call stack limits).
+                        baseFlatten(value, isDeep, isStrict, result);
+                    } else {
+                        arrayPush(result, value);
+                    }
+                } else if (!isStrict) {
+                    result[result.length] = value;
+                }
+            }
+            return result;
+        }
+
+        module.exports = baseFlatten;
+
+    }, {
+        "../lang/isArguments": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./arrayPush": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayPush.js",
+        "./isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js",
+        "./isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFor.js": [function(require, module, exports) {
+        var createBaseFor = require('./createBaseFor');
+
+        /**
+         * The base implementation of `baseForIn` and `baseForOwn` which iterates over
+         * `object` properties returned by `keysFunc` invoking `iteratee` for each
+         * property. Iteratee functions may exit iteration early by explicitly returning
+         * `false`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @param {Function}
+         *            keysFunc The function to get the keys of `object`.
+         * @returns {Object} Returns `object`.
+         */
+        var baseFor = createBaseFor();
+
+        module.exports = baseFor;
+
+    }, {
+        "./createBaseFor": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBaseFor.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseForIn.js": [function(require, module, exports) {
+        var baseFor = require('./baseFor'),
+            keysIn = require('../object/keysIn');
+
+        /**
+         * The base implementation of `_.forIn` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Object} Returns `object`.
+         */
+        function baseForIn(object, iteratee) {
+            return baseFor(object, iteratee, keysIn);
+        }
+
+        module.exports = baseForIn;
+
+    }, {
+        "../object/keysIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keysIn.js",
+        "./baseFor": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFor.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseForOwn.js": [function(require, module, exports) {
+        var baseFor = require('./baseFor'),
+            keys = require('../object/keys');
+
+        /**
+         * The base implementation of `_.forOwn` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Object} Returns `object`.
+         */
+        function baseForOwn(object, iteratee) {
+            return baseFor(object, iteratee, keys);
+        }
+
+        module.exports = baseForOwn;
+
+    }, {
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js",
+        "./baseFor": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFor.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseGet.js": [function(require, module, exports) {
+        var toObject = require('./toObject');
+
+        /**
+         * The base implementation of `get` without support for string paths and default
+         * values.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @param {Array}
+         *            path The path of the property to get.
+         * @param {string}
+         *            [pathKey] The key representation of path.
+         * @returns {*} Returns the resolved value.
+         */
+        function baseGet(object, path, pathKey) {
+            if (object == null) {
+                return;
+            }
+            if (pathKey !== undefined && pathKey in toObject(object)) {
+                path = [pathKey];
+            }
+            var index = 0,
+                length = path.length;
+
+            while (object != null && index < length) {
+                object = object[path[index++]];
+            }
+            return (index && index == length) ? object : undefined;
+        }
+
+        module.exports = baseGet;
+
+    }, {
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIndexOf.js": [function(require, module, exports) {
+        var indexOfNaN = require('./indexOfNaN');
+
+        /**
+         * The base implementation of `_.indexOf` without support for binary searches.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to search.
+         * @param {*}
+         *            value The value to search for.
+         * @param {number}
+         *            fromIndex The index to search from.
+         * @returns {number} Returns the index of the matched value, else `-1`.
+         */
+        function baseIndexOf(array, value, fromIndex) {
+            if (value !== value) {
+                return indexOfNaN(array, fromIndex);
+            }
+            var index = fromIndex - 1,
+                length = array.length;
+
+            while (++index < length) {
+                if (array[index] === value) {
+                    return index;
+                }
+            }
+            return -1;
+        }
+
+        module.exports = baseIndexOf;
+
+    }, {
+        "./indexOfNaN": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\indexOfNaN.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsEqual.js": [function(require, module, exports) {
+        var baseIsEqualDeep = require('./baseIsEqualDeep'),
+            isObject = require('../lang/isObject'),
+            isObjectLike = require('./isObjectLike');
+
+        /**
+         * The base implementation of `_.isEqual` without support for `this` binding
+         * `customizer` functions.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to compare.
+         * @param {*}
+         *            other The other value to compare.
+         * @param {Function}
+         *            [customizer] The function to customize comparing values.
+         * @param {boolean}
+         *            [isLoose] Specify performing partial comparisons.
+         * @param {Array}
+         *            [stackA] Tracks traversed `value` objects.
+         * @param {Array}
+         *            [stackB] Tracks traversed `other` objects.
+         * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+         */
+        function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+            if (value === other) {
+                return true;
+            }
+            if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+                return value !== value && other !== other;
+            }
+            return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+        }
+
+        module.exports = baseIsEqual;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "./baseIsEqualDeep": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsEqualDeep.js",
+        "./isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsEqualDeep.js": [function(require, module, exports) {
+        var equalArrays = require('./equalArrays'),
+            equalByTag = require('./equalByTag'),
+            equalObjects = require('./equalObjects'),
+            isArray = require('../lang/isArray'),
+            isTypedArray = require('../lang/isTypedArray');
+
+        /** `Object#toString` result references. */
+        var argsTag = '[object Arguments]',
+            arrayTag = '[object Array]',
+            objectTag = '[object Object]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * A specialized version of `baseIsEqual` for arrays and objects which performs
+         * deep comparisons and tracks traversed objects enabling objects with circular
+         * references to be compared.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to compare.
+         * @param {Object}
+         *            other The other object to compare.
+         * @param {Function}
+         *            equalFunc The function to determine equivalents of values.
+         * @param {Function}
+         *            [customizer] The function to customize comparing objects.
+         * @param {boolean}
+         *            [isLoose] Specify performing partial comparisons.
+         * @param {Array}
+         *            [stackA=[]] Tracks traversed `value` objects.
+         * @param {Array}
+         *            [stackB=[]] Tracks traversed `other` objects.
+         * @returns {boolean} Returns `true` if the objects are equivalent, else
+         *          `false`.
+         */
+        function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+            var objIsArr = isArray(object),
+                othIsArr = isArray(other),
+                objTag = arrayTag,
+                othTag = arrayTag;
+
+            if (!objIsArr) {
+                objTag = objToString.call(object);
+                if (objTag == argsTag) {
+                    objTag = objectTag;
+                } else if (objTag != objectTag) {
+                    objIsArr = isTypedArray(object);
+                }
+            }
+            if (!othIsArr) {
+                othTag = objToString.call(other);
+                if (othTag == argsTag) {
+                    othTag = objectTag;
+                } else if (othTag != objectTag) {
+                    othIsArr = isTypedArray(other);
+                }
+            }
+            var objIsObj = objTag == objectTag,
+                othIsObj = othTag == objectTag,
+                isSameTag = objTag == othTag;
+
+            if (isSameTag && !(objIsArr || objIsObj)) {
+                return equalByTag(object, other, objTag);
+            }
+            if (!isLoose) {
+                var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+                    othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+                if (objIsWrapped || othIsWrapped) {
+                    return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+                }
+            }
+            if (!isSameTag) {
+                return false;
+            }
+            // Assume cyclic values are equal.
+            // For more information on detecting circular references see
+            // https://es5.github.io/#JO.
+            stackA || (stackA = []);
+            stackB || (stackB = []);
+
+            var length = stackA.length;
+            while (length--) {
+                if (stackA[length] == object) {
+                    return stackB[length] == other;
+                }
+            }
+            // Add `object` and `other` to the stack of traversed objects.
+            stackA.push(object);
+            stackB.push(other);
+
+            var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
+
+            stackA.pop();
+            stackB.pop();
+
+            return result;
+        }
+
+        module.exports = baseIsEqualDeep;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../lang/isTypedArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isTypedArray.js",
+        "./equalArrays": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalArrays.js",
+        "./equalByTag": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalByTag.js",
+        "./equalObjects": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalObjects.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsMatch.js": [function(require, module, exports) {
+        var baseIsEqual = require('./baseIsEqual'),
+            toObject = require('./toObject');
+
+        /**
+         * The base implementation of `_.isMatch` without support for callback
+         * shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to inspect.
+         * @param {Array}
+         *            matchData The propery names, values, and compare flags to match.
+         * @param {Function}
+         *            [customizer] The function to customize comparing objects.
+         * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+         */
+        function baseIsMatch(object, matchData, customizer) {
+            var index = matchData.length,
+                length = index,
+                noCustomizer = !customizer;
+
+            if (object == null) {
+                return !length;
+            }
+            object = toObject(object);
+            while (index--) {
+                var data = matchData[index];
+                if ((noCustomizer && data[2]) ? data[1] !== object[data[0]] : !(data[0] in object)) {
+                    return false;
+                }
+            }
+            while (++index < length) {
+                data = matchData[index];
+                var key = data[0],
+                    objValue = object[key],
+                    srcValue = data[1];
+
+                if (noCustomizer && data[2]) {
+                    if (objValue === undefined && !(key in object)) {
+                        return false;
+                    }
+                } else {
+                    var result = customizer ? customizer(objValue, srcValue, key) : undefined;
+                    if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        module.exports = baseIsMatch;
+
+    }, {
+        "./baseIsEqual": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsEqual.js",
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseLodash.js": [function(require, module, exports) {
+        /**
+         * The function whose prototype all chaining wrappers inherit from.
+         * 
+         * @private
+         */
+        function baseLodash() {
+            // No operation performed.
+        }
+
+        module.exports = baseLodash;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMap.js": [function(require, module, exports) {
+        var baseEach = require('./baseEach'),
+            isArrayLike = require('./isArrayLike');
+
+        /**
+         * The base implementation of `_.map` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @returns {Array} Returns the new mapped array.
+         */
+        function baseMap(collection, iteratee) {
+            var index = -1,
+                result = isArrayLike(collection) ? Array(collection.length) : [];
+
+            baseEach(collection, function(value, key, collection) {
+                result[++index] = iteratee(value, key, collection);
+            });
+            return result;
+        }
+
+        module.exports = baseMap;
+
+    }, {
+        "./baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js",
+        "./isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMatches.js": [function(require, module, exports) {
+        var baseIsMatch = require('./baseIsMatch'),
+            getMatchData = require('./getMatchData'),
+            toObject = require('./toObject');
+
+        /**
+         * The base implementation of `_.matches` which does not clone `source`.
+         * 
+         * @private
+         * @param {Object}
+         *            source The object of property values to match.
+         * @returns {Function} Returns the new function.
+         */
+        function baseMatches(source) {
+            var matchData = getMatchData(source);
+            if (matchData.length == 1 && matchData[0][2]) {
+                var key = matchData[0][0],
+                    value = matchData[0][1];
+
+                return function(object) {
+                    if (object == null) {
+                        return false;
+                    }
+                    return object[key] === value && (value !== undefined || (key in toObject(object)));
+                };
+            }
+            return function(object) {
+                return baseIsMatch(object, matchData);
+            };
+        }
+
+        module.exports = baseMatches;
+
+    }, {
+        "./baseIsMatch": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsMatch.js",
+        "./getMatchData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getMatchData.js",
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMatchesProperty.js": [function(require, module, exports) {
+        var baseGet = require('./baseGet'),
+            baseIsEqual = require('./baseIsEqual'),
+            baseSlice = require('./baseSlice'),
+            isArray = require('../lang/isArray'),
+            isKey = require('./isKey'),
+            isStrictComparable = require('./isStrictComparable'),
+            last = require('../array/last'),
+            toObject = require('./toObject'),
+            toPath = require('./toPath');
+
+        /**
+         * The base implementation of `_.matchesProperty` which does not clone
+         * `srcValue`.
+         * 
+         * @private
+         * @param {string}
+         *            path The path of the property to get.
+         * @param {*}
+         *            srcValue The value to compare.
+         * @returns {Function} Returns the new function.
+         */
+        function baseMatchesProperty(path, srcValue) {
+            var isArr = isArray(path),
+                isCommon = isKey(path) && isStrictComparable(srcValue),
+                pathKey = (path + '');
+
+            path = toPath(path);
+            return function(object) {
+                if (object == null) {
+                    return false;
+                }
+                var key = pathKey;
+                object = toObject(object);
+                if ((isArr || !isCommon) && !(key in object)) {
+                    object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+                    if (object == null) {
+                        return false;
+                    }
+                    key = last(path);
+                    object = toObject(object);
+                }
+                return object[key] === srcValue ? (srcValue !== undefined || (key in object)) : baseIsEqual(srcValue, object[key], undefined, true);
+            };
+        }
+
+        module.exports = baseMatchesProperty;
+
+    }, {
+        "../array/last": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\array\\last.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./baseGet": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseGet.js",
+        "./baseIsEqual": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIsEqual.js",
+        "./baseSlice": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSlice.js",
+        "./isKey": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isKey.js",
+        "./isStrictComparable": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isStrictComparable.js",
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js",
+        "./toPath": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toPath.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMerge.js": [function(require, module, exports) {
+        var arrayEach = require('./arrayEach'),
+            baseMergeDeep = require('./baseMergeDeep'),
+            isArray = require('../lang/isArray'),
+            isArrayLike = require('./isArrayLike'),
+            isObject = require('../lang/isObject'),
+            isObjectLike = require('./isObjectLike'),
+            isTypedArray = require('../lang/isTypedArray'),
+            keys = require('../object/keys');
+
+        /**
+         * The base implementation of `_.merge` without support for argument juggling,
+         * multiple sources, and `this` binding `customizer` functions.
+         * 
+         * @private
+         * @param {Object}
+         *            object The destination object.
+         * @param {Object}
+         *            source The source object.
+         * @param {Function}
+         *            [customizer] The function to customize merged values.
+         * @param {Array}
+         *            [stackA=[]] Tracks traversed source objects.
+         * @param {Array}
+         *            [stackB=[]] Associates values with source counterparts.
+         * @returns {Object} Returns `object`.
+         */
+        function baseMerge(object, source, customizer, stackA, stackB) {
+            if (!isObject(object)) {
+                return object;
+            }
+            var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
+                props = isSrcArr ? undefined : keys(source);
+
+            arrayEach(props || source, function(srcValue, key) {
+                if (props) {
+                    key = srcValue;
+                    srcValue = source[key];
+                }
+                if (isObjectLike(srcValue)) {
+                    stackA || (stackA = []);
+                    stackB || (stackB = []);
+                    baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
+                } else {
+                    var value = object[key],
+                        result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
+                        isCommon = result === undefined;
+
+                    if (isCommon) {
+                        result = srcValue;
+                    }
+                    if ((result !== undefined || (isSrcArr && !(key in object))) &&
+                        (isCommon || (result === result ? (result !== value) : (value === value)))) {
+                        object[key] = result;
+                    }
+                }
+            });
+            return object;
+        }
+
+        module.exports = baseMerge;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "../lang/isTypedArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isTypedArray.js",
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js",
+        "./arrayEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayEach.js",
+        "./baseMergeDeep": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMergeDeep.js",
+        "./isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js",
+        "./isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMergeDeep.js": [function(require, module, exports) {
+        var arrayCopy = require('./arrayCopy'),
+            isArguments = require('../lang/isArguments'),
+            isArray = require('../lang/isArray'),
+            isArrayLike = require('./isArrayLike'),
+            isPlainObject = require('../lang/isPlainObject'),
+            isTypedArray = require('../lang/isTypedArray'),
+            toPlainObject = require('../lang/toPlainObject');
+
+        /**
+         * A specialized version of `baseMerge` for arrays and objects which performs
+         * deep merges and tracks traversed objects enabling objects with circular
+         * references to be merged.
+         * 
+         * @private
+         * @param {Object}
+         *            object The destination object.
+         * @param {Object}
+         *            source The source object.
+         * @param {string}
+         *            key The key of the value to merge.
+         * @param {Function}
+         *            mergeFunc The function to merge values.
+         * @param {Function}
+         *            [customizer] The function to customize merged values.
+         * @param {Array}
+         *            [stackA=[]] Tracks traversed source objects.
+         * @param {Array}
+         *            [stackB=[]] Associates values with source counterparts.
+         * @returns {boolean} Returns `true` if the objects are equivalent, else
+         *          `false`.
+         */
+        function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
+            var length = stackA.length,
+                srcValue = source[key];
+
+            while (length--) {
+                if (stackA[length] == srcValue) {
+                    object[key] = stackB[length];
+                    return;
+                }
+            }
+            var value = object[key],
+                result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
+                isCommon = result === undefined;
+
+            if (isCommon) {
+                result = srcValue;
+                if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
+                    result = isArray(value) ? value : (isArrayLike(value) ? arrayCopy(value) : []);
+                } else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+                    result = isArguments(value) ? toPlainObject(value) : (isPlainObject(value) ? value : {});
+                } else {
+                    isCommon = false;
+                }
+            }
+            // Add the source value to the stack of traversed objects and associate
+            // it with its merged value.
+            stackA.push(srcValue);
+            stackB.push(result);
+
+            if (isCommon) {
+                // Recursively merge objects and arrays (susceptible to call stack limits).
+                object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
+            } else if (result === result ? (result !== value) : (value === value)) {
+                object[key] = result;
+            }
+        }
+
+        module.exports = baseMergeDeep;
+
+    }, {
+        "../lang/isArguments": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../lang/isPlainObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isPlainObject.js",
+        "../lang/isTypedArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isTypedArray.js",
+        "../lang/toPlainObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\toPlainObject.js",
+        "./arrayCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js",
+        "./isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseProperty.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.property` without support for deep paths.
+         * 
+         * @private
+         * @param {string}
+         *            key The key of the property to get.
+         * @returns {Function} Returns the new function.
+         */
+        function baseProperty(key) {
+            return function(object) {
+                return object == null ? undefined : object[key];
+            };
+        }
+
+        module.exports = baseProperty;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\basePropertyDeep.js": [function(require, module, exports) {
+        var baseGet = require('./baseGet'),
+            toPath = require('./toPath');
+
+        /**
+         * A specialized version of `baseProperty` which supports deep paths.
+         * 
+         * @private
+         * @param {Array|string}
+         *            path The path of the property to get.
+         * @returns {Function} Returns the new function.
+         */
+        function basePropertyDeep(path) {
+            var pathKey = (path + '');
+            path = toPath(path);
+            return function(object) {
+                return baseGet(object, path, pathKey);
+            };
+        }
+
+        module.exports = basePropertyDeep;
+
+    }, {
+        "./baseGet": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseGet.js",
+        "./toPath": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toPath.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseReduce.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.reduce` and `_.reduceRight` without support for
+         * callback shorthands and `this` binding, which iterates over `collection`
+         * using the provided `eachFunc`.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            iteratee The function invoked per iteration.
+         * @param {*}
+         *            accumulator The initial value.
+         * @param {boolean}
+         *            initFromCollection Specify using the first or last element of
+         *            `collection` as the initial value.
+         * @param {Function}
+         *            eachFunc The function to iterate over `collection`.
+         * @returns {*} Returns the accumulated value.
+         */
+        function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
+            eachFunc(collection, function(value, index, collection) {
+                accumulator = initFromCollection ? (initFromCollection = false, value) : iteratee(accumulator, value, index, collection);
+            });
+            return accumulator;
+        }
+
+        module.exports = baseReduce;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSetData.js": [function(require, module, exports) {
+        var identity = require('../utility/identity'),
+            metaMap = require('./metaMap');
+
+        /**
+         * The base implementation of `setData` without support for hot loop detection.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to associate metadata with.
+         * @param {*}
+         *            data The metadata.
+         * @returns {Function} Returns `func`.
+         */
+        var baseSetData = !metaMap ? identity : function(func, data) {
+            metaMap.set(func, data);
+            return func;
+        };
+
+        module.exports = baseSetData;
+
+    }, {
+        "../utility/identity": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\identity.js",
+        "./metaMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\metaMap.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSlice.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.slice` without an iteratee call guard.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to slice.
+         * @param {number}
+         *            [start=0] The start position.
+         * @param {number}
+         *            [end=array.length] The end position.
+         * @returns {Array} Returns the slice of `array`.
+         */
+        function baseSlice(array, start, end) {
+            var index = -1,
+                length = array.length;
+
+            start = start == null ? 0 : (+start || 0);
+            if (start < 0) {
+                start = -start > length ? 0 : (length + start);
+            }
+            end = (end === undefined || end > length) ? length : (+end || 0);
+            if (end < 0) {
+                end += length;
+            }
+            length = start > end ? 0 : ((end - start) >>> 0);
+            start >>>= 0;
+
+            var result = Array(length);
+            while (++index < length) {
+                result[index] = array[index + start];
+            }
+            return result;
+        }
+
+        module.exports = baseSlice;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSome.js": [function(require, module, exports) {
+        var baseEach = require('./baseEach');
+
+        /**
+         * The base implementation of `_.some` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Array|Object|string}
+         *            collection The collection to iterate over.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {boolean} Returns `true` if any element passes the predicate check,
+         *          else `false`.
+         */
+        function baseSome(collection, predicate) {
+            var result;
+
+            baseEach(collection, function(value, index, collection) {
+                result = predicate(value, index, collection);
+                return !result;
+            });
+            return !!result;
+        }
+
+        module.exports = baseSome;
+
+    }, {
+        "./baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSortBy.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.sortBy` which uses `comparer` to define the
+         * sort order of `array` and replaces criteria objects with their corresponding
+         * values.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to sort.
+         * @param {Function}
+         *            comparer The function to define sort order.
+         * @returns {Array} Returns `array`.
+         */
+        function baseSortBy(array, comparer) {
+            var length = array.length;
+
+            array.sort(comparer);
+            while (length--) {
+                array[length] = array[length].value;
+            }
+            return array;
+        }
+
+        module.exports = baseSortBy;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseToString.js": [function(require, module, exports) {
+        /**
+         * Converts `value` to a string if it's not one. An empty string is returned for
+         * `null` or `undefined` values.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to process.
+         * @returns {string} Returns the string.
+         */
+        function baseToString(value) {
+            return value == null ? '' : (value + '');
+        }
+
+        module.exports = baseToString;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseUniq.js": [function(require, module, exports) {
+        var baseIndexOf = require('./baseIndexOf'),
+            cacheIndexOf = require('./cacheIndexOf'),
+            createCache = require('./createCache');
+
+        /** Used as the size to enable large array optimizations. */
+        var LARGE_ARRAY_SIZE = 200;
+
+        /**
+         * The base implementation of `_.uniq` without support for callback shorthands
+         * and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to inspect.
+         * @param {Function}
+         *            [iteratee] The function invoked per iteration.
+         * @returns {Array} Returns the new duplicate free array.
+         */
+        function baseUniq(array, iteratee) {
+            var index = -1,
+                indexOf = baseIndexOf,
+                length = array.length,
+                isCommon = true,
+                isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
+                seen = isLarge ? createCache() : null,
+                result = [];
+
+            if (seen) {
+                indexOf = cacheIndexOf;
+                isCommon = false;
+            } else {
+                isLarge = false;
+                seen = iteratee ? [] : result;
+            }
+            outer:
+                while (++index < length) {
+                    var value = array[index],
+                        computed = iteratee ? iteratee(value, index, array) : value;
+
+                    if (isCommon && value === value) {
+                        var seenIndex = seen.length;
+                        while (seenIndex--) {
+                            if (seen[seenIndex] === computed) {
+                                continue outer;
+                            }
+                        }
+                        if (iteratee) {
+                            seen.push(computed);
+                        }
+                        result.push(value);
+                    } else if (indexOf(seen, computed, 0) < 0) {
+                        if (iteratee || isLarge) {
+                            seen.push(computed);
+                        }
+                        result.push(value);
+                    }
+                }
+            return result;
+        }
+
+        module.exports = baseUniq;
+
+    }, {
+        "./baseIndexOf": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseIndexOf.js",
+        "./cacheIndexOf": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\cacheIndexOf.js",
+        "./createCache": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCache.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseValues.js": [function(require, module, exports) {
+        /**
+         * The base implementation of `_.values` and `_.valuesIn` which creates an array
+         * of `object` property values corresponding to the property names of `props`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @param {Array}
+         *            props The property names to get values for.
+         * @returns {Object} Returns the array of property values.
+         */
+        function baseValues(object, props) {
+            var index = -1,
+                length = props.length,
+                result = Array(length);
+
+            while (++index < length) {
+                result[index] = object[props[index]];
+            }
+            return result;
+        }
+
+        module.exports = baseValues;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js": [function(require, module, exports) {
+        var identity = require('../utility/identity');
+
+        /**
+         * A specialized version of `baseCallback` which only supports `this` binding
+         * and specifying the number of arguments to provide to `func`.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to bind.
+         * @param {*}
+         *            thisArg The `this` binding of `func`.
+         * @param {number}
+         *            [argCount] The number of arguments to provide to `func`.
+         * @returns {Function} Returns the callback.
+         */
+        function bindCallback(func, thisArg, argCount) {
+            if (typeof func != 'function') {
+                return identity;
+            }
+            if (thisArg === undefined) {
+                return func;
+            }
+            switch (argCount) {
+                case 1:
+                    return function(value) {
+                        return func.call(thisArg, value);
+                    };
+                case 3:
+                    return function(value, index, collection) {
+                        return func.call(thisArg, value, index, collection);
+                    };
+                case 4:
+                    return function(accumulator, value, index, collection) {
+                        return func.call(thisArg, accumulator, value, index, collection);
+                    };
+                case 5:
+                    return function(value, other, key, object, source) {
+                        return func.call(thisArg, value, other, key, object, source);
+                    };
+            }
+            return function() {
+                return func.apply(thisArg, arguments);
+            };
+        }
+
+        module.exports = bindCallback;
+
+    }, {
+        "../utility/identity": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\identity.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\cacheIndexOf.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject');
+
+        /**
+         * Checks if `value` is in `cache` mimicking the return signature of `_.indexOf`
+         * by returning `0` if the value is found, else `-1`.
+         * 
+         * @private
+         * @param {Object}
+         *            cache The cache to search.
+         * @param {*}
+         *            value The value to search for.
+         * @returns {number} Returns `0` if `value` is found, else `-1`.
+         */
+        function cacheIndexOf(cache, value) {
+            var data = cache.data,
+                result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
+
+            return result ? 0 : -1;
+        }
+
+        module.exports = cacheIndexOf;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\cachePush.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject');
+
+        /**
+         * Adds `value` to the cache.
+         * 
+         * @private
+         * @name push
+         * @memberOf SetCache
+         * @param {*}
+         *            value The value to cache.
+         */
+        function cachePush(value) {
+            var data = this.data;
+            if (typeof value == 'string' || isObject(value)) {
+                data.set.add(value);
+            } else {
+                data.hash[value] = true;
+            }
+        }
+
+        module.exports = cachePush;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\compareAscending.js": [function(require, module, exports) {
+        var baseCompareAscending = require('./baseCompareAscending');
+
+        /**
+         * Used by `_.sortBy` to compare transformed elements of a collection and stable
+         * sort them in ascending order.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to compare.
+         * @param {Object}
+         *            other The other object to compare.
+         * @returns {number} Returns the sort order indicator for `object`.
+         */
+        function compareAscending(object, other) {
+            return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index);
+        }
+
+        module.exports = compareAscending;
+
+    }, {
+        "./baseCompareAscending": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCompareAscending.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgs.js": [function(require, module, exports) {
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * Creates an array that is the composition of partially applied arguments,
+         * placeholders, and provided arguments into a single array of arguments.
+         * 
+         * @private
+         * @param {Array|Object}
+         *            args The provided arguments.
+         * @param {Array}
+         *            partials The arguments to prepend to those provided.
+         * @param {Array}
+         *            holders The `partials` placeholder indexes.
+         * @returns {Array} Returns the new array of composed arguments.
+         */
+        function composeArgs(args, partials, holders) {
+            var holdersLength = holders.length,
+                argsIndex = -1,
+                argsLength = nativeMax(args.length - holdersLength, 0),
+                leftIndex = -1,
+                leftLength = partials.length,
+                result = Array(leftLength + argsLength);
+
+            while (++leftIndex < leftLength) {
+                result[leftIndex] = partials[leftIndex];
+            }
+            while (++argsIndex < holdersLength) {
+                result[holders[argsIndex]] = args[argsIndex];
+            }
+            while (argsLength--) {
+                result[leftIndex++] = args[argsIndex++];
+            }
+            return result;
+        }
+
+        module.exports = composeArgs;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgsRight.js": [function(require, module, exports) {
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * This function is like `composeArgs` except that the arguments composition is
+         * tailored for `_.partialRight`.
+         * 
+         * @private
+         * @param {Array|Object}
+         *            args The provided arguments.
+         * @param {Array}
+         *            partials The arguments to append to those provided.
+         * @param {Array}
+         *            holders The `partials` placeholder indexes.
+         * @returns {Array} Returns the new array of composed arguments.
+         */
+        function composeArgsRight(args, partials, holders) {
+            var holdersIndex = -1,
+                holdersLength = holders.length,
+                argsIndex = -1,
+                argsLength = nativeMax(args.length - holdersLength, 0),
+                rightIndex = -1,
+                rightLength = partials.length,
+                result = Array(argsLength + rightLength);
+
+            while (++argsIndex < argsLength) {
+                result[argsIndex] = args[argsIndex];
+            }
+            var offset = argsIndex;
+            while (++rightIndex < rightLength) {
+                result[offset + rightIndex] = partials[rightIndex];
+            }
+            while (++holdersIndex < holdersLength) {
+                result[offset + holders[holdersIndex]] = args[argsIndex++];
+            }
+            return result;
+        }
+
+        module.exports = composeArgsRight;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createAggregator.js": [function(require, module, exports) {
+        var baseCallback = require('./baseCallback'),
+            baseEach = require('./baseEach'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function.
+         * 
+         * @private
+         * @param {Function}
+         *            setter The function to set keys and values of the accumulator
+         *            object.
+         * @param {Function}
+         *            [initializer] The function to initialize the accumulator object.
+         * @returns {Function} Returns the new aggregator function.
+         */
+        function createAggregator(setter, initializer) {
+            return function(collection, iteratee, thisArg) {
+                var result = initializer ? initializer() : {};
+                iteratee = baseCallback(iteratee, thisArg, 3);
+
+                if (isArray(collection)) {
+                    var index = -1,
+                        length = collection.length;
+
+                    while (++index < length) {
+                        var value = collection[index];
+                        setter(result, value, iteratee(value, index, collection), collection);
+                    }
+                } else {
+                    baseEach(collection, function(value, key, collection) {
+                        setter(result, value, iteratee(value, key, collection), collection);
+                    });
+                }
+                return result;
+            };
+        }
+
+        module.exports = createAggregator;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "./baseEach": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseEach.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createAssigner.js": [function(require, module, exports) {
+        var bindCallback = require('./bindCallback'),
+            isIterateeCall = require('./isIterateeCall'),
+            restParam = require('../function/restParam');
+
+        /**
+         * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
+         * 
+         * @private
+         * @param {Function}
+         *            assigner The function to assign values.
+         * @returns {Function} Returns the new assigner function.
+         */
+        function createAssigner(assigner) {
+            return restParam(function(object, sources) {
+                var index = -1,
+                    length = object == null ? 0 : sources.length,
+                    customizer = length > 2 ? sources[length - 2] : undefined,
+                    guard = length > 2 ? sources[2] : undefined,
+                    thisArg = length > 1 ? sources[length - 1] : undefined;
+
+                if (typeof customizer == 'function') {
+                    customizer = bindCallback(customizer, thisArg, 5);
+                    length -= 2;
+                } else {
+                    customizer = typeof thisArg == 'function' ? thisArg : undefined;
+                    length -= (customizer ? 1 : 0);
+                }
+                if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+                    customizer = length < 3 ? undefined : customizer;
+                    length = 1;
+                }
+                while (++index < length) {
+                    var source = sources[index];
+                    if (source) {
+                        assigner(object, source, customizer);
+                    }
+                }
+                return object;
+            });
+        }
+
+        module.exports = createAssigner;
+
+    }, {
+        "../function/restParam": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js",
+        "./bindCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js",
+        "./isIterateeCall": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBaseEach.js": [function(require, module, exports) {
+        var getLength = require('./getLength'),
+            isLength = require('./isLength'),
+            toObject = require('./toObject');
+
+        /**
+         * Creates a `baseEach` or `baseEachRight` function.
+         * 
+         * @private
+         * @param {Function}
+         *            eachFunc The function to iterate over a collection.
+         * @param {boolean}
+         *            [fromRight] Specify iterating from right to left.
+         * @returns {Function} Returns the new base function.
+         */
+        function createBaseEach(eachFunc, fromRight) {
+            return function(collection, iteratee) {
+                var length = collection ? getLength(collection) : 0;
+                if (!isLength(length)) {
+                    return eachFunc(collection, iteratee);
+                }
+                var index = fromRight ? length : -1,
+                    iterable = toObject(collection);
+
+                while ((fromRight ? index-- : ++index < length)) {
+                    if (iteratee(iterable[index], index, iterable) === false) {
+                        break;
+                    }
+                }
+                return collection;
+            };
+        }
+
+        module.exports = createBaseEach;
+
+    }, {
+        "./getLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getLength.js",
+        "./isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBaseFor.js": [function(require, module, exports) {
+        var toObject = require('./toObject');
+
+        /**
+         * Creates a base function for `_.forIn` or `_.forInRight`.
+         * 
+         * @private
+         * @param {boolean}
+         *            [fromRight] Specify iterating from right to left.
+         * @returns {Function} Returns the new base function.
+         */
+        function createBaseFor(fromRight) {
+            return function(object, iteratee, keysFunc) {
+                var iterable = toObject(object),
+                    props = keysFunc(object),
+                    length = props.length,
+                    index = fromRight ? length : -1;
+
+                while ((fromRight ? index-- : ++index < length)) {
+                    var key = props[index];
+                    if (iteratee(iterable[key], key, iterable) === false) {
+                        break;
+                    }
+                }
+                return object;
+            };
+        }
+
+        module.exports = createBaseFor;
+
+    }, {
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBindWrapper.js": [function(require, module, exports) {
+        (function(global) {
+            var createCtorWrapper = require('./createCtorWrapper');
+
+            /**
+             * Creates a function that wraps `func` and invokes it with the `this` binding
+             * of `thisArg`.
+             * 
+             * @private
+             * @param {Function}
+             *            func The function to bind.
+             * @param {*}
+             *            [thisArg] The `this` binding of `func`.
+             * @returns {Function} Returns the new bound function.
+             */
+            function createBindWrapper(func, thisArg) {
+                var Ctor = createCtorWrapper(func);
+
+                function wrapper() {
+                    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+                    return fn.apply(thisArg, arguments);
+                }
+                return wrapper;
+            }
+
+            module.exports = createBindWrapper;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./createCtorWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCtorWrapper.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCache.js": [function(require, module, exports) {
+        (function(global) {
+            var SetCache = require('./SetCache'),
+                getNative = require('./getNative');
+
+            /** Native method references. */
+            var Set = getNative(global, 'Set');
+
+            /*
+             * Native method references for those with the same name as other `lodash`
+             * methods.
+             */
+            var nativeCreate = getNative(Object, 'create');
+
+            /**
+             * Creates a `Set` cache object to optimize linear searches of large arrays.
+             * 
+             * @private
+             * @param {Array}
+             *            [values] The values to cache.
+             * @returns {null|Object} Returns the new cache object if `Set` is supported,
+             *          else `null`.
+             */
+            function createCache(values) {
+                return (nativeCreate && Set) ? new SetCache(values) : null;
+            }
+
+            module.exports = createCache;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./SetCache": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\SetCache.js",
+        "./getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCtorWrapper.js": [function(require, module, exports) {
+        var baseCreate = require('./baseCreate'),
+            isObject = require('../lang/isObject');
+
+        /**
+         * Creates a function that produces an instance of `Ctor` regardless of whether
+         * it was invoked as part of a `new` expression or by `call` or `apply`.
+         * 
+         * @private
+         * @param {Function}
+         *            Ctor The constructor to wrap.
+         * @returns {Function} Returns the new wrapped function.
+         */
+        function createCtorWrapper(Ctor) {
+            return function() {
+                // Use a `switch` statement to work with class constructors.
+                // See
+                // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+                // for more details.
+                var args = arguments;
+                switch (args.length) {
+                    case 0:
+                        return new Ctor;
+                    case 1:
+                        return new Ctor(args[0]);
+                    case 2:
+                        return new Ctor(args[0], args[1]);
+                    case 3:
+                        return new Ctor(args[0], args[1], args[2]);
+                    case 4:
+                        return new Ctor(args[0], args[1], args[2], args[3]);
+                    case 5:
+                        return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+                    case 6:
+                        return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+                    case 7:
+                        return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+                }
+                var thisBinding = baseCreate(Ctor.prototype),
+                    result = Ctor.apply(thisBinding, args);
+
+                // Mimic the constructor's `return` behavior.
+                // See https://es5.github.io/#x13.2.2 for more details.
+                return isObject(result) ? result : thisBinding;
+            };
+        }
+
+        module.exports = createCtorWrapper;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "./baseCreate": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCreate.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createFind.js": [function(require, module, exports) {
+        var baseCallback = require('./baseCallback'),
+            baseFind = require('./baseFind'),
+            baseFindIndex = require('./baseFindIndex'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Creates a `_.find` or `_.findLast` function.
+         * 
+         * @private
+         * @param {Function}
+         *            eachFunc The function to iterate over a collection.
+         * @param {boolean}
+         *            [fromRight] Specify iterating from right to left.
+         * @returns {Function} Returns the new find function.
+         */
+        function createFind(eachFunc, fromRight) {
+            return function(collection, predicate, thisArg) {
+                predicate = baseCallback(predicate, thisArg, 3);
+                if (isArray(collection)) {
+                    var index = baseFindIndex(collection, predicate, fromRight);
+                    return index > -1 ? collection[index] : undefined;
+                }
+                return baseFind(collection, predicate, eachFunc);
+            };
+        }
+
+        module.exports = createFind;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "./baseFind": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFind.js",
+        "./baseFindIndex": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFindIndex.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createForEach.js": [function(require, module, exports) {
+        var bindCallback = require('./bindCallback'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Creates a function for `_.forEach` or `_.forEachRight`.
+         * 
+         * @private
+         * @param {Function}
+         *            arrayFunc The function to iterate over an array.
+         * @param {Function}
+         *            eachFunc The function to iterate over a collection.
+         * @returns {Function} Returns the new each function.
+         */
+        function createForEach(arrayFunc, eachFunc) {
+            return function(collection, iteratee, thisArg) {
+                return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) ? arrayFunc(collection, iteratee) : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
+            };
+        }
+
+        module.exports = createForEach;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./bindCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createHybridWrapper.js": [function(require, module, exports) {
+        (function(global) {
+            var arrayCopy = require('./arrayCopy'),
+                composeArgs = require('./composeArgs'),
+                composeArgsRight = require('./composeArgsRight'),
+                createCtorWrapper = require('./createCtorWrapper'),
+                isLaziable = require('./isLaziable'),
+                reorder = require('./reorder'),
+                replaceHolders = require('./replaceHolders'),
+                setData = require('./setData');
+
+            /** Used to compose bitmasks for wrapper metadata. */
+            var BIND_FLAG = 1,
+                BIND_KEY_FLAG = 2,
+                CURRY_BOUND_FLAG = 4,
+                CURRY_FLAG = 8,
+                CURRY_RIGHT_FLAG = 16,
+                PARTIAL_FLAG = 32,
+                PARTIAL_RIGHT_FLAG = 64,
+                ARY_FLAG = 128;
+
+            /*
+             * Native method references for those with the same name as other `lodash`
+             * methods.
+             */
+            var nativeMax = Math.max;
+
+            /**
+             * Creates a function that wraps `func` and invokes it with optional `this`
+             * binding of, partial application, and currying.
+             * 
+             * @private
+             * @param {Function|string}
+             *            func The function or method name to reference.
+             * @param {number}
+             *            bitmask The bitmask of flags. See `createWrapper` for more
+             *            details.
+             * @param {*}
+             *            [thisArg] The `this` binding of `func`.
+             * @param {Array}
+             *            [partials] The arguments to prepend to those provided to the new
+             *            function.
+             * @param {Array}
+             *            [holders] The `partials` placeholder indexes.
+             * @param {Array}
+             *            [partialsRight] The arguments to append to those provided to the
+             *            new function.
+             * @param {Array}
+             *            [holdersRight] The `partialsRight` placeholder indexes.
+             * @param {Array}
+             *            [argPos] The argument positions of the new function.
+             * @param {number}
+             *            [ary] The arity cap of `func`.
+             * @param {number}
+             *            [arity] The arity of `func`.
+             * @returns {Function} Returns the new wrapped function.
+             */
+            function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+                var isAry = bitmask & ARY_FLAG,
+                    isBind = bitmask & BIND_FLAG,
+                    isBindKey = bitmask & BIND_KEY_FLAG,
+                    isCurry = bitmask & CURRY_FLAG,
+                    isCurryBound = bitmask & CURRY_BOUND_FLAG,
+                    isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+                    Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+                function wrapper() {
+                    // Avoid `arguments` object use disqualifying optimizations by
+                    // converting it to an array before providing it to other functions.
+                    var length = arguments.length,
+                        index = length,
+                        args = Array(length);
+
+                    while (index--) {
+                        args[index] = arguments[index];
+                    }
+                    if (partials) {
+                        args = composeArgs(args, partials, holders);
+                    }
+                    if (partialsRight) {
+                        args = composeArgsRight(args, partialsRight, holdersRight);
+                    }
+                    if (isCurry || isCurryRight) {
+                        var placeholder = wrapper.placeholder,
+                            argsHolders = replaceHolders(args, placeholder);
+
+                        length -= argsHolders.length;
+                        if (length < arity) {
+                            var newArgPos = argPos ? arrayCopy(argPos) : undefined,
+                                newArity = nativeMax(arity - length, 0),
+                                newsHolders = isCurry ? argsHolders : undefined,
+                                newHoldersRight = isCurry ? undefined : argsHolders,
+                                newPartials = isCurry ? args : undefined,
+                                newPartialsRight = isCurry ? undefined : args;
+
+                            bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+                            bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+                            if (!isCurryBound) {
+                                bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+                            }
+                            var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
+                                result = createHybridWrapper.apply(undefined, newData);
+
+                            if (isLaziable(func)) {
+                                setData(result, newData);
+                            }
+                            result.placeholder = placeholder;
+                            return result;
+                        }
+                    }
+                    var thisBinding = isBind ? thisArg : this,
+                        fn = isBindKey ? thisBinding[func] : func;
+
+                    if (argPos) {
+                        args = reorder(args, argPos);
+                    }
+                    if (isAry && ary < args.length) {
+                        args.length = ary;
+                    }
+                    if (this && this !== global && this instanceof wrapper) {
+                        fn = Ctor || createCtorWrapper(func);
+                    }
+                    return fn.apply(thisBinding, args);
+                }
+                return wrapper;
+            }
+
+            module.exports = createHybridWrapper;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./arrayCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js",
+        "./composeArgs": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgs.js",
+        "./composeArgsRight": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgsRight.js",
+        "./createCtorWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCtorWrapper.js",
+        "./isLaziable": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLaziable.js",
+        "./reorder": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\reorder.js",
+        "./replaceHolders": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\replaceHolders.js",
+        "./setData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\setData.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createPartialWrapper.js": [function(require, module, exports) {
+        (function(global) {
+            var createCtorWrapper = require('./createCtorWrapper');
+
+            /** Used to compose bitmasks for wrapper metadata. */
+            var BIND_FLAG = 1;
+
+            /**
+             * Creates a function that wraps `func` and invokes it with the optional `this`
+             * binding of `thisArg` and the `partials` prepended to those provided to the
+             * wrapper.
+             * 
+             * @private
+             * @param {Function}
+             *            func The function to partially apply arguments to.
+             * @param {number}
+             *            bitmask The bitmask of flags. See `createWrapper` for more
+             *            details.
+             * @param {*}
+             *            thisArg The `this` binding of `func`.
+             * @param {Array}
+             *            partials The arguments to prepend to those provided to the new
+             *            function.
+             * @returns {Function} Returns the new bound function.
+             */
+            function createPartialWrapper(func, bitmask, thisArg, partials) {
+                var isBind = bitmask & BIND_FLAG,
+                    Ctor = createCtorWrapper(func);
+
+                function wrapper() {
+                    // Avoid `arguments` object use disqualifying optimizations by
+                    // converting it to an array before providing it `func`.
+                    var argsIndex = -1,
+                        argsLength = arguments.length,
+                        leftIndex = -1,
+                        leftLength = partials.length,
+                        args = Array(leftLength + argsLength);
+
+                    while (++leftIndex < leftLength) {
+                        args[leftIndex] = partials[leftIndex];
+                    }
+                    while (argsLength--) {
+                        args[leftIndex++] = arguments[++argsIndex];
+                    }
+                    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+                    return fn.apply(isBind ? thisArg : this, args);
+                }
+                return wrapper;
+            }
+
+            module.exports = createPartialWrapper;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./createCtorWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createCtorWrapper.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createReduce.js": [function(require, module, exports) {
+        var baseCallback = require('./baseCallback'),
+            baseReduce = require('./baseReduce'),
+            isArray = require('../lang/isArray');
+
+        /**
+         * Creates a function for `_.reduce` or `_.reduceRight`.
+         * 
+         * @private
+         * @param {Function}
+         *            arrayFunc The function to iterate over an array.
+         * @param {Function}
+         *            eachFunc The function to iterate over a collection.
+         * @returns {Function} Returns the new each function.
+         */
+        function createReduce(arrayFunc, eachFunc) {
+            return function(collection, iteratee, accumulator, thisArg) {
+                var initFromArray = arguments.length < 3;
+                return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) ? arrayFunc(collection, iteratee, accumulator, initFromArray) : baseReduce(collection, baseCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc);
+            };
+        }
+
+        module.exports = createReduce;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./baseCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCallback.js",
+        "./baseReduce": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseReduce.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createWrapper.js": [function(require, module, exports) {
+        var baseSetData = require('./baseSetData'),
+            createBindWrapper = require('./createBindWrapper'),
+            createHybridWrapper = require('./createHybridWrapper'),
+            createPartialWrapper = require('./createPartialWrapper'),
+            getData = require('./getData'),
+            mergeData = require('./mergeData'),
+            setData = require('./setData');
+
+        /** Used to compose bitmasks for wrapper metadata. */
+        var BIND_FLAG = 1,
+            BIND_KEY_FLAG = 2,
+            PARTIAL_FLAG = 32,
+            PARTIAL_RIGHT_FLAG = 64;
+
+        /** Used as the `TypeError` message for "Functions" methods. */
+        var FUNC_ERROR_TEXT = 'Expected a function';
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMax = Math.max;
+
+        /**
+         * Creates a function that either curries or invokes `func` with optional `this`
+         * binding and partially applied arguments.
+         * 
+         * @private
+         * @param {Function|string}
+         *            func The function or method name to reference.
+         * @param {number}
+         *            bitmask The bitmask of flags. The bitmask may be composed of the
+         *            following flags: 1 - `_.bind` 2 - `_.bindKey` 4 - `_.curry` or
+         *            `_.curryRight` of a bound function 8 - `_.curry` 16 -
+         *            `_.curryRight` 32 - `_.partial` 64 - `_.partialRight` 128 -
+         *            `_.rearg` 256 - `_.ary`
+         * @param {*}
+         *            [thisArg] The `this` binding of `func`.
+         * @param {Array}
+         *            [partials] The arguments to be partially applied.
+         * @param {Array}
+         *            [holders] The `partials` placeholder indexes.
+         * @param {Array}
+         *            [argPos] The argument positions of the new function.
+         * @param {number}
+         *            [ary] The arity cap of `func`.
+         * @param {number}
+         *            [arity] The arity of `func`.
+         * @returns {Function} Returns the new wrapped function.
+         */
+        function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+            var isBindKey = bitmask & BIND_KEY_FLAG;
+            if (!isBindKey && typeof func != 'function') {
+                throw new TypeError(FUNC_ERROR_TEXT);
+            }
+            var length = partials ? partials.length : 0;
+            if (!length) {
+                bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
+                partials = holders = undefined;
+            }
+            length -= (holders ? holders.length : 0);
+            if (bitmask & PARTIAL_RIGHT_FLAG) {
+                var partialsRight = partials,
+                    holdersRight = holders;
+
+                partials = holders = undefined;
+            }
+            var data = isBindKey ? undefined : getData(func),
+                newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
+
+            if (data) {
+                mergeData(newData, data);
+                bitmask = newData[1];
+                arity = newData[9];
+            }
+            newData[9] = arity == null ? (isBindKey ? 0 : func.length) : (nativeMax(arity - length, 0) || 0);
+
+            if (bitmask == BIND_FLAG) {
+                var result = createBindWrapper(newData[0], newData[2]);
+            } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
+                result = createPartialWrapper.apply(undefined, newData);
+            } else {
+                result = createHybridWrapper.apply(undefined, newData);
+            }
+            var setter = data ? baseSetData : setData;
+            return setter(result, newData);
+        }
+
+        module.exports = createWrapper;
+
+    }, {
+        "./baseSetData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSetData.js",
+        "./createBindWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createBindWrapper.js",
+        "./createHybridWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createHybridWrapper.js",
+        "./createPartialWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createPartialWrapper.js",
+        "./getData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getData.js",
+        "./mergeData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\mergeData.js",
+        "./setData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\setData.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalArrays.js": [function(require, module, exports) {
+        var arraySome = require('./arraySome');
+
+        /**
+         * A specialized version of `baseIsEqualDeep` for arrays with support for
+         * partial deep comparisons.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to compare.
+         * @param {Array}
+         *            other The other array to compare.
+         * @param {Function}
+         *            equalFunc The function to determine equivalents of values.
+         * @param {Function}
+         *            [customizer] The function to customize comparing arrays.
+         * @param {boolean}
+         *            [isLoose] Specify performing partial comparisons.
+         * @param {Array}
+         *            [stackA] Tracks traversed `value` objects.
+         * @param {Array}
+         *            [stackB] Tracks traversed `other` objects.
+         * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+         */
+        function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+            var index = -1,
+                arrLength = array.length,
+                othLength = other.length;
+
+            if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+                return false;
+            }
+            // Ignore non-index properties.
+            while (++index < arrLength) {
+                var arrValue = array[index],
+                    othValue = other[index],
+                    result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+
+                if (result !== undefined) {
+                    if (result) {
+                        continue;
+                    }
+                    return false;
+                }
+                // Recursively compare arrays (susceptible to call stack limits).
+                if (isLoose) {
+                    if (!arraySome(other, function(othValue) {
+                            return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+                        })) {
+                        return false;
+                    }
+                } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        module.exports = equalArrays;
+
+    }, {
+        "./arraySome": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arraySome.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalByTag.js": [function(require, module, exports) {
+        /** `Object#toString` result references. */
+        var boolTag = '[object Boolean]',
+            dateTag = '[object Date]',
+            errorTag = '[object Error]',
+            numberTag = '[object Number]',
+            regexpTag = '[object RegExp]',
+            stringTag = '[object String]';
+
+        /**
+         * A specialized version of `baseIsEqualDeep` for comparing objects of the same
+         * `toStringTag`.
+         * 
+         * **Note:** This function only supports comparing values with tags of
+         * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to compare.
+         * @param {Object}
+         *            other The other object to compare.
+         * @param {string}
+         *            tag The `toStringTag` of the objects to compare.
+         * @returns {boolean} Returns `true` if the objects are equivalent, else
+         *          `false`.
+         */
+        function equalByTag(object, other, tag) {
+            switch (tag) {
+                case boolTag:
+                case dateTag:
+                    // Coerce dates and booleans to numbers, dates to milliseconds and
+                    // booleans
+                    // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
+                    return +object == +other;
+
+                case errorTag:
+                    return object.name == other.name && object.message == other.message;
+
+                case numberTag:
+                    // Treat `NaN` vs. `NaN` as equal.
+                    return (object != +object) ? other != +other : object == +other;
+
+                case regexpTag:
+                case stringTag:
+                    // Coerce regexes to strings and treat strings primitives and string
+                    // objects as equal. See https://es5.github.io/#x15.10.6.4 for more
+                    // details.
+                    return object == (other + '');
+            }
+            return false;
+        }
+
+        module.exports = equalByTag;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\equalObjects.js": [function(require, module, exports) {
+        var keys = require('../object/keys');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * A specialized version of `baseIsEqualDeep` for objects with support for
+         * partial deep comparisons.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to compare.
+         * @param {Object}
+         *            other The other object to compare.
+         * @param {Function}
+         *            equalFunc The function to determine equivalents of values.
+         * @param {Function}
+         *            [customizer] The function to customize comparing values.
+         * @param {boolean}
+         *            [isLoose] Specify performing partial comparisons.
+         * @param {Array}
+         *            [stackA] Tracks traversed `value` objects.
+         * @param {Array}
+         *            [stackB] Tracks traversed `other` objects.
+         * @returns {boolean} Returns `true` if the objects are equivalent, else
+         *          `false`.
+         */
+        function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+            var objProps = keys(object),
+                objLength = objProps.length,
+                othProps = keys(other),
+                othLength = othProps.length;
+
+            if (objLength != othLength && !isLoose) {
+                return false;
+            }
+            var index = objLength;
+            while (index--) {
+                var key = objProps[index];
+                if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+                    return false;
+                }
+            }
+            var skipCtor = isLoose;
+            while (++index < objLength) {
+                key = objProps[index];
+                var objValue = object[key],
+                    othValue = other[key],
+                    result = customizer ? customizer(isLoose ? othValue : objValue, isLoose ? objValue : othValue, key) : undefined;
+
+                // Recursively compare objects (susceptible to call stack limits).
+                if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
+                    return false;
+                }
+                skipCtor || (skipCtor = key == 'constructor');
+            }
+            if (!skipCtor) {
+                var objCtor = object.constructor,
+                    othCtor = other.constructor;
+
+                // Non `Object` object instances with different constructors are not equal.
+                if (objCtor != othCtor &&
+                    ('constructor' in object && 'constructor' in other) &&
+                    !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+                        typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        module.exports = equalObjects;
+
+    }, {
+        "../object/keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getData.js": [function(require, module, exports) {
+        var metaMap = require('./metaMap'),
+            noop = require('../utility/noop');
+
+        /**
+         * Gets metadata for `func`.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to query.
+         * @returns {*} Returns the metadata for `func`.
+         */
+        var getData = !metaMap ? noop : function(func) {
+            return metaMap.get(func);
+        };
+
+        module.exports = getData;
+
+    }, {
+        "../utility/noop": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\noop.js",
+        "./metaMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\metaMap.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getFuncName.js": [function(require, module, exports) {
+        var realNames = require('./realNames');
+
+        /**
+         * Gets the name of `func`.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to query.
+         * @returns {string} Returns the function name.
+         */
+        function getFuncName(func) {
+            var result = (func.name + ''),
+                array = realNames[result],
+                length = array ? array.length : 0;
+
+            while (length--) {
+                var data = array[length],
+                    otherFunc = data.func;
+                if (otherFunc == null || otherFunc == func) {
+                    return data.name;
+                }
+            }
+            return result;
+        }
+
+        module.exports = getFuncName;
+
+    }, {
+        "./realNames": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\realNames.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getLength.js": [function(require, module, exports) {
+        var baseProperty = require('./baseProperty');
+
+        /**
+         * Gets the "length" property value of `object`.
+         * 
+         * **Note:** This function is used to avoid a [JIT
+         * bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects Safari on
+         * at least iOS 8.1-8.3 ARM64.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @returns {*} Returns the "length" value.
+         */
+        var getLength = baseProperty('length');
+
+        module.exports = getLength;
+
+    }, {
+        "./baseProperty": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseProperty.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getMatchData.js": [function(require, module, exports) {
+        var isStrictComparable = require('./isStrictComparable'),
+            pairs = require('../object/pairs');
+
+        /**
+         * Gets the propery names, values, and compare flags of `object`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the match data of `object`.
+         */
+        function getMatchData(object) {
+            var result = pairs(object),
+                length = result.length;
+
+            while (length--) {
+                result[length][2] = isStrictComparable(result[length][1]);
+            }
+            return result;
+        }
+
+        module.exports = getMatchData;
+
+    }, {
+        "../object/pairs": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pairs.js",
+        "./isStrictComparable": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isStrictComparable.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js": [function(require, module, exports) {
+        var isNative = require('../lang/isNative');
+
+        /**
+         * Gets the native function at `key` of `object`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @param {string}
+         *            key The key of the method to get.
+         * @returns {*} Returns the function if it's native, else `undefined`.
+         */
+        function getNative(object, key) {
+            var value = object == null ? undefined : object[key];
+            return isNative(value) ? value : undefined;
+        }
+
+        module.exports = getNative;
+
+    }, {
+        "../lang/isNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNative.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\indexOfNaN.js": [function(require, module, exports) {
+        /**
+         * Gets the index at which the first occurrence of `NaN` is found in `array`.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to search.
+         * @param {number}
+         *            fromIndex The index to search from.
+         * @param {boolean}
+         *            [fromRight] Specify iterating from right to left.
+         * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+         */
+        function indexOfNaN(array, fromIndex, fromRight) {
+            var length = array.length,
+                index = fromIndex + (fromRight ? 0 : -1);
+
+            while ((fromRight ? index-- : ++index < length)) {
+                var other = array[index];
+                if (other !== other) {
+                    return index;
+                }
+            }
+            return -1;
+        }
+
+        module.exports = indexOfNaN;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js": [function(require, module, exports) {
+        var getLength = require('./getLength'),
+            isLength = require('./isLength');
+
+        /**
+         * Checks if `value` is array-like.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+         */
+        function isArrayLike(value) {
+            return value != null && isLength(getLength(value));
+        }
+
+        module.exports = isArrayLike;
+
+    }, {
+        "./getLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getLength.js",
+        "./isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIndex.js": [function(require, module, exports) {
+        /** Used to detect unsigned integer values. */
+        var reIsUint = /^\d+$/;
+
+        /**
+         * Used as the [maximum
+         * length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+         * of an array-like value.
+         */
+        var MAX_SAFE_INTEGER = 9007199254740991;
+
+        /**
+         * Checks if `value` is a valid array-like index.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @param {number}
+         *            [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+         * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+         */
+        function isIndex(value, length) {
+            value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+            length = length == null ? MAX_SAFE_INTEGER : length;
+            return value > -1 && value % 1 == 0 && value < length;
+        }
+
+        module.exports = isIndex;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIterateeCall.js": [function(require, module, exports) {
+        var isArrayLike = require('./isArrayLike'),
+            isIndex = require('./isIndex'),
+            isObject = require('../lang/isObject');
+
+        /**
+         * Checks if the provided arguments are from an iteratee call.
+         * 
+         * @private
+         * @param {*}
+         *            value The potential iteratee value argument.
+         * @param {*}
+         *            index The potential iteratee index or key argument.
+         * @param {*}
+         *            object The potential iteratee object argument.
+         * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
+         *          else `false`.
+         */
+        function isIterateeCall(value, index, object) {
+            if (!isObject(object)) {
+                return false;
+            }
+            var type = typeof index;
+            if (type == 'number' ? (isArrayLike(object) && isIndex(index, object.length)) : (type == 'string' && index in object)) {
+                var other = object[index];
+                return value === value ? (value === other) : (other !== other);
+            }
+            return false;
+        }
+
+        module.exports = isIterateeCall;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js",
+        "./isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js",
+        "./isIndex": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIndex.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isKey.js": [function(require, module, exports) {
+        var isArray = require('../lang/isArray'),
+            toObject = require('./toObject');
+
+        /** Used to match property names within property paths. */
+        var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+            reIsPlainProp = /^\w*$/;
+
+        /**
+         * Checks if `value` is a property name and not a property path.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @param {Object}
+         *            [object] The object to query keys on.
+         * @returns {boolean} Returns `true` if `value` is a property name, else
+         *          `false`.
+         */
+        function isKey(value, object) {
+            var type = typeof value;
+            if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+                return true;
+            }
+            if (isArray(value)) {
+                return false;
+            }
+            var result = !reIsDeepProp.test(value);
+            return result || (object != null && value in toObject(object));
+        }
+
+        module.exports = isKey;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLaziable.js": [function(require, module, exports) {
+        var LazyWrapper = require('./LazyWrapper'),
+            getData = require('./getData'),
+            getFuncName = require('./getFuncName'),
+            lodash = require('../chain/lodash');
+
+        /**
+         * Checks if `func` has a lazy counterpart.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to check.
+         * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else
+         *          `false`.
+         */
+        function isLaziable(func) {
+            var funcName = getFuncName(func),
+                other = lodash[funcName];
+
+            if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+                return false;
+            }
+            if (func === other) {
+                return true;
+            }
+            var data = getData(other);
+            return !!data && func === data[0];
+        }
+
+        module.exports = isLaziable;
+
+    }, {
+        "../chain/lodash": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\chain\\lodash.js",
+        "./LazyWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LazyWrapper.js",
+        "./getData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getData.js",
+        "./getFuncName": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getFuncName.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js": [function(require, module, exports) {
+        /**
+         * Used as the [maximum
+         * length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+         * of an array-like value.
+         */
+        var MAX_SAFE_INTEGER = 9007199254740991;
+
+        /**
+         * Checks if `value` is a valid array-like length.
+         * 
+         * **Note:** This function is based on
+         * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+         */
+        function isLength(value) {
+            return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+        }
+
+        module.exports = isLength;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js": [function(require, module, exports) {
+        /**
+         * Checks if `value` is object-like.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+         */
+        function isObjectLike(value) {
+            return !!value && typeof value == 'object';
+        }
+
+        module.exports = isObjectLike;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isStrictComparable.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject');
+
+        /**
+         * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` if suitable for strict equality
+         *          comparisons, else `false`.
+         */
+        function isStrictComparable(value) {
+            return value === value && !isObject(value);
+        }
+
+        module.exports = isStrictComparable;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\mergeData.js": [function(require, module, exports) {
+        var arrayCopy = require('./arrayCopy'),
+            composeArgs = require('./composeArgs'),
+            composeArgsRight = require('./composeArgsRight'),
+            replaceHolders = require('./replaceHolders');
+
+        /** Used to compose bitmasks for wrapper metadata. */
+        var BIND_FLAG = 1,
+            CURRY_BOUND_FLAG = 4,
+            CURRY_FLAG = 8,
+            ARY_FLAG = 128,
+            REARG_FLAG = 256;
+
+        /** Used as the internal argument placeholder. */
+        var PLACEHOLDER = '__lodash_placeholder__';
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMin = Math.min;
+
+        /**
+         * Merges the function metadata of `source` into `data`.
+         * 
+         * Merging metadata reduces the number of wrappers required to invoke a
+         * function. This is possible because methods like `_.bind`, `_.curry`, and
+         * `_.partial` may be applied regardless of execution order. Methods like
+         * `_.ary` and `_.rearg` augment function arguments, making the order in which
+         * they are executed important, preventing the merging of metadata. However, we
+         * make an exception for a safe common case where curried functions have `_.ary`
+         * and or `_.rearg` applied.
+         * 
+         * @private
+         * @param {Array}
+         *            data The destination metadata.
+         * @param {Array}
+         *            source The source metadata.
+         * @returns {Array} Returns `data`.
+         */
+        function mergeData(data, source) {
+            var bitmask = data[1],
+                srcBitmask = source[1],
+                newBitmask = bitmask | srcBitmask,
+                isCommon = newBitmask < ARY_FLAG;
+
+            var isCombo =
+                (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
+                (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
+                (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+
+            // Exit early if metadata can't be merged.
+            if (!(isCommon || isCombo)) {
+                return data;
+            }
+            // Use source `thisArg` if available.
+            if (srcBitmask & BIND_FLAG) {
+                data[2] = source[2];
+                // Set when currying a bound function.
+                newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
+            }
+            // Compose partial arguments.
+            var value = source[3];
+            if (value) {
+                var partials = data[3];
+                data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
+                data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+            }
+            // Compose partial right arguments.
+            value = source[5];
+            if (value) {
+                partials = data[5];
+                data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
+                data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+            }
+            // Use source `argPos` if available.
+            value = source[7];
+            if (value) {
+                data[7] = arrayCopy(value);
+            }
+            // Use source `ary` if it's smaller.
+            if (srcBitmask & ARY_FLAG) {
+                data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+            }
+            // Use source `arity` if one is not provided.
+            if (data[9] == null) {
+                data[9] = source[9];
+            }
+            // Use source `func` and merge bitmasks.
+            data[0] = source[0];
+            data[1] = newBitmask;
+
+            return data;
+        }
+
+        module.exports = mergeData;
+
+    }, {
+        "./arrayCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js",
+        "./composeArgs": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgs.js",
+        "./composeArgsRight": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\composeArgsRight.js",
+        "./replaceHolders": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\replaceHolders.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\metaMap.js": [function(require, module, exports) {
+        (function(global) {
+            var getNative = require('./getNative');
+
+            /** Native method references. */
+            var WeakMap = getNative(global, 'WeakMap');
+
+            /** Used to store function metadata. */
+            var metaMap = WeakMap && new WeakMap;
+
+            module.exports = metaMap;
+
+        }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+    }, {
+        "./getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByArray.js": [function(require, module, exports) {
+        var toObject = require('./toObject');
+
+        /**
+         * A specialized version of `_.pick` which picks `object` properties specified
+         * by `props`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The source object.
+         * @param {string[]}
+         *            props The property names to pick.
+         * @returns {Object} Returns the new object.
+         */
+        function pickByArray(object, props) {
+            object = toObject(object);
+
+            var index = -1,
+                length = props.length,
+                result = {};
+
+            while (++index < length) {
+                var key = props[index];
+                if (key in object) {
+                    result[key] = object[key];
+                }
+            }
+            return result;
+        }
+
+        module.exports = pickByArray;
+
+    }, {
+        "./toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByCallback.js": [function(require, module, exports) {
+        var baseForIn = require('./baseForIn');
+
+        /**
+         * A specialized version of `_.pick` which picks `object` properties `predicate`
+         * returns truthy for.
+         * 
+         * @private
+         * @param {Object}
+         *            object The source object.
+         * @param {Function}
+         *            predicate The function invoked per iteration.
+         * @returns {Object} Returns the new object.
+         */
+        function pickByCallback(object, predicate) {
+            var result = {};
+            baseForIn(object, function(value, key, object) {
+                if (predicate(value, key, object)) {
+                    result[key] = value;
+                }
+            });
+            return result;
+        }
+
+        module.exports = pickByCallback;
+
+    }, {
+        "./baseForIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseForIn.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\realNames.js": [function(require, module, exports) {
+        /** Used to lookup unminified function names. */
+        var realNames = {};
+
+        module.exports = realNames;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\reorder.js": [function(require, module, exports) {
+        var arrayCopy = require('./arrayCopy'),
+            isIndex = require('./isIndex');
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeMin = Math.min;
+
+        /**
+         * Reorder `array` according to the specified indexes where the element at the
+         * first index is assigned as the first element, the element at the second index
+         * is assigned as the second element, and so on.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to reorder.
+         * @param {Array}
+         *            indexes The arranged array indexes.
+         * @returns {Array} Returns `array`.
+         */
+        function reorder(array, indexes) {
+            var arrLength = array.length,
+                length = nativeMin(indexes.length, arrLength),
+                oldArray = arrayCopy(array);
+
+            while (length--) {
+                var index = indexes[length];
+                array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+            }
+            return array;
+        }
+
+        module.exports = reorder;
+
+    }, {
+        "./arrayCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js",
+        "./isIndex": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIndex.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\replaceHolders.js": [function(require, module, exports) {
+        /** Used as the internal argument placeholder. */
+        var PLACEHOLDER = '__lodash_placeholder__';
+
+        /**
+         * Replaces all `placeholder` elements in `array` with an internal placeholder
+         * and returns an array of their indexes.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to modify.
+         * @param {*}
+         *            placeholder The placeholder to replace.
+         * @returns {Array} Returns the new array of placeholder indexes.
+         */
+        function replaceHolders(array, placeholder) {
+            var index = -1,
+                length = array.length,
+                resIndex = -1,
+                result = [];
+
+            while (++index < length) {
+                if (array[index] === placeholder) {
+                    array[index] = PLACEHOLDER;
+                    result[++resIndex] = index;
+                }
+            }
+            return result;
+        }
+
+        module.exports = replaceHolders;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\setData.js": [function(require, module, exports) {
+        var baseSetData = require('./baseSetData'),
+            now = require('../date/now');
+
+        /** Used to detect when a function becomes hot. */
+        var HOT_COUNT = 150,
+            HOT_SPAN = 16;
+
+        /**
+         * Sets metadata for `func`.
+         * 
+         * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+         * period of time, it will trip its breaker and transition to an identity
+         * function to avoid garbage collection pauses in V8. See [V8 issue
+         * 2070](https://code.google.com/p/v8/issues/detail?id=2070) for more details.
+         * 
+         * @private
+         * @param {Function}
+         *            func The function to associate metadata with.
+         * @param {*}
+         *            data The metadata.
+         * @returns {Function} Returns `func`.
+         */
+        var setData = (function() {
+            var count = 0,
+                lastCalled = 0;
+
+            return function(key, value) {
+                var stamp = now(),
+                    remaining = HOT_SPAN - (stamp - lastCalled);
+
+                lastCalled = stamp;
+                if (remaining > 0) {
+                    if (++count >= HOT_COUNT) {
+                        return key;
+                    }
+                } else {
+                    count = 0;
+                }
+                return baseSetData(key, value);
+            };
+        }());
+
+        module.exports = setData;
+
+    }, {
+        "../date/now": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\date\\now.js",
+        "./baseSetData": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseSetData.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\shimKeys.js": [function(require, module, exports) {
+        var isArguments = require('../lang/isArguments'),
+            isArray = require('../lang/isArray'),
+            isIndex = require('./isIndex'),
+            isLength = require('./isLength'),
+            keysIn = require('../object/keysIn');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * A fallback implementation of `Object.keys` which creates an array of the own
+         * enumerable property names of `object`.
+         * 
+         * @private
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the array of property names.
+         */
+        function shimKeys(object) {
+            var props = keysIn(object),
+                propsLength = props.length,
+                length = propsLength && object.length;
+
+            var allowIndexes = !!length && isLength(length) &&
+                (isArray(object) || isArguments(object));
+
+            var index = -1,
+                result = [];
+
+            while (++index < propsLength) {
+                var key = props[index];
+                if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+                    result.push(key);
+                }
+            }
+            return result;
+        }
+
+        module.exports = shimKeys;
+
+    }, {
+        "../lang/isArguments": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../object/keysIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keysIn.js",
+        "./isIndex": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIndex.js",
+        "./isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\sortedUniq.js": [function(require, module, exports) {
+        /**
+         * An implementation of `_.uniq` optimized for sorted arrays without support for
+         * callback shorthands and `this` binding.
+         * 
+         * @private
+         * @param {Array}
+         *            array The array to inspect.
+         * @param {Function}
+         *            [iteratee] The function invoked per iteration.
+         * @returns {Array} Returns the new duplicate free array.
+         */
+        function sortedUniq(array, iteratee) {
+            var seen,
+                index = -1,
+                length = array.length,
+                resIndex = -1,
+                result = [];
+
+            while (++index < length) {
+                var value = array[index],
+                    computed = iteratee ? iteratee(value, index, array) : value;
+
+                if (!index || seen !== computed) {
+                    seen = computed;
+                    result[++resIndex] = value;
+                }
+            }
+            return result;
+        }
+
+        module.exports = sortedUniq;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js": [function(require, module, exports) {
+        var isObject = require('../lang/isObject');
+
+        /**
+         * Converts `value` to an object if it's not one.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to process.
+         * @returns {Object} Returns the object.
+         */
+        function toObject(value) {
+            return isObject(value) ? value : Object(value);
+        }
+
+        module.exports = toObject;
+
+    }, {
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toPath.js": [function(require, module, exports) {
+        var baseToString = require('./baseToString'),
+            isArray = require('../lang/isArray');
+
+        /** Used to match property names within property paths. */
+        var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+
+        /** Used to match backslashes in property paths. */
+        var reEscapeChar = /\\(\\)?/g;
+
+        /**
+         * Converts `value` to property path array if it's not one.
+         * 
+         * @private
+         * @param {*}
+         *            value The value to process.
+         * @returns {Array} Returns the property path array.
+         */
+        function toPath(value) {
+            if (isArray(value)) {
+                return value;
+            }
+            var result = [];
+            baseToString(value).replace(rePropName, function(match, number, quote, string) {
+                result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+            });
+            return result;
+        }
+
+        module.exports = toPath;
+
+    }, {
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "./baseToString": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseToString.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\wrapperClone.js": [function(require, module, exports) {
+        var LazyWrapper = require('./LazyWrapper'),
+            LodashWrapper = require('./LodashWrapper'),
+            arrayCopy = require('./arrayCopy');
+
+        /**
+         * Creates a clone of `wrapper`.
+         * 
+         * @private
+         * @param {Object}
+         *            wrapper The wrapper to clone.
+         * @returns {Object} Returns the cloned wrapper.
+         */
+        function wrapperClone(wrapper) {
+            return wrapper instanceof LazyWrapper ? wrapper.clone() : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+        }
+
+        module.exports = wrapperClone;
+
+    }, {
+        "./LazyWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LazyWrapper.js",
+        "./LodashWrapper": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\LodashWrapper.js",
+        "./arrayCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayCopy.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js": [function(require, module, exports) {
+        var isArrayLike = require('../internal/isArrayLike'),
+            isObjectLike = require('../internal/isObjectLike');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /** Native method references. */
+        var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+        /**
+         * Checks if `value` is classified as an `arguments` object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isArguments(function() { return arguments; }()); // => true
+         * 
+         * _.isArguments([1, 2, 3]); // => false
+         */
+        function isArguments(value) {
+            return isObjectLike(value) && isArrayLike(value) &&
+                hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
+        }
+
+        module.exports = isArguments;
+
+    }, {
+        "../internal/isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js",
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js": [function(require, module, exports) {
+        var getNative = require('../internal/getNative'),
+            isLength = require('../internal/isLength'),
+            isObjectLike = require('../internal/isObjectLike');
+
+        /** `Object#toString` result references. */
+        var arrayTag = '[object Array]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeIsArray = getNative(Array, 'isArray');
+
+        /**
+         * Checks if `value` is classified as an `Array` object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isArray([1, 2, 3]); // => true
+         * 
+         * _.isArray(function() { return arguments; }()); // => false
+         */
+        var isArray = nativeIsArray || function(value) {
+            return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+        };
+
+        module.exports = isArray;
+
+    }, {
+        "../internal/getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js",
+        "../internal/isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js": [function(require, module, exports) {
+        var isObject = require('./isObject');
+
+        /** `Object#toString` result references. */
+        var funcTag = '[object Function]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * Checks if `value` is classified as a `Function` object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isFunction(_); // => true
+         * 
+         * _.isFunction(/abc/); // => false
+         */
+        function isFunction(value) {
+            // The use of `Object#toString` avoids issues with the `typeof` operator
+            // in older versions of Chrome and Safari which return 'function' for
+            // regexes
+            // and Safari 8 which returns 'object' for typed array constructors.
+            return isObject(value) && objToString.call(value) == funcTag;
+        }
+
+        module.exports = isFunction;
+
+    }, {
+        "./isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNative.js": [function(require, module, exports) {
+        var isFunction = require('./isFunction'),
+            isObjectLike = require('../internal/isObjectLike');
+
+        /** Used to detect host constructors (Safari > 5). */
+        var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to resolve the decompiled source of functions. */
+        var fnToString = Function.prototype.toString;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /** Used to detect if a method is native. */
+        var reIsNative = RegExp('^' +
+            fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+            .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+        );
+
+        /**
+         * Checks if `value` is a native function.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is a native function, else
+         *          `false`.
+         * @example
+         * 
+         * _.isNative(Array.prototype.push); // => true
+         * 
+         * _.isNative(_); // => false
+         */
+        function isNative(value) {
+            if (value == null) {
+                return false;
+            }
+            if (isFunction(value)) {
+                return reIsNative.test(fnToString.call(value));
+            }
+            return isObjectLike(value) && reIsHostCtor.test(value);
+        }
+
+        module.exports = isNative;
+
+    }, {
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js",
+        "./isFunction": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isFunction.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isNumber.js": [function(require, module, exports) {
+        var isObjectLike = require('../internal/isObjectLike');
+
+        /** `Object#toString` result references. */
+        var numberTag = '[object Number]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * Checks if `value` is classified as a `Number` primitive or object.
+         * 
+         * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
+         * as numbers, use the `_.isFinite` method.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isNumber(8.4); // => true
+         * 
+         * _.isNumber(NaN); // => true
+         * 
+         * _.isNumber('8.4'); // => false
+         */
+        function isNumber(value) {
+            return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
+        }
+
+        module.exports = isNumber;
+
+    }, {
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js": [function(require, module, exports) {
+        /**
+         * Checks if `value` is the [language type](https://es5.github.io/#x8) of
+         * `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and
+         * `new String('')`)
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+         * @example
+         * 
+         * _.isObject({}); // => true
+         * 
+         * _.isObject([1, 2, 3]); // => true
+         * 
+         * _.isObject(1); // => false
+         */
+        function isObject(value) {
+            // Avoid a V8 JIT bug in Chrome 19-20.
+            // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+            var type = typeof value;
+            return !!value && (type == 'object' || type == 'function');
+        }
+
+        module.exports = isObject;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isPlainObject.js": [function(require, module, exports) {
+        var baseForIn = require('../internal/baseForIn'),
+            isArguments = require('./isArguments'),
+            isObjectLike = require('../internal/isObjectLike');
+
+        /** `Object#toString` result references. */
+        var objectTag = '[object Object]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * Checks if `value` is a plain object, that is, an object created by the
+         * `Object` constructor or one with a `[[Prototype]]` of `null`.
+         * 
+         * **Note:** This method assumes objects created by the `Object` constructor
+         * have no inherited enumerable properties.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+         * @example
+         * 
+         * function Foo() { this.a = 1; }
+         * 
+         * _.isPlainObject(new Foo); // => false
+         * 
+         * _.isPlainObject([1, 2, 3]); // => false
+         * 
+         * _.isPlainObject({ 'x': 0, 'y': 0 }); // => true
+         * 
+         * _.isPlainObject(Object.create(null)); // => true
+         */
+        function isPlainObject(value) {
+            var Ctor;
+
+            // Exit early for non `Object` objects.
+            if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
+                (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
+                return false;
+            }
+            // IE < 9 iterates inherited properties before own properties. If the first
+            // iterated property is an object's own property then there are no inherited
+            // enumerable properties.
+            var result;
+            // In most environments an object's own properties are iterated before
+            // its inherited properties. If the last iterated property is an object's
+            // own property then there are no inherited enumerable properties.
+            baseForIn(value, function(subValue, key) {
+                result = key;
+            });
+            return result === undefined || hasOwnProperty.call(value, result);
+        }
+
+        module.exports = isPlainObject;
+
+    }, {
+        "../internal/baseForIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseForIn.js",
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js",
+        "./isArguments": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isString.js": [function(require, module, exports) {
+        var isObjectLike = require('../internal/isObjectLike');
+
+        /** `Object#toString` result references. */
+        var stringTag = '[object String]';
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * Checks if `value` is classified as a `String` primitive or object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isString('abc'); // => true
+         * 
+         * _.isString(1); // => false
+         */
+        function isString(value) {
+            return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+        }
+
+        module.exports = isString;
+
+    }, {
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isTypedArray.js": [function(require, module, exports) {
+        var isLength = require('../internal/isLength'),
+            isObjectLike = require('../internal/isObjectLike');
+
+        /** `Object#toString` result references. */
+        var argsTag = '[object Arguments]',
+            arrayTag = '[object Array]',
+            boolTag = '[object Boolean]',
+            dateTag = '[object Date]',
+            errorTag = '[object Error]',
+            funcTag = '[object Function]',
+            mapTag = '[object Map]',
+            numberTag = '[object Number]',
+            objectTag = '[object Object]',
+            regexpTag = '[object RegExp]',
+            setTag = '[object Set]',
+            stringTag = '[object String]',
+            weakMapTag = '[object WeakMap]';
+
+        var arrayBufferTag = '[object ArrayBuffer]',
+            float32Tag = '[object Float32Array]',
+            float64Tag = '[object Float64Array]',
+            int8Tag = '[object Int8Array]',
+            int16Tag = '[object Int16Array]',
+            int32Tag = '[object Int32Array]',
+            uint8Tag = '[object Uint8Array]',
+            uint8ClampedTag = '[object Uint8ClampedArray]',
+            uint16Tag = '[object Uint16Array]',
+            uint32Tag = '[object Uint32Array]';
+
+        /** Used to identify `toStringTag` values of typed arrays. */
+        var typedArrayTags = {};
+        typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+            typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+            typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+            typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+            typedArrayTags[uint32Tag] = true;
+        typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+            typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+            typedArrayTags[dateTag] = typedArrayTags[errorTag] =
+            typedArrayTags[funcTag] = typedArrayTags[mapTag] =
+            typedArrayTags[numberTag] = typedArrayTags[objectTag] =
+            typedArrayTags[regexpTag] = typedArrayTags[setTag] =
+            typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /**
+         * Used to resolve the
+         * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+         * of values.
+         */
+        var objToString = objectProto.toString;
+
+        /**
+         * Checks if `value` is classified as a typed array.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to check.
+         * @returns {boolean} Returns `true` if `value` is correctly classified, else
+         *          `false`.
+         * @example
+         * 
+         * _.isTypedArray(new Uint8Array); // => true
+         * 
+         * _.isTypedArray([]); // => false
+         */
+        function isTypedArray(value) {
+            return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+        }
+
+        module.exports = isTypedArray;
+
+    }, {
+        "../internal/isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "../internal/isObjectLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isObjectLike.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\toPlainObject.js": [function(require, module, exports) {
+        var baseCopy = require('../internal/baseCopy'),
+            keysIn = require('../object/keysIn');
+
+        /**
+         * Converts `value` to a plain object flattening inherited enumerable properties
+         * of `value` to own properties of the plain object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Lang
+         * @param {*}
+         *            value The value to convert.
+         * @returns {Object} Returns the converted plain object.
+         * @example
+         * 
+         * function Foo() { this.b = 2; }
+         * 
+         * Foo.prototype.c = 3;
+         * 
+         * _.assign({ 'a': 1 }, new Foo); // => { 'a': 1, 'b': 2 }
+         * 
+         * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); // => { 'a': 1, 'b': 2, 'c':
+         * 3 }
+         */
+        function toPlainObject(value) {
+            return baseCopy(value, keysIn(value));
+        }
+
+        module.exports = toPlainObject;
+
+    }, {
+        "../internal/baseCopy": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseCopy.js",
+        "../object/keysIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keysIn.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\assign.js": [function(require, module, exports) {
+        var assignWith = require('../internal/assignWith'),
+            baseAssign = require('../internal/baseAssign'),
+            createAssigner = require('../internal/createAssigner');
+
+        /**
+         * Assigns own enumerable properties of source object(s) to the destination
+         * object. Subsequent sources overwrite property assignments of previous
+         * sources. If `customizer` is provided it's invoked to produce the assigned
+         * values. The `customizer` is bound to `thisArg` and invoked with five
+         * arguments: (objectValue, sourceValue, key, object, source).
+         * 
+         * **Note:** This method mutates `object` and is based on
+         * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
+         * 
+         * @static
+         * @memberOf _
+         * @alias extend
+         * @category Object
+         * @param {Object}
+         *            object The destination object.
+         * @param {...Object}
+         *            [sources] The source objects.
+         * @param {Function}
+         *            [customizer] The function to customize assigned values.
+         * @param {*}
+         *            [thisArg] The `this` binding of `customizer`.
+         * @returns {Object} Returns `object`.
+         * @example
+         * 
+         * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); // => {
+         * 'user': 'fred', 'age': 40 }
+         *  // using a customizer callback var defaults = _.partialRight(_.assign,
+         * function(value, other) { return _.isUndefined(value) ? other : value; });
+         * 
+         * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); // => {
+         * 'user': 'barney', 'age': 36 }
+         */
+        var assign = createAssigner(function(object, source, customizer) {
+            return customizer ? assignWith(object, source, customizer) : baseAssign(object, source);
+        });
+
+        module.exports = assign;
+
+    }, {
+        "../internal/assignWith": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\assignWith.js",
+        "../internal/baseAssign": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseAssign.js",
+        "../internal/createAssigner": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createAssigner.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js": [function(require, module, exports) {
+        var getNative = require('../internal/getNative'),
+            isArrayLike = require('../internal/isArrayLike'),
+            isObject = require('../lang/isObject'),
+            shimKeys = require('../internal/shimKeys');
+
+        /*
+         * Native method references for those with the same name as other `lodash`
+         * methods.
+         */
+        var nativeKeys = getNative(Object, 'keys');
+
+        /**
+         * Creates an array of the own enumerable property names of `object`.
+         * 
+         * **Note:** Non-object values are coerced to objects. See the [ES
+         * spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) for more
+         * details.
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the array of property names.
+         * @example
+         * 
+         * function Foo() { this.a = 1; this.b = 2; }
+         * 
+         * Foo.prototype.c = 3;
+         * 
+         * _.keys(new Foo); // => ['a', 'b'] (iteration order is not guaranteed)
+         * 
+         * _.keys('hi'); // => ['0', '1']
+         */
+        var keys = !nativeKeys ? shimKeys : function(object) {
+            var Ctor = object == null ? undefined : object.constructor;
+            if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+                (typeof object != 'function' && isArrayLike(object))) {
+                return shimKeys(object);
+            }
+            return isObject(object) ? nativeKeys(object) : [];
+        };
+
+        module.exports = keys;
+
+    }, {
+        "../internal/getNative": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\getNative.js",
+        "../internal/isArrayLike": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isArrayLike.js",
+        "../internal/shimKeys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\shimKeys.js",
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keysIn.js": [function(require, module, exports) {
+        var isArguments = require('../lang/isArguments'),
+            isArray = require('../lang/isArray'),
+            isIndex = require('../internal/isIndex'),
+            isLength = require('../internal/isLength'),
+            isObject = require('../lang/isObject');
+
+        /** Used for native method references. */
+        var objectProto = Object.prototype;
+
+        /** Used to check objects for own properties. */
+        var hasOwnProperty = objectProto.hasOwnProperty;
+
+        /**
+         * Creates an array of the own and inherited enumerable property names of
+         * `object`.
+         * 
+         * **Note:** Non-object values are coerced to objects.
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the array of property names.
+         * @example
+         * 
+         * function Foo() { this.a = 1; this.b = 2; }
+         * 
+         * Foo.prototype.c = 3;
+         * 
+         * _.keysIn(new Foo); // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+         */
+        function keysIn(object) {
+            if (object == null) {
+                return [];
+            }
+            if (!isObject(object)) {
+                object = Object(object);
+            }
+            var length = object.length;
+            length = (length && isLength(length) &&
+                (isArray(object) || isArguments(object)) && length) || 0;
+
+            var Ctor = object.constructor,
+                index = -1,
+                isProto = typeof Ctor == 'function' && Ctor.prototype === object,
+                result = Array(length),
+                skipIndexes = length > 0;
+
+            while (++index < length) {
+                result[index] = (index + '');
+            }
+            for (var key in object) {
+                if (!(skipIndexes && isIndex(key, length)) &&
+                    !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+                    result.push(key);
+                }
+            }
+            return result;
+        }
+
+        module.exports = keysIn;
+
+    }, {
+        "../internal/isIndex": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isIndex.js",
+        "../internal/isLength": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isLength.js",
+        "../lang/isArguments": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArguments.js",
+        "../lang/isArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isArray.js",
+        "../lang/isObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\lang\\isObject.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\merge.js": [function(require, module, exports) {
+        var baseMerge = require('../internal/baseMerge'),
+            createAssigner = require('../internal/createAssigner');
+
+        /**
+         * Recursively merges own enumerable properties of the source object(s), that
+         * don't resolve to `undefined` into the destination object. Subsequent sources
+         * overwrite property assignments of previous sources. If `customizer` is
+         * provided it's invoked to produce the merged values of the destination and
+         * source properties. If `customizer` returns `undefined` merging is handled by
+         * the method instead. The `customizer` is bound to `thisArg` and invoked with
+         * five arguments: (objectValue, sourceValue, key, object, source).
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The destination object.
+         * @param {...Object}
+         *            [sources] The source objects.
+         * @param {Function}
+         *            [customizer] The function to customize assigned values.
+         * @param {*}
+         *            [thisArg] The `this` binding of `customizer`.
+         * @returns {Object} Returns `object`.
+         * @example
+         * 
+         * var users = { 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] };
+         * 
+         * var ages = { 'data': [{ 'age': 36 }, { 'age': 40 }] };
+         * 
+         * _.merge(users, ages); // => { 'data': [{ 'user': 'barney', 'age': 36 }, {
+         * 'user': 'fred', 'age': 40 }] }
+         *  // using a customizer callback var object = { 'fruits': ['apple'],
+         * 'vegetables': ['beet'] };
+         * 
+         * var other = { 'fruits': ['banana'], 'vegetables': ['carrot'] };
+         * 
+         * _.merge(object, other, function(a, b) { if (_.isArray(a)) { return
+         * a.concat(b); } }); // => { 'fruits': ['apple', 'banana'], 'vegetables':
+         * ['beet', 'carrot'] }
+         */
+        var merge = createAssigner(baseMerge);
+
+        module.exports = merge;
+
+    }, {
+        "../internal/baseMerge": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseMerge.js",
+        "../internal/createAssigner": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\createAssigner.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\omit.js": [function(require, module, exports) {
+        var arrayMap = require('../internal/arrayMap'),
+            baseDifference = require('../internal/baseDifference'),
+            baseFlatten = require('../internal/baseFlatten'),
+            bindCallback = require('../internal/bindCallback'),
+            keysIn = require('./keysIn'),
+            pickByArray = require('../internal/pickByArray'),
+            pickByCallback = require('../internal/pickByCallback'),
+            restParam = require('../function/restParam');
+
+        /**
+         * The opposite of `_.pick`; this method creates an object composed of the own
+         * and inherited enumerable properties of `object` that are not omitted.
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The source object.
+         * @param {Function|...(string|string[])}
+         *            [predicate] The function invoked per iteration or property names
+         *            to omit, specified as individual property names or arrays of
+         *            property names.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {Object} Returns the new object.
+         * @example
+         * 
+         * var object = { 'user': 'fred', 'age': 40 };
+         * 
+         * _.omit(object, 'age'); // => { 'user': 'fred' }
+         * 
+         * _.omit(object, _.isNumber); // => { 'user': 'fred' }
+         */
+        var omit = restParam(function(object, props) {
+            if (object == null) {
+                return {};
+            }
+            if (typeof props[0] != 'function') {
+                var props = arrayMap(baseFlatten(props), String);
+                return pickByArray(object, baseDifference(keysIn(object), props));
+            }
+            var predicate = bindCallback(props[0], props[1], 3);
+            return pickByCallback(object, function(value, key, object) {
+                return !predicate(value, key, object);
+            });
+        });
+
+        module.exports = omit;
+
+    }, {
+        "../function/restParam": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js",
+        "../internal/arrayMap": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\arrayMap.js",
+        "../internal/baseDifference": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseDifference.js",
+        "../internal/baseFlatten": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFlatten.js",
+        "../internal/bindCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js",
+        "../internal/pickByArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByArray.js",
+        "../internal/pickByCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByCallback.js",
+        "./keysIn": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keysIn.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pairs.js": [function(require, module, exports) {
+        var keys = require('./keys'),
+            toObject = require('../internal/toObject');
+
+        /**
+         * Creates a two dimensional array of the key-value pairs for `object`, e.g.
+         * `[[key1, value1], [key2, value2]]`.
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the new array of key-value pairs.
+         * @example
+         * 
+         * _.pairs({ 'barney': 36, 'fred': 40 }); // => [['barney', 36], ['fred', 40]]
+         * (iteration order is not guaranteed)
+         */
+        function pairs(object) {
+            object = toObject(object);
+
+            var index = -1,
+                props = keys(object),
+                length = props.length,
+                result = Array(length);
+
+            while (++index < length) {
+                var key = props[index];
+                result[index] = [key, object[key]];
+            }
+            return result;
+        }
+
+        module.exports = pairs;
+
+    }, {
+        "../internal/toObject": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\toObject.js",
+        "./keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\pick.js": [function(require, module, exports) {
+        var baseFlatten = require('../internal/baseFlatten'),
+            bindCallback = require('../internal/bindCallback'),
+            pickByArray = require('../internal/pickByArray'),
+            pickByCallback = require('../internal/pickByCallback'),
+            restParam = require('../function/restParam');
+
+        /**
+         * Creates an object composed of the picked `object` properties. Property names
+         * may be specified as individual arguments or as arrays of property names. If
+         * `predicate` is provided it's invoked for each property of `object` picking
+         * the properties `predicate` returns truthy for. The predicate is bound to
+         * `thisArg` and invoked with three arguments: (value, key, object).
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The source object.
+         * @param {Function|...(string|string[])}
+         *            [predicate] The function invoked per iteration or property names
+         *            to pick, specified as individual property names or arrays of
+         *            property names.
+         * @param {*}
+         *            [thisArg] The `this` binding of `predicate`.
+         * @returns {Object} Returns the new object.
+         * @example
+         * 
+         * var object = { 'user': 'fred', 'age': 40 };
+         * 
+         * _.pick(object, 'user'); // => { 'user': 'fred' }
+         * 
+         * _.pick(object, _.isString); // => { 'user': 'fred' }
+         */
+        var pick = restParam(function(object, props) {
+            if (object == null) {
+                return {};
+            }
+            return typeof props[0] == 'function' ? pickByCallback(object, bindCallback(props[0], props[1], 3)) : pickByArray(object, baseFlatten(props));
+        });
+
+        module.exports = pick;
+
+    }, {
+        "../function/restParam": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\function\\restParam.js",
+        "../internal/baseFlatten": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseFlatten.js",
+        "../internal/bindCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\bindCallback.js",
+        "../internal/pickByArray": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByArray.js",
+        "../internal/pickByCallback": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\pickByCallback.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\values.js": [function(require, module, exports) {
+        var baseValues = require('../internal/baseValues'),
+            keys = require('./keys');
+
+        /**
+         * Creates an array of the own enumerable property values of `object`.
+         * 
+         * **Note:** Non-object values are coerced to objects.
+         * 
+         * @static
+         * @memberOf _
+         * @category Object
+         * @param {Object}
+         *            object The object to query.
+         * @returns {Array} Returns the array of property values.
+         * @example
+         * 
+         * function Foo() { this.a = 1; this.b = 2; }
+         * 
+         * Foo.prototype.c = 3;
+         * 
+         * _.values(new Foo); // => [1, 2] (iteration order is not guaranteed)
+         * 
+         * _.values('hi'); // => ['h', 'i']
+         */
+        function values(object) {
+            return baseValues(object, keys(object));
+        }
+
+        module.exports = values;
+
+    }, {
+        "../internal/baseValues": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseValues.js",
+        "./keys": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\object\\keys.js"
+    }],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\identity.js": [function(require, module, exports) {
+        /**
+         * This method returns the first argument provided to it.
+         * 
+         * @static
+         * @memberOf _
+         * @category Utility
+         * @param {*}
+         *            value Any value.
+         * @returns {*} Returns `value`.
+         * @example
+         * 
+         * var object = { 'user': 'fred' };
+         * 
+         * _.identity(object) === object; // => true
+         */
+        function identity(value) {
+            return value;
+        }
+
+        module.exports = identity;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\noop.js": [function(require, module, exports) {
+        /**
+         * A no-operation function that returns `undefined` regardless of the arguments
+         * it receives.
+         * 
+         * @static
+         * @memberOf _
+         * @category Utility
+         * @example
+         * 
+         * var object = { 'user': 'fred' };
+         * 
+         * _.noop(object) === undefined; // => true
+         */
+        function noop() {
+            // No operation performed.
+        }
+
+        module.exports = noop;
+
+    }, {}],
+    "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\utility\\property.js": [function(require, module, exports) {
+        var baseProperty = require('../internal/baseProperty'),
+            basePropertyDeep = require('../internal/basePropertyDeep'),
+            isKey = require('../internal/isKey');
+
+        /**
+         * Creates a function that returns the property value at `path` on a given
+         * object.
+         * 
+         * @static
+         * @memberOf _
+         * @category Utility
+         * @param {Array|string}
+         *            path The path of the property to get.
+         * @returns {Function} Returns the new function.
+         * @example
+         * 
+         * var objects = [ { 'a': { 'b': { 'c': 2 } } }, { 'a': { 'b': { 'c': 1 } } } ];
+         * 
+         * _.map(objects, _.property('a.b.c')); // => [2, 1]
+         * 
+         * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); // => [1,
+         * 2]
+         */
+        function property(path) {
+            return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
+        }
+
+        module.exports = property;
+
+    }, {
+        "../internal/baseProperty": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\baseProperty.js",
+        "../internal/basePropertyDeep": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\basePropertyDeep.js",
+        "../internal/isKey": "\\bpmn-js-examples-master\\modeler\\node_modules\\lodash\\internal\\isKey.js"
+    }]
+}, {}, ["\\bpmn-js-examples-master\\modeler\\app\\index.js"]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angucomplete.js b/src/main/resources/META-INF/resources/designer/lib/angucomplete.js
new file mode 100644 (file)
index 0000000..261aa9a
--- /dev/null
@@ -0,0 +1,246 @@
+/**
+ * Angucomplete
+ * Autocomplete directive for AngularJS
+ * By Daryl Rowland
+ */
+
+angular.module('angucomplete', [] )
+    .directive('angucomplete', function ($parse, $http, $sce, $timeout) {
+    return {
+        restrict: 'EA',
+        scope: {
+            "id": "@id",
+            "placeholder": "@placeholder",
+            "selectedObject": "=selectedobject",
+            "url": "@url",
+            "dataField": "@datafield",
+            "titleField": "@titlefield",
+            "descriptionField": "@descriptionfield",
+            "imageField": "@imagefield",
+            "imageUri": "@imageuri",
+            "inputClass": "@inputclass",
+            "userPause": "@pause",
+            "localData": "=localdata",
+            "searchFields": "@searchfields",
+            "minLengthUser": "@minlength",
+            "matchClass": "@matchclass"
+        },
+        template: '<div class="angucomplete-holder"><input id="{{id}}_value" ng-model="searchStr" type="text" placeholder="{{placeholder}}" class="{{inputClass}}" onmouseup="this.select();" ng-focus="resetHideResults()" ng-blur="hideResults()" /><div id="{{id}}_dropdown" class="angucomplete-dropdown" style="height:300px;overflow:auto;" ng-if="showDropdown"><div class="angucomplete-searching" ng-show="searching">Searching...</div><div class="angucomplete-searching" ng-show="!searching && (!results || results.length == 0)">No results found</div><div class="angucomplete-row" ng-repeat="result in results" ng-click="selectResult(result)" ng-mouseover="hoverRow()" ng-class="{\'angucomplete-selected-row\': $index == currentIndex}"><div ng-if="imageField" class="angucomplete-image-holder"><img ng-if="result.image && result.image != \'\'" ng-src="{{result.image}}" class="angucomplete-image"/><div ng-if="!result.image && result.image != \'\'" class="angucomplete-image-default"></div></div><div class="angucomplete-title" ng-if="matchClass" ng-bind-html="result.title"></div><div class="angucomplete-title" ng-if="!matchClass">{{ result.title }}</div><div ng-if="result.description && result.description != \'\'" class="angucomplete-description">{{result.description}}</div></div></div></div>',
+
+        link: function($scope, elem, attrs) {
+            $scope.lastSearchTerm = null;
+            $scope.currentIndex = null;
+            $scope.justChanged = false;
+            $scope.searchTimer = null;
+            $scope.hideTimer = null;
+            $scope.searching = false;
+            $scope.pause = 500;
+            $scope.minLength = 3;
+            $scope.searchStr = null;
+
+            if ($scope.minLengthUser && $scope.minLengthUser != "") {
+                $scope.minLength = $scope.minLengthUser;
+            }
+
+            if ($scope.userPause) {
+                $scope.pause = $scope.userPause;
+            }
+
+            isNewSearchNeeded = function(newTerm, oldTerm) {
+                return newTerm.length >= $scope.minLength && newTerm != oldTerm
+            }
+
+            $scope.processResults = function(responseData, str) {
+                if (responseData && responseData.length > 0) {
+                    $scope.results = [];
+
+                    var titleFields = [];
+                    if ($scope.titleField && $scope.titleField != "") {
+                        titleFields = $scope.titleField.split(",");
+                    }
+
+                    for (var i = 0; i < responseData.length; i++) {
+                        // Get title variables
+                        var titleCode = [];
+
+                        for (var t = 0; t < titleFields.length; t++) {
+                            titleCode.push(responseData[i][titleFields[t]]);
+                        }
+
+                        var description = "";
+                        if ($scope.descriptionField) {
+                            description = responseData[i][$scope.descriptionField];
+                        }
+
+                        var imageUri = "";
+                        if ($scope.imageUri) {
+                            imageUri = $scope.imageUri;
+                        }
+
+                        var image = "";
+                        if ($scope.imageField) {
+                            image = imageUri + responseData[i][$scope.imageField];
+                        }
+
+                        var text = titleCode.join(' ');
+                        if ($scope.matchClass) {
+                            var re = new RegExp(str, 'i');
+                            var strPart = text.match(re)[0];
+                            text = $sce.trustAsHtml(text.replace(re, '<span class="'+ $scope.matchClass +'">'+ strPart +'</span>'));
+                        }
+
+                        var resultRow = {
+                            title: text,
+                            description: description,
+                            image: image,
+                            originalObject: responseData[i]
+                        }
+
+                        $scope.results[$scope.results.length] = resultRow;
+                    }
+
+
+                } else {
+                    $scope.results = [];
+                }
+            }
+
+            $scope.searchTimerComplete = function(str) {
+                // Begin the search
+
+                if (str.length >= $scope.minLength) {
+                    if ($scope.localData) {
+                        var searchFields = $scope.searchFields.split(",");
+
+                        var matches = [];
+
+                        for (var i = 0; i < $scope.localData.length; i++) {
+                            var match = false;
+
+                            for (var s = 0; s < searchFields.length; s++) {
+                                match = match || (typeof $scope.localData[i][searchFields[s]] === 'string' && typeof str === 'string' && $scope.localData[i][searchFields[s]].toLowerCase().indexOf(str.toLowerCase()) >= 0);
+                            }
+
+                            if (match) {
+                                matches[matches.length] = $scope.localData[i];
+                            }
+                        }
+
+                        $scope.searching = false;
+                        $scope.processResults(matches, str);
+
+                    } else {
+                        $http.get($scope.url + str, {}).
+                            success(function(responseData, status, headers, config) {
+                                $scope.searching = false;
+                                $scope.processResults((($scope.dataField) ? responseData[$scope.dataField] : responseData ), str);
+                            }).
+                            error(function(data, status, headers, config) {
+                                console.log("error");
+                            });
+                    }
+                }
+            }
+
+            $scope.hideResults = function() {
+                $scope.hideTimer = $timeout(function() {
+                    $scope.showDropdown = false;
+                }, $scope.pause);
+            };
+
+            $scope.resetHideResults = function() {
+                if($scope.hideTimer) {
+                    $timeout.cancel($scope.hideTimer);
+                };
+            };
+
+            $scope.hoverRow = function(index) {
+                $scope.currentIndex = index;
+            }
+
+            $scope.keyPressed = function(event) {
+                if (!(event.which == 38 || event.which == 40 || event.which == 13)) {
+                    if (!$scope.searchStr || $scope.searchStr == "") {
+                        $scope.showDropdown = false;
+                        $scope.lastSearchTerm = null
+                    } else if (isNewSearchNeeded($scope.searchStr, $scope.lastSearchTerm)) {
+                        $scope.lastSearchTerm = $scope.searchStr
+                        $scope.showDropdown = true;
+                        $scope.currentIndex = -1;
+                        $scope.results = [];
+
+                        if ($scope.searchTimer) {
+                            $timeout.cancel($scope.searchTimer);
+                        }
+
+                        $scope.searching = true;
+
+                        $scope.searchTimer = $timeout(function() {
+                            $scope.searchTimerComplete($scope.searchStr);
+                        }, $scope.pause);
+                    }
+                } else {
+                    event.preventDefault();
+                }
+            }
+
+            $scope.selectResult = function(result) {
+                if ($scope.matchClass) {
+                    result.title = result.title.toString().replace(/(<([^>]+)>)/ig, '');
+                }
+                $scope.searchStr = $scope.lastSearchTerm = result.title;
+                $scope.selectedObject = result;
+                $scope.showDropdown = false;
+                $scope.results = [];
+                //$scope.$apply();
+            }
+
+            var inputField = elem.find('input');
+
+            inputField.on('keyup', $scope.keyPressed);
+
+            elem.on("keyup", function (event) {
+                if(event.which === 40) {
+                    if ($scope.results && ($scope.currentIndex + 1) < $scope.results.length) {
+                        $scope.currentIndex ++;
+                        $scope.$apply();
+                        event.preventDefault;
+                        event.stopPropagation();
+                    }
+
+                    $scope.$apply();
+                } else if(event.which == 38) {
+                    if ($scope.currentIndex >= 1) {
+                        $scope.currentIndex --;
+                        $scope.$apply();
+                        event.preventDefault;
+                        event.stopPropagation();
+                    }
+
+                } else if (event.which == 13) {
+                    if ($scope.results && $scope.currentIndex >= 0 && $scope.currentIndex < $scope.results.length) {
+                        $scope.selectResult($scope.results[$scope.currentIndex]);
+                        $scope.$apply();
+                        event.preventDefault;
+                        event.stopPropagation();
+                    } else {
+                        $scope.results = [];
+                        $scope.$apply();
+                        event.preventDefault;
+                        event.stopPropagation();
+                    }
+
+                } else if (event.which == 27) {
+                    $scope.results = [];
+                    $scope.showDropdown = false;
+                    $scope.$apply();
+                } else if (event.which == 8) {
+                    $scope.selectedObject = null;
+                    $scope.$apply();
+                }
+            });
+
+        }
+    };
+});
+
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-animate.js b/src/main/resources/META-INF/resources/designer/lib/angular-animate.js
new file mode 100644 (file)
index 0000000..6dae4ad
--- /dev/null
@@ -0,0 +1,1616 @@
+/**
+ * @license AngularJS v1.2.16
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/* jshint maxlen: false */
+
+/**
+ * @ngdoc module
+ * @name ngAnimate
+ * @description
+ *
+ * # ngAnimate
+ *
+ * The `ngAnimate` module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives.
+ *
+ *
+ * <div doc-module-components="ngAnimate"></div>
+ *
+ * # Usage
+ *
+ * To see animations in action, all that is required is to define the appropriate CSS classes
+ * or to register a JavaScript animation via the myModule.animation() function. The directives that support animation automatically are:
+ * `ngRepeat`, `ngInclude`, `ngIf`, `ngSwitch`, `ngShow`, `ngHide`, `ngView` and `ngClass`. Custom directives can take advantage of animation
+ * by using the `$animate` service.
+ *
+ * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives:
+ *
+ * | Directive                                                 | Supported Animations                               |
+ * |---------------------------------------------------------- |----------------------------------------------------|
+ * | {@link ng.directive:ngRepeat#usage_animations ngRepeat}         | enter, leave and move                              |
+ * | {@link ngRoute.directive:ngView#usage_animations ngView}        | enter and leave                                    |
+ * | {@link ng.directive:ngInclude#usage_animations ngInclude}       | enter and leave                                    |
+ * | {@link ng.directive:ngSwitch#usage_animations ngSwitch}         | enter and leave                                    |
+ * | {@link ng.directive:ngIf#usage_animations ngIf}                 | enter and leave                                    |
+ * | {@link ng.directive:ngClass#usage_animations ngClass}           | add and remove                                     |
+ * | {@link ng.directive:ngShow#usage_animations ngShow & ngHide}    | add and remove (the ng-hide class value)           |
+ * | {@link ng.directive:form#usage_animations form}                 | add and remove (dirty, pristine, valid, invalid & all other validations)                |
+ * | {@link ng.directive:ngModel#usage_animations ngModel}           | add and remove (dirty, pristine, valid, invalid & all other validations)                |
+ *
+ * You can find out more information about animations upon visiting each directive page.
+ *
+ * Below is an example of how to apply animations to a directive that supports animation hooks:
+ *
+ * ```html
+ * <style type="text/css">
+ * .slide.ng-enter, .slide.ng-leave {
+ *   -webkit-transition:0.5s linear all;
+ *   transition:0.5s linear all;
+ * }
+ *
+ * .slide.ng-enter { }        /&#42; starting animations for enter &#42;/
+ * .slide.ng-enter-active { } /&#42; terminal animations for enter &#42;/
+ * .slide.ng-leave { }        /&#42; starting animations for leave &#42;/
+ * .slide.ng-leave-active { } /&#42; terminal animations for leave &#42;/
+ * </style>
+ *
+ * <!--
+ * the animate service will automatically add .ng-enter and .ng-leave to the element
+ * to trigger the CSS transition/animations
+ * -->
+ * <ANY class="slide" ng-include="..."></ANY>
+ * ```
+ *
+ * Keep in mind that if an animation is running, any child elements cannot be animated until the parent element's
+ * animation has completed.
+ *
+ * <h2>CSS-defined Animations</h2>
+ * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes
+ * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported
+ * and can be used to play along with this naming structure.
+ *
+ * The following code below demonstrates how to perform animations using **CSS transitions** with Angular:
+ *
+ * ```html
+ * <style type="text/css">
+ * /&#42;
+ *  The animate class is apart of the element and the ng-enter class
+ *  is attached to the element once the enter animation event is triggered
+ * &#42;/
+ * .reveal-animation.ng-enter {
+ *  -webkit-transition: 1s linear all; /&#42; Safari/Chrome &#42;/
+ *  transition: 1s linear all; /&#42; All other modern browsers and IE10+ &#42;/
+ *
+ *  /&#42; The animation preparation code &#42;/
+ *  opacity: 0;
+ * }
+ *
+ * /&#42;
+ *  Keep in mind that you want to combine both CSS
+ *  classes together to avoid any CSS-specificity
+ *  conflicts
+ * &#42;/
+ * .reveal-animation.ng-enter.ng-enter-active {
+ *  /&#42; The animation code itself &#42;/
+ *  opacity: 1;
+ * }
+ * </style>
+ *
+ * <div class="view-container">
+ *   <div ng-view class="reveal-animation"></div>
+ * </div>
+ * ```
+ *
+ * The following code below demonstrates how to perform animations using **CSS animations** with Angular:
+ *
+ * ```html
+ * <style type="text/css">
+ * .reveal-animation.ng-enter {
+ *   -webkit-animation: enter_sequence 1s linear; /&#42; Safari/Chrome &#42;/
+ *   animation: enter_sequence 1s linear; /&#42; IE10+ and Future Browsers &#42;/
+ * }
+ * @-webkit-keyframes enter_sequence {
+ *   from { opacity:0; }
+ *   to { opacity:1; }
+ * }
+ * @keyframes enter_sequence {
+ *   from { opacity:0; }
+ *   to { opacity:1; }
+ * }
+ * </style>
+ *
+ * <div class="view-container">
+ *   <div ng-view class="reveal-animation"></div>
+ * </div>
+ * ```
+ *
+ * Both CSS3 animations and transitions can be used together and the animate service will figure out the correct duration and delay timing.
+ *
+ * Upon DOM mutation, the event class is added first (something like `ng-enter`), then the browser prepares itself to add
+ * the active class (in this case `ng-enter-active`) which then triggers the animation. The animation module will automatically
+ * detect the CSS code to determine when the animation ends. Once the animation is over then both CSS classes will be
+ * removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end
+ * immediately resulting in a DOM element that is at its final state. This final state is when the DOM element
+ * has no CSS transition/animation classes applied to it.
+ *
+ * <h3>CSS Staggering Animations</h3>
+ * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a
+ * curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be
+ * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for
+ * the animation. The style property expected within the stagger class can either be a **transition-delay** or an
+ * **animation-delay** property (or both if your animation contains both transitions and keyframe animations).
+ *
+ * ```css
+ * .my-animation.ng-enter {
+ *   /&#42; standard transition code &#42;/
+ *   -webkit-transition: 1s linear all;
+ *   transition: 1s linear all;
+ *   opacity:0;
+ * }
+ * .my-animation.ng-enter-stagger {
+ *   /&#42; this will have a 100ms delay between each successive leave animation &#42;/
+ *   -webkit-transition-delay: 0.1s;
+ *   transition-delay: 0.1s;
+ *
+ *   /&#42; in case the stagger doesn't work then these two values
+ *    must be set to 0 to avoid an accidental CSS inheritance &#42;/
+ *   -webkit-transition-duration: 0s;
+ *   transition-duration: 0s;
+ * }
+ * .my-animation.ng-enter.ng-enter-active {
+ *   /&#42; standard transition styles &#42;/
+ *   opacity:1;
+ * }
+ * ```
+ *
+ * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations
+ * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this
+ * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation
+ * will also be reset if more than 10ms has passed after the last animation has been fired.
+ *
+ * The following code will issue the **ng-leave-stagger** event on the element provided:
+ *
+ * ```js
+ * var kids = parent.children();
+ *
+ * $animate.leave(kids[0]); //stagger index=0
+ * $animate.leave(kids[1]); //stagger index=1
+ * $animate.leave(kids[2]); //stagger index=2
+ * $animate.leave(kids[3]); //stagger index=3
+ * $animate.leave(kids[4]); //stagger index=4
+ *
+ * $timeout(function() {
+ *   //stagger has reset itself
+ *   $animate.leave(kids[5]); //stagger index=0
+ *   $animate.leave(kids[6]); //stagger index=1
+ * }, 100, false);
+ * ```
+ *
+ * Stagger animations are currently only supported within CSS-defined animations.
+ *
+ * <h2>JavaScript-defined Animations</h2>
+ * In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations on browsers that do not
+ * yet support CSS transitions/animations, then you can make use of JavaScript animations defined inside of your AngularJS module.
+ *
+ * ```js
+ * //!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application.
+ * var ngModule = angular.module('YourApp', ['ngAnimate']);
+ * ngModule.animation('.my-crazy-animation', function() {
+ *   return {
+ *     enter: function(element, done) {
+ *       //run the animation here and call done when the animation is complete
+ *       return function(cancelled) {
+ *         //this (optional) function will be called when the animation
+ *         //completes or when the animation is cancelled (the cancelled
+ *         //flag will be set to true if cancelled).
+ *       };
+ *     },
+ *     leave: function(element, done) { },
+ *     move: function(element, done) { },
+ *
+ *     //animation that can be triggered before the class is added
+ *     beforeAddClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered after the class is added
+ *     addClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered before the class is removed
+ *     beforeRemoveClass: function(element, className, done) { },
+ *
+ *     //animation that can be triggered after the class is removed
+ *     removeClass: function(element, className, done) { }
+ *   };
+ * });
+ * ```
+ *
+ * JavaScript-defined animations are created with a CSS-like class selector and a collection of events which are set to run
+ * a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits
+ * the element's CSS class attribute value and then run the matching animation event function (if found).
+ * In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function will
+ * be executed. It should be also noted that only simple, single class selectors are allowed (compound class selectors are not supported).
+ *
+ * Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned.
+ * As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run,
+ * and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation
+ * or transition code that is defined via a stylesheet).
+ *
+ */
+
+angular.module('ngAnimate', ['ng'])
+
+  /**
+   * @ngdoc provider
+   * @name $animateProvider
+   * @description
+   *
+   * The `$animateProvider` allows developers to register JavaScript animation event handlers directly inside of a module.
+   * When an animation is triggered, the $animate service will query the $animate service to find any animations that match
+   * the provided name value.
+   *
+   * Requires the {@link ngAnimate `ngAnimate`} module to be installed.
+   *
+   * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
+   *
+   */
+
+  //this private service is only used within CSS-enabled animations
+  //IE8 + IE9 do not support rAF natively, but that is fine since they
+  //also don't support transitions and keyframes which means that the code
+  //below will never be used by the two browsers.
+  .factory('$$animateReflow', ['$$rAF', '$document', function($$rAF, $document) {
+    var bod = $document[0].body;
+    return function(fn) {
+      //the returned function acts as the cancellation function
+      return $$rAF(function() {
+        //the line below will force the browser to perform a repaint
+        //so that all the animated elements within the animation frame
+        //will be properly updated and drawn on screen. This is
+        //required to perform multi-class CSS based animations with
+        //Firefox. DO NOT REMOVE THIS LINE.
+        var a = bod.offsetWidth + 1;
+        fn();
+      });
+    };
+  }])
+
+  .config(['$provide', '$animateProvider', function($provide, $animateProvider) {
+    var noop = angular.noop;
+    var forEach = angular.forEach;
+    var selectors = $animateProvider.$$selectors;
+
+    var ELEMENT_NODE = 1;
+    var NG_ANIMATE_STATE = '$$ngAnimateState';
+    var NG_ANIMATE_CLASS_NAME = 'ng-animate';
+    var rootAnimateState = {running: true};
+
+    function extractElementNode(element) {
+      for(var i = 0; i < element.length; i++) {
+        var elm = element[i];
+        if(elm.nodeType == ELEMENT_NODE) {
+          return elm;
+        }
+      }
+    }
+
+    function stripCommentsFromElement(element) {
+      return angular.element(extractElementNode(element));
+    }
+
+    function isMatchingElement(elm1, elm2) {
+      return extractElementNode(elm1) == extractElementNode(elm2);
+    }
+
+    $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document',
+                            function($delegate,   $injector,   $sniffer,   $rootElement,   $$asyncCallback,    $rootScope,   $document) {
+
+      var globalAnimationCounter = 0;
+      $rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
+
+      // disable animations during bootstrap, but once we bootstrapped, wait again
+      // for another digest until enabling animations. The reason why we digest twice
+      // is because all structural animations (enter, leave and move) all perform a
+      // post digest operation before animating. If we only wait for a single digest
+      // to pass then the structural animation would render its animation on page load.
+      // (which is what we're trying to avoid when the application first boots up.)
+      $rootScope.$$postDigest(function() {
+        $rootScope.$$postDigest(function() {
+          rootAnimateState.running = false;
+        });
+      });
+
+      var classNameFilter = $animateProvider.classNameFilter();
+      var isAnimatableClassName = !classNameFilter
+              ? function() { return true; }
+              : function(className) {
+                return classNameFilter.test(className);
+              };
+
+      function lookup(name) {
+        if (name) {
+          var matches = [],
+              flagMap = {},
+              classes = name.substr(1).split('.');
+
+          //the empty string value is the default animation
+          //operation which performs CSS transition and keyframe
+          //animations sniffing. This is always included for each
+          //element animation procedure if the browser supports
+          //transitions and/or keyframe animations. The default
+          //animation is added to the top of the list to prevent
+          //any previous animations from affecting the element styling
+          //prior to the element being animated.
+          if ($sniffer.transitions || $sniffer.animations) {
+            matches.push($injector.get(selectors['']));
+          }
+
+          for(var i=0; i < classes.length; i++) {
+            var klass = classes[i],
+                selectorFactoryName = selectors[klass];
+            if(selectorFactoryName && !flagMap[klass]) {
+              matches.push($injector.get(selectorFactoryName));
+              flagMap[klass] = true;
+            }
+          }
+          return matches;
+        }
+      }
+
+      function animationRunner(element, animationEvent, className) {
+        //transcluded directives may sometimes fire an animation using only comment nodes
+        //best to catch this early on to prevent any animation operations from occurring
+        var node = element[0];
+        if(!node) {
+          return;
+        }
+
+        var isSetClassOperation = animationEvent == 'setClass';
+        var isClassBased = isSetClassOperation ||
+                           animationEvent == 'addClass' ||
+                           animationEvent == 'removeClass';
+
+        var classNameAdd, classNameRemove;
+        if(angular.isArray(className)) {
+          classNameAdd = className[0];
+          classNameRemove = className[1];
+          className = classNameAdd + ' ' + classNameRemove;
+        }
+
+        var currentClassName = element.attr('class');
+        var classes = currentClassName + ' ' + className;
+        if(!isAnimatableClassName(classes)) {
+          return;
+        }
+
+        var beforeComplete = noop,
+            beforeCancel = [],
+            before = [],
+            afterComplete = noop,
+            afterCancel = [],
+            after = [];
+
+        var animationLookup = (' ' + classes).replace(/\s+/g,'.');
+        forEach(lookup(animationLookup), function(animationFactory) {
+          var created = registerAnimation(animationFactory, animationEvent);
+          if(!created && isSetClassOperation) {
+            registerAnimation(animationFactory, 'addClass');
+            registerAnimation(animationFactory, 'removeClass');
+          }
+        });
+
+        function registerAnimation(animationFactory, event) {
+          var afterFn = animationFactory[event];
+          var beforeFn = animationFactory['before' + event.charAt(0).toUpperCase() + event.substr(1)];
+          if(afterFn || beforeFn) {
+            if(event == 'leave') {
+              beforeFn = afterFn;
+              //when set as null then animation knows to skip this phase
+              afterFn = null;
+            }
+            after.push({
+              event : event, fn : afterFn
+            });
+            before.push({
+              event : event, fn : beforeFn
+            });
+            return true;
+          }
+        }
+
+        function run(fns, cancellations, allCompleteFn) {
+          var animations = [];
+          forEach(fns, function(animation) {
+            animation.fn && animations.push(animation);
+          });
+
+          var count = 0;
+          function afterAnimationComplete(index) {
+            if(cancellations) {
+              (cancellations[index] || noop)();
+              if(++count < animations.length) return;
+              cancellations = null;
+            }
+            allCompleteFn();
+          }
+
+          //The code below adds directly to the array in order to work with
+          //both sync and async animations. Sync animations are when the done()
+          //operation is called right away. DO NOT REFACTOR!
+          forEach(animations, function(animation, index) {
+            var progress = function() {
+              afterAnimationComplete(index);
+            };
+            switch(animation.event) {
+              case 'setClass':
+                cancellations.push(animation.fn(element, classNameAdd, classNameRemove, progress));
+                break;
+              case 'addClass':
+                cancellations.push(animation.fn(element, classNameAdd || className,     progress));
+                break;
+              case 'removeClass':
+                cancellations.push(animation.fn(element, classNameRemove || className,  progress));
+                break;
+              default:
+                cancellations.push(animation.fn(element, progress));
+                break;
+            }
+          });
+
+          if(cancellations && cancellations.length === 0) {
+            allCompleteFn();
+          }
+        }
+
+        return {
+          node : node,
+          event : animationEvent,
+          className : className,
+          isClassBased : isClassBased,
+          isSetClassOperation : isSetClassOperation,
+          before : function(allCompleteFn) {
+            beforeComplete = allCompleteFn;
+            run(before, beforeCancel, function() {
+              beforeComplete = noop;
+              allCompleteFn();
+            });
+          },
+          after : function(allCompleteFn) {
+            afterComplete = allCompleteFn;
+            run(after, afterCancel, function() {
+              afterComplete = noop;
+              allCompleteFn();
+            });
+          },
+          cancel : function() {
+            if(beforeCancel) {
+              forEach(beforeCancel, function(cancelFn) {
+                (cancelFn || noop)(true);
+              });
+              beforeComplete(true);
+            }
+            if(afterCancel) {
+              forEach(afterCancel, function(cancelFn) {
+                (cancelFn || noop)(true);
+              });
+              afterComplete(true);
+            }
+          }
+        };
+      }
+
+      /**
+       * @ngdoc service
+       * @name $animate
+       * @function
+       *
+       * @description
+       * The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move) as well as during addClass and removeClass operations.
+       * When any of these operations are run, the $animate service
+       * will examine any JavaScript-defined animations (which are defined by using the $animateProvider provider object)
+       * as well as any CSS-defined animations against the CSS classes present on the element once the DOM operation is run.
+       *
+       * The `$animate` service is used behind the scenes with pre-existing directives and animation with these directives
+       * will work out of the box without any extra configuration.
+       *
+       * Requires the {@link ngAnimate `ngAnimate`} module to be installed.
+       *
+       * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
+       *
+       */
+      return {
+        /**
+         * @ngdoc method
+         * @name $animate#enter
+         * @function
+         *
+         * @description
+         * Appends the element to the parentElement element that resides in the document and then runs the enter animation. Once
+         * the animation is started, the following CSS classes will be present on the element for the duration of the animation:
+         *
+         * Below is a breakdown of each step that occurs during enter animation:
+         *
+         * | Animation Step                                                                               | What the element class attribute looks like |
+         * |----------------------------------------------------------------------------------------------|---------------------------------------------|
+         * | 1. $animate.enter(...) is called                                                             | class="my-animation"                        |
+         * | 2. element is inserted into the parentElement element or beside the afterElement element     | class="my-animation"                        |
+         * | 3. $animate runs any JavaScript-defined animations on the element                            | class="my-animation ng-animate"             |
+         * | 4. the .ng-enter class is added to the element                                               | class="my-animation ng-animate ng-enter"    |
+         * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay  | class="my-animation ng-animate ng-enter"    |
+         * | 6. $animate waits for 10ms (this performs a reflow)                                          | class="my-animation ng-animate ng-enter"    |
+         * | 7. the .ng-enter-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" |
+         * | 8. $animate waits for X milliseconds for the animation to complete                           | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" |
+         * | 9. The animation ends and all generated CSS classes are removed from the element             | class="my-animation"                        |
+         * | 10. The doneCallback() callback is fired (if provided)                                       | class="my-animation"                        |
+         *
+         * @param {DOMElement} element the element that will be the focus of the enter animation
+         * @param {DOMElement} parentElement the parent element of the element that will be the focus of the enter animation
+         * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation
+         * @param {function()=} doneCallback the callback function that will be called once the animation is complete
+        */
+        enter : function(element, parentElement, afterElement, doneCallback) {
+          this.enabled(false, element);
+          $delegate.enter(element, parentElement, afterElement);
+          $rootScope.$$postDigest(function() {
+            element = stripCommentsFromElement(element);
+            performAnimation('enter', 'ng-enter', element, parentElement, afterElement, noop, doneCallback);
+          });
+        },
+
+        /**
+         * @ngdoc method
+         * @name $animate#leave
+         * @function
+         *
+         * @description
+         * Runs the leave animation operation and, upon completion, removes the element from the DOM. Once
+         * the animation is started, the following CSS classes will be added for the duration of the animation:
+         *
+         * Below is a breakdown of each step that occurs during leave animation:
+         *
+         * | Animation Step                                                                               | What the element class attribute looks like |
+         * |----------------------------------------------------------------------------------------------|---------------------------------------------|
+         * | 1. $animate.leave(...) is called                                                             | class="my-animation"                        |
+         * | 2. $animate runs any JavaScript-defined animations on the element                            | class="my-animation ng-animate"             |
+         * | 3. the .ng-leave class is added to the element                                               | class="my-animation ng-animate ng-leave"    |
+         * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay  | class="my-animation ng-animate ng-leave"    |
+         * | 5. $animate waits for 10ms (this performs a reflow)                                          | class="my-animation ng-animate ng-leave"    |
+         * | 6. the .ng-leave-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" |
+         * | 7. $animate waits for X milliseconds for the animation to complete                           | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" |
+         * | 8. The animation ends and all generated CSS classes are removed from the element             | class="my-animation"                        |
+         * | 9. The element is removed from the DOM                                                       | ...                                         |
+         * | 10. The doneCallback() callback is fired (if provided)                                       | ...                                         |
+         *
+         * @param {DOMElement} element the element that will be the focus of the leave animation
+         * @param {function()=} doneCallback the callback function that will be called once the animation is complete
+        */
+        leave : function(element, doneCallback) {
+          cancelChildAnimations(element);
+          this.enabled(false, element);
+          $rootScope.$$postDigest(function() {
+            performAnimation('leave', 'ng-leave', stripCommentsFromElement(element), null, null, function() {
+              $delegate.leave(element);
+            }, doneCallback);
+          });
+        },
+
+        /**
+         * @ngdoc method
+         * @name $animate#move
+         * @function
+         *
+         * @description
+         * Fires the move DOM operation. Just before the animation starts, the animate service will either append it into the parentElement container or
+         * add the element directly after the afterElement element if present. Then the move animation will be run. Once
+         * the animation is started, the following CSS classes will be added for the duration of the animation:
+         *
+         * Below is a breakdown of each step that occurs during move animation:
+         *
+         * | Animation Step                                                                               | What the element class attribute looks like |
+         * |----------------------------------------------------------------------------------------------|---------------------------------------------|
+         * | 1. $animate.move(...) is called                                                              | class="my-animation"                        |
+         * | 2. element is moved into the parentElement element or beside the afterElement element        | class="my-animation"                        |
+         * | 3. $animate runs any JavaScript-defined animations on the element                            | class="my-animation ng-animate"             |
+         * | 4. the .ng-move class is added to the element                                                | class="my-animation ng-animate ng-move"     |
+         * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay  | class="my-animation ng-animate ng-move"     |
+         * | 6. $animate waits for 10ms (this performs a reflow)                                          | class="my-animation ng-animate ng-move"     |
+         * | 7. the .ng-move-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" |
+         * | 8. $animate waits for X milliseconds for the animation to complete                           | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" |
+         * | 9. The animation ends and all generated CSS classes are removed from the element             | class="my-animation"                        |
+         * | 10. The doneCallback() callback is fired (if provided)                                       | class="my-animation"                        |
+         *
+         * @param {DOMElement} element the element that will be the focus of the move animation
+         * @param {DOMElement} parentElement the parentElement element of the element that will be the focus of the move animation
+         * @param {DOMElement} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation
+         * @param {function()=} doneCallback the callback function that will be called once the animation is complete
+        */
+        move : function(element, parentElement, afterElement, doneCallback) {
+          cancelChildAnimations(element);
+          this.enabled(false, element);
+          $delegate.move(element, parentElement, afterElement);
+          $rootScope.$$postDigest(function() {
+            element = stripCommentsFromElement(element);
+            performAnimation('move', 'ng-move', element, parentElement, afterElement, noop, doneCallback);
+          });
+        },
+
+        /**
+         * @ngdoc method
+         * @name $animate#addClass
+         *
+         * @description
+         * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class.
+         * Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide
+         * the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if no CSS transitions
+         * or keyframes are defined on the -add or base CSS class).
+         *
+         * Below is a breakdown of each step that occurs during addClass animation:
+         *
+         * | Animation Step                                                                                 | What the element class attribute looks like |
+         * |------------------------------------------------------------------------------------------------|---------------------------------------------|
+         * | 1. $animate.addClass(element, 'super') is called                                               | class="my-animation"                        |
+         * | 2. $animate runs any JavaScript-defined animations on the element                              | class="my-animation ng-animate"             |
+         * | 3. the .super-add class are added to the element                                               | class="my-animation ng-animate super-add"   |
+         * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay    | class="my-animation ng-animate super-add"   |
+         * | 5. $animate waits for 10ms (this performs a reflow)                                            | class="my-animation ng-animate super-add"   |
+         * | 6. the .super, .super-add-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super super-add super-add-active"          |
+         * | 7. $animate waits for X milliseconds for the animation to complete                             | class="my-animation super super-add super-add-active"  |
+         * | 8. The animation ends and all generated CSS classes are removed from the element               | class="my-animation super"                  |
+         * | 9. The super class is kept on the element                                                      | class="my-animation super"                  |
+         * | 10. The doneCallback() callback is fired (if provided)                                         | class="my-animation super"                  |
+         *
+         * @param {DOMElement} element the element that will be animated
+         * @param {string} className the CSS class that will be added to the element and then animated
+         * @param {function()=} doneCallback the callback function that will be called once the animation is complete
+        */
+        addClass : function(element, className, doneCallback) {
+          element = stripCommentsFromElement(element);
+          performAnimation('addClass', className, element, null, null, function() {
+            $delegate.addClass(element, className);
+          }, doneCallback);
+        },
+
+        /**
+         * @ngdoc method
+         * @name $animate#removeClass
+         *
+         * @description
+         * Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value
+         * from the element. Unlike the other animation methods, the animate service will suffix the className value with {@type -remove} in
+         * order to provide the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if
+         * no CSS transitions or keyframes are defined on the -remove or base CSS classes).
+         *
+         * Below is a breakdown of each step that occurs during removeClass animation:
+         *
+         * | Animation Step                                                                                | What the element class attribute looks like     |
+         * |-----------------------------------------------------------------------------------------------|---------------------------------------------|
+         * | 1. $animate.removeClass(element, 'super') is called                                           | class="my-animation super"                  |
+         * | 2. $animate runs any JavaScript-defined animations on the element                             | class="my-animation super ng-animate"       |
+         * | 3. the .super-remove class are added to the element                                           | class="my-animation super ng-animate super-remove"|
+         * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay   | class="my-animation super ng-animate super-remove"   |
+         * | 5. $animate waits for 10ms (this performs a reflow)                                           | class="my-animation super ng-animate super-remove"   |
+         * | 6. the .super-remove-active and .ng-animate-active classes are added and .super is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super-remove super-remove-active"          |
+         * | 7. $animate waits for X milliseconds for the animation to complete                            | class="my-animation ng-animate ng-animate-active super-remove super-remove-active"   |
+         * | 8. The animation ends and all generated CSS classes are removed from the element              | class="my-animation"                        |
+         * | 9. The doneCallback() callback is fired (if provided)                                         | class="my-animation"                        |
+         *
+         *
+         * @param {DOMElement} element the element that will be animated
+         * @param {string} className the CSS class that will be animated and then removed from the element
+         * @param {function()=} doneCallback the callback function that will be called once the animation is complete
+        */
+        removeClass : function(element, className, doneCallback) {
+          element = stripCommentsFromElement(element);
+          performAnimation('removeClass', className, element, null, null, function() {
+            $delegate.removeClass(element, className);
+          }, doneCallback);
+        },
+
+          /**
+           *
+           * @ngdoc function
+           * @name $animate#setClass
+           * @function
+           * @description Adds and/or removes the given CSS classes to and from the element.
+           * Once complete, the done() callback will be fired (if provided).
+           * @param {DOMElement} element the element which will it's CSS classes changed
+           *   removed from it
+           * @param {string} add the CSS classes which will be added to the element
+           * @param {string} remove the CSS class which will be removed from the element
+           * @param {Function=} done the callback function (if provided) that will be fired after the
+           *   CSS classes have been set on the element
+           */
+        setClass : function(element, add, remove, doneCallback) {
+          element = stripCommentsFromElement(element);
+          performAnimation('setClass', [add, remove], element, null, null, function() {
+            $delegate.setClass(element, add, remove);
+          }, doneCallback);
+        },
+
+        /**
+         * @ngdoc method
+         * @name $animate#enabled
+         * @function
+         *
+         * @param {boolean=} value If provided then set the animation on or off.
+         * @param {DOMElement=} element If provided then the element will be used to represent the enable/disable operation
+         * @return {boolean} Current animation state.
+         *
+         * @description
+         * Globally enables/disables animations.
+         *
+        */
+        enabled : function(value, element) {
+          switch(arguments.length) {
+            case 2:
+              if(value) {
+                cleanup(element);
+              } else {
+                var data = element.data(NG_ANIMATE_STATE) || {};
+                data.disabled = true;
+                element.data(NG_ANIMATE_STATE, data);
+              }
+            break;
+
+            case 1:
+              rootAnimateState.disabled = !value;
+            break;
+
+            default:
+              value = !rootAnimateState.disabled;
+            break;
+          }
+          return !!value;
+         }
+      };
+
+      /*
+        all animations call this shared animation triggering function internally.
+        The animationEvent variable refers to the JavaScript animation event that will be triggered
+        and the className value is the name of the animation that will be applied within the
+        CSS code. Element, parentElement and afterElement are provided DOM elements for the animation
+        and the onComplete callback will be fired once the animation is fully complete.
+      */
+      function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
+
+        var runner = animationRunner(element, animationEvent, className);
+        if(!runner) {
+          fireDOMOperation();
+          fireBeforeCallbackAsync();
+          fireAfterCallbackAsync();
+          closeAnimation();
+          return;
+        }
+
+        className = runner.className;
+        var elementEvents = angular.element._data(runner.node);
+        elementEvents = elementEvents && elementEvents.events;
+
+        if (!parentElement) {
+          parentElement = afterElement ? afterElement.parent() : element.parent();
+        }
+
+        var ngAnimateState  = element.data(NG_ANIMATE_STATE) || {};
+        var runningAnimations     = ngAnimateState.active || {};
+        var totalActiveAnimations = ngAnimateState.totalActive || 0;
+        var lastAnimation         = ngAnimateState.last;
+
+        //only allow animations if the currently running animation is not structural
+        //or if there is no animation running at all
+        var skipAnimations = runner.isClassBased ?
+          ngAnimateState.disabled || (lastAnimation && !lastAnimation.isClassBased) :
+          false;
+
+        //skip the animation if animations are disabled, a parent is already being animated,
+        //the element is not currently attached to the document body or then completely close
+        //the animation if any matching animations are not found at all.
+        //NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case an animation was found.
+        if (skipAnimations || animationsDisabled(element, parentElement)) {
+          fireDOMOperation();
+          fireBeforeCallbackAsync();
+          fireAfterCallbackAsync();
+          closeAnimation();
+          return;
+        }
+
+        var skipAnimation = false;
+        if(totalActiveAnimations > 0) {
+          var animationsToCancel = [];
+          if(!runner.isClassBased) {
+            if(animationEvent == 'leave' && runningAnimations['ng-leave']) {
+              skipAnimation = true;
+            } else {
+              //cancel all animations when a structural animation takes place
+              for(var klass in runningAnimations) {
+                animationsToCancel.push(runningAnimations[klass]);
+                cleanup(element, klass);
+              }
+              runningAnimations = {};
+              totalActiveAnimations = 0;
+            }
+          } else if(lastAnimation.event == 'setClass') {
+            animationsToCancel.push(lastAnimation);
+            cleanup(element, className);
+          }
+          else if(runningAnimations[className]) {
+            var current = runningAnimations[className];
+            if(current.event == animationEvent) {
+              skipAnimation = true;
+            } else {
+              animationsToCancel.push(current);
+              cleanup(element, className);
+            }
+          }
+
+          if(animationsToCancel.length > 0) {
+            forEach(animationsToCancel, function(operation) {
+              operation.cancel();
+            });
+          }
+        }
+
+        if(runner.isClassBased && !runner.isSetClassOperation && !skipAnimation) {
+          skipAnimation = (animationEvent == 'addClass') == element.hasClass(className); //opposite of XOR
+        }
+
+        if(skipAnimation) {
+          fireBeforeCallbackAsync();
+          fireAfterCallbackAsync();
+          fireDoneCallbackAsync();
+          return;
+        }
+
+        if(animationEvent == 'leave') {
+          //there's no need to ever remove the listener since the element
+          //will be removed (destroyed) after the leave animation ends or
+          //is cancelled midway
+          element.one('$destroy', function(e) {
+            var element = angular.element(this);
+            var state = element.data(NG_ANIMATE_STATE);
+            if(state) {
+              var activeLeaveAnimation = state.active['ng-leave'];
+              if(activeLeaveAnimation) {
+                activeLeaveAnimation.cancel();
+                cleanup(element, 'ng-leave');
+              }
+            }
+          });
+        }
+
+        //the ng-animate class does nothing, but it's here to allow for
+        //parent animations to find and cancel child animations when needed
+        element.addClass(NG_ANIMATE_CLASS_NAME);
+
+        var localAnimationCount = globalAnimationCounter++;
+        totalActiveAnimations++;
+        runningAnimations[className] = runner;
+
+        element.data(NG_ANIMATE_STATE, {
+          last : runner,
+          active : runningAnimations,
+          index : localAnimationCount,
+          totalActive : totalActiveAnimations
+        });
+
+        //first we run the before animations and when all of those are complete
+        //then we perform the DOM operation and run the next set of animations
+        fireBeforeCallbackAsync();
+        runner.before(function(cancelled) {
+          var data = element.data(NG_ANIMATE_STATE);
+          cancelled = cancelled ||
+                        !data || !data.active[className] ||
+                        (runner.isClassBased && data.active[className].event != animationEvent);
+
+          fireDOMOperation();
+          if(cancelled === true) {
+            closeAnimation();
+          } else {
+            fireAfterCallbackAsync();
+            runner.after(closeAnimation);
+          }
+        });
+
+        function fireDOMCallback(animationPhase) {
+          var eventName = '$animate:' + animationPhase;
+          if(elementEvents && elementEvents[eventName] && elementEvents[eventName].length > 0) {
+            $$asyncCallback(function() {
+              element.triggerHandler(eventName, {
+                event : animationEvent,
+                className : className
+              });
+            });
+          }
+        }
+
+        function fireBeforeCallbackAsync() {
+          fireDOMCallback('before');
+        }
+
+        function fireAfterCallbackAsync() {
+          fireDOMCallback('after');
+        }
+
+        function fireDoneCallbackAsync() {
+          fireDOMCallback('close');
+          if(doneCallback) {
+            $$asyncCallback(function() {
+              doneCallback();
+            });
+          }
+        }
+
+        //it is less complicated to use a flag than managing and canceling
+        //timeouts containing multiple callbacks.
+        function fireDOMOperation() {
+          if(!fireDOMOperation.hasBeenRun) {
+            fireDOMOperation.hasBeenRun = true;
+            domOperation();
+          }
+        }
+
+        function closeAnimation() {
+          if(!closeAnimation.hasBeenRun) {
+            closeAnimation.hasBeenRun = true;
+            var data = element.data(NG_ANIMATE_STATE);
+            if(data) {
+              /* only structural animations wait for reflow before removing an
+                 animation, but class-based animations don't. An example of this
+                 failing would be when a parent HTML tag has a ng-class attribute
+                 causing ALL directives below to skip animations during the digest */
+              if(runner && runner.isClassBased) {
+                cleanup(element, className);
+              } else {
+                $$asyncCallback(function() {
+                  var data = element.data(NG_ANIMATE_STATE) || {};
+                  if(localAnimationCount == data.index) {
+                    cleanup(element, className, animationEvent);
+                  }
+                });
+                element.data(NG_ANIMATE_STATE, data);
+              }
+            }
+            fireDoneCallbackAsync();
+          }
+        }
+      }
+
+      function cancelChildAnimations(element) {
+        var node = extractElementNode(element);
+        if (node) {
+          var nodes = angular.isFunction(node.getElementsByClassName) ?
+            node.getElementsByClassName(NG_ANIMATE_CLASS_NAME) :
+            node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME);
+          forEach(nodes, function(element) {
+            element = angular.element(element);
+            var data = element.data(NG_ANIMATE_STATE);
+            if(data && data.active) {
+              forEach(data.active, function(runner) {
+                runner.cancel();
+              });
+            }
+          });
+        }
+      }
+
+      function cleanup(element, className) {
+        if(isMatchingElement(element, $rootElement)) {
+          if(!rootAnimateState.disabled) {
+            rootAnimateState.running = false;
+            rootAnimateState.structural = false;
+          }
+        } else if(className) {
+          var data = element.data(NG_ANIMATE_STATE) || {};
+
+          var removeAnimations = className === true;
+          if(!removeAnimations && data.active && data.active[className]) {
+            data.totalActive--;
+            delete data.active[className];
+          }
+
+          if(removeAnimations || !data.totalActive) {
+            element.removeClass(NG_ANIMATE_CLASS_NAME);
+            element.removeData(NG_ANIMATE_STATE);
+          }
+        }
+      }
+
+      function animationsDisabled(element, parentElement) {
+        if (rootAnimateState.disabled) return true;
+
+        if(isMatchingElement(element, $rootElement)) {
+          return rootAnimateState.disabled || rootAnimateState.running;
+        }
+
+        do {
+          //the element did not reach the root element which means that it
+          //is not apart of the DOM. Therefore there is no reason to do
+          //any animations on it
+          if(parentElement.length === 0) break;
+
+          var isRoot = isMatchingElement(parentElement, $rootElement);
+          var state = isRoot ? rootAnimateState : parentElement.data(NG_ANIMATE_STATE);
+          var result = state && (!!state.disabled || state.running || state.totalActive > 0);
+          if(isRoot || result) {
+            return result;
+          }
+
+          if(isRoot) return true;
+        }
+        while(parentElement = parentElement.parent());
+
+        return true;
+      }
+    }]);
+
+    $animateProvider.register('', ['$window', '$sniffer', '$timeout', '$$animateReflow',
+                           function($window,   $sniffer,   $timeout,   $$animateReflow) {
+      // Detect proper transitionend/animationend event names.
+      var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
+
+      // If unprefixed events are not supported but webkit-prefixed are, use the latter.
+      // Otherwise, just use W3C names, browsers not supporting them at all will just ignore them.
+      // Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend`
+      // but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`.
+      // Register both events in case `window.onanimationend` is not supported because of that,
+      // do the same for `transitionend` as Safari is likely to exhibit similar behavior.
+      // Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit
+      // therefore there is no reason to test anymore for other vendor prefixes: http://caniuse.com/#search=transition
+      if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
+        CSS_PREFIX = '-webkit-';
+        TRANSITION_PROP = 'WebkitTransition';
+        TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
+      } else {
+        TRANSITION_PROP = 'transition';
+        TRANSITIONEND_EVENT = 'transitionend';
+      }
+
+      if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
+        CSS_PREFIX = '-webkit-';
+        ANIMATION_PROP = 'WebkitAnimation';
+        ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
+      } else {
+        ANIMATION_PROP = 'animation';
+        ANIMATIONEND_EVENT = 'animationend';
+      }
+
+      var DURATION_KEY = 'Duration';
+      var PROPERTY_KEY = 'Property';
+      var DELAY_KEY = 'Delay';
+      var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
+      var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey';
+      var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data';
+      var NG_ANIMATE_BLOCK_CLASS_NAME = 'ng-animate-block-transitions';
+      var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
+      var CLOSING_TIME_BUFFER = 1.5;
+      var ONE_SECOND = 1000;
+
+      var lookupCache = {};
+      var parentCounter = 0;
+      var animationReflowQueue = [];
+      var cancelAnimationReflow;
+      function afterReflow(element, callback) {
+        if(cancelAnimationReflow) {
+          cancelAnimationReflow();
+        }
+        animationReflowQueue.push(callback);
+        cancelAnimationReflow = $$animateReflow(function() {
+          forEach(animationReflowQueue, function(fn) {
+            fn();
+          });
+
+          animationReflowQueue = [];
+          cancelAnimationReflow = null;
+          lookupCache = {};
+        });
+      }
+
+      var closingTimer = null;
+      var closingTimestamp = 0;
+      var animationElementQueue = [];
+      function animationCloseHandler(element, totalTime) {
+        var node = extractElementNode(element);
+        element = angular.element(node);
+
+        //this item will be garbage collected by the closing
+        //animation timeout
+        animationElementQueue.push(element);
+
+        //but it may not need to cancel out the existing timeout
+        //if the timestamp is less than the previous one
+        var futureTimestamp = Date.now() + totalTime;
+        if(futureTimestamp <= closingTimestamp) {
+          return;
+        }
+
+        $timeout.cancel(closingTimer);
+
+        closingTimestamp = futureTimestamp;
+        closingTimer = $timeout(function() {
+          closeAllAnimations(animationElementQueue);
+          animationElementQueue = [];
+        }, totalTime, false);
+      }
+
+      function closeAllAnimations(elements) {
+        forEach(elements, function(element) {
+          var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
+          if(elementData) {
+            (elementData.closeAnimationFn || noop)();
+          }
+        });
+      }
+
+      function getElementAnimationDetails(element, cacheKey) {
+        var data = cacheKey ? lookupCache[cacheKey] : null;
+        if(!data) {
+          var transitionDuration = 0;
+          var transitionDelay = 0;
+          var animationDuration = 0;
+          var animationDelay = 0;
+          var transitionDelayStyle;
+          var animationDelayStyle;
+          var transitionDurationStyle;
+          var transitionPropertyStyle;
+
+          //we want all the styles defined before and after
+          forEach(element, function(element) {
+            if (element.nodeType == ELEMENT_NODE) {
+              var elementStyles = $window.getComputedStyle(element) || {};
+
+              transitionDurationStyle = elementStyles[TRANSITION_PROP + DURATION_KEY];
+
+              transitionDuration = Math.max(parseMaxTime(transitionDurationStyle), transitionDuration);
+
+              transitionPropertyStyle = elementStyles[TRANSITION_PROP + PROPERTY_KEY];
+
+              transitionDelayStyle = elementStyles[TRANSITION_PROP + DELAY_KEY];
+
+              transitionDelay  = Math.max(parseMaxTime(transitionDelayStyle), transitionDelay);
+
+              animationDelayStyle = elementStyles[ANIMATION_PROP + DELAY_KEY];
+
+              animationDelay   = Math.max(parseMaxTime(animationDelayStyle), animationDelay);
+
+              var aDuration  = parseMaxTime(elementStyles[ANIMATION_PROP + DURATION_KEY]);
+
+              if(aDuration > 0) {
+                aDuration *= parseInt(elementStyles[ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY], 10) || 1;
+              }
+
+              animationDuration = Math.max(aDuration, animationDuration);
+            }
+          });
+          data = {
+            total : 0,
+            transitionPropertyStyle: transitionPropertyStyle,
+            transitionDurationStyle: transitionDurationStyle,
+            transitionDelayStyle: transitionDelayStyle,
+            transitionDelay: transitionDelay,
+            transitionDuration: transitionDuration,
+            animationDelayStyle: animationDelayStyle,
+            animationDelay: animationDelay,
+            animationDuration: animationDuration
+          };
+          if(cacheKey) {
+            lookupCache[cacheKey] = data;
+          }
+        }
+        return data;
+      }
+
+      function parseMaxTime(str) {
+        var maxValue = 0;
+        var values = angular.isString(str) ?
+          str.split(/\s*,\s*/) :
+          [];
+        forEach(values, function(value) {
+          maxValue = Math.max(parseFloat(value) || 0, maxValue);
+        });
+        return maxValue;
+      }
+
+      function getCacheKey(element) {
+        var parentElement = element.parent();
+        var parentID = parentElement.data(NG_ANIMATE_PARENT_KEY);
+        if(!parentID) {
+          parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter);
+          parentID = parentCounter;
+        }
+        return parentID + '-' + extractElementNode(element).getAttribute('class');
+      }
+
+      function animateSetup(animationEvent, element, className, calculationDecorator) {
+        var cacheKey = getCacheKey(element);
+        var eventCacheKey = cacheKey + ' ' + className;
+        var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
+
+        var stagger = {};
+        if(itemIndex > 0) {
+          var staggerClassName = className + '-stagger';
+          var staggerCacheKey = cacheKey + ' ' + staggerClassName;
+          var applyClasses = !lookupCache[staggerCacheKey];
+
+          applyClasses && element.addClass(staggerClassName);
+
+          stagger = getElementAnimationDetails(element, staggerCacheKey);
+
+          applyClasses && element.removeClass(staggerClassName);
+        }
+
+        /* the animation itself may need to add/remove special CSS classes
+         * before calculating the anmation styles */
+        calculationDecorator = calculationDecorator ||
+                               function(fn) { return fn(); };
+
+        element.addClass(className);
+
+        var formerData = element.data(NG_ANIMATE_CSS_DATA_KEY) || {};
+
+        var timings = calculationDecorator(function() {
+          return getElementAnimationDetails(element, eventCacheKey);
+        });
+
+        var transitionDuration = timings.transitionDuration;
+        var animationDuration = timings.animationDuration;
+        if(transitionDuration === 0 && animationDuration === 0) {
+          element.removeClass(className);
+          return false;
+        }
+
+        element.data(NG_ANIMATE_CSS_DATA_KEY, {
+          running : formerData.running || 0,
+          itemIndex : itemIndex,
+          stagger : stagger,
+          timings : timings,
+          closeAnimationFn : noop
+        });
+
+        //temporarily disable the transition so that the enter styles
+        //don't animate twice (this is here to avoid a bug in Chrome/FF).
+        var isCurrentlyAnimating = formerData.running > 0 || animationEvent == 'setClass';
+        if(transitionDuration > 0) {
+          blockTransitions(element, className, isCurrentlyAnimating);
+        }
+
+        //staggering keyframe animations work by adjusting the `animation-delay` CSS property
+        //on the given element, however, the delay value can only calculated after the reflow
+        //since by that time $animate knows how many elements are being animated. Therefore,
+        //until the reflow occurs the element needs to be blocked (where the keyframe animation
+        //is set to `none 0s`). This blocking mechanism should only be set for when a stagger
+        //animation is detected and when the element item index is greater than 0.
+        if(animationDuration > 0 && stagger.animationDelay > 0 && stagger.animationDuration === 0) {
+          blockKeyframeAnimations(element);
+        }
+
+        return true;
+      }
+
+      function isStructuralAnimation(className) {
+        return className == 'ng-enter' || className == 'ng-move' || className == 'ng-leave';
+      }
+
+      function blockTransitions(element, className, isAnimating) {
+        if(isStructuralAnimation(className) || !isAnimating) {
+          extractElementNode(element).style[TRANSITION_PROP + PROPERTY_KEY] = 'none';
+        } else {
+          element.addClass(NG_ANIMATE_BLOCK_CLASS_NAME);
+        }
+      }
+
+      function blockKeyframeAnimations(element) {
+        extractElementNode(element).style[ANIMATION_PROP] = 'none 0s';
+      }
+
+      function unblockTransitions(element, className) {
+        var prop = TRANSITION_PROP + PROPERTY_KEY;
+        var node = extractElementNode(element);
+        if(node.style[prop] && node.style[prop].length > 0) {
+          node.style[prop] = '';
+        }
+        element.removeClass(NG_ANIMATE_BLOCK_CLASS_NAME);
+      }
+
+      function unblockKeyframeAnimations(element) {
+        var prop = ANIMATION_PROP;
+        var node = extractElementNode(element);
+        if(node.style[prop] && node.style[prop].length > 0) {
+          node.style[prop] = '';
+        }
+      }
+
+      function animateRun(animationEvent, element, className, activeAnimationComplete) {
+        var node = extractElementNode(element);
+        var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
+        if(node.getAttribute('class').indexOf(className) == -1 || !elementData) {
+          activeAnimationComplete();
+          return;
+        }
+
+        var activeClassName = '';
+        forEach(className.split(' '), function(klass, i) {
+          activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
+        });
+
+        var stagger = elementData.stagger;
+        var timings = elementData.timings;
+        var itemIndex = elementData.itemIndex;
+        var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
+        var maxDelay = Math.max(timings.transitionDelay, timings.animationDelay);
+        var maxDelayTime = maxDelay * ONE_SECOND;
+
+        var startTime = Date.now();
+        var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
+
+        var style = '', appliedStyles = [];
+        if(timings.transitionDuration > 0) {
+          var propertyStyle = timings.transitionPropertyStyle;
+          if(propertyStyle.indexOf('all') == -1) {
+            style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';';
+            style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ';';
+            appliedStyles.push(CSS_PREFIX + 'transition-property');
+            appliedStyles.push(CSS_PREFIX + 'transition-duration');
+          }
+        }
+
+        if(itemIndex > 0) {
+          if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
+            var delayStyle = timings.transitionDelayStyle;
+            style += CSS_PREFIX + 'transition-delay: ' +
+                     prepareStaggerDelay(delayStyle, stagger.transitionDelay, itemIndex) + '; ';
+            appliedStyles.push(CSS_PREFIX + 'transition-delay');
+          }
+
+          if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
+            style += CSS_PREFIX + 'animation-delay: ' +
+                     prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, itemIndex) + '; ';
+            appliedStyles.push(CSS_PREFIX + 'animation-delay');
+          }
+        }
+
+        if(appliedStyles.length > 0) {
+          //the element being animated may sometimes contain comment nodes in
+          //the jqLite object, so we're safe to use a single variable to house
+          //the styles since there is always only one element being animated
+          var oldStyle = node.getAttribute('style') || '';
+          node.setAttribute('style', oldStyle + ' ' + style);
+        }
+
+        element.on(css3AnimationEvents, onAnimationProgress);
+        element.addClass(activeClassName);
+        elementData.closeAnimationFn = function() {
+          onEnd();
+          activeAnimationComplete();
+        };
+
+        var staggerTime       = itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);
+        var animationTime     = (maxDelay + maxDuration) * CLOSING_TIME_BUFFER;
+        var totalTime         = (staggerTime + animationTime) * ONE_SECOND;
+
+        elementData.running++;
+        animationCloseHandler(element, totalTime);
+        return onEnd;
+
+        // This will automatically be called by $animate so
+        // there is no need to attach this internally to the
+        // timeout done method.
+        function onEnd(cancelled) {
+          element.off(css3AnimationEvents, onAnimationProgress);
+          element.removeClass(activeClassName);
+          animateClose(element, className);
+          var node = extractElementNode(element);
+          for (var i in appliedStyles) {
+            node.style.removeProperty(appliedStyles[i]);
+          }
+        }
+
+        function onAnimationProgress(event) {
+          event.stopPropagation();
+          var ev = event.originalEvent || event;
+          var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now();
+
+          /* Firefox (or possibly just Gecko) likes to not round values up
+           * when a ms measurement is used for the animation */
+          var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));
+
+          /* $manualTimeStamp is a mocked timeStamp value which is set
+           * within browserTrigger(). This is only here so that tests can
+           * mock animations properly. Real events fallback to event.timeStamp,
+           * or, if they don't, then a timeStamp is automatically created for them.
+           * We're checking to see if the timeStamp surpasses the expected delay,
+           * but we're using elapsedTime instead of the timeStamp on the 2nd
+           * pre-condition since animations sometimes close off early */
+          if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
+            activeAnimationComplete();
+          }
+        }
+      }
+
+      function prepareStaggerDelay(delayStyle, staggerDelay, index) {
+        var style = '';
+        forEach(delayStyle.split(','), function(val, i) {
+          style += (i > 0 ? ',' : '') +
+                   (index * staggerDelay + parseInt(val, 10)) + 's';
+        });
+        return style;
+      }
+
+      function animateBefore(animationEvent, element, className, calculationDecorator) {
+        if(animateSetup(animationEvent, element, className, calculationDecorator)) {
+          return function(cancelled) {
+            cancelled && animateClose(element, className);
+          };
+        }
+      }
+
+      function animateAfter(animationEvent, element, className, afterAnimationComplete) {
+        if(element.data(NG_ANIMATE_CSS_DATA_KEY)) {
+          return animateRun(animationEvent, element, className, afterAnimationComplete);
+        } else {
+          animateClose(element, className);
+          afterAnimationComplete();
+        }
+      }
+
+      function animate(animationEvent, element, className, animationComplete) {
+        //If the animateSetup function doesn't bother returning a
+        //cancellation function then it means that there is no animation
+        //to perform at all
+        var preReflowCancellation = animateBefore(animationEvent, element, className);
+        if(!preReflowCancellation) {
+          animationComplete();
+          return;
+        }
+
+        //There are two cancellation functions: one is before the first
+        //reflow animation and the second is during the active state
+        //animation. The first function will take care of removing the
+        //data from the element which will not make the 2nd animation
+        //happen in the first place
+        var cancel = preReflowCancellation;
+        afterReflow(element, function() {
+          unblockTransitions(element, className);
+          unblockKeyframeAnimations(element);
+          //once the reflow is complete then we point cancel to
+          //the new cancellation function which will remove all of the
+          //animation properties from the active animation
+          cancel = animateAfter(animationEvent, element, className, animationComplete);
+        });
+
+        return function(cancelled) {
+          (cancel || noop)(cancelled);
+        };
+      }
+
+      function animateClose(element, className) {
+        element.removeClass(className);
+        var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
+        if(data) {
+          if(data.running) {
+            data.running--;
+          }
+          if(!data.running || data.running === 0) {
+            element.removeData(NG_ANIMATE_CSS_DATA_KEY);
+          }
+        }
+      }
+
+      return {
+        enter : function(element, animationCompleted) {
+          return animate('enter', element, 'ng-enter', animationCompleted);
+        },
+
+        leave : function(element, animationCompleted) {
+          return animate('leave', element, 'ng-leave', animationCompleted);
+        },
+
+        move : function(element, animationCompleted) {
+          return animate('move', element, 'ng-move', animationCompleted);
+        },
+
+        beforeSetClass : function(element, add, remove, animationCompleted) {
+          var className = suffixClasses(remove, '-remove') + ' ' +
+                          suffixClasses(add, '-add');
+          var cancellationMethod = animateBefore('setClass', element, className, function(fn) {
+            /* when classes are removed from an element then the transition style
+             * that is applied is the transition defined on the element without the
+             * CSS class being there. This is how CSS3 functions outside of ngAnimate.
+             * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
+            var klass = element.attr('class');
+            element.removeClass(remove);
+            element.addClass(add);
+            var timings = fn();
+            element.attr('class', klass);
+            return timings;
+          });
+
+          if(cancellationMethod) {
+            afterReflow(element, function() {
+              unblockTransitions(element, className);
+              unblockKeyframeAnimations(element);
+              animationCompleted();
+            });
+            return cancellationMethod;
+          }
+          animationCompleted();
+        },
+
+        beforeAddClass : function(element, className, animationCompleted) {
+          var cancellationMethod = animateBefore('addClass', element, suffixClasses(className, '-add'), function(fn) {
+
+            /* when a CSS class is added to an element then the transition style that
+             * is applied is the transition defined on the element when the CSS class
+             * is added at the time of the animation. This is how CSS3 functions
+             * outside of ngAnimate. */
+            element.addClass(className);
+            var timings = fn();
+            element.removeClass(className);
+            return timings;
+          });
+
+          if(cancellationMethod) {
+            afterReflow(element, function() {
+              unblockTransitions(element, className);
+              unblockKeyframeAnimations(element);
+              animationCompleted();
+            });
+            return cancellationMethod;
+          }
+          animationCompleted();
+        },
+
+        setClass : function(element, add, remove, animationCompleted) {
+          remove = suffixClasses(remove, '-remove');
+          add = suffixClasses(add, '-add');
+          var className = remove + ' ' + add;
+          return animateAfter('setClass', element, className, animationCompleted);
+        },
+
+        addClass : function(element, className, animationCompleted) {
+          return animateAfter('addClass', element, suffixClasses(className, '-add'), animationCompleted);
+        },
+
+        beforeRemoveClass : function(element, className, animationCompleted) {
+          var cancellationMethod = animateBefore('removeClass', element, suffixClasses(className, '-remove'), function(fn) {
+            /* when classes are removed from an element then the transition style
+             * that is applied is the transition defined on the element without the
+             * CSS class being there. This is how CSS3 functions outside of ngAnimate.
+             * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
+            var klass = element.attr('class');
+            element.removeClass(className);
+            var timings = fn();
+            element.attr('class', klass);
+            return timings;
+          });
+
+          if(cancellationMethod) {
+            afterReflow(element, function() {
+              unblockTransitions(element, className);
+              unblockKeyframeAnimations(element);
+              animationCompleted();
+            });
+            return cancellationMethod;
+          }
+          animationCompleted();
+        },
+
+        removeClass : function(element, className, animationCompleted) {
+          return animateAfter('removeClass', element, suffixClasses(className, '-remove'), animationCompleted);
+        }
+      };
+
+      function suffixClasses(classes, suffix) {
+        var className = '';
+        classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
+        forEach(classes, function(klass, i) {
+          if(klass && klass.length > 0) {
+            className += (i > 0 ? ' ' : '') + klass + suffix;
+          }
+        });
+        return className;
+      }
+    }]);
+  }]);
+
+
+})(window, window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-cookies.js b/src/main/resources/META-INF/resources/designer/lib/angular-cookies.js
new file mode 100644 (file)
index 0000000..7aa5d34
--- /dev/null
@@ -0,0 +1,206 @@
+/**
+ * @license AngularJS v1.3.6-build.3675+sha.facfec9
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngCookies
+ * @description
+ *
+ * # ngCookies
+ *
+ * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
+ *
+ *
+ * <div doc-module-components="ngCookies"></div>
+ *
+ * See {@link ngCookies.$cookies `$cookies`} and
+ * {@link ngCookies.$cookieStore `$cookieStore`} for usage.
+ */
+
+
+angular.module('ngCookies', ['ng']).
+  /**
+   * @ngdoc service
+   * @name $cookies
+   *
+   * @description
+   * Provides read/write access to browser's cookies.
+   *
+   * Only a simple Object is exposed and by adding or removing properties to/from this object, new
+   * cookies are created/deleted at the end of current $eval.
+   * The object's properties can only be strings.
+   *
+   * Requires the {@link ngCookies `ngCookies`} module to be installed.
+   *
+   * @example
+   *
+   * ```js
+   * angular.module('cookiesExample', ['ngCookies'])
+   *   .controller('ExampleController', ['$cookies', function($cookies) {
+   *     // Retrieving a cookie
+   *     var favoriteCookie = $cookies.myFavorite;
+   *     // Setting a cookie
+   *     $cookies.myFavorite = 'oatmeal';
+   *   }]);
+   * ```
+   */
+   factory('$cookies', ['$rootScope', '$browser', function($rootScope, $browser) {
+      var cookies = {},
+          lastCookies = {},
+          lastBrowserCookies,
+          runEval = false,
+          copy = angular.copy,
+          isUndefined = angular.isUndefined;
+
+      //creates a poller fn that copies all cookies from the $browser to service & inits the service
+      $browser.addPollFn(function() {
+        var currentCookies = $browser.cookies();
+        if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
+          lastBrowserCookies = currentCookies;
+          copy(currentCookies, lastCookies);
+          copy(currentCookies, cookies);
+          if (runEval) $rootScope.$apply();
+        }
+      })();
+
+      runEval = true;
+
+      //at the end of each eval, push cookies
+      //TODO: this should happen before the "delayed" watches fire, because if some cookies are not
+      //      strings or browser refuses to store some cookies, we update the model in the push fn.
+      $rootScope.$watch(push);
+
+      return cookies;
+
+
+      /**
+       * Pushes all the cookies from the service to the browser and verifies if all cookies were
+       * stored.
+       */
+      function push() {
+        var name,
+            value,
+            browserCookies,
+            updated;
+
+        //delete any cookies deleted in $cookies
+        for (name in lastCookies) {
+          if (isUndefined(cookies[name])) {
+            $browser.cookies(name, undefined);
+          }
+        }
+
+        //update all cookies updated in $cookies
+        for (name in cookies) {
+          value = cookies[name];
+          if (!angular.isString(value)) {
+            value = '' + value;
+            cookies[name] = value;
+          }
+          if (value !== lastCookies[name]) {
+            $browser.cookies(name, value);
+            updated = true;
+          }
+        }
+
+        //verify what was actually stored
+        if (updated) {
+          updated = false;
+          browserCookies = $browser.cookies();
+
+          for (name in cookies) {
+            if (cookies[name] !== browserCookies[name]) {
+              //delete or reset all cookies that the browser dropped from $cookies
+              if (isUndefined(browserCookies[name])) {
+                delete cookies[name];
+              } else {
+                cookies[name] = browserCookies[name];
+              }
+              updated = true;
+            }
+          }
+        }
+      }
+    }]).
+
+
+  /**
+   * @ngdoc service
+   * @name $cookieStore
+   * @requires $cookies
+   *
+   * @description
+   * Provides a key-value (string-object) storage, that is backed by session cookies.
+   * Objects put or retrieved from this storage are automatically serialized or
+   * deserialized by angular's toJson/fromJson.
+   *
+   * Requires the {@link ngCookies `ngCookies`} module to be installed.
+   *
+   * @example
+   *
+   * ```js
+   * angular.module('cookieStoreExample', ['ngCookies'])
+   *   .controller('ExampleController', ['$cookieStore', function($cookieStore) {
+   *     // Put cookie
+   *     $cookieStore.put('myFavorite','oatmeal');
+   *     // Get cookie
+   *     var favoriteCookie = $cookieStore.get('myFavorite');
+   *     // Removing a cookie
+   *     $cookieStore.remove('myFavorite');
+   *   }]);
+   * ```
+   */
+   factory('$cookieStore', ['$cookies', function($cookies) {
+
+      return {
+        /**
+         * @ngdoc method
+         * @name $cookieStore#get
+         *
+         * @description
+         * Returns the value of given cookie key
+         *
+         * @param {string} key Id to use for lookup.
+         * @returns {Object} Deserialized cookie value.
+         */
+        get: function(key) {
+          var value = $cookies[key];
+          return value ? angular.fromJson(value) : value;
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookieStore#put
+         *
+         * @description
+         * Sets a value for given cookie key
+         *
+         * @param {string} key Id for the `value`.
+         * @param {Object} value Value to be stored.
+         */
+        put: function(key, value) {
+          $cookies[key] = angular.toJson(value);
+        },
+
+        /**
+         * @ngdoc method
+         * @name $cookieStore#remove
+         *
+         * @description
+         * Remove given cookie
+         *
+         * @param {string} key Id of the key-value pair to delete.
+         */
+        remove: function(key) {
+          delete $cookies[key];
+        }
+      };
+
+    }]);
+
+
+})(window, window.angular);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-highlightjs.js b/src/main/resources/META-INF/resources/designer/lib/angular-highlightjs.js
new file mode 100644 (file)
index 0000000..1ded24b
--- /dev/null
@@ -0,0 +1,380 @@
+/*! angular-highlightjs
+version: 0.4.1
+build date: 2015-02-03
+author: Chih-Hsuan Fan
+https://github.com/pc035860/angular-highlightjs.git */
+
+/* commonjs package manager support (eg componentjs) */
+if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){
+  module.exports = 'hljs';
+}
+
+(function (window, angular, undefined) {
+/*global angular*/
+
+function shouldHighlightStatics(attrs) {
+  var should = true;
+  angular.forEach([
+    'source', 'include'
+  ], function (name) {
+    if (attrs[name]) {
+      should = false;
+    }
+  });
+  return should;
+}
+
+
+var ngModule = angular.module('hljs', []);
+
+/**
+ * hljsService service
+ */
+ngModule.provider('hljsService', function () {
+  var _hljsOptions = {};
+
+  return {
+    setOptions: function (options) {
+      angular.extend(_hljsOptions, options);
+    },
+    getOptions: function () {
+      return angular.copy(_hljsOptions);
+    },
+    $get: ['$window', function ($window) {
+      ($window.hljs.configure || angular.noop)(_hljsOptions);
+      return $window.hljs;
+    }]
+  };
+});
+
+/**
+ * hljsCache service
+ */
+ngModule.factory('hljsCache', [
+         '$cacheFactory',
+function ($cacheFactory) {
+  return $cacheFactory('hljsCache');
+}]);
+
+/**
+ * HljsCtrl controller
+ */
+ngModule.controller('HljsCtrl', [
+                  'hljsCache', 'hljsService',
+function HljsCtrl (hljsCache,   hljsService) {
+  var ctrl = this;
+
+  var _elm = null,
+      _lang = null,
+      _code = null,
+      _hlCb = null;
+
+  ctrl.init = function (codeElm) {
+    _elm = codeElm;
+  };
+
+  ctrl.setLanguage = function (lang) {
+    _lang = lang;
+
+    if (_code) {
+      ctrl.highlight(_code);
+    }
+  };
+
+  ctrl.highlightCallback = function (cb) {
+    _hlCb = cb;
+  };
+
+  ctrl.highlight = function (code) {
+    if (!_elm) {
+      return;
+    }
+
+    var res, cacheKey;
+
+    _code = code;
+
+    if (_lang) {
+      // language specified
+      cacheKey = ctrl._cacheKey(_lang, _code);
+      res = hljsCache.get(cacheKey);
+
+      if (!res) {
+        res = hljsService.highlight(_lang, hljsService.fixMarkup(_code), true);
+        hljsCache.put(cacheKey, res);
+      }
+    }
+    else {
+      // language auto-detect
+      cacheKey = ctrl._cacheKey(_code);
+      res = hljsCache.get(cacheKey);
+
+      if (!res) {
+        res = hljsService.highlightAuto(hljsService.fixMarkup(_code));
+        hljsCache.put(cacheKey, res);
+      }
+    }
+
+    _elm.html(res.value);
+    // language as class on the <code> tag
+    _elm.addClass(res.language);
+
+    if (_hlCb !== null && angular.isFunction(_hlCb)) {
+      _hlCb();
+    }
+  };
+
+  ctrl.clear = function () {
+    if (!_elm) {
+      return;
+    }
+    _code = null;
+    _elm.text('');
+  };
+
+  ctrl.release = function () {
+    _elm = null;
+  };
+
+  ctrl._cacheKey = function () {
+    var args = Array.prototype.slice.call(arguments),
+        glue = "!angular-highlightjs!";
+    return args.join(glue);
+  };
+}]);
+
+
+var hljsDir, languageDirFactory, sourceDirFactory, includeDirFactory;
+
+/**
+ * hljs directive
+ */
+hljsDir = ['$compile', '$parse', function ($compile, $parse) {
+  return {
+    restrict: 'EA',
+    controller: 'HljsCtrl',
+    compile: function(tElm, tAttrs, transclude) {
+      // get static code
+      // strip the starting "new line" character
+      var staticHTML = tElm[0].innerHTML.replace(/^(\r\n|\r|\n)/m, ''),
+          staticText = tElm[0].textContent.replace(/^(\r\n|\r|\n)/m, '');
+
+      // put template
+      tElm.html('<pre><code class="hljs"></code></pre>');
+
+      return function postLink(scope, iElm, iAttrs, ctrl) {
+        var compileCheck, escapeCheck;
+
+        if (angular.isDefined(iAttrs.compile)) {
+          compileCheck = $parse(iAttrs.compile);
+        }
+
+        if (angular.isDefined(iAttrs.escape)) {
+          escapeCheck = $parse(iAttrs.escape);
+        } else if (angular.isDefined(iAttrs.noEscape)) {
+          escapeCheck = $parse('false');
+        }
+
+        ctrl.init(iElm.find('code'));
+
+        if (iAttrs.onhighlight) {
+          ctrl.highlightCallback(function () {
+            scope.$eval(iAttrs.onhighlight);
+          });
+        }
+
+        if ((staticHTML || staticText) && shouldHighlightStatics(iAttrs)) {
+
+          var code;
+
+          // Auto-escape check
+          // default to "true"
+          if (escapeCheck && !escapeCheck(scope)) {
+            code = staticText;
+          }
+          else {
+            code = staticHTML;
+          }
+
+          ctrl.highlight(code);
+
+          // Check if the highlight result needs to be compiled
+          if (compileCheck && compileCheck(scope)) {
+            // compile the new DOM and link it to the current scope.
+            // NOTE: we only compile .childNodes so that
+            // we don't get into infinite loop compiling ourselves
+            $compile(iElm.find('code').contents())(scope);
+          }
+        }
+
+        scope.$on('$destroy', function () {
+          ctrl.release();
+        });
+      };
+    }
+  };
+}];
+
+/**
+ * language directive
+ */
+languageDirFactory = function (dirName) {
+  return [function () {
+    return {
+      require: '?hljs',
+      restrict: 'A',
+      link: function (scope, iElm, iAttrs, ctrl) {
+        if (!ctrl) {
+          return;
+        }      
+        iAttrs.$observe(dirName, function (lang) {
+          if (angular.isDefined(lang)) {
+            ctrl.setLanguage(lang);
+          }
+        });
+      }
+    };
+  }];
+};
+
+/**
+ * source directive
+ */
+sourceDirFactory = function (dirName) {
+  return ['$compile', '$parse', function ($compile, $parse) {
+    return {
+      require: '?hljs',
+      restrict: 'A',
+      link: function(scope, iElm, iAttrs, ctrl) {
+        var compileCheck;
+
+        if (!ctrl) {
+          return;
+        }
+
+        if (angular.isDefined(iAttrs.compile)) {
+          compileCheck = $parse(iAttrs.compile);
+        }
+
+        scope.$watch(iAttrs[dirName], function (newCode, oldCode) {
+          if (newCode) {
+            ctrl.highlight(newCode);
+
+            // Check if the highlight result needs to be compiled
+            if (compileCheck && compileCheck(scope)) {
+              // compile the new DOM and link it to the current scope.
+              // NOTE: we only compile .childNodes so that
+              // we don't get into infinite loop compiling ourselves
+              $compile(iElm.find('code').contents())(scope);
+            }
+          }
+          else {
+            ctrl.clear();
+          }
+        });
+      }
+    };
+  }];
+};
+
+/**
+ * include directive
+ */
+includeDirFactory = function (dirName) {
+  return [
+             '$http', '$templateCache', '$q', '$compile', '$parse',
+    function ($http,   $templateCache,   $q,   $compile,   $parse) {
+      return {
+        require: '?hljs',
+        restrict: 'A',
+        compile: function(tElm, tAttrs, transclude) {
+          var srcExpr = tAttrs[dirName];
+
+          return function postLink(scope, iElm, iAttrs, ctrl) {
+            var changeCounter = 0, compileCheck;
+
+            if (!ctrl) {
+              return;
+            }
+
+            if (angular.isDefined(iAttrs.compile)) {
+              compileCheck = $parse(iAttrs.compile);
+            }
+
+            scope.$watch(srcExpr, function (src) {
+              var thisChangeId = ++changeCounter;
+
+              if (src && angular.isString(src)) {
+                var templateCachePromise, dfd;
+
+                templateCachePromise = $templateCache.get(src);
+                if (!templateCachePromise) {
+                  dfd = $q.defer();
+                  $http.get(src, {
+                    cache: $templateCache,
+                    transformResponse: function(data, headersGetter) {
+                      // Return the raw string, so $http doesn't parse it
+                      // if it's json.
+                      return data;
+                    }
+                  }).success(function (code) {
+                    if (thisChangeId !== changeCounter) {
+                      return;
+                    }
+                    dfd.resolve(code);
+                  }).error(function() {
+                    if (thisChangeId === changeCounter) {
+                      ctrl.clear();
+                    }
+                    dfd.resolve();
+                  });
+                  templateCachePromise = dfd.promise;
+                }
+
+                $q.when(templateCachePromise)
+                .then(function (code) {
+                  if (!code) {
+                    return;
+                  }
+
+                  // $templateCache from $http
+                  if (angular.isArray(code)) {
+                    // 1.1.5
+                    code = code[1];
+                  }
+                  else if (angular.isObject(code)) {
+                    // 1.0.7
+                    code = code.data;
+                  }
+
+                  code = code.replace(/^(\r\n|\r|\n)/m, '');
+                  ctrl.highlight(code);
+
+                  // Check if the highlight result needs to be compiled
+                  if (compileCheck && compileCheck(scope)) {
+                    // compile the new DOM and link it to the current scope.
+                    // NOTE: we only compile .childNodes so that
+                    // we don't get into infinite loop compiling ourselves
+                    $compile(iElm.find('code').contents())(scope);
+                  }
+                });
+              }
+              else {
+                ctrl.clear();
+              }
+            });
+          };
+        }
+      };
+  }];
+};
+
+/**
+ * Add directives
+ */
+ngModule
+.directive('hljs', hljsDir)
+.directive('language', languageDirFactory('language'))
+.directive('source', sourceDirFactory('source'))
+.directive('include', includeDirFactory('include'));
+})(window, window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js b/src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js
new file mode 100644 (file)
index 0000000..36ec2ec
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ AngularJS v1.2.26
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
+b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f<c&&k!==A;f++){var g=a[f];k=null!==k?k[g]:A}}else k=b;e[d]=k});return e}function e(a){return a.resource}function f(a){D(a||{},this)}var F=new c(n);l=x({},B,l);s(l,function(h,d){var c=/^(POST|PUT|PATCH)$/i.test(h.method);f[d]=function(b,d,k,w){var q={},n,l,y;switch(arguments.length){case 4:y=w,l=k;case 3:case 2:if(u(d)){if(u(b)){l=
+b;y=d;break}l=d;y=k}else{q=b;n=d;l=k;break}case 1:u(b)?l=b:c?n=b:q=b;break;case 0:break;default:throw v("badargs",arguments.length);}var t=this instanceof f,m=t?n:h.isArray?[]:new f(n),z={},B=h.interceptor&&h.interceptor.response||e,C=h.interceptor&&h.interceptor.responseError||A;s(h,function(a,b){"params"!=b&&("isArray"!=b&&"interceptor"!=b)&&(z[b]=G(a))});c&&(z.data=n);F.setUrlParams(z,x({},r(n,h.params||{}),q),h.url);q=p(z).then(function(b){var d=b.data,k=m.$promise;if(d){if(a.isArray(d)!==!!h.isArray)throw v("badcfg",
+h.isArray?"array":"object",a.isArray(d)?"array":"object");h.isArray?(m.length=0,s(d,function(b){"object"===typeof b?m.push(new f(b)):m.push(b)})):(D(d,m),m.$promise=k)}m.$resolved=!0;b.resource=m;return b},function(b){m.$resolved=!0;(y||E)(b);return g.reject(b)});q=q.then(function(b){var a=B(b);(l||E)(a,b.headers);return a},C);return t?q:(m.$promise=q,m.$resolved=!1,m)};f.prototype["$"+d]=function(b,a,k){u(b)&&(k=a,a=b,b={});b=f[d].call(this,b,this,a,k);return b.$promise||b}});f.bind=function(a){return t(n,
+x({},w,a),l)};return f}var B={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},E=a.noop,s=a.forEach,x=a.extend,G=a.copy,u=a.isFunction;c.prototype={setUrlParams:function(c,g,l){var r=this,e=l||r.template,f,p,h=r.urlParams={};s(e.split(/\W/),function(a){if("hasOwnProperty"===a)throw v("badname");!/^\d+$/.test(a)&&(a&&RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(e))&&(h[a]=!0)});e=e.replace(/\\:/g,":");g=g||{};s(r.urlParams,function(d,
+c){f=g.hasOwnProperty(c)?g[c]:r.defaults[c];a.isDefined(f)&&null!==f?(p=encodeURIComponent(f).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),e=e.replace(RegExp(":"+c+"(\\W|$)","g"),function(a,c){return p+c})):e=e.replace(RegExp("(/?):"+c+"(\\W|$)","g"),function(a,c,d){return"/"==d.charAt(0)?d:c+d})});e=e.replace(/\/+$/,"")||"/";e=e.replace(/\/\.(?=\w+($|\?))/,".");c.url=e.replace(/\/\\\./,
+"/.");s(g,function(a,e){r.urlParams[e]||(c.params=c.params||{},c.params[e]=a)})}};return t}])})(window,window.angular);
+//# sourceMappingURL=angular-resource.min.js.map
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js.map b/src/main/resources/META-INF/resources/designer/lib/angular-resource.min.js.map
new file mode 100644 (file)
index 0000000..7ae259d
--- /dev/null
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular-resource.min.js",
+"lineCount":12,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CA6BtCC,QAASA,EAAmB,CAACC,CAAD,CAAMC,CAAN,CAAW,CACrCA,CAAA,CAAMA,CAAN,EAAa,EAEbJ,EAAAK,QAAA,CAAgBD,CAAhB,CAAqB,QAAQ,CAACE,CAAD,CAAQC,CAAR,CAAY,CACvC,OAAOH,CAAA,CAAIG,CAAJ,CADgC,CAAzC,CAIA,KAAKA,IAAIA,CAAT,GAAgBJ,EAAhB,CACM,CAAAA,CAAAK,eAAA,CAAmBD,CAAnB,CAAJ,EAAmD,GAAnD,GAAiCA,CAAAE,OAAA,CAAW,CAAX,CAAjC,EAA4E,GAA5E,GAA0DF,CAAAE,OAAA,CAAW,CAAX,CAA1D,GACEL,CAAA,CAAIG,CAAJ,CADF,CACaJ,CAAA,CAAII,CAAJ,CADb,CAKF,OAAOH,EAb8B,CA3BvC,IAAIM,EAAkBV,CAAAW,SAAA,CAAiB,WAAjB,CAAtB,CAKIC,EAAoB,iCA+TxBZ,EAAAa,OAAA,CAAe,YAAf,CAA6B,CAAC,IAAD,CAA7B,CAAAC,QAAA,CACU,WADV,CACuB,CAAC,OAAD,CAAU,IAAV,CAAgB,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAY,CAsDvDC,QAASA,EAAK,CAACC,CAAD,CAAWC,CAAX,CAAqB,CACjC,IAAAD,SAAA,CAAgBA,CAChB,KAAAC,SAAA,CAAgBA,CAAhB,EAA4B,EAC5B,KAAAC,UAAA,CAAiB,EAHgB,CAiEnCC,QAASA,EAAe,CAACC,CAAD,CAAMC,CAAN,CAAqBC,CAArB,CAA8B,CAKpDC,QAASA,EAAa,CAACC,CAAD,CAAOC,CAAP,CAAoB,CACxC,IAAIC,EAAM,EACVD,EAAA,CAAeE,CAAA,CAAO,EAAP,CAAWN,CAAX,CAA0BI,CAA1B,CACftB,EAAA,CAAQsB,CAAR,CAAsB,QAAQ,CAACrB,CAAD,CAAQC,CAAR,CAAY,CACpCuB,CAAA,CAAWxB,CAAX,CAAJ,GAAyBA,CAAzB,CAAiCA,CAAA,EAAjC,CACW,KAAA,CAAA,IAAAA,CAAA;AAASA,CAAAG,OAAT,EAA4C,GAA5C,EAAyBH,CAAAG,OAAA,CAAa,CAAb,CAAzB,CAAA,CACT,CAAA,CAAA,CAAA,KAAA,EAAA,CAAA,OAAA,CAAA,CAAA,CA1bV,IALgB,IAKhB,EAAuBsB,CAAvB,EALiC,EAKjC,GAAuBA,CAAvB,EALgD,gBAKhD,GAAuBA,CAAvB,EAJI,CAAAnB,CAAAoB,KAAA,CAAuB,GAAvB,CAImBD,CAJnB,CAIJ,CACE,KAAMrB,EAAA,CAAgB,WAAhB,CAAsEqB,CAAtE,CAAN,CAGF,IADIE,IAAAA,EAAOF,CAAAG,MAAA,CAAW,GAAX,CAAPD,CACKE,EAAI,CADTF,CACYG,EAAKH,CAAAI,OAArB,CAAkCF,CAAlC,CAAsCC,CAAtC,EAA4CE,CAA5C,GAAoDrC,CAApD,CAA+DkC,CAAA,EAA/D,CAAoE,CAClE,IAAI5B,EAAM0B,CAAA,CAAKE,CAAL,CACVG,EAAA,CAAe,IAAT,GAACA,CAAD,CAAiBA,CAAA,CAAI/B,CAAJ,CAAjB,CAA4BN,CAFgC,CAqbjD,CAAA,IACiCK,EAAAA,CAAAA,CAD5CsB,EAAA,CAAIrB,CAAJ,CAAA,CAAW,CAF6B,CAA1C,CAKA,OAAOqB,EARiC,CAW1CW,QAASA,EAA0B,CAACC,CAAD,CAAW,CAC5C,MAAOA,EAAAC,SADqC,CAI9CC,QAASA,EAAQ,CAACpC,CAAD,CAAO,CACtBJ,CAAA,CAAoBI,CAApB,EAA6B,EAA7B,CAAiC,IAAjC,CADsB,CAnBxB,IAAIqC,EAAQ,IAAI1B,CAAJ,CAAUK,CAAV,CAEZE,EAAA,CAAUK,CAAA,CAAO,EAAP,CAAWe,CAAX,CAA4BpB,CAA5B,CAqBVnB,EAAA,CAAQmB,CAAR,CAAiB,QAAQ,CAACqB,CAAD,CAASC,CAAT,CAAe,CACtC,IAAIC,EAAU,qBAAAf,KAAA,CAA2Ba,CAAAG,OAA3B,CAEdN,EAAA,CAASI,CAAT,CAAA,CAAiB,QAAQ,CAACG,CAAD,CAAKC,CAAL,CAASC,CAAT,CAAaC,CAAb,CAAiB,CAAA,IACpCC,EAAS,EAD2B,CACvB3B,CADuB,CACjB4B,CADiB,CACRC,CAGhC,QAAOC,SAAAnB,OAAP,EACA,KAAK,CAAL,CACEkB,CACA,CADQH,CACR,CAAAE,CAAA,CAAUH,CAEZ,MAAK,CAAL,CACA,KAAK,CAAL,CACE,GAAIrB,CAAA,CAAWoB,CAAX,CAAJ,CAAoB,CAClB,GAAIpB,CAAA,CAAWmB,CAAX,CAAJ,CAAoB,CAClBK,CAAA;AAAUL,CACVM,EAAA,CAAQL,CACR,MAHkB,CAMpBI,CAAA,CAAUJ,CACVK,EAAA,CAAQJ,CARU,CAApB,IAUO,CACLE,CAAA,CAASJ,CACTvB,EAAA,CAAOwB,CACPI,EAAA,CAAUH,CACV,MAJK,CAMT,KAAK,CAAL,CACMrB,CAAA,CAAWmB,CAAX,CAAJ,CAAoBK,CAApB,CAA8BL,CAA9B,CACSF,CAAJ,CAAarB,CAAb,CAAoBuB,CAApB,CACAI,CADA,CACSJ,CACd,MACF,MAAK,CAAL,CAAQ,KACR,SACE,KAAMvC,EAAA,CAAgB,SAAhB,CAEJ8C,SAAAnB,OAFI,CAAN,CA9BF,CAoCA,IAAIoB,EAAiB,IAAjBA,WAAiCf,EAArC,CACIpC,EAAQmD,CAAA,CAAiB/B,CAAjB,CAAyBmB,CAAAa,QAAA,CAAiB,EAAjB,CAAsB,IAAIhB,CAAJ,CAAahB,CAAb,CAD3D,CAEIiC,EAAa,EAFjB,CAGIC,EAAsBf,CAAAgB,YAAtBD,EAA4Cf,CAAAgB,YAAArB,SAA5CoB,EACsBrB,CAJ1B,CAKIuB,EAA2BjB,CAAAgB,YAA3BC,EAAiDjB,CAAAgB,YAAAE,cAAjDD,EACsB7D,CAE1BI,EAAA,CAAQwC,CAAR,CAAgB,QAAQ,CAACvC,CAAD,CAAQC,CAAR,CAAa,CACxB,QAAX,EAAIA,CAAJ,GAA8B,SAA9B,EAAuBA,CAAvB,EAAkD,aAAlD,EAA2CA,CAA3C,IACEoD,CAAA,CAAWpD,CAAX,CADF,CACoByD,CAAA,CAAK1D,CAAL,CADpB,CADmC,CAArC,CAMIyC,EAAJ,GAAaY,CAAAjC,KAAb,CAA+BA,CAA/B,CACAiB,EAAAsB,aAAA,CAAmBN,CAAnB,CACmB9B,CAAA,CAAO,EAAP,CAAWJ,CAAA,CAAcC,CAAd,CAAoBmB,CAAAQ,OAApB,EAAqC,EAArC,CAAX,CAAqDA,CAArD,CADnB,CAEmBR,CAAAvB,IAFnB,CAII4C,EAAAA,CAAUnD,CAAA,CAAM4C,CAAN,CAAAQ,KAAA,CAAuB,QAAS,CAAC3B,CAAD,CAAW,CAAA,IACnDd,EAAOc,CAAAd,KAD4C,CAErDwC,EAAU5D,CAAA8D,SAEZ,IAAI1C,CAAJ,CAAU,CAGR,GAAI1B,CAAA0D,QAAA,CAAgBhC,CAAhB,CAAJ,GAA+B,CAAC,CAACmB,CAAAa,QAAjC,CACE,KAAMhD,EAAA,CAAgB,QAAhB;AAGJmC,CAAAa,QAAA,CAAiB,OAAjB,CAA2B,QAHvB,CAIJ1D,CAAA0D,QAAA,CAAgBhC,CAAhB,CAAA,CAAwB,OAAxB,CAAkC,QAJ9B,CAAN,CAOEmB,CAAAa,QAAJ,EACEpD,CAAA+B,OACA,CADe,CACf,CAAAhC,CAAA,CAAQqB,CAAR,CAAc,QAAS,CAAC2C,CAAD,CAAO,CACR,QAApB,GAAI,MAAOA,EAAX,CACE/D,CAAAgE,KAAA,CAAW,IAAI5B,CAAJ,CAAa2B,CAAb,CAAX,CADF,CAME/D,CAAAgE,KAAA,CAAWD,CAAX,CAP0B,CAA9B,CAFF,GAaEnE,CAAA,CAAoBwB,CAApB,CAA0BpB,CAA1B,CACA,CAAAA,CAAA8D,SAAA,CAAiBF,CAdnB,CAXQ,CA6BV5D,CAAAiE,UAAA,CAAkB,CAAA,CAElB/B,EAAAC,SAAA,CAAoBnC,CAEpB,OAAOkC,EArCgD,CAA3C,CAsCX,QAAQ,CAACA,CAAD,CAAW,CACpBlC,CAAAiE,UAAA,CAAkB,CAAA,CAEjB,EAAAhB,CAAA,EAAOiB,CAAP,EAAahC,CAAb,CAED,OAAOxB,EAAAyD,OAAA,CAAUjC,CAAV,CALa,CAtCR,CA8Cd0B,EAAA,CAAUA,CAAAC,KAAA,CACN,QAAQ,CAAC3B,CAAD,CAAW,CACjB,IAAIlC,EAAQsD,CAAA,CAAoBpB,CAApB,CACX,EAAAc,CAAA,EAASkB,CAAT,EAAelE,CAAf,CAAsBkC,CAAAkC,QAAtB,CACD,OAAOpE,EAHU,CADb,CAMNwD,CANM,CAQV,OAAKL,EAAL,CAWOS,CAXP,EAIE5D,CAAA8D,SAGO9D,CAHU4D,CAGV5D,CAFPA,CAAAiE,UAEOjE,CAFW,CAAA,CAEXA,CAAAA,CAPT,CAjHwC,CAgI1CoC,EAAAiC,UAAA,CAAmB,GAAnB,CAAyB7B,CAAzB,CAAA,CAAiC,QAAQ,CAACO,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAAyB,CAC5DzB,CAAA,CAAWuB,CAAX,CAAJ,GACEE,CAAmC,CAA3BD,CAA2B,CAAlBA,CAAkB,CAARD,CAAQ,CAAAA,CAAA,CAAS,EAD9C,CAGIuB,EAAAA,CAASlC,CAAA,CAASI,CAAT,CAAA+B,KAAA,CAAoB,IAApB,CAA0BxB,CAA1B,CAAkC,IAAlC,CAAwCC,CAAxC,CAAiDC,CAAjD,CACb,OAAOqB,EAAAR,SAAP,EAA0BQ,CALsC,CAnI5B,CAAxC,CA4IAlC,EAAAoC,KAAA,CAAgBC,QAAQ,CAACC,CAAD,CAAyB,CAC/C,MAAO3D,EAAA,CAAgBC,CAAhB;AAAqBO,CAAA,CAAO,EAAP,CAAWN,CAAX,CAA0ByD,CAA1B,CAArB,CAAyExD,CAAzE,CADwC,CAIjD,OAAOkB,EAxK6C,CArHtD,IAAIE,EAAkB,KACV,QAAQ,KAAR,CADU,MAEV,QAAQ,MAAR,CAFU,OAGV,QAAQ,KAAR,SAAuB,CAAA,CAAvB,CAHU,QAIV,QAAQ,QAAR,CAJU,CAKpB,QALoB,CAKV,QAAQ,QAAR,CALU,CAAtB,CAOI4B,EAAOxE,CAAAwE,KAPX,CAQInE,EAAUL,CAAAK,QARd,CASIwB,EAAS7B,CAAA6B,OATb,CAUImC,EAAOhE,CAAAgE,KAVX,CAWIlC,EAAa9B,CAAA8B,WA+CjBb,EAAA0D,UAAA,CAAkB,cACFV,QAAQ,CAACgB,CAAD,CAAS5B,CAAT,CAAiB6B,CAAjB,CAA4B,CAAA,IAC5CC,EAAO,IADqC,CAE5C7D,EAAM4D,CAAN5D,EAAmB6D,CAAAjE,SAFyB,CAG5CkE,CAH4C,CAI5CC,CAJ4C,CAM5CjE,EAAY+D,CAAA/D,UAAZA,CAA6B,EACjCf,EAAA,CAAQiB,CAAAY,MAAA,CAAU,IAAV,CAAR,CAAyB,QAAQ,CAACoD,CAAD,CAAO,CACtC,GAAc,gBAAd,GAAIA,CAAJ,CACE,KAAM5E,EAAA,CAAgB,SAAhB,CAAN,CAEI,CAAA,OAAAsB,KAAA,CAA0BsD,CAA1B,CAAN,GAA2CA,CAA3C,EACUC,MAAJ,CAAW,cAAX,CAA4BD,CAA5B,CAAoC,SAApC,CAAAtD,KAAA,CAAoDV,CAApD,CADN,IAEEF,CAAA,CAAUkE,CAAV,CAFF,CAEqB,CAAA,CAFrB,CAJsC,CAAxC,CASAhE,EAAA,CAAMA,CAAAkE,QAAA,CAAY,MAAZ,CAAoB,GAApB,CAENnC,EAAA,CAASA,CAAT,EAAmB,EACnBhD,EAAA,CAAQ8E,CAAA/D,UAAR,CAAwB,QAAQ,CAACqE,CAAD;AAAIC,CAAJ,CAAa,CAC3CN,CAAA,CAAM/B,CAAA7C,eAAA,CAAsBkF,CAAtB,CAAA,CAAkCrC,CAAA,CAAOqC,CAAP,CAAlC,CAAqDP,CAAAhE,SAAA,CAAcuE,CAAd,CACvD1F,EAAA2F,UAAA,CAAkBP,CAAlB,CAAJ,EAAsC,IAAtC,GAA8BA,CAA9B,EACEC,CACA,CAtCCO,kBAAA,CAqC6BR,CArC7B,CAAAI,QAAA,CACG,OADH,CACY,GADZ,CAAAA,QAAA,CAEG,OAFH,CAEY,GAFZ,CAAAA,QAAA,CAGG,MAHH,CAGW,GAHX,CAAAA,QAAA,CAIG,OAJH,CAIY,GAJZ,CAAAA,QAAA,CAKG,MALH,CAK8B,KAL9B,CAnBAA,QAAA,CACG,OADH,CACY,GADZ,CAAAA,QAAA,CAEG,OAFH,CAEY,GAFZ,CAAAA,QAAA,CAGG,OAHH,CAGY,GAHZ,CAyDD,CAAAlE,CAAA,CAAMA,CAAAkE,QAAA,CAAgBD,MAAJ,CAAW,GAAX,CAAiBG,CAAjB,CAA4B,SAA5B,CAAuC,GAAvC,CAAZ,CAAyD,QAAQ,CAACG,CAAD,CAAQC,CAAR,CAAY,CACjF,MAAOT,EAAP,CAAoBS,CAD6D,CAA7E,CAFR,EAMExE,CANF,CAMQA,CAAAkE,QAAA,CAAgBD,MAAJ,CAAW,OAAX,CAAsBG,CAAtB,CAAiC,SAAjC,CAA4C,GAA5C,CAAZ,CAA8D,QAAQ,CAACG,CAAD,CACxEE,CADwE,CACxDC,CADwD,CAClD,CACxB,MAAsB,GAAtB,EAAIA,CAAAvF,OAAA,CAAY,CAAZ,CAAJ,CACSuF,CADT,CAGSD,CAHT,CAG0BC,CAJF,CADpB,CARmC,CAA7C,CAoBA1E,EAAA,CAAMA,CAAAkE,QAAA,CAAY,MAAZ,CAAoB,EAApB,CAAN,EAAiC,GAGjClE,EAAA,CAAMA,CAAAkE,QAAA,CAAY,mBAAZ,CAAiC,GAAjC,CAENP,EAAA3D,IAAA,CAAaA,CAAAkE,QAAA,CAAY,QAAZ;AAAsB,IAAtB,CAIbnF,EAAA,CAAQgD,CAAR,CAAgB,QAAQ,CAAC/C,CAAD,CAAQC,CAAR,CAAY,CAC7B4E,CAAA/D,UAAA,CAAeb,CAAf,CAAL,GACE0E,CAAA5B,OACA,CADgB4B,CAAA5B,OAChB,EADiC,EACjC,CAAA4B,CAAA5B,OAAA,CAAc9C,CAAd,CAAA,CAAqBD,CAFvB,CADkC,CAApC,CAhDgD,CADlC,CAsOlB,OAAOe,EAlSgD,CAApC,CADvB,CAtUsC,CAArC,CAAA,CA6mBEtB,MA7mBF,CA6mBUA,MAAAC,QA7mBV;",
+"sources":["angular-resource.js"],
+"names":["window","angular","undefined","shallowClearAndCopy","src","dst","forEach","value","key","hasOwnProperty","charAt","$resourceMinErr","$$minErr","MEMBER_NAME_REGEX","module","factory","$http","$q","Route","template","defaults","urlParams","resourceFactory","url","paramDefaults","actions","extractParams","data","actionParams","ids","extend","isFunction","path","test","keys","split","i","ii","length","obj","defaultResponseInterceptor","response","resource","Resource","route","DEFAULT_ACTIONS","action","name","hasBody","method","a1","a2","a3","a4","params","success","error","arguments","isInstanceCall","isArray","httpConfig","responseInterceptor","interceptor","responseErrorInterceptor","responseError","copy","setUrlParams","promise","then","$promise","item","push","$resolved","noop","reject","headers","prototype","result","call","bind","Resource.bind","additionalParamDefaults","config","actionUrl","self","val","encodedVal","param","RegExp","replace","_","urlParam","isDefined","encodeURIComponent","match","p1","leadingSlashes","tail"]
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-route.js b/src/main/resources/META-INF/resources/designer/lib/angular-route.js
new file mode 100644 (file)
index 0000000..393d962
--- /dev/null
@@ -0,0 +1,921 @@
+/**
+ * @license AngularJS v1.2.26
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngRoute
+ * @description
+ *
+ * # ngRoute
+ *
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ *
+ * <div doc-module-components="ngRoute"></div>
+ */
+ /* global -ngRouteModule */
+var ngRouteModule = angular.module('ngRoute', ['ng']).
+                        provider('$route', $RouteProvider);
+
+/**
+ * @ngdoc provider
+ * @name $routeProvider
+ * @kind function
+ *
+ * @description
+ *
+ * Used for configuring routes.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ * ## Dependencies
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ */
+function $RouteProvider(){
+  function inherit(parent, extra) {
+    return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
+  }
+
+  var routes = {};
+
+  /**
+   * @ngdoc method
+   * @name $routeProvider#when
+   *
+   * @param {string} path Route path (matched against `$location.path`). If `$location.path`
+   *    contains redundant trailing slash or is missing one, the route will still match and the
+   *    `$location.path` will be updated to add or drop the trailing slash to exactly match the
+   *    route definition.
+   *
+   *    * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
+   *        to the next slash are matched and stored in `$routeParams` under the given `name`
+   *        when the route matches.
+   *    * `path` can contain named groups starting with a colon and ending with a star:
+   *        e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
+   *        when the route matches.
+   *    * `path` can contain optional named groups with a question mark: e.g.`:name?`.
+   *
+   *    For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
+   *    `/color/brown/largecode/code/with/slashes/edit` and extract:
+   *
+   *    * `color: brown`
+   *    * `largecode: code/with/slashes`.
+   *
+   *
+   * @param {Object} route Mapping information to be assigned to `$route.current` on route
+   *    match.
+   *
+   *    Object properties:
+   *
+   *    - `controller` – `{(string|function()=}` – Controller fn that should be associated with
+   *      newly created scope or the name of a {@link angular.Module#controller registered
+   *      controller} if passed as a string.
+   *    - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
+   *      published to scope under the `controllerAs` name.
+   *    - `template` – `{string=|function()=}` – html template as a string or a function that
+   *      returns an html template as a string which should be used by {@link
+   *      ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
+   *      This property takes precedence over `templateUrl`.
+   *
+   *      If `template` is a function, it will be called with the following parameters:
+   *
+   *      - `{Array.<Object>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route
+   *
+   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
+   *      template that should be used by {@link ngRoute.directive:ngView ngView}.
+   *
+   *      If `templateUrl` is a function, it will be called with the following parameters:
+   *
+   *      - `{Array.<Object>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route
+   *
+   *    - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
+   *      be injected into the controller. If any of these dependencies are promises, the router
+   *      will wait for them all to be resolved or one to be rejected before the controller is
+   *      instantiated.
+   *      If all the promises are resolved successfully, the values of the resolved promises are
+   *      injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
+   *      fired. If any of the promises are rejected the
+   *      {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
+   *      is:
+   *
+   *      - `key` – `{string}`: a name of a dependency to be injected into the controller.
+   *      - `factory` - `{string|function}`: If `string` then it is an alias for a service.
+   *        Otherwise if function, then it is {@link auto.$injector#invoke injected}
+   *        and the return value is treated as the dependency. If the result is a promise, it is
+   *        resolved before its value is injected into the controller. Be aware that
+   *        `ngRoute.$routeParams` will still refer to the previous route within these resolve
+   *        functions.  Use `$route.current.params` to access the new route parameters, instead.
+   *
+   *    - `redirectTo` – {(string|function())=} – value to update
+   *      {@link ng.$location $location} path with and trigger route redirection.
+   *
+   *      If `redirectTo` is a function, it will be called with the following parameters:
+   *
+   *      - `{Object.<string>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route templateUrl.
+   *      - `{string}` - current `$location.path()`
+   *      - `{Object}` - current `$location.search()`
+   *
+   *      The custom `redirectTo` function is expected to return a string which will be used
+   *      to update `$location.path()` and `$location.search()`.
+   *
+   *    - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
+   *      or `$location.hash()` changes.
+   *
+   *      If the option is set to `false` and url in the browser changes, then
+   *      `$routeUpdate` event is broadcasted on the root scope.
+   *
+   *    - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
+   *
+   *      If the option is set to `true`, then the particular route can be matched without being
+   *      case sensitive
+   *
+   * @returns {Object} self
+   *
+   * @description
+   * Adds a new route definition to the `$route` service.
+   */
+  this.when = function(path, route) {
+    routes[path] = angular.extend(
+      {reloadOnSearch: true},
+      route,
+      path && pathRegExp(path, route)
+    );
+
+    // create redirection for trailing slashes
+    if (path) {
+      var redirectPath = (path[path.length-1] == '/')
+            ? path.substr(0, path.length-1)
+            : path +'/';
+
+      routes[redirectPath] = angular.extend(
+        {redirectTo: path},
+        pathRegExp(redirectPath, route)
+      );
+    }
+
+    return this;
+  };
+
+   /**
+    * @param path {string} path
+    * @param opts {Object} options
+    * @return {?Object}
+    *
+    * @description
+    * Normalizes the given path, returning a regular expression
+    * and the original path.
+    *
+    * Inspired by pathRexp in visionmedia/express/lib/utils.js.
+    */
+  function pathRegExp(path, opts) {
+    var insensitive = opts.caseInsensitiveMatch,
+        ret = {
+          originalPath: path,
+          regexp: path
+        },
+        keys = ret.keys = [];
+
+    path = path
+      .replace(/([().])/g, '\\$1')
+      .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option){
+        var optional = option === '?' ? option : null;
+        var star = option === '*' ? option : null;
+        keys.push({ name: key, optional: !!optional });
+        slash = slash || '';
+        return ''
+          + (optional ? '' : slash)
+          + '(?:'
+          + (optional ? slash : '')
+          + (star && '(.+?)' || '([^/]+)')
+          + (optional || '')
+          + ')'
+          + (optional || '');
+      })
+      .replace(/([\/$\*])/g, '\\$1');
+
+    ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
+    return ret;
+  }
+
+  /**
+   * @ngdoc method
+   * @name $routeProvider#otherwise
+   *
+   * @description
+   * Sets route definition that will be used on route change when no other route definition
+   * is matched.
+   *
+   * @param {Object} params Mapping information to be assigned to `$route.current`.
+   * @returns {Object} self
+   */
+  this.otherwise = function(params) {
+    this.when(null, params);
+    return this;
+  };
+
+
+  this.$get = ['$rootScope',
+               '$location',
+               '$routeParams',
+               '$q',
+               '$injector',
+               '$http',
+               '$templateCache',
+               '$sce',
+      function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
+
+    /**
+     * @ngdoc service
+     * @name $route
+     * @requires $location
+     * @requires $routeParams
+     *
+     * @property {Object} current Reference to the current route definition.
+     * The route definition contains:
+     *
+     *   - `controller`: The controller constructor as define in route definition.
+     *   - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
+     *     controller instantiation. The `locals` contain
+     *     the resolved values of the `resolve` map. Additionally the `locals` also contain:
+     *
+     *     - `$scope` - The current route scope.
+     *     - `$template` - The current route template HTML.
+     *
+     * @property {Object} routes Object with all route configuration Objects as its properties.
+     *
+     * @description
+     * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
+     * It watches `$location.url()` and tries to map the path to an existing route definition.
+     *
+     * Requires the {@link ngRoute `ngRoute`} module to be installed.
+     *
+     * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
+     *
+     * The `$route` service is typically used in conjunction with the
+     * {@link ngRoute.directive:ngView `ngView`} directive and the
+     * {@link ngRoute.$routeParams `$routeParams`} service.
+     *
+     * @example
+     * This example shows how changing the URL hash causes the `$route` to match a route against the
+     * URL, and the `ngView` pulls in the partial.
+     *
+     * <example name="$route-service" module="ngRouteExample"
+     *          deps="angular-route.js" fixBase="true">
+     *   <file name="index.html">
+     *     <div ng-controller="MainController">
+     *       Choose:
+     *       <a href="Book/Moby">Moby</a> |
+     *       <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+     *       <a href="Book/Gatsby">Gatsby</a> |
+     *       <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+     *       <a href="Book/Scarlet">Scarlet Letter</a><br/>
+     *
+     *       <div ng-view></div>
+     *
+     *       <hr />
+     *
+     *       <pre>$location.path() = {{$location.path()}}</pre>
+     *       <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
+     *       <pre>$route.current.params = {{$route.current.params}}</pre>
+     *       <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
+     *       <pre>$routeParams = {{$routeParams}}</pre>
+     *     </div>
+     *   </file>
+     *
+     *   <file name="book.html">
+     *     controller: {{name}}<br />
+     *     Book Id: {{params.bookId}}<br />
+     *   </file>
+     *
+     *   <file name="chapter.html">
+     *     controller: {{name}}<br />
+     *     Book Id: {{params.bookId}}<br />
+     *     Chapter Id: {{params.chapterId}}
+     *   </file>
+     *
+     *   <file name="script.js">
+     *     angular.module('ngRouteExample', ['ngRoute'])
+     *
+     *      .controller('MainController', function($scope, $route, $routeParams, $location) {
+     *          $scope.$route = $route;
+     *          $scope.$location = $location;
+     *          $scope.$routeParams = $routeParams;
+     *      })
+     *
+     *      .controller('BookController', function($scope, $routeParams) {
+     *          $scope.name = "BookController";
+     *          $scope.params = $routeParams;
+     *      })
+     *
+     *      .controller('ChapterController', function($scope, $routeParams) {
+     *          $scope.name = "ChapterController";
+     *          $scope.params = $routeParams;
+     *      })
+     *
+     *     .config(function($routeProvider, $locationProvider) {
+     *       $routeProvider
+     *        .when('/Book/:bookId', {
+     *         templateUrl: 'book.html',
+     *         controller: 'BookController',
+     *         resolve: {
+     *           // I will cause a 1 second delay
+     *           delay: function($q, $timeout) {
+     *             var delay = $q.defer();
+     *             $timeout(delay.resolve, 1000);
+     *             return delay.promise;
+     *           }
+     *         }
+     *       })
+     *       .when('/Book/:bookId/ch/:chapterId', {
+     *         templateUrl: 'chapter.html',
+     *         controller: 'ChapterController'
+     *       });
+     *
+     *       // configure html5 to get links working on jsfiddle
+     *       $locationProvider.html5Mode(true);
+     *     });
+     *
+     *   </file>
+     *
+     *   <file name="protractor.js" type="protractor">
+     *     it('should load and compile correct template', function() {
+     *       element(by.linkText('Moby: Ch1')).click();
+     *       var content = element(by.css('[ng-view]')).getText();
+     *       expect(content).toMatch(/controller\: ChapterController/);
+     *       expect(content).toMatch(/Book Id\: Moby/);
+     *       expect(content).toMatch(/Chapter Id\: 1/);
+     *
+     *       element(by.partialLinkText('Scarlet')).click();
+     *
+     *       content = element(by.css('[ng-view]')).getText();
+     *       expect(content).toMatch(/controller\: BookController/);
+     *       expect(content).toMatch(/Book Id\: Scarlet/);
+     *     });
+     *   </file>
+     * </example>
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeStart
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted before a route change. At this  point the route services starts
+     * resolving all of the dependencies needed for the route change to occur.
+     * Typically this involves fetching the view template as well as any dependencies
+     * defined in `resolve` route property. Once  all of the dependencies are resolved
+     * `$routeChangeSuccess` is fired.
+     *
+     * @param {Object} angularEvent Synthetic event object.
+     * @param {Route} next Future route information.
+     * @param {Route} current Current route information.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeSuccess
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted after a route dependencies are resolved.
+     * {@link ngRoute.directive:ngView ngView} listens for the directive
+     * to instantiate the controller and render the view.
+     *
+     * @param {Object} angularEvent Synthetic event object.
+     * @param {Route} current Current route information.
+     * @param {Route|Undefined} previous Previous route information, or undefined if current is
+     * first route entered.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeError
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted if any of the resolve promises are rejected.
+     *
+     * @param {Object} angularEvent Synthetic event object
+     * @param {Route} current Current route information.
+     * @param {Route} previous Previous route information.
+     * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeUpdate
+     * @eventType broadcast on root scope
+     * @description
+     *
+     * The `reloadOnSearch` property has been set to false, and we are reusing the same
+     * instance of the Controller.
+     */
+
+    var forceReload = false,
+        $route = {
+          routes: routes,
+
+          /**
+           * @ngdoc method
+           * @name $route#reload
+           *
+           * @description
+           * Causes `$route` service to reload the current route even if
+           * {@link ng.$location $location} hasn't changed.
+           *
+           * As a result of that, {@link ngRoute.directive:ngView ngView}
+           * creates new scope, reinstantiates the controller.
+           */
+          reload: function() {
+            forceReload = true;
+            $rootScope.$evalAsync(updateRoute);
+          }
+        };
+
+    $rootScope.$on('$locationChangeSuccess', updateRoute);
+
+    return $route;
+
+    /////////////////////////////////////////////////////
+
+    /**
+     * @param on {string} current url
+     * @param route {Object} route regexp to match the url against
+     * @return {?Object}
+     *
+     * @description
+     * Check if the route matches the current url.
+     *
+     * Inspired by match in
+     * visionmedia/express/lib/router/router.js.
+     */
+    function switchRouteMatcher(on, route) {
+      var keys = route.keys,
+          params = {};
+
+      if (!route.regexp) return null;
+
+      var m = route.regexp.exec(on);
+      if (!m) return null;
+
+      for (var i = 1, len = m.length; i < len; ++i) {
+        var key = keys[i - 1];
+
+        var val = m[i];
+
+        if (key && val) {
+          params[key.name] = val;
+        }
+      }
+      return params;
+    }
+
+    function updateRoute() {
+      var next = parseRoute(),
+          last = $route.current;
+
+      if (next && last && next.$$route === last.$$route
+          && angular.equals(next.pathParams, last.pathParams)
+          && !next.reloadOnSearch && !forceReload) {
+        last.params = next.params;
+        angular.copy(last.params, $routeParams);
+        $rootScope.$broadcast('$routeUpdate', last);
+      } else if (next || last) {
+        forceReload = false;
+        $rootScope.$broadcast('$routeChangeStart', next, last);
+        $route.current = next;
+        if (next) {
+          if (next.redirectTo) {
+            if (angular.isString(next.redirectTo)) {
+              $location.path(interpolate(next.redirectTo, next.params)).search(next.params)
+                       .replace();
+            } else {
+              $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
+                       .replace();
+            }
+          }
+        }
+
+        $q.when(next).
+          then(function() {
+            if (next) {
+              var locals = angular.extend({}, next.resolve),
+                  template, templateUrl;
+
+              angular.forEach(locals, function(value, key) {
+                locals[key] = angular.isString(value) ?
+                    $injector.get(value) : $injector.invoke(value);
+              });
+
+              if (angular.isDefined(template = next.template)) {
+                if (angular.isFunction(template)) {
+                  template = template(next.params);
+                }
+              } else if (angular.isDefined(templateUrl = next.templateUrl)) {
+                if (angular.isFunction(templateUrl)) {
+                  templateUrl = templateUrl(next.params);
+                }
+                templateUrl = $sce.getTrustedResourceUrl(templateUrl);
+                if (angular.isDefined(templateUrl)) {
+                  next.loadedTemplateUrl = templateUrl;
+                  template = $http.get(templateUrl, {cache: $templateCache}).
+                      then(function(response) { return response.data; });
+                }
+              }
+              if (angular.isDefined(template)) {
+                locals['$template'] = template;
+              }
+              return $q.all(locals);
+            }
+          }).
+          // after route change
+          then(function(locals) {
+            if (next == $route.current) {
+              if (next) {
+                next.locals = locals;
+                angular.copy(next.params, $routeParams);
+              }
+              $rootScope.$broadcast('$routeChangeSuccess', next, last);
+            }
+          }, function(error) {
+            if (next == $route.current) {
+              $rootScope.$broadcast('$routeChangeError', next, last, error);
+            }
+          });
+      }
+    }
+
+
+    /**
+     * @returns {Object} the current active route, by matching it against the URL
+     */
+    function parseRoute() {
+      // Match a route
+      var params, match;
+      angular.forEach(routes, function(route, path) {
+        if (!match && (params = switchRouteMatcher($location.path(), route))) {
+          match = inherit(route, {
+            params: angular.extend({}, $location.search(), params),
+            pathParams: params});
+          match.$$route = route;
+        }
+      });
+      // No route matched; fallback to "otherwise" route
+      return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
+    }
+
+    /**
+     * @returns {string} interpolation of the redirect path with the parameters
+     */
+    function interpolate(string, params) {
+      var result = [];
+      angular.forEach((string||'').split(':'), function(segment, i) {
+        if (i === 0) {
+          result.push(segment);
+        } else {
+          var segmentMatch = segment.match(/(\w+)(.*)/);
+          var key = segmentMatch[1];
+          result.push(params[key]);
+          result.push(segmentMatch[2] || '');
+          delete params[key];
+        }
+      });
+      return result.join('');
+    }
+  }];
+}
+
+ngRouteModule.provider('$routeParams', $RouteParamsProvider);
+
+
+/**
+ * @ngdoc service
+ * @name $routeParams
+ * @requires $route
+ *
+ * @description
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
+ * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}.
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
+ *
+ * In case of parameter name collision, `path` params take precedence over `search` params.
+ *
+ * The service guarantees that the identity of the `$routeParams` object will remain unchanged
+ * (but its properties will likely change) even when a route change occurs.
+ *
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
+ * Instead you can use `$route.current.params` to access the new route's parameters.
+ *
+ * @example
+ * ```js
+ *  // Given:
+ *  // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
+ *  // Route: /Chapter/:chapterId/Section/:sectionId
+ *  //
+ *  // Then
+ *  $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
+ * ```
+ */
+function $RouteParamsProvider() {
+  this.$get = function() { return {}; };
+}
+
+ngRouteModule.directive('ngView', ngViewFactory);
+ngRouteModule.directive('ngView', ngViewFillContentFactory);
+
+
+/**
+ * @ngdoc directive
+ * @name ngView
+ * @restrict ECA
+ *
+ * @description
+ * # Overview
+ * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
+ * including the rendered template of the current route into the main layout (`index.html`) file.
+ * Every time the current route changes, the included view changes with it according to the
+ * configuration of the `$route` service.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * @animations
+ * enter - animation is used to bring new content into the browser.
+ * leave - animation is used to animate existing content away.
+ *
+ * The enter and leave animation occur concurrently.
+ *
+ * @scope
+ * @priority 400
+ * @param {string=} onload Expression to evaluate whenever the view updates.
+ *
+ * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll
+ *                  $anchorScroll} to scroll the viewport after the view is updated.
+ *
+ *                  - If the attribute is not set, disable scrolling.
+ *                  - If the attribute is set without value, enable scrolling.
+ *                  - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated
+ *                    as an expression yields a truthy value.
+ * @example
+    <example name="ngView-directive" module="ngViewExample"
+             deps="angular-route.js;angular-animate.js"
+             animations="true" fixBase="true">
+      <file name="index.html">
+        <div ng-controller="MainCtrl as main">
+          Choose:
+          <a href="Book/Moby">Moby</a> |
+          <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+          <a href="Book/Gatsby">Gatsby</a> |
+          <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+          <a href="Book/Scarlet">Scarlet Letter</a><br/>
+
+          <div class="view-animate-container">
+            <div ng-view class="view-animate"></div>
+          </div>
+          <hr />
+
+          <pre>$location.path() = {{main.$location.path()}}</pre>
+          <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
+          <pre>$route.current.params = {{main.$route.current.params}}</pre>
+          <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
+          <pre>$routeParams = {{main.$routeParams}}</pre>
+        </div>
+      </file>
+
+      <file name="book.html">
+        <div>
+          controller: {{book.name}}<br />
+          Book Id: {{book.params.bookId}}<br />
+        </div>
+      </file>
+
+      <file name="chapter.html">
+        <div>
+          controller: {{chapter.name}}<br />
+          Book Id: {{chapter.params.bookId}}<br />
+          Chapter Id: {{chapter.params.chapterId}}
+        </div>
+      </file>
+
+      <file name="animations.css">
+        .view-animate-container {
+          position:relative;
+          height:100px!important;
+          position:relative;
+          background:white;
+          border:1px solid black;
+          height:40px;
+          overflow:hidden;
+        }
+
+        .view-animate {
+          padding:10px;
+        }
+
+        .view-animate.ng-enter, .view-animate.ng-leave {
+          -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+          transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+
+          display:block;
+          width:100%;
+          border-left:1px solid black;
+
+          position:absolute;
+          top:0;
+          left:0;
+          right:0;
+          bottom:0;
+          padding:10px;
+        }
+
+        .view-animate.ng-enter {
+          left:100%;
+        }
+        .view-animate.ng-enter.ng-enter-active {
+          left:0;
+        }
+        .view-animate.ng-leave.ng-leave-active {
+          left:-100%;
+        }
+      </file>
+
+      <file name="script.js">
+        angular.module('ngViewExample', ['ngRoute', 'ngAnimate'])
+          .config(['$routeProvider', '$locationProvider',
+            function($routeProvider, $locationProvider) {
+              $routeProvider
+                .when('/Book/:bookId', {
+                  templateUrl: 'book.html',
+                  controller: 'BookCtrl',
+                  controllerAs: 'book'
+                })
+                .when('/Book/:bookId/ch/:chapterId', {
+                  templateUrl: 'chapter.html',
+                  controller: 'ChapterCtrl',
+                  controllerAs: 'chapter'
+                });
+
+              $locationProvider.html5Mode(true);
+          }])
+          .controller('MainCtrl', ['$route', '$routeParams', '$location',
+            function($route, $routeParams, $location) {
+              this.$route = $route;
+              this.$location = $location;
+              this.$routeParams = $routeParams;
+          }])
+          .controller('BookCtrl', ['$routeParams', function($routeParams) {
+            this.name = "BookCtrl";
+            this.params = $routeParams;
+          }])
+          .controller('ChapterCtrl', ['$routeParams', function($routeParams) {
+            this.name = "ChapterCtrl";
+            this.params = $routeParams;
+          }]);
+
+      </file>
+
+      <file name="protractor.js" type="protractor">
+        it('should load and compile correct template', function() {
+          element(by.linkText('Moby: Ch1')).click();
+          var content = element(by.css('[ng-view]')).getText();
+          expect(content).toMatch(/controller\: ChapterCtrl/);
+          expect(content).toMatch(/Book Id\: Moby/);
+          expect(content).toMatch(/Chapter Id\: 1/);
+
+          element(by.partialLinkText('Scarlet')).click();
+
+          content = element(by.css('[ng-view]')).getText();
+          expect(content).toMatch(/controller\: BookCtrl/);
+          expect(content).toMatch(/Book Id\: Scarlet/);
+        });
+      </file>
+    </example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngView#$viewContentLoaded
+ * @eventType emit on the current ngView scope
+ * @description
+ * Emitted every time the ngView content is reloaded.
+ */
+ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
+function ngViewFactory(   $route,   $anchorScroll,   $animate) {
+  return {
+    restrict: 'ECA',
+    terminal: true,
+    priority: 400,
+    transclude: 'element',
+    link: function(scope, $element, attr, ctrl, $transclude) {
+        var currentScope,
+            currentElement,
+            previousElement,
+            autoScrollExp = attr.autoscroll,
+            onloadExp = attr.onload || '';
+
+        scope.$on('$routeChangeSuccess', update);
+        update();
+
+        function cleanupLastView() {
+          if(previousElement) {
+            previousElement.remove();
+            previousElement = null;
+          }
+          if(currentScope) {
+            currentScope.$destroy();
+            currentScope = null;
+          }
+          if(currentElement) {
+            $animate.leave(currentElement, function() {
+              previousElement = null;
+            });
+            previousElement = currentElement;
+            currentElement = null;
+          }
+        }
+
+        function update() {
+          var locals = $route.current && $route.current.locals,
+              template = locals && locals.$template;
+
+          if (angular.isDefined(template)) {
+            var newScope = scope.$new();
+            var current = $route.current;
+
+            // Note: This will also link all children of ng-view that were contained in the original
+            // html. If that content contains controllers, ... they could pollute/change the scope.
+            // However, using ng-view on an element with additional content does not make sense...
+            // Note: We can't remove them in the cloneAttchFn of $transclude as that
+            // function is called before linking the content, which would apply child
+            // directives to non existing elements.
+            var clone = $transclude(newScope, function(clone) {
+              $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
+                if (angular.isDefined(autoScrollExp)
+                  && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+                  $anchorScroll();
+                }
+              });
+              cleanupLastView();
+            });
+
+            currentElement = clone;
+            currentScope = current.scope = newScope;
+            currentScope.$emit('$viewContentLoaded');
+            currentScope.$eval(onloadExp);
+          } else {
+            cleanupLastView();
+          }
+        }
+    }
+  };
+}
+
+// This directive is called during the $transclude call of the first `ngView` directive.
+// It will replace and compile the content of the element with the loaded template.
+// We need this directive so that the element content is already filled when
+// the link function of another directive on the same element as ngView
+// is called.
+ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
+function ngViewFillContentFactory($compile, $controller, $route) {
+  return {
+    restrict: 'ECA',
+    priority: -400,
+    link: function(scope, $element) {
+      var current = $route.current,
+          locals = current.locals;
+
+      $element.html(locals.$template);
+
+      var link = $compile($element.contents());
+
+      if (current.controller) {
+        locals.$scope = scope;
+        var controller = $controller(current.controller, locals);
+        if (current.controllerAs) {
+          scope[current.controllerAs] = controller;
+        }
+        $element.data('$ngControllerController', controller);
+        $element.children().data('$ngControllerController', controller);
+      }
+
+      link(scope);
+    }
+  };
+}
+
+
+})(window, window.angular);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-sanitize.js b/src/main/resources/META-INF/resources/designer/lib/angular-sanitize.js
new file mode 100644 (file)
index 0000000..2a28206
--- /dev/null
@@ -0,0 +1,624 @@
+/**
+ * @license AngularJS v1.2.16
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+var $sanitizeMinErr = angular.$$minErr('$sanitize');
+
+/**
+ * @ngdoc module
+ * @name ngSanitize
+ * @description
+ *
+ * # ngSanitize
+ *
+ * The `ngSanitize` module provides functionality to sanitize HTML.
+ *
+ *
+ * <div doc-module-components="ngSanitize"></div>
+ *
+ * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
+ */
+
+/*
+ * HTML Parser By Misko Hevery (misko@hevery.com)
+ * based on:  HTML Parser By John Resig (ejohn.org)
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * // Use like so:
+ * htmlParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+ *
+ */
+
+
+/**
+ * @ngdoc service
+ * @name $sanitize
+ * @function
+ *
+ * @description
+ *   The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
+ *   then serialized back to properly escaped html string. This means that no unsafe input can make
+ *   it into the returned string, however, since our parser is more strict than a typical browser
+ *   parser, it's possible that some obscure input, which would be recognized as valid HTML by a
+ *   browser, won't make it through the sanitizer.
+ *   The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
+ *   `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
+ *
+ * @param {string} html Html input.
+ * @returns {string} Sanitized html.
+ *
+ * @example
+   <example module="ngSanitize" deps="angular-sanitize.js">
+   <file name="index.html">
+     <script>
+       function Ctrl($scope, $sce) {
+         $scope.snippet =
+           '<p style="color:blue">an html\n' +
+           '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
+           'snippet</p>';
+         $scope.deliberatelyTrustDangerousSnippet = function() {
+           return $sce.trustAsHtml($scope.snippet);
+         };
+       }
+     </script>
+     <div ng-controller="Ctrl">
+        Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
+       <table>
+         <tr>
+           <td>Directive</td>
+           <td>How</td>
+           <td>Source</td>
+           <td>Rendered</td>
+         </tr>
+         <tr id="bind-html-with-sanitize">
+           <td>ng-bind-html</td>
+           <td>Automatically uses $sanitize</td>
+           <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
+           <td><div ng-bind-html="snippet"></div></td>
+         </tr>
+         <tr id="bind-html-with-trust">
+           <td>ng-bind-html</td>
+           <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
+           <td>
+           <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
+&lt;/div&gt;</pre>
+           </td>
+           <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
+         </tr>
+         <tr id="bind-default">
+           <td>ng-bind</td>
+           <td>Automatically escapes</td>
+           <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
+           <td><div ng-bind="snippet"></div></td>
+         </tr>
+       </table>
+       </div>
+   </file>
+   <file name="protractor.js" type="protractor">
+     it('should sanitize the html snippet by default', function() {
+       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+         toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
+     });
+
+     it('should inline raw snippet if bound to a trusted value', function() {
+       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
+         toBe("<p style=\"color:blue\">an html\n" +
+              "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
+              "snippet</p>");
+     });
+
+     it('should escape snippet without any filter', function() {
+       expect(element(by.css('#bind-default div')).getInnerHtml()).
+         toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
+              "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
+              "snippet&lt;/p&gt;");
+     });
+
+     it('should update', function() {
+       element(by.model('snippet')).clear();
+       element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
+       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+         toBe('new <b>text</b>');
+       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
+         'new <b onclick="alert(1)">text</b>');
+       expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
+         "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
+     });
+   </file>
+   </example>
+ */
+function $SanitizeProvider() {
+  this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
+    return function(html) {
+      var buf = [];
+      htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
+        return !/^unsafe/.test($$sanitizeUri(uri, isImage));
+      }));
+      return buf.join('');
+    };
+  }];
+}
+
+function sanitizeText(chars) {
+  var buf = [];
+  var writer = htmlSanitizeWriter(buf, angular.noop);
+  writer.chars(chars);
+  return buf.join('');
+}
+
+
+// Regular Expressions for parsing tags and attributes
+var START_TAG_REGEXP =
+       /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
+  END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
+  ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
+  BEGIN_TAG_REGEXP = /^</,
+  BEGING_END_TAGE_REGEXP = /^<\s*\//,
+  COMMENT_REGEXP = /<!--(.*?)-->/g,
+  DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
+  CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
+  // Match everything outside of normal chars and " (quote character)
+  NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
+
+
+// Good source of info about elements and attributes
+// http://dev.w3.org/html5/spec/Overview.html#semantics
+// http://simon.html5.org/html-elements
+
+// Safe Void Elements - HTML5
+// http://dev.w3.org/html5/spec/Overview.html#void-elements
+var voidElements = makeMap("area,br,col,hr,img,wbr");
+
+// Elements that you can, intentionally, leave open (and which close themselves)
+// http://dev.w3.org/html5/spec/Overview.html#optional-tags
+var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
+    optionalEndTagInlineElements = makeMap("rp,rt"),
+    optionalEndTagElements = angular.extend({},
+                                            optionalEndTagInlineElements,
+                                            optionalEndTagBlockElements);
+
+// Safe Block Elements - HTML5
+var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
+        "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
+        "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
+
+// Inline Elements - HTML5
+var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
+        "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
+        "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
+
+
+// Special Elements (can contain anything)
+var specialElements = makeMap("script,style");
+
+var validElements = angular.extend({},
+                                   voidElements,
+                                   blockElements,
+                                   inlineElements,
+                                   optionalEndTagElements);
+
+//Attributes that have href and hence need to be sanitized
+var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
+var validAttrs = angular.extend({}, uriAttrs, makeMap(
+    'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
+    'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
+    'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
+    'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
+    'valign,value,vspace,width'));
+
+function makeMap(str) {
+  var obj = {}, items = str.split(','), i;
+  for (i = 0; i < items.length; i++) obj[items[i]] = true;
+  return obj;
+}
+
+
+/**
+ * @example
+ * htmlParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+ *
+ * @param {string} html string
+ * @param {object} handler
+ */
+function htmlParser( html, handler ) {
+  var index, chars, match, stack = [], last = html;
+  stack.last = function() { return stack[ stack.length - 1 ]; };
+
+  while ( html ) {
+    chars = true;
+
+    // Make sure we're not in a script or style element
+    if ( !stack.last() || !specialElements[ stack.last() ] ) {
+
+      // Comment
+      if ( html.indexOf("<!--") === 0 ) {
+        // comments containing -- are not allowed unless they terminate the comment
+        index = html.indexOf("--", 4);
+
+        if ( index >= 0 && html.lastIndexOf("-->", index) === index) {
+          if (handler.comment) handler.comment( html.substring( 4, index ) );
+          html = html.substring( index + 3 );
+          chars = false;
+        }
+      // DOCTYPE
+      } else if ( DOCTYPE_REGEXP.test(html) ) {
+        match = html.match( DOCTYPE_REGEXP );
+
+        if ( match ) {
+          html = html.replace( match[0], '');
+          chars = false;
+        }
+      // end tag
+      } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
+        match = html.match( END_TAG_REGEXP );
+
+        if ( match ) {
+          html = html.substring( match[0].length );
+          match[0].replace( END_TAG_REGEXP, parseEndTag );
+          chars = false;
+        }
+
+      // start tag
+      } else if ( BEGIN_TAG_REGEXP.test(html) ) {
+        match = html.match( START_TAG_REGEXP );
+
+        if ( match ) {
+          html = html.substring( match[0].length );
+          match[0].replace( START_TAG_REGEXP, parseStartTag );
+          chars = false;
+        }
+      }
+
+      if ( chars ) {
+        index = html.indexOf("<");
+
+        var text = index < 0 ? html : html.substring( 0, index );
+        html = index < 0 ? "" : html.substring( index );
+
+        if (handler.chars) handler.chars( decodeEntities(text) );
+      }
+
+    } else {
+      html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
+        function(all, text){
+          text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
+
+          if (handler.chars) handler.chars( decodeEntities(text) );
+
+          return "";
+      });
+
+      parseEndTag( "", stack.last() );
+    }
+
+    if ( html == last ) {
+      throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
+                                        "of html: {0}", html);
+    }
+    last = html;
+  }
+
+  // Clean up any remaining tags
+  parseEndTag();
+
+  function parseStartTag( tag, tagName, rest, unary ) {
+    tagName = angular.lowercase(tagName);
+    if ( blockElements[ tagName ] ) {
+      while ( stack.last() && inlineElements[ stack.last() ] ) {
+        parseEndTag( "", stack.last() );
+      }
+    }
+
+    if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
+      parseEndTag( "", tagName );
+    }
+
+    unary = voidElements[ tagName ] || !!unary;
+
+    if ( !unary )
+      stack.push( tagName );
+
+    var attrs = {};
+
+    rest.replace(ATTR_REGEXP,
+      function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
+        var value = doubleQuotedValue
+          || singleQuotedValue
+          || unquotedValue
+          || '';
+
+        attrs[name] = decodeEntities(value);
+    });
+    if (handler.start) handler.start( tagName, attrs, unary );
+  }
+
+  function parseEndTag( tag, tagName ) {
+    var pos = 0, i;
+    tagName = angular.lowercase(tagName);
+    if ( tagName )
+      // Find the closest opened tag of the same type
+      for ( pos = stack.length - 1; pos >= 0; pos-- )
+        if ( stack[ pos ] == tagName )
+          break;
+
+    if ( pos >= 0 ) {
+      // Close all the open elements, up the stack
+      for ( i = stack.length - 1; i >= pos; i-- )
+        if (handler.end) handler.end( stack[ i ] );
+
+      // Remove the open elements from the stack
+      stack.length = pos;
+    }
+  }
+}
+
+var hiddenPre=document.createElement("pre");
+var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
+/**
+ * decodes all entities into regular string
+ * @param value
+ * @returns {string} A string with decoded entities.
+ */
+function decodeEntities(value) {
+  if (!value) { return ''; }
+
+  // Note: IE8 does not preserve spaces at the start/end of innerHTML
+  // so we must capture them and reattach them afterward
+  var parts = spaceRe.exec(value);
+  var spaceBefore = parts[1];
+  var spaceAfter = parts[3];
+  var content = parts[2];
+  if (content) {
+    hiddenPre.innerHTML=content.replace(/</g,"&lt;");
+    // innerText depends on styling as it doesn't display hidden elements.
+    // Therefore, it's better to use textContent not to cause unnecessary
+    // reflows. However, IE<9 don't support textContent so the innerText
+    // fallback is necessary.
+    content = 'textContent' in hiddenPre ?
+      hiddenPre.textContent : hiddenPre.innerText;
+  }
+  return spaceBefore + content + spaceAfter;
+}
+
+/**
+ * Escapes all potentially dangerous characters, so that the
+ * resulting string can be safely inserted into attribute or
+ * element text.
+ * @param value
+ * @returns {string} escaped text
+ */
+function encodeEntities(value) {
+  return value.
+    replace(/&/g, '&amp;').
+    replace(NON_ALPHANUMERIC_REGEXP, function(value){
+      return '&#' + value.charCodeAt(0) + ';';
+    }).
+    replace(/</g, '&lt;').
+    replace(/>/g, '&gt;');
+}
+
+/**
+ * create an HTML/XML writer which writes to buffer
+ * @param {Array} buf use buf.jain('') to get out sanitized html string
+ * @returns {object} in the form of {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * }
+ */
+function htmlSanitizeWriter(buf, uriValidator){
+  var ignore = false;
+  var out = angular.bind(buf, buf.push);
+  return {
+    start: function(tag, attrs, unary){
+      tag = angular.lowercase(tag);
+      if (!ignore && specialElements[tag]) {
+        ignore = tag;
+      }
+      if (!ignore && validElements[tag] === true) {
+        out('<');
+        out(tag);
+        angular.forEach(attrs, function(value, key){
+          var lkey=angular.lowercase(key);
+          var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
+          if (validAttrs[lkey] === true &&
+            (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
+            out(' ');
+            out(key);
+            out('="');
+            out(encodeEntities(value));
+            out('"');
+          }
+        });
+        out(unary ? '/>' : '>');
+      }
+    },
+    end: function(tag){
+        tag = angular.lowercase(tag);
+        if (!ignore && validElements[tag] === true) {
+          out('</');
+          out(tag);
+          out('>');
+        }
+        if (tag == ignore) {
+          ignore = false;
+        }
+      },
+    chars: function(chars){
+        if (!ignore) {
+          out(encodeEntities(chars));
+        }
+      }
+  };
+}
+
+
+// define ngSanitize module and register $sanitize service
+angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
+
+/* global sanitizeText: false */
+
+/**
+ * @ngdoc filter
+ * @name linky
+ * @function
+ *
+ * @description
+ * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
+ * plain email address links.
+ *
+ * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
+ *
+ * @param {string} text Input text.
+ * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
+ * @returns {string} Html-linkified text.
+ *
+ * @usage
+   <span ng-bind-html="linky_expression | linky"></span>
+ *
+ * @example
+   <example module="ngSanitize" deps="angular-sanitize.js">
+     <file name="index.html">
+       <script>
+         function Ctrl($scope) {
+           $scope.snippet =
+             'Pretty text with some links:\n'+
+             'http://angularjs.org/,\n'+
+             'mailto:us@somewhere.org,\n'+
+             'another@somewhere.org,\n'+
+             'and one more: ftp://127.0.0.1/.';
+           $scope.snippetWithTarget = 'http://angularjs.org/';
+         }
+       </script>
+       <div ng-controller="Ctrl">
+       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
+       <table>
+         <tr>
+           <td>Filter</td>
+           <td>Source</td>
+           <td>Rendered</td>
+         </tr>
+         <tr id="linky-filter">
+           <td>linky filter</td>
+           <td>
+             <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
+           </td>
+           <td>
+             <div ng-bind-html="snippet | linky"></div>
+           </td>
+         </tr>
+         <tr id="linky-target">
+          <td>linky target</td>
+          <td>
+            <pre>&lt;div ng-bind-html="snippetWithTarget | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
+          </td>
+          <td>
+            <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
+          </td>
+         </tr>
+         <tr id="escaped-html">
+           <td>no filter</td>
+           <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
+           <td><div ng-bind="snippet"></div></td>
+         </tr>
+       </table>
+     </file>
+     <file name="protractor.js" type="protractor">
+       it('should linkify the snippet with urls', function() {
+         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+             toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
+                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+         expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
+       });
+
+       it('should not linkify snippet without the linky filter', function() {
+         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
+             toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
+                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+         expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
+       });
+
+       it('should update', function() {
+         element(by.model('snippet')).clear();
+         element(by.model('snippet')).sendKeys('new http://link.');
+         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+             toBe('new http://link.');
+         expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
+         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
+             .toBe('new http://link.');
+       });
+
+       it('should work with the target property', function() {
+        expect(element(by.id('linky-target')).
+            element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
+            toBe('http://angularjs.org/');
+        expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
+       });
+     </file>
+   </example>
+ */
+angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
+  var LINKY_URL_REGEXP =
+        /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
+      MAILTO_REGEXP = /^mailto:/;
+
+  return function(text, target) {
+    if (!text) return text;
+    var match;
+    var raw = text;
+    var html = [];
+    var url;
+    var i;
+    while ((match = raw.match(LINKY_URL_REGEXP))) {
+      // We can not end in these as they are sometimes found at the end of the sentence
+      url = match[0];
+      // if we did not match ftp/http/mailto then assume mailto
+      if (match[2] == match[3]) url = 'mailto:' + url;
+      i = match.index;
+      addText(raw.substr(0, i));
+      addLink(url, match[0].replace(MAILTO_REGEXP, ''));
+      raw = raw.substring(i + match[0].length);
+    }
+    addText(raw);
+    return $sanitize(html.join(''));
+
+    function addText(text) {
+      if (!text) {
+        return;
+      }
+      html.push(sanitizeText(text));
+    }
+
+    function addLink(url, text) {
+      html.push('<a ');
+      if (angular.isDefined(target)) {
+        html.push('target="');
+        html.push(target);
+        html.push('" ');
+      }
+      html.push('href="');
+      html.push(url);
+      html.push('">');
+      addText(text);
+      html.push('</a>');
+    }
+  };
+}]);
+
+
+})(window, window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-touch.js b/src/main/resources/META-INF/resources/designer/lib/angular-touch.js
new file mode 100644 (file)
index 0000000..8d16019
--- /dev/null
@@ -0,0 +1,584 @@
+/**
+ * @license AngularJS v1.2.26
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngTouch
+ * @description
+ *
+ * # ngTouch
+ *
+ * The `ngTouch` module provides touch events and other helpers for touch-enabled devices.
+ * The implementation is based on jQuery Mobile touch event handling
+ * ([jquerymobile.com](http://jquerymobile.com/)).
+ *
+ *
+ * See {@link ngTouch.$swipe `$swipe`} for usage.
+ *
+ * <div doc-module-components="ngTouch"></div>
+ *
+ */
+
+// define ngTouch module
+/* global -ngTouch */
+var ngTouch = angular.module('ngTouch', []);
+
+/* global ngTouch: false */
+
+    /**
+     * @ngdoc service
+     * @name $swipe
+     *
+     * @description
+     * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe
+     * behavior, to make implementing swipe-related directives more convenient.
+     *
+     * Requires the {@link ngTouch `ngTouch`} module to be installed.
+     *
+     * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by
+     * `ngCarousel` in a separate component.
+     *
+     * # Usage
+     * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element
+     * which is to be watched for swipes, and an object with four handler functions. See the
+     * documentation for `bind` below.
+     */
+
+ngTouch.factory('$swipe', [function() {
+  // The total distance in any direction before we make the call on swipe vs. scroll.
+  var MOVE_BUFFER_RADIUS = 10;
+
+  function getCoordinates(event) {
+    var touches = event.touches && event.touches.length ? event.touches : [event];
+    var e = (event.changedTouches && event.changedTouches[0]) ||
+        (event.originalEvent && event.originalEvent.changedTouches &&
+            event.originalEvent.changedTouches[0]) ||
+        touches[0].originalEvent || touches[0];
+
+    return {
+      x: e.clientX,
+      y: e.clientY
+    };
+  }
+
+  return {
+    /**
+     * @ngdoc method
+     * @name $swipe#bind
+     *
+     * @description
+     * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
+     * object containing event handlers.
+     *
+     * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
+     * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
+     *
+     * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is
+     * watching for `touchmove` or `mousemove` events. These events are ignored until the total
+     * distance moved in either dimension exceeds a small threshold.
+     *
+     * Once this threshold is exceeded, either the horizontal or vertical delta is greater.
+     * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
+     * - If the vertical distance is greater, this is a scroll, and we let the browser take over.
+     *   A `cancel` event is sent.
+     *
+     * `move` is called on `mousemove` and `touchmove` after the above logic has determined that
+     * a swipe is in progress.
+     *
+     * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`.
+     *
+     * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling
+     * as described above.
+     *
+     */
+    bind: function(element, eventHandlers) {
+      // Absolute total movement, used to control swipe vs. scroll.
+      var totalX, totalY;
+      // Coordinates of the start position.
+      var startCoords;
+      // Last event's position.
+      var lastPos;
+      // Whether a swipe is active.
+      var active = false;
+
+      element.on('touchstart mousedown', function(event) {
+        startCoords = getCoordinates(event);
+        active = true;
+        totalX = 0;
+        totalY = 0;
+        lastPos = startCoords;
+        eventHandlers['start'] && eventHandlers['start'](startCoords, event);
+      });
+
+      element.on('touchcancel', function(event) {
+        active = false;
+        eventHandlers['cancel'] && eventHandlers['cancel'](event);
+      });
+
+      element.on('touchmove mousemove', function(event) {
+        if (!active) return;
+
+        // Android will send a touchcancel if it thinks we're starting to scroll.
+        // So when the total distance (+ or - or both) exceeds 10px in either direction,
+        // we either:
+        // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
+        // - On totalY > totalX, we let the browser handle it as a scroll.
+
+        if (!startCoords) return;
+        var coords = getCoordinates(event);
+
+        totalX += Math.abs(coords.x - lastPos.x);
+        totalY += Math.abs(coords.y - lastPos.y);
+
+        lastPos = coords;
+
+        if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
+          return;
+        }
+
+        // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
+        if (totalY > totalX) {
+          // Allow native scrolling to take over.
+          active = false;
+          eventHandlers['cancel'] && eventHandlers['cancel'](event);
+          return;
+        } else {
+          // Prevent the browser from scrolling.
+          event.preventDefault();
+          eventHandlers['move'] && eventHandlers['move'](coords, event);
+        }
+      });
+
+      element.on('touchend mouseup', function(event) {
+        if (!active) return;
+        active = false;
+        eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
+      });
+    }
+  };
+}]);
+
+/* global ngTouch: false */
+
+/**
+ * @ngdoc directive
+ * @name ngClick
+ *
+ * @description
+ * A more powerful replacement for the default ngClick designed to be used on touchscreen
+ * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
+ * the click event. This version handles them immediately, and then prevents the
+ * following click event from propagating.
+ *
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
+ * This directive can fall back to using an ordinary click event, and so works on desktop
+ * browsers as well as mobile.
+ *
+ * This directive also sets the CSS class `ng-click-active` while the element is being held
+ * down (by a mouse click or touch) so you can restyle the depressed element if you wish.
+ *
+ * @element ANY
+ * @param {expression} ngClick {@link guide/expression Expression} to evaluate
+ * upon tap. (Event object is available as `$event`)
+ *
+ * @example
+    <example module="ngClickExample" deps="angular-touch.js">
+      <file name="index.html">
+        <button ng-click="count = count + 1" ng-init="count=0">
+          Increment
+        </button>
+        count: {{ count }}
+      </file>
+      <file name="script.js">
+        angular.module('ngClickExample', ['ngTouch']);
+      </file>
+    </example>
+ */
+
+ngTouch.config(['$provide', function($provide) {
+  $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
+    // drop the default ngClick directive
+    $delegate.shift();
+    return $delegate;
+  }]);
+}]);
+
+ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
+    function($parse, $timeout, $rootElement) {
+  var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag.
+  var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
+  var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click
+  var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks.
+
+  var ACTIVE_CLASS_NAME = 'ng-click-active';
+  var lastPreventedTime;
+  var touchCoordinates;
+  var lastLabelClickCoordinates;
+
+
+  // TAP EVENTS AND GHOST CLICKS
+  //
+  // Why tap events?
+  // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're
+  // double-tapping, and then fire a click event.
+  //
+  // This delay sucks and makes mobile apps feel unresponsive.
+  // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when
+  // the user has tapped on something.
+  //
+  // What happens when the browser then generates a click event?
+  // The browser, of course, also detects the tap and fires a click after a delay. This results in
+  // tapping/clicking twice. We do "clickbusting" to prevent it.
+  //
+  // How does it work?
+  // We attach global touchstart and click handlers, that run during the capture (early) phase.
+  // So the sequence for a tap is:
+  // - global touchstart: Sets an "allowable region" at the point touched.
+  // - element's touchstart: Starts a touch
+  // (- touchmove or touchcancel ends the touch, no click follows)
+  // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold
+  //   too long) and fires the user's tap handler. The touchend also calls preventGhostClick().
+  // - preventGhostClick() removes the allowable region the global touchstart created.
+  // - The browser generates a click event.
+  // - The global click handler catches the click, and checks whether it was in an allowable region.
+  //     - If preventGhostClick was called, the region will have been removed, the click is busted.
+  //     - If the region is still there, the click proceeds normally. Therefore clicks on links and
+  //       other elements without ngTap on them work normally.
+  //
+  // This is an ugly, terrible hack!
+  // Yeah, tell me about it. The alternatives are using the slow click events, or making our users
+  // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular
+  // encapsulates this ugly logic away from the user.
+  //
+  // Why not just put click handlers on the element?
+  // We do that too, just to be sure. If the tap event caused the DOM to change,
+  // it is possible another element is now in that position. To take account for these possibly
+  // distinct elements, the handlers are global and care only about coordinates.
+
+  // Checks if the coordinates are close enough to be within the region.
+  function hit(x1, y1, x2, y2) {
+    return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD;
+  }
+
+  // Checks a list of allowable regions against a click location.
+  // Returns true if the click should be allowed.
+  // Splices out the allowable region from the list after it has been used.
+  function checkAllowableRegions(touchCoordinates, x, y) {
+    for (var i = 0; i < touchCoordinates.length; i += 2) {
+      if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) {
+        touchCoordinates.splice(i, i + 2);
+        return true; // allowable region
+      }
+    }
+    return false; // No allowable region; bust it.
+  }
+
+  // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick
+  // was called recently.
+  function onClick(event) {
+    if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
+      return; // Too old.
+    }
+
+    var touches = event.touches && event.touches.length ? event.touches : [event];
+    var x = touches[0].clientX;
+    var y = touches[0].clientY;
+    // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label
+    // and on the input element). Depending on the exact browser, this second click we don't want
+    // to bust has either (0,0), negative coordinates, or coordinates equal to triggering label
+    // click event
+    if (x < 1 && y < 1) {
+      return; // offscreen
+    }
+    if (lastLabelClickCoordinates &&
+        lastLabelClickCoordinates[0] === x && lastLabelClickCoordinates[1] === y) {
+      return; // input click triggered by label click
+    }
+    // reset label click coordinates on first subsequent click
+    if (lastLabelClickCoordinates) {
+      lastLabelClickCoordinates = null;
+    }
+    // remember label click coordinates to prevent click busting of trigger click event on input
+    if (event.target.tagName.toLowerCase() === 'label') {
+      lastLabelClickCoordinates = [x, y];
+    }
+
+    // Look for an allowable region containing this click.
+    // If we find one, that means it was created by touchstart and not removed by
+    // preventGhostClick, so we don't bust it.
+    if (checkAllowableRegions(touchCoordinates, x, y)) {
+      return;
+    }
+
+    // If we didn't find an allowable region, bust the click.
+    event.stopPropagation();
+    event.preventDefault();
+
+    // Blur focused form elements
+    event.target && event.target.blur();
+  }
+
+
+  // Global touchstart handler that creates an allowable region for a click event.
+  // This allowable region can be removed by preventGhostClick if we want to bust it.
+  function onTouchStart(event) {
+    var touches = event.touches && event.touches.length ? event.touches : [event];
+    var x = touches[0].clientX;
+    var y = touches[0].clientY;
+    touchCoordinates.push(x, y);
+
+    $timeout(function() {
+      // Remove the allowable region.
+      for (var i = 0; i < touchCoordinates.length; i += 2) {
+        if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) {
+          touchCoordinates.splice(i, i + 2);
+          return;
+        }
+      }
+    }, PREVENT_DURATION, false);
+  }
+
+  // On the first call, attaches some event handlers. Then whenever it gets called, it creates a
+  // zone around the touchstart where clicks will get busted.
+  function preventGhostClick(x, y) {
+    if (!touchCoordinates) {
+      $rootElement[0].addEventListener('click', onClick, true);
+      $rootElement[0].addEventListener('touchstart', onTouchStart, true);
+      touchCoordinates = [];
+    }
+
+    lastPreventedTime = Date.now();
+
+    checkAllowableRegions(touchCoordinates, x, y);
+  }
+
+  // Actual linking function.
+  return function(scope, element, attr) {
+    var clickHandler = $parse(attr.ngClick),
+        tapping = false,
+        tapElement,  // Used to blur the element after a tap.
+        startTime,   // Used to check if the tap was held too long.
+        touchStartX,
+        touchStartY;
+
+    function resetState() {
+      tapping = false;
+      element.removeClass(ACTIVE_CLASS_NAME);
+    }
+
+    element.on('touchstart', function(event) {
+      tapping = true;
+      tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
+      // Hack for Safari, which can target text nodes instead of containers.
+      if(tapElement.nodeType == 3) {
+        tapElement = tapElement.parentNode;
+      }
+
+      element.addClass(ACTIVE_CLASS_NAME);
+
+      startTime = Date.now();
+
+      var touches = event.touches && event.touches.length ? event.touches : [event];
+      var e = touches[0].originalEvent || touches[0];
+      touchStartX = e.clientX;
+      touchStartY = e.clientY;
+    });
+
+    element.on('touchmove', function(event) {
+      resetState();
+    });
+
+    element.on('touchcancel', function(event) {
+      resetState();
+    });
+
+    element.on('touchend', function(event) {
+      var diff = Date.now() - startTime;
+
+      var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches :
+          ((event.touches && event.touches.length) ? event.touches : [event]);
+      var e = touches[0].originalEvent || touches[0];
+      var x = e.clientX;
+      var y = e.clientY;
+      var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) );
+
+      if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
+        // Call preventGhostClick so the clickbuster will catch the corresponding click.
+        preventGhostClick(x, y);
+
+        // Blur the focused element (the button, probably) before firing the callback.
+        // This doesn't work perfectly on Android Chrome, but seems to work elsewhere.
+        // I couldn't get anything to work reliably on Android Chrome.
+        if (tapElement) {
+          tapElement.blur();
+        }
+
+        if (!angular.isDefined(attr.disabled) || attr.disabled === false) {
+          element.triggerHandler('click', [event]);
+        }
+      }
+
+      resetState();
+    });
+
+    // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
+    // something else nearby.
+    element.onclick = function(event) { };
+
+    // Actual click handler.
+    // There are three different kinds of clicks, only two of which reach this point.
+    // - On desktop browsers without touch events, their clicks will always come here.
+    // - On mobile browsers, the simulated "fast" click will call this.
+    // - But the browser's follow-up slow click will be "busted" before it reaches this handler.
+    // Therefore it's safe to use this directive on both mobile and desktop.
+    element.on('click', function(event, touchend) {
+      scope.$apply(function() {
+        clickHandler(scope, {$event: (touchend || event)});
+      });
+    });
+
+    element.on('mousedown', function(event) {
+      element.addClass(ACTIVE_CLASS_NAME);
+    });
+
+    element.on('mousemove mouseup', function(event) {
+      element.removeClass(ACTIVE_CLASS_NAME);
+    });
+
+  };
+}]);
+
+/* global ngTouch: false */
+
+/**
+ * @ngdoc directive
+ * @name ngSwipeLeft
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the left on a touchscreen device.
+ * A leftward swipe is a quick, right-to-left slide of the finger.
+ * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag
+ * too.
+ *
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
+ * upon left swipe. (Event object is available as `$event`)
+ *
+ * @example
+    <example module="ngSwipeLeftExample" deps="angular-touch.js">
+      <file name="index.html">
+        <div ng-show="!showActions" ng-swipe-left="showActions = true">
+          Some list content, like an email in the inbox
+        </div>
+        <div ng-show="showActions" ng-swipe-right="showActions = false">
+          <button ng-click="reply()">Reply</button>
+          <button ng-click="delete()">Delete</button>
+        </div>
+      </file>
+      <file name="script.js">
+        angular.module('ngSwipeLeftExample', ['ngTouch']);
+      </file>
+    </example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngSwipeRight
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the right on a touchscreen device.
+ * A rightward swipe is a quick, left-to-right slide of the finger.
+ * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag
+ * too.
+ *
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
+ * upon right swipe. (Event object is available as `$event`)
+ *
+ * @example
+    <example module="ngSwipeRightExample" deps="angular-touch.js">
+      <file name="index.html">
+        <div ng-show="!showActions" ng-swipe-left="showActions = true">
+          Some list content, like an email in the inbox
+        </div>
+        <div ng-show="showActions" ng-swipe-right="showActions = false">
+          <button ng-click="reply()">Reply</button>
+          <button ng-click="delete()">Delete</button>
+        </div>
+      </file>
+      <file name="script.js">
+        angular.module('ngSwipeRightExample', ['ngTouch']);
+      </file>
+    </example>
+ */
+
+function makeSwipeDirective(directiveName, direction, eventName) {
+  ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
+    // The maximum vertical delta for a swipe should be less than 75px.
+    var MAX_VERTICAL_DISTANCE = 75;
+    // Vertical distance should not be more than a fraction of the horizontal distance.
+    var MAX_VERTICAL_RATIO = 0.3;
+    // At least a 30px lateral motion is necessary for a swipe.
+    var MIN_HORIZONTAL_DISTANCE = 30;
+
+    return function(scope, element, attr) {
+      var swipeHandler = $parse(attr[directiveName]);
+
+      var startCoords, valid;
+
+      function validSwipe(coords) {
+        // Check that it's within the coordinates.
+        // Absolute vertical distance must be within tolerances.
+        // Horizontal distance, we take the current X - the starting X.
+        // This is negative for leftward swipes and positive for rightward swipes.
+        // After multiplying by the direction (-1 for left, +1 for right), legal swipes
+        // (ie. same direction as the directive wants) will have a positive delta and
+        // illegal ones a negative delta.
+        // Therefore this delta must be positive, and larger than the minimum.
+        if (!startCoords) return false;
+        var deltaY = Math.abs(coords.y - startCoords.y);
+        var deltaX = (coords.x - startCoords.x) * direction;
+        return valid && // Short circuit for already-invalidated swipes.
+            deltaY < MAX_VERTICAL_DISTANCE &&
+            deltaX > 0 &&
+            deltaX > MIN_HORIZONTAL_DISTANCE &&
+            deltaY / deltaX < MAX_VERTICAL_RATIO;
+      }
+
+      $swipe.bind(element, {
+        'start': function(coords, event) {
+          startCoords = coords;
+          valid = true;
+        },
+        'cancel': function(event) {
+          valid = false;
+        },
+        'end': function(coords, event) {
+          if (validSwipe(coords)) {
+            scope.$apply(function() {
+              element.triggerHandler(eventName);
+              swipeHandler(scope, {$event: event});
+            });
+          }
+        }
+      });
+    };
+  }]);
+}
+
+// Left is negative X-coordinate, right is positive.
+makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
+makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
+
+
+
+})(window, window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js b/src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js
new file mode 100644 (file)
index 0000000..5665a3c
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ AngularJS v1.2.16
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(y,w,z){'use strict';function u(f,a,c){r.directive(f,["$parse","$swipe",function(m,p){var q=75,g=0.3,e=30;return function(h,n,l){function k(d){if(!b)return!1;var s=Math.abs(d.y-b.y);d=(d.x-b.x)*a;return v&&s<q&&0<d&&d>e&&s/d<g}var s=m(l[f]),b,v;p.bind(n,{start:function(d,s){b=d;v=!0},cancel:function(b){v=!1},end:function(b,a){k(b)&&h.$apply(function(){n.triggerHandler(c);s(h,{$event:a})})}})}}])}var r=w.module("ngTouch",[]);r.factory("$swipe",[function(){function f(a){var c=a.touches&&a.touches.length?
+a.touches:[a];a=a.changedTouches&&a.changedTouches[0]||a.originalEvent&&a.originalEvent.changedTouches&&a.originalEvent.changedTouches[0]||c[0].originalEvent||c[0];return{x:a.clientX,y:a.clientY}}return{bind:function(a,c){var m,p,q,g,e=!1;a.on("touchstart mousedown",function(a){q=f(a);e=!0;p=m=0;g=q;c.start&&c.start(q,a)});a.on("touchcancel",function(a){e=!1;c.cancel&&c.cancel(a)});a.on("touchmove mousemove",function(a){if(e&&q){var n=f(a);m+=Math.abs(n.x-g.x);p+=Math.abs(n.y-g.y);g=n;10>m&&10>p||
+(p>m?(e=!1,c.cancel&&c.cancel(a)):(a.preventDefault(),c.move&&c.move(n,a)))}});a.on("touchend mouseup",function(a){e&&(e=!1,c.end&&c.end(f(a),a))})}}}]);r.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);r.directive("ngClick",["$parse","$timeout","$rootElement",function(f,a,c){function m(a,b,c){for(var d=0;d<a.length;d+=2)if(Math.abs(a[d]-b)<e&&Math.abs(a[d+1]-c)<e)return a.splice(d,d+2),!0;return!1}function p(a){if(!(Date.now()-n>g)){var b=
+a.touches&&a.touches.length?a.touches:[a],c=b[0].clientX,b=b[0].clientY;1>c&&1>b||k&&k[0]===c&&k[1]===b||(k&&(k=null),"label"===a.target.tagName.toLowerCase()&&(k=[c,b]),m(l,c,b)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur()))}}function q(c){c=c.touches&&c.touches.length?c.touches:[c];var b=c[0].clientX,e=c[0].clientY;l.push(b,e);a(function(){for(var a=0;a<l.length;a+=2)if(l[a]==b&&l[a+1]==e){l.splice(a,a+2);break}},g,!1)}var g=2500,e=25,h="ng-click-active",n,l,k;return function(a,
+b,e){function d(){k=!1;b.removeClass(h)}var g=f(e.ngClick),k=!1,t,r,u,x;b.on("touchstart",function(a){k=!0;t=a.target?a.target:a.srcElement;3==t.nodeType&&(t=t.parentNode);b.addClass(h);r=Date.now();a=a.touches&&a.touches.length?a.touches:[a];a=a[0].originalEvent||a[0];u=a.clientX;x=a.clientY});b.on("touchmove",function(a){d()});b.on("touchcancel",function(a){d()});b.on("touchend",function(a){var g=Date.now()-r,f=a.changedTouches&&a.changedTouches.length?a.changedTouches:a.touches&&a.touches.length?
+a.touches:[a],h=f[0].originalEvent||f[0],f=h.clientX,h=h.clientY,s=Math.sqrt(Math.pow(f-u,2)+Math.pow(h-x,2));k&&(750>g&&12>s)&&(l||(c[0].addEventListener("click",p,!0),c[0].addEventListener("touchstart",q,!0),l=[]),n=Date.now(),m(l,f,h),t&&t.blur(),w.isDefined(e.disabled)&&!1!==e.disabled||b.triggerHandler("click",[a]));d()});b.onclick=function(a){};b.on("click",function(b,c){a.$apply(function(){g(a,{$event:c||b})})});b.on("mousedown",function(a){b.addClass(h)});b.on("mousemove mouseup",function(a){b.removeClass(h)})}}]);
+u("ngSwipeLeft",-1,"swipeleft");u("ngSwipeRight",1,"swiperight")})(window,window.angular);
+//# sourceMappingURL=angular-touch.min.js.map
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js.map b/src/main/resources/META-INF/resources/designer/lib/angular-touch.min.js.map
new file mode 100644 (file)
index 0000000..e26dfa8
--- /dev/null
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular-touch.min.js",
+"lineCount":12,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAsgBtCC,QAASA,EAAkB,CAACC,CAAD,CAAgBC,CAAhB,CAA2BC,CAA3B,CAAsC,CAC/DC,CAAAC,UAAA,CAAkBJ,CAAlB,CAAiC,CAAC,QAAD,CAAW,QAAX,CAAqB,QAAQ,CAACK,CAAD,CAASC,CAAT,CAAiB,CAE7E,IAAIC,EAAwB,EAA5B,CAEIC,EAAqB,GAFzB,CAIIC,EAA0B,EAE9B,OAAO,SAAQ,CAACC,CAAD,CAAQC,CAAR,CAAiBC,CAAjB,CAAuB,CAKpCC,QAASA,EAAU,CAACC,CAAD,CAAS,CAS1B,GAAI,CAACC,CAAL,CAAkB,MAAO,CAAA,CACzB,KAAIC,EAASC,IAAAC,IAAA,CAASJ,CAAAK,EAAT,CAAoBJ,CAAAI,EAApB,CACTC,EAAAA,EAAUN,CAAAO,EAAVD,CAAqBL,CAAAM,EAArBD,EAAsCnB,CAC1C,OAAOqB,EAAP,EACIN,CADJ,CACaT,CADb,EAEa,CAFb,CAEIa,CAFJ,EAGIA,CAHJ,CAGaX,CAHb,EAIIO,CAJJ,CAIaI,CAJb,CAIsBZ,CAhBI,CAJ5B,IAAIe,EAAelB,CAAA,CAAOO,CAAA,CAAKZ,CAAL,CAAP,CAAnB,CAEIe,CAFJ,CAEiBO,CAqBjBhB,EAAAkB,KAAA,CAAYb,CAAZ,CAAqB,OACVc,QAAQ,CAACX,CAAD,CAASY,CAAT,CAAgB,CAC/BX,CAAA,CAAcD,CACdQ,EAAA,CAAQ,CAAA,CAFuB,CADd,QAKTK,QAAQ,CAACD,CAAD,CAAQ,CACxBJ,CAAA,CAAQ,CAAA,CADgB,CALP,KAQZM,QAAQ,CAACd,CAAD,CAASY,CAAT,CAAgB,CACzBb,CAAA,CAAWC,CAAX,CAAJ,EACEJ,CAAAmB,OAAA,CAAa,QAAQ,EAAG,CACtBlB,CAAAmB,eAAA,CAAuB5B,CAAvB,CACAqB,EAAA,CAAab,CAAb,CAAoB,QAASgB,CAAT,CAApB,CAFsB,CAAxB,CAF2B,CARZ,CAArB,CAxBoC,CARuC,CAA9C,CAAjC,CAD+D,CAhfjE,IAAIvB,EAAUN,CAAAkC,OAAA,CAAe,SAAf,CAA0B,EAA1B,CAuBd5B,EAAA6B,QAAA,CAAgB,QAAhB,CAA0B,CAAC,QAAQ,EAAG,CAIpCC,QAASA,EAAc,CAACP,CAAD,CAAQ,CAC7B,IAAIQ,EAAUR,CAAAQ,QAAA,EAAiBR,CAAAQ,QAAAC,OAAjB;AAAwCT,CAAAQ,QAAxC,CAAwD,CAACR,CAAD,CAClEU,EAAAA,CAAKV,CAAAW,eAALD,EAA6BV,CAAAW,eAAA,CAAqB,CAArB,CAA7BD,EACCV,CAAAY,cADDF,EACwBV,CAAAY,cAAAD,eADxBD,EAEIV,CAAAY,cAAAD,eAAA,CAAmC,CAAnC,CAFJD,EAGAF,CAAA,CAAQ,CAAR,CAAAI,cAHAF,EAG4BF,CAAA,CAAQ,CAAR,CAEhC,OAAO,GACFE,CAAAG,QADE,GAEFH,CAAAI,QAFE,CAPsB,CAa/B,MAAO,MA8BChB,QAAQ,CAACb,CAAD,CAAU8B,CAAV,CAAyB,CAAA,IAEjCC,CAFiC,CAEzBC,CAFyB,CAIjC5B,CAJiC,CAMjC6B,CANiC,CAQjCC,EAAS,CAAA,CAEblC,EAAAmC,GAAA,CAAW,sBAAX,CAAmC,QAAQ,CAACpB,CAAD,CAAQ,CACjDX,CAAA,CAAckB,CAAA,CAAeP,CAAf,CACdmB,EAAA,CAAS,CAAA,CAETF,EAAA,CADAD,CACA,CADS,CAETE,EAAA,CAAU7B,CACV0B,EAAA,MAAA,EAA0BA,CAAA,MAAA,CAAuB1B,CAAvB,CAAoCW,CAApC,CANuB,CAAnD,CASAf,EAAAmC,GAAA,CAAW,aAAX,CAA0B,QAAQ,CAACpB,CAAD,CAAQ,CACxCmB,CAAA,CAAS,CAAA,CACTJ,EAAA,OAAA,EAA2BA,CAAA,OAAA,CAAwBf,CAAxB,CAFa,CAA1C,CAKAf,EAAAmC,GAAA,CAAW,qBAAX,CAAkC,QAAQ,CAACpB,CAAD,CAAQ,CAChD,GAAKmB,CAAL,EAQK9B,CARL,CAQA,CACA,IAAID,EAASmB,CAAA,CAAeP,CAAf,CAEbgB,EAAA,EAAUzB,IAAAC,IAAA,CAASJ,CAAAO,EAAT,CAAoBuB,CAAAvB,EAApB,CACVsB,EAAA,EAAU1B,IAAAC,IAAA,CAASJ,CAAAK,EAAT,CAAoByB,CAAAzB,EAApB,CAEVyB,EAAA,CAAU9B,CApFSiC,GAsFnB,CAAIL,CAAJ,EAtFmBK,EAsFnB,CAAmCJ,CAAnC;CAKIA,CAAJ,CAAaD,CAAb,EAEEG,CACA,CADS,CAAA,CACT,CAAAJ,CAAA,OAAA,EAA2BA,CAAA,OAAA,CAAwBf,CAAxB,CAH7B,GAOEA,CAAAsB,eAAA,EACA,CAAAP,CAAA,KAAA,EAAyBA,CAAA,KAAA,CAAsB3B,CAAtB,CAA8BY,CAA9B,CAR3B,CALA,CARA,CATgD,CAAlD,CAkCAf,EAAAmC,GAAA,CAAW,kBAAX,CAA+B,QAAQ,CAACpB,CAAD,CAAQ,CACxCmB,CAAL,GACAA,CACA,CADS,CAAA,CACT,CAAAJ,CAAA,IAAA,EAAwBA,CAAA,IAAA,CAAqBR,CAAA,CAAeP,CAAf,CAArB,CAA4CA,CAA5C,CAFxB,CAD6C,CAA/C,CA1DqC,CA9BlC,CAjB6B,CAAZ,CAA1B,CAwJAvB,EAAA8C,OAAA,CAAe,CAAC,UAAD,CAAa,QAAQ,CAACC,CAAD,CAAW,CAC7CA,CAAAC,UAAA,CAAmB,kBAAnB,CAAuC,CAAC,WAAD,CAAc,QAAQ,CAACC,CAAD,CAAY,CAEvEA,CAAAC,MAAA,EACA,OAAOD,EAHgE,CAAlC,CAAvC,CAD6C,CAAhC,CAAf,CAQAjD,EAAAC,UAAA,CAAkB,SAAlB,CAA6B,CAAC,QAAD,CAAW,UAAX,CAAuB,cAAvB,CACzB,QAAQ,CAACC,CAAD,CAASiD,CAAT,CAAmBC,CAAnB,CAAiC,CA2D3CC,QAASA,EAAqB,CAACC,CAAD,CAAmBpC,CAAnB,CAAsBF,CAAtB,CAAyB,CACrD,IAAK,IAAIuC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBD,CAAAtB,OAApB,CAA6CuB,CAA7C,EAAkD,CAAlD,CACE,GARKzC,IAAAC,IAAA,CAQGuC,CAAAE,CAAiBD,CAAjBC,CARH,CAQ+CtC,CAR/C,CAQL,CARyBuC,CAQzB,EARkD3C,IAAAC,IAAA,CAQrBuC,CAAAI,CAAiBH,CAAjBG,CAAmB,CAAnBA,CARqB,CAQK1C,CARL,CAQlD,CARsEyC,CAQtE,CAEE,MADAH,EAAAK,OAAA,CAAwBJ,CAAxB,CAA2BA,CAA3B,CAA+B,CAA/B,CACO,CAAA,CAAA,CAGX,OAAO,CAAA,CAP8C,CAYvDK,QAASA,EAAO,CAACrC,CAAD,CAAQ,CACtB,GAAI,EAAAsC,IAAAC,IAAA,EAAA,CAAaC,CAAb,CAAiCC,CAAjC,CAAJ,CAAA,CAIA,IAAIjC;AAAUR,CAAAQ,QAAA,EAAiBR,CAAAQ,QAAAC,OAAjB,CAAwCT,CAAAQ,QAAxC,CAAwD,CAACR,CAAD,CAAtE,CACIL,EAAIa,CAAA,CAAQ,CAAR,CAAAK,QADR,CAEIpB,EAAIe,CAAA,CAAQ,CAAR,CAAAM,QAKA,EAAR,CAAInB,CAAJ,EAAiB,CAAjB,CAAaF,CAAb,EAGIiD,CAHJ,EAIIA,CAAA,CAA0B,CAA1B,CAJJ,GAIqC/C,CAJrC,EAI0C+C,CAAA,CAA0B,CAA1B,CAJ1C,GAI2EjD,CAJ3E,GAQIiD,CAWJ,GAVEA,CAUF,CAV8B,IAU9B,EAP2C,OAO3C,GAPI1C,CAAA2C,OAAAC,QAAAC,YAAA,EAOJ,GANEH,CAMF,CAN8B,CAAC/C,CAAD,CAAIF,CAAJ,CAM9B,EAAIqC,CAAA,CAAsBC,CAAtB,CAAwCpC,CAAxC,CAA2CF,CAA3C,CAAJ,GAKAO,CAAA8C,gBAAA,EAIA,CAHA9C,CAAAsB,eAAA,EAGA,CAAAtB,CAAA2C,OAAA,EAAgB3C,CAAA2C,OAAAI,KAAA,EAThB,CAnBA,CAXA,CADsB,CA8CxBC,QAASA,EAAY,CAAChD,CAAD,CAAQ,CACvBQ,CAAAA,CAAUR,CAAAQ,QAAA,EAAiBR,CAAAQ,QAAAC,OAAjB,CAAwCT,CAAAQ,QAAxC,CAAwD,CAACR,CAAD,CACtE,KAAIL,EAAIa,CAAA,CAAQ,CAAR,CAAAK,QAAR,CACIpB,EAAIe,CAAA,CAAQ,CAAR,CAAAM,QACRiB,EAAAkB,KAAA,CAAsBtD,CAAtB,CAAyBF,CAAzB,CAEAmC,EAAA,CAAS,QAAQ,EAAG,CAElB,IAAK,IAAII,EAAI,CAAb,CAAgBA,CAAhB,CAAoBD,CAAAtB,OAApB,CAA6CuB,CAA7C,EAAkD,CAAlD,CACE,GAAID,CAAA,CAAiBC,CAAjB,CAAJ,EAA2BrC,CAA3B,EAAgCoC,CAAA,CAAiBC,CAAjB,CAAmB,CAAnB,CAAhC,EAAyDvC,CAAzD,CAA4D,CAC1DsC,CAAAK,OAAA,CAAwBJ,CAAxB,CAA2BA,CAA3B,CAA+B,CAA/B,CACA,MAF0D,CAH5C,CAApB,CAQGS,CARH,CAQqB,CAAA,CARrB,CAN2B,CAlH7B,IAAIA,EAAmB,IAAvB,CACIP,EAAwB,EAD5B,CAGIgB,EAAoB,iBAHxB,CAIIV,CAJJ,CAKIT,CALJ,CAMIW,CA4IJ,OAAO,SAAQ,CAAC1D,CAAD;AAAQC,CAAR,CAAiBC,CAAjB,CAAuB,CAQpCiE,QAASA,EAAU,EAAG,CACpBC,CAAA,CAAU,CAAA,CACVnE,EAAAoE,YAAA,CAAoBH,CAApB,CAFoB,CARc,IAChCI,EAAe3E,CAAA,CAAOO,CAAAqE,QAAP,CADiB,CAEhCH,EAAU,CAAA,CAFsB,CAGhCI,CAHgC,CAIhCC,CAJgC,CAKhCC,CALgC,CAMhCC,CAOJ1E,EAAAmC,GAAA,CAAW,YAAX,CAAyB,QAAQ,CAACpB,CAAD,CAAQ,CACvCoD,CAAA,CAAU,CAAA,CACVI,EAAA,CAAaxD,CAAA2C,OAAA,CAAe3C,CAAA2C,OAAf,CAA8B3C,CAAA4D,WAEjB,EAA1B,EAAGJ,CAAAK,SAAH,GACEL,CADF,CACeA,CAAAM,WADf,CAIA7E,EAAA8E,SAAA,CAAiBb,CAAjB,CAEAO,EAAA,CAAYnB,IAAAC,IAAA,EAER/B,EAAAA,CAAUR,CAAAQ,QAAA,EAAiBR,CAAAQ,QAAAC,OAAjB,CAAwCT,CAAAQ,QAAxC,CAAwD,CAACR,CAAD,CAClEU,EAAAA,CAAIF,CAAA,CAAQ,CAAR,CAAAI,cAAJF,EAAgCF,CAAA,CAAQ,CAAR,CACpCkD,EAAA,CAAchD,CAAAG,QACd8C,EAAA,CAAcjD,CAAAI,QAfyB,CAAzC,CAkBA7B,EAAAmC,GAAA,CAAW,WAAX,CAAwB,QAAQ,CAACpB,CAAD,CAAQ,CACtCmD,CAAA,EADsC,CAAxC,CAIAlE,EAAAmC,GAAA,CAAW,aAAX,CAA0B,QAAQ,CAACpB,CAAD,CAAQ,CACxCmD,CAAA,EADwC,CAA1C,CAIAlE,EAAAmC,GAAA,CAAW,UAAX,CAAuB,QAAQ,CAACpB,CAAD,CAAQ,CACrC,IAAIgE,EAAO1B,IAAAC,IAAA,EAAPyB,CAAoBP,CAAxB,CAEIjD,EAAWR,CAAAW,eAAD,EAAyBX,CAAAW,eAAAF,OAAzB,CAAwDT,CAAAW,eAAxD,CACRX,CAAAQ,QAAD,EAAkBR,CAAAQ,QAAAC,OAAlB;AAA0CT,CAAAQ,QAA1C,CAA0D,CAACR,CAAD,CAH/D,CAIIU,EAAIF,CAAA,CAAQ,CAAR,CAAAI,cAAJF,EAAgCF,CAAA,CAAQ,CAAR,CAJpC,CAKIb,EAAIe,CAAAG,QALR,CAMIpB,EAAIiB,CAAAI,QANR,CAOImD,EAAO1E,IAAA2E,KAAA,CAAW3E,IAAA4E,IAAA,CAASxE,CAAT,CAAa+D,CAAb,CAA0B,CAA1B,CAAX,CAA0CnE,IAAA4E,IAAA,CAAS1E,CAAT,CAAakE,CAAb,CAA0B,CAA1B,CAA1C,CAEPP,EAAJ,GArMegB,GAqMf,CAAeJ,CAAf,EApMiBK,EAoMjB,CAAsCJ,CAAtC,IA7DGlC,CAwED,GAvEFF,CAAA,CAAa,CAAb,CAAAyC,iBAAA,CAAiC,OAAjC,CAA0CjC,CAA1C,CAAmD,CAAA,CAAnD,CAEA,CADAR,CAAA,CAAa,CAAb,CAAAyC,iBAAA,CAAiC,YAAjC,CAA+CtB,CAA/C,CAA6D,CAAA,CAA7D,CACA,CAAAjB,CAAA,CAAmB,EAqEjB,EAlEJS,CAkEI,CAlEgBF,IAAAC,IAAA,EAkEhB,CAhEJT,CAAA,CAAsBC,CAAtB,CAuDsBpC,CAvDtB,CAuDyBF,CAvDzB,CAgEI,CAJI+D,CAIJ,EAHEA,CAAAT,KAAA,EAGF,CAAK5E,CAAAoG,UAAA,CAAkBrF,CAAAsF,SAAlB,CAAL,EAA2D,CAAA,CAA3D,GAAyCtF,CAAAsF,SAAzC,EACEvF,CAAAmB,eAAA,CAAuB,OAAvB,CAAgC,CAACJ,CAAD,CAAhC,CAZJ,CAgBAmD,EAAA,EA1BqC,CAAvC,CA+BAlE,EAAAwF,QAAA,CAAkBC,QAAQ,CAAC1E,CAAD,CAAQ,EAQlCf,EAAAmC,GAAA,CAAW,OAAX,CAAoB,QAAQ,CAACpB,CAAD,CAAQ2E,CAAR,CAAkB,CAC5C3F,CAAAmB,OAAA,CAAa,QAAQ,EAAG,CACtBmD,CAAA,CAAatE,CAAb,CAAoB,QAAU2F,CAAV,EAAsB3E,CAAtB,CAApB,CADsB,CAAxB,CAD4C,CAA9C,CAMAf,EAAAmC,GAAA,CAAW,WAAX,CAAwB,QAAQ,CAACpB,CAAD,CAAQ,CACtCf,CAAA8E,SAAA,CAAiBb,CAAjB,CADsC,CAAxC,CAIAjE,EAAAmC,GAAA,CAAW,mBAAX,CAAgC,QAAQ,CAACpB,CAAD,CAAQ,CAC9Cf,CAAAoE,YAAA,CAAoBH,CAApB,CAD8C,CAAhD,CAxFoC,CArJK,CADhB,CAA7B,CAgXA7E;CAAA,CAAmB,aAAnB,CAAmC,EAAnC,CAAsC,WAAtC,CACAA,EAAA,CAAmB,cAAnB,CAAmC,CAAnC,CAAsC,YAAtC,CA9jBsC,CAArC,CAAA,CAkkBEH,MAlkBF,CAkkBUA,MAAAC,QAlkBV;",
+"sources":["angular-touch.js"],
+"names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","MAX_VERTICAL_DISTANCE","MAX_VERTICAL_RATIO","MIN_HORIZONTAL_DISTANCE","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","swipeHandler","bind","start","event","cancel","end","$apply","triggerHandler","module","factory","getCoordinates","touches","length","e","changedTouches","originalEvent","clientX","clientY","eventHandlers","totalX","totalY","lastPos","active","on","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","x1","CLICKBUSTER_THRESHOLD","y1","splice","onClick","Date","now","lastPreventedTime","PREVENT_DURATION","lastLabelClickCoordinates","target","tagName","toLowerCase","stopPropagation","blur","onTouchStart","push","ACTIVE_CLASS_NAME","resetState","tapping","removeClass","clickHandler","ngClick","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","isDefined","disabled","onclick","element.onclick","touchend"]
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.js b/src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.js
new file mode 100644 (file)
index 0000000..11e34d7
--- /dev/null
@@ -0,0 +1,427 @@
+//
+// Copyright Kamil Pękala http://github.com/kamilkp
+// Angular Virtual Scroll Repeat v1.0.0-rc5 2014/08/01
+//
+
+(function(window, angular){
+       'use strict';
+       /* jshint eqnull:true */
+       /* jshint -W038 */
+
+       // DESCRIPTION:
+       // vsRepeat directive stands for Virtual Scroll Repeat. It turns a standard ngRepeated set of elements in a scrollable container
+       // into a component, where the user thinks he has all the elements rendered and all he needs to do is scroll (without any kind of
+       // pagination - which most users loath) and at the same time the browser isn't overloaded by that many elements/angular bindings etc.
+       // The directive renders only so many elements that can fit into current container's clientHeight/clientWidth.
+
+       // LIMITATIONS:
+       // - current version only supports an Array as a right-hand-side object for ngRepeat
+       // - all rendered elements must have the same height/width or the sizes of the elements must be known up front
+
+       // USAGE:
+       // In order to use the vsRepeat directive you need to place a vs-repeat attribute on a direct parent of an element with ng-repeat
+       // example:
+       // <div vs-repeat>
+       //              <div ng-repeat="item in someArray">
+       //                      <!-- content -->
+       //              </div>
+       // </div>
+       //
+       // You can also measure the single element's height/width (including all paddings and margins), and then speficy it as a value
+       // of the attribute 'vs-repeat'. This can be used if one wants to override the automatically computed element size.
+       // example:
+       // <div vs-repeat="50"> <!-- the specified element height is 50px -->
+       //              <div ng-repeat="item in someArray">
+       //                      <!-- content -->
+       //              </div>
+       // </div>
+       //
+       // IMPORTANT!
+       //
+       // - the vsRepeat directive must be applied to a direct parent of an element with ngRepeat
+       // - the value of vsRepeat attribute is the single element's height/width measured in pixels. If none provided, the directive
+       //              will compute it automatically
+
+       // OPTIONAL PARAMETERS (attributes):
+       // vs-scroll-parent="selector" - selector to the scrollable container. The directive will look for a closest parent matching
+       //                                                              he given selector (defaults to the current element)
+       // vs-horizontal - stack repeated elements horizontally instead of vertically
+       // vs-offset-before="value" - top/left offset in pixels (defaults to 0)
+       // vs-offset-after="value" - bottom/right offset in pixels (defaults to 0)
+       // vs-excess="value" - an integer number representing the number of elements to be rendered outside of the current container's viewport
+       //                                              (defaults to 2)
+       // vs-size-property - a property name of the items in collection that is a number denoting the element size (in pixels)
+       // vs-autoresize - use this attribute without vs-size-property and without specifying element's size. The automatically computed element style will
+       //                              readjust upon window resize if the size is dependable on the viewport size
+
+       // EVENTS:
+       // - 'vsRepeatTrigger' - an event the directive listens for to manually trigger reinitialization
+       // - 'vsRepeatReinitialized' - an event the directive emits upon reinitialization done
+
+       var isMacOS = navigator.appVersion.indexOf('Mac') != -1,
+               wheelEventName = typeof window.onwheel !== 'undefined' ? 'wheel' : typeof window.onmousewheel !== 'undefined' ? 'mousewheel' : 'DOMMouseScroll',
+               dde = document.documentElement,
+               matchingFunction = dde.matches ? 'matches' :
+                                                       dde.matchesSelector ? 'matchesSelector' :
+                                                       dde.webkitMatches ? 'webkitMatches' :
+                                                       dde.webkitMatchesSelector ? 'webkitMatchesSelector' :
+                                                       dde.msMatches ? 'msMatches' :
+                                                       dde.msMatchesSelector ? 'msMatchesSelector' :
+                                                       dde.mozMatches ? 'mozMatches' :
+                                                       dde.mozMatchesSelector ? 'mozMatchesSelector' : null;
+
+       var closestElement = angular.element.prototype.closest || function (selector){
+               var el = this[0].parentNode;
+               while(el !== document.documentElement && el != null && !el[matchingFunction](selector)){
+                       el = el.parentNode;
+               }
+
+               if(el && el[matchingFunction](selector))
+                       return angular.element(el);
+               else
+                       return angular.element();
+       };
+
+       angular.module('vs-repeat', []).directive('vsRepeat', ['$compile', function($compile){
+               return {
+                       restrict: 'A',
+                       scope: true,
+                       require: '?^vsRepeat',
+                       controller: ['$scope', function($scope){
+                               this.$scrollParent = $scope.$scrollParent;
+                               this.$fillElement = $scope.$fillElement;
+                       }],
+                       compile: function($element, $attrs){
+                               var ngRepeatChild = $element.children().eq(0),
+                                       ngRepeatExpression = ngRepeatChild.attr('ng-repeat'),
+                                       childCloneHtml = ngRepeatChild[0].outerHTML,
+                                       expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(ngRepeatExpression),
+                                       lhs = expressionMatches[1],
+                                       rhs = expressionMatches[2],
+                                       rhsSuffix = expressionMatches[3],
+                                       collectionName = '$vs_collection',
+                                       attributesDictionary = {
+                                               'vsRepeat': 'elementSize',
+                                               'vsOffsetBefore': 'offsetBefore',
+                                               'vsOffsetAfter': 'offsetAfter',
+                                               'vsExcess': 'excess'
+                                       };
+
+                               $element.empty();
+                               if(!window.getComputedStyle || window.getComputedStyle($element[0]).position !== 'absolute')
+                                       $element.css('position', 'relative');
+                               return {
+                                       pre: function($scope, $element, $attrs, $ctrl){
+                                               var childClone = angular.element(childCloneHtml),
+                                                       originalCollection = [],
+                                                       originalLength,
+                                                       $$horizontal = typeof $attrs.vsHorizontal !== "undefined",
+                                                       $wheelHelper,
+                                                       $fillElement,
+                                                       autoSize = !$attrs.vsRepeat,
+                                                       sizesPropertyExists = !!$attrs.vsSizeProperty,
+                                                       $scrollParent = $attrs.vsScrollParent ? closestElement.call($element, $attrs.vsScrollParent) : $element,
+                                                       positioningPropertyTransform = $$horizontal ? 'translateX' : 'translateY',
+                                                       positioningProperty = $$horizontal ? 'left' : 'top',
+
+                                                       clientSize =  $$horizontal ? 'clientWidth' : 'clientHeight',
+                                                       offsetSize =  $$horizontal ? 'offsetWidth' : 'offsetHeight',
+                                                       scrollPos =  $$horizontal ? 'scrollLeft' : 'scrollTop';
+
+                                               if($scrollParent.length === 0) throw 'Specified scroll parent selector did not match any element';
+                                               $scope.$scrollParent = $scrollParent;
+
+                                               if(sizesPropertyExists) $scope.sizesCumulative = [];
+
+                                               //initial defaults
+                                               $scope.elementSize = $scrollParent[0][clientSize] || 50;
+                                               $scope.offsetBefore = 0;
+                                               $scope.offsetAfter = 0;
+                                               $scope.excess = 2;
+
+                                               Object.keys(attributesDictionary).forEach(function(key){
+                                                       if($attrs[key]){
+                                                               $attrs.$observe(key, function(value){
+                                                                       $scope[attributesDictionary[key]] = +value;
+                                                                       reinitialize();
+                                                               });
+                                                       }
+                                               });
+
+
+                                               $scope.$watchCollection(rhs, function(coll){
+                                                       originalCollection = coll || [];
+                                                       refresh();
+                                               });
+
+                                               function refresh(){
+                                                       if(!originalCollection || originalCollection.length < 1){
+                                                               $scope[collectionName] = [];
+                                                               originalLength = 0;
+                                                               resizeFillElement(0);
+                                                               $scope.sizesCumulative = [0];
+                                                               return;
+                                                       }
+                                                       else{
+                                                               originalLength = originalCollection.length;
+                                                               if(sizesPropertyExists){
+                                                                       $scope.sizes = originalCollection.map(function(item){
+                                                                               return item[$attrs.vsSizeProperty];
+                                                                       });
+                                                                       var sum = 0;
+                                                                       $scope.sizesCumulative = $scope.sizes.map(function(size){
+                                                                               var res = sum;
+                                                                               sum += size;
+                                                                               return res;
+                                                                       });
+                                                                       $scope.sizesCumulative.push(sum);
+                                                               }
+                                                               setAutoSize();
+                                                       }
+
+                                                       reinitialize();
+                                               }
+
+                                               function setAutoSize(){
+                                                       if(autoSize){
+                                                               $scope.$$postDigest(function(){
+                                                                       if($element[0].offsetHeight || $element[0].offsetWidth){ // element is visible
+                                                                               var children = $element.children(),
+                                                                                       i = 0;
+                                                                               while(i < children.length){
+                                                                                       if(children[i].attributes['ng-repeat'] != null){
+                                                                                               if(children[i][offsetSize]){
+                                                                                                       $scope.elementSize = children[i][offsetSize];
+                                                                                                       reinitialize();
+                                                                                                       autoSize = false;
+                                                                                                       if($scope.$root && !$scope.$root.$$phase)
+                                                                                                               $scope.$apply();
+                                                                                               }
+                                                                                               break;
+                                                                                       }
+                                                                                       i++;
+                                                                               }
+                                                                       }
+                                                                       else{
+                                                                               var dereg = $scope.$watch(function(){
+                                                                                       if($element[0].offsetHeight || $element[0].offsetWidth){
+                                                                                               dereg();
+                                                                                               setAutoSize();
+                                                                                       }
+                                                                               });
+                                                                       }
+                                                               });
+                                                       }
+                                               }
+
+                                               childClone.attr('ng-repeat', lhs + ' in ' + collectionName + (rhsSuffix ? ' ' + rhsSuffix : ''))
+                                                               .addClass('vs-repeat-repeated-element');
+
+                                               var offsetCalculationString = sizesPropertyExists ?
+                                                       '(sizesCumulative[$index + startIndex] + offsetBefore)' :
+                                                       '(($index + startIndex) * elementSize + offsetBefore)';
+
+                                               if(typeof document.documentElement.style.transform !== "undefined"){ // browser supports transform css property
+                                                       childClone.attr('ng-style', '{ "transform": "' + positioningPropertyTransform + '(" + ' + offsetCalculationString + ' + "px)"}');
+                                               }
+                                               else if(typeof document.documentElement.style.webkitTransform !== "undefined"){ // browser supports -webkit-transform css property
+                                                       childClone.attr('ng-style', '{ "-webkit-transform": "' + positioningPropertyTransform + '(" + ' + offsetCalculationString + ' + "px)"}');
+                                               }
+                                               else{
+                                                       childClone.attr('ng-style', '{' + positioningProperty + ': ' + offsetCalculationString + ' + "px"}');
+                                               }
+
+                                               $compile(childClone)($scope);
+                                               $element.append(childClone);
+
+                                               $fillElement = angular.element('<div class="vs-repeat-fill-element"></div>')
+                                                       .css({
+                                                               'position':'relative',
+                                                               'min-height': '100%',
+                                                               'min-width': '100%'
+                                                       });
+                                               $element.append($fillElement);
+                                               $compile($fillElement)($scope);
+                                               $scope.$fillElement = $fillElement;
+
+                                               var _prevMouse = {};
+                                               if(isMacOS){
+                                                       $wheelHelper = angular.element('<div class="vs-repeat-wheel-helper"></div>')
+                                                               .on(wheelEventName, function(e){
+                                                                       e.preventDefault();
+                                                                       e.stopPropagation();
+                                                                       if(e.originalEvent) e = e.originalEvent;
+                                                                       $scrollParent[0].scrollLeft += (e.deltaX || -e.wheelDeltaX);
+                                                                       $scrollParent[0].scrollTop += (e.deltaY || -e.wheelDeltaY);
+                                                               }).on('mousemove', function(e){
+                                                                       if(_prevMouse.x !== e.clientX || _prevMouse.y !== e.clientY)
+                                                                               angular.element(this).css('display', 'none');
+                                                                       _prevMouse = {
+                                                                               x: e.clientX,
+                                                                               y: e.clientY
+                                                                       };
+                                                               }).css('display', 'none');
+                                                       $fillElement.append($wheelHelper);
+                                               }
+
+                                               $scope.startIndex = 0;
+                                               $scope.endIndex = 0;
+
+                                               $scrollParent.on('scroll', function scrollHandler(e){
+                                                       if(updateInnerCollection())
+                                                               $scope.$apply();
+                                               });
+
+                                               if(isMacOS){
+                                                       $scrollParent.on(wheelEventName, wheelHandler);
+                                               }
+                                               function wheelHandler(e){
+                                                       var elem = e.currentTarget;
+                                                       if(elem.scrollWidth > elem.clientWidth || elem.scrollHeight > elem.clientHeight)
+                                                               $wheelHelper.css('display', 'block');
+                                               }
+
+                                               function onWindowResize(){
+                                                       if(typeof $attrs.vsAutoresize !== 'undefined'){
+                                                               autoSize = true;
+                                                               setAutoSize();
+                                                               if($scope.$root && !$scope.$root.$$phase)
+                                                                       $scope.$apply();
+                                                       }
+                                                       if(updateInnerCollection())
+                                                               $scope.$apply();
+                                               }
+
+                                               angular.element(window).on('resize', onWindowResize);
+                                               $scope.$on('$destroy', function(){
+                                                       angular.element(window).off('resize', onWindowResize);
+                                               });
+
+                                               $scope.$on('vsRepeatTrigger', refresh);
+                                               $scope.$on('vsRepeatResize', function(){
+                                                       autoSize = true;
+                                                       setAutoSize();
+                                               });
+
+                                               var _prevStartIndex,
+                                                       _prevEndIndex;
+                                               function reinitialize(){
+                                                       _prevStartIndex = void 0;
+                                                       _prevEndIndex = void 0;
+                                                       updateInnerCollection();
+                                                       resizeFillElement(sizesPropertyExists ?
+                                                                                               $scope.sizesCumulative[originalLength] :
+                                                                                               $scope.elementSize*originalLength
+                                                                                       );
+                                                       $scope.$emit('vsRepeatReinitialized');
+                                               }
+
+                                               function resizeFillElement(size){
+                                                       if($$horizontal){
+                                                               $fillElement.css({
+                                                                       'width': $scope.offsetBefore + size + $scope.offsetAfter + 'px',
+                                                                       'height': '100%'
+                                                               });
+                                                               if($ctrl && $ctrl.$fillElement){
+                                                                       var referenceElement = $ctrl.$fillElement[0].parentNode.querySelector('[ng-repeat]');
+                                                                       if(referenceElement)
+                                                                               $ctrl.$fillElement.css({
+                                                                                       'width': referenceElement.scrollWidth + 'px'
+                                                                               });
+                                                               }
+                                                       }
+                                                       else{
+                                                               $fillElement.css({
+                                                                       'height': $scope.offsetBefore + size + $scope.offsetAfter + 'px',
+                                                                       'width': '100%'
+                                                               });
+                                                               if($ctrl && $ctrl.$fillElement){
+                                                                       referenceElement = $ctrl.$fillElement[0].parentNode.querySelector('[ng-repeat]');
+                                                                       if(referenceElement)
+                                                                               $ctrl.$fillElement.css({
+                                                                                       'height': referenceElement.scrollHeight + 'px'
+                                                                               });
+                                                               }
+                                                       }
+                                               }
+
+                                               var _prevClientSize;
+                                               function reinitOnClientHeightChange(){
+                                                       var ch = $scrollParent[0][clientSize];
+                                                       if(ch !== _prevClientSize){
+                                                               reinitialize();
+                                                               if($scope.$root && !$scope.$root.$$phase)
+                                                                       $scope.$apply();
+                                                       }
+                                                       _prevClientSize = ch;
+                                               }
+
+                                               $scope.$watch(function(){
+                                                       if(typeof window.requestAnimationFrame === "function")
+                                                               window.requestAnimationFrame(reinitOnClientHeightChange);
+                                                       else
+                                                               reinitOnClientHeightChange();
+                                               });
+
+                                               function updateInnerCollection(){
+                                                       if(sizesPropertyExists){
+                                                               $scope.startIndex = 0;
+                                                               while($scope.sizesCumulative[$scope.startIndex] < $scrollParent[0][scrollPos] - $scope.offsetBefore)
+                                                                       $scope.startIndex++;
+                                                               if($scope.startIndex > 0) $scope.startIndex--;
+
+                                                               $scope.endIndex = $scope.startIndex;
+                                                               while($scope.sizesCumulative[$scope.endIndex] < $scrollParent[0][scrollPos] - $scope.offsetBefore + $scrollParent[0][clientSize])
+                                                                       $scope.endIndex++;
+                                                       }
+                                                       else{
+                                                               $scope.startIndex = Math.max(
+                                                                       Math.floor(
+                                                                               ($scrollParent[0][scrollPos] - $scope.offsetBefore) / $scope.elementSize + $scope.excess/2
+                                                                       ) - $scope.excess,
+                                                                       0
+                                                               );
+
+                                                               $scope.endIndex = Math.min(
+                                                                       $scope.startIndex + Math.ceil(
+                                                                               $scrollParent[0][clientSize] / $scope.elementSize
+                                                                       ) + $scope.excess,
+                                                                       originalLength
+                                                               );
+                                                       }
+
+
+                                                       var digestRequired = $scope.startIndex !== _prevStartIndex || $scope.endIndex !== _prevEndIndex;
+
+                                                       if(digestRequired)
+                                                               $scope[collectionName] = originalCollection.slice($scope.startIndex, $scope.endIndex);
+
+                                                       _prevStartIndex = $scope.startIndex;
+                                                       _prevEndIndex = $scope.endIndex;
+
+                                                       return digestRequired;
+                                               }
+                                       }
+                               };
+                       }
+               };
+       }]);
+
+       angular.element(document.head).append([
+               '<style>' +
+               '.vs-repeat-wheel-helper{' +
+                       'position: absolute;' +
+                       'top: 0;' +
+                       'bottom: 0;' +
+                       'left: 0;' +
+                       'right: 0;' +
+                       'z-index: 99999;' +
+                       'background: rgba(0, 0, 0, 0);' +
+               '}' +
+               '.vs-repeat-repeated-element{' +
+                       'position: absolute;' +
+                       'z-index: 1;' +
+               '}' +
+               '</style>'
+       ].join(''));
+})(window, window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.min.js b/src/main/resources/META-INF/resources/designer/lib/angular-vs-repeat.min.js
new file mode 100644 (file)
index 0000000..b83fbca
--- /dev/null
@@ -0,0 +1 @@
+!function(a,b){"use strict";var c=-1!=navigator.appVersion.indexOf("Mac"),d="undefined"!=typeof a.onwheel?"wheel":"undefined"!=typeof a.onmousewheel?"mousewheel":"DOMMouseScroll",e=document.documentElement,f=e.matches?"matches":e.matchesSelector?"matchesSelector":e.webkitMatches?"webkitMatches":e.webkitMatchesSelector?"webkitMatchesSelector":e.msMatches?"msMatches":e.msMatchesSelector?"msMatchesSelector":e.mozMatches?"mozMatches":e.mozMatchesSelector?"mozMatchesSelector":null,g=b.element.prototype.closest||function(a){for(var c=this[0].parentNode;c!==document.documentElement&&null!=c&&!c[f](a);)c=c.parentNode;return c&&c[f](a)?b.element(c):b.element()};b.module("vs-repeat",[]).directive("vsRepeat",["$compile",function(e){return{restrict:"A",scope:!0,require:"?^vsRepeat",controller:["$scope",function(a){this.$scrollParent=a.$scrollParent,this.$fillElement=a.$fillElement}],compile:function(f){var h=f.children().eq(0),i=h.attr("ng-repeat"),j=h[0].outerHTML,k=/^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(i),l=k[1],m=k[2],n=k[3],o="$vs_collection",p={vsRepeat:"elementSize",vsOffsetBefore:"offsetBefore",vsOffsetAfter:"offsetAfter",vsExcess:"excess"};return f.empty(),a.getComputedStyle&&"absolute"===a.getComputedStyle(f[0]).position||f.css("position","relative"),{pre:function(f,h,i,k){function q(){if(!C||C.length<1)return f[o]=[],y=0,v(0),void(f.sizesCumulative=[0]);if(y=C.length,F){f.sizes=C.map(function(a){return a[i.vsSizeProperty]});var a=0;f.sizesCumulative=f.sizes.map(function(b){var c=a;return a+=b,c}),f.sizesCumulative.push(a)}r(),u()}function r(){E&&f.$$postDigest(function(){if(h[0].offsetHeight||h[0].offsetWidth)for(var a=h.children(),b=0;b<a.length;){if(null!=a[b].attributes["ng-repeat"]){a[b][K]&&(f.elementSize=a[b][K],u(),E=!1,f.$root&&!f.$root.$$phase&&f.$apply());break}b++}else var c=f.$watch(function(){(h[0].offsetHeight||h[0].offsetWidth)&&(c(),r())})})}function s(a){var b=a.currentTarget;(b.scrollWidth>b.clientWidth||b.scrollHeight>b.clientHeight)&&z.css("display","block")}function t(){"undefined"!=typeof i.vsAutoresize&&(E=!0,r(),f.$root&&!f.$root.$$phase&&f.$apply()),x()&&f.$apply()}function u(){O=void 0,P=void 0,x(),v(F?f.sizesCumulative[y]:f.elementSize*y),f.$emit("vsRepeatReinitialized")}function v(a){if(D){if(A.css({width:f.offsetBefore+a+f.offsetAfter+"px",height:"100%"}),k&&k.$fillElement){var b=k.$fillElement[0].parentNode.querySelector("[ng-repeat]");b&&k.$fillElement.css({width:b.scrollWidth+"px"})}}else A.css({height:f.offsetBefore+a+f.offsetAfter+"px",width:"100%"}),k&&k.$fillElement&&(b=k.$fillElement[0].parentNode.querySelector("[ng-repeat]"),b&&k.$fillElement.css({height:b.scrollHeight+"px"}))}function w(){var a=G[0][J];a!==Q&&(u(),f.$root&&!f.$root.$$phase&&f.$apply()),Q=a}function x(){if(F){for(f.startIndex=0;f.sizesCumulative[f.startIndex]<G[0][L]-f.offsetBefore;)f.startIndex++;for(f.startIndex>0&&f.startIndex--,f.endIndex=f.startIndex;f.sizesCumulative[f.endIndex]<G[0][L]-f.offsetBefore+G[0][J];)f.endIndex++}else f.startIndex=Math.max(Math.floor((G[0][L]-f.offsetBefore)/f.elementSize+f.excess/2)-f.excess,0),f.endIndex=Math.min(f.startIndex+Math.ceil(G[0][J]/f.elementSize)+f.excess,y);var a=f.startIndex!==O||f.endIndex!==P;return a&&(f[o]=C.slice(f.startIndex,f.endIndex)),O=f.startIndex,P=f.endIndex,a}var y,z,A,B=b.element(j),C=[],D="undefined"!=typeof i.vsHorizontal,E=!i.vsRepeat,F=!!i.vsSizeProperty,G=i.vsScrollParent?g.call(h,i.vsScrollParent):h,H=D?"translateX":"translateY",I=D?"left":"top",J=D?"clientWidth":"clientHeight",K=D?"offsetWidth":"offsetHeight",L=D?"scrollLeft":"scrollTop";if(0===G.length)throw"Specified scroll parent selector did not match any element";f.$scrollParent=G,F&&(f.sizesCumulative=[]),f.elementSize=G[0][J]||50,f.offsetBefore=0,f.offsetAfter=0,f.excess=2,Object.keys(p).forEach(function(a){i[a]&&i.$observe(a,function(b){f[p[a]]=+b,u()})}),f.$watchCollection(m,function(a){C=a||[],q()}),B.attr("ng-repeat",l+" in "+o+(n?" "+n:"")).addClass("vs-repeat-repeated-element");var M=F?"(sizesCumulative[$index + startIndex] + offsetBefore)":"(($index + startIndex) * elementSize + offsetBefore)";"undefined"!=typeof document.documentElement.style.transform?B.attr("ng-style",'{ "transform": "'+H+'(" + '+M+' + "px)"}'):"undefined"!=typeof document.documentElement.style.webkitTransform?B.attr("ng-style",'{ "-webkit-transform": "'+H+'(" + '+M+' + "px)"}'):B.attr("ng-style","{"+I+": "+M+' + "px"}'),e(B)(f),h.append(B),A=b.element('<div class="vs-repeat-fill-element"></div>').css({position:"relative","min-height":"100%","min-width":"100%"}),h.append(A),e(A)(f),f.$fillElement=A;var N={};c&&(z=b.element('<div class="vs-repeat-wheel-helper"></div>').on(d,function(a){a.preventDefault(),a.stopPropagation(),a.originalEvent&&(a=a.originalEvent),G[0].scrollLeft+=a.deltaX||-a.wheelDeltaX,G[0].scrollTop+=a.deltaY||-a.wheelDeltaY}).on("mousemove",function(a){(N.x!==a.clientX||N.y!==a.clientY)&&b.element(this).css("display","none"),N={x:a.clientX,y:a.clientY}}).css("display","none"),A.append(z)),f.startIndex=0,f.endIndex=0,G.on("scroll",function(){x()&&f.$apply()}),c&&G.on(d,s),b.element(a).on("resize",t),f.$on("$destroy",function(){b.element(a).off("resize",t)}),f.$on("vsRepeatTrigger",q),f.$on("vsRepeatResize",function(){E=!0,r()});var O,P,Q;f.$watch(function(){"function"==typeof a.requestAnimationFrame?a.requestAnimationFrame(w):w()})}}}}}]),b.element(document.head).append(["<style>.vs-repeat-wheel-helper{position: absolute;top: 0;bottom: 0;left: 0;right: 0;z-index: 99999;background: rgba(0, 0, 0, 0);}.vs-repeat-repeated-element{position: absolute;z-index: 1;}</style>"].join(""))}(window,window.angular);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular.min.js b/src/main/resources/META-INF/resources/designer/lib/angular.min.js
new file mode 100644 (file)
index 0000000..b9f64f4
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ AngularJS v1.2.26
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(W,X,t){'use strict';function C(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.26/"+(b?b+"/":"")+a;for(c=1;c<arguments.length;c++)a=a+(1==c?"?":"&")+"p"+(c-1)+"="+encodeURIComponent("function"==typeof arguments[c]?arguments[c].toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof arguments[c]?"undefined":"string"!=typeof arguments[c]?JSON.stringify(arguments[c]):arguments[c]);return Error(a)}}function Pa(b){if(null==b||Ga(b))return!1;
+var a=b.length;return 1===b.nodeType&&a?!0:v(b)||J(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function r(b,a,c){var d;if(b)if(P(b))for(d in b)"prototype"==d||("length"==d||"name"==d||b.hasOwnProperty&&!b.hasOwnProperty(d))||a.call(c,b[d],d);else if(J(b)||Pa(b))for(d=0;d<b.length;d++)a.call(c,b[d],d);else if(b.forEach&&b.forEach!==r)b.forEach(a,c);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function Zb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function Tc(b,
+a,c){for(var d=Zb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function $b(b){return function(a,c){b(c,a)}}function hb(){for(var b=ma.length,a;b;){b--;a=ma[b].charCodeAt(0);if(57==a)return ma[b]="A",ma.join("");if(90==a)ma[b]="0";else return ma[b]=String.fromCharCode(a+1),ma.join("")}ma.unshift("0");return ma.join("")}function ac(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function D(b){var a=b.$$hashKey;r(arguments,function(a){a!==b&&r(a,function(a,c){b[c]=a})});ac(b,a);return b}function U(b){return parseInt(b,
+10)}function bc(b,a){return D(new (D(function(){},{prototype:b})),a)}function E(){}function Qa(b){return b}function ba(b){return function(){return b}}function x(b){return"undefined"===typeof b}function y(b){return"undefined"!==typeof b}function T(b){return null!=b&&"object"===typeof b}function v(b){return"string"===typeof b}function ib(b){return"number"===typeof b}function ta(b){return"[object Date]"===za.call(b)}function P(b){return"function"===typeof b}function jb(b){return"[object RegExp]"===za.call(b)}
+function Ga(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function Uc(b){return!(!b||!(b.nodeName||b.prop&&b.attr&&b.find))}function Vc(b,a,c){var d=[];r(b,function(b,f,g){d.push(a.call(c,b,f,g))});return d}function Ra(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Sa(b,a){var c=Ra(b,a);0<=c&&b.splice(c,1);return a}function Ha(b,a,c,d){if(Ga(b)||b&&b.$evalAsync&&b.$watch)throw Ta("cpws");if(a){if(b===a)throw Ta("cpi");c=c||[];
+d=d||[];if(T(b)){var e=Ra(c,b);if(-1!==e)return d[e];c.push(b);d.push(a)}if(J(b))for(var f=a.length=0;f<b.length;f++)e=Ha(b[f],null,c,d),T(b[f])&&(c.push(b[f]),d.push(e)),a.push(e);else{var g=a.$$hashKey;J(a)?a.length=0:r(a,function(b,c){delete a[c]});for(f in b)e=Ha(b[f],null,c,d),T(b[f])&&(c.push(b[f]),d.push(e)),a[f]=e;ac(a,g)}}else if(a=b)J(b)?a=Ha(b,[],c,d):ta(b)?a=new Date(b.getTime()):jb(b)?(a=RegExp(b.source,b.toString().match(/[^\/]*$/)[0]),a.lastIndex=b.lastIndex):T(b)&&(a=Ha(b,{},c,d));
+return a}function ha(b,a){if(J(b)){a=a||[];for(var c=0;c<b.length;c++)a[c]=b[c]}else if(T(b))for(c in a=a||{},b)!kb.call(b,c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(a[c]=b[c]);return a||b}function Aa(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&"object"==c)if(J(b)){if(!J(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!Aa(b[d],a[d]))return!1;return!0}}else{if(ta(b))return ta(a)?isNaN(b.getTime())&&isNaN(a.getTime())||b.getTime()===
+a.getTime():!1;if(jb(b)&&jb(a))return b.toString()==a.toString();if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||Ga(b)||Ga(a)||J(a))return!1;c={};for(d in b)if("$"!==d.charAt(0)&&!P(b[d])){if(!Aa(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==t&&!P(a[d]))return!1;return!0}return!1}function Bb(b,a){var c=2<arguments.length?Ba.call(arguments,2):[];return!P(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,c.concat(Ba.call(arguments,
+0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function Wc(b,a){var c=a;"string"===typeof b&&"$"===b.charAt(0)?c=t:Ga(a)?c="$WINDOW":a&&X===a?c="$DOCUMENT":a&&(a.$evalAsync&&a.$watch)&&(c="$SCOPE");return c}function na(b,a){return"undefined"===typeof b?t:JSON.stringify(b,Wc,a?"  ":null)}function cc(b){return v(b)?JSON.parse(b):b}function Ua(b){"function"===typeof b?b=!0:b&&0!==b.length?(b=K(""+b),b=!("f"==b||"0"==b||"false"==b||"no"==b||"n"==b||"[]"==b)):b=!1;
+return b}function ia(b){b=w(b).clone();try{b.empty()}catch(a){}var c=w("<div>").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function dc(b){try{return decodeURIComponent(b)}catch(a){}}function ec(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=dc(c[0]),y(d)&&(b=y(c[1])?dc(c[1]):!0,kb.call(a,d)?J(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Cb(b){var a=
+[];r(b,function(b,d){J(b)?r(b,function(b){a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))}):a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))});return a.length?a.join("&"):""}function lb(b){return Ca(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ca(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Xc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app",
+"data-ng-app"],k=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(X.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=k.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function fc(b,a){var c=function(){b=w(b);if(b.injector()){var c=b[0]===X?
+"document":ia(b);throw Ta("btstrpd",c.replace(/</,"&lt;").replace(/>/,"&gt;"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=gc(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(W&&!d.test(W.name))return c();W.name=W.name.replace(d,"");Va.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function mb(b,a){a=
+a||"_";return b.replace(Yc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Db(b,a,c){if(!b)throw Ta("areq",a||"?",c||"required");return b}function Wa(b,a,c){c&&J(b)&&(b=b[b.length-1]);Db(P(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Da(b,a){if("hasOwnProperty"===b)throw Ta("badname",a);}function hc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&P(b)?Bb(e,b):b}function Eb(b){var a=
+b[0];b=b[b.length-1];if(a===b)return w(a);var c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b);return w(c)}function Zc(b){var a=C("$injector"),c=C("ng");b=b.angular||(b.angular={});b.$$minErr=b.$$minErr||C;return b.module||(b.module=function(){var b={};return function(e,f,g){if("hasOwnProperty"===e)throw c("badname","module");f&&b.hasOwnProperty(e)&&(b[e]=null);return b[e]||(b[e]=function(){function b(a,d,e){return function(){c[e||"push"]([a,d,arguments]);return n}}if(!f)throw a("nomod",
+e);var c=[],d=[],l=b("$injector","invoke"),n={_invokeQueue:c,_runBlocks:d,requires:f,name:e,provider:b("$provide","provider"),factory:b("$provide","factory"),service:b("$provide","service"),value:b("$provide","value"),constant:b("$provide","constant","unshift"),animation:b("$animateProvider","register"),filter:b("$filterProvider","register"),controller:b("$controllerProvider","register"),directive:b("$compileProvider","directive"),config:l,run:function(a){d.push(a);return this}};g&&l(g);return n}())}}())}
+function $c(b){D(b,{bootstrap:fc,copy:Ha,extend:D,equals:Aa,element:w,forEach:r,injector:gc,noop:E,bind:Bb,toJson:na,fromJson:cc,identity:Qa,isUndefined:x,isDefined:y,isString:v,isFunction:P,isObject:T,isNumber:ib,isElement:Uc,isArray:J,version:ad,isDate:ta,lowercase:K,uppercase:Ia,callbacks:{counter:0},$$minErr:C,$$csp:Xa});Ya=Zc(W);try{Ya("ngLocale")}catch(a){Ya("ngLocale",[]).provider("$locale",bd)}Ya("ng",["ngLocale"],["$provide",function(a){a.provider({$$sanitizeUri:cd});a.provider("$compile",
+ic).directive({a:dd,input:jc,textarea:jc,form:ed,script:fd,select:gd,style:hd,option:id,ngBind:jd,ngBindHtml:kd,ngBindTemplate:ld,ngClass:md,ngClassEven:nd,ngClassOdd:od,ngCloak:pd,ngController:qd,ngForm:rd,ngHide:sd,ngIf:td,ngInclude:ud,ngInit:vd,ngNonBindable:wd,ngPluralize:xd,ngRepeat:yd,ngShow:zd,ngStyle:Ad,ngSwitch:Bd,ngSwitchWhen:Cd,ngSwitchDefault:Dd,ngOptions:Ed,ngTransclude:Fd,ngModel:Gd,ngList:Hd,ngChange:Id,required:kc,ngRequired:kc,ngValue:Jd}).directive({ngInclude:Kd}).directive(Fb).directive(lc);
+a.provider({$anchorScroll:Ld,$animate:Md,$browser:Nd,$cacheFactory:Od,$controller:Pd,$document:Qd,$exceptionHandler:Rd,$filter:mc,$interpolate:Sd,$interval:Td,$http:Ud,$httpBackend:Vd,$location:Wd,$log:Xd,$parse:Yd,$rootScope:Zd,$q:$d,$sce:ae,$sceDelegate:be,$sniffer:ce,$templateCache:de,$timeout:ee,$window:fe,$$rAF:ge,$$asyncCallback:he})}])}function Za(b){return b.replace(ie,function(a,b,d,e){return e?d.toUpperCase():d}).replace(je,"Moz$1")}function Gb(b,a,c,d){function e(b){var e=c&&b?[this.filter(b)]:
+[this],m=a,h,l,n,p,q,s;if(!d||null!=b)for(;e.length;)for(h=e.shift(),l=0,n=h.length;l<n;l++)for(p=w(h[l]),m?p.triggerHandler("$destroy"):m=!m,q=0,p=(s=p.children()).length;q<p;q++)e.push(Ea(s[q]));return f.apply(this,arguments)}var f=Ea.fn[b],f=f.$original||f;e.$original=f;Ea.fn[b]=e}function S(b){if(b instanceof S)return b;v(b)&&(b=aa(b));if(!(this instanceof S)){if(v(b)&&"<"!=b.charAt(0))throw Hb("nosel");return new S(b)}if(v(b)){var a=b;b=X;var c;if(c=ke.exec(a))b=[b.createElement(c[1])];else{var d=
+b,e;b=d.createDocumentFragment();c=[];if(Ib.test(a)){d=b.appendChild(d.createElement("div"));e=(le.exec(a)||["",""])[1].toLowerCase();e=ea[e]||ea._default;d.innerHTML="<div>&#160;</div>"+e[1]+a.replace(me,"<$1></$2>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a<e;++a)c.push(d.childNodes[a]);d=b.firstChild;d.textContent=""}else c.push(d.createTextNode(a));b.textContent="";b.innerHTML="";b=c}Jb(this,b);w(X.createDocumentFragment()).append(this)}else Jb(this,
+b)}function Kb(b){return b.cloneNode(!0)}function Ja(b){Lb(b);var a=0;for(b=b.childNodes||[];a<b.length;a++)Ja(b[a])}function nc(b,a,c,d){if(y(d))throw Hb("offargs");var e=oa(b,"events");oa(b,"handle")&&(x(a)?r(e,function(a,c){$a(b,c,a);delete e[c]}):r(a.split(" "),function(a){x(c)?($a(b,a,e[a]),delete e[a]):Sa(e[a]||[],c)}))}function Lb(b,a){var c=b.ng339,d=ab[c];d&&(a?delete ab[c].data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),nc(b)),delete ab[c],b.ng339=t))}function oa(b,a,c){var d=
+b.ng339,d=ab[d||-1];if(y(c))d||(b.ng339=d=++ne,d=ab[d]={}),d[a]=c;else return d&&d[a]}function Mb(b,a,c){var d=oa(b,"data"),e=y(c),f=!e&&y(a),g=f&&!T(a);d||g||oa(b,"data",d={});if(e)d[a]=c;else if(f){if(g)return d&&d[a];D(d,a)}else return d}function Nb(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function nb(b,a){a&&b.setAttribute&&r(a.split(" "),function(a){b.setAttribute("class",aa((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g,
+" ").replace(" "+aa(a)+" "," ")))})}function ob(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ");r(a.split(" "),function(a){a=aa(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",aa(c))}}function Jb(b,a){if(a){a=a.nodeName||!y(a.length)||Ga(a)?[a]:a;for(var c=0;c<a.length;c++)b.push(a[c])}}function oc(b,a){return pb(b,"$"+(a||"ngController")+"Controller")}function pb(b,a,c){9==b.nodeType&&(b=b.documentElement);for(a=J(a)?a:[a];b;){for(var d=
+0,e=a.length;d<e;d++)if((c=w.data(b,a[d]))!==t)return c;b=b.parentNode||11===b.nodeType&&b.host}}function pc(b){for(var a=0,c=b.childNodes;a<c.length;a++)Ja(c[a]);for(;b.firstChild;)b.removeChild(b.firstChild)}function qc(b,a){var c=qb[a.toLowerCase()];return c&&rc[b.nodeName]&&c}function oe(b,a){var c=function(c,e){c.preventDefault||(c.preventDefault=function(){c.returnValue=!1});c.stopPropagation||(c.stopPropagation=function(){c.cancelBubble=!0});c.target||(c.target=c.srcElement||X);if(x(c.defaultPrevented)){var f=
+c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;f.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented||!1===c.returnValue};var g=ha(a[e||c.type]||[]);r(g,function(a){a.call(b,c)});8>=Q?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ka(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d=
+b.$$hashKey)?d=b.$$hashKey():d===t&&(d=b.$$hashKey=(a||hb)()):d=b;return c+":"+d}function bb(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function sc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(pe,""),c=c.match(qe),r(c[1].split(re),function(b){b.replace(se,function(b,c,d){a.push(d)})})),b.$inject=a):J(b)?(c=b.length-1,Wa(b[c],"fn"),a=b.slice(0,c)):Wa(b,"fn",!0);return a}function gc(b){function a(a){return function(b,c){if(T(b))r(b,
+$b(a));else return a(b,c)}}function c(a,b){Da(a,"service");if(P(b)||J(b))b=n.instantiate(b);if(!b.$get)throw cb("pget",a);return l[a+k]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,k;r(a,function(a){if(!h.get(a)){h.put(a,!0);try{if(v(a))for(c=Ya(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,k=d.length;f<k;f++){var g=d[f],m=n.get(g[0]);m[g[1]].apply(m,g[2])}else P(a)?b.push(n.invoke(a)):J(a)?b.push(n.invoke(a)):Wa(a,"module")}catch(l){throw J(a)&&(a=
+a[a.length-1]),l.message&&(l.stack&&-1==l.stack.indexOf(l.message))&&(l=l.message+"\n"+l.stack),cb("modulerr",a,l.stack||l.message||l);}}});return b}function f(a,b){function c(d){if(a.hasOwnProperty(d)){if(a[d]===g)throw cb("cdep",d+" <- "+m.join(" <- "));return a[d]}try{return m.unshift(d),a[d]=g,a[d]=b(d)}catch(e){throw a[d]===g&&delete a[d],e;}finally{m.shift()}}function d(a,b,e){var f=[],k=sc(a),g,m,h;m=0;for(g=k.length;m<g;m++){h=k[m];if("string"!==typeof h)throw cb("itkn",h);f.push(e&&e.hasOwnProperty(h)?
+e[h]:c(h))}J(a)&&(a=a[g]);return a.apply(b,f)}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(J(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return T(e)||P(e)?e:c},get:c,annotate:sc,has:function(b){return l.hasOwnProperty(b+k)||a.hasOwnProperty(b)}}}var g={},k="Provider",m=[],h=new bb([],!0),l={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,ba(b))}),constant:a(function(a,
+b){Da(a,"constant");l[a]=b;p[a]=b}),decorator:function(a,b){var c=n.get(a+k),d=c.$get;c.$get=function(){var a=q.invoke(d,c);return q.invoke(b,null,{$delegate:a})}}}},n=l.$injector=f(l,function(){throw cb("unpr",m.join(" <- "));}),p={},q=p.$injector=f(p,function(a){a=n.get(a+k);return q.invoke(a.$get,a)});r(e(b),function(a){q.invoke(a||E)});return q}function Ld(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;
+r(a,function(a){b||"a"!==K(a.nodeName)||(b=a)});return b}function f(){var b=c.hash(),d;b?(d=g.getElementById(b))?d.scrollIntoView():(d=e(g.getElementsByName(b)))?d.scrollIntoView():"top"===b&&a.scrollTo(0,0):a.scrollTo(0,0)}var g=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(f)});return f}]}function he(){this.$get=["$$rAF","$timeout",function(b,a){return b.supported?function(a){return b(a)}:function(b){return a(b,0,!1)}}]}function te(b,a,c,d){function e(a){try{a.apply(null,
+Ba.call(arguments,1))}finally{if(s--,0===s)for(;F.length;)try{F.pop()()}catch(b){c.error(b)}}}function f(a,b){(function fa(){r(u,function(a){a()});A=b(fa,a)})()}function g(){z=null;N!=k.url()&&(N=k.url(),r(ca,function(a){a(k.url())}))}var k=this,m=a[0],h=b.location,l=b.history,n=b.setTimeout,p=b.clearTimeout,q={};k.isMock=!1;var s=0,F=[];k.$$completeOutstandingRequest=e;k.$$incOutstandingRequestCount=function(){s++};k.notifyWhenNoOutstandingRequests=function(a){r(u,function(a){a()});0===s?a():F.push(a)};
+var u=[],A;k.addPollFn=function(a){x(A)&&f(100,n);u.push(a);return a};var N=h.href,R=a.find("base"),z=null;k.url=function(a,c){h!==b.location&&(h=b.location);l!==b.history&&(l=b.history);if(a){if(N!=a)return N=a,d.history?c?l.replaceState(null,"",a):(l.pushState(null,"",a),R.attr("href",R.attr("href"))):(z=a,c?h.replace(a):h.href=a),k}else return z||h.href.replace(/%27/g,"'")};var ca=[],L=!1;k.onUrlChange=function(a){if(!L){if(d.history)w(b).on("popstate",g);if(d.hashchange)w(b).on("hashchange",g);
+else k.addPollFn(g);L=!0}ca.push(a);return a};k.$$checkUrlChange=g;k.baseHref=function(){var a=R.attr("href");return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};var O={},da="",B=k.baseHref();k.cookies=function(a,b){var d,e,f,k;if(a)b===t?m.cookie=escape(a)+"=;path="+B+";expires=Thu, 01 Jan 1970 00:00:00 GMT":v(b)&&(d=(m.cookie=escape(a)+"="+escape(b)+";path="+B).length+1,4096<d&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"));else{if(m.cookie!==
+da)for(da=m.cookie,d=da.split("; "),O={},f=0;f<d.length;f++)e=d[f],k=e.indexOf("="),0<k&&(a=unescape(e.substring(0,k)),O[a]===t&&(O[a]=unescape(e.substring(k+1))));return O}};k.defer=function(a,b){var c;s++;c=n(function(){delete q[c];e(a)},b||0);q[c]=!0;return c};k.defer.cancel=function(a){return q[a]?(delete q[a],p(a),e(E),!0):!1}}function Nd(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new te(b,d,a,c)}]}function Od(){this.$get=function(){function b(b,d){function e(a){a!=
+n&&(p?p==a&&(p=a.n):p=a,f(a.n,a.p),f(a,n),n=a,n.n=null)}function f(a,b){a!=b&&(a&&(a.p=b),b&&(b.n=a))}if(b in a)throw C("$cacheFactory")("iid",b);var g=0,k=D({},d,{id:b}),m={},h=d&&d.capacity||Number.MAX_VALUE,l={},n=null,p=null;return a[b]={put:function(a,b){if(h<Number.MAX_VALUE){var c=l[a]||(l[a]={key:a});e(c)}if(!x(b))return a in m||g++,m[a]=b,g>h&&this.remove(p.key),b},get:function(a){if(h<Number.MAX_VALUE){var b=l[a];if(!b)return;e(b)}return m[a]},remove:function(a){if(h<Number.MAX_VALUE){var b=
+l[a];if(!b)return;b==n&&(n=b.p);b==p&&(p=b.n);f(b.n,b.p);delete l[a]}delete m[a];g--},removeAll:function(){m={};g=0;l={};n=p=null},destroy:function(){l=k=m=null;delete a[b]},info:function(){return D({},k,{size:g})}}}var a={};b.info=function(){var b={};r(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function de(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function ic(b,a){var c={},d="Directive",e=/^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,f=/(([\d\w_\-]+)(?:\:([^;]+))?;?)/,
+g=/^(on[a-z]+|formaction)$/;this.directive=function m(a,e){Da(a,"directive");v(a)?(Db(e,"directiveFactory"),c.hasOwnProperty(a)||(c[a]=[],b.factory(a+d,["$injector","$exceptionHandler",function(b,d){var e=[];r(c[a],function(c,f){try{var g=b.invoke(c);P(g)?g={compile:ba(g)}:!g.compile&&g.link&&(g.compile=ba(g.link));g.priority=g.priority||0;g.index=f;g.name=g.name||a;g.require=g.require||g.controller&&g.name;g.restrict=g.restrict||"A";e.push(g)}catch(m){d(m)}});return e}])),c[a].push(e)):r(a,$b(m));
+return this};this.aHrefSanitizationWhitelist=function(b){return y(b)?(a.aHrefSanitizationWhitelist(b),this):a.aHrefSanitizationWhitelist()};this.imgSrcSanitizationWhitelist=function(b){return y(b)?(a.imgSrcSanitizationWhitelist(b),this):a.imgSrcSanitizationWhitelist()};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document","$sce","$animate","$$sanitizeUri",function(a,b,l,n,p,q,s,F,u,A,N,R){function z(a,b,c,d,e){a instanceof
+w||(a=w(a));r(a,function(b,c){3==b.nodeType&&b.nodeValue.match(/\S+/)&&(a[c]=w(b).wrap("<span></span>").parent()[0])});var f=L(a,b,a,c,d,e);ca(a,"ng-scope");return function(b,c,d,e){Db(b,"scope");var g=c?La.clone.call(a):a;r(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var m=g.length;d<m;d++){var h=g[d].nodeType;1!==h&&9!==h||g.eq(d).data("$scope",b)}c&&c(g,b);f&&f(b,g,g,e);return g}}function ca(a,b){try{a.addClass(b)}catch(c){}}function L(a,b,c,d,e,f){function g(a,c,d,e){var f,h,l,q,n,
+p,s;f=c.length;var M=Array(f);for(q=0;q<f;q++)M[q]=c[q];p=q=0;for(n=m.length;q<n;p++)h=M[p],c=m[q++],f=m[q++],c?(c.scope?(l=a.$new(),w.data(h,"$scope",l)):l=a,s=c.transcludeOnThisElement?O(a,c.transclude,e):!c.templateOnThisElement&&e?e:!e&&b?O(a,b):null,c(f,l,h,d,s)):f&&f(a,h.childNodes,t,e)}for(var m=[],h,l,q,n,p=0;p<a.length;p++)h=new Ob,l=da(a[p],[],h,0===p?d:t,e),(f=l.length?H(l,a[p],h,b,c,null,[],[],f):null)&&f.scope&&ca(h.$$element,"ng-scope"),h=f&&f.terminal||!(q=a[p].childNodes)||!q.length?
+null:L(q,f?(f.transcludeOnThisElement||!f.templateOnThisElement)&&f.transclude:b),m.push(f,h),n=n||f||h,f=null;return n?g:null}function O(a,b,c){return function(d,e,f){var g=!1;d||(d=a.$new(),g=d.$$transcluded=!0);e=b(d,e,f,c);if(g)e.on("$destroy",function(){d.$destroy()});return e}}function da(a,b,c,d,g){var m=c.$attr,h;switch(a.nodeType){case 1:fa(b,pa(Ma(a).toLowerCase()),"E",d,g);for(var l,q,n,p=a.attributes,s=0,F=p&&p.length;s<F;s++){var A=!1,N=!1;l=p[s];if(!Q||8<=Q||l.specified){h=l.name;q=
+aa(l.value);l=pa(h);if(n=U.test(l))h=mb(l.substr(6),"-");var u=l.replace(/(Start|End)$/,"");l===u+"Start"&&(A=h,N=h.substr(0,h.length-5)+"end",h=h.substr(0,h.length-6));l=pa(h.toLowerCase());m[l]=h;if(n||!c.hasOwnProperty(l))c[l]=q,qc(a,l)&&(c[l]=!0);S(a,b,q,l);fa(b,l,"A",d,g,A,N)}}a=a.className;if(v(a)&&""!==a)for(;h=f.exec(a);)l=pa(h[2]),fa(b,l,"C",d,g)&&(c[l]=aa(h[3])),a=a.substr(h.index+h[0].length);break;case 3:K(b,a.nodeValue);break;case 8:try{if(h=e.exec(a.nodeValue))l=pa(h[1]),fa(b,l,"M",
+d,g)&&(c[l]=aa(h[2]))}catch(z){}}b.sort(x);return b}function B(a,b,c){var d=[],e=0;if(b&&a.hasAttribute&&a.hasAttribute(b)){do{if(!a)throw ja("uterdir",b,c);1==a.nodeType&&(a.hasAttribute(b)&&e++,a.hasAttribute(c)&&e--);d.push(a);a=a.nextSibling}while(0<e)}else d.push(a);return w(d)}function I(a,b,c){return function(d,e,f,g,h){e=B(e[0],b,c);return a(d,e,f,g,h)}}function H(a,c,d,e,f,g,m,n,p){function F(a,b,c,d){if(a){c&&(a=I(a,c,d));a.require=G.require;a.directiveName=C;if(L===G||G.$$isolateScope)a=
+tc(a,{isolateScope:!0});m.push(a)}if(b){c&&(b=I(b,c,d));b.require=G.require;b.directiveName=C;if(L===G||G.$$isolateScope)b=tc(b,{isolateScope:!0});n.push(b)}}function A(a,b,c,d){var e,f="data",g=!1;if(v(b)){for(;"^"==(e=b.charAt(0))||"?"==e;)b=b.substr(1),"^"==e&&(f="inheritedData"),g=g||"?"==e;e=null;d&&"data"===f&&(e=d[b]);e=e||c[f]("$"+b+"Controller");if(!e&&!g)throw ja("ctreq",b,a);}else J(b)&&(e=[],r(b,function(b){e.push(A(a,b,c,d))}));return e}function N(a,e,f,g,p){function F(a,b){var c;2>arguments.length&&
+(b=a,a=t);K&&(c=da);return p(a,b,c)}var u,M,z,O,I,B,da={},rb;u=c===f?d:ha(d,new Ob(w(f),d.$attr));M=u.$$element;if(L){var Na=/^\s*([@=&])(\??)\s*(\w*)\s*$/;B=e.$new(!0);!H||H!==L&&H!==L.$$originalDirective?M.data("$isolateScopeNoTemplate",B):M.data("$isolateScope",B);ca(M,"ng-isolate-scope");r(L.scope,function(a,c){var d=a.match(Na)||[],f=d[3]||c,g="?"==d[2],d=d[1],m,l,n,p;B.$$isolateBindings[c]=d+f;switch(d){case "@":u.$observe(f,function(a){B[c]=a});u.$$observers[f].$$scope=e;u[f]&&(B[c]=b(u[f])(e));
+break;case "=":if(g&&!u[f])break;l=q(u[f]);p=l.literal?Aa:function(a,b){return a===b||a!==a&&b!==b};n=l.assign||function(){m=B[c]=l(e);throw ja("nonassign",u[f],L.name);};m=B[c]=l(e);B.$watch(function(){var a=l(e);p(a,B[c])||(p(a,m)?n(e,a=B[c]):B[c]=a);return m=a},null,l.literal);break;case "&":l=q(u[f]);B[c]=function(a){return l(e,a)};break;default:throw ja("iscp",L.name,c,a);}})}rb=p&&F;R&&r(R,function(a){var b={$scope:a===L||a.$$isolateScope?B:e,$element:M,$attrs:u,$transclude:rb},c;I=a.controller;
+"@"==I&&(I=u[a.name]);c=s(I,b);da[a.name]=c;K||M.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(z=m.length;g<z;g++)try{O=m[g],O(O.isolateScope?B:e,M,u,O.require&&A(O.directiveName,O.require,M,da),rb)}catch(G){l(G,ia(M))}g=e;L&&(L.template||null===L.templateUrl)&&(g=B);a&&a(g,f.childNodes,t,p);for(g=n.length-1;0<=g;g--)try{O=n[g],O(O.isolateScope?B:e,M,u,O.require&&A(O.directiveName,O.require,M,da),rb)}catch(y){l(y,ia(M))}}p=p||{};for(var u=-Number.MAX_VALUE,
+O,R=p.controllerDirectives,L=p.newIsolateScopeDirective,H=p.templateDirective,fa=p.nonTlbTranscludeDirective,x=!1,D=!1,K=p.hasElementTranscludeDirective,Z=d.$$element=w(c),G,C,V,S=e,Q,Fa=0,qa=a.length;Fa<qa;Fa++){G=a[Fa];var U=G.$$start,Y=G.$$end;U&&(Z=B(c,U,Y));V=t;if(u>G.priority)break;if(V=G.scope)O=O||G,G.templateUrl||(db("new/isolated scope",L,G,Z),T(V)&&(L=G));C=G.name;!G.templateUrl&&G.controller&&(V=G.controller,R=R||{},db("'"+C+"' controller",R[C],G,Z),R[C]=G);if(V=G.transclude)x=!0,G.$$tlb||
+(db("transclusion",fa,G,Z),fa=G),"element"==V?(K=!0,u=G.priority,V=Z,Z=d.$$element=w(X.createComment(" "+C+": "+d[C]+" ")),c=Z[0],Na(f,Ba.call(V,0),c),S=z(V,e,u,g&&g.name,{nonTlbTranscludeDirective:fa})):(V=w(Kb(c)).contents(),Z.empty(),S=z(V,e));if(G.template)if(D=!0,db("template",H,G,Z),H=G,V=P(G.template)?G.template(Z,d):G.template,V=W(V),G.replace){g=G;V=Ib.test(V)?w(aa(V)):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",C,"");Na(f,Z,c);qa={$attr:{}};V=da(c,[],qa);var $=a.splice(Fa+
+1,a.length-(Fa+1));L&&y(V);a=a.concat(V).concat($);E(d,qa);qa=a.length}else Z.html(V);if(G.templateUrl)D=!0,db("template",H,G,Z),H=G,G.replace&&(g=G),N=ue(a.splice(Fa,a.length-Fa),Z,d,f,x&&S,m,n,{controllerDirectives:R,newIsolateScopeDirective:L,templateDirective:H,nonTlbTranscludeDirective:fa}),qa=a.length;else if(G.compile)try{Q=G.compile(Z,d,S),P(Q)?F(null,Q,U,Y):Q&&F(Q.pre,Q.post,U,Y)}catch(ve){l(ve,ia(Z))}G.terminal&&(N.terminal=!0,u=Math.max(u,G.priority))}N.scope=O&&!0===O.scope;N.transcludeOnThisElement=
+x;N.templateOnThisElement=D;N.transclude=S;p.hasElementTranscludeDirective=K;return N}function y(a){for(var b=0,c=a.length;b<c;b++)a[b]=bc(a[b],{$$isolateScope:!0})}function fa(b,e,f,g,h,q,n){if(e===h)return null;h=null;if(c.hasOwnProperty(e)){var p;e=a.get(e+d);for(var s=0,u=e.length;s<u;s++)try{p=e[s],(g===t||g>p.priority)&&-1!=p.restrict.indexOf(f)&&(q&&(p=bc(p,{$$start:q,$$end:n})),b.push(p),h=p)}catch(F){l(F)}}return h}function E(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!=
+e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(ca(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function ue(a,b,c,d,e,f,g,h){var m=[],l,q,s=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),N=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl;
+b.empty();n.get(A.getTrustedResourceUrl(N),{cache:p}).success(function(n){var p,A;n=W(n);if(u.replace){n=Ib.test(n)?w(aa(n)):[];p=n[0];if(1!=n.length||1!==p.nodeType)throw ja("tplrt",u.name,N);n={$attr:{}};Na(d,b,p);var z=da(p,[],n);T(u.scope)&&y(z);a=z.concat(a);E(c,n)}else p=s,b.html(n);a.unshift(F);l=H(a,p,c,e,b,u,f,g,h);r(d,function(a,c){a==p&&(d[c]=b[0])});for(q=L(b[0].childNodes,e);m.length;){n=m.shift();A=m.shift();var R=m.shift(),I=m.shift(),z=b[0];if(A!==s){var B=A.className;h.hasElementTranscludeDirective&&
+u.replace||(z=Kb(p));Na(R,w(A),z);ca(w(z),B)}A=l.transcludeOnThisElement?O(n,l.transclude,I):I;l(q,n,z,d,A)}m=null}).error(function(a,b,c,d){throw ja("tpload",d.url);});return function(a,b,c,d,e){a=e;m?(m.push(b),m.push(c),m.push(d),m.push(a)):(l.transcludeOnThisElement&&(a=O(b,l.transclude,e)),l(q,b,c,d,a))}}function x(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name<b.name?-1:1:a.index-b.index}function db(a,b,c,d){if(b)throw ja("multidir",b.name,c.name,a,ia(d));}function K(a,
+c){var d=b(c,!0);d&&a.push({priority:0,compile:function(a){var b=a.parent().length;b&&ca(a.parent(),"ng-binding");return function(a,c){var e=c.parent(),f=e.data("$binding")||[];f.push(d);e.data("$binding",f);b||ca(e,"ng-binding");a.$watch(d,function(a){c[0].nodeValue=a})}}})}function C(a,b){if("srcdoc"==b)return A.HTML;var c=Ma(a);if("xlinkHref"==b||"FORM"==c&&"action"==b||"IMG"!=c&&("src"==b||"ngSrc"==b))return A.RESOURCE_URL}function S(a,c,d,e){var f=b(d,!0);if(f){if("multiple"===e&&"SELECT"===
+Ma(a))throw ja("selmulti",ia(a));c.push({priority:100,compile:function(){return{pre:function(c,d,m){d=m.$$observers||(m.$$observers={});if(g.test(e))throw ja("nodomevents");if(f=b(m[e],!0,C(a,e)))m[e]=f(c),(d[e]||(d[e]=[])).$$inter=!0,(m.$$observers&&m.$$observers[e].$$scope||c).$watch(f,function(a,b){"class"===e&&a!=b?m.$updateClass(a,b):m.$set(e,a)})}}}})}}function Na(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,m;if(a)for(g=0,m=a.length;g<m;g++)if(a[g]==d){a[g++]=c;m=g+e-1;for(var h=a.length;g<
+h;g++,m++)m<h?a[g]=a[m]:delete a[g];a.length-=e-1;break}f&&f.replaceChild(c,d);a=X.createDocumentFragment();a.appendChild(d);c[w.expando]=d[w.expando];d=1;for(e=b.length;d<e;d++)f=b[d],w(f).remove(),a.appendChild(f),delete b[d];b[0]=c;b.length=1}function tc(a,b){return D(function(){return a.apply(null,arguments)},a,b)}var Ob=function(a,b){this.$$element=a;this.$attr=b||{}};Ob.prototype={$normalize:pa,$addClass:function(a){a&&0<a.length&&N.addClass(this.$$element,a)},$removeClass:function(a){a&&0<
+a.length&&N.removeClass(this.$$element,a)},$updateClass:function(a,b){var c=uc(a,b),d=uc(b,a);0===c.length?N.removeClass(this.$$element,d):0===d.length?N.addClass(this.$$element,c):N.setClass(this.$$element,c,d)},$set:function(a,b,c,d){var e=qc(this.$$element[0],a);e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=mb(a,"-"));e=Ma(this.$$element);if("A"===e&&"href"===a||"IMG"===e&&"src"===a)this[a]=b=R(b,"src"===a);!1!==c&&(null===b||b===t?this.$$element.removeAttr(d):
+this.$$element.attr(d,b));(c=this.$$observers)&&r(c[a],function(a){try{a(b)}catch(c){l(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);F.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var qa=b.startSymbol(),Z=b.endSymbol(),W="{{"==qa||"}}"==Z?Qa:function(a){return a.replace(/\{\{/g,qa).replace(/}}/g,Z)},U=/^ngAttr[A-Z]/;return z}]}function pa(b){return Za(b.replace(we,""))}function uc(b,a){var c="",d=b.split(/\s+/),e=a.split(/\s+/),f=
+0;a:for(;f<d.length;f++){for(var g=d[f],k=0;k<e.length;k++)if(g==e[k])continue a;c+=(0<c.length?" ":"")+g}return c}function Pd(){var b={},a=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,d){Da(a,"controller");T(a)?D(b,a):b[a]=d};this.$get=["$injector","$window",function(c,d){return function(e,f){var g,k,m;v(e)&&(g=e.match(a),k=g[1],m=g[3],e=b.hasOwnProperty(k)?b[k]:hc(f.$scope,k,!0)||hc(d,k,!0),Wa(e,k,!0));g=c.instantiate(e,f);if(m){if(!f||"object"!==typeof f.$scope)throw C("$controller")("noscp",
+k||e.name,m);f.$scope[m]=g}return g}}]}function Qd(){this.$get=["$window",function(b){return w(b.document)}]}function Rd(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function vc(b){var a={},c,d,e;if(!b)return a;r(b.split("\n"),function(b){e=b.indexOf(":");c=K(aa(b.substr(0,e)));d=aa(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function wc(b){var a=T(b)?b:t;return function(c){a||(a=vc(b));return c?a[K(c)]||null:a}}function xc(b,a,c){if(P(c))return c(b,
+a);r(c,function(c){b=c(b,a)});return b}function Ud(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d={"Content-Type":"application/json;charset=utf-8"},e=this.defaults={transformResponse:[function(d){v(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=cc(d)));return d}],transformRequest:[function(a){return T(a)&&"[object File]"!==za.call(a)&&"[object Blob]"!==za.call(a)?na(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:ha(d),put:ha(d),patch:ha(d)},xsrfCookieName:"XSRF-TOKEN",
+xsrfHeaderName:"X-XSRF-TOKEN"},f=this.interceptors=[],g=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,d,n,p){function q(a){function b(a){var d=D({},a,{data:xc(a.data,a.headers,c.transformResponse)});return 200<=a.status&&300>a.status?d:n.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=D({},a.headers),d,f,b=D({},b.common,b[K(a.method)]);
+a:for(d in b){a=K(d);for(f in c)if(K(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){P(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);return c}(a);D(c,a);c.headers=d;c.method=Ia(c.method);var f=[function(a){d=a.headers;var c=xc(a.data,wc(d),a.transformRequest);x(c)&&r(d,function(a,b){"content-type"===K(b)&&delete d[b]});x(a.withCredentials)&&!x(e.withCredentials)&&(a.withCredentials=e.withCredentials);return s(a,c,d).then(b,b)},t],g=n.when(c);for(r(A,function(a){(a.request||a.requestError)&&
+f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var m=f.shift(),g=g.then(a,m)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function s(c,f,g){function h(a,b,c,e){I&&(200<=a&&300>a?I.put(w,[a,b,vc(c),e]):I.remove(w));p(b,a,c,e);d.$$phase||d.$apply()}function p(a,b,d,e){b=Math.max(b,0);(200<=
+b&&300>b?A.resolve:A.reject)({data:a,status:b,headers:wc(d),config:c,statusText:e})}function s(){var a=Ra(q.pendingRequests,c);-1!==a&&q.pendingRequests.splice(a,1)}var A=n.defer(),r=A.promise,I,H,w=F(c.url,c.params);q.pendingRequests.push(c);r.then(s,s);!c.cache&&!e.cache||(!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method)||(I=T(c.cache)?c.cache:T(e.cache)?e.cache:u);if(I)if(H=I.get(w),y(H)){if(H&&P(H.then))return H.then(s,s),H;J(H)?p(H[1],H[0],ha(H[2]),H[3]):p(H,200,{},"OK")}else I.put(w,r);x(H)&&
+((H=Pb(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:t)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=H),a(c.method,w,f,h,g,c.timeout,c.withCredentials,c.responseType));return r}function F(a,b){if(!b)return a;var c=[];Tc(b,function(a,b){null===a||x(a)||(J(a)||(a=[a]),r(a,function(a){T(a)&&(a=ta(a)?a.toISOString():na(a));c.push(Ca(b)+"="+Ca(a))}))});0<c.length&&(a+=(-1==a.indexOf("?")?"?":"&")+c.join("&"));return a}var u=c("$http"),A=[];r(f,function(a){A.unshift(v(a)?p.get(a):p.invoke(a))});r(g,
+function(a,b){var c=v(a)?p.get(a):p.invoke(a);A.splice(b,0,{response:function(a){return c(n.when(a))},responseError:function(a){return c(n.reject(a))}})});q.pendingRequests=[];(function(a){r(arguments,function(a){q[a]=function(b,c){return q(D(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){r(arguments,function(a){q[a]=function(b,c,d){return q(D(d||{},{method:a,url:b,data:c}))}})})("post","put");q.defaults=e;return q}]}function xe(b){if(8>=Q&&(!b.match(/^(get|post|head|put|delete|options)$/i)||
+!W.XMLHttpRequest))return new W.ActiveXObject("Microsoft.XMLHTTP");if(W.XMLHttpRequest)return new W.XMLHttpRequest;throw C("$httpBackend")("noxhr");}function Vd(){this.$get=["$browser","$window","$document",function(b,a,c){return ye(b,xe,b.defer,a.angular.callbacks,c[0])}]}function ye(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){$a(f,"load",g);$a(f,"error",g);e.body.removeChild(f);f=null;var k=-1,s="unknown";a&&("load"!==
+a.type||d[b].called||(a={type:"error"}),s=a.type,k="error"===a.type?404:200);c&&c(k,s)};sb(f,"load",g);sb(f,"error",g);8>=Q&&(f.onreadystatechange=function(){v(f.readyState)&&/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,m,h,l,n,p,q,s){function F(){A=g;R&&R();z&&z.abort()}function u(a,d,e,f,g){L&&c.cancel(L);R=z=null;0===d&&(d=e?200:"file"==ua(m).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(E)}
+var A;b.$$incOutstandingRequestCount();m=m||b.url();if("jsonp"==K(e)){var N="_"+(d.counter++).toString(36);d[N]=function(a){d[N].data=a;d[N].called=!0};var R=f(m.replace("JSON_CALLBACK","angular.callbacks."+N),N,function(a,b){u(l,a,d[N].data,"",b);d[N]=E})}else{var z=a(e);z.open(e,m,!0);r(n,function(a,b){y(a)&&z.setRequestHeader(b,a)});z.onreadystatechange=function(){if(z&&4==z.readyState){var a=null,b=null,c="";A!==g&&(a=z.getAllResponseHeaders(),b="response"in z?z.response:z.responseText);A===g&&
+10>Q||(c=z.statusText);u(l,A||z.status,b,a,c)}};q&&(z.withCredentials=!0);if(s)try{z.responseType=s}catch(ca){if("json"!==s)throw ca;}z.send(h||null)}if(0<p)var L=c(F,p);else p&&P(p.then)&&p.then(F)}}function Sd(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler","$sce",function(c,d,e){function f(f,h,l){for(var n,p,q=0,s=[],F=f.length,u=!1,A=[];q<F;)-1!=(n=f.indexOf(b,q))&&-1!=(p=f.indexOf(a,
+n+g))?(q!=n&&s.push(f.substring(q,n)),s.push(q=c(u=f.substring(n+g,p))),q.exp=u,q=p+k,u=!0):(q!=F&&s.push(f.substring(q)),q=F);(F=s.length)||(s.push(""),F=1);if(l&&1<s.length)throw yc("noconcat",f);if(!h||u)return A.length=F,q=function(a){try{for(var b=0,c=F,g;b<c;b++){if("function"==typeof(g=s[b]))if(g=g(a),g=l?e.getTrusted(l,g):e.valueOf(g),null==g)g="";else switch(typeof g){case "string":break;case "number":g=""+g;break;default:g=na(g)}A[b]=g}return A.join("")}catch(k){a=yc("interr",f,k.toString()),
+d(a)}},q.exp=f,q.parts=s,q}var g=b.length,k=a.length;f.startSymbol=function(){return b};f.endSymbol=function(){return a};return f}]}function Td(){this.$get=["$rootScope","$window","$q",function(b,a,c){function d(d,g,k,m){var h=a.setInterval,l=a.clearInterval,n=c.defer(),p=n.promise,q=0,s=y(m)&&!m;k=y(k)?k:0;p.then(null,null,d);p.$$intervalId=h(function(){n.notify(q++);0<k&&q>=k&&(n.resolve(q),l(p.$$intervalId),delete e[p.$$intervalId]);s||b.$apply()},g);e[p.$$intervalId]=n;return p}var e={};d.cancel=
+function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],!0):!1};return d}]}function bd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),
+SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Qb(b){b=b.split("/");for(var a=b.length;a--;)b[a]=
+lb(b[a]);return b.join("/")}function zc(b,a,c){b=ua(b,c);a.$$protocol=b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||ze[b.protocol]||null}function Ac(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=ua(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=ec(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function ra(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function eb(b){var a=
+b.indexOf("#");return-1==a?b:b.substr(0,a)}function Rb(b){return b.substr(0,eb(b).lastIndexOf("/")+1)}function Bc(b,a){this.$$html5=!0;a=a||"";var c=Rb(b);zc(b,this,b);this.$$parse=function(a){var e=ra(c,a);if(!v(e))throw Sb("ipthprfx",a,c);Ac(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Cb(this.$$search),b=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;
+if((e=ra(b,d))!==t)return d=e,(e=ra(a,e))!==t?c+(ra("/",e)||e):b+d;if((e=ra(c,d))!==t)return c+e;if(c==d+"/")return c}}function Tb(b,a){var c=Rb(b);zc(b,this,b);this.$$parse=function(d){var e=ra(b,d)||ra(c,d),e="#"==e.charAt(0)?ra(a,e):this.$$html5?e:"";if(!v(e))throw Sb("ihshprfx",d,a);Ac(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?
+"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(eb(b)==eb(a))return a}}function Ub(b,a){this.$$html5=!0;Tb.apply(this,arguments);var c=Rb(b);this.$$rewrite=function(d){var e;if(b==eb(d))return d;if(e=ra(c,d))return b+a+e;if(c===d+"/")return c};this.$$compose=function(){var c=Cb(this.$$search),e=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Qb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function tb(b){return function(){return this[b]}}
+function Cc(b,a){return function(c){if(x(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Wd(){var b="",a=!1;this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return y(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",k.absUrl(),a)}var k,m,h=d.baseHref(),l=d.url(),n;a?(n=l.substring(0,l.indexOf("/",l.indexOf("//")+2))+(h||"/"),m=e.history?Bc:Ub):(n=
+eb(l),m=Tb);k=new m(n,"#"+b);k.$$parse(k.$$rewrite(l));var p=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var e=w(a.target);"a"!==K(e[0].nodeName);)if(e[0]===f[0]||!(e=e.parent())[0])return;var g=e.prop("href");T(g)&&"[object SVGAnimatedString]"===g.toString()&&(g=ua(g.animVal).href);if(!p.test(g)){if(m===Ub){var h=e.attr("href")||e.attr("xlink:href");if(h&&0>h.indexOf("://"))if(g="#"+b,"/"==h[0])g=n+g+h;else if("#"==h[0])g=n+g+(k.path()||"/")+h;
+else{var l=k.path().split("/"),h=h.split("/");2!==l.length||l[1]||(l.length=1);for(var q=0;q<h.length;q++)"."!=h[q]&&(".."==h[q]?l.pop():h[q].length&&l.push(h[q]));g=n+g+l.join("/")}}l=k.$$rewrite(g);g&&(!e.attr("target")&&l&&!a.isDefaultPrevented())&&(a.preventDefault(),l!=d.url()&&(k.$$parse(l),c.$apply(),W.angular["ff-684208-preventDefault"]=!0))}}});k.absUrl()!=l&&d.url(k.absUrl(),!0);d.onUrlChange(function(a){k.absUrl()!=a&&(c.$evalAsync(function(){var b=k.absUrl();k.$$parse(a);c.$broadcast("$locationChangeStart",
+a,b).defaultPrevented?(k.$$parse(b),d.url(b)):g(b)}),c.$$phase||c.$digest())});var q=0;c.$watch(function(){var a=d.url(),b=k.$$replace;q&&a==k.absUrl()||(q++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",k.absUrl(),a).defaultPrevented?k.$$parse(a):(d.url(k.absUrl(),b),g(a))}));k.$$replace=!1;return q});return k}]}function Xd(){var b=!0,a=this;this.debugEnabled=function(a){return y(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&
+-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||E;a=!1;try{a=!!e.apply}catch(m){}return a?function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function ka(b,
+a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw la("isecfld",a);return b}function va(b,a){if(b){if(b.constructor===b)throw la("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw la("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw la("isecdom",a);if(b===Object)throw la("isecobj",a);}return b}function ub(b,a,c,d,e){va(b,d);e=e||{};a=a.split(".");for(var f,g=0;1<a.length;g++){f=ka(a.shift(),
+d);var k=va(b[f],d);k||(k={},b[f]=k);b=k;b.then&&e.unwrapPromises&&(wa(d),"$$v"in b||function(a){a.then(function(b){a.$$v=b})}(b),b.$$v===t&&(b.$$v={}),b=b.$$v)}f=ka(a.shift(),d);va(b[f],d);return b[f]=c}function Dc(b,a,c,d,e,f,g){ka(b,f);ka(a,f);ka(c,f);ka(d,f);ka(e,f);return g.unwrapPromises?function(g,m){var h=m&&m.hasOwnProperty(b)?m:g,l;if(null==h)return h;(h=h[b])&&h.then&&(wa(f),"$$v"in h||(l=h,l.$$v=t,l.then(function(a){l.$$v=a})),h=h.$$v);if(!a)return h;if(null==h)return t;(h=h[a])&&h.then&&
+(wa(f),"$$v"in h||(l=h,l.$$v=t,l.then(function(a){l.$$v=a})),h=h.$$v);if(!c)return h;if(null==h)return t;(h=h[c])&&h.then&&(wa(f),"$$v"in h||(l=h,l.$$v=t,l.then(function(a){l.$$v=a})),h=h.$$v);if(!d)return h;if(null==h)return t;(h=h[d])&&h.then&&(wa(f),"$$v"in h||(l=h,l.$$v=t,l.then(function(a){l.$$v=a})),h=h.$$v);if(!e)return h;if(null==h)return t;(h=h[e])&&h.then&&(wa(f),"$$v"in h||(l=h,l.$$v=t,l.then(function(a){l.$$v=a})),h=h.$$v);return h}:function(f,g){var h=g&&g.hasOwnProperty(b)?g:f;if(null==
+h)return h;h=h[b];if(!a)return h;if(null==h)return t;h=h[a];if(!c)return h;if(null==h)return t;h=h[c];if(!d)return h;if(null==h)return t;h=h[d];return e?null==h?t:h=h[e]:h}}function Ec(b,a,c){if(Vb.hasOwnProperty(b))return Vb[b];var d=b.split("."),e=d.length,f;if(a.csp)f=6>e?Dc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,f){var g=0,k;do k=Dc(d[g++],d[g++],d[g++],d[g++],d[g++],c,a)(b,f),f=t,b=k;while(g<e);return k};else{var g="var p;\n";r(d,function(b,d){ka(b,c);g+="if(s == null) return undefined;\ns="+
+(d?"s":'((k&&k.hasOwnProperty("'+b+'"))?k:s)')+'["'+b+'"];\n'+(a.unwrapPromises?'if (s && s.then) {\n pw("'+c.replace(/(["\r\n])/g,"\\$1")+'");\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n':"")});var g=g+"return s;",k=new Function("s","k","pw",g);k.toString=ba(g);f=a.unwrapPromises?function(a,b){return k(a,b,wa)}:k}"hasOwnProperty"!==b&&(Vb[b]=f);return f}function Yd(){var b={},a={csp:!1,unwrapPromises:!1,logPromiseWarnings:!0};this.unwrapPromises=
+function(b){return y(b)?(a.unwrapPromises=!!b,this):a.unwrapPromises};this.logPromiseWarnings=function(b){return y(b)?(a.logPromiseWarnings=b,this):a.logPromiseWarnings};this.$get=["$filter","$sniffer","$log",function(c,d,e){a.csp=d.csp;wa=function(b){a.logPromiseWarnings&&!Fc.hasOwnProperty(b)&&(Fc[b]=!0,e.warn("[$parse] Promise found in the expression `"+b+"`. Automatic unwrapping of promises in Angular expressions is deprecated."))};return function(d){var e;switch(typeof d){case "string":if(b.hasOwnProperty(d))return b[d];
+e=new Wb(a);e=(new fb(e,c,a)).parse(d);"hasOwnProperty"!==d&&(b[d]=e);return e;case "function":return d;default:return E}}}]}function $d(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Ae(function(a){b.$evalAsync(a)},a)}]}function Ae(b,a){function c(a){return a}function d(a){return g(a)}var e=function(){var g=[],h,l;return l={resolve:function(a){if(g){var c=g;g=t;h=f(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],h.then(a[0],a[1],a[2])})}},reject:function(a){l.resolve(k(a))},
+notify:function(a){if(g){var c=g;g.length&&b(function(){for(var b,d=0,e=c.length;d<e;d++)b=c[d],b[2](a)})}},promise:{then:function(b,f,k){var l=e(),F=function(d){try{l.resolve((P(b)?b:c)(d))}catch(e){l.reject(e),a(e)}},u=function(b){try{l.resolve((P(f)?f:d)(b))}catch(c){l.reject(c),a(c)}},A=function(b){try{l.notify((P(k)?k:c)(b))}catch(d){a(d)}};g?g.push([F,u,A]):h.then(F,u,A);return l.promise},"catch":function(a){return this.then(null,a)},"finally":function(a){function b(a,c){var d=e();c?d.resolve(a):
+d.reject(a);return d.promise}function d(e,f){var g=null;try{g=(a||c)()}catch(k){return b(k,!1)}return g&&P(g.then)?g.then(function(){return b(e,f)},function(a){return b(a,!1)}):b(e,f)}return this.then(function(a){return d(a,!0)},function(a){return d(a,!1)})}}}},f=function(a){return a&&P(a.then)?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},g=function(a){var b=e();b.reject(a);return b.promise},k=function(c){return{then:function(f,g){var k=e();b(function(){try{k.resolve((P(g)?
+g:d)(c))}catch(b){k.reject(b),a(b)}});return k.promise}}};return{defer:e,reject:g,when:function(k,h,l,n){var p=e(),q,s=function(b){try{return(P(h)?h:c)(b)}catch(d){return a(d),g(d)}},F=function(b){try{return(P(l)?l:d)(b)}catch(c){return a(c),g(c)}},u=function(b){try{return(P(n)?n:c)(b)}catch(d){a(d)}};b(function(){f(k).then(function(a){q||(q=!0,p.resolve(f(a).then(s,F,u)))},function(a){q||(q=!0,p.resolve(F(a)))},function(a){q||p.notify(u(a))})});return p.promise},all:function(a){var b=e(),c=0,d=J(a)?
+[]:{};r(a,function(a,e){c++;f(a).then(function(a){d.hasOwnProperty(e)||(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||b.reject(a)})});0===c&&b.resolve(d);return b.promise}}}function ge(){this.$get=["$window","$timeout",function(b,a){var c=b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame,d=b.cancelAnimationFrame||b.webkitCancelAnimationFrame||b.mozCancelAnimationFrame||b.webkitCancelRequestAnimationFrame,e=!!c,f=e?function(a){var b=c(a);return function(){d(b)}}:
+function(b){var c=a(b,16.66,!1);return function(){a.cancel(c)}};f.supported=e;return f}]}function Zd(){var b=10,a=C("$rootScope"),c=null;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse","$browser",function(d,e,f,g){function k(){this.$id=hb();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$postDigestQueue=
+[];this.$$listeners={};this.$$listenerCount={};this.$$isolateBindings={}}function m(b){if(p.$$phase)throw a("inprog",p.$$phase);p.$$phase=b}function h(a,b){var c=f(a);Wa(c,b);return c}function l(a,b,c){do a.$$listenerCount[c]-=b,0===a.$$listenerCount[c]&&delete a.$$listenerCount[c];while(a=a.$parent)}function n(){}k.prototype={constructor:k,$new:function(a){a?(a=new k,a.$root=this.$root,a.$$asyncQueue=this.$$asyncQueue,a.$$postDigestQueue=this.$$postDigestQueue):(this.$$childScopeClass||(this.$$childScopeClass=
+function(){this.$$watchers=this.$$nextSibling=this.$$childHead=this.$$childTail=null;this.$$listeners={};this.$$listenerCount={};this.$id=hb();this.$$childScopeClass=null},this.$$childScopeClass.prototype=this),a=new this.$$childScopeClass);a["this"]=a;a.$parent=this;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,d){var e=h(a,"watch"),f=this.$$watchers,g={fn:b,last:n,get:e,exp:a,
+eq:!!d};c=null;if(!P(b)){var k=h(b||E,"listener");g.fn=function(a,b,c){k(c)}}if("string"==typeof a&&e.constant){var l=g.fn;g.fn=function(a,b,c){l.call(this,a,b,c);Sa(f,g)}}f||(f=this.$$watchers=[]);f.unshift(g);return function(){Sa(f,g);c=null}},$watchCollection:function(a,b){var c=this,d,e,g,k=1<b.length,h=0,l=f(a),m=[],p={},n=!0,r=0;return this.$watch(function(){d=l(c);var a,b,f;if(T(d))if(Pa(d))for(e!==m&&(e=m,r=e.length=0,h++),a=d.length,r!==a&&(h++,e.length=r=a),b=0;b<a;b++)f=e[b]!==e[b]&&d[b]!==
+d[b],f||e[b]===d[b]||(h++,e[b]=d[b]);else{e!==p&&(e=p={},r=0,h++);a=0;for(b in d)d.hasOwnProperty(b)&&(a++,e.hasOwnProperty(b)?(f=e[b]!==e[b]&&d[b]!==d[b],f||e[b]===d[b]||(h++,e[b]=d[b])):(r++,e[b]=d[b],h++));if(r>a)for(b in h++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(r--,delete e[b])}else e!==d&&(e=d,h++);return h},function(){n?(n=!1,b(d,d,c)):b(d,g,c);if(k)if(T(d))if(Pa(d)){g=Array(d.length);for(var a=0;a<d.length;a++)g[a]=d[a]}else for(a in g={},d)kb.call(d,a)&&(g[a]=d[a]);else g=d})},$digest:function(){var d,
+f,k,h,l=this.$$asyncQueue,r=this.$$postDigestQueue,R,z,t=b,L,O=[],w,B,I;m("$digest");g.$$checkUrlChange();c=null;do{z=!1;for(L=this;l.length;){try{I=l.shift(),I.scope.$eval(I.expression)}catch(H){p.$$phase=null,e(H)}c=null}a:do{if(h=L.$$watchers)for(R=h.length;R--;)try{if(d=h[R])if((f=d.get(L))!==(k=d.last)&&!(d.eq?Aa(f,k):"number"===typeof f&&"number"===typeof k&&isNaN(f)&&isNaN(k)))z=!0,c=d,d.last=d.eq?Ha(f,null):f,d.fn(f,k===n?f:k,L),5>t&&(w=4-t,O[w]||(O[w]=[]),B=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):
+d.exp,B+="; newVal: "+na(f)+"; oldVal: "+na(k),O[w].push(B));else if(d===c){z=!1;break a}}catch(y){p.$$phase=null,e(y)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((z||l.length)&&!t--)throw p.$$phase=null,a("infdig",b,na(O));}while(z||l.length);for(p.$$phase=null;r.length;)try{r.shift()()}catch(v){e(v)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(r(this.$$listenerCount,
+Bb(null,l,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&&(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=E,this.$on=
+this.$watch=function(){return E})}},$eval:function(a,b){return f(a)(this,b)},$evalAsync:function(a){p.$$phase||p.$$asyncQueue.length||g.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return m("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=
+c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){c[Ra(c,b)]=null;l(e,1,a)}},$emit:function(a,b){var c=[],d,f=this,g=!1,k={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){k.defaultPrevented=!0},defaultPrevented:!1},h=[k].concat(Ba.call(arguments,1)),l,m;do{d=f.$$listeners[a]||c;k.currentScope=f;l=0;for(m=d.length;l<m;l++)if(d[l])try{d[l].apply(null,h)}catch(p){e(p)}else d.splice(l,
+1),l--,m--;if(g)break;f=f.$parent}while(f);return k},$broadcast:function(a,b){for(var c=this,d=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},g=[f].concat(Ba.call(arguments,1)),k,h;c=d;){f.currentScope=c;d=c.$$listeners[a]||[];k=0;for(h=d.length;k<h;k++)if(d[k])try{d[k].apply(null,g)}catch(l){e(l)}else d.splice(k,1),k--,h--;if(!(d=c.$$listenerCount[a]&&c.$$childHead||c!==this&&c.$$nextSibling))for(;c!==this&&!(d=c.$$nextSibling);)c=c.$parent}return f}};
+var p=new k;return p}]}function cd(){var b=/^\s*(https?|ftp|mailto|tel|file):/,a=/^\s*((https?|ftp|file):|data:image\/)/;this.aHrefSanitizationWhitelist=function(a){return y(a)?(b=a,this):b};this.imgSrcSanitizationWhitelist=function(b){return y(b)?(a=b,this):a};this.$get=function(){return function(c,d){var e=d?a:b,f;if(!Q||8<=Q)if(f=ua(c).href,""!==f&&!f.match(e))return"unsafe:"+f;return c}}}function Be(b){if("self"===b)return b;if(v(b)){if(-1<b.indexOf("***"))throw xa("iwcard",b);b=b.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,
+"\\$1").replace(/\x08/g,"\\x08").replace("\\*\\*",".*").replace("\\*","[^:/.?&;]*");return RegExp("^"+b+"$")}if(jb(b))return RegExp("^"+b.source+"$");throw xa("imatcher");}function Gc(b){var a=[];y(b)&&r(b,function(b){a.push(Be(b))});return a}function be(){this.SCE_CONTEXTS=ga;var b=["self"],a=[];this.resourceUrlWhitelist=function(a){arguments.length&&(b=Gc(a));return b};this.resourceUrlBlacklist=function(b){arguments.length&&(a=Gc(b));return a};this.$get=["$injector",function(c){function d(a){var b=
+function(a){this.$$unwrapTrustedValue=function(){return a}};a&&(b.prototype=new a);b.prototype.valueOf=function(){return this.$$unwrapTrustedValue()};b.prototype.toString=function(){return this.$$unwrapTrustedValue().toString()};return b}var e=function(a){throw xa("unsafe");};c.has("$sanitize")&&(e=c.get("$sanitize"));var f=d(),g={};g[ga.HTML]=d(f);g[ga.CSS]=d(f);g[ga.URL]=d(f);g[ga.JS]=d(f);g[ga.RESOURCE_URL]=d(g[ga.URL]);return{trustAs:function(a,b){var c=g.hasOwnProperty(a)?g[a]:null;if(!c)throw xa("icontext",
+a,b);if(null===b||b===t||""===b)return b;if("string"!==typeof b)throw xa("itype",a);return new c(b)},getTrusted:function(c,d){if(null===d||d===t||""===d)return d;var f=g.hasOwnProperty(c)?g[c]:null;if(f&&d instanceof f)return d.$$unwrapTrustedValue();if(c===ga.RESOURCE_URL){var f=ua(d.toString()),l,n,p=!1;l=0;for(n=b.length;l<n;l++)if("self"===b[l]?Pb(f):b[l].exec(f.href)){p=!0;break}if(p)for(l=0,n=a.length;l<n;l++)if("self"===a[l]?Pb(f):a[l].exec(f.href)){p=!1;break}if(p)return d;throw xa("insecurl",
+d.toString());}if(c===ga.HTML)return e(d);throw xa("unsafe");},valueOf:function(a){return a instanceof f?a.$$unwrapTrustedValue():a}}}]}function ae(){var b=!0;this.enabled=function(a){arguments.length&&(b=!!a);return b};this.$get=["$parse","$sniffer","$sceDelegate",function(a,c,d){if(b&&c.msie&&8>c.msieDocumentMode)throw xa("iequirks");var e=ha(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},
+e.valueOf=Qa);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,k=e.trustAs;r(ga,function(a,b){var c=K(b);e[Za("parse_as_"+c)]=function(b){return f(a,b)};e[Za("get_trusted_"+c)]=function(b){return g(a,b)};e[Za("trust_as_"+c)]=function(b){return k(a,b)}});return e}]}function ce(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||
+{}).userAgent),f=a[0]||{},g=f.documentMode,k,m=/^(Moz|webkit|O|ms)(?=[A-Z])/,h=f.body&&f.body.style,l=!1,n=!1;if(h){for(var p in h)if(l=m.exec(p)){k=l[0];k=k.substr(0,1).toUpperCase()+k.substr(1);break}k||(k="WebkitOpacity"in h&&"webkit");l=!!("transition"in h||k+"Transition"in h);n=!!("animation"in h||k+"Animation"in h);!d||l&&n||(l=v(f.body.style.webkitTransition),n=v(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7<
+g),hasEvent:function(a){if("input"==a&&9==Q)return!1;if(x(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Xa(),vendorPrefix:k,transitions:l,animations:n,android:d,msie:Q,msieDocumentMode:g}}]}function ee(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,k,m){var h=c.defer(),l=h.promise,n=y(m)&&!m;k=a.defer(function(){try{h.resolve(e())}catch(a){h.reject(a),d(a)}finally{delete f[l.$$timeoutId]}n||b.$apply()},k);l.$$timeoutId=k;f[k]=h;
+return l}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),delete f[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return e}]}function ua(b,a){var c=b;Q&&(Y.setAttribute("href",c),c=Y.href);Y.setAttribute("href",c);return{href:Y.href,protocol:Y.protocol?Y.protocol.replace(/:$/,""):"",host:Y.host,search:Y.search?Y.search.replace(/^\?/,""):"",hash:Y.hash?Y.hash.replace(/^#/,""):"",hostname:Y.hostname,port:Y.port,pathname:"/"===Y.pathname.charAt(0)?Y.pathname:
+"/"+Y.pathname}}function Pb(b){b=v(b)?ua(b):b;return b.protocol===Hc.protocol&&b.host===Hc.host}function fe(){this.$get=ba(W)}function mc(b){function a(d,e){if(T(d)){var f={};r(d,function(b,c){f[c]=a(c,b)});return f}return b.factory(d+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Ic);a("date",Jc);a("filter",Ce);a("json",De);a("limitTo",Ee);a("lowercase",Fe);a("number",Kc);a("orderBy",Lc);a("uppercase",Ge)}function Ce(){return function(b,
+a,c){if(!J(b))return b;var d=typeof c,e=[];e.check=function(a){for(var b=0;b<e.length;b++)if(!e[b](a))return!1;return!0};"function"!==d&&(c="boolean"===d&&c?function(a,b){return Va.equals(a,b)}:function(a,b){if(a&&b&&"object"===typeof a&&"object"===typeof b){for(var d in a)if("$"!==d.charAt(0)&&kb.call(a,d)&&c(a[d],b[d]))return!0;return!1}b=(""+b).toLowerCase();return-1<(""+a).toLowerCase().indexOf(b)});var f=function(a,b){if("string"==typeof b&&"!"===b.charAt(0))return!f(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return c(a,
+b);case "object":switch(typeof b){case "object":return c(a,b);default:for(var d in a)if("$"!==d.charAt(0)&&f(a[d],b))return!0}return!1;case "array":for(d=0;d<a.length;d++)if(f(a[d],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a={$:a};case "object":for(var g in a)(function(b){"undefined"!==typeof a[b]&&e.push(function(c){return f("$"==b?c:c&&c[b],a[b])})})(g);break;case "function":e.push(a);break;default:return b}d=[];for(g=0;g<b.length;g++){var k=
+b[g];e.check(k)&&d.push(k)}return d}}function Ic(b){var a=b.NUMBER_FORMATS;return function(b,d){x(d)&&(d=a.CURRENCY_SYM);return Mc(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function Kc(b){var a=b.NUMBER_FORMATS;return function(b,d){return Mc(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Mc(b,a,c,d,e){if(null==b||!isFinite(b)||T(b))return"";var f=0>b;b=Math.abs(b);var g=b+"",k="",m=[],h=!1;if(-1!==g.indexOf("e")){var l=g.match(/([\d\.]+)e(-?)(\d+)/);l&&"-"==l[2]&&
+l[3]>e+1?(g="0",b=0):(k=g,h=!0)}if(h)0<e&&(-1<b&&1>b)&&(k=b.toFixed(e));else{g=(g.split(Nc)[1]||"").length;x(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(Nc);g=b[0];b=b[1]||"";var l=0,n=a.lgSize,p=a.gSize;if(g.length>=n+p)for(l=g.length-n,h=0;h<l;h++)0===(l-h)%p&&0!==h&&(k+=c),k+=g.charAt(h);for(h=l;h<g.length;h++)0===(g.length-h)%n&&0!==h&&(k+=c),k+=g.charAt(h);for(;b.length<e;)b+="0";e&&"0"!==e&&(k+=d+b.substr(0,
+e))}m.push(f?a.negPre:a.posPre);m.push(k);m.push(f?a.negSuf:a.posSuf);return m.join("")}function Xb(b,a,c){var d="";0>b&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function $(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(0<c||e>-c)e+=c;0===e&&-12==c&&(e=12);return Xb(e,a,d)}}function vb(b,a){return function(c,d){var e=c["get"+b](),f=Ia(a?"SHORT"+b:b);return d[f][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,k=b[8]?
+a.setUTCFullYear:a.setFullYear,m=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));k.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;k=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));m.call(a,f,g,k,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var f="",g=[],k,m;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;v(c)&&(c=He.test(c)?U(c):a(c));ib(c)&&(c=new Date(c));
+if(!ta(c))return c;for(;e;)(m=Ie.exec(e))?(g=g.concat(Ba.call(m,1)),e=g.pop()):(g.push(e),e=null);r(g,function(a){k=Je[a];f+=k?k(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function De(){return function(b){return na(b,!0)}}function Ee(){return function(b,a){if(!J(b)&&!v(b))return b;a=Infinity===Math.abs(Number(a))?Number(a):U(a);if(v(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0<a?(d=0,e=a):(d=
+b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Lc(b){return function(a,c,d){function e(a,b){return Ua(b)?function(b,c){return a(c,b)}:a}function f(a,b){var c=typeof a,d=typeof b;return c==d?(ta(a)&&ta(b)&&(a=a.valueOf(),b=b.valueOf()),"string"==c&&(a=a.toLowerCase(),b=b.toLowerCase()),a===b?0:a<b?-1:1):c<d?-1:1}if(!Pa(a)||!c)return a;c=J(c)?c:[c];c=Vc(c,function(a){var c=!1,d=a||Qa;if(v(a)){if("+"==a.charAt(0)||"-"==a.charAt(0))c="-"==a.charAt(0),a=a.substring(1);d=b(a);if(d.constant){var g=
+d();return e(function(a,b){return f(a[g],b[g])},c)}}return e(function(a,b){return f(d(a),d(b))},c)});for(var g=[],k=0;k<a.length;k++)g.push(a[k]);return g.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function ya(b){P(b)&&(b={link:b});b.restrict=b.restrict||"AC";return ba(b)}function Oc(b,a,c,d){function e(a,c){c=c?"-"+mb(c,"-"):"";d.setClass(b,(a?wb:xb)+c,(a?xb:wb)+c)}var f=this,g=b.parent().controller("form")||yb,k=0,m=f.$error={},h=[];f.$name=
+a.name||a.ngForm;f.$dirty=!1;f.$pristine=!0;f.$valid=!0;f.$invalid=!1;g.$addControl(f);b.addClass(Oa);e(!0);f.$addControl=function(a){Da(a.$name,"input");h.push(a);a.$name&&(f[a.$name]=a)};f.$removeControl=function(a){a.$name&&f[a.$name]===a&&delete f[a.$name];r(m,function(b,c){f.$setValidity(c,!0,a)});Sa(h,a)};f.$setValidity=function(a,b,c){var d=m[a];if(b)d&&(Sa(d,c),d.length||(k--,k||(e(b),f.$valid=!0,f.$invalid=!1),m[a]=!1,e(!0,a),g.$setValidity(a,!0,f)));else{k||e(b);if(d){if(-1!=Ra(d,c))return}else m[a]=
+d=[],k++,e(!1,a),g.$setValidity(a,!1,f);d.push(c);f.$valid=!1;f.$invalid=!0}};f.$setDirty=function(){d.removeClass(b,Oa);d.addClass(b,zb);f.$dirty=!0;f.$pristine=!1;g.$setDirty()};f.$setPristine=function(){d.removeClass(b,zb);d.addClass(b,Oa);f.$dirty=!1;f.$pristine=!0;r(h,function(a){a.$setPristine()})}}function sa(b,a,c,d){b.$setValidity(a,c);return c?d:t}function Pc(b,a){var c,d;if(a)for(c=0;c<a.length;++c)if(d=a[c],b[d])return!0;return!1}function Ke(b,a,c,d,e){T(e)&&(b.$$hasNativeValidators=!0,
+b.$parsers.push(function(f){if(b.$error[a]||Pc(e,d)||!Pc(e,c))return f;b.$setValidity(a,!1)}))}function Ab(b,a,c,d,e,f){var g=a.prop(Le),k=a[0].placeholder,m={},h=K(a[0].type);d.$$validityState=g;if(!e.android){var l=!1;a.on("compositionstart",function(a){l=!0});a.on("compositionend",function(){l=!1;n()})}var n=function(e){if(!l){var f=a.val();if(Q&&"input"===(e||m).type&&a[0].placeholder!==k)k=a[0].placeholder;else if("password"!==h&&Ua(c.ngTrim||"T")&&(f=aa(f)),e=g&&d.$$hasNativeValidators,d.$viewValue!==
+f||""===f&&e)b.$root.$$phase?d.$setViewValue(f):b.$apply(function(){d.$setViewValue(f)})}};if(e.hasEvent("input"))a.on("input",n);else{var p,q=function(){p||(p=f.defer(function(){n();p=null}))};a.on("keydown",function(a){a=a.keyCode;91===a||(15<a&&19>a||37<=a&&40>=a)||q()});if(e.hasEvent("paste"))a.on("paste cut",q)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?(s=RegExp(e[1],e[2]),e=function(a){return sa(d,
+"pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw C("ngPattern")("noregexp",s,e,ia(a));return sa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return sa(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var u=U(c.ngMaxlength);e=function(a){return sa(d,"maxlength",d.$isEmpty(a)||a.length<=u,a)};d.$parsers.push(e);
+d.$formatters.push(e)}}function Yb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;d<a.length;d++){for(var e=a[d],l=0;l<b.length;l++)if(e==b[l])continue a;c.push(e)}return c}function e(a){if(!J(a)){if(v(a))return a.split(" ");if(T(a)){var b=[];r(a,function(a,c){a&&(b=b.concat(c.split(" ")))});return b}}return a}return{restrict:"AC",link:function(f,g,k){function m(a,b){var c=g.data("$classCounts")||{},d=[];r(a,function(a){if(0<b||c[a])c[a]=(c[a]||0)+b,c[a]===+(0<
+b)&&d.push(a)});g.data("$classCounts",c);return d.join(" ")}function h(b){if(!0===a||f.$index%2===a){var h=e(b||[]);if(!l){var q=m(h,1);k.$addClass(q)}else if(!Aa(b,l)){var s=e(l),q=d(h,s),h=d(s,h),h=m(h,-1),q=m(q,1);0===q.length?c.removeClass(g,h):0===h.length?c.addClass(g,q):c.setClass(g,q,h)}}l=ha(b)}var l;f.$watch(k[b],h,!0);k.$observe("class",function(a){h(f.$eval(k[b]))});"ngClass"!==b&&f.$watch("$index",function(c,d){var g=c&1;if(g!==(d&1)){var h=e(f.$eval(k[b]));g===a?(g=m(h,1),k.$addClass(g)):
+(g=m(h,-1),k.$removeClass(g))}})}}}]}var Le="validity",K=function(b){return v(b)?b.toLowerCase():b},kb=Object.prototype.hasOwnProperty,Ia=function(b){return v(b)?b.toUpperCase():b},Q,w,Ea,Ba=[].slice,Me=[].push,za=Object.prototype.toString,Ta=C("ng"),Va=W.angular||(W.angular={}),Ya,Ma,ma=["0","0","0"];Q=U((/msie (\d+)/.exec(K(navigator.userAgent))||[])[1]);isNaN(Q)&&(Q=U((/trident\/.*; rv:(\d+)/.exec(K(navigator.userAgent))||[])[1]));E.$inject=[];Qa.$inject=[];var J=function(){return P(Array.isArray)?
+Array.isArray:function(b){return"[object Array]"===za.call(b)}}(),aa=function(){return String.prototype.trim?function(b){return v(b)?b.trim():b}:function(b){return v(b)?b.replace(/^\s\s*/,"").replace(/\s\s*$/,""):b}}();Ma=9>Q?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ia(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xa=function(){if(y(Xa.isActive_))return Xa.isActive_;var b=!(!X.querySelector("[ng-csp]")&&!X.querySelector("[data-ng-csp]"));
+if(!b)try{new Function("")}catch(a){b=!0}return Xa.isActive_=b},Yc=/[A-Z]/g,ad={full:"1.2.26",major:1,minor:2,dot:26,codeName:"captivating-disinterest"};S.expando="ng339";var ab=S.cache={},ne=1,sb=W.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},$a=W.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};S._data=function(b){return this.cache[b[this.expando]]||{}};var ie=/([\:\-\_]+(.))/g,
+je=/^moz([A-Z])/,Hb=C("jqLite"),ke=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Ib=/<|&#?\w+;/,le=/<([\w:]+)/,me=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea={option:[1,'<select multiple="multiple">',"</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th=
+ea.td;var La=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===X.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),S(W).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?w(this[b]):w(this[this.length+b])},length:0,push:Me,sort:[].sort,splice:[].splice},qb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){qb[K(b)]=b});var rc={};r("input select option textarea button form details".split(" "),
+function(b){rc[Ia(b)]=!0});r({data:Mb,removeData:Lb},function(b,a){S[a]=b});r({data:Mb,inheritedData:pb,scope:function(b){return w.data(b,"$scope")||pb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return w.data(b,"$isolateScope")||w.data(b,"$isolateScopeNoTemplate")},controller:oc,injector:function(b){return pb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Nb,css:function(b,a,c){a=Za(a);if(y(c))b.style[a]=c;else{var d;8>=Q&&(d=b.currentStyle&&b.currentStyle[a],
+""===d&&(d="auto"));d=d||b.style[a];8>=Q&&(d=""===d?t:d);return d}},attr:function(b,a,c){var d=K(a);if(qb[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||E).specified?d:t;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?t:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(x(d))return e?b[e]:"";b[e]=d}var a=[];9>Q?(a[1]=
+"innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(x(a)){if("SELECT"===Ma(b)&&b.multiple){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(x(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)Ja(d[c]);b.innerHTML=a},empty:pc},function(b,a){S.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==pc&&(2==b.length&&b!==Nb&&b!==oc?a:d)===t){if(T(a)){for(e=
+0;e<g;e++)if(b===Mb)b(this[e],a);else for(f in a)b(this[e],f,a[f]);return this}e=b.$dv;g=e===t?Math.min(g,1):g;for(f=0;f<g;f++){var k=b(this[f],a,d);e=e?e+k:k}return e}for(e=0;e<g;e++)b(this[e],a,d);return this}});r({removeData:Lb,dealoc:Ja,on:function a(c,d,e,f){if(y(f))throw Hb("onargs");var g=oa(c,"events"),k=oa(c,"handle");g||oa(c,"events",g={});k||oa(c,"handle",k=oe(c,g));r(d.split(" "),function(d){var f=g[d];if(!f){if("mouseenter"==d||"mouseleave"==d){var l=X.body.contains||X.body.compareDocumentPosition?
+function(a,c){var d=9===a.nodeType?a.documentElement:a,e=c&&c.parentNode;return a===e||!!(e&&1===e.nodeType&&(d.contains?d.contains(e):a.compareDocumentPosition&&a.compareDocumentPosition(e)&16))}:function(a,c){if(c)for(;c=c.parentNode;)if(c===a)return!0;return!1};g[d]=[];a(c,{mouseleave:"mouseout",mouseenter:"mouseover"}[d],function(a){var c=a.relatedTarget;c&&(c===this||l(this,c))||k(a,d)})}else sb(c,d,k),g[d]=[];f=g[d]}f.push(e)})},off:nc,one:function(a,c,d){a=w(a);a.on(c,function f(){a.off(c,
+d);a.off(c,f)});a.on(c,d)},replaceWith:function(a,c){var d,e=a.parentNode;Ja(a);r(new S(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];r(a.childNodes,function(a){1===a.nodeType&&c.push(a)});return c},contents:function(a){return a.contentDocument||a.childNodes||[]},append:function(a,c){r(new S(c),function(c){1!==a.nodeType&&11!==a.nodeType||a.appendChild(c)})},prepend:function(a,c){if(1===a.nodeType){var d=a.firstChild;r(new S(c),function(c){a.insertBefore(c,
+d)})}},wrap:function(a,c){c=w(c)[0];var d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){Ja(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;r(new S(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:ob,removeClass:nb,toggleClass:function(a,c,d){c&&r(c.split(" "),function(c){var f=d;x(f)&&(f=!Nb(a,c));(f?ob:nb)(a,c)})},parent:function(a){return(a=a.parentNode)&&11!==a.nodeType?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;
+for(a=a.nextSibling;null!=a&&1!==a.nodeType;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName?a.getElementsByTagName(c):[]},clone:Kb,triggerHandler:function(a,c,d){var e,f;e=c.type||c;var g=(oa(a,"events")||{})[e];g&&(e={preventDefault:function(){this.defaultPrevented=!0},isDefaultPrevented:function(){return!0===this.defaultPrevented},stopPropagation:E,type:e,target:a},c.type&&(e=D(e,c)),c=ha(g),f=d?[e].concat(d):[e],r(c,function(c){c.apply(a,f)}))}},function(a,c){S.prototype[c]=
+function(c,e,f){for(var g,k=0;k<this.length;k++)x(g)?(g=a(this[k],c,e,f),y(g)&&(g=w(g))):Jb(g,a(this[k],c,e,f));return y(g)?g:this};S.prototype.bind=S.prototype.on;S.prototype.unbind=S.prototype.off});bb.prototype={put:function(a,c){this[Ka(a,this.nextUid)]=c},get:function(a){return this[Ka(a,this.nextUid)]},remove:function(a){var c=this[a=Ka(a,this.nextUid)];delete this[a];return c}};var qe=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,re=/,/,se=/^\s*(_?)(\S+?)\1\s*$/,pe=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,
+cb=C("$injector"),Ne=C("$animate"),Md=["$provide",function(a){this.$$selectors={};this.register=function(c,d){var e=c+"-animation";if(c&&"."!=c.charAt(0))throw Ne("notcsel",c);this.$$selectors[c.substr(1)]=e;a.factory(e,d)};this.classNameFilter=function(a){1===arguments.length&&(this.$$classNameFilter=a instanceof RegExp?a:null);return this.$$classNameFilter};this.$get=["$timeout","$$asyncCallback",function(a,d){return{enter:function(a,c,g,k){g?g.after(a):(c&&c[0]||(c=g.parent()),c.append(a));k&&
+d(k)},leave:function(a,c){a.remove();c&&d(c)},move:function(a,c,d,k){this.enter(a,c,d,k)},addClass:function(a,c,g){c=v(c)?c:J(c)?c.join(" "):"";r(a,function(a){ob(a,c)});g&&d(g)},removeClass:function(a,c,g){c=v(c)?c:J(c)?c.join(" "):"";r(a,function(a){nb(a,c)});g&&d(g)},setClass:function(a,c,g,k){r(a,function(a){ob(a,c);nb(a,g)});k&&d(k)},enabled:E}}]}],ja=C("$compile");ic.$inject=["$provide","$$sanitizeUriProvider"];var we=/^(x[\:\-_]|data[\:\-_])/i,yc=C("$interpolate"),Oe=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,
+ze={http:80,https:443,ftp:21},Sb=C("$location");Ub.prototype=Tb.prototype=Bc.prototype={$$html5:!1,$$replace:!1,absUrl:tb("$$absUrl"),url:function(a){if(x(a))return this.$$url;a=Oe.exec(a);a[1]&&this.path(decodeURIComponent(a[1]));(a[2]||a[1])&&this.search(a[3]||"");this.hash(a[5]||"");return this},protocol:tb("$$protocol"),host:tb("$$host"),port:tb("$$port"),path:Cc("$$path",function(a){a=a?a.toString():"";return"/"==a.charAt(0)?a:"/"+a}),search:function(a,c){switch(arguments.length){case 0:return this.$$search;
+case 1:if(v(a)||ib(a))a=a.toString(),this.$$search=ec(a);else if(T(a))r(a,function(c,e){null==c&&delete a[e]}),this.$$search=a;else throw Sb("isrcharg");break;default:x(c)||null===c?delete this.$$search[a]:this.$$search[a]=c}this.$$compose();return this},hash:Cc("$$hash",function(a){return a?a.toString():""}),replace:function(){this.$$replace=!0;return this}};var la=C("$parse"),Fc={},wa,Pe=Function.prototype.call,Qe=Function.prototype.apply,Qc=Function.prototype.bind,gb={"null":function(){return null},
+"true":function(){return!0},"false":function(){return!1},undefined:E,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return y(d)?y(e)?d+e:d:y(e)?e:t},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(y(d)?d:0)-(y(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":E,"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,
+c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Re={n:"\n",f:"\f",r:"\r",
+t:"\t",v:"\v","'":"'",'"':'"'},Wb=function(a){this.options=a};Wb.prototype={constructor:Wb,lex:function(a){this.text=a;this.index=0;this.ch=t;this.lastCh=":";for(this.tokens=[];this.index<this.text.length;){this.ch=this.text.charAt(this.index);if(this.is("\"'"))this.readString(this.ch);else if(this.isNumber(this.ch)||this.is(".")&&this.isNumber(this.peek()))this.readNumber();else if(this.isIdent(this.ch))this.readIdent();else if(this.is("(){}[].,;:?"))this.tokens.push({index:this.index,text:this.ch}),
+this.index++;else if(this.isWhitespace(this.ch)){this.index++;continue}else{a=this.ch+this.peek();var c=a+this.peek(2),d=gb[this.ch],e=gb[a],f=gb[c];f?(this.tokens.push({index:this.index,text:c,fn:f}),this.index+=3):e?(this.tokens.push({index:this.index,text:a,fn:e}),this.index+=2):d?(this.tokens.push({index:this.index,text:this.ch,fn:d}),this.index+=1):this.throwError("Unexpected next character ",this.index,this.index+1)}this.lastCh=this.ch}return this.tokens},is:function(a){return-1!==a.indexOf(this.ch)},
+was:function(a){return-1!==a.indexOf(this.lastCh)},peek:function(a){a=a||1;return this.index+a<this.text.length?this.text.charAt(this.index+a):!1},isNumber:function(a){return"0"<=a&&"9">=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+
+this.text.substring(c,d)+"]":" "+d;throw la("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index<this.text.length;){var d=K(this.text.charAt(this.index));if("."==d||this.isNumber(d))a+=d;else{var e=this.peek();if("e"==d&&this.isExpOperator(e))a+=d;else if(this.isExpOperator(d)&&e&&this.isNumber(e)&&"e"==a.charAt(a.length-1))a+=d;else if(!this.isExpOperator(d)||e&&this.isNumber(e)||"e"!=a.charAt(a.length-1))break;else this.throwError("Invalid exponent")}this.index++}a*=
+1;this.tokens.push({index:c,text:a,literal:!0,constant:!0,fn:function(){return a}})},readIdent:function(){for(var a=this,c="",d=this.index,e,f,g,k;this.index<this.text.length;){k=this.text.charAt(this.index);if("."===k||this.isIdent(k)||this.isNumber(k))"."===k&&(e=this.index),c+=k;else break;this.index++}if(e)for(f=this.index;f<this.text.length;){k=this.text.charAt(f);if("("===k){g=c.substr(e-d+1);c=c.substr(0,e-d);this.index=f;break}if(this.isWhitespace(k))f++;else break}d={index:d,text:c};if(gb.hasOwnProperty(c))d.fn=
+gb[c],d.literal=!0,d.constant=!0;else{var m=Ec(c,this.options,this.text);d.fn=D(function(a,c){return m(a,c)},{assign:function(d,e){return ub(d,c,e,a.text,a.options)}})}this.tokens.push(d);g&&(this.tokens.push({index:e,text:"."}),this.tokens.push({index:e+1,text:g}))},readString:function(a){var c=this.index;this.index++;for(var d="",e=a,f=!1;this.index<this.text.length;){var g=this.text.charAt(this.index),e=e+g;if(f)"u"===g?(f=this.text.substring(this.index+1,this.index+5),f.match(/[\da-f]{4}/i)||
+this.throwError("Invalid unicode escape [\\u"+f+"]"),this.index+=4,d+=String.fromCharCode(parseInt(f,16))):d+=Re[g]||g,f=!1;else if("\\"===g)f=!0;else{if(g===a){this.index++;this.tokens.push({index:c,text:e,string:d,literal:!0,constant:!0,fn:function(){return d}});return}d+=g}this.index++}this.throwError("Unterminated quote",c)}};var fb=function(a,c,d){this.lexer=a;this.$filter=c;this.options=d};fb.ZERO=D(function(){return 0},{constant:!0});fb.prototype={constructor:fb,parse:function(a){this.text=
+a;this.tokens=this.lexer.lex(a);a=this.statements();0!==this.tokens.length&&this.throwError("is an unexpected token",this.tokens[0]);a.literal=!!a.literal;a.constant=!!a.constant;return a},primary:function(){var a;if(this.expect("("))a=this.filterChain(),this.consume(")");else if(this.expect("["))a=this.arrayDeclaration();else if(this.expect("{"))a=this.object();else{var c=this.expect();(a=c.fn)||this.throwError("not a primary expression",c);a.literal=!!c.literal;a.constant=!!c.constant}for(var d;c=
+this.expect("(","[",".");)"("===c.text?(a=this.functionCall(a,d),d=null):"["===c.text?(d=a,a=this.objectIndex(a)):"."===c.text?(d=a,a=this.fieldAccess(a)):this.throwError("IMPOSSIBLE");return a},throwError:function(a,c){throw la("syntax",c.text,a,c.index+1,this.text,this.text.substring(c.index));},peekToken:function(){if(0===this.tokens.length)throw la("ueoe",this.text);return this.tokens[0]},peek:function(a,c,d,e){if(0<this.tokens.length){var f=this.tokens[0],g=f.text;if(g===a||g===c||g===d||g===
+e||!(a||c||d||e))return f}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){this.expect(a)||this.throwError("is unexpected, expecting ["+a+"]",this.peek())},unaryFn:function(a,c){return D(function(d,e){return a(d,e,c)},{constant:c.constant})},ternaryFn:function(a,c,d){return D(function(e,f){return a(e,f)?c(e,f):d(e,f)},{constant:a.constant&&c.constant&&d.constant})},binaryFn:function(a,c,d){return D(function(e,f){return c(e,f,a,d)},{constant:a.constant&&
+d.constant})},statements:function(){for(var a=[];;)if(0<this.tokens.length&&!this.peek("}",")",";","]")&&a.push(this.filterChain()),!this.expect(";"))return 1===a.length?a[0]:function(c,d){for(var e,f=0;f<a.length;f++){var g=a[f];g&&(e=g(c,d))}return e}},filterChain:function(){for(var a=this.expression(),c;;)if(c=this.expect("|"))a=this.binaryFn(a,c.fn,this.filter());else return a},filter:function(){for(var a=this.expect(),c=this.$filter(a.text),d=[];;)if(a=this.expect(":"))d.push(this.expression());
+else{var e=function(a,e,k){k=[k];for(var m=0;m<d.length;m++)k.push(d[m](a,e));return c.apply(a,k)};return function(){return e}}},expression:function(){return this.assignment()},assignment:function(){var a=this.ternary(),c,d;return(d=this.expect("="))?(a.assign||this.throwError("implies assignment but ["+this.text.substring(0,d.index)+"] can not be assigned to",d),c=this.ternary(),function(d,f){return a.assign(d,c(d,f),f)}):a},ternary:function(){var a=this.logicalOR(),c,d;if(this.expect("?")){c=this.assignment();
+if(d=this.expect(":"))return this.ternaryFn(a,c,this.assignment());this.throwError("expected :",d)}else return a},logicalOR:function(){for(var a=this.logicalAND(),c;;)if(c=this.expect("||"))a=this.binaryFn(a,c.fn,this.logicalAND());else return a},logicalAND:function(){var a=this.equality(),c;if(c=this.expect("&&"))a=this.binaryFn(a,c.fn,this.logicalAND());return a},equality:function(){var a=this.relational(),c;if(c=this.expect("==","!=","===","!=="))a=this.binaryFn(a,c.fn,this.equality());return a},
+relational:function(){var a=this.additive(),c;if(c=this.expect("<",">","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(fb.ZERO,a.fn,
+this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Ec(d,this.options,this.text);return D(function(c,d,k){return e(k||a(c,d))},{assign:function(e,g,k){(k=a(e,k))||a.assign(e,k={});return ub(k,d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,f){var g=a(e,f),k=d(e,f),m;ka(k,c.text);if(!g)return t;(g=va(g[k],c.text))&&(g.then&&c.options.unwrapPromises)&&
+(m=g,"$$v"in g||(m.$$v=t,m.then(function(a){m.$$v=a})),g=g.$$v);return g},{assign:function(e,f,g){var k=ka(d(e,g),c.text);(g=va(a(e,g),c.text))||a.assign(e,g={});return g[k]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var k=[],m=c?c(f,g):f,h=0;h<d.length;h++)k.push(va(d[h](f,g),e.text));h=a(f,g,m)||E;va(m,e.text);var l=e.text;if(h){if(h.constructor===h)throw la("isecfn",
+l);if(h===Pe||h===Qe||Qc&&h===Qc)throw la("isecff",l);}k=h.apply?h.apply(m,k):h(k[0],k[1],k[2],k[3],k[4]);return va(k,e.text)}},arrayDeclaration:function(){var a=[],c=!0;if("]"!==this.peekToken().text){do{if(this.peek("]"))break;var d=this.expression();a.push(d);d.constant||(c=!1)}while(this.expect(","))}this.consume("]");return D(function(c,d){for(var g=[],k=0;k<a.length;k++)g.push(a[k](c,d));return g},{literal:!0,constant:c})},object:function(){var a=[],c=!0;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;
+var d=this.expect(),d=d.string||d.text;this.consume(":");var e=this.expression();a.push({key:d,value:e});e.constant||(c=!1)}while(this.expect(","))}this.consume("}");return D(function(c,d){for(var e={},m=0;m<a.length;m++){var h=a[m];e[h.key]=h.value(c,d)}return e},{literal:!0,constant:c})}};var Vb={},xa=C("$sce"),ga={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},Y=X.createElement("a"),Hc=ua(W.location.href,!0);mc.$inject=["$provide"];Ic.$inject=["$locale"];Kc.$inject=["$locale"];
+var Nc=".",Je={yyyy:$("FullYear",4),yy:$("FullYear",2,0,!0),y:$("FullYear",1),MMMM:vb("Month"),MMM:vb("Month",!0),MM:$("Month",2,1),M:$("Month",1,1),dd:$("Date",2),d:$("Date",1),HH:$("Hours",2),H:$("Hours",1),hh:$("Hours",2,-12),h:$("Hours",1,-12),mm:$("Minutes",2),m:$("Minutes",1),ss:$("Seconds",2),s:$("Seconds",1),sss:$("Milliseconds",3),EEEE:vb("Day"),EEE:vb("Day",!0),a:function(a,c){return 12>a.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Xb(Math[0<
+a?"floor":"ceil"](a/60),2)+Xb(Math.abs(a%60),2))}},Ie=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,He=/^\-?\d+$/;Jc.$inject=["$locale"];var Fe=ba(K),Ge=ba(Ia);Lc.$inject=["$parse"];var dd=ba({restrict:"E",compile:function(a,c){8>=Q&&(c.href||c.name||c.$set("href",""),a.append(X.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===za.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)||
+a.preventDefault()})}}}),Fb={};r(qb,function(a,c){if("multiple"!=a){var d=pa("ng-"+c);Fb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(["src","srcset","href"],function(a){var c=pa("ng-"+a);Fb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,k=a;"href"===a&&"[object SVGAnimatedString]"===za.call(e.prop("href"))&&(k="xlinkHref",f.$attr[k]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(k,c),Q&&g&&e.prop(g,f[k])):"href"===
+a&&f.$set(k,null)})}}}});var yb={$addControl:E,$removeControl:E,$setValidity:E,$setDirty:E,$setPristine:E};Oc.$inject=["$element","$attrs","$scope","$animate"];var Rc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var k=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};sb(e[0],"submit",k);e.on("$destroy",function(){c(function(){$a(e[0],"submit",k)},0,!1)})}var m=e.parent().controller("form"),
+h=f.name||f.ngForm;h&&ub(a,h,g,h);if(m)e.on("$destroy",function(){m.$removeControl(g);h&&ub(a,h,t,h);D(g,yb)})}}}}}]},ed=Rc(),rd=Rc(!0),Se=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Te=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Ue=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Sc={text:Ab,number:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Ue.test(a))return e.$setValidity("number",
+!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return t});Ke(e,"number",Ve,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return sa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return sa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return sa(e,"number",e.$isEmpty(a)||
+ib(a),a)})},url:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"url",e.$isEmpty(a)||Se.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){Ab(a,c,d,e,f,g);a=function(a){return sa(e,"email",e.$isEmpty(a)||Te.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){x(d.name)&&c.attr("name",hb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};
+d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;v(f)||(f=!0);v(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:E,button:E,submit:E,reset:E,file:E},Ve=["badInput"],jc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",
+link:function(d,e,f,g){g&&(Sc[K(f.type)]||Sc.text)(d,e,f,g,c,a)}}}],wb="ng-valid",xb="ng-invalid",Oa="ng-pristine",zb="ng-dirty",We=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function k(a,c){c=c?"-"+mb(c,"-"):"";g.removeClass(e,(a?xb:wb)+c);g.addClass(e,(a?wb:xb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=
+d.name;var m=f(d.ngModel),h=m.assign;if(!h)throw C("ngModel")("nonassign",d.ngModel,ia(e));this.$render=E;this.$isEmpty=function(a){return x(a)||""===a||null===a||a!==a};var l=e.inheritedData("$formController")||yb,n=0,p=this.$error={};e.addClass(Oa);k(!0);this.$setValidity=function(a,c){p[a]!==!c&&(c?(p[a]&&n--,n||(k(!0),this.$valid=!0,this.$invalid=!1)):(k(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,k(c,a),l.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=
+!0;g.removeClass(e,zb);g.addClass(e,Oa)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Oa),g.addClass(e,zb),l.$setDirty());r(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,h(a,d),r(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var q=this;a.$watch(function(){var c=m(a);if(q.$modelValue!==c){var d=q.$formatters,e=d.length;for(q.$modelValue=c;e--;)c=d[e](c);q.$viewValue!==c&&(q.$viewValue=
+c,q.$render())}return c})}],Gd=function(){return{require:["ngModel","^?form"],controller:We,link:function(a,c,d,e){var f=e[0],g=e[1]||yb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Id=ba({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),kc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",
+!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Hd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!x(a)){var c=[];a&&r(a.split(f),function(a){a&&c.push(aa(a))});return c}});e.$formatters.push(function(a){return J(a)?a.join(", "):t});e.$isEmpty=function(a){return!a||!a.length}}}},Xe=/^(true|false|\d+)$/,Jd=function(){return{priority:100,
+compile:function(a,c){return Xe.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},jd=ya({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==t?"":a)})}}}),ld=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],
+kd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var k=c(g.ngBindHtml);d.$watch(function(){return(k(d)||"").toString()},function(c){f.html(a.getTrustedHtml(k(d))||"")})}}}}],md=Yb("",!0),od=Yb("Odd",0),nd=Yb("Even",1),pd=ya({compile:function(a,c){c.$set("ngCloak",t);a.removeClass("ng-cloak")}}),qd=[function(){return{scope:!0,controller:"@",priority:500}}],lc={},Ye={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),
+function(a){var c=pa("ng-"+a);lc[c]=["$parse","$rootScope",function(d,e){return{compile:function(f,g){var k=d(g[c]);return function(c,d){d.on(a,function(d){var f=function(){k(c,{$event:d})};Ye[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var td=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var k,m,h;c.$watch(e.ngIf,function(f){Ua(f)?m||(m=c.$new(),g(m,function(c){c[c.length++]=X.createComment(" end ngIf: "+e.ngIf+
+" ");k={clone:c};a.enter(c,d.parent(),d)})):(h&&(h.remove(),h=null),m&&(m.$destroy(),m=null),k&&(h=Eb(k.clone),a.leave(h,function(){h=null}),k=null))})}}}],ud=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Va.noop,compile:function(g,k){var m=k.ngInclude||k.src,h=k.onload||"",l=k.autoscroll;return function(g,k,q,r,F){var u=0,t,w,R,z=function(){w&&(w.remove(),w=null);t&&(t.$destroy(),t=null);
+R&&(e.leave(R,function(){w=null}),w=R,R=null)};g.$watch(f.parseAsResourceUrl(m),function(f){var m=function(){!y(l)||l&&!g.$eval(l)||d()},q=++u;f?(a.get(f,{cache:c}).success(function(a){if(q===u){var c=g.$new();r.template=a;a=F(c,function(a){z();e.enter(a,null,k,m)});t=c;R=a;t.$emit("$includeContentLoaded");g.$eval(h)}}).error(function(){q===u&&z()}),g.$emit("$includeContentRequested")):(z(),r.template=null)})}}}}],Kd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",
+link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],vd=ya({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),wd=ya({terminal:!0,priority:1E3}),xd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var k=g.count,m=g.$attr.when&&f.attr(g.$attr.when),h=g.offset||0,l=e.$eval(m)||{},n={},p=c.startSymbol(),q=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(l[K(c.replace("when","").replace("Minus","-"))]=
+f.attr(g.$attr[c]))});r(l,function(a,e){n[e]=c(a.replace(d,p+k+"-"+h+q))});e.$watch(function(){var c=parseFloat(e.$eval(k));if(isNaN(c))return"";c in l||(c=a.pluralCat(c-h));return n[c](e,f,!0)},function(a){f.text(a)})}}}],yd=["$parse","$animate",function(a,c){var d=C("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,k,m){var h=g.ngRepeat,l=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,q,s,t,u,A={$id:Ka};if(!l)throw d("iexp",
+h);g=l[1];k=l[2];(l=l[3])?(n=a(l),p=function(a,c,d){u&&(A[u]=a);A[t]=c;A.$index=d;return n(e,A)}):(q=function(a,c){return Ka(c)},s=function(a){return a});l=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!l)throw d("iidexp",g);t=l[3]||l[1];u=l[2];var y={};e.$watchCollection(k,function(a){var g,k,l=f[0],n,A={},B,I,H,v,E,C,x,J=[];if(Pa(a))C=a,E=p||q;else{E=p||s;C=[];for(H in a)a.hasOwnProperty(H)&&"$"!=H.charAt(0)&&C.push(H);C.sort()}B=C.length;k=J.length=C.length;for(g=0;g<k;g++)if(H=a===
+C?g:C[g],v=a[H],n=E(H,v,g),Da(n,"`track by` id"),y.hasOwnProperty(n))x=y[n],delete y[n],A[n]=x,J[g]=x;else{if(A.hasOwnProperty(n))throw r(J,function(a){a&&a.scope&&(y[a.id]=a)}),d("dupes",h,n,na(v));J[g]={id:n};A[n]=!1}for(H in y)y.hasOwnProperty(H)&&(x=y[H],g=Eb(x.clone),c.leave(g),r(g,function(a){a.$$NG_REMOVED=!0}),x.scope.$destroy());g=0;for(k=C.length;g<k;g++){H=a===C?g:C[g];v=a[H];x=J[g];J[g-1]&&(l=J[g-1].clone[J[g-1].clone.length-1]);if(x.scope){I=x.scope;n=l;do n=n.nextSibling;while(n&&n.$$NG_REMOVED);
+x.clone[0]!=n&&c.move(Eb(x.clone),null,w(l));l=x.clone[x.clone.length-1]}else I=e.$new();I[t]=v;u&&(I[u]=H);I.$index=g;I.$first=0===g;I.$last=g===B-1;I.$middle=!(I.$first||I.$last);I.$odd=!(I.$even=0===(g&1));x.scope||m(I,function(a){a[a.length++]=X.createComment(" end ngRepeat: "+h+" ");c.enter(a,null,w(l));l=a;x.scope=I;x.clone=a;A[x.id]=x})}y=A})}}}],zd=["$animate",function(a){return function(c,d,e){c.$watch(e.ngShow,function(c){a[Ua(c)?"removeClass":"addClass"](d,"ng-hide")})}}],sd=["$animate",
+function(a){return function(c,d,e){c.$watch(e.ngHide,function(c){a[Ua(c)?"addClass":"removeClass"](d,"ng-hide")})}}],Ad=ya(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&r(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Bd=["$animate",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,f){var g=[],k=[],m=[],h=[];c.$watch(e.ngSwitch||e.on,function(d){var n,p;n=0;for(p=m.length;n<p;++n)m[n].remove();n=m.length=0;for(p=
+h.length;n<p;++n){var q=k[n];h[n].$destroy();m[n]=q;a.leave(q,function(){m.splice(n,1)})}k.length=0;h.length=0;if(g=f.cases["!"+d]||f.cases["?"])c.$eval(e.change),r(g,function(d){var e=c.$new();h.push(e);d.transclude(e,function(c){var e=d.element;k.push(c);a.enter(c,e.parent(),e)})})})}}}],Cd=ya({transclude:"element",priority:800,require:"^ngSwitch",link:function(a,c,d,e,f){e.cases["!"+d.ngSwitchWhen]=e.cases["!"+d.ngSwitchWhen]||[];e.cases["!"+d.ngSwitchWhen].push({transclude:f,element:c})}}),Dd=
+ya({transclude:"element",priority:800,require:"^ngSwitch",link:function(a,c,d,e,f){e.cases["?"]=e.cases["?"]||[];e.cases["?"].push({transclude:f,element:c})}}),Fd=ya({link:function(a,c,d,e,f){if(!f)throw C("ngTransclude")("orphan",ia(c));f(function(a){c.empty();c.append(a)})}}),fd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){"text/ng-template"==d.type&&a.put(d.id,c[0].text)}}}],Ze=C("ngOptions"),Ed=ba({terminal:!0}),gd=["$compile","$parse",function(a,c){var d=
+/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,e={$setViewValue:E};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var m=this,h={},l=e,n;m.databound=d.ngModel;m.init=function(a,c,d){l=a;n=d};m.addOption=function(c){Da(c,'"option value"');h[c]=!0;l.$viewValue==c&&(a.val(c),n.parent()&&n.remove())};
+m.removeOption=function(a){this.hasOption(a)&&(delete h[a],l.$viewValue==a&&this.renderUnknownOption(a))};m.renderUnknownOption=function(c){c="? "+Ka(c)+" ?";n.val(c);a.prepend(n);a.val(c);n.prop("selected",!0)};m.hasOption=function(a){return h.hasOwnProperty(a)};c.$on("$destroy",function(){m.renderUnknownOption=E})}],link:function(e,g,k,m){function h(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(v.parent()&&v.remove(),c.val(a),""===a&&u.prop("selected",!0)):x(a)&&u?c.val(""):e.renderUnknownOption(a)};
+c.on("change",function(){a.$apply(function(){v.parent()&&v.remove();d.$setViewValue(c.val())})})}function l(a,c,d){var e;d.$render=function(){var a=new bb(d.$viewValue);r(c.find("option"),function(c){c.selected=y(a.get(c.value))})};a.$watch(function(){Aa(e,d.$viewValue)||(e=ha(d.$viewValue),d.$render())});c.on("change",function(){a.$apply(function(){var a=[];r(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function n(e,f,g){function k(){var a={"":[]},c=[""],d,h,
+s,t,v;s=g.$modelValue;t=w(e)||[];var E=n?Zb(t):t,I,M,B;M={};B=!1;if(q)if(h=g.$modelValue,x&&J(h))for(B=new bb([]),d={},v=0;v<h.length;v++)d[m]=h[v],B.put(x(e,d),h[v]);else B=new bb(h);v=B;var D,K;for(B=0;I=E.length,B<I;B++){h=B;if(n){h=E[B];if("$"===h.charAt(0))continue;M[n]=h}M[m]=t[h];d=r(e,M)||"";(h=a[d])||(h=a[d]=[],c.push(d));q?d=y(v.remove(x?x(e,M):u(e,M))):(x?(d={},d[m]=s,d=x(e,d)===x(e,M)):d=s===u(e,M),v=v||d);D=l(e,M);D=y(D)?D:"";h.push({id:x?x(e,M):n?E[B]:B,label:D,selected:d})}q||(F||null===
+s?a[""].unshift({id:"",label:"",selected:!v}):v||a[""].unshift({id:"?",label:"",selected:!0}));M=0;for(E=c.length;M<E;M++){d=c[M];h=a[d];z.length<=M?(s={element:C.clone().attr("label",d),label:h.label},t=[s],z.push(t),f.append(s.element)):(t=z[M],s=t[0],s.label!=d&&s.element.attr("label",s.label=d));D=null;B=0;for(I=h.length;B<I;B++)d=h[B],(v=t[B+1])?(D=v.element,v.label!==d.label&&D.text(v.label=d.label),v.id!==d.id&&D.val(v.id=d.id),D[0].selected!==d.selected&&(D.prop("selected",v.selected=d.selected),
+Q&&D.prop("selected",v.selected))):(""===d.id&&F?K=F:(K=A.clone()).val(d.id).prop("selected",d.selected).attr("selected",d.selected).text(d.label),t.push({element:K,label:d.label,id:d.id,selected:d.selected}),p.addOption(d.label,K),D?D.after(K):s.element.append(K),D=K);for(B++;t.length>B;)d=t.pop(),p.removeOption(d.label),d.element.remove()}for(;z.length>M;)z.pop()[0].element.remove()}var h;if(!(h=s.match(d)))throw Ze("iexp",s,ia(f));var l=c(h[2]||h[1]),m=h[4]||h[6],n=h[5],r=c(h[3]||""),u=c(h[2]?
+h[1]:m),w=c(h[7]),x=h[8]?c(h[8]):null,z=[[{element:f,label:""}]];F&&(a(F)(e),F.removeClass("ng-scope"),F.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=w(e)||[],d={},h,l,p,r,s,v,y;if(q)for(l=[],r=0,v=z.length;r<v;r++)for(a=z[r],p=1,s=a.length;p<s;p++){if((h=a[p].element)[0].selected){h=h.val();n&&(d[n]=h);if(x)for(y=0;y<c.length&&(d[m]=c[y],x(e,d)!=h);y++);else d[m]=c[h];l.push(u(e,d))}}else if(h=f.val(),"?"==h)l=t;else if(""===h)l=null;else if(x)for(y=0;y<c.length;y++){if(d[m]=
+c[y],x(e,d)==h){l=u(e,d);break}}else d[m]=c[h],n&&(d[n]=h),l=u(e,d);g.$setViewValue(l);k()})});g.$render=k;e.$watchCollection(w,k);e.$watchCollection(function(){var a={},c=w(e);if(c){for(var d=Array(c.length),f=0,g=c.length;f<g;f++)a[m]=c[f],d[f]=l(e,a);return d}},k);q&&e.$watchCollection(function(){return g.$modelValue},k)}if(m[1]){var p=m[0];m=m[1];var q=k.multiple,s=k.ngOptions,F=!1,u,A=w(X.createElement("option")),C=w(X.createElement("optgroup")),v=A.clone();k=0;for(var z=g.children(),E=z.length;k<
+E;k++)if(""===z[k].value){u=F=z.eq(k);break}p.init(m,F,v);q&&(m.$isEmpty=function(a){return!a||0===a.length});s?n(e,g,m):q?l(e,g,m):h(e,g,m,p)}}}}],id=["$interpolate",function(a){var c={addOption:E,removeOption:E};return{restrict:"E",priority:100,compile:function(d,e){if(x(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,d,e){var h=d.parent(),l=h.data("$selectController")||h.parent().data("$selectController");l&&l.databound?d.prop("selected",!1):l=c;f?a.$watch(f,function(a,
+c){e.$set("value",a);a!==c&&l.removeOption(c);l.addOption(a)}):l.addOption(e.value);d.on("$destroy",function(){l.removeOption(e.value)})}}}}],hd=ba({restrict:"E",terminal:!0});W.angular.bootstrap?console.log("WARNING: Tried to load angular more than once."):((Ea=W.jQuery)&&Ea.fn.on?(w=Ea,D(Ea.fn,{scope:La.scope,isolateScope:La.isolateScope,controller:La.controller,injector:La.injector,inheritedData:La.inheritedData}),Gb("remove",!0,!0,!1),Gb("empty",!1,!1,!1),Gb("html",!1,!1,!0)):w=S,Va.element=w,
+$c(Va),w(X).ready(function(){Xc(X,fc)}))})(window,document);!window.angular.$$csp()&&window.angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}</style>');
+//# sourceMappingURL=angular.min.js.map
diff --git a/src/main/resources/META-INF/resources/designer/lib/angular.min.js.map b/src/main/resources/META-INF/resources/designer/lib/angular.min.js.map
new file mode 100644 (file)
index 0000000..178bdf4
--- /dev/null
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular.min.js",
+"lineCount":246,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAmBC,CAAnB,CAA8B,CAgCvCC,QAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,MAAAA,SAAAA,EAAAA,CAAAA,IAAAA,EAAAA,SAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,EAAAA,CAAAA,GAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,GAAAA,CAAAA,EAAAA,EAAAA,CAAAA,CAAAA,sCAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,GAAAA,CAAAA,EAAAA,EAAAA,CAAAA,KAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,SAAAA,OAAAA,CAAAA,CAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,EAAAA,CAAAA,EAAAA,CAAAA,CAAAA,GAAAA,CAAAA,GAAAA,EAAAA,GAAAA,EAAAA,CAAAA,CAAAA,CAAAA,EAAAA,GAAAA,KAAAA,EAAAA,kBAAAA,CAAAA,CAAAA,EAAAA,CAAAA,SAAAA,CAAAA,CAAAA,CAAAA,EAAAA,CAAAA,UAAAA,EAAAA,MAAAA,EAAAA,CAAAA,CAAAA,SAAAA,EAAAA,QAAAA,CAAAA,aAAAA,CAAAA,EAAAA,CAAAA,CAAAA,WAAAA,EAAAA,MAAAA,EAAAA,CAAAA,WAAAA,CAAAA,QAAAA,EAAAA,MAAAA,EAAAA,CAAAA,IAAAA,UAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,EAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,MAAAA,MAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CA6OAC,QAASA,GAAW,CAACC,CAAD,CAAM,CACxB,GAAW,IAAX,EAAIA,CAAJ,EAAmBC,EAAA,CAASD,CAAT,CAAnB,CACE,MAAO,CAAA,CAGT,KAAIE,EAASF,CAAAE,OAEb,OAAIF,EAAAG,SAAJ;AAAqBC,EAArB,EAA0CF,CAA1C,CACS,CAAA,CADT,CAIOG,CAAA,CAASL,CAAT,CAJP,EAIwBM,CAAA,CAAQN,CAAR,CAJxB,EAImD,CAJnD,GAIwCE,CAJxC,EAKyB,QALzB,GAKO,MAAOA,EALd,EAK8C,CAL9C,CAKqCA,CALrC,EAKoDA,CALpD,CAK6D,CAL7D,GAKmEF,EAZ3C,CA6C1BO,QAASA,EAAO,CAACP,CAAD,CAAMQ,CAAN,CAAgBC,CAAhB,CAAyB,CAAA,IACnCC,CADmC,CAC9BR,CACT,IAAIF,CAAJ,CACE,GAAIW,CAAA,CAAWX,CAAX,CAAJ,CACE,IAAKU,CAAL,GAAYV,EAAZ,CAGa,WAAX,EAAIU,CAAJ,EAAiC,QAAjC,EAA0BA,CAA1B,EAAoD,MAApD,EAA6CA,CAA7C,EAAgEV,CAAAY,eAAhE,EAAsF,CAAAZ,CAAAY,eAAA,CAAmBF,CAAnB,CAAtF,EACEF,CAAAK,KAAA,CAAcJ,CAAd,CAAuBT,CAAA,CAAIU,CAAJ,CAAvB,CAAiCA,CAAjC,CAAsCV,CAAtC,CALN,KAQO,IAAIM,CAAA,CAAQN,CAAR,CAAJ,EAAoBD,EAAA,CAAYC,CAAZ,CAApB,CAAsC,CAC3C,IAAIc,EAA6B,QAA7BA,GAAc,MAAOd,EACpBU,EAAA,CAAM,CAAX,KAAcR,CAAd,CAAuBF,CAAAE,OAAvB,CAAmCQ,CAAnC,CAAyCR,CAAzC,CAAiDQ,CAAA,EAAjD,CACE,CAAII,CAAJ,EAAmBJ,CAAnB,GAA0BV,EAA1B,GACEQ,CAAAK,KAAA,CAAcJ,CAAd,CAAuBT,CAAA,CAAIU,CAAJ,CAAvB,CAAiCA,CAAjC,CAAsCV,CAAtC,CAJuC,CAAtC,IAOA,IAAIA,CAAAO,QAAJ,EAAmBP,CAAAO,QAAnB,GAAmCA,CAAnC,CACHP,CAAAO,QAAA,CAAYC,CAAZ,CAAsBC,CAAtB,CAA+BT,CAA/B,CADG,KAGL,KAAKU,CAAL,GAAYV,EAAZ,CACMA,CAAAY,eAAA,CAAmBF,CAAnB,CAAJ,EACEF,CAAAK,KAAA,CAAcJ,CAAd,CAAuBT,CAAA,CAAIU,CAAJ,CAAvB,CAAiCA,CAAjC,CAAsCV,CAAtC,CAKR,OAAOA,EA5BgC,CA+BzCe,QAASA,GAAU,CAACf,CAAD,CAAM,CACvB,IAAIgB,EAAO,EAAX,CACSN,CAAT,KAASA,CAAT,GAAgBV,EAAhB,CACMA,CAAAY,eAAA,CAAmBF,CAAnB,CAAJ,EACEM,CAAAC,KAAA,CAAUP,CAAV,CAGJ;MAAOM,EAAAE,KAAA,EAPgB,CAUzBC,QAASA,GAAa,CAACnB,CAAD,CAAMQ,CAAN,CAAgBC,CAAhB,CAAyB,CAE7C,IADA,IAAIO,EAAOD,EAAA,CAAWf,CAAX,CAAX,CACUoB,EAAI,CAAd,CAAiBA,CAAjB,CAAqBJ,CAAAd,OAArB,CAAkCkB,CAAA,EAAlC,CACEZ,CAAAK,KAAA,CAAcJ,CAAd,CAAuBT,CAAA,CAAIgB,CAAA,CAAKI,CAAL,CAAJ,CAAvB,CAAqCJ,CAAA,CAAKI,CAAL,CAArC,CAEF,OAAOJ,EALsC,CAc/CK,QAASA,GAAa,CAACC,CAAD,CAAa,CACjC,MAAO,SAAQ,CAACC,CAAD,CAAQb,CAAR,CAAa,CAAEY,CAAA,CAAWZ,CAAX,CAAgBa,CAAhB,CAAF,CADK,CAcnCC,QAASA,GAAO,EAAG,CACjB,MAAO,EAAEC,EADQ,CAUnBC,QAASA,GAAU,CAAC1B,CAAD,CAAM2B,CAAN,CAAS,CACtBA,CAAJ,CACE3B,CAAA4B,UADF,CACkBD,CADlB,CAIE,OAAO3B,CAAA4B,UALiB,CAwB5BC,QAASA,EAAM,CAACC,CAAD,CAAM,CAGnB,IAFA,IAAIH,EAAIG,CAAAF,UAAR,CAESR,EAAI,CAFb,CAEgBW,EAAKC,SAAA9B,OAArB,CAAuCkB,CAAvC,CAA2CW,CAA3C,CAA+CX,CAAA,EAA/C,CAAoD,CAClD,IAAIpB,EAAMgC,SAAA,CAAUZ,CAAV,CACV,IAAIpB,CAAJ,CAEE,IADA,IAAIgB,EAAOiB,MAAAjB,KAAA,CAAYhB,CAAZ,CAAX,CACSkC,EAAI,CADb,CACgBC,EAAKnB,CAAAd,OAArB,CAAkCgC,CAAlC,CAAsCC,CAAtC,CAA0CD,CAAA,EAA1C,CAA+C,CAC7C,IAAIxB,EAAMM,CAAA,CAAKkB,CAAL,CACVJ,EAAA,CAAIpB,CAAJ,CAAA,CAAWV,CAAA,CAAIU,CAAJ,CAFkC,CAJC,CAWpDgB,EAAA,CAAWI,CAAX,CAAgBH,CAAhB,CACA,OAAOG,EAfY,CAkBrBM,QAASA,GAAG,CAACC,CAAD,CAAM,CAChB,MAAOC,SAAA,CAASD,CAAT,CAAc,EAAd,CADS,CAKlBE,QAASA,GAAO,CAACC,CAAD,CAASC,CAAT,CAAgB,CAC9B,MAAOZ,EAAA,CAAO,KAAKA,CAAA,CAAO,QAAQ,EAAG,EAAlB,CAAsB,CAACa,UAAUF,CAAX,CAAtB,CAAL,CAAP;AAA0DC,CAA1D,CADuB,CAoBhCE,QAASA,EAAI,EAAG,EAoBhBC,QAASA,GAAQ,CAACC,CAAD,CAAI,CAAC,MAAOA,EAAR,CAIrBC,QAASA,GAAO,CAACvB,CAAD,CAAQ,CAAC,MAAO,SAAQ,EAAG,CAAC,MAAOA,EAAR,CAAnB,CAcxBwB,QAASA,EAAW,CAACxB,CAAD,CAAO,CAAC,MAAwB,WAAxB,GAAO,MAAOA,EAAf,CAe3ByB,QAASA,EAAS,CAACzB,CAAD,CAAO,CAAC,MAAwB,WAAxB,GAAO,MAAOA,EAAf,CAgBzB0B,QAASA,EAAQ,CAAC1B,CAAD,CAAO,CAEtB,MAAiB,KAAjB,GAAOA,CAAP,EAA0C,QAA1C,GAAyB,MAAOA,EAFV,CAkBxBlB,QAASA,EAAQ,CAACkB,CAAD,CAAO,CAAC,MAAwB,QAAxB,GAAO,MAAOA,EAAf,CAexB2B,QAASA,EAAQ,CAAC3B,CAAD,CAAO,CAAC,MAAwB,QAAxB,GAAO,MAAOA,EAAf,CAexB4B,QAASA,GAAM,CAAC5B,CAAD,CAAQ,CACrB,MAAgC,eAAhC,GAAO6B,EAAAvC,KAAA,CAAcU,CAAd,CADc,CA+BvBZ,QAASA,EAAU,CAACY,CAAD,CAAO,CAAC,MAAwB,UAAxB,GAAO,MAAOA,EAAf,CAU1B8B,QAASA,GAAQ,CAAC9B,CAAD,CAAQ,CACvB,MAAgC,iBAAhC,GAAO6B,EAAAvC,KAAA,CAAcU,CAAd,CADgB,CAYzBtB,QAASA,GAAQ,CAACD,CAAD,CAAM,CACrB,MAAOA,EAAP,EAAcA,CAAAL,OAAd,GAA6BK,CADR,CAKvBsD,QAASA,GAAO,CAACtD,CAAD,CAAM,CACpB,MAAOA,EAAP;AAAcA,CAAAuD,WAAd,EAAgCvD,CAAAwD,OADZ,CAetBC,QAASA,GAAS,CAAClC,CAAD,CAAQ,CACxB,MAAwB,SAAxB,GAAO,MAAOA,EADU,CA2B1BmC,QAASA,GAAS,CAACC,CAAD,CAAO,CACvB,MAAO,EAAGA,CAAAA,CAAH,EACJ,EAAAA,CAAAC,SAAA,EACGD,CAAAE,KADH,EACgBF,CAAAG,KADhB,EAC6BH,CAAAI,KAD7B,CADI,CADgB,CAUzBC,QAASA,GAAO,CAAC3B,CAAD,CAAM,CAAA,IAChBrC,EAAM,EAAIiE,EAAAA,CAAQ5B,CAAA6B,MAAA,CAAU,GAAV,CAAtB,KAAsC9C,CACtC,KAAMA,CAAN,CAAU,CAAV,CAAaA,CAAb,CAAiB6C,CAAA/D,OAAjB,CAA+BkB,CAAA,EAA/B,CACEpB,CAAA,CAAKiE,CAAA,CAAM7C,CAAN,CAAL,CAAA,CAAkB,CAAA,CACpB,OAAOpB,EAJa,CAQtBmE,QAASA,GAAS,CAACC,CAAD,CAAU,CAC1B,MAAOC,EAAA,CAAUD,CAAAR,SAAV,EAA8BQ,CAAA,CAAQ,CAAR,CAAAR,SAA9B,CADmB,CAoC5BU,QAASA,GAAW,CAACC,CAAD,CAAQhD,CAAR,CAAe,CACjC,IAAIiD,EAAQD,CAAAE,QAAA,CAAclD,CAAd,CACA,EAAZ,EAAIiD,CAAJ,EACED,CAAAG,OAAA,CAAaF,CAAb,CAAoB,CAApB,CACF,OAAOjD,EAJ0B,CA6EnCoD,QAASA,GAAI,CAACC,CAAD,CAASC,CAAT,CAAsBC,CAAtB,CAAmCC,CAAnC,CAA8C,CACzD,GAAI9E,EAAA,CAAS2E,CAAT,CAAJ,EAAwBtB,EAAA,CAAQsB,CAAR,CAAxB,CACE,KAAMI,GAAA,CAAS,MAAT,CAAN,CAIF,GAAKH,CAAL,CAeO,CACL,GAAID,CAAJ,GAAeC,CAAf,CAA4B,KAAMG,GAAA,CAAS,KAAT,CAAN,CAG5BF,CAAA,CAAcA,CAAd,EAA6B,EAC7BC,EAAA,CAAYA,CAAZ,EAAyB,EAEzB,IAAI9B,CAAA,CAAS2B,CAAT,CAAJ,CAAsB,CACpB,IAAIJ,EAAQM,CAAAL,QAAA,CAAoBG,CAApB,CACZ,IAAe,EAAf,GAAIJ,CAAJ,CAAkB,MAAOO,EAAA,CAAUP,CAAV,CAEzBM,EAAA7D,KAAA,CAAiB2D,CAAjB,CACAG,EAAA9D,KAAA,CAAe4D,CAAf,CALoB,CAStB,GAAIvE,CAAA,CAAQsE,CAAR,CAAJ,CAEE,IAAU,IAAAxD;AADVyD,CAAA3E,OACUkB,CADW,CACrB,CAAiBA,CAAjB,CAAqBwD,CAAA1E,OAArB,CAAoCkB,CAAA,EAApC,CACE6D,CAKA,CALSN,EAAA,CAAKC,CAAA,CAAOxD,CAAP,CAAL,CAAgB,IAAhB,CAAsB0D,CAAtB,CAAmCC,CAAnC,CAKT,CAJI9B,CAAA,CAAS2B,CAAA,CAAOxD,CAAP,CAAT,CAIJ,GAHE0D,CAAA7D,KAAA,CAAiB2D,CAAA,CAAOxD,CAAP,CAAjB,CACA,CAAA2D,CAAA9D,KAAA,CAAegE,CAAf,CAEF,EAAAJ,CAAA5D,KAAA,CAAiBgE,CAAjB,CARJ,KAUO,CACL,IAAItD,EAAIkD,CAAAjD,UACJtB,EAAA,CAAQuE,CAAR,CAAJ,CACEA,CAAA3E,OADF,CACuB,CADvB,CAGEK,CAAA,CAAQsE,CAAR,CAAqB,QAAQ,CAACtD,CAAD,CAAQb,CAAR,CAAa,CACxC,OAAOmE,CAAA,CAAYnE,CAAZ,CADiC,CAA1C,CAIF,KAAUA,CAAV,GAAiBkE,EAAjB,CACKA,CAAAhE,eAAA,CAAsBF,CAAtB,CAAH,GACEuE,CAKA,CALSN,EAAA,CAAKC,CAAA,CAAOlE,CAAP,CAAL,CAAkB,IAAlB,CAAwBoE,CAAxB,CAAqCC,CAArC,CAKT,CAJI9B,CAAA,CAAS2B,CAAA,CAAOlE,CAAP,CAAT,CAIJ,GAHEoE,CAAA7D,KAAA,CAAiB2D,CAAA,CAAOlE,CAAP,CAAjB,CACA,CAAAqE,CAAA9D,KAAA,CAAegE,CAAf,CAEF,EAAAJ,CAAA,CAAYnE,CAAZ,CAAA,CAAmBuE,CANrB,CASFvD,GAAA,CAAWmD,CAAX,CAAuBlD,CAAvB,CAnBK,CA1BF,CAfP,IAEE,IADAkD,CACA,CADcD,CACd,CACMtE,CAAA,CAAQsE,CAAR,CAAJ,CACEC,CADF,CACgBF,EAAA,CAAKC,CAAL,CAAa,EAAb,CAAiBE,CAAjB,CAA8BC,CAA9B,CADhB,CAEW5B,EAAA,CAAOyB,CAAP,CAAJ,CACLC,CADK,CACS,IAAIK,IAAJ,CAASN,CAAAO,QAAA,EAAT,CADT,CAEI9B,EAAA,CAASuB,CAAT,CAAJ,EACLC,CACA,CADc,IAAIO,MAAJ,CAAWR,CAAAA,OAAX,CAA0BA,CAAAxB,SAAA,EAAAiC,MAAA,CAAwB,SAAxB,CAAA,CAAmC,CAAnC,CAA1B,CACd,CAAAR,CAAAS,UAAA,CAAwBV,CAAAU,UAFnB,EAGIrC,CAAA,CAAS2B,CAAT,CAHJ,GAIDW,CACJ,CADkBtD,MAAAuD,OAAA,CAAcvD,MAAAwD,eAAA,CAAsBb,CAAtB,CAAd,CAClB,CAAAC,CAAA,CAAcF,EAAA,CAAKC,CAAL,CAAaW,CAAb,CAA0BT,CAA1B,CAAuCC,CAAvC,CALT,CAyDX,OAAOF,EAtEkD,CA8E3Da,QAASA,GAAW,CAACC,CAAD;AAAM7D,CAAN,CAAW,CAC7B,GAAIxB,CAAA,CAAQqF,CAAR,CAAJ,CAAkB,CAChB7D,CAAA,CAAMA,CAAN,EAAa,EAEb,KAHgB,IAGPV,EAAI,CAHG,CAGAW,EAAK4D,CAAAzF,OAArB,CAAiCkB,CAAjC,CAAqCW,CAArC,CAAyCX,CAAA,EAAzC,CACEU,CAAA,CAAIV,CAAJ,CAAA,CAASuE,CAAA,CAAIvE,CAAJ,CAJK,CAAlB,IAMO,IAAI6B,CAAA,CAAS0C,CAAT,CAAJ,CAGL,IAASjF,CAAT,GAFAoB,EAEgB6D,CAFV7D,CAEU6D,EAFH,EAEGA,CAAAA,CAAhB,CACE,GAAwB,GAAxB,GAAMjF,CAAAkF,OAAA,CAAW,CAAX,CAAN,EAAiD,GAAjD,GAA+BlF,CAAAkF,OAAA,CAAW,CAAX,CAA/B,CACE9D,CAAA,CAAIpB,CAAJ,CAAA,CAAWiF,CAAA,CAAIjF,CAAJ,CAKjB,OAAOoB,EAAP,EAAc6D,CAjBe,CAkD/BE,QAASA,GAAM,CAACC,CAAD,CAAKC,CAAL,CAAS,CACtB,GAAID,CAAJ,GAAWC,CAAX,CAAe,MAAO,CAAA,CACtB,IAAW,IAAX,GAAID,CAAJ,EAA0B,IAA1B,GAAmBC,CAAnB,CAAgC,MAAO,CAAA,CACvC,IAAID,CAAJ,GAAWA,CAAX,EAAiBC,CAAjB,GAAwBA,CAAxB,CAA4B,MAAO,CAAA,CAHb,KAIlBC,EAAK,MAAOF,EAJM,CAIsBpF,CAC5C,IAAIsF,CAAJ,EADyBC,MAAOF,EAChC,EACY,QADZ,EACMC,CADN,CAEI,GAAI1F,CAAA,CAAQwF,CAAR,CAAJ,CAAiB,CACf,GAAK,CAAAxF,CAAA,CAAQyF,CAAR,CAAL,CAAkB,MAAO,CAAA,CACzB,KAAK7F,CAAL,CAAc4F,CAAA5F,OAAd,GAA4B6F,CAAA7F,OAA5B,CAAuC,CACrC,IAAIQ,CAAJ,CAAQ,CAAR,CAAWA,CAAX,CAAeR,CAAf,CAAuBQ,CAAA,EAAvB,CACE,GAAK,CAAAmF,EAAA,CAAOC,CAAA,CAAGpF,CAAH,CAAP,CAAgBqF,CAAA,CAAGrF,CAAH,CAAhB,CAAL,CAA+B,MAAO,CAAA,CAExC,OAAO,CAAA,CAJ8B,CAFxB,CAAjB,IAQO,CAAA,GAAIyC,EAAA,CAAO2C,CAAP,CAAJ,CACL,MAAK3C,GAAA,CAAO4C,CAAP,CAAL,CACOF,EAAA,CAAOC,CAAAX,QAAA,EAAP,CAAqBY,CAAAZ,QAAA,EAArB,CADP,CAAwB,CAAA,CAEnB,IAAI9B,EAAA,CAASyC,CAAT,CAAJ,EAAoBzC,EAAA,CAAS0C,CAAT,CAApB,CACL,MAAOD,EAAA1C,SAAA,EAAP,EAAwB2C,CAAA3C,SAAA,EAExB;GAAIE,EAAA,CAAQwC,CAAR,CAAJ,EAAmBxC,EAAA,CAAQyC,CAAR,CAAnB,EAAkC9F,EAAA,CAAS6F,CAAT,CAAlC,EAAkD7F,EAAA,CAAS8F,CAAT,CAAlD,EAAkEzF,CAAA,CAAQyF,CAAR,CAAlE,CAA+E,MAAO,CAAA,CACtFG,EAAA,CAAS,EACT,KAAIxF,CAAJ,GAAWoF,EAAX,CACE,GAAsB,GAAtB,GAAIpF,CAAAkF,OAAA,CAAW,CAAX,CAAJ,EAA6B,CAAAjF,CAAA,CAAWmF,CAAA,CAAGpF,CAAH,CAAX,CAA7B,CAAA,CACA,GAAK,CAAAmF,EAAA,CAAOC,CAAA,CAAGpF,CAAH,CAAP,CAAgBqF,CAAA,CAAGrF,CAAH,CAAhB,CAAL,CAA+B,MAAO,CAAA,CACtCwF,EAAA,CAAOxF,CAAP,CAAA,CAAc,CAAA,CAFd,CAIF,IAAIA,CAAJ,GAAWqF,EAAX,CACE,GAAK,CAAAG,CAAAtF,eAAA,CAAsBF,CAAtB,CAAL,EACsB,GADtB,GACIA,CAAAkF,OAAA,CAAW,CAAX,CADJ,EAEIG,CAAA,CAAGrF,CAAH,CAFJ,GAEgBb,CAFhB,EAGK,CAAAc,CAAA,CAAWoF,CAAA,CAAGrF,CAAH,CAAX,CAHL,CAG0B,MAAO,CAAA,CAEnC,OAAO,CAAA,CAnBF,CAuBX,MAAO,CAAA,CAtCe,CA8DxByF,QAASA,GAAM,CAACC,CAAD,CAASC,CAAT,CAAiB7B,CAAjB,CAAwB,CACrC,MAAO4B,EAAAD,OAAA,CAAcG,EAAAzF,KAAA,CAAWwF,CAAX,CAAmB7B,CAAnB,CAAd,CAD8B,CA4BvC+B,QAASA,GAAI,CAACC,CAAD,CAAOC,CAAP,CAAW,CACtB,IAAIC,EAA+B,CAAnB,CAAA1E,SAAA9B,OAAA,CAxBToG,EAAAzF,KAAA,CAwB0CmB,SAxB1C,CAwBqD2E,CAxBrD,CAwBS,CAAiD,EACjE,OAAI,CAAAhG,CAAA,CAAW8F,CAAX,CAAJ,EAAwBA,CAAxB,WAAsCrB,OAAtC,CAcSqB,CAdT,CACSC,CAAAxG,OAAA,CACH,QAAQ,EAAG,CACT,MAAO8B,UAAA9B,OAAA,CACHuG,CAAAG,MAAA,CAASJ,CAAT,CAAeE,CAAAP,OAAA,CAAiBG,EAAAzF,KAAA,CAAWmB,SAAX,CAAsB,CAAtB,CAAjB,CAAf,CADG,CAEHyE,CAAAG,MAAA,CAASJ,CAAT,CAAeE,CAAf,CAHK,CADR,CAMH,QAAQ,EAAG,CACT,MAAO1E,UAAA9B,OAAA;AACHuG,CAAAG,MAAA,CAASJ,CAAT,CAAexE,SAAf,CADG,CAEHyE,CAAA5F,KAAA,CAAQ2F,CAAR,CAHK,CATK,CAqBxBK,QAASA,GAAc,CAACnG,CAAD,CAAMa,CAAN,CAAa,CAClC,IAAIuF,EAAMvF,CAES,SAAnB,GAAI,MAAOb,EAAX,EAAiD,GAAjD,GAA+BA,CAAAkF,OAAA,CAAW,CAAX,CAA/B,EAA0E,GAA1E,GAAwDlF,CAAAkF,OAAA,CAAW,CAAX,CAAxD,CACEkB,CADF,CACQjH,CADR,CAEWI,EAAA,CAASsB,CAAT,CAAJ,CACLuF,CADK,CACC,SADD,CAEIvF,CAAJ,EAAc3B,CAAd,GAA2B2B,CAA3B,CACLuF,CADK,CACC,WADD,CAEIxD,EAAA,CAAQ/B,CAAR,CAFJ,GAGLuF,CAHK,CAGC,QAHD,CAMP,OAAOA,EAb2B,CA+BpCC,QAASA,GAAM,CAAC/G,CAAD,CAAMgH,CAAN,CAAc,CAC3B,MAAmB,WAAnB,GAAI,MAAOhH,EAAX,CAAuCH,CAAvC,CACOoH,IAAAC,UAAA,CAAelH,CAAf,CAAoB6G,EAApB,CAAoCG,CAAA,CAAS,IAAT,CAAgB,IAApD,CAFoB,CAkB7BG,QAASA,GAAQ,CAACC,CAAD,CAAO,CACtB,MAAO/G,EAAA,CAAS+G,CAAT,CAAA,CACDH,IAAAI,MAAA,CAAWD,CAAX,CADC,CAEDA,CAHgB,CAUxBE,QAASA,GAAW,CAAClD,CAAD,CAAU,CAC5BA,CAAA,CAAUmD,CAAA,CAAOnD,CAAP,CAAAoD,MAAA,EACV,IAAI,CAGFpD,CAAAqD,MAAA,EAHE,CAIF,MAAMC,CAAN,CAAS,EACX,IAAIC,EAAWJ,CAAA,CAAO,OAAP,CAAAK,OAAA,CAAuBxD,CAAvB,CAAAyD,KAAA,EACf,IAAI,CACF,MAAOzD,EAAA,CAAQ,CAAR,CAAAjE,SAAA,GAAwB2H,EAAxB,CAAyCzD,CAAA,CAAUsD,CAAV,CAAzC,CACHA,CAAAtC,MAAA,CACQ,YADR,CAAA,CACsB,CADtB,CAAA0C,QAAA,CAEU,aAFV,CAEyB,QAAQ,CAAC1C,CAAD,CAAQzB,CAAR,CAAkB,CAAE,MAAO,GAAP;AAAaS,CAAA,CAAUT,CAAV,CAAf,CAFnD,CAFF,CAKF,MAAM8D,CAAN,CAAS,CACT,MAAOrD,EAAA,CAAUsD,CAAV,CADE,CAbiB,CA8B9BK,QAASA,GAAqB,CAACzG,CAAD,CAAQ,CACpC,GAAI,CACF,MAAO0G,mBAAA,CAAmB1G,CAAnB,CADL,CAEF,MAAMmG,CAAN,CAAS,EAHyB,CAatCQ,QAASA,GAAa,CAAYC,CAAZ,CAAsB,CAAA,IACtCnI,EAAM,EADgC,CAC5BoI,CAD4B,CACjB1H,CACzBH,EAAA,CAAQ2D,CAACiE,CAADjE,EAAa,EAAbA,OAAA,CAAuB,GAAvB,CAAR,CAAqC,QAAQ,CAACiE,CAAD,CAAW,CACjDA,CAAL,GACEC,CAEA,CAFYD,CAAAJ,QAAA,CAAiB,KAAjB,CAAuB,KAAvB,CAAA7D,MAAA,CAAoC,GAApC,CAEZ,CADAxD,CACA,CADMsH,EAAA,CAAsBI,CAAA,CAAU,CAAV,CAAtB,CACN,CAAKpF,CAAA,CAAUtC,CAAV,CAAL,GACMoG,CACJ,CADU9D,CAAA,CAAUoF,CAAA,CAAU,CAAV,CAAV,CAAA,CAA0BJ,EAAA,CAAsBI,CAAA,CAAU,CAAV,CAAtB,CAA1B,CAAgE,CAAA,CAC1E,CAAKxH,EAAAC,KAAA,CAAoBb,CAApB,CAAyBU,CAAzB,CAAL,CAEUJ,CAAA,CAAQN,CAAA,CAAIU,CAAJ,CAAR,CAAH,CACLV,CAAA,CAAIU,CAAJ,CAAAO,KAAA,CAAc6F,CAAd,CADK,CAGL9G,CAAA,CAAIU,CAAJ,CAHK,CAGM,CAACV,CAAA,CAAIU,CAAJ,CAAD,CAAUoG,CAAV,CALb,CACE9G,CAAA,CAAIU,CAAJ,CADF,CACaoG,CAHf,CAHF,CADsD,CAAxD,CAgBA,OAAO9G,EAlBmC,CAqB5CqI,QAASA,GAAU,CAACrI,CAAD,CAAM,CACvB,IAAIsI,EAAQ,EACZ/H,EAAA,CAAQP,CAAR,CAAa,QAAQ,CAACuB,CAAD,CAAQb,CAAR,CAAa,CAC5BJ,CAAA,CAAQiB,CAAR,CAAJ,CACEhB,CAAA,CAAQgB,CAAR,CAAe,QAAQ,CAACgH,CAAD,CAAa,CAClCD,CAAArH,KAAA,CAAWuH,EAAA,CAAe9H,CAAf,CAAoB,CAAA,CAApB,CAAX,EAC2B,CAAA,CAAf,GAAA6H,CAAA,CAAsB,EAAtB,CAA2B,GAA3B,CAAiCC,EAAA,CAAeD,CAAf,CAA2B,CAAA,CAA3B,CAD7C,EADkC,CAApC,CADF,CAMAD,CAAArH,KAAA,CAAWuH,EAAA,CAAe9H,CAAf,CAAoB,CAAA,CAApB,CAAX,EACsB,CAAA,CAAV,GAAAa,CAAA,CAAiB,EAAjB,CAAsB,GAAtB,CAA4BiH,EAAA,CAAejH,CAAf,CAAsB,CAAA,CAAtB,CADxC,EAPgC,CAAlC,CAWA,OAAO+G,EAAApI,OAAA,CAAeoI,CAAAG,KAAA,CAAW,GAAX,CAAf,CAAiC,EAbjB,CA4BzBC,QAASA,GAAgB,CAAC5B,CAAD,CAAM,CAC7B,MAAO0B,GAAA,CAAe1B,CAAf;AAAoB,CAAA,CAApB,CAAAiB,QAAA,CACY,OADZ,CACqB,GADrB,CAAAA,QAAA,CAEY,OAFZ,CAEqB,GAFrB,CAAAA,QAAA,CAGY,OAHZ,CAGqB,GAHrB,CADsB,CAmB/BS,QAASA,GAAc,CAAC1B,CAAD,CAAM6B,CAAN,CAAuB,CAC5C,MAAOC,mBAAA,CAAmB9B,CAAnB,CAAAiB,QAAA,CACY,OADZ,CACqB,GADrB,CAAAA,QAAA,CAEY,OAFZ,CAEqB,GAFrB,CAAAA,QAAA,CAGY,MAHZ,CAGoB,GAHpB,CAAAA,QAAA,CAIY,OAJZ,CAIqB,GAJrB,CAAAA,QAAA,CAKY,OALZ,CAKqB,GALrB,CAAAA,QAAA,CAMY,MANZ,CAMqBY,CAAA,CAAkB,KAAlB,CAA0B,GAN/C,CADqC,CAY9CE,QAASA,GAAc,CAACzE,CAAD,CAAU0E,CAAV,CAAkB,CAAA,IACnChF,CADmC,CAC7B1C,CAD6B,CAC1BW,EAAKgH,EAAA7I,OAClBkE,EAAA,CAAUmD,CAAA,CAAOnD,CAAP,CACV,KAAKhD,CAAL,CAAO,CAAP,CAAUA,CAAV,CAAYW,CAAZ,CAAgB,EAAEX,CAAlB,CAEE,GADA0C,CACI,CADGiF,EAAA,CAAe3H,CAAf,CACH,CADuB0H,CACvB,CAAAzI,CAAA,CAASyD,CAAT,CAAgBM,CAAAN,KAAA,CAAaA,CAAb,CAAhB,CAAJ,CACE,MAAOA,EAGX,OAAO,KATgC,CA2IzCkF,QAASA,GAAW,CAAC5E,CAAD,CAAU6E,CAAV,CAAqB,CAAA,IACnCC,CADmC,CAEnCC,CAFmC,CAGnCC,EAAS,EAGb7I,EAAA,CAAQwI,EAAR,CAAwB,QAAQ,CAACM,CAAD,CAAS,CACnCC,CAAAA,EAAgB,KAEfJ,EAAAA,CAAL,EAAmB9E,CAAAmF,aAAnB,EAA2CnF,CAAAmF,aAAA,CAAqBD,CAArB,CAA3C,GACEJ,CACA,CADa9E,CACb,CAAA+E,CAAA,CAAS/E,CAAAoF,aAAA,CAAqBF,CAArB,CAFX,CAHuC,CAAzC,CAQA/I,EAAA,CAAQwI,EAAR,CAAwB,QAAQ,CAACM,CAAD,CAAS,CACnCC,CAAAA,EAAgB,KACpB;IAAIG,CAECP,EAAAA,CAAL,GAAoBO,CAApB,CAAgCrF,CAAAsF,cAAA,CAAsB,GAAtB,CAA4BJ,CAAAvB,QAAA,CAAa,GAAb,CAAkB,KAAlB,CAA5B,CAAuD,GAAvD,CAAhC,IACEmB,CACA,CADaO,CACb,CAAAN,CAAA,CAASM,CAAAD,aAAA,CAAuBF,CAAvB,CAFX,CAJuC,CAAzC,CASIJ,EAAJ,GACEE,CAAAO,SACA,CAD8D,IAC9D,GADkBd,EAAA,CAAeK,CAAf,CAA2B,WAA3B,CAClB,CAAAD,CAAA,CAAUC,CAAV,CAAsBC,CAAA,CAAS,CAACA,CAAD,CAAT,CAAoB,EAA1C,CAA8CC,CAA9C,CAFF,CAvBuC,CA+EzCH,QAASA,GAAS,CAAC7E,CAAD,CAAUwF,CAAV,CAAmBR,CAAnB,CAA2B,CACtCnG,CAAA,CAASmG,CAAT,CAAL,GAAuBA,CAAvB,CAAgC,EAAhC,CAIAA,EAAA,CAASvH,CAAA,CAHWgI,CAClBF,SAAU,CAAA,CADQE,CAGX,CAAsBT,CAAtB,CACT,KAAIU,EAAcA,QAAQ,EAAG,CAC3B1F,CAAA,CAAUmD,CAAA,CAAOnD,CAAP,CAEV,IAAIA,CAAA2F,SAAA,EAAJ,CAAwB,CACtB,IAAIC,EAAO5F,CAAA,CAAQ,CAAR,CAAD,GAAgBxE,CAAhB,CAA4B,UAA5B,CAAyC0H,EAAA,CAAYlD,CAAZ,CAEnD,MAAMY,GAAA,CACF,SADE,CAGFgF,CAAAjC,QAAA,CAAY,GAAZ,CAAgB,MAAhB,CAAAA,QAAA,CAAgC,GAAhC,CAAoC,MAApC,CAHE,CAAN,CAHsB,CASxB6B,CAAA,CAAUA,CAAV,EAAqB,EACrBA,EAAAK,QAAA,CAAgB,CAAC,UAAD,CAAa,QAAQ,CAACC,CAAD,CAAW,CAC9CA,CAAA3I,MAAA,CAAe,cAAf,CAA+B6C,CAA/B,CAD8C,CAAhC,CAAhB,CAIIgF,EAAAe,iBAAJ,EAEEP,CAAA3I,KAAA,CAAa,CAAC,kBAAD,CAAqB,QAAQ,CAACmJ,CAAD,CAAmB,CAC3DA,CAAAD,iBAAA,CAAkC,CAAA,CAAlC,CAD2D,CAAhD,CAAb,CAKFP,EAAAK,QAAA,CAAgB,IAAhB,CACIF;CAAAA,CAAWM,EAAA,CAAeT,CAAf,CAAwBR,CAAAO,SAAxB,CACfI,EAAAO,OAAA,CAAgB,CAAC,YAAD,CAAe,cAAf,CAA+B,UAA/B,CAA2C,WAA3C,CACbC,QAAuB,CAACC,CAAD,CAAQpG,CAAR,CAAiBqG,CAAjB,CAA0BV,CAA1B,CAAoC,CAC1DS,CAAAE,OAAA,CAAa,QAAQ,EAAG,CACtBtG,CAAAuG,KAAA,CAAa,WAAb,CAA0BZ,CAA1B,CACAU,EAAA,CAAQrG,CAAR,CAAA,CAAiBoG,CAAjB,CAFsB,CAAxB,CAD0D,CAD9C,CAAhB,CAQA,OAAOT,EAlCoB,CAA7B,CAqCIa,EAAuB,wBArC3B,CAsCIC,EAAqB,sBAErBlL,EAAJ,EAAciL,CAAAE,KAAA,CAA0BnL,CAAA2J,KAA1B,CAAd,GACEF,CAAAe,iBACA,CAD0B,CAAA,CAC1B,CAAAxK,CAAA2J,KAAA,CAAc3J,CAAA2J,KAAAvB,QAAA,CAAoB6C,CAApB,CAA0C,EAA1C,CAFhB,CAKA,IAAIjL,CAAJ,EAAe,CAAAkL,CAAAC,KAAA,CAAwBnL,CAAA2J,KAAxB,CAAf,CACE,MAAOQ,EAAA,EAGTnK,EAAA2J,KAAA,CAAc3J,CAAA2J,KAAAvB,QAAA,CAAoB8C,CAApB,CAAwC,EAAxC,CACdE,GAAAC,gBAAA,CAA0BC,QAAQ,CAACC,CAAD,CAAe,CAC/C3K,CAAA,CAAQ2K,CAAR,CAAsB,QAAQ,CAAC/B,CAAD,CAAS,CACrCS,CAAA3I,KAAA,CAAakI,CAAb,CADqC,CAAvC,CAGAW,EAAA,EAJ+C,CAxDN,CA0E7CqB,QAASA,GAAmB,EAAG,CAC7BxL,CAAA2J,KAAA,CAAc,uBAAd,CAAwC3J,CAAA2J,KACxC3J,EAAAyL,SAAAC,OAAA,EAF6B,CAa/BC,QAASA,GAAc,CAACC,CAAD,CAAc,CACnC,MAAOR,GAAA3G,QAAA,CAAgBmH,CAAhB,CAAAxB,SAAA,EAAAyB,IAAA,CAA4C,eAA5C,CAD4B,CA9/CE;AAmgDvCC,QAASA,GAAU,CAACnC,CAAD,CAAOoC,CAAP,CAAkB,CACnCA,CAAA,CAAYA,CAAZ,EAAyB,GACzB,OAAOpC,EAAAvB,QAAA,CAAa4D,EAAb,CAAgC,QAAQ,CAACC,CAAD,CAASC,CAAT,CAAc,CAC3D,OAAQA,CAAA,CAAMH,CAAN,CAAkB,EAA1B,EAAgCE,CAAAE,YAAA,EAD2B,CAAtD,CAF4B,CASrCC,QAASA,GAAU,EAAG,CACpB,IAAIC,CAEAC,GAAJ,GAUA,CALAC,EAKA,CALSvM,CAAAuM,OAKT,GAAcA,EAAAzF,GAAA0F,GAAd,EACE5E,CAaA,CAbS2E,EAaT,CAZArK,CAAA,CAAOqK,EAAAzF,GAAP,CAAkB,CAChB+D,MAAO4B,EAAA5B,MADS,CAEhB6B,aAAcD,EAAAC,aAFE,CAGhBC,WAAYF,EAAAE,WAHI,CAIhBvC,SAAUqC,EAAArC,SAJM,CAKhBwC,cAAeH,EAAAG,cALC,CAAlB,CAYA,CADAP,CACA,CADoBE,EAAAM,UACpB,CAAAN,EAAAM,UAAA,CAAmBC,QAAQ,CAACC,CAAD,CAAQ,CACjC,IAAIC,CACJ,IAAKC,EAAL,CAQEA,EAAA,CAAmC,CAAA,CARrC,KACE,KADqC,IAC5BxL,EAAI,CADwB,CACrByL,CAAhB,CAA2C,IAA3C,GAAuBA,CAAvB,CAA8BH,CAAA,CAAMtL,CAAN,CAA9B,EAAiDA,CAAA,EAAjD,CAEE,CADAuL,CACA,CADST,EAAAY,MAAA,CAAaD,CAAb,CAAmB,QAAnB,CACT,GAAcF,CAAAI,SAAd,EACEb,EAAA,CAAOW,CAAP,CAAAG,eAAA,CAA4B,UAA5B,CAMNhB,EAAA,CAAkBU,CAAlB,CAZiC,CAdrC,EA6BEnF,CA7BF,CA6BW0F,CAMX,CAHAlC,EAAA3G,QAGA,CAHkBmD,CAGlB,CAAA0E,EAAA,CAAkB,CAAA,CA7ClB,CAHoB,CAsDtBiB,QAASA,GAAS,CAACC,CAAD,CAAM7D,CAAN,CAAY8D,CAAZ,CAAoB,CACpC,GAAKD,CAAAA,CAAL,CACE,KAAMnI,GAAA,CAAS,MAAT;AAA2CsE,CAA3C,EAAmD,GAAnD,CAA0D8D,CAA1D,EAAoE,UAApE,CAAN,CAEF,MAAOD,EAJ6B,CAOtCE,QAASA,GAAW,CAACF,CAAD,CAAM7D,CAAN,CAAYgE,CAAZ,CAAmC,CACjDA,CAAJ,EAA6BhN,CAAA,CAAQ6M,CAAR,CAA7B,GACIA,CADJ,CACUA,CAAA,CAAIA,CAAAjN,OAAJ,CAAiB,CAAjB,CADV,CAIAgN,GAAA,CAAUvM,CAAA,CAAWwM,CAAX,CAAV,CAA2B7D,CAA3B,CAAiC,sBAAjC,EACK6D,CAAA,EAAsB,QAAtB,GAAO,MAAOA,EAAd,CAAiCA,CAAAI,YAAAjE,KAAjC,EAAyD,QAAzD,CAAoE,MAAO6D,EADhF,EAEA,OAAOA,EAP8C,CAevDK,QAASA,GAAuB,CAAClE,CAAD,CAAO7I,CAAP,CAAgB,CAC9C,GAAa,gBAAb,GAAI6I,CAAJ,CACE,KAAMtE,GAAA,CAAS,SAAT,CAA8DvE,CAA9D,CAAN,CAF4C,CAchDgN,QAASA,GAAM,CAACzN,CAAD,CAAM0N,CAAN,CAAYC,CAAZ,CAA2B,CACxC,GAAKD,CAAAA,CAAL,CAAW,MAAO1N,EACdgB,EAAAA,CAAO0M,CAAAxJ,MAAA,CAAW,GAAX,CAKX,KAJA,IAAIxD,CAAJ,CACIkN,EAAe5N,CADnB,CAEI6N,EAAM7M,CAAAd,OAFV,CAISkB,EAAI,CAAb,CAAgBA,CAAhB,CAAoByM,CAApB,CAAyBzM,CAAA,EAAzB,CACEV,CACA,CADMM,CAAA,CAAKI,CAAL,CACN,CAAIpB,CAAJ,GACEA,CADF,CACQ,CAAC4N,CAAD,CAAgB5N,CAAhB,EAAqBU,CAArB,CADR,CAIF,OAAKiN,CAAAA,CAAL,EAAsBhN,CAAA,CAAWX,CAAX,CAAtB,CACSuG,EAAA,CAAKqH,CAAL,CAAmB5N,CAAnB,CADT,CAGOA,CAhBiC,CAwB1C8N,QAASA,GAAa,CAACC,CAAD,CAAQ,CAG5B,IAAIpK,EAAOoK,CAAA,CAAM,CAAN,CACPC,EAAAA,CAAUD,CAAA,CAAMA,CAAA7N,OAAN,CAAqB,CAArB,CACd,KAAI+N,EAAa,CAACtK,CAAD,CAEjB,GAAG,CACDA,CAAA,CAAOA,CAAAuK,YACP,IAAKvK,CAAAA,CAAL,CAAW,KACXsK,EAAAhN,KAAA,CAAgB0C,CAAhB,CAHC,CAAH,MAISA,CAJT,GAIkBqK,CAJlB,CAMA,OAAOzG,EAAA,CAAO0G,CAAP,CAbqB,CA4B9BE,QAASA,GAAS,EAAG,CACnB,MAAOlM,OAAAuD,OAAA,CAAc,IAAd,CADY,CA1pDkB;AA6qDvC4I,QAASA,GAAiB,CAACzO,CAAD,CAAS,CAKjC0O,QAASA,EAAM,CAACrO,CAAD,CAAMsJ,CAAN,CAAYgF,CAAZ,CAAqB,CAClC,MAAOtO,EAAA,CAAIsJ,CAAJ,CAAP,GAAqBtJ,CAAA,CAAIsJ,CAAJ,CAArB,CAAiCgF,CAAA,EAAjC,CADkC,CAHpC,IAAIC,EAAkBzO,CAAA,CAAO,WAAP,CAAtB,CACIkF,EAAWlF,CAAA,CAAO,IAAP,CAMXiL,EAAAA,CAAUsD,CAAA,CAAO1O,CAAP,CAAe,SAAf,CAA0BsC,MAA1B,CAGd8I,EAAAyD,SAAA,CAAmBzD,CAAAyD,SAAnB,EAAuC1O,CAEvC,OAAOuO,EAAA,CAAOtD,CAAP,CAAgB,QAAhB,CAA0B,QAAQ,EAAG,CAE1C,IAAInB,EAAU,EAqDd,OAAOT,SAAe,CAACG,CAAD,CAAOmF,CAAP,CAAiBC,CAAjB,CAA2B,CAE7C,GAAa,gBAAb,GAKsBpF,CALtB,CACE,KAAMtE,EAAA,CAAS,SAAT,CAIoBvE,QAJpB,CAAN,CAKAgO,CAAJ,EAAgB7E,CAAAhJ,eAAA,CAAuB0I,CAAvB,CAAhB,GACEM,CAAA,CAAQN,CAAR,CADF,CACkB,IADlB,CAGA,OAAO+E,EAAA,CAAOzE,CAAP,CAAgBN,CAAhB,CAAsB,QAAQ,EAAG,CAuNtCqF,QAASA,EAAW,CAACC,CAAD,CAAWC,CAAX,CAAmBC,CAAnB,CAAiCC,CAAjC,CAAwC,CACrDA,CAAL,GAAYA,CAAZ,CAAoBC,CAApB,CACA,OAAO,SAAQ,EAAG,CAChBD,CAAA,CAAMD,CAAN,EAAsB,MAAtB,CAAA,CAA8B,CAACF,CAAD,CAAWC,CAAX,CAAmB7M,SAAnB,CAA9B,CACA,OAAOiN,EAFS,CAFwC,CAtN5D,GAAKR,CAAAA,CAAL,CACE,KAAMF,EAAA,CAAgB,OAAhB,CAEiDjF,CAFjD,CAAN,CAMF,IAAI0F,EAAc,EAAlB,CAGIE,EAAe,EAHnB,CAMIC,EAAY,EANhB,CAQI/F,EAASuF,CAAA,CAAY,WAAZ,CAAyB,QAAzB,CAAmC,MAAnC,CAA2CO,CAA3C,CARb,CAWID,EAAiB,CAEnBG,aAAcJ,CAFK,CAGnBK,cAAeH,CAHI;AAInBI,WAAYH,CAJO,CAenBV,SAAUA,CAfS,CAyBnBnF,KAAMA,CAzBa,CAsCnBsF,SAAUD,CAAA,CAAY,UAAZ,CAAwB,UAAxB,CAtCS,CAiDnBL,QAASK,CAAA,CAAY,UAAZ,CAAwB,SAAxB,CAjDU,CA4DnBY,QAASZ,CAAA,CAAY,UAAZ,CAAwB,SAAxB,CA5DU,CAuEnBpN,MAAOoN,CAAA,CAAY,UAAZ,CAAwB,OAAxB,CAvEY,CAmFnBa,SAAUb,CAAA,CAAY,UAAZ,CAAwB,UAAxB,CAAoC,SAApC,CAnFS,CAqHnBc,UAAWd,CAAA,CAAY,kBAAZ,CAAgC,UAAhC,CArHQ,CAgInBe,OAAQf,CAAA,CAAY,iBAAZ,CAA+B,UAA/B,CAhIW,CA4InBrC,WAAYqC,CAAA,CAAY,qBAAZ,CAAmC,UAAnC,CA5IO,CAyJnBgB,UAAWhB,CAAA,CAAY,kBAAZ,CAAgC,WAAhC,CAzJQ,CAsKnBvF,OAAQA,CAtKW,CAkLnBwG,IAAKA,QAAQ,CAACC,CAAD,CAAQ,CACnBV,CAAAlO,KAAA,CAAe4O,CAAf,CACA,OAAO,KAFY,CAlLF,CAwLjBnB,EAAJ,EACEtF,CAAA,CAAOsF,CAAP,CAGF,OAAQO,EA/M8B,CAAjC,CAXwC,CAvDP,CAArC,CAd0B,CAkanCa,QAASA,GAAkB,CAAC/E,CAAD,CAAS,CAClClJ,CAAA,CAAOkJ,CAAP,CAAgB,CACd,UAAa9B,EADC,CAEd,KAAQtE,EAFM,CAGd,OAAU9C,CAHI,CAId,OAAUgE,EAJI;AAKd,QAAW0B,CALG,CAMd,QAAWhH,CANG,CAOd,SAAY8J,EAPE,CAQd,KAAQ1H,CARM,CASd,KAAQ4D,EATM,CAUd,OAAUQ,EAVI,CAWd,SAAYI,EAXE,CAYd,SAAYvE,EAZE,CAad,YAAeG,CAbD,CAcd,UAAaC,CAdC,CAed,SAAY3C,CAfE,CAgBd,WAAcM,CAhBA,CAiBd,SAAYsC,CAjBE,CAkBd,SAAYC,CAlBE,CAmBd,UAAaQ,EAnBC,CAoBd,QAAWpD,CApBG,CAqBd,QAAWyP,EArBG,CAsBd,OAAU5M,EAtBI,CAuBd,UAAakB,CAvBC,CAwBd,UAAa2L,EAxBC,CAyBd,UAAa,CAACC,QAAS,CAAV,CAzBC,CA0Bd,eAAkB3E,EA1BJ,CA2Bd,SAAYxL,CA3BE,CA4Bd,MAASoQ,EA5BK,CA6Bd,oBAAuB/E,EA7BT,CAAhB,CAgCAgF,GAAA,CAAgB/B,EAAA,CAAkBzO,CAAlB,CAChB,IAAI,CACFwQ,EAAA,CAAc,UAAd,CADE,CAEF,MAAOzI,CAAP,CAAU,CACVyI,EAAA,CAAc,UAAd,CAA0B,EAA1B,CAAAvB,SAAA,CAAuC,SAAvC,CAAkDwB,EAAlD,CADU,CAIZD,EAAA,CAAc,IAAd,CAAoB,CAAC,UAAD,CAApB,CAAkC,CAAC,UAAD,CAChCE,QAAiB,CAACnG,CAAD,CAAW,CAE1BA,CAAA0E,SAAA,CAAkB,CAChB0B,cAAeC,EADC,CAAlB,CAGArG,EAAA0E,SAAA,CAAkB,UAAlB,CAA8B4B,EAA9B,CAAAb,UAAA,CACY,CACNc,EAAGC,EADG;AAENC,MAAOC,EAFD,CAGNC,SAAUD,EAHJ,CAINE,KAAMC,EAJA,CAKNC,OAAQC,EALF,CAMNC,OAAQC,EANF,CAONC,MAAOC,EAPD,CAQNC,OAAQC,EARF,CASNC,OAAQC,EATF,CAUNC,WAAYC,EAVN,CAWNC,eAAgBC,EAXV,CAYNC,QAASC,EAZH,CAaNC,YAAaC,EAbP,CAcNC,WAAYC,EAdN,CAeNC,QAASC,EAfH,CAgBNC,aAAcC,EAhBR,CAiBNC,OAAQC,EAjBF,CAkBNC,OAAQC,EAlBF,CAmBNC,KAAMC,EAnBA,CAoBNC,UAAWC,EApBL,CAqBNC,OAAQC,EArBF,CAsBNC,cAAeC,EAtBT,CAuBNC,YAAaC,EAvBP,CAwBNC,SAAUC,EAxBJ,CAyBNC,OAAQC,EAzBF,CA0BNC,QAASC,EA1BH,CA2BNC,SAAUC,EA3BJ,CA4BNC,aAAcC,EA5BR,CA6BNC,gBAAiBC,EA7BX,CA8BNC,UAAWC,EA9BL,CA+BNC,aAAcC,EA/BR,CAgCNC,QAASC,EAhCH,CAiCNC,OAAQC,EAjCF,CAkCNC,SAAUC,EAlCJ,CAmCNC,QAASC,EAnCH,CAoCNC,UAAWD,EApCL,CAqCNE,SAAUC,EArCJ,CAsCNC,WAAYD,EAtCN,CAuCNE,UAAWC,EAvCL,CAwCNC,YAAaD,EAxCP,CAyCNE,UAAWC,EAzCL,CA0CNC,YAAaD,EA1CP;AA2CNE,QAASC,EA3CH,CA4CNC,eAAgBC,EA5CV,CADZ,CAAAhG,UAAA,CA+CY,CACRmD,UAAW8C,EADH,CA/CZ,CAAAjG,UAAA,CAkDYkG,EAlDZ,CAAAlG,UAAA,CAmDYmG,EAnDZ,CAoDA5L,EAAA0E,SAAA,CAAkB,CAChBmH,cAAeC,EADC,CAEhBC,SAAUC,EAFM,CAGhBC,SAAUC,EAHM,CAIhBC,cAAeC,EAJC,CAKhBC,YAAaC,EALG,CAMhBC,UAAWC,EANK,CAOhBC,kBAAmBC,EAPH,CAQhBC,QAASC,EARO,CAShBC,aAAcC,EATE,CAUhBC,UAAWC,EAVK,CAWhBC,MAAOC,EAXS,CAYhBC,aAAcC,EAZE,CAahBC,UAAWC,EAbK,CAchBC,KAAMC,EAdU,CAehBC,OAAQC,EAfQ,CAgBhBC,WAAYC,EAhBI,CAiBhBC,GAAIC,EAjBY,CAkBhBC,IAAKC,EAlBW,CAmBhBC,KAAMC,EAnBU,CAoBhBC,aAAcC,EApBE,CAqBhBC,SAAUC,EArBM,CAsBhBC,eAAgBC,EAtBA,CAuBhBC,iBAAkBC,EAvBF,CAwBhBC,cAAeC,EAxBC,CAyBhBC,SAAUC,EAzBM,CA0BhBC,QAASC,EA1BO,CA2BhBC,MAAOC,EA3BS,CA4BhBC,gBAAkBC,EA5BF,CAAlB,CAzD0B,CADI,CAAlC,CAxCkC,CAsQpCC,QAASA,GAAS,CAACjQ,CAAD,CAAO,CACvB,MAAOA,EAAAvB,QAAA,CACGyR,EADH;AACyB,QAAQ,CAACC,CAAD,CAAI/N,CAAJ,CAAeE,CAAf,CAAuB8N,CAAvB,CAA+B,CACnE,MAAOA,EAAA,CAAS9N,CAAA+N,YAAA,EAAT,CAAgC/N,CAD4B,CADhE,CAAA7D,QAAA,CAIG6R,EAJH,CAIoB,OAJpB,CADgB,CAgCzBC,QAASA,GAAiB,CAAClW,CAAD,CAAO,CAG3BxD,CAAAA,CAAWwD,CAAAxD,SACf,OAAOA,EAAP,GAAoBC,EAApB,EAAyC,CAACD,CAA1C,EAxtBuB2Z,CAwtBvB,GAAsD3Z,CAJvB,CAOjC4Z,QAASA,GAAmB,CAAClS,CAAD,CAAOpH,CAAP,CAAgB,CAAA,IACtCuZ,CADsC,CACjChQ,CADiC,CAEtCiQ,EAAWxZ,CAAAyZ,uBAAA,EAF2B,CAGtCnM,EAAQ,EAEZ,IAfQoM,EAAArP,KAAA,CAeajD,CAfb,CAeR,CAGO,CAELmS,CAAA,CAAMA,CAAN,EAAaC,CAAAG,YAAA,CAAqB3Z,CAAA4Z,cAAA,CAAsB,KAAtB,CAArB,CACbrQ,EAAA,CAAM,CAACsQ,EAAAC,KAAA,CAAqB1S,CAArB,CAAD,EAA+B,CAAC,EAAD,CAAK,EAAL,CAA/B,EAAyC,CAAzC,CAAAiE,YAAA,EACN0O,EAAA,CAAOC,EAAA,CAAQzQ,CAAR,CAAP,EAAuByQ,EAAAC,SACvBV,EAAAW,UAAA,CAAgBH,CAAA,CAAK,CAAL,CAAhB,CAA0B3S,CAAAE,QAAA,CAAa6S,EAAb,CAA+B,WAA/B,CAA1B,CAAwEJ,CAAA,CAAK,CAAL,CAIxE,KADApZ,CACA,CADIoZ,CAAA,CAAK,CAAL,CACJ,CAAOpZ,CAAA,EAAP,CAAA,CACE4Y,CAAA,CAAMA,CAAAa,UAGR9M,EAAA,CAAQ5H,EAAA,CAAO4H,CAAP,CAAciM,CAAAc,WAAd,CAERd,EAAA,CAAMC,CAAAc,WACNf,EAAAgB,YAAA,CAAkB,EAhBb,CAHP,IAEEjN,EAAA9M,KAAA,CAAWR,CAAAwa,eAAA,CAAuBpT,CAAvB,CAAX,CAqBFoS,EAAAe,YAAA,CAAuB,EACvBf,EAAAU,UAAA,CAAqB,EACrBpa,EAAA,CAAQwN,CAAR,CAAe,QAAQ,CAACpK,CAAD,CAAO,CAC5BsW,CAAAG,YAAA,CAAqBzW,CAArB,CAD4B,CAA9B,CAIA;MAAOsW,EAlCmC,CAqD5ChN,QAASA,EAAM,CAAC7I,CAAD,CAAU,CACvB,GAAIA,CAAJ,WAAuB6I,EAAvB,CACE,MAAO7I,EAGT,KAAI8W,CAEA7a,EAAA,CAAS+D,CAAT,CAAJ,GACEA,CACA,CADU+W,CAAA,CAAK/W,CAAL,CACV,CAAA8W,CAAA,CAAc,CAAA,CAFhB,CAIA,IAAM,EAAA,IAAA,WAAgBjO,EAAhB,CAAN,CAA+B,CAC7B,GAAIiO,CAAJ,EAAwC,GAAxC,EAAmB9W,CAAAwB,OAAA,CAAe,CAAf,CAAnB,CACE,KAAMwV,GAAA,CAAa,OAAb,CAAN,CAEF,MAAO,KAAInO,CAAJ,CAAW7I,CAAX,CAJsB,CAO/B,GAAI8W,CAAJ,CAAiB,CAjCjBza,CAAA,CAAqBb,CACrB,KAAIyb,CAGF,EAAA,CADF,CAAKA,CAAL,CAAcC,EAAAf,KAAA,CAAuB1S,CAAvB,CAAd,EACS,CAACpH,CAAA4Z,cAAA,CAAsBgB,CAAA,CAAO,CAAP,CAAtB,CAAD,CADT,CAIA,CAAKA,CAAL,CAActB,EAAA,CAAoBlS,CAApB,CAA0BpH,CAA1B,CAAd,EACS4a,CAAAP,WADT,CAIO,EAsBU,CACfS,EAAA,CAAe,IAAf,CAAqB,CAArB,CAnBqB,CAyBzBC,QAASA,GAAW,CAACpX,CAAD,CAAU,CAC5B,MAAOA,EAAAqX,UAAA,CAAkB,CAAA,CAAlB,CADqB,CAI9BC,QAASA,GAAY,CAACtX,CAAD,CAAUuX,CAAV,CAA0B,CACxCA,CAAL,EAAsBC,EAAA,CAAiBxX,CAAjB,CAEtB,IAAIA,CAAAyX,iBAAJ,CAEE,IADA,IAAIC,EAAc1X,CAAAyX,iBAAA,CAAyB,GAAzB,CAAlB,CACSza,EAAI,CADb,CACgB2a,EAAID,CAAA5b,OAApB,CAAwCkB,CAAxC,CAA4C2a,CAA5C,CAA+C3a,CAAA,EAA/C,CACEwa,EAAA,CAAiBE,CAAA,CAAY1a,CAAZ,CAAjB,CANyC,CAW/C4a,QAASA,GAAS,CAAC5X,CAAD,CAAU6X,CAAV,CAAgBxV,CAAhB,CAAoByV,CAApB,CAAiC,CACjD,GAAIlZ,CAAA,CAAUkZ,CAAV,CAAJ,CAA4B,KAAMd,GAAA,CAAa,SAAb,CAAN,CAG5B,IAAIzO,GADAwP,CACAxP,CADeyP,EAAA,CAAmBhY,CAAnB,CACfuI,GAAyBwP,CAAAxP,OAA7B,CACI0P,EAASF,CAATE,EAAyBF,CAAAE,OAE7B,IAAKA,CAAL,CAEA,GAAKJ,CAAL,CAQE1b,CAAA,CAAQ0b,CAAA/X,MAAA,CAAW,GAAX,CAAR;AAAyB,QAAQ,CAAC+X,CAAD,CAAO,CACtC,GAAIjZ,CAAA,CAAUyD,CAAV,CAAJ,CAAmB,CACjB,IAAI6V,EAAc3P,CAAA,CAAOsP,CAAP,CAClB3X,GAAA,CAAYgY,CAAZ,EAA2B,EAA3B,CAA+B7V,CAA/B,CACA,IAAI6V,CAAJ,EAAwC,CAAxC,CAAmBA,CAAApc,OAAnB,CACE,MAJe,CAQGkE,CAtLtBmY,oBAAA,CAsL+BN,CAtL/B,CAsLqCI,CAtLrC,CAAsC,CAAA,CAAtC,CAuLA,QAAO1P,CAAA,CAAOsP,CAAP,CAV+B,CAAxC,CARF,KACE,KAAKA,CAAL,GAAatP,EAAb,CACe,UAGb,GAHIsP,CAGJ,EAFwB7X,CAxKxBmY,oBAAA,CAwKiCN,CAxKjC,CAwKuCI,CAxKvC,CAAsC,CAAA,CAAtC,CA0KA,CAAA,OAAO1P,CAAA,CAAOsP,CAAP,CAdsC,CAgCnDL,QAASA,GAAgB,CAACxX,CAAD,CAAUkF,CAAV,CAAgB,CACvC,IAAIkT,EAAYpY,CAAAqY,MAAhB,CACIN,EAAeK,CAAfL,EAA4BO,EAAA,CAAQF,CAAR,CAE5BL,EAAJ,GACM7S,CAAJ,CACE,OAAO6S,CAAAxR,KAAA,CAAkBrB,CAAlB,CADT,EAKI6S,CAAAE,OAOJ,GANMF,CAAAxP,OAAAI,SAGJ,EAFEoP,CAAAE,OAAA,CAAoB,EAApB,CAAwB,UAAxB,CAEF,CAAAL,EAAA,CAAU5X,CAAV,CAGF,EADA,OAAOsY,EAAA,CAAQF,CAAR,CACP,CAAApY,CAAAqY,MAAA,CAAgB5c,CAZhB,CADF,CAJuC,CAsBzCuc,QAASA,GAAkB,CAAChY,CAAD,CAAUuY,CAAV,CAA6B,CAAA,IAClDH,EAAYpY,CAAAqY,MADsC,CAElDN,EAAeK,CAAfL,EAA4BO,EAAA,CAAQF,CAAR,CAE5BG,EAAJ,EAA0BR,CAAAA,CAA1B,GACE/X,CAAAqY,MACA,CADgBD,CAChB,CA7MyB,EAAEI,EA6M3B,CAAAT,CAAA,CAAeO,EAAA,CAAQF,CAAR,CAAf,CAAoC,CAAC7P,OAAQ,EAAT,CAAahC,KAAM,EAAnB,CAAuB0R,OAAQxc,CAA/B,CAFtC,CAKA,OAAOsc,EAT+C,CAaxDU,QAASA,GAAU,CAACzY,CAAD,CAAU1D,CAAV,CAAea,CAAf,CAAsB,CACvC,GAAIsY,EAAA,CAAkBzV,CAAlB,CAAJ,CAAgC,CAE9B,IAAI0Y,EAAiB9Z,CAAA,CAAUzB,CAAV,CAArB,CACIwb,EAAiB,CAACD,CAAlBC,EAAoCrc,CAApCqc,EAA2C,CAAC9Z,CAAA,CAASvC,CAAT,CADhD;AAEIsc,EAAa,CAACtc,CAEdiK,EAAAA,EADAwR,CACAxR,CADeyR,EAAA,CAAmBhY,CAAnB,CAA4B,CAAC2Y,CAA7B,CACfpS,GAAuBwR,CAAAxR,KAE3B,IAAImS,CAAJ,CACEnS,CAAA,CAAKjK,CAAL,CAAA,CAAYa,CADd,KAEO,CACL,GAAIyb,CAAJ,CACE,MAAOrS,EAEP,IAAIoS,CAAJ,CAEE,MAAOpS,EAAP,EAAeA,CAAA,CAAKjK,CAAL,CAEfmB,EAAA,CAAO8I,CAAP,CAAajK,CAAb,CARC,CAVuB,CADO,CA0BzCuc,QAASA,GAAc,CAAC7Y,CAAD,CAAU8Y,CAAV,CAAoB,CACzC,MAAK9Y,EAAAoF,aAAL,CAEuC,EAFvC,CACQzB,CAAC,GAADA,EAAQ3D,CAAAoF,aAAA,CAAqB,OAArB,CAARzB,EAAyC,EAAzCA,EAA+C,GAA/CA,SAAA,CAA4D,SAA5D,CAAuE,GAAvE,CAAAtD,QAAA,CACK,GADL,CACWyY,CADX,CACsB,GADtB,CADR,CAAkC,CAAA,CADO,CAM3CC,QAASA,GAAiB,CAAC/Y,CAAD,CAAUgZ,CAAV,CAAsB,CAC1CA,CAAJ,EAAkBhZ,CAAAiZ,aAAlB,EACE9c,CAAA,CAAQ6c,CAAAlZ,MAAA,CAAiB,GAAjB,CAAR,CAA+B,QAAQ,CAACoZ,CAAD,CAAW,CAChDlZ,CAAAiZ,aAAA,CAAqB,OAArB,CAA8BlC,CAAA,CAC1BpT,CAAC,GAADA,EAAQ3D,CAAAoF,aAAA,CAAqB,OAArB,CAARzB,EAAyC,EAAzCA,EAA+C,GAA/CA,SAAA,CACS,SADT,CACoB,GADpB,CAAAA,QAAA,CAES,GAFT,CAEeoT,CAAA,CAAKmC,CAAL,CAFf,CAEgC,GAFhC,CAEqC,GAFrC,CAD0B,CAA9B,CADgD,CAAlD,CAF4C,CAYhDC,QAASA,GAAc,CAACnZ,CAAD,CAAUgZ,CAAV,CAAsB,CAC3C,GAAIA,CAAJ,EAAkBhZ,CAAAiZ,aAAlB,CAAwC,CACtC,IAAIG,EAAkBzV,CAAC,GAADA,EAAQ3D,CAAAoF,aAAA,CAAqB,OAArB,CAARzB,EAAyC,EAAzCA,EAA+C,GAA/CA,SAAA,CACW,SADX,CACsB,GADtB,CAGtBxH;CAAA,CAAQ6c,CAAAlZ,MAAA,CAAiB,GAAjB,CAAR,CAA+B,QAAQ,CAACoZ,CAAD,CAAW,CAChDA,CAAA,CAAWnC,CAAA,CAAKmC,CAAL,CAC4C,GAAvD,GAAIE,CAAA/Y,QAAA,CAAwB,GAAxB,CAA8B6Y,CAA9B,CAAyC,GAAzC,CAAJ,GACEE,CADF,EACqBF,CADrB,CACgC,GADhC,CAFgD,CAAlD,CAOAlZ,EAAAiZ,aAAA,CAAqB,OAArB,CAA8BlC,CAAA,CAAKqC,CAAL,CAA9B,CAXsC,CADG,CAiB7CjC,QAASA,GAAc,CAACkC,CAAD,CAAOC,CAAP,CAAiB,CAGtC,GAAIA,CAAJ,CAGE,GAAIA,CAAAvd,SAAJ,CACEsd,CAAA,CAAKA,CAAAvd,OAAA,EAAL,CAAA,CAAsBwd,CADxB,KAEO,CACL,IAAIxd,EAASwd,CAAAxd,OAGb,IAAsB,QAAtB,GAAI,MAAOA,EAAX,EAAkCwd,CAAA/d,OAAlC,GAAsD+d,CAAtD,CACE,IAAIxd,CAAJ,CACE,IAAS,IAAAkB,EAAI,CAAb,CAAgBA,CAAhB,CAAoBlB,CAApB,CAA4BkB,CAAA,EAA5B,CACEqc,CAAA,CAAKA,CAAAvd,OAAA,EAAL,CAAA,CAAsBwd,CAAA,CAAStc,CAAT,CAF1B,CADF,IAOEqc,EAAA,CAAKA,CAAAvd,OAAA,EAAL,CAAA,CAAsBwd,CAXnB,CAR6B,CA0BxCC,QAASA,GAAgB,CAACvZ,CAAD,CAAUkF,CAAV,CAAgB,CACvC,MAAOsU,GAAA,CAAoBxZ,CAApB,CAA6B,GAA7B,EAAoCkF,CAApC,EAA4C,cAA5C,EAA+D,YAA/D,CADgC,CAIzCsU,QAASA,GAAmB,CAACxZ,CAAD,CAAUkF,CAAV,CAAgB/H,CAAhB,CAAuB,CAt9B1BuY,CAy9BvB,EAAG1V,CAAAjE,SAAH,GACEiE,CADF,CACYA,CAAAyZ,gBADZ,CAKA,KAFIC,CAEJ,CAFYxd,CAAA,CAAQgJ,CAAR,CAAA,CAAgBA,CAAhB,CAAuB,CAACA,CAAD,CAEnC,CAAOlF,CAAP,CAAA,CAAgB,CACd,IADc,IACLhD,EAAI,CADC,CACEW,EAAK+b,CAAA5d,OAArB,CAAmCkB,CAAnC,CAAuCW,CAAvC,CAA2CX,CAAA,EAA3C,CACE,IAAKG,CAAL,CAAagG,CAAAoD,KAAA,CAAYvG,CAAZ,CAAqB0Z,CAAA,CAAM1c,CAAN,CAArB,CAAb,IAAiDvB,CAAjD,CAA4D,MAAO0B,EAMrE6C,EAAA,CAAUA,CAAA2Z,WAAV;AAr+B8BC,EAq+B9B,GAAiC5Z,CAAAjE,SAAjC,EAAqFiE,CAAA6Z,KARvE,CARiC,CAoBnDC,QAASA,GAAW,CAAC9Z,CAAD,CAAU,CAE5B,IADAsX,EAAA,CAAatX,CAAb,CAAsB,CAAA,CAAtB,CACA,CAAOA,CAAA2W,WAAP,CAAA,CACE3W,CAAA+Z,YAAA,CAAoB/Z,CAAA2W,WAApB,CAH0B,CAO9BqD,QAASA,GAAY,CAACha,CAAD,CAAUia,CAAV,CAAoB,CAClCA,CAAL,EAAe3C,EAAA,CAAatX,CAAb,CACf,KAAI5B,EAAS4B,CAAA2Z,WACTvb,EAAJ,EAAYA,CAAA2b,YAAA,CAAmB/Z,CAAnB,CAH2B,CAOzCka,QAASA,GAAoB,CAACC,CAAD,CAASC,CAAT,CAAc,CACzCA,CAAA,CAAMA,CAAN,EAAa7e,CACb,IAAgC,UAAhC,GAAI6e,CAAA5e,SAAA6e,WAAJ,CAIED,CAAAE,WAAA,CAAeH,CAAf,CAJF,KAOEhX,EAAA,CAAOiX,CAAP,CAAArS,GAAA,CAAe,MAAf,CAAuBoS,CAAvB,CATuC,CA2E3CI,QAASA,GAAkB,CAACva,CAAD,CAAUkF,CAAV,CAAgB,CAEzC,IAAIsV,EAAcC,EAAA,CAAavV,CAAAwC,YAAA,EAAb,CAGlB,OAAO8S,EAAP,EAAsBE,EAAA,CAAiB3a,EAAA,CAAUC,CAAV,CAAjB,CAAtB,EAA8Dwa,CALrB,CAQ3CG,QAASA,GAAkB,CAAC3a,CAAD,CAAUkF,CAAV,CAAgB,CACzC,IAAI1F,EAAWQ,CAAAR,SACf,QAAqB,OAArB,GAAQA,CAAR,EAA6C,UAA7C,GAAgCA,CAAhC,GAA4Dob,EAAA,CAAa1V,CAAb,CAFnB,CA6K3C2V,QAASA,GAAkB,CAAC7a,CAAD,CAAUuI,CAAV,CAAkB,CAC3C,IAAIuS,EAAeA,QAAS,CAACC,CAAD,CAAQlD,CAAR,CAAc,CAExCkD,CAAAC,mBAAA,CAA2BC,QAAQ,EAAG,CACpC,MAAOF,EAAAG,iBAD6B,CAItC,KAAIC;AAAW5S,CAAA,CAAOsP,CAAP,EAAekD,CAAAlD,KAAf,CAAf,CACIuD,EAAiBD,CAAA,CAAWA,CAAArf,OAAX,CAA6B,CAElD,IAAKsf,CAAL,CAAA,CAEA,GAAIzc,CAAA,CAAYoc,CAAAM,4BAAZ,CAAJ,CAAoD,CAClD,IAAIC,EAAmCP,CAAAQ,yBACvCR,EAAAQ,yBAAA,CAAiCC,QAAQ,EAAG,CAC1CT,CAAAM,4BAAA,CAAoC,CAAA,CAEhCN,EAAAU,gBAAJ,EACEV,CAAAU,gBAAA,EAGEH,EAAJ,EACEA,CAAA7e,KAAA,CAAsCse,CAAtC,CARwC,CAFM,CAepDA,CAAAW,8BAAA,CAAsCC,QAAQ,EAAG,CAC/C,MAA6C,CAAA,CAA7C,GAAOZ,CAAAM,4BADwC,CAK3B,EAAtB,CAAKD,CAAL,GACED,CADF,CACa7Z,EAAA,CAAY6Z,CAAZ,CADb,CAIA,KAAS,IAAAne,EAAI,CAAb,CAAgBA,CAAhB,CAAoBoe,CAApB,CAAoCpe,CAAA,EAApC,CACO+d,CAAAW,8BAAA,EAAL,EACEP,CAAA,CAASne,CAAT,CAAAP,KAAA,CAAiBuD,CAAjB,CAA0B+a,CAA1B,CA5BJ,CATwC,CA4C1CD,EAAArS,KAAA,CAAoBzI,CACpB,OAAO8a,EA9CoC,CAiT7Cc,QAASA,GAAO,CAAChgB,CAAD,CAAMigB,CAAN,CAAiB,CAC/B,IAAIvf,EAAMV,CAANU,EAAaV,CAAA4B,UAEjB,IAAIlB,CAAJ,CAIE,MAHmB,UAGZA,GAHH,MAAOA,EAGJA,GAFLA,CAEKA,CAFCV,CAAA4B,UAAA,EAEDlB;AAAAA,CAGLwf,EAAAA,CAAU,MAAOlgB,EAOrB,OALEU,EAKF,CANe,UAAf,EAAIwf,CAAJ,EAAyC,QAAzC,EAA8BA,CAA9B,EAA6D,IAA7D,GAAqDlgB,CAArD,CACQA,CAAA4B,UADR,CACwBse,CADxB,CACkC,GADlC,CACwC,CAACD,CAAD,EAAcze,EAAd,GADxC,CAGQ0e,CAHR,CAGkB,GAHlB,CAGwBlgB,CAdO,CAuBjCmgB,QAASA,GAAO,CAAC5b,CAAD,CAAQ6b,CAAR,CAAqB,CACnC,GAAIA,CAAJ,CAAiB,CACf,IAAI3e,EAAM,CACV,KAAAD,QAAA,CAAe6e,QAAQ,EAAG,CACxB,MAAO,EAAE5e,CADe,CAFX,CAMjBlB,CAAA,CAAQgE,CAAR,CAAe,IAAA+b,IAAf,CAAyB,IAAzB,CAPmC,CAyGrCC,QAASA,GAAM,CAAC9Z,CAAD,CAAK,CAKlB,MAAA,CADI+Z,CACJ,CAFa/Z,CAAArD,SAAA,EAAA2E,QAAA0Y,CAAsBC,EAAtBD,CAAsC,EAAtCA,CACFpb,MAAA,CAAasb,EAAb,CACX,EACS,WADT,CACuB5Y,CAACyY,CAAA,CAAK,CAAL,CAADzY,EAAY,EAAZA,SAAA,CAAwB,WAAxB,CAAqC,GAArC,CADvB,CACmE,GADnE,CAGO,IARW,CAWpB6Y,QAASA,GAAQ,CAACna,CAAD,CAAKkD,CAAL,CAAeL,CAAf,CAAqB,CAAA,IAChCuX,CAKJ,IAAkB,UAAlB,GAAI,MAAOpa,EAAX,CACE,IAAM,EAAAoa,CAAA,CAAUpa,CAAAoa,QAAV,CAAN,CAA6B,CAC3BA,CAAA,CAAU,EACV,IAAIpa,CAAAvG,OAAJ,CAAe,CACb,GAAIyJ,CAAJ,CAIE,KAHKtJ,EAAA,CAASiJ,CAAT,CAGC,EAHkBA,CAGlB,GAFJA,CAEI,CAFG7C,CAAA6C,KAEH,EAFciX,EAAA,CAAO9Z,CAAP,CAEd,EAAA8H,EAAA,CAAgB,UAAhB,CACyEjF,CADzE,CAAN,CAGFmX,CAAA,CAASha,CAAArD,SAAA,EAAA2E,QAAA,CAAsB2Y,EAAtB,CAAsC,EAAtC,CACTI,EAAA,CAAUL,CAAApb,MAAA,CAAasb,EAAb,CACVpgB,EAAA,CAAQugB,CAAA,CAAQ,CAAR,CAAA5c,MAAA,CAAiB6c,EAAjB,CAAR;AAAwC,QAAQ,CAAC5T,CAAD,CAAM,CACpDA,CAAApF,QAAA,CAAYiZ,EAAZ,CAAoB,QAAQ,CAACC,CAAD,CAAMC,CAAN,CAAkB5X,CAAlB,CAAwB,CAClDuX,CAAA5f,KAAA,CAAaqI,CAAb,CADkD,CAApD,CADoD,CAAtD,CAVa,CAgBf7C,CAAAoa,QAAA,CAAaA,CAlBc,CAA7B,CADF,IAqBWvgB,EAAA,CAAQmG,CAAR,CAAJ,EACL0a,CAEA,CAFO1a,CAAAvG,OAEP,CAFmB,CAEnB,CADAmN,EAAA,CAAY5G,CAAA,CAAG0a,CAAH,CAAZ,CAAsB,IAAtB,CACA,CAAAN,CAAA,CAAUpa,CAAAH,MAAA,CAAS,CAAT,CAAY6a,CAAZ,CAHL,EAKL9T,EAAA,CAAY5G,CAAZ,CAAgB,IAAhB,CAAsB,CAAA,CAAtB,CAEF,OAAOoa,EAlC6B,CA+gBtCxW,QAASA,GAAc,CAAC+W,CAAD,CAAgBzX,CAAhB,CAA0B,CAoC/C0X,QAASA,EAAa,CAACC,CAAD,CAAW,CAC/B,MAAO,SAAQ,CAAC5gB,CAAD,CAAMa,CAAN,CAAa,CAC1B,GAAI0B,CAAA,CAASvC,CAAT,CAAJ,CACEH,CAAA,CAAQG,CAAR,CAAaW,EAAA,CAAcigB,CAAd,CAAb,CADF,KAGE,OAAOA,EAAA,CAAS5gB,CAAT,CAAca,CAAd,CAJiB,CADG,CAUjCqN,QAASA,EAAQ,CAACtF,CAAD,CAAOiY,CAAP,CAAkB,CACjC/T,EAAA,CAAwBlE,CAAxB,CAA8B,SAA9B,CACA,IAAI3I,CAAA,CAAW4gB,CAAX,CAAJ,EAA6BjhB,CAAA,CAAQihB,CAAR,CAA7B,CACEA,CAAA,CAAYC,CAAAC,YAAA,CAA6BF,CAA7B,CAEd,IAAKG,CAAAH,CAAAG,KAAL,CACE,KAAMnT,GAAA,CAAgB,MAAhB,CAA2EjF,CAA3E,CAAN,CAEF,MAAOqY,EAAA,CAAcrY,CAAd,CAnDYsY,UAmDZ,CAAP,CAA8CL,CARb,CAWnCM,QAASA,EAAkB,CAACvY,CAAD,CAAOgF,CAAP,CAAgB,CACzC,MAAOwT,SAA4B,EAAG,CACpC,IAAI7c,EAAS8c,CAAAzX,OAAA,CAAwBgE,CAAxB,CAAiC,IAAjC,CAAuCzO,CAAvC,CAAkDyJ,CAAlD,CACb,IAAIvG,CAAA,CAAYkC,CAAZ,CAAJ,CACE,KAAMsJ,GAAA,CAAgB,OAAhB,CAAyFjF,CAAzF,CAAN,CAEF,MAAOrE,EAL6B,CADG,CAU3CqJ,QAASA,EAAO,CAAChF,CAAD,CAAO0Y,CAAP,CAAkBC,CAAlB,CAA2B,CACzC,MAAOrT,EAAA,CAAStF,CAAT,CAAe,CACpBoY,KAAkB,CAAA,CAAZ,GAAAO,CAAA,CAAoBJ,CAAA,CAAmBvY,CAAnB;AAAyB0Y,CAAzB,CAApB,CAA0DA,CAD5C,CAAf,CADkC,CAiC3CE,QAASA,EAAW,CAACd,CAAD,CAAe,CAAA,IAC7BjS,EAAY,EADiB,CACbgT,CACpB5hB,EAAA,CAAQ6gB,CAAR,CAAuB,QAAQ,CAACjY,CAAD,CAAS,CAItCiZ,QAASA,EAAc,CAACrT,CAAD,CAAQ,CAAA,IACzB3N,CADyB,CACtBW,CACHX,EAAA,CAAI,CAAR,KAAWW,CAAX,CAAgBgN,CAAA7O,OAAhB,CAA8BkB,CAA9B,CAAkCW,CAAlC,CAAsCX,CAAA,EAAtC,CAA2C,CAAA,IACrCihB,EAAatT,CAAA,CAAM3N,CAAN,CADwB,CAErCwN,EAAW4S,CAAAhW,IAAA,CAAqB6W,CAAA,CAAW,CAAX,CAArB,CAEfzT,EAAA,CAASyT,CAAA,CAAW,CAAX,CAAT,CAAAzb,MAAA,CAA8BgI,CAA9B,CAAwCyT,CAAA,CAAW,CAAX,CAAxC,CAJyC,CAFd,CAH/B,GAAI,CAAAC,CAAA9W,IAAA,CAAkBrC,CAAlB,CAAJ,CAAA,CACAmZ,CAAAhC,IAAA,CAAkBnX,CAAlB,CAA0B,CAAA,CAA1B,CAYA,IAAI,CACE9I,CAAA,CAAS8I,CAAT,CAAJ,EACEgZ,CAGA,CAHWhS,EAAA,CAAchH,CAAd,CAGX,CAFAgG,CAEA,CAFYA,CAAAhJ,OAAA,CAAiB+b,CAAA,CAAYC,CAAA1T,SAAZ,CAAjB,CAAAtI,OAAA,CAAwDgc,CAAA7S,WAAxD,CAEZ,CADA8S,CAAA,CAAeD,CAAA/S,aAAf,CACA,CAAAgT,CAAA,CAAeD,CAAA9S,cAAf,CAJF,EAKW1O,CAAA,CAAWwI,CAAX,CAAJ,CACHgG,CAAAlO,KAAA,CAAeugB,CAAAlX,OAAA,CAAwBnB,CAAxB,CAAf,CADG,CAEI7I,CAAA,CAAQ6I,CAAR,CAAJ,CACHgG,CAAAlO,KAAA,CAAeugB,CAAAlX,OAAA,CAAwBnB,CAAxB,CAAf,CADG,CAGLkE,EAAA,CAAYlE,CAAZ,CAAoB,QAApB,CAXA,CAaF,MAAOzB,CAAP,CAAU,CAYV,KAXIpH,EAAA,CAAQ6I,CAAR,CAWE,GAVJA,CAUI,CAVKA,CAAA,CAAOA,CAAAjJ,OAAP,CAAuB,CAAvB,CAUL,EARFwH,CAAA6a,QAQE,EARW7a,CAAA8a,MAQX,EARqD,EAQrD,EARsB9a,CAAA8a,MAAA/d,QAAA,CAAgBiD,CAAA6a,QAAhB,CAQtB,GAFJ7a,CAEI,CAFAA,CAAA6a,QAEA,CAFY,IAEZ,CAFmB7a,CAAA8a,MAEnB,EAAAjU,EAAA,CAAgB,UAAhB,CACIpF,CADJ,CACYzB,CAAA8a,MADZ,EACuB9a,CAAA6a,QADvB,EACoC7a,CADpC,CAAN,CAZU,CA1BZ,CADsC,CAAxC,CA2CA;MAAOyH,EA7C0B,CAoDnCsT,QAASA,EAAsB,CAACC,CAAD,CAAQpU,CAAR,CAAiB,CAE9CqU,QAASA,EAAU,CAACC,CAAD,CAAc,CAC/B,GAAIF,CAAA9hB,eAAA,CAAqBgiB,CAArB,CAAJ,CAAuC,CACrC,GAAIF,CAAA,CAAME,CAAN,CAAJ,GAA2BC,CAA3B,CACE,KAAMtU,GAAA,CAAgB,MAAhB,CACIqU,CADJ,CACkB,MADlB,CAC2BlV,CAAAjF,KAAA,CAAU,MAAV,CAD3B,CAAN,CAGF,MAAOia,EAAA,CAAME,CAAN,CAL8B,CAOrC,GAAI,CAGF,MAFAlV,EAAAzD,QAAA,CAAa2Y,CAAb,CAEO,CADPF,CAAA,CAAME,CAAN,CACO,CADcC,CACd,CAAAH,CAAA,CAAME,CAAN,CAAA,CAAqBtU,CAAA,CAAQsU,CAAR,CAH1B,CAIF,MAAOE,CAAP,CAAY,CAIZ,KAHIJ,EAAA,CAAME,CAAN,CAGEE,GAHqBD,CAGrBC,EAFJ,OAAOJ,CAAA,CAAME,CAAN,CAEHE,CAAAA,CAAN,CAJY,CAJd,OASU,CACRpV,CAAAqV,MAAA,EADQ,CAjBmB,CAuBjCzY,QAASA,EAAM,CAAC7D,CAAD,CAAKD,CAAL,CAAWwc,CAAX,CAAmBJ,CAAnB,CAAgC,CACvB,QAAtB,GAAI,MAAOI,EAAX,GACEJ,CACA,CADcI,CACd,CAAAA,CAAA,CAAS,IAFX,CAD6C,KAMzCxC,EAAO,EACPK,EAAAA,CAAUD,EAAA,CAASna,CAAT,CAAakD,CAAb,CAAuBiZ,CAAvB,CAP+B,KAQzC1iB,CARyC,CAQjCkB,CARiC,CASzCV,CAEAU,EAAA,CAAI,CAAR,KAAWlB,CAAX,CAAoB2gB,CAAA3gB,OAApB,CAAoCkB,CAApC,CAAwClB,CAAxC,CAAgDkB,CAAA,EAAhD,CAAqD,CACnDV,CAAA,CAAMmgB,CAAA,CAAQzf,CAAR,CACN,IAAmB,QAAnB,GAAI,MAAOV,EAAX,CACE,KAAM6N,GAAA,CAAgB,MAAhB,CACyE7N,CADzE,CAAN,CAGF8f,CAAAvf,KAAA,CACE+hB,CAAA,EAAUA,CAAApiB,eAAA,CAAsBF,CAAtB,CAAV,CACEsiB,CAAA,CAAOtiB,CAAP,CADF,CAEEiiB,CAAA,CAAWjiB,CAAX,CAHJ,CANmD,CAYjDJ,CAAA,CAAQmG,CAAR,CAAJ,GACEA,CADF,CACOA,CAAA,CAAGvG,CAAH,CADP,CAMA,OAAOuG,EAAAG,MAAA,CAASJ,CAAT,CAAega,CAAf,CA7BsC,CA6C/C,MAAO,CACLlW,OAAQA,CADH,CAELmX,YAfFA,QAAoB,CAACwB,CAAD;AAAOD,CAAP,CAAeJ,CAAf,CAA4B,CAAA,IAC1CM,EAAcA,QAAQ,EAAG,EAK7BA,EAAAxgB,UAAA,CAAwBA,CAACpC,CAAA,CAAQ2iB,CAAR,CAAA,CAAgBA,CAAA,CAAKA,CAAA/iB,OAAL,CAAmB,CAAnB,CAAhB,CAAwC+iB,CAAzCvgB,WACxBygB,EAAA,CAAW,IAAID,CACfE,EAAA,CAAgB9Y,CAAA,CAAO2Y,CAAP,CAAaE,CAAb,CAAuBH,CAAvB,CAA+BJ,CAA/B,CAEhB,OAAO3f,EAAA,CAASmgB,CAAT,CAAA,EAA2BziB,CAAA,CAAWyiB,CAAX,CAA3B,CAAuDA,CAAvD,CAAuED,CAVhC,CAazC,CAGL3X,IAAKmX,CAHA,CAIL/B,SAAUA,EAJL,CAKLyC,IAAKA,QAAQ,CAAC/Z,CAAD,CAAO,CAClB,MAAOqY,EAAA/gB,eAAA,CAA6B0I,CAA7B,CAjOQsY,UAiOR,CAAP,EAA8Dc,CAAA9hB,eAAA,CAAqB0I,CAArB,CAD5C,CALf,CAtEuC,CAvJhDK,CAAA,CAAyB,CAAA,CAAzB,GAAYA,CADmC,KAE3CkZ,EAAgB,EAF2B,CAI3CnV,EAAO,EAJoC,CAK3C4U,EAAgB,IAAInC,EAAJ,CAAY,EAAZ,CAAgB,CAAA,CAAhB,CAL2B,CAM3CwB,EAAgB,CACdzX,SAAU,CACN0E,SAAUyS,CAAA,CAAczS,CAAd,CADJ,CAENN,QAAS+S,CAAA,CAAc/S,CAAd,CAFH,CAGNiB,QAAS8R,CAAA,CA+DnB9R,QAAgB,CAACjG,CAAD,CAAOiE,CAAP,CAAoB,CAClC,MAAOe,EAAA,CAAQhF,CAAR,CAAc,CAAC,WAAD,CAAc,QAAQ,CAACga,CAAD,CAAY,CACrD,MAAOA,EAAA7B,YAAA,CAAsBlU,CAAtB,CAD8C,CAAlC,CAAd,CAD2B,CA/DjB,CAHH,CAINhM,MAAO8f,CAAA,CAoEjB9f,QAAc,CAAC+H,CAAD,CAAOxC,CAAP,CAAY,CAAE,MAAOwH,EAAA,CAAQhF,CAAR,CAAcxG,EAAA,CAAQgE,CAAR,CAAd,CAA4B,CAAA,CAA5B,CAAT,CApET,CAJD,CAKN0I,SAAU6R,CAAA,CAqEpB7R,QAAiB,CAAClG,CAAD,CAAO/H,CAAP,CAAc,CAC7BiM,EAAA,CAAwBlE,CAAxB,CAA8B,UAA9B,CACAqY,EAAA,CAAcrY,CAAd,CAAA,CAAsB/H,CACtBgiB,EAAA,CAAcja,CAAd,CAAA,CAAsB/H,CAHO,CArEX,CALJ,CAMNiiB,UA0EVA,QAAkB,CAACZ,CAAD,CAAca,CAAd,CAAuB,CAAA,IACnCC;AAAelC,CAAAhW,IAAA,CAAqBoX,CAArB,CArFAhB,UAqFA,CADoB,CAEnC+B,EAAWD,CAAAhC,KAEfgC,EAAAhC,KAAA,CAAoBkC,QAAQ,EAAG,CAC7B,IAAIC,EAAe9B,CAAAzX,OAAA,CAAwBqZ,CAAxB,CAAkCD,CAAlC,CACnB,OAAO3B,EAAAzX,OAAA,CAAwBmZ,CAAxB,CAAiC,IAAjC,CAAuC,CAACK,UAAWD,CAAZ,CAAvC,CAFsB,CAJQ,CAhFzB,CADI,CAN2B,CAgB3CrC,EAAoBG,CAAA2B,UAApB9B,CACIiB,CAAA,CAAuBd,CAAvB,CAAsC,QAAQ,EAAG,CAC/C,KAAMpT,GAAA,CAAgB,MAAhB,CAAiDb,CAAAjF,KAAA,CAAU,MAAV,CAAjD,CAAN,CAD+C,CAAjD,CAjBuC,CAoB3C8a,EAAgB,EApB2B,CAqB3CxB,EAAoBwB,CAAAD,UAApBvB,CACIU,CAAA,CAAuBc,CAAvB,CAAsC,QAAQ,CAACQ,CAAD,CAAc,CAC1D,IAAInV,EAAW4S,CAAAhW,IAAA,CAAqBuY,CAArB,CApBJnC,UAoBI,CACf,OAAOG,EAAAzX,OAAA,CAAwBsE,CAAA8S,KAAxB,CAAuC9S,CAAvC,CAAiD/O,CAAjD,CAA4DkkB,CAA5D,CAFmD,CAA5D,CAMRxjB,EAAA,CAAQ2hB,CAAA,CAAYd,CAAZ,CAAR,CAAoC,QAAQ,CAAC3a,CAAD,CAAK,CAAEsb,CAAAzX,OAAA,CAAwB7D,CAAxB,EAA8B9D,CAA9B,CAAF,CAAjD,CAEA,OAAOof,EA9BwC,CAoPjD/L,QAASA,GAAqB,EAAG,CAE/B,IAAIgO,EAAuB,CAAA,CAe3B,KAAAC,qBAAA,CAA4BC,QAAQ,EAAG,CACrCF,CAAA,CAAuB,CAAA,CADc,CA6IvC,KAAAtC,KAAA,CAAY,CAAC,SAAD,CAAY,WAAZ,CAAyB,YAAzB,CAAuC,QAAQ,CAACzI,CAAD,CAAU1B,CAAV,CAAqBM,CAArB,CAAiC,CAO1FsM,QAASA,EAAc,CAACC,CAAD,CAAO,CAC5B,IAAInf,EAAS,IACbof,MAAA3hB,UAAA4hB,KAAAzjB,KAAA,CAA0BujB,CAA1B,CAAgC,QAAQ,CAAChgB,CAAD,CAAU,CAChD,GAA2B,GAA3B;AAAID,EAAA,CAAUC,CAAV,CAAJ,CAEE,MADAa,EACO,CADEb,CACF,CAAA,CAAA,CAHuC,CAAlD,CAMA,OAAOa,EARqB,CAgC9Bsf,QAASA,EAAQ,CAAC1X,CAAD,CAAO,CACtB,GAAIA,CAAJ,CAAU,CACRA,CAAA2X,eAAA,EAEA,KAAI9K,CAvBFA,EAAAA,CAAS+K,CAAAC,QAET/jB,EAAA,CAAW+Y,CAAX,CAAJ,CACEA,CADF,CACWA,CAAA,EADX,CAEWhW,EAAA,CAAUgW,CAAV,CAAJ,EACD7M,CAGF,CAHS6M,CAAA,CAAO,CAAP,CAGT,CAAAA,CAAA,CADqB,OAAvB,GADYT,CAAA0L,iBAAAvT,CAAyBvE,CAAzBuE,CACRwT,SAAJ,CACW,CADX,CAGW/X,CAAAgY,sBAAA,EAAAC,OANN,EAQK5hB,CAAA,CAASwW,CAAT,CARL,GASLA,CATK,CASI,CATJ,CAqBDA,EAAJ,GAcMqL,CACJ,CADclY,CAAAgY,sBAAA,EAAAG,IACd,CAAA/L,CAAAgM,SAAA,CAAiB,CAAjB,CAAoBF,CAApB,CAA8BrL,CAA9B,CAfF,CALQ,CAAV,IAuBET,EAAAsL,SAAA,CAAiB,CAAjB,CAAoB,CAApB,CAxBoB,CA4BxBE,QAASA,EAAM,EAAG,CAAA,IACZS,EAAO3N,CAAA2N,KAAA,EADK,CACaC,CAGxBD,EAAL,CAGK,CAAKC,CAAL,CAAWvlB,CAAAwlB,eAAA,CAAwBF,CAAxB,CAAX,EAA2CX,CAAA,CAASY,CAAT,CAA3C,CAGA,CAAKA,CAAL,CAAWhB,CAAA,CAAevkB,CAAAylB,kBAAA,CAA2BH,CAA3B,CAAf,CAAX,EAA8DX,CAAA,CAASY,CAAT,CAA9D,CAGa,KAHb,GAGID,CAHJ,EAGoBX,CAAA,CAAS,IAAT,CATzB,CAAWA,CAAA,CAAS,IAAT,CAJK,CAlElB,IAAI3kB,EAAWqZ,CAAArZ,SAoFXokB,EAAJ,EACEnM,CAAArU,OAAA,CAAkB8hB,QAAwB,EAAG,CAAC,MAAO/N,EAAA2N,KAAA,EAAR,CAA7C,CACEK,QAA8B,CAACC,CAAD,CAASC,CAAT,CAAiB,CAEzCD,CAAJ,GAAeC,CAAf,EAAoC,EAApC,GAAyBD,CAAzB,EAEAlH,EAAA,CAAqB,QAAQ,EAAG,CAC9BzG,CAAAtU,WAAA,CAAsBkhB,CAAtB,CAD8B,CAAhC,CAJ6C,CADjD,CAWF;MAAOA,EAjGmF,CAAhF,CA9JmB,CAqnBjCnL,QAASA,GAAuB,EAAE,CAChC,IAAAoI,KAAA,CAAY,CAAC,OAAD,CAAU,UAAV,CAAsB,QAAQ,CAACvI,CAAD,CAAQJ,CAAR,CAAkB,CAC1D,MAAOI,EAAAuM,UAAA,CACH,QAAQ,CAACjf,CAAD,CAAK,CAAE,MAAO0S,EAAA,CAAM1S,CAAN,CAAT,CADV,CAEH,QAAQ,CAACA,CAAD,CAAK,CACb,MAAOsS,EAAA,CAAStS,CAAT,CAAa,CAAb,CAAgB,CAAA,CAAhB,CADM,CAHyC,CAAhD,CADoB,CAkClCkf,QAASA,GAAO,CAAChmB,CAAD,CAASC,CAAT,CAAmB6X,CAAnB,CAAyBc,CAAzB,CAAmC,CAsBjDqN,QAASA,EAA0B,CAACnf,CAAD,CAAK,CACtC,GAAI,CACFA,CAAAG,MAAA,CAAS,IAAT,CA5xHGN,EAAAzF,KAAA,CA4xHsBmB,SA5xHtB,CA4xHiC2E,CA5xHjC,CA4xHH,CADE,CAAJ,OAEU,CAER,GADAkf,CAAA,EACI,CAA4B,CAA5B,GAAAA,CAAJ,CACE,IAAA,CAAMC,CAAA5lB,OAAN,CAAA,CACE,GAAI,CACF4lB,CAAAC,IAAA,EAAA,EADE,CAEF,MAAOre,CAAP,CAAU,CACV+P,CAAAuO,MAAA,CAAWte,CAAX,CADU,CANR,CAH4B,CAmExCue,QAASA,EAAW,CAACC,CAAD,CAAWxH,CAAX,CAAuB,CACxCyH,SAASA,GAAK,EAAG,CAChB5lB,CAAA,CAAQ6lB,CAAR,CAAiB,QAAQ,CAACC,CAAD,CAAQ,CAAEA,CAAA,EAAF,CAAjC,CACAC,EAAA,CAAc5H,CAAA,CAAWyH,EAAX,CAAkBD,CAAlB,CAFE,CAAjBC,CAAD,EADyC,CA8G3CI,QAASA,EAA0B,EAAG,CACpCC,CAAA,EACAC,EAAA,EAFoC,CAOtCD,QAASA,EAAU,EAAG,CAEpBE,CAAA,CAAc/mB,CAAAgnB,QAAAC,MACdF,EAAA,CAAc3jB,CAAA,CAAY2jB,CAAZ,CAAA,CAA2B,IAA3B,CAAkCA,CAG5C7gB,GAAA,CAAO6gB,CAAP,CAAoBG,CAApB,CAAJ,GACEH,CADF,CACgBG,CADhB,CAGAA,EAAA,CAAkBH,CATE,CAYtBD,QAASA,EAAa,EAAG,CACvB,GAAIK,CAAJ,GAAuBtgB,CAAAugB,IAAA,EAAvB,EAAqCC,CAArC,GAA0DN,CAA1D,CAIAI,CAEA,CAFiBtgB,CAAAugB,IAAA,EAEjB,CADAC,CACA,CADmBN,CACnB,CAAAnmB,CAAA,CAAQ0mB,CAAR,CAA4B,QAAQ,CAACC,CAAD,CAAW,CAC7CA,CAAA,CAAS1gB,CAAAugB,IAAA,EAAT;AAAqBL,CAArB,CAD6C,CAA/C,CAPuB,CAoFzBS,QAASA,EAAsB,CAAC9kB,CAAD,CAAM,CACnC,GAAI,CACF,MAAO4F,mBAAA,CAAmB5F,CAAnB,CADL,CAEF,MAAOqF,CAAP,CAAU,CACV,MAAOrF,EADG,CAHuB,CA9SY,IAC7CmE,EAAO,IADsC,CAE7C4gB,EAAcxnB,CAAA,CAAS,CAAT,CAF+B,CAG7CwL,EAAWzL,CAAAyL,SAHkC,CAI7Cub,EAAUhnB,CAAAgnB,QAJmC,CAK7CjI,EAAa/e,CAAA+e,WALgC,CAM7C2I,EAAe1nB,CAAA0nB,aAN8B,CAO7CC,EAAkB,EAEtB9gB,EAAA+gB,OAAA,CAAc,CAAA,CAEd,KAAI1B,EAA0B,CAA9B,CACIC,EAA8B,EAGlCtf,EAAAghB,6BAAA,CAAoC5B,CACpCpf,EAAAihB,6BAAA,CAAoCC,QAAQ,EAAG,CAAE7B,CAAA,EAAF,CA6B/Crf,EAAAmhB,gCAAA,CAAuCC,QAAQ,CAACC,CAAD,CAAW,CAIxDtnB,CAAA,CAAQ6lB,CAAR,CAAiB,QAAQ,CAACC,CAAD,CAAQ,CAAEA,CAAA,EAAF,CAAjC,CAEgC,EAAhC,GAAIR,CAAJ,CACEgC,CAAA,EADF,CAGE/B,CAAA7kB,KAAA,CAAiC4mB,CAAjC,CATsD,CA7CT,KA6D7CzB,EAAU,EA7DmC,CA8D7CE,CAaJ9f,EAAAshB,UAAA,CAAiBC,QAAQ,CAACthB,CAAD,CAAK,CACxB1D,CAAA,CAAYujB,CAAZ,CAAJ,EAA8BL,CAAA,CAAY,GAAZ,CAAiBvH,CAAjB,CAC9B0H,EAAAnlB,KAAA,CAAawF,CAAb,CACA,OAAOA,EAHqB,CA3EmB,KAoG7CigB,CApG6C,CAoGhCM,CApGgC,CAqG7CF,EAAiB1b,CAAA4c,KArG4B,CAsG7CC,EAAcroB,CAAAmE,KAAA,CAAc,MAAd,CAtG+B,CAuG7CmkB,GAAiB,IAErB1B,EAAA,EACAQ,EAAA,CAAmBN,CAsBnBlgB,EAAAugB,IAAA,CAAWoB,QAAQ,CAACpB,CAAD,CAAMhf,CAAN,CAAe6e,CAAf,CAAsB,CAInC7jB,CAAA,CAAY6jB,CAAZ,CAAJ,GACEA,CADF,CACU,IADV,CAKIxb;CAAJ,GAAiBzL,CAAAyL,SAAjB,GAAkCA,CAAlC,CAA6CzL,CAAAyL,SAA7C,CACIub,EAAJ,GAAgBhnB,CAAAgnB,QAAhB,GAAgCA,CAAhC,CAA0ChnB,CAAAgnB,QAA1C,CAGA,IAAII,CAAJ,CAAS,CACP,IAAIqB,EAAYpB,CAAZoB,GAAiCxB,CAKrC,IAAIE,CAAJ,GAAuBC,CAAvB,EAAgCxO,CAAAoO,QAAhC,EAAoDyB,CAAAA,CAApD,CAAA,CAGA,IAAIC,EAAWvB,CAAXuB,EAA6BC,EAAA,CAAUxB,CAAV,CAA7BuB,GAA2DC,EAAA,CAAUvB,CAAV,CAC/DD,EAAA,CAAiBC,CACjBC,EAAA,CAAmBJ,CAKfD,EAAApO,CAAAoO,QAAJ,EAA0B0B,CAA1B,EAAuCD,CAAvC,EAMOC,CAGL,GAFEH,EAEF,CAFmBnB,CAEnB,EAAIhf,CAAJ,CACEqD,CAAArD,QAAA,CAAiBgf,CAAjB,CADF,CAGE3b,CAAA4c,KAHF,CAGkBjB,CAZpB,GACEJ,CAAA,CAAQ5e,CAAA,CAAU,cAAV,CAA2B,WAAnC,CAAA,CAAgD6e,CAAhD,CAAuD,EAAvD,CAA2DG,CAA3D,CAGA,CAFAP,CAAA,EAEA,CAAAQ,CAAA,CAAmBN,CAJrB,CAeA,OAAOlgB,EAzBP,CANO,CAAT,IAqCE,OAAO0hB,GAAP,EAAyB9c,CAAA4c,KAAAjgB,QAAA,CAAsB,MAAtB,CAA6B,GAA7B,CAlDY,CAgEzCvB,EAAAogB,MAAA,CAAa2B,QAAQ,EAAG,CACtB,MAAO7B,EADe,CAhMyB,KAoM7CO,EAAqB,EApMwB,CAqM7CuB,EAAgB,CAAA,CArM6B,CA6M7C3B,EAAkB,IA8CtBrgB,EAAAiiB,YAAA,CAAmBC,QAAQ,CAACb,CAAD,CAAW,CAEpC,GAAKW,CAAAA,CAAL,CAAoB,CAMlB,GAAIjQ,CAAAoO,QAAJ,CAAsBpf,CAAA,CAAO5H,CAAP,CAAAwM,GAAA,CAAkB,UAAlB,CAA8Boa,CAA9B,CAEtBhf,EAAA,CAAO5H,CAAP,CAAAwM,GAAA,CAAkB,YAAlB,CAAgCoa,CAAhC,CAEAiC,EAAA,CAAgB,CAAA,CAVE,CAapBvB,CAAAhmB,KAAA,CAAwB4mB,CAAxB,CACA,OAAOA,EAhB6B,CAwBtCrhB,EAAAmiB,iBAAA,CAAwBlC,CAexBjgB,EAAAoiB,SAAA,CAAgBC,QAAQ,EAAG,CACzB,IAAIb;AAAOC,CAAAnkB,KAAA,CAAiB,MAAjB,CACX,OAAOkkB,EAAA,CAAOA,CAAAjgB,QAAA,CAAa,wBAAb,CAAuC,EAAvC,CAAP,CAAoD,EAFlC,CAQ3B,KAAI+gB,GAAc,EAAlB,CACIC,GAAmB,EADvB,CAEIC,GAAaxiB,CAAAoiB,SAAA,EA8BjBpiB,EAAAyiB,QAAA,CAAeC,QAAQ,CAAC5f,CAAD,CAAO/H,CAAP,CAAc,CAAA,IAC/B4nB,CAD+B,CACJC,CADI,CACIhoB,CADJ,CACOoD,CAE1C,IAAI8E,CAAJ,CACM/H,CAAJ,GAAc1B,CAAd,CACEunB,CAAAgC,OADF,CACuBxgB,kBAAA,CAAmBU,CAAnB,CADvB,CACkD,SADlD,CAC8D0f,EAD9D,CAE0B,wCAF1B,CAIM3oB,CAAA,CAASkB,CAAT,CAJN,GAKI4nB,CAOA,CAPejpB,CAACknB,CAAAgC,OAADlpB,CAAsB0I,kBAAA,CAAmBU,CAAnB,CAAtBpJ,CAAiD,GAAjDA,CAAuD0I,kBAAA,CAAmBrH,CAAnB,CAAvDrB,CACO,QADPA,CACkB8oB,EADlB9oB,QAOf,CANsD,CAMtD,CAAmB,IAAnB,CAAIipB,CAAJ,EACE1R,CAAA4R,KAAA,CAAU,UAAV,CAAsB/f,CAAtB,CACE,6DADF,CAEE6f,CAFF,CAEiB,iBAFjB,CAbN,CADF,KAoBO,CACL,GAAI/B,CAAAgC,OAAJ,GAA2BL,EAA3B,CAKE,IAJAA,EAIK,CAJc3B,CAAAgC,OAId,CAHLE,CAGK,CAHSP,EAAA7kB,MAAA,CAAuB,IAAvB,CAGT,CAFL4kB,EAEK,CAFS,EAET,CAAA1nB,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgBkoB,CAAAppB,OAAhB,CAAoCkB,CAAA,EAApC,CACEgoB,CAEA;AAFSE,CAAA,CAAYloB,CAAZ,CAET,CADAoD,CACA,CADQ4kB,CAAA3kB,QAAA,CAAe,GAAf,CACR,CAAY,CAAZ,CAAID,CAAJ,GACE8E,CAIA,CAJO6d,CAAA,CAAuBiC,CAAAG,UAAA,CAAiB,CAAjB,CAAoB/kB,CAApB,CAAvB,CAIP,CAAIskB,EAAA,CAAYxf,CAAZ,CAAJ,GAA0BzJ,CAA1B,GACEipB,EAAA,CAAYxf,CAAZ,CADF,CACsB6d,CAAA,CAAuBiC,CAAAG,UAAA,CAAiB/kB,CAAjB,CAAyB,CAAzB,CAAvB,CADtB,CALF,CAWJ,OAAOskB,GApBF,CAvB4B,CA8DrCtiB,EAAAgjB,MAAA,CAAaC,QAAQ,CAAChjB,CAAD,CAAKijB,CAAL,CAAY,CAC/B,IAAIC,CACJ9D,EAAA,EACA8D,EAAA,CAAYjL,CAAA,CAAW,QAAQ,EAAG,CAChC,OAAO4I,CAAA,CAAgBqC,CAAhB,CACP/D,EAAA,CAA2Bnf,CAA3B,CAFgC,CAAtB,CAGTijB,CAHS,EAGA,CAHA,CAIZpC,EAAA,CAAgBqC,CAAhB,CAAA,CAA6B,CAAA,CAC7B,OAAOA,EARwB,CAsBjCnjB,EAAAgjB,MAAAI,OAAA,CAAoBC,QAAQ,CAACC,CAAD,CAAU,CACpC,MAAIxC,EAAA,CAAgBwC,CAAhB,CAAJ,EACE,OAAOxC,CAAA,CAAgBwC,CAAhB,CAGA,CAFPzC,CAAA,CAAayC,CAAb,CAEO,CADPlE,CAAA,CAA2BjjB,CAA3B,CACO,CAAA,CAAA,CAJT,EAMO,CAAA,CAP6B,CA9ZW,CA0anDyT,QAASA,GAAgB,EAAE,CACzB,IAAAsL,KAAA,CAAY,CAAC,SAAD,CAAY,MAAZ,CAAoB,UAApB,CAAgC,WAAhC,CACR,QAAQ,CAAEzI,CAAF,CAAaxB,CAAb,CAAqBc,CAArB,CAAiC9B,CAAjC,CAA2C,CACjD,MAAO,KAAIkP,EAAJ,CAAY1M,CAAZ,CAAqBxC,CAArB,CAAgCgB,CAAhC,CAAsCc,CAAtC,CAD0C,CAD3C,CADa,CAwF3BjC,QAASA,GAAqB,EAAG,CAE/B,IAAAoL,KAAA,CAAYqI,QAAQ,EAAG,CAGrBC,QAASA,EAAY,CAACC,CAAD,CAAUC,CAAV,CAAmB,CAwMtCC,QAASA,EAAO,CAACC,CAAD,CAAQ,CAClBA,CAAJ,EAAaC,CAAb,GACOC,CAAL,CAEWA,CAFX,EAEuBF,CAFvB,GAGEE,CAHF,CAGaF,CAAAG,EAHb,EACED,CADF,CACaF,CAQb,CAHAI,CAAA,CAAKJ,CAAAG,EAAL,CAAcH,CAAAK,EAAd,CAGA,CAFAD,CAAA,CAAKJ,CAAL,CAAYC,CAAZ,CAEA,CADAA,CACA,CADWD,CACX,CAAAC,CAAAE,EAAA,CAAa,IAVf,CADsB,CAmBxBC,QAASA,EAAI,CAACE,CAAD;AAAYC,CAAZ,CAAuB,CAC9BD,CAAJ,EAAiBC,CAAjB,GACMD,CACJ,GADeA,CAAAD,EACf,CAD6BE,CAC7B,EAAIA,CAAJ,GAAeA,CAAAJ,EAAf,CAA6BG,CAA7B,CAFF,CADkC,CA1NpC,GAAIT,CAAJ,GAAeW,EAAf,CACE,KAAM9qB,EAAA,CAAO,eAAP,CAAA,CAAwB,KAAxB,CAAkEmqB,CAAlE,CAAN,CAFoC,IAKlCY,EAAO,CAL2B,CAMlCC,EAAQjpB,CAAA,CAAO,EAAP,CAAWqoB,CAAX,CAAoB,CAACa,GAAId,CAAL,CAApB,CAN0B,CAOlCtf,EAAO,EAP2B,CAQlCqgB,EAAYd,CAAZc,EAAuBd,CAAAc,SAAvBA,EAA4CC,MAAAC,UARV,CASlCC,EAAU,EATwB,CAUlCd,EAAW,IAVuB,CAWlCC,EAAW,IAyCf,OAAOM,EAAA,CAAOX,CAAP,CAAP,CAAyB,CAoBvB3J,IAAKA,QAAQ,CAAC5f,CAAD,CAAMa,CAAN,CAAa,CACxB,GAAIypB,CAAJ,CAAeC,MAAAC,UAAf,CAAiC,CAC/B,IAAIE,EAAWD,CAAA,CAAQzqB,CAAR,CAAX0qB,GAA4BD,CAAA,CAAQzqB,CAAR,CAA5B0qB,CAA2C,CAAC1qB,IAAKA,CAAN,CAA3C0qB,CAEJjB,EAAA,CAAQiB,CAAR,CAH+B,CAMjC,GAAI,CAAAroB,CAAA,CAAYxB,CAAZ,CAAJ,CAQA,MAPMb,EAOCa,GAPMoJ,EAONpJ,EAPaspB,CAAA,EAObtpB,CANPoJ,CAAA,CAAKjK,CAAL,CAMOa,CANKA,CAMLA,CAJHspB,CAIGtpB,CAJIypB,CAIJzpB,EAHL,IAAA8pB,OAAA,CAAYf,CAAA5pB,IAAZ,CAGKa,CAAAA,CAfiB,CApBH,CAiDvBiK,IAAKA,QAAQ,CAAC9K,CAAD,CAAM,CACjB,GAAIsqB,CAAJ,CAAeC,MAAAC,UAAf,CAAiC,CAC/B,IAAIE,EAAWD,CAAA,CAAQzqB,CAAR,CAEf,IAAK0qB,CAAAA,CAAL,CAAe,MAEfjB,EAAA,CAAQiB,CAAR,CAL+B,CAQjC,MAAOzgB,EAAA,CAAKjK,CAAL,CATU,CAjDI,CAwEvB2qB,OAAQA,QAAQ,CAAC3qB,CAAD,CAAM,CACpB,GAAIsqB,CAAJ,CAAeC,MAAAC,UAAf,CAAiC,CAC/B,IAAIE,EAAWD,CAAA,CAAQzqB,CAAR,CAEf,IAAK0qB,CAAAA,CAAL,CAAe,MAEXA,EAAJ,EAAgBf,CAAhB,GAA0BA,CAA1B,CAAqCe,CAAAX,EAArC,CACIW,EAAJ,EAAgBd,CAAhB,GAA0BA,CAA1B,CAAqCc,CAAAb,EAArC,CACAC,EAAA,CAAKY,CAAAb,EAAL,CAAgBa,CAAAX,EAAhB,CAEA,QAAOU,CAAA,CAAQzqB,CAAR,CATwB,CAYjC,OAAOiK,CAAA,CAAKjK,CAAL,CACPmqB;CAAA,EAdoB,CAxEC,CAkGvBS,UAAWA,QAAQ,EAAG,CACpB3gB,CAAA,CAAO,EACPkgB,EAAA,CAAO,CACPM,EAAA,CAAU,EACVd,EAAA,CAAWC,CAAX,CAAsB,IAJF,CAlGC,CAmHvBiB,QAASA,QAAQ,EAAG,CAGlBJ,CAAA,CADAL,CACA,CAFAngB,CAEA,CAFO,IAGP,QAAOigB,CAAA,CAAOX,CAAP,CAJW,CAnHG,CA2IvBuB,KAAMA,QAAQ,EAAG,CACf,MAAO3pB,EAAA,CAAO,EAAP,CAAWipB,CAAX,CAAkB,CAACD,KAAMA,CAAP,CAAlB,CADQ,CA3IM,CApDa,CAFxC,IAAID,EAAS,EA+ObZ,EAAAwB,KAAA,CAAoBC,QAAQ,EAAG,CAC7B,IAAID,EAAO,EACXjrB,EAAA,CAAQqqB,CAAR,CAAgB,QAAQ,CAAClI,CAAD,CAAQuH,CAAR,CAAiB,CACvCuB,CAAA,CAAKvB,CAAL,CAAA,CAAgBvH,CAAA8I,KAAA,EADuB,CAAzC,CAGA,OAAOA,EALsB,CAmB/BxB,EAAAxe,IAAA,CAAmBkgB,QAAQ,CAACzB,CAAD,CAAU,CACnC,MAAOW,EAAA,CAAOX,CAAP,CAD4B,CAKrC,OAAOD,EAxQc,CAFQ,CAwTjCtR,QAASA,GAAsB,EAAG,CAChC,IAAAgJ,KAAA,CAAY,CAAC,eAAD,CAAkB,QAAQ,CAACrL,CAAD,CAAgB,CACpD,MAAOA,EAAA,CAAc,WAAd,CAD6C,CAA1C,CADoB,CA2qBlC7F,QAASA,GAAgB,CAACtG,CAAD,CAAWyhB,CAAX,CAAkC,CAazDC,QAASA,EAAoB,CAACphB,CAAD,CAAQqhB,CAAR,CAAuB,CAClD,IAAIC,EAAe,8BAAnB,CAEIC,EAAW,EAEfxrB,EAAA,CAAQiK,CAAR,CAAe,QAAQ,CAACwhB,CAAD,CAAaC,CAAb,CAAwB,CAC7C,IAAI5mB,EAAQ2mB,CAAA3mB,MAAA,CAAiBymB,CAAjB,CAEZ,IAAKzmB,CAAAA,CAAL,CACE,KAAM6mB,GAAA,CAAe,MAAf,CAGFL,CAHE,CAGaI,CAHb,CAGwBD,CAHxB,CAAN,CAMFD,CAAA,CAASE,CAAT,CAAA,CAAsB,CACpBE,SAAU9mB,CAAA,CAAM,CAAN,CAAV8mB,EAAsBF,CADF,CAEpBG,KAAM/mB,CAAA,CAAM,CAAN,CAFc;AAGpBgnB,SAAuB,GAAvBA,GAAUhnB,CAAA,CAAM,CAAN,CAHU,CAVuB,CAA/C,CAiBA,OAAO0mB,EAtB2C,CAbK,IACrDO,EAAgB,EADqC,CAGrDC,EAA2B,wCAH0B,CAIrDC,EAAyB,gCAJ4B,CAKrDC,EAAuBzoB,EAAA,CAAQ,2BAAR,CAL8B,CAMrD0oB,EAAwB,6BAN6B,CAWrDC,EAA4B,yBA0C/B,KAAAhd,UAAA,CAAiBid,QAASC,EAAiB,CAACvjB,CAAD,CAAOwjB,CAAP,CAAyB,CACnEtf,EAAA,CAAwBlE,CAAxB,CAA8B,WAA9B,CACIjJ,EAAA,CAASiJ,CAAT,CAAJ,EACE4D,EAAA,CAAU4f,CAAV,CAA4B,kBAA5B,CA8BA,CA7BKR,CAAA1rB,eAAA,CAA6B0I,CAA7B,CA6BL,GA5BEgjB,CAAA,CAAchjB,CAAd,CACA,CADsB,EACtB,CAAAY,CAAAoE,QAAA,CAAiBhF,CAAjB,CAzDOyjB,WAyDP,CAAgC,CAAC,WAAD,CAAc,mBAAd,CAC9B,QAAQ,CAACzJ,CAAD,CAAY3M,CAAZ,CAA+B,CACrC,IAAIqW,EAAa,EACjBzsB,EAAA,CAAQ+rB,CAAA,CAAchjB,CAAd,CAAR,CAA6B,QAAQ,CAACwjB,CAAD,CAAmBtoB,CAAnB,CAA0B,CAC7D,GAAI,CACF,IAAImL,EAAY2T,CAAAhZ,OAAA,CAAiBwiB,CAAjB,CACZnsB,EAAA,CAAWgP,CAAX,CAAJ,CACEA,CADF,CACc,CAAElF,QAAS3H,EAAA,CAAQ6M,CAAR,CAAX,CADd,CAEYlF,CAAAkF,CAAAlF,QAFZ,EAEiCkF,CAAA6a,KAFjC,GAGE7a,CAAAlF,QAHF,CAGsB3H,EAAA,CAAQ6M,CAAA6a,KAAR,CAHtB,CAKA7a;CAAAsd,SAAA,CAAqBtd,CAAAsd,SAArB,EAA2C,CAC3Ctd,EAAAnL,MAAA,CAAkBA,CAClBmL,EAAArG,KAAA,CAAiBqG,CAAArG,KAAjB,EAAmCA,CACnCqG,EAAAud,QAAA,CAAoBvd,CAAAud,QAApB,EAA0Cvd,CAAArD,WAA1C,EAAkEqD,CAAArG,KAClEqG,EAAAwd,SAAA,CAAqBxd,CAAAwd,SAArB,EAA2C,IACvClqB,EAAA,CAAS0M,CAAAnF,MAAT,CAAJ,GACEmF,CAAAyd,kBADF,CACgCxB,CAAA,CAAqBjc,CAAAnF,MAArB,CAAsCmF,CAAArG,KAAtC,CADhC,CAGA0jB,EAAA/rB,KAAA,CAAgB0O,CAAhB,CAfE,CAgBF,MAAOjI,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CAjBiD,CAA/D,CAqBA,OAAOslB,EAvB8B,CADT,CAAhC,CA2BF,EAAAV,CAAA,CAAchjB,CAAd,CAAArI,KAAA,CAAyB6rB,CAAzB,CA/BF,EAiCEvsB,CAAA,CAAQ+I,CAAR,CAAcjI,EAAA,CAAcwrB,CAAd,CAAd,CAEF,OAAO,KArC4D,CA6DrE,KAAAQ,2BAAA,CAAkCC,QAAQ,CAACC,CAAD,CAAS,CACjD,MAAIvqB,EAAA,CAAUuqB,CAAV,CAAJ,EACE5B,CAAA0B,2BAAA,CAAiDE,CAAjD,CACO,CAAA,IAFT,EAIS5B,CAAA0B,2BAAA,EALwC,CA8BnD,KAAAG,4BAAA,CAAmCC,QAAQ,CAACF,CAAD,CAAS,CAClD,MAAIvqB,EAAA,CAAUuqB,CAAV,CAAJ,EACE5B,CAAA6B,4BAAA,CAAkDD,CAAlD,CACO,CAAA,IAFT,EAIS5B,CAAA6B,4BAAA,EALyC,CA+BpD;IAAIrjB,EAAmB,CAAA,CACvB,KAAAA,iBAAA,CAAwBujB,QAAQ,CAACC,CAAD,CAAU,CACxC,MAAG3qB,EAAA,CAAU2qB,CAAV,CAAH,EACExjB,CACO,CADYwjB,CACZ,CAAA,IAFT,EAIOxjB,CALiC,CAQ1C,KAAAuX,KAAA,CAAY,CACF,WADE,CACW,cADX,CAC2B,mBAD3B,CACgD,kBADhD,CACoE,QADpE,CAEF,aAFE,CAEa,YAFb,CAE2B,WAF3B,CAEwC,MAFxC,CAEgD,UAFhD,CAE4D,eAF5D,CAGV,QAAQ,CAAC4B,CAAD,CAAcvM,CAAd,CAA8BJ,CAA9B,CAAmDgC,CAAnD,CAAuEhB,CAAvE,CACCpB,CADD,CACgBsB,CADhB,CAC8BpB,CAD9B,CAC2C0B,CAD3C,CACmDlC,CADnD,CAC+D3F,CAD/D,CAC8E,CA6NtFsd,QAASA,EAAY,CAACC,CAAD,CAAWC,CAAX,CAAsB,CACzC,GAAI,CACFD,CAAAE,SAAA,CAAkBD,CAAlB,CADE,CAEF,MAAMpmB,CAAN,CAAS,EAH8B,CAgD3C+C,QAASA,EAAO,CAACujB,CAAD,CAAgBC,CAAhB,CAA8BC,CAA9B,CAA2CC,CAA3C,CACIC,CADJ,CAC4B,CACpCJ,CAAN,WAA+BzmB,EAA/B,GAGEymB,CAHF,CAGkBzmB,CAAA,CAAOymB,CAAP,CAHlB,CAOAztB,EAAA,CAAQytB,CAAR,CAAuB,QAAQ,CAACrqB,CAAD,CAAOa,CAAP,CAAa,CACtCb,CAAAxD,SAAJ,EAAqB2H,EAArB,EAAuCnE,CAAA0qB,UAAAhpB,MAAA,CAAqB,KAArB,CAAvC,GACE2oB,CAAA,CAAcxpB,CAAd,CADF,CACyB+C,CAAA,CAAO5D,CAAP,CAAA6W,KAAA,CAAkB,eAAlB,CAAAhY,OAAA,EAAA,CAA4C,CAA5C,CADzB,CAD0C,CAA5C,CAKA,KAAI8rB,EACIC,CAAA,CAAaP,CAAb,CAA4BC,CAA5B,CAA0CD,CAA1C,CACaE,CADb,CAC0BC,CAD1B,CAC2CC,CAD3C,CAER3jB,EAAA+jB,gBAAA,CAAwBR,CAAxB,CACA;IAAIS,EAAY,IAChB,OAAOC,SAAqB,CAAClkB,CAAD,CAAQmkB,CAAR,CAAwBC,CAAxB,CAA+CC,CAA/C,CAAwEC,CAAxE,CAA4F,CACtH5hB,EAAA,CAAU1C,CAAV,CAAiB,OAAjB,CACKikB,EAAL,GAyCA,CAzCA,CAsCF,CADI9qB,CACJ,CArCgDmrB,CAqChD,EArCgDA,CAoCpB,CAAc,CAAd,CAC5B,EAG6B,eAApB,GAAA3qB,EAAA,CAAUR,CAAV,CAAA,EAAuCA,CAAAP,SAAA,EAAAiC,MAAA,CAAsB,KAAtB,CAAvC,CAAsE,KAAtE,CAA6E,MAHtF,CACS,MAvCP,CAUE0pB,EAAA,CANgB,MAAlB,GAAIN,CAAJ,CAMclnB,CAAA,CACVynB,CAAA,CAAaP,CAAb,CAAwBlnB,CAAA,CAAO,OAAP,CAAAK,OAAA,CAAuBomB,CAAvB,CAAAnmB,KAAA,EAAxB,CADU,CANd,CASW8mB,CAAJ,CAGOviB,EAAA5E,MAAA3G,KAAA,CAA2BmtB,CAA3B,CAHP,CAKOA,CAGd,IAAIY,CAAJ,CACE,IAASK,IAAAA,CAAT,GAA2BL,EAA3B,CACEG,CAAApkB,KAAA,CAAe,GAAf,CAAqBskB,CAArB,CAAsC,YAAtC,CAAoDL,CAAA,CAAsBK,CAAtB,CAAA9L,SAApD,CAIJ1Y,EAAAykB,eAAA,CAAuBH,CAAvB,CAAkCvkB,CAAlC,CAEImkB,EAAJ,EAAoBA,CAAA,CAAeI,CAAf,CAA0BvkB,CAA1B,CAChB8jB,EAAJ,EAAqBA,CAAA,CAAgB9jB,CAAhB,CAAuBukB,CAAvB,CAAkCA,CAAlC,CAA6CF,CAA7C,CACrB,OAAOE,EAjC+G,CAlB9E,CAgF5CR,QAASA,EAAY,CAACY,CAAD,CAAWlB,CAAX,CAAyBmB,CAAzB,CAAuClB,CAAvC,CAAoDC,CAApD,CACGC,CADH,CAC2B,CA0C9CE,QAASA,EAAe,CAAC9jB,CAAD,CAAQ2kB,CAAR,CAAkBC,CAAlB,CAAgCP,CAAhC,CAAyD,CAAA,IAC/DQ,CAD+D,CAClD1rB,CADkD,CAC5C2rB,CAD4C,CAChCluB,CADgC,CAC7BW,CAD6B,CACpBwtB,CADoB,CAE3EC,CAGJ,IAAIC,CAAJ,CAOE,IAHAD,CAGK,CAHgBnL,KAAJ,CADI8K,CAAAjvB,OACJ,CAGZ,CAAAkB,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgBsuB,CAAAxvB,OAAhB,CAAgCkB,CAAhC,EAAmC,CAAnC,CACEuuB,CACA,CADMD,CAAA,CAAQtuB,CAAR,CACN,CAAAouB,CAAA,CAAeG,CAAf,CAAA,CAAsBR,CAAA,CAASQ,CAAT,CAT1B,KAYEH,EAAA,CAAiBL,CAGf/tB,EAAA,CAAI,CAAR,KAAWW,CAAX,CAAgB2tB,CAAAxvB,OAAhB,CAAgCkB,CAAhC,CAAoCW,CAApC,CAAA,CACE4B,CAIA,CAJO6rB,CAAA,CAAeE,CAAA,CAAQtuB,CAAA,EAAR,CAAf,CAIP,CAHAwuB,CAGA;AAHaF,CAAA,CAAQtuB,CAAA,EAAR,CAGb,CAFAiuB,CAEA,CAFcK,CAAA,CAAQtuB,CAAA,EAAR,CAEd,CAAIwuB,CAAJ,EACMA,CAAAplB,MAAJ,EACE8kB,CACA,CADa9kB,CAAAqlB,KAAA,EACb,CAAAplB,CAAAykB,eAAA,CAAuB3nB,CAAA,CAAO5D,CAAP,CAAvB,CAAqC2rB,CAArC,CAFF,EAIEA,CAJF,CAIe9kB,CAkBf,CAdE+kB,CAcF,CAfKK,CAAAE,wBAAL,CAC2BC,EAAA,CACrBvlB,CADqB,CACdolB,CAAAI,WADc,CACSnB,CADT,CAErBe,CAAAK,+BAFqB,CAD3B,CAKYC,CAAAN,CAAAM,sBAAL,EAAyCrB,CAAzC,CACoBA,CADpB,CAGKA,CAAAA,CAAL,EAAgCZ,CAAhC,CACoB8B,EAAA,CAAwBvlB,CAAxB,CAA+ByjB,CAA/B,CADpB,CAIoB,IAG3B,CAAA2B,CAAA,CAAWP,CAAX,CAAwBC,CAAxB,CAAoC3rB,CAApC,CAA0CyrB,CAA1C,CAAwDG,CAAxD,CAvBF,EAyBWF,CAzBX,EA0BEA,CAAA,CAAY7kB,CAAZ,CAAmB7G,CAAAmX,WAAnB,CAAoCjb,CAApC,CAA+CgvB,CAA/C,CAnD2E,CAtCjF,IAJ8C,IAC1Ca,EAAU,EADgC,CAE1CS,CAF0C,CAEnCnD,CAFmC,CAEXlS,CAFW,CAEcsV,CAFd,CAE2BX,CAF3B,CAIrCruB,EAAI,CAAb,CAAgBA,CAAhB,CAAoB+tB,CAAAjvB,OAApB,CAAqCkB,CAAA,EAArC,CAA0C,CACxC+uB,CAAA,CAAQ,IAAIE,EAGZrD,EAAA,CAAasD,CAAA,CAAkBnB,CAAA,CAAS/tB,CAAT,CAAlB,CAA+B,EAA/B,CAAmC+uB,CAAnC,CAAgD,CAAN,GAAA/uB,CAAA,CAAU8sB,CAAV,CAAwBruB,CAAlE,CACmBsuB,CADnB,CAQb,EALAyB,CAKA,CALc5C,CAAA9sB,OAAD,CACPqwB,EAAA,CAAsBvD,CAAtB,CAAkCmC,CAAA,CAAS/tB,CAAT,CAAlC,CAA+C+uB,CAA/C,CAAsDlC,CAAtD,CAAoEmB,CAApE,CACwB,IADxB,CAC8B,EAD9B,CACkC,EADlC,CACsChB,CADtC,CADO,CAGP,IAEN,GAAkBwB,CAAAplB,MAAlB,EACEC,CAAA+jB,gBAAA,CAAwB2B,CAAAK,UAAxB,CAGFnB,EAAA,CAAeO,CAAD,EAAeA,CAAAa,SAAf,EACE,EAAA3V,CAAA,CAAaqU,CAAA,CAAS/tB,CAAT,CAAA0Z,WAAb,CADF,EAEC5a,CAAA4a,CAAA5a,OAFD,CAGR,IAHQ,CAIRquB,CAAA,CAAazT,CAAb,CACG8U,CAAA,EACEA,CAAAE,wBADF,EACwC,CAACF,CAAAM,sBADzC;AAEON,CAAAI,WAFP,CAEgC/B,CAHnC,CAKN,IAAI2B,CAAJ,EAAkBP,CAAlB,CACEK,CAAAzuB,KAAA,CAAaG,CAAb,CAAgBwuB,CAAhB,CAA4BP,CAA5B,CAEA,CADAe,CACA,CADc,CAAA,CACd,CAAAX,CAAA,CAAkBA,CAAlB,EAAqCG,CAIvCxB,EAAA,CAAyB,IAhCe,CAoC1C,MAAOgC,EAAA,CAAc9B,CAAd,CAAgC,IAxCO,CAmGhDyB,QAASA,GAAuB,CAACvlB,CAAD,CAAQyjB,CAAR,CAAsByC,CAAtB,CAAiDC,CAAjD,CAAsE,CAYpG,MAVwBC,SAAQ,CAACC,CAAD,CAAmBC,CAAnB,CAA4BC,CAA5B,CAAyCjC,CAAzC,CAA8DkC,CAA9D,CAA+E,CAExGH,CAAL,GACEA,CACA,CADmBrmB,CAAAqlB,KAAA,CAAW,CAAA,CAAX,CAAkBmB,CAAlB,CACnB,CAAAH,CAAAI,cAAA,CAAiC,CAAA,CAFnC,CAKA,OAAOhD,EAAA,CAAa4C,CAAb,CAA+BC,CAA/B,CAAwCC,CAAxC,CAAqDL,CAArD,CAAgF5B,CAAhF,CAPsG,CAFX,CAyBtGwB,QAASA,EAAiB,CAAC3sB,CAAD,CAAOqpB,CAAP,CAAmBmD,CAAnB,CAA0BjC,CAA1B,CAAuCC,CAAvC,CAAwD,CAAA,IAE5E+C,EAAWf,CAAAgB,MAFiE,CAG5E9rB,CAGJ,QALe1B,CAAAxD,SAKf,EACE,KAAKC,EAAL,CAEEgxB,EAAA,CAAapE,CAAb,CACIqE,EAAA,CAAmBltB,EAAA,CAAUR,CAAV,CAAnB,CADJ,CACyC,GADzC,CAC8CuqB,CAD9C,CAC2DC,CAD3D,CAIA,KANF,IAMWrqB,CANX,CAMuBwtB,CANvB,CAMiDC,CANjD,CAM2DC,EAAS7tB,CAAA8tB,WANpE,CAOWvvB,EAAI,CAPf,CAOkBC,EAAKqvB,CAALrvB,EAAeqvB,CAAAtxB,OAD/B,CAC8CgC,CAD9C,CACkDC,CADlD,CACsDD,CAAA,EADtD,CAC2D,CACzD,IAAIwvB,EAAgB,CAAA,CAApB,CACIC,EAAc,CAAA,CAElB7tB,EAAA,CAAO0tB,CAAA,CAAOtvB,CAAP,CACPoH,EAAA,CAAOxF,CAAAwF,KACP/H,EAAA,CAAQ4Z,CAAA,CAAKrX,CAAAvC,MAAL,CAGRqwB,EAAA,CAAaP,EAAA,CAAmB/nB,CAAnB,CACb,IAAIioB,CAAJ,CAAeM,EAAA/mB,KAAA,CAAqB8mB,CAArB,CAAf,CACEtoB,CAAA,CAAOmC,EAAA,CAAWmmB,CAAAE,OAAA,CAAkB,CAAlB,CAAX,CAAiC,GAAjC,CAGT,KAAIC,EAAiBH,CAAA7pB,QAAA,CAAmB,cAAnB,CAAmC,EAAnC,CAArB,CACI,CA8oB2B,EAAA,CAAA,CA9oBHgqB,IAAAA,EAAAA,CA+oBlC,IAAIzF,CAAA1rB,eAAA,CAA6B0I,CAA7B,CAAJ,CAAwC,CAC9BqG,CAAAA,CAAAA,IAAAA,EAAR,KAAmBqd,IAAAA;AAAa1J,CAAA9X,IAAA,CAAclC,CAAd,CAl0CzByjB,WAk0CyB,CAAbC,CACf5rB,EAAI,CADW4rB,CACRjrB,GAAKirB,CAAA9sB,OADhB,CACmCkB,CADnC,CACqCW,EADrC,CACyCX,CAAA,EADzC,CAGE,GADAuO,CACIqiB,CADQhF,CAAA,CAAW5rB,CAAX,CACR4wB,CAAAriB,CAAAqiB,aAAJ,CAA4B,CAC1B,CAAA,CAAO,CAAA,CAAP,OAAA,CAD0B,CAJQ,CASxC,CAAA,CAAO,CAAA,CAV8B,CA9oB3B,CAAJ,EACMJ,CADN,GACqBG,CADrB,CACsC,OADtC,GAEIL,CAEA,CAFgBpoB,CAEhB,CADAqoB,CACA,CADcroB,CAAAwoB,OAAA,CAAY,CAAZ,CAAexoB,CAAApJ,OAAf,CAA6B,CAA7B,CACd,CADgD,KAChD,CAAAoJ,CAAA,CAAOA,CAAAwoB,OAAA,CAAY,CAAZ,CAAexoB,CAAApJ,OAAf,CAA6B,CAA7B,CAJX,CAQAoxB,EAAA,CAAQD,EAAA,CAAmB/nB,CAAAwC,YAAA,EAAnB,CACRolB,EAAA,CAASI,CAAT,CAAA,CAAkBhoB,CAClB,IAAIioB,CAAJ,EAAiB,CAAApB,CAAAvvB,eAAA,CAAqB0wB,CAArB,CAAjB,CACInB,CAAA,CAAMmB,CAAN,CACA,CADe/vB,CACf,CAAIod,EAAA,CAAmBhb,CAAnB,CAAyB2tB,CAAzB,CAAJ,GACEnB,CAAA,CAAMmB,CAAN,CADF,CACiB,CAAA,CADjB,CAIJW,EAAA,CAA4BtuB,CAA5B,CAAkCqpB,CAAlC,CAA8CzrB,CAA9C,CAAqD+vB,CAArD,CAA4DC,CAA5D,CACAH,GAAA,CAAapE,CAAb,CAAyBsE,CAAzB,CAAgC,GAAhC,CAAqCpD,CAArC,CAAkDC,CAAlD,CAAmEuD,CAAnE,CACcC,CADd,CAhCyD,CAqC3D7D,CAAA,CAAYnqB,CAAAmqB,UACZ,IAAIztB,CAAA,CAASytB,CAAT,CAAJ,EAAyC,EAAzC,GAA2BA,CAA3B,CACE,IAAA,CAAOzoB,CAAP,CAAemnB,CAAAjS,KAAA,CAA4BuT,CAA5B,CAAf,CAAA,CACEwD,CAIA,CAJQD,EAAA,CAAmBhsB,CAAA,CAAM,CAAN,CAAnB,CAIR,CAHI+rB,EAAA,CAAapE,CAAb,CAAyBsE,CAAzB,CAAgC,GAAhC,CAAqCpD,CAArC,CAAkDC,CAAlD,CAGJ,GAFEgC,CAAA,CAAMmB,CAAN,CAEF,CAFiBnW,CAAA,CAAK9V,CAAA,CAAM,CAAN,CAAL,CAEjB,EAAAyoB,CAAA,CAAYA,CAAAgE,OAAA,CAAiBzsB,CAAAb,MAAjB,CAA+Ba,CAAA,CAAM,CAAN,CAAAnF,OAA/B,CAGhB,MACF,MAAK4H,EAAL,CACEoqB,CAAA,CAA4BlF,CAA5B,CAAwCrpB,CAAA0qB,UAAxC,CACA,MACF,MA5wKgB8D,CA4wKhB,CACE,GAAI,CAEF,GADA9sB,CACA,CADQknB,CAAAhS,KAAA,CAA8B5W,CAAA0qB,UAA9B,CACR,CACEiD,CACA,CADQD,EAAA,CAAmBhsB,CAAA,CAAM,CAAN,CAAnB,CACR,CAAI+rB,EAAA,CAAapE,CAAb,CAAyBsE,CAAzB,CAAgC,GAAhC;AAAqCpD,CAArC,CAAkDC,CAAlD,CAAJ,GACEgC,CAAA,CAAMmB,CAAN,CADF,CACiBnW,CAAA,CAAK9V,CAAA,CAAM,CAAN,CAAL,CADjB,CAJA,CAQF,MAAOqC,CAAP,CAAU,EApEhB,CA4EAslB,CAAA9rB,KAAA,CAAgBkxB,CAAhB,CACA,OAAOpF,EAnFyE,CA8FlFqF,QAASA,EAAS,CAAC1uB,CAAD,CAAO2uB,CAAP,CAAkBC,CAAlB,CAA2B,CAC3C,IAAIxkB,EAAQ,EAAZ,CACIykB,EAAQ,CACZ,IAAIF,CAAJ,EAAiB3uB,CAAA4F,aAAjB,EAAsC5F,CAAA4F,aAAA,CAAkB+oB,CAAlB,CAAtC,EAEE,EAAG,CACD,GAAK3uB,CAAAA,CAAL,CACE,KAAMuoB,GAAA,CAAe,SAAf,CAEIoG,CAFJ,CAEeC,CAFf,CAAN,CAIE5uB,CAAAxD,SAAJ,EAAqBC,EAArB,GACMuD,CAAA4F,aAAA,CAAkB+oB,CAAlB,CACJ,EADkCE,CAAA,EAClC,CAAI7uB,CAAA4F,aAAA,CAAkBgpB,CAAlB,CAAJ,EAAgCC,CAAA,EAFlC,CAIAzkB,EAAA9M,KAAA,CAAW0C,CAAX,CACAA,EAAA,CAAOA,CAAAuK,YAXN,CAAH,MAYiB,CAZjB,CAYSskB,CAZT,CAFF,KAgBEzkB,EAAA9M,KAAA,CAAW0C,CAAX,CAGF,OAAO4D,EAAA,CAAOwG,CAAP,CAtBoC,CAiC7C0kB,QAASA,EAA0B,CAACC,CAAD,CAASJ,CAAT,CAAoBC,CAApB,CAA6B,CAC9D,MAAO,SAAQ,CAAC/nB,CAAD,CAAQpG,CAAR,CAAiB+rB,CAAjB,CAAwBY,CAAxB,CAAqC9C,CAArC,CAAmD,CAChE7pB,CAAA,CAAUiuB,CAAA,CAAUjuB,CAAA,CAAQ,CAAR,CAAV,CAAsBkuB,CAAtB,CAAiCC,CAAjC,CACV,OAAOG,EAAA,CAAOloB,CAAP,CAAcpG,CAAd,CAAuB+rB,CAAvB,CAA8BY,CAA9B,CAA2C9C,CAA3C,CAFyD,CADJ,CA8BhEsC,QAASA,GAAqB,CAACvD,CAAD,CAAa2F,CAAb,CAA0BC,CAA1B,CAAyC3E,CAAzC,CACC4E,CADD,CACeC,CADf,CACyCC,CADzC,CACqDC,CADrD,CAEC5E,CAFD,CAEyB,CAiNrD6E,QAASA,EAAU,CAACC,CAAD,CAAMC,CAAN,CAAYb,CAAZ,CAAuBC,CAAvB,CAAgC,CACjD,GAAIW,CAAJ,CAAS,CACHZ,CAAJ,GAAeY,CAAf,CAAqBT,CAAA,CAA2BS,CAA3B,CAAgCZ,CAAhC,CAA2CC,CAA3C,CAArB,CACAW,EAAAhG,QAAA,CAAcvd,CAAAud,QACdgG,EAAArH,cAAA,CAAoBA,EACpB,IAAIuH,CAAJ,GAAiCzjB,CAAjC,EAA8CA,CAAA0jB,eAA9C,CACEH,CAAA;AAAMI,CAAA,CAAmBJ,CAAnB,CAAwB,CAAC7mB,aAAc,CAAA,CAAf,CAAxB,CAER0mB,EAAA9xB,KAAA,CAAgBiyB,CAAhB,CAPO,CAST,GAAIC,CAAJ,CAAU,CACJb,CAAJ,GAAea,CAAf,CAAsBV,CAAA,CAA2BU,CAA3B,CAAiCb,CAAjC,CAA4CC,CAA5C,CAAtB,CACAY,EAAAjG,QAAA,CAAevd,CAAAud,QACfiG,EAAAtH,cAAA,CAAqBA,EACrB,IAAIuH,CAAJ,GAAiCzjB,CAAjC,EAA8CA,CAAA0jB,eAA9C,CACEF,CAAA,CAAOG,CAAA,CAAmBH,CAAnB,CAAyB,CAAC9mB,aAAc,CAAA,CAAf,CAAzB,CAET2mB,EAAA/xB,KAAA,CAAiBkyB,CAAjB,CAPQ,CAVuC,CAsBnDI,QAASA,EAAc,CAAC1H,CAAD,CAAgBqB,CAAhB,CAAyBW,CAAzB,CAAmC2F,CAAnC,CAAuD,CAAA,IACxEjyB,CADwE,CACjEkyB,EAAkB,MAD+C,CACvCpH,EAAW,CAAA,CAD4B,CAExEqH,EAAiB7F,CAFuD,CAGxExoB,CACJ,IAAIhF,CAAA,CAAS6sB,CAAT,CAAJ,CA2BE,IA1BA7nB,CA0BI,CA1BI6nB,CAAA7nB,MAAA,CAAcqnB,CAAd,CA0BJ,CAzBJQ,CAyBI,CAzBMA,CAAA3D,UAAA,CAAkBlkB,CAAA,CAAM,CAAN,CAAAnF,OAAlB,CAyBN,CAvBAmF,CAAA,CAAM,CAAN,CAuBA,GAtBEA,CAAA,CAAM,CAAN,CAAJ,CAAcA,CAAA,CAAM,CAAN,CAAd,CAAyB,IAAzB,CACKA,CAAA,CAAM,CAAN,CADL,CACgBA,CAAA,CAAM,CAAN,CAqBd,EAnBa,GAAjB,GAAIA,CAAA,CAAM,CAAN,CAAJ,CACEouB,CADF,CACoB,eADpB,CAEwB,IAFxB,GAEWpuB,CAAA,CAAM,CAAN,CAFX,GAGEouB,CACA,CADkB,eAClB,CAAAC,CAAA,CAAiB7F,CAAArrB,OAAA,EAJnB,CAmBI,CAba,GAab,GAbA6C,CAAA,CAAM,CAAN,CAaA,GAZFgnB,CAYE,CAZS,CAAA,CAYT,EATJ9qB,CASI,CATI,IASJ,CAPAiyB,CAOA,EAP0C,MAO1C,GAPsBC,CAOtB,GANElyB,CAMF,CANUiyB,CAAA,CAAmBtG,CAAnB,CAMV,IALA3rB,CAKA,CALQA,CAAA4hB,SAKR,EAFJ5hB,CAEI,CAFIA,CAEJ,EAFamyB,CAAA,CAAeD,CAAf,CAAA,CAAgC,GAAhC,CAAsCvG,CAAtC,CAAgD,YAAhD,CAEb,CAAC3rB,CAAAA,CAAD,EAAW8qB,CAAAA,CAAf,CACE,KAAMH,GAAA,CAAe,OAAf,CAEFgB,CAFE,CAEOrB,CAFP,CAAN,CADF,CA3BF,IAiCWvrB,EAAA,CAAQ4sB,CAAR,CAAJ,GACL3rB,CACA;AADQ,EACR,CAAAhB,CAAA,CAAQ2sB,CAAR,CAAiB,QAAQ,CAACA,CAAD,CAAU,CACjC3rB,CAAAN,KAAA,CAAWsyB,CAAA,CAAe1H,CAAf,CAA8BqB,CAA9B,CAAuCW,CAAvC,CAAiD2F,CAAjD,CAAX,CADiC,CAAnC,CAFK,CAMP,OAAOjyB,EA3CqE,CA+C9EquB,QAASA,EAAU,CAACP,CAAD,CAAc7kB,CAAd,CAAqBmpB,CAArB,CAA+BvE,CAA/B,CAA6CwB,CAA7C,CAAgE,CA4KjFgD,QAASA,EAA0B,CAACppB,CAAD,CAAQqpB,CAAR,CAAuB/E,CAAvB,CAA4C,CAC7E,IAAIF,CAGCtrB,GAAA,CAAQkH,CAAR,CAAL,GACEskB,CAEA,CAFsB+E,CAEtB,CADAA,CACA,CADgBrpB,CAChB,CAAAA,CAAA,CAAQ3K,CAHV,CAMIi0B,EAAJ,GACElF,CADF,CAC0B4E,CAD1B,CAGK1E,EAAL,GACEA,CADF,CACwBgF,CAAA,CAAgCjG,CAAArrB,OAAA,EAAhC,CAAoDqrB,CAD5E,CAGA,OAAO+C,EAAA,CAAkBpmB,CAAlB,CAAyBqpB,CAAzB,CAAwCjF,CAAxC,CAA+DE,CAA/D,CAAoFiF,EAApF,CAhBsE,CA5KE,IAC1EhyB,CAD0E,CACtE2wB,CADsE,CAC9DpmB,CAD8D,CAClDD,CADkD,CACpCmnB,CADoC,CAChBvF,EADgB,CACFJ,CADE,CAE7EsC,CAEAwC,EAAJ,GAAoBgB,CAApB,EACExD,CACA,CADQyC,CACR,CAAA/E,CAAA,CAAW+E,CAAApC,UAFb,GAIE3C,CACA,CADWtmB,CAAA,CAAOosB,CAAP,CACX,CAAAxD,CAAA,CAAQ,IAAIE,EAAJ,CAAexC,CAAf,CAAyB+E,CAAzB,CALV,CAQIQ,EAAJ,GACE/mB,CADF,CACiB7B,CAAAqlB,KAAA,CAAW,CAAA,CAAX,CADjB,CAIA5B,GAAA,CAAe2C,CAAf,EAAoCgD,CAChCI,GAAJ,GAEEjD,CAEA,CAFc,EAEd,CADAyC,CACA,CADqB,EACrB,CAAAjzB,CAAA,CAAQyzB,EAAR,CAA8B,QAAQ,CAACrkB,CAAD,CAAY,CAAA,IAC5CqT,EAAS,CACXiR,OAAQtkB,CAAA,GAAcyjB,CAAd,EAA0CzjB,CAAA0jB,eAA1C,CAAqEhnB,CAArE,CAAoF7B,CADjF,CAEXqjB,SAAUA,CAFC,CAGXqG,OAAQ/D,CAHG,CAIXgE,YAAalG,EAJF,CAOb3hB,EAAA,CAAaqD,CAAArD,WACK,IAAlB,EAAIA,CAAJ,GACEA,CADF,CACe6jB,CAAA,CAAMxgB,CAAArG,KAAN,CADf,CAIA8qB,EAAA,CAAqB7d,CAAA,CAAYjK,CAAZ,CAAwB0W,CAAxB,CAAgC,CAAA,CAAhC,CAAsCrT,CAAA0kB,aAAtC,CAOrBb,EAAA,CAAmB7jB,CAAArG,KAAnB,CAAA,CAAqC8qB,CAChCN,EAAL,EACEjG,CAAAljB,KAAA,CAAc,GAAd,CAAoBgF,CAAArG,KAApB,CAAqC,YAArC,CAAmD8qB,CAAAjR,SAAnD,CAGF4N,EAAA,CAAYphB,CAAArG,KAAZ,CAAA;AAA8B8qB,CAzBkB,CAAlD,CAJF,CAiCA,IAAIhB,CAAJ,CAA8B,CAG5B3oB,CAAAykB,eAAA,CAAuBrB,CAAvB,CAAiCxhB,CAAjC,CAA+C,CAAA,CAA/C,CAAqD,EAAEioB,EAAF,GAAwBA,EAAxB,GAA8ClB,CAA9C,EACjDkB,EADiD,GAC3BlB,CAAAmB,oBAD2B,EAArD,CAEA9pB,EAAA+jB,gBAAA,CAAwBX,CAAxB,CAAkC,CAAA,CAAlC,CAEI2G,EAAAA,CAAyBzD,CAAzByD,EAAwCzD,CAAA,CAAYqC,CAAA9pB,KAAZ,CAC5C,KAAImrB,EAAwBpoB,CACxBmoB,EAAJ,EAA8BA,CAAAE,WAA9B,EACkD,CAAA,CADlD,GACItB,CAAAuB,iBADJ,GAEEF,CAFF,CAE0BD,CAAArR,SAF1B,CAKA5iB,EAAA,CAAQ8L,CAAA+gB,kBAAR,CAAyCgG,CAAAhG,kBAAzC,CAAqF,QAAQ,CAACpB,CAAD,CAAaC,CAAb,CAAwB,CAAA,IAC/GE,EAAWH,CAAAG,SADoG,CAE/GE,EAAWL,CAAAK,SAFoG,CAI/GuI,CAJ+G,CAK/GC,CAL+G,CAKpGC,CALoG,CAKzFC,CAE1B,QAJW/I,CAAAI,KAIX,EAEE,KAAK,GAAL,CACE+D,CAAA6E,SAAA,CAAe7I,CAAf,CAAyB,QAAQ,CAAC5qB,CAAD,CAAQ,CACvCkzB,CAAA,CAAsBxI,CAAtB,CAAA,CAAmC1qB,CADI,CAAzC,CAGA4uB,EAAA8E,YAAA,CAAkB9I,CAAlB,CAAA+I,QAAA,CAAsC1qB,CAClC2lB,EAAA,CAAMhE,CAAN,CAAJ,GAGEsI,CAAA,CAAsBxI,CAAtB,CAHF,CAGqClV,CAAA,CAAaoZ,CAAA,CAAMhE,CAAN,CAAb,CAAA,CAA8B3hB,CAA9B,CAHrC,CAKA,MAEF,MAAK,GAAL,CACE,GAAI6hB,CAAJ,EAAiB,CAAA8D,CAAA,CAAMhE,CAAN,CAAjB,CACE,KAEF0I,EAAA,CAAYld,CAAA,CAAOwY,CAAA,CAAMhE,CAAN,CAAP,CAEV4I,EAAA,CADEF,CAAAM,QAAJ,CACYtvB,EADZ,CAGYkvB,QAAQ,CAACtkB,CAAD,CAAG2kB,CAAH,CAAM,CAAE,MAAO3kB,EAAP,GAAa2kB,CAAb,EAAmB3kB,CAAnB,GAAyBA,CAAzB,EAA8B2kB,CAA9B,GAAoCA,CAAtC,CAE1BN,EAAA,CAAYD,CAAAQ,OAAZ,EAAgC,QAAQ,EAAG,CAEzCT,CAAA;AAAYH,CAAA,CAAsBxI,CAAtB,CAAZ,CAA+C4I,CAAA,CAAUrqB,CAAV,CAC/C,MAAM0hB,GAAA,CAAe,WAAf,CAEFiE,CAAA,CAAMhE,CAAN,CAFE,CAEeiH,CAAA9pB,KAFf,CAAN,CAHyC,CAO3CsrB,EAAA,CAAYH,CAAA,CAAsBxI,CAAtB,CAAZ,CAA+C4I,CAAA,CAAUrqB,CAAV,CAC3C8qB,EAAAA,CAAmBA,QAAyB,CAACC,CAAD,CAAc,CACvDR,CAAA,CAAQQ,CAAR,CAAqBd,CAAA,CAAsBxI,CAAtB,CAArB,CAAL,GAEO8I,CAAA,CAAQQ,CAAR,CAAqBX,CAArB,CAAL,CAKEE,CAAA,CAAUtqB,CAAV,CAAiB+qB,CAAjB,CAA+Bd,CAAA,CAAsBxI,CAAtB,CAA/B,CALF,CAEEwI,CAAA,CAAsBxI,CAAtB,CAFF,CAEqCsJ,CAJvC,CAUA,OAAOX,EAAP,CAAmBW,CAXyC,CAa9DD,EAAAE,UAAA,CAA6B,CAAA,CACzBC,EAAAA,CAAUjrB,CAAAhH,OAAA,CAAamU,CAAA,CAAOwY,CAAA,CAAMhE,CAAN,CAAP,CAAwBmJ,CAAxB,CAAb,CAAwD,IAAxD,CAA8DT,CAAAM,QAA9D,CACd9oB,EAAAqpB,IAAA,CAAiB,UAAjB,CAA6BD,CAA7B,CACA,MAEF,MAAK,GAAL,CACEZ,CACA,CADYld,CAAA,CAAOwY,CAAA,CAAMhE,CAAN,CAAP,CACZ,CAAAsI,CAAA,CAAsBxI,CAAtB,CAAA,CAAmC,QAAQ,CAACjJ,CAAD,CAAS,CAClD,MAAO6R,EAAA,CAAUrqB,CAAV,CAAiBwY,CAAjB,CAD2C,CApDxD,CAPmH,CAArH,CAd4B,CAgF1B+N,CAAJ,GACExwB,CAAA,CAAQwwB,CAAR,CAAqB,QAAQ,CAACzkB,CAAD,CAAa,CACxCA,CAAA,EADwC,CAA1C,CAGA,CAAAykB,CAAA,CAAc,IAJhB,CAQI3vB,EAAA,CAAI,CAAR,KAAWW,CAAX,CAAgBgxB,CAAA7yB,OAAhB,CAAmCkB,CAAnC,CAAuCW,CAAvC,CAA2CX,CAAA,EAA3C,CACEsxB,CACA,CADSK,CAAA,CAAW3xB,CAAX,CACT,CAAAu0B,CAAA,CAAajD,CAAb,CACIA,CAAArmB,aAAA,CAAsBA,CAAtB,CAAqC7B,CADzC,CAEIqjB,CAFJ,CAGIsC,CAHJ,CAIIuC,CAAAxF,QAJJ,EAIsBqG,CAAA,CAAeb,CAAA7G,cAAf,CAAqC6G,CAAAxF,QAArC,CAAqDW,CAArD,CAA+D2F,CAA/D,CAJtB,CAKIvF,EALJ,CAYF,KAAI8F,GAAevpB,CACf4oB,EAAJ,GAAiCA,CAAAwC,SAAjC,EAA+G,IAA/G,GAAsExC,CAAAyC,YAAtE,IACE9B,EADF,CACiB1nB,CADjB,CAGAgjB,EAAA,EAAeA,CAAA,CAAY0E,EAAZ,CAA0BJ,CAAA7Y,WAA1B,CAA+Cjb,CAA/C,CAA0D+wB,CAA1D,CAGf,KAAIxvB,CAAJ,CAAQ4xB,CAAA9yB,OAAR,CAA6B,CAA7B,CAAqC,CAArC,EAAgCkB,CAAhC,CAAwCA,CAAA,EAAxC,CACEsxB,CACA;AADSM,CAAA,CAAY5xB,CAAZ,CACT,CAAAu0B,CAAA,CAAajD,CAAb,CACIA,CAAArmB,aAAA,CAAsBA,CAAtB,CAAqC7B,CADzC,CAEIqjB,CAFJ,CAGIsC,CAHJ,CAIIuC,CAAAxF,QAJJ,EAIsBqG,CAAA,CAAeb,CAAA7G,cAAf,CAAqC6G,CAAAxF,QAArC,CAAqDW,CAArD,CAA+D2F,CAA/D,CAJtB,CAKIvF,EALJ,CAjK+E,CArRnFG,CAAA,CAAyBA,CAAzB,EAAmD,EAsBnD,KAvBqD,IAGjD0H,EAAmB,CAAC7K,MAAAC,UAH6B,CAIjD6K,CAJiD,CAKjD/B,GAAuB5F,CAAA4F,qBAL0B,CAMjDjD,CANiD,CAOjDqC,EAA2BhF,CAAAgF,yBAPsB,CAQjDkB,GAAoBlG,CAAAkG,kBAR6B,CASjD0B,GAA4B5H,CAAA4H,0BATqB,CAUjDC,GAAyB,CAAA,CAVwB,CAWjDC,EAAc,CAAA,CAXmC,CAYjDpC,EAAgC1F,CAAA0F,8BAZiB,CAajDqC,EAAevD,CAAApC,UAAf2F,CAAyC5uB,CAAA,CAAOorB,CAAP,CAbQ,CAcjDhjB,CAdiD,CAejDkc,EAfiD,CAgBjDuK,CAhBiD,CAkBjDC,GAAoBpI,CAlB6B,CAmBjDyE,CAnBiD,CAuB7CtxB,EAAI,CAvByC,CAuBtCW,GAAKirB,CAAA9sB,OAApB,CAAuCkB,CAAvC,CAA2CW,EAA3C,CAA+CX,CAAA,EAA/C,CAAoD,CAClDuO,CAAA,CAAYqd,CAAA,CAAW5rB,CAAX,CACZ,KAAIkxB,EAAY3iB,CAAA2mB,QAAhB,CACI/D,GAAU5iB,CAAA4mB,MAGVjE,EAAJ,GACE6D,CADF,CACiB9D,CAAA,CAAUM,CAAV,CAAuBL,CAAvB,CAAkCC,EAAlC,CADjB,CAGA6D,EAAA,CAAYv2B,CAEZ,IAAIi2B,CAAJ,CAAuBnmB,CAAAsd,SAAvB,CACE,KAGF,IAAIuJ,CAAJ,CAAqB7mB,CAAAnF,MAArB,CAIOmF,CAAAkmB,YAeL,GAdM5yB,CAAA,CAASuzB,CAAT,CAAJ,EAGEC,EAAA,CAAkB,oBAAlB,CAAwCrD,CAAxC,EAAoE2C,CAApE,CACkBpmB,CADlB,CAC6BwmB,CAD7B,CAEA,CAAA/C,CAAA,CAA2BzjB,CAL7B,EASE8mB,EAAA,CAAkB,oBAAlB;AAAwCrD,CAAxC,CAAkEzjB,CAAlE,CACkBwmB,CADlB,CAKJ,EAAAJ,CAAA,CAAoBA,CAApB,EAAyCpmB,CAG3Ckc,GAAA,CAAgBlc,CAAArG,KAEXusB,EAAAlmB,CAAAkmB,YAAL,EAA8BlmB,CAAArD,WAA9B,GACEkqB,CAIA,CAJiB7mB,CAAArD,WAIjB,CAHA0nB,EAGA,CAHuBA,EAGvB,EAH+C,EAG/C,CAFAyC,EAAA,CAAkB,GAAlB,CAAwB5K,EAAxB,CAAwC,cAAxC,CACImI,EAAA,CAAqBnI,EAArB,CADJ,CACyClc,CADzC,CACoDwmB,CADpD,CAEA,CAAAnC,EAAA,CAAqBnI,EAArB,CAAA,CAAsClc,CALxC,CAQA,IAAI6mB,CAAJ,CAAqB7mB,CAAAqgB,WAArB,CACEiG,EAUA,CAVyB,CAAA,CAUzB,CALKtmB,CAAA+mB,MAKL,GAJED,EAAA,CAAkB,cAAlB,CAAkCT,EAAlC,CAA6DrmB,CAA7D,CAAwEwmB,CAAxE,CACA,CAAAH,EAAA,CAA4BrmB,CAG9B,EAAsB,SAAtB,EAAI6mB,CAAJ,EACE1C,CASA,CATgC,CAAA,CAShC,CARAgC,CAQA,CARmBnmB,CAAAsd,SAQnB,CAPAmJ,CAOA,CAPYD,CAOZ,CANAA,CAMA,CANevD,CAAApC,UAMf,CALIjpB,CAAA,CAAO3H,CAAA+2B,cAAA,CAAuB,GAAvB,CAA6B9K,EAA7B,CAA6C,IAA7C,CACuB+G,CAAA,CAAc/G,EAAd,CADvB,CACsD,GADtD,CAAP,CAKJ,CAHA8G,CAGA,CAHcwD,CAAA,CAAa,CAAb,CAGd,CAFAS,EAAA,CAAY/D,CAAZ,CAxnMHvsB,EAAAzF,KAAA,CAwnMuCu1B,CAxnMvC,CAA+B,CAA/B,CAwnMG,CAAgDzD,CAAhD,CAEA,CAAA0D,EAAA,CAAoB5rB,CAAA,CAAQ2rB,CAAR,CAAmBnI,CAAnB,CAAiC6H,CAAjC,CACQe,CADR,EAC4BA,CAAAvtB,KAD5B,CACmD,CAQzC0sB,0BAA2BA,EARc,CADnD,CAVtB,GAsBEI,CAEA,CAFY7uB,CAAA,CAAOiU,EAAA,CAAYmX,CAAZ,CAAP,CAAAmE,SAAA,EAEZ,CADAX,CAAA1uB,MAAA,EACA,CAAA4uB,EAAA,CAAoB5rB,CAAA,CAAQ2rB,CAAR,CAAmBnI,CAAnB,CAxBtB,CA4BF,IAAIte,CAAAimB,SAAJ,CAWE,GAVAM,CAUInuB,CAVU,CAAA,CAUVA,CATJ0uB,EAAA,CAAkB,UAAlB,CAA8BnC,EAA9B,CAAiD3kB,CAAjD,CAA4DwmB,CAA5D,CASIpuB,CARJusB,EAQIvsB,CARgB4H,CAQhB5H,CANJyuB,CAMIzuB,CANcpH,CAAA,CAAWgP,CAAAimB,SAAX,CAAD,CACXjmB,CAAAimB,SAAA,CAAmBO,CAAnB,CAAiCvD,CAAjC,CADW,CAEXjjB,CAAAimB,SAIF7tB;AAFJyuB,CAEIzuB,CAFagvB,EAAA,CAAoBP,CAApB,CAEbzuB,CAAA4H,CAAA5H,QAAJ,CAAuB,CACrB8uB,CAAA,CAAmBlnB,CAIjBymB,EAAA,CArxJJjc,EAAArP,KAAA,CAkxJuB0rB,CAlxJvB,CAkxJE,CAGcQ,EAAA,CAAehI,CAAA,CAAarf,CAAAsnB,kBAAb,CAA0C9b,CAAA,CAAKqb,CAAL,CAA1C,CAAf,CAHd,CACc,EAId7D,EAAA,CAAcyD,CAAA,CAAU,CAAV,CAEd,IAAwB,CAAxB,EAAIA,CAAAl2B,OAAJ,EAA6ByyB,CAAAxyB,SAA7B,GAAsDC,EAAtD,CACE,KAAM8rB,GAAA,CAAe,OAAf,CAEFL,EAFE,CAEa,EAFb,CAAN,CAKF+K,EAAA,CAAY/D,CAAZ,CAA0BsD,CAA1B,CAAwCxD,CAAxC,CAEIuE,GAAAA,CAAmB,CAAC/F,MAAO,EAAR,CAOnBgG,EAAAA,CAAqB7G,CAAA,CAAkBqC,CAAlB,CAA+B,EAA/B,CAAmCuE,EAAnC,CACzB,KAAIE,GAAwBpK,CAAAtoB,OAAA,CAAkBtD,CAAlB,CAAsB,CAAtB,CAAyB4rB,CAAA9sB,OAAzB,EAA8CkB,CAA9C,CAAkD,CAAlD,EAExBgyB,EAAJ,EACEiE,EAAA,CAAwBF,CAAxB,CAEFnK,EAAA,CAAaA,CAAA7mB,OAAA,CAAkBgxB,CAAlB,CAAAhxB,OAAA,CAA6CixB,EAA7C,CACbE,EAAA,CAAwB1E,CAAxB,CAAuCsE,EAAvC,CAEAn1B,GAAA,CAAKirB,CAAA9sB,OAjCgB,CAAvB,IAmCEi2B,EAAAtuB,KAAA,CAAkB2uB,CAAlB,CAIJ,IAAI7mB,CAAAkmB,YAAJ,CACEK,CAeA,CAfc,CAAA,CAed,CAdAO,EAAA,CAAkB,UAAlB,CAA8BnC,EAA9B,CAAiD3kB,CAAjD,CAA4DwmB,CAA5D,CAcA,CAbA7B,EAaA,CAboB3kB,CAapB,CAXIA,CAAA5H,QAWJ,GAVE8uB,CAUF,CAVqBlnB,CAUrB,EAPAigB,CAOA,CAPa2H,CAAA,CAAmBvK,CAAAtoB,OAAA,CAAkBtD,CAAlB,CAAqB4rB,CAAA9sB,OAArB,CAAyCkB,CAAzC,CAAnB,CAAgE+0B,CAAhE,CACTvD,CADS,CACMC,CADN,CACoBoD,EADpB,EAC8CI,EAD9C,CACiEtD,CADjE,CAC6EC,CAD7E,CAC0F,CACjGgB,qBAAsBA,EAD2E,CAEjGZ,yBAA0BA,CAFuE,CAGjGkB,kBAAmBA,EAH8E,CAIjG0B,0BAA2BA,EAJsE,CAD1F,CAOb,CAAAj0B,EAAA,CAAKirB,CAAA9sB,OAhBP;IAiBO,IAAIyP,CAAAlF,QAAJ,CACL,GAAI,CACFioB,CACA,CADS/iB,CAAAlF,QAAA,CAAkB0rB,CAAlB,CAAgCvD,CAAhC,CAA+CyD,EAA/C,CACT,CAAI11B,CAAA,CAAW+xB,CAAX,CAAJ,CACEO,CAAA,CAAW,IAAX,CAAiBP,CAAjB,CAAyBJ,CAAzB,CAAoCC,EAApC,CADF,CAEWG,CAFX,EAGEO,CAAA,CAAWP,CAAAQ,IAAX,CAAuBR,CAAAS,KAAvB,CAAoCb,CAApC,CAA+CC,EAA/C,CALA,CAOF,MAAO7qB,EAAP,CAAU,CACViP,CAAA,CAAkBjP,EAAlB,CAAqBJ,EAAA,CAAY6uB,CAAZ,CAArB,CADU,CAKVxmB,CAAA8gB,SAAJ,GACEb,CAAAa,SACA,CADsB,CAAA,CACtB,CAAAqF,CAAA,CAAmB0B,IAAAC,IAAA,CAAS3B,CAAT,CAA2BnmB,CAAAsd,SAA3B,CAFrB,CAtKkD,CA6KpD2C,CAAAplB,MAAA,CAAmBurB,CAAnB,EAAoE,CAAA,CAApE,GAAwCA,CAAAvrB,MACxColB,EAAAE,wBAAA,CAAqCmG,EACrCrG,EAAAK,+BAAA,CAA4C6D,CAC5ClE,EAAAM,sBAAA,CAAmCgG,CACnCtG,EAAAI,WAAA,CAAwBqG,EAExBjI,EAAA0F,8BAAA,CAAuDA,CAGvD,OAAOlE,EA7M8C,CAudvDyH,QAASA,GAAuB,CAACrK,CAAD,CAAa,CAE3C,IAF2C,IAElC9qB,EAAI,CAF8B,CAE3BC,EAAK6qB,CAAA9sB,OAArB,CAAwCgC,CAAxC,CAA4CC,CAA5C,CAAgDD,CAAA,EAAhD,CACE8qB,CAAA,CAAW9qB,CAAX,CAAA,CAAgBK,EAAA,CAAQyqB,CAAA,CAAW9qB,CAAX,CAAR,CAAuB,CAACmxB,eAAgB,CAAA,CAAjB,CAAvB,CAHyB,CAqB7CjC,QAASA,GAAY,CAACsG,CAAD,CAAcpuB,CAAd,CAAoB8B,CAApB,CAA8B8iB,CAA9B,CAA2CC,CAA3C,CAA4DwJ,CAA5D,CACCC,CADD,CACc,CACjC,GAAItuB,CAAJ,GAAa6kB,CAAb,CAA8B,MAAO,KACjC9oB,EAAAA,CAAQ,IACZ,IAAIinB,CAAA1rB,eAAA,CAA6B0I,CAA7B,CAAJ,CAAwC,CAAA,IAC9BqG,CAAWqd,EAAAA;AAAa1J,CAAA9X,IAAA,CAAclC,CAAd,CAryCzByjB,WAqyCyB,CAAhC,KADsC,IAElC3rB,EAAI,CAF8B,CAE3BW,EAAKirB,CAAA9sB,OADhB,CACmCkB,CADnC,CACqCW,CADrC,CACyCX,CAAA,EADzC,CAEE,GAAI,CACFuO,CACA,CADYqd,CAAA,CAAW5rB,CAAX,CACZ,EAAM8sB,CAAN,GAAsBruB,CAAtB,EAAmCquB,CAAnC,CAAiDve,CAAAsd,SAAjD,GAC8C,EAD9C,EACKtd,CAAAwd,SAAA1oB,QAAA,CAA2B2G,CAA3B,CADL,GAEMusB,CAIJ,GAHEhoB,CAGF,CAHcpN,EAAA,CAAQoN,CAAR,CAAmB,CAAC2mB,QAASqB,CAAV,CAAyBpB,MAAOqB,CAAhC,CAAnB,CAGd,EADAF,CAAAz2B,KAAA,CAAiB0O,CAAjB,CACA,CAAAtK,CAAA,CAAQsK,CANV,CAFE,CAUF,MAAMjI,CAAN,CAAS,CAAEiP,CAAA,CAAkBjP,CAAlB,CAAF,CAbyB,CAgBxC,MAAOrC,EAnB0B,CAoDnCiyB,QAASA,EAAuB,CAACx1B,CAAD,CAAM6D,CAAN,CAAW,CAAA,IACrCkyB,EAAUlyB,CAAAwrB,MAD2B,CAErC2G,EAAUh2B,CAAAqvB,MAF2B,CAGrCtD,EAAW/rB,CAAA0uB,UAGfjwB,EAAA,CAAQuB,CAAR,CAAa,QAAQ,CAACP,CAAD,CAAQb,CAAR,CAAa,CACX,GAArB,EAAIA,CAAAkF,OAAA,CAAW,CAAX,CAAJ,GACMD,CAAA,CAAIjF,CAAJ,CAGJ,EAHgBiF,CAAA,CAAIjF,CAAJ,CAGhB,GAH6Ba,CAG7B,GAFEA,CAEF,GAFoB,OAAR,GAAAb,CAAA,CAAkB,GAAlB,CAAwB,GAEpC,EAF2CiF,CAAA,CAAIjF,CAAJ,CAE3C,EAAAoB,CAAAi2B,KAAA,CAASr3B,CAAT,CAAca,CAAd,CAAqB,CAAA,CAArB,CAA2Bs2B,CAAA,CAAQn3B,CAAR,CAA3B,CAJF,CADgC,CAAlC,CAUAH,EAAA,CAAQoF,CAAR,CAAa,QAAQ,CAACpE,CAAD,CAAQb,CAAR,CAAa,CACrB,OAAX,EAAIA,CAAJ,EACEktB,CAAA,CAAaC,CAAb,CAAuBtsB,CAAvB,CACA,CAAAO,CAAA,CAAI,OAAJ,CAAA,EAAgBA,CAAA,CAAI,OAAJ,CAAA,CAAeA,CAAA,CAAI,OAAJ,CAAf,CAA8B,GAA9B,CAAoC,EAApD,EAA0DP,CAF5D,EAGkB,OAAX,EAAIb,CAAJ,EACLmtB,CAAA/pB,KAAA,CAAc,OAAd,CAAuB+pB,CAAA/pB,KAAA,CAAc,OAAd,CAAvB,CAAgD,GAAhD,CAAsDvC,CAAtD,CACA,CAAAO,CAAA,MAAA,EAAgBA,CAAA,MAAA,CAAeA,CAAA,MAAf;AAA8B,GAA9B,CAAoC,EAApD,EAA0DP,CAFrD,EAMqB,GANrB,EAMIb,CAAAkF,OAAA,CAAW,CAAX,CANJ,EAM6B9D,CAAAlB,eAAA,CAAmBF,CAAnB,CAN7B,GAOLoB,CAAA,CAAIpB,CAAJ,CACA,CADWa,CACX,CAAAu2B,CAAA,CAAQp3B,CAAR,CAAA,CAAem3B,CAAA,CAAQn3B,CAAR,CARV,CAJyB,CAAlC,CAhByC,CAkC3C62B,QAASA,EAAkB,CAACvK,CAAD,CAAamJ,CAAb,CAA2B6B,CAA3B,CACvB5I,CADuB,CACTiH,CADS,CACUtD,CADV,CACsBC,CADtB,CACmC5E,CADnC,CAC2D,CAAA,IAChF6J,EAAY,EADoE,CAEhFC,CAFgF,CAGhFC,CAHgF,CAIhFC,EAA4BjC,CAAA,CAAa,CAAb,CAJoD,CAKhFkC,EAAqBrL,CAAAjK,MAAA,EAL2D,CAOhFuV,EAAuBz2B,CAAA,CAAO,EAAP,CAAWw2B,CAAX,CAA+B,CACpDxC,YAAa,IADuC,CACjC7F,WAAY,IADqB,CACfjoB,QAAS,IADM,CACAwsB,oBAAqB8D,CADrB,CAA/B,CAPyD,CAUhFxC,EAAel1B,CAAA,CAAW03B,CAAAxC,YAAX,CAAD,CACRwC,CAAAxC,YAAA,CAA+BM,CAA/B,CAA6C6B,CAA7C,CADQ,CAERK,CAAAxC,YAZ0E,CAahFoB,EAAoBoB,CAAApB,kBAExBd,EAAA1uB,MAAA,EAEAkR,EAAA,CAAiBR,CAAAogB,sBAAA,CAA2B1C,CAA3B,CAAjB,CAAA2C,KAAA,CACQ,QAAQ,CAACC,CAAD,CAAU,CAAA,IAClB9F,CADkB,CACyBpD,CAE/CkJ,EAAA,CAAU1B,EAAA,CAAoB0B,CAApB,CAEV,IAAIJ,CAAAtwB,QAAJ,CAAgC,CAI5BquB,CAAA,CAvvKJjc,EAAArP,KAAA,CAovKuB2tB,CApvKvB,CAovKE,CAGczB,EAAA,CAAehI,CAAA,CAAaiI,CAAb,CAAgC9b,CAAA,CAAKsd,CAAL,CAAhC,CAAf,CAHd,CACc,EAId9F,EAAA,CAAcyD,CAAA,CAAU,CAAV,CAEd,IAAwB,CAAxB,EAAIA,CAAAl2B,OAAJ,EAA6ByyB,CAAAxyB,SAA7B,GAAsDC,EAAtD,CACE,KAAM8rB,GAAA,CAAe,OAAf,CAEFmM,CAAA/uB,KAFE,CAEuBusB,CAFvB,CAAN,CAKF6C,CAAA,CAAoB,CAACvH,MAAO,EAAR,CACpByF,GAAA,CAAYxH,CAAZ,CAA0B+G,CAA1B,CAAwCxD,CAAxC,CACA,KAAIwE,EAAqB7G,CAAA,CAAkBqC,CAAlB;AAA+B,EAA/B,CAAmC+F,CAAnC,CAErBz1B,EAAA,CAASo1B,CAAA7tB,MAAT,CAAJ,EACE6sB,EAAA,CAAwBF,CAAxB,CAEFnK,EAAA,CAAamK,CAAAhxB,OAAA,CAA0B6mB,CAA1B,CACbsK,EAAA,CAAwBU,CAAxB,CAAgCU,CAAhC,CAtB8B,CAAhC,IAwBE/F,EACA,CADcyF,CACd,CAAAjC,CAAAtuB,KAAA,CAAkB4wB,CAAlB,CAGFzL,EAAA/iB,QAAA,CAAmBquB,CAAnB,CAEAJ,EAAA,CAA0B3H,EAAA,CAAsBvD,CAAtB,CAAkC2F,CAAlC,CAA+CqF,CAA/C,CACtB3B,CADsB,CACHF,CADG,CACWkC,CADX,CAC+BtF,CAD/B,CAC2CC,CAD3C,CAEtB5E,CAFsB,CAG1B7tB,EAAA,CAAQ6uB,CAAR,CAAsB,QAAQ,CAACzrB,CAAD,CAAOvC,CAAP,CAAU,CAClCuC,CAAJ,EAAYgvB,CAAZ,GACEvD,CAAA,CAAahuB,CAAb,CADF,CACoB+0B,CAAA,CAAa,CAAb,CADpB,CADsC,CAAxC,CAOA,KAFAgC,CAEA,CAF2B5J,CAAA,CAAa4H,CAAA,CAAa,CAAb,CAAArb,WAAb,CAAyCub,CAAzC,CAE3B,CAAM4B,CAAA/3B,OAAN,CAAA,CAAwB,CAClBsK,CAAAA,CAAQytB,CAAAlV,MAAA,EACR4V,EAAAA,CAAyBV,CAAAlV,MAAA,EAFP,KAGlB6V,EAAkBX,CAAAlV,MAAA,EAHA,CAIlB6N,EAAoBqH,CAAAlV,MAAA,EAJF,CAKlB4Q,EAAWwC,CAAA,CAAa,CAAb,CAEf,IAAI0C,CAAAruB,CAAAquB,YAAJ,CAAA,CAEA,GAAIF,CAAJ,GAA+BP,CAA/B,CAA0D,CACxD,IAAIU,EAAaH,CAAA7K,UAEXM,EAAA0F,8BAAN,EACIuE,CAAAtwB,QADJ,GAGE4rB,CAHF,CAGanY,EAAA,CAAYmX,CAAZ,CAHb,CAKAiE,GAAA,CAAYgC,CAAZ,CAA6BrxB,CAAA,CAAOoxB,CAAP,CAA7B,CAA6DhF,CAA7D,CAGA/F,EAAA,CAAarmB,CAAA,CAAOosB,CAAP,CAAb,CAA+BmF,CAA/B,CAXwD,CAcxDvJ,CAAA,CADE2I,CAAApI,wBAAJ,CAC2BC,EAAA,CAAwBvlB,CAAxB,CAA+B0tB,CAAAlI,WAA/B,CAAmEY,CAAnE,CAD3B,CAG2BA,CAE3BsH,EAAA,CAAwBC,CAAxB,CAAkD3tB,CAAlD,CAAyDmpB,CAAzD,CAAmEvE,CAAnE,CACEG,CADF,CApBA,CAPsB,CA8BxB0I,CAAA,CAAY,IA3EU,CAD1B,CA+EA,OAAOc,SAA0B,CAACC,CAAD,CAAoBxuB,CAApB,CAA2B7G,CAA3B,CAAiC4H,CAAjC,CAA8CqlB,CAA9C,CAAiE,CAC5FrB,CAAAA,CAAyBqB,CACzBpmB,EAAAquB,YAAJ,GACIZ,CAAJ,EACEA,CAAAh3B,KAAA,CAAeuJ,CAAf,CAGA,CAFAytB,CAAAh3B,KAAA,CAAe0C,CAAf,CAEA;AADAs0B,CAAAh3B,KAAA,CAAesK,CAAf,CACA,CAAA0sB,CAAAh3B,KAAA,CAAesuB,CAAf,CAJF,GAMM2I,CAAApI,wBAGJ,GAFEP,CAEF,CAF2BQ,EAAA,CAAwBvlB,CAAxB,CAA+B0tB,CAAAlI,WAA/B,CAAmEY,CAAnE,CAE3B,EAAAsH,CAAA,CAAwBC,CAAxB,CAAkD3tB,CAAlD,CAAyD7G,CAAzD,CAA+D4H,CAA/D,CAA4EgkB,CAA5E,CATF,CADA,CAFgG,CAhGd,CAqHtF6C,QAASA,EAAU,CAAC3hB,CAAD,CAAI2kB,CAAJ,CAAO,CACxB,IAAI6D,EAAO7D,CAAAnI,SAAPgM,CAAoBxoB,CAAAwc,SACxB,OAAa,EAAb,GAAIgM,CAAJ,CAAuBA,CAAvB,CACIxoB,CAAAnH,KAAJ,GAAe8rB,CAAA9rB,KAAf,CAA+BmH,CAAAnH,KAAD,CAAU8rB,CAAA9rB,KAAV,CAAqB,EAArB,CAAyB,CAAvD,CACOmH,CAAAjM,MADP,CACiB4wB,CAAA5wB,MAJO,CAQ1BiyB,QAASA,GAAiB,CAACyC,CAAD,CAAOC,CAAP,CAA0BxpB,CAA1B,CAAqCvL,CAArC,CAA8C,CACtE,GAAI+0B,CAAJ,CACE,KAAMjN,GAAA,CAAe,UAAf,CACFiN,CAAA7vB,KADE,CACsBqG,CAAArG,KADtB,CACsC4vB,CADtC,CAC4C5xB,EAAA,CAAYlD,CAAZ,CAD5C,CAAN,CAFoE,CAQxE8tB,QAASA,EAA2B,CAAClF,CAAD,CAAaoM,CAAb,CAAmB,CACrD,IAAIC,EAAgBtiB,CAAA,CAAaqiB,CAAb,CAAmB,CAAA,CAAnB,CAChBC,EAAJ,EACErM,CAAA/rB,KAAA,CAAgB,CACdgsB,SAAU,CADI,CAEdxiB,QAAS6uB,QAAiC,CAACC,CAAD,CAAe,CACnDC,CAAAA,CAAqBD,CAAA/2B,OAAA,EAAzB,KACIi3B,EAAmB,CAAEv5B,CAAAs5B,CAAAt5B,OAIrBu5B,EAAJ,EAAsBhvB,CAAAivB,kBAAA,CAA0BF,CAA1B,CAEtB,OAAOG,SAA8B,CAACnvB,CAAD,CAAQ7G,CAAR,CAAc,CACjD,IAAInB,EAASmB,CAAAnB,OAAA,EACRi3B,EAAL,EAAuBhvB,CAAAivB,kBAAA,CAA0Bl3B,CAA1B,CACvBiI,EAAAmvB,iBAAA,CAAyBp3B,CAAzB,CAAiC62B,CAAAQ,YAAjC,CACArvB,EAAAhH,OAAA,CAAa61B,CAAb;AAA4BS,QAAiC,CAACv4B,CAAD,CAAQ,CACnEoC,CAAA,CAAK,CAAL,CAAA0qB,UAAA,CAAoB9sB,CAD+C,CAArE,CAJiD,CARI,CAF3C,CAAhB,CAHmD,CA2BvDytB,QAASA,EAAY,CAAC/S,CAAD,CAAO2Z,CAAP,CAAiB,CACpC3Z,CAAA,CAAO5X,CAAA,CAAU4X,CAAV,EAAkB,MAAlB,CACP,QAAOA,CAAP,EACA,KAAK,KAAL,CACA,KAAK,MAAL,CACE,IAAI8d,EAAUn6B,CAAAya,cAAA,CAAuB,KAAvB,CACd0f,EAAApf,UAAA,CAAoB,GAApB,CAAwBsB,CAAxB,CAA6B,GAA7B,CAAiC2Z,CAAjC,CAA0C,IAA1C,CAA+C3Z,CAA/C,CAAoD,GACpD,OAAO8d,EAAAjf,WAAA,CAAmB,CAAnB,CAAAA,WACT,SACE,MAAO8a,EAPT,CAFoC,CActCoE,QAASA,GAAiB,CAACr2B,CAAD,CAAOs2B,CAAP,CAA2B,CACnD,GAA0B,QAA1B,EAAIA,CAAJ,CACE,MAAO9hB,EAAA+hB,KAET,KAAIlwB,EAAM7F,EAAA,CAAUR,CAAV,CAEV,IAA0B,WAA1B,EAAIs2B,CAAJ,EACY,MADZ,EACKjwB,CADL,EAC4C,QAD5C,EACsBiwB,CADtB,EAEY,KAFZ,EAEKjwB,CAFL,GAE4C,KAF5C,EAEsBiwB,CAFtB,EAG4C,OAH5C,EAGsBA,CAHtB,EAIE,MAAO9hB,EAAAgiB,aAV0C,CAerDlI,QAASA,EAA2B,CAACtuB,CAAD,CAAOqpB,CAAP,CAAmBzrB,CAAnB,CAA0B+H,CAA1B,CAAgC8wB,CAAhC,CAA8C,CAChF,IAAIf,EAAgBtiB,CAAA,CAAaxV,CAAb,CAAoB,CAAA,CAApB,CAGpB,IAAK83B,CAAL,CAAA,CAGA,GAAa,UAAb,GAAI/vB,CAAJ,EAA+C,QAA/C,GAA2BnF,EAAA,CAAUR,CAAV,CAA3B,CACE,KAAMuoB,GAAA,CAAe,UAAf,CAEF5kB,EAAA,CAAY3D,CAAZ,CAFE,CAAN,CAKFqpB,CAAA/rB,KAAA,CAAgB,CACdgsB,SAAU,GADI,CAEdxiB,QAASA,QAAQ,EAAG,CAChB,MAAO,CACLyoB,IAAKmH,QAAiC,CAAC7vB,CAAD;AAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACvDmxB,CAAAA,CAAenxB,CAAAmxB,YAAfA,GAAoCnxB,CAAAmxB,YAApCA,CAAuD,EAAvDA,CAEJ,IAAItI,CAAA7hB,KAAA,CAA+BxB,CAA/B,CAAJ,CACE,KAAM4iB,GAAA,CAAe,aAAf,CAAN,CAMGpoB,CAAA,CAAKwF,CAAL,CAAL,GAMA+vB,CANA,CAMgBtiB,CAAA,CAAajT,CAAA,CAAKwF,CAAL,CAAb,CAAyB,CAAA,CAAzB,CAA+B0wB,EAAA,CAAkBr2B,CAAlB,CAAwB2F,CAAxB,CAA/B,CACZmjB,CAAA,CAAqBnjB,CAArB,CADY,EACkB8wB,CADlB,CANhB,IAgBAt2B,CAAA,CAAKwF,CAAL,CAGA,CAHa+vB,CAAA,CAAc7uB,CAAd,CAGb,CADA8vB,CAACrF,CAAA,CAAY3rB,CAAZ,CAADgxB,GAAuBrF,CAAA,CAAY3rB,CAAZ,CAAvBgxB,CAA2C,EAA3CA,UACA,CAD0D,CAAA,CAC1D,CAAA92B,CAACM,CAAAmxB,YAADzxB,EAAqBM,CAAAmxB,YAAA,CAAiB3rB,CAAjB,CAAA4rB,QAArB1xB,EAAuDgH,CAAvDhH,QAAA,CACS61B,CADT,CACwBS,QAAiC,CAACS,CAAD,CAAWC,CAAX,CAAqB,CAO9D,OAAZ,GAAGlxB,CAAH,EAAuBixB,CAAvB,EAAmCC,CAAnC,CACE12B,CAAA22B,aAAA,CAAkBF,CAAlB,CAA4BC,CAA5B,CADF,CAGE12B,CAAAi0B,KAAA,CAAUzuB,CAAV,CAAgBixB,CAAhB,CAVwE,CAD9E,CAnBA,CAV2D,CADxD,CADS,CAFN,CAAhB,CATA,CAJgF,CA6ElF3D,QAASA,GAAW,CAACxH,CAAD,CAAesL,CAAf,CAAiCC,CAAjC,CAA0C,CAAA,IACxDC,EAAuBF,CAAA,CAAiB,CAAjB,CADiC,CAExDG,EAAcH,CAAAx6B,OAF0C,CAGxDsC,EAASo4B,CAAA7c,WAH+C,CAIxD3c,CAJwD,CAIrDW,CAEP,IAAIqtB,CAAJ,CACE,IAAIhuB,CAAO,CAAH,CAAG,CAAAW,CAAA,CAAKqtB,CAAAlvB,OAAhB,CAAqCkB,CAArC,CAAyCW,CAAzC,CAA6CX,CAAA,EAA7C,CACE,GAAIguB,CAAA,CAAahuB,CAAb,CAAJ,EAAuBw5B,CAAvB,CAA6C,CAC3CxL,CAAA,CAAahuB,CAAA,EAAb,CAAA,CAAoBu5B,CACJG,EAAAA,CAAK54B,CAAL44B,CAASD,CAATC,CAAuB,CAAvC,KAAS,IACA34B,EAAKitB,CAAAlvB,OADd,CAEKgC,CAFL,CAESC,CAFT,CAEaD,CAAA,EAAA,CAAK44B,CAAA,EAFlB,CAGMA,CAAJ,CAAS34B,CAAT,CACEitB,CAAA,CAAaltB,CAAb,CADF,CACoBktB,CAAA,CAAa0L,CAAb,CADpB,CAGE,OAAO1L,CAAA,CAAaltB,CAAb,CAGXktB,EAAAlvB,OAAA,EAAuB26B,CAAvB,CAAqC,CAKjCzL,EAAA3uB,QAAJ,GAA6Bm6B,CAA7B,GACExL,CAAA3uB,QADF;AACyBk6B,CADzB,CAGA,MAnB2C,CAwB7Cn4B,CAAJ,EACEA,CAAAu4B,aAAA,CAAoBJ,CAApB,CAA6BC,CAA7B,CAIE3gB,EAAAA,CAAWra,CAAAsa,uBAAA,EACfD,EAAAG,YAAA,CAAqBwgB,CAArB,CAKArzB,EAAA,CAAOozB,CAAP,CAAAhwB,KAAA,CAAqBpD,CAAA,CAAOqzB,CAAP,CAAAjwB,KAAA,EAArB,CAKKuB,GAAL,EAUEU,EACA,CADmC,CAAA,CACnC,CAAAV,EAAAM,UAAA,CAAiB,CAACouB,CAAD,CAAjB,CAXF,EACE,OAAOrzB,CAAAmb,MAAA,CAAakY,CAAA,CAAqBrzB,CAAAyzB,QAArB,CAAb,CAaAC,EAAAA,CAAI,CAAb,KAAgBC,CAAhB,CAAqBR,CAAAx6B,OAArB,CAA8C+6B,CAA9C,CAAkDC,CAAlD,CAAsDD,CAAA,EAAtD,CACM72B,CAGJ,CAHcs2B,CAAA,CAAiBO,CAAjB,CAGd,CAFA1zB,CAAA,CAAOnD,CAAP,CAAAinB,OAAA,EAEA,CADApR,CAAAG,YAAA,CAAqBhW,CAArB,CACA,CAAA,OAAOs2B,CAAA,CAAiBO,CAAjB,CAGTP,EAAA,CAAiB,CAAjB,CAAA,CAAsBC,CACtBD,EAAAx6B,OAAA,CAA0B,CAtEkC,CA0E9DozB,QAASA,EAAkB,CAAC7sB,CAAD,CAAK00B,CAAL,CAAiB,CAC1C,MAAOt5B,EAAA,CAAO,QAAQ,EAAG,CAAE,MAAO4E,EAAAG,MAAA,CAAS,IAAT,CAAe5E,SAAf,CAAT,CAAlB,CAAyDyE,CAAzD,CAA6D00B,CAA7D,CADmC,CAK5CxF,QAASA,EAAY,CAACjD,CAAD,CAASloB,CAAT,CAAgBqjB,CAAhB,CAA0BsC,CAA1B,CAAiCY,CAAjC,CAA8C9C,CAA9C,CAA4D,CAC/E,GAAI,CACFyE,CAAA,CAAOloB,CAAP,CAAcqjB,CAAd,CAAwBsC,CAAxB,CAA+BY,CAA/B,CAA4C9C,CAA5C,CADE,CAEF,MAAMvmB,CAAN,CAAS,CACTiP,CAAA,CAAkBjP,CAAlB,CAAqBJ,EAAA,CAAYumB,CAAZ,CAArB,CADS,CAHoE,CArhDjF,IAAIwC,GAAaA,QAAQ,CAACjsB,CAAD,CAAUg3B,CAAV,CAA4B,CACnD,GAAIA,CAAJ,CAAsB,CACpB,IAAIp6B,EAAOiB,MAAAjB,KAAA,CAAYo6B,CAAZ,CAAX,CACIh6B,CADJ,CACO2a,CADP,CACUrb,CAELU,EAAA,CAAI,CAAT,KAAY2a,CAAZ,CAAgB/a,CAAAd,OAAhB,CAA6BkB,CAA7B,CAAiC2a,CAAjC,CAAoC3a,CAAA,EAApC,CACEV,CACA,CADMM,CAAA,CAAKI,CAAL,CACN,CAAA,IAAA,CAAKV,CAAL,CAAA,CAAY06B,CAAA,CAAiB16B,CAAjB,CANM,CAAtB,IASE,KAAAywB,MAAA;AAAa,EAGf,KAAAX,UAAA,CAAiBpsB,CAbkC,CAgBrDisB,GAAA3tB,UAAA,CAAuB,CACrB24B,WAAYhK,EADS,CAerBiK,UAAYA,QAAQ,CAACC,CAAD,CAAW,CAC1BA,CAAH,EAAiC,CAAjC,CAAeA,CAAAr7B,OAAf,EACE+V,CAAA8X,SAAA,CAAkB,IAAAyC,UAAlB,CAAkC+K,CAAlC,CAF2B,CAfV,CAgCrBC,aAAeA,QAAQ,CAACD,CAAD,CAAW,CAC7BA,CAAH,EAAiC,CAAjC,CAAeA,CAAAr7B,OAAf,EACE+V,CAAAwlB,YAAA,CAAqB,IAAAjL,UAArB,CAAqC+K,CAArC,CAF8B,CAhCb,CAkDrBd,aAAeA,QAAQ,CAACiB,CAAD,CAAa5C,CAAb,CAAyB,CAC9C,IAAI6C,EAAQC,EAAA,CAAgBF,CAAhB,CAA4B5C,CAA5B,CACR6C,EAAJ,EAAaA,CAAAz7B,OAAb,EACE+V,CAAA8X,SAAA,CAAkB,IAAAyC,UAAlB,CAAkCmL,CAAlC,CAIF,EADIE,CACJ,CADeD,EAAA,CAAgB9C,CAAhB,CAA4B4C,CAA5B,CACf,GAAgBG,CAAA37B,OAAhB,EACE+V,CAAAwlB,YAAA,CAAqB,IAAAjL,UAArB,CAAqCqL,CAArC,CAR4C,CAlD3B,CAuErB9D,KAAMA,QAAQ,CAACr3B,CAAD,CAAMa,CAAN,CAAau6B,CAAb,CAAwB3P,CAAxB,CAAkC,CAAA,IAK1CxoB,EAAO,IAAA6sB,UAAA,CAAe,CAAf,CALmC,CAM1CuL,EAAapd,EAAA,CAAmBhb,CAAnB,CAAyBjD,CAAzB,CAN6B,CAO1Cs7B,EAAajd,EAAA,CAAmBpb,CAAnB,CAAyBjD,CAAzB,CAP6B,CAQ1Cu7B,EAAWv7B,CAIXq7B,EAAJ,EACE,IAAAvL,UAAA3sB,KAAA,CAAoBnD,CAApB,CAAyBa,CAAzB,CACA,CAAA4qB,CAAA,CAAW4P,CAFb,EAGUC,CAHV,GAIE,IAAA,CAAKA,CAAL,CACA,CADmBz6B,CACnB,CAAA06B,CAAA,CAAWD,CALb,CAQA,KAAA,CAAKt7B,CAAL,CAAA,CAAYa,CAGR4qB,EAAJ,CACE,IAAAgF,MAAA,CAAWzwB,CAAX,CADF,CACoByrB,CADpB,EAGEA,CAHF,CAGa,IAAAgF,MAAA,CAAWzwB,CAAX,CAHb,IAKI,IAAAywB,MAAA,CAAWzwB,CAAX,CALJ;AAKsByrB,CALtB,CAKiC1gB,EAAA,CAAW/K,CAAX,CAAgB,GAAhB,CALjC,CASAkD,EAAA,CAAWO,EAAA,CAAU,IAAAqsB,UAAV,CAEX,IAAkB,GAAlB,GAAK5sB,CAAL,EAAiC,MAAjC,GAAyBlD,CAAzB,EACkB,KADlB,GACKkD,CADL,EACmC,KADnC,GAC2BlD,CAD3B,CAGE,IAAA,CAAKA,CAAL,CAAA,CAAYa,CAAZ,CAAoB+O,CAAA,CAAc/O,CAAd,CAA6B,KAA7B,GAAqBb,CAArB,CAHtB,KAIO,IAAiB,KAAjB,GAAIkD,CAAJ,EAAkC,QAAlC,GAA0BlD,CAA1B,CAA4C,CAejD,IAbIuE,IAAAA,EAAS,EAATA,CAGAi3B,EAAgB/gB,CAAA,CAAK5Z,CAAL,CAHhB0D,CAKAk3B,EAAa,qCALbl3B,CAMA2P,EAAU,IAAA9J,KAAA,CAAUoxB,CAAV,CAAA,CAA2BC,CAA3B,CAAwC,KANlDl3B,CASAm3B,EAAUF,CAAAh4B,MAAA,CAAoB0Q,CAApB,CATV3P,CAYAo3B,EAAoB7E,IAAA8E,MAAA,CAAWF,CAAAl8B,OAAX,CAA4B,CAA5B,CAZpB+E,CAaK7D,EAAE,CAAX,CAAcA,CAAd,CAAgBi7B,CAAhB,CAAmCj7B,CAAA,EAAnC,CACE,IAAIm7B,EAAa,CAAbA,CAAWn7B,CAAf,CAEA6D,EAAAA,CAAAA,CAAUqL,CAAA,CAAc6K,CAAA,CAAMihB,CAAA,CAAQG,CAAR,CAAN,CAAd,CAAwC,CAAA,CAAxC,CAFV,CAIAt3B,EAAAA,CAAAA,EAAY,GAAZA,CAAkBkW,CAAA,CAAKihB,CAAA,CAAQG,CAAR,CAAiB,CAAjB,CAAL,CAAlBt3B,CAIEu3B,EAAAA,CAAYrhB,CAAA,CAAKihB,CAAA,CAAU,CAAV,CAAQh7B,CAAR,CAAL,CAAA8C,MAAA,CAAyB,IAAzB,CAGhBe,EAAA,EAAUqL,CAAA,CAAc6K,CAAA,CAAKqhB,CAAA,CAAU,CAAV,CAAL,CAAd,CAAkC,CAAA,CAAlC,CAGe,EAAzB,GAAIA,CAAAt8B,OAAJ,GACE+E,CADF,EACa,GADb,CACmBkW,CAAA,CAAKqhB,CAAA,CAAU,CAAV,CAAL,CADnB,CAGA,KAAA,CAAK97B,CAAL,CAAA,CAAYa,CAAZ,CAAoB0D,CAjC6B,CAoCjC,CAAA,CAAlB,GAAI62B,CAAJ,GACgB,IAAd,GAAIv6B,CAAJ,EAAsBA,CAAtB,GAAgC1B,CAAhC,CACE,IAAA2wB,UAAAiM,WAAA,CAA0BtQ,CAA1B,CADF,CAGE,IAAAqE,UAAA1sB,KAAA,CAAoBqoB,CAApB,CAA8B5qB,CAA9B,CAJJ,CAUA,EADI0zB,CACJ,CADkB,IAAAA,YAClB;AAAe10B,CAAA,CAAQ00B,CAAA,CAAYgH,CAAZ,CAAR,CAA+B,QAAQ,CAACx1B,CAAD,CAAK,CACzD,GAAI,CACFA,CAAA,CAAGlF,CAAH,CADE,CAEF,MAAOmG,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CAH6C,CAA5C,CApF+B,CAvE3B,CAuLrBstB,SAAUA,QAAQ,CAACt0B,CAAD,CAAM+F,CAAN,CAAU,CAAA,IACtB0pB,EAAQ,IADc,CAEtB8E,EAAe9E,CAAA8E,YAAfA,GAAqC9E,CAAA8E,YAArCA,CAAyD9mB,EAAA,EAAzD8mB,CAFsB,CAGtByH,EAAazH,CAAA,CAAYv0B,CAAZ,CAAbg8B,GAAkCzH,CAAA,CAAYv0B,CAAZ,CAAlCg8B,CAAqD,EAArDA,CAEJA,EAAAz7B,KAAA,CAAewF,CAAf,CACAoR,EAAAtU,WAAA,CAAsB,QAAQ,EAAG,CAC1Bm5B,CAAApC,QAAL,EAEE7zB,CAAA,CAAG0pB,CAAA,CAAMzvB,CAAN,CAAH,CAH6B,CAAjC,CAOA,OAAO,SAAQ,EAAG,CAChB4D,EAAA,CAAYo4B,CAAZ,CAAuBj2B,CAAvB,CADgB,CAbQ,CAvLP,CAlB+D,KAuOlFk2B,GAAc5lB,CAAA4lB,YAAA,EAvOoE,CAwOlFC,GAAY7lB,CAAA6lB,UAAA,EAxOsE,CAyOlF7F,GAAsC,IAAhB,EAAC4F,EAAD,EAAsC,IAAtC,EAAwBC,EAAxB,CAChBh6B,EADgB,CAEhBm0B,QAA4B,CAACnB,CAAD,CAAW,CACvC,MAAOA,EAAA7tB,QAAA,CAAiB,OAAjB,CAA0B40B,EAA1B,CAAA50B,QAAA,CAA+C,KAA/C,CAAsD60B,EAAtD,CADgC,CA3OqC,CA8OlF/K,GAAkB,cAEtBpnB,EAAAmvB,iBAAA,CAA2BzvB,CAAA,CAAmByvB,QAAyB,CAAC/L,CAAD,CAAWgP,CAAX,CAAoB,CACzF,IAAI9Q,EAAW8B,CAAAljB,KAAA,CAAc,UAAd,CAAXohB,EAAwC,EAExCzrB,EAAA,CAAQu8B,CAAR,CAAJ,CACE9Q,CADF,CACaA,CAAA5lB,OAAA,CAAgB02B,CAAhB,CADb,CAGE9Q,CAAA9qB,KAAA,CAAc47B,CAAd,CAGFhP,EAAAljB,KAAA,CAAc,UAAd,CAA0BohB,CAA1B,CATyF,CAAhE,CAUvBppB,CAEJ8H,EAAAivB,kBAAA,CAA4BvvB,CAAA;AAAmBuvB,QAA0B,CAAC7L,CAAD,CAAW,CAClFD,CAAA,CAAaC,CAAb,CAAuB,YAAvB,CADkF,CAAxD,CAExBlrB,CAEJ8H,EAAAykB,eAAA,CAAyB/kB,CAAA,CAAmB+kB,QAAuB,CAACrB,CAAD,CAAWrjB,CAAX,CAAkBsyB,CAAlB,CAA4BC,CAA5B,CAAwC,CAEzGlP,CAAAljB,KAAA,CADemyB,CAAAE,CAAYD,CAAA,CAAa,yBAAb,CAAyC,eAArDC,CAAwE,QACvF,CAAwBxyB,CAAxB,CAFyG,CAAlF,CAGrB7H,CAEJ8H,EAAA+jB,gBAAA,CAA0BrkB,CAAA,CAAmBqkB,QAAwB,CAACX,CAAD,CAAWiP,CAAX,CAAqB,CACxFlP,CAAA,CAAaC,CAAb,CAAuBiP,CAAA,CAAW,kBAAX,CAAgC,UAAvD,CADwF,CAAhE,CAEtBn6B,CAEJ,OAAO8H,EAzQ+E,CAJ5E,CAxL6C,CAyuD3D4mB,QAASA,GAAkB,CAAC/nB,CAAD,CAAO,CAChC,MAAOiQ,GAAA,CAAUjQ,CAAAvB,QAAA,CAAak1B,EAAb,CAA4B,EAA5B,CAAV,CADyB,CAgElCrB,QAASA,GAAe,CAACsB,CAAD,CAAOC,CAAP,CAAa,CAAA,IAC/BC,EAAS,EADsB,CAE/BC,EAAUH,CAAAh5B,MAAA,CAAW,KAAX,CAFqB,CAG/Bo5B,EAAUH,CAAAj5B,MAAA,CAAW,KAAX,CAHqB,CAM3B9C,EAAI,CADZ,EAAA,CACA,IAAA,CAAeA,CAAf,CAAmBi8B,CAAAn9B,OAAnB,CAAmCkB,CAAA,EAAnC,CAAwC,CAEtC,IADA,IAAIm8B,EAAQF,CAAA,CAAQj8B,CAAR,CAAZ,CACQc,EAAI,CAAZ,CAAeA,CAAf,CAAmBo7B,CAAAp9B,OAAnB,CAAmCgC,CAAA,EAAnC,CACE,GAAGq7B,CAAH,EAAYD,CAAA,CAAQp7B,CAAR,CAAZ,CAAwB,SAAS,CAEnCk7B,EAAA,GAA2B,CAAhB,CAAAA,CAAAl9B,OAAA,CAAoB,GAApB,CAA0B,EAArC,EAA2Cq9B,CALL,CAOxC,MAAOH,EAb4B,CAgBrCpG,QAASA,GAAc,CAACwG,CAAD,CAAU,CAC/BA,CAAA,CAAUj2B,CAAA,CAAOi2B,CAAP,CACV,KAAIp8B,EAAIo8B,CAAAt9B,OAER,IAAS,CAAT,EAAIkB,CAAJ,CACE,MAAOo8B,EAGT,KAAA,CAAOp8B,CAAA,EAAP,CAAA,CAr3MsB+wB,CAu3MpB;AADWqL,CAAA75B,CAAQvC,CAARuC,CACPxD,SAAJ,EACEuE,EAAA7D,KAAA,CAAY28B,CAAZ,CAAqBp8B,CAArB,CAAwB,CAAxB,CAGJ,OAAOo8B,EAdwB,CA2BjChnB,QAASA,GAAmB,EAAG,CAAA,IACzBua,EAAc,EADW,CAEzB0M,EAAU,CAAA,CAFe,CAGzBC,EAAY,yBAWhB,KAAAC,SAAA,CAAgBC,QAAQ,CAACt0B,CAAD,CAAOiE,CAAP,CAAoB,CAC1CC,EAAA,CAAwBlE,CAAxB,CAA8B,YAA9B,CACIrG,EAAA,CAASqG,CAAT,CAAJ,CACEzH,CAAA,CAAOkvB,CAAP,CAAoBznB,CAApB,CADF,CAGEynB,CAAA,CAAYznB,CAAZ,CAHF,CAGsBiE,CALoB,CAc5C,KAAAswB,aAAA,CAAoBC,QAAQ,EAAG,CAC7BL,CAAA,CAAU,CAAA,CADmB,CAK/B,KAAA/b,KAAA,CAAY,CAAC,WAAD,CAAc,SAAd,CAAyB,QAAQ,CAAC4B,CAAD,CAAYrK,CAAZ,CAAqB,CAwFhE8kB,QAASA,EAAa,CAAC/a,CAAD,CAAS0R,CAAT,CAAqBvR,CAArB,CAA+B7Z,CAA/B,CAAqC,CACzD,GAAM0Z,CAAAA,CAAN,EAAgB,CAAA/f,CAAA,CAAS+f,CAAAiR,OAAT,CAAhB,CACE,KAAMn0B,EAAA,CAAO,aAAP,CAAA,CAAsB,OAAtB,CAEJwJ,CAFI,CAEEorB,CAFF,CAAN,CAKF1R,CAAAiR,OAAA,CAAcS,CAAd,CAAA,CAA4BvR,CAP6B,CA/D3D,MAAO,SAAQ,CAAC6a,CAAD,CAAahb,CAAb,CAAqBib,CAArB,CAA4BC,CAA5B,CAAmC,CAAA,IAQ5C/a,CAR4C,CAQ3B5V,CAR2B,CAQdmnB,CAClCuJ,EAAA,CAAkB,CAAA,CAAlB,GAAQA,CACJC,EAAJ,EAAa79B,CAAA,CAAS69B,CAAT,CAAb,GACExJ,CADF,CACewJ,CADf,CAIG79B,EAAA,CAAS29B,CAAT,CAAH,GACE34B,CAQA,CARQ24B,CAAA34B,MAAA,CAAiBq4B,CAAjB,CAQR,CAPAnwB,CAOA,CAPclI,CAAA,CAAM,CAAN,CAOd,CANAqvB,CAMA,CANaA,CAMb,EAN2BrvB,CAAA,CAAM,CAAN,CAM3B,CALA24B,CAKA,CALajN,CAAAnwB,eAAA,CAA2B2M,CAA3B,CAAA,CACPwjB,CAAA,CAAYxjB,CAAZ,CADO,CAEPE,EAAA,CAAOuV,CAAAiR,OAAP,CAAsB1mB,CAAtB,CAAmC,CAAA,CAAnC,CAFO,GAGJkwB,CAAA,CAAUhwB,EAAA,CAAOwL,CAAP,CAAgB1L,CAAhB,CAA6B,CAAA,CAA7B,CAAV,CAA+C1N,CAH3C,CAKb,CAAAwN,EAAA,CAAY2wB,CAAZ,CAAwBzwB,CAAxB,CAAqC,CAAA,CAArC,CATF,CAYA;GAAI0wB,CAAJ,CAmBE,MATI/a,EASG,CATWA,QAAQ,EAAG,EAStB,CARPA,CAAAxgB,UAQO,CARiBA,CAACpC,CAAA,CAAQ09B,CAAR,CAAA,CACvBA,CAAA,CAAWA,CAAA99B,OAAX,CAA+B,CAA/B,CADuB,CACa89B,CADdt7B,WAQjB,CANPygB,CAMO,CANI,IAAID,CAMR,CAJHwR,CAIG,EAHLqJ,CAAA,CAAc/a,CAAd,CAAsB0R,CAAtB,CAAkCvR,CAAlC,CAA4C5V,CAA5C,EAA2DywB,CAAA10B,KAA3D,CAGK,CAAAzH,CAAA,CAAO,QAAQ,EAAG,CACvByhB,CAAAhZ,OAAA,CAAiB0zB,CAAjB,CAA6B7a,CAA7B,CAAuCH,CAAvC,CAA+CzV,CAA/C,CACA,OAAO4V,EAFgB,CAAlB,CAGJ,CACDA,SAAUA,CADT,CAEDuR,WAAYA,CAFX,CAHI,CASTvR,EAAA,CAAWG,CAAA7B,YAAA,CAAsBuc,CAAtB,CAAkChb,CAAlC,CAA0CzV,CAA1C,CAEPmnB,EAAJ,EACEqJ,CAAA,CAAc/a,CAAd,CAAsB0R,CAAtB,CAAkCvR,CAAlC,CAA4C5V,CAA5C,EAA2DywB,CAAA10B,KAA3D,CAGF,OAAO6Z,EA5DyC,CAzBc,CAAtD,CAjCiB,CA8J/BzM,QAASA,GAAiB,EAAE,CAC1B,IAAAgL,KAAA,CAAY,CAAC,SAAD,CAAY,QAAQ,CAAC/hB,CAAD,CAAQ,CACtC,MAAO4H,EAAA,CAAO5H,CAAAC,SAAP,CAD+B,CAA5B,CADc,CA8C5BgX,QAASA,GAAyB,EAAG,CACnC,IAAA8K,KAAA,CAAY,CAAC,MAAD,CAAS,QAAQ,CAACjK,CAAD,CAAO,CAClC,MAAO,SAAQ,CAAC0mB,CAAD,CAAYC,CAAZ,CAAmB,CAChC3mB,CAAAuO,MAAApf,MAAA,CAAiB6Q,CAAjB,CAAuBzV,SAAvB,CADgC,CADA,CAAxB,CADuB,CAcrCq8B,QAASA,GAAY,CAACC,CAAD,CAAU,CAAA,IACzBjjB,EAAS,EADgB,CACZ3a,CADY,CACPoG,CADO,CACF1F,CAE3B,IAAKk9B,CAAAA,CAAL,CAAc,MAAOjjB,EAErB9a,EAAA,CAAQ+9B,CAAAp6B,MAAA,CAAc,IAAd,CAAR,CAA6B,QAAQ,CAACq6B,CAAD,CAAO,CAC1Cn9B,CAAA,CAAIm9B,CAAA95B,QAAA,CAAa,GAAb,CACJ/D,EAAA,CAAM2D,CAAA,CAAU8W,CAAA,CAAKojB,CAAAzM,OAAA,CAAY,CAAZ,CAAe1wB,CAAf,CAAL,CAAV,CACN0F;CAAA,CAAMqU,CAAA,CAAKojB,CAAAzM,OAAA,CAAY1wB,CAAZ,CAAgB,CAAhB,CAAL,CAEFV,EAAJ,GACE2a,CAAA,CAAO3a,CAAP,CADF,CACgB2a,CAAA,CAAO3a,CAAP,CAAA,CAAc2a,CAAA,CAAO3a,CAAP,CAAd,CAA4B,IAA5B,CAAmCoG,CAAnC,CAAyCA,CADzD,CAL0C,CAA5C,CAUA,OAAOuU,EAfsB,CA+B/BmjB,QAASA,GAAa,CAACF,CAAD,CAAU,CAC9B,IAAIG,EAAax7B,CAAA,CAASq7B,CAAT,CAAA,CAAoBA,CAApB,CAA8Bz+B,CAE/C,OAAO,SAAQ,CAACyJ,CAAD,CAAO,CACfm1B,CAAL,GAAiBA,CAAjB,CAA+BJ,EAAA,CAAaC,CAAb,CAA/B,CAEA,OAAIh1B,EAAJ,CACSm1B,CAAA,CAAWp6B,CAAA,CAAUiF,CAAV,CAAX,CADT,EACwC,IADxC,CAIOm1B,CAPa,CAHQ,CAyBhCC,QAASA,GAAa,CAAC/zB,CAAD,CAAO2zB,CAAP,CAAgBK,CAAhB,CAAqB,CACzC,GAAIh+B,CAAA,CAAWg+B,CAAX,CAAJ,CACE,MAAOA,EAAA,CAAIh0B,CAAJ,CAAU2zB,CAAV,CAET/9B,EAAA,CAAQo+B,CAAR,CAAa,QAAQ,CAACl4B,CAAD,CAAK,CACxBkE,CAAA,CAAOlE,CAAA,CAAGkE,CAAH,CAAS2zB,CAAT,CADiB,CAA1B,CAIA,OAAO3zB,EARkC,CAuB3CyM,QAASA,GAAa,EAAG,CAAA,IACnBwnB,EAAa,kBADM,CAEnBC,EAAW,YAFQ,CAGnBC,EAAoB,cAHD,CAKnBC,EAAgC,CAAC,eAAgB,gCAAjB,CALb,CA4BnBC,EAAW,IAAAA,SAAXA,CAA2B,CAE7BC,kBAAmB,CAACC,QAAqC,CAACv0B,CAAD,CAAO2zB,CAAP,CAAgB,CACvE,GAAIj+B,CAAA,CAASsK,CAAT,CAAJ,CAAoB,CAElBA,CAAA,CAAOA,CAAA5C,QAAA,CAAa+2B,CAAb,CAAgC,EAAhC,CACP,KAAIK,EAAcb,CAAA,CAAQ,cAAR,CAClB,IAAKa,CAAL,EAA8D,CAA9D,GAAoBA,CAAA16B,QAAA,CA/BH26B,kBA+BG,CAApB,EACKR,CAAA9zB,KAAA,CAAgBH,CAAhB,CADL,EAC8Bk0B,CAAA/zB,KAAA,CAAcH,CAAd,CAD9B,CAEEA,CAAA;AAAOxD,EAAA,CAASwD,CAAT,CANS,CASpB,MAAOA,EAVgE,CAAtD,CAFU,CAgB7B00B,iBAAkB,CAAC,QAAQ,CAACC,CAAD,CAAI,CAC7B,MAAOr8B,EAAA,CAASq8B,CAAT,CAAA,EA7vPmB,eA6vPnB,GA7vPJl8B,EAAAvC,KAAA,CA6vP2By+B,CA7vP3B,CA6vPI,EAxvPmB,eAwvPnB,GAxvPJl8B,EAAAvC,KAAA,CAwvPyCy+B,CAxvPzC,CAwvPI,CAA0Cv4B,EAAA,CAAOu4B,CAAP,CAA1C,CAAsDA,CADhC,CAAb,CAhBW,CAqB7BhB,QAAS,CACPiB,OAAQ,CACN,OAAU,mCADJ,CADD,CAIPpM,KAAQztB,EAAA,CAAYq5B,CAAZ,CAJD,CAKPze,IAAQ5a,EAAA,CAAYq5B,CAAZ,CALD,CAMPS,MAAQ95B,EAAA,CAAYq5B,CAAZ,CAND,CArBoB,CA8B7BU,eAAgB,YA9Ba,CA+B7BC,eAAgB,cA/Ba,CA5BR,CA8DnBC,EAAgB,CAAA,CAoBpB,KAAAA,cAAA,CAAqBC,QAAQ,CAACr+B,CAAD,CAAQ,CACnC,MAAIyB,EAAA,CAAUzB,CAAV,CAAJ,EACEo+B,CACO,CADS,CAAEp+B,CAAAA,CACX,CAAA,IAFT,EAIOo+B,CAL4B,CAYrC,KAAIE,EAAuB,IAAAC,aAAvBD,CAA2C,EAE/C,KAAAne,KAAA,CAAY,CAAC,cAAD,CAAiB,UAAjB,CAA6B,eAA7B,CAA8C,YAA9C,CAA4D,IAA5D,CAAkE,WAAlE,CACR,QAAQ,CAACrK,CAAD,CAAelB,CAAf,CAAyBE,CAAzB,CAAwCwB,CAAxC,CAAoDE,CAApD,CAAwDuL,CAAxD,CAAmE,CAqgB7EnM,QAASA,EAAK,CAAC4oB,CAAD,CAAgB,CAqE5Bd,QAASA,EAAiB,CAACe,CAAD,CAAW,CAEnC,IAAIC;AAAOp+B,CAAA,CAAO,EAAP,CAAWm+B,CAAX,CAITC,EAAAt1B,KAAA,CAHGq1B,CAAAr1B,KAAL,CAGc+zB,EAAA,CAAcsB,CAAAr1B,KAAd,CAA6Bq1B,CAAA1B,QAA7B,CAA+Cl1B,CAAA61B,kBAA/C,CAHd,CACce,CAAAr1B,KAIIu1B,EAAAA,CAAAF,CAAAE,OAAlB,OA7rBC,IA6rBM,EA7rBCA,CA6rBD,EA7rBoB,GA6rBpB,CA7rBWA,CA6rBX,CACHD,CADG,CAEHloB,CAAAooB,OAAA,CAAUF,CAAV,CAV+B,CApErC,IAAI72B,EAAS,CACXyF,OAAQ,KADG,CAEXwwB,iBAAkBL,CAAAK,iBAFP,CAGXJ,kBAAmBD,CAAAC,kBAHR,CAAb,CAKIX,EA4EJ8B,QAAqB,CAACh3B,CAAD,CAAS,CAAA,IACxBi3B,EAAarB,CAAAV,QADW,CAExBgC,EAAaz+B,CAAA,CAAO,EAAP,CAAWuH,CAAAk1B,QAAX,CAFW,CAGxBiC,CAHwB,CAGeC,CAHf,CAK5BH,EAAax+B,CAAA,CAAO,EAAP,CAAWw+B,CAAAd,OAAX,CAA8Bc,CAAA,CAAWh8B,CAAA,CAAU+E,CAAAyF,OAAV,CAAX,CAA9B,CAGb,EAAA,CACA,IAAK0xB,CAAL,GAAsBF,EAAtB,CAAkC,CAChCI,CAAA,CAAyBp8B,CAAA,CAAUk8B,CAAV,CAEzB,KAAKC,CAAL,GAAsBF,EAAtB,CACE,GAAIj8B,CAAA,CAAUm8B,CAAV,CAAJ,GAAiCC,CAAjC,CACE,SAAS,CAIbH,EAAA,CAAWC,CAAX,CAAA,CAA4BF,CAAA,CAAWE,CAAX,CATI,CAgBlCG,SAAoB,CAACpC,CAAD,CAAU,CAC5B,IAAIqC,CAEJpgC,EAAA,CAAQ+9B,CAAR,CAAiB,QAAQ,CAACsC,CAAD,CAAWC,CAAX,CAAmB,CACtClgC,CAAA,CAAWigC,CAAX,CAAJ,GACED,CACA,CADgBC,CAAA,EAChB,CAAqB,IAArB,EAAID,CAAJ,CACErC,CAAA,CAAQuC,CAAR,CADF,CACoBF,CADpB,CAGE,OAAOrC,CAAA,CAAQuC,CAAR,CALX,CAD0C,CAA5C,CAH4B,CAA9BH,CAHA,CAAYJ,CAAZ,CACA,OAAOA,EAvBqB,CA5EhB,CAAaP,CAAb,CAEdl+B,EAAA,CAAOuH,CAAP,CAAe22B,CAAf,CACA32B,EAAAk1B,QAAA,CAAiBA,CACjBl1B,EAAAyF,OAAA,CAAgBmB,EAAA,CAAU5G,CAAAyF,OAAV,CAuBhB,KAAIiyB;AAAQ,CArBQC,QAAQ,CAAC33B,CAAD,CAAS,CACnCk1B,CAAA,CAAUl1B,CAAAk1B,QACV,KAAI0C,EAAUtC,EAAA,CAAct1B,CAAAuB,KAAd,CAA2B6zB,EAAA,CAAcF,CAAd,CAA3B,CAAmDl1B,CAAAi2B,iBAAnD,CAGVt8B,EAAA,CAAYi+B,CAAZ,CAAJ,EACEzgC,CAAA,CAAQ+9B,CAAR,CAAiB,QAAQ,CAAC/8B,CAAD,CAAQs/B,CAAR,CAAgB,CACb,cAA1B,GAAIx8B,CAAA,CAAUw8B,CAAV,CAAJ,EACI,OAAOvC,CAAA,CAAQuC,CAAR,CAF4B,CAAzC,CAOE99B,EAAA,CAAYqG,CAAA63B,gBAAZ,CAAJ,EAA4C,CAAAl+B,CAAA,CAAYi8B,CAAAiC,gBAAZ,CAA5C,GACE73B,CAAA63B,gBADF,CAC2BjC,CAAAiC,gBAD3B,CAKA,OAAOC,EAAA,CAAQ93B,CAAR,CAAgB43B,CAAhB,CAAyB1C,CAAzB,CAAA9F,KAAA,CAAuCyG,CAAvC,CAA0DA,CAA1D,CAlB4B,CAqBzB,CAAgBp/B,CAAhB,CAAZ,CACIshC,EAAUppB,CAAAqpB,KAAA,CAAQh4B,CAAR,CAYd,KATA7I,CAAA,CAAQ8gC,CAAR,CAA8B,QAAQ,CAACC,CAAD,CAAc,CAClD,CAAIA,CAAAC,QAAJ,EAA2BD,CAAAE,aAA3B,GACEV,CAAA72B,QAAA,CAAcq3B,CAAAC,QAAd,CAAmCD,CAAAE,aAAnC,CAEF,EAAIF,CAAAtB,SAAJ,EAA4BsB,CAAAG,cAA5B,GACEX,CAAA7/B,KAAA,CAAWqgC,CAAAtB,SAAX,CAAiCsB,CAAAG,cAAjC,CALgD,CAApD,CASA,CAAMX,CAAA5gC,OAAN,CAAA,CAAoB,CACdwhC,CAAAA,CAASZ,CAAA/d,MAAA,EACb,KAAI4e,EAAWb,CAAA/d,MAAA,EAAf,CAEAoe,EAAUA,CAAA3I,KAAA,CAAakJ,CAAb,CAAqBC,CAArB,CAJQ,CAOpBR,CAAAS,QAAA,CAAkBC,QAAQ,CAACp7B,CAAD,CAAK,CAC7B06B,CAAA3I,KAAA,CAAa,QAAQ,CAACwH,CAAD,CAAW,CAC9Bv5B,CAAA,CAAGu5B,CAAAr1B,KAAH;AAAkBq1B,CAAAE,OAAlB,CAAmCF,CAAA1B,QAAnC,CAAqDl1B,CAArD,CAD8B,CAAhC,CAGA,OAAO+3B,EAJsB,CAO/BA,EAAAnb,MAAA,CAAgB8b,QAAQ,CAACr7B,CAAD,CAAK,CAC3B06B,CAAA3I,KAAA,CAAa,IAAb,CAAmB,QAAQ,CAACwH,CAAD,CAAW,CACpCv5B,CAAA,CAAGu5B,CAAAr1B,KAAH,CAAkBq1B,CAAAE,OAAlB,CAAmCF,CAAA1B,QAAnC,CAAqDl1B,CAArD,CADoC,CAAtC,CAGA,OAAO+3B,EAJoB,CAO7B,OAAOA,EAnEqB,CAuQ9BD,QAASA,EAAO,CAAC93B,CAAD,CAAS43B,CAAT,CAAkBV,CAAlB,CAA8B,CA+D5CyB,QAASA,EAAI,CAAC7B,CAAD,CAASF,CAAT,CAAmBgC,CAAnB,CAAkCC,CAAlC,CAA8C,CAUzDC,QAASA,EAAkB,EAAG,CAC5BC,CAAA,CAAenC,CAAf,CAAyBE,CAAzB,CAAiC8B,CAAjC,CAAgDC,CAAhD,CAD4B,CAT1Bvf,CAAJ,GAv7BC,GAw7BC,EAAcwd,CAAd,EAx7ByB,GAw7BzB,CAAcA,CAAd,CACExd,CAAApC,IAAA,CAAUyG,CAAV,CAAe,CAACmZ,CAAD,CAASF,CAAT,CAAmB3B,EAAA,CAAa2D,CAAb,CAAnB,CAAgDC,CAAhD,CAAf,CADF,CAIEvf,CAAA2I,OAAA,CAAatE,CAAb,CALJ,CAaI4Y,EAAJ,CACE9nB,CAAAuqB,YAAA,CAAuBF,CAAvB,CADF,EAGEA,CAAA,EACA,CAAKrqB,CAAAwqB,QAAL,EAAyBxqB,CAAAnN,OAAA,EAJ3B,CAdyD,CA0B3Dy3B,QAASA,EAAc,CAACnC,CAAD,CAAWE,CAAX,CAAmB5B,CAAnB,CAA4B2D,CAA5B,CAAwC,CAE7D/B,CAAA,CAAS1I,IAAAC,IAAA,CAASyI,CAAT,CAAiB,CAAjB,CAET,EAp9BC,GAo9BA,EAAUA,CAAV,EAp9B0B,GAo9B1B,CAAUA,CAAV,CAAoBoC,CAAAC,QAApB,CAAuCD,CAAAnC,OAAxC,EAAyD,CACvDx1B,KAAMq1B,CADiD,CAEvDE,OAAQA,CAF+C,CAGvD5B,QAASE,EAAA,CAAcF,CAAd,CAH8C,CAIvDl1B,OAAQA,CAJ+C,CAKvD64B,WAAaA,CAL0C,CAAzD,CAJ6D,CAc/DO,QAASA,EAAgB,EAAG,CAC1B,IAAI7S,EAAMxY,CAAAsrB,gBAAAh+B,QAAA,CAA8B2E,CAA9B,CACG,GAAb,GAAIumB,CAAJ,EAAgBxY,CAAAsrB,gBAAA/9B,OAAA,CAA6BirB,CAA7B;AAAkC,CAAlC,CAFU,CAvGgB,IACxC2S,EAAWvqB,CAAAyR,MAAA,EAD6B,CAExC2X,EAAUmB,CAAAnB,QAF8B,CAGxCze,CAHwC,CAIxCggB,CAJwC,CAKxC3b,EAAM4b,CAAA,CAASv5B,CAAA2d,IAAT,CAAqB3d,CAAAw5B,OAArB,CAEVzrB,EAAAsrB,gBAAAxhC,KAAA,CAA2BmI,CAA3B,CACA+3B,EAAA3I,KAAA,CAAagK,CAAb,CAA+BA,CAA/B,CAGK9f,EAAAtZ,CAAAsZ,MAAL,EAAqBA,CAAAsc,CAAAtc,MAArB,EAAyD,CAAA,CAAzD,GAAwCtZ,CAAAsZ,MAAxC,EACuB,KADvB,GACKtZ,CAAAyF,OADL,EACkD,OADlD,GACgCzF,CAAAyF,OADhC,GAEE6T,CAFF,CAEUzf,CAAA,CAASmG,CAAAsZ,MAAT,CAAA,CAAyBtZ,CAAAsZ,MAAzB,CACAzf,CAAA,CAAS+7B,CAAAtc,MAAT,CAAA,CAA2Bsc,CAAAtc,MAA3B,CACAmgB,CAJV,CAOA,IAAIngB,CAAJ,CAEE,GADAggB,CACI,CADShgB,CAAAlX,IAAA,CAAUub,CAAV,CACT,CAAA/jB,CAAA,CAAU0/B,CAAV,CAAJ,CAA2B,CACzB,GAAkBA,CAAlB,EAnkRM/hC,CAAA,CAmkRY+hC,CAnkRDlK,KAAX,CAmkRN,CAGE,MADAkK,EAAAlK,KAAA,CAAgBgK,CAAhB,CAAkCA,CAAlC,CACOE,CAAAA,CAGHpiC,EAAA,CAAQoiC,CAAR,CAAJ,CACEP,CAAA,CAAeO,CAAA,CAAW,CAAX,CAAf,CAA8BA,CAAA,CAAW,CAAX,CAA9B,CAA6Ch9B,EAAA,CAAYg9B,CAAA,CAAW,CAAX,CAAZ,CAA7C,CAAyEA,CAAA,CAAW,CAAX,CAAzE,CADF,CAGEP,CAAA,CAAeO,CAAf,CAA2B,GAA3B,CAAgC,EAAhC,CAAoC,IAApC,CAVqB,CAA3B,IAeEhgB,EAAApC,IAAA,CAAUyG,CAAV,CAAeoa,CAAf,CAOAp+B,EAAA,CAAY2/B,CAAZ,CAAJ,GAQE,CAPII,CAOJ,CAPgBC,EAAA,CAAgB35B,CAAA2d,IAAhB,CAAA,CACV5Q,CAAA8S,QAAA,EAAA,CAAmB7f,CAAAq2B,eAAnB,EAA4CT,CAAAS,eAA5C,CADU,CAEV5/B,CAKN,IAHEygC,CAAA,CAAYl3B,CAAAs2B,eAAZ,EAAqCV,CAAAU,eAArC,CAGF,CAHmEoD,CAGnE,EAAAzrB,CAAA,CAAajO,CAAAyF,OAAb,CAA4BkY,CAA5B,CAAiCia,CAAjC,CAA0Ce,CAA1C,CAAgDzB,CAAhD,CAA4Dl3B,CAAA45B,QAA5D,CACI55B,CAAA63B,gBADJ,CAC4B73B,CAAA65B,aAD5B,CARF,CAYA;MAAO9B,EAtDqC,CA8G9CwB,QAASA,EAAQ,CAAC5b,CAAD,CAAM6b,CAAN,CAAc,CAC7B,GAAKA,CAAAA,CAAL,CAAa,MAAO7b,EACpB,KAAIze,EAAQ,EACZnH,GAAA,CAAcyhC,CAAd,CAAsB,QAAQ,CAACrhC,CAAD,CAAQb,CAAR,CAAa,CAC3B,IAAd,GAAIa,CAAJ,EAAsBwB,CAAA,CAAYxB,CAAZ,CAAtB,GACKjB,CAAA,CAAQiB,CAAR,CAEL,GAFqBA,CAErB,CAF6B,CAACA,CAAD,CAE7B,EAAAhB,CAAA,CAAQgB,CAAR,CAAe,QAAQ,CAAC2hC,CAAD,CAAI,CACrBjgC,CAAA,CAASigC,CAAT,CAAJ,GAEIA,CAFJ,CACM//B,EAAA,CAAO+/B,CAAP,CAAJ,CACMA,CAAAC,YAAA,EADN,CAGMp8B,EAAA,CAAOm8B,CAAP,CAJR,CAOA56B,EAAArH,KAAA,CAAWuH,EAAA,CAAe9H,CAAf,CAAX,CAAiC,GAAjC,CACW8H,EAAA,CAAe06B,CAAf,CADX,CARyB,CAA3B,CAHA,CADyC,CAA3C,CAgBkB,EAAlB,CAAG56B,CAAApI,OAAH,GACE6mB,CADF,GACgC,EAAtB,EAACA,CAAAtiB,QAAA,CAAY,GAAZ,CAAD,CAA2B,GAA3B,CAAiC,GAD3C,EACkD6D,CAAAG,KAAA,CAAW,GAAX,CADlD,CAGA,OAAOse,EAtBsB,CAx3B/B,IAAI8b,EAAexsB,CAAA,CAAc,OAAd,CAAnB,CAOIgrB,EAAuB,EAE3B9gC,EAAA,CAAQs/B,CAAR,CAA8B,QAAQ,CAACuD,CAAD,CAAqB,CACzD/B,CAAAp3B,QAAA,CAA6B5J,CAAA,CAAS+iC,CAAT,CAAA,CACvB9f,CAAA9X,IAAA,CAAc43B,CAAd,CADuB,CACa9f,CAAAhZ,OAAA,CAAiB84B,CAAjB,CAD1C,CADyD,CAA3D,CAsnBAjsB,EAAAsrB,gBAAA,CAAwB,EA4GxBY,UAA2B,CAACvlB,CAAD,CAAQ,CACjCvd,CAAA,CAAQyB,SAAR,CAAmB,QAAQ,CAACsH,CAAD,CAAO,CAChC6N,CAAA,CAAM7N,CAAN,CAAA,CAAc,QAAQ,CAACyd,CAAD,CAAM3d,CAAN,CAAc,CAClC,MAAO+N,EAAA,CAAMtV,CAAA,CAAOuH,CAAP,EAAiB,EAAjB,CAAqB,CAChCyF,OAAQvF,CADwB,CAEhCyd,IAAKA,CAF2B,CAArB,CAAN,CAD2B,CADJ,CAAlC,CADiC,CAAnCsc,CA1DA,CAAmB,KAAnB,CAA0B,QAA1B,CAAoC,MAApC,CAA4C,OAA5C,CAsEAC,UAAmC,CAACh6B,CAAD,CAAO,CACxC/I,CAAA,CAAQyB,SAAR,CAAmB,QAAQ,CAACsH,CAAD,CAAO,CAChC6N,CAAA,CAAM7N,CAAN,CAAA;AAAc,QAAQ,CAACyd,CAAD,CAAMpc,CAAN,CAAYvB,CAAZ,CAAoB,CACxC,MAAO+N,EAAA,CAAMtV,CAAA,CAAOuH,CAAP,EAAiB,EAAjB,CAAqB,CAChCyF,OAAQvF,CADwB,CAEhCyd,IAAKA,CAF2B,CAGhCpc,KAAMA,CAH0B,CAArB,CAAN,CADiC,CADV,CAAlC,CADwC,CAA1C24B,CA9BA,CAA2B,MAA3B,CAAmC,KAAnC,CAA0C,OAA1C,CAYAnsB,EAAA6nB,SAAA,CAAiBA,CAGjB,OAAO7nB,EA1uBsE,CADnE,CAhGW,CAs/BzBosB,QAASA,GAAS,EAAG,CACjB,MAAO,KAAI5jC,CAAA6jC,eADM,CAoBrBlsB,QAASA,GAAoB,EAAG,CAC9B,IAAAoK,KAAA,CAAY,CAAC,UAAD,CAAa,SAAb,CAAwB,WAAxB,CAAqC,QAAQ,CAACvL,CAAD,CAAW8C,CAAX,CAAoBxC,CAApB,CAA+B,CACtF,MAAOgtB,GAAA,CAAkBttB,CAAlB,CAA4BotB,EAA5B,CAAuCptB,CAAAqT,MAAvC,CAAuDvQ,CAAAlO,QAAA24B,UAAvD,CAAkFjtB,CAAA,CAAU,CAAV,CAAlF,CAD+E,CAA5E,CADkB,CAMhCgtB,QAASA,GAAiB,CAACttB,CAAD,CAAWotB,CAAX,CAAsBI,CAAtB,CAAqCD,CAArC,CAAgDtc,CAAhD,CAA6D,CA4GrFwc,QAASA,EAAQ,CAAC7c,CAAD,CAAM8c,CAAN,CAAkB9B,CAAlB,CAAwB,CAAA,IAInC/wB,EAASoW,CAAA/M,cAAA,CAA0B,QAA1B,CAJ0B,CAIWwN,EAAW,IAC7D7W,EAAAiL,KAAA,CAAc,iBACdjL,EAAArL,IAAA,CAAaohB,CACb/V,EAAA8yB,MAAA,CAAe,CAAA,CAEfjc,EAAA,CAAWA,QAAQ,CAAC1I,CAAD,CAAQ,CACHnO,CA1pOtBuL,oBAAA,CA0pO8BN,MA1pO9B,CA0pOsC4L,CA1pOtC,CAAsC,CAAA,CAAtC,CA2pOsB7W,EA3pOtBuL,oBAAA,CA2pO8BN,OA3pO9B,CA2pOuC4L,CA3pOvC,CAAsC,CAAA,CAAtC,CA4pOAT,EAAA2c,KAAA5lB,YAAA,CAA6BnN,CAA7B,CACAA;CAAA,CAAS,IACT,KAAIkvB,EAAU,EAAd,CACI9G,EAAO,SAEPja,EAAJ,GACqB,MAInB,GAJIA,CAAAlD,KAIJ,EAJ8BynB,CAAA,CAAUG,CAAV,CAAAG,OAI9B,GAHE7kB,CAGF,CAHU,CAAElD,KAAM,OAAR,CAGV,EADAmd,CACA,CADOja,CAAAlD,KACP,CAAAikB,CAAA,CAAwB,OAAf,GAAA/gB,CAAAlD,KAAA,CAAyB,GAAzB,CAA+B,GAL1C,CAQI8lB,EAAJ,EACEA,CAAA,CAAK7B,CAAL,CAAa9G,CAAb,CAjBuB,CAqBRpoB,EAjrOjBizB,iBAAA,CAirOyBhoB,MAjrOzB,CAirOiC4L,CAjrOjC,CAAmC,CAAA,CAAnC,CAkrOiB7W,EAlrOjBizB,iBAAA,CAkrOyBhoB,OAlrOzB,CAkrOkC4L,CAlrOlC,CAAmC,CAAA,CAAnC,CAmrOFT,EAAA2c,KAAA3pB,YAAA,CAA6BpJ,CAA7B,CACA,OAAO6W,EAjCgC,CA1GzC,MAAO,SAAQ,CAAChZ,CAAD,CAASkY,CAAT,CAAcoM,CAAd,CAAoBtL,CAApB,CAA8ByW,CAA9B,CAAuC0E,CAAvC,CAAgD/B,CAAhD,CAAiEgC,CAAjE,CAA+E,CA2F5FiB,QAASA,EAAc,EAAG,CACxBC,CAAA,EAAaA,CAAA,EACbC,EAAA,EAAOA,CAAAC,MAAA,EAFiB,CAK1BC,QAASA,EAAe,CAACzc,CAAD,CAAWqY,CAAX,CAAmBF,CAAnB,CAA6BgC,CAA7B,CAA4CC,CAA5C,CAAwD,CAE9EtY,CAAA,EAAaga,CAAA/Z,OAAA,CAAqBD,CAArB,CACbwa,EAAA,CAAYC,CAAZ,CAAkB,IAElBvc,EAAA,CAASqY,CAAT,CAAiBF,CAAjB,CAA2BgC,CAA3B,CAA0CC,CAA1C,CACA9rB,EAAAqR,6BAAA,CAAsC7kB,CAAtC,CAN8E,CA/FhFwT,CAAAsR,6BAAA,EACAV,EAAA,CAAMA,CAAN,EAAa5Q,CAAA4Q,IAAA,EAEb,IAAyB,OAAzB,EAAI1iB,CAAA,CAAUwK,CAAV,CAAJ,CAAkC,CAChC,IAAIg1B,EAAa,GAAbA,CAAmBzgC,CAACsgC,CAAAzzB,QAAA,EAAD7M,UAAA,CAA+B,EAA/B,CACvBsgC,EAAA,CAAUG,CAAV,CAAA,CAAwB,QAAQ,CAACl5B,CAAD,CAAO,CACrC+4B,CAAA,CAAUG,CAAV,CAAAl5B,KAAA;AAA6BA,CAC7B+4B,EAAA,CAAUG,CAAV,CAAAG,OAAA,CAA+B,CAAA,CAFM,CAKvC,KAAIG,EAAYP,CAAA,CAAS7c,CAAAhf,QAAA,CAAY,eAAZ,CAA6B,oBAA7B,CAAoD87B,CAApD,CAAT,CACZA,CADY,CACA,QAAQ,CAAC3D,CAAD,CAAS9G,CAAT,CAAe,CACrCkL,CAAA,CAAgBzc,CAAhB,CAA0BqY,CAA1B,CAAkCwD,CAAA,CAAUG,CAAV,CAAAl5B,KAAlC,CAA8D,EAA9D,CAAkEyuB,CAAlE,CACAsK,EAAA,CAAUG,CAAV,CAAA,CAAwBlhC,CAFa,CADvB,CAPgB,CAAlC,IAYO,CAEL,IAAIyhC,EAAMb,CAAA,EAEVa,EAAAG,KAAA,CAAS11B,CAAT,CAAiBkY,CAAjB,CAAsB,CAAA,CAAtB,CACAxmB,EAAA,CAAQ+9B,CAAR,CAAiB,QAAQ,CAAC/8B,CAAD,CAAQb,CAAR,CAAa,CAChCsC,CAAA,CAAUzB,CAAV,CAAJ,EACI6iC,CAAAI,iBAAA,CAAqB9jC,CAArB,CAA0Ba,CAA1B,CAFgC,CAAtC,CAMA6iC,EAAAK,OAAA,CAAaC,QAAsB,EAAG,CACpC,IAAIzC,EAAamC,CAAAnC,WAAbA,EAA+B,EAAnC,CAIIjC,EAAY,UAAD,EAAeoE,EAAf,CAAsBA,CAAApE,SAAtB,CAAqCoE,CAAAO,aAJpD,CAOIzE,EAAwB,IAAf,GAAAkE,CAAAlE,OAAA,CAAsB,GAAtB,CAA4BkE,CAAAlE,OAK1B,EAAf,GAAIA,CAAJ,GACEA,CADF,CACWF,CAAA,CAAW,GAAX,CAA6C,MAA5B,EAAA4E,EAAA,CAAW7d,CAAX,CAAA8d,SAAA,CAAqC,GAArC,CAA2C,CADvE,CAIAP,EAAA,CAAgBzc,CAAhB,CACIqY,CADJ,CAEIF,CAFJ,CAGIoE,CAAAU,sBAAA,EAHJ,CAII7C,CAJJ,CAjBoC,CAwBlCT,EAAAA,CAAeA,QAAS,EAAG,CAG7B8C,CAAA,CAAgBzc,CAAhB,CAA2B,EAA3B,CAA8B,IAA9B,CAAoC,IAApC,CAA0C,EAA1C,CAH6B,CAM/Buc,EAAAW,QAAA,CAAcvD,CACd4C,EAAAY,QAAA,CAAcxD,CAEVP,EAAJ,GACEmD,CAAAnD,gBADF,CACwB,CAAA,CADxB,CAIA,IAAIgC,CAAJ,CACE,GAAI,CACFmB,CAAAnB,aAAA;AAAmBA,CADjB,CAEF,MAAOv7B,CAAP,CAAU,CAQV,GAAqB,MAArB,GAAIu7B,CAAJ,CACE,KAAMv7B,EAAN,CATQ,CAcd08B,CAAAa,KAAA,CAAS9R,CAAT,EAAiB,IAAjB,CAjEK,CAoEP,GAAc,CAAd,CAAI6P,CAAJ,CACE,IAAIrZ,EAAYga,CAAA,CAAcO,CAAd,CAA8BlB,CAA9B,CADlB,KAEyBA,EAAlB,EAzyRKriC,CAAA,CAyyRaqiC,CAzyRFxK,KAAX,CAyyRL,EACLwK,CAAAxK,KAAA,CAAa0L,CAAb,CAvF0F,CAFT,CAsLvFltB,QAASA,GAAoB,EAAG,CAC9B,IAAI2lB,EAAc,IAAlB,CACIC,EAAY,IAWhB,KAAAD,YAAA,CAAmBuI,QAAQ,CAAC3jC,CAAD,CAAO,CAChC,MAAIA,EAAJ,EACEo7B,CACO,CADOp7B,CACP,CAAA,IAFT,EAISo7B,CALuB,CAkBlC,KAAAC,UAAA,CAAiBuI,QAAQ,CAAC5jC,CAAD,CAAO,CAC9B,MAAIA,EAAJ,EACEq7B,CACO,CADKr7B,CACL,CAAA,IAFT,EAISq7B,CALqB,CAUhC,KAAAlb,KAAA,CAAY,CAAC,QAAD,CAAW,mBAAX,CAAgC,MAAhC,CAAwC,QAAQ,CAAC/J,CAAD,CAAShB,CAAT,CAA4BwB,CAA5B,CAAkC,CAM5FitB,QAASA,EAAM,CAACC,CAAD,CAAK,CAClB,MAAO,QAAP,CAAkBA,CADA,CAkGpBtuB,QAASA,EAAY,CAACqiB,CAAD,CAAOkM,CAAP,CAA2BC,CAA3B,CAA2CnL,CAA3C,CAAyD,CAgH5EoL,QAASA,EAAY,CAACpM,CAAD,CAAO,CAC1B,MAAOA,EAAArxB,QAAA,CAAa09B,CAAb,CAAiC9I,CAAjC,CAAA50B,QAAA,CACG29B,CADH,CACqB9I,CADrB,CADmB,CAK5B+I,QAASA,EAAyB,CAACpkC,CAAD,CAAQ,CACxC,GAAI,CACK,IAAA,CAAU,KAAA,EA/DVgkC,CAAA,CACLptB,CAAAytB,WAAA,CAAgBL,CAAhB,CA8DwBhkC,CA9DxB,CADK,CAEL4W,CAAA0tB,QAAA,CA6DwBtkC,CA7DxB,CAIF,IAAa,IAAb,EAAIA,CAAJ,CACE,CAAA,CAAO,EADT,KAAA,CAGA,OAAQ,MAAOA,EAAf,EACE,KAAK,QAAL,CACE,KACF;KAAK,QAAL,CACEA,CAAA,CAAQ,EAAR,CAAaA,CACb,MACF,SACEA,CAAA,CAAQwF,EAAA,CAAOxF,CAAP,CAPZ,CAUA,CAAA,CAAOA,CAbP,CAyDA,MAAO,EADL,CAEF,MAAMuhB,CAAN,CAAW,CACPgjB,CAEJ,CAFaC,EAAA,CAAmB,QAAnB,CAA4D3M,CAA5D,CACXtW,CAAA1f,SAAA,EADW,CAEb,CAAAuT,CAAA,CAAkBmvB,CAAlB,CAHW,CAH2B,CApH1C1L,CAAA,CAAe,CAAEA,CAAAA,CAWjB,KAZ4E,IAExEzzB,CAFwE,CAGxEq/B,CAHwE,CAIxExhC,EAAQ,CAJgE,CAKxEq1B,EAAc,EAL0D,CAMxEoM,EAAW,EAN6D,CAOxEC,EAAa9M,CAAAl5B,OAP2D,CASxEiG,EAAS,EAT+D,CAUxEggC,EAAsB,EAE1B,CAAM3hC,CAAN,CAAc0hC,CAAd,CAAA,CACE,GAA0D,EAA1D,GAAOv/B,CAAP,CAAoByyB,CAAA30B,QAAA,CAAak4B,CAAb,CAA0Bn4B,CAA1B,CAApB,GAC+E,EAD/E,GACOwhC,CADP,CACkB5M,CAAA30B,QAAA,CAAam4B,CAAb,CAAwBj2B,CAAxB,CAAqCy/B,CAArC,CADlB,EAEM5hC,CAQJ,GARcmC,CAQd,EAPER,CAAAlF,KAAA,CAAYukC,CAAA,CAAapM,CAAA7P,UAAA,CAAe/kB,CAAf,CAAsBmC,CAAtB,CAAb,CAAZ,CAOF,CALA0/B,CAKA,CALMjN,CAAA7P,UAAA,CAAe5iB,CAAf,CAA4By/B,CAA5B,CAA+CJ,CAA/C,CAKN,CAJAnM,CAAA54B,KAAA,CAAiBolC,CAAjB,CAIA,CAHAJ,CAAAhlC,KAAA,CAAc0W,CAAA,CAAO0uB,CAAP,CAAYV,CAAZ,CAAd,CAGA,CAFAnhC,CAEA,CAFQwhC,CAER,CAFmBM,CAEnB,CADAH,CAAAllC,KAAA,CAAyBkF,CAAAjG,OAAzB,CACA,CAAAiG,CAAAlF,KAAA,CAAY,EAAZ,CAVF,KAWO,CAEDuD,CAAJ,GAAc0hC,CAAd,EACE//B,CAAAlF,KAAA,CAAYukC,CAAA,CAAapM,CAAA7P,UAAA,CAAe/kB,CAAf,CAAb,CAAZ,CAEF,MALK,CAeT,GAAI+gC,CAAJ,EAAsC,CAAtC,CAAsBp/B,CAAAjG,OAAtB,CACI,KAAM6lC,GAAA,CAAmB,UAAnB,CAGsD3M,CAHtD,CAAN,CAMJ,GAAKkM,CAAAA,CAAL,EAA2BzL,CAAA35B,OAA3B,CAA+C,CAC7C,IAAIqmC,EAAUA,QAAQ,CAACnJ,CAAD,CAAS,CAC7B,IAD6B,IACrBh8B,EAAI,CADiB,CACdW,EAAK83B,CAAA35B,OAApB,CAAwCkB,CAAxC,CAA4CW,CAA5C,CAAgDX,CAAA,EAAhD,CAAqD,CACnD,GAAIg5B,CAAJ,EAAoBr3B,CAAA,CAAYq6B,CAAA,CAAOh8B,CAAP,CAAZ,CAApB,CAA4C,MAC5C+E,EAAA,CAAOggC,CAAA,CAAoB/kC,CAApB,CAAP,CAAA;AAAiCg8B,CAAA,CAAOh8B,CAAP,CAFkB,CAIrD,MAAO+E,EAAAsC,KAAA,CAAY,EAAZ,CALsB,CA+B/B,OAAO5G,EAAA,CAAO2kC,QAAwB,CAAC/lC,CAAD,CAAU,CAC5C,IAAIW,EAAI,CAAR,CACIW,EAAK83B,CAAA35B,OADT,CAEIk9B,EAAa/Y,KAAJ,CAAUtiB,CAAV,CAEb,IAAI,CACF,IAAA,CAAOX,CAAP,CAAWW,CAAX,CAAeX,CAAA,EAAf,CACEg8B,CAAA,CAAOh8B,CAAP,CAAA,CAAY6kC,CAAA,CAAS7kC,CAAT,CAAA,CAAYX,CAAZ,CAGd,OAAO8lC,EAAA,CAAQnJ,CAAR,CALL,CAMF,MAAMta,CAAN,CAAW,CACPgjB,CAEJ,CAFaC,EAAA,CAAmB,QAAnB,CAA4D3M,CAA5D,CACTtW,CAAA1f,SAAA,EADS,CAEb,CAAAuT,CAAA,CAAkBmvB,CAAlB,CAHW,CAX+B,CAAzC,CAiBF,CAEHO,IAAKjN,CAFF,CAGHS,YAAaA,CAHV,CAIH4M,gBAAiBA,QAAS,CAACj8B,CAAD,CAAQ0c,CAAR,CAAkBwf,CAAlB,CAAkC,CAC1D,IAAI9R,CACJ,OAAOpqB,EAAAm8B,YAAA,CAAkBV,CAAlB,CAA4BW,QAA6B,CAACxJ,CAAD,CAASyJ,CAAT,CAAoB,CAClF,IAAIC,EAAYP,CAAA,CAAQnJ,CAAR,CACZz8B,EAAA,CAAWumB,CAAX,CAAJ,EACEA,CAAArmB,KAAA,CAAc,IAAd,CAAoBimC,CAApB,CAA+B1J,CAAA,GAAWyJ,CAAX,CAAuBjS,CAAvB,CAAmCkS,CAAlE,CAA6Et8B,CAA7E,CAEFoqB,EAAA,CAAYkS,CALsE,CAA7E,CAMJJ,CANI,CAFmD,CAJzD,CAjBE,CAhCsC,CA9C6B,CAxGc,IACxFN,EAAoBzJ,CAAAz8B,OADoE,CAExFomC,EAAkB1J,CAAA18B,OAFsE,CAGxFulC,EAAqB,IAAIrgC,MAAJ,CAAWu3B,CAAA50B,QAAA,CAAoB,IAApB,CAA0Bq9B,CAA1B,CAAX,CAA8C,GAA9C,CAHmE,CAIxFM,EAAmB,IAAItgC,MAAJ,CAAWw3B,CAAA70B,QAAA,CAAkB,IAAlB,CAAwBq9B,CAAxB,CAAX,CAA4C,GAA5C,CAgPvBruB,EAAA4lB,YAAA,CAA2BoK,QAAQ,EAAG,CACpC,MAAOpK,EAD6B,CAgBtC5lB,EAAA6lB,UAAA,CAAyBoK,QAAQ,EAAG,CAClC,MAAOpK,EAD2B,CAIpC,OAAO7lB,EAxQqF,CAAlF,CAzCkB,CAqThCG,QAASA,GAAiB,EAAG,CAC3B,IAAAwK,KAAA;AAAY,CAAC,YAAD,CAAe,SAAf,CAA0B,IAA1B,CAAgC,KAAhC,CACP,QAAQ,CAAC7J,CAAD,CAAeoB,CAAf,CAA0BlB,CAA1B,CAAgCE,CAAhC,CAAqC,CAgIhDiO,QAASA,EAAQ,CAACzf,CAAD,CAAKijB,CAAL,CAAYud,CAAZ,CAAmBC,CAAnB,CAAgC,CAAA,IAC3CC,EAAcluB,CAAAkuB,YAD6B,CAE3CC,EAAgBnuB,CAAAmuB,cAF2B,CAG3CC,EAAY,CAH+B,CAI3CC,EAAatkC,CAAA,CAAUkkC,CAAV,CAAbI,EAAuC,CAACJ,CAJG,CAK3C5E,EAAW9Y,CAAC8d,CAAA,CAAYrvB,CAAZ,CAAkBF,CAAnByR,OAAA,EALgC,CAM3C2X,EAAUmB,CAAAnB,QAEd8F,EAAA,CAAQjkC,CAAA,CAAUikC,CAAV,CAAA,CAAmBA,CAAnB,CAA2B,CAEnC9F,EAAA3I,KAAA,CAAa,IAAb,CAAmB,IAAnB,CAAyB/xB,CAAzB,CAEA06B,EAAAoG,aAAA,CAAuBJ,CAAA,CAAYK,QAAa,EAAG,CACjDlF,CAAAmF,OAAA,CAAgBJ,CAAA,EAAhB,CAEY,EAAZ,CAAIJ,CAAJ,EAAiBI,CAAjB,EAA8BJ,CAA9B,GACE3E,CAAAC,QAAA,CAAiB8E,CAAjB,CAEA,CADAD,CAAA,CAAcjG,CAAAoG,aAAd,CACA,CAAA,OAAOG,CAAA,CAAUvG,CAAAoG,aAAV,CAHT,CAMKD,EAAL,EAAgBzvB,CAAAnN,OAAA,EATiC,CAA5B,CAWpBgf,CAXoB,CAavBge,EAAA,CAAUvG,CAAAoG,aAAV,CAAA,CAAkCjF,CAElC,OAAOnB,EA3BwC,CA/HjD,IAAIuG,EAAY,EAwKhBxhB,EAAA0D,OAAA,CAAkB+d,QAAQ,CAACxG,CAAD,CAAU,CAClC,MAAIA,EAAJ,EAAeA,CAAAoG,aAAf,GAAuCG,EAAvC,EACEA,CAAA,CAAUvG,CAAAoG,aAAV,CAAApH,OAAA,CAAuC,UAAvC,CAGO,CAFPlnB,CAAAmuB,cAAA,CAAsBjG,CAAAoG,aAAtB,CAEO,CADP,OAAOG,CAAA,CAAUvG,CAAAoG,aAAV,CACA,CAAA,CAAA,CAJT;AAMO,CAAA,CAP2B,CAUpC,OAAOrhB,EAnLyC,CADtC,CADe,CAmM7B9V,QAASA,GAAe,EAAE,CACxB,IAAAsR,KAAA,CAAYqI,QAAQ,EAAG,CACrB,MAAO,CACLgB,GAAI,OADC,CAGL6c,eAAgB,CACdC,YAAa,GADC,CAEdC,UAAW,GAFG,CAGdC,SAAU,CACR,CACEC,OAAQ,CADV,CAEEC,QAAS,CAFX,CAGEC,QAAS,CAHX,CAIEC,OAAQ,EAJV,CAKEC,OAAQ,EALV,CAMEC,OAAQ,GANV,CAOEC,OAAQ,EAPV,CAQEC,MAAO,CART,CASEC,OAAQ,CATV,CADQ,CAWN,CACAR,OAAQ,CADR,CAEAC,QAAS,CAFT,CAGAC,QAAS,CAHT,CAIAC,OAAQ,QAJR,CAKAC,OAAQ,EALR,CAMAC,OAAQ,SANR,CAOAC,OAAQ,GAPR,CAQAC,MAAO,CARP,CASAC,OAAQ,CATR,CAXM,CAHI,CA0BdC,aAAc,GA1BA,CAHX,CAgCLC,iBAAkB,CAChBC,MACI,uFAAA,MAAA,CAAA,GAAA,CAFY,CAIhBC,WAAa,iDAAA,MAAA,CAAA,GAAA,CAJG;AAKhBC,IAAK,0DAAA,MAAA,CAAA,GAAA,CALW,CAMhBC,SAAU,6BAAA,MAAA,CAAA,GAAA,CANM,CAOhBC,MAAO,CAAC,IAAD,CAAM,IAAN,CAPS,CAQhBC,OAAQ,oBARQ,CAShBC,MAAO,eATS,CAUhBC,SAAU,iBAVM,CAWhBC,SAAU,WAXM,CAYhBC,WAAY,UAZI,CAahBC,UAAW,QAbK,CAchBC,WAAY,WAdI,CAehBC,UAAW,QAfK,CAhCb,CAkDLC,UAAWA,QAAQ,CAACC,CAAD,CAAM,CACvB,MAAY,EAAZ,GAAIA,CAAJ,CACS,KADT,CAGO,OAJgB,CAlDpB,CADc,CADC,CAyE1BC,QAASA,GAAU,CAACh8B,CAAD,CAAO,CACpBi8B,CAAAA,CAAWj8B,CAAAxJ,MAAA,CAAW,GAAX,CAGf,KAHA,IACI9C,EAAIuoC,CAAAzpC,OAER,CAAOkB,CAAA,EAAP,CAAA,CACEuoC,CAAA,CAASvoC,CAAT,CAAA,CAAcsH,EAAA,CAAiBihC,CAAA,CAASvoC,CAAT,CAAjB,CAGhB,OAAOuoC,EAAAlhC,KAAA,CAAc,GAAd,CARiB,CAW1BmhC,QAASA,GAAgB,CAACC,CAAD,CAAcC,CAAd,CAA2BC,CAA3B,CAAoC,CACvDC,CAAAA,CAAYpF,EAAA,CAAWiF,CAAX,CAAwBE,CAAxB,CAEhBD,EAAAG,WAAA;AAAyBD,CAAAnF,SACzBiF,EAAAI,OAAA,CAAqBF,CAAAG,SACrBL,EAAAM,OAAA,CAAqBhoC,EAAA,CAAI4nC,CAAAK,KAAJ,CAArB,EAA4CC,EAAA,CAAcN,CAAAnF,SAAd,CAA5C,EAAiF,IALtB,CAS7D0F,QAASA,GAAW,CAACC,CAAD,CAAcV,CAAd,CAA2BC,CAA3B,CAAoC,CACtD,IAAIU,EAAsC,GAAtCA,GAAYD,CAAA5kC,OAAA,CAAmB,CAAnB,CACZ6kC,EAAJ,GACED,CADF,CACgB,GADhB,CACsBA,CADtB,CAGInlC,EAAAA,CAAQu/B,EAAA,CAAW4F,CAAX,CAAwBT,CAAxB,CACZD,EAAAY,OAAA,CAAqBziC,kBAAA,CAAmBwiC,CAAA,EAAyC,GAAzC,GAAYplC,CAAAslC,SAAA/kC,OAAA,CAAsB,CAAtB,CAAZ,CACpCP,CAAAslC,SAAAphB,UAAA,CAAyB,CAAzB,CADoC,CACNlkB,CAAAslC,SADb,CAErBb,EAAAc,SAAA,CAAuB1iC,EAAA,CAAc7C,CAAAwlC,OAAd,CACvBf,EAAAgB,OAAA,CAAqB7iC,kBAAA,CAAmB5C,CAAA6f,KAAnB,CAGjB4kB,EAAAY,OAAJ,EAA0D,GAA1D,EAA0BZ,CAAAY,OAAA9kC,OAAA,CAA0B,CAA1B,CAA1B,GACEkkC,CAAAY,OADF,CACuB,GADvB,CAC6BZ,CAAAY,OAD7B,CAZsD,CAyBxDK,QAASA,GAAU,CAACC,CAAD,CAAQC,CAAR,CAAe,CAChC,GAA6B,CAA7B,GAAIA,CAAAxmC,QAAA,CAAcumC,CAAd,CAAJ,CACE,MAAOC,EAAAnZ,OAAA,CAAakZ,CAAA9qC,OAAb,CAFuB,CAOlCooB,QAASA,GAAS,CAACvB,CAAD,CAAM,CACtB,IAAIviB,EAAQuiB,CAAAtiB,QAAA,CAAY,GAAZ,CACZ,OAAiB,EAAV,EAAAD,CAAA,CAAcuiB,CAAd,CAAoBA,CAAA+K,OAAA,CAAW,CAAX,CAActtB,CAAd,CAFL,CAMxB0mC,QAASA,GAAS,CAACnkB,CAAD,CAAM,CACtB,MAAOA,EAAA+K,OAAA,CAAW,CAAX;AAAcxJ,EAAA,CAAUvB,CAAV,CAAAokB,YAAA,CAA2B,GAA3B,CAAd,CAAgD,CAAhD,CADe,CAkBxBC,QAASA,GAAgB,CAACrB,CAAD,CAAUsB,CAAV,CAAsB,CAC7C,IAAAC,QAAA,CAAe,CAAA,CACfD,EAAA,CAAaA,CAAb,EAA2B,EAC3B,KAAIE,EAAgBL,EAAA,CAAUnB,CAAV,CACpBH,GAAA,CAAiBG,CAAjB,CAA0B,IAA1B,CAAgCA,CAAhC,CAQA,KAAAyB,QAAA,CAAeC,QAAQ,CAAC1kB,CAAD,CAAM,CAC3B,IAAI2kB,EAAUX,EAAA,CAAWQ,CAAX,CAA0BxkB,CAA1B,CACd,IAAK,CAAA1mB,CAAA,CAASqrC,CAAT,CAAL,CACE,KAAMC,GAAA,CAAgB,UAAhB,CAA6E5kB,CAA7E,CACFwkB,CADE,CAAN,CAIFhB,EAAA,CAAYmB,CAAZ,CAAqB,IAArB,CAA2B3B,CAA3B,CAEK,KAAAW,OAAL,GACE,IAAAA,OADF,CACgB,GADhB,CAIA,KAAAkB,UAAA,EAb2B,CAoB7B,KAAAA,UAAA,CAAiBC,QAAQ,EAAG,CAAA,IACtBhB,EAASxiC,EAAA,CAAW,IAAAuiC,SAAX,CADa,CAEtB1lB,EAAO,IAAA4lB,OAAA,CAAc,GAAd,CAAoBpiC,EAAA,CAAiB,IAAAoiC,OAAjB,CAApB,CAAoD,EAE/D,KAAAgB,MAAA,CAAapC,EAAA,CAAW,IAAAgB,OAAX,CAAb,EAAwCG,CAAA,CAAS,GAAT,CAAeA,CAAf,CAAwB,EAAhE,EAAsE3lB,CACtE,KAAA6mB,SAAA,CAAgBR,CAAhB,CAAgC,IAAAO,MAAAha,OAAA,CAAkB,CAAlB,CALN,CAQ5B,KAAAka,eAAA,CAAsBC,QAAQ,CAACllB,CAAD,CAAMmlB,CAAN,CAAe,CAC3C,GAAIA,CAAJ,EAA8B,GAA9B,GAAeA,CAAA,CAAQ,CAAR,CAAf,CAIE,MADA,KAAAhnB,KAAA,CAAUgnB,CAAA5lC,MAAA,CAAc,CAAd,CAAV,CACO,CAAA,CAAA,CALkC,KAOvC6lC,CAPuC,CAO/BC,CAGZ,EAAMD,CAAN,CAAepB,EAAA,CAAWhB,CAAX,CAAoBhjB,CAApB,CAAf,IAA6ClnB,CAA7C;CACEusC,CAEE,CAFWD,CAEX,CAAAE,CAAA,CADF,CAAMF,CAAN,CAAepB,EAAA,CAAWM,CAAX,CAAuBc,CAAvB,CAAf,IAAmDtsC,CAAnD,CACiB0rC,CADjB,EACkCR,EAAA,CAAW,GAAX,CAAgBoB,CAAhB,CADlC,EAC6DA,CAD7D,EAGiBpC,CAHjB,CAG2BqC,CAL7B,EAOO,CAAMD,CAAN,CAAepB,EAAA,CAAWQ,CAAX,CAA0BxkB,CAA1B,CAAf,IAAmDlnB,CAAnD,CACLwsC,CADK,CACUd,CADV,CAC0BY,CAD1B,CAEIZ,CAFJ,EAEqBxkB,CAFrB,CAE2B,GAF3B,GAGLslB,CAHK,CAGUd,CAHV,CAKHc,EAAJ,EACE,IAAAb,QAAA,CAAaa,CAAb,CAEF,OAAO,CAAEA,CAAAA,CAzBkC,CAxCA,CA+E/CC,QAASA,GAAmB,CAACvC,CAAD,CAAUwC,CAAV,CAAsB,CAChD,IAAIhB,EAAgBL,EAAA,CAAUnB,CAAV,CAEpBH,GAAA,CAAiBG,CAAjB,CAA0B,IAA1B,CAAgCA,CAAhC,CAQA,KAAAyB,QAAA,CAAeC,QAAQ,CAAC1kB,CAAD,CAAM,CAC3B,IAAIylB,EAAiBzB,EAAA,CAAWhB,CAAX,CAAoBhjB,CAApB,CAAjBylB,EAA6CzB,EAAA,CAAWQ,CAAX,CAA0BxkB,CAA1B,CAAjD,CACI0lB,EAA6C,GAA5B,EAAAD,CAAA5mC,OAAA,CAAsB,CAAtB,CAAA,CACfmlC,EAAA,CAAWwB,CAAX,CAAuBC,CAAvB,CADe,CAEd,IAAAlB,QAAD,CACEkB,CADF,CAEE,EAER,IAAK,CAAAnsC,CAAA,CAASosC,CAAT,CAAL,CACE,KAAMd,GAAA,CAAgB,UAAhB,CAA6E5kB,CAA7E,CACFwlB,CADE,CAAN,CAGFhC,EAAA,CAAYkC,CAAZ,CAA4B,IAA5B,CAAkC1C,CAAlC,CAEqCW,EAAAA,CAAAA,IAAAA,OAoBnC,KAAIgC,EAAqB,iBAKC,EAA1B,GAAI3lB,CAAAtiB,QAAA,CAzB4DslC,CAyB5D,CAAJ,GACEhjB,CADF,CACQA,CAAAhf,QAAA,CA1BwDgiC,CA0BxD,CAAkB,EAAlB,CADR,CAKI2C,EAAAnyB,KAAA,CAAwBwM,CAAxB,CAAJ,GAKA,CALA,CAKO,CADP4lB,CACO,CADiBD,CAAAnyB,KAAA,CAAwB7M,CAAxB,CACjB,EAAwBi/B,CAAA,CAAsB,CAAtB,CAAxB,CAAmDj/B,CAL1D,CA9BF,KAAAg9B,OAAA,CAAc,CAEd,KAAAkB,UAAA,EAhB2B,CAyD7B,KAAAA,UAAA,CAAiBC,QAAQ,EAAG,CAAA,IACtBhB,EAASxiC,EAAA,CAAW,IAAAuiC,SAAX,CADa,CAEtB1lB,EAAO,IAAA4lB,OAAA;AAAc,GAAd,CAAoBpiC,EAAA,CAAiB,IAAAoiC,OAAjB,CAApB,CAAoD,EAE/D,KAAAgB,MAAA,CAAapC,EAAA,CAAW,IAAAgB,OAAX,CAAb,EAAwCG,CAAA,CAAS,GAAT,CAAeA,CAAf,CAAwB,EAAhE,EAAsE3lB,CACtE,KAAA6mB,SAAA,CAAgBhC,CAAhB,EAA2B,IAAA+B,MAAA,CAAaS,CAAb,CAA0B,IAAAT,MAA1B,CAAuC,EAAlE,CAL0B,CAQ5B,KAAAE,eAAA,CAAsBC,QAAQ,CAACllB,CAAD,CAAMmlB,CAAN,CAAe,CAC3C,MAAG5jB,GAAA,CAAUyhB,CAAV,CAAH,EAAyBzhB,EAAA,CAAUvB,CAAV,CAAzB,EACE,IAAAykB,QAAA,CAAazkB,CAAb,CACO,CAAA,CAAA,CAFT,EAIO,CAAA,CALoC,CA5EG,CA+FlD6lB,QAASA,GAA0B,CAAC7C,CAAD,CAAUwC,CAAV,CAAsB,CACvD,IAAAjB,QAAA,CAAe,CAAA,CACfgB,GAAA1lC,MAAA,CAA0B,IAA1B,CAAgC5E,SAAhC,CAEA,KAAIupC,EAAgBL,EAAA,CAAUnB,CAAV,CAEpB,KAAAiC,eAAA,CAAsBC,QAAQ,CAACllB,CAAD,CAAMmlB,CAAN,CAAe,CAC3C,GAAIA,CAAJ,EAA8B,GAA9B,GAAeA,CAAA,CAAQ,CAAR,CAAf,CAIE,MADA,KAAAhnB,KAAA,CAAUgnB,CAAA5lC,MAAA,CAAc,CAAd,CAAV,CACO,CAAA,CAAA,CAGT,KAAI+lC,CAAJ,CACIF,CAECpC,EAAL,EAAgBzhB,EAAA,CAAUvB,CAAV,CAAhB,CACEslB,CADF,CACiBtlB,CADjB,CAEO,CAAMolB,CAAN,CAAepB,EAAA,CAAWQ,CAAX,CAA0BxkB,CAA1B,CAAf,EACLslB,CADK,CACUtC,CADV,CACoBwC,CADpB,CACiCJ,CADjC,CAEKZ,CAFL,GAEuBxkB,CAFvB,CAE6B,GAF7B,GAGLslB,CAHK,CAGUd,CAHV,CAKHc,EAAJ,EACE,IAAAb,QAAA,CAAaa,CAAb,CAEF,OAAO,CAAEA,CAAAA,CArBkC,CAwB7C,KAAAT,UAAA,CAAiBC,QAAQ,EAAG,CAAA,IACtBhB,EAASxiC,EAAA,CAAW,IAAAuiC,SAAX,CADa,CAEtB1lB,EAAO,IAAA4lB,OAAA,CAAc,GAAd,CAAoBpiC,EAAA,CAAiB,IAAAoiC,OAAjB,CAApB;AAAoD,EAE/D,KAAAgB,MAAA,CAAapC,EAAA,CAAW,IAAAgB,OAAX,CAAb,EAAwCG,CAAA,CAAS,GAAT,CAAeA,CAAf,CAAwB,EAAhE,EAAsE3lB,CAEtE,KAAA6mB,SAAA,CAAgBhC,CAAhB,CAA0BwC,CAA1B,CAAuC,IAAAT,MANb,CA9B2B,CAoTzDe,QAASA,GAAc,CAACC,CAAD,CAAW,CAChC,MAAO,SAAQ,EAAG,CAChB,MAAO,KAAA,CAAKA,CAAL,CADS,CADc,CAOlCC,QAASA,GAAoB,CAACD,CAAD,CAAWE,CAAX,CAAuB,CAClD,MAAO,SAAQ,CAACzrC,CAAD,CAAQ,CACrB,GAAIwB,CAAA,CAAYxB,CAAZ,CAAJ,CACE,MAAO,KAAA,CAAKurC,CAAL,CAET,KAAA,CAAKA,CAAL,CAAA,CAAiBE,CAAA,CAAWzrC,CAAX,CACjB,KAAAqqC,UAAA,EAEA,OAAO,KAPc,CAD2B,CA6CpDp0B,QAASA,GAAiB,EAAE,CAAA,IACtB+0B,EAAa,EADS,CAEtBU,EAAY,CACVtf,QAAS,CAAA,CADC,CAEVuf,YAAa,CAAA,CAFH,CAGVC,aAAc,CAAA,CAHJ,CAahB,KAAAZ,WAAA,CAAkBa,QAAQ,CAAC/jC,CAAD,CAAS,CACjC,MAAIrG,EAAA,CAAUqG,CAAV,CAAJ,EACEkjC,CACO,CADMljC,CACN,CAAA,IAFT,EAISkjC,CALwB,CA4BnC,KAAAU,UAAA,CAAiBI,QAAQ,CAACjhB,CAAD,CAAO,CAC9B,MAAI3oB,GAAA,CAAU2oB,CAAV,CAAJ,EACE6gB,CAAAtf,QACO,CADavB,CACb,CAAA,IAFT,EAGWnpB,CAAA,CAASmpB,CAAT,CAAJ,EAED3oB,EAAA,CAAU2oB,CAAAuB,QAAV,CAYG,GAXLsf,CAAAtf,QAWK,CAXevB,CAAAuB,QAWf,EARHlqB,EAAA,CAAU2oB,CAAA8gB,YAAV,CAQG,GAPLD,CAAAC,YAOK,CAPmB9gB,CAAA8gB,YAOnB,EAJHzpC,EAAA,CAAU2oB,CAAA+gB,aAAV,CAIG;CAHLF,CAAAE,aAGK,CAHoB/gB,CAAA+gB,aAGpB,EAAA,IAdF,EAgBEF,CApBqB,CA+DhC,KAAAvrB,KAAA,CAAY,CAAC,YAAD,CAAe,UAAf,CAA2B,UAA3B,CAAuC,cAAvC,CACR,QAAQ,CAAE7J,CAAF,CAAgB1B,CAAhB,CAA4BoC,CAA5B,CAAwC6W,CAAxC,CAAsD,CAyBhEke,QAASA,EAAyB,CAACvmB,CAAD,CAAMhf,CAAN,CAAe6e,CAAf,CAAsB,CACtD,IAAI2mB,EAASh2B,CAAAwP,IAAA,EAAb,CACIymB,EAAWj2B,CAAAk2B,QACf,IAAI,CACFt3B,CAAA4Q,IAAA,CAAaA,CAAb,CAAkBhf,CAAlB,CAA2B6e,CAA3B,CAKA,CAAArP,CAAAk2B,QAAA,CAAoBt3B,CAAAyQ,MAAA,EANlB,CAOF,MAAOlf,CAAP,CAAU,CAKV,KAHA6P,EAAAwP,IAAA,CAAcwmB,CAAd,CAGM7lC,CAFN6P,CAAAk2B,QAEM/lC,CAFc8lC,CAEd9lC,CAAAA,CAAN,CALU,CAV0C,CA8HxDgmC,QAASA,EAAmB,CAACH,CAAD,CAASC,CAAT,CAAmB,CAC7C31B,CAAA81B,WAAA,CAAsB,wBAAtB,CAAgDp2B,CAAAq2B,OAAA,EAAhD,CAAoEL,CAApE,CACEh2B,CAAAk2B,QADF,CACqBD,CADrB,CAD6C,CAvJiB,IAC5Dj2B,CAD4D,CAE5Ds2B,CACAjlB,EAAAA,CAAWzS,CAAAyS,SAAA,EAHiD,KAI5DklB,EAAa33B,CAAA4Q,IAAA,EAJ+C,CAK5DgjB,CAEJ,IAAIkD,CAAAtf,QAAJ,CAAuB,CACrB,GAAK/E,CAAAA,CAAL,EAAiBqkB,CAAAC,YAAjB,CACE,KAAMvB,GAAA,CAAgB,QAAhB,CAAN,CAGF5B,CAAA,CAAqB+D,CAzpBlBvkB,UAAA,CAAc,CAAd,CAypBkBukB,CAzpBDrpC,QAAA,CAAY,GAAZ,CAypBCqpC,CAzpBgBrpC,QAAA,CAAY,IAAZ,CAAjB,CAAqC,CAArC,CAAjB,CAypBH,EAAoCmkB,CAApC,EAAgD,GAAhD,CACAilB,EAAA,CAAet1B,CAAAoO,QAAA,CAAmBykB,EAAnB,CAAsCwB,EANhC,CAAvB,IAQE7C,EACA,CADUzhB,EAAA,CAAUwlB,CAAV,CACV;AAAAD,CAAA,CAAevB,EAEjB/0B,EAAA,CAAY,IAAIs2B,CAAJ,CAAiB9D,CAAjB,CAA0B,GAA1B,CAAgCwC,CAAhC,CACZh1B,EAAAy0B,eAAA,CAAyB8B,CAAzB,CAAqCA,CAArC,CAEAv2B,EAAAk2B,QAAA,CAAoBt3B,CAAAyQ,MAAA,EAEpB,KAAImnB,EAAoB,2BAqBxB3e,EAAAjjB,GAAA,CAAgB,OAAhB,CAAyB,QAAQ,CAACgT,CAAD,CAAQ,CAIvC,GAAK8tB,CAAAE,aAAL,EAA+Ba,CAAA7uB,CAAA6uB,QAA/B,EAAgDC,CAAA9uB,CAAA8uB,QAAhD,EAAgF,CAAhF,EAAiE9uB,CAAA+uB,MAAjE,CAAA,CAKA,IAHA,IAAI/oB,EAAM5d,CAAA,CAAO4X,CAAAgvB,OAAP,CAGV,CAA6B,GAA7B,GAAOhqC,EAAA,CAAUghB,CAAA,CAAI,CAAJ,CAAV,CAAP,CAAA,CAEE,GAAIA,CAAA,CAAI,CAAJ,CAAJ,GAAeiK,CAAA,CAAa,CAAb,CAAf,EAAmC,CAAA,CAACjK,CAAD,CAAOA,CAAA3iB,OAAA,EAAP,EAAqB,CAArB,CAAnC,CAA4D,MAG9D,KAAI4rC,EAAUjpB,CAAAthB,KAAA,CAAS,MAAT,CAAd,CAGIqoC,EAAU/mB,CAAArhB,KAAA,CAAS,MAAT,CAAVooC,EAA8B/mB,CAAArhB,KAAA,CAAS,YAAT,CAE9Bb,EAAA,CAASmrC,CAAT,CAAJ,EAAgD,4BAAhD,GAAyBA,CAAAhrC,SAAA,EAAzB,GAGEgrC,CAHF,CAGYxJ,EAAA,CAAWwJ,CAAAC,QAAX,CAAArmB,KAHZ,CAOI+lB,EAAAjjC,KAAA,CAAuBsjC,CAAvB,CAAJ,EAEIA,CAAAA,CAFJ,EAEgBjpB,CAAArhB,KAAA,CAAS,QAAT,CAFhB,EAEuCqb,CAAAC,mBAAA,EAFvC,EAGM,CAAA7H,CAAAy0B,eAAA,CAAyBoC,CAAzB,CAAkClC,CAAlC,CAHN,GAOI/sB,CAAAmvB,eAAA,EAEA,CAAI/2B,CAAAq2B,OAAA,EAAJ;AAA0Bz3B,CAAA4Q,IAAA,EAA1B,GACElP,CAAAnN,OAAA,EAEA,CAAA/K,CAAAoL,QAAA,CAAe,0BAAf,CAAA,CAA6C,CAAA,CAH/C,CATJ,CAtBA,CAJuC,CAAzC,CA8CIwM,EAAAq2B,OAAA,EAAJ,EAA0BE,CAA1B,EACE33B,CAAA4Q,IAAA,CAAaxP,CAAAq2B,OAAA,EAAb,CAAiC,CAAA,CAAjC,CAGF,KAAIW,EAAe,CAAA,CAGnBp4B,EAAAsS,YAAA,CAAqB,QAAQ,CAAC+lB,CAAD,CAASC,CAAT,CAAmB,CAC9C52B,CAAAtU,WAAA,CAAsB,QAAQ,EAAG,CAC/B,IAAIgqC,EAASh2B,CAAAq2B,OAAA,EAAb,CACIJ,EAAWj2B,CAAAk2B,QAEfl2B,EAAAi0B,QAAA,CAAkBgD,CAAlB,CACAj3B,EAAAk2B,QAAA,CAAoBgB,CAChB52B,EAAA81B,WAAA,CAAsB,sBAAtB,CAA8Ca,CAA9C,CAAsDjB,CAAtD,CACAkB,CADA,CACUjB,CADV,CAAAluB,iBAAJ,EAEE/H,CAAAi0B,QAAA,CAAkB+B,CAAlB,CAEA,CADAh2B,CAAAk2B,QACA,CADoBD,CACpB,CAAAF,CAAA,CAA0BC,CAA1B,CAAkC,CAAA,CAAlC,CAAyCC,CAAzC,CAJF,GAMEe,CACA,CADe,CAAA,CACf,CAAAb,CAAA,CAAoBH,CAApB,CAA4BC,CAA5B,CAPF,CAN+B,CAAjC,CAgBK31B,EAAAwqB,QAAL,EAAyBxqB,CAAA62B,QAAA,EAjBqB,CAAhD,CAqBA72B,EAAArU,OAAA,CAAkBmrC,QAAuB,EAAG,CAC1C,IAAIpB,EAASp3B,CAAA4Q,IAAA,EAAb,CACIymB,EAAWr3B,CAAAyQ,MAAA,EADf,CAEIgoB,EAAiBr3B,CAAAs3B,UAFrB,CAGIC,EAAoBvB,CAApBuB,GAA+Bv3B,CAAAq2B,OAAA,EAA/BkB,EACDv3B,CAAA+zB,QADCwD,EACoBv2B,CAAAoO,QADpBmoB,EACwCtB,CADxCsB,GACqDv3B,CAAAk2B,QAEzD,IAAIc,CAAJ,EAAoBO,CAApB,CACEP,CAEA,CAFe,CAAA,CAEf,CAAA12B,CAAAtU,WAAA,CAAsB,QAAQ,EAAG,CAC3BsU,CAAA81B,WAAA,CAAsB,sBAAtB;AAA8Cp2B,CAAAq2B,OAAA,EAA9C,CAAkEL,CAAlE,CACAh2B,CAAAk2B,QADA,CACmBD,CADnB,CAAAluB,iBAAJ,EAEE/H,CAAAi0B,QAAA,CAAkB+B,CAAlB,CACA,CAAAh2B,CAAAk2B,QAAA,CAAoBD,CAHtB,GAKMsB,CAIJ,EAHExB,CAAA,CAA0B/1B,CAAAq2B,OAAA,EAA1B,CAA8CgB,CAA9C,CAC0BpB,CAAA,GAAaj2B,CAAAk2B,QAAb,CAAiC,IAAjC,CAAwCl2B,CAAAk2B,QADlE,CAGF,CAAAC,CAAA,CAAoBH,CAApB,CAA4BC,CAA5B,CATF,CAD+B,CAAjC,CAeFj2B,EAAAs3B,UAAA,CAAsB,CAAA,CAzBoB,CAA5C,CA+BA,OAAOt3B,EArJyD,CADtD,CA1Gc,CAoT5BG,QAASA,GAAY,EAAE,CAAA,IACjBq3B,EAAQ,CAAA,CADS,CAEjBvoC,EAAO,IASX,KAAAwoC,aAAA,CAAoBC,QAAQ,CAACC,CAAD,CAAO,CACjC,MAAIlsC,EAAA,CAAUksC,CAAV,CAAJ,EACEH,CACK,CADGG,CACH,CAAA,IAFP,EAISH,CALwB,CASnC,KAAArtB,KAAA,CAAY,CAAC,SAAD,CAAY,QAAQ,CAACzI,CAAD,CAAS,CAwDvCk2B,QAASA,EAAW,CAAChiC,CAAD,CAAM,CACpBA,CAAJ,WAAmBiiC,MAAnB,GACMjiC,CAAAqV,MAAJ,CACErV,CADF,CACSA,CAAAoV,QAAD,EAAoD,EAApD,GAAgBpV,CAAAqV,MAAA/d,QAAA,CAAkB0I,CAAAoV,QAAlB,CAAhB,CACA,SADA,CACYpV,CAAAoV,QADZ,CAC0B,IAD1B,CACiCpV,CAAAqV,MADjC,CAEArV,CAAAqV,MAHR,CAIWrV,CAAAkiC,UAJX,GAKEliC,CALF,CAKQA,CAAAoV,QALR,CAKsB,IALtB,CAK6BpV,CAAAkiC,UAL7B,CAK6C,GAL7C,CAKmDliC,CAAAoxB,KALnD,CADF,CASA,OAAOpxB,EAViB,CAa1BmiC,QAASA,EAAU,CAACrzB,CAAD,CAAO,CAAA,IACpBszB,EAAUt2B,CAAAs2B,QAAVA;AAA6B,EADT,CAEpBC,EAAQD,CAAA,CAAQtzB,CAAR,CAARuzB,EAAyBD,CAAAE,IAAzBD,EAAwC7sC,CACxC+sC,EAAAA,CAAW,CAAA,CAIf,IAAI,CACFA,CAAA,CAAW,CAAE9oC,CAAA4oC,CAAA5oC,MADX,CAEF,MAAOc,CAAP,CAAU,EAEZ,MAAIgoC,EAAJ,CACS,QAAQ,EAAG,CAChB,IAAIlvB,EAAO,EACXjgB,EAAA,CAAQyB,SAAR,CAAmB,QAAQ,CAACmL,CAAD,CAAM,CAC/BqT,CAAAvf,KAAA,CAAUkuC,CAAA,CAAYhiC,CAAZ,CAAV,CAD+B,CAAjC,CAGA,OAAOqiC,EAAA5oC,MAAA,CAAY2oC,CAAZ,CAAqB/uB,CAArB,CALS,CADpB,CAYO,QAAQ,CAACmvB,CAAD,CAAOC,CAAP,CAAa,CAC1BJ,CAAA,CAAMG,CAAN,CAAoB,IAAR,EAAAC,CAAA,CAAe,EAAf,CAAoBA,CAAhC,CAD0B,CAvBJ,CApE1B,MAAO,CAQLH,IAAKH,CAAA,CAAW,KAAX,CARA,CAiBL9jB,KAAM8jB,CAAA,CAAW,MAAX,CAjBD,CA0BLjmB,KAAMimB,CAAA,CAAW,MAAX,CA1BD,CAmCLtpB,MAAOspB,CAAA,CAAW,OAAX,CAnCF,CA4CLP,MAAQ,QAAS,EAAG,CAClB,IAAItoC,EAAK6oC,CAAA,CAAW,OAAX,CAET,OAAO,SAAQ,EAAG,CACZP,CAAJ,EACEtoC,CAAAG,MAAA,CAASJ,CAAT,CAAexE,SAAf,CAFc,CAHA,CAAZ,EA5CH,CADgC,CAA7B,CApBS,CA+IvB6tC,QAASA,GAAoB,CAACvmC,CAAD,CAAOwmC,CAAP,CAAuB,CAClD,GAAa,kBAAb,GAAIxmC,CAAJ,EAA4C,kBAA5C,GAAmCA,CAAnC,EACgB,kBADhB,GACOA,CADP,EAC+C,kBAD/C,GACsCA,CADtC,EAEgB,WAFhB,GAEOA,CAFP,CAGE,KAAMymC,GAAA,CAAa,SAAb,CAEkBD,CAFlB,CAAN,CAIF,MAAOxmC,EAR2C,CAWpD0mC,QAASA,GAAgB,CAAChwC,CAAD,CAAM8vC,CAAN,CAAsB,CAE7C,GAAI9vC,CAAJ,CAAS,CACP,GAAIA,CAAAuN,YAAJ;AAAwBvN,CAAxB,CACE,KAAM+vC,GAAA,CAAa,QAAb,CAEFD,CAFE,CAAN,CAGK,GACH9vC,CAAAL,OADG,GACYK,CADZ,CAEL,KAAM+vC,GAAA,CAAa,YAAb,CAEFD,CAFE,CAAN,CAGK,GACH9vC,CAAAiwC,SADG,GACcjwC,CAAA4D,SADd,EAC+B5D,CAAA6D,KAD/B,EAC2C7D,CAAA8D,KAD3C,EACuD9D,CAAA+D,KADvD,EAEL,KAAMgsC,GAAA,CAAa,SAAb,CAEFD,CAFE,CAAN,CAGK,GACH9vC,CADG,GACKiC,MADL,CAEL,KAAM8tC,GAAA,CAAa,SAAb,CAEFD,CAFE,CAAN,CAjBK,CAsBT,MAAO9vC,EAxBsC,CAsV/CkwC,QAASA,GAAU,CAAC7J,CAAD,CAAM,CACvB,MAAOA,EAAA72B,SADgB,CAwczB2gC,QAASA,GAAM,CAACnwC,CAAD,CAAM0N,CAAN,CAAY0iC,CAAZ,CAAsBC,CAAtB,CAA+B,CAC5CL,EAAA,CAAiBhwC,CAAjB,CAAsBqwC,CAAtB,CAEIjsC,EAAAA,CAAUsJ,CAAAxJ,MAAA,CAAW,GAAX,CACd,KADA,IAA+BxD,CAA/B,CACSU,EAAI,CAAb,CAAiC,CAAjC,CAAgBgD,CAAAlE,OAAhB,CAAoCkB,CAAA,EAApC,CAAyC,CACvCV,CAAA,CAAMmvC,EAAA,CAAqBzrC,CAAA2e,MAAA,EAArB,CAAsCstB,CAAtC,CACN,KAAIC,EAAcN,EAAA,CAAiBhwC,CAAA,CAAIU,CAAJ,CAAjB,CAA2B2vC,CAA3B,CACbC,EAAL,GACEA,CACA,CADc,EACd,CAAAtwC,CAAA,CAAIU,CAAJ,CAAA,CAAW4vC,CAFb,CAIAtwC,EAAA,CAAMswC,CAPiC,CASzC5vC,CAAA,CAAMmvC,EAAA,CAAqBzrC,CAAA2e,MAAA,EAArB,CAAsCstB,CAAtC,CACNL,GAAA,CAAiBhwC,CAAA,CAAIU,CAAJ,CAAjB,CAA2B2vC,CAA3B,CAEA,OADArwC,EAAA,CAAIU,CAAJ,CACA,CADW0vC,CAfiC,CA0B9CG,QAASA,GAAe,CAACC,CAAD,CAAOC,CAAP,CAAaC,CAAb,CAAmBC,CAAnB,CAAyBC,CAAzB,CAA+BP,CAA/B,CAAwC,CAC9DR,EAAA,CAAqBW,CAArB,CAA2BH,CAA3B,CACAR,GAAA,CAAqBY,CAArB,CAA2BJ,CAA3B,CACAR,GAAA,CAAqBa,CAArB,CAA2BL,CAA3B,CACAR,GAAA,CAAqBc,CAArB,CAA2BN,CAA3B,CACAR,GAAA,CAAqBe,CAArB,CAA2BP,CAA3B,CAEA,OAAOQ,SAAsB,CAACrmC,CAAD,CAAQwY,CAAR,CAAgB,CAC3C,IAAI8tB,EAAW9tB,CAAD,EAAWA,CAAApiB,eAAA,CAAsB4vC,CAAtB,CAAX;AAA0CxtB,CAA1C,CAAmDxY,CAEjE,IAAe,IAAf,EAAIsmC,CAAJ,CAAqB,MAAOA,EAC5BA,EAAA,CAAUA,CAAA,CAAQN,CAAR,CAEV,IAAKC,CAAAA,CAAL,CAAW,MAAOK,EAClB,IAAe,IAAf,EAAIA,CAAJ,CAAqB,MAAOjxC,EAC5BixC,EAAA,CAAUA,CAAA,CAAQL,CAAR,CAEV,IAAKC,CAAAA,CAAL,CAAW,MAAOI,EAClB,IAAe,IAAf,EAAIA,CAAJ,CAAqB,MAAOjxC,EAC5BixC,EAAA,CAAUA,CAAA,CAAQJ,CAAR,CAEV,IAAKC,CAAAA,CAAL,CAAW,MAAOG,EAClB,IAAe,IAAf,EAAIA,CAAJ,CAAqB,MAAOjxC,EAC5BixC,EAAA,CAAUA,CAAA,CAAQH,CAAR,CAEV,OAAKC,EAAL,CACe,IAAf,EAAIE,CAAJ,CAA4BjxC,CAA5B,CACAixC,CADA,CACUA,CAAA,CAAQF,CAAR,CAFV,CAAkBE,CAlByB,CAPiB,CAiChEC,QAASA,GAAQ,CAACrjC,CAAD,CAAOwc,CAAP,CAAgBmmB,CAAhB,CAAyB,CACxC,IAAI5pC,EAAKuqC,EAAA,CAActjC,CAAd,CAET,IAAIjH,CAAJ,CAAQ,MAAOA,EAHyB,KAKpCwqC,EAAWvjC,CAAAxJ,MAAA,CAAW,GAAX,CALyB,CAMpCgtC,EAAiBD,CAAA/wC,OAGrB,IAAIgqB,CAAAha,IAAJ,CAEIzJ,CAAA,CADmB,CAArB,CAAIyqC,CAAJ,CACOX,EAAA,CAAgBU,CAAA,CAAS,CAAT,CAAhB,CAA6BA,CAAA,CAAS,CAAT,CAA7B,CAA0CA,CAAA,CAAS,CAAT,CAA1C,CAAuDA,CAAA,CAAS,CAAT,CAAvD,CAAoEA,CAAA,CAAS,CAAT,CAApE,CAAiFZ,CAAjF,CADP,CAGO5pC,QAAsB,CAAC+D,CAAD,CAAQwY,CAAR,CAAgB,CAAA,IACrC5hB,EAAI,CADiC,CAC9B0F,CACX,GACEA,EAIA,CAJMypC,EAAA,CAAgBU,CAAA,CAAS7vC,CAAA,EAAT,CAAhB,CAA+B6vC,CAAA,CAAS7vC,CAAA,EAAT,CAA/B,CAA8C6vC,CAAA,CAAS7vC,CAAA,EAAT,CAA9C,CAA6D6vC,CAAA,CAAS7vC,CAAA,EAAT,CAA7D,CACgB6vC,CAAA,CAAS7vC,CAAA,EAAT,CADhB,CAC+BivC,CAD/B,CAAA,CACwC7lC,CADxC,CAC+CwY,CAD/C,CAIN,CADAA,CACA,CADSnjB,CACT,CAAA2K,CAAA,CAAQ1D,CALV,OAMS1F,CANT,CAMa8vC,CANb,CAOA,OAAOpqC,EATkC,CAJ/C,KAgBO,CACL,IAAIqqC,EAAO,EACX5wC,EAAA,CAAQ0wC,CAAR,CAAkB,QAAQ,CAACvwC,CAAD,CAAM8D,CAAN,CAAa,CACrCqrC,EAAA,CAAqBnvC,CAArB,CAA0B2vC,CAA1B,CACAc,EAAA,EAAQ,qCAAR,EACe3sC,CAAA,CAEG,GAFH,CAIG,yBAJH;AAI+B9D,CAJ/B,CAIqC,UALpD,EAKkE,GALlE,CAKwEA,CALxE,CAK8E,KAPzC,CAAvC,CASAywC,EAAA,EAAQ,WAGJC,EAAAA,CAAiB,IAAIC,QAAJ,CAAa,GAAb,CAAkB,GAAlB,CAAuBF,CAAvB,CAErBC,EAAAhuC,SAAA,CAA0BN,EAAA,CAAQquC,CAAR,CAE1B1qC,EAAA,CAAK2qC,CAlBA,CAqBP3qC,CAAA6qC,aAAA,CAAkB,CAAA,CAClB7qC,EAAA4uB,OAAA,CAAYkc,QAAQ,CAAC/qC,CAAD,CAAOjF,CAAP,CAAc,CAChC,MAAO4uC,GAAA,CAAO3pC,CAAP,CAAakH,CAAb,CAAmBnM,CAAnB,CAA0BmM,CAA1B,CADyB,CAIlC,OADAsjC,GAAA,CAActjC,CAAd,CACA,CADsBjH,CAlDkB,CAyG1CmR,QAASA,GAAc,EAAG,CACxB,IAAI8K,EAAQvU,EAAA,EAAZ,CAEIqjC,EAAgB,CAClBthC,IAAK,CAAA,CADa,CAKpB,KAAAwR,KAAA,CAAY,CAAC,SAAD,CAAY,UAAZ,CAAwB,QAAQ,CAAC7K,CAAD,CAAU0B,CAAV,CAAoB,CAG9Dk5B,QAASA,EAAoB,CAACpL,CAAD,CAAM,CACjC,IAAIqL,EAAUrL,CAEVA,EAAAiL,aAAJ,GACEI,CAKA,CALUA,QAAsB,CAAClrC,CAAD,CAAOwc,CAAP,CAAe,CAC7C,MAAOqjB,EAAA,CAAI7/B,CAAJ,CAAUwc,CAAV,CADsC,CAK/C,CAFA0uB,CAAAvc,QAEA,CAFkBkR,CAAAlR,QAElB,CADAuc,CAAAliC,SACA,CADmB62B,CAAA72B,SACnB,CAAAkiC,CAAArc,OAAA,CAAiBgR,CAAAhR,OANnB,CASA,OAAOqc,EAZ0B,CA0DnCC,QAASA,EAAuB,CAACC,CAAD,CAASxtB,CAAT,CAAe,CAC7C,IAD6C,IACpChjB,EAAI,CADgC,CAC7BW,EAAK6vC,CAAA1xC,OAArB,CAAoCkB,CAApC,CAAwCW,CAAxC,CAA4CX,CAAA,EAA5C,CAAiD,CAC/C,IAAIuP,EAAQihC,CAAA,CAAOxwC,CAAP,CACPuP,EAAAnB,SAAL,GACMmB,CAAAihC,OAAJ,CACED,CAAA,CAAwBhhC,CAAAihC,OAAxB,CAAsCxtB,CAAtC,CADF,CAEoC,EAFpC,GAEWA,CAAA3f,QAAA,CAAakM,CAAb,CAFX;AAGEyT,CAAAnjB,KAAA,CAAU0P,CAAV,CAJJ,CAF+C,CAWjD,MAAOyT,EAZsC,CAe/CytB,QAASA,EAAyB,CAACtX,CAAD,CAAWuX,CAAX,CAA4B,CAE5D,MAAgB,KAAhB,EAAIvX,CAAJ,EAA2C,IAA3C,EAAwBuX,CAAxB,CACSvX,CADT,GACsBuX,CADtB,CAIwB,QAAxB,GAAI,MAAOvX,EAAX,GAKEA,CAEI,CAFOA,CAAAsL,QAAA,EAEP,CAAoB,QAApB,GAAA,MAAOtL,EAPb,EASW,CAAA,CATX,CAgBOA,CAhBP,GAgBoBuX,CAhBpB,EAgBwCvX,CAhBxC,GAgBqDA,CAhBrD,EAgBiEuX,CAhBjE,GAgBqFA,CAtBzB,CAyB9DC,QAASA,EAAmB,CAACvnC,CAAD,CAAQ0c,CAAR,CAAkBwf,CAAlB,CAAkCsL,CAAlC,CAAoD,CAC9E,IAAIC,EAAmBD,CAAAE,SAAnBD,GACWD,CAAAE,SADXD,CACuCN,CAAA,CAAwBK,CAAAJ,OAAxB,CAAiD,EAAjD,CADvCK,CAAJ,CAGIE,CAEJ,IAAgC,CAAhC,GAAIF,CAAA/xC,OAAJ,CAAmC,CACjC,IAAIkyC,EAAgBP,CAApB,CACAI,EAAmBA,CAAA,CAAiB,CAAjB,CACnB,OAAOznC,EAAAhH,OAAA,CAAa6uC,QAA6B,CAAC7nC,CAAD,CAAQ,CACvD,IAAI8nC,EAAgBL,CAAA,CAAiBznC,CAAjB,CACfqnC,EAAA,CAA0BS,CAA1B,CAAyCF,CAAzC,CAAL,GACED,CACA,CADaH,CAAA,CAAiBxnC,CAAjB,CACb,CAAA4nC,CAAA,CAAgBE,CAAhB,EAAiCA,CAAAzM,QAAA,EAFnC,CAIA,OAAOsM,EANgD,CAAlD,CAOJjrB,CAPI,CAOMwf,CAPN,CAH0B,CAcnC,IADA,IAAI6L,EAAwB,EAA5B,CACSnxC,EAAI,CADb,CACgBW,EAAKkwC,CAAA/xC,OAArB,CAA8CkB,CAA9C,CAAkDW,CAAlD,CAAsDX,CAAA,EAAtD,CACEmxC,CAAA,CAAsBnxC,CAAtB,CAAA,CAA2BywC,CAG7B,OAAOrnC,EAAAhH,OAAA,CAAagvC,QAA8B,CAAChoC,CAAD,CAAQ,CAGxD,IAFA,IAAIioC,EAAU,CAAA,CAAd,CAESrxC,EAAI,CAFb,CAEgBW,EAAKkwC,CAAA/xC,OAArB,CAA8CkB,CAA9C,CAAkDW,CAAlD,CAAsDX,CAAA,EAAtD,CAA2D,CACzD,IAAIkxC,EAAgBL,CAAA,CAAiB7wC,CAAjB,CAAA,CAAoBoJ,CAApB,CACpB,IAAIioC,CAAJ,GAAgBA,CAAhB,CAA0B,CAACZ,CAAA,CAA0BS,CAA1B,CAAyCC,CAAA,CAAsBnxC,CAAtB,CAAzC,CAA3B,EACEmxC,CAAA,CAAsBnxC,CAAtB,CAAA,CAA2BkxC,CAA3B,EAA4CA,CAAAzM,QAAA,EAHW,CAOvD4M,CAAJ,GACEN,CADF;AACeH,CAAA,CAAiBxnC,CAAjB,CADf,CAIA,OAAO2nC,EAdiD,CAAnD,CAeJjrB,CAfI,CAeMwf,CAfN,CAxBuE,CA0ChFgM,QAASA,EAAoB,CAACloC,CAAD,CAAQ0c,CAAR,CAAkBwf,CAAlB,CAAkCsL,CAAlC,CAAoD,CAAA,IAC3Evc,CAD2E,CAClEb,CACb,OAAOa,EAAP,CAAiBjrB,CAAAhH,OAAA,CAAamvC,QAAqB,CAACnoC,CAAD,CAAQ,CACzD,MAAOwnC,EAAA,CAAiBxnC,CAAjB,CADkD,CAA1C,CAEdooC,QAAwB,CAACrxC,CAAD,CAAQsxC,CAAR,CAAaroC,CAAb,CAAoB,CAC7CoqB,CAAA,CAAYrzB,CACRZ,EAAA,CAAWumB,CAAX,CAAJ,EACEA,CAAAtgB,MAAA,CAAe,IAAf,CAAqB5E,SAArB,CAEEgB,EAAA,CAAUzB,CAAV,CAAJ,EACEiJ,CAAAsoC,aAAA,CAAmB,QAAS,EAAG,CACzB9vC,CAAA,CAAU4xB,CAAV,CAAJ,EACEa,CAAA,EAF2B,CAA/B,CAN2C,CAF9B,CAcdiR,CAdc,CAF8D,CAmBjFqM,QAASA,EAA2B,CAACvoC,CAAD,CAAQ0c,CAAR,CAAkBwf,CAAlB,CAAkCsL,CAAlC,CAAoD,CAgBtFgB,QAASA,EAAY,CAACzxC,CAAD,CAAQ,CAC3B,IAAI0xC,EAAa,CAAA,CACjB1yC,EAAA,CAAQgB,CAAR,CAAe,QAAS,CAACuF,CAAD,CAAM,CACvB9D,CAAA,CAAU8D,CAAV,CAAL,GAAqBmsC,CAArB,CAAkC,CAAA,CAAlC,CAD4B,CAA9B,CAGA,OAAOA,EALoB,CAhByD,IAClFxd,CADkF,CACzEb,CACb,OAAOa,EAAP,CAAiBjrB,CAAAhH,OAAA,CAAamvC,QAAqB,CAACnoC,CAAD,CAAQ,CACzD,MAAOwnC,EAAA,CAAiBxnC,CAAjB,CADkD,CAA1C,CAEdooC,QAAwB,CAACrxC,CAAD,CAAQsxC,CAAR,CAAaroC,CAAb,CAAoB,CAC7CoqB,CAAA,CAAYrzB,CACRZ,EAAA,CAAWumB,CAAX,CAAJ,EACEA,CAAArmB,KAAA,CAAc,IAAd,CAAoBU,CAApB,CAA2BsxC,CAA3B,CAAgCroC,CAAhC,CAEEwoC,EAAA,CAAazxC,CAAb,CAAJ,EACEiJ,CAAAsoC,aAAA,CAAmB,QAAS,EAAG,CAC1BE,CAAA,CAAape,CAAb,CAAH,EAA4Ba,CAAA,EADC,CAA/B,CAN2C,CAF9B,CAYdiR,CAZc,CAFqE,CAyBxFwM,QAASA,EAAqB,CAAC1oC,CAAD,CAAQ0c,CAAR,CAAkBwf,CAAlB,CAAkCsL,CAAlC,CAAoD,CAChF,IAAIvc,CACJ,OAAOA,EAAP,CAAiBjrB,CAAAhH,OAAA,CAAa2vC,QAAsB,CAAC3oC,CAAD,CAAQ,CAC1D,MAAOwnC,EAAA,CAAiBxnC,CAAjB,CADmD,CAA3C,CAEd4oC,QAAyB,CAAC7xC,CAAD,CAAQsxC,CAAR,CAAaroC,CAAb,CAAoB,CAC1C7J,CAAA,CAAWumB,CAAX,CAAJ;AACEA,CAAAtgB,MAAA,CAAe,IAAf,CAAqB5E,SAArB,CAEFyzB,EAAA,EAJ8C,CAF/B,CAOdiR,CAPc,CAF+D,CAYlF2M,QAASA,EAAc,CAACrB,CAAD,CAAmBsB,CAAnB,CAAkC,CACvD,GAAKA,CAAAA,CAAL,CAAoB,MAAOtB,EAE3B,KAAIvrC,EAAKA,QAA8B,CAAC+D,CAAD,CAAQwY,CAAR,CAAgB,CACrD,IAAIzhB,EAAQywC,CAAA,CAAiBxnC,CAAjB,CAAwBwY,CAAxB,CAAZ,CACI/d,EAASquC,CAAA,CAAc/xC,CAAd,CAAqBiJ,CAArB,CAA4BwY,CAA5B,CAGb,OAAOhgB,EAAA,CAAUzB,CAAV,CAAA,CAAmB0D,CAAnB,CAA4B1D,CALkB,CASnDywC,EAAAvL,gBAAJ,EACIuL,CAAAvL,gBADJ,GACyCsL,CADzC,CAEEtrC,CAAAggC,gBAFF,CAEuBuL,CAAAvL,gBAFvB,CAGY6M,CAAA9d,UAHZ,GAME/uB,CAAAggC,gBACA,CADqBsL,CACrB,CAAAtrC,CAAAmrC,OAAA,CAAY,CAACI,CAAD,CAPd,CAUA,OAAOvrC,EAtBgD,CAtMzD+qC,CAAAthC,IAAA,CAAoBqI,CAAArI,IAiBpB,OAAOyH,SAAe,CAAC0uB,CAAD,CAAMiN,CAAN,CAAqB,CAAA,IACrCtB,CADqC,CACnBuB,CADmB,CACVC,CAE/B,QAAQ,MAAOnN,EAAf,EACE,KAAK,QAAL,CA6BE,MA5BAmN,EA4BO,CA5BInN,CA4BJ,CA5BUA,CAAAlrB,KAAA,EA4BV,CA1BP62B,CA0BO,CA1BYtvB,CAAA,CAAM8wB,CAAN,CA0BZ,CAxBFxB,CAwBE,GAvBiB,GAqBtB,GArBI3L,CAAAzgC,OAAA,CAAW,CAAX,CAqBJ,EArB+C,GAqB/C,GArB6BygC,CAAAzgC,OAAA,CAAW,CAAX,CAqB7B,GApBE2tC,CACA,CADU,CAAA,CACV,CAAAlN,CAAA,CAAMA,CAAA9c,UAAA,CAAc,CAAd,CAmBR,EAhBIkqB,CAgBJ,CAhBY,IAAIC,EAAJ,CAAUlC,CAAV,CAgBZ,CAdAQ,CAcA,CAdmB3qC,CADNssC,IAAIC,EAAJD,CAAWF,CAAXE,CAAkB98B,CAAlB88B,CAA2BnC,CAA3BmC,CACMtsC,OAAA,CAAag/B,CAAb,CAcnB,CAZI2L,CAAAxiC,SAAJ,CACEwiC,CAAAvL,gBADF,CACqCyM,CADrC,CAEWK,CAAJ,EAGLvB,CACA,CADmBP,CAAA,CAAqBO,CAArB,CACnB;AAAAA,CAAAvL,gBAAA,CAAmCuL,CAAA7c,QAAA,CACjC4d,CADiC,CACHL,CAL3B,EAMIV,CAAAJ,OANJ,GAOLI,CAAAvL,gBAPK,CAO8BsL,CAP9B,CAUP,CAAArvB,CAAA,CAAM8wB,CAAN,CAAA,CAAkBxB,CAEb,EAAAqB,CAAA,CAAerB,CAAf,CAAiCsB,CAAjC,CAET,MAAK,UAAL,CACE,MAAOD,EAAA,CAAehN,CAAf,CAAoBiN,CAApB,CAET,SACE,MAAOD,EAAA,CAAe1wC,CAAf,CAAqB2wC,CAArB,CApCX,CAHyC,CAlBmB,CAApD,CARY,CA8b1Bt7B,QAASA,GAAU,EAAG,CAEpB,IAAA0J,KAAA,CAAY,CAAC,YAAD,CAAe,mBAAf,CAAoC,QAAQ,CAAC7J,CAAD,CAAalB,CAAb,CAAgC,CACtF,MAAOk9B,GAAA,CAAS,QAAQ,CAAChsB,CAAD,CAAW,CACjChQ,CAAAtU,WAAA,CAAsBskB,CAAtB,CADiC,CAA5B,CAEJlR,CAFI,CAD+E,CAA5E,CAFQ,CAStBuB,QAASA,GAAW,EAAG,CACrB,IAAAwJ,KAAA,CAAY,CAAC,UAAD,CAAa,mBAAb,CAAkC,QAAQ,CAACvL,CAAD,CAAWQ,CAAX,CAA8B,CAClF,MAAOk9B,GAAA,CAAS,QAAQ,CAAChsB,CAAD,CAAW,CACjC1R,CAAAqT,MAAA,CAAe3B,CAAf,CADiC,CAA5B,CAEJlR,CAFI,CAD2E,CAAxE,CADS,CAgBvBk9B,QAASA,GAAQ,CAACC,CAAD,CAAWC,CAAX,CAA6B,CAE5CC,QAASA,EAAQ,CAACxtC,CAAD,CAAOytC,CAAP,CAAkBtS,CAAlB,CAA4B,CAE3CnnB,QAASA,EAAI,CAAC/T,CAAD,CAAK,CAChB,MAAO,SAAQ,CAAClF,CAAD,CAAQ,CACjByiC,CAAJ,GACAA,CACA,CADS,CAAA,CACT,CAAAv9B,CAAA5F,KAAA,CAAQ2F,CAAR,CAAcjF,CAAd,CAFA,CADqB,CADP,CADlB,IAAIyiC,EAAS,CAAA,CASb,OAAO,CAACxpB,CAAA,CAAKy5B,CAAL,CAAD,CAAkBz5B,CAAA,CAAKmnB,CAAL,CAAlB,CAVoC,CA2B7CuS,QAASA,EAAO,EAAG,CACjB,IAAAzG,QAAA;AAAe,CAAEvN,OAAQ,CAAV,CADE,CA6BnBiU,QAASA,EAAU,CAAC1zC,CAAD,CAAUgG,CAAV,CAAc,CAC/B,MAAO,SAAQ,CAAClF,CAAD,CAAQ,CACrBkF,CAAA5F,KAAA,CAAQJ,CAAR,CAAiBc,CAAjB,CADqB,CADQ,CA8BjC6yC,QAASA,EAAoB,CAACxtB,CAAD,CAAQ,CAC/BytB,CAAAztB,CAAAytB,iBAAJ,EAA+BztB,CAAA0tB,QAA/B,GACA1tB,CAAAytB,iBACA,CADyB,CAAA,CACzB,CAAAP,CAAA,CAAS,QAAQ,EAAG,CA3BO,IACvBrtC,CADuB,CACnB06B,CADmB,CACVmT,CAEjBA,EAAA,CAwBmC1tB,CAxBzB0tB,QAwByB1tB,EAvBnCytB,iBAAA,CAAyB,CAAA,CAuBUztB,EAtBnC0tB,QAAA,CAAgBz0C,CAChB,KAN2B,IAMlBuB,EAAI,CANc,CAMXW,EAAKuyC,CAAAp0C,OAArB,CAAqCkB,CAArC,CAAyCW,CAAzC,CAA6C,EAAEX,CAA/C,CAAkD,CAChD+/B,CAAA,CAAUmT,CAAA,CAAQlzC,CAAR,CAAA,CAAW,CAAX,CACVqF,EAAA,CAAK6tC,CAAA,CAAQlzC,CAAR,CAAA,CAmB4BwlB,CAnBjBsZ,OAAX,CACL,IAAI,CACEv/B,CAAA,CAAW8F,CAAX,CAAJ,CACE06B,CAAAoB,QAAA,CAAgB97B,CAAA,CAgBamgB,CAhBVrlB,MAAH,CAAhB,CADF,CAE4B,CAArB,GAewBqlB,CAfpBsZ,OAAJ,CACLiB,CAAAoB,QAAA,CAc6B3b,CAdbrlB,MAAhB,CADK,CAGL4/B,CAAAhB,OAAA,CAY6BvZ,CAZdrlB,MAAf,CANA,CAQF,MAAMmG,CAAN,CAAS,CACTy5B,CAAAhB,OAAA,CAAez4B,CAAf,CACA,CAAAqsC,CAAA,CAAiBrsC,CAAjB,CAFS,CAXqC,CAqB9B,CAApB,CAFA,CADmC,CAMrC6sC,QAASA,EAAQ,EAAG,CAClB,IAAApT,QAAA,CAAe,IAAI+S,CAEnB,KAAA3R,QAAA,CAAe4R,CAAA,CAAW,IAAX,CAAiB,IAAA5R,QAAjB,CACf,KAAApC,OAAA,CAAcgU,CAAA,CAAW,IAAX,CAAiB,IAAAhU,OAAjB,CACd,KAAAsH,OAAA,CAAc0M,CAAA,CAAW,IAAX,CAAiB,IAAA1M,OAAjB,CALI,CA7FpB,IAAI+M;AAAW10C,CAAA,CAAO,IAAP,CAAa20C,SAAb,CAgCfP,EAAAxxC,UAAA,CAAoB,CAClB81B,KAAMA,QAAQ,CAACkc,CAAD,CAAcC,CAAd,CAA0BC,CAA1B,CAAwC,CACpD,IAAI3vC,EAAS,IAAIsvC,CAEjB,KAAA9G,QAAA6G,QAAA,CAAuB,IAAA7G,QAAA6G,QAAvB,EAA+C,EAC/C,KAAA7G,QAAA6G,QAAArzC,KAAA,CAA0B,CAACgE,CAAD,CAASyvC,CAAT,CAAsBC,CAAtB,CAAkCC,CAAlC,CAA1B,CAC0B,EAA1B,CAAI,IAAAnH,QAAAvN,OAAJ,EAA6BkU,CAAA,CAAqB,IAAA3G,QAArB,CAE7B,OAAOxoC,EAAAk8B,QAP6C,CADpC,CAWlB,QAAS0T,QAAQ,CAAChtB,CAAD,CAAW,CAC1B,MAAO,KAAA2Q,KAAA,CAAU,IAAV,CAAgB3Q,CAAhB,CADmB,CAXV,CAelB,UAAWitB,QAAQ,CAACjtB,CAAD,CAAW+sB,CAAX,CAAyB,CAC1C,MAAO,KAAApc,KAAA,CAAU,QAAQ,CAACj3B,CAAD,CAAQ,CAC/B,MAAOwzC,EAAA,CAAexzC,CAAf,CAAsB,CAAA,CAAtB,CAA4BsmB,CAA5B,CADwB,CAA1B,CAEJ,QAAQ,CAAC7B,CAAD,CAAQ,CACjB,MAAO+uB,EAAA,CAAe/uB,CAAf,CAAsB,CAAA,CAAtB,CAA6B6B,CAA7B,CADU,CAFZ,CAIJ+sB,CAJI,CADmC,CAf1B,CAqEpBL,EAAA7xC,UAAA,CAAqB,CACnB6/B,QAASA,QAAQ,CAACz7B,CAAD,CAAM,CACjB,IAAAq6B,QAAAsM,QAAAvN,OAAJ,GACIp5B,CAAJ,GAAY,IAAAq6B,QAAZ,CACE,IAAA6T,SAAA,CAAcR,CAAA,CACZ,QADY,CAGZ1tC,CAHY,CAAd,CADF,CAOE,IAAAmuC,UAAA,CAAenuC,CAAf,CARF,CADqB,CADJ,CAenBmuC,UAAWA,QAAQ,CAACnuC,CAAD,CAAM,CAAA,IACnB0xB,CADmB;AACbmG,CAEVA,EAAA,CAAMqV,CAAA,CAAS,IAAT,CAAe,IAAAiB,UAAf,CAA+B,IAAAD,SAA/B,CACN,IAAI,CACF,GAAK/xC,CAAA,CAAS6D,CAAT,CAAL,EAAsBnG,CAAA,CAAWmG,CAAX,CAAtB,CAAwC0xB,CAAA,CAAO1xB,CAAP,EAAcA,CAAA0xB,KAClD73B,EAAA,CAAW63B,CAAX,CAAJ,EACE,IAAA2I,QAAAsM,QAAAvN,OACA,CAD+B,EAC/B,CAAA1H,CAAA33B,KAAA,CAAUiG,CAAV,CAAe63B,CAAA,CAAI,CAAJ,CAAf,CAAuBA,CAAA,CAAI,CAAJ,CAAvB,CAA+B,IAAA8I,OAA/B,CAFF,GAIE,IAAAtG,QAAAsM,QAAAlsC,MAEA,CAF6BuF,CAE7B,CADA,IAAAq6B,QAAAsM,QAAAvN,OACA,CAD8B,CAC9B,CAAAkU,CAAA,CAAqB,IAAAjT,QAAAsM,QAArB,CANF,CAFE,CAUF,MAAM/lC,CAAN,CAAS,CACTi3B,CAAA,CAAI,CAAJ,CAAA,CAAOj3B,CAAP,CACA,CAAAqsC,CAAA,CAAiBrsC,CAAjB,CAFS,CAdY,CAfN,CAmCnBy4B,OAAQA,QAAQ,CAAC/yB,CAAD,CAAS,CACnB,IAAA+zB,QAAAsM,QAAAvN,OAAJ,EACA,IAAA8U,SAAA,CAAc5nC,CAAd,CAFuB,CAnCN,CAwCnB4nC,SAAUA,QAAQ,CAAC5nC,CAAD,CAAS,CACzB,IAAA+zB,QAAAsM,QAAAlsC,MAAA,CAA6B6L,CAC7B,KAAA+zB,QAAAsM,QAAAvN,OAAA,CAA8B,CAC9BkU,EAAA,CAAqB,IAAAjT,QAAAsM,QAArB,CAHyB,CAxCR,CA8CnBhG,OAAQA,QAAQ,CAACyN,CAAD,CAAW,CACzB,IAAIxR,EAAY,IAAAvC,QAAAsM,QAAA6G,QAEoB,EAApC,EAAK,IAAAnT,QAAAsM,QAAAvN,OAAL;AAA0CwD,CAA1C,EAAuDA,CAAAxjC,OAAvD,EACE4zC,CAAA,CAAS,QAAQ,EAAG,CAElB,IAFkB,IACdjsB,CADc,CACJ5iB,CADI,CAET7D,EAAI,CAFK,CAEFW,EAAK2hC,CAAAxjC,OAArB,CAAuCkB,CAAvC,CAA2CW,CAA3C,CAA+CX,CAAA,EAA/C,CAAoD,CAClD6D,CAAA,CAASy+B,CAAA,CAAUtiC,CAAV,CAAA,CAAa,CAAb,CACTymB,EAAA,CAAW6b,CAAA,CAAUtiC,CAAV,CAAA,CAAa,CAAb,CACX,IAAI,CACF6D,CAAAwiC,OAAA,CAAc9mC,CAAA,CAAWknB,CAAX,CAAA,CAAuBA,CAAA,CAASqtB,CAAT,CAAvB,CAA4CA,CAA1D,CADE,CAEF,MAAMxtC,CAAN,CAAS,CACTqsC,CAAA,CAAiBrsC,CAAjB,CADS,CALuC,CAFlC,CAApB,CAJuB,CA9CR,CA4GrB,KAAIytC,EAAcA,QAAoB,CAAC5zC,CAAD,CAAQ6zC,CAAR,CAAkB,CACtD,IAAInwC,EAAS,IAAIsvC,CACba,EAAJ,CACEnwC,CAAAs9B,QAAA,CAAehhC,CAAf,CADF,CAGE0D,CAAAk7B,OAAA,CAAc5+B,CAAd,CAEF,OAAO0D,EAAAk8B,QAP+C,CAAxD,CAUI4T,EAAiBA,QAAuB,CAACxzC,CAAD,CAAQ8zC,CAAR,CAAoBxtB,CAApB,CAA8B,CACxE,IAAIytB,EAAiB,IACrB,IAAI,CACE30C,CAAA,CAAWknB,CAAX,CAAJ,GAA0BytB,CAA1B,CAA2CztB,CAAA,EAA3C,CADE,CAEF,MAAMngB,CAAN,CAAS,CACT,MAAOytC,EAAA,CAAYztC,CAAZ,CAAe,CAAA,CAAf,CADE,CAGX,MAAkB4tC,EAAlB,EApnYY30C,CAAA,CAonYM20C,CApnYK9c,KAAX,CAonYZ,CACS8c,CAAA9c,KAAA,CAAoB,QAAQ,EAAG,CACpC,MAAO2c,EAAA,CAAY5zC,CAAZ,CAAmB8zC,CAAnB,CAD6B,CAA/B,CAEJ,QAAQ,CAACrvB,CAAD,CAAQ,CACjB,MAAOmvB,EAAA,CAAYnvB,CAAZ,CAAmB,CAAA,CAAnB,CADU,CAFZ,CADT,CAOSmvB,CAAA,CAAY5zC,CAAZ,CAAmB8zC,CAAnB,CAd+D,CAV1E,CA2CIjU,EAAOA,QAAQ,CAAC7/B,CAAD,CAAQsmB,CAAR,CAAkB0tB,CAAlB,CAA2BX,CAA3B,CAAyC,CAC1D,IAAI3vC,EAAS,IAAIsvC,CACjBtvC,EAAAs9B,QAAA,CAAehhC,CAAf,CACA,OAAO0D,EAAAk8B,QAAA3I,KAAA,CAAoB3Q,CAApB,CAA8B0tB,CAA9B,CAAuCX,CAAvC,CAHmD,CA3C5D,CAyFIY,EAAKA,QAASC,EAAC,CAACC,CAAD,CAAW,CAC5B,GAAK,CAAA/0C,CAAA,CAAW+0C,CAAX,CAAL,CACE,KAAMlB,EAAA,CAAS,SAAT,CAAsDkB,CAAtD,CAAN,CAGF,GAAM,EAAA,IAAA;AAAgBD,CAAhB,CAAN,CAEE,MAAO,KAAIA,CAAJ,CAAMC,CAAN,CAGT,KAAIpT,EAAW,IAAIiS,CAUnBmB,EAAA,CARAzB,QAAkB,CAAC1yC,CAAD,CAAQ,CACxB+gC,CAAAC,QAAA,CAAiBhhC,CAAjB,CADwB,CAQ1B,CAJAogC,QAAiB,CAACv0B,CAAD,CAAS,CACxBk1B,CAAAnC,OAAA,CAAgB/yB,CAAhB,CADwB,CAI1B,CAEA,OAAOk1B,EAAAnB,QAtBqB,CAyB9BqU,EAAAhsB,MAAA,CA3SYA,QAAQ,EAAG,CACrB,MAAO,KAAI+qB,CADU,CA4SvBiB,EAAArV,OAAA,CAzHaA,QAAQ,CAAC/yB,CAAD,CAAS,CAC5B,IAAInI,EAAS,IAAIsvC,CACjBtvC,EAAAk7B,OAAA,CAAc/yB,CAAd,CACA,OAAOnI,EAAAk8B,QAHqB,CA0H9BqU,EAAApU,KAAA,CAAUA,CACVoU,EAAAv0B,IAAA,CApDAA,QAAY,CAAC00B,CAAD,CAAW,CAAA,IACjBrT,EAAW,IAAIiS,CADE,CAEjBtkC,EAAU,CAFO,CAGjB2lC,EAAUt1C,CAAA,CAAQq1C,CAAR,CAAA,CAAoB,EAApB,CAAyB,EAEvCp1C,EAAA,CAAQo1C,CAAR,CAAkB,QAAQ,CAACxU,CAAD,CAAUzgC,CAAV,CAAe,CACvCuP,CAAA,EACAmxB,EAAA,CAAKD,CAAL,CAAA3I,KAAA,CAAmB,QAAQ,CAACj3B,CAAD,CAAQ,CAC7Bq0C,CAAAh1C,eAAA,CAAuBF,CAAvB,CAAJ,GACAk1C,CAAA,CAAQl1C,CAAR,CACA,CADea,CACf,CAAM,EAAE0O,CAAR,EAAkBqyB,CAAAC,QAAA,CAAiBqT,CAAjB,CAFlB,CADiC,CAAnC,CAIG,QAAQ,CAACxoC,CAAD,CAAS,CACdwoC,CAAAh1C,eAAA,CAAuBF,CAAvB,CAAJ,EACA4hC,CAAAnC,OAAA,CAAgB/yB,CAAhB,CAFkB,CAJpB,CAFuC,CAAzC,CAYgB,EAAhB,GAAI6C,CAAJ,EACEqyB,CAAAC,QAAA,CAAiBqT,CAAjB,CAGF,OAAOtT,EAAAnB,QArBc,CAsDvB,OAAOqU,EAzUqC,CA4U9Cp8B,QAASA,GAAa,EAAE,CACtB,IAAAsI,KAAA,CAAY,CAAC,SAAD,CAAY,UAAZ,CAAwB,QAAQ,CAACzI,CAAD;AAAUF,CAAV,CAAoB,CAC9D,IAAI88B,EAAwB58B,CAAA48B,sBAAxBA,EACwB58B,CAAA68B,4BADxBD,EAEwB58B,CAAA88B,yBAF5B,CAIIC,EAAuB/8B,CAAA+8B,qBAAvBA,EACuB/8B,CAAAg9B,2BADvBD,EAEuB/8B,CAAAi9B,wBAFvBF,EAGuB/8B,CAAAk9B,kCAP3B,CASIC,EAAe,CAAEP,CAAAA,CATrB,CAUIQ,EAAMD,CAAA,CACN,QAAQ,CAAC3vC,CAAD,CAAK,CACX,IAAIskB,EAAK8qB,CAAA,CAAsBpvC,CAAtB,CACT,OAAO,SAAQ,EAAG,CAChBuvC,CAAA,CAAqBjrB,CAArB,CADgB,CAFP,CADP,CAON,QAAQ,CAACtkB,CAAD,CAAK,CACX,IAAI6vC,EAAQv9B,CAAA,CAAStS,CAAT,CAAa,KAAb,CAAoB,CAAA,CAApB,CACZ,OAAO,SAAQ,EAAG,CAChBsS,CAAA6Q,OAAA,CAAgB0sB,CAAhB,CADgB,CAFP,CAOjBD,EAAA3wB,UAAA,CAAgB0wB,CAEhB,OAAOC,EA3BuD,CAApD,CADU,CAmGxBv+B,QAASA,GAAkB,EAAE,CAC3B,IAAIy+B,EAAM,EAAV,CACIC,EAAmB12C,CAAA,CAAO,YAAP,CADvB,CAEI22C,EAAiB,IAFrB,CAGIC,EAAe,IAEnB,KAAAC,UAAA,CAAiBC,QAAQ,CAACr1C,CAAD,CAAQ,CAC3BS,SAAA9B,OAAJ,GACEq2C,CADF,CACQh1C,CADR,CAGA,OAAOg1C,EAJwB,CAOjC,KAAA70B,KAAA,CAAY,CAAC,WAAD,CAAc,mBAAd;AAAmC,QAAnC,CAA6C,UAA7C,CACR,QAAQ,CAAE4B,CAAF,CAAe3M,CAAf,CAAoCgB,CAApC,CAA8CxB,CAA9C,CAAwD,CA0ClE0gC,QAASA,EAAK,EAAG,CACf,IAAAC,IAAA,CAzoZG,EAAEr1C,EA0oZL,KAAA4gC,QAAA,CAAe,IAAA0U,QAAf,CAA8B,IAAAC,WAA9B,CACe,IAAAC,cADf,CACoC,IAAAC,cADpC,CAEe,IAAAC,YAFf,CAEkC,IAAAC,YAFlC,CAEqD,IACrD,KAAAC,MAAA,CAAa,IACb,KAAAxe,YAAA,CAAmB,CAAA,CACnB,KAAAye,YAAA,CAAmB,EACnB,KAAAC,gBAAA,CAAuB,EACvB,KAAAnqB,kBAAA,CAAyB,IATV,CAynCjBoqB,QAASA,EAAU,CAACC,CAAD,CAAQ,CACzB,GAAI5/B,CAAAwqB,QAAJ,CACE,KAAMmU,EAAA,CAAiB,QAAjB,CAAsD3+B,CAAAwqB,QAAtD,CAAN,CAGFxqB,CAAAwqB,QAAA,CAAqBoV,CALI,CAa3BC,QAASA,EAAsB,CAACC,CAAD,CAAU1Q,CAAV,CAAiB39B,CAAjB,CAAuB,CACpD,EACEquC,EAAAJ,gBAAA,CAAwBjuC,CAAxB,CAEA,EAFiC29B,CAEjC,CAAsC,CAAtC,GAAI0Q,CAAAJ,gBAAA,CAAwBjuC,CAAxB,CAAJ,EACE,OAAOquC,CAAAJ,gBAAA,CAAwBjuC,CAAxB,CAJX,OAMUquC,CANV,CAMoBA,CAAAZ,QANpB,CADoD,CActDa,QAASA,EAAY,EAAG,EAExBC,QAASA,EAAe,EAAG,CACzB,IAAA,CAAOC,CAAA53C,OAAP,CAAA,CACE,GAAI,CACF43C,CAAA/0B,MAAA,EAAA,EADE,CAEF,MAAMrb,CAAN,CAAS,CACTiP,CAAA,CAAkBjP,CAAlB,CADS,CAIbgvC,CAAA;AAAe,IARU,CAW3BqB,QAASA,EAAkB,EAAG,CACP,IAArB,GAAIrB,CAAJ,GACEA,CADF,CACiBvgC,CAAAqT,MAAA,CAAe,QAAQ,EAAG,CACvC3R,CAAAnN,OAAA,CAAkBmtC,CAAlB,CADuC,CAA1B,CADjB,CAD4B,CA7nC9BhB,CAAAn0C,UAAA,CAAkB,CAChB6K,YAAaspC,CADG,CA+BhBhnB,KAAMA,QAAQ,CAACmoB,CAAD,CAAUx1C,CAAV,CAAkB,CA0C9By1C,QAASA,EAAY,EAAG,CACtBC,CAAArf,YAAA,CAAoB,CAAA,CADE,CAzCxB,IAAIqf,CAEJ11C,EAAA,CAASA,CAAT,EAAmB,IAEfw1C,EAAJ,EACEE,CACA,CADQ,IAAIrB,CACZ,CAAAqB,CAAAb,MAAA,CAAc,IAAAA,MAFhB,GAMO,IAAAc,aAWL,GAVE,IAAAA,aAQA,CARoBC,QAAmB,EAAG,CACxC,IAAApB,WAAA,CAAkB,IAAAC,cAAlB,CACI,IAAAE,YADJ,CACuB,IAAAC,YADvB,CAC0C,IAC1C,KAAAE,YAAA,CAAmB,EACnB,KAAAC,gBAAA,CAAuB,EACvB,KAAAT,IAAA,CA5tZL,EAAEr1C,EA6tZG,KAAA02C,aAAA,CAAoB,IANoB,CAQ1C,CAAA,IAAAA,aAAAz1C,UAAA,CAA8B,IAEhC,EAAAw1C,CAAA,CAAQ,IAAI,IAAAC,aAjBd,CAmBAD,EAAAnB,QAAA,CAAgBv0C,CAChB01C,EAAAhB,cAAA,CAAsB10C,CAAA40C,YAClB50C,EAAA20C,YAAJ;CACE30C,CAAA40C,YAAAH,cACA,CADmCiB,CACnC,CAAA11C,CAAA40C,YAAA,CAAqBc,CAFvB,EAIE11C,CAAA20C,YAJF,CAIuB30C,CAAA40C,YAJvB,CAI4Cc,CAQ5C,EAAIF,CAAJ,EAAex1C,CAAf,EAAyB,IAAzB,GAA+B01C,CAAAxiB,IAAA,CAAU,UAAV,CAAsBuiB,CAAtB,CAE/B,OAAOC,EAxCuB,CA/BhB,CAkMhB10C,OAAQA,QAAQ,CAAC60C,CAAD,CAAWnxB,CAAX,CAAqBwf,CAArB,CAAqC,CACnD,IAAIl7B,EAAMmM,CAAA,CAAO0gC,CAAP,CAEV,IAAI7sC,CAAAi7B,gBAAJ,CACE,MAAOj7B,EAAAi7B,gBAAA,CAAoB,IAApB,CAA0Bvf,CAA1B,CAAoCwf,CAApC,CAAoDl7B,CAApD,CAJ0C,KAO/CjH,EADQiG,IACAwsC,WAPuC,CAQ/CsB,EAAU,CACR7xC,GAAIygB,CADI,CAER/F,KAAMy2B,CAFE,CAGRpsC,IAAKA,CAHG,CAIR66B,IAAKgS,CAJG,CAKRE,GAAI,CAAE7R,CAAAA,CALE,CAQd+P,EAAA,CAAiB,IAEZ91C,EAAA,CAAWumB,CAAX,CAAL,GACEoxB,CAAA7xC,GADF,CACe9D,CADf,CAIK4B,EAAL,GACEA,CADF,CAhBYiG,IAiBFwsC,WADV,CAC6B,EAD7B,CAKAzyC,EAAA0F,QAAA,CAAcquC,CAAd,CAEA,OAAOE,SAAwB,EAAG,CAChCl0C,EAAA,CAAYC,CAAZ,CAAmB+zC,CAAnB,CACA7B,EAAA,CAAiB,IAFe,CA7BiB,CAlMrC,CA8PhB9P,YAAaA,QAAQ,CAAC8R,CAAD,CAAmBvxB,CAAnB,CAA6B,CAwChDwxB,QAASA,EAAgB,EAAG,CAC1BC,CAAA,CAA0B,CAAA,CAEtBC,EAAJ,EACEA,CACA,CADW,CAAA,CACX,CAAA1xB,CAAA,CAAS2xB,CAAT,CAAoBA,CAApB,CAA+BryC,CAA/B,CAFF,EAIE0gB,CAAA,CAAS2xB,CAAT,CAAoBhS,CAApB,CAA+BrgC,CAA/B,CAPwB,CAvC5B,IAAIqgC,EAAgBxiB,KAAJ,CAAUo0B,CAAAv4C,OAAV,CAAhB,CACI24C,EAAgBx0B,KAAJ,CAAUo0B,CAAAv4C,OAAV,CADhB,CAEI44C,EAAgB,EAFpB,CAGItyC,EAAO,IAHX,CAIImyC,EAA0B,CAAA,CAJ9B,CAKIC,EAAW,CAAA,CAEf,IAAK14C,CAAAu4C,CAAAv4C,OAAL,CAA8B,CAE5B,IAAI64C;AAAa,CAAA,CACjBvyC,EAAAjD,WAAA,CAAgB,QAAS,EAAG,CACtBw1C,CAAJ,EAAgB7xB,CAAA,CAAS2xB,CAAT,CAAoBA,CAApB,CAA+BryC,CAA/B,CADU,CAA5B,CAGA,OAAOwyC,SAA6B,EAAG,CACrCD,CAAA,CAAa,CAAA,CADwB,CANX,CAW9B,GAAgC,CAAhC,GAAIN,CAAAv4C,OAAJ,CAEE,MAAO,KAAAsD,OAAA,CAAYi1C,CAAA,CAAiB,CAAjB,CAAZ,CAAiCC,QAAyB,CAACn3C,CAAD,CAAQi5B,CAAR,CAAkBhwB,CAAlB,CAAyB,CACxFquC,CAAA,CAAU,CAAV,CAAA,CAAet3C,CACfslC,EAAA,CAAU,CAAV,CAAA,CAAerM,CACftT,EAAA,CAAS2xB,CAAT,CAAqBt3C,CAAD,GAAWi5B,CAAX,CAAuBqe,CAAvB,CAAmChS,CAAvD,CAAkEr8B,CAAlE,CAHwF,CAAnF,CAOTjK,EAAA,CAAQk4C,CAAR,CAA0B,QAAS,CAACQ,CAAD,CAAO73C,CAAP,CAAU,CAC3C,IAAI83C,EAAY1yC,CAAAhD,OAAA,CAAYy1C,CAAZ,CAAkBE,QAA4B,CAAC53C,CAAD,CAAQi5B,CAAR,CAAkB,CAC9Eqe,CAAA,CAAUz3C,CAAV,CAAA,CAAeG,CACfslC,EAAA,CAAUzlC,CAAV,CAAA,CAAeo5B,CACVme,EAAL,GACEA,CACA,CAD0B,CAAA,CAC1B,CAAAnyC,CAAAjD,WAAA,CAAgBm1C,CAAhB,CAFF,CAH8E,CAAhE,CAQhBI,EAAA73C,KAAA,CAAmBi4C,CAAnB,CAT2C,CAA7C,CAuBA,OAAOF,SAA6B,EAAG,CACrC,IAAA,CAAOF,CAAA54C,OAAP,CAAA,CACE44C,CAAA/1B,MAAA,EAAA,EAFmC,CAnDS,CA9PlC,CAgXhBq2B,iBAAkBA,QAAQ,CAACp5C,CAAD,CAAMknB,CAAN,CAAgB,CAoBxCmyB,QAASA,EAA2B,CAACC,CAAD,CAAS,CAC3C/e,CAAA,CAAW+e,CADgC,KAE5B54C,CAF4B,CAEvB64C,CAFuB,CAEdC,CAFc,CAELC,CAEtC,IAAKx2C,CAAA,CAASs3B,CAAT,CAAL,CAKO,GAAIx6B,EAAA,CAAYw6B,CAAZ,CAAJ,CAgBL,IAfIC,CAeKp5B,GAfQs4C,CAeRt4C,GAbPo5B,CAEA,CAFWkf,CAEX,CADAC,CACA,CADYnf,CAAAt6B,OACZ,CAD8B,CAC9B,CAAA05C,CAAA,EAWOx4C,EARTy4C,CAQSz4C,CARGm5B,CAAAr6B,OAQHkB,CANLu4C,CAMKv4C,GANSy4C,CAMTz4C,GAJPw4C,CAAA,EACA,CAAApf,CAAAt6B,OAAA,CAAkBy5C,CAAlB,CAA8BE,CAGvBz4C,EAAAA,CAAAA,CAAI,CAAb,CAAgBA,CAAhB,CAAoBy4C,CAApB,CAA+Bz4C,CAAA,EAA/B,CACEq4C,CAIA,CAJUjf,CAAA,CAASp5B,CAAT,CAIV,CAHAo4C,CAGA,CAHUjf,CAAA,CAASn5B,CAAT,CAGV,CADAm4C,CACA,CADWE,CACX,GADuBA,CACvB,EADoCD,CACpC,GADgDA,CAChD,CAAKD,CAAL,EAAiBE,CAAjB;AAA6BD,CAA7B,GACEI,CAAA,EACA,CAAApf,CAAA,CAASp5B,CAAT,CAAA,CAAco4C,CAFhB,CArBG,KA0BA,CACDhf,CAAJ,GAAiBsf,CAAjB,GAEEtf,CAEA,CAFWsf,CAEX,CAF4B,EAE5B,CADAH,CACA,CADY,CACZ,CAAAC,CAAA,EAJF,CAOAC,EAAA,CAAY,CACZ,KAAKn5C,CAAL,GAAY65B,EAAZ,CACMA,CAAA35B,eAAA,CAAwBF,CAAxB,CAAJ,GACEm5C,CAAA,EAIA,CAHAL,CAGA,CAHUjf,CAAA,CAAS75B,CAAT,CAGV,CAFA+4C,CAEA,CAFUjf,CAAA,CAAS95B,CAAT,CAEV,CAAIA,CAAJ,GAAW85B,EAAX,EACE+e,CACA,CADWE,CACX,GADuBA,CACvB,EADoCD,CACpC,GADgDA,CAChD,CAAKD,CAAL,EAAiBE,CAAjB,GAA6BD,CAA7B,GACEI,CAAA,EACA,CAAApf,CAAA,CAAS95B,CAAT,CAAA,CAAgB84C,CAFlB,CAFF,GAOEG,CAAA,EAEA,CADAnf,CAAA,CAAS95B,CAAT,CACA,CADgB84C,CAChB,CAAAI,CAAA,EATF,CALF,CAkBF,IAAID,CAAJ,CAAgBE,CAAhB,CAGE,IAAIn5C,CAAJ,GADAk5C,EAAA,EACWpf,CAAAA,CAAX,CACOD,CAAA35B,eAAA,CAAwBF,CAAxB,CAAL,GACEi5C,CAAA,EACA,CAAA,OAAOnf,CAAA,CAAS95B,CAAT,CAFT,CAhCC,CA/BP,IACM85B,EAAJ,GAAiBD,CAAjB,GACEC,CACA,CADWD,CACX,CAAAqf,CAAA,EAFF,CAqEF,OAAOA,EA1EoC,CAnB7CP,CAAA7jB,UAAA,CAAwC,CAAA,CAExC,KAAIhvB,EAAO,IAAX,CAEI+zB,CAFJ,CAKIC,CALJ,CAOIuf,CAPJ,CASIC,EAAuC,CAAvCA,CAAqB9yB,CAAAhnB,OATzB,CAUI05C,EAAiB,CAVrB,CAWIK,EAAiBtiC,CAAA,CAAO3X,CAAP,CAAYq5C,CAAZ,CAXrB,CAYIK,EAAgB,EAZpB,CAaII,EAAiB,EAbrB,CAcII,EAAU,CAAA,CAdd,CAeIP,EAAY,CA4GhB,OAAO,KAAAn2C,OAAA,CAAYy2C,CAAZ,CA7BPE,QAA+B,EAAG,CAC5BD,CAAJ,EACEA,CACA,CADU,CAAA,CACV,CAAAhzB,CAAA,CAASqT,CAAT,CAAmBA,CAAnB,CAA6B/zB,CAA7B,CAFF,EAIE0gB,CAAA,CAASqT,CAAT,CAAmBwf,CAAnB,CAAiCvzC,CAAjC,CAIF,IAAIwzC,CAAJ,CACE,GAAK/2C,CAAA,CAASs3B,CAAT,CAAL,CAGO,GAAIx6B,EAAA,CAAYw6B,CAAZ,CAAJ,CAA2B,CAChCwf,CAAA,CAAmB11B,KAAJ,CAAUkW,CAAAr6B,OAAV,CACf,KAAS,IAAAkB,EAAI,CAAb,CAAgBA,CAAhB,CAAoBm5B,CAAAr6B,OAApB,CAAqCkB,CAAA,EAArC,CACE24C,CAAA,CAAa34C,CAAb,CAAA,CAAkBm5B,CAAA,CAASn5B,CAAT,CAHY,CAA3B,IAOL,KAASV,CAAT,GADAq5C,EACgBxf,CADD,EACCA,CAAAA,CAAhB,CACM35B,EAAAC,KAAA,CAAoB05B,CAApB;AAA8B75B,CAA9B,CAAJ,GACEq5C,CAAA,CAAar5C,CAAb,CADF,CACsB65B,CAAA,CAAS75B,CAAT,CADtB,CAXJ,KAEEq5C,EAAA,CAAexf,CAZa,CA6B3B,CA9HiC,CAhX1B,CAoiBhBmU,QAASA,QAAQ,EAAG,CAAA,IACd0L,CADc,CACP74C,CADO,CACA4f,CADA,CAEdk5B,CAFc,CAGdn6C,CAHc,CAIdo6C,CAJc,CAIPC,EAAMhE,CAJC,CAKRoB,CALQ,CAMd6C,EAAW,EANG,CAOdC,CAPc,CAONC,CAPM,CAOEC,CAEpBnD,EAAA,CAAW,SAAX,CAEArhC,EAAAwS,iBAAA,EAEI,KAAJ,GAAa9Q,CAAb,EAA4C,IAA5C,GAA2B6+B,CAA3B,GAGEvgC,CAAAqT,MAAAI,OAAA,CAAsB8sB,CAAtB,CACA,CAAAmB,CAAA,EAJF,CAOApB,EAAA,CAAiB,IAEjB,GAAG,CACD6D,CAAA,CAAQ,CAAA,CAGR,KAFA3C,CAEA,CArB0BxJ,IAqB1B,CAAMyM,CAAA16C,OAAN,CAAA,CAAyB,CACvB,GAAI,CACFy6C,CACA,CADYC,CAAA73B,MAAA,EACZ,CAAA43B,CAAAnwC,MAAAqwC,MAAA,CAAsBF,CAAA3c,WAAtB,CAFE,CAGF,MAAOt2B,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CAGZ+uC,CAAA,CAAiB,IAPM,CAUzB,CAAA,CACA,EAAG,CACD,GAAK4D,CAAL,CAAgB1C,CAAAX,WAAhB,CAGE,IADA92C,CACA,CADSm6C,CAAAn6C,OACT,CAAOA,CAAA,EAAP,CAAA,CACE,GAAI,CAIF,GAHAk6C,CAGA,CAHQC,CAAA,CAASn6C,CAAT,CAGR,CACE,IAAKqB,CAAL,CAAa64C,CAAA5uC,IAAA,CAAUmsC,CAAV,CAAb,KAAsCx2B,CAAtC,CAA6Ci5B,CAAAj5B,KAA7C,GACM,EAAAi5B,CAAA7B,GAAA,CACI1yC,EAAA,CAAOtE,CAAP,CAAc4f,CAAd,CADJ,CAEsB,QAFtB,GAEK,MAAO5f,EAFZ,EAEkD,QAFlD,GAEkC,MAAO4f,EAFzC,EAGQ25B,KAAA,CAAMv5C,CAAN,CAHR,EAGwBu5C,KAAA,CAAM35B,CAAN,CAHxB,CADN,CAKEm5B,CAIA,CAJQ,CAAA,CAIR,CAHA7D,CAGA,CAHiB2D,CAGjB,CAFAA,CAAAj5B,KAEA,CAFai5B,CAAA7B,GAAA,CAAW5zC,EAAA,CAAKpD,CAAL,CAAY,IAAZ,CAAX,CAA+BA,CAE5C,CADA64C,CAAA3zC,GAAA,CAASlF,CAAT,CAAkB4f,CAAD,GAAUy2B,CAAV,CAA0Br2C,CAA1B,CAAkC4f,CAAnD,CAA0Dw2B,CAA1D,CACA,CAAU,CAAV,CAAI4C,CAAJ,GACEE,CAMA,CANS,CAMT,CANaF,CAMb,CALKC,CAAA,CAASC,CAAT,CAKL,GALuBD,CAAA,CAASC,CAAT,CAKvB;AAL0C,EAK1C,EAJAC,CAIA,CAJU/5C,CAAA,CAAWy5C,CAAA/T,IAAX,CAAD,CACH,MADG,EACO+T,CAAA/T,IAAA/8B,KADP,EACyB8wC,CAAA/T,IAAAjjC,SAAA,EADzB,EAEHg3C,CAAA/T,IAEN,CADAqU,CACA,EADU,YACV,CADyB3zC,EAAA,CAAOxF,CAAP,CACzB,CADyC,YACzC,CADwDwF,EAAA,CAAOoa,CAAP,CACxD,CAAAq5B,CAAA,CAASC,CAAT,CAAAx5C,KAAA,CAAsBy5C,CAAtB,CAPF,CATF,KAkBO,IAAIN,CAAJ,GAAc3D,CAAd,CAA8B,CAGnC6D,CAAA,CAAQ,CAAA,CACR,OAAM,CAJ6B,CAvBrC,CA8BF,MAAO5yC,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CAShB,GAAM,EAAAqzC,CAAA,CAAQpD,CAAAR,YAAR,EACDQ,CADC,GA5EkBxJ,IA4ElB,EACqBwJ,CAAAV,cADrB,CAAN,CAEE,IAAA,CAAMU,CAAN,GA9EsBxJ,IA8EtB,EAA8B,EAAA4M,CAAA,CAAOpD,CAAAV,cAAP,CAA9B,CAAA,CACEU,CAAA,CAAUA,CAAAZ,QA/Cb,CAAH,MAkDUY,CAlDV,CAkDoBoD,CAlDpB,CAsDA,KAAIT,CAAJ,EAAaM,CAAA16C,OAAb,GAAqC,CAAAq6C,CAAA,EAArC,CAEE,KA6dN1iC,EAAAwqB,QA7dY,CA6dS,IA7dT,CAAAmU,CAAA,CAAiB,QAAjB,CAGFD,CAHE,CAGGxvC,EAAA,CAAOyzC,CAAP,CAHH,CAAN,CAvED,CAAH,MA6ESF,CA7ET,EA6EkBM,CAAA16C,OA7ElB,CAiFA,KAmdF2X,CAAAwqB,QAndE,CAmdmB,IAndnB,CAAM2Y,CAAA96C,OAAN,CAAA,CACE,GAAI,CACF86C,CAAAj4B,MAAA,EAAA,EADE,CAEF,MAAOrb,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CA1GI,CApiBJ,CAurBhBqF,SAAUA,QAAQ,EAAG,CAEnB,GAAI8rB,CAAA,IAAAA,YAAJ,CAAA,CACA,IAAIr2B,EAAS,IAAAu0C,QAEb,KAAApJ,WAAA,CAAgB,UAAhB,CACA,KAAA9U,YAAA;AAAmB,CAAA,CACnB,IAAI,IAAJ,GAAahhB,CAAb,CAAA,CAEA,IAASojC,IAAAA,CAAT,GAAsB,KAAA1D,gBAAtB,CACEG,CAAA,CAAuB,IAAvB,CAA6B,IAAAH,gBAAA,CAAqB0D,CAArB,CAA7B,CAA8DA,CAA9D,CAKEz4C,EAAA20C,YAAJ,EAA0B,IAA1B,GAAgC30C,CAAA20C,YAAhC,CAAqD,IAAAF,cAArD,CACIz0C,EAAA40C,YAAJ,EAA0B,IAA1B,GAAgC50C,CAAA40C,YAAhC,CAAqD,IAAAF,cAArD,CACI,KAAAA,cAAJ,GAAwB,IAAAA,cAAAD,cAAxB,CAA2D,IAAAA,cAA3D,CACI,KAAAA,cAAJ,GAAwB,IAAAA,cAAAC,cAAxB,CAA2D,IAAAA,cAA3D,CAGA,KAAAnqC,SAAA,CAAgB,IAAA2hC,QAAhB,CAA+B,IAAAhkC,OAA/B,CAA6C,IAAAnH,WAA7C,CAA+D,IAAA6+B,YAA/D,CAAkFz/B,CAClF,KAAA+yB,IAAA,CAAW,IAAAlyB,OAAX,CAAyB,IAAAmjC,YAAzB,CAA4CuU,QAAQ,EAAG,CAAE,MAAOv4C,EAAT,CACvD,KAAA20C,YAAA,CAAmB,EAUnB,KAAAP,QAAA;AAAe,IAAAE,cAAf,CAAoC,IAAAC,cAApC,CAAyD,IAAAC,YAAzD,CACI,IAAAC,YADJ,CACuB,IAAAC,MADvB,CACoC,IAAAL,WADpC,CACsD,IA3BtD,CALA,CAFmB,CAvrBL,CAwvBhB6D,MAAOA,QAAQ,CAAC5B,CAAD,CAAOj2B,CAAP,CAAe,CAC5B,MAAOrL,EAAA,CAAOshC,CAAP,CAAA,CAAa,IAAb,CAAmBj2B,CAAnB,CADqB,CAxvBd,CAyxBhBzf,WAAYA,QAAQ,CAAC01C,CAAD,CAAO,CAGpBphC,CAAAwqB,QAAL,EAA4BuY,CAAA16C,OAA5B,EACEiW,CAAAqT,MAAA,CAAe,QAAQ,EAAG,CACpBoxB,CAAA16C,OAAJ,EACE2X,CAAA62B,QAAA,EAFsB,CAA1B,CAOFkM,EAAA35C,KAAA,CAAgB,CAACuJ,MAAO,IAAR,CAAcwzB,WAAYib,CAA1B,CAAhB,CAXyB,CAzxBX,CAuyBhBnG,aAAeA,QAAQ,CAACrsC,CAAD,CAAK,CAC1Bu0C,CAAA/5C,KAAA,CAAqBwF,CAArB,CAD0B,CAvyBZ,CAw1BhBiE,OAAQA,QAAQ,CAACuuC,CAAD,CAAO,CACrB,GAAI,CAEF,MADAzB,EAAA,CAAW,QAAX,CACO,CAAA,IAAAqD,MAAA,CAAW5B,CAAX,CAFL,CAGF,MAAOvxC,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CAHZ,OAKU,CAgQZmQ,CAAAwqB,QAAA,CAAqB,IA9PjB,IAAI,CACFxqB,CAAA62B,QAAA,EADE,CAEF,MAAOhnC,CAAP,CAAU,CAEV,KADAiP,EAAA,CAAkBjP,CAAlB,CACMA,CAAAA,CAAN,CAFU,CAJJ,CANW,CAx1BP,CA03BhB06B,YAAaA,QAAQ,CAAC6W,CAAD,CAAO,CAK1BkC,QAASA,EAAqB,EAAG,CAC/B3wC,CAAAqwC,MAAA,CAAY5B,CAAZ,CAD+B,CAJjC,IAAIzuC,EAAQ,IACZyuC,EAAA;AAAQnB,CAAA72C,KAAA,CAAqBk6C,CAArB,CACRpD,EAAA,EAH0B,CA13BZ,CA+5BhBriB,IAAKA,QAAQ,CAACpsB,CAAD,CAAO4d,CAAP,CAAiB,CAC5B,IAAIk0B,EAAiB,IAAA9D,YAAA,CAAiBhuC,CAAjB,CAChB8xC,EAAL,GACE,IAAA9D,YAAA,CAAiBhuC,CAAjB,CADF,CAC2B8xC,CAD3B,CAC4C,EAD5C,CAGAA,EAAAn6C,KAAA,CAAoBimB,CAApB,CAEA,KAAIywB,EAAU,IACd,GACOA,EAAAJ,gBAAA,CAAwBjuC,CAAxB,CAGL,GAFEquC,CAAAJ,gBAAA,CAAwBjuC,CAAxB,CAEF,CAFkC,CAElC,EAAAquC,CAAAJ,gBAAA,CAAwBjuC,CAAxB,CAAA,EAJF,OAKUquC,CALV,CAKoBA,CAAAZ,QALpB,CAOA,KAAIvwC,EAAO,IACX,OAAO,SAAQ,EAAG,CAChB40C,CAAA,CAAeA,CAAA32C,QAAA,CAAuByiB,CAAvB,CAAf,CAAA,CAAmD,IACnDwwB,EAAA,CAAuBlxC,CAAvB,CAA6B,CAA7B,CAAgC8C,CAAhC,CAFgB,CAhBU,CA/5Bd,CA48BhB+xC,MAAOA,QAAQ,CAAC/xC,CAAD,CAAOkX,CAAP,CAAa,CAAA,IACtB/Y,EAAQ,EADc,CAEtB2zC,CAFsB,CAGtB5wC,EAAQ,IAHc,CAItBqV,EAAkB,CAAA,CAJI,CAKtBV,EAAQ,CACN7V,KAAMA,CADA,CAENgyC,YAAa9wC,CAFP,CAGNqV,gBAAiBA,QAAQ,EAAG,CAACA,CAAA,CAAkB,CAAA,CAAnB,CAHtB,CAINyuB,eAAgBA,QAAQ,EAAG,CACzBnvB,CAAAG,iBAAA,CAAyB,CAAA,CADA,CAJrB,CAONA,iBAAkB,CAAA,CAPZ,CALc,CActBi8B,EAAep1C,EAAA,CAAO,CAACgZ,CAAD,CAAP,CAAgBnd,SAAhB,CAA2B,CAA3B,CAdO,CAetBZ,CAfsB,CAenBlB,CAEP,GAAG,CACDk7C,CAAA,CAAiB5wC,CAAA8sC,YAAA,CAAkBhuC,CAAlB,CAAjB,EAA4C7B,CAC5C0X,EAAAq8B,aAAA,CAAqBhxC,CAChBpJ;CAAA,CAAE,CAAP,KAAUlB,CAAV,CAAiBk7C,CAAAl7C,OAAjB,CAAwCkB,CAAxC,CAA0ClB,CAA1C,CAAkDkB,CAAA,EAAlD,CAGE,GAAKg6C,CAAA,CAAeh6C,CAAf,CAAL,CAMA,GAAI,CAEFg6C,CAAA,CAAeh6C,CAAf,CAAAwF,MAAA,CAAwB,IAAxB,CAA8B20C,CAA9B,CAFE,CAGF,MAAO7zC,CAAP,CAAU,CACViP,CAAA,CAAkBjP,CAAlB,CADU,CATZ,IACE0zC,EAAA12C,OAAA,CAAsBtD,CAAtB,CAAyB,CAAzB,CAEA,CADAA,CAAA,EACA,CAAAlB,CAAA,EAWJ,IAAI2f,CAAJ,CAEE,MADAV,EAAAq8B,aACOr8B,CADc,IACdA,CAAAA,CAGT3U,EAAA,CAAQA,CAAAusC,QAzBP,CAAH,MA0BSvsC,CA1BT,CA4BA2U,EAAAq8B,aAAA,CAAqB,IAErB,OAAOr8B,EA/CmB,CA58BZ,CAohChBwuB,WAAYA,QAAQ,CAACrkC,CAAD,CAAOkX,CAAP,CAAa,CAAA,IAE3Bm3B,EADSxJ,IADkB,CAG3B4M,EAFS5M,IADkB,CAI3BhvB,EAAQ,CACN7V,KAAMA,CADA,CAENgyC,YALOnN,IAGD,CAGNG,eAAgBA,QAAQ,EAAG,CACzBnvB,CAAAG,iBAAA,CAAyB,CAAA,CADA,CAHrB,CAMNA,iBAAkB,CAAA,CANZ,CASZ,IAAK,CAZQ6uB,IAYRoJ,gBAAA,CAAuBjuC,CAAvB,CAAL,CAAmC,MAAO6V,EAM1C,KAnB+B,IAe3Bo8B,EAAep1C,EAAA,CAAO,CAACgZ,CAAD,CAAP,CAAgBnd,SAAhB,CAA2B,CAA3B,CAfY,CAgBhBZ,CAhBgB,CAgBblB,CAGlB,CAAQy3C,CAAR,CAAkBoD,CAAlB,CAAA,CAAyB,CACvB57B,CAAAq8B,aAAA,CAAqB7D,CACrBjb,EAAA,CAAYib,CAAAL,YAAA,CAAoBhuC,CAApB,CAAZ,EAAyC,EACpClI,EAAA,CAAE,CAAP,KAAUlB,CAAV,CAAmBw8B,CAAAx8B,OAAnB,CAAqCkB,CAArC,CAAuClB,CAAvC,CAA+CkB,CAAA,EAA/C,CAEE,GAAKs7B,CAAA,CAAUt7B,CAAV,CAAL,CAOA,GAAI,CACFs7B,CAAA,CAAUt7B,CAAV,CAAAwF,MAAA,CAAmB,IAAnB,CAAyB20C,CAAzB,CADE,CAEF,MAAM7zC,CAAN,CAAS,CACTiP,CAAA,CAAkBjP,CAAlB,CADS,CATX,IACEg1B,EAAAh4B,OAAA,CAAiBtD,CAAjB;AAAoB,CAApB,CAEA,CADAA,CAAA,EACA,CAAAlB,CAAA,EAeJ,IAAM,EAAA66C,CAAA,CAASpD,CAAAJ,gBAAA,CAAwBjuC,CAAxB,CAAT,EAA0CquC,CAAAR,YAA1C,EACDQ,CADC,GAzCKxJ,IAyCL,EACqBwJ,CAAAV,cADrB,CAAN,CAEE,IAAA,CAAMU,CAAN,GA3CSxJ,IA2CT,EAA8B,EAAA4M,CAAA,CAAOpD,CAAAV,cAAP,CAA9B,CAAA,CACEU,CAAA,CAAUA,CAAAZ,QA1BS,CA+BzB53B,CAAAq8B,aAAA,CAAqB,IACrB,OAAOr8B,EAnDwB,CAphCjB,CA2kClB,KAAItH,EAAa,IAAIg/B,CAArB,CAGI+D,EAAa/iC,CAAA4jC,aAAbb,CAAuC,EAH3C,CAIII,EAAkBnjC,CAAA6jC,kBAAlBV,CAAiD,EAJrD,CAKIlD,EAAkBjgC,CAAA8jC,kBAAlB7D,CAAiD,EAErD,OAAOjgC,EAhqC2D,CADxD,CAbe,CAuuC7BtH,QAASA,GAAqB,EAAG,CAAA,IAC3B8c,EAA6B,mCADF,CAE7BG,EAA8B,4CAkBhC,KAAAH,2BAAA,CAAkCC,QAAQ,CAACC,CAAD,CAAS,CACjD,MAAIvqB,EAAA,CAAUuqB,CAAV,CAAJ,EACEF,CACO,CADsBE,CACtB,CAAA,IAFT,EAIOF,CAL0C,CAyBnD,KAAAG,4BAAA,CAAmCC,QAAQ,CAACF,CAAD,CAAS,CAClD,MAAIvqB,EAAA,CAAUuqB,CAAV,CAAJ,EACEC,CACO,CADuBD,CACvB,CAAA,IAFT,EAIOC,CAL2C,CAQpD,KAAA9L,KAAA;AAAYqI,QAAQ,EAAG,CACrB,MAAO6xB,SAAoB,CAACC,CAAD,CAAMC,CAAN,CAAe,CACxC,IAAIC,EAAQD,CAAA,CAAUtuB,CAAV,CAAwCH,CAApD,CACI2uB,CACJA,EAAA,CAAgBpX,EAAA,CAAWiX,CAAX,CAAA7zB,KAChB,OAAsB,EAAtB,GAAIg0B,CAAJ,EAA6BA,CAAA32C,MAAA,CAAoB02C,CAApB,CAA7B,CAGOF,CAHP,CACS,SADT,CACmBG,CALqB,CADrB,CArDQ,CAyFjCC,QAASA,GAAa,CAACC,CAAD,CAAU,CAC9B,GAAgB,MAAhB,GAAIA,CAAJ,CACE,MAAOA,EACF,IAAI77C,CAAA,CAAS67C,CAAT,CAAJ,CAAuB,CAK5B,GAA8B,EAA9B,CAAIA,CAAAz3C,QAAA,CAAgB,KAAhB,CAAJ,CACE,KAAM03C,GAAA,CAAW,QAAX,CACsDD,CADtD,CAAN,CAGFA,CAAA,CAA0BA,CAjBrBn0C,QAAA,CAAU,+BAAV,CAA2C,MAA3C,CAAAA,QAAA,CACU,OADV,CACmB,OADnB,CAiBKA,QAAA,CACY,QADZ,CACsB,IADtB,CAAAA,QAAA,CAEY,KAFZ,CAEmB,YAFnB,CAGV,OAAO,KAAI3C,MAAJ,CAAW,GAAX,CAAiB82C,CAAjB,CAA2B,GAA3B,CAZqB,CAavB,GAAI74C,EAAA,CAAS64C,CAAT,CAAJ,CAIL,MAAO,KAAI92C,MAAJ,CAAW,GAAX,CAAiB82C,CAAAt3C,OAAjB,CAAkC,GAAlC,CAEP,MAAMu3C,GAAA,CAAW,UAAX,CAAN,CAtB4B,CA4BhCC,QAASA,GAAc,CAACC,CAAD,CAAW,CAChC,IAAIC,EAAmB,EACnBt5C,EAAA,CAAUq5C,CAAV,CAAJ,EACE97C,CAAA,CAAQ87C,CAAR,CAAkB,QAAQ,CAACH,CAAD,CAAU,CAClCI,CAAAr7C,KAAA,CAAsBg7C,EAAA,CAAcC,CAAd,CAAtB,CADkC,CAApC,CAIF,OAAOI,EAPyB,CA8ElChkC,QAASA,GAAoB,EAAG,CAC9B,IAAAikC,aAAA;AAAoBA,EADU,KAI1BC,EAAuB,CAAC,MAAD,CAJG,CAK1BC,EAAuB,EAwB3B,KAAAD,qBAAA,CAA4BE,QAAS,CAACn7C,CAAD,CAAQ,CACvCS,SAAA9B,OAAJ,GACEs8C,CADF,CACyBJ,EAAA,CAAe76C,CAAf,CADzB,CAGA,OAAOi7C,EAJoC,CAkC7C,KAAAC,qBAAA,CAA4BE,QAAS,CAACp7C,CAAD,CAAQ,CACvCS,SAAA9B,OAAJ,GACEu8C,CADF,CACyBL,EAAA,CAAe76C,CAAf,CADzB,CAGA,OAAOk7C,EAJoC,CAO7C,KAAA/6B,KAAA,CAAY,CAAC,WAAD,CAAc,QAAQ,CAAC4B,CAAD,CAAY,CAW5Cs5B,QAASA,EAAQ,CAACV,CAAD,CAAUlS,CAAV,CAAqB,CACpC,MAAgB,MAAhB,GAAIkS,CAAJ,CACSnZ,EAAA,CAAgBiH,CAAhB,CADT,CAIS,CAAE,CAAAkS,CAAA3hC,KAAA,CAAayvB,CAAAhiB,KAAb,CALyB,CA+BtC60B,QAASA,EAAkB,CAACC,CAAD,CAAO,CAChC,IAAIC,EAAaA,QAA+B,CAACC,CAAD,CAAe,CAC7D,IAAAC,qBAAA,CAA4BC,QAAQ,EAAG,CACrC,MAAOF,EAD8B,CADsB,CAK3DF,EAAJ,GACEC,CAAAr6C,UADF,CACyB,IAAIo6C,CAD7B,CAGAC,EAAAr6C,UAAAmjC,QAAA,CAA+BsX,QAAmB,EAAG,CACnD,MAAO,KAAAF,qBAAA,EAD4C,CAGrDF,EAAAr6C,UAAAU,SAAA,CAAgCg6C,QAAoB,EAAG,CACrD,MAAO,KAAAH,qBAAA,EAAA75C,SAAA,EAD8C,CAGvD;MAAO25C,EAfyB,CAxClC,IAAIM,EAAgBA,QAAsB,CAACx1C,CAAD,CAAO,CAC/C,KAAMs0C,GAAA,CAAW,QAAX,CAAN,CAD+C,CAI7C74B,EAAAD,IAAA,CAAc,WAAd,CAAJ,GACEg6B,CADF,CACkB/5B,CAAA9X,IAAA,CAAc,WAAd,CADlB,CAN4C,KA4DxC8xC,EAAyBT,CAAA,EA5De,CA6DxCU,EAAS,EAEbA,EAAA,CAAOhB,EAAAriB,KAAP,CAAA,CAA4B2iB,CAAA,CAAmBS,CAAnB,CAC5BC,EAAA,CAAOhB,EAAAiB,IAAP,CAAA,CAA2BX,CAAA,CAAmBS,CAAnB,CAC3BC,EAAA,CAAOhB,EAAAkB,IAAP,CAAA,CAA2BZ,CAAA,CAAmBS,CAAnB,CAC3BC,EAAA,CAAOhB,EAAAmB,GAAP,CAAA,CAA0Bb,CAAA,CAAmBS,CAAnB,CAC1BC,EAAA,CAAOhB,EAAApiB,aAAP,CAAA,CAAoC0iB,CAAA,CAAmBU,CAAA,CAAOhB,EAAAkB,IAAP,CAAnB,CAyGpC,OAAO,CAAEE,QAtFTA,QAAgB,CAAC1hC,CAAD,CAAO+gC,CAAP,CAAqB,CACnC,IAAI95B,EAAeq6B,CAAA38C,eAAA,CAAsBqb,CAAtB,CAAA,CAA8BshC,CAAA,CAAOthC,CAAP,CAA9B,CAA6C,IAChE,IAAKiH,CAAAA,CAAL,CACE,KAAMi5B,GAAA,CAAW,UAAX,CAEFlgC,CAFE,CAEI+gC,CAFJ,CAAN,CAIF,GAAqB,IAArB,GAAIA,CAAJ,EAA6BA,CAA7B,GAA8Cn9C,CAA9C,EAA4E,EAA5E,GAA2Dm9C,CAA3D,CACE,MAAOA,EAIT,IAA4B,QAA5B,GAAI,MAAOA,EAAX,CACE,KAAMb,GAAA,CAAW,OAAX,CAEFlgC,CAFE,CAAN,CAIF,MAAO,KAAIiH,CAAJ,CAAgB85B,CAAhB,CAjB4B,CAsF9B,CACEpX,WA1BTA,QAAmB,CAAC3pB,CAAD,CAAO2hC,CAAP,CAAqB,CACtC,GAAqB,IAArB,GAAIA,CAAJ,EAA6BA,CAA7B,GAA8C/9C,CAA9C,EAA4E,EAA5E,GAA2D+9C,CAA3D,CACE,MAAOA,EAET,KAAIrwC,EAAegwC,CAAA38C,eAAA,CAAsBqb,CAAtB,CAAA,CAA8BshC,CAAA,CAAOthC,CAAP,CAA9B,CAA6C,IAChE,IAAI1O,CAAJ,EAAmBqwC,CAAnB;AAA2CrwC,CAA3C,CACE,MAAOqwC,EAAAX,qBAAA,EAKT,IAAIhhC,CAAJ,GAAasgC,EAAApiB,aAAb,CAAwC,CAzIpC6P,IAAAA,EAAYpF,EAAA,CA0ImBgZ,CA1IRx6C,SAAA,EAAX,CAAZ4mC,CACA5oC,CADA4oC,CACGzf,CADHyf,CACM6T,EAAU,CAAA,CAEfz8C,EAAA,CAAI,CAAT,KAAYmpB,CAAZ,CAAgBiyB,CAAAt8C,OAAhB,CAA6CkB,CAA7C,CAAiDmpB,CAAjD,CAAoDnpB,CAAA,EAApD,CACE,GAAIw7C,CAAA,CAASJ,CAAA,CAAqBp7C,CAArB,CAAT,CAAkC4oC,CAAlC,CAAJ,CAAkD,CAChD6T,CAAA,CAAU,CAAA,CACV,MAFgD,CAKpD,GAAIA,CAAJ,CAEE,IAAKz8C,CAAO,CAAH,CAAG,CAAAmpB,CAAA,CAAIkyB,CAAAv8C,OAAhB,CAA6CkB,CAA7C,CAAiDmpB,CAAjD,CAAoDnpB,CAAA,EAApD,CACE,GAAIw7C,CAAA,CAASH,CAAA,CAAqBr7C,CAArB,CAAT,CAAkC4oC,CAAlC,CAAJ,CAAkD,CAChD6T,CAAA,CAAU,CAAA,CACV,MAFgD,CA8HpD,GAxHKA,CAwHL,CACE,MAAOD,EAEP,MAAMzB,GAAA,CAAW,UAAX,CAEFyB,CAAAx6C,SAAA,EAFE,CAAN,CAJoC,CAQjC,GAAI6Y,CAAJ,GAAasgC,EAAAriB,KAAb,CACL,MAAOmjB,EAAA,CAAcO,CAAd,CAET,MAAMzB,GAAA,CAAW,QAAX,CAAN,CAtBsC,CAyBjC,CAEEtW,QAlDTA,QAAgB,CAAC+X,CAAD,CAAe,CAC7B,MAAIA,EAAJ,WAA4BN,EAA5B,CACSM,CAAAX,qBAAA,EADT,CAGSW,CAJoB,CAgDxB,CA5KqC,CAAlC,CAtEkB,CAkhBhCxlC,QAASA,GAAY,EAAG,CACtB,IAAIuV,EAAU,CAAA,CAad,KAAAA,QAAA,CAAemwB,QAAS,CAACv8C,CAAD,CAAQ,CAC1BS,SAAA9B,OAAJ,GACEytB,CADF,CACY,CAAEpsB,CAAAA,CADd,CAGA,OAAOosB,EAJuB,CAsDhC,KAAAjM,KAAA,CAAY,CAAC,WAAD,CAAc,QAAd,CAAwB,cAAxB,CAAwC,QAAQ,CAC9CjL,CAD8C;AACjCkB,CADiC,CACvBU,CADuB,CACT,CAGjD,GAAIsV,CAAJ,EAA2C,CAA3C,CAAelX,CAAA,CAAU,CAAV,CAAAsnC,aAAf,CACE,KAAM5B,GAAA,CAAW,UAAX,CAAN,CAMF,IAAI6B,EAAMt4C,EAAA,CAAY62C,EAAZ,CAaVyB,EAAAC,UAAA,CAAgBC,QAAS,EAAG,CAC1B,MAAOvwB,EADmB,CAG5BqwB,EAAAL,QAAA,CAActlC,CAAAslC,QACdK,EAAApY,WAAA,CAAiBvtB,CAAAutB,WACjBoY,EAAAnY,QAAA,CAAcxtB,CAAAwtB,QAETlY,EAAL,GACEqwB,CAAAL,QACA,CADcK,CAAApY,WACd,CAD+BuY,QAAQ,CAACliC,CAAD,CAAO1a,CAAP,CAAc,CAAE,MAAOA,EAAT,CACrD,CAAAy8C,CAAAnY,QAAA,CAAcjjC,EAFhB,CAwBAo7C,EAAAI,QAAA,CAAcC,QAAmB,CAACpiC,CAAD,CAAOg9B,CAAP,CAAa,CAC5C,IAAI59B,EAAS1D,CAAA,CAAOshC,CAAP,CACb,OAAI59B,EAAA8Z,QAAJ,EAAsB9Z,CAAA7L,SAAtB,CACS6L,CADT,CAGS1D,CAAA,CAAOshC,CAAP,CAAa,QAAS,CAAC13C,CAAD,CAAQ,CACnC,MAAOy8C,EAAApY,WAAA,CAAe3pB,CAAf,CAAqB1a,CAArB,CAD4B,CAA9B,CALmC,CAtDG,KAoT7C8F,EAAQ22C,CAAAI,QApTqC,CAqT7CxY,EAAaoY,CAAApY,WArTgC,CAsT7C+X,EAAUK,CAAAL,QAEdp9C,EAAA,CAAQg8C,EAAR,CAAsB,QAAS,CAAC+B,CAAD,CAAYh1C,CAAZ,CAAkB,CAC/C,IAAIi1C,EAAQl6C,CAAA,CAAUiF,CAAV,CACZ00C,EAAA,CAAIzkC,EAAA,CAAU,WAAV,CAAwBglC,CAAxB,CAAJ,CAAA,CAAsC,QAAS,CAACtF,CAAD,CAAO,CACpD,MAAO5xC,EAAA,CAAMi3C,CAAN,CAAiBrF,CAAjB,CAD6C,CAGtD+E,EAAA,CAAIzkC,EAAA,CAAU,cAAV,CAA2BglC,CAA3B,CAAJ,CAAA,CAAyC,QAAS,CAACh9C,CAAD,CAAQ,CACxD,MAAOqkC,EAAA,CAAW0Y,CAAX;AAAsB/8C,CAAtB,CADiD,CAG1Dy8C,EAAA,CAAIzkC,EAAA,CAAU,WAAV,CAAwBglC,CAAxB,CAAJ,CAAA,CAAsC,QAAS,CAACh9C,CAAD,CAAQ,CACrD,MAAOo8C,EAAA,CAAQW,CAAR,CAAmB/8C,CAAnB,CAD8C,CARR,CAAjD,CAaA,OAAOy8C,EArU0C,CADvC,CApEU,CA4ZxBxlC,QAASA,GAAgB,EAAG,CAC1B,IAAAkJ,KAAA,CAAY,CAAC,SAAD,CAAY,WAAZ,CAAyB,QAAQ,CAACzI,CAAD,CAAUxC,CAAV,CAAqB,CAAA,IAC5D+nC,EAAe,EAD6C,CAE5DC,EACEr8C,EAAA,CAAI,CAAC,eAAAmY,KAAA,CAAqBlW,CAAA,CAAUq6C,CAACzlC,CAAA0lC,UAADD,EAAsB,EAAtBA,WAAV,CAArB,CAAD,EAAyE,EAAzE,EAA6E,CAA7E,CAAJ,CAH0D,CAI5DE,EAAQ,QAAA9zC,KAAA,CAAc4zC,CAACzlC,CAAA0lC,UAADD,EAAsB,EAAtBA,WAAd,CAJoD,CAK5D9+C,EAAW6W,CAAA,CAAU,CAAV,CAAX7W,EAA2B,EALiC,CAM5Di/C,CAN4D,CAO5DC,EAAc,6BAP8C,CAQ5DC,EAAYn/C,CAAAmkC,KAAZgb,EAA6Bn/C,CAAAmkC,KAAA3yB,MAR+B,CAS5D4tC,EAAc,CAAA,CAT8C,CAU5DC,EAAa,CAAA,CAGjB,IAAIF,CAAJ,CAAe,CACb,IAAQl7C,IAAAA,CAAR,GAAgBk7C,EAAhB,CACE,GAAG15C,CAAH,CAAWy5C,CAAAvkC,KAAA,CAAiB1W,CAAjB,CAAX,CAAmC,CACjCg7C,CAAA,CAAex5C,CAAA,CAAM,CAAN,CACfw5C,EAAA,CAAeA,CAAA/sB,OAAA,CAAoB,CAApB,CAAuB,CAAvB,CAAAnY,YAAA,EAAf,CAAyDklC,CAAA/sB,OAAA,CAAoB,CAApB,CACzD,MAHiC,CAOjC+sB,CAAJ,GACEA,CADF,CACkB,eADlB,EACqCE,EADrC,EACmD,QADnD,CAIAC,EAAA,CAAc,CAAG,EAAC,YAAD,EAAiBD,EAAjB,EAAgCF,CAAhC,CAA+C,YAA/C,EAA+DE,EAA/D,CACjBE,EAAA,CAAc,CAAG,EAAC,WAAD;AAAgBF,CAAhB,EAA+BF,CAA/B,CAA8C,WAA9C,EAA6DE,EAA7D,CAEbN,EAAAA,CAAJ,EAAiBO,CAAjB,EAA+BC,CAA/B,GACED,CACA,CADc3+C,CAAA,CAAST,CAAAmkC,KAAA3yB,MAAA8tC,iBAAT,CACd,CAAAD,CAAA,CAAa5+C,CAAA,CAAST,CAAAmkC,KAAA3yB,MAAA+tC,gBAAT,CAFf,CAhBa,CAuBf,MAAO,CAULx4B,QAAS,EAAGA,CAAA1N,CAAA0N,QAAH,EAAsBy4B,CAAAnmC,CAAA0N,QAAAy4B,UAAtB,EAA+D,CAA/D,CAAqDX,CAArD,EAAsEG,CAAtE,CAVJ,CAYLS,SAAUA,QAAQ,CAAClgC,CAAD,CAAQ,CAIxB,GAAa,OAAb,EAAIA,CAAJ,EAAgC,CAAhC,EAAwBmgC,EAAxB,CAAmC,MAAO,CAAA,CAE1C,IAAIv8C,CAAA,CAAYy7C,CAAA,CAAar/B,CAAb,CAAZ,CAAJ,CAAsC,CACpC,IAAIogC,EAAS3/C,CAAAya,cAAA,CAAuB,KAAvB,CACbmkC,EAAA,CAAar/B,CAAb,CAAA,CAAsB,IAAtB,CAA6BA,CAA7B,GAAsCogC,EAFF,CAKtC,MAAOf,EAAA,CAAar/B,CAAb,CAXiB,CAZrB,CAyBLjP,IAAKA,EAAA,EAzBA,CA0BL2uC,aAAcA,CA1BT,CA2BLG,YAAcA,CA3BT,CA4BLC,WAAaA,CA5BR,CA6BLR,QAASA,CA7BJ,CApCyD,CAAtD,CADc,CA0F5B7lC,QAASA,GAAwB,EAAG,CAClC,IAAA8I,KAAA,CAAY,CAAC,gBAAD,CAAmB,OAAnB,CAA4B,IAA5B,CAAkC,QAAQ,CAACjJ,CAAD,CAAiBtB,CAAjB,CAAwBY,CAAxB,CAA4B,CAChFynC,QAASA,EAAe,CAACC,CAAD,CAAMC,CAAN,CAA0B,CAgBhDC,QAASA,EAAW,EAAG,CACrBn5C,CAAAo5C,qBAAA,EACA,IAAKF,CAAAA,CAAL,CACE,KAAMxzB,GAAA,CAAe,QAAf,CAAyDuzB,CAAzD,CAAN,CAEF,MAAO1nC,EAAAooB,OAAA,EALc,CAhByB;AAChD,IAAI35B,EAAOg5C,CACXh5C,EAAAo5C,qBAAA,EAEA,OAAOzoC,EAAA3L,IAAA,CAAUi0C,CAAV,CAAe,CAAE/8B,MAAQjK,CAAV,CAAf,CAAA+f,KAAA,CACC,QAAQ,CAACwH,CAAD,CAAW,CACnBn4B,CAAAA,CAAOm4B,CAAAr1B,KACX,IAAI9C,CAAAA,CAAJ,EAA4B,CAA5B,GAAYA,CAAA3H,OAAZ,CACE,MAAOy/C,EAAA,EAGTn5C,EAAAo5C,qBAAA,EACAnnC,EAAA6H,IAAA,CAAmBm/B,CAAnB,CAAwB53C,CAAxB,CACA,OAAOA,EARgB,CADpB,CAUF83C,CAVE,CAJyC,CAyBlDH,CAAAI,qBAAA,CAAuC,CAEvC,OAAOJ,EA5ByE,CAAtE,CADsB,CAiCpC1mC,QAASA,GAAqB,EAAG,CAC/B,IAAA4I,KAAA,CAAY,CAAC,YAAD,CAAe,UAAf,CAA2B,WAA3B,CACP,QAAQ,CAAC7J,CAAD,CAAe1B,CAAf,CAA2BoB,CAA3B,CAAsC,CA6GjD,MApGkBsoC,CAcN,aAAeC,QAAQ,CAAC17C,CAAD,CAAU45B,CAAV,CAAsB+hB,CAAtB,CAAsC,CACnEh0B,CAAAA,CAAW3nB,CAAA47C,uBAAA,CAA+B,YAA/B,CACf,KAAIC,EAAU,EACd1/C,EAAA,CAAQwrB,CAAR,CAAkB,QAAQ,CAAC8Q,CAAD,CAAU,CAClC,IAAIqjB,EAAcn1C,EAAA3G,QAAA,CAAgBy4B,CAAhB,CAAAlyB,KAAA,CAA8B,UAA9B,CACdu1C,EAAJ,EACE3/C,CAAA,CAAQ2/C,CAAR,CAAqB,QAAQ,CAACC,CAAD,CAAc,CACrCJ,CAAJ,CAEMj1C,CADUoxC,IAAI92C,MAAJ82C,CAAW,SAAXA,CAAuBle,CAAvBke,CAAoC,aAApCA,CACVpxC,MAAA,CAAaq1C,CAAb,CAFN,EAGIF,CAAAh/C,KAAA,CAAa47B,CAAb,CAHJ,CAM0C,EAN1C;AAMMsjB,CAAA17C,QAAA,CAAoBu5B,CAApB,CANN,EAOIiiB,CAAAh/C,KAAA,CAAa47B,CAAb,CARqC,CAA3C,CAHgC,CAApC,CAiBA,OAAOojB,EApBgE,CAdvDJ,CAiDN,WAAaO,QAAQ,CAACh8C,CAAD,CAAU45B,CAAV,CAAsB+hB,CAAtB,CAAsC,CAErE,IADA,IAAIM,EAAW,CAAC,KAAD,CAAQ,UAAR,CAAoB,OAApB,CAAf,CACS51B,EAAI,CAAb,CAAgBA,CAAhB,CAAoB41B,CAAAngD,OAApB,CAAqC,EAAEuqB,CAAvC,CAA0C,CAGxC,IAAI/M,EAAWtZ,CAAAyX,iBAAA,CADA,GACA,CADMwkC,CAAA,CAAS51B,CAAT,CACN,CADoB,OACpB,EAFOs1B,CAAAO,CAAiB,GAAjBA,CAAuB,IAE9B,EADgD,GAChD,CADsDtiB,CACtD,CADmE,IACnE,CACf,IAAItgB,CAAAxd,OAAJ,CACE,MAAOwd,EAL+B,CAF2B,CAjDrDmiC,CAoEN,YAAcU,QAAQ,EAAG,CACnC,MAAOhpC,EAAAwP,IAAA,EAD4B,CApEnB84B,CAiFN,YAAcW,QAAQ,CAACz5B,CAAD,CAAM,CAClCA,CAAJ,GAAYxP,CAAAwP,IAAA,EAAZ,GACExP,CAAAwP,IAAA,CAAcA,CAAd,CACA,CAAAlP,CAAA62B,QAAA,EAFF,CADsC,CAjFtBmR,CAgGN,WAAaY,QAAQ,CAAC54B,CAAD,CAAW,CAC1C1R,CAAAwR,gCAAA,CAAyCE,CAAzC,CAD0C,CAhG1Bg4B,CAT+B,CADvC,CADmB,CAmHjC7mC,QAASA,GAAgB,EAAG,CAC1B,IAAA0I,KAAA,CAAY,CAAC,YAAD,CAAe,UAAf,CAA2B,IAA3B,CAAiC,KAAjC,CAAwC,mBAAxC,CACP,QAAQ,CAAC7J,CAAD,CAAe1B,CAAf,CAA2B4B,CAA3B,CAAiCE,CAAjC,CAAwCtB,CAAxC,CAA2D,CA6BtEqsB,QAASA,EAAO,CAACv8B,CAAD,CAAKijB,CAAL,CAAYwd,CAAZ,CAAyB,CAAA,IACnCI,EAAatkC,CAAA,CAAUkkC,CAAV,CAAbI;AAAuC,CAACJ,CADL,CAEnC5E,EAAW9Y,CAAC8d,CAAA,CAAYrvB,CAAZ,CAAkBF,CAAnByR,OAAA,EAFwB,CAGnC2X,EAAUmB,CAAAnB,QAGdxX,EAAA,CAAYxT,CAAAqT,MAAA,CAAe,QAAQ,EAAG,CACpC,GAAI,CACF8Y,CAAAC,QAAA,CAAiB97B,CAAA,EAAjB,CADE,CAEF,MAAMiB,CAAN,CAAS,CACT46B,CAAAnC,OAAA,CAAgBz4B,CAAhB,CACA,CAAAiP,CAAA,CAAkBjP,CAAlB,CAFS,CAFX,OAMQ,CACN,OAAOg5C,CAAA,CAAUvf,CAAAwf,YAAV,CADD,CAIHrZ,CAAL,EAAgBzvB,CAAAnN,OAAA,EAXoB,CAA1B,CAYTgf,CAZS,CAcZyX,EAAAwf,YAAA,CAAsBh3B,CACtB+2B,EAAA,CAAU/2B,CAAV,CAAA,CAAuB2Y,CAEvB,OAAOnB,EAvBgC,CA5BzC,IAAIuf,EAAY,EAmEhB1d,EAAApZ,OAAA,CAAiBg3B,QAAQ,CAACzf,CAAD,CAAU,CACjC,MAAIA,EAAJ,EAAeA,CAAAwf,YAAf,GAAsCD,EAAtC,EACEA,CAAA,CAAUvf,CAAAwf,YAAV,CAAAxgB,OAAA,CAAsC,UAAtC,CAEO,CADP,OAAOugB,CAAA,CAAUvf,CAAAwf,YAAV,CACA,CAAAxqC,CAAAqT,MAAAI,OAAA,CAAsBuX,CAAAwf,YAAtB,CAHT,EAKO,CAAA,CAN0B,CASnC,OAAO3d,EA7E+D,CAD5D,CADc,CAkJ5B4B,QAASA,GAAU,CAAC7d,CAAD,CAAM85B,CAAN,CAAY,CAC7B,IAAI74B,EAAOjB,CAEPu4B,GAAJ,GAGEwB,CAAAzjC,aAAA,CAA4B,MAA5B,CAAoC2K,CAApC,CACA,CAAAA,CAAA,CAAO84B,CAAA94B,KAJT,CAOA84B,EAAAzjC,aAAA,CAA4B,MAA5B,CAAoC2K,CAApC,CAGA,OAAO,CACLA,KAAM84B,CAAA94B,KADD,CAEL6c,SAAUic,CAAAjc,SAAA,CAA0Bic,CAAAjc,SAAA98B,QAAA,CAAgC,IAAhC,CAAsC,EAAtC,CAA1B;AAAsE,EAF3E,CAGLkW,KAAM6iC,CAAA7iC,KAHD,CAIL4sB,OAAQiW,CAAAjW,OAAA,CAAwBiW,CAAAjW,OAAA9iC,QAAA,CAA8B,KAA9B,CAAqC,EAArC,CAAxB,CAAmE,EAJtE,CAKLmd,KAAM47B,CAAA57B,KAAA,CAAsB47B,CAAA57B,KAAAnd,QAAA,CAA4B,IAA5B,CAAkC,EAAlC,CAAtB,CAA8D,EAL/D,CAMLoiC,SAAU2W,CAAA3W,SANL,CAOLE,KAAMyW,CAAAzW,KAPD,CAQLM,SAAiD,GAAvC,GAACmW,CAAAnW,SAAA/kC,OAAA,CAA+B,CAA/B,CAAD,CACNk7C,CAAAnW,SADM,CAEN,GAFM,CAEAmW,CAAAnW,SAVL,CAbsB,CAkC/B5H,QAASA,GAAe,CAACge,CAAD,CAAa,CAC/B1lC,CAAAA,CAAUhb,CAAA,CAAS0gD,CAAT,CAAD,CAAyBnc,EAAA,CAAWmc,CAAX,CAAzB,CAAkDA,CAC/D,OAAQ1lC,EAAAwpB,SAAR,GAA4Bmc,EAAAnc,SAA5B,EACQxpB,CAAA4C,KADR,GACwB+iC,EAAA/iC,KAHW,CA+CrC/E,QAASA,GAAe,EAAE,CACxB,IAAAwI,KAAA,CAAY5e,EAAA,CAAQnD,CAAR,CADY,CAiG1BmX,QAASA,GAAe,CAAC5M,CAAD,CAAW,CAWjCyzB,QAASA,EAAQ,CAACr0B,CAAD,CAAOgF,CAAP,CAAgB,CAC/B,GAAGrL,CAAA,CAASqG,CAAT,CAAH,CAAmB,CACjB,IAAI23C,EAAU,EACd1gD,EAAA,CAAQ+I,CAAR,CAAc,QAAQ,CAACoG,CAAD,CAAShP,CAAT,CAAc,CAClCugD,CAAA,CAAQvgD,CAAR,CAAA,CAAei9B,CAAA,CAASj9B,CAAT,CAAcgP,CAAd,CADmB,CAApC,CAGA,OAAOuxC,EALU,CAOjB,MAAO/2C,EAAAoE,QAAA,CAAiBhF,CAAjB,CAlBE43C,QAkBF,CAAgC5yC,CAAhC,CARsB,CAWjC,IAAAqvB,SAAA,CAAgBA,CAEhB,KAAAjc,KAAA,CAAY,CAAC,WAAD,CAAc,QAAQ,CAAC4B,CAAD,CAAY,CAC5C,MAAO,SAAQ,CAACha,CAAD,CAAO,CACpB,MAAOga,EAAA9X,IAAA,CAAclC,CAAd;AAzBE43C,QAyBF,CADa,CADsB,CAAlC,CAoBZvjB,EAAA,CAAS,UAAT,CAAqBwjB,EAArB,CACAxjB,EAAA,CAAS,MAAT,CAAiByjB,EAAjB,CACAzjB,EAAA,CAAS,QAAT,CAAmB0jB,EAAnB,CACA1jB,EAAA,CAAS,MAAT,CAAiB2jB,EAAjB,CACA3jB,EAAA,CAAS,SAAT,CAAoB4jB,EAApB,CACA5jB,EAAA,CAAS,WAAT,CAAsB6jB,EAAtB,CACA7jB,EAAA,CAAS,QAAT,CAAmB8jB,EAAnB,CACA9jB,EAAA,CAAS,SAAT,CAAoB+jB,EAApB,CACA/jB,EAAA,CAAS,WAAT,CAAsBgkB,EAAtB,CApDiC,CA0KnCN,QAASA,GAAY,EAAG,CACtB,MAAO,SAAQ,CAAC98C,CAAD,CAAQy5B,CAAR,CAAoB4jB,CAApB,CAAgC,CAC7C,GAAK,CAAAthD,CAAA,CAAQiE,CAAR,CAAL,CAAqB,MAAOA,EADiB,KAGzCs9C,EAAiB,MAAOD,EAHiB,CAIzCE,EAAa,EAEjBA,EAAA37B,MAAA,CAAmB47B,QAAQ,CAACxgD,CAAD,CAAQiD,CAAR,CAAe,CACxC,IAAS,IAAAtC,EAAI,CAAb,CAAgBA,CAAhB,CAAoB4/C,CAAA5hD,OAApB,CAAuCgC,CAAA,EAAvC,CACE,GAAI,CAAA4/C,CAAA,CAAW5/C,CAAX,CAAA,CAAcX,CAAd,CAAqBiD,CAArB,CAAJ,CACE,MAAO,CAAA,CAGX,OAAO,CAAA,CANiC,CASnB,WAAvB,GAAIq9C,CAAJ,GAEID,CAFJ,CACyB,SAAvB,GAAIC,CAAJ,EAAoCD,CAApC,CACeA,QAAQ,CAAC5hD,CAAD,CAAMo5B,CAAN,CAAY,CAC/B,MAAOruB,GAAAlF,OAAA,CAAe7F,CAAf,CAAoBo5B,CAApB,CADwB,CADnC,CAKewoB,QAAQ,CAAC5hD,CAAD,CAAMo5B,CAAN,CAAY,CAC/B,GAAIp5B,CAAJ,EAAWo5B,CAAX,EAAkC,QAAlC,GAAmB,MAAOp5B,EAA1B,EAA8D,QAA9D,GAA8C,MAAOo5B,EAArD,CAAwE,CACtE,IAAS4oB,IAAAA,CAAT,GAAmBhiD,EAAnB,CACE,GAAyB,GAAzB,GAAIgiD,CAAAp8C,OAAA,CAAc,CAAd,CAAJ,EAAgChF,EAAAC,KAAA,CAAoBb,CAApB,CAAyBgiD,CAAzB,CAAhC,EACIJ,CAAA,CAAW5hD,CAAA,CAAIgiD,CAAJ,CAAX;AAAwB5oB,CAAA,CAAK4oB,CAAL,CAAxB,CADJ,CAEE,MAAO,CAAA,CAGX,OAAO,CAAA,CAP+D,CASxE5oB,CAAA,CAAOttB,CAAC,EAADA,CAAIstB,CAAJttB,aAAA,EACP,OAA+C,EAA/C,CAAOA,CAAC,EAADA,CAAI9L,CAAJ8L,aAAA,EAAArH,QAAA,CAA+B20B,CAA/B,CAXwB,CANrC,CAsBA,KAAIyR,EAASA,QAAQ,CAAC7qC,CAAD,CAAMo5B,CAAN,CAAW,CAC9B,GAAoB,QAApB,GAAI,MAAOA,EAAX,EAAmD,GAAnD,GAAgCA,CAAAxzB,OAAA,CAAY,CAAZ,CAAhC,CACE,MAAO,CAACilC,CAAA,CAAO7qC,CAAP,CAAYo5B,CAAAtH,OAAA,CAAY,CAAZ,CAAZ,CAEV,QAAQ,MAAO9xB,EAAf,EACE,KAAK,SAAL,CACA,KAAK,QAAL,CACA,KAAK,QAAL,CACE,MAAO4hD,EAAA,CAAW5hD,CAAX,CAAgBo5B,CAAhB,CACT,MAAK,QAAL,CACE,OAAQ,MAAOA,EAAf,EACE,KAAK,QAAL,CACE,MAAOwoB,EAAA,CAAW5hD,CAAX,CAAgBo5B,CAAhB,CACT,SACE,IAAU4oB,IAAAA,CAAV,GAAoBhiD,EAApB,CACE,GAAyB,GAAzB,GAAIgiD,CAAAp8C,OAAA,CAAc,CAAd,CAAJ,EAAgCilC,CAAA,CAAO7qC,CAAA,CAAIgiD,CAAJ,CAAP,CAAoB5oB,CAApB,CAAhC,CACE,MAAO,CAAA,CANf,CAWA,MAAO,CAAA,CACT,MAAK,OAAL,CACE,IAAUh4B,CAAV,CAAc,CAAd,CAAiBA,CAAjB,CAAqBpB,CAAAE,OAArB,CAAiCkB,CAAA,EAAjC,CACE,GAAIypC,CAAA,CAAO7qC,CAAA,CAAIoB,CAAJ,CAAP,CAAeg4B,CAAf,CAAJ,CACE,MAAO,CAAA,CAGX,OAAO,CAAA,CACT,SACE,MAAO,CAAA,CA1BX,CAJ8B,CAiChC,QAAQ,MAAO4E,EAAf,EACE,KAAK,SAAL,CACA,KAAK,QAAL,CACA,KAAK,QAAL,CAEEA,CAAA;AAAa,CAACn7B,EAAEm7B,CAAH,CAEf,MAAK,QAAL,CAEE,IAASt9B,IAAAA,CAAT,GAAgBs9B,EAAhB,CACG,SAAQ,CAACtwB,CAAD,CAAO,CACkB,WAAhC,GAAI,MAAOswB,EAAA,CAAWtwB,CAAX,CAAX,EACAo0C,CAAA7gD,KAAA,CAAgB,QAAQ,CAACM,CAAD,CAAQ,CAC9B,MAAOspC,EAAA,CAAe,GAAR,EAAAn9B,CAAA,CAAcnM,CAAd,CAAuBA,CAAvB,EAAgCA,CAAA,CAAMmM,CAAN,CAAvC,CAAqDswB,CAAA,CAAWtwB,CAAX,CAArD,CADuB,CAAhC,CAFc,CAAf,CAAD,CAKGhN,CALH,CAOF,MACF,MAAK,UAAL,CACEohD,CAAA7gD,KAAA,CAAgB+8B,CAAhB,CACA,MACF,SACE,MAAOz5B,EAtBX,CAwBI09C,CAAAA,CAAW,EACf,KAAU//C,CAAV,CAAc,CAAd,CAAiBA,CAAjB,CAAqBqC,CAAArE,OAArB,CAAmCgC,CAAA,EAAnC,CAAwC,CACtC,IAAIX,EAAQgD,CAAA,CAAMrC,CAAN,CACR4/C,EAAA37B,MAAA,CAAiB5kB,CAAjB,CAAwBW,CAAxB,CAAJ,EACE+/C,CAAAhhD,KAAA,CAAcM,CAAd,CAHoC,CAMxC,MAAO0gD,EArGsC,CADzB,CA+JxBd,QAASA,GAAc,CAACe,CAAD,CAAU,CAC/B,IAAIC,EAAUD,CAAAta,eACd,OAAO,SAAQ,CAACwa,CAAD,CAASC,CAAT,CAAyBC,CAAzB,CAAsC,CAC/Cv/C,CAAA,CAAYs/C,CAAZ,CAAJ,GACEA,CADF,CACmBF,CAAA1Z,aADnB,CAII1lC,EAAA,CAAYu/C,CAAZ,CAAJ,GAEEA,CAFF,CAEiB,CAFjB,CAMA,OAAkB,KAAX,EAACF,CAAD,CACDA,CADC,CAEDG,EAAA,CAAaH,CAAb,CAAqBD,CAAApa,SAAA,CAAiB,CAAjB,CAArB,CAA0Coa,CAAAra,UAA1C,CAA6Dqa,CAAAta,YAA7D,CAAkFya,CAAlF,CAAAv6C,QAAA,CACU,SADV,CACqBs6C,CADrB,CAb6C,CAFtB,CAwEjCZ,QAASA,GAAY,CAACS,CAAD,CAAU,CAC7B,IAAIC,EAAUD,CAAAta,eACd,OAAO,SAAQ,CAAC4a,CAAD;AAASF,CAAT,CAAuB,CAGpC,MAAkB,KAAX,EAACE,CAAD,CACDA,CADC,CAEDD,EAAA,CAAaC,CAAb,CAAqBL,CAAApa,SAAA,CAAiB,CAAjB,CAArB,CAA0Coa,CAAAra,UAA1C,CAA6Dqa,CAAAta,YAA7D,CACaya,CADb,CAL8B,CAFT,CAa/BC,QAASA,GAAY,CAACC,CAAD,CAAS5tC,CAAT,CAAkB6tC,CAAlB,CAA4BC,CAA5B,CAAwCJ,CAAxC,CAAsD,CACzE,GAAK,CAAAK,QAAA,CAASH,CAAT,CAAL,EAAyBv/C,CAAA,CAASu/C,CAAT,CAAzB,CAA2C,MAAO,EAElD,KAAII,EAAsB,CAAtBA,CAAaJ,CACjBA,EAAA,CAAShrB,IAAAqrB,IAAA,CAASL,CAAT,CAJgE,KAKrEM,EAASN,CAATM,CAAkB,EALmD,CAMrEC,EAAe,EANsD,CAOrEz6C,EAAQ,EAP6D,CASrE06C,EAAc,CAAA,CAClB,IAA6B,EAA7B,GAAIF,CAAAr+C,QAAA,CAAe,GAAf,CAAJ,CAAgC,CAC9B,IAAIY,EAAQy9C,CAAAz9C,MAAA,CAAa,qBAAb,CACRA,EAAJ,EAAyB,GAAzB,EAAaA,CAAA,CAAM,CAAN,CAAb,EAAgCA,CAAA,CAAM,CAAN,CAAhC,CAA2Ci9C,CAA3C,CAA0D,CAA1D,EACEQ,CACA,CADS,GACT,CAAAN,CAAA,CAAS,CAFX,GAIEO,CACA,CADeD,CACf,CAAAE,CAAA,CAAc,CAAA,CALhB,CAF8B,CAWhC,GAAKA,CAAL,CAkDqB,CAAnB,CAAIV,CAAJ,EAAkC,EAAlC,CAAwBE,CAAxB,EAAgD,CAAhD,CAAuCA,CAAvC,GACEO,CADF,CACiBP,CAAAS,QAAA,CAAeX,CAAf,CADjB,CAlDF,KAAkB,CACZY,CAAAA,CAAchjD,CAAC4iD,CAAA5+C,MAAA,CAAa2jC,EAAb,CAAA,CAA0B,CAA1B,CAAD3nC,EAAiC,EAAjCA,QAGd6C,EAAA,CAAYu/C,CAAZ,CAAJ,GACEA,CADF,CACiB9qB,IAAA2rB,IAAA,CAAS3rB,IAAAC,IAAA,CAAS7iB,CAAAqzB,QAAT,CAA0Bib,CAA1B,CAAT,CAAiDtuC,CAAAszB,QAAjD,CADjB,CAOAsa,EAAA,CAAS,EAAEhrB,IAAA4rB,MAAA,CAAW,EAAEZ,CAAAp/C,SAAA,EAAF,CAAsB,GAAtB,CAA4Bk/C,CAA5B,CAAX,CAAAl/C,SAAA,EAAF,CAAqE,GAArE,CAA2E,CAACk/C,CAA5E,CAEM,EAAf,GAAIE,CAAJ,GACEI,CADF,CACe,CAAA,CADf,CAIIS,EAAAA,CAAWn/C,CAAC,EAADA,CAAMs+C,CAANt+C,OAAA,CAAoB2jC,EAApB,CACXoD,EAAAA,CAAQoY,CAAA,CAAS,CAAT,CACZA;CAAA,CAAWA,CAAA,CAAS,CAAT,CAAX,EAA0B,EAEnBx3C,KAAAA,EAAM,CAANA,CACHy3C,EAAS1uC,CAAA4zB,OADN38B,CAEH03C,EAAQ3uC,CAAA2zB,MAEZ,IAAI0C,CAAA/qC,OAAJ,EAAqBojD,CAArB,CAA8BC,CAA9B,CAEE,IADA13C,CACK,CADCo/B,CAAA/qC,OACD,CADgBojD,CAChB,CAAAliD,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgByK,CAAhB,CAAqBzK,CAAA,EAArB,CAC0B,CAGxB,IAHKyK,CAGL,CAHWzK,CAGX,EAHcmiD,CAGd,EAHmC,CAGnC,GAH6BniD,CAG7B,GAFE2hD,CAEF,EAFkBN,CAElB,EAAAM,CAAA,EAAgB9X,CAAArlC,OAAA,CAAaxE,CAAb,CAIpB,KAAKA,CAAL,CAASyK,CAAT,CAAczK,CAAd,CAAkB6pC,CAAA/qC,OAAlB,CAAgCkB,CAAA,EAAhC,CACoC,CAGlC,IAHK6pC,CAAA/qC,OAGL,CAHoBkB,CAGpB,EAHuBkiD,CAGvB,EAH6C,CAG7C,GAHuCliD,CAGvC,GAFE2hD,CAEF,EAFkBN,CAElB,EAAAM,CAAA,EAAgB9X,CAAArlC,OAAA,CAAaxE,CAAb,CAIlB,KAAA,CAAMiiD,CAAAnjD,OAAN,CAAwBoiD,CAAxB,CAAA,CACEe,CAAA,EAAY,GAGVf,EAAJ,EAAqC,GAArC,GAAoBA,CAApB,GAA0CS,CAA1C,EAA0DL,CAA1D,CAAuEW,CAAAvxB,OAAA,CAAgB,CAAhB,CAAmBwwB,CAAnB,CAAvE,CA/CgB,CAuDlBh6C,CAAArH,KAAA,CAAW2hD,CAAA,CAAahuC,CAAAyzB,OAAb,CAA8BzzB,CAAAuzB,OAAzC,CACA7/B,EAAArH,KAAA,CAAW8hD,CAAX,CACAz6C,EAAArH,KAAA,CAAW2hD,CAAA,CAAahuC,CAAA0zB,OAAb,CAA8B1zB,CAAAwzB,OAAzC,CACA,OAAO9/B,EAAAG,KAAA,CAAW,EAAX,CA/EkE,CAkF3E+6C,QAASA,GAAS,CAAC/Z,CAAD,CAAMga,CAAN,CAActoC,CAAd,CAAoB,CACpC,IAAIuoC,EAAM,EACA,EAAV,CAAIja,CAAJ,GACEia,CACA,CADO,GACP,CAAAja,CAAA,CAAM,CAACA,CAFT,CAKA,KADAA,CACA,CADM,EACN,CADWA,CACX,CAAMA,CAAAvpC,OAAN,CAAmBujD,CAAnB,CAAA,CAA2Bha,CAAA,CAAM,GAAN,CAAYA,CACnCtuB,EAAJ,GACEsuB,CADF,CACQA,CAAA3X,OAAA,CAAW2X,CAAAvpC,OAAX,CAAwBujD,CAAxB,CADR,CAEA,OAAOC,EAAP,CAAaja,CAVuB,CActCka,QAASA,EAAU,CAACr6C,CAAD,CAAOuhB,CAAP,CAAanR,CAAb,CAAqByB,CAArB,CAA2B,CAC5CzB,CAAA,CAASA,CAAT,EAAmB,CACnB,OAAO,SAAQ,CAACkqC,CAAD,CAAO,CAChBriD,CAAAA;AAAQqiD,CAAA,CAAK,KAAL,CAAat6C,CAAb,CAAA,EACZ,IAAa,CAAb,CAAIoQ,CAAJ,EAAkBnY,CAAlB,CAA0B,CAACmY,CAA3B,CACEnY,CAAA,EAASmY,CACG,EAAd,GAAInY,CAAJ,EAA8B,GAA9B,EAAmBmY,CAAnB,GAAmCnY,CAAnC,CAA2C,EAA3C,CACA,OAAOiiD,GAAA,CAAUjiD,CAAV,CAAiBspB,CAAjB,CAAuB1P,CAAvB,CALa,CAFsB,CAW9C0oC,QAASA,GAAa,CAACv6C,CAAD,CAAOw6C,CAAP,CAAkB,CACtC,MAAO,SAAQ,CAACF,CAAD,CAAOzB,CAAP,CAAgB,CAC7B,IAAI5gD,EAAQqiD,CAAA,CAAK,KAAL,CAAat6C,CAAb,CAAA,EAAZ,CACIkC,EAAMwE,EAAA,CAAU8zC,CAAA,CAAa,OAAb,CAAuBx6C,CAAvB,CAA+BA,CAAzC,CAEV,OAAO64C,EAAA,CAAQ32C,CAAR,CAAA,CAAajK,CAAb,CAJsB,CADO,CAmBxCwiD,QAASA,GAAsB,CAACC,CAAD,CAAO,CAElC,IAAIC,EAAmBC,CAAC,IAAIh/C,IAAJ,CAAS8+C,CAAT,CAAe,CAAf,CAAkB,CAAlB,CAADE,QAAA,EAGvB,OAAO,KAAIh/C,IAAJ,CAAS8+C,CAAT,CAAe,CAAf,EAAwC,CAArB,EAACC,CAAD,CAA0B,CAA1B,CAA8B,EAAjD,EAAuDA,CAAvD,CAL2B,CActCE,QAASA,GAAU,CAACt5B,CAAD,CAAO,CACvB,MAAO,SAAQ,CAAC+4B,CAAD,CAAO,CAAA,IACfQ,EAAaL,EAAA,CAAuBH,CAAAS,YAAA,EAAvB,CAGbprB,EAAAA,CAAO,CAVNqrB,IAAIp/C,IAAJo/C,CAQ8BV,CARrBS,YAAA,EAATC,CAQ8BV,CARGW,SAAA,EAAjCD,CAQ8BV,CANnCY,QAAA,EAFKF,EAEiB,CAFjBA,CAQ8BV,CANTM,OAAA,EAFrBI,EAUDrrB,CAAoB,CAACmrB,CACtBn/C,EAAAA,CAAS,CAATA,CAAauyB,IAAA4rB,MAAA,CAAWnqB,CAAX,CAAkB,MAAlB,CAEhB,OAAOuqB,GAAA,CAAUv+C,CAAV,CAAkB4lB,CAAlB,CAPY,CADC,CA0I1Bu2B,QAASA,GAAU,CAACc,CAAD,CAAU,CAK3BuC,QAASA,EAAgB,CAACC,CAAD,CAAS,CAChC,IAAIr/C,CACJ,IAAIA,CAAJ,CAAYq/C,CAAAr/C,MAAA,CAAas/C,CAAb,CAAZ,CAAyC,CACnCf,CAAAA,CAAO,IAAI1+C,IAAJ,CAAS,CAAT,CAD4B,KAEnC0/C,EAAS,CAF0B,CAGnCC,EAAS,CAH0B,CAInCC,EAAaz/C,CAAA,CAAM,CAAN,CAAA;AAAWu+C,CAAAmB,eAAX,CAAiCnB,CAAAoB,YAJX,CAKnCC,EAAa5/C,CAAA,CAAM,CAAN,CAAA,CAAWu+C,CAAAsB,YAAX,CAA8BtB,CAAAuB,SAE3C9/C,EAAA,CAAM,CAAN,CAAJ,GACEu/C,CACA,CADSxiD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,CAAeA,CAAA,CAAM,EAAN,CAAf,CACT,CAAAw/C,CAAA,CAAQziD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,CAAeA,CAAA,CAAM,EAAN,CAAf,CAFV,CAIAy/C,EAAAjkD,KAAA,CAAgB+iD,CAAhB,CAAsBxhD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,CAAtB,CAAqCjD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,CAArC,CAAqD,CAArD,CAAwDjD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,CAAxD,CACI1D,EAAAA,CAAIS,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,EAAc,CAAd,CAAJ1D,CAAuBijD,CACvBQ,EAAAA,CAAIhjD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,EAAc,CAAd,CAAJ+/C,CAAuBP,CACvBQ,EAAAA,CAAIjjD,EAAA,CAAIiD,CAAA,CAAM,CAAN,CAAJ,EAAc,CAAd,CACJigD,EAAAA,CAAK9tB,IAAA4rB,MAAA,CAA8C,GAA9C,CAAWmC,UAAA,CAAW,IAAX,EAAmBlgD,CAAA,CAAM,CAAN,CAAnB,EAA6B,CAA7B,EAAX,CACT4/C,EAAApkD,KAAA,CAAgB+iD,CAAhB,CAAsBjiD,CAAtB,CAAyByjD,CAAzB,CAA4BC,CAA5B,CAA+BC,CAA/B,CAhBuC,CAmBzC,MAAOZ,EArByB,CAFlC,IAAIC,EAAgB,sGA2BpB,OAAO,SAAQ,CAACf,CAAD,CAAO4B,CAAP,CAAeC,CAAf,CAAyB,CAAA,IAClCrsB,EAAO,EAD2B,CAElC9wB,EAAQ,EAF0B,CAGlC7B,CAHkC,CAG9BpB,CAERmgD,EAAA,CAASA,CAAT,EAAmB,YACnBA,EAAA,CAAStD,CAAAxZ,iBAAA,CAAyB8c,CAAzB,CAAT,EAA6CA,CACzCnlD,EAAA,CAASujD,CAAT,CAAJ,GACEA,CADF,CACS8B,EAAA56C,KAAA,CAAmB84C,CAAnB,CAAA,CAA2BxhD,EAAA,CAAIwhD,CAAJ,CAA3B,CAAuCa,CAAA,CAAiBb,CAAjB,CADhD,CAII1gD,EAAA,CAAS0gD,CAAT,CAAJ,GACEA,CADF,CACS,IAAI1+C,IAAJ,CAAS0+C,CAAT,CADT,CAIA;GAAK,CAAAzgD,EAAA,CAAOygD,CAAP,CAAL,CACE,MAAOA,EAGT,KAAA,CAAM4B,CAAN,CAAA,CAEE,CADAngD,CACA,CADQsgD,EAAAprC,KAAA,CAAwBirC,CAAxB,CACR,GACEl9C,CACA,CADQnC,EAAA,CAAOmC,CAAP,CAAcjD,CAAd,CAAqB,CAArB,CACR,CAAAmgD,CAAA,CAASl9C,CAAAyd,IAAA,EAFX,GAIEzd,CAAArH,KAAA,CAAWukD,CAAX,CACA,CAAAA,CAAA,CAAS,IALX,CASEC,EAAJ,EAA6B,KAA7B,GAAgBA,CAAhB,GACE7B,CACA,CADO,IAAI1+C,IAAJ,CAAS0+C,CAAAz+C,QAAA,EAAT,CACP,CAAAy+C,CAAAgC,WAAA,CAAgBhC,CAAAiC,WAAA,EAAhB,CAAoCjC,CAAAkC,kBAAA,EAApC,CAFF,CAIAvlD,EAAA,CAAQ+H,CAAR,CAAe,QAAQ,CAAC/G,CAAD,CAAO,CAC5BkF,CAAA,CAAKs/C,EAAA,CAAaxkD,CAAb,CACL63B,EAAA,EAAQ3yB,CAAA,CAAKA,CAAA,CAAGm9C,CAAH,CAAS1B,CAAAxZ,iBAAT,CAAL,CACKnnC,CAAAwG,QAAA,CAAc,UAAd,CAA0B,EAA1B,CAAAA,QAAA,CAAsC,KAAtC,CAA6C,GAA7C,CAHe,CAA9B,CAMA,OAAOqxB,EAxC+B,CA9Bb,CAuG7BkoB,QAASA,GAAU,EAAG,CACpB,MAAO,SAAQ,CAAC0E,CAAD,CAAS,CACtB,MAAOj/C,GAAA,CAAOi/C,CAAP,CAAe,CAAA,CAAf,CADe,CADJ,CAkHtBzE,QAASA,GAAa,EAAE,CACtB,MAAO,SAAQ,CAAC5wC,CAAD,CAAQs1C,CAAR,CAAe,CACxB/iD,CAAA,CAASyN,CAAT,CAAJ,GAAqBA,CAArB,CAA6BA,CAAAvN,SAAA,EAA7B,CACA,IAAK,CAAA9C,CAAA,CAAQqQ,CAAR,CAAL,EAAwB,CAAAtQ,CAAA,CAASsQ,CAAT,CAAxB,CAAyC,MAAOA,EAG9Cs1C,EAAA,CAD8BC,QAAhC,GAAI1uB,IAAAqrB,IAAA,CAAS53B,MAAA,CAAOg7B,CAAP,CAAT,CAAJ,CACUh7B,MAAA,CAAOg7B,CAAP,CADV,CAGU7jD,EAAA,CAAI6jD,CAAJ,CAGV,IAAI5lD,CAAA,CAASsQ,CAAT,CAAJ,CAEE,MAAIs1C,EAAJ,CACkB,CAAT,EAAAA,CAAA,CAAat1C,CAAArK,MAAA,CAAY,CAAZ,CAAe2/C,CAAf,CAAb;AAAqCt1C,CAAArK,MAAA,CAAY2/C,CAAZ,CAAmBt1C,CAAAzQ,OAAnB,CAD9C,CAGS,EAfiB,KAmBxBimD,EAAM,EAnBkB,CAoB1B/kD,CApB0B,CAoBvBmpB,CAGD07B,EAAJ,CAAYt1C,CAAAzQ,OAAZ,CACE+lD,CADF,CACUt1C,CAAAzQ,OADV,CAES+lD,CAFT,CAEiB,CAACt1C,CAAAzQ,OAFlB,GAGE+lD,CAHF,CAGU,CAACt1C,CAAAzQ,OAHX,CAKY,EAAZ,CAAI+lD,CAAJ,EACE7kD,CACA,CADI,CACJ,CAAAmpB,CAAA,CAAI07B,CAFN,GAIE7kD,CACA,CADIuP,CAAAzQ,OACJ,CADmB+lD,CACnB,CAAA17B,CAAA,CAAI5Z,CAAAzQ,OALN,CAQA,KAAA,CAAOkB,CAAP,CAASmpB,CAAT,CAAYnpB,CAAA,EAAZ,CACE+kD,CAAAllD,KAAA,CAAS0P,CAAA,CAAMvP,CAAN,CAAT,CAGF,OAAO+kD,EAxCqB,CADR,CAiKxBzE,QAASA,GAAa,CAAC/pC,CAAD,CAAQ,CAC5B,MAAO,SAAQ,CAACpT,CAAD,CAAQ6hD,CAAR,CAAuBC,CAAvB,CAAqC,CAwClDC,QAASA,EAAiB,CAACC,CAAD,CAAOC,CAAP,CAAmB,CAC3C,MAAOA,EAAA,CACD,QAAQ,CAAC/1C,CAAD,CAAG2kB,CAAH,CAAK,CAAC,MAAOmxB,EAAA,CAAKnxB,CAAL,CAAO3kB,CAAP,CAAR,CADZ,CAED81C,CAHqC,CAK7CxxB,QAASA,EAAO,CAAC0xB,CAAD,CAAKC,CAAL,CAAQ,CACtB,IAAI1gD,EAAK,MAAOygD,EAAhB,CACIxgD,EAAK,MAAOygD,EAChB,OAAI1gD,EAAJ,EAAUC,CAAV,EACM9C,EAAA,CAAOsjD,CAAP,CAQJ,EARkBtjD,EAAA,CAAOujD,CAAP,CAQlB,GAPED,CACA,CADKA,CAAA5gB,QAAA,EACL,CAAA6gB,CAAA,CAAKA,CAAA7gB,QAAA,EAMP,EAJU,QAIV,EAJI7/B,CAIJ,GAHGygD,CACA,CADKA,CAAA36C,YAAA,EACL,CAAA46C,CAAA,CAAKA,CAAA56C,YAAA,EAER,EAAI26C,CAAJ,GAAWC,CAAX,CAAsB,CAAtB,CACOD,CAAA,CAAKC,CAAL,CAAW,EAAX,CAAe,CAVxB,EAYS1gD,CAAA,CAAKC,CAAL,CAAW,EAAX,CAAe,CAfF,CA5CxB,GAAM,CAAAlG,EAAA,CAAYwE,CAAZ,CAAN,CAA2B,MAAOA,EAClC6hD,EAAA,CAAgB9lD,CAAA,CAAQ8lD,CAAR,CAAA,CAAyBA,CAAzB,CAAwC,CAACA,CAAD,CAC3B,EAA7B,GAAIA,CAAAlmD,OAAJ,GAAkCkmD,CAAlC,CAAkD,CAAC,GAAD,CAAlD,CACAA,EAAA,CAAgBA,CAAAO,IAAA,CAAkB,QAAQ,CAACC,CAAD,CAAW,CAAA,IAC/CJ;AAAa,CAAA,CADkC,CAC3Bh7C,EAAMo7C,CAANp7C,EAAmB5I,EAC3C,IAAIvC,CAAA,CAASumD,CAAT,CAAJ,CAAyB,CACvB,GAA4B,GAA5B,EAAKA,CAAAhhD,OAAA,CAAiB,CAAjB,CAAL,EAA0D,GAA1D,EAAmCghD,CAAAhhD,OAAA,CAAiB,CAAjB,CAAnC,CACE4gD,CACA,CADoC,GACpC,EADaI,CAAAhhD,OAAA,CAAiB,CAAjB,CACb,CAAAghD,CAAA,CAAYA,CAAAr9B,UAAA,CAAoB,CAApB,CAEd,IAAmB,EAAnB,GAAKq9B,CAAL,CAEE,MAAON,EAAA,CAAkB,QAAQ,CAAC71C,CAAD,CAAG2kB,CAAH,CAAM,CACrC,MAAOL,EAAA,CAAQtkB,CAAR,CAAW2kB,CAAX,CAD8B,CAAhC,CAEJoxB,CAFI,CAITh7C,EAAA,CAAMmM,CAAA,CAAOivC,CAAP,CACN,IAAIp7C,CAAAgE,SAAJ,CAAkB,CAChB,IAAI9O,EAAM8K,CAAA,EACV,OAAO86C,EAAA,CAAkB,QAAQ,CAAC71C,CAAD,CAAG2kB,CAAH,CAAM,CACrC,MAAOL,EAAA,CAAQtkB,CAAA,CAAE/P,CAAF,CAAR,CAAgB00B,CAAA,CAAE10B,CAAF,CAAhB,CAD8B,CAAhC,CAEJ8lD,CAFI,CAFS,CAZK,CAmBzB,MAAOF,EAAA,CAAkB,QAAQ,CAAC71C,CAAD,CAAG2kB,CAAH,CAAK,CACpC,MAAOL,EAAA,CAAQvpB,CAAA,CAAIiF,CAAJ,CAAR,CAAejF,CAAA,CAAI4pB,CAAJ,CAAf,CAD6B,CAA/B,CAEJoxB,CAFI,CArB4C,CAArC,CA0BhB,KADA,IAAIK,EAAY,EAAhB,CACUzlD,EAAI,CAAd,CAAiBA,CAAjB,CAAqBmD,CAAArE,OAArB,CAAmCkB,CAAA,EAAnC,CAA0CylD,CAAA5lD,KAAA,CAAesD,CAAA,CAAMnD,CAAN,CAAf,CAC1C,OAAOylD,EAAA3lD,KAAA,CAAeolD,CAAA,CAEtB1E,QAAmB,CAAC97C,CAAD,CAAKC,CAAL,CAAQ,CACzB,IAAU,IAAA3E,EAAI,CAAd,CAAiBA,CAAjB,CAAqBglD,CAAAlmD,OAArB,CAA2CkB,CAAA,EAA3C,CAAgD,CAC9C,IAAImlD,EAAOH,CAAA,CAAchlD,CAAd,CAAA,CAAiB0E,CAAjB,CAAqBC,CAArB,CACX,IAAa,CAAb,GAAIwgD,CAAJ,CAAgB,MAAOA,EAFuB,CAIhD,MAAO,EALkB,CAFL,CAA8BF,CAA9B,CAAf,CA/B2C,CADxB,CAmE9BS,QAASA,GAAW,CAACn3C,CAAD,CAAY,CAC1BhP,CAAA,CAAWgP,CAAX,CAAJ,GACEA,CADF,CACc,CACV6a,KAAM7a,CADI,CADd,CAKAA,EAAAwd,SAAA,CAAqBxd,CAAAwd,SAArB,EAA2C,IAC3C,OAAOrqB,GAAA,CAAQ6M,CAAR,CAPuB,CA38hBO;AAo9iBvCo3C,QAASA,GAAc,CAAC3iD,CAAD,CAAU+rB,CAAV,CAAiB8D,CAAjB,CAAyBhe,CAAzB,CAAmCc,CAAnC,CAAiD,CAAA,IAClEjG,EAAO,IAD2D,CAElEk2C,EAAW,EAFuD,CAIlEC,EAAan2C,CAAAo2C,aAAbD,CAAiC7iD,CAAA5B,OAAA,EAAA8J,WAAA,CAA4B,MAA5B,CAAjC26C,EAAwEE,EAG5Er2C,EAAAs2C,OAAA,CAAc,EACdt2C,EAAAu2C,UAAA,CAAiB,EACjBv2C,EAAAw2C,SAAA,CAAgBznD,CAChBiR,EAAAy2C,MAAA,CAAaxwC,CAAA,CAAaoZ,CAAA7mB,KAAb,EAA2B6mB,CAAA3d,OAA3B,EAA2C,EAA3C,CAAA,CAA+CyhB,CAA/C,CACbnjB,EAAA02C,OAAA,CAAc,CAAA,CACd12C,EAAA22C,UAAA,CAAiB,CAAA,CACjB32C,EAAA42C,OAAA,CAAc,CAAA,CACd52C,EAAA62C,SAAA,CAAgB,CAAA,CAChB72C,EAAA82C,WAAA,CAAkB,CAAA,CAElBX,EAAAY,YAAA,CAAuB/2C,CAAvB,CAaAA,EAAAg3C,mBAAA,CAA0BC,QAAQ,EAAG,CACnCxnD,CAAA,CAAQymD,CAAR,CAAkB,QAAQ,CAACgB,CAAD,CAAU,CAClCA,CAAAF,mBAAA,EADkC,CAApC,CADmC,CAiBrCh3C,EAAAm3C,iBAAA,CAAwBC,QAAQ,EAAG,CACjC3nD,CAAA,CAAQymD,CAAR,CAAkB,QAAQ,CAACgB,CAAD,CAAU,CAClCA,CAAAC,iBAAA,EADkC,CAApC,CADiC,CAenCn3C,EAAA+2C,YAAA,CAAmBM,QAAQ,CAACH,CAAD,CAAU,CAGnCx6C,EAAA,CAAwBw6C,CAAAT,MAAxB,CAAuC,OAAvC,CACAP,EAAA/lD,KAAA,CAAc+mD,CAAd,CAEIA,EAAAT,MAAJ,GACEz2C,CAAA,CAAKk3C,CAAAT,MAAL,CADF,CACwBS,CADxB,CANmC,CAYrCl3C,EAAAs3C,gBAAA,CAAuBC,QAAQ,CAACL,CAAD;AAAUM,CAAV,CAAmB,CAChD,IAAIC,EAAUP,CAAAT,MAEVz2C,EAAA,CAAKy3C,CAAL,CAAJ,GAAsBP,CAAtB,EACE,OAAOl3C,CAAA,CAAKy3C,CAAL,CAETz3C,EAAA,CAAKw3C,CAAL,CAAA,CAAgBN,CAChBA,EAAAT,MAAA,CAAgBe,CAPgC,CAmBlDx3C,EAAA03C,eAAA,CAAsBC,QAAQ,CAACT,CAAD,CAAU,CAClCA,CAAAT,MAAJ,EAAqBz2C,CAAA,CAAKk3C,CAAAT,MAAL,CAArB,GAA6CS,CAA7C,EACE,OAAOl3C,CAAA,CAAKk3C,CAAAT,MAAL,CAEThnD,EAAA,CAAQuQ,CAAAw2C,SAAR,CAAuB,QAAQ,CAAC/lD,CAAD,CAAQ+H,CAAR,CAAc,CAC3CwH,CAAA43C,aAAA,CAAkBp/C,CAAlB,CAAwB,IAAxB,CAA8B0+C,CAA9B,CAD2C,CAA7C,CAGAznD,EAAA,CAAQuQ,CAAAs2C,OAAR,CAAqB,QAAQ,CAAC7lD,CAAD,CAAQ+H,CAAR,CAAc,CACzCwH,CAAA43C,aAAA,CAAkBp/C,CAAlB,CAAwB,IAAxB,CAA8B0+C,CAA9B,CADyC,CAA3C,CAIA1jD,GAAA,CAAY0iD,CAAZ,CAAsBgB,CAAtB,CAXsC,CAwBxCW,GAAA,CAAqB,CACnBC,KAAM,IADa,CAEnB/6B,SAAUzpB,CAFS,CAGnBykD,IAAKA,QAAQ,CAAC7C,CAAD,CAASlZ,CAAT,CAAmBkb,CAAnB,CAA4B,CACvC,IAAI5jC,EAAO4hC,CAAA,CAAOlZ,CAAP,CACN1oB,EAAL,CAIiB,EAJjB,GAGcA,CAAA3f,QAAAD,CAAawjD,CAAbxjD,CAHd,EAKI4f,CAAAnjB,KAAA,CAAU+mD,CAAV,CALJ,CACEhC,CAAA,CAAOlZ,CAAP,CADF,CACqB,CAACkb,CAAD,CAHkB,CAHtB,CAcnBc,MAAOA,QAAQ,CAAC9C,CAAD,CAASlZ,CAAT,CAAmBkb,CAAnB,CAA4B,CACzC,IAAI5jC,EAAO4hC,CAAA,CAAOlZ,CAAP,CACN1oB,EAAL,GAGA9f,EAAA,CAAY8f,CAAZ,CAAkB4jC,CAAlB,CACA,CAAoB,CAApB,GAAI5jC,CAAAlkB,OAAJ,EACE,OAAO8lD,CAAA,CAAOlZ,CAAP,CALT,CAFyC,CAdxB,CAwBnBma,WAAYA,CAxBO,CAyBnBhxC,SAAUA,CAzBS,CAArB,CAsCAnF,EAAAi4C,UAAA,CAAiBC,QAAQ,EAAG,CAC1B/yC,CAAAwlB,YAAA,CAAqBr3B,CAArB,CAA8B6kD,EAA9B,CACAhzC,EAAA8X,SAAA,CAAkB3pB,CAAlB,CAA2B8kD,EAA3B,CACAp4C,EAAA02C,OAAA;AAAc,CAAA,CACd12C,EAAA22C,UAAA,CAAiB,CAAA,CACjBR,EAAA8B,UAAA,EAL0B,CAsB5Bj4C,EAAAq4C,aAAA,CAAoBC,QAAS,EAAG,CAC9BnzC,CAAAozC,SAAA,CAAkBjlD,CAAlB,CAA2B6kD,EAA3B,CAA2CC,EAA3C,CA9NcI,eA8Nd,CACAx4C,EAAA02C,OAAA,CAAc,CAAA,CACd12C,EAAA22C,UAAA,CAAiB,CAAA,CACjB32C,EAAA82C,WAAA,CAAkB,CAAA,CAClBrnD,EAAA,CAAQymD,CAAR,CAAkB,QAAQ,CAACgB,CAAD,CAAU,CAClCA,CAAAmB,aAAA,EADkC,CAApC,CAL8B,CAuBhCr4C,EAAAy4C,cAAA,CAAqBC,QAAS,EAAG,CAC/BjpD,CAAA,CAAQymD,CAAR,CAAkB,QAAQ,CAACgB,CAAD,CAAU,CAClCA,CAAAuB,cAAA,EADkC,CAApC,CAD+B,CAajCz4C,EAAA24C,cAAA,CAAqBC,QAAS,EAAG,CAC/BzzC,CAAA8X,SAAA,CAAkB3pB,CAAlB,CAlQcklD,cAkQd,CACAx4C,EAAA82C,WAAA,CAAkB,CAAA,CAClBX,EAAAwC,cAAA,EAH+B,CArNqC,CAi1CxEE,QAASA,GAAoB,CAACf,CAAD,CAAO,CAClCA,CAAAgB,YAAA3oD,KAAA,CAAsB,QAAQ,CAACM,CAAD,CAAQ,CACpC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAA,CAAuBA,CAAvB,CAA+BA,CAAA6B,SAAA,EADF,CAAtC,CADkC,CAWpC0mD,QAASA,GAAa,CAACt/C,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiD,CACtD/R,CAAAP,KAAA,CAnnlBakmD,UAmnlBb,CADsD,KAEjEC,EAAc5lD,CAAA,CAAQ,CAAR,CAAA4lD,YAFmD,CAE3BC,EAAU,EAFiB,CAGjEhuC,EAAO5X,CAAA,CAAUD,CAAA,CAAQ,CAAR,CAAA6X,KAAV,CAKX,IAAKwiC,CAAAlmC,CAAAkmC,QAAL,CAAuB,CACrB,IAAIyL;AAAY,CAAA,CAEhB9lD,EAAA+H,GAAA,CAAW,kBAAX,CAA+B,QAAQ,CAACxB,CAAD,CAAO,CAC5Cu/C,CAAA,CAAY,CAAA,CADgC,CAA9C,CAIA9lD,EAAA+H,GAAA,CAAW,gBAAX,CAA6B,QAAQ,EAAG,CACtC+9C,CAAA,CAAY,CAAA,CACZhjC,EAAA,EAFsC,CAAxC,CAPqB,CAavB,IAAIA,EAAWA,QAAQ,CAACijC,CAAD,CAAK,CAC1B,GAAID,CAAAA,CAAJ,CAAA,CAD0B,IAEtB3oD,EAAQ6C,CAAA0C,IAAA,EAFc,CAGtBqY,EAAQgrC,CAARhrC,EAAcgrC,CAAAluC,KAMdqjC,GAAJ,EAAqC,OAArC,GAAYrjC,CAACkuC,CAADluC,EAAOguC,CAAPhuC,MAAZ,EAAgD7X,CAAA,CAAQ,CAAR,CAAA4lD,YAAhD,GAA2EA,CAA3E,CACEA,CADF,CACgB5lD,CAAA,CAAQ,CAAR,CAAA4lD,YADhB,EAQa,UAOb,GAPI/tC,CAOJ,EAP6BnY,CAAAsmD,OAO7B,EAP4D,OAO5D,GAP4CtmD,CAAAsmD,OAO5C,GANE7oD,CAMF,CANU4Z,CAAA,CAAK5Z,CAAL,CAMV,GAAIqnD,CAAAyB,WAAJ,GAAwB9oD,CAAxB,EAA4C,EAA5C,GAAkCA,CAAlC,EAAkDqnD,CAAA0B,sBAAlD,GACE1B,CAAA2B,cAAA,CAAmBhpD,CAAnB,CAA0B4d,CAA1B,CAhBF,CARA,CAD0B,CA+B5B,IAAI5G,CAAA8mC,SAAA,CAAkB,OAAlB,CAAJ,CACEj7C,CAAA+H,GAAA,CAAW,OAAX,CAAoB+a,CAApB,CADF,KAEO,CACL,IAAI8b,CAAJ,CAEIwnB,EAAgBA,QAAQ,CAACL,CAAD,CAAK,CAC1BnnB,CAAL,GACEA,CADF,CACY7sB,CAAAqT,MAAA,CAAe,QAAQ,EAAG,CAClCtC,CAAA,CAASijC,CAAT,CACAnnB,EAAA,CAAU,IAFwB,CAA1B,CADZ,CAD+B,CASjC5+B,EAAA+H,GAAA,CAAW,SAAX,CAAsB,QAAQ,CAACgT,CAAD,CAAQ,CACpC,IAAIze,EAAMye,CAAAsrC,QAIE,GAAZ,GAAI/pD,CAAJ,EAAmB,EAAnB,CAAwBA,CAAxB;AAAqC,EAArC,CAA+BA,CAA/B,EAA6C,EAA7C,EAAmDA,CAAnD,EAAiE,EAAjE,EAA0DA,CAA1D,EAEA8pD,CAAA,CAAcrrC,CAAd,CAPoC,CAAtC,CAWA,IAAI5G,CAAA8mC,SAAA,CAAkB,OAAlB,CAAJ,CACEj7C,CAAA+H,GAAA,CAAW,WAAX,CAAwBq+C,CAAxB,CAxBG,CA8BPpmD,CAAA+H,GAAA,CAAW,QAAX,CAAqB+a,CAArB,CAEA0hC,EAAA8B,QAAA,CAAeC,QAAQ,EAAG,CACxBvmD,CAAA0C,IAAA,CAAY8hD,CAAAiB,SAAA,CAAcjB,CAAAgC,YAAd,CAAA,CAAkC,EAAlC,CAAuChC,CAAAyB,WAAnD,CADwB,CAtF2C,CA2HvEQ,QAASA,GAAgB,CAACt9B,CAAD,CAASu9B,CAAT,CAAkB,CACzC,MAAO,SAAQ,CAACC,CAAD,CAAMnH,CAAN,CAAY,CAAA,IACrBt7C,CADqB,CACdq+C,CAEX,IAAIxjD,EAAA,CAAO4nD,CAAP,CAAJ,CACE,MAAOA,EAGT,IAAI1qD,CAAA,CAAS0qD,CAAT,CAAJ,CAAmB,CAII,GAArB,EAAIA,CAAAnlD,OAAA,CAAW,CAAX,CAAJ,EAAwD,GAAxD,EAA4BmlD,CAAAnlD,OAAA,CAAWmlD,CAAA7qD,OAAX,CAAsB,CAAtB,CAA5B,GACE6qD,CADF,CACQA,CAAAxhC,UAAA,CAAc,CAAd,CAAiBwhC,CAAA7qD,OAAjB,CAA4B,CAA5B,CADR,CAGA,IAAI8qD,EAAAlgD,KAAA,CAAqBigD,CAArB,CAAJ,CACE,MAAO,KAAI7lD,IAAJ,CAAS6lD,CAAT,CAETx9B,EAAAjoB,UAAA,CAAmB,CAGnB,IAFAgD,CAEA,CAFQilB,CAAAhT,KAAA,CAAYwwC,CAAZ,CAER,CAqBE,MApBAziD,EAAAya,MAAA,EAoBO,CAlBL4jC,CAkBK,CAnBH/C,CAAJ,CACQ,CACJqH,KAAMrH,CAAAS,YAAA,EADF,CAEJ6G,GAAItH,CAAAW,SAAA,EAAJ2G,CAAsB,CAFlB,CAGJC,GAAIvH,CAAAY,QAAA,EAHA,CAIJ4G,GAAIxH,CAAAyH,SAAA,EAJA,CAKJC,GAAI1H,CAAAiC,WAAA,EALA,CAMJ0F,GAAI3H,CAAA4H,WAAA,EANA,CAOJC,IAAK7H,CAAA8H,gBAAA,EAALD;AAA8B,GAP1B,CADR,CAWQ,CAAER,KAAM,IAAR,CAAcC,GAAI,CAAlB,CAAqBC,GAAI,CAAzB,CAA4BC,GAAI,CAAhC,CAAmCE,GAAI,CAAvC,CAA0CC,GAAI,CAA9C,CAAiDE,IAAK,CAAtD,CAQD,CALPlrD,CAAA,CAAQ+H,CAAR,CAAe,QAAQ,CAACqjD,CAAD,CAAOnnD,CAAP,CAAc,CAC/BA,CAAJ,CAAYsmD,CAAA5qD,OAAZ,GACEymD,CAAA,CAAImE,CAAA,CAAQtmD,CAAR,CAAJ,CADF,CACwB,CAACmnD,CADzB,CADmC,CAArC,CAKO,CAAA,IAAIzmD,IAAJ,CAASyhD,CAAAsE,KAAT,CAAmBtE,CAAAuE,GAAnB,CAA4B,CAA5B,CAA+BvE,CAAAwE,GAA/B,CAAuCxE,CAAAyE,GAAvC,CAA+CzE,CAAA2E,GAA/C,CAAuD3E,CAAA4E,GAAvD,EAAiE,CAAjE,CAA8E,GAA9E,CAAoE5E,CAAA8E,IAApE,EAAsF,CAAtF,CAlCQ,CAsCnB,MAAOG,IA7CkB,CADc,CAkD3CC,QAASA,GAAmB,CAAC5vC,CAAD,CAAOsR,CAAP,CAAeu+B,CAAf,CAA0BtG,CAA1B,CAAkC,CAC5D,MAAOuG,SAA6B,CAACvhD,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiDU,CAAjD,CAA0D,CAkE5Fm1C,QAASA,EAAsB,CAACllD,CAAD,CAAM,CACnC,MAAO9D,EAAA,CAAU8D,CAAV,CAAA,CAAkB3D,EAAA,CAAO2D,CAAP,CAAA,CAAcA,CAAd,CAAoBglD,CAAA,CAAUhlD,CAAV,CAAtC,CAAwDjH,CAD5B,CAjErCosD,EAAA,CAAgBzhD,CAAhB,CAAuBpG,CAAvB,CAAgCN,CAAhC,CAAsC8kD,CAAtC,CACAkB,GAAA,CAAct/C,CAAd,CAAqBpG,CAArB,CAA8BN,CAA9B,CAAoC8kD,CAApC,CAA0CrwC,CAA1C,CAAoDpC,CAApD,CACA,KAAIsvC,EAAWmD,CAAXnD,EAAmBmD,CAAAsD,SAAnBzG,EAAoCmD,CAAAsD,SAAAzG,SAAxC,CACI0G,CAEJvD,EAAAwD,aAAA,CAAoBnwC,CACpB2sC,EAAAyD,SAAAprD,KAAA,CAAmB,QAAQ,CAACM,CAAD,CAAQ,CACjC,MAAIqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAJ,CAAiC,IAAjC,CACIgsB,CAAAziB,KAAA,CAAYvJ,CAAZ,CAAJ,EAIM+qD,CAIGA,CAJUR,CAAA,CAAUvqD,CAAV,CAAiB4qD,CAAjB,CAIVG,CAHU,KAGVA,GAHH7G,CAGG6G,EAFLA,CAAA1G,WAAA,CAAsB0G,CAAAzG,WAAA,EAAtB,CAAgDyG,CAAAxG,kBAAA,EAAhD,CAEKwG,CAAAA,CART,EAUOzsD,CAZ0B,CAAnC,CAeA+oD,EAAAgB,YAAA3oD,KAAA,CAAsB,QAAQ,CAACM,CAAD,CAAQ,CACpC,GAAKqnD,CAAAiB,SAAA,CAActoD,CAAd,CAAL,CAWE4qD,CAAA;AAAe,IAXjB,KAA2B,CACzB,GAAK,CAAAhpD,EAAA,CAAO5B,CAAP,CAAL,CACE,KAAMgrD,GAAA,CAAe,SAAf,CAAyDhrD,CAAzD,CAAN,CAGF,IADA4qD,CACA,CADe5qD,CACf,GAAiC,KAAjC,GAAoBkkD,CAApB,CAAwC,CACtC,IAAI+G,EAAiB,GAAjBA,CAAyBL,CAAArG,kBAAA,EAC7BqG,EAAA,CAAe,IAAIjnD,IAAJ,CAASinD,CAAAhnD,QAAA,EAAT,CAAkCqnD,CAAlC,CAFuB,CAIxC,MAAO31C,EAAA,CAAQ,MAAR,CAAA,CAAgBtV,CAAhB,CAAuBikD,CAAvB,CAA+BC,CAA/B,CATkB,CAa3B,MAAO,EAd6B,CAAtC,CAiBA,IAAIziD,CAAA,CAAUc,CAAAq/C,IAAV,CAAJ,EAA2Br/C,CAAA2oD,MAA3B,CAAuC,CACrC,IAAIC,CACJ9D,EAAA+D,YAAAxJ,IAAA,CAAuByJ,QAAQ,CAACrrD,CAAD,CAAQ,CACrC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+BwB,CAAA,CAAY2pD,CAAZ,CAA/B,EAAsDZ,CAAA,CAAUvqD,CAAV,CAAtD,EAA0EmrD,CADrC,CAGvC5oD,EAAAkxB,SAAA,CAAc,KAAd,CAAqB,QAAQ,CAACluB,CAAD,CAAM,CACjC4lD,CAAA,CAASV,CAAA,CAAuBllD,CAAvB,CACT8hD,EAAAiE,UAAA,EAFiC,CAAnC,CALqC,CAWvC,GAAI7pD,CAAA,CAAUc,CAAA2zB,IAAV,CAAJ,EAA2B3zB,CAAAgpD,MAA3B,CAAuC,CACrC,IAAIC,CACJnE,EAAA+D,YAAAl1B,IAAA,CAAuBu1B,QAAQ,CAACzrD,CAAD,CAAQ,CACrC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+BwB,CAAA,CAAYgqD,CAAZ,CAA/B,EAAsDjB,CAAA,CAAUvqD,CAAV,CAAtD,EAA0EwrD,CADrC,CAGvCjpD,EAAAkxB,SAAA,CAAc,KAAd,CAAqB,QAAQ,CAACluB,CAAD,CAAM,CACjCimD,CAAA,CAASf,CAAA,CAAuBllD,CAAvB,CACT8hD,EAAAiE,UAAA,EAFiC,CAAnC,CALqC,CAWvCjE,CAAAiB,SAAA,CAAgBoD,QAAQ,CAAC1rD,CAAD,CAAQ,CAE9B,MAAO,CAACA,CAAR,EAAkBA,CAAA4D,QAAlB,EAAmC5D,CAAA4D,QAAA,EAAnC;AAAuD5D,CAAA4D,QAAA,EAFzB,CA7D4D,CADlC,CAyE9D8mD,QAASA,GAAe,CAACzhD,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6B,CAGnD,CADuBA,CAAA0B,sBACvB,CADoDrnD,CAAA,CADzCmB,CAAAT,CAAQ,CAARA,CACkDupD,SAAT,CACpD,GACEtE,CAAAyD,SAAAprD,KAAA,CAAmB,QAAQ,CAACM,CAAD,CAAQ,CACjC,IAAI2rD,EAAW9oD,CAAAP,KAAA,CA72lBSkmD,UA62lBT,CAAXmD,EAAoD,EAKxD,OAAOA,EAAAC,SAAA,EAAsBC,CAAAF,CAAAE,aAAtB,CAA8CvtD,CAA9C,CAA0D0B,CANhC,CAAnC,CAJiD,CAmHrD8rD,QAASA,GAAiB,CAAC11C,CAAD,CAASlX,CAAT,CAAkB6I,CAAlB,CAAwB00B,CAAxB,CAAoCsvB,CAApC,CAA8C,CAEtE,GAAItqD,CAAA,CAAUg7B,CAAV,CAAJ,CAA2B,CACzBuvB,CAAA,CAAU51C,CAAA,CAAOqmB,CAAP,CACV,IAAKxuB,CAAA+9C,CAAA/9C,SAAL,CACE,KAAM1P,EAAA,CAAO,SAAP,CAAA,CAAkB,WAAlB,CACiCwJ,CADjC,CACuC00B,CADvC,CAAN,CAGF,MAAOuvB,EAAA,CAAQ9sD,CAAR,CANkB,CAQ3B,MAAO6sD,EAV+D,CA2qDxE3E,QAASA,GAAoB,CAACloD,CAAD,CAAU,CA4ErC+sD,QAASA,EAAiB,CAAC1/B,CAAD,CAAY2/B,CAAZ,CAAyB,CAC7CA,CAAJ,EAAoB,CAAAC,CAAA,CAAW5/B,CAAX,CAApB,EACE7X,CAAA8X,SAAA,CAAkBF,CAAlB,CAA4BC,CAA5B,CACA,CAAA4/B,CAAA,CAAW5/B,CAAX,CAAA,CAAwB,CAAA,CAF1B,EAGY2/B,CAAAA,CAHZ,EAG2BC,CAAA,CAAW5/B,CAAX,CAH3B,GAIE7X,CAAAwlB,YAAA,CAAqB5N,CAArB,CAA+BC,CAA/B,CACA,CAAA4/B,CAAA,CAAW5/B,CAAX,CAAA,CAAwB,CAAA,CAL1B,CADiD,CAUnD6/B,QAASA,EAAmB,CAACC,CAAD,CAAqBC,CAArB,CAA8B,CACxDD,CAAA,CAAqBA,CAAA,CAAqB,GAArB,CAA2BniD,EAAA,CAAWmiD,CAAX,CAA+B,GAA/B,CAA3B,CAAiE,EAEtFJ,EAAA,CAAkBM,EAAlB,CAAgCF,CAAhC,CAAgE,CAAA,CAAhE,GAAoDC,CAApD,CACAL,EAAA,CAAkBO,EAAlB,CAAkCH,CAAlC,CAAkE,CAAA,CAAlE,GAAsDC,CAAtD,CAJwD,CAtFrB,IACjCjF,EAAOnoD,CAAAmoD,KAD0B,CAEjC/6B,EAAWptB,CAAAotB,SAFsB,CAGjC6/B,EAAa,EAHoB,CAIjC7E,EAAMpoD,CAAAooD,IAJ2B,CAKjCC;AAAQroD,CAAAqoD,MALyB,CAMjC7B,EAAaxmD,CAAAwmD,WANoB,CAOjChxC,EAAWxV,CAAAwV,SAEfy3C,EAAA,CAAWK,EAAX,CAAA,CAA4B,EAAEL,CAAA,CAAWI,EAAX,CAAF,CAA4BjgC,CAAAmgC,SAAA,CAAkBF,EAAlB,CAA5B,CAE5BlF,EAAAF,aAAA,CAEAuF,QAAoB,CAACL,CAAD,CAAqBhnC,CAArB,CAA4BsD,CAA5B,CAAqC,CACnDtD,CAAJ,GAAc/mB,CAAd,EA+CK+oD,CAAA,SAGL,GAFEA,CAAA,SAEF,CAFe,EAEf,EAAAC,CAAA,CAAID,CAAA,SAAJ,CAjD2BgF,CAiD3B,CAjD+C1jC,CAiD/C,CAlDA,GAsDI0+B,CAAA,SAGJ,EAFEE,CAAA,CAAMF,CAAA,SAAN,CApD4BgF,CAoD5B,CApDgD1jC,CAoDhD,CAEF,CAAIgkC,EAAA,CAActF,CAAA,SAAd,CAAJ,GACEA,CAAA,SADF,CACe/oD,CADf,CAzDA,CAKK4D,GAAA,CAAUmjB,CAAV,CAAL,CAIMA,CAAJ,EACEkiC,CAAA,CAAMF,CAAAxB,OAAN,CAAmBwG,CAAnB,CAAuC1jC,CAAvC,CACA,CAAA2+B,CAAA,CAAID,CAAAvB,UAAJ,CAAoBuG,CAApB,CAAwC1jC,CAAxC,CAFF,GAIE2+B,CAAA,CAAID,CAAAxB,OAAJ,CAAiBwG,CAAjB,CAAqC1jC,CAArC,CACA,CAAA4+B,CAAA,CAAMF,CAAAvB,UAAN,CAAsBuG,CAAtB,CAA0C1jC,CAA1C,CALF,CAJF,EACE4+B,CAAA,CAAMF,CAAAxB,OAAN,CAAmBwG,CAAnB,CAAuC1jC,CAAvC,CACA,CAAA4+B,CAAA,CAAMF,CAAAvB,UAAN,CAAsBuG,CAAtB,CAA0C1jC,CAA1C,CAFF,CAYI0+B,EAAAtB,SAAJ,EACEkG,CAAA,CAAkBW,EAAlB,CAAiC,CAAA,CAAjC,CAEA,CADAvF,CAAAlB,OACA,CADckB,CAAAjB,SACd,CAD8B9nD,CAC9B,CAAA8tD,CAAA,CAAoB,EAApB,CAAwB,IAAxB,CAHF,GAKEH,CAAA,CAAkBW,EAAlB,CAAiC,CAAA,CAAjC,CAGA,CAFAvF,CAAAlB,OAEA,CAFcwG,EAAA,CAActF,CAAAxB,OAAd,CAEd,CADAwB,CAAAjB,SACA,CADgB,CAACiB,CAAAlB,OACjB,CAAAiG,CAAA,CAAoB,EAApB,CAAwB/E,CAAAlB,OAAxB,CARF,CAiBE0G,EAAA,CADExF,CAAAtB,SAAJ,EAAqBsB,CAAAtB,SAAA,CAAcsG,CAAd,CAArB,CACkB/tD,CADlB,CAEW+oD,CAAAxB,OAAA,CAAYwG,CAAZ,CAAJ,CACW,CAAA,CADX;AAEIhF,CAAAvB,UAAA,CAAeuG,CAAf,CAAJ,CACW,CAAA,CADX,CAGW,IAElBD,EAAA,CAAoBC,CAApB,CAAwCQ,CAAxC,CACAnH,EAAAyB,aAAA,CAAwBkF,CAAxB,CAA4CQ,CAA5C,CAA2DxF,CAA3D,CA5CuD,CAbpB,CA8FvCsF,QAASA,GAAa,CAACluD,CAAD,CAAM,CAC1B,GAAIA,CAAJ,CACE,IAAS6D,IAAAA,CAAT,GAAiB7D,EAAjB,CACE,MAAO,CAAA,CAGX,OAAO,CAAA,CANmB,CAwN5BquD,QAASA,GAAc,CAAC/kD,CAAD,CAAO4T,CAAP,CAAiB,CACtC5T,CAAA,CAAO,SAAP,CAAmBA,CACnB,OAAO,CAAC,UAAD,CAAa,QAAQ,CAAC2M,CAAD,CAAW,CA+ErCq4C,QAASA,EAAe,CAACjxB,CAAD,CAAUC,CAAV,CAAmB,CACzC,IAAIF,EAAS,EAAb,CAGQh8B,EAAI,CADZ,EAAA,CACA,IAAA,CAAeA,CAAf,CAAmBi8B,CAAAn9B,OAAnB,CAAmCkB,CAAA,EAAnC,CAAwC,CAEtC,IADA,IAAIm8B,EAAQF,CAAA,CAAQj8B,CAAR,CAAZ,CACQc,EAAI,CAAZ,CAAeA,CAAf,CAAmBo7B,CAAAp9B,OAAnB,CAAmCgC,CAAA,EAAnC,CACE,GAAGq7B,CAAH,EAAYD,CAAA,CAAQp7B,CAAR,CAAZ,CAAwB,SAAS,CAEnCk7B,EAAAn8B,KAAA,CAAYs8B,CAAZ,CALsC,CAOxC,MAAOH,EAXkC,CAc3CmxB,QAASA,EAAa,CAAChzB,CAAD,CAAW,CAC/B,GAAI,CAAAj7B,CAAA,CAAQi7B,CAAR,CAAJ,CAEO,CAAA,GAAIl7B,CAAA,CAASk7B,CAAT,CAAJ,CACL,MAAOA,EAAAr3B,MAAA,CAAe,GAAf,CACF,IAAIjB,CAAA,CAASs4B,CAAT,CAAJ,CAAwB,CAAA,IACzBizB,EAAU,EACdjuD,EAAA,CAAQg7B,CAAR,CAAkB,QAAQ,CAAC2H,CAAD,CAAIjI,CAAJ,CAAO,CAC3BiI,CAAJ,GACEsrB,CADF,CACYA,CAAAroD,OAAA,CAAe80B,CAAA/2B,MAAA,CAAQ,GAAR,CAAf,CADZ,CAD+B,CAAjC,CAKA,OAAOsqD,EAPsB,CAFxB,CAWP,MAAOjzB,EAdwB,CA5FjC,MAAO,CACLpO,SAAU,IADL,CAEL3C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAiCnC2qD,QAASA,EAAkB,CAACD,CAAD,CAAUvnB,CAAV,CAAiB,CAC1C,IAAIynB,EAActqD,CAAAuG,KAAA,CAAa,cAAb,CAAd+jD;AAA8C,EAAlD,CACIC,EAAkB,EACtBpuD,EAAA,CAAQiuD,CAAR,CAAiB,QAAS,CAAC1gC,CAAD,CAAY,CACpC,GAAY,CAAZ,CAAImZ,CAAJ,EAAiBynB,CAAA,CAAY5gC,CAAZ,CAAjB,CACE4gC,CAAA,CAAY5gC,CAAZ,CACA,EAD0B4gC,CAAA,CAAY5gC,CAAZ,CAC1B,EADoD,CACpD,EADyDmZ,CACzD,CAAIynB,CAAA,CAAY5gC,CAAZ,CAAJ,GAA+B,EAAU,CAAV,CAAEmZ,CAAF,CAA/B,EACE0nB,CAAA1tD,KAAA,CAAqB6sB,CAArB,CAJgC,CAAtC,CAQA1pB,EAAAuG,KAAA,CAAa,cAAb,CAA6B+jD,CAA7B,CACA,OAAOC,EAAAlmD,KAAA,CAAqB,GAArB,CAZmC,CA4B5CmmD,QAASA,EAAkB,CAACppC,CAAD,CAAS,CAClC,GAAiB,CAAA,CAAjB,GAAItI,CAAJ,EAAyB1S,CAAAqkD,OAAzB,CAAwC,CAAxC,GAA8C3xC,CAA9C,CAAwD,CACtD,IAAIwe,EAAa6yB,CAAA,CAAa/oC,CAAb,EAAuB,EAAvB,CACjB,IAAKC,CAAAA,CAAL,CAAa,CAxCf,IAAIiW,EAAa+yB,CAAA,CAyCF/yB,CAzCE,CAA2B,CAA3B,CACjB53B,EAAAw3B,UAAA,CAAeI,CAAf,CAuCe,CAAb,IAEO,IAAK,CAAA71B,EAAA,CAAO2f,CAAP,CAAcC,CAAd,CAAL,CAA4B,CAEnBqT,IAAAA,EADGy1B,CAAAz1B,CAAarT,CAAbqT,CACHA,CAnBd6C,EAAQ2yB,CAAA,CAmBkB5yB,CAnBlB,CAA4B5C,CAA5B,CAmBMA,CAlBd+C,EAAWyyB,CAAA,CAAgBx1B,CAAhB,CAkBe4C,CAlBf,CAkBG5C,CAjBlB6C,EAAQ8yB,CAAA,CAAkB9yB,CAAlB,CAAyB,CAAzB,CAiBU7C,CAhBlB+C,EAAW4yB,CAAA,CAAkB5yB,CAAlB,CAA6B,EAA7B,CACPF,EAAJ,EAAaA,CAAAz7B,OAAb,EACE+V,CAAA8X,SAAA,CAAkB3pB,CAAlB,CAA2Bu3B,CAA3B,CAEEE,EAAJ,EAAgBA,CAAA37B,OAAhB,EACE+V,CAAAwlB,YAAA,CAAqBr3B,CAArB,CAA8By3B,CAA9B,CASmC,CAJmB,CASxDpW,CAAA,CAAS/f,EAAA,CAAY8f,CAAZ,CAVyB,CA5DpC,IAAIC,CAEJjb,EAAAhH,OAAA,CAAaM,CAAA,CAAKwF,CAAL,CAAb,CAAyBslD,CAAzB,CAA6C,CAAA,CAA7C,CAEA9qD,EAAAkxB,SAAA,CAAc,OAAd,CAAuB,QAAQ,CAACzzB,CAAD,CAAQ,CACrCqtD,CAAA,CAAmBpkD,CAAAqwC,MAAA,CAAY/2C,CAAA,CAAKwF,CAAL,CAAZ,CAAnB,CADqC,CAAvC,CAKa,UAAb,GAAIA,CAAJ,EACEkB,CAAAhH,OAAA,CAAa,QAAb,CAAuB,QAAQ,CAACqrD,CAAD,CAASC,CAAT,CAAoB,CAEjD,IAAIC,EAAMF,CAANE,CAAe,CACnB,IAAIA,CAAJ,IAAaD,CAAb,CAAyB,CAAzB,EAA6B,CAC3B,IAAIN;AAAUD,CAAA,CAAa/jD,CAAAqwC,MAAA,CAAY/2C,CAAA,CAAKwF,CAAL,CAAZ,CAAb,CACdylD,EAAA,GAAQ7xC,CAAR,EAQAwe,CACJ,CADiB+yB,CAAA,CAPAD,CAOA,CAA2B,CAA3B,CACjB,CAAA1qD,CAAAw3B,UAAA,CAAeI,CAAf,CATI,GAaAA,CACJ,CADiB+yB,CAAA,CAXGD,CAWH,CAA4B,EAA5B,CACjB,CAAA1qD,CAAA03B,aAAA,CAAkBE,CAAlB,CAdI,CAF2B,CAHoB,CAAnD,CAXiC,CAFhC,CAD8B,CAAhC,CAF+B,CAh8pBxC,IAAIszB,GAAsB,oBAA1B,CAgBI3qD,EAAYA,QAAQ,CAACqgD,CAAD,CAAQ,CAAC,MAAOrkD,EAAA,CAASqkD,CAAT,CAAA,CAAmBA,CAAA54C,YAAA,EAAnB,CAA0C44C,CAAlD,CAhBhC,CAiBI9jD,GAAiBqB,MAAAS,UAAA9B,eAjBrB,CA6BIoP,GAAYA,QAAQ,CAAC00C,CAAD,CAAQ,CAAC,MAAOrkD,EAAA,CAASqkD,CAAT,CAAA,CAAmBA,CAAA/qC,YAAA,EAAnB,CAA0C+qC,CAAlD,CA7BhC,CAwDIpF,EAxDJ,CAyDI/3C,CAzDJ,CA0DI2E,EA1DJ,CA2DI5F,GAAoB,EAAAA,MA3DxB,CA4DI5B,GAAoB,EAAAA,OA5DxB,CA6DIzD,GAAoB,EAAAA,KA7DxB,CA8DImC,GAAoBnB,MAAAS,UAAAU,SA9DxB,CA+DI4B,GAAoBlF,CAAA,CAAO,IAAP,CA/DxB,CAkEIiL,GAAoBpL,CAAAoL,QAApBA,GAAuCpL,CAAAoL,QAAvCA,CAAwD,EAAxDA,CAlEJ,CAmEIoF,EAnEJ,CAoEI1O,GAAoB,CAMxB69C,GAAA,CAAO1/C,CAAAm+C,aAyMPp7C,EAAAke,QAAA,CAAe,EAoBfje,GAAAie,QAAA,CAAmB,EAiHnB,KAAIvgB,EAAU+jB,KAAA/jB,QAAd,CAkEI6a,EAAOA,QAAQ,CAAC5Z,CAAD,CAAQ,CACzB,MAAOlB,EAAA,CAASkB,CAAT,CAAA,CAAkBA,CAAA4Z,KAAA,EAAlB,CAAiC5Z,CADf,CAlE3B,CA+XI2O,GAAMA,QAAQ,EAAG,CACnB,GAAIlN,CAAA,CAAUkN,EAAA++C,UAAV,CAAJ,CAA8B,MAAO/+C,GAAA++C,UAErC;IAAIC,EAAS,EAAG,CAAAtvD,CAAA8J,cAAA,CAAuB,UAAvB,CAAH,EACG,CAAA9J,CAAA8J,cAAA,CAAuB,eAAvB,CADH,CAGb,IAAKwlD,CAAAA,CAAL,CACE,GAAI,CAEF,IAAI7d,QAAJ,CAAa,EAAb,CAFE,CAIF,MAAO3pC,CAAP,CAAU,CACVwnD,CAAA,CAAS,CAAA,CADC,CAKd,MAAQh/C,GAAA++C,UAAR,CAAwBC,CAhBL,CA/XrB,CAynBInmD,GAAiB,CAAC,KAAD,CAAQ,UAAR,CAAoB,KAApB,CAA2B,OAA3B,CAznBrB,CAg7BI4C,GAAoB,QAh7BxB,CAw7BIM,GAAkB,CAAA,CAx7BtB,CAy7BIW,EAz7BJ,CA4kCIxM,GAAoB,CA5kCxB,CA6kCI0H,GAAiB,CA7kCrB,CAo/CIiI,GAAU,CACZo/C,KAAM,OADM,CAEZC,MAAO,CAFK,CAGZC,MAAO,CAHK,CAIZC,IAAK,CAJO,CAKZC,SAAU,oBALE,CA+OdtiD,EAAA+tB,QAAA,CAAiB,OArzEsB,KAuzEnCte,GAAUzP,CAAAyV,MAAVhG,CAAyB,EAvzEU,CAwzEnCE,GAAO,CAWX3P,EAAAH,MAAA,CAAe0iD,QAAQ,CAAC7rD,CAAD,CAAO,CAE5B,MAAO,KAAA+e,MAAA,CAAW/e,CAAA,CAAK,IAAAq3B,QAAL,CAAX,CAAP,EAAyC,EAFb,CAQ9B,KAAIxhB,GAAuB,iBAA3B,CACII,GAAkB,aADtB,CAEI61C,GAAiB,CAAEC,WAAa,UAAf,CAA2BC,WAAa,WAAxC,CAFrB,CAGIv0C,GAAetb,CAAA,CAAO,QAAP,CAHnB,CAkBIwb,GAAoB,4BAlBxB;AAmBInB,GAAc,WAnBlB,CAoBIG,GAAkB,WApBtB,CAqBIM,GAAmB,yEArBvB,CAuBIH,GAAU,CACZ,OAAU,CAAC,CAAD,CAAI,8BAAJ,CAAoC,WAApC,CADE,CAGZ,MAAS,CAAC,CAAD,CAAI,SAAJ,CAAe,UAAf,CAHG,CAIZ,IAAO,CAAC,CAAD,CAAI,mBAAJ,CAAyB,qBAAzB,CAJK,CAKZ,GAAM,CAAC,CAAD,CAAI,gBAAJ,CAAsB,kBAAtB,CALM,CAMZ,GAAM,CAAC,CAAD,CAAI,oBAAJ,CAA0B,uBAA1B,CANM,CAOZ,SAAY,CAAC,CAAD,CAAI,EAAJ,CAAQ,EAAR,CAPA,CAUdA,GAAAm1C,SAAA,CAAmBn1C,EAAAnJ,OACnBmJ,GAAAo1C,MAAA,CAAgBp1C,EAAAq1C,MAAhB,CAAgCr1C,EAAAs1C,SAAhC,CAAmDt1C,EAAAu1C,QAAnD,CAAqEv1C,EAAAw1C,MACrEx1C,GAAAy1C,GAAA,CAAaz1C,EAAA01C,GA2Tb,KAAI/jD,GAAkBa,CAAAvK,UAAlB0J,CAAqC,CACvCgkD,MAAOA,QAAQ,CAAC3pD,CAAD,CAAK,CAGlB4pD,QAASA,EAAO,EAAG,CACbC,CAAJ,GACAA,CACA;AADQ,CAAA,CACR,CAAA7pD,CAAA,EAFA,CADiB,CAFnB,IAAI6pD,EAAQ,CAAA,CASgB,WAA5B,GAAI1wD,CAAA6e,WAAJ,CACEC,UAAA,CAAW2xC,CAAX,CADF,EAGE,IAAAlkD,GAAA,CAAQ,kBAAR,CAA4BkkD,CAA5B,CAKA,CAFApjD,CAAA,CAAOtN,CAAP,CAAAwM,GAAA,CAAkB,MAAlB,CAA0BkkD,CAA1B,CAEA,CAAA,IAAAlkD,GAAA,CAAQ,kBAAR,CAA4BkkD,CAA5B,CARF,CAVkB,CADmB,CAsBvCjtD,SAAUA,QAAQ,EAAG,CACnB,IAAI7B,EAAQ,EACZhB,EAAA,CAAQ,IAAR,CAAc,QAAQ,CAACmH,CAAD,CAAG,CAAEnG,CAAAN,KAAA,CAAW,EAAX,CAAgByG,CAAhB,CAAF,CAAzB,CACA,OAAO,GAAP,CAAanG,CAAAkH,KAAA,CAAW,IAAX,CAAb,CAAgC,GAHb,CAtBkB,CA4BvC8vC,GAAIA,QAAQ,CAAC/zC,CAAD,CAAQ,CAChB,MAAiB,EAAV,EAACA,CAAD,CAAe+C,CAAA,CAAO,IAAA,CAAK/C,CAAL,CAAP,CAAf,CAAqC+C,CAAA,CAAO,IAAA,CAAK,IAAArH,OAAL,CAAmBsE,CAAnB,CAAP,CAD5B,CA5BmB,CAgCvCtE,OAAQ,CAhC+B,CAiCvCe,KAAMA,EAjCiC,CAkCvCC,KAAM,EAAAA,KAlCiC,CAmCvCwD,OAAQ,EAAAA,OAnC+B,CAAzC,CA2CIma,GAAe,EACnBte,EAAA,CAAQ,2DAAA,MAAA,CAAA,GAAA,CAAR,CAAgF,QAAQ,CAACgB,CAAD,CAAQ,CAC9Fsd,EAAA,CAAaxa,CAAA,CAAU9C,CAAV,CAAb,CAAA,CAAiCA,CAD6D,CAAhG,CAGA,KAAIud,GAAmB,EACvBve,EAAA,CAAQ,kDAAA,MAAA,CAAA,GAAA,CAAR;AAAuE,QAAQ,CAACgB,CAAD,CAAQ,CACrFud,EAAA,CAAiBvd,CAAjB,CAAA,CAA0B,CAAA,CAD2D,CAAvF,CAGA,KAAIyd,GAAe,CACjB,YAAgB,WADC,CAEjB,YAAgB,WAFC,CAGjB,MAAU,KAHO,CAIjB,MAAU,KAJO,CAKjB,UAAc,SALG,CAqBnBze,EAAA,CAAQ,CACNoK,KAAMkS,EADA,CAEN0zC,WAAY30C,EAFN,CAAR,CAGG,QAAQ,CAACnV,CAAD,CAAK6C,CAAL,CAAW,CACpB2D,CAAA,CAAO3D,CAAP,CAAA,CAAe7C,CADK,CAHtB,CAOAlG,EAAA,CAAQ,CACNoK,KAAMkS,EADA,CAENtQ,cAAeqR,EAFT,CAINpT,MAAOA,QAAQ,CAACpG,CAAD,CAAU,CAEvB,MAAOmD,EAAAoD,KAAA,CAAYvG,CAAZ,CAAqB,QAArB,CAAP,EAAyCwZ,EAAA,CAAoBxZ,CAAA2Z,WAApB,EAA0C3Z,CAA1C,CAAmD,CAAC,eAAD,CAAkB,QAAlB,CAAnD,CAFlB,CAJnB,CASNiI,aAAcA,QAAQ,CAACjI,CAAD,CAAU,CAE9B,MAAOmD,EAAAoD,KAAA,CAAYvG,CAAZ,CAAqB,eAArB,CAAP,EAAgDmD,CAAAoD,KAAA,CAAYvG,CAAZ,CAAqB,yBAArB,CAFlB,CAT1B,CAcNkI,WAAYqR,EAdN,CAgBN5T,SAAUA,QAAQ,CAAC3F,CAAD,CAAU,CAC1B,MAAOwZ,GAAA,CAAoBxZ,CAApB,CAA6B,WAA7B,CADmB,CAhBtB,CAoBNq4B,WAAYA,QAAQ,CAACr4B,CAAD,CAAUkF,CAAV,CAAgB,CAClClF,CAAAosD,gBAAA,CAAwBlnD,CAAxB,CADkC,CApB9B,CAwBN0kD,SAAU/wC,EAxBJ;AA0BNwzC,IAAKA,QAAQ,CAACrsD,CAAD,CAAUkF,CAAV,CAAgB/H,CAAhB,CAAuB,CAClC+H,CAAA,CAAOiQ,EAAA,CAAUjQ,CAAV,CAEP,IAAItG,CAAA,CAAUzB,CAAV,CAAJ,CACE6C,CAAAgN,MAAA,CAAc9H,CAAd,CAAA,CAAsB/H,CADxB,KAGE,OAAO6C,EAAAgN,MAAA,CAAc9H,CAAd,CANyB,CA1B9B,CAoCNxF,KAAMA,QAAQ,CAACM,CAAD,CAAUkF,CAAV,CAAgB/H,CAAhB,CAAsB,CAClC,IAAImvD,EAAiBrsD,CAAA,CAAUiF,CAAV,CACrB,IAAIuV,EAAA,CAAa6xC,CAAb,CAAJ,CACE,GAAI1tD,CAAA,CAAUzB,CAAV,CAAJ,CACQA,CAAN,EACE6C,CAAA,CAAQkF,CAAR,CACA,CADgB,CAAA,CAChB,CAAAlF,CAAAiZ,aAAA,CAAqB/T,CAArB,CAA2BonD,CAA3B,CAFF,GAIEtsD,CAAA,CAAQkF,CAAR,CACA,CADgB,CAAA,CAChB,CAAAlF,CAAAosD,gBAAA,CAAwBE,CAAxB,CALF,CADF,KASE,OAAQtsD,EAAA,CAAQkF,CAAR,CAAD,EACEqnD,CAACvsD,CAAAqtB,WAAAm/B,aAAA,CAAgCtnD,CAAhC,CAADqnD,EAAyChuD,CAAzCguD,WADF,CAEED,CAFF,CAGE7wD,CAbb,KAeO,IAAImD,CAAA,CAAUzB,CAAV,CAAJ,CACL6C,CAAAiZ,aAAA,CAAqB/T,CAArB,CAA2B/H,CAA3B,CADK,KAEA,IAAI6C,CAAAoF,aAAJ,CAKL,MAFIqnD,EAEG,CAFGzsD,CAAAoF,aAAA,CAAqBF,CAArB,CAA2B,CAA3B,CAEH,CAAQ,IAAR,GAAAunD,CAAA,CAAehxD,CAAf,CAA2BgxD,CAxBF,CApC9B,CAgENhtD,KAAMA,QAAQ,CAACO,CAAD,CAAUkF,CAAV,CAAgB/H,CAAhB,CAAuB,CACnC,GAAIyB,CAAA,CAAUzB,CAAV,CAAJ,CACE6C,CAAA,CAAQkF,CAAR,CAAA,CAAgB/H,CADlB,KAGE,OAAO6C,EAAA,CAAQkF,CAAR,CAJ0B,CAhE/B,CAwEN8vB,KAAO,QAAQ,EAAG,CAIhB03B,QAASA,EAAO,CAAC1sD,CAAD,CAAU7C,CAAV,CAAiB,CAC/B,GAAIwB,CAAA,CAAYxB,CAAZ,CAAJ,CAAwB,CACtB,IAAIpB,EAAWiE,CAAAjE,SACf,OAAQA,EAAD,GAAcC,EAAd,EAAmCD,CAAnC,GAAgD2H,EAAhD,CAAkE1D,CAAA4W,YAAlE,CAAwF,EAFzE,CAIxB5W,CAAA4W,YAAA;AAAsBzZ,CALS,CAHjCuvD,CAAAC,IAAA,CAAc,EACd,OAAOD,EAFS,CAAZ,EAxEA,CAqFNhqD,IAAKA,QAAQ,CAAC1C,CAAD,CAAU7C,CAAV,CAAiB,CAC5B,GAAIwB,CAAA,CAAYxB,CAAZ,CAAJ,CAAwB,CACtB,GAAI6C,CAAA4sD,SAAJ,EAA+C,QAA/C,GAAwB7sD,EAAA,CAAUC,CAAV,CAAxB,CAAyD,CACvD,IAAIa,EAAS,EACb1E,EAAA,CAAQ6D,CAAA8lB,QAAR,CAAyB,QAAS,CAAC5Y,CAAD,CAAS,CACrCA,CAAA2/C,SAAJ,EACEhsD,CAAAhE,KAAA,CAAYqQ,CAAA/P,MAAZ,EAA4B+P,CAAA8nB,KAA5B,CAFuC,CAA3C,CAKA,OAAyB,EAAlB,GAAAn0B,CAAA/E,OAAA,CAAsB,IAAtB,CAA6B+E,CAPmB,CASzD,MAAOb,EAAA7C,MAVe,CAYxB6C,CAAA7C,MAAA,CAAgBA,CAbY,CArFxB,CAqGNsG,KAAMA,QAAQ,CAACzD,CAAD,CAAU7C,CAAV,CAAiB,CAC7B,GAAIwB,CAAA,CAAYxB,CAAZ,CAAJ,CACE,MAAO6C,EAAAuW,UAETe,GAAA,CAAatX,CAAb,CAAsB,CAAA,CAAtB,CACAA,EAAAuW,UAAA,CAAoBpZ,CALS,CArGzB,CA6GNkG,MAAOyW,EA7GD,CAAR,CA8GG,QAAQ,CAACzX,CAAD,CAAK6C,CAAL,CAAU,CAInB2D,CAAAvK,UAAA,CAAiB4G,CAAjB,CAAA,CAAyB,QAAQ,CAACqmC,CAAD,CAAOC,CAAP,CAAa,CAAA,IACxCxuC,CADwC,CACrCV,CADqC,CAExCwwD,EAAY,IAAAhxD,OAKhB,IAAIuG,CAAJ,GAAWyX,EAAX,GACoB,CAAd,EAACzX,CAAAvG,OAAD,EAAoBuG,CAApB,GAA2BwW,EAA3B,EAA6CxW,CAA7C,GAAoDkX,EAApD,CAAyEgyB,CAAzE,CAAgFC,CADtF,IACgG/vC,CADhG,CAC4G,CAC1G,GAAIoD,CAAA,CAAS0sC,CAAT,CAAJ,CAAoB,CAGlB,IAAKvuC,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB8vD,CAAhB,CAA2B9vD,CAAA,EAA3B,CACE,GAAIqF,CAAJ,GAAWoW,EAAX,CAEEpW,CAAA,CAAG,IAAA,CAAKrF,CAAL,CAAH,CAAYuuC,CAAZ,CAFF,KAIE,KAAKjvC,CAAL,GAAYivC,EAAZ,CACElpC,CAAA,CAAG,IAAA,CAAKrF,CAAL,CAAH,CAAYV,CAAZ,CAAiBivC,CAAA,CAAKjvC,CAAL,CAAjB,CAKN,OAAO,KAdW,CAkBda,CAAAA,CAAQkF,CAAAsqD,IAER5uD;CAAAA,CAAMZ,CAAD,GAAW1B,CAAX,CAAwB23B,IAAA2rB,IAAA,CAAS+N,CAAT,CAAoB,CAApB,CAAxB,CAAiDA,CAC1D,KAAShvD,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoBC,CAApB,CAAwBD,CAAA,EAAxB,CAA6B,CAC3B,IAAImsB,EAAY5nB,CAAA,CAAG,IAAA,CAAKvE,CAAL,CAAH,CAAYytC,CAAZ,CAAkBC,CAAlB,CAChBruC,EAAA,CAAQA,CAAA,CAAQA,CAAR,CAAgB8sB,CAAhB,CAA4BA,CAFT,CAI7B,MAAO9sB,EA1BiG,CA8B1G,IAAKH,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgB8vD,CAAhB,CAA2B9vD,CAAA,EAA3B,CACEqF,CAAA,CAAG,IAAA,CAAKrF,CAAL,CAAH,CAAYuuC,CAAZ,CAAkBC,CAAlB,CAGF,OAAO,KA1CmC,CAJ3B,CA9GrB,CAuNArvC,EAAA,CAAQ,CACNgwD,WAAY30C,EADN,CAGNzP,GAAIglD,QAASA,EAAQ,CAAC/sD,CAAD,CAAU6X,CAAV,CAAgBxV,CAAhB,CAAoByV,CAApB,CAAgC,CACnD,GAAIlZ,CAAA,CAAUkZ,CAAV,CAAJ,CAA4B,KAAMd,GAAA,CAAa,QAAb,CAAN,CAG5B,GAAKvB,EAAA,CAAkBzV,CAAlB,CAAL,CAAA,CAIA,IAAI+X,EAAeC,EAAA,CAAmBhY,CAAnB,CAA4B,CAAA,CAA5B,CACfuI,EAAAA,CAASwP,CAAAxP,OACb,KAAI0P,EAASF,CAAAE,OAERA,EAAL,GACEA,CADF,CACWF,CAAAE,OADX,CACiC4C,EAAA,CAAmB7a,CAAnB,CAA4BuI,CAA5B,CADjC,CAQA,KAHIykD,IAAAA,EAA6B,CAArB,EAAAn1C,CAAAxX,QAAA,CAAa,GAAb,CAAA,CAAyBwX,CAAA/X,MAAA,CAAW,GAAX,CAAzB,CAA2C,CAAC+X,CAAD,CAAnDm1C,CACAhwD,EAAIgwD,CAAAlxD,OAER,CAAOkB,CAAA,EAAP,CAAA,CAAY,CACV6a,CAAA,CAAOm1C,CAAA,CAAMhwD,CAAN,CACP,KAAIme,EAAW5S,CAAA,CAAOsP,CAAP,CAEVsD,EAAL,GACE5S,CAAA,CAAOsP,CAAP,CAqBA,CArBe,EAqBf,CAnBa,YAAb,GAAIA,CAAJ,EAAsC,YAAtC,GAA6BA,CAA7B,CAKEk1C,CAAA,CAAS/sD,CAAT,CAAkBqrD,EAAA,CAAgBxzC,CAAhB,CAAlB,CAAyC,QAAQ,CAACkD,CAAD,CAAQ,CACvD,IAAmBkyC,EAAUlyC,CAAAmyC,cAGvBD,EAAN,GAAkBA,CAAlB,GAHaljB,IAGb,EAHaA,IAG4BojB,SAAA,CAAgBF,CAAhB,CAAzC,GACEh1C,CAAA,CAAO8C,CAAP,CAAclD,CAAd,CALqD,CAAzD,CALF,CAee,UAff,GAeMA,CAfN,EAgBuB7X,CAnsBzB6/B,iBAAA,CAmsBkChoB,CAnsBlC;AAmsBwCI,CAnsBxC,CAAmC,CAAA,CAAnC,CAssBE,CAAAkD,CAAA,CAAW5S,CAAA,CAAOsP,CAAP,CAtBb,CAwBAsD,EAAAte,KAAA,CAAcwF,CAAd,CA5BU,CAhBZ,CAJmD,CAH/C,CAuDN+qD,IAAKx1C,EAvDC,CAyDNy1C,IAAKA,QAAQ,CAACrtD,CAAD,CAAU6X,CAAV,CAAgBxV,CAAhB,CAAoB,CAC/BrC,CAAA,CAAUmD,CAAA,CAAOnD,CAAP,CAKVA,EAAA+H,GAAA,CAAW8P,CAAX,CAAiBy1C,QAASA,EAAI,EAAG,CAC/BttD,CAAAotD,IAAA,CAAYv1C,CAAZ,CAAkBxV,CAAlB,CACArC,EAAAotD,IAAA,CAAYv1C,CAAZ,CAAkBy1C,CAAlB,CAF+B,CAAjC,CAIAttD,EAAA+H,GAAA,CAAW8P,CAAX,CAAiBxV,CAAjB,CAV+B,CAzD3B,CAsENmwB,YAAaA,QAAQ,CAACxyB,CAAD,CAAUutD,CAAV,CAAuB,CAAA,IACtCntD,CADsC,CAC/BhC,EAAS4B,CAAA2Z,WACpBrC,GAAA,CAAatX,CAAb,CACA7D,EAAA,CAAQ,IAAI0M,CAAJ,CAAW0kD,CAAX,CAAR,CAAiC,QAAQ,CAAChuD,CAAD,CAAM,CACzCa,CAAJ,CACEhC,CAAAovD,aAAA,CAAoBjuD,CAApB,CAA0Ba,CAAA0J,YAA1B,CADF,CAGE1L,CAAAu4B,aAAA,CAAoBp3B,CAApB,CAA0BS,CAA1B,CAEFI,EAAA,CAAQb,CANqC,CAA/C,CAH0C,CAtEtC,CAmFNssC,SAAUA,QAAQ,CAAC7rC,CAAD,CAAU,CAC1B,IAAI6rC,EAAW,EACf1vC,EAAA,CAAQ6D,CAAA0W,WAAR,CAA4B,QAAQ,CAAC1W,CAAD,CAAS,CACvCA,CAAAjE,SAAJ,GAAyBC,EAAzB,EACE6vC,CAAAhvC,KAAA,CAAcmD,CAAd,CAFyC,CAA7C,CAIA,OAAO6rC,EANmB,CAnFtB,CA4FNnZ,SAAUA,QAAQ,CAAC1yB,CAAD,CAAU,CAC1B,MAAOA,EAAAytD,gBAAP,EAAkCztD,CAAA0W,WAAlC,EAAwD,EAD9B,CA5FtB,CAgGNlT,OAAQA,QAAQ,CAACxD,CAAD,CAAUT,CAAV,CAAgB,CAC9B,IAAIxD,EAAWiE,CAAAjE,SACf,IAAIA,CAAJ,GAAiBC,EAAjB,EA/4C8B4d,EA+4C9B,GAAsC7d,CAAtC,CAAA,CAEAwD,CAAA,CAAO,IAAIsJ,CAAJ,CAAWtJ,CAAX,CAEP,KAASvC,IAAAA,EAAI,CAAJA,CAAOW,EAAK4B,CAAAzD,OAArB,CAAkCkB,CAAlC;AAAsCW,CAAtC,CAA0CX,CAAA,EAA1C,CAEEgD,CAAAgW,YAAA,CADYzW,CAAAu0C,CAAK92C,CAAL82C,CACZ,CANF,CAF8B,CAhG1B,CA4GN4Z,QAASA,QAAQ,CAAC1tD,CAAD,CAAUT,CAAV,CAAgB,CAC/B,GAAIS,CAAAjE,SAAJ,GAAyBC,EAAzB,CAA4C,CAC1C,IAAIoE,EAAQJ,CAAA2W,WACZxa,EAAA,CAAQ,IAAI0M,CAAJ,CAAWtJ,CAAX,CAAR,CAA0B,QAAQ,CAACu0C,CAAD,CAAO,CACvC9zC,CAAAwtD,aAAA,CAAqB1Z,CAArB,CAA4B1zC,CAA5B,CADuC,CAAzC,CAF0C,CADb,CA5G3B,CAqHNgW,KAAMA,QAAQ,CAACpW,CAAD,CAAU2tD,CAAV,CAAoB,CAChCA,CAAA,CAAWxqD,CAAA,CAAOwqD,CAAP,CAAAxZ,GAAA,CAAoB,CAApB,CAAA/wC,MAAA,EAAA,CAA+B,CAA/B,CACX,KAAIhF,EAAS4B,CAAA2Z,WACTvb,EAAJ,EACEA,CAAAu4B,aAAA,CAAoBg3B,CAApB,CAA8B3tD,CAA9B,CAEF2tD,EAAA33C,YAAA,CAAqBhW,CAArB,CANgC,CArH5B,CA8HNinB,OAAQjN,EA9HF,CAgIN4zC,OAAQA,QAAQ,CAAC5tD,CAAD,CAAU,CACxBga,EAAA,CAAaha,CAAb,CAAsB,CAAA,CAAtB,CADwB,CAhIpB,CAoIN6tD,MAAOA,QAAQ,CAAC7tD,CAAD,CAAU8tD,CAAV,CAAsB,CAAA,IAC/B1tD,EAAQJ,CADuB,CACd5B,EAAS4B,CAAA2Z,WAC9Bm0C,EAAA,CAAa,IAAIjlD,CAAJ,CAAWilD,CAAX,CAEb,KAJmC,IAI1B9wD,EAAI,CAJsB,CAInBW,EAAKmwD,CAAAhyD,OAArB,CAAwCkB,CAAxC,CAA4CW,CAA5C,CAAgDX,CAAA,EAAhD,CAAqD,CACnD,IAAIuC,EAAOuuD,CAAA,CAAW9wD,CAAX,CACXoB,EAAAovD,aAAA,CAAoBjuD,CAApB,CAA0Ba,CAAA0J,YAA1B,CACA1J,EAAA,CAAQb,CAH2C,CAJlB,CApI/B,CA+INoqB,SAAUxQ,EA/IJ,CAgJNke,YAAate,EAhJP,CAkJNg1C,YAAaA,QAAQ,CAAC/tD,CAAD,CAAU8Y,CAAV,CAAoBk1C,CAApB,CAA+B,CAC9Cl1C,CAAJ,EACE3c,CAAA,CAAQ2c,CAAAhZ,MAAA,CAAe,GAAf,CAAR,CAA6B,QAAQ,CAAC4pB,CAAD,CAAW,CAC9C,IAAIukC;AAAiBD,CACjBrvD,EAAA,CAAYsvD,CAAZ,CAAJ,GACEA,CADF,CACmB,CAACp1C,EAAA,CAAe7Y,CAAf,CAAwB0pB,CAAxB,CADpB,CAGA,EAACukC,CAAA,CAAiB90C,EAAjB,CAAkCJ,EAAnC,EAAsD/Y,CAAtD,CAA+D0pB,CAA/D,CAL8C,CAAhD,CAFgD,CAlJ9C,CA8JNtrB,OAAQA,QAAQ,CAAC4B,CAAD,CAAU,CAExB,MAAO,CADH5B,CACG,CADM4B,CAAA2Z,WACN,GA78CuBC,EA68CvB,GAAUxb,CAAArC,SAAV,CAA4DqC,CAA5D,CAAqE,IAFpD,CA9JpB,CAmKNu4C,KAAMA,QAAQ,CAAC32C,CAAD,CAAU,CACtB,MAAOA,EAAAkuD,mBADe,CAnKlB,CAuKNvuD,KAAMA,QAAQ,CAACK,CAAD,CAAU8Y,CAAV,CAAoB,CAChC,MAAI9Y,EAAAmuD,qBAAJ,CACSnuD,CAAAmuD,qBAAA,CAA6Br1C,CAA7B,CADT,CAGS,EAJuB,CAvK5B,CA+KN1V,MAAOgU,EA/KD,CAiLNxO,eAAgBA,QAAQ,CAAC5I,CAAD,CAAU+a,CAAV,CAAiBqzC,CAAjB,CAAkC,CAAA,IAEpDC,CAFoD,CAE1BC,CAF0B,CAGpDzX,EAAY97B,CAAAlD,KAAZg/B,EAA0B97B,CAH0B,CAIpDhD,EAAeC,EAAA,CAAmBhY,CAAnB,CAInB,IAFImb,CAEJ,EAHI5S,CAGJ,CAHawP,CAGb,EAH6BA,CAAAxP,OAG7B,GAFyBA,CAAA,CAAOsuC,CAAP,CAEzB,CAEEwX,CAmBA,CAnBa,CACXnkB,eAAgBA,QAAQ,EAAG,CAAE,IAAAhvB,iBAAA,CAAwB,CAAA,CAA1B,CADhB,CAEXF,mBAAoBA,QAAQ,EAAG,CAAE,MAAiC,CAAA,CAAjC,GAAO,IAAAE,iBAAT,CAFpB,CAGXK,yBAA0BA,QAAQ,EAAG,CAAE,IAAAF,4BAAA;AAAmC,CAAA,CAArC,CAH1B,CAIXK,8BAA+BA,QAAQ,EAAG,CAAE,MAA4C,CAAA,CAA5C,GAAO,IAAAL,4BAAT,CAJ/B,CAKXI,gBAAiBld,CALN,CAMXsZ,KAAMg/B,CANK,CAOX9M,OAAQ/pC,CAPG,CAmBb,CARI+a,CAAAlD,KAQJ,GAPEw2C,CAOF,CAPe5wD,CAAA,CAAO4wD,CAAP,CAAmBtzC,CAAnB,CAOf,EAHAwzC,CAGA,CAHejtD,EAAA,CAAY6Z,CAAZ,CAGf,CAFAmzC,CAEA,CAFcF,CAAA,CAAkB,CAACC,CAAD,CAAAtsD,OAAA,CAAoBqsD,CAApB,CAAlB,CAAyD,CAACC,CAAD,CAEvE,CAAAlyD,CAAA,CAAQoyD,CAAR,CAAsB,QAAQ,CAAClsD,CAAD,CAAK,CAC5BgsD,CAAA3yC,8BAAA,EAAL,EACErZ,CAAAG,MAAA,CAASxC,CAAT,CAAkBsuD,CAAlB,CAF+B,CAAnC,CA7BsD,CAjLpD,CAAR,CAqNG,QAAQ,CAACjsD,CAAD,CAAK6C,CAAL,CAAU,CAInB2D,CAAAvK,UAAA,CAAiB4G,CAAjB,CAAA,CAAyB,QAAQ,CAACqmC,CAAD,CAAOC,CAAP,CAAagjB,CAAb,CAAmB,CAGlD,IAFA,IAAIrxD,CAAJ,CAEQH,EAAI,CAFZ,CAEeW,EAAK,IAAA7B,OAApB,CAAiCkB,CAAjC,CAAqCW,CAArC,CAAyCX,CAAA,EAAzC,CACM2B,CAAA,CAAYxB,CAAZ,CAAJ,EACEA,CACA,CADQkF,CAAA,CAAG,IAAA,CAAKrF,CAAL,CAAH,CAAYuuC,CAAZ,CAAkBC,CAAlB,CAAwBgjB,CAAxB,CACR,CAAI5vD,CAAA,CAAUzB,CAAV,CAAJ,GAEEA,CAFF,CAEUgG,CAAA,CAAOhG,CAAP,CAFV,CAFF,EAOEga,EAAA,CAAeha,CAAf,CAAsBkF,CAAA,CAAG,IAAA,CAAKrF,CAAL,CAAH,CAAYuuC,CAAZ,CAAkBC,CAAlB,CAAwBgjB,CAAxB,CAAtB,CAGJ,OAAO5vD,EAAA,CAAUzB,CAAV,CAAA,CAAmBA,CAAnB,CAA2B,IAdgB,CAkBpD0L,EAAAvK,UAAA6D,KAAA,CAAwB0G,CAAAvK,UAAAyJ,GACxBc,EAAAvK,UAAAmwD,OAAA,CAA0B5lD,CAAAvK,UAAA8uD,IAvBP,CArNrB,CA2RArxC,GAAAzd,UAAA,CAAoB,CAMlB4d,IAAKA,QAAQ,CAAC5f,CAAD;AAAMa,CAAN,CAAa,CACxB,IAAA,CAAKye,EAAA,CAAQtf,CAAR,CAAa,IAAAc,QAAb,CAAL,CAAA,CAAmCD,CADX,CANR,CAclBiK,IAAKA,QAAQ,CAAC9K,CAAD,CAAM,CACjB,MAAO,KAAA,CAAKsf,EAAA,CAAQtf,CAAR,CAAa,IAAAc,QAAb,CAAL,CADU,CAdD,CAsBlB6pB,OAAQA,QAAQ,CAAC3qB,CAAD,CAAM,CACpB,IAAIa,EAAQ,IAAA,CAAKb,CAAL,CAAWsf,EAAA,CAAQtf,CAAR,CAAa,IAAAc,QAAb,CAAX,CACZ,QAAO,IAAA,CAAKd,CAAL,CACP,OAAOa,EAHa,CAtBJ,CA0FpB,KAAIof,GAAU,oCAAd,CACII,GAAe,GADnB,CAEIC,GAAS,sBAFb,CAGIN,GAAiB,kCAHrB,CAIInS,GAAkBzO,CAAA,CAAO,WAAP,CAswBtBuK,GAAAyoD,WAAA,CAA4BlyC,EA6Q5B,KAAImyC,GAAiBjzD,CAAA,CAAO,UAAP,CAArB,CAeIoW,GAAmB,CAAC,UAAD,CAAa,QAAQ,CAAChM,CAAD,CAAW,CAGrD,IAAA8oD,YAAA,CAAmB,EAkCnB,KAAAr1B,SAAA,CAAgBC,QAAQ,CAACt0B,CAAD,CAAOgF,CAAP,CAAgB,CACtC,IAAI5N,EAAM4I,CAAN5I,CAAa,YACjB,IAAI4I,CAAJ,EAA8B,GAA9B,EAAYA,CAAA1D,OAAA,CAAY,CAAZ,CAAZ,CAAmC,KAAMmtD,GAAA,CAAe,SAAf,CACoBzpD,CADpB,CAAN,CAEnC,IAAA0pD,YAAA,CAAiB1pD,CAAAwoB,OAAA,CAAY,CAAZ,CAAjB,CAAA,CAAmCpxB,CACnCwJ;CAAAoE,QAAA,CAAiB5N,CAAjB,CAAsB4N,CAAtB,CALsC,CAsBxC,KAAA2kD,gBAAA,CAAuBC,QAAQ,CAACl1B,CAAD,CAAa,CAClB,CAAxB,GAAGh8B,SAAA9B,OAAH,GACE,IAAAizD,kBADF,CAC4Bn1B,CAAD,WAAuB54B,OAAvB,CAAiC44B,CAAjC,CAA8C,IADzE,CAGA,OAAO,KAAAm1B,kBAJmC,CAO5C,KAAAzxC,KAAA,CAAY,CAAC,KAAD,CAAQ,iBAAR,CAA2B,YAA3B,CAAyC,QAAQ,CAACzJ,CAAD,CAAMoB,CAAN,CAAuBxB,CAAvB,CAAmC,CAI9Fu7C,QAASA,EAAsB,CAAC3sD,CAAD,CAAK,CAAA,IAC9B4sD,CAD8B,CACpB7pC,EAAQvR,CAAAuR,MAAA,EACtBA,EAAA2X,QAAAmyB,WAAA,CAA2BC,QAA6B,EAAG,CACzDF,CAAA,EAAYA,CAAA,EAD6C,CAI3Dx7C,EAAAi7B,aAAA,CAAwB0gB,QAA4B,EAAG,CACrDH,CAAA,CAAW5sD,CAAA,CAAGgtD,QAAgC,EAAG,CAC/CjqC,CAAA+Y,QAAA,EAD+C,CAAtC,CAD0C,CAAvD,CAMA,OAAO/Y,EAAA2X,QAZ2B,CAepCuyB,QAASA,EAAqB,CAACtvD,CAAD,CAAUoqD,CAAV,CAAmB,CAAA,IAC3C7yB,EAAQ,EADmC,CAC/BE,EAAW,EADoB,CAG3C83B,EAAaxlD,EAAA,EACjB5N,EAAA,CAAQ2D,CAACE,CAAAN,KAAA,CAAa,OAAb,CAADI,EAA0B,EAA1BA,OAAA,CAAoC,KAApC,CAAR,CAAoD,QAAQ,CAAC4pB,CAAD,CAAY,CACtE6lC,CAAA,CAAW7lC,CAAX,CAAA,CAAwB,CAAA,CAD8C,CAAxE,CAIAvtB,EAAA,CAAQiuD,CAAR,CAAiB,QAAQ,CAACtuB,CAAD,CAASpS,CAAT,CAAoB,CAC3C,IAAIkgC,EAAW2F,CAAA,CAAW7lC,CAAX,CAMA,EAAA,CAAf,GAAIoS,CAAJ,EAAwB8tB,CAAxB,CACEnyB,CAAA56B,KAAA,CAAc6sB,CAAd,CADF;AAEsB,CAAA,CAFtB,GAEWoS,CAFX,EAE+B8tB,CAF/B,EAGEryB,CAAA16B,KAAA,CAAW6sB,CAAX,CAVyC,CAA7C,CAcA,OAA0C,EAA1C,CAAQ6N,CAAAz7B,OAAR,CAAuB27B,CAAA37B,OAAvB,EACE,CAACy7B,CAAAz7B,OAAA,CAAey7B,CAAf,CAAuB,IAAxB,CAA8BE,CAAA37B,OAAA,CAAkB27B,CAAlB,CAA6B,IAA3D,CAvB6C,CA0BjD+3B,QAASA,EAAuB,CAAClxC,CAAD,CAAQ8rC,CAAR,CAAiBqF,CAAjB,CAAqB,CACnD,IADmD,IAC1CzyD,EAAE,CADwC,CACrCW,EAAKysD,CAAAtuD,OAAnB,CAAmCkB,CAAnC,CAAuCW,CAAvC,CAA2C,EAAEX,CAA7C,CAEEshB,CAAA,CADgB8rC,CAAA1gC,CAAQ1sB,CAAR0sB,CAChB,CAAA,CAAmB+lC,CAH8B,CAOrDC,QAASA,EAAY,EAAG,CAEjBC,CAAL,GACEA,CACA,CADe97C,CAAAuR,MAAA,EACf,CAAAnQ,CAAA,CAAgB,QAAQ,EAAG,CACzB06C,CAAAxxB,QAAA,EACAwxB,EAAA,CAAe,IAFU,CAA3B,CAFF,CAOA,OAAOA,EAAA5yB,QATe,CAYxB6yB,QAASA,EAAW,CAAC5vD,CAAD,CAAU8lB,CAAV,CAAmB,CACrC,GAAInf,EAAA9H,SAAA,CAAiBinB,CAAjB,CAAJ,CAA+B,CAC7B,IAAI+pC,EAASpyD,CAAA,CAAOqoB,CAAAgqC,KAAP,EAAuB,EAAvB,CAA2BhqC,CAAAiqC,GAA3B,EAAyC,EAAzC,CACb/vD,EAAAqsD,IAAA,CAAYwD,CAAZ,CAF6B,CADM,CA9DvC,IAAIF,CAsFJ,OAAO,CACLK,QAAUA,QAAQ,CAAChwD,CAAD,CAAU8vD,CAAV,CAAgBC,CAAhB,CAAoB,CACpCH,CAAA,CAAY5vD,CAAZ,CAAqB,CAAE8vD,KAAMA,CAAR,CAAcC,GAAIA,CAAlB,CAArB,CACA,OAAOL,EAAA,EAF6B,CADjC,CAsBLO,MAAQA,QAAQ,CAACjwD,CAAD,CAAU5B,CAAV,CAAkByvD,CAAlB,CAAyB/nC,CAAzB,CAAkC,CAChD8pC,CAAA,CAAY5vD,CAAZ,CAAqB8lB,CAArB,CACA+nC,EAAA,CAAQA,CAAAA,MAAA,CAAY7tD,CAAZ,CAAR,CACQ5B,CAAAsvD,QAAA,CAAe1tD,CAAf,CACR,OAAO0vD,EAAA,EAJyC,CAtB7C,CAwCLQ,MAAQA,QAAQ,CAAClwD,CAAD,CAAU8lB,CAAV,CAAmB,CACjC9lB,CAAAinB,OAAA,EACA,OAAOyoC,EAAA,EAF0B,CAxC9B,CA+DLS,KAAOA,QAAQ,CAACnwD,CAAD,CAAU5B,CAAV,CAAkByvD,CAAlB,CAAyB/nC,CAAzB,CAAkC,CAG/C,MAAO,KAAAmqC,MAAA,CAAWjwD,CAAX;AAAoB5B,CAApB,CAA4ByvD,CAA5B,CAAmC/nC,CAAnC,CAHwC,CA/D5C,CAkFL6D,SAAWA,QAAQ,CAAC3pB,CAAD,CAAU0pB,CAAV,CAAqB5D,CAArB,CAA8B,CAC/C,MAAO,KAAAm/B,SAAA,CAAcjlD,CAAd,CAAuB0pB,CAAvB,CAAkC,EAAlC,CAAsC5D,CAAtC,CADwC,CAlF5C,CAsFLsqC,sBAAwBA,QAAQ,CAACpwD,CAAD,CAAU0pB,CAAV,CAAqB5D,CAArB,CAA8B,CAC5D9lB,CAAA,CAAUmD,CAAA,CAAOnD,CAAP,CACV0pB,EAAA,CAAaztB,CAAA,CAASytB,CAAT,CAAD,CAEMA,CAFN,CACOxtB,CAAA,CAAQwtB,CAAR,CAAA,CAAqBA,CAAArlB,KAAA,CAAe,GAAf,CAArB,CAA2C,EAE9DlI,EAAA,CAAQ6D,CAAR,CAAiB,QAAS,CAACA,CAAD,CAAU,CAClCmZ,EAAA,CAAenZ,CAAf,CAAwB0pB,CAAxB,CADkC,CAApC,CAGAkmC,EAAA,CAAY5vD,CAAZ,CAAqB8lB,CAArB,CACA,OAAO4pC,EAAA,EATqD,CAtFzD,CA+GLr4B,YAAcA,QAAQ,CAACr3B,CAAD,CAAU0pB,CAAV,CAAqB5D,CAArB,CAA8B,CAClD,MAAO,KAAAm/B,SAAA,CAAcjlD,CAAd,CAAuB,EAAvB,CAA2B0pB,CAA3B,CAAsC5D,CAAtC,CAD2C,CA/G/C,CAmHLuqC,yBAA2BA,QAAQ,CAACrwD,CAAD,CAAU0pB,CAAV,CAAqB5D,CAArB,CAA8B,CAC/D9lB,CAAA,CAAUmD,CAAA,CAAOnD,CAAP,CACV0pB,EAAA,CAAaztB,CAAA,CAASytB,CAAT,CAAD,CAEMA,CAFN,CACOxtB,CAAA,CAAQwtB,CAAR,CAAA,CAAqBA,CAAArlB,KAAA,CAAe,GAAf,CAArB,CAA2C,EAE9DlI,EAAA,CAAQ6D,CAAR,CAAiB,QAAS,CAACA,CAAD,CAAU,CAClC+Y,EAAA,CAAkB/Y,CAAlB,CAA2B0pB,CAA3B,CADkC,CAApC,CAGAkmC,EAAA,CAAY5vD,CAAZ,CAAqB8lB,CAArB,CACA,OAAO4pC,EAAA,EATwD,CAnH5D,CA6ILzK,SAAWA,QAAQ,CAACjlD,CAAD,CAAUswD,CAAV,CAAerpC,CAAf,CAAuBnB,CAAvB,CAAgC,CACjD,IAAI1jB,EAAO,IAAX,CAEImuD,EAAe,CAAA,CACnBvwD,EAAA,CAAUmD,CAAA,CAAOnD,CAAP,CAEV,KAAIse,EAAQte,CAAAuG,KAAA,CAJMiqD,kBAIN,CACPlyC,EAAL,CAMWwH,CANX,EAMsBxH,CAAAwH,QANtB,GAOExH,CAAAwH,QAPF,CAOkBnf,EAAAlJ,OAAA,CAAe6gB,CAAAwH,QAAf,EAAgC,EAAhC,CAAoCA,CAApC,CAPlB;CACExH,CAIA,CAJQ,CACN8rC,QAAS,EADH,CAENtkC,QAAUA,CAFJ,CAIR,CAAAyqC,CAAA,CAAe,CAAA,CALjB,CAUInG,EAAAA,CAAU9rC,CAAA8rC,QAEdkG,EAAA,CAAMp0D,CAAA,CAAQo0D,CAAR,CAAA,CAAeA,CAAf,CAAqBA,CAAAxwD,MAAA,CAAU,GAAV,CAC3BmnB,EAAA,CAAS/qB,CAAA,CAAQ+qB,CAAR,CAAA,CAAkBA,CAAlB,CAA2BA,CAAAnnB,MAAA,CAAa,GAAb,CACpC0vD,EAAA,CAAwBpF,CAAxB,CAAiCkG,CAAjC,CAAsC,CAAA,CAAtC,CACAd,EAAA,CAAwBpF,CAAxB,CAAiCnjC,CAAjC,CAAyC,CAAA,CAAzC,CAEIspC,EAAJ,GACEjyC,CAAAye,QAgBA,CAhBgBiyB,CAAA,CAAuB,QAAQ,CAACrxB,CAAD,CAAO,CACpD,IAAIrf,EAAQte,CAAAuG,KAAA,CAxBEiqD,kBAwBF,CACZxwD,EAAAmsD,WAAA,CAzBcqE,kBAyBd,CAKA,IAAIlyC,CAAJ,CAAW,CACT,IAAI8rC,EAAUkF,CAAA,CAAsBtvD,CAAtB,CAA+Bse,CAAA8rC,QAA/B,CACVA,EAAJ,EACEhoD,CAAAquD,sBAAA,CAA2BzwD,CAA3B,CAAoCoqD,CAAA,CAAQ,CAAR,CAApC,CAAgDA,CAAA,CAAQ,CAAR,CAAhD,CAA4D9rC,CAAAwH,QAA5D,CAHO,CAOX6X,CAAA,EAdoD,CAAtC,CAgBhB,CAAA39B,CAAAuG,KAAA,CAvCgBiqD,kBAuChB,CAA0BlyC,CAA1B,CAjBF,CAoBA,OAAOA,EAAAye,QA5C0C,CA7I9C,CA4LL0zB,sBAAwBA,QAAQ,CAACzwD,CAAD,CAAUswD,CAAV,CAAerpC,CAAf,CAAuBnB,CAAvB,CAAgC,CAC9DwqC,CAAA,EAAO,IAAAF,sBAAA,CAA2BpwD,CAA3B,CAAoCswD,CAApC,CACPrpC,EAAA,EAAU,IAAAopC,yBAAA,CAA8BrwD,CAA9B,CAAuCinB,CAAvC,CACV2oC,EAAA,CAAY5vD,CAAZ,CAAqB8lB,CAArB,CACA,OAAO4pC,EAAA,EAJuD,CA5L3D,CAmMLnmC,QAAUhrB,CAnML,CAoMLinB,OAASjnB,CApMJ,CAxFuF,CAApF,CAlEyC,CAAhC,CAfvB,CAg3DIupB,GAAiBpsB,CAAA,CAAO,UAAP,CAQrB0Q;EAAAqQ,QAAA,CAA2B,CAAC,UAAD,CAAa,uBAAb,CA8tD3B,KAAIoc,GAAgB,0BAApB,CAikDI8I,GAAqBjmC,CAAA,CAAO,cAAP,CAjkDzB,CA4pEIg1D,GAAa,iCA5pEjB,CA6pEIxqB,GAAgB,CAAC,KAAQ,EAAT,CAAa,MAAS,GAAtB,CAA2B,IAAO,EAAlC,CA7pEpB,CA8pEIqB,GAAkB7rC,CAAA,CAAO,WAAP,CA9pEtB,CA28EIi1D,GAAoB,CAMtBzpB,QAAS,CAAA,CANa,CAYtBuD,UAAW,CAAA,CAZW,CA0BtBjB,OAAQf,EAAA,CAAe,UAAf,CA1Bc,CA0CtB9lB,IAAKA,QAAQ,CAACA,CAAD,CAAM,CACjB,GAAIhkB,CAAA,CAAYgkB,CAAZ,CAAJ,CACE,MAAO,KAAA+kB,MAELzmC,EAAAA,CAAQyvD,EAAAv6C,KAAA,CAAgBwM,CAAhB,CACR1hB,EAAA,CAAM,CAAN,CAAJ,EAAc,IAAAqI,KAAA,CAAUzF,kBAAA,CAAmB5C,CAAA,CAAM,CAAN,CAAnB,CAAV,CACd,EAAIA,CAAA,CAAM,CAAN,CAAJ,EAAgBA,CAAA,CAAM,CAAN,CAAhB,GAA0B,IAAAwlC,OAAA,CAAYxlC,CAAA,CAAM,CAAN,CAAZ,EAAwB,EAAxB,CAC1B,KAAA6f,KAAA,CAAU7f,CAAA,CAAM,CAAN,CAAV,EAAsB,EAAtB,CAEA,OAAO,KATU,CA1CG,CAiEtBw/B,SAAUgI,EAAA,CAAe,YAAf,CAjEY,CA8EtB5uB,KAAM4uB,EAAA,CAAe,QAAf,CA9EgB,CA2FtBxC,KAAMwC,EAAA,CAAe,QAAf,CA3FgB,CA8GtBn/B,KAAMq/B,EAAA,CAAqB,QAArB,CAA+B,QAAQ,CAACr/B,CAAD,CAAO,CAClDA,CAAA,CAAgB,IAAT;AAAAA,CAAA,CAAgBA,CAAAtK,SAAA,EAAhB,CAAkC,EACzC,OAAyB,GAAlB,EAAAsK,CAAA9H,OAAA,CAAY,CAAZ,CAAA,CAAwB8H,CAAxB,CAA+B,GAA/B,CAAqCA,CAFM,CAA9C,CA9GgB,CAiKtBm9B,OAAQA,QAAQ,CAACA,CAAD,CAASmqB,CAAT,CAAqB,CACnC,OAAQhzD,SAAA9B,OAAR,EACE,KAAK,CAAL,CACE,MAAO,KAAA0qC,SACT,MAAK,CAAL,CACE,GAAIvqC,CAAA,CAASwqC,CAAT,CAAJ,EAAwB3nC,CAAA,CAAS2nC,CAAT,CAAxB,CACEA,CACA,CADSA,CAAAznC,SAAA,EACT,CAAA,IAAAwnC,SAAA,CAAgB1iC,EAAA,CAAc2iC,CAAd,CAFlB,KAGO,IAAI5nC,CAAA,CAAS4nC,CAAT,CAAJ,CACLA,CAMA,CANSlmC,EAAA,CAAKkmC,CAAL,CAAa,EAAb,CAMT,CAJAtqC,CAAA,CAAQsqC,CAAR,CAAgB,QAAQ,CAACtpC,CAAD,CAAQb,CAAR,CAAa,CACtB,IAAb,EAAIa,CAAJ,EAAmB,OAAOspC,CAAA,CAAOnqC,CAAP,CADS,CAArC,CAIA,CAAA,IAAAkqC,SAAA,CAAgBC,CAPX,KASL,MAAMc,GAAA,CAAgB,UAAhB,CAAN,CAGF,KACF,SACM5oC,CAAA,CAAYiyD,CAAZ,CAAJ,EAA8C,IAA9C,GAA+BA,CAA/B,CACE,OAAO,IAAApqB,SAAA,CAAcC,CAAd,CADT,CAGE,IAAAD,SAAA,CAAcC,CAAd,CAHF,CAG0BmqB,CAxB9B,CA4BA,IAAAppB,UAAA,EACA,OAAO,KA9B4B,CAjKf,CAgNtB1mB,KAAM6nB,EAAA,CAAqB,QAArB,CAA+B,QAAQ,CAAC7nB,CAAD,CAAO,CAClD,MAAgB,KAAT,GAAAA,CAAA,CAAgBA,CAAA9hB,SAAA,EAAhB,CAAkC,EADS,CAA9C,CAhNgB,CA4NtB2E,QAASA,QAAQ,EAAG,CAClB,IAAA8mC,UAAA,CAAiB,CAAA,CACjB,OAAO,KAFW,CA5NE,CAkOxBtuC;CAAA,CAAQ,CAACqsC,EAAD,CAA6BN,EAA7B,CAAkDlB,EAAlD,CAAR,CAA6E,QAAS,CAAC6pB,CAAD,CAAW,CAC/FA,CAAAvyD,UAAA,CAAqBT,MAAAuD,OAAA,CAAcuvD,EAAd,CAqBrBE,EAAAvyD,UAAAkkB,MAAA,CAA2BsuC,QAAQ,CAACtuC,CAAD,CAAQ,CACzC,GAAK1mB,CAAA8B,SAAA9B,OAAL,CACE,MAAO,KAAAutC,QAET,IAAIwnB,CAAJ,GAAiB7pB,EAAjB,EAAsCE,CAAA,IAAAA,QAAtC,CACE,KAAMK,GAAA,CAAgB,SAAhB,CAAN,CAMF,IAAA8B,QAAA,CAAe1qC,CAAA,CAAY6jB,CAAZ,CAAA,CAAqB,IAArB,CAA4BA,CAE3C,OAAO,KAbkC,CAtBoD,CAAjG,CAugBA,KAAImpB,GAAejwC,CAAA,CAAO,QAAP,CAAnB,CA8DIq1D,GAAO9jB,QAAA3uC,UAAA7B,KA9DX,CA+DIu0D,GAAQ/jB,QAAA3uC,UAAAkE,MA/DZ,CAgEIyuD,GAAOhkB,QAAA3uC,UAAA6D,KAhEX,CAiFI+uD,GAAYnnD,EAAA,EAChB5N,EAAA,CAAQ,CACN,OAAQg1D,QAAQ,EAAG,CAAE,MAAO,KAAT,CADb,CAEN,OAAQC,QAAQ,EAAG,CAAE,MAAO,CAAA,CAAT,CAFb,CAGN,QAASC,QAAQ,EAAG,CAAE,MAAO,CAAA,CAAT,CAHd,CAIN,UAAa51D,QAAQ,EAAG,EAJlB,CAAR,CAKG,QAAQ,CAAC61D,CAAD,CAAiBpsD,CAAjB,CAAuB,CAChCosD,CAAAlmD,SAAA,CAA0BkmD,CAAAvgC,QAA1B,CAAmDugC,CAAApkB,aAAnD,CAAiF,CAAA,CACjFgkB,GAAA,CAAUhsD,CAAV,CAAA,CAAkBosD,CAFc,CALlC,CAWAJ,GAAA,CAAU,MAAV,CAAA;AAAoB,QAAQ,CAAC9uD,CAAD,CAAO,CAAE,MAAOA,EAAT,CACnC8uD,GAAA,CAAU,MAAV,CAAAhkB,aAAA,CAAiC,CAAA,CAIjC,KAAIqkB,GAAY9zD,CAAA,CAAOsM,EAAA,EAAP,CAAoB,CAChC,IAAIynD,QAAQ,CAACpvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAC7B3kB,CAAA,CAAEA,CAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAiBoS,EAAA,CAAEA,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CACrB,OAAIhgB,EAAA,CAAUyN,CAAV,CAAJ,CACMzN,CAAA,CAAUoyB,CAAV,CAAJ,CACS3kB,CADT,CACa2kB,CADb,CAGO3kB,CAJT,CAMOzN,CAAA,CAAUoyB,CAAV,CAAA,CAAaA,CAAb,CAAev1B,CARO,CADC,CAUhC,IAAIg2D,QAAQ,CAACrvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CACzB3kB,CAAA,CAAEA,CAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAiBoS,EAAA,CAAEA,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CACrB,QAAQhgB,CAAA,CAAUyN,CAAV,CAAA,CAAaA,CAAb,CAAe,CAAvB,GAA2BzN,CAAA,CAAUoyB,CAAV,CAAA,CAAaA,CAAb,CAAe,CAA1C,CAFyB,CAVC,CAchC,IAAI0gC,QAAQ,CAACtvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,CAAuBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAxB,CAdC,CAehC,IAAI+yC,QAAQ,CAACvvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,CAAuBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAxB,CAfC,CAgBhC,IAAIgzC,QAAQ,CAACxvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,CAAuBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAxB,CAhBC,CAiBhC,MAAMizC,QAAQ,CAACzvD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAkB2kB,CAAlB,CAAoB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,GAAyBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAA1B,CAjBF,CAkBhC,MAAMkzC,QAAQ,CAAC1vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAkB2kB,CAAlB,CAAoB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,GAAyBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAA1B,CAlBF,CAmBhC,KAAKmzC,QAAQ,CAAC3vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CAnBA,CAoBhC,KAAKozC,QAAQ,CAAC5vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF;AAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CApBA,CAqBhC,IAAIqzC,QAAQ,CAAC7vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,CAAuBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAxB,CArBC,CAsBhC,IAAIszC,QAAQ,CAAC9vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,CAAuBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAxB,CAtBC,CAuBhC,KAAKuzC,QAAQ,CAAC/vD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CAvBA,CAwBhC,KAAKwzC,QAAQ,CAAChwD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CAxBA,CAyBhC,KAAKyzC,QAAQ,CAACjwD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CAzBA,CA0BhC,KAAK0zC,QAAQ,CAAClwD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB2kB,CAAjB,CAAmB,CAAC,MAAO3kB,EAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAP,EAAwBoS,CAAA,CAAE5uB,CAAF,CAAQwc,CAAR,CAAzB,CA1BA,CA2BhC,IAAI2zC,QAAQ,CAACnwD,CAAD,CAAOwc,CAAP,CAAevS,CAAf,CAAiB,CAAC,MAAO,CAACA,CAAA,CAAEjK,CAAF,CAAQwc,CAAR,CAAT,CA3BG,CA8BhC,IAAI,CAAA,CA9B4B,CA+BhC,IAAI,CAAA,CA/B4B,CAApB,CAAhB,CAiCI4zC,GAAS,CAAC,EAAI,IAAL,CAAW,EAAI,IAAf,CAAqB,EAAI,IAAzB,CAA+B,EAAI,IAAnC,CAAyC,EAAI,IAA7C,CAAmD,IAAI,GAAvD,CAA4D,IAAI,GAAhE,CAjCb,CA0CIljB,GAAQA,QAAS,CAACxpB,CAAD,CAAU,CAC7B,IAAAA,QAAA,CAAeA,CADc,CAI/BwpB,GAAAhxC,UAAA,CAAkB,CAChB6K,YAAammC,EADG,CAGhBmjB,IAAKA,QAAS,CAACz9B,CAAD,CAAO,CACnB,IAAAA,KAAA,CAAYA,CACZ,KAAA50B,MAAA,CAAa,CACb,KAAA6gC,GAAA,CAAUxlC,CAGV;IAFA,IAAAi3D,OAEA,CAFc,EAEd,CAAO,IAAAtyD,MAAP,CAAoB,IAAA40B,KAAAl5B,OAApB,CAAA,CAEE,GADA,IAAAmlC,GACI,CADM,IAAAjM,KAAAxzB,OAAA,CAAiB,IAAApB,MAAjB,CACN,CAAA,IAAAuyD,GAAA,CAAQ,KAAR,CAAJ,CACE,IAAAC,WAAA,CAAgB,IAAA3xB,GAAhB,CADF,KAEO,IAAI,IAAAniC,SAAA,CAAc,IAAAmiC,GAAd,CAAJ,EAA8B,IAAA0xB,GAAA,CAAQ,GAAR,CAA9B,EAA8C,IAAA7zD,SAAA,CAAc,IAAA+zD,KAAA,EAAd,CAA9C,CACL,IAAAC,WAAA,EADK,KAEA,IAAI,IAAAC,QAAA,CAAa,IAAA9xB,GAAb,CAAJ,CACL,IAAA+xB,UAAA,EADK,KAEA,IAAI,IAAAL,GAAA,CAAQ,aAAR,CAAJ,CACL,IAAAD,OAAA71D,KAAA,CAAiB,CACfuD,MAAO,IAAAA,MADQ,CAEf40B,KAAM,IAAAiM,GAFS,CAAjB,CAIA,CAAA,IAAA7gC,MAAA,EALK,KAMA,IAAI,IAAA6yD,aAAA,CAAkB,IAAAhyB,GAAlB,CAAJ,CACL,IAAA7gC,MAAA,EADK,KAEA,CACD8yD,CAAAA,CAAM,IAAAjyB,GAANiyB,CAAgB,IAAAL,KAAA,EACpB,KAAIM,EAAMD,CAANC,CAAY,IAAAN,KAAA,CAAU,CAAV,CAAhB,CACIxwD,EAAKkvD,EAAA,CAAU,IAAAtwB,GAAV,CADT,CAEImyB,EAAM7B,EAAA,CAAU2B,CAAV,CAFV,CAGIG,EAAM9B,EAAA,CAAU4B,CAAV,CACNE,EAAJ,EACE,IAAAX,OAAA71D,KAAA,CAAiB,CAACuD,MAAO,IAAAA,MAAR;AAAoB40B,KAAMm+B,CAA1B,CAA+B9wD,GAAIgxD,CAAnC,CAAjB,CACA,CAAA,IAAAjzD,MAAA,EAAc,CAFhB,EAGWgzD,CAAJ,EACL,IAAAV,OAAA71D,KAAA,CAAiB,CAACuD,MAAO,IAAAA,MAAR,CAAoB40B,KAAMk+B,CAA1B,CAA+B7wD,GAAI+wD,CAAnC,CAAjB,CACA,CAAA,IAAAhzD,MAAA,EAAc,CAFT,EAGIiC,CAAJ,EACL,IAAAqwD,OAAA71D,KAAA,CAAiB,CACfuD,MAAO,IAAAA,MADQ,CAEf40B,KAAM,IAAAiM,GAFS,CAGf5+B,GAAIA,CAHW,CAAjB,CAKA,CAAA,IAAAjC,MAAA,EAAc,CANT,EAQL,IAAAkzD,WAAA,CAAgB,4BAAhB,CAA8C,IAAAlzD,MAA9C,CAA0D,IAAAA,MAA1D,CAAuE,CAAvE,CApBG,CAwBT,MAAO,KAAAsyD,OA9CY,CAHL,CAoDhBC,GAAIA,QAAQ,CAACY,CAAD,CAAQ,CAClB,MAAmC,EAAnC,GAAOA,CAAAlzD,QAAA,CAAc,IAAA4gC,GAAd,CADW,CApDJ,CAwDhB4xB,KAAMA,QAAQ,CAAC71D,CAAD,CAAI,CACZqoC,CAAAA,CAAMroC,CAANqoC,EAAW,CACf,OAAQ,KAAAjlC,MAAD,CAAcilC,CAAd,CAAoB,IAAArQ,KAAAl5B,OAApB,CAAwC,IAAAk5B,KAAAxzB,OAAA,CAAiB,IAAApB,MAAjB,CAA8BilC,CAA9B,CAAxC,CAA6E,CAAA,CAFpE,CAxDF,CA6DhBvmC,SAAUA,QAAQ,CAACmiC,CAAD,CAAK,CACrB,MAAQ,GAAR,EAAeA,CAAf,EAA2B,GAA3B,EAAqBA,CADA,CA7DP,CAiEhBgyB,aAAcA,QAAQ,CAAChyB,CAAD,CAAK,CAEzB,MAAe,GAAf,GAAQA,CAAR,EAA6B,IAA7B,GAAsBA,CAAtB,EAA4C,IAA5C;AAAqCA,CAArC,EACe,IADf,GACQA,CADR,EAC8B,IAD9B,GACuBA,CADvB,EAC6C,QAD7C,GACsCA,CAHb,CAjEX,CAuEhB8xB,QAASA,QAAQ,CAAC9xB,CAAD,CAAK,CACpB,MAAQ,GAAR,EAAeA,CAAf,EAA2B,GAA3B,EAAqBA,CAArB,EACQ,GADR,EACeA,CADf,EAC2B,GAD3B,EACqBA,CADrB,EAEQ,GAFR,GAEgBA,CAFhB,EAE6B,GAF7B,GAEsBA,CAHF,CAvEN,CA6EhBuyB,cAAeA,QAAQ,CAACvyB,CAAD,CAAK,CAC1B,MAAe,GAAf,GAAQA,CAAR,EAA6B,GAA7B,GAAsBA,CAAtB,EAAoC,IAAAniC,SAAA,CAAcmiC,CAAd,CADV,CA7EZ,CAiFhBqyB,WAAYA,QAAQ,CAAC1xC,CAAD,CAAQ6xC,CAAR,CAAeC,CAAf,CAAoB,CACtCA,CAAA,CAAMA,CAAN,EAAa,IAAAtzD,MACTuzD,EAAAA,CAAU/0D,CAAA,CAAU60D,CAAV,CAAA,CACJ,IADI,CACGA,CADH,CACY,GADZ,CACkB,IAAArzD,MADlB,CAC+B,IAD/B,CACsC,IAAA40B,KAAA7P,UAAA,CAAoBsuC,CAApB,CAA2BC,CAA3B,CADtC,CACwE,GADxE,CAEJ,GAFI,CAEEA,CAChB,MAAM/nB,GAAA,CAAa,QAAb,CACF/pB,CADE,CACK+xC,CADL,CACa,IAAA3+B,KADb,CAAN,CALsC,CAjFxB,CA0FhB89B,WAAYA,QAAQ,EAAG,CAGrB,IAFA,IAAI1U,EAAS,EAAb,CACIqV,EAAQ,IAAArzD,MACZ,CAAO,IAAAA,MAAP,CAAoB,IAAA40B,KAAAl5B,OAApB,CAAA,CAAsC,CACpC,IAAImlC,EAAKhhC,CAAA,CAAU,IAAA+0B,KAAAxzB,OAAA,CAAiB,IAAApB,MAAjB,CAAV,CACT,IAAU,GAAV,EAAI6gC,CAAJ,EAAiB,IAAAniC,SAAA,CAAcmiC,CAAd,CAAjB,CACEmd,CAAA,EAAUnd,CADZ,KAEO,CACL,IAAI2yB,EAAS,IAAAf,KAAA,EACb,IAAU,GAAV;AAAI5xB,CAAJ,EAAiB,IAAAuyB,cAAA,CAAmBI,CAAnB,CAAjB,CACExV,CAAA,EAAUnd,CADZ,KAEO,IAAI,IAAAuyB,cAAA,CAAmBvyB,CAAnB,CAAJ,EACH2yB,CADG,EACO,IAAA90D,SAAA,CAAc80D,CAAd,CADP,EAEiC,GAFjC,EAEHxV,CAAA58C,OAAA,CAAc48C,CAAAtiD,OAAd,CAA8B,CAA9B,CAFG,CAGLsiD,CAAA,EAAUnd,CAHL,KAIA,IAAI,CAAA,IAAAuyB,cAAA,CAAmBvyB,CAAnB,CAAJ,EACD2yB,CADC,EACU,IAAA90D,SAAA,CAAc80D,CAAd,CADV,EAEiC,GAFjC,EAEHxV,CAAA58C,OAAA,CAAc48C,CAAAtiD,OAAd,CAA8B,CAA9B,CAFG,CAKL,KALK,KAGL,KAAAw3D,WAAA,CAAgB,kBAAhB,CAXG,CAgBP,IAAAlzD,MAAA,EApBoC,CAsBtCg+C,CAAA,EAAS,CACT,KAAAsU,OAAA71D,KAAA,CAAiB,CACfuD,MAAOqzD,CADQ,CAEfz+B,KAAMopB,CAFS,CAGfhzC,SAAU,CAAA,CAHK,CAIf/I,GAAIA,QAAQ,EAAG,CAAE,MAAO+7C,EAAT,CAJA,CAAjB,CA1BqB,CA1FP,CA4HhB4U,UAAWA,QAAQ,EAAG,CAQpB,IAPA,IAAIp5B,EAAa,IAAA5E,KAAjB,CAEI8E,EAAQ,EAFZ,CAGI25B,EAAQ,IAAArzD,MAHZ,CAKIyzD,CALJ,CAKaC,CALb,CAKwBC,CALxB,CAKoC9yB,CAEpC,CAAO,IAAA7gC,MAAP,CAAoB,IAAA40B,KAAAl5B,OAApB,CAAA,CAAsC,CACpCmlC,CAAA,CAAK,IAAAjM,KAAAxzB,OAAA,CAAiB,IAAApB,MAAjB,CACL,IAAW,GAAX,GAAI6gC,CAAJ,EAAkB,IAAA8xB,QAAA,CAAa9xB,CAAb,CAAlB,EAAsC,IAAAniC,SAAA,CAAcmiC,CAAd,CAAtC,CACa,GACX;AADIA,CACJ,GADgB4yB,CAChB,CAD0B,IAAAzzD,MAC1B,EAAA05B,CAAA,EAASmH,CAFX,KAIE,MAEF,KAAA7gC,MAAA,EARoC,CAYlCyzD,CAAJ,EAA2C,GAA3C,GAAe/5B,CAAA,CAAMA,CAAAh+B,OAAN,CAAqB,CAArB,CAAf,GACE,IAAAsE,MAAA,EAGA,CAFA05B,CAEA,CAFQA,CAAA53B,MAAA,CAAY,CAAZ,CAAgB,EAAhB,CAER,CADA2xD,CACA,CADU/5B,CAAAiN,YAAA,CAAkB,GAAlB,CACV,CAAiB,EAAjB,GAAI8sB,CAAJ,GACEA,CADF,CACYp4D,CADZ,CAJF,CAUA,IAAIo4D,CAAJ,CAEE,IADAC,CACA,CADY,IAAA1zD,MACZ,CAAO0zD,CAAP,CAAmB,IAAA9+B,KAAAl5B,OAAnB,CAAA,CAAqC,CACnCmlC,CAAA,CAAK,IAAAjM,KAAAxzB,OAAA,CAAiBsyD,CAAjB,CACL,IAAW,GAAX,GAAI7yB,CAAJ,CAAgB,CACd8yB,CAAA,CAAaj6B,CAAApM,OAAA,CAAammC,CAAb,CAAuBJ,CAAvB,CAA+B,CAA/B,CACb35B,EAAA,CAAQA,CAAApM,OAAA,CAAa,CAAb,CAAgBmmC,CAAhB,CAA0BJ,CAA1B,CACR,KAAArzD,MAAA,CAAa0zD,CACb,MAJc,CAMhB,GAAI,IAAAb,aAAA,CAAkBhyB,CAAlB,CAAJ,CACE6yB,CAAA,EADF,KAGE,MAXiC,CAgBvC,IAAApB,OAAA71D,KAAA,CAAiB,CACfuD,MAAOqzD,CADQ,CAEfz+B,KAAM8E,CAFS,CAGfz3B,GAAI6uD,EAAA,CAAUp3B,CAAV,CAAJz3B,EAAwBsqC,EAAA,CAAS7S,CAAT,CAAgB,IAAAhU,QAAhB,CAA8B8T,CAA9B,CAHT,CAAjB,CAMIm6B,EAAJ,GACE,IAAArB,OAAA71D,KAAA,CAAiB,CACfuD,MAAOyzD,CADQ,CAEf7+B,KAAM,GAFS,CAAjB,CAIA,CAAA,IAAA09B,OAAA71D,KAAA,CAAiB,CACfuD,MAAOyzD,CAAPzzD,CAAiB,CADF,CAEf40B,KAAM++B,CAFS,CAAjB,CALF,CAtDoB,CA5HN,CA8LhBnB,WAAYA,QAAQ,CAACoB,CAAD,CAAQ,CAC1B,IAAIP,EAAQ,IAAArzD,MACZ,KAAAA,MAAA,EAIA;IAHA,IAAIkgD,EAAS,EAAb,CACI2T,EAAYD,CADhB,CAEIhzB,EAAS,CAAA,CACb,CAAO,IAAA5gC,MAAP,CAAoB,IAAA40B,KAAAl5B,OAApB,CAAA,CAAsC,CACpC,IAAImlC,EAAK,IAAAjM,KAAAxzB,OAAA,CAAiB,IAAApB,MAAjB,CAAT,CACA6zD,EAAAA,CAAAA,CAAahzB,CACb,IAAID,CAAJ,CACa,GAAX,GAAIC,CAAJ,EACMizB,CAIJ,CAJU,IAAAl/B,KAAA7P,UAAA,CAAoB,IAAA/kB,MAApB,CAAiC,CAAjC,CAAoC,IAAAA,MAApC,CAAiD,CAAjD,CAIV,CAHK8zD,CAAAjzD,MAAA,CAAU,aAAV,CAGL,EAFE,IAAAqyD,WAAA,CAAgB,6BAAhB,CAAgDY,CAAhD,CAAsD,GAAtD,CAEF,CADA,IAAA9zD,MACA,EADc,CACd,CAAAkgD,CAAA,EAAU6T,MAAAC,aAAA,CAAoBl2D,QAAA,CAASg2D,CAAT,CAAc,EAAd,CAApB,CALZ,EAQE5T,CARF,EAOYkS,EAAA6B,CAAOpzB,CAAPozB,CAPZ,EAQ4BpzB,CAE5B,CAAAD,CAAA,CAAS,CAAA,CAXX,KAYO,IAAW,IAAX,GAAIC,CAAJ,CACLD,CAAA,CAAS,CAAA,CADJ,KAEA,CAAA,GAAIC,CAAJ,GAAW+yB,CAAX,CAAkB,CACvB,IAAA5zD,MAAA,EACA,KAAAsyD,OAAA71D,KAAA,CAAiB,CACfuD,MAAOqzD,CADQ,CAEfz+B,KAAMi/B,CAFS,CAGf3T,OAAQA,CAHO,CAIfl1C,SAAU,CAAA,CAJK,CAKf/I,GAAIA,QAAQ,EAAG,CAAE,MAAOi+C,EAAT,CALA,CAAjB,CAOA,OATuB,CAWvBA,CAAA,EAAUrf,CAXL,CAaP,IAAA7gC,MAAA,EA9BoC,CAgCtC,IAAAkzD,WAAA,CAAgB,oBAAhB,CAAsCG,CAAtC,CAtC0B,CA9LZ,CAgPlB;IAAIjkB,GAASA,QAAS,CAACH,CAAD,CAAQ58B,CAAR,CAAiBqT,CAAjB,CAA0B,CAC9C,IAAAupB,MAAA,CAAaA,CACb,KAAA58B,QAAA,CAAeA,CACf,KAAAqT,QAAA,CAAeA,CAH+B,CAMhD0pB,GAAA8kB,KAAA,CAAc72D,CAAA,CAAO,QAAS,EAAG,CAC/B,MAAO,EADwB,CAAnB,CAEX,CACDyvC,aAAc,CAAA,CADb,CAED9hC,SAAU,CAAA,CAFT,CAFW,CAOdokC,GAAAlxC,UAAA,CAAmB,CACjB6K,YAAaqmC,EADI,CAGjBvsC,MAAOA,QAAS,CAAC+xB,CAAD,CAAO,CACrB,IAAAA,KAAA,CAAYA,CACZ,KAAA09B,OAAA,CAAc,IAAArjB,MAAAojB,IAAA,CAAez9B,CAAf,CAEV73B,EAAAA,CAAQ,IAAAo3D,WAAA,EAEe,EAA3B,GAAI,IAAA7B,OAAA52D,OAAJ,EACE,IAAAw3D,WAAA,CAAgB,wBAAhB,CAA0C,IAAAZ,OAAA,CAAY,CAAZ,CAA1C,CAGFv1D,EAAA4zB,QAAA,CAAgB,CAAEA,CAAA5zB,CAAA4zB,QAClB5zB,EAAAiO,SAAA,CAAiB,CAAEA,CAAAjO,CAAAiO,SAEnB,OAAOjO,EAbc,CAHN,CAmBjBq3D,QAASA,QAAS,EAAG,CACnB,IAAIA,CACJ,IAAI,IAAAC,OAAA,CAAY,GAAZ,CAAJ,CACED,CACA,CADU,IAAAE,YAAA,EACV,CAAA,IAAAC,QAAA,CAAa,GAAb,CAFF,KAGO,IAAI,IAAAF,OAAA,CAAY,GAAZ,CAAJ,CACLD,CAAA,CAAU,IAAAI,iBAAA,EADL;IAEA,IAAI,IAAAH,OAAA,CAAY,GAAZ,CAAJ,CACLD,CAAA,CAAU,IAAA5S,OAAA,EADL,KAEA,CACL,IAAIzoB,EAAQ,IAAAs7B,OAAA,EAEZ,EADAD,CACA,CADUr7B,CAAA92B,GACV,GACE,IAAAixD,WAAA,CAAgB,0BAAhB,CAA4Cn6B,CAA5C,CAEEA,EAAA/tB,SAAJ,GACEopD,CAAAppD,SACA,CADmB,CAAA,CACnB,CAAAopD,CAAAzjC,QAAA,CAAkB,CAAA,CAFpB,CANK,CAaP,IADA,IAAU10B,CACV,CAAQs6C,CAAR,CAAe,IAAA8d,OAAA,CAAY,GAAZ,CAAiB,GAAjB,CAAsB,GAAtB,CAAf,CAAA,CACoB,GAAlB,GAAI9d,CAAA3hB,KAAJ,EACEw/B,CACA,CADU,IAAAK,aAAA,CAAkBL,CAAlB,CAA2Bn4D,CAA3B,CACV,CAAAA,CAAA,CAAU,IAFZ,EAGyB,GAAlB,GAAIs6C,CAAA3hB,KAAJ,EACL34B,CACA,CADUm4D,CACV,CAAAA,CAAA,CAAU,IAAAM,YAAA,CAAiBN,CAAjB,CAFL,EAGkB,GAAlB,GAAI7d,CAAA3hB,KAAJ,EACL34B,CACA,CADUm4D,CACV,CAAAA,CAAA,CAAU,IAAAO,YAAA,CAAiBP,CAAjB,CAFL,EAIL,IAAAlB,WAAA,CAAgB,YAAhB,CAGJ,OAAOkB,EApCY,CAnBJ,CA0DjBlB,WAAYA,QAAQ,CAAC0B,CAAD,CAAM77B,CAAN,CAAa,CAC/B,KAAMwS,GAAA,CAAa,QAAb,CAEAxS,CAAAnE,KAFA,CAEYggC,CAFZ,CAEkB77B,CAAA/4B,MAFlB,CAEgC,CAFhC,CAEoC,IAAA40B,KAFpC,CAE+C,IAAAA,KAAA7P,UAAA,CAAoBgU,CAAA/4B,MAApB,CAF/C,CAAN,CAD+B,CA1DhB,CAgEjB60D,UAAWA,QAAQ,EAAG,CACpB,GAA2B,CAA3B;AAAI,IAAAvC,OAAA52D,OAAJ,CACE,KAAM6vC,GAAA,CAAa,MAAb,CAA0D,IAAA3W,KAA1D,CAAN,CACF,MAAO,KAAA09B,OAAA,CAAY,CAAZ,CAHa,CAhEL,CAsEjBG,KAAMA,QAAQ,CAACqC,CAAD,CAAKC,CAAL,CAASC,CAAT,CAAaC,CAAb,CAAiB,CAC7B,GAAyB,CAAzB,CAAI,IAAA3C,OAAA52D,OAAJ,CAA4B,CAC1B,IAAIq9B,EAAQ,IAAAu5B,OAAA,CAAY,CAAZ,CAAZ,CACI4C,EAAIn8B,CAAAnE,KACR,IAAIsgC,CAAJ,GAAUJ,CAAV,EAAgBI,CAAhB,GAAsBH,CAAtB,EAA4BG,CAA5B,GAAkCF,CAAlC,EAAwCE,CAAxC,GAA8CD,CAA9C,EACK,EAACH,CAAD,EAAQC,CAAR,EAAeC,CAAf,EAAsBC,CAAtB,CADL,CAEE,MAAOl8B,EALiB,CAQ5B,MAAO,CAAA,CATsB,CAtEd,CAkFjBs7B,OAAQA,QAAQ,CAACS,CAAD,CAAKC,CAAL,CAASC,CAAT,CAAaC,CAAb,CAAgB,CAE9B,MAAA,CADIl8B,CACJ,CADY,IAAA05B,KAAA,CAAUqC,CAAV,CAAcC,CAAd,CAAkBC,CAAlB,CAAsBC,CAAtB,CACZ,GACE,IAAA3C,OAAA/zC,MAAA,EACOwa,CAAAA,CAFT,EAIO,CAAA,CANuB,CAlFf,CA2FjBw7B,QAASA,QAAQ,CAACO,CAAD,CAAI,CACd,IAAAT,OAAA,CAAYS,CAAZ,CAAL,EACE,IAAA5B,WAAA,CAAgB,4BAAhB,CAA+C4B,CAA/C,CAAoD,GAApD,CAAyD,IAAArC,KAAA,EAAzD,CAFiB,CA3FJ,CAiGjB0C,QAASA,QAAQ,CAAClzD,CAAD,CAAKmzD,CAAL,CAAY,CAC3B,MAAO/3D,EAAA,CAAOg4D,QAAsB,CAACrzD,CAAD,CAAOwc,CAAP,CAAe,CACjD,MAAOvc,EAAA,CAAGD,CAAH,CAASwc,CAAT,CAAiB42C,CAAjB,CAD0C,CAA5C,CAEJ,CACDpqD,SAASoqD,CAAApqD,SADR,CAEDoiC,OAAQ,CAACgoB,CAAD,CAFP,CAFI,CADoB,CAjGZ,CA0GjBE,SAAUA,QAAQ,CAACC,CAAD;AAAOtzD,CAAP,CAAWmzD,CAAX,CAAkBI,CAAlB,CAA+B,CAC/C,MAAOn4D,EAAA,CAAOo4D,QAAuB,CAACzzD,CAAD,CAAOwc,CAAP,CAAe,CAClD,MAAOvc,EAAA,CAAGD,CAAH,CAASwc,CAAT,CAAiB+2C,CAAjB,CAAuBH,CAAvB,CAD2C,CAA7C,CAEJ,CACDpqD,SAAUuqD,CAAAvqD,SAAVA,EAA2BoqD,CAAApqD,SAD1B,CAEDoiC,OAAQ,CAACooB,CAATpoB,EAAwB,CAACmoB,CAAD,CAAOH,CAAP,CAFvB,CAFI,CADwC,CA1GhC,CAmHjBjB,WAAYA,QAAQ,EAAG,CAErB,IADA,IAAIA,EAAa,EACjB,CAAA,CAAA,CAGE,GAFyB,CAEpB,CAFD,IAAA7B,OAAA52D,OAEC,EAF0B,CAAA,IAAA+2D,KAAA,CAAU,GAAV,CAAe,GAAf,CAAoB,GAApB,CAAyB,GAAzB,CAE1B,EADH0B,CAAA13D,KAAA,CAAgB,IAAA63D,YAAA,EAAhB,CACG,CAAA,CAAA,IAAAD,OAAA,CAAY,GAAZ,CAAL,CAGE,MAA8B,EAAvB,GAACF,CAAAz4D,OAAD,CACDy4D,CAAA,CAAW,CAAX,CADC,CAEDuB,QAAyB,CAAC1zD,CAAD,CAAOwc,CAAP,CAAe,CAEtC,IADA,IAAIzhB,CAAJ,CACSH,EAAI,CADb,CACgBW,EAAK42D,CAAAz4D,OAArB,CAAwCkB,CAAxC,CAA4CW,CAA5C,CAAgDX,CAAA,EAAhD,CACEG,CAAA,CAAQo3D,CAAA,CAAWv3D,CAAX,CAAA,CAAcoF,CAAd,CAAoBwc,CAApB,CAEV,OAAOzhB,EAL+B,CAV7B,CAnHN,CAwIjBu3D,YAAaA,QAAQ,EAAG,CAGtB,IAFA,IAAIiB,EAAO,IAAA/7B,WAAA,EAEX,CAAgB,IAAA66B,OAAA,CAAY,GAAZ,CAAhB,CAAA,CACEkB,CAAA,CAAO,IAAArqD,OAAA,CAAYqqD,CAAZ,CAET,OAAOA,EANe,CAxIP,CAiJjBrqD,OAAQA,QAAQ,CAACyqD,CAAD,CAAU,CACxB,IAAI58B,EAAQ,IAAAs7B,OAAA,EAAZ,CACIpyD,EAAK,IAAAoQ,QAAA,CAAa0mB,CAAAnE,KAAb,CADT,CAEIghC,CAFJ,CAGI55C,CAEJ,IAAI,IAAAy2C,KAAA,CAAU,GAAV,CAAJ,CAGE,IAFAmD,CACA;AADS,EACT,CAAA55C,CAAA,CAAO,EACP,CAAO,IAAAq4C,OAAA,CAAY,GAAZ,CAAP,CAAA,CACEuB,CAAAn5D,KAAA,CAAY,IAAA+8B,WAAA,EAAZ,CAIA4T,EAAAA,CAAS,CAACuoB,CAAD,CAAAh0D,OAAA,CAAiBi0D,CAAjB,EAA2B,EAA3B,CAEb,OAAOv4D,EAAA,CAAOw4D,QAAqB,CAAC7zD,CAAD,CAAOwc,CAAP,CAAe,CAChD,IAAIrS,EAAQwpD,CAAA,CAAQ3zD,CAAR,CAAcwc,CAAd,CACZ,IAAIxC,CAAJ,CAAU,CACRA,CAAA,CAAK,CAAL,CAAA,CAAU7P,CAGV,KADIvP,CACJ,CADQg5D,CAAAl6D,OACR,CAAOkB,CAAA,EAAP,CAAA,CACEof,CAAA,CAAKpf,CAAL,CAAS,CAAT,CAAA,CAAcg5D,CAAA,CAAOh5D,CAAP,CAAA,CAAUoF,CAAV,CAAgBwc,CAAhB,CAGhB,OAAOvc,EAAAG,MAAA,CAAS/G,CAAT,CAAoB2gB,CAApB,CARC,CAWV,MAAO/Z,EAAA,CAAGkK,CAAH,CAbyC,CAA3C,CAcJ,CACDnB,SAAU,CAAC/I,CAAA+uB,UAAXhmB,EAA2BoiC,CAAA0oB,MAAA,CAAapqB,EAAb,CAD1B,CAED0B,OAAQ,CAACnrC,CAAA+uB,UAAToc,EAAyBA,CAFxB,CAdI,CAhBiB,CAjJT,CAqLjB5T,WAAYA,QAAQ,EAAG,CACrB,MAAO,KAAAu8B,WAAA,EADc,CArLN,CAyLjBA,WAAYA,QAAQ,EAAG,CACrB,IAAIR,EAAO,IAAAS,QAAA,EAAX,CACIZ,CADJ,CAEIr8B,CACJ,OAAA,CAAKA,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAb,GACOkB,CAAA1kC,OAKE,EAJL,IAAAqiC,WAAA,CAAgB,0BAAhB,CACI,IAAAt+B,KAAA7P,UAAA,CAAoB,CAApB,CAAuBgU,CAAA/4B,MAAvB,CADJ,CAC0C,0BAD1C,CACsE+4B,CADtE,CAIK,CADPq8B,CACO,CADC,IAAAY,QAAA,EACD;AAAA34D,CAAA,CAAO44D,QAAyB,CAACjwD,CAAD,CAAQwY,CAAR,CAAgB,CACrD,MAAO+2C,EAAA1kC,OAAA,CAAY7qB,CAAZ,CAAmBovD,CAAA,CAAMpvD,CAAN,CAAawY,CAAb,CAAnB,CAAyCA,CAAzC,CAD8C,CAAhD,CAEJ,CACD4uB,OAAQ,CAACmoB,CAAD,CAAOH,CAAP,CADP,CAFI,CANT,EAYOG,CAhBc,CAzLN,CA4MjBS,QAASA,QAAQ,EAAG,CAClB,IAAIT,EAAO,IAAAW,UAAA,EAAX,CACIC,CADJ,CAEIp9B,CACJ,IAAKA,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAb,CAAgC,CAC9B8B,CAAA,CAAS,IAAAJ,WAAA,EACT,IAAKh9B,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAb,CAAgC,CAC9B,IAAIe,EAAQ,IAAAW,WAAA,EAEZ,OAAO14D,EAAA,CAAO+4D,QAAsB,CAACp0D,CAAD,CAAOwc,CAAP,CAAc,CAChD,MAAO+2C,EAAA,CAAKvzD,CAAL,CAAWwc,CAAX,CAAA,CAAqB23C,CAAA,CAAOn0D,CAAP,CAAawc,CAAb,CAArB,CAA4C42C,CAAA,CAAMpzD,CAAN,CAAYwc,CAAZ,CADH,CAA3C,CAEJ,CACDxT,SAAUuqD,CAAAvqD,SAAVA,EAA2BmrD,CAAAnrD,SAA3BA,EAA8CoqD,CAAApqD,SAD7C,CAFI,CAHuB,CAU9B,IAAAkoD,WAAA,CAAgB,YAAhB,CAA8Bn6B,CAA9B,CAZ4B,CAgBhC,MAAOw8B,EApBW,CA5MH,CAmOjBW,UAAWA,QAAQ,EAAG,CAGpB,IAFA,IAAIX,EAAO,IAAAc,WAAA,EAAX,CACIt9B,CACJ,CAAQA,CAAR,CAAgB,IAAAs7B,OAAA,CAAY,IAAZ,CAAhB,CAAA,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAo0D,WAAA,EAA9B,CAAiD,CAAA,CAAjD,CAET,OAAOd,EANa,CAnOL,CA4OjBc,WAAYA,QAAQ,EAAG,CACrB,IAAId,EAAO,IAAAe,SAAA,EAAX;AACIv9B,CACJ,IAAKA,CAAL,CAAa,IAAAs7B,OAAA,CAAY,IAAZ,CAAb,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAo0D,WAAA,EAA9B,CAAiD,CAAA,CAAjD,CAET,OAAOd,EANc,CA5ON,CAqPjBe,SAAUA,QAAQ,EAAG,CACnB,IAAIf,EAAO,IAAAgB,WAAA,EAAX,CACIx9B,CACJ,IAAKA,CAAL,CAAa,IAAAs7B,OAAA,CAAY,IAAZ,CAAiB,IAAjB,CAAsB,KAAtB,CAA4B,KAA5B,CAAb,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAq0D,SAAA,EAA9B,CAET,OAAOf,EANY,CArPJ,CA8PjBgB,WAAYA,QAAQ,EAAG,CACrB,IAAIhB,EAAO,IAAAiB,SAAA,EAAX,CACIz9B,CACJ,IAAKA,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAiB,GAAjB,CAAsB,IAAtB,CAA4B,IAA5B,CAAb,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAs0D,WAAA,EAA9B,CAET,OAAOhB,EANc,CA9PN,CAuQjBiB,SAAUA,QAAQ,EAAG,CAGnB,IAFA,IAAIjB,EAAO,IAAAkB,eAAA,EAAX,CACI19B,CACJ,CAAQA,CAAR,CAAgB,IAAAs7B,OAAA,CAAY,GAAZ,CAAgB,GAAhB,CAAhB,CAAA,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAw0D,eAAA,EAA9B,CAET,OAAOlB,EANY,CAvQJ,CAgRjBkB,eAAgBA,QAAQ,EAAG,CAGzB,IAFA,IAAIlB;AAAO,IAAAmB,MAAA,EAAX,CACI39B,CACJ,CAAQA,CAAR,CAAgB,IAAAs7B,OAAA,CAAY,GAAZ,CAAgB,GAAhB,CAAoB,GAApB,CAAhB,CAAA,CACEkB,CAAA,CAAO,IAAAD,SAAA,CAAcC,CAAd,CAAoBx8B,CAAA92B,GAApB,CAA8B,IAAAy0D,MAAA,EAA9B,CAET,OAAOnB,EANkB,CAhRV,CAyRjBmB,MAAOA,QAAQ,EAAG,CAChB,IAAI39B,CACJ,OAAI,KAAAs7B,OAAA,CAAY,GAAZ,CAAJ,CACS,IAAAD,QAAA,EADT,CAEO,CAAKr7B,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAb,EACE,IAAAiB,SAAA,CAAclmB,EAAA8kB,KAAd,CAA2Bn7B,CAAA92B,GAA3B,CAAqC,IAAAy0D,MAAA,EAArC,CADF,CAEA,CAAK39B,CAAL,CAAa,IAAAs7B,OAAA,CAAY,GAAZ,CAAb,EACE,IAAAc,QAAA,CAAap8B,CAAA92B,GAAb,CAAuB,IAAAy0D,MAAA,EAAvB,CADF,CAGE,IAAAtC,QAAA,EATO,CAzRD,CAsSjBO,YAAaA,QAAQ,CAACnT,CAAD,CAAS,CAC5B,IAAIhoB,EAAa,IAAA5E,KAAjB,CACI+hC,EAAQ,IAAAtC,OAAA,EAAAz/B,KADZ,CAEI3rB,EAASsjC,EAAA,CAASoqB,CAAT,CAAgB,IAAAjxC,QAAhB,CAA8B8T,CAA9B,CAEb,OAAOn8B,EAAA,CAAOu5D,QAA0B,CAAC5wD,CAAD,CAAQwY,CAAR,CAAgBxc,CAAhB,CAAsB,CAC5D,MAAOiH,EAAA,CAAOjH,CAAP,EAAew/C,CAAA,CAAOx7C,CAAP,CAAcwY,CAAd,CAAf,CADqD,CAAvD,CAEJ,CACDqS,OAAQA,QAAQ,CAAC7qB,CAAD,CAAQjJ,CAAR,CAAeyhB,CAAf,CAAuB,CAErC,CADIq4C,CACJ,CADQrV,CAAA,CAAOx7C,CAAP,CAAcwY,CAAd,CACR,GAAQgjC,CAAA3wB,OAAA,CAAc7qB,CAAd,CAAqB6wD,CAArB,CAAyB,EAAzB,CACR,OAAOlrB,GAAA,CAAOkrB,CAAP,CAAUF,CAAV,CAAiB55D,CAAjB,CAAwBy8B,CAAxB,CAH8B,CADtC,CAFI,CALqB,CAtSb,CAsTjBk7B,YAAaA,QAAQ,CAACl5D,CAAD,CAAM,CACzB,IAAIg+B;AAAa,IAAA5E,KAAjB,CAEIkiC,EAAU,IAAAt9B,WAAA,EACd,KAAA+6B,QAAA,CAAa,GAAb,CAEA,OAAOl3D,EAAA,CAAO05D,QAA0B,CAAC/0D,CAAD,CAAOwc,CAAP,CAAe,CAAA,IACjDq4C,EAAIr7D,CAAA,CAAIwG,CAAJ,CAAUwc,CAAV,CAD6C,CAEjD5hB,EAAIk6D,CAAA,CAAQ90D,CAAR,CAAcwc,CAAd,CAGR6sB,GAAA,CAAqBzuC,CAArB,CAAwB48B,CAAxB,CACA,OAAKq9B,EAAL,CACIrrB,EAAA9M,CAAiBm4B,CAAA,CAAEj6D,CAAF,CAAjB8hC,CAAuBlF,CAAvBkF,CADJ,CAAerjC,CANsC,CAAhD,CASJ,CACDw1B,OAAQA,QAAQ,CAAC7uB,CAAD,CAAOjF,CAAP,CAAcyhB,CAAd,CAAsB,CACpC,IAAItiB,EAAMmvC,EAAA,CAAqByrB,CAAA,CAAQ90D,CAAR,CAAcwc,CAAd,CAArB,CAA4Cgb,CAA5C,CAGV,EADIq9B,CACJ,CADQrrB,EAAA,CAAiBhwC,CAAA,CAAIwG,CAAJ,CAAUwc,CAAV,CAAjB,CAAoCgb,CAApC,CACR,GAAQh+B,CAAAq1B,OAAA,CAAW7uB,CAAX,CAAiB60D,CAAjB,CAAqB,EAArB,CACR,OAAOA,EAAA,CAAE36D,CAAF,CAAP,CAAgBa,CALoB,CADrC,CATI,CANkB,CAtTV,CAgVjB03D,aAAcA,QAAQ,CAACuC,CAAD,CAAWC,CAAX,CAA0B,CAC9C,IAAIrB,EAAS,EACb,IAA8B,GAA9B,GAAI,IAAAf,UAAA,EAAAjgC,KAAJ,EACE,EACEghC,EAAAn5D,KAAA,CAAY,IAAA+8B,WAAA,EAAZ,CADF,OAES,IAAA66B,OAAA,CAAY,GAAZ,CAFT,CADF,CAKA,IAAAE,QAAA,CAAa,GAAb,CAEA,KAAI2C,EAAiB,IAAAtiC,KAArB,CAEI5Y,EAAO45C,CAAAl6D,OAAA,CAAgB,EAAhB,CAAqB,IAEhC,OAAOy7D,SAA2B,CAACnxD,CAAD,CAAQwY,CAAR,CAAgB,CAChD,IAAIviB,EAAUg7D,CAAA,CAAgBA,CAAA,CAAcjxD,CAAd,CAAqBwY,CAArB,CAAhB,CAA+CxY,CAA7D,CACI/D,EAAK+0D,CAAA,CAAShxD,CAAT,CAAgBwY,CAAhB,CAAwBviB,CAAxB,CAALgG,EAAyC9D,CAE7C,IAAI6d,CAAJ,CAEE,IADA,IAAIpf,EAAIg5D,CAAAl6D,OACR,CAAOkB,CAAA,EAAP,CAAA,CACEof,CAAA,CAAKpf,CAAL,CAAA,CAAU4uC,EAAA,CAAiBoqB,CAAA,CAAOh5D,CAAP,CAAA,CAAUoJ,CAAV,CAAiBwY,CAAjB,CAAjB,CAA2C04C,CAA3C,CAId1rB,GAAA,CAAiBvvC,CAAjB;AAA0Bi7D,CAA1B,CAlrBJ,IAmrBuBj1D,CAnrBvB,CAAS,CACP,GAkrBqBA,CAlrBjB8G,YAAJ,GAkrBqB9G,CAlrBrB,CACE,KAAMspC,GAAA,CAAa,QAAb,CAirBiB2rB,CAjrBjB,CAAN,CAGK,GA8qBcj1D,CA9qBd,GAAY0uD,EAAZ,EA8qBc1uD,CA9qBd,GAA4B2uD,EAA5B,EA8qBc3uD,CA9qBd,GAA6C4uD,EAA7C,CACL,KAAMtlB,GAAA,CAAa,QAAb,CA6qBiB2rB,CA7qBjB,CAAN,CANK,CAsrBDx4B,CAAAA,CAAIz8B,CAAAG,MAAA,CACAH,CAAAG,MAAA,CAASnG,CAAT,CAAkB+f,CAAlB,CADA,CAEA/Z,CAAA,CAAG+Z,CAAA,CAAK,CAAL,CAAH,CAAYA,CAAA,CAAK,CAAL,CAAZ,CAAqBA,CAAA,CAAK,CAAL,CAArB,CAA8BA,CAAA,CAAK,CAAL,CAA9B,CAAuCA,CAAA,CAAK,CAAL,CAAvC,CAER,OAAOwvB,GAAA,CAAiB9M,CAAjB,CAAoBw4B,CAApB,CAnByC,CAbJ,CAhV/B,CAqXjB1C,iBAAkBA,QAAS,EAAG,CAC5B,IAAI4C,EAAa,EACjB,IAA8B,GAA9B,GAAI,IAAAvC,UAAA,EAAAjgC,KAAJ,EACE,EAAG,CACD,GAAI,IAAA69B,KAAA,CAAU,GAAV,CAAJ,CAEE,KAEF,KAAI4E,EAAY,IAAA79B,WAAA,EAChB49B,EAAA36D,KAAA,CAAgB46D,CAAhB,CANC,CAAH,MAOS,IAAAhD,OAAA,CAAY,GAAZ,CAPT,CADF,CAUA,IAAAE,QAAA,CAAa,GAAb,CAEA,OAAOl3D,EAAA,CAAOi6D,QAA2B,CAACt1D,CAAD,CAAOwc,CAAP,CAAe,CAEtD,IADA,IAAIze,EAAQ,EAAZ,CACSnD,EAAI,CADb,CACgBW,EAAK65D,CAAA17D,OAArB,CAAwCkB,CAAxC,CAA4CW,CAA5C,CAAgDX,CAAA,EAAhD,CACEmD,CAAAtD,KAAA,CAAW26D,CAAA,CAAWx6D,CAAX,CAAA,CAAcoF,CAAd,CAAoBwc,CAApB,CAAX,CAEF,OAAOze,EAL+C,CAAjD,CAMJ,CACD4wB,QAAS,CAAA,CADR,CAED3lB,SAAUosD,CAAAtB,MAAA,CAAiBpqB,EAAjB,CAFT,CAGD0B,OAAQgqB,CAHP,CANI,CAdqB,CArXb,CAgZjB5V,OAAQA,QAAS,EAAG,CAAA,IACdhlD,EAAO,EADO,CACH+6D,EAAW,EAC1B;GAA8B,GAA9B,GAAI,IAAA1C,UAAA,EAAAjgC,KAAJ,EACE,EAAG,CACD,GAAI,IAAA69B,KAAA,CAAU,GAAV,CAAJ,CAEE,KAEF,KAAI15B,EAAQ,IAAAs7B,OAAA,EACZ73D,EAAAC,KAAA,CAAUs8B,CAAAmnB,OAAV,EAA0BnnB,CAAAnE,KAA1B,CACA,KAAA2/B,QAAA,CAAa,GAAb,CACIx3D,EAAAA,CAAQ,IAAAy8B,WAAA,EACZ+9B,EAAA96D,KAAA,CAAcM,CAAd,CATC,CAAH,MAUS,IAAAs3D,OAAA,CAAY,GAAZ,CAVT,CADF,CAaA,IAAAE,QAAA,CAAa,GAAb,CAEA,OAAOl3D,EAAA,CAAOm6D,QAA4B,CAACx1D,CAAD,CAAOwc,CAAP,CAAe,CAEvD,IADA,IAAIgjC,EAAS,EAAb,CACS5kD,EAAI,CADb,CACgBW,EAAKg6D,CAAA77D,OAArB,CAAsCkB,CAAtC,CAA0CW,CAA1C,CAA8CX,CAAA,EAA9C,CACE4kD,CAAA,CAAOhlD,CAAA,CAAKI,CAAL,CAAP,CAAA,CAAkB26D,CAAA,CAAS36D,CAAT,CAAA,CAAYoF,CAAZ,CAAkBwc,CAAlB,CAEpB,OAAOgjC,EALgD,CAAlD,CAMJ,CACD7wB,QAAS,CAAA,CADR,CAED3lB,SAAUusD,CAAAzB,MAAA,CAAepqB,EAAf,CAFT,CAGD0B,OAAQmqB,CAHP,CANI,CAjBW,CAhZH,CAucnB,KAAI/qB,GAAgB7iC,EAAA,EAApB,CAg0EIguC,GAAar8C,CAAA,CAAO,MAAP,CAh0EjB,CAk0EIy8C,GAAe,CACjBriB,KAAM,MADW,CAEjBsjB,IAAK,KAFY,CAGjBC,IAAK,KAHY,CAMjBtjB,aAAc,aANG,CAOjBujB,GAAI,IAPa,CAl0EnB,CAs7GIxxB,GAAiBpsB,CAAA,CAAO,UAAP,CAt7GrB,CAurHIghD,EAAiBlhD,CAAAya,cAAA,CAAuB,GAAvB,CAvrHrB,CAwrHI2mC,GAAYpc,EAAA,CAAWjlC,CAAAyL,SAAA4c,KAAX,CAAiC,CAAA,CAAjC,CAwOhBlR,GAAA+J,QAAA;AAA0B,CAAC,UAAD,CAyU1BsgC,GAAAtgC,QAAA,CAAyB,CAAC,SAAD,CAwEzB4gC,GAAA5gC,QAAA,CAAuB,CAAC,SAAD,CAavB,KAAIgnB,GAAc,GAAlB,CA6JIke,GAAe,CACjBkF,KAAMtH,CAAA,CAAW,UAAX,CAAuB,CAAvB,CADW,CAEfsY,GAAItY,CAAA,CAAW,UAAX,CAAuB,CAAvB,CAA0B,CAA1B,CAA6B,CAAA,CAA7B,CAFW,CAGduY,EAAGvY,CAAA,CAAW,UAAX,CAAuB,CAAvB,CAHW,CAIjBwY,KAAMtY,EAAA,CAAc,OAAd,CAJW,CAKhBuY,IAAKvY,EAAA,CAAc,OAAd,CAAuB,CAAA,CAAvB,CALW,CAMfqH,GAAIvH,CAAA,CAAW,OAAX,CAAoB,CAApB,CAAuB,CAAvB,CANW,CAOd0Y,EAAG1Y,CAAA,CAAW,OAAX,CAAoB,CAApB,CAAuB,CAAvB,CAPW,CAQfwH,GAAIxH,CAAA,CAAW,MAAX,CAAmB,CAAnB,CARW,CASdrkB,EAAGqkB,CAAA,CAAW,MAAX,CAAmB,CAAnB,CATW,CAUfyH,GAAIzH,CAAA,CAAW,OAAX,CAAoB,CAApB,CAVW,CAWd2Y,EAAG3Y,CAAA,CAAW,OAAX,CAAoB,CAApB,CAXW,CAYf4Y,GAAI5Y,CAAA,CAAW,OAAX,CAAoB,CAApB,CAAwB,GAAxB,CAZW,CAadhiD,EAAGgiD,CAAA,CAAW,OAAX,CAAoB,CAApB,CAAwB,GAAxB,CAbW,CAcf2H,GAAI3H,CAAA,CAAW,SAAX,CAAsB,CAAtB,CAdW,CAedyB,EAAGzB,CAAA,CAAW,SAAX,CAAsB,CAAtB,CAfW,CAgBf4H,GAAI5H,CAAA,CAAW,SAAX,CAAsB,CAAtB,CAhBW,CAiBd0B,EAAG1B,CAAA,CAAW,SAAX,CAAsB,CAAtB,CAjBW,CAoBhB8H,IAAK9H,CAAA,CAAW,cAAX,CAA2B,CAA3B,CApBW,CAqBjB6Y,KAAM3Y,EAAA,CAAc,KAAd,CArBW,CAsBhB4Y,IAAK5Y,EAAA,CAAc,KAAd,CAAqB,CAAA,CAArB,CAtBW,CAuBdpzC,EA3BLisD,QAAmB,CAAC9Y,CAAD,CAAOzB,CAAP,CAAgB,CACjC,MAAyB,GAAlB,CAAAyB,CAAAyH,SAAA,EAAA,CAAuBlJ,CAAApZ,MAAA,CAAc,CAAd,CAAvB,CAA0CoZ,CAAApZ,MAAA,CAAc,CAAd,CADhB,CAIhB,CAwBd4zB,EAhELC,QAAuB,CAAChZ,CAAD,CAAO,CACxBiZ,CAAAA;AAAQ,EAARA,CAAYjZ,CAAAkC,kBAAA,EAMhB,OAHAgX,EAGA,EAL0B,CAATA,EAACD,CAADC,CAAc,GAAdA,CAAoB,EAKrC,GAHctZ,EAAA,CAAUhsB,IAAA,CAAY,CAAP,CAAAqlC,CAAA,CAAW,OAAX,CAAqB,MAA1B,CAAA,CAAkCA,CAAlC,CAAyC,EAAzC,CAAV,CAAwD,CAAxD,CAGd,CAFcrZ,EAAA,CAAUhsB,IAAAqrB,IAAA,CAASga,CAAT,CAAgB,EAAhB,CAAV,CAA+B,CAA/B,CAEd,CAP4B,CAwCX,CAyBfE,GAAI5Y,EAAA,CAAW,CAAX,CAzBW,CA0Bd6Y,EAAG7Y,EAAA,CAAW,CAAX,CA1BW,CA7JnB,CA0LIwB,GAAqB,kFA1LzB,CA2LID,GAAgB,UA2FpBtE,GAAAvgC,QAAA,CAAqB,CAAC,SAAD,CAuHrB,KAAI2gC,GAAkB1+C,EAAA,CAAQuB,CAAR,CAAtB,CAWIs9C,GAAkB7+C,EAAA,CAAQkN,EAAR,CAwPtB0xC,GAAA7gC,QAAA,CAAwB,CAAC,QAAD,CA2FxB,KAAInQ,GAAsB5N,EAAA,CAAQ,CAChCqqB,SAAU,GADsB,CAEhC1iB,QAASA,QAAQ,CAACrG,CAAD,CAAUN,CAAV,CAAgB,CAC/B,GAAKkkB,CAAAlkB,CAAAkkB,KAAL,EAAmBi1C,CAAAn5D,CAAAm5D,UAAnB,EAAsC3zD,CAAAxF,CAAAwF,KAAtC,CACE,MAAO,SAAQ,CAACkB,CAAD,CAAQpG,CAAR,CAAiB,CAE9B,IAAI4jB,EAA+C,4BAAxC,GAAA5kB,EAAAvC,KAAA,CAAcuD,CAAAP,KAAA,CAAa,MAAb,CAAd,CAAA,CACA,YADA,CACe,MAC1BO,EAAA+H,GAAA,CAAW,OAAX,CAAoB,QAAQ,CAACgT,CAAD,CAAO,CAE5B/a,CAAAN,KAAA,CAAakkB,CAAb,CAAL;AACE7I,CAAAmvB,eAAA,EAH+B,CAAnC,CAJ8B,CAFH,CAFD,CAAR,CAA1B,CAuWIz4B,GAA6B,EAIjCtV,EAAA,CAAQse,EAAR,CAAsB,QAAQ,CAACq+C,CAAD,CAAW/wC,CAAX,CAAqB,CAEjD,GAAgB,UAAhB,EAAI+wC,CAAJ,CAAA,CAEA,IAAIC,EAAa9rC,EAAA,CAAmB,KAAnB,CAA2BlF,CAA3B,CACjBtW,GAAA,CAA2BsnD,CAA3B,CAAA,CAAyC,QAAQ,EAAG,CAClD,MAAO,CACLhwC,SAAU,GADL,CAELF,SAAU,GAFL,CAGLzC,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACnC0G,CAAAhH,OAAA,CAAaM,CAAA,CAAKq5D,CAAL,CAAb,CAA+BC,QAAiC,CAAC77D,CAAD,CAAQ,CACtEuC,CAAAi0B,KAAA,CAAU5L,CAAV,CAAoB,CAAE5qB,CAAAA,CAAtB,CADsE,CAAxE,CADmC,CAHhC,CAD2C,CAHpD,CAFiD,CAAnD,CAmBAhB,EAAA,CAAQye,EAAR,CAAsB,QAAQ,CAACq+C,CAAD,CAAWv0D,CAAX,CAAmB,CAC/C+M,EAAA,CAA2B/M,CAA3B,CAAA,CAAqC,QAAQ,EAAG,CAC9C,MAAO,CACLmkB,SAAU,GADL,CAELzC,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAGnC,GAAe,WAAf,GAAIgF,CAAJ,EAA0D,GAA1D,EAA8BhF,CAAAgR,UAAAlP,OAAA,CAAsB,CAAtB,CAA9B,GACMP,CADN,CACcvB,CAAAgR,UAAAzP,MAAA,CAAqB2pD,EAArB,CADd,EAEa,CACTlrD,CAAAi0B,KAAA,CAAU,WAAV,CAAuB,IAAI3yB,MAAJ,CAAWC,CAAA,CAAM,CAAN,CAAX,CAAqBA,CAAA,CAAM,CAAN,CAArB,CAAvB,CACA,OAFS,CAMbmF,CAAAhH,OAAA,CAAaM,CAAA,CAAKgF,CAAL,CAAb,CAA2Bw0D,QAA+B,CAAC/7D,CAAD,CAAQ,CAChEuC,CAAAi0B,KAAA,CAAUjvB,CAAV,CAAkBvH,CAAlB,CADgE,CAAlE,CAXmC,CAFhC,CADuC,CADD,CAAjD,CAwBAhB,EAAA,CAAQ,CAAC,KAAD,CAAQ,QAAR,CAAkB,MAAlB,CAAR,CAAmC,QAAQ,CAAC4rB,CAAD,CAAW,CACpD,IAAIgxC,EAAa9rC,EAAA,CAAmB,KAAnB;AAA2BlF,CAA3B,CACjBtW,GAAA,CAA2BsnD,CAA3B,CAAA,CAAyC,QAAQ,EAAG,CAClD,MAAO,CACLlwC,SAAU,EADL,CAELzC,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAAA,IAC/Bo5D,EAAW/wC,CADoB,CAE/B7iB,EAAO6iB,CAEM,OAAjB,GAAIA,CAAJ,EAC4C,4BAD5C,GACI/oB,EAAAvC,KAAA,CAAcuD,CAAAP,KAAA,CAAa,MAAb,CAAd,CADJ,GAEEyF,CAEA,CAFO,WAEP,CADAxF,CAAAqtB,MAAA,CAAW7nB,CAAX,CACA,CADmB,YACnB,CAAA4zD,CAAA,CAAW,IAJb,CAOAp5D,EAAAkxB,SAAA,CAAcmoC,CAAd,CAA0B,QAAQ,CAAC57D,CAAD,CAAQ,CACnCA,CAAL,EAOAuC,CAAAi0B,KAAA,CAAUzuB,CAAV,CAAgB/H,CAAhB,CAMA,CAAI+9C,EAAJ,EAAY4d,CAAZ,EAAsB94D,CAAAP,KAAA,CAAaq5D,CAAb,CAAuBp5D,CAAA,CAAKwF,CAAL,CAAvB,CAbtB,EACmB,MADnB,GACM6iB,CADN,EAEIroB,CAAAi0B,KAAA,CAAUzuB,CAAV,CAAgB,IAAhB,CAHoC,CAA1C,CAXmC,CAFhC,CAD2C,CAFA,CAAtD,CAx3iBuC,KA+5iBnC69C,GAAe,CACjBU,YAAallD,CADI,CAEjBylD,gBASFmV,QAA8B,CAACvV,CAAD,CAAU1+C,CAAV,CAAgB,CAC5C0+C,CAAAT,MAAA,CAAgBj+C,CAD4B,CAX3B,CAGjBk/C,eAAgB7lD,CAHC,CAIjB+lD,aAAc/lD,CAJG,CAKjBomD,UAAWpmD,CALM,CAMjBwmD,aAAcxmD,CANG,CAOjB8mD,cAAe9mD,CAPE,CAoDnBokD,GAAAlmC,QAAA,CAAyB,CAAC,UAAD,CAAa,QAAb,CAAuB,QAAvB,CAAiC,UAAjC,CAA6C,cAA7C,CAkYzB,KAAI28C,GAAuBA,QAAQ,CAACC,CAAD,CAAW,CAC5C,MAAO,CAAC,UAAD;AAAa,QAAQ,CAAC1kD,CAAD,CAAW,CAkErC,MAjEoBhI,CAClBzH,KAAM,MADYyH,CAElBoc,SAAUswC,CAAA,CAAW,KAAX,CAAmB,GAFX1sD,CAGlBzE,WAAYy6C,EAHMh2C,CAIlBtG,QAASizD,QAAsB,CAACC,CAAD,CAAc,CAE3CA,CAAA5vC,SAAA,CAAqBk7B,EAArB,CAAAl7B,SAAA,CAA8C+/B,EAA9C,CAEA,OAAO,CACL56B,IAAK0qC,QAAsB,CAACpzD,CAAD,CAAQmzD,CAAR,CAAqB75D,CAArB,CAA2BwI,CAA3B,CAAuC,CAEhE,GAAM,EAAA,QAAA,EAAYxI,EAAZ,CAAN,CAAyB,CAOvB,IAAI+5D,EAAuBA,QAAQ,CAAC1+C,CAAD,CAAQ,CACzC3U,CAAAE,OAAA,CAAa,QAAQ,EAAG,CACtB4B,CAAA27C,iBAAA,EACA37C,EAAAm9C,cAAA,EAFsB,CAAxB,CAKAtqC,EAAAmvB,eAAA,CACInvB,CAAAmvB,eAAA,EADJ,CAEInvB,CAAA2+C,YAFJ,CAEwB,CAAA,CARiB,CAWxBH,EAAAv5D,CAAY,CAAZA,CA1jf3B6/B,iBAAA,CA0jf2ChoB,QA1jf3C,CA0jfqD4hD,CA1jfrD,CAAmC,CAAA,CAAnC,CA8jfQF,EAAAxxD,GAAA,CAAe,UAAf,CAA2B,QAAQ,EAAG,CACpC4M,CAAA,CAAS,QAAQ,EAAG,CACI4kD,CAAAv5D,CAAY,CAAZA,CA7jflCmY,oBAAA,CA6jfkDN,QA7jflD,CA6jf4D4hD,CA7jf5D,CAAsC,CAAA,CAAtC,CA4jf8B,CAApB,CAEG,CAFH,CAEM,CAAA,CAFN,CADoC,CAAtC,CAtBuB,CAFuC,IA+B5DE,EAAiBzxD,CAAA46C,aA/B2C,CAgC5D8W,EAAQ1xD,CAAAi7C,MAERyW,EAAJ,GACE7tB,EAAA,CAAO3lC,CAAP,CAAcwzD,CAAd,CAAqB1xD,CAArB,CAAiC0xD,CAAjC,CACA,CAAAl6D,CAAAkxB,SAAA,CAAclxB,CAAAwF,KAAA,CAAY,MAAZ,CAAqB,QAAnC;AAA6C,QAAQ,CAACixB,CAAD,CAAW,CAC1DyjC,CAAJ,GAAczjC,CAAd,GACA4V,EAAA,CAAO3lC,CAAP,CAAcwzD,CAAd,CAAqBn+D,CAArB,CAAgCm+D,CAAhC,CAGA,CAFAA,CAEA,CAFQzjC,CAER,CADA4V,EAAA,CAAO3lC,CAAP,CAAcwzD,CAAd,CAAqB1xD,CAArB,CAAiC0xD,CAAjC,CACA,CAAAD,CAAA3V,gBAAA,CAA+B97C,CAA/B,CAA2C0xD,CAA3C,CAJA,CAD8D,CAAhE,CAFF,CAUAL,EAAAxxD,GAAA,CAAe,UAAf,CAA2B,QAAQ,EAAG,CACpC4xD,CAAAvV,eAAA,CAA8Bl8C,CAA9B,CACI0xD,EAAJ,EACE7tB,EAAA,CAAO3lC,CAAP,CAAcwzD,CAAd,CAAqBn+D,CAArB,CAAgCm+D,CAAhC,CAEFn8D,EAAA,CAAOyK,CAAP,CAAmB66C,EAAnB,CALoC,CAAtC,CA5CgE,CAD7D,CAJoC,CAJ3Bp2C,CADiB,CAAhC,CADqC,CAA9C,CAuEIA,GAAgBysD,EAAA,EAvEpB,CAwEI/qD,GAAkB+qD,EAAA,CAAqB,CAAA,CAArB,CAxEtB,CAmFIxS,GAAkB,0EAnFtB,CAoFIiT,GAAa,qFApFjB,CAqFIC,GAAe,mGArFnB,CAsFIC,GAAgB,oCAtFpB,CAuFIC,GAAc,2BAvFlB;AAwFIC,GAAuB,+DAxF3B,CAyFIC,GAAc,mBAzFlB,CA0FIC,GAAe,kBA1FnB,CA2FIC,GAAc,yCA3FlB,CA4FIC,GAAiB,uBA5FrB,CA8FIlS,GAAiB,IAAIzsD,CAAJ,CAAW,SAAX,CA9FrB,CAgGI4+D,GAAY,CAkFd,KAoyBFC,QAAsB,CAACn0D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiD,CACrE2zC,EAAA,CAAct/C,CAAd,CAAqBpG,CAArB,CAA8BN,CAA9B,CAAoC8kD,CAApC,CAA0CrwC,CAA1C,CAAoDpC,CAApD,CACAwzC,GAAA,CAAqBf,CAArB,CAFqE,CAt3BvD,CA0Kd,KAAQiD,EAAA,CAAoB,MAApB,CAA4BuS,EAA5B,CACDvT,EAAA,CAAiBuT,EAAjB,CAA8B,CAAC,MAAD,CAAS,IAAT,CAAe,IAAf,CAA9B,CADC,CAED,YAFC,CA1KM,CAkQd,iBAAkBvS,EAAA,CAAoB,eAApB,CAAqCwS,EAArC,CACdxT,EAAA,CAAiBwT,EAAjB,CAAuC,yBAAA,MAAA,CAAA,GAAA,CAAvC,CADc,CAEd,yBAFc,CAlQJ,CA2Vd,KAAQxS,EAAA,CAAoB,MAApB,CAA4B2S,EAA5B,CACJ3T,EAAA,CAAiB2T,EAAjB,CAA8B,CAAC,IAAD,CAAO,IAAP,CAAa,IAAb,CAAmB,KAAnB,CAA9B,CADI,CAEL,cAFK,CA3VM,CAmbd,KAAQ3S,EAAA,CAAoB,MAApB;AAA4ByS,EAA5B,CAmiBVM,QAAmB,CAACC,CAAD,CAAUC,CAAV,CAAwB,CACzC,GAAI37D,EAAA,CAAO07D,CAAP,CAAJ,CACE,MAAOA,EAGT,IAAIx+D,CAAA,CAASw+D,CAAT,CAAJ,CAAuB,CACrBP,EAAAh5D,UAAA,CAAwB,CACxB,KAAIgD,EAAQg2D,EAAA/jD,KAAA,CAAiBskD,CAAjB,CACZ,IAAIv2D,CAAJ,CAAW,CAAA,IACL07C,EAAO,CAAC17C,CAAA,CAAM,CAAN,CADH,CAELy2D,EAAO,CAACz2D,CAAA,CAAM,CAAN,CAFH,CAIL02D,EADAC,CACAD,CADQ,CAHH,CAKLE,EAAU,CALL,CAMLC,EAAe,CANV,CAOL/a,EAAaL,EAAA,CAAuBC,CAAvB,CAPR,CAQLob,EAAuB,CAAvBA,EAAWL,CAAXK,CAAkB,CAAlBA,CAEAN,EAAJ,GACEG,CAGA,CAHQH,CAAAzT,SAAA,EAGR,CAFA2T,CAEA,CAFUF,CAAAjZ,WAAA,EAEV,CADAqZ,CACA,CADUJ,CAAAtT,WAAA,EACV,CAAA2T,CAAA,CAAeL,CAAApT,gBAAA,EAJjB,CAOA,OAAO,KAAIxmD,IAAJ,CAAS8+C,CAAT,CAAe,CAAf,CAAkBI,CAAAI,QAAA,EAAlB,CAAyC4a,CAAzC,CAAkDH,CAAlD,CAAyDD,CAAzD,CAAkEE,CAAlE,CAA2EC,CAA3E,CAjBE,CAHU,CAwBvB,MAAOvT,IA7BkC,CAniBjC,CAAqD,UAArD,CAnbM,CA0gBd,MAASC,EAAA,CAAoB,OAApB,CAA6B0S,EAA7B,CACN1T,EAAA,CAAiB0T,EAAjB,CAA+B,CAAC,MAAD,CAAS,IAAT,CAA/B,CADM,CAEN,SAFM,CA1gBK,CAylBd,OAuiBFc,QAAwB,CAAC70D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiD,CACvE81C,EAAA,CAAgBzhD,CAAhB,CAAuBpG,CAAvB,CAAgCN,CAAhC,CAAsC8kD,CAAtC,CACAkB,GAAA,CAAct/C,CAAd,CAAqBpG,CAArB,CAA8BN,CAA9B,CAAoC8kD,CAApC,CAA0CrwC,CAA1C,CAAoDpC,CAApD,CAEAyyC,EAAAwD,aAAA,CAAoB,QACpBxD,EAAAyD,SAAAprD,KAAA,CAAmB,QAAQ,CAACM,CAAD,CAAQ,CACjC,MAAIqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAJ,CAAsC,IAAtC,CACI48D,EAAArzD,KAAA,CAAmBvJ,CAAnB,CAAJ,CAAsCgkD,UAAA,CAAWhkD,CAAX,CAAtC,CACO1B,CAH0B,CAAnC,CAMA+oD,EAAAgB,YAAA3oD,KAAA,CAAsB,QAAQ,CAACM,CAAD,CAAQ,CACpC,GAAK,CAAAqnD,CAAAiB,SAAA,CAActoD,CAAd,CAAL,CAA2B,CACzB,GAAK,CAAA2B,CAAA,CAAS3B,CAAT,CAAL,CACE,KAAMgrD,GAAA,CAAe,QAAf;AAA0DhrD,CAA1D,CAAN,CAEFA,CAAA,CAAQA,CAAA6B,SAAA,EAJiB,CAM3B,MAAO7B,EAP6B,CAAtC,CAUA,IAAIuC,CAAAq/C,IAAJ,EAAgBr/C,CAAA2oD,MAAhB,CAA4B,CAC1B,IAAIC,CACJ9D,EAAA+D,YAAAxJ,IAAA,CAAuByJ,QAAQ,CAACrrD,CAAD,CAAQ,CACrC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+BwB,CAAA,CAAY2pD,CAAZ,CAA/B,EAAsDnrD,CAAtD,EAA+DmrD,CAD1B,CAIvC5oD,EAAAkxB,SAAA,CAAc,KAAd,CAAqB,QAAQ,CAACluB,CAAD,CAAM,CAC7B9D,CAAA,CAAU8D,CAAV,CAAJ,EAAuB,CAAA5D,CAAA,CAAS4D,CAAT,CAAvB,GACEA,CADF,CACQy+C,UAAA,CAAWz+C,CAAX,CAAgB,EAAhB,CADR,CAGA4lD,EAAA,CAASxpD,CAAA,CAAS4D,CAAT,CAAA,EAAkB,CAAAg0C,KAAA,CAAMh0C,CAAN,CAAlB,CAA+BA,CAA/B,CAAqCjH,CAE9C+oD,EAAAiE,UAAA,EANiC,CAAnC,CAN0B,CAgB5B,GAAI/oD,CAAA2zB,IAAJ,EAAgB3zB,CAAAgpD,MAAhB,CAA4B,CAC1B,IAAIC,CACJnE,EAAA+D,YAAAl1B,IAAA,CAAuBu1B,QAAQ,CAACzrD,CAAD,CAAQ,CACrC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+BwB,CAAA,CAAYgqD,CAAZ,CAA/B,EAAsDxrD,CAAtD,EAA+DwrD,CAD1B,CAIvCjpD,EAAAkxB,SAAA,CAAc,KAAd,CAAqB,QAAQ,CAACluB,CAAD,CAAM,CAC7B9D,CAAA,CAAU8D,CAAV,CAAJ,EAAuB,CAAA5D,CAAA,CAAS4D,CAAT,CAAvB,GACEA,CADF,CACQy+C,UAAA,CAAWz+C,CAAX,CAAgB,EAAhB,CADR,CAGAimD,EAAA,CAAS7pD,CAAA,CAAS4D,CAAT,CAAA,EAAkB,CAAAg0C,KAAA,CAAMh0C,CAAN,CAAlB,CAA+BA,CAA/B,CAAqCjH,CAE9C+oD,EAAAiE,UAAA,EANiC,CAAnC,CAN0B,CArC2C,CAhoCzD,CAsqBd,IAghBFyS,QAAqB,CAAC90D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiD,CAGpE2zC,EAAA,CAAct/C,CAAd,CAAqBpG,CAArB,CAA8BN,CAA9B,CAAoC8kD,CAApC,CAA0CrwC,CAA1C,CAAoDpC,CAApD,CACAwzC,GAAA,CAAqBf,CAArB,CAEAA,EAAAwD,aAAA,CAAoB,KACpBxD,EAAA+D,YAAA5lC,IAAA,CAAuBw4C,QAAQ,CAACh+D,CAAD,CAAQ,CACrC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP;AAA+B08D,EAAAnzD,KAAA,CAAgBvJ,CAAhB,CADM,CAP6B,CAtrCtD,CAkvBd,MAgdFi+D,QAAuB,CAACh1D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiD,CAGtE2zC,EAAA,CAAct/C,CAAd,CAAqBpG,CAArB,CAA8BN,CAA9B,CAAoC8kD,CAApC,CAA0CrwC,CAA1C,CAAoDpC,CAApD,CACAwzC,GAAA,CAAqBf,CAArB,CAEAA,EAAAwD,aAAA,CAAoB,OACpBxD,EAAA+D,YAAA8S,MAAA,CAAyBC,QAAQ,CAACn+D,CAAD,CAAQ,CACvC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+B28D,EAAApzD,KAAA,CAAkBvJ,CAAlB,CADQ,CAP6B,CAlsCxD,CAsyBd,MAwaFo+D,QAAuB,CAACn1D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6B,CAE9C7lD,CAAA,CAAYe,CAAAwF,KAAZ,CAAJ,EACElF,CAAAN,KAAA,CAAa,MAAb,CAtwlBK,EAAErC,EAswlBP,CASF2C,EAAA+H,GAAA,CAAW,OAAX,CANe+a,QAAQ,CAACijC,CAAD,CAAK,CACtB/lD,CAAA,CAAQ,CAAR,CAAAw7D,QAAJ,EACEhX,CAAA2B,cAAA,CAAmBzmD,CAAAvC,MAAnB,CAA+B4oD,CAA/B,EAAqCA,CAAAluC,KAArC,CAFwB,CAM5B,CAEA2sC,EAAA8B,QAAA,CAAeC,QAAQ,EAAG,CAExBvmD,CAAA,CAAQ,CAAR,CAAAw7D,QAAA,CADY97D,CAAAvC,MACZ,EAA+BqnD,CAAAyB,WAFP,CAK1BvmD,EAAAkxB,SAAA,CAAc,OAAd,CAAuB4zB,CAAA8B,QAAvB,CAnBkD,CA9sCpC,CA01Bd,SAuZFmV,QAA0B,CAACr1D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6BrwC,CAA7B,CAAuCpC,CAAvC,CAAiDU,CAAjD,CAA0Dc,CAA1D,CAAkE,CAC1F,IAAImoD,EAAYzS,EAAA,CAAkB11C,CAAlB,CAA0BnN,CAA1B,CAAiC,aAAjC,CAAgD1G,CAAAi8D,YAAhD,CAAkE,CAAA,CAAlE,CAAhB,CACIC,EAAa3S,EAAA,CAAkB11C,CAAlB,CAA0BnN,CAA1B,CAAiC,cAAjC,CAAiD1G,CAAAm8D,aAAjD,CAAoE,CAAA,CAApE,CAMjB77D,EAAA+H,GAAA,CAAW,OAAX;AAJe+a,QAAQ,CAACijC,CAAD,CAAK,CAC1BvB,CAAA2B,cAAA,CAAmBnmD,CAAA,CAAQ,CAAR,CAAAw7D,QAAnB,CAAuCzV,CAAvC,EAA6CA,CAAAluC,KAA7C,CAD0B,CAI5B,CAEA2sC,EAAA8B,QAAA,CAAeC,QAAQ,EAAG,CACxBvmD,CAAA,CAAQ,CAAR,CAAAw7D,QAAA,CAAqBhX,CAAAyB,WADG,CAK1BzB,EAAAiB,SAAA,CAAgBoD,QAAQ,CAAC1rD,CAAD,CAAQ,CAC9B,MAAOA,EAAP,GAAiBu+D,CADa,CAIhClX,EAAAgB,YAAA3oD,KAAA,CAAsB,QAAQ,CAACM,CAAD,CAAQ,CACpC,MAAOsE,GAAA,CAAOtE,CAAP,CAAcu+D,CAAd,CAD6B,CAAtC,CAIAlX,EAAAyD,SAAAprD,KAAA,CAAmB,QAAQ,CAACM,CAAD,CAAQ,CACjC,MAAOA,EAAA,CAAQu+D,CAAR,CAAoBE,CADM,CAAnC,CAvB0F,CAjvC5E,CA41Bd,OAAUr9D,CA51BI,CA61Bd,OAAUA,CA71BI,CA81Bd,OAAUA,CA91BI,CA+1Bd,MAASA,CA/1BK,CAg2Bd,KAAQA,CAh2BM,CAhGhB,CA+/CIiO,GAAiB,CAAC,UAAD,CAAa,UAAb,CAAyB,SAAzB,CAAoC,QAApC,CACjB,QAAQ,CAACuF,CAAD,CAAWoC,CAAX,CAAqB1B,CAArB,CAA8Bc,CAA9B,CAAsC,CAChD,MAAO,CACLwV,SAAU,GADL,CAELD,QAAS,CAAC,UAAD,CAFJ,CAGL1C,KAAM,CACJ0I,IAAKA,QAAQ,CAAC1oB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuBo8D,CAAvB,CAA8B,CACrCA,CAAA,CAAM,CAAN,CAAJ,EACE,CAACxB,EAAA,CAAUr6D,CAAA,CAAUP,CAAAmY,KAAV,CAAV,CAAD,EAAoCyiD,EAAAtlC,KAApC,EAAoD5uB,CAApD,CAA2DpG,CAA3D,CAAoEN,CAApE,CAA0Eo8D,CAAA,CAAM,CAAN,CAA1E,CAAoF3nD,CAApF,CACoDpC,CADpD,CAC8DU,CAD9D,CACuEc,CADvE,CAFuC,CADvC,CAHD,CADyC,CAD7B,CA//CrB,CA+gDIm2C,GAAc,UA/gDlB,CAghDIC,GAAgB,YAhhDpB,CAihDI9E,GAAiB,aAjhDrB;AAkhDIC,GAAc,UAlhDlB,CAqhDIiF,GAAgB,YArhDpB,CAmtDIgS,GAAoB,CAAC,QAAD,CAAW,mBAAX,CAAgC,QAAhC,CAA0C,UAA1C,CAAsD,QAAtD,CAAgE,UAAhE,CAA4E,UAA5E,CAAwF,YAAxF,CAAsG,IAAtG,CAA4G,cAA5G,CACpB,QAAQ,CAAClsC,CAAD,CAAStd,CAAT,CAA4Bwa,CAA5B,CAAmCtD,CAAnC,CAA6ClW,CAA7C,CAAqD1B,CAArD,CAA+D8C,CAA/D,CAAyElB,CAAzE,CAAqFE,CAArF,CAAyFhB,CAAzF,CAAuG,CAEjH,IAAA6zC,YAAA,CADA,IAAAP,WACA,CADkBp/B,MAAA2gC,IAElB,KAAAe,YAAA,CAAmB,EACnB,KAAAyT,iBAAA,CAAwB,EACxB,KAAA/T,SAAA,CAAgB,EAChB,KAAAzC,YAAA,CAAmB,EACnB,KAAAyW,qBAAA,CAA4B,EAC5B,KAAAC,WAAA,CAAkB,CAAA,CAClB,KAAAC,SAAA,CAAgB,CAAA,CAChB,KAAA9Y,UAAA,CAAiB,CAAA,CACjB,KAAAD,OAAA,CAAc,CAAA,CACd,KAAAE,OAAA,CAAc,CAAA,CACd,KAAAC,SAAA,CAAgB,CAAA,CAChB,KAAAP,OAAA,CAAc,EACd,KAAAC,UAAA,CAAiB,EACjB,KAAAC,SAAA,CAAgBznD,CAChB,KAAA0nD,MAAA,CAAaxwC,CAAA,CAAaoa,CAAA7nB,KAAb;AAA2B,EAA3B,CAA+B,CAAA,CAA/B,CAAA,CAAsC2qB,CAAtC,CAjBoG,KAoB7GusC,EAAgB7oD,CAAA,CAAOwZ,CAAA7c,QAAP,CApB6F,CAqB7GmsD,EAAkB,IArB2F,CAsB7G7X,EAAO,IAtBsG,CAwB7G8X,EAAaA,QAAmB,EAAG,CACrC,IAAIC,EAAaH,CAAA,CAAcvsC,CAAd,CACb20B,EAAAsD,SAAJ,EAAqBtD,CAAAsD,SAAA0U,aAArB,EAAmDjgE,CAAA,CAAWggE,CAAX,CAAnD,GACEA,CADF,CACeA,CAAA,EADf,CAGA,OAAOA,EAL8B,CAxB0E,CAgC7GE,EAAaA,QAAmB,CAACtmC,CAAD,CAAW,CAC7C,IAAIqmC,CACAhY,EAAAsD,SAAJ,EAAqBtD,CAAAsD,SAAA0U,aAArB,EACIjgE,CAAA,CAAWigE,CAAX,CAA0BJ,CAAA,CAAcvsC,CAAd,CAA1B,CADJ,CAGE2sC,CAAA,CAAahY,CAAAgC,YAAb,CAHF,CAKE4V,CAAAnrC,OAAA,CAAqBpB,CAArB,CAA6B20B,CAAAgC,YAA7B,CAP2C,CAW/C,KAAAkW,aAAA,CAAoBC,QAAQ,CAAC72C,CAAD,CAAU,CACpC0+B,CAAAsD,SAAA,CAAgBhiC,CAEhB,IAAI,EAACs2C,CAAAnrC,OAAD,EAA2BnL,CAA3B,EAAuCA,CAAA02C,aAAvC,CAAJ,CACE,KAAMrU,GAAA,CAAe,WAAf,CACFp7B,CAAA7c,QADE,CACahN,EAAA,CAAYumB,CAAZ,CADb,CAAN,CAJkC,CA6BtC,KAAA68B,QAAA,CAAe/nD,CAmBf,KAAAknD,SAAA,CAAgBmX,QAAQ,CAACz/D,CAAD,CAAQ,CAC9B,MAAOwB,EAAA,CAAYxB,CAAZ,CAAP,EAAuC,EAAvC,GAA6BA,CAA7B,EAAuD,IAAvD,GAA6CA,CAA7C,EAA+DA,CAA/D,GAAyEA,CAD3C,CA3FiF,KA+F7G0lD,EAAap5B,CAAAthB,cAAA,CAAuB,iBAAvB,CAAb06C,EAA0DE,EA/FmD,CAgG7G8Z,EAAyB,CAqB7BtY,GAAA,CAAqB,CACnBC,KAAM,IADa,CAEnB/6B,SAAUA,CAFS;AAGnBg7B,IAAKA,QAAQ,CAAC7C,CAAD,CAASlZ,CAAT,CAAmB,CAC9BkZ,CAAA,CAAOlZ,CAAP,CAAA,CAAmB,CAAA,CADW,CAHb,CAMnBgc,MAAOA,QAAQ,CAAC9C,CAAD,CAASlZ,CAAT,CAAmB,CAChC,OAAOkZ,CAAA,CAAOlZ,CAAP,CADyB,CANf,CASnBma,WAAYA,CATO,CAUnBhxC,SAAUA,CAVS,CAArB,CAwBA,KAAAkzC,aAAA,CAAoB+X,QAAS,EAAG,CAC9BtY,CAAApB,OAAA,CAAc,CAAA,CACdoB,EAAAnB,UAAA,CAAiB,CAAA,CACjBxxC,EAAAwlB,YAAA,CAAqB5N,CAArB,CAA+Bq7B,EAA/B,CACAjzC,EAAA8X,SAAA,CAAkBF,CAAlB,CAA4Bo7B,EAA5B,CAJ8B,CAmBhC,KAAAM,cAAA,CAAqB4X,QAAQ,EAAG,CAC9BvY,CAAA2X,SAAA,CAAgB,CAAA,CAChB3X,EAAA0X,WAAA,CAAkB,CAAA,CAClBrqD,EAAAozC,SAAA,CAAkBx7B,CAAlB,CApWkBuzC,cAoWlB,CAnWgBC,YAmWhB,CAH8B,CAkBhC,KAAAC,YAAA,CAAmBC,QAAQ,EAAG,CAC5B3Y,CAAA2X,SAAA,CAAgB,CAAA,CAChB3X,EAAA0X,WAAA,CAAkB,CAAA,CAClBrqD,EAAAozC,SAAA,CAAkBx7B,CAAlB,CArXgBwzC,YAqXhB,CAtXkBD,cAsXlB,CAH4B,CAiE9B,KAAAtZ,mBAAA,CAA0B0Z,QAAQ,EAAG,CACnCzoD,CAAA6Q,OAAA,CAAgB62C,CAAhB,CACA7X,EAAAyB,WAAA,CAAkBzB,CAAA6Y,yBAClB7Y,EAAA8B,QAAA,EAHmC,CAarC,KAAAmC,UAAA,CAAiB6U,QAAQ,EAAG,CAEtBx+D,CAAA,CAAS0lD,CAAAgC,YAAT,CAAJ;AAAkC9P,KAAA,CAAM8N,CAAAgC,YAAN,CAAlC,EAGA,IAAA+W,mBAAA,EAL0B,CAQ5B,KAAAC,gBAAA,CAAuBC,QAAQ,CAACC,CAAD,CAAanB,CAAb,CAAyBoB,CAAzB,CAAoCC,CAApC,CAAkD,CAkC/EC,QAASA,EAAqB,EAAG,CAC/B,IAAIC,EAAsB,CAAA,CAC1B3hE,EAAA,CAAQqoD,CAAA+D,YAAR,CAA0B,QAAQ,CAACwV,CAAD,CAAY74D,CAAZ,CAAkB,CAClD,IAAIrE,EAASk9D,CAAA,CAAUxB,CAAV,CAAsBoB,CAAtB,CACbG,EAAA,CAAsBA,CAAtB,EAA6Cj9D,CAC7CgpD,EAAA,CAAY3kD,CAAZ,CAAkBrE,CAAlB,CAHkD,CAApD,CAKA,OAAKi9D,EAAL,CAMO,CAAA,CANP,EACE3hE,CAAA,CAAQqoD,CAAAwX,iBAAR,CAA+B,QAAQ,CAACl9B,CAAD,CAAI55B,CAAJ,CAAU,CAC/C2kD,CAAA,CAAY3kD,CAAZ,CAAkB,IAAlB,CAD+C,CAAjD,CAGO,CAAA,CAAA,CAJT,CAP+B,CAgBjC84D,QAASA,EAAsB,EAAG,CAChC,IAAIC,EAAoB,EAAxB,CACIC,EAAW,CAAA,CACf/hE,EAAA,CAAQqoD,CAAAwX,iBAAR,CAA+B,QAAQ,CAAC+B,CAAD,CAAY74D,CAAZ,CAAkB,CACvD,IAAI63B,EAAUghC,CAAA,CAAUxB,CAAV,CAAsBoB,CAAtB,CACd,IAAmB5gC,CAAAA,CAAnB,EAxtmBQ,CAAAxgC,CAAA,CAwtmBWwgC,CAxtmBA3I,KAAX,CAwtmBR,CACE,KAAM+zB,GAAA,CAAe,kBAAf,CAC0EprB,CAD1E,CAAN,CAGF8sB,CAAA,CAAY3kD,CAAZ,CAAkBzJ,CAAlB,CACAwiE,EAAAphE,KAAA,CAAuBkgC,CAAA3I,KAAA,CAAa,QAAQ,EAAG,CAC7Cy1B,CAAA,CAAY3kD,CAAZ,CAAkB,CAAA,CAAlB,CAD6C,CAAxB,CAEpB,QAAQ,CAAC0c,CAAD,CAAQ,CACjBs8C,CAAA,CAAW,CAAA,CACXrU,EAAA,CAAY3kD,CAAZ,CAAkB,CAAA,CAAlB,CAFiB,CAFI,CAAvB,CAPuD,CAAzD,CAcK+4D,EAAAniE,OAAL,CAGE6X,CAAAkJ,IAAA,CAAOohD,CAAP,CAAA7pC,KAAA,CAA+B,QAAQ,EAAG,CACxC+pC,CAAA,CAAeD,CAAf,CADwC,CAA1C,CAEG3/D,CAFH,CAHF,CACE4/D,CAAA,CAAe,CAAA,CAAf,CAlB8B,CA0BlCtU,QAASA,EAAW,CAAC3kD,CAAD,CAAOukD,CAAP,CAAgB,CAC9B2U,CAAJ,GAA6BvB,CAA7B,EACErY,CAAAF,aAAA,CAAkBp/C,CAAlB;AAAwBukD,CAAxB,CAFgC,CAMpC0U,QAASA,EAAc,CAACD,CAAD,CAAW,CAC5BE,CAAJ,GAA6BvB,CAA7B,EAEEe,CAAA,CAAaM,CAAb,CAH8B,CAjFlCrB,CAAA,EACA,KAAIuB,EAAuBvB,CAa3BwB,UAA2B,CAACX,CAAD,CAAa,CACtC,IAAIY,EAAW9Z,CAAAwD,aAAXsW,EAAgC,OACpC,IAAIZ,CAAJ,GAAmBjiE,CAAnB,CACEouD,CAAA,CAAYyU,CAAZ,CAAsB,IAAtB,CADF,KAIE,IADAzU,CAAA,CAAYyU,CAAZ,CAAsBZ,CAAtB,CACKA,CAAAA,CAAAA,CAAL,CAOE,MANAvhE,EAAA,CAAQqoD,CAAA+D,YAAR,CAA0B,QAAQ,CAACzpB,CAAD,CAAI55B,CAAJ,CAAU,CAC1C2kD,CAAA,CAAY3kD,CAAZ,CAAkB,IAAlB,CAD0C,CAA5C,CAMO,CAHP/I,CAAA,CAAQqoD,CAAAwX,iBAAR,CAA+B,QAAQ,CAACl9B,CAAD,CAAI55B,CAAJ,CAAU,CAC/C2kD,CAAA,CAAY3kD,CAAZ,CAAkB,IAAlB,CAD+C,CAAjD,CAGO,CAAA,CAAA,CAGX,OAAO,CAAA,CAhB+B,CAAxCm5D,CAVK,CAAmBX,CAAnB,CAAL,CAIKG,CAAA,EAAL,CAIAG,CAAA,EAJA,CACEG,CAAA,CAAe,CAAA,CAAf,CALF,CACEA,CAAA,CAAe,CAAA,CAAf,CAN6E,CAqGjF,KAAAta,iBAAA,CAAwB0a,QAAQ,EAAG,CACjC,IAAIZ,EAAYnZ,CAAAyB,WAEhBtxC,EAAA6Q,OAAA,CAAgB62C,CAAhB,CAKA,IAAI7X,CAAA6Y,yBAAJ,GAAsCM,CAAtC,EAAkE,EAAlE,GAAoDA,CAApD,EAAyEnZ,CAAA0B,sBAAzE,CAGA1B,CAAA6Y,yBAUA,CAVgCM,CAUhC,CAPInZ,CAAAnB,UAOJ,GANEmB,CAAApB,OAIA,CAJc,CAAA,CAId,CAHAoB,CAAAnB,UAGA,CAHiB,CAAA,CAGjB,CAFAxxC,CAAAwlB,YAAA,CAAqB5N,CAArB,CAA+Bo7B,EAA/B,CAEA,CADAhzC,CAAA8X,SAAA,CAAkBF,CAAlB,CAA4Bq7B,EAA5B,CACA,CAAAjC,CAAA8B,UAAA,EAEF;AAAA,IAAA4Y,mBAAA,EArBiC,CAwBnC,KAAAA,mBAAA,CAA0BiB,QAAQ,EAAG,CACnC,IAAIb,EAAYnZ,CAAA6Y,yBAAhB,CACId,EAAaoB,CADjB,CAEIc,EAAc9/D,CAAA,CAAY49D,CAAZ,CAAA,CAA0B9gE,CAA1B,CAAsC,CAAA,CAExD,IAAIgjE,CAAJ,CACE,IAAQ,IAAAzhE,EAAI,CAAZ,CAAeA,CAAf,CAAmBwnD,CAAAyD,SAAAnsD,OAAnB,CAAyCkB,CAAA,EAAzC,CAEE,GADAu/D,CACI,CADS/X,CAAAyD,SAAA,CAAcjrD,CAAd,CAAA,CAAiBu/D,CAAjB,CACT,CAAA59D,CAAA,CAAY49D,CAAZ,CAAJ,CAA6B,CAC3BkC,CAAA,CAAc,CAAA,CACd,MAF2B,CAM7B3/D,CAAA,CAAS0lD,CAAAgC,YAAT,CAAJ,EAAkC9P,KAAA,CAAM8N,CAAAgC,YAAN,CAAlC,GAEEhC,CAAAgC,YAFF,CAEqB8V,CAAA,EAFrB,CAIA,KAAIoC,EAAiBla,CAAAgC,YAArB,CACImY,EAAena,CAAAsD,SAAf6W,EAAgCna,CAAAsD,SAAA6W,aAChCA,EAAJ,GACEna,CAAAgC,YAeA,CAfmB+V,CAenB,CAAI/X,CAAAgC,YAAJ,GAAyBkY,CAAzB,EACEla,CAAAoa,oBAAA,EAjBJ,CAIApa,EAAAgZ,gBAAA,CAAqBiB,CAArB,CAAkClC,CAAlC,CAA8CoB,CAA9C,CAAyD,QAAQ,CAACO,CAAD,CAAW,CACrES,CAAL,GAKEna,CAAAgC,YAMF,CANqB0X,CAAA,CAAW3B,CAAX,CAAwB9gE,CAM7C,CAAI+oD,CAAAgC,YAAJ,GAAyBkY,CAAzB,EACEla,CAAAoa,oBAAA,EAZF,CAD0E,CAA5E,CAxBmC,CA0CrC,KAAAA,oBAAA;AAA2BC,QAAQ,EAAG,CACpCpC,CAAA,CAAWjY,CAAAgC,YAAX,CACArqD,EAAA,CAAQqoD,CAAAyX,qBAAR,CAAmC,QAAQ,CAACn5C,CAAD,CAAW,CACpD,GAAI,CACFA,CAAA,EADE,CAEF,MAAMxf,CAAN,CAAS,CACTiP,CAAA,CAAkBjP,CAAlB,CADS,CAHyC,CAAtD,CAFoC,CAmDtC,KAAA6iD,cAAA,CAAqB2Y,QAAQ,CAAC3hE,CAAD,CAAQ8uD,CAAR,CAAiB,CAC5CzH,CAAAyB,WAAA,CAAkB9oD,CACbqnD,EAAAsD,SAAL,EAAsBiX,CAAAva,CAAAsD,SAAAiX,gBAAtB,EACEva,CAAAwa,0BAAA,CAA+B/S,CAA/B,CAH0C,CAO9C,KAAA+S,0BAAA,CAAiCC,QAAQ,CAAChT,CAAD,CAAU,CAAA,IAC7CiT,EAAgB,CAD6B,CAE7Cp5C,EAAU0+B,CAAAsD,SAGVhiC,EAAJ,EAAelnB,CAAA,CAAUknB,CAAAq5C,SAAV,CAAf,GACEA,CACA,CADWr5C,CAAAq5C,SACX,CAAIrgE,CAAA,CAASqgE,CAAT,CAAJ,CACED,CADF,CACkBC,CADlB,CAEWrgE,CAAA,CAASqgE,CAAA,CAASlT,CAAT,CAAT,CAAJ,CACLiT,CADK,CACWC,CAAA,CAASlT,CAAT,CADX,CAEIntD,CAAA,CAASqgE,CAAA,CAAS,SAAT,CAAT,CAFJ,GAGLD,CAHK,CAGWC,CAAA,CAAS,SAAT,CAHX,CAJT,CAWAxqD,EAAA6Q,OAAA,CAAgB62C,CAAhB,CACI6C,EAAJ,CACE7C,CADF,CACoB1nD,CAAA,CAAS,QAAQ,EAAG,CACpC6vC,CAAAX,iBAAA,EADoC,CAApB,CAEfqb,CAFe,CADpB,CAIWzrD,CAAAwqB,QAAJ,CACLumB,CAAAX,iBAAA,EADK,CAGLh0B,CAAAvpB,OAAA,CAAc,QAAQ,EAAG,CACvBk+C,CAAAX,iBAAA,EADuB,CAAzB,CAxB+C,CAsCnDh0B,EAAAzwB,OAAA,CAAcggE,QAAqB,EAAG,CACpC,IAAI7C;AAAaD,CAAA,EAIjB,IAAIC,CAAJ,GAAmB/X,CAAAgC,YAAnB,CAAqC,CACnChC,CAAAgC,YAAA,CAAmB+V,CAMnB,KAPmC,IAG/B8C,EAAa7a,CAAAgB,YAHkB,CAI/Bj6B,EAAM8zC,CAAAvjE,OAJyB,CAM/B6hE,EAAYpB,CAChB,CAAMhxC,CAAA,EAAN,CAAA,CACEoyC,CAAA,CAAY0B,CAAA,CAAW9zC,CAAX,CAAA,CAAgBoyC,CAAhB,CAEVnZ,EAAAyB,WAAJ,GAAwB0X,CAAxB,GACEnZ,CAAAyB,WAGA,CAHkBzB,CAAA6Y,yBAGlB,CAHkDM,CAGlD,CAFAnZ,CAAA8B,QAAA,EAEA,CAAA9B,CAAAgZ,gBAAA,CAAqB/hE,CAArB,CAAgC8gE,CAAhC,CAA4CoB,CAA5C,CAAuDp/D,CAAvD,CAJF,CAVmC,CAkBrC,MAAOg+D,EAvB6B,CAAtC,CA/gBiH,CAD3F,CAntDxB,CA45EIpsD,GAAmBA,QAAQ,EAAG,CAChC,MAAO,CACL4Y,SAAU,GADL,CAELD,QAAS,CAAC,SAAD,CAAY,QAAZ,CAAsB,kBAAtB,CAFJ,CAGL5gB,WAAY6zD,EAHP,CAOLlzC,SAAU,CAPL,CAQLxiB,QAASi5D,QAAuB,CAACt/D,CAAD,CAAU,CAExCA,CAAA2pB,SAAA,CAAiBk7B,EAAjB,CAAAl7B,SAAA,CAp5BgBqzC,cAo5BhB,CAAArzC,SAAA,CAAoE+/B,EAApE,CAEA,OAAO,CACL56B,IAAKywC,QAAuB,CAACn5D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuBo8D,CAAvB,CAA8B,CAAA,IACpD0D,EAAY1D,CAAA,CAAM,CAAN,CADwC,CAEpD2D,EAAW3D,CAAA,CAAM,CAAN,CAAX2D,EAAuB1c,EAE3Byc,EAAA9C,aAAA,CAAuBZ,CAAA,CAAM,CAAN,CAAvB,EAAmCA,CAAA,CAAM,CAAN,CAAAhU,SAAnC,CAGA2X,EAAAhc,YAAA,CAAqB+b,CAArB,CAEA9/D,EAAAkxB,SAAA,CAAc,MAAd;AAAsB,QAAQ,CAACuF,CAAD,CAAW,CACnCqpC,CAAArc,MAAJ,GAAwBhtB,CAAxB,EACEspC,CAAAzb,gBAAA,CAAyBwb,CAAzB,CAAoCrpC,CAApC,CAFqC,CAAzC,CAMA/vB,EAAAkrB,IAAA,CAAU,UAAV,CAAsB,QAAQ,EAAG,CAC/BmuC,CAAArb,eAAA,CAAwBob,CAAxB,CAD+B,CAAjC,CAfwD,CADrD,CAoBLzwC,KAAM2wC,QAAwB,CAACt5D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuBo8D,CAAvB,CAA8B,CAC1D,IAAI0D,EAAY1D,CAAA,CAAM,CAAN,CAChB,IAAI0D,CAAA1X,SAAJ,EAA0B0X,CAAA1X,SAAA6X,SAA1B,CACE3/D,CAAA+H,GAAA,CAAWy3D,CAAA1X,SAAA6X,SAAX,CAAwC,QAAQ,CAAC5Z,CAAD,CAAK,CACnDyZ,CAAAR,0BAAA,CAAoCjZ,CAApC,EAA0CA,CAAAluC,KAA1C,CADmD,CAArD,CAKF7X,EAAA+H,GAAA,CAAW,MAAX,CAAmB,QAAQ,CAACg+C,CAAD,CAAK,CAC1ByZ,CAAArD,SAAJ,EAEA/1D,CAAAE,OAAA,CAAa,QAAQ,EAAG,CACtBk5D,CAAAtC,YAAA,EADsB,CAAxB,CAH8B,CAAhC,CAR0D,CApBvD,CAJiC,CARrC,CADyB,CA55ElC,CAshFI3sD,GAAoB7R,EAAA,CAAQ,CAC9BqqB,SAAU,GADoB,CAE9BD,QAAS,SAFqB,CAG9B1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6B,CACzCA,CAAAyX,qBAAAp/D,KAAA,CAA+B,QAAQ,EAAG,CACxCuJ,CAAAqwC,MAAA,CAAY/2C,CAAA4Q,SAAZ,CADwC,CAA1C,CADyC,CAHb,CAAR,CAthFxB,CAiiFIM,GAAoBA,QAAQ,EAAG,CACjC,MAAO,CACLmY,SAAU,GADL,CAELD,QAAS,UAFJ;AAGL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQ2a,CAAR,CAAarhB,CAAb,CAAmB8kD,CAAnB,CAAyB,CAChCA,CAAL,GACA9kD,CAAAiR,SAMA,CANgB,CAAA,CAMhB,CAJA6zC,CAAA+D,YAAA53C,SAIA,CAJ4BivD,QAAQ,CAACziE,CAAD,CAAQ,CAC1C,MAAO,CAACuC,CAAAiR,SAAR,EAAyB,CAAC6zC,CAAAiB,SAAA,CAActoD,CAAd,CADgB,CAI5C,CAAAuC,CAAAkxB,SAAA,CAAc,UAAd,CAA0B,QAAQ,EAAG,CACnC4zB,CAAAiE,UAAA,EADmC,CAArC,CAPA,CADqC,CAHlC,CAD0B,CAjiFnC,CAqjFIh4C,GAAmBA,QAAQ,EAAG,CAChC,MAAO,CACLsY,SAAU,GADL,CAELD,QAAS,UAFJ,CAGL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQ2a,CAAR,CAAarhB,CAAb,CAAmB8kD,CAAnB,CAAyB,CACrC,GAAKA,CAAL,CAAA,CADqC,IAGjCr7B,CAHiC,CAGzB02C,EAAangE,CAAAgR,UAAbmvD,EAA+BngE,CAAA8Q,QAC3C9Q,EAAAkxB,SAAA,CAAc,SAAd,CAAyB,QAAQ,CAAC+mB,CAAD,CAAQ,CACnC17C,CAAA,CAAS07C,CAAT,CAAJ,EAAsC,CAAtC,CAAuBA,CAAA77C,OAAvB,GACE67C,CADF,CACU,IAAI32C,MAAJ,CAAW22C,CAAX,CADV,CAIA,IAAIA,CAAJ,EAAcjxC,CAAAixC,CAAAjxC,KAAd,CACE,KAAMhL,EAAA,CAAO,WAAP,CAAA,CAAoB,UAApB,CACqDmkE,CADrD,CAEJloB,CAFI,CAEGz0C,EAAA,CAAY6d,CAAZ,CAFH,CAAN,CAKFoI,CAAA,CAASwuB,CAAT,EAAkBl8C,CAClB+oD,EAAAiE,UAAA,EAZuC,CAAzC,CAeAjE,EAAA+D,YAAA/3C,QAAA,CAA2BsvD,QAAQ,CAAC3iE,CAAD,CAAQ,CACzC,MAAOqnD,EAAAiB,SAAA,CAActoD,CAAd,CAAP,EAA+BwB,CAAA,CAAYwqB,CAAZ,CAA/B,EAAsDA,CAAAziB,KAAA,CAAYvJ,CAAZ,CADb,CAlB3C,CADqC,CAHlC,CADyB,CArjFlC;AAolFI+T,GAAqBA,QAAQ,EAAG,CAClC,MAAO,CACL6X,SAAU,GADL,CAELD,QAAS,UAFJ,CAGL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQ2a,CAAR,CAAarhB,CAAb,CAAmB8kD,CAAnB,CAAyB,CACrC,GAAKA,CAAL,CAAA,CAEA,IAAIvzC,EAAY,CAChBvR,EAAAkxB,SAAA,CAAc,WAAd,CAA2B,QAAQ,CAACzzB,CAAD,CAAQ,CACzC8T,CAAA,CAAYjT,EAAA,CAAIb,CAAJ,CAAZ,EAA0B,CAC1BqnD,EAAAiE,UAAA,EAFyC,CAA3C,CAIAjE,EAAA+D,YAAAt3C,UAAA,CAA6B8uD,QAAQ,CAACxD,CAAD,CAAaoB,CAAb,CAAwB,CAC3D,MAAOnZ,EAAAiB,SAAA,CAAc8W,CAAd,CAAP,EAAoCoB,CAAA7hE,OAApC,EAAwDmV,CADG,CAP7D,CADqC,CAHlC,CAD2B,CAplFpC,CAumFIF,GAAqBA,QAAQ,EAAG,CAClC,MAAO,CACLgY,SAAU,GADL,CAELD,QAAS,UAFJ,CAGL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQ2a,CAAR,CAAarhB,CAAb,CAAmB8kD,CAAnB,CAAyB,CACrC,GAAKA,CAAL,CAAA,CAEA,IAAI1zC,EAAY,CAChBpR,EAAAkxB,SAAA,CAAc,WAAd,CAA2B,QAAQ,CAACzzB,CAAD,CAAQ,CACzC2T,CAAA,CAAY9S,EAAA,CAAIb,CAAJ,CAAZ,EAA0B,CAC1BqnD,EAAAiE,UAAA,EAFyC,CAA3C,CAIAjE,EAAA+D,YAAAz3C,UAAA,CAA6BkvD,QAAQ,CAACzD,CAAD,CAAaoB,CAAb,CAAwB,CAC3D,MAAOnZ,EAAAiB,SAAA,CAAc8W,CAAd,CAAP,EAAoCoB,CAAA7hE,OAApC,EAAwDgV,CADG,CAP7D,CADqC,CAHlC,CAD2B,CAvmFpC,CA6sFIT,GAAkBA,QAAQ,EAAG,CAC/B,MAAO,CACL0Y,SAAU,GADL,CAELF,SAAU,GAFL;AAGLC,QAAS,SAHJ,CAIL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6B,CAGzC,IAAIp0C,EAASpQ,CAAAN,KAAA,CAAaA,CAAAqtB,MAAA3c,OAAb,CAATA,EAA4C,IAAhD,CACI6vD,EAA6B,OAA7BA,GAAavgE,CAAAsmD,OADjB,CAEI1+C,EAAY24D,CAAA,CAAalpD,CAAA,CAAK3G,CAAL,CAAb,CAA4BA,CAiB5Co0C,EAAAyD,SAAAprD,KAAA,CAfYoG,QAAQ,CAAC06D,CAAD,CAAY,CAE9B,GAAI,CAAAh/D,CAAA,CAAYg/D,CAAZ,CAAJ,CAAA,CAEA,IAAI39C,EAAO,EAEP29C,EAAJ,EACExhE,CAAA,CAAQwhE,CAAA79D,MAAA,CAAgBwH,CAAhB,CAAR,CAAoC,QAAQ,CAACnK,CAAD,CAAQ,CAC9CA,CAAJ,EAAW6iB,CAAAnjB,KAAA,CAAUojE,CAAA,CAAalpD,CAAA,CAAK5Z,CAAL,CAAb,CAA2BA,CAArC,CADuC,CAApD,CAKF,OAAO6iB,EAVP,CAF8B,CAehC,CACAwkC,EAAAgB,YAAA3oD,KAAA,CAAsB,QAAQ,CAACM,CAAD,CAAQ,CACpC,MAAIjB,EAAA,CAAQiB,CAAR,CAAJ,CACSA,CAAAkH,KAAA,CAAW+L,CAAX,CADT,CAIO3U,CAL6B,CAAtC,CASA+oD,EAAAiB,SAAA,CAAgBoD,QAAQ,CAAC1rD,CAAD,CAAQ,CAC9B,MAAO,CAACA,CAAR,EAAiB,CAACA,CAAArB,OADY,CAhCS,CAJtC,CADwB,CA7sFjC,CA0vFIokE,GAAwB,oBA1vF5B,CA+yFI7uD,GAAmBA,QAAQ,EAAG,CAChC,MAAO,CACL0X,SAAU,GADL,CAELF,SAAU,GAFL,CAGLxiB,QAASA,QAAQ,CAACg1C,CAAD,CAAM8kB,CAAN,CAAe,CAC9B,MAAID,GAAAx5D,KAAA,CAA2By5D,CAAA/uD,QAA3B,CAAJ,CACSgvD,QAA4B,CAACh6D,CAAD,CAAQ2a,CAAR,CAAarhB,CAAb,CAAmB,CACpDA,CAAAi0B,KAAA,CAAU,OAAV,CAAmBvtB,CAAAqwC,MAAA,CAAY/2C,CAAA0R,QAAZ,CAAnB,CADoD,CADxD,CAKSivD,QAAoB,CAACj6D,CAAD;AAAQ2a,CAAR,CAAarhB,CAAb,CAAmB,CAC5C0G,CAAAhH,OAAA,CAAaM,CAAA0R,QAAb,CAA2BkvD,QAAyB,CAACnjE,CAAD,CAAQ,CAC1DuC,CAAAi0B,KAAA,CAAU,OAAV,CAAmBx2B,CAAnB,CAD0D,CAA5D,CAD4C,CANlB,CAH3B,CADyB,CA/yFlC,CAy9FIoU,GAA0BA,QAAQ,EAAG,CACvC,MAAO,CACLwX,SAAU,GADL,CAEL7gB,WAAY,CAAC,QAAD,CAAW,QAAX,CAAqB,QAAQ,CAAC2nB,CAAD,CAASC,CAAT,CAAiB,CACxD,IAAIywC,EAAO,IACX,KAAAzY,SAAA,CAAgBj4B,CAAA4mB,MAAA,CAAa3mB,CAAAxe,eAAb,CAEZ,KAAAw2C,SAAA6X,SAAJ,GAA+BlkE,CAA/B,EACE,IAAAqsD,SAAAiX,gBAEA,CAFgC,CAAA,CAEhC,CAAA,IAAAjX,SAAA6X,SAAA,CAAyB5oD,CAAA,CAAK,IAAA+wC,SAAA6X,SAAAh8D,QAAA,CAA+B02D,EAA/B,CAA+C,QAAQ,EAAG,CACtFkG,CAAAzY,SAAAiX,gBAAA,CAAgC,CAAA,CAChC,OAAO,GAF+E,CAA1D,CAAL,CAH3B,EAQE,IAAAjX,SAAAiX,gBARF,CAQkC,CAAA,CAZsB,CAA9C,CAFP,CADgC,CAz9FzC,CAyoGI1xD,GAAkB,CAAC,UAAD,CAAa,QAAQ,CAACmzD,CAAD,CAAW,CACpD,MAAO,CACLz3C,SAAU,IADL,CAEL1iB,QAASo6D,QAAsB,CAACC,CAAD,CAAkB,CAC/CF,CAAAlrC,kBAAA,CAA2BorC,CAA3B,CACA,OAAOC,SAAmB,CAACv6D,CAAD;AAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAC/C8gE,CAAAhrC,iBAAA,CAA0Bx1B,CAA1B,CAAmCN,CAAA0N,OAAnC,CACApN,EAAA,CAAUA,CAAA,CAAQ,CAAR,CACVoG,EAAAhH,OAAA,CAAaM,CAAA0N,OAAb,CAA0BwzD,QAA0B,CAACzjE,CAAD,CAAQ,CAC1D6C,CAAA4W,YAAA,CAAsBzZ,CAAA,GAAU1B,CAAV,CAAsB,EAAtB,CAA2B0B,CADS,CAA5D,CAH+C,CAFF,CAF5C,CAD6C,CAAhC,CAzoGtB,CA6sGIsQ,GAA0B,CAAC,cAAD,CAAiB,UAAjB,CAA6B,QAAQ,CAACkF,CAAD,CAAe6tD,CAAf,CAAyB,CAC1F,MAAO,CACLn6D,QAASw6D,QAA8B,CAACH,CAAD,CAAkB,CACvDF,CAAAlrC,kBAAA,CAA2BorC,CAA3B,CACA,OAAOI,SAA2B,CAAC16D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACnDu1B,CAAAA,CAAgBtiB,CAAA,CAAa3S,CAAAN,KAAA,CAAaA,CAAAqtB,MAAAvf,eAAb,CAAb,CACpBgzD,EAAAhrC,iBAAA,CAA0Bx1B,CAA1B,CAAmCi1B,CAAAQ,YAAnC,CACAz1B,EAAA,CAAUA,CAAA,CAAQ,CAAR,CACVN,EAAAkxB,SAAA,CAAc,gBAAd,CAAgC,QAAQ,CAACzzB,CAAD,CAAQ,CAC9C6C,CAAA4W,YAAA,CAAsBzZ,CAAA,GAAU1B,CAAV,CAAsB,EAAtB,CAA2B0B,CADH,CAAhD,CAJuD,CAFF,CADpD,CADmF,CAA9D,CA7sG9B,CA8wGIoQ,GAAsB,CAAC,MAAD,CAAS,QAAT,CAAmB,UAAnB,CAA+B,QAAQ,CAACwG,CAAD,CAAOR,CAAP,CAAeitD,CAAf,CAAyB,CACxF,MAAO,CACLz3C,SAAU,GADL,CAEL1iB,QAAS06D,QAA0B,CAACC,CAAD,CAAWptC,CAAX,CAAmB,CACpD,IAAIqtC,EAAmB1tD,CAAA,CAAOqgB,CAAAtmB,WAAP,CAAvB,CACI4zD,EAAkB3tD,CAAA,CAAOqgB,CAAAtmB,WAAP;AAA0B6zD,QAAuB,CAAChkE,CAAD,CAAQ,CAC7E,MAAO6B,CAAC7B,CAAD6B,EAAU,EAAVA,UAAA,EADsE,CAAzD,CAGtBwhE,EAAAlrC,kBAAA,CAA2B0rC,CAA3B,CAEA,OAAOI,SAAuB,CAACh7D,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACnD8gE,CAAAhrC,iBAAA,CAA0Bx1B,CAA1B,CAAmCN,CAAA4N,WAAnC,CAEAlH,EAAAhH,OAAA,CAAa8hE,CAAb,CAA8BG,QAA8B,EAAG,CAG7DrhE,CAAAyD,KAAA,CAAasQ,CAAAutD,eAAA,CAAoBL,CAAA,CAAiB76D,CAAjB,CAApB,CAAb,EAA6D,EAA7D,CAH6D,CAA/D,CAHmD,CAPD,CAFjD,CADiF,CAAhE,CA9wG1B,CAuiHIuH,GAAmBs8C,EAAA,CAAe,EAAf,CAAmB,CAAA,CAAnB,CAviHvB,CAulHIl8C,GAAsBk8C,EAAA,CAAe,KAAf,CAAsB,CAAtB,CAvlH1B,CAuoHIp8C,GAAuBo8C,EAAA,CAAe,MAAf,CAAuB,CAAvB,CAvoH3B,CAisHIh8C,GAAmBy0C,EAAA,CAAY,CACjCr8C,QAASA,QAAQ,CAACrG,CAAD,CAAUN,CAAV,CAAgB,CAC/BA,CAAAi0B,KAAA,CAAU,SAAV,CAAqBl4B,CAArB,CACAuE,EAAAq3B,YAAA,CAAoB,UAApB,CAF+B,CADA,CAAZ,CAjsHvB,CA06HIlpB,GAAwB,CAAC,QAAQ,EAAG,CACtC,MAAO,CACL4a,SAAU,GADL,CAEL3iB,MAAO,CAAA,CAFF,CAGL8B,WAAY,GAHP,CAIL2gB,SAAU,GAJL,CAD+B,CAAZ,CA16H5B,CAsoIInX,GAAoB,EAtoIxB,CA2oII6vD,GAAmB,CACrB,KAAQ,CAAA,CADa,CAErB,MAAS,CAAA,CAFY,CAIvBplE,EAAA,CACE,6IAAA,MAAA,CAAA,GAAA,CADF;AAEE,QAAQ,CAAC06C,CAAD,CAAY,CAClB,IAAIpvB,EAAgBwF,EAAA,CAAmB,KAAnB,CAA2B4pB,CAA3B,CACpBnlC,GAAA,CAAkB+V,CAAlB,CAAA,CAAmC,CAAC,QAAD,CAAW,YAAX,CAAyB,QAAQ,CAAClU,CAAD,CAASE,CAAT,CAAqB,CACvF,MAAO,CACLsV,SAAU,GADL,CAEL1iB,QAASA,QAAQ,CAACojB,CAAD,CAAW/pB,CAAX,CAAiB,CAChC,IAAI2C,EAAKkR,CAAA,CAAO7T,CAAA,CAAK+nB,CAAL,CAAP,CACT,OAAO+5C,SAAuB,CAACp7D,CAAD,CAAQpG,CAAR,CAAiB,CAC7CA,CAAA+H,GAAA,CAAW8uC,CAAX,CAAsB,QAAQ,CAAC97B,CAAD,CAAQ,CACpC,IAAI0I,EAAWA,QAAQ,EAAG,CACxBphB,CAAA,CAAG+D,CAAH,CAAU,CAACq7D,OAAO1mD,CAAR,CAAV,CADwB,CAGtBwmD,GAAA,CAAiB1qB,CAAjB,CAAJ,EAAmCpjC,CAAAwqB,QAAnC,CACE73B,CAAAjH,WAAA,CAAiBskB,CAAjB,CADF,CAGErd,CAAAE,OAAA,CAAamd,CAAb,CAPkC,CAAtC,CAD6C,CAFf,CAF7B,CADgF,CAAtD,CAFjB,CAFtB,CA+fA,KAAIhV,GAAgB,CAAC,UAAD,CAAa,QAAQ,CAACoD,CAAD,CAAW,CAClD,MAAO,CACL+b,aAAc,CAAA,CADT,CAELhC,WAAY,SAFP,CAGL/C,SAAU,GAHL,CAILwD,SAAU,CAAA,CAJL,CAKLtD,SAAU,GALL,CAMLuJ,MAAO,CAAA,CANF,CAOLlM,KAAMA,QAAS,CAACyJ,CAAD,CAASpG,CAAT,CAAmBsD,CAAnB,CAA0By3B,CAA1B,CAAgCz0B,CAAhC,CAA6C,CAAA,IACpDtkB,CADoD,CAC7Cyf,CAD6C,CACjCw2C,CACvB7xC,EAAAzwB,OAAA,CAAc2tB,CAAAve,KAAd,CAA0BmzD,QAAwB,CAACxkE,CAAD,CAAQ,CAEpDA,CAAJ,CACO+tB,CADP,EAEI6E,CAAA,CAAY,QAAS,CAAC3sB,CAAD,CAAQw+D,CAAR,CAAkB,CACrC12C,CAAA,CAAa02C,CACbx+D,EAAA,CAAMA,CAAAtH,OAAA,EAAN,CAAA,CAAwBN,CAAA+2B,cAAA,CAAuB,aAAvB;AAAuCxF,CAAAve,KAAvC,CAAoD,GAApD,CAIxB/C,EAAA,CAAQ,CACNrI,MAAOA,CADD,CAGRyO,EAAAo+C,MAAA,CAAe7sD,CAAf,CAAsBqmB,CAAArrB,OAAA,EAAtB,CAAyCqrB,CAAzC,CATqC,CAAvC,CAFJ,EAeMi4C,CAQJ,GAPEA,CAAAz6C,OAAA,EACA,CAAAy6C,CAAA,CAAmB,IAMrB,EAJIx2C,CAIJ,GAHEA,CAAAviB,SAAA,EACA,CAAAuiB,CAAA,CAAa,IAEf,EAAIzf,CAAJ,GACEi2D,CAIA,CAJmBh4D,EAAA,CAAc+B,CAAArI,MAAd,CAInB,CAHAyO,CAAAq+C,MAAA,CAAewR,CAAf,CAAAttC,KAAA,CAAsC,QAAQ,EAAG,CAC/CstC,CAAA,CAAmB,IAD4B,CAAjD,CAGA,CAAAj2D,CAAA,CAAQ,IALV,CAvBF,CAFwD,CAA1D,CAFwD,CAPvD,CAD2C,CAAhC,CAApB,CAkOIkD,GAAqB,CAAC,kBAAD,CAAqB,eAArB,CAAsC,UAAtC,CAAkD,MAAlD,CACP,QAAQ,CAAC4F,CAAD,CAAqB5C,CAArB,CAAsCE,CAAtC,CAAkDkC,CAAlD,CAAwD,CAChF,MAAO,CACLgV,SAAU,KADL,CAELF,SAAU,GAFL,CAGLwD,SAAU,CAAA,CAHL,CAILT,WAAY,SAJP,CAKL1jB,WAAYvB,EAAApI,KALP,CAML8H,QAASA,QAAQ,CAACrG,CAAD,CAAUN,CAAV,CAAgB,CAAA,IAC3BmiE,EAASniE,CAAAgP,UAATmzD,EAA2BniE,CAAA6B,IADA,CAE3BugE,EAAYpiE,CAAA2gC,OAAZyhC,EAA2B,EAFA,CAG3BC,EAAgBriE,CAAAsiE,WAEpB,OAAO,SAAQ,CAAC57D,CAAD,CAAQqjB,CAAR,CAAkBsD,CAAlB,CAAyBy3B,CAAzB,CAA+Bz0B,CAA/B,CAA4C,CAAA,IACrDkyC,EAAgB,CADqC,CAErD7qB,CAFqD,CAGrD8qB,CAHqD,CAIrDC,CAJqD,CAMrDC,EAA4BA,QAAQ,EAAG,CACtCF,CAAH,GACEA,CAAAj7C,OAAA,EACA,CAAAi7C,CAAA,CAAkB,IAFpB,CAIG9qB,EAAH,GACEA,CAAAzuC,SAAA,EACA;AAAAyuC,CAAA,CAAe,IAFjB,CAIG+qB,EAAH,GACEtwD,CAAAq+C,MAAA,CAAeiS,CAAf,CAAA/tC,KAAA,CAAoC,QAAQ,EAAG,CAC7C8tC,CAAA,CAAkB,IAD2B,CAA/C,CAIA,CADAA,CACA,CADkBC,CAClB,CAAAA,CAAA,CAAiB,IALnB,CATyC,CAkB3C/7D,EAAAhH,OAAA,CAAa2U,CAAAsuD,mBAAA,CAAwBR,CAAxB,CAAb,CAA8CS,QAA6B,CAAC/gE,CAAD,CAAM,CAC/E,IAAIghE,EAAiBA,QAAQ,EAAG,CAC1B,CAAA3jE,CAAA,CAAUmjE,CAAV,CAAJ,EAAkCA,CAAlC,EAAmD,CAAA37D,CAAAqwC,MAAA,CAAYsrB,CAAZ,CAAnD,EACEpwD,CAAA,EAF4B,CAAhC,CAKI6wD,EAAe,EAAEP,CAEjB1gE,EAAJ,EAGEgT,CAAA,CAAiBhT,CAAjB,CAAsB,CAAA,CAAtB,CAAA6yB,KAAA,CAAiC,QAAQ,CAACwH,CAAD,CAAW,CAClD,GAAI4mC,CAAJ,GAAqBP,CAArB,CAAA,CACA,IAAIL,EAAWx7D,CAAAqlB,KAAA,EACf+4B,EAAAhzB,SAAA,CAAgBoK,CAQZx4B,EAAAA,CAAQ2sB,CAAA,CAAY6xC,CAAZ,CAAsB,QAAQ,CAACx+D,CAAD,CAAQ,CAChDg/D,CAAA,EACAvwD,EAAAo+C,MAAA,CAAe7sD,CAAf,CAAsB,IAAtB,CAA4BqmB,CAA5B,CAAA2K,KAAA,CAA2CmuC,CAA3C,CAFgD,CAAtC,CAKZnrB,EAAA,CAAewqB,CACfO,EAAA,CAAiB/+D,CAEjBg0C,EAAAH,MAAA,CAAmB,uBAAnB,CAA4C11C,CAA5C,CACA6E,EAAAqwC,MAAA,CAAYqrB,CAAZ,CAnBA,CADkD,CAApD,CAqBG,QAAQ,EAAG,CACRU,CAAJ,GAAqBP,CAArB,GACEG,CAAA,EACA,CAAAh8D,CAAA6wC,MAAA,CAAY,sBAAZ,CAAoC11C,CAApC,CAFF,CADY,CArBd,CA2BA,CAAA6E,CAAA6wC,MAAA,CAAY,0BAAZ,CAAwC11C,CAAxC,CA9BF,GAgCE6gE,CAAA,EACA,CAAA5d,CAAAhzB,SAAA,CAAgB,IAjClB,CAR+E,CAAjF,CAxByD,CAL5B,CAN5B,CADyE,CADzD,CAlOzB,CA6TIhgB,GAAgC,CAAC,UAAD,CAClC,QAAQ,CAACgvD,CAAD,CAAW,CACjB,MAAO,CACLz3C,SAAU,KADL;AAELF,SAAW,IAFN,CAGLC,QAAS,WAHJ,CAIL1C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQqjB,CAAR,CAAkBsD,CAAlB,CAAyBy3B,CAAzB,CAA+B,CACvC,KAAA99C,KAAA,CAAW+iB,CAAA,CAAS,CAAT,CAAAzqB,SAAA,EAAX,CAAJ,EAIEyqB,CAAApmB,MAAA,EACA,CAAAm9D,CAAA,CAAS7qD,EAAA,CAAoB6uC,CAAAhzB,SAApB,CAAmCh2B,CAAnC,CAAAkb,WAAT,CAAA,CAAkEtQ,CAAlE,CACIq8D,QAA8B,CAACr/D,CAAD,CAAQ,CACxCqmB,CAAAjmB,OAAA,CAAgBJ,CAAhB,CADwC,CAD1C,CAGG3H,CAHH,CAGcA,CAHd,CAGyBguB,CAHzB,CALF,GAYAA,CAAAhmB,KAAA,CAAc+gD,CAAAhzB,SAAd,CACA,CAAAgvC,CAAA,CAAS/2C,CAAAiJ,SAAA,EAAT,CAAA,CAA8BtsB,CAA9B,CAbA,CAD2C,CAJxC,CADU,CADe,CA7TpC,CA8YIyI,GAAkB6zC,EAAA,CAAY,CAChC75B,SAAU,GADsB,CAEhCxiB,QAASA,QAAQ,EAAG,CAClB,MAAO,CACLyoB,IAAKA,QAAQ,CAAC1oB,CAAD,CAAQpG,CAAR,CAAiB+rB,CAAjB,CAAwB,CACnC3lB,CAAAqwC,MAAA,CAAY1qB,CAAAnd,OAAZ,CADmC,CADhC,CADW,CAFY,CAAZ,CA9YtB,CAybIG,GAAyB2zC,EAAA,CAAY,CAAEr2B,SAAU,CAAA,CAAZ,CAAkBxD,SAAU,GAA5B,CAAZ,CAzb7B,CAumBI5Z,GAAuB,CAAC,SAAD,CAAY,cAAZ,CAA4B,QAAQ,CAAC6uC,CAAD,CAAUnrC,CAAV,CAAwB,CACrF,IAAI+vD,EAAQ,KACZ,OAAO,CACL35C,SAAU,IADL,CAEL3C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAAA,IAC/BijE,EAAYjjE,CAAAmjC,MADmB,CAE/B+/B,EAAUljE,CAAAqtB,MAAAiQ,KAAV4lC,EAA6B5iE,CAAAN,KAAA,CAAaA,CAAAqtB,MAAAiQ,KAAb,CAFE,CAG/B1nB,EAAS5V,CAAA4V,OAATA,EAAwB,CAHO,CAI/ButD,EAAQz8D,CAAAqwC,MAAA,CAAYmsB,CAAZ,CAARC;AAAgC,EAJD,CAK/BC,EAAc,EALiB,CAM/BvqC,EAAc5lB,CAAA4lB,YAAA,EANiB,CAO/BC,EAAY7lB,CAAA6lB,UAAA,EAPmB,CAQ/BuqC,EAAS,oBAEb5mE,EAAA,CAAQuD,CAAR,CAAc,QAAQ,CAACk6B,CAAD,CAAaopC,CAAb,CAA4B,CAC5CD,CAAAr8D,KAAA,CAAYs8D,CAAZ,CAAJ,GACEH,CAAA,CAAM5iE,CAAA,CAAU+iE,CAAAr/D,QAAA,CAAsB,MAAtB,CAA8B,EAA9B,CAAAA,QAAA,CAA0C,OAA1C,CAAmD,GAAnD,CAAV,CAAN,CADF,CAEI3D,CAAAN,KAAA,CAAaA,CAAAqtB,MAAA,CAAWi2C,CAAX,CAAb,CAFJ,CADgD,CAAlD,CAMA7mE,EAAA,CAAQ0mE,CAAR,CAAe,QAAQ,CAACjpC,CAAD,CAAat9B,CAAb,CAAkB,CACvCwmE,CAAA,CAAYxmE,CAAZ,CAAA,CACEqW,CAAA,CAAainB,CAAAj2B,QAAA,CAAmB++D,CAAnB,CAA0BnqC,CAA1B,CAAwCoqC,CAAxC,CAAoD,GAApD,CACXrtD,CADW,CACFkjB,CADE,CAAb,CAFqC,CAAzC,CAMApyB,EAAAhH,OAAA,CAAa6jE,QAAyB,EAAG,CACvC,IAAI9lE,EAAQgkD,UAAA,CAAW/6C,CAAAqwC,MAAA,CAAYksB,CAAZ,CAAX,CAEZ,IAAKjsB,KAAA,CAAMv5C,CAAN,CAAL,CAME,MAAO,EAHDA,EAAN,GAAe0lE,EAAf,GAAuB1lE,CAAvB,CAA+B2gD,CAAA1Y,UAAA,CAAkBjoC,CAAlB,CAA0BmY,CAA1B,CAA/B,CACC,OAAOwtD,EAAA,CAAY3lE,CAAZ,CAAA,CAAmBiJ,CAAnB,CAP6B,CAAzC,CAWG88D,QAA+B,CAAC9hD,CAAD,CAAS,CACzCphB,CAAAg1B,KAAA,CAAa5T,CAAb,CADyC,CAX3C,CAtBmC,CAFhC,CAF8E,CAA5D,CAvmB3B,CAm2BIjS,GAAoB,CAAC,QAAD,CAAW,UAAX,CAAuB,QAAQ,CAACoE,CAAD,CAAS1B,CAAT,CAAmB,CAExE,IAAIsxD,EAAiBznE,CAAA,CAAO,UAAP,CAArB,CAEI0nE,EAAcA,QAAQ,CAACh9D,CAAD,CAAQhG,CAAR,CAAeijE,CAAf,CAAgClmE,CAAhC,CAAuCmmE,CAAvC,CAAsDhnE,CAAtD,CAA2DinE,CAA3D,CAAwE,CAEhGn9D,CAAA,CAAMi9D,CAAN,CAAA,CAAyBlmE,CACrBmmE,EAAJ,GAAmBl9D,CAAA,CAAMk9D,CAAN,CAAnB,CAA0ChnE,CAA1C,CACA8J,EAAAqkD,OAAA,CAAerqD,CACfgG,EAAAo9D,OAAA,CAA0B,CAA1B,GAAgBpjE,CAChBgG,EAAAq9D,MAAA,CAAerjE,CAAf;AAA0BmjE,CAA1B,CAAwC,CACxCn9D,EAAAs9D,QAAA,CAAgB,EAAEt9D,CAAAo9D,OAAF,EAAkBp9D,CAAAq9D,MAAlB,CAEhBr9D,EAAAu9D,KAAA,CAAa,EAAEv9D,CAAAw9D,MAAF,CAA8B,CAA9B,IAAiBxjE,CAAjB,CAAuB,CAAvB,EATmF,CAsBlG,OAAO,CACL2oB,SAAU,GADL,CAEL6E,aAAc,CAAA,CAFT,CAGLhC,WAAY,SAHP,CAIL/C,SAAU,GAJL,CAKLwD,SAAU,CAAA,CALL,CAMLiG,MAAO,CAAA,CANF,CAOLjsB,QAASw9D,QAAwB,CAACp6C,CAAD,CAAWsD,CAAX,CAAkB,CACjD,IAAI6M,EAAa7M,CAAA7d,SAAjB,CACI40D,EAAqBtoE,CAAA+2B,cAAA,CAAuB,iBAAvB,CAA2CqH,CAA3C,CAAwD,GAAxD,CADzB,CAGI34B,EAAQ24B,CAAA34B,MAAA,CAAiB,4FAAjB,CAEZ,IAAKA,CAAAA,CAAL,CACE,KAAMkiE,EAAA,CAAe,MAAf,CACFvpC,CADE,CAAN,CAIF,IAAImqC,EAAM9iE,CAAA,CAAM,CAAN,CAAV,CACI+iE,EAAM/iE,CAAA,CAAM,CAAN,CADV,CAEIgjE,EAAUhjE,CAAA,CAAM,CAAN,CAFd,CAGIijE,EAAajjE,CAAA,CAAM,CAAN,CAHjB,CAKAA,EAAQ8iE,CAAA9iE,MAAA,CAAU,+CAAV,CAER,IAAKA,CAAAA,CAAL,CACE,KAAMkiE,EAAA,CAAe,QAAf,CACFY,CADE,CAAN,CAGF,IAAIV,EAAkBpiE,CAAA,CAAM,CAAN,CAAlBoiE,EAA8BpiE,CAAA,CAAM,CAAN,CAAlC,CACIqiE;AAAgBriE,CAAA,CAAM,CAAN,CAEpB,IAAIgjE,CAAJ,GAAiB,CAAA,4BAAAv9D,KAAA,CAAkCu9D,CAAlC,CAAjB,EACI,+EAAAv9D,KAAA,CAAqFu9D,CAArF,CADJ,EAEE,KAAMd,EAAA,CAAe,UAAf,CACJc,CADI,CAAN,CA3B+C,IA+B7CE,CA/B6C,CA+B3BC,CA/B2B,CA+BXC,CA/BW,CA+BOC,CA/BP,CAgC7CC,EAAe,CAAC7xB,IAAK92B,EAAN,CAEfsoD,EAAJ,CACEC,CADF,CACqB5wD,CAAA,CAAO2wD,CAAP,CADrB,EAGEG,CAGA,CAHmBA,QAAS,CAAC/nE,CAAD,CAAMa,CAAN,CAAa,CACvC,MAAOye,GAAA,CAAQze,CAAR,CADgC,CAGzC,CAAAmnE,CAAA,CAAiBA,QAAS,CAAChoE,CAAD,CAAM,CAC9B,MAAOA,EADuB,CANlC,CAWA,OAAOkoE,SAAqB,CAAC30C,CAAD,CAASpG,CAAT,CAAmBsD,CAAnB,CAA0By3B,CAA1B,CAAgCz0B,CAAhC,CAA6C,CAEnEo0C,CAAJ,GACEC,CADF,CACmBA,QAAQ,CAAC9nE,CAAD,CAAMa,CAAN,CAAaiD,CAAb,CAAoB,CAEvCkjE,CAAJ,GAAmBiB,CAAA,CAAajB,CAAb,CAAnB,CAAiDhnE,CAAjD,CACAioE,EAAA,CAAalB,CAAb,CAAA,CAAgClmE,CAChConE,EAAA9Z,OAAA,CAAsBrqD,CACtB,OAAO+jE,EAAA,CAAiBt0C,CAAjB,CAAyB00C,CAAzB,CALoC,CAD/C,CAkBA,KAAIE,EAAe16D,EAAA,EAGnB8lB,EAAAmlB,iBAAA,CAAwBgvB,CAAxB,CAA6BU,QAAuB,CAACC,CAAD,CAAa,CAAA,IAC3DvkE,CAD2D,CACpDtE,CADoD,CAE3D8oE,EAAen7C,CAAA,CAAS,CAAT,CAF4C,CAI3Do7C,CAJ2D,CAO3DC,EAAe/6D,EAAA,EAP4C,CAQ3Dg7D,CAR2D,CAS3DzoE,CAT2D,CAStDa,CATsD,CAU3D6nE,CAV2D,CAY3DC,CAZ2D,CAa3Dx5D,CAb2D,CAc3Dy5D,CAGAjB,EAAJ,GACEp0C,CAAA,CAAOo0C,CAAP,CADF,CACoBU,CADpB,CAIA,IAAIhpE,EAAA,CAAYgpE,CAAZ,CAAJ,CACEM,CACA,CADiBN,CACjB,CAAAQ,CAAA,CAAcf,CAAd,EAAgCC,CAFlC,KAGO,CACLc,CAAA,CAAcf,CAAd,EAAgCE,CAEhCW,EAAA,CAAiB,EACjB,KAASG,CAAT,GAAoBT,EAApB,CACMA,CAAAnoE,eAAA,CAA0B4oE,CAA1B,CAAJ;AAA+D,GAA/D,EAA0CA,CAAA5jE,OAAA,CAAe,CAAf,CAA1C,EACEyjE,CAAApoE,KAAA,CAAoBuoE,CAApB,CAGJH,EAAAnoE,KAAA,EATK,CAYPioE,CAAA,CAAmBE,CAAAnpE,OACnBopE,EAAA,CAAqBjlD,KAAJ,CAAU8kD,CAAV,CAGjB,KAAK3kE,CAAL,CAAa,CAAb,CAAgBA,CAAhB,CAAwB2kE,CAAxB,CAA0C3kE,CAAA,EAA1C,CAIE,GAHA9D,CAGI,CAHGqoE,CAAD,GAAgBM,CAAhB,CAAkC7kE,CAAlC,CAA0C6kE,CAAA,CAAe7kE,CAAf,CAG5C,CAFJjD,CAEI,CAFIwnE,CAAA,CAAWroE,CAAX,CAEJ,CADJ0oE,CACI,CADQG,CAAA,CAAY7oE,CAAZ,CAAiBa,CAAjB,CAAwBiD,CAAxB,CACR,CAAAqkE,CAAA,CAAaO,CAAb,CAAJ,CAEEv5D,CAGA,CAHQg5D,CAAA,CAAaO,CAAb,CAGR,CAFA,OAAOP,CAAA,CAAaO,CAAb,CAEP,CADAF,CAAA,CAAaE,CAAb,CACA,CAD0Bv5D,CAC1B,CAAAy5D,CAAA,CAAe9kE,CAAf,CAAA,CAAwBqL,CAL1B,KAMO,CAAA,GAAIq5D,CAAA,CAAaE,CAAb,CAAJ,CAKL,KAHA7oE,EAAA,CAAQ+oE,CAAR,CAAwB,QAAS,CAACz5D,CAAD,CAAQ,CACnCA,CAAJ,EAAaA,CAAArF,MAAb,GAA0Bq+D,CAAA,CAAah5D,CAAAkb,GAAb,CAA1B,CAAmDlb,CAAnD,CADuC,CAAzC,CAGM,CAAA03D,CAAA,CAAe,OAAf,CAEFvpC,CAFE,CAEUorC,CAFV,CAEqBriE,EAAA,CAAOxF,CAAP,CAFrB,CAAN,CAKA+nE,CAAA,CAAe9kE,CAAf,CAAA,CAAwB,CAACumB,GAAIq+C,CAAL,CAAgB5+D,MAAO3K,CAAvB,CAAkC2H,MAAO3H,CAAzC,CACxBqpE,EAAA,CAAaE,CAAb,CAAA,CAA0B,CAAA,CAXrB,CAgBT,IAASK,CAAT,GAAqBZ,EAArB,CAAmC,CACjCh5D,CAAA,CAAQg5D,CAAA,CAAaY,CAAb,CACR/uC,EAAA,CAAmB5sB,EAAA,CAAc+B,CAAArI,MAAd,CACnByO,EAAAq+C,MAAA,CAAe55B,CAAf,CACA,IAAIA,CAAA,CAAiB,CAAjB,CAAA3c,WAAJ,CAGE,IAAKvZ,CAAW,CAAH,CAAG,CAAAtE,CAAA,CAASw6B,CAAAx6B,OAAzB,CAAkDsE,CAAlD,CAA0DtE,CAA1D,CAAkEsE,CAAA,EAAlE,CACEk2B,CAAA,CAAiBl2B,CAAjB,CAAA,aAAA,CAAsC,CAAA,CAG1CqL,EAAArF,MAAAuC,SAAA,EAXiC,CAenC,IAAKvI,CAAL,CAAa,CAAb,CAAgBA,CAAhB,CAAwB2kE,CAAxB,CAA0C3kE,CAAA,EAA1C,CAKE,GAJA9D,CAII8J,CAJGu+D,CAAD,GAAgBM,CAAhB,CAAkC7kE,CAAlC,CAA0C6kE,CAAA,CAAe7kE,CAAf,CAI5CgG,CAHJjJ,CAGIiJ,CAHIu+D,CAAA,CAAWroE,CAAX,CAGJ8J,CAFJqF,CAEIrF,CAFI8+D,CAAA,CAAe9kE,CAAf,CAEJgG,CAAAqF,CAAArF,MAAJ,CAAiB,CAIfy+D,CAAA,CAAWD,CAGX,GACEC,EAAA,CAAWA,CAAA/6D,YADb,OAES+6D,CAFT,EAEqBA,CAAA,aAFrB,CAIkBp5D;CApLrBrI,MAAA,CAAY,CAAZ,CAoLG,EAA4ByhE,CAA5B,EAEEhzD,CAAAs+C,KAAA,CAAczmD,EAAA,CAAc+B,CAAArI,MAAd,CAAd,CAA0C,IAA1C,CAAgDD,CAAA,CAAOyhE,CAAP,CAAhD,CAEFA,EAAA,CAA2Bn5D,CApL9BrI,MAAA,CAoL8BqI,CApLlBrI,MAAAtH,OAAZ,CAAiC,CAAjC,CAqLGsnE,EAAA,CAAY33D,CAAArF,MAAZ,CAAyBhG,CAAzB,CAAgCijE,CAAhC,CAAiDlmE,CAAjD,CAAwDmmE,CAAxD,CAAuEhnE,CAAvE,CAA4EyoE,CAA5E,CAhBe,CAAjB,IAmBEh1C,EAAA,CAAYu1C,QAA2B,CAACliE,CAAD,CAAQgD,CAAR,CAAe,CACpDqF,CAAArF,MAAA,CAAcA,CAEd,KAAIwD,EAAUk6D,CAAAzsD,UAAA,CAA6B,CAAA,CAA7B,CACdjU,EAAA,CAAMA,CAAAtH,OAAA,EAAN,CAAA,CAAwB8N,CAGxBiI,EAAAo+C,MAAA,CAAe7sD,CAAf,CAAsB,IAAtB,CAA4BD,CAAA,CAAOyhE,CAAP,CAA5B,CACAA,EAAA,CAAeh7D,CAIf6B,EAAArI,MAAA,CAAcA,CACd0hE,EAAA,CAAar5D,CAAAkb,GAAb,CAAA,CAAyBlb,CACzB23D,EAAA,CAAY33D,CAAArF,MAAZ,CAAyBhG,CAAzB,CAAgCijE,CAAhC,CAAiDlmE,CAAjD,CAAwDmmE,CAAxD,CAAuEhnE,CAAvE,CAA4EyoE,CAA5E,CAdoD,CAAtD,CAkBJN,EAAA,CAAeK,CA3HgD,CAAjE,CAvBuE,CA7CxB,CAP9C,CA1BiE,CAAlD,CAn2BxB,CAuuCIz1D,GAAkB,CAAC,UAAD,CAAa,QAAQ,CAACwC,CAAD,CAAW,CACpD,MAAO,CACLkX,SAAU,GADL,CAEL6E,aAAc,CAAA,CAFT,CAGLxH,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACnC0G,CAAAhH,OAAA,CAAaM,CAAA0P,OAAb,CAA0Bm2D,QAA0B,CAACpoE,CAAD,CAAO,CAKzD0U,CAAA,CAAS1U,CAAA,CAAQ,aAAR,CAAwB,UAAjC,CAAA,CAA6C6C,CAA7C,CAvKYwlE,SAuKZ,CAAqE,CACnEC,YAvKsBC,iBAsK6C,CAArE,CALyD,CAA3D,CADmC,CAHhC,CAD6C,CAAhC,CAvuCtB,CAw4CIn3D,GAAkB,CAAC,UAAD,CAAa,QAAQ,CAACsD,CAAD,CAAW,CACpD,MAAO,CACLkX,SAAU,GADL,CAEL6E,aAAc,CAAA,CAFT;AAGLxH,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CACnC0G,CAAAhH,OAAA,CAAaM,CAAA4O,OAAb,CAA0Bq3D,QAA0B,CAACxoE,CAAD,CAAO,CAGzD0U,CAAA,CAAS1U,CAAA,CAAQ,UAAR,CAAqB,aAA9B,CAAA,CAA6C6C,CAA7C,CAtUYwlE,SAsUZ,CAAoE,CAClEC,YAtUsBC,iBAqU4C,CAApE,CAHyD,CAA3D,CADmC,CAHhC,CAD6C,CAAhC,CAx4CtB,CAs8CIn2D,GAAmBmzC,EAAA,CAAY,QAAQ,CAACt8C,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAChE0G,CAAAhH,OAAA,CAAaM,CAAA4P,QAAb,CAA2Bs2D,QAA2B,CAACC,CAAD,CAAYC,CAAZ,CAAuB,CACvEA,CAAJ,EAAkBD,CAAlB,GAAgCC,CAAhC,EACE3pE,CAAA,CAAQ2pE,CAAR,CAAmB,QAAQ,CAACpjE,CAAD,CAAMsK,CAAN,CAAa,CAAEhN,CAAAqsD,IAAA,CAAYr/C,CAAZ,CAAmB,EAAnB,CAAF,CAAxC,CAEE64D,EAAJ,EAAe7lE,CAAAqsD,IAAA,CAAYwZ,CAAZ,CAJ4D,CAA7E,CAKG,CAAA,CALH,CADgE,CAA3C,CAt8CvB,CA+kDIp2D,GAAoB,CAAC,UAAD,CAAa,QAAQ,CAACoC,CAAD,CAAW,CACtD,MAAO,CACLkX,SAAU,IADL,CAELD,QAAS,UAFJ,CAKL5gB,WAAY,CAAC,QAAD,CAAW69D,QAA2B,EAAG,CACpD,IAAAC,MAAA,CAAa,EADuC,CAAzC,CALP,CAQL5/C,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuBqmE,CAAvB,CAA2C,CAAA,IAEnDE,EAAsB,EAF6B,CAGnDC,EAAmB,EAHgC,CAInDC,EAA0B,EAJyB,CAKnDC,EAAiB,EALkC,CAOnDC,EAAgBA,QAAQ,CAAClmE,CAAD,CAAQC,CAAR,CAAe,CACvC,MAAO,SAAQ,EAAG,CAAED,CAAAG,OAAA,CAAaF,CAAb,CAAoB,CAApB,CAAF,CADqB,CAI3CgG,EAAAhH,OAAA,CAVgBM,CAAA8P,SAUhB,EAViC9P,CAAAqI,GAUjC,CAAwBu+D,QAA4B,CAACnpE,CAAD,CAAQ,CAAA,IACtDH,CADsD;AACnDW,CACFX,EAAA,CAAI,CAAT,KAAYW,CAAZ,CAAiBwoE,CAAArqE,OAAjB,CAAiDkB,CAAjD,CAAqDW,CAArD,CAAyD,EAAEX,CAA3D,CACE6U,CAAA2T,OAAA,CAAgB2gD,CAAA,CAAwBnpE,CAAxB,CAAhB,CAIGA,EAAA,CAFLmpE,CAAArqE,OAEK,CAF4B,CAEjC,KAAY6B,CAAZ,CAAiByoE,CAAAtqE,OAAjB,CAAwCkB,CAAxC,CAA4CW,CAA5C,CAAgD,EAAEX,CAAlD,CAAqD,CACnD,IAAI6vD,EAAWnjD,EAAA,CAAcw8D,CAAA,CAAiBlpE,CAAjB,CAAAoG,MAAd,CACfgjE,EAAA,CAAeppE,CAAf,CAAA2L,SAAA,EAEAyrB,EADc+xC,CAAA,CAAwBnpE,CAAxB,CACdo3B,CAD2CviB,CAAAq+C,MAAA,CAAerD,CAAf,CAC3Cz4B,MAAA,CAAaiyC,CAAA,CAAcF,CAAd,CAAuCnpE,CAAvC,CAAb,CAJmD,CAOrDkpE,CAAApqE,OAAA,CAA0B,CAC1BsqE,EAAAtqE,OAAA,CAAwB,CAExB,EAAKmqE,CAAL,CAA2BF,CAAAC,MAAA,CAAyB,GAAzB,CAA+B7oE,CAA/B,CAA3B,EAAoE4oE,CAAAC,MAAA,CAAyB,GAAzB,CAApE,GACE7pE,CAAA,CAAQ8pE,CAAR,CAA6B,QAAQ,CAACM,CAAD,CAAqB,CACxDA,CAAA36C,WAAA,CAA8B,QAAQ,CAAC46C,CAAD,CAAcC,CAAd,CAA6B,CACjEL,CAAAvpE,KAAA,CAAoB4pE,CAApB,CACA,KAAIC,EAASH,CAAAvmE,QACbwmE,EAAA,CAAYA,CAAA1qE,OAAA,EAAZ,CAAA,CAAoCN,CAAA+2B,cAAA,CAAuB,qBAAvB,CAGpC2zC,EAAArpE,KAAA,CAFY4O,CAAErI,MAAOojE,CAAT/6D,CAEZ,CACAoG,EAAAo+C,MAAA,CAAeuW,CAAf,CAA4BE,CAAAtoE,OAAA,EAA5B,CAA6CsoE,CAA7C,CAPiE,CAAnE,CADwD,CAA1D,CAlBwD,CAA5D,CAXuD,CARpD,CAD+C,CAAhC,CA/kDxB,CAsoDI/2D,GAAwB+yC,EAAA,CAAY,CACtC92B,WAAY,SAD0B,CAEtC/C,SAAU,IAF4B,CAGtCC,QAAS,WAH6B,CAItC8E,aAAc,CAAA,CAJwB,CAKtCxH,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiB+rB,CAAjB,CAAwBy4B,CAAxB,CAA8Bz0B,CAA9B,CAA2C,CACvDy0B,CAAAwhB,MAAA,CAAW,GAAX,CAAiBj6C,CAAArc,aAAjB,CAAA;AAAwC80C,CAAAwhB,MAAA,CAAW,GAAX,CAAiBj6C,CAAArc,aAAjB,CAAxC,EAAgF,EAChF80C,EAAAwhB,MAAA,CAAW,GAAX,CAAiBj6C,CAAArc,aAAjB,CAAA7S,KAAA,CAA0C,CAAE+uB,WAAYmE,CAAd,CAA2B/vB,QAASA,CAApC,CAA1C,CAFuD,CALnB,CAAZ,CAtoD5B,CAipDI6P,GAA2B6yC,EAAA,CAAY,CACzC92B,WAAY,SAD6B,CAEzC/C,SAAU,IAF+B,CAGzCC,QAAS,WAHgC,CAIzC8E,aAAc,CAAA,CAJ2B,CAKzCxH,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB8kD,CAAvB,CAA6Bz0B,CAA7B,CAA0C,CACtDy0B,CAAAwhB,MAAA,CAAW,GAAX,CAAA,CAAmBxhB,CAAAwhB,MAAA,CAAW,GAAX,CAAnB,EAAsC,EACtCxhB,EAAAwhB,MAAA,CAAW,GAAX,CAAAnpE,KAAA,CAAqB,CAAE+uB,WAAYmE,CAAd,CAA2B/vB,QAASA,CAApC,CAArB,CAFsD,CALf,CAAZ,CAjpD/B,CAktDIiQ,GAAwByyC,EAAA,CAAY,CACtC35B,SAAU,KAD4B,CAEtC3C,KAAMA,QAAQ,CAACyJ,CAAD,CAASpG,CAAT,CAAmBqG,CAAnB,CAA2B5nB,CAA3B,CAAuC6nB,CAAvC,CAAoD,CAChE,GAAKA,CAAAA,CAAL,CACE,KAAMr0B,EAAA,CAAO,cAAP,CAAA,CAAuB,QAAvB,CAILwH,EAAA,CAAYumB,CAAZ,CAJK,CAAN,CAOFsG,CAAA,CAAY,QAAQ,CAAC3sB,CAAD,CAAQ,CAC1BqmB,CAAApmB,MAAA,EACAomB,EAAAjmB,OAAA,CAAgBJ,CAAhB,CAF0B,CAA5B,CATgE,CAF5B,CAAZ,CAltD5B,CAqwDIyJ,GAAkB,CAAC,gBAAD,CAAmB,QAAQ,CAACwH,CAAD,CAAiB,CAChE,MAAO,CACL0U,SAAU,GADL,CAELsD,SAAU,CAAA,CAFL,CAGLhmB,QAASA,QAAQ,CAACrG,CAAD,CAAUN,CAAV,CAAgB,CACd,kBAAjB;AAAIA,CAAAmY,KAAJ,EAKExD,CAAA6H,IAAA,CAJkBxc,CAAAinB,GAIlB,CAFW3mB,CAAA,CAAQ,CAAR,CAAAg1B,KAEX,CAN6B,CAH5B,CADyD,CAA5C,CArwDtB,CAqxDI2xC,GAAkBjrE,CAAA,CAAO,WAAP,CArxDtB,CAi7DIqU,GAAqBrR,EAAA,CAAQ,CAC/BqqB,SAAU,GADqB,CAE/BsD,SAAU,CAAA,CAFqB,CAAR,CAj7DzB,CAu7DItf,GAAkB,CAAC,UAAD,CAAa,QAAb,CAAuB,QAAQ,CAACyzD,CAAD,CAAajtD,CAAb,CAAqB,CAAA,IAEpEqzD,EAAoB,wMAFgD,CAGpEC,EAAgB,CAAC1gB,cAAe5nD,CAAhB,CAGpB,OAAO,CACLwqB,SAAU,GADL,CAELD,QAAS,CAAC,QAAD,CAAW,UAAX,CAFJ,CAGL5gB,WAAY,CAAC,UAAD,CAAa,QAAb,CAAuB,QAAvB,CAAiC,QAAQ,CAACuhB,CAAD,CAAWoG,CAAX,CAAmBC,CAAnB,CAA2B,CAAA,IAC1E1tB,EAAO,IADmE,CAE1E0kE,EAAa,EAF6D,CAG1EC,EAAcF,CAH4D,CAK1EG,CAGJ5kE,EAAA6kE,UAAA,CAAiBn3C,CAAA5f,QAGjB9N;CAAA8kE,KAAA,CAAYC,QAAQ,CAACC,CAAD,CAAeC,CAAf,CAA4BC,CAA5B,CAA4C,CAC9DP,CAAA,CAAcK,CAEdJ,EAAA,CAAgBM,CAH8C,CAOhEllE,EAAAmlE,UAAA,CAAiBC,QAAQ,CAACrqE,CAAD,CAAQ6C,CAAR,CAAiB,CACxCoJ,EAAA,CAAwBjM,CAAxB,CAA+B,gBAA/B,CACA2pE,EAAA,CAAW3pE,CAAX,CAAA,CAAoB,CAAA,CAEhB4pE,EAAA9gB,WAAJ,EAA8B9oD,CAA9B,GACEssB,CAAA/mB,IAAA,CAAavF,CAAb,CACA,CAAI6pE,CAAA5oE,OAAA,EAAJ,EAA4B4oE,CAAA//C,OAAA,EAF9B,CAOIjnB,EAAJ,EAAeA,CAAA,CAAQ,CAAR,CAAAmF,aAAA,CAAwB,UAAxB,CAAf,GACEnF,CAAA,CAAQ,CAAR,CAAA6sD,SADF,CACwB,CAAA,CADxB,CAXwC,CAiB1CzqD,EAAAqlE,aAAA,CAAoBC,QAAQ,CAACvqE,CAAD,CAAQ,CAC9B,IAAAwqE,UAAA,CAAexqE,CAAf,CAAJ,GACE,OAAO2pE,CAAA,CAAW3pE,CAAX,CACP,CAAI4pE,CAAA9gB,WAAJ,EAA8B9oD,CAA9B,EACE,IAAAyqE,oBAAA,CAAyBzqE,CAAzB,CAHJ,CADkC,CAUpCiF,EAAAwlE,oBAAA,CAA2BC,QAAQ,CAACnlE,CAAD,CAAM,CACnColE,CAAAA,CAAa,IAAbA,CAAoBlsD,EAAA,CAAQlZ,CAAR,CAApBolE,CAAmC,IACvCd,EAAAtkE,IAAA,CAAkBolE,CAAlB,CACAr+C,EAAAikC,QAAA,CAAiBsZ,CAAjB,CACAv9C,EAAA/mB,IAAA,CAAaolE,CAAb,CACAd,EAAAvnE,KAAA,CAAmB,UAAnB,CAA+B,CAAA,CAA/B,CALuC,CASzC2C,EAAAulE,UAAA,CAAiBI,QAAQ,CAAC5qE,CAAD,CAAQ,CAC/B,MAAO2pE,EAAAtqE,eAAA,CAA0BW,CAA1B,CADwB,CAIjC0yB,EAAAyB,IAAA,CAAW,UAAX,CAAuB,QAAQ,EAAG,CAEhClvB,CAAAwlE,oBAAA;AAA2BrpE,CAFK,CAAlC,CA1D8E,CAApE,CAHP,CAmEL6nB,KAAMA,QAAQ,CAAChgB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuBo8D,CAAvB,CAA8B,CA2C1CkM,QAASA,EAAa,CAAC5hE,CAAD,CAAQ6hE,CAAR,CAAuBlB,CAAvB,CAAoCmB,CAApC,CAAgD,CACpEnB,CAAAzgB,QAAA,CAAsB6hB,QAAQ,EAAG,CAC/B,IAAIxK,EAAYoJ,CAAA9gB,WAEZiiB,EAAAP,UAAA,CAAqBhK,CAArB,CAAJ,EACMqJ,CAAA5oE,OAAA,EAEJ,EAF4B4oE,CAAA//C,OAAA,EAE5B,CADAghD,CAAAvlE,IAAA,CAAkBi7D,CAAlB,CACA,CAAkB,EAAlB,GAAIA,CAAJ,EAAsByK,CAAA3oE,KAAA,CAAiB,UAAjB,CAA6B,CAAA,CAA7B,CAHxB,EAKMd,CAAA,CAAYg/D,CAAZ,CAAJ,EAA8ByK,CAA9B,CACEH,CAAAvlE,IAAA,CAAkB,EAAlB,CADF,CAGEwlE,CAAAN,oBAAA,CAA+BjK,CAA/B,CAX2B,CAgBjCsK,EAAAlgE,GAAA,CAAiB,QAAjB,CAA2B,QAAQ,EAAG,CACpC3B,CAAAE,OAAA,CAAa,QAAQ,EAAG,CAClB0gE,CAAA5oE,OAAA,EAAJ,EAA4B4oE,CAAA//C,OAAA,EAC5B8/C,EAAA5gB,cAAA,CAA0B8hB,CAAAvlE,IAAA,EAA1B,CAFsB,CAAxB,CADoC,CAAtC,CAjBoE,CAyBtE2lE,QAASA,EAAe,CAACjiE,CAAD,CAAQ6hE,CAAR,CAAuBzjB,CAAvB,CAA6B,CACnD,IAAI8jB,CACJ9jB,EAAA8B,QAAA,CAAeC,QAAQ,EAAG,CACxB,IAAI1mD,EAAQ,IAAIkc,EAAJ,CAAYyoC,CAAAyB,WAAZ,CACZ9pD,EAAA,CAAQ8rE,CAAAtoE,KAAA,CAAmB,QAAnB,CAAR,CAAsC,QAAQ,CAACuN,CAAD,CAAS,CACrDA,CAAA2/C,SAAA,CAAkBjuD,CAAA,CAAUiB,CAAAuH,IAAA,CAAU8F,CAAA/P,MAAV,CAAV,CADmC,CAAvD,CAFwB,CAS1BiJ,EAAAhH,OAAA,CAAampE,QAA4B,EAAG,CACrC9mE,EAAA,CAAO6mE,CAAP,CAAiB9jB,CAAAyB,WAAjB,CAAL,GACEqiB,CACA,CADWhnE,EAAA,CAAYkjD,CAAAyB,WAAZ,CACX;AAAAzB,CAAA8B,QAAA,EAFF,CAD0C,CAA5C,CAOA2hB,EAAAlgE,GAAA,CAAiB,QAAjB,CAA2B,QAAQ,EAAG,CACpC3B,CAAAE,OAAA,CAAa,QAAQ,EAAG,CACtB,IAAInG,EAAQ,EACZhE,EAAA,CAAQ8rE,CAAAtoE,KAAA,CAAmB,QAAnB,CAAR,CAAsC,QAAQ,CAACuN,CAAD,CAAS,CACjDA,CAAA2/C,SAAJ,EACE1sD,CAAAtD,KAAA,CAAWqQ,CAAA/P,MAAX,CAFmD,CAAvD,CAKAqnD,EAAA2B,cAAA,CAAmBhmD,CAAnB,CAPsB,CAAxB,CADoC,CAAtC,CAlBmD,CA+BrDqoE,QAASA,EAAc,CAACpiE,CAAD,CAAQ6hE,CAAR,CAAuBzjB,CAAvB,CAA6B,CA0DlDikB,QAASA,EAAc,CAACC,CAAD,CAASpsE,CAAT,CAAca,CAAd,CAAqB,CAC1CyhB,CAAA,CAAO+pD,CAAP,CAAA,CAAoBxrE,CAChByrE,EAAJ,GAAahqD,CAAA,CAAOgqD,CAAP,CAAb,CAA+BtsE,CAA/B,CACA,OAAOosE,EAAA,CAAOtiE,CAAP,CAAcwY,CAAd,CAHmC,CA0D5CiqD,QAASA,EAAkB,CAAClL,CAAD,CAAY,CACrC,IAAImL,CACJ,IAAIlc,CAAJ,CACE,GAAImc,CAAJ,EAAe7sE,CAAA,CAAQyhE,CAAR,CAAf,CAAmC,CAEjCmL,CAAA,CAAc,IAAI/sD,EAAJ,CAAY,EAAZ,CACd,KAAS,IAAAitD,EAAa,CAAtB,CAAyBA,CAAzB,CAAsCrL,CAAA7hE,OAAtC,CAAwDktE,CAAA,EAAxD,CAEEF,CAAA5sD,IAAA,CAAgBusD,CAAA,CAAeM,CAAf,CAAwB,IAAxB,CAA8BpL,CAAA,CAAUqL,CAAV,CAA9B,CAAhB,CAAsE,CAAA,CAAtE,CAL+B,CAAnC,IAQEF,EAAA,CAAc,IAAI/sD,EAAJ,CAAY4hD,CAAZ,CATlB,KAWWoL,EAAJ,GACLpL,CADK,CACO8K,CAAA,CAAeM,CAAf,CAAwB,IAAxB,CAA8BpL,CAA9B,CADP,CAIP,OAAOsL,SAAmB,CAAC3sE,CAAD,CAAMa,CAAN,CAAa,CACrC,IAAI+rE,CAEFA,EAAA,CADEH,CAAJ,CACmBA,CADnB,CAEWI,CAAJ,CACYA,CADZ,CAGYzqE,CAGnB,OAAIkuD,EAAJ,CACShuD,CAAA,CAAUkqE,CAAA7hD,OAAA,CAAmBwhD,CAAA,CAAeS,CAAf,CAA+B5sE,CAA/B,CAAoCa,CAApC,CAAnB,CAAV,CADT,CAGSwgE,CAHT,EAGsB8K,CAAA,CAAeS,CAAf,CAA+B5sE,CAA/B,CAAoCa,CAApC,CAbe,CAjBF,CAmCvCisE,QAASA,EAAiB,EAAG,CACtBC,CAAL,GACEjjE,CAAAsoC,aAAA,CAAmB46B,CAAnB,CACA,CAAAD,CAAA,CAAkB,CAAA,CAFpB,CAD2B,CAmB7BE,QAASA,EAAc,CAACC,CAAD;AAAWC,CAAX,CAAkBC,CAAlB,CAAyB,CAC9CF,CAAA,CAASC,CAAT,CAAA,CAAkBD,CAAA,CAASC,CAAT,CAAlB,EAAqC,CACrCD,EAAA,CAASC,CAAT,CAAA,EAAoBC,CAAA,CAAQ,CAAR,CAAa,EAFa,CAKhDJ,QAASA,EAAM,EAAG,CAChBD,CAAA,CAAkB,CAAA,CADF,KAIZM,EAAe,CAAC,GAAG,EAAJ,CAJH,CAKZC,EAAmB,CAAC,EAAD,CALP,CAMZC,CANY,CAOZC,CAPY,CASZC,CATY,CASIC,CATJ,CASqBC,CACjCtM,EAAAA,CAAYnZ,CAAAyB,WACZjtB,EAAAA,CAASkxC,CAAA,CAAS9jE,CAAT,CAAT4yB,EAA4B,EAXhB,KAYZp8B,EAAOgsE,CAAA,CAAUjsE,EAAA,CAAWq8B,CAAX,CAAV,CAA+BA,CAZ1B,CAaZ18B,CAbY,CAcZa,CAdY,CAeCrB,CAfD,CAgBZquE,CAhBY,CAgBA/pE,CAhBA,CAiBZopE,EAAW,EAEXP,EAAAA,CAAaJ,CAAA,CAAmBlL,CAAnB,CACbyM,EAAAA,CAAc,CAAA,CApBF,KAsBZpqE,CAIJ,KAAKI,CAAL,CAAa,CAAb,CAAgBtE,CAAA,CAASc,CAAAd,OAAT,CAAsBsE,CAAtB,CAA8BtE,CAA9C,CAAsDsE,CAAA,EAAtD,CAA+D,CAC7D9D,CAAA,CAAM8D,CACN,IAAIwoE,CAAJ,GACEtsE,CACK,CADCM,CAAA,CAAKwD,CAAL,CACD,CAAkB,GAAlB,GAAA9D,CAAAkF,OAAA,CAAW,CAAX,CAFP,EAE+B,QAE/BrE,EAAA,CAAQ67B,CAAA,CAAO18B,CAAP,CAERutE,EAAA,CAAkBpB,CAAA,CAAe4B,CAAf,CAA0B/tE,CAA1B,CAA+Ba,CAA/B,CAAlB,EAA2D,EAC3D,EAAM2sE,CAAN,CAAoBH,CAAA,CAAaE,CAAb,CAApB,IACEC,CACA,CADcH,CAAA,CAAaE,CAAb,CACd,CAD8C,EAC9C,CAAAD,CAAA/sE,KAAA,CAAsBgtE,CAAtB,CAFF,CAKAhd,EAAA,CAAWoc,CAAA,CAAW3sE,CAAX,CAAgBa,CAAhB,CACXitE,EAAA,CAAcA,CAAd,EAA6Bvd,CAE7B4c,EAAA,CAAQhB,CAAA,CAAe6B,CAAf,CAA0BhuE,CAA1B,CAA+Ba,CAA/B,CAGRssE,EAAA,CAAQ7qE,CAAA,CAAU6qE,CAAV,CAAA,CAAmBA,CAAnB,CAA2B,EACnCK,EAAAjtE,KAAA,CAAiB,CAEf8pB,GAAKiiD,CAAA,CAAUhsE,CAAA,CAAKwD,CAAL,CAAV,CAAwBA,CAFd,CAGfqpE,MAAOA,CAHQ,CAIf5c,SAAUA,CAJK,CAAjB,CArB6D,CA4B1DD,CAAL,GACM2d,CAAJ,EAAgC,IAAhC,GAAkB5M,CAAlB,CAEEgM,CAAA,CAAa,EAAb,CAAA9jE,QAAA,CAAyB,CAAC8gB,GAAG,EAAJ,CAAQ8iD,MAAM,EAAd,CAAkB5c,SAAS,CAACud,CAA5B,CAAzB,CAFF,CAGYA,CAHZ,EAKET,CAAA,CAAa,EAAb,CAAA9jE,QAAA,CAAyB,CAAC8gB,GAAG,GAAJ,CAAS8iD,MAAM,EAAf,CAAmB5c,SAAS,CAAA,CAA5B,CAAzB,CANJ,CAWKsd,EAAA,CAAa,CAAlB,KAAqBK,CAArB,CAAmCZ,CAAA9tE,OAAnC,CACKquE,CADL,CACkBK,CADlB,CAEKL,CAAA,EAFL,CAEmB,CAEjBN,CAAA;AAAkBD,CAAA,CAAiBO,CAAjB,CAGlBL,EAAA,CAAcH,CAAA,CAAaE,CAAb,CAEVY,EAAA3uE,OAAJ,EAAgCquE,CAAhC,EAEEJ,CAMA,CANiB,CACf/pE,QAAS0qE,CAAAtnE,MAAA,EAAA1D,KAAA,CAA8B,OAA9B,CAAuCmqE,CAAvC,CADM,CAEfJ,MAAOK,CAAAL,MAFQ,CAMjB,CAFAO,CAEA,CAFkB,CAACD,CAAD,CAElB,CADAU,CAAA5tE,KAAA,CAAuBmtE,CAAvB,CACA,CAAA/B,CAAAzkE,OAAA,CAAqBumE,CAAA/pE,QAArB,CARF,GAUEgqE,CAIA,CAJkBS,CAAA,CAAkBN,CAAlB,CAIlB,CAHAJ,CAGA,CAHiBC,CAAA,CAAgB,CAAhB,CAGjB,CAAID,CAAAN,MAAJ,EAA4BI,CAA5B,EACEE,CAAA/pE,QAAAN,KAAA,CAA4B,OAA5B,CAAqCqqE,CAAAN,MAArC,CAA4DI,CAA5D,CAfJ,CAmBAc,EAAA,CAAc,IACVvqE,EAAA,CAAQ,CAAZ,KAAetE,CAAf,CAAwBguE,CAAAhuE,OAAxB,CAA4CsE,CAA5C,CAAoDtE,CAApD,CAA4DsE,CAAA,EAA5D,CACE8M,CACA,CADS48D,CAAA,CAAY1pE,CAAZ,CACT,CAAA,CAAK6pE,CAAL,CAAsBD,CAAA,CAAgB5pE,CAAhB,CAAsB,CAAtB,CAAtB,GAEEuqE,CAUA,CAVcV,CAAAjqE,QAUd,CATIiqE,CAAAR,MASJ,GAT6Bv8D,CAAAu8D,MAS7B,GAREF,CAAA,CAAeC,CAAf,CAAyBS,CAAAR,MAAzB,CAA+C,CAAA,CAA/C,CAEA,CADAF,CAAA,CAAeC,CAAf,CAAyBt8D,CAAAu8D,MAAzB,CAAuC,CAAA,CAAvC,CACA,CAAAkB,CAAA31C,KAAA,CAAiBi1C,CAAAR,MAAjB,CAAwCv8D,CAAAu8D,MAAxC,CAMF,EAJIQ,CAAAtjD,GAIJ,GAJ0BzZ,CAAAyZ,GAI1B,EAHEgkD,CAAAjoE,IAAA,CAAgBunE,CAAAtjD,GAAhB,CAAoCzZ,CAAAyZ,GAApC,CAGF,CAAIgkD,CAAA,CAAY,CAAZ,CAAA9d,SAAJ,GAAgC3/C,CAAA2/C,SAAhC,GACE8d,CAAAlrE,KAAA,CAAiB,UAAjB,CAA8BwqE,CAAApd,SAA9B,CAAwD3/C,CAAA2/C,SAAxD,CACA,CAAI3R,EAAJ,EAIEyvB,CAAAlrE,KAAA,CAAiB,UAAjB,CAA6BwqE,CAAApd,SAA7B,CANJ,CAZF,GAyBoB,EAAlB,GAAI3/C,CAAAyZ,GAAJ,EAAwB4jD,CAAxB,CAEEvqE,CAFF,CAEYuqE,CAFZ,CAOE7nE,CAAC1C,CAAD0C,CAAWkoE,CAAAxnE,MAAA,EAAXV,KAAA,CACSwK,CAAAyZ,GADT,CAAAlnB,KAAA,CAEU,UAFV;AAEsByN,CAAA2/C,SAFtB,CAAAntD,KAAA,CAGU,UAHV,CAGsBwN,CAAA2/C,SAHtB,CAAA73B,KAAA,CAIU9nB,CAAAu8D,MAJV,CAmBF,CAZAO,CAAAntE,KAAA,CAAqBotE,CAArB,CAAsC,CAClCjqE,QAASA,CADyB,CAElCypE,MAAOv8D,CAAAu8D,MAF2B,CAGlC9iD,GAAIzZ,CAAAyZ,GAH8B,CAIlCkmC,SAAU3/C,CAAA2/C,SAJwB,CAAtC,CAYA,CANA0c,CAAA,CAAeC,CAAf,CAAyBt8D,CAAAu8D,MAAzB,CAAuC,CAAA,CAAvC,CAMA,CALIkB,CAAJ,CACEA,CAAA9c,MAAA,CAAkB7tD,CAAlB,CADF,CAGE+pE,CAAA/pE,QAAAwD,OAAA,CAA8BxD,CAA9B,CAEF,CAAA2qE,CAAA,CAAc3qE,CAnDhB,CAwDF,KADAI,CAAA,EACA,CAAM4pE,CAAAluE,OAAN,CAA+BsE,CAA/B,CAAA,CACE8M,CAEA,CAFS88D,CAAAroD,IAAA,EAET,CADA4nD,CAAA,CAAeC,CAAf,CAAyBt8D,CAAAu8D,MAAzB,CAAuC,CAAA,CAAvC,CACA,CAAAv8D,CAAAlN,QAAAinB,OAAA,EAEF9qB,EAAA,CAAQqtE,CAAR,CAAkB,QAAS,CAAC3mC,CAAD,CAAQ4mC,CAAR,CAAe,CAC5B,CAAZ,CAAI5mC,CAAJ,CACEqlC,CAAAX,UAAA,CAAqBkC,CAArB,CADF,CAEmB,CAFnB,CAEW5mC,CAFX,EAGEqlC,CAAAT,aAAA,CAAwBgC,CAAxB,CAJsC,CAA1C,CA1FiB,CAmGnB,IAAA,CAAMgB,CAAA3uE,OAAN,CAAiCquE,CAAjC,CAAA,CACEM,CAAA9oD,IAAA,EAAA,CAAwB,CAAxB,CAAA3hB,QAAAinB,OAAA,EAvKc,CA9KlB,IAAIhmB,CAEJ,IAAM,EAAAA,CAAA,CAAQ4pE,CAAA5pE,MAAA,CAAiB2lE,CAAjB,CAAR,CAAN,CACE,KAAMD,GAAA,CAAgB,MAAhB,CAIJkE,CAJI,CAIQ3nE,EAAA,CAAY+kE,CAAZ,CAJR,CAAN,CAJgD,IAW9CqC,EAAY/2D,CAAA,CAAOtS,CAAA,CAAM,CAAN,CAAP,EAAmBA,CAAA,CAAM,CAAN,CAAnB,CAXkC,CAY9C0nE,EAAY1nE,CAAA,CAAM,CAAN,CAAZ0nE,EAAwB1nE,CAAA,CAAM,CAAN,CAZsB,CAa9C6pE,EAAW,MAAApkE,KAAA,CAAYzF,CAAA,CAAM,CAAN,CAAZ,CAAX6pE,EAAoC7pE,CAAA,CAAM,CAAN,CAbU,CAc9CkoE,EAAa2B,CAAA,CAAWv3D,CAAA,CAAOu3D,CAAP,CAAX,CAA8B,IAdG,CAe9ClC,EAAU3nE,CAAA,CAAM,CAAN,CAfoC,CAgB9CopE,EAAY92D,CAAA,CAAOtS,CAAA,CAAM,CAAN,CAAP,EAAmB,EAAnB,CAhBkC,CAiB9CvC,EAAU6U,CAAA,CAAOtS,CAAA,CAAM,CAAN,CAAA,CAAWA,CAAA,CAAM,CAAN,CAAX;AAAsB0nE,CAA7B,CAjBoC,CAkB9CuB,EAAW32D,CAAA,CAAOtS,CAAA,CAAM,CAAN,CAAP,CAlBmC,CAoB9C8nE,EADQ9nE,CAAA8pE,CAAM,CAANA,CACE,CAAQx3D,CAAA,CAAOtS,CAAA,CAAM,CAAN,CAAP,CAAR,CAA2B,IApBS,CAyB9CwpE,EAAoB,CAAC,CAAC,CAACzqE,QAASioE,CAAV,CAAyBwB,MAAM,EAA/B,CAAD,CAAD,CAzB0B,CA2B9C7qD,EAAS,EAET2rD,EAAJ,GAEE/J,CAAA,CAAS+J,CAAT,CAAA,CAAqBnkE,CAArB,CAQA,CAJAmkE,CAAAlzC,YAAA,CAAuB,UAAvB,CAIA,CAAAkzC,CAAAtjD,OAAA,EAVF,CAcAghD,EAAA5kE,MAAA,EAEA4kE,EAAAlgE,GAAA,CAAiB,QAAjB,CAmBAijE,QAAyB,EAAG,CAC1B5kE,CAAAE,OAAA,CAAa,QAAQ,EAAG,CAAA,IAElBq+D,EAAauF,CAAA,CAAS9jE,CAAT,CAAbu+D,EAAgC,EAFd,CAIlBhH,CACJ,IAAI/Q,CAAJ,CACE+Q,CACA,CADY,EACZ,CAAAxhE,CAAA,CAAQ8rE,CAAAvlE,IAAA,EAAR,CAA6B,QAAQ,CAACuoE,CAAD,CAAc,CACjDtN,CAAA9gE,KAAA,CAYM,GAAZ,GAZkCouE,CAYlC,CACSxvE,CADT,CAEmB,EAAZ,GAd2BwvE,CAc3B,CACE,IADF,CAIExC,CAAA,CADWU,CAAA+B,CAAa/B,CAAb+B,CAA0BxsE,CACrC,CAlByBusE,CAkBzB,CAlBsCtG,CAAAxnE,CAAW8tE,CAAX9tE,CAkBtC,CAlBH,CADiD,CAAnD,CAFF,KAKO,CACL,IAAI8tE,EAAchD,CAAAvlE,IAAA,EAClBi7D,EAAA,CAQQ,GAAZ,GAR6BsN,CAQ7B,CACSxvE,CADT,CAEmB,EAAZ,GAVsBwvE,CAUtB,CACE,IADF,CAIExC,CAAA,CADWU,CAAA+B,CAAa/B,CAAb+B,CAA0BxsE,CACrC,CAdoBusE,CAcpB,CAdiCtG,CAAAxnE,CAAW8tE,CAAX9tE,CAcjC,CAhBA,CAIPqnD,CAAA2B,cAAA,CAAmBwX,CAAnB,CACA2L,EAAA,EAfsB,CAAxB,CAD0B,CAnB5B,CAEA9kB,EAAA8B,QAAA,CAAegjB,CAEfljE,EAAA4uC,iBAAA,CAAuBk1B,CAAvB,CAAiCd,CAAjC,CACAhjE,EAAA4uC,iBAAA,CA6CAm2B,QAAkB,EAAG,CACnB,IAAInyC,EAASkxC,CAAA,CAAS9jE,CAAT,CAAb,CACIglE,CACJ,IAAIpyC,CAAJ,EAAc98B,CAAA,CAAQ88B,CAAR,CAAd,CAA+B,CAC7BoyC,CAAA,CAAgBnrD,KAAJ,CAAU+Y,CAAAl9B,OAAV,CACZ,KAF6B,IAEpBkB,EAAI,CAFgB,CAEbW,EAAKq7B,CAAAl9B,OAArB,CAAoCkB,CAApC,CAAwCW,CAAxC,CAA4CX,CAAA,EAA5C,CACEouE,CAAA,CAAUpuE,CAAV,CAAA,CAAeyrE,CAAA,CAAe6B,CAAf;AAA0BttE,CAA1B,CAA6Bg8B,CAAA,CAAOh8B,CAAP,CAA7B,CAHY,CAA/B,IAMO,IAAIg8B,CAAJ,CAGL,IAASv5B,CAAT,GADA2rE,EACiBpyC,CADL,EACKA,CAAAA,CAAjB,CACMA,CAAAx8B,eAAA,CAAsBiD,CAAtB,CAAJ,GACE2rE,CAAA,CAAU3rE,CAAV,CADF,CACoBgpE,CAAA,CAAe6B,CAAf,CAA0B7qE,CAA1B,CAAgCu5B,CAAA,CAAOv5B,CAAP,CAAhC,CADpB,CAKJ,OAAO2rE,EAlBY,CA7CrB,CAAkChC,CAAlC,CAEIxc,EAAJ,EACExmD,CAAA4uC,iBAAA,CAAuB,QAAQ,EAAG,CAAE,MAAOwP,EAAAgC,YAAT,CAAlC,CAAgE4iB,CAAhE,CArDgD,CAjGpD,GAAKtN,CAAA,CAAM,CAAN,CAAL,CAAA,CAF0C,IAItCoM,EAAapM,CAAA,CAAM,CAAN,CACbiL,EAAAA,CAAcjL,CAAA,CAAM,CAAN,CALwB,KAMtClP,EAAWltD,CAAAktD,SAN2B,CAOtCie,EAAanrE,CAAAoQ,UAPyB,CAQtCy6D,EAAa,CAAA,CARyB,CAStCnC,CATsC,CAUtCiB,EAAkB,CAAA,CAVoB,CAatCuB,EAAiBznE,CAAA,CAAO3H,CAAAya,cAAA,CAAuB,QAAvB,CAAP,CAbqB,CActCy0D,EAAkBvnE,CAAA,CAAO3H,CAAAya,cAAA,CAAuB,UAAvB,CAAP,CAdoB,CAetC+wD,EAAgB4D,CAAAxnE,MAAA,EAGZpG,EAAAA,CAAI,CAAZ,KAlB0C,IAkB3B6uC,EAAW7rC,CAAA6rC,SAAA,EAlBgB,CAkBIluC,EAAKkuC,CAAA/vC,OAAnD,CAAoEkB,CAApE,CAAwEW,CAAxE,CAA4EX,CAAA,EAA5E,CACE,GAA0B,EAA1B,GAAI6uC,CAAA,CAAS7uC,CAAT,CAAAG,MAAJ,CAA8B,CAC5BirE,CAAA,CAAcmC,CAAd,CAA2B1+B,CAAAsI,GAAA,CAAYn3C,CAAZ,CAC3B,MAF4B,CAMhCkrE,CAAAhB,KAAA,CAAgBH,CAAhB,CAA6BwD,CAA7B,CAAyCvD,CAAzC,CAGIpa,EAAJ,GACEma,CAAAthB,SADF,CACyB4lB,QAAQ,CAACluE,CAAD,CAAQ,CACrC,MAAO,CAACA,CAAR,EAAkC,CAAlC,GAAiBA,CAAArB,OADoB,CADzC,CAMI+uE,EAAJ,CAAgBrC,CAAA,CAAepiE,CAAf,CAAsBpG,CAAtB,CAA+B+mE,CAA/B,CAAhB,CACSna,CAAJ,CAAcyb,CAAA,CAAgBjiE,CAAhB,CAAuBpG,CAAvB,CAAgC+mE,CAAhC,CAAd,CACAiB,CAAA,CAAc5hE,CAAd,CAAqBpG,CAArB,CAA8B+mE,CAA9B,CAA2CmB,CAA3C,CAlCL,CAF0C,CAnEvC,CANiE,CAApD,CAv7DtB,CAi8EI/6D,GAAkB,CAAC,cAAD,CAAiB,QAAQ,CAACwF,CAAD,CAAe,CAC5D,IAAI24D;AAAiB,CACnB/D,UAAWhpE,CADQ,CAEnBkpE,aAAclpE,CAFK,CAKrB,OAAO,CACLwqB,SAAU,GADL,CAELF,SAAU,GAFL,CAGLxiB,QAASA,QAAQ,CAACrG,CAAD,CAAUN,CAAV,CAAgB,CAC/B,GAAIf,CAAA,CAAYe,CAAAvC,MAAZ,CAAJ,CAA6B,CAC3B,IAAI83B,EAAgBtiB,CAAA,CAAa3S,CAAAg1B,KAAA,EAAb,CAA6B,CAAA,CAA7B,CACfC,EAAL,EACEv1B,CAAAi0B,KAAA,CAAU,OAAV,CAAmB3zB,CAAAg1B,KAAA,EAAnB,CAHyB,CAO7B,MAAO,SAAS,CAAC5uB,CAAD,CAAQpG,CAAR,CAAiBN,CAAjB,CAAuB,CAAA,IAEjCtB,EAAS4B,CAAA5B,OAAA,EAFwB,CAGjC8pE,EAAa9pE,CAAAmI,KAAA,CAFIglE,mBAEJ,CAAbrD,EACE9pE,CAAAA,OAAA,EAAAmI,KAAA,CAHeglE,mBAGf,CAEDrD,EAAL,EAAoBA,CAAAjB,UAApB,GACEiB,CADF,CACeoD,CADf,CAIIr2C,EAAJ,CACE7uB,CAAAhH,OAAA,CAAa61B,CAAb,CAA4Bu2C,QAA+B,CAACpqD,CAAD,CAASC,CAAT,CAAiB,CAC1E3hB,CAAAi0B,KAAA,CAAU,OAAV,CAAmBvS,CAAnB,CACIC,EAAJ,GAAeD,CAAf,EACE8mD,CAAAT,aAAA,CAAwBpmD,CAAxB,CAEF6mD,EAAAX,UAAA,CAAqBnmD,CAArB,CAA6BphB,CAA7B,CAL0E,CAA5E,CADF,CASEkoE,CAAAX,UAAA,CAAqB7nE,CAAAvC,MAArB,CAAiC6C,CAAjC,CAGFA,EAAA+H,GAAA,CAAW,UAAX,CAAuB,QAAQ,EAAG,CAChCmgE,CAAAT,aAAA,CAAwB/nE,CAAAvC,MAAxB,CADgC,CAAlC,CAtBqC,CARR,CAH5B,CANqD,CAAxC,CAj8EtB,CAg/EI8P,GAAiBvO,EAAA,CAAQ,CAC3BqqB,SAAU,GADiB,CAE3BsD,SAAU,CAAA,CAFiB,CAAR,CAKf9wB,EAAAoL,QAAA9B,UAAJ;AAEEsmC,OAAAE,IAAA,CAAY,gDAAZ,CAFF,EAQA1jC,EAAA,EAIA,CAFA+D,EAAA,CAAmB/E,EAAnB,CAEA,CAAAxD,CAAA,CAAO3H,CAAP,CAAAwwD,MAAA,CAAuB,QAAQ,EAAG,CAChCpnD,EAAA,CAAYpJ,CAAZ,CAAsBqJ,EAAtB,CADgC,CAAlC,CAZA,CAx9xBqC,CAAtC,CAAD,CAw+xBGtJ,MAx+xBH,CAw+xBWC,QAx+xBX,CA0+xBC,EAAAD,MAAAoL,QAAA8kE,MAAA,EAAD,EAA2BlwE,MAAAoL,QAAA3G,QAAA,CAAuBxE,QAAvB,CAAAmE,KAAA,CAAsC,MAAtC,CAAA+tD,QAAA,CAAsD,8MAAtD;",
+"sources":["angular.js"],
+"names":["window","document","undefined","minErr","isArrayLike","obj","isWindow","length","nodeType","NODE_TYPE_ELEMENT","isString","isArray","forEach","iterator","context","key","isFunction","hasOwnProperty","call","isPrimitive","sortedKeys","keys","push","sort","forEachSorted","i","reverseParams","iteratorFn","value","nextUid","uid","setHashKey","h","$$hashKey","extend","dst","ii","arguments","Object","j","jj","int","str","parseInt","inherit","parent","extra","prototype","noop","identity","$","valueFn","isUndefined","isDefined","isObject","isNumber","isDate","toString","isRegExp","isScope","$evalAsync","$watch","isBoolean","isElement","node","nodeName","prop","attr","find","makeMap","items","split","nodeName_","element","lowercase","arrayRemove","array","index","indexOf","splice","copy","source","destination","stackSource","stackDest","ngMinErr","result","Date","getTime","RegExp","match","lastIndex","emptyObject","create","getPrototypeOf","shallowCopy","src","charAt","equals","o1","o2","t1","t2","keySet","concat","array1","array2","slice","bind","self","fn","curryArgs","startIndex","apply","toJsonReplacer","val","toJson","pretty","JSON","stringify","fromJson","json","parse","startingTag","jqLite","clone","empty","e","elemHtml","append","html","NODE_TYPE_TEXT","replace","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","key_value","toKeyValue","parts","arrayValue","encodeUriQuery","join","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","getNgAttribute","ngAttr","ngAttrPrefixes","angularInit","bootstrap","appElement","module","config","prefix","name","hasAttribute","getAttribute","candidate","querySelector","strictDi","modules","defaultConfig","doBootstrap","injector","tag","unshift","$provide","debugInfoEnabled","$compileProvider","createInjector","invoke","bootstrapApply","scope","compile","$apply","data","NG_ENABLE_DEBUG_INFO","NG_DEFER_BOOTSTRAP","test","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","reloadWithDebugInfo","location","reload","getTestability","rootElement","get","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","bindJQuery","originalCleanData","bindJQueryFired","jQuery","on","JQLitePrototype","isolateScope","controller","inheritedData","cleanData","jQuery.cleanData","elems","events","skipDestroyOnNextJQueryCleanData","elem","_data","$destroy","triggerHandler","JQLite","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","constructor","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockNodes","nodes","endNode","blockNodes","nextSibling","createMap","setupModuleLoader","ensure","factory","$injectorMinErr","$$minErr","requires","configFn","invokeLater","provider","method","insertMethod","queue","invokeQueue","moduleInstance","configBlocks","runBlocks","_invokeQueue","_configBlocks","_runBlocks","service","constant","animation","filter","directive","run","block","publishExternalAPI","version","uppercase","counter","csp","angularModule","$LocaleProvider","ngModule","$$sanitizeUri","$$SanitizeUriProvider","$CompileProvider","a","htmlAnchorDirective","input","inputDirective","textarea","form","formDirective","script","scriptDirective","select","selectDirective","style","styleDirective","option","optionDirective","ngBind","ngBindDirective","ngBindHtml","ngBindHtmlDirective","ngBindTemplate","ngBindTemplateDirective","ngClass","ngClassDirective","ngClassEven","ngClassEvenDirective","ngClassOdd","ngClassOddDirective","ngCloak","ngCloakDirective","ngController","ngControllerDirective","ngForm","ngFormDirective","ngHide","ngHideDirective","ngIf","ngIfDirective","ngInclude","ngIncludeDirective","ngInit","ngInitDirective","ngNonBindable","ngNonBindableDirective","ngPluralize","ngPluralizeDirective","ngRepeat","ngRepeatDirective","ngShow","ngShowDirective","ngStyle","ngStyleDirective","ngSwitch","ngSwitchDirective","ngSwitchWhen","ngSwitchWhenDirective","ngSwitchDefault","ngSwitchDefaultDirective","ngOptions","ngOptionsDirective","ngTransclude","ngTranscludeDirective","ngModel","ngModelDirective","ngList","ngListDirective","ngChange","ngChangeDirective","pattern","patternDirective","ngPattern","required","requiredDirective","ngRequired","minlength","minlengthDirective","ngMinlength","maxlength","maxlengthDirective","ngMaxlength","ngValue","ngValueDirective","ngModelOptions","ngModelOptionsDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$anchorScroll","$AnchorScrollProvider","$animate","$AnimateProvider","$browser","$BrowserProvider","$cacheFactory","$CacheFactoryProvider","$controller","$ControllerProvider","$document","$DocumentProvider","$exceptionHandler","$ExceptionHandlerProvider","$filter","$FilterProvider","$interpolate","$InterpolateProvider","$interval","$IntervalProvider","$http","$HttpProvider","$httpBackend","$HttpBackendProvider","$location","$LocationProvider","$log","$LogProvider","$parse","$ParseProvider","$rootScope","$RootScopeProvider","$q","$QProvider","$$q","$$QProvider","$sce","$SceProvider","$sceDelegate","$SceDelegateProvider","$sniffer","$SnifferProvider","$templateCache","$TemplateCacheProvider","$templateRequest","$TemplateRequestProvider","$$testability","$$TestabilityProvider","$timeout","$TimeoutProvider","$window","$WindowProvider","$$rAF","$$RAFProvider","$$asyncCallback","$$AsyncCallbackProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLiteAcceptsData","NODE_TYPE_DOCUMENT","jqLiteBuildFragment","tmp","fragment","createDocumentFragment","HTML_REGEXP","appendChild","createElement","TAG_NAME_REGEXP","exec","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","lastChild","childNodes","firstChild","textContent","createTextNode","argIsString","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","jqLiteAddNodes","jqLiteClone","cloneNode","jqLiteDealoc","onlyDescendants","jqLiteRemoveData","querySelectorAll","descendants","l","jqLiteOff","type","unsupported","expandoStore","jqLiteExpandoStore","handle","listenerFns","removeEventListener","expandoId","ng339","jqCache","createIfNecessary","jqId","jqLiteData","isSimpleSetter","isSimpleGetter","massGetter","jqLiteHasClass","selector","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","elements","jqLiteController","jqLiteInheritedData","documentElement","names","parentNode","NODE_TYPE_DOCUMENT_FRAGMENT","host","jqLiteEmpty","removeChild","jqLiteRemove","keepData","jqLiteDocumentLoaded","action","win","readyState","setTimeout","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","getAliasedAttrName","ALIASED_ATTR","createEventHandler","eventHandler","event","isDefaultPrevented","event.isDefaultPrevented","defaultPrevented","eventFns","eventFnsLength","immediatePropagationStopped","originalStopImmediatePropagation","stopImmediatePropagation","event.stopImmediatePropagation","stopPropagation","isImmediatePropagationStopped","event.isImmediatePropagationStopped","hashKey","nextUidFn","objType","HashMap","isolatedUid","this.nextUid","put","anonFn","args","fnText","STRIP_COMMENTS","FN_ARGS","annotate","$inject","argDecl","FN_ARG_SPLIT","FN_ARG","all","underscore","last","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","$get","providerCache","providerSuffix","enforceReturnValue","enforcedReturnValue","instanceInjector","factoryFn","enforce","loadModules","moduleFn","runInvokeQueue","invokeArgs","loadedModules","message","stack","createInternalInjector","cache","getService","serviceName","INSTANTIATING","err","shift","locals","Type","Constructor","instance","returnedValue","has","$injector","instanceCache","decorator","decorFn","origProvider","orig$get","origProvider.$get","origInstance","$delegate","servicename","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","getFirstAnchor","list","Array","some","scrollTo","scrollIntoView","scroll","yOffset","getComputedStyle","position","getBoundingClientRect","bottom","elemTop","top","scrollBy","hash","elm","getElementById","getElementsByName","autoScrollWatch","autoScrollWatchAction","newVal","oldVal","supported","Browser","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","startPoller","interval","check","pollFns","pollFn","pollTimeout","cacheStateAndFireUrlChange","cacheState","fireUrlChange","cachedState","history","state","lastCachedState","lastBrowserUrl","url","lastHistoryState","urlChangeListeners","listener","safeDecodeURIComponent","rawDocument","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","addPollFn","self.addPollFn","href","baseElement","reloadLocation","self.url","sameState","sameBase","stripHash","self.state","urlChangeInit","onUrlChange","self.onUrlChange","$$checkUrlChange","baseHref","self.baseHref","lastCookies","lastCookieString","cookiePath","cookies","self.cookies","cookieLength","cookie","warn","cookieArray","substring","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","this.$get","cacheFactory","cacheId","options","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","id","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$$sanitizeUriProvider","parseIsolateBindings","directiveName","LOCAL_REGEXP","bindings","definition","scopeName","$compileMinErr","attrName","mode","optional","hasDirectives","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","ALL_OR_NOTHING_ATTRS","REQUIRE_PREFIX_REGEXP","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","Suffix","directives","priority","require","restrict","$$isolateBindings","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","this.debugInfoEnabled","enabled","safeAddClass","$element","className","addClass","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","nodeValue","compositeLinkFn","compileNodes","$$addScopeClass","namespace","publicLinkFn","cloneConnectFn","transcludeControllers","parentBoundTranscludeFn","futureParentElement","$linkNode","wrapTemplate","controllerName","$$addScopeInfo","nodeList","$rootElement","childLinkFn","childScope","childBoundTranscludeFn","stableNodeList","nodeLinkFnFound","linkFns","idx","nodeLinkFn","$new","transcludeOnThisElement","createBoundTranscludeFn","transclude","elementTranscludeOnThisElement","templateOnThisElement","attrs","linkFnFound","Attributes","collectDirectives","applyDirectivesToNode","$$element","terminal","previousBoundTranscludeFn","elementTransclusion","boundTranscludeFn","transcludedScope","cloneFn","controllers","containingScope","$$transcluded","attrsMap","$attr","addDirective","directiveNormalize","nName","isNgAttr","nAttrs","attributes","attrStartName","attrEndName","ngAttrName","NG_ATTR_BINDING","substr","directiveNName","multiElement","addAttrInterpolateDirective","addTextInterpolateDirective","NODE_TYPE_COMMENT","byPriority","groupScan","attrStart","attrEnd","depth","groupElementsLinkFnWrapper","linkFn","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","getControllers","elementControllers","retrievalMethod","$searchElement","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","scopeToChild","controllerDirectives","$scope","$attrs","$transclude","controllerInstance","controllerAs","templateDirective","$$originalDirective","isolateScopeController","isolateBindingContext","identifier","bindToController","lastValue","parentGet","parentSet","compare","$observe","$$observers","$$scope","literal","b","assign","parentValueWatch","parentValue","$stateful","unwatch","$on","invokeLinkFn","template","templateUrl","terminalPriority","newScopeDirective","nonTlbTranscludeDirective","hasTranscludeDirective","hasTemplate","$compileNode","$template","childTranscludeFn","$$start","$$end","directiveValue","assertNoDuplicate","$$tlb","createComment","replaceWith","replaceDirective","contents","denormalizeTemplate","removeComments","templateNamespace","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectivesAsIsolate","mergeTemplateAttributes","compileTemplateUrl","Math","max","tDirectives","startAttrName","endAttrName","srcAttr","dstAttr","$set","tAttrs","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","getTrustedResourceUrl","then","content","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","$$destroyed","oldClasses","delayedNodeLinkFn","ignoreChildLinkFn","diff","what","previousDirective","text","interpolateFn","textInterpolateCompileFn","templateNode","templateNodeParent","hasCompileParent","$$addBindingClass","textInterpolateLinkFn","$$addBindingInfo","expressions","interpolateFnWatchAction","wrapper","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","allOrNothing","attrInterpolatePreLinkFn","$$inter","newValue","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","replaceChild","expando","k","kk","annotation","attributesToCopy","$normalize","$addClass","classVal","$removeClass","removeClass","newClasses","toAdd","tokenDifference","toRemove","writeAttr","booleanKey","aliasedKey","observer","trimmedSrcset","srcPattern","rawUris","nbrUrisWith2parts","floor","innerIdx","lastTuple","removeAttr","listeners","startSymbol","endSymbol","binding","isolated","noTemplate","dataName","PREFIX_REGEXP","str1","str2","values","tokens1","tokens2","token","jqNodes","globals","CNTRL_REG","register","this.register","allowGlobals","this.allowGlobals","addIdentifier","expression","later","ident","exception","cause","parseHeaders","headers","line","headersGetter","headersObj","transformData","fns","JSON_START","JSON_END","PROTECTION_PREFIX","CONTENT_TYPE_APPLICATION_JSON","defaults","transformResponse","defaultHttpResponseTransform","contentType","APPLICATION_JSON","transformRequest","d","common","patch","xsrfCookieName","xsrfHeaderName","useApplyAsync","this.useApplyAsync","interceptorFactories","interceptors","requestConfig","response","resp","status","reject","mergeHeaders","defHeaders","reqHeaders","defHeaderName","reqHeaderName","lowercaseDefHeaderName","execHeaders","headerContent","headerFn","header","chain","serverRequest","reqData","withCredentials","sendReq","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","success","promise.success","promise.error","done","headersString","statusText","resolveHttpPromise","resolvePromise","$applyAsync","$$phase","deferred","resolve","removePendingReq","pendingRequests","cachedResp","buildUrl","params","defaultCache","xsrfValue","urlIsSameOrigin","timeout","responseType","v","toISOString","interceptorFactory","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","createHttpBackend","callbacks","$browserDefer","jsonpReq","callbackId","async","body","called","addEventListener","timeoutRequest","jsonpDone","xhr","abort","completeRequest","open","setRequestHeader","onload","xhr.onload","responseText","urlResolve","protocol","getAllResponseHeaders","onerror","onabort","send","this.startSymbol","this.endSymbol","escape","ch","mustHaveExpression","trustedContext","unescapeText","escapedStartRegexp","escapedEndRegexp","parseStringifyInterceptor","getTrusted","valueOf","newErr","$interpolateMinErr","endIndex","parseFns","textLength","expressionPositions","startSymbolLength","exp","endSymbolLength","compute","interpolationFn","$$watchDelegate","objectEquality","$watchGroup","interpolateFnWatcher","oldValues","currValue","$interpolate.startSymbol","$interpolate.endSymbol","count","invokeApply","setInterval","clearInterval","iteration","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","NUMBER_FORMATS","DECIMAL_SEP","GROUP_SEP","PATTERNS","minInt","minFrac","maxFrac","posPre","posSuf","negPre","negSuf","gSize","lgSize","CURRENCY_SYM","DATETIME_FORMATS","MONTH","SHORTMONTH","DAY","SHORTDAY","AMPMS","medium","short","fullDate","longDate","mediumDate","shortDate","mediumTime","shortTime","pluralCat","num","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","appBase","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","beginsWith","begin","whole","stripFile","lastIndexOf","LocationHtml5Url","basePrefix","$$html5","appBaseNoFile","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$parseLinkUrl","this.$$parseLinkUrl","relHref","appUrl","prevAppUrl","rewrittenUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","property","locationGetterSetter","preprocess","html5Mode","requireBase","rewriteLinks","this.hashPrefix","this.html5Mode","setBrowserUrlWithFallback","oldUrl","oldState","$$state","afterLocationChange","$broadcast","absUrl","LocationMode","initialUrl","IGNORE_URI_REGEXP","ctrlKey","metaKey","which","target","absHref","animVal","preventDefault","initializing","newUrl","newState","$digest","$locationWatch","currentReplace","$$replace","urlOrStateChanged","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","ensureSafeMemberName","fullExpression","$parseMinErr","ensureSafeObject","children","isConstant","setter","setValue","fullExp","propertyObj","cspSafeGetterFn","key0","key1","key2","key3","key4","cspSafeGetter","pathVal","getterFn","getterFnCache","pathKeys","pathKeysLength","code","evaledFnGetter","Function","sharedGetter","fn.assign","$parseOptions","wrapSharedExpression","wrapped","collectExpressionInputs","inputs","expressionInputDirtyCheck","oldValueOfValue","inputsWatchDelegate","parsedExpression","inputExpressions","$$inputs","lastResult","oldInputValue","expressionInputWatch","newInputValue","oldInputValueOfValues","expressionInputsWatch","changed","oneTimeWatchDelegate","oneTimeWatch","oneTimeListener","old","$$postDigest","oneTimeLiteralWatchDelegate","isAllDefined","allDefined","constantWatchDelegate","constantWatch","constantListener","addInterceptor","interceptorFn","oneTime","cacheKey","lexer","Lexer","parser","Parser","qFactory","nextTick","exceptionHandler","callOnce","resolveFn","Promise","simpleBind","scheduleProcessQueue","processScheduled","pending","Deferred","$qMinErr","TypeError","onFulfilled","onRejected","progressBack","catch","finally","handleCallback","$$reject","$$resolve","progress","makePromise","resolved","isResolved","callbackOutput","errback","$Q","Q","resolver","promises","results","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","timer","TTL","$rootScopeMinErr","lastDirtyWatch","applyAsyncId","digestTtl","this.digestTtl","Scope","$id","$parent","$$watchers","$$nextSibling","$$prevSibling","$$childHead","$$childTail","$root","$$listeners","$$listenerCount","beginPhase","phase","decrementListenerCount","current","initWatchVal","flushApplyAsync","applyAsyncQueue","scheduleApplyAsync","isolate","destroyChild","child","$$ChildScope","this.$$ChildScope","watchExp","watcher","eq","deregisterWatch","watchExpressions","watchGroupAction","changeReactionScheduled","firstRun","newValues","deregisterFns","shouldCall","deregisterWatchGroup","expr","unwatchFn","watchGroupSubAction","$watchCollection","$watchCollectionInterceptor","_value","bothNaN","newItem","oldItem","internalArray","oldLength","changeDetected","newLength","internalObject","veryOldValue","trackVeryOldValue","changeDetector","initRun","$watchCollectionAction","watch","watchers","dirty","ttl","watchLog","logIdx","logMsg","asyncTask","asyncQueue","$eval","isNaN","next","postDigestQueue","eventName","this.$watchGroup","$applyAsyncExpression","namedListeners","$emit","targetScope","listenerArgs","currentScope","$$asyncQueue","$$postDigestQueue","$$applyAsyncQueue","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","matchUrl","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","maybeTrusted","allowed","this.enabled","documentMode","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","enumValue","lName","eventSupport","android","userAgent","navigator","boxee","vendorPrefix","vendorRegex","bodyStyle","transitions","animations","webkitTransition","webkitAnimation","pushState","hasEvent","msie","divElm","handleRequestFn","tpl","ignoreRequestError","handleError","totalPendingRequests","testability","testability.findBindings","opt_exactMatch","getElementsByClassName","matches","dataBinding","bindingName","testability.findModels","prefixes","attributeEquals","testability.getLocation","testability.setLocation","testability.whenStable","deferreds","$$timeoutId","timeout.cancel","base","urlParsingNode","requestUrl","originUrl","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","comparatorType","predicates","predicates.check","objKey","filtered","$locale","formats","amount","currencySymbol","fractionSize","formatNumber","number","groupSep","decimalSep","isFinite","isNegative","abs","numStr","formatedText","hasExponent","toFixed","fractionLen","min","round","fraction","lgroup","group","padNumber","digits","neg","dateGetter","date","dateStrGetter","shortForm","getFirstThursdayOfYear","year","dayOfWeekOnFirst","getDay","weekGetter","firstThurs","getFullYear","thisThurs","getMonth","getDate","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","s","ms","parseFloat","format","timezone","NUMBER_STRING","DATE_FORMATS_SPLIT","setMinutes","getMinutes","getTimezoneOffset","DATE_FORMATS","object","limit","Infinity","out","sortPredicate","reverseOrder","reverseComparator","comp","descending","v1","v2","map","predicate","arrayCopy","ngDirective","FormController","controls","parentForm","$$parentForm","nullFormCtrl","$error","$$success","$pending","$name","$dirty","$pristine","$valid","$invalid","$submitted","$addControl","$rollbackViewValue","form.$rollbackViewValue","control","$commitViewValue","form.$commitViewValue","form.$addControl","$$renameControl","form.$$renameControl","newName","oldName","$removeControl","form.$removeControl","$setValidity","addSetValidityMethod","ctrl","set","unset","$setDirty","form.$setDirty","PRISTINE_CLASS","DIRTY_CLASS","$setPristine","form.$setPristine","setClass","SUBMITTED_CLASS","$setUntouched","form.$setUntouched","$setSubmitted","form.$setSubmitted","stringBasedInputType","$formatters","$isEmpty","baseInputType","VALIDITY_STATE_PROPERTY","placeholder","noevent","composing","ev","ngTrim","$viewValue","$$hasNativeValidators","$setViewValue","deferListener","keyCode","$render","ctrl.$render","$modelValue","createDateParser","mapping","iso","ISO_DATE_REGEXP","yyyy","MM","dd","HH","getHours","mm","ss","getSeconds","sss","getMilliseconds","part","NaN","createDateInputType","parseDate","dynamicDateInputType","parseObservedDateValue","badInputChecker","$options","previousDate","$$parserName","$parsers","parsedDate","$ngModelMinErr","timezoneOffset","ngMin","minVal","$validators","ctrl.$validators.min","$validate","ngMax","maxVal","ctrl.$validators.max","ctrl.$isEmpty","validity","badInput","typeMismatch","parseConstantExpr","fallback","parseFn","cachedToggleClass","switchValue","classCache","toggleValidationCss","validationErrorKey","isValid","VALID_CLASS","INVALID_CLASS","hasClass","setValidity","isObjectEmpty","PENDING_CLASS","combinedState","classDirective","arrayDifference","arrayClasses","classes","digestClassCounts","classCounts","classesToUpdate","ngClassWatchAction","$index","old$index","mod","REGEX_STRING_REGEXP","isActive_","active","full","major","minor","dot","codeName","JQLite._data","MOUSE_EVENT_MAP","mouseleave","mouseenter","optgroup","tbody","tfoot","colgroup","caption","thead","th","td","ready","trigger","fired","removeData","removeAttribute","css","lowercasedName","specified","getNamedItem","ret","getText","$dv","multiple","selected","nodeCount","jqLiteOn","types","related","relatedTarget","contains","off","one","onFn","replaceNode","insertBefore","contentDocument","prepend","wrapNode","detach","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","extraParameters","dummyEvent","handlerArgs","eventFnsCopy","arg3","unbind","$$annotate","$animateMinErr","$$selectors","classNameFilter","this.classNameFilter","$$classNameFilter","runAnimationPostDigest","cancelFn","$$cancelFn","defer.promise.$$cancelFn","ngAnimatePostDigest","ngAnimateNotifyComplete","resolveElementClasses","hasClasses","cachedClassManipulation","op","asyncPromise","currentDefer","applyStyles","styles","from","to","animate","enter","leave","move","$$addClassImmediately","$$removeClassImmediately","add","createdCache","STORAGE_KEY","$$setClassImmediately","PATH_MATCH","locationPrototype","paramValue","Location","Location.prototype.state","CALL","APPLY","BIND","CONSTANTS","null","true","false","constantGetter","OPERATORS","+","-","*","/","%","===","!==","==","!=","<",">","<=",">=","&&","||","!","ESCAPE","lex","tokens","is","readString","peek","readNumber","isIdent","readIdent","isWhitespace","ch2","ch3","fn2","fn3","throwError","chars","isExpOperator","start","end","colStr","peekCh","lastDot","peekIndex","methodName","quote","rawString","hex","String","fromCharCode","rep","ZERO","statements","primary","expect","filterChain","consume","arrayDeclaration","functionCall","objectIndex","fieldAccess","msg","peekToken","e1","e2","e3","e4","t","unaryFn","right","$parseUnaryFn","binaryFn","left","isBranching","$parseBinaryFn","$parseStatements","inputFn","argsFn","$parseFilter","every","assignment","ternary","$parseAssignment","logicalOR","middle","$parseTernary","logicalAND","equality","relational","additive","multiplicative","unary","field","$parseFieldAccess","o","indexFn","$parseObjectIndex","fnGetter","contextGetter","expressionText","$parseFunctionCall","elementFns","elementFn","$parseArrayLiteral","valueFns","$parseObjectLiteral","yy","y","MMMM","MMM","M","H","hh","EEEE","EEE","ampmGetter","Z","timeZoneGetter","zone","paddedZone","ww","w","xlinkHref","propName","normalized","ngBooleanAttrWatchAction","htmlAttr","ngAttrAliasWatchAction","nullFormRenameControl","formDirectiveFactory","isNgForm","ngFormCompile","formElement","ngFormPreLink","handleFormSubmission","returnValue","parentFormCtrl","alias","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","DATE_REGEXP","DATETIMELOCAL_REGEXP","WEEK_REGEXP","MONTH_REGEXP","TIME_REGEXP","DEFAULT_REGEXP","inputType","textInputType","weekParser","isoWeek","existingDate","week","minutes","hours","seconds","milliseconds","addDays","numberInputType","urlInputType","ctrl.$validators.url","emailInputType","email","ctrl.$validators.email","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrls","NgModelController","$asyncValidators","$viewChangeListeners","$untouched","$touched","parsedNgModel","pendingDebounce","ngModelGet","modelValue","getterSetter","ngModelSet","$$setOptions","this.$$setOptions","this.$isEmpty","currentValidationRunId","this.$setPristine","this.$setUntouched","UNTOUCHED_CLASS","TOUCHED_CLASS","$setTouched","this.$setTouched","this.$rollbackViewValue","$$lastCommittedViewValue","this.$validate","$$parseAndValidate","$$runValidators","this.$$runValidators","parseValid","viewValue","doneCallback","processSyncValidators","syncValidatorsValid","validator","processAsyncValidators","validatorPromises","allValid","validationDone","localValidationRunId","processParseErrors","errorKey","this.$commitViewValue","this.$$parseAndValidate","parserValid","prevModelValue","allowInvalid","$$writeModelToScope","this.$$writeModelToScope","this.$setViewValue","updateOnDefault","$$debounceViewValueCommit","this.$$debounceViewValueCommit","debounceDelay","debounce","ngModelWatch","formatters","ngModelCompile","ngModelPreLink","modelCtrl","formCtrl","ngModelPostLink","updateOn","ctrl.$validators.required","patternExp","ctrl.$validators.pattern","ctrl.$validators.maxlength","ctrl.$validators.minlength","trimValues","CONSTANT_VALUE_REGEXP","tplAttr","ngValueConstantLink","ngValueLink","valueWatchAction","that","$compile","ngBindCompile","templateElement","ngBindLink","ngBindWatchAction","ngBindTemplateCompile","ngBindTemplateLink","ngBindHtmlCompile","tElement","ngBindHtmlGetter","ngBindHtmlWatch","getStringValue","ngBindHtmlLink","ngBindHtmlWatchAction","getTrustedHtml","forceAsyncEvents","ngEventHandler","$event","previousElements","ngIfWatchAction","newScope","srcExp","onloadExp","autoScrollExp","autoscroll","changeCounter","previousElement","currentElement","cleanupLastIncludeContent","parseAsResourceUrl","ngIncludeWatchAction","afterAnimation","thisChangeId","namespaceAdaptedClone","BRACE","numberExp","whenExp","whens","whensExpFns","isWhen","attributeName","ngPluralizeWatch","ngPluralizeWatchAction","ngRepeatMinErr","updateScope","valueIdentifier","keyIdentifier","arrayLength","$first","$last","$middle","$odd","$even","ngRepeatCompile","ngRepeatEndComment","lhs","rhs","aliasAs","trackByExp","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","hashFnLocals","ngRepeatLink","lastBlockMap","ngRepeatAction","collection","previousNode","nextNode","nextBlockMap","collectionLength","trackById","collectionKeys","nextBlockOrder","trackByIdFn","itemKey","blockKey","ngRepeatTransclude","ngShowWatchAction","NG_HIDE_CLASS","tempClasses","NG_HIDE_IN_PROGRESS_CLASS","ngHideWatchAction","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","previousLeaveAnimations","selectedScopes","spliceFactory","ngSwitchWatchAction","selectedTransclude","caseElement","selectedScope","anchor","ngOptionsMinErr","NG_OPTIONS_REGEXP","nullModelCtrl","optionsMap","ngModelCtrl","unknownOption","databound","init","self.init","ngModelCtrl_","nullOption_","unknownOption_","addOption","self.addOption","removeOption","self.removeOption","hasOption","renderUnknownOption","self.renderUnknownOption","unknownVal","self.hasOption","setupAsSingle","selectElement","selectCtrl","ngModelCtrl.$render","emptyOption","setupAsMultiple","lastView","selectMultipleWatch","setupAsOptions","callExpression","exprFn","valueName","keyName","createIsSelectedFn","selectedSet","trackFn","trackIndex","isSelected","compareValueFn","selectAsFn","scheduleRendering","renderScheduled","render","updateLabelMap","labelMap","label","added","optionGroups","optionGroupNames","optionGroupName","optionGroup","existingParent","existingOptions","existingOption","valuesFn","groupIndex","anySelected","groupByFn","displayFn","nullOption","groupLength","optionGroupsCache","optGroupTemplate","lastElement","optionTemplate","optionsExp","selectAs","track","selectionChanged","selectedKey","viewValueFn","getLabels","toDisplay","ngModelCtrl.$isEmpty","nullSelectCtrl","selectCtrlName","interpolateWatchAction","$$csp"]
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-new.js b/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-new.js
new file mode 100644 (file)
index 0000000..6675e49
--- /dev/null
@@ -0,0 +1,296 @@
+'use strict';
+
+var directiveModule = angular.module('angularjs-dropdown-multiselect-new', ['vs-repeat']);
+
+directiveModule.directive('ngDropdownMultiselectNew', ['$filter', '$document', '$compile', '$parse',
+    function ($filter, $document, $compile, $parse) {
+
+        return {
+            restrict: 'AE',
+            scope: {
+                selectedModel: '=',
+                options: '=',
+                extraSettings: '=',
+                events: '=',
+                searchFilter: '=?',
+                translationTexts: '=',
+                groupBy: '@'
+            },
+            template: function (element, attrs) {
+                var checkboxes = attrs.checkboxes ? true : false;
+                var groups = attrs.groupBy ? true : false;
+
+                var template = '<div class="multiselect-parent btn-group dropdown-multiselect" style="width:100%;">';
+                template += '<div style="width:100%;" class="dropdown-toggle" ng-class="settings.buttonClasses" ng-click="toggleDropdown()">{{getButtonText()}}&nbsp;<span class="caret"></span></div>';
+                template += '<ul class="dropdown-menu dropdown-menu-form" ng-style="{display: open ? \'block\' : \'none\', height : settings.scrollable ? settings.scrollableHeight : \'auto\' }" style="overflow: scroll; width:280px;" >';
+                template += '<li ng-hide="!settings.showCheckAll"><a data-ng-click="selectAll()"><span class="glyphicon glyphicon-ok"></span>  {{texts.checkAll}}</a>';
+                template += '<li ng-show="settings.showUncheckAll"><a data-ng-click="deselectAll();"><span class="glyphicon glyphicon-remove"></span>   {{texts.uncheckAll}}</a></li>';
+                template += '<li ng-hide="(!settings.showCheckAll) && !settings.showUncheckAll" class="divider"></li>';
+                template += '<li ng-show="settings.enableSearch"><div class="dropdown-header"><input type="text" class="form-control" style="width: 100%;" ng-model="searchFilter" placeholder="{{texts.searchPlaceholder}}" /></li>';
+                template += '<li ng-show="settings.enableSearch" class="divider"></li>';
+                       
+                template += '<div style="width:98%;" vs-repeat> ';
+                
+                if (groups) {
+                    template += '<li ng-repeat-start="option in orderedItems | filter: searchFilter" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header">{{ getGroupTitle(getPropertyForObject(option, settings.groupBy)) }}</li>';
+                    template += '<li ng-repeat-end role="presentation">';
+                } else {
+                    template += '<li role="presentation" ng-repeat="option in options| filter: searchFilter">';
+                }
+
+                template += '<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">';
+
+                if (checkboxes) {
+                    template += '<div class="checkbox"><label><input class="checkboxInput" type="checkbox" ng-click="checkboxClick($event, getPropertyForObject(option,settings.idProp))" ng-checked="isChecked(getPropertyForObject(option,settings.idProp))" /> {{getPropertyForObject(option, settings.displayProp)}}</label></div></a>';
+                } else {
+                    template += '<span data-ng-class="{\'glyphicon glyphicon-ok\': isChecked(getPropertyForObject(option,settings.idProp))}"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>';
+                }
+
+                template += '</li>';
+                template += '</div>';
+                
+
+                template += '<li class="divider" ng-show="settings.selectionLimit > 1"></li>';
+                template += '<li role="presentation" ng-show="settings.selectionLimit > 1"><a role="menuitem">{{selectedModel.length}} {{texts.selectionOf}} {{settings.selectionLimit}} {{texts.selectionCount}}</a></li>';
+
+                template += '</ul>';
+                template += '</div>';
+
+                element.html(template);
+            },
+            link: function ($scope, $element, $attrs) {
+                var $dropdownTrigger = $element.children()[0];
+                
+                $scope.toggleDropdown = function () {
+                    $scope.open = !$scope.open;
+                };
+
+                $scope.checkboxClick = function ($event, id) {
+                    $scope.setSelectedItem(id);
+                    $event.stopImmediatePropagation();
+                };
+
+                $scope.externalEvents = {
+                    onItemSelect: angular.noop,
+                    onItemDeselect: angular.noop,
+                    onSelectAll: angular.noop,
+                    onDeselectAll: angular.noop,
+                    onInitDone: angular.noop,
+                    onMaxSelectionReached: angular.noop
+                };
+
+                $scope.settings = {
+                    dynamicTitle: true,
+                    scrollable: false,
+                    scrollableHeight: '300px',
+                    closeOnBlur: true,
+                    displayProp: 'label',
+                    idProp: 'id',
+                    externalIdProp: 'id',
+                    enableSearch: false,
+                    selectionLimit: 0,
+                    showCheckAll: false,
+                    showUncheckAll: false,
+                    closeOnSelect: false,
+                    buttonClasses: 'btn btn-default',
+                    closeOnDeselect: false,
+                    groupBy: $attrs.groupBy || undefined,
+                    groupByTextProvider: null,
+                    smartButtonMaxItems: 0,
+                    smartButtonTextConverter: angular.noop
+                };
+
+                $scope.texts = {
+                    checkAll: 'Check All',
+                    uncheckAll: 'Uncheck All',
+                    selectionCount: 'checked',
+                    selectionOf: '/',
+                    searchPlaceholder: 'Search...',
+                    buttonDefaultText: 'Select',
+                    dynamicButtonTextSuffix: 'checked'
+                };
+
+                $scope.searchFilter = $scope.searchFilter || '';
+
+                if (angular.isDefined($scope.settings.groupBy)) {
+                    $scope.$watch('options', function (newValue) {
+                        if (angular.isDefined(newValue)) {
+                            $scope.orderedItems = $filter('orderBy')(newValue, $scope.settings.groupBy);
+                        }
+                    });
+                }
+
+                angular.extend($scope.settings, $scope.extraSettings || []);
+                angular.extend($scope.externalEvents, $scope.events || []);
+                angular.extend($scope.texts, $scope.translationTexts);
+
+                $scope.singleSelection = $scope.settings.selectionLimit === 1;
+
+                function getFindObj(id) {
+                    var findObj = {};
+
+                    if ($scope.settings.externalIdProp === '') {
+                        findObj[$scope.settings.idProp] = id;
+                    } else {
+                        findObj[$scope.settings.externalIdProp] = id;
+                    }
+
+                    return findObj;
+                }
+
+                function clearObject(object) {
+                    for (var prop in object) {
+                        delete object[prop];
+                    }
+                }
+
+                if ($scope.singleSelection) {
+                    if (angular.isArray($scope.selectedModel) && $scope.selectedModel.length === 0) {
+                        clearObject($scope.selectedModel);
+                    }
+                }
+
+                if ($scope.settings.closeOnBlur) {
+                    $document.on('click', function (e) {
+                        var target = e.target.parentElement;
+                        var parentFound = false;
+
+                        while (angular.isDefined(target) && target !== null && !parentFound) {
+                            if (_.contains(target.className.split(' '), 'multiselect-parent') && !parentFound) {
+                                if(target === $dropdownTrigger) {
+                                    parentFound = true;
+                                }
+                            }
+                            target = target.parentElement;
+                        }
+
+                        if (!parentFound) {
+                            $scope.$apply(function () {
+                                $scope.open = false;
+                            });
+                        }
+                    });
+                }
+
+                $scope.getGroupTitle = function (groupValue) {
+                    if ($scope.settings.groupByTextProvider !== null) {
+                        return $scope.settings.groupByTextProvider(groupValue);
+                    }
+
+                    return groupValue;
+                };
+
+                $scope.getButtonText = function () {
+                    if ($scope.settings.dynamicTitle && ($scope.selectedModel.length > 0 || (angular.isObject($scope.selectedModel) && _.keys($scope.selectedModel).length > 0))) {
+                        if ($scope.settings.smartButtonMaxItems > 0) {
+                            var itemsText = [];
+
+                            angular.forEach($scope.options, function (optionItem) {
+                                if ($scope.isChecked($scope.getPropertyForObject(optionItem, $scope.settings.idProp))) {
+                                    var displayText = $scope.getPropertyForObject(optionItem, $scope.settings.displayProp);
+                                    var converterResponse = $scope.settings.smartButtonTextConverter(displayText, optionItem);
+
+                                    itemsText.push(converterResponse ? converterResponse : displayText);
+                                }
+                            });
+
+                            if ($scope.selectedModel.length > $scope.settings.smartButtonMaxItems) {
+                                itemsText = itemsText.slice(0, $scope.settings.smartButtonMaxItems);
+                                itemsText.push('...');
+                            }
+
+                            return itemsText.join(', ');
+                        } else {
+                            var totalSelected;
+
+                            if ($scope.singleSelection) {
+                                totalSelected = ($scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp])) ? 1 : 0;
+                            } else {
+                                totalSelected = angular.isDefined($scope.selectedModel) ? $scope.selectedModel.length : 0;
+                            }
+
+                            if (totalSelected === 0) {
+                                return $scope.texts.buttonDefaultText;
+                            } else {
+                                return totalSelected + ' ' + $scope.texts.dynamicButtonTextSuffix;
+                            }
+                        }
+                    } else {
+                        return $scope.texts.buttonDefaultText;
+                    }
+                };
+
+                $scope.getPropertyForObject = function (object, property) {
+                    if (angular.isDefined(object) && object.hasOwnProperty(property)) {
+                        return object[property];
+                    }
+
+                    return '';
+                };
+
+                $scope.selectAll = function () {
+                    $scope.deselectAll(false);
+                    $scope.externalEvents.onSelectAll();
+
+                    angular.forEach($scope.options, function (value) {
+                        $scope.setSelectedItem(value[$scope.settings.idProp], true);
+                    });
+                };
+
+                $scope.deselectAll = function (sendEvent) {
+                    sendEvent = sendEvent || true;
+
+                    if (sendEvent) {
+                        $scope.externalEvents.onDeselectAll();
+                    }
+
+                    if ($scope.singleSelection) {
+                        clearObject($scope.selectedModel);
+                    } else {
+                        $scope.selectedModel.splice(0, $scope.selectedModel.length);
+                    }
+                };
+
+                $scope.setSelectedItem = function (id, dontRemove) {
+                    var findObj = getFindObj(id);
+                    var finalObj = null;
+
+                    if ($scope.settings.externalIdProp === '') {
+                        finalObj = _.find($scope.options, findObj);
+                    } else {
+                        finalObj = findObj;
+                    }
+
+                    if ($scope.singleSelection) {
+                        clearObject($scope.selectedModel);
+                        angular.extend($scope.selectedModel, finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+
+                        return;
+                    }
+
+                    dontRemove = dontRemove || false;
+
+                    var exists = _.findIndex($scope.selectedModel, findObj) !== -1;
+
+                    if (!dontRemove && exists) {
+                        $scope.selectedModel.splice(_.findIndex($scope.selectedModel, findObj), 1);
+                        $scope.externalEvents.onItemDeselect(findObj);
+                    } else if (!exists && ($scope.settings.selectionLimit === 0 || $scope.selectedModel.length < $scope.settings.selectionLimit)) {
+                        $scope.selectedModel.push(finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+                    }
+                };
+
+                $scope.isChecked = function (id) {
+                    if ($scope.singleSelection) {
+                        return $scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp]) && $scope.selectedModel[$scope.settings.idProp] === getFindObj(id)[$scope.settings.idProp];
+                    }
+
+                    return _.findIndex($scope.selectedModel, getFindObj(id)) !== -1;
+                };
+
+                $scope.externalEvents.onInitDone();
+            }
+        };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-old.js b/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect-old.js
new file mode 100644 (file)
index 0000000..7a67bae
--- /dev/null
@@ -0,0 +1,433 @@
+'use strict';
+
+var directiveModule = angular.module('angularjs-dropdown-multiselect-old', ['ngRoute', 
+                                                                        'ngResource',                                                                        
+                                                                        'hljs',
+                                                                        'ui.bootstrap',
+                                                                        'angular-loading-bar', 
+                                                                        'ngAnimate',
+                                                                        'dialogs.main',
+                                                                        'ui.grid', 
+                                                                        'ui.grid.resizeColumns',
+                                                                        'ui.grid.paging',
+                                                                        'ui.grid.selection',
+                                                                        'ui.grid.cellNav',
+                                                                        'ui.grid.pinning',
+                                                                        'ngSanitize','vs-repeat']);
+
+directiveModule.directive('ngDropdownMultiselectOld', ['$filter', '$document', '$compile', '$parse','$rootScope', '$resource', '$http','$location',
+    function ($filter, $document, $compile, $parse, $rootScope, $resource, $http,$location) 
+    {
+       
+               //console.log($http);
+
+        return {
+            restrict: 'AE',
+            scope: {
+                selectedModel: '=',
+                options: '=',
+                extraSettings: '=',
+                events: '=',
+                searchFilter: '=?',
+                translationTexts: '=',
+                groupBy: '@'
+            },
+            template: function (element, attrs) 
+            {
+                var checkboxes = attrs.checkboxes ? true : false;
+                var groups = attrs.groupBy ? true : false;
+
+                var template = '<div class="multiselect-parent btn-group dropdown-multiselect" style="width:100%;">';
+                template += '<div style="width:98%;" class="dropdown-toggle" ng-class="settings.buttonClasses" ng-click="toggleDropdown()">{{getButtonText()}}&nbsp;<span class="caret"></span></div>';
+                template += '<ul class="dropdown-menu dropdown-menu-form" ng-style="{display: open ? \'block\' : \'none\', height : settings.scrollable ? settings.scrollableHeight : \'auto\' }" style="overflow: scroll; width:280px;" >';
+                template += '<li ng-show="settings.enableSearch"><div class="dropdown-header"><input type="text"  class="form-control" style="width: 100%;" ng-model="searchFilter"  ng-focus="this"  placeholder="{{texts.searchPlaceholder}}" /></li>';
+                template += '<li ng-show="settings.enableSearch" class="divider"></li>';
+                       
+                template += '<div>';
+                
+                if (groups) {
+                       
+                    template += '<li ng-repeat-start="option in orderedItems | filter: searchFilter" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header1">{{ getGroupTitle(getPropertyForObject(option, settings.groupBy)) }}</li>';
+                    template += '<li ng-repeat-end role="presentation">';
+                } else {
+                    template += '<li role="presentation" ng-repeat="option in options| filter: searchFilter">';
+                }
+
+                template += '<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">';
+
+                if (checkboxes) {
+                    template += '<div class="checkbox"><label><input class="checkboxInput" type="checkbox" ng-click="checkboxClick($event, getPropertyForObject(option,settings.idProp))" ng-checked="isChecked(getPropertyForObject(option,settings.idProp))" /> {{getPropertyForObject(option, settings.displayProp)}}</label></div></a>';
+                } else {
+                    template += '<span data-ng-class="{\'glyphicon glyphicon-ok\': isChecked(getPropertyForObject(option,settings.idProp))}"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>';
+                }
+
+                template += '</li>';
+                template += '</div>';
+                
+                template += '<li ng-hide="(!settings.showCheckAll) && !settings.showUncheckAll" class="divider"></li>';
+                template += '<li ng-hide="!settings.showCheckAll"><a data-ng-click="selectAll()"><span class="glyphicon glyphicon-ok"></span> {{texts.checkAll}}</a>';
+                template += '<li ng-show="settings.showUncheckAll"><a data-ng-click="deselectAll();"><span class="glyphicon glyphicon-remove"></span> {{texts.uncheckAll}}</a></li>';
+
+                template += '<li class="divider" ng-show="settings.selectionLimit > 1"></li>';
+                template += '<li role="presentation" ng-show="settings.selectionLimit > 1"><a role="menuitem">{{selectedModel.length}} {{texts.selectionOf}} {{settings.selectionLimit}} {{texts.selectionCount}}</a></li>';
+
+                template += '</ul>';
+                template += '</div>';
+
+                element.html(template);
+            },
+            link: function ($scope, $element, $attrs) 
+            {
+                var $dropdownTrigger = $element.children()[0];
+            
+               
+                $scope.toggleDropdown = function () {
+                    $scope.open = !$scope.open;
+                   
+                   
+                    
+                    
+                };
+
+                $scope.checkboxClick = function ($event, id) {
+                    $scope.setSelectedItem(id);
+                    $event.stopImmediatePropagation();
+                };
+
+                $scope.externalEvents = 
+                {
+                    onItemSelect: angular.noop,
+                    onItemDeselect: angular.noop,
+                    onSelectAll: angular.noop,
+                    onDeselectAll: angular.noop,
+                    onInitDone: angular.noop,
+                    onMaxSelectionReached: angular.noop
+                };
+
+                $scope.settings = {
+                    dynamicTitle: true,
+                    scrollable: false,
+                    scrollableHeight: '300px',
+                    closeOnBlur: true,
+                    displayProp: 'id',
+                    idProp: 'id',
+                    externalIdProp: 'id',
+                    enableSearch: false,
+                    selectionLimit: 0,
+                    showCheckAll: true,
+                    showUncheckAll: true,
+                    closeOnSelect: false,
+                    buttonClasses: 'btn btn-default',
+                    closeOnDeselect: false,
+                    groupBy: $attrs.groupBy || undefined,
+                    groupByTextProvider: null,
+                    smartButtonMaxItems: 0,
+                    smartButtonTextConverter: angular.noop
+                };
+
+                $scope.texts = {
+                    checkAll: 'Check All',
+                    uncheckAll: 'Uncheck All',
+                    selectionCount: 'checked',
+                    selectionOf: '/',
+                    searchPlaceholder: 'Search...',
+                    buttonDefaultText: 'Select',
+                    dynamicButtonTextSuffix: 'checked'
+                };
+
+                $scope.searchFilter = $scope.searchFilter || '';
+
+                if (angular.isDefined($scope.settings.groupBy)) 
+                {
+                    $scope.$watch('options', function (newValue)
+                    {
+                        if (angular.isDefined(newValue)) 
+                        {
+                            $scope.orderedItems = $filter('orderBy')(newValue, $scope.settings.groupBy);
+                        }
+                    });
+                }
+
+                angular.extend($scope.settings, $scope.extraSettings || []);
+                angular.extend($scope.externalEvents, $scope.events || []);
+                angular.extend($scope.texts, $scope.translationTexts);
+
+                $scope.singleSelection = $scope.settings.selectionLimit === 1;
+
+                function getFindObj(id) 
+                {
+                    var findObj = {};
+
+                    if ($scope.settings.externalIdProp === '') 
+                    {
+                        findObj[$scope.settings.idProp] = id;
+                    } 
+                    else 
+                    {
+                        findObj[$scope.settings.externalIdProp] = id;
+                    }
+
+                    return findObj;
+                }
+
+                function clearObject(object) 
+                {
+                    for (var prop in object) 
+                    {
+                        delete object[prop];
+                    }
+                }
+
+                if ($scope.singleSelection) 
+                {
+                    if (angular.isArray($scope.selectedModel) && $scope.selectedModel.length === 0) 
+                    {
+                        clearObject($scope.selectedModel);
+                    }
+                }
+
+                if ($scope.settings.closeOnBlur) 
+                {
+                    $document.on('click', function (e) 
+                    {
+                       var target = e.target.parentElement;
+                        var parentFound = false;
+
+                        while (angular.isDefined(target) && target !== null && !parentFound) 
+                        {
+                               try
+                               {
+                                       if (_.contains(target.className.split(' '), 'multiselect-parent') && !parentFound)
+                                    {
+                                        if(target === $dropdownTrigger) 
+                                        {
+                                            parentFound = true;
+                                        }
+                                    }
+                                    
+                                    target = target.parentElement;                               
+                                       
+                               }catch(e){break;}
+                               
+                        }
+
+                        if (!parentFound) {
+                            $scope.$apply(function () {
+                                $scope.open = false;
+                            });
+                        }
+                    });
+                }
+
+                $scope.getGroupTitle = function (groupValue) {
+                    if ($scope.settings.groupByTextProvider !== null) {
+                        return $scope.settings.groupByTextProvider(groupValue);
+                    }
+
+                    return groupValue;
+                };
+
+                $scope.getButtonText = function () {
+                    if ($scope.settings.dynamicTitle && ($scope.selectedModel.length > 0 || (angular.isObject($scope.selectedModel) && _.keys($scope.selectedModel).length > 0))) {
+                        if ($scope.settings.smartButtonMaxItems > 0) {
+                            var itemsText = [];
+
+                            angular.forEach($scope.options, function (optionItem) {
+                                if ($scope.isChecked($scope.getPropertyForObject(optionItem, $scope.settings.idProp))) {
+                                    var displayText = $scope.getPropertyForObject(optionItem, $scope.settings.displayProp);
+                                    var converterResponse = $scope.settings.smartButtonTextConverter(displayText, optionItem);
+
+                                    itemsText.push(converterResponse ? converterResponse : displayText);
+                                }
+                            });
+
+                            if ($scope.selectedModel.length > $scope.settings.smartButtonMaxItems) {
+                                itemsText = itemsText.slice(0, $scope.settings.smartButtonMaxItems);
+                                itemsText.push('...');
+                            }
+
+                            return itemsText.join(', ');
+                        } else {
+                            var totalSelected;
+
+                            if ($scope.singleSelection) {
+                                totalSelected = ($scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp])) ? 1 : 0;
+                            } else {
+                                totalSelected = angular.isDefined($scope.selectedModel) ? $scope.selectedModel.length : 0;
+                            }
+
+                            if (totalSelected === 0) {
+                                return $scope.texts.buttonDefaultText;
+                            } else {
+                                return totalSelected + ' ' + $scope.texts.dynamicButtonTextSuffix;
+                            }
+                        }
+                    } else {
+                        return $scope.texts.buttonDefaultText;
+                    }
+                };
+
+                $scope.getPropertyForObject = function (object, property)
+                {
+                    if (angular.isDefined(object) && object.hasOwnProperty(property)) {
+                        return object[property];
+                    }
+
+                    return '';
+                };
+
+                $scope.selectAll = function () 
+                {
+                       $scope.deselectAll(false,true);
+                    $scope.externalEvents.onSelectAll();
+                    
+                    var len = $scope.selectedModel.length;
+                    
+                    angular.forEach($scope.options, function (value) 
+                    {
+                       if(value[$scope.settings.idProp]=="All")
+                               {
+                               if(len > 1)
+                            {
+                                       $scope.setSelectedItem(value[$scope.settings.idProp], true, true);
+                            }
+                            else
+                               {
+                               $scope.setSelectedItem(value[$scope.settings.idProp], true, true);
+                            }
+                               }
+                    });
+                };
+
+                $scope.deselectAll = function (sendEvent,ignore) 
+                {
+                       var len = $scope.selectedModel.length;
+                       
+                       sendEvent = sendEvent || true;
+
+                    if (sendEvent) 
+                    {
+                        $scope.externalEvents.onDeselectAll();
+                    }
+
+                    if ($scope.singleSelection) 
+                    {
+                        clearObject($scope.selectedModel);
+                    } 
+                    else 
+                    {
+                        $scope.selectedModel.splice(0, $scope.selectedModel.length);
+                    }                    
+                    
+                    if(ignore!=true || ignore==undefined)
+                    {
+                           if(len > 1)
+                           {
+                               $scope.setSelectedItem("All", true, true);
+                           }
+                           else
+                               {
+                               $scope.setSelectedItem("All", true, true);
+                           } 
+                    }
+                    
+                    
+                };
+
+                $scope.setSelectedItem = function (id, dontRemove, refresh) 
+                {
+                       var findObj = getFindObj(id);
+                    var finalObj = null;
+
+                    if ($scope.settings.externalIdProp === '') 
+                    {
+                        finalObj = _.find($scope.options, findObj);
+                    } 
+                    else 
+                    {
+                        finalObj = findObj;
+                    }
+                    
+                    
+                    if ($scope.singleSelection) 
+                    {
+                        clearObject($scope.selectedModel);
+                        angular.extend($scope.selectedModel, finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+                        
+                        if ($scope.settings.closeOnSelect) $scope.open = false;
+                        
+                        return;
+                    }
+
+                    dontRemove = dontRemove || false;
+                    
+
+                    var exists = _.findIndex($scope.selectedModel, findObj) !== -1;
+
+                    if (!dontRemove && exists) {
+                        $scope.selectedModel.splice(_.findIndex($scope.selectedModel, findObj), 1);
+                        $scope.externalEvents.onItemDeselect(findObj);
+                    } else if (!exists && ($scope.settings.selectionLimit === 0 || $scope.selectedModel.length < $scope.settings.selectionLimit)) {
+                        $scope.selectedModel.push(finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+                    }
+                    
+                    if ($scope.settings.closeOnSelect) $scope.open = false;
+                    
+                    if(refresh || refresh==undefined)
+                       {
+                        if("/dashboard"==$location.path())
+                                {
+                               $rootScope.ReLoadDashboardComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);       
+                                 }
+                                 else if("/api_portfolio"==$location.path())
+                                 {
+                                       $rootScope.ReLoadAPIPortfolioComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);
+                                 }
+                                 else if("/project_portfolio"==$location.path())
+                                 {
+                                       $rootScope.ReLoadProjectPortFolioComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);
+                                 }
+                                 else if("/installed_bundle_versions"==$location.path())
+                                 {
+                                       $rootScope.ReLoadInstalledBundleComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);        
+                                 }else if("/adapter_inventory"==$location.path())
+                                 {
+                                               $rootScope.ReLoadAdapterInventoryComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);       
+                                 }
+                                 else if("/api_taxonomy"==$location.path())
+                                 {
+                                               $rootScope.ReLoadAPITaxonomyComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);    
+                                 }else if("/defects"==$location.path())
+                                 {
+                                               $rootScope.ReLoadDefectReportComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);   
+                                 } else if("/environment_configurations"==$location.path())
+                                 {
+                                               $rootScope.ReLoadEnvConfigComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);      
+                                 }
+                                       else if("/federated_qc_coverage"==$location.path())       {
+                                               $rootScope.ReLoadQcCodeCoverageComboBox($scope.translationTexts.buttonDefaultText,finalObj.id); 
+                                 }
+                        
+                        
+                        
+                        
+                        
+                       
+                       }
+                    
+                };
+
+                $scope.isChecked = function (id) {
+                    if ($scope.singleSelection) {
+                        return $scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp]) && $scope.selectedModel[$scope.settings.idProp] === getFindObj(id)[$scope.settings.idProp];
+                    }
+
+                    return _.findIndex($scope.selectedModel, getFindObj(id)) !== -1;
+                };
+
+                $scope.externalEvents.onInitDone();
+            }
+        };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.js b/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.js
new file mode 100644 (file)
index 0000000..126cc2f
--- /dev/null
@@ -0,0 +1,436 @@
+'use strict';
+
+var directiveModule = angular.module('angularjs-dropdown-multiselect', ['ngRoute', 
+                                                                        'ngResource',                                                                        
+                                                                        'hljs',
+                                                                        'ui.bootstrap',
+                                                                        'angular-loading-bar', 
+                                                                        'ngAnimate',
+                                                                        'dialogs.main',
+                                                                        'ui.grid', 
+                                                                        'ui.grid.resizeColumns',
+                                                                        'ui.grid.paging',
+                                                                        'ui.grid.selection',
+                                                                        'ui.grid.cellNav',
+                                                                        'ui.grid.pinning',
+                                                                        'ngSanitize','vs-repeat']);
+
+directiveModule.directive('ngDropdownMultiselect', ['$filter', '$document', '$compile', '$parse','$rootScope', '$resource', '$http','$location',
+    function ($filter, $document, $compile, $parse, $rootScope, $resource, $http,$location) 
+    {
+       
+               //console.log($http);
+
+        return {
+            restrict: 'AE',
+            scope: {
+                selectedModel: '=',
+                options: '=',
+                extraSettings: '=',
+                events: '=',
+                searchFilter: '=?',
+                translationTexts: '=',
+                groupBy: '@'
+            },
+            template: function (element, attrs) 
+            {
+                var checkboxes = attrs.checkboxes ? true : false;
+                var groups = attrs.groupBy ? true : false;
+
+                var template = '<div class="multiselect-parent btn-group dropdown-multiselect" style="width:100%;">';
+                template += '<div style="width:98%;" class="dropdown-toggle" ng-class="settings.buttonClasses" ng-click="toggleDropdown()">{{getButtonText()}}&nbsp;<span class="caret"></span></div>';
+                template += '<ul class="dropdown-menu dropdown-menu-form" ng-style="{display: open ? \'block\' : \'none\', height : settings.scrollable ? settings.scrollableHeight : \'auto\' }" style="overflow: scroll; width:280px;" >';
+                template += '<li ng-hide="!settings.showCheckAll"><a data-ng-click="selectAll()"><span class="glyphicon glyphicon-ok"></span>  {{texts.checkAll}}</a>';
+                template += '<li ng-show="settings.showUncheckAll"><a data-ng-click="deselectAll();"><span class="glyphicon glyphicon-remove"></span>   {{texts.uncheckAll}}</a></li>';
+                template += '<li ng-hide="(!settings.showCheckAll) && !settings.showUncheckAll" class="divider"></li>';
+                template += '<li ng-show="settings.enableSearch"><div class="dropdown-header"><input type="text" class="form-control" style="width: 100%;" ng-model="searchFilter" placeholder="{{texts.searchPlaceholder}}" /></li>';
+                template += '<li ng-show="settings.enableSearch" class="divider"></li>';
+                       
+                template += '<div vs-repeat> ';
+                
+                if (groups) {
+                    template += '<li ng-repeat-start="option in orderedItems | filter: searchFilter" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header">{{ getGroupTitle(getPropertyForObject(option, settings.groupBy)) }}</li>';
+                    template += '<li ng-repeat-end role="presentation">';
+                } else {
+                    template += '<li role="presentation" ng-repeat="option in options| filter: searchFilter">';
+                }
+
+                template += '<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">';
+
+                if (checkboxes) {
+                    template += '<div class="checkbox"><label><input class="checkboxInput" type="checkbox" ng-click="checkboxClick($event, getPropertyForObject(option,settings.idProp))" ng-checked="isChecked(getPropertyForObject(option,settings.idProp))" /> {{getPropertyForObject(option, settings.displayProp)}}</label></div></a>';
+                } else {
+                    template += '<span data-ng-class="{\'glyphicon glyphicon-ok\': isChecked(getPropertyForObject(option,settings.idProp))}"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>';
+                }
+
+                template += '</li>';
+                template += '</div>';
+                
+
+                template += '<li class="divider" ng-show="settings.selectionLimit > 1"></li>';
+                template += '<li role="presentation" ng-show="settings.selectionLimit > 1"><a role="menuitem">{{selectedModel.length}} {{texts.selectionOf}} {{settings.selectionLimit}} {{texts.selectionCount}}</a></li>';
+
+                template += '</ul>';
+                template += '</div>';
+
+                element.html(template);
+            },
+            link: function ($scope, $element, $attrs) 
+            {
+                var $dropdownTrigger = $element.children()[0];
+                
+                $scope.toggleDropdown = function () {
+                    $scope.open = !$scope.open;
+                    if ($('#left').height()<$('#right').height()){
+                       $('#left').height($('#right').height());        
+                    }                    
+                       setTimeout(function(){ $('#left').scrollTop($('#left')[0].scrollHeight); }, 1);                 
+                };
+
+                $scope.checkboxClick = function ($event, id) {
+                    $scope.setSelectedItem(id);
+                    $event.stopImmediatePropagation();
+                };
+
+                $scope.externalEvents = 
+                {
+                    onItemSelect: angular.noop,
+                    onItemDeselect: angular.noop,
+                    onSelectAll: angular.noop,
+                    onDeselectAll: angular.noop,
+                    onInitDone: angular.noop,
+                    onMaxSelectionReached: angular.noop
+                };
+
+                $scope.settings = {
+                    dynamicTitle: true,
+                    scrollable: false,
+                    scrollableHeight: '300px',
+                    closeOnBlur: true,
+                    displayProp: 'id',
+                    idProp: 'id',
+                    externalIdProp: 'id',
+                    enableSearch: false,
+                    selectionLimit: 0,
+                    showCheckAll: true,
+                    showUncheckAll: true,
+                    closeOnSelect: false,
+                    buttonClasses: 'btn btn-default',
+                    closeOnDeselect: false,
+                    groupBy: $attrs.groupBy || undefined,
+                    groupByTextProvider: null,
+                    smartButtonMaxItems: 0,
+                    smartButtonTextConverter: angular.noop
+                };
+
+                $scope.texts = {
+                    checkAll: 'Check All',
+                    uncheckAll: 'Uncheck All',
+                    selectionCount: 'checked',
+                    selectionOf: '/',
+                    searchPlaceholder: 'Search...',
+                    buttonDefaultText: 'Select',
+                    dynamicButtonTextSuffix: 'checked'
+                };
+
+                $scope.searchFilter = $scope.searchFilter || '';
+
+                if (angular.isDefined($scope.settings.groupBy)) 
+                {
+                    $scope.$watch('options', function (newValue)
+                    {
+                        if (angular.isDefined(newValue)) 
+                        {
+                            $scope.orderedItems = $filter('orderBy')(newValue, $scope.settings.groupBy);
+                        }
+                    });
+                }
+
+                angular.extend($scope.settings, $scope.extraSettings || []);
+                angular.extend($scope.externalEvents, $scope.events || []);
+                angular.extend($scope.texts, $scope.translationTexts);
+
+                $scope.singleSelection = $scope.settings.selectionLimit === 1;
+
+                function getFindObj(id) 
+                {
+                    var findObj = {};
+
+                    if ($scope.settings.externalIdProp === '') 
+                    {
+                        findObj[$scope.settings.idProp] = id;
+                    } 
+                    else 
+                    {
+                        findObj[$scope.settings.externalIdProp] = id;
+                    }
+
+                    return findObj;
+                }
+
+                function clearObject(object) 
+                {
+                    for (var prop in object) 
+                    {
+                        delete object[prop];
+                    }
+                }
+
+                if ($scope.singleSelection) 
+                {
+                    if (angular.isArray($scope.selectedModel) && $scope.selectedModel.length === 0) 
+                    {
+                        clearObject($scope.selectedModel);
+                    }
+                }
+
+                if ($scope.settings.closeOnBlur) 
+                {
+                    $document.on('click', function (e) 
+                    {
+                       var target = e.target.parentElement;
+                        var parentFound = false;
+
+                        while (angular.isDefined(target) && target !== null && !parentFound) 
+                        {
+                               try
+                               {
+                                       if (_.contains(target.className.split(' '), 'multiselect-parent') && !parentFound)
+                                    {
+                                        if(target === $dropdownTrigger) 
+                                        {
+                                            parentFound = true;
+                                        }
+                                    }
+                                    
+                                    target = target.parentElement;                               
+                                       
+                               }catch(e){break;}
+                               
+                        }
+
+                        if (!parentFound) {
+                            $scope.$apply(function () {
+                                $scope.open = false;
+                            });
+                        }
+                    });
+                }
+
+                $scope.getGroupTitle = function (groupValue) {
+                    if ($scope.settings.groupByTextProvider !== null) {
+                        return $scope.settings.groupByTextProvider(groupValue);
+                    }
+
+                    return groupValue;
+                };
+
+                $scope.getButtonText = function () {
+                    if ($scope.settings.dynamicTitle && ($scope.selectedModel.length > 0 || (angular.isObject($scope.selectedModel) && _.keys($scope.selectedModel).length > 0))) {
+                        if ($scope.settings.smartButtonMaxItems > 0) {
+                            var itemsText = [];
+
+                            angular.forEach($scope.options, function (optionItem) {
+                                if ($scope.isChecked($scope.getPropertyForObject(optionItem, $scope.settings.idProp))) {
+                                    var displayText = $scope.getPropertyForObject(optionItem, $scope.settings.displayProp);
+                                    var converterResponse = $scope.settings.smartButtonTextConverter(displayText, optionItem);
+
+                                    itemsText.push(converterResponse ? converterResponse : displayText);
+                                }
+                            });
+
+                            if ($scope.selectedModel.length > $scope.settings.smartButtonMaxItems) {
+                                itemsText = itemsText.slice(0, $scope.settings.smartButtonMaxItems);
+                                itemsText.push('...');
+                            }
+
+                            return itemsText.join(', ');
+                        } else {
+                            var totalSelected;
+
+                            if ($scope.singleSelection) {
+                                totalSelected = ($scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp])) ? 1 : 0;
+                            } else {
+                                totalSelected = angular.isDefined($scope.selectedModel) ? $scope.selectedModel.length : 0;
+                            }
+
+                            if (totalSelected === 0) {
+                                return $scope.texts.buttonDefaultText;
+                            } else {
+                                return totalSelected + ' ' + $scope.texts.dynamicButtonTextSuffix;
+                            }
+                        }
+                    } else {
+                        return $scope.texts.buttonDefaultText;
+                    }
+                };
+
+                $scope.getPropertyForObject = function (object, property)
+                {
+                    if (angular.isDefined(object) && object.hasOwnProperty(property)) {
+                        return object[property];
+                    }
+
+                    return '';
+                };
+
+                $scope.selectAll = function () 
+                {
+                       $scope.deselectAll(false,true);
+                    $scope.externalEvents.onSelectAll();
+                    
+                    var len = $scope.selectedModel.length;
+                    
+                    angular.forEach($scope.options, function (value) 
+                    {
+                       if(value[$scope.settings.idProp]=="All")
+                               {
+                               if(len > 1)
+                            {
+                                       $scope.setSelectedItem(value[$scope.settings.idProp], true, true);
+                            }
+                            else
+                               {
+                               $scope.setSelectedItem(value[$scope.settings.idProp], true, true);
+                            }
+                               }
+                    });
+                };
+
+                $scope.deselectAll = function (sendEvent,ignore) 
+                {
+                       var len = $scope.selectedModel.length;
+                       
+                       sendEvent = sendEvent || true;
+
+                    if (sendEvent) 
+                    {
+                        $scope.externalEvents.onDeselectAll();
+                    }
+
+                    if ($scope.singleSelection) 
+                    {
+                        clearObject($scope.selectedModel);
+                    } 
+                    else 
+                    {
+                        $scope.selectedModel.splice(0, $scope.selectedModel.length);
+                    }                    
+                    
+                    if(ignore!=true || ignore==undefined)
+                    {
+                           if(len > 1)
+                           {
+                               $scope.setSelectedItem("All", true, true);
+                           }
+                           else
+                               {
+                               $scope.setSelectedItem("All", true, true);
+                           } 
+                    }
+                    
+                    
+                };
+
+                $scope.setSelectedItem = function (id, dontRemove, refresh) 
+                {
+                       var findObj = getFindObj(id);
+                    var finalObj = null;
+
+                    if ($scope.settings.externalIdProp === '') 
+                    {
+                        finalObj = _.find($scope.options, findObj);
+                    } 
+                    else 
+                    {
+                        finalObj = findObj;
+                    }
+                    
+                    
+                    if ($scope.singleSelection) 
+                    {
+                        clearObject($scope.selectedModel);
+                        angular.extend($scope.selectedModel, finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+                        
+                        if ($scope.settings.closeOnSelect) $scope.open = false;
+                        
+                        return;
+                    }
+
+                    dontRemove = dontRemove || false;
+                    
+
+                    var exists = _.findIndex($scope.selectedModel, findObj) !== -1;
+
+                    if (!dontRemove && exists) {
+                        $scope.selectedModel.splice(_.findIndex($scope.selectedModel, findObj), 1);
+                        $scope.externalEvents.onItemDeselect(findObj);
+                    } else if (!exists && ($scope.settings.selectionLimit === 0 || $scope.selectedModel.length < $scope.settings.selectionLimit)) {
+                        $scope.selectedModel.push(finalObj);
+                        $scope.externalEvents.onItemSelect(finalObj);
+                    }
+                    
+                    if ($scope.settings.closeOnSelect) $scope.open = false;
+                    
+                    if(refresh || refresh==undefined)
+                       {
+                        if("/dashboard"==$location.path())
+                                {
+                               $rootScope.ReLoadDashboardComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);       
+                                 }
+                                 else if("/api_portfolio"==$location.path())
+                                 {
+                                       $rootScope.ReLoadAPIPortfolioComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);
+                                 }
+                                 else if("/project_portfolio"==$location.path())
+                                 {
+                                       $rootScope.ReLoadProjectPortFolioComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);
+                                 }
+                                 else if("/installed_bundle_versions"==$location.path())
+                                 {
+                                       $rootScope.ReLoadInstalledBundleComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);        
+                                 }else if("/adapter_inventory"==$location.path())
+                                 {
+                                               $rootScope.ReLoadAdapterInventoryComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);       
+                                 }
+                                 else if("/api_taxonomy"==$location.path())
+                                 {
+                                               $rootScope.ReLoadAPITaxonomyComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);    
+                                 }else if("/defects"==$location.path())
+                                 {
+                                               $rootScope.ReLoadDefectReportComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);   
+                                 } else if("/environment_configurations"==$location.path())
+                                 {
+                                               $rootScope.ReLoadEnvConfigComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);      
+                                 }
+                                       else if("/qc_coverage_report"==$location.path())          {
+                                               $rootScope.ReLoadQcCodeCoverageComboBox($scope.translationTexts.buttonDefaultText,finalObj.id); 
+                                 }else if("/func_test_exec_status"==$location.path())    {
+                                               $rootScope.ReLoadFunTestResultComboBox($scope.translationTexts.buttonDefaultText,finalObj.id);  
+                                 }
+                                       else if("/api_schema"==$location.path())          {
+                                               
+                                               $rootScope.reloadApiSchemaPage($scope.translationTexts.buttonDefaultText,finalObj.id);  
+                                 }
+                        
+                        
+                        
+                        
+                       
+                       }
+                    
+                };
+
+                $scope.isChecked = function (id) {
+                    if ($scope.singleSelection) {
+                        return $scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp]) && $scope.selectedModel[$scope.settings.idProp] === getFindObj(id)[$scope.settings.idProp];
+                    }
+
+                    return _.findIndex($scope.selectedModel, getFindObj(id)) !== -1;
+                };
+
+                $scope.externalEvents.onInitDone();
+            }
+        };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.min.js b/src/main/resources/META-INF/resources/designer/lib/angularjs-dropdown-multiselect.min.js
new file mode 100644 (file)
index 0000000..373c58b
--- /dev/null
@@ -0,0 +1 @@
+"use strict";var directiveModule=angular.module("angularjs-dropdown-multiselect",[]);directiveModule.directive("ngDropdownMultiselect",["$filter","$document","$compile","$parse",function($filter,$document){return{restrict:"AE",scope:{selectedModel:"=",options:"=",extraSettings:"=",events:"=",searchFilter:"=?",translationTexts:"=",groupBy:"@"},template:function(element,attrs){var checkboxes=attrs.checkboxes?!0:!1,groups=attrs.groupBy?!0:!1,template='<div class="multiselect-parent btn-group dropdown-multiselect">';template+='<button type="button" class="dropdown-toggle" ng-class="settings.buttonClasses" ng-click="toggleDropdown()">{{getButtonText()}}&nbsp;<span class="caret"></span></button>',template+="<ul class=\"dropdown-menu dropdown-menu-form\" ng-style=\"{display: open ? 'block' : 'none', height : settings.scrollable ? settings.scrollableHeight : 'auto' }\" style=\"overflow: scroll\" >",template+='<li ng-hide="!settings.showCheckAll || settings.selectionLimit > 0"><a data-ng-click="selectAll()"><span class="glyphicon glyphicon-ok"></span>  {{texts.checkAll}}</a>',template+='<li ng-show="settings.showUncheckAll"><a data-ng-click="deselectAll();"><span class="glyphicon glyphicon-remove"></span>   {{texts.uncheckAll}}</a></li>',template+='<li ng-hide="(!settings.showCheckAll || settings.selectionLimit > 0) && !settings.showUncheckAll" class="divider"></li>',template+='<li ng-show="settings.enableSearch"><div class="dropdown-header"><input type="text" class="form-control" style="width: 100%;" ng-model="searchFilter" placeholder="{{texts.searchPlaceholder}}" /></li>',template+='<li ng-show="settings.enableSearch" class="divider"></li>',groups?(template+='<li ng-repeat-start="option in orderedItems | filter: searchFilter" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header">{{ getGroupTitle(getPropertyForObject(option, settings.groupBy)) }}</li>',template+='<li ng-repeat-end role="presentation">'):template+='<li role="presentation" ng-repeat="option in options | filter: searchFilter">',template+='<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">',template+=checkboxes?'<div class="checkbox"><label><input class="checkboxInput" type="checkbox" ng-click="checkboxClick($event, getPropertyForObject(option,settings.idProp))" ng-checked="isChecked(getPropertyForObject(option,settings.idProp))" /> {{getPropertyForObject(option, settings.displayProp)}}</label></div></a>':"<span data-ng-class=\"{'glyphicon glyphicon-ok': isChecked(getPropertyForObject(option,settings.idProp))}\"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>",template+="</li>",template+='<li class="divider" ng-show="settings.selectionLimit > 1"></li>',template+='<li role="presentation" ng-show="settings.selectionLimit > 1"><a role="menuitem">{{selectedModel.length}} {{texts.selectionOf}} {{settings.selectionLimit}} {{texts.selectionCount}}</a></li>',template+="</ul>",template+="</div>",element.html(template)},link:function($scope,$element,$attrs){function getFindObj(id){var findObj={};return""===$scope.settings.externalIdProp?findObj[$scope.settings.idProp]=id:findObj[$scope.settings.externalIdProp]=id,findObj}function clearObject(object){for(var prop in object)delete object[prop]}var $dropdownTrigger=$element.children()[0];$scope.toggleDropdown=function(){$scope.open=!$scope.open},$scope.checkboxClick=function($event,id){$scope.setSelectedItem(id),$event.stopImmediatePropagation()},$scope.externalEvents={onItemSelect:angular.noop,onItemDeselect:angular.noop,onSelectAll:angular.noop,onDeselectAll:angular.noop,onInitDone:angular.noop,onMaxSelectionReached:angular.noop},$scope.settings={dynamicTitle:!0,scrollable:!1,scrollableHeight:"300px",closeOnBlur:!0,displayProp:"label",idProp:"id",externalIdProp:"id",enableSearch:!1,selectionLimit:0,showCheckAll:!0,showUncheckAll:!0,closeOnSelect:!1,buttonClasses:"btn btn-default",closeOnDeselect:!1,groupBy:$attrs.groupBy||void 0,groupByTextProvider:null,smartButtonMaxItems:0,smartButtonTextConverter:angular.noop},$scope.texts={checkAll:"Check All",uncheckAll:"Uncheck All",selectionCount:"checked",selectionOf:"/",searchPlaceholder:"Search...",buttonDefaultText:"Select",dynamicButtonTextSuffix:"checked"},$scope.searchFilter=$scope.searchFilter||"",angular.isDefined($scope.settings.groupBy)&&$scope.$watch("options",function(newValue){angular.isDefined(newValue)&&($scope.orderedItems=$filter("orderBy")(newValue,$scope.settings.groupBy))}),angular.extend($scope.settings,$scope.extraSettings||[]),angular.extend($scope.externalEvents,$scope.events||[]),angular.extend($scope.texts,$scope.translationTexts),$scope.singleSelection=1===$scope.settings.selectionLimit,$scope.singleSelection&&angular.isArray($scope.selectedModel)&&0===$scope.selectedModel.length&&clearObject($scope.selectedModel),$scope.settings.closeOnBlur&&$document.on("click",function(e){for(var target=e.target.parentElement,parentFound=!1;angular.isDefined(target)&&null!==target&&!parentFound;)_.contains(target.className.split(" "),"multiselect-parent")&&!parentFound&&target===$dropdownTrigger&&(parentFound=!0),target=target.parentElement;parentFound||$scope.$apply(function(){$scope.open=!1})}),$scope.getGroupTitle=function(groupValue){return null!==$scope.settings.groupByTextProvider?$scope.settings.groupByTextProvider(groupValue):groupValue},$scope.getButtonText=function(){if($scope.settings.dynamicTitle&&($scope.selectedModel.length>0||angular.isObject($scope.selectedModel)&&_.keys($scope.selectedModel).length>0)){if($scope.settings.smartButtonMaxItems>0){var itemsText=[];return angular.forEach($scope.options,function(optionItem){if($scope.isChecked($scope.getPropertyForObject(optionItem,$scope.settings.idProp))){var displayText=$scope.getPropertyForObject(optionItem,$scope.settings.displayProp),converterResponse=$scope.settings.smartButtonTextConverter(displayText,optionItem);itemsText.push(converterResponse?converterResponse:displayText)}}),$scope.selectedModel.length>$scope.settings.smartButtonMaxItems&&(itemsText=itemsText.slice(0,$scope.settings.smartButtonMaxItems),itemsText.push("...")),itemsText.join(", ")}var totalSelected;return totalSelected=$scope.singleSelection?null!==$scope.selectedModel&&angular.isDefined($scope.selectedModel[$scope.settings.idProp])?1:0:angular.isDefined($scope.selectedModel)?$scope.selectedModel.length:0,0===totalSelected?$scope.texts.buttonDefaultText:totalSelected+" "+$scope.texts.dynamicButtonTextSuffix}return $scope.texts.buttonDefaultText},$scope.getPropertyForObject=function(object,property){return angular.isDefined(object)&&object.hasOwnProperty(property)?object[property]:""},$scope.selectAll=function(){$scope.deselectAll(!1),$scope.externalEvents.onSelectAll(),angular.forEach($scope.options,function(value){$scope.setSelectedItem(value[$scope.settings.idProp],!0)})},$scope.deselectAll=function(sendEvent){sendEvent=sendEvent||!0,sendEvent&&$scope.externalEvents.onDeselectAll(),$scope.singleSelection?clearObject($scope.selectedModel):$scope.selectedModel.splice(0,$scope.selectedModel.length)},$scope.setSelectedItem=function(id,dontRemove){var findObj=getFindObj(id),finalObj=null;if(finalObj=""===$scope.settings.externalIdProp?_.find($scope.options,findObj):findObj,$scope.singleSelection)return clearObject($scope.selectedModel),angular.extend($scope.selectedModel,finalObj),void $scope.externalEvents.onItemSelect(finalObj);dontRemove=dontRemove||!1;var exists=-1!==_.findIndex($scope.selectedModel,findObj);!dontRemove&&exists?($scope.selectedModel.splice(_.findIndex($scope.selectedModel,findObj),1),$scope.externalEvents.onItemDeselect(findObj)):!exists&&(0===$scope.settings.selectionLimit||$scope.selectedModel.length<$scope.settings.selectionLimit)&&($scope.selectedModel.push(finalObj),$scope.externalEvents.onItemSelect(finalObj))},$scope.isChecked=function(id){return $scope.singleSelection?null!==$scope.selectedModel&&angular.isDefined($scope.selectedModel[$scope.settings.idProp])&&$scope.selectedModel[$scope.settings.idProp]===getFindObj(id)[$scope.settings.idProp]:-1!==_.findIndex($scope.selectedModel,getFindObj(id))},$scope.externalEvents.onInitDone()}}}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.js b/src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.js
new file mode 100644 (file)
index 0000000..fe077fe
--- /dev/null
@@ -0,0 +1,172 @@
+/*! ========================================================================
+ * Bootstrap Toggle: bootstrap-toggle.js v2.0.0
+ * http://www.bootstraptoggle.com
+ * ========================================================================
+ * Copyright 2014 Min Hur, The New York Times Company
+ * Licensed under MIT
+ * ======================================================================== */
+
+
+ +function ($) {
+       'use strict';
+
+       // TOGGLE PUBLIC CLASS DEFINITION
+       // ==============================
+
+       var Toggle = function (element, options) {
+               this.$element  = $(element)
+               this.options   = $.extend({}, this.defaults(), options)
+               this.render()
+       }
+
+       Toggle.VERSION  = '3.0.0'
+
+       Toggle.DEFAULTS = {
+               on: 'On',
+               off: 'Off',
+               onstyle: 'primary',
+               offstyle: 'default',
+               size: 'normal',
+               style: ''
+       }
+
+       Toggle.prototype.defaults = function() {
+               return {
+                       on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
+                       off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
+                       onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
+                       offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
+                       size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
+                       style: this.$element.attr('data-style') || Toggle.DEFAULTS.style
+               }
+       }
+
+       Toggle.prototype.render = function () {
+               this._onstyle = 'btn-' + this.options.onstyle
+               this._offstyle = 'btn-' + this.options.offstyle
+               var size = this.options.size === 'large' ? 'btn-lg'
+                       : this.options.size === 'small' ? 'btn-sm'
+                       : this.options.size === 'mini' ? 'btn-xs'
+                       : ''
+               var $toggleOn = $('<label class="btn">').html(this.options.on)
+                       .addClass(this._onstyle + ' ' + size)
+               var $toggleOff = $('<label class="btn">').html(this.options.off)
+                       .addClass(this._offstyle + ' ' + size + ' active')
+               var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
+                       .addClass(size)
+               var $toggleGroup = $('<div class="toggle-group">')
+                       .append($toggleOn, $toggleOff, $toggleHandle)
+               var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
+                       .addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
+                       .addClass(size).addClass(this.options.style)
+
+               this.$element.wrap($toggle)
+               $.extend(this, {
+                       $toggle: this.$element.parent(),
+                       $toggleOn: $toggleOn,
+                       $toggleOff: $toggleOff,
+                       $toggleGroup: $toggleGroup
+               })
+               this.$toggle.append($toggleGroup)
+
+               var width = Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
+               var height = Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
+               $toggleOn.addClass('toggle-on')
+               $toggleOff.addClass('toggle-off')
+               this.$toggle.css({ width: width, height: height })
+               this.update()
+               this.trigger(true)
+       }
+
+       Toggle.prototype.toggle = function () {
+               if (this.$element.prop('checked')) this.off()
+               else this.on()
+       }
+
+       Toggle.prototype.on = function () {
+               if (this.$element.prop('disabled')) return false
+               this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
+               this.$element.prop('checked', true)
+               this.trigger()
+       }
+
+       Toggle.prototype.off = function () {
+               if (this.$element.prop('disabled')) return false
+               this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
+               this.$element.prop('checked', false)
+               this.trigger()
+       }
+
+       Toggle.prototype.enable = function () {
+               this.$toggle.removeAttr('disabled')
+               this.$element.prop('disabled', false)
+       }
+
+       Toggle.prototype.disable = function () {
+               this.$toggle.attr('disabled', 'disabled')
+               this.$element.prop('disabled', true)
+       }
+
+       Toggle.prototype.update = function () {
+               if (this.$element.prop('disabled')) this.disable()
+               else this.enable()
+               if (this.$element.prop('checked')) this.on()
+               else this.off()
+       }
+
+       Toggle.prototype.trigger = function (silent) {
+               this.$element.off('change.bs.toggle')
+               if (!silent) this.$element.change()
+               this.$element.on('change.bs.toggle', $.proxy(function() {
+                       this.update()
+               }, this))
+       }
+
+       Toggle.prototype.destroy = function() {
+               this.$element.off('change.bs.toggle')
+               this.$toggleGroup.remove()
+               this.$element.removeData('bs.toggle')
+               this.$element.unwrap()
+       }
+
+       // TOGGLE PLUGIN DEFINITION
+       // ========================
+
+       function Plugin(option) {
+               return this.each(function () {
+                       var $this   = $(this)
+                       var data    = $this.data('bs.toggle')
+                       var options = typeof option == 'object' && option
+
+                       if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
+                       if (typeof option == 'string' && data[option]) data[option]()
+               })
+       }
+
+       var old = $.fn.bootstrapToggle
+
+       $.fn.bootstrapToggle             = Plugin
+       $.fn.bootstrapToggle.Constructor = Toggle
+
+       // TOGGLE NO CONFLICT
+       // ==================
+
+       $.fn.toggle.noConflict = function () {
+               $.fn.bootstrapToggle = old
+               return this
+       }
+
+       // TOGGLE DATA-API
+       // ===============
+
+       $(function() {
+               $('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
+       })
+
+       $(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
+               var $checkbox = $(this).find('input[type=checkbox]')
+               $checkbox.bootstrapToggle('toggle')
+               e.preventDefault()
+       })
+
+}(jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.min.js b/src/main/resources/META-INF/resources/designer/lib/bootstrap-toggle.min.js
new file mode 100644 (file)
index 0000000..d05310d
--- /dev/null
@@ -0,0 +1,9 @@
+/*! ========================================================================
+ * Bootstrap Toggle: bootstrap-toggle.js v2.0.0
+ * http://www.bootstraptoggle.com
+ * ========================================================================
+ * Copyright 2014 Min Hur, The New York Times Company
+ * Licensed under MIT
+ * ======================================================================== */
++function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="3.0.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:""},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.update(),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void this.trigger())},c.prototype.off=function(){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void this.trigger())},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on():this.off()},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
+//# sourceMappingURL=bootstrap-toggle.min.js.map
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/bootstrap.min.js b/src/main/resources/META-INF/resources/designer/lib/bootstrap.min.js
new file mode 100644 (file)
index 0000000..d839865
--- /dev/null
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.1",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})
+})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dataTables.bootstrap.js b/src/main/resources/META-INF/resources/designer/lib/dataTables.bootstrap.js
new file mode 100644 (file)
index 0000000..c2fba68
--- /dev/null
@@ -0,0 +1,245 @@
+/* Set the defaults for DataTables initialisation */
+$.extend(true, $.fn.dataTable.defaults, {
+    "sDom": "<'row'<'col-sm-6'l><'col-sm-6'f>r>" + "t" + "<'row'<'col-sm-6'i><'col-sm-6'p>>",
+    "oLanguage": {
+        "sLengthMenu": "_MENU_ records per page"
+    }
+});
+
+
+/* Default class modification */
+$.extend($.fn.dataTableExt.oStdClasses, {
+    "sWrapper": "dataTables_wrapper form-inline",
+    "sFilterInput": "form-control input-sm",
+    "sLengthSelect": "form-control input-sm"
+});
+
+// In 1.10 we use the pagination renderers to draw the Bootstrap paging,
+// rather than  custom plug-in
+if ($.fn.dataTable.Api) {
+    $.fn.dataTable.defaults.renderer = 'bootstrap';
+    $.fn.dataTable.ext.renderer.pageButton.bootstrap = function(settings, host, idx, buttons, page, pages) {
+        var api = new $.fn.dataTable.Api(settings);
+        var classes = settings.oClasses;
+        var lang = settings.oLanguage.oPaginate;
+        var btnDisplay, btnClass;
+
+        var attach = function(container, buttons) {
+            var i, ien, node, button;
+            var clickHandler = function(e) {
+                e.preventDefault();
+                if (e.data.action !== 'ellipsis') {
+                    api.page(e.data.action).draw(false);
+                }
+            };
+
+            for (i = 0, ien = buttons.length; i < ien; i++) {
+                button = buttons[i];
+
+                if ($.isArray(button)) {
+                    attach(container, button);
+                } else {
+                    btnDisplay = '';
+                    btnClass = '';
+
+                    switch (button) {
+                        case 'ellipsis':
+                            btnDisplay = '&hellip;';
+                            btnClass = 'disabled';
+                            break;
+
+                        case 'first':
+                            btnDisplay = lang.sFirst;
+                            btnClass = button + (page > 0 ?
+                                '' : ' disabled');
+                            break;
+
+                        case 'previous':
+                            btnDisplay = lang.sPrevious;
+                            btnClass = button + (page > 0 ?
+                                '' : ' disabled');
+                            break;
+
+                        case 'next':
+                            btnDisplay = lang.sNext;
+                            btnClass = button + (page < pages - 1 ?
+                                '' : ' disabled');
+                            break;
+
+                        case 'last':
+                            btnDisplay = lang.sLast;
+                            btnClass = button + (page < pages - 1 ?
+                                '' : ' disabled');
+                            break;
+
+                        default:
+                            btnDisplay = button + 1;
+                            btnClass = page === button ?
+                                'active' : '';
+                            break;
+                    }
+
+                    if (btnDisplay) {
+                        node = $('<li>', {
+                            'class': classes.sPageButton + ' ' + btnClass,
+                            'aria-controls': settings.sTableId,
+                            'tabindex': settings.iTabIndex,
+                            'id': idx === 0 && typeof button === 'string' ? settings.sTableId + '_' + button : null
+                        })
+                            .append($('<a>', {
+                                    'href': '#'
+                                })
+                                .html(btnDisplay)
+                        )
+                            .appendTo(container);
+
+                        settings.oApi._fnBindAction(
+                            node, {
+                                action: button
+                            }, clickHandler
+                        );
+                    }
+                }
+            }
+        };
+
+        attach(
+            $(host).empty().html('<ul class="pagination"/>').children('ul'),
+            buttons
+        );
+    }
+} else {
+    // Integration for 1.9-
+    $.fn.dataTable.defaults.sPaginationType = 'bootstrap';
+
+    /* API method to get paging information */
+    $.fn.dataTableExt.oApi.fnPagingInfo = function(oSettings) {
+        return {
+            "iStart": oSettings._iDisplayStart,
+            "iEnd": oSettings.fnDisplayEnd(),
+            "iLength": oSettings._iDisplayLength,
+            "iTotal": oSettings.fnRecordsTotal(),
+            "iFilteredTotal": oSettings.fnRecordsDisplay(),
+            "iPage": oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength),
+            "iTotalPages": oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength)
+        };
+    };
+
+    /* Bootstrap style pagination control */
+    $.extend($.fn.dataTableExt.oPagination, {
+        "bootstrap": {
+            "fnInit": function(oSettings, nPaging, fnDraw) {
+                var oLang = oSettings.oLanguage.oPaginate;
+                var fnClickHandler = function(e) {
+                    e.preventDefault();
+                    if (oSettings.oApi._fnPageChange(oSettings, e.data.action)) {
+                        fnDraw(oSettings);
+                    }
+                };
+
+                $(nPaging).append(
+                    '<ul class="pagination">' +
+                    '<li class="prev disabled"><a href="#">&larr; ' + oLang.sPrevious + '</a></li>' +
+                    '<li class="next disabled"><a href="#">' + oLang.sNext + ' &rarr; </a></li>' +
+                    '</ul>'
+                );
+                var els = $('a', nPaging);
+                $(els[0]).bind('click.DT', {
+                    action: "previous"
+                }, fnClickHandler);
+                $(els[1]).bind('click.DT', {
+                    action: "next"
+                }, fnClickHandler);
+            },
+
+            "fnUpdate": function(oSettings, fnDraw) {
+                var iListLength = 5;
+                var oPaging = oSettings.oInstance.fnPagingInfo();
+                var an = oSettings.aanFeatures.p;
+                var i, ien, j, sClass, iStart, iEnd, iHalf = Math.floor(iListLength / 2);
+
+                if (oPaging.iTotalPages < iListLength) {
+                    iStart = 1;
+                    iEnd = oPaging.iTotalPages;
+                } else if (oPaging.iPage <= iHalf) {
+                    iStart = 1;
+                    iEnd = iListLength;
+                } else if (oPaging.iPage >= (oPaging.iTotalPages - iHalf)) {
+                    iStart = oPaging.iTotalPages - iListLength + 1;
+                    iEnd = oPaging.iTotalPages;
+                } else {
+                    iStart = oPaging.iPage - iHalf + 1;
+                    iEnd = iStart + iListLength - 1;
+                }
+
+                for (i = 0, ien = an.length; i < ien; i++) {
+                    // Remove the middle elements
+                    $('li:gt(0)', an[i]).filter(':not(:last)').remove();
+
+                    // Add the new list items and their event handlers
+                    for (j = iStart; j <= iEnd; j++) {
+                        sClass = (j == oPaging.iPage + 1) ? 'class="active"' : '';
+                        $('<li ' + sClass + '><a href="#">' + j + '</a></li>')
+                            .insertBefore($('li:last', an[i])[0])
+                            .bind('click', function(e) {
+                                e.preventDefault();
+                                oSettings._iDisplayStart = (parseInt($('a', this).text(), 10) - 1) * oPaging.iLength;
+                                fnDraw(oSettings);
+                            });
+                    }
+
+                    // Add / remove disabled classes from the static elements
+                    if (oPaging.iPage === 0) {
+                        $('li:first', an[i]).addClass('disabled');
+                    } else {
+                        $('li:first', an[i]).removeClass('disabled');
+                    }
+
+                    if (oPaging.iPage === oPaging.iTotalPages - 1 || oPaging.iTotalPages === 0) {
+                        $('li:last', an[i]).addClass('disabled');
+                    } else {
+                        $('li:last', an[i]).removeClass('disabled');
+                    }
+                }
+            }
+        }
+    });
+}
+
+
+/*
+ * TableTools Bootstrap compatibility
+ * Required TableTools 2.1+
+ */
+if ($.fn.DataTable.TableTools) {
+    // Set the classes that TableTools uses to something suitable for Bootstrap
+    $.extend(true, $.fn.DataTable.TableTools.classes, {
+        "container": "DTTT btn-group",
+        "buttons": {
+            "normal": "btn btn-default",
+            "disabled": "disabled"
+        },
+        "collection": {
+            "container": "DTTT_dropdown dropdown-menu",
+            "buttons": {
+                "normal": "",
+                "disabled": "disabled"
+            }
+        },
+        "print": {
+            "info": "DTTT_print_info modal"
+        },
+        "select": {
+            "row": "active"
+        }
+    });
+
+    // Have the collection use a bootstrap compatible dropdown
+    $.extend(true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
+        "collection": {
+            "container": "ul",
+            "button": "li",
+            "liner": "a"
+        }
+    });
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/dataTables.fixedColumns.js b/src/main/resources/META-INF/resources/designer/lib/dataTables.fixedColumns.js
new file mode 100644 (file)
index 0000000..0e0ec27
--- /dev/null
@@ -0,0 +1,1413 @@
+/*! FixedColumns 3.0.3
+ * ©2010-2014 SpryMedia Ltd - datatables.net/license
+ */
+
+/**
+ * @summary     FixedColumns
+ * @description Freeze columns in place on a scrolling DataTable
+ * @version     3.0.3
+ * @file        dataTables.fixedColumns.js
+ * @author      SpryMedia Ltd (www.sprymedia.co.uk)
+ * @contact     www.sprymedia.co.uk/contact
+ * @copyright   Copyright 2010-2014 SpryMedia Ltd.
+ *
+ * This source file is free software, available under the following license:
+ *   MIT license - http://datatables.net/license/mit
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ *
+ * For details please refer to: http://www.datatables.net
+ */
+
+
+(function(window, document, undefined) {
+
+
+var factory = function( $, DataTable ) {
+"use strict";
+
+/**
+ * When making use of DataTables' x-axis scrolling feature, you may wish to
+ * fix the left most column in place. This plug-in for DataTables provides
+ * exactly this option (note for non-scrolling tables, please use the
+ * FixedHeader plug-in, which can fix headers, footers and columns). Key
+ * features include:
+ *
+ * * Freezes the left or right most columns to the side of the table
+ * * Option to freeze two or more columns
+ * * Full integration with DataTables' scrolling options
+ * * Speed - FixedColumns is fast in its operation
+ *
+ *  @class
+ *  @constructor
+ *  @global
+ *  @param {object} dt DataTables instance. With DataTables 1.10 this can also
+ *    be a jQuery collection, a jQuery selector, DataTables API instance or
+ *    settings object.
+ *  @param {object} [init={}] Configuration object for FixedColumns. Options are
+ *    defined by {@link FixedColumns.defaults}
+ *
+ *  @requires jQuery 1.7+
+ *  @requires DataTables 1.8.0+
+ *
+ *  @example
+ *      var table = $('#example').dataTable( {
+ *        "scrollX": "100%"
+ *      } );
+ *      new $.fn.dataTable.fixedColumns( table );
+ */
+var FixedColumns = function ( dt, init ) {
+       var that = this;
+
+       /* Sanity check - you just know it will happen */
+       if ( ! ( this instanceof FixedColumns ) )
+       {
+               alert( "FixedColumns warning: FixedColumns must be initialised with the 'new' keyword." );
+               return;
+       }
+
+       if ( typeof init == 'undefined' )
+       {
+               init = {};
+       }
+
+       // Use the DataTables Hungarian notation mapping method, if it exists to
+       // provide forwards compatibility for camel case variables
+       var camelToHungarian = $.fn.dataTable.camelToHungarian;
+       if ( camelToHungarian ) {
+               camelToHungarian( FixedColumns.defaults, FixedColumns.defaults, true );
+               camelToHungarian( FixedColumns.defaults, init );
+       }
+
+       // v1.10 allows the settings object to be got form a number of sources
+       var dtSettings = $.fn.dataTable.Api ?
+               new $.fn.dataTable.Api( dt ).settings()[0] :
+               dt.fnSettings();
+
+       /**
+        * Settings object which contains customisable information for FixedColumns instance
+        * @namespace
+        * @extends FixedColumns.defaults
+        * @private
+        */
+       this.s = {
+               /**
+                * DataTables settings objects
+                *  @type     object
+                *  @default  Obtained from DataTables instance
+                */
+               "dt": dtSettings,
+
+               /**
+                * Number of columns in the DataTable - stored for quick access
+                *  @type     int
+                *  @default  Obtained from DataTables instance
+                */
+               "iTableColumns": dtSettings.aoColumns.length,
+
+               /**
+                * Original outer widths of the columns as rendered by DataTables - used to calculate
+                * the FixedColumns grid bounding box
+                *  @type     array.<int>
+                *  @default  []
+                */
+               "aiOuterWidths": [],
+
+               /**
+                * Original inner widths of the columns as rendered by DataTables - used to apply widths
+                * to the columns
+                *  @type     array.<int>
+                *  @default  []
+                */
+               "aiInnerWidths": []
+       };
+
+
+       /**
+        * DOM elements used by the class instance
+        * @namespace
+        * @private
+        *
+        */
+       this.dom = {
+               /**
+                * DataTables scrolling element
+                *  @type     node
+                *  @default  null
+                */
+               "scroller": null,
+
+               /**
+                * DataTables header table
+                *  @type     node
+                *  @default  null
+                */
+               "header": null,
+
+               /**
+                * DataTables body table
+                *  @type     node
+                *  @default  null
+                */
+               "body": null,
+
+               /**
+                * DataTables footer table
+                *  @type     node
+                *  @default  null
+                */
+               "footer": null,
+
+               /**
+                * Display grid elements
+                * @namespace
+                */
+               "grid": {
+                       /**
+                        * Grid wrapper. This is the container element for the 3x3 grid
+                        *  @type     node
+                        *  @default  null
+                        */
+                       "wrapper": null,
+
+                       /**
+                        * DataTables scrolling element. This element is the DataTables
+                        * component in the display grid (making up the main table - i.e.
+                        * not the fixed columns).
+                        *  @type     node
+                        *  @default  null
+                        */
+                       "dt": null,
+
+                       /**
+                        * Left fixed column grid components
+                        * @namespace
+                        */
+                       "left": {
+                               "wrapper": null,
+                               "head": null,
+                               "body": null,
+                               "foot": null
+                       },
+
+                       /**
+                        * Right fixed column grid components
+                        * @namespace
+                        */
+                       "right": {
+                               "wrapper": null,
+                               "head": null,
+                               "body": null,
+                               "foot": null
+                       }
+               },
+
+               /**
+                * Cloned table nodes
+                * @namespace
+                */
+               "clone": {
+                       /**
+                        * Left column cloned table nodes
+                        * @namespace
+                        */
+                       "left": {
+                               /**
+                                * Cloned header table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "header": null,
+
+                               /**
+                                * Cloned body table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "body": null,
+
+                               /**
+                                * Cloned footer table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "footer": null
+                       },
+
+                       /**
+                        * Right column cloned table nodes
+                        * @namespace
+                        */
+                       "right": {
+                               /**
+                                * Cloned header table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "header": null,
+
+                               /**
+                                * Cloned body table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "body": null,
+
+                               /**
+                                * Cloned footer table
+                                *  @type     node
+                                *  @default  null
+                                */
+                               "footer": null
+                       }
+               }
+       };
+
+       /* Attach the instance to the DataTables instance so it can be accessed easily */
+       dtSettings._oFixedColumns = this;
+
+       /* Let's do it */
+       if ( ! dtSettings._bInitComplete )
+       {
+               dtSettings.oApi._fnCallbackReg( dtSettings, 'aoInitComplete', function () {
+                       that._fnConstruct( init );
+               }, 'FixedColumns' );
+       }
+       else
+       {
+               this._fnConstruct( init );
+       }
+};
+
+
+
+FixedColumns.prototype = /** @lends FixedColumns.prototype */{
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Public methods
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * Update the fixed columns - including headers and footers. Note that FixedColumns will
+        * automatically update the display whenever the host DataTable redraws.
+        *  @returns {void}
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      var fc = new $.fn.dataTable.fixedColumns( table );
+        *
+        *      // at some later point when the table has been manipulated....
+        *      fc.fnUpdate();
+        */
+       "fnUpdate": function ()
+       {
+               this._fnDraw( true );
+       },
+
+
+       /**
+        * Recalculate the resizes of the 3x3 grid that FixedColumns uses for display of the table.
+        * This is useful if you update the width of the table container. Note that FixedColumns will
+        * perform this function automatically when the window.resize event is fired.
+        *  @returns {void}
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      var fc = new $.fn.dataTable.fixedColumns( table );
+        *
+        *      // Resize the table container and then have FixedColumns adjust its layout....
+        *      $('#content').width( 1200 );
+        *      fc.fnRedrawLayout();
+        */
+       "fnRedrawLayout": function ()
+       {
+               this._fnColCalc();
+               this._fnGridLayout();
+               this.fnUpdate();
+       },
+
+
+       /**
+        * Mark a row such that it's height should be recalculated when using 'semiauto' row
+        * height matching. This function will have no effect when 'none' or 'auto' row height
+        * matching is used.
+        *  @param   {Node} nTr TR element that should have it's height recalculated
+        *  @returns {void}
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      var fc = new $.fn.dataTable.fixedColumns( table );
+        *
+        *      // manipulate the table - mark the row as needing an update then update the table
+        *      // this allows the redraw performed by DataTables fnUpdate to recalculate the row
+        *      // height
+        *      fc.fnRecalculateHeight();
+        *      table.fnUpdate( $('#example tbody tr:eq(0)')[0], ["insert date", 1, 2, 3 ... ]);
+        */
+       "fnRecalculateHeight": function ( nTr )
+       {
+               delete nTr._DTTC_iHeight;
+               nTr.style.height = 'auto';
+       },
+
+
+       /**
+        * Set the height of a given row - provides cross browser compatibility
+        *  @param   {Node} nTarget TR element that should have it's height recalculated
+        *  @param   {int} iHeight Height in pixels to set
+        *  @returns {void}
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      var fc = new $.fn.dataTable.fixedColumns( table );
+        *
+        *      // You may want to do this after manipulating a row in the fixed column
+        *      fc.fnSetRowHeight( $('#example tbody tr:eq(0)')[0], 50 );
+        */
+       "fnSetRowHeight": function ( nTarget, iHeight )
+       {
+               nTarget.style.height = iHeight+"px";
+       },
+
+
+       /**
+        * Get data index information about a row or cell in the table body.
+        * This function is functionally identical to fnGetPosition in DataTables,
+        * taking the same parameter (TH, TD or TR node) and returning exactly the
+        * the same information (data index information). THe difference between
+        * the two is that this method takes into account the fixed columns in the
+        * table, so you can pass in nodes from the master table, or the cloned
+        * tables and get the index position for the data in the main table.
+        *  @param {node} node TR, TH or TD element to get the information about
+        *  @returns {int} If nNode is given as a TR, then a single index is 
+        *    returned, or if given as a cell, an array of [row index, column index
+        *    (visible), column index (all)] is given.
+        */
+       "fnGetPosition": function ( node )
+       {
+               var idx;
+               var inst = this.s.dt.oInstance;
+
+               if ( ! $(node).parents('.DTFC_Cloned').length )
+               {
+                       // Not in a cloned table
+                       return inst.fnGetPosition( node );
+               }
+               else
+               {
+                       // Its in the cloned table, so need to look up position
+                       if ( node.nodeName.toLowerCase() === 'tr' ) {
+                               idx = $(node).index();
+                               return inst.fnGetPosition( $('tr', this.s.dt.nTBody)[ idx ] );
+                       }
+                       else
+                       {
+                               var colIdx = $(node).index();
+                               idx = $(node.parentNode).index();
+                               var row = inst.fnGetPosition( $('tr', this.s.dt.nTBody)[ idx ] );
+
+                               return [
+                                       row,
+                                       colIdx,
+                                       inst.oApi._fnVisibleToColumnIndex( this.s.dt, colIdx )
+                               ];
+                       }
+               }
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Private methods (they are of course public in JS, but recommended as private)
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * Initialisation for FixedColumns
+        *  @param   {Object} oInit User settings for initialisation
+        *  @returns {void}
+        *  @private
+        */
+       "_fnConstruct": function ( oInit )
+       {
+               var i, iLen, iWidth,
+                       that = this;
+
+               /* Sanity checking */
+               if ( typeof this.s.dt.oInstance.fnVersionCheck != 'function' ||
+                    this.s.dt.oInstance.fnVersionCheck( '1.8.0' ) !== true )
+               {
+                       alert( "FixedColumns "+FixedColumns.VERSION+" required DataTables 1.8.0 or later. "+
+                               "Please upgrade your DataTables installation" );
+                       return;
+               }
+
+               if ( this.s.dt.oScroll.sX === "" )
+               {
+                       this.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, "FixedColumns is not needed (no "+
+                               "x-scrolling in DataTables enabled), so no action will be taken. Use 'FixedHeader' for "+
+                               "column fixing when scrolling is not enabled" );
+                       return;
+               }
+
+               /* Apply the settings from the user / defaults */
+               this.s = $.extend( true, this.s, FixedColumns.defaults, oInit );
+
+               /* Set up the DOM as we need it and cache nodes */
+               var classes = this.s.dt.oClasses;
+               this.dom.grid.dt = $(this.s.dt.nTable).parents('div.'+classes.sScrollWrapper)[0];
+               this.dom.scroller = $('div.'+classes.sScrollBody, this.dom.grid.dt )[0];
+
+               /* Set up the DOM that we want for the fixed column layout grid */
+               this._fnColCalc();
+               this._fnGridSetup();
+
+               /* Event handlers */
+               var mouseController;
+
+               // When the body is scrolled - scroll the left and right columns
+               $(this.dom.scroller)
+                       .on( 'mouseover.DTFC touchstart.DTFC', function () {
+                               mouseController = 'main';
+                       } )
+                       .on( 'scroll.DTFC', function () {
+                               if ( mouseController === 'main' ) {
+                                       if ( that.s.iLeftColumns > 0 ) {
+                                               that.dom.grid.left.liner.scrollTop = that.dom.scroller.scrollTop;
+                                       }
+                                       if ( that.s.iRightColumns > 0 ) {
+                                               that.dom.grid.right.liner.scrollTop = that.dom.scroller.scrollTop;
+                                       }
+                               }
+                       } );
+
+               var wheelType = 'onwheel' in document.createElement('div') ?
+                       'wheel.DTFC' :
+                       'mousewheel.DTFC';
+
+               if ( that.s.iLeftColumns > 0 ) {
+                       // When scrolling the left column, scroll the body and right column
+                       $(that.dom.grid.left.liner)
+                               .on( 'mouseover.DTFC touchstart.DTFC', function () {
+                                       mouseController = 'left';
+                               } )
+                               .on( 'scroll.DTFC', function () {
+                                       if ( mouseController === 'left' ) {
+                                               that.dom.scroller.scrollTop = that.dom.grid.left.liner.scrollTop;
+                                               if ( that.s.iRightColumns > 0 ) {
+                                                       that.dom.grid.right.liner.scrollTop = that.dom.grid.left.liner.scrollTop;
+                                               }
+                                       }
+                               } )
+                               .on( wheelType, function(e) { // xxx update the destroy as well
+                                       // Pass horizontal scrolling through
+                                       var xDelta = e.type === 'wheel' ?
+                                               -e.originalEvent.deltaX :
+                                               e.originalEvent.wheelDeltaX;
+                                       that.dom.scroller.scrollLeft -= xDelta;
+                               } );
+               }
+
+               if ( that.s.iRightColumns > 0 ) {
+                       // When scrolling the right column, scroll the body and the left column
+                       $(that.dom.grid.right.liner)
+                               .on( 'mouseover.DTFC touchstart.DTFC', function () {
+                                       mouseController = 'right';
+                               } )
+                               .on( 'scroll.DTFC', function () {
+                                       if ( mouseController === 'right' ) {
+                                               that.dom.scroller.scrollTop = that.dom.grid.right.liner.scrollTop;
+                                               if ( that.s.iLeftColumns > 0 ) {
+                                                       that.dom.grid.left.liner.scrollTop = that.dom.grid.right.liner.scrollTop;
+                                               }
+                                       }
+                               } )
+                               .on( wheelType, function(e) {
+                                       // Pass horizontal scrolling through
+                                       var xDelta = e.type === 'wheel' ?
+                                               -e.originalEvent.deltaX :
+                                               e.originalEvent.wheelDeltaX;
+                                       that.dom.scroller.scrollLeft -= xDelta;
+                               } );
+               }
+
+               $(window).on( 'resize.DTFC', function () {
+                       that._fnGridLayout.call( that );
+               } );
+
+               var bFirstDraw = true;
+               var jqTable = $(this.s.dt.nTable);
+
+               jqTable
+                       .on( 'draw.dt.DTFC', function () {
+                               that._fnDraw.call( that, bFirstDraw );
+                               bFirstDraw = false;
+                       } )
+                       .on( 'column-sizing.dt.DTFC', function () {
+                               that._fnColCalc();
+                               that._fnGridLayout( that );
+                       } )
+                       .on( 'column-visibility.dt.DTFC', function () {
+                               that._fnColCalc();
+                               that._fnGridLayout( that );
+                               that._fnDraw( true );
+                       } )
+                       .on( 'destroy.dt.DTFC', function () {
+                               jqTable.off( 'column-sizing.dt.DTFC destroy.dt.DTFC draw.dt.DTFC' );
+
+                               $(that.dom.scroller).off( 'scroll.DTFC mouseover.DTFC' );
+                               $(window).off( 'resize.DTFC' );
+
+                               $(that.dom.grid.left.liner).off( 'scroll.DTFC mouseover.DTFC '+wheelType );
+                               $(that.dom.grid.left.wrapper).remove();
+
+                               $(that.dom.grid.right.liner).off( 'scroll.DTFC mouseover.DTFC '+wheelType );
+                               $(that.dom.grid.right.wrapper).remove();
+                       } );
+
+               /* Get things right to start with - note that due to adjusting the columns, there must be
+                * another redraw of the main table. It doesn't need to be a full redraw however.
+                */
+               this._fnGridLayout();
+               this.s.dt.oInstance.fnDraw(false);
+       },
+
+
+       /**
+        * Calculate the column widths for the grid layout
+        *  @returns {void}
+        *  @private
+        */
+       "_fnColCalc": function ()
+       {
+               var that = this;
+               var iLeftWidth = 0;
+               var iRightWidth = 0;
+
+               this.s.aiInnerWidths = [];
+               this.s.aiOuterWidths = [];
+
+               $.each( this.s.dt.aoColumns, function (i, col) {
+                       var th = $(col.nTh);
+                       var border;
+
+                       if ( ! th.filter(':visible').length ) {
+                               that.s.aiInnerWidths.push( 0 );
+                               that.s.aiOuterWidths.push( 0 );
+                       }
+                       else
+                       {
+                               // Inner width is used to assign widths to cells
+                               // Outer width is used to calculate the container
+                               var iWidth = th.outerWidth();
+
+                               // When working with the left most-cell, need to add on the
+                               // table's border to the outerWidth, since we need to take
+                               // account of it, but it isn't in any cell
+                               if ( that.s.aiOuterWidths.length === 0 ) {
+                                       border = $(that.s.dt.nTable).css('border-left-width');
+                                       iWidth += typeof border === 'string' ? 1 : parseInt( border, 10 );
+                               }
+
+                               // Likewise with the final column on the right
+                               if ( that.s.aiOuterWidths.length === that.s.dt.aoColumns.length-1 ) {
+                                       border = $(that.s.dt.nTable).css('border-right-width');
+                                       iWidth += typeof border === 'string' ? 1 : parseInt( border, 10 );
+                               }
+
+                               that.s.aiOuterWidths.push( iWidth );
+                               that.s.aiInnerWidths.push( th.width() );
+
+                               if ( i < that.s.iLeftColumns )
+                               {
+                                       iLeftWidth += iWidth;
+                               }
+
+                               if ( that.s.iTableColumns-that.s.iRightColumns <= i )
+                               {
+                                       iRightWidth += iWidth;
+                               }
+                       }
+               } );
+
+               this.s.iLeftWidth = iLeftWidth;
+               this.s.iRightWidth = iRightWidth;
+       },
+
+
+       /**
+        * Set up the DOM for the fixed column. The way the layout works is to create a 1x3 grid
+        * for the left column, the DataTable (for which we just reuse the scrolling element DataTable
+        * puts into the DOM) and the right column. In each of he two fixed column elements there is a
+        * grouping wrapper element and then a head, body and footer wrapper. In each of these we then
+        * place the cloned header, body or footer tables. This effectively gives as 3x3 grid structure.
+        *  @returns {void}
+        *  @private
+        */
+       "_fnGridSetup": function ()
+       {
+               var that = this;
+               var oOverflow = this._fnDTOverflow();
+               var block;
+
+               this.dom.body = this.s.dt.nTable;
+               this.dom.header = this.s.dt.nTHead.parentNode;
+               this.dom.header.parentNode.parentNode.style.position = "relative";
+
+               var nSWrapper =
+                       $('<div class="DTFC_ScrollWrapper" style="position:relative; clear:both;">'+
+                               '<div class="DTFC_LeftWrapper" style="position:absolute; top:0; left:0;">'+
+                                       '<div class="DTFC_LeftHeadWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
+                                       '<div class="DTFC_LeftBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
+                                               '<div class="DTFC_LeftBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
+                                       '</div>'+
+                                       '<div class="DTFC_LeftFootWrapper" style="position:relative; top:0; left:0; overflow:hidden;"></div>'+
+                               '</div>'+
+                               '<div class="DTFC_RightWrapper" style="position:absolute; top:0; left:0;">'+
+                                       '<div class="DTFC_RightHeadWrapper" style="position:relative; top:0; left:0;">'+
+                                               '<div class="DTFC_RightHeadBlocker DTFC_Blocker" style="position:absolute; top:0; bottom:0;"></div>'+
+                                       '</div>'+
+                                       '<div class="DTFC_RightBodyWrapper" style="position:relative; top:0; left:0; overflow:hidden;">'+
+                                               '<div class="DTFC_RightBodyLiner" style="position:relative; top:0; left:0; overflow-y:scroll;"></div>'+
+                                       '</div>'+
+                                       '<div class="DTFC_RightFootWrapper" style="position:relative; top:0; left:0;">'+
+                                               '<div class="DTFC_RightFootBlocker DTFC_Blocker" style="position:absolute; top:0; bottom:0;"></div>'+
+                                       '</div>'+
+                               '</div>'+
+                       '</div>')[0];
+               var nLeft = nSWrapper.childNodes[0];
+               var nRight = nSWrapper.childNodes[1];
+
+               this.dom.grid.dt.parentNode.insertBefore( nSWrapper, this.dom.grid.dt );
+               nSWrapper.appendChild( this.dom.grid.dt );
+
+               this.dom.grid.wrapper = nSWrapper;
+
+               if ( this.s.iLeftColumns > 0 )
+               {
+                       this.dom.grid.left.wrapper = nLeft;
+                       this.dom.grid.left.head = nLeft.childNodes[0];
+                       this.dom.grid.left.body = nLeft.childNodes[1];
+                       this.dom.grid.left.liner = $('div.DTFC_LeftBodyLiner', nSWrapper)[0];
+
+                       nSWrapper.appendChild( nLeft );
+               }
+
+               if ( this.s.iRightColumns > 0 )
+               {
+                       this.dom.grid.right.wrapper = nRight;
+                       this.dom.grid.right.head = nRight.childNodes[0];
+                       this.dom.grid.right.body = nRight.childNodes[1];
+                       this.dom.grid.right.liner = $('div.DTFC_RightBodyLiner', nSWrapper)[0];
+
+                       block = $('div.DTFC_RightHeadBlocker', nSWrapper)[0];
+                       block.style.width = oOverflow.bar+"px";
+                       block.style.right = -oOverflow.bar+"px";
+                       this.dom.grid.right.headBlock = block;
+
+                       block = $('div.DTFC_RightFootBlocker', nSWrapper)[0];
+                       block.style.width = oOverflow.bar+"px";
+                       block.style.right = -oOverflow.bar+"px";
+                       this.dom.grid.right.footBlock = block;
+
+                       nSWrapper.appendChild( nRight );
+               }
+
+               if ( this.s.dt.nTFoot )
+               {
+                       this.dom.footer = this.s.dt.nTFoot.parentNode;
+                       if ( this.s.iLeftColumns > 0 )
+                       {
+                               this.dom.grid.left.foot = nLeft.childNodes[2];
+                       }
+                       if ( this.s.iRightColumns > 0 )
+                       {
+                               this.dom.grid.right.foot = nRight.childNodes[2];
+                       }
+               }
+       },
+
+
+       /**
+        * Style and position the grid used for the FixedColumns layout
+        *  @returns {void}
+        *  @private
+        */
+       "_fnGridLayout": function ()
+       {
+               var oGrid = this.dom.grid;
+               var iWidth = $(oGrid.wrapper).width();
+               var iBodyHeight = $(this.s.dt.nTable.parentNode).outerHeight();
+               var iFullHeight = $(this.s.dt.nTable.parentNode.parentNode).outerHeight();
+               var oOverflow = this._fnDTOverflow();
+               var
+                       iLeftWidth = this.s.iLeftWidth,
+                       iRightWidth = this.s.iRightWidth,
+                       iRight;
+               var scrollbarAdjust = function ( node, width ) {
+                       if ( ! oOverflow.bar ) {
+                               // If there is no scrollbar (Macs) we need to hide the auto scrollbar
+                               node.style.width = (width+20)+"px";
+                               node.style.paddingRight = "20px";
+                               node.style.boxSizing = "border-box";
+                       }
+                       else {
+                               // Otherwise just overflow by the scrollbar
+                               node.style.width = (width+oOverflow.bar)+"px";
+                       }
+               };
+
+               // When x scrolling - don't paint the fixed columns over the x scrollbar
+               if ( oOverflow.x )
+               {
+                       iBodyHeight -= oOverflow.bar;
+               }
+
+               oGrid.wrapper.style.height = iFullHeight+"px";
+
+               if ( this.s.iLeftColumns > 0 )
+               {
+                       oGrid.left.wrapper.style.width = iLeftWidth+"px";
+                       oGrid.left.wrapper.style.height = "1px";
+                       oGrid.left.body.style.height = iBodyHeight+"px";
+                       if ( oGrid.left.foot ) {
+                               oGrid.left.foot.style.top = (oOverflow.x ? oOverflow.bar : 0)+"px"; // shift footer for scrollbar
+                       }
+
+                       scrollbarAdjust( oGrid.left.liner, iLeftWidth );
+                       oGrid.left.liner.style.height = iBodyHeight+"px";
+               }
+
+               if ( this.s.iRightColumns > 0 )
+               {
+                       iRight = iWidth - iRightWidth;
+                       if ( oOverflow.y )
+                       {
+                               iRight -= oOverflow.bar;
+                       }
+
+                       oGrid.right.wrapper.style.width = iRightWidth+"px";
+                       oGrid.right.wrapper.style.left = iRight+"px";
+                       oGrid.right.wrapper.style.height = "1px";
+                       oGrid.right.body.style.height = iBodyHeight+"px";
+                       if ( oGrid.right.foot ) {
+                               oGrid.right.foot.style.top = (oOverflow.x ? oOverflow.bar : 0)+"px";
+                       }
+
+                       scrollbarAdjust( oGrid.right.liner, iRightWidth );
+                       oGrid.right.liner.style.height = iBodyHeight+"px";
+
+                       oGrid.right.headBlock.style.display = oOverflow.y ? 'block' : 'none';
+                       oGrid.right.footBlock.style.display = oOverflow.y ? 'block' : 'none';
+               }
+       },
+
+
+       /**
+        * Get information about the DataTable's scrolling state - specifically if the table is scrolling
+        * on either the x or y axis, and also the scrollbar width.
+        *  @returns {object} Information about the DataTables scrolling state with the properties:
+        *    'x', 'y' and 'bar'
+        *  @private
+        */
+       "_fnDTOverflow": function ()
+       {
+               var nTable = this.s.dt.nTable;
+               var nTableScrollBody = nTable.parentNode;
+               var out = {
+                       "x": false,
+                       "y": false,
+                       "bar": this.s.dt.oScroll.iBarWidth
+               };
+
+               if ( nTable.offsetWidth > nTableScrollBody.clientWidth )
+               {
+                       out.x = true;
+               }
+
+               if ( nTable.offsetHeight > nTableScrollBody.clientHeight )
+               {
+                       out.y = true;
+               }
+
+               return out;
+       },
+
+
+       /**
+        * Clone and position the fixed columns
+        *  @returns {void}
+        *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
+        *  @private
+        */
+       "_fnDraw": function ( bAll )
+       {
+               this._fnGridLayout();
+               this._fnCloneLeft( bAll );
+               this._fnCloneRight( bAll );
+
+               /* Draw callback function */
+               if ( this.s.fnDrawCallback !== null )
+               {
+                       this.s.fnDrawCallback.call( this, this.dom.clone.left, this.dom.clone.right );
+               }
+
+               /* Event triggering */
+               $(this).trigger( 'draw.dtfc', {
+                       "leftClone": this.dom.clone.left,
+                       "rightClone": this.dom.clone.right
+               } );
+       },
+
+
+       /**
+        * Clone the right columns
+        *  @returns {void}
+        *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
+        *  @private
+        */
+       "_fnCloneRight": function ( bAll )
+       {
+               if ( this.s.iRightColumns <= 0 ) {
+                       return;
+               }
+
+               var that = this,
+                       i, jq,
+                       aiColumns = [];
+
+               for ( i=this.s.iTableColumns-this.s.iRightColumns ; i<this.s.iTableColumns ; i++ ) {
+                       if ( this.s.dt.aoColumns[i].bVisible ) {
+                               aiColumns.push( i );
+                       }
+               }
+
+               this._fnClone( this.dom.clone.right, this.dom.grid.right, aiColumns, bAll );
+       },
+
+
+       /**
+        * Clone the left columns
+        *  @returns {void}
+        *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
+        *  @private
+        */
+       "_fnCloneLeft": function ( bAll )
+       {
+               if ( this.s.iLeftColumns <= 0 ) {
+                       return;
+               }
+
+               var that = this,
+                       i, jq,
+                       aiColumns = [];
+
+               for ( i=0 ; i<this.s.iLeftColumns ; i++ ) {
+                       if ( this.s.dt.aoColumns[i].bVisible ) {
+                               aiColumns.push( i );
+                       }
+               }
+
+               this._fnClone( this.dom.clone.left, this.dom.grid.left, aiColumns, bAll );
+       },
+
+
+       /**
+        * Make a copy of the layout object for a header or footer element from DataTables. Note that
+        * this method will clone the nodes in the layout object.
+        *  @returns {Array} Copy of the layout array
+        *  @param   {Object} aoOriginal Layout array from DataTables (aoHeader or aoFooter)
+        *  @param   {Object} aiColumns Columns to copy
+        *  @private
+        */
+       "_fnCopyLayout": function ( aoOriginal, aiColumns )
+       {
+               var aReturn = [];
+               var aClones = [];
+               var aCloned = [];
+
+               for ( var i=0, iLen=aoOriginal.length ; i<iLen ; i++ )
+               {
+                       var aRow = [];
+                       aRow.nTr = $(aoOriginal[i].nTr).clone(true, true)[0];
+
+                       for ( var j=0, jLen=this.s.iTableColumns ; j<jLen ; j++ )
+                       {
+                               if ( $.inArray( j, aiColumns ) === -1 )
+                               {
+                                       continue;
+                               }
+
+                               var iCloned = $.inArray( aoOriginal[i][j].cell, aCloned );
+                               if ( iCloned === -1 )
+                               {
+                                       var nClone = $(aoOriginal[i][j].cell).clone(true, true)[0];
+                                       aClones.push( nClone );
+                                       aCloned.push( aoOriginal[i][j].cell );
+
+                                       aRow.push( {
+                                               "cell": nClone,
+                                               "unique": aoOriginal[i][j].unique
+                                       } );
+                               }
+                               else
+                               {
+                                       aRow.push( {
+                                               "cell": aClones[ iCloned ],
+                                               "unique": aoOriginal[i][j].unique
+                                       } );
+                               }
+                       }
+
+                       aReturn.push( aRow );
+               }
+
+               return aReturn;
+       },
+
+
+       /**
+        * Clone the DataTable nodes and place them in the DOM (sized correctly)
+        *  @returns {void}
+        *  @param   {Object} oClone Object containing the header, footer and body cloned DOM elements
+        *  @param   {Object} oGrid Grid object containing the display grid elements for the cloned
+        *                    column (left or right)
+        *  @param   {Array} aiColumns Column indexes which should be operated on from the DataTable
+        *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)
+        *  @private
+        */
+       "_fnClone": function ( oClone, oGrid, aiColumns, bAll )
+       {
+               var that = this,
+                       i, iLen, j, jLen, jq, nTarget, iColumn, nClone, iIndex, aoCloneLayout,
+                       jqCloneThead, aoFixedHeader;
+
+               /*
+                * Header
+                */
+               if ( bAll )
+               {
+                       if ( oClone.header !== null )
+                       {
+                               oClone.header.parentNode.removeChild( oClone.header );
+                       }
+                       oClone.header = $(this.dom.header).clone(true, true)[0];
+                       oClone.header.className += " DTFC_Cloned";
+                       oClone.header.style.width = "100%";
+                       oGrid.head.appendChild( oClone.header );
+
+                       /* Copy the DataTables layout cache for the header for our floating column */
+                       aoCloneLayout = this._fnCopyLayout( this.s.dt.aoHeader, aiColumns );
+                       jqCloneThead = $('>thead', oClone.header);
+                       jqCloneThead.empty();
+
+                       /* Add the created cloned TR elements to the table */
+                       for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
+                       {
+                               jqCloneThead[0].appendChild( aoCloneLayout[i].nTr );
+                       }
+
+                       /* Use the handy _fnDrawHead function in DataTables to do the rowspan/colspan
+                        * calculations for us
+                        */
+                       this.s.dt.oApi._fnDrawHead( this.s.dt, aoCloneLayout, true );
+               }
+               else
+               {
+                       /* To ensure that we copy cell classes exactly, regardless of colspan, multiple rows
+                        * etc, we make a copy of the header from the DataTable again, but don't insert the
+                        * cloned cells, just copy the classes across. To get the matching layout for the
+                        * fixed component, we use the DataTables _fnDetectHeader method, allowing 1:1 mapping
+                        */
+                       aoCloneLayout = this._fnCopyLayout( this.s.dt.aoHeader, aiColumns );
+                       aoFixedHeader=[];
+
+                       this.s.dt.oApi._fnDetectHeader( aoFixedHeader, $('>thead', oClone.header)[0] );
+
+                       for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
+                       {
+                               for ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )
+                               {
+                                       aoFixedHeader[i][j].cell.className = aoCloneLayout[i][j].cell.className;
+
+                                       // If jQuery UI theming is used we need to copy those elements as well
+                                       $('span.DataTables_sort_icon', aoFixedHeader[i][j].cell).each( function () {
+                                               this.className = $('span.DataTables_sort_icon', aoCloneLayout[i][j].cell)[0].className;
+                                       } );
+                               }
+                       }
+               }
+               this._fnEqualiseHeights( 'thead', this.dom.header, oClone.header );
+
+               /*
+                * Body
+                */
+               if ( this.s.sHeightMatch == 'auto' )
+               {
+                       /* Remove any heights which have been applied already and let the browser figure it out */
+                       $('>tbody>tr', that.dom.body).css('height', 'auto');
+               }
+
+               if ( oClone.body !== null )
+               {
+                       oClone.body.parentNode.removeChild( oClone.body );
+                       oClone.body = null;
+               }
+
+               oClone.body = $(this.dom.body).clone(true)[0];
+               oClone.body.className += " DTFC_Cloned";
+               oClone.body.style.paddingBottom = this.s.dt.oScroll.iBarWidth+"px";
+               oClone.body.style.marginBottom = (this.s.dt.oScroll.iBarWidth*2)+"px"; /* For IE */
+               if ( oClone.body.getAttribute('id') !== null )
+               {
+                       oClone.body.removeAttribute('id');
+               }
+
+               $('>thead>tr', oClone.body).empty();
+               $('>tfoot', oClone.body).remove();
+
+               var nBody = $('tbody', oClone.body)[0];
+               $(nBody).empty();
+               if ( this.s.dt.aiDisplay.length > 0 )
+               {
+                       /* Copy the DataTables' header elements to force the column width in exactly the
+                        * same way that DataTables does it - have the header element, apply the width and
+                        * colapse it down
+                        */
+                       var nInnerThead = $('>thead>tr', oClone.body)[0];
+                       for ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )
+                       {
+                               iColumn = aiColumns[iIndex];
+
+                               nClone = $(this.s.dt.aoColumns[iColumn].nTh).clone(true)[0];
+                               nClone.innerHTML = "";
+
+                               var oStyle = nClone.style;
+                               oStyle.paddingTop = "0";
+                               oStyle.paddingBottom = "0";
+                               oStyle.borderTopWidth = "0";
+                               oStyle.borderBottomWidth = "0";
+                               oStyle.height = 0;
+                               oStyle.width = that.s.aiInnerWidths[iColumn]+"px";
+
+                               nInnerThead.appendChild( nClone );
+                       }
+
+                       /* Add in the tbody elements, cloning form the master table */
+                       $('>tbody>tr', that.dom.body).each( function (z) {
+                               var n = this.cloneNode(false);
+                               n.removeAttribute('id');
+                               var i = that.s.dt.oFeatures.bServerSide===false ?
+                                       that.s.dt.aiDisplay[ that.s.dt._iDisplayStart+z ] : z;
+                               var aTds = $(this).children('td, th');
+
+                               for ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )
+                               {
+                                       iColumn = aiColumns[iIndex];
+
+                                       if ( aTds.length > 0 )
+                                       {
+                                               nClone = $( aTds[iColumn] ).clone(true, true)[0];
+                                               n.appendChild( nClone );
+                                       }
+                               }
+                               nBody.appendChild( n );
+                       } );
+               }
+               else
+               {
+                       $('>tbody>tr', that.dom.body).each( function (z) {
+                               nClone = this.cloneNode(true);
+                               nClone.className += ' DTFC_NoData';
+                               $('td', nClone).html('');
+                               nBody.appendChild( nClone );
+                       } );
+               }
+
+               oClone.body.style.width = "100%";
+               oClone.body.style.margin = "0";
+               oClone.body.style.padding = "0";
+
+               if ( bAll )
+               {
+                       if ( typeof this.s.dt.oScroller != 'undefined' )
+                       {
+                               oGrid.liner.appendChild( this.s.dt.oScroller.dom.force.cloneNode(true) );
+                       }
+               }
+               oGrid.liner.appendChild( oClone.body );
+
+               this._fnEqualiseHeights( 'tbody', that.dom.body, oClone.body );
+
+               /*
+                * Footer
+                */
+               if ( this.s.dt.nTFoot !== null )
+               {
+                       if ( bAll )
+                       {
+                               if ( oClone.footer !== null )
+                               {
+                                       oClone.footer.parentNode.removeChild( oClone.footer );
+                               }
+                               oClone.footer = $(this.dom.footer).clone(true, true)[0];
+                               oClone.footer.className += " DTFC_Cloned";
+                               oClone.footer.style.width = "100%";
+                               oGrid.foot.appendChild( oClone.footer );
+
+                               /* Copy the footer just like we do for the header */
+                               aoCloneLayout = this._fnCopyLayout( this.s.dt.aoFooter, aiColumns );
+                               var jqCloneTfoot = $('>tfoot', oClone.footer);
+                               jqCloneTfoot.empty();
+
+                               for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
+                               {
+                                       jqCloneTfoot[0].appendChild( aoCloneLayout[i].nTr );
+                               }
+                               this.s.dt.oApi._fnDrawHead( this.s.dt, aoCloneLayout, true );
+                       }
+                       else
+                       {
+                               aoCloneLayout = this._fnCopyLayout( this.s.dt.aoFooter, aiColumns );
+                               var aoCurrFooter=[];
+
+                               this.s.dt.oApi._fnDetectHeader( aoCurrFooter, $('>tfoot', oClone.footer)[0] );
+
+                               for ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )
+                               {
+                                       for ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )
+                                       {
+                                               aoCurrFooter[i][j].cell.className = aoCloneLayout[i][j].cell.className;
+                                       }
+                               }
+                       }
+                       this._fnEqualiseHeights( 'tfoot', this.dom.footer, oClone.footer );
+               }
+
+               /* Equalise the column widths between the header footer and body - body get's priority */
+               var anUnique = this.s.dt.oApi._fnGetUniqueThs( this.s.dt, $('>thead', oClone.header)[0] );
+               $(anUnique).each( function (i) {
+                       iColumn = aiColumns[i];
+                       this.style.width = that.s.aiInnerWidths[iColumn]+"px";
+               } );
+
+               if ( that.s.dt.nTFoot !== null )
+               {
+                       anUnique = this.s.dt.oApi._fnGetUniqueThs( this.s.dt, $('>tfoot', oClone.footer)[0] );
+                       $(anUnique).each( function (i) {
+                               iColumn = aiColumns[i];
+                               this.style.width = that.s.aiInnerWidths[iColumn]+"px";
+                       } );
+               }
+       },
+
+
+       /**
+        * From a given table node (THEAD etc), get a list of TR direct child elements
+        *  @param   {Node} nIn Table element to search for TR elements (THEAD, TBODY or TFOOT element)
+        *  @returns {Array} List of TR elements found
+        *  @private
+        */
+       "_fnGetTrNodes": function ( nIn )
+       {
+               var aOut = [];
+               for ( var i=0, iLen=nIn.childNodes.length ; i<iLen ; i++ )
+               {
+                       if ( nIn.childNodes[i].nodeName.toUpperCase() == "TR" )
+                       {
+                               aOut.push( nIn.childNodes[i] );
+                       }
+               }
+               return aOut;
+       },
+
+
+       /**
+        * Equalise the heights of the rows in a given table node in a cross browser way
+        *  @returns {void}
+        *  @param   {String} nodeName Node type - thead, tbody or tfoot
+        *  @param   {Node} original Original node to take the heights from
+        *  @param   {Node} clone Copy the heights to
+        *  @private
+        */
+       "_fnEqualiseHeights": function ( nodeName, original, clone )
+       {
+               if ( this.s.sHeightMatch == 'none' && nodeName !== 'thead' && nodeName !== 'tfoot' )
+               {
+                       return;
+               }
+
+               var that = this,
+                       i, iLen, iHeight, iHeight2, iHeightOriginal, iHeightClone,
+                       rootOriginal = original.getElementsByTagName(nodeName)[0],
+                       rootClone    = clone.getElementsByTagName(nodeName)[0],
+                       jqBoxHack    = $('>'+nodeName+'>tr:eq(0)', original).children(':first'),
+                       iBoxHack     = jqBoxHack.outerHeight() - jqBoxHack.height(),
+                       anOriginal   = this._fnGetTrNodes( rootOriginal ),
+                       anClone      = this._fnGetTrNodes( rootClone ),
+                       heights      = [];
+
+               for ( i=0, iLen=anClone.length ; i<iLen ; i++ )
+               {
+                       iHeightOriginal = anOriginal[i].offsetHeight;
+                       iHeightClone = anClone[i].offsetHeight;
+                       iHeight = iHeightClone > iHeightOriginal ? iHeightClone : iHeightOriginal;
+
+                       if ( this.s.sHeightMatch == 'semiauto' )
+                       {
+                               anOriginal[i]._DTTC_iHeight = iHeight;
+                       }
+
+                       heights.push( iHeight );
+               }
+
+               for ( i=0, iLen=anClone.length ; i<iLen ; i++ )
+               {
+                       anClone[i].style.height = heights[i]+"px";
+                       anOriginal[i].style.height = heights[i]+"px";
+               }
+       }
+};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Statics
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/**
+ * FixedColumns default settings for initialisation
+ *  @name FixedColumns.defaults
+ *  @namespace
+ *  @static
+ */
+FixedColumns.defaults = /** @lends FixedColumns.defaults */{
+       /**
+        * Number of left hand columns to fix in position
+        *  @type     int
+        *  @default  1
+        *  @static
+        *  @example
+        *      var  = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      new $.fn.dataTable.fixedColumns( table, {
+        *          "leftColumns": 2
+        *      } );
+        */
+       "iLeftColumns": 1,
+
+       /**
+        * Number of right hand columns to fix in position
+        *  @type     int
+        *  @default  0
+        *  @static
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      new $.fn.dataTable.fixedColumns( table, {
+        *          "rightColumns": 1
+        *      } );
+        */
+       "iRightColumns": 0,
+
+       /**
+        * Draw callback function which is called when FixedColumns has redrawn the fixed assets
+        *  @type     function(object, object):void
+        *  @default  null
+        *  @static
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      new $.fn.dataTable.fixedColumns( table, {
+        *          "drawCallback": function () {
+        *                  alert( "FixedColumns redraw" );
+        *              }
+        *      } );
+        */
+       "fnDrawCallback": null,
+
+       /**
+        * Height matching algorthim to use. This can be "none" which will result in no height
+        * matching being applied by FixedColumns (height matching could be forced by CSS in this
+        * case), "semiauto" whereby the height calculation will be performed once, and the result
+        * cached to be used again (fnRecalculateHeight can be used to force recalculation), or
+        * "auto" when height matching is performed on every draw (slowest but must accurate)
+        *  @type     string
+        *  @default  semiauto
+        *  @static
+        *  @example
+        *      var table = $('#example').dataTable( {
+        *          "scrollX": "100%"
+        *      } );
+        *      new $.fn.dataTable.fixedColumns( table, {
+        *          "heightMatch": "auto"
+        *      } );
+        */
+       "sHeightMatch": "semiauto"
+};
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Constants
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/**
+ * FixedColumns version
+ *  @name      FixedColumns.version
+ *  @type      String
+ *  @default   See code
+ *  @static
+ */
+FixedColumns.version = "3.0.3";
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Fired events (for documentation)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/**
+ * Event fired whenever FixedColumns redraws the fixed columns (i.e. clones the table elements from the main DataTable). This will occur whenever the DataTable that the FixedColumns instance is attached does its own draw.
+ * @name FixedColumns#draw.dtfc
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o Event parameters from FixedColumns
+ * @param {object} o.leftClone Instance's object dom.clone.left for easy reference. This object contains references to the left fixed clumn column's nodes
+ * @param {object} o.rightClone Instance's object dom.clone.right for easy reference. This object contains references to the right fixed clumn column's nodes
+ */
+
+
+// Make FixedColumns accessible from the DataTables instance
+$.fn.dataTable.FixedColumns = FixedColumns;
+$.fn.DataTable.FixedColumns = FixedColumns;
+
+
+return FixedColumns;
+}; // /factory
+
+
+// Define as an AMD module if possible
+if ( typeof define === 'function' && define.amd ) {
+       define( ['jquery', 'datatables'], factory );
+}
+else if ( typeof exports === 'object' ) {
+    // Node/CommonJS
+    factory( require('jquery'), require('datatables') );
+}
+else if ( jQuery && !jQuery.fn.dataTable.FixedColumns ) {
+       // Otherwise simply initialise as normal, stopping multiple evaluation
+       factory( jQuery, jQuery.fn.dataTable );
+}
+
+
+})(window, document);
diff --git a/src/main/resources/META-INF/resources/designer/lib/dataTables.searchHighlight.min.js b/src/main/resources/META-INF/resources/designer/lib/dataTables.searchHighlight.min.js
new file mode 100644 (file)
index 0000000..37f2bef
--- /dev/null
@@ -0,0 +1,6 @@
+/*!
+ SearchHighlight for DataTables v1.0.1
+ 2014 SpryMedia Ltd - datatables.net/license
+*/
+(function(g,d,a){function e(a,c){a.unhighlight();c.rows({filter:"applied"}).data().length&&a.highlight(c.search().split(" "))}a(d).on("init.dt.dth",function(d,c){var b=new a.fn.dataTable.Api(c),f=a(b.table().body());if(a(b.table().node()).hasClass("searchHighlight")||c.oInit.searchHighlight||a.fn.dataTable.defaults.searchHighlight)b.on("draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth",function(){e(f,b)}).on("destroy",function(){b.off("draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth")}),
+b.search()&&e(f,b)})})(window,document,jQuery);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dataTables.tableTools.js b/src/main/resources/META-INF/resources/designer/lib/dataTables.tableTools.js
new file mode 100644 (file)
index 0000000..4fd3939
--- /dev/null
@@ -0,0 +1,3215 @@
+/*! TableTools 2.2.3
+ * 2009-2014 SpryMedia Ltd - datatables.net/license
+ *
+ * ZeroClipboard 1.0.4
+ * Author: Joseph Huckaby - MIT licensed
+ */
+
+/**
+ * @summary     TableTools
+ * @description Tools and buttons for DataTables
+ * @version     2.2.3
+ * @file        dataTables.tableTools.js
+ * @author      SpryMedia Ltd (www.sprymedia.co.uk)
+ * @contact     www.sprymedia.co.uk/contact
+ * @copyright   Copyright 2009-2014 SpryMedia Ltd.
+ *
+ * This source file is free software, available under the following license:
+ *   MIT license - http://datatables.net/license/mit
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ *
+ * For details please refer to: http://www.datatables.net
+ */
+
+
+/* Global scope for TableTools for backwards compatibility.
+ * Will be removed in 2.3
+ */
+var TableTools;
+
+(function(window, document, undefined) {
+
+
+var factory = function( $, DataTable ) {
+"use strict";
+
+
+//include ZeroClipboard.js
+/* ZeroClipboard 1.0.4
+ * Author: Joseph Huckaby
+ */
+
+var ZeroClipboard_TableTools = {
+
+       version: "1.0.4-TableTools2",
+       clients: {}, // registered upload clients on page, indexed by id
+       moviePath: '', // URL to movie
+       nextId: 1, // ID of next movie
+
+       $: function(thingy) {
+               // simple DOM lookup utility function
+               if (typeof(thingy) == 'string') {
+                       thingy = document.getElementById(thingy);
+               }
+               if (!thingy.addClass) {
+                       // extend element with a few useful methods
+                       thingy.hide = function() { this.style.display = 'none'; };
+                       thingy.show = function() { this.style.display = ''; };
+                       thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
+                       thingy.removeClass = function(name) {
+                               this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
+                       };
+                       thingy.hasClass = function(name) {
+                               return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
+                       };
+               }
+               return thingy;
+       },
+
+       setMoviePath: function(path) {
+               // set path to ZeroClipboard.swf
+               this.moviePath = path;
+       },
+
+       dispatch: function(id, eventName, args) {
+               // receive event from flash movie, send to client
+               var client = this.clients[id];
+               if (client) {
+                       client.receiveEvent(eventName, args);
+               }
+       },
+
+       register: function(id, client) {
+               // register new client to receive events
+               this.clients[id] = client;
+       },
+
+       getDOMObjectPosition: function(obj) {
+               // get absolute coordinates for dom element
+               var info = {
+                       left: 0,
+                       top: 0,
+                       width: obj.width ? obj.width : obj.offsetWidth,
+                       height: obj.height ? obj.height : obj.offsetHeight
+               };
+
+               if ( obj.style.width !== "" ) {
+                       info.width = obj.style.width.replace("px","");
+               }
+
+               if ( obj.style.height !== "" ) {
+                       info.height = obj.style.height.replace("px","");
+               }
+
+               while (obj) {
+                       info.left += obj.offsetLeft;
+                       info.top += obj.offsetTop;
+                       obj = obj.offsetParent;
+               }
+
+               return info;
+       },
+
+       Client: function(elem) {
+               // constructor for new simple upload client
+               this.handlers = {};
+
+               // unique ID
+               this.id = ZeroClipboard_TableTools.nextId++;
+               this.movieId = 'ZeroClipboard_TableToolsMovie_' + this.id;
+
+               // register client with singleton to receive flash events
+               ZeroClipboard_TableTools.register(this.id, this);
+
+               // create movie
+               if (elem) {
+                       this.glue(elem);
+               }
+       }
+};
+
+ZeroClipboard_TableTools.Client.prototype = {
+
+       id: 0, // unique ID for us
+       ready: false, // whether movie is ready to receive events or not
+       movie: null, // reference to movie object
+       clipText: '', // text to copy to clipboard
+       fileName: '', // default file save name
+       action: 'copy', // action to perform
+       handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
+       cssEffects: true, // enable CSS mouse effects on dom container
+       handlers: null, // user event handlers
+       sized: false,
+
+       glue: function(elem, title) {
+               // glue to DOM element
+               // elem can be ID or actual DOM element object
+               this.domElement = ZeroClipboard_TableTools.$(elem);
+
+               // float just above object, or zIndex 99 if dom element isn't set
+               var zIndex = 99;
+               if (this.domElement.style.zIndex) {
+                       zIndex = parseInt(this.domElement.style.zIndex, 10) + 1;
+               }
+
+               // find X/Y position of domElement
+               var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+
+               // create floating DIV above element
+               this.div = document.createElement('div');
+               var style = this.div.style;
+               style.position = 'absolute';
+               style.left = '0px';
+               style.top = '0px';
+               style.width = (box.width) + 'px';
+               style.height = box.height + 'px';
+               style.zIndex = zIndex;
+
+               if ( typeof title != "undefined" && title !== "" ) {
+                       this.div.title = title;
+               }
+               if ( box.width !== 0 && box.height !== 0 ) {
+                       this.sized = true;
+               }
+
+               // style.backgroundColor = '#f00'; // debug
+               if ( this.domElement ) {
+                       this.domElement.appendChild(this.div);
+                       this.div.innerHTML = this.getHTML( box.width, box.height ).replace(/&/g, '&amp;');
+               }
+       },
+
+       positionElement: function() {
+               var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+               var style = this.div.style;
+
+               style.position = 'absolute';
+               //style.left = (this.domElement.offsetLeft)+'px';
+               //style.top = this.domElement.offsetTop+'px';
+               style.width = box.width + 'px';
+               style.height = box.height + 'px';
+
+               if ( box.width !== 0 && box.height !== 0 ) {
+                       this.sized = true;
+               } else {
+                       return;
+               }
+
+               var flash = this.div.childNodes[0];
+               flash.width = box.width;
+               flash.height = box.height;
+       },
+
+       getHTML: function(width, height) {
+               // return HTML for movie
+               var html = '';
+               var flashvars = 'id=' + this.id +
+                       '&width=' + width +
+                       '&height=' + height;
+
+               if (navigator.userAgent.match(/MSIE/)) {
+                       // IE gets an OBJECT tag
+                       var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
+                       html += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard_TableTools.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
+               }
+               else {
+                       // all other browsers get an EMBED tag
+                       html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard_TableTools.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
+               }
+               return html;
+       },
+
+       hide: function() {
+               // temporarily hide floater offscreen
+               if (this.div) {
+                       this.div.style.left = '-2000px';
+               }
+       },
+
+       show: function() {
+               // show ourselves after a call to hide()
+               this.reposition();
+       },
+
+       destroy: function() {
+               // destroy control and floater
+               if (this.domElement && this.div) {
+                       this.hide();
+                       this.div.innerHTML = '';
+
+                       var body = document.getElementsByTagName('body')[0];
+                       try { body.removeChild( this.div ); } catch(e) {}
+
+                       this.domElement = null;
+                       this.div = null;
+               }
+       },
+
+       reposition: function(elem) {
+               // reposition our floating div, optionally to new container
+               // warning: container CANNOT change size, only position
+               if (elem) {
+                       this.domElement = ZeroClipboard_TableTools.$(elem);
+                       if (!this.domElement) {
+                               this.hide();
+                       }
+               }
+
+               if (this.domElement && this.div) {
+                       var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+                       var style = this.div.style;
+                       style.left = '' + box.left + 'px';
+                       style.top = '' + box.top + 'px';
+               }
+       },
+
+       clearText: function() {
+               // clear the text to be copy / saved
+               this.clipText = '';
+               if (this.ready) {
+                       this.movie.clearText();
+               }
+       },
+
+       appendText: function(newText) {
+               // append text to that which is to be copied / saved
+               this.clipText += newText;
+               if (this.ready) { this.movie.appendText(newText) ;}
+       },
+
+       setText: function(newText) {
+               // set text to be copied to be copied / saved
+               this.clipText = newText;
+               if (this.ready) { this.movie.setText(newText) ;}
+       },
+
+       setCharSet: function(charSet) {
+               // set the character set (UTF16LE or UTF8)
+               this.charSet = charSet;
+               if (this.ready) { this.movie.setCharSet(charSet) ;}
+       },
+
+       setBomInc: function(bomInc) {
+               // set if the BOM should be included or not
+               this.incBom = bomInc;
+               if (this.ready) { this.movie.setBomInc(bomInc) ;}
+       },
+
+       setFileName: function(newText) {
+               // set the file name
+               this.fileName = newText;
+               if (this.ready) {
+                       this.movie.setFileName(newText);
+               }
+       },
+
+       setAction: function(newText) {
+               // set action (save or copy)
+               this.action = newText;
+               if (this.ready) {
+                       this.movie.setAction(newText);
+               }
+       },
+
+       addEventListener: function(eventName, func) {
+               // add user event listener for event
+               // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
+               eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+               if (!this.handlers[eventName]) {
+                       this.handlers[eventName] = [];
+               }
+               this.handlers[eventName].push(func);
+       },
+
+       setHandCursor: function(enabled) {
+               // enable hand cursor (true), or default arrow cursor (false)
+               this.handCursorEnabled = enabled;
+               if (this.ready) {
+                       this.movie.setHandCursor(enabled);
+               }
+       },
+
+       setCSSEffects: function(enabled) {
+               // enable or disable CSS effects on DOM container
+               this.cssEffects = !!enabled;
+       },
+
+       receiveEvent: function(eventName, args) {
+               var self;
+
+               // receive event from flash
+               eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+
+               // special behavior for certain events
+               switch (eventName) {
+                       case 'load':
+                               // movie claims it is ready, but in IE this isn't always the case...
+                               // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
+                               this.movie = document.getElementById(this.movieId);
+                               if (!this.movie) {
+                                       self = this;
+                                       setTimeout( function() { self.receiveEvent('load', null); }, 1 );
+                                       return;
+                               }
+
+                               // firefox on pc needs a "kick" in order to set these in certain cases
+                               if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
+                                       self = this;
+                                       setTimeout( function() { self.receiveEvent('load', null); }, 100 );
+                                       this.ready = true;
+                                       return;
+                               }
+
+                               this.ready = true;
+                               this.movie.clearText();
+                               this.movie.appendText( this.clipText );
+                               this.movie.setFileName( this.fileName );
+                               this.movie.setAction( this.action );
+                               this.movie.setCharSet( this.charSet );
+                               this.movie.setBomInc( this.incBom );
+                               this.movie.setHandCursor( this.handCursorEnabled );
+                               break;
+
+                       case 'mouseover':
+                               if (this.domElement && this.cssEffects) {
+                                       //this.domElement.addClass('hover');
+                                       if (this.recoverActive) {
+                                               this.domElement.addClass('active');
+                                       }
+                               }
+                               break;
+
+                       case 'mouseout':
+                               if (this.domElement && this.cssEffects) {
+                                       this.recoverActive = false;
+                                       if (this.domElement.hasClass('active')) {
+                                               this.domElement.removeClass('active');
+                                               this.recoverActive = true;
+                                       }
+                                       //this.domElement.removeClass('hover');
+                               }
+                               break;
+
+                       case 'mousedown':
+                               if (this.domElement && this.cssEffects) {
+                                       this.domElement.addClass('active');
+                               }
+                               break;
+
+                       case 'mouseup':
+                               if (this.domElement && this.cssEffects) {
+                                       this.domElement.removeClass('active');
+                                       this.recoverActive = false;
+                               }
+                               break;
+               } // switch eventName
+
+               if (this.handlers[eventName]) {
+                       for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
+                               var func = this.handlers[eventName][idx];
+
+                               if (typeof(func) == 'function') {
+                                       // actual function reference
+                                       func(this, args);
+                               }
+                               else if ((typeof(func) == 'object') && (func.length == 2)) {
+                                       // PHP style object + method, i.e. [myObject, 'myMethod']
+                                       func[0][ func[1] ](this, args);
+                               }
+                               else if (typeof(func) == 'string') {
+                                       // name of function
+                                       window[func](this, args);
+                               }
+                       } // foreach event handler defined
+               } // user defined handler for event
+       }
+
+};
+
+// For the Flash binding to work, ZeroClipboard_TableTools must be on the global
+// object list
+window.ZeroClipboard_TableTools = ZeroClipboard_TableTools;
+//include TableTools.js
+/* TableTools
+ * 2009-2014 SpryMedia Ltd - datatables.net/license
+ */
+
+/*globals TableTools,ZeroClipboard_TableTools*/
+
+
+(function($, window, document) {
+
+/** 
+ * TableTools provides flexible buttons and other tools for a DataTables enhanced table
+ * @class TableTools
+ * @constructor
+ * @param {Object} oDT DataTables instance. When using DataTables 1.10 this can
+ *   also be a jQuery collection, jQuery selector, table node, DataTables API
+ *   instance or DataTables settings object.
+ * @param {Object} oOpts TableTools options
+ * @param {String} oOpts.sSwfPath ZeroClipboard SWF path
+ * @param {String} oOpts.sRowSelect Row selection options - 'none', 'single', 'multi' or 'os'
+ * @param {Function} oOpts.fnPreRowSelect Callback function just prior to row selection
+ * @param {Function} oOpts.fnRowSelected Callback function just after row selection
+ * @param {Function} oOpts.fnRowDeselected Callback function when row is deselected
+ * @param {Array} oOpts.aButtons List of buttons to be used
+ */
+TableTools = function( oDT, oOpts )
+{
+       /* Santiy check that we are a new instance */
+       if ( ! this instanceof TableTools )
+       {
+               alert( "Warning: TableTools must be initialised with the keyword 'new'" );
+       }
+
+       // In 1.10 we can use the API to get the settings object from a number of
+       // sources
+       var dtSettings = $.fn.dataTable.Api ?
+               new $.fn.dataTable.Api( oDT ).settings()[0] :
+               oDT.fnSettings();
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Public class variables
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * @namespace Settings object which contains customisable information for TableTools instance
+        */
+       this.s = {
+               /**
+                * Store 'this' so the instance can be retrieved from the settings object
+                * @property that
+                * @type         object
+                * @default  this
+                */
+               "that": this,
+
+               /** 
+                * DataTables settings objects
+                * @property dt
+                * @type         object
+                * @default  <i>From the oDT init option</i>
+                */
+               "dt": dtSettings,
+
+               /**
+                * @namespace Print specific information
+                */
+               "print": {
+                       /** 
+                        * DataTables draw 'start' point before the printing display was shown
+                        *  @property saveStart
+                        *  @type        int
+                        *  @default  -1
+                        */
+                       "saveStart": -1,
+
+                       /** 
+                        * DataTables draw 'length' point before the printing display was shown
+                        *  @property saveLength
+                        *  @type        int
+                        *  @default  -1
+                        */
+                       "saveLength": -1,
+
+                       /** 
+                        * Page scrolling point before the printing display was shown so it can be restored
+                        *  @property saveScroll
+                        *  @type        int
+                        *  @default  -1
+                        */
+                       "saveScroll": -1,
+
+                       /** 
+                        * Wrapped function to end the print display (to maintain scope)
+                        *  @property funcEnd
+                        *  @type        Function
+                        *  @default  function () {}
+                        */
+                       "funcEnd": function () {}
+               },
+
+               /**
+                * A unique ID is assigned to each button in each instance
+                * @property buttonCounter
+                *  @type        int
+                * @default  0
+                */
+               "buttonCounter": 0,
+
+               /**
+                * @namespace Select rows specific information
+                */
+               "select": {
+                       /**
+                        * Select type - can be 'none', 'single' or 'multi'
+                        * @property type
+                        *  @type        string
+                        * @default  ""
+                        */
+                       "type": "",
+
+                       /**
+                        * Array of nodes which are currently selected
+                        *  @property selected
+                        *  @type        array
+                        *  @default  []
+                        */
+                       "selected": [],
+
+                       /**
+                        * Function to run before the selection can take place. Will cancel the select if the
+                        * function returns false
+                        *  @property preRowSelect
+                        *  @type        Function
+                        *  @default  null
+                        */
+                       "preRowSelect": null,
+
+                       /**
+                        * Function to run when a row is selected
+                        *  @property postSelected
+                        *  @type        Function
+                        *  @default  null
+                        */
+                       "postSelected": null,
+
+                       /**
+                        * Function to run when a row is deselected
+                        *  @property postDeselected
+                        *  @type        Function
+                        *  @default  null
+                        */
+                       "postDeselected": null,
+
+                       /**
+                        * Indicate if all rows are selected (needed for server-side processing)
+                        *  @property all
+                        *  @type        boolean
+                        *  @default  false
+                        */
+                       "all": false,
+
+                       /**
+                        * Class name to add to selected TR nodes
+                        *  @property selectedClass
+                        *  @type        String
+                        *  @default  ""
+                        */
+                       "selectedClass": ""
+               },
+
+               /**
+                * Store of the user input customisation object
+                *  @property custom
+                *  @type        object
+                *  @default  {}
+                */
+               "custom": {},
+
+               /**
+                * SWF movie path
+                *  @property swfPath
+                *  @type        string
+                *  @default  ""
+                */
+               "swfPath": "",
+
+               /**
+                * Default button set
+                *  @property buttonSet
+                *  @type        array
+                *  @default  []
+                */
+               "buttonSet": [],
+
+               /**
+                * When there is more than one TableTools instance for a DataTable, there must be a 
+                * master which controls events (row selection etc)
+                *  @property master
+                *  @type        boolean
+                *  @default  false
+                */
+               "master": false,
+
+               /**
+                * Tag names that are used for creating collections and buttons
+                *  @namesapce
+                */
+               "tags": {}
+       };
+
+
+       /**
+        * @namespace Common and useful DOM elements for the class instance
+        */
+       this.dom = {
+               /**
+                * DIV element that is create and all TableTools buttons (and their children) put into
+                *  @property container
+                *  @type        node
+                *  @default  null
+                */
+               "container": null,
+
+               /**
+                * The table node to which TableTools will be applied
+                *  @property table
+                *  @type        node
+                *  @default  null
+                */
+               "table": null,
+
+               /**
+                * @namespace Nodes used for the print display
+                */
+               "print": {
+                       /**
+                        * Nodes which have been removed from the display by setting them to display none
+                        *  @property hidden
+                        *  @type        array
+                        *  @default  []
+                        */
+                       "hidden": [],
+
+                       /**
+                        * The information display saying telling the user about the print display
+                        *  @property message
+                        *  @type        node
+                        *  @default  null
+                        */
+                       "message": null
+         },
+
+               /**
+                * @namespace Nodes used for a collection display. This contains the currently used collection
+                */
+               "collection": {
+                       /**
+                        * The div wrapper containing the buttons in the collection (i.e. the menu)
+                        *  @property collection
+                        *  @type        node
+                        *  @default  null
+                        */
+                       "collection": null,
+
+                       /**
+                        * Background display to provide focus and capture events
+                        *  @property background
+                        *  @type        node
+                        *  @default  null
+                        */
+                       "background": null
+               }
+       };
+
+       /**
+        * @namespace Name space for the classes that this TableTools instance will use
+        * @extends TableTools.classes
+        */
+       this.classes = $.extend( true, {}, TableTools.classes );
+       if ( this.s.dt.bJUI )
+       {
+               $.extend( true, this.classes, TableTools.classes_themeroller );
+       }
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Public class methods
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * Retreieve the settings object from an instance
+        *  @method fnSettings
+        *  @returns {object} TableTools settings object
+        */
+       this.fnSettings = function () {
+               return this.s;
+       };
+
+
+       /* Constructor logic */
+       if ( typeof oOpts == 'undefined' )
+       {
+               oOpts = {};
+       }
+
+
+       TableTools._aInstances.push( this );
+       this._fnConstruct( oOpts );
+
+       return this;
+};
+
+
+
+TableTools.prototype = {
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Public methods
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * Retreieve the settings object from an instance
+        *  @returns {array} List of TR nodes which are currently selected
+        *  @param {boolean} [filtered=false] Get only selected rows which are  
+        *    available given the filtering applied to the table. By default
+        *    this is false -  i.e. all rows, regardless of filtering are 
+             selected.
+        */
+       "fnGetSelected": function ( filtered )
+       {
+               var
+                       out = [],
+                       data = this.s.dt.aoData,
+                       displayed = this.s.dt.aiDisplay,
+                       i, iLen;
+
+               if ( filtered )
+               {
+                       // Only consider filtered rows
+                       for ( i=0, iLen=displayed.length ; i<iLen ; i++ )
+                       {
+                               if ( data[ displayed[i] ]._DTTT_selected )
+                               {
+                                       out.push( data[ displayed[i] ].nTr );
+                               }
+                       }
+               }
+               else
+               {
+                       // Use all rows
+                       for ( i=0, iLen=data.length ; i<iLen ; i++ )
+                       {
+                               if ( data[i]._DTTT_selected )
+                               {
+                                       out.push( data[i].nTr );
+                               }
+                       }
+               }
+
+               return out;
+       },
+
+
+       /**
+        * Get the data source objects/arrays from DataTables for the selected rows (same as
+        * fnGetSelected followed by fnGetData on each row from the table)
+        *  @returns {array} Data from the TR nodes which are currently selected
+        */
+       "fnGetSelectedData": function ()
+       {
+               var out = [];
+               var data=this.s.dt.aoData;
+               var i, iLen;
+
+               for ( i=0, iLen=data.length ; i<iLen ; i++ )
+               {
+                       if ( data[i]._DTTT_selected )
+                       {
+                               out.push( this.s.dt.oInstance.fnGetData(i) );
+                       }
+               }
+
+               return out;
+       },
+
+
+       /**
+        * Get the indexes of the selected rows
+        *  @returns {array} List of row indexes
+        *  @param {boolean} [filtered=false] Get only selected rows which are  
+        *    available given the filtering applied to the table. By default
+        *    this is false -  i.e. all rows, regardless of filtering are 
+             selected.
+        */
+       "fnGetSelectedIndexes": function ( filtered )
+       {
+               var
+                       out = [],
+                       data = this.s.dt.aoData,
+                       displayed = this.s.dt.aiDisplay,
+                       i, iLen;
+
+               if ( filtered )
+               {
+                       // Only consider filtered rows
+                       for ( i=0, iLen=displayed.length ; i<iLen ; i++ )
+                       {
+                               if ( data[ displayed[i] ]._DTTT_selected )
+                               {
+                                       out.push( displayed[i] );
+                               }
+                       }
+               }
+               else
+               {
+                       // Use all rows
+                       for ( i=0, iLen=data.length ; i<iLen ; i++ )
+                       {
+                               if ( data[i]._DTTT_selected )
+                               {
+                                       out.push( i );
+                               }
+                       }
+               }
+
+               return out;
+       },
+
+
+       /**
+        * Check to see if a current row is selected or not
+        *  @param {Node} n TR node to check if it is currently selected or not
+        *  @returns {Boolean} true if select, false otherwise
+        */
+       "fnIsSelected": function ( n )
+       {
+               var pos = this.s.dt.oInstance.fnGetPosition( n );
+               return (this.s.dt.aoData[pos]._DTTT_selected===true) ? true : false;
+       },
+
+
+       /**
+        * Select all rows in the table
+        *  @param {boolean} [filtered=false] Select only rows which are available 
+        *    given the filtering applied to the table. By default this is false - 
+        *    i.e. all rows, regardless of filtering are selected.
+        */
+       "fnSelectAll": function ( filtered )
+       {
+               this._fnRowSelect( filtered ?
+                       this.s.dt.aiDisplay :
+                       this.s.dt.aoData
+               );
+       },
+
+
+       /**
+        * Deselect all rows in the table
+        *  @param {boolean} [filtered=false] Deselect only rows which are available 
+        *    given the filtering applied to the table. By default this is false - 
+        *    i.e. all rows, regardless of filtering are deselected.
+        */
+       "fnSelectNone": function ( filtered )
+       {
+               this._fnRowDeselect( this.fnGetSelectedIndexes(filtered) );
+       },
+
+
+       /**
+        * Select row(s)
+        *  @param {node|object|array} n The row(s) to select. Can be a single DOM
+        *    TR node, an array of TR nodes or a jQuery object.
+        */
+       "fnSelect": function ( n )
+       {
+               if ( this.s.select.type == "single" )
+               {
+                       this.fnSelectNone();
+                       this._fnRowSelect( n );
+               }
+               else
+               {
+                       this._fnRowSelect( n );
+               }
+       },
+
+
+       /**
+        * Deselect row(s)
+        *  @param {node|object|array} n The row(s) to deselect. Can be a single DOM
+        *    TR node, an array of TR nodes or a jQuery object.
+        */
+       "fnDeselect": function ( n )
+       {
+               this._fnRowDeselect( n );
+       },
+
+
+       /**
+        * Get the title of the document - useful for file names. The title is retrieved from either
+        * the configuration object's 'title' parameter, or the HTML document title
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns {String} Button title
+        */
+       "fnGetTitle": function( oConfig )
+       {
+               var sTitle = "";
+               if ( typeof oConfig.sTitle != 'undefined' && oConfig.sTitle !== "" ) {
+                       sTitle = oConfig.sTitle;
+               } else {
+                       var anTitle = document.getElementsByTagName('title');
+                       if ( anTitle.length > 0 )
+                       {
+                               sTitle = anTitle[0].innerHTML;
+                       }
+               }
+
+               /* Strip characters which the OS will object to - checking for UTF8 support in the scripting
+                * engine
+                */
+               if ( "\u00A1".toString().length < 4 ) {
+                       return sTitle.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "");
+               } else {
+                       return sTitle.replace(/[^a-zA-Z0-9_\.,\-_ !\(\)]/g, "");
+               }
+       },
+
+
+       /**
+        * Calculate a unity array with the column width by proportion for a set of columns to be
+        * included for a button. This is particularly useful for PDF creation, where we can use the
+        * column widths calculated by the browser to size the columns in the PDF.
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns {Array} Unity array of column ratios
+        */
+       "fnCalcColRatios": function ( oConfig )
+       {
+               var
+                       aoCols = this.s.dt.aoColumns,
+                       aColumnsInc = this._fnColumnTargets( oConfig.mColumns ),
+                       aColWidths = [],
+                       iWidth = 0, iTotal = 0, i, iLen;
+
+               for ( i=0, iLen=aColumnsInc.length ; i<iLen ; i++ )
+               {
+                       if ( aColumnsInc[i] )
+                       {
+                               iWidth = aoCols[i].nTh.offsetWidth;
+                               iTotal += iWidth;
+                               aColWidths.push( iWidth );
+                       }
+               }
+
+               for ( i=0, iLen=aColWidths.length ; i<iLen ; i++ )
+               {
+                       aColWidths[i] = aColWidths[i] / iTotal;
+               }
+
+               return aColWidths.join('\t');
+       },
+
+
+       /**
+        * Get the information contained in a table as a string
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns {String} Table data as a string
+        */
+       "fnGetTableData": function ( oConfig )
+       {
+               /* In future this could be used to get data from a plain HTML source as well as DataTables */
+               if ( this.s.dt )
+               {
+                       return this._fnGetDataTablesData( oConfig );
+               }
+       },
+
+
+       /**
+        * Pass text to a flash button instance, which will be used on the button's click handler
+        *  @param   {Object} clip Flash button object
+        *  @param   {String} text Text to set
+        */
+       "fnSetText": function ( clip, text )
+       {
+               this._fnFlashSetText( clip, text );
+       },
+
+
+       /**
+        * Resize the flash elements of the buttons attached to this TableTools instance - this is
+        * useful for when initialising TableTools when it is hidden (display:none) since sizes can't
+        * be calculated at that time.
+        */
+       "fnResizeButtons": function ()
+       {
+               for ( var cli in ZeroClipboard_TableTools.clients )
+               {
+                       if ( cli )
+                       {
+                               var client = ZeroClipboard_TableTools.clients[cli];
+                               if ( typeof client.domElement != 'undefined' &&
+                                        client.domElement.parentNode )
+                               {
+                                       client.positionElement();
+                               }
+                       }
+               }
+       },
+
+
+       /**
+        * Check to see if any of the ZeroClipboard client's attached need to be resized
+        */
+       "fnResizeRequired": function ()
+       {
+               for ( var cli in ZeroClipboard_TableTools.clients )
+               {
+                       if ( cli )
+                       {
+                               var client = ZeroClipboard_TableTools.clients[cli];
+                               if ( typeof client.domElement != 'undefined' &&
+                                        client.domElement.parentNode == this.dom.container &&
+                                        client.sized === false )
+                               {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       },
+
+
+       /**
+        * Programmatically enable or disable the print view
+        *  @param {boolean} [bView=true] Show the print view if true or not given. If false, then
+        *    terminate the print view and return to normal.
+        *  @param {object} [oConfig={}] Configuration for the print view
+        *  @param {boolean} [oConfig.bShowAll=false] Show all rows in the table if true
+        *  @param {string} [oConfig.sInfo] Information message, displayed as an overlay to the
+        *    user to let them know what the print view is.
+        *  @param {string} [oConfig.sMessage] HTML string to show at the top of the document - will
+        *    be included in the printed document.
+        */
+       "fnPrint": function ( bView, oConfig )
+       {
+               if ( oConfig === undefined )
+               {
+                       oConfig = {};
+               }
+
+               if ( bView === undefined || bView )
+               {
+                       this._fnPrintStart( oConfig );
+               }
+               else
+               {
+                       this._fnPrintEnd();
+               }
+       },
+
+
+       /**
+        * Show a message to the end user which is nicely styled
+        *  @param {string} message The HTML string to show to the user
+        *  @param {int} time The duration the message is to be shown on screen for (mS)
+        */
+       "fnInfo": function ( message, time ) {
+               var info = $('<div/>')
+                       .addClass( this.classes.print.info )
+                       .html( message )
+                       .appendTo( 'body' );
+
+               setTimeout( function() {
+                       info.fadeOut( "normal", function() {
+                               info.remove();
+                       } );
+               }, time );
+       },
+
+
+
+       /**
+        * Get the container element of the instance for attaching to the DOM
+        *   @returns {node} DOM node
+        */
+       "fnContainer": function () {
+               return this.dom.container;
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Private methods (they are of course public in JS, but recommended as private)
+        * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+       /**
+        * Constructor logic
+        *  @method  _fnConstruct
+        *  @param   {Object} oOpts Same as TableTools constructor
+        *  @returns void
+        *  @private 
+        */
+       "_fnConstruct": function ( oOpts )
+       {
+               var that = this;
+
+               this._fnCustomiseSettings( oOpts );
+
+               /* Container element */
+               this.dom.container = document.createElement( this.s.tags.container );
+               this.dom.container.className = this.classes.container;
+
+               /* Row selection config */
+               if ( this.s.select.type != 'none' )
+               {
+                       this._fnRowSelectConfig();
+               }
+
+               /* Buttons */
+               this._fnButtonDefinations( this.s.buttonSet, this.dom.container );
+
+               /* Destructor */
+               this.s.dt.aoDestroyCallback.push( {
+                       "sName": "TableTools",
+                       "fn": function () {
+                               $(that.s.dt.nTBody).off( 'click.DTTT_Select', 'tr' );
+                               $(that.dom.container).empty();
+
+                               // Remove the instance
+                               var idx = $.inArray( that, TableTools._aInstances );
+                               if ( idx !== -1 ) {
+                                       TableTools._aInstances.splice( idx, 1 );
+                               }
+                       }
+               } );
+       },
+
+
+       /**
+        * Take the user defined settings and the default settings and combine them.
+        *  @method  _fnCustomiseSettings
+        *  @param   {Object} oOpts Same as TableTools constructor
+        *  @returns void
+        *  @private 
+        */
+       "_fnCustomiseSettings": function ( oOpts )
+       {
+               /* Is this the master control instance or not? */
+               if ( typeof this.s.dt._TableToolsInit == 'undefined' )
+               {
+                       this.s.master = true;
+                       this.s.dt._TableToolsInit = true;
+               }
+
+               /* We can use the table node from comparisons to group controls */
+               this.dom.table = this.s.dt.nTable;
+
+               /* Clone the defaults and then the user options */
+               this.s.custom = $.extend( {}, TableTools.DEFAULTS, oOpts );
+
+               /* Flash file location */
+               this.s.swfPath = this.s.custom.sSwfPath;
+               if ( typeof ZeroClipboard_TableTools != 'undefined' )
+               {
+                       ZeroClipboard_TableTools.moviePath = this.s.swfPath;
+               }
+
+               /* Table row selecting */
+               this.s.select.type = this.s.custom.sRowSelect;
+               this.s.select.preRowSelect = this.s.custom.fnPreRowSelect;
+               this.s.select.postSelected = this.s.custom.fnRowSelected;
+               this.s.select.postDeselected = this.s.custom.fnRowDeselected;
+
+               // Backwards compatibility - allow the user to specify a custom class in the initialiser
+               if ( this.s.custom.sSelectedClass )
+               {
+                       this.classes.select.row = this.s.custom.sSelectedClass;
+               }
+
+               this.s.tags = this.s.custom.oTags;
+
+               /* Button set */
+               this.s.buttonSet = this.s.custom.aButtons;
+       },
+
+
+       /**
+        * Take the user input arrays and expand them to be fully defined, and then add them to a given
+        * DOM element
+        *  @method  _fnButtonDefinations
+        *  @param {array} buttonSet Set of user defined buttons
+        *  @param {node} wrapper Node to add the created buttons to
+        *  @returns void
+        *  @private 
+        */
+       "_fnButtonDefinations": function ( buttonSet, wrapper )
+       {
+               var buttonDef;
+
+               for ( var i=0, iLen=buttonSet.length ; i<iLen ; i++ )
+               {
+                       if ( typeof buttonSet[i] == "string" )
+                       {
+                               if ( typeof TableTools.BUTTONS[ buttonSet[i] ] == 'undefined' )
+                               {
+                                       alert( "TableTools: Warning - unknown button type: "+buttonSet[i] );
+                                       continue;
+                               }
+                               buttonDef = $.extend( {}, TableTools.BUTTONS[ buttonSet[i] ], true );
+                       }
+                       else
+                       {
+                               if ( typeof TableTools.BUTTONS[ buttonSet[i].sExtends ] == 'undefined' )
+                               {
+                                       alert( "TableTools: Warning - unknown button type: "+buttonSet[i].sExtends );
+                                       continue;
+                               }
+                               var o = $.extend( {}, TableTools.BUTTONS[ buttonSet[i].sExtends ], true );
+                               buttonDef = $.extend( o, buttonSet[i], true );
+                       }
+
+                       var button = this._fnCreateButton(
+                               buttonDef,
+                               $(wrapper).hasClass(this.classes.collection.container)
+                       );
+
+                       if ( button ) {
+                               wrapper.appendChild( button );
+                       }
+               }
+       },
+
+
+       /**
+        * Create and configure a TableTools button
+        *  @method  _fnCreateButton
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns {Node} Button element
+        *  @private 
+        */
+       "_fnCreateButton": function ( oConfig, bCollectionButton )
+       {
+         var nButton = this._fnButtonBase( oConfig, bCollectionButton );
+
+               if ( oConfig.sAction.match(/flash/) )
+               {
+                       if ( ! this._fnHasFlash() ) {
+                               return false;
+                       }
+
+                       this._fnFlashConfig( nButton, oConfig );
+               }
+               else if ( oConfig.sAction == "text" )
+               {
+                       this._fnTextConfig( nButton, oConfig );
+               }
+               else if ( oConfig.sAction == "div" )
+               {
+                       this._fnTextConfig( nButton, oConfig );
+               }
+               else if ( oConfig.sAction == "collection" )
+               {
+                       this._fnTextConfig( nButton, oConfig );
+                       this._fnCollectionConfig( nButton, oConfig );
+               }
+
+               if ( this.s.dt.iTabIndex !== -1 ) {
+                       $(nButton)
+                               .attr( 'tabindex', this.s.dt.iTabIndex )
+                               .attr( 'aria-controls', this.s.dt.sTableId )
+                               .on( 'keyup.DTTT', function (e) {
+                                       // Trigger the click event on return key when focused.
+                                       // Note that for Flash buttons this has no effect since we
+                                       // can't programmatically trigger the Flash export
+                                       if ( e.keyCode === 13 ) {
+                                               e.stopPropagation();
+
+                                               $(this).trigger( 'click' );
+                                       }
+                               } )
+                               .on( 'mousedown.DTTT', function (e) {
+                                       // On mousedown we want to stop the focus occurring on the
+                                       // button, focus is used only for the keyboard navigation.
+                                       // But using preventDefault for the flash buttons stops the
+                                       // flash action. However, it is not the button that gets
+                                       // focused but the flash element for flash buttons, so this
+                                       // works
+                                       if ( ! oConfig.sAction.match(/flash/) ) {
+                                               e.preventDefault();
+                                       }
+                               } );
+               }
+
+               return nButton;
+       },
+
+
+       /**
+        * Create the DOM needed for the button and apply some base properties. All buttons start here
+        *  @method  _fnButtonBase
+        *  @param   {o} oConfig Button configuration object
+        *  @returns {Node} DIV element for the button
+        *  @private
+        */
+       "_fnButtonBase": function ( o, bCollectionButton )
+       {
+               var sTag, sLiner, sClass;
+
+               if ( bCollectionButton )
+               {
+                       sTag = o.sTag && o.sTag !== "default" ? o.sTag : this.s.tags.collection.button;
+                       sLiner = o.sLinerTag && o.sLinerTag !== "default" ? o.sLiner : this.s.tags.collection.liner;
+                       sClass = this.classes.collection.buttons.normal;
+               }
+               else
+               {
+                       sTag = o.sTag && o.sTag !== "default" ? o.sTag : this.s.tags.button;
+                       sLiner = o.sLinerTag && o.sLinerTag !== "default" ? o.sLiner : this.s.tags.liner;
+                       sClass = this.classes.buttons.normal;
+               }
+
+               var
+                 nButton = document.createElement( sTag ),
+                 nSpan = document.createElement( sLiner ),
+                 masterS = this._fnGetMasterSettings();
+
+               nButton.className = sClass+" "+o.sButtonClass;
+               nButton.setAttribute('id', "ToolTables_"+this.s.dt.sInstance+"_"+masterS.buttonCounter );
+               nButton.appendChild( nSpan );
+               nSpan.innerHTML = o.sButtonText;
+
+               masterS.buttonCounter++;
+
+               return nButton;
+       },
+
+
+       /**
+        * Get the settings object for the master instance. When more than one TableTools instance is
+        * assigned to a DataTable, only one of them can be the 'master' (for the select rows). As such,
+        * we will typically want to interact with that master for global properties.
+        *  @method  _fnGetMasterSettings
+        *  @returns {Object} TableTools settings object
+        *  @private 
+        */
+       "_fnGetMasterSettings": function ()
+       {
+               if ( this.s.master )
+               {
+                       return this.s;
+               }
+               else
+               {
+                       /* Look for the master which has the same DT as this one */
+                       var instances = TableTools._aInstances;
+                       for ( var i=0, iLen=instances.length ; i<iLen ; i++ )
+                       {
+                               if ( this.dom.table == instances[i].s.dt.nTable )
+                               {
+                                       return instances[i].s;
+                               }
+                       }
+               }
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Button collection functions
+        */
+
+       /**
+        * Create a collection button, when activated will present a drop down list of other buttons
+        *  @param   {Node} nButton Button to use for the collection activation
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns void
+        *  @private
+        */
+       "_fnCollectionConfig": function ( nButton, oConfig )
+       {
+               var nHidden = document.createElement( this.s.tags.collection.container );
+               nHidden.style.display = "none";
+               nHidden.className = this.classes.collection.container;
+               oConfig._collection = nHidden;
+               document.body.appendChild( nHidden );
+
+               this._fnButtonDefinations( oConfig.aButtons, nHidden );
+       },
+
+
+       /**
+        * Show a button collection
+        *  @param   {Node} nButton Button to use for the collection
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns void
+        *  @private
+        */
+       "_fnCollectionShow": function ( nButton, oConfig )
+       {
+               var
+                       that = this,
+                       oPos = $(nButton).offset(),
+                       nHidden = oConfig._collection,
+                       iDivX = oPos.left,
+                       iDivY = oPos.top + $(nButton).outerHeight(),
+                       iWinHeight = $(window).height(), iDocHeight = $(document).height(),
+                       iWinWidth = $(window).width(), iDocWidth = $(document).width();
+
+               nHidden.style.position = "absolute";
+               nHidden.style.left = iDivX+"px";
+               nHidden.style.top = iDivY+"px";
+               nHidden.style.display = "block";
+               $(nHidden).css('opacity',0);
+
+               var nBackground = document.createElement('div');
+               nBackground.style.position = "absolute";
+               nBackground.style.left = "0px";
+               nBackground.style.top = "0px";
+               nBackground.style.height = ((iWinHeight>iDocHeight)? iWinHeight : iDocHeight) +"px";
+               nBackground.style.width = ((iWinWidth>iDocWidth)? iWinWidth : iDocWidth) +"px";
+               nBackground.className = this.classes.collection.background;
+               $(nBackground).css('opacity',0);
+
+               document.body.appendChild( nBackground );
+               document.body.appendChild( nHidden );
+
+               /* Visual corrections to try and keep the collection visible */
+               var iDivWidth = $(nHidden).outerWidth();
+               var iDivHeight = $(nHidden).outerHeight();
+
+               if ( iDivX + iDivWidth > iDocWidth )
+               {
+                       nHidden.style.left = (iDocWidth-iDivWidth)+"px";
+               }
+
+               if ( iDivY + iDivHeight > iDocHeight )
+               {
+                       nHidden.style.top = (iDivY-iDivHeight-$(nButton).outerHeight())+"px";
+               }
+
+               this.dom.collection.collection = nHidden;
+               this.dom.collection.background = nBackground;
+
+               /* This results in a very small delay for the end user but it allows the animation to be
+                * much smoother. If you don't want the animation, then the setTimeout can be removed
+                */
+               setTimeout( function () {
+                       $(nHidden).animate({"opacity": 1}, 500);
+                       $(nBackground).animate({"opacity": 0.25}, 500);
+               }, 10 );
+
+               /* Resize the buttons to the Flash contents fit */
+               this.fnResizeButtons();
+
+               /* Event handler to remove the collection display */
+               $(nBackground).click( function () {
+                       that._fnCollectionHide.call( that, null, null );
+               } );
+       },
+
+
+       /**
+        * Hide a button collection
+        *  @param   {Node} nButton Button to use for the collection
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns void
+        *  @private
+        */
+       "_fnCollectionHide": function ( nButton, oConfig )
+       {
+               if ( oConfig !== null && oConfig.sExtends == 'collection' )
+               {
+                       return;
+               }
+
+               if ( this.dom.collection.collection !== null )
+               {
+                       $(this.dom.collection.collection).animate({"opacity": 0}, 500, function (e) {
+                               this.style.display = "none";
+                       } );
+
+                       $(this.dom.collection.background).animate({"opacity": 0}, 500, function (e) {
+                               this.parentNode.removeChild( this );
+                       } );
+
+                       this.dom.collection.collection = null;
+                       this.dom.collection.background = null;
+               }
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Row selection functions
+        */
+
+       /**
+        * Add event handlers to a table to allow for row selection
+        *  @method  _fnRowSelectConfig
+        *  @returns void
+        *  @private 
+        */
+       "_fnRowSelectConfig": function ()
+       {
+               if ( this.s.master )
+               {
+                       var
+                               that = this,
+                               i, iLen,
+                               dt = this.s.dt,
+                               aoOpenRows = this.s.dt.aoOpenRows;
+
+                       $(dt.nTable).addClass( this.classes.select.table );
+
+                       // When using OS style selection, we want to cancel the shift text
+                       // selection, but only when the shift key is used (so you can
+                       // actually still select text in the table)
+                       if ( this.s.select.type === 'os' ) {
+                               $(dt.nTBody).on( 'mousedown.DTTT_Select', 'tr', function(e) {
+                                       if ( e.shiftKey ) {
+
+                                               $(dt.nTBody)
+                                                       .css( '-moz-user-select', 'none' )
+                                                       .one('selectstart.DTTT_Select', 'tr', function () {
+                                                               return false;
+                                                       } );
+                                       }
+                               } );
+
+                               $(dt.nTBody).on( 'mouseup.DTTT_Select', 'tr', function(e) {
+                                       $(dt.nTBody).css( '-moz-user-select', '' );
+                               } );
+                       }
+
+                       // Row selection
+                       $(dt.nTBody).on( 'click.DTTT_Select', this.s.custom.sRowSelector, function(e) {
+                               var row = this.nodeName.toLowerCase() === 'tr' ?
+                                       this :
+                                       $(this).parents('tr')[0];
+
+                               var select = that.s.select;
+                               var pos = that.s.dt.oInstance.fnGetPosition( row );
+
+                               /* Sub-table must be ignored (odd that the selector won't do this with >) */
+                               if ( row.parentNode != dt.nTBody ) {
+                                       return;
+                               }
+
+                               /* Check that we are actually working with a DataTables controlled row */
+                               if ( dt.oInstance.fnGetData(row) === null ) {
+                                   return;
+                               }
+
+                               // Shift click, ctrl click and simple click handling to make
+                               // row selection a lot like a file system in desktop OSs
+                               if ( select.type == 'os' ) {
+                                       if ( e.ctrlKey || e.metaKey ) {
+                                               // Add or remove from the selection
+                                               if ( that.fnIsSelected( row ) ) {
+                                                       that._fnRowDeselect( row, e );
+                                               }
+                                               else {
+                                                       that._fnRowSelect( row, e );
+                                               }
+                                       }
+                                       else if ( e.shiftKey ) {
+                                               // Add a range of rows, from the last selected row to
+                                               // this one
+                                               var rowIdxs = that.s.dt.aiDisplay.slice(); // visible rows
+                                               var idx1 = $.inArray( select.lastRow, rowIdxs );
+                                               var idx2 = $.inArray( pos, rowIdxs );
+
+                                               if ( that.fnGetSelected().length === 0 || idx1 === -1 ) {
+                                                       // select from top to here - slightly odd, but both
+                                                       // Windows and Mac OS do this
+                                                       rowIdxs.splice( $.inArray( pos, rowIdxs )+1, rowIdxs.length );
+                                               }
+                                               else {
+                                                       // reverse so we can shift click 'up' as well as down
+                                                       if ( idx1 > idx2 ) {
+                                                               var tmp = idx2;
+                                                               idx2 = idx1;
+                                                               idx1 = tmp;
+                                                       }
+
+                                                       rowIdxs.splice( idx2+1, rowIdxs.length );
+                                                       rowIdxs.splice( 0, idx1 );
+                                               }
+
+                                               if ( ! that.fnIsSelected( row ) ) {
+                                                       // Select range
+                                                       that._fnRowSelect( rowIdxs, e );
+                                               }
+                                               else {
+                                                       // Deselect range - need to keep the clicked on row selected
+                                                       rowIdxs.splice( $.inArray( pos, rowIdxs ), 1 );
+                                                       that._fnRowDeselect( rowIdxs, e );
+                                               }
+                                       }
+                                       else {
+                                               // No cmd or shift click. Deselect current if selected,
+                                               // or select this row only
+                                               if ( that.fnIsSelected( row ) && that.fnGetSelected().length === 1 ) {
+                                                       that._fnRowDeselect( row, e );
+                                               }
+                                               else {
+                                                       that.fnSelectNone();
+                                                       that._fnRowSelect( row, e );
+                                               }
+                                       }
+                               }
+                               else if ( that.fnIsSelected( row ) ) {
+                                       that._fnRowDeselect( row, e );
+                               }
+                               else if ( select.type == "single" ) {
+                                       that.fnSelectNone();
+                                       that._fnRowSelect( row, e );
+                               }
+                               else if ( select.type == "multi" ) {
+                                       that._fnRowSelect( row, e );
+                               }
+
+                               select.lastRow = pos;
+                       } );//.on('selectstart', function () { return false; } );
+
+                       // Bind a listener to the DataTable for when new rows are created.
+                       // This allows rows to be visually selected when they should be and
+                       // deferred rendering is used.
+                       dt.oApi._fnCallbackReg( dt, 'aoRowCreatedCallback', function (tr, data, index) {
+                               if ( dt.aoData[index]._DTTT_selected ) {
+                                       $(tr).addClass( that.classes.select.row );
+                               }
+                       }, 'TableTools-SelectAll' );
+               }
+       },
+
+       /**
+        * Select rows
+        *  @param   {*} src Rows to select - see _fnSelectData for a description of valid inputs
+        *  @private 
+        */
+       "_fnRowSelect": function ( src, e )
+       {
+               var
+                       that = this,
+                       data = this._fnSelectData( src ),
+                       firstTr = data.length===0 ? null : data[0].nTr,
+                       anSelected = [],
+                       i, len;
+
+               // Get all the rows that will be selected
+               for ( i=0, len=data.length ; i<len ; i++ )
+               {
+                       if ( data[i].nTr )
+                       {
+                               anSelected.push( data[i].nTr );
+                       }
+               }
+
+               // User defined pre-selection function
+               if ( this.s.select.preRowSelect !== null && !this.s.select.preRowSelect.call(this, e, anSelected, true) )
+               {
+                       return;
+               }
+
+               // Mark them as selected
+               for ( i=0, len=data.length ; i<len ; i++ )
+               {
+                       data[i]._DTTT_selected = true;
+
+                       if ( data[i].nTr )
+                       {
+                               $(data[i].nTr).addClass( that.classes.select.row );
+                       }
+               }
+
+               // Post-selection function
+               if ( this.s.select.postSelected !== null )
+               {
+                       this.s.select.postSelected.call( this, anSelected );
+               }
+
+               TableTools._fnEventDispatch( this, 'select', anSelected, true );
+       },
+
+       /**
+        * Deselect rows
+        *  @param   {*} src Rows to deselect - see _fnSelectData for a description of valid inputs
+        *  @private 
+        */
+       "_fnRowDeselect": function ( src, e )
+       {
+               var
+                       that = this,
+                       data = this._fnSelectData( src ),
+                       firstTr = data.length===0 ? null : data[0].nTr,
+                       anDeselectedTrs = [],
+                       i, len;
+
+               // Get all the rows that will be deselected
+               for ( i=0, len=data.length ; i<len ; i++ )
+               {
+                       if ( data[i].nTr )
+                       {
+                               anDeselectedTrs.push( data[i].nTr );
+                       }
+               }
+
+               // User defined pre-selection function
+               if ( this.s.select.preRowSelect !== null && !this.s.select.preRowSelect.call(this, e, anDeselectedTrs, false) )
+               {
+                       return;
+               }
+
+               // Mark them as deselected
+               for ( i=0, len=data.length ; i<len ; i++ )
+               {
+                       data[i]._DTTT_selected = false;
+
+                       if ( data[i].nTr )
+                       {
+                               $(data[i].nTr).removeClass( that.classes.select.row );
+                       }
+               }
+
+               // Post-deselection function
+               if ( this.s.select.postDeselected !== null )
+               {
+                       this.s.select.postDeselected.call( this, anDeselectedTrs );
+               }
+
+               TableTools._fnEventDispatch( this, 'select', anDeselectedTrs, false );
+       },
+
+       /**
+        * Take a data source for row selection and convert it into aoData points for the DT
+        *   @param {*} src Can be a single DOM TR node, an array of TR nodes (including a
+        *     a jQuery object), a single aoData point from DataTables, an array of aoData
+        *     points or an array of aoData indexes
+        *   @returns {array} An array of aoData points
+        */
+       "_fnSelectData": function ( src )
+       {
+               var out = [], pos, i, iLen;
+
+               if ( src.nodeName )
+               {
+                       // Single node
+                       pos = this.s.dt.oInstance.fnGetPosition( src );
+                       out.push( this.s.dt.aoData[pos] );
+               }
+               else if ( typeof src.length !== 'undefined' )
+               {
+                       // jQuery object or an array of nodes, or aoData points
+                       for ( i=0, iLen=src.length ; i<iLen ; i++ )
+                       {
+                               if ( src[i].nodeName )
+                               {
+                                       pos = this.s.dt.oInstance.fnGetPosition( src[i] );
+                                       out.push( this.s.dt.aoData[pos] );
+                               }
+                               else if ( typeof src[i] === 'number' )
+                               {
+                                       out.push( this.s.dt.aoData[ src[i] ] );
+                               }
+                               else
+                               {
+                                       out.push( src[i] );
+                               }
+                       }
+
+                       return out;
+               }
+               else
+               {
+                       // A single aoData point
+                       out.push( src );
+               }
+
+               return out;
+       },
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Text button functions
+        */
+
+       /**
+        * Configure a text based button for interaction events
+        *  @method  _fnTextConfig
+        *  @param   {Node} nButton Button element which is being considered
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns void
+        *  @private 
+        */
+       "_fnTextConfig": function ( nButton, oConfig )
+       {
+               var that = this;
+
+               if ( oConfig.fnInit !== null )
+               {
+                       oConfig.fnInit.call( this, nButton, oConfig );
+               }
+
+               if ( oConfig.sToolTip !== "" )
+               {
+                       nButton.title = oConfig.sToolTip;
+               }
+
+               $(nButton).hover( function () {
+                       if ( oConfig.fnMouseover !== null )
+                       {
+                               oConfig.fnMouseover.call( this, nButton, oConfig, null );
+                       }
+               }, function () {
+                       if ( oConfig.fnMouseout !== null )
+                       {
+                               oConfig.fnMouseout.call( this, nButton, oConfig, null );
+                       }
+               } );
+
+               if ( oConfig.fnSelect !== null )
+               {
+                       TableTools._fnEventListen( this, 'select', function (n) {
+                               oConfig.fnSelect.call( that, nButton, oConfig, n );
+                       } );
+               }
+
+               $(nButton).click( function (e) {
+                       //e.preventDefault();
+
+                       if ( oConfig.fnClick !== null )
+                       {
+                               oConfig.fnClick.call( that, nButton, oConfig, null, e );
+                       }
+
+                       /* Provide a complete function to match the behaviour of the flash elements */
+                       if ( oConfig.fnComplete !== null )
+                       {
+                               oConfig.fnComplete.call( that, nButton, oConfig, null, null );
+                       }
+
+                       that._fnCollectionHide( nButton, oConfig );
+               } );
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Flash button functions
+        */
+       
+       /**
+        * Check if the Flash plug-in is available
+        *  @method  _fnHasFlash
+        *  @returns {boolean} `true` if Flash available, `false` otherwise
+        *  @private 
+        */
+       "_fnHasFlash": function ()
+       {
+               try {
+                       var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
+                       if (fo) {
+                               return true;
+                       }
+               }
+               catch (e) {
+                       if (
+                               navigator.mimeTypes &&
+                               navigator.mimeTypes['application/x-shockwave-flash'] !== undefined &&
+                               navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin
+                       ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       },
+
+
+       /**
+        * Configure a flash based button for interaction events
+        *  @method  _fnFlashConfig
+        *  @param   {Node} nButton Button element which is being considered
+        *  @param   {o} oConfig Button configuration object
+        *  @returns void
+        *  @private 
+        */
+       "_fnFlashConfig": function ( nButton, oConfig )
+       {
+               var that = this;
+               var flash = new ZeroClipboard_TableTools.Client();
+
+               if ( oConfig.fnInit !== null )
+               {
+                       oConfig.fnInit.call( this, nButton, oConfig );
+               }
+
+               flash.setHandCursor( true );
+
+               if ( oConfig.sAction == "flash_save" )
+               {
+                       flash.setAction( 'save' );
+                       flash.setCharSet( (oConfig.sCharSet=="utf16le") ? 'UTF16LE' : 'UTF8' );
+                       flash.setBomInc( oConfig.bBomInc );
+                       flash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle(oConfig)) );
+               }
+               else if ( oConfig.sAction == "flash_pdf" )
+               {
+                       flash.setAction( 'pdf' );
+                       flash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle(oConfig)) );
+               }
+               else
+               {
+                       flash.setAction( 'copy' );
+               }
+
+               flash.addEventListener('mouseOver', function(client) {
+                       if ( oConfig.fnMouseover !== null )
+                       {
+                               oConfig.fnMouseover.call( that, nButton, oConfig, flash );
+                       }
+               } );
+
+               flash.addEventListener('mouseOut', function(client) {
+                       if ( oConfig.fnMouseout !== null )
+                       {
+                               oConfig.fnMouseout.call( that, nButton, oConfig, flash );
+                       }
+               } );
+
+               flash.addEventListener('mouseDown', function(client) {
+                       if ( oConfig.fnClick !== null )
+                       {
+                               oConfig.fnClick.call( that, nButton, oConfig, flash );
+                       }
+               } );
+
+               flash.addEventListener('complete', function (client, text) {
+                       if ( oConfig.fnComplete !== null )
+                       {
+                               oConfig.fnComplete.call( that, nButton, oConfig, flash, text );
+                       }
+                       that._fnCollectionHide( nButton, oConfig );
+               } );
+
+               this._fnFlashGlue( flash, nButton, oConfig.sToolTip );
+       },
+
+
+       /**
+        * Wait until the id is in the DOM before we "glue" the swf. Note that this function will call
+        * itself (using setTimeout) until it completes successfully
+        *  @method  _fnFlashGlue
+        *  @param   {Object} clip Zero clipboard object
+        *  @param   {Node} node node to glue swf to
+        *  @param   {String} text title of the flash movie
+        *  @returns void
+        *  @private 
+        */
+       "_fnFlashGlue": function ( flash, node, text )
+       {
+               var that = this;
+               var id = node.getAttribute('id');
+
+               if ( document.getElementById(id) )
+               {
+                       flash.glue( node, text );
+               }
+               else
+               {
+                       setTimeout( function () {
+                               that._fnFlashGlue( flash, node, text );
+                       }, 100 );
+               }
+       },
+
+
+       /**
+        * Set the text for the flash clip to deal with
+        * 
+        * This function is required for large information sets. There is a limit on the 
+        * amount of data that can be transferred between Javascript and Flash in a single call, so
+        * we use this method to build up the text in Flash by sending over chunks. It is estimated
+        * that the data limit is around 64k, although it is undocumented, and appears to be different
+        * between different flash versions. We chunk at 8KiB.
+        *  @method  _fnFlashSetText
+        *  @param   {Object} clip the ZeroClipboard object
+        *  @param   {String} sData the data to be set
+        *  @returns void
+        *  @private 
+        */
+       "_fnFlashSetText": function ( clip, sData )
+       {
+               var asData = this._fnChunkData( sData, 8192 );
+
+               clip.clearText();
+               for ( var i=0, iLen=asData.length ; i<iLen ; i++ )
+               {
+                       clip.appendText( asData[i] );
+               }
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Data retrieval functions
+        */
+
+       /**
+        * Convert the mixed columns variable into a boolean array the same size as the columns, which
+        * indicates which columns we want to include
+        *  @method  _fnColumnTargets
+        *  @param   {String|Array} mColumns The columns to be included in data retrieval. If a string
+        *                       then it can take the value of "visible" or "hidden" (to include all visible or
+        *                       hidden columns respectively). Or an array of column indexes
+        *  @returns {Array} A boolean array the length of the columns of the table, which each value
+        *                       indicating if the column is to be included or not
+        *  @private 
+        */
+       "_fnColumnTargets": function ( mColumns )
+       {
+               var aColumns = [];
+               var dt = this.s.dt;
+               var i, iLen;
+               var columns = dt.aoColumns;
+               var columnCount = columns.length;
+
+               if ( typeof mColumns == "function" )
+               {
+                       var a = mColumns.call( this, dt );
+
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( $.inArray( i, a ) !== -1 ? true : false );
+                       }
+               }
+               else if ( typeof mColumns == "object" )
+               {
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( false );
+                       }
+
+                       for ( i=0, iLen=mColumns.length ; i<iLen ; i++ )
+                       {
+                               aColumns[ mColumns[i] ] = true;
+                       }
+               }
+               else if ( mColumns == "visible" )
+               {
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( columns[i].bVisible ? true : false );
+                       }
+               }
+               else if ( mColumns == "hidden" )
+               {
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( columns[i].bVisible ? false : true );
+                       }
+               }
+               else if ( mColumns == "sortable" )
+               {
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( columns[i].bSortable ? true : false );
+                       }
+               }
+               else /* all */
+               {
+                       for ( i=0, iLen=columnCount ; i<iLen ; i++ )
+                       {
+                               aColumns.push( true );
+                       }
+               }
+
+               return aColumns;
+       },
+
+
+       /**
+        * New line character(s) depend on the platforms
+        *  @method  method
+        *  @param   {Object} oConfig Button configuration object - only interested in oConfig.sNewLine
+        *  @returns {String} Newline character
+        */
+       "_fnNewline": function ( oConfig )
+       {
+               if ( oConfig.sNewLine == "auto" )
+               {
+                       return navigator.userAgent.match(/Windows/) ? "\r\n" : "\n";
+               }
+               else
+               {
+                       return oConfig.sNewLine;
+               }
+       },
+
+
+       /**
+        * Get data from DataTables' internals and format it for output
+        *  @method  _fnGetDataTablesData
+        *  @param   {Object} oConfig Button configuration object
+        *  @param   {String} oConfig.sFieldBoundary Field boundary for the data cells in the string
+        *  @param   {String} oConfig.sFieldSeperator Field separator for the data cells
+        *  @param   {String} oConfig.sNewline New line options
+        *  @param   {Mixed} oConfig.mColumns Which columns should be included in the output
+        *  @param   {Boolean} oConfig.bHeader Include the header
+        *  @param   {Boolean} oConfig.bFooter Include the footer
+        *  @param   {Boolean} oConfig.bSelectedOnly Include only the selected rows in the output
+        *  @returns {String} Concatenated string of data
+        *  @private 
+        */
+       "_fnGetDataTablesData": function ( oConfig )
+       {
+               var i, iLen, j, jLen;
+               var aRow, aData=[], sLoopData='', arr;
+               var dt = this.s.dt, tr, child;
+               var regex = new RegExp(oConfig.sFieldBoundary, "g"); /* Do it here for speed */
+               var aColumnsInc = this._fnColumnTargets( oConfig.mColumns );
+               var bSelectedOnly = (typeof oConfig.bSelectedOnly != 'undefined') ? oConfig.bSelectedOnly : false;
+
+               /*
+                * Header
+                */
+               if ( oConfig.bHeader )
+               {
+                       aRow = [];
+
+                       for ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )
+                       {
+                               if ( aColumnsInc[i] )
+                               {
+                                       sLoopData = dt.aoColumns[i].sTitle.replace(/\n/g," ").replace( /<.*?>/g, "" ).replace(/^\s+|\s+$/g,"");
+                                       sLoopData = this._fnHtmlDecode( sLoopData );
+
+                                       aRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );
+                               }
+                       }
+
+                       aData.push( aRow.join(oConfig.sFieldSeperator) );
+               }
+
+               bSelectedOnly = true;
+
+               /*
+                * Body
+                */
+               var aDataIndex;
+               var aSelected = this.fnGetSelectedIndexes();
+               bSelectedOnly = this.s.select.type !== "none" && bSelectedOnly && aSelected.length !== 0;
+
+               if ( bSelectedOnly ) {
+                       // Use the selected indexes
+                       aDataIndex = aSelected;
+               }
+               else if ( DataTable.Api ) {
+                       // 1.10+ style
+                       aDataIndex = new DataTable.Api( dt )
+                               .rows( oConfig.oSelectorOpts )
+                               .indexes()
+                               .flatten()
+                               .toArray();
+               }
+               else {
+                       // 1.9- style
+                       aDataIndex = dt.oInstance
+                               .$('tr', oConfig.oSelectorOpts)
+                               .map( function (id, row) {
+                                       return dt.oInstance.fnGetPosition( row );
+                               } )
+                               .get();
+               }
+
+               for ( j=0, jLen=aDataIndex.length ; j<jLen ; j++ )
+               {
+                       tr = dt.aoData[ aDataIndex[j] ].nTr;
+                       aRow = [];
+
+                       /* Columns */
+                       for ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )
+                       {
+                               if ( aColumnsInc[i] )
+                               {
+                                       /* Convert to strings (with small optimisation) */
+                                       var mTypeData = dt.oApi._fnGetCellData( dt, aDataIndex[j], i, 'display' );
+                                       if ( oConfig.fnCellRender )
+                                       {
+                                               sLoopData = oConfig.fnCellRender( mTypeData, i, tr, aDataIndex[j] )+"";
+                                       }
+                                       else if ( typeof mTypeData == "string" )
+                                       {
+                                               /* Strip newlines, replace img tags with alt attr. and finally strip html... */
+                                               sLoopData = mTypeData.replace(/\n/g," ");
+                                               sLoopData =
+                                                   sLoopData.replace(/<img.*?\s+alt\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s>]+)).*?>/gi,
+                                                       '$1$2$3');
+                                               sLoopData = sLoopData.replace( /<.*?>/g, "" );
+                                       }
+                                       else
+                                       {
+                                               sLoopData = mTypeData+"";
+                                       }
+
+                                       /* Trim and clean the data */
+                                       sLoopData = sLoopData.replace(/^\s+/, '').replace(/\s+$/, '');
+                                       sLoopData = this._fnHtmlDecode( sLoopData );
+
+                                       /* Bound it and add it to the total data */
+                                       aRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );
+                               }
+                       }
+
+                       aData.push( aRow.join(oConfig.sFieldSeperator) );
+
+                       /* Details rows from fnOpen */
+                       if ( oConfig.bOpenRows )
+                       {
+                               arr = $.grep(dt.aoOpenRows, function(o) { return o.nParent === tr; });
+
+                               if ( arr.length === 1 )
+                               {
+                                       sLoopData = this._fnBoundData( $('td', arr[0].nTr).html(), oConfig.sFieldBoundary, regex );
+                                       aData.push( sLoopData );
+                               }
+                       }
+               }
+
+               /*
+                * Footer
+                */
+               if ( oConfig.bFooter && dt.nTFoot !== null )
+               {
+                       aRow = [];
+
+                       for ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )
+                       {
+                               if ( aColumnsInc[i] && dt.aoColumns[i].nTf !== null )
+                               {
+                                       sLoopData = dt.aoColumns[i].nTf.innerHTML.replace(/\n/g," ").replace( /<.*?>/g, "" );
+                                       sLoopData = this._fnHtmlDecode( sLoopData );
+
+                                       aRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );
+                               }
+                       }
+
+                       aData.push( aRow.join(oConfig.sFieldSeperator) );
+               }
+
+               var _sLastData = aData.join( this._fnNewline(oConfig) );
+               return _sLastData;
+       },
+
+
+       /**
+        * Wrap data up with a boundary string
+        *  @method  _fnBoundData
+        *  @param   {String} sData data to bound
+        *  @param   {String} sBoundary bounding char(s)
+        *  @param   {RegExp} regex search for the bounding chars - constructed outside for efficiency
+        *                       in the loop
+        *  @returns {String} bound data
+        *  @private 
+        */
+       "_fnBoundData": function ( sData, sBoundary, regex )
+       {
+               if ( sBoundary === "" )
+               {
+                       return sData;
+               }
+               else
+               {
+                       return sBoundary + sData.replace(regex, sBoundary+sBoundary) + sBoundary;
+               }
+       },
+
+
+       /**
+        * Break a string up into an array of smaller strings
+        *  @method  _fnChunkData
+        *  @param   {String} sData data to be broken up
+        *  @param   {Int} iSize chunk size
+        *  @returns {Array} String array of broken up text
+        *  @private 
+        */
+       "_fnChunkData": function ( sData, iSize )
+       {
+               var asReturn = [];
+               var iStrlen = sData.length;
+
+               for ( var i=0 ; i<iStrlen ; i+=iSize )
+               {
+                       if ( i+iSize < iStrlen )
+                       {
+                               asReturn.push( sData.substring( i, i+iSize ) );
+                       }
+                       else
+                       {
+                               asReturn.push( sData.substring( i, iStrlen ) );
+                       }
+               }
+
+               return asReturn;
+       },
+
+
+       /**
+        * Decode HTML entities
+        *  @method  _fnHtmlDecode
+        *  @param   {String} sData encoded string
+        *  @returns {String} decoded string
+        *  @private 
+        */
+       "_fnHtmlDecode": function ( sData )
+       {
+               if ( sData.indexOf('&') === -1 )
+               {
+                       return sData;
+               }
+
+               var n = document.createElement('div');
+
+               return sData.replace( /&([^\s]*?);/g, function( match, match2 ) {
+                       if ( match.substr(1, 1) === '#' )
+                       {
+                               return String.fromCharCode( Number(match2.substr(1)) );
+                       }
+                       else
+                       {
+                               n.innerHTML = match;
+                               return n.childNodes[0].nodeValue;
+                       }
+               } );
+       },
+
+
+
+       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        * Printing functions
+        */
+
+       /**
+        * Show print display
+        *  @method  _fnPrintStart
+        *  @param   {Event} e Event object
+        *  @param   {Object} oConfig Button configuration object
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintStart": function ( oConfig )
+       {
+         var that = this;
+         var oSetDT = this.s.dt;
+
+               /* Parse through the DOM hiding everything that isn't needed for the table */
+               this._fnPrintHideNodes( oSetDT.nTable );
+
+               /* Show the whole table */
+               this.s.print.saveStart = oSetDT._iDisplayStart;
+               this.s.print.saveLength = oSetDT._iDisplayLength;
+
+               if ( oConfig.bShowAll )
+               {
+                       oSetDT._iDisplayStart = 0;
+                       oSetDT._iDisplayLength = -1;
+                       if ( oSetDT.oApi._fnCalculateEnd ) {
+                               oSetDT.oApi._fnCalculateEnd( oSetDT );
+                       }
+                       oSetDT.oApi._fnDraw( oSetDT );
+               }
+
+               /* Adjust the display for scrolling which might be done by DataTables */
+               if ( oSetDT.oScroll.sX !== "" || oSetDT.oScroll.sY !== "" )
+               {
+                       this._fnPrintScrollStart( oSetDT );
+
+                       // If the table redraws while in print view, the DataTables scrolling
+                       // setup would hide the header, so we need to readd it on draw
+                       $(this.s.dt.nTable).bind('draw.DTTT_Print', function () {
+                               that._fnPrintScrollStart( oSetDT );
+                       } );
+               }
+
+               /* Remove the other DataTables feature nodes - but leave the table! and info div */
+               var anFeature = oSetDT.aanFeatures;
+               for ( var cFeature in anFeature )
+               {
+                       if ( cFeature != 'i' && cFeature != 't' && cFeature.length == 1 )
+                       {
+                               for ( var i=0, iLen=anFeature[cFeature].length ; i<iLen ; i++ )
+                               {
+                                       this.dom.print.hidden.push( {
+                                               "node": anFeature[cFeature][i],
+                                               "display": "block"
+                                       } );
+                                       anFeature[cFeature][i].style.display = "none";
+                               }
+                       }
+               }
+
+               /* Print class can be used for styling */
+               $(document.body).addClass( this.classes.print.body );
+
+               /* Show information message to let the user know what is happening */
+               if ( oConfig.sInfo !== "" )
+               {
+                       this.fnInfo( oConfig.sInfo, 3000 );
+               }
+
+               /* Add a message at the top of the page */
+               if ( oConfig.sMessage )
+               {
+                       $('<div/>')
+                               .addClass( this.classes.print.message )
+                               .html( oConfig.sMessage )
+                               .prependTo( 'body' );
+               }
+
+               /* Cache the scrolling and the jump to the top of the page */
+               this.s.print.saveScroll = $(window).scrollTop();
+               window.scrollTo( 0, 0 );
+
+               /* Bind a key event listener to the document for the escape key -
+                * it is removed in the callback
+                */
+               $(document).bind( "keydown.DTTT", function(e) {
+                       /* Only interested in the escape key */
+                       if ( e.keyCode == 27 )
+                       {
+                               e.preventDefault();
+                               that._fnPrintEnd.call( that, e );
+                       }
+               } );
+       },
+
+
+       /**
+        * Printing is finished, resume normal display
+        *  @method  _fnPrintEnd
+        *  @param   {Event} e Event object
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintEnd": function ( e )
+       {
+               var that = this;
+               var oSetDT = this.s.dt;
+               var oSetPrint = this.s.print;
+               var oDomPrint = this.dom.print;
+
+               /* Show all hidden nodes */
+               this._fnPrintShowNodes();
+
+               /* Restore DataTables' scrolling */
+               if ( oSetDT.oScroll.sX !== "" || oSetDT.oScroll.sY !== "" )
+               {
+                       $(this.s.dt.nTable).unbind('draw.DTTT_Print');
+
+                       this._fnPrintScrollEnd();
+               }
+
+               /* Restore the scroll */
+               window.scrollTo( 0, oSetPrint.saveScroll );
+
+               /* Drop the print message */
+               $('div.'+this.classes.print.message).remove();
+
+               /* Styling class */
+               $(document.body).removeClass( 'DTTT_Print' );
+
+               /* Restore the table length */
+               oSetDT._iDisplayStart = oSetPrint.saveStart;
+               oSetDT._iDisplayLength = oSetPrint.saveLength;
+               if ( oSetDT.oApi._fnCalculateEnd ) {
+                       oSetDT.oApi._fnCalculateEnd( oSetDT );
+               }
+               oSetDT.oApi._fnDraw( oSetDT );
+
+               $(document).unbind( "keydown.DTTT" );
+       },
+
+
+       /**
+        * Take account of scrolling in DataTables by showing the full table
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintScrollStart": function ()
+       {
+               var
+                       oSetDT = this.s.dt,
+                       nScrollHeadInner = oSetDT.nScrollHead.getElementsByTagName('div')[0],
+                       nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0],
+                       nScrollBody = oSetDT.nTable.parentNode,
+                       nTheadSize, nTfootSize;
+
+               /* Copy the header in the thead in the body table, this way we show one single table when
+                * in print view. Note that this section of code is more or less verbatim from DT 1.7.0
+                */
+               nTheadSize = oSetDT.nTable.getElementsByTagName('thead');
+               if ( nTheadSize.length > 0 )
+               {
+                       oSetDT.nTable.removeChild( nTheadSize[0] );
+               }
+
+               if ( oSetDT.nTFoot !== null )
+               {
+                       nTfootSize = oSetDT.nTable.getElementsByTagName('tfoot');
+                       if ( nTfootSize.length > 0 )
+                       {
+                               oSetDT.nTable.removeChild( nTfootSize[0] );
+                       }
+               }
+
+               nTheadSize = oSetDT.nTHead.cloneNode(true);
+               oSetDT.nTable.insertBefore( nTheadSize, oSetDT.nTable.childNodes[0] );
+
+               if ( oSetDT.nTFoot !== null )
+               {
+                       nTfootSize = oSetDT.nTFoot.cloneNode(true);
+                       oSetDT.nTable.insertBefore( nTfootSize, oSetDT.nTable.childNodes[1] );
+               }
+
+               /* Now adjust the table's viewport so we can actually see it */
+               if ( oSetDT.oScroll.sX !== "" )
+               {
+                       oSetDT.nTable.style.width = $(oSetDT.nTable).outerWidth()+"px";
+                       nScrollBody.style.width = $(oSetDT.nTable).outerWidth()+"px";
+                       nScrollBody.style.overflow = "visible";
+               }
+
+               if ( oSetDT.oScroll.sY !== "" )
+               {
+                       nScrollBody.style.height = $(oSetDT.nTable).outerHeight()+"px";
+                       nScrollBody.style.overflow = "visible";
+               }
+       },
+
+
+       /**
+        * Take account of scrolling in DataTables by showing the full table. Note that the redraw of
+        * the DataTable that we do will actually deal with the majority of the hard work here
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintScrollEnd": function ()
+       {
+               var
+                       oSetDT = this.s.dt,
+                       nScrollBody = oSetDT.nTable.parentNode;
+
+               if ( oSetDT.oScroll.sX !== "" )
+               {
+                       nScrollBody.style.width = oSetDT.oApi._fnStringToCss( oSetDT.oScroll.sX );
+                       nScrollBody.style.overflow = "auto";
+               }
+
+               if ( oSetDT.oScroll.sY !== "" )
+               {
+                       nScrollBody.style.height = oSetDT.oApi._fnStringToCss( oSetDT.oScroll.sY );
+                       nScrollBody.style.overflow = "auto";
+               }
+       },
+
+
+       /**
+        * Resume the display of all TableTools hidden nodes
+        *  @method  _fnPrintShowNodes
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintShowNodes": function ( )
+       {
+         var anHidden = this.dom.print.hidden;
+
+               for ( var i=0, iLen=anHidden.length ; i<iLen ; i++ )
+               {
+                       anHidden[i].node.style.display = anHidden[i].display;
+               }
+               anHidden.splice( 0, anHidden.length );
+       },
+
+
+       /**
+        * Hide nodes which are not needed in order to display the table. Note that this function is
+        * recursive
+        *  @method  _fnPrintHideNodes
+        *  @param   {Node} nNode Element which should be showing in a 'print' display
+        *  @returns void
+        *  @private 
+        */
+       "_fnPrintHideNodes": function ( nNode )
+       {
+               var anHidden = this.dom.print.hidden;
+
+               var nParent = nNode.parentNode;
+               var nChildren = nParent.childNodes;
+               for ( var i=0, iLen=nChildren.length ; i<iLen ; i++ )
+               {
+                       if ( nChildren[i] != nNode && nChildren[i].nodeType == 1 )
+                       {
+                               /* If our node is shown (don't want to show nodes which were previously hidden) */
+                               var sDisplay = $(nChildren[i]).css("display");
+                               if ( sDisplay != "none" )
+                               {
+                                       /* Cache the node and it's previous state so we can restore it */
+                                       anHidden.push( {
+                                               "node": nChildren[i],
+                                               "display": sDisplay
+                                       } );
+                                       nChildren[i].style.display = "none";
+                               }
+                       }
+               }
+
+               if ( nParent.nodeName.toUpperCase() != "BODY" )
+               {
+                       this._fnPrintHideNodes( nParent );
+               }
+       }
+};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Static variables
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/**
+ * Store of all instances that have been created of TableTools, so one can look up other (when
+ * there is need of a master)
+ *  @property _aInstances
+ *  @type       Array
+ *  @default  []
+ *  @private
+ */
+TableTools._aInstances = [];
+
+
+/**
+ * Store of all listeners and their callback functions
+ *  @property _aListeners
+ *  @type       Array
+ *  @default  []
+ */
+TableTools._aListeners = [];
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Static methods
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/**
+ * Get an array of all the master instances
+ *  @method  fnGetMasters
+ *  @returns {Array} List of master TableTools instances
+ *  @static
+ */
+TableTools.fnGetMasters = function ()
+{
+       var a = [];
+       for ( var i=0, iLen=TableTools._aInstances.length ; i<iLen ; i++ )
+       {
+               if ( TableTools._aInstances[i].s.master )
+               {
+                       a.push( TableTools._aInstances[i] );
+               }
+       }
+       return a;
+};
+
+/**
+ * Get the master instance for a table node (or id if a string is given)
+ *  @method  fnGetInstance
+ *  @returns {Object} ID of table OR table node, for which we want the TableTools instance
+ *  @static
+ */
+TableTools.fnGetInstance = function ( node )
+{
+       if ( typeof node != 'object' )
+       {
+               node = document.getElementById(node);
+       }
+
+       for ( var i=0, iLen=TableTools._aInstances.length ; i<iLen ; i++ )
+       {
+               if ( TableTools._aInstances[i].s.master && TableTools._aInstances[i].dom.table == node )
+               {
+                       return TableTools._aInstances[i];
+               }
+       }
+       return null;
+};
+
+
+/**
+ * Add a listener for a specific event
+ *  @method  _fnEventListen
+ *  @param   {Object} that Scope of the listening function (i.e. 'this' in the caller)
+ *  @param   {String} type Event type
+ *  @param   {Function} fn Function
+ *  @returns void
+ *  @private
+ *  @static
+ */
+TableTools._fnEventListen = function ( that, type, fn )
+{
+       TableTools._aListeners.push( {
+               "that": that,
+               "type": type,
+               "fn": fn
+       } );
+};
+
+
+/**
+ * An event has occurred - look up every listener and fire it off. We check that the event we are
+ * going to fire is attached to the same table (using the table node as reference) before firing
+ *  @method  _fnEventDispatch
+ *  @param   {Object} that Scope of the listening function (i.e. 'this' in the caller)
+ *  @param   {String} type Event type
+ *  @param   {Node} node Element that the event occurred on (may be null)
+ *  @param   {boolean} [selected] Indicate if the node was selected (true) or deselected (false)
+ *  @returns void
+ *  @private
+ *  @static
+ */
+TableTools._fnEventDispatch = function ( that, type, node, selected )
+{
+       var listeners = TableTools._aListeners;
+       for ( var i=0, iLen=listeners.length ; i<iLen ; i++ )
+       {
+               if ( that.dom.table == listeners[i].that.dom.table && listeners[i].type == type )
+               {
+                       listeners[i].fn( node, selected );
+               }
+       }
+};
+
+
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Constants
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+
+TableTools.buttonBase = {
+       // Button base
+       "sAction": "text",
+       "sTag": "default",
+       "sLinerTag": "default",
+       "sButtonClass": "DTTT_button_text",
+       "sButtonText": "Button text",
+       "sTitle": "",
+       "sToolTip": "",
+
+       // Common button specific options
+       "sCharSet": "utf8",
+       "bBomInc": false,
+       "sFileName": "*.csv",
+       "sFieldBoundary": "",
+       "sFieldSeperator": "\t",
+       "sNewLine": "auto",
+       "mColumns": "all", /* "all", "visible", "hidden" or array of column integers */
+       "bHeader": true,
+       "bFooter": true,
+       "bOpenRows": false,
+       "bSelectedOnly": false,
+       "oSelectorOpts": undefined, // See http://datatables.net/docs/DataTables/1.9.4/#$ for full options
+
+       // Callbacks
+       "fnMouseover": null,
+       "fnMouseout": null,
+       "fnClick": null,
+       "fnSelect": null,
+       "fnComplete": null,
+       "fnInit": null,
+       "fnCellRender": null
+};
+
+
+/**
+ * @namespace Default button configurations
+ */
+TableTools.BUTTONS = {
+       "csv": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "flash_save",
+               "sButtonClass": "DTTT_button_csv",
+               "sButtonText": "CSV",
+               "sFieldBoundary": '"',
+               "sFieldSeperator": ",",
+               "fnClick": function( nButton, oConfig, flash ) {
+                       this.fnSetText( flash, this.fnGetTableData(oConfig) );
+               }
+       } ),
+
+       "xls": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "flash_save",
+               "sCharSet": "utf16le",
+               "bBomInc": true,
+               "sButtonClass": "DTTT_button_xls",
+               "sButtonText": "Excel",
+               "fnClick": function( nButton, oConfig, flash ) {
+                       this.fnSetText( flash, this.fnGetTableData(oConfig) );
+               }
+       } ),
+
+       "copy": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "flash_copy",
+               "sButtonClass": "DTTT_button_copy",
+               "sButtonText": "Copy",
+               "fnClick": function( nButton, oConfig, flash ) {
+                       this.fnSetText( flash, this.fnGetTableData(oConfig) );
+               },
+               "fnComplete": function(nButton, oConfig, flash, text) {
+                       var lines = text.split('\n').length;
+            if (oConfig.bHeader) lines--;
+            if (this.s.dt.nTFoot !== null && oConfig.bFooter) lines--;
+                       var plural = (lines==1) ? "" : "s";
+                       this.fnInfo( '<h6>Table copied</h6>'+
+                               '<p>Copied '+lines+' row'+plural+' to the clipboard.</p>',
+                               1500
+                       );
+               }
+       } ),
+
+       "pdf": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "flash_pdf",
+               "sNewLine": "\n",
+               "sFileName": "*.pdf",
+               "sButtonClass": "DTTT_button_pdf",
+               "sButtonText": "PDF",
+               "sPdfOrientation": "portrait",
+               "sPdfSize": "A4",
+               "sPdfMessage": "",
+               "fnClick": function( nButton, oConfig, flash ) {
+                       this.fnSetText( flash,
+                               "title:"+ this.fnGetTitle(oConfig) +"\n"+
+                               "message:"+ oConfig.sPdfMessage +"\n"+
+                               "colWidth:"+ this.fnCalcColRatios(oConfig) +"\n"+
+                               "orientation:"+ oConfig.sPdfOrientation +"\n"+
+                               "size:"+ oConfig.sPdfSize +"\n"+
+                               "--/TableToolsOpts--\n" +
+                               this.fnGetTableData(oConfig)
+                       );
+               }
+       } ),
+
+       "print": $.extend( {}, TableTools.buttonBase, {
+               "sInfo": "<h6>Print view</h6><p>Please use your browser's print function to "+
+                 "print this table. Press escape when finished.</p>",
+               "sMessage": null,
+               "bShowAll": true,
+               "sToolTip": "View print view",
+               "sButtonClass": "DTTT_button_print",
+               "sButtonText": "Print",
+               "fnClick": function ( nButton, oConfig ) {
+                       this.fnPrint( true, oConfig );
+               }
+       } ),
+
+       "text": $.extend( {}, TableTools.buttonBase ),
+
+       "select": $.extend( {}, TableTools.buttonBase, {
+               "sButtonText": "Select button",
+               "fnSelect": function( nButton, oConfig ) {
+                       if ( this.fnGetSelected().length !== 0 ) {
+                               $(nButton).removeClass( this.classes.buttons.disabled );
+                       } else {
+                               $(nButton).addClass( this.classes.buttons.disabled );
+                       }
+               },
+               "fnInit": function( nButton, oConfig ) {
+                       $(nButton).addClass( this.classes.buttons.disabled );
+               }
+       } ),
+
+       "select_single": $.extend( {}, TableTools.buttonBase, {
+               "sButtonText": "Select button",
+               "fnSelect": function( nButton, oConfig ) {
+                       var iSelected = this.fnGetSelected().length;
+                       if ( iSelected == 1 ) {
+                               $(nButton).removeClass( this.classes.buttons.disabled );
+                       } else {
+                               $(nButton).addClass( this.classes.buttons.disabled );
+                       }
+               },
+               "fnInit": function( nButton, oConfig ) {
+                       $(nButton).addClass( this.classes.buttons.disabled );
+               }
+       } ),
+
+       "select_all": $.extend( {}, TableTools.buttonBase, {
+               "sButtonText": "Select all",
+               "fnClick": function( nButton, oConfig ) {
+                       this.fnSelectAll();
+               },
+               "fnSelect": function( nButton, oConfig ) {
+                       if ( this.fnGetSelected().length == this.s.dt.fnRecordsDisplay() ) {
+                               $(nButton).addClass( this.classes.buttons.disabled );
+                       } else {
+                               $(nButton).removeClass( this.classes.buttons.disabled );
+                       }
+               }
+       } ),
+
+       "select_none": $.extend( {}, TableTools.buttonBase, {
+               "sButtonText": "Deselect all",
+               "fnClick": function( nButton, oConfig ) {
+                       this.fnSelectNone();
+               },
+               "fnSelect": function( nButton, oConfig ) {
+                       if ( this.fnGetSelected().length !== 0 ) {
+                               $(nButton).removeClass( this.classes.buttons.disabled );
+                       } else {
+                               $(nButton).addClass( this.classes.buttons.disabled );
+                       }
+               },
+               "fnInit": function( nButton, oConfig ) {
+                       $(nButton).addClass( this.classes.buttons.disabled );
+               }
+       } ),
+
+       "ajax": $.extend( {}, TableTools.buttonBase, {
+               "sAjaxUrl": "/xhr.php",
+               "sButtonText": "Ajax button",
+               "fnClick": function( nButton, oConfig ) {
+                       var sData = this.fnGetTableData(oConfig);
+                       $.ajax( {
+                               "url": oConfig.sAjaxUrl,
+                               "data": [
+                                       { "name": "tableData", "value": sData }
+                               ],
+                               "success": oConfig.fnAjaxComplete,
+                               "dataType": "json",
+                               "type": "POST",
+                               "cache": false,
+                               "error": function () {
+                                       alert( "Error detected when sending table data to server" );
+                               }
+                       } );
+               },
+               "fnAjaxComplete": function( json ) {
+                       alert( 'Ajax complete' );
+               }
+       } ),
+
+       "div": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "div",
+               "sTag": "div",
+               "sButtonClass": "DTTT_nonbutton",
+               "sButtonText": "Text button"
+       } ),
+
+       "collection": $.extend( {}, TableTools.buttonBase, {
+               "sAction": "collection",
+               "sButtonClass": "DTTT_button_collection",
+               "sButtonText": "Collection",
+               "fnClick": function( nButton, oConfig ) {
+                       this._fnCollectionShow(nButton, oConfig);
+               }
+       } )
+};
+/*
+ *  on* callback parameters:
+ *     1. node - button element
+ *     2. object - configuration object for this button
+ *     3. object - ZeroClipboard reference (flash button only)
+ *     4. string - Returned string from Flash (flash button only - and only on 'complete')
+ */
+
+// Alias to match the other plug-ins styling
+TableTools.buttons = TableTools.BUTTONS;
+
+
+/**
+ * @namespace Classes used by TableTools - allows the styles to be override easily.
+ *   Note that when TableTools initialises it will take a copy of the classes object
+ *   and will use its internal copy for the remainder of its run time.
+ */
+TableTools.classes = {
+       "container": "DTTT_container",
+       "buttons": {
+               "normal": "DTTT_button",
+               "disabled": "DTTT_disabled"
+       },
+       "collection": {
+               "container": "DTTT_collection",
+               "background": "DTTT_collection_background",
+               "buttons": {
+                       "normal": "DTTT_button",
+                       "disabled": "DTTT_disabled"
+               }
+       },
+       "select": {
+               "table": "DTTT_selectable",
+               "row": "DTTT_selected selected"
+       },
+       "print": {
+               "body": "DTTT_Print",
+               "info": "DTTT_print_info",
+               "message": "DTTT_PrintMessage"
+       }
+};
+
+
+/**
+ * @namespace ThemeRoller classes - built in for compatibility with DataTables' 
+ *   bJQueryUI option.
+ */
+TableTools.classes_themeroller = {
+       "container": "DTTT_container ui-buttonset ui-buttonset-multi",
+       "buttons": {
+               "normal": "DTTT_button ui-button ui-state-default"
+       },
+       "collection": {
+               "container": "DTTT_collection ui-buttonset ui-buttonset-multi"
+       }
+};
+
+
+/**
+ * @namespace TableTools default settings for initialisation
+ */
+TableTools.DEFAULTS = {
+       "sSwfPath":        "../swf/copy_csv_xls_pdf.swf",
+       "sRowSelect":      "none",
+       "sRowSelector":    "tr",
+       "sSelectedClass":  null,
+       "fnPreRowSelect":  null,
+       "fnRowSelected":   null,
+       "fnRowDeselected": null,
+       "aButtons":        [ "copy", "csv", "xls", "pdf", "print" ],
+       "oTags": {
+               "container": "div",
+               "button": "a", // We really want to use buttons here, but Firefox and IE ignore the
+                                // click on the Flash element in the button (but not mouse[in|out]).
+               "liner": "span",
+               "collection": {
+                       "container": "div",
+                       "button": "a",
+                       "liner": "span"
+               }
+       }
+};
+
+// Alias to match the other plug-ins
+TableTools.defaults = TableTools.DEFAULTS;
+
+
+/**
+ * Name of this class
+ *  @constant CLASS
+ *  @type       String
+ *  @default  TableTools
+ */
+TableTools.prototype.CLASS = "TableTools";
+
+
+/**
+ * TableTools version
+ *  @constant  VERSION
+ *  @type        String
+ *  @default   See code
+ */
+TableTools.version = "2.2.3";
+
+
+
+// DataTables 1.10 API
+// 
+// This will be extended in a big way in in TableTools 3 to provide API methods
+// such as rows().select() and rows.selected() etc, but for the moment the
+// tabletools() method simply returns the instance.
+
+if ( $.fn.dataTable.Api ) {
+       $.fn.dataTable.Api.register( 'tabletools()', function () {
+               var tt = null;
+
+               if ( this.context.length > 0 ) {
+                       tt = TableTools.fnGetInstance( this.context[0].nTable );
+               }
+
+               return tt;
+       } );
+}
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Initialisation
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Register a new feature with DataTables
+ */
+if ( typeof $.fn.dataTable == "function" &&
+        typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
+        $.fn.dataTableExt.fnVersionCheck('1.9.0') )
+{
+       $.fn.dataTableExt.aoFeatures.push( {
+               "fnInit": function( oDTSettings ) {
+                       var init = oDTSettings.oInit;
+                       var opts = init ?
+                               init.tableTools || init.oTableTools || {} :
+                               {};
+
+                       return new TableTools( oDTSettings.oInstance, opts ).dom.container;
+               },
+               "cFeature": "T",
+               "sFeature": "TableTools"
+       } );
+}
+else
+{
+       alert( "Warning: TableTools requires DataTables 1.9.0 or newer - www.datatables.net/download");
+}
+
+$.fn.DataTable.TableTools = TableTools;
+
+})(jQuery, window, document);
+
+/*
+ * Register a new feature with DataTables
+ */
+if ( typeof $.fn.dataTable == "function" &&
+        typeof $.fn.dataTableExt.fnVersionCheck == "function" &&
+        $.fn.dataTableExt.fnVersionCheck('1.9.0') )
+{
+       $.fn.dataTableExt.aoFeatures.push( {
+               "fnInit": function( oDTSettings ) {
+                       var oOpts = typeof oDTSettings.oInit.oTableTools != 'undefined' ?
+                               oDTSettings.oInit.oTableTools : {};
+
+                       var oTT = new TableTools( oDTSettings.oInstance, oOpts );
+                       TableTools._aInstances.push( oTT );
+
+                       return oTT.dom.container;
+               },
+               "cFeature": "T",
+               "sFeature": "TableTools"
+       } );
+}
+else
+{
+       alert( "Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download");
+}
+
+
+$.fn.dataTable.TableTools = TableTools;
+$.fn.DataTable.TableTools = TableTools;
+
+
+return TableTools;
+}; // /factory
+
+
+// Define as an AMD module if possible
+if ( typeof define === 'function' && define.amd ) {
+       define( ['jquery', 'datatables'], factory );
+}
+else if ( typeof exports === 'object' ) {
+    // Node/CommonJS
+    factory( require('jquery'), require('datatables') );
+}
+else if ( jQuery && !jQuery.fn.dataTable.TableTools ) {
+       // Otherwise simply initialise as normal, stopping multiple evaluation
+       factory( jQuery, jQuery.fn.dataTable );
+}
+
+
+})(window, document);
+
diff --git a/src/main/resources/META-INF/resources/designer/lib/dialogs-controllers.js b/src/main/resources/META-INF/resources/designer/lib/dialogs-controllers.js
new file mode 100644 (file)
index 0000000..5573fc8
--- /dev/null
@@ -0,0 +1,116 @@
+//== Controllers =============================================================//
+
+var ctrlrs; // will be dialogs.controllers module
+
+// determine if Angular-Translate is available, if not use the substitute
+try{
+       angular.module('pascalprecht.translate'); // throws error if module not loaded
+       // console.log('Dialogs (Angular-Translate): OK');
+       
+       // dialogs.controllers: module declaration
+       ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate']);
+}catch(err){
+       // console.log('Dialogs: (Angular-Translate): ' + err.message);
+       // console.log('Dialogs: Attempting to use translate.sub module.');
+
+       // dialogs.controllers: module declaration
+       ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','translate.sub']);
+} // end try/catch
+
+// angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate'])
+
+/**
+ * Error Dialog Controller 
+ */
+ctrlrs.controller('errorDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_ERROR');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_ERROR_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-warning' : 'glyphicon glyphicon-warning-sign';
+
+       //-- Methods -----//
+       
+       $scope.close = function(){
+               $modalInstance.close();
+               $scope.$destroy();
+       }; // end close
+}]); // end ErrorDialogCtrl
+       
+/**
+ * Wait Dialog Controller 
+ */
+ctrlrs.controller('waitDialogCtrl',['$scope','$modalInstance','$translate','$timeout','data',function($scope,$modalInstance,$translate,$timeout,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_PLEASE_WAIT_ELIPS');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_PLEASE_WAIT_MSG');
+       $scope.progress = (angular.isDefined(data.progress)) ? data.progress : 100;
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-clock-o' : 'glyphicon glyphicon-time';
+
+       //-- Listeners -----//
+       
+       // Note: used $timeout instead of $scope.$apply() because I was getting a $$nextSibling error
+       
+       // close wait dialog
+       $scope.$on('dialogs.wait.complete',function(){
+               $timeout(function(){ $modalInstance.close(); $scope.$destroy(); });
+       }); // end on(dialogs.wait.complete)
+       
+       // update the dialog's message
+       $scope.$on('dialogs.wait.message',function(evt,args){
+               $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
+       }); // end on(dialogs.wait.message)
+       
+       // update the dialog's progress (bar) and/or message
+       $scope.$on('dialogs.wait.progress',function(evt,args){
+               $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
+               $scope.progress = (angular.isDefined(args.progress)) ? args.progress : $scope.progress;
+       }); // end on(dialogs.wait.progress)
+       
+       //-- Methods -----//
+
+       $scope.getProgress = function(){
+               return {'width': $scope.progress + '%'};
+       }; // end getProgress
+       
+}]); // end WaitDialogCtrl
+
+/**
+ * Notify Dialog Controller 
+ */
+ctrlrs.controller('notifyDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_NOTIFICATION');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_NOTIFICATION_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-info' : 'glyphicon glyphicon-info-sign';
+
+       //-- Methods -----//
+       
+       $scope.close = function(){
+               $modalInstance.close();
+               $scope.$destroy();
+       }; // end close
+}]); // end WaitDialogCtrl
+
+/**
+ * Confirm Dialog Controller 
+ */
+ctrlrs.controller('confirmDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_CONFIRMATION');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_CONFIRMATION_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-check' : 'glyphicon glyphicon-check';
+
+       //-- Methods -----//
+       
+       $scope.no = function(){
+               $modalInstance.dismiss('no');
+       }; // end close
+       
+       $scope.yes = function(){
+               $modalInstance.close('yes');
+       }; // end yes
+}]); // end ConfirmDialogCtrl / dialogs.controllers
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dialogs-default-translations.js b/src/main/resources/META-INF/resources/designer/lib/dialogs-default-translations.js
new file mode 100644 (file)
index 0000000..2bf4466
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Dialog Default Translations.
+ *
+ * Include this module if you're not already using angular-translate in your application, and
+ * add it to your application module's dependency list in order to get default header and 
+ * dialog messages to appear.
+ * 
+ * Ex: var myApp = angular.module('myApplication',['dialogs.main','dialogs.default-translations']);
+ *
+ * It was necessary to separate this out for those already using angular-translate because this would
+ * automatically reset their translation list for 'en-US'
+ *
+ * For those already using angular-translate, just copy the list of DIALOG_[..] translations to your
+ * translation list where you set 'en-US' using the $translateProvider.
+ */
+
+//== Translations =============================================================//
+
+ angular.module('dialogs.default-translations',['pascalprecht.translate'])
+ /**
+     * Default translations in English.
+     * 
+     * Use angular-translate's $translateProvider to provide translations in an
+     * alternate language.
+     *
+     * $translateProvider.translations('[lang]',{[translations]});
+     * To use alternate translations set the preferred language to your desired
+     * language.
+     * $translateProvider.preferredLanguage('[lang]');
+     */
+    .config(['$translateProvider',function($translateProvider){
+        $translateProvider.translations('en-US',{
+            DIALOGS_ERROR: "Error",
+            DIALOGS_ERROR_MSG: "An unknown error has occurred.",
+            DIALOGS_CLOSE: "Close",
+            DIALOGS_PLEASE_WAIT: "Please Wait",
+            DIALOGS_PLEASE_WAIT_ELIPS: "Please Wait...",
+            DIALOGS_PLEASE_WAIT_MSG: "Waiting on operation to complete.",
+            DIALOGS_PERCENT_COMPLETE: "% Complete",
+            DIALOGS_NOTIFICATION: "Notification",
+            DIALOGS_NOTIFICATION_MSG: "Unknown application notification.",
+            DIALOGS_CONFIRMATION: "Confirmation",
+            DIALOGS_CONFIRMATION_MSG: "Confirmation required.",
+            DIALOGS_OK: "OK",
+            DIALOGS_YES: "Yes",
+            DIALOGS_NO: "No"
+        });
+
+        $translateProvider.preferredLanguage('en-US');
+    }]); // end config
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dialogs-main.js b/src/main/resources/META-INF/resources/designer/lib/dialogs-main.js
new file mode 100644 (file)
index 0000000..68afc46
--- /dev/null
@@ -0,0 +1,105 @@
+//== Dialogs.Main Module =====================================================//
+
+/**
+ * Include this module 'dialogs.main' in your module's dependency list where you
+ * intend to use it.  Then inject the 'dialogs' service in your controllers that
+ * need it.
+ */
+
+angular.module('dialogs.main',['dialogs.services','ngSanitize']) // requires angular-sanitize.min.js (ngSanitize) //code.angularjs.org/1.2.1/angular-sanitize.min.js
+               
+       .config(['$translateProvider','dialogsProvider',function($translateProvider,dialogsProvider){
+               /** 
+                * if Angular-Translate is not loaded, use the translate substitute
+                * module and create default translations to use as default modal texts
+                */
+               try{
+                       angular.module('pascalprecht.translate');
+               }catch(err){
+                       // console.log('Dialogs: Creating default translations for use without Angular-Translate.');
+
+                       // This will set default modal buttons, header and message text
+                       $translateProvider.translations('en-US',{
+                   DIALOGS_ERROR: "Error",
+                   DIALOGS_ERROR_MSG: "An unknown error has occurred.",
+                   DIALOGS_CLOSE: "Close",
+                   DIALOGS_PLEASE_WAIT: "Please Wait",
+                   DIALOGS_PLEASE_WAIT_ELIPS: "Please Wait...",
+                   DIALOGS_PLEASE_WAIT_MSG: "Waiting on operation to complete.",
+                   DIALOGS_PERCENT_COMPLETE: "% Complete",
+                   DIALOGS_NOTIFICATION: "Notification",
+                   DIALOGS_NOTIFICATION_MSG: "Unknown application notification.",
+                   DIALOGS_CONFIRMATION: "Confirmation",
+                   DIALOGS_CONFIRMATION_MSG: "Confirmation required.",
+                   DIALOGS_OK: "OK",
+                   DIALOGS_YES: "Yes",
+                   DIALOGS_NO: "No"
+               });
+               } // end try/catch
+
+               /**
+                * Attempt to ascertain if page is using Font Awesome instead of the
+                * regular Bootstrap Icons.  If you are changing the stylesheet name or
+                * not including it from a CDN or have included Font-Awesome as a 
+                * concatentation of CSS sheets together, then you will have to manually
+                * set Font-Awesome usage in your Angular Module's config by including
+                * the $dialogsProvider and calling the method $dialogsProvider.useFontAwesome().
+                */
+                try{
+                       var _sheets = document.styleSheets;
+
+                       sheetLoop:
+                       for(var i = (_sheets.length - 1);i >= 0;i--){
+                               var _matches = null;
+                               var _rules = null;
+
+                               if(!_sheets[i].disabled){
+                                       // check href of style sheet first
+                                       if(_sheets[i].href !== null)
+                                               _matches = _sheets[i].match(/font\-*awesome/i);
+
+                                       if(angular.isArray(_matches)){
+                                               dialogsProvider.useFontAwesome();
+                                               break; // done, leave the style sheet for loop
+                                       }else{
+                                               // try to find css rule .fa, in case style sheet has been concatenated
+                                               _rules = _sheets[i].cssRules;
+                                               for(var x = (_rules.length - 1);x >= 0;x--){
+                                                       if(_rules[x].selectorText.toLowerCase() == '.fa'){
+                                                               dialogsProvider.useFontAwesome();
+                                                               break sheetLoop; // done, exit both for loops
+                                                       }
+                                               }
+                                       }
+                               } // end if(disabled)
+                       } // end for
+
+                       /* Removed in favor of above, will delete this permanently after more testing
+                       angular.forEach(_sheets,function(_sheet,key){
+                               var _matches = null;
+                               if(!angular.equals(_sheet.href,null))
+                                       _matches = _sheet.href.match(/font\-*awesome/);
+
+                               if(!_sheet.disabled && angular.isArray(_matches)){
+                                       // console.log('Dialogs: Using Font-Awesome Icons');
+                                       dialogsProvider.useFontAwesome();
+                               }
+                       });
+                       */
+                }catch(err){
+                       // console.log('Error Message: ' + err);
+                }
+       }]) // end config
+
+       // Add default templates via $templateCache
+       .run(['$templateCache','$interpolate',function($templateCache,$interpolate){
+    
+       // get interpolation symbol (possible that someone may have changed it in their application instead of using '{{}}')
+       var startSym = $interpolate.startSymbol();
+       var endSym = $interpolate.endSymbol();
+    
+       $templateCache.put('/dialogs/error.html','<div class="modal-header dialog-header-error"><button type="button" class="close" ng-click="close()">&times;</button><h4 class="modal-title text-danger"><span class="'+startSym+'icon'+endSym+'"></span> <span ng-bind-html="header"></span></h4></div><div class="modal-body text-danger" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="close()">'+startSym+'"DIALOGS_CLOSE" | translate'+endSym+'</button></div>');
+       $templateCache.put('/dialogs/wait.html','<div class="modal-header dialog-header-wait"><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body"><p ng-bind-html="msg"></p><div class="progress progress-striped active"><div class="progress-bar progress-bar-info" ng-style="getProgress()"></div><span class="sr-only">'+startSym+'progress'+endSym+''+startSym+'"DIALOGS_PERCENT_COMPLETE" | translate'+endSym+'</span></div></div>');
+       $templateCache.put('/dialogs/notify.html','<div class="modal-header dialog-header-notify"><button type="button" class="close" ng-click="close()" class="pull-right">&times;</button><h4 class="modal-title text-info"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body text-info" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-primary" ng-click="close()">'+startSym+'"DIALOGS_OK" | translate'+endSym+'</button></div>');
+       $templateCache.put('/dialogs/confirm.html','<div class="modal-header dialog-header-confirm"><button type="button" class="close" ng-click="no()">&times;</button><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="yes()">'+startSym+'"DIALOGS_YES" | translate'+endSym+'</button><button type="button" class="btn btn-primary" ng-click="no()">'+startSym+'"DIALOGS_NO" | translate'+endSym+'</button></div>');
+       }]); // end run / dialogs.main
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dialogs-services.js b/src/main/resources/META-INF/resources/designer/lib/dialogs-services.js
new file mode 100644 (file)
index 0000000..d7301f0
--- /dev/null
@@ -0,0 +1,265 @@
+//== Services ================================================================//
+
+angular.module('dialogs.services',['ui.bootstrap.modal','dialogs.controllers'])
+
+       .provider('dialogs',[function(){
+               var _b = true; // backdrop
+               var _k = true; // keyboard
+               var _w = 'dialogs-default'; // windowClass
+               var _copy = true; // controls use of angular.copy
+               var _wTmpl = null; // window template
+               var _wSize = 'lg'; // large modal window default
+
+               var _fa = false; // fontawesome flag
+
+               var _setOpts = function(opts){
+                       var _opts = {};
+                       opts = opts || {};
+                       _opts.kb = (angular.isDefined(opts.keyboard)) ? opts.keyboard : _k; // values: true,false
+                       _opts.bd = (angular.isDefined(opts.backdrop)) ? opts.backdrop : _b; // values: 'static',true,false
+                       _opts.ws = (angular.isDefined(opts.size) && (angular.equals(opts.size,'sm') || angular.equals(opts.size,'lg') || angular.equals(opts.size,'md'))) ? opts.size : _wSize; // values: 'sm', 'lg', 'md'
+                       _opts.wc = (angular.isDefined(opts.windowClass)) ? opts.windowClass : _w; // additional CSS class(es) to be added to a modal window
+
+                       return _opts;
+               }; // end _setOpts
+
+               /**
+                * Use Backdrop
+                * 
+                * Sets the use of the modal backdrop.  Either to have one or not and
+                * whether or not it responds to mouse clicks ('static' sets the 
+                * backdrop to true and does not respond to mouse clicks).
+                *
+                * @param       val     mixed   (true, false, 'static')
+                */
+               this.useBackdrop = function(val){ // possible values : true, false, 'static'
+                       if(angular.isDefined(val))
+                               _b = val;
+               }; // end useStaticBackdrop
+
+               /**
+                * Use ESC Close
+                * 
+                * Sets the use of the ESC (escape) key to close modal windows.
+                *
+                * @param       val     boolean
+                */
+               this.useEscClose = function(val){ // possible values : true, false
+                       if(angular.isDefined(val))
+                               _k = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
+               }; // end useESCClose
+
+               /**
+                * Use Class
+                *
+                * Sets the additional CSS window class of the modal window template.
+                *
+                * @param       val     string
+                */
+               this.useClass = function(val){
+                       if(angular.isDefined(val))
+                               _w = val;
+               }; // end useClass
+
+               /**
+                * Use Copy
+                * 
+                * Determines the use of angular.copy when sending data to the modal controller.
+                *
+                * @param       val     boolean
+                */
+               this.useCopy = function(val){
+                       if(angular.isDefined(val))
+                               _copy = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
+               }; // end useCopy
+
+               /**
+                * Set Window Template
+                *
+                * Sets a path to a template to use overriding modal's window template.
+                *
+                * @param       val     string
+                */
+               this.setWindowTmpl = function(val){
+                       if(angular.isDefined(val))
+                               _wTmpl = val;
+               }; // end setWindowTmpl
+
+               /**
+                * Set Size
+                *
+                * Sets the modal size to use (sm,lg,md), requires Angular-ui-Bootstrap 0.11.0 and Bootstrap 3.1.0 + 
+                *
+                * @param       val     string (sm,lg,md)
+                */
+               this.setSize = function(val){
+                       if(angular.isDefined(val))
+                               _wSize = (angular.equals(val,'sm') || angular.equals(val,'lg') || angular.equals(val,'md')) ? val : _wSize;
+               }; // end setSize
+
+               /**
+                * Use Font-Awesome.
+                *
+                * Sets Font-Awesome flag to true and substitutes font-awesome icons for
+                * Bootstrap's glyphicons.
+                */
+               this.useFontAwesome = function(){
+                       _fa = true;
+               }; // end useFontAwesome
+
+
+               this.$get = ['$modal',function ($modal){
+                       
+                       return {
+                               /**
+                                * Error Dialog
+                                *
+                                * @param       header  string
+                                * @param       msg     string
+                                * @param       opts    object
+                                */
+                               error : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/error.html',
+                                               controller : 'errorDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end error
+                               
+                               /**
+                                * Wait Dialog
+                                *
+                                * @param       header          string
+                                * @param       msg             string
+                                * @param       progress        int
+                                * @param       opts    object
+                                */
+                               wait : function(header,msg,progress,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/wait.html',
+                                               controller : 'waitDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       progress : angular.copy(progress),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end wait
+                               
+                               /**
+                                * Notify Dialog
+                                *
+                                * @param       header          string
+                                * @param       msg             string
+                                * @param       opts    object
+                                */
+                               notify : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/notify.html',
+                                               controller : 'notifyDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end notify
+                               
+                               /**
+                                * Confirm Dialog
+                                *
+                                * @param       header  string
+                                * @param       msg     string
+                                * @param       opts    object
+                                */
+                               confirm : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/confirm.html',
+                                               controller : 'confirmDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end confirm
+                               
+                               /**
+                                * Create Custom Dialog
+                                *
+                                * @param       url     string
+                                * @param       ctrlr   string
+                                * @param       data    object
+                                * @param       opts    object
+                                */
+                               create : function(url,ctrlr,data,opts){
+                                       var copy = (opts && angular.isDefined(opts.copy)) ? opts.copy : _copy;
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : url,
+                                               controller : ctrlr,
+                                               keyboard : opts.kb,
+                                               backdrop : opts.bd,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function() { 
+                                                               if(copy)
+                                                                       return angular.copy(data);
+                                                               else
+                                                                       return data;
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               } // end create
+
+                       }; // end return
+
+               }]; // end $get
+       }]); // end provider dialogs
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/dialogs.js b/src/main/resources/META-INF/resources/designer/lib/dialogs.js
new file mode 100644 (file)
index 0000000..b8d26d1
--- /dev/null
@@ -0,0 +1,549 @@
+(function(){
+"use strict";
+//== Translate Substitute Module =============================================//
+
+/**
+ * For those not using Angular-Translate (pascalprecht.translate), this will sub
+ * in for it so we don't have to include Angular-Translate if we don't want to.
+ */
+
+var translateSubMod = angular.module('translate.sub',[]);
+
+       /**
+        * $translate Service
+        * Sets up a $translateProvider service to use in your module's config
+        * function.  $translate.Provider syntax is the same as Angular-Translate,
+        * use $translate.Provider.translations(lang,obj) to change the defaults
+        * for modal button, header and message text.
+        */
+       translateSubMod.provider('$translate',[function(){
+               var _translations = []; // object of key/value translation pairs
+               var _current = 'en-US'; // default language
+
+               /**
+                * Translations
+                * Set the internal object of translation key/value pairs.
+                */
+               this.translations = function(lang,obj){
+                       if(angular.isDefined(lang) && angular.isDefined(obj)){
+                               _translations[lang] = angular.copy(obj);
+                               _current = lang;
+                       }
+               }; // end translations
+
+               this.$get = [function(){
+                       return {
+                               /**
+                                * Instant
+                                * Retrieve the translation for the given key, if key not found
+                                * return an empty string.
+                                * Example: $translate.instant('DIALOGS_OK');
+                                */
+                               instant : function(what){
+                                       if(angular.isDefined(what) && angular.isDefined(_translations[_current][what]))
+                                               return _translations[_current][what];
+                                       else
+                                               return '';
+                               } // end instant
+                       }; // end return 
+               }]; // end $get
+
+       }]); // end $translate
+
+       /**
+        * Translate Filter
+        * For use in an Angular template.  
+        * Example: {{"DIALOGS_CLOSE" | translate}}
+        */
+       translateSubMod.filter('translate',['$translate',function($translate){
+               return function(what){
+                       return $translate.instant(what);
+               };
+       }]); // end translate / translate.sub
+//== Controllers =============================================================//
+
+var ctrlrs; // will be dialogs.controllers module
+
+// determine if Angular-Translate is available, if not use the substitute
+try{
+       angular.module('pascalprecht.translate'); // throws error if module not loaded
+       // console.log('Dialogs (Angular-Translate): OK');
+       
+       // dialogs.controllers: module declaration
+       ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate']);
+}catch(err){
+       // console.log('Dialogs: (Angular-Translate): ' + err.message);
+       // console.log('Dialogs: Attempting to use translate.sub module.');
+
+       // dialogs.controllers: module declaration
+       ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','translate.sub']);
+} // end try/catch
+
+// angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate'])
+
+/**
+ * Error Dialog Controller 
+ */
+ctrlrs.controller('errorDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_ERROR');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_ERROR_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-warning' : 'glyphicon glyphicon-warning-sign';
+
+       //-- Methods -----//
+       
+       $scope.close = function(){
+               $modalInstance.close();
+               $scope.$destroy();
+       }; // end close
+}]); // end ErrorDialogCtrl
+       
+/**
+ * Wait Dialog Controller 
+ */
+ctrlrs.controller('waitDialogCtrl',['$scope','$modalInstance','$translate','$timeout','data',function($scope,$modalInstance,$translate,$timeout,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_PLEASE_WAIT_ELIPS');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_PLEASE_WAIT_MSG');
+       $scope.progress = (angular.isDefined(data.progress)) ? data.progress : 100;
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-clock-o' : 'glyphicon glyphicon-time';
+
+       //-- Listeners -----//
+       
+       // Note: used $timeout instead of $scope.$apply() because I was getting a $$nextSibling error
+       
+       // close wait dialog
+       $scope.$on('dialogs.wait.complete',function(){
+               $timeout(function(){ $modalInstance.close(); $scope.$destroy(); });
+       }); // end on(dialogs.wait.complete)
+       
+       // update the dialog's message
+       $scope.$on('dialogs.wait.message',function(evt,args){
+               $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
+       }); // end on(dialogs.wait.message)
+       
+       // update the dialog's progress (bar) and/or message
+       $scope.$on('dialogs.wait.progress',function(evt,args){
+               $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
+               $scope.progress = (angular.isDefined(args.progress)) ? args.progress : $scope.progress;
+       }); // end on(dialogs.wait.progress)
+       
+       //-- Methods -----//
+
+       $scope.getProgress = function(){
+               return {'width': $scope.progress + '%'};
+       }; // end getProgress
+       
+}]); // end WaitDialogCtrl
+
+/**
+ * Notify Dialog Controller 
+ */
+ctrlrs.controller('notifyDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_NOTIFICATION');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_NOTIFICATION_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-info' : 'glyphicon glyphicon-info-sign';
+
+       //-- Methods -----//
+       
+       $scope.close = function(){
+               $modalInstance.close();
+               $scope.$destroy();
+       }; // end close
+}]); // end WaitDialogCtrl
+
+/**
+ * Confirm Dialog Controller 
+ */
+ctrlrs.controller('confirmDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
+       //-- Variables -----//
+
+       $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_CONFIRMATION');
+       $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_CONFIRMATION_MSG');
+       $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-check' : 'glyphicon glyphicon-check';
+
+       //-- Methods -----//
+       
+       $scope.no = function(){
+               $modalInstance.dismiss('no');
+       }; // end close
+       
+       $scope.yes = function(){
+               $modalInstance.close('yes');
+       }; // end yes
+}]); // end ConfirmDialogCtrl / dialogs.controllers
+//== Services ================================================================//
+
+angular.module('dialogs.services',['ui.bootstrap.modal','dialogs.controllers'])
+
+       .provider('dialogs',[function(){
+               var _b = true; // backdrop
+               var _k = true; // keyboard
+               var _w = 'dialogs-default'; // windowClass
+               var _copy = true; // controls use of angular.copy
+               var _wTmpl = null; // window template
+               var _wSize = 'lg'; // large modal window default
+
+               var _fa = false; // fontawesome flag
+
+               var _setOpts = function(opts){
+                       var _opts = {};
+                       opts = opts || {};
+                       _opts.kb = (angular.isDefined(opts.keyboard)) ? opts.keyboard : _k; // values: true,false
+                       _opts.bd = (angular.isDefined(opts.backdrop)) ? opts.backdrop : _b; // values: 'static',true,false
+                       _opts.ws = (angular.isDefined(opts.size) && (angular.equals(opts.size,'sm') || angular.equals(opts.size,'lg') || angular.equals(opts.size,'md'))) ? opts.size : _wSize; // values: 'sm', 'lg', 'md'
+                       _opts.wc = (angular.isDefined(opts.windowClass)) ? opts.windowClass : _w; // additional CSS class(es) to be added to a modal window
+
+                       return _opts;
+               }; // end _setOpts
+
+               /**
+                * Use Backdrop
+                * 
+                * Sets the use of the modal backdrop.  Either to have one or not and
+                * whether or not it responds to mouse clicks ('static' sets the 
+                * backdrop to true and does not respond to mouse clicks).
+                *
+                * @param       val     mixed   (true, false, 'static')
+                */
+               this.useBackdrop = function(val){ // possible values : true, false, 'static'
+                       if(angular.isDefined(val))
+                               _b = val;
+               }; // end useStaticBackdrop
+
+               /**
+                * Use ESC Close
+                * 
+                * Sets the use of the ESC (escape) key to close modal windows.
+                *
+                * @param       val     boolean
+                */
+               this.useEscClose = function(val){ // possible values : true, false
+                       if(angular.isDefined(val))
+                               _k = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
+               }; // end useESCClose
+
+               /**
+                * Use Class
+                *
+                * Sets the additional CSS window class of the modal window template.
+                *
+                * @param       val     string
+                */
+               this.useClass = function(val){
+                       if(angular.isDefined(val))
+                               _w = val;
+               }; // end useClass
+
+               /**
+                * Use Copy
+                * 
+                * Determines the use of angular.copy when sending data to the modal controller.
+                *
+                * @param       val     boolean
+                */
+               this.useCopy = function(val){
+                       if(angular.isDefined(val))
+                               _copy = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
+               }; // end useCopy
+
+               /**
+                * Set Window Template
+                *
+                * Sets a path to a template to use overriding modal's window template.
+                *
+                * @param       val     string
+                */
+               this.setWindowTmpl = function(val){
+                       if(angular.isDefined(val))
+                               _wTmpl = val;
+               }; // end setWindowTmpl
+
+               /**
+                * Set Size
+                *
+                * Sets the modal size to use (sm,lg,md), requires Angular-ui-Bootstrap 0.11.0 and Bootstrap 3.1.0 + 
+                *
+                * @param       val     string (sm,lg,md)
+                */
+               this.setSize = function(val){
+                       if(angular.isDefined(val))
+                               _wSize = (angular.equals(val,'sm') || angular.equals(val,'lg') || angular.equals(val,'md')) ? val : _wSize;
+               }; // end setSize
+
+               /**
+                * Use Font-Awesome.
+                *
+                * Sets Font-Awesome flag to true and substitutes font-awesome icons for
+                * Bootstrap's glyphicons.
+                */
+               this.useFontAwesome = function(){
+                       _fa = true;
+               }; // end useFontAwesome
+
+
+               this.$get = ['$modal',function ($modal){
+                       
+                       return {
+                               /**
+                                * Error Dialog
+                                *
+                                * @param       header  string
+                                * @param       msg     string
+                                * @param       opts    object
+                                */
+                               error : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/error.html',
+                                               controller : 'errorDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end error
+                               
+                               /**
+                                * Wait Dialog
+                                *
+                                * @param       header          string
+                                * @param       msg             string
+                                * @param       progress        int
+                                * @param       opts    object
+                                */
+                               wait : function(header,msg,progress,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/wait.html',
+                                               controller : 'waitDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       progress : angular.copy(progress),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end wait
+                               
+                               /**
+                                * Notify Dialog
+                                *
+                                * @param       header          string
+                                * @param       msg             string
+                                * @param       opts    object
+                                */
+                               notify : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/notify.html',
+                                               controller : 'notifyDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end notify
+                               
+                               /**
+                                * Confirm Dialog
+                                *
+                                * @param       header  string
+                                * @param       msg     string
+                                * @param       opts    object
+                                */
+                               confirm : function(header,msg,opts){
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : '/dialogs/confirm.html',
+                                               controller : 'confirmDialogCtrl',
+                                               backdrop: opts.bd,
+                                               keyboard: opts.kb,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function(){
+                                                               return {
+                                                                       header : angular.copy(header),
+                                                                       msg : angular.copy(msg),
+                                                                       fa : _fa
+                                                               };
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               }, // end confirm
+                               
+                               /**
+                                * Create Custom Dialog
+                                *
+                                * @param       url     string
+                                * @param       ctrlr   string
+                                * @param       data    object
+                                * @param       opts    object
+                                */
+                               create : function(url,ctrlr,data,opts){
+                                       var copy = (opts && angular.isDefined(opts.copy)) ? opts.copy : _copy;
+                                       opts = _setOpts(opts);
+
+                                       return $modal.open({
+                                               templateUrl : url,
+                                               controller : ctrlr,
+                                               keyboard : opts.kb,
+                                               backdrop : opts.bd,
+                                               windowClass: opts.wc,
+                                               size: opts.ws,
+                                               resolve : {
+                                                       data : function() { 
+                                                               if(copy)
+                                                                       return angular.copy(data);
+                                                               else
+                                                                       return data;
+                                                       }
+                                               }
+                                       }); // end modal.open
+                               } // end create
+
+                       }; // end return
+
+               }]; // end $get
+       }]); // end provider dialogs
+//== Dialogs.Main Module =====================================================//
+
+/**
+ * Include this module 'dialogs.main' in your module's dependency list where you
+ * intend to use it.  Then inject the 'dialogs' service in your controllers that
+ * need it.
+ */
+
+angular.module('dialogs.main',['dialogs.services','ngSanitize']) // requires angular-sanitize.min.js (ngSanitize) //code.angularjs.org/1.2.1/angular-sanitize.min.js
+               
+       .config(['$translateProvider','dialogsProvider',function($translateProvider,dialogsProvider){
+               /** 
+                * if Angular-Translate is not loaded, use the translate substitute
+                * module and create default translations to use as default modal texts
+                */
+               try{
+                       angular.module('pascalprecht.translate');
+               }catch(err){
+                       // console.log('Dialogs: Creating default translations for use without Angular-Translate.');
+
+                       // This will set default modal buttons, header and message text
+                       $translateProvider.translations('en-US',{
+                   DIALOGS_ERROR: "Error",
+                   DIALOGS_ERROR_MSG: "An unknown error has occurred.",
+                   DIALOGS_CLOSE: "Close",
+                   DIALOGS_PLEASE_WAIT: "Please Wait",
+                   DIALOGS_PLEASE_WAIT_ELIPS: "Please Wait...",
+                   DIALOGS_PLEASE_WAIT_MSG: "Waiting on operation to complete.",
+                   DIALOGS_PERCENT_COMPLETE: "% Complete",
+                   DIALOGS_NOTIFICATION: "Notification",
+                   DIALOGS_NOTIFICATION_MSG: "Unknown application notification.",
+                   DIALOGS_CONFIRMATION: "Confirmation",
+                   DIALOGS_CONFIRMATION_MSG: "Confirmation required.",
+                   DIALOGS_OK: "OK",
+                   DIALOGS_YES: "Yes",
+                   DIALOGS_NO: "No"
+               });
+               } // end try/catch
+
+               /**
+                * Attempt to ascertain if page is using Font Awesome instead of the
+                * regular Bootstrap Icons.  If you are changing the stylesheet name or
+                * not including it from a CDN or have included Font-Awesome as a 
+                * concatentation of CSS sheets together, then you will have to manually
+                * set Font-Awesome usage in your Angular Module's config by including
+                * the $dialogsProvider and calling the method $dialogsProvider.useFontAwesome().
+                */
+                try{
+                       var _sheets = document.styleSheets;
+
+                       sheetLoop:
+                       for(var i = (_sheets.length - 1);i >= 0;i--){
+                               var _matches = null;
+                               var _rules = null;
+
+                               if(!_sheets[i].disabled){
+                                       // check href of style sheet first
+                                       if(_sheets[i].href !== null)
+                                               _matches = _sheets[i].match(/font\-*awesome/i);
+
+                                       if(angular.isArray(_matches)){
+                                               dialogsProvider.useFontAwesome();
+                                               break; // done, leave the style sheet for loop
+                                       }else{
+                                               // try to find css rule .fa, in case style sheet has been concatenated
+                                               _rules = _sheets[i].cssRules;
+                                               for(var x = (_rules.length - 1);x >= 0;x--){
+                                                       if(_rules[x].selectorText.toLowerCase() == '.fa'){
+                                                               dialogsProvider.useFontAwesome();
+                                                               break sheetLoop; // done, exit both for loops
+                                                       }
+                                               }
+                                       }
+                               } // end if(disabled)
+                       } // end for
+
+                       /* Removed in favor of above, will delete this permanently after more testing
+                       angular.forEach(_sheets,function(_sheet,key){
+                               var _matches = null;
+                               if(!angular.equals(_sheet.href,null))
+                                       _matches = _sheet.href.match(/font\-*awesome/);
+
+                               if(!_sheet.disabled && angular.isArray(_matches)){
+                                       // console.log('Dialogs: Using Font-Awesome Icons');
+                                       dialogsProvider.useFontAwesome();
+                               }
+                       });
+                       */
+                }catch(err){
+                       // console.log('Error Message: ' + err);
+                }
+       }]) // end config
+
+       // Add default templates via $templateCache
+       .run(['$templateCache','$interpolate',function($templateCache,$interpolate){
+    
+       // get interpolation symbol (possible that someone may have changed it in their application instead of using '{{}}')
+       var startSym = $interpolate.startSymbol();
+       var endSym = $interpolate.endSymbol();
+    
+       $templateCache.put('/dialogs/error.html','<div class="modal-header dialog-header-error"><button type="button" class="close" ng-click="close()">&times;</button><h4 class="modal-title text-danger"><span class="'+startSym+'icon'+endSym+'"></span> <span ng-bind-html="header"></span></h4></div><div class="modal-body text-danger" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="close()">'+startSym+'"DIALOGS_CLOSE" | translate'+endSym+'</button></div>');
+       $templateCache.put('/dialogs/wait.html','<div class="modal-header dialog-header-wait"><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body"><p ng-bind-html="msg"></p><div class="progress progress-striped active"><div class="progress-bar progress-bar-info" ng-style="getProgress()"></div><span class="sr-only">'+startSym+'progress'+endSym+''+startSym+'"DIALOGS_PERCENT_COMPLETE" | translate'+endSym+'</span></div></div>');
+       $templateCache.put('/dialogs/notify.html','<div class="modal-header dialog-header-notify"><button type="button" class="close" ng-click="close()" class="pull-right">&times;</button><h4 class="modal-title text-info"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body text-info" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-primary" ng-click="close()">'+startSym+'"DIALOGS_OK" | translate'+endSym+'</button></div>');
+       $templateCache.put('/dialogs/confirm.html','<div class="modal-header dialog-header-confirm"><button type="button" class="close" ng-click="no()">&times;</button><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="yes()">'+startSym+'"DIALOGS_YES" | translate'+endSym+'</button><button type="button" class="btn btn-primary" ng-click="no()">'+startSym+'"DIALOGS_NO" | translate'+endSym+'</button></div>');
+       }]); // end run / dialogs.main
+})();
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/excanvas.js b/src/main/resources/META-INF/resources/designer/lib/excanvas.js
new file mode 100644 (file)
index 0000000..4ca9653
--- /dev/null
@@ -0,0 +1,1438 @@
+// Memory Leaks patch from http://explorercanvas.googlecode.com/svn/trunk/ 
+//  svn : r73
+// ------------------------------------------------------------------
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns only support repeat.
+// * Radial gradient are not implemented. The VML version of these look very
+//   different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+//   width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+//   Quirks mode will draw the canvas using border-box. Either change your
+//   doctype to HTML5
+//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+//   or use Box Sizing Behavior from WebFX
+//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Non uniform scaling does not correctly scale strokes.
+// * Optimize. There is always room for speed improvements.
+
+// Only add this code if we do not already have a canvas implementation
+if (!document.createElement('canvas').getContext) {
+
+(function() {
+
+  // alias some functions to make (compiled) code shorter
+  var m = Math;
+  var mr = m.round;
+  var ms = m.sin;
+  var mc = m.cos;
+  var abs = m.abs;
+  var sqrt = m.sqrt;
+
+  // this is used for sub pixel precision
+  var Z = 10;
+  var Z2 = Z / 2;
+
+  var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];
+
+  /**
+   * This funtion is assigned to the <canvas> elements as element.getContext().
+   * @this {HTMLElement}
+   * @return {CanvasRenderingContext2D_}
+   */
+  function getContext() {
+    return this.context_ ||
+        (this.context_ = new CanvasRenderingContext2D_(this));
+  }
+
+  var slice = Array.prototype.slice;
+
+  /**
+   * Binds a function to an object. The returned function will always use the
+   * passed in {@code obj} as {@code this}.
+   *
+   * Example:
+   *
+   *   g = bind(f, obj, a, b)
+   *   g(c, d) // will do f.call(obj, a, b, c, d)
+   *
+   * @param {Function} f The function to bind the object to
+   * @param {Object} obj The object that should act as this when the function
+   *     is called
+   * @param {*} var_args Rest arguments that will be used as the initial
+   *     arguments when the function is called
+   * @return {Function} A new function that has bound this
+   */
+  function bind(f, obj, var_args) {
+    var a = slice.call(arguments, 2);
+    return function() {
+      return f.apply(obj, a.concat(slice.call(arguments)));
+    };
+  }
+
+  function encodeHtmlAttribute(s) {
+    return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
+  }
+
+  function addNamespace(doc, prefix, urn) {
+    if (!doc.namespaces[prefix]) {
+      doc.namespaces.add(prefix, urn, '#default#VML');
+    }
+  }
+
+  function addNamespacesAndStylesheet(doc) {
+    addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');
+    addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');
+
+    // Setup default CSS.  Only add one style sheet per document
+    if (!doc.styleSheets['ex_canvas_']) {
+      var ss = doc.createStyleSheet();
+      ss.owningElement.id = 'ex_canvas_';
+      ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
+          // default size is 300x150 in Gecko and Opera
+          'text-align:left;width:300px;height:150px}';
+    }
+  }
+
+  // Add namespaces and stylesheet at startup.
+  addNamespacesAndStylesheet(document);
+
+  var G_vmlCanvasManager_ = {
+    init: function(opt_doc) {
+      var doc = opt_doc || document;
+      // Create a dummy element so that IE will allow canvas elements to be
+      // recognized.
+      doc.createElement('canvas');
+      doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
+    },
+
+    init_: function(doc) {
+      // find all canvas elements
+      var els = doc.getElementsByTagName('canvas');
+      for (var i = 0; i < els.length; i++) {
+        this.initElement(els[i]);
+      }
+    },
+
+    /**
+     * Public initializes a canvas element so that it can be used as canvas
+     * element from now on. This is called automatically before the page is
+     * loaded but if you are creating elements using createElement you need to
+     * make sure this is called on the element.
+     * @param {HTMLElement} el The canvas element to initialize.
+     * @return {HTMLElement} the element that was created.
+     */
+    initElement: function(el) {
+      if (!el.getContext) {
+        el.getContext = getContext;
+
+        // Add namespaces and stylesheet to document of the element.
+        addNamespacesAndStylesheet(el.ownerDocument);
+
+        // Remove fallback content. There is no way to hide text nodes so we
+        // just remove all childNodes. We could hide all elements and remove
+        // text nodes but who really cares about the fallback content.
+        el.innerHTML = '';
+
+        // do not use inline function because that will leak memory
+        el.attachEvent('onpropertychange', onPropertyChange);
+        el.attachEvent('onresize', onResize);
+
+        var attrs = el.attributes;
+        if (attrs.width && attrs.width.specified) {
+          // TODO: use runtimeStyle and coordsize
+          // el.getContext().setWidth_(attrs.width.nodeValue);
+          el.style.width = attrs.width.nodeValue + 'px';
+        } else {
+          el.width = el.clientWidth;
+        }
+        if (attrs.height && attrs.height.specified) {
+          // TODO: use runtimeStyle and coordsize
+          // el.getContext().setHeight_(attrs.height.nodeValue);
+          el.style.height = attrs.height.nodeValue + 'px';
+        } else {
+          el.height = el.clientHeight;
+        }
+        //el.getContext().setCoordsize_()
+      }
+      return el;
+    },
+
+    // Memory Leaks patch : see http://code.google.com/p/explorercanvas/issues/detail?id=82
+    uninitElement: function(el){
+      if (el.getContext) {
+        var ctx = el.getContext();
+        delete ctx.element_;
+        delete ctx.canvas;
+        el.innerHTML = "";
+        //el.outerHTML = "";
+        el.context_ = null;
+        el.getContext = null;
+        el.detachEvent("onpropertychange", onPropertyChange);
+        el.detachEvent("onresize", onResize);
+      }
+    }
+  };
+
+  function onPropertyChange(e) {
+    var el = e.srcElement;
+
+    switch (e.propertyName) {
+      case 'width':
+        el.getContext().clearRect();
+        el.style.width = el.attributes.width.nodeValue + 'px';
+        // In IE8 this does not trigger onresize.
+        el.firstChild.style.width =  el.clientWidth + 'px';
+        break;
+      case 'height':
+        el.getContext().clearRect();
+        el.style.height = el.attributes.height.nodeValue + 'px';
+        el.firstChild.style.height = el.clientHeight + 'px';
+        break;
+    }
+  }
+
+  function onResize(e) {
+    var el = e.srcElement;
+    if (el.firstChild) {
+      el.firstChild.style.width =  el.clientWidth + 'px';
+      el.firstChild.style.height = el.clientHeight + 'px';
+    }
+  }
+
+  G_vmlCanvasManager_.init();
+
+  // precompute "00" to "FF"
+  var decToHex = [];
+  for (var i = 0; i < 16; i++) {
+    for (var j = 0; j < 16; j++) {
+      decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
+    }
+  }
+
+  function createMatrixIdentity() {
+    return [
+      [1, 0, 0],
+      [0, 1, 0],
+      [0, 0, 1]
+    ];
+  }
+
+  function matrixMultiply(m1, m2) {
+    var result = createMatrixIdentity();
+
+    for (var x = 0; x < 3; x++) {
+      for (var y = 0; y < 3; y++) {
+        var sum = 0;
+
+        for (var z = 0; z < 3; z++) {
+          sum += m1[x][z] * m2[z][y];
+        }
+
+        result[x][y] = sum;
+      }
+    }
+    return result;
+  }
+
+  function copyState(o1, o2) {
+    o2.fillStyle     = o1.fillStyle;
+    o2.lineCap       = o1.lineCap;
+    o2.lineJoin      = o1.lineJoin;
+    o2.lineWidth     = o1.lineWidth;
+    o2.miterLimit    = o1.miterLimit;
+    o2.shadowBlur    = o1.shadowBlur;
+    o2.shadowColor   = o1.shadowColor;
+    o2.shadowOffsetX = o1.shadowOffsetX;
+    o2.shadowOffsetY = o1.shadowOffsetY;
+    o2.strokeStyle   = o1.strokeStyle;
+    o2.globalAlpha   = o1.globalAlpha;
+    o2.font          = o1.font;
+    o2.textAlign     = o1.textAlign;
+    o2.textBaseline  = o1.textBaseline;
+    o2.arcScaleX_    = o1.arcScaleX_;
+    o2.arcScaleY_    = o1.arcScaleY_;
+    o2.lineScale_    = o1.lineScale_;
+  }
+
+  var colorData = {
+    aliceblue: '#F0F8FF',
+    antiquewhite: '#FAEBD7',
+    aquamarine: '#7FFFD4',
+    azure: '#F0FFFF',
+    beige: '#F5F5DC',
+    bisque: '#FFE4C4',
+    black: '#000000',
+    blanchedalmond: '#FFEBCD',
+    blueviolet: '#8A2BE2',
+    brown: '#A52A2A',
+    burlywood: '#DEB887',
+    cadetblue: '#5F9EA0',
+    chartreuse: '#7FFF00',
+    chocolate: '#D2691E',
+    coral: '#FF7F50',
+    cornflowerblue: '#6495ED',
+    cornsilk: '#FFF8DC',
+    crimson: '#DC143C',
+    cyan: '#00FFFF',
+    darkblue: '#00008B',
+    darkcyan: '#008B8B',
+    darkgoldenrod: '#B8860B',
+    darkgray: '#A9A9A9',
+    darkgreen: '#006400',
+    darkgrey: '#A9A9A9',
+    darkkhaki: '#BDB76B',
+    darkmagenta: '#8B008B',
+    darkolivegreen: '#556B2F',
+    darkorange: '#FF8C00',
+    darkorchid: '#9932CC',
+    darkred: '#8B0000',
+    darksalmon: '#E9967A',
+    darkseagreen: '#8FBC8F',
+    darkslateblue: '#483D8B',
+    darkslategray: '#2F4F4F',
+    darkslategrey: '#2F4F4F',
+    darkturquoise: '#00CED1',
+    darkviolet: '#9400D3',
+    deeppink: '#FF1493',
+    deepskyblue: '#00BFFF',
+    dimgray: '#696969',
+    dimgrey: '#696969',
+    dodgerblue: '#1E90FF',
+    firebrick: '#B22222',
+    floralwhite: '#FFFAF0',
+    forestgreen: '#228B22',
+    gainsboro: '#DCDCDC',
+    ghostwhite: '#F8F8FF',
+    gold: '#FFD700',
+    goldenrod: '#DAA520',
+    grey: '#808080',
+    greenyellow: '#ADFF2F',
+    honeydew: '#F0FFF0',
+    hotpink: '#FF69B4',
+    indianred: '#CD5C5C',
+    indigo: '#4B0082',
+    ivory: '#FFFFF0',
+    khaki: '#F0E68C',
+    lavender: '#E6E6FA',
+    lavenderblush: '#FFF0F5',
+    lawngreen: '#7CFC00',
+    lemonchiffon: '#FFFACD',
+    lightblue: '#ADD8E6',
+    lightcoral: '#F08080',
+    lightcyan: '#E0FFFF',
+    lightgoldenrodyellow: '#FAFAD2',
+    lightgreen: '#90EE90',
+    lightgrey: '#D3D3D3',
+    lightpink: '#FFB6C1',
+    lightsalmon: '#FFA07A',
+    lightseagreen: '#20B2AA',
+    lightskyblue: '#87CEFA',
+    lightslategray: '#778899',
+    lightslategrey: '#778899',
+    lightsteelblue: '#B0C4DE',
+    lightyellow: '#FFFFE0',
+    limegreen: '#32CD32',
+    linen: '#FAF0E6',
+    magenta: '#FF00FF',
+    mediumaquamarine: '#66CDAA',
+    mediumblue: '#0000CD',
+    mediumorchid: '#BA55D3',
+    mediumpurple: '#9370DB',
+    mediumseagreen: '#3CB371',
+    mediumslateblue: '#7B68EE',
+    mediumspringgreen: '#00FA9A',
+    mediumturquoise: '#48D1CC',
+    mediumvioletred: '#C71585',
+    midnightblue: '#191970',
+    mintcream: '#F5FFFA',
+    mistyrose: '#FFE4E1',
+    moccasin: '#FFE4B5',
+    navajowhite: '#FFDEAD',
+    oldlace: '#FDF5E6',
+    olivedrab: '#6B8E23',
+    orange: '#FFA500',
+    orangered: '#FF4500',
+    orchid: '#DA70D6',
+    palegoldenrod: '#EEE8AA',
+    palegreen: '#98FB98',
+    paleturquoise: '#AFEEEE',
+    palevioletred: '#DB7093',
+    papayawhip: '#FFEFD5',
+    peachpuff: '#FFDAB9',
+    peru: '#CD853F',
+    pink: '#FFC0CB',
+    plum: '#DDA0DD',
+    powderblue: '#B0E0E6',
+    rosybrown: '#BC8F8F',
+    royalblue: '#4169E1',
+    saddlebrown: '#8B4513',
+    salmon: '#FA8072',
+    sandybrown: '#F4A460',
+    seagreen: '#2E8B57',
+    seashell: '#FFF5EE',
+    sienna: '#A0522D',
+    skyblue: '#87CEEB',
+    slateblue: '#6A5ACD',
+    slategray: '#708090',
+    slategrey: '#708090',
+    snow: '#FFFAFA',
+    springgreen: '#00FF7F',
+    steelblue: '#4682B4',
+    tan: '#D2B48C',
+    thistle: '#D8BFD8',
+    tomato: '#FF6347',
+    turquoise: '#40E0D0',
+    violet: '#EE82EE',
+    wheat: '#F5DEB3',
+    whitesmoke: '#F5F5F5',
+    yellowgreen: '#9ACD32'
+  };
+
+
+  function getRgbHslContent(styleString) {
+    var start = styleString.indexOf('(', 3);
+    var end = styleString.indexOf(')', start + 1);
+    var parts = styleString.substring(start + 1, end).split(',');
+    // add alpha if needed
+    if (parts.length != 4 || styleString.charAt(3) != 'a') {
+      parts[3] = 1;
+    }
+    return parts;
+  }
+
+  function percent(s) {
+    return parseFloat(s) / 100;
+  }
+
+  function clamp(v, min, max) {
+    return Math.min(max, Math.max(min, v));
+  }
+
+  function hslToRgb(parts){
+    var r, g, b, h, s, l;
+    h = parseFloat(parts[0]) / 360 % 360;
+    if (h < 0)
+      h++;
+    s = clamp(percent(parts[1]), 0, 1);
+    l = clamp(percent(parts[2]), 0, 1);
+    if (s == 0) {
+      r = g = b = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hueToRgb(p, q, h + 1 / 3);
+      g = hueToRgb(p, q, h);
+      b = hueToRgb(p, q, h - 1 / 3);
+    }
+
+    return '#' + decToHex[Math.floor(r * 255)] +
+        decToHex[Math.floor(g * 255)] +
+        decToHex[Math.floor(b * 255)];
+  }
+
+  function hueToRgb(m1, m2, h) {
+    if (h < 0)
+      h++;
+    if (h > 1)
+      h--;
+
+    if (6 * h < 1)
+      return m1 + (m2 - m1) * 6 * h;
+    else if (2 * h < 1)
+      return m2;
+    else if (3 * h < 2)
+      return m1 + (m2 - m1) * (2 / 3 - h) * 6;
+    else
+      return m1;
+  }
+
+  var processStyleCache = {};
+
+  function processStyle(styleString) {
+    if (styleString in processStyleCache) {
+      return processStyleCache[styleString];
+    }
+
+    var str, alpha = 1;
+
+    styleString = String(styleString);
+    if (styleString.charAt(0) == '#') {
+      str = styleString;
+    } else if (/^rgb/.test(styleString)) {
+      var parts = getRgbHslContent(styleString);
+      var str = '#', n;
+      for (var i = 0; i < 3; i++) {
+        if (parts[i].indexOf('%') != -1) {
+          n = Math.floor(percent(parts[i]) * 255);
+        } else {
+          n = +parts[i];
+        }
+        str += decToHex[clamp(n, 0, 255)];
+      }
+      alpha = +parts[3];
+    } else if (/^hsl/.test(styleString)) {
+      var parts = getRgbHslContent(styleString);
+      str = hslToRgb(parts);
+      alpha = parts[3];
+    } else {
+      str = colorData[styleString] || styleString;
+    }
+    return processStyleCache[styleString] = {color: str, alpha: alpha};
+  }
+
+  var DEFAULT_STYLE = {
+    style: 'normal',
+    variant: 'normal',
+    weight: 'normal',
+    size: 10,
+    family: 'sans-serif'
+  };
+
+  // Internal text style cache
+  var fontStyleCache = {};
+
+  function processFontStyle(styleString) {
+    if (fontStyleCache[styleString]) {
+      return fontStyleCache[styleString];
+    }
+
+    var el = document.createElement('div');
+    var style = el.style;
+    try {
+      style.font = styleString;
+    } catch (ex) {
+      // Ignore failures to set to invalid font.
+    }
+
+    return fontStyleCache[styleString] = {
+      style: style.fontStyle || DEFAULT_STYLE.style,
+      variant: style.fontVariant || DEFAULT_STYLE.variant,
+      weight: style.fontWeight || DEFAULT_STYLE.weight,
+      size: style.fontSize || DEFAULT_STYLE.size,
+      family: style.fontFamily || DEFAULT_STYLE.family
+    };
+  }
+
+  function getComputedStyle(style, element) {
+    var computedStyle = {};
+
+    for (var p in style) {
+      computedStyle[p] = style[p];
+    }
+
+    // Compute the size
+    var canvasFontSize = parseFloat(element.currentStyle.fontSize),
+        fontSize = parseFloat(style.size);
+
+    if (typeof style.size == 'number') {
+      computedStyle.size = style.size;
+    } else if (style.size.indexOf('px') != -1) {
+      computedStyle.size = fontSize;
+    } else if (style.size.indexOf('em') != -1) {
+      computedStyle.size = canvasFontSize * fontSize;
+    } else if(style.size.indexOf('%') != -1) {
+      computedStyle.size = (canvasFontSize / 100) * fontSize;
+    } else if (style.size.indexOf('pt') != -1) {
+      computedStyle.size = fontSize / .75;
+    } else {
+      computedStyle.size = canvasFontSize;
+    }
+
+    // Different scaling between normal text and VML text. This was found using
+    // trial and error to get the same size as non VML text.
+    computedStyle.size *= 0.981;
+
+    // Fix for VML handling of bare font family names.  Add a '' around font family names.
+    computedStyle.family =  "'" + computedStyle.family.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'";
+
+    return computedStyle;
+  }
+
+  function buildStyle(style) {
+    return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
+        style.size + 'px ' + style.family;
+  }
+
+  var lineCapMap = {
+    'butt': 'flat',
+    'round': 'round'
+  };
+
+  function processLineCap(lineCap) {
+    return lineCapMap[lineCap] || 'square';
+  }
+
+  /**
+   * This class implements CanvasRenderingContext2D interface as described by
+   * the WHATWG.
+   * @param {HTMLElement} canvasElement The element that the 2D context should
+   * be associated with
+   */
+  function CanvasRenderingContext2D_(canvasElement) {
+    this.m_ = createMatrixIdentity();
+
+    this.mStack_ = [];
+    this.aStack_ = [];
+    this.currentPath_ = [];
+
+    // Canvas context properties
+    this.strokeStyle = '#000';
+    this.fillStyle = '#000';
+
+    this.lineWidth = 1;
+    this.lineJoin = 'miter';
+    this.lineCap = 'butt';
+    this.miterLimit = Z * 1;
+    this.globalAlpha = 1;
+    this.font = '10px sans-serif';
+    this.textAlign = 'left';
+    this.textBaseline = 'alphabetic';
+    this.canvas = canvasElement;
+
+    var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +
+        canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';
+    var el = canvasElement.ownerDocument.createElement('div');
+    el.style.cssText = cssText;
+    canvasElement.appendChild(el);
+
+    var overlayEl = el.cloneNode(false);
+    // Use a non transparent background.
+    overlayEl.style.backgroundColor = 'red';
+    overlayEl.style.filter = 'alpha(opacity=0)';
+    canvasElement.appendChild(overlayEl);
+
+    this.element_ = el;
+    this.arcScaleX_ = 1;
+    this.arcScaleY_ = 1;
+    this.lineScale_ = 1;
+  }
+
+  var contextPrototype = CanvasRenderingContext2D_.prototype;
+  contextPrototype.clearRect = function() {
+    if (this.textMeasureEl_) {
+      this.textMeasureEl_.removeNode(true);
+      this.textMeasureEl_ = null;
+    }
+    this.element_.innerHTML = '';
+  };
+
+  contextPrototype.beginPath = function() {
+    // TODO: Branch current matrix so that save/restore has no effect
+    //       as per safari docs.
+    this.currentPath_ = [];
+  };
+
+  contextPrototype.moveTo = function(aX, aY) {
+    var p = getCoords(this, aX, aY);
+    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
+    this.currentX_ = p.x;
+    this.currentY_ = p.y;
+  };
+
+  contextPrototype.lineTo = function(aX, aY) {
+    var p = getCoords(this, aX, aY);
+    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
+
+    this.currentX_ = p.x;
+    this.currentY_ = p.y;
+  };
+
+  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+                                            aCP2x, aCP2y,
+                                            aX, aY) {
+    var p = getCoords(this, aX, aY);
+    var cp1 = getCoords(this, aCP1x, aCP1y);
+    var cp2 = getCoords(this, aCP2x, aCP2y);
+    bezierCurveTo(this, cp1, cp2, p);
+  };
+
+  // Helper function that takes the already fixed cordinates.
+  function bezierCurveTo(self, cp1, cp2, p) {
+    self.currentPath_.push({
+      type: 'bezierCurveTo',
+      cp1x: cp1.x,
+      cp1y: cp1.y,
+      cp2x: cp2.x,
+      cp2y: cp2.y,
+      x: p.x,
+      y: p.y
+    });
+    self.currentX_ = p.x;
+    self.currentY_ = p.y;
+  }
+
+  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+    // the following is lifted almost directly from
+    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
+
+    var cp = getCoords(this, aCPx, aCPy);
+    var p = getCoords(this, aX, aY);
+
+    var cp1 = {
+      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
+      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
+    };
+    var cp2 = {
+      x: cp1.x + (p.x - this.currentX_) / 3.0,
+      y: cp1.y + (p.y - this.currentY_) / 3.0
+    };
+
+    bezierCurveTo(this, cp1, cp2, p);
+  };
+
+  contextPrototype.arc = function(aX, aY, aRadius,
+                                  aStartAngle, aEndAngle, aClockwise) {
+    aRadius *= Z;
+    var arcType = aClockwise ? 'at' : 'wa';
+
+    var xStart = aX + mc(aStartAngle) * aRadius - Z2;
+    var yStart = aY + ms(aStartAngle) * aRadius - Z2;
+
+    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
+    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
+
+    // IE won't render arches drawn counter clockwise if xStart == xEnd.
+    if (xStart == xEnd && !aClockwise) {
+      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+                       // that can be represented in binary
+    }
+
+    var p = getCoords(this, aX, aY);
+    var pStart = getCoords(this, xStart, yStart);
+    var pEnd = getCoords(this, xEnd, yEnd);
+
+    this.currentPath_.push({type: arcType,
+                           x: p.x,
+                           y: p.y,
+                           radius: aRadius,
+                           xStart: pStart.x,
+                           yStart: pStart.y,
+                           xEnd: pEnd.x,
+                           yEnd: pEnd.y});
+
+  };
+
+  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+    this.moveTo(aX, aY);
+    this.lineTo(aX + aWidth, aY);
+    this.lineTo(aX + aWidth, aY + aHeight);
+    this.lineTo(aX, aY + aHeight);
+    this.closePath();
+  };
+
+  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+    var oldPath = this.currentPath_;
+    this.beginPath();
+
+    this.moveTo(aX, aY);
+    this.lineTo(aX + aWidth, aY);
+    this.lineTo(aX + aWidth, aY + aHeight);
+    this.lineTo(aX, aY + aHeight);
+    this.closePath();
+    this.stroke();
+
+    this.currentPath_ = oldPath;
+  };
+
+  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+    var oldPath = this.currentPath_;
+    this.beginPath();
+
+    this.moveTo(aX, aY);
+    this.lineTo(aX + aWidth, aY);
+    this.lineTo(aX + aWidth, aY + aHeight);
+    this.lineTo(aX, aY + aHeight);
+    this.closePath();
+    this.fill();
+
+    this.currentPath_ = oldPath;
+  };
+
+  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+    var gradient = new CanvasGradient_('gradient');
+    gradient.x0_ = aX0;
+    gradient.y0_ = aY0;
+    gradient.x1_ = aX1;
+    gradient.y1_ = aY1;
+    return gradient;
+  };
+
+  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
+                                                   aX1, aY1, aR1) {
+    var gradient = new CanvasGradient_('gradientradial');
+    gradient.x0_ = aX0;
+    gradient.y0_ = aY0;
+    gradient.r0_ = aR0;
+    gradient.x1_ = aX1;
+    gradient.y1_ = aY1;
+    gradient.r1_ = aR1;
+    return gradient;
+  };
+
+  contextPrototype.drawImage = function(image, var_args) {
+    var dx, dy, dw, dh, sx, sy, sw, sh;
+
+    // to find the original width we overide the width and height
+    var oldRuntimeWidth = image.runtimeStyle.width;
+    var oldRuntimeHeight = image.runtimeStyle.height;
+    image.runtimeStyle.width = 'auto';
+    image.runtimeStyle.height = 'auto';
+
+    // get the original size
+    var w = image.width;
+    var h = image.height;
+
+    // and remove overides
+    image.runtimeStyle.width = oldRuntimeWidth;
+    image.runtimeStyle.height = oldRuntimeHeight;
+
+    if (arguments.length == 3) {
+      dx = arguments[1];
+      dy = arguments[2];
+      sx = sy = 0;
+      sw = dw = w;
+      sh = dh = h;
+    } else if (arguments.length == 5) {
+      dx = arguments[1];
+      dy = arguments[2];
+      dw = arguments[3];
+      dh = arguments[4];
+      sx = sy = 0;
+      sw = w;
+      sh = h;
+    } else if (arguments.length == 9) {
+      sx = arguments[1];
+      sy = arguments[2];
+      sw = arguments[3];
+      sh = arguments[4];
+      dx = arguments[5];
+      dy = arguments[6];
+      dw = arguments[7];
+      dh = arguments[8];
+    } else {
+      throw Error('Invalid number of arguments');
+    }
+
+    var d = getCoords(this, dx, dy);
+
+    var w2 = sw / 2;
+    var h2 = sh / 2;
+
+    var vmlStr = [];
+
+    var W = 10;
+    var H = 10;
+
+    // For some reason that I've now forgotten, using divs didn't work
+    vmlStr.push(' <g_vml_:group',
+                ' coordsize="', Z * W, ',', Z * H, '"',
+                ' coordorigin="0,0"' ,
+                ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
+
+    // If filters are necessary (rotation exists), create them
+    // filters are bog-slow, so only create them if abbsolutely necessary
+    // The following check doesn't account for skews (which don't exist
+    // in the canvas spec (yet) anyway.
+
+    if (this.m_[0][0] != 1 || this.m_[0][1] ||
+        this.m_[1][1] != 1 || this.m_[1][0]) {
+      var filter = [];
+
+      // Note the 12/21 reversal
+      filter.push('M11=', this.m_[0][0], ',',
+                  'M12=', this.m_[1][0], ',',
+                  'M21=', this.m_[0][1], ',',
+                  'M22=', this.m_[1][1], ',',
+                  'Dx=', mr(d.x / Z), ',',
+                  'Dy=', mr(d.y / Z), '');
+
+      // Bounding box calculation (need to minimize displayed area so that
+      // filters don't waste time on unused pixels.
+      var max = d;
+      var c2 = getCoords(this, dx + dw, dy);
+      var c3 = getCoords(this, dx, dy + dh);
+      var c4 = getCoords(this, dx + dw, dy + dh);
+
+      max.x = m.max(max.x, c2.x, c3.x, c4.x);
+      max.y = m.max(max.y, c2.y, c3.y, c4.y);
+
+      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
+                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
+                  filter.join(''), ", sizingmethod='clip');");
+
+    } else {
+      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
+    }
+
+    vmlStr.push(' ">' ,
+                '<g_vml_:image src="', image.src, '"',
+                ' style="width:', Z * dw, 'px;',
+                ' height:', Z * dh, 'px"',
+                ' cropleft="', sx / w, '"',
+                ' croptop="', sy / h, '"',
+                ' cropright="', (w - sx - sw) / w, '"',
+                ' cropbottom="', (h - sy - sh) / h, '"',
+                ' />',
+                '</g_vml_:group>');
+
+    this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
+  };
+
+  contextPrototype.stroke = function(aFill) {
+    var lineStr = [];
+    var lineOpen = false;
+
+    var W = 10;
+    var H = 10;
+
+    lineStr.push('<g_vml_:shape',
+                 ' filled="', !!aFill, '"',
+                 ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
+                 ' coordorigin="0,0"',
+                 ' coordsize="', Z * W, ',', Z * H, '"',
+                 ' stroked="', !aFill, '"',
+                 ' path="');
+
+    var newSeq = false;
+    var min = {x: null, y: null};
+    var max = {x: null, y: null};
+
+    for (var i = 0; i < this.currentPath_.length; i++) {
+      var p = this.currentPath_[i];
+      var c;
+
+      switch (p.type) {
+        case 'moveTo':
+          c = p;
+          lineStr.push(' m ', mr(p.x), ',', mr(p.y));
+          break;
+        case 'lineTo':
+          lineStr.push(' l ', mr(p.x), ',', mr(p.y));
+          break;
+        case 'close':
+          lineStr.push(' x ');
+          p = null;
+          break;
+        case 'bezierCurveTo':
+          lineStr.push(' c ',
+                       mr(p.cp1x), ',', mr(p.cp1y), ',',
+                       mr(p.cp2x), ',', mr(p.cp2y), ',',
+                       mr(p.x), ',', mr(p.y));
+          break;
+        case 'at':
+        case 'wa':
+          lineStr.push(' ', p.type, ' ',
+                       mr(p.x - this.arcScaleX_ * p.radius), ',',
+                       mr(p.y - this.arcScaleY_ * p.radius), ' ',
+                       mr(p.x + this.arcScaleX_ * p.radius), ',',
+                       mr(p.y + this.arcScaleY_ * p.radius), ' ',
+                       mr(p.xStart), ',', mr(p.yStart), ' ',
+                       mr(p.xEnd), ',', mr(p.yEnd));
+          break;
+      }
+
+
+      // TODO: Following is broken for curves due to
+      //       move to proper paths.
+
+      // Figure out dimensions so we can do gradient fills
+      // properly
+      if (p) {
+        if (min.x == null || p.x < min.x) {
+          min.x = p.x;
+        }
+        if (max.x == null || p.x > max.x) {
+          max.x = p.x;
+        }
+        if (min.y == null || p.y < min.y) {
+          min.y = p.y;
+        }
+        if (max.y == null || p.y > max.y) {
+          max.y = p.y;
+        }
+      }
+    }
+    lineStr.push(' ">');
+
+    if (!aFill) {
+      appendStroke(this, lineStr);
+    } else {
+      appendFill(this, lineStr, min, max);
+    }
+
+    lineStr.push('</g_vml_:shape>');
+
+    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
+  };
+
+  function appendStroke(ctx, lineStr) {
+    var a = processStyle(ctx.strokeStyle);
+    var color = a.color;
+    var opacity = a.alpha * ctx.globalAlpha;
+    var lineWidth = ctx.lineScale_ * ctx.lineWidth;
+
+    // VML cannot correctly render a line if the width is less than 1px.
+    // In that case, we dilute the color to make the line look thinner.
+    if (lineWidth < 1) {
+      opacity *= lineWidth;
+    }
+
+    lineStr.push(
+      '<g_vml_:stroke',
+      ' opacity="', opacity, '"',
+      ' joinstyle="', ctx.lineJoin, '"',
+      ' miterlimit="', ctx.miterLimit, '"',
+      ' endcap="', processLineCap(ctx.lineCap), '"',
+      ' weight="', lineWidth, 'px"',
+      ' color="', color, '" />'
+    );
+  }
+
+  function appendFill(ctx, lineStr, min, max) {
+    var fillStyle = ctx.fillStyle;
+    var arcScaleX = ctx.arcScaleX_;
+    var arcScaleY = ctx.arcScaleY_;
+    var width = max.x - min.x;
+    var height = max.y - min.y;
+    if (fillStyle instanceof CanvasGradient_) {
+      // TODO: Gradients transformed with the transformation matrix.
+      var angle = 0;
+      var focus = {x: 0, y: 0};
+
+      // additional offset
+      var shift = 0;
+      // scale factor for offset
+      var expansion = 1;
+
+      if (fillStyle.type_ == 'gradient') {
+        var x0 = fillStyle.x0_ / arcScaleX;
+        var y0 = fillStyle.y0_ / arcScaleY;
+        var x1 = fillStyle.x1_ / arcScaleX;
+        var y1 = fillStyle.y1_ / arcScaleY;
+        var p0 = getCoords(ctx, x0, y0);
+        var p1 = getCoords(ctx, x1, y1);
+        var dx = p1.x - p0.x;
+        var dy = p1.y - p0.y;
+        angle = Math.atan2(dx, dy) * 180 / Math.PI;
+
+        // The angle should be a non-negative number.
+        if (angle < 0) {
+          angle += 360;
+        }
+
+        // Very small angles produce an unexpected result because they are
+        // converted to a scientific notation string.
+        if (angle < 1e-6) {
+          angle = 0;
+        }
+      } else {
+        var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);
+        focus = {
+          x: (p0.x - min.x) / width,
+          y: (p0.y - min.y) / height
+        };
+
+        width  /= arcScaleX * Z;
+        height /= arcScaleY * Z;
+        var dimension = m.max(width, height);
+        shift = 2 * fillStyle.r0_ / dimension;
+        expansion = 2 * fillStyle.r1_ / dimension - shift;
+      }
+
+      // We need to sort the color stops in ascending order by offset,
+      // otherwise IE won't interpret it correctly.
+      var stops = fillStyle.colors_;
+      stops.sort(function(cs1, cs2) {
+        return cs1.offset - cs2.offset;
+      });
+
+      var length = stops.length;
+      var color1 = stops[0].color;
+      var color2 = stops[length - 1].color;
+      var opacity1 = stops[0].alpha * ctx.globalAlpha;
+      var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
+
+      var colors = [];
+      for (var i = 0; i < length; i++) {
+        var stop = stops[i];
+        colors.push(stop.offset * expansion + shift + ' ' + stop.color);
+      }
+
+      // When colors attribute is used, the meanings of opacity and o:opacity2
+      // are reversed.
+      lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
+                   ' method="none" focus="100%"',
+                   ' color="', color1, '"',
+                   ' color2="', color2, '"',
+                   ' colors="', colors.join(','), '"',
+                   ' opacity="', opacity2, '"',
+                   ' g_o_:opacity2="', opacity1, '"',
+                   ' angle="', angle, '"',
+                   ' focusposition="', focus.x, ',', focus.y, '" />');
+    } else if (fillStyle instanceof CanvasPattern_) {
+      if (width && height) {
+        var deltaLeft = -min.x;
+        var deltaTop = -min.y;
+        lineStr.push('<g_vml_:fill',
+                     ' position="',
+                     deltaLeft / width * arcScaleX * arcScaleX, ',',
+                     deltaTop / height * arcScaleY * arcScaleY, '"',
+                     ' type="tile"',
+                     // TODO: Figure out the correct size to fit the scale.
+                     //' size="', w, 'px ', h, 'px"',
+                     ' src="', fillStyle.src_, '" />');
+       }
+    } else {
+      var a = processStyle(ctx.fillStyle);
+      var color = a.color;
+      var opacity = a.alpha * ctx.globalAlpha;
+      lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
+                   '" />');
+    }
+  }
+
+  contextPrototype.fill = function() {
+    this.stroke(true);
+  };
+
+  contextPrototype.closePath = function() {
+    this.currentPath_.push({type: 'close'});
+  };
+
+  function getCoords(ctx, aX, aY) {
+    var m = ctx.m_;
+    return {
+      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
+      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
+    };
+  };
+
+  contextPrototype.save = function() {
+    var o = {};
+    copyState(this, o);
+    this.aStack_.push(o);
+    this.mStack_.push(this.m_);
+    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+  };
+
+  contextPrototype.restore = function() {
+    if (this.aStack_.length) {
+      copyState(this.aStack_.pop(), this);
+      this.m_ = this.mStack_.pop();
+    }
+  };
+
+  function matrixIsFinite(m) {
+    return isFinite(m[0][0]) && isFinite(m[0][1]) &&
+        isFinite(m[1][0]) && isFinite(m[1][1]) &&
+        isFinite(m[2][0]) && isFinite(m[2][1]);
+  }
+
+  function setM(ctx, m, updateLineScale) {
+    if (!matrixIsFinite(m)) {
+      return;
+    }
+    ctx.m_ = m;
+
+    if (updateLineScale) {
+      // Get the line scale.
+      // Determinant of this.m_ means how much the area is enlarged by the
+      // transformation. So its square root can be used as a scale factor
+      // for width.
+      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+      ctx.lineScale_ = sqrt(abs(det));
+    }
+  }
+
+  contextPrototype.translate = function(aX, aY) {
+    var m1 = [
+      [1,  0,  0],
+      [0,  1,  0],
+      [aX, aY, 1]
+    ];
+
+    setM(this, matrixMultiply(m1, this.m_), false);
+  };
+
+  contextPrototype.rotate = function(aRot) {
+    var c = mc(aRot);
+    var s = ms(aRot);
+
+    var m1 = [
+      [c,  s, 0],
+      [-s, c, 0],
+      [0,  0, 1]
+    ];
+
+    setM(this, matrixMultiply(m1, this.m_), false);
+  };
+
+  contextPrototype.scale = function(aX, aY) {
+    this.arcScaleX_ *= aX;
+    this.arcScaleY_ *= aY;
+    var m1 = [
+      [aX, 0,  0],
+      [0,  aY, 0],
+      [0,  0,  1]
+    ];
+
+    setM(this, matrixMultiply(m1, this.m_), true);
+  };
+
+  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
+    var m1 = [
+      [m11, m12, 0],
+      [m21, m22, 0],
+      [dx,  dy,  1]
+    ];
+
+    setM(this, matrixMultiply(m1, this.m_), true);
+  };
+
+  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
+    var m = [
+      [m11, m12, 0],
+      [m21, m22, 0],
+      [dx,  dy,  1]
+    ];
+
+    setM(this, m, true);
+  };
+
+  /**
+   * The text drawing function.
+   * The maxWidth argument isn't taken in account, since no browser supports
+   * it yet.
+   */
+  contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
+    var m = this.m_,
+        delta = 1000,
+        left = 0,
+        right = delta,
+        offset = {x: 0, y: 0},
+        lineStr = [];
+
+    var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_);
+
+    var fontStyleString = buildStyle(fontStyle);
+
+    var elementStyle = this.element_.currentStyle;
+    var textAlign = this.textAlign.toLowerCase();
+    switch (textAlign) {
+      case 'left':
+      case 'center':
+      case 'right':
+        break;
+      case 'end':
+        textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
+        break;
+      case 'start':
+        textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
+        break;
+      default:
+        textAlign = 'left';
+    }
+
+    // 1.75 is an arbitrary number, as there is no info about the text baseline
+    switch (this.textBaseline) {
+      case 'hanging':
+      case 'top':
+        offset.y = fontStyle.size / 1.75;
+        break;
+      case 'middle':
+        break;
+      default:
+      case null:
+      case 'alphabetic':
+      case 'ideographic':
+      case 'bottom':
+        offset.y = -fontStyle.size / 2.25;
+        break;
+    }
+
+    switch(textAlign) {
+      case 'right':
+        left = delta;
+        right = 0.05;
+        break;
+      case 'center':
+        left = right = delta / 2;
+        break;
+    }
+
+    var d = getCoords(this, x + offset.x, y + offset.y);
+
+    lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
+                 ' coordsize="100 100" coordorigin="0 0"',
+                 ' filled="', !stroke, '" stroked="', !!stroke,
+                 '" style="position:absolute;width:1px;height:1px;">');
+
+    if (stroke) {
+      appendStroke(this, lineStr);
+    } else {
+      // TODO: Fix the min and max params.
+      appendFill(this, lineStr, {x: -left, y: 0},
+                 {x: right, y: fontStyle.size});
+    }
+
+    var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
+                m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
+
+    var skewOffset = mr(d.x / Z + 1 - m[0][0]) + ',' + mr(d.y / Z - 2 * m[1][0]);
+
+
+    lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
+                 ' offset="', skewOffset, '" origin="', left ,' 0" />',
+                 '<g_vml_:path textpathok="true" />',
+                 '<g_vml_:textpath on="true" string="',
+                 encodeHtmlAttribute(text),
+                 '" style="v-text-align:', textAlign,
+                 ';font:', encodeHtmlAttribute(fontStyleString),
+                 '" /></g_vml_:line>');
+
+    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
+  };
+
+  contextPrototype.fillText = function(text, x, y, maxWidth) {
+    this.drawText_(text, x, y, maxWidth, false);
+  };
+
+  contextPrototype.strokeText = function(text, x, y, maxWidth) {
+    this.drawText_(text, x, y, maxWidth, true);
+  };
+
+  contextPrototype.measureText = function(text) {
+    if (!this.textMeasureEl_) {
+      var s = '<span style="position:absolute;' +
+          'top:-20000px;left:0;padding:0;margin:0;border:none;' +
+          'white-space:pre;"></span>';
+      this.element_.insertAdjacentHTML('beforeEnd', s);
+      this.textMeasureEl_ = this.element_.lastChild;
+    }
+    var doc = this.element_.ownerDocument;
+    this.textMeasureEl_.innerHTML = '';
+    this.textMeasureEl_.style.font = this.font;
+    // Don't use innerHTML or innerText because they allow markup/whitespace.
+    this.textMeasureEl_.appendChild(doc.createTextNode(text));
+    return {width: this.textMeasureEl_.offsetWidth};
+  };
+
+  /******** STUBS ********/
+  contextPrototype.clip = function() {
+    // TODO: Implement
+  };
+
+  contextPrototype.arcTo = function() {
+    // TODO: Implement
+  };
+
+  contextPrototype.createPattern = function(image, repetition) {
+    return new CanvasPattern_(image, repetition);
+  };
+
+  // Gradient / Pattern Stubs
+  function CanvasGradient_(aType) {
+    this.type_ = aType;
+    this.x0_ = 0;
+    this.y0_ = 0;
+    this.r0_ = 0;
+    this.x1_ = 0;
+    this.y1_ = 0;
+    this.r1_ = 0;
+    this.colors_ = [];
+  }
+
+  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+    aColor = processStyle(aColor);
+    this.colors_.push({offset: aOffset,
+                       color: aColor.color,
+                       alpha: aColor.alpha});
+  };
+
+  function CanvasPattern_(image, repetition) {
+    assertImageIsValid(image);
+    switch (repetition) {
+      case 'repeat':
+      case null:
+      case '':
+        this.repetition_ = 'repeat';
+        break;
+      case 'repeat-x':
+      case 'repeat-y':
+      case 'no-repeat':
+        this.repetition_ = repetition;
+        break;
+      default:
+        throwException('SYNTAX_ERR');
+    }
+
+    this.src_ = image.src;
+    this.width_ = image.width;
+    this.height_ = image.height;
+  }
+
+  function throwException(s) {
+    throw new DOMException_(s);
+  }
+
+  function assertImageIsValid(img) {
+    if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
+      throwException('TYPE_MISMATCH_ERR');
+    }
+    if (img.readyState != 'complete') {
+      throwException('INVALID_STATE_ERR');
+    }
+  }
+
+  function DOMException_(s) {
+    this.code = this[s];
+    this.message = s +': DOM Exception ' + this.code;
+  }
+  var p = DOMException_.prototype = new Error;
+  p.INDEX_SIZE_ERR = 1;
+  p.DOMSTRING_SIZE_ERR = 2;
+  p.HIERARCHY_REQUEST_ERR = 3;
+  p.WRONG_DOCUMENT_ERR = 4;
+  p.INVALID_CHARACTER_ERR = 5;
+  p.NO_DATA_ALLOWED_ERR = 6;
+  p.NO_MODIFICATION_ALLOWED_ERR = 7;
+  p.NOT_FOUND_ERR = 8;
+  p.NOT_SUPPORTED_ERR = 9;
+  p.INUSE_ATTRIBUTE_ERR = 10;
+  p.INVALID_STATE_ERR = 11;
+  p.SYNTAX_ERR = 12;
+  p.INVALID_MODIFICATION_ERR = 13;
+  p.NAMESPACE_ERR = 14;
+  p.INVALID_ACCESS_ERR = 15;
+  p.VALIDATION_ERR = 16;
+  p.TYPE_MISMATCH_ERR = 17;
+
+  // set up externs
+  G_vmlCanvasManager = G_vmlCanvasManager_;
+  CanvasRenderingContext2D = CanvasRenderingContext2D_;
+  CanvasGradient = CanvasGradient_;
+  CanvasPattern = CanvasPattern_;
+  DOMException = DOMException_;
+  G_vmlCanvasManager._version = 888;
+})();
+
+} // if
diff --git a/src/main/resources/META-INF/resources/designer/lib/excanvas.min.js b/src/main/resources/META-INF/resources/designer/lib/excanvas.min.js
new file mode 100644 (file)
index 0000000..e699a26
--- /dev/null
@@ -0,0 +1,3 @@
+/* jqPlot @VERSION | (c) 2009-2013 Chris Leonello | jplot.com
+   jsDate | (c) 2010-2013 Chris Leonello
+ */if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=y;R(j.ownerDocument);j.innerHTML="";j.attachEvent("onpropertychange",x);j.attachEvent("onresize",W);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j},uninitElement:function(j){if(j.getContext){var i=j.getContext();delete i.element_;delete i.canvas;j.innerHTML="";j.context_=null;j.getContext=null;j.detachEvent("onpropertychange",x);j.detachEvent("onresize",W)}}};function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.getContext().clearRect();i.style.width=i.attributes.width.nodeValue+"px";i.firstChild.style.width=i.clientWidth+"px";break;case"height":i.getContext().clearRect();i.style.height=i.attributes.height.nodeValue+"px";i.firstChild.style.height=i.clientHeight+"px";break}}function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}e.init();var k=[];for(var ae=0;ae<16;ae++){for(var ad=0;ad<16;ad++){k[ae*16+ad]=ae.toString(16)+ad.toString(16)}}function B(){return[[1,0,0],[0,1,0],[0,0,1]]}function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){var Z=0;for(var ag=0;ag<3;ag++){Z+=p[i][ag]*m[ag][ah]}j[i][ah]=Z}}return j}function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.font=j.font;i.textAlign=j.textAlign;i.textBaseline=j.textBaseline;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}var b={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.substring(p+1,i).split(",");if(m.length!=4||j.charAt(3)!="a"){m[3]=1}return m}function c(i){return parseFloat(i)/100}function r(j,m,i){return Math.min(i,Math.max(m,j))}function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0){ah++}ak=r(c(ag[1]),0,1);Z=r(c(ag[2]),0,1);if(ak==0){i=ai=aj=Z}else{var j=Z<0.5?Z*(1+ak):Z+ak-Z*ak;var m=2*Z-j;i=a(m,j,ah+1/3);ai=a(m,j,ah);aj=a(m,j,ah-1/3)}return"#"+k[Math.floor(i*255)]+k[Math.floor(ai*255)]+k[Math.floor(aj*255)]}function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;i.family="'"+i.family.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'";return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" <g_vml_:group",' coordsize="',d*i,",",d*ag,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",ag,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var Z=[];Z.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",n(az.x/d),",","Dy=",n(az.y/d),"");var av=az;var au=V(this,aj+al,ah);var ar=V(this,aj,ah+ay);var an=V(this,aj+al,ah+ay);av.x=ab.max(av.x,au.x,ar.x,an.x);av.y=ab.max(av.y,au.y,ar.y,an.y);ax.push("padding:0 ",n(av.x/d),"px ",n(av.y/d),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",Z.join(""),", sizingmethod='clip');")}else{ax.push("top:",n(az.y/d),"px;left:",n(az.x/d),"px;")}ax.push(' ">','<g_vml_:image src="',aq.src,'"',' style="width:',d*al,"px;"," height:",d*ay,'px"',' cropleft="',ao/ai,'"',' croptop="',am/aw,'"',' cropright="',(ai-ao-at)/ai,'"',' cropbottom="',(aw-am-aA)/aw,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(al){var aj=[];var Z=false;var m=10;var am=10;aj.push("<g_vml_:shape",' filled="',!!al,'"',' style="position:absolute;width:',m,"px;height:",am,'px;"',' coordorigin="0,0"',' coordsize="',d*m,",",d*am,'"',' stroked="',!al,'"',' path="');var an=false;var ag={x:null,y:null};var ak={x:null,y:null};for(var ah=0;ah<this.currentPath_.length;ah++){var j=this.currentPath_[ah];var ai;switch(j.type){case"moveTo":ai=j;aj.push(" m ",n(j.x),",",n(j.y));break;case"lineTo":aj.push(" l ",n(j.x),",",n(j.y));break;case"close":aj.push(" x ");j=null;break;case"bezierCurveTo":aj.push(" c ",n(j.cp1x),",",n(j.cp1y),",",n(j.cp2x),",",n(j.cp2y),",",n(j.x),",",n(j.y));break;case"at":case"wa":aj.push(" ",j.type," ",n(j.x-this.arcScaleX_*j.radius),",",n(j.y-this.arcScaleY_*j.radius)," ",n(j.x+this.arcScaleX_*j.radius),",",n(j.y+this.arcScaleY_*j.radius)," ",n(j.xStart),",",n(j.yStart)," ",n(j.xEnd),",",n(j.yEnd));break}if(j){if(ag.x==null||j.x<ag.x){ag.x=j.x}if(ak.x==null||j.x>ak.x){ak.x=j.x}if(ag.y==null||j.y<ag.y){ag.y=j.y}if(ak.y==null||j.y>ak.y){ak.y=j.y}}}aj.push(' ">');if(!al){w(this,aj)}else{G(this,aj,ag,ak)}aj.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",aj.join(""))};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("<g_vml_:stroke",' opacity="',Z,'"',' joinstyle="',m.lineJoin,'"',' miterlimit="',m.miterLimit,'"',' endcap="',S(m.lineCap),'"',' weight="',i,'px"',' color="',p,'" />')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH<ap;aH++){var ao=av[aH];aE.push(ao.offset*am+ax+" "+ao.color)}ai.push('<g_vml_:fill type="',aj.type_,'"',' method="none" focus="100%"',' color="',au,'"',' color2="',at,'"',' colors="',aE.join(","),'"',' opacity="',ay,'"',' g_o_:opacity2="',az,'"',' angle="',an,'"',' focusposition="',aF.x,",",aF.y,'" />')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("<g_vml_:fill",' position="',ah/j*aB*aB,",",aC/p*aA*aA,'"',' type="tile"',' src="',aj.src_,'" />')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('<g_vml_:fill color="',aw,'" opacity="',aG,'" />')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('<g_vml_:line from="',-j,' 0" to="',ar,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!ai,'" stroked="',!!ai,'" style="position:absolute;width:1px;height:1px;">');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d+1-ao[0][0])+","+n(aq.y/d-2*ao[1][0]);ag.push('<g_vml_:skew on="t" matrix="',an,'" ',' offset="',al,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',af(am),'" style="v-text-align:',Z,";font:",af(p),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P;G_vmlCanvasManager._version=888})()};
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.js b/src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.js
new file mode 100644 (file)
index 0000000..d2ff279
--- /dev/null
@@ -0,0 +1,1575 @@
+/*
+ * Flexigrid for jQuery -  v1.1
+ *
+ * Copyright (c) 2008 Paulo P. Marinas (code.google.com/p/flexigrid/)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ */
+(function ($) {
+       /*
+        * jQuery 1.9 support. browser object has been removed in 1.9 
+        */
+       var browser = $.browser
+       
+       if (!browser) {
+               function uaMatch( ua ) {
+                       ua = ua.toLowerCase();
+
+                       var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+                               /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+                               /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+                               /(msie) ([\w.]+)/.exec( ua ) ||
+                               ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+                               [];
+
+                       return {
+                               browser: match[ 1 ] || "",
+                               version: match[ 2 ] || "0"
+                       };
+               };
+
+               var matched = uaMatch( navigator.userAgent );
+               browser = {};
+
+               if ( matched.browser ) {
+                       browser[ matched.browser ] = true;
+                       browser.version = matched.version;
+               }
+
+               // Chrome is Webkit, but Webkit is also Safari.
+               if ( browser.chrome ) {
+                       browser.webkit = true;
+               } else if ( browser.webkit ) {
+                       browser.safari = true;
+               }
+       }
+       
+    /*!
+     * START code from jQuery UI
+     *
+     * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+     * Dual licensed under the MIT or GPL Version 2 licenses.
+     * http://jquery.org/license
+     *
+     * http://docs.jquery.com/UI
+     */
+     
+    if(typeof $.support.selectstart != 'function') {
+        $.support.selectstart = "onselectstart" in document.createElement("div");
+    }
+    
+    if(typeof $.fn.disableSelection != 'function') {
+        $.fn.disableSelection = function() {
+            return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+                ".ui-disableSelection", function( event ) {
+                event.preventDefault();
+            });
+        };
+    }
+    
+    /* END code from jQuery UI */
+    
+       $.addFlex = function (t, p) {
+               if (t.grid) return false; //return if already exist
+               p = $.extend({ //apply default properties
+                       height: 200, //default height
+                       width: 'auto', //auto width
+                       striped: true, //apply odd even stripes
+                       novstripe: false,
+                       minwidth: 30, //min width of columns
+                       minheight: 80, //min height of columns
+                       resizable: true, //allow table resizing
+                       url: false, //URL if using data from AJAX
+                       method: 'POST', //data sending method
+                       dataType: 'xml', //type of data for AJAX, either xml or json
+                       errormsg: 'Connection Error',
+                       usepager: false,
+                       nowrap: true,
+                       page: 1, //current page
+                       total: 1, //total pages
+                       useRp: true, //use the results per page select box
+                       rp: 15, //results per page
+                       rpOptions: [10, 15, 20, 30, 50], //allowed per-page values
+                       title: false,
+                       idProperty: 'id',
+                       pagestat: 'Displaying {from} to {to} of {total} items',
+                       pagetext: 'Page',
+                       outof: 'of',
+                       findtext: 'Find',
+                       params: [], //allow optional parameters to be passed around
+                       procmsg: 'Processing, please wait ...',
+                       query: '',
+                       qtype: '',
+                       nomsg: 'No items',
+                       minColToggle: 1, //minimum allowed column to be hidden
+                       showToggleBtn: true, //show or hide column toggle popup
+                       hideOnSubmit: true,
+                       autoload: true,
+                       blockOpacity: 0.5,
+                       preProcess: false,
+                       addTitleToCell: false, // add a title attr to cells with truncated contents
+                       dblClickResize: false, //auto resize column by double clicking
+                       onDragCol: false,
+                       onToggleCol: false,
+                       onChangeSort: false,
+                       onDoubleClick: false,
+                       onSuccess: false,
+                       onError: false,
+                       onSubmit: false, //using a custom populate function
+            __mw: { //extendable middleware function holding object
+                datacol: function(p, col, val) { //middleware for formatting data columns
+                    var _col = (typeof p.datacol[col] == 'function') ? p.datacol[col](val) : val; //format column using function
+                    if(typeof p.datacol['*'] == 'function') { //if wildcard function exists
+                        return p.datacol['*'](_col); //run wildcard function
+                    } else {
+                        return _col; //return column without wildcard
+                    }
+                }
+            },
+            getGridClass: function(g) { //get the grid class, always returns g
+                return g;
+            },
+            datacol: {}, //datacol middleware object 'colkey': function(colval) {}
+            colResize: true, //from: http://stackoverflow.com/a/10615589
+            colMove: true
+               }, p);
+               $(t).show() //show if hidden
+                       .attr({
+                               cellPadding: 0,
+                               cellSpacing: 0,
+                               border: 0
+                       }) //remove padding and spacing
+                       .removeAttr('width'); //remove width properties
+               //create grid class
+               var g = {
+                       hset: {},
+                       rePosDrag: function () {
+                               var cdleft = 0 - this.hDiv.scrollLeft;
+                               if (this.hDiv.scrollLeft > 0) cdleft -= Math.floor(p.cgwidth / 2);
+                               $(g.cDrag).css({
+                                       top: g.hDiv.offsetTop + 1
+                               });
+                               var cdpad = this.cdpad;
+                               var cdcounter=0;
+                               $('div', g.cDrag).hide();
+                               $('thead tr:first th:visible', this.hDiv).each(function () {
+                                       var n = $('thead tr:first th:visible', g.hDiv).index(this);
+                                       var cdpos = parseInt($('div', this).width());
+                                       if (cdleft == 0) cdleft -= Math.floor(p.cgwidth / 2);
+                                       cdpos = cdpos + cdleft + cdpad;
+                                       if (isNaN(cdpos)) {
+                                               cdpos = 0;
+                                       }
+                                       $('div:eq(' + n + ')', g.cDrag).css({
+                                               'left': (!(browser.mozilla) ? cdpos - cdcounter : cdpos) + 'px'
+                                       }).show();
+                                       cdleft = cdpos;
+                                       cdcounter++;
+                               });
+                       },
+                       fixHeight: function (newH) {
+                               newH = false;
+                               if (!newH) newH = $(g.bDiv).height();
+                               var hdHeight = $(this.hDiv).height();
+                               $('div', this.cDrag).each(
+                                       function () {
+                                               $(this).height(newH + hdHeight);
+                                       }
+                               );
+                               var nd = parseInt($(g.nDiv).height(), 10);
+                               if (nd > newH) $(g.nDiv).height(newH).width(200);
+                               else $(g.nDiv).height('auto').width('auto');
+                               $(g.block).css({
+                                       height: newH,
+                                       marginBottom: (newH * -1)
+                               });
+                               var hrH = g.bDiv.offsetTop + newH;
+                               if (p.height != 'auto' && p.resizable) hrH = g.vDiv.offsetTop;
+                               $(g.rDiv).css({
+                                       height: hrH
+                               });
+                       },
+                       dragStart: function (dragtype, e, obj) { //default drag function start
+                if (dragtype == 'colresize' && p.colResize === true) {//column resize
+                                       $(g.nDiv).hide();
+                                       $(g.nBtn).hide();
+                                       var n = $('div', this.cDrag).index(obj);
+                                       var ow = $('th:visible div:eq(' + n + ')', this.hDiv).width();
+                                       $(obj).addClass('dragging').siblings().hide();
+                                       $(obj).prev().addClass('dragging').show();
+                                       this.colresize = {
+                                               startX: e.pageX,
+                                               ol: parseInt(obj.style.left, 10),
+                                               ow: ow,
+                                               n: n
+                                       };
+                                       $('body').css('cursor', 'col-resize');
+                               } else if (dragtype == 'vresize') {//table resize
+                                       var hgo = false;
+                                       $('body').css('cursor', 'row-resize');
+                                       if (obj) {
+                                               hgo = true;
+                                               $('body').css('cursor', 'col-resize');
+                                       }
+                                       this.vresize = {
+                                               h: p.height,
+                                               sy: e.pageY,
+                                               w: p.width,
+                                               sx: e.pageX,
+                                               hgo: hgo
+                                       };
+                               } else if (dragtype == 'colMove') {//column header drag
+                    $(e.target).disableSelection(); //disable selecting the column header
+                    if((p.colMove === true)) {
+                        $(g.nDiv).hide();
+                        $(g.nBtn).hide();
+                        this.hset = $(this.hDiv).offset();
+                        this.hset.right = this.hset.left + $('table', this.hDiv).width();
+                        this.hset.bottom = this.hset.top + $('table', this.hDiv).height();
+                        this.dcol = obj;
+                        this.dcoln = $('th', this.hDiv).index(obj);
+                        this.colCopy = document.createElement("div");
+                        this.colCopy.className = "colCopy";
+                        this.colCopy.innerHTML = obj.innerHTML;
+                        if (browser.msie) {
+                            this.colCopy.className = "colCopy ie";
+                        }
+                        $(this.colCopy).css({
+                            position: 'absolute',
+                            'float': 'left',
+                            display: 'none',
+                            textAlign: obj.align
+                        });
+                        $('body').append(this.colCopy);
+                        $(this.cDrag).hide();
+                    }
+                               }
+                               $('body').noSelect();
+                       },
+                       dragMove: function (e) {
+                               if (this.colresize) {//column resize
+                                       var n = this.colresize.n;
+                                       var diff = e.pageX - this.colresize.startX;
+                                       var nleft = this.colresize.ol + diff;
+                                       var nw = this.colresize.ow + diff;
+                                       if (nw > p.minwidth) {
+                                               $('div:eq(' + n + ')', this.cDrag).css('left', nleft);
+                                               this.colresize.nw = nw;
+                                       }
+                               } else if (this.vresize) {//table resize
+                                       var v = this.vresize;
+                                       var y = e.pageY;
+                                       var diff = y - v.sy;
+                                       if (!p.defwidth) p.defwidth = p.width;
+                                       if (p.width != 'auto' && !p.nohresize && v.hgo) {
+                                               var x = e.pageX;
+                                               var xdiff = x - v.sx;
+                                               var newW = v.w + xdiff;
+                                               if (newW > p.defwidth) {
+                                                       this.gDiv.style.width = newW + 'px';
+                                                       p.width = newW;
+                                               }
+                                       }
+                                       var newH = v.h + diff;
+                                       if ((newH > p.minheight || p.height < p.minheight) && !v.hgo) {
+                                               this.bDiv.style.height = newH + 'px';
+                                               p.height = newH;
+                                               this.fixHeight(newH);
+                                       }
+                                       v = null;
+                               } else if (this.colCopy) {
+                                       $(this.dcol).addClass('thMove').removeClass('thOver');
+                                       if (e.pageX > this.hset.right || e.pageX < this.hset.left || e.pageY > this.hset.bottom || e.pageY < this.hset.top) {
+                                               //this.dragEnd();
+                                               $('body').css('cursor', 'move');
+                                       } else {
+                                               $('body').css('cursor', 'pointer');
+                                       }
+                                       $(this.colCopy).css({
+                                               top: e.pageY + 10,
+                                               left: e.pageX + 20,
+                                               display: 'block'
+                                       });
+                               }
+                       },
+                       dragEnd: function () {
+                               if (this.colresize) {
+                                       var n = this.colresize.n;
+                                       var nw = this.colresize.nw;
+                                       $('th:visible div:eq(' + n + ')', this.hDiv).css('width', nw);
+                                       $('tr', this.bDiv).each(
+                                               function () {
+                                                       var $tdDiv = $('td:visible div:eq(' + n + ')', this);
+                                                       $tdDiv.css('width', nw);
+                                                       g.addTitleToCell($tdDiv);
+                                               }
+                                       );
+                                       this.hDiv.scrollLeft = this.bDiv.scrollLeft;
+                                       $('div:eq(' + n + ')', this.cDrag).siblings().show();
+                                       $('.dragging', this.cDrag).removeClass('dragging');
+                                       this.rePosDrag();
+                                       this.fixHeight();
+                                       this.colresize = false;
+                                       if ($.cookies) {
+                                               var name = p.colModel[n].name;          // Store the widths in the cookies
+                                               $.cookie('flexiwidths/'+name, nw);
+                                       }
+                               } else if (this.vresize) {
+                                       this.vresize = false;
+                               } else if (this.colCopy) {
+                                       $(this.colCopy).remove();
+                                       if (this.dcolt !== null) {
+                                               if (this.dcoln > this.dcolt) $('th:eq(' + this.dcolt + ')', this.hDiv).before(this.dcol);
+                                               else $('th:eq(' + this.dcolt + ')', this.hDiv).after(this.dcol);
+                                               this.switchCol(this.dcoln, this.dcolt);
+                                               $(this.cdropleft).remove();
+                                               $(this.cdropright).remove();
+                                               this.rePosDrag();
+                                               if (p.onDragCol) {
+                                                       p.onDragCol(this.dcoln, this.dcolt);
+                                               }
+                                       }
+                                       this.dcol = null;
+                                       this.hset = null;
+                                       this.dcoln = null;
+                                       this.dcolt = null;
+                                       this.colCopy = null;
+                                       $('.thMove', this.hDiv).removeClass('thMove');
+                                       $(this.cDrag).show();
+                               }
+                               $('body').css('cursor', 'default');
+                               $('body').noSelect(false);
+                       },
+                       toggleCol: function (cid, visible) {
+                               var ncol = $("th[axis='col" + cid + "']", this.hDiv)[0];
+                               var n = $('thead th', g.hDiv).index(ncol);
+                               var cb = $('input[value=' + cid + ']', g.nDiv)[0];
+                               if (visible == null) {
+                                       visible = ncol.hidden;
+                               }
+                               if ($('input:checked', g.nDiv).length < p.minColToggle && !visible) {
+                                       return false;
+                               }
+                               if (visible) {
+                                       ncol.hidden = false;
+                                       $(ncol).show();
+                                       cb.checked = true;
+                               } else {
+                                       ncol.hidden = true;
+                                       $(ncol).hide();
+                                       cb.checked = false;
+                               }
+                               $('tbody tr', t).each(
+                                       function () {
+                                               if (visible) {
+                                                       $('td:eq(' + n + ')', this).show();
+                                               } else {
+                                                       $('td:eq(' + n + ')', this).hide();
+                                               }
+                                       }
+                               );
+                               this.rePosDrag();
+                               if (p.onToggleCol) {
+                                       p.onToggleCol(cid, visible);
+                               }
+                               return visible;
+                       },
+                       switchCol: function (cdrag, cdrop) { //switch columns
+                               $('tbody tr', t).each(
+                                       function () {
+                                               if (cdrag > cdrop) $('td:eq(' + cdrop + ')', this).before($('td:eq(' + cdrag + ')', this));
+                                               else $('td:eq(' + cdrop + ')', this).after($('td:eq(' + cdrag + ')', this));
+                                       }
+                               );
+                               //switch order in nDiv
+                               if (cdrag > cdrop) {
+                                       $('tr:eq(' + cdrop + ')', this.nDiv).before($('tr:eq(' + cdrag + ')', this.nDiv));
+                               } else {
+                                       $('tr:eq(' + cdrop + ')', this.nDiv).after($('tr:eq(' + cdrag + ')', this.nDiv));
+                               }
+                               if (browser.msie && browser.version < 7.0) {
+                                       $('tr:eq(' + cdrop + ') input', this.nDiv)[0].checked = true;
+                               }
+                               this.hDiv.scrollLeft = this.bDiv.scrollLeft;
+                       },
+                       scroll: function () {
+                               this.hDiv.scrollLeft = this.bDiv.scrollLeft;
+                               this.rePosDrag();
+                       },
+                       addData: function (data) { //parse data
+                               if (p.dataType == 'json') {
+                                       data = $.extend({rows: [], page: 0, total: 0}, data);
+                               }
+                               if (p.preProcess) {
+                                       data = p.preProcess(data);
+                               }
+                               $('.pReload', this.pDiv).removeClass('loading');
+                               this.loading = false;
+                               if (!data) {
+                                       $('.pPageStat', this.pDiv).html(p.errormsg);
+                    if (p.onSuccess) p.onSuccess(this);
+                                       return false;
+                               }
+                               if (p.dataType == 'xml') {
+                                       p.total = +$('rows total', data).text();
+                               } else {
+                                       p.total = data.total;
+                               }
+                               if (p.total === 0) {
+                                       $('tr, a, td, div', t).unbind();
+                                       $(t).empty();
+                                       p.pages = 1;
+                                       p.page = 1;
+                                       this.buildpager();
+                                       $('.pPageStat', this.pDiv).html(p.nomsg);
+                    if (p.onSuccess) p.onSuccess(this);
+                                       return false;
+                               }
+                               p.pages = Math.ceil(p.total / p.rp);
+                               if (p.dataType == 'xml') {
+                                       p.page = +$('rows page', data).text();
+                               } else {
+                                       p.page = data.page;
+                               }
+                               this.buildpager();
+                               //build new body
+                               var tbody = document.createElement('tbody');
+                               if (p.dataType == 'json') {
+                                       $.each(data.rows, function (i, row) {
+                                               var tr = document.createElement('tr');
+                                               var jtr = $(tr);
+                                               if (row.name) tr.name = row.name;
+                                               if (row.color) {
+                                                       jtr.css('background',row.color);
+                                               } else {
+                                                       if (i % 2 && p.striped) tr.className = 'erow';
+                                               }
+                                               if (row[p.idProperty]) {
+                                                       tr.id = 'row' + row[p.idProperty];
+                                                       jtr.attr('data-id', row[p.idProperty]);
+                                               }
+                                               $('thead tr:first th', g.hDiv).each( //add cell
+                                                       function () {
+                                                               var td = document.createElement('td');
+                                                               var idx = $(this).attr('axis').substr(3);
+                                                               td.align = this.align;
+                                                               // If each row is the object itself (no 'cell' key)
+                                                               if (typeof row.cell == 'undefined') {
+                                                                       td.innerHTML = row[p.colModel[idx].name];
+                                                               } else {
+                                                                       // If the json elements aren't named (which is typical), use numeric order
+                                    var iHTML = '';
+                                    if (typeof row.cell[idx] != "undefined") {
+                                        iHTML = (row.cell[idx] !== null) ? row.cell[idx] : ''; //null-check for Opera-browser
+                                    } else {
+                                        iHTML = row.cell[p.colModel[idx].name];
+                                    }
+                                    td.innerHTML = p.__mw.datacol(p, $(this).attr('abbr'), iHTML); //use middleware datacol to format cols
+                                                               }
+                                                               // If the content has a <BGCOLOR=nnnnnn> option, decode it.
+                                                               var offs = td.innerHTML.indexOf( '<BGCOLOR=' );
+                                                               if( offs >0 ) {
+                                    $(td).css('background', text.substr(offs+7,7) );
+                                                               }
+
+                                                               $(td).attr('abbr', $(this).attr('abbr'));
+                                                               $(tr).append(td);
+                                                               td = null;
+                                                       }
+                                               );
+                                               if ($('thead', this.gDiv).length < 1) {//handle if grid has no headers
+                                                       for (idx = 0; idx < row.cell.length; idx++) {
+                                                               var td = document.createElement('td');
+                                                               // If the json elements aren't named (which is typical), use numeric order
+                                                               if (typeof row.cell[idx] != "undefined") {
+                                                                       td.innerHTML = (row.cell[idx] != null) ? row.cell[idx] : '';//null-check for Opera-browser
+                                                               } else {
+                                                                       td.innerHTML = row.cell[p.colModel[idx].name];
+                                                               }
+                                                               $(tr).append(td);
+                                                               td = null;
+                                                       }
+                                               }
+                                               $(tbody).append(tr);
+                                               tr = null;
+                                       });
+                               } else if (p.dataType == 'xml') {
+                                       var i = 1;
+                                       $("rows row", data).each(function () {
+                                               i++;
+                                               var tr = document.createElement('tr');
+                                               if ($(this).attr('name')) tr.name = $(this).attr('name');
+                                               if ($(this).attr('color')) {
+                                                       $(tr).css('background',$(this).attr('id'));
+                                               } else {
+                                                       if (i % 2 && p.striped) tr.className = 'erow';
+                                               }
+                                               var nid = $(this).attr('id');
+                                               if (nid) {
+                                                       tr.id = 'row' + nid;
+                                               }
+                                               nid = null;
+                                               var robj = this;
+                                               $('thead tr:first th', g.hDiv).each(function () {
+                                                       var td = document.createElement('td');
+                                                       var idx = $(this).attr('axis').substr(3);
+                                                       td.align = this.align;
+
+                                                       var text = $("cell:eq(" + idx + ")", robj).text();
+                                                       var offs = text.indexOf( '<BGCOLOR=' );
+                                                       if( offs >0 ) {
+                                                               $(td).css('background',  text.substr(offs+7,7) );
+                                                       }
+                            td.innerHTML = p.__mw.datacol(p, $(this).attr('abbr'), text); //use middleware datacol to format cols
+                                                       $(td).attr('abbr', $(this).attr('abbr'));
+                                                       $(tr).append(td);
+                                                       td = null;
+                                               });
+                                               if ($('thead', this.gDiv).length < 1) {//handle if grid has no headers
+                                                       $('cell', this).each(function () {
+                                                               var td = document.createElement('td');
+                                                               td.innerHTML = $(this).text();
+                                                               $(tr).append(td);
+                                                               td = null;
+                                                       });
+                                               }
+                                               $(tbody).append(tr);
+                                               tr = null;
+                                               robj = null;
+                                       });
+                               }
+                               $('tr', t).unbind();
+                               $(t).empty();
+                               $(t).append(tbody);
+                               this.addCellProp();
+                               this.addRowProp();
+                               this.rePosDrag();
+                               tbody = null;
+                               data = null;
+                               i = null;
+                               if (p.onSuccess) {
+                                       p.onSuccess(this);
+                               }
+                               if (p.hideOnSubmit) {
+                                       $(g.block).remove();
+                               }
+                               this.hDiv.scrollLeft = this.bDiv.scrollLeft;
+                               if (browser.opera) {
+                                       $(t).css('visibility', 'visible');
+                               }
+                       },
+                       changeSort: function (th) { //change sortorder
+                               if (this.loading) {
+                                       return true;
+                               }
+                               $(g.nDiv).hide();
+                               $(g.nBtn).hide();
+                               if (p.sortname == $(th).attr('abbr')) {
+                                       if (p.sortorder == 'asc') {
+                                               p.sortorder = 'desc';
+                                       } else {
+                                               p.sortorder = 'asc';
+                                       }
+                               }
+                               $(th).addClass('sorted').siblings().removeClass('sorted');
+                               $('.sdesc', this.hDiv).removeClass('sdesc');
+                               $('.sasc', this.hDiv).removeClass('sasc');
+                               $('div', th).addClass('s' + p.sortorder);
+                               p.sortname = $(th).attr('abbr');
+                               if (p.onChangeSort) {
+                                       p.onChangeSort(p.sortname, p.sortorder);
+                               } else {
+                                       this.populate();
+                               }
+                       },
+                       buildpager: function () { //rebuild pager based on new properties
+                               $('.pcontrol input', this.pDiv).val(p.page);
+                               $('.pcontrol span', this.pDiv).html(p.pages);
+                               var r1 = p.total == 0 ? 0 : (p.page - 1) * p.rp + 1;
+                               var r2 = r1 + p.rp - 1;
+                               if (p.total < r2) {
+                                       r2 = p.total;
+                               }
+                               var stat = p.pagestat;
+                               stat = stat.replace(/{from}/, r1);
+                               stat = stat.replace(/{to}/, r2);
+                               stat = stat.replace(/{total}/, p.total);
+                               $('.pPageStat', this.pDiv).html(stat);
+                       },
+                       populate: function () { //get latest data
+                               if (this.loading) {
+                                       return true;
+                               }
+                               if (p.onSubmit) {
+                                       var gh = p.onSubmit();
+                                       if (!gh) {
+                                               return false;
+                                       }
+                               }
+                               this.loading = true;
+                               if (!p.url) {
+                                       return false;
+                               }
+                               $('.pPageStat', this.pDiv).html(p.procmsg);
+                               $('.pReload', this.pDiv).addClass('loading');
+                               $(g.block).css({
+                                       top: g.bDiv.offsetTop
+                               });
+                               if (p.hideOnSubmit) {
+                                       $(this.gDiv).prepend(g.block);
+                               }
+                               if (browser.opera) {
+                                       $(t).css('visibility', 'hidden');
+                               }
+                               if (!p.newp) {
+                                       p.newp = 1;
+                               }
+                               if (p.page > p.pages) {
+                                       p.page = p.pages;
+                               }
+                               var param = [{
+                                       name: 'page',
+                                       value: p.newp
+                               }, {
+                                       name: 'rp',
+                                       value: p.rp
+                               }, {
+                                       name: 'sortname',
+                                       value: p.sortname
+                               }, {
+                                       name: 'sortorder',
+                                       value: p.sortorder
+                               }, {
+                                       name: 'query',
+                                       value: p.query
+                               }, {
+                                       name: 'qtype',
+                                       value: p.qtype
+                               }];
+                               if (p.params.length) {
+                                       for (var pi = 0; pi < p.params.length; pi++) {
+                                               param[param.length] = p.params[pi];
+                                       }
+                               }
+                               $.ajax({
+                                       type: p.method,
+                                       url: p.url,
+                                       data: param,
+                                       dataType: p.dataType,
+                                       success: function (data) {
+                                               g.addData(data);
+                                       },
+                                       error: function (XMLHttpRequest, textStatus, errorThrown) {
+                                               try {
+                                                       if (p.onError) p.onError(XMLHttpRequest, textStatus, errorThrown);
+                                               } catch (e) {}
+                                       }
+                               });
+                       },
+                       doSearch: function () {
+                               p.query = $('input[name=q]', g.sDiv).val();
+                               p.qtype = $('select[name=qtype]', g.sDiv).val();
+                               p.newp = 1;
+                               this.populate();
+                       },
+                       changePage: function (ctype) { //change page
+                               if (this.loading) {
+                                       return true;
+                               }
+                               switch (ctype) {
+                                       case 'first':
+                                               p.newp = 1;
+                                               break;
+                                       case 'prev':
+                                               if (p.page > 1) {
+                                                       p.newp = parseInt(p.page, 10) - 1;
+                                               }
+                                               break;
+                                       case 'next':
+                                               if (p.page < p.pages) {
+                                                       p.newp = parseInt(p.page, 10) + 1;
+                                               }
+                                               break;
+                                       case 'last':
+                                               p.newp = p.pages;
+                                               break;
+                                       case 'input':
+                                               var nv = parseInt($('.pcontrol input', this.pDiv).val(), 10);
+                                               if (isNaN(nv)) {
+                                                       nv = 1;
+                                               }
+                                               if (nv < 1) {
+                                                       nv = 1;
+                                               } else if (nv > p.pages) {
+                                                       nv = p.pages;
+                                               }
+                                               $('.pcontrol input', this.pDiv).val(nv);
+                                               p.newp = nv;
+                                               break;
+                               }
+                               if (p.newp == p.page) {
+                                       return false;
+                               }
+                               if (p.onChangePage) {
+                                       p.onChangePage(p.newp);
+                               } else {
+                                       this.populate();
+                               }
+                       },
+                       addCellProp: function () {
+                               $('tbody tr td', g.bDiv).each(function () {
+                                       var tdDiv = document.createElement('div');
+                                       var n = $('td', $(this).parent()).index(this);
+                                       var pth = $('th:eq(' + n + ')', g.hDiv).get(0);
+                                       if (pth != null) {
+                                               if (p.sortname == $(pth).attr('abbr') && p.sortname) {
+                                                       this.className = 'sorted';
+                                               }
+                                               $(tdDiv).css({
+                                                       textAlign: pth.align,
+                                                       width: $('div:first', pth)[0].style.width
+                                               });
+                                               if (pth.hidden) {
+                                                       $(this).css('display', 'none');
+                                               }
+                                       }
+                                       if (p.nowrap == false) {
+                                               $(tdDiv).css('white-space', 'normal');
+                                       }
+                                       if (this.innerHTML == '') {
+                                               this.innerHTML = '&nbsp;';
+                                       }
+                                       tdDiv.innerHTML = this.innerHTML;
+                                       var prnt = $(this).parent()[0];
+                                       var pid = false;
+                                       if (prnt.id) {
+                                               pid = prnt.id.substr(3);
+                                       }
+                                       if (pth != null) {
+                                               if (pth.process) pth.process(tdDiv, pid);
+                                       }
+                                       $(this).empty().append(tdDiv).removeAttr('width'); //wrap content
+                                       g.addTitleToCell(tdDiv);
+                               });
+                       },
+                       getCellDim: function (obj) {// get cell prop for editable event
+                               var ht = parseInt($(obj).height(), 10);
+                               var pht = parseInt($(obj).parent().height(), 10);
+                               var wt = parseInt(obj.style.width, 10);
+                               var pwt = parseInt($(obj).parent().width(), 10);
+                               var top = obj.offsetParent.offsetTop;
+                               var left = obj.offsetParent.offsetLeft;
+                               var pdl = parseInt($(obj).css('paddingLeft'), 10);
+                               var pdt = parseInt($(obj).css('paddingTop'), 10);
+                               return {
+                                       ht: ht,
+                                       wt: wt,
+                                       top: top,
+                                       left: left,
+                                       pdl: pdl,
+                                       pdt: pdt,
+                                       pht: pht,
+                                       pwt: pwt
+                               };
+                       },
+                       addRowProp: function () {
+                               $('tbody tr', g.bDiv).on('click', function (e) {
+                                       var obj = (e.target || e.srcElement);
+                                       if (obj.href || obj.type) return true;
+                                       if (e.ctrlKey || e.metaKey) {
+                                               // mousedown already took care of this case
+                                               return;
+                                       }
+                                       $(this).toggleClass('trSelected');
+                                       if (p.singleSelect && ! g.multisel) {
+                                               $(this).siblings().removeClass('trSelected');
+                                       }
+                               }).on('mousedown', function (e) {
+                                       if (e.shiftKey) {
+                                               $(this).toggleClass('trSelected');
+                                               g.multisel = true;
+                                               this.focus();
+                                               $(g.gDiv).noSelect();
+                                       }
+                                       if (e.ctrlKey || e.metaKey) {
+                                               $(this).toggleClass('trSelected');
+                                               g.multisel = true;
+                                               this.focus();
+                                       }
+                               }).on('mouseup', function (e) {
+                                       if (g.multisel && ! (e.ctrlKey || e.metaKey)) {
+                                               g.multisel = false;
+                                               $(g.gDiv).noSelect(false);
+                                       }
+                               }).on('dblclick', function () {
+                                       if (p.onDoubleClick) {
+                                               p.onDoubleClick(this, g, p);
+                                       }
+                               }).hover(function (e) {
+                                       if (g.multisel && e.shiftKey) {
+                                               $(this).toggleClass('trSelected');
+                                       }
+                               }, function () {});
+                               if (browser.msie && browser.version < 7.0) {
+                                       $(this).hover(function () {
+                                               $(this).addClass('trOver');
+                                       }, function () {
+                                               $(this).removeClass('trOver');
+                                       });
+                               }
+                       },
+
+                       combo_flag: true,
+                       combo_resetIndex: function(selObj)
+                       {
+                               if(this.combo_flag) {
+                                       selObj.selectedIndex = 0;
+                               }
+                               this.combo_flag = true;
+                       },
+                       combo_doSelectAction: function(selObj)
+                       {
+                               eval( selObj.options[selObj.selectedIndex].value );
+                               selObj.selectedIndex = 0;
+                               this.combo_flag = false;
+                       },
+                       //Add title attribute to div if cell contents is truncated
+                       addTitleToCell: function(tdDiv) {
+                               if(p.addTitleToCell) {
+                                       var $span = $('<span />').css('display', 'none'),
+                                               $div = (tdDiv instanceof jQuery) ? tdDiv : $(tdDiv),
+                                               div_w = $div.outerWidth(),
+                                               span_w = 0;
+
+                                       $('body').children(':first').before($span);
+                                       $span.html($div.html());
+                                       $span.css('font-size', '' + $div.css('font-size'));
+                                       $span.css('padding-left', '' + $div.css('padding-left'));
+                                       span_w = $span.innerWidth();
+                                       $span.remove();
+
+                                       if(span_w > div_w) {
+                                               $div.attr('title', $div.text());
+                                       } else {
+                                               $div.removeAttr('title');
+                                       }
+                               }
+                       },
+                       autoResizeColumn: function (obj) {
+                               if(!p.dblClickResize) {
+                                       return;
+                               }
+                               var n = $('div', this.cDrag).index(obj),
+                                       $th = $('th:visible div:eq(' + n + ')', this.hDiv),
+                                       ol = parseInt(obj.style.left, 10),
+                                       ow = $th.width(),
+                                       nw = 0,
+                                       nl = 0,
+                                       $span = $('<span />');
+                               $('body').children(':first').before($span);
+                               $span.html($th.html());
+                               $span.css('font-size', '' + $th.css('font-size'));
+                               $span.css('padding-left', '' + $th.css('padding-left'));
+                               $span.css('padding-right', '' + $th.css('padding-right'));
+                               nw = $span.width();
+                               $('tr', this.bDiv).each(function () {
+                                       var $tdDiv = $('td:visible div:eq(' + n + ')', this),
+                                               spanW = 0;
+                                       $span.html($tdDiv.html());
+                                       $span.css('font-size', '' + $tdDiv.css('font-size'));
+                                       $span.css('padding-left', '' + $tdDiv.css('padding-left'));
+                                       $span.css('padding-right', '' + $tdDiv.css('padding-right'));
+                                       spanW = $span.width();
+                                       nw = (spanW > nw) ? spanW : nw;
+                               });
+                               $span.remove();
+                               nw = (p.minWidth > nw) ? p.minWidth : nw;
+                               nl = ol + (nw - ow);
+                               $('div:eq(' + n + ')', this.cDrag).css('left', nl);
+                               this.colresize = {
+                                       nw: nw,
+                                       n: n
+                               };
+                               g.dragEnd();
+                       },
+                       pager: 0
+               };
+        
+        g = p.getGridClass(g); //get the grid class
+        
+               if (p.colModel) { //create model if any
+                       thead = document.createElement('thead');
+                       var tr = document.createElement('tr');
+                       for (var i = 0; i < p.colModel.length; i++) {
+                               var cm = p.colModel[i];
+                               var th = document.createElement('th');
+                               $(th).attr('axis', 'col' + i);
+                               if( cm ) {      // only use cm if its defined
+                                       if ($.cookies) {
+                                               var cookie_width = 'flexiwidths/'+cm.name;              // Re-Store the widths in the cookies
+                                               if( $.cookie(cookie_width) != undefined ) {
+                                                       cm.width = $.cookie(cookie_width);
+                                               }
+                                       }
+                                       if( cm.display != undefined ) {
+                                               th.innerHTML = cm.display;
+                                       }
+                                       if (cm.name && cm.sortable) {
+                                               $(th).attr('abbr', cm.name);
+                                       }
+                                       if (cm.align) {
+                                               th.align = cm.align;
+                                       }
+                                       if (cm.width) {
+                                               $(th).attr('width', cm.width);
+                                       }
+                                       if ($(cm).attr('hide')) {
+                                               th.hidden = true;
+                                       }
+                                       if (cm.process) {
+                                               th.process = cm.process;
+                                       }
+                               } else {
+                                       th.innerHTML = "";
+                                       $(th).attr('width',30);
+                               }
+                               $(tr).append(th);
+                       }
+                       $(thead).append(tr);
+                       $(t).prepend(thead);
+               } // end if p.colmodel
+               //init divs
+               g.gDiv = document.createElement('div'); //create global container
+               g.mDiv = document.createElement('div'); //create title container
+               g.hDiv = document.createElement('div'); //create header container
+               g.bDiv = document.createElement('div'); //create body container
+               g.vDiv = document.createElement('div'); //create grip
+               g.rDiv = document.createElement('div'); //create horizontal resizer
+               g.cDrag = document.createElement('div'); //create column drag
+               g.block = document.createElement('div'); //creat blocker
+               g.nDiv = document.createElement('div'); //create column show/hide popup
+               g.nBtn = document.createElement('div'); //create column show/hide button
+               g.iDiv = document.createElement('div'); //create editable layer
+               g.tDiv = document.createElement('div'); //create toolbar
+               g.sDiv = document.createElement('div');
+               g.pDiv = document.createElement('div'); //create pager container
+        
+        if(p.colResize === false) { //don't display column drag if we are not using it
+            $(g.cDrag).css('display', 'none');
+        }
+        
+               if (!p.usepager) {
+                       g.pDiv.style.display = 'none';
+               }
+               g.hTable = document.createElement('table');
+               g.gDiv.className = 'flexigrid';
+               if (p.width != 'auto') {
+                       g.gDiv.style.width = p.width + (isNaN(p.width) ? '' : 'px');
+               } 
+               //add conditional classes
+               if (browser.msie) {
+                       $(g.gDiv).addClass('ie');
+               }
+               if (p.novstripe) {
+                       $(g.gDiv).addClass('novstripe');
+               }
+               $(t).before(g.gDiv);
+               $(g.gDiv).append(t);
+               //set toolbar
+               if (p.buttons) {
+                       g.tDiv.className = 'tDiv';
+                       var tDiv2 = document.createElement('div');
+                       tDiv2.className = 'tDiv2';
+                       for (var i = 0; i < p.buttons.length; i++) {
+                               var btn = p.buttons[i];
+                               if (!btn.separator) {
+                                       var btnDiv = document.createElement('div');
+                                       btnDiv.className = 'fbutton';
+                                       btnDiv.innerHTML = ("<div><span>") + (btn.hidename ? "&nbsp;" : btn.name) + ("</span></div>");
+                                       if (btn.bclass) $('span', btnDiv).addClass(btn.bclass).css({
+                                               paddingLeft: 20
+                                       });
+                                       if (btn.bimage) // if bimage defined, use its string as an image url for this buttons style (RS)
+                                               $('span',btnDiv).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
+                                               $('span',btnDiv).css( 'paddingLeft', 20 );
+
+                                       if (btn.tooltip) // add title if exists (RS)
+                                               $('span',btnDiv)[0].title = btn.tooltip;
+
+                                       btnDiv.onpress = btn.onpress;
+                                       btnDiv.name = btn.name;
+                                       if (btn.id) {
+                                               btnDiv.id = btn.id;
+                                       }
+                                       if (btn.onpress) {
+                                               $(btnDiv).click(function () {
+                                                       this.onpress(this.id || this.name, g.gDiv);
+                                               });
+                                       }
+                                       $(tDiv2).append(btnDiv);
+                                       if (browser.msie && browser.version < 7.0) {
+                                               $(btnDiv).hover(function () {
+                                                       $(this).addClass('fbOver');
+                                               }, function () {
+                                                       $(this).removeClass('fbOver');
+                                               });
+                                       }
+                               } else {
+                                       $(tDiv2).append("<div class='btnseparator'></div>");
+                               }
+                       }
+                       $(g.tDiv).append(tDiv2);
+                       $(g.tDiv).append("<div style='clear:both'></div>");
+                       $(g.gDiv).prepend(g.tDiv);
+               }
+               g.hDiv.className = 'hDiv';
+
+               // Define a combo button set with custom action'ed calls when clicked.
+               if( p.combobuttons && $(g.tDiv2) )
+               {
+                       var btnDiv = document.createElement('div');
+                       btnDiv.className = 'fbutton';
+
+                       var tSelect = document.createElement('select');
+                       $(tSelect).change( function () { g.combo_doSelectAction( tSelect ) } );
+                       $(tSelect).click( function () { g.combo_resetIndex( tSelect) } );
+                       tSelect.className = 'cselect';
+                       $(btnDiv).append(tSelect);
+
+                       for (i=0;i<p.combobuttons.length;i++)
+                       {
+                               var btn = p.combobuttons[i];
+                               if (!btn.separator)
+                               {
+                                       var btnOpt = document.createElement('option');
+                                       btnOpt.innerHTML = btn.name;
+
+                                       if (btn.bclass)
+                                               $(btnOpt)
+                                               .addClass(btn.bclass)
+                                               .css({paddingLeft:20})
+                                               ;
+                                       if (btn.bimage)  // if bimage defined, use its string as an image url for this buttons style (RS)
+                                               $(btnOpt).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
+                                               $(btnOpt).css( 'paddingLeft', 20 );
+
+                                       if (btn.tooltip) // add title if exists (RS)
+                                               $(btnOpt)[0].title = btn.tooltip;
+
+                                       if (btn.onpress)
+                                       {
+                                               btnOpt.value = btn.onpress;
+                                       }
+                                       $(tSelect).append(btnOpt);
+                               }
+                       }
+                       $('.tDiv2').append(btnDiv);
+               }
+
+
+               $(t).before(g.hDiv);
+               g.hTable.cellPadding = 0;
+               g.hTable.cellSpacing = 0;
+               $(g.hDiv).append('<div class="hDivBox"></div>');
+               $('div', g.hDiv).append(g.hTable);
+               var thead = $("thead:first", t).get(0);
+               if (thead) $(g.hTable).append(thead);
+               thead = null;
+               if (!p.colmodel) var ci = 0;
+               $('thead tr:first th', g.hDiv).each(function () {
+                       var thdiv = document.createElement('div');
+                       if ($(this).attr('abbr')) {
+                               $(this).click(function (e) {
+                                       if (!$(this).hasClass('thOver')) return false;
+                                       var obj = (e.target || e.srcElement);
+                                       if (obj.href || obj.type) return true;
+                                       g.changeSort(this);
+                               });
+                               if ($(this).attr('abbr') == p.sortname) {
+                                       this.className = 'sorted';
+                                       thdiv.className = 's' + p.sortorder;
+                               }
+                       }
+                       if (this.hidden) {
+                               $(this).hide();
+                       }
+                       if (!p.colmodel) {
+                               $(this).attr('axis', 'col' + ci++);
+                       }
+                       
+                       // if there isn't a default width, then the column headers don't match
+                       // i'm sure there is a better way, but this at least stops it failing
+                       if (this.width == '') {
+                               this.width = 100;
+                       }
+                       
+                       $(thdiv).css({
+                               textAlign: this.align,
+                               width: this.width + 'px'
+                       });
+                       thdiv.innerHTML = this.innerHTML;
+                       $(this).empty().append(thdiv).removeAttr('width').mousedown(function (e) {
+                               g.dragStart('colMove', e, this);
+                       }).hover(function () {
+                               if (!g.colresize && !$(this).hasClass('thMove') && !g.colCopy) {
+                                       $(this).addClass('thOver');
+                               }
+                               if ($(this).attr('abbr') != p.sortname && !g.colCopy && !g.colresize && $(this).attr('abbr')) {
+                                       $('div', this).addClass('s' + p.sortorder);
+                               } else if ($(this).attr('abbr') == p.sortname && !g.colCopy && !g.colresize && $(this).attr('abbr')) {
+                                       var no = (p.sortorder == 'asc') ? 'desc' : 'asc';
+                                       $('div', this).removeClass('s' + p.sortorder).addClass('s' + no);
+                               }
+                               if (g.colCopy) {
+                                       var n = $('th', g.hDiv).index(this);
+                                       if (n == g.dcoln) {
+                                               return false;
+                                       }
+                                       if (n < g.dcoln) {
+                                               $(this).append(g.cdropleft);
+                                       } else {
+                                               $(this).append(g.cdropright);
+                                       }
+                                       g.dcolt = n;
+                               } else if (!g.colresize) {
+                                       var nv = $('th:visible', g.hDiv).index(this);
+                                       var onl = parseInt($('div:eq(' + nv + ')', g.cDrag).css('left'), 10);
+                                       var nw = jQuery(g.nBtn).outerWidth();
+                                       var nl = onl - nw + Math.floor(p.cgwidth / 2);
+                                       $(g.nDiv).hide();
+                                       $(g.nBtn).hide();
+                                       $(g.nBtn).css({
+                                               'left': nl,
+                                               top: g.hDiv.offsetTop
+                                       }).show();
+                                       var ndw = parseInt($(g.nDiv).width(), 10);
+                                       $(g.nDiv).css({
+                                               top: g.bDiv.offsetTop
+                                       });
+                                       if ((nl + ndw) > $(g.gDiv).width()) {
+                                               $(g.nDiv).css('left', onl - ndw + 1);
+                                       } else {
+                                               $(g.nDiv).css('left', nl);
+                                       }
+                                       if ($(this).hasClass('sorted')) {
+                                               $(g.nBtn).addClass('srtd');
+                                       } else {
+                                               $(g.nBtn).removeClass('srtd');
+                                       }
+                               }
+                       }, function () {
+                               $(this).removeClass('thOver');
+                               if ($(this).attr('abbr') != p.sortname) {
+                                       $('div', this).removeClass('s' + p.sortorder);
+                               } else if ($(this).attr('abbr') == p.sortname) {
+                                       var no = (p.sortorder == 'asc') ? 'desc' : 'asc';
+                                       $('div', this).addClass('s' + p.sortorder).removeClass('s' + no);
+                               }
+                               if (g.colCopy) {
+                                       $(g.cdropleft).remove();
+                                       $(g.cdropright).remove();
+                                       g.dcolt = null;
+                               }
+                       }); //wrap content
+               });
+               //set bDiv
+               g.bDiv.className = 'bDiv';
+               $(t).before(g.bDiv);
+               $(g.bDiv).css({
+                       height: (p.height == 'auto') ? 'auto' : p.height + "px"
+               }).scroll(function (e) {
+                       g.scroll()
+               }).append(t);
+               if (p.height == 'auto') {
+                       $('table', g.bDiv).addClass('autoht');
+               }
+               //add td & row properties
+               g.addCellProp();
+               g.addRowProp();
+        //set cDrag only if we are using it
+        if (p.colResize === true) {
+            var cdcol = $('thead tr:first th:first', g.hDiv).get(0);
+            if(cdcol !== null) {
+                g.cDrag.className = 'cDrag';
+                g.cdpad = 0;
+                g.cdpad += (isNaN(parseInt($('div', cdcol).css('borderLeftWidth'), 10)) ? 0 : parseInt($('div', cdcol).css('borderLeftWidth'), 10));
+                g.cdpad += (isNaN(parseInt($('div', cdcol).css('borderRightWidth'), 10)) ? 0 : parseInt($('div', cdcol).css('borderRightWidth'), 10));
+                g.cdpad += (isNaN(parseInt($('div', cdcol).css('paddingLeft'), 10)) ? 0 : parseInt($('div', cdcol).css('paddingLeft'), 10));
+                g.cdpad += (isNaN(parseInt($('div', cdcol).css('paddingRight'), 10)) ? 0 : parseInt($('div', cdcol).css('paddingRight'), 10));
+                g.cdpad += (isNaN(parseInt($(cdcol).css('borderLeftWidth'), 10)) ? 0 : parseInt($(cdcol).css('borderLeftWidth'), 10));
+                g.cdpad += (isNaN(parseInt($(cdcol).css('borderRightWidth'), 10)) ? 0 : parseInt($(cdcol).css('borderRightWidth'), 10));
+                g.cdpad += (isNaN(parseInt($(cdcol).css('paddingLeft'), 10)) ? 0 : parseInt($(cdcol).css('paddingLeft'), 10));
+                g.cdpad += (isNaN(parseInt($(cdcol).css('paddingRight'), 10)) ? 0 : parseInt($(cdcol).css('paddingRight'), 10));
+                $(g.bDiv).before(g.cDrag);
+                var cdheight = $(g.bDiv).height();
+                var hdheight = $(g.hDiv).height();
+                $(g.cDrag).css({
+                    top: -hdheight + 'px'
+                });
+                $('thead tr:first th', g.hDiv).each(function() {
+                    var cgDiv = document.createElement('div');
+                    $(g.cDrag).append(cgDiv);
+                    if (!p.cgwidth) {
+                        p.cgwidth = $(cgDiv).width();
+                    }
+                    $(cgDiv).css({
+                        height: cdheight + hdheight
+                    }).mousedown(function(e) {
+                        g.dragStart('colresize', e, this);
+                    }).dblclick(function(e) {
+                        g.autoResizeColumn(this);
+                    });
+                    if (browser.msie && browser.version < 7.0) {
+                        g.fixHeight($(g.gDiv).height());
+                        $(cgDiv).hover(function() {
+                            g.fixHeight();
+                            $(this).addClass('dragging');
+                        }, function() {
+                            if(!g.colresize) {
+                                $(this).removeClass('dragging');
+                            }
+                        });
+                    }
+                });
+            }
+        }
+               //add strip
+               if (p.striped) {
+                       $('tbody tr:odd', g.bDiv).addClass('erow');
+               }
+               if (p.resizable && p.height != 'auto') {
+                       g.vDiv.className = 'vGrip';
+                       $(g.vDiv).mousedown(function (e) {
+                               g.dragStart('vresize', e);
+                       }).html('<span></span>');
+                       $(g.bDiv).after(g.vDiv);
+               }
+               if (p.resizable && p.width != 'auto' && !p.nohresize) {
+                       g.rDiv.className = 'hGrip';
+                       $(g.rDiv).mousedown(function (e) {
+                               g.dragStart('vresize', e, true);
+                       }).html('<span></span>').css('height', $(g.gDiv).height());
+                       if (browser.msie && browser.version < 7.0) {
+                               $(g.rDiv).hover(function () {
+                                       $(this).addClass('hgOver');
+                               }, function () {
+                                       $(this).removeClass('hgOver');
+                               });
+                       }
+                       $(g.gDiv).append(g.rDiv);
+               }
+               // add pager
+               if (p.usepager) {
+                       g.pDiv.className = 'pDiv';
+                       g.pDiv.innerHTML = '<div class="pDiv2"></div>';
+                       $(g.bDiv).after(g.pDiv);
+                       var html = ' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">' + p.pagetext + ' <input type="text" size="4" value="1" /> ' + p.outof + ' <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';
+                       $('div', g.pDiv).html(html);
+                       $('.pReload', g.pDiv).click(function () {
+                               g.populate();
+                       });
+                       $('.pFirst', g.pDiv).click(function () {
+                               g.changePage('first');
+                       });
+                       $('.pPrev', g.pDiv).click(function () {
+                               g.changePage('prev');
+                       });
+                       $('.pNext', g.pDiv).click(function () {
+                               g.changePage('next');
+                       });
+                       $('.pLast', g.pDiv).click(function () {
+                               g.changePage('last');
+                       });
+                       $('.pcontrol input', g.pDiv).keydown(function (e) {
+                               if (e.keyCode == 13) { 
+                    g.changePage('input');
+                               }
+                       });
+                       if (browser.msie && browser.version < 7) $('.pButton', g.pDiv).hover(function () {
+                               $(this).addClass('pBtnOver');
+                       }, function () {
+                               $(this).removeClass('pBtnOver');
+                       });
+                       if (p.useRp) {
+                               var opt = '',
+                                       sel = '';
+                               for (var nx = 0; nx < p.rpOptions.length; nx++) {
+                                       if (p.rp == p.rpOptions[nx]) sel = 'selected="selected"';
+                                       else sel = '';
+                                       opt += "<option value='" + p.rpOptions[nx] + "' " + sel + " >" + p.rpOptions[nx] + "&nbsp;&nbsp;</option>";
+                               }
+                               $('.pDiv2', g.pDiv).prepend("<div class='pGroup'><select name='rp'>" + opt + "</select></div> <div class='btnseparator'></div>");
+                               $('select', g.pDiv).change(function () {
+                                       if (p.onRpChange) {
+                                               p.onRpChange(+this.value);
+                                       } else {
+                                               p.newp = 1;
+                                               p.rp = +this.value;
+                                               g.populate();
+                                       }
+                               });
+                       }
+                       //add search button
+                       if (p.searchitems) {
+                               $('.pDiv2', g.pDiv).prepend("<div class='pGroup'> <div class='pSearch pButton'><span></span></div> </div>  <div class='btnseparator'></div>");
+                               $('.pSearch', g.pDiv).click(function () {
+                                       $(g.sDiv).slideToggle('fast', function () {
+                                               $('.sDiv:visible input:first', g.gDiv).trigger('focus');
+                                       });
+                               });
+                               //add search box
+                               g.sDiv.className = 'sDiv';
+                               var sitems = p.searchitems;
+                               var sopt = '', sel = '';
+                               for (var s = 0; s < sitems.length; s++) {
+                                       if (p.qtype === '' && sitems[s].isdefault === true) {
+                                               p.qtype = sitems[s].name;
+                                               sel = 'selected="selected"';
+                                       } else {
+                                               sel = '';
+                                       }
+                                       sopt += "<option value='" + sitems[s].name + "' " + sel + " >" + sitems[s].display + "&nbsp;&nbsp;</option>";
+                               }
+                               if (p.qtype === '') {
+                                       p.qtype = sitems[0].name;
+                               }
+                               $(g.sDiv).append("<div class='sDiv2'>" + p.findtext +
+                                               " <input type='text' value='" + p.query +"' size='30' name='q' class='qsbox' /> "+
+                                               " <select name='qtype'>" + sopt + "</select></div>");
+                               //Split into separate selectors because of bug in jQuery 1.3.2
+                               $('input[name=q]', g.sDiv).keydown(function (e) {
+                                       if (e.keyCode == 13) {
+                                               g.doSearch();
+                                       }
+                               });
+                               $('select[name=qtype]', g.sDiv).keydown(function (e) {
+                                       if (e.keyCode == 13) {
+                                               g.doSearch();
+                                       }
+                               });
+                               $('input[value=Clear]', g.sDiv).click(function () {
+                                       $('input[name=q]', g.sDiv).val('');
+                                       p.query = '';
+                                       g.doSearch();
+                               });
+                               $(g.bDiv).after(g.sDiv);
+                       }
+               }
+               $(g.pDiv, g.sDiv).append("<div style='clear:both'></div>");
+               // add title
+               if (p.title) {
+                       g.mDiv.className = 'mDiv';
+                       g.mDiv.innerHTML = '<div class="ftitle">' + p.title + '</div>';
+                       $(g.gDiv).prepend(g.mDiv);
+                       if (p.showTableToggleBtn) {
+                               $(g.mDiv).append('<div class="ptogtitle" title="Minimize/Maximize Table"><span></span></div>');
+                               $('div.ptogtitle', g.mDiv).click(function () {
+                                       $(g.gDiv).toggleClass('hideBody');
+                                       $(this).toggleClass('vsble');
+                               });
+                       }
+               }
+               //setup cdrops
+               g.cdropleft = document.createElement('span');
+               g.cdropleft.className = 'cdropleft';
+               g.cdropright = document.createElement('span');
+               g.cdropright.className = 'cdropright';
+               //add block
+               g.block.className = 'gBlock';
+               var gh = $(g.bDiv).height();
+               var gtop = g.bDiv.offsetTop;
+               $(g.block).css({
+                       width: g.bDiv.style.width,
+                       height: gh,
+                       background: 'white',
+                       position: 'relative',
+                       marginBottom: (gh * -1),
+                       zIndex: 1,
+                       top: gtop,
+                       left: '0px'
+               });
+               $(g.block).fadeTo(0, p.blockOpacity);
+               // add column control
+               if ($('th', g.hDiv).length) {
+                       g.nDiv.className = 'nDiv';
+                       g.nDiv.innerHTML = "<table cellpadding='0' cellspacing='0'><tbody></tbody></table>";
+                       $(g.nDiv).css({
+                               marginBottom: (gh * -1),
+                               display: 'none',
+                               top: gtop
+                       }).noSelect();
+                       var cn = 0;
+                       $('th div', g.hDiv).each(function () {
+                               var kcol = $("th[axis='col" + cn + "']", g.hDiv)[0];
+                               var chk = 'checked="checked"';
+                               if (kcol.style.display == 'none') {
+                                       chk = '';
+                               }
+                               $('tbody', g.nDiv).append('<tr><td class="ndcol1"><input type="checkbox" ' + chk + ' class="togCol" value="' + cn + '" /></td><td class="ndcol2">' + this.innerHTML + '</td></tr>');
+                               cn++;
+                       });
+                       if (browser.msie && browser.version < 7.0) $('tr', g.nDiv).hover(function () {
+                               $(this).addClass('ndcolover');
+                       }, function () {
+                               $(this).removeClass('ndcolover');
+                       });
+                       $('td.ndcol2', g.nDiv).click(function () {
+                               if ($('input:checked', g.nDiv).length <= p.minColToggle && $(this).prev().find('input')[0].checked) return false;
+                               return g.toggleCol($(this).prev().find('input').val());
+                       });
+                       $('input.togCol', g.nDiv).click(function () {
+                               if ($('input:checked', g.nDiv).length < p.minColToggle && this.checked === false) return false;
+                               $(this).parent().next().trigger('click');
+                       });
+                       $(g.gDiv).prepend(g.nDiv);
+                       $(g.nBtn).addClass('nBtn')
+                               .html('<div></div>')
+                               .attr('title', 'Hide/Show Columns')
+                               .click(function () {
+                                       $(g.nDiv).toggle();
+                                       return true;
+                               }
+                       );
+                       if (p.showToggleBtn) {
+                               $(g.gDiv).prepend(g.nBtn);
+                       }
+               }
+               // add date edit layer
+               $(g.iDiv).addClass('iDiv').css({
+                       display: 'none'
+               });
+               $(g.bDiv).append(g.iDiv);
+               // add flexigrid events
+               $(g.bDiv).hover(function () {
+                       $(g.nDiv).hide();
+                       $(g.nBtn).hide();
+               }, function () {
+                       if (g.multisel) {
+                               g.multisel = false;
+                       }
+               });
+               $(g.gDiv).hover(function () {}, function () {
+                       $(g.nDiv).hide();
+                       $(g.nBtn).hide();
+               });
+               //add document events
+               $(document).mousemove(function (e) {
+                       g.dragMove(e);
+               }).mouseup(function (e) {
+                       g.dragEnd();
+               }).hover(function () {}, function () {
+                       g.dragEnd();
+               });
+               //browser adjustments
+               if (browser.msie && browser.version < 7.0) {
+                       $('.hDiv,.bDiv,.mDiv,.pDiv,.vGrip,.tDiv, .sDiv', g.gDiv).css({
+                               width: '100%'
+                       });
+                       $(g.gDiv).addClass('ie6');
+                       if (p.width != 'auto') {
+                               $(g.gDiv).addClass('ie6fullwidthbug');
+                       }
+               }
+               g.rePosDrag();
+               g.fixHeight();
+               //make grid functions accessible
+               t.p = p;
+               t.grid = g;
+               // load data
+               if (p.url && p.autoload) {
+                       g.populate();
+               }
+               return t;
+       };
+       var docloaded = false;
+       $(document).ready(function () {
+               docloaded = true;
+       });
+       $.fn.flexigrid = function (p) {
+               return this.each(function () {
+                       if (!docloaded) {
+                               $(this).hide();
+                               var t = this;
+                               $(document).ready(function () {
+                                       $.addFlex(t, p);
+                               });
+                       } else {
+                               $.addFlex(this, p);
+                       }
+               });
+       }; //end flexigrid
+       $.fn.flexReload = function (p) { // function to reload grid
+               return this.each(function () {
+                       if (this.grid && this.p.url) this.grid.populate();
+               });
+       }; //end flexReload
+       $.fn.flexOptions = function (p) { //function to update general options
+               return this.each(function () {
+                       if (this.grid) $.extend(this.p, p);
+               });
+       }; //end flexOptions
+       $.fn.flexToggleCol = function (cid, visible) { // function to reload grid
+               return this.each(function () {
+                       if (this.grid) this.grid.toggleCol(cid, visible);
+               });
+       }; //end flexToggleCol
+       $.fn.flexAddData = function (data) { // function to add data to grid
+               return this.each(function () {
+                       if (this.grid) this.grid.addData(data);
+               });
+       };
+       $.fn.noSelect = function (p) { //no select plugin by me :-)
+               var prevent = (p === null) ? true : p;
+               if (prevent) {
+                       return this.each(function () {
+                               if (browser.msie || browser.safari) $(this).bind('selectstart', function () {
+                                       return false;
+                               });
+                               else if (browser.mozilla) {
+                                       $(this).css('MozUserSelect', 'none');
+                                       $('body').trigger('focus');
+                               } else if (browser.opera) $(this).bind('mousedown', function () {
+                                       return false;
+                               });
+                               else $(this).attr('unselectable', 'on');
+                       });
+               } else {
+                       return this.each(function () {
+                               if (browser.msie || browser.safari) $(this).unbind('selectstart');
+                               else if (browser.mozilla) $(this).css('MozUserSelect', 'inherit');
+                               else if (browser.opera) $(this).unbind('mousedown');
+                               else $(this).removeAttr('unselectable', 'on');
+                       });
+               }
+       }; //end noSelect
+       $.fn.flexSearch = function(p) { // function to search grid
+               return this.each( function() { if (this.grid&&this.p.searchitems) this.grid.doSearch(); });
+       }; //end flexSearch
+       $.fn.selectedRows = function (p) { // Returns the selected rows as an array, taken and adapted from http://stackoverflow.com/questions/11868404/flexigrid-get-selected-row-columns-values
+               var arReturn = [];
+               var arRow = [];
+               var selector = $(this.selector + ' .trSelected');
+
+
+               $(selector).each(function (i, row) {
+                       arRow = [];
+                       var idr = $(row).data('id');
+                       $.each(row.cells, function (c, cell) {
+                               var col = cell.abbr;
+                               var val = cell.firstChild.innerHTML;
+                               if (val == '&nbsp;') val = '';      // Trim the content
+                               var idx = cell.cellIndex;                
+
+                               arRow.push({
+                                       Column: col,        // Column identifier
+                                       Value: val,         // Column value
+                                       CellIndex: idx,     // Cell index
+                                       RowIdentifier: idr  // Identifier of this row element
+                               });
+                       });
+                       arReturn.push(arRow);
+               });
+               return arReturn;
+       };
+})(jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.pack.js b/src/main/resources/META-INF/resources/designer/lib/flexigrid/js/flexigrid.pack.js
new file mode 100644 (file)
index 0000000..2f9ee95
--- /dev/null
@@ -0,0 +1 @@
+(function($){var browser=$.browser;if(!browser){function uaMatch(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}}var matched=uaMatch(navigator.userAgent);browser={};if(matched.browser){browser[matched.browser]=true;browser.version=matched.version}if(browser.chrome){browser.webkit=true}else if(browser.webkit){browser.safari=true}}if(typeof $.support.selectstart!="function"){$.support.selectstart="onselectstart"in document.createElement("div")}if(typeof $.fn.disableSelection!="function"){$.fn.disableSelection=function(){return this.bind(($.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})}}$.addFlex=function(t,p){if(t.grid)return false;p=$.extend({height:200,width:"auto",striped:true,novstripe:false,minwidth:30,minheight:80,resizable:true,url:false,method:"POST",dataType:"xml",errormsg:"Connection Error",usepager:false,nowrap:true,page:1,total:1,useRp:true,rp:15,rpOptions:[10,20,30,50,100],title:false,idProperty:"id",pagestat:"Displaying {from} to {to} of {total} items",pagetext:"Page",outof:"of",findtext:"Find",params:[],procmsg:"Processing, please wait ...",query:"",qtype:"",nomsg:"No items",minColToggle:1,showToggleBtn:true,hideOnSubmit:true,autoload:true,blockOpacity:.5,preProcess:false,addTitleToCell:false,dblClickResize:false,onDragCol:false,onToggleCol:false,onChangeSort:false,onDoubleClick:false,onSuccess:false,onError:false,onSubmit:false,__mw:{datacol:function(e,t,n){var r=typeof e.datacol[t]=="function"?e.datacol[t](n):n;if(typeof e.datacol["*"]=="function"){return e.datacol["*"](r)}else{return r}}},getGridClass:function(e){return e},datacol:{},colResize:true,colMove:true},p);$(t).show().attr({cellPadding:0,cellSpacing:0,border:0}).removeAttr("width");var g={hset:{},rePosDrag:function(){var e=0-this.hDiv.scrollLeft;if(this.hDiv.scrollLeft>0)e-=Math.floor(p.cgwidth/2);$(g.cDrag).css({top:g.hDiv.offsetTop+1});var t=this.cdpad;var n=0;$("div",g.cDrag).hide();$("thead tr:first th:visible",this.hDiv).each(function(){var r=$("thead tr:first th:visible",g.hDiv).index(this);var i=parseInt($("div",this).width());if(e==0)e-=Math.floor(p.cgwidth/2);i=i+e+t;if(isNaN(i)){i=0}$("div:eq("+r+")",g.cDrag).css({left:(!browser.mozilla?i-n:i)+"px"}).show();e=i;n++})},fixHeight:function(e){e=false;if(!e)e=$(g.bDiv).height();var t=$(this.hDiv).height();$("div",this.cDrag).each(function(){$(this).height(e+t)});var n=parseInt($(g.nDiv).height(),10);if(n>e)$(g.nDiv).height(e).width(200);else $(g.nDiv).height("auto").width("auto");$(g.block).css({height:e,marginBottom:e*-1});var r=g.bDiv.offsetTop+e;if(p.height!="auto"&&p.resizable)r=g.vDiv.offsetTop;$(g.rDiv).css({height:r})},dragStart:function(e,t,n){if(e=="colresize"&&p.colResize===true){$(g.nDiv).hide();$(g.nBtn).hide();var r=$("div",this.cDrag).index(n);var i=$("th:visible div:eq("+r+")",this.hDiv).width();$(n).addClass("dragging").siblings().hide();$(n).prev().addClass("dragging").show();this.colresize={startX:t.pageX,ol:parseInt(n.style.left,10),ow:i,n:r};$("body").css("cursor","col-resize")}else if(e=="vresize"){var s=false;$("body").css("cursor","row-resize");if(n){s=true;$("body").css("cursor","col-resize")}this.vresize={h:p.height,sy:t.pageY,w:p.width,sx:t.pageX,hgo:s}}else if(e=="colMove"){$(t.target).disableSelection();if(p.colMove===true){$(g.nDiv).hide();$(g.nBtn).hide();this.hset=$(this.hDiv).offset();this.hset.right=this.hset.left+$("table",this.hDiv).width();this.hset.bottom=this.hset.top+$("table",this.hDiv).height();this.dcol=n;this.dcoln=$("th",this.hDiv).index(n);this.colCopy=document.createElement("div");this.colCopy.className="colCopy";this.colCopy.innerHTML=n.innerHTML;if(browser.msie){this.colCopy.className="colCopy ie"}$(this.colCopy).css({position:"absolute","float":"left",display:"none",textAlign:n.align});$("body").append(this.colCopy);$(this.cDrag).hide()}}$("body").noSelect()},dragMove:function(e){if(this.colresize){var t=this.colresize.n;var n=e.pageX-this.colresize.startX;var r=this.colresize.ol+n;var i=this.colresize.ow+n;if(i>p.minwidth){$("div:eq("+t+")",this.cDrag).css("left",r);this.colresize.nw=i}}else if(this.vresize){var s=this.vresize;var o=e.pageY;var n=o-s.sy;if(!p.defwidth)p.defwidth=p.width;if(p.width!="auto"&&!p.nohresize&&s.hgo){var u=e.pageX;var a=u-s.sx;var f=s.w+a;if(f>p.defwidth){this.gDiv.style.width=f+"px";p.width=f}}var l=s.h+n;if((l>p.minheight||p.height<p.minheight)&&!s.hgo){this.bDiv.style.height=l+"px";p.height=l;this.fixHeight(l)}s=null}else if(this.colCopy){$(this.dcol).addClass("thMove").removeClass("thOver");if(e.pageX>this.hset.right||e.pageX<this.hset.left||e.pageY>this.hset.bottom||e.pageY<this.hset.top){$("body").css("cursor","move")}else{$("body").css("cursor","pointer")}$(this.colCopy).css({top:e.pageY+10,left:e.pageX+20,display:"block"})}},dragEnd:function(){if(this.colresize){var e=this.colresize.n;var t=this.colresize.nw;$("th:visible div:eq("+e+")",this.hDiv).css("width",t);$("tr",this.bDiv).each(function(){var n=$("td:visible div:eq("+e+")",this);n.css("width",t);g.addTitleToCell(n)});this.hDiv.scrollLeft=this.bDiv.scrollLeft;$("div:eq("+e+")",this.cDrag).siblings().show();$(".dragging",this.cDrag).removeClass("dragging");this.rePosDrag();this.fixHeight();this.colresize=false;if($.cookies){var n=p.colModel[e].name;$.cookie("flexiwidths/"+n,t)}}else if(this.vresize){this.vresize=false}else if(this.colCopy){$(this.colCopy).remove();if(this.dcolt!==null){if(this.dcoln>this.dcolt)$("th:eq("+this.dcolt+")",this.hDiv).before(this.dcol);else $("th:eq("+this.dcolt+")",this.hDiv).after(this.dcol);this.switchCol(this.dcoln,this.dcolt);$(this.cdropleft).remove();$(this.cdropright).remove();this.rePosDrag();if(p.onDragCol){p.onDragCol(this.dcoln,this.dcolt)}}this.dcol=null;this.hset=null;this.dcoln=null;this.dcolt=null;this.colCopy=null;$(".thMove",this.hDiv).removeClass("thMove");$(this.cDrag).show()}$("body").css("cursor","default");$("body").noSelect(false)},toggleCol:function(e,n){var r=$("th[axis='col"+e+"']",this.hDiv)[0];var i=$("thead th",g.hDiv).index(r);var s=$("input[value="+e+"]",g.nDiv)[0];if(n==null){n=r.hidden}if($("input:checked",g.nDiv).length<p.minColToggle&&!n){return false}if(n){r.hidden=false;$(r).show();s.checked=true}else{r.hidden=true;$(r).hide();s.checked=false}$("tbody tr",t).each(function(){if(n){$("td:eq("+i+")",this).show()}else{$("td:eq("+i+")",this).hide()}});this.rePosDrag();if(p.onToggleCol){p.onToggleCol(e,n)}return n},switchCol:function(e,n){$("tbody tr",t).each(function(){if(e>n)$("td:eq("+n+")",this).before($("td:eq("+e+")",this));else $("td:eq("+n+")",this).after($("td:eq("+e+")",this))});if(e>n){$("tr:eq("+n+")",this.nDiv).before($("tr:eq("+e+")",this.nDiv))}else{$("tr:eq("+n+")",this.nDiv).after($("tr:eq("+e+")",this.nDiv))}if(browser.msie&&browser.version<7){$("tr:eq("+n+") input",this.nDiv)[0].checked=true}this.hDiv.scrollLeft=this.bDiv.scrollLeft},scroll:function(){this.hDiv.scrollLeft=this.bDiv.scrollLeft;this.rePosDrag()},addData:function(e){if(p.dataType=="json"){e=$.extend({rows:[],page:0,total:0},e)}if(p.preProcess){e=p.preProcess(e)}$(".pReload",this.pDiv).removeClass("loading");this.loading=false;if(!e){$(".pPageStat",this.pDiv).html(p.errormsg);if(p.onSuccess)p.onSuccess(this);return false}if(p.dataType=="xml"){p.total=+$("rows total",e).text()}else{p.total=e.total}if(p.total===0){$("tr, a, td, div",t).unbind();$(t).empty();p.pages=1;p.page=1;this.buildpager();$(".pPageStat",this.pDiv).html(p.nomsg);if(p.onSuccess)p.onSuccess(this);return false}p.pages=Math.ceil(p.total/p.rp);if(p.dataType=="xml"){p.page=+$("rows page",e).text()}else{p.page=e.page}this.buildpager();var n=document.createElement("tbody");if(p.dataType=="json"){$.each(e.rows,function(e,t){var r=document.createElement("tr");var i=$(r);if(t.name)r.name=t.name;if(t.color){i.css("background",t.color)}else{if(e%2&&p.striped)r.className="erow"}if(t[p.idProperty]){r.id="row"+t[p.idProperty];i.attr("data-id",t[p.idProperty])}$("thead tr:first th",g.hDiv).each(function(){var e=document.createElement("td");var n=$(this).attr("axis").substr(3);e.align=this.align;if(typeof t.cell=="undefined"){e.innerHTML=t[p.colModel[n].name]}else{var i="";if(typeof t.cell[n]!="undefined"){i=t.cell[n]!==null?t.cell[n]:""}else{i=t.cell[p.colModel[n].name]}e.innerHTML=p.__mw.datacol(p,$(this).attr("abbr"),i)}var s=e.innerHTML.indexOf("<BGCOLOR=");if(s>0){$(e).css("background",text.substr(s+7,7))}$(e).attr("abbr",$(this).attr("abbr"));$(r).append(e);e=null});if($("thead",this.gDiv).length<1){for(idx=0;idx<t.cell.length;idx++){var s=document.createElement("td");if(typeof t.cell[idx]!="undefined"){s.innerHTML=t.cell[idx]!=null?t.cell[idx]:""}else{s.innerHTML=t.cell[p.colModel[idx].name]}$(r).append(s);s=null}}$(n).append(r);r=null})}else if(p.dataType=="xml"){var r=1;$("rows row",e).each(function(){r++;var e=document.createElement("tr");if($(this).attr("name"))e.name=$(this).attr("name");if($(this).attr("color")){$(e).css("background",$(this).attr("id"))}else{if(r%2&&p.striped)e.className="erow"}var t=$(this).attr("id");if(t){e.id="row"+t}t=null;var s=this;$("thead tr:first th",g.hDiv).each(function(){var t=document.createElement("td");var n=$(this).attr("axis").substr(3);t.align=this.align;var r=$("cell:eq("+n+")",s).text();var i=r.indexOf("<BGCOLOR=");if(i>0){$(t).css("background",r.substr(i+7,7))}t.innerHTML=p.__mw.datacol(p,$(this).attr("abbr"),r);$(t).attr("abbr",$(this).attr("abbr"));$(e).append(t);t=null});if($("thead",this.gDiv).length<1){$("cell",this).each(function(){var t=document.createElement("td");t.innerHTML=$(this).text();$(e).append(t);t=null})}$(n).append(e);e=null;s=null})}$("tr",t).unbind();$(t).empty();$(t).append(n);this.addCellProp();this.addRowProp();this.rePosDrag();n=null;e=null;r=null;if(p.onSuccess){p.onSuccess(this)}if(p.hideOnSubmit){$(g.block).remove()}this.hDiv.scrollLeft=this.bDiv.scrollLeft;if(browser.opera){$(t).css("visibility","visible")}},changeSort:function(e){if(this.loading){return true}$(g.nDiv).hide();$(g.nBtn).hide();if(p.sortname==$(e).attr("abbr")){if(p.sortorder=="asc"){p.sortorder="desc"}else{p.sortorder="asc"}}$(e).addClass("sorted").siblings().removeClass("sorted");$(".sdesc",this.hDiv).removeClass("sdesc");$(".sasc",this.hDiv).removeClass("sasc");$("div",e).addClass("s"+p.sortorder);p.sortname=$(e).attr("abbr");if(p.onChangeSort){p.onChangeSort(p.sortname,p.sortorder)}else{this.populate()}},buildpager:function(){$(".pcontrol input",this.pDiv).val(p.page);$(".pcontrol span",this.pDiv).html(p.pages);var e=(p.page-1)*p.rp+1;var t=e+p.rp-1;if(p.total<t){t=p.total}var n=p.pagestat;n=n.replace(/{from}/,e);n=n.replace(/{to}/,t);n=n.replace(/{total}/,p.total);$(".pPageStat",this.pDiv).html(n)},populate:function(){if(this.loading){return true}if(p.onSubmit){var e=p.onSubmit();if(!e){return false}}this.loading=true;if(!p.url){return false}$(".pPageStat",this.pDiv).html(p.procmsg);$(".pReload",this.pDiv).addClass("loading");$(g.block).css({top:g.bDiv.offsetTop});if(p.hideOnSubmit){$(this.gDiv).prepend(g.block)}if(browser.opera){$(t).css("visibility","hidden")}if(!p.newp){p.newp=1}if(p.page>p.pages){p.page=p.pages}var n=[{name:"page",value:p.newp},{name:"rp",value:p.rp},{name:"sortname",value:p.sortname},{name:"sortorder",value:p.sortorder},{name:"query",value:p.query},{name:"qtype",value:p.qtype}];if(p.params.length){for(var r=0;r<p.params.length;r++){n[n.length]=p.params[r]}}$.ajax({type:p.method,url:p.url,data:n,dataType:p.dataType,success:function(e){g.addData(e)},error:function(e,t,n){try{if(p.onError)p.onError(e,t,n)}catch(r){}}})},doSearch:function(){p.query=$("input[name=q]",g.sDiv).val();p.qtype=$("select[name=qtype]",g.sDiv).val();p.newp=1;this.populate()},changePage:function(e){if(this.loading){return true}switch(e){case"first":p.newp=1;break;case"prev":if(p.page>1){p.newp=parseInt(p.page,10)-1}break;case"next":if(p.page<p.pages){p.newp=parseInt(p.page,10)+1}break;case"last":p.newp=p.pages;break;case"input":var t=parseInt($(".pcontrol input",this.pDiv).val(),10);if(isNaN(t)){t=1}if(t<1){t=1}else if(t>p.pages){t=p.pages}$(".pcontrol input",this.pDiv).val(t);p.newp=t;break}if(p.newp==p.page){return false}if(p.onChangePage){p.onChangePage(p.newp)}else{this.populate()}},addCellProp:function(){$("tbody tr td",g.bDiv).each(function(){var e=document.createElement("div");var t=$("td",$(this).parent()).index(this);var n=$("th:eq("+t+")",g.hDiv).get(0);if(n!=null){if(p.sortname==$(n).attr("abbr")&&p.sortname){this.className="sorted"}$(e).css({textAlign:n.align,width:$("div:first",n)[0].style.width});if(n.hidden){$(this).css("display","none")}}if(p.nowrap==false){$(e).css("white-space","normal")}if(this.innerHTML==""){this.innerHTML=" "}e.innerHTML=this.innerHTML;var r=$(this).parent()[0];var i=false;if(r.id){i=r.id.substr(3)}if(n!=null){if(n.process)n.process(e,i)}$(this).empty().append(e).removeAttr("width");g.addTitleToCell(e)})},getCellDim:function(e){var t=parseInt($(e).height(),10);var n=parseInt($(e).parent().height(),10);var r=parseInt(e.style.width,10);var i=parseInt($(e).parent().width(),10);var s=e.offsetParent.offsetTop;var o=e.offsetParent.offsetLeft;var u=parseInt($(e).css("paddingLeft"),10);var a=parseInt($(e).css("paddingTop"),10);return{ht:t,wt:r,top:s,left:o,pdl:u,pdt:a,pht:n,pwt:i}},addRowProp:function(){$("tbody tr",g.bDiv).on("click",function(e){var t=e.target||e.srcElement;if(t.href||t.type)return true;if(e.ctrlKey||e.metaKey){return}$(this).toggleClass("trSelected");if(p.singleSelect&&!g.multisel){$(this).siblings().removeClass("trSelected")}}).on("mousedown",function(e){if(e.shiftKey){$(this).toggleClass("trSelected");g.multisel=true;this.focus();$(g.gDiv).noSelect()}if(e.ctrlKey||e.metaKey){$(this).toggleClass("trSelected");g.multisel=true;this.focus()}}).on("mouseup",function(e){if(g.multisel&&!(e.ctrlKey||e.metaKey)){g.multisel=false;$(g.gDiv).noSelect(false)}}).on("dblclick",function(){$(this).addClass("trSelected");if(p.onDoubleClick){p.onDoubleClick(this,g,p)}}).hover(function(e){if(g.multisel&&e.shiftKey){$(this).toggleClass("trSelected")}},function(){});if(browser.msie&&browser.version<7){$(this).hover(function(){$(this).addClass("trOver")},function(){$(this).removeClass("trOver")})}},combo_flag:true,combo_resetIndex:function(e){if(this.combo_flag){e.selectedIndex=0}this.combo_flag=true},combo_doSelectAction:function(selObj){eval(selObj.options[selObj.selectedIndex].value);selObj.selectedIndex=0;this.combo_flag=false},addTitleToCell:function(e){if(p.addTitleToCell){var t=$("<span />").css("display","none"),n=e instanceof jQuery?e:$(e),r=n.outerWidth(),i=0;$("body").children(":first").before(t);t.html(n.html());t.css("font-size",""+n.css("font-size"));t.css("padding-left",""+n.css("padding-left"));i=t.innerWidth();t.remove();if(i>r){n.attr("title",n.text())}else{n.removeAttr("title")}}},autoResizeColumn:function(e){if(!p.dblClickResize){return}var t=$("div",this.cDrag).index(e),n=$("th:visible div:eq("+t+")",this.hDiv),r=parseInt(e.style.left,10),i=n.width(),s=0,o=0,u=$("<span />");$("body").children(":first").before(u);u.html(n.html());u.css("font-size",""+n.css("font-size"));u.css("padding-left",""+n.css("padding-left"));u.css("padding-right",""+n.css("padding-right"));s=u.width();$("tr",this.bDiv).each(function(){var e=$("td:visible div:eq("+t+")",this),n=0;u.html(e.html());u.css("font-size",""+e.css("font-size"));u.css("padding-left",""+e.css("padding-left"));u.css("padding-right",""+e.css("padding-right"));n=u.width();s=n>s?n:s});u.remove();s=p.minWidth>s?p.minWidth:s;o=r+(s-i);$("div:eq("+t+")",this.cDrag).css("left",o);this.colresize={nw:s,n:t};g.dragEnd()},pager:0};g=p.getGridClass(g);if(p.colModel){thead=document.createElement("thead");var tr=document.createElement("tr");for(var i=0;i<p.colModel.length;i++){var cm=p.colModel[i];var th=document.createElement("th");$(th).attr("axis","col"+i);if(cm){if($.cookies){var cookie_width="flexiwidths/"+cm.name;if($.cookie(cookie_width)!=undefined){cm.width=$.cookie(cookie_width)}}if(cm.display!=undefined){th.innerHTML=cm.display}if(cm.name&&cm.sortable){$(th).attr("abbr",cm.name)}if(cm.align){th.align=cm.align}if(cm.width){$(th).attr("width",cm.width)}if($(cm).attr("hide")){th.hidden=true}if(cm.process){th.process=cm.process}}else{th.innerHTML="";$(th).attr("width",30)}$(tr).append(th)}$(thead).append(tr);$(t).prepend(thead)}g.gDiv=document.createElement("div");g.mDiv=document.createElement("div");g.hDiv=document.createElement("div");g.bDiv=document.createElement("div");g.vDiv=document.createElement("div");g.rDiv=document.createElement("div");g.cDrag=document.createElement("div");g.block=document.createElement("div");g.nDiv=document.createElement("div");g.nBtn=document.createElement("div");g.iDiv=document.createElement("div");g.tDiv=document.createElement("div");g.sDiv=document.createElement("div");g.pDiv=document.createElement("div");if(p.colResize===false){$(g.cDrag).css("display","none")}if(!p.usepager){g.pDiv.style.display="none"}g.hTable=document.createElement("table");g.gDiv.className="flexigrid";if(p.width!="auto"){g.gDiv.style.width=p.width+(isNaN(p.width)?"":"px")}if(browser.msie){$(g.gDiv).addClass("ie")}if(p.novstripe){$(g.gDiv).addClass("novstripe")}$(t).before(g.gDiv);$(g.gDiv).append(t);if(p.buttons){g.tDiv.className="tDiv";var tDiv2=document.createElement("div");tDiv2.className="tDiv2";for(var i=0;i<p.buttons.length;i++){var btn=p.buttons[i];if(!btn.separator){var btnDiv=document.createElement("div");btnDiv.className="fbutton";btnDiv.innerHTML="<div><span>"+(btn.hidename?" ":btn.name)+"</span></div>";if(btn.bclass)$("span",btnDiv).addClass(btn.bclass).css({paddingLeft:20});if(btn.bimage)$("span",btnDiv).css("background","url("+btn.bimage+") no-repeat center left");$("span",btnDiv).css("paddingLeft",20);if(btn.tooltip)$("span",btnDiv)[0].title=btn.tooltip;btnDiv.onpress=btn.onpress;btnDiv.name=btn.name;if(btn.id){btnDiv.id=btn.id}if(btn.onpress){$(btnDiv).click(function(){this.onpress(this.id||this.name,g.gDiv)})}$(tDiv2).append(btnDiv);if(browser.msie&&browser.version<7){$(btnDiv).hover(function(){$(this).addClass("fbOver")},function(){$(this).removeClass("fbOver")})}}else{$(tDiv2).append("<div class='btnseparator'></div>")}}$(g.tDiv).append(tDiv2);$(g.tDiv).append("<div style='clear:both'></div>");$(g.gDiv).prepend(g.tDiv)}g.hDiv.className="hDiv";if(p.combobuttons&&$(g.tDiv2)){var btnDiv=document.createElement("div");btnDiv.className="fbutton";var tSelect=document.createElement("select");$(tSelect).change(function(){g.combo_doSelectAction(tSelect)});$(tSelect).click(function(){g.combo_resetIndex(tSelect)});tSelect.className="cselect";$(btnDiv).append(tSelect);for(i=0;i<p.combobuttons.length;i++){var btn=p.combobuttons[i];if(!btn.separator){var btnOpt=document.createElement("option");btnOpt.innerHTML=btn.name;if(btn.bclass)$(btnOpt).addClass(btn.bclass).css({paddingLeft:20});if(btn.bimage)$(btnOpt).css("background","url("+btn.bimage+") no-repeat center left");$(btnOpt).css("paddingLeft",20);if(btn.tooltip)$(btnOpt)[0].title=btn.tooltip;if(btn.onpress){btnOpt.value=btn.onpress}$(tSelect).append(btnOpt)}}$(".tDiv2").append(btnDiv)}$(t).before(g.hDiv);g.hTable.cellPadding=0;g.hTable.cellSpacing=0;$(g.hDiv).append('<div class="hDivBox"></div>');$("div",g.hDiv).append(g.hTable);var thead=$("thead:first",t).get(0);if(thead)$(g.hTable).append(thead);thead=null;if(!p.colmodel)var ci=0;$("thead tr:first th",g.hDiv).each(function(){var e=document.createElement("div");if($(this).attr("abbr")){$(this).click(function(e){if(!$(this).hasClass("thOver"))return false;var t=e.target||e.srcElement;if(t.href||t.type)return true;g.changeSort(this)});if($(this).attr("abbr")==p.sortname){this.className="sorted";e.className="s"+p.sortorder}}if(this.hidden){$(this).hide()}if(!p.colmodel){$(this).attr("axis","col"+ci++)}if(this.width==""){this.width=100}$(e).css({textAlign:this.align,width:this.width+"px"});e.innerHTML=this.innerHTML;$(this).empty().append(e).removeAttr("width").mousedown(function(e){g.dragStart("colMove",e,this)}).hover(function(){if(!g.colresize&&!$(this).hasClass("thMove")&&!g.colCopy){$(this).addClass("thOver")}if($(this).attr("abbr")!=p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr("abbr")){$("div",this).addClass("s"+p.sortorder)}else if($(this).attr("abbr")==p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr("abbr")){var e=p.sortorder=="asc"?"desc":"asc";$("div",this).removeClass("s"+p.sortorder).addClass("s"+e)}if(g.colCopy){var t=$("th",g.hDiv).index(this);if(t==g.dcoln){return false}if(t<g.dcoln){$(this).append(g.cdropleft)}else{$(this).append(g.cdropright)}g.dcolt=t}else if(!g.colresize){var n=$("th:visible",g.hDiv).index(this);var r=parseInt($("div:eq("+n+")",g.cDrag).css("left"),10);var i=jQuery(g.nBtn).outerWidth();var s=r-i+Math.floor(p.cgwidth/2);$(g.nDiv).hide();$(g.nBtn).hide();$(g.nBtn).css({left:s,top:g.hDiv.offsetTop}).show();var o=parseInt($(g.nDiv).width(),10);$(g.nDiv).css({top:g.bDiv.offsetTop});if(s+o>$(g.gDiv).width()){$(g.nDiv).css("left",r-o+1)}else{$(g.nDiv).css("left",s)}if($(this).hasClass("sorted")){$(g.nBtn).addClass("srtd")}else{$(g.nBtn).removeClass("srtd")}}},function(){$(this).removeClass("thOver");if($(this).attr("abbr")!=p.sortname){$("div",this).removeClass("s"+p.sortorder)}else if($(this).attr("abbr")==p.sortname){var e=p.sortorder=="asc"?"desc":"asc";$("div",this).addClass("s"+p.sortorder).removeClass("s"+e)}if(g.colCopy){$(g.cdropleft).remove();$(g.cdropright).remove();g.dcolt=null}})});g.bDiv.className="bDiv";$(t).before(g.bDiv);$(g.bDiv).css({height:p.height=="auto"?"auto":p.height+"px"}).scroll(function(e){g.scroll()}).append(t);if(p.height=="auto"){$("table",g.bDiv).addClass("autoht")}g.addCellProp();g.addRowProp();if(p.colResize===true){var cdcol=$("thead tr:first th:first",g.hDiv).get(0);if(cdcol!==null){g.cDrag.className="cDrag";g.cdpad=0;g.cdpad+=isNaN(parseInt($("div",cdcol).css("borderLeftWidth"),10))?0:parseInt($("div",cdcol).css("borderLeftWidth"),10);g.cdpad+=isNaN(parseInt($("div",cdcol).css("borderRightWidth"),10))?0:parseInt($("div",cdcol).css("borderRightWidth"),10);g.cdpad+=isNaN(parseInt($("div",cdcol).css("paddingLeft"),10))?0:parseInt($("div",cdcol).css("paddingLeft"),10);g.cdpad+=isNaN(parseInt($("div",cdcol).css("paddingRight"),10))?0:parseInt($("div",cdcol).css("paddingRight"),10);g.cdpad+=isNaN(parseInt($(cdcol).css("borderLeftWidth"),10))?0:parseInt($(cdcol).css("borderLeftWidth"),10);g.cdpad+=isNaN(parseInt($(cdcol).css("borderRightWidth"),10))?0:parseInt($(cdcol).css("borderRightWidth"),10);g.cdpad+=isNaN(parseInt($(cdcol).css("paddingLeft"),10))?0:parseInt($(cdcol).css("paddingLeft"),10);g.cdpad+=isNaN(parseInt($(cdcol).css("paddingRight"),10))?0:parseInt($(cdcol).css("paddingRight"),10);$(g.bDiv).before(g.cDrag);var cdheight=$(g.bDiv).height();var hdheight=$(g.hDiv).height();$(g.cDrag).css({top:-hdheight+"px"});$("thead tr:first th",g.hDiv).each(function(){var e=document.createElement("div");$(g.cDrag).append(e);if(!p.cgwidth){p.cgwidth=$(e).width()}$(e).css({height:cdheight+hdheight}).mousedown(function(e){g.dragStart("colresize",e,this)}).dblclick(function(e){g.autoResizeColumn(this)});if(browser.msie&&browser.version<7){g.fixHeight($(g.gDiv).height());$(e).hover(function(){g.fixHeight();$(this).addClass("dragging")},function(){if(!g.colresize){$(this).removeClass("dragging")}})}})}}if(p.striped){$("tbody tr:odd",g.bDiv).addClass("erow")}if(p.resizable&&p.height!="auto"){g.vDiv.className="vGrip";$(g.vDiv).mousedown(function(e){g.dragStart("vresize",e)}).html("<span></span>");$(g.bDiv).after(g.vDiv)}if(p.resizable&&p.width!="auto"&&!p.nohresize){g.rDiv.className="hGrip";$(g.rDiv).mousedown(function(e){g.dragStart("vresize",e,true)}).html("<span></span>").css("height",$(g.gDiv).height());if(browser.msie&&browser.version<7){$(g.rDiv).hover(function(){$(this).addClass("hgOver")},function(){$(this).removeClass("hgOver")})}$(g.gDiv).append(g.rDiv)}if(p.usepager){g.pDiv.className="pDiv";g.pDiv.innerHTML='<div class="pDiv2"></div>';$(g.bDiv).after(g.pDiv);var html=' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">'+p.pagetext+' <input type="text" size="4" value="1" /> '+p.outof+' <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';$("div",g.pDiv).html(html);$(".pReload",g.pDiv).click(function(){g.populate()});$(".pFirst",g.pDiv).click(function(){g.changePage("first")});$(".pPrev",g.pDiv).click(function(){g.changePage("prev")});$(".pNext",g.pDiv).click(function(){g.changePage("next")});$(".pLast",g.pDiv).click(function(){g.changePage("last")});$(".pcontrol input",g.pDiv).keydown(function(e){if(e.keyCode==13){g.changePage("input")}});if(browser.msie&&browser.version<7)$(".pButton",g.pDiv).hover(function(){$(this).addClass("pBtnOver")},function(){$(this).removeClass("pBtnOver")});if(p.useRp){var opt="",sel="";for(var nx=0;nx<p.rpOptions.length;nx++){if(p.rp==p.rpOptions[nx])sel='selected="selected"';else sel="";opt+="<option value='"+p.rpOptions[nx]+"' "+sel+" >"+p.rpOptions[nx]+"  </option>"}$(".pDiv2",g.pDiv).prepend("<div class='pGroup'><select name='rp'>"+opt+"</select></div> <div class='btnseparator'></div>");$("select",g.pDiv).change(function(){if(p.onRpChange){p.onRpChange(+this.value)}else{p.newp=1;p.rp=+this.value;g.populate()}})}if(p.searchitems){$(".pDiv2",g.pDiv).prepend("<div class='pGroup'> <div class='pSearch pButton'><span></span></div> </div>  <div class='btnseparator'></div>");$(".pSearch",g.pDiv).click(function(){$(g.sDiv).slideToggle("fast",function(){$(".sDiv:visible input:first",g.gDiv).trigger("focus")})});g.sDiv.className="sDiv";var sitems=p.searchitems;var sopt="",sel="";for(var s=0;s<sitems.length;s++){if(p.qtype===""&&sitems[s].isdefault===true){p.qtype=sitems[s].name;sel='selected="selected"'}else{sel=""}sopt+="<option value='"+sitems[s].name+"' "+sel+" >"+sitems[s].display+"  </option>"}if(p.qtype===""){p.qtype=sitems[0].name}$(g.sDiv).append("<div class='sDiv2'>"+p.findtext+" <input type='text' value='"+p.query+"' size='30' name='q' class='qsbox' /> "+" <select name='qtype'>"+sopt+"</select></div>");$("input[name=q]",g.sDiv).keydown(function(e){if(e.keyCode==13){g.doSearch()}});$("select[name=qtype]",g.sDiv).keydown(function(e){if(e.keyCode==13){g.doSearch()}});$("input[value=Clear]",g.sDiv).click(function(){$("input[name=q]",g.sDiv).val("");p.query="";g.doSearch()});$(g.bDiv).after(g.sDiv)}}$(g.pDiv,g.sDiv).append("<div style='clear:both'></div>");if(p.title){g.mDiv.className="mDiv";g.mDiv.innerHTML='<div class="ftitle">'+p.title+"</div>";$(g.gDiv).prepend(g.mDiv);if(p.showTableToggleBtn){$(g.mDiv).append('<div class="ptogtitle" title="Minimize/Maximize Table"><span></span></div>');$("div.ptogtitle",g.mDiv).click(function(){$(g.gDiv).toggleClass("hideBody");$(this).toggleClass("vsble")})}}g.cdropleft=document.createElement("span");g.cdropleft.className="cdropleft";g.cdropright=document.createElement("span");g.cdropright.className="cdropright";g.block.className="gBlock";var gh=$(g.bDiv).height();var gtop=g.bDiv.offsetTop;$(g.block).css({width:g.bDiv.style.width,height:gh,background:"white",position:"relative",marginBottom:gh*-1,zIndex:1,top:gtop,left:"0px"});$(g.block).fadeTo(0,p.blockOpacity);if($("th",g.hDiv).length){g.nDiv.className="nDiv";g.nDiv.innerHTML="<table cellpadding='0' cellspacing='0'><tbody></tbody></table>";$(g.nDiv).css({marginBottom:gh*-1,display:"none",top:gtop}).noSelect();var cn=0;$("th div",g.hDiv).each(function(){var e=$("th[axis='col"+cn+"']",g.hDiv)[0];var t='checked="checked"';if(e.style.display=="none"){t=""}$("tbody",g.nDiv).append('<tr><td class="ndcol1"><input type="checkbox" '+t+' class="togCol" value="'+cn+'" /></td><td class="ndcol2">'+this.innerHTML+"</td></tr>");cn++});if(browser.msie&&browser.version<7)$("tr",g.nDiv).hover(function(){$(this).addClass("ndcolover")},function(){$(this).removeClass("ndcolover")});$("td.ndcol2",g.nDiv).click(function(){if($("input:checked",g.nDiv).length<=p.minColToggle&&$(this).prev().find("input")[0].checked)return false;return g.toggleCol($(this).prev().find("input").val())});$("input.togCol",g.nDiv).click(function(){if($("input:checked",g.nDiv).length<p.minColToggle&&this.checked===false)return false;$(this).parent().next().trigger("click")});$(g.gDiv).prepend(g.nDiv);$(g.nBtn).addClass("nBtn").html("<div></div>").attr("title","Hide/Show Columns").click(function(){$(g.nDiv).toggle();return true});if(p.showToggleBtn){$(g.gDiv).prepend(g.nBtn)}}$(g.iDiv).addClass("iDiv").css({display:"none"});$(g.bDiv).append(g.iDiv);$(g.bDiv).hover(function(){$(g.nDiv).hide();$(g.nBtn).hide()},function(){if(g.multisel){g.multisel=false}});$(g.gDiv).hover(function(){},function(){$(g.nDiv).hide();$(g.nBtn).hide()});$(document).mousemove(function(e){g.dragMove(e)}).mouseup(function(e){g.dragEnd()}).hover(function(){},function(){g.dragEnd()});if(browser.msie&&browser.version<7){$(".hDiv,.bDiv,.mDiv,.pDiv,.vGrip,.tDiv, .sDiv",g.gDiv).css({width:"100%"});$(g.gDiv).addClass("ie6");if(p.width!="auto"){$(g.gDiv).addClass("ie6fullwidthbug")}}g.rePosDrag();g.fixHeight();t.p=p;t.grid=g;if(p.url&&p.autoload){g.populate()}return t};var docloaded=false;$(document).ready(function(){docloaded=true});$.fn.flexigrid=function(e){return this.each(function(){if(!docloaded){$(this).hide();var t=this;$(document).ready(function(){$.addFlex(t,e)})}else{$.addFlex(this,e)}})};$.fn.flexReload=function(e){return this.each(function(){if(this.grid&&this.p.url)this.grid.populate()})};$.fn.flexOptions=function(e){return this.each(function(){if(this.grid)$.extend(this.p,e)})};$.fn.flexToggleCol=function(e,t){return this.each(function(){if(this.grid)this.grid.toggleCol(e,t)})};$.fn.flexAddData=function(e){return this.each(function(){if(this.grid)this.grid.addData(e)})};$.fn.noSelect=function(e){var t=e===null?true:e;if(t){return this.each(function(){if(browser.msie||browser.safari)$(this).bind("selectstart",function(){return false});else if(browser.mozilla){$(this).css("MozUserSelect","none");$("body").trigger("focus")}else if(browser.opera)$(this).bind("mousedown",function(){return false});else $(this).attr("unselectable","on")})}else{return this.each(function(){if(browser.msie||browser.safari)$(this).unbind("selectstart");else if(browser.mozilla)$(this).css("MozUserSelect","inherit");else if(browser.opera)$(this).unbind("mousedown");else $(this).removeAttr("unselectable","on")})}};$.fn.flexSearch=function(e){return this.each(function(){if(this.grid&&this.p.searchitems)this.grid.doSearch()})};$.fn.selectedRows=function(e){var t=[];var n=[];var r=$(this.selector+" .trSelected");$(r).each(function(e,r){n=[];var i=$(r).data("id");$.each(r.cells,function(e,t){var r=t.abbr;var s=t.firstChild.innerHTML;if(s==" ")s="";var o=t.cellIndex;n.push({Column:r,Value:s,CellIndex:o,RowIdentifier:i})});t.push(n)});return t}})(jQuery)
diff --git a/src/main/resources/META-INF/resources/designer/lib/index.js b/src/main/resources/META-INF/resources/designer/lib/index.js
new file mode 100644 (file)
index 0000000..0a66133
--- /dev/null
@@ -0,0 +1,52 @@
+$(function() {
+       var $wrapper = $('#wrapper');
+
+       // theme switcher
+       var theme_match = String(window.location).match(/[?&]theme=([a-z0-9]+)/);
+       var theme = (theme_match && theme_match[1]) || 'default';
+       var themes = ['default','legacy','bootstrap2','bootstrap3'];
+       $('head').append('<link rel="stylesheet" href="css/selectize.' + theme + '.css">');
+
+       var $themes = $('<div>').addClass('theme-selector').insertAfter('h1');
+       for (var i = 0; i < themes.length; i++) {
+               $themes.append('<a href="?theme=' + themes[i] + '"' + (themes[i] === theme ? ' class="active"' : '') + '>' + themes[i] + '</a>');
+       }
+
+       // display scripts on the page
+       $('script', $wrapper).each(function() 
+       {
+               var code = this.text;
+               if (code && code.length) {
+                       var lines = code.split('\n');
+                       var indent = null;
+
+                       for (var i = 0; i < lines.length; i++) {
+                               if (/^[  ]*$/.test(lines[i])) continue;
+                               if (!indent) {
+                                       var lineindent = lines[i].match(/^([    ]+)/);
+                                       if (!lineindent) break;
+                                       indent = lineindent[1];
+                               }
+                               lines[i] = lines[i].replace(new RegExp('^' + indent), '');
+                       }
+
+                       var code = $.trim(lines.join('\n')).replace(/   /g, '    ');
+                       var $pre = $('<pre>').addClass('js').text(code);
+                       $pre.insertAfter(this);
+               }
+       });
+
+       // show current input values
+       $('select.selectized,input.selectized', $wrapper).each(function() 
+    {
+               var $container = $('<div>').addClass('value').html('Current Value: ');
+               var $value = $('<span>').appendTo($container);
+               var $input = $(this);
+               var update = function(e) { $value.text(JSON.stringify($input.val())); }
+
+               $(this).on('change', update);
+               update();
+
+               $container.insertAfter($input);
+       });
+});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.js b/src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.js
new file mode 100644 (file)
index 0000000..9e7b219
--- /dev/null
@@ -0,0 +1,1024 @@
+/*!
+ * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
+ * Copyright 2012-2014 Arnold Daniels
+ * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
+ */
+
+if (typeof jQuery === 'undefined') { throw new Error('Jasny Bootstrap\'s JavaScript requires jQuery') }
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.1.3
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+  'use strict';
+
+  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+  // ============================================================
+
+  function transitionEnd() {
+    var el = document.createElement('bootstrap')
+
+    var transEndEventNames = {
+      WebkitTransition : 'webkitTransitionEnd',
+      MozTransition    : 'transitionend',
+      OTransition      : 'oTransitionEnd otransitionend',
+      transition       : 'transitionend'
+    }
+
+    for (var name in transEndEventNames) {
+      if (el.style[name] !== undefined) {
+        return { end: transEndEventNames[name] }
+      }
+    }
+
+    return false // explicit for ie8 (  ._.)
+  }
+
+  if ($.support.transition !== undefined) return  // Prevent conflict with Twitter Bootstrap
+
+  // http://blog.alexmaccaw.com/css-transitions
+  $.fn.emulateTransitionEnd = function (duration) {
+    var called = false, $el = this
+    $(this).one($.support.transition.end, function () { called = true })
+    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+    setTimeout(callback, duration)
+    return this
+  }
+
+  $(function () {
+    $.support.transition = transitionEnd()
+  })
+
+}(window.jQuery);
+
+/* ========================================================================
+ * Bootstrap: offcanvas.js v3.1.3
+ * http://jasny.github.io/bootstrap/javascript/#offcanvas
+ * ========================================================================
+ * Copyright 2013-2014 Arnold Daniels
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ======================================================================== */
+
++function ($) { "use strict";
+
+  // OFFCANVAS PUBLIC CLASS DEFINITION
+  // =================================
+
+  var OffCanvas = function (element, options) {
+    this.$element = $(element)
+    this.options  = $.extend({}, OffCanvas.DEFAULTS, options)
+    this.state    = null
+    this.placement = null
+    
+    if (this.options.recalc) {
+      this.calcClone()
+      $(window).on('resize', $.proxy(this.recalc, this))
+    }
+    
+    if (this.options.autohide)
+      $(document).on('click', $.proxy(this.autohide, this))
+
+    if (this.options.toggle) this.toggle()
+    
+    if (this.options.disablescrolling) {
+        this.options.disableScrolling = this.options.disablescrolling
+        delete this.options.disablescrolling
+    }
+  }
+
+  OffCanvas.DEFAULTS = {
+    toggle: true,
+    placement: 'auto',
+    autohide: true,
+    recalc: true,
+    disableScrolling: true
+  }
+
+  OffCanvas.prototype.offset = function () {
+    switch (this.placement) {
+      case 'left':
+      case 'right':  return this.$element.outerWidth()
+      case 'top':
+      case 'bottom': return this.$element.outerHeight()
+    }
+  }
+  
+  OffCanvas.prototype.calcPlacement = function () {
+    if (this.options.placement !== 'auto') {
+        this.placement = this.options.placement
+        return
+    }
+    
+    if (!this.$element.hasClass('in')) {
+      this.$element.css('visiblity', 'hidden !important').addClass('in')
+    } 
+    
+    var horizontal = $(window).width() / this.$element.width()
+    var vertical = $(window).height() / this.$element.height()
+        
+    var element = this.$element
+    function ab(a, b) {
+      if (element.css(b) === 'auto') return a
+      if (element.css(a) === 'auto') return b
+      
+      var size_a = parseInt(element.css(a), 10)
+      var size_b = parseInt(element.css(b), 10)
+  
+      return size_a > size_b ? b : a
+    }
+    
+    this.placement = horizontal >= vertical ? ab('left', 'right') : ab('top', 'bottom')
+      
+    if (this.$element.css('visibility') === 'hidden !important') {
+      this.$element.removeClass('in').css('visiblity', '')
+    }
+  }
+  
+  OffCanvas.prototype.opposite = function (placement) {
+    switch (placement) {
+      case 'top':    return 'bottom'
+      case 'left':   return 'right'
+      case 'bottom': return 'top'
+      case 'right':  return 'left'
+    }
+  }
+  
+  OffCanvas.prototype.getCanvasElements = function() {
+    // Return a set containing the canvas plus all fixed elements
+    var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
+    
+    var fixed_elements = canvas.find('*').filter(function() {
+      return $(this).css('position') === 'fixed'
+    }).not(this.options.exclude)
+    
+    return canvas.add(fixed_elements)
+  }
+  
+  OffCanvas.prototype.slide = function (elements, offset, callback) {
+    // Use jQuery animation if CSS transitions aren't supported
+    if (!$.support.transition) {
+      var anim = {}
+      anim[this.placement] = "+=" + offset
+      return elements.animate(anim, 350, callback)
+    }
+
+    var placement = this.placement
+    var opposite = this.opposite(placement)
+    
+    elements.each(function() {
+      if ($(this).css(placement) !== 'auto')
+        $(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
+      
+      if ($(this).css(opposite) !== 'auto')
+        $(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
+    })
+    
+    this.$element
+      .one($.support.transition.end, callback)
+      .emulateTransitionEnd(350)
+  }
+
+  OffCanvas.prototype.disableScrolling = function() {
+    var bodyWidth = $('body').width()
+    var prop = 'padding-' + this.opposite(this.placement)
+
+    if ($('body').data('offcanvas-style') === undefined) {
+      $('body').data('offcanvas-style', $('body').attr('style') || '')
+    }
+      
+    $('body').css('overflow', 'hidden')
+
+    if ($('body').width() > bodyWidth) {
+      var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
+      
+      setTimeout(function() {
+        $('body').css(prop, padding)
+      }, 1)
+    }
+  }
+
+  OffCanvas.prototype.show = function () {
+    if (this.state) return
+    
+    var startEvent = $.Event('show.bs.offcanvas')
+    this.$element.trigger(startEvent)
+    if (startEvent.isDefaultPrevented()) return
+
+    this.state = 'slide-in'
+    this.calcPlacement();
+    
+    var elements = this.getCanvasElements()
+    var placement = this.placement
+    var opposite = this.opposite(placement)
+    var offset = this.offset()
+
+    if (elements.index(this.$element) !== -1) {
+      $(this.$element).data('offcanvas-style', $(this.$element).attr('style') || '')
+      this.$element.css(placement, -1 * offset)
+      this.$element.css(placement); // Workaround: Need to get the CSS property for it to be applied before the next line of code
+    }
+
+    elements.addClass('canvas-sliding').each(function() {
+      if ($(this).data('offcanvas-style') === undefined) $(this).data('offcanvas-style', $(this).attr('style') || '')
+      if ($(this).css('position') === 'static') $(this).css('position', 'relative')
+      if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
+          ($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
+        $(this).css(placement, 0)
+      }
+    })
+    
+    if (this.options.disableScrolling) this.disableScrolling()
+    
+    var complete = function () {
+      if (this.state != 'slide-in') return
+      
+      this.state = 'slid'
+
+      elements.removeClass('canvas-sliding').addClass('canvas-slid')
+      this.$element.trigger('shown.bs.offcanvas')
+    }
+
+    setTimeout($.proxy(function() {
+      this.$element.addClass('in')
+      this.slide(elements, offset, $.proxy(complete, this))
+    }, this), 1)
+  }
+
+  OffCanvas.prototype.hide = function (fast) {
+    if (this.state !== 'slid') return
+
+    var startEvent = $.Event('hide.bs.offcanvas')
+    this.$element.trigger(startEvent)
+    if (startEvent.isDefaultPrevented()) return
+
+    this.state = 'slide-out'
+
+    var elements = $('.canvas-slid')
+    var placement = this.placement
+    var offset = -1 * this.offset()
+
+    var complete = function () {
+      if (this.state != 'slide-out') return
+      
+      this.state = null
+      this.placement = null
+      
+      this.$element.removeClass('in')
+      
+      elements.removeClass('canvas-sliding')
+      elements.add(this.$element).add('body').each(function() {
+        $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
+      })
+
+      this.$element.trigger('hidden.bs.offcanvas')
+    }
+
+    elements.removeClass('canvas-slid').addClass('canvas-sliding')
+    
+    setTimeout($.proxy(function() {
+      this.slide(elements, offset, $.proxy(complete, this))
+    }, this), 1)
+  }
+
+  OffCanvas.prototype.toggle = function () {
+    if (this.state === 'slide-in' || this.state === 'slide-out') return
+    this[this.state === 'slid' ? 'hide' : 'show']()
+  }
+
+  OffCanvas.prototype.calcClone = function() {
+    this.$calcClone = this.$element.clone()
+      .html('')
+      .addClass('offcanvas-clone').removeClass('in')
+      .appendTo($('body'))
+  }
+
+  OffCanvas.prototype.recalc = function () {
+    if (this.$calcClone.css('display') === 'none' || (this.state !== 'slid' && this.state !== 'slide-in')) return
+    
+    this.state = null
+    this.placement = null
+    var elements = this.getCanvasElements()
+    
+    this.$element.removeClass('in')
+    
+    elements.removeClass('canvas-slid')
+    elements.add(this.$element).add('body').each(function() {
+      $(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
+    })
+  }
+  
+  OffCanvas.prototype.autohide = function (e) {
+    if ($(e.target).closest(this.$element).length === 0) this.hide()
+  }
+
+  // OFFCANVAS PLUGIN DEFINITION
+  // ==========================
+
+  var old = $.fn.offcanvas
+
+  $.fn.offcanvas = function (option) {
+    return this.each(function () {
+      var $this   = $(this)
+      var data    = $this.data('bs.offcanvas')
+      var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option === 'object' && option)
+
+      if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
+      if (typeof option === 'string') data[option]()
+    })
+  }
+
+  $.fn.offcanvas.Constructor = OffCanvas
+
+
+  // OFFCANVAS NO CONFLICT
+  // ====================
+
+  $.fn.offcanvas.noConflict = function () {
+    $.fn.offcanvas = old
+    return this
+  }
+
+
+  // OFFCANVAS DATA-API
+  // =================
+
+  $(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
+    var $this   = $(this), href
+    var target  = $this.attr('data-target')
+        || e.preventDefault()
+        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+    var $canvas = $(target)
+    var data    = $canvas.data('bs.offcanvas')
+    var option  = data ? 'toggle' : $this.data()
+
+    e.stopPropagation()
+
+    if (data) data.toggle()
+      else $canvas.offcanvas(option)
+  })
+
+}(window.jQuery);
+
+/* ============================================================
+ * Bootstrap: rowlink.js v3.1.3
+ * http://jasny.github.io/bootstrap/javascript/#rowlink
+ * ============================================================
+ * Copyright 2012-2014 Arnold Daniels
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
++function ($) { "use strict";
+
+  var Rowlink = function (element, options) {
+    this.$element = $(element)
+    this.options = $.extend({}, Rowlink.DEFAULTS, options)
+    
+    this.$element.on('click.bs.rowlink', 'td:not(.rowlink-skip)', $.proxy(this.click, this))
+  }
+
+  Rowlink.DEFAULTS = {
+    target: "a"
+  }
+
+  Rowlink.prototype.click = function(e) {
+    var target = $(e.currentTarget).closest('tr').find(this.options.target)[0]
+    if ($(e.target)[0] === target) return
+    
+    e.preventDefault();
+    
+    if (target.click) {
+      target.click()
+    } else if (document.createEvent) {
+      var evt = document.createEvent("MouseEvents"); 
+      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
+      target.dispatchEvent(evt);
+    }
+  }
+
+  
+  // ROWLINK PLUGIN DEFINITION
+  // ===========================
+
+  var old = $.fn.rowlink
+
+  $.fn.rowlink = function (options) {
+    return this.each(function () {
+      var $this = $(this)
+      var data = $this.data('bs.rowlink')
+      if (!data) $this.data('bs.rowlink', (data = new Rowlink(this, options)))
+    })
+  }
+
+  $.fn.rowlink.Constructor = Rowlink
+
+
+  // ROWLINK NO CONFLICT
+  // ====================
+
+  $.fn.rowlink.noConflict = function () {
+    $.fn.rowlink = old
+    return this
+  }
+
+
+  // ROWLINK DATA-API
+  // ==================
+
+  $(document).on('click.bs.rowlink.data-api', '[data-link="row"]', function (e) {
+    if ($(e.target).closest('.rowlink-skip').length !== 0) return
+    
+    var $this = $(this)
+    if ($this.data('bs.rowlink')) return
+    $this.rowlink($this.data())
+    $(e.target).trigger('click.bs.rowlink')
+  })
+  
+}(window.jQuery);
+
+/* ===========================================================
+ * Bootstrap: inputmask.js v3.1.0
+ * http://jasny.github.io/bootstrap/javascript/#inputmask
+ * 
+ * Based on Masked Input plugin by Josh Bush (digitalbush.com)
+ * ===========================================================
+ * Copyright 2012-2014 Arnold Daniels
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
++function ($) { "use strict";
+
+  var isIphone = (window.orientation !== undefined)
+  var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1
+  var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
+
+  // INPUTMASK PUBLIC CLASS DEFINITION
+  // =================================
+
+  var Inputmask = function (element, options) {
+    if (isAndroid) return // No support because caret positioning doesn't work on Android
+    
+    this.$element = $(element)
+    this.options = $.extend({}, Inputmask.DEFAULTS, options)
+    this.mask = String(this.options.mask)
+    
+    this.init()
+    this.listen()
+        
+    this.checkVal() //Perform initial check for existing values
+  }
+
+  Inputmask.DEFAULTS = {
+    mask: "",
+    placeholder: "_",
+    definitions: {
+      '9': "[0-9]",
+      'a': "[A-Za-z]",
+      'w': "[A-Za-z0-9]",
+      '*': "."
+    }
+  }
+
+  Inputmask.prototype.init = function() {
+    var defs = this.options.definitions
+    var len = this.mask.length
+
+    this.tests = [] 
+    this.partialPosition = this.mask.length
+    this.firstNonMaskPos = null
+
+    $.each(this.mask.split(""), $.proxy(function(i, c) {
+      if (c == '?') {
+        len--
+        this.partialPosition = i
+      } else if (defs[c]) {
+        this.tests.push(new RegExp(defs[c]))
+        if (this.firstNonMaskPos === null)
+          this.firstNonMaskPos =  this.tests.length - 1
+      } else {
+        this.tests.push(null)
+      }
+    }, this))
+
+    this.buffer = $.map(this.mask.split(""), $.proxy(function(c, i) {
+      if (c != '?') return defs[c] ? this.options.placeholder : c
+    }, this))
+
+    this.focusText = this.$element.val()
+
+    this.$element.data("rawMaskFn", $.proxy(function() {
+      return $.map(this.buffer, function(c, i) {
+        return this.tests[i] && c != this.options.placeholder ? c : null
+      }).join('')
+    }, this))
+  }
+    
+  Inputmask.prototype.listen = function() {
+    if (this.$element.attr("readonly")) return
+
+    var pasteEventName = (isIE ? 'paste' : 'input') + ".mask"
+
+    this.$element
+      .on("unmask.bs.inputmask", $.proxy(this.unmask, this))
+
+      .on("focus.bs.inputmask", $.proxy(this.focusEvent, this))
+      .on("blur.bs.inputmask", $.proxy(this.blurEvent, this))
+
+      .on("keydown.bs.inputmask", $.proxy(this.keydownEvent, this))
+      .on("keypress.bs.inputmask", $.proxy(this.keypressEvent, this))
+
+      .on(pasteEventName, $.proxy(this.pasteEvent, this))
+  }
+
+  //Helper Function for Caret positioning
+  Inputmask.prototype.caret = function(begin, end) {
+    if (this.$element.length === 0) return
+    if (typeof begin == 'number') {
+      end = (typeof end == 'number') ? end : begin
+      return this.$element.each(function() {
+        if (this.setSelectionRange) {
+          this.setSelectionRange(begin, end)
+        } else if (this.createTextRange) {
+          var range = this.createTextRange()
+          range.collapse(true)
+          range.moveEnd('character', end)
+          range.moveStart('character', begin)
+          range.select()
+        }
+      })
+    } else {
+      if (this.$element[0].setSelectionRange) {
+        begin = this.$element[0].selectionStart
+        end = this.$element[0].selectionEnd
+      } else if (document.selection && document.selection.createRange) {
+        var range = document.selection.createRange()
+        begin = 0 - range.duplicate().moveStart('character', -100000)
+        end = begin + range.text.length
+      }
+      return {
+        begin: begin, 
+        end: end
+      }
+    }
+  }
+  
+  Inputmask.prototype.seekNext = function(pos) {
+    var len = this.mask.length
+    while (++pos <= len && !this.tests[pos]);
+
+    return pos
+  }
+  
+  Inputmask.prototype.seekPrev = function(pos) {
+    while (--pos >= 0 && !this.tests[pos]);
+
+    return pos
+  }
+
+  Inputmask.prototype.shiftL = function(begin,end) {
+    var len = this.mask.length
+
+    if (begin < 0) return
+
+    for (var i = begin, j = this.seekNext(end); i < len; i++) {
+      if (this.tests[i]) {
+        if (j < len && this.tests[i].test(this.buffer[j])) {
+          this.buffer[i] = this.buffer[j]
+          this.buffer[j] = this.options.placeholder
+        } else
+          break
+        j = this.seekNext(j)
+      }
+    }
+    this.writeBuffer()
+    this.caret(Math.max(this.firstNonMaskPos, begin))
+  }
+
+  Inputmask.prototype.shiftR = function(pos) {
+    var len = this.mask.length
+
+    for (var i = pos, c = this.options.placeholder; i < len; i++) {
+      if (this.tests[i]) {
+        var j = this.seekNext(i)
+        var t = this.buffer[i]
+        this.buffer[i] = c
+        if (j < len && this.tests[j].test(t))
+          c = t
+        else
+          break
+      }
+    }
+  },
+
+  Inputmask.prototype.unmask = function() {
+    this.$element
+      .unbind(".mask")
+      .removeData("inputmask")
+  }
+
+  Inputmask.prototype.focusEvent = function() {
+    this.focusText = this.$element.val()
+    var len = this.mask.length 
+    var pos = this.checkVal()
+    this.writeBuffer()
+
+    var that = this
+    var moveCaret = function() {
+      if (pos == len)
+        that.caret(0, pos)
+      else
+        that.caret(pos)
+    }
+
+    moveCaret()
+    setTimeout(moveCaret, 50)
+  }
+
+  Inputmask.prototype.blurEvent = function() {
+    this.checkVal()
+    if (this.$element.val() !== this.focusText)
+      this.$element.trigger('change')
+  }
+
+  Inputmask.prototype.keydownEvent = function(e) {
+    var k = e.which
+
+    //backspace, delete, and escape get special treatment
+    if (k == 8 || k == 46 || (isIphone && k == 127)) {
+      var pos = this.caret(),
+      begin = pos.begin,
+      end = pos.end
+
+      if (end - begin === 0) {
+        begin = k != 46 ? this.seekPrev(begin) : (end = this.seekNext(begin - 1))
+        end = k == 46 ? this.seekNext(end) : end
+      }
+      this.clearBuffer(begin, end)
+      this.shiftL(begin, end - 1)
+
+      return false
+    } else if (k == 27) {//escape
+      this.$element.val(this.focusText)
+      this.caret(0, this.checkVal())
+      return false
+    }
+  }
+
+  Inputmask.prototype.keypressEvent = function(e) {
+    var len = this.mask.length
+
+    var k = e.which,
+    pos = this.caret()
+
+    if (e.ctrlKey || e.altKey || e.metaKey || k < 32)  {//Ignore
+      return true
+    } else if (k) {
+      if (pos.end - pos.begin !== 0) {
+        this.clearBuffer(pos.begin, pos.end)
+        this.shiftL(pos.begin, pos.end - 1)
+      }
+
+      var p = this.seekNext(pos.begin - 1)
+      if (p < len) {
+        var c = String.fromCharCode(k)
+        if (this.tests[p].test(c)) {
+          this.shiftR(p)
+          this.buffer[p] = c
+          this.writeBuffer()
+          var next = this.seekNext(p)
+          this.caret(next)
+        }
+      }
+      return false
+    }
+  }
+
+  Inputmask.prototype.pasteEvent = function() {
+    var that = this
+
+    setTimeout(function() {
+      that.caret(that.checkVal(true))
+    }, 0)
+  }
+
+  Inputmask.prototype.clearBuffer = function(start, end) {
+    var len = this.mask.length
+
+    for (var i = start; i < end && i < len; i++) {
+      if (this.tests[i])
+        this.buffer[i] = this.options.placeholder
+    }
+  }
+
+  Inputmask.prototype.writeBuffer = function() {
+    return this.$element.val(this.buffer.join('')).val()
+  }
+
+  Inputmask.prototype.checkVal = function(allow) {
+    var len = this.mask.length
+    //try to place characters where they belong
+    var test = this.$element.val()
+    var lastMatch = -1
+
+    for (var i = 0, pos = 0; i < len; i++) {
+      if (this.tests[i]) {
+        this.buffer[i] = this.options.placeholder
+        while (pos++ < test.length) {
+          var c = test.charAt(pos - 1)
+          if (this.tests[i].test(c)) {
+            this.buffer[i] = c
+            lastMatch = i
+            break
+          }
+        }
+        if (pos > test.length)
+          break
+      } else if (this.buffer[i] == test.charAt(pos) && i != this.partialPosition) {
+        pos++
+        lastMatch = i
+      }
+    }
+    if (!allow && lastMatch + 1 < this.partialPosition) {
+      this.$element.val("")
+      this.clearBuffer(0, len)
+    } else if (allow || lastMatch + 1 >= this.partialPosition) {
+      this.writeBuffer()
+      if (!allow) this.$element.val(this.$element.val().substring(0, lastMatch + 1))
+    }
+    return (this.partialPosition ? i : this.firstNonMaskPos)
+  }
+
+  
+  // INPUTMASK PLUGIN DEFINITION
+  // ===========================
+
+  var old = $.fn.inputmask
+  
+  $.fn.inputmask = function (options) {
+    return this.each(function () {
+      var $this = $(this)
+      var data = $this.data('bs.inputmask')
+      
+      if (!data) $this.data('bs.inputmask', (data = new Inputmask(this, options)))
+    })
+  }
+
+  $.fn.inputmask.Constructor = Inputmask
+
+
+  // INPUTMASK NO CONFLICT
+  // ====================
+
+  $.fn.inputmask.noConflict = function () {
+    $.fn.inputmask = old
+    return this
+  }
+
+
+  // INPUTMASK DATA-API
+  // ==================
+
+  $(document).on('focus.bs.inputmask.data-api', '[data-mask]', function (e) {
+    var $this = $(this)
+    if ($this.data('bs.inputmask')) return
+    $this.inputmask($this.data())
+  })
+
+}(window.jQuery);
+
+/* ===========================================================
+ * Bootstrap: fileinput.js v3.1.3
+ * http://jasny.github.com/bootstrap/javascript/#fileinput
+ * ===========================================================
+ * Copyright 2012-2014 Arnold Daniels
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
++function ($) { "use strict";
+
+  var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
+
+  // FILEUPLOAD PUBLIC CLASS DEFINITION
+  // =================================
+
+  var Fileinput = function (element, options) {
+    this.$element = $(element)
+    
+    this.$input = this.$element.find(':file')
+    if (this.$input.length === 0) return
+
+    this.name = this.$input.attr('name') || options.name
+
+    this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]')
+    if (this.$hidden.length === 0) {
+      this.$hidden = $('<input type="hidden">').insertBefore(this.$input)
+    }
+
+    this.$preview = this.$element.find('.fileinput-preview')
+    var height = this.$preview.css('height')
+    if (this.$preview.css('display') !== 'inline' && height !== '0px' && height !== 'none') {
+      this.$preview.css('line-height', height)
+    }
+        
+    this.original = {
+      exists: this.$element.hasClass('fileinput-exists'),
+      preview: this.$preview.html(),
+      hiddenVal: this.$hidden.val()
+    }
+    
+    this.listen()
+  }
+  
+  Fileinput.prototype.listen = function() {
+    this.$input.on('change.bs.fileinput', $.proxy(this.change, this))
+    $(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this))
+    
+    this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this))
+    this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this))
+  },
+
+  Fileinput.prototype.change = function(e) {
+    var files = e.target.files === undefined ? (e.target && e.target.value ? [{ name: e.target.value.replace(/^.+\\/, '')}] : []) : e.target.files
+    
+    e.stopPropagation()
+
+    if (files.length === 0) {
+      this.clear()
+      return
+    }
+
+    this.$hidden.val('')
+    this.$hidden.attr('name', '')
+    this.$input.attr('name', this.name)
+
+    var file = files[0]
+
+    if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match(/^image\/(gif|png|jpeg)$/) : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
+      var reader = new FileReader()
+      var preview = this.$preview
+      var element = this.$element
+
+      reader.onload = function(re) {
+        var $img = $('<img>')
+        $img[0].src = re.target.result
+        files[0].result = re.target.result
+        
+        element.find('.fileinput-filename').text(file.name)
+        
+        // if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account
+        if (preview.css('max-height') != 'none') $img.css('max-height', parseInt(preview.css('max-height'), 10) - parseInt(preview.css('padding-top'), 10) - parseInt(preview.css('padding-bottom'), 10)  - parseInt(preview.css('border-top'), 10) - parseInt(preview.css('border-bottom'), 10))
+        
+        preview.html($img)
+        element.addClass('fileinput-exists').removeClass('fileinput-new')
+
+        element.trigger('change.bs.fileinput', files)
+      }
+
+      reader.readAsDataURL(file)
+    } else {
+      this.$element.find('.fileinput-filename').text(file.name)
+      this.$preview.text(file.name)
+      
+      this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
+      
+      this.$element.trigger('change.bs.fileinput')
+    }
+  },
+
+  Fileinput.prototype.clear = function(e) {
+    if (e) e.preventDefault()
+    
+    this.$hidden.val('')
+    this.$hidden.attr('name', this.name)
+    this.$input.attr('name', '')
+
+    //ie8+ doesn't support changing the value of input with type=file so clone instead
+    if (isIE) { 
+      var inputClone = this.$input.clone(true);
+      this.$input.after(inputClone);
+      this.$input.remove();
+      this.$input = inputClone;
+    } else {
+      this.$input.val('')
+    }
+
+    this.$preview.html('')
+    this.$element.find('.fileinput-filename').text('')
+    this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
+    
+    if (e !== undefined) {
+      this.$input.trigger('change')
+      this.$element.trigger('clear.bs.fileinput')
+    }
+  },
+
+  Fileinput.prototype.reset = function() {
+    this.clear()
+
+    this.$hidden.val(this.original.hiddenVal)
+    this.$preview.html(this.original.preview)
+    this.$element.find('.fileinput-filename').text('')
+
+    if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
+     else this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
+    
+    this.$element.trigger('reset.bs.fileinput')
+  },
+
+  Fileinput.prototype.trigger = function(e) {
+    this.$input.trigger('click')
+    e.preventDefault()
+  }
+
+  
+  // FILEUPLOAD PLUGIN DEFINITION
+  // ===========================
+
+  var old = $.fn.fileinput
+  
+  $.fn.fileinput = function (options) {
+    return this.each(function () {
+      var $this = $(this),
+          data = $this.data('bs.fileinput')
+      if (!data) $this.data('bs.fileinput', (data = new Fileinput(this, options)))
+      if (typeof options == 'string') data[options]()
+    })
+  }
+
+  $.fn.fileinput.Constructor = Fileinput
+
+
+  // FILEINPUT NO CONFLICT
+  // ====================
+
+  $.fn.fileinput.noConflict = function () {
+    $.fn.fileinput = old
+    return this
+  }
+
+
+  // FILEUPLOAD DATA-API
+  // ==================
+
+  $(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function (e) {
+    var $this = $(this)
+    if ($this.data('bs.fileinput')) return
+    $this.fileinput($this.data())
+      
+    var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');
+    if ($target.length > 0) {
+      e.preventDefault()
+      $target.trigger('click.bs.fileinput')
+    }
+  })
+
+}(window.jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.min.js b/src/main/resources/META-INF/resources/designer/lib/jasny-bootstrap.min.js
new file mode 100644 (file)
index 0000000..6eb1756
--- /dev/null
@@ -0,0 +1,6 @@
+/*!
+ * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
+ * Copyright 2012-2014 Arnold Daniels
+ * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Jasny Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}void 0===a.support.transition&&(a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()}))}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.state=null,this.placement=null,this.options.recalc&&(this.calcClone(),a(window).on("resize",a.proxy(this.recalc,this))),this.options.autohide&&a(document).on("click",a.proxy(this.autohide,this)),this.options.toggle&&this.toggle(),this.options.disablescrolling&&(this.options.disableScrolling=this.options.disablescrolling,delete this.options.disablescrolling)};b.DEFAULTS={toggle:!0,placement:"auto",autohide:!0,recalc:!0,disableScrolling:!0},b.prototype.offset=function(){switch(this.placement){case"left":case"right":return this.$element.outerWidth();case"top":case"bottom":return this.$element.outerHeight()}},b.prototype.calcPlacement=function(){function b(a,b){if("auto"===e.css(b))return a;if("auto"===e.css(a))return b;var c=parseInt(e.css(a),10),d=parseInt(e.css(b),10);return c>d?b:a}if("auto"!==this.options.placement)return void(this.placement=this.options.placement);this.$element.hasClass("in")||this.$element.css("visiblity","hidden !important").addClass("in");var c=a(window).width()/this.$element.width(),d=a(window).height()/this.$element.height(),e=this.$element;this.placement=c>=d?b("left","right"):b("top","bottom"),"hidden !important"===this.$element.css("visibility")&&this.$element.removeClass("in").css("visiblity","")},b.prototype.opposite=function(a){switch(a){case"top":return"bottom";case"left":return"right";case"bottom":return"top";case"right":return"left"}},b.prototype.getCanvasElements=function(){var b=this.options.canvas?a(this.options.canvas):this.$element,c=b.find("*").filter(function(){return"fixed"===a(this).css("position")}).not(this.options.exclude);return b.add(c)},b.prototype.slide=function(b,c,d){if(!a.support.transition){var e={};return e[this.placement]="+="+c,b.animate(e,350,d)}var f=this.placement,g=this.opposite(f);b.each(function(){"auto"!==a(this).css(f)&&a(this).css(f,(parseInt(a(this).css(f),10)||0)+c),"auto"!==a(this).css(g)&&a(this).css(g,(parseInt(a(this).css(g),10)||0)-c)}),this.$element.one(a.support.transition.end,d).emulateTransitionEnd(350)},b.prototype.disableScrolling=function(){var b=a("body").width(),c="padding-"+this.opposite(this.placement);if(void 0===a("body").data("offcanvas-style")&&a("body").data("offcanvas-style",a("body").attr("style")||""),a("body").css("overflow","hidden"),a("body").width()>b){var d=parseInt(a("body").css(c),10)+a("body").width()-b;setTimeout(function(){a("body").css(c,d)},1)}},b.prototype.show=function(){if(!this.state){var b=a.Event("show.bs.offcanvas");if(this.$element.trigger(b),!b.isDefaultPrevented()){this.state="slide-in",this.calcPlacement();var c=this.getCanvasElements(),d=this.placement,e=this.opposite(d),f=this.offset();-1!==c.index(this.$element)&&(a(this.$element).data("offcanvas-style",a(this.$element).attr("style")||""),this.$element.css(d,-1*f),this.$element.css(d)),c.addClass("canvas-sliding").each(function(){void 0===a(this).data("offcanvas-style")&&a(this).data("offcanvas-style",a(this).attr("style")||""),"static"===a(this).css("position")&&a(this).css("position","relative"),"auto"!==a(this).css(d)&&"0px"!==a(this).css(d)||"auto"!==a(this).css(e)&&"0px"!==a(this).css(e)||a(this).css(d,0)}),this.options.disableScrolling&&this.disableScrolling();var g=function(){"slide-in"==this.state&&(this.state="slid",c.removeClass("canvas-sliding").addClass("canvas-slid"),this.$element.trigger("shown.bs.offcanvas"))};setTimeout(a.proxy(function(){this.$element.addClass("in"),this.slide(c,f,a.proxy(g,this))},this),1)}}},b.prototype.hide=function(){if("slid"===this.state){var b=a.Event("hide.bs.offcanvas");if(this.$element.trigger(b),!b.isDefaultPrevented()){this.state="slide-out";var c=a(".canvas-slid"),d=(this.placement,-1*this.offset()),e=function(){"slide-out"==this.state&&(this.state=null,this.placement=null,this.$element.removeClass("in"),c.removeClass("canvas-sliding"),c.add(this.$element).add("body").each(function(){a(this).attr("style",a(this).data("offcanvas-style")).removeData("offcanvas-style")}),this.$element.trigger("hidden.bs.offcanvas"))};c.removeClass("canvas-slid").addClass("canvas-sliding"),setTimeout(a.proxy(function(){this.slide(c,d,a.proxy(e,this))},this),1)}}},b.prototype.toggle=function(){"slide-in"!==this.state&&"slide-out"!==this.state&&this["slid"===this.state?"hide":"show"]()},b.prototype.calcClone=function(){this.$calcClone=this.$element.clone().html("").addClass("offcanvas-clone").removeClass("in").appendTo(a("body"))},b.prototype.recalc=function(){if("none"!==this.$calcClone.css("display")&&("slid"===this.state||"slide-in"===this.state)){this.state=null,this.placement=null;var b=this.getCanvasElements();this.$element.removeClass("in"),b.removeClass("canvas-slid"),b.add(this.$element).add("body").each(function(){a(this).attr("style",a(this).data("offcanvas-style")).removeData("offcanvas-style")})}},b.prototype.autohide=function(b){0===a(b.target).closest(this.$element).length&&this.hide()};var c=a.fn.offcanvas;a.fn.offcanvas=function(c){return this.each(function(){var d=a(this),e=d.data("bs.offcanvas"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.offcanvas",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.offcanvas.Constructor=b,a.fn.offcanvas.noConflict=function(){return a.fn.offcanvas=c,this},a(document).on("click.bs.offcanvas.data-api","[data-toggle=offcanvas]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.offcanvas"),h=g?"toggle":d.data();b.stopPropagation(),g?g.toggle():f.offcanvas(h)})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.$element.on("click.bs.rowlink","td:not(.rowlink-skip)",a.proxy(this.click,this))};b.DEFAULTS={target:"a"},b.prototype.click=function(b){var c=a(b.currentTarget).closest("tr").find(this.options.target)[0];if(a(b.target)[0]!==c)if(b.preventDefault(),c.click)c.click();else if(document.createEvent){var d=document.createEvent("MouseEvents");d.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),c.dispatchEvent(d)}};var c=a.fn.rowlink;a.fn.rowlink=function(c){return this.each(function(){var d=a(this),e=d.data("bs.rowlink");e||d.data("bs.rowlink",e=new b(this,c))})},a.fn.rowlink.Constructor=b,a.fn.rowlink.noConflict=function(){return a.fn.rowlink=c,this},a(document).on("click.bs.rowlink.data-api",'[data-link="row"]',function(b){if(0===a(b.target).closest(".rowlink-skip").length){var c=a(this);c.data("bs.rowlink")||(c.rowlink(c.data()),a(b.target).trigger("click.bs.rowlink"))}})}(window.jQuery),+function(a){"use strict";var b=void 0!==window.orientation,c=navigator.userAgent.toLowerCase().indexOf("android")>-1,d="Microsoft Internet Explorer"==window.navigator.appName,e=function(b,d){c||(this.$element=a(b),this.options=a.extend({},e.DEFAULTS,d),this.mask=String(this.options.mask),this.init(),this.listen(),this.checkVal())};e.DEFAULTS={mask:"",placeholder:"_",definitions:{9:"[0-9]",a:"[A-Za-z]",w:"[A-Za-z0-9]","*":"."}},e.prototype.init=function(){var b=this.options.definitions,c=this.mask.length;this.tests=[],this.partialPosition=this.mask.length,this.firstNonMaskPos=null,a.each(this.mask.split(""),a.proxy(function(a,d){"?"==d?(c--,this.partialPosition=a):b[d]?(this.tests.push(new RegExp(b[d])),null===this.firstNonMaskPos&&(this.firstNonMaskPos=this.tests.length-1)):this.tests.push(null)},this)),this.buffer=a.map(this.mask.split(""),a.proxy(function(a){return"?"!=a?b[a]?this.options.placeholder:a:void 0},this)),this.focusText=this.$element.val(),this.$element.data("rawMaskFn",a.proxy(function(){return a.map(this.buffer,function(a,b){return this.tests[b]&&a!=this.options.placeholder?a:null}).join("")},this))},e.prototype.listen=function(){if(!this.$element.attr("readonly")){var b=(d?"paste":"input")+".mask";this.$element.on("unmask.bs.inputmask",a.proxy(this.unmask,this)).on("focus.bs.inputmask",a.proxy(this.focusEvent,this)).on("blur.bs.inputmask",a.proxy(this.blurEvent,this)).on("keydown.bs.inputmask",a.proxy(this.keydownEvent,this)).on("keypress.bs.inputmask",a.proxy(this.keypressEvent,this)).on(b,a.proxy(this.pasteEvent,this))}},e.prototype.caret=function(a,b){if(0!==this.$element.length){if("number"==typeof a)return b="number"==typeof b?b:a,this.$element.each(function(){if(this.setSelectionRange)this.setSelectionRange(a,b);else if(this.createTextRange){var c=this.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select()}});if(this.$element[0].setSelectionRange)a=this.$element[0].selectionStart,b=this.$element[0].selectionEnd;else if(document.selection&&document.selection.createRange){var c=document.selection.createRange();a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length}return{begin:a,end:b}}},e.prototype.seekNext=function(a){for(var b=this.mask.length;++a<=b&&!this.tests[a];);return a},e.prototype.seekPrev=function(a){for(;--a>=0&&!this.tests[a];);return a},e.prototype.shiftL=function(a,b){var c=this.mask.length;if(!(0>a)){for(var d=a,e=this.seekNext(b);c>d;d++)if(this.tests[d]){if(!(c>e&&this.tests[d].test(this.buffer[e])))break;this.buffer[d]=this.buffer[e],this.buffer[e]=this.options.placeholder,e=this.seekNext(e)}this.writeBuffer(),this.caret(Math.max(this.firstNonMaskPos,a))}},e.prototype.shiftR=function(a){for(var b=this.mask.length,c=a,d=this.options.placeholder;b>c;c++)if(this.tests[c]){var e=this.seekNext(c),f=this.buffer[c];if(this.buffer[c]=d,!(b>e&&this.tests[e].test(f)))break;d=f}},e.prototype.unmask=function(){this.$element.unbind(".mask").removeData("inputmask")},e.prototype.focusEvent=function(){this.focusText=this.$element.val();var a=this.mask.length,b=this.checkVal();this.writeBuffer();var c=this,d=function(){b==a?c.caret(0,b):c.caret(b)};d(),setTimeout(d,50)},e.prototype.blurEvent=function(){this.checkVal(),this.$element.val()!==this.focusText&&this.$element.trigger("change")},e.prototype.keydownEvent=function(a){var c=a.which;if(8==c||46==c||b&&127==c){var d=this.caret(),e=d.begin,f=d.end;return f-e===0&&(e=46!=c?this.seekPrev(e):f=this.seekNext(e-1),f=46==c?this.seekNext(f):f),this.clearBuffer(e,f),this.shiftL(e,f-1),!1}return 27==c?(this.$element.val(this.focusText),this.caret(0,this.checkVal()),!1):void 0},e.prototype.keypressEvent=function(a){var b=this.mask.length,c=a.which,d=this.caret();if(a.ctrlKey||a.altKey||a.metaKey||32>c)return!0;if(c){d.end-d.begin!==0&&(this.clearBuffer(d.begin,d.end),this.shiftL(d.begin,d.end-1));var e=this.seekNext(d.begin-1);if(b>e){var f=String.fromCharCode(c);if(this.tests[e].test(f)){this.shiftR(e),this.buffer[e]=f,this.writeBuffer();var g=this.seekNext(e);this.caret(g)}}return!1}},e.prototype.pasteEvent=function(){var a=this;setTimeout(function(){a.caret(a.checkVal(!0))},0)},e.prototype.clearBuffer=function(a,b){for(var c=this.mask.length,d=a;b>d&&c>d;d++)this.tests[d]&&(this.buffer[d]=this.options.placeholder)},e.prototype.writeBuffer=function(){return this.$element.val(this.buffer.join("")).val()},e.prototype.checkVal=function(a){for(var b=this.mask.length,c=this.$element.val(),d=-1,e=0,f=0;b>e;e++)if(this.tests[e]){for(this.buffer[e]=this.options.placeholder;f++<c.length;){var g=c.charAt(f-1);if(this.tests[e].test(g)){this.buffer[e]=g,d=e;break}}if(f>c.length)break}else this.buffer[e]==c.charAt(f)&&e!=this.partialPosition&&(f++,d=e);return!a&&d+1<this.partialPosition?(this.$element.val(""),this.clearBuffer(0,b)):(a||d+1>=this.partialPosition)&&(this.writeBuffer(),a||this.$element.val(this.$element.val().substring(0,d+1))),this.partialPosition?e:this.firstNonMaskPos};var f=a.fn.inputmask;a.fn.inputmask=function(b){return this.each(function(){var c=a(this),d=c.data("bs.inputmask");d||c.data("bs.inputmask",d=new e(this,b))})},a.fn.inputmask.Constructor=e,a.fn.inputmask.noConflict=function(){return a.fn.inputmask=f,this},a(document).on("focus.bs.inputmask.data-api","[data-mask]",function(){var b=a(this);b.data("bs.inputmask")||b.inputmask(b.data())})}(window.jQuery),+function(a){"use strict";var b="Microsoft Internet Explorer"==window.navigator.appName,c=function(b,c){if(this.$element=a(b),this.$input=this.$element.find(":file"),0!==this.$input.length){this.name=this.$input.attr("name")||c.name,this.$hidden=this.$element.find('input[type=hidden][name="'+this.name+'"]'),0===this.$hidden.length&&(this.$hidden=a('<input type="hidden">').insertBefore(this.$input)),this.$preview=this.$element.find(".fileinput-preview");var d=this.$preview.css("height");"inline"!==this.$preview.css("display")&&"0px"!==d&&"none"!==d&&this.$preview.css("line-height",d),this.original={exists:this.$element.hasClass("fileinput-exists"),preview:this.$preview.html(),hiddenVal:this.$hidden.val()},this.listen()}};c.prototype.listen=function(){this.$input.on("change.bs.fileinput",a.proxy(this.change,this)),a(this.$input[0].form).on("reset.bs.fileinput",a.proxy(this.reset,this)),this.$element.find('[data-trigger="fileinput"]').on("click.bs.fileinput",a.proxy(this.trigger,this)),this.$element.find('[data-dismiss="fileinput"]').on("click.bs.fileinput",a.proxy(this.clear,this))},c.prototype.change=function(b){var c=void 0===b.target.files?b.target&&b.target.value?[{name:b.target.value.replace(/^.+\\/,"")}]:[]:b.target.files;if(b.stopPropagation(),0===c.length)return void this.clear();this.$hidden.val(""),this.$hidden.attr("name",""),this.$input.attr("name",this.name);var d=c[0];if(this.$preview.length>0&&("undefined"!=typeof d.type?d.type.match(/^image\/(gif|png|jpeg)$/):d.name.match(/\.(gif|png|jpe?g)$/i))&&"undefined"!=typeof FileReader){var e=new FileReader,f=this.$preview,g=this.$element;e.onload=function(b){var e=a("<img>");e[0].src=b.target.result,c[0].result=b.target.result,g.find(".fileinput-filename").text(d.name),"none"!=f.css("max-height")&&e.css("max-height",parseInt(f.css("max-height"),10)-parseInt(f.css("padding-top"),10)-parseInt(f.css("padding-bottom"),10)-parseInt(f.css("border-top"),10)-parseInt(f.css("border-bottom"),10)),f.html(e),g.addClass("fileinput-exists").removeClass("fileinput-new"),g.trigger("change.bs.fileinput",c)},e.readAsDataURL(d)}else this.$element.find(".fileinput-filename").text(d.name),this.$preview.text(d.name),this.$element.addClass("fileinput-exists").removeClass("fileinput-new"),this.$element.trigger("change.bs.fileinput")},c.prototype.clear=function(a){if(a&&a.preventDefault(),this.$hidden.val(""),this.$hidden.attr("name",this.name),this.$input.attr("name",""),b){var c=this.$input.clone(!0);this.$input.after(c),this.$input.remove(),this.$input=c}else this.$input.val("");this.$preview.html(""),this.$element.find(".fileinput-filename").text(""),this.$element.addClass("fileinput-new").removeClass("fileinput-exists"),void 0!==a&&(this.$input.trigger("change"),this.$element.trigger("clear.bs.fileinput"))},c.prototype.reset=function(){this.clear(),this.$hidden.val(this.original.hiddenVal),this.$preview.html(this.original.preview),this.$element.find(".fileinput-filename").text(""),this.original.exists?this.$element.addClass("fileinput-exists").removeClass("fileinput-new"):this.$element.addClass("fileinput-new").removeClass("fileinput-exists"),this.$element.trigger("reset.bs.fileinput")},c.prototype.trigger=function(a){this.$input.trigger("click"),a.preventDefault()};var d=a.fn.fileinput;a.fn.fileinput=function(b){return this.each(function(){var d=a(this),e=d.data("bs.fileinput");e||d.data("bs.fileinput",e=new c(this,b)),"string"==typeof b&&e[b]()})},a.fn.fileinput.Constructor=c,a.fn.fileinput.noConflict=function(){return a.fn.fileinput=d,this},a(document).on("click.fileinput.data-api",'[data-provides="fileinput"]',function(b){var c=a(this);if(!c.data("bs.fileinput")){c.fileinput(c.data());var d=a(b.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');d.length>0&&(b.preventDefault(),d.trigger("click.bs.fileinput"))}})}(window.jQuery);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/external/jquery/jquery.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/external/jquery/jquery.js
new file mode 100644 (file)
index 0000000..c5c6482
--- /dev/null
@@ -0,0 +1,9789 @@
+/*!
+ * jQuery JavaScript Library v1.10.2
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03T13:48Z
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+       // The deferred used on DOM ready
+       readyList,
+
+       // A central reference to the root jQuery(document)
+       rootjQuery,
+
+       // Support: IE<10
+       // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
+       core_strundefined = typeof undefined,
+
+       // Use the correct document accordingly with window argument (sandbox)
+       location = window.location,
+       document = window.document,
+       docElem = document.documentElement,
+
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$,
+
+       // [[Class]] -> type pairs
+       class2type = {},
+
+       // List of deleted data cache ids, so we can reuse them
+       core_deletedIds = [],
+
+       core_version = "1.10.2",
+
+       // Save a reference to some core methods
+       core_concat = core_deletedIds.concat,
+       core_push = core_deletedIds.push,
+       core_slice = core_deletedIds.slice,
+       core_indexOf = core_deletedIds.indexOf,
+       core_toString = class2type.toString,
+       core_hasOwn = class2type.hasOwnProperty,
+       core_trim = core_version.trim,
+
+       // Define a local copy of jQuery
+       jQuery = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               return new jQuery.fn.init( selector, context, rootjQuery );
+       },
+
+       // Used for matching numbers
+       core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+       // Used for splitting on whitespace
+       core_rnotwhite = /\S+/g,
+
+       // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+       rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+       // A simple way to check for HTML strings
+       // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+       // Strict HTML recognition (#11290: must start with <)
+       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+       // Match a standalone tag
+       rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+       // JSON RegExp
+       rvalidchars = /^[\],:{}\s]*$/,
+       rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+       rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+       rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
+       // Matches dashed string for camelizing
+       rmsPrefix = /^-ms-/,
+       rdashAlpha = /-([\da-z])/gi,
+
+       // Used by jQuery.camelCase as callback to replace()
+       fcamelCase = function( all, letter ) {
+               return letter.toUpperCase();
+       },
+
+       // The ready event handler
+       completed = function( event ) {
+
+               // readyState === "complete" is good enough for us to call the dom ready in oldIE
+               if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+                       detach();
+                       jQuery.ready();
+               }
+       },
+       // Clean-up method for dom ready events
+       detach = function() {
+               if ( document.addEventListener ) {
+                       document.removeEventListener( "DOMContentLoaded", completed, false );
+                       window.removeEventListener( "load", completed, false );
+
+               } else {
+                       document.detachEvent( "onreadystatechange", completed );
+                       window.detachEvent( "onload", completed );
+               }
+       };
+
+jQuery.fn = jQuery.prototype = {
+       // The current version of jQuery being used
+       jquery: core_version,
+
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
+               var match, elem;
+
+               // HANDLE: $(""), $(null), $(undefined), $(false)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+                               // Assume that strings that start and end with <> are HTML and skip the regex check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = rquickExpr.exec( selector );
+                       }
+
+                       // Match html or make sure no context is specified for #id
+                       if ( match && (match[1] || !context) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
+
+                                       // scripts is true for back-compat
+                                       jQuery.merge( this, jQuery.parseHTML(
+                                               match[1],
+                                               context && context.nodeType ? context.ownerDocument || context : document,
+                                               true
+                                       ) );
+
+                                       // HANDLE: $(html, props)
+                                       if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+                                               for ( match in context ) {
+                                                       // Properties of context are called as methods if possible
+                                                       if ( jQuery.isFunction( this[ match ] ) ) {
+                                                               this[ match ]( context[ match ] );
+
+                                                       // ...and otherwise set as attributes
+                                                       } else {
+                                                               this.attr( match, context[ match ] );
+                                                       }
+                                               }
+                                       }
+
+                                       return this;
+
+                               // HANDLE: $(#id)
+                               } else {
+                                       elem = document.getElementById( match[2] );
+
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE and Opera return items
+                                               // by name instead of ID
+                                               if ( elem.id !== match[2] ) {
+                                                       return rootjQuery.find( selector );
+                                               }
+
+                                               // Otherwise, we inject the element directly into the jQuery object
+                                               this.length = 1;
+                                               this[0] = elem;
+                                       }
+
+                                       this.context = document;
+                                       this.selector = selector;
+                                       return this;
+                               }
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return ( context || rootjQuery ).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return this.constructor( context ).find( selector );
+                       }
+
+               // HANDLE: $(DOMElement)
+               } else if ( selector.nodeType ) {
+                       this.context = this[0] = selector;
+                       this.length = 1;
+                       return this;
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return rootjQuery.ready( selector );
+               }
+
+               if ( selector.selector !== undefined ) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
+               return jQuery.makeArray( selector, this );
+       },
+
+       // Start with an empty selector
+       selector: "",
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       toArray: function() {
+               return core_slice.call( this );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+               return num == null ?
+
+                       // Return a 'clean' array
+                       this.toArray() :
+
+                       // Return just the object
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems ) {
+
+               // Build a new jQuery matched element set
+               var ret = jQuery.merge( this.constructor(), elems );
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+               ret.context = this.context;
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       // (You can seed the arguments with an array of args, but this is
+       // only used internally.)
+       each: function( callback, args ) {
+               return jQuery.each( this, callback, args );
+       },
+
+       ready: function( fn ) {
+               // Add the callback
+               jQuery.ready.promise().done( fn );
+
+               return this;
+       },
+
+       slice: function() {
+               return this.pushStack( core_slice.apply( this, arguments ) );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       eq: function( i ) {
+               var len = this.length,
+                       j = +i + ( i < 0 ? len : 0 );
+               return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               }));
+       },
+
+       end: function() {
+               return this.prevObject || this.constructor(null);
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: core_push,
+       sort: [].sort,
+       splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+       var src, copyIsArray, copy, name, options, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+               target = arguments[1] || {};
+               // skip the boolean and the target
+               i = 2;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+               target = {};
+       }
+
+       // extend jQuery itself if only one argument is passed
+       if ( length === i ) {
+               target = this;
+               --i;
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && jQuery.isArray(src) ? src : [];
+
+                                       } else {
+                                               clone = src && jQuery.isPlainObject(src) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend({
+       // Unique for each copy of jQuery on the page
+       // Non-digits removed to match rinlinejQuery
+       expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+       noConflict: function( deep ) {
+               if ( window.$ === jQuery ) {
+                       window.$ = _$;
+               }
+
+               if ( deep && window.jQuery === jQuery ) {
+                       window.jQuery = _jQuery;
+               }
+
+               return jQuery;
+       },
+
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+
+       // A counter to track how many items to wait for before
+       // the ready event fires. See #6781
+       readyWait: 1,
+
+       // Hold (or release) the ready event
+       holdReady: function( hold ) {
+               if ( hold ) {
+                       jQuery.readyWait++;
+               } else {
+                       jQuery.ready( true );
+               }
+       },
+
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+
+               // Abort if there are pending holds or we're already ready
+               if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+                       return;
+               }
+
+               // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+               if ( !document.body ) {
+                       return setTimeout( jQuery.ready );
+               }
+
+               // Remember that the DOM is ready
+               jQuery.isReady = true;
+
+               // If a normal DOM Ready event fired, decrement, and wait if need be
+               if ( wait !== true && --jQuery.readyWait > 0 ) {
+                       return;
+               }
+
+               // If there are functions bound, to execute
+               readyList.resolveWith( document, [ jQuery ] );
+
+               // Trigger any bound ready events
+               if ( jQuery.fn.trigger ) {
+                       jQuery( document ).trigger("ready").off("ready");
+               }
+       },
+
+       // See test/unit/core.js for details concerning isFunction.
+       // Since version 1.3, DOM methods and functions like alert
+       // aren't supported. They return false on IE (#2968).
+       isFunction: function( obj ) {
+               return jQuery.type(obj) === "function";
+       },
+
+       isArray: Array.isArray || function( obj ) {
+               return jQuery.type(obj) === "array";
+       },
+
+       isWindow: function( obj ) {
+               /* jshint eqeqeq: false */
+               return obj != null && obj == obj.window;
+       },
+
+       isNumeric: function( obj ) {
+               return !isNaN( parseFloat(obj) ) && isFinite( obj );
+       },
+
+       type: function( obj ) {
+               if ( obj == null ) {
+                       return String( obj );
+               }
+               return typeof obj === "object" || typeof obj === "function" ?
+                       class2type[ core_toString.call(obj) ] || "object" :
+                       typeof obj;
+       },
+
+       isPlainObject: function( obj ) {
+               var key;
+
+               // Must be an Object.
+               // Because of IE, we also have to check the presence of the constructor property.
+               // Make sure that DOM nodes and window objects don't pass through, as well
+               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+                       return false;
+               }
+
+               try {
+                       // Not own constructor property must be Object
+                       if ( obj.constructor &&
+                               !core_hasOwn.call(obj, "constructor") &&
+                               !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+                               return false;
+                       }
+               } catch ( e ) {
+                       // IE8,9 Will throw exceptions on certain host objects #9897
+                       return false;
+               }
+
+               // Support: IE<9
+               // Handle iteration over inherited properties before own properties.
+               if ( jQuery.support.ownLast ) {
+                       for ( key in obj ) {
+                               return core_hasOwn.call( obj, key );
+                       }
+               }
+
+               // Own properties are enumerated firstly, so to speed up,
+               // if last one is own, then all properties are own.
+               for ( key in obj ) {}
+
+               return key === undefined || core_hasOwn.call( obj, key );
+       },
+
+       isEmptyObject: function( obj ) {
+               var name;
+               for ( name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+
+       error: function( msg ) {
+               throw new Error( msg );
+       },
+
+       // data: string of html
+       // context (optional): If specified, the fragment will be created in this context, defaults to document
+       // keepScripts (optional): If true, will include scripts passed in the html string
+       parseHTML: function( data, context, keepScripts ) {
+               if ( !data || typeof data !== "string" ) {
+                       return null;
+               }
+               if ( typeof context === "boolean" ) {
+                       keepScripts = context;
+                       context = false;
+               }
+               context = context || document;
+
+               var parsed = rsingleTag.exec( data ),
+                       scripts = !keepScripts && [];
+
+               // Single tag
+               if ( parsed ) {
+                       return [ context.createElement( parsed[1] ) ];
+               }
+
+               parsed = jQuery.buildFragment( [ data ], context, scripts );
+               if ( scripts ) {
+                       jQuery( scripts ).remove();
+               }
+               return jQuery.merge( [], parsed.childNodes );
+       },
+
+       parseJSON: function( data ) {
+               // Attempt to parse using the native JSON parser first
+               if ( window.JSON && window.JSON.parse ) {
+                       return window.JSON.parse( data );
+               }
+
+               if ( data === null ) {
+                       return data;
+               }
+
+               if ( typeof data === "string" ) {
+
+                       // Make sure leading/trailing whitespace is removed (IE can't handle it)
+                       data = jQuery.trim( data );
+
+                       if ( data ) {
+                               // Make sure the incoming data is actual JSON
+                               // Logic borrowed from http://json.org/json2.js
+                               if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+                                       .replace( rvalidtokens, "]" )
+                                       .replace( rvalidbraces, "")) ) {
+
+                                       return ( new Function( "return " + data ) )();
+                               }
+                       }
+               }
+
+               jQuery.error( "Invalid JSON: " + data );
+       },
+
+       // Cross-browser xml parsing
+       parseXML: function( data ) {
+               var xml, tmp;
+               if ( !data || typeof data !== "string" ) {
+                       return null;
+               }
+               try {
+                       if ( window.DOMParser ) { // Standard
+                               tmp = new DOMParser();
+                               xml = tmp.parseFromString( data , "text/xml" );
+                       } else { // IE
+                               xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                               xml.async = "false";
+                               xml.loadXML( data );
+                       }
+               } catch( e ) {
+                       xml = undefined;
+               }
+               if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+               return xml;
+       },
+
+       noop: function() {},
+
+       // Evaluates a script in a global context
+       // Workarounds based on findings by Jim Driscoll
+       // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+       globalEval: function( data ) {
+               if ( data && jQuery.trim( data ) ) {
+                       // We use execScript on Internet Explorer
+                       // We use an anonymous function so that context is window
+                       // rather than jQuery in Firefox
+                       ( window.execScript || function( data ) {
+                               window[ "eval" ].call( window, data );
+                       } )( data );
+               }
+       },
+
+       // Convert dashed to camelCase; used by the css and data modules
+       // Microsoft forgot to hump their vendor prefix (#9572)
+       camelCase: function( string ) {
+               return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+       },
+
+       nodeName: function( elem, name ) {
+               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+       },
+
+       // args is for internal usage only
+       each: function( obj, callback, args ) {
+               var value,
+                       i = 0,
+                       length = obj.length,
+                       isArray = isArraylike( obj );
+
+               if ( args ) {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               // A special, fast, case for the most common use of each
+               } else {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return obj;
+       },
+
+       // Use native String.trim function wherever possible
+       trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               core_trim.call( text );
+               } :
+
+               // Otherwise use our own trimming functionality
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               ( text + "" ).replace( rtrim, "" );
+               },
+
+       // results is for internal usage only
+       makeArray: function( arr, results ) {
+               var ret = results || [];
+
+               if ( arr != null ) {
+                       if ( isArraylike( Object(arr) ) ) {
+                               jQuery.merge( ret,
+                                       typeof arr === "string" ?
+                                       [ arr ] : arr
+                               );
+                       } else {
+                               core_push.call( ret, arr );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, arr, i ) {
+               var len;
+
+               if ( arr ) {
+                       if ( core_indexOf ) {
+                               return core_indexOf.call( arr, elem, i );
+                       }
+
+                       len = arr.length;
+                       i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+                       for ( ; i < len; i++ ) {
+                               // Skip accessing in sparse arrays
+                               if ( i in arr && arr[ i ] === elem ) {
+                                       return i;
+                               }
+                       }
+               }
+
+               return -1;
+       },
+
+       merge: function( first, second ) {
+               var l = second.length,
+                       i = first.length,
+                       j = 0;
+
+               if ( typeof l === "number" ) {
+                       for ( ; j < l; j++ ) {
+                               first[ i++ ] = second[ j ];
+                       }
+               } else {
+                       while ( second[j] !== undefined ) {
+                               first[ i++ ] = second[ j++ ];
+                       }
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, inv ) {
+               var retVal,
+                       ret = [],
+                       i = 0,
+                       length = elems.length;
+               inv = !!inv;
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( ; i < length; i++ ) {
+                       retVal = !!callback( elems[ i ], i );
+                       if ( inv !== retVal ) {
+                               ret.push( elems[ i ] );
+                       }
+               }
+
+               return ret;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var value,
+                       i = 0,
+                       length = elems.length,
+                       isArray = isArraylike( elems ),
+                       ret = [];
+
+               // Go through the array, translating each of the items to their
+               if ( isArray ) {
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( i in elems ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+               }
+
+               // Flatten any nested arrays
+               return core_concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               var args, proxy, tmp;
+
+               if ( typeof context === "string" ) {
+                       tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
+
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
+               }
+
+               // Simulated bind
+               args = core_slice.call( arguments, 2 );
+               proxy = function() {
+                       return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
+               };
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+               return proxy;
+       },
+
+       // Multifunctional method to get and set values of a collection
+       // The value/s can optionally be executed if it's a function
+       access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+               var i = 0,
+                       length = elems.length,
+                       bulk = key == null;
+
+               // Sets many values
+               if ( jQuery.type( key ) === "object" ) {
+                       chainable = true;
+                       for ( i in key ) {
+                               jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+                       }
+
+               // Sets one value
+               } else if ( value !== undefined ) {
+                       chainable = true;
+
+                       if ( !jQuery.isFunction( value ) ) {
+                               raw = true;
+                       }
+
+                       if ( bulk ) {
+                               // Bulk operations run against the entire set
+                               if ( raw ) {
+                                       fn.call( elems, value );
+                                       fn = null;
+
+                               // ...except when executing function values
+                               } else {
+                                       bulk = fn;
+                                       fn = function( elem, key, value ) {
+                                               return bulk.call( jQuery( elem ), value );
+                                       };
+                               }
+                       }
+
+                       if ( fn ) {
+                               for ( ; i < length; i++ ) {
+                                       fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+                               }
+                       }
+               }
+
+               return chainable ?
+                       elems :
+
+                       // Gets
+                       bulk ?
+                               fn.call( elems ) :
+                               length ? fn( elems[0], key ) : emptyGet;
+       },
+
+       now: function() {
+               return ( new Date() ).getTime();
+       },
+
+       // A method for quickly swapping in/out CSS properties to get correct calculations.
+       // Note: this method belongs to the css module but it's needed here for the support module.
+       // If support gets modularized, this method should be moved back to the css module.
+       swap: function( elem, options, callback, args ) {
+               var ret, name,
+                       old = {};
+
+               // Remember the old values, and insert the new ones
+               for ( name in options ) {
+                       old[ name ] = elem.style[ name ];
+                       elem.style[ name ] = options[ name ];
+               }
+
+               ret = callback.apply( elem, args || [] );
+
+               // Revert the old values
+               for ( name in options ) {
+                       elem.style[ name ] = old[ name ];
+               }
+
+               return ret;
+       }
+});
+
+jQuery.ready.promise = function( obj ) {
+       if ( !readyList ) {
+
+               readyList = jQuery.Deferred();
+
+               // Catch cases where $(document).ready() is called after the browser event has already occurred.
+               // we once tried to use readyState "interactive" here, but it caused issues like the one
+               // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+               if ( document.readyState === "complete" ) {
+                       // Handle it asynchronously to allow scripts the opportunity to delay ready
+                       setTimeout( jQuery.ready );
+
+               // Standards-based browsers support DOMContentLoaded
+               } else if ( document.addEventListener ) {
+                       // Use the handy event callback
+                       document.addEventListener( "DOMContentLoaded", completed, false );
+
+                       // A fallback to window.onload, that will always work
+                       window.addEventListener( "load", completed, false );
+
+               // If IE event model is used
+               } else {
+                       // Ensure firing before onload, maybe late but safe also for iframes
+                       document.attachEvent( "onreadystatechange", completed );
+
+                       // A fallback to window.onload, that will always work
+                       window.attachEvent( "onload", completed );
+
+                       // If IE and not a frame
+                       // continually check to see if the document is ready
+                       var top = false;
+
+                       try {
+                               top = window.frameElement == null && document.documentElement;
+                       } catch(e) {}
+
+                       if ( top && top.doScroll ) {
+                               (function doScrollCheck() {
+                                       if ( !jQuery.isReady ) {
+
+                                               try {
+                                                       // Use the trick by Diego Perini
+                                                       // http://javascript.nwbox.com/IEContentLoaded/
+                                                       top.doScroll("left");
+                                               } catch(e) {
+                                                       return setTimeout( doScrollCheck, 50 );
+                                               }
+
+                                               // detach all dom ready events
+                                               detach();
+
+                                               // and execute any waiting functions
+                                               jQuery.ready();
+                                       }
+                               })();
+                       }
+               }
+       }
+       return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+       class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+       var length = obj.length,
+               type = jQuery.type( obj );
+
+       if ( jQuery.isWindow( obj ) ) {
+               return false;
+       }
+
+       if ( obj.nodeType === 1 && length ) {
+               return true;
+       }
+
+       return type === "array" || type !== "function" &&
+               ( length === 0 ||
+               typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+/*!
+ * Sizzle CSS Selector Engine v1.10.2
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03
+ */
+(function( window, undefined ) {
+
+var i,
+       support,
+       cachedruns,
+       Expr,
+       getText,
+       isXML,
+       compile,
+       outermostContext,
+       sortInput,
+
+       // Local document vars
+       setDocument,
+       document,
+       docElem,
+       documentIsHTML,
+       rbuggyQSA,
+       rbuggyMatches,
+       matches,
+       contains,
+
+       // Instance-specific data
+       expando = "sizzle" + -(new Date()),
+       preferredDoc = window.document,
+       dirruns = 0,
+       done = 0,
+       classCache = createCache(),
+       tokenCache = createCache(),
+       compilerCache = createCache(),
+       hasDuplicate = false,
+       sortOrder = function( a, b ) {
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+               return 0;
+       },
+
+       // General-purpose constants
+       strundefined = typeof undefined,
+       MAX_NEGATIVE = 1 << 31,
+
+       // Instance methods
+       hasOwn = ({}).hasOwnProperty,
+       arr = [],
+       pop = arr.pop,
+       push_native = arr.push,
+       push = arr.push,
+       slice = arr.slice,
+       // Use a stripped-down indexOf if we can't use a native one
+       indexOf = arr.indexOf || function( elem ) {
+               var i = 0,
+                       len = this.length;
+               for ( ; i < len; i++ ) {
+                       if ( this[i] === elem ) {
+                               return i;
+                       }
+               }
+               return -1;
+       },
+
+       booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+       // Regular expressions
+
+       // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+       whitespace = "[\\x20\\t\\r\\n\\f]",
+       // http://www.w3.org/TR/css3-syntax/#characters
+       characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+       // Loosely modeled on CSS identifier characters
+       // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+       // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+       identifier = characterEncoding.replace( "w", "w#" ),
+
+       // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+       attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+               "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+       // Prefer arguments quoted,
+       //   then not containing pseudos/brackets,
+       //   then attribute selectors/non-parenthetical expressions,
+       //   then anything else
+       // These preferences are here to reduce the number of selectors
+       //   needing tokenize in the PSEUDO preFilter
+       pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+       rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+       rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+       rsibling = new RegExp( whitespace + "*[+~]" ),
+       rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
+
+       rpseudo = new RegExp( pseudos ),
+       ridentifier = new RegExp( "^" + identifier + "$" ),
+
+       matchExpr = {
+               "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+               "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+               "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+               "ATTR": new RegExp( "^" + attributes ),
+               "PSEUDO": new RegExp( "^" + pseudos ),
+               "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                       "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                       "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+               "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+               // For use in libraries implementing .is()
+               // We use this for POS matching in `select`
+               "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                       whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+       },
+
+       rnative = /^[^{]+\{\s*\[native \w/,
+
+       // Easily-parseable/retrievable ID or TAG or CLASS selectors
+       rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+       rinputs = /^(?:input|select|textarea|button)$/i,
+       rheader = /^h\d$/i,
+
+       rescape = /'|\\/g,
+
+       // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+       runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+       funescape = function( _, escaped, escapedWhitespace ) {
+               var high = "0x" + escaped - 0x10000;
+               // NaN means non-codepoint
+               // Support: Firefox
+               // Workaround erroneous numeric interpretation of +"0x"
+               return high !== high || escapedWhitespace ?
+                       escaped :
+                       // BMP codepoint
+                       high < 0 ?
+                               String.fromCharCode( high + 0x10000 ) :
+                               // Supplemental Plane codepoint (surrogate pair)
+                               String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+       };
+
+// Optimize for push.apply( _, NodeList )
+try {
+       push.apply(
+               (arr = slice.call( preferredDoc.childNodes )),
+               preferredDoc.childNodes
+       );
+       // Support: Android<4.0
+       // Detect silently failing push.apply
+       arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+       push = { apply: arr.length ?
+
+               // Leverage slice if possible
+               function( target, els ) {
+                       push_native.apply( target, slice.call(els) );
+               } :
+
+               // Support: IE<9
+               // Otherwise append directly
+               function( target, els ) {
+                       var j = target.length,
+                               i = 0;
+                       // Can't trust NodeList.length
+                       while ( (target[j++] = els[i++]) ) {}
+                       target.length = j - 1;
+               }
+       };
+}
+
+function Sizzle( selector, context, results, seed ) {
+       var match, elem, m, nodeType,
+               // QSA vars
+               i, groups, old, nid, newContext, newSelector;
+
+       if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+               setDocument( context );
+       }
+
+       context = context || document;
+       results = results || [];
+
+       if ( !selector || typeof selector !== "string" ) {
+               return results;
+       }
+
+       if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+               return [];
+       }
+
+       if ( documentIsHTML && !seed ) {
+
+               // Shortcuts
+               if ( (match = rquickExpr.exec( selector )) ) {
+                       // Speed-up: Sizzle("#ID")
+                       if ( (m = match[1]) ) {
+                               if ( nodeType === 9 ) {
+                                       elem = context.getElementById( m );
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE, Opera, and Webkit return items
+                                               // by name instead of ID
+                                               if ( elem.id === m ) {
+                                                       results.push( elem );
+                                                       return results;
+                                               }
+                                       } else {
+                                               return results;
+                                       }
+                               } else {
+                                       // Context is not a document
+                                       if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+                                               contains( context, elem ) && elem.id === m ) {
+                                               results.push( elem );
+                                               return results;
+                                       }
+                               }
+
+                       // Speed-up: Sizzle("TAG")
+                       } else if ( match[2] ) {
+                               push.apply( results, context.getElementsByTagName( selector ) );
+                               return results;
+
+                       // Speed-up: Sizzle(".CLASS")
+                       } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+                               push.apply( results, context.getElementsByClassName( m ) );
+                               return results;
+                       }
+               }
+
+               // QSA path
+               if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+                       nid = old = expando;
+                       newContext = context;
+                       newSelector = nodeType === 9 && selector;
+
+                       // qSA works strangely on Element-rooted queries
+                       // We can work around this by specifying an extra ID on the root
+                       // and working up from there (Thanks to Andrew Dupont for the technique)
+                       // IE 8 doesn't work on object elements
+                       if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+                               groups = tokenize( selector );
+
+                               if ( (old = context.getAttribute("id")) ) {
+                                       nid = old.replace( rescape, "\\$&" );
+                               } else {
+                                       context.setAttribute( "id", nid );
+                               }
+                               nid = "[id='" + nid + "'] ";
+
+                               i = groups.length;
+                               while ( i-- ) {
+                                       groups[i] = nid + toSelector( groups[i] );
+                               }
+                               newContext = rsibling.test( selector ) && context.parentNode || context;
+                               newSelector = groups.join(",");
+                       }
+
+                       if ( newSelector ) {
+                               try {
+                                       push.apply( results,
+                                               newContext.querySelectorAll( newSelector )
+                                       );
+                                       return results;
+                               } catch(qsaError) {
+                               } finally {
+                                       if ( !old ) {
+                                               context.removeAttribute("id");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // All others
+       return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *     property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *     deleting the oldest entry
+ */
+function createCache() {
+       var keys = [];
+
+       function cache( key, value ) {
+               // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+               if ( keys.push( key += " " ) > Expr.cacheLength ) {
+                       // Only keep the most recent entries
+                       delete cache[ keys.shift() ];
+               }
+               return (cache[ key ] = value);
+       }
+       return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+       fn[ expando ] = true;
+       return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+       var div = document.createElement("div");
+
+       try {
+               return !!fn( div );
+       } catch (e) {
+               return false;
+       } finally {
+               // Remove from its parent by default
+               if ( div.parentNode ) {
+                       div.parentNode.removeChild( div );
+               }
+               // release memory in IE
+               div = null;
+       }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+       var arr = attrs.split("|"),
+               i = attrs.length;
+
+       while ( i-- ) {
+               Expr.attrHandle[ arr[i] ] = handler;
+       }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+       var cur = b && a,
+               diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                       ( ~b.sourceIndex || MAX_NEGATIVE ) -
+                       ( ~a.sourceIndex || MAX_NEGATIVE );
+
+       // Use IE sourceIndex if available on both nodes
+       if ( diff ) {
+               return diff;
+       }
+
+       // Check if b follows a
+       if ( cur ) {
+               while ( (cur = cur.nextSibling) ) {
+                       if ( cur === b ) {
+                               return -1;
+                       }
+               }
+       }
+
+       return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return name === "input" && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return (name === "input" || name === "button") && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+       return markFunction(function( argument ) {
+               argument = +argument;
+               return markFunction(function( seed, matches ) {
+                       var j,
+                               matchIndexes = fn( [], seed.length, argument ),
+                               i = matchIndexes.length;
+
+                       // Match elements found at the specified indexes
+                       while ( i-- ) {
+                               if ( seed[ (j = matchIndexes[i]) ] ) {
+                                       seed[j] = !(matches[j] = seed[j]);
+                               }
+                       }
+               });
+       });
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+       // documentElement is verified for cases where it doesn't yet exist
+       // (such as loading iframes in IE - #4833)
+       var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+       return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+       var doc = node ? node.ownerDocument || node : preferredDoc,
+               parent = doc.defaultView;
+
+       // If no document and documentElement is available, return
+       if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+               return document;
+       }
+
+       // Set our document
+       document = doc;
+       docElem = doc.documentElement;
+
+       // Support tests
+       documentIsHTML = !isXML( doc );
+
+       // Support: IE>8
+       // If iframe document is assigned to "document" variable and if iframe has been reloaded,
+       // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+       // IE6-8 do not support the defaultView property so parent will be undefined
+       if ( parent && parent.attachEvent && parent !== parent.top ) {
+               parent.attachEvent( "onbeforeunload", function() {
+                       setDocument();
+               });
+       }
+
+       /* Attributes
+       ---------------------------------------------------------------------- */
+
+       // Support: IE<8
+       // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+       support.attributes = assert(function( div ) {
+               div.className = "i";
+               return !div.getAttribute("className");
+       });
+
+       /* getElement(s)By*
+       ---------------------------------------------------------------------- */
+
+       // Check if getElementsByTagName("*") returns only elements
+       support.getElementsByTagName = assert(function( div ) {
+               div.appendChild( doc.createComment("") );
+               return !div.getElementsByTagName("*").length;
+       });
+
+       // Check if getElementsByClassName can be trusted
+       support.getElementsByClassName = assert(function( div ) {
+               div.innerHTML = "<div class='a'></div><div class='a i'></div>";
+
+               // Support: Safari<4
+               // Catch class over-caching
+               div.firstChild.className = "i";
+               // Support: Opera<10
+               // Catch gEBCN failure to find non-leading classes
+               return div.getElementsByClassName("i").length === 2;
+       });
+
+       // Support: IE<10
+       // Check if getElementById returns elements by name
+       // The broken getElementById methods don't pick up programatically-set names,
+       // so use a roundabout getElementsByName test
+       support.getById = assert(function( div ) {
+               docElem.appendChild( div ).id = expando;
+               return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+       });
+
+       // ID find and filter
+       if ( support.getById ) {
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+                               var m = context.getElementById( id );
+                               // Check parentNode to catch when Blackberry 4.6 returns
+                               // nodes that are no longer in the document #6963
+                               return m && m.parentNode ? [m] : [];
+                       }
+               };
+               Expr.filter["ID"] = function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               return elem.getAttribute("id") === attrId;
+                       };
+               };
+       } else {
+               // Support: IE6/7
+               // getElementById is not reliable as a find shortcut
+               delete Expr.find["ID"];
+
+               Expr.filter["ID"] =  function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+                               return node && node.value === attrId;
+                       };
+               };
+       }
+
+       // Tag
+       Expr.find["TAG"] = support.getElementsByTagName ?
+               function( tag, context ) {
+                       if ( typeof context.getElementsByTagName !== strundefined ) {
+                               return context.getElementsByTagName( tag );
+                       }
+               } :
+               function( tag, context ) {
+                       var elem,
+                               tmp = [],
+                               i = 0,
+                               results = context.getElementsByTagName( tag );
+
+                       // Filter out possible comments
+                       if ( tag === "*" ) {
+                               while ( (elem = results[i++]) ) {
+                                       if ( elem.nodeType === 1 ) {
+                                               tmp.push( elem );
+                                       }
+                               }
+
+                               return tmp;
+                       }
+                       return results;
+               };
+
+       // Class
+       Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+               if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+                       return context.getElementsByClassName( className );
+               }
+       };
+
+       /* QSA/matchesSelector
+       ---------------------------------------------------------------------- */
+
+       // QSA and matchesSelector support
+
+       // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+       rbuggyMatches = [];
+
+       // qSa(:focus) reports false when true (Chrome 21)
+       // We allow this because of a bug in IE8/9 that throws an error
+       // whenever `document.activeElement` is accessed on an iframe
+       // So, we allow :focus to pass through QSA all the time to avoid the IE error
+       // See http://bugs.jquery.com/ticket/13378
+       rbuggyQSA = [];
+
+       if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+               // Build QSA regex
+               // Regex strategy adopted from Diego Perini
+               assert(function( div ) {
+                       // Select is set to empty string on purpose
+                       // This is to test IE's treatment of not explicitly
+                       // setting a boolean content attribute,
+                       // since its presence should be enough
+                       // http://bugs.jquery.com/ticket/12359
+                       div.innerHTML = "<select><option selected=''></option></select>";
+
+                       // Support: IE8
+                       // Boolean attributes and "value" are not treated correctly
+                       if ( !div.querySelectorAll("[selected]").length ) {
+                               rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+                       }
+
+                       // Webkit/Opera - :checked should return selected option elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":checked").length ) {
+                               rbuggyQSA.push(":checked");
+                       }
+               });
+
+               assert(function( div ) {
+
+                       // Support: Opera 10-12/IE8
+                       // ^= $= *= and empty values
+                       // Should not select anything
+                       // Support: Windows 8 Native Apps
+                       // The type attribute is restricted during .innerHTML assignment
+                       var input = doc.createElement("input");
+                       input.setAttribute( "type", "hidden" );
+                       div.appendChild( input ).setAttribute( "t", "" );
+
+                       if ( div.querySelectorAll("[t^='']").length ) {
+                               rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+                       }
+
+                       // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":enabled").length ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Opera 10-11 does not throw on post-comma invalid pseudos
+                       div.querySelectorAll("*,:x");
+                       rbuggyQSA.push(",.*:");
+               });
+       }
+
+       if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
+               docElem.mozMatchesSelector ||
+               docElem.oMatchesSelector ||
+               docElem.msMatchesSelector) )) ) {
+
+               assert(function( div ) {
+                       // Check to see if it's possible to do matchesSelector
+                       // on a disconnected node (IE 9)
+                       support.disconnectedMatch = matches.call( div, "div" );
+
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( div, "[s!='']:x" );
+                       rbuggyMatches.push( "!=", pseudos );
+               });
+       }
+
+       rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+       rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+       /* Contains
+       ---------------------------------------------------------------------- */
+
+       // Element contains another
+       // Purposefully does not implement inclusive descendent
+       // As in, an element does not contain itself
+       contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
+               function( a, b ) {
+                       var adown = a.nodeType === 9 ? a.documentElement : a,
+                               bup = b && b.parentNode;
+                       return a === bup || !!( bup && bup.nodeType === 1 && (
+                               adown.contains ?
+                                       adown.contains( bup ) :
+                                       a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+                       ));
+               } :
+               function( a, b ) {
+                       if ( b ) {
+                               while ( (b = b.parentNode) ) {
+                                       if ( b === a ) {
+                                               return true;
+                                       }
+                               }
+                       }
+                       return false;
+               };
+
+       /* Sorting
+       ---------------------------------------------------------------------- */
+
+       // Document order sorting
+       sortOrder = docElem.compareDocumentPosition ?
+       function( a, b ) {
+
+               // Flag for duplicate removal
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
+
+               if ( compare ) {
+                       // Disconnected nodes
+                       if ( compare & 1 ||
+                               (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+                               // Choose the first element that is related to our preferred document
+                               if ( a === doc || contains(preferredDoc, a) ) {
+                                       return -1;
+                               }
+                               if ( b === doc || contains(preferredDoc, b) ) {
+                                       return 1;
+                               }
+
+                               // Maintain original order
+                               return sortInput ?
+                                       ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                                       0;
+                       }
+
+                       return compare & 4 ? -1 : 1;
+               }
+
+               // Not directly comparable, sort on existence of method
+               return a.compareDocumentPosition ? -1 : 1;
+       } :
+       function( a, b ) {
+               var cur,
+                       i = 0,
+                       aup = a.parentNode,
+                       bup = b.parentNode,
+                       ap = [ a ],
+                       bp = [ b ];
+
+               // Exit early if the nodes are identical
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+
+               // Parentless nodes are either documents or disconnected
+               } else if ( !aup || !bup ) {
+                       return a === doc ? -1 :
+                               b === doc ? 1 :
+                               aup ? -1 :
+                               bup ? 1 :
+                               sortInput ?
+                               ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                               0;
+
+               // If the nodes are siblings, we can do a quick check
+               } else if ( aup === bup ) {
+                       return siblingCheck( a, b );
+               }
+
+               // Otherwise we need full lists of their ancestors for comparison
+               cur = a;
+               while ( (cur = cur.parentNode) ) {
+                       ap.unshift( cur );
+               }
+               cur = b;
+               while ( (cur = cur.parentNode) ) {
+                       bp.unshift( cur );
+               }
+
+               // Walk down the tree looking for a discrepancy
+               while ( ap[i] === bp[i] ) {
+                       i++;
+               }
+
+               return i ?
+                       // Do a sibling check if the nodes have a common ancestor
+                       siblingCheck( ap[i], bp[i] ) :
+
+                       // Otherwise nodes in our document sort first
+                       ap[i] === preferredDoc ? -1 :
+                       bp[i] === preferredDoc ? 1 :
+                       0;
+       };
+
+       return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+       return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       // Make sure that attribute selectors are quoted
+       expr = expr.replace( rattributeQuotes, "='$1']" );
+
+       if ( support.matchesSelector && documentIsHTML &&
+               ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+               ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+               try {
+                       var ret = matches.call( elem, expr );
+
+                       // IE 9's matchesSelector returns false on disconnected nodes
+                       if ( ret || support.disconnectedMatch ||
+                                       // As well, disconnected nodes are said to be in a document
+                                       // fragment in IE 9
+                                       elem.document && elem.document.nodeType !== 11 ) {
+                               return ret;
+                       }
+               } catch(e) {}
+       }
+
+       return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+       // Set document vars if needed
+       if ( ( context.ownerDocument || context ) !== document ) {
+               setDocument( context );
+       }
+       return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       var fn = Expr.attrHandle[ name.toLowerCase() ],
+               // Don't get fooled by Object.prototype properties (jQuery #13807)
+               val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+                       fn( elem, name, !documentIsHTML ) :
+                       undefined;
+
+       return val === undefined ?
+               support.attributes || !documentIsHTML ?
+                       elem.getAttribute( name ) :
+                       (val = elem.getAttributeNode(name)) && val.specified ?
+                               val.value :
+                               null :
+               val;
+};
+
+Sizzle.error = function( msg ) {
+       throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+       var elem,
+               duplicates = [],
+               j = 0,
+               i = 0;
+
+       // Unless we *know* we can detect duplicates, assume their presence
+       hasDuplicate = !support.detectDuplicates;
+       sortInput = !support.sortStable && results.slice( 0 );
+       results.sort( sortOrder );
+
+       if ( hasDuplicate ) {
+               while ( (elem = results[i++]) ) {
+                       if ( elem === results[ i ] ) {
+                               j = duplicates.push( i );
+                       }
+               }
+               while ( j-- ) {
+                       results.splice( duplicates[ j ], 1 );
+               }
+       }
+
+       return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+       var node,
+               ret = "",
+               i = 0,
+               nodeType = elem.nodeType;
+
+       if ( !nodeType ) {
+               // If no nodeType, this is expected to be an array
+               for ( ; (node = elem[i]); i++ ) {
+                       // Do not traverse comment nodes
+                       ret += getText( node );
+               }
+       } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+               // Use textContent for elements
+               // innerText usage removed for consistency of new lines (see #11153)
+               if ( typeof elem.textContent === "string" ) {
+                       return elem.textContent;
+               } else {
+                       // Traverse its children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               ret += getText( elem );
+                       }
+               }
+       } else if ( nodeType === 3 || nodeType === 4 ) {
+               return elem.nodeValue;
+       }
+       // Do not include comment or processing instruction nodes
+
+       return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+       // Can be adjusted by the user
+       cacheLength: 50,
+
+       createPseudo: markFunction,
+
+       match: matchExpr,
+
+       attrHandle: {},
+
+       find: {},
+
+       relative: {
+               ">": { dir: "parentNode", first: true },
+               " ": { dir: "parentNode" },
+               "+": { dir: "previousSibling", first: true },
+               "~": { dir: "previousSibling" }
+       },
+
+       preFilter: {
+               "ATTR": function( match ) {
+                       match[1] = match[1].replace( runescape, funescape );
+
+                       // Move the given value to match[3] whether quoted or unquoted
+                       match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+                       if ( match[2] === "~=" ) {
+                               match[3] = " " + match[3] + " ";
+                       }
+
+                       return match.slice( 0, 4 );
+               },
+
+               "CHILD": function( match ) {
+                       /* matches from matchExpr["CHILD"]
+                               1 type (only|nth|...)
+                               2 what (child|of-type)
+                               3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                               4 xn-component of xn+y argument ([+-]?\d*n|)
+                               5 sign of xn-component
+                               6 x of xn-component
+                               7 sign of y-component
+                               8 y of y-component
+                       */
+                       match[1] = match[1].toLowerCase();
+
+                       if ( match[1].slice( 0, 3 ) === "nth" ) {
+                               // nth-* requires argument
+                               if ( !match[3] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               // numeric x and y parameters for Expr.filter.CHILD
+                               // remember that false/true cast respectively to 0/1
+                               match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+                               match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+                       // other types prohibit arguments
+                       } else if ( match[3] ) {
+                               Sizzle.error( match[0] );
+                       }
+
+                       return match;
+               },
+
+               "PSEUDO": function( match ) {
+                       var excess,
+                               unquoted = !match[5] && match[2];
+
+                       if ( matchExpr["CHILD"].test( match[0] ) ) {
+                               return null;
+                       }
+
+                       // Accept quoted arguments as-is
+                       if ( match[3] && match[4] !== undefined ) {
+                               match[2] = match[4];
+
+                       // Strip excess characters from unquoted arguments
+                       } else if ( unquoted && rpseudo.test( unquoted ) &&
+                               // Get excess from tokenize (recursively)
+                               (excess = tokenize( unquoted, true )) &&
+                               // advance to the next closing parenthesis
+                               (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+                               // excess is a negative index
+                               match[0] = match[0].slice( 0, excess );
+                               match[2] = unquoted.slice( 0, excess );
+                       }
+
+                       // Return only captures needed by the pseudo filter method (type and argument)
+                       return match.slice( 0, 3 );
+               }
+       },
+
+       filter: {
+
+               "TAG": function( nodeNameSelector ) {
+                       var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+                       return nodeNameSelector === "*" ?
+                               function() { return true; } :
+                               function( elem ) {
+                                       return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                               };
+               },
+
+               "CLASS": function( className ) {
+                       var pattern = classCache[ className + " " ];
+
+                       return pattern ||
+                               (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+                               classCache( className, function( elem ) {
+                                       return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+                               });
+               },
+
+               "ATTR": function( name, operator, check ) {
+                       return function( elem ) {
+                               var result = Sizzle.attr( elem, name );
+
+                               if ( result == null ) {
+                                       return operator === "!=";
+                               }
+                               if ( !operator ) {
+                                       return true;
+                               }
+
+                               result += "";
+
+                               return operator === "=" ? result === check :
+                                       operator === "!=" ? result !== check :
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :
+                                       operator === "$=" ? check && result.slice( -check.length ) === check :
+                                       operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+                                       operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+                                       false;
+                       };
+               },
+
+               "CHILD": function( type, what, argument, first, last ) {
+                       var simple = type.slice( 0, 3 ) !== "nth",
+                               forward = type.slice( -4 ) !== "last",
+                               ofType = what === "of-type";
+
+                       return first === 1 && last === 0 ?
+
+                               // Shortcut for :nth-*(n)
+                               function( elem ) {
+                                       return !!elem.parentNode;
+                               } :
+
+                               function( elem, context, xml ) {
+                                       var cache, outerCache, node, diff, nodeIndex, start,
+                                               dir = simple !== forward ? "nextSibling" : "previousSibling",
+                                               parent = elem.parentNode,
+                                               name = ofType && elem.nodeName.toLowerCase(),
+                                               useCache = !xml && !ofType;
+
+                                       if ( parent ) {
+
+                                               // :(first|last|only)-(child|of-type)
+                                               if ( simple ) {
+                                                       while ( dir ) {
+                                                               node = elem;
+                                                               while ( (node = node[ dir ]) ) {
+                                                                       if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+                                                                               return false;
+                                                                       }
+                                                               }
+                                                               // Reverse direction for :only-* (if we haven't yet done so)
+                                                               start = dir = type === "only" && !start && "nextSibling";
+                                                       }
+                                                       return true;
+                                               }
+
+                                               start = [ forward ? parent.firstChild : parent.lastChild ];
+
+                                               // non-xml :nth-child(...) stores cache data on `parent`
+                                               if ( forward && useCache ) {
+                                                       // Seek `elem` from a previously-cached index
+                                                       outerCache = parent[ expando ] || (parent[ expando ] = {});
+                                                       cache = outerCache[ type ] || [];
+                                                       nodeIndex = cache[0] === dirruns && cache[1];
+                                                       diff = cache[0] === dirruns && cache[2];
+                                                       node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+                                                               // Fallback to seeking `elem` from the start
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               // When found, cache indexes on `parent` and break
+                                                               if ( node.nodeType === 1 && ++diff && node === elem ) {
+                                                                       outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+                                                                       break;
+                                                               }
+                                                       }
+
+                                               // Use previously-cached element index if available
+                                               } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+                                                       diff = cache[1];
+
+                                               // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+                                               } else {
+                                                       // Use the same loop as above to seek `elem` from the start
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+                                                                       // Cache the index of each encountered element
+                                                                       if ( useCache ) {
+                                                                               (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+                                                                       }
+
+                                                                       if ( node === elem ) {
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               // Incorporate the offset, then check against cycle size
+                                               diff -= last;
+                                               return diff === first || ( diff % first === 0 && diff / first >= 0 );
+                                       }
+                               };
+               },
+
+               "PSEUDO": function( pseudo, argument ) {
+                       // pseudo-class names are case-insensitive
+                       // http://www.w3.org/TR/selectors/#pseudo-classes
+                       // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+                       // Remember that setFilters inherits from pseudos
+                       var args,
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );
+
+                       // The user may use createPseudo to indicate that
+                       // arguments are needed to create the filter function
+                       // just as Sizzle does
+                       if ( fn[ expando ] ) {
+                               return fn( argument );
+                       }
+
+                       // But maintain support for old signatures
+                       if ( fn.length > 1 ) {
+                               args = [ pseudo, pseudo, "", argument ];
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                                       markFunction(function( seed, matches ) {
+                                               var idx,
+                                                       matched = fn( seed, argument ),
+                                                       i = matched.length;
+                                               while ( i-- ) {
+                                                       idx = indexOf.call( seed, matched[i] );
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );
+                                               }
+                                       }) :
+                                       function( elem ) {
+                                               return fn( elem, 0, args );
+                                       };
+                       }
+
+                       return fn;
+               }
+       },
+
+       pseudos: {
+               // Potentially complex pseudos
+               "not": markFunction(function( selector ) {
+                       // Trim the selector passed to compile
+                       // to avoid treating leading and trailing
+                       // spaces as combinators
+                       var input = [],
+                               results = [],
+                               matcher = compile( selector.replace( rtrim, "$1" ) );
+
+                       return matcher[ expando ] ?
+                               markFunction(function( seed, matches, context, xml ) {
+                                       var elem,
+                                               unmatched = matcher( seed, null, xml, [] ),
+                                               i = seed.length;
+
+                                       // Match elements unmatched by `matcher`
+                                       while ( i-- ) {
+                                               if ( (elem = unmatched[i]) ) {
+                                                       seed[i] = !(matches[i] = elem);
+                                               }
+                                       }
+                               }) :
+                               function( elem, context, xml ) {
+                                       input[0] = elem;
+                                       matcher( input, null, xml, results );
+                                       return !results.pop();
+                               };
+               }),
+
+               "has": markFunction(function( selector ) {
+                       return function( elem ) {
+                               return Sizzle( selector, elem ).length > 0;
+                       };
+               }),
+
+               "contains": markFunction(function( text ) {
+                       return function( elem ) {
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+                       };
+               }),
+
+               // "Whether an element is represented by a :lang() selector
+               // is based solely on the element's language value
+               // being equal to the identifier C,
+               // or beginning with the identifier C immediately followed by "-".
+               // The matching of C against the element's language value is performed case-insensitively.
+               // The identifier C does not have to be a valid language name."
+               // http://www.w3.org/TR/selectors/#lang-pseudo
+               "lang": markFunction( function( lang ) {
+                       // lang value must be a valid identifier
+                       if ( !ridentifier.test(lang || "") ) {
+                               Sizzle.error( "unsupported lang: " + lang );
+                       }
+                       lang = lang.replace( runescape, funescape ).toLowerCase();
+                       return function( elem ) {
+                               var elemLang;
+                               do {
+                                       if ( (elemLang = documentIsHTML ?
+                                               elem.lang :
+                                               elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+                                               elemLang = elemLang.toLowerCase();
+                                               return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+                                       }
+                               } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                               return false;
+                       };
+               }),
+
+               // Miscellaneous
+               "target": function( elem ) {
+                       var hash = window.location && window.location.hash;
+                       return hash && hash.slice( 1 ) === elem.id;
+               },
+
+               "root": function( elem ) {
+                       return elem === docElem;
+               },
+
+               "focus": function( elem ) {
+                       return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+               },
+
+               // Boolean properties
+               "enabled": function( elem ) {
+                       return elem.disabled === false;
+               },
+
+               "disabled": function( elem ) {
+                       return elem.disabled === true;
+               },
+
+               "checked": function( elem ) {
+                       // In CSS3, :checked should return both checked and selected elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       var nodeName = elem.nodeName.toLowerCase();
+                       return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+               },
+
+               "selected": function( elem ) {
+                       // Accessing this property makes selected-by-default
+                       // options in Safari work properly
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
+
+                       return elem.selected === true;
+               },
+
+               // Contents
+               "empty": function( elem ) {
+                       // http://www.w3.org/TR/selectors/#empty-pseudo
+                       // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+                       //   not comment, processing instructions, or others
+                       // Thanks to Diego Perini for the nodeName shortcut
+                       //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               },
+
+               "parent": function( elem ) {
+                       return !Expr.pseudos["empty"]( elem );
+               },
+
+               // Element/input types
+               "header": function( elem ) {
+                       return rheader.test( elem.nodeName );
+               },
+
+               "input": function( elem ) {
+                       return rinputs.test( elem.nodeName );
+               },
+
+               "button": function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && elem.type === "button" || name === "button";
+               },
+
+               "text": function( elem ) {
+                       var attr;
+                       // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+                       // use getAttribute instead to test this case
+                       return elem.nodeName.toLowerCase() === "input" &&
+                               elem.type === "text" &&
+                               ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+               },
+
+               // Position-in-collection
+               "first": createPositionalPseudo(function() {
+                       return [ 0 ];
+               }),
+
+               "last": createPositionalPseudo(function( matchIndexes, length ) {
+                       return [ length - 1 ];
+               }),
+
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       return [ argument < 0 ? argument + length : argument ];
+               }),
+
+               "even": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 0;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "odd": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 1;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; --i >= 0; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; ++i < length; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               })
+       }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+       Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+       Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+function tokenize( selector, parseOnly ) {
+       var matched, match, tokens, type,
+               soFar, groups, preFilters,
+               cached = tokenCache[ selector + " " ];
+
+       if ( cached ) {
+               return parseOnly ? 0 : cached.slice( 0 );
+       }
+
+       soFar = selector;
+       groups = [];
+       preFilters = Expr.preFilter;
+
+       while ( soFar ) {
+
+               // Comma and first run
+               if ( !matched || (match = rcomma.exec( soFar )) ) {
+                       if ( match ) {
+                               // Don't consume trailing commas as valid
+                               soFar = soFar.slice( match[0].length ) || soFar;
+                       }
+                       groups.push( tokens = [] );
+               }
+
+               matched = false;
+
+               // Combinators
+               if ( (match = rcombinators.exec( soFar )) ) {
+                       matched = match.shift();
+                       tokens.push({
+                               value: matched,
+                               // Cast descendant combinators to space
+                               type: match[0].replace( rtrim, " " )
+                       });
+                       soFar = soFar.slice( matched.length );
+               }
+
+               // Filters
+               for ( type in Expr.filter ) {
+                       if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+                               (match = preFilters[ type ]( match ))) ) {
+                               matched = match.shift();
+                               tokens.push({
+                                       value: matched,
+                                       type: type,
+                                       matches: match
+                               });
+                               soFar = soFar.slice( matched.length );
+                       }
+               }
+
+               if ( !matched ) {
+                       break;
+               }
+       }
+
+       // Return the length of the invalid excess
+       // if we're just parsing
+       // Otherwise, throw an error or return tokens
+       return parseOnly ?
+               soFar.length :
+               soFar ?
+                       Sizzle.error( selector ) :
+                       // Cache the tokens
+                       tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+       var i = 0,
+               len = tokens.length,
+               selector = "";
+       for ( ; i < len; i++ ) {
+               selector += tokens[i].value;
+       }
+       return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+       var dir = combinator.dir,
+               checkNonElements = base && dir === "parentNode",
+               doneName = done++;
+
+       return combinator.first ?
+               // Check against closest ancestor/preceding element
+               function( elem, context, xml ) {
+                       while ( (elem = elem[ dir ]) ) {
+                               if ( elem.nodeType === 1 || checkNonElements ) {
+                                       return matcher( elem, context, xml );
+                               }
+                       }
+               } :
+
+               // Check against all ancestor/preceding elements
+               function( elem, context, xml ) {
+                       var data, cache, outerCache,
+                               dirkey = dirruns + " " + doneName;
+
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+                       if ( xml ) {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       } else {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               outerCache = elem[ expando ] || (elem[ expando ] = {});
+                                               if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+                                                       if ( (data = cache[1]) === true || data === cachedruns ) {
+                                                               return data === true;
+                                                       }
+                                               } else {
+                                                       cache = outerCache[ dir ] = [ dirkey ];
+                                                       cache[1] = matcher( elem, context, xml ) || cachedruns;
+                                                       if ( cache[1] === true ) {
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               };
+}
+
+function elementMatcher( matchers ) {
+       return matchers.length > 1 ?
+               function( elem, context, xml ) {
+                       var i = matchers.length;
+                       while ( i-- ) {
+                               if ( !matchers[i]( elem, context, xml ) ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               } :
+               matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+       var elem,
+               newUnmatched = [],
+               i = 0,
+               len = unmatched.length,
+               mapped = map != null;
+
+       for ( ; i < len; i++ ) {
+               if ( (elem = unmatched[i]) ) {
+                       if ( !filter || filter( elem, context, xml ) ) {
+                               newUnmatched.push( elem );
+                               if ( mapped ) {
+                                       map.push( i );
+                               }
+                       }
+               }
+       }
+
+       return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+       if ( postFilter && !postFilter[ expando ] ) {
+               postFilter = setMatcher( postFilter );
+       }
+       if ( postFinder && !postFinder[ expando ] ) {
+               postFinder = setMatcher( postFinder, postSelector );
+       }
+       return markFunction(function( seed, results, context, xml ) {
+               var temp, i, elem,
+                       preMap = [],
+                       postMap = [],
+                       preexisting = results.length,
+
+                       // Get initial elements from seed or context
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization
+                       matcherIn = preFilter && ( seed || !selector ) ?
+                               condense( elems, preMap, preFilter, context, xml ) :
+                               elems,
+
+                       matcherOut = matcher ?
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+                                       // ...intermediate processing is necessary
+                                       [] :
+
+                                       // ...otherwise use results directly
+                                       results :
+                               matcherIn;
+
+               // Find primary matches
+               if ( matcher ) {
+                       matcher( matcherIn, matcherOut, context, xml );
+               }
+
+               // Apply postFilter
+               if ( postFilter ) {
+                       temp = condense( matcherOut, postMap );
+                       postFilter( temp, [], context, xml );
+
+                       // Un-match failing elements by moving them back to matcherIn
+                       i = temp.length;
+                       while ( i-- ) {
+                               if ( (elem = temp[i]) ) {
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                               }
+                       }
+               }
+
+               if ( seed ) {
+                       if ( postFinder || preFilter ) {
+                               if ( postFinder ) {
+                                       // Get the final matcherOut by condensing this intermediate into postFinder contexts
+                                       temp = [];
+                                       i = matcherOut.length;
+                                       while ( i-- ) {
+                                               if ( (elem = matcherOut[i]) ) {
+                                                       // Restore matcherIn since elem is not yet a final match
+                                                       temp.push( (matcherIn[i] = elem) );
+                                               }
+                                       }
+                                       postFinder( null, (matcherOut = []), temp, xml );
+                               }
+
+                               // Move matched elements from seed to results to keep them synchronized
+                               i = matcherOut.length;
+                               while ( i-- ) {
+                                       if ( (elem = matcherOut[i]) &&
+                                               (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+                                               seed[temp] = !(results[temp] = elem);
+                                       }
+                               }
+                       }
+
+               // Add elements to results, through postFinder if defined
+               } else {
+                       matcherOut = condense(
+                               matcherOut === results ?
+                                       matcherOut.splice( preexisting, matcherOut.length ) :
+                                       matcherOut
+                       );
+                       if ( postFinder ) {
+                               postFinder( null, results, matcherOut, xml );
+                       } else {
+                               push.apply( results, matcherOut );
+                       }
+               }
+       });
+}
+
+function matcherFromTokens( tokens ) {
+       var checkContext, matcher, j,
+               len = tokens.length,
+               leadingRelative = Expr.relative[ tokens[0].type ],
+               implicitRelative = leadingRelative || Expr.relative[" "],
+               i = leadingRelative ? 1 : 0,
+
+               // The foundational matcher ensures that elements are reachable from top-level context(s)
+               matchContext = addCombinator( function( elem ) {
+                       return elem === checkContext;
+               }, implicitRelative, true ),
+               matchAnyContext = addCombinator( function( elem ) {
+                       return indexOf.call( checkContext, elem ) > -1;
+               }, implicitRelative, true ),
+               matchers = [ function( elem, context, xml ) {
+                       return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+                               (checkContext = context).nodeType ?
+                                       matchContext( elem, context, xml ) :
+                                       matchAnyContext( elem, context, xml ) );
+               } ];
+
+       for ( ; i < len; i++ ) {
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+                       matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+               } else {
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+                       // Return special upon seeing a positional matcher
+                       if ( matcher[ expando ] ) {
+                               // Find the next relative operator (if any) for proper handling
+                               j = ++i;
+                               for ( ; j < len; j++ ) {
+                                       if ( Expr.relative[ tokens[j].type ] ) {
+                                               break;
+                                       }
+                               }
+                               return setMatcher(
+                                       i > 1 && elementMatcher( matchers ),
+                                       i > 1 && toSelector(
+                                               // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+                                               tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+                                       ).replace( rtrim, "$1" ),
+                                       matcher,
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+                                       j < len && toSelector( tokens )
+                               );
+                       }
+                       matchers.push( matcher );
+               }
+       }
+
+       return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+       // A counter to specify which element is currently being matched
+       var matcherCachedRuns = 0,
+               bySet = setMatchers.length > 0,
+               byElement = elementMatchers.length > 0,
+               superMatcher = function( seed, context, xml, results, expandContext ) {
+                       var elem, j, matcher,
+                               setMatched = [],
+                               matchedCount = 0,
+                               i = "0",
+                               unmatched = seed && [],
+                               outermost = expandContext != null,
+                               contextBackup = outermostContext,
+                               // We must always have either seed elements or context
+                               elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+                               // Use integer dirruns iff this is the outermost matcher
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+                       if ( outermost ) {
+                               outermostContext = context !== document && context;
+                               cachedruns = matcherCachedRuns;
+                       }
+
+                       // Add elements passing elementMatchers directly to results
+                       // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+                       for ( ; (elem = elems[i]) != null; i++ ) {
+                               if ( byElement && elem ) {
+                                       j = 0;
+                                       while ( (matcher = elementMatchers[j++]) ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       results.push( elem );
+                                                       break;
+                                               }
+                                       }
+                                       if ( outermost ) {
+                                               dirruns = dirrunsUnique;
+                                               cachedruns = ++matcherCachedRuns;
+                                       }
+                               }
+
+                               // Track unmatched elements for set filters
+                               if ( bySet ) {
+                                       // They will have gone through all possible matchers
+                                       if ( (elem = !matcher && elem) ) {
+                                               matchedCount--;
+                                       }
+
+                                       // Lengthen the array for every element, matched or not
+                                       if ( seed ) {
+                                               unmatched.push( elem );
+                                       }
+                               }
+                       }
+
+                       // Apply set filters to unmatched elements
+                       matchedCount += i;
+                       if ( bySet && i !== matchedCount ) {
+                               j = 0;
+                               while ( (matcher = setMatchers[j++]) ) {
+                                       matcher( unmatched, setMatched, context, xml );
+                               }
+
+                               if ( seed ) {
+                                       // Reintegrate element matches to eliminate the need for sorting
+                                       if ( matchedCount > 0 ) {
+                                               while ( i-- ) {
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {
+                                                               setMatched[i] = pop.call( results );
+                                                       }
+                                               }
+                                       }
+
+                                       // Discard index placeholder values to get only actual matches
+                                       setMatched = condense( setMatched );
+                               }
+
+                               // Add matches to results
+                               push.apply( results, setMatched );
+
+                               // Seedless set matches succeeding multiple successful matchers stipulate sorting
+                               if ( outermost && !seed && setMatched.length > 0 &&
+                                       ( matchedCount + setMatchers.length ) > 1 ) {
+
+                                       Sizzle.uniqueSort( results );
+                               }
+                       }
+
+                       // Override manipulation of globals by nested matchers
+                       if ( outermost ) {
+                               dirruns = dirrunsUnique;
+                               outermostContext = contextBackup;
+                       }
+
+                       return unmatched;
+               };
+
+       return bySet ?
+               markFunction( superMatcher ) :
+               superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+       var i,
+               setMatchers = [],
+               elementMatchers = [],
+               cached = compilerCache[ selector + " " ];
+
+       if ( !cached ) {
+               // Generate a function of recursive functions that can be used to check each element
+               if ( !group ) {
+                       group = tokenize( selector );
+               }
+               i = group.length;
+               while ( i-- ) {
+                       cached = matcherFromTokens( group[i] );
+                       if ( cached[ expando ] ) {
+                               setMatchers.push( cached );
+                       } else {
+                               elementMatchers.push( cached );
+                       }
+               }
+
+               // Cache the compiled function
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+       }
+       return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+       var i = 0,
+               len = contexts.length;
+       for ( ; i < len; i++ ) {
+               Sizzle( selector, contexts[i], results );
+       }
+       return results;
+}
+
+function select( selector, context, results, seed ) {
+       var i, tokens, token, type, find,
+               match = tokenize( selector );
+
+       if ( !seed ) {
+               // Try to minimize operations if there is only one group
+               if ( match.length === 1 ) {
+
+                       // Take a shortcut and set the context if the root selector is an ID
+                       tokens = match[0] = match[0].slice( 0 );
+                       if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                                       support.getById && context.nodeType === 9 && documentIsHTML &&
+                                       Expr.relative[ tokens[1].type ] ) {
+
+                               context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+                               if ( !context ) {
+                                       return results;
+                               }
+                               selector = selector.slice( tokens.shift().value.length );
+                       }
+
+                       // Fetch a seed set for right-to-left matching
+                       i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+                       while ( i-- ) {
+                               token = tokens[i];
+
+                               // Abort if we hit a combinator
+                               if ( Expr.relative[ (type = token.type) ] ) {
+                                       break;
+                               }
+                               if ( (find = Expr.find[ type ]) ) {
+                                       // Search, expanding context for leading sibling combinators
+                                       if ( (seed = find(
+                                               token.matches[0].replace( runescape, funescape ),
+                                               rsibling.test( tokens[0].type ) && context.parentNode || context
+                                       )) ) {
+
+                                               // If seed is empty or no tokens remain, we can return early
+                                               tokens.splice( i, 1 );
+                                               selector = seed.length && toSelector( tokens );
+                                               if ( !selector ) {
+                                                       push.apply( results, seed );
+                                                       return results;
+                                               }
+
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // Compile and execute a filtering function
+       // Provide `match` to avoid retokenization if we modified the selector above
+       compile( selector, match )(
+               seed,
+               context,
+               !documentIsHTML,
+               results,
+               rsibling.test( selector )
+       );
+       return results;
+}
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+       // Should return 1, but returns 4 (following)
+       return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+       div.innerHTML = "<a href='#'></a>";
+       return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+       addHandle( "type|href|height|width", function( elem, name, isXML ) {
+               if ( !isXML ) {
+                       return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+               }
+       });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+       div.innerHTML = "<input/>";
+       div.firstChild.setAttribute( "value", "" );
+       return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+       addHandle( "value", function( elem, name, isXML ) {
+               if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+                       return elem.defaultValue;
+               }
+       });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+       return div.getAttribute("disabled") == null;
+}) ) {
+       addHandle( booleans, function( elem, name, isXML ) {
+               var val;
+               if ( !isXML ) {
+                       return (val = elem.getAttributeNode( name )) && val.specified ?
+                               val.value :
+                               elem[ name ] === true ? name.toLowerCase() : null;
+               }
+       });
+}
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+       var object = optionsCache[ options ] = {};
+       jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
+               object[ flag ] = true;
+       });
+       return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *     options: an optional list of space-separated options that will change how
+ *                     the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *     once:                   will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *     memory:                 will keep track of previous values and will call any callback added
+ *                                     after the list has been fired right away with the latest "memorized"
+ *                                     values (like a Deferred)
+ *
+ *     unique:                 will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *     stopOnFalse:    interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+       // Convert options from String-formatted to Object-formatted if needed
+       // (we check in cache first)
+       options = typeof options === "string" ?
+               ( optionsCache[ options ] || createOptions( options ) ) :
+               jQuery.extend( {}, options );
+
+       var // Flag to know if list is currently firing
+               firing,
+               // Last fire value (for non-forgettable lists)
+               memory,
+               // Flag to know if list was already fired
+               fired,
+               // End of the loop when firing
+               firingLength,
+               // Index of currently firing callback (modified by remove if needed)
+               firingIndex,
+               // First callback to fire (used internally by add and fireWith)
+               firingStart,
+               // Actual callback list
+               list = [],
+               // Stack of fire calls for repeatable lists
+               stack = !options.once && [],
+               // Fire callbacks
+               fire = function( data ) {
+                       memory = options.memory && data;
+                       fired = true;
+                       firingIndex = firingStart || 0;
+                       firingStart = 0;
+                       firingLength = list.length;
+                       firing = true;
+                       for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+                               if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+                                       memory = false; // To prevent further calls using add
+                                       break;
+                               }
+                       }
+                       firing = false;
+                       if ( list ) {
+                               if ( stack ) {
+                                       if ( stack.length ) {
+                                               fire( stack.shift() );
+                                       }
+                               } else if ( memory ) {
+                                       list = [];
+                               } else {
+                                       self.disable();
+                               }
+                       }
+               },
+               // Actual Callbacks object
+               self = {
+                       // Add a callback or a collection of callbacks to the list
+                       add: function() {
+                               if ( list ) {
+                                       // First, we save the current length
+                                       var start = list.length;
+                                       (function add( args ) {
+                                               jQuery.each( args, function( _, arg ) {
+                                                       var type = jQuery.type( arg );
+                                                       if ( type === "function" ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && type !== "string" ) {
+                                                               // Inspect recursively
+                                                               add( arg );
+                                                       }
+                                               });
+                                       })( arguments );
+                                       // Do we need to add the callbacks to the
+                                       // current firing batch?
+                                       if ( firing ) {
+                                               firingLength = list.length;
+                                       // With memory, if we're not firing then
+                                       // we should call right away
+                                       } else if ( memory ) {
+                                               firingStart = start;
+                                               fire( memory );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Remove a callback from the list
+                       remove: function() {
+                               if ( list ) {
+                                       jQuery.each( arguments, function( _, arg ) {
+                                               var index;
+                                               while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+                                                       list.splice( index, 1 );
+                                                       // Handle firing indexes
+                                                       if ( firing ) {
+                                                               if ( index <= firingLength ) {
+                                                                       firingLength--;
+                                                               }
+                                                               if ( index <= firingIndex ) {
+                                                                       firingIndex--;
+                                                               }
+                                                       }
+                                               }
+                                       });
+                               }
+                               return this;
+                       },
+                       // Check if a given callback is in the list.
+                       // If no argument is given, return whether or not list has callbacks attached.
+                       has: function( fn ) {
+                               return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+                       },
+                       // Remove all callbacks from the list
+                       empty: function() {
+                               list = [];
+                               firingLength = 0;
+                               return this;
+                       },
+                       // Have the list do nothing anymore
+                       disable: function() {
+                               list = stack = memory = undefined;
+                               return this;
+                       },
+                       // Is it disabled?
+                       disabled: function() {
+                               return !list;
+                       },
+                       // Lock the list in its current state
+                       lock: function() {
+                               stack = undefined;
+                               if ( !memory ) {
+                                       self.disable();
+                               }
+                               return this;
+                       },
+                       // Is it locked?
+                       locked: function() {
+                               return !stack;
+                       },
+                       // Call all callbacks with the given context and arguments
+                       fireWith: function( context, args ) {
+                               if ( list && ( !fired || stack ) ) {
+                                       args = args || [];
+                                       args = [ context, args.slice ? args.slice() : args ];
+                                       if ( firing ) {
+                                               stack.push( args );
+                                       } else {
+                                               fire( args );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Call all the callbacks with the given arguments
+                       fire: function() {
+                               self.fireWith( this, arguments );
+                               return this;
+                       },
+                       // To know if the callbacks have already been called at least once
+                       fired: function() {
+                               return !!fired;
+                       }
+               };
+
+       return self;
+};
+jQuery.extend({
+
+       Deferred: function( func ) {
+               var tuples = [
+                               // action, add listener, listener list, final state
+                               [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+                               [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+                               [ "notify", "progress", jQuery.Callbacks("memory") ]
+                       ],
+                       state = "pending",
+                       promise = {
+                               state: function() {
+                                       return state;
+                               },
+                               always: function() {
+                                       deferred.done( arguments ).fail( arguments );
+                                       return this;
+                               },
+                               then: function( /* fnDone, fnFail, fnProgress */ ) {
+                                       var fns = arguments;
+                                       return jQuery.Deferred(function( newDefer ) {
+                                               jQuery.each( tuples, function( i, tuple ) {
+                                                       var action = tuple[ 0 ],
+                                                               fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+                                                       // deferred[ done | fail | progress ] for forwarding actions to newDefer
+                                                       deferred[ tuple[1] ](function() {
+                                                               var returned = fn && fn.apply( this, arguments );
+                                                               if ( returned && jQuery.isFunction( returned.promise ) ) {
+                                                                       returned.promise()
+                                                                               .done( newDefer.resolve )
+                                                                               .fail( newDefer.reject )
+                                                                               .progress( newDefer.notify );
+                                                               } else {
+                                                                       newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+                                                               }
+                                                       });
+                                               });
+                                               fns = null;
+                                       }).promise();
+                               },
+                               // Get a promise for this deferred
+                               // If obj is provided, the promise aspect is added to the object
+                               promise: function( obj ) {
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
+                               }
+                       },
+                       deferred = {};
+
+               // Keep pipe for back-compat
+               promise.pipe = promise.then;
+
+               // Add list-specific methods
+               jQuery.each( tuples, function( i, tuple ) {
+                       var list = tuple[ 2 ],
+                               stateString = tuple[ 3 ];
+
+                       // promise[ done | fail | progress ] = list.add
+                       promise[ tuple[1] ] = list.add;
+
+                       // Handle state
+                       if ( stateString ) {
+                               list.add(function() {
+                                       // state = [ resolved | rejected ]
+                                       state = stateString;
+
+                               // [ reject_list | resolve_list ].disable; progress_list.lock
+                               }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+                       }
+
+                       // deferred[ resolve | reject | notify ]
+                       deferred[ tuple[0] ] = function() {
+                               deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+                               return this;
+                       };
+                       deferred[ tuple[0] + "With" ] = list.fireWith;
+               });
+
+               // Make the deferred a promise
+               promise.promise( deferred );
+
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+
+               // All done!
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( subordinate /* , ..., subordinateN */ ) {
+               var i = 0,
+                       resolveValues = core_slice.call( arguments ),
+                       length = resolveValues.length,
+
+                       // the count of uncompleted subordinates
+                       remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+                       // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+                       deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+                       // Update function for both resolve and progress values
+                       updateFunc = function( i, contexts, values ) {
+                               return function( value ) {
+                                       contexts[ i ] = this;
+                                       values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+                                       if( values === progressValues ) {
+                                               deferred.notifyWith( contexts, values );
+                                       } else if ( !( --remaining ) ) {
+                                               deferred.resolveWith( contexts, values );
+                                       }
+                               };
+                       },
+
+                       progressValues, progressContexts, resolveContexts;
+
+               // add listeners to Deferred subordinates; treat others as resolved
+               if ( length > 1 ) {
+                       progressValues = new Array( length );
+                       progressContexts = new Array( length );
+                       resolveContexts = new Array( length );
+                       for ( ; i < length; i++ ) {
+                               if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+                                       resolveValues[ i ].promise()
+                                               .done( updateFunc( i, resolveContexts, resolveValues ) )
+                                               .fail( deferred.reject )
+                                               .progress( updateFunc( i, progressContexts, progressValues ) );
+                               } else {
+                                       --remaining;
+                               }
+                       }
+               }
+
+               // if we're not waiting on anything, resolve the master
+               if ( !remaining ) {
+                       deferred.resolveWith( resolveContexts, resolveValues );
+               }
+
+               return deferred.promise();
+       }
+});
+jQuery.support = (function( support ) {
+
+       var all, a, input, select, fragment, opt, eventName, isSupported, i,
+               div = document.createElement("div");
+
+       // Setup
+       div.setAttribute( "className", "t" );
+       div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+       // Finish early in limited (non-browser) environments
+       all = div.getElementsByTagName("*") || [];
+       a = div.getElementsByTagName("a")[ 0 ];
+       if ( !a || !a.style || !all.length ) {
+               return support;
+       }
+
+       // First batch of tests
+       select = document.createElement("select");
+       opt = select.appendChild( document.createElement("option") );
+       input = div.getElementsByTagName("input")[ 0 ];
+
+       a.style.cssText = "top:1px;float:left;opacity:.5";
+
+       // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+       support.getSetAttribute = div.className !== "t";
+
+       // IE strips leading whitespace when .innerHTML is used
+       support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+       // Make sure that tbody elements aren't automatically inserted
+       // IE will insert them into empty tables
+       support.tbody = !div.getElementsByTagName("tbody").length;
+
+       // Make sure that link elements get serialized correctly by innerHTML
+       // This requires a wrapper element in IE
+       support.htmlSerialize = !!div.getElementsByTagName("link").length;
+
+       // Get the style information from getAttribute
+       // (IE uses .cssText instead)
+       support.style = /top/.test( a.getAttribute("style") );
+
+       // Make sure that URLs aren't manipulated
+       // (IE normalizes it by default)
+       support.hrefNormalized = a.getAttribute("href") === "/a";
+
+       // Make sure that element opacity exists
+       // (IE uses filter instead)
+       // Use a regex to work around a WebKit issue. See #5145
+       support.opacity = /^0.5/.test( a.style.opacity );
+
+       // Verify style float existence
+       // (IE uses styleFloat instead of cssFloat)
+       support.cssFloat = !!a.style.cssFloat;
+
+       // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+       support.checkOn = !!input.value;
+
+       // Make sure that a selected-by-default option has a working selected property.
+       // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+       support.optSelected = opt.selected;
+
+       // Tests for enctype support on a form (#6743)
+       support.enctype = !!document.createElement("form").enctype;
+
+       // Makes sure cloning an html5 element does not cause problems
+       // Where outerHTML is undefined, this still works
+       support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>";
+
+       // Will be defined later
+       support.inlineBlockNeedsLayout = false;
+       support.shrinkWrapBlocks = false;
+       support.pixelPosition = false;
+       support.deleteExpando = true;
+       support.noCloneEvent = true;
+       support.reliableMarginRight = true;
+       support.boxSizingReliable = true;
+
+       // Make sure checked status is properly cloned
+       input.checked = true;
+       support.noCloneChecked = input.cloneNode( true ).checked;
+
+       // Make sure that the options inside disabled selects aren't marked as disabled
+       // (WebKit marks them as disabled)
+       select.disabled = true;
+       support.optDisabled = !opt.disabled;
+
+       // Support: IE<9
+       try {
+               delete div.test;
+       } catch( e ) {
+               support.deleteExpando = false;
+       }
+
+       // Check if we can trust getAttribute("value")
+       input = document.createElement("input");
+       input.setAttribute( "value", "" );
+       support.input = input.getAttribute( "value" ) === "";
+
+       // Check if an input maintains its value after becoming a radio
+       input.value = "t";
+       input.setAttribute( "type", "radio" );
+       support.radioValue = input.value === "t";
+
+       // #11217 - WebKit loses check when the name is after the checked attribute
+       input.setAttribute( "checked", "t" );
+       input.setAttribute( "name", "t" );
+
+       fragment = document.createDocumentFragment();
+       fragment.appendChild( input );
+
+       // Check if a disconnected checkbox will retain its checked
+       // value of true after appended to the DOM (IE6/7)
+       support.appendChecked = input.checked;
+
+       // WebKit doesn't clone checked state correctly in fragments
+       support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       // Support: IE<9
+       // Opera does not clone events (and typeof div.attachEvent === undefined).
+       // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+       if ( div.attachEvent ) {
+               div.attachEvent( "onclick", function() {
+                       support.noCloneEvent = false;
+               });
+
+               div.cloneNode( true ).click();
+       }
+
+       // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+       // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
+       for ( i in { submit: true, change: true, focusin: true }) {
+               div.setAttribute( eventName = "on" + i, "t" );
+
+               support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+       }
+
+       div.style.backgroundClip = "content-box";
+       div.cloneNode( true ).style.backgroundClip = "";
+       support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+       // Support: IE<9
+       // Iteration over object's inherited properties before its own.
+       for ( i in jQuery( support ) ) {
+               break;
+       }
+       support.ownLast = i !== "0";
+
+       // Run tests that need a body at doc ready
+       jQuery(function() {
+               var container, marginDiv, tds,
+                       divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+                       body = document.getElementsByTagName("body")[0];
+
+               if ( !body ) {
+                       // Return for frameset docs that don't have a body
+                       return;
+               }
+
+               container = document.createElement("div");
+               container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+               body.appendChild( container ).appendChild( div );
+
+               // Support: IE8
+               // Check if table cells still have offsetWidth/Height when they are set
+               // to display:none and there are still other visible table cells in a
+               // table row; if so, offsetWidth/Height are not reliable for use when
+               // determining if an element has been hidden directly using
+               // display:none (it is still safe to use offsets if a parent element is
+               // hidden; don safety goggles and see bug #4512 for more information).
+               div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+               tds = div.getElementsByTagName("td");
+               tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+               isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+               tds[ 0 ].style.display = "";
+               tds[ 1 ].style.display = "none";
+
+               // Support: IE8
+               // Check if empty table cells still have offsetWidth/Height
+               support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+               // Check box-sizing and margin behavior.
+               div.innerHTML = "";
+               div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+
+               // Workaround failing boxSizing test due to offsetWidth returning wrong value
+               // with some non-1 values of body zoom, ticket #13543
+               jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
+                       support.boxSizing = div.offsetWidth === 4;
+               });
+
+               // Use window.getComputedStyle because jsdom on node.js will break without it.
+               if ( window.getComputedStyle ) {
+                       support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+                       support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+                       // Check if div with explicit width and no margin-right incorrectly
+                       // gets computed margin-right based on width of container. (#3333)
+                       // Fails in WebKit before Feb 2011 nightlies
+                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                       marginDiv = div.appendChild( document.createElement("div") );
+                       marginDiv.style.cssText = div.style.cssText = divReset;
+                       marginDiv.style.marginRight = marginDiv.style.width = "0";
+                       div.style.width = "1px";
+
+                       support.reliableMarginRight =
+                               !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+               }
+
+               if ( typeof div.style.zoom !== core_strundefined ) {
+                       // Support: IE<8
+                       // Check if natively block-level elements act like inline-block
+                       // elements when setting their display to 'inline' and giving
+                       // them layout
+                       div.innerHTML = "";
+                       div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+                       support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+                       // Support: IE6
+                       // Check if elements with layout shrink-wrap their children
+                       div.style.display = "block";
+                       div.innerHTML = "<div></div>";
+                       div.firstChild.style.width = "5px";
+                       support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+                       if ( support.inlineBlockNeedsLayout ) {
+                               // Prevent IE 6 from affecting layout for positioned elements #11048
+                               // Prevent IE from shrinking the body in IE 7 mode #12869
+                               // Support: IE<8
+                               body.style.zoom = 1;
+                       }
+               }
+
+               body.removeChild( container );
+
+               // Null elements to avoid leaks in IE
+               container = div = tds = marginDiv = null;
+       });
+
+       // Null elements to avoid leaks in IE
+       all = select = fragment = opt = a = input = null;
+
+       return support;
+})({});
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+       rmultiDash = /([A-Z])/g;
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+       if ( !jQuery.acceptData( elem ) ) {
+               return;
+       }
+
+       var ret, thisCache,
+               internalKey = jQuery.expando,
+
+               // We have to handle DOM nodes and JS objects differently because IE6-7
+               // can't GC object references properly across the DOM-JS boundary
+               isNode = elem.nodeType,
+
+               // Only DOM nodes need the global jQuery cache; JS object data is
+               // attached directly to the object so GC can occur automatically
+               cache = isNode ? jQuery.cache : elem,
+
+               // Only defining an ID for JS objects if its cache already exists allows
+               // the code to shortcut on the same path as a DOM node with no cache
+               id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+       // Avoid doing any more work than we need to when trying to get data on an
+       // object that has no data at all
+       if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
+               return;
+       }
+
+       if ( !id ) {
+               // Only DOM nodes need a new unique ID for each element since their data
+               // ends up in the global cache
+               if ( isNode ) {
+                       id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;
+               } else {
+                       id = internalKey;
+               }
+       }
+
+       if ( !cache[ id ] ) {
+               // Avoid exposing jQuery metadata on plain JS objects when the object
+               // is serialized using JSON.stringify
+               cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
+       }
+
+       // An object can be passed to jQuery.data instead of a key/value pair; this gets
+       // shallow copied over onto the existing cache
+       if ( typeof name === "object" || typeof name === "function" ) {
+               if ( pvt ) {
+                       cache[ id ] = jQuery.extend( cache[ id ], name );
+               } else {
+                       cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+               }
+       }
+
+       thisCache = cache[ id ];
+
+       // jQuery data() is stored in a separate object inside the object's internal data
+       // cache in order to avoid key collisions between internal data and user-defined
+       // data.
+       if ( !pvt ) {
+               if ( !thisCache.data ) {
+                       thisCache.data = {};
+               }
+
+               thisCache = thisCache.data;
+       }
+
+       if ( data !== undefined ) {
+               thisCache[ jQuery.camelCase( name ) ] = data;
+       }
+
+       // Check for both converted-to-camel and non-converted data property names
+       // If a data property was specified
+       if ( typeof name === "string" ) {
+
+               // First Try to find as-is property data
+               ret = thisCache[ name ];
+
+               // Test for null|undefined property data
+               if ( ret == null ) {
+
+                       // Try to find the camelCased property
+                       ret = thisCache[ jQuery.camelCase( name ) ];
+               }
+       } else {
+               ret = thisCache;
+       }
+
+       return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+       if ( !jQuery.acceptData( elem ) ) {
+               return;
+       }
+
+       var thisCache, i,
+               isNode = elem.nodeType,
+
+               // See jQuery.data for more information
+               cache = isNode ? jQuery.cache : elem,
+               id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+       // If there is already no cache entry for this object, there is no
+       // purpose in continuing
+       if ( !cache[ id ] ) {
+               return;
+       }
+
+       if ( name ) {
+
+               thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+               if ( thisCache ) {
+
+                       // Support array or space separated string names for data keys
+                       if ( !jQuery.isArray( name ) ) {
+
+                               // try the string as a key before any manipulation
+                               if ( name in thisCache ) {
+                                       name = [ name ];
+                               } else {
+
+                                       // split the camel cased version by spaces unless a key with the spaces exists
+                                       name = jQuery.camelCase( name );
+                                       if ( name in thisCache ) {
+                                               name = [ name ];
+                                       } else {
+                                               name = name.split(" ");
+                                       }
+                               }
+                       } else {
+                               // If "name" is an array of keys...
+                               // When data is initially created, via ("key", "val") signature,
+                               // keys will be converted to camelCase.
+                               // Since there is no way to tell _how_ a key was added, remove
+                               // both plain key and camelCase key. #12786
+                               // This will only penalize the array argument path.
+                               name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+                       }
+
+                       i = name.length;
+                       while ( i-- ) {
+                               delete thisCache[ name[i] ];
+                       }
+
+                       // If there is no data left in the cache, we want to continue
+                       // and let the cache object itself get destroyed
+                       if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
+                               return;
+                       }
+               }
+       }
+
+       // See jQuery.data for more information
+       if ( !pvt ) {
+               delete cache[ id ].data;
+
+               // Don't destroy the parent cache unless the internal data object
+               // had been the only thing left in it
+               if ( !isEmptyDataObject( cache[ id ] ) ) {
+                       return;
+               }
+       }
+
+       // Destroy the cache
+       if ( isNode ) {
+               jQuery.cleanData( [ elem ], true );
+
+       // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+       /* jshint eqeqeq: false */
+       } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+               /* jshint eqeqeq: true */
+               delete cache[ id ];
+
+       // When all else fails, null
+       } else {
+               cache[ id ] = null;
+       }
+}
+
+jQuery.extend({
+       cache: {},
+
+       // The following elements throw uncatchable exceptions if you
+       // attempt to add expando properties to them.
+       noData: {
+               "applet": true,
+               "embed": true,
+               // Ban all objects except for Flash (which handle expandos)
+               "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+       },
+
+       hasData: function( elem ) {
+               elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+               return !!elem && !isEmptyDataObject( elem );
+       },
+
+       data: function( elem, name, data ) {
+               return internalData( elem, name, data );
+       },
+
+       removeData: function( elem, name ) {
+               return internalRemoveData( elem, name );
+       },
+
+       // For internal use only.
+       _data: function( elem, name, data ) {
+               return internalData( elem, name, data, true );
+       },
+
+       _removeData: function( elem, name ) {
+               return internalRemoveData( elem, name, true );
+       },
+
+       // A method for determining if a DOM node can handle the data expando
+       acceptData: function( elem ) {
+               // Do not set data on non-element because it will not be cleared (#8335).
+               if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+                       return false;
+               }
+
+               var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+               // nodes accept data unless otherwise specified; rejection can be conditional
+               return !noData || noData !== true && elem.getAttribute("classid") === noData;
+       }
+});
+
+jQuery.fn.extend({
+       data: function( key, value ) {
+               var attrs, name,
+                       data = null,
+                       i = 0,
+                       elem = this[0];
+
+               // Special expections of .data basically thwart jQuery.access,
+               // so implement the relevant behavior ourselves
+
+               // Gets all values
+               if ( key === undefined ) {
+                       if ( this.length ) {
+                               data = jQuery.data( elem );
+
+                               if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+                                       attrs = elem.attributes;
+                                       for ( ; i < attrs.length; i++ ) {
+                                               name = attrs[i].name;
+
+                                               if ( name.indexOf("data-") === 0 ) {
+                                                       name = jQuery.camelCase( name.slice(5) );
+
+                                                       dataAttr( elem, name, data[ name ] );
+                                               }
+                                       }
+                                       jQuery._data( elem, "parsedAttrs", true );
+                               }
+                       }
+
+                       return data;
+               }
+
+               // Sets multiple values
+               if ( typeof key === "object" ) {
+                       return this.each(function() {
+                               jQuery.data( this, key );
+                       });
+               }
+
+               return arguments.length > 1 ?
+
+                       // Sets one value
+                       this.each(function() {
+                               jQuery.data( this, key, value );
+                       }) :
+
+                       // Gets one value
+                       // Try to fetch any internally stored data first
+                       elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+       },
+
+       removeData: function( key ) {
+               return this.each(function() {
+                       jQuery.removeData( this, key );
+               });
+       }
+});
+
+function dataAttr( elem, key, data ) {
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+
+               var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+               data = elem.getAttribute( name );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                                       data === "false" ? false :
+                                       data === "null" ? null :
+                                       // Only convert to a number if it doesn't change the string
+                                       +data + "" === data ? +data :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                               data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       jQuery.data( elem, key, data );
+
+               } else {
+                       data = undefined;
+               }
+       }
+
+       return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+       var name;
+       for ( name in obj ) {
+
+               // if the public data object is empty, the private is still empty
+               if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+                       continue;
+               }
+               if ( name !== "toJSON" ) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+jQuery.extend({
+       queue: function( elem, type, data ) {
+               var queue;
+
+               if ( elem ) {
+                       type = ( type || "fx" ) + "queue";
+                       queue = jQuery._data( elem, type );
+
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !queue || jQuery.isArray(data) ) {
+                                       queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+                               } else {
+                                       queue.push( data );
+                               }
+                       }
+                       return queue || [];
+               }
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ),
+                       startLength = queue.length,
+                       fn = queue.shift(),
+                       hooks = jQuery._queueHooks( elem, type ),
+                       next = function() {
+                               jQuery.dequeue( elem, type );
+                       };
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+                       startLength--;
+               }
+
+               if ( fn ) {
+
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift( "inprogress" );
+                       }
+
+                       // clear up the last queue stop function
+                       delete hooks.stop;
+                       fn.call( elem, next, hooks );
+               }
+
+               if ( !startLength && hooks ) {
+                       hooks.empty.fire();
+               }
+       },
+
+       // not intended for public consumption - generates a queueHooks object, or returns the current one
+       _queueHooks: function( elem, type ) {
+               var key = type + "queueHooks";
+               return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+                       empty: jQuery.Callbacks("once memory").add(function() {
+                               jQuery._removeData( elem, type + "queue" );
+                               jQuery._removeData( elem, key );
+                       })
+               });
+       }
+});
+
+jQuery.fn.extend({
+       queue: function( type, data ) {
+               var setter = 2;
+
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+                       setter--;
+               }
+
+               if ( arguments.length < setter ) {
+                       return jQuery.queue( this[0], type );
+               }
+
+               return data === undefined ?
+                       this :
+                       this.each(function() {
+                               var queue = jQuery.queue( this, type, data );
+
+                               // ensure a hooks for this queue
+                               jQuery._queueHooks( this, type );
+
+                               if ( type === "fx" && queue[0] !== "inprogress" ) {
+                                       jQuery.dequeue( this, type );
+                               }
+                       });
+       },
+       dequeue: function( type ) {
+               return this.each(function() {
+                       jQuery.dequeue( this, type );
+               });
+       },
+       // Based off of the plugin by Clint Helfers, with permission.
+       // http://blindsignals.com/index.php/2009/07/jquery-delay/
+       delay: function( time, type ) {
+               time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+               type = type || "fx";
+
+               return this.queue( type, function( next, hooks ) {
+                       var timeout = setTimeout( next, time );
+                       hooks.stop = function() {
+                               clearTimeout( timeout );
+                       };
+               });
+       },
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       },
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, obj ) {
+               var tmp,
+                       count = 1,
+                       defer = jQuery.Deferred(),
+                       elements = this,
+                       i = this.length,
+                       resolve = function() {
+                               if ( !( --count ) ) {
+                                       defer.resolveWith( elements, [ elements ] );
+                               }
+                       };
+
+               if ( typeof type !== "string" ) {
+                       obj = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+
+               while( i-- ) {
+                       tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+                       if ( tmp && tmp.empty ) {
+                               count++;
+                               tmp.empty.add( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise( obj );
+       }
+});
+var nodeHook, boolHook,
+       rclass = /[\t\r\n\f]/g,
+       rreturn = /\r/g,
+       rfocusable = /^(?:input|select|textarea|button|object)$/i,
+       rclickable = /^(?:a|area)$/i,
+       ruseDefault = /^(?:checked|selected)$/i,
+       getSetAttribute = jQuery.support.getSetAttribute,
+       getSetInput = jQuery.support.input;
+
+jQuery.fn.extend({
+       attr: function( name, value ) {
+               return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+       },
+
+       removeAttr: function( name ) {
+               return this.each(function() {
+                       jQuery.removeAttr( this, name );
+               });
+       },
+
+       prop: function( name, value ) {
+               return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+       },
+
+       removeProp: function( name ) {
+               name = jQuery.propFix[ name ] || name;
+               return this.each(function() {
+                       // try/catch handles cases where IE balks (such as removing a property on window)
+                       try {
+                               this[ name ] = undefined;
+                               delete this[ name ];
+                       } catch( e ) {}
+               });
+       },
+
+       addClass: function( value ) {
+               var classes, elem, cur, clazz, j,
+                       i = 0,
+                       len = this.length,
+                       proceed = typeof value === "string" && value;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).addClass( value.call( this, j, this.className ) );
+                       });
+               }
+
+               if ( proceed ) {
+                       // The disjunction here is for better compressibility (see removeClass)
+                       classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       " "
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+                                                       cur += clazz + " ";
+                                               }
+                                       }
+                                       elem.className = jQuery.trim( cur );
+
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               var classes, elem, cur, clazz, j,
+                       i = 0,
+                       len = this.length,
+                       proceed = arguments.length === 0 || typeof value === "string" && value;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).removeClass( value.call( this, j, this.className ) );
+                       });
+               }
+               if ( proceed ) {
+                       classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               // This expression is here for better compressibility (see addClass)
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       ""
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               // Remove *all* instances
+                                               while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+                                                       cur = cur.replace( " " + clazz + " ", " " );
+                                               }
+                                       }
+                                       elem.className = value ? jQuery.trim( cur ) : "";
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value;
+
+               if ( typeof stateVal === "boolean" && type === "string" ) {
+                       return stateVal ? this.addClass( value ) : this.removeClass( value );
+               }
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( i ) {
+                               jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+                       });
+               }
+
+               return this.each(function() {
+                       if ( type === "string" ) {
+                               // toggle individual class names
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
+                                       classNames = value.match( core_rnotwhite ) || [];
+
+                               while ( (className = classNames[ i++ ]) ) {
+                                       // check each className given, space separated list
+                                       if ( self.hasClass( className ) ) {
+                                               self.removeClass( className );
+                                       } else {
+                                               self.addClass( className );
+                                       }
+                               }
+
+                       // Toggle whole class name
+                       } else if ( type === core_strundefined || type === "boolean" ) {
+                               if ( this.className ) {
+                                       // store className if set
+                                       jQuery._data( this, "__className__", this.className );
+                               }
+
+                               // If the element has a class name or if we're passed "false",
+                               // then remove the whole classname (if there was one, the above saved it).
+                               // Otherwise bring back whatever was previously saved (if anything),
+                               // falling back to the empty string if nothing was stored.
+                               this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+                       }
+               });
+       },
+
+       hasClass: function( selector ) {
+               var className = " " + selector + " ",
+                       i = 0,
+                       l = this.length;
+               for ( ; i < l; i++ ) {
+                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       },
+
+       val: function( value ) {
+               var ret, hooks, isFunction,
+                       elem = this[0];
+
+               if ( !arguments.length ) {
+                       if ( elem ) {
+                               hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+                               if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+                                       return ret;
+                               }
+
+                               ret = elem.value;
+
+                               return typeof ret === "string" ?
+                                       // handle most common string cases
+                                       ret.replace(rreturn, "") :
+                                       // handle cases where value is null/undef or number
+                                       ret == null ? "" : ret;
+                       }
+
+                       return;
+               }
+
+               isFunction = jQuery.isFunction( value );
+
+               return this.each(function( i ) {
+                       var val;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call( this, i, jQuery( this ).val() );
+                       } else {
+                               val = value;
+                       }
+
+                       // Treat null/undefined as ""; convert numbers to string
+                       if ( val == null ) {
+                               val = "";
+                       } else if ( typeof val === "number" ) {
+                               val += "";
+                       } else if ( jQuery.isArray( val ) ) {
+                               val = jQuery.map(val, function ( value ) {
+                                       return value == null ? "" : value + "";
+                               });
+                       }
+
+                       hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+                               // Use proper attribute retrieval(#6932, #12072)
+                               var val = jQuery.find.attr( elem, "value" );
+                               return val != null ?
+                                       val :
+                                       elem.text;
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var value, option,
+                                       options = elem.options,
+                                       index = elem.selectedIndex,
+                                       one = elem.type === "select-one" || index < 0,
+                                       values = one ? null : [],
+                                       max = one ? index + 1 : options.length,
+                                       i = index < 0 ?
+                                               max :
+                                               one ? index : 0;
+
+                               // Loop through all the selected options
+                               for ( ; i < max; i++ ) {
+                                       option = options[ i ];
+
+                                       // oldIE doesn't update selected after form reset (#2551)
+                                       if ( ( option.selected || i === index ) &&
+                                                       // Don't return options that are disabled or in a disabled optgroup
+                                                       ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+                                                       ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var optionSet, option,
+                                       options = elem.options,
+                                       values = jQuery.makeArray( value ),
+                                       i = options.length;
+
+                               while ( i-- ) {
+                                       option = options[ i ];
+                                       if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
+                                               optionSet = true;
+                                       }
+                               }
+
+                               // force browsers to behave consistently when non-matching value is set
+                               if ( !optionSet ) {
+                                       elem.selectedIndex = -1;
+                               }
+                               return values;
+                       }
+               }
+       },
+
+       attr: function( elem, name, value ) {
+               var hooks, ret,
+                       nType = elem.nodeType;
+
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               // Fallback to prop when attributes are not supported
+               if ( typeof elem.getAttribute === core_strundefined ) {
+                       return jQuery.prop( elem, name, value );
+               }
+
+               // All attributes are lowercase
+               // Grab necessary hook if one is defined
+               if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+                       name = name.toLowerCase();
+                       hooks = jQuery.attrHooks[ name ] ||
+                               ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+               }
+
+               if ( value !== undefined ) {
+
+                       if ( value === null ) {
+                               jQuery.removeAttr( elem, name );
+
+                       } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               elem.setAttribute( name, value + "" );
+                               return value;
+                       }
+
+               } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+                       return ret;
+
+               } else {
+                       ret = jQuery.find.attr( elem, name );
+
+                       // Non-existent attributes return null, we normalize to undefined
+                       return ret == null ?
+                               undefined :
+                               ret;
+               }
+       },
+
+       removeAttr: function( elem, value ) {
+               var name, propName,
+                       i = 0,
+                       attrNames = value && value.match( core_rnotwhite );
+
+               if ( attrNames && elem.nodeType === 1 ) {
+                       while ( (name = attrNames[i++]) ) {
+                               propName = jQuery.propFix[ name ] || name;
+
+                               // Boolean attributes get special treatment (#10870)
+                               if ( jQuery.expr.match.bool.test( name ) ) {
+                                       // Set corresponding property to false
+                                       if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+                                               elem[ propName ] = false;
+                                       // Support: IE<9
+                                       // Also clear defaultChecked/defaultSelected (if appropriate)
+                                       } else {
+                                               elem[ jQuery.camelCase( "default-" + name ) ] =
+                                                       elem[ propName ] = false;
+                                       }
+
+                               // See #9699 for explanation of this approach (setting first, then removal)
+                               } else {
+                                       jQuery.attr( elem, name, "" );
+                               }
+
+                               elem.removeAttribute( getSetAttribute ? name : propName );
+                       }
+               }
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+                                       // Setting the type on a radio button after the value resets the value in IE6-9
+                                       // Reset value to default in case type is set after value during creation
+                                       var val = elem.value;
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               }
+       },
+
+       propFix: {
+               "for": "htmlFor",
+               "class": "className"
+       },
+
+       prop: function( elem, name, value ) {
+               var ret, hooks, notxml,
+                       nType = elem.nodeType;
+
+               // don't get/set properties on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+               if ( notxml ) {
+                       // Fix name and attach hooks
+                       name = jQuery.propFix[ name ] || name;
+                       hooks = jQuery.propHooks[ name ];
+               }
+
+               if ( value !== undefined ) {
+                       return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
+                               ret :
+                               ( elem[ name ] = value );
+
+               } else {
+                       return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
+                               ret :
+                               elem[ name ];
+               }
+       },
+
+       propHooks: {
+               tabIndex: {
+                       get: function( elem ) {
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               // Use proper attribute retrieval(#12072)
+                               var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+                               return tabindex ?
+                                       parseInt( tabindex, 10 ) :
+                                       rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+                                               0 :
+                                               -1;
+                       }
+               }
+       }
+});
+
+// Hooks for boolean attributes
+boolHook = {
+       set: function( elem, value, name ) {
+               if ( value === false ) {
+                       // Remove boolean attributes when set to false
+                       jQuery.removeAttr( elem, name );
+               } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+                       // IE<8 needs the *property* name
+                       elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+               // Use defaultChecked and defaultSelected for oldIE
+               } else {
+                       elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+               }
+
+               return name;
+       }
+};
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+       var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
+
+       jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
+               function( elem, name, isXML ) {
+                       var fn = jQuery.expr.attrHandle[ name ],
+                               ret = isXML ?
+                                       undefined :
+                                       /* jshint eqeqeq: false */
+                                       (jQuery.expr.attrHandle[ name ] = undefined) !=
+                                               getter( elem, name, isXML ) ?
+
+                                               name.toLowerCase() :
+                                               null;
+                       jQuery.expr.attrHandle[ name ] = fn;
+                       return ret;
+               } :
+               function( elem, name, isXML ) {
+                       return isXML ?
+                               undefined :
+                               elem[ jQuery.camelCase( "default-" + name ) ] ?
+                                       name.toLowerCase() :
+                                       null;
+               };
+});
+
+// fix oldIE attroperties
+if ( !getSetInput || !getSetAttribute ) {
+       jQuery.attrHooks.value = {
+               set: function( elem, value, name ) {
+                       if ( jQuery.nodeName( elem, "input" ) ) {
+                               // Does not return so that setAttribute is also used
+                               elem.defaultValue = value;
+                       } else {
+                               // Use nodeHook if defined (#1954); otherwise setAttribute is fine
+                               return nodeHook && nodeHook.set( elem, value, name );
+                       }
+               }
+       };
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+       // Use this for any attribute in IE6/7
+       // This fixes almost every IE6/7 issue
+       nodeHook = {
+               set: function( elem, value, name ) {
+                       // Set the existing or create a new attribute node
+                       var ret = elem.getAttributeNode( name );
+                       if ( !ret ) {
+                               elem.setAttributeNode(
+                                       (ret = elem.ownerDocument.createAttribute( name ))
+                               );
+                       }
+
+                       ret.value = value += "";
+
+                       // Break association with cloned elements by also using setAttribute (#9646)
+                       return name === "value" || value === elem.getAttribute( name ) ?
+                               value :
+                               undefined;
+               }
+       };
+       jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =
+               // Some attributes are constructed with empty-string values when not defined
+               function( elem, name, isXML ) {
+                       var ret;
+                       return isXML ?
+                               undefined :
+                               (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
+                                       ret.value :
+                                       null;
+               };
+       jQuery.valHooks.button = {
+               get: function( elem, name ) {
+                       var ret = elem.getAttributeNode( name );
+                       return ret && ret.specified ?
+                               ret.value :
+                               undefined;
+               },
+               set: nodeHook.set
+       };
+
+       // Set contenteditable to false on removals(#10429)
+       // Setting to empty string throws an error as an invalid value
+       jQuery.attrHooks.contenteditable = {
+               set: function( elem, value, name ) {
+                       nodeHook.set( elem, value === "" ? false : value, name );
+               }
+       };
+
+       // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+       // This is for removals
+       jQuery.each([ "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = {
+                       set: function( elem, value ) {
+                               if ( value === "" ) {
+                                       elem.setAttribute( name, "auto" );
+                                       return value;
+                               }
+                       }
+               };
+       });
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+       // href/src property should get the full normalized URL (#10299/#12915)
+       jQuery.each([ "href", "src" ], function( i, name ) {
+               jQuery.propHooks[ name ] = {
+                       get: function( elem ) {
+                               return elem.getAttribute( name, 4 );
+                       }
+               };
+       });
+}
+
+if ( !jQuery.support.style ) {
+       jQuery.attrHooks.style = {
+               get: function( elem ) {
+                       // Return undefined in the case of empty string
+                       // Note: IE uppercases css property names, but if we were to .toLowerCase()
+                       // .cssText, that would destroy case senstitivity in URL's, like in "background"
+                       return elem.style.cssText || undefined;
+               },
+               set: function( elem, value ) {
+                       return ( elem.style.cssText = value + "" );
+               }
+       };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+       jQuery.propHooks.selected = {
+               get: function( elem ) {
+                       var parent = elem.parentNode;
+
+                       if ( parent ) {
+                               parent.selectedIndex;
+
+                               // Make sure that it also works with optgroups, see #5701
+                               if ( parent.parentNode ) {
+                                       parent.parentNode.selectedIndex;
+                               }
+                       }
+                       return null;
+               }
+       };
+}
+
+jQuery.each([
+       "tabIndex",
+       "readOnly",
+       "maxLength",
+       "cellSpacing",
+       "cellPadding",
+       "rowSpan",
+       "colSpan",
+       "useMap",
+       "frameBorder",
+       "contentEditable"
+], function() {
+       jQuery.propFix[ this.toLowerCase() ] = this;
+});
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+       jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+jQuery.each([ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = {
+               set: function( elem, value ) {
+                       if ( jQuery.isArray( value ) ) {
+                               return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+                       }
+               }
+       };
+       if ( !jQuery.support.checkOn ) {
+               jQuery.valHooks[ this ].get = function( elem ) {
+                       // Support: Webkit
+                       // "" is returned instead of "on" if a value isn't specified
+                       return elem.getAttribute("value") === null ? "on" : elem.value;
+               };
+       }
+});
+var rformElems = /^(?:input|select|textarea)$/i,
+       rkeyEvent = /^key/,
+       rmouseEvent = /^(?:mouse|contextmenu)|click/,
+       rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+       rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+       return true;
+}
+
+function returnFalse() {
+       return false;
+}
+
+function safeActiveElement() {
+       try {
+               return document.activeElement;
+       } catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+       global: {},
+
+       add: function( elem, types, handler, data, selector ) {
+               var tmp, events, t, handleObjIn,
+                       special, eventHandle, handleObj,
+                       handlers, type, namespaces, origType,
+                       elemData = jQuery._data( elem );
+
+               // Don't attach events to noData or text/comment nodes (but allow plain objects)
+               if ( !elemData ) {
+                       return;
+               }
+
+               // Caller can pass in an object of custom data in lieu of the handler
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+                       selector = handleObjIn.selector;
+               }
+
+               // Make sure that the handler has a unique ID, used to find/remove it later
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure and main handler, if this is the first
+               if ( !(events = elemData.events) ) {
+                       events = elemData.events = {};
+               }
+               if ( !(eventHandle = elemData.handle) ) {
+                       eventHandle = elemData.handle = function( e ) {
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
+                                       jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+                                       undefined;
+                       };
+                       // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+                       eventHandle.elem = elem;
+               }
+
+               // Handle multiple events separated by a space
+               types = ( types || "" ).match( core_rnotwhite ) || [""];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // There *must* be a type, no attaching namespace-only handlers
+                       if ( !type ) {
+                               continue;
+                       }
+
+                       // If event changes its type, use the special event handlers for the changed type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // If selector defined, determine special event api type, otherwise given type
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+
+                       // Update special based on newly reset type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // handleObj is passed to all event handlers
+                       handleObj = jQuery.extend({
+                               type: type,
+                               origType: origType,
+                               data: data,
+                               handler: handler,
+                               guid: handler.guid,
+                               selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+                               namespace: namespaces.join(".")
+                       }, handleObjIn );
+
+                       // Init the event handler queue if we're the first
+                       if ( !(handlers = events[ type ]) ) {
+                               handlers = events[ type ] = [];
+                               handlers.delegateCount = 0;
+
+                               // Only use addEventListener/attachEvent if the special events handler returns false
+                               if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                                       // Bind the global event handler to the element
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle, false );
+
+                                       } else if ( elem.attachEvent ) {
+                                               elem.attachEvent( "on" + type, eventHandle );
+                                       }
+                               }
+                       }
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add to the element's handler list, delegates in front
+                       if ( selector ) {
+                               handlers.splice( handlers.delegateCount++, 0, handleObj );
+                       } else {
+                               handlers.push( handleObj );
+                       }
+
+                       // Keep track of which events have ever been used, for event optimization
+                       jQuery.event.global[ type ] = true;
+               }
+
+               // Nullify elem to prevent memory leaks in IE
+               elem = null;
+       },
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, selector, mappedTypes ) {
+               var j, handleObj, tmp,
+                       origCount, t, events,
+                       special, handlers, type,
+                       namespaces, origType,
+                       elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+               if ( !elemData || !(events = elemData.events) ) {
+                       return;
+               }
+
+               // Once for each type.namespace in types; type may be omitted
+               types = ( types || "" ).match( core_rnotwhite ) || [""];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // Unbind all events (on this namespace, if provided) for the element
+                       if ( !type ) {
+                               for ( type in events ) {
+                                       jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+                               }
+                               continue;
+                       }
+
+                       special = jQuery.event.special[ type ] || {};
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+                       handlers = events[ type ] || [];
+                       tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+                       // Remove matching events
+                       origCount = j = handlers.length;
+                       while ( j-- ) {
+                               handleObj = handlers[ j ];
+
+                               if ( ( mappedTypes || origType === handleObj.origType ) &&
+                                       ( !handler || handler.guid === handleObj.guid ) &&
+                                       ( !tmp || tmp.test( handleObj.namespace ) ) &&
+                                       ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+                                       handlers.splice( j, 1 );
+
+                                       if ( handleObj.selector ) {
+                                               handlers.delegateCount--;
+                                       }
+                                       if ( special.remove ) {
+                                               special.remove.call( elem, handleObj );
+                                       }
+                               }
+                       }
+
+                       // Remove generic event handler if we removed something and no more handlers exist
+                       // (avoids potential for endless recursion during removal of special event handlers)
+                       if ( origCount && !handlers.length ) {
+                               if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+                                       jQuery.removeEvent( elem, type, elemData.handle );
+                               }
+
+                               delete events[ type ];
+                       }
+               }
+
+               // Remove the expando if it's no longer used
+               if ( jQuery.isEmptyObject( events ) ) {
+                       delete elemData.handle;
+
+                       // removeData also checks for emptiness and clears the expando if empty
+                       // so use it instead of delete
+                       jQuery._removeData( elem, "events" );
+               }
+       },
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+               var handle, ontype, cur,
+                       bubbleType, special, tmp, i,
+                       eventPath = [ elem || document ],
+                       type = core_hasOwn.call( event, "type" ) ? event.type : event,
+                       namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+               cur = tmp = elem = elem || document;
+
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // focus/blur morphs to focusin/out; ensure we're not firing them right now
+               if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+                       return;
+               }
+
+               if ( type.indexOf(".") >= 0 ) {
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split(".");
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
+               ontype = type.indexOf(":") < 0 && "on" + type;
+
+               // Caller can pass in a jQuery.Event object, Object, or just an event type string
+               event = event[ jQuery.expando ] ?
+                       event :
+                       new jQuery.Event( type, typeof event === "object" && event );
+
+               // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+               event.isTrigger = onlyHandlers ? 2 : 3;
+               event.namespace = namespaces.join(".");
+               event.namespace_re = event.namespace ?
+                       new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+                       null;
+
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               if ( !event.target ) {
+                       event.target = elem;
+               }
+
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data == null ?
+                       [ event ] :
+                       jQuery.makeArray( data, [ event ] );
+
+               // Allow special events to draw outside the lines
+               special = jQuery.event.special[ type ] || {};
+               if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+                       return;
+               }
+
+               // Determine event propagation path in advance, per W3C events spec (#9951)
+               // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+               if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+                       bubbleType = special.delegateType || type;
+                       if ( !rfocusMorph.test( bubbleType + type ) ) {
+                               cur = cur.parentNode;
+                       }
+                       for ( ; cur; cur = cur.parentNode ) {
+                               eventPath.push( cur );
+                               tmp = cur;
+                       }
+
+                       // Only add window if we got to document (e.g., not plain obj or detached DOM)
+                       if ( tmp === (elem.ownerDocument || document) ) {
+                               eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+                       }
+               }
+
+               // Fire handlers on the event path
+               i = 0;
+               while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+                       event.type = i > 1 ?
+                               bubbleType :
+                               special.bindType || type;
+
+                       // jQuery handler
+                       handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+                       if ( handle ) {
+                               handle.apply( cur, data );
+                       }
+
+                       // Native handler
+                       handle = ontype && cur[ ontype ];
+                       if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+                               event.preventDefault();
+                       }
+               }
+               event.type = type;
+
+               // If nobody prevented the default action, do it now
+               if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+                       if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+                               jQuery.acceptData( elem ) ) {
+
+                               // Call a native DOM method on the target with the same name name as the event.
+                               // Can't use an .isFunction() check here because IE6/7 fails that test.
+                               // Don't do default actions on window, that's where global variables be (#6170)
+                               if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+                                       // Don't re-trigger an onFOO event when we call its FOO() method
+                                       tmp = elem[ ontype ];
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = null;
+                                       }
+
+                                       // Prevent re-triggering of the same event, since we already bubbled it above
+                                       jQuery.event.triggered = type;
+                                       try {
+                                               elem[ type ]();
+                                       } catch ( e ) {
+                                               // IE<9 dies on focus/blur to hidden element (#1486,#12518)
+                                               // only reproducible on winXP IE8 native, not IE9 in IE8 mode
+                                       }
+                                       jQuery.event.triggered = undefined;
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = tmp;
+                                       }
+                               }
+                       }
+               }
+
+               return event.result;
+       },
+
+       dispatch: function( event ) {
+
+               // Make a writable jQuery.Event from the native event object
+               event = jQuery.event.fix( event );
+
+               var i, ret, handleObj, matched, j,
+                       handlerQueue = [],
+                       args = core_slice.call( arguments ),
+                       handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+                       special = jQuery.event.special[ event.type ] || {};
+
+               // Use the fix-ed jQuery.Event rather than the (read-only) native event
+               args[0] = event;
+               event.delegateTarget = this;
+
+               // Call the preDispatch hook for the mapped type, and let it bail if desired
+               if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+                       return;
+               }
+
+               // Determine handlers
+               handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+               // Run delegates first; they may want to stop propagation beneath us
+               i = 0;
+               while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+                       event.currentTarget = matched.elem;
+
+                       j = 0;
+                       while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+                               // Triggered event must either 1) have no namespace, or
+                               // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+                               if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+                                       event.handleObj = handleObj;
+                                       event.data = handleObj.data;
+
+                                       ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+                                                       .apply( matched.elem, args );
+
+                                       if ( ret !== undefined ) {
+                                               if ( (event.result = ret) === false ) {
+                                                       event.preventDefault();
+                                                       event.stopPropagation();
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Call the postDispatch hook for the mapped type
+               if ( special.postDispatch ) {
+                       special.postDispatch.call( this, event );
+               }
+
+               return event.result;
+       },
+
+       handlers: function( event, handlers ) {
+               var sel, handleObj, matches, i,
+                       handlerQueue = [],
+                       delegateCount = handlers.delegateCount,
+                       cur = event.target;
+
+               // Find delegate handlers
+               // Black-hole SVG <use> instance trees (#13180)
+               // Avoid non-left-click bubbling in Firefox (#3861)
+               if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+                       /* jshint eqeqeq: false */
+                       for ( ; cur != this; cur = cur.parentNode || this ) {
+                               /* jshint eqeqeq: true */
+
+                               // Don't check non-elements (#13208)
+                               // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+                               if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+                                       matches = [];
+                                       for ( i = 0; i < delegateCount; i++ ) {
+                                               handleObj = handlers[ i ];
+
+                                               // Don't conflict with Object.prototype properties (#13203)
+                                               sel = handleObj.selector + " ";
+
+                                               if ( matches[ sel ] === undefined ) {
+                                                       matches[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) >= 0 :
+                                                               jQuery.find( sel, this, null, [ cur ] ).length;
+                                               }
+                                               if ( matches[ sel ] ) {
+                                                       matches.push( handleObj );
+                                               }
+                                       }
+                                       if ( matches.length ) {
+                                               handlerQueue.push({ elem: cur, handlers: matches });
+                                       }
+                               }
+                       }
+               }
+
+               // Add the remaining (directly-bound) handlers
+               if ( delegateCount < handlers.length ) {
+                       handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+               }
+
+               return handlerQueue;
+       },
+
+       fix: function( event ) {
+               if ( event[ jQuery.expando ] ) {
+                       return event;
+               }
+
+               // Create a writable copy of the event object and normalize some properties
+               var i, prop, copy,
+                       type = event.type,
+                       originalEvent = event,
+                       fixHook = this.fixHooks[ type ];
+
+               if ( !fixHook ) {
+                       this.fixHooks[ type ] = fixHook =
+                               rmouseEvent.test( type ) ? this.mouseHooks :
+                               rkeyEvent.test( type ) ? this.keyHooks :
+                               {};
+               }
+               copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+               event = new jQuery.Event( originalEvent );
+
+               i = copy.length;
+               while ( i-- ) {
+                       prop = copy[ i ];
+                       event[ prop ] = originalEvent[ prop ];
+               }
+
+               // Support: IE<9
+               // Fix target property (#1925)
+               if ( !event.target ) {
+                       event.target = originalEvent.srcElement || document;
+               }
+
+               // Support: Chrome 23+, Safari?
+               // Target should not be a text node (#504, #13143)
+               if ( event.target.nodeType === 3 ) {
+                       event.target = event.target.parentNode;
+               }
+
+               // Support: IE<9
+               // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+               event.metaKey = !!event.metaKey;
+
+               return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+       },
+
+       // Includes some event props shared by KeyEvent and MouseEvent
+       props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+       fixHooks: {},
+
+       keyHooks: {
+               props: "char charCode key keyCode".split(" "),
+               filter: function( event, original ) {
+
+                       // Add which for key events
+                       if ( event.which == null ) {
+                               event.which = original.charCode != null ? original.charCode : original.keyCode;
+                       }
+
+                       return event;
+               }
+       },
+
+       mouseHooks: {
+               props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+               filter: function( event, original ) {
+                       var body, eventDoc, doc,
+                               button = original.button,
+                               fromElement = original.fromElement;
+
+                       // Calculate pageX/Y if missing and clientX/Y available
+                       if ( event.pageX == null && original.clientX != null ) {
+                               eventDoc = event.target.ownerDocument || document;
+                               doc = eventDoc.documentElement;
+                               body = eventDoc.body;
+
+                               event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+                               event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+                       }
+
+                       // Add relatedTarget, if necessary
+                       if ( !event.relatedTarget && fromElement ) {
+                               event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+                       }
+
+                       // Add which for click: 1 === left; 2 === middle; 3 === right
+                       // Note: button is not normalized, so don't use it
+                       if ( !event.which && button !== undefined ) {
+                               event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+                       }
+
+                       return event;
+               }
+       },
+
+       special: {
+               load: {
+                       // Prevent triggered image.load events from bubbling to window.load
+                       noBubble: true
+               },
+               focus: {
+                       // Fire native event if possible so blur/focus sequence is correct
+                       trigger: function() {
+                               if ( this !== safeActiveElement() && this.focus ) {
+                                       try {
+                                               this.focus();
+                                               return false;
+                                       } catch ( e ) {
+                                               // Support: IE<9
+                                               // If we error on focus to hidden element (#1486, #12518),
+                                               // let .trigger() run the handlers
+                                       }
+                               }
+                       },
+                       delegateType: "focusin"
+               },
+               blur: {
+                       trigger: function() {
+                               if ( this === safeActiveElement() && this.blur ) {
+                                       this.blur();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusout"
+               },
+               click: {
+                       // For checkbox, fire native event so checked state will be right
+                       trigger: function() {
+                               if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+                                       this.click();
+                                       return false;
+                               }
+                       },
+
+                       // For cross-browser consistency, don't fire native .click() on links
+                       _default: function( event ) {
+                               return jQuery.nodeName( event.target, "a" );
+                       }
+               },
+
+               beforeunload: {
+                       postDispatch: function( event ) {
+
+                               // Even when returnValue equals to undefined Firefox will still show alert
+                               if ( event.result !== undefined ) {
+                                       event.originalEvent.returnValue = event.result;
+                               }
+                       }
+               }
+       },
+
+       simulate: function( type, elem, event, bubble ) {
+               // Piggyback on a donor event to simulate a different one.
+               // Fake originalEvent to avoid donor's stopPropagation, but if the
+               // simulated event prevents default then we do the same on the donor.
+               var e = jQuery.extend(
+                       new jQuery.Event(),
+                       event,
+                       {
+                               type: type,
+                               isSimulated: true,
+                               originalEvent: {}
+                       }
+               );
+               if ( bubble ) {
+                       jQuery.event.trigger( e, null, elem );
+               } else {
+                       jQuery.event.dispatch.call( elem, e );
+               }
+               if ( e.isDefaultPrevented() ) {
+                       event.preventDefault();
+               }
+       }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+       function( elem, type, handle ) {
+               if ( elem.removeEventListener ) {
+                       elem.removeEventListener( type, handle, false );
+               }
+       } :
+       function( elem, type, handle ) {
+               var name = "on" + type;
+
+               if ( elem.detachEvent ) {
+
+                       // #8545, #7054, preventing memory leaks for custom events in IE6-8
+                       // detachEvent needed property on element, by name of that event, to properly expose it to GC
+                       if ( typeof elem[ name ] === core_strundefined ) {
+                               elem[ name ] = null;
+                       }
+
+                       elem.detachEvent( name, handle );
+               }
+       };
+
+jQuery.Event = function( src, props ) {
+       // Allow instantiation without the 'new' keyword
+       if ( !(this instanceof jQuery.Event) ) {
+               return new jQuery.Event( src, props );
+       }
+
+       // Event object
+       if ( src && src.type ) {
+               this.originalEvent = src;
+               this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+                       src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+       // Event type
+       } else {
+               this.type = src;
+       }
+
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
+       // Create a timestamp if incoming event doesn't have one
+       this.timeStamp = src && src.timeStamp || jQuery.now();
+
+       // Mark it as fixed
+       this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+       isDefaultPrevented: returnFalse,
+       isPropagationStopped: returnFalse,
+       isImmediatePropagationStopped: returnFalse,
+
+       preventDefault: function() {
+               var e = this.originalEvent;
+
+               this.isDefaultPrevented = returnTrue;
+               if ( !e ) {
+                       return;
+               }
+
+               // If preventDefault exists, run it on the original event
+               if ( e.preventDefault ) {
+                       e.preventDefault();
+
+               // Support: IE
+               // Otherwise set the returnValue property of the original event to false
+               } else {
+                       e.returnValue = false;
+               }
+       },
+       stopPropagation: function() {
+               var e = this.originalEvent;
+
+               this.isPropagationStopped = returnTrue;
+               if ( !e ) {
+                       return;
+               }
+               // If stopPropagation exists, run it on the original event
+               if ( e.stopPropagation ) {
+                       e.stopPropagation();
+               }
+
+               // Support: IE
+               // Set the cancelBubble property of the original event to true
+               e.cancelBubble = true;
+       },
+       stopImmediatePropagation: function() {
+               this.isImmediatePropagationStopped = returnTrue;
+               this.stopPropagation();
+       }
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+       mouseenter: "mouseover",
+       mouseleave: "mouseout"
+}, function( orig, fix ) {
+       jQuery.event.special[ orig ] = {
+               delegateType: fix,
+               bindType: fix,
+
+               handle: function( event ) {
+                       var ret,
+                               target = this,
+                               related = event.relatedTarget,
+                               handleObj = event.handleObj;
+
+                       // For mousenter/leave call the handler if related is outside the target.
+                       // NB: No relatedTarget if the mouse left/entered the browser window
+                       if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+                               event.type = handleObj.origType;
+                               ret = handleObj.handler.apply( this, arguments );
+                               event.type = fix;
+                       }
+                       return ret;
+               }
+       };
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+       jQuery.event.special.submit = {
+               setup: function() {
+                       // Only need this for delegated form submit events
+                       if ( jQuery.nodeName( this, "form" ) ) {
+                               return false;
+                       }
+
+                       // Lazy-add a submit handler when a descendant form may potentially be submitted
+                       jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+                               // Node name check avoids a VML-related crash in IE (#9807)
+                               var elem = e.target,
+                                       form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+                               if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+                                       jQuery.event.add( form, "submit._submit", function( event ) {
+                                               event._submit_bubble = true;
+                                       });
+                                       jQuery._data( form, "submitBubbles", true );
+                               }
+                       });
+                       // return undefined since we don't need an event listener
+               },
+
+               postDispatch: function( event ) {
+                       // If form was submitted by the user, bubble the event up the tree
+                       if ( event._submit_bubble ) {
+                               delete event._submit_bubble;
+                               if ( this.parentNode && !event.isTrigger ) {
+                                       jQuery.event.simulate( "submit", this.parentNode, event, true );
+                               }
+                       }
+               },
+
+               teardown: function() {
+                       // Only need this for delegated form submit events
+                       if ( jQuery.nodeName( this, "form" ) ) {
+                               return false;
+                       }
+
+                       // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+                       jQuery.event.remove( this, "._submit" );
+               }
+       };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+       jQuery.event.special.change = {
+
+               setup: function() {
+
+                       if ( rformElems.test( this.nodeName ) ) {
+                               // IE doesn't fire change on a check/radio until blur; trigger it on click
+                               // after a propertychange. Eat the blur-change in special.change.handle.
+                               // This still fires onchange a second time for check/radio after blur.
+                               if ( this.type === "checkbox" || this.type === "radio" ) {
+                                       jQuery.event.add( this, "propertychange._change", function( event ) {
+                                               if ( event.originalEvent.propertyName === "checked" ) {
+                                                       this._just_changed = true;
+                                               }
+                                       });
+                                       jQuery.event.add( this, "click._change", function( event ) {
+                                               if ( this._just_changed && !event.isTrigger ) {
+                                                       this._just_changed = false;
+                                               }
+                                               // Allow triggered, simulated change events (#11500)
+                                               jQuery.event.simulate( "change", this, event, true );
+                                       });
+                               }
+                               return false;
+                       }
+                       // Delegated event; lazy-add a change handler on descendant inputs
+                       jQuery.event.add( this, "beforeactivate._change", function( e ) {
+                               var elem = e.target;
+
+                               if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+                                       jQuery.event.add( elem, "change._change", function( event ) {
+                                               if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+                                                       jQuery.event.simulate( "change", this.parentNode, event, true );
+                                               }
+                                       });
+                                       jQuery._data( elem, "changeBubbles", true );
+                               }
+                       });
+               },
+
+               handle: function( event ) {
+                       var elem = event.target;
+
+                       // Swallow native change events from checkbox/radio, we already triggered them above
+                       if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+                               return event.handleObj.handler.apply( this, arguments );
+                       }
+               },
+
+               teardown: function() {
+                       jQuery.event.remove( this, "._change" );
+
+                       return !rformElems.test( this.nodeName );
+               }
+       };
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+       jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler while someone wants focusin/focusout
+               var attaches = 0,
+                       handler = function( event ) {
+                               jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+                       };
+
+               jQuery.event.special[ fix ] = {
+                       setup: function() {
+                               if ( attaches++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
+                       },
+                       teardown: function() {
+                               if ( --attaches === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
+                       }
+               };
+       });
+}
+
+jQuery.fn.extend({
+
+       on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+               var type, origFn;
+
+               // Types can be a map of types/handlers
+               if ( typeof types === "object" ) {
+                       // ( types-Object, selector, data )
+                       if ( typeof selector !== "string" ) {
+                               // ( types-Object, data )
+                               data = data || selector;
+                               selector = undefined;
+                       }
+                       for ( type in types ) {
+                               this.on( type, selector, data, types[ type ], one );
+                       }
+                       return this;
+               }
+
+               if ( data == null && fn == null ) {
+                       // ( types, fn )
+                       fn = selector;
+                       data = selector = undefined;
+               } else if ( fn == null ) {
+                       if ( typeof selector === "string" ) {
+                               // ( types, selector, fn )
+                               fn = data;
+                               data = undefined;
+                       } else {
+                               // ( types, data, fn )
+                               fn = data;
+                               data = selector;
+                               selector = undefined;
+                       }
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               } else if ( !fn ) {
+                       return this;
+               }
+
+               if ( one === 1 ) {
+                       origFn = fn;
+                       fn = function( event ) {
+                               // Can use an empty set, since event contains the info
+                               jQuery().off( event );
+                               return origFn.apply( this, arguments );
+                       };
+                       // Use same guid so caller can remove using origFn
+                       fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+               }
+               return this.each( function() {
+                       jQuery.event.add( this, types, fn, data, selector );
+               });
+       },
+       one: function( types, selector, data, fn ) {
+               return this.on( types, selector, data, fn, 1 );
+       },
+       off: function( types, selector, fn ) {
+               var handleObj, type;
+               if ( types && types.preventDefault && types.handleObj ) {
+                       // ( event )  dispatched jQuery.Event
+                       handleObj = types.handleObj;
+                       jQuery( types.delegateTarget ).off(
+                               handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+                               handleObj.selector,
+                               handleObj.handler
+                       );
+                       return this;
+               }
+               if ( typeof types === "object" ) {
+                       // ( types-object [, selector] )
+                       for ( type in types ) {
+                               this.off( type, selector, types[ type ] );
+                       }
+                       return this;
+               }
+               if ( selector === false || typeof selector === "function" ) {
+                       // ( types [, fn] )
+                       fn = selector;
+                       selector = undefined;
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               }
+               return this.each(function() {
+                       jQuery.event.remove( this, types, fn, selector );
+               });
+       },
+
+       trigger: function( type, data ) {
+               return this.each(function() {
+                       jQuery.event.trigger( type, data, this );
+               });
+       },
+       triggerHandler: function( type, data ) {
+               var elem = this[0];
+               if ( elem ) {
+                       return jQuery.event.trigger( type, data, elem, true );
+               }
+       }
+});
+var isSimple = /^.[^:#\[\.,]*$/,
+       rparentsprev = /^(?:parents|prev(?:Until|All))/,
+       rneedsContext = jQuery.expr.match.needsContext,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
+
+jQuery.fn.extend({
+       find: function( selector ) {
+               var i,
+                       ret = [],
+                       self = this,
+                       len = self.length;
+
+               if ( typeof selector !== "string" ) {
+                       return this.pushStack( jQuery( selector ).filter(function() {
+                               for ( i = 0; i < len; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       }) );
+               }
+
+               for ( i = 0; i < len; i++ ) {
+                       jQuery.find( selector, self[ i ], ret );
+               }
+
+               // Needed because $( selector, context ) becomes $( context ).find( selector )
+               ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+               ret.selector = this.selector ? this.selector + " " + selector : selector;
+               return ret;
+       },
+
+       has: function( target ) {
+               var i,
+                       targets = jQuery( target, this ),
+                       len = targets.length;
+
+               return this.filter(function() {
+                       for ( i = 0; i < len; i++ ) {
+                               if ( jQuery.contains( this, targets[i] ) ) {
+                                       return true;
+                               }
+                       }
+               });
+       },
+
+       not: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], true) );
+       },
+
+       filter: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], false) );
+       },
+
+       is: function( selector ) {
+               return !!winnow(
+                       this,
+
+                       // If this is a positional/relative selector, check membership in the returned set
+                       // so $("p:first").is("p:last") won't return true for a doc with two "p".
+                       typeof selector === "string" && rneedsContext.test( selector ) ?
+                               jQuery( selector ) :
+                               selector || [],
+                       false
+               ).length;
+       },
+
+       closest: function( selectors, context ) {
+               var cur,
+                       i = 0,
+                       l = this.length,
+                       ret = [],
+                       pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+                               jQuery( selectors, context || this.context ) :
+                               0;
+
+               for ( ; i < l; i++ ) {
+                       for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+                               // Always skip document fragments
+                               if ( cur.nodeType < 11 && (pos ?
+                                       pos.index(cur) > -1 :
+
+                                       // Don't pass non-elements to Sizzle
+                                       cur.nodeType === 1 &&
+                                               jQuery.find.matchesSelector(cur, selectors)) ) {
+
+                                       cur = ret.push( cur );
+                                       break;
+                               }
+                       }
+               }
+
+               return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+       },
+
+       // Determine the position of an element within
+       // the matched set of elements
+       index: function( elem ) {
+
+               // No argument, return index in parent
+               if ( !elem ) {
+                       return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+               }
+
+               // index in selector
+               if ( typeof elem === "string" ) {
+                       return jQuery.inArray( this[0], jQuery( elem ) );
+               }
+
+               // Locate the position of the desired element
+               return jQuery.inArray(
+                       // If it receives a jQuery object, the first element is used
+                       elem.jquery ? elem[0] : elem, this );
+       },
+
+       add: function( selector, context ) {
+               var set = typeof selector === "string" ?
+                               jQuery( selector, context ) :
+                               jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+                       all = jQuery.merge( this.get(), set );
+
+               return this.pushStack( jQuery.unique(all) );
+       },
+
+       addBack: function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter(selector)
+               );
+       }
+});
+
+function sibling( cur, dir ) {
+       do {
+               cur = cur[ dir ];
+       } while ( cur && cur.nodeType !== 1 );
+
+       return cur;
+}
+
+jQuery.each({
+       parent: function( elem ) {
+               var parent = elem.parentNode;
+               return parent && parent.nodeType !== 11 ? parent : null;
+       },
+       parents: function( elem ) {
+               return jQuery.dir( elem, "parentNode" );
+       },
+       parentsUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "parentNode", until );
+       },
+       next: function( elem ) {
+               return sibling( elem, "nextSibling" );
+       },
+       prev: function( elem ) {
+               return sibling( elem, "previousSibling" );
+       },
+       nextAll: function( elem ) {
+               return jQuery.dir( elem, "nextSibling" );
+       },
+       prevAll: function( elem ) {
+               return jQuery.dir( elem, "previousSibling" );
+       },
+       nextUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "nextSibling", until );
+       },
+       prevUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "previousSibling", until );
+       },
+       siblings: function( elem ) {
+               return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+       },
+       children: function( elem ) {
+               return jQuery.sibling( elem.firstChild );
+       },
+       contents: function( elem ) {
+               return jQuery.nodeName( elem, "iframe" ) ?
+                       elem.contentDocument || elem.contentWindow.document :
+                       jQuery.merge( [], elem.childNodes );
+       }
+}, function( name, fn ) {
+       jQuery.fn[ name ] = function( until, selector ) {
+               var ret = jQuery.map( this, fn, until );
+
+               if ( name.slice( -5 ) !== "Until" ) {
+                       selector = until;
+               }
+
+               if ( selector && typeof selector === "string" ) {
+                       ret = jQuery.filter( selector, ret );
+               }
+
+               if ( this.length > 1 ) {
+                       // Remove duplicates
+                       if ( !guaranteedUnique[ name ] ) {
+                               ret = jQuery.unique( ret );
+                       }
+
+                       // Reverse order for parents* and prev-derivatives
+                       if ( rparentsprev.test( name ) ) {
+                               ret = ret.reverse();
+                       }
+               }
+
+               return this.pushStack( ret );
+       };
+});
+
+jQuery.extend({
+       filter: function( expr, elems, not ) {
+               var elem = elems[ 0 ];
+
+               if ( not ) {
+                       expr = ":not(" + expr + ")";
+               }
+
+               return elems.length === 1 && elem.nodeType === 1 ?
+                       jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+                       jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+                               return elem.nodeType === 1;
+                       }));
+       },
+
+       dir: function( elem, dir, until ) {
+               var matched = [],
+                       cur = elem[ dir ];
+
+               while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+                       if ( cur.nodeType === 1 ) {
+                               matched.push( cur );
+                       }
+                       cur = cur[dir];
+               }
+               return matched;
+       },
+
+       sibling: function( n, elem ) {
+               var r = [];
+
+               for ( ; n; n = n.nextSibling ) {
+                       if ( n.nodeType === 1 && n !== elem ) {
+                               r.push( n );
+                       }
+               }
+
+               return r;
+       }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+       if ( jQuery.isFunction( qualifier ) ) {
+               return jQuery.grep( elements, function( elem, i ) {
+                       /* jshint -W018 */
+                       return !!qualifier.call( elem, i, elem ) !== not;
+               });
+
+       }
+
+       if ( qualifier.nodeType ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( elem === qualifier ) !== not;
+               });
+
+       }
+
+       if ( typeof qualifier === "string" ) {
+               if ( isSimple.test( qualifier ) ) {
+                       return jQuery.filter( qualifier, elements, not );
+               }
+
+               qualifier = jQuery.filter( qualifier, elements );
+       }
+
+       return jQuery.grep( elements, function( elem ) {
+               return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
+       });
+}
+function createSafeFragment( document ) {
+       var list = nodeNames.split( "|" ),
+               safeFrag = document.createDocumentFragment();
+
+       if ( safeFrag.createElement ) {
+               while ( list.length ) {
+                       safeFrag.createElement(
+                               list.pop()
+                       );
+               }
+       }
+       return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+               "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+       rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+       rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+       rleadingWhitespace = /^\s+/,
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+       rtagName = /<([\w:]+)/,
+       rtbody = /<tbody/i,
+       rhtml = /<|&#?\w+;/,
+       rnoInnerhtml = /<(?:script|style|link)/i,
+       manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+       // checked="checked" or checked
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+       rscriptType = /^$|\/(?:java|ecma)script/i,
+       rscriptTypeMasked = /^true\/(.*)/,
+       rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+       // We have to close these tags to support XHTML (#13200)
+       wrapMap = {
+               option: [ 1, "<select multiple='multiple'>", "</select>" ],
+               legend: [ 1, "<fieldset>", "</fieldset>" ],
+               area: [ 1, "<map>", "</map>" ],
+               param: [ 1, "<object>", "</object>" ],
+               thead: [ 1, "<table>", "</table>" ],
+               tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+               col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+               td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+               // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+               // unless wrapped in a div with non-breaking characters in front of it.
+               _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+       },
+       safeFragment = createSafeFragment( document ),
+       fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+jQuery.fn.extend({
+       text: function( value ) {
+               return jQuery.access( this, function( value ) {
+                       return value === undefined ?
+                               jQuery.text( this ) :
+                               this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+               }, null, value, arguments.length );
+       },
+
+       append: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.appendChild( elem );
+                       }
+               });
+       },
+
+       prepend: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.insertBefore( elem, target.firstChild );
+                       }
+               });
+       },
+
+       before: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this );
+                       }
+               });
+       },
+
+       after: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this.nextSibling );
+                       }
+               });
+       },
+
+       // keepData is for internal use only--do not document
+       remove: function( selector, keepData ) {
+               var elem,
+                       elems = selector ? jQuery.filter( selector, this ) : this,
+                       i = 0;
+
+               for ( ; (elem = elems[i]) != null; i++ ) {
+
+                       if ( !keepData && elem.nodeType === 1 ) {
+                               jQuery.cleanData( getAll( elem ) );
+                       }
+
+                       if ( elem.parentNode ) {
+                               if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+                                       setGlobalEval( getAll( elem, "script" ) );
+                               }
+                               elem.parentNode.removeChild( elem );
+                       }
+               }
+
+               return this;
+       },
+
+       empty: function() {
+               var elem,
+                       i = 0;
+
+               for ( ; (elem = this[i]) != null; i++ ) {
+                       // Remove element nodes and prevent memory leaks
+                       if ( elem.nodeType === 1 ) {
+                               jQuery.cleanData( getAll( elem, false ) );
+                       }
+
+                       // Remove any remaining nodes
+                       while ( elem.firstChild ) {
+                               elem.removeChild( elem.firstChild );
+                       }
+
+                       // If this is a select, ensure that it displays empty (#12336)
+                       // Support: IE<9
+                       if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+                               elem.options.length = 0;
+                       }
+               }
+
+               return this;
+       },
+
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+               return this.map( function () {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               });
+       },
+
+       html: function( value ) {
+               return jQuery.access( this, function( value ) {
+                       var elem = this[0] || {},
+                               i = 0,
+                               l = this.length;
+
+                       if ( value === undefined ) {
+                               return elem.nodeType === 1 ?
+                                       elem.innerHTML.replace( rinlinejQuery, "" ) :
+                                       undefined;
+                       }
+
+                       // See if we can take a shortcut and just use innerHTML
+                       if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+                               ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+                               ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+                               !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+                               value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+                               try {
+                                       for (; i < l; i++ ) {
+                                               // Remove element nodes and prevent memory leaks
+                                               elem = this[i] || {};
+                                               if ( elem.nodeType === 1 ) {
+                                                       jQuery.cleanData( getAll( elem, false ) );
+                                                       elem.innerHTML = value;
+                                               }
+                                       }
+
+                                       elem = 0;
+
+                               // If using innerHTML throws an exception, use the fallback method
+                               } catch(e) {}
+                       }
+
+                       if ( elem ) {
+                               this.empty().append( value );
+                       }
+               }, null, value, arguments.length );
+       },
+
+       replaceWith: function() {
+               var
+                       // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
+                       args = jQuery.map( this, function( elem ) {
+                               return [ elem.nextSibling, elem.parentNode ];
+                       }),
+                       i = 0;
+
+               // Make the changes, replacing each context element with the new content
+               this.domManip( arguments, function( elem ) {
+                       var next = args[ i++ ],
+                               parent = args[ i++ ];
+
+                       if ( parent ) {
+                               // Don't use the snapshot next if it has moved (#13810)
+                               if ( next && next.parentNode !== parent ) {
+                                       next = this.nextSibling;
+                               }
+                               jQuery( this ).remove();
+                               parent.insertBefore( elem, next );
+                       }
+               // Allow new content to include elements from the context set
+               }, true );
+
+               // Force removal if there was no new content (e.g., from empty arguments)
+               return i ? this : this.remove();
+       },
+
+       detach: function( selector ) {
+               return this.remove( selector, true );
+       },
+
+       domManip: function( args, callback, allowIntersection ) {
+
+               // Flatten any nested arrays
+               args = core_concat.apply( [], args );
+
+               var first, node, hasScripts,
+                       scripts, doc, fragment,
+                       i = 0,
+                       l = this.length,
+                       set = this,
+                       iNoClone = l - 1,
+                       value = args[0],
+                       isFunction = jQuery.isFunction( value );
+
+               // We can't cloneNode fragments that contain checked, in WebKit
+               if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+                       return this.each(function( index ) {
+                               var self = set.eq( index );
+                               if ( isFunction ) {
+                                       args[0] = value.call( this, index, self.html() );
+                               }
+                               self.domManip( args, callback, allowIntersection );
+                       });
+               }
+
+               if ( l ) {
+                       fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
+                       first = fragment.firstChild;
+
+                       if ( fragment.childNodes.length === 1 ) {
+                               fragment = first;
+                       }
+
+                       if ( first ) {
+                               scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+                               hasScripts = scripts.length;
+
+                               // Use the original fragment for the last item instead of the first because it can end up
+                               // being emptied incorrectly in certain situations (#8070).
+                               for ( ; i < l; i++ ) {
+                                       node = fragment;
+
+                                       if ( i !== iNoClone ) {
+                                               node = jQuery.clone( node, true, true );
+
+                                               // Keep references to cloned scripts for later restoration
+                                               if ( hasScripts ) {
+                                                       jQuery.merge( scripts, getAll( node, "script" ) );
+                                               }
+                                       }
+
+                                       callback.call( this[i], node, i );
+                               }
+
+                               if ( hasScripts ) {
+                                       doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+                                       // Reenable scripts
+                                       jQuery.map( scripts, restoreScript );
+
+                                       // Evaluate executable scripts on first document insertion
+                                       for ( i = 0; i < hasScripts; i++ ) {
+                                               node = scripts[ i ];
+                                               if ( rscriptType.test( node.type || "" ) &&
+                                                       !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+                                                       if ( node.src ) {
+                                                               // Hope ajax is available...
+                                                               jQuery._evalUrl( node.src );
+                                                       } else {
+                                                               jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Fix #11809: Avoid leaking memory
+                               fragment = first = null;
+                       }
+               }
+
+               return this;
+       }
+});
+
+// Support: IE<8
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+       return jQuery.nodeName( elem, "table" ) &&
+               jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
+
+               elem.getElementsByTagName("tbody")[0] ||
+                       elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
+               elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+       elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
+       return elem;
+}
+function restoreScript( elem ) {
+       var match = rscriptTypeMasked.exec( elem.type );
+       if ( match ) {
+               elem.type = match[1];
+       } else {
+               elem.removeAttribute("type");
+       }
+       return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+       var elem,
+               i = 0;
+       for ( ; (elem = elems[i]) != null; i++ ) {
+               jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+       }
+}
+
+function cloneCopyEvent( src, dest ) {
+
+       if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+               return;
+       }
+
+       var type, i, l,
+               oldData = jQuery._data( src ),
+               curData = jQuery._data( dest, oldData ),
+               events = oldData.events;
+
+       if ( events ) {
+               delete curData.handle;
+               curData.events = {};
+
+               for ( type in events ) {
+                       for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+                               jQuery.event.add( dest, type, events[ type ][ i ] );
+                       }
+               }
+       }
+
+       // make the cloned public data object a copy from the original
+       if ( curData.data ) {
+               curData.data = jQuery.extend( {}, curData.data );
+       }
+}
+
+function fixCloneNodeIssues( src, dest ) {
+       var nodeName, e, data;
+
+       // We do not need to do anything for non-Elements
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       nodeName = dest.nodeName.toLowerCase();
+
+       // IE6-8 copies events bound via attachEvent when using cloneNode.
+       if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+               data = jQuery._data( dest );
+
+               for ( e in data.events ) {
+                       jQuery.removeEvent( dest, e, data.handle );
+               }
+
+               // Event data gets referenced instead of copied if the expando gets copied too
+               dest.removeAttribute( jQuery.expando );
+       }
+
+       // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+       if ( nodeName === "script" && dest.text !== src.text ) {
+               disableScript( dest ).text = src.text;
+               restoreScript( dest );
+
+       // IE6-10 improperly clones children of object elements using classid.
+       // IE10 throws NoModificationAllowedError if parent is null, #12132.
+       } else if ( nodeName === "object" ) {
+               if ( dest.parentNode ) {
+                       dest.outerHTML = src.outerHTML;
+               }
+
+               // This path appears unavoidable for IE9. When cloning an object
+               // element in IE9, the outerHTML strategy above is not sufficient.
+               // If the src has innerHTML and the destination does not,
+               // copy the src.innerHTML into the dest.innerHTML. #10324
+               if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+                       dest.innerHTML = src.innerHTML;
+               }
+
+       } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+               // IE6-8 fails to persist the checked state of a cloned checkbox
+               // or radio button. Worse, IE6-7 fail to give the cloned element
+               // a checked appearance if the defaultChecked value isn't also set
+
+               dest.defaultChecked = dest.checked = src.checked;
+
+               // IE6-7 get confused and end up setting the value of a cloned
+               // checkbox/radio button to an empty string instead of "on"
+               if ( dest.value !== src.value ) {
+                       dest.value = src.value;
+               }
+
+       // IE6-8 fails to return the selected option to the default selected
+       // state when cloning options
+       } else if ( nodeName === "option" ) {
+               dest.defaultSelected = dest.selected = src.defaultSelected;
+
+       // IE6-8 fails to set the defaultValue to the correct value when
+       // cloning other types of input fields
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+}
+
+jQuery.each({
+       appendTo: "append",
+       prependTo: "prepend",
+       insertBefore: "before",
+       insertAfter: "after",
+       replaceAll: "replaceWith"
+}, function( name, original ) {
+       jQuery.fn[ name ] = function( selector ) {
+               var elems,
+                       i = 0,
+                       ret = [],
+                       insert = jQuery( selector ),
+                       last = insert.length - 1;
+
+               for ( ; i <= last; i++ ) {
+                       elems = i === last ? this : this.clone(true);
+                       jQuery( insert[i] )[ original ]( elems );
+
+                       // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+                       core_push.apply( ret, elems.get() );
+               }
+
+               return this.pushStack( ret );
+       };
+});
+
+function getAll( context, tag ) {
+       var elems, elem,
+               i = 0,
+               found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+                       typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+                       undefined;
+
+       if ( !found ) {
+               for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+                       if ( !tag || jQuery.nodeName( elem, tag ) ) {
+                               found.push( elem );
+                       } else {
+                               jQuery.merge( found, getAll( elem, tag ) );
+                       }
+               }
+       }
+
+       return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+               jQuery.merge( [ context ], found ) :
+               found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+       if ( manipulation_rcheckableType.test( elem.type ) ) {
+               elem.defaultChecked = elem.checked;
+       }
+}
+
+jQuery.extend({
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var destElements, node, clone, i, srcElements,
+                       inPage = jQuery.contains( elem.ownerDocument, elem );
+
+               if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+                       clone = elem.cloneNode( true );
+
+               // IE<=8 does not properly clone detached, unknown element nodes
+               } else {
+                       fragmentDiv.innerHTML = elem.outerHTML;
+                       fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+               }
+
+               if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+                               (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+                       // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+                       destElements = getAll( clone );
+                       srcElements = getAll( elem );
+
+                       // Fix all IE cloning issues
+                       for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+                               // Ensure that the destination node is not null; Fixes #9587
+                               if ( destElements[i] ) {
+                                       fixCloneNodeIssues( node, destElements[i] );
+                               }
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       if ( deepDataAndEvents ) {
+                               srcElements = srcElements || getAll( elem );
+                               destElements = destElements || getAll( clone );
+
+                               for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+                                       cloneCopyEvent( node, destElements[i] );
+                               }
+                       } else {
+                               cloneCopyEvent( elem, clone );
+                       }
+               }
+
+               // Preserve script evaluation history
+               destElements = getAll( clone, "script" );
+               if ( destElements.length > 0 ) {
+                       setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+               }
+
+               destElements = srcElements = node = null;
+
+               // Return the cloned set
+               return clone;
+       },
+
+       buildFragment: function( elems, context, scripts, selection ) {
+               var j, elem, contains,
+                       tmp, tag, tbody, wrap,
+                       l = elems.length,
+
+                       // Ensure a safe fragment
+                       safe = createSafeFragment( context ),
+
+                       nodes = [],
+                       i = 0;
+
+               for ( ; i < l; i++ ) {
+                       elem = elems[ i ];
+
+                       if ( elem || elem === 0 ) {
+
+                               // Add nodes directly
+                               if ( jQuery.type( elem ) === "object" ) {
+                                       jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+                               // Convert non-html into a text node
+                               } else if ( !rhtml.test( elem ) ) {
+                                       nodes.push( context.createTextNode( elem ) );
+
+                               // Convert html into DOM nodes
+                               } else {
+                                       tmp = tmp || safe.appendChild( context.createElement("div") );
+
+                                       // Deserialize a standard representation
+                                       tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+                                       wrap = wrapMap[ tag ] || wrapMap._default;
+
+                                       tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+                                       // Descend through wrappers to the right content
+                                       j = wrap[0];
+                                       while ( j-- ) {
+                                               tmp = tmp.lastChild;
+                                       }
+
+                                       // Manually add leading whitespace removed by IE
+                                       if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+                                               nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+                                       }
+
+                                       // Remove IE's autoinserted <tbody> from table fragments
+                                       if ( !jQuery.support.tbody ) {
+
+                                               // String was a <table>, *may* have spurious <tbody>
+                                               elem = tag === "table" && !rtbody.test( elem ) ?
+                                                       tmp.firstChild :
+
+                                                       // String was a bare <thead> or <tfoot>
+                                                       wrap[1] === "<table>" && !rtbody.test( elem ) ?
+                                                               tmp :
+                                                               0;
+
+                                               j = elem && elem.childNodes.length;
+                                               while ( j-- ) {
+                                                       if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+                                                               elem.removeChild( tbody );
+                                                       }
+                                               }
+                                       }
+
+                                       jQuery.merge( nodes, tmp.childNodes );
+
+                                       // Fix #12392 for WebKit and IE > 9
+                                       tmp.textContent = "";
+
+                                       // Fix #12392 for oldIE
+                                       while ( tmp.firstChild ) {
+                                               tmp.removeChild( tmp.firstChild );
+                                       }
+
+                                       // Remember the top-level container for proper cleanup
+                                       tmp = safe.lastChild;
+                               }
+                       }
+               }
+
+               // Fix #11356: Clear elements from fragment
+               if ( tmp ) {
+                       safe.removeChild( tmp );
+               }
+
+               // Reset defaultChecked for any radios and checkboxes
+               // about to be appended to the DOM in IE 6/7 (#8060)
+               if ( !jQuery.support.appendChecked ) {
+                       jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+               }
+
+               i = 0;
+               while ( (elem = nodes[ i++ ]) ) {
+
+                       // #4087 - If origin and destination elements are the same, and this is
+                       // that element, do not do anything
+                       if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+                               continue;
+                       }
+
+                       contains = jQuery.contains( elem.ownerDocument, elem );
+
+                       // Append to fragment
+                       tmp = getAll( safe.appendChild( elem ), "script" );
+
+                       // Preserve script evaluation history
+                       if ( contains ) {
+                               setGlobalEval( tmp );
+                       }
+
+                       // Capture executables
+                       if ( scripts ) {
+                               j = 0;
+                               while ( (elem = tmp[ j++ ]) ) {
+                                       if ( rscriptType.test( elem.type || "" ) ) {
+                                               scripts.push( elem );
+                                       }
+                               }
+                       }
+               }
+
+               tmp = null;
+
+               return safe;
+       },
+
+       cleanData: function( elems, /* internal */ acceptData ) {
+               var elem, type, id, data,
+                       i = 0,
+                       internalKey = jQuery.expando,
+                       cache = jQuery.cache,
+                       deleteExpando = jQuery.support.deleteExpando,
+                       special = jQuery.event.special;
+
+               for ( ; (elem = elems[i]) != null; i++ ) {
+
+                       if ( acceptData || jQuery.acceptData( elem ) ) {
+
+                               id = elem[ internalKey ];
+                               data = id && cache[ id ];
+
+                               if ( data ) {
+                                       if ( data.events ) {
+                                               for ( type in data.events ) {
+                                                       if ( special[ type ] ) {
+                                                               jQuery.event.remove( elem, type );
+
+                                                       // This is a shortcut to avoid jQuery.event.remove's overhead
+                                                       } else {
+                                                               jQuery.removeEvent( elem, type, data.handle );
+                                                       }
+                                               }
+                                       }
+
+                                       // Remove cache only if it was not already removed by jQuery.event.remove
+                                       if ( cache[ id ] ) {
+
+                                               delete cache[ id ];
+
+                                               // IE does not allow us to delete expando properties from nodes,
+                                               // nor does it have a removeAttribute function on Document nodes;
+                                               // we must handle all of these cases
+                                               if ( deleteExpando ) {
+                                                       delete elem[ internalKey ];
+
+                                               } else if ( typeof elem.removeAttribute !== core_strundefined ) {
+                                                       elem.removeAttribute( internalKey );
+
+                                               } else {
+                                                       elem[ internalKey ] = null;
+                                               }
+
+                                               core_deletedIds.push( id );
+                                       }
+                               }
+                       }
+               }
+       },
+
+       _evalUrl: function( url ) {
+               return jQuery.ajax({
+                       url: url,
+                       type: "GET",
+                       dataType: "script",
+                       async: false,
+                       global: false,
+                       "throws": true
+               });
+       }
+});
+jQuery.fn.extend({
+       wrapAll: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapAll( html.call(this, i) );
+                       });
+               }
+
+               if ( this[0] ) {
+                       // The elements to wrap the target around
+                       var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+                       if ( this[0].parentNode ) {
+                               wrap.insertBefore( this[0] );
+                       }
+
+                       wrap.map(function() {
+                               var elem = this;
+
+                               while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+                                       elem = elem.firstChild;
+                               }
+
+                               return elem;
+                       }).append( this );
+               }
+
+               return this;
+       },
+
+       wrapInner: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapInner( html.call(this, i) );
+                       });
+               }
+
+               return this.each(function() {
+                       var self = jQuery( this ),
+                               contents = self.contents();
+
+                       if ( contents.length ) {
+                               contents.wrapAll( html );
+
+                       } else {
+                               self.append( html );
+                       }
+               });
+       },
+
+       wrap: function( html ) {
+               var isFunction = jQuery.isFunction( html );
+
+               return this.each(function(i) {
+                       jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+               });
+       },
+
+       unwrap: function() {
+               return this.parent().each(function() {
+                       if ( !jQuery.nodeName( this, "body" ) ) {
+                               jQuery( this ).replaceWith( this.childNodes );
+                       }
+               }).end();
+       }
+});
+var iframe, getStyles, curCSS,
+       ralpha = /alpha\([^)]*\)/i,
+       ropacity = /opacity\s*=\s*([^)]*)/,
+       rposition = /^(top|right|bottom|left)$/,
+       // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+       // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+       rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+       rmargin = /^margin/,
+       rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+       rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+       rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+       elemdisplay = { BODY: "block" },
+
+       cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+       cssNormalTransform = {
+               letterSpacing: 0,
+               fontWeight: 400
+       },
+
+       cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+       cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+       // shortcut for names that are not vendor prefixed
+       if ( name in style ) {
+               return name;
+       }
+
+       // check for vendor prefixed names
+       var capName = name.charAt(0).toUpperCase() + name.slice(1),
+               origName = name,
+               i = cssPrefixes.length;
+
+       while ( i-- ) {
+               name = cssPrefixes[ i ] + capName;
+               if ( name in style ) {
+                       return name;
+               }
+       }
+
+       return origName;
+}
+
+function isHidden( elem, el ) {
+       // isHidden might be called from jQuery#filter function;
+       // in that case, element will be second argument
+       elem = el || elem;
+       return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+       var display, elem, hidden,
+               values = [],
+               index = 0,
+               length = elements.length;
+
+       for ( ; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+
+               values[ index ] = jQuery._data( elem, "olddisplay" );
+               display = elem.style.display;
+               if ( show ) {
+                       // Reset the inline display of this element to learn if it is
+                       // being hidden by cascaded rules or not
+                       if ( !values[ index ] && display === "none" ) {
+                               elem.style.display = "";
+                       }
+
+                       // Set elements which have been overridden with display: none
+                       // in a stylesheet to whatever the default browser style is
+                       // for such an element
+                       if ( elem.style.display === "" && isHidden( elem ) ) {
+                               values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+                       }
+               } else {
+
+                       if ( !values[ index ] ) {
+                               hidden = isHidden( elem );
+
+                               if ( display && display !== "none" || !hidden ) {
+                                       jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+                               }
+                       }
+               }
+       }
+
+       // Set the display of most of the elements in a second loop
+       // to avoid the constant reflow
+       for ( index = 0; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+               if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+                       elem.style.display = show ? values[ index ] || "" : "none";
+               }
+       }
+
+       return elements;
+}
+
+jQuery.fn.extend({
+       css: function( name, value ) {
+               return jQuery.access( this, function( elem, name, value ) {
+                       var len, styles,
+                               map = {},
+                               i = 0;
+
+                       if ( jQuery.isArray( name ) ) {
+                               styles = getStyles( elem );
+                               len = name.length;
+
+                               for ( ; i < len; i++ ) {
+                                       map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+                               }
+
+                               return map;
+                       }
+
+                       return value !== undefined ?
+                               jQuery.style( elem, name, value ) :
+                               jQuery.css( elem, name );
+               }, name, value, arguments.length > 1 );
+       },
+       show: function() {
+               return showHide( this, true );
+       },
+       hide: function() {
+               return showHide( this );
+       },
+       toggle: function( state ) {
+               if ( typeof state === "boolean" ) {
+                       return state ? this.show() : this.hide();
+               }
+
+               return this.each(function() {
+                       if ( isHidden( this ) ) {
+                               jQuery( this ).show();
+                       } else {
+                               jQuery( this ).hide();
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       // Add in style property hooks for overriding the default
+       // behavior of getting and setting a style property
+       cssHooks: {
+               opacity: {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // We should always get a number back from opacity
+                                       var ret = curCSS( elem, "opacity" );
+                                       return ret === "" ? "1" : ret;
+                               }
+                       }
+               }
+       },
+
+       // Don't automatically add "px" to these possibly-unitless properties
+       cssNumber: {
+               "columnCount": true,
+               "fillOpacity": true,
+               "fontWeight": true,
+               "lineHeight": true,
+               "opacity": true,
+               "order": true,
+               "orphans": true,
+               "widows": true,
+               "zIndex": true,
+               "zoom": true
+       },
+
+       // Add in properties whose names you wish to fix before
+       // setting or getting the value
+       cssProps: {
+               // normalize float css property
+               "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+       },
+
+       // Get and set the style property on a DOM Node
+       style: function( elem, name, value, extra ) {
+               // Don't set styles on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+                       return;
+               }
+
+               // Make sure that we're working with the right name
+               var ret, type, hooks,
+                       origName = jQuery.camelCase( name ),
+                       style = elem.style;
+
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // Check if we're setting a value
+               if ( value !== undefined ) {
+                       type = typeof value;
+
+                       // convert relative number strings (+= or -=) to relative numbers. #7345
+                       if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+                               value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+                               // Fixes bug #9237
+                               type = "number";
+                       }
+
+                       // Make sure that NaN and null values aren't set. See: #7116
+                       if ( value == null || type === "number" && isNaN( value ) ) {
+                               return;
+                       }
+
+                       // If a number was passed in, add 'px' to the (except for certain CSS properties)
+                       if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+                               value += "px";
+                       }
+
+                       // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+                       // but it would mean to define eight (for every problematic property) identical functions
+                       if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+                               style[ name ] = "inherit";
+                       }
+
+                       // If a hook was provided, use that value, otherwise just set the specified value
+                       if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+                               // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+                               // Fixes bug #5509
+                               try {
+                                       style[ name ] = value;
+                               } catch(e) {}
+                       }
+
+               } else {
+                       // If a hook was provided get the non-computed value from there
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+                               return ret;
+                       }
+
+                       // Otherwise just get the value from the style object
+                       return style[ name ];
+               }
+       },
+
+       css: function( elem, name, extra, styles ) {
+               var num, val, hooks,
+                       origName = jQuery.camelCase( name );
+
+               // Make sure that we're working with the right name
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // If a hook was provided get the computed value from there
+               if ( hooks && "get" in hooks ) {
+                       val = hooks.get( elem, true, extra );
+               }
+
+               // Otherwise, if a way to get the computed value exists, use that
+               if ( val === undefined ) {
+                       val = curCSS( elem, name, styles );
+               }
+
+               //convert "normal" to computed value
+               if ( val === "normal" && name in cssNormalTransform ) {
+                       val = cssNormalTransform[ name ];
+               }
+
+               // Return, converting to number if forced or a qualifier was provided and val looks numeric
+               if ( extra === "" || extra ) {
+                       num = parseFloat( val );
+                       return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+               }
+               return val;
+       }
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+       getStyles = function( elem ) {
+               return window.getComputedStyle( elem, null );
+       };
+
+       curCSS = function( elem, name, _computed ) {
+               var width, minWidth, maxWidth,
+                       computed = _computed || getStyles( elem ),
+
+                       // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+                       ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+                       style = elem.style;
+
+               if ( computed ) {
+
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+                               ret = jQuery.style( elem, name );
+                       }
+
+                       // A tribute to the "awesome hack by Dean Edwards"
+                       // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+                       // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+                       // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+                       if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+                               // Remember the original values
+                               width = style.width;
+                               minWidth = style.minWidth;
+                               maxWidth = style.maxWidth;
+
+                               // Put in the new values to get a computed value out
+                               style.minWidth = style.maxWidth = style.width = ret;
+                               ret = computed.width;
+
+                               // Revert the changed values
+                               style.width = width;
+                               style.minWidth = minWidth;
+                               style.maxWidth = maxWidth;
+                       }
+               }
+
+               return ret;
+       };
+} else if ( document.documentElement.currentStyle ) {
+       getStyles = function( elem ) {
+               return elem.currentStyle;
+       };
+
+       curCSS = function( elem, name, _computed ) {
+               var left, rs, rsLeft,
+                       computed = _computed || getStyles( elem ),
+                       ret = computed ? computed[ name ] : undefined,
+                       style = elem.style;
+
+               // Avoid setting ret to empty string here
+               // so we don't default to auto
+               if ( ret == null && style && style[ name ] ) {
+                       ret = style[ name ];
+               }
+
+               // From the awesome hack by Dean Edwards
+               // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+               // If we're not dealing with a regular pixel number
+               // but a number that has a weird ending, we need to convert it to pixels
+               // but not position css attributes, as those are proportional to the parent element instead
+               // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+               if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+                       // Remember the original values
+                       left = style.left;
+                       rs = elem.runtimeStyle;
+                       rsLeft = rs && rs.left;
+
+                       // Put in the new values to get a computed value out
+                       if ( rsLeft ) {
+                               rs.left = elem.currentStyle.left;
+                       }
+                       style.left = name === "fontSize" ? "1em" : ret;
+                       ret = style.pixelLeft + "px";
+
+                       // Revert the changed values
+                       style.left = left;
+                       if ( rsLeft ) {
+                               rs.left = rsLeft;
+                       }
+               }
+
+               return ret === "" ? "auto" : ret;
+       };
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+       var matches = rnumsplit.exec( value );
+       return matches ?
+               // Guard against undefined "subtract", e.g., when used as in cssHooks
+               Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+               value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+       var i = extra === ( isBorderBox ? "border" : "content" ) ?
+               // If we already have the right measurement, avoid augmentation
+               4 :
+               // Otherwise initialize for horizontal or vertical properties
+               name === "width" ? 1 : 0,
+
+               val = 0;
+
+       for ( ; i < 4; i += 2 ) {
+               // both box models exclude margin, so add it if we want it
+               if ( extra === "margin" ) {
+                       val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+               }
+
+               if ( isBorderBox ) {
+                       // border-box includes padding, so remove it if we want content
+                       if ( extra === "content" ) {
+                               val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+                       }
+
+                       // at this point, extra isn't border nor margin, so remove border
+                       if ( extra !== "margin" ) {
+                               val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               } else {
+                       // at this point, extra isn't content, so add padding
+                       val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+                       // at this point, extra isn't content nor padding, so add border
+                       if ( extra !== "padding" ) {
+                               val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               }
+       }
+
+       return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+       // Start with offset property, which is equivalent to the border-box value
+       var valueIsBorderBox = true,
+               val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+               styles = getStyles( elem ),
+               isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+       // some non-html elements return undefined for offsetWidth, so check for null/undefined
+       // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+       // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+       if ( val <= 0 || val == null ) {
+               // Fall back to computed then uncomputed css if necessary
+               val = curCSS( elem, name, styles );
+               if ( val < 0 || val == null ) {
+                       val = elem.style[ name ];
+               }
+
+               // Computed unit is not pixels. Stop here and return.
+               if ( rnumnonpx.test(val) ) {
+                       return val;
+               }
+
+               // we need the check for style in case a browser which returns unreliable values
+               // for getComputedStyle silently falls back to the reliable elem.style
+               valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+               // Normalize "", auto, and prepare for extra
+               val = parseFloat( val ) || 0;
+       }
+
+       // use the active box-sizing model to add/subtract irrelevant styles
+       return ( val +
+               augmentWidthOrHeight(
+                       elem,
+                       name,
+                       extra || ( isBorderBox ? "border" : "content" ),
+                       valueIsBorderBox,
+                       styles
+               )
+       ) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+       var doc = document,
+               display = elemdisplay[ nodeName ];
+
+       if ( !display ) {
+               display = actualDisplay( nodeName, doc );
+
+               // If the simple way fails, read from inside an iframe
+               if ( display === "none" || !display ) {
+                       // Use the already-created iframe if possible
+                       iframe = ( iframe ||
+                               jQuery("<iframe frameborder='0' width='0' height='0'/>")
+                               .css( "cssText", "display:block !important" )
+                       ).appendTo( doc.documentElement );
+
+                       // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+                       doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+                       doc.write("<!doctype html><html><body>");
+                       doc.close();
+
+                       display = actualDisplay( nodeName, doc );
+                       iframe.detach();
+               }
+
+               // Store the correct default display
+               elemdisplay[ nodeName ] = display;
+       }
+
+       return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+       var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+               display = jQuery.css( elem[0], "display" );
+       elem.remove();
+       return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+       jQuery.cssHooks[ name ] = {
+               get: function( elem, computed, extra ) {
+                       if ( computed ) {
+                               // certain elements can have dimension info if we invisibly show them
+                               // however, it must have a current display style that would benefit from this
+                               return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+                                       jQuery.swap( elem, cssShow, function() {
+                                               return getWidthOrHeight( elem, name, extra );
+                                       }) :
+                                       getWidthOrHeight( elem, name, extra );
+                       }
+               },
+
+               set: function( elem, value, extra ) {
+                       var styles = extra && getStyles( elem );
+                       return setPositiveNumber( elem, value, extra ?
+                               augmentWidthOrHeight(
+                                       elem,
+                                       name,
+                                       extra,
+                                       jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+                                       styles
+                               ) : 0
+                       );
+               }
+       };
+});
+
+if ( !jQuery.support.opacity ) {
+       jQuery.cssHooks.opacity = {
+               get: function( elem, computed ) {
+                       // IE uses filters for opacity
+                       return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+                               ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+                               computed ? "1" : "";
+               },
+
+               set: function( elem, value ) {
+                       var style = elem.style,
+                               currentStyle = elem.currentStyle,
+                               opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+                               filter = currentStyle && currentStyle.filter || style.filter || "";
+
+                       // IE has trouble with opacity if it does not have layout
+                       // Force it by setting the zoom level
+                       style.zoom = 1;
+
+                       // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+                       // if value === "", then remove inline opacity #12685
+                       if ( ( value >= 1 || value === "" ) &&
+                                       jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+                                       style.removeAttribute ) {
+
+                               // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+                               // if "filter:" is present at all, clearType is disabled, we want to avoid this
+                               // style.removeAttribute is IE Only, but so apparently is this code path...
+                               style.removeAttribute( "filter" );
+
+                               // if there is no filter style applied in a css rule or unset inline opacity, we are done
+                               if ( value === "" || currentStyle && !currentStyle.filter ) {
+                                       return;
+                               }
+                       }
+
+                       // otherwise, set new filter values
+                       style.filter = ralpha.test( filter ) ?
+                               filter.replace( ralpha, opacity ) :
+                               filter + " " + opacity;
+               }
+       };
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+       if ( !jQuery.support.reliableMarginRight ) {
+               jQuery.cssHooks.marginRight = {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                                       // Work around by temporarily setting element display to inline-block
+                                       return jQuery.swap( elem, { "display": "inline-block" },
+                                               curCSS, [ elem, "marginRight" ] );
+                               }
+                       }
+               };
+       }
+
+       // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+       // getComputedStyle returns percent when specified for top/left/bottom/right
+       // rather than make the css module depend on the offset module, we just check for it here
+       if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+               jQuery.each( [ "top", "left" ], function( i, prop ) {
+                       jQuery.cssHooks[ prop ] = {
+                               get: function( elem, computed ) {
+                                       if ( computed ) {
+                                               computed = curCSS( elem, prop );
+                                               // if curCSS returns percentage, fallback to offset
+                                               return rnumnonpx.test( computed ) ?
+                                                       jQuery( elem ).position()[ prop ] + "px" :
+                                                       computed;
+                                       }
+                               }
+                       };
+               });
+       }
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.hidden = function( elem ) {
+               // Support: Opera <= 12.12
+               // Opera reports offsetWidths and offsetHeights less than zero on some elements
+               return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+                       (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+       };
+
+       jQuery.expr.filters.visible = function( elem ) {
+               return !jQuery.expr.filters.hidden( elem );
+       };
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+       margin: "",
+       padding: "",
+       border: "Width"
+}, function( prefix, suffix ) {
+       jQuery.cssHooks[ prefix + suffix ] = {
+               expand: function( value ) {
+                       var i = 0,
+                               expanded = {},
+
+                               // assumes a single number if not a string
+                               parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+                       for ( ; i < 4; i++ ) {
+                               expanded[ prefix + cssExpand[ i ] + suffix ] =
+                                       parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+                       }
+
+                       return expanded;
+               }
+       };
+
+       if ( !rmargin.test( prefix ) ) {
+               jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+       }
+});
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+       rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map(function(){
+                       // Can add propHook for "elements" to filter or add form elements
+                       var elements = jQuery.prop( this, "elements" );
+                       return elements ? jQuery.makeArray( elements ) : this;
+               })
+               .filter(function(){
+                       var type = this.type;
+                       // Use .is(":disabled") so that fieldset[disabled] works
+                       return this.name && !jQuery( this ).is( ":disabled" ) &&
+                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                               ( this.checked || !manipulation_rcheckableType.test( type ) );
+               })
+               .map(function( i, elem ){
+                       var val = jQuery( this ).val();
+
+                       return val == null ?
+                               null :
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val ){
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                                       }) :
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               }).get();
+       }
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, value ) {
+                       // If value is a function, invoke it and return its value
+                       value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+                       s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+               };
+
+       // Set traditional to true for jQuery <= 1.3.2 behavior.
+       if ( traditional === undefined ) {
+               traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+       }
+
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               });
+
+       } else {
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
+
+       // Return the resulting serialization
+       return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( jQuery.isArray( obj ) ) {
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+                               // Item is non-scalar (array or object), encode its numeric index.
+                               buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+                       }
+               });
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+jQuery.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( i, name ) {
+
+       // Handle event binding
+       jQuery.fn[ name ] = function( data, fn ) {
+               return arguments.length > 0 ?
+                       this.on( name, null, data, fn ) :
+                       this.trigger( name );
+       };
+});
+
+jQuery.fn.extend({
+       hover: function( fnOver, fnOut ) {
+               return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+       },
+
+       bind: function( types, data, fn ) {
+               return this.on( types, null, data, fn );
+       },
+       unbind: function( types, fn ) {
+               return this.off( types, null, fn );
+       },
+
+       delegate: function( selector, types, data, fn ) {
+               return this.on( types, selector, data, fn );
+       },
+       undelegate: function( selector, types, fn ) {
+               // ( namespace ) or ( selector, types [, fn] )
+               return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+       }
+});
+var
+       // Document location
+       ajaxLocParts,
+       ajaxLocation,
+       ajax_nonce = jQuery.now(),
+
+       ajax_rquery = /\?/,
+       rhash = /#.*$/,
+       rts = /([?&])_=[^&]*/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+       rnoContent = /^(?:GET|HEAD)$/,
+       rprotocol = /^\/\//,
+       rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+       // Keep a copy of the old load method
+       _load = jQuery.fn.load,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+       allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+       ajaxLocation = location.href;
+} catch( e ) {
+       // Use the href attribute of an A element
+       // since IE will modify it given document.location
+       ajaxLocation = document.createElement( "a" );
+       ajaxLocation.href = "";
+       ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               var dataType,
+                       i = 0,
+                       dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+               if ( jQuery.isFunction( func ) ) {
+                       // For each dataType in the dataTypeExpression
+                       while ( (dataType = dataTypes[i++]) ) {
+                               // Prepend if requested
+                               if ( dataType[0] === "+" ) {
+                                       dataType = dataType.slice( 1 ) || "*";
+                                       (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+                               // Otherwise append
+                               } else {
+                                       (structure[ dataType ] = structure[ dataType ] || []).push( func );
+                               }
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+       var inspected = {},
+               seekingTransport = ( structure === transports );
+
+       function inspect( dataType ) {
+               var selected;
+               inspected[ dataType ] = true;
+               jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+                       var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+                       if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+                               options.dataTypes.unshift( dataTypeOrTransport );
+                               inspect( dataTypeOrTransport );
+                               return false;
+                       } else if ( seekingTransport ) {
+                               return !( selected = dataTypeOrTransport );
+                       }
+               });
+               return selected;
+       }
+
+       return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+       var deep, key,
+               flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+       for ( key in src ) {
+               if ( src[ key ] !== undefined ) {
+                       ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+               }
+       }
+       if ( deep ) {
+               jQuery.extend( true, target, deep );
+       }
+
+       return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+       if ( typeof url !== "string" && _load ) {
+               return _load.apply( this, arguments );
+       }
+
+       var selector, response, type,
+               self = this,
+               off = url.indexOf(" ");
+
+       if ( off >= 0 ) {
+               selector = url.slice( off, url.length );
+               url = url.slice( 0, off );
+       }
+
+       // If it's a function
+       if ( jQuery.isFunction( params ) ) {
+
+               // We assume that it's the callback
+               callback = params;
+               params = undefined;
+
+       // Otherwise, build a param string
+       } else if ( params && typeof params === "object" ) {
+               type = "POST";
+       }
+
+       // If we have elements to modify, make the request
+       if ( self.length > 0 ) {
+               jQuery.ajax({
+                       url: url,
+
+                       // if "type" variable is undefined, then "GET" method will be used
+                       type: type,
+                       dataType: "html",
+                       data: params
+               }).done(function( responseText ) {
+
+                       // Save response for use in complete callback
+                       response = arguments;
+
+                       self.html( selector ?
+
+                               // If a selector was specified, locate the right elements in a dummy div
+                               // Exclude scripts to avoid IE 'Permission Denied' errors
+                               jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+                               // Otherwise use the full result
+                               responseText );
+
+               }).complete( callback && function( jqXHR, status ) {
+                       self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+               });
+       }
+
+       return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+       jQuery.fn[ type ] = function( fn ){
+               return this.on( type, fn );
+       };
+});
+
+jQuery.extend({
+
+       // Counter for holding the number of active queries
+       active: 0,
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       etag: {},
+
+       ajaxSettings: {
+               url: ajaxLocation,
+               type: "GET",
+               isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+               global: true,
+               processData: true,
+               async: true,
+               contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+               /*
+               timeout: 0,
+               data: null,
+               dataType: null,
+               username: null,
+               password: null,
+               cache: null,
+               throws: false,
+               traditional: false,
+               headers: {},
+               */
+
+               accepts: {
+                       "*": allTypes,
+                       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"
+               },
+
+               // Data converters
+               // Keys separate source (or catchall "*") and destination types with a single space
+               converters: {
+
+                       // Convert anything to text
+                       "* text": String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": jQuery.parseJSON,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               },
+
+               // For options that shouldn't be deep extended:
+               // you can add your own custom options here if
+               // and when you create one that shouldn't be
+               // deep extended (see ajaxExtend)
+               flatOptions: {
+                       url: true,
+                       context: true
+               }
+       },
+
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function( target, settings ) {
+               return settings ?
+
+                       // Building a settings object
+                       ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+                       // Extending ajaxSettings
+                       ajaxExtend( jQuery.ajaxSettings, target );
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var // Cross-domain detection vars
+                       parts,
+                       // Loop variable
+                       i,
+                       // URL without anti-cache param
+                       cacheURL,
+                       // Response headers as string
+                       responseHeadersString,
+                       // timeout handle
+                       timeoutTimer,
+
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+
+                       transport,
+                       // Response headers
+                       responseHeaders,
+                       // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+                       // Callbacks context
+                       callbackContext = s.context || s,
+                       // Context for global events is callbackContext if it is a DOM node or jQuery collection
+                       globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+                               jQuery( callbackContext ) :
+                               jQuery.event,
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery.Callbacks("once memory"),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+                       // The jqXHR state
+                       state = 0,
+                       // Default abort message
+                       strAbort = "canceled",
+                       // Fake xhr
+                       jqXHR = {
+                               readyState: 0,
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( state === 2 ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while ( (match = rheaders.exec( responseHeadersString )) ) {
+                                                               responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match == null ? null : match;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return state === 2 ? responseHeadersString : null;
+                               },
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       var lname = name.toLowerCase();
+                                       if ( !state ) {
+                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
+                               // Status-dependent callbacks
+                               statusCode: function( map ) {
+                                       var code;
+                                       if ( map ) {
+                                               if ( state < 2 ) {
+                                                       for ( code in map ) {
+                                                               // Lazy-add the new callback in a way that preserves old ones
+                                                               statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                                                       }
+                                               } else {
+                                                       // Execute the appropriate callbacks
+                                                       jqXHR.always( map[ jqXHR.status ] );
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       var finalText = statusText || strAbort;
+                                       if ( transport ) {
+                                               transport.abort( finalText );
+                                       }
+                                       done( 0, finalText );
+                                       return this;
+                               }
+                       };
+
+               // Attach deferreds
+               deferred.promise( jqXHR ).complete = completeDeferred.add;
+               jqXHR.success = jqXHR.done;
+               jqXHR.error = jqXHR.fail;
+
+               // Remove hash character (#7531: and string promotion)
+               // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+               // Handle falsy url in the settings object (#10093: consistency with old signature)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+               // Alias method option to type as per ticket #12004
+               s.type = options.method || options.type || s.method || s.type;
+
+               // Extract dataTypes list
+               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+               // A cross-domain request is in order when we have a protocol:host:port mismatch
+               if ( s.crossDomain == null ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!( parts &&
+                               ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+                       );
+               }
+
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
+
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+               // If request was aborted inside a prefilter, stop there
+               if ( state === 2 ) {
+                       return jqXHR;
+               }
+
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
+
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger("ajaxStart");
+               }
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
+
+               // Save the URL in case we're toying with the If-Modified-Since
+               // and/or If-None-Match header later on
+               cacheURL = s.url;
+
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
+
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+                               // #9682: remove data so that it's not used in an eventual retry
+                               delete s.data;
+                       }
+
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
+                               s.url = rts.test( cacheURL ) ?
+
+                                       // If there is already a '_' parameter, set its value
+                                       cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+                                       // Otherwise add one to the end
+                                       cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+                       }
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       if ( jQuery.lastModified[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+                       }
+                       if ( jQuery.etag[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+                       }
+               }
+
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+                               s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                       // Abort if not done already and return
+                       return jqXHR.abort();
+               }
+
+               // aborting is no longer a cancellation
+               strAbort = "abort";
+
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
+
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout(function() {
+                                       jqXHR.abort("timeout");
+                               }, s.timeout );
+                       }
+
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch ( e ) {
+                               // Propagate exception as error if not done
+                               if ( state < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       throw e;
+                               }
+                       }
+               }
+
+               // Callback for when everything is done
+               function done( status, nativeStatusText, responses, headers ) {
+                       var isSuccess, success, error, response, modified,
+                               statusText = nativeStatusText;
+
+                       // Called once
+                       if ( state === 2 ) {
+                               return;
+                       }
+
+                       // State is "done" now
+                       state = 2;
+
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               clearTimeout( timeoutTimer );
+                       }
+
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
+
+                       // Cache response headers
+                       responseHeadersString = headers || "";
+
+                       // Set readyState
+                       jqXHR.readyState = status > 0 ? 4 : 0;
+
+                       // Determine if successful
+                       isSuccess = status >= 200 && status < 300 || status === 304;
+
+                       // Get response data
+                       if ( responses ) {
+                               response = ajaxHandleResponses( s, jqXHR, responses );
+                       }
+
+                       // Convert no matter what (that way responseXXX fields are always set)
+                       response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+                       // If successful, handle type chaining
+                       if ( isSuccess ) {
+
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                               if ( s.ifModified ) {
+                                       modified = jqXHR.getResponseHeader("Last-Modified");
+                                       if ( modified ) {
+                                               jQuery.lastModified[ cacheURL ] = modified;
+                                       }
+                                       modified = jqXHR.getResponseHeader("etag");
+                                       if ( modified ) {
+                                               jQuery.etag[ cacheURL ] = modified;
+                                       }
+                               }
+
+                               // if no content
+                               if ( status === 204 || s.type === "HEAD" ) {
+                                       statusText = "nocontent";
+
+                               // if not modified
+                               } else if ( status === 304 ) {
+                                       statusText = "notmodified";
+
+                               // If we have data, let's convert it
+                               } else {
+                                       statusText = response.state;
+                                       success = response.data;
+                                       error = response.error;
+                                       isSuccess = !error;
+                               }
+                       } else {
+                               // We extract error from statusText
+                               // then normalize statusText and status for non-aborts
+                               error = statusText;
+                               if ( status || !statusText ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
+                       }
+
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
+
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+                                       [ jqXHR, s, isSuccess ? success : error ] );
+                       }
+
+                       // Complete
+                       completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger("ajaxStop");
+                               }
+                       }
+               }
+
+               return jqXHR;
+       },
+
+       getJSON: function( url, data, callback ) {
+               return jQuery.get( url, data, callback, "json" );
+       },
+
+       getScript: function( url, callback ) {
+               return jQuery.get( url, undefined, callback, "script" );
+       }
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+               // shift arguments if data argument was omitted
+               if ( jQuery.isFunction( data ) ) {
+                       type = type || callback;
+                       callback = data;
+                       data = undefined;
+               }
+
+               return jQuery.ajax({
+                       url: url,
+                       type: method,
+                       dataType: type,
+                       data: data,
+                       success: callback
+               });
+       };
+});
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+       var firstDataType, ct, finalDataType, type,
+               contents = s.contents,
+               dataTypes = s.dataTypes;
+
+       // Remove auto dataType and get content-type in the process
+       while( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+               }
+       }
+
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
+               }
+       }
+
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
+               }
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
+
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+       var conv2, current, conv, tmp, prev,
+               converters = {},
+               // Work with a copy of dataTypes in case we need to modify it for conversion
+               dataTypes = s.dataTypes.slice();
+
+       // Create converters map with lowercased keys
+       if ( dataTypes[ 1 ] ) {
+               for ( conv in s.converters ) {
+                       converters[ conv.toLowerCase() ] = s.converters[ conv ];
+               }
+       }
+
+       current = dataTypes.shift();
+
+       // Convert to each sequential dataType
+       while ( current ) {
+
+               if ( s.responseFields[ current ] ) {
+                       jqXHR[ s.responseFields[ current ] ] = response;
+               }
+
+               // Apply the dataFilter if provided
+               if ( !prev && isSuccess && s.dataFilter ) {
+                       response = s.dataFilter( response, s.dataType );
+               }
+
+               prev = current;
+               current = dataTypes.shift();
+
+               if ( current ) {
+
+                       // There's only work to do if current dataType is non-auto
+                       if ( current === "*" ) {
+
+                               current = prev;
+
+                       // Convert response if prev dataType is non-auto and differs from current
+                       } else if ( prev !== "*" && prev !== current ) {
+
+                               // Seek a direct converter
+                               conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+                               // If none found, seek a pair
+                               if ( !conv ) {
+                                       for ( conv2 in converters ) {
+
+                                               // If conv2 outputs current
+                                               tmp = conv2.split( " " );
+                                               if ( tmp[ 1 ] === current ) {
+
+                                                       // If prev can be converted to accepted input
+                                                       conv = converters[ prev + " " + tmp[ 0 ] ] ||
+                                                               converters[ "* " + tmp[ 0 ] ];
+                                                       if ( conv ) {
+                                                               // Condense equivalence converters
+                                                               if ( conv === true ) {
+                                                                       conv = converters[ conv2 ];
+
+                                                               // Otherwise, insert the intermediate dataType
+                                                               } else if ( converters[ conv2 ] !== true ) {
+                                                                       current = tmp[ 0 ];
+                                                                       dataTypes.unshift( tmp[ 1 ] );
+                                                               }
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Apply converter (if not an equivalence)
+                               if ( conv !== true ) {
+
+                                       // Unless errors are allowed to bubble, catch and return them
+                                       if ( conv && s[ "throws" ] ) {
+                                               response = conv( response );
+                                       } else {
+                                               try {
+                                                       response = conv( response );
+                                               } catch ( e ) {
+                                                       return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+       accepts: {
+               script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /(?:java|ecma)script/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
+               }
+       }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+               s.global = false;
+       }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+
+               var script,
+                       head = document.head || jQuery("head")[0] || document.documentElement;
+
+               return {
+
+                       send: function( _, callback ) {
+
+                               script = document.createElement("script");
+
+                               script.async = true;
+
+                               if ( s.scriptCharset ) {
+                                       script.charset = s.scriptCharset;
+                               }
+
+                               script.src = s.url;
+
+                               // Attach handlers for all browsers
+                               script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+                                       if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+                                               // Handle memory leak in IE
+                                               script.onload = script.onreadystatechange = null;
+
+                                               // Remove the script
+                                               if ( script.parentNode ) {
+                                                       script.parentNode.removeChild( script );
+                                               }
+
+                                               // Dereference the script
+                                               script = null;
+
+                                               // Callback if not abort
+                                               if ( !isAbort ) {
+                                                       callback( 200, "success" );
+                                               }
+                                       }
+                               };
+
+                               // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+                               // Use native DOM manipulation to avoid our domManip AJAX trickery
+                               head.insertBefore( script, head.firstChild );
+                       },
+
+                       abort: function() {
+                               if ( script ) {
+                                       script.onload( undefined, true );
+                               }
+                       }
+               };
+       }
+});
+var oldCallbacks = [],
+       rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+       jsonp: "callback",
+       jsonpCallback: function() {
+               var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+               this[ callback ] = true;
+               return callback;
+       }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var callbackName, overwritten, responseContainer,
+               jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+                       "url" :
+                       typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+               );
+
+       // Handle iff the expected data type is "jsonp" or we have a parameter to set
+       if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+               // Get callback name, remembering preexisting value associated with it
+               callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+                       s.jsonpCallback() :
+                       s.jsonpCallback;
+
+               // Insert callback into url or form data
+               if ( jsonProp ) {
+                       s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+               } else if ( s.jsonp !== false ) {
+                       s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+               }
+
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( callbackName + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
+
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Install callback
+               overwritten = window[ callbackName ];
+               window[ callbackName ] = function() {
+                       responseContainer = arguments;
+               };
+
+               // Clean-up function (fires after converters)
+               jqXHR.always(function() {
+                       // Restore preexisting value
+                       window[ callbackName ] = overwritten;
+
+                       // Save back as free
+                       if ( s[ callbackName ] ) {
+                               // make sure that re-using the options doesn't screw things around
+                               s.jsonpCallback = originalSettings.jsonpCallback;
+
+                               // save the callback name for future use
+                               oldCallbacks.push( callbackName );
+                       }
+
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+                               overwritten( responseContainer[ 0 ] );
+                       }
+
+                       responseContainer = overwritten = undefined;
+               });
+
+               // Delegate to script
+               return "script";
+       }
+});
+var xhrCallbacks, xhrSupported,
+       xhrId = 0,
+       // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+       xhrOnUnloadAbort = window.ActiveXObject && function() {
+               // Abort all pending requests
+               var key;
+               for ( key in xhrCallbacks ) {
+                       xhrCallbacks[ key ]( undefined, true );
+               }
+       };
+
+// Functions to create xhrs
+function createStandardXHR() {
+       try {
+               return new window.XMLHttpRequest();
+       } catch( e ) {}
+}
+
+function createActiveXHR() {
+       try {
+               return new window.ActiveXObject("Microsoft.XMLHTTP");
+       } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+       /* Microsoft failed to properly
+        * implement the XMLHttpRequest in IE7 (can't request local files),
+        * so we use the ActiveXObject when it is available
+        * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+        * we need a fallback.
+        */
+       function() {
+               return !this.isLocal && createStandardXHR() || createActiveXHR();
+       } :
+       // For all other browsers, use the standard XMLHttpRequest object
+       createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+       jQuery.ajaxTransport(function( s ) {
+               // Cross domain only allowed if supported through XMLHttpRequest
+               if ( !s.crossDomain || jQuery.support.cors ) {
+
+                       var callback;
+
+                       return {
+                               send: function( headers, complete ) {
+
+                                       // Get a new xhr
+                                       var handle, i,
+                                               xhr = s.xhr();
+
+                                       // Open the socket
+                                       // Passing null username, generates a login popup on Opera (#2865)
+                                       if ( s.username ) {
+                                               xhr.open( s.type, s.url, s.async, s.username, s.password );
+                                       } else {
+                                               xhr.open( s.type, s.url, s.async );
+                                       }
+
+                                       // Apply custom fields if provided
+                                       if ( s.xhrFields ) {
+                                               for ( i in s.xhrFields ) {
+                                                       xhr[ i ] = s.xhrFields[ i ];
+                                               }
+                                       }
+
+                                       // Override mime type if needed
+                                       if ( s.mimeType && xhr.overrideMimeType ) {
+                                               xhr.overrideMimeType( s.mimeType );
+                                       }
+
+                                       // X-Requested-With header
+                                       // For cross-domain requests, seeing as conditions for a preflight are
+                                       // akin to a jigsaw puzzle, we simply never set it to be sure.
+                                       // (it can always be set on a per-request basis or even using ajaxSetup)
+                                       // For same-domain requests, won't change header if already provided.
+                                       if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+                                               headers["X-Requested-With"] = "XMLHttpRequest";
+                                       }
+
+                                       // Need an extra try/catch for cross domain requests in Firefox 3
+                                       try {
+                                               for ( i in headers ) {
+                                                       xhr.setRequestHeader( i, headers[ i ] );
+                                               }
+                                       } catch( err ) {}
+
+                                       // Do send the request
+                                       // This may raise an exception which is actually
+                                       // handled in jQuery.ajax (so no try/catch here)
+                                       xhr.send( ( s.hasContent && s.data ) || null );
+
+                                       // Listener
+                                       callback = function( _, isAbort ) {
+                                               var status, responseHeaders, statusText, responses;
+
+                                               // Firefox throws exceptions when accessing properties
+                                               // of an xhr when a network error occurred
+                                               // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+                                               try {
+
+                                                       // Was never called and is aborted or complete
+                                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+                                                               // Only called once
+                                                               callback = undefined;
+
+                                                               // Do not keep as active anymore
+                                                               if ( handle ) {
+                                                                       xhr.onreadystatechange = jQuery.noop;
+                                                                       if ( xhrOnUnloadAbort ) {
+                                                                               delete xhrCallbacks[ handle ];
+                                                                       }
+                                                               }
+
+                                                               // If it's an abort
+                                                               if ( isAbort ) {
+                                                                       // Abort it manually if needed
+                                                                       if ( xhr.readyState !== 4 ) {
+                                                                               xhr.abort();
+                                                                       }
+                                                               } else {
+                                                                       responses = {};
+                                                                       status = xhr.status;
+                                                                       responseHeaders = xhr.getAllResponseHeaders();
+
+                                                                       // When requesting binary data, IE6-9 will throw an exception
+                                                                       // on any attempt to access responseText (#11426)
+                                                                       if ( typeof xhr.responseText === "string" ) {
+                                                                               responses.text = xhr.responseText;
+                                                                       }
+
+                                                                       // Firefox throws an exception when accessing
+                                                                       // statusText for faulty cross-domain requests
+                                                                       try {
+                                                                               statusText = xhr.statusText;
+                                                                       } catch( e ) {
+                                                                               // We normalize with Webkit giving an empty statusText
+                                                                               statusText = "";
+                                                                       }
+
+                                                                       // Filter status for non standard behaviors
+
+                                                                       // If the request is local and we have data: assume a success
+                                                                       // (success with no data won't get notified, that's the best we
+                                                                       // can do given current implementations)
+                                                                       if ( !status && s.isLocal && !s.crossDomain ) {
+                                                                               status = responses.text ? 200 : 404;
+                                                                       // IE - #1450: sometimes returns 1223 when it should be 204
+                                                                       } else if ( status === 1223 ) {
+                                                                               status = 204;
+                                                                       }
+                                                               }
+                                                       }
+                                               } catch( firefoxAccessException ) {
+                                                       if ( !isAbort ) {
+                                                               complete( -1, firefoxAccessException );
+                                                       }
+                                               }
+
+                                               // Call complete if needed
+                                               if ( responses ) {
+                                                       complete( status, statusText, responses, responseHeaders );
+                                               }
+                                       };
+
+                                       if ( !s.async ) {
+                                               // if we're in sync mode we fire the callback
+                                               callback();
+                                       } else if ( xhr.readyState === 4 ) {
+                                               // (IE6 & IE7) if it's in cache and has been
+                                               // retrieved directly we need to fire the callback
+                                               setTimeout( callback );
+                                       } else {
+                                               handle = ++xhrId;
+                                               if ( xhrOnUnloadAbort ) {
+                                                       // Create the active xhrs callbacks list if needed
+                                                       // and attach the unload handler
+                                                       if ( !xhrCallbacks ) {
+                                                               xhrCallbacks = {};
+                                                               jQuery( window ).unload( xhrOnUnloadAbort );
+                                                       }
+                                                       // Add to list of active xhrs callbacks
+                                                       xhrCallbacks[ handle ] = callback;
+                                               }
+                                               xhr.onreadystatechange = callback;
+                                       }
+                               },
+
+                               abort: function() {
+                                       if ( callback ) {
+                                               callback( undefined, true );
+                                       }
+                               }
+                       };
+               }
+       });
+}
+var fxNow, timerId,
+       rfxtypes = /^(?:toggle|show|hide)$/,
+       rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+       rrun = /queueHooks$/,
+       animationPrefilters = [ defaultPrefilter ],
+       tweeners = {
+               "*": [function( prop, value ) {
+                       var tween = this.createTween( prop, value ),
+                               target = tween.cur(),
+                               parts = rfxnum.exec( value ),
+                               unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+                               // Starting value computation is required for potential unit mismatches
+                               start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+                                       rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+                               scale = 1,
+                               maxIterations = 20;
+
+                       if ( start && start[ 3 ] !== unit ) {
+                               // Trust units reported by jQuery.css
+                               unit = unit || start[ 3 ];
+
+                               // Make sure we update the tween properties later on
+                               parts = parts || [];
+
+                               // Iteratively approximate from a nonzero starting point
+                               start = +target || 1;
+
+                               do {
+                                       // If previous iteration zeroed out, double until we get *something*
+                                       // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+                                       scale = scale || ".5";
+
+                                       // Adjust and apply
+                                       start = start / scale;
+                                       jQuery.style( tween.elem, prop, start + unit );
+
+                               // Update scale, tolerating zero or NaN from tween.cur()
+                               // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                               } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+                       }
+
+                       // Update tween properties
+                       if ( parts ) {
+                               start = tween.start = +start || +target || 0;
+                               tween.unit = unit;
+                               // If a +=/-= token was provided, we're doing a relative animation
+                               tween.end = parts[ 1 ] ?
+                                       start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+                                       +parts[ 2 ];
+                       }
+
+                       return tween;
+               }]
+       };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       setTimeout(function() {
+               fxNow = undefined;
+       });
+       return ( fxNow = jQuery.now() );
+}
+
+function createTween( value, prop, animation ) {
+       var tween,
+               collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+               index = 0,
+               length = collection.length;
+       for ( ; index < length; index++ ) {
+               if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+                       // we're done with this property
+                       return tween;
+               }
+       }
+}
+
+function Animation( elem, properties, options ) {
+       var result,
+               stopped,
+               index = 0,
+               length = animationPrefilters.length,
+               deferred = jQuery.Deferred().always( function() {
+                       // don't match elem in the :animated selector
+                       delete tick.elem;
+               }),
+               tick = function() {
+                       if ( stopped ) {
+                               return false;
+                       }
+                       var currentTime = fxNow || createFxNow(),
+                               remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+                               // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+                               temp = remaining / animation.duration || 0,
+                               percent = 1 - temp,
+                               index = 0,
+                               length = animation.tweens.length;
+
+                       for ( ; index < length ; index++ ) {
+                               animation.tweens[ index ].run( percent );
+                       }
+
+                       deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+                       if ( percent < 1 && length ) {
+                               return remaining;
+                       } else {
+                               deferred.resolveWith( elem, [ animation ] );
+                               return false;
+                       }
+               },
+               animation = deferred.promise({
+                       elem: elem,
+                       props: jQuery.extend( {}, properties ),
+                       opts: jQuery.extend( true, { specialEasing: {} }, options ),
+                       originalProperties: properties,
+                       originalOptions: options,
+                       startTime: fxNow || createFxNow(),
+                       duration: options.duration,
+                       tweens: [],
+                       createTween: function( prop, end ) {
+                               var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                                               animation.opts.specialEasing[ prop ] || animation.opts.easing );
+                               animation.tweens.push( tween );
+                               return tween;
+                       },
+                       stop: function( gotoEnd ) {
+                               var index = 0,
+                                       // if we are going to the end, we want to run all the tweens
+                                       // otherwise we skip this part
+                                       length = gotoEnd ? animation.tweens.length : 0;
+                               if ( stopped ) {
+                                       return this;
+                               }
+                               stopped = true;
+                               for ( ; index < length ; index++ ) {
+                                       animation.tweens[ index ].run( 1 );
+                               }
+
+                               // resolve when we played the last frame
+                               // otherwise, reject
+                               if ( gotoEnd ) {
+                                       deferred.resolveWith( elem, [ animation, gotoEnd ] );
+                               } else {
+                                       deferred.rejectWith( elem, [ animation, gotoEnd ] );
+                               }
+                               return this;
+                       }
+               }),
+               props = animation.props;
+
+       propFilter( props, animation.opts.specialEasing );
+
+       for ( ; index < length ; index++ ) {
+               result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+               if ( result ) {
+                       return result;
+               }
+       }
+
+       jQuery.map( props, createTween, animation );
+
+       if ( jQuery.isFunction( animation.opts.start ) ) {
+               animation.opts.start.call( elem, animation );
+       }
+
+       jQuery.fx.timer(
+               jQuery.extend( tick, {
+                       elem: elem,
+                       anim: animation,
+                       queue: animation.opts.queue
+               })
+       );
+
+       // attach callbacks from options
+       return animation.progress( animation.opts.progress )
+               .done( animation.opts.done, animation.opts.complete )
+               .fail( animation.opts.fail )
+               .always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+       var index, name, easing, value, hooks;
+
+       // camelCase, specialEasing and expand cssHook pass
+       for ( index in props ) {
+               name = jQuery.camelCase( index );
+               easing = specialEasing[ name ];
+               value = props[ index ];
+               if ( jQuery.isArray( value ) ) {
+                       easing = value[ 1 ];
+                       value = props[ index ] = value[ 0 ];
+               }
+
+               if ( index !== name ) {
+                       props[ name ] = value;
+                       delete props[ index ];
+               }
+
+               hooks = jQuery.cssHooks[ name ];
+               if ( hooks && "expand" in hooks ) {
+                       value = hooks.expand( value );
+                       delete props[ name ];
+
+                       // not quite $.extend, this wont overwrite keys already present.
+                       // also - reusing 'index' from above because we have the correct "name"
+                       for ( index in value ) {
+                               if ( !( index in props ) ) {
+                                       props[ index ] = value[ index ];
+                                       specialEasing[ index ] = easing;
+                               }
+                       }
+               } else {
+                       specialEasing[ name ] = easing;
+               }
+       }
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+       tweener: function( props, callback ) {
+               if ( jQuery.isFunction( props ) ) {
+                       callback = props;
+                       props = [ "*" ];
+               } else {
+                       props = props.split(" ");
+               }
+
+               var prop,
+                       index = 0,
+                       length = props.length;
+
+               for ( ; index < length ; index++ ) {
+                       prop = props[ index ];
+                       tweeners[ prop ] = tweeners[ prop ] || [];
+                       tweeners[ prop ].unshift( callback );
+               }
+       },
+
+       prefilter: function( callback, prepend ) {
+               if ( prepend ) {
+                       animationPrefilters.unshift( callback );
+               } else {
+                       animationPrefilters.push( callback );
+               }
+       }
+});
+
+function defaultPrefilter( elem, props, opts ) {
+       /* jshint validthis: true */
+       var prop, value, toggle, tween, hooks, oldfire,
+               anim = this,
+               orig = {},
+               style = elem.style,
+               hidden = elem.nodeType && isHidden( elem ),
+               dataShow = jQuery._data( elem, "fxshow" );
+
+       // handle queue: false promises
+       if ( !opts.queue ) {
+               hooks = jQuery._queueHooks( elem, "fx" );
+               if ( hooks.unqueued == null ) {
+                       hooks.unqueued = 0;
+                       oldfire = hooks.empty.fire;
+                       hooks.empty.fire = function() {
+                               if ( !hooks.unqueued ) {
+                                       oldfire();
+                               }
+                       };
+               }
+               hooks.unqueued++;
+
+               anim.always(function() {
+                       // doing this makes sure that the complete handler will be called
+                       // before this completes
+                       anim.always(function() {
+                               hooks.unqueued--;
+                               if ( !jQuery.queue( elem, "fx" ).length ) {
+                                       hooks.empty.fire();
+                               }
+                       });
+               });
+       }
+
+       // height/width overflow pass
+       if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+               // Make sure that nothing sneaks out
+               // Record all 3 overflow attributes because IE does not
+               // change the overflow attribute when overflowX and
+               // overflowY are set to the same value
+               opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+               // Set display property to inline-block for height/width
+               // animations on inline elements that are having width/height animated
+               if ( jQuery.css( elem, "display" ) === "inline" &&
+                               jQuery.css( elem, "float" ) === "none" ) {
+
+                       // inline-level elements accept inline-block;
+                       // block-level elements need to be inline with layout
+                       if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+                               style.display = "inline-block";
+
+                       } else {
+                               style.zoom = 1;
+                       }
+               }
+       }
+
+       if ( opts.overflow ) {
+               style.overflow = "hidden";
+               if ( !jQuery.support.shrinkWrapBlocks ) {
+                       anim.always(function() {
+                               style.overflow = opts.overflow[ 0 ];
+                               style.overflowX = opts.overflow[ 1 ];
+                               style.overflowY = opts.overflow[ 2 ];
+                       });
+               }
+       }
+
+
+       // show/hide pass
+       for ( prop in props ) {
+               value = props[ prop ];
+               if ( rfxtypes.exec( value ) ) {
+                       delete props[ prop ];
+                       toggle = toggle || value === "toggle";
+                       if ( value === ( hidden ? "hide" : "show" ) ) {
+                               continue;
+                       }
+                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+               }
+       }
+
+       if ( !jQuery.isEmptyObject( orig ) ) {
+               if ( dataShow ) {
+                       if ( "hidden" in dataShow ) {
+                               hidden = dataShow.hidden;
+                       }
+               } else {
+                       dataShow = jQuery._data( elem, "fxshow", {} );
+               }
+
+               // store state if its toggle - enables .stop().toggle() to "reverse"
+               if ( toggle ) {
+                       dataShow.hidden = !hidden;
+               }
+               if ( hidden ) {
+                       jQuery( elem ).show();
+               } else {
+                       anim.done(function() {
+                               jQuery( elem ).hide();
+                       });
+               }
+               anim.done(function() {
+                       var prop;
+                       jQuery._removeData( elem, "fxshow" );
+                       for ( prop in orig ) {
+                               jQuery.style( elem, prop, orig[ prop ] );
+                       }
+               });
+               for ( prop in orig ) {
+                       tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+                       if ( !( prop in dataShow ) ) {
+                               dataShow[ prop ] = tween.start;
+                               if ( hidden ) {
+                                       tween.end = tween.start;
+                                       tween.start = prop === "width" || prop === "height" ? 1 : 0;
+                               }
+                       }
+               }
+       }
+}
+
+function Tween( elem, options, prop, end, easing ) {
+       return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+       constructor: Tween,
+       init: function( elem, options, prop, end, easing, unit ) {
+               this.elem = elem;
+               this.prop = prop;
+               this.easing = easing || "swing";
+               this.options = options;
+               this.start = this.now = this.cur();
+               this.end = end;
+               this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+       },
+       cur: function() {
+               var hooks = Tween.propHooks[ this.prop ];
+
+               return hooks && hooks.get ?
+                       hooks.get( this ) :
+                       Tween.propHooks._default.get( this );
+       },
+       run: function( percent ) {
+               var eased,
+                       hooks = Tween.propHooks[ this.prop ];
+
+               if ( this.options.duration ) {
+                       this.pos = eased = jQuery.easing[ this.easing ](
+                               percent, this.options.duration * percent, 0, 1, this.options.duration
+                       );
+               } else {
+                       this.pos = eased = percent;
+               }
+               this.now = ( this.end - this.start ) * eased + this.start;
+
+               if ( this.options.step ) {
+                       this.options.step.call( this.elem, this.now, this );
+               }
+
+               if ( hooks && hooks.set ) {
+                       hooks.set( this );
+               } else {
+                       Tween.propHooks._default.set( this );
+               }
+               return this;
+       }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+       _default: {
+               get: function( tween ) {
+                       var result;
+
+                       if ( tween.elem[ tween.prop ] != null &&
+                               (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+                               return tween.elem[ tween.prop ];
+                       }
+
+                       // passing an empty string as a 3rd parameter to .css will automatically
+                       // attempt a parseFloat and fallback to a string if the parse fails
+                       // so, simple values such as "10px" are parsed to Float.
+                       // complex values such as "rotate(1rad)" are returned as is.
+                       result = jQuery.css( tween.elem, tween.prop, "" );
+                       // Empty strings, null, undefined and "auto" are converted to 0.
+                       return !result || result === "auto" ? 0 : result;
+               },
+               set: function( tween ) {
+                       // use step hook for back compat - use cssHook if its there - use .style if its
+                       // available and use plain properties where available
+                       if ( jQuery.fx.step[ tween.prop ] ) {
+                               jQuery.fx.step[ tween.prop ]( tween );
+                       } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+                               jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+                       } else {
+                               tween.elem[ tween.prop ] = tween.now;
+                       }
+               }
+       }
+};
+
+// Support: IE <=9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+       set: function( tween ) {
+               if ( tween.elem.nodeType && tween.elem.parentNode ) {
+                       tween.elem[ tween.prop ] = tween.now;
+               }
+       }
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+       var cssFn = jQuery.fn[ name ];
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return speed == null || typeof speed === "boolean" ?
+                       cssFn.apply( this, arguments ) :
+                       this.animate( genFx( name, true ), speed, easing, callback );
+       };
+});
+
+jQuery.fn.extend({
+       fadeTo: function( speed, to, easing, callback ) {
+
+               // show any hidden elements after setting opacity to 0
+               return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+                       // animate to the value specified
+                       .end().animate({ opacity: to }, speed, easing, callback );
+       },
+       animate: function( prop, speed, easing, callback ) {
+               var empty = jQuery.isEmptyObject( prop ),
+                       optall = jQuery.speed( speed, easing, callback ),
+                       doAnimation = function() {
+                               // Operate on a copy of prop so per-property easing won't be lost
+                               var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+                               // Empty animations, or finishing resolves immediately
+                               if ( empty || jQuery._data( this, "finish" ) ) {
+                                       anim.stop( true );
+                               }
+                       };
+                       doAnimation.finish = doAnimation;
+
+               return empty || optall.queue === false ?
+                       this.each( doAnimation ) :
+                       this.queue( optall.queue, doAnimation );
+       },
+       stop: function( type, clearQueue, gotoEnd ) {
+               var stopQueue = function( hooks ) {
+                       var stop = hooks.stop;
+                       delete hooks.stop;
+                       stop( gotoEnd );
+               };
+
+               if ( typeof type !== "string" ) {
+                       gotoEnd = clearQueue;
+                       clearQueue = type;
+                       type = undefined;
+               }
+               if ( clearQueue && type !== false ) {
+                       this.queue( type || "fx", [] );
+               }
+
+               return this.each(function() {
+                       var dequeue = true,
+                               index = type != null && type + "queueHooks",
+                               timers = jQuery.timers,
+                               data = jQuery._data( this );
+
+                       if ( index ) {
+                               if ( data[ index ] && data[ index ].stop ) {
+                                       stopQueue( data[ index ] );
+                               }
+                       } else {
+                               for ( index in data ) {
+                                       if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+                                               stopQueue( data[ index ] );
+                                       }
+                               }
+                       }
+
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+                                       timers[ index ].anim.stop( gotoEnd );
+                                       dequeue = false;
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // start the next in the queue if the last step wasn't forced
+                       // timers currently will call their complete callbacks, which will dequeue
+                       // but only if they were gotoEnd
+                       if ( dequeue || !gotoEnd ) {
+                               jQuery.dequeue( this, type );
+                       }
+               });
+       },
+       finish: function( type ) {
+               if ( type !== false ) {
+                       type = type || "fx";
+               }
+               return this.each(function() {
+                       var index,
+                               data = jQuery._data( this ),
+                               queue = data[ type + "queue" ],
+                               hooks = data[ type + "queueHooks" ],
+                               timers = jQuery.timers,
+                               length = queue ? queue.length : 0;
+
+                       // enable finishing flag on private data
+                       data.finish = true;
+
+                       // empty the queue first
+                       jQuery.queue( this, type, [] );
+
+                       if ( hooks && hooks.stop ) {
+                               hooks.stop.call( this, true );
+                       }
+
+                       // look for any active animations, and finish them
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+                                       timers[ index ].anim.stop( true );
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // look for any animations in the old queue and finish them
+                       for ( index = 0; index < length; index++ ) {
+                               if ( queue[ index ] && queue[ index ].finish ) {
+                                       queue[ index ].finish.call( this );
+                               }
+                       }
+
+                       // turn off finishing flag
+                       delete data.finish;
+               });
+       }
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+       var which,
+               attrs = { height: type },
+               i = 0;
+
+       // if we include width, step value is 1 to do all cssExpand values,
+       // if we don't include width, step value is 2 to skip over Left and Right
+       includeWidth = includeWidth? 1 : 0;
+       for( ; i < 4 ; i += 2 - includeWidth ) {
+               which = cssExpand[ i ];
+               attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+       }
+
+       if ( includeWidth ) {
+               attrs.opacity = attrs.width = type;
+       }
+
+       return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+       slideDown: genFx("show"),
+       slideUp: genFx("hide"),
+       slideToggle: genFx("toggle"),
+       fadeIn: { opacity: "show" },
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return this.animate( props, speed, easing, callback );
+       };
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+       var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+               complete: fn || !fn && easing ||
+                       jQuery.isFunction( speed ) && speed,
+               duration: speed,
+               easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+       };
+
+       opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+               opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+       // normalize opt.queue - true/undefined/null -> "fx"
+       if ( opt.queue == null || opt.queue === true ) {
+               opt.queue = "fx";
+       }
+
+       // Queueing
+       opt.old = opt.complete;
+
+       opt.complete = function() {
+               if ( jQuery.isFunction( opt.old ) ) {
+                       opt.old.call( this );
+               }
+
+               if ( opt.queue ) {
+                       jQuery.dequeue( this, opt.queue );
+               }
+       };
+
+       return opt;
+};
+
+jQuery.easing = {
+       linear: function( p ) {
+               return p;
+       },
+       swing: function( p ) {
+               return 0.5 - Math.cos( p*Math.PI ) / 2;
+       }
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+       var timer,
+               timers = jQuery.timers,
+               i = 0;
+
+       fxNow = jQuery.now();
+
+       for ( ; i < timers.length; i++ ) {
+               timer = timers[ i ];
+               // Checks the timer has not already been removed
+               if ( !timer() && timers[ i ] === timer ) {
+                       timers.splice( i--, 1 );
+               }
+       }
+
+       if ( !timers.length ) {
+               jQuery.fx.stop();
+       }
+       fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+       if ( timer() && jQuery.timers.push( timer ) ) {
+               jQuery.fx.start();
+       }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+       if ( !timerId ) {
+               timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+       }
+};
+
+jQuery.fx.stop = function() {
+       clearInterval( timerId );
+       timerId = null;
+};
+
+jQuery.fx.speeds = {
+       slow: 600,
+       fast: 200,
+       // Default speed
+       _default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.animated = function( elem ) {
+               return jQuery.grep(jQuery.timers, function( fn ) {
+                       return elem === fn.elem;
+               }).length;
+       };
+}
+jQuery.fn.offset = function( options ) {
+       if ( arguments.length ) {
+               return options === undefined ?
+                       this :
+                       this.each(function( i ) {
+                               jQuery.offset.setOffset( this, options, i );
+                       });
+       }
+
+       var docElem, win,
+               box = { top: 0, left: 0 },
+               elem = this[ 0 ],
+               doc = elem && elem.ownerDocument;
+
+       if ( !doc ) {
+               return;
+       }
+
+       docElem = doc.documentElement;
+
+       // Make sure it's not a disconnected DOM node
+       if ( !jQuery.contains( docElem, elem ) ) {
+               return box;
+       }
+
+       // If we don't have gBCR, just use 0,0 rather than error
+       // BlackBerry 5, iOS 3 (original iPhone)
+       if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+               box = elem.getBoundingClientRect();
+       }
+       win = getWindow( doc );
+       return {
+               top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
+               left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+       };
+};
+
+jQuery.offset = {
+
+       setOffset: function( elem, options, i ) {
+               var position = jQuery.css( elem, "position" );
+
+               // set position first, in-case top/left are set even on static elem
+               if ( position === "static" ) {
+                       elem.style.position = "relative";
+               }
+
+               var curElem = jQuery( elem ),
+                       curOffset = curElem.offset(),
+                       curCSSTop = jQuery.css( elem, "top" ),
+                       curCSSLeft = jQuery.css( elem, "left" ),
+                       calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+                       props = {}, curPosition = {}, curTop, curLeft;
+
+               // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+               if ( calculatePosition ) {
+                       curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
+               }
+
+               if ( jQuery.isFunction( options ) ) {
+                       options = options.call( elem, i, curOffset );
+               }
+
+               if ( options.top != null ) {
+                       props.top = ( options.top - curOffset.top ) + curTop;
+               }
+               if ( options.left != null ) {
+                       props.left = ( options.left - curOffset.left ) + curLeft;
+               }
+
+               if ( "using" in options ) {
+                       options.using.call( elem, props );
+               } else {
+                       curElem.css( props );
+               }
+       }
+};
+
+
+jQuery.fn.extend({
+
+       position: function() {
+               if ( !this[ 0 ] ) {
+                       return;
+               }
+
+               var offsetParent, offset,
+                       parentOffset = { top: 0, left: 0 },
+                       elem = this[ 0 ];
+
+               // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+               if ( jQuery.css( elem, "position" ) === "fixed" ) {
+                       // we assume that getBoundingClientRect is available when computed position is fixed
+                       offset = elem.getBoundingClientRect();
+               } else {
+                       // Get *real* offsetParent
+                       offsetParent = this.offsetParent();
+
+                       // Get correct offsets
+                       offset = this.offset();
+                       if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+                               parentOffset = offsetParent.offset();
+                       }
+
+                       // Add offsetParent borders
+                       parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+                       parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+               }
+
+               // Subtract parent offsets and element margins
+               // note: when an element has margin: auto the offsetLeft and marginLeft
+               // are the same in Safari causing offset.left to incorrectly be 0
+               return {
+                       top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+                       left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+               };
+       },
+
+       offsetParent: function() {
+               return this.map(function() {
+                       var offsetParent = this.offsetParent || docElem;
+                       while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+                               offsetParent = offsetParent.offsetParent;
+                       }
+                       return offsetParent || docElem;
+               });
+       }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+       var top = /Y/.test( prop );
+
+       jQuery.fn[ method ] = function( val ) {
+               return jQuery.access( this, function( elem, method, val ) {
+                       var win = getWindow( elem );
+
+                       if ( val === undefined ) {
+                               return win ? (prop in win) ? win[ prop ] :
+                                       win.document.documentElement[ method ] :
+                                       elem[ method ];
+                       }
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !top ? val : jQuery( win ).scrollLeft(),
+                                       top ? val : jQuery( win ).scrollTop()
+                               );
+
+                       } else {
+                               elem[ method ] = val;
+                       }
+               }, method, val, arguments.length, null );
+       };
+});
+
+function getWindow( elem ) {
+       return jQuery.isWindow( elem ) ?
+               elem :
+               elem.nodeType === 9 ?
+                       elem.defaultView || elem.parentWindow :
+                       false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+       jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+               // margin is only for outerHeight, outerWidth
+               jQuery.fn[ funcName ] = function( margin, value ) {
+                       var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+                               extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+                       return jQuery.access( this, function( elem, type, value ) {
+                               var doc;
+
+                               if ( jQuery.isWindow( elem ) ) {
+                                       // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+                                       // isn't a whole lot we can do. See pull request at this URL for discussion:
+                                       // https://github.com/jquery/jquery/pull/764
+                                       return elem.document.documentElement[ "client" + name ];
+                               }
+
+                               // Get document width or height
+                               if ( elem.nodeType === 9 ) {
+                                       doc = elem.documentElement;
+
+                                       // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+                                       // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+                                       return Math.max(
+                                               elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+                                               elem.body[ "offset" + name ], doc[ "offset" + name ],
+                                               doc[ "client" + name ]
+                                       );
+                               }
+
+                               return value === undefined ?
+                                       // Get width or height on the element, requesting but not forcing parseFloat
+                                       jQuery.css( elem, type, extra ) :
+
+                                       // Set width or height on the element
+                                       jQuery.style( elem, type, value, extra );
+                       }, type, chainable ? margin : undefined, chainable, null );
+               };
+       });
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+       return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+// })();
+if ( typeof module === "object" && module && typeof module.exports === "object" ) {
+       // Expose jQuery as module.exports in loaders that implement the Node
+       // module pattern (including browserify). Do not create the global, since
+       // the user will be storing it themselves locally, and globals are frowned
+       // upon in the Node module world.
+       module.exports = jQuery;
+} else {
+       // Otherwise expose jQuery to the global object as usual
+       window.jQuery = window.$ = jQuery;
+
+       // Register as a named AMD module, since jQuery can be concatenated with other
+       // files that may use define, but not via a proper concatenation script that
+       // understands anonymous AMD modules. A named AMD is safest and most robust
+       // way to register. Lowercase jquery is used because AMD module names are
+       // derived from file names, and jQuery is normally delivered in a lowercase
+       // file name. Do this after creating the global so that if an AMD module wants
+       // to call noConflict to hide this version of jQuery, it will work.
+       if ( typeof define === "function" && define.amd ) {
+               define( "jquery", [], function () { return jQuery; } );
+       }
+}
+
+})( window );
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644 (file)
index 0000000..b527b5a
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_0_aaaaaa_40x100.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_75_ffffff_40x100.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644 (file)
index 0000000..1b7f2e4
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_flat_75_ffffff_40x100.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_55_fbf9ee_1x400.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644 (file)
index 0000000..55faf25
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_55_fbf9ee_1x400.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_65_ffffff_1x400.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644 (file)
index 0000000..a97b928
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_65_ffffff_1x400.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_dadada_1x400.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644 (file)
index 0000000..7ef631c
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_dadada_1x400.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_e6e6e6_1x400.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644 (file)
index 0000000..5aa4a22
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_75_e6e6e6_1x400.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_95_fef1ec_1x400.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644 (file)
index 0000000..920e13b
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_glass_95_fef1ec_1x400.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644 (file)
index 0000000..4496537
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_222222_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_222222_256x240.png
new file mode 100644 (file)
index 0000000..24de795
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_222222_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_2e83ff_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_2e83ff_256x240.png
new file mode 100644 (file)
index 0000000..a2980c8
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_2e83ff_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_454545_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_454545_256x240.png
new file mode 100644 (file)
index 0000000..e7687a3
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_454545_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_888888_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_888888_256x240.png
new file mode 100644 (file)
index 0000000..a85f2c4
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_888888_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_cd0a0a_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_cd0a0a_256x240.png
new file mode 100644 (file)
index 0000000..7af13a6
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/images/ui-icons_cd0a0a_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/index.html b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/index.html
new file mode 100644 (file)
index 0000000..b878272
--- /dev/null
@@ -0,0 +1,513 @@
+<!doctype html>
+<html lang="us">
+<head>
+       <meta charset="utf-8">
+       <title>jQuery UI Example Page</title>
+       <link href="jquery-ui.css" rel="stylesheet">
+       <style>
+       body{
+               font: 62.5% "Trebuchet MS", sans-serif;
+               margin: 50px;
+       }
+       .demoHeaders {
+               margin-top: 2em;
+       }
+       #dialog-link {
+               padding: .4em 1em .4em 20px;
+               text-decoration: none;
+               position: relative;
+       }
+       #dialog-link span.ui-icon {
+               margin: 0 5px 0 0;
+               position: absolute;
+               left: .2em;
+               top: 50%;
+               margin-top: -8px;
+       }
+       #icons {
+               margin: 0;
+               padding: 0;
+       }
+       #icons li {
+               margin: 2px;
+               position: relative;
+               padding: 4px 0;
+               cursor: pointer;
+               float: left;
+               list-style: none;
+       }
+       #icons span.ui-icon {
+               float: left;
+               margin: 0 4px;
+       }
+       .fakewindowcontain .ui-widget-overlay {
+               position: absolute;
+       }
+       select {
+               width: 200px;
+       }
+       </style>
+</head>
+<body>
+
+<h1>Welcome to jQuery UI!</h1>
+
+<div class="ui-widget">
+       <p>This page demonstrates the widgets and theme you selected in Download Builder. Please make sure you are using them with a compatible jQuery version.</p>
+</div>
+
+<h1>YOUR COMPONENTS:</h1>
+
+
+<!-- Accordion -->
+<h2 class="demoHeaders">Accordion</h2>
+<div id="accordion">
+       <h3>First</h3>
+       <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
+       <h3>Second</h3>
+       <div>Phasellus mattis tincidunt nibh.</div>
+       <h3>Third</h3>
+       <div>Nam dui erat, auctor a, dignissim quis.</div>
+</div>
+
+
+
+<!-- Autocomplete -->
+<h2 class="demoHeaders">Autocomplete</h2>
+<div>
+       <input id="autocomplete" title="type &quot;a&quot;">
+</div>
+
+
+
+<!-- Button -->
+<h2 class="demoHeaders">Button</h2>
+<button id="button">A button element</button>
+<form style="margin-top: 1em;">
+       <div id="radioset">
+               <input type="radio" id="radio1" name="radio"><label for="radio1">Choice 1</label>
+               <input type="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Choice 2</label>
+               <input type="radio" id="radio3" name="radio"><label for="radio3">Choice 3</label>
+       </div>
+</form>
+
+
+
+<!-- Tabs -->
+<h2 class="demoHeaders">Tabs</h2>
+<div id="tabs">
+       <ul>
+               <li><a href="#tabs-1">First</a></li>
+               <li><a href="#tabs-2">Second</a></li>
+               <li><a href="#tabs-3">Third</a></li>
+       </ul>
+       <div id="tabs-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
+       <div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
+       <div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
+</div>
+
+
+
+<!-- Dialog NOTE: Dialog is not generated by UI in this demo so it can be visually styled in themeroller-->
+<h2 class="demoHeaders">Dialog</h2>
+<p><a href="#" id="dialog-link" class="ui-state-default ui-corner-all"><span class="ui-icon ui-icon-newwin"></span>Open Dialog</a></p>
+
+<h2 class="demoHeaders">Overlay and Shadow Classes <em>(not currently used in UI widgets)</em></h2>
+<div style="position: relative; width: 96%; height: 200px; padding:1% 2%; overflow:hidden;" class="fakewindowcontain">
+       <p>Lorem ipsum dolor sit amet,  Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
+
+       <!-- ui-dialog -->
+       <div class="ui-overlay"><div class="ui-widget-overlay"></div><div class="ui-widget-shadow ui-corner-all" style="width: 302px; height: 152px; position: absolute; left: 50px; top: 30px;"></div></div>
+       <div style="position: absolute; width: 280px; height: 130px;left: 50px; top: 30px; padding: 10px;" class="ui-widget ui-widget-content ui-corner-all">
+               <div class="ui-dialog-content ui-widget-content" style="background: none; border: 0;">
+                       <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+               </div>
+       </div>
+
+</div>
+
+<!-- ui-dialog -->
+<div id="dialog" title="Dialog Title">
+       <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+</div>
+
+
+
+<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
+<ul id="icons" class="ui-widget ui-helper-clearfix">
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-n"><span class="ui-icon ui-icon-carat-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-ne"><span class="ui-icon ui-icon-carat-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-e"><span class="ui-icon ui-icon-carat-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-se"><span class="ui-icon ui-icon-carat-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-s"><span class="ui-icon ui-icon-carat-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-sw"><span class="ui-icon ui-icon-carat-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-w"><span class="ui-icon ui-icon-carat-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-nw"><span class="ui-icon ui-icon-carat-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-n-s"><span class="ui-icon ui-icon-carat-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-e-w"><span class="ui-icon ui-icon-carat-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-sw"><span class="ui-icon ui-icon-triangle-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-w"><span class="ui-icon ui-icon-triangle-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-nw"><span class="ui-icon ui-icon-triangle-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-s"><span class="ui-icon ui-icon-arrow-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-sw"><span class="ui-icon ui-icon-arrow-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-w"><span class="ui-icon ui-icon-arrow-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-e"><span class="ui-icon ui-icon-arrowstop-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-s"><span class="ui-icon ui-icon-arrowstop-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-w"><span class="ui-icon ui-icon-arrowstop-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-w"><span class="ui-icon ui-icon-arrowthick-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-nw"><span class="ui-icon ui-icon-arrowthick-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-n-s"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-w"><span class="ui-icon ui-icon-arrowthickstop-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-w"><span class="ui-icon ui-icon-arrowreturnthick-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-n"><span class="ui-icon ui-icon-arrowreturnthick-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-w"><span class="ui-icon ui-icon-arrowrefresh-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-n"><span class="ui-icon ui-icon-arrowrefresh-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-e"><span class="ui-icon ui-icon-arrowrefresh-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-shuffle"><span class="ui-icon ui-icon-shuffle"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-transfer-e-w"><span class="ui-icon ui-icon-transfer-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-transferthick-e-w"><span class="ui-icon ui-icon-transferthick-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-mail-open"><span class="ui-icon ui-icon-mail-open"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-suitcase"><span class="ui-icon ui-icon-suitcase"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-comment"><span class="ui-icon ui-icon-comment"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-tag"><span class="ui-icon ui-icon-tag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-home"><span class="ui-icon ui-icon-home"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-flag"><span class="ui-icon ui-icon-flag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-zoomin"><span class="ui-icon ui-icon-zoomin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-zoomout"><span class="ui-icon ui-icon-zoomout"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-search"><span class="ui-icon ui-icon-search"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-plus"><span class="ui-icon ui-icon-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-minus"><span class="ui-icon ui-icon-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-clipboard"><span class="ui-icon ui-icon-clipboard"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-copy"><span class="ui-icon ui-icon-copy"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-contact"><span class="ui-icon ui-icon-contact"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-image"><span class="ui-icon ui-icon-image"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-bullet"><span class="ui-icon ui-icon-bullet"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-radio-off"><span class="ui-icon ui-icon-radio-off"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-radio-on"><span class="ui-icon ui-icon-radio-on"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pin-w"><span class="ui-icon ui-icon-pin-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-first"><span class="ui-icon ui-icon-seek-first"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-stop"><span class="ui-icon ui-icon-stop"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-eject"><span class="ui-icon ui-icon-eject"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-1"><span class="ui-icon ui-icon-battery-1"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-2"><span class="ui-icon ui-icon-battery-2"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-3"><span class="ui-icon ui-icon-battery-3"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-n"><span class="ui-icon ui-icon-circle-triangle-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-e"><span class="ui-icon ui-icon-circle-arrow-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-s"><span class="ui-icon ui-icon-circle-arrow-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-minus"><span class="ui-icon ui-icon-circlesmall-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-close"><span class="ui-icon ui-icon-circlesmall-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-plus"><span class="ui-icon ui-icon-squaresmall-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-gripsmall-diagonal-se"><span class="ui-icon ui-icon-gripsmall-diagonal-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
+</ul>
+
+
+<!-- Slider -->
+<h2 class="demoHeaders">Slider</h2>
+<div id="slider"></div>
+
+
+
+<!-- Datepicker -->
+<h2 class="demoHeaders">Datepicker</h2>
+<div id="datepicker"></div>
+
+
+
+<!-- Progressbar -->
+<h2 class="demoHeaders">Progressbar</h2>
+<div id="progressbar"></div>
+
+
+
+<!-- Progressbar -->
+<h2 class="demoHeaders">Selectmenu</h2>
+<select id="selectmenu">
+       <option>Slower</option>
+       <option>Slow</option>
+       <option selected="selected">Medium</option>
+       <option>Fast</option>
+       <option>Faster</option>
+</select>
+
+
+
+<!-- Spinner -->
+<h2 class="demoHeaders">Spinner</h2>
+<input id="spinner">
+
+
+
+<!-- Menu -->
+<h2 class="demoHeaders">Menu</h2>
+<ul style="width:100px;" id="menu">
+       <li>Item 1</li>
+       <li>Item 2</li>
+       <li>Item 3
+               <ul>
+                       <li>Item 3-1</li>
+                       <li>Item 3-2</li>
+                       <li>Item 3-3</li>
+                       <li>Item 3-4</li>
+                       <li>Item 3-5</li>
+               </ul>
+       </li>
+       <li>Item 4</li>
+       <li>Item 5</li>
+</ul>
+
+
+
+<!-- Tooltip -->
+<h2 class="demoHeaders">Tooltip</h2>
+<p id="tooltip">
+       <a href="#" title="That&apos;s what this widget is">Tooltips</a> can be attached to any element. When you hover
+the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.
+</p>
+
+
+<!-- Highlight / Error -->
+<h2 class="demoHeaders">Highlight / Error</h2>
+<div class="ui-widget">
+       <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;">
+               <p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
+               <strong>Hey!</strong> Sample ui-state-highlight style.</p>
+       </div>
+</div>
+<br>
+<div class="ui-widget">
+       <div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
+               <p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
+               <strong>Alert:</strong> Sample ui-state-error style.</p>
+       </div>
+</div>
+
+<script src="external/jquery/jquery.js"></script>
+<script src="jquery-ui.js"></script>
+<script>
+
+$( "#accordion" ).accordion();
+
+
+
+var availableTags = [
+       "ActionScript",
+       "AppleScript",
+       "Asp",
+       "BASIC",
+       "C",
+       "C++",
+       "Clojure",
+       "COBOL",
+       "ColdFusion",
+       "Erlang",
+       "Fortran",
+       "Groovy",
+       "Haskell",
+       "Java",
+       "JavaScript",
+       "Lisp",
+       "Perl",
+       "PHP",
+       "Python",
+       "Ruby",
+       "Scala",
+       "Scheme"
+];
+$( "#autocomplete" ).autocomplete({
+       source: availableTags
+});
+
+
+
+$( "#button" ).button();
+$( "#radioset" ).buttonset();
+
+
+
+$( "#tabs" ).tabs();
+
+
+
+$( "#dialog" ).dialog({
+       autoOpen: false,
+       width: 400,
+       buttons: [
+               {
+                       text: "Ok",
+                       click: function() {
+                               $( this ).dialog( "close" );
+                       }
+               },
+               {
+                       text: "Cancel",
+                       click: function() {
+                               $( this ).dialog( "close" );
+                       }
+               }
+       ]
+});
+
+// Link to open the dialog
+$( "#dialog-link" ).click(function( event ) {
+       $( "#dialog" ).dialog( "open" );
+       event.preventDefault();
+});
+
+
+
+$( "#datepicker" ).datepicker({
+       inline: true
+});
+
+
+
+$( "#slider" ).slider({
+       range: true,
+       values: [ 17, 67 ]
+});
+
+
+
+$( "#progressbar" ).progressbar({
+       value: 20
+});
+
+
+
+$( "#spinner" ).spinner();
+
+
+
+$( "#menu" ).menu();
+
+
+
+$( "#tooltip" ).tooltip();
+
+
+
+$( "#selectmenu" ).selectmenu();
+
+
+// Hover states on the static widgets
+$( "#dialog-link, #icons li" ).hover(
+       function() {
+               $( this ).addClass( "ui-state-hover" );
+       },
+       function() {
+               $( this ).removeClass( "ui-state-hover" );
+       }
+);
+</script>
+</body>
+</html>
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.css
new file mode 100644 (file)
index 0000000..f1d4964
--- /dev/null
@@ -0,0 +1,1225 @@
+/*! jQuery UI - v1.11.3 - 2015-03-03
+* http://jqueryui.com
+* Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+       display: none;
+}
+.ui-helper-hidden-accessible {
+       border: 0;
+       clip: rect(0 0 0 0);
+       height: 1px;
+       margin: -1px;
+       overflow: hidden;
+       padding: 0;
+       position: absolute;
+       width: 1px;
+}
+.ui-helper-reset {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       outline: 0;
+       line-height: 1.3;
+       text-decoration: none;
+       font-size: 100%;
+       list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+       content: "";
+       display: table;
+       border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+       clear: both;
+}
+.ui-helper-clearfix {
+       min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       left: 0;
+       position: absolute;
+       opacity: 0;
+       filter:Alpha(Opacity=0); /* support: IE8 */
+}
+
+.ui-front {
+       z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+       cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       display: block;
+       text-indent: -99999px;
+       overflow: hidden;
+       background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+       position: fixed;
+       top: 0;
+       left: 0;
+       width: 100%;
+       height: 100%;
+}
+.ui-draggable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable {
+       position: relative;
+}
+.ui-resizable-handle {
+       position: absolute;
+       font-size: 0.1px;
+       display: block;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+       display: none;
+}
+.ui-resizable-n {
+       cursor: n-resize;
+       height: 7px;
+       width: 100%;
+       top: -5px;
+       left: 0;
+}
+.ui-resizable-s {
+       cursor: s-resize;
+       height: 7px;
+       width: 100%;
+       bottom: -5px;
+       left: 0;
+}
+.ui-resizable-e {
+       cursor: e-resize;
+       width: 7px;
+       right: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-w {
+       cursor: w-resize;
+       width: 7px;
+       left: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-se {
+       cursor: se-resize;
+       width: 12px;
+       height: 12px;
+       right: 1px;
+       bottom: 1px;
+}
+.ui-resizable-sw {
+       cursor: sw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       bottom: -5px;
+}
+.ui-resizable-nw {
+       cursor: nw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       top: -5px;
+}
+.ui-resizable-ne {
+       cursor: ne-resize;
+       width: 9px;
+       height: 9px;
+       right: -5px;
+       top: -5px;
+}
+.ui-selectable {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-selectable-helper {
+       position: absolute;
+       z-index: 100;
+       border: 1px dotted black;
+}
+.ui-sortable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-accordion .ui-accordion-header {
+       display: block;
+       cursor: pointer;
+       position: relative;
+       margin: 2px 0 0 0;
+       padding: .5em .5em .5em .7em;
+       min-height: 0; /* support: IE7 */
+       font-size: 100%;
+}
+.ui-accordion .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+       position: absolute;
+       left: .5em;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+       padding: 1em 2.2em;
+       border-top: 0;
+       overflow: auto;
+}
+.ui-autocomplete {
+       position: absolute;
+       top: 0;
+       left: 0;
+       cursor: default;
+}
+.ui-button {
+       display: inline-block;
+       position: relative;
+       padding: 0;
+       line-height: normal;
+       margin-right: .1em;
+       cursor: pointer;
+       vertical-align: middle;
+       text-align: center;
+       overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+       text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+       width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+       width: 2.4em;
+}
+.ui-button-icons-only {
+       width: 3.4em;
+}
+button.ui-button-icons-only {
+       width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+       display: block;
+       line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+       padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+       padding: .4em;
+       text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+       padding-left: 2.1em;
+       padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+       padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+       position: absolute;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+       left: 50%;
+       margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+       left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+       right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+       margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+       margin-left: 0;
+       margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+       border: 0;
+       padding: 0;
+}
+.ui-datepicker {
+       width: 17em;
+       padding: .2em .2em 0;
+       display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+       position: relative;
+       padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+       position: absolute;
+       top: 2px;
+       width: 1.8em;
+       height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+       top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+       left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+       right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+       left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+       right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+       display: block;
+       position: absolute;
+       left: 50%;
+       margin-left: -8px;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+       margin: 0 2.3em;
+       line-height: 1.8em;
+       text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+       font-size: 1em;
+       margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+       width: 45%;
+}
+.ui-datepicker table {
+       width: 100%;
+       font-size: .9em;
+       border-collapse: collapse;
+       margin: 0 0 .4em;
+}
+.ui-datepicker th {
+       padding: .7em .3em;
+       text-align: center;
+       font-weight: bold;
+       border: 0;
+}
+.ui-datepicker td {
+       border: 0;
+       padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+       display: block;
+       padding: .2em;
+       text-align: right;
+       text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+       background-image: none;
+       margin: .7em 0 0 0;
+       padding: 0 .2em;
+       border-left: 0;
+       border-right: 0;
+       border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+       float: right;
+       margin: .5em .2em .4em;
+       cursor: pointer;
+       padding: .2em .6em .3em .6em;
+       width: auto;
+       overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+       float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+       width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+       float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+       width: 95%;
+       margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+       width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+       width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+       width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+       border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+       clear: left;
+}
+.ui-datepicker-row-break {
+       clear: both;
+       width: 100%;
+       font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+       direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+       right: 2px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+       left: 2px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+       right: 1px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+       left: 1px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+       clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+       float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+       float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+       border-right-width: 0;
+       border-left-width: 1px;
+}
+.ui-dialog {
+       overflow: hidden;
+       position: absolute;
+       top: 0;
+       left: 0;
+       padding: .2em;
+       outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+       padding: .4em 1em;
+       position: relative;
+}
+.ui-dialog .ui-dialog-title {
+       float: left;
+       margin: .1em 0;
+       white-space: nowrap;
+       width: 90%;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+       position: absolute;
+       right: .3em;
+       top: 50%;
+       width: 20px;
+       margin: -10px 0 0 0;
+       padding: 1px;
+       height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+       position: relative;
+       border: 0;
+       padding: .5em 1em;
+       background: none;
+       overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+       text-align: left;
+       border-width: 1px 0 0 0;
+       background-image: none;
+       margin-top: .5em;
+       padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+       float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+       margin: .5em .4em .5em 0;
+       cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+       width: 12px;
+       height: 12px;
+       right: -5px;
+       bottom: -5px;
+       background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+       cursor: move;
+}
+.ui-menu {
+       list-style: none;
+       padding: 0;
+       margin: 0;
+       display: block;
+       outline: none;
+}
+.ui-menu .ui-menu {
+       position: absolute;
+}
+.ui-menu .ui-menu-item {
+       position: relative;
+       margin: 0;
+       padding: 3px 1em 3px .4em;
+       cursor: pointer;
+       min-height: 0; /* support: IE7 */
+       /* support: IE10, see #8844 */
+       list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
+}
+.ui-menu .ui-menu-divider {
+       margin: 5px 0;
+       height: 0;
+       font-size: 0;
+       line-height: 0;
+       border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-focus,
+.ui-menu .ui-state-active {
+       margin: -1px;
+}
+
+/* icon support */
+.ui-menu-icons {
+       position: relative;
+}
+.ui-menu-icons .ui-menu-item {
+       padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: .2em;
+       margin: auto 0;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+       left: auto;
+       right: 0;
+}
+.ui-progressbar {
+       height: 2em;
+       text-align: left;
+       overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+       margin: -1px;
+       height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+       background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
+       height: 100%;
+       filter: alpha(opacity=25); /* support: IE8 */
+       opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+       background-image: none;
+}
+.ui-selectmenu-menu {
+       padding: 0;
+       margin: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+       overflow: auto;
+       /* Support: IE7 */
+       overflow-x: hidden;
+       padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+       font-size: 1em;
+       font-weight: bold;
+       line-height: 1.5;
+       padding: 2px 0.4em;
+       margin: 0.5em 0 0 0;
+       height: auto;
+       border: 0;
+}
+.ui-selectmenu-open {
+       display: block;
+}
+.ui-selectmenu-button {
+       display: inline-block;
+       overflow: hidden;
+       position: relative;
+       text-decoration: none;
+       cursor: pointer;
+}
+.ui-selectmenu-button span.ui-icon {
+       right: 0.5em;
+       left: auto;
+       margin-top: -8px;
+       position: absolute;
+       top: 50%;
+}
+.ui-selectmenu-button span.ui-selectmenu-text {
+       text-align: left;
+       padding: 0.4em 2.1em 0.4em 1em;
+       display: block;
+       line-height: 1.4;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.ui-slider {
+       position: relative;
+       text-align: left;
+}
+.ui-slider .ui-slider-handle {
+       position: absolute;
+       z-index: 2;
+       width: 1.2em;
+       height: 1.2em;
+       cursor: default;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-slider .ui-slider-range {
+       position: absolute;
+       z-index: 1;
+       font-size: .7em;
+       display: block;
+       border: 0;
+       background-position: 0 0;
+}
+
+/* support: IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+       filter: inherit;
+}
+
+.ui-slider-horizontal {
+       height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+       top: -.3em;
+       margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+       top: 0;
+       height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+       left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+       right: 0;
+}
+
+.ui-slider-vertical {
+       width: .8em;
+       height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+       left: -.3em;
+       margin-left: 0;
+       margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+       left: 0;
+       width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+       bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+       top: 0;
+}
+.ui-spinner {
+       position: relative;
+       display: inline-block;
+       overflow: hidden;
+       padding: 0;
+       vertical-align: middle;
+}
+.ui-spinner-input {
+       border: none;
+       background: none;
+       color: inherit;
+       padding: 0;
+       margin: .2em 0;
+       vertical-align: middle;
+       margin-left: .4em;
+       margin-right: 22px;
+}
+.ui-spinner-button {
+       width: 16px;
+       height: 50%;
+       font-size: .5em;
+       padding: 0;
+       margin: 0;
+       text-align: center;
+       position: absolute;
+       cursor: default;
+       display: block;
+       overflow: hidden;
+       right: 0;
+}
+/* more specificity required here to override default borders */
+.ui-spinner a.ui-spinner-button {
+       border-top: none;
+       border-bottom: none;
+       border-right: none;
+}
+/* vertically center icon */
+.ui-spinner .ui-icon {
+       position: absolute;
+       margin-top: -8px;
+       top: 50%;
+       left: 0;
+}
+.ui-spinner-up {
+       top: 0;
+}
+.ui-spinner-down {
+       bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+       /* need to fix icons sprite */
+       background-position: -65px -16px;
+}
+.ui-tabs {
+       position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+       padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+       margin: 0;
+       padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+       list-style: none;
+       float: left;
+       position: relative;
+       top: 0;
+       margin: 1px .2em 0 0;
+       border-bottom-width: 0;
+       padding: 0;
+       white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+       float: left;
+       padding: .5em 1em;
+       text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+       margin-bottom: -1px;
+       padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+       cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+       cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+       display: block;
+       border-width: 0;
+       padding: 1em 1.4em;
+       background: none;
+}
+.ui-tooltip {
+       padding: 8px;
+       position: absolute;
+       z-index: 9999;
+       max-width: 300px;
+       -webkit-box-shadow: 0 0 5px #aaa;
+       box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+       border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+       font-family: Verdana,Arial,sans-serif;
+       font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+       font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+       font-family: Verdana,Arial,sans-serif;
+       font-size: 1em;
+}
+.ui-widget-content {
+       border: 1px solid #aaaaaa;
+       background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+       color: #222222;
+}
+.ui-widget-content a {
+       color: #222222;
+}
+.ui-widget-header {
+       border: 1px solid #aaaaaa;
+       background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
+       color: #222222;
+       font-weight: bold;
+}
+.ui-widget-header a {
+       color: #222222;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+       border: 1px solid #d3d3d3;
+       background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #555555;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+       color: #555555;
+       text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+       border: 1px solid #999999;
+       background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #212121;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited {
+       color: #212121;
+       text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+       border: 1px solid #aaaaaa;
+       background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #212121;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+       color: #212121;
+       text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+       border: 1px solid #fcefa1;
+       background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
+       color: #363636;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+       color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+       border: 1px solid #cd0a0a;
+       background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
+       color: #cd0a0a;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+       color: #cd0a0a;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+       color: #cd0a0a;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+       font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+       opacity: .7;
+       filter:Alpha(Opacity=70); /* support: IE8 */
+       font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+       opacity: .35;
+       filter:Alpha(Opacity=35); /* support: IE8 */
+       background-image: none;
+}
+.ui-state-disabled .ui-icon {
+       filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       width: 16px;
+       height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+       background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-widget-header .ui-icon {
+       background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-state-default .ui-icon {
+       background-image: url("images/ui-icons_888888_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+       background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-active .ui-icon {
+       background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+       background-image: url("images/ui-icons_2e83ff_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+       background-image: url("images/ui-icons_cd0a0a_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+       border-top-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+       border-top-right-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+       border-bottom-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+       border-bottom-right-radius: 4px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+       background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+}
+.ui-widget-shadow {
+       margin: -8px 0 0 -8px;
+       padding: 8px;
+       background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+       border-radius: 8px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.js
new file mode 100644 (file)
index 0000000..583a1b2
--- /dev/null
@@ -0,0 +1,16608 @@
+/*! jQuery UI - v1.11.3 - 2015-03-01
+* http://jqueryui.com
+* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+(function( factory ) {
+       if ( typeof define === "function" && define.amd ) {
+
+               // AMD. Register as an anonymous module.
+               define([ "jquery" ], factory );
+       } else {
+
+               // Browser globals
+               factory( jQuery );
+       }
+}(function( $ ) {
+/*!
+ * jQuery UI Core 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/ui-core/
+ */
+
+
+// $.ui might exist from components with no dependencies, e.g., $.ui.position
+$.ui = $.ui || {};
+
+$.extend( $.ui, {
+       version: "1.11.3",
+
+       keyCode: {
+               BACKSPACE: 8,
+               COMMA: 188,
+               DELETE: 46,
+               DOWN: 40,
+               END: 35,
+               ENTER: 13,
+               ESCAPE: 27,
+               HOME: 36,
+               LEFT: 37,
+               PAGE_DOWN: 34,
+               PAGE_UP: 33,
+               PERIOD: 190,
+               RIGHT: 39,
+               SPACE: 32,
+               TAB: 9,
+               UP: 38
+       }
+});
+
+// plugins
+$.fn.extend({
+       scrollParent: function( includeHidden ) {
+               var position = this.css( "position" ),
+                       excludeStaticParent = position === "absolute",
+                       overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
+                       scrollParent = this.parents().filter( function() {
+                               var parent = $( this );
+                               if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+                                       return false;
+                               }
+                               return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
+                       }).eq( 0 );
+
+               return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
+       },
+
+       uniqueId: (function() {
+               var uuid = 0;
+
+               return function() {
+                       return this.each(function() {
+                               if ( !this.id ) {
+                                       this.id = "ui-id-" + ( ++uuid );
+                               }
+                       });
+               };
+       })(),
+
+       removeUniqueId: function() {
+               return this.each(function() {
+                       if ( /^ui-id-\d+$/.test( this.id ) ) {
+                               $( this ).removeAttr( "id" );
+                       }
+               });
+       }
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+       var map, mapName, img,
+               nodeName = element.nodeName.toLowerCase();
+       if ( "area" === nodeName ) {
+               map = element.parentNode;
+               mapName = map.name;
+               if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+                       return false;
+               }
+               img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
+               return !!img && visible( img );
+       }
+       return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
+               !element.disabled :
+               "a" === nodeName ?
+                       element.href || isTabIndexNotNaN :
+                       isTabIndexNotNaN) &&
+               // the element and all of its ancestors must be visible
+               visible( element );
+}
+
+function visible( element ) {
+       return $.expr.filters.visible( element ) &&
+               !$( element ).parents().addBack().filter(function() {
+                       return $.css( this, "visibility" ) === "hidden";
+               }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+       data: $.expr.createPseudo ?
+               $.expr.createPseudo(function( dataName ) {
+                       return function( elem ) {
+                               return !!$.data( elem, dataName );
+                       };
+               }) :
+               // support: jQuery <1.8
+               function( elem, i, match ) {
+                       return !!$.data( elem, match[ 3 ] );
+               },
+
+       focusable: function( element ) {
+               return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+       },
+
+       tabbable: function( element ) {
+               var tabIndex = $.attr( element, "tabindex" ),
+                       isTabIndexNaN = isNaN( tabIndex );
+               return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+       }
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+       $.each( [ "Width", "Height" ], function( i, name ) {
+               var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+                       type = name.toLowerCase(),
+                       orig = {
+                               innerWidth: $.fn.innerWidth,
+                               innerHeight: $.fn.innerHeight,
+                               outerWidth: $.fn.outerWidth,
+                               outerHeight: $.fn.outerHeight
+                       };
+
+               function reduce( elem, size, border, margin ) {
+                       $.each( side, function() {
+                               size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+                               if ( border ) {
+                                       size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+                               }
+                               if ( margin ) {
+                                       size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+                               }
+                       });
+                       return size;
+               }
+
+               $.fn[ "inner" + name ] = function( size ) {
+                       if ( size === undefined ) {
+                               return orig[ "inner" + name ].call( this );
+                       }
+
+                       return this.each(function() {
+                               $( this ).css( type, reduce( this, size ) + "px" );
+                       });
+               };
+
+               $.fn[ "outer" + name] = function( size, margin ) {
+                       if ( typeof size !== "number" ) {
+                               return orig[ "outer" + name ].call( this, size );
+                       }
+
+                       return this.each(function() {
+                               $( this).css( type, reduce( this, size, true, margin ) + "px" );
+                       });
+               };
+       });
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+       $.fn.removeData = (function( removeData ) {
+               return function( key ) {
+                       if ( arguments.length ) {
+                               return removeData.call( this, $.camelCase( key ) );
+                       } else {
+                               return removeData.call( this );
+                       }
+               };
+       })( $.fn.removeData );
+}
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.fn.extend({
+       focus: (function( orig ) {
+               return function( delay, fn ) {
+                       return typeof delay === "number" ?
+                               this.each(function() {
+                                       var elem = this;
+                                       setTimeout(function() {
+                                               $( elem ).focus();
+                                               if ( fn ) {
+                                                       fn.call( elem );
+                                               }
+                                       }, delay );
+                               }) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.focus ),
+
+       disableSelection: (function() {
+               var eventType = "onselectstart" in document.createElement( "div" ) ?
+                       "selectstart" :
+                       "mousedown";
+
+               return function() {
+                       return this.bind( eventType + ".ui-disableSelection", function( event ) {
+                               event.preventDefault();
+                       });
+               };
+       })(),
+
+       enableSelection: function() {
+               return this.unbind( ".ui-disableSelection" );
+       },
+
+       zIndex: function( zIndex ) {
+               if ( zIndex !== undefined ) {
+                       return this.css( "zIndex", zIndex );
+               }
+
+               if ( this.length ) {
+                       var elem = $( this[ 0 ] ), position, value;
+                       while ( elem.length && elem[ 0 ] !== document ) {
+                               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+                               // This makes behavior of this function consistent across browsers
+                               // WebKit always returns auto if the element is positioned
+                               position = elem.css( "position" );
+                               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                                       // IE returns 0 when zIndex is not specified
+                                       // other browsers return a string
+                                       // we ignore the case of nested elements with an explicit value of 0
+                                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                                       value = parseInt( elem.css( "zIndex" ), 10 );
+                                       if ( !isNaN( value ) && value !== 0 ) {
+                                               return value;
+                                       }
+                               }
+                               elem = elem.parent();
+                       }
+               }
+
+               return 0;
+       }
+});
+
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
+$.ui.plugin = {
+       add: function( module, option, set ) {
+               var i,
+                       proto = $.ui[ module ].prototype;
+               for ( i in set ) {
+                       proto.plugins[ i ] = proto.plugins[ i ] || [];
+                       proto.plugins[ i ].push( [ option, set[ i ] ] );
+               }
+       },
+       call: function( instance, name, args, allowDisconnected ) {
+               var i,
+                       set = instance.plugins[ name ];
+
+               if ( !set ) {
+                       return;
+               }
+
+               if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
+                       return;
+               }
+
+               for ( i = 0; i < set.length; i++ ) {
+                       if ( instance.options[ set[ i ][ 0 ] ] ) {
+                               set[ i ][ 1 ].apply( instance.element, args );
+                       }
+               }
+       }
+};
+
+
+/*!
+ * jQuery UI Widget 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/jQuery.widget/
+ */
+
+
+var widget_uuid = 0,
+       widget_slice = Array.prototype.slice;
+
+$.cleanData = (function( orig ) {
+       return function( elems ) {
+               var events, elem, i;
+               for ( i = 0; (elem = elems[i]) != null; i++ ) {
+                       try {
+
+                               // Only trigger remove when necessary to save time
+                               events = $._data( elem, "events" );
+                               if ( events && events.remove ) {
+                                       $( elem ).triggerHandler( "remove" );
+                               }
+
+                       // http://bugs.jquery.com/ticket/8235
+                       } catch ( e ) {}
+               }
+               orig( elems );
+       };
+})( $.cleanData );
+
+$.widget = function( name, base, prototype ) {
+       var fullName, existingConstructor, constructor, basePrototype,
+               // proxiedPrototype allows the provided prototype to remain unmodified
+               // so that it can be used as a mixin for multiple widgets (#8876)
+               proxiedPrototype = {},
+               namespace = name.split( "." )[ 0 ];
+
+       name = name.split( "." )[ 1 ];
+       fullName = namespace + "-" + name;
+
+       if ( !prototype ) {
+               prototype = base;
+               base = $.Widget;
+       }
+
+       // create selector for plugin
+       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+               return !!$.data( elem, fullName );
+       };
+
+       $[ namespace ] = $[ namespace ] || {};
+       existingConstructor = $[ namespace ][ name ];
+       constructor = $[ namespace ][ name ] = function( options, element ) {
+               // allow instantiation without "new" keyword
+               if ( !this._createWidget ) {
+                       return new constructor( options, element );
+               }
+
+               // allow instantiation without initializing for simple inheritance
+               // must use "new" keyword (the code above always passes args)
+               if ( arguments.length ) {
+                       this._createWidget( options, element );
+               }
+       };
+       // extend with the existing constructor to carry over any static properties
+       $.extend( constructor, existingConstructor, {
+               version: prototype.version,
+               // copy the object used to create the prototype in case we need to
+               // redefine the widget later
+               _proto: $.extend( {}, prototype ),
+               // track widgets that inherit from this widget in case this widget is
+               // redefined after a widget inherits from it
+               _childConstructors: []
+       });
+
+       basePrototype = new base();
+       // we need to make the options hash a property directly on the new instance
+       // otherwise we'll modify the options hash on the prototype that we're
+       // inheriting from
+       basePrototype.options = $.widget.extend( {}, basePrototype.options );
+       $.each( prototype, function( prop, value ) {
+               if ( !$.isFunction( value ) ) {
+                       proxiedPrototype[ prop ] = value;
+                       return;
+               }
+               proxiedPrototype[ prop ] = (function() {
+                       var _super = function() {
+                                       return base.prototype[ prop ].apply( this, arguments );
+                               },
+                               _superApply = function( args ) {
+                                       return base.prototype[ prop ].apply( this, args );
+                               };
+                       return function() {
+                               var __super = this._super,
+                                       __superApply = this._superApply,
+                                       returnValue;
+
+                               this._super = _super;
+                               this._superApply = _superApply;
+
+                               returnValue = value.apply( this, arguments );
+
+                               this._super = __super;
+                               this._superApply = __superApply;
+
+                               return returnValue;
+                       };
+               })();
+       });
+       constructor.prototype = $.widget.extend( basePrototype, {
+               // TODO: remove support for widgetEventPrefix
+               // always use the name + a colon as the prefix, e.g., draggable:start
+               // don't prefix for widgets that aren't DOM-based
+               widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
+       }, proxiedPrototype, {
+               constructor: constructor,
+               namespace: namespace,
+               widgetName: name,
+               widgetFullName: fullName
+       });
+
+       // If this widget is being redefined then we need to find all widgets that
+       // are inheriting from it and redefine all of them so that they inherit from
+       // the new version of this widget. We're essentially trying to replace one
+       // level in the prototype chain.
+       if ( existingConstructor ) {
+               $.each( existingConstructor._childConstructors, function( i, child ) {
+                       var childPrototype = child.prototype;
+
+                       // redefine the child widget using the same prototype that was
+                       // originally used, but inherit from the new version of the base
+                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+               });
+               // remove the list of existing child constructors from the old constructor
+               // so the old child constructors can be garbage collected
+               delete existingConstructor._childConstructors;
+       } else {
+               base._childConstructors.push( constructor );
+       }
+
+       $.widget.bridge( name, constructor );
+
+       return constructor;
+};
+
+$.widget.extend = function( target ) {
+       var input = widget_slice.call( arguments, 1 ),
+               inputIndex = 0,
+               inputLength = input.length,
+               key,
+               value;
+       for ( ; inputIndex < inputLength; inputIndex++ ) {
+               for ( key in input[ inputIndex ] ) {
+                       value = input[ inputIndex ][ key ];
+                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+                               // Clone objects
+                               if ( $.isPlainObject( value ) ) {
+                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
+                                               $.widget.extend( {}, target[ key ], value ) :
+                                               // Don't extend strings, arrays, etc. with objects
+                                               $.widget.extend( {}, value );
+                               // Copy everything else by reference
+                               } else {
+                                       target[ key ] = value;
+                               }
+                       }
+               }
+       }
+       return target;
+};
+
+$.widget.bridge = function( name, object ) {
+       var fullName = object.prototype.widgetFullName || name;
+       $.fn[ name ] = function( options ) {
+               var isMethodCall = typeof options === "string",
+                       args = widget_slice.call( arguments, 1 ),
+                       returnValue = this;
+
+               if ( isMethodCall ) {
+                       this.each(function() {
+                               var methodValue,
+                                       instance = $.data( this, fullName );
+                               if ( options === "instance" ) {
+                                       returnValue = instance;
+                                       return false;
+                               }
+                               if ( !instance ) {
+                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
+                                               "attempted to call method '" + options + "'" );
+                               }
+                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+                               }
+                               methodValue = instance[ options ].apply( instance, args );
+                               if ( methodValue !== instance && methodValue !== undefined ) {
+                                       returnValue = methodValue && methodValue.jquery ?
+                                               returnValue.pushStack( methodValue.get() ) :
+                                               methodValue;
+                                       return false;
+                               }
+                       });
+               } else {
+
+                       // Allow multiple hashes to be passed on init
+                       if ( args.length ) {
+                               options = $.widget.extend.apply( null, [ options ].concat(args) );
+                       }
+
+                       this.each(function() {
+                               var instance = $.data( this, fullName );
+                               if ( instance ) {
+                                       instance.option( options || {} );
+                                       if ( instance._init ) {
+                                               instance._init();
+                                       }
+                               } else {
+                                       $.data( this, fullName, new object( options, this ) );
+                               }
+                       });
+               }
+
+               return returnValue;
+       };
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+       widgetName: "widget",
+       widgetEventPrefix: "",
+       defaultElement: "<div>",
+       options: {
+               disabled: false,
+
+               // callbacks
+               create: null
+       },
+       _createWidget: function( options, element ) {
+               element = $( element || this.defaultElement || this )[ 0 ];
+               this.element = $( element );
+               this.uuid = widget_uuid++;
+               this.eventNamespace = "." + this.widgetName + this.uuid;
+
+               this.bindings = $();
+               this.hoverable = $();
+               this.focusable = $();
+
+               if ( element !== this ) {
+                       $.data( element, this.widgetFullName, this );
+                       this._on( true, this.element, {
+                               remove: function( event ) {
+                                       if ( event.target === element ) {
+                                               this.destroy();
+                                       }
+                               }
+                       });
+                       this.document = $( element.style ?
+                               // element within the document
+                               element.ownerDocument :
+                               // element is window or document
+                               element.document || element );
+                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+               }
+
+               this.options = $.widget.extend( {},
+                       this.options,
+                       this._getCreateOptions(),
+                       options );
+
+               this._create();
+               this._trigger( "create", null, this._getCreateEventData() );
+               this._init();
+       },
+       _getCreateOptions: $.noop,
+       _getCreateEventData: $.noop,
+       _create: $.noop,
+       _init: $.noop,
+
+       destroy: function() {
+               this._destroy();
+               // we can probably remove the unbind calls in 2.0
+               // all event bindings should go through this._on()
+               this.element
+                       .unbind( this.eventNamespace )
+                       .removeData( this.widgetFullName )
+                       // support: jquery <1.6.3
+                       // http://bugs.jquery.com/ticket/9413
+                       .removeData( $.camelCase( this.widgetFullName ) );
+               this.widget()
+                       .unbind( this.eventNamespace )
+                       .removeAttr( "aria-disabled" )
+                       .removeClass(
+                               this.widgetFullName + "-disabled " +
+                               "ui-state-disabled" );
+
+               // clean up events and states
+               this.bindings.unbind( this.eventNamespace );
+               this.hoverable.removeClass( "ui-state-hover" );
+               this.focusable.removeClass( "ui-state-focus" );
+       },
+       _destroy: $.noop,
+
+       widget: function() {
+               return this.element;
+       },
+
+       option: function( key, value ) {
+               var options = key,
+                       parts,
+                       curOption,
+                       i;
+
+               if ( arguments.length === 0 ) {
+                       // don't return a reference to the internal hash
+                       return $.widget.extend( {}, this.options );
+               }
+
+               if ( typeof key === "string" ) {
+                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+                       options = {};
+                       parts = key.split( "." );
+                       key = parts.shift();
+                       if ( parts.length ) {
+                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+                               for ( i = 0; i < parts.length - 1; i++ ) {
+                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+                                       curOption = curOption[ parts[ i ] ];
+                               }
+                               key = parts.pop();
+                               if ( arguments.length === 1 ) {
+                                       return curOption[ key ] === undefined ? null : curOption[ key ];
+                               }
+                               curOption[ key ] = value;
+                       } else {
+                               if ( arguments.length === 1 ) {
+                                       return this.options[ key ] === undefined ? null : this.options[ key ];
+                               }
+                               options[ key ] = value;
+                       }
+               }
+
+               this._setOptions( options );
+
+               return this;
+       },
+       _setOptions: function( options ) {
+               var key;
+
+               for ( key in options ) {
+                       this._setOption( key, options[ key ] );
+               }
+
+               return this;
+       },
+       _setOption: function( key, value ) {
+               this.options[ key ] = value;
+
+               if ( key === "disabled" ) {
+                       this.widget()
+                               .toggleClass( this.widgetFullName + "-disabled", !!value );
+
+                       // If the widget is becoming disabled, then nothing is interactive
+                       if ( value ) {
+                               this.hoverable.removeClass( "ui-state-hover" );
+                               this.focusable.removeClass( "ui-state-focus" );
+                       }
+               }
+
+               return this;
+       },
+
+       enable: function() {
+               return this._setOptions({ disabled: false });
+       },
+       disable: function() {
+               return this._setOptions({ disabled: true });
+       },
+
+       _on: function( suppressDisabledCheck, element, handlers ) {
+               var delegateElement,
+                       instance = this;
+
+               // no suppressDisabledCheck flag, shuffle arguments
+               if ( typeof suppressDisabledCheck !== "boolean" ) {
+                       handlers = element;
+                       element = suppressDisabledCheck;
+                       suppressDisabledCheck = false;
+               }
+
+               // no element argument, shuffle and use this.element
+               if ( !handlers ) {
+                       handlers = element;
+                       element = this.element;
+                       delegateElement = this.widget();
+               } else {
+                       element = delegateElement = $( element );
+                       this.bindings = this.bindings.add( element );
+               }
+
+               $.each( handlers, function( event, handler ) {
+                       function handlerProxy() {
+                               // allow widgets to customize the disabled handling
+                               // - disabled as an array instead of boolean
+                               // - disabled class as method for disabling individual parts
+                               if ( !suppressDisabledCheck &&
+                                               ( instance.options.disabled === true ||
+                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
+                                       return;
+                               }
+                               return ( typeof handler === "string" ? instance[ handler ] : handler )
+                                       .apply( instance, arguments );
+                       }
+
+                       // copy the guid so direct unbinding works
+                       if ( typeof handler !== "string" ) {
+                               handlerProxy.guid = handler.guid =
+                                       handler.guid || handlerProxy.guid || $.guid++;
+                       }
+
+                       var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
+                               eventName = match[1] + instance.eventNamespace,
+                               selector = match[2];
+                       if ( selector ) {
+                               delegateElement.delegate( selector, eventName, handlerProxy );
+                       } else {
+                               element.bind( eventName, handlerProxy );
+                       }
+               });
+       },
+
+       _off: function( element, eventName ) {
+               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
+                       this.eventNamespace;
+               element.unbind( eventName ).undelegate( eventName );
+
+               // Clear the stack to avoid memory leaks (#10056)
+               this.bindings = $( this.bindings.not( element ).get() );
+               this.focusable = $( this.focusable.not( element ).get() );
+               this.hoverable = $( this.hoverable.not( element ).get() );
+       },
+
+       _delay: function( handler, delay ) {
+               function handlerProxy() {
+                       return ( typeof handler === "string" ? instance[ handler ] : handler )
+                               .apply( instance, arguments );
+               }
+               var instance = this;
+               return setTimeout( handlerProxy, delay || 0 );
+       },
+
+       _hoverable: function( element ) {
+               this.hoverable = this.hoverable.add( element );
+               this._on( element, {
+                       mouseenter: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-hover" );
+                       },
+                       mouseleave: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-hover" );
+                       }
+               });
+       },
+
+       _focusable: function( element ) {
+               this.focusable = this.focusable.add( element );
+               this._on( element, {
+                       focusin: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-focus" );
+                       },
+                       focusout: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-focus" );
+                       }
+               });
+       },
+
+       _trigger: function( type, event, data ) {
+               var prop, orig,
+                       callback = this.options[ type ];
+
+               data = data || {};
+               event = $.Event( event );
+               event.type = ( type === this.widgetEventPrefix ?
+                       type :
+                       this.widgetEventPrefix + type ).toLowerCase();
+               // the original event may come from any element
+               // so we need to reset the target on the new event
+               event.target = this.element[ 0 ];
+
+               // copy original event properties over to the new event
+               orig = event.originalEvent;
+               if ( orig ) {
+                       for ( prop in orig ) {
+                               if ( !( prop in event ) ) {
+                                       event[ prop ] = orig[ prop ];
+                               }
+                       }
+               }
+
+               this.element.trigger( event, data );
+               return !( $.isFunction( callback ) &&
+                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+                       event.isDefaultPrevented() );
+       }
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+               if ( typeof options === "string" ) {
+                       options = { effect: options };
+               }
+               var hasOptions,
+                       effectName = !options ?
+                               method :
+                               options === true || typeof options === "number" ?
+                                       defaultEffect :
+                                       options.effect || defaultEffect;
+               options = options || {};
+               if ( typeof options === "number" ) {
+                       options = { duration: options };
+               }
+               hasOptions = !$.isEmptyObject( options );
+               options.complete = callback;
+               if ( options.delay ) {
+                       element.delay( options.delay );
+               }
+               if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+                       element[ method ]( options );
+               } else if ( effectName !== method && element[ effectName ] ) {
+                       element[ effectName ]( options.duration, options.easing, callback );
+               } else {
+                       element.queue(function( next ) {
+                               $( this )[ method ]();
+                               if ( callback ) {
+                                       callback.call( element[ 0 ] );
+                               }
+                               next();
+                       });
+               }
+       };
+});
+
+var widget = $.widget;
+
+
+/*!
+ * jQuery UI Mouse 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/mouse/
+ */
+
+
+var mouseHandled = false;
+$( document ).mouseup( function() {
+       mouseHandled = false;
+});
+
+var mouse = $.widget("ui.mouse", {
+       version: "1.11.3",
+       options: {
+               cancel: "input,textarea,button,select,option",
+               distance: 1,
+               delay: 0
+       },
+       _mouseInit: function() {
+               var that = this;
+
+               this.element
+                       .bind("mousedown." + this.widgetName, function(event) {
+                               return that._mouseDown(event);
+                       })
+                       .bind("click." + this.widgetName, function(event) {
+                               if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
+                                       $.removeData(event.target, that.widgetName + ".preventClickEvent");
+                                       event.stopImmediatePropagation();
+                                       return false;
+                               }
+                       });
+
+               this.started = false;
+       },
+
+       // TODO: make sure destroying one instance of mouse doesn't mess with
+       // other instances of mouse
+       _mouseDestroy: function() {
+               this.element.unbind("." + this.widgetName);
+               if ( this._mouseMoveDelegate ) {
+                       this.document
+                               .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
+                               .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
+               }
+       },
+
+       _mouseDown: function(event) {
+               // don't let more than one widget handle mouseStart
+               if ( mouseHandled ) {
+                       return;
+               }
+
+               this._mouseMoved = false;
+
+               // we may have missed mouseup (out of window)
+               (this._mouseStarted && this._mouseUp(event));
+
+               this._mouseDownEvent = event;
+
+               var that = this,
+                       btnIsLeft = (event.which === 1),
+                       // event.target.nodeName works around a bug in IE 8 with
+                       // disabled inputs (#7620)
+                       elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+                       return true;
+               }
+
+               this.mouseDelayMet = !this.options.delay;
+               if (!this.mouseDelayMet) {
+                       this._mouseDelayTimer = setTimeout(function() {
+                               that.mouseDelayMet = true;
+                       }, this.options.delay);
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted = (this._mouseStart(event) !== false);
+                       if (!this._mouseStarted) {
+                               event.preventDefault();
+                               return true;
+                       }
+               }
+
+               // Click event may never have fired (Gecko & Opera)
+               if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
+                       $.removeData(event.target, this.widgetName + ".preventClickEvent");
+               }
+
+               // these delegates are required to keep context
+               this._mouseMoveDelegate = function(event) {
+                       return that._mouseMove(event);
+               };
+               this._mouseUpDelegate = function(event) {
+                       return that._mouseUp(event);
+               };
+
+               this.document
+                       .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+                       .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+               event.preventDefault();
+
+               mouseHandled = true;
+               return true;
+       },
+
+       _mouseMove: function(event) {
+               // Only check for mouseups outside the document if you've moved inside the document
+               // at least once. This prevents the firing of mouseup in the case of IE<9, which will
+               // fire a mousemove event if content is placed under the cursor. See #7778
+               // Support: IE <9
+               if ( this._mouseMoved ) {
+                       // IE mouseup check - mouseup happened when mouse was out of window
+                       if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
+                               return this._mouseUp(event);
+
+                       // Iframe mouseup check - mouseup occurred in another document
+                       } else if ( !event.which ) {
+                               return this._mouseUp( event );
+                       }
+               }
+
+               if ( event.which || event.button ) {
+                       this._mouseMoved = true;
+               }
+
+               if (this._mouseStarted) {
+                       this._mouseDrag(event);
+                       return event.preventDefault();
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted =
+                               (this._mouseStart(this._mouseDownEvent, event) !== false);
+                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+               }
+
+               return !this._mouseStarted;
+       },
+
+       _mouseUp: function(event) {
+               this.document
+                       .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+                       .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+               if (this._mouseStarted) {
+                       this._mouseStarted = false;
+
+                       if (event.target === this._mouseDownEvent.target) {
+                               $.data(event.target, this.widgetName + ".preventClickEvent", true);
+                       }
+
+                       this._mouseStop(event);
+               }
+
+               mouseHandled = false;
+               return false;
+       },
+
+       _mouseDistanceMet: function(event) {
+               return (Math.max(
+                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
+                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
+                       ) >= this.options.distance
+               );
+       },
+
+       _mouseDelayMet: function(/* event */) {
+               return this.mouseDelayMet;
+       },
+
+       // These are placeholder methods, to be overriden by extending plugin
+       _mouseStart: function(/* event */) {},
+       _mouseDrag: function(/* event */) {},
+       _mouseStop: function(/* event */) {},
+       _mouseCapture: function(/* event */) { return true; }
+});
+
+
+/*!
+ * jQuery UI Position 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/position/
+ */
+
+(function() {
+
+$.ui = $.ui || {};
+
+var cachedScrollbarWidth, supportsOffsetFractions,
+       max = Math.max,
+       abs = Math.abs,
+       round = Math.round,
+       rhorizontal = /left|center|right/,
+       rvertical = /top|center|bottom/,
+       roffset = /[\+\-]\d+(\.[\d]+)?%?/,
+       rposition = /^\w+/,
+       rpercent = /%$/,
+       _position = $.fn.position;
+
+function getOffsets( offsets, width, height ) {
+       return [
+               parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
+               parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
+       ];
+}
+
+function parseCss( element, property ) {
+       return parseInt( $.css( element, property ), 10 ) || 0;
+}
+
+function getDimensions( elem ) {
+       var raw = elem[0];
+       if ( raw.nodeType === 9 ) {
+               return {
+                       width: elem.width(),
+                       height: elem.height(),
+                       offset: { top: 0, left: 0 }
+               };
+       }
+       if ( $.isWindow( raw ) ) {
+               return {
+                       width: elem.width(),
+                       height: elem.height(),
+                       offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
+               };
+       }
+       if ( raw.preventDefault ) {
+               return {
+                       width: 0,
+                       height: 0,
+                       offset: { top: raw.pageY, left: raw.pageX }
+               };
+       }
+       return {
+               width: elem.outerWidth(),
+               height: elem.outerHeight(),
+               offset: elem.offset()
+       };
+}
+
+$.position = {
+       scrollbarWidth: function() {
+               if ( cachedScrollbarWidth !== undefined ) {
+                       return cachedScrollbarWidth;
+               }
+               var w1, w2,
+                       div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
+                       innerDiv = div.children()[0];
+
+               $( "body" ).append( div );
+               w1 = innerDiv.offsetWidth;
+               div.css( "overflow", "scroll" );
+
+               w2 = innerDiv.offsetWidth;
+
+               if ( w1 === w2 ) {
+                       w2 = div[0].clientWidth;
+               }
+
+               div.remove();
+
+               return (cachedScrollbarWidth = w1 - w2);
+       },
+       getScrollInfo: function( within ) {
+               var overflowX = within.isWindow || within.isDocument ? "" :
+                               within.element.css( "overflow-x" ),
+                       overflowY = within.isWindow || within.isDocument ? "" :
+                               within.element.css( "overflow-y" ),
+                       hasOverflowX = overflowX === "scroll" ||
+                               ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
+                       hasOverflowY = overflowY === "scroll" ||
+                               ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
+               return {
+                       width: hasOverflowY ? $.position.scrollbarWidth() : 0,
+                       height: hasOverflowX ? $.position.scrollbarWidth() : 0
+               };
+       },
+       getWithinInfo: function( element ) {
+               var withinElement = $( element || window ),
+                       isWindow = $.isWindow( withinElement[0] ),
+                       isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
+               return {
+                       element: withinElement,
+                       isWindow: isWindow,
+                       isDocument: isDocument,
+                       offset: withinElement.offset() || { left: 0, top: 0 },
+                       scrollLeft: withinElement.scrollLeft(),
+                       scrollTop: withinElement.scrollTop(),
+
+                       // support: jQuery 1.6.x
+                       // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
+                       width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
+                       height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
+               };
+       }
+};
+
+$.fn.position = function( options ) {
+       if ( !options || !options.of ) {
+               return _position.apply( this, arguments );
+       }
+
+       // make a copy, we don't want to modify arguments
+       options = $.extend( {}, options );
+
+       var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
+               target = $( options.of ),
+               within = $.position.getWithinInfo( options.within ),
+               scrollInfo = $.position.getScrollInfo( within ),
+               collision = ( options.collision || "flip" ).split( " " ),
+               offsets = {};
+
+       dimensions = getDimensions( target );
+       if ( target[0].preventDefault ) {
+               // force left top to allow flipping
+               options.at = "left top";
+       }
+       targetWidth = dimensions.width;
+       targetHeight = dimensions.height;
+       targetOffset = dimensions.offset;
+       // clone to reuse original targetOffset later
+       basePosition = $.extend( {}, targetOffset );
+
+       // force my and at to have valid horizontal and vertical positions
+       // if a value is missing or invalid, it will be converted to center
+       $.each( [ "my", "at" ], function() {
+               var pos = ( options[ this ] || "" ).split( " " ),
+                       horizontalOffset,
+                       verticalOffset;
+
+               if ( pos.length === 1) {
+                       pos = rhorizontal.test( pos[ 0 ] ) ?
+                               pos.concat( [ "center" ] ) :
+                               rvertical.test( pos[ 0 ] ) ?
+                                       [ "center" ].concat( pos ) :
+                                       [ "center", "center" ];
+               }
+               pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
+               pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
+
+               // calculate offsets
+               horizontalOffset = roffset.exec( pos[ 0 ] );
+               verticalOffset = roffset.exec( pos[ 1 ] );
+               offsets[ this ] = [
+                       horizontalOffset ? horizontalOffset[ 0 ] : 0,
+                       verticalOffset ? verticalOffset[ 0 ] : 0
+               ];
+
+               // reduce to just the positions without the offsets
+               options[ this ] = [
+                       rposition.exec( pos[ 0 ] )[ 0 ],
+                       rposition.exec( pos[ 1 ] )[ 0 ]
+               ];
+       });
+
+       // normalize collision option
+       if ( collision.length === 1 ) {
+               collision[ 1 ] = collision[ 0 ];
+       }
+
+       if ( options.at[ 0 ] === "right" ) {
+               basePosition.left += targetWidth;
+       } else if ( options.at[ 0 ] === "center" ) {
+               basePosition.left += targetWidth / 2;
+       }
+
+       if ( options.at[ 1 ] === "bottom" ) {
+               basePosition.top += targetHeight;
+       } else if ( options.at[ 1 ] === "center" ) {
+               basePosition.top += targetHeight / 2;
+       }
+
+       atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
+       basePosition.left += atOffset[ 0 ];
+       basePosition.top += atOffset[ 1 ];
+
+       return this.each(function() {
+               var collisionPosition, using,
+                       elem = $( this ),
+                       elemWidth = elem.outerWidth(),
+                       elemHeight = elem.outerHeight(),
+                       marginLeft = parseCss( this, "marginLeft" ),
+                       marginTop = parseCss( this, "marginTop" ),
+                       collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
+                       collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
+                       position = $.extend( {}, basePosition ),
+                       myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
+
+               if ( options.my[ 0 ] === "right" ) {
+                       position.left -= elemWidth;
+               } else if ( options.my[ 0 ] === "center" ) {
+                       position.left -= elemWidth / 2;
+               }
+
+               if ( options.my[ 1 ] === "bottom" ) {
+                       position.top -= elemHeight;
+               } else if ( options.my[ 1 ] === "center" ) {
+                       position.top -= elemHeight / 2;
+               }
+
+               position.left += myOffset[ 0 ];
+               position.top += myOffset[ 1 ];
+
+               // if the browser doesn't support fractions, then round for consistent results
+               if ( !supportsOffsetFractions ) {
+                       position.left = round( position.left );
+                       position.top = round( position.top );
+               }
+
+               collisionPosition = {
+                       marginLeft: marginLeft,
+                       marginTop: marginTop
+               };
+
+               $.each( [ "left", "top" ], function( i, dir ) {
+                       if ( $.ui.position[ collision[ i ] ] ) {
+                               $.ui.position[ collision[ i ] ][ dir ]( position, {
+                                       targetWidth: targetWidth,
+                                       targetHeight: targetHeight,
+                                       elemWidth: elemWidth,
+                                       elemHeight: elemHeight,
+                                       collisionPosition: collisionPosition,
+                                       collisionWidth: collisionWidth,
+                                       collisionHeight: collisionHeight,
+                                       offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
+                                       my: options.my,
+                                       at: options.at,
+                                       within: within,
+                                       elem: elem
+                               });
+                       }
+               });
+
+               if ( options.using ) {
+                       // adds feedback as second argument to using callback, if present
+                       using = function( props ) {
+                               var left = targetOffset.left - position.left,
+                                       right = left + targetWidth - elemWidth,
+                                       top = targetOffset.top - position.top,
+                                       bottom = top + targetHeight - elemHeight,
+                                       feedback = {
+                                               target: {
+                                                       element: target,
+                                                       left: targetOffset.left,
+                                                       top: targetOffset.top,
+                                                       width: targetWidth,
+                                                       height: targetHeight
+                                               },
+                                               element: {
+                                                       element: elem,
+                                                       left: position.left,
+                                                       top: position.top,
+                                                       width: elemWidth,
+                                                       height: elemHeight
+                                               },
+                                               horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
+                                               vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
+                                       };
+                               if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
+                                       feedback.horizontal = "center";
+                               }
+                               if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
+                                       feedback.vertical = "middle";
+                               }
+                               if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
+                                       feedback.important = "horizontal";
+                               } else {
+                                       feedback.important = "vertical";
+                               }
+                               options.using.call( this, props, feedback );
+                       };
+               }
+
+               elem.offset( $.extend( position, { using: using } ) );
+       });
+};
+
+$.ui.position = {
+       fit: {
+               left: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
+                               outerWidth = within.width,
+                               collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+                               overLeft = withinOffset - collisionPosLeft,
+                               overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
+                               newOverRight;
+
+                       // element is wider than within
+                       if ( data.collisionWidth > outerWidth ) {
+                               // element is initially over the left side of within
+                               if ( overLeft > 0 && overRight <= 0 ) {
+                                       newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
+                                       position.left += overLeft - newOverRight;
+                               // element is initially over right side of within
+                               } else if ( overRight > 0 && overLeft <= 0 ) {
+                                       position.left = withinOffset;
+                               // element is initially over both left and right sides of within
+                               } else {
+                                       if ( overLeft > overRight ) {
+                                               position.left = withinOffset + outerWidth - data.collisionWidth;
+                                       } else {
+                                               position.left = withinOffset;
+                                       }
+                               }
+                       // too far left -> align with left edge
+                       } else if ( overLeft > 0 ) {
+                               position.left += overLeft;
+                       // too far right -> align with right edge
+                       } else if ( overRight > 0 ) {
+                               position.left -= overRight;
+                       // adjust based on position and margin
+                       } else {
+                               position.left = max( position.left - collisionPosLeft, position.left );
+                       }
+               },
+               top: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
+                               outerHeight = data.within.height,
+                               collisionPosTop = position.top - data.collisionPosition.marginTop,
+                               overTop = withinOffset - collisionPosTop,
+                               overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
+                               newOverBottom;
+
+                       // element is taller than within
+                       if ( data.collisionHeight > outerHeight ) {
+                               // element is initially over the top of within
+                               if ( overTop > 0 && overBottom <= 0 ) {
+                                       newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
+                                       position.top += overTop - newOverBottom;
+                               // element is initially over bottom of within
+                               } else if ( overBottom > 0 && overTop <= 0 ) {
+                                       position.top = withinOffset;
+                               // element is initially over both top and bottom of within
+                               } else {
+                                       if ( overTop > overBottom ) {
+                                               position.top = withinOffset + outerHeight - data.collisionHeight;
+                                       } else {
+                                               position.top = withinOffset;
+                                       }
+                               }
+                       // too far up -> align with top
+                       } else if ( overTop > 0 ) {
+                               position.top += overTop;
+                       // too far down -> align with bottom edge
+                       } else if ( overBottom > 0 ) {
+                               position.top -= overBottom;
+                       // adjust based on position and margin
+                       } else {
+                               position.top = max( position.top - collisionPosTop, position.top );
+                       }
+               }
+       },
+       flip: {
+               left: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.offset.left + within.scrollLeft,
+                               outerWidth = within.width,
+                               offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
+                               collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+                               overLeft = collisionPosLeft - offsetLeft,
+                               overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
+                               myOffset = data.my[ 0 ] === "left" ?
+                                       -data.elemWidth :
+                                       data.my[ 0 ] === "right" ?
+                                               data.elemWidth :
+                                               0,
+                               atOffset = data.at[ 0 ] === "left" ?
+                                       data.targetWidth :
+                                       data.at[ 0 ] === "right" ?
+                                               -data.targetWidth :
+                                               0,
+                               offset = -2 * data.offset[ 0 ],
+                               newOverRight,
+                               newOverLeft;
+
+                       if ( overLeft < 0 ) {
+                               newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
+                               if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
+                                       position.left += myOffset + atOffset + offset;
+                               }
+                       } else if ( overRight > 0 ) {
+                               newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
+                               if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
+                                       position.left += myOffset + atOffset + offset;
+                               }
+                       }
+               },
+               top: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.offset.top + within.scrollTop,
+                               outerHeight = within.height,
+                               offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
+                               collisionPosTop = position.top - data.collisionPosition.marginTop,
+                               overTop = collisionPosTop - offsetTop,
+                               overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
+                               top = data.my[ 1 ] === "top",
+                               myOffset = top ?
+                                       -data.elemHeight :
+                                       data.my[ 1 ] === "bottom" ?
+                                               data.elemHeight :
+                                               0,
+                               atOffset = data.at[ 1 ] === "top" ?
+                                       data.targetHeight :
+                                       data.at[ 1 ] === "bottom" ?
+                                               -data.targetHeight :
+                                               0,
+                               offset = -2 * data.offset[ 1 ],
+                               newOverTop,
+                               newOverBottom;
+                       if ( overTop < 0 ) {
+                               newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
+                               if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
+                                       position.top += myOffset + atOffset + offset;
+                               }
+                       } else if ( overBottom > 0 ) {
+                               newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
+                               if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
+                                       position.top += myOffset + atOffset + offset;
+                               }
+                       }
+               }
+       },
+       flipfit: {
+               left: function() {
+                       $.ui.position.flip.left.apply( this, arguments );
+                       $.ui.position.fit.left.apply( this, arguments );
+               },
+               top: function() {
+                       $.ui.position.flip.top.apply( this, arguments );
+                       $.ui.position.fit.top.apply( this, arguments );
+               }
+       }
+};
+
+// fraction support test
+(function() {
+       var testElement, testElementParent, testElementStyle, offsetLeft, i,
+               body = document.getElementsByTagName( "body" )[ 0 ],
+               div = document.createElement( "div" );
+
+       //Create a "fake body" for testing based on method used in jQuery.support
+       testElement = document.createElement( body ? "div" : "body" );
+       testElementStyle = {
+               visibility: "hidden",
+               width: 0,
+               height: 0,
+               border: 0,
+               margin: 0,
+               background: "none"
+       };
+       if ( body ) {
+               $.extend( testElementStyle, {
+                       position: "absolute",
+                       left: "-1000px",
+                       top: "-1000px"
+               });
+       }
+       for ( i in testElementStyle ) {
+               testElement.style[ i ] = testElementStyle[ i ];
+       }
+       testElement.appendChild( div );
+       testElementParent = body || document.documentElement;
+       testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+       div.style.cssText = "position: absolute; left: 10.7432222px;";
+
+       offsetLeft = $( div ).offset().left;
+       supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
+
+       testElement.innerHTML = "";
+       testElementParent.removeChild( testElement );
+})();
+
+})();
+
+var position = $.ui.position;
+
+
+/*!
+ * jQuery UI Draggable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/draggable/
+ */
+
+
+$.widget("ui.draggable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "drag",
+       options: {
+               addClasses: true,
+               appendTo: "parent",
+               axis: false,
+               connectToSortable: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               iframeFix: false,
+               opacity: false,
+               refreshPositions: false,
+               revert: false,
+               revertDuration: 500,
+               scope: "default",
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               snap: false,
+               snapMode: "both",
+               snapTolerance: 20,
+               stack: false,
+               zIndex: false,
+
+               // callbacks
+               drag: null,
+               start: null,
+               stop: null
+       },
+       _create: function() {
+
+               if ( this.options.helper === "original" ) {
+                       this._setPositionRelative();
+               }
+               if (this.options.addClasses){
+                       this.element.addClass("ui-draggable");
+               }
+               if (this.options.disabled){
+                       this.element.addClass("ui-draggable-disabled");
+               }
+               this._setHandleClassName();
+
+               this._mouseInit();
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "handle" ) {
+                       this._removeHandleClassName();
+                       this._setHandleClassName();
+               }
+       },
+
+       _destroy: function() {
+               if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
+                       this.destroyOnClear = true;
+                       return;
+               }
+               this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
+               this._removeHandleClassName();
+               this._mouseDestroy();
+       },
+
+       _mouseCapture: function(event) {
+               var o = this.options;
+
+               this._blurActiveElement( event );
+
+               // among others, prevent a drag on a resizable-handle
+               if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
+                       return false;
+               }
+
+               //Quit if we're not on a valid handle
+               this.handle = this._getHandle(event);
+               if (!this.handle) {
+                       return false;
+               }
+
+               this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
+
+               return true;
+
+       },
+
+       _blockFrames: function( selector ) {
+               this.iframeBlocks = this.document.find( selector ).map(function() {
+                       var iframe = $( this );
+
+                       return $( "<div>" )
+                               .css( "position", "absolute" )
+                               .appendTo( iframe.parent() )
+                               .outerWidth( iframe.outerWidth() )
+                               .outerHeight( iframe.outerHeight() )
+                               .offset( iframe.offset() )[ 0 ];
+               });
+       },
+
+       _unblockFrames: function() {
+               if ( this.iframeBlocks ) {
+                       this.iframeBlocks.remove();
+                       delete this.iframeBlocks;
+               }
+       },
+
+       _blurActiveElement: function( event ) {
+               var document = this.document[ 0 ];
+
+               // Only need to blur if the event occurred on the draggable itself, see #10527
+               if ( !this.handleElement.is( event.target ) ) {
+                       return;
+               }
+
+               // support: IE9
+               // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+               try {
+
+                       // Support: IE9, IE10
+                       // If the <body> is blurred, IE will switch windows, see #9520
+                       if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
+
+                               // Blur any element that currently has focus, see #4261
+                               $( document.activeElement ).blur();
+                       }
+               } catch ( error ) {}
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options;
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               this.helper.addClass("ui-draggable-dragging");
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               //If ddmanager is used for droppables, set the global draggable
+               if ($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Store the helper's css position
+               this.cssPosition = this.helper.css( "position" );
+               this.scrollParent = this.helper.scrollParent( true );
+               this.offsetParent = this.helper.offsetParent();
+               this.hasFixedAncestor = this.helper.parents().filter(function() {
+                               return $( this ).css( "position" ) === "fixed";
+                       }).length > 0;
+
+               //The element's absolute position on the page minus margins
+               this.positionAbs = this.element.offset();
+               this._refreshOffsets( event );
+
+               //Generate the original position
+               this.originalPosition = this.position = this._generatePosition( event, false );
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Set a containment if given in the options
+               this._setContainment();
+
+               //Trigger event + callbacks
+               if (this._trigger("start", event) === false) {
+                       this._clear();
+                       return false;
+               }
+
+               //Recache the helper size
+               this._cacheHelperProportions();
+
+               //Prepare the droppable offsets
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               // Reset helper's right/bottom css if they're set and set explicit width/height instead
+               // as this prevents resizing of elements with right/bottom set (see #7772)
+               this._normalizeRightBottom();
+
+               this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+               if ( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStart(this, event);
+               }
+
+               return true;
+       },
+
+       _refreshOffsets: function( event ) {
+               this.offset = {
+                       top: this.positionAbs.top - this.margins.top,
+                       left: this.positionAbs.left - this.margins.left,
+                       scroll: false,
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset()
+               };
+
+               this.offset.click = {
+                       left: event.pageX - this.offset.left,
+                       top: event.pageY - this.offset.top
+               };
+       },
+
+       _mouseDrag: function(event, noPropagation) {
+               // reset any necessary cached properties (see #5009)
+               if ( this.hasFixedAncestor ) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               //Compute the helpers position
+               this.position = this._generatePosition( event, true );
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Call plugins and callbacks and use the resulting position if something is returned
+               if (!noPropagation) {
+                       var ui = this._uiHash();
+                       if (this._trigger("drag", event, ui) === false) {
+                               this._mouseUp({});
+                               return false;
+                       }
+                       this.position = ui.position;
+               }
+
+               this.helper[ 0 ].style.left = this.position.left + "px";
+               this.helper[ 0 ].style.top = this.position.top + "px";
+
+               if ($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               //If we are using droppables, inform the manager about the drop
+               var that = this,
+                       dropped = false;
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       dropped = $.ui.ddmanager.drop(this, event);
+               }
+
+               //if a drop comes from outside (a sortable)
+               if (this.dropped) {
+                       dropped = this.dropped;
+                       this.dropped = false;
+               }
+
+               if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+                       $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+                               if (that._trigger("stop", event) !== false) {
+                                       that._clear();
+                               }
+                       });
+               } else {
+                       if (this._trigger("stop", event) !== false) {
+                               this._clear();
+                       }
+               }
+
+               return false;
+       },
+
+       _mouseUp: function( event ) {
+               this._unblockFrames();
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+               if ( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStop(this, event);
+               }
+
+               // Only need to focus if the event occurred on the draggable itself, see #10527
+               if ( this.handleElement.is( event.target ) ) {
+                       // The interaction is over; whether or not the click resulted in a drag, focus the element
+                       this.element.focus();
+               }
+
+               return $.ui.mouse.prototype._mouseUp.call(this, event);
+       },
+
+       cancel: function() {
+
+               if (this.helper.is(".ui-draggable-dragging")) {
+                       this._mouseUp({});
+               } else {
+                       this._clear();
+               }
+
+               return this;
+
+       },
+
+       _getHandle: function(event) {
+               return this.options.handle ?
+                       !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
+                       true;
+       },
+
+       _setHandleClassName: function() {
+               this.handleElement = this.options.handle ?
+                       this.element.find( this.options.handle ) : this.element;
+               this.handleElement.addClass( "ui-draggable-handle" );
+       },
+
+       _removeHandleClassName: function() {
+               this.handleElement.removeClass( "ui-draggable-handle" );
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helperIsFunction = $.isFunction( o.helper ),
+                       helper = helperIsFunction ?
+                               $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
+                               ( o.helper === "clone" ?
+                                       this.element.clone().removeAttr( "id" ) :
+                                       this.element );
+
+               if (!helper.parents("body").length) {
+                       helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
+               }
+
+               // http://bugs.jqueryui.com/ticket/9446
+               // a helper function can return the original element
+               // which wouldn't have been set to relative in _create
+               if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
+                       this._setPositionRelative();
+               }
+
+               if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
+                       helper.css("position", "absolute");
+               }
+
+               return helper;
+
+       },
+
+       _setPositionRelative: function() {
+               if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
+                       this.element[ 0 ].style.position = "relative";
+               }
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = { left: +obj[0], top: +obj[1] || 0 };
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _isRootNode: function( element ) {
+               return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
+       },
+
+       _getParentOffset: function() {
+
+               //Get the offsetParent and cache its position
+               var po = this.offsetParent.offset(),
+                       document = this.document[ 0 ];
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+               if ( this.cssPosition !== "relative" ) {
+                       return { top: 0, left: 0 };
+               }
+
+               var p = this.element.position(),
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+               return {
+                       top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+                       left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+               };
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.element.css("marginLeft"), 10) || 0),
+                       top: (parseInt(this.element.css("marginTop"), 10) || 0),
+                       right: (parseInt(this.element.css("marginRight"), 10) || 0),
+                       bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var isUserScrollable, c, ce,
+                       o = this.options,
+                       document = this.document[ 0 ];
+
+               this.relativeContainer = null;
+
+               if ( !o.containment ) {
+                       this.containment = null;
+                       return;
+               }
+
+               if ( o.containment === "window" ) {
+                       this.containment = [
+                               $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+                               $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+                               $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
+                               $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+                       ];
+                       return;
+               }
+
+               if ( o.containment === "document") {
+                       this.containment = [
+                               0,
+                               0,
+                               $( document ).width() - this.helperProportions.width - this.margins.left,
+                               ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+                       ];
+                       return;
+               }
+
+               if ( o.containment.constructor === Array ) {
+                       this.containment = o.containment;
+                       return;
+               }
+
+               if ( o.containment === "parent" ) {
+                       o.containment = this.helper[ 0 ].parentNode;
+               }
+
+               c = $( o.containment );
+               ce = c[ 0 ];
+
+               if ( !ce ) {
+                       return;
+               }
+
+               isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
+
+               this.containment = [
+                       ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
+                       ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
+                       ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
+                               ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
+                               ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
+                               this.helperProportions.width -
+                               this.margins.left -
+                               this.margins.right,
+                       ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
+                               ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
+                               ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
+                               this.helperProportions.height -
+                               this.margins.top -
+                               this.margins.bottom
+               ];
+               this.relativeContainer = c;
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if (!pos) {
+                       pos = this.position;
+               }
+
+               var mod = d === "absolute" ? 1 : -1,
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function( event, constrainPosition ) {
+
+               var containment, co, top, left,
+                       o = this.options,
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
+                       pageX = event.pageX,
+                       pageY = event.pageY;
+
+               // Cache the scroll
+               if ( !scrollIsRootNode || !this.offset.scroll ) {
+                       this.offset.scroll = {
+                               top: this.scrollParent.scrollTop(),
+                               left: this.scrollParent.scrollLeft()
+                       };
+               }
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               // If we are not dragging yet, we won't check for options
+               if ( constrainPosition ) {
+                       if ( this.containment ) {
+                               if ( this.relativeContainer ){
+                                       co = this.relativeContainer.offset();
+                                       containment = [
+                                               this.containment[ 0 ] + co.left,
+                                               this.containment[ 1 ] + co.top,
+                                               this.containment[ 2 ] + co.left,
+                                               this.containment[ 3 ] + co.top
+                                       ];
+                               } else {
+                                       containment = this.containment;
+                               }
+
+                               if (event.pageX - this.offset.click.left < containment[0]) {
+                                       pageX = containment[0] + this.offset.click.left;
+                               }
+                               if (event.pageY - this.offset.click.top < containment[1]) {
+                                       pageY = containment[1] + this.offset.click.top;
+                               }
+                               if (event.pageX - this.offset.click.left > containment[2]) {
+                                       pageX = containment[2] + this.offset.click.left;
+                               }
+                               if (event.pageY - this.offset.click.top > containment[3]) {
+                                       pageY = containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if (o.grid) {
+                               //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+                               top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+                               pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+                               pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+                       if ( o.axis === "y" ) {
+                               pageX = this.originalPageX;
+                       }
+
+                       if ( o.axis === "x" ) {
+                               pageY = this.originalPageY;
+                       }
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.top   -                                                                                               // Click offset (relative to the element)
+                               this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+                       ),
+                       left: (
+                               pageX -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+                       )
+               };
+
+       },
+
+       _clear: function() {
+               this.helper.removeClass("ui-draggable-dragging");
+               if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
+                       this.helper.remove();
+               }
+               this.helper = null;
+               this.cancelHelperRemoval = false;
+               if ( this.destroyOnClear ) {
+                       this.destroy();
+               }
+       },
+
+       _normalizeRightBottom: function() {
+               if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
+                       this.helper.width( this.helper.width() );
+                       this.helper.css( "right", "auto" );
+               }
+               if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
+                       this.helper.height( this.helper.height() );
+                       this.helper.css( "bottom", "auto" );
+               }
+       },
+
+       // From now on bulk stuff - mainly helpers
+
+       _trigger: function( type, event, ui ) {
+               ui = ui || this._uiHash();
+               $.ui.plugin.call( this, type, [ event, ui, this ], true );
+
+               // Absolute position and offset (see #6884 ) have to be recalculated after plugins
+               if ( /^(drag|start|stop)/.test( type ) ) {
+                       this.positionAbs = this._convertPositionTo( "absolute" );
+                       ui.offset = this.positionAbs;
+               }
+               return $.Widget.prototype._trigger.call( this, type, event, ui );
+       },
+
+       plugins: {},
+
+       _uiHash: function() {
+               return {
+                       helper: this.helper,
+                       position: this.position,
+                       originalPosition: this.originalPosition,
+                       offset: this.positionAbs
+               };
+       }
+
+});
+
+$.ui.plugin.add( "draggable", "connectToSortable", {
+       start: function( event, ui, draggable ) {
+               var uiSortable = $.extend( {}, ui, {
+                       item: draggable.element
+               });
+
+               draggable.sortables = [];
+               $( draggable.options.connectToSortable ).each(function() {
+                       var sortable = $( this ).sortable( "instance" );
+
+                       if ( sortable && !sortable.options.disabled ) {
+                               draggable.sortables.push( sortable );
+
+                               // refreshPositions is called at drag start to refresh the containerCache
+                               // which is used in drag. This ensures it's initialized and synchronized
+                               // with any changes that might have happened on the page since initialization.
+                               sortable.refreshPositions();
+                               sortable._trigger("activate", event, uiSortable);
+                       }
+               });
+       },
+       stop: function( event, ui, draggable ) {
+               var uiSortable = $.extend( {}, ui, {
+                       item: draggable.element
+               });
+
+               draggable.cancelHelperRemoval = false;
+
+               $.each( draggable.sortables, function() {
+                       var sortable = this;
+
+                       if ( sortable.isOver ) {
+                               sortable.isOver = 0;
+
+                               // Allow this sortable to handle removing the helper
+                               draggable.cancelHelperRemoval = true;
+                               sortable.cancelHelperRemoval = false;
+
+                               // Use _storedCSS To restore properties in the sortable,
+                               // as this also handles revert (#9675) since the draggable
+                               // may have modified them in unexpected ways (#8809)
+                               sortable._storedCSS = {
+                                       position: sortable.placeholder.css( "position" ),
+                                       top: sortable.placeholder.css( "top" ),
+                                       left: sortable.placeholder.css( "left" )
+                               };
+
+                               sortable._mouseStop(event);
+
+                               // Once drag has ended, the sortable should return to using
+                               // its original helper, not the shared helper from draggable
+                               sortable.options.helper = sortable.options._helper;
+                       } else {
+                               // Prevent this Sortable from removing the helper.
+                               // However, don't set the draggable to remove the helper
+                               // either as another connected Sortable may yet handle the removal.
+                               sortable.cancelHelperRemoval = true;
+
+                               sortable._trigger( "deactivate", event, uiSortable );
+                       }
+               });
+       },
+       drag: function( event, ui, draggable ) {
+               $.each( draggable.sortables, function() {
+                       var innermostIntersecting = false,
+                               sortable = this;
+
+                       // Copy over variables that sortable's _intersectsWith uses
+                       sortable.positionAbs = draggable.positionAbs;
+                       sortable.helperProportions = draggable.helperProportions;
+                       sortable.offset.click = draggable.offset.click;
+
+                       if ( sortable._intersectsWith( sortable.containerCache ) ) {
+                               innermostIntersecting = true;
+
+                               $.each( draggable.sortables, function() {
+                                       // Copy over variables that sortable's _intersectsWith uses
+                                       this.positionAbs = draggable.positionAbs;
+                                       this.helperProportions = draggable.helperProportions;
+                                       this.offset.click = draggable.offset.click;
+
+                                       if ( this !== sortable &&
+                                                       this._intersectsWith( this.containerCache ) &&
+                                                       $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
+                                               innermostIntersecting = false;
+                                       }
+
+                                       return innermostIntersecting;
+                               });
+                       }
+
+                       if ( innermostIntersecting ) {
+                               // If it intersects, we use a little isOver variable and set it once,
+                               // so that the move-in stuff gets fired only once.
+                               if ( !sortable.isOver ) {
+                                       sortable.isOver = 1;
+
+                                       sortable.currentItem = ui.helper
+                                               .appendTo( sortable.element )
+                                               .data( "ui-sortable-item", true );
+
+                                       // Store helper option to later restore it
+                                       sortable.options._helper = sortable.options.helper;
+
+                                       sortable.options.helper = function() {
+                                               return ui.helper[ 0 ];
+                                       };
+
+                                       // Fire the start events of the sortable with our passed browser event,
+                                       // and our own helper (so it doesn't create a new one)
+                                       event.target = sortable.currentItem[ 0 ];
+                                       sortable._mouseCapture( event, true );
+                                       sortable._mouseStart( event, true, true );
+
+                                       // Because the browser event is way off the new appended portlet,
+                                       // modify necessary variables to reflect the changes
+                                       sortable.offset.click.top = draggable.offset.click.top;
+                                       sortable.offset.click.left = draggable.offset.click.left;
+                                       sortable.offset.parent.left -= draggable.offset.parent.left -
+                                               sortable.offset.parent.left;
+                                       sortable.offset.parent.top -= draggable.offset.parent.top -
+                                               sortable.offset.parent.top;
+
+                                       draggable._trigger( "toSortable", event );
+
+                                       // Inform draggable that the helper is in a valid drop zone,
+                                       // used solely in the revert option to handle "valid/invalid".
+                                       draggable.dropped = sortable.element;
+
+                                       // Need to refreshPositions of all sortables in the case that
+                                       // adding to one sortable changes the location of the other sortables (#9675)
+                                       $.each( draggable.sortables, function() {
+                                               this.refreshPositions();
+                                       });
+
+                                       // hack so receive/update callbacks work (mostly)
+                                       draggable.currentItem = draggable.element;
+                                       sortable.fromOutside = draggable;
+                               }
+
+                               if ( sortable.currentItem ) {
+                                       sortable._mouseDrag( event );
+                                       // Copy the sortable's position because the draggable's can potentially reflect
+                                       // a relative position, while sortable is always absolute, which the dragged
+                                       // element has now become. (#8809)
+                                       ui.position = sortable.position;
+                               }
+                       } else {
+                               // If it doesn't intersect with the sortable, and it intersected before,
+                               // we fake the drag stop of the sortable, but make sure it doesn't remove
+                               // the helper by using cancelHelperRemoval.
+                               if ( sortable.isOver ) {
+
+                                       sortable.isOver = 0;
+                                       sortable.cancelHelperRemoval = true;
+
+                                       // Calling sortable's mouseStop would trigger a revert,
+                                       // so revert must be temporarily false until after mouseStop is called.
+                                       sortable.options._revert = sortable.options.revert;
+                                       sortable.options.revert = false;
+
+                                       sortable._trigger( "out", event, sortable._uiHash( sortable ) );
+                                       sortable._mouseStop( event, true );
+
+                                       // restore sortable behaviors that were modfied
+                                       // when the draggable entered the sortable area (#9481)
+                                       sortable.options.revert = sortable.options._revert;
+                                       sortable.options.helper = sortable.options._helper;
+
+                                       if ( sortable.placeholder ) {
+                                               sortable.placeholder.remove();
+                                       }
+
+                                       // Recalculate the draggable's offset considering the sortable
+                                       // may have modified them in unexpected ways (#8809)
+                                       draggable._refreshOffsets( event );
+                                       ui.position = draggable._generatePosition( event, true );
+
+                                       draggable._trigger( "fromSortable", event );
+
+                                       // Inform draggable that the helper is no longer in a valid drop zone
+                                       draggable.dropped = false;
+
+                                       // Need to refreshPositions of all sortables just in case removing
+                                       // from one sortable changes the location of other sortables (#9675)
+                                       $.each( draggable.sortables, function() {
+                                               this.refreshPositions();
+                                       });
+                               }
+                       }
+               });
+       }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+       start: function( event, ui, instance ) {
+               var t = $( "body" ),
+                       o = instance.options;
+
+               if (t.css("cursor")) {
+                       o._cursor = t.css("cursor");
+               }
+               t.css("cursor", o.cursor);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+               if (o._cursor) {
+                       $("body").css("cursor", o._cursor);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+       start: function( event, ui, instance ) {
+               var t = $( ui.helper ),
+                       o = instance.options;
+               if (t.css("opacity")) {
+                       o._opacity = t.css("opacity");
+               }
+               t.css("opacity", o.opacity);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+               if (o._opacity) {
+                       $(ui.helper).css("opacity", o._opacity);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+       start: function( event, ui, i ) {
+               if ( !i.scrollParentNotHidden ) {
+                       i.scrollParentNotHidden = i.helper.scrollParent( false );
+               }
+
+               if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
+                       i.overflowOffset = i.scrollParentNotHidden.offset();
+               }
+       },
+       drag: function( event, ui, i  ) {
+
+               var o = i.options,
+                       scrolled = false,
+                       scrollParent = i.scrollParentNotHidden[ 0 ],
+                       document = i.document[ 0 ];
+
+               if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
+                       if ( !o.axis || o.axis !== "x" ) {
+                               if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
+                                       scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
+                               } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
+                                       scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
+                               }
+                       }
+
+                       if ( !o.axis || o.axis !== "y" ) {
+                               if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
+                                       scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
+                               } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
+                                       scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
+                               }
+                       }
+
+               } else {
+
+                       if (!o.axis || o.axis !== "x") {
+                               if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+                               }
+                       }
+
+                       if (!o.axis || o.axis !== "y") {
+                               if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+                               }
+                       }
+
+               }
+
+               if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(i, event);
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+       start: function( event, ui, i ) {
+
+               var o = i.options;
+
+               i.snapElements = [];
+
+               $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
+                       var $t = $(this),
+                               $o = $t.offset();
+                       if (this !== i.element[0]) {
+                               i.snapElements.push({
+                                       item: this,
+                                       width: $t.outerWidth(), height: $t.outerHeight(),
+                                       top: $o.top, left: $o.left
+                               });
+                       }
+               });
+
+       },
+       drag: function( event, ui, inst ) {
+
+               var ts, bs, ls, rs, l, r, t, b, i, first,
+                       o = inst.options,
+                       d = o.snapTolerance,
+                       x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+                       y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+               for (i = inst.snapElements.length - 1; i >= 0; i--){
+
+                       l = inst.snapElements[i].left - inst.margins.left;
+                       r = l + inst.snapElements[i].width;
+                       t = inst.snapElements[i].top - inst.margins.top;
+                       b = t + inst.snapElements[i].height;
+
+                       if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
+                               if (inst.snapElements[i].snapping) {
+                                       (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                               }
+                               inst.snapElements[i].snapping = false;
+                               continue;
+                       }
+
+                       if (o.snapMode !== "inner") {
+                               ts = Math.abs(t - y2) <= d;
+                               bs = Math.abs(b - y1) <= d;
+                               ls = Math.abs(l - x2) <= d;
+                               rs = Math.abs(r - x1) <= d;
+                               if (ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
+                               }
+                               if (bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
+                               }
+                               if (ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
+                               }
+                               if (rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
+                               }
+                       }
+
+                       first = (ts || bs || ls || rs);
+
+                       if (o.snapMode !== "outer") {
+                               ts = Math.abs(t - y1) <= d;
+                               bs = Math.abs(b - y2) <= d;
+                               ls = Math.abs(l - x1) <= d;
+                               rs = Math.abs(r - x2) <= d;
+                               if (ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
+                               }
+                               if (bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
+                               }
+                               if (ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
+                               }
+                               if (rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
+                               }
+                       }
+
+                       if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
+                               (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                       }
+                       inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+       start: function( event, ui, instance ) {
+               var min,
+                       o = instance.options,
+                       group = $.makeArray($(o.stack)).sort(function(a, b) {
+                               return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
+                       });
+
+               if (!group.length) { return; }
+
+               min = parseInt($(group[0]).css("zIndex"), 10) || 0;
+               $(group).each(function(i) {
+                       $(this).css("zIndex", min + i);
+               });
+               this.css("zIndex", (min + group.length));
+       }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+       start: function( event, ui, instance ) {
+               var t = $( ui.helper ),
+                       o = instance.options;
+
+               if (t.css("zIndex")) {
+                       o._zIndex = t.css("zIndex");
+               }
+               t.css("zIndex", o.zIndex);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+
+               if (o._zIndex) {
+                       $(ui.helper).css("zIndex", o._zIndex);
+               }
+       }
+});
+
+var draggable = $.ui.draggable;
+
+
+/*!
+ * jQuery UI Droppable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/droppable/
+ */
+
+
+$.widget( "ui.droppable", {
+       version: "1.11.3",
+       widgetEventPrefix: "drop",
+       options: {
+               accept: "*",
+               activeClass: false,
+               addClasses: true,
+               greedy: false,
+               hoverClass: false,
+               scope: "default",
+               tolerance: "intersect",
+
+               // callbacks
+               activate: null,
+               deactivate: null,
+               drop: null,
+               out: null,
+               over: null
+       },
+       _create: function() {
+
+               var proportions,
+                       o = this.options,
+                       accept = o.accept;
+
+               this.isover = false;
+               this.isout = true;
+
+               this.accept = $.isFunction( accept ) ? accept : function( d ) {
+                       return d.is( accept );
+               };
+
+               this.proportions = function( /* valueToWrite */ ) {
+                       if ( arguments.length ) {
+                               // Store the droppable's proportions
+                               proportions = arguments[ 0 ];
+                       } else {
+                               // Retrieve or derive the droppable's proportions
+                               return proportions ?
+                                       proportions :
+                                       proportions = {
+                                               width: this.element[ 0 ].offsetWidth,
+                                               height: this.element[ 0 ].offsetHeight
+                                       };
+                       }
+               };
+
+               this._addToManager( o.scope );
+
+               o.addClasses && this.element.addClass( "ui-droppable" );
+
+       },
+
+       _addToManager: function( scope ) {
+               // Add the reference and positions to the manager
+               $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
+               $.ui.ddmanager.droppables[ scope ].push( this );
+       },
+
+       _splice: function( drop ) {
+               var i = 0;
+               for ( ; i < drop.length; i++ ) {
+                       if ( drop[ i ] === this ) {
+                               drop.splice( i, 1 );
+                       }
+               }
+       },
+
+       _destroy: function() {
+               var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+               this._splice( drop );
+
+               this.element.removeClass( "ui-droppable ui-droppable-disabled" );
+       },
+
+       _setOption: function( key, value ) {
+
+               if ( key === "accept" ) {
+                       this.accept = $.isFunction( value ) ? value : function( d ) {
+                               return d.is( value );
+                       };
+               } else if ( key === "scope" ) {
+                       var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+                       this._splice( drop );
+                       this._addToManager( value );
+               }
+
+               this._super( key, value );
+       },
+
+       _activate: function( event ) {
+               var draggable = $.ui.ddmanager.current;
+               if ( this.options.activeClass ) {
+                       this.element.addClass( this.options.activeClass );
+               }
+               if ( draggable ){
+                       this._trigger( "activate", event, this.ui( draggable ) );
+               }
+       },
+
+       _deactivate: function( event ) {
+               var draggable = $.ui.ddmanager.current;
+               if ( this.options.activeClass ) {
+                       this.element.removeClass( this.options.activeClass );
+               }
+               if ( draggable ){
+                       this._trigger( "deactivate", event, this.ui( draggable ) );
+               }
+       },
+
+       _over: function( event ) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.hoverClass ) {
+                               this.element.addClass( this.options.hoverClass );
+                       }
+                       this._trigger( "over", event, this.ui( draggable ) );
+               }
+
+       },
+
+       _out: function( event ) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.hoverClass ) {
+                               this.element.removeClass( this.options.hoverClass );
+                       }
+                       this._trigger( "out", event, this.ui( draggable ) );
+               }
+
+       },
+
+       _drop: function( event, custom ) {
+
+               var draggable = custom || $.ui.ddmanager.current,
+                       childrenIntersection = false;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return false;
+               }
+
+               this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
+                       var inst = $( this ).droppable( "instance" );
+                       if (
+                               inst.options.greedy &&
+                               !inst.options.disabled &&
+                               inst.options.scope === draggable.options.scope &&
+                               inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
+                               $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
+                       ) { childrenIntersection = true; return false; }
+               });
+               if ( childrenIntersection ) {
+                       return false;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.activeClass ) {
+                               this.element.removeClass( this.options.activeClass );
+                       }
+                       if ( this.options.hoverClass ) {
+                               this.element.removeClass( this.options.hoverClass );
+                       }
+                       this._trigger( "drop", event, this.ui( draggable ) );
+                       return this.element;
+               }
+
+               return false;
+
+       },
+
+       ui: function( c ) {
+               return {
+                       draggable: ( c.currentItem || c.element ),
+                       helper: c.helper,
+                       position: c.position,
+                       offset: c.positionAbs
+               };
+       }
+
+});
+
+$.ui.intersect = (function() {
+       function isOverAxis( x, reference, size ) {
+               return ( x >= reference ) && ( x < ( reference + size ) );
+       }
+
+       return function( draggable, droppable, toleranceMode, event ) {
+
+               if ( !droppable.offset ) {
+                       return false;
+               }
+
+               var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
+                       y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
+                       x2 = x1 + draggable.helperProportions.width,
+                       y2 = y1 + draggable.helperProportions.height,
+                       l = droppable.offset.left,
+                       t = droppable.offset.top,
+                       r = l + droppable.proportions().width,
+                       b = t + droppable.proportions().height;
+
+               switch ( toleranceMode ) {
+               case "fit":
+                       return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
+               case "intersect":
+                       return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
+                               x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
+                               t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
+                               y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
+               case "pointer":
+                       return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
+               case "touch":
+                       return (
+                               ( y1 >= t && y1 <= b ) || // Top edge touching
+                               ( y2 >= t && y2 <= b ) || // Bottom edge touching
+                               ( y1 < t && y2 > b ) // Surrounded vertically
+                       ) && (
+                               ( x1 >= l && x1 <= r ) || // Left edge touching
+                               ( x2 >= l && x2 <= r ) || // Right edge touching
+                               ( x1 < l && x2 > r ) // Surrounded horizontally
+                       );
+               default:
+                       return false;
+               }
+       };
+})();
+
+/*
+       This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+       current: null,
+       droppables: { "default": [] },
+       prepareOffsets: function( t, event ) {
+
+               var i, j,
+                       m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
+                       type = event ? event.type : null, // workaround for #2317
+                       list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
+
+               droppablesLoop: for ( i = 0; i < m.length; i++ ) {
+
+                       // No disabled and non-accepted
+                       if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
+                               continue;
+                       }
+
+                       // Filter out elements in the current dragged item
+                       for ( j = 0; j < list.length; j++ ) {
+                               if ( list[ j ] === m[ i ].element[ 0 ] ) {
+                                       m[ i ].proportions().height = 0;
+                                       continue droppablesLoop;
+                               }
+                       }
+
+                       m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
+                       if ( !m[ i ].visible ) {
+                               continue;
+                       }
+
+                       // Activate the droppable if used directly from draggables
+                       if ( type === "mousedown" ) {
+                               m[ i ]._activate.call( m[ i ], event );
+                       }
+
+                       m[ i ].offset = m[ i ].element.offset();
+                       m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
+
+               }
+
+       },
+       drop: function( draggable, event ) {
+
+               var dropped = false;
+               // Create a copy of the droppables in case the list changes during the drop (#9116)
+               $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
+
+                       if ( !this.options ) {
+                               return;
+                       }
+                       if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
+                               dropped = this._drop.call( this, event ) || dropped;
+                       }
+
+                       if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                               this.isout = true;
+                               this.isover = false;
+                               this._deactivate.call( this, event );
+                       }
+
+               });
+               return dropped;
+
+       },
+       dragStart: function( draggable, event ) {
+               // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+               draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
+                       if ( !draggable.options.refreshPositions ) {
+                               $.ui.ddmanager.prepareOffsets( draggable, event );
+                       }
+               });
+       },
+       drag: function( draggable, event ) {
+
+               // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+               if ( draggable.options.refreshPositions ) {
+                       $.ui.ddmanager.prepareOffsets( draggable, event );
+               }
+
+               // Run through all droppables and check their positions based on specific tolerance options
+               $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
+
+                       if ( this.options.disabled || this.greedyChild || !this.visible ) {
+                               return;
+                       }
+
+                       var parentInstance, scope, parent,
+                               intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
+                               c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
+                       if ( !c ) {
+                               return;
+                       }
+
+                       if ( this.options.greedy ) {
+                               // find droppable parents with same scope
+                               scope = this.options.scope;
+                               parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
+                                       return $( this ).droppable( "instance" ).options.scope === scope;
+                               });
+
+                               if ( parent.length ) {
+                                       parentInstance = $( parent[ 0 ] ).droppable( "instance" );
+                                       parentInstance.greedyChild = ( c === "isover" );
+                               }
+                       }
+
+                       // we just moved into a greedy child
+                       if ( parentInstance && c === "isover" ) {
+                               parentInstance.isover = false;
+                               parentInstance.isout = true;
+                               parentInstance._out.call( parentInstance, event );
+                       }
+
+                       this[ c ] = true;
+                       this[c === "isout" ? "isover" : "isout"] = false;
+                       this[c === "isover" ? "_over" : "_out"].call( this, event );
+
+                       // we just moved out of a greedy child
+                       if ( parentInstance && c === "isout" ) {
+                               parentInstance.isout = false;
+                               parentInstance.isover = true;
+                               parentInstance._over.call( parentInstance, event );
+                       }
+               });
+
+       },
+       dragStop: function( draggable, event ) {
+               draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
+               // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+               if ( !draggable.options.refreshPositions ) {
+                       $.ui.ddmanager.prepareOffsets( draggable, event );
+               }
+       }
+};
+
+var droppable = $.ui.droppable;
+
+
+/*!
+ * jQuery UI Resizable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/resizable/
+ */
+
+
+$.widget("ui.resizable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "resize",
+       options: {
+               alsoResize: false,
+               animate: false,
+               animateDuration: "slow",
+               animateEasing: "swing",
+               aspectRatio: false,
+               autoHide: false,
+               containment: false,
+               ghost: false,
+               grid: false,
+               handles: "e,s,se",
+               helper: false,
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 10,
+               minWidth: 10,
+               // See #7960
+               zIndex: 90,
+
+               // callbacks
+               resize: null,
+               start: null,
+               stop: null
+       },
+
+       _num: function( value ) {
+               return parseInt( value, 10 ) || 0;
+       },
+
+       _isNumber: function( value ) {
+               return !isNaN( parseInt( value, 10 ) );
+       },
+
+       _hasScroll: function( el, a ) {
+
+               if ( $( el ).css( "overflow" ) === "hidden") {
+                       return false;
+               }
+
+               var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+                       has = false;
+
+               if ( el[ scroll ] > 0 ) {
+                       return true;
+               }
+
+               // TODO: determine which cases actually cause this to happen
+               // if the element doesn't have the scroll set, see if it's possible to
+               // set the scroll
+               el[ scroll ] = 1;
+               has = ( el[ scroll ] > 0 );
+               el[ scroll ] = 0;
+               return has;
+       },
+
+       _create: function() {
+
+               var n, i, handle, axis, hname,
+                       that = this,
+                       o = this.options;
+               this.element.addClass("ui-resizable");
+
+               $.extend(this, {
+                       _aspectRatio: !!(o.aspectRatio),
+                       aspectRatio: o.aspectRatio,
+                       originalElement: this.element,
+                       _proportionallyResizeElements: [],
+                       _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
+               });
+
+               // Wrap the element if it cannot hold child nodes
+               if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
+
+                       this.element.wrap(
+                               $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
+                                       position: this.element.css("position"),
+                                       width: this.element.outerWidth(),
+                                       height: this.element.outerHeight(),
+                                       top: this.element.css("top"),
+                                       left: this.element.css("left")
+                               })
+                       );
+
+                       this.element = this.element.parent().data(
+                               "ui-resizable", this.element.resizable( "instance" )
+                       );
+
+                       this.elementIsWrapper = true;
+
+                       this.element.css({
+                               marginLeft: this.originalElement.css("marginLeft"),
+                               marginTop: this.originalElement.css("marginTop"),
+                               marginRight: this.originalElement.css("marginRight"),
+                               marginBottom: this.originalElement.css("marginBottom")
+                       });
+                       this.originalElement.css({
+                               marginLeft: 0,
+                               marginTop: 0,
+                               marginRight: 0,
+                               marginBottom: 0
+                       });
+                       // support: Safari
+                       // Prevent Safari textarea resize
+                       this.originalResizeStyle = this.originalElement.css("resize");
+                       this.originalElement.css("resize", "none");
+
+                       this._proportionallyResizeElements.push( this.originalElement.css({
+                               position: "static",
+                               zoom: 1,
+                               display: "block"
+                       }) );
+
+                       // support: IE9
+                       // avoid IE jump (hard set the margin)
+                       this.originalElement.css({ margin: this.originalElement.css("margin") });
+
+                       this._proportionallyResize();
+               }
+
+               this.handles = o.handles ||
+                       ( !$(".ui-resizable-handle", this.element).length ?
+                               "e,s,se" : {
+                                       n: ".ui-resizable-n",
+                                       e: ".ui-resizable-e",
+                                       s: ".ui-resizable-s",
+                                       w: ".ui-resizable-w",
+                                       se: ".ui-resizable-se",
+                                       sw: ".ui-resizable-sw",
+                                       ne: ".ui-resizable-ne",
+                                       nw: ".ui-resizable-nw"
+                               } );
+
+               if (this.handles.constructor === String) {
+
+                       if ( this.handles === "all") {
+                               this.handles = "n,e,s,w,se,sw,ne,nw";
+                       }
+
+                       n = this.handles.split(",");
+                       this.handles = {};
+
+                       for (i = 0; i < n.length; i++) {
+
+                               handle = $.trim(n[i]);
+                               hname = "ui-resizable-" + handle;
+                               axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
+
+                               axis.css({ zIndex: o.zIndex });
+
+                               // TODO : What's going on here?
+                               if ("se" === handle) {
+                                       axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
+                               }
+
+                               this.handles[handle] = ".ui-resizable-" + handle;
+                               this.element.append(axis);
+                       }
+
+               }
+
+               this._renderAxis = function(target) {
+
+                       var i, axis, padPos, padWrapper;
+
+                       target = target || this.element;
+
+                       for (i in this.handles) {
+
+                               if (this.handles[i].constructor === String) {
+                                       this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
+                               }
+
+                               if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
+
+                                       axis = $(this.handles[i], this.element);
+
+                                       padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+                                       padPos = [ "padding",
+                                               /ne|nw|n/.test(i) ? "Top" :
+                                               /se|sw|s/.test(i) ? "Bottom" :
+                                               /^e$/.test(i) ? "Right" : "Left" ].join("");
+
+                                       target.css(padPos, padWrapper);
+
+                                       this._proportionallyResize();
+
+                               }
+
+                               // TODO: What's that good for? There's not anything to be executed left
+                               if (!$(this.handles[i]).length) {
+                                       continue;
+                               }
+                       }
+               };
+
+               // TODO: make renderAxis a prototype function
+               this._renderAxis(this.element);
+
+               this._handles = $(".ui-resizable-handle", this.element)
+                       .disableSelection();
+
+               this._handles.mouseover(function() {
+                       if (!that.resizing) {
+                               if (this.className) {
+                                       axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+                               }
+                               that.axis = axis && axis[1] ? axis[1] : "se";
+                       }
+               });
+
+               if (o.autoHide) {
+                       this._handles.hide();
+                       $(this.element)
+                               .addClass("ui-resizable-autohide")
+                               .mouseenter(function() {
+                                       if (o.disabled) {
+                                               return;
+                                       }
+                                       $(this).removeClass("ui-resizable-autohide");
+                                       that._handles.show();
+                               })
+                               .mouseleave(function() {
+                                       if (o.disabled) {
+                                               return;
+                                       }
+                                       if (!that.resizing) {
+                                               $(this).addClass("ui-resizable-autohide");
+                                               that._handles.hide();
+                                       }
+                               });
+               }
+
+               this._mouseInit();
+
+       },
+
+       _destroy: function() {
+
+               this._mouseDestroy();
+
+               var wrapper,
+                       _destroy = function(exp) {
+                               $(exp)
+                                       .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+                                       .removeData("resizable")
+                                       .removeData("ui-resizable")
+                                       .unbind(".resizable")
+                                       .find(".ui-resizable-handle")
+                                               .remove();
+                       };
+
+               // TODO: Unwrap at same DOM position
+               if (this.elementIsWrapper) {
+                       _destroy(this.element);
+                       wrapper = this.element;
+                       this.originalElement.css({
+                               position: wrapper.css("position"),
+                               width: wrapper.outerWidth(),
+                               height: wrapper.outerHeight(),
+                               top: wrapper.css("top"),
+                               left: wrapper.css("left")
+                       }).insertAfter( wrapper );
+                       wrapper.remove();
+               }
+
+               this.originalElement.css("resize", this.originalResizeStyle);
+               _destroy(this.originalElement);
+
+               return this;
+       },
+
+       _mouseCapture: function(event) {
+               var i, handle,
+                       capture = false;
+
+               for (i in this.handles) {
+                       handle = $(this.handles[i])[0];
+                       if (handle === event.target || $.contains(handle, event.target)) {
+                               capture = true;
+                       }
+               }
+
+               return !this.options.disabled && capture;
+       },
+
+       _mouseStart: function(event) {
+
+               var curleft, curtop, cursor,
+                       o = this.options,
+                       el = this.element;
+
+               this.resizing = true;
+
+               this._renderProxy();
+
+               curleft = this._num(this.helper.css("left"));
+               curtop = this._num(this.helper.css("top"));
+
+               if (o.containment) {
+                       curleft += $(o.containment).scrollLeft() || 0;
+                       curtop += $(o.containment).scrollTop() || 0;
+               }
+
+               this.offset = this.helper.offset();
+               this.position = { left: curleft, top: curtop };
+
+               this.size = this._helper ? {
+                               width: this.helper.width(),
+                               height: this.helper.height()
+                       } : {
+                               width: el.width(),
+                               height: el.height()
+                       };
+
+               this.originalSize = this._helper ? {
+                               width: el.outerWidth(),
+                               height: el.outerHeight()
+                       } : {
+                               width: el.width(),
+                               height: el.height()
+                       };
+
+               this.sizeDiff = {
+                       width: el.outerWidth() - el.width(),
+                       height: el.outerHeight() - el.height()
+               };
+
+               this.originalPosition = { left: curleft, top: curtop };
+               this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+               this.aspectRatio = (typeof o.aspectRatio === "number") ?
+                       o.aspectRatio :
+                       ((this.originalSize.width / this.originalSize.height) || 1);
+
+               cursor = $(".ui-resizable-" + this.axis).css("cursor");
+               $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
+
+               el.addClass("ui-resizable-resizing");
+               this._propagate("start", event);
+               return true;
+       },
+
+       _mouseDrag: function(event) {
+
+               var data, props,
+                       smp = this.originalMousePosition,
+                       a = this.axis,
+                       dx = (event.pageX - smp.left) || 0,
+                       dy = (event.pageY - smp.top) || 0,
+                       trigger = this._change[a];
+
+               this._updatePrevProperties();
+
+               if (!trigger) {
+                       return false;
+               }
+
+               data = trigger.apply(this, [ event, dx, dy ]);
+
+               this._updateVirtualBoundaries(event.shiftKey);
+               if (this._aspectRatio || event.shiftKey) {
+                       data = this._updateRatio(data, event);
+               }
+
+               data = this._respectSize(data, event);
+
+               this._updateCache(data);
+
+               this._propagate("resize", event);
+
+               props = this._applyChanges();
+
+               if ( !this._helper && this._proportionallyResizeElements.length ) {
+                       this._proportionallyResize();
+               }
+
+               if ( !$.isEmptyObject( props ) ) {
+                       this._updatePrevProperties();
+                       this._trigger( "resize", event, this.ui() );
+                       this._applyChanges();
+               }
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               this.resizing = false;
+               var pr, ista, soffseth, soffsetw, s, left, top,
+                       o = this.options, that = this;
+
+               if (this._helper) {
+
+                       pr = this._proportionallyResizeElements;
+                       ista = pr.length && (/textarea/i).test(pr[0].nodeName);
+                       soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
+                       soffsetw = ista ? 0 : that.sizeDiff.width;
+
+                       s = {
+                               width: (that.helper.width()  - soffsetw),
+                               height: (that.helper.height() - soffseth)
+                       };
+                       left = (parseInt(that.element.css("left"), 10) +
+                               (that.position.left - that.originalPosition.left)) || null;
+                       top = (parseInt(that.element.css("top"), 10) +
+                               (that.position.top - that.originalPosition.top)) || null;
+
+                       if (!o.animate) {
+                               this.element.css($.extend(s, { top: top, left: left }));
+                       }
+
+                       that.helper.height(that.size.height);
+                       that.helper.width(that.size.width);
+
+                       if (this._helper && !o.animate) {
+                               this._proportionallyResize();
+                       }
+               }
+
+               $("body").css("cursor", "auto");
+
+               this.element.removeClass("ui-resizable-resizing");
+
+               this._propagate("stop", event);
+
+               if (this._helper) {
+                       this.helper.remove();
+               }
+
+               return false;
+
+       },
+
+       _updatePrevProperties: function() {
+               this.prevPosition = {
+                       top: this.position.top,
+                       left: this.position.left
+               };
+               this.prevSize = {
+                       width: this.size.width,
+                       height: this.size.height
+               };
+       },
+
+       _applyChanges: function() {
+               var props = {};
+
+               if ( this.position.top !== this.prevPosition.top ) {
+                       props.top = this.position.top + "px";
+               }
+               if ( this.position.left !== this.prevPosition.left ) {
+                       props.left = this.position.left + "px";
+               }
+               if ( this.size.width !== this.prevSize.width ) {
+                       props.width = this.size.width + "px";
+               }
+               if ( this.size.height !== this.prevSize.height ) {
+                       props.height = this.size.height + "px";
+               }
+
+               this.helper.css( props );
+
+               return props;
+       },
+
+       _updateVirtualBoundaries: function(forceAspectRatio) {
+               var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
+                       o = this.options;
+
+               b = {
+                       minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
+                       maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+                       minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
+                       maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
+               };
+
+               if (this._aspectRatio || forceAspectRatio) {
+                       pMinWidth = b.minHeight * this.aspectRatio;
+                       pMinHeight = b.minWidth / this.aspectRatio;
+                       pMaxWidth = b.maxHeight * this.aspectRatio;
+                       pMaxHeight = b.maxWidth / this.aspectRatio;
+
+                       if (pMinWidth > b.minWidth) {
+                               b.minWidth = pMinWidth;
+                       }
+                       if (pMinHeight > b.minHeight) {
+                               b.minHeight = pMinHeight;
+                       }
+                       if (pMaxWidth < b.maxWidth) {
+                               b.maxWidth = pMaxWidth;
+                       }
+                       if (pMaxHeight < b.maxHeight) {
+                               b.maxHeight = pMaxHeight;
+                       }
+               }
+               this._vBoundaries = b;
+       },
+
+       _updateCache: function(data) {
+               this.offset = this.helper.offset();
+               if (this._isNumber(data.left)) {
+                       this.position.left = data.left;
+               }
+               if (this._isNumber(data.top)) {
+                       this.position.top = data.top;
+               }
+               if (this._isNumber(data.height)) {
+                       this.size.height = data.height;
+               }
+               if (this._isNumber(data.width)) {
+                       this.size.width = data.width;
+               }
+       },
+
+       _updateRatio: function( data ) {
+
+               var cpos = this.position,
+                       csize = this.size,
+                       a = this.axis;
+
+               if (this._isNumber(data.height)) {
+                       data.width = (data.height * this.aspectRatio);
+               } else if (this._isNumber(data.width)) {
+                       data.height = (data.width / this.aspectRatio);
+               }
+
+               if (a === "sw") {
+                       data.left = cpos.left + (csize.width - data.width);
+                       data.top = null;
+               }
+               if (a === "nw") {
+                       data.top = cpos.top + (csize.height - data.height);
+                       data.left = cpos.left + (csize.width - data.width);
+               }
+
+               return data;
+       },
+
+       _respectSize: function( data ) {
+
+               var o = this._vBoundaries,
+                       a = this.axis,
+                       ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
+                       ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+                       isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
+                       isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
+                       dw = this.originalPosition.left + this.originalSize.width,
+                       dh = this.position.top + this.size.height,
+                       cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+               if (isminw) {
+                       data.width = o.minWidth;
+               }
+               if (isminh) {
+                       data.height = o.minHeight;
+               }
+               if (ismaxw) {
+                       data.width = o.maxWidth;
+               }
+               if (ismaxh) {
+                       data.height = o.maxHeight;
+               }
+
+               if (isminw && cw) {
+                       data.left = dw - o.minWidth;
+               }
+               if (ismaxw && cw) {
+                       data.left = dw - o.maxWidth;
+               }
+               if (isminh && ch) {
+                       data.top = dh - o.minHeight;
+               }
+               if (ismaxh && ch) {
+                       data.top = dh - o.maxHeight;
+               }
+
+               // Fixing jump error on top/left - bug #2330
+               if (!data.width && !data.height && !data.left && data.top) {
+                       data.top = null;
+               } else if (!data.width && !data.height && !data.top && data.left) {
+                       data.left = null;
+               }
+
+               return data;
+       },
+
+       _getPaddingPlusBorderDimensions: function( element ) {
+               var i = 0,
+                       widths = [],
+                       borders = [
+                               element.css( "borderTopWidth" ),
+                               element.css( "borderRightWidth" ),
+                               element.css( "borderBottomWidth" ),
+                               element.css( "borderLeftWidth" )
+                       ],
+                       paddings = [
+                               element.css( "paddingTop" ),
+                               element.css( "paddingRight" ),
+                               element.css( "paddingBottom" ),
+                               element.css( "paddingLeft" )
+                       ];
+
+               for ( ; i < 4; i++ ) {
+                       widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
+                       widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
+               }
+
+               return {
+                       height: widths[ 0 ] + widths[ 2 ],
+                       width: widths[ 1 ] + widths[ 3 ]
+               };
+       },
+
+       _proportionallyResize: function() {
+
+               if (!this._proportionallyResizeElements.length) {
+                       return;
+               }
+
+               var prel,
+                       i = 0,
+                       element = this.helper || this.element;
+
+               for ( ; i < this._proportionallyResizeElements.length; i++) {
+
+                       prel = this._proportionallyResizeElements[i];
+
+                       // TODO: Seems like a bug to cache this.outerDimensions
+                       // considering that we are in a loop.
+                       if (!this.outerDimensions) {
+                               this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
+                       }
+
+                       prel.css({
+                               height: (element.height() - this.outerDimensions.height) || 0,
+                               width: (element.width() - this.outerDimensions.width) || 0
+                       });
+
+               }
+
+       },
+
+       _renderProxy: function() {
+
+               var el = this.element, o = this.options;
+               this.elementOffset = el.offset();
+
+               if (this._helper) {
+
+                       this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
+
+                       this.helper.addClass(this._helper).css({
+                               width: this.element.outerWidth() - 1,
+                               height: this.element.outerHeight() - 1,
+                               position: "absolute",
+                               left: this.elementOffset.left + "px",
+                               top: this.elementOffset.top + "px",
+                               zIndex: ++o.zIndex //TODO: Don't modify option
+                       });
+
+                       this.helper
+                               .appendTo("body")
+                               .disableSelection();
+
+               } else {
+                       this.helper = this.element;
+               }
+
+       },
+
+       _change: {
+               e: function(event, dx) {
+                       return { width: this.originalSize.width + dx };
+               },
+               w: function(event, dx) {
+                       var cs = this.originalSize, sp = this.originalPosition;
+                       return { left: sp.left + dx, width: cs.width - dx };
+               },
+               n: function(event, dx, dy) {
+                       var cs = this.originalSize, sp = this.originalPosition;
+                       return { top: sp.top + dy, height: cs.height - dy };
+               },
+               s: function(event, dx, dy) {
+                       return { height: this.originalSize.height + dy };
+               },
+               se: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments),
+                               this._change.e.apply(this, [ event, dx, dy ]));
+               },
+               sw: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments),
+                               this._change.w.apply(this, [ event, dx, dy ]));
+               },
+               ne: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments),
+                               this._change.e.apply(this, [ event, dx, dy ]));
+               },
+               nw: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments),
+                               this._change.w.apply(this, [ event, dx, dy ]));
+               }
+       },
+
+       _propagate: function(n, event) {
+               $.ui.plugin.call(this, n, [ event, this.ui() ]);
+               (n !== "resize" && this._trigger(n, event, this.ui()));
+       },
+
+       plugins: {},
+
+       ui: function() {
+               return {
+                       originalElement: this.originalElement,
+                       element: this.element,
+                       helper: this.helper,
+                       position: this.position,
+                       size: this.size,
+                       originalSize: this.originalSize,
+                       originalPosition: this.originalPosition
+               };
+       }
+
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "animate", {
+
+       stop: function( event ) {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       pr = that._proportionallyResizeElements,
+                       ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                       soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
+                       soffsetw = ista ? 0 : that.sizeDiff.width,
+                       style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
+                       left = (parseInt(that.element.css("left"), 10) +
+                               (that.position.left - that.originalPosition.left)) || null,
+                       top = (parseInt(that.element.css("top"), 10) +
+                               (that.position.top - that.originalPosition.top)) || null;
+
+               that.element.animate(
+                       $.extend(style, top && left ? { top: top, left: left } : {}), {
+                               duration: o.animateDuration,
+                               easing: o.animateEasing,
+                               step: function() {
+
+                                       var data = {
+                                               width: parseInt(that.element.css("width"), 10),
+                                               height: parseInt(that.element.css("height"), 10),
+                                               top: parseInt(that.element.css("top"), 10),
+                                               left: parseInt(that.element.css("left"), 10)
+                                       };
+
+                                       if (pr && pr.length) {
+                                               $(pr[0]).css({ width: data.width, height: data.height });
+                                       }
+
+                                       // propagating resize, and updating values for each animation step
+                                       that._updateCache(data);
+                                       that._propagate("resize", event);
+
+                               }
+                       }
+               );
+       }
+
+});
+
+$.ui.plugin.add( "resizable", "containment", {
+
+       start: function() {
+               var element, p, co, ch, cw, width, height,
+                       that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       el = that.element,
+                       oc = o.containment,
+                       ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
+
+               if ( !ce ) {
+                       return;
+               }
+
+               that.containerElement = $( ce );
+
+               if ( /document/.test( oc ) || oc === document ) {
+                       that.containerOffset = {
+                               left: 0,
+                               top: 0
+                       };
+                       that.containerPosition = {
+                               left: 0,
+                               top: 0
+                       };
+
+                       that.parentData = {
+                               element: $( document ),
+                               left: 0,
+                               top: 0,
+                               width: $( document ).width(),
+                               height: $( document ).height() || document.body.parentNode.scrollHeight
+                       };
+               } else {
+                       element = $( ce );
+                       p = [];
+                       $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
+                               p[ i ] = that._num( element.css( "padding" + name ) );
+                       });
+
+                       that.containerOffset = element.offset();
+                       that.containerPosition = element.position();
+                       that.containerSize = {
+                               height: ( element.innerHeight() - p[ 3 ] ),
+                               width: ( element.innerWidth() - p[ 1 ] )
+                       };
+
+                       co = that.containerOffset;
+                       ch = that.containerSize.height;
+                       cw = that.containerSize.width;
+                       width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
+                       height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
+
+                       that.parentData = {
+                               element: ce,
+                               left: co.left,
+                               top: co.top,
+                               width: width,
+                               height: height
+                       };
+               }
+       },
+
+       resize: function( event ) {
+               var woset, hoset, isParent, isOffsetRelative,
+                       that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       co = that.containerOffset,
+                       cp = that.position,
+                       pRatio = that._aspectRatio || event.shiftKey,
+                       cop = {
+                               top: 0,
+                               left: 0
+                       },
+                       ce = that.containerElement,
+                       continueResize = true;
+
+               if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
+                       cop = co;
+               }
+
+               if ( cp.left < ( that._helper ? co.left : 0 ) ) {
+                       that.size.width = that.size.width +
+                               ( that._helper ?
+                                       ( that.position.left - co.left ) :
+                                       ( that.position.left - cop.left ) );
+
+                       if ( pRatio ) {
+                               that.size.height = that.size.width / that.aspectRatio;
+                               continueResize = false;
+                       }
+                       that.position.left = o.helper ? co.left : 0;
+               }
+
+               if ( cp.top < ( that._helper ? co.top : 0 ) ) {
+                       that.size.height = that.size.height +
+                               ( that._helper ?
+                                       ( that.position.top - co.top ) :
+                                       that.position.top );
+
+                       if ( pRatio ) {
+                               that.size.width = that.size.height * that.aspectRatio;
+                               continueResize = false;
+                       }
+                       that.position.top = that._helper ? co.top : 0;
+               }
+
+               isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
+               isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
+
+               if ( isParent && isOffsetRelative ) {
+                       that.offset.left = that.parentData.left + that.position.left;
+                       that.offset.top = that.parentData.top + that.position.top;
+               } else {
+                       that.offset.left = that.element.offset().left;
+                       that.offset.top = that.element.offset().top;
+               }
+
+               woset = Math.abs( that.sizeDiff.width +
+                       (that._helper ?
+                               that.offset.left - cop.left :
+                               (that.offset.left - co.left)) );
+
+               hoset = Math.abs( that.sizeDiff.height +
+                       (that._helper ?
+                               that.offset.top - cop.top :
+                               (that.offset.top - co.top)) );
+
+               if ( woset + that.size.width >= that.parentData.width ) {
+                       that.size.width = that.parentData.width - woset;
+                       if ( pRatio ) {
+                               that.size.height = that.size.width / that.aspectRatio;
+                               continueResize = false;
+                       }
+               }
+
+               if ( hoset + that.size.height >= that.parentData.height ) {
+                       that.size.height = that.parentData.height - hoset;
+                       if ( pRatio ) {
+                               that.size.width = that.size.height * that.aspectRatio;
+                               continueResize = false;
+                       }
+               }
+
+               if ( !continueResize ) {
+                       that.position.left = that.prevPosition.left;
+                       that.position.top = that.prevPosition.top;
+                       that.size.width = that.prevSize.width;
+                       that.size.height = that.prevSize.height;
+               }
+       },
+
+       stop: function() {
+               var that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       co = that.containerOffset,
+                       cop = that.containerPosition,
+                       ce = that.containerElement,
+                       helper = $( that.helper ),
+                       ho = helper.offset(),
+                       w = helper.outerWidth() - that.sizeDiff.width,
+                       h = helper.outerHeight() - that.sizeDiff.height;
+
+               if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
+                       $( this ).css({
+                               left: ho.left - cop.left - co.left,
+                               width: w,
+                               height: h
+                       });
+               }
+
+               if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
+                       $( this ).css({
+                               left: ho.left - cop.left - co.left,
+                               width: w,
+                               height: h
+                       });
+               }
+       }
+});
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+       start: function() {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       _store = function(exp) {
+                               $(exp).each(function() {
+                                       var el = $(this);
+                                       el.data("ui-resizable-alsoresize", {
+                                               width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+                                               left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
+                                       });
+                               });
+                       };
+
+               if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
+                       if (o.alsoResize.length) {
+                               o.alsoResize = o.alsoResize[0];
+                               _store(o.alsoResize);
+                       } else {
+                               $.each(o.alsoResize, function(exp) {
+                                       _store(exp);
+                               });
+                       }
+               } else {
+                       _store(o.alsoResize);
+               }
+       },
+
+       resize: function(event, ui) {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       os = that.originalSize,
+                       op = that.originalPosition,
+                       delta = {
+                               height: (that.size.height - os.height) || 0,
+                               width: (that.size.width - os.width) || 0,
+                               top: (that.position.top - op.top) || 0,
+                               left: (that.position.left - op.left) || 0
+                       },
+
+                       _alsoResize = function(exp, c) {
+                               $(exp).each(function() {
+                                       var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
+                                               css = c && c.length ?
+                                                       c :
+                                                       el.parents(ui.originalElement[0]).length ?
+                                                               [ "width", "height" ] :
+                                                               [ "width", "height", "top", "left" ];
+
+                                       $.each(css, function(i, prop) {
+                                               var sum = (start[prop] || 0) + (delta[prop] || 0);
+                                               if (sum && sum >= 0) {
+                                                       style[prop] = sum || null;
+                                               }
+                                       });
+
+                                       el.css(style);
+                               });
+                       };
+
+               if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
+                       $.each(o.alsoResize, function(exp, c) {
+                               _alsoResize(exp, c);
+                       });
+               } else {
+                       _alsoResize(o.alsoResize);
+               }
+       },
+
+       stop: function() {
+               $(this).removeData("resizable-alsoresize");
+       }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+       start: function() {
+
+               var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
+
+               that.ghost = that.originalElement.clone();
+               that.ghost
+                       .css({
+                               opacity: 0.25,
+                               display: "block",
+                               position: "relative",
+                               height: cs.height,
+                               width: cs.width,
+                               margin: 0,
+                               left: 0,
+                               top: 0
+                       })
+                       .addClass("ui-resizable-ghost")
+                       .addClass(typeof o.ghost === "string" ? o.ghost : "");
+
+               that.ghost.appendTo(that.helper);
+
+       },
+
+       resize: function() {
+               var that = $(this).resizable( "instance" );
+               if (that.ghost) {
+                       that.ghost.css({
+                               position: "relative",
+                               height: that.size.height,
+                               width: that.size.width
+                       });
+               }
+       },
+
+       stop: function() {
+               var that = $(this).resizable( "instance" );
+               if (that.ghost && that.helper) {
+                       that.helper.get(0).removeChild(that.ghost.get(0));
+               }
+       }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+       resize: function() {
+               var outerDimensions,
+                       that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       cs = that.size,
+                       os = that.originalSize,
+                       op = that.originalPosition,
+                       a = that.axis,
+                       grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
+                       gridX = (grid[0] || 1),
+                       gridY = (grid[1] || 1),
+                       ox = Math.round((cs.width - os.width) / gridX) * gridX,
+                       oy = Math.round((cs.height - os.height) / gridY) * gridY,
+                       newWidth = os.width + ox,
+                       newHeight = os.height + oy,
+                       isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
+                       isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
+                       isMinWidth = o.minWidth && (o.minWidth > newWidth),
+                       isMinHeight = o.minHeight && (o.minHeight > newHeight);
+
+               o.grid = grid;
+
+               if (isMinWidth) {
+                       newWidth += gridX;
+               }
+               if (isMinHeight) {
+                       newHeight += gridY;
+               }
+               if (isMaxWidth) {
+                       newWidth -= gridX;
+               }
+               if (isMaxHeight) {
+                       newHeight -= gridY;
+               }
+
+               if (/^(se|s|e)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+               } else if (/^(ne)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+                       that.position.top = op.top - oy;
+               } else if (/^(sw)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+                       that.position.left = op.left - ox;
+               } else {
+                       if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
+                               outerDimensions = that._getPaddingPlusBorderDimensions( this );
+                       }
+
+                       if ( newHeight - gridY > 0 ) {
+                               that.size.height = newHeight;
+                               that.position.top = op.top - oy;
+                       } else {
+                               newHeight = gridY - outerDimensions.height;
+                               that.size.height = newHeight;
+                               that.position.top = op.top + os.height - newHeight;
+                       }
+                       if ( newWidth - gridX > 0 ) {
+                               that.size.width = newWidth;
+                               that.position.left = op.left - ox;
+                       } else {
+                               newWidth = gridX - outerDimensions.width;
+                               that.size.width = newWidth;
+                               that.position.left = op.left + os.width - newWidth;
+                       }
+               }
+       }
+
+});
+
+var resizable = $.ui.resizable;
+
+
+/*!
+ * jQuery UI Selectable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/selectable/
+ */
+
+
+var selectable = $.widget("ui.selectable", $.ui.mouse, {
+       version: "1.11.3",
+       options: {
+               appendTo: "body",
+               autoRefresh: true,
+               distance: 0,
+               filter: "*",
+               tolerance: "touch",
+
+               // callbacks
+               selected: null,
+               selecting: null,
+               start: null,
+               stop: null,
+               unselected: null,
+               unselecting: null
+       },
+       _create: function() {
+               var selectees,
+                       that = this;
+
+               this.element.addClass("ui-selectable");
+
+               this.dragged = false;
+
+               // cache selectee children based on filter
+               this.refresh = function() {
+                       selectees = $(that.options.filter, that.element[0]);
+                       selectees.addClass("ui-selectee");
+                       selectees.each(function() {
+                               var $this = $(this),
+                                       pos = $this.offset();
+                               $.data(this, "selectable-item", {
+                                       element: this,
+                                       $element: $this,
+                                       left: pos.left,
+                                       top: pos.top,
+                                       right: pos.left + $this.outerWidth(),
+                                       bottom: pos.top + $this.outerHeight(),
+                                       startselected: false,
+                                       selected: $this.hasClass("ui-selected"),
+                                       selecting: $this.hasClass("ui-selecting"),
+                                       unselecting: $this.hasClass("ui-unselecting")
+                               });
+                       });
+               };
+               this.refresh();
+
+               this.selectees = selectees.addClass("ui-selectee");
+
+               this._mouseInit();
+
+               this.helper = $("<div class='ui-selectable-helper'></div>");
+       },
+
+       _destroy: function() {
+               this.selectees
+                       .removeClass("ui-selectee")
+                       .removeData("selectable-item");
+               this.element
+                       .removeClass("ui-selectable ui-selectable-disabled");
+               this._mouseDestroy();
+       },
+
+       _mouseStart: function(event) {
+               var that = this,
+                       options = this.options;
+
+               this.opos = [ event.pageX, event.pageY ];
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               this.selectees = $(options.filter, this.element[0]);
+
+               this._trigger("start", event);
+
+               $(options.appendTo).append(this.helper);
+               // position helper (lasso)
+               this.helper.css({
+                       "left": event.pageX,
+                       "top": event.pageY,
+                       "width": 0,
+                       "height": 0
+               });
+
+               if (options.autoRefresh) {
+                       this.refresh();
+               }
+
+               this.selectees.filter(".ui-selected").each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.startselected = true;
+                       if (!event.metaKey && !event.ctrlKey) {
+                               selectee.$element.removeClass("ui-selected");
+                               selectee.selected = false;
+                               selectee.$element.addClass("ui-unselecting");
+                               selectee.unselecting = true;
+                               // selectable UNSELECTING callback
+                               that._trigger("unselecting", event, {
+                                       unselecting: selectee.element
+                               });
+                       }
+               });
+
+               $(event.target).parents().addBack().each(function() {
+                       var doSelect,
+                               selectee = $.data(this, "selectable-item");
+                       if (selectee) {
+                               doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
+                               selectee.$element
+                                       .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+                                       .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+                               selectee.unselecting = !doSelect;
+                               selectee.selecting = doSelect;
+                               selectee.selected = doSelect;
+                               // selectable (UN)SELECTING callback
+                               if (doSelect) {
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               } else {
+                                       that._trigger("unselecting", event, {
+                                               unselecting: selectee.element
+                                       });
+                               }
+                               return false;
+                       }
+               });
+
+       },
+
+       _mouseDrag: function(event) {
+
+               this.dragged = true;
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               var tmp,
+                       that = this,
+                       options = this.options,
+                       x1 = this.opos[0],
+                       y1 = this.opos[1],
+                       x2 = event.pageX,
+                       y2 = event.pageY;
+
+               if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
+               if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
+               this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
+
+               this.selectees.each(function() {
+                       var selectee = $.data(this, "selectable-item"),
+                               hit = false;
+
+                       //prevent helper from being selected if appendTo: selectable
+                       if (!selectee || selectee.element === that.element[0]) {
+                               return;
+                       }
+
+                       if (options.tolerance === "touch") {
+                               hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+                       } else if (options.tolerance === "fit") {
+                               hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+                       }
+
+                       if (hit) {
+                               // SELECT
+                               if (selectee.selected) {
+                                       selectee.$element.removeClass("ui-selected");
+                                       selectee.selected = false;
+                               }
+                               if (selectee.unselecting) {
+                                       selectee.$element.removeClass("ui-unselecting");
+                                       selectee.unselecting = false;
+                               }
+                               if (!selectee.selecting) {
+                                       selectee.$element.addClass("ui-selecting");
+                                       selectee.selecting = true;
+                                       // selectable SELECTING callback
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               }
+                       } else {
+                               // UNSELECT
+                               if (selectee.selecting) {
+                                       if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               selectee.$element.addClass("ui-selected");
+                                               selectee.selected = true;
+                                       } else {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               if (selectee.startselected) {
+                                                       selectee.$element.addClass("ui-unselecting");
+                                                       selectee.unselecting = true;
+                                               }
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                               if (selectee.selected) {
+                                       if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selected");
+                                               selectee.selected = false;
+
+                                               selectee.$element.addClass("ui-unselecting");
+                                               selectee.unselecting = true;
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                       }
+               });
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+               var that = this;
+
+               this.dragged = false;
+
+               $(".ui-unselecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-unselecting");
+                       selectee.unselecting = false;
+                       selectee.startselected = false;
+                       that._trigger("unselected", event, {
+                               unselected: selectee.element
+                       });
+               });
+               $(".ui-selecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
+                       selectee.selecting = false;
+                       selectee.selected = true;
+                       selectee.startselected = true;
+                       that._trigger("selected", event, {
+                               selected: selectee.element
+                       });
+               });
+               this._trigger("stop", event);
+
+               this.helper.remove();
+
+               return false;
+       }
+
+});
+
+
+/*!
+ * jQuery UI Sortable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/sortable/
+ */
+
+
+var sortable = $.widget("ui.sortable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "sort",
+       ready: false,
+       options: {
+               appendTo: "parent",
+               axis: false,
+               connectWith: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               dropOnEmpty: true,
+               forcePlaceholderSize: false,
+               forceHelperSize: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               items: "> *",
+               opacity: false,
+               placeholder: false,
+               revert: false,
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               scope: "default",
+               tolerance: "intersect",
+               zIndex: 1000,
+
+               // callbacks
+               activate: null,
+               beforeStop: null,
+               change: null,
+               deactivate: null,
+               out: null,
+               over: null,
+               receive: null,
+               remove: null,
+               sort: null,
+               start: null,
+               stop: null,
+               update: null
+       },
+
+       _isOverAxis: function( x, reference, size ) {
+               return ( x >= reference ) && ( x < ( reference + size ) );
+       },
+
+       _isFloating: function( item ) {
+               return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
+       },
+
+       _create: function() {
+
+               var o = this.options;
+               this.containerCache = {};
+               this.element.addClass("ui-sortable");
+
+               //Get the items
+               this.refresh();
+
+               //Let's determine if the items are being displayed horizontally
+               this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
+
+               //Let's determine the parent's offset
+               this.offset = this.element.offset();
+
+               //Initialize mouse events for interaction
+               this._mouseInit();
+
+               this._setHandleClassName();
+
+               //We're ready to go
+               this.ready = true;
+
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+
+               if ( key === "handle" ) {
+                       this._setHandleClassName();
+               }
+       },
+
+       _setHandleClassName: function() {
+               this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
+               $.each( this.items, function() {
+                       ( this.instance.options.handle ?
+                               this.item.find( this.instance.options.handle ) : this.item )
+                               .addClass( "ui-sortable-handle" );
+               });
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-sortable ui-sortable-disabled" )
+                       .find( ".ui-sortable-handle" )
+                               .removeClass( "ui-sortable-handle" );
+               this._mouseDestroy();
+
+               for ( var i = this.items.length - 1; i >= 0; i-- ) {
+                       this.items[i].item.removeData(this.widgetName + "-item");
+               }
+
+               return this;
+       },
+
+       _mouseCapture: function(event, overrideHandle) {
+               var currentItem = null,
+                       validHandle = false,
+                       that = this;
+
+               if (this.reverting) {
+                       return false;
+               }
+
+               if(this.options.disabled || this.options.type === "static") {
+                       return false;
+               }
+
+               //We have to refresh the items data once first
+               this._refreshItems(event);
+
+               //Find out if the clicked node (or one of its parents) is a actual item in this.items
+               $(event.target).parents().each(function() {
+                       if($.data(this, that.widgetName + "-item") === that) {
+                               currentItem = $(this);
+                               return false;
+                       }
+               });
+               if($.data(event.target, that.widgetName + "-item") === that) {
+                       currentItem = $(event.target);
+               }
+
+               if(!currentItem) {
+                       return false;
+               }
+               if(this.options.handle && !overrideHandle) {
+                       $(this.options.handle, currentItem).find("*").addBack().each(function() {
+                               if(this === event.target) {
+                                       validHandle = true;
+                               }
+                       });
+                       if(!validHandle) {
+                               return false;
+                       }
+               }
+
+               this.currentItem = currentItem;
+               this._removeCurrentsFromItems();
+               return true;
+
+       },
+
+       _mouseStart: function(event, overrideHandle, noActivation) {
+
+               var i, body,
+                       o = this.options;
+
+               this.currentContainer = this;
+
+               //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+               this.refreshPositions();
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Get the next scrolling parent
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.currentItem.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               // Only after we got the offset, we can change the helper's position to absolute
+               // TODO: Still need to figure out a way to make relative sorting possible
+               this.helper.css("position", "absolute");
+               this.cssPosition = this.helper.css("position");
+
+               //Generate the original position
+               this.originalPosition = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Cache the former DOM position
+               this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+               //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+               if(this.helper[0] !== this.currentItem[0]) {
+                       this.currentItem.hide();
+               }
+
+               //Create the placeholder
+               this._createPlaceholder();
+
+               //Set a containment if given in the options
+               if(o.containment) {
+                       this._setContainment();
+               }
+
+               if( o.cursor && o.cursor !== "auto" ) { // cursor option
+                       body = this.document.find( "body" );
+
+                       // support: IE
+                       this.storedCursor = body.css( "cursor" );
+                       body.css( "cursor", o.cursor );
+
+                       this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
+               }
+
+               if(o.opacity) { // opacity option
+                       if (this.helper.css("opacity")) {
+                               this._storedOpacity = this.helper.css("opacity");
+                       }
+                       this.helper.css("opacity", o.opacity);
+               }
+
+               if(o.zIndex) { // zIndex option
+                       if (this.helper.css("zIndex")) {
+                               this._storedZIndex = this.helper.css("zIndex");
+                       }
+                       this.helper.css("zIndex", o.zIndex);
+               }
+
+               //Prepare scrolling
+               if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
+                       this.overflowOffset = this.scrollParent.offset();
+               }
+
+               //Call callbacks
+               this._trigger("start", event, this._uiHash());
+
+               //Recache the helper size
+               if(!this._preserveHelperProportions) {
+                       this._cacheHelperProportions();
+               }
+
+
+               //Post "activate" events to possible containers
+               if( !noActivation ) {
+                       for ( i = this.containers.length - 1; i >= 0; i-- ) {
+                               this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
+                       }
+               }
+
+               //Prepare possible droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               this.dragging = true;
+
+               this.helper.addClass("ui-sortable-helper");
+               this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+               return true;
+
+       },
+
+       _mouseDrag: function(event) {
+               var i, item, itemElement, intersection,
+                       o = this.options,
+                       scrolled = false;
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               if (!this.lastPositionAbs) {
+                       this.lastPositionAbs = this.positionAbs;
+               }
+
+               //Do scrolling
+               if(this.options.scroll) {
+                       if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
+
+                               if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+                               } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+                               }
+
+                               if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+                               }
+
+                       } else {
+
+                               if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
+                               } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
+                               }
+
+                               if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
+                               } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
+                               }
+
+                       }
+
+                       if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                               $.ui.ddmanager.prepareOffsets(this, event);
+                       }
+               }
+
+               //Regenerate the absolute position used for position checks
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Set the helper position
+               if(!this.options.axis || this.options.axis !== "y") {
+                       this.helper[0].style.left = this.position.left+"px";
+               }
+               if(!this.options.axis || this.options.axis !== "x") {
+                       this.helper[0].style.top = this.position.top+"px";
+               }
+
+               //Rearrange
+               for (i = this.items.length - 1; i >= 0; i--) {
+
+                       //Cache variables and intersection, continue if no intersection
+                       item = this.items[i];
+                       itemElement = item.item[0];
+                       intersection = this._intersectsWithPointer(item);
+                       if (!intersection) {
+                               continue;
+                       }
+
+                       // Only put the placeholder inside the current Container, skip all
+                       // items from other containers. This works because when moving
+                       // an item from one container to another the
+                       // currentContainer is switched before the placeholder is moved.
+                       //
+                       // Without this, moving items in "sub-sortables" can cause
+                       // the placeholder to jitter between the outer and inner container.
+                       if (item.instance !== this.currentContainer) {
+                               continue;
+                       }
+
+                       // cannot intersect with itself
+                       // no useless actions that have been done before
+                       // no action if the item moved is the parent of the item checked
+                       if (itemElement !== this.currentItem[0] &&
+                               this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
+                               !$.contains(this.placeholder[0], itemElement) &&
+                               (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
+                       ) {
+
+                               this.direction = intersection === 1 ? "down" : "up";
+
+                               if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
+                                       this._rearrange(event, item);
+                               } else {
+                                       break;
+                               }
+
+                               this._trigger("change", event, this._uiHash());
+                               break;
+                       }
+               }
+
+               //Post events to containers
+               this._contactContainers(event);
+
+               //Interconnect with droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               //Call callbacks
+               this._trigger("sort", event, this._uiHash());
+
+               this.lastPositionAbs = this.positionAbs;
+               return false;
+
+       },
+
+       _mouseStop: function(event, noPropagation) {
+
+               if(!event) {
+                       return;
+               }
+
+               //If we are using droppables, inform the manager about the drop
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       $.ui.ddmanager.drop(this, event);
+               }
+
+               if(this.options.revert) {
+                       var that = this,
+                               cur = this.placeholder.offset(),
+                               axis = this.options.axis,
+                               animation = {};
+
+                       if ( !axis || axis === "x" ) {
+                               animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
+                       }
+                       if ( !axis || axis === "y" ) {
+                               animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
+                       }
+                       this.reverting = true;
+                       $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
+                               that._clear(event);
+                       });
+               } else {
+                       this._clear(event, noPropagation);
+               }
+
+               return false;
+
+       },
+
+       cancel: function() {
+
+               if(this.dragging) {
+
+                       this._mouseUp({ target: null });
+
+                       if(this.options.helper === "original") {
+                               this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+                       } else {
+                               this.currentItem.show();
+                       }
+
+                       //Post deactivating events to containers
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               this.containers[i]._trigger("deactivate", null, this._uiHash(this));
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", null, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               if (this.placeholder) {
+                       //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+                       if(this.placeholder[0].parentNode) {
+                               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+                       }
+                       if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
+                               this.helper.remove();
+                       }
+
+                       $.extend(this, {
+                               helper: null,
+                               dragging: false,
+                               reverting: false,
+                               _noFinalSort: null
+                       });
+
+                       if(this.domPosition.prev) {
+                               $(this.domPosition.prev).after(this.currentItem);
+                       } else {
+                               $(this.domPosition.parent).prepend(this.currentItem);
+                       }
+               }
+
+               return this;
+
+       },
+
+       serialize: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       str = [];
+               o = o || {};
+
+               $(items).each(function() {
+                       var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
+                       if (res) {
+                               str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
+                       }
+               });
+
+               if(!str.length && o.key) {
+                       str.push(o.key + "=");
+               }
+
+               return str.join("&");
+
+       },
+
+       toArray: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       ret = [];
+
+               o = o || {};
+
+               items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
+               return ret;
+
+       },
+
+       /* Be careful with the following core functions */
+       _intersectsWith: function(item) {
+
+               var x1 = this.positionAbs.left,
+                       x2 = x1 + this.helperProportions.width,
+                       y1 = this.positionAbs.top,
+                       y2 = y1 + this.helperProportions.height,
+                       l = item.left,
+                       r = l + item.width,
+                       t = item.top,
+                       b = t + item.height,
+                       dyClick = this.offset.click.top,
+                       dxClick = this.offset.click.left,
+                       isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
+                       isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
+                       isOverElement = isOverElementHeight && isOverElementWidth;
+
+               if ( this.options.tolerance === "pointer" ||
+                       this.options.forcePointerForContainers ||
+                       (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
+               ) {
+                       return isOverElement;
+               } else {
+
+                       return (l < x1 + (this.helperProportions.width / 2) && // Right Half
+                               x2 - (this.helperProportions.width / 2) < r && // Left Half
+                               t < y1 + (this.helperProportions.height / 2) && // Bottom Half
+                               y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+               }
+       },
+
+       _intersectsWithPointer: function(item) {
+
+               var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+                       isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+                       isOverElement = isOverElementHeight && isOverElementWidth,
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (!isOverElement) {
+                       return false;
+               }
+
+               return this.floating ?
+                       ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
+                       : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
+
+       },
+
+       _intersectsWithSides: function(item) {
+
+               var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+                       isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (this.floating && horizontalDirection) {
+                       return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
+               } else {
+                       return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
+               }
+
+       },
+
+       _getDragVerticalDirection: function() {
+               var delta = this.positionAbs.top - this.lastPositionAbs.top;
+               return delta !== 0 && (delta > 0 ? "down" : "up");
+       },
+
+       _getDragHorizontalDirection: function() {
+               var delta = this.positionAbs.left - this.lastPositionAbs.left;
+               return delta !== 0 && (delta > 0 ? "right" : "left");
+       },
+
+       refresh: function(event) {
+               this._refreshItems(event);
+               this._setHandleClassName();
+               this.refreshPositions();
+               return this;
+       },
+
+       _connectWith: function() {
+               var options = this.options;
+               return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
+       },
+
+       _getItemsAsjQuery: function(connected) {
+
+               var i, j, cur, inst,
+                       items = [],
+                       queries = [],
+                       connectWith = this._connectWith();
+
+               if(connectWith && connected) {
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i], this.document[0]);
+                               for ( j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
+                                       }
+                               }
+                       }
+               }
+
+               queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
+
+               function addItems() {
+                       items.push( this );
+               }
+               for (i = queries.length - 1; i >= 0; i--){
+                       queries[i][0].each( addItems );
+               }
+
+               return $(items);
+
+       },
+
+       _removeCurrentsFromItems: function() {
+
+               var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
+
+               this.items = $.grep(this.items, function (item) {
+                       for (var j=0; j < list.length; j++) {
+                               if(list[j] === item.item[0]) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               });
+
+       },
+
+       _refreshItems: function(event) {
+
+               this.items = [];
+               this.containers = [this];
+
+               var i, j, cur, inst, targetData, _queries, item, queriesLength,
+                       items = this.items,
+                       queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
+                       connectWith = this._connectWith();
+
+               if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i], this.document[0]);
+                               for (j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+                                               this.containers.push(inst);
+                                       }
+                               }
+                       }
+               }
+
+               for (i = queries.length - 1; i >= 0; i--) {
+                       targetData = queries[i][1];
+                       _queries = queries[i][0];
+
+                       for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+                               item = $(_queries[j]);
+
+                               item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
+
+                               items.push({
+                                       item: item,
+                                       instance: targetData,
+                                       width: 0, height: 0,
+                                       left: 0, top: 0
+                               });
+                       }
+               }
+
+       },
+
+       refreshPositions: function(fast) {
+
+               //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+               if(this.offsetParent && this.helper) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               var i, item, t, p;
+
+               for (i = this.items.length - 1; i >= 0; i--){
+                       item = this.items[i];
+
+                       //We ignore calculating positions of all connected containers when we're not over them
+                       if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
+                               continue;
+                       }
+
+                       t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+                       if (!fast) {
+                               item.width = t.outerWidth();
+                               item.height = t.outerHeight();
+                       }
+
+                       p = t.offset();
+                       item.left = p.left;
+                       item.top = p.top;
+               }
+
+               if(this.options.custom && this.options.custom.refreshContainers) {
+                       this.options.custom.refreshContainers.call(this);
+               } else {
+                       for (i = this.containers.length - 1; i >= 0; i--){
+                               p = this.containers[i].element.offset();
+                               this.containers[i].containerCache.left = p.left;
+                               this.containers[i].containerCache.top = p.top;
+                               this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+                               this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+                       }
+               }
+
+               return this;
+       },
+
+       _createPlaceholder: function(that) {
+               that = that || this;
+               var className,
+                       o = that.options;
+
+               if(!o.placeholder || o.placeholder.constructor === String) {
+                       className = o.placeholder;
+                       o.placeholder = {
+                               element: function() {
+
+                                       var nodeName = that.currentItem[0].nodeName.toLowerCase(),
+                                               element = $( "<" + nodeName + ">", that.document[0] )
+                                                       .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
+                                                       .removeClass("ui-sortable-helper");
+
+                                       if ( nodeName === "tr" ) {
+                                               that.currentItem.children().each(function() {
+                                                       $( "<td>&#160;</td>", that.document[0] )
+                                                               .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
+                                                               .appendTo( element );
+                                               });
+                                       } else if ( nodeName === "img" ) {
+                                               element.attr( "src", that.currentItem.attr( "src" ) );
+                                       }
+
+                                       if ( !className ) {
+                                               element.css( "visibility", "hidden" );
+                                       }
+
+                                       return element;
+                               },
+                               update: function(container, p) {
+
+                                       // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+                                       // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+                                       if(className && !o.forcePlaceholderSize) {
+                                               return;
+                                       }
+
+                                       //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+                                       if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
+                                       if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
+                               }
+                       };
+               }
+
+               //Create the placeholder
+               that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
+
+               //Append it after the actual current item
+               that.currentItem.after(that.placeholder);
+
+               //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+               o.placeholder.update(that, that.placeholder);
+
+       },
+
+       _contactContainers: function(event) {
+               var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
+                       innermostContainer = null,
+                       innermostIndex = null;
+
+               // get innermost container that intersects with item
+               for (i = this.containers.length - 1; i >= 0; i--) {
+
+                       // never consider a container that's located within the item itself
+                       if($.contains(this.currentItem[0], this.containers[i].element[0])) {
+                               continue;
+                       }
+
+                       if(this._intersectsWith(this.containers[i].containerCache)) {
+
+                               // if we've already found a container and it's more "inner" than this, then continue
+                               if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
+                                       continue;
+                               }
+
+                               innermostContainer = this.containers[i];
+                               innermostIndex = i;
+
+                       } else {
+                               // container doesn't intersect. trigger "out" event if necessary
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", event, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               // if no intersecting containers found, return
+               if(!innermostContainer) {
+                       return;
+               }
+
+               // move the item into the container if it's not there already
+               if(this.containers.length === 1) {
+                       if (!this.containers[innermostIndex].containerCache.over) {
+                               this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                               this.containers[innermostIndex].containerCache.over = 1;
+                       }
+               } else {
+
+                       //When entering a new container, we will find the item with the least distance and append our item near it
+                       dist = 10000;
+                       itemWithLeastDistance = null;
+                       floating = innermostContainer.floating || this._isFloating(this.currentItem);
+                       posProperty = floating ? "left" : "top";
+                       sizeProperty = floating ? "width" : "height";
+                       axis = floating ? "clientX" : "clientY";
+
+                       for (j = this.items.length - 1; j >= 0; j--) {
+                               if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
+                                       continue;
+                               }
+                               if(this.items[j].item[0] === this.currentItem[0]) {
+                                       continue;
+                               }
+
+                               cur = this.items[j].item.offset()[posProperty];
+                               nearBottom = false;
+                               if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
+                                       nearBottom = true;
+                               }
+
+                               if ( Math.abs( event[ axis ] - cur ) < dist ) {
+                                       dist = Math.abs( event[ axis ] - cur );
+                                       itemWithLeastDistance = this.items[ j ];
+                                       this.direction = nearBottom ? "up": "down";
+                               }
+                       }
+
+                       //Check if dropOnEmpty is enabled
+                       if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
+                               return;
+                       }
+
+                       if(this.currentContainer === this.containers[innermostIndex]) {
+                               if ( !this.currentContainer.containerCache.over ) {
+                                       this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
+                                       this.currentContainer.containerCache.over = 1;
+                               }
+                               return;
+                       }
+
+                       itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+                       this._trigger("change", event, this._uiHash());
+                       this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+                       this.currentContainer = this.containers[innermostIndex];
+
+                       //Update the placeholder
+                       this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                       this.containers[innermostIndex].containerCache.over = 1;
+               }
+
+
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
+
+               //Add the helper to the DOM if that didn't happen already
+               if(!helper.parents("body").length) {
+                       $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+               }
+
+               if(helper[0] === this.currentItem[0]) {
+                       this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+               }
+
+               if(!helper[0].style.width || o.forceHelperSize) {
+                       helper.width(this.currentItem.width());
+               }
+               if(!helper[0].style.height || o.forceHelperSize) {
+                       helper.height(this.currentItem.height());
+               }
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               // This needs to be actually done for all browsers, since pageX/pageY includes this information
+               // with an ugly IE fix
+               if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition === "relative") {
+                       var p = this.currentItem.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var ce, co, over,
+                       o = this.options;
+               if(o.containment === "parent") {
+                       o.containment = this.helper[0].parentNode;
+               }
+               if(o.containment === "document" || o.containment === "window") {
+                       this.containment = [
+                               0 - this.offset.relative.left - this.offset.parent.left,
+                               0 - this.offset.relative.top - this.offset.parent.top,
+                               o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
+                               (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+               if(!(/^(document|window|parent)$/).test(o.containment)) {
+                       ce = $(o.containment)[0];
+                       co = $(o.containment).offset();
+                       over = ($(ce).css("overflow") !== "hidden");
+
+                       this.containment = [
+                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) {
+                       pos = this.position;
+               }
+               var mod = d === "absolute" ? 1 : -1,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
+                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var top, left,
+                       o = this.options,
+                       pageX = event.pageX,
+                       pageY = event.pageY,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               // This is another very weird special case that only happens for relative elements:
+               // 1. If the css position is relative
+               // 2. and the scroll parent is the document or similar to the offset parent
+               // we have to refresh the relative offset during the scroll so there are no jumps
+               if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
+                       this.offset.relative = this._getRelativeOffset();
+               }
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+                       if(this.containment) {
+                               if(event.pageX - this.offset.click.left < this.containment[0]) {
+                                       pageX = this.containment[0] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top < this.containment[1]) {
+                                       pageY = this.containment[1] + this.offset.click.top;
+                               }
+                               if(event.pageX - this.offset.click.left > this.containment[2]) {
+                                       pageX = this.containment[2] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top > this.containment[3]) {
+                                       pageY = this.containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if(o.grid) {
+                               top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+                               pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+                               pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                         // The absolute mouse position
+                               this.offset.click.top -                                                                                                 // Click offset (relative to the element)
+                               this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX -                                                                                                                         // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _rearrange: function(event, i, a, hardRefresh) {
+
+               a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
+
+               //Various things done here to improve the performance:
+               // 1. we create a setTimeout, that calls refreshPositions
+               // 2. on the instance, we have a counter variable, that get's higher after every append
+               // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+               // 4. this lets only the last addition to the timeout stack through
+               this.counter = this.counter ? ++this.counter : 1;
+               var counter = this.counter;
+
+               this._delay(function() {
+                       if(counter === this.counter) {
+                               this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+                       }
+               });
+
+       },
+
+       _clear: function(event, noPropagation) {
+
+               this.reverting = false;
+               // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+               // everything else normalized again
+               var i,
+                       delayedTriggers = [];
+
+               // We first have to update the dom position of the actual currentItem
+               // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+               if(!this._noFinalSort && this.currentItem.parent().length) {
+                       this.placeholder.before(this.currentItem);
+               }
+               this._noFinalSort = null;
+
+               if(this.helper[0] === this.currentItem[0]) {
+                       for(i in this._storedCSS) {
+                               if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
+                                       this._storedCSS[i] = "";
+                               }
+                       }
+                       this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+               } else {
+                       this.currentItem.show();
+               }
+
+               if(this.fromOutside && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+               }
+               if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+               }
+
+               // Check if the items Container has Changed and trigger appropriate
+               // events.
+               if (this !== this.currentContainer) {
+                       if(!noPropagation) {
+                               delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
+                       }
+               }
+
+
+               //Post events to containers
+               function delayEvent( type, instance, container ) {
+                       return function( event ) {
+                               container._trigger( type, event, instance._uiHash( instance ) );
+                       };
+               }
+               for (i = this.containers.length - 1; i >= 0; i--){
+                       if (!noPropagation) {
+                               delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
+                       }
+                       if(this.containers[i].containerCache.over) {
+                               delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
+                               this.containers[i].containerCache.over = 0;
+                       }
+               }
+
+               //Do what was originally in plugins
+               if ( this.storedCursor ) {
+                       this.document.find( "body" ).css( "cursor", this.storedCursor );
+                       this.storedStylesheet.remove();
+               }
+               if(this._storedOpacity) {
+                       this.helper.css("opacity", this._storedOpacity);
+               }
+               if(this._storedZIndex) {
+                       this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
+               }
+
+               this.dragging = false;
+
+               if(!noPropagation) {
+                       this._trigger("beforeStop", event, this._uiHash());
+               }
+
+               //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+               if ( !this.cancelHelperRemoval ) {
+                       if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
+                               this.helper.remove();
+                       }
+                       this.helper = null;
+               }
+
+               if(!noPropagation) {
+                       for (i=0; i < delayedTriggers.length; i++) {
+                               delayedTriggers[i].call(this, event);
+                       } //Trigger all delayed events
+                       this._trigger("stop", event, this._uiHash());
+               }
+
+               this.fromOutside = false;
+               return !this.cancelHelperRemoval;
+
+       },
+
+       _trigger: function() {
+               if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+                       this.cancel();
+               }
+       },
+
+       _uiHash: function(_inst) {
+               var inst = _inst || this;
+               return {
+                       helper: inst.helper,
+                       placeholder: inst.placeholder || $([]),
+                       position: inst.position,
+                       originalPosition: inst.originalPosition,
+                       offset: inst.positionAbs,
+                       item: inst.currentItem,
+                       sender: _inst ? _inst.element : null
+               };
+       }
+
+});
+
+
+/*!
+ * jQuery UI Accordion 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/accordion/
+ */
+
+
+var accordion = $.widget( "ui.accordion", {
+       version: "1.11.3",
+       options: {
+               active: 0,
+               animate: {},
+               collapsible: false,
+               event: "click",
+               header: "> li > :first-child,> :not(li):even",
+               heightStyle: "auto",
+               icons: {
+                       activeHeader: "ui-icon-triangle-1-s",
+                       header: "ui-icon-triangle-1-e"
+               },
+
+               // callbacks
+               activate: null,
+               beforeActivate: null
+       },
+
+       hideProps: {
+               borderTopWidth: "hide",
+               borderBottomWidth: "hide",
+               paddingTop: "hide",
+               paddingBottom: "hide",
+               height: "hide"
+       },
+
+       showProps: {
+               borderTopWidth: "show",
+               borderBottomWidth: "show",
+               paddingTop: "show",
+               paddingBottom: "show",
+               height: "show"
+       },
+
+       _create: function() {
+               var options = this.options;
+               this.prevShow = this.prevHide = $();
+               this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
+                       // ARIA
+                       .attr( "role", "tablist" );
+
+               // don't allow collapsible: false and active: false / null
+               if ( !options.collapsible && (options.active === false || options.active == null) ) {
+                       options.active = 0;
+               }
+
+               this._processPanels();
+               // handle negative values
+               if ( options.active < 0 ) {
+                       options.active += this.headers.length;
+               }
+               this._refresh();
+       },
+
+       _getCreateEventData: function() {
+               return {
+                       header: this.active,
+                       panel: !this.active.length ? $() : this.active.next()
+               };
+       },
+
+       _createIcons: function() {
+               var icons = this.options.icons;
+               if ( icons ) {
+                       $( "<span>" )
+                               .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
+                               .prependTo( this.headers );
+                       this.active.children( ".ui-accordion-header-icon" )
+                               .removeClass( icons.header )
+                               .addClass( icons.activeHeader );
+                       this.headers.addClass( "ui-accordion-icons" );
+               }
+       },
+
+       _destroyIcons: function() {
+               this.headers
+                       .removeClass( "ui-accordion-icons" )
+                       .children( ".ui-accordion-header-icon" )
+                               .remove();
+       },
+
+       _destroy: function() {
+               var contents;
+
+               // clean up main element
+               this.element
+                       .removeClass( "ui-accordion ui-widget ui-helper-reset" )
+                       .removeAttr( "role" );
+
+               // clean up headers
+               this.headers
+                       .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
+                               "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-expanded" )
+                       .removeAttr( "aria-selected" )
+                       .removeAttr( "aria-controls" )
+                       .removeAttr( "tabIndex" )
+                       .removeUniqueId();
+
+               this._destroyIcons();
+
+               // clean up content panels
+               contents = this.headers.next()
+                       .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
+                               "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
+                       .css( "display", "" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-hidden" )
+                       .removeAttr( "aria-labelledby" )
+                       .removeUniqueId();
+
+               if ( this.options.heightStyle !== "content" ) {
+                       contents.css( "height", "" );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "active" ) {
+                       // _activate() will handle invalid values and update this.options
+                       this._activate( value );
+                       return;
+               }
+
+               if ( key === "event" ) {
+                       if ( this.options.event ) {
+                               this._off( this.headers, this.options.event );
+                       }
+                       this._setupEvents( value );
+               }
+
+               this._super( key, value );
+
+               // setting collapsible: false while collapsed; open first panel
+               if ( key === "collapsible" && !value && this.options.active === false ) {
+                       this._activate( 0 );
+               }
+
+               if ( key === "icons" ) {
+                       this._destroyIcons();
+                       if ( value ) {
+                               this._createIcons();
+                       }
+               }
+
+               // #5332 - opacity doesn't cascade to positioned elements in IE
+               // so we need to add the disabled class to the headers and panels
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+                       this.headers.add( this.headers.next() )
+                               .toggleClass( "ui-state-disabled", !!value );
+               }
+       },
+
+       _keydown: function( event ) {
+               if ( event.altKey || event.ctrlKey ) {
+                       return;
+               }
+
+               var keyCode = $.ui.keyCode,
+                       length = this.headers.length,
+                       currentIndex = this.headers.index( event.target ),
+                       toFocus = false;
+
+               switch ( event.keyCode ) {
+                       case keyCode.RIGHT:
+                       case keyCode.DOWN:
+                               toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+                               break;
+                       case keyCode.LEFT:
+                       case keyCode.UP:
+                               toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+                               break;
+                       case keyCode.SPACE:
+                       case keyCode.ENTER:
+                               this._eventHandler( event );
+                               break;
+                       case keyCode.HOME:
+                               toFocus = this.headers[ 0 ];
+                               break;
+                       case keyCode.END:
+                               toFocus = this.headers[ length - 1 ];
+                               break;
+               }
+
+               if ( toFocus ) {
+                       $( event.target ).attr( "tabIndex", -1 );
+                       $( toFocus ).attr( "tabIndex", 0 );
+                       toFocus.focus();
+                       event.preventDefault();
+               }
+       },
+
+       _panelKeyDown: function( event ) {
+               if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
+                       $( event.currentTarget ).prev().focus();
+               }
+       },
+
+       refresh: function() {
+               var options = this.options;
+               this._processPanels();
+
+               // was collapsed or no panel
+               if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
+                       options.active = false;
+                       this.active = $();
+               // active false only when collapsible is true
+               } else if ( options.active === false ) {
+                       this._activate( 0 );
+               // was active, but active panel is gone
+               } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+                       // all remaining panel are disabled
+                       if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
+                               options.active = false;
+                               this.active = $();
+                       // activate previous panel
+                       } else {
+                               this._activate( Math.max( 0, options.active - 1 ) );
+                       }
+               // was active, active panel still exists
+               } else {
+                       // make sure active index is correct
+                       options.active = this.headers.index( this.active );
+               }
+
+               this._destroyIcons();
+
+               this._refresh();
+       },
+
+       _processPanels: function() {
+               var prevHeaders = this.headers,
+                       prevPanels = this.panels;
+
+               this.headers = this.element.find( this.options.header )
+                       .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
+
+               this.panels = this.headers.next()
+                       .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
+                       .filter( ":not(.ui-accordion-content-active)" )
+                       .hide();
+
+               // Avoid memory leaks (#10056)
+               if ( prevPanels ) {
+                       this._off( prevHeaders.not( this.headers ) );
+                       this._off( prevPanels.not( this.panels ) );
+               }
+       },
+
+       _refresh: function() {
+               var maxHeight,
+                       options = this.options,
+                       heightStyle = options.heightStyle,
+                       parent = this.element.parent();
+
+               this.active = this._findActive( options.active )
+                       .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
+                       .removeClass( "ui-corner-all" );
+               this.active.next()
+                       .addClass( "ui-accordion-content-active" )
+                       .show();
+
+               this.headers
+                       .attr( "role", "tab" )
+                       .each(function() {
+                               var header = $( this ),
+                                       headerId = header.uniqueId().attr( "id" ),
+                                       panel = header.next(),
+                                       panelId = panel.uniqueId().attr( "id" );
+                               header.attr( "aria-controls", panelId );
+                               panel.attr( "aria-labelledby", headerId );
+                       })
+                       .next()
+                               .attr( "role", "tabpanel" );
+
+               this.headers
+                       .not( this.active )
+                       .attr({
+                               "aria-selected": "false",
+                               "aria-expanded": "false",
+                               tabIndex: -1
+                       })
+                       .next()
+                               .attr({
+                                       "aria-hidden": "true"
+                               })
+                               .hide();
+
+               // make sure at least one header is in the tab order
+               if ( !this.active.length ) {
+                       this.headers.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       this.active.attr({
+                               "aria-selected": "true",
+                               "aria-expanded": "true",
+                               tabIndex: 0
+                       })
+                       .next()
+                               .attr({
+                                       "aria-hidden": "false"
+                               });
+               }
+
+               this._createIcons();
+
+               this._setupEvents( options.event );
+
+               if ( heightStyle === "fill" ) {
+                       maxHeight = parent.height();
+                       this.element.siblings( ":visible" ).each(function() {
+                               var elem = $( this ),
+                                       position = elem.css( "position" );
+
+                               if ( position === "absolute" || position === "fixed" ) {
+                                       return;
+                               }
+                               maxHeight -= elem.outerHeight( true );
+                       });
+
+                       this.headers.each(function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       });
+
+                       this.headers.next()
+                               .each(function() {
+                                       $( this ).height( Math.max( 0, maxHeight -
+                                               $( this ).innerHeight() + $( this ).height() ) );
+                               })
+                               .css( "overflow", "auto" );
+               } else if ( heightStyle === "auto" ) {
+                       maxHeight = 0;
+                       this.headers.next()
+                               .each(function() {
+                                       maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
+                               })
+                               .height( maxHeight );
+               }
+       },
+
+       _activate: function( index ) {
+               var active = this._findActive( index )[ 0 ];
+
+               // trying to activate the already active panel
+               if ( active === this.active[ 0 ] ) {
+                       return;
+               }
+
+               // trying to collapse, simulate a click on the currently active header
+               active = active || this.active[ 0 ];
+
+               this._eventHandler({
+                       target: active,
+                       currentTarget: active,
+                       preventDefault: $.noop
+               });
+       },
+
+       _findActive: function( selector ) {
+               return typeof selector === "number" ? this.headers.eq( selector ) : $();
+       },
+
+       _setupEvents: function( event ) {
+               var events = {
+                       keydown: "_keydown"
+               };
+               if ( event ) {
+                       $.each( event.split( " " ), function( index, eventName ) {
+                               events[ eventName ] = "_eventHandler";
+                       });
+               }
+
+               this._off( this.headers.add( this.headers.next() ) );
+               this._on( this.headers, events );
+               this._on( this.headers.next(), { keydown: "_panelKeyDown" });
+               this._hoverable( this.headers );
+               this._focusable( this.headers );
+       },
+
+       _eventHandler: function( event ) {
+               var options = this.options,
+                       active = this.active,
+                       clicked = $( event.currentTarget ),
+                       clickedIsActive = clicked[ 0 ] === active[ 0 ],
+                       collapsing = clickedIsActive && options.collapsible,
+                       toShow = collapsing ? $() : clicked.next(),
+                       toHide = active.next(),
+                       eventData = {
+                               oldHeader: active,
+                               oldPanel: toHide,
+                               newHeader: collapsing ? $() : clicked,
+                               newPanel: toShow
+                       };
+
+               event.preventDefault();
+
+               if (
+                               // click on active header, but not collapsible
+                               ( clickedIsActive && !options.collapsible ) ||
+                               // allow canceling activation
+                               ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+                       return;
+               }
+
+               options.active = collapsing ? false : this.headers.index( clicked );
+
+               // when the call to ._toggle() comes after the class changes
+               // it causes a very odd bug in IE 8 (see #6720)
+               this.active = clickedIsActive ? $() : clicked;
+               this._toggle( eventData );
+
+               // switch classes
+               // corner classes on the previously active header stay after the animation
+               active.removeClass( "ui-accordion-header-active ui-state-active" );
+               if ( options.icons ) {
+                       active.children( ".ui-accordion-header-icon" )
+                               .removeClass( options.icons.activeHeader )
+                               .addClass( options.icons.header );
+               }
+
+               if ( !clickedIsActive ) {
+                       clicked
+                               .removeClass( "ui-corner-all" )
+                               .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
+                       if ( options.icons ) {
+                               clicked.children( ".ui-accordion-header-icon" )
+                                       .removeClass( options.icons.header )
+                                       .addClass( options.icons.activeHeader );
+                       }
+
+                       clicked
+                               .next()
+                               .addClass( "ui-accordion-content-active" );
+               }
+       },
+
+       _toggle: function( data ) {
+               var toShow = data.newPanel,
+                       toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
+
+               // handle activating a panel during the animation for another activation
+               this.prevShow.add( this.prevHide ).stop( true, true );
+               this.prevShow = toShow;
+               this.prevHide = toHide;
+
+               if ( this.options.animate ) {
+                       this._animate( toShow, toHide, data );
+               } else {
+                       toHide.hide();
+                       toShow.show();
+                       this._toggleComplete( data );
+               }
+
+               toHide.attr({
+                       "aria-hidden": "true"
+               });
+               toHide.prev().attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false"
+               });
+               // if we're switching panels, remove the old header from the tab order
+               // if we're opening from collapsed state, remove the previous header from the tab order
+               // if we're collapsing, then keep the collapsing header in the tab order
+               if ( toShow.length && toHide.length ) {
+                       toHide.prev().attr({
+                               "tabIndex": -1,
+                               "aria-expanded": "false"
+                       });
+               } else if ( toShow.length ) {
+                       this.headers.filter(function() {
+                               return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
+                       })
+                       .attr( "tabIndex", -1 );
+               }
+
+               toShow
+                       .attr( "aria-hidden", "false" )
+                       .prev()
+                               .attr({
+                                       "aria-selected": "true",
+                                       "aria-expanded": "true",
+                                       tabIndex: 0
+                               });
+       },
+
+       _animate: function( toShow, toHide, data ) {
+               var total, easing, duration,
+                       that = this,
+                       adjust = 0,
+                       down = toShow.length &&
+                               ( !toHide.length || ( toShow.index() < toHide.index() ) ),
+                       animate = this.options.animate || {},
+                       options = down && animate.down || animate,
+                       complete = function() {
+                               that._toggleComplete( data );
+                       };
+
+               if ( typeof options === "number" ) {
+                       duration = options;
+               }
+               if ( typeof options === "string" ) {
+                       easing = options;
+               }
+               // fall back from options to animation in case of partial down settings
+               easing = easing || options.easing || animate.easing;
+               duration = duration || options.duration || animate.duration;
+
+               if ( !toHide.length ) {
+                       return toShow.animate( this.showProps, duration, easing, complete );
+               }
+               if ( !toShow.length ) {
+                       return toHide.animate( this.hideProps, duration, easing, complete );
+               }
+
+               total = toShow.show().outerHeight();
+               toHide.animate( this.hideProps, {
+                       duration: duration,
+                       easing: easing,
+                       step: function( now, fx ) {
+                               fx.now = Math.round( now );
+                       }
+               });
+               toShow
+                       .hide()
+                       .animate( this.showProps, {
+                               duration: duration,
+                               easing: easing,
+                               complete: complete,
+                               step: function( now, fx ) {
+                                       fx.now = Math.round( now );
+                                       if ( fx.prop !== "height" ) {
+                                               adjust += fx.now;
+                                       } else if ( that.options.heightStyle !== "content" ) {
+                                               fx.now = Math.round( total - toHide.outerHeight() - adjust );
+                                               adjust = 0;
+                                       }
+                               }
+                       });
+       },
+
+       _toggleComplete: function( data ) {
+               var toHide = data.oldPanel;
+
+               toHide
+                       .removeClass( "ui-accordion-content-active" )
+                       .prev()
+                               .removeClass( "ui-corner-top" )
+                               .addClass( "ui-corner-all" );
+
+               // Work around for rendering bug in IE (#5421)
+               if ( toHide.length ) {
+                       toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
+               }
+               this._trigger( "activate", null, data );
+       }
+});
+
+
+/*!
+ * jQuery UI Menu 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/menu/
+ */
+
+
+var menu = $.widget( "ui.menu", {
+       version: "1.11.3",
+       defaultElement: "<ul>",
+       delay: 300,
+       options: {
+               icons: {
+                       submenu: "ui-icon-carat-1-e"
+               },
+               items: "> *",
+               menus: "ul",
+               position: {
+                       my: "left-1 top",
+                       at: "right top"
+               },
+               role: "menu",
+
+               // callbacks
+               blur: null,
+               focus: null,
+               select: null
+       },
+
+       _create: function() {
+               this.activeMenu = this.element;
+
+               // Flag used to prevent firing of the click handler
+               // as the event bubbles up through nested menus
+               this.mouseHandled = false;
+               this.element
+                       .uniqueId()
+                       .addClass( "ui-menu ui-widget ui-widget-content" )
+                       .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
+                       .attr({
+                               role: this.options.role,
+                               tabIndex: 0
+                       });
+
+               if ( this.options.disabled ) {
+                       this.element
+                               .addClass( "ui-state-disabled" )
+                               .attr( "aria-disabled", "true" );
+               }
+
+               this._on({
+                       // Prevent focus from sticking to links inside menu after clicking
+                       // them (focus should always stay on UL during navigation).
+                       "mousedown .ui-menu-item": function( event ) {
+                               event.preventDefault();
+                       },
+                       "click .ui-menu-item": function( event ) {
+                               var target = $( event.target );
+                               if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
+                                       this.select( event );
+
+                                       // Only set the mouseHandled flag if the event will bubble, see #9469.
+                                       if ( !event.isPropagationStopped() ) {
+                                               this.mouseHandled = true;
+                                       }
+
+                                       // Open submenu on click
+                                       if ( target.has( ".ui-menu" ).length ) {
+                                               this.expand( event );
+                                       } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
+
+                                               // Redirect focus to the menu
+                                               this.element.trigger( "focus", [ true ] );
+
+                                               // If the active item is on the top level, let it stay active.
+                                               // Otherwise, blur the active item since it is no longer visible.
+                                               if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
+                                                       clearTimeout( this.timer );
+                                               }
+                                       }
+                               }
+                       },
+                       "mouseenter .ui-menu-item": function( event ) {
+                               // Ignore mouse events while typeahead is active, see #10458.
+                               // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
+                               // is over an item in the menu
+                               if ( this.previousFilter ) {
+                                       return;
+                               }
+                               var target = $( event.currentTarget );
+                               // Remove ui-state-active class from siblings of the newly focused menu item
+                               // to avoid a jump caused by adjacent elements both having a class with a border
+                               target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
+                               this.focus( event, target );
+                       },
+                       mouseleave: "collapseAll",
+                       "mouseleave .ui-menu": "collapseAll",
+                       focus: function( event, keepActiveItem ) {
+                               // If there's already an active item, keep it active
+                               // If not, activate the first item
+                               var item = this.active || this.element.find( this.options.items ).eq( 0 );
+
+                               if ( !keepActiveItem ) {
+                                       this.focus( event, item );
+                               }
+                       },
+                       blur: function( event ) {
+                               this._delay(function() {
+                                       if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
+                                               this.collapseAll( event );
+                                       }
+                               });
+                       },
+                       keydown: "_keydown"
+               });
+
+               this.refresh();
+
+               // Clicks outside of a menu collapse any open menus
+               this._on( this.document, {
+                       click: function( event ) {
+                               if ( this._closeOnDocumentClick( event ) ) {
+                                       this.collapseAll( event );
+                               }
+
+                               // Reset the mouseHandled flag
+                               this.mouseHandled = false;
+                       }
+               });
+       },
+
+       _destroy: function() {
+               // Destroy (sub)menus
+               this.element
+                       .removeAttr( "aria-activedescendant" )
+                       .find( ".ui-menu" ).addBack()
+                               .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
+                               .removeAttr( "role" )
+                               .removeAttr( "tabIndex" )
+                               .removeAttr( "aria-labelledby" )
+                               .removeAttr( "aria-expanded" )
+                               .removeAttr( "aria-hidden" )
+                               .removeAttr( "aria-disabled" )
+                               .removeUniqueId()
+                               .show();
+
+               // Destroy menu items
+               this.element.find( ".ui-menu-item" )
+                       .removeClass( "ui-menu-item" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-disabled" )
+                       .removeUniqueId()
+                       .removeClass( "ui-state-hover" )
+                       .removeAttr( "tabIndex" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-haspopup" )
+                       .children().each( function() {
+                               var elem = $( this );
+                               if ( elem.data( "ui-menu-submenu-carat" ) ) {
+                                       elem.remove();
+                               }
+                       });
+
+               // Destroy menu dividers
+               this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
+       },
+
+       _keydown: function( event ) {
+               var match, prev, character, skip,
+                       preventDefault = true;
+
+               switch ( event.keyCode ) {
+               case $.ui.keyCode.PAGE_UP:
+                       this.previousPage( event );
+                       break;
+               case $.ui.keyCode.PAGE_DOWN:
+                       this.nextPage( event );
+                       break;
+               case $.ui.keyCode.HOME:
+                       this._move( "first", "first", event );
+                       break;
+               case $.ui.keyCode.END:
+                       this._move( "last", "last", event );
+                       break;
+               case $.ui.keyCode.UP:
+                       this.previous( event );
+                       break;
+               case $.ui.keyCode.DOWN:
+                       this.next( event );
+                       break;
+               case $.ui.keyCode.LEFT:
+                       this.collapse( event );
+                       break;
+               case $.ui.keyCode.RIGHT:
+                       if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
+                               this.expand( event );
+                       }
+                       break;
+               case $.ui.keyCode.ENTER:
+               case $.ui.keyCode.SPACE:
+                       this._activate( event );
+                       break;
+               case $.ui.keyCode.ESCAPE:
+                       this.collapse( event );
+                       break;
+               default:
+                       preventDefault = false;
+                       prev = this.previousFilter || "";
+                       character = String.fromCharCode( event.keyCode );
+                       skip = false;
+
+                       clearTimeout( this.filterTimer );
+
+                       if ( character === prev ) {
+                               skip = true;
+                       } else {
+                               character = prev + character;
+                       }
+
+                       match = this._filterMenuItems( character );
+                       match = skip && match.index( this.active.next() ) !== -1 ?
+                               this.active.nextAll( ".ui-menu-item" ) :
+                               match;
+
+                       // If no matches on the current filter, reset to the last character pressed
+                       // to move down the menu to the first item that starts with that character
+                       if ( !match.length ) {
+                               character = String.fromCharCode( event.keyCode );
+                               match = this._filterMenuItems( character );
+                       }
+
+                       if ( match.length ) {
+                               this.focus( event, match );
+                               this.previousFilter = character;
+                               this.filterTimer = this._delay(function() {
+                                       delete this.previousFilter;
+                               }, 1000 );
+                       } else {
+                               delete this.previousFilter;
+                       }
+               }
+
+               if ( preventDefault ) {
+                       event.preventDefault();
+               }
+       },
+
+       _activate: function( event ) {
+               if ( !this.active.is( ".ui-state-disabled" ) ) {
+                       if ( this.active.is( "[aria-haspopup='true']" ) ) {
+                               this.expand( event );
+                       } else {
+                               this.select( event );
+                       }
+               }
+       },
+
+       refresh: function() {
+               var menus, items,
+                       that = this,
+                       icon = this.options.icons.submenu,
+                       submenus = this.element.find( this.options.menus );
+
+               this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
+
+               // Initialize nested menus
+               submenus.filter( ":not(.ui-menu)" )
+                       .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
+                       .hide()
+                       .attr({
+                               role: this.options.role,
+                               "aria-hidden": "true",
+                               "aria-expanded": "false"
+                       })
+                       .each(function() {
+                               var menu = $( this ),
+                                       item = menu.parent(),
+                                       submenuCarat = $( "<span>" )
+                                               .addClass( "ui-menu-icon ui-icon " + icon )
+                                               .data( "ui-menu-submenu-carat", true );
+
+                               item
+                                       .attr( "aria-haspopup", "true" )
+                                       .prepend( submenuCarat );
+                               menu.attr( "aria-labelledby", item.attr( "id" ) );
+                       });
+
+               menus = submenus.add( this.element );
+               items = menus.find( this.options.items );
+
+               // Initialize menu-items containing spaces and/or dashes only as dividers
+               items.not( ".ui-menu-item" ).each(function() {
+                       var item = $( this );
+                       if ( that._isDivider( item ) ) {
+                               item.addClass( "ui-widget-content ui-menu-divider" );
+                       }
+               });
+
+               // Don't refresh list items that are already adapted
+               items.not( ".ui-menu-item, .ui-menu-divider" )
+                       .addClass( "ui-menu-item" )
+                       .uniqueId()
+                       .attr({
+                               tabIndex: -1,
+                               role: this._itemRole()
+                       });
+
+               // Add aria-disabled attribute to any disabled menu item
+               items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
+
+               // If the active item has been removed, blur the menu
+               if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+                       this.blur();
+               }
+       },
+
+       _itemRole: function() {
+               return {
+                       menu: "menuitem",
+                       listbox: "option"
+               }[ this.options.role ];
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "icons" ) {
+                       this.element.find( ".ui-menu-icon" )
+                               .removeClass( this.options.icons.submenu )
+                               .addClass( value.submenu );
+               }
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+               }
+               this._super( key, value );
+       },
+
+       focus: function( event, item ) {
+               var nested, focused;
+               this.blur( event, event && event.type === "focus" );
+
+               this._scrollIntoView( item );
+
+               this.active = item.first();
+               focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
+               // Only update aria-activedescendant if there's a role
+               // otherwise we assume focus is managed elsewhere
+               if ( this.options.role ) {
+                       this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
+               }
+
+               // Highlight active parent menu item, if any
+               this.active
+                       .parent()
+                       .closest( ".ui-menu-item" )
+                       .addClass( "ui-state-active" );
+
+               if ( event && event.type === "keydown" ) {
+                       this._close();
+               } else {
+                       this.timer = this._delay(function() {
+                               this._close();
+                       }, this.delay );
+               }
+
+               nested = item.children( ".ui-menu" );
+               if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
+                       this._startOpening(nested);
+               }
+               this.activeMenu = item.parent();
+
+               this._trigger( "focus", event, { item: item } );
+       },
+
+       _scrollIntoView: function( item ) {
+               var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
+               if ( this._hasScroll() ) {
+                       borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
+                       paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
+                       offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
+                       scroll = this.activeMenu.scrollTop();
+                       elementHeight = this.activeMenu.height();
+                       itemHeight = item.outerHeight();
+
+                       if ( offset < 0 ) {
+                               this.activeMenu.scrollTop( scroll + offset );
+                       } else if ( offset + itemHeight > elementHeight ) {
+                               this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
+                       }
+               }
+       },
+
+       blur: function( event, fromFocus ) {
+               if ( !fromFocus ) {
+                       clearTimeout( this.timer );
+               }
+
+               if ( !this.active ) {
+                       return;
+               }
+
+               this.active.removeClass( "ui-state-focus" );
+               this.active = null;
+
+               this._trigger( "blur", event, { item: this.active } );
+       },
+
+       _startOpening: function( submenu ) {
+               clearTimeout( this.timer );
+
+               // Don't open if already open fixes a Firefox bug that caused a .5 pixel
+               // shift in the submenu position when mousing over the carat icon
+               if ( submenu.attr( "aria-hidden" ) !== "true" ) {
+                       return;
+               }
+
+               this.timer = this._delay(function() {
+                       this._close();
+                       this._open( submenu );
+               }, this.delay );
+       },
+
+       _open: function( submenu ) {
+               var position = $.extend({
+                       of: this.active
+               }, this.options.position );
+
+               clearTimeout( this.timer );
+               this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
+                       .hide()
+                       .attr( "aria-hidden", "true" );
+
+               submenu
+                       .show()
+                       .removeAttr( "aria-hidden" )
+                       .attr( "aria-expanded", "true" )
+                       .position( position );
+       },
+
+       collapseAll: function( event, all ) {
+               clearTimeout( this.timer );
+               this.timer = this._delay(function() {
+                       // If we were passed an event, look for the submenu that contains the event
+                       var currentMenu = all ? this.element :
+                               $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
+
+                       // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
+                       if ( !currentMenu.length ) {
+                               currentMenu = this.element;
+                       }
+
+                       this._close( currentMenu );
+
+                       this.blur( event );
+                       this.activeMenu = currentMenu;
+               }, this.delay );
+       },
+
+       // With no arguments, closes the currently active menu - if nothing is active
+       // it closes all menus.  If passed an argument, it will search for menus BELOW
+       _close: function( startMenu ) {
+               if ( !startMenu ) {
+                       startMenu = this.active ? this.active.parent() : this.element;
+               }
+
+               startMenu
+                       .find( ".ui-menu" )
+                               .hide()
+                               .attr( "aria-hidden", "true" )
+                               .attr( "aria-expanded", "false" )
+                       .end()
+                       .find( ".ui-state-active" ).not( ".ui-state-focus" )
+                               .removeClass( "ui-state-active" );
+       },
+
+       _closeOnDocumentClick: function( event ) {
+               return !$( event.target ).closest( ".ui-menu" ).length;
+       },
+
+       _isDivider: function( item ) {
+
+               // Match hyphen, em dash, en dash
+               return !/[^\-\u2014\u2013\s]/.test( item.text() );
+       },
+
+       collapse: function( event ) {
+               var newItem = this.active &&
+                       this.active.parent().closest( ".ui-menu-item", this.element );
+               if ( newItem && newItem.length ) {
+                       this._close();
+                       this.focus( event, newItem );
+               }
+       },
+
+       expand: function( event ) {
+               var newItem = this.active &&
+                       this.active
+                               .children( ".ui-menu " )
+                               .find( this.options.items )
+                               .first();
+
+               if ( newItem && newItem.length ) {
+                       this._open( newItem.parent() );
+
+                       // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
+                       this._delay(function() {
+                               this.focus( event, newItem );
+                       });
+               }
+       },
+
+       next: function( event ) {
+               this._move( "next", "first", event );
+       },
+
+       previous: function( event ) {
+               this._move( "prev", "last", event );
+       },
+
+       isFirstItem: function() {
+               return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
+       },
+
+       isLastItem: function() {
+               return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
+       },
+
+       _move: function( direction, filter, event ) {
+               var next;
+               if ( this.active ) {
+                       if ( direction === "first" || direction === "last" ) {
+                               next = this.active
+                                       [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
+                                       .eq( -1 );
+                       } else {
+                               next = this.active
+                                       [ direction + "All" ]( ".ui-menu-item" )
+                                       .eq( 0 );
+                       }
+               }
+               if ( !next || !next.length || !this.active ) {
+                       next = this.activeMenu.find( this.options.items )[ filter ]();
+               }
+
+               this.focus( event, next );
+       },
+
+       nextPage: function( event ) {
+               var item, base, height;
+
+               if ( !this.active ) {
+                       this.next( event );
+                       return;
+               }
+               if ( this.isLastItem() ) {
+                       return;
+               }
+               if ( this._hasScroll() ) {
+                       base = this.active.offset().top;
+                       height = this.element.height();
+                       this.active.nextAll( ".ui-menu-item" ).each(function() {
+                               item = $( this );
+                               return item.offset().top - base - height < 0;
+                       });
+
+                       this.focus( event, item );
+               } else {
+                       this.focus( event, this.activeMenu.find( this.options.items )
+                               [ !this.active ? "first" : "last" ]() );
+               }
+       },
+
+       previousPage: function( event ) {
+               var item, base, height;
+               if ( !this.active ) {
+                       this.next( event );
+                       return;
+               }
+               if ( this.isFirstItem() ) {
+                       return;
+               }
+               if ( this._hasScroll() ) {
+                       base = this.active.offset().top;
+                       height = this.element.height();
+                       this.active.prevAll( ".ui-menu-item" ).each(function() {
+                               item = $( this );
+                               return item.offset().top - base + height > 0;
+                       });
+
+                       this.focus( event, item );
+               } else {
+                       this.focus( event, this.activeMenu.find( this.options.items ).first() );
+               }
+       },
+
+       _hasScroll: function() {
+               return this.element.outerHeight() < this.element.prop( "scrollHeight" );
+       },
+
+       select: function( event ) {
+               // TODO: It should never be possible to not have an active item at this
+               // point, but the tests don't trigger mouseenter before click.
+               this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
+               var ui = { item: this.active };
+               if ( !this.active.has( ".ui-menu" ).length ) {
+                       this.collapseAll( event, true );
+               }
+               this._trigger( "select", event, ui );
+       },
+
+       _filterMenuItems: function(character) {
+               var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
+                       regex = new RegExp( "^" + escapedCharacter, "i" );
+
+               return this.activeMenu
+                       .find( this.options.items )
+
+                       // Only match on items, not dividers or other content (#10571)
+                       .filter( ".ui-menu-item" )
+                       .filter(function() {
+                               return regex.test( $.trim( $( this ).text() ) );
+                       });
+       }
+});
+
+
+/*!
+ * jQuery UI Autocomplete 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/autocomplete/
+ */
+
+
+$.widget( "ui.autocomplete", {
+       version: "1.11.3",
+       defaultElement: "<input>",
+       options: {
+               appendTo: null,
+               autoFocus: false,
+               delay: 300,
+               minLength: 1,
+               position: {
+                       my: "left top",
+                       at: "left bottom",
+                       collision: "none"
+               },
+               source: null,
+
+               // callbacks
+               change: null,
+               close: null,
+               focus: null,
+               open: null,
+               response: null,
+               search: null,
+               select: null
+       },
+
+       requestIndex: 0,
+       pending: 0,
+
+       _create: function() {
+               // Some browsers only repeat keydown events, not keypress events,
+               // so we use the suppressKeyPress flag to determine if we've already
+               // handled the keydown event. #7269
+               // Unfortunately the code for & in keypress is the same as the up arrow,
+               // so we use the suppressKeyPressRepeat flag to avoid handling keypress
+               // events when we know the keydown event was used to modify the
+               // search term. #7799
+               var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
+                       nodeName = this.element[ 0 ].nodeName.toLowerCase(),
+                       isTextarea = nodeName === "textarea",
+                       isInput = nodeName === "input";
+
+               this.isMultiLine =
+                       // Textareas are always multi-line
+                       isTextarea ? true :
+                       // Inputs are always single-line, even if inside a contentEditable element
+                       // IE also treats inputs as contentEditable
+                       isInput ? false :
+                       // All other element types are determined by whether or not they're contentEditable
+                       this.element.prop( "isContentEditable" );
+
+               this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
+               this.isNewMenu = true;
+
+               this.element
+                       .addClass( "ui-autocomplete-input" )
+                       .attr( "autocomplete", "off" );
+
+               this._on( this.element, {
+                       keydown: function( event ) {
+                               if ( this.element.prop( "readOnly" ) ) {
+                                       suppressKeyPress = true;
+                                       suppressInput = true;
+                                       suppressKeyPressRepeat = true;
+                                       return;
+                               }
+
+                               suppressKeyPress = false;
+                               suppressInput = false;
+                               suppressKeyPressRepeat = false;
+                               var keyCode = $.ui.keyCode;
+                               switch ( event.keyCode ) {
+                               case keyCode.PAGE_UP:
+                                       suppressKeyPress = true;
+                                       this._move( "previousPage", event );
+                                       break;
+                               case keyCode.PAGE_DOWN:
+                                       suppressKeyPress = true;
+                                       this._move( "nextPage", event );
+                                       break;
+                               case keyCode.UP:
+                                       suppressKeyPress = true;
+                                       this._keyEvent( "previous", event );
+                                       break;
+                               case keyCode.DOWN:
+                                       suppressKeyPress = true;
+                                       this._keyEvent( "next", event );
+                                       break;
+                               case keyCode.ENTER:
+                                       // when menu is open and has focus
+                                       if ( this.menu.active ) {
+                                               // #6055 - Opera still allows the keypress to occur
+                                               // which causes forms to submit
+                                               suppressKeyPress = true;
+                                               event.preventDefault();
+                                               this.menu.select( event );
+                                       }
+                                       break;
+                               case keyCode.TAB:
+                                       if ( this.menu.active ) {
+                                               this.menu.select( event );
+                                       }
+                                       break;
+                               case keyCode.ESCAPE:
+                                       if ( this.menu.element.is( ":visible" ) ) {
+                                               if ( !this.isMultiLine ) {
+                                                       this._value( this.term );
+                                               }
+                                               this.close( event );
+                                               // Different browsers have different default behavior for escape
+                                               // Single press can mean undo or clear
+                                               // Double press in IE means clear the whole form
+                                               event.preventDefault();
+                                       }
+                                       break;
+                               default:
+                                       suppressKeyPressRepeat = true;
+                                       // search timeout should be triggered before the input value is changed
+                                       this._searchTimeout( event );
+                                       break;
+                               }
+                       },
+                       keypress: function( event ) {
+                               if ( suppressKeyPress ) {
+                                       suppressKeyPress = false;
+                                       if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+                                               event.preventDefault();
+                                       }
+                                       return;
+                               }
+                               if ( suppressKeyPressRepeat ) {
+                                       return;
+                               }
+
+                               // replicate some key handlers to allow them to repeat in Firefox and Opera
+                               var keyCode = $.ui.keyCode;
+                               switch ( event.keyCode ) {
+                               case keyCode.PAGE_UP:
+                                       this._move( "previousPage", event );
+                                       break;
+                               case keyCode.PAGE_DOWN:
+                                       this._move( "nextPage", event );
+                                       break;
+                               case keyCode.UP:
+                                       this._keyEvent( "previous", event );
+                                       break;
+                               case keyCode.DOWN:
+                                       this._keyEvent( "next", event );
+                                       break;
+                               }
+                       },
+                       input: function( event ) {
+                               if ( suppressInput ) {
+                                       suppressInput = false;
+                                       event.preventDefault();
+                                       return;
+                               }
+                               this._searchTimeout( event );
+                       },
+                       focus: function() {
+                               this.selectedItem = null;
+                               this.previous = this._value();
+                       },
+                       blur: function( event ) {
+                               if ( this.cancelBlur ) {
+                                       delete this.cancelBlur;
+                                       return;
+                               }
+
+                               clearTimeout( this.searching );
+                               this.close( event );
+                               this._change( event );
+                       }
+               });
+
+               this._initSource();
+               this.menu = $( "<ul>" )
+                       .addClass( "ui-autocomplete ui-front" )
+                       .appendTo( this._appendTo() )
+                       .menu({
+                               // disable ARIA support, the live region takes care of that
+                               role: null
+                       })
+                       .hide()
+                       .menu( "instance" );
+
+               this._on( this.menu.element, {
+                       mousedown: function( event ) {
+                               // prevent moving focus out of the text field
+                               event.preventDefault();
+
+                               // IE doesn't prevent moving focus even with event.preventDefault()
+                               // so we set a flag to know when we should ignore the blur event
+                               this.cancelBlur = true;
+                               this._delay(function() {
+                                       delete this.cancelBlur;
+                               });
+
+                               // clicking on the scrollbar causes focus to shift to the body
+                               // but we can't detect a mouseup or a click immediately afterward
+                               // so we have to track the next mousedown and close the menu if
+                               // the user clicks somewhere outside of the autocomplete
+                               var menuElement = this.menu.element[ 0 ];
+                               if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
+                                       this._delay(function() {
+                                               var that = this;
+                                               this.document.one( "mousedown", function( event ) {
+                                                       if ( event.target !== that.element[ 0 ] &&
+                                                                       event.target !== menuElement &&
+                                                                       !$.contains( menuElement, event.target ) ) {
+                                                               that.close();
+                                                       }
+                                               });
+                                       });
+                               }
+                       },
+                       menufocus: function( event, ui ) {
+                               var label, item;
+                               // support: Firefox
+                               // Prevent accidental activation of menu items in Firefox (#7024 #9118)
+                               if ( this.isNewMenu ) {
+                                       this.isNewMenu = false;
+                                       if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
+                                               this.menu.blur();
+
+                                               this.document.one( "mousemove", function() {
+                                                       $( event.target ).trigger( event.originalEvent );
+                                               });
+
+                                               return;
+                                       }
+                               }
+
+                               item = ui.item.data( "ui-autocomplete-item" );
+                               if ( false !== this._trigger( "focus", event, { item: item } ) ) {
+                                       // use value to match what will end up in the input, if it was a key event
+                                       if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
+                                               this._value( item.value );
+                                       }
+                               }
+
+                               // Announce the value in the liveRegion
+                               label = ui.item.attr( "aria-label" ) || item.value;
+                               if ( label && $.trim( label ).length ) {
+                                       this.liveRegion.children().hide();
+                                       $( "<div>" ).text( label ).appendTo( this.liveRegion );
+                               }
+                       },
+                       menuselect: function( event, ui ) {
+                               var item = ui.item.data( "ui-autocomplete-item" ),
+                                       previous = this.previous;
+
+                               // only trigger when focus was lost (click on menu)
+                               if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
+                                       this.element.focus();
+                                       this.previous = previous;
+                                       // #6109 - IE triggers two focus events and the second
+                                       // is asynchronous, so we need to reset the previous
+                                       // term synchronously and asynchronously :-(
+                                       this._delay(function() {
+                                               this.previous = previous;
+                                               this.selectedItem = item;
+                                       });
+                               }
+
+                               if ( false !== this._trigger( "select", event, { item: item } ) ) {
+                                       this._value( item.value );
+                               }
+                               // reset the term after the select event
+                               // this allows custom select handling to work properly
+                               this.term = this._value();
+
+                               this.close( event );
+                               this.selectedItem = item;
+                       }
+               });
+
+               this.liveRegion = $( "<span>", {
+                               role: "status",
+                               "aria-live": "assertive",
+                               "aria-relevant": "additions"
+                       })
+                       .addClass( "ui-helper-hidden-accessible" )
+                       .appendTo( this.document[ 0 ].body );
+
+               // turning off autocomplete prevents the browser from remembering the
+               // value when navigating through history, so we re-enable autocomplete
+               // if the page is unloaded before the widget is destroyed. #7790
+               this._on( this.window, {
+                       beforeunload: function() {
+                               this.element.removeAttr( "autocomplete" );
+                       }
+               });
+       },
+
+       _destroy: function() {
+               clearTimeout( this.searching );
+               this.element
+                       .removeClass( "ui-autocomplete-input" )
+                       .removeAttr( "autocomplete" );
+               this.menu.element.remove();
+               this.liveRegion.remove();
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "source" ) {
+                       this._initSource();
+               }
+               if ( key === "appendTo" ) {
+                       this.menu.element.appendTo( this._appendTo() );
+               }
+               if ( key === "disabled" && value && this.xhr ) {
+                       this.xhr.abort();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+
+               if ( element ) {
+                       element = element.jquery || element.nodeType ?
+                               $( element ) :
+                               this.document.find( element ).eq( 0 );
+               }
+
+               if ( !element || !element[ 0 ] ) {
+                       element = this.element.closest( ".ui-front" );
+               }
+
+               if ( !element.length ) {
+                       element = this.document[ 0 ].body;
+               }
+
+               return element;
+       },
+
+       _initSource: function() {
+               var array, url,
+                       that = this;
+               if ( $.isArray( this.options.source ) ) {
+                       array = this.options.source;
+                       this.source = function( request, response ) {
+                               response( $.ui.autocomplete.filter( array, request.term ) );
+                       };
+               } else if ( typeof this.options.source === "string" ) {
+                       url = this.options.source;
+                       this.source = function( request, response ) {
+                               if ( that.xhr ) {
+                                       that.xhr.abort();
+                               }
+                               that.xhr = $.ajax({
+                                       url: url,
+                                       data: request,
+                                       dataType: "json",
+                                       success: function( data ) {
+                                               response( data );
+                                       },
+                                       error: function() {
+                                               response([]);
+                                       }
+                               });
+                       };
+               } else {
+                       this.source = this.options.source;
+               }
+       },
+
+       _searchTimeout: function( event ) {
+               clearTimeout( this.searching );
+               this.searching = this._delay(function() {
+
+                       // Search if the value has changed, or if the user retypes the same value (see #7434)
+                       var equalValues = this.term === this._value(),
+                               menuVisible = this.menu.element.is( ":visible" ),
+                               modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
+
+                       if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
+                               this.selectedItem = null;
+                               this.search( null, event );
+                       }
+               }, this.options.delay );
+       },
+
+       search: function( value, event ) {
+               value = value != null ? value : this._value();
+
+               // always save the actual value, not the one passed as an argument
+               this.term = this._value();
+
+               if ( value.length < this.options.minLength ) {
+                       return this.close( event );
+               }
+
+               if ( this._trigger( "search", event ) === false ) {
+                       return;
+               }
+
+               return this._search( value );
+       },
+
+       _search: function( value ) {
+               this.pending++;
+               this.element.addClass( "ui-autocomplete-loading" );
+               this.cancelSearch = false;
+
+               this.source( { term: value }, this._response() );
+       },
+
+       _response: function() {
+               var index = ++this.requestIndex;
+
+               return $.proxy(function( content ) {
+                       if ( index === this.requestIndex ) {
+                               this.__response( content );
+                       }
+
+                       this.pending--;
+                       if ( !this.pending ) {
+                               this.element.removeClass( "ui-autocomplete-loading" );
+                       }
+               }, this );
+       },
+
+       __response: function( content ) {
+               if ( content ) {
+                       content = this._normalize( content );
+               }
+               this._trigger( "response", null, { content: content } );
+               if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
+                       this._suggest( content );
+                       this._trigger( "open" );
+               } else {
+                       // use ._close() instead of .close() so we don't cancel future searches
+                       this._close();
+               }
+       },
+
+       close: function( event ) {
+               this.cancelSearch = true;
+               this._close( event );
+       },
+
+       _close: function( event ) {
+               if ( this.menu.element.is( ":visible" ) ) {
+                       this.menu.element.hide();
+                       this.menu.blur();
+                       this.isNewMenu = true;
+                       this._trigger( "close", event );
+               }
+       },
+
+       _change: function( event ) {
+               if ( this.previous !== this._value() ) {
+                       this._trigger( "change", event, { item: this.selectedItem } );
+               }
+       },
+
+       _normalize: function( items ) {
+               // assume all items have the right format when the first item is complete
+               if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
+                       return items;
+               }
+               return $.map( items, function( item ) {
+                       if ( typeof item === "string" ) {
+                               return {
+                                       label: item,
+                                       value: item
+                               };
+                       }
+                       return $.extend( {}, item, {
+                               label: item.label || item.value,
+                               value: item.value || item.label
+                       });
+               });
+       },
+
+       _suggest: function( items ) {
+               var ul = this.menu.element.empty();
+               this._renderMenu( ul, items );
+               this.isNewMenu = true;
+               this.menu.refresh();
+
+               // size and position menu
+               ul.show();
+               this._resizeMenu();
+               ul.position( $.extend({
+                       of: this.element
+               }, this.options.position ) );
+
+               if ( this.options.autoFocus ) {
+                       this.menu.next();
+               }
+       },
+
+       _resizeMenu: function() {
+               var ul = this.menu.element;
+               ul.outerWidth( Math.max(
+                       // Firefox wraps long text (possibly a rounding bug)
+                       // so we add 1px to avoid the wrapping (#7513)
+                       ul.width( "" ).outerWidth() + 1,
+                       this.element.outerWidth()
+               ) );
+       },
+
+       _renderMenu: function( ul, items ) {
+               var that = this;
+               $.each( items, function( index, item ) {
+                       that._renderItemData( ul, item );
+               });
+       },
+
+       _renderItemData: function( ul, item ) {
+               return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
+       },
+
+       _renderItem: function( ul, item ) {
+               return $( "<li>" ).text( item.label ).appendTo( ul );
+       },
+
+       _move: function( direction, event ) {
+               if ( !this.menu.element.is( ":visible" ) ) {
+                       this.search( null, event );
+                       return;
+               }
+               if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
+                               this.menu.isLastItem() && /^next/.test( direction ) ) {
+
+                       if ( !this.isMultiLine ) {
+                               this._value( this.term );
+                       }
+
+                       this.menu.blur();
+                       return;
+               }
+               this.menu[ direction ]( event );
+       },
+
+       widget: function() {
+               return this.menu.element;
+       },
+
+       _value: function() {
+               return this.valueMethod.apply( this.element, arguments );
+       },
+
+       _keyEvent: function( keyEvent, event ) {
+               if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+                       this._move( keyEvent, event );
+
+                       // prevents moving cursor to beginning/end of the text field in some browsers
+                       event.preventDefault();
+               }
+       }
+});
+
+$.extend( $.ui.autocomplete, {
+       escapeRegex: function( value ) {
+               return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
+       },
+       filter: function( array, term ) {
+               var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
+               return $.grep( array, function( value ) {
+                       return matcher.test( value.label || value.value || value );
+               });
+       }
+});
+
+// live region extension, adding a `messages` option
+// NOTE: This is an experimental API. We are still investigating
+// a full solution for string manipulation and internationalization.
+$.widget( "ui.autocomplete", $.ui.autocomplete, {
+       options: {
+               messages: {
+                       noResults: "No search results.",
+                       results: function( amount ) {
+                               return amount + ( amount > 1 ? " results are" : " result is" ) +
+                                       " available, use up and down arrow keys to navigate.";
+                       }
+               }
+       },
+
+       __response: function( content ) {
+               var message;
+               this._superApply( arguments );
+               if ( this.options.disabled || this.cancelSearch ) {
+                       return;
+               }
+               if ( content && content.length ) {
+                       message = this.options.messages.results( content.length );
+               } else {
+                       message = this.options.messages.noResults;
+               }
+               this.liveRegion.children().hide();
+               $( "<div>" ).text( message ).appendTo( this.liveRegion );
+       }
+});
+
+var autocomplete = $.ui.autocomplete;
+
+
+/*!
+ * jQuery UI Button 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/button/
+ */
+
+
+var lastActive,
+       baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+       typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+       formResetHandler = function() {
+               var form = $( this );
+               setTimeout(function() {
+                       form.find( ":ui-button" ).button( "refresh" );
+               }, 1 );
+       },
+       radioGroup = function( radio ) {
+               var name = radio.name,
+                       form = radio.form,
+                       radios = $( [] );
+               if ( name ) {
+                       name = name.replace( /'/g, "\\'" );
+                       if ( form ) {
+                               radios = $( form ).find( "[name='" + name + "'][type=radio]" );
+                       } else {
+                               radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
+                                       .filter(function() {
+                                               return !this.form;
+                                       });
+                       }
+               }
+               return radios;
+       };
+
+$.widget( "ui.button", {
+       version: "1.11.3",
+       defaultElement: "<button>",
+       options: {
+               disabled: null,
+               text: true,
+               label: null,
+               icons: {
+                       primary: null,
+                       secondary: null
+               }
+       },
+       _create: function() {
+               this.element.closest( "form" )
+                       .unbind( "reset" + this.eventNamespace )
+                       .bind( "reset" + this.eventNamespace, formResetHandler );
+
+               if ( typeof this.options.disabled !== "boolean" ) {
+                       this.options.disabled = !!this.element.prop( "disabled" );
+               } else {
+                       this.element.prop( "disabled", this.options.disabled );
+               }
+
+               this._determineButtonType();
+               this.hasTitle = !!this.buttonElement.attr( "title" );
+
+               var that = this,
+                       options = this.options,
+                       toggleButton = this.type === "checkbox" || this.type === "radio",
+                       activeClass = !toggleButton ? "ui-state-active" : "";
+
+               if ( options.label === null ) {
+                       options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
+               }
+
+               this._hoverable( this.buttonElement );
+
+               this.buttonElement
+                       .addClass( baseClasses )
+                       .attr( "role", "button" )
+                       .bind( "mouseenter" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               if ( this === lastActive ) {
+                                       $( this ).addClass( "ui-state-active" );
+                               }
+                       })
+                       .bind( "mouseleave" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).removeClass( activeClass );
+                       })
+                       .bind( "click" + this.eventNamespace, function( event ) {
+                               if ( options.disabled ) {
+                                       event.preventDefault();
+                                       event.stopImmediatePropagation();
+                               }
+                       });
+
+               // Can't use _focusable() because the element that receives focus
+               // and the element that gets the ui-state-focus class are different
+               this._on({
+                       focus: function() {
+                               this.buttonElement.addClass( "ui-state-focus" );
+                       },
+                       blur: function() {
+                               this.buttonElement.removeClass( "ui-state-focus" );
+                       }
+               });
+
+               if ( toggleButton ) {
+                       this.element.bind( "change" + this.eventNamespace, function() {
+                               that.refresh();
+                       });
+               }
+
+               if ( this.type === "checkbox" ) {
+                       this.buttonElement.bind( "click" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                       });
+               } else if ( this.type === "radio" ) {
+                       this.buttonElement.bind( "click" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                               $( this ).addClass( "ui-state-active" );
+                               that.buttonElement.attr( "aria-pressed", "true" );
+
+                               var radio = that.element[ 0 ];
+                               radioGroup( radio )
+                                       .not( radio )
+                                       .map(function() {
+                                               return $( this ).button( "widget" )[ 0 ];
+                                       })
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "false" );
+                       });
+               } else {
+                       this.buttonElement
+                               .bind( "mousedown" + this.eventNamespace, function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).addClass( "ui-state-active" );
+                                       lastActive = this;
+                                       that.document.one( "mouseup", function() {
+                                               lastActive = null;
+                                       });
+                               })
+                               .bind( "mouseup" + this.eventNamespace, function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).removeClass( "ui-state-active" );
+                               })
+                               .bind( "keydown" + this.eventNamespace, function(event) {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
+                                               $( this ).addClass( "ui-state-active" );
+                                       }
+                               })
+                               // see #8559, we bind to blur here in case the button element loses
+                               // focus between keydown and keyup, it would be left in an "active" state
+                               .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
+                                       $( this ).removeClass( "ui-state-active" );
+                               });
+
+                       if ( this.buttonElement.is("a") ) {
+                               this.buttonElement.keyup(function(event) {
+                                       if ( event.keyCode === $.ui.keyCode.SPACE ) {
+                                               // TODO pass through original event correctly (just as 2nd argument doesn't work)
+                                               $( this ).click();
+                                       }
+                               });
+                       }
+               }
+
+               this._setOption( "disabled", options.disabled );
+               this._resetButton();
+       },
+
+       _determineButtonType: function() {
+               var ancestor, labelSelector, checked;
+
+               if ( this.element.is("[type=checkbox]") ) {
+                       this.type = "checkbox";
+               } else if ( this.element.is("[type=radio]") ) {
+                       this.type = "radio";
+               } else if ( this.element.is("input") ) {
+                       this.type = "input";
+               } else {
+                       this.type = "button";
+               }
+
+               if ( this.type === "checkbox" || this.type === "radio" ) {
+                       // we don't search against the document in case the element
+                       // is disconnected from the DOM
+                       ancestor = this.element.parents().last();
+                       labelSelector = "label[for='" + this.element.attr("id") + "']";
+                       this.buttonElement = ancestor.find( labelSelector );
+                       if ( !this.buttonElement.length ) {
+                               ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+                               this.buttonElement = ancestor.filter( labelSelector );
+                               if ( !this.buttonElement.length ) {
+                                       this.buttonElement = ancestor.find( labelSelector );
+                               }
+                       }
+                       this.element.addClass( "ui-helper-hidden-accessible" );
+
+                       checked = this.element.is( ":checked" );
+                       if ( checked ) {
+                               this.buttonElement.addClass( "ui-state-active" );
+                       }
+                       this.buttonElement.prop( "aria-pressed", checked );
+               } else {
+                       this.buttonElement = this.element;
+               }
+       },
+
+       widget: function() {
+               return this.buttonElement;
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-helper-hidden-accessible" );
+               this.buttonElement
+                       .removeClass( baseClasses + " ui-state-active " + typeClasses )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-pressed" )
+                       .html( this.buttonElement.find(".ui-button-text").html() );
+
+               if ( !this.hasTitle ) {
+                       this.buttonElement.removeAttr( "title" );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "disabled" ) {
+                       this.widget().toggleClass( "ui-state-disabled", !!value );
+                       this.element.prop( "disabled", !!value );
+                       if ( value ) {
+                               if ( this.type === "checkbox" || this.type === "radio" ) {
+                                       this.buttonElement.removeClass( "ui-state-focus" );
+                               } else {
+                                       this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
+                               }
+                       }
+                       return;
+               }
+               this._resetButton();
+       },
+
+       refresh: function() {
+               //See #8237 & #8828
+               var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
+
+               if ( isDisabled !== this.options.disabled ) {
+                       this._setOption( "disabled", isDisabled );
+               }
+               if ( this.type === "radio" ) {
+                       radioGroup( this.element[0] ).each(function() {
+                               if ( $( this ).is( ":checked" ) ) {
+                                       $( this ).button( "widget" )
+                                               .addClass( "ui-state-active" )
+                                               .attr( "aria-pressed", "true" );
+                               } else {
+                                       $( this ).button( "widget" )
+                                               .removeClass( "ui-state-active" )
+                                               .attr( "aria-pressed", "false" );
+                               }
+                       });
+               } else if ( this.type === "checkbox" ) {
+                       if ( this.element.is( ":checked" ) ) {
+                               this.buttonElement
+                                       .addClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "true" );
+                       } else {
+                               this.buttonElement
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "false" );
+                       }
+               }
+       },
+
+       _resetButton: function() {
+               if ( this.type === "input" ) {
+                       if ( this.options.label ) {
+                               this.element.val( this.options.label );
+                       }
+                       return;
+               }
+               var buttonElement = this.buttonElement.removeClass( typeClasses ),
+                       buttonText = $( "<span></span>", this.document[0] )
+                               .addClass( "ui-button-text" )
+                               .html( this.options.label )
+                               .appendTo( buttonElement.empty() )
+                               .text(),
+                       icons = this.options.icons,
+                       multipleIcons = icons.primary && icons.secondary,
+                       buttonClasses = [];
+
+               if ( icons.primary || icons.secondary ) {
+                       if ( this.options.text ) {
+                               buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+                       }
+
+                       if ( icons.primary ) {
+                               buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+                       }
+
+                       if ( icons.secondary ) {
+                               buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+                       }
+
+                       if ( !this.options.text ) {
+                               buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+                               if ( !this.hasTitle ) {
+                                       buttonElement.attr( "title", $.trim( buttonText ) );
+                               }
+                       }
+               } else {
+                       buttonClasses.push( "ui-button-text-only" );
+               }
+               buttonElement.addClass( buttonClasses.join( " " ) );
+       }
+});
+
+$.widget( "ui.buttonset", {
+       version: "1.11.3",
+       options: {
+               items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
+       },
+
+       _create: function() {
+               this.element.addClass( "ui-buttonset" );
+       },
+
+       _init: function() {
+               this.refresh();
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "disabled" ) {
+                       this.buttons.button( "option", key, value );
+               }
+
+               this._super( key, value );
+       },
+
+       refresh: function() {
+               var rtl = this.element.css( "direction" ) === "rtl",
+                       allButtons = this.element.find( this.options.items ),
+                       existingButtons = allButtons.filter( ":ui-button" );
+
+               // Initialize new buttons
+               allButtons.not( ":ui-button" ).button();
+
+               // Refresh existing buttons
+               existingButtons.button( "refresh" );
+
+               this.buttons = allButtons
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+                               .filter( ":first" )
+                                       .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
+                               .end()
+                               .filter( ":last" )
+                                       .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
+                               .end()
+                       .end();
+       },
+
+       _destroy: function() {
+               this.element.removeClass( "ui-buttonset" );
+               this.buttons
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-left ui-corner-right" )
+                       .end()
+                       .button( "destroy" );
+       }
+});
+
+var button = $.ui.button;
+
+
+/*!
+ * jQuery UI Datepicker 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/datepicker/
+ */
+
+
+$.extend($.ui, { datepicker: { version: "1.11.3" } });
+
+var datepicker_instActive;
+
+function datepicker_getZindex( elem ) {
+       var position, value;
+       while ( elem.length && elem[ 0 ] !== document ) {
+               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+               // This makes behavior of this function consistent across browsers
+               // WebKit always returns auto if the element is positioned
+               position = elem.css( "position" );
+               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                       // IE returns 0 when zIndex is not specified
+                       // other browsers return a string
+                       // we ignore the case of nested elements with an explicit value of 0
+                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                       value = parseInt( elem.css( "zIndex" ), 10 );
+                       if ( !isNaN( value ) && value !== 0 ) {
+                               return value;
+                       }
+               }
+               elem = elem.parent();
+       }
+
+       return 0;
+}
+/* Date picker manager.
+   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+   Settings for (groups of) date pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Datepicker() {
+       this._curInst = null; // The current instance in use
+       this._keyEvent = false; // If the last event was a key event
+       this._disabledInputs = []; // List of date picker inputs that have been disabled
+       this._datepickerShowing = false; // True if the popup picker is showing , false if not
+       this._inDialog = false; // True if showing within a "dialog", false if not
+       this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
+       this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
+       this._appendClass = "ui-datepicker-append"; // The name of the append marker class
+       this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
+       this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
+       this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
+       this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
+       this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
+       this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
+       this.regional = []; // Available regional settings, indexed by language code
+       this.regional[""] = { // Default regional settings
+               closeText: "Done", // Display text for close link
+               prevText: "Prev", // Display text for previous month link
+               nextText: "Next", // Display text for next month link
+               currentText: "Today", // Display text for current month link
+               monthNames: ["January","February","March","April","May","June",
+                       "July","August","September","October","November","December"], // Names of months for drop-down and formatting
+               monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
+               dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
+               dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
+               dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
+               weekHeader: "Wk", // Column header for week of the year
+               dateFormat: "mm/dd/yy", // See format options on parseDate
+               firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+               isRTL: false, // True if right-to-left language, false if left-to-right
+               showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+               yearSuffix: "" // Additional text to append to the year in the month headers
+       };
+       this._defaults = { // Global defaults for all the date picker instances
+               showOn: "focus", // "focus" for popup on focus,
+                       // "button" for trigger button, or "both" for either
+               showAnim: "fadeIn", // Name of jQuery animation for popup
+               showOptions: {}, // Options for enhanced animations
+               defaultDate: null, // Used when field is blank: actual date,
+                       // +/-number for offset from today, null for today
+               appendText: "", // Display text following the input box, e.g. showing the format
+               buttonText: "...", // Text for trigger button
+               buttonImage: "", // URL for trigger button image
+               buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+               hideIfNoPrevNext: false, // True to hide next/previous month links
+                       // if not applicable, false to just disable them
+               navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+               gotoCurrent: false, // True if today link goes back to current selection instead
+               changeMonth: false, // True if month can be selected directly, false if only prev/next
+               changeYear: false, // True if year can be selected directly, false if only prev/next
+               yearRange: "c-10:c+10", // Range of years to display in drop-down,
+                       // either relative to today's year (-nn:+nn), relative to currently displayed year
+                       // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+               showOtherMonths: false, // True to show dates in other months, false to leave blank
+               selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+               showWeek: false, // True to show week of the year, false to not show it
+               calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+                       // takes a Date and returns the number of the week for it
+               shortYearCutoff: "+10", // Short year values < this are in the current century,
+                       // > this are in the previous century,
+                       // string value starting with "+" for current year + value
+               minDate: null, // The earliest selectable date, or null for no limit
+               maxDate: null, // The latest selectable date, or null for no limit
+               duration: "fast", // Duration of display/closure
+               beforeShowDay: null, // Function that takes a date and returns an array with
+                       // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
+                       // [2] = cell title (optional), e.g. $.datepicker.noWeekends
+               beforeShow: null, // Function that takes an input field and
+                       // returns a set of custom settings for the date picker
+               onSelect: null, // Define a callback function when a date is selected
+               onChangeMonthYear: null, // Define a callback function when the month or year is changed
+               onClose: null, // Define a callback function when the datepicker is closed
+               numberOfMonths: 1, // Number of months to show at a time
+               showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+               stepMonths: 1, // Number of months to step back/forward
+               stepBigMonths: 12, // Number of months to step back/forward for the big links
+               altField: "", // Selector for an alternate field to store selected dates into
+               altFormat: "", // The date format to use for the alternate field
+               constrainInput: true, // The input is constrained by the current date format
+               showButtonPanel: false, // True to show button panel, false to not show it
+               autoSize: false, // True to size the input for the date format, false to leave as is
+               disabled: false // The initial disabled state
+       };
+       $.extend(this._defaults, this.regional[""]);
+       this.regional.en = $.extend( true, {}, this.regional[ "" ]);
+       this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
+       this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
+}
+
+$.extend(Datepicker.prototype, {
+       /* Class name added to elements to indicate already configured with a date picker. */
+       markerClassName: "hasDatepicker",
+
+       //Keep track of the maximum number of rows displayed (see #7043)
+       maxRows: 4,
+
+       // TODO rename to "widget" when switching to widget factory
+       _widgetDatepicker: function() {
+               return this.dpDiv;
+       },
+
+       /* Override the default settings for all instances of the date picker.
+        * @param  settings  object - the new settings to use as defaults (anonymous object)
+        * @return the manager object
+        */
+       setDefaults: function(settings) {
+               datepicker_extendRemove(this._defaults, settings || {});
+               return this;
+       },
+
+       /* Attach the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        * @param  settings  object - the new settings to use for this date picker instance (anonymous)
+        */
+       _attachDatepicker: function(target, settings) {
+               var nodeName, inline, inst;
+               nodeName = target.nodeName.toLowerCase();
+               inline = (nodeName === "div" || nodeName === "span");
+               if (!target.id) {
+                       this.uuid += 1;
+                       target.id = "dp" + this.uuid;
+               }
+               inst = this._newInst($(target), inline);
+               inst.settings = $.extend({}, settings || {});
+               if (nodeName === "input") {
+                       this._connectDatepicker(target, inst);
+               } else if (inline) {
+                       this._inlineDatepicker(target, inst);
+               }
+       },
+
+       /* Create a new instance object. */
+       _newInst: function(target, inline) {
+               var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
+               return {id: id, input: target, // associated target
+                       selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+                       drawMonth: 0, drawYear: 0, // month being drawn
+                       inline: inline, // is datepicker inline or not
+                       dpDiv: (!inline ? this.dpDiv : // presentation div
+                       datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
+       },
+
+       /* Attach the date picker to an input field. */
+       _connectDatepicker: function(target, inst) {
+               var input = $(target);
+               inst.append = $([]);
+               inst.trigger = $([]);
+               if (input.hasClass(this.markerClassName)) {
+                       return;
+               }
+               this._attachments(input, inst);
+               input.addClass(this.markerClassName).keydown(this._doKeyDown).
+                       keypress(this._doKeyPress).keyup(this._doKeyUp);
+               this._autoSize(inst);
+               $.data(target, "datepicker", inst);
+               //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
+               if( inst.settings.disabled ) {
+                       this._disableDatepicker( target );
+               }
+       },
+
+       /* Make attachments based on settings. */
+       _attachments: function(input, inst) {
+               var showOn, buttonText, buttonImage,
+                       appendText = this._get(inst, "appendText"),
+                       isRTL = this._get(inst, "isRTL");
+
+               if (inst.append) {
+                       inst.append.remove();
+               }
+               if (appendText) {
+                       inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
+                       input[isRTL ? "before" : "after"](inst.append);
+               }
+
+               input.unbind("focus", this._showDatepicker);
+
+               if (inst.trigger) {
+                       inst.trigger.remove();
+               }
+
+               showOn = this._get(inst, "showOn");
+               if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
+                       input.focus(this._showDatepicker);
+               }
+               if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
+                       buttonText = this._get(inst, "buttonText");
+                       buttonImage = this._get(inst, "buttonImage");
+                       inst.trigger = $(this._get(inst, "buttonImageOnly") ?
+                               $("<img/>").addClass(this._triggerClass).
+                                       attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+                               $("<button type='button'></button>").addClass(this._triggerClass).
+                                       html(!buttonImage ? buttonText : $("<img/>").attr(
+                                       { src:buttonImage, alt:buttonText, title:buttonText })));
+                       input[isRTL ? "before" : "after"](inst.trigger);
+                       inst.trigger.click(function() {
+                               if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
+                                       $.datepicker._hideDatepicker();
+                               } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
+                                       $.datepicker._hideDatepicker();
+                                       $.datepicker._showDatepicker(input[0]);
+                               } else {
+                                       $.datepicker._showDatepicker(input[0]);
+                               }
+                               return false;
+                       });
+               }
+       },
+
+       /* Apply the maximum length for the date format. */
+       _autoSize: function(inst) {
+               if (this._get(inst, "autoSize") && !inst.inline) {
+                       var findMax, max, maxI, i,
+                               date = new Date(2009, 12 - 1, 20), // Ensure double digits
+                               dateFormat = this._get(inst, "dateFormat");
+
+                       if (dateFormat.match(/[DM]/)) {
+                               findMax = function(names) {
+                                       max = 0;
+                                       maxI = 0;
+                                       for (i = 0; i < names.length; i++) {
+                                               if (names[i].length > max) {
+                                                       max = names[i].length;
+                                                       maxI = i;
+                                               }
+                                       }
+                                       return maxI;
+                               };
+                               date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
+                                       "monthNames" : "monthNamesShort"))));
+                               date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
+                                       "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
+                       }
+                       inst.input.attr("size", this._formatDate(inst, date).length);
+               }
+       },
+
+       /* Attach an inline date picker to a div. */
+       _inlineDatepicker: function(target, inst) {
+               var divSpan = $(target);
+               if (divSpan.hasClass(this.markerClassName)) {
+                       return;
+               }
+               divSpan.addClass(this.markerClassName).append(inst.dpDiv);
+               $.data(target, "datepicker", inst);
+               this._setDate(inst, this._getDefaultDate(inst), true);
+               this._updateDatepicker(inst);
+               this._updateAlternate(inst);
+               //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
+               if( inst.settings.disabled ) {
+                       this._disableDatepicker( target );
+               }
+               // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
+               // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
+               inst.dpDiv.css( "display", "block" );
+       },
+
+       /* Pop-up the date picker in a "dialog" box.
+        * @param  input element - ignored
+        * @param  date string or Date - the initial date to display
+        * @param  onSelect  function - the function to call when a date is selected
+        * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
+        * @param  pos int[2] - coordinates for the dialog's position within the screen or
+        *                                      event - with x/y coordinates or
+        *                                      leave empty for default (screen centre)
+        * @return the manager object
+        */
+       _dialogDatepicker: function(input, date, onSelect, settings, pos) {
+               var id, browserWidth, browserHeight, scrollX, scrollY,
+                       inst = this._dialogInst; // internal instance
+
+               if (!inst) {
+                       this.uuid += 1;
+                       id = "dp" + this.uuid;
+                       this._dialogInput = $("<input type='text' id='" + id +
+                               "' style='position: absolute; top: -100px; width: 0px;'/>");
+                       this._dialogInput.keydown(this._doKeyDown);
+                       $("body").append(this._dialogInput);
+                       inst = this._dialogInst = this._newInst(this._dialogInput, false);
+                       inst.settings = {};
+                       $.data(this._dialogInput[0], "datepicker", inst);
+               }
+               datepicker_extendRemove(inst.settings, settings || {});
+               date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
+               this._dialogInput.val(date);
+
+               this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+               if (!this._pos) {
+                       browserWidth = document.documentElement.clientWidth;
+                       browserHeight = document.documentElement.clientHeight;
+                       scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+                       scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+                       this._pos = // should use actual width/height below
+                               [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+               }
+
+               // move input on screen for focus, but hidden behind dialog
+               this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
+               inst.settings.onSelect = onSelect;
+               this._inDialog = true;
+               this.dpDiv.addClass(this._dialogClass);
+               this._showDatepicker(this._dialogInput[0]);
+               if ($.blockUI) {
+                       $.blockUI(this.dpDiv);
+               }
+               $.data(this._dialogInput[0], "datepicker", inst);
+               return this;
+       },
+
+       /* Detach a datepicker from its control.
+        * @param  target       element - the target input field or division or span
+        */
+       _destroyDatepicker: function(target) {
+               var nodeName,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               $.removeData(target, "datepicker");
+               if (nodeName === "input") {
+                       inst.append.remove();
+                       inst.trigger.remove();
+                       $target.removeClass(this.markerClassName).
+                               unbind("focus", this._showDatepicker).
+                               unbind("keydown", this._doKeyDown).
+                               unbind("keypress", this._doKeyPress).
+                               unbind("keyup", this._doKeyUp);
+               } else if (nodeName === "div" || nodeName === "span") {
+                       $target.removeClass(this.markerClassName).empty();
+               }
+
+               if ( datepicker_instActive === inst ) {
+                       datepicker_instActive = null;
+               }
+       },
+
+       /* Enable the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        */
+       _enableDatepicker: function(target) {
+               var nodeName, inline,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               if (nodeName === "input") {
+                       target.disabled = false;
+                       inst.trigger.filter("button").
+                               each(function() { this.disabled = false; }).end().
+                               filter("img").css({opacity: "1.0", cursor: ""});
+               } else if (nodeName === "div" || nodeName === "span") {
+                       inline = $target.children("." + this._inlineClass);
+                       inline.children().removeClass("ui-state-disabled");
+                       inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+                               prop("disabled", false);
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value === target ? null : value); }); // delete entry
+       },
+
+       /* Disable the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        */
+       _disableDatepicker: function(target) {
+               var nodeName, inline,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               if (nodeName === "input") {
+                       target.disabled = true;
+                       inst.trigger.filter("button").
+                               each(function() { this.disabled = true; }).end().
+                               filter("img").css({opacity: "0.5", cursor: "default"});
+               } else if (nodeName === "div" || nodeName === "span") {
+                       inline = $target.children("." + this._inlineClass);
+                       inline.children().addClass("ui-state-disabled");
+                       inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+                               prop("disabled", true);
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value === target ? null : value); }); // delete entry
+               this._disabledInputs[this._disabledInputs.length] = target;
+       },
+
+       /* Is the first field in a jQuery collection disabled as a datepicker?
+        * @param  target       element - the target input field or division or span
+        * @return boolean - true if disabled, false if enabled
+        */
+       _isDisabledDatepicker: function(target) {
+               if (!target) {
+                       return false;
+               }
+               for (var i = 0; i < this._disabledInputs.length; i++) {
+                       if (this._disabledInputs[i] === target) {
+                               return true;
+                       }
+               }
+               return false;
+       },
+
+       /* Retrieve the instance data for the target control.
+        * @param  target  element - the target input field or division or span
+        * @return  object - the associated instance data
+        * @throws  error if a jQuery problem getting data
+        */
+       _getInst: function(target) {
+               try {
+                       return $.data(target, "datepicker");
+               }
+               catch (err) {
+                       throw "Missing instance data for this datepicker";
+               }
+       },
+
+       /* Update or retrieve the settings for a date picker attached to an input field or division.
+        * @param  target  element - the target input field or division or span
+        * @param  name object - the new settings to update or
+        *                              string - the name of the setting to change or retrieve,
+        *                              when retrieving also "all" for all instance settings or
+        *                              "defaults" for all global defaults
+        * @param  value   any - the new value for the setting
+        *                              (omit if above is an object or to retrieve a value)
+        */
+       _optionDatepicker: function(target, name, value) {
+               var settings, date, minDate, maxDate,
+                       inst = this._getInst(target);
+
+               if (arguments.length === 2 && typeof name === "string") {
+                       return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
+                               (inst ? (name === "all" ? $.extend({}, inst.settings) :
+                               this._get(inst, name)) : null));
+               }
+
+               settings = name || {};
+               if (typeof name === "string") {
+                       settings = {};
+                       settings[name] = value;
+               }
+
+               if (inst) {
+                       if (this._curInst === inst) {
+                               this._hideDatepicker();
+                       }
+
+                       date = this._getDateDatepicker(target, true);
+                       minDate = this._getMinMaxDate(inst, "min");
+                       maxDate = this._getMinMaxDate(inst, "max");
+                       datepicker_extendRemove(inst.settings, settings);
+                       // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+                       if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
+                               inst.settings.minDate = this._formatDate(inst, minDate);
+                       }
+                       if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
+                               inst.settings.maxDate = this._formatDate(inst, maxDate);
+                       }
+                       if ( "disabled" in settings ) {
+                               if ( settings.disabled ) {
+                                       this._disableDatepicker(target);
+                               } else {
+                                       this._enableDatepicker(target);
+                               }
+                       }
+                       this._attachments($(target), inst);
+                       this._autoSize(inst);
+                       this._setDate(inst, date);
+                       this._updateAlternate(inst);
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       // change method deprecated
+       _changeDatepicker: function(target, name, value) {
+               this._optionDatepicker(target, name, value);
+       },
+
+       /* Redraw the date picker attached to an input field or division.
+        * @param  target  element - the target input field or division or span
+        */
+       _refreshDatepicker: function(target) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       /* Set the dates for a jQuery selection.
+        * @param  target element - the target input field or division or span
+        * @param  date Date - the new date
+        */
+       _setDateDatepicker: function(target, date) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._setDate(inst, date);
+                       this._updateDatepicker(inst);
+                       this._updateAlternate(inst);
+               }
+       },
+
+       /* Get the date(s) for the first entry in a jQuery selection.
+        * @param  target element - the target input field or division or span
+        * @param  noDefault boolean - true if no default date is to be used
+        * @return Date - the current date
+        */
+       _getDateDatepicker: function(target, noDefault) {
+               var inst = this._getInst(target);
+               if (inst && !inst.inline) {
+                       this._setDateFromField(inst, noDefault);
+               }
+               return (inst ? this._getDate(inst) : null);
+       },
+
+       /* Handle keystrokes. */
+       _doKeyDown: function(event) {
+               var onSelect, dateStr, sel,
+                       inst = $.datepicker._getInst(event.target),
+                       handled = true,
+                       isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
+
+               inst._keyEvent = true;
+               if ($.datepicker._datepickerShowing) {
+                       switch (event.keyCode) {
+                               case 9: $.datepicker._hideDatepicker();
+                                               handled = false;
+                                               break; // hide on tab out
+                               case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
+                                                                       $.datepicker._currentClass + ")", inst.dpDiv);
+                                               if (sel[0]) {
+                                                       $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
+                                               }
+
+                                               onSelect = $.datepicker._get(inst, "onSelect");
+                                               if (onSelect) {
+                                                       dateStr = $.datepicker._formatDate(inst);
+
+                                                       // trigger custom callback
+                                                       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
+                                               } else {
+                                                       $.datepicker._hideDatepicker();
+                                               }
+
+                                               return false; // don't submit the form
+                               case 27: $.datepicker._hideDatepicker();
+                                               break; // hide on escape
+                               case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       -$.datepicker._get(inst, "stepBigMonths") :
+                                                       -$.datepicker._get(inst, "stepMonths")), "M");
+                                               break; // previous month/year on page up/+ ctrl
+                               case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       +$.datepicker._get(inst, "stepBigMonths") :
+                                                       +$.datepicker._get(inst, "stepMonths")), "M");
+                                               break; // next month/year on page down/+ ctrl
+                               case 35: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._clearDate(event.target);
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // clear on ctrl or command +end
+                               case 36: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._gotoToday(event.target);
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // current on ctrl or command +home
+                               case 37: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // -1 day on ctrl or command +left
+                                               if (event.originalEvent.altKey) {
+                                                       $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                               -$.datepicker._get(inst, "stepBigMonths") :
+                                                               -$.datepicker._get(inst, "stepMonths")), "M");
+                                               }
+                                               // next month/year on alt +left on Mac
+                                               break;
+                               case 38: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, -7, "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // -1 week on ctrl or command +up
+                               case 39: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // +1 day on ctrl or command +right
+                                               if (event.originalEvent.altKey) {
+                                                       $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                               +$.datepicker._get(inst, "stepBigMonths") :
+                                                               +$.datepicker._get(inst, "stepMonths")), "M");
+                                               }
+                                               // next month/year on alt +right
+                                               break;
+                               case 40: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, +7, "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // +1 week on ctrl or command +down
+                               default: handled = false;
+                       }
+               } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
+                       $.datepicker._showDatepicker(this);
+               } else {
+                       handled = false;
+               }
+
+               if (handled) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
+       },
+
+       /* Filter entered characters - based on date format. */
+       _doKeyPress: function(event) {
+               var chars, chr,
+                       inst = $.datepicker._getInst(event.target);
+
+               if ($.datepicker._get(inst, "constrainInput")) {
+                       chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
+                       chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
+                       return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
+               }
+       },
+
+       /* Synchronise manual entry and field/alternate field. */
+       _doKeyUp: function(event) {
+               var date,
+                       inst = $.datepicker._getInst(event.target);
+
+               if (inst.input.val() !== inst.lastVal) {
+                       try {
+                               date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
+                                       (inst.input ? inst.input.val() : null),
+                                       $.datepicker._getFormatConfig(inst));
+
+                               if (date) { // only if valid
+                                       $.datepicker._setDateFromField(inst);
+                                       $.datepicker._updateAlternate(inst);
+                                       $.datepicker._updateDatepicker(inst);
+                               }
+                       }
+                       catch (err) {
+                       }
+               }
+               return true;
+       },
+
+       /* Pop-up the date picker for a given input field.
+        * If false returned from beforeShow event handler do not show.
+        * @param  input  element - the input field attached to the date picker or
+        *                                      event - if triggered by focus
+        */
+       _showDatepicker: function(input) {
+               input = input.target || input;
+               if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
+                       input = $("input", input.parentNode)[0];
+               }
+
+               if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
+                       return;
+               }
+
+               var inst, beforeShow, beforeShowSettings, isFixed,
+                       offset, showAnim, duration;
+
+               inst = $.datepicker._getInst(input);
+               if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
+                       $.datepicker._curInst.dpDiv.stop(true, true);
+                       if ( inst && $.datepicker._datepickerShowing ) {
+                               $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
+                       }
+               }
+
+               beforeShow = $.datepicker._get(inst, "beforeShow");
+               beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
+               if(beforeShowSettings === false){
+                       return;
+               }
+               datepicker_extendRemove(inst.settings, beforeShowSettings);
+
+               inst.lastVal = null;
+               $.datepicker._lastInput = input;
+               $.datepicker._setDateFromField(inst);
+
+               if ($.datepicker._inDialog) { // hide cursor
+                       input.value = "";
+               }
+               if (!$.datepicker._pos) { // position below input
+                       $.datepicker._pos = $.datepicker._findPos(input);
+                       $.datepicker._pos[1] += input.offsetHeight; // add the height
+               }
+
+               isFixed = false;
+               $(input).parents().each(function() {
+                       isFixed |= $(this).css("position") === "fixed";
+                       return !isFixed;
+               });
+
+               offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+               $.datepicker._pos = null;
+               //to avoid flashes on Firefox
+               inst.dpDiv.empty();
+               // determine sizing offscreen
+               inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
+               $.datepicker._updateDatepicker(inst);
+               // fix width for dynamic number of date pickers
+               // and adjust position before showing
+               offset = $.datepicker._checkOffset(inst, offset, isFixed);
+               inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+                       "static" : (isFixed ? "fixed" : "absolute")), display: "none",
+                       left: offset.left + "px", top: offset.top + "px"});
+
+               if (!inst.inline) {
+                       showAnim = $.datepicker._get(inst, "showAnim");
+                       duration = $.datepicker._get(inst, "duration");
+                       inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
+                       $.datepicker._datepickerShowing = true;
+
+                       if ( $.effects && $.effects.effect[ showAnim ] ) {
+                               inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
+                       } else {
+                               inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
+                       }
+
+                       if ( $.datepicker._shouldFocusInput( inst ) ) {
+                               inst.input.focus();
+                       }
+
+                       $.datepicker._curInst = inst;
+               }
+       },
+
+       /* Generate the date picker content. */
+       _updateDatepicker: function(inst) {
+               this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
+               datepicker_instActive = inst; // for delegate hover events
+               inst.dpDiv.empty().append(this._generateHTML(inst));
+               this._attachHandlers(inst);
+
+               var origyearshtml,
+                       numMonths = this._getNumberOfMonths(inst),
+                       cols = numMonths[1],
+                       width = 17,
+                       activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
+
+               if ( activeCell.length > 0 ) {
+                       datepicker_handleMouseover.apply( activeCell.get( 0 ) );
+               }
+
+               inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
+               if (cols > 1) {
+                       inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
+               }
+               inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
+                       "Class"]("ui-datepicker-multi");
+               inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
+                       "Class"]("ui-datepicker-rtl");
+
+               if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
+                       inst.input.focus();
+               }
+
+               // deffered render of the years select (to avoid flashes on Firefox)
+               if( inst.yearshtml ){
+                       origyearshtml = inst.yearshtml;
+                       setTimeout(function(){
+                               //assure that inst.yearshtml didn't change.
+                               if( origyearshtml === inst.yearshtml && inst.yearshtml ){
+                                       inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
+                               }
+                               origyearshtml = inst.yearshtml = null;
+                       }, 0);
+               }
+       },
+
+       // #6694 - don't focus the input if it's already focused
+       // this breaks the change event in IE
+       // Support: IE and jQuery <1.9
+       _shouldFocusInput: function( inst ) {
+               return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+       },
+
+       /* Check positioning to remain on screen. */
+       _checkOffset: function(inst, offset, isFixed) {
+               var dpWidth = inst.dpDiv.outerWidth(),
+                       dpHeight = inst.dpDiv.outerHeight(),
+                       inputWidth = inst.input ? inst.input.outerWidth() : 0,
+                       inputHeight = inst.input ? inst.input.outerHeight() : 0,
+                       viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
+                       viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
+
+               offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
+               offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
+               offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
+
+               // now check if datepicker is showing outside window viewport - move to a better place if so.
+               offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
+                       Math.abs(offset.left + dpWidth - viewWidth) : 0);
+               offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
+                       Math.abs(dpHeight + inputHeight) : 0);
+
+               return offset;
+       },
+
+       /* Find an object's position on the screen. */
+       _findPos: function(obj) {
+               var position,
+                       inst = this._getInst(obj),
+                       isRTL = this._get(inst, "isRTL");
+
+               while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
+                       obj = obj[isRTL ? "previousSibling" : "nextSibling"];
+               }
+
+               position = $(obj).offset();
+               return [position.left, position.top];
+       },
+
+       /* Hide the date picker from view.
+        * @param  input  element - the input field attached to the date picker
+        */
+       _hideDatepicker: function(input) {
+               var showAnim, duration, postProcess, onClose,
+                       inst = this._curInst;
+
+               if (!inst || (input && inst !== $.data(input, "datepicker"))) {
+                       return;
+               }
+
+               if (this._datepickerShowing) {
+                       showAnim = this._get(inst, "showAnim");
+                       duration = this._get(inst, "duration");
+                       postProcess = function() {
+                               $.datepicker._tidyDialog(inst);
+                       };
+
+                       // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
+                       if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
+                               inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
+                       } else {
+                               inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
+                                       (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
+                       }
+
+                       if (!showAnim) {
+                               postProcess();
+                       }
+                       this._datepickerShowing = false;
+
+                       onClose = this._get(inst, "onClose");
+                       if (onClose) {
+                               onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
+                       }
+
+                       this._lastInput = null;
+                       if (this._inDialog) {
+                               this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
+                               if ($.blockUI) {
+                                       $.unblockUI();
+                                       $("body").append(this.dpDiv);
+                               }
+                       }
+                       this._inDialog = false;
+               }
+       },
+
+       /* Tidy up after a dialog display. */
+       _tidyDialog: function(inst) {
+               inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
+       },
+
+       /* Close date picker if clicked elsewhere. */
+       _checkExternalClick: function(event) {
+               if (!$.datepicker._curInst) {
+                       return;
+               }
+
+               var $target = $(event.target),
+                       inst = $.datepicker._getInst($target[0]);
+
+               if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
+                               $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
+                               !$target.hasClass($.datepicker.markerClassName) &&
+                               !$target.closest("." + $.datepicker._triggerClass).length &&
+                               $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
+                       ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
+                               $.datepicker._hideDatepicker();
+               }
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustDate: function(id, offset, period) {
+               var target = $(id),
+                       inst = this._getInst(target[0]);
+
+               if (this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+               this._adjustInstDate(inst, offset +
+                       (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
+                       period);
+               this._updateDatepicker(inst);
+       },
+
+       /* Action for current link. */
+       _gotoToday: function(id) {
+               var date,
+                       target = $(id),
+                       inst = this._getInst(target[0]);
+
+               if (this._get(inst, "gotoCurrent") && inst.currentDay) {
+                       inst.selectedDay = inst.currentDay;
+                       inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+                       inst.drawYear = inst.selectedYear = inst.currentYear;
+               } else {
+                       date = new Date();
+                       inst.selectedDay = date.getDate();
+                       inst.drawMonth = inst.selectedMonth = date.getMonth();
+                       inst.drawYear = inst.selectedYear = date.getFullYear();
+               }
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Action for selecting a new month/year. */
+       _selectMonthYear: function(id, select, period) {
+               var target = $(id),
+                       inst = this._getInst(target[0]);
+
+               inst["selected" + (period === "M" ? "Month" : "Year")] =
+               inst["draw" + (period === "M" ? "Month" : "Year")] =
+                       parseInt(select.options[select.selectedIndex].value,10);
+
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Action for selecting a day. */
+       _selectDay: function(id, month, year, td) {
+               var inst,
+                       target = $(id);
+
+               if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+
+               inst = this._getInst(target[0]);
+               inst.selectedDay = inst.currentDay = $("a", td).html();
+               inst.selectedMonth = inst.currentMonth = month;
+               inst.selectedYear = inst.currentYear = year;
+               this._selectDate(id, this._formatDate(inst,
+                       inst.currentDay, inst.currentMonth, inst.currentYear));
+       },
+
+       /* Erase the input field and hide the date picker. */
+       _clearDate: function(id) {
+               var target = $(id);
+               this._selectDate(target, "");
+       },
+
+       /* Update the input field with the selected date. */
+       _selectDate: function(id, dateStr) {
+               var onSelect,
+                       target = $(id),
+                       inst = this._getInst(target[0]);
+
+               dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+               if (inst.input) {
+                       inst.input.val(dateStr);
+               }
+               this._updateAlternate(inst);
+
+               onSelect = this._get(inst, "onSelect");
+               if (onSelect) {
+                       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
+               } else if (inst.input) {
+                       inst.input.trigger("change"); // fire the change event
+               }
+
+               if (inst.inline){
+                       this._updateDatepicker(inst);
+               } else {
+                       this._hideDatepicker();
+                       this._lastInput = inst.input[0];
+                       if (typeof(inst.input[0]) !== "object") {
+                               inst.input.focus(); // restore focus
+                       }
+                       this._lastInput = null;
+               }
+       },
+
+       /* Update any alternate field to synchronise with the main field. */
+       _updateAlternate: function(inst) {
+               var altFormat, date, dateStr,
+                       altField = this._get(inst, "altField");
+
+               if (altField) { // update alternate field too
+                       altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
+                       date = this._getDate(inst);
+                       dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
+                       $(altField).each(function() { $(this).val(dateStr); });
+               }
+       },
+
+       /* Set as beforeShowDay function to prevent selection of weekends.
+        * @param  date  Date - the date to customise
+        * @return [boolean, string] - is this date selectable?, what is its CSS class?
+        */
+       noWeekends: function(date) {
+               var day = date.getDay();
+               return [(day > 0 && day < 6), ""];
+       },
+
+       /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+        * @param  date  Date - the date to get the week for
+        * @return  number - the number of the week within the year that contains this date
+        */
+       iso8601Week: function(date) {
+               var time,
+                       checkDate = new Date(date.getTime());
+
+               // Find Thursday of this week starting on Monday
+               checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
+
+               time = checkDate.getTime();
+               checkDate.setMonth(0); // Compare with Jan 1
+               checkDate.setDate(1);
+               return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+       },
+
+       /* Parse a string value into a date object.
+        * See formatDate below for the possible formats.
+        *
+        * @param  format string - the expected format of the date
+        * @param  value string - the date in the above format
+        * @param  settings Object - attributes include:
+        *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
+        *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
+        *                                      dayNames                string[7] - names of the days from Sunday (optional)
+        *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
+        *                                      monthNames              string[12] - names of the months (optional)
+        * @return  Date - the extracted date value or null if value is blank
+        */
+       parseDate: function (format, value, settings) {
+               if (format == null || value == null) {
+                       throw "Invalid arguments";
+               }
+
+               value = (typeof value === "object" ? value.toString() : value + "");
+               if (value === "") {
+                       return null;
+               }
+
+               var iFormat, dim, extra,
+                       iValue = 0,
+                       shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
+                       shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
+                               new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
+                       dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
+                       dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
+                       monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
+                       monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
+                       year = -1,
+                       month = -1,
+                       day = -1,
+                       doy = -1,
+                       literal = false,
+                       date,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       },
+                       // Extract a number from the string value
+                       getNumber = function(match) {
+                               var isDoubled = lookAhead(match),
+                                       size = (match === "@" ? 14 : (match === "!" ? 20 :
+                                       (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
+                                       minSize = (match === "y" ? size : 1),
+                                       digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
+                                       num = value.substring(iValue).match(digits);
+                               if (!num) {
+                                       throw "Missing number at position " + iValue;
+                               }
+                               iValue += num[0].length;
+                               return parseInt(num[0], 10);
+                       },
+                       // Extract a name from the string value and convert to an index
+                       getName = function(match, shortNames, longNames) {
+                               var index = -1,
+                                       names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
+                                               return [ [k, v] ];
+                                       }).sort(function (a, b) {
+                                               return -(a[1].length - b[1].length);
+                                       });
+
+                               $.each(names, function (i, pair) {
+                                       var name = pair[1];
+                                       if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
+                                               index = pair[0];
+                                               iValue += name.length;
+                                               return false;
+                                       }
+                               });
+                               if (index !== -1) {
+                                       return index + 1;
+                               } else {
+                                       throw "Unknown name at position " + iValue;
+                               }
+                       },
+                       // Confirm that a literal character matches the string value
+                       checkLiteral = function() {
+                               if (value.charAt(iValue) !== format.charAt(iFormat)) {
+                                       throw "Unexpected literal at position " + iValue;
+                               }
+                               iValue++;
+                       };
+
+               for (iFormat = 0; iFormat < format.length; iFormat++) {
+                       if (literal) {
+                               if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                       literal = false;
+                               } else {
+                                       checkLiteral();
+                               }
+                       } else {
+                               switch (format.charAt(iFormat)) {
+                                       case "d":
+                                               day = getNumber("d");
+                                               break;
+                                       case "D":
+                                               getName("D", dayNamesShort, dayNames);
+                                               break;
+                                       case "o":
+                                               doy = getNumber("o");
+                                               break;
+                                       case "m":
+                                               month = getNumber("m");
+                                               break;
+                                       case "M":
+                                               month = getName("M", monthNamesShort, monthNames);
+                                               break;
+                                       case "y":
+                                               year = getNumber("y");
+                                               break;
+                                       case "@":
+                                               date = new Date(getNumber("@"));
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case "!":
+                                               date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case "'":
+                                               if (lookAhead("'")){
+                                                       checkLiteral();
+                                               } else {
+                                                       literal = true;
+                                               }
+                                               break;
+                                       default:
+                                               checkLiteral();
+                               }
+                       }
+               }
+
+               if (iValue < value.length){
+                       extra = value.substr(iValue);
+                       if (!/^\s+/.test(extra)) {
+                               throw "Extra/unparsed characters found in date: " + extra;
+                       }
+               }
+
+               if (year === -1) {
+                       year = new Date().getFullYear();
+               } else if (year < 100) {
+                       year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+                               (year <= shortYearCutoff ? 0 : -100);
+               }
+
+               if (doy > -1) {
+                       month = 1;
+                       day = doy;
+                       do {
+                               dim = this._getDaysInMonth(year, month - 1);
+                               if (day <= dim) {
+                                       break;
+                               }
+                               month++;
+                               day -= dim;
+                       } while (true);
+               }
+
+               date = this._daylightSavingAdjust(new Date(year, month - 1, day));
+               if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
+                       throw "Invalid date"; // E.g. 31/02/00
+               }
+               return date;
+       },
+
+       /* Standard date formats. */
+       ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
+       COOKIE: "D, dd M yy",
+       ISO_8601: "yy-mm-dd",
+       RFC_822: "D, d M y",
+       RFC_850: "DD, dd-M-y",
+       RFC_1036: "D, d M y",
+       RFC_1123: "D, d M yy",
+       RFC_2822: "D, d M yy",
+       RSS: "D, d M y", // RFC 822
+       TICKS: "!",
+       TIMESTAMP: "@",
+       W3C: "yy-mm-dd", // ISO 8601
+
+       _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
+               Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
+
+       /* Format a date object into a string value.
+        * The format can be combinations of the following:
+        * d  - day of month (no leading zero)
+        * dd - day of month (two digit)
+        * o  - day of year (no leading zeros)
+        * oo - day of year (three digit)
+        * D  - day name short
+        * DD - day name long
+        * m  - month of year (no leading zero)
+        * mm - month of year (two digit)
+        * M  - month name short
+        * MM - month name long
+        * y  - year (two digit)
+        * yy - year (four digit)
+        * @ - Unix timestamp (ms since 01/01/1970)
+        * ! - Windows ticks (100ns since 01/01/0001)
+        * "..." - literal text
+        * '' - single quote
+        *
+        * @param  format string - the desired format of the date
+        * @param  date Date - the date value to format
+        * @param  settings Object - attributes include:
+        *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
+        *                                      dayNames                string[7] - names of the days from Sunday (optional)
+        *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
+        *                                      monthNames              string[12] - names of the months (optional)
+        * @return  string - the date in the above format
+        */
+       formatDate: function (format, date, settings) {
+               if (!date) {
+                       return "";
+               }
+
+               var iFormat,
+                       dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
+                       dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
+                       monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
+                       monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       },
+                       // Format a number, with leading zero if necessary
+                       formatNumber = function(match, value, len) {
+                               var num = "" + value;
+                               if (lookAhead(match)) {
+                                       while (num.length < len) {
+                                               num = "0" + num;
+                                       }
+                               }
+                               return num;
+                       },
+                       // Format a name, short or long as requested
+                       formatName = function(match, value, shortNames, longNames) {
+                               return (lookAhead(match) ? longNames[value] : shortNames[value]);
+                       },
+                       output = "",
+                       literal = false;
+
+               if (date) {
+                       for (iFormat = 0; iFormat < format.length; iFormat++) {
+                               if (literal) {
+                                       if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                               literal = false;
+                                       } else {
+                                               output += format.charAt(iFormat);
+                                       }
+                               } else {
+                                       switch (format.charAt(iFormat)) {
+                                               case "d":
+                                                       output += formatNumber("d", date.getDate(), 2);
+                                                       break;
+                                               case "D":
+                                                       output += formatName("D", date.getDay(), dayNamesShort, dayNames);
+                                                       break;
+                                               case "o":
+                                                       output += formatNumber("o",
+                                                               Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
+                                                       break;
+                                               case "m":
+                                                       output += formatNumber("m", date.getMonth() + 1, 2);
+                                                       break;
+                                               case "M":
+                                                       output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
+                                                       break;
+                                               case "y":
+                                                       output += (lookAhead("y") ? date.getFullYear() :
+                                                               (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
+                                                       break;
+                                               case "@":
+                                                       output += date.getTime();
+                                                       break;
+                                               case "!":
+                                                       output += date.getTime() * 10000 + this._ticksTo1970;
+                                                       break;
+                                               case "'":
+                                                       if (lookAhead("'")) {
+                                                               output += "'";
+                                                       } else {
+                                                               literal = true;
+                                                       }
+                                                       break;
+                                               default:
+                                                       output += format.charAt(iFormat);
+                                       }
+                               }
+                       }
+               }
+               return output;
+       },
+
+       /* Extract all possible characters from the date format. */
+       _possibleChars: function (format) {
+               var iFormat,
+                       chars = "",
+                       literal = false,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       };
+
+               for (iFormat = 0; iFormat < format.length; iFormat++) {
+                       if (literal) {
+                               if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                       literal = false;
+                               } else {
+                                       chars += format.charAt(iFormat);
+                               }
+                       } else {
+                               switch (format.charAt(iFormat)) {
+                                       case "d": case "m": case "y": case "@":
+                                               chars += "0123456789";
+                                               break;
+                                       case "D": case "M":
+                                               return null; // Accept anything
+                                       case "'":
+                                               if (lookAhead("'")) {
+                                                       chars += "'";
+                                               } else {
+                                                       literal = true;
+                                               }
+                                               break;
+                                       default:
+                                               chars += format.charAt(iFormat);
+                               }
+                       }
+               }
+               return chars;
+       },
+
+       /* Get a setting value, defaulting if necessary. */
+       _get: function(inst, name) {
+               return inst.settings[name] !== undefined ?
+                       inst.settings[name] : this._defaults[name];
+       },
+
+       /* Parse existing date and initialise date picker. */
+       _setDateFromField: function(inst, noDefault) {
+               if (inst.input.val() === inst.lastVal) {
+                       return;
+               }
+
+               var dateFormat = this._get(inst, "dateFormat"),
+                       dates = inst.lastVal = inst.input ? inst.input.val() : null,
+                       defaultDate = this._getDefaultDate(inst),
+                       date = defaultDate,
+                       settings = this._getFormatConfig(inst);
+
+               try {
+                       date = this.parseDate(dateFormat, dates, settings) || defaultDate;
+               } catch (event) {
+                       dates = (noDefault ? "" : dates);
+               }
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               inst.currentDay = (dates ? date.getDate() : 0);
+               inst.currentMonth = (dates ? date.getMonth() : 0);
+               inst.currentYear = (dates ? date.getFullYear() : 0);
+               this._adjustInstDate(inst);
+       },
+
+       /* Retrieve the default date shown on opening. */
+       _getDefaultDate: function(inst) {
+               return this._restrictMinMax(inst,
+                       this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
+       },
+
+       /* A date may be specified as an exact value or a relative one. */
+       _determineDate: function(inst, date, defaultDate) {
+               var offsetNumeric = function(offset) {
+                               var date = new Date();
+                               date.setDate(date.getDate() + offset);
+                               return date;
+                       },
+                       offsetString = function(offset) {
+                               try {
+                                       return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
+                                               offset, $.datepicker._getFormatConfig(inst));
+                               }
+                               catch (e) {
+                                       // Ignore
+                               }
+
+                               var date = (offset.toLowerCase().match(/^c/) ?
+                                       $.datepicker._getDate(inst) : null) || new Date(),
+                                       year = date.getFullYear(),
+                                       month = date.getMonth(),
+                                       day = date.getDate(),
+                                       pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
+                                       matches = pattern.exec(offset);
+
+                               while (matches) {
+                                       switch (matches[2] || "d") {
+                                               case "d" : case "D" :
+                                                       day += parseInt(matches[1],10); break;
+                                               case "w" : case "W" :
+                                                       day += parseInt(matches[1],10) * 7; break;
+                                               case "m" : case "M" :
+                                                       month += parseInt(matches[1],10);
+                                                       day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                                       break;
+                                               case "y": case "Y" :
+                                                       year += parseInt(matches[1],10);
+                                                       day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                                       break;
+                                       }
+                                       matches = pattern.exec(offset);
+                               }
+                               return new Date(year, month, day);
+                       },
+                       newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
+                               (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+
+               newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
+               if (newDate) {
+                       newDate.setHours(0);
+                       newDate.setMinutes(0);
+                       newDate.setSeconds(0);
+                       newDate.setMilliseconds(0);
+               }
+               return this._daylightSavingAdjust(newDate);
+       },
+
+       /* Handle switch to/from daylight saving.
+        * Hours may be non-zero on daylight saving cut-over:
+        * > 12 when midnight changeover, but then cannot generate
+        * midnight datetime, so jump to 1AM, otherwise reset.
+        * @param  date  (Date) the date to check
+        * @return  (Date) the corrected date
+        */
+       _daylightSavingAdjust: function(date) {
+               if (!date) {
+                       return null;
+               }
+               date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
+               return date;
+       },
+
+       /* Set the date(s) directly. */
+       _setDate: function(inst, date, noChange) {
+               var clear = !date,
+                       origMonth = inst.selectedMonth,
+                       origYear = inst.selectedYear,
+                       newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
+
+               inst.selectedDay = inst.currentDay = newDate.getDate();
+               inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+               inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+               if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
+                       this._notifyChange(inst);
+               }
+               this._adjustInstDate(inst);
+               if (inst.input) {
+                       inst.input.val(clear ? "" : this._formatDate(inst));
+               }
+       },
+
+       /* Retrieve the date(s) directly. */
+       _getDate: function(inst) {
+               var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
+                       this._daylightSavingAdjust(new Date(
+                       inst.currentYear, inst.currentMonth, inst.currentDay)));
+                       return startDate;
+       },
+
+       /* Attach the onxxx handlers.  These are declared statically so
+        * they work with static code transformers like Caja.
+        */
+       _attachHandlers: function(inst) {
+               var stepMonths = this._get(inst, "stepMonths"),
+                       id = "#" + inst.id.replace( /\\\\/g, "\\" );
+               inst.dpDiv.find("[data-handler]").map(function () {
+                       var handler = {
+                               prev: function () {
+                                       $.datepicker._adjustDate(id, -stepMonths, "M");
+                               },
+                               next: function () {
+                                       $.datepicker._adjustDate(id, +stepMonths, "M");
+                               },
+                               hide: function () {
+                                       $.datepicker._hideDatepicker();
+                               },
+                               today: function () {
+                                       $.datepicker._gotoToday(id);
+                               },
+                               selectDay: function () {
+                                       $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
+                                       return false;
+                               },
+                               selectMonth: function () {
+                                       $.datepicker._selectMonthYear(id, this, "M");
+                                       return false;
+                               },
+                               selectYear: function () {
+                                       $.datepicker._selectMonthYear(id, this, "Y");
+                                       return false;
+                               }
+                       };
+                       $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
+               });
+       },
+
+       /* Generate the HTML for the current state of the date picker. */
+       _generateHTML: function(inst) {
+               var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
+                       controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
+                       monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
+                       selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
+                       cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
+                       printDate, dRow, tbody, daySettings, otherMonth, unselectable,
+                       tempDate = new Date(),
+                       today = this._daylightSavingAdjust(
+                               new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
+                       isRTL = this._get(inst, "isRTL"),
+                       showButtonPanel = this._get(inst, "showButtonPanel"),
+                       hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
+                       navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
+                       numMonths = this._getNumberOfMonths(inst),
+                       showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
+                       stepMonths = this._get(inst, "stepMonths"),
+                       isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
+                       currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
+                               new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
+                       minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       drawMonth = inst.drawMonth - showCurrentAtPos,
+                       drawYear = inst.drawYear;
+
+               if (drawMonth < 0) {
+                       drawMonth += 12;
+                       drawYear--;
+               }
+               if (maxDate) {
+                       maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
+                               maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
+                       maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+                       while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
+                               drawMonth--;
+                               if (drawMonth < 0) {
+                                       drawMonth = 11;
+                                       drawYear--;
+                               }
+                       }
+               }
+               inst.drawMonth = drawMonth;
+               inst.drawYear = drawYear;
+
+               prevText = this._get(inst, "prevText");
+               prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+
+               prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
+                       "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
+                       " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
+                       (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
+
+               nextText = this._get(inst, "nextText");
+               nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+
+               next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+                       "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
+                       " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
+                       (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
+
+               currentText = this._get(inst, "currentText");
+               gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
+               currentText = (!navigationAsDateFormat ? currentText :
+                       this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
+
+               controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
+                       this._get(inst, "closeText") + "</button>" : "");
+
+               buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
+                       (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
+                       ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
+
+               firstDay = parseInt(this._get(inst, "firstDay"),10);
+               firstDay = (isNaN(firstDay) ? 0 : firstDay);
+
+               showWeek = this._get(inst, "showWeek");
+               dayNames = this._get(inst, "dayNames");
+               dayNamesMin = this._get(inst, "dayNamesMin");
+               monthNames = this._get(inst, "monthNames");
+               monthNamesShort = this._get(inst, "monthNamesShort");
+               beforeShowDay = this._get(inst, "beforeShowDay");
+               showOtherMonths = this._get(inst, "showOtherMonths");
+               selectOtherMonths = this._get(inst, "selectOtherMonths");
+               defaultDate = this._getDefaultDate(inst);
+               html = "";
+               dow;
+               for (row = 0; row < numMonths[0]; row++) {
+                       group = "";
+                       this.maxRows = 4;
+                       for (col = 0; col < numMonths[1]; col++) {
+                               selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
+                               cornerClass = " ui-corner-all";
+                               calender = "";
+                               if (isMultiMonth) {
+                                       calender += "<div class='ui-datepicker-group";
+                                       if (numMonths[1] > 1) {
+                                               switch (col) {
+                                                       case 0: calender += " ui-datepicker-group-first";
+                                                               cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
+                                                       case numMonths[1]-1: calender += " ui-datepicker-group-last";
+                                                               cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
+                                                       default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
+                                               }
+                                       }
+                                       calender += "'>";
+                               }
+                               calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
+                                       (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
+                                       (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
+                                       this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+                                       row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
+                                       "</div><table class='ui-datepicker-calendar'><thead>" +
+                                       "<tr>";
+                               thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
+                               for (dow = 0; dow < 7; dow++) { // days of the week
+                                       day = (dow + firstDay) % 7;
+                                       thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
+                                               "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
+                               }
+                               calender += thead + "</tr></thead><tbody>";
+                               daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+                               if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
+                                       inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+                               }
+                               leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+                               curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
+                               numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
+                               this.maxRows = numRows;
+                               printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
+                               for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+                                       calender += "<tr>";
+                                       tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
+                                               this._get(inst, "calculateWeek")(printDate) + "</td>");
+                                       for (dow = 0; dow < 7; dow++) { // create date picker days
+                                               daySettings = (beforeShowDay ?
+                                                       beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
+                                               otherMonth = (printDate.getMonth() !== drawMonth);
+                                               unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
+                                                       (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+                                               tbody += "<td class='" +
+                                                       ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
+                                                       (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
+                                                       ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
+                                                       (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
+                                                       // or defaultDate is current printedDate and defaultDate is selectedDate
+                                                       " " + this._dayOverClass : "") + // highlight selected day
+                                                       (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
+                                                       (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
+                                                       (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
+                                                       (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
+                                                       ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
+                                                       (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
+                                                       (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
+                                                       (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
+                                                       (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
+                                                       (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
+                                                       (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
+                                                       "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
+                                               printDate.setDate(printDate.getDate() + 1);
+                                               printDate = this._daylightSavingAdjust(printDate);
+                                       }
+                                       calender += tbody + "</tr>";
+                               }
+                               drawMonth++;
+                               if (drawMonth > 11) {
+                                       drawMonth = 0;
+                                       drawYear++;
+                               }
+                               calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
+                                                       ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
+                               group += calender;
+                       }
+                       html += group;
+               }
+               html += buttonPanel;
+               inst._keyEvent = false;
+               return html;
+       },
+
+       /* Generate the month and year header. */
+       _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+                       secondary, monthNames, monthNamesShort) {
+
+               var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
+                       changeMonth = this._get(inst, "changeMonth"),
+                       changeYear = this._get(inst, "changeYear"),
+                       showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
+                       html = "<div class='ui-datepicker-title'>",
+                       monthHtml = "";
+
+               // month selection
+               if (secondary || !changeMonth) {
+                       monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
+               } else {
+                       inMinYear = (minDate && minDate.getFullYear() === drawYear);
+                       inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
+                       monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
+                       for ( month = 0; month < 12; month++) {
+                               if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
+                                       monthHtml += "<option value='" + month + "'" +
+                                               (month === drawMonth ? " selected='selected'" : "") +
+                                               ">" + monthNamesShort[month] + "</option>";
+                               }
+                       }
+                       monthHtml += "</select>";
+               }
+
+               if (!showMonthAfterYear) {
+                       html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
+               }
+
+               // year selection
+               if ( !inst.yearshtml ) {
+                       inst.yearshtml = "";
+                       if (secondary || !changeYear) {
+                               html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
+                       } else {
+                               // determine range of years to display
+                               years = this._get(inst, "yearRange").split(":");
+                               thisYear = new Date().getFullYear();
+                               determineYear = function(value) {
+                                       var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+                                               (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
+                                               parseInt(value, 10)));
+                                       return (isNaN(year) ? thisYear : year);
+                               };
+                               year = determineYear(years[0]);
+                               endYear = Math.max(year, determineYear(years[1] || ""));
+                               year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+                               endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+                               inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
+                               for (; year <= endYear; year++) {
+                                       inst.yearshtml += "<option value='" + year + "'" +
+                                               (year === drawYear ? " selected='selected'" : "") +
+                                               ">" + year + "</option>";
+                               }
+                               inst.yearshtml += "</select>";
+
+                               html += inst.yearshtml;
+                               inst.yearshtml = null;
+                       }
+               }
+
+               html += this._get(inst, "yearSuffix");
+               if (showMonthAfterYear) {
+                       html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
+               }
+               html += "</div>"; // Close datepicker_header
+               return html;
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustInstDate: function(inst, offset, period) {
+               var year = inst.drawYear + (period === "Y" ? offset : 0),
+                       month = inst.drawMonth + (period === "M" ? offset : 0),
+                       day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
+                       date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
+
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               if (period === "M" || period === "Y") {
+                       this._notifyChange(inst);
+               }
+       },
+
+       /* Ensure a date is within any min/max bounds. */
+       _restrictMinMax: function(inst, date) {
+               var minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       newDate = (minDate && date < minDate ? minDate : date);
+               return (maxDate && newDate > maxDate ? maxDate : newDate);
+       },
+
+       /* Notify change of month/year. */
+       _notifyChange: function(inst) {
+               var onChange = this._get(inst, "onChangeMonthYear");
+               if (onChange) {
+                       onChange.apply((inst.input ? inst.input[0] : null),
+                               [inst.selectedYear, inst.selectedMonth + 1, inst]);
+               }
+       },
+
+       /* Determine the number of months to show. */
+       _getNumberOfMonths: function(inst) {
+               var numMonths = this._get(inst, "numberOfMonths");
+               return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
+       },
+
+       /* Determine the current maximum date - ensure no time components are set. */
+       _getMinMaxDate: function(inst, minMax) {
+               return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
+       },
+
+       /* Find the number of days in a given month. */
+       _getDaysInMonth: function(year, month) {
+               return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
+       },
+
+       /* Find the day of the week of the first of a month. */
+       _getFirstDayOfMonth: function(year, month) {
+               return new Date(year, month, 1).getDay();
+       },
+
+       /* Determines if we should allow a "next/prev" month display change. */
+       _canAdjustMonth: function(inst, offset, curYear, curMonth) {
+               var numMonths = this._getNumberOfMonths(inst),
+                       date = this._daylightSavingAdjust(new Date(curYear,
+                       curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
+
+               if (offset < 0) {
+                       date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+               }
+               return this._isInRange(inst, date);
+       },
+
+       /* Is the given date in the accepted range? */
+       _isInRange: function(inst, date) {
+               var yearSplit, currentYear,
+                       minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       minYear = null,
+                       maxYear = null,
+                       years = this._get(inst, "yearRange");
+                       if (years){
+                               yearSplit = years.split(":");
+                               currentYear = new Date().getFullYear();
+                               minYear = parseInt(yearSplit[0], 10);
+                               maxYear = parseInt(yearSplit[1], 10);
+                               if ( yearSplit[0].match(/[+\-].*/) ) {
+                                       minYear += currentYear;
+                               }
+                               if ( yearSplit[1].match(/[+\-].*/) ) {
+                                       maxYear += currentYear;
+                               }
+                       }
+
+               return ((!minDate || date.getTime() >= minDate.getTime()) &&
+                       (!maxDate || date.getTime() <= maxDate.getTime()) &&
+                       (!minYear || date.getFullYear() >= minYear) &&
+                       (!maxYear || date.getFullYear() <= maxYear));
+       },
+
+       /* Provide the configuration settings for formatting/parsing. */
+       _getFormatConfig: function(inst) {
+               var shortYearCutoff = this._get(inst, "shortYearCutoff");
+               shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
+                       new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+               return {shortYearCutoff: shortYearCutoff,
+                       dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
+                       monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
+       },
+
+       /* Format the given date for display. */
+       _formatDate: function(inst, day, month, year) {
+               if (!day) {
+                       inst.currentDay = inst.selectedDay;
+                       inst.currentMonth = inst.selectedMonth;
+                       inst.currentYear = inst.selectedYear;
+               }
+               var date = (day ? (typeof day === "object" ? day :
+                       this._daylightSavingAdjust(new Date(year, month, day))) :
+                       this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+               return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
+       }
+});
+
+/*
+ * Bind hover events for datepicker elements.
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
+ * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
+ */
+function datepicker_bindHover(dpDiv) {
+       var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
+       return dpDiv.delegate(selector, "mouseout", function() {
+                       $(this).removeClass("ui-state-hover");
+                       if (this.className.indexOf("ui-datepicker-prev") !== -1) {
+                               $(this).removeClass("ui-datepicker-prev-hover");
+                       }
+                       if (this.className.indexOf("ui-datepicker-next") !== -1) {
+                               $(this).removeClass("ui-datepicker-next-hover");
+                       }
+               })
+               .delegate( selector, "mouseover", datepicker_handleMouseover );
+}
+
+function datepicker_handleMouseover() {
+       if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
+               $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
+               $(this).addClass("ui-state-hover");
+               if (this.className.indexOf("ui-datepicker-prev") !== -1) {
+                       $(this).addClass("ui-datepicker-prev-hover");
+               }
+               if (this.className.indexOf("ui-datepicker-next") !== -1) {
+                       $(this).addClass("ui-datepicker-next-hover");
+               }
+       }
+}
+
+/* jQuery extend now ignores nulls! */
+function datepicker_extendRemove(target, props) {
+       $.extend(target, props);
+       for (var name in props) {
+               if (props[name] == null) {
+                       target[name] = props[name];
+               }
+       }
+       return target;
+}
+
+/* Invoke the datepicker functionality.
+   @param  options  string - a command, optionally followed by additional parameters or
+                                       Object - settings for attaching new datepicker functionality
+   @return  jQuery object */
+$.fn.datepicker = function(options){
+
+       /* Verify an empty collection wasn't passed - Fixes #6976 */
+       if ( !this.length ) {
+               return this;
+       }
+
+       /* Initialise the date picker. */
+       if (!$.datepicker.initialized) {
+               $(document).mousedown($.datepicker._checkExternalClick);
+               $.datepicker.initialized = true;
+       }
+
+       /* Append datepicker main container to body if not exist. */
+       if ($("#"+$.datepicker._mainDivId).length === 0) {
+               $("body").append($.datepicker.dpDiv);
+       }
+
+       var otherArgs = Array.prototype.slice.call(arguments, 1);
+       if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
+               return $.datepicker["_" + options + "Datepicker"].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       }
+       if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
+               return $.datepicker["_" + options + "Datepicker"].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       }
+       return this.each(function() {
+               typeof options === "string" ?
+                       $.datepicker["_" + options + "Datepicker"].
+                               apply($.datepicker, [this].concat(otherArgs)) :
+                       $.datepicker._attachDatepicker(this, options);
+       });
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.11.3";
+
+var datepicker = $.datepicker;
+
+
+/*!
+ * jQuery UI Dialog 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/dialog/
+ */
+
+
+var dialog = $.widget( "ui.dialog", {
+       version: "1.11.3",
+       options: {
+               appendTo: "body",
+               autoOpen: true,
+               buttons: [],
+               closeOnEscape: true,
+               closeText: "Close",
+               dialogClass: "",
+               draggable: true,
+               hide: null,
+               height: "auto",
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 150,
+               minWidth: 150,
+               modal: false,
+               position: {
+                       my: "center",
+                       at: "center",
+                       of: window,
+                       collision: "fit",
+                       // Ensure the titlebar is always visible
+                       using: function( pos ) {
+                               var topOffset = $( this ).css( pos ).offset().top;
+                               if ( topOffset < 0 ) {
+                                       $( this ).css( "top", pos.top - topOffset );
+                               }
+                       }
+               },
+               resizable: true,
+               show: null,
+               title: null,
+               width: 300,
+
+               // callbacks
+               beforeClose: null,
+               close: null,
+               drag: null,
+               dragStart: null,
+               dragStop: null,
+               focus: null,
+               open: null,
+               resize: null,
+               resizeStart: null,
+               resizeStop: null
+       },
+
+       sizeRelatedOptions: {
+               buttons: true,
+               height: true,
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true,
+               width: true
+       },
+
+       resizableRelatedOptions: {
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true
+       },
+
+       _create: function() {
+               this.originalCss = {
+                       display: this.element[ 0 ].style.display,
+                       width: this.element[ 0 ].style.width,
+                       minHeight: this.element[ 0 ].style.minHeight,
+                       maxHeight: this.element[ 0 ].style.maxHeight,
+                       height: this.element[ 0 ].style.height
+               };
+               this.originalPosition = {
+                       parent: this.element.parent(),
+                       index: this.element.parent().children().index( this.element )
+               };
+               this.originalTitle = this.element.attr( "title" );
+               this.options.title = this.options.title || this.originalTitle;
+
+               this._createWrapper();
+
+               this.element
+                       .show()
+                       .removeAttr( "title" )
+                       .addClass( "ui-dialog-content ui-widget-content" )
+                       .appendTo( this.uiDialog );
+
+               this._createTitlebar();
+               this._createButtonPane();
+
+               if ( this.options.draggable && $.fn.draggable ) {
+                       this._makeDraggable();
+               }
+               if ( this.options.resizable && $.fn.resizable ) {
+                       this._makeResizable();
+               }
+
+               this._isOpen = false;
+
+               this._trackFocus();
+       },
+
+       _init: function() {
+               if ( this.options.autoOpen ) {
+                       this.open();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+               if ( element && (element.jquery || element.nodeType) ) {
+                       return $( element );
+               }
+               return this.document.find( element || "body" ).eq( 0 );
+       },
+
+       _destroy: function() {
+               var next,
+                       originalPosition = this.originalPosition;
+
+               this._destroyOverlay();
+
+               this.element
+                       .removeUniqueId()
+                       .removeClass( "ui-dialog-content ui-widget-content" )
+                       .css( this.originalCss )
+                       // Without detaching first, the following becomes really slow
+                       .detach();
+
+               this.uiDialog.stop( true, true ).remove();
+
+               if ( this.originalTitle ) {
+                       this.element.attr( "title", this.originalTitle );
+               }
+
+               next = originalPosition.parent.children().eq( originalPosition.index );
+               // Don't try to place the dialog next to itself (#8613)
+               if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
+                       next.before( this.element );
+               } else {
+                       originalPosition.parent.append( this.element );
+               }
+       },
+
+       widget: function() {
+               return this.uiDialog;
+       },
+
+       disable: $.noop,
+       enable: $.noop,
+
+       close: function( event ) {
+               var activeElement,
+                       that = this;
+
+               if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
+                       return;
+               }
+
+               this._isOpen = false;
+               this._focusedElement = null;
+               this._destroyOverlay();
+               this._untrackInstance();
+
+               if ( !this.opener.filter( ":focusable" ).focus().length ) {
+
+                       // support: IE9
+                       // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+                       try {
+                               activeElement = this.document[ 0 ].activeElement;
+
+                               // Support: IE9, IE10
+                               // If the <body> is blurred, IE will switch windows, see #4520
+                               if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
+
+                                       // Hiding a focused element doesn't trigger blur in WebKit
+                                       // so in case we have nothing to focus on, explicitly blur the active element
+                                       // https://bugs.webkit.org/show_bug.cgi?id=47182
+                                       $( activeElement ).blur();
+                               }
+                       } catch ( error ) {}
+               }
+
+               this._hide( this.uiDialog, this.options.hide, function() {
+                       that._trigger( "close", event );
+               });
+       },
+
+       isOpen: function() {
+               return this._isOpen;
+       },
+
+       moveToTop: function() {
+               this._moveToTop();
+       },
+
+       _moveToTop: function( event, silent ) {
+               var moved = false,
+                       zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
+                               return +$( this ).css( "z-index" );
+                       }).get(),
+                       zIndexMax = Math.max.apply( null, zIndicies );
+
+               if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
+                       this.uiDialog.css( "z-index", zIndexMax + 1 );
+                       moved = true;
+               }
+
+               if ( moved && !silent ) {
+                       this._trigger( "focus", event );
+               }
+               return moved;
+       },
+
+       open: function() {
+               var that = this;
+               if ( this._isOpen ) {
+                       if ( this._moveToTop() ) {
+                               this._focusTabbable();
+                       }
+                       return;
+               }
+
+               this._isOpen = true;
+               this.opener = $( this.document[ 0 ].activeElement );
+
+               this._size();
+               this._position();
+               this._createOverlay();
+               this._moveToTop( null, true );
+
+               // Ensure the overlay is moved to the top with the dialog, but only when
+               // opening. The overlay shouldn't move after the dialog is open so that
+               // modeless dialogs opened after the modal dialog stack properly.
+               if ( this.overlay ) {
+                       this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
+               }
+
+               this._show( this.uiDialog, this.options.show, function() {
+                       that._focusTabbable();
+                       that._trigger( "focus" );
+               });
+
+               // Track the dialog immediately upon openening in case a focus event
+               // somehow occurs outside of the dialog before an element inside the
+               // dialog is focused (#10152)
+               this._makeFocusTarget();
+
+               this._trigger( "open" );
+       },
+
+       _focusTabbable: function() {
+               // Set focus to the first match:
+               // 1. An element that was focused previously
+               // 2. First element inside the dialog matching [autofocus]
+               // 3. Tabbable element inside the content element
+               // 4. Tabbable element inside the buttonpane
+               // 5. The close button
+               // 6. The dialog itself
+               var hasFocus = this._focusedElement;
+               if ( !hasFocus ) {
+                       hasFocus = this.element.find( "[autofocus]" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.element.find( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialog;
+               }
+               hasFocus.eq( 0 ).focus();
+       },
+
+       _keepFocus: function( event ) {
+               function checkFocus() {
+                       var activeElement = this.document[0].activeElement,
+                               isActive = this.uiDialog[0] === activeElement ||
+                                       $.contains( this.uiDialog[0], activeElement );
+                       if ( !isActive ) {
+                               this._focusTabbable();
+                       }
+               }
+               event.preventDefault();
+               checkFocus.call( this );
+               // support: IE
+               // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
+               // so we check again later
+               this._delay( checkFocus );
+       },
+
+       _createWrapper: function() {
+               this.uiDialog = $("<div>")
+                       .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
+                               this.options.dialogClass )
+                       .hide()
+                       .attr({
+                               // Setting tabIndex makes the div focusable
+                               tabIndex: -1,
+                               role: "dialog"
+                       })
+                       .appendTo( this._appendTo() );
+
+               this._on( this.uiDialog, {
+                       keydown: function( event ) {
+                               if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+                                               event.keyCode === $.ui.keyCode.ESCAPE ) {
+                                       event.preventDefault();
+                                       this.close( event );
+                                       return;
+                               }
+
+                               // prevent tabbing out of dialogs
+                               if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
+                                       return;
+                               }
+                               var tabbables = this.uiDialog.find( ":tabbable" ),
+                                       first = tabbables.filter( ":first" ),
+                                       last = tabbables.filter( ":last" );
+
+                               if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
+                                       this._delay(function() {
+                                               first.focus();
+                                       });
+                                       event.preventDefault();
+                               } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
+                                       this._delay(function() {
+                                               last.focus();
+                                       });
+                                       event.preventDefault();
+                               }
+                       },
+                       mousedown: function( event ) {
+                               if ( this._moveToTop( event ) ) {
+                                       this._focusTabbable();
+                               }
+                       }
+               });
+
+               // We assume that any existing aria-describedby attribute means
+               // that the dialog content is marked up properly
+               // otherwise we brute force the content as the description
+               if ( !this.element.find( "[aria-describedby]" ).length ) {
+                       this.uiDialog.attr({
+                               "aria-describedby": this.element.uniqueId().attr( "id" )
+                       });
+               }
+       },
+
+       _createTitlebar: function() {
+               var uiDialogTitle;
+
+               this.uiDialogTitlebar = $( "<div>" )
+                       .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
+                       .prependTo( this.uiDialog );
+               this._on( this.uiDialogTitlebar, {
+                       mousedown: function( event ) {
+                               // Don't prevent click on close button (#8838)
+                               // Focusing a dialog that is partially scrolled out of view
+                               // causes the browser to scroll it into view, preventing the click event
+                               if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
+                                       // Dialog isn't getting focus when dragging (#8063)
+                                       this.uiDialog.focus();
+                               }
+                       }
+               });
+
+               // support: IE
+               // Use type="button" to prevent enter keypresses in textboxes from closing the
+               // dialog in IE (#9312)
+               this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
+                       .button({
+                               label: this.options.closeText,
+                               icons: {
+                                       primary: "ui-icon-closethick"
+                               },
+                               text: false
+                       })
+                       .addClass( "ui-dialog-titlebar-close" )
+                       .appendTo( this.uiDialogTitlebar );
+               this._on( this.uiDialogTitlebarClose, {
+                       click: function( event ) {
+                               event.preventDefault();
+                               this.close( event );
+                       }
+               });
+
+               uiDialogTitle = $( "<span>" )
+                       .uniqueId()
+                       .addClass( "ui-dialog-title" )
+                       .prependTo( this.uiDialogTitlebar );
+               this._title( uiDialogTitle );
+
+               this.uiDialog.attr({
+                       "aria-labelledby": uiDialogTitle.attr( "id" )
+               });
+       },
+
+       _title: function( title ) {
+               if ( !this.options.title ) {
+                       title.html( "&#160;" );
+               }
+               title.text( this.options.title );
+       },
+
+       _createButtonPane: function() {
+               this.uiDialogButtonPane = $( "<div>" )
+                       .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
+
+               this.uiButtonSet = $( "<div>" )
+                       .addClass( "ui-dialog-buttonset" )
+                       .appendTo( this.uiDialogButtonPane );
+
+               this._createButtons();
+       },
+
+       _createButtons: function() {
+               var that = this,
+                       buttons = this.options.buttons;
+
+               // if we already have a button pane, remove it
+               this.uiDialogButtonPane.remove();
+               this.uiButtonSet.empty();
+
+               if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
+                       this.uiDialog.removeClass( "ui-dialog-buttons" );
+                       return;
+               }
+
+               $.each( buttons, function( name, props ) {
+                       var click, buttonOptions;
+                       props = $.isFunction( props ) ?
+                               { click: props, text: name } :
+                               props;
+                       // Default to a non-submitting button
+                       props = $.extend( { type: "button" }, props );
+                       // Change the context for the click callback to be the main element
+                       click = props.click;
+                       props.click = function() {
+                               click.apply( that.element[ 0 ], arguments );
+                       };
+                       buttonOptions = {
+                               icons: props.icons,
+                               text: props.showText
+                       };
+                       delete props.icons;
+                       delete props.showText;
+                       $( "<button></button>", props )
+                               .button( buttonOptions )
+                               .appendTo( that.uiButtonSet );
+               });
+               this.uiDialog.addClass( "ui-dialog-buttons" );
+               this.uiDialogButtonPane.appendTo( this.uiDialog );
+       },
+
+       _makeDraggable: function() {
+               var that = this,
+                       options = this.options;
+
+               function filteredUi( ui ) {
+                       return {
+                               position: ui.position,
+                               offset: ui.offset
+                       };
+               }
+
+               this.uiDialog.draggable({
+                       cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
+                       handle: ".ui-dialog-titlebar",
+                       containment: "document",
+                       start: function( event, ui ) {
+                               $( this ).addClass( "ui-dialog-dragging" );
+                               that._blockFrames();
+                               that._trigger( "dragStart", event, filteredUi( ui ) );
+                       },
+                       drag: function( event, ui ) {
+                               that._trigger( "drag", event, filteredUi( ui ) );
+                       },
+                       stop: function( event, ui ) {
+                               var left = ui.offset.left - that.document.scrollLeft(),
+                                       top = ui.offset.top - that.document.scrollTop();
+
+                               options.position = {
+                                       my: "left top",
+                                       at: "left" + (left >= 0 ? "+" : "") + left + " " +
+                                               "top" + (top >= 0 ? "+" : "") + top,
+                                       of: that.window
+                               };
+                               $( this ).removeClass( "ui-dialog-dragging" );
+                               that._unblockFrames();
+                               that._trigger( "dragStop", event, filteredUi( ui ) );
+                       }
+               });
+       },
+
+       _makeResizable: function() {
+               var that = this,
+                       options = this.options,
+                       handles = options.resizable,
+                       // .ui-resizable has position: relative defined in the stylesheet
+                       // but dialogs have to use absolute or fixed positioning
+                       position = this.uiDialog.css("position"),
+                       resizeHandles = typeof handles === "string" ?
+                               handles :
+                               "n,e,s,w,se,sw,ne,nw";
+
+               function filteredUi( ui ) {
+                       return {
+                               originalPosition: ui.originalPosition,
+                               originalSize: ui.originalSize,
+                               position: ui.position,
+                               size: ui.size
+                       };
+               }
+
+               this.uiDialog.resizable({
+                       cancel: ".ui-dialog-content",
+                       containment: "document",
+                       alsoResize: this.element,
+                       maxWidth: options.maxWidth,
+                       maxHeight: options.maxHeight,
+                       minWidth: options.minWidth,
+                       minHeight: this._minHeight(),
+                       handles: resizeHandles,
+                       start: function( event, ui ) {
+                               $( this ).addClass( "ui-dialog-resizing" );
+                               that._blockFrames();
+                               that._trigger( "resizeStart", event, filteredUi( ui ) );
+                       },
+                       resize: function( event, ui ) {
+                               that._trigger( "resize", event, filteredUi( ui ) );
+                       },
+                       stop: function( event, ui ) {
+                               var offset = that.uiDialog.offset(),
+                                       left = offset.left - that.document.scrollLeft(),
+                                       top = offset.top - that.document.scrollTop();
+
+                               options.height = that.uiDialog.height();
+                               options.width = that.uiDialog.width();
+                               options.position = {
+                                       my: "left top",
+                                       at: "left" + (left >= 0 ? "+" : "") + left + " " +
+                                               "top" + (top >= 0 ? "+" : "") + top,
+                                       of: that.window
+                               };
+                               $( this ).removeClass( "ui-dialog-resizing" );
+                               that._unblockFrames();
+                               that._trigger( "resizeStop", event, filteredUi( ui ) );
+                       }
+               })
+               .css( "position", position );
+       },
+
+       _trackFocus: function() {
+               this._on( this.widget(), {
+                       focusin: function( event ) {
+                               this._makeFocusTarget();
+                               this._focusedElement = $( event.target );
+                       }
+               });
+       },
+
+       _makeFocusTarget: function() {
+               this._untrackInstance();
+               this._trackingInstances().unshift( this );
+       },
+
+       _untrackInstance: function() {
+               var instances = this._trackingInstances(),
+                       exists = $.inArray( this, instances );
+               if ( exists !== -1 ) {
+                       instances.splice( exists, 1 );
+               }
+       },
+
+       _trackingInstances: function() {
+               var instances = this.document.data( "ui-dialog-instances" );
+               if ( !instances ) {
+                       instances = [];
+                       this.document.data( "ui-dialog-instances", instances );
+               }
+               return instances;
+       },
+
+       _minHeight: function() {
+               var options = this.options;
+
+               return options.height === "auto" ?
+                       options.minHeight :
+                       Math.min( options.minHeight, options.height );
+       },
+
+       _position: function() {
+               // Need to show the dialog to get the actual offset in the position plugin
+               var isVisible = this.uiDialog.is( ":visible" );
+               if ( !isVisible ) {
+                       this.uiDialog.show();
+               }
+               this.uiDialog.position( this.options.position );
+               if ( !isVisible ) {
+                       this.uiDialog.hide();
+               }
+       },
+
+       _setOptions: function( options ) {
+               var that = this,
+                       resize = false,
+                       resizableOptions = {};
+
+               $.each( options, function( key, value ) {
+                       that._setOption( key, value );
+
+                       if ( key in that.sizeRelatedOptions ) {
+                               resize = true;
+                       }
+                       if ( key in that.resizableRelatedOptions ) {
+                               resizableOptions[ key ] = value;
+                       }
+               });
+
+               if ( resize ) {
+                       this._size();
+                       this._position();
+               }
+               if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+                       this.uiDialog.resizable( "option", resizableOptions );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               var isDraggable, isResizable,
+                       uiDialog = this.uiDialog;
+
+               if ( key === "dialogClass" ) {
+                       uiDialog
+                               .removeClass( this.options.dialogClass )
+                               .addClass( value );
+               }
+
+               if ( key === "disabled" ) {
+                       return;
+               }
+
+               this._super( key, value );
+
+               if ( key === "appendTo" ) {
+                       this.uiDialog.appendTo( this._appendTo() );
+               }
+
+               if ( key === "buttons" ) {
+                       this._createButtons();
+               }
+
+               if ( key === "closeText" ) {
+                       this.uiDialogTitlebarClose.button({
+                               // Ensure that we always pass a string
+                               label: "" + value
+                       });
+               }
+
+               if ( key === "draggable" ) {
+                       isDraggable = uiDialog.is( ":data(ui-draggable)" );
+                       if ( isDraggable && !value ) {
+                               uiDialog.draggable( "destroy" );
+                       }
+
+                       if ( !isDraggable && value ) {
+                               this._makeDraggable();
+                       }
+               }
+
+               if ( key === "position" ) {
+                       this._position();
+               }
+
+               if ( key === "resizable" ) {
+                       // currently resizable, becoming non-resizable
+                       isResizable = uiDialog.is( ":data(ui-resizable)" );
+                       if ( isResizable && !value ) {
+                               uiDialog.resizable( "destroy" );
+                       }
+
+                       // currently resizable, changing handles
+                       if ( isResizable && typeof value === "string" ) {
+                               uiDialog.resizable( "option", "handles", value );
+                       }
+
+                       // currently non-resizable, becoming resizable
+                       if ( !isResizable && value !== false ) {
+                               this._makeResizable();
+                       }
+               }
+
+               if ( key === "title" ) {
+                       this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
+               }
+       },
+
+       _size: function() {
+               // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+               // divs will both have width and height set, so we need to reset them
+               var nonContentHeight, minContentHeight, maxContentHeight,
+                       options = this.options;
+
+               // Reset content sizing
+               this.element.show().css({
+                       width: "auto",
+                       minHeight: 0,
+                       maxHeight: "none",
+                       height: 0
+               });
+
+               if ( options.minWidth > options.width ) {
+                       options.width = options.minWidth;
+               }
+
+               // reset wrapper sizing
+               // determine the height of all the non-content elements
+               nonContentHeight = this.uiDialog.css({
+                               height: "auto",
+                               width: options.width
+                       })
+                       .outerHeight();
+               minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+               maxContentHeight = typeof options.maxHeight === "number" ?
+                       Math.max( 0, options.maxHeight - nonContentHeight ) :
+                       "none";
+
+               if ( options.height === "auto" ) {
+                       this.element.css({
+                               minHeight: minContentHeight,
+                               maxHeight: maxContentHeight,
+                               height: "auto"
+                       });
+               } else {
+                       this.element.height( Math.max( 0, options.height - nonContentHeight ) );
+               }
+
+               if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+                       this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
+               }
+       },
+
+       _blockFrames: function() {
+               this.iframeBlocks = this.document.find( "iframe" ).map(function() {
+                       var iframe = $( this );
+
+                       return $( "<div>" )
+                               .css({
+                                       position: "absolute",
+                                       width: iframe.outerWidth(),
+                                       height: iframe.outerHeight()
+                               })
+                               .appendTo( iframe.parent() )
+                               .offset( iframe.offset() )[0];
+               });
+       },
+
+       _unblockFrames: function() {
+               if ( this.iframeBlocks ) {
+                       this.iframeBlocks.remove();
+                       delete this.iframeBlocks;
+               }
+       },
+
+       _allowInteraction: function( event ) {
+               if ( $( event.target ).closest( ".ui-dialog" ).length ) {
+                       return true;
+               }
+
+               // TODO: Remove hack when datepicker implements
+               // the .ui-front logic (#8989)
+               return !!$( event.target ).closest( ".ui-datepicker" ).length;
+       },
+
+       _createOverlay: function() {
+               if ( !this.options.modal ) {
+                       return;
+               }
+
+               // We use a delay in case the overlay is created from an
+               // event that we're going to be cancelling (#2804)
+               var isOpening = true;
+               this._delay(function() {
+                       isOpening = false;
+               });
+
+               if ( !this.document.data( "ui-dialog-overlays" ) ) {
+
+                       // Prevent use of anchors and inputs
+                       // Using _on() for an event handler shared across many instances is
+                       // safe because the dialogs stack and must be closed in reverse order
+                       this._on( this.document, {
+                               focusin: function( event ) {
+                                       if ( isOpening ) {
+                                               return;
+                                       }
+
+                                       if ( !this._allowInteraction( event ) ) {
+                                               event.preventDefault();
+                                               this._trackingInstances()[ 0 ]._focusTabbable();
+                                       }
+                               }
+                       });
+               }
+
+               this.overlay = $( "<div>" )
+                       .addClass( "ui-widget-overlay ui-front" )
+                       .appendTo( this._appendTo() );
+               this._on( this.overlay, {
+                       mousedown: "_keepFocus"
+               });
+               this.document.data( "ui-dialog-overlays",
+                       (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
+       },
+
+       _destroyOverlay: function() {
+               if ( !this.options.modal ) {
+                       return;
+               }
+
+               if ( this.overlay ) {
+                       var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
+
+                       if ( !overlays ) {
+                               this.document
+                                       .unbind( "focusin" )
+                                       .removeData( "ui-dialog-overlays" );
+                       } else {
+                               this.document.data( "ui-dialog-overlays", overlays );
+                       }
+
+                       this.overlay.remove();
+                       this.overlay = null;
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Progressbar 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/progressbar/
+ */
+
+
+var progressbar = $.widget( "ui.progressbar", {
+       version: "1.11.3",
+       options: {
+               max: 100,
+               value: 0,
+
+               change: null,
+               complete: null
+       },
+
+       min: 0,
+
+       _create: function() {
+               // Constrain initial value
+               this.oldValue = this.options.value = this._constrainedValue();
+
+               this.element
+                       .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .attr({
+                               // Only set static values, aria-valuenow and aria-valuemax are
+                               // set inside _refreshValue()
+                               role: "progressbar",
+                               "aria-valuemin": this.min
+                       });
+
+               this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
+                       .appendTo( this.element );
+
+               this._refreshValue();
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-valuemin" )
+                       .removeAttr( "aria-valuemax" )
+                       .removeAttr( "aria-valuenow" );
+
+               this.valueDiv.remove();
+       },
+
+       value: function( newValue ) {
+               if ( newValue === undefined ) {
+                       return this.options.value;
+               }
+
+               this.options.value = this._constrainedValue( newValue );
+               this._refreshValue();
+       },
+
+       _constrainedValue: function( newValue ) {
+               if ( newValue === undefined ) {
+                       newValue = this.options.value;
+               }
+
+               this.indeterminate = newValue === false;
+
+               // sanitize value
+               if ( typeof newValue !== "number" ) {
+                       newValue = 0;
+               }
+
+               return this.indeterminate ? false :
+                       Math.min( this.options.max, Math.max( this.min, newValue ) );
+       },
+
+       _setOptions: function( options ) {
+               // Ensure "value" option is set after other values (like max)
+               var value = options.value;
+               delete options.value;
+
+               this._super( options );
+
+               this.options.value = this._constrainedValue( value );
+               this._refreshValue();
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "max" ) {
+                       // Don't allow a max less than min
+                       value = Math.max( this.min, value );
+               }
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+               }
+               this._super( key, value );
+       },
+
+       _percentage: function() {
+               return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
+       },
+
+       _refreshValue: function() {
+               var value = this.options.value,
+                       percentage = this._percentage();
+
+               this.valueDiv
+                       .toggle( this.indeterminate || value > this.min )
+                       .toggleClass( "ui-corner-right", value === this.options.max )
+                       .width( percentage.toFixed(0) + "%" );
+
+               this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
+
+               if ( this.indeterminate ) {
+                       this.element.removeAttr( "aria-valuenow" );
+                       if ( !this.overlayDiv ) {
+                               this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
+                       }
+               } else {
+                       this.element.attr({
+                               "aria-valuemax": this.options.max,
+                               "aria-valuenow": value
+                       });
+                       if ( this.overlayDiv ) {
+                               this.overlayDiv.remove();
+                               this.overlayDiv = null;
+                       }
+               }
+
+               if ( this.oldValue !== value ) {
+                       this.oldValue = value;
+                       this._trigger( "change" );
+               }
+               if ( value === this.options.max ) {
+                       this._trigger( "complete" );
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Selectmenu 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/selectmenu
+ */
+
+
+var selectmenu = $.widget( "ui.selectmenu", {
+       version: "1.11.3",
+       defaultElement: "<select>",
+       options: {
+               appendTo: null,
+               disabled: null,
+               icons: {
+                       button: "ui-icon-triangle-1-s"
+               },
+               position: {
+                       my: "left top",
+                       at: "left bottom",
+                       collision: "none"
+               },
+               width: null,
+
+               // callbacks
+               change: null,
+               close: null,
+               focus: null,
+               open: null,
+               select: null
+       },
+
+       _create: function() {
+               var selectmenuId = this.element.uniqueId().attr( "id" );
+               this.ids = {
+                       element: selectmenuId,
+                       button: selectmenuId + "-button",
+                       menu: selectmenuId + "-menu"
+               };
+
+               this._drawButton();
+               this._drawMenu();
+
+               if ( this.options.disabled ) {
+                       this.disable();
+               }
+       },
+
+       _drawButton: function() {
+               var that = this;
+
+               // Associate existing label with the new button
+               this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
+               this._on( this.label, {
+                       click: function( event ) {
+                               this.button.focus();
+                               event.preventDefault();
+                       }
+               });
+
+               // Hide original select element
+               this.element.hide();
+
+               // Create button
+               this.button = $( "<span>", {
+                       "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
+                       tabindex: this.options.disabled ? -1 : 0,
+                       id: this.ids.button,
+                       role: "combobox",
+                       "aria-expanded": "false",
+                       "aria-autocomplete": "list",
+                       "aria-owns": this.ids.menu,
+                       "aria-haspopup": "true"
+               })
+                       .insertAfter( this.element );
+
+               $( "<span>", {
+                       "class": "ui-icon " + this.options.icons.button
+               })
+                       .prependTo( this.button );
+
+               this.buttonText = $( "<span>", {
+                       "class": "ui-selectmenu-text"
+               })
+                       .appendTo( this.button );
+
+               this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
+               this._resizeButton();
+
+               this._on( this.button, this._buttonEvents );
+               this.button.one( "focusin", function() {
+
+                       // Delay rendering the menu items until the button receives focus.
+                       // The menu may have already been rendered via a programmatic open.
+                       if ( !that.menuItems ) {
+                               that._refreshMenu();
+                       }
+               });
+               this._hoverable( this.button );
+               this._focusable( this.button );
+       },
+
+       _drawMenu: function() {
+               var that = this;
+
+               // Create menu
+               this.menu = $( "<ul>", {
+                       "aria-hidden": "true",
+                       "aria-labelledby": this.ids.button,
+                       id: this.ids.menu
+               });
+
+               // Wrap menu
+               this.menuWrap = $( "<div>", {
+                       "class": "ui-selectmenu-menu ui-front"
+               })
+                       .append( this.menu )
+                       .appendTo( this._appendTo() );
+
+               // Initialize menu widget
+               this.menuInstance = this.menu
+                       .menu({
+                               role: "listbox",
+                               select: function( event, ui ) {
+                                       event.preventDefault();
+
+                                       // support: IE8
+                                       // If the item was selected via a click, the text selection
+                                       // will be destroyed in IE
+                                       that._setSelection();
+
+                                       that._select( ui.item.data( "ui-selectmenu-item" ), event );
+                               },
+                               focus: function( event, ui ) {
+                                       var item = ui.item.data( "ui-selectmenu-item" );
+
+                                       // Prevent inital focus from firing and check if its a newly focused item
+                                       if ( that.focusIndex != null && item.index !== that.focusIndex ) {
+                                               that._trigger( "focus", event, { item: item } );
+                                               if ( !that.isOpen ) {
+                                                       that._select( item, event );
+                                               }
+                                       }
+                                       that.focusIndex = item.index;
+
+                                       that.button.attr( "aria-activedescendant",
+                                               that.menuItems.eq( item.index ).attr( "id" ) );
+                               }
+                       })
+                       .menu( "instance" );
+
+               // Adjust menu styles to dropdown
+               this.menu
+                       .addClass( "ui-corner-bottom" )
+                       .removeClass( "ui-corner-all" );
+
+               // Don't close the menu on mouseleave
+               this.menuInstance._off( this.menu, "mouseleave" );
+
+               // Cancel the menu's collapseAll on document click
+               this.menuInstance._closeOnDocumentClick = function() {
+                       return false;
+               };
+
+               // Selects often contain empty items, but never contain dividers
+               this.menuInstance._isDivider = function() {
+                       return false;
+               };
+       },
+
+       refresh: function() {
+               this._refreshMenu();
+               this._setText( this.buttonText, this._getSelectedItem().text() );
+               if ( !this.options.width ) {
+                       this._resizeButton();
+               }
+       },
+
+       _refreshMenu: function() {
+               this.menu.empty();
+
+               var item,
+                       options = this.element.find( "option" );
+
+               if ( !options.length ) {
+                       return;
+               }
+
+               this._parseOptions( options );
+               this._renderMenu( this.menu, this.items );
+
+               this.menuInstance.refresh();
+               this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
+
+               item = this._getSelectedItem();
+
+               // Update the menu to have the correct item focused
+               this.menuInstance.focus( null, item );
+               this._setAria( item.data( "ui-selectmenu-item" ) );
+
+               // Set disabled state
+               this._setOption( "disabled", this.element.prop( "disabled" ) );
+       },
+
+       open: function( event ) {
+               if ( this.options.disabled ) {
+                       return;
+               }
+
+               // If this is the first time the menu is being opened, render the items
+               if ( !this.menuItems ) {
+                       this._refreshMenu();
+               } else {
+
+                       // Menu clears focus on close, reset focus to selected item
+                       this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
+                       this.menuInstance.focus( null, this._getSelectedItem() );
+               }
+
+               this.isOpen = true;
+               this._toggleAttr();
+               this._resizeMenu();
+               this._position();
+
+               this._on( this.document, this._documentClick );
+
+               this._trigger( "open", event );
+       },
+
+       _position: function() {
+               this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
+       },
+
+       close: function( event ) {
+               if ( !this.isOpen ) {
+                       return;
+               }
+
+               this.isOpen = false;
+               this._toggleAttr();
+
+               this.range = null;
+               this._off( this.document );
+
+               this._trigger( "close", event );
+       },
+
+       widget: function() {
+               return this.button;
+       },
+
+       menuWidget: function() {
+               return this.menu;
+       },
+
+       _renderMenu: function( ul, items ) {
+               var that = this,
+                       currentOptgroup = "";
+
+               $.each( items, function( index, item ) {
+                       if ( item.optgroup !== currentOptgroup ) {
+                               $( "<li>", {
+                                       "class": "ui-selectmenu-optgroup ui-menu-divider" +
+                                               ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
+                                                       " ui-state-disabled" :
+                                                       "" ),
+                                       text: item.optgroup
+                               })
+                                       .appendTo( ul );
+
+                               currentOptgroup = item.optgroup;
+                       }
+
+                       that._renderItemData( ul, item );
+               });
+       },
+
+       _renderItemData: function( ul, item ) {
+               return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
+       },
+
+       _renderItem: function( ul, item ) {
+               var li = $( "<li>" );
+
+               if ( item.disabled ) {
+                       li.addClass( "ui-state-disabled" );
+               }
+               this._setText( li, item.label );
+
+               return li.appendTo( ul );
+       },
+
+       _setText: function( element, value ) {
+               if ( value ) {
+                       element.text( value );
+               } else {
+                       element.html( "&#160;" );
+               }
+       },
+
+       _move: function( direction, event ) {
+               var item, next,
+                       filter = ".ui-menu-item";
+
+               if ( this.isOpen ) {
+                       item = this.menuItems.eq( this.focusIndex );
+               } else {
+                       item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
+                       filter += ":not(.ui-state-disabled)";
+               }
+
+               if ( direction === "first" || direction === "last" ) {
+                       next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
+               } else {
+                       next = item[ direction + "All" ]( filter ).eq( 0 );
+               }
+
+               if ( next.length ) {
+                       this.menuInstance.focus( event, next );
+               }
+       },
+
+       _getSelectedItem: function() {
+               return this.menuItems.eq( this.element[ 0 ].selectedIndex );
+       },
+
+       _toggle: function( event ) {
+               this[ this.isOpen ? "close" : "open" ]( event );
+       },
+
+       _setSelection: function() {
+               var selection;
+
+               if ( !this.range ) {
+                       return;
+               }
+
+               if ( window.getSelection ) {
+                       selection = window.getSelection();
+                       selection.removeAllRanges();
+                       selection.addRange( this.range );
+
+               // support: IE8
+               } else {
+                       this.range.select();
+               }
+
+               // support: IE
+               // Setting the text selection kills the button focus in IE, but
+               // restoring the focus doesn't kill the selection.
+               this.button.focus();
+       },
+
+       _documentClick: {
+               mousedown: function( event ) {
+                       if ( !this.isOpen ) {
+                               return;
+                       }
+
+                       if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
+                               this.close( event );
+                       }
+               }
+       },
+
+       _buttonEvents: {
+
+               // Prevent text selection from being reset when interacting with the selectmenu (#10144)
+               mousedown: function() {
+                       var selection;
+
+                       if ( window.getSelection ) {
+                               selection = window.getSelection();
+                               if ( selection.rangeCount ) {
+                                       this.range = selection.getRangeAt( 0 );
+                               }
+
+                       // support: IE8
+                       } else {
+                               this.range = document.selection.createRange();
+                       }
+               },
+
+               click: function( event ) {
+                       this._setSelection();
+                       this._toggle( event );
+               },
+
+               keydown: function( event ) {
+                       var preventDefault = true;
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.TAB:
+                               case $.ui.keyCode.ESCAPE:
+                                       this.close( event );
+                                       preventDefault = false;
+                                       break;
+                               case $.ui.keyCode.ENTER:
+                                       if ( this.isOpen ) {
+                                               this._selectFocusedItem( event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.UP:
+                                       if ( event.altKey ) {
+                                               this._toggle( event );
+                                       } else {
+                                               this._move( "prev", event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.DOWN:
+                                       if ( event.altKey ) {
+                                               this._toggle( event );
+                                       } else {
+                                               this._move( "next", event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.SPACE:
+                                       if ( this.isOpen ) {
+                                               this._selectFocusedItem( event );
+                                       } else {
+                                               this._toggle( event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.LEFT:
+                                       this._move( "prev", event );
+                                       break;
+                               case $.ui.keyCode.RIGHT:
+                                       this._move( "next", event );
+                                       break;
+                               case $.ui.keyCode.HOME:
+                               case $.ui.keyCode.PAGE_UP:
+                                       this._move( "first", event );
+                                       break;
+                               case $.ui.keyCode.END:
+                               case $.ui.keyCode.PAGE_DOWN:
+                                       this._move( "last", event );
+                                       break;
+                               default:
+                                       this.menu.trigger( event );
+                                       preventDefault = false;
+                       }
+
+                       if ( preventDefault ) {
+                               event.preventDefault();
+                       }
+               }
+       },
+
+       _selectFocusedItem: function( event ) {
+               var item = this.menuItems.eq( this.focusIndex );
+               if ( !item.hasClass( "ui-state-disabled" ) ) {
+                       this._select( item.data( "ui-selectmenu-item" ), event );
+               }
+       },
+
+       _select: function( item, event ) {
+               var oldIndex = this.element[ 0 ].selectedIndex;
+
+               // Change native select element
+               this.element[ 0 ].selectedIndex = item.index;
+               this._setText( this.buttonText, item.label );
+               this._setAria( item );
+               this._trigger( "select", event, { item: item } );
+
+               if ( item.index !== oldIndex ) {
+                       this._trigger( "change", event, { item: item } );
+               }
+
+               this.close( event );
+       },
+
+       _setAria: function( item ) {
+               var id = this.menuItems.eq( item.index ).attr( "id" );
+
+               this.button.attr({
+                       "aria-labelledby": id,
+                       "aria-activedescendant": id
+               });
+               this.menu.attr( "aria-activedescendant", id );
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "icons" ) {
+                       this.button.find( "span.ui-icon" )
+                               .removeClass( this.options.icons.button )
+                               .addClass( value.button );
+               }
+
+               this._super( key, value );
+
+               if ( key === "appendTo" ) {
+                       this.menuWrap.appendTo( this._appendTo() );
+               }
+
+               if ( key === "disabled" ) {
+                       this.menuInstance.option( "disabled", value );
+                       this.button
+                               .toggleClass( "ui-state-disabled", value )
+                               .attr( "aria-disabled", value );
+
+                       this.element.prop( "disabled", value );
+                       if ( value ) {
+                               this.button.attr( "tabindex", -1 );
+                               this.close();
+                       } else {
+                               this.button.attr( "tabindex", 0 );
+                       }
+               }
+
+               if ( key === "width" ) {
+                       this._resizeButton();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+
+               if ( element ) {
+                       element = element.jquery || element.nodeType ?
+                               $( element ) :
+                               this.document.find( element ).eq( 0 );
+               }
+
+               if ( !element || !element[ 0 ] ) {
+                       element = this.element.closest( ".ui-front" );
+               }
+
+               if ( !element.length ) {
+                       element = this.document[ 0 ].body;
+               }
+
+               return element;
+       },
+
+       _toggleAttr: function() {
+               this.button
+                       .toggleClass( "ui-corner-top", this.isOpen )
+                       .toggleClass( "ui-corner-all", !this.isOpen )
+                       .attr( "aria-expanded", this.isOpen );
+               this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
+               this.menu.attr( "aria-hidden", !this.isOpen );
+       },
+
+       _resizeButton: function() {
+               var width = this.options.width;
+
+               if ( !width ) {
+                       width = this.element.show().outerWidth();
+                       this.element.hide();
+               }
+
+               this.button.outerWidth( width );
+       },
+
+       _resizeMenu: function() {
+               this.menu.outerWidth( Math.max(
+                       this.button.outerWidth(),
+
+                       // support: IE10
+                       // IE10 wraps long text (possibly a rounding bug)
+                       // so we add 1px to avoid the wrapping
+                       this.menu.width( "" ).outerWidth() + 1
+               ) );
+       },
+
+       _getCreateOptions: function() {
+               return { disabled: this.element.prop( "disabled" ) };
+       },
+
+       _parseOptions: function( options ) {
+               var data = [];
+               options.each(function( index, item ) {
+                       var option = $( item ),
+                               optgroup = option.parent( "optgroup" );
+                       data.push({
+                               element: option,
+                               index: index,
+                               value: option.val(),
+                               label: option.text(),
+                               optgroup: optgroup.attr( "label" ) || "",
+                               disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
+                       });
+               });
+               this.items = data;
+       },
+
+       _destroy: function() {
+               this.menuWrap.remove();
+               this.button.remove();
+               this.element.show();
+               this.element.removeUniqueId();
+               this.label.attr( "for", this.ids.element );
+       }
+});
+
+
+/*!
+ * jQuery UI Slider 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/slider/
+ */
+
+
+var slider = $.widget( "ui.slider", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "slide",
+
+       options: {
+               animate: false,
+               distance: 0,
+               max: 100,
+               min: 0,
+               orientation: "horizontal",
+               range: false,
+               step: 1,
+               value: 0,
+               values: null,
+
+               // callbacks
+               change: null,
+               slide: null,
+               start: null,
+               stop: null
+       },
+
+       // number of pages in a slider
+       // (how many times can you page up/down to go through the whole range)
+       numPages: 5,
+
+       _create: function() {
+               this._keySliding = false;
+               this._mouseSliding = false;
+               this._animateOff = true;
+               this._handleIndex = null;
+               this._detectOrientation();
+               this._mouseInit();
+               this._calculateNewMax();
+
+               this.element
+                       .addClass( "ui-slider" +
+                               " ui-slider-" + this.orientation +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all");
+
+               this._refresh();
+               this._setOption( "disabled", this.options.disabled );
+
+               this._animateOff = false;
+       },
+
+       _refresh: function() {
+               this._createRange();
+               this._createHandles();
+               this._setupEvents();
+               this._refreshValue();
+       },
+
+       _createHandles: function() {
+               var i, handleCount,
+                       options = this.options,
+                       existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
+                       handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
+                       handles = [];
+
+               handleCount = ( options.values && options.values.length ) || 1;
+
+               if ( existingHandles.length > handleCount ) {
+                       existingHandles.slice( handleCount ).remove();
+                       existingHandles = existingHandles.slice( 0, handleCount );
+               }
+
+               for ( i = existingHandles.length; i < handleCount; i++ ) {
+                       handles.push( handle );
+               }
+
+               this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
+
+               this.handle = this.handles.eq( 0 );
+
+               this.handles.each(function( i ) {
+                       $( this ).data( "ui-slider-handle-index", i );
+               });
+       },
+
+       _createRange: function() {
+               var options = this.options,
+                       classes = "";
+
+               if ( options.range ) {
+                       if ( options.range === true ) {
+                               if ( !options.values ) {
+                                       options.values = [ this._valueMin(), this._valueMin() ];
+                               } else if ( options.values.length && options.values.length !== 2 ) {
+                                       options.values = [ options.values[0], options.values[0] ];
+                               } else if ( $.isArray( options.values ) ) {
+                                       options.values = options.values.slice(0);
+                               }
+                       }
+
+                       if ( !this.range || !this.range.length ) {
+                               this.range = $( "<div></div>" )
+                                       .appendTo( this.element );
+
+                               classes = "ui-slider-range" +
+                               // note: this isn't the most fittingly semantic framework class for this element,
+                               // but worked best visually with a variety of themes
+                               " ui-widget-header ui-corner-all";
+                       } else {
+                               this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
+                                       // Handle range switching from true to min/max
+                                       .css({
+                                               "left": "",
+                                               "bottom": ""
+                                       });
+                       }
+
+                       this.range.addClass( classes +
+                               ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
+               } else {
+                       if ( this.range ) {
+                               this.range.remove();
+                       }
+                       this.range = null;
+               }
+       },
+
+       _setupEvents: function() {
+               this._off( this.handles );
+               this._on( this.handles, this._handleEvents );
+               this._hoverable( this.handles );
+               this._focusable( this.handles );
+       },
+
+       _destroy: function() {
+               this.handles.remove();
+               if ( this.range ) {
+                       this.range.remove();
+               }
+
+               this.element
+                       .removeClass( "ui-slider" +
+                               " ui-slider-horizontal" +
+                               " ui-slider-vertical" +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all" );
+
+               this._mouseDestroy();
+       },
+
+       _mouseCapture: function( event ) {
+               var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
+                       that = this,
+                       o = this.options;
+
+               if ( o.disabled ) {
+                       return false;
+               }
+
+               this.elementSize = {
+                       width: this.element.outerWidth(),
+                       height: this.element.outerHeight()
+               };
+               this.elementOffset = this.element.offset();
+
+               position = { x: event.pageX, y: event.pageY };
+               normValue = this._normValueFromMouse( position );
+               distance = this._valueMax() - this._valueMin() + 1;
+               this.handles.each(function( i ) {
+                       var thisDistance = Math.abs( normValue - that.values(i) );
+                       if (( distance > thisDistance ) ||
+                               ( distance === thisDistance &&
+                                       (i === that._lastChangedValue || that.values(i) === o.min ))) {
+                               distance = thisDistance;
+                               closestHandle = $( this );
+                               index = i;
+                       }
+               });
+
+               allowed = this._start( event, index );
+               if ( allowed === false ) {
+                       return false;
+               }
+               this._mouseSliding = true;
+
+               this._handleIndex = index;
+
+               closestHandle
+                       .addClass( "ui-state-active" )
+                       .focus();
+
+               offset = closestHandle.offset();
+               mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
+               this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+                       left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+                       top: event.pageY - offset.top -
+                               ( closestHandle.height() / 2 ) -
+                               ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
+                               ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
+                               ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
+               };
+
+               if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+                       this._slide( event, index, normValue );
+               }
+               this._animateOff = true;
+               return true;
+       },
+
+       _mouseStart: function() {
+               return true;
+       },
+
+       _mouseDrag: function( event ) {
+               var position = { x: event.pageX, y: event.pageY },
+                       normValue = this._normValueFromMouse( position );
+
+               this._slide( event, this._handleIndex, normValue );
+
+               return false;
+       },
+
+       _mouseStop: function( event ) {
+               this.handles.removeClass( "ui-state-active" );
+               this._mouseSliding = false;
+
+               this._stop( event, this._handleIndex );
+               this._change( event, this._handleIndex );
+
+               this._handleIndex = null;
+               this._clickOffset = null;
+               this._animateOff = false;
+
+               return false;
+       },
+
+       _detectOrientation: function() {
+               this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+       },
+
+       _normValueFromMouse: function( position ) {
+               var pixelTotal,
+                       pixelMouse,
+                       percentMouse,
+                       valueTotal,
+                       valueMouse;
+
+               if ( this.orientation === "horizontal" ) {
+                       pixelTotal = this.elementSize.width;
+                       pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
+               } else {
+                       pixelTotal = this.elementSize.height;
+                       pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
+               }
+
+               percentMouse = ( pixelMouse / pixelTotal );
+               if ( percentMouse > 1 ) {
+                       percentMouse = 1;
+               }
+               if ( percentMouse < 0 ) {
+                       percentMouse = 0;
+               }
+               if ( this.orientation === "vertical" ) {
+                       percentMouse = 1 - percentMouse;
+               }
+
+               valueTotal = this._valueMax() - this._valueMin();
+               valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+               return this._trimAlignValue( valueMouse );
+       },
+
+       _start: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+               return this._trigger( "start", event, uiHash );
+       },
+
+       _slide: function( event, index, newVal ) {
+               var otherVal,
+                       newValues,
+                       allowed;
+
+               if ( this.options.values && this.options.values.length ) {
+                       otherVal = this.values( index ? 0 : 1 );
+
+                       if ( ( this.options.values.length === 2 && this.options.range === true ) &&
+                                       ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
+                               ) {
+                               newVal = otherVal;
+                       }
+
+                       if ( newVal !== this.values( index ) ) {
+                               newValues = this.values();
+                               newValues[ index ] = newVal;
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal,
+                                       values: newValues
+                               } );
+                               otherVal = this.values( index ? 0 : 1 );
+                               if ( allowed !== false ) {
+                                       this.values( index, newVal );
+                               }
+                       }
+               } else {
+                       if ( newVal !== this.value() ) {
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal
+                               } );
+                               if ( allowed !== false ) {
+                                       this.value( newVal );
+                               }
+                       }
+               }
+       },
+
+       _stop: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+
+               this._trigger( "stop", event, uiHash );
+       },
+
+       _change: function( event, index ) {
+               if ( !this._keySliding && !this._mouseSliding ) {
+                       var uiHash = {
+                               handle: this.handles[ index ],
+                               value: this.value()
+                       };
+                       if ( this.options.values && this.options.values.length ) {
+                               uiHash.value = this.values( index );
+                               uiHash.values = this.values();
+                       }
+
+                       //store the last changed value index for reference when handles overlap
+                       this._lastChangedValue = index;
+
+                       this._trigger( "change", event, uiHash );
+               }
+       },
+
+       value: function( newValue ) {
+               if ( arguments.length ) {
+                       this.options.value = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, 0 );
+                       return;
+               }
+
+               return this._value();
+       },
+
+       values: function( index, newValue ) {
+               var vals,
+                       newValues,
+                       i;
+
+               if ( arguments.length > 1 ) {
+                       this.options.values[ index ] = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, index );
+                       return;
+               }
+
+               if ( arguments.length ) {
+                       if ( $.isArray( arguments[ 0 ] ) ) {
+                               vals = this.options.values;
+                               newValues = arguments[ 0 ];
+                               for ( i = 0; i < vals.length; i += 1 ) {
+                                       vals[ i ] = this._trimAlignValue( newValues[ i ] );
+                                       this._change( null, i );
+                               }
+                               this._refreshValue();
+                       } else {
+                               if ( this.options.values && this.options.values.length ) {
+                                       return this._values( index );
+                               } else {
+                                       return this.value();
+                               }
+                       }
+               } else {
+                       return this._values();
+               }
+       },
+
+       _setOption: function( key, value ) {
+               var i,
+                       valsLength = 0;
+
+               if ( key === "range" && this.options.range === true ) {
+                       if ( value === "min" ) {
+                               this.options.value = this._values( 0 );
+                               this.options.values = null;
+                       } else if ( value === "max" ) {
+                               this.options.value = this._values( this.options.values.length - 1 );
+                               this.options.values = null;
+                       }
+               }
+
+               if ( $.isArray( this.options.values ) ) {
+                       valsLength = this.options.values.length;
+               }
+
+               if ( key === "disabled" ) {
+                       this.element.toggleClass( "ui-state-disabled", !!value );
+               }
+
+               this._super( key, value );
+
+               switch ( key ) {
+                       case "orientation":
+                               this._detectOrientation();
+                               this.element
+                                       .removeClass( "ui-slider-horizontal ui-slider-vertical" )
+                                       .addClass( "ui-slider-" + this.orientation );
+                               this._refreshValue();
+
+                               // Reset positioning from previous orientation
+                               this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
+                               break;
+                       case "value":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               this._change( null, 0 );
+                               this._animateOff = false;
+                               break;
+                       case "values":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               for ( i = 0; i < valsLength; i += 1 ) {
+                                       this._change( null, i );
+                               }
+                               this._animateOff = false;
+                               break;
+                       case "step":
+                       case "min":
+                       case "max":
+                               this._animateOff = true;
+                               this._calculateNewMax();
+                               this._refreshValue();
+                               this._animateOff = false;
+                               break;
+                       case "range":
+                               this._animateOff = true;
+                               this._refresh();
+                               this._animateOff = false;
+                               break;
+               }
+       },
+
+       //internal value getter
+       // _value() returns value trimmed by min and max, aligned by step
+       _value: function() {
+               var val = this.options.value;
+               val = this._trimAlignValue( val );
+
+               return val;
+       },
+
+       //internal values getter
+       // _values() returns array of values trimmed by min and max, aligned by step
+       // _values( index ) returns single value trimmed by min and max, aligned by step
+       _values: function( index ) {
+               var val,
+                       vals,
+                       i;
+
+               if ( arguments.length ) {
+                       val = this.options.values[ index ];
+                       val = this._trimAlignValue( val );
+
+                       return val;
+               } else if ( this.options.values && this.options.values.length ) {
+                       // .slice() creates a copy of the array
+                       // this copy gets trimmed by min and max and then returned
+                       vals = this.options.values.slice();
+                       for ( i = 0; i < vals.length; i += 1) {
+                               vals[ i ] = this._trimAlignValue( vals[ i ] );
+                       }
+
+                       return vals;
+               } else {
+                       return [];
+               }
+       },
+
+       // returns the step-aligned value that val is closest to, between (inclusive) min and max
+       _trimAlignValue: function( val ) {
+               if ( val <= this._valueMin() ) {
+                       return this._valueMin();
+               }
+               if ( val >= this._valueMax() ) {
+                       return this._valueMax();
+               }
+               var step = ( this.options.step > 0 ) ? this.options.step : 1,
+                       valModStep = (val - this._valueMin()) % step,
+                       alignValue = val - valModStep;
+
+               if ( Math.abs(valModStep) * 2 >= step ) {
+                       alignValue += ( valModStep > 0 ) ? step : ( -step );
+               }
+
+               // Since JavaScript has problems with large floats, round
+               // the final value to 5 digits after the decimal point (see #4124)
+               return parseFloat( alignValue.toFixed(5) );
+       },
+
+       _calculateNewMax: function() {
+               var max = this.options.max,
+                       min = this._valueMin(),
+                       step = this.options.step,
+                       aboveMin = Math.floor( ( max - min ) / step ) * step;
+               max = aboveMin + min;
+               this.max = parseFloat( max.toFixed( this._precision() ) );
+       },
+
+       _precision: function() {
+               var precision = this._precisionOf( this.options.step );
+               if ( this.options.min !== null ) {
+                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
+               }
+               return precision;
+       },
+
+       _precisionOf: function( num ) {
+               var str = num.toString(),
+                       decimal = str.indexOf( "." );
+               return decimal === -1 ? 0 : str.length - decimal - 1;
+       },
+
+       _valueMin: function() {
+               return this.options.min;
+       },
+
+       _valueMax: function() {
+               return this.max;
+       },
+
+       _refreshValue: function() {
+               var lastValPercent, valPercent, value, valueMin, valueMax,
+                       oRange = this.options.range,
+                       o = this.options,
+                       that = this,
+                       animate = ( !this._animateOff ) ? o.animate : false,
+                       _set = {};
+
+               if ( this.options.values && this.options.values.length ) {
+                       this.handles.each(function( i ) {
+                               valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
+                               _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                               $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+                               if ( that.options.range === true ) {
+                                       if ( that.orientation === "horizontal" ) {
+                                               if ( i === 0 ) {
+                                                       that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       } else {
+                                               if ( i === 0 ) {
+                                                       that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       }
+                               }
+                               lastValPercent = valPercent;
+                       });
+               } else {
+                       value = this.value();
+                       valueMin = this._valueMin();
+                       valueMax = this._valueMax();
+                       valPercent = ( valueMax !== valueMin ) ?
+                                       ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+                                       0;
+                       _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                       this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+                       if ( oRange === "min" && this.orientation === "horizontal" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "horizontal" ) {
+                               this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+                       if ( oRange === "min" && this.orientation === "vertical" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "vertical" ) {
+                               this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+               }
+       },
+
+       _handleEvents: {
+               keydown: function( event ) {
+                       var allowed, curVal, newVal, step,
+                               index = $( event.target ).data( "ui-slider-handle-index" );
+
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.HOME:
+                               case $.ui.keyCode.END:
+                               case $.ui.keyCode.PAGE_UP:
+                               case $.ui.keyCode.PAGE_DOWN:
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       event.preventDefault();
+                                       if ( !this._keySliding ) {
+                                               this._keySliding = true;
+                                               $( event.target ).addClass( "ui-state-active" );
+                                               allowed = this._start( event, index );
+                                               if ( allowed === false ) {
+                                                       return;
+                                               }
+                                       }
+                                       break;
+                       }
+
+                       step = this.options.step;
+                       if ( this.options.values && this.options.values.length ) {
+                               curVal = newVal = this.values( index );
+                       } else {
+                               curVal = newVal = this.value();
+                       }
+
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.HOME:
+                                       newVal = this._valueMin();
+                                       break;
+                               case $.ui.keyCode.END:
+                                       newVal = this._valueMax();
+                                       break;
+                               case $.ui.keyCode.PAGE_UP:
+                                       newVal = this._trimAlignValue(
+                                               curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
+                                       );
+                                       break;
+                               case $.ui.keyCode.PAGE_DOWN:
+                                       newVal = this._trimAlignValue(
+                                               curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
+                                       break;
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                                       if ( curVal === this._valueMax() ) {
+                                               return;
+                                       }
+                                       newVal = this._trimAlignValue( curVal + step );
+                                       break;
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       if ( curVal === this._valueMin() ) {
+                                               return;
+                                       }
+                                       newVal = this._trimAlignValue( curVal - step );
+                                       break;
+                       }
+
+                       this._slide( event, index, newVal );
+               },
+               keyup: function( event ) {
+                       var index = $( event.target ).data( "ui-slider-handle-index" );
+
+                       if ( this._keySliding ) {
+                               this._keySliding = false;
+                               this._stop( event, index );
+                               this._change( event, index );
+                               $( event.target ).removeClass( "ui-state-active" );
+                       }
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Spinner 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/spinner/
+ */
+
+
+function spinner_modifier( fn ) {
+       return function() {
+               var previous = this.element.val();
+               fn.apply( this, arguments );
+               this._refresh();
+               if ( previous !== this.element.val() ) {
+                       this._trigger( "change" );
+               }
+       };
+}
+
+var spinner = $.widget( "ui.spinner", {
+       version: "1.11.3",
+       defaultElement: "<input>",
+       widgetEventPrefix: "spin",
+       options: {
+               culture: null,
+               icons: {
+                       down: "ui-icon-triangle-1-s",
+                       up: "ui-icon-triangle-1-n"
+               },
+               incremental: true,
+               max: null,
+               min: null,
+               numberFormat: null,
+               page: 10,
+               step: 1,
+
+               change: null,
+               spin: null,
+               start: null,
+               stop: null
+       },
+
+       _create: function() {
+               // handle string values that need to be parsed
+               this._setOption( "max", this.options.max );
+               this._setOption( "min", this.options.min );
+               this._setOption( "step", this.options.step );
+
+               // Only format if there is a value, prevents the field from being marked
+               // as invalid in Firefox, see #9573.
+               if ( this.value() !== "" ) {
+                       // Format the value, but don't constrain.
+                       this._value( this.element.val(), true );
+               }
+
+               this._draw();
+               this._on( this._events );
+               this._refresh();
+
+               // turning off autocomplete prevents the browser from remembering the
+               // value when navigating through history, so we re-enable autocomplete
+               // if the page is unloaded before the widget is destroyed. #7790
+               this._on( this.window, {
+                       beforeunload: function() {
+                               this.element.removeAttr( "autocomplete" );
+                       }
+               });
+       },
+
+       _getCreateOptions: function() {
+               var options = {},
+                       element = this.element;
+
+               $.each( [ "min", "max", "step" ], function( i, option ) {
+                       var value = element.attr( option );
+                       if ( value !== undefined && value.length ) {
+                               options[ option ] = value;
+                       }
+               });
+
+               return options;
+       },
+
+       _events: {
+               keydown: function( event ) {
+                       if ( this._start( event ) && this._keydown( event ) ) {
+                               event.preventDefault();
+                       }
+               },
+               keyup: "_stop",
+               focus: function() {
+                       this.previous = this.element.val();
+               },
+               blur: function( event ) {
+                       if ( this.cancelBlur ) {
+                               delete this.cancelBlur;
+                               return;
+                       }
+
+                       this._stop();
+                       this._refresh();
+                       if ( this.previous !== this.element.val() ) {
+                               this._trigger( "change", event );
+                       }
+               },
+               mousewheel: function( event, delta ) {
+                       if ( !delta ) {
+                               return;
+                       }
+                       if ( !this.spinning && !this._start( event ) ) {
+                               return false;
+                       }
+
+                       this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
+                       clearTimeout( this.mousewheelTimer );
+                       this.mousewheelTimer = this._delay(function() {
+                               if ( this.spinning ) {
+                                       this._stop( event );
+                               }
+                       }, 100 );
+                       event.preventDefault();
+               },
+               "mousedown .ui-spinner-button": function( event ) {
+                       var previous;
+
+                       // We never want the buttons to have focus; whenever the user is
+                       // interacting with the spinner, the focus should be on the input.
+                       // If the input is focused then this.previous is properly set from
+                       // when the input first received focus. If the input is not focused
+                       // then we need to set this.previous based on the value before spinning.
+                       previous = this.element[0] === this.document[0].activeElement ?
+                               this.previous : this.element.val();
+                       function checkFocus() {
+                               var isActive = this.element[0] === this.document[0].activeElement;
+                               if ( !isActive ) {
+                                       this.element.focus();
+                                       this.previous = previous;
+                                       // support: IE
+                                       // IE sets focus asynchronously, so we need to check if focus
+                                       // moved off of the input because the user clicked on the button.
+                                       this._delay(function() {
+                                               this.previous = previous;
+                                       });
+                               }
+                       }
+
+                       // ensure focus is on (or stays on) the text field
+                       event.preventDefault();
+                       checkFocus.call( this );
+
+                       // support: IE
+                       // IE doesn't prevent moving focus even with event.preventDefault()
+                       // so we set a flag to know when we should ignore the blur event
+                       // and check (again) if focus moved off of the input.
+                       this.cancelBlur = true;
+                       this._delay(function() {
+                               delete this.cancelBlur;
+                               checkFocus.call( this );
+                       });
+
+                       if ( this._start( event ) === false ) {
+                               return;
+                       }
+
+                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+               },
+               "mouseup .ui-spinner-button": "_stop",
+               "mouseenter .ui-spinner-button": function( event ) {
+                       // button will add ui-state-active if mouse was down while mouseleave and kept down
+                       if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
+                               return;
+                       }
+
+                       if ( this._start( event ) === false ) {
+                               return false;
+                       }
+                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+               },
+               // TODO: do we really want to consider this a stop?
+               // shouldn't we just stop the repeater and wait until mouseup before
+               // we trigger the stop event?
+               "mouseleave .ui-spinner-button": "_stop"
+       },
+
+       _draw: function() {
+               var uiSpinner = this.uiSpinner = this.element
+                       .addClass( "ui-spinner-input" )
+                       .attr( "autocomplete", "off" )
+                       .wrap( this._uiSpinnerHtml() )
+                       .parent()
+                               // add buttons
+                               .append( this._buttonHtml() );
+
+               this.element.attr( "role", "spinbutton" );
+
+               // button bindings
+               this.buttons = uiSpinner.find( ".ui-spinner-button" )
+                       .attr( "tabIndex", -1 )
+                       .button()
+                       .removeClass( "ui-corner-all" );
+
+               // IE 6 doesn't understand height: 50% for the buttons
+               // unless the wrapper has an explicit height
+               if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
+                               uiSpinner.height() > 0 ) {
+                       uiSpinner.height( uiSpinner.height() );
+               }
+
+               // disable spinner if element was already disabled
+               if ( this.options.disabled ) {
+                       this.disable();
+               }
+       },
+
+       _keydown: function( event ) {
+               var options = this.options,
+                       keyCode = $.ui.keyCode;
+
+               switch ( event.keyCode ) {
+               case keyCode.UP:
+                       this._repeat( null, 1, event );
+                       return true;
+               case keyCode.DOWN:
+                       this._repeat( null, -1, event );
+                       return true;
+               case keyCode.PAGE_UP:
+                       this._repeat( null, options.page, event );
+                       return true;
+               case keyCode.PAGE_DOWN:
+                       this._repeat( null, -options.page, event );
+                       return true;
+               }
+
+               return false;
+       },
+
+       _uiSpinnerHtml: function() {
+               return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
+       },
+
+       _buttonHtml: function() {
+               return "" +
+                       "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
+                               "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
+                       "</a>" +
+                       "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
+                               "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
+                       "</a>";
+       },
+
+       _start: function( event ) {
+               if ( !this.spinning && this._trigger( "start", event ) === false ) {
+                       return false;
+               }
+
+               if ( !this.counter ) {
+                       this.counter = 1;
+               }
+               this.spinning = true;
+               return true;
+       },
+
+       _repeat: function( i, steps, event ) {
+               i = i || 500;
+
+               clearTimeout( this.timer );
+               this.timer = this._delay(function() {
+                       this._repeat( 40, steps, event );
+               }, i );
+
+               this._spin( steps * this.options.step, event );
+       },
+
+       _spin: function( step, event ) {
+               var value = this.value() || 0;
+
+               if ( !this.counter ) {
+                       this.counter = 1;
+               }
+
+               value = this._adjustValue( value + step * this._increment( this.counter ) );
+
+               if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
+                       this._value( value );
+                       this.counter++;
+               }
+       },
+
+       _increment: function( i ) {
+               var incremental = this.options.incremental;
+
+               if ( incremental ) {
+                       return $.isFunction( incremental ) ?
+                               incremental( i ) :
+                               Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
+               }
+
+               return 1;
+       },
+
+       _precision: function() {
+               var precision = this._precisionOf( this.options.step );
+               if ( this.options.min !== null ) {
+                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
+               }
+               return precision;
+       },
+
+       _precisionOf: function( num ) {
+               var str = num.toString(),
+                       decimal = str.indexOf( "." );
+               return decimal === -1 ? 0 : str.length - decimal - 1;
+       },
+
+       _adjustValue: function( value ) {
+               var base, aboveMin,
+                       options = this.options;
+
+               // make sure we're at a valid step
+               // - find out where we are relative to the base (min or 0)
+               base = options.min !== null ? options.min : 0;
+               aboveMin = value - base;
+               // - round to the nearest step
+               aboveMin = Math.round(aboveMin / options.step) * options.step;
+               // - rounding is based on 0, so adjust back to our base
+               value = base + aboveMin;
+
+               // fix precision from bad JS floating point math
+               value = parseFloat( value.toFixed( this._precision() ) );
+
+               // clamp the value
+               if ( options.max !== null && value > options.max) {
+                       return options.max;
+               }
+               if ( options.min !== null && value < options.min ) {
+                       return options.min;
+               }
+
+               return value;
+       },
+
+       _stop: function( event ) {
+               if ( !this.spinning ) {
+                       return;
+               }
+
+               clearTimeout( this.timer );
+               clearTimeout( this.mousewheelTimer );
+               this.counter = 0;
+               this.spinning = false;
+               this._trigger( "stop", event );
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "culture" || key === "numberFormat" ) {
+                       var prevValue = this._parse( this.element.val() );
+                       this.options[ key ] = value;
+                       this.element.val( this._format( prevValue ) );
+                       return;
+               }
+
+               if ( key === "max" || key === "min" || key === "step" ) {
+                       if ( typeof value === "string" ) {
+                               value = this._parse( value );
+                       }
+               }
+               if ( key === "icons" ) {
+                       this.buttons.first().find( ".ui-icon" )
+                               .removeClass( this.options.icons.up )
+                               .addClass( value.up );
+                       this.buttons.last().find( ".ui-icon" )
+                               .removeClass( this.options.icons.down )
+                               .addClass( value.down );
+               }
+
+               this._super( key, value );
+
+               if ( key === "disabled" ) {
+                       this.widget().toggleClass( "ui-state-disabled", !!value );
+                       this.element.prop( "disabled", !!value );
+                       this.buttons.button( value ? "disable" : "enable" );
+               }
+       },
+
+       _setOptions: spinner_modifier(function( options ) {
+               this._super( options );
+       }),
+
+       _parse: function( val ) {
+               if ( typeof val === "string" && val !== "" ) {
+                       val = window.Globalize && this.options.numberFormat ?
+                               Globalize.parseFloat( val, 10, this.options.culture ) : +val;
+               }
+               return val === "" || isNaN( val ) ? null : val;
+       },
+
+       _format: function( value ) {
+               if ( value === "" ) {
+                       return "";
+               }
+               return window.Globalize && this.options.numberFormat ?
+                       Globalize.format( value, this.options.numberFormat, this.options.culture ) :
+                       value;
+       },
+
+       _refresh: function() {
+               this.element.attr({
+                       "aria-valuemin": this.options.min,
+                       "aria-valuemax": this.options.max,
+                       // TODO: what should we do with values that can't be parsed?
+                       "aria-valuenow": this._parse( this.element.val() )
+               });
+       },
+
+       isValid: function() {
+               var value = this.value();
+
+               // null is invalid
+               if ( value === null ) {
+                       return false;
+               }
+
+               // if value gets adjusted, it's invalid
+               return value === this._adjustValue( value );
+       },
+
+       // update the value without triggering change
+       _value: function( value, allowAny ) {
+               var parsed;
+               if ( value !== "" ) {
+                       parsed = this._parse( value );
+                       if ( parsed !== null ) {
+                               if ( !allowAny ) {
+                                       parsed = this._adjustValue( parsed );
+                               }
+                               value = this._format( parsed );
+                       }
+               }
+               this.element.val( value );
+               this._refresh();
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-spinner-input" )
+                       .prop( "disabled", false )
+                       .removeAttr( "autocomplete" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-valuemin" )
+                       .removeAttr( "aria-valuemax" )
+                       .removeAttr( "aria-valuenow" );
+               this.uiSpinner.replaceWith( this.element );
+       },
+
+       stepUp: spinner_modifier(function( steps ) {
+               this._stepUp( steps );
+       }),
+       _stepUp: function( steps ) {
+               if ( this._start() ) {
+                       this._spin( (steps || 1) * this.options.step );
+                       this._stop();
+               }
+       },
+
+       stepDown: spinner_modifier(function( steps ) {
+               this._stepDown( steps );
+       }),
+       _stepDown: function( steps ) {
+               if ( this._start() ) {
+                       this._spin( (steps || 1) * -this.options.step );
+                       this._stop();
+               }
+       },
+
+       pageUp: spinner_modifier(function( pages ) {
+               this._stepUp( (pages || 1) * this.options.page );
+       }),
+
+       pageDown: spinner_modifier(function( pages ) {
+               this._stepDown( (pages || 1) * this.options.page );
+       }),
+
+       value: function( newVal ) {
+               if ( !arguments.length ) {
+                       return this._parse( this.element.val() );
+               }
+               spinner_modifier( this._value ).call( this, newVal );
+       },
+
+       widget: function() {
+               return this.uiSpinner;
+       }
+});
+
+
+/*!
+ * jQuery UI Tabs 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/tabs/
+ */
+
+
+var tabs = $.widget( "ui.tabs", {
+       version: "1.11.3",
+       delay: 300,
+       options: {
+               active: null,
+               collapsible: false,
+               event: "click",
+               heightStyle: "content",
+               hide: null,
+               show: null,
+
+               // callbacks
+               activate: null,
+               beforeActivate: null,
+               beforeLoad: null,
+               load: null
+       },
+
+       _isLocal: (function() {
+               var rhash = /#.*$/;
+
+               return function( anchor ) {
+                       var anchorUrl, locationUrl;
+
+                       // support: IE7
+                       // IE7 doesn't normalize the href property when set via script (#9317)
+                       anchor = anchor.cloneNode( false );
+
+                       anchorUrl = anchor.href.replace( rhash, "" );
+                       locationUrl = location.href.replace( rhash, "" );
+
+                       // decoding may throw an error if the URL isn't UTF-8 (#9518)
+                       try {
+                               anchorUrl = decodeURIComponent( anchorUrl );
+                       } catch ( error ) {}
+                       try {
+                               locationUrl = decodeURIComponent( locationUrl );
+                       } catch ( error ) {}
+
+                       return anchor.hash.length > 1 && anchorUrl === locationUrl;
+               };
+       })(),
+
+       _create: function() {
+               var that = this,
+                       options = this.options;
+
+               this.running = false;
+
+               this.element
+                       .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
+                       .toggleClass( "ui-tabs-collapsible", options.collapsible );
+
+               this._processTabs();
+               options.active = this._initialActive();
+
+               // Take disabling tabs via class attribute from HTML
+               // into account and update option properly.
+               if ( $.isArray( options.disabled ) ) {
+                       options.disabled = $.unique( options.disabled.concat(
+                               $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
+                                       return that.tabs.index( li );
+                               })
+                       ) ).sort();
+               }
+
+               // check for length avoids error when initializing empty list
+               if ( this.options.active !== false && this.anchors.length ) {
+                       this.active = this._findActive( options.active );
+               } else {
+                       this.active = $();
+               }
+
+               this._refresh();
+
+               if ( this.active.length ) {
+                       this.load( options.active );
+               }
+       },
+
+       _initialActive: function() {
+               var active = this.options.active,
+                       collapsible = this.options.collapsible,
+                       locationHash = location.hash.substring( 1 );
+
+               if ( active === null ) {
+                       // check the fragment identifier in the URL
+                       if ( locationHash ) {
+                               this.tabs.each(function( i, tab ) {
+                                       if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+                                               active = i;
+                                               return false;
+                                       }
+                               });
+                       }
+
+                       // check for a tab marked active via a class
+                       if ( active === null ) {
+                               active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
+                       }
+
+                       // no active tab, set to false
+                       if ( active === null || active === -1 ) {
+                               active = this.tabs.length ? 0 : false;
+                       }
+               }
+
+               // handle numbers: negative, out of range
+               if ( active !== false ) {
+                       active = this.tabs.index( this.tabs.eq( active ) );
+                       if ( active === -1 ) {
+                               active = collapsible ? false : 0;
+                       }
+               }
+
+               // don't allow collapsible: false and active: false
+               if ( !collapsible && active === false && this.anchors.length ) {
+                       active = 0;
+               }
+
+               return active;
+       },
+
+       _getCreateEventData: function() {
+               return {
+                       tab: this.active,
+                       panel: !this.active.length ? $() : this._getPanelForTab( this.active )
+               };
+       },
+
+       _tabKeydown: function( event ) {
+               var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
+                       selectedIndex = this.tabs.index( focusedTab ),
+                       goingForward = true;
+
+               if ( this._handlePageNav( event ) ) {
+                       return;
+               }
+
+               switch ( event.keyCode ) {
+                       case $.ui.keyCode.RIGHT:
+                       case $.ui.keyCode.DOWN:
+                               selectedIndex++;
+                               break;
+                       case $.ui.keyCode.UP:
+                       case $.ui.keyCode.LEFT:
+                               goingForward = false;
+                               selectedIndex--;
+                               break;
+                       case $.ui.keyCode.END:
+                               selectedIndex = this.anchors.length - 1;
+                               break;
+                       case $.ui.keyCode.HOME:
+                               selectedIndex = 0;
+                               break;
+                       case $.ui.keyCode.SPACE:
+                               // Activate only, no collapsing
+                               event.preventDefault();
+                               clearTimeout( this.activating );
+                               this._activate( selectedIndex );
+                               return;
+                       case $.ui.keyCode.ENTER:
+                               // Toggle (cancel delayed activation, allow collapsing)
+                               event.preventDefault();
+                               clearTimeout( this.activating );
+                               // Determine if we should collapse or activate
+                               this._activate( selectedIndex === this.options.active ? false : selectedIndex );
+                               return;
+                       default:
+                               return;
+               }
+
+               // Focus the appropriate tab, based on which key was pressed
+               event.preventDefault();
+               clearTimeout( this.activating );
+               selectedIndex = this._focusNextTab( selectedIndex, goingForward );
+
+               // Navigating with control/command key will prevent automatic activation
+               if ( !event.ctrlKey && !event.metaKey ) {
+
+                       // Update aria-selected immediately so that AT think the tab is already selected.
+                       // Otherwise AT may confuse the user by stating that they need to activate the tab,
+                       // but the tab will already be activated by the time the announcement finishes.
+                       focusedTab.attr( "aria-selected", "false" );
+                       this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
+
+                       this.activating = this._delay(function() {
+                               this.option( "active", selectedIndex );
+                       }, this.delay );
+               }
+       },
+
+       _panelKeydown: function( event ) {
+               if ( this._handlePageNav( event ) ) {
+                       return;
+               }
+
+               // Ctrl+up moves focus to the current tab
+               if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
+                       event.preventDefault();
+                       this.active.focus();
+               }
+       },
+
+       // Alt+page up/down moves focus to the previous/next tab (and activates)
+       _handlePageNav: function( event ) {
+               if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
+                       this._activate( this._focusNextTab( this.options.active - 1, false ) );
+                       return true;
+               }
+               if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
+                       this._activate( this._focusNextTab( this.options.active + 1, true ) );
+                       return true;
+               }
+       },
+
+       _findNextTab: function( index, goingForward ) {
+               var lastTabIndex = this.tabs.length - 1;
+
+               function constrain() {
+                       if ( index > lastTabIndex ) {
+                               index = 0;
+                       }
+                       if ( index < 0 ) {
+                               index = lastTabIndex;
+                       }
+                       return index;
+               }
+
+               while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
+                       index = goingForward ? index + 1 : index - 1;
+               }
+
+               return index;
+       },
+
+       _focusNextTab: function( index, goingForward ) {
+               index = this._findNextTab( index, goingForward );
+               this.tabs.eq( index ).focus();
+               return index;
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "active" ) {
+                       // _activate() will handle invalid values and update this.options
+                       this._activate( value );
+                       return;
+               }
+
+               if ( key === "disabled" ) {
+                       // don't use the widget factory's disabled handling
+                       this._setupDisabled( value );
+                       return;
+               }
+
+               this._super( key, value);
+
+               if ( key === "collapsible" ) {
+                       this.element.toggleClass( "ui-tabs-collapsible", value );
+                       // Setting collapsible: false while collapsed; open first panel
+                       if ( !value && this.options.active === false ) {
+                               this._activate( 0 );
+                       }
+               }
+
+               if ( key === "event" ) {
+                       this._setupEvents( value );
+               }
+
+               if ( key === "heightStyle" ) {
+                       this._setupHeightStyle( value );
+               }
+       },
+
+       _sanitizeSelector: function( hash ) {
+               return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+       },
+
+       refresh: function() {
+               var options = this.options,
+                       lis = this.tablist.children( ":has(a[href])" );
+
+               // get disabled tabs from class attribute from HTML
+               // this will get converted to a boolean if needed in _refresh()
+               options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
+                       return lis.index( tab );
+               });
+
+               this._processTabs();
+
+               // was collapsed or no tabs
+               if ( options.active === false || !this.anchors.length ) {
+                       options.active = false;
+                       this.active = $();
+               // was active, but active tab is gone
+               } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
+                       // all remaining tabs are disabled
+                       if ( this.tabs.length === options.disabled.length ) {
+                               options.active = false;
+                               this.active = $();
+                       // activate previous tab
+                       } else {
+                               this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
+                       }
+               // was active, active tab still exists
+               } else {
+                       // make sure active index is correct
+                       options.active = this.tabs.index( this.active );
+               }
+
+               this._refresh();
+       },
+
+       _refresh: function() {
+               this._setupDisabled( this.options.disabled );
+               this._setupEvents( this.options.event );
+               this._setupHeightStyle( this.options.heightStyle );
+
+               this.tabs.not( this.active ).attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false",
+                       tabIndex: -1
+               });
+               this.panels.not( this._getPanelForTab( this.active ) )
+                       .hide()
+                       .attr({
+                               "aria-hidden": "true"
+                       });
+
+               // Make sure one tab is in the tab order
+               if ( !this.active.length ) {
+                       this.tabs.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       this.active
+                               .addClass( "ui-tabs-active ui-state-active" )
+                               .attr({
+                                       "aria-selected": "true",
+                                       "aria-expanded": "true",
+                                       tabIndex: 0
+                               });
+                       this._getPanelForTab( this.active )
+                               .show()
+                               .attr({
+                                       "aria-hidden": "false"
+                               });
+               }
+       },
+
+       _processTabs: function() {
+               var that = this,
+                       prevTabs = this.tabs,
+                       prevAnchors = this.anchors,
+                       prevPanels = this.panels;
+
+               this.tablist = this._getList()
+                       .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+                       .attr( "role", "tablist" )
+
+                       // Prevent users from focusing disabled tabs via click
+                       .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
+                               if ( $( this ).is( ".ui-state-disabled" ) ) {
+                                       event.preventDefault();
+                               }
+                       })
+
+                       // support: IE <9
+                       // Preventing the default action in mousedown doesn't prevent IE
+                       // from focusing the element, so if the anchor gets focused, blur.
+                       // We don't have to worry about focusing the previously focused
+                       // element since clicking on a non-focusable element should focus
+                       // the body anyway.
+                       .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
+                               if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
+                                       this.blur();
+                               }
+                       });
+
+               this.tabs = this.tablist.find( "> li:has(a[href])" )
+                       .addClass( "ui-state-default ui-corner-top" )
+                       .attr({
+                               role: "tab",
+                               tabIndex: -1
+                       });
+
+               this.anchors = this.tabs.map(function() {
+                               return $( "a", this )[ 0 ];
+                       })
+                       .addClass( "ui-tabs-anchor" )
+                       .attr({
+                               role: "presentation",
+                               tabIndex: -1
+                       });
+
+               this.panels = $();
+
+               this.anchors.each(function( i, anchor ) {
+                       var selector, panel, panelId,
+                               anchorId = $( anchor ).uniqueId().attr( "id" ),
+                               tab = $( anchor ).closest( "li" ),
+                               originalAriaControls = tab.attr( "aria-controls" );
+
+                       // inline tab
+                       if ( that._isLocal( anchor ) ) {
+                               selector = anchor.hash;
+                               panelId = selector.substring( 1 );
+                               panel = that.element.find( that._sanitizeSelector( selector ) );
+                       // remote tab
+                       } else {
+                               // If the tab doesn't already have aria-controls,
+                               // generate an id by using a throw-away element
+                               panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
+                               selector = "#" + panelId;
+                               panel = that.element.find( selector );
+                               if ( !panel.length ) {
+                                       panel = that._createPanel( panelId );
+                                       panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
+                               }
+                               panel.attr( "aria-live", "polite" );
+                       }
+
+                       if ( panel.length) {
+                               that.panels = that.panels.add( panel );
+                       }
+                       if ( originalAriaControls ) {
+                               tab.data( "ui-tabs-aria-controls", originalAriaControls );
+                       }
+                       tab.attr({
+                               "aria-controls": panelId,
+                               "aria-labelledby": anchorId
+                       });
+                       panel.attr( "aria-labelledby", anchorId );
+               });
+
+               this.panels
+                       .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+                       .attr( "role", "tabpanel" );
+
+               // Avoid memory leaks (#10056)
+               if ( prevTabs ) {
+                       this._off( prevTabs.not( this.tabs ) );
+                       this._off( prevAnchors.not( this.anchors ) );
+                       this._off( prevPanels.not( this.panels ) );
+               }
+       },
+
+       // allow overriding how to find the list for rare usage scenarios (#7715)
+       _getList: function() {
+               return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
+       },
+
+       _createPanel: function( id ) {
+               return $( "<div>" )
+                       .attr( "id", id )
+                       .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+                       .data( "ui-tabs-destroy", true );
+       },
+
+       _setupDisabled: function( disabled ) {
+               if ( $.isArray( disabled ) ) {
+                       if ( !disabled.length ) {
+                               disabled = false;
+                       } else if ( disabled.length === this.anchors.length ) {
+                               disabled = true;
+                       }
+               }
+
+               // disable tabs
+               for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
+                       if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
+                               $( li )
+                                       .addClass( "ui-state-disabled" )
+                                       .attr( "aria-disabled", "true" );
+                       } else {
+                               $( li )
+                                       .removeClass( "ui-state-disabled" )
+                                       .removeAttr( "aria-disabled" );
+                       }
+               }
+
+               this.options.disabled = disabled;
+       },
+
+       _setupEvents: function( event ) {
+               var events = {};
+               if ( event ) {
+                       $.each( event.split(" "), function( index, eventName ) {
+                               events[ eventName ] = "_eventHandler";
+                       });
+               }
+
+               this._off( this.anchors.add( this.tabs ).add( this.panels ) );
+               // Always prevent the default action, even when disabled
+               this._on( true, this.anchors, {
+                       click: function( event ) {
+                               event.preventDefault();
+                       }
+               });
+               this._on( this.anchors, events );
+               this._on( this.tabs, { keydown: "_tabKeydown" } );
+               this._on( this.panels, { keydown: "_panelKeydown" } );
+
+               this._focusable( this.tabs );
+               this._hoverable( this.tabs );
+       },
+
+       _setupHeightStyle: function( heightStyle ) {
+               var maxHeight,
+                       parent = this.element.parent();
+
+               if ( heightStyle === "fill" ) {
+                       maxHeight = parent.height();
+                       maxHeight -= this.element.outerHeight() - this.element.height();
+
+                       this.element.siblings( ":visible" ).each(function() {
+                               var elem = $( this ),
+                                       position = elem.css( "position" );
+
+                               if ( position === "absolute" || position === "fixed" ) {
+                                       return;
+                               }
+                               maxHeight -= elem.outerHeight( true );
+                       });
+
+                       this.element.children().not( this.panels ).each(function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       });
+
+                       this.panels.each(function() {
+                               $( this ).height( Math.max( 0, maxHeight -
+                                       $( this ).innerHeight() + $( this ).height() ) );
+                       })
+                       .css( "overflow", "auto" );
+               } else if ( heightStyle === "auto" ) {
+                       maxHeight = 0;
+                       this.panels.each(function() {
+                               maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+                       }).height( maxHeight );
+               }
+       },
+
+       _eventHandler: function( event ) {
+               var options = this.options,
+                       active = this.active,
+                       anchor = $( event.currentTarget ),
+                       tab = anchor.closest( "li" ),
+                       clickedIsActive = tab[ 0 ] === active[ 0 ],
+                       collapsing = clickedIsActive && options.collapsible,
+                       toShow = collapsing ? $() : this._getPanelForTab( tab ),
+                       toHide = !active.length ? $() : this._getPanelForTab( active ),
+                       eventData = {
+                               oldTab: active,
+                               oldPanel: toHide,
+                               newTab: collapsing ? $() : tab,
+                               newPanel: toShow
+                       };
+
+               event.preventDefault();
+
+               if ( tab.hasClass( "ui-state-disabled" ) ||
+                               // tab is already loading
+                               tab.hasClass( "ui-tabs-loading" ) ||
+                               // can't switch durning an animation
+                               this.running ||
+                               // click on active header, but not collapsible
+                               ( clickedIsActive && !options.collapsible ) ||
+                               // allow canceling activation
+                               ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+                       return;
+               }
+
+               options.active = collapsing ? false : this.tabs.index( tab );
+
+               this.active = clickedIsActive ? $() : tab;
+               if ( this.xhr ) {
+                       this.xhr.abort();
+               }
+
+               if ( !toHide.length && !toShow.length ) {
+                       $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
+               }
+
+               if ( toShow.length ) {
+                       this.load( this.tabs.index( tab ), event );
+               }
+               this._toggle( event, eventData );
+       },
+
+       // handles show/hide for selecting tabs
+       _toggle: function( event, eventData ) {
+               var that = this,
+                       toShow = eventData.newPanel,
+                       toHide = eventData.oldPanel;
+
+               this.running = true;
+
+               function complete() {
+                       that.running = false;
+                       that._trigger( "activate", event, eventData );
+               }
+
+               function show() {
+                       eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
+
+                       if ( toShow.length && that.options.show ) {
+                               that._show( toShow, that.options.show, complete );
+                       } else {
+                               toShow.show();
+                               complete();
+                       }
+               }
+
+               // start out by hiding, then showing, then completing
+               if ( toHide.length && this.options.hide ) {
+                       this._hide( toHide, this.options.hide, function() {
+                               eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+                               show();
+                       });
+               } else {
+                       eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+                       toHide.hide();
+                       show();
+               }
+
+               toHide.attr( "aria-hidden", "true" );
+               eventData.oldTab.attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false"
+               });
+               // If we're switching tabs, remove the old tab from the tab order.
+               // If we're opening from collapsed state, remove the previous tab from the tab order.
+               // If we're collapsing, then keep the collapsing tab in the tab order.
+               if ( toShow.length && toHide.length ) {
+                       eventData.oldTab.attr( "tabIndex", -1 );
+               } else if ( toShow.length ) {
+                       this.tabs.filter(function() {
+                               return $( this ).attr( "tabIndex" ) === 0;
+                       })
+                       .attr( "tabIndex", -1 );
+               }
+
+               toShow.attr( "aria-hidden", "false" );
+               eventData.newTab.attr({
+                       "aria-selected": "true",
+                       "aria-expanded": "true",
+                       tabIndex: 0
+               });
+       },
+
+       _activate: function( index ) {
+               var anchor,
+                       active = this._findActive( index );
+
+               // trying to activate the already active panel
+               if ( active[ 0 ] === this.active[ 0 ] ) {
+                       return;
+               }
+
+               // trying to collapse, simulate a click on the current active header
+               if ( !active.length ) {
+                       active = this.active;
+               }
+
+               anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
+               this._eventHandler({
+                       target: anchor,
+                       currentTarget: anchor,
+                       preventDefault: $.noop
+               });
+       },
+
+       _findActive: function( index ) {
+               return index === false ? $() : this.tabs.eq( index );
+       },
+
+       _getIndex: function( index ) {
+               // meta-function to give users option to provide a href string instead of a numerical index.
+               if ( typeof index === "string" ) {
+                       index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
+               }
+
+               return index;
+       },
+
+       _destroy: function() {
+               if ( this.xhr ) {
+                       this.xhr.abort();
+               }
+
+               this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
+
+               this.tablist
+                       .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+                       .removeAttr( "role" );
+
+               this.anchors
+                       .removeClass( "ui-tabs-anchor" )
+                       .removeAttr( "role" )
+                       .removeAttr( "tabIndex" )
+                       .removeUniqueId();
+
+               this.tablist.unbind( this.eventNamespace );
+
+               this.tabs.add( this.panels ).each(function() {
+                       if ( $.data( this, "ui-tabs-destroy" ) ) {
+                               $( this ).remove();
+                       } else {
+                               $( this )
+                                       .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
+                                               "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
+                                       .removeAttr( "tabIndex" )
+                                       .removeAttr( "aria-live" )
+                                       .removeAttr( "aria-busy" )
+                                       .removeAttr( "aria-selected" )
+                                       .removeAttr( "aria-labelledby" )
+                                       .removeAttr( "aria-hidden" )
+                                       .removeAttr( "aria-expanded" )
+                                       .removeAttr( "role" );
+                       }
+               });
+
+               this.tabs.each(function() {
+                       var li = $( this ),
+                               prev = li.data( "ui-tabs-aria-controls" );
+                       if ( prev ) {
+                               li
+                                       .attr( "aria-controls", prev )
+                                       .removeData( "ui-tabs-aria-controls" );
+                       } else {
+                               li.removeAttr( "aria-controls" );
+                       }
+               });
+
+               this.panels.show();
+
+               if ( this.options.heightStyle !== "content" ) {
+                       this.panels.css( "height", "" );
+               }
+       },
+
+       enable: function( index ) {
+               var disabled = this.options.disabled;
+               if ( disabled === false ) {
+                       return;
+               }
+
+               if ( index === undefined ) {
+                       disabled = false;
+               } else {
+                       index = this._getIndex( index );
+                       if ( $.isArray( disabled ) ) {
+                               disabled = $.map( disabled, function( num ) {
+                                       return num !== index ? num : null;
+                               });
+                       } else {
+                               disabled = $.map( this.tabs, function( li, num ) {
+                                       return num !== index ? num : null;
+                               });
+                       }
+               }
+               this._setupDisabled( disabled );
+       },
+
+       disable: function( index ) {
+               var disabled = this.options.disabled;
+               if ( disabled === true ) {
+                       return;
+               }
+
+               if ( index === undefined ) {
+                       disabled = true;
+               } else {
+                       index = this._getIndex( index );
+                       if ( $.inArray( index, disabled ) !== -1 ) {
+                               return;
+                       }
+                       if ( $.isArray( disabled ) ) {
+                               disabled = $.merge( [ index ], disabled ).sort();
+                       } else {
+                               disabled = [ index ];
+                       }
+               }
+               this._setupDisabled( disabled );
+       },
+
+       load: function( index, event ) {
+               index = this._getIndex( index );
+               var that = this,
+                       tab = this.tabs.eq( index ),
+                       anchor = tab.find( ".ui-tabs-anchor" ),
+                       panel = this._getPanelForTab( tab ),
+                       eventData = {
+                               tab: tab,
+                               panel: panel
+                       };
+
+               // not remote
+               if ( this._isLocal( anchor[ 0 ] ) ) {
+                       return;
+               }
+
+               this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
+
+               // support: jQuery <1.8
+               // jQuery <1.8 returns false if the request is canceled in beforeSend,
+               // but as of 1.8, $.ajax() always returns a jqXHR object.
+               if ( this.xhr && this.xhr.statusText !== "canceled" ) {
+                       tab.addClass( "ui-tabs-loading" );
+                       panel.attr( "aria-busy", "true" );
+
+                       this.xhr
+                               .success(function( response ) {
+                                       // support: jQuery <1.8
+                                       // http://bugs.jquery.com/ticket/11778
+                                       setTimeout(function() {
+                                               panel.html( response );
+                                               that._trigger( "load", event, eventData );
+                                       }, 1 );
+                               })
+                               .complete(function( jqXHR, status ) {
+                                       // support: jQuery <1.8
+                                       // http://bugs.jquery.com/ticket/11778
+                                       setTimeout(function() {
+                                               if ( status === "abort" ) {
+                                                       that.panels.stop( false, true );
+                                               }
+
+                                               tab.removeClass( "ui-tabs-loading" );
+                                               panel.removeAttr( "aria-busy" );
+
+                                               if ( jqXHR === that.xhr ) {
+                                                       delete that.xhr;
+                                               }
+                                       }, 1 );
+                               });
+               }
+       },
+
+       _ajaxSettings: function( anchor, event, eventData ) {
+               var that = this;
+               return {
+                       url: anchor.attr( "href" ),
+                       beforeSend: function( jqXHR, settings ) {
+                               return that._trigger( "beforeLoad", event,
+                                       $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
+                       }
+               };
+       },
+
+       _getPanelForTab: function( tab ) {
+               var id = $( tab ).attr( "aria-controls" );
+               return this.element.find( this._sanitizeSelector( "#" + id ) );
+       }
+});
+
+
+/*!
+ * jQuery UI Tooltip 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/tooltip/
+ */
+
+
+var tooltip = $.widget( "ui.tooltip", {
+       version: "1.11.3",
+       options: {
+               content: function() {
+                       // support: IE<9, Opera in jQuery <1.7
+                       // .text() can't accept undefined, so coerce to a string
+                       var title = $( this ).attr( "title" ) || "";
+                       // Escape title, since we're going from an attribute to raw HTML
+                       return $( "<a>" ).text( title ).html();
+               },
+               hide: true,
+               // Disabled elements have inconsistent behavior across browsers (#8661)
+               items: "[title]:not([disabled])",
+               position: {
+                       my: "left top+15",
+                       at: "left bottom",
+                       collision: "flipfit flip"
+               },
+               show: true,
+               tooltipClass: null,
+               track: false,
+
+               // callbacks
+               close: null,
+               open: null
+       },
+
+       _addDescribedBy: function( elem, id ) {
+               var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
+               describedby.push( id );
+               elem
+                       .data( "ui-tooltip-id", id )
+                       .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
+       },
+
+       _removeDescribedBy: function( elem ) {
+               var id = elem.data( "ui-tooltip-id" ),
+                       describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
+                       index = $.inArray( id, describedby );
+
+               if ( index !== -1 ) {
+                       describedby.splice( index, 1 );
+               }
+
+               elem.removeData( "ui-tooltip-id" );
+               describedby = $.trim( describedby.join( " " ) );
+               if ( describedby ) {
+                       elem.attr( "aria-describedby", describedby );
+               } else {
+                       elem.removeAttr( "aria-describedby" );
+               }
+       },
+
+       _create: function() {
+               this._on({
+                       mouseover: "open",
+                       focusin: "open"
+               });
+
+               // IDs of generated tooltips, needed for destroy
+               this.tooltips = {};
+
+               // IDs of parent tooltips where we removed the title attribute
+               this.parents = {};
+
+               if ( this.options.disabled ) {
+                       this._disable();
+               }
+
+               // Append the aria-live region so tooltips announce correctly
+               this.liveRegion = $( "<div>" )
+                       .attr({
+                               role: "log",
+                               "aria-live": "assertive",
+                               "aria-relevant": "additions"
+                       })
+                       .addClass( "ui-helper-hidden-accessible" )
+                       .appendTo( this.document[ 0 ].body );
+       },
+
+       _setOption: function( key, value ) {
+               var that = this;
+
+               if ( key === "disabled" ) {
+                       this[ value ? "_disable" : "_enable" ]();
+                       this.options[ key ] = value;
+                       // disable element style changes
+                       return;
+               }
+
+               this._super( key, value );
+
+               if ( key === "content" ) {
+                       $.each( this.tooltips, function( id, tooltipData ) {
+                               that._updateContent( tooltipData.element );
+                       });
+               }
+       },
+
+       _disable: function() {
+               var that = this;
+
+               // close open tooltips
+               $.each( this.tooltips, function( id, tooltipData ) {
+                       var event = $.Event( "blur" );
+                       event.target = event.currentTarget = tooltipData.element[ 0 ];
+                       that.close( event, true );
+               });
+
+               // remove title attributes to prevent native tooltips
+               this.element.find( this.options.items ).addBack().each(function() {
+                       var element = $( this );
+                       if ( element.is( "[title]" ) ) {
+                               element
+                                       .data( "ui-tooltip-title", element.attr( "title" ) )
+                                       .removeAttr( "title" );
+                       }
+               });
+       },
+
+       _enable: function() {
+               // restore title attributes
+               this.element.find( this.options.items ).addBack().each(function() {
+                       var element = $( this );
+                       if ( element.data( "ui-tooltip-title" ) ) {
+                               element.attr( "title", element.data( "ui-tooltip-title" ) );
+                       }
+               });
+       },
+
+       open: function( event ) {
+               var that = this,
+                       target = $( event ? event.target : this.element )
+                               // we need closest here due to mouseover bubbling,
+                               // but always pointing at the same event target
+                               .closest( this.options.items );
+
+               // No element to show a tooltip for or the tooltip is already open
+               if ( !target.length || target.data( "ui-tooltip-id" ) ) {
+                       return;
+               }
+
+               if ( target.attr( "title" ) ) {
+                       target.data( "ui-tooltip-title", target.attr( "title" ) );
+               }
+
+               target.data( "ui-tooltip-open", true );
+
+               // kill parent tooltips, custom or native, for hover
+               if ( event && event.type === "mouseover" ) {
+                       target.parents().each(function() {
+                               var parent = $( this ),
+                                       blurEvent;
+                               if ( parent.data( "ui-tooltip-open" ) ) {
+                                       blurEvent = $.Event( "blur" );
+                                       blurEvent.target = blurEvent.currentTarget = this;
+                                       that.close( blurEvent, true );
+                               }
+                               if ( parent.attr( "title" ) ) {
+                                       parent.uniqueId();
+                                       that.parents[ this.id ] = {
+                                               element: this,
+                                               title: parent.attr( "title" )
+                                       };
+                                       parent.attr( "title", "" );
+                               }
+                       });
+               }
+
+               this._updateContent( target, event );
+       },
+
+       _updateContent: function( target, event ) {
+               var content,
+                       contentOption = this.options.content,
+                       that = this,
+                       eventType = event ? event.type : null;
+
+               if ( typeof contentOption === "string" ) {
+                       return this._open( event, target, contentOption );
+               }
+
+               content = contentOption.call( target[0], function( response ) {
+                       // ignore async response if tooltip was closed already
+                       if ( !target.data( "ui-tooltip-open" ) ) {
+                               return;
+                       }
+                       // IE may instantly serve a cached response for ajax requests
+                       // delay this call to _open so the other call to _open runs first
+                       that._delay(function() {
+                               // jQuery creates a special event for focusin when it doesn't
+                               // exist natively. To improve performance, the native event
+                               // object is reused and the type is changed. Therefore, we can't
+                               // rely on the type being correct after the event finished
+                               // bubbling, so we set it back to the previous value. (#8740)
+                               if ( event ) {
+                                       event.type = eventType;
+                               }
+                               this._open( event, target, response );
+                       });
+               });
+               if ( content ) {
+                       this._open( event, target, content );
+               }
+       },
+
+       _open: function( event, target, content ) {
+               var tooltipData, tooltip, events, delayedShow, a11yContent,
+                       positionOption = $.extend( {}, this.options.position );
+
+               if ( !content ) {
+                       return;
+               }
+
+               // Content can be updated multiple times. If the tooltip already
+               // exists, then just update the content and bail.
+               tooltipData = this._find( target );
+               if ( tooltipData ) {
+                       tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
+                       return;
+               }
+
+               // if we have a title, clear it to prevent the native tooltip
+               // we have to check first to avoid defining a title if none exists
+               // (we don't want to cause an element to start matching [title])
+               //
+               // We use removeAttr only for key events, to allow IE to export the correct
+               // accessible attributes. For mouse events, set to empty string to avoid
+               // native tooltip showing up (happens only when removing inside mouseover).
+               if ( target.is( "[title]" ) ) {
+                       if ( event && event.type === "mouseover" ) {
+                               target.attr( "title", "" );
+                       } else {
+                               target.removeAttr( "title" );
+                       }
+               }
+
+               tooltipData = this._tooltip( target );
+               tooltip = tooltipData.tooltip;
+               this._addDescribedBy( target, tooltip.attr( "id" ) );
+               tooltip.find( ".ui-tooltip-content" ).html( content );
+
+               // Support: Voiceover on OS X, JAWS on IE <= 9
+               // JAWS announces deletions even when aria-relevant="additions"
+               // Voiceover will sometimes re-read the entire log region's contents from the beginning
+               this.liveRegion.children().hide();
+               if ( content.clone ) {
+                       a11yContent = content.clone();
+                       a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
+               } else {
+                       a11yContent = content;
+               }
+               $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
+
+               function position( event ) {
+                       positionOption.of = event;
+                       if ( tooltip.is( ":hidden" ) ) {
+                               return;
+                       }
+                       tooltip.position( positionOption );
+               }
+               if ( this.options.track && event && /^mouse/.test( event.type ) ) {
+                       this._on( this.document, {
+                               mousemove: position
+                       });
+                       // trigger once to override element-relative positioning
+                       position( event );
+               } else {
+                       tooltip.position( $.extend({
+                               of: target
+                       }, this.options.position ) );
+               }
+
+               tooltip.hide();
+
+               this._show( tooltip, this.options.show );
+               // Handle tracking tooltips that are shown with a delay (#8644). As soon
+               // as the tooltip is visible, position the tooltip using the most recent
+               // event.
+               if ( this.options.show && this.options.show.delay ) {
+                       delayedShow = this.delayedShow = setInterval(function() {
+                               if ( tooltip.is( ":visible" ) ) {
+                                       position( positionOption.of );
+                                       clearInterval( delayedShow );
+                               }
+                       }, $.fx.interval );
+               }
+
+               this._trigger( "open", event, { tooltip: tooltip } );
+
+               events = {
+                       keyup: function( event ) {
+                               if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
+                                       var fakeEvent = $.Event(event);
+                                       fakeEvent.currentTarget = target[0];
+                                       this.close( fakeEvent, true );
+                               }
+                       }
+               };
+
+               // Only bind remove handler for delegated targets. Non-delegated
+               // tooltips will handle this in destroy.
+               if ( target[ 0 ] !== this.element[ 0 ] ) {
+                       events.remove = function() {
+                               this._removeTooltip( tooltip );
+                       };
+               }
+
+               if ( !event || event.type === "mouseover" ) {
+                       events.mouseleave = "close";
+               }
+               if ( !event || event.type === "focusin" ) {
+                       events.focusout = "close";
+               }
+               this._on( true, target, events );
+       },
+
+       close: function( event ) {
+               var tooltip,
+                       that = this,
+                       target = $( event ? event.currentTarget : this.element ),
+                       tooltipData = this._find( target );
+
+               // The tooltip may already be closed
+               if ( !tooltipData ) {
+                       return;
+               }
+
+               tooltip = tooltipData.tooltip;
+
+               // disabling closes the tooltip, so we need to track when we're closing
+               // to avoid an infinite loop in case the tooltip becomes disabled on close
+               if ( tooltipData.closing ) {
+                       return;
+               }
+
+               // Clear the interval for delayed tracking tooltips
+               clearInterval( this.delayedShow );
+
+               // only set title if we had one before (see comment in _open())
+               // If the title attribute has changed since open(), don't restore
+               if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
+                       target.attr( "title", target.data( "ui-tooltip-title" ) );
+               }
+
+               this._removeDescribedBy( target );
+
+               tooltipData.hiding = true;
+               tooltip.stop( true );
+               this._hide( tooltip, this.options.hide, function() {
+                       that._removeTooltip( $( this ) );
+               });
+
+               target.removeData( "ui-tooltip-open" );
+               this._off( target, "mouseleave focusout keyup" );
+
+               // Remove 'remove' binding only on delegated targets
+               if ( target[ 0 ] !== this.element[ 0 ] ) {
+                       this._off( target, "remove" );
+               }
+               this._off( this.document, "mousemove" );
+
+               if ( event && event.type === "mouseleave" ) {
+                       $.each( this.parents, function( id, parent ) {
+                               $( parent.element ).attr( "title", parent.title );
+                               delete that.parents[ id ];
+                       });
+               }
+
+               tooltipData.closing = true;
+               this._trigger( "close", event, { tooltip: tooltip } );
+               if ( !tooltipData.hiding ) {
+                       tooltipData.closing = false;
+               }
+       },
+
+       _tooltip: function( element ) {
+               var tooltip = $( "<div>" )
+                               .attr( "role", "tooltip" )
+                               .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
+                                       ( this.options.tooltipClass || "" ) ),
+                       id = tooltip.uniqueId().attr( "id" );
+
+               $( "<div>" )
+                       .addClass( "ui-tooltip-content" )
+                       .appendTo( tooltip );
+
+               tooltip.appendTo( this.document[0].body );
+
+               return this.tooltips[ id ] = {
+                       element: element,
+                       tooltip: tooltip
+               };
+       },
+
+       _find: function( target ) {
+               var id = target.data( "ui-tooltip-id" );
+               return id ? this.tooltips[ id ] : null;
+       },
+
+       _removeTooltip: function( tooltip ) {
+               tooltip.remove();
+               delete this.tooltips[ tooltip.attr( "id" ) ];
+       },
+
+       _destroy: function() {
+               var that = this;
+
+               // close open tooltips
+               $.each( this.tooltips, function( id, tooltipData ) {
+                       // Delegate to close method to handle common cleanup
+                       var event = $.Event( "blur" ),
+                               element = tooltipData.element;
+                       event.target = event.currentTarget = element[ 0 ];
+                       that.close( event, true );
+
+                       // Remove immediately; destroying an open tooltip doesn't use the
+                       // hide animation
+                       $( "#" + id ).remove();
+
+                       // Restore the title
+                       if ( element.data( "ui-tooltip-title" ) ) {
+                               // If the title attribute has changed since open(), don't restore
+                               if ( !element.attr( "title" ) ) {
+                                       element.attr( "title", element.data( "ui-tooltip-title" ) );
+                               }
+                               element.removeData( "ui-tooltip-title" );
+                       }
+               });
+               this.liveRegion.remove();
+       }
+});
+
+
+/*!
+ * jQuery UI Effects 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/effects-core/
+ */
+
+
+var dataSpace = "ui-effects-",
+
+       // Create a local jQuery because jQuery Color relies on it and the
+       // global may not exist with AMD and a custom build (#10199)
+       jQuery = $;
+
+$.effects = {
+       effect: {}
+};
+
+/*!
+ * jQuery Color Animations v2.1.2
+ * https://github.com/jquery/jquery-color
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * Date: Wed Jan 16 08:47:09 2013 -0600
+ */
+(function( jQuery, undefined ) {
+
+       var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
+
+       // plusequals test for += 100 -= 100
+       rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
+       // a set of RE's that can match strings and generate color tuples.
+       stringParsers = [ {
+                       re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ],
+                                       execResult[ 3 ],
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ] * 2.55,
+                                       execResult[ 2 ] * 2.55,
+                                       execResult[ 3 ] * 2.55,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       space: "hsla",
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ] / 100,
+                                       execResult[ 3 ] / 100,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               } ],
+
+       // jQuery.Color( )
+       color = jQuery.Color = function( color, green, blue, alpha ) {
+               return new jQuery.Color.fn.parse( color, green, blue, alpha );
+       },
+       spaces = {
+               rgba: {
+                       props: {
+                               red: {
+                                       idx: 0,
+                                       type: "byte"
+                               },
+                               green: {
+                                       idx: 1,
+                                       type: "byte"
+                               },
+                               blue: {
+                                       idx: 2,
+                                       type: "byte"
+                               }
+                       }
+               },
+
+               hsla: {
+                       props: {
+                               hue: {
+                                       idx: 0,
+                                       type: "degrees"
+                               },
+                               saturation: {
+                                       idx: 1,
+                                       type: "percent"
+                               },
+                               lightness: {
+                                       idx: 2,
+                                       type: "percent"
+                               }
+                       }
+               }
+       },
+       propTypes = {
+               "byte": {
+                       floor: true,
+                       max: 255
+               },
+               "percent": {
+                       max: 1
+               },
+               "degrees": {
+                       mod: 360,
+                       floor: true
+               }
+       },
+       support = color.support = {},
+
+       // element for support tests
+       supportElem = jQuery( "<p>" )[ 0 ],
+
+       // colors = jQuery.Color.names
+       colors,
+
+       // local aliases of functions called often
+       each = jQuery.each;
+
+// determine rgba support immediately
+supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
+support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
+
+// define cache name and alpha properties
+// for rgba and hsla spaces
+each( spaces, function( spaceName, space ) {
+       space.cache = "_" + spaceName;
+       space.props.alpha = {
+               idx: 3,
+               type: "percent",
+               def: 1
+       };
+});
+
+function clamp( value, prop, allowEmpty ) {
+       var type = propTypes[ prop.type ] || {};
+
+       if ( value == null ) {
+               return (allowEmpty || !prop.def) ? null : prop.def;
+       }
+
+       // ~~ is an short way of doing floor for positive numbers
+       value = type.floor ? ~~value : parseFloat( value );
+
+       // IE will pass in empty strings as value for alpha,
+       // which will hit this case
+       if ( isNaN( value ) ) {
+               return prop.def;
+       }
+
+       if ( type.mod ) {
+               // we add mod before modding to make sure that negatives values
+               // get converted properly: -10 -> 350
+               return (value + type.mod) % type.mod;
+       }
+
+       // for now all property types without mod have min and max
+       return 0 > value ? 0 : type.max < value ? type.max : value;
+}
+
+function stringParse( string ) {
+       var inst = color(),
+               rgba = inst._rgba = [];
+
+       string = string.toLowerCase();
+
+       each( stringParsers, function( i, parser ) {
+               var parsed,
+                       match = parser.re.exec( string ),
+                       values = match && parser.parse( match ),
+                       spaceName = parser.space || "rgba";
+
+               if ( values ) {
+                       parsed = inst[ spaceName ]( values );
+
+                       // if this was an rgba parse the assignment might happen twice
+                       // oh well....
+                       inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
+                       rgba = inst._rgba = parsed._rgba;
+
+                       // exit each( stringParsers ) here because we matched
+                       return false;
+               }
+       });
+
+       // Found a stringParser that handled it
+       if ( rgba.length ) {
+
+               // if this came from a parsed string, force "transparent" when alpha is 0
+               // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
+               if ( rgba.join() === "0,0,0,0" ) {
+                       jQuery.extend( rgba, colors.transparent );
+               }
+               return inst;
+       }
+
+       // named colors
+       return colors[ string ];
+}
+
+color.fn = jQuery.extend( color.prototype, {
+       parse: function( red, green, blue, alpha ) {
+               if ( red === undefined ) {
+                       this._rgba = [ null, null, null, null ];
+                       return this;
+               }
+               if ( red.jquery || red.nodeType ) {
+                       red = jQuery( red ).css( green );
+                       green = undefined;
+               }
+
+               var inst = this,
+                       type = jQuery.type( red ),
+                       rgba = this._rgba = [];
+
+               // more than 1 argument specified - assume ( red, green, blue, alpha )
+               if ( green !== undefined ) {
+                       red = [ red, green, blue, alpha ];
+                       type = "array";
+               }
+
+               if ( type === "string" ) {
+                       return this.parse( stringParse( red ) || colors._default );
+               }
+
+               if ( type === "array" ) {
+                       each( spaces.rgba.props, function( key, prop ) {
+                               rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
+                       });
+                       return this;
+               }
+
+               if ( type === "object" ) {
+                       if ( red instanceof color ) {
+                               each( spaces, function( spaceName, space ) {
+                                       if ( red[ space.cache ] ) {
+                                               inst[ space.cache ] = red[ space.cache ].slice();
+                                       }
+                               });
+                       } else {
+                               each( spaces, function( spaceName, space ) {
+                                       var cache = space.cache;
+                                       each( space.props, function( key, prop ) {
+
+                                               // if the cache doesn't exist, and we know how to convert
+                                               if ( !inst[ cache ] && space.to ) {
+
+                                                       // if the value was null, we don't need to copy it
+                                                       // if the key was alpha, we don't need to copy it either
+                                                       if ( key === "alpha" || red[ key ] == null ) {
+                                                               return;
+                                                       }
+                                                       inst[ cache ] = space.to( inst._rgba );
+                                               }
+
+                                               // this is the only case where we allow nulls for ALL properties.
+                                               // call clamp with alwaysAllowEmpty
+                                               inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
+                                       });
+
+                                       // everything defined but alpha?
+                                       if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
+                                               // use the default of 1
+                                               inst[ cache ][ 3 ] = 1;
+                                               if ( space.from ) {
+                                                       inst._rgba = space.from( inst[ cache ] );
+                                               }
+                                       }
+                               });
+                       }
+                       return this;
+               }
+       },
+       is: function( compare ) {
+               var is = color( compare ),
+                       same = true,
+                       inst = this;
+
+               each( spaces, function( _, space ) {
+                       var localCache,
+                               isCache = is[ space.cache ];
+                       if (isCache) {
+                               localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
+                               each( space.props, function( _, prop ) {
+                                       if ( isCache[ prop.idx ] != null ) {
+                                               same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
+                                               return same;
+                                       }
+                               });
+                       }
+                       return same;
+               });
+               return same;
+       },
+       _space: function() {
+               var used = [],
+                       inst = this;
+               each( spaces, function( spaceName, space ) {
+                       if ( inst[ space.cache ] ) {
+                               used.push( spaceName );
+                       }
+               });
+               return used.pop();
+       },
+       transition: function( other, distance ) {
+               var end = color( other ),
+                       spaceName = end._space(),
+                       space = spaces[ spaceName ],
+                       startColor = this.alpha() === 0 ? color( "transparent" ) : this,
+                       start = startColor[ space.cache ] || space.to( startColor._rgba ),
+                       result = start.slice();
+
+               end = end[ space.cache ];
+               each( space.props, function( key, prop ) {
+                       var index = prop.idx,
+                               startValue = start[ index ],
+                               endValue = end[ index ],
+                               type = propTypes[ prop.type ] || {};
+
+                       // if null, don't override start value
+                       if ( endValue === null ) {
+                               return;
+                       }
+                       // if null - use end
+                       if ( startValue === null ) {
+                               result[ index ] = endValue;
+                       } else {
+                               if ( type.mod ) {
+                                       if ( endValue - startValue > type.mod / 2 ) {
+                                               startValue += type.mod;
+                                       } else if ( startValue - endValue > type.mod / 2 ) {
+                                               startValue -= type.mod;
+                                       }
+                               }
+                               result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
+                       }
+               });
+               return this[ spaceName ]( result );
+       },
+       blend: function( opaque ) {
+               // if we are already opaque - return ourself
+               if ( this._rgba[ 3 ] === 1 ) {
+                       return this;
+               }
+
+               var rgb = this._rgba.slice(),
+                       a = rgb.pop(),
+                       blend = color( opaque )._rgba;
+
+               return color( jQuery.map( rgb, function( v, i ) {
+                       return ( 1 - a ) * blend[ i ] + a * v;
+               }));
+       },
+       toRgbaString: function() {
+               var prefix = "rgba(",
+                       rgba = jQuery.map( this._rgba, function( v, i ) {
+                               return v == null ? ( i > 2 ? 1 : 0 ) : v;
+                       });
+
+               if ( rgba[ 3 ] === 1 ) {
+                       rgba.pop();
+                       prefix = "rgb(";
+               }
+
+               return prefix + rgba.join() + ")";
+       },
+       toHslaString: function() {
+               var prefix = "hsla(",
+                       hsla = jQuery.map( this.hsla(), function( v, i ) {
+                               if ( v == null ) {
+                                       v = i > 2 ? 1 : 0;
+                               }
+
+                               // catch 1 and 2
+                               if ( i && i < 3 ) {
+                                       v = Math.round( v * 100 ) + "%";
+                               }
+                               return v;
+                       });
+
+               if ( hsla[ 3 ] === 1 ) {
+                       hsla.pop();
+                       prefix = "hsl(";
+               }
+               return prefix + hsla.join() + ")";
+       },
+       toHexString: function( includeAlpha ) {
+               var rgba = this._rgba.slice(),
+                       alpha = rgba.pop();
+
+               if ( includeAlpha ) {
+                       rgba.push( ~~( alpha * 255 ) );
+               }
+
+               return "#" + jQuery.map( rgba, function( v ) {
+
+                       // default to 0 when nulls exist
+                       v = ( v || 0 ).toString( 16 );
+                       return v.length === 1 ? "0" + v : v;
+               }).join("");
+       },
+       toString: function() {
+               return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
+       }
+});
+color.fn.parse.prototype = color.fn;
+
+// hsla conversions adapted from:
+// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
+
+function hue2rgb( p, q, h ) {
+       h = ( h + 1 ) % 1;
+       if ( h * 6 < 1 ) {
+               return p + ( q - p ) * h * 6;
+       }
+       if ( h * 2 < 1) {
+               return q;
+       }
+       if ( h * 3 < 2 ) {
+               return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
+       }
+       return p;
+}
+
+spaces.hsla.to = function( rgba ) {
+       if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
+               return [ null, null, null, rgba[ 3 ] ];
+       }
+       var r = rgba[ 0 ] / 255,
+               g = rgba[ 1 ] / 255,
+               b = rgba[ 2 ] / 255,
+               a = rgba[ 3 ],
+               max = Math.max( r, g, b ),
+               min = Math.min( r, g, b ),
+               diff = max - min,
+               add = max + min,
+               l = add * 0.5,
+               h, s;
+
+       if ( min === max ) {
+               h = 0;
+       } else if ( r === max ) {
+               h = ( 60 * ( g - b ) / diff ) + 360;
+       } else if ( g === max ) {
+               h = ( 60 * ( b - r ) / diff ) + 120;
+       } else {
+               h = ( 60 * ( r - g ) / diff ) + 240;
+       }
+
+       // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
+       // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
+       if ( diff === 0 ) {
+               s = 0;
+       } else if ( l <= 0.5 ) {
+               s = diff / add;
+       } else {
+               s = diff / ( 2 - add );
+       }
+       return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
+};
+
+spaces.hsla.from = function( hsla ) {
+       if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
+               return [ null, null, null, hsla[ 3 ] ];
+       }
+       var h = hsla[ 0 ] / 360,
+               s = hsla[ 1 ],
+               l = hsla[ 2 ],
+               a = hsla[ 3 ],
+               q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
+               p = 2 * l - q;
+
+       return [
+               Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
+               Math.round( hue2rgb( p, q, h ) * 255 ),
+               Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
+               a
+       ];
+};
+
+each( spaces, function( spaceName, space ) {
+       var props = space.props,
+               cache = space.cache,
+               to = space.to,
+               from = space.from;
+
+       // makes rgba() and hsla()
+       color.fn[ spaceName ] = function( value ) {
+
+               // generate a cache for this space if it doesn't exist
+               if ( to && !this[ cache ] ) {
+                       this[ cache ] = to( this._rgba );
+               }
+               if ( value === undefined ) {
+                       return this[ cache ].slice();
+               }
+
+               var ret,
+                       type = jQuery.type( value ),
+                       arr = ( type === "array" || type === "object" ) ? value : arguments,
+                       local = this[ cache ].slice();
+
+               each( props, function( key, prop ) {
+                       var val = arr[ type === "object" ? key : prop.idx ];
+                       if ( val == null ) {
+                               val = local[ prop.idx ];
+                       }
+                       local[ prop.idx ] = clamp( val, prop );
+               });
+
+               if ( from ) {
+                       ret = color( from( local ) );
+                       ret[ cache ] = local;
+                       return ret;
+               } else {
+                       return color( local );
+               }
+       };
+
+       // makes red() green() blue() alpha() hue() saturation() lightness()
+       each( props, function( key, prop ) {
+               // alpha is included in more than one space
+               if ( color.fn[ key ] ) {
+                       return;
+               }
+               color.fn[ key ] = function( value ) {
+                       var vtype = jQuery.type( value ),
+                               fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
+                               local = this[ fn ](),
+                               cur = local[ prop.idx ],
+                               match;
+
+                       if ( vtype === "undefined" ) {
+                               return cur;
+                       }
+
+                       if ( vtype === "function" ) {
+                               value = value.call( this, cur );
+                               vtype = jQuery.type( value );
+                       }
+                       if ( value == null && prop.empty ) {
+                               return this;
+                       }
+                       if ( vtype === "string" ) {
+                               match = rplusequals.exec( value );
+                               if ( match ) {
+                                       value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
+                               }
+                       }
+                       local[ prop.idx ] = value;
+                       return this[ fn ]( local );
+               };
+       });
+});
+
+// add cssHook and .fx.step function for each named hook.
+// accept a space separated string of properties
+color.hook = function( hook ) {
+       var hooks = hook.split( " " );
+       each( hooks, function( i, hook ) {
+               jQuery.cssHooks[ hook ] = {
+                       set: function( elem, value ) {
+                               var parsed, curElem,
+                                       backgroundColor = "";
+
+                               if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
+                                       value = color( parsed || value );
+                                       if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
+                                               curElem = hook === "backgroundColor" ? elem.parentNode : elem;
+                                               while (
+                                                       (backgroundColor === "" || backgroundColor === "transparent") &&
+                                                       curElem && curElem.style
+                                               ) {
+                                                       try {
+                                                               backgroundColor = jQuery.css( curElem, "backgroundColor" );
+                                                               curElem = curElem.parentNode;
+                                                       } catch ( e ) {
+                                                       }
+                                               }
+
+                                               value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
+                                                       backgroundColor :
+                                                       "_default" );
+                                       }
+
+                                       value = value.toRgbaString();
+                               }
+                               try {
+                                       elem.style[ hook ] = value;
+                               } catch ( e ) {
+                                       // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
+                               }
+                       }
+               };
+               jQuery.fx.step[ hook ] = function( fx ) {
+                       if ( !fx.colorInit ) {
+                               fx.start = color( fx.elem, hook );
+                               fx.end = color( fx.end );
+                               fx.colorInit = true;
+                       }
+                       jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
+               };
+       });
+
+};
+
+color.hook( stepHooks );
+
+jQuery.cssHooks.borderColor = {
+       expand: function( value ) {
+               var expanded = {};
+
+               each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
+                       expanded[ "border" + part + "Color" ] = value;
+               });
+               return expanded;
+       }
+};
+
+// Basic color names only.
+// Usage of any of the other color names requires adding yourself or including
+// jquery.color.svg-names.js.
+colors = jQuery.Color.names = {
+       // 4.1. Basic color keywords
+       aqua: "#00ffff",
+       black: "#000000",
+       blue: "#0000ff",
+       fuchsia: "#ff00ff",
+       gray: "#808080",
+       green: "#008000",
+       lime: "#00ff00",
+       maroon: "#800000",
+       navy: "#000080",
+       olive: "#808000",
+       purple: "#800080",
+       red: "#ff0000",
+       silver: "#c0c0c0",
+       teal: "#008080",
+       white: "#ffffff",
+       yellow: "#ffff00",
+
+       // 4.2.3. "transparent" color keyword
+       transparent: [ null, null, null, 0 ],
+
+       _default: "#ffffff"
+};
+
+})( jQuery );
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+(function() {
+
+var classAnimationActions = [ "add", "remove", "toggle" ],
+       shorthandStyles = {
+               border: 1,
+               borderBottom: 1,
+               borderColor: 1,
+               borderLeft: 1,
+               borderRight: 1,
+               borderTop: 1,
+               borderWidth: 1,
+               margin: 1,
+               padding: 1
+       };
+
+$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
+       $.fx.step[ prop ] = function( fx ) {
+               if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
+                       jQuery.style( fx.elem, prop, fx.end );
+                       fx.setAttr = true;
+               }
+       };
+});
+
+function getElementStyles( elem ) {
+       var key, len,
+               style = elem.ownerDocument.defaultView ?
+                       elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+                       elem.currentStyle,
+               styles = {};
+
+       if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
+               len = style.length;
+               while ( len-- ) {
+                       key = style[ len ];
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ $.camelCase( key ) ] = style[ key ];
+                       }
+               }
+       // support: Opera, IE <9
+       } else {
+               for ( key in style ) {
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ key ] = style[ key ];
+                       }
+               }
+       }
+
+       return styles;
+}
+
+function styleDifference( oldStyle, newStyle ) {
+       var diff = {},
+               name, value;
+
+       for ( name in newStyle ) {
+               value = newStyle[ name ];
+               if ( oldStyle[ name ] !== value ) {
+                       if ( !shorthandStyles[ name ] ) {
+                               if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
+                                       diff[ name ] = value;
+                               }
+                       }
+               }
+       }
+
+       return diff;
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+$.effects.animateClass = function( value, duration, easing, callback ) {
+       var o = $.speed( duration, easing, callback );
+
+       return this.queue( function() {
+               var animated = $( this ),
+                       baseClass = animated.attr( "class" ) || "",
+                       applyClassChange,
+                       allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
+
+               // map the animated objects to store the original styles.
+               allAnimations = allAnimations.map(function() {
+                       var el = $( this );
+                       return {
+                               el: el,
+                               start: getElementStyles( this )
+                       };
+               });
+
+               // apply class change
+               applyClassChange = function() {
+                       $.each( classAnimationActions, function(i, action) {
+                               if ( value[ action ] ) {
+                                       animated[ action + "Class" ]( value[ action ] );
+                               }
+                       });
+               };
+               applyClassChange();
+
+               // map all animated objects again - calculate new styles and diff
+               allAnimations = allAnimations.map(function() {
+                       this.end = getElementStyles( this.el[ 0 ] );
+                       this.diff = styleDifference( this.start, this.end );
+                       return this;
+               });
+
+               // apply original class
+               animated.attr( "class", baseClass );
+
+               // map all animated objects again - this time collecting a promise
+               allAnimations = allAnimations.map(function() {
+                       var styleInfo = this,
+                               dfd = $.Deferred(),
+                               opts = $.extend({}, o, {
+                                       queue: false,
+                                       complete: function() {
+                                               dfd.resolve( styleInfo );
+                                       }
+                               });
+
+                       this.el.animate( this.diff, opts );
+                       return dfd.promise();
+               });
+
+               // once all animations have completed:
+               $.when.apply( $, allAnimations.get() ).done(function() {
+
+                       // set the final class
+                       applyClassChange();
+
+                       // for each animated element,
+                       // clear all css properties that were animated
+                       $.each( arguments, function() {
+                               var el = this.el;
+                               $.each( this.diff, function(key) {
+                                       el.css( key, "" );
+                               });
+                       });
+
+                       // this is guarnteed to be there if you use jQuery.speed()
+                       // it also handles dequeuing the next anim...
+                       o.complete.call( animated[ 0 ] );
+               });
+       });
+};
+
+$.fn.extend({
+       addClass: (function( orig ) {
+               return function( classNames, speed, easing, callback ) {
+                       return speed ?
+                               $.effects.animateClass.call( this,
+                                       { add: classNames }, speed, easing, callback ) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.addClass ),
+
+       removeClass: (function( orig ) {
+               return function( classNames, speed, easing, callback ) {
+                       return arguments.length > 1 ?
+                               $.effects.animateClass.call( this,
+                                       { remove: classNames }, speed, easing, callback ) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.removeClass ),
+
+       toggleClass: (function( orig ) {
+               return function( classNames, force, speed, easing, callback ) {
+                       if ( typeof force === "boolean" || force === undefined ) {
+                               if ( !speed ) {
+                                       // without speed parameter
+                                       return orig.apply( this, arguments );
+                               } else {
+                                       return $.effects.animateClass.call( this,
+                                               (force ? { add: classNames } : { remove: classNames }),
+                                               speed, easing, callback );
+                               }
+                       } else {
+                               // without force parameter
+                               return $.effects.animateClass.call( this,
+                                       { toggle: classNames }, force, speed, easing );
+                       }
+               };
+       })( $.fn.toggleClass ),
+
+       switchClass: function( remove, add, speed, easing, callback) {
+               return $.effects.animateClass.call( this, {
+                       add: add,
+                       remove: remove
+               }, speed, easing, callback );
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+(function() {
+
+$.extend( $.effects, {
+       version: "1.11.3",
+
+       // Saves a set of properties in a data storage
+       save: function( element, set ) {
+               for ( var i = 0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
+                       }
+               }
+       },
+
+       // Restores a set of previously saved properties from a data storage
+       restore: function( element, set ) {
+               var val, i;
+               for ( i = 0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               val = element.data( dataSpace + set[ i ] );
+                               // support: jQuery 1.6.2
+                               // http://bugs.jquery.com/ticket/9917
+                               // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
+                               // We can't differentiate between "" and 0 here, so we just assume
+                               // empty string since it's likely to be a more common value...
+                               if ( val === undefined ) {
+                                       val = "";
+                               }
+                               element.css( set[ i ], val );
+                       }
+               }
+       },
+
+       setMode: function( el, mode ) {
+               if (mode === "toggle") {
+                       mode = el.is( ":hidden" ) ? "show" : "hide";
+               }
+               return mode;
+       },
+
+       // Translates a [top,left] array into a baseline value
+       // this should be a little more flexible in the future to handle a string & hash
+       getBaseline: function( origin, original ) {
+               var y, x;
+               switch ( origin[ 0 ] ) {
+                       case "top": y = 0; break;
+                       case "middle": y = 0.5; break;
+                       case "bottom": y = 1; break;
+                       default: y = origin[ 0 ] / original.height;
+               }
+               switch ( origin[ 1 ] ) {
+                       case "left": x = 0; break;
+                       case "center": x = 0.5; break;
+                       case "right": x = 1; break;
+                       default: x = origin[ 1 ] / original.width;
+               }
+               return {
+                       x: x,
+                       y: y
+               };
+       },
+
+       // Wraps the element around a wrapper that copies position properties
+       createWrapper: function( element ) {
+
+               // if the element is already wrapped, return it
+               if ( element.parent().is( ".ui-effects-wrapper" )) {
+                       return element.parent();
+               }
+
+               // wrap the element
+               var props = {
+                               width: element.outerWidth(true),
+                               height: element.outerHeight(true),
+                               "float": element.css( "float" )
+                       },
+                       wrapper = $( "<div></div>" )
+                               .addClass( "ui-effects-wrapper" )
+                               .css({
+                                       fontSize: "100%",
+                                       background: "transparent",
+                                       border: "none",
+                                       margin: 0,
+                                       padding: 0
+                               }),
+                       // Store the size in case width/height are defined in % - Fixes #5245
+                       size = {
+                               width: element.width(),
+                               height: element.height()
+                       },
+                       active = document.activeElement;
+
+               // support: Firefox
+               // Firefox incorrectly exposes anonymous content
+               // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
+               try {
+                       active.id;
+               } catch ( e ) {
+                       active = document.body;
+               }
+
+               element.wrap( wrapper );
+
+               // Fixes #7595 - Elements lose focus when wrapped.
+               if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                       $( active ).focus();
+               }
+
+               wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
+
+               // transfer positioning properties to the wrapper
+               if ( element.css( "position" ) === "static" ) {
+                       wrapper.css({ position: "relative" });
+                       element.css({ position: "relative" });
+               } else {
+                       $.extend( props, {
+                               position: element.css( "position" ),
+                               zIndex: element.css( "z-index" )
+                       });
+                       $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
+                               props[ pos ] = element.css( pos );
+                               if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
+                                       props[ pos ] = "auto";
+                               }
+                       });
+                       element.css({
+                               position: "relative",
+                               top: 0,
+                               left: 0,
+                               right: "auto",
+                               bottom: "auto"
+                       });
+               }
+               element.css(size);
+
+               return wrapper.css( props ).show();
+       },
+
+       removeWrapper: function( element ) {
+               var active = document.activeElement;
+
+               if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+                       element.parent().replaceWith( element );
+
+                       // Fixes #7595 - Elements lose focus when wrapped.
+                       if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                               $( active ).focus();
+                       }
+               }
+
+               return element;
+       },
+
+       setTransition: function( element, list, factor, value ) {
+               value = value || {};
+               $.each( list, function( i, x ) {
+                       var unit = element.cssUnit( x );
+                       if ( unit[ 0 ] > 0 ) {
+                               value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
+                       }
+               });
+               return value;
+       }
+});
+
+// return an effect options object for the given parameters:
+function _normalizeArguments( effect, options, speed, callback ) {
+
+       // allow passing all options as the first parameter
+       if ( $.isPlainObject( effect ) ) {
+               options = effect;
+               effect = effect.effect;
+       }
+
+       // convert to an object
+       effect = { effect: effect };
+
+       // catch (effect, null, ...)
+       if ( options == null ) {
+               options = {};
+       }
+
+       // catch (effect, callback)
+       if ( $.isFunction( options ) ) {
+               callback = options;
+               speed = null;
+               options = {};
+       }
+
+       // catch (effect, speed, ?)
+       if ( typeof options === "number" || $.fx.speeds[ options ] ) {
+               callback = speed;
+               speed = options;
+               options = {};
+       }
+
+       // catch (effect, options, callback)
+       if ( $.isFunction( speed ) ) {
+               callback = speed;
+               speed = null;
+       }
+
+       // add options to effect
+       if ( options ) {
+               $.extend( effect, options );
+       }
+
+       speed = speed || options.duration;
+       effect.duration = $.fx.off ? 0 :
+               typeof speed === "number" ? speed :
+               speed in $.fx.speeds ? $.fx.speeds[ speed ] :
+               $.fx.speeds._default;
+
+       effect.complete = callback || options.complete;
+
+       return effect;
+}
+
+function standardAnimationOption( option ) {
+       // Valid standard speeds (nothing, number, named speed)
+       if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
+               return true;
+       }
+
+       // Invalid strings - treat as "normal" speed
+       if ( typeof option === "string" && !$.effects.effect[ option ] ) {
+               return true;
+       }
+
+       // Complete callback
+       if ( $.isFunction( option ) ) {
+               return true;
+       }
+
+       // Options hash (but not naming an effect)
+       if ( typeof option === "object" && !option.effect ) {
+               return true;
+       }
+
+       // Didn't match any standard API
+       return false;
+}
+
+$.fn.extend({
+       effect: function( /* effect, options, speed, callback */ ) {
+               var args = _normalizeArguments.apply( this, arguments ),
+                       mode = args.mode,
+                       queue = args.queue,
+                       effectMethod = $.effects.effect[ args.effect ];
+
+               if ( $.fx.off || !effectMethod ) {
+                       // delegate to the original method (e.g., .show()) if possible
+                       if ( mode ) {
+                               return this[ mode ]( args.duration, args.complete );
+                       } else {
+                               return this.each( function() {
+                                       if ( args.complete ) {
+                                               args.complete.call( this );
+                                       }
+                               });
+                       }
+               }
+
+               function run( next ) {
+                       var elem = $( this ),
+                               complete = args.complete,
+                               mode = args.mode;
+
+                       function done() {
+                               if ( $.isFunction( complete ) ) {
+                                       complete.call( elem[0] );
+                               }
+                               if ( $.isFunction( next ) ) {
+                                       next();
+                               }
+                       }
+
+                       // If the element already has the correct final state, delegate to
+                       // the core methods so the internal tracking of "olddisplay" works.
+                       if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
+                               elem[ mode ]();
+                               done();
+                       } else {
+                               effectMethod.call( elem[0], args, done );
+                       }
+               }
+
+               return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
+       },
+
+       show: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "show";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.show ),
+
+       hide: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "hide";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.hide ),
+
+       toggle: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "toggle";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.toggle ),
+
+       // helper functions
+       cssUnit: function(key) {
+               var style = this.css( key ),
+                       val = [];
+
+               $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
+                       if ( style.indexOf( unit ) > 0 ) {
+                               val = [ parseFloat( style ), unit ];
+                       }
+               });
+               return val;
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+(function() {
+
+// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
+
+var baseEasings = {};
+
+$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
+       baseEasings[ name ] = function( p ) {
+               return Math.pow( p, i + 2 );
+       };
+});
+
+$.extend( baseEasings, {
+       Sine: function( p ) {
+               return 1 - Math.cos( p * Math.PI / 2 );
+       },
+       Circ: function( p ) {
+               return 1 - Math.sqrt( 1 - p * p );
+       },
+       Elastic: function( p ) {
+               return p === 0 || p === 1 ? p :
+                       -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
+       },
+       Back: function( p ) {
+               return p * p * ( 3 * p - 2 );
+       },
+       Bounce: function( p ) {
+               var pow2,
+                       bounce = 4;
+
+               while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
+               return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
+       }
+});
+
+$.each( baseEasings, function( name, easeIn ) {
+       $.easing[ "easeIn" + name ] = easeIn;
+       $.easing[ "easeOut" + name ] = function( p ) {
+               return 1 - easeIn( 1 - p );
+       };
+       $.easing[ "easeInOut" + name ] = function( p ) {
+               return p < 0.5 ?
+                       easeIn( p * 2 ) / 2 :
+                       1 - easeIn( p * -2 + 2 ) / 2;
+       };
+});
+
+})();
+
+var effect = $.effects;
+
+
+/*!
+ * jQuery UI Effects Blind 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/blind-effect/
+ */
+
+
+var effectBlind = $.effects.effect.blind = function( o, done ) {
+       // Create element
+       var el = $( this ),
+               rvertical = /up|down|vertical/,
+               rpositivemotion = /up|left|vertical|horizontal/,
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               direction = o.direction || "up",
+               vertical = rvertical.test( direction ),
+               ref = vertical ? "height" : "width",
+               ref2 = vertical ? "top" : "left",
+               motion = rpositivemotion.test( direction ),
+               animation = {},
+               show = mode === "show",
+               wrapper, distance, margin;
+
+       // if already wrapped, the wrapper's properties are my property. #6245
+       if ( el.parent().is( ".ui-effects-wrapper" ) ) {
+               $.effects.save( el.parent(), props );
+       } else {
+               $.effects.save( el, props );
+       }
+       el.show();
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+
+       distance = wrapper[ ref ]();
+       margin = parseFloat( wrapper.css( ref2 ) ) || 0;
+
+       animation[ ref ] = show ? distance : 0;
+       if ( !motion ) {
+               el
+                       .css( vertical ? "bottom" : "right", 0 )
+                       .css( vertical ? "top" : "left", "auto" )
+                       .css({ position: "absolute" });
+
+               animation[ ref2 ] = show ? margin : distance + margin;
+       }
+
+       // start at 0 if we are showing
+       if ( show ) {
+               wrapper.css( ref, 0 );
+               if ( !motion ) {
+                       wrapper.css( ref2, margin + distance );
+               }
+       }
+
+       // Animate
+       wrapper.animate( animation, {
+               duration: o.duration,
+               easing: o.easing,
+               queue: false,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Bounce 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/bounce-effect/
+ */
+
+
+var effectBounce = $.effects.effect.bounce = function( o, done ) {
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+
+               // defaults:
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               hide = mode === "hide",
+               show = mode === "show",
+               direction = o.direction || "up",
+               distance = o.distance,
+               times = o.times || 5,
+
+               // number of internal animations
+               anims = times * 2 + ( show || hide ? 1 : 0 ),
+               speed = o.duration / anims,
+               easing = o.easing,
+
+               // utility:
+               ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+               motion = ( direction === "up" || direction === "left" ),
+               i,
+               upAnim,
+               downAnim,
+
+               // we will need to re-assemble the queue to stack our animations in place
+               queue = el.queue(),
+               queuelen = queue.length;
+
+       // Avoid touching opacity to prevent clearType and PNG issues in IE
+       if ( show || hide ) {
+               props.push( "opacity" );
+       }
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el ); // Create Wrapper
+
+       // default distance for the BIGGEST bounce is the outer Distance / 3
+       if ( !distance ) {
+               distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
+       }
+
+       if ( show ) {
+               downAnim = { opacity: 1 };
+               downAnim[ ref ] = 0;
+
+               // if we are showing, force opacity 0 and set the initial position
+               // then do the "first" animation
+               el.css( "opacity", 0 )
+                       .css( ref, motion ? -distance * 2 : distance * 2 )
+                       .animate( downAnim, speed, easing );
+       }
+
+       // start at the smallest distance if we are hiding
+       if ( hide ) {
+               distance = distance / Math.pow( 2, times - 1 );
+       }
+
+       downAnim = {};
+       downAnim[ ref ] = 0;
+       // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
+       for ( i = 0; i < times; i++ ) {
+               upAnim = {};
+               upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+               el.animate( upAnim, speed, easing )
+                       .animate( downAnim, speed, easing );
+
+               distance = hide ? distance * 2 : distance / 2;
+       }
+
+       // Last Bounce when Hiding
+       if ( hide ) {
+               upAnim = { opacity: 0 };
+               upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+               el.animate( upAnim, speed, easing );
+       }
+
+       el.queue(function() {
+               if ( hide ) {
+                       el.hide();
+               }
+               $.effects.restore( el, props );
+               $.effects.removeWrapper( el );
+               done();
+       });
+
+       // inject all the animations we just queued to be first in line (after "inprogress")
+       if ( queuelen > 1) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       el.dequeue();
+
+};
+
+
+/*!
+ * jQuery UI Effects Clip 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/clip-effect/
+ */
+
+
+var effectClip = $.effects.effect.clip = function( o, done ) {
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               direction = o.direction || "vertical",
+               vert = direction === "vertical",
+               size = vert ? "height" : "width",
+               position = vert ? "top" : "left",
+               animation = {},
+               wrapper, animate, distance;
+
+       // Save & Show
+       $.effects.save( el, props );
+       el.show();
+
+       // Create Wrapper
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+       animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
+       distance = animate[ size ]();
+
+       // Shift
+       if ( show ) {
+               animate.css( size, 0 );
+               animate.css( position, distance / 2 );
+       }
+
+       // Create Animation Object:
+       animation[ size ] = show ? distance : 0;
+       animation[ position ] = show ? 0 : distance / 2;
+
+       // Animate
+       animate.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( !show ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+
+};
+
+
+/*!
+ * jQuery UI Effects Drop 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/drop-effect/
+ */
+
+
+var effectDrop = $.effects.effect.drop = function( o, done ) {
+
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               direction = o.direction || "left",
+               ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+               motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
+               animation = {
+                       opacity: show ? 1 : 0
+               },
+               distance;
+
+       // Adjust
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+
+       distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
+
+       if ( show ) {
+               el
+                       .css( "opacity", 0 )
+                       .css( ref, motion === "pos" ? -distance : distance );
+       }
+
+       // Animation
+       animation[ ref ] = ( show ?
+               ( motion === "pos" ? "+=" : "-=" ) :
+               ( motion === "pos" ? "-=" : "+=" ) ) +
+               distance;
+
+       // Animate
+       el.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Explode 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/explode-effect/
+ */
+
+
+var effectExplode = $.effects.effect.explode = function( o, done ) {
+
+       var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
+               cells = rows,
+               el = $( this ),
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+
+               // show and then visibility:hidden the element before calculating offset
+               offset = el.show().css( "visibility", "hidden" ).offset(),
+
+               // width and height of a piece
+               width = Math.ceil( el.outerWidth() / cells ),
+               height = Math.ceil( el.outerHeight() / rows ),
+               pieces = [],
+
+               // loop
+               i, j, left, top, mx, my;
+
+       // children animate complete:
+       function childComplete() {
+               pieces.push( this );
+               if ( pieces.length === rows * cells ) {
+                       animComplete();
+               }
+       }
+
+       // clone the element for each row and cell.
+       for ( i = 0; i < rows ; i++ ) { // ===>
+               top = offset.top + i * height;
+               my = i - ( rows - 1 ) / 2 ;
+
+               for ( j = 0; j < cells ; j++ ) { // |||
+                       left = offset.left + j * width;
+                       mx = j - ( cells - 1 ) / 2 ;
+
+                       // Create a clone of the now hidden main element that will be absolute positioned
+                       // within a wrapper div off the -left and -top equal to size of our pieces
+                       el
+                               .clone()
+                               .appendTo( "body" )
+                               .wrap( "<div></div>" )
+                               .css({
+                                       position: "absolute",
+                                       visibility: "visible",
+                                       left: -j * width,
+                                       top: -i * height
+                               })
+
+                       // select the wrapper - make it overflow: hidden and absolute positioned based on
+                       // where the original was located +left and +top equal to the size of pieces
+                               .parent()
+                               .addClass( "ui-effects-explode" )
+                               .css({
+                                       position: "absolute",
+                                       overflow: "hidden",
+                                       width: width,
+                                       height: height,
+                                       left: left + ( show ? mx * width : 0 ),
+                                       top: top + ( show ? my * height : 0 ),
+                                       opacity: show ? 0 : 1
+                               }).animate({
+                                       left: left + ( show ? 0 : mx * width ),
+                                       top: top + ( show ? 0 : my * height ),
+                                       opacity: show ? 1 : 0
+                               }, o.duration || 500, o.easing, childComplete );
+               }
+       }
+
+       function animComplete() {
+               el.css({
+                       visibility: "visible"
+               });
+               $( pieces ).remove();
+               if ( !show ) {
+                       el.hide();
+               }
+               done();
+       }
+};
+
+
+/*!
+ * jQuery UI Effects Fade 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/fade-effect/
+ */
+
+
+var effectFade = $.effects.effect.fade = function( o, done ) {
+       var el = $( this ),
+               mode = $.effects.setMode( el, o.mode || "toggle" );
+
+       el.animate({
+               opacity: mode
+       }, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: done
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Fold 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/fold-effect/
+ */
+
+
+var effectFold = $.effects.effect.fold = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               hide = mode === "hide",
+               size = o.size || 15,
+               percent = /([0-9]+)%/.exec( size ),
+               horizFirst = !!o.horizFirst,
+               widthFirst = show !== horizFirst,
+               ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
+               duration = o.duration / 2,
+               wrapper, distance,
+               animation1 = {},
+               animation2 = {};
+
+       $.effects.save( el, props );
+       el.show();
+
+       // Create Wrapper
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+       distance = widthFirst ?
+               [ wrapper.width(), wrapper.height() ] :
+               [ wrapper.height(), wrapper.width() ];
+
+       if ( percent ) {
+               size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
+       }
+       if ( show ) {
+               wrapper.css( horizFirst ? {
+                       height: 0,
+                       width: size
+               } : {
+                       height: size,
+                       width: 0
+               });
+       }
+
+       // Animation
+       animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
+       animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
+
+       // Animate
+       wrapper
+               .animate( animation1, duration, o.easing )
+               .animate( animation2, duration, o.easing, function() {
+                       if ( hide ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               });
+
+};
+
+
+/*!
+ * jQuery UI Effects Highlight 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/highlight-effect/
+ */
+
+
+var effectHighlight = $.effects.effect.highlight = function( o, done ) {
+       var elem = $( this ),
+               props = [ "backgroundImage", "backgroundColor", "opacity" ],
+               mode = $.effects.setMode( elem, o.mode || "show" ),
+               animation = {
+                       backgroundColor: elem.css( "backgroundColor" )
+               };
+
+       if (mode === "hide") {
+               animation.opacity = 0;
+       }
+
+       $.effects.save( elem, props );
+
+       elem
+               .show()
+               .css({
+                       backgroundImage: "none",
+                       backgroundColor: o.color || "#ffff99"
+               })
+               .animate( animation, {
+                       queue: false,
+                       duration: o.duration,
+                       easing: o.easing,
+                       complete: function() {
+                               if ( mode === "hide" ) {
+                                       elem.hide();
+                               }
+                               $.effects.restore( elem, props );
+                               done();
+                       }
+               });
+};
+
+
+/*!
+ * jQuery UI Effects Size 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/size-effect/
+ */
+
+
+var effectSize = $.effects.effect.size = function( o, done ) {
+
+       // Create element
+       var original, baseline, factor,
+               el = $( this ),
+               props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
+
+               // Always restore
+               props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
+
+               // Copy for children
+               props2 = [ "width", "height", "overflow" ],
+               cProps = [ "fontSize" ],
+               vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
+               hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
+
+               // Set options
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               restore = o.restore || mode !== "effect",
+               scale = o.scale || "both",
+               origin = o.origin || [ "middle", "center" ],
+               position = el.css( "position" ),
+               props = restore ? props0 : props1,
+               zero = {
+                       height: 0,
+                       width: 0,
+                       outerHeight: 0,
+                       outerWidth: 0
+               };
+
+       if ( mode === "show" ) {
+               el.show();
+       }
+       original = {
+               height: el.height(),
+               width: el.width(),
+               outerHeight: el.outerHeight(),
+               outerWidth: el.outerWidth()
+       };
+
+       if ( o.mode === "toggle" && mode === "show" ) {
+               el.from = o.to || zero;
+               el.to = o.from || original;
+       } else {
+               el.from = o.from || ( mode === "show" ? zero : original );
+               el.to = o.to || ( mode === "hide" ? zero : original );
+       }
+
+       // Set scaling factor
+       factor = {
+               from: {
+                       y: el.from.height / original.height,
+                       x: el.from.width / original.width
+               },
+               to: {
+                       y: el.to.height / original.height,
+                       x: el.to.width / original.width
+               }
+       };
+
+       // Scale the css box
+       if ( scale === "box" || scale === "both" ) {
+
+               // Vertical props scaling
+               if ( factor.from.y !== factor.to.y ) {
+                       props = props.concat( vProps );
+                       el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
+                       el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
+               }
+
+               // Horizontal props scaling
+               if ( factor.from.x !== factor.to.x ) {
+                       props = props.concat( hProps );
+                       el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
+                       el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
+               }
+       }
+
+       // Scale the content
+       if ( scale === "content" || scale === "both" ) {
+
+               // Vertical props scaling
+               if ( factor.from.y !== factor.to.y ) {
+                       props = props.concat( cProps ).concat( props2 );
+                       el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
+                       el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
+               }
+       }
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+       el.css( "overflow", "hidden" ).css( el.from );
+
+       // Adjust
+       if (origin) { // Calculate baseline shifts
+               baseline = $.effects.getBaseline( origin, original );
+               el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
+               el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
+               el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
+               el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
+       }
+       el.css( el.from ); // set top & left
+
+       // Animate
+       if ( scale === "content" || scale === "both" ) { // Scale the children
+
+               // Add margins/font-size
+               vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
+               hProps = hProps.concat([ "marginLeft", "marginRight" ]);
+               props2 = props0.concat(vProps).concat(hProps);
+
+               el.find( "*[width]" ).each( function() {
+                       var child = $( this ),
+                               c_original = {
+                                       height: child.height(),
+                                       width: child.width(),
+                                       outerHeight: child.outerHeight(),
+                                       outerWidth: child.outerWidth()
+                               };
+                       if (restore) {
+                               $.effects.save(child, props2);
+                       }
+
+                       child.from = {
+                               height: c_original.height * factor.from.y,
+                               width: c_original.width * factor.from.x,
+                               outerHeight: c_original.outerHeight * factor.from.y,
+                               outerWidth: c_original.outerWidth * factor.from.x
+                       };
+                       child.to = {
+                               height: c_original.height * factor.to.y,
+                               width: c_original.width * factor.to.x,
+                               outerHeight: c_original.height * factor.to.y,
+                               outerWidth: c_original.width * factor.to.x
+                       };
+
+                       // Vertical props scaling
+                       if ( factor.from.y !== factor.to.y ) {
+                               child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
+                               child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
+                       }
+
+                       // Horizontal props scaling
+                       if ( factor.from.x !== factor.to.x ) {
+                               child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
+                               child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
+                       }
+
+                       // Animate children
+                       child.css( child.from );
+                       child.animate( child.to, o.duration, o.easing, function() {
+
+                               // Restore children
+                               if ( restore ) {
+                                       $.effects.restore( child, props2 );
+                               }
+                       });
+               });
+       }
+
+       // Animate
+       el.animate( el.to, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( el.to.opacity === 0 ) {
+                               el.css( "opacity", el.from.opacity );
+                       }
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       if ( !restore ) {
+
+                               // we need to calculate our new positioning based on the scaling
+                               if ( position === "static" ) {
+                                       el.css({
+                                               position: "relative",
+                                               top: el.to.top,
+                                               left: el.to.left
+                                       });
+                               } else {
+                                       $.each([ "top", "left" ], function( idx, pos ) {
+                                               el.css( pos, function( _, str ) {
+                                                       var val = parseInt( str, 10 ),
+                                                               toRef = idx ? el.to.left : el.to.top;
+
+                                                       // if original was "auto", recalculate the new value from wrapper
+                                                       if ( str === "auto" ) {
+                                                               return toRef + "px";
+                                                       }
+
+                                                       return val + toRef + "px";
+                                               });
+                                       });
+                               }
+                       }
+
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+
+};
+
+
+/*!
+ * jQuery UI Effects Scale 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/scale-effect/
+ */
+
+
+var effectScale = $.effects.effect.scale = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               options = $.extend( true, {}, o ),
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               percent = parseInt( o.percent, 10 ) ||
+                       ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
+               direction = o.direction || "both",
+               origin = o.origin,
+               original = {
+                       height: el.height(),
+                       width: el.width(),
+                       outerHeight: el.outerHeight(),
+                       outerWidth: el.outerWidth()
+               },
+               factor = {
+                       y: direction !== "horizontal" ? (percent / 100) : 1,
+                       x: direction !== "vertical" ? (percent / 100) : 1
+               };
+
+       // We are going to pass this effect to the size effect:
+       options.effect = "size";
+       options.queue = false;
+       options.complete = done;
+
+       // Set default origin and restore for show/hide
+       if ( mode !== "effect" ) {
+               options.origin = origin || [ "middle", "center" ];
+               options.restore = true;
+       }
+
+       options.from = o.from || ( mode === "show" ? {
+               height: 0,
+               width: 0,
+               outerHeight: 0,
+               outerWidth: 0
+       } : original );
+       options.to = {
+               height: original.height * factor.y,
+               width: original.width * factor.x,
+               outerHeight: original.outerHeight * factor.y,
+               outerWidth: original.outerWidth * factor.x
+       };
+
+       // Fade option to support puff
+       if ( options.fade ) {
+               if ( mode === "show" ) {
+                       options.from.opacity = 0;
+                       options.to.opacity = 1;
+               }
+               if ( mode === "hide" ) {
+                       options.from.opacity = 1;
+                       options.to.opacity = 0;
+               }
+       }
+
+       // Animate
+       el.effect( options );
+
+};
+
+
+/*!
+ * jQuery UI Effects Puff 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/puff-effect/
+ */
+
+
+var effectPuff = $.effects.effect.puff = function( o, done ) {
+       var elem = $( this ),
+               mode = $.effects.setMode( elem, o.mode || "hide" ),
+               hide = mode === "hide",
+               percent = parseInt( o.percent, 10 ) || 150,
+               factor = percent / 100,
+               original = {
+                       height: elem.height(),
+                       width: elem.width(),
+                       outerHeight: elem.outerHeight(),
+                       outerWidth: elem.outerWidth()
+               };
+
+       $.extend( o, {
+               effect: "scale",
+               queue: false,
+               fade: true,
+               mode: mode,
+               complete: done,
+               percent: hide ? percent : 100,
+               from: hide ?
+                       original :
+                       {
+                               height: original.height * factor,
+                               width: original.width * factor,
+                               outerHeight: original.outerHeight * factor,
+                               outerWidth: original.outerWidth * factor
+                       }
+       });
+
+       elem.effect( o );
+};
+
+
+/*!
+ * jQuery UI Effects Pulsate 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/pulsate-effect/
+ */
+
+
+var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
+       var elem = $( this ),
+               mode = $.effects.setMode( elem, o.mode || "show" ),
+               show = mode === "show",
+               hide = mode === "hide",
+               showhide = ( show || mode === "hide" ),
+
+               // showing or hiding leaves of the "last" animation
+               anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
+               duration = o.duration / anims,
+               animateTo = 0,
+               queue = elem.queue(),
+               queuelen = queue.length,
+               i;
+
+       if ( show || !elem.is(":visible")) {
+               elem.css( "opacity", 0 ).show();
+               animateTo = 1;
+       }
+
+       // anims - 1 opacity "toggles"
+       for ( i = 1; i < anims; i++ ) {
+               elem.animate({
+                       opacity: animateTo
+               }, duration, o.easing );
+               animateTo = 1 - animateTo;
+       }
+
+       elem.animate({
+               opacity: animateTo
+       }, duration, o.easing);
+
+       elem.queue(function() {
+               if ( hide ) {
+                       elem.hide();
+               }
+               done();
+       });
+
+       // We just queued up "anims" animations, we need to put them next in the queue
+       if ( queuelen > 1 ) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       elem.dequeue();
+};
+
+
+/*!
+ * jQuery UI Effects Shake 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/shake-effect/
+ */
+
+
+var effectShake = $.effects.effect.shake = function( o, done ) {
+
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               direction = o.direction || "left",
+               distance = o.distance || 20,
+               times = o.times || 3,
+               anims = times * 2 + 1,
+               speed = Math.round( o.duration / anims ),
+               ref = (direction === "up" || direction === "down") ? "top" : "left",
+               positiveMotion = (direction === "up" || direction === "left"),
+               animation = {},
+               animation1 = {},
+               animation2 = {},
+               i,
+
+               // we will need to re-assemble the queue to stack our animations in place
+               queue = el.queue(),
+               queuelen = queue.length;
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+
+       // Animation
+       animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
+       animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
+       animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
+
+       // Animate
+       el.animate( animation, speed, o.easing );
+
+       // Shakes
+       for ( i = 1; i < times; i++ ) {
+               el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
+       }
+       el
+               .animate( animation1, speed, o.easing )
+               .animate( animation, speed / 2, o.easing )
+               .queue(function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               });
+
+       // inject all the animations we just queued to be first in line (after "inprogress")
+       if ( queuelen > 1) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       el.dequeue();
+
+};
+
+
+/*!
+ * jQuery UI Effects Slide 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/slide-effect/
+ */
+
+
+var effectSlide = $.effects.effect.slide = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
+               mode = $.effects.setMode( el, o.mode || "show" ),
+               show = mode === "show",
+               direction = o.direction || "left",
+               ref = (direction === "up" || direction === "down") ? "top" : "left",
+               positiveMotion = (direction === "up" || direction === "left"),
+               distance,
+               animation = {};
+
+       // Adjust
+       $.effects.save( el, props );
+       el.show();
+       distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
+
+       $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+
+       if ( show ) {
+               el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
+       }
+
+       // Animation
+       animation[ ref ] = ( show ?
+               ( positiveMotion ? "+=" : "-=") :
+               ( positiveMotion ? "-=" : "+=")) +
+               distance;
+
+       // Animate
+       el.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Transfer 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/transfer-effect/
+ */
+
+
+var effectTransfer = $.effects.effect.transfer = function( o, done ) {
+       var elem = $( this ),
+               target = $( o.to ),
+               targetFixed = target.css( "position" ) === "fixed",
+               body = $("body"),
+               fixTop = targetFixed ? body.scrollTop() : 0,
+               fixLeft = targetFixed ? body.scrollLeft() : 0,
+               endPosition = target.offset(),
+               animation = {
+                       top: endPosition.top - fixTop,
+                       left: endPosition.left - fixLeft,
+                       height: target.innerHeight(),
+                       width: target.innerWidth()
+               },
+               startPosition = elem.offset(),
+               transfer = $( "<div class='ui-effects-transfer'></div>" )
+                       .appendTo( document.body )
+                       .addClass( o.className )
+                       .css({
+                               top: startPosition.top - fixTop,
+                               left: startPosition.left - fixLeft,
+                               height: elem.innerHeight(),
+                               width: elem.innerWidth(),
+                               position: targetFixed ? "fixed" : "absolute"
+                       })
+                       .animate( animation, o.duration, o.easing, function() {
+                               transfer.remove();
+                               done();
+                       });
+};
+
+
+
+}));
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.css
new file mode 100644 (file)
index 0000000..640dc1e
--- /dev/null
@@ -0,0 +1,7 @@
+/*! jQuery UI - v1.11.3 - 2015-03-03
+* http://jqueryui.com
+* Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.min.js
new file mode 100644 (file)
index 0000000..0299692
--- /dev/null
@@ -0,0 +1,13 @@
+/*! jQuery UI - v1.11.3 - 2015-03-01
+* http://jqueryui.com
+* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}function s(e){for(var t,i;e.length&&e[0]!==document;){if(t=e.css("position"),("absolute"===t||"relative"===t||"fixed"===t)&&(i=parseInt(e.css("zIndex"),10),!isNaN(i)&&0!==i))return i;e=e.parent()}return 0}function n(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.regional.en=e.extend(!0,{},this.regional[""]),this.regional["en-US"]=e.extend(!0,{},this.regional.en),this.dpDiv=a(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",o)}function o(){e.datepicker._isDisabledDatepicker(v.inline?v.dpDiv.parent()[0]:v.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))}function r(t,i){e.extend(t,i);for(var s in i)null==i[s]&&(t[s]=i[s]);return t}function h(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var l=0,u=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,n=u.call(arguments,1),a=0,o=n.length;o>a;a++)for(i in n[a])s=n[a][i],n[a].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(n){var a="string"==typeof n,o=u.call(arguments,1),r=this;return a?this.each(function(){var i,a=e.data(this,s);return"instance"===n?(r=a,!1):a?e.isFunction(a[n])&&"_"!==n.charAt(0)?(i=a[n].apply(a,o),i!==a&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+n+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+n+"'")}):(o.length&&(n=e.widget.extend.apply(null,[n].concat(o))),this.each(function(){var t=e.data(this,s);t?(t.option(n||{}),t._init&&t._init()):e.data(this,s,new i(n,this))})),r}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=l++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var d=!1;e(document).mouseup(function(){d=!1}),e.widget("ui.mouse",{version:"1.11.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!d){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),d=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),d=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,i,s=e("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=s.children()[0];return e("body").append(s),t=a.offsetWidth,s.css("overflow","scroll"),i=a.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),n=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),n="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,a="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:a?e.position.scrollbarWidth():0,height:n?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:n,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s||n?i.width():i.outerWidth(),height:s||n?i.height():i.outerHeight()}}},e.fn.position=function(n){if(!n||!n.of)return f.apply(this,arguments);n=e.extend({},n);var p,m,g,v,y,b,_=e(n.of),x=e.position.getWithinInfo(n.within),w=e.position.getScrollInfo(x),k=(n.collision||"flip").split(" "),T={};return b=s(_),_[0].preventDefault&&(n.at="left top"),m=b.width,g=b.height,v=b.offset,y=e.extend({},v),e.each(["my","at"],function(){var e,t,i=(n[this]||"").split(" ");1===i.length&&(i=l.test(i[0])?i.concat(["center"]):u.test(i[0])?["center"].concat(i):["center","center"]),i[0]=l.test(i[0])?i[0]:"center",i[1]=u.test(i[1])?i[1]:"center",e=d.exec(i[0]),t=d.exec(i[1]),T[this]=[e?e[0]:0,t?t[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===n.at[0]?y.left+=m:"center"===n.at[0]&&(y.left+=m/2),"bottom"===n.at[1]?y.top+=g:"center"===n.at[1]&&(y.top+=g/2),p=t(T.at,m,g),y.left+=p[0],y.top+=p[1],this.each(function(){var s,l,u=e(this),d=u.outerWidth(),c=u.outerHeight(),f=i(this,"marginLeft"),b=i(this,"marginTop"),D=d+f+i(this,"marginRight")+w.width,S=c+b+i(this,"marginBottom")+w.height,M=e.extend({},y),C=t(T.my,u.outerWidth(),u.outerHeight());"right"===n.my[0]?M.left-=d:"center"===n.my[0]&&(M.left-=d/2),"bottom"===n.my[1]?M.top-=c:"center"===n.my[1]&&(M.top-=c/2),M.left+=C[0],M.top+=C[1],a||(M.left=h(M.left),M.top=h(M.top)),s={marginLeft:f,marginTop:b},e.each(["left","top"],function(t,i){e.ui.position[k[t]]&&e.ui.position[k[t]][i](M,{targetWidth:m,targetHeight:g,elemWidth:d,elemHeight:c,collisionPosition:s,collisionWidth:D,collisionHeight:S,offset:[p[0]+C[0],p[1]+C[1]],my:n.my,at:n.at,within:x,elem:u})}),n.using&&(l=function(e){var t=v.left-M.left,i=t+m-d,s=v.top-M.top,a=s+g-c,h={target:{element:_,left:v.left,top:v.top,width:m,height:g},element:{element:u,left:M.left,top:M.top,width:d,height:c},horizontal:0>i?"left":t>0?"right":"center",vertical:0>a?"top":s>0?"bottom":"middle"};d>m&&m>r(t+i)&&(h.horizontal="center"),c>g&&g>r(s+a)&&(h.vertical="middle"),h.important=o(r(t),r(i))>o(r(s),r(a))?"horizontal":"vertical",n.using.call(this,e,h)}),u.offset(e.extend(M,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=e.left-t.collisionPosition.marginLeft,h=n-r,l=r+t.collisionWidth-a-n;t.collisionWidth>a?h>0&&0>=l?(i=e.left+h+t.collisionWidth-a-n,e.left+=h-i):e.left=l>0&&0>=h?n:h>l?n+a-t.collisionWidth:n:h>0?e.left+=h:l>0?e.left-=l:e.left=o(e.left-r,e.left)},top:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollTop:s.offset.top,a=t.within.height,r=e.top-t.collisionPosition.marginTop,h=n-r,l=r+t.collisionHeight-a-n;t.collisionHeight>a?h>0&&0>=l?(i=e.top+h+t.collisionHeight-a-n,e.top+=h-i):e.top=l>0&&0>=h?n:h>l?n+a-t.collisionHeight:n:h>0?e.top+=h:l>0?e.top-=l:e.top=o(e.top-r,e.top)}},flip:{left:function(e,t){var i,s,n=t.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-o-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-o-a,(0>i||r(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>r(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,n=t.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-o-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-o-a,(0>s||r(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,(i>0||d>r(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,n,o,r=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)t.style[o]=s[o];t.appendChild(h),i=r||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",n=e(h).offset().left,a=n>10&&11>n,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.draggable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(t){var i=this.options;return this._blurActiveElement(t),this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=e(this);return e("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var i=this.document[0];if(this.handleElement.is(t.target))try{i.activeElement&&"body"!==i.activeElement.nodeName.toLowerCase()&&e(i.activeElement).blur()}catch(s){}},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===e(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._normalizeRightBottom(),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(e){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:e.pageX-this.offset.left,top:e.pageY-this.offset.top}},_mouseDrag:function(t,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper),n=s?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options,a=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,e(a).width()-this.helperProportions.width-this.margins.left,(e(a).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=e(n.containment),s=i[0],s&&(t=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(e,t){t||(t=this.position);var i="absolute"===e?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:t.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(e,t){var i,s,n,a,o=this.options,r=this._isRootNode(this.scrollParent[0]),h=e.pageX,l=e.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,h=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a),"y"===o.axis&&(h=this.originalPageX),"x"===o.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}
+},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i,s){var n=e.extend({},i,{item:s.element});s.sortables=[],e(s.options.connectToSortable).each(function(){var i=e(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i,s){var n=e.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,e.each(s.sortables,function(){var e=this;e.isOver?(e.isOver=0,s.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,n))})},drag:function(t,i,s){e.each(s.sortables,function(){var n=!1,a=this;a.positionAbs=s.positionAbs,a.helperProportions=s.helperProportions,a.offset.click=s.offset.click,a._intersectsWith(a.containerCache)&&(n=!0,e.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==a&&this._intersectsWith(this.containerCache)&&e.contains(a.element[0],this.element[0])&&(n=!1),n})),n?(a.isOver||(a.isOver=1,a.currentItem=i.helper.appendTo(a.element).data("ui-sortable-item",!0),a.options._helper=a.options.helper,a.options.helper=function(){return i.helper[0]},t.target=a.currentItem[0],a._mouseCapture(t,!0),a._mouseStart(t,!0,!0),a.offset.click.top=s.offset.click.top,a.offset.click.left=s.offset.click.left,a.offset.parent.left-=s.offset.parent.left-a.offset.parent.left,a.offset.parent.top-=s.offset.parent.top-a.offset.parent.top,s._trigger("toSortable",t),s.dropped=a.element,e.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,a.fromOutside=s),a.currentItem&&(a._mouseDrag(t),i.position=a.position)):a.isOver&&(a.isOver=0,a.cancelHelperRemoval=!0,a.options._revert=a.options.revert,a.options.revert=!1,a._trigger("out",t,a._uiHash(a)),a._mouseStop(t,!0),a.options.revert=a.options._revert,a.options.helper=a.options._helper,a.placeholder&&a.placeholder.remove(),s._refreshOffsets(t),i.position=s._generatePosition(t,!0),s._trigger("fromSortable",t),s.dropped=!1,e.each(s.sortables,function(){this.refreshPositions()}))})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,i,s){var n=e("body"),a=s.options;n.css("cursor")&&(a._cursor=n.css("cursor")),n.css("cursor",a.cursor)},stop:function(t,i,s){var n=s.options;n._cursor&&e("body").css("cursor",n._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("opacity")&&(a._opacity=n.css("opacity")),n.css("opacity",a.opacity)},stop:function(t,i,s){var n=s.options;n._opacity&&e(i.helper).css("opacity",n._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,i,s){var n=s.options,a=!1,o=s.scrollParentNotHidden[0],r=s.document[0];o!==r&&"HTML"!==o.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+o.offsetHeight-t.pageY<n.scrollSensitivity?o.scrollTop=a=o.scrollTop+n.scrollSpeed:t.pageY-s.overflowOffset.top<n.scrollSensitivity&&(o.scrollTop=a=o.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+o.offsetWidth-t.pageX<n.scrollSensitivity?o.scrollLeft=a=o.scrollLeft+n.scrollSpeed:t.pageX-s.overflowOffset.left<n.scrollSensitivity&&(o.scrollLeft=a=o.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(t.pageY-e(r).scrollTop()<n.scrollSensitivity?a=e(r).scrollTop(e(r).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(r).scrollTop())<n.scrollSensitivity&&(a=e(r).scrollTop(e(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(t.pageX-e(r).scrollLeft()<n.scrollSensitivity?a=e(r).scrollLeft(e(r).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(r).scrollLeft())<n.scrollSensitivity&&(a=e(r).scrollLeft(e(r).scrollLeft()+n.scrollSpeed)))),a!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(s,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,i,s){var n=s.options;s.snapElements=[],e(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var t=e(this),i=t.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:i.top,left:i.left})})},drag:function(t,i,s){var n,a,o,r,h,l,u,d,c,p,f=s.options,m=f.snapTolerance,g=i.offset.left,v=g+s.helperProportions.width,y=i.offset.top,b=y+s.helperProportions.height;for(c=s.snapElements.length-1;c>=0;c--)h=s.snapElements[c].left-s.margins.left,l=h+s.snapElements[c].width,u=s.snapElements[c].top-s.margins.top,d=u+s.snapElements[c].height,h-m>v||g>l+m||u-m>b||y>d+m||!e.contains(s.snapElements[c].item.ownerDocument,s.snapElements[c].item)?(s.snapElements[c].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(n=m>=Math.abs(u-b),a=m>=Math.abs(d-y),o=m>=Math.abs(h-v),r=m>=Math.abs(l-g),n&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||a||o||r,"outer"!==f.snapMode&&(n=m>=Math.abs(u-y),a=m>=Math.abs(d-b),o=m>=Math.abs(h-g),r=m>=Math.abs(l-v),n&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d-s.helperProportions.height,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[c].snapping&&(n||a||o||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=n||a||o||r||p)}}),e.ui.plugin.add("draggable","stack",{start:function(t,i,s){var n,a=s.options,o=e.makeArray(e(a.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});o.length&&(n=parseInt(e(o[0]).css("zIndex"),10)||0,e(o).each(function(t){e(this).css("zIndex",n+t)}),this.css("zIndex",n+o.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("zIndex")&&(a._zIndex=n.css("zIndex")),n.css("zIndex",a.zIndex)},stop:function(t,i,s){var n=s.options;n._zIndex&&e(i.helper).css("zIndex",n._zIndex)}}),e.ui.draggable,e.widget("ui.droppable",{version:"1.11.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(s)?s:function(e){return e.is(s)},this.proportions=function(){return arguments.length?(t=arguments[0],void 0):t?t:t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(t){e.ui.ddmanager.droppables[t]=e.ui.ddmanager.droppables[t]||[],e.ui.ddmanager.droppables[t].push(this)},_splice:function(e){for(var t=0;e.length>t;t++)e[t]===this&&e.splice(t,1)},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];this._splice(t),this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){if("accept"===t)this.accept=e.isFunction(i)?i:function(e){return e.is(i)};else if("scope"===t){var s=e.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(t,i)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=e(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(i,{offset:i.element.offset()}),i.options.tolerance,t)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(){function e(e,t,i){return e>=t&&t+i>e}return function(t,i,s,n){if(!i.offset)return!1;var a=(t.positionAbs||t.position.absolute).left+t.margins.left,o=(t.positionAbs||t.position.absolute).top+t.margins.top,r=a+t.helperProportions.width,h=o+t.helperProportions.height,l=i.offset.left,u=i.offset.top,d=l+i.proportions().width,c=u+i.proportions().height;switch(s){case"fit":return a>=l&&d>=r&&o>=u&&c>=h;case"intersect":return a+t.helperProportions.width/2>l&&d>r-t.helperProportions.width/2&&o+t.helperProportions.height/2>u&&c>h-t.helperProportions.height/2;case"pointer":return e(n.pageY,u,i.proportions().height)&&e(n.pageX,l,i.proportions().width);case"touch":return(o>=u&&c>=o||h>=u&&c>=h||u>o&&h>c)&&(a>=l&&d>=a||r>=l&&d>=r||l>a&&r>d);default:return!1}}}(),e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,n,a=e.ui.ddmanager.droppables[t.options.scope]||[],o=i?i.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||t&&!a[s].accept.call(a[s].element[0],t.currentItem||t.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions().height=0;continue e}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions({width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight}))}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=e.ui.intersect(t,this,this.options.tolerance,i),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return e(this).droppable("instance").options.scope===n}),a.length&&(s=e(a[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}},e.ui.droppable,e.widget("ui.resizable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(e){return parseInt(e,10)||0},_isNumber:function(e){return!isNaN(parseInt(e,10))},_hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return t[s]>0?!0:(t[s]=1,n=t[s]>0,t[s]=0,n)},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("<div class='ui-resizable-handle "+a+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=this.element.children(this.handles[i]).first().show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var i,s,n,a=this.options,o=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),a.containment&&(i+=e(a.containment).scrollLeft()||0,s+=e(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:o.width(),height:o.height()},this.originalSize=this._helper?{width:o.outerWidth(),height:o.outerHeight()}:{width:o.width(),height:o.height()},this.sizeDiff={width:o.outerWidth()-o.width(),height:o.outerHeight()-o.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===n?this.axis+"-resize":n),o.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var i,s,n=this.originalMousePosition,a=this.axis,o=t.pageX-n.left||0,r=t.pageY-n.top||0,h=this._change[a];return this._updatePrevProperties(),h?(i=h.apply(this,[t,o,r]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var e={};return this.position.top!==this.prevPosition.top&&(e.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(e.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(e.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(e.height=this.size.height+"px"),this.helper.css(e),e},_updateVirtualBoundaries:function(e){var t,i,s,n,a,o=this.options;a={minWidth:this._isNumber(o.minWidth)?o.minWidth:0,maxWidth:this._isNumber(o.maxWidth)?o.maxWidth:1/0,minHeight:this._isNumber(o.minHeight)?o.minHeight:0,maxHeight:this._isNumber(o.maxHeight)?o.maxHeight:1/0},(this._aspectRatio||e)&&(t=a.minHeight*this.aspectRatio,s=a.minWidth/this.aspectRatio,i=a.maxHeight*this.aspectRatio,n=a.maxWidth/this.aspectRatio,t>a.minWidth&&(a.minWidth=t),s>a.minHeight&&(a.minHeight=s),a.maxWidth>i&&(a.maxWidth=i),a.maxHeight>n&&(a.maxHeight=n)),this._vBoundaries=a},_updateCache:function(e){this.offset=this.helper.offset(),this._isNumber(e.left)&&(this.position.left=e.left),this._isNumber(e.top)&&(this.position.top=e.top),this._isNumber(e.height)&&(this.size.height=e.height),this._isNumber(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,i=this.size,s=this.axis;return this._isNumber(e.height)?e.width=e.height*this.aspectRatio:this._isNumber(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===s&&(e.left=t.left+(i.width-e.width),e.top=null),"nw"===s&&(e.top=t.top+(i.height-e.height),e.left=t.left+(i.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,i=this.axis,s=this._isNumber(e.width)&&t.maxWidth&&t.maxWidth<e.width,n=this._isNumber(e.height)&&t.maxHeight&&t.maxHeight<e.height,a=this._isNumber(e.width)&&t.minWidth&&t.minWidth>e.width,o=this._isNumber(e.height)&&t.minHeight&&t.minHeight>e.height,r=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,l=/sw|nw|w/.test(i),u=/nw|ne|n/.test(i);return a&&(e.width=t.minWidth),o&&(e.height=t.minHeight),s&&(e.width=t.maxWidth),n&&(e.height=t.maxHeight),a&&l&&(e.left=r-t.minWidth),s&&l&&(e.left=r-t.maxWidth),o&&u&&(e.top=h-t.minHeight),n&&u&&(e.top=h-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_getPaddingPlusBorderDimensions:function(e){for(var t=0,i=[],s=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],n=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];4>t;t++)i[t]=parseInt(s[t],10)||0,i[t]+=parseInt(n[t],10)||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e,t=0,i=this.helper||this.element;this._proportionallyResizeElements.length>t;t++)e=this._proportionallyResizeElements[t],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(e)),e.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,i,s,n,a,o,r,h=e(this).resizable("instance"),l=h.options,u=h.element,d=l.containment,c=d instanceof e?d.get(0):/parent/.test(d)?u.parent().get(0):d;c&&(h.containerElement=e(c),/document/.test(d)||d===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(c),i=[],e(["Top","Right","Left","Bottom"]).each(function(e,s){i[e]=h._num(t.css("padding"+s))}),h.containerOffset=t.offset(),h.containerPosition=t.position(),h.containerSize={height:t.innerHeight()-i[3],width:t.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,a=h.containerSize.width,o=h._hasScroll(c,"left")?c.scrollWidth:a,r=h._hasScroll(c)?c.scrollHeight:n,h.parentData={element:c,left:s.left,top:s.top,width:o,height:r}))},resize:function(t){var i,s,n,a,o=e(this).resizable("instance"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,d={top:0,left:0},c=o.containerElement,p=!0;c[0]!==document&&/static/.test(c.css("position"))&&(d=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-d.left),u&&(o.size.height=o.size.width/o.aspectRatio,p=!1),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio,p=!1),o.position.top=o._helper?h.top:0),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a?(o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top):(o.offset.left=o.element.offset().left,o.offset.top=o.element.offset().top),i=Math.abs(o.sizeDiff.width+(o._helper?o.offset.left-d.left:o.offset.left-h.left)),s=Math.abs(o.sizeDiff.height+(o._helper?o.offset.top-d.top:o.offset.top-h.top)),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio,p=!1)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio,p=!1)),p||(o.position.left=o.prevPosition.left,o.position.top=o.prevPosition.top,o.size.width=o.prevSize.width,o.size.height=o.prevSize.height)},stop:function(){var t=e(this).resizable("instance"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).resizable("instance"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(t,s){e(t).each(function(){var t=e(this),n=e(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var i=(n[t]||0)+(r[t]||0);i&&i>=0&&(a[t]=i||null)}),t.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):e.each(n.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t,i=e(this).resizable("instance"),s=i.options,n=i.size,a=i.originalSize,o=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,u=h[1]||1,d=Math.round((n.width-a.width)/l)*l,c=Math.round((n.height-a.height)/u)*u,p=a.width+d,f=a.height+c,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,v=s.minWidth&&s.minWidth>p,y=s.minHeight&&s.minHeight>f;s.grid=h,v&&(p+=l),y&&(f+=u),m&&(p-=l),g&&(f-=u),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=o.top-c):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=o.left-d):((0>=f-u||0>=p-l)&&(t=i._getPaddingPlusBorderDimensions(this)),f-u>0?(i.size.height=f,i.position.top=o.top-c):(f=u-t.height,i.size.height=f,i.position.top=o.top+a.height-f),p-l>0?(i.size.width=p,i.position.left=o.left-d):(p=l-t.width,i.size.width=p,i.position.left=o.left+a.width-p))}}),e.ui.resizable,e.widget("ui.selectable",e.ui.mouse,{version:"1.11.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;
+this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,n=e.data(this,"selectable-item");return n?(s=!t.metaKey&&!t.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",t,{selecting:n.element}):i._trigger("unselecting",t,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=t.pageX,h=t.pageY;return a>r&&(i=r,r=a,a=i),o>h&&(i=h,h=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:h-o}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||a>i.right||i.top>h||o>i.bottom):"fit"===n.tolerance&&(l=i.left>a&&r>i.right&&i.top>o&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===e.axis||this._isFloating(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,a.widgetName+"-item")===a?(s=e(this),!1):void 0}),e.data(t.target,a.widgetName+"-item")===a&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=e("<style>*{ cursor: "+o.cursor+" !important; }</style>").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<o.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+o.scrollSpeed:t.pageY-this.overflowOffset.top<o.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-o.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<o.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+o.scrollSpeed:t.pageX-this.overflowOffset.left<o.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-o.scrollSpeed)):(t.pageY-this.document.scrollTop()<o.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-o.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<o.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+o.scrollSpeed)),t.pageX-this.document.scrollLeft()<o.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-o.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<o.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+o.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>r&&h>s+l,c="y"===this.options.axis||t+u>a&&o>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return s?this.floating?a&&"right"===a||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(n=e(c[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(d.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=d.length-1;i>=0;i--)for(o=d[i][1],r=d[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?t.currentItem.children().each(function(){e("<td>&#160;</td>",t.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,d,c=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(c&&e.contains(this.containers[i].element[0],c.element[0]))continue;c=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=c.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",d=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[d]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[d]-h)&&(n=Math.abs(t[d]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.width():this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(a=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}}),e.widget("ui.accordion",{version:"1.11.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),e=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&(this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)),void 0)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,s=this.headers.length,n=this.headers.index(t.target),a=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(e(t.target).attr("tabIndex",-1),e(a).attr("tabIndex",0),a.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var e=this.headers,t=this.panels;this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.panels=this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide(),t&&(this._off(e.not(this.headers)),this._off(t.not(this.panels)))
+},_refresh:function(){var t,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var t=e(this),i=t.uniqueId().attr("id"),s=t.next(),n=s.uniqueId().attr("id");t.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(t=n.height(),this.element.siblings(":visible").each(function(){var i=e(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(t-=i.outerHeight(!0))}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n[0]===s[0],o=a&&i.collapsible,r=o?e():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:o?e():n,newPanel:r};t.preventDefault(),a&&!i.collapsible||this._trigger("beforeActivate",t,l)===!1||(i.active=o?!1:this.headers.index(n),this.active=a?e():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),a||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,s=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,t):(s.hide(),i.show(),this._toggleComplete(t)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(e(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(e,t,i){var s,n,a,o=this,r=0,h=e.length&&(!t.length||e.index()<t.index()),l=this.options.animate||{},u=h&&l.down||l,d=function(){o._toggleComplete(i)};return"number"==typeof u&&(a=u),"string"==typeof u&&(n=u),n=n||u.easing||l.easing,a=a||u.duration||l.duration,t.length?e.length?(s=e.show().outerHeight(),t.animate(this.hideProps,{duration:a,easing:n,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(this.showProps,{duration:a,easing:n,complete:d,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?r+=i.now:"content"!==o.options.heightStyle&&(i.now=Math.round(s-t.outerHeight()-r),r=0)}}),void 0):t.animate(this.hideProps,a,n,d):e.animate(this.showProps,a,n,d)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.widget("ui.menu",{version:"1.11.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(e){e.preventDefault()},"click .ui-menu-item":function(t){var i=e(t.target);!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&e(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){if(!this.previousFilter){var i=e(t.currentTarget);i.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(t,i)}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.find(this.options.items).eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){this._closeOnDocumentClick(e)&&this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){var i,s,n,a,o=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:o=!1,s=this.previousFilter||"",n=String.fromCharCode(t.keyCode),a=!1,clearTimeout(this.filterTimer),n===s?a=!0:n=s+n,i=this._filterMenuItems(n),i=a&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(t.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(t,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}o&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(e):this.select(e))},refresh:function(){var t,i,s=this,n=this.options.icons.submenu,a=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),a.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),i=t.parent(),s=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);i.attr("aria-haspopup","true").prepend(s),t.attr("aria-labelledby",i.attr("id"))}),t=a.add(this.element),i=t.find(this.options.items),i.not(".ui-menu-item").each(function(){var t=e(this);s._isDivider(t)&&t.addClass("ui-widget-content ui-menu-divider")}),i.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){"icons"===e&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},focus:function(e,t){var i,s;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&e&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,n=t.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=t.outerHeight(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active}))},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(t){return!e(t.target).closest(".ui-menu").length},_isDivider:function(e){return!/[^\-\u2014\u2013\s]/.test(e.text())},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[t]()),this.focus(i,s)},nextPage:function(t){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-n}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(t),void 0)},previousPage:function(t){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+n>0}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items).first())),void 0):(this.next(t),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,i)},_filterMenuItems:function(t){var i=t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(e.trim(e(this).text()))})}}),e.widget("ui.autocomplete",{version:"1.11.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,void 0;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),void 0):(this._searchTimeout(e),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(e),this._change(e),void 0)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:n})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&e.trim(s).length&&(this.liveRegion.children().hide(),e("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,n){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){n(e)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),i=this.menu.element.is(":visible"),s=e.altKey||e.ctrlKey||e.metaKey||e.shiftKey;(!t||t&&!i&&!s)&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):void 0},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var t=++this.requestIndex;return e.proxy(function(e){t===this.requestIndex&&this.__response(e),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").text(i.label).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[e](t),void 0):(this.search(null,t),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.children().hide(),e("<div>").text(i).appendTo(this.liveRegion))}}),e.ui.autocomplete;var c,p="ui-button ui-widget ui-state-default ui-corner-all",f="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",m=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},g=function(t){var i=t.name,s=t.form,n=e([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?e(s).find("[name='"+i+"'][type=radio]"):e("[name='"+i+"'][type=radio]",t.ownerDocument).filter(function(){return!this.form})),n};e.widget("ui.button",{version:"1.11.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,m),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,i=this.options,s="checkbox"===this.type||"radio"===this.type,n=s?"":"ui-state-active";null===i.label&&(i.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(p).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){i.disabled||this===c&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){i.disabled||e(this).removeClass(n)}).bind("click"+this.eventNamespace,function(e){i.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),s&&this.element.bind("change"+this.eventNamespace,function(){t.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return i.disabled?!1:void 0}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(i.disabled)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var s=t.element[0];g(s).not(s).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return i.disabled?!1:(e(this).addClass("ui-state-active"),c=this,t.document.one("mouseup",function(){c=null}),void 0)}).bind("mouseup"+this.eventNamespace,function(){return i.disabled?!1:(e(this).removeClass("ui-state-active"),void 0)}).bind("keydown"+this.eventNamespace,function(t){return i.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),void 0)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",i.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(p+" ui-state-active "+f).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),t&&("checkbox"===this.type||"radio"===this.type?this.buttonElement.removeClass("ui-state-focus"):this.buttonElement.removeClass("ui-state-focus ui-state-active")),void 0):(this._resetButton(),void 0)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?g(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),void 0;var t=this.buttonElement.removeClass(f),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,a=[];s.primary||s.secondary?(this.options.text&&a.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(a.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):a.push("ui-button-text-only"),t.addClass(a.join(" "))}}),e.widget("ui.buttonset",{version:"1.11.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction"),i=this.element.find(this.options.items),s=i.filter(":ui-button");i.not(":ui-button").button(),s.button("refresh"),this.buttons=i.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}}),e.ui.button,e.extend(e.ui,{datepicker:{version:"1.11.3"}});var v;e.extend(n.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return r(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var s,n,a;s=t.nodeName.toLowerCase(),n="div"===s||"span"===s,t.id||(this.uuid+=1,t.id="dp"+this.uuid),a=this._newInst(e(t),n),a.settings=e.extend({},i||{}),"input"===s?this._connectDatepicker(t,a):n&&this._inlineDatepicker(t,a)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?a(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var s=e(t);i.append=e([]),i.trigger=e([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,"datepicker",i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var s,n,a,o=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),o&&(i.append=e("<span class='"+this._appendClass+"'>"+o+"</span>"),t[r?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&t.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),a=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:a,alt:n,title:n}):e("<button type='button'></button>").addClass(this._triggerClass).html(a?e("<img/>").attr({src:a,alt:n,title:n}):n)),t[r?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,s,n,a=new Date(2009,11,20),o=this._get(e,"dateFormat");o.match(/[DM]/)&&(t=function(e){for(i=0,s=0,n=0;e.length>n;n++)e[n].length>i&&(i=e[n].length,s=n);return s},a.setMonth(t(this._get(e,o.match(/MM/)?"monthNames":"monthNamesShort"))),a.setDate(t(this._get(e,o.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())),e.input.attr("size",this._formatDate(e,a).length)}},_inlineDatepicker:function(t,i){var s=e(t);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),e.data(t,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,s,n,a){var o,h,l,u,d,c=this._dialogInst;return c||(this.uuid+=1,o="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+o+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),c=this._dialogInst=this._newInst(this._dialogInput,!1),c.settings={},e.data(this._dialogInput[0],"datepicker",c)),r(c.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(c,i):i,this._dialogInput.val(i),this._pos=a?a.length?a:[a.pageX,a.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+u,l/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),c.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],"datepicker",c),this
+},_destroyDatepicker:function(t){var i,s=e(t),n=e.data(t,"datepicker");s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),v===n&&(v=null))},_enableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,a.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,a.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(t,i,s){var n,a,o,h,l=this._getInst(t);return 2===arguments.length&&"string"==typeof i?"defaults"===i?e.extend({},e.datepicker._defaults):l?"all"===i?e.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),a=this._getDateDatepicker(t,!0),o=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),r(l.settings,n),null!==o&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,o)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(t):this._enableDatepicker(t)),this._attachments(e(t),l),this._autoSize(l),this._setDate(l,a),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,s,n,a=e.datepicker._getInst(t.target),o=!0,r=a.dpDiv.is(".ui-datepicker-rtl");if(a._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),o=!1;break;case 13:return n=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",a.dpDiv),n[0]&&e.datepicker._selectDay(t.target,a.selectedMonth,a.selectedYear,n[0]),i=e.datepicker._get(a,"onSelect"),i?(s=e.datepicker._formatDate(a),i.apply(a.input?a.input[0]:null,[s,a])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),o=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),o=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?1:-1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),o=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?-1:1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),o=t.ctrlKey||t.metaKey;break;default:o=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):o=!1;o&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(t){var i,s,n=e.datepicker._getInst(t.target);return e.datepicker._get(n,"constrainInput")?(i=e.datepicker._possibleChars(e.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==t.charCode?t.keyCode:t.charCode),t.ctrlKey||t.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(t){var i,s=e.datepicker._getInst(t.target);if(s.input.val()!==s.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,e.datepicker._getFormatConfig(s)),i&&(e.datepicker._setDateFromField(s),e.datepicker._updateAlternate(s),e.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,n,a,o,h,l,u;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),n=e.datepicker._get(i,"beforeShow"),a=n?n.apply(t,[t,i]):{},a!==!1&&(r(i.settings,a),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),o=!1,e(t).parents().each(function(){return o|="fixed"===e(this).css("position"),!o}),h={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),h=e.datepicker._checkOffset(i,h,o),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":o?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),i.inline||(l=e.datepicker._get(i,"showAnim"),u=e.datepicker._get(i,"duration"),i.dpDiv.css("z-index",s(e(t))+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[l]?i.dpDiv.show(l,e.datepicker._get(i,"showOptions"),u):i.dpDiv[l||"show"](l?u:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,v=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t);var i,s=this._getNumberOfMonths(t),n=s[1],a=17,r=t.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&t.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),t.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,s){var n=t.dpDiv.outerWidth(),a=t.dpDiv.outerHeight(),o=t.input?t.input.outerWidth():0,r=t.input?t.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:e(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?n-o:0,i.left-=s&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=s&&i.top===t.input.offset().top+r?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+a>l&&l>a?Math.abs(a+r):0),i},_findPos:function(t){for(var i,s=this._getInst(t),n=this._get(s,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[n?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,s,n,a,o=this._curInst;!o||t&&o!==e.data(t,"datepicker")||this._datepickerShowing&&(i=this._get(o,"showAnim"),s=this._get(o,"duration"),n=function(){e.datepicker._tidyDialog(o)},e.effects&&(e.effects.effect[i]||e.effects[i])?o.dpDiv.hide(i,e.datepicker._get(o,"showOptions"),s,n):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,a=this._get(o,"onClose"),a&&a.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),s=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==s)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,s){var n=e(t),a=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(a,i+("M"===s?this._get(a,"showCurrentAtPos"):0),s),this._updateDatepicker(a))},_gotoToday:function(t){var i,s=e(t),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(t,i,s){var n=e(t),a=this._getInst(n[0]);a["selected"+("M"===s?"Month":"Year")]=a["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(a),this._adjustDate(n)},_selectDay:function(t,i,s,n){var a,o=e(t);e(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0])||(a=this._getInst(o[0]),a.selectedDay=a.currentDay=e("a",n).html(),a.selectedMonth=a.currentMonth=i,a.selectedYear=a.currentYear=s,this._selectDate(t,this._formatDate(a,a.currentDay,a.currentMonth,a.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var s,n=e(t),a=this._getInst(n[0]);i=null!=i?i:this._formatDate(a),a.input&&a.input.val(i),this._updateAlternate(a),s=this._get(a,"onSelect"),s?s.apply(a.input?a.input[0]:null,[i,a]):a.input&&a.input.trigger("change"),a.inline?this._updateDatepicker(a):(this._hideDatepicker(),this._lastInput=a.input[0],"object"!=typeof a.input[0]&&a.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,s,n,a=this._get(t,"altField");a&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),s=this._getDate(t),n=this.formatDate(i,s,this._getFormatConfig(t)),e(a).each(function(){e(this).val(n)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(t,i,s){if(null==t||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,a,o,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),d=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,c=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,m=-1,g=-1,v=-1,y=-1,b=!1,_=function(e){var i=t.length>n+1&&t.charAt(n+1)===e;return i&&n++,i},x=function(e){var t=_(e),s="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,n="y"===e?s:1,a=RegExp("^\\d{"+n+","+s+"}"),o=i.substring(h).match(a);if(!o)throw"Missing number at position "+h;return h+=o[0].length,parseInt(o[0],10)},w=function(t,s,n){var a=-1,o=e.map(_(t)?n:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(o,function(e,t){var s=t[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(a=t[0],h+=s.length,!1):void 0}),-1!==a)return a+1;throw"Unknown name at position "+h},k=function(){if(i.charAt(h)!==t.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;t.length>n;n++)if(b)"'"!==t.charAt(n)||_("'")?k():b=!1;else switch(t.charAt(n)){case"d":v=x("d");break;case"D":w("D",d,c);break;case"o":y=x("o");break;case"m":g=x("m");break;case"M":g=w("M",p,f);break;case"y":m=x("y");break;case"@":r=new Date(x("@")),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"!":r=new Date((x("!")-this._ticksTo1970)/1e4),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"'":_("'")?k():b=!0;break;default:k()}if(i.length>h&&(o=i.substr(h),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),y>-1)for(g=1,v=y;;){if(a=this._getDaysInMonth(m,g-1),a>=v)break;g++,v-=a}if(r=this._daylightSavingAdjust(new Date(m,g-1,v)),r.getFullYear()!==m||r.getMonth()+1!==g||r.getDate()!==v)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,a=(i?i.dayNames:null)||this._defaults.dayNames,o=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(t){var i=e.length>s+1&&e.charAt(s+1)===t;return i&&s++,i},l=function(e,t,i){var s=""+t;if(h(e))for(;i>s.length;)s="0"+s;return s},u=function(e,t,i,s){return h(e)?s[t]:i[t]},d="",c=!1;if(t)for(s=0;e.length>s;s++)if(c)"'"!==e.charAt(s)||h("'")?d+=e.charAt(s):c=!1;else switch(e.charAt(s)){case"d":d+=l("d",t.getDate(),2);break;case"D":d+=u("D",t.getDay(),n,a);break;case"o":d+=l("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":d+=l("m",t.getMonth()+1,2);break;case"M":d+=u("M",t.getMonth(),o,r);break;case"y":d+=h("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":d+=t.getTime();break;case"!":d+=1e4*t.getTime()+this._ticksTo1970;break;case"'":h("'")?d+="'":c=!0;break;default:d+=e.charAt(s)}return d},_possibleChars:function(e){var t,i="",s=!1,n=function(i){var s=e.length>t+1&&e.charAt(t+1)===i;return s&&t++,s};for(t=0;e.length>t;t++)if(s)"'"!==e.charAt(t)||n("'")?i+=e.charAt(t):s=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,t){return void 0!==e.settings[t]?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),s=e.lastVal=e.input?e.input.val():null,n=this._getDefaultDate(e),a=n,o=this._getFormatConfig(e);try{a=this.parseDate(i,s,o)||n}catch(r){s=t?"":s}e.selectedDay=a.getDate(),e.drawMonth=e.selectedMonth=a.getMonth(),e.drawYear=e.selectedYear=a.getFullYear(),e.currentDay=s?a.getDate():0,e.currentMonth=s?a.getMonth():0,e.currentYear=s?a.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,s){var n=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},a=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,a=n.getFullYear(),o=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":o+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o));break;case"y":case"Y":a+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o))}l=h.exec(i)}return new Date(a,o,r)},o=null==i||""===i?s:"string"==typeof i?a(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return o=o&&"Invalid Date"==""+o?s:o,o&&(o.setHours(0),o.setMinutes(0),o.setSeconds(0),o.setMilliseconds(0)),this._daylightSavingAdjust(o)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var s=!t,n=e.selectedMonth,a=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),n===e.selectedMonth&&a===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(s?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),s="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(s,-i,"M")},next:function(){e.datepicker._adjustDate(s,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(s)},selectDay:function(){return e.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(s,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,s,n,a,o,r,h,l,u,d,c,p,f,m,g,v,y,b,_,x,w,k,T,D,S,M,C,N,A,I,P,z,H,F,E,O,j,W,L=new Date,R=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(e,"isRTL"),B=this._get(e,"showButtonPanel"),J=this._get(e,"hideIfNoPrevNext"),q=this._get(e,"navigationAsDateFormat"),K=this._getNumberOfMonths(e),V=this._get(e,"showCurrentAtPos"),U=this._get(e,"stepMonths"),Q=1!==K[0]||1!==K[1],G=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),X=this._getMinMaxDate(e,"min"),$=this._getMinMaxDate(e,"max"),Z=e.drawMonth-V,et=e.drawYear;if(0>Z&&(Z+=12,et--),$)for(t=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-K[0]*K[1]+1,$.getDate())),t=X&&X>t?X:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=q?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-U,1)),this._getFormatConfig(e)):i,s=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":J?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(e,"nextText"),n=q?this.formatDate(n,this._daylightSavingAdjust(new Date(et,Z+U,1)),this._getFormatConfig(e)):n,a=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":J?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",o=this._get(e,"currentText"),r=this._get(e,"gotoCurrent")&&e.currentDay?G:R,o=q?this.formatDate(o,r,this._getFormatConfig(e)):o,h=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(e,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+o+"</button>":"")+(Y?"":h)+"</div>":"",u=parseInt(this._get(e,"firstDay"),10),u=isNaN(u)?0:u,d=this._get(e,"showWeek"),c=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),f=this._get(e,"monthNames"),m=this._get(e,"monthNamesShort"),g=this._get(e,"beforeShowDay"),v=this._get(e,"showOtherMonths"),y=this._get(e,"selectOtherMonths"),b=this._getDefaultDate(e),_="",w=0;K[0]>w;w++){for(k="",this.maxRows=4,T=0;K[1]>T;T++){if(D=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),S=" ui-corner-all",M="",Q){if(M+="<div class='ui-datepicker-group",K[1]>1)switch(T){case 0:M+=" ui-datepicker-group-first",S=" ui-corner-"+(Y?"right":"left");break;case K[1]-1:M+=" ui-datepicker-group-last",S=" ui-corner-"+(Y?"left":"right");break;default:M+=" ui-datepicker-group-middle",S=""}M+="'>"}for(M+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+S+"'>"+(/all|left/.test(S)&&0===w?Y?a:s:"")+(/all|right/.test(S)&&0===w?Y?s:a:"")+this._generateMonthYearHeader(e,Z,et,X,$,w>0||T>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",C=d?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",x=0;7>x;x++)N=(x+u)%7,C+="<th scope='col'"+((x+u+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+c[N]+"'>"+p[N]+"</span></th>";for(M+=C+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),I=(this._getFirstDayOfMonth(et,Z)-u+7)%7,P=Math.ceil((I+A)/7),z=Q?this.maxRows>P?this.maxRows:P:P,this.maxRows=z,H=this._daylightSavingAdjust(new Date(et,Z,1-I)),F=0;z>F;F++){for(M+="<tr>",E=d?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(H)+"</td>":"",x=0;7>x;x++)O=g?g.apply(e.input?e.input[0]:null,[H]):[!0,""],j=H.getMonth()!==Z,W=j&&!y||!O[0]||X&&X>H||$&&H>$,E+="<td class='"+((x+u+6)%7>=5?" ui-datepicker-week-end":"")+(j?" ui-datepicker-other-month":"")+(H.getTime()===D.getTime()&&Z===e.selectedMonth&&e._keyEvent||b.getTime()===H.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(W?" "+this._unselectableClass+" ui-state-disabled":"")+(j&&!v?"":" "+O[1]+(H.getTime()===G.getTime()?" "+this._currentClass:"")+(H.getTime()===R.getTime()?" ui-datepicker-today":""))+"'"+(j&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(W?"":" data-handler='selectDay' data-event='click' data-month='"+H.getMonth()+"' data-year='"+H.getFullYear()+"'")+">"+(j&&!v?"&#xa0;":W?"<span class='ui-state-default'>"+H.getDate()+"</span>":"<a class='ui-state-default"+(H.getTime()===R.getTime()?" ui-state-highlight":"")+(H.getTime()===G.getTime()?" ui-state-active":"")+(j?" ui-priority-secondary":"")+"' href='#'>"+H.getDate()+"</a>")+"</td>",H.setDate(H.getDate()+1),H=this._daylightSavingAdjust(H);M+=E+"</tr>"}Z++,Z>11&&(Z=0,et++),M+="</tbody></table>"+(Q?"</div>"+(K[0]>0&&T===K[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),k+=M}_+=k}return _+=l,e._keyEvent=!1,_},_generateMonthYearHeader:function(e,t,i,s,n,a,o,r){var h,l,u,d,c,p,f,m,g=this._get(e,"changeMonth"),v=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",_="";if(a||!g)_+="<span class='ui-datepicker-month'>"+o[t]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,_+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",u=0;12>u;u++)(!h||u>=s.getMonth())&&(!l||n.getMonth()>=u)&&(_+="<option value='"+u+"'"+(u===t?" selected='selected'":"")+">"+r[u]+"</option>");_+="</select>"}if(y||(b+=_+(!a&&g&&v?"":"&#xa0;")),!e.yearshtml)if(e.yearshtml="",a||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(d=this._get(e,"yearRange").split(":"),c=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?c+parseInt(e,10):parseInt(e,10);return isNaN(t)?c:t},f=p(d[0]),m=Math.max(f,p(d[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=n?Math.min(m,n.getFullYear()):m,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)e.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";e.yearshtml+="</select>",b+=e.yearshtml,e.yearshtml=null}return b+=this._get(e,"yearSuffix"),y&&(b+=(!a&&g&&v?"":"&#xa0;")+_),b+="</div>"},_adjustInstDate:function(e,t,i){var s=e.drawYear+("Y"===i?t:0),n=e.drawMonth+("M"===i?t:0),a=Math.min(e.selectedDay,this._getDaysInMonth(s,n))+("D"===i?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(s,n,a)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),s=this._getMinMaxDate(e,"max"),n=i&&i>t?i:t;return s&&n>s?s:n},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,s){var n=this._getNumberOfMonths(e),a=this._daylightSavingAdjust(new Date(i,s+(0>t?t:n[0]*n[1]),1));return 0>t&&a.setDate(this._getDaysInMonth(a.getFullYear(),a.getMonth())),this._isInRange(e,a)},_isInRange:function(e,t){var i,s,n=this._getMinMaxDate(e,"min"),a=this._getMinMaxDate(e,"max"),o=null,r=null,h=this._get(e,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),o=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(o+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||t.getTime()>=n.getTime())&&(!a||t.getTime()<=a.getTime())&&(!o||t.getFullYear()>=o)&&(!r||r>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,s){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var n=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(s,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),n,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new n,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.11.3",e.datepicker,e.widget("ui.dialog",{version:"1.11.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i,s=this;if(this._isOpen&&this._trigger("beforeClose",t)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&e(i).blur()}catch(n){}this._hide(this.uiDialog,this.options.hide,function(){s._trigger("close",t)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+e(this).css("z-index")}).get(),a=Math.max.apply(null,n);return a>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",a+1),s=!0),s&&!i&&this._trigger("focus",t),s},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")
+}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var e=this._focusedElement;e||(e=this.element.find("[autofocus]")),e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),void 0;if(t.keyCode===e.ui.keyCode.TAB&&!t.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");t.target!==n[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==s[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){n.focus()}),t.preventDefault()):(this._delay(function(){s.focus()}),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html("&#160;"),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),void 0):(e.each(i,function(i,s){var n,a;s=e.isFunction(s)?{click:s,text:i}:s,s=e.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(t.element[0],arguments)},a={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,e("<button></button>",s).button(a).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,t(n))},drag:function(e,s){i._trigger("drag",e,t(s))},stop:function(n,a){var o=a.offset.left-i.document.scrollLeft(),r=a.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(o>=0?"+":"")+o+" "+"top"+(r>=0?"+":"")+r,of:i.window},e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,t(a))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,s=this.options,n=s.resizable,a=this.uiDialog.css("position"),o="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:o,start:function(s,n){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,t(n))},resize:function(e,s){i._trigger("resize",e,t(s))},stop:function(n,a){var o=i.uiDialog.offset(),r=o.left-i.document.scrollLeft(),h=o.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,t(a))}}).css("position",a)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=e(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),i=e.inArray(this,t);-1!==i&&t.splice(i,1)},_trackingInstances:function(){var e=this.document.data("ui-dialog-instances");return e||(e=[],this.document.data("ui-dialog-instances",e)),e},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};e.each(t,function(e,t){i._setOption(e,t),e in i.sizeRelatedOptions&&(s=!0),e in i.resizableRelatedOptions&&(n[e]=t)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,t){var i,s,n=this.uiDialog;"dialogClass"===e&&n.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=n.is(":data(ui-draggable)"),i&&!t&&n.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(s=n.is(":data(ui-resizable)"),s&&!t&&n.resizable("destroy"),s&&"string"==typeof t&&n.resizable("option","handles",t),s||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),e=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),t=Math.max(0,s.minHeight-e),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-e):"none","auto"===s.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=!0;this._delay(function(){t=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(e){t||this._allowInteraction(e)||(e.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var e=this.document.data("ui-dialog-overlays")-1;e?this.document.data("ui-dialog-overlays",e):this.document.unbind("focusin").removeData("ui-dialog-overlays"),this.overlay.remove(),this.overlay=null}}}),e.widget("ui.progressbar",{version:"1.11.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return void 0===e?this.options.value:(this.options.value=this._constrainedValue(e),this._refreshValue(),void 0)},_constrainedValue:function(e){return void 0===e&&(e=this.options.value),this.indeterminate=e===!1,"number"!=typeof e&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){"max"===e&&(t=Math.max(this.min,t)),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),e.widget("ui.selectmenu",{version:"1.11.3",defaultElement:"<select>",options:{appendTo:null,disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:null,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this.options.disabled&&this.disable()},_drawButton:function(){var t=this;this.label=e("label[for='"+this.ids.element+"']").attr("for",this.ids.button),this._on(this.label,{click:function(e){this.button.focus(),e.preventDefault()}}),this.element.hide(),this.button=e("<span>",{"class":"ui-selectmenu-button ui-widget ui-state-default ui-corner-all",tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true"}).insertAfter(this.element),e("<span>",{"class":"ui-icon "+this.options.icons.button}).prependTo(this.button),this.buttonText=e("<span>",{"class":"ui-selectmenu-text"}).appendTo(this.button),this._setText(this.buttonText,this.element.find("option:selected").text()),this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){t.menuItems||t._refreshMenu()}),this._hoverable(this.button),this._focusable(this.button)},_drawMenu:function(){var t=this;this.menu=e("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=e("<div>",{"class":"ui-selectmenu-menu ui-front"}).append(this.menu).appendTo(this._appendTo()),this.menuInstance=this.menu.menu({role:"listbox",select:function(e,i){e.preventDefault(),t._setSelection(),t._select(i.item.data("ui-selectmenu-item"),e)},focus:function(e,i){var s=i.item.data("ui-selectmenu-item");null!=t.focusIndex&&s.index!==t.focusIndex&&(t._trigger("focus",e,{item:s}),t.isOpen||t._select(s,e)),t.focusIndex=s.index,t.button.attr("aria-activedescendant",t.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menu.addClass("ui-corner-bottom").removeClass("ui-corner-all"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this._setText(this.buttonText,this._getSelectedItem().text()),this.options.width||this._resizeButton()},_refreshMenu:function(){this.menu.empty();var e,t=this.element.find("option");t.length&&(this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup"),e=this._getSelectedItem(),this.menuInstance.focus(null,e),this._setAria(e.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(e){this.options.disabled||(this.menuItems?(this.menu.find(".ui-state-focus").removeClass("ui-state-focus"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",e))},_position:function(){this.menuWrap.position(e.extend({of:this.button},this.options.position))},close:function(e){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",e))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderMenu:function(t,i){var s=this,n="";e.each(i,function(i,a){a.optgroup!==n&&(e("<li>",{"class":"ui-selectmenu-optgroup ui-menu-divider"+(a.element.parent("optgroup").prop("disabled")?" ui-state-disabled":""),text:a.optgroup}).appendTo(t),n=a.optgroup),s._renderItemData(t,a)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-selectmenu-item",t)},_renderItem:function(t,i){var s=e("<li>");return i.disabled&&s.addClass("ui-state-disabled"),this._setText(s,i.label),s.appendTo(t)},_setText:function(e,t){t?e.text(t):e.html("&#160;")},_move:function(e,t){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex):(i=this.menuItems.eq(this.element[0].selectedIndex),n+=":not(.ui-state-disabled)"),s="first"===e||"last"===e?i["first"===e?"prevAll":"nextAll"](n).eq(-1):i[e+"All"](n).eq(0),s.length&&this.menuInstance.focus(t,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex)},_toggle:function(e){this[this.isOpen?"close":"open"](e)},_setSelection:function(){var e;this.range&&(window.getSelection?(e=window.getSelection(),e.removeAllRanges(),e.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(t){this.isOpen&&(e(t.target).closest(".ui-selectmenu-menu, #"+this.ids.button).length||this.close(t))}},_buttonEvents:{mousedown:function(){var e;window.getSelection?(e=window.getSelection(),e.rangeCount&&(this.range=e.getRangeAt(0))):this.range=document.selection.createRange()},click:function(e){this._setSelection(),this._toggle(e)},keydown:function(t){var i=!0;switch(t.keyCode){case e.ui.keyCode.TAB:case e.ui.keyCode.ESCAPE:this.close(t),i=!1;break;case e.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case e.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case e.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case e.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case e.ui.keyCode.LEFT:this._move("prev",t);break;case e.ui.keyCode.RIGHT:this._move("next",t);break;case e.ui.keyCode.HOME:case e.ui.keyCode.PAGE_UP:this._move("first",t);break;case e.ui.keyCode.END:case e.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),i=!1}i&&t.preventDefault()}},_selectFocusedItem:function(e){var t=this.menuItems.eq(this.focusIndex);t.hasClass("ui-state-disabled")||this._select(t.data("ui-selectmenu-item"),e)},_select:function(e,t){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=e.index,this._setText(this.buttonText,e.label),this._setAria(e),this._trigger("select",t,{item:e}),e.index!==i&&this._trigger("change",t,{item:e}),this.close(t)},_setAria:function(e){var t=this.menuItems.eq(e.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(e,t){"icons"===e&&this.button.find("span.ui-icon").removeClass(this.options.icons.button).addClass(t.button),this._super(e,t),"appendTo"===e&&this.menuWrap.appendTo(this._appendTo()),"disabled"===e&&(this.menuInstance.option("disabled",t),this.button.toggleClass("ui-state-disabled",t).attr("aria-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)),"width"===e&&this._resizeButton()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_toggleAttr:function(){this.button.toggleClass("ui-corner-top",this.isOpen).toggleClass("ui-corner-all",!this.isOpen).attr("aria-expanded",this.isOpen),this.menuWrap.toggleClass("ui-selectmenu-open",this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var e=this.options.width;e||(e=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(e)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){return{disabled:this.element.prop("disabled")}},_parseOptions:function(t){var i=[];t.each(function(t,s){var n=e(s),a=n.parent("optgroup");i.push({element:n,index:t,value:n.val(),label:n.text(),optgroup:a.attr("label")||"",disabled:a.prop("disabled")||n.prop("disabled")})}),this.items=i},_destroy:function(){this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.label.attr("for",this.ids.element)}}),e.widget("ui.slider",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),a="<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",o=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),t=n.length;i>t;t++)o.push(a);this.handles=n.add(e(o.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)})},_createRange:function(){var t=this.options,i="";t.range?(t.range===!0&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:e.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=e("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===t.range||"max"===t.range?" ui-slider-range-"+t.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var i,s,n,a,o,r,h,l,u=this,d=this.options;return d.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:t.pageX,y:t.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var i=Math.abs(s-u.values(t));(n>i||n===i&&(t===u._lastChangedValue||u.values(t)===d.min))&&(n=i,a=e(this),o=t)}),r=this._start(t,o),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,a.addClass("ui-state-active").focus(),h=a.offset(),l=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:t.pageX-h.left-a.width()/2,top:t.pageY-h.top-a.height()/2-(parseInt(a.css("borderTopWidth"),10)||0)-(parseInt(a.css("borderBottomWidth"),10)||0)+(parseInt(a.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},i=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,i),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,i,s,n,a;return"horizontal"===this.orientation?(t=this.elementSize.width,i=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,i=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/t,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),a=this._valueMin()+s*n,this._trimAlignValue(a)},_start:function(e,t){var i={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("start",e,i)},_slide:function(e,t,i){var s,n,a;this.options.values&&this.options.values.length?(s=this.values(t?0:1),2===this.options.values.length&&this.options.range===!0&&(0===t&&i>s||1===t&&s>i)&&(i=s),i!==this.values(t)&&(n=this.values(),n[t]=i,a=this._trigger("slide",e,{handle:this.handles[t],value:i,values:n}),s=this.values(t?0:1),a!==!1&&this.values(t,i))):i!==this.value()&&(a=this._trigger("slide",e,{handle:this.handles[t],value:i}),a!==!1&&this.value(i))},_stop:function(e,t){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("stop",e,i)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._lastChangedValue=t,this._trigger("change",e,i)}},value:function(e){return arguments.length?(this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(t,i){var s,n,a;if(arguments.length>1)return this.options.values[t]=this._trimAlignValue(i),this._refreshValue(),this._change(null,t),void 0;if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();for(s=this.options.values,n=arguments[0],a=0;s.length>a;a+=1)s[a]=this._trimAlignValue(n[a]),this._change(null,a);this._refreshValue()},_setOption:function(t,i){var s,n=0;switch("range"===t&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),e.isArray(this.options.values)&&(n=this.options.values.length),"disabled"===t&&this.element.toggleClass("ui-state-disabled",!!i),this._super(t,i),t){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue(),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e)},_values:function(e){var t,i,s;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(e){if(this._valueMin()>=e)return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,i=(e-this._valueMin())%t,s=e-i;return 2*Math.abs(i)>=t&&(s+=i>0?t:-t),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var e=this.options.max,t=this._valueMin(),i=this.options.step,s=Math.floor((e-t)/i)*i;e=s+t,this.max=parseFloat(e.toFixed(this._precision()))},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshValue:function(){var t,i,s,n,a,o=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",e(this).stop(1,1)[l?"animate":"css"](u,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-t+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-t+"%"},{queue:!1,duration:r.animate}))),t=i}):(s=this.value(),n=this._valueMin(),a=this._valueMax(),i=a!==n?100*((s-n)/(a-n)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,r.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===o&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===o&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(t){var i,s,n,a,o=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,e(t.target).addClass("ui-state-active"),i=this._start(t,o),i===!1))return}switch(a=this.options.step,s=n=this.options.values&&this.options.values.length?this.values(o):this.value(),t.keyCode){case e.ui.keyCode.HOME:n=this._valueMin();break;case e.ui.keyCode.END:n=this._valueMax();break;case e.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+a);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-a)}this._slide(t,o,n)},keyup:function(t){var i=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,i),this._change(t,i),e(t.target).removeClass("ui-state-active"))}}}),e.widget("ui.spinner",{version:"1.11.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},i=this.element;return e.each(["min","max","step"],function(e,s){var n=i.attr(s);void 0!==n&&n.length&&(t[s]=n)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e),void 0)},mousewheel:function(e,t){if(t){if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()}},"mousedown .ui-spinner-button":function(t){function i(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(t)!==!1&&this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){return e(t.currentTarget).hasClass("ui-state-active")?this._start(t)===!1?!1:(this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*e.height())&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var i=this.options,s=e.ui.keyCode;switch(t.keyCode){case s.UP:return this._repeat(null,1,t),!0;case s.DOWN:return this._repeat(null,-1,t),!0;case s.PAGE_UP:return this._repeat(null,i.page,t),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"
+},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return this.spinning||this._trigger("start",e)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(e,t,i){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,i)},e),this._spin(t*this.options.step,i)},_spin:function(e,t){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+e*this._increment(this.counter)),this.spinning&&this._trigger("spin",t,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(t){var i=this.options.incremental;return i?e.isFunction(i)?i(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_adjustValue:function(e){var t,i,s=this.options;return t=null!==s.min?s.min:0,i=e-t,i=Math.round(i/s.step)*s.step,e=t+i,e=parseFloat(e.toFixed(this._precision())),null!==s.max&&e>s.max?s.max:null!==s.min&&s.min>e?s.min:e},_stop:function(e){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e))},_setOption:function(e,t){if("culture"===e||"numberFormat"===e){var i=this._parse(this.element.val());return this.options[e]=t,this.element.val(this._format(i)),void 0}("max"===e||"min"===e||"step"===e)&&"string"==typeof t&&(t=this._parse(t)),"icons"===e&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(t.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(t.down)),this._super(e,t),"disabled"===e&&(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable"))},_setOptions:h(function(e){this._super(e)}),_parse:function(e){return"string"==typeof e&&""!==e&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),""===e||isNaN(e)?null:e},_format:function(e){return""===e?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var e=this.value();return null===e?!1:e===this._adjustValue(e)},_value:function(e,t){var i;""!==e&&(i=this._parse(e),null!==i&&(t||(i=this._adjustValue(i)),e=this._format(i))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:h(function(e){this._stepUp(e)}),_stepUp:function(e){this._start()&&(this._spin((e||1)*this.options.step),this._stop())},stepDown:h(function(e){this._stepDown(e)}),_stepDown:function(e){this._start()&&(this._spin((e||1)*-this.options.step),this._stop())},pageUp:h(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:h(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){return arguments.length?(h(this._value).call(this,e),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),e.widget("ui.tabs",{version:"1.11.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,n){return e(n).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),t.ctrlKey||t.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>n&&(t=0),0>t&&(t=n),t}for(var n=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var n,a,o,r=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(n=s.hash,o=n.substring(1),a=t.element.find(t._sanitizeSelector(n))):(o=h.attr("aria-controls")||e({}).uniqueId()[0].id,n="#"+o,a=t.element.find(n),a.length||(a=t._createPanel(o),a.insertAfter(t.panels[i-1]||t.tablist)),a.attr("aria-live","polite")),a.length&&(t.panels=t.panels.add(a)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":o,"aria-labelledby":r}),a.attr("aria-labelledby",r)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?e():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:r?e():a,newPanel:h};t.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?e():a,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),t),this._toggle(t,u))},_toggle:function(t,i){function s(){a.running=!1,a._trigger("activate",t,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,n=this.tabs.eq(t),a=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),r={tab:n,panel:o};this._isLocal(a[0])||(this.xhr=e.ajax(this._ajaxSettings(a,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){o.html(e),s._trigger("load",i,r)},1)}).complete(function(e,t){setTimeout(function(){"abort"===t&&s.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,a){return n._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:a},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),e.widget("ui.tooltip",{version:"1.11.3",options:{content:function(){var t=e(this).attr("title")||"";return e("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_addDescribedBy:function(t,i){var s=(t.attr("aria-describedby")||"").split(/\s+/);s.push(i),t.data("ui-tooltip-id",i).attr("aria-describedby",e.trim(s.join(" ")))},_removeDescribedBy:function(t){var i=t.data("ui-tooltip-id"),s=(t.attr("aria-describedby")||"").split(/\s+/),n=e.inArray(i,s);-1!==n&&s.splice(n,1),t.removeData("ui-tooltip-id"),s=e.trim(s.join(" ")),s?t.attr("aria-describedby",s):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable(),this.liveRegion=e("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body)},_setOption:function(t,i){var s=this;return"disabled"===t?(this[i?"_disable":"_enable"](),this.options[t]=i,void 0):(this._super(t,i),"content"===t&&e.each(this.tooltips,function(e,t){s._updateContent(t.element)}),void 0)},_disable:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur");n.target=n.currentTarget=s.element[0],t.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var i=this,s=e(t?t.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&s.parents().each(function(){var t,s=e(this);s.data("ui-tooltip-open")&&(t=e.Event("blur"),t.target=t.currentTarget=this,i.close(t,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,t))},_updateContent:function(e,t){var i,s=this.options.content,n=this,a=t?t.type:null;return"string"==typeof s?this._open(t,e,s):(i=s.call(e[0],function(i){e.data("ui-tooltip-open")&&n._delay(function(){t&&(t.type=a),this._open(t,e,i)})}),i&&this._open(t,e,i),void 0)},_open:function(t,i,s){function n(e){u.of=e,o.is(":hidden")||o.position(u)}var a,o,r,h,l,u=e.extend({},this.options.position);if(s){if(a=this._find(i))return a.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(t&&"mouseover"===t.type?i.attr("title",""):i.removeAttr("title")),a=this._tooltip(i),o=a.tooltip,this._addDescribedBy(i,o.attr("id")),o.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),s.clone?(l=s.clone(),l.removeAttr("id").find("[id]").removeAttr("id")):l=s,e("<div>").html(l).appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:n}),n(t)):o.position(e.extend({of:i},this.options.position)),o.hide(),this._show(o,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){o.is(":visible")&&(n(u.of),clearInterval(h))},e.fx.interval)),this._trigger("open",t,{tooltip:o}),r={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var s=e.Event(t);s.currentTarget=i[0],this.close(s,!0)}}},i[0]!==this.element[0]&&(r.remove=function(){this._removeTooltip(o)}),t&&"mouseover"!==t.type||(r.mouseleave="close"),t&&"focusin"!==t.type||(r.focusout="close"),this._on(!0,i,r)}},close:function(t){var i,s=this,n=e(t?t.currentTarget:this.element),a=this._find(n);a&&(i=a.tooltip,a.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),a.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(e(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&e.each(this.parents,function(t,i){e(i.element).attr("title",i.title),delete s.parents[t]}),a.closing=!0,this._trigger("close",t,{tooltip:i}),a.hiding||(a.closing=!1)))},_tooltip:function(t){var i=e("<div>").attr("role","tooltip").addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||"")),s=i.uniqueId().attr("id");return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),this.tooltips[s]={element:t,tooltip:i}},_find:function(e){var t=e.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur"),a=s.element;n.target=n.currentTarget=a[0],t.close(n,!0),e("#"+i).remove(),a.data("ui-tooltip-title")&&(a.attr("title")||a.attr("title",a.data("ui-tooltip-title")),a.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}});var y="ui-effects-",b=e;e.effects={effect:{}},function(e,t){function i(e,t,i){var s=d[t.type]||{};return null==e?i||!t.def?null:t.def:(e=s.floor?~~e:parseFloat(e),isNaN(e)?t.def:s.mod?(e+s.mod)%s.mod:0>e?0:e>s.max?s.max:e)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(e,a){var o,r=a.re.exec(i),h=r&&a.parse(r),l=a.space||"rgba";return h?(o=s[l](h),s[u[l].cache]=o[u[l].cache],n=s._rgba=o._rgba,!1):t}),n.length?("0,0,0,0"===n.join()&&e.extend(n,a.transparent),s):a[i]}function n(e,t,i){return i=(i+1)%1,1>6*i?e+6*(t-e)*i:1>2*i?t:2>3*i?e+6*(t-e)*(2/3-i):e}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[2.55*e[1],2.55*e[2],2.55*e[3],e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],l=e.Color=function(t,i,s,n){return new e.Color.fn.parse(t,i,s,n)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},d={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},c=l.support={},p=e("<p>")[0],f=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",c.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(n,o,r,h){if(n===t)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=e(n).css(o),o=t);var d=this,c=e.type(n),p=this._rgba=[];return o!==t&&(n=[n,o,r,h],c="array"),"string"===c?this.parse(s(n)||a._default):"array"===c?(f(u.rgba.props,function(e,t){p[t.idx]=i(n[t.idx],t)}),this):"object"===c?(n instanceof l?f(u,function(e,t){n[t.cache]&&(d[t.cache]=n[t.cache].slice())}):f(u,function(t,s){var a=s.cache;f(s.props,function(e,t){if(!d[a]&&s.to){if("alpha"===e||null==n[e])return;d[a]=s.to(d._rgba)}d[a][t.idx]=i(n[e],t,!0)}),d[a]&&0>e.inArray(null,d[a].slice(0,3))&&(d[a][3]=1,s.from&&(d._rgba=s.from(d[a])))}),this):t},is:function(e){var i=l(e),s=!0,n=this;return f(u,function(e,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(e,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:t})),s}),s},_space:function(){var e=[],t=this;return f(u,function(i,s){t[s.cache]&&e.push(i)}),e.pop()},transition:function(e,t){var s=l(e),n=s._space(),a=u[n],o=0===this.alpha()?l("transparent"):this,r=o[a.cache]||a.to(o._rgba),h=r.slice();return s=s[a.cache],f(a.props,function(e,n){var a=n.idx,o=r[a],l=s[a],u=d[n.type]||{};null!==l&&(null===o?h[a]=l:(u.mod&&(l-o>u.mod/2?o+=u.mod:o-l>u.mod/2&&(o-=u.mod)),h[a]=i((l-o)*t+o,n)))}),this[n](h)},blend:function(t){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(t)._rgba;return l(e.map(i,function(e,t){return(1-s)*n[t]+s*e}))},toRgbaString:function(){var t="rgba(",i=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===i[3]&&(i.pop(),t="rgb("),t+i.join()+")"},toHslaString:function(){var t="hsla(",i=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&3>t&&(e=Math.round(100*e)+"%"),e});return 1===i[3]&&(i.pop(),t="hsl("),t+i.join()+")"},toHexString:function(t){var i=this._rgba.slice(),s=i.pop();return t&&i.push(~~(255*s)),"#"+e.map(i,function(e){return e=(e||0).toString(16),1===e.length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,i,s=e[0]/255,n=e[1]/255,a=e[2]/255,o=e[3],r=Math.max(s,n,a),h=Math.min(s,n,a),l=r-h,u=r+h,d=.5*u;return t=h===r?0:s===r?60*(n-a)/l+360:n===r?60*(a-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=d?l/u:l/(2-u),[Math.round(t)%360,i,d,null==o?1:o]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,i=e[1],s=e[2],a=e[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,t+1/3)),Math.round(255*n(r,o,t)),Math.round(255*n(r,o,t-1/3)),a]},f(u,function(s,n){var a=n.props,o=n.cache,h=n.to,u=n.from;l.fn[s]=function(s){if(h&&!this[o]&&(this[o]=h(this._rgba)),s===t)return this[o].slice();var n,r=e.type(s),d="array"===r||"object"===r?s:arguments,c=this[o].slice();return f(a,function(e,t){var s=d["object"===r?e:t.idx];null==s&&(s=c[t.idx]),c[t.idx]=i(s,t)}),u?(n=l(u(c)),n[o]=c,n):l(c)},f(a,function(t,i){l.fn[t]||(l.fn[t]=function(n){var a,o=e.type(n),h="alpha"===t?this._hsla?"hsla":"rgba":s,l=this[h](),u=l[i.idx];return"undefined"===o?u:("function"===o&&(n=n.call(this,u),o=e.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=u+parseFloat(a[2])*("+"===a[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(t){var i=t.split(" ");f(i,function(t,i){e.cssHooks[i]={set:function(t,n){var a,o,r="";if("transparent"!==n&&("string"!==e.type(n)||(a=s(n)))){if(n=l(a||n),!c.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?t.parentNode:t;(""===r||"transparent"===r)&&o&&o.style;)try{r=e.css(o,"backgroundColor"),o=o.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{t.style[i]=n}catch(h){}}},e.fx.step[i]=function(t){t.colorInit||(t.start=l(t.elem,i),t.end=l(t.end),t.colorInit=!0),e.cssHooks[i].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook(o),e.cssHooks.borderColor={expand:function(e){var t={};return f(["Top","Right","Bottom","Left"],function(i,s){t["border"+s+"Color"]=e}),t}},a=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(b),function(){function t(t){var i,s,n=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[e.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function i(t,i){var s,a,o={};for(s in i)a=i[s],t[s]!==a&&(n[s]||(e.fx.step[s]||!isNaN(parseFloat(a)))&&(o[s]=a));return o}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,i){e.fx.step[i]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(b.style(e.elem,i,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(n,a,o,r){var h=e.speed(a,o,r);return this.queue(function(){var a,o=e(this),r=o.attr("class")||"",l=h.children?o.find("*").addBack():o;l=l.map(function(){var i=e(this);return{el:i,start:t(this)}}),a=function(){e.each(s,function(e,t){n[t]&&o[t+"Class"](n[t])})},a(),l=l.map(function(){return this.end=t(this.el[0]),this.diff=i(this.start,this.end),this}),o.attr("class",r),l=l.map(function(){var t=this,i=e.Deferred(),s=e.extend({},h,{queue:!1,complete:function(){i.resolve(t)}});return this.el.animate(this.diff,s),i.promise()}),e.when.apply(e,l.get()).done(function(){a(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),h.complete.call(o[0])})})},e.fn.extend({addClass:function(t){return function(i,s,n,a){return s?e.effects.animateClass.call(this,{add:i},s,n,a):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(i,s,n,a){return arguments.length>1?e.effects.animateClass.call(this,{remove:i},s,n,a):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(t){return function(i,s,n,a,o){return"boolean"==typeof s||void 0===s?n?e.effects.animateClass.call(this,s?{add:i}:{remove:i},n,a,o):t.apply(this,arguments):e.effects.animateClass.call(this,{toggle:i},s,n,a)}}(e.fn.toggleClass),switchClass:function(t,i,s,n,a){return e.effects.animateClass.call(this,{add:i,remove:t},s,n,a)}})}(),function(){function t(t,i,s,n){return e.isPlainObject(t)&&(i=t,t=t.effect),t={effect:t},null==i&&(i={}),e.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||e.fx.speeds[i])&&(n=s,s=i,i={}),e.isFunction(s)&&(n=s,s=null),i&&e.extend(t,i),s=s||i.duration,t.duration=e.fx.off?0:"number"==typeof s?s:s in e.fx.speeds?e.fx.speeds[s]:e.fx.speeds._default,t.complete=n||i.complete,t}function i(t){return!t||"number"==typeof t||e.fx.speeds[t]?!0:"string"!=typeof t||e.effects.effect[t]?e.isFunction(t)?!0:"object"!=typeof t||t.effect?!1:!0:!0}e.extend(e.effects,{version:"1.11.3",save:function(e,t){for(var i=0;t.length>i;i++)null!==t[i]&&e.data(y+t[i],e[0].style[t[i]])},restore:function(e,t){var i,s;for(s=0;t.length>s;s++)null!==t[s]&&(i=e.data(y+t[s]),void 0===i&&(i=""),e.css(t[s],i))},setMode:function(e,t){return"toggle"===t&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var i,s;switch(e[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=e[0]/t.height}switch(e[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=e[1]/t.width}return{x:s,y:i}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var i={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},s=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:t.width(),height:t.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return t.wrap(s),(t[0]===a||e.contains(t[0],a))&&e(a).focus(),s=t.parent(),"static"===t.css("position")?(s.css({position:"relative"}),t.css({position:"relative"})):(e.extend(i,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,s){i[s]=t.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(n),s.css(i).show()},removeWrapper:function(t){var i=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===i||e.contains(t[0],i))&&e(i).focus()),t},setTransition:function(t,i,s,n){return n=n||{},e.each(i,function(e,i){var a=t.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),e.fn.extend({effect:function(){function i(t){function i(){e.isFunction(a)&&a.call(n[0]),e.isFunction(t)&&t()}var n=e(this),a=s.complete,r=s.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),i()):o.call(n[0],s,i)}var s=t.apply(this,arguments),n=s.mode,a=s.queue,o=e.effects.effect[s.effect];return e.fx.off||!o?n?this[n](s.duration,s.complete):this.each(function(){s.complete&&s.complete.call(this)
+}):a===!1?this.each(i):this.queue(a||"fx",i)},show:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(e.fn.show),hide:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(e.fn.hide),toggle:function(e){return function(s){if(i(s)||"boolean"==typeof s)return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(e.fn.toggle),cssUnit:function(t){var i=this.css(t),s=[];return e.each(["em","px","%","pt"],function(e,t){i.indexOf(t)>0&&(s=[parseFloat(i),t])}),s}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,i){t[i]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,i=4;((t=Math.pow(2,--i))-1)/11>e;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,i){e.easing["easeIn"+t]=i,e.easing["easeOut"+t]=function(e){return 1-i(1-e)},e.easing["easeInOut"+t]=function(e){return.5>e?i(2*e)/2:1-i(-2*e+2)/2}})}(),e.effects,e.effects.effect.blind=function(t,i){var s,n,a,o=e(this),r=/up|down|vertical/,h=/up|left|vertical|horizontal/,l=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(o,t.mode||"hide"),d=t.direction||"up",c=r.test(d),p=c?"height":"width",f=c?"top":"left",m=h.test(d),g={},v="show"===u;o.parent().is(".ui-effects-wrapper")?e.effects.save(o.parent(),l):e.effects.save(o,l),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n=s[p](),a=parseFloat(s.css(f))||0,g[p]=v?n:0,m||(o.css(c?"bottom":"right",0).css(c?"top":"left","auto").css({position:"absolute"}),g[f]=v?a:n+a),v&&(s.css(p,0),m||s.css(f,a+n)),s.animate(g,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){"hide"===u&&o.hide(),e.effects.restore(o,l),e.effects.removeWrapper(o),i()}})},e.effects.effect.bounce=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"effect"),l="hide"===h,u="show"===h,d=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(u||l?1:0),m=t.duration/f,g=t.easing,v="up"===d||"down"===d?"top":"left",y="up"===d||"left"===d,b=o.queue(),_=b.length;for((u||l)&&r.push("opacity"),e.effects.save(o,r),o.show(),e.effects.createWrapper(o),c||(c=o["top"===v?"outerHeight":"outerWidth"]()/3),u&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,y?2*-c:2*c).animate(a,m,g)),l&&(c/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g).animate(a,m,g),c=l?2*c:c/2;l&&(n={opacity:0},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g)),o.queue(function(){l&&o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}),_>1&&b.splice.apply(b,[1,0].concat(b.splice(_,f+1))),o.dequeue()},e.effects.effect.clip=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"hide"),l="show"===h,u=t.direction||"vertical",d="vertical"===u,c=d?"height":"width",p=d?"top":"left",f={};e.effects.save(o,r),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[c](),l&&(n.css(c,0),n.css(p,a/2)),f[c]=l?a:0,f[p]=l?0:a/2,n.animate(f,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){l||o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}})},e.effects.effect.drop=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","opacity","height","width"],o=e.effects.setMode(n,t.mode||"hide"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h?"pos":"neg",d={opacity:r?1:0};e.effects.save(n,a),n.show(),e.effects.createWrapper(n),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===u?-s:s),d[l]=(r?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.explode=function(t,i){function s(){b.push(this),b.length===d*c&&n()}function n(){p.css({visibility:"visible"}),e(b).remove(),m||p.hide(),i()}var a,o,r,h,l,u,d=t.pieces?Math.round(Math.sqrt(t.pieces)):3,c=d,p=e(this),f=e.effects.setMode(p,t.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/c),y=Math.ceil(p.outerHeight()/d),b=[];for(a=0;d>a;a++)for(h=g.top+a*y,u=a-(d-1)/2,o=0;c>o;o++)r=g.left+o*v,l=o-(c-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*y}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:y,left:r+(m?l*v:0),top:h+(m?u*y:0),opacity:m?0:1}).animate({left:r+(m?0:l*v),top:h+(m?0:u*y),opacity:m?1:0},t.duration||500,t.easing,s)},e.effects.effect.fade=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:t.duration,easing:t.easing,complete:i})},e.effects.effect.fold=function(t,i){var s,n,a=e(this),o=["position","top","bottom","left","right","height","width"],r=e.effects.setMode(a,t.mode||"hide"),h="show"===r,l="hide"===r,u=t.size||15,d=/([0-9]+)%/.exec(u),c=!!t.horizFirst,p=h!==c,f=p?["width","height"]:["height","width"],m=t.duration/2,g={},v={};e.effects.save(a,o),a.show(),s=e.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],d&&(u=parseInt(d[1],10)/100*n[l?0:1]),h&&s.css(c?{height:0,width:u}:{height:u,width:0}),g[f[0]]=h?n[0]:u,v[f[1]]=h?n[1]:0,s.animate(g,m,t.easing).animate(v,m,t.easing,function(){l&&a.hide(),e.effects.restore(a,o),e.effects.removeWrapper(a),i()})},e.effects.effect.highlight=function(t,i){var s=e(this),n=["backgroundImage","backgroundColor","opacity"],a=e.effects.setMode(s,t.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),e.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===a&&s.hide(),e.effects.restore(s,n),i()}})},e.effects.effect.size=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],u=["fontSize"],d=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],c=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),f=t.restore||"effect"!==p,m=t.scale||"both",g=t.origin||["middle","center"],v=o.css("position"),y=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===t.mode&&"show"===p?(o.from=t.to||b,o.to=t.from||s):(o.from=t.from||("show"===p?b:s),o.to=t.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===m||"both"===m)&&(a.from.y!==a.to.y&&(y=y.concat(d),o.from=e.effects.setTransition(o,d,a.from.y,o.from),o.to=e.effects.setTransition(o,d,a.to.y,o.to)),a.from.x!==a.to.x&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,a.from.x,o.from),o.to=e.effects.setTransition(o,c,a.to.x,o.to))),("content"===m||"both"===m)&&a.from.y!==a.to.y&&(y=y.concat(u).concat(l),o.from=e.effects.setTransition(o,u,a.from.y,o.from),o.to=e.effects.setTransition(o,u,a.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),g&&(n=e.effects.getBaseline(g,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===m||"both"===m)&&(d=d.concat(["marginTop","marginBottom"]).concat(u),c=c.concat(["marginLeft","marginRight"]),l=r.concat(d).concat(c),o.find("*[width]").each(function(){var i=e(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&e.effects.save(i,l),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=e.effects.setTransition(i,d,a.from.y,i.from),i.to=e.effects.setTransition(i,d,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=e.effects.setTransition(i,c,a.from.x,i.from),i.to=e.effects.setTransition(i,c,a.to.x,i.to)),i.css(i.from),i.animate(i.to,t.duration,t.easing,function(){f&&e.effects.restore(i,l)})})),o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),e.effects.restore(o,y),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,i){var s=parseInt(i,10),n=e?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),e.effects.removeWrapper(o),i()}})},e.effects.effect.scale=function(t,i){var s=e(this),n=e.extend(!0,{},t),a=e.effects.setMode(s,t.mode||"effect"),o=parseInt(t.percent,10)||(0===parseInt(t.percent,10)?0:"hide"===a?0:100),r=t.direction||"both",h=t.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},u={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=h||["middle","center"],n.restore=!0),n.from=t.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*u.y,width:l.width*u.x,outerHeight:l.outerHeight*u.y,outerWidth:l.outerWidth*u.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},e.effects.effect.puff=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"hide"),a="hide"===n,o=parseInt(t.percent,10)||150,r=o/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(t)},e.effects.effect.pulsate=function(t,i){var s,n=e(this),a=e.effects.setMode(n,t.mode||"show"),o="show"===a,r="hide"===a,h=o||"hide"===a,l=2*(t.times||5)+(h?1:0),u=t.duration/l,d=0,c=n.queue(),p=c.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),d=1),s=1;l>s;s++)n.animate({opacity:d},u,t.easing),d=1-d;n.animate({opacity:d},u,t.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&c.splice.apply(c,[1,0].concat(c.splice(p,l+1))),n.dequeue()},e.effects.effect.shake=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","height","width"],o=e.effects.setMode(n,t.mode||"effect"),r=t.direction||"left",h=t.distance||20,l=t.times||3,u=2*l+1,d=Math.round(t.duration/u),c="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},m={},g={},v=n.queue(),y=v.length;for(e.effects.save(n,a),n.show(),e.effects.createWrapper(n),f[c]=(p?"-=":"+=")+h,m[c]=(p?"+=":"-=")+2*h,g[c]=(p?"-=":"+=")+2*h,n.animate(f,d,t.easing),s=1;l>s;s++)n.animate(m,d,t.easing).animate(g,d,t.easing);n.animate(m,d,t.easing).animate(f,d/2,t.easing).queue(function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}),y>1&&v.splice.apply(v,[1,0].concat(v.splice(y,u+1))),n.dequeue()},e.effects.effect.slide=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","width","height"],o=e.effects.setMode(n,t.mode||"show"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h,d={};e.effects.save(n,a),n.show(),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,u?isNaN(s)?"-"+s:-s:s),d[l]=(r?u?"+=":"-=":u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.transfer=function(t,i){var s=e(this),n=e(t.to),a="fixed"===n.css("position"),o=e("body"),r=a?o.scrollTop():0,h=a?o.scrollLeft():0,l=n.offset(),u={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},d=s.offset(),c=e("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(t.className).css({top:d.top-r,left:d.left-h,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(u,t.duration,t.easing,function(){c.remove(),i()})}});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.css
new file mode 100644 (file)
index 0000000..32ff6f7
--- /dev/null
@@ -0,0 +1,833 @@
+/*!
+ * jQuery UI CSS Framework 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/theming/
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+       display: none;
+}
+.ui-helper-hidden-accessible {
+       border: 0;
+       clip: rect(0 0 0 0);
+       height: 1px;
+       margin: -1px;
+       overflow: hidden;
+       padding: 0;
+       position: absolute;
+       width: 1px;
+}
+.ui-helper-reset {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       outline: 0;
+       line-height: 1.3;
+       text-decoration: none;
+       font-size: 100%;
+       list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+       content: "";
+       display: table;
+       border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+       clear: both;
+}
+.ui-helper-clearfix {
+       min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       left: 0;
+       position: absolute;
+       opacity: 0;
+       filter:Alpha(Opacity=0); /* support: IE8 */
+}
+
+.ui-front {
+       z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+       cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       display: block;
+       text-indent: -99999px;
+       overflow: hidden;
+       background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+       position: fixed;
+       top: 0;
+       left: 0;
+       width: 100%;
+       height: 100%;
+}
+.ui-draggable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable {
+       position: relative;
+}
+.ui-resizable-handle {
+       position: absolute;
+       font-size: 0.1px;
+       display: block;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+       display: none;
+}
+.ui-resizable-n {
+       cursor: n-resize;
+       height: 7px;
+       width: 100%;
+       top: -5px;
+       left: 0;
+}
+.ui-resizable-s {
+       cursor: s-resize;
+       height: 7px;
+       width: 100%;
+       bottom: -5px;
+       left: 0;
+}
+.ui-resizable-e {
+       cursor: e-resize;
+       width: 7px;
+       right: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-w {
+       cursor: w-resize;
+       width: 7px;
+       left: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-se {
+       cursor: se-resize;
+       width: 12px;
+       height: 12px;
+       right: 1px;
+       bottom: 1px;
+}
+.ui-resizable-sw {
+       cursor: sw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       bottom: -5px;
+}
+.ui-resizable-nw {
+       cursor: nw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       top: -5px;
+}
+.ui-resizable-ne {
+       cursor: ne-resize;
+       width: 9px;
+       height: 9px;
+       right: -5px;
+       top: -5px;
+}
+.ui-selectable {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-selectable-helper {
+       position: absolute;
+       z-index: 100;
+       border: 1px dotted black;
+}
+.ui-sortable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-accordion .ui-accordion-header {
+       display: block;
+       cursor: pointer;
+       position: relative;
+       margin: 2px 0 0 0;
+       padding: .5em .5em .5em .7em;
+       min-height: 0; /* support: IE7 */
+       font-size: 100%;
+}
+.ui-accordion .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+       position: absolute;
+       left: .5em;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+       padding: 1em 2.2em;
+       border-top: 0;
+       overflow: auto;
+}
+.ui-autocomplete {
+       position: absolute;
+       top: 0;
+       left: 0;
+       cursor: default;
+}
+.ui-button {
+       display: inline-block;
+       position: relative;
+       padding: 0;
+       line-height: normal;
+       margin-right: .1em;
+       cursor: pointer;
+       vertical-align: middle;
+       text-align: center;
+       overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+       text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+       width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+       width: 2.4em;
+}
+.ui-button-icons-only {
+       width: 3.4em;
+}
+button.ui-button-icons-only {
+       width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+       display: block;
+       line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+       padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+       padding: .4em;
+       text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+       padding-left: 2.1em;
+       padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+       padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+       position: absolute;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+       left: 50%;
+       margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+       left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+       right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+       margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+       margin-left: 0;
+       margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+       border: 0;
+       padding: 0;
+}
+.ui-datepicker {
+       width: 17em;
+       padding: .2em .2em 0;
+       display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+       position: relative;
+       padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+       position: absolute;
+       top: 2px;
+       width: 1.8em;
+       height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+       top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+       left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+       right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+       left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+       right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+       display: block;
+       position: absolute;
+       left: 50%;
+       margin-left: -8px;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+       margin: 0 2.3em;
+       line-height: 1.8em;
+       text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+       font-size: 1em;
+       margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+       width: 45%;
+}
+.ui-datepicker table {
+       width: 100%;
+       font-size: .9em;
+       border-collapse: collapse;
+       margin: 0 0 .4em;
+}
+.ui-datepicker th {
+       padding: .7em .3em;
+       text-align: center;
+       font-weight: bold;
+       border: 0;
+}
+.ui-datepicker td {
+       border: 0;
+       padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+       display: block;
+       padding: .2em;
+       text-align: right;
+       text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+       background-image: none;
+       margin: .7em 0 0 0;
+       padding: 0 .2em;
+       border-left: 0;
+       border-right: 0;
+       border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+       float: right;
+       margin: .5em .2em .4em;
+       cursor: pointer;
+       padding: .2em .6em .3em .6em;
+       width: auto;
+       overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+       float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+       width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+       float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+       width: 95%;
+       margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+       width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+       width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+       width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+       border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+       clear: left;
+}
+.ui-datepicker-row-break {
+       clear: both;
+       width: 100%;
+       font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+       direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+       right: 2px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+       left: 2px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+       right: 1px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+       left: 1px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+       clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+       float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+       float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+       border-right-width: 0;
+       border-left-width: 1px;
+}
+.ui-dialog {
+       overflow: hidden;
+       position: absolute;
+       top: 0;
+       left: 0;
+       padding: .2em;
+       outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+       padding: .4em 1em;
+       position: relative;
+}
+.ui-dialog .ui-dialog-title {
+       float: left;
+       margin: .1em 0;
+       white-space: nowrap;
+       width: 90%;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+       position: absolute;
+       right: .3em;
+       top: 50%;
+       width: 20px;
+       margin: -10px 0 0 0;
+       padding: 1px;
+       height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+       position: relative;
+       border: 0;
+       padding: .5em 1em;
+       background: none;
+       overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+       text-align: left;
+       border-width: 1px 0 0 0;
+       background-image: none;
+       margin-top: .5em;
+       padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+       float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+       margin: .5em .4em .5em 0;
+       cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+       width: 12px;
+       height: 12px;
+       right: -5px;
+       bottom: -5px;
+       background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+       cursor: move;
+}
+.ui-menu {
+       list-style: none;
+       padding: 0;
+       margin: 0;
+       display: block;
+       outline: none;
+}
+.ui-menu .ui-menu {
+       position: absolute;
+}
+.ui-menu .ui-menu-item {
+       position: relative;
+       margin: 0;
+       padding: 3px 1em 3px .4em;
+       cursor: pointer;
+       min-height: 0; /* support: IE7 */
+       /* support: IE10, see #8844 */
+       list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
+}
+.ui-menu .ui-menu-divider {
+       margin: 5px 0;
+       height: 0;
+       font-size: 0;
+       line-height: 0;
+       border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-focus,
+.ui-menu .ui-state-active {
+       margin: -1px;
+}
+
+/* icon support */
+.ui-menu-icons {
+       position: relative;
+}
+.ui-menu-icons .ui-menu-item {
+       padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: .2em;
+       margin: auto 0;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+       left: auto;
+       right: 0;
+}
+.ui-progressbar {
+       height: 2em;
+       text-align: left;
+       overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+       margin: -1px;
+       height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+       background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
+       height: 100%;
+       filter: alpha(opacity=25); /* support: IE8 */
+       opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+       background-image: none;
+}
+.ui-selectmenu-menu {
+       padding: 0;
+       margin: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+       overflow: auto;
+       /* Support: IE7 */
+       overflow-x: hidden;
+       padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+       font-size: 1em;
+       font-weight: bold;
+       line-height: 1.5;
+       padding: 2px 0.4em;
+       margin: 0.5em 0 0 0;
+       height: auto;
+       border: 0;
+}
+.ui-selectmenu-open {
+       display: block;
+}
+.ui-selectmenu-button {
+       display: inline-block;
+       overflow: hidden;
+       position: relative;
+       text-decoration: none;
+       cursor: pointer;
+}
+.ui-selectmenu-button span.ui-icon {
+       right: 0.5em;
+       left: auto;
+       margin-top: -8px;
+       position: absolute;
+       top: 50%;
+}
+.ui-selectmenu-button span.ui-selectmenu-text {
+       text-align: left;
+       padding: 0.4em 2.1em 0.4em 1em;
+       display: block;
+       line-height: 1.4;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.ui-slider {
+       position: relative;
+       text-align: left;
+}
+.ui-slider .ui-slider-handle {
+       position: absolute;
+       z-index: 2;
+       width: 1.2em;
+       height: 1.2em;
+       cursor: default;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-slider .ui-slider-range {
+       position: absolute;
+       z-index: 1;
+       font-size: .7em;
+       display: block;
+       border: 0;
+       background-position: 0 0;
+}
+
+/* support: IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+       filter: inherit;
+}
+
+.ui-slider-horizontal {
+       height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+       top: -.3em;
+       margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+       top: 0;
+       height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+       left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+       right: 0;
+}
+
+.ui-slider-vertical {
+       width: .8em;
+       height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+       left: -.3em;
+       margin-left: 0;
+       margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+       left: 0;
+       width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+       bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+       top: 0;
+}
+.ui-spinner {
+       position: relative;
+       display: inline-block;
+       overflow: hidden;
+       padding: 0;
+       vertical-align: middle;
+}
+.ui-spinner-input {
+       border: none;
+       background: none;
+       color: inherit;
+       padding: 0;
+       margin: .2em 0;
+       vertical-align: middle;
+       margin-left: .4em;
+       margin-right: 22px;
+}
+.ui-spinner-button {
+       width: 16px;
+       height: 50%;
+       font-size: .5em;
+       padding: 0;
+       margin: 0;
+       text-align: center;
+       position: absolute;
+       cursor: default;
+       display: block;
+       overflow: hidden;
+       right: 0;
+}
+/* more specificity required here to override default borders */
+.ui-spinner a.ui-spinner-button {
+       border-top: none;
+       border-bottom: none;
+       border-right: none;
+}
+/* vertically center icon */
+.ui-spinner .ui-icon {
+       position: absolute;
+       margin-top: -8px;
+       top: 50%;
+       left: 0;
+}
+.ui-spinner-up {
+       top: 0;
+}
+.ui-spinner-down {
+       bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+       /* need to fix icons sprite */
+       background-position: -65px -16px;
+}
+.ui-tabs {
+       position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+       padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+       margin: 0;
+       padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+       list-style: none;
+       float: left;
+       position: relative;
+       top: 0;
+       margin: 1px .2em 0 0;
+       border-bottom-width: 0;
+       padding: 0;
+       white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+       float: left;
+       padding: .5em 1em;
+       text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+       margin-bottom: -1px;
+       padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+       cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+       cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+       display: block;
+       border-width: 0;
+       padding: 1em 1.4em;
+       background: none;
+}
+.ui-tooltip {
+       padding: 8px;
+       position: absolute;
+       z-index: 9999;
+       max-width: 300px;
+       -webkit-box-shadow: 0 0 5px #aaa;
+       box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+       border-width: 2px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.structure.min.css
new file mode 100644 (file)
index 0000000..85b63cc
--- /dev/null
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.11.3 - 2015-03-01
+* http://jqueryui.com
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.css
new file mode 100644 (file)
index 0000000..22b988a
--- /dev/null
@@ -0,0 +1,410 @@
+/*!
+ * jQuery UI CSS Framework 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/theming/
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+       font-family: Verdana,Arial,sans-serif;
+       font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+       font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+       font-family: Verdana,Arial,sans-serif;
+       font-size: 1em;
+}
+.ui-widget-content {
+       border: 1px solid #aaaaaa;
+       background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
+       color: #222222;
+}
+.ui-widget-content a {
+       color: #222222;
+}
+.ui-widget-header {
+       border: 1px solid #aaaaaa;
+       background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
+       color: #222222;
+       font-weight: bold;
+}
+.ui-widget-header a {
+       color: #222222;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+       border: 1px solid #d3d3d3;
+       background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #555555;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+       color: #555555;
+       text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+       border: 1px solid #999999;
+       background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #212121;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited {
+       color: #212121;
+       text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+       border: 1px solid #aaaaaa;
+       background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+       font-weight: normal;
+       color: #212121;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+       color: #212121;
+       text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+       border: 1px solid #fcefa1;
+       background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
+       color: #363636;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+       color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+       border: 1px solid #cd0a0a;
+       background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
+       color: #cd0a0a;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+       color: #cd0a0a;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+       color: #cd0a0a;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+       font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+       opacity: .7;
+       filter:Alpha(Opacity=70); /* support: IE8 */
+       font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+       opacity: .35;
+       filter:Alpha(Opacity=35); /* support: IE8 */
+       background-image: none;
+}
+.ui-state-disabled .ui-icon {
+       filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       width: 16px;
+       height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+       background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-widget-header .ui-icon {
+       background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-state-default .ui-icon {
+       background-image: url("images/ui-icons_888888_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+       background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-active .ui-icon {
+       background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+       background-image: url("images/ui-icons_2e83ff_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+       background-image: url("images/ui-icons_cd0a0a_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+       border-top-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+       border-top-right-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+       border-bottom-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+       border-bottom-right-radius: 4px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+       background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+}
+.ui-widget-shadow {
+       margin: -8px 0 0 -8px;
+       padding: 8px;
+       background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+       border-radius: 8px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3.custom/jquery-ui.theme.min.css
new file mode 100644 (file)
index 0000000..16c531c
--- /dev/null
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.11.3 - 2015-03-03
+* http://jqueryui.com
+* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/external/jquery/jquery.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/external/jquery/jquery.js
new file mode 100644 (file)
index 0000000..c5c6482
--- /dev/null
@@ -0,0 +1,9789 @@
+/*!
+ * jQuery JavaScript Library v1.10.2
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03T13:48Z
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+       // The deferred used on DOM ready
+       readyList,
+
+       // A central reference to the root jQuery(document)
+       rootjQuery,
+
+       // Support: IE<10
+       // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
+       core_strundefined = typeof undefined,
+
+       // Use the correct document accordingly with window argument (sandbox)
+       location = window.location,
+       document = window.document,
+       docElem = document.documentElement,
+
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$,
+
+       // [[Class]] -> type pairs
+       class2type = {},
+
+       // List of deleted data cache ids, so we can reuse them
+       core_deletedIds = [],
+
+       core_version = "1.10.2",
+
+       // Save a reference to some core methods
+       core_concat = core_deletedIds.concat,
+       core_push = core_deletedIds.push,
+       core_slice = core_deletedIds.slice,
+       core_indexOf = core_deletedIds.indexOf,
+       core_toString = class2type.toString,
+       core_hasOwn = class2type.hasOwnProperty,
+       core_trim = core_version.trim,
+
+       // Define a local copy of jQuery
+       jQuery = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               return new jQuery.fn.init( selector, context, rootjQuery );
+       },
+
+       // Used for matching numbers
+       core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+       // Used for splitting on whitespace
+       core_rnotwhite = /\S+/g,
+
+       // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+       rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+       // A simple way to check for HTML strings
+       // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+       // Strict HTML recognition (#11290: must start with <)
+       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+       // Match a standalone tag
+       rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+       // JSON RegExp
+       rvalidchars = /^[\],:{}\s]*$/,
+       rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+       rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+       rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
+       // Matches dashed string for camelizing
+       rmsPrefix = /^-ms-/,
+       rdashAlpha = /-([\da-z])/gi,
+
+       // Used by jQuery.camelCase as callback to replace()
+       fcamelCase = function( all, letter ) {
+               return letter.toUpperCase();
+       },
+
+       // The ready event handler
+       completed = function( event ) {
+
+               // readyState === "complete" is good enough for us to call the dom ready in oldIE
+               if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+                       detach();
+                       jQuery.ready();
+               }
+       },
+       // Clean-up method for dom ready events
+       detach = function() {
+               if ( document.addEventListener ) {
+                       document.removeEventListener( "DOMContentLoaded", completed, false );
+                       window.removeEventListener( "load", completed, false );
+
+               } else {
+                       document.detachEvent( "onreadystatechange", completed );
+                       window.detachEvent( "onload", completed );
+               }
+       };
+
+jQuery.fn = jQuery.prototype = {
+       // The current version of jQuery being used
+       jquery: core_version,
+
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
+               var match, elem;
+
+               // HANDLE: $(""), $(null), $(undefined), $(false)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+                               // Assume that strings that start and end with <> are HTML and skip the regex check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = rquickExpr.exec( selector );
+                       }
+
+                       // Match html or make sure no context is specified for #id
+                       if ( match && (match[1] || !context) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
+
+                                       // scripts is true for back-compat
+                                       jQuery.merge( this, jQuery.parseHTML(
+                                               match[1],
+                                               context && context.nodeType ? context.ownerDocument || context : document,
+                                               true
+                                       ) );
+
+                                       // HANDLE: $(html, props)
+                                       if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+                                               for ( match in context ) {
+                                                       // Properties of context are called as methods if possible
+                                                       if ( jQuery.isFunction( this[ match ] ) ) {
+                                                               this[ match ]( context[ match ] );
+
+                                                       // ...and otherwise set as attributes
+                                                       } else {
+                                                               this.attr( match, context[ match ] );
+                                                       }
+                                               }
+                                       }
+
+                                       return this;
+
+                               // HANDLE: $(#id)
+                               } else {
+                                       elem = document.getElementById( match[2] );
+
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE and Opera return items
+                                               // by name instead of ID
+                                               if ( elem.id !== match[2] ) {
+                                                       return rootjQuery.find( selector );
+                                               }
+
+                                               // Otherwise, we inject the element directly into the jQuery object
+                                               this.length = 1;
+                                               this[0] = elem;
+                                       }
+
+                                       this.context = document;
+                                       this.selector = selector;
+                                       return this;
+                               }
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return ( context || rootjQuery ).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return this.constructor( context ).find( selector );
+                       }
+
+               // HANDLE: $(DOMElement)
+               } else if ( selector.nodeType ) {
+                       this.context = this[0] = selector;
+                       this.length = 1;
+                       return this;
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return rootjQuery.ready( selector );
+               }
+
+               if ( selector.selector !== undefined ) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
+               return jQuery.makeArray( selector, this );
+       },
+
+       // Start with an empty selector
+       selector: "",
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       toArray: function() {
+               return core_slice.call( this );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+               return num == null ?
+
+                       // Return a 'clean' array
+                       this.toArray() :
+
+                       // Return just the object
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems ) {
+
+               // Build a new jQuery matched element set
+               var ret = jQuery.merge( this.constructor(), elems );
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+               ret.context = this.context;
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       // (You can seed the arguments with an array of args, but this is
+       // only used internally.)
+       each: function( callback, args ) {
+               return jQuery.each( this, callback, args );
+       },
+
+       ready: function( fn ) {
+               // Add the callback
+               jQuery.ready.promise().done( fn );
+
+               return this;
+       },
+
+       slice: function() {
+               return this.pushStack( core_slice.apply( this, arguments ) );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       eq: function( i ) {
+               var len = this.length,
+                       j = +i + ( i < 0 ? len : 0 );
+               return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               }));
+       },
+
+       end: function() {
+               return this.prevObject || this.constructor(null);
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: core_push,
+       sort: [].sort,
+       splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+       var src, copyIsArray, copy, name, options, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+               target = arguments[1] || {};
+               // skip the boolean and the target
+               i = 2;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+               target = {};
+       }
+
+       // extend jQuery itself if only one argument is passed
+       if ( length === i ) {
+               target = this;
+               --i;
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && jQuery.isArray(src) ? src : [];
+
+                                       } else {
+                                               clone = src && jQuery.isPlainObject(src) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend({
+       // Unique for each copy of jQuery on the page
+       // Non-digits removed to match rinlinejQuery
+       expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+       noConflict: function( deep ) {
+               if ( window.$ === jQuery ) {
+                       window.$ = _$;
+               }
+
+               if ( deep && window.jQuery === jQuery ) {
+                       window.jQuery = _jQuery;
+               }
+
+               return jQuery;
+       },
+
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+
+       // A counter to track how many items to wait for before
+       // the ready event fires. See #6781
+       readyWait: 1,
+
+       // Hold (or release) the ready event
+       holdReady: function( hold ) {
+               if ( hold ) {
+                       jQuery.readyWait++;
+               } else {
+                       jQuery.ready( true );
+               }
+       },
+
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+
+               // Abort if there are pending holds or we're already ready
+               if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+                       return;
+               }
+
+               // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+               if ( !document.body ) {
+                       return setTimeout( jQuery.ready );
+               }
+
+               // Remember that the DOM is ready
+               jQuery.isReady = true;
+
+               // If a normal DOM Ready event fired, decrement, and wait if need be
+               if ( wait !== true && --jQuery.readyWait > 0 ) {
+                       return;
+               }
+
+               // If there are functions bound, to execute
+               readyList.resolveWith( document, [ jQuery ] );
+
+               // Trigger any bound ready events
+               if ( jQuery.fn.trigger ) {
+                       jQuery( document ).trigger("ready").off("ready");
+               }
+       },
+
+       // See test/unit/core.js for details concerning isFunction.
+       // Since version 1.3, DOM methods and functions like alert
+       // aren't supported. They return false on IE (#2968).
+       isFunction: function( obj ) {
+               return jQuery.type(obj) === "function";
+       },
+
+       isArray: Array.isArray || function( obj ) {
+               return jQuery.type(obj) === "array";
+       },
+
+       isWindow: function( obj ) {
+               /* jshint eqeqeq: false */
+               return obj != null && obj == obj.window;
+       },
+
+       isNumeric: function( obj ) {
+               return !isNaN( parseFloat(obj) ) && isFinite( obj );
+       },
+
+       type: function( obj ) {
+               if ( obj == null ) {
+                       return String( obj );
+               }
+               return typeof obj === "object" || typeof obj === "function" ?
+                       class2type[ core_toString.call(obj) ] || "object" :
+                       typeof obj;
+       },
+
+       isPlainObject: function( obj ) {
+               var key;
+
+               // Must be an Object.
+               // Because of IE, we also have to check the presence of the constructor property.
+               // Make sure that DOM nodes and window objects don't pass through, as well
+               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+                       return false;
+               }
+
+               try {
+                       // Not own constructor property must be Object
+                       if ( obj.constructor &&
+                               !core_hasOwn.call(obj, "constructor") &&
+                               !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+                               return false;
+                       }
+               } catch ( e ) {
+                       // IE8,9 Will throw exceptions on certain host objects #9897
+                       return false;
+               }
+
+               // Support: IE<9
+               // Handle iteration over inherited properties before own properties.
+               if ( jQuery.support.ownLast ) {
+                       for ( key in obj ) {
+                               return core_hasOwn.call( obj, key );
+                       }
+               }
+
+               // Own properties are enumerated firstly, so to speed up,
+               // if last one is own, then all properties are own.
+               for ( key in obj ) {}
+
+               return key === undefined || core_hasOwn.call( obj, key );
+       },
+
+       isEmptyObject: function( obj ) {
+               var name;
+               for ( name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+
+       error: function( msg ) {
+               throw new Error( msg );
+       },
+
+       // data: string of html
+       // context (optional): If specified, the fragment will be created in this context, defaults to document
+       // keepScripts (optional): If true, will include scripts passed in the html string
+       parseHTML: function( data, context, keepScripts ) {
+               if ( !data || typeof data !== "string" ) {
+                       return null;
+               }
+               if ( typeof context === "boolean" ) {
+                       keepScripts = context;
+                       context = false;
+               }
+               context = context || document;
+
+               var parsed = rsingleTag.exec( data ),
+                       scripts = !keepScripts && [];
+
+               // Single tag
+               if ( parsed ) {
+                       return [ context.createElement( parsed[1] ) ];
+               }
+
+               parsed = jQuery.buildFragment( [ data ], context, scripts );
+               if ( scripts ) {
+                       jQuery( scripts ).remove();
+               }
+               return jQuery.merge( [], parsed.childNodes );
+       },
+
+       parseJSON: function( data ) {
+               // Attempt to parse using the native JSON parser first
+               if ( window.JSON && window.JSON.parse ) {
+                       return window.JSON.parse( data );
+               }
+
+               if ( data === null ) {
+                       return data;
+               }
+
+               if ( typeof data === "string" ) {
+
+                       // Make sure leading/trailing whitespace is removed (IE can't handle it)
+                       data = jQuery.trim( data );
+
+                       if ( data ) {
+                               // Make sure the incoming data is actual JSON
+                               // Logic borrowed from http://json.org/json2.js
+                               if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+                                       .replace( rvalidtokens, "]" )
+                                       .replace( rvalidbraces, "")) ) {
+
+                                       return ( new Function( "return " + data ) )();
+                               }
+                       }
+               }
+
+               jQuery.error( "Invalid JSON: " + data );
+       },
+
+       // Cross-browser xml parsing
+       parseXML: function( data ) {
+               var xml, tmp;
+               if ( !data || typeof data !== "string" ) {
+                       return null;
+               }
+               try {
+                       if ( window.DOMParser ) { // Standard
+                               tmp = new DOMParser();
+                               xml = tmp.parseFromString( data , "text/xml" );
+                       } else { // IE
+                               xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                               xml.async = "false";
+                               xml.loadXML( data );
+                       }
+               } catch( e ) {
+                       xml = undefined;
+               }
+               if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+               return xml;
+       },
+
+       noop: function() {},
+
+       // Evaluates a script in a global context
+       // Workarounds based on findings by Jim Driscoll
+       // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+       globalEval: function( data ) {
+               if ( data && jQuery.trim( data ) ) {
+                       // We use execScript on Internet Explorer
+                       // We use an anonymous function so that context is window
+                       // rather than jQuery in Firefox
+                       ( window.execScript || function( data ) {
+                               window[ "eval" ].call( window, data );
+                       } )( data );
+               }
+       },
+
+       // Convert dashed to camelCase; used by the css and data modules
+       // Microsoft forgot to hump their vendor prefix (#9572)
+       camelCase: function( string ) {
+               return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+       },
+
+       nodeName: function( elem, name ) {
+               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+       },
+
+       // args is for internal usage only
+       each: function( obj, callback, args ) {
+               var value,
+                       i = 0,
+                       length = obj.length,
+                       isArray = isArraylike( obj );
+
+               if ( args ) {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               // A special, fast, case for the most common use of each
+               } else {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return obj;
+       },
+
+       // Use native String.trim function wherever possible
+       trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               core_trim.call( text );
+               } :
+
+               // Otherwise use our own trimming functionality
+               function( text ) {
+                       return text == null ?
+                               "" :
+                               ( text + "" ).replace( rtrim, "" );
+               },
+
+       // results is for internal usage only
+       makeArray: function( arr, results ) {
+               var ret = results || [];
+
+               if ( arr != null ) {
+                       if ( isArraylike( Object(arr) ) ) {
+                               jQuery.merge( ret,
+                                       typeof arr === "string" ?
+                                       [ arr ] : arr
+                               );
+                       } else {
+                               core_push.call( ret, arr );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, arr, i ) {
+               var len;
+
+               if ( arr ) {
+                       if ( core_indexOf ) {
+                               return core_indexOf.call( arr, elem, i );
+                       }
+
+                       len = arr.length;
+                       i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+                       for ( ; i < len; i++ ) {
+                               // Skip accessing in sparse arrays
+                               if ( i in arr && arr[ i ] === elem ) {
+                                       return i;
+                               }
+                       }
+               }
+
+               return -1;
+       },
+
+       merge: function( first, second ) {
+               var l = second.length,
+                       i = first.length,
+                       j = 0;
+
+               if ( typeof l === "number" ) {
+                       for ( ; j < l; j++ ) {
+                               first[ i++ ] = second[ j ];
+                       }
+               } else {
+                       while ( second[j] !== undefined ) {
+                               first[ i++ ] = second[ j++ ];
+                       }
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, inv ) {
+               var retVal,
+                       ret = [],
+                       i = 0,
+                       length = elems.length;
+               inv = !!inv;
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( ; i < length; i++ ) {
+                       retVal = !!callback( elems[ i ], i );
+                       if ( inv !== retVal ) {
+                               ret.push( elems[ i ] );
+                       }
+               }
+
+               return ret;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var value,
+                       i = 0,
+                       length = elems.length,
+                       isArray = isArraylike( elems ),
+                       ret = [];
+
+               // Go through the array, translating each of the items to their
+               if ( isArray ) {
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( i in elems ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret[ ret.length ] = value;
+                               }
+                       }
+               }
+
+               // Flatten any nested arrays
+               return core_concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               var args, proxy, tmp;
+
+               if ( typeof context === "string" ) {
+                       tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
+
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
+               }
+
+               // Simulated bind
+               args = core_slice.call( arguments, 2 );
+               proxy = function() {
+                       return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
+               };
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+               return proxy;
+       },
+
+       // Multifunctional method to get and set values of a collection
+       // The value/s can optionally be executed if it's a function
+       access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+               var i = 0,
+                       length = elems.length,
+                       bulk = key == null;
+
+               // Sets many values
+               if ( jQuery.type( key ) === "object" ) {
+                       chainable = true;
+                       for ( i in key ) {
+                               jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+                       }
+
+               // Sets one value
+               } else if ( value !== undefined ) {
+                       chainable = true;
+
+                       if ( !jQuery.isFunction( value ) ) {
+                               raw = true;
+                       }
+
+                       if ( bulk ) {
+                               // Bulk operations run against the entire set
+                               if ( raw ) {
+                                       fn.call( elems, value );
+                                       fn = null;
+
+                               // ...except when executing function values
+                               } else {
+                                       bulk = fn;
+                                       fn = function( elem, key, value ) {
+                                               return bulk.call( jQuery( elem ), value );
+                                       };
+                               }
+                       }
+
+                       if ( fn ) {
+                               for ( ; i < length; i++ ) {
+                                       fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+                               }
+                       }
+               }
+
+               return chainable ?
+                       elems :
+
+                       // Gets
+                       bulk ?
+                               fn.call( elems ) :
+                               length ? fn( elems[0], key ) : emptyGet;
+       },
+
+       now: function() {
+               return ( new Date() ).getTime();
+       },
+
+       // A method for quickly swapping in/out CSS properties to get correct calculations.
+       // Note: this method belongs to the css module but it's needed here for the support module.
+       // If support gets modularized, this method should be moved back to the css module.
+       swap: function( elem, options, callback, args ) {
+               var ret, name,
+                       old = {};
+
+               // Remember the old values, and insert the new ones
+               for ( name in options ) {
+                       old[ name ] = elem.style[ name ];
+                       elem.style[ name ] = options[ name ];
+               }
+
+               ret = callback.apply( elem, args || [] );
+
+               // Revert the old values
+               for ( name in options ) {
+                       elem.style[ name ] = old[ name ];
+               }
+
+               return ret;
+       }
+});
+
+jQuery.ready.promise = function( obj ) {
+       if ( !readyList ) {
+
+               readyList = jQuery.Deferred();
+
+               // Catch cases where $(document).ready() is called after the browser event has already occurred.
+               // we once tried to use readyState "interactive" here, but it caused issues like the one
+               // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+               if ( document.readyState === "complete" ) {
+                       // Handle it asynchronously to allow scripts the opportunity to delay ready
+                       setTimeout( jQuery.ready );
+
+               // Standards-based browsers support DOMContentLoaded
+               } else if ( document.addEventListener ) {
+                       // Use the handy event callback
+                       document.addEventListener( "DOMContentLoaded", completed, false );
+
+                       // A fallback to window.onload, that will always work
+                       window.addEventListener( "load", completed, false );
+
+               // If IE event model is used
+               } else {
+                       // Ensure firing before onload, maybe late but safe also for iframes
+                       document.attachEvent( "onreadystatechange", completed );
+
+                       // A fallback to window.onload, that will always work
+                       window.attachEvent( "onload", completed );
+
+                       // If IE and not a frame
+                       // continually check to see if the document is ready
+                       var top = false;
+
+                       try {
+                               top = window.frameElement == null && document.documentElement;
+                       } catch(e) {}
+
+                       if ( top && top.doScroll ) {
+                               (function doScrollCheck() {
+                                       if ( !jQuery.isReady ) {
+
+                                               try {
+                                                       // Use the trick by Diego Perini
+                                                       // http://javascript.nwbox.com/IEContentLoaded/
+                                                       top.doScroll("left");
+                                               } catch(e) {
+                                                       return setTimeout( doScrollCheck, 50 );
+                                               }
+
+                                               // detach all dom ready events
+                                               detach();
+
+                                               // and execute any waiting functions
+                                               jQuery.ready();
+                                       }
+                               })();
+                       }
+               }
+       }
+       return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+       class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+       var length = obj.length,
+               type = jQuery.type( obj );
+
+       if ( jQuery.isWindow( obj ) ) {
+               return false;
+       }
+
+       if ( obj.nodeType === 1 && length ) {
+               return true;
+       }
+
+       return type === "array" || type !== "function" &&
+               ( length === 0 ||
+               typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+/*!
+ * Sizzle CSS Selector Engine v1.10.2
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03
+ */
+(function( window, undefined ) {
+
+var i,
+       support,
+       cachedruns,
+       Expr,
+       getText,
+       isXML,
+       compile,
+       outermostContext,
+       sortInput,
+
+       // Local document vars
+       setDocument,
+       document,
+       docElem,
+       documentIsHTML,
+       rbuggyQSA,
+       rbuggyMatches,
+       matches,
+       contains,
+
+       // Instance-specific data
+       expando = "sizzle" + -(new Date()),
+       preferredDoc = window.document,
+       dirruns = 0,
+       done = 0,
+       classCache = createCache(),
+       tokenCache = createCache(),
+       compilerCache = createCache(),
+       hasDuplicate = false,
+       sortOrder = function( a, b ) {
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+               return 0;
+       },
+
+       // General-purpose constants
+       strundefined = typeof undefined,
+       MAX_NEGATIVE = 1 << 31,
+
+       // Instance methods
+       hasOwn = ({}).hasOwnProperty,
+       arr = [],
+       pop = arr.pop,
+       push_native = arr.push,
+       push = arr.push,
+       slice = arr.slice,
+       // Use a stripped-down indexOf if we can't use a native one
+       indexOf = arr.indexOf || function( elem ) {
+               var i = 0,
+                       len = this.length;
+               for ( ; i < len; i++ ) {
+                       if ( this[i] === elem ) {
+                               return i;
+                       }
+               }
+               return -1;
+       },
+
+       booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+       // Regular expressions
+
+       // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+       whitespace = "[\\x20\\t\\r\\n\\f]",
+       // http://www.w3.org/TR/css3-syntax/#characters
+       characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+       // Loosely modeled on CSS identifier characters
+       // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+       // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+       identifier = characterEncoding.replace( "w", "w#" ),
+
+       // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+       attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+               "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+       // Prefer arguments quoted,
+       //   then not containing pseudos/brackets,
+       //   then attribute selectors/non-parenthetical expressions,
+       //   then anything else
+       // These preferences are here to reduce the number of selectors
+       //   needing tokenize in the PSEUDO preFilter
+       pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+       rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+       rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+       rsibling = new RegExp( whitespace + "*[+~]" ),
+       rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
+
+       rpseudo = new RegExp( pseudos ),
+       ridentifier = new RegExp( "^" + identifier + "$" ),
+
+       matchExpr = {
+               "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+               "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+               "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+               "ATTR": new RegExp( "^" + attributes ),
+               "PSEUDO": new RegExp( "^" + pseudos ),
+               "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                       "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                       "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+               "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+               // For use in libraries implementing .is()
+               // We use this for POS matching in `select`
+               "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                       whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+       },
+
+       rnative = /^[^{]+\{\s*\[native \w/,
+
+       // Easily-parseable/retrievable ID or TAG or CLASS selectors
+       rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+       rinputs = /^(?:input|select|textarea|button)$/i,
+       rheader = /^h\d$/i,
+
+       rescape = /'|\\/g,
+
+       // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+       runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+       funescape = function( _, escaped, escapedWhitespace ) {
+               var high = "0x" + escaped - 0x10000;
+               // NaN means non-codepoint
+               // Support: Firefox
+               // Workaround erroneous numeric interpretation of +"0x"
+               return high !== high || escapedWhitespace ?
+                       escaped :
+                       // BMP codepoint
+                       high < 0 ?
+                               String.fromCharCode( high + 0x10000 ) :
+                               // Supplemental Plane codepoint (surrogate pair)
+                               String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+       };
+
+// Optimize for push.apply( _, NodeList )
+try {
+       push.apply(
+               (arr = slice.call( preferredDoc.childNodes )),
+               preferredDoc.childNodes
+       );
+       // Support: Android<4.0
+       // Detect silently failing push.apply
+       arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+       push = { apply: arr.length ?
+
+               // Leverage slice if possible
+               function( target, els ) {
+                       push_native.apply( target, slice.call(els) );
+               } :
+
+               // Support: IE<9
+               // Otherwise append directly
+               function( target, els ) {
+                       var j = target.length,
+                               i = 0;
+                       // Can't trust NodeList.length
+                       while ( (target[j++] = els[i++]) ) {}
+                       target.length = j - 1;
+               }
+       };
+}
+
+function Sizzle( selector, context, results, seed ) {
+       var match, elem, m, nodeType,
+               // QSA vars
+               i, groups, old, nid, newContext, newSelector;
+
+       if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+               setDocument( context );
+       }
+
+       context = context || document;
+       results = results || [];
+
+       if ( !selector || typeof selector !== "string" ) {
+               return results;
+       }
+
+       if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+               return [];
+       }
+
+       if ( documentIsHTML && !seed ) {
+
+               // Shortcuts
+               if ( (match = rquickExpr.exec( selector )) ) {
+                       // Speed-up: Sizzle("#ID")
+                       if ( (m = match[1]) ) {
+                               if ( nodeType === 9 ) {
+                                       elem = context.getElementById( m );
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE, Opera, and Webkit return items
+                                               // by name instead of ID
+                                               if ( elem.id === m ) {
+                                                       results.push( elem );
+                                                       return results;
+                                               }
+                                       } else {
+                                               return results;
+                                       }
+                               } else {
+                                       // Context is not a document
+                                       if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+                                               contains( context, elem ) && elem.id === m ) {
+                                               results.push( elem );
+                                               return results;
+                                       }
+                               }
+
+                       // Speed-up: Sizzle("TAG")
+                       } else if ( match[2] ) {
+                               push.apply( results, context.getElementsByTagName( selector ) );
+                               return results;
+
+                       // Speed-up: Sizzle(".CLASS")
+                       } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+                               push.apply( results, context.getElementsByClassName( m ) );
+                               return results;
+                       }
+               }
+
+               // QSA path
+               if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+                       nid = old = expando;
+                       newContext = context;
+                       newSelector = nodeType === 9 && selector;
+
+                       // qSA works strangely on Element-rooted queries
+                       // We can work around this by specifying an extra ID on the root
+                       // and working up from there (Thanks to Andrew Dupont for the technique)
+                       // IE 8 doesn't work on object elements
+                       if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+                               groups = tokenize( selector );
+
+                               if ( (old = context.getAttribute("id")) ) {
+                                       nid = old.replace( rescape, "\\$&" );
+                               } else {
+                                       context.setAttribute( "id", nid );
+                               }
+                               nid = "[id='" + nid + "'] ";
+
+                               i = groups.length;
+                               while ( i-- ) {
+                                       groups[i] = nid + toSelector( groups[i] );
+                               }
+                               newContext = rsibling.test( selector ) && context.parentNode || context;
+                               newSelector = groups.join(",");
+                       }
+
+                       if ( newSelector ) {
+                               try {
+                                       push.apply( results,
+                                               newContext.querySelectorAll( newSelector )
+                                       );
+                                       return results;
+                               } catch(qsaError) {
+                               } finally {
+                                       if ( !old ) {
+                                               context.removeAttribute("id");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // All others
+       return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *     property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *     deleting the oldest entry
+ */
+function createCache() {
+       var keys = [];
+
+       function cache( key, value ) {
+               // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+               if ( keys.push( key += " " ) > Expr.cacheLength ) {
+                       // Only keep the most recent entries
+                       delete cache[ keys.shift() ];
+               }
+               return (cache[ key ] = value);
+       }
+       return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+       fn[ expando ] = true;
+       return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+       var div = document.createElement("div");
+
+       try {
+               return !!fn( div );
+       } catch (e) {
+               return false;
+       } finally {
+               // Remove from its parent by default
+               if ( div.parentNode ) {
+                       div.parentNode.removeChild( div );
+               }
+               // release memory in IE
+               div = null;
+       }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+       var arr = attrs.split("|"),
+               i = attrs.length;
+
+       while ( i-- ) {
+               Expr.attrHandle[ arr[i] ] = handler;
+       }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+       var cur = b && a,
+               diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                       ( ~b.sourceIndex || MAX_NEGATIVE ) -
+                       ( ~a.sourceIndex || MAX_NEGATIVE );
+
+       // Use IE sourceIndex if available on both nodes
+       if ( diff ) {
+               return diff;
+       }
+
+       // Check if b follows a
+       if ( cur ) {
+               while ( (cur = cur.nextSibling) ) {
+                       if ( cur === b ) {
+                               return -1;
+                       }
+               }
+       }
+
+       return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return name === "input" && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return (name === "input" || name === "button") && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+       return markFunction(function( argument ) {
+               argument = +argument;
+               return markFunction(function( seed, matches ) {
+                       var j,
+                               matchIndexes = fn( [], seed.length, argument ),
+                               i = matchIndexes.length;
+
+                       // Match elements found at the specified indexes
+                       while ( i-- ) {
+                               if ( seed[ (j = matchIndexes[i]) ] ) {
+                                       seed[j] = !(matches[j] = seed[j]);
+                               }
+                       }
+               });
+       });
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+       // documentElement is verified for cases where it doesn't yet exist
+       // (such as loading iframes in IE - #4833)
+       var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+       return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+       var doc = node ? node.ownerDocument || node : preferredDoc,
+               parent = doc.defaultView;
+
+       // If no document and documentElement is available, return
+       if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+               return document;
+       }
+
+       // Set our document
+       document = doc;
+       docElem = doc.documentElement;
+
+       // Support tests
+       documentIsHTML = !isXML( doc );
+
+       // Support: IE>8
+       // If iframe document is assigned to "document" variable and if iframe has been reloaded,
+       // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+       // IE6-8 do not support the defaultView property so parent will be undefined
+       if ( parent && parent.attachEvent && parent !== parent.top ) {
+               parent.attachEvent( "onbeforeunload", function() {
+                       setDocument();
+               });
+       }
+
+       /* Attributes
+       ---------------------------------------------------------------------- */
+
+       // Support: IE<8
+       // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+       support.attributes = assert(function( div ) {
+               div.className = "i";
+               return !div.getAttribute("className");
+       });
+
+       /* getElement(s)By*
+       ---------------------------------------------------------------------- */
+
+       // Check if getElementsByTagName("*") returns only elements
+       support.getElementsByTagName = assert(function( div ) {
+               div.appendChild( doc.createComment("") );
+               return !div.getElementsByTagName("*").length;
+       });
+
+       // Check if getElementsByClassName can be trusted
+       support.getElementsByClassName = assert(function( div ) {
+               div.innerHTML = "<div class='a'></div><div class='a i'></div>";
+
+               // Support: Safari<4
+               // Catch class over-caching
+               div.firstChild.className = "i";
+               // Support: Opera<10
+               // Catch gEBCN failure to find non-leading classes
+               return div.getElementsByClassName("i").length === 2;
+       });
+
+       // Support: IE<10
+       // Check if getElementById returns elements by name
+       // The broken getElementById methods don't pick up programatically-set names,
+       // so use a roundabout getElementsByName test
+       support.getById = assert(function( div ) {
+               docElem.appendChild( div ).id = expando;
+               return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+       });
+
+       // ID find and filter
+       if ( support.getById ) {
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+                               var m = context.getElementById( id );
+                               // Check parentNode to catch when Blackberry 4.6 returns
+                               // nodes that are no longer in the document #6963
+                               return m && m.parentNode ? [m] : [];
+                       }
+               };
+               Expr.filter["ID"] = function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               return elem.getAttribute("id") === attrId;
+                       };
+               };
+       } else {
+               // Support: IE6/7
+               // getElementById is not reliable as a find shortcut
+               delete Expr.find["ID"];
+
+               Expr.filter["ID"] =  function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+                               return node && node.value === attrId;
+                       };
+               };
+       }
+
+       // Tag
+       Expr.find["TAG"] = support.getElementsByTagName ?
+               function( tag, context ) {
+                       if ( typeof context.getElementsByTagName !== strundefined ) {
+                               return context.getElementsByTagName( tag );
+                       }
+               } :
+               function( tag, context ) {
+                       var elem,
+                               tmp = [],
+                               i = 0,
+                               results = context.getElementsByTagName( tag );
+
+                       // Filter out possible comments
+                       if ( tag === "*" ) {
+                               while ( (elem = results[i++]) ) {
+                                       if ( elem.nodeType === 1 ) {
+                                               tmp.push( elem );
+                                       }
+                               }
+
+                               return tmp;
+                       }
+                       return results;
+               };
+
+       // Class
+       Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+               if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+                       return context.getElementsByClassName( className );
+               }
+       };
+
+       /* QSA/matchesSelector
+       ---------------------------------------------------------------------- */
+
+       // QSA and matchesSelector support
+
+       // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+       rbuggyMatches = [];
+
+       // qSa(:focus) reports false when true (Chrome 21)
+       // We allow this because of a bug in IE8/9 that throws an error
+       // whenever `document.activeElement` is accessed on an iframe
+       // So, we allow :focus to pass through QSA all the time to avoid the IE error
+       // See http://bugs.jquery.com/ticket/13378
+       rbuggyQSA = [];
+
+       if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+               // Build QSA regex
+               // Regex strategy adopted from Diego Perini
+               assert(function( div ) {
+                       // Select is set to empty string on purpose
+                       // This is to test IE's treatment of not explicitly
+                       // setting a boolean content attribute,
+                       // since its presence should be enough
+                       // http://bugs.jquery.com/ticket/12359
+                       div.innerHTML = "<select><option selected=''></option></select>";
+
+                       // Support: IE8
+                       // Boolean attributes and "value" are not treated correctly
+                       if ( !div.querySelectorAll("[selected]").length ) {
+                               rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+                       }
+
+                       // Webkit/Opera - :checked should return selected option elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":checked").length ) {
+                               rbuggyQSA.push(":checked");
+                       }
+               });
+
+               assert(function( div ) {
+
+                       // Support: Opera 10-12/IE8
+                       // ^= $= *= and empty values
+                       // Should not select anything
+                       // Support: Windows 8 Native Apps
+                       // The type attribute is restricted during .innerHTML assignment
+                       var input = doc.createElement("input");
+                       input.setAttribute( "type", "hidden" );
+                       div.appendChild( input ).setAttribute( "t", "" );
+
+                       if ( div.querySelectorAll("[t^='']").length ) {
+                               rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+                       }
+
+                       // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":enabled").length ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Opera 10-11 does not throw on post-comma invalid pseudos
+                       div.querySelectorAll("*,:x");
+                       rbuggyQSA.push(",.*:");
+               });
+       }
+
+       if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
+               docElem.mozMatchesSelector ||
+               docElem.oMatchesSelector ||
+               docElem.msMatchesSelector) )) ) {
+
+               assert(function( div ) {
+                       // Check to see if it's possible to do matchesSelector
+                       // on a disconnected node (IE 9)
+                       support.disconnectedMatch = matches.call( div, "div" );
+
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( div, "[s!='']:x" );
+                       rbuggyMatches.push( "!=", pseudos );
+               });
+       }
+
+       rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+       rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+       /* Contains
+       ---------------------------------------------------------------------- */
+
+       // Element contains another
+       // Purposefully does not implement inclusive descendent
+       // As in, an element does not contain itself
+       contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
+               function( a, b ) {
+                       var adown = a.nodeType === 9 ? a.documentElement : a,
+                               bup = b && b.parentNode;
+                       return a === bup || !!( bup && bup.nodeType === 1 && (
+                               adown.contains ?
+                                       adown.contains( bup ) :
+                                       a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+                       ));
+               } :
+               function( a, b ) {
+                       if ( b ) {
+                               while ( (b = b.parentNode) ) {
+                                       if ( b === a ) {
+                                               return true;
+                                       }
+                               }
+                       }
+                       return false;
+               };
+
+       /* Sorting
+       ---------------------------------------------------------------------- */
+
+       // Document order sorting
+       sortOrder = docElem.compareDocumentPosition ?
+       function( a, b ) {
+
+               // Flag for duplicate removal
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
+
+               if ( compare ) {
+                       // Disconnected nodes
+                       if ( compare & 1 ||
+                               (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+                               // Choose the first element that is related to our preferred document
+                               if ( a === doc || contains(preferredDoc, a) ) {
+                                       return -1;
+                               }
+                               if ( b === doc || contains(preferredDoc, b) ) {
+                                       return 1;
+                               }
+
+                               // Maintain original order
+                               return sortInput ?
+                                       ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                                       0;
+                       }
+
+                       return compare & 4 ? -1 : 1;
+               }
+
+               // Not directly comparable, sort on existence of method
+               return a.compareDocumentPosition ? -1 : 1;
+       } :
+       function( a, b ) {
+               var cur,
+                       i = 0,
+                       aup = a.parentNode,
+                       bup = b.parentNode,
+                       ap = [ a ],
+                       bp = [ b ];
+
+               // Exit early if the nodes are identical
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+
+               // Parentless nodes are either documents or disconnected
+               } else if ( !aup || !bup ) {
+                       return a === doc ? -1 :
+                               b === doc ? 1 :
+                               aup ? -1 :
+                               bup ? 1 :
+                               sortInput ?
+                               ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                               0;
+
+               // If the nodes are siblings, we can do a quick check
+               } else if ( aup === bup ) {
+                       return siblingCheck( a, b );
+               }
+
+               // Otherwise we need full lists of their ancestors for comparison
+               cur = a;
+               while ( (cur = cur.parentNode) ) {
+                       ap.unshift( cur );
+               }
+               cur = b;
+               while ( (cur = cur.parentNode) ) {
+                       bp.unshift( cur );
+               }
+
+               // Walk down the tree looking for a discrepancy
+               while ( ap[i] === bp[i] ) {
+                       i++;
+               }
+
+               return i ?
+                       // Do a sibling check if the nodes have a common ancestor
+                       siblingCheck( ap[i], bp[i] ) :
+
+                       // Otherwise nodes in our document sort first
+                       ap[i] === preferredDoc ? -1 :
+                       bp[i] === preferredDoc ? 1 :
+                       0;
+       };
+
+       return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+       return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       // Make sure that attribute selectors are quoted
+       expr = expr.replace( rattributeQuotes, "='$1']" );
+
+       if ( support.matchesSelector && documentIsHTML &&
+               ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+               ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+               try {
+                       var ret = matches.call( elem, expr );
+
+                       // IE 9's matchesSelector returns false on disconnected nodes
+                       if ( ret || support.disconnectedMatch ||
+                                       // As well, disconnected nodes are said to be in a document
+                                       // fragment in IE 9
+                                       elem.document && elem.document.nodeType !== 11 ) {
+                               return ret;
+                       }
+               } catch(e) {}
+       }
+
+       return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+       // Set document vars if needed
+       if ( ( context.ownerDocument || context ) !== document ) {
+               setDocument( context );
+       }
+       return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       var fn = Expr.attrHandle[ name.toLowerCase() ],
+               // Don't get fooled by Object.prototype properties (jQuery #13807)
+               val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+                       fn( elem, name, !documentIsHTML ) :
+                       undefined;
+
+       return val === undefined ?
+               support.attributes || !documentIsHTML ?
+                       elem.getAttribute( name ) :
+                       (val = elem.getAttributeNode(name)) && val.specified ?
+                               val.value :
+                               null :
+               val;
+};
+
+Sizzle.error = function( msg ) {
+       throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+       var elem,
+               duplicates = [],
+               j = 0,
+               i = 0;
+
+       // Unless we *know* we can detect duplicates, assume their presence
+       hasDuplicate = !support.detectDuplicates;
+       sortInput = !support.sortStable && results.slice( 0 );
+       results.sort( sortOrder );
+
+       if ( hasDuplicate ) {
+               while ( (elem = results[i++]) ) {
+                       if ( elem === results[ i ] ) {
+                               j = duplicates.push( i );
+                       }
+               }
+               while ( j-- ) {
+                       results.splice( duplicates[ j ], 1 );
+               }
+       }
+
+       return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+       var node,
+               ret = "",
+               i = 0,
+               nodeType = elem.nodeType;
+
+       if ( !nodeType ) {
+               // If no nodeType, this is expected to be an array
+               for ( ; (node = elem[i]); i++ ) {
+                       // Do not traverse comment nodes
+                       ret += getText( node );
+               }
+       } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+               // Use textContent for elements
+               // innerText usage removed for consistency of new lines (see #11153)
+               if ( typeof elem.textContent === "string" ) {
+                       return elem.textContent;
+               } else {
+                       // Traverse its children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               ret += getText( elem );
+                       }
+               }
+       } else if ( nodeType === 3 || nodeType === 4 ) {
+               return elem.nodeValue;
+       }
+       // Do not include comment or processing instruction nodes
+
+       return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+       // Can be adjusted by the user
+       cacheLength: 50,
+
+       createPseudo: markFunction,
+
+       match: matchExpr,
+
+       attrHandle: {},
+
+       find: {},
+
+       relative: {
+               ">": { dir: "parentNode", first: true },
+               " ": { dir: "parentNode" },
+               "+": { dir: "previousSibling", first: true },
+               "~": { dir: "previousSibling" }
+       },
+
+       preFilter: {
+               "ATTR": function( match ) {
+                       match[1] = match[1].replace( runescape, funescape );
+
+                       // Move the given value to match[3] whether quoted or unquoted
+                       match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+                       if ( match[2] === "~=" ) {
+                               match[3] = " " + match[3] + " ";
+                       }
+
+                       return match.slice( 0, 4 );
+               },
+
+               "CHILD": function( match ) {
+                       /* matches from matchExpr["CHILD"]
+                               1 type (only|nth|...)
+                               2 what (child|of-type)
+                               3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                               4 xn-component of xn+y argument ([+-]?\d*n|)
+                               5 sign of xn-component
+                               6 x of xn-component
+                               7 sign of y-component
+                               8 y of y-component
+                       */
+                       match[1] = match[1].toLowerCase();
+
+                       if ( match[1].slice( 0, 3 ) === "nth" ) {
+                               // nth-* requires argument
+                               if ( !match[3] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               // numeric x and y parameters for Expr.filter.CHILD
+                               // remember that false/true cast respectively to 0/1
+                               match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+                               match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+                       // other types prohibit arguments
+                       } else if ( match[3] ) {
+                               Sizzle.error( match[0] );
+                       }
+
+                       return match;
+               },
+
+               "PSEUDO": function( match ) {
+                       var excess,
+                               unquoted = !match[5] && match[2];
+
+                       if ( matchExpr["CHILD"].test( match[0] ) ) {
+                               return null;
+                       }
+
+                       // Accept quoted arguments as-is
+                       if ( match[3] && match[4] !== undefined ) {
+                               match[2] = match[4];
+
+                       // Strip excess characters from unquoted arguments
+                       } else if ( unquoted && rpseudo.test( unquoted ) &&
+                               // Get excess from tokenize (recursively)
+                               (excess = tokenize( unquoted, true )) &&
+                               // advance to the next closing parenthesis
+                               (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+                               // excess is a negative index
+                               match[0] = match[0].slice( 0, excess );
+                               match[2] = unquoted.slice( 0, excess );
+                       }
+
+                       // Return only captures needed by the pseudo filter method (type and argument)
+                       return match.slice( 0, 3 );
+               }
+       },
+
+       filter: {
+
+               "TAG": function( nodeNameSelector ) {
+                       var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+                       return nodeNameSelector === "*" ?
+                               function() { return true; } :
+                               function( elem ) {
+                                       return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                               };
+               },
+
+               "CLASS": function( className ) {
+                       var pattern = classCache[ className + " " ];
+
+                       return pattern ||
+                               (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+                               classCache( className, function( elem ) {
+                                       return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+                               });
+               },
+
+               "ATTR": function( name, operator, check ) {
+                       return function( elem ) {
+                               var result = Sizzle.attr( elem, name );
+
+                               if ( result == null ) {
+                                       return operator === "!=";
+                               }
+                               if ( !operator ) {
+                                       return true;
+                               }
+
+                               result += "";
+
+                               return operator === "=" ? result === check :
+                                       operator === "!=" ? result !== check :
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :
+                                       operator === "$=" ? check && result.slice( -check.length ) === check :
+                                       operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+                                       operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+                                       false;
+                       };
+               },
+
+               "CHILD": function( type, what, argument, first, last ) {
+                       var simple = type.slice( 0, 3 ) !== "nth",
+                               forward = type.slice( -4 ) !== "last",
+                               ofType = what === "of-type";
+
+                       return first === 1 && last === 0 ?
+
+                               // Shortcut for :nth-*(n)
+                               function( elem ) {
+                                       return !!elem.parentNode;
+                               } :
+
+                               function( elem, context, xml ) {
+                                       var cache, outerCache, node, diff, nodeIndex, start,
+                                               dir = simple !== forward ? "nextSibling" : "previousSibling",
+                                               parent = elem.parentNode,
+                                               name = ofType && elem.nodeName.toLowerCase(),
+                                               useCache = !xml && !ofType;
+
+                                       if ( parent ) {
+
+                                               // :(first|last|only)-(child|of-type)
+                                               if ( simple ) {
+                                                       while ( dir ) {
+                                                               node = elem;
+                                                               while ( (node = node[ dir ]) ) {
+                                                                       if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+                                                                               return false;
+                                                                       }
+                                                               }
+                                                               // Reverse direction for :only-* (if we haven't yet done so)
+                                                               start = dir = type === "only" && !start && "nextSibling";
+                                                       }
+                                                       return true;
+                                               }
+
+                                               start = [ forward ? parent.firstChild : parent.lastChild ];
+
+                                               // non-xml :nth-child(...) stores cache data on `parent`
+                                               if ( forward && useCache ) {
+                                                       // Seek `elem` from a previously-cached index
+                                                       outerCache = parent[ expando ] || (parent[ expando ] = {});
+                                                       cache = outerCache[ type ] || [];
+                                                       nodeIndex = cache[0] === dirruns && cache[1];
+                                                       diff = cache[0] === dirruns && cache[2];
+                                                       node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+                                                               // Fallback to seeking `elem` from the start
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               // When found, cache indexes on `parent` and break
+                                                               if ( node.nodeType === 1 && ++diff && node === elem ) {
+                                                                       outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+                                                                       break;
+                                                               }
+                                                       }
+
+                                               // Use previously-cached element index if available
+                                               } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+                                                       diff = cache[1];
+
+                                               // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+                                               } else {
+                                                       // Use the same loop as above to seek `elem` from the start
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+                                                                       // Cache the index of each encountered element
+                                                                       if ( useCache ) {
+                                                                               (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+                                                                       }
+
+                                                                       if ( node === elem ) {
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               // Incorporate the offset, then check against cycle size
+                                               diff -= last;
+                                               return diff === first || ( diff % first === 0 && diff / first >= 0 );
+                                       }
+                               };
+               },
+
+               "PSEUDO": function( pseudo, argument ) {
+                       // pseudo-class names are case-insensitive
+                       // http://www.w3.org/TR/selectors/#pseudo-classes
+                       // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+                       // Remember that setFilters inherits from pseudos
+                       var args,
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );
+
+                       // The user may use createPseudo to indicate that
+                       // arguments are needed to create the filter function
+                       // just as Sizzle does
+                       if ( fn[ expando ] ) {
+                               return fn( argument );
+                       }
+
+                       // But maintain support for old signatures
+                       if ( fn.length > 1 ) {
+                               args = [ pseudo, pseudo, "", argument ];
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                                       markFunction(function( seed, matches ) {
+                                               var idx,
+                                                       matched = fn( seed, argument ),
+                                                       i = matched.length;
+                                               while ( i-- ) {
+                                                       idx = indexOf.call( seed, matched[i] );
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );
+                                               }
+                                       }) :
+                                       function( elem ) {
+                                               return fn( elem, 0, args );
+                                       };
+                       }
+
+                       return fn;
+               }
+       },
+
+       pseudos: {
+               // Potentially complex pseudos
+               "not": markFunction(function( selector ) {
+                       // Trim the selector passed to compile
+                       // to avoid treating leading and trailing
+                       // spaces as combinators
+                       var input = [],
+                               results = [],
+                               matcher = compile( selector.replace( rtrim, "$1" ) );
+
+                       return matcher[ expando ] ?
+                               markFunction(function( seed, matches, context, xml ) {
+                                       var elem,
+                                               unmatched = matcher( seed, null, xml, [] ),
+                                               i = seed.length;
+
+                                       // Match elements unmatched by `matcher`
+                                       while ( i-- ) {
+                                               if ( (elem = unmatched[i]) ) {
+                                                       seed[i] = !(matches[i] = elem);
+                                               }
+                                       }
+                               }) :
+                               function( elem, context, xml ) {
+                                       input[0] = elem;
+                                       matcher( input, null, xml, results );
+                                       return !results.pop();
+                               };
+               }),
+
+               "has": markFunction(function( selector ) {
+                       return function( elem ) {
+                               return Sizzle( selector, elem ).length > 0;
+                       };
+               }),
+
+               "contains": markFunction(function( text ) {
+                       return function( elem ) {
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+                       };
+               }),
+
+               // "Whether an element is represented by a :lang() selector
+               // is based solely on the element's language value
+               // being equal to the identifier C,
+               // or beginning with the identifier C immediately followed by "-".
+               // The matching of C against the element's language value is performed case-insensitively.
+               // The identifier C does not have to be a valid language name."
+               // http://www.w3.org/TR/selectors/#lang-pseudo
+               "lang": markFunction( function( lang ) {
+                       // lang value must be a valid identifier
+                       if ( !ridentifier.test(lang || "") ) {
+                               Sizzle.error( "unsupported lang: " + lang );
+                       }
+                       lang = lang.replace( runescape, funescape ).toLowerCase();
+                       return function( elem ) {
+                               var elemLang;
+                               do {
+                                       if ( (elemLang = documentIsHTML ?
+                                               elem.lang :
+                                               elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+                                               elemLang = elemLang.toLowerCase();
+                                               return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+                                       }
+                               } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                               return false;
+                       };
+               }),
+
+               // Miscellaneous
+               "target": function( elem ) {
+                       var hash = window.location && window.location.hash;
+                       return hash && hash.slice( 1 ) === elem.id;
+               },
+
+               "root": function( elem ) {
+                       return elem === docElem;
+               },
+
+               "focus": function( elem ) {
+                       return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+               },
+
+               // Boolean properties
+               "enabled": function( elem ) {
+                       return elem.disabled === false;
+               },
+
+               "disabled": function( elem ) {
+                       return elem.disabled === true;
+               },
+
+               "checked": function( elem ) {
+                       // In CSS3, :checked should return both checked and selected elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       var nodeName = elem.nodeName.toLowerCase();
+                       return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+               },
+
+               "selected": function( elem ) {
+                       // Accessing this property makes selected-by-default
+                       // options in Safari work properly
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
+
+                       return elem.selected === true;
+               },
+
+               // Contents
+               "empty": function( elem ) {
+                       // http://www.w3.org/TR/selectors/#empty-pseudo
+                       // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+                       //   not comment, processing instructions, or others
+                       // Thanks to Diego Perini for the nodeName shortcut
+                       //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               },
+
+               "parent": function( elem ) {
+                       return !Expr.pseudos["empty"]( elem );
+               },
+
+               // Element/input types
+               "header": function( elem ) {
+                       return rheader.test( elem.nodeName );
+               },
+
+               "input": function( elem ) {
+                       return rinputs.test( elem.nodeName );
+               },
+
+               "button": function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && elem.type === "button" || name === "button";
+               },
+
+               "text": function( elem ) {
+                       var attr;
+                       // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+                       // use getAttribute instead to test this case
+                       return elem.nodeName.toLowerCase() === "input" &&
+                               elem.type === "text" &&
+                               ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+               },
+
+               // Position-in-collection
+               "first": createPositionalPseudo(function() {
+                       return [ 0 ];
+               }),
+
+               "last": createPositionalPseudo(function( matchIndexes, length ) {
+                       return [ length - 1 ];
+               }),
+
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       return [ argument < 0 ? argument + length : argument ];
+               }),
+
+               "even": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 0;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "odd": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 1;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; --i >= 0; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; ++i < length; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               })
+       }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+       Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+       Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+function tokenize( selector, parseOnly ) {
+       var matched, match, tokens, type,
+               soFar, groups, preFilters,
+               cached = tokenCache[ selector + " " ];
+
+       if ( cached ) {
+               return parseOnly ? 0 : cached.slice( 0 );
+       }
+
+       soFar = selector;
+       groups = [];
+       preFilters = Expr.preFilter;
+
+       while ( soFar ) {
+
+               // Comma and first run
+               if ( !matched || (match = rcomma.exec( soFar )) ) {
+                       if ( match ) {
+                               // Don't consume trailing commas as valid
+                               soFar = soFar.slice( match[0].length ) || soFar;
+                       }
+                       groups.push( tokens = [] );
+               }
+
+               matched = false;
+
+               // Combinators
+               if ( (match = rcombinators.exec( soFar )) ) {
+                       matched = match.shift();
+                       tokens.push({
+                               value: matched,
+                               // Cast descendant combinators to space
+                               type: match[0].replace( rtrim, " " )
+                       });
+                       soFar = soFar.slice( matched.length );
+               }
+
+               // Filters
+               for ( type in Expr.filter ) {
+                       if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+                               (match = preFilters[ type ]( match ))) ) {
+                               matched = match.shift();
+                               tokens.push({
+                                       value: matched,
+                                       type: type,
+                                       matches: match
+                               });
+                               soFar = soFar.slice( matched.length );
+                       }
+               }
+
+               if ( !matched ) {
+                       break;
+               }
+       }
+
+       // Return the length of the invalid excess
+       // if we're just parsing
+       // Otherwise, throw an error or return tokens
+       return parseOnly ?
+               soFar.length :
+               soFar ?
+                       Sizzle.error( selector ) :
+                       // Cache the tokens
+                       tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+       var i = 0,
+               len = tokens.length,
+               selector = "";
+       for ( ; i < len; i++ ) {
+               selector += tokens[i].value;
+       }
+       return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+       var dir = combinator.dir,
+               checkNonElements = base && dir === "parentNode",
+               doneName = done++;
+
+       return combinator.first ?
+               // Check against closest ancestor/preceding element
+               function( elem, context, xml ) {
+                       while ( (elem = elem[ dir ]) ) {
+                               if ( elem.nodeType === 1 || checkNonElements ) {
+                                       return matcher( elem, context, xml );
+                               }
+                       }
+               } :
+
+               // Check against all ancestor/preceding elements
+               function( elem, context, xml ) {
+                       var data, cache, outerCache,
+                               dirkey = dirruns + " " + doneName;
+
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+                       if ( xml ) {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       } else {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               outerCache = elem[ expando ] || (elem[ expando ] = {});
+                                               if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+                                                       if ( (data = cache[1]) === true || data === cachedruns ) {
+                                                               return data === true;
+                                                       }
+                                               } else {
+                                                       cache = outerCache[ dir ] = [ dirkey ];
+                                                       cache[1] = matcher( elem, context, xml ) || cachedruns;
+                                                       if ( cache[1] === true ) {
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               };
+}
+
+function elementMatcher( matchers ) {
+       return matchers.length > 1 ?
+               function( elem, context, xml ) {
+                       var i = matchers.length;
+                       while ( i-- ) {
+                               if ( !matchers[i]( elem, context, xml ) ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               } :
+               matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+       var elem,
+               newUnmatched = [],
+               i = 0,
+               len = unmatched.length,
+               mapped = map != null;
+
+       for ( ; i < len; i++ ) {
+               if ( (elem = unmatched[i]) ) {
+                       if ( !filter || filter( elem, context, xml ) ) {
+                               newUnmatched.push( elem );
+                               if ( mapped ) {
+                                       map.push( i );
+                               }
+                       }
+               }
+       }
+
+       return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+       if ( postFilter && !postFilter[ expando ] ) {
+               postFilter = setMatcher( postFilter );
+       }
+       if ( postFinder && !postFinder[ expando ] ) {
+               postFinder = setMatcher( postFinder, postSelector );
+       }
+       return markFunction(function( seed, results, context, xml ) {
+               var temp, i, elem,
+                       preMap = [],
+                       postMap = [],
+                       preexisting = results.length,
+
+                       // Get initial elements from seed or context
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization
+                       matcherIn = preFilter && ( seed || !selector ) ?
+                               condense( elems, preMap, preFilter, context, xml ) :
+                               elems,
+
+                       matcherOut = matcher ?
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+                                       // ...intermediate processing is necessary
+                                       [] :
+
+                                       // ...otherwise use results directly
+                                       results :
+                               matcherIn;
+
+               // Find primary matches
+               if ( matcher ) {
+                       matcher( matcherIn, matcherOut, context, xml );
+               }
+
+               // Apply postFilter
+               if ( postFilter ) {
+                       temp = condense( matcherOut, postMap );
+                       postFilter( temp, [], context, xml );
+
+                       // Un-match failing elements by moving them back to matcherIn
+                       i = temp.length;
+                       while ( i-- ) {
+                               if ( (elem = temp[i]) ) {
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                               }
+                       }
+               }
+
+               if ( seed ) {
+                       if ( postFinder || preFilter ) {
+                               if ( postFinder ) {
+                                       // Get the final matcherOut by condensing this intermediate into postFinder contexts
+                                       temp = [];
+                                       i = matcherOut.length;
+                                       while ( i-- ) {
+                                               if ( (elem = matcherOut[i]) ) {
+                                                       // Restore matcherIn since elem is not yet a final match
+                                                       temp.push( (matcherIn[i] = elem) );
+                                               }
+                                       }
+                                       postFinder( null, (matcherOut = []), temp, xml );
+                               }
+
+                               // Move matched elements from seed to results to keep them synchronized
+                               i = matcherOut.length;
+                               while ( i-- ) {
+                                       if ( (elem = matcherOut[i]) &&
+                                               (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+                                               seed[temp] = !(results[temp] = elem);
+                                       }
+                               }
+                       }
+
+               // Add elements to results, through postFinder if defined
+               } else {
+                       matcherOut = condense(
+                               matcherOut === results ?
+                                       matcherOut.splice( preexisting, matcherOut.length ) :
+                                       matcherOut
+                       );
+                       if ( postFinder ) {
+                               postFinder( null, results, matcherOut, xml );
+                       } else {
+                               push.apply( results, matcherOut );
+                       }
+               }
+       });
+}
+
+function matcherFromTokens( tokens ) {
+       var checkContext, matcher, j,
+               len = tokens.length,
+               leadingRelative = Expr.relative[ tokens[0].type ],
+               implicitRelative = leadingRelative || Expr.relative[" "],
+               i = leadingRelative ? 1 : 0,
+
+               // The foundational matcher ensures that elements are reachable from top-level context(s)
+               matchContext = addCombinator( function( elem ) {
+                       return elem === checkContext;
+               }, implicitRelative, true ),
+               matchAnyContext = addCombinator( function( elem ) {
+                       return indexOf.call( checkContext, elem ) > -1;
+               }, implicitRelative, true ),
+               matchers = [ function( elem, context, xml ) {
+                       return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+                               (checkContext = context).nodeType ?
+                                       matchContext( elem, context, xml ) :
+                                       matchAnyContext( elem, context, xml ) );
+               } ];
+
+       for ( ; i < len; i++ ) {
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+                       matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+               } else {
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+                       // Return special upon seeing a positional matcher
+                       if ( matcher[ expando ] ) {
+                               // Find the next relative operator (if any) for proper handling
+                               j = ++i;
+                               for ( ; j < len; j++ ) {
+                                       if ( Expr.relative[ tokens[j].type ] ) {
+                                               break;
+                                       }
+                               }
+                               return setMatcher(
+                                       i > 1 && elementMatcher( matchers ),
+                                       i > 1 && toSelector(
+                                               // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+                                               tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+                                       ).replace( rtrim, "$1" ),
+                                       matcher,
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+                                       j < len && toSelector( tokens )
+                               );
+                       }
+                       matchers.push( matcher );
+               }
+       }
+
+       return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+       // A counter to specify which element is currently being matched
+       var matcherCachedRuns = 0,
+               bySet = setMatchers.length > 0,
+               byElement = elementMatchers.length > 0,
+               superMatcher = function( seed, context, xml, results, expandContext ) {
+                       var elem, j, matcher,
+                               setMatched = [],
+                               matchedCount = 0,
+                               i = "0",
+                               unmatched = seed && [],
+                               outermost = expandContext != null,
+                               contextBackup = outermostContext,
+                               // We must always have either seed elements or context
+                               elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+                               // Use integer dirruns iff this is the outermost matcher
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+                       if ( outermost ) {
+                               outermostContext = context !== document && context;
+                               cachedruns = matcherCachedRuns;
+                       }
+
+                       // Add elements passing elementMatchers directly to results
+                       // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+                       for ( ; (elem = elems[i]) != null; i++ ) {
+                               if ( byElement && elem ) {
+                                       j = 0;
+                                       while ( (matcher = elementMatchers[j++]) ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       results.push( elem );
+                                                       break;
+                                               }
+                                       }
+                                       if ( outermost ) {
+                                               dirruns = dirrunsUnique;
+                                               cachedruns = ++matcherCachedRuns;
+                                       }
+                               }
+
+                               // Track unmatched elements for set filters
+                               if ( bySet ) {
+                                       // They will have gone through all possible matchers
+                                       if ( (elem = !matcher && elem) ) {
+                                               matchedCount--;
+                                       }
+
+                                       // Lengthen the array for every element, matched or not
+                                       if ( seed ) {
+                                               unmatched.push( elem );
+                                       }
+                               }
+                       }
+
+                       // Apply set filters to unmatched elements
+                       matchedCount += i;
+                       if ( bySet && i !== matchedCount ) {
+                               j = 0;
+                               while ( (matcher = setMatchers[j++]) ) {
+                                       matcher( unmatched, setMatched, context, xml );
+                               }
+
+                               if ( seed ) {
+                                       // Reintegrate element matches to eliminate the need for sorting
+                                       if ( matchedCount > 0 ) {
+                                               while ( i-- ) {
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {
+                                                               setMatched[i] = pop.call( results );
+                                                       }
+                                               }
+                                       }
+
+                                       // Discard index placeholder values to get only actual matches
+                                       setMatched = condense( setMatched );
+                               }
+
+                               // Add matches to results
+                               push.apply( results, setMatched );
+
+                               // Seedless set matches succeeding multiple successful matchers stipulate sorting
+                               if ( outermost && !seed && setMatched.length > 0 &&
+                                       ( matchedCount + setMatchers.length ) > 1 ) {
+
+                                       Sizzle.uniqueSort( results );
+                               }
+                       }
+
+                       // Override manipulation of globals by nested matchers
+                       if ( outermost ) {
+                               dirruns = dirrunsUnique;
+                               outermostContext = contextBackup;
+                       }
+
+                       return unmatched;
+               };
+
+       return bySet ?
+               markFunction( superMatcher ) :
+               superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+       var i,
+               setMatchers = [],
+               elementMatchers = [],
+               cached = compilerCache[ selector + " " ];
+
+       if ( !cached ) {
+               // Generate a function of recursive functions that can be used to check each element
+               if ( !group ) {
+                       group = tokenize( selector );
+               }
+               i = group.length;
+               while ( i-- ) {
+                       cached = matcherFromTokens( group[i] );
+                       if ( cached[ expando ] ) {
+                               setMatchers.push( cached );
+                       } else {
+                               elementMatchers.push( cached );
+                       }
+               }
+
+               // Cache the compiled function
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+       }
+       return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+       var i = 0,
+               len = contexts.length;
+       for ( ; i < len; i++ ) {
+               Sizzle( selector, contexts[i], results );
+       }
+       return results;
+}
+
+function select( selector, context, results, seed ) {
+       var i, tokens, token, type, find,
+               match = tokenize( selector );
+
+       if ( !seed ) {
+               // Try to minimize operations if there is only one group
+               if ( match.length === 1 ) {
+
+                       // Take a shortcut and set the context if the root selector is an ID
+                       tokens = match[0] = match[0].slice( 0 );
+                       if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                                       support.getById && context.nodeType === 9 && documentIsHTML &&
+                                       Expr.relative[ tokens[1].type ] ) {
+
+                               context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+                               if ( !context ) {
+                                       return results;
+                               }
+                               selector = selector.slice( tokens.shift().value.length );
+                       }
+
+                       // Fetch a seed set for right-to-left matching
+                       i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+                       while ( i-- ) {
+                               token = tokens[i];
+
+                               // Abort if we hit a combinator
+                               if ( Expr.relative[ (type = token.type) ] ) {
+                                       break;
+                               }
+                               if ( (find = Expr.find[ type ]) ) {
+                                       // Search, expanding context for leading sibling combinators
+                                       if ( (seed = find(
+                                               token.matches[0].replace( runescape, funescape ),
+                                               rsibling.test( tokens[0].type ) && context.parentNode || context
+                                       )) ) {
+
+                                               // If seed is empty or no tokens remain, we can return early
+                                               tokens.splice( i, 1 );
+                                               selector = seed.length && toSelector( tokens );
+                                               if ( !selector ) {
+                                                       push.apply( results, seed );
+                                                       return results;
+                                               }
+
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // Compile and execute a filtering function
+       // Provide `match` to avoid retokenization if we modified the selector above
+       compile( selector, match )(
+               seed,
+               context,
+               !documentIsHTML,
+               results,
+               rsibling.test( selector )
+       );
+       return results;
+}
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+       // Should return 1, but returns 4 (following)
+       return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+       div.innerHTML = "<a href='#'></a>";
+       return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+       addHandle( "type|href|height|width", function( elem, name, isXML ) {
+               if ( !isXML ) {
+                       return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+               }
+       });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+       div.innerHTML = "<input/>";
+       div.firstChild.setAttribute( "value", "" );
+       return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+       addHandle( "value", function( elem, name, isXML ) {
+               if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+                       return elem.defaultValue;
+               }
+       });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+       return div.getAttribute("disabled") == null;
+}) ) {
+       addHandle( booleans, function( elem, name, isXML ) {
+               var val;
+               if ( !isXML ) {
+                       return (val = elem.getAttributeNode( name )) && val.specified ?
+                               val.value :
+                               elem[ name ] === true ? name.toLowerCase() : null;
+               }
+       });
+}
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+       var object = optionsCache[ options ] = {};
+       jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
+               object[ flag ] = true;
+       });
+       return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *     options: an optional list of space-separated options that will change how
+ *                     the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *     once:                   will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *     memory:                 will keep track of previous values and will call any callback added
+ *                                     after the list has been fired right away with the latest "memorized"
+ *                                     values (like a Deferred)
+ *
+ *     unique:                 will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *     stopOnFalse:    interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+       // Convert options from String-formatted to Object-formatted if needed
+       // (we check in cache first)
+       options = typeof options === "string" ?
+               ( optionsCache[ options ] || createOptions( options ) ) :
+               jQuery.extend( {}, options );
+
+       var // Flag to know if list is currently firing
+               firing,
+               // Last fire value (for non-forgettable lists)
+               memory,
+               // Flag to know if list was already fired
+               fired,
+               // End of the loop when firing
+               firingLength,
+               // Index of currently firing callback (modified by remove if needed)
+               firingIndex,
+               // First callback to fire (used internally by add and fireWith)
+               firingStart,
+               // Actual callback list
+               list = [],
+               // Stack of fire calls for repeatable lists
+               stack = !options.once && [],
+               // Fire callbacks
+               fire = function( data ) {
+                       memory = options.memory && data;
+                       fired = true;
+                       firingIndex = firingStart || 0;
+                       firingStart = 0;
+                       firingLength = list.length;
+                       firing = true;
+                       for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+                               if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+                                       memory = false; // To prevent further calls using add
+                                       break;
+                               }
+                       }
+                       firing = false;
+                       if ( list ) {
+                               if ( stack ) {
+                                       if ( stack.length ) {
+                                               fire( stack.shift() );
+                                       }
+                               } else if ( memory ) {
+                                       list = [];
+                               } else {
+                                       self.disable();
+                               }
+                       }
+               },
+               // Actual Callbacks object
+               self = {
+                       // Add a callback or a collection of callbacks to the list
+                       add: function() {
+                               if ( list ) {
+                                       // First, we save the current length
+                                       var start = list.length;
+                                       (function add( args ) {
+                                               jQuery.each( args, function( _, arg ) {
+                                                       var type = jQuery.type( arg );
+                                                       if ( type === "function" ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && type !== "string" ) {
+                                                               // Inspect recursively
+                                                               add( arg );
+                                                       }
+                                               });
+                                       })( arguments );
+                                       // Do we need to add the callbacks to the
+                                       // current firing batch?
+                                       if ( firing ) {
+                                               firingLength = list.length;
+                                       // With memory, if we're not firing then
+                                       // we should call right away
+                                       } else if ( memory ) {
+                                               firingStart = start;
+                                               fire( memory );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Remove a callback from the list
+                       remove: function() {
+                               if ( list ) {
+                                       jQuery.each( arguments, function( _, arg ) {
+                                               var index;
+                                               while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+                                                       list.splice( index, 1 );
+                                                       // Handle firing indexes
+                                                       if ( firing ) {
+                                                               if ( index <= firingLength ) {
+                                                                       firingLength--;
+                                                               }
+                                                               if ( index <= firingIndex ) {
+                                                                       firingIndex--;
+                                                               }
+                                                       }
+                                               }
+                                       });
+                               }
+                               return this;
+                       },
+                       // Check if a given callback is in the list.
+                       // If no argument is given, return whether or not list has callbacks attached.
+                       has: function( fn ) {
+                               return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+                       },
+                       // Remove all callbacks from the list
+                       empty: function() {
+                               list = [];
+                               firingLength = 0;
+                               return this;
+                       },
+                       // Have the list do nothing anymore
+                       disable: function() {
+                               list = stack = memory = undefined;
+                               return this;
+                       },
+                       // Is it disabled?
+                       disabled: function() {
+                               return !list;
+                       },
+                       // Lock the list in its current state
+                       lock: function() {
+                               stack = undefined;
+                               if ( !memory ) {
+                                       self.disable();
+                               }
+                               return this;
+                       },
+                       // Is it locked?
+                       locked: function() {
+                               return !stack;
+                       },
+                       // Call all callbacks with the given context and arguments
+                       fireWith: function( context, args ) {
+                               if ( list && ( !fired || stack ) ) {
+                                       args = args || [];
+                                       args = [ context, args.slice ? args.slice() : args ];
+                                       if ( firing ) {
+                                               stack.push( args );
+                                       } else {
+                                               fire( args );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Call all the callbacks with the given arguments
+                       fire: function() {
+                               self.fireWith( this, arguments );
+                               return this;
+                       },
+                       // To know if the callbacks have already been called at least once
+                       fired: function() {
+                               return !!fired;
+                       }
+               };
+
+       return self;
+};
+jQuery.extend({
+
+       Deferred: function( func ) {
+               var tuples = [
+                               // action, add listener, listener list, final state
+                               [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+                               [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+                               [ "notify", "progress", jQuery.Callbacks("memory") ]
+                       ],
+                       state = "pending",
+                       promise = {
+                               state: function() {
+                                       return state;
+                               },
+                               always: function() {
+                                       deferred.done( arguments ).fail( arguments );
+                                       return this;
+                               },
+                               then: function( /* fnDone, fnFail, fnProgress */ ) {
+                                       var fns = arguments;
+                                       return jQuery.Deferred(function( newDefer ) {
+                                               jQuery.each( tuples, function( i, tuple ) {
+                                                       var action = tuple[ 0 ],
+                                                               fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+                                                       // deferred[ done | fail | progress ] for forwarding actions to newDefer
+                                                       deferred[ tuple[1] ](function() {
+                                                               var returned = fn && fn.apply( this, arguments );
+                                                               if ( returned && jQuery.isFunction( returned.promise ) ) {
+                                                                       returned.promise()
+                                                                               .done( newDefer.resolve )
+                                                                               .fail( newDefer.reject )
+                                                                               .progress( newDefer.notify );
+                                                               } else {
+                                                                       newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+                                                               }
+                                                       });
+                                               });
+                                               fns = null;
+                                       }).promise();
+                               },
+                               // Get a promise for this deferred
+                               // If obj is provided, the promise aspect is added to the object
+                               promise: function( obj ) {
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
+                               }
+                       },
+                       deferred = {};
+
+               // Keep pipe for back-compat
+               promise.pipe = promise.then;
+
+               // Add list-specific methods
+               jQuery.each( tuples, function( i, tuple ) {
+                       var list = tuple[ 2 ],
+                               stateString = tuple[ 3 ];
+
+                       // promise[ done | fail | progress ] = list.add
+                       promise[ tuple[1] ] = list.add;
+
+                       // Handle state
+                       if ( stateString ) {
+                               list.add(function() {
+                                       // state = [ resolved | rejected ]
+                                       state = stateString;
+
+                               // [ reject_list | resolve_list ].disable; progress_list.lock
+                               }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+                       }
+
+                       // deferred[ resolve | reject | notify ]
+                       deferred[ tuple[0] ] = function() {
+                               deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+                               return this;
+                       };
+                       deferred[ tuple[0] + "With" ] = list.fireWith;
+               });
+
+               // Make the deferred a promise
+               promise.promise( deferred );
+
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+
+               // All done!
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( subordinate /* , ..., subordinateN */ ) {
+               var i = 0,
+                       resolveValues = core_slice.call( arguments ),
+                       length = resolveValues.length,
+
+                       // the count of uncompleted subordinates
+                       remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+                       // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+                       deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+                       // Update function for both resolve and progress values
+                       updateFunc = function( i, contexts, values ) {
+                               return function( value ) {
+                                       contexts[ i ] = this;
+                                       values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+                                       if( values === progressValues ) {
+                                               deferred.notifyWith( contexts, values );
+                                       } else if ( !( --remaining ) ) {
+                                               deferred.resolveWith( contexts, values );
+                                       }
+                               };
+                       },
+
+                       progressValues, progressContexts, resolveContexts;
+
+               // add listeners to Deferred subordinates; treat others as resolved
+               if ( length > 1 ) {
+                       progressValues = new Array( length );
+                       progressContexts = new Array( length );
+                       resolveContexts = new Array( length );
+                       for ( ; i < length; i++ ) {
+                               if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+                                       resolveValues[ i ].promise()
+                                               .done( updateFunc( i, resolveContexts, resolveValues ) )
+                                               .fail( deferred.reject )
+                                               .progress( updateFunc( i, progressContexts, progressValues ) );
+                               } else {
+                                       --remaining;
+                               }
+                       }
+               }
+
+               // if we're not waiting on anything, resolve the master
+               if ( !remaining ) {
+                       deferred.resolveWith( resolveContexts, resolveValues );
+               }
+
+               return deferred.promise();
+       }
+});
+jQuery.support = (function( support ) {
+
+       var all, a, input, select, fragment, opt, eventName, isSupported, i,
+               div = document.createElement("div");
+
+       // Setup
+       div.setAttribute( "className", "t" );
+       div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+       // Finish early in limited (non-browser) environments
+       all = div.getElementsByTagName("*") || [];
+       a = div.getElementsByTagName("a")[ 0 ];
+       if ( !a || !a.style || !all.length ) {
+               return support;
+       }
+
+       // First batch of tests
+       select = document.createElement("select");
+       opt = select.appendChild( document.createElement("option") );
+       input = div.getElementsByTagName("input")[ 0 ];
+
+       a.style.cssText = "top:1px;float:left;opacity:.5";
+
+       // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+       support.getSetAttribute = div.className !== "t";
+
+       // IE strips leading whitespace when .innerHTML is used
+       support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+       // Make sure that tbody elements aren't automatically inserted
+       // IE will insert them into empty tables
+       support.tbody = !div.getElementsByTagName("tbody").length;
+
+       // Make sure that link elements get serialized correctly by innerHTML
+       // This requires a wrapper element in IE
+       support.htmlSerialize = !!div.getElementsByTagName("link").length;
+
+       // Get the style information from getAttribute
+       // (IE uses .cssText instead)
+       support.style = /top/.test( a.getAttribute("style") );
+
+       // Make sure that URLs aren't manipulated
+       // (IE normalizes it by default)
+       support.hrefNormalized = a.getAttribute("href") === "/a";
+
+       // Make sure that element opacity exists
+       // (IE uses filter instead)
+       // Use a regex to work around a WebKit issue. See #5145
+       support.opacity = /^0.5/.test( a.style.opacity );
+
+       // Verify style float existence
+       // (IE uses styleFloat instead of cssFloat)
+       support.cssFloat = !!a.style.cssFloat;
+
+       // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+       support.checkOn = !!input.value;
+
+       // Make sure that a selected-by-default option has a working selected property.
+       // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+       support.optSelected = opt.selected;
+
+       // Tests for enctype support on a form (#6743)
+       support.enctype = !!document.createElement("form").enctype;
+
+       // Makes sure cloning an html5 element does not cause problems
+       // Where outerHTML is undefined, this still works
+       support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>";
+
+       // Will be defined later
+       support.inlineBlockNeedsLayout = false;
+       support.shrinkWrapBlocks = false;
+       support.pixelPosition = false;
+       support.deleteExpando = true;
+       support.noCloneEvent = true;
+       support.reliableMarginRight = true;
+       support.boxSizingReliable = true;
+
+       // Make sure checked status is properly cloned
+       input.checked = true;
+       support.noCloneChecked = input.cloneNode( true ).checked;
+
+       // Make sure that the options inside disabled selects aren't marked as disabled
+       // (WebKit marks them as disabled)
+       select.disabled = true;
+       support.optDisabled = !opt.disabled;
+
+       // Support: IE<9
+       try {
+               delete div.test;
+       } catch( e ) {
+               support.deleteExpando = false;
+       }
+
+       // Check if we can trust getAttribute("value")
+       input = document.createElement("input");
+       input.setAttribute( "value", "" );
+       support.input = input.getAttribute( "value" ) === "";
+
+       // Check if an input maintains its value after becoming a radio
+       input.value = "t";
+       input.setAttribute( "type", "radio" );
+       support.radioValue = input.value === "t";
+
+       // #11217 - WebKit loses check when the name is after the checked attribute
+       input.setAttribute( "checked", "t" );
+       input.setAttribute( "name", "t" );
+
+       fragment = document.createDocumentFragment();
+       fragment.appendChild( input );
+
+       // Check if a disconnected checkbox will retain its checked
+       // value of true after appended to the DOM (IE6/7)
+       support.appendChecked = input.checked;
+
+       // WebKit doesn't clone checked state correctly in fragments
+       support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       // Support: IE<9
+       // Opera does not clone events (and typeof div.attachEvent === undefined).
+       // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+       if ( div.attachEvent ) {
+               div.attachEvent( "onclick", function() {
+                       support.noCloneEvent = false;
+               });
+
+               div.cloneNode( true ).click();
+       }
+
+       // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+       // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
+       for ( i in { submit: true, change: true, focusin: true }) {
+               div.setAttribute( eventName = "on" + i, "t" );
+
+               support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+       }
+
+       div.style.backgroundClip = "content-box";
+       div.cloneNode( true ).style.backgroundClip = "";
+       support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+       // Support: IE<9
+       // Iteration over object's inherited properties before its own.
+       for ( i in jQuery( support ) ) {
+               break;
+       }
+       support.ownLast = i !== "0";
+
+       // Run tests that need a body at doc ready
+       jQuery(function() {
+               var container, marginDiv, tds,
+                       divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+                       body = document.getElementsByTagName("body")[0];
+
+               if ( !body ) {
+                       // Return for frameset docs that don't have a body
+                       return;
+               }
+
+               container = document.createElement("div");
+               container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+               body.appendChild( container ).appendChild( div );
+
+               // Support: IE8
+               // Check if table cells still have offsetWidth/Height when they are set
+               // to display:none and there are still other visible table cells in a
+               // table row; if so, offsetWidth/Height are not reliable for use when
+               // determining if an element has been hidden directly using
+               // display:none (it is still safe to use offsets if a parent element is
+               // hidden; don safety goggles and see bug #4512 for more information).
+               div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+               tds = div.getElementsByTagName("td");
+               tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+               isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+               tds[ 0 ].style.display = "";
+               tds[ 1 ].style.display = "none";
+
+               // Support: IE8
+               // Check if empty table cells still have offsetWidth/Height
+               support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+               // Check box-sizing and margin behavior.
+               div.innerHTML = "";
+               div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+
+               // Workaround failing boxSizing test due to offsetWidth returning wrong value
+               // with some non-1 values of body zoom, ticket #13543
+               jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
+                       support.boxSizing = div.offsetWidth === 4;
+               });
+
+               // Use window.getComputedStyle because jsdom on node.js will break without it.
+               if ( window.getComputedStyle ) {
+                       support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+                       support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+                       // Check if div with explicit width and no margin-right incorrectly
+                       // gets computed margin-right based on width of container. (#3333)
+                       // Fails in WebKit before Feb 2011 nightlies
+                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                       marginDiv = div.appendChild( document.createElement("div") );
+                       marginDiv.style.cssText = div.style.cssText = divReset;
+                       marginDiv.style.marginRight = marginDiv.style.width = "0";
+                       div.style.width = "1px";
+
+                       support.reliableMarginRight =
+                               !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+               }
+
+               if ( typeof div.style.zoom !== core_strundefined ) {
+                       // Support: IE<8
+                       // Check if natively block-level elements act like inline-block
+                       // elements when setting their display to 'inline' and giving
+                       // them layout
+                       div.innerHTML = "";
+                       div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+                       support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+                       // Support: IE6
+                       // Check if elements with layout shrink-wrap their children
+                       div.style.display = "block";
+                       div.innerHTML = "<div></div>";
+                       div.firstChild.style.width = "5px";
+                       support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+                       if ( support.inlineBlockNeedsLayout ) {
+                               // Prevent IE 6 from affecting layout for positioned elements #11048
+                               // Prevent IE from shrinking the body in IE 7 mode #12869
+                               // Support: IE<8
+                               body.style.zoom = 1;
+                       }
+               }
+
+               body.removeChild( container );
+
+               // Null elements to avoid leaks in IE
+               container = div = tds = marginDiv = null;
+       });
+
+       // Null elements to avoid leaks in IE
+       all = select = fragment = opt = a = input = null;
+
+       return support;
+})({});
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+       rmultiDash = /([A-Z])/g;
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+       if ( !jQuery.acceptData( elem ) ) {
+               return;
+       }
+
+       var ret, thisCache,
+               internalKey = jQuery.expando,
+
+               // We have to handle DOM nodes and JS objects differently because IE6-7
+               // can't GC object references properly across the DOM-JS boundary
+               isNode = elem.nodeType,
+
+               // Only DOM nodes need the global jQuery cache; JS object data is
+               // attached directly to the object so GC can occur automatically
+               cache = isNode ? jQuery.cache : elem,
+
+               // Only defining an ID for JS objects if its cache already exists allows
+               // the code to shortcut on the same path as a DOM node with no cache
+               id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+       // Avoid doing any more work than we need to when trying to get data on an
+       // object that has no data at all
+       if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
+               return;
+       }
+
+       if ( !id ) {
+               // Only DOM nodes need a new unique ID for each element since their data
+               // ends up in the global cache
+               if ( isNode ) {
+                       id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;
+               } else {
+                       id = internalKey;
+               }
+       }
+
+       if ( !cache[ id ] ) {
+               // Avoid exposing jQuery metadata on plain JS objects when the object
+               // is serialized using JSON.stringify
+               cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
+       }
+
+       // An object can be passed to jQuery.data instead of a key/value pair; this gets
+       // shallow copied over onto the existing cache
+       if ( typeof name === "object" || typeof name === "function" ) {
+               if ( pvt ) {
+                       cache[ id ] = jQuery.extend( cache[ id ], name );
+               } else {
+                       cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+               }
+       }
+
+       thisCache = cache[ id ];
+
+       // jQuery data() is stored in a separate object inside the object's internal data
+       // cache in order to avoid key collisions between internal data and user-defined
+       // data.
+       if ( !pvt ) {
+               if ( !thisCache.data ) {
+                       thisCache.data = {};
+               }
+
+               thisCache = thisCache.data;
+       }
+
+       if ( data !== undefined ) {
+               thisCache[ jQuery.camelCase( name ) ] = data;
+       }
+
+       // Check for both converted-to-camel and non-converted data property names
+       // If a data property was specified
+       if ( typeof name === "string" ) {
+
+               // First Try to find as-is property data
+               ret = thisCache[ name ];
+
+               // Test for null|undefined property data
+               if ( ret == null ) {
+
+                       // Try to find the camelCased property
+                       ret = thisCache[ jQuery.camelCase( name ) ];
+               }
+       } else {
+               ret = thisCache;
+       }
+
+       return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+       if ( !jQuery.acceptData( elem ) ) {
+               return;
+       }
+
+       var thisCache, i,
+               isNode = elem.nodeType,
+
+               // See jQuery.data for more information
+               cache = isNode ? jQuery.cache : elem,
+               id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+       // If there is already no cache entry for this object, there is no
+       // purpose in continuing
+       if ( !cache[ id ] ) {
+               return;
+       }
+
+       if ( name ) {
+
+               thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+               if ( thisCache ) {
+
+                       // Support array or space separated string names for data keys
+                       if ( !jQuery.isArray( name ) ) {
+
+                               // try the string as a key before any manipulation
+                               if ( name in thisCache ) {
+                                       name = [ name ];
+                               } else {
+
+                                       // split the camel cased version by spaces unless a key with the spaces exists
+                                       name = jQuery.camelCase( name );
+                                       if ( name in thisCache ) {
+                                               name = [ name ];
+                                       } else {
+                                               name = name.split(" ");
+                                       }
+                               }
+                       } else {
+                               // If "name" is an array of keys...
+                               // When data is initially created, via ("key", "val") signature,
+                               // keys will be converted to camelCase.
+                               // Since there is no way to tell _how_ a key was added, remove
+                               // both plain key and camelCase key. #12786
+                               // This will only penalize the array argument path.
+                               name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+                       }
+
+                       i = name.length;
+                       while ( i-- ) {
+                               delete thisCache[ name[i] ];
+                       }
+
+                       // If there is no data left in the cache, we want to continue
+                       // and let the cache object itself get destroyed
+                       if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
+                               return;
+                       }
+               }
+       }
+
+       // See jQuery.data for more information
+       if ( !pvt ) {
+               delete cache[ id ].data;
+
+               // Don't destroy the parent cache unless the internal data object
+               // had been the only thing left in it
+               if ( !isEmptyDataObject( cache[ id ] ) ) {
+                       return;
+               }
+       }
+
+       // Destroy the cache
+       if ( isNode ) {
+               jQuery.cleanData( [ elem ], true );
+
+       // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+       /* jshint eqeqeq: false */
+       } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+               /* jshint eqeqeq: true */
+               delete cache[ id ];
+
+       // When all else fails, null
+       } else {
+               cache[ id ] = null;
+       }
+}
+
+jQuery.extend({
+       cache: {},
+
+       // The following elements throw uncatchable exceptions if you
+       // attempt to add expando properties to them.
+       noData: {
+               "applet": true,
+               "embed": true,
+               // Ban all objects except for Flash (which handle expandos)
+               "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+       },
+
+       hasData: function( elem ) {
+               elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+               return !!elem && !isEmptyDataObject( elem );
+       },
+
+       data: function( elem, name, data ) {
+               return internalData( elem, name, data );
+       },
+
+       removeData: function( elem, name ) {
+               return internalRemoveData( elem, name );
+       },
+
+       // For internal use only.
+       _data: function( elem, name, data ) {
+               return internalData( elem, name, data, true );
+       },
+
+       _removeData: function( elem, name ) {
+               return internalRemoveData( elem, name, true );
+       },
+
+       // A method for determining if a DOM node can handle the data expando
+       acceptData: function( elem ) {
+               // Do not set data on non-element because it will not be cleared (#8335).
+               if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+                       return false;
+               }
+
+               var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+               // nodes accept data unless otherwise specified; rejection can be conditional
+               return !noData || noData !== true && elem.getAttribute("classid") === noData;
+       }
+});
+
+jQuery.fn.extend({
+       data: function( key, value ) {
+               var attrs, name,
+                       data = null,
+                       i = 0,
+                       elem = this[0];
+
+               // Special expections of .data basically thwart jQuery.access,
+               // so implement the relevant behavior ourselves
+
+               // Gets all values
+               if ( key === undefined ) {
+                       if ( this.length ) {
+                               data = jQuery.data( elem );
+
+                               if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+                                       attrs = elem.attributes;
+                                       for ( ; i < attrs.length; i++ ) {
+                                               name = attrs[i].name;
+
+                                               if ( name.indexOf("data-") === 0 ) {
+                                                       name = jQuery.camelCase( name.slice(5) );
+
+                                                       dataAttr( elem, name, data[ name ] );
+                                               }
+                                       }
+                                       jQuery._data( elem, "parsedAttrs", true );
+                               }
+                       }
+
+                       return data;
+               }
+
+               // Sets multiple values
+               if ( typeof key === "object" ) {
+                       return this.each(function() {
+                               jQuery.data( this, key );
+                       });
+               }
+
+               return arguments.length > 1 ?
+
+                       // Sets one value
+                       this.each(function() {
+                               jQuery.data( this, key, value );
+                       }) :
+
+                       // Gets one value
+                       // Try to fetch any internally stored data first
+                       elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+       },
+
+       removeData: function( key ) {
+               return this.each(function() {
+                       jQuery.removeData( this, key );
+               });
+       }
+});
+
+function dataAttr( elem, key, data ) {
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+
+               var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+               data = elem.getAttribute( name );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                                       data === "false" ? false :
+                                       data === "null" ? null :
+                                       // Only convert to a number if it doesn't change the string
+                                       +data + "" === data ? +data :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                               data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       jQuery.data( elem, key, data );
+
+               } else {
+                       data = undefined;
+               }
+       }
+
+       return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+       var name;
+       for ( name in obj ) {
+
+               // if the public data object is empty, the private is still empty
+               if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+                       continue;
+               }
+               if ( name !== "toJSON" ) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+jQuery.extend({
+       queue: function( elem, type, data ) {
+               var queue;
+
+               if ( elem ) {
+                       type = ( type || "fx" ) + "queue";
+                       queue = jQuery._data( elem, type );
+
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !queue || jQuery.isArray(data) ) {
+                                       queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+                               } else {
+                                       queue.push( data );
+                               }
+                       }
+                       return queue || [];
+               }
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ),
+                       startLength = queue.length,
+                       fn = queue.shift(),
+                       hooks = jQuery._queueHooks( elem, type ),
+                       next = function() {
+                               jQuery.dequeue( elem, type );
+                       };
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+                       startLength--;
+               }
+
+               if ( fn ) {
+
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift( "inprogress" );
+                       }
+
+                       // clear up the last queue stop function
+                       delete hooks.stop;
+                       fn.call( elem, next, hooks );
+               }
+
+               if ( !startLength && hooks ) {
+                       hooks.empty.fire();
+               }
+       },
+
+       // not intended for public consumption - generates a queueHooks object, or returns the current one
+       _queueHooks: function( elem, type ) {
+               var key = type + "queueHooks";
+               return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+                       empty: jQuery.Callbacks("once memory").add(function() {
+                               jQuery._removeData( elem, type + "queue" );
+                               jQuery._removeData( elem, key );
+                       })
+               });
+       }
+});
+
+jQuery.fn.extend({
+       queue: function( type, data ) {
+               var setter = 2;
+
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+                       setter--;
+               }
+
+               if ( arguments.length < setter ) {
+                       return jQuery.queue( this[0], type );
+               }
+
+               return data === undefined ?
+                       this :
+                       this.each(function() {
+                               var queue = jQuery.queue( this, type, data );
+
+                               // ensure a hooks for this queue
+                               jQuery._queueHooks( this, type );
+
+                               if ( type === "fx" && queue[0] !== "inprogress" ) {
+                                       jQuery.dequeue( this, type );
+                               }
+                       });
+       },
+       dequeue: function( type ) {
+               return this.each(function() {
+                       jQuery.dequeue( this, type );
+               });
+       },
+       // Based off of the plugin by Clint Helfers, with permission.
+       // http://blindsignals.com/index.php/2009/07/jquery-delay/
+       delay: function( time, type ) {
+               time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+               type = type || "fx";
+
+               return this.queue( type, function( next, hooks ) {
+                       var timeout = setTimeout( next, time );
+                       hooks.stop = function() {
+                               clearTimeout( timeout );
+                       };
+               });
+       },
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       },
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, obj ) {
+               var tmp,
+                       count = 1,
+                       defer = jQuery.Deferred(),
+                       elements = this,
+                       i = this.length,
+                       resolve = function() {
+                               if ( !( --count ) ) {
+                                       defer.resolveWith( elements, [ elements ] );
+                               }
+                       };
+
+               if ( typeof type !== "string" ) {
+                       obj = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+
+               while( i-- ) {
+                       tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+                       if ( tmp && tmp.empty ) {
+                               count++;
+                               tmp.empty.add( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise( obj );
+       }
+});
+var nodeHook, boolHook,
+       rclass = /[\t\r\n\f]/g,
+       rreturn = /\r/g,
+       rfocusable = /^(?:input|select|textarea|button|object)$/i,
+       rclickable = /^(?:a|area)$/i,
+       ruseDefault = /^(?:checked|selected)$/i,
+       getSetAttribute = jQuery.support.getSetAttribute,
+       getSetInput = jQuery.support.input;
+
+jQuery.fn.extend({
+       attr: function( name, value ) {
+               return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+       },
+
+       removeAttr: function( name ) {
+               return this.each(function() {
+                       jQuery.removeAttr( this, name );
+               });
+       },
+
+       prop: function( name, value ) {
+               return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+       },
+
+       removeProp: function( name ) {
+               name = jQuery.propFix[ name ] || name;
+               return this.each(function() {
+                       // try/catch handles cases where IE balks (such as removing a property on window)
+                       try {
+                               this[ name ] = undefined;
+                               delete this[ name ];
+                       } catch( e ) {}
+               });
+       },
+
+       addClass: function( value ) {
+               var classes, elem, cur, clazz, j,
+                       i = 0,
+                       len = this.length,
+                       proceed = typeof value === "string" && value;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).addClass( value.call( this, j, this.className ) );
+                       });
+               }
+
+               if ( proceed ) {
+                       // The disjunction here is for better compressibility (see removeClass)
+                       classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       " "
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+                                                       cur += clazz + " ";
+                                               }
+                                       }
+                                       elem.className = jQuery.trim( cur );
+
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               var classes, elem, cur, clazz, j,
+                       i = 0,
+                       len = this.length,
+                       proceed = arguments.length === 0 || typeof value === "string" && value;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).removeClass( value.call( this, j, this.className ) );
+                       });
+               }
+               if ( proceed ) {
+                       classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               // This expression is here for better compressibility (see addClass)
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       ""
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               // Remove *all* instances
+                                               while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+                                                       cur = cur.replace( " " + clazz + " ", " " );
+                                               }
+                                       }
+                                       elem.className = value ? jQuery.trim( cur ) : "";
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value;
+
+               if ( typeof stateVal === "boolean" && type === "string" ) {
+                       return stateVal ? this.addClass( value ) : this.removeClass( value );
+               }
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( i ) {
+                               jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+                       });
+               }
+
+               return this.each(function() {
+                       if ( type === "string" ) {
+                               // toggle individual class names
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
+                                       classNames = value.match( core_rnotwhite ) || [];
+
+                               while ( (className = classNames[ i++ ]) ) {
+                                       // check each className given, space separated list
+                                       if ( self.hasClass( className ) ) {
+                                               self.removeClass( className );
+                                       } else {
+                                               self.addClass( className );
+                                       }
+                               }
+
+                       // Toggle whole class name
+                       } else if ( type === core_strundefined || type === "boolean" ) {
+                               if ( this.className ) {
+                                       // store className if set
+                                       jQuery._data( this, "__className__", this.className );
+                               }
+
+                               // If the element has a class name or if we're passed "false",
+                               // then remove the whole classname (if there was one, the above saved it).
+                               // Otherwise bring back whatever was previously saved (if anything),
+                               // falling back to the empty string if nothing was stored.
+                               this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+                       }
+               });
+       },
+
+       hasClass: function( selector ) {
+               var className = " " + selector + " ",
+                       i = 0,
+                       l = this.length;
+               for ( ; i < l; i++ ) {
+                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       },
+
+       val: function( value ) {
+               var ret, hooks, isFunction,
+                       elem = this[0];
+
+               if ( !arguments.length ) {
+                       if ( elem ) {
+                               hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+                               if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+                                       return ret;
+                               }
+
+                               ret = elem.value;
+
+                               return typeof ret === "string" ?
+                                       // handle most common string cases
+                                       ret.replace(rreturn, "") :
+                                       // handle cases where value is null/undef or number
+                                       ret == null ? "" : ret;
+                       }
+
+                       return;
+               }
+
+               isFunction = jQuery.isFunction( value );
+
+               return this.each(function( i ) {
+                       var val;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call( this, i, jQuery( this ).val() );
+                       } else {
+                               val = value;
+                       }
+
+                       // Treat null/undefined as ""; convert numbers to string
+                       if ( val == null ) {
+                               val = "";
+                       } else if ( typeof val === "number" ) {
+                               val += "";
+                       } else if ( jQuery.isArray( val ) ) {
+                               val = jQuery.map(val, function ( value ) {
+                                       return value == null ? "" : value + "";
+                               });
+                       }
+
+                       hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+                               // Use proper attribute retrieval(#6932, #12072)
+                               var val = jQuery.find.attr( elem, "value" );
+                               return val != null ?
+                                       val :
+                                       elem.text;
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var value, option,
+                                       options = elem.options,
+                                       index = elem.selectedIndex,
+                                       one = elem.type === "select-one" || index < 0,
+                                       values = one ? null : [],
+                                       max = one ? index + 1 : options.length,
+                                       i = index < 0 ?
+                                               max :
+                                               one ? index : 0;
+
+                               // Loop through all the selected options
+                               for ( ; i < max; i++ ) {
+                                       option = options[ i ];
+
+                                       // oldIE doesn't update selected after form reset (#2551)
+                                       if ( ( option.selected || i === index ) &&
+                                                       // Don't return options that are disabled or in a disabled optgroup
+                                                       ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+                                                       ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var optionSet, option,
+                                       options = elem.options,
+                                       values = jQuery.makeArray( value ),
+                                       i = options.length;
+
+                               while ( i-- ) {
+                                       option = options[ i ];
+                                       if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
+                                               optionSet = true;
+                                       }
+                               }
+
+                               // force browsers to behave consistently when non-matching value is set
+                               if ( !optionSet ) {
+                                       elem.selectedIndex = -1;
+                               }
+                               return values;
+                       }
+               }
+       },
+
+       attr: function( elem, name, value ) {
+               var hooks, ret,
+                       nType = elem.nodeType;
+
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               // Fallback to prop when attributes are not supported
+               if ( typeof elem.getAttribute === core_strundefined ) {
+                       return jQuery.prop( elem, name, value );
+               }
+
+               // All attributes are lowercase
+               // Grab necessary hook if one is defined
+               if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+                       name = name.toLowerCase();
+                       hooks = jQuery.attrHooks[ name ] ||
+                               ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+               }
+
+               if ( value !== undefined ) {
+
+                       if ( value === null ) {
+                               jQuery.removeAttr( elem, name );
+
+                       } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               elem.setAttribute( name, value + "" );
+                               return value;
+                       }
+
+               } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+                       return ret;
+
+               } else {
+                       ret = jQuery.find.attr( elem, name );
+
+                       // Non-existent attributes return null, we normalize to undefined
+                       return ret == null ?
+                               undefined :
+                               ret;
+               }
+       },
+
+       removeAttr: function( elem, value ) {
+               var name, propName,
+                       i = 0,
+                       attrNames = value && value.match( core_rnotwhite );
+
+               if ( attrNames && elem.nodeType === 1 ) {
+                       while ( (name = attrNames[i++]) ) {
+                               propName = jQuery.propFix[ name ] || name;
+
+                               // Boolean attributes get special treatment (#10870)
+                               if ( jQuery.expr.match.bool.test( name ) ) {
+                                       // Set corresponding property to false
+                                       if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+                                               elem[ propName ] = false;
+                                       // Support: IE<9
+                                       // Also clear defaultChecked/defaultSelected (if appropriate)
+                                       } else {
+                                               elem[ jQuery.camelCase( "default-" + name ) ] =
+                                                       elem[ propName ] = false;
+                                       }
+
+                               // See #9699 for explanation of this approach (setting first, then removal)
+                               } else {
+                                       jQuery.attr( elem, name, "" );
+                               }
+
+                               elem.removeAttribute( getSetAttribute ? name : propName );
+                       }
+               }
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+                                       // Setting the type on a radio button after the value resets the value in IE6-9
+                                       // Reset value to default in case type is set after value during creation
+                                       var val = elem.value;
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               }
+       },
+
+       propFix: {
+               "for": "htmlFor",
+               "class": "className"
+       },
+
+       prop: function( elem, name, value ) {
+               var ret, hooks, notxml,
+                       nType = elem.nodeType;
+
+               // don't get/set properties on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+               if ( notxml ) {
+                       // Fix name and attach hooks
+                       name = jQuery.propFix[ name ] || name;
+                       hooks = jQuery.propHooks[ name ];
+               }
+
+               if ( value !== undefined ) {
+                       return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
+                               ret :
+                               ( elem[ name ] = value );
+
+               } else {
+                       return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
+                               ret :
+                               elem[ name ];
+               }
+       },
+
+       propHooks: {
+               tabIndex: {
+                       get: function( elem ) {
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               // Use proper attribute retrieval(#12072)
+                               var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+                               return tabindex ?
+                                       parseInt( tabindex, 10 ) :
+                                       rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+                                               0 :
+                                               -1;
+                       }
+               }
+       }
+});
+
+// Hooks for boolean attributes
+boolHook = {
+       set: function( elem, value, name ) {
+               if ( value === false ) {
+                       // Remove boolean attributes when set to false
+                       jQuery.removeAttr( elem, name );
+               } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+                       // IE<8 needs the *property* name
+                       elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+               // Use defaultChecked and defaultSelected for oldIE
+               } else {
+                       elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+               }
+
+               return name;
+       }
+};
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+       var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
+
+       jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
+               function( elem, name, isXML ) {
+                       var fn = jQuery.expr.attrHandle[ name ],
+                               ret = isXML ?
+                                       undefined :
+                                       /* jshint eqeqeq: false */
+                                       (jQuery.expr.attrHandle[ name ] = undefined) !=
+                                               getter( elem, name, isXML ) ?
+
+                                               name.toLowerCase() :
+                                               null;
+                       jQuery.expr.attrHandle[ name ] = fn;
+                       return ret;
+               } :
+               function( elem, name, isXML ) {
+                       return isXML ?
+                               undefined :
+                               elem[ jQuery.camelCase( "default-" + name ) ] ?
+                                       name.toLowerCase() :
+                                       null;
+               };
+});
+
+// fix oldIE attroperties
+if ( !getSetInput || !getSetAttribute ) {
+       jQuery.attrHooks.value = {
+               set: function( elem, value, name ) {
+                       if ( jQuery.nodeName( elem, "input" ) ) {
+                               // Does not return so that setAttribute is also used
+                               elem.defaultValue = value;
+                       } else {
+                               // Use nodeHook if defined (#1954); otherwise setAttribute is fine
+                               return nodeHook && nodeHook.set( elem, value, name );
+                       }
+               }
+       };
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+       // Use this for any attribute in IE6/7
+       // This fixes almost every IE6/7 issue
+       nodeHook = {
+               set: function( elem, value, name ) {
+                       // Set the existing or create a new attribute node
+                       var ret = elem.getAttributeNode( name );
+                       if ( !ret ) {
+                               elem.setAttributeNode(
+                                       (ret = elem.ownerDocument.createAttribute( name ))
+                               );
+                       }
+
+                       ret.value = value += "";
+
+                       // Break association with cloned elements by also using setAttribute (#9646)
+                       return name === "value" || value === elem.getAttribute( name ) ?
+                               value :
+                               undefined;
+               }
+       };
+       jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =
+               // Some attributes are constructed with empty-string values when not defined
+               function( elem, name, isXML ) {
+                       var ret;
+                       return isXML ?
+                               undefined :
+                               (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
+                                       ret.value :
+                                       null;
+               };
+       jQuery.valHooks.button = {
+               get: function( elem, name ) {
+                       var ret = elem.getAttributeNode( name );
+                       return ret && ret.specified ?
+                               ret.value :
+                               undefined;
+               },
+               set: nodeHook.set
+       };
+
+       // Set contenteditable to false on removals(#10429)
+       // Setting to empty string throws an error as an invalid value
+       jQuery.attrHooks.contenteditable = {
+               set: function( elem, value, name ) {
+                       nodeHook.set( elem, value === "" ? false : value, name );
+               }
+       };
+
+       // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+       // This is for removals
+       jQuery.each([ "width", "height" ], function( i, name ) {
+               jQuery.attrHooks[ name ] = {
+                       set: function( elem, value ) {
+                               if ( value === "" ) {
+                                       elem.setAttribute( name, "auto" );
+                                       return value;
+                               }
+                       }
+               };
+       });
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+       // href/src property should get the full normalized URL (#10299/#12915)
+       jQuery.each([ "href", "src" ], function( i, name ) {
+               jQuery.propHooks[ name ] = {
+                       get: function( elem ) {
+                               return elem.getAttribute( name, 4 );
+                       }
+               };
+       });
+}
+
+if ( !jQuery.support.style ) {
+       jQuery.attrHooks.style = {
+               get: function( elem ) {
+                       // Return undefined in the case of empty string
+                       // Note: IE uppercases css property names, but if we were to .toLowerCase()
+                       // .cssText, that would destroy case senstitivity in URL's, like in "background"
+                       return elem.style.cssText || undefined;
+               },
+               set: function( elem, value ) {
+                       return ( elem.style.cssText = value + "" );
+               }
+       };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+       jQuery.propHooks.selected = {
+               get: function( elem ) {
+                       var parent = elem.parentNode;
+
+                       if ( parent ) {
+                               parent.selectedIndex;
+
+                               // Make sure that it also works with optgroups, see #5701
+                               if ( parent.parentNode ) {
+                                       parent.parentNode.selectedIndex;
+                               }
+                       }
+                       return null;
+               }
+       };
+}
+
+jQuery.each([
+       "tabIndex",
+       "readOnly",
+       "maxLength",
+       "cellSpacing",
+       "cellPadding",
+       "rowSpan",
+       "colSpan",
+       "useMap",
+       "frameBorder",
+       "contentEditable"
+], function() {
+       jQuery.propFix[ this.toLowerCase() ] = this;
+});
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+       jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+jQuery.each([ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = {
+               set: function( elem, value ) {
+                       if ( jQuery.isArray( value ) ) {
+                               return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+                       }
+               }
+       };
+       if ( !jQuery.support.checkOn ) {
+               jQuery.valHooks[ this ].get = function( elem ) {
+                       // Support: Webkit
+                       // "" is returned instead of "on" if a value isn't specified
+                       return elem.getAttribute("value") === null ? "on" : elem.value;
+               };
+       }
+});
+var rformElems = /^(?:input|select|textarea)$/i,
+       rkeyEvent = /^key/,
+       rmouseEvent = /^(?:mouse|contextmenu)|click/,
+       rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+       rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+       return true;
+}
+
+function returnFalse() {
+       return false;
+}
+
+function safeActiveElement() {
+       try {
+               return document.activeElement;
+       } catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+       global: {},
+
+       add: function( elem, types, handler, data, selector ) {
+               var tmp, events, t, handleObjIn,
+                       special, eventHandle, handleObj,
+                       handlers, type, namespaces, origType,
+                       elemData = jQuery._data( elem );
+
+               // Don't attach events to noData or text/comment nodes (but allow plain objects)
+               if ( !elemData ) {
+                       return;
+               }
+
+               // Caller can pass in an object of custom data in lieu of the handler
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+                       selector = handleObjIn.selector;
+               }
+
+               // Make sure that the handler has a unique ID, used to find/remove it later
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure and main handler, if this is the first
+               if ( !(events = elemData.events) ) {
+                       events = elemData.events = {};
+               }
+               if ( !(eventHandle = elemData.handle) ) {
+                       eventHandle = elemData.handle = function( e ) {
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
+                                       jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+                                       undefined;
+                       };
+                       // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+                       eventHandle.elem = elem;
+               }
+
+               // Handle multiple events separated by a space
+               types = ( types || "" ).match( core_rnotwhite ) || [""];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // There *must* be a type, no attaching namespace-only handlers
+                       if ( !type ) {
+                               continue;
+                       }
+
+                       // If event changes its type, use the special event handlers for the changed type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // If selector defined, determine special event api type, otherwise given type
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+
+                       // Update special based on newly reset type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // handleObj is passed to all event handlers
+                       handleObj = jQuery.extend({
+                               type: type,
+                               origType: origType,
+                               data: data,
+                               handler: handler,
+                               guid: handler.guid,
+                               selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+                               namespace: namespaces.join(".")
+                       }, handleObjIn );
+
+                       // Init the event handler queue if we're the first
+                       if ( !(handlers = events[ type ]) ) {
+                               handlers = events[ type ] = [];
+                               handlers.delegateCount = 0;
+
+                               // Only use addEventListener/attachEvent if the special events handler returns false
+                               if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                                       // Bind the global event handler to the element
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle, false );
+
+                                       } else if ( elem.attachEvent ) {
+                                               elem.attachEvent( "on" + type, eventHandle );
+                                       }
+                               }
+                       }
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add to the element's handler list, delegates in front
+                       if ( selector ) {
+                               handlers.splice( handlers.delegateCount++, 0, handleObj );
+                       } else {
+                               handlers.push( handleObj );
+                       }
+
+                       // Keep track of which events have ever been used, for event optimization
+                       jQuery.event.global[ type ] = true;
+               }
+
+               // Nullify elem to prevent memory leaks in IE
+               elem = null;
+       },
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, selector, mappedTypes ) {
+               var j, handleObj, tmp,
+                       origCount, t, events,
+                       special, handlers, type,
+                       namespaces, origType,
+                       elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+               if ( !elemData || !(events = elemData.events) ) {
+                       return;
+               }
+
+               // Once for each type.namespace in types; type may be omitted
+               types = ( types || "" ).match( core_rnotwhite ) || [""];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // Unbind all events (on this namespace, if provided) for the element
+                       if ( !type ) {
+                               for ( type in events ) {
+                                       jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+                               }
+                               continue;
+                       }
+
+                       special = jQuery.event.special[ type ] || {};
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+                       handlers = events[ type ] || [];
+                       tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+                       // Remove matching events
+                       origCount = j = handlers.length;
+                       while ( j-- ) {
+                               handleObj = handlers[ j ];
+
+                               if ( ( mappedTypes || origType === handleObj.origType ) &&
+                                       ( !handler || handler.guid === handleObj.guid ) &&
+                                       ( !tmp || tmp.test( handleObj.namespace ) ) &&
+                                       ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+                                       handlers.splice( j, 1 );
+
+                                       if ( handleObj.selector ) {
+                                               handlers.delegateCount--;
+                                       }
+                                       if ( special.remove ) {
+                                               special.remove.call( elem, handleObj );
+                                       }
+                               }
+                       }
+
+                       // Remove generic event handler if we removed something and no more handlers exist
+                       // (avoids potential for endless recursion during removal of special event handlers)
+                       if ( origCount && !handlers.length ) {
+                               if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+                                       jQuery.removeEvent( elem, type, elemData.handle );
+                               }
+
+                               delete events[ type ];
+                       }
+               }
+
+               // Remove the expando if it's no longer used
+               if ( jQuery.isEmptyObject( events ) ) {
+                       delete elemData.handle;
+
+                       // removeData also checks for emptiness and clears the expando if empty
+                       // so use it instead of delete
+                       jQuery._removeData( elem, "events" );
+               }
+       },
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+               var handle, ontype, cur,
+                       bubbleType, special, tmp, i,
+                       eventPath = [ elem || document ],
+                       type = core_hasOwn.call( event, "type" ) ? event.type : event,
+                       namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+               cur = tmp = elem = elem || document;
+
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // focus/blur morphs to focusin/out; ensure we're not firing them right now
+               if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+                       return;
+               }
+
+               if ( type.indexOf(".") >= 0 ) {
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split(".");
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
+               ontype = type.indexOf(":") < 0 && "on" + type;
+
+               // Caller can pass in a jQuery.Event object, Object, or just an event type string
+               event = event[ jQuery.expando ] ?
+                       event :
+                       new jQuery.Event( type, typeof event === "object" && event );
+
+               // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+               event.isTrigger = onlyHandlers ? 2 : 3;
+               event.namespace = namespaces.join(".");
+               event.namespace_re = event.namespace ?
+                       new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+                       null;
+
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               if ( !event.target ) {
+                       event.target = elem;
+               }
+
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data == null ?
+                       [ event ] :
+                       jQuery.makeArray( data, [ event ] );
+
+               // Allow special events to draw outside the lines
+               special = jQuery.event.special[ type ] || {};
+               if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+                       return;
+               }
+
+               // Determine event propagation path in advance, per W3C events spec (#9951)
+               // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+               if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+                       bubbleType = special.delegateType || type;
+                       if ( !rfocusMorph.test( bubbleType + type ) ) {
+                               cur = cur.parentNode;
+                       }
+                       for ( ; cur; cur = cur.parentNode ) {
+                               eventPath.push( cur );
+                               tmp = cur;
+                       }
+
+                       // Only add window if we got to document (e.g., not plain obj or detached DOM)
+                       if ( tmp === (elem.ownerDocument || document) ) {
+                               eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+                       }
+               }
+
+               // Fire handlers on the event path
+               i = 0;
+               while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+                       event.type = i > 1 ?
+                               bubbleType :
+                               special.bindType || type;
+
+                       // jQuery handler
+                       handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+                       if ( handle ) {
+                               handle.apply( cur, data );
+                       }
+
+                       // Native handler
+                       handle = ontype && cur[ ontype ];
+                       if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+                               event.preventDefault();
+                       }
+               }
+               event.type = type;
+
+               // If nobody prevented the default action, do it now
+               if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+                       if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+                               jQuery.acceptData( elem ) ) {
+
+                               // Call a native DOM method on the target with the same name name as the event.
+                               // Can't use an .isFunction() check here because IE6/7 fails that test.
+                               // Don't do default actions on window, that's where global variables be (#6170)
+                               if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+                                       // Don't re-trigger an onFOO event when we call its FOO() method
+                                       tmp = elem[ ontype ];
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = null;
+                                       }
+
+                                       // Prevent re-triggering of the same event, since we already bubbled it above
+                                       jQuery.event.triggered = type;
+                                       try {
+                                               elem[ type ]();
+                                       } catch ( e ) {
+                                               // IE<9 dies on focus/blur to hidden element (#1486,#12518)
+                                               // only reproducible on winXP IE8 native, not IE9 in IE8 mode
+                                       }
+                                       jQuery.event.triggered = undefined;
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = tmp;
+                                       }
+                               }
+                       }
+               }
+
+               return event.result;
+       },
+
+       dispatch: function( event ) {
+
+               // Make a writable jQuery.Event from the native event object
+               event = jQuery.event.fix( event );
+
+               var i, ret, handleObj, matched, j,
+                       handlerQueue = [],
+                       args = core_slice.call( arguments ),
+                       handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+                       special = jQuery.event.special[ event.type ] || {};
+
+               // Use the fix-ed jQuery.Event rather than the (read-only) native event
+               args[0] = event;
+               event.delegateTarget = this;
+
+               // Call the preDispatch hook for the mapped type, and let it bail if desired
+               if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+                       return;
+               }
+
+               // Determine handlers
+               handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+               // Run delegates first; they may want to stop propagation beneath us
+               i = 0;
+               while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+                       event.currentTarget = matched.elem;
+
+                       j = 0;
+                       while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+                               // Triggered event must either 1) have no namespace, or
+                               // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+                               if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+                                       event.handleObj = handleObj;
+                                       event.data = handleObj.data;
+
+                                       ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+                                                       .apply( matched.elem, args );
+
+                                       if ( ret !== undefined ) {
+                                               if ( (event.result = ret) === false ) {
+                                                       event.preventDefault();
+                                                       event.stopPropagation();
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Call the postDispatch hook for the mapped type
+               if ( special.postDispatch ) {
+                       special.postDispatch.call( this, event );
+               }
+
+               return event.result;
+       },
+
+       handlers: function( event, handlers ) {
+               var sel, handleObj, matches, i,
+                       handlerQueue = [],
+                       delegateCount = handlers.delegateCount,
+                       cur = event.target;
+
+               // Find delegate handlers
+               // Black-hole SVG <use> instance trees (#13180)
+               // Avoid non-left-click bubbling in Firefox (#3861)
+               if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+                       /* jshint eqeqeq: false */
+                       for ( ; cur != this; cur = cur.parentNode || this ) {
+                               /* jshint eqeqeq: true */
+
+                               // Don't check non-elements (#13208)
+                               // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+                               if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+                                       matches = [];
+                                       for ( i = 0; i < delegateCount; i++ ) {
+                                               handleObj = handlers[ i ];
+
+                                               // Don't conflict with Object.prototype properties (#13203)
+                                               sel = handleObj.selector + " ";
+
+                                               if ( matches[ sel ] === undefined ) {
+                                                       matches[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) >= 0 :
+                                                               jQuery.find( sel, this, null, [ cur ] ).length;
+                                               }
+                                               if ( matches[ sel ] ) {
+                                                       matches.push( handleObj );
+                                               }
+                                       }
+                                       if ( matches.length ) {
+                                               handlerQueue.push({ elem: cur, handlers: matches });
+                                       }
+                               }
+                       }
+               }
+
+               // Add the remaining (directly-bound) handlers
+               if ( delegateCount < handlers.length ) {
+                       handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+               }
+
+               return handlerQueue;
+       },
+
+       fix: function( event ) {
+               if ( event[ jQuery.expando ] ) {
+                       return event;
+               }
+
+               // Create a writable copy of the event object and normalize some properties
+               var i, prop, copy,
+                       type = event.type,
+                       originalEvent = event,
+                       fixHook = this.fixHooks[ type ];
+
+               if ( !fixHook ) {
+                       this.fixHooks[ type ] = fixHook =
+                               rmouseEvent.test( type ) ? this.mouseHooks :
+                               rkeyEvent.test( type ) ? this.keyHooks :
+                               {};
+               }
+               copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+               event = new jQuery.Event( originalEvent );
+
+               i = copy.length;
+               while ( i-- ) {
+                       prop = copy[ i ];
+                       event[ prop ] = originalEvent[ prop ];
+               }
+
+               // Support: IE<9
+               // Fix target property (#1925)
+               if ( !event.target ) {
+                       event.target = originalEvent.srcElement || document;
+               }
+
+               // Support: Chrome 23+, Safari?
+               // Target should not be a text node (#504, #13143)
+               if ( event.target.nodeType === 3 ) {
+                       event.target = event.target.parentNode;
+               }
+
+               // Support: IE<9
+               // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+               event.metaKey = !!event.metaKey;
+
+               return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+       },
+
+       // Includes some event props shared by KeyEvent and MouseEvent
+       props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+       fixHooks: {},
+
+       keyHooks: {
+               props: "char charCode key keyCode".split(" "),
+               filter: function( event, original ) {
+
+                       // Add which for key events
+                       if ( event.which == null ) {
+                               event.which = original.charCode != null ? original.charCode : original.keyCode;
+                       }
+
+                       return event;
+               }
+       },
+
+       mouseHooks: {
+               props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+               filter: function( event, original ) {
+                       var body, eventDoc, doc,
+                               button = original.button,
+                               fromElement = original.fromElement;
+
+                       // Calculate pageX/Y if missing and clientX/Y available
+                       if ( event.pageX == null && original.clientX != null ) {
+                               eventDoc = event.target.ownerDocument || document;
+                               doc = eventDoc.documentElement;
+                               body = eventDoc.body;
+
+                               event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+                               event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+                       }
+
+                       // Add relatedTarget, if necessary
+                       if ( !event.relatedTarget && fromElement ) {
+                               event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+                       }
+
+                       // Add which for click: 1 === left; 2 === middle; 3 === right
+                       // Note: button is not normalized, so don't use it
+                       if ( !event.which && button !== undefined ) {
+                               event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+                       }
+
+                       return event;
+               }
+       },
+
+       special: {
+               load: {
+                       // Prevent triggered image.load events from bubbling to window.load
+                       noBubble: true
+               },
+               focus: {
+                       // Fire native event if possible so blur/focus sequence is correct
+                       trigger: function() {
+                               if ( this !== safeActiveElement() && this.focus ) {
+                                       try {
+                                               this.focus();
+                                               return false;
+                                       } catch ( e ) {
+                                               // Support: IE<9
+                                               // If we error on focus to hidden element (#1486, #12518),
+                                               // let .trigger() run the handlers
+                                       }
+                               }
+                       },
+                       delegateType: "focusin"
+               },
+               blur: {
+                       trigger: function() {
+                               if ( this === safeActiveElement() && this.blur ) {
+                                       this.blur();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusout"
+               },
+               click: {
+                       // For checkbox, fire native event so checked state will be right
+                       trigger: function() {
+                               if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+                                       this.click();
+                                       return false;
+                               }
+                       },
+
+                       // For cross-browser consistency, don't fire native .click() on links
+                       _default: function( event ) {
+                               return jQuery.nodeName( event.target, "a" );
+                       }
+               },
+
+               beforeunload: {
+                       postDispatch: function( event ) {
+
+                               // Even when returnValue equals to undefined Firefox will still show alert
+                               if ( event.result !== undefined ) {
+                                       event.originalEvent.returnValue = event.result;
+                               }
+                       }
+               }
+       },
+
+       simulate: function( type, elem, event, bubble ) {
+               // Piggyback on a donor event to simulate a different one.
+               // Fake originalEvent to avoid donor's stopPropagation, but if the
+               // simulated event prevents default then we do the same on the donor.
+               var e = jQuery.extend(
+                       new jQuery.Event(),
+                       event,
+                       {
+                               type: type,
+                               isSimulated: true,
+                               originalEvent: {}
+                       }
+               );
+               if ( bubble ) {
+                       jQuery.event.trigger( e, null, elem );
+               } else {
+                       jQuery.event.dispatch.call( elem, e );
+               }
+               if ( e.isDefaultPrevented() ) {
+                       event.preventDefault();
+               }
+       }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+       function( elem, type, handle ) {
+               if ( elem.removeEventListener ) {
+                       elem.removeEventListener( type, handle, false );
+               }
+       } :
+       function( elem, type, handle ) {
+               var name = "on" + type;
+
+               if ( elem.detachEvent ) {
+
+                       // #8545, #7054, preventing memory leaks for custom events in IE6-8
+                       // detachEvent needed property on element, by name of that event, to properly expose it to GC
+                       if ( typeof elem[ name ] === core_strundefined ) {
+                               elem[ name ] = null;
+                       }
+
+                       elem.detachEvent( name, handle );
+               }
+       };
+
+jQuery.Event = function( src, props ) {
+       // Allow instantiation without the 'new' keyword
+       if ( !(this instanceof jQuery.Event) ) {
+               return new jQuery.Event( src, props );
+       }
+
+       // Event object
+       if ( src && src.type ) {
+               this.originalEvent = src;
+               this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+                       src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+       // Event type
+       } else {
+               this.type = src;
+       }
+
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
+       // Create a timestamp if incoming event doesn't have one
+       this.timeStamp = src && src.timeStamp || jQuery.now();
+
+       // Mark it as fixed
+       this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+       isDefaultPrevented: returnFalse,
+       isPropagationStopped: returnFalse,
+       isImmediatePropagationStopped: returnFalse,
+
+       preventDefault: function() {
+               var e = this.originalEvent;
+
+               this.isDefaultPrevented = returnTrue;
+               if ( !e ) {
+                       return;
+               }
+
+               // If preventDefault exists, run it on the original event
+               if ( e.preventDefault ) {
+                       e.preventDefault();
+
+               // Support: IE
+               // Otherwise set the returnValue property of the original event to false
+               } else {
+                       e.returnValue = false;
+               }
+       },
+       stopPropagation: function() {
+               var e = this.originalEvent;
+
+               this.isPropagationStopped = returnTrue;
+               if ( !e ) {
+                       return;
+               }
+               // If stopPropagation exists, run it on the original event
+               if ( e.stopPropagation ) {
+                       e.stopPropagation();
+               }
+
+               // Support: IE
+               // Set the cancelBubble property of the original event to true
+               e.cancelBubble = true;
+       },
+       stopImmediatePropagation: function() {
+               this.isImmediatePropagationStopped = returnTrue;
+               this.stopPropagation();
+       }
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+       mouseenter: "mouseover",
+       mouseleave: "mouseout"
+}, function( orig, fix ) {
+       jQuery.event.special[ orig ] = {
+               delegateType: fix,
+               bindType: fix,
+
+               handle: function( event ) {
+                       var ret,
+                               target = this,
+                               related = event.relatedTarget,
+                               handleObj = event.handleObj;
+
+                       // For mousenter/leave call the handler if related is outside the target.
+                       // NB: No relatedTarget if the mouse left/entered the browser window
+                       if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+                               event.type = handleObj.origType;
+                               ret = handleObj.handler.apply( this, arguments );
+                               event.type = fix;
+                       }
+                       return ret;
+               }
+       };
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+       jQuery.event.special.submit = {
+               setup: function() {
+                       // Only need this for delegated form submit events
+                       if ( jQuery.nodeName( this, "form" ) ) {
+                               return false;
+                       }
+
+                       // Lazy-add a submit handler when a descendant form may potentially be submitted
+                       jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+                               // Node name check avoids a VML-related crash in IE (#9807)
+                               var elem = e.target,
+                                       form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+                               if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+                                       jQuery.event.add( form, "submit._submit", function( event ) {
+                                               event._submit_bubble = true;
+                                       });
+                                       jQuery._data( form, "submitBubbles", true );
+                               }
+                       });
+                       // return undefined since we don't need an event listener
+               },
+
+               postDispatch: function( event ) {
+                       // If form was submitted by the user, bubble the event up the tree
+                       if ( event._submit_bubble ) {
+                               delete event._submit_bubble;
+                               if ( this.parentNode && !event.isTrigger ) {
+                                       jQuery.event.simulate( "submit", this.parentNode, event, true );
+                               }
+                       }
+               },
+
+               teardown: function() {
+                       // Only need this for delegated form submit events
+                       if ( jQuery.nodeName( this, "form" ) ) {
+                               return false;
+                       }
+
+                       // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+                       jQuery.event.remove( this, "._submit" );
+               }
+       };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+       jQuery.event.special.change = {
+
+               setup: function() {
+
+                       if ( rformElems.test( this.nodeName ) ) {
+                               // IE doesn't fire change on a check/radio until blur; trigger it on click
+                               // after a propertychange. Eat the blur-change in special.change.handle.
+                               // This still fires onchange a second time for check/radio after blur.
+                               if ( this.type === "checkbox" || this.type === "radio" ) {
+                                       jQuery.event.add( this, "propertychange._change", function( event ) {
+                                               if ( event.originalEvent.propertyName === "checked" ) {
+                                                       this._just_changed = true;
+                                               }
+                                       });
+                                       jQuery.event.add( this, "click._change", function( event ) {
+                                               if ( this._just_changed && !event.isTrigger ) {
+                                                       this._just_changed = false;
+                                               }
+                                               // Allow triggered, simulated change events (#11500)
+                                               jQuery.event.simulate( "change", this, event, true );
+                                       });
+                               }
+                               return false;
+                       }
+                       // Delegated event; lazy-add a change handler on descendant inputs
+                       jQuery.event.add( this, "beforeactivate._change", function( e ) {
+                               var elem = e.target;
+
+                               if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+                                       jQuery.event.add( elem, "change._change", function( event ) {
+                                               if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+                                                       jQuery.event.simulate( "change", this.parentNode, event, true );
+                                               }
+                                       });
+                                       jQuery._data( elem, "changeBubbles", true );
+                               }
+                       });
+               },
+
+               handle: function( event ) {
+                       var elem = event.target;
+
+                       // Swallow native change events from checkbox/radio, we already triggered them above
+                       if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+                               return event.handleObj.handler.apply( this, arguments );
+                       }
+               },
+
+               teardown: function() {
+                       jQuery.event.remove( this, "._change" );
+
+                       return !rformElems.test( this.nodeName );
+               }
+       };
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+       jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler while someone wants focusin/focusout
+               var attaches = 0,
+                       handler = function( event ) {
+                               jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+                       };
+
+               jQuery.event.special[ fix ] = {
+                       setup: function() {
+                               if ( attaches++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
+                       },
+                       teardown: function() {
+                               if ( --attaches === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
+                       }
+               };
+       });
+}
+
+jQuery.fn.extend({
+
+       on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+               var type, origFn;
+
+               // Types can be a map of types/handlers
+               if ( typeof types === "object" ) {
+                       // ( types-Object, selector, data )
+                       if ( typeof selector !== "string" ) {
+                               // ( types-Object, data )
+                               data = data || selector;
+                               selector = undefined;
+                       }
+                       for ( type in types ) {
+                               this.on( type, selector, data, types[ type ], one );
+                       }
+                       return this;
+               }
+
+               if ( data == null && fn == null ) {
+                       // ( types, fn )
+                       fn = selector;
+                       data = selector = undefined;
+               } else if ( fn == null ) {
+                       if ( typeof selector === "string" ) {
+                               // ( types, selector, fn )
+                               fn = data;
+                               data = undefined;
+                       } else {
+                               // ( types, data, fn )
+                               fn = data;
+                               data = selector;
+                               selector = undefined;
+                       }
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               } else if ( !fn ) {
+                       return this;
+               }
+
+               if ( one === 1 ) {
+                       origFn = fn;
+                       fn = function( event ) {
+                               // Can use an empty set, since event contains the info
+                               jQuery().off( event );
+                               return origFn.apply( this, arguments );
+                       };
+                       // Use same guid so caller can remove using origFn
+                       fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+               }
+               return this.each( function() {
+                       jQuery.event.add( this, types, fn, data, selector );
+               });
+       },
+       one: function( types, selector, data, fn ) {
+               return this.on( types, selector, data, fn, 1 );
+       },
+       off: function( types, selector, fn ) {
+               var handleObj, type;
+               if ( types && types.preventDefault && types.handleObj ) {
+                       // ( event )  dispatched jQuery.Event
+                       handleObj = types.handleObj;
+                       jQuery( types.delegateTarget ).off(
+                               handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+                               handleObj.selector,
+                               handleObj.handler
+                       );
+                       return this;
+               }
+               if ( typeof types === "object" ) {
+                       // ( types-object [, selector] )
+                       for ( type in types ) {
+                               this.off( type, selector, types[ type ] );
+                       }
+                       return this;
+               }
+               if ( selector === false || typeof selector === "function" ) {
+                       // ( types [, fn] )
+                       fn = selector;
+                       selector = undefined;
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               }
+               return this.each(function() {
+                       jQuery.event.remove( this, types, fn, selector );
+               });
+       },
+
+       trigger: function( type, data ) {
+               return this.each(function() {
+                       jQuery.event.trigger( type, data, this );
+               });
+       },
+       triggerHandler: function( type, data ) {
+               var elem = this[0];
+               if ( elem ) {
+                       return jQuery.event.trigger( type, data, elem, true );
+               }
+       }
+});
+var isSimple = /^.[^:#\[\.,]*$/,
+       rparentsprev = /^(?:parents|prev(?:Until|All))/,
+       rneedsContext = jQuery.expr.match.needsContext,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
+
+jQuery.fn.extend({
+       find: function( selector ) {
+               var i,
+                       ret = [],
+                       self = this,
+                       len = self.length;
+
+               if ( typeof selector !== "string" ) {
+                       return this.pushStack( jQuery( selector ).filter(function() {
+                               for ( i = 0; i < len; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       }) );
+               }
+
+               for ( i = 0; i < len; i++ ) {
+                       jQuery.find( selector, self[ i ], ret );
+               }
+
+               // Needed because $( selector, context ) becomes $( context ).find( selector )
+               ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+               ret.selector = this.selector ? this.selector + " " + selector : selector;
+               return ret;
+       },
+
+       has: function( target ) {
+               var i,
+                       targets = jQuery( target, this ),
+                       len = targets.length;
+
+               return this.filter(function() {
+                       for ( i = 0; i < len; i++ ) {
+                               if ( jQuery.contains( this, targets[i] ) ) {
+                                       return true;
+                               }
+                       }
+               });
+       },
+
+       not: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], true) );
+       },
+
+       filter: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], false) );
+       },
+
+       is: function( selector ) {
+               return !!winnow(
+                       this,
+
+                       // If this is a positional/relative selector, check membership in the returned set
+                       // so $("p:first").is("p:last") won't return true for a doc with two "p".
+                       typeof selector === "string" && rneedsContext.test( selector ) ?
+                               jQuery( selector ) :
+                               selector || [],
+                       false
+               ).length;
+       },
+
+       closest: function( selectors, context ) {
+               var cur,
+                       i = 0,
+                       l = this.length,
+                       ret = [],
+                       pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+                               jQuery( selectors, context || this.context ) :
+                               0;
+
+               for ( ; i < l; i++ ) {
+                       for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+                               // Always skip document fragments
+                               if ( cur.nodeType < 11 && (pos ?
+                                       pos.index(cur) > -1 :
+
+                                       // Don't pass non-elements to Sizzle
+                                       cur.nodeType === 1 &&
+                                               jQuery.find.matchesSelector(cur, selectors)) ) {
+
+                                       cur = ret.push( cur );
+                                       break;
+                               }
+                       }
+               }
+
+               return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+       },
+
+       // Determine the position of an element within
+       // the matched set of elements
+       index: function( elem ) {
+
+               // No argument, return index in parent
+               if ( !elem ) {
+                       return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+               }
+
+               // index in selector
+               if ( typeof elem === "string" ) {
+                       return jQuery.inArray( this[0], jQuery( elem ) );
+               }
+
+               // Locate the position of the desired element
+               return jQuery.inArray(
+                       // If it receives a jQuery object, the first element is used
+                       elem.jquery ? elem[0] : elem, this );
+       },
+
+       add: function( selector, context ) {
+               var set = typeof selector === "string" ?
+                               jQuery( selector, context ) :
+                               jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+                       all = jQuery.merge( this.get(), set );
+
+               return this.pushStack( jQuery.unique(all) );
+       },
+
+       addBack: function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter(selector)
+               );
+       }
+});
+
+function sibling( cur, dir ) {
+       do {
+               cur = cur[ dir ];
+       } while ( cur && cur.nodeType !== 1 );
+
+       return cur;
+}
+
+jQuery.each({
+       parent: function( elem ) {
+               var parent = elem.parentNode;
+               return parent && parent.nodeType !== 11 ? parent : null;
+       },
+       parents: function( elem ) {
+               return jQuery.dir( elem, "parentNode" );
+       },
+       parentsUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "parentNode", until );
+       },
+       next: function( elem ) {
+               return sibling( elem, "nextSibling" );
+       },
+       prev: function( elem ) {
+               return sibling( elem, "previousSibling" );
+       },
+       nextAll: function( elem ) {
+               return jQuery.dir( elem, "nextSibling" );
+       },
+       prevAll: function( elem ) {
+               return jQuery.dir( elem, "previousSibling" );
+       },
+       nextUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "nextSibling", until );
+       },
+       prevUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "previousSibling", until );
+       },
+       siblings: function( elem ) {
+               return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+       },
+       children: function( elem ) {
+               return jQuery.sibling( elem.firstChild );
+       },
+       contents: function( elem ) {
+               return jQuery.nodeName( elem, "iframe" ) ?
+                       elem.contentDocument || elem.contentWindow.document :
+                       jQuery.merge( [], elem.childNodes );
+       }
+}, function( name, fn ) {
+       jQuery.fn[ name ] = function( until, selector ) {
+               var ret = jQuery.map( this, fn, until );
+
+               if ( name.slice( -5 ) !== "Until" ) {
+                       selector = until;
+               }
+
+               if ( selector && typeof selector === "string" ) {
+                       ret = jQuery.filter( selector, ret );
+               }
+
+               if ( this.length > 1 ) {
+                       // Remove duplicates
+                       if ( !guaranteedUnique[ name ] ) {
+                               ret = jQuery.unique( ret );
+                       }
+
+                       // Reverse order for parents* and prev-derivatives
+                       if ( rparentsprev.test( name ) ) {
+                               ret = ret.reverse();
+                       }
+               }
+
+               return this.pushStack( ret );
+       };
+});
+
+jQuery.extend({
+       filter: function( expr, elems, not ) {
+               var elem = elems[ 0 ];
+
+               if ( not ) {
+                       expr = ":not(" + expr + ")";
+               }
+
+               return elems.length === 1 && elem.nodeType === 1 ?
+                       jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+                       jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+                               return elem.nodeType === 1;
+                       }));
+       },
+
+       dir: function( elem, dir, until ) {
+               var matched = [],
+                       cur = elem[ dir ];
+
+               while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+                       if ( cur.nodeType === 1 ) {
+                               matched.push( cur );
+                       }
+                       cur = cur[dir];
+               }
+               return matched;
+       },
+
+       sibling: function( n, elem ) {
+               var r = [];
+
+               for ( ; n; n = n.nextSibling ) {
+                       if ( n.nodeType === 1 && n !== elem ) {
+                               r.push( n );
+                       }
+               }
+
+               return r;
+       }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+       if ( jQuery.isFunction( qualifier ) ) {
+               return jQuery.grep( elements, function( elem, i ) {
+                       /* jshint -W018 */
+                       return !!qualifier.call( elem, i, elem ) !== not;
+               });
+
+       }
+
+       if ( qualifier.nodeType ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( elem === qualifier ) !== not;
+               });
+
+       }
+
+       if ( typeof qualifier === "string" ) {
+               if ( isSimple.test( qualifier ) ) {
+                       return jQuery.filter( qualifier, elements, not );
+               }
+
+               qualifier = jQuery.filter( qualifier, elements );
+       }
+
+       return jQuery.grep( elements, function( elem ) {
+               return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
+       });
+}
+function createSafeFragment( document ) {
+       var list = nodeNames.split( "|" ),
+               safeFrag = document.createDocumentFragment();
+
+       if ( safeFrag.createElement ) {
+               while ( list.length ) {
+                       safeFrag.createElement(
+                               list.pop()
+                       );
+               }
+       }
+       return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+               "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+       rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+       rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+       rleadingWhitespace = /^\s+/,
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+       rtagName = /<([\w:]+)/,
+       rtbody = /<tbody/i,
+       rhtml = /<|&#?\w+;/,
+       rnoInnerhtml = /<(?:script|style|link)/i,
+       manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+       // checked="checked" or checked
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+       rscriptType = /^$|\/(?:java|ecma)script/i,
+       rscriptTypeMasked = /^true\/(.*)/,
+       rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+       // We have to close these tags to support XHTML (#13200)
+       wrapMap = {
+               option: [ 1, "<select multiple='multiple'>", "</select>" ],
+               legend: [ 1, "<fieldset>", "</fieldset>" ],
+               area: [ 1, "<map>", "</map>" ],
+               param: [ 1, "<object>", "</object>" ],
+               thead: [ 1, "<table>", "</table>" ],
+               tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+               col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+               td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+               // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+               // unless wrapped in a div with non-breaking characters in front of it.
+               _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+       },
+       safeFragment = createSafeFragment( document ),
+       fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+jQuery.fn.extend({
+       text: function( value ) {
+               return jQuery.access( this, function( value ) {
+                       return value === undefined ?
+                               jQuery.text( this ) :
+                               this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+               }, null, value, arguments.length );
+       },
+
+       append: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.appendChild( elem );
+                       }
+               });
+       },
+
+       prepend: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.insertBefore( elem, target.firstChild );
+                       }
+               });
+       },
+
+       before: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this );
+                       }
+               });
+       },
+
+       after: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this.nextSibling );
+                       }
+               });
+       },
+
+       // keepData is for internal use only--do not document
+       remove: function( selector, keepData ) {
+               var elem,
+                       elems = selector ? jQuery.filter( selector, this ) : this,
+                       i = 0;
+
+               for ( ; (elem = elems[i]) != null; i++ ) {
+
+                       if ( !keepData && elem.nodeType === 1 ) {
+                               jQuery.cleanData( getAll( elem ) );
+                       }
+
+                       if ( elem.parentNode ) {
+                               if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+                                       setGlobalEval( getAll( elem, "script" ) );
+                               }
+                               elem.parentNode.removeChild( elem );
+                       }
+               }
+
+               return this;
+       },
+
+       empty: function() {
+               var elem,
+                       i = 0;
+
+               for ( ; (elem = this[i]) != null; i++ ) {
+                       // Remove element nodes and prevent memory leaks
+                       if ( elem.nodeType === 1 ) {
+                               jQuery.cleanData( getAll( elem, false ) );
+                       }
+
+                       // Remove any remaining nodes
+                       while ( elem.firstChild ) {
+                               elem.removeChild( elem.firstChild );
+                       }
+
+                       // If this is a select, ensure that it displays empty (#12336)
+                       // Support: IE<9
+                       if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+                               elem.options.length = 0;
+                       }
+               }
+
+               return this;
+       },
+
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+               return this.map( function () {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               });
+       },
+
+       html: function( value ) {
+               return jQuery.access( this, function( value ) {
+                       var elem = this[0] || {},
+                               i = 0,
+                               l = this.length;
+
+                       if ( value === undefined ) {
+                               return elem.nodeType === 1 ?
+                                       elem.innerHTML.replace( rinlinejQuery, "" ) :
+                                       undefined;
+                       }
+
+                       // See if we can take a shortcut and just use innerHTML
+                       if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+                               ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+                               ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+                               !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+                               value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+                               try {
+                                       for (; i < l; i++ ) {
+                                               // Remove element nodes and prevent memory leaks
+                                               elem = this[i] || {};
+                                               if ( elem.nodeType === 1 ) {
+                                                       jQuery.cleanData( getAll( elem, false ) );
+                                                       elem.innerHTML = value;
+                                               }
+                                       }
+
+                                       elem = 0;
+
+                               // If using innerHTML throws an exception, use the fallback method
+                               } catch(e) {}
+                       }
+
+                       if ( elem ) {
+                               this.empty().append( value );
+                       }
+               }, null, value, arguments.length );
+       },
+
+       replaceWith: function() {
+               var
+                       // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
+                       args = jQuery.map( this, function( elem ) {
+                               return [ elem.nextSibling, elem.parentNode ];
+                       }),
+                       i = 0;
+
+               // Make the changes, replacing each context element with the new content
+               this.domManip( arguments, function( elem ) {
+                       var next = args[ i++ ],
+                               parent = args[ i++ ];
+
+                       if ( parent ) {
+                               // Don't use the snapshot next if it has moved (#13810)
+                               if ( next && next.parentNode !== parent ) {
+                                       next = this.nextSibling;
+                               }
+                               jQuery( this ).remove();
+                               parent.insertBefore( elem, next );
+                       }
+               // Allow new content to include elements from the context set
+               }, true );
+
+               // Force removal if there was no new content (e.g., from empty arguments)
+               return i ? this : this.remove();
+       },
+
+       detach: function( selector ) {
+               return this.remove( selector, true );
+       },
+
+       domManip: function( args, callback, allowIntersection ) {
+
+               // Flatten any nested arrays
+               args = core_concat.apply( [], args );
+
+               var first, node, hasScripts,
+                       scripts, doc, fragment,
+                       i = 0,
+                       l = this.length,
+                       set = this,
+                       iNoClone = l - 1,
+                       value = args[0],
+                       isFunction = jQuery.isFunction( value );
+
+               // We can't cloneNode fragments that contain checked, in WebKit
+               if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+                       return this.each(function( index ) {
+                               var self = set.eq( index );
+                               if ( isFunction ) {
+                                       args[0] = value.call( this, index, self.html() );
+                               }
+                               self.domManip( args, callback, allowIntersection );
+                       });
+               }
+
+               if ( l ) {
+                       fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
+                       first = fragment.firstChild;
+
+                       if ( fragment.childNodes.length === 1 ) {
+                               fragment = first;
+                       }
+
+                       if ( first ) {
+                               scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+                               hasScripts = scripts.length;
+
+                               // Use the original fragment for the last item instead of the first because it can end up
+                               // being emptied incorrectly in certain situations (#8070).
+                               for ( ; i < l; i++ ) {
+                                       node = fragment;
+
+                                       if ( i !== iNoClone ) {
+                                               node = jQuery.clone( node, true, true );
+
+                                               // Keep references to cloned scripts for later restoration
+                                               if ( hasScripts ) {
+                                                       jQuery.merge( scripts, getAll( node, "script" ) );
+                                               }
+                                       }
+
+                                       callback.call( this[i], node, i );
+                               }
+
+                               if ( hasScripts ) {
+                                       doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+                                       // Reenable scripts
+                                       jQuery.map( scripts, restoreScript );
+
+                                       // Evaluate executable scripts on first document insertion
+                                       for ( i = 0; i < hasScripts; i++ ) {
+                                               node = scripts[ i ];
+                                               if ( rscriptType.test( node.type || "" ) &&
+                                                       !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+                                                       if ( node.src ) {
+                                                               // Hope ajax is available...
+                                                               jQuery._evalUrl( node.src );
+                                                       } else {
+                                                               jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Fix #11809: Avoid leaking memory
+                               fragment = first = null;
+                       }
+               }
+
+               return this;
+       }
+});
+
+// Support: IE<8
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+       return jQuery.nodeName( elem, "table" ) &&
+               jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
+
+               elem.getElementsByTagName("tbody")[0] ||
+                       elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
+               elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+       elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
+       return elem;
+}
+function restoreScript( elem ) {
+       var match = rscriptTypeMasked.exec( elem.type );
+       if ( match ) {
+               elem.type = match[1];
+       } else {
+               elem.removeAttribute("type");
+       }
+       return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+       var elem,
+               i = 0;
+       for ( ; (elem = elems[i]) != null; i++ ) {
+               jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+       }
+}
+
+function cloneCopyEvent( src, dest ) {
+
+       if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+               return;
+       }
+
+       var type, i, l,
+               oldData = jQuery._data( src ),
+               curData = jQuery._data( dest, oldData ),
+               events = oldData.events;
+
+       if ( events ) {
+               delete curData.handle;
+               curData.events = {};
+
+               for ( type in events ) {
+                       for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+                               jQuery.event.add( dest, type, events[ type ][ i ] );
+                       }
+               }
+       }
+
+       // make the cloned public data object a copy from the original
+       if ( curData.data ) {
+               curData.data = jQuery.extend( {}, curData.data );
+       }
+}
+
+function fixCloneNodeIssues( src, dest ) {
+       var nodeName, e, data;
+
+       // We do not need to do anything for non-Elements
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       nodeName = dest.nodeName.toLowerCase();
+
+       // IE6-8 copies events bound via attachEvent when using cloneNode.
+       if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+               data = jQuery._data( dest );
+
+               for ( e in data.events ) {
+                       jQuery.removeEvent( dest, e, data.handle );
+               }
+
+               // Event data gets referenced instead of copied if the expando gets copied too
+               dest.removeAttribute( jQuery.expando );
+       }
+
+       // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+       if ( nodeName === "script" && dest.text !== src.text ) {
+               disableScript( dest ).text = src.text;
+               restoreScript( dest );
+
+       // IE6-10 improperly clones children of object elements using classid.
+       // IE10 throws NoModificationAllowedError if parent is null, #12132.
+       } else if ( nodeName === "object" ) {
+               if ( dest.parentNode ) {
+                       dest.outerHTML = src.outerHTML;
+               }
+
+               // This path appears unavoidable for IE9. When cloning an object
+               // element in IE9, the outerHTML strategy above is not sufficient.
+               // If the src has innerHTML and the destination does not,
+               // copy the src.innerHTML into the dest.innerHTML. #10324
+               if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+                       dest.innerHTML = src.innerHTML;
+               }
+
+       } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+               // IE6-8 fails to persist the checked state of a cloned checkbox
+               // or radio button. Worse, IE6-7 fail to give the cloned element
+               // a checked appearance if the defaultChecked value isn't also set
+
+               dest.defaultChecked = dest.checked = src.checked;
+
+               // IE6-7 get confused and end up setting the value of a cloned
+               // checkbox/radio button to an empty string instead of "on"
+               if ( dest.value !== src.value ) {
+                       dest.value = src.value;
+               }
+
+       // IE6-8 fails to return the selected option to the default selected
+       // state when cloning options
+       } else if ( nodeName === "option" ) {
+               dest.defaultSelected = dest.selected = src.defaultSelected;
+
+       // IE6-8 fails to set the defaultValue to the correct value when
+       // cloning other types of input fields
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+}
+
+jQuery.each({
+       appendTo: "append",
+       prependTo: "prepend",
+       insertBefore: "before",
+       insertAfter: "after",
+       replaceAll: "replaceWith"
+}, function( name, original ) {
+       jQuery.fn[ name ] = function( selector ) {
+               var elems,
+                       i = 0,
+                       ret = [],
+                       insert = jQuery( selector ),
+                       last = insert.length - 1;
+
+               for ( ; i <= last; i++ ) {
+                       elems = i === last ? this : this.clone(true);
+                       jQuery( insert[i] )[ original ]( elems );
+
+                       // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+                       core_push.apply( ret, elems.get() );
+               }
+
+               return this.pushStack( ret );
+       };
+});
+
+function getAll( context, tag ) {
+       var elems, elem,
+               i = 0,
+               found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+                       typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+                       undefined;
+
+       if ( !found ) {
+               for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+                       if ( !tag || jQuery.nodeName( elem, tag ) ) {
+                               found.push( elem );
+                       } else {
+                               jQuery.merge( found, getAll( elem, tag ) );
+                       }
+               }
+       }
+
+       return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+               jQuery.merge( [ context ], found ) :
+               found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+       if ( manipulation_rcheckableType.test( elem.type ) ) {
+               elem.defaultChecked = elem.checked;
+       }
+}
+
+jQuery.extend({
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var destElements, node, clone, i, srcElements,
+                       inPage = jQuery.contains( elem.ownerDocument, elem );
+
+               if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+                       clone = elem.cloneNode( true );
+
+               // IE<=8 does not properly clone detached, unknown element nodes
+               } else {
+                       fragmentDiv.innerHTML = elem.outerHTML;
+                       fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+               }
+
+               if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+                               (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+                       // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+                       destElements = getAll( clone );
+                       srcElements = getAll( elem );
+
+                       // Fix all IE cloning issues
+                       for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+                               // Ensure that the destination node is not null; Fixes #9587
+                               if ( destElements[i] ) {
+                                       fixCloneNodeIssues( node, destElements[i] );
+                               }
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       if ( deepDataAndEvents ) {
+                               srcElements = srcElements || getAll( elem );
+                               destElements = destElements || getAll( clone );
+
+                               for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+                                       cloneCopyEvent( node, destElements[i] );
+                               }
+                       } else {
+                               cloneCopyEvent( elem, clone );
+                       }
+               }
+
+               // Preserve script evaluation history
+               destElements = getAll( clone, "script" );
+               if ( destElements.length > 0 ) {
+                       setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+               }
+
+               destElements = srcElements = node = null;
+
+               // Return the cloned set
+               return clone;
+       },
+
+       buildFragment: function( elems, context, scripts, selection ) {
+               var j, elem, contains,
+                       tmp, tag, tbody, wrap,
+                       l = elems.length,
+
+                       // Ensure a safe fragment
+                       safe = createSafeFragment( context ),
+
+                       nodes = [],
+                       i = 0;
+
+               for ( ; i < l; i++ ) {
+                       elem = elems[ i ];
+
+                       if ( elem || elem === 0 ) {
+
+                               // Add nodes directly
+                               if ( jQuery.type( elem ) === "object" ) {
+                                       jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+                               // Convert non-html into a text node
+                               } else if ( !rhtml.test( elem ) ) {
+                                       nodes.push( context.createTextNode( elem ) );
+
+                               // Convert html into DOM nodes
+                               } else {
+                                       tmp = tmp || safe.appendChild( context.createElement("div") );
+
+                                       // Deserialize a standard representation
+                                       tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+                                       wrap = wrapMap[ tag ] || wrapMap._default;
+
+                                       tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+                                       // Descend through wrappers to the right content
+                                       j = wrap[0];
+                                       while ( j-- ) {
+                                               tmp = tmp.lastChild;
+                                       }
+
+                                       // Manually add leading whitespace removed by IE
+                                       if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+                                               nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+                                       }
+
+                                       // Remove IE's autoinserted <tbody> from table fragments
+                                       if ( !jQuery.support.tbody ) {
+
+                                               // String was a <table>, *may* have spurious <tbody>
+                                               elem = tag === "table" && !rtbody.test( elem ) ?
+                                                       tmp.firstChild :
+
+                                                       // String was a bare <thead> or <tfoot>
+                                                       wrap[1] === "<table>" && !rtbody.test( elem ) ?
+                                                               tmp :
+                                                               0;
+
+                                               j = elem && elem.childNodes.length;
+                                               while ( j-- ) {
+                                                       if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+                                                               elem.removeChild( tbody );
+                                                       }
+                                               }
+                                       }
+
+                                       jQuery.merge( nodes, tmp.childNodes );
+
+                                       // Fix #12392 for WebKit and IE > 9
+                                       tmp.textContent = "";
+
+                                       // Fix #12392 for oldIE
+                                       while ( tmp.firstChild ) {
+                                               tmp.removeChild( tmp.firstChild );
+                                       }
+
+                                       // Remember the top-level container for proper cleanup
+                                       tmp = safe.lastChild;
+                               }
+                       }
+               }
+
+               // Fix #11356: Clear elements from fragment
+               if ( tmp ) {
+                       safe.removeChild( tmp );
+               }
+
+               // Reset defaultChecked for any radios and checkboxes
+               // about to be appended to the DOM in IE 6/7 (#8060)
+               if ( !jQuery.support.appendChecked ) {
+                       jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+               }
+
+               i = 0;
+               while ( (elem = nodes[ i++ ]) ) {
+
+                       // #4087 - If origin and destination elements are the same, and this is
+                       // that element, do not do anything
+                       if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+                               continue;
+                       }
+
+                       contains = jQuery.contains( elem.ownerDocument, elem );
+
+                       // Append to fragment
+                       tmp = getAll( safe.appendChild( elem ), "script" );
+
+                       // Preserve script evaluation history
+                       if ( contains ) {
+                               setGlobalEval( tmp );
+                       }
+
+                       // Capture executables
+                       if ( scripts ) {
+                               j = 0;
+                               while ( (elem = tmp[ j++ ]) ) {
+                                       if ( rscriptType.test( elem.type || "" ) ) {
+                                               scripts.push( elem );
+                                       }
+                               }
+                       }
+               }
+
+               tmp = null;
+
+               return safe;
+       },
+
+       cleanData: function( elems, /* internal */ acceptData ) {
+               var elem, type, id, data,
+                       i = 0,
+                       internalKey = jQuery.expando,
+                       cache = jQuery.cache,
+                       deleteExpando = jQuery.support.deleteExpando,
+                       special = jQuery.event.special;
+
+               for ( ; (elem = elems[i]) != null; i++ ) {
+
+                       if ( acceptData || jQuery.acceptData( elem ) ) {
+
+                               id = elem[ internalKey ];
+                               data = id && cache[ id ];
+
+                               if ( data ) {
+                                       if ( data.events ) {
+                                               for ( type in data.events ) {
+                                                       if ( special[ type ] ) {
+                                                               jQuery.event.remove( elem, type );
+
+                                                       // This is a shortcut to avoid jQuery.event.remove's overhead
+                                                       } else {
+                                                               jQuery.removeEvent( elem, type, data.handle );
+                                                       }
+                                               }
+                                       }
+
+                                       // Remove cache only if it was not already removed by jQuery.event.remove
+                                       if ( cache[ id ] ) {
+
+                                               delete cache[ id ];
+
+                                               // IE does not allow us to delete expando properties from nodes,
+                                               // nor does it have a removeAttribute function on Document nodes;
+                                               // we must handle all of these cases
+                                               if ( deleteExpando ) {
+                                                       delete elem[ internalKey ];
+
+                                               } else if ( typeof elem.removeAttribute !== core_strundefined ) {
+                                                       elem.removeAttribute( internalKey );
+
+                                               } else {
+                                                       elem[ internalKey ] = null;
+                                               }
+
+                                               core_deletedIds.push( id );
+                                       }
+                               }
+                       }
+               }
+       },
+
+       _evalUrl: function( url ) {
+               return jQuery.ajax({
+                       url: url,
+                       type: "GET",
+                       dataType: "script",
+                       async: false,
+                       global: false,
+                       "throws": true
+               });
+       }
+});
+jQuery.fn.extend({
+       wrapAll: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapAll( html.call(this, i) );
+                       });
+               }
+
+               if ( this[0] ) {
+                       // The elements to wrap the target around
+                       var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+                       if ( this[0].parentNode ) {
+                               wrap.insertBefore( this[0] );
+                       }
+
+                       wrap.map(function() {
+                               var elem = this;
+
+                               while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+                                       elem = elem.firstChild;
+                               }
+
+                               return elem;
+                       }).append( this );
+               }
+
+               return this;
+       },
+
+       wrapInner: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function(i) {
+                               jQuery(this).wrapInner( html.call(this, i) );
+                       });
+               }
+
+               return this.each(function() {
+                       var self = jQuery( this ),
+                               contents = self.contents();
+
+                       if ( contents.length ) {
+                               contents.wrapAll( html );
+
+                       } else {
+                               self.append( html );
+                       }
+               });
+       },
+
+       wrap: function( html ) {
+               var isFunction = jQuery.isFunction( html );
+
+               return this.each(function(i) {
+                       jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+               });
+       },
+
+       unwrap: function() {
+               return this.parent().each(function() {
+                       if ( !jQuery.nodeName( this, "body" ) ) {
+                               jQuery( this ).replaceWith( this.childNodes );
+                       }
+               }).end();
+       }
+});
+var iframe, getStyles, curCSS,
+       ralpha = /alpha\([^)]*\)/i,
+       ropacity = /opacity\s*=\s*([^)]*)/,
+       rposition = /^(top|right|bottom|left)$/,
+       // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+       // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+       rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+       rmargin = /^margin/,
+       rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+       rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+       rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+       elemdisplay = { BODY: "block" },
+
+       cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+       cssNormalTransform = {
+               letterSpacing: 0,
+               fontWeight: 400
+       },
+
+       cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+       cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+       // shortcut for names that are not vendor prefixed
+       if ( name in style ) {
+               return name;
+       }
+
+       // check for vendor prefixed names
+       var capName = name.charAt(0).toUpperCase() + name.slice(1),
+               origName = name,
+               i = cssPrefixes.length;
+
+       while ( i-- ) {
+               name = cssPrefixes[ i ] + capName;
+               if ( name in style ) {
+                       return name;
+               }
+       }
+
+       return origName;
+}
+
+function isHidden( elem, el ) {
+       // isHidden might be called from jQuery#filter function;
+       // in that case, element will be second argument
+       elem = el || elem;
+       return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+       var display, elem, hidden,
+               values = [],
+               index = 0,
+               length = elements.length;
+
+       for ( ; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+
+               values[ index ] = jQuery._data( elem, "olddisplay" );
+               display = elem.style.display;
+               if ( show ) {
+                       // Reset the inline display of this element to learn if it is
+                       // being hidden by cascaded rules or not
+                       if ( !values[ index ] && display === "none" ) {
+                               elem.style.display = "";
+                       }
+
+                       // Set elements which have been overridden with display: none
+                       // in a stylesheet to whatever the default browser style is
+                       // for such an element
+                       if ( elem.style.display === "" && isHidden( elem ) ) {
+                               values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+                       }
+               } else {
+
+                       if ( !values[ index ] ) {
+                               hidden = isHidden( elem );
+
+                               if ( display && display !== "none" || !hidden ) {
+                                       jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+                               }
+                       }
+               }
+       }
+
+       // Set the display of most of the elements in a second loop
+       // to avoid the constant reflow
+       for ( index = 0; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+               if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+                       elem.style.display = show ? values[ index ] || "" : "none";
+               }
+       }
+
+       return elements;
+}
+
+jQuery.fn.extend({
+       css: function( name, value ) {
+               return jQuery.access( this, function( elem, name, value ) {
+                       var len, styles,
+                               map = {},
+                               i = 0;
+
+                       if ( jQuery.isArray( name ) ) {
+                               styles = getStyles( elem );
+                               len = name.length;
+
+                               for ( ; i < len; i++ ) {
+                                       map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+                               }
+
+                               return map;
+                       }
+
+                       return value !== undefined ?
+                               jQuery.style( elem, name, value ) :
+                               jQuery.css( elem, name );
+               }, name, value, arguments.length > 1 );
+       },
+       show: function() {
+               return showHide( this, true );
+       },
+       hide: function() {
+               return showHide( this );
+       },
+       toggle: function( state ) {
+               if ( typeof state === "boolean" ) {
+                       return state ? this.show() : this.hide();
+               }
+
+               return this.each(function() {
+                       if ( isHidden( this ) ) {
+                               jQuery( this ).show();
+                       } else {
+                               jQuery( this ).hide();
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       // Add in style property hooks for overriding the default
+       // behavior of getting and setting a style property
+       cssHooks: {
+               opacity: {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // We should always get a number back from opacity
+                                       var ret = curCSS( elem, "opacity" );
+                                       return ret === "" ? "1" : ret;
+                               }
+                       }
+               }
+       },
+
+       // Don't automatically add "px" to these possibly-unitless properties
+       cssNumber: {
+               "columnCount": true,
+               "fillOpacity": true,
+               "fontWeight": true,
+               "lineHeight": true,
+               "opacity": true,
+               "order": true,
+               "orphans": true,
+               "widows": true,
+               "zIndex": true,
+               "zoom": true
+       },
+
+       // Add in properties whose names you wish to fix before
+       // setting or getting the value
+       cssProps: {
+               // normalize float css property
+               "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+       },
+
+       // Get and set the style property on a DOM Node
+       style: function( elem, name, value, extra ) {
+               // Don't set styles on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+                       return;
+               }
+
+               // Make sure that we're working with the right name
+               var ret, type, hooks,
+                       origName = jQuery.camelCase( name ),
+                       style = elem.style;
+
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // Check if we're setting a value
+               if ( value !== undefined ) {
+                       type = typeof value;
+
+                       // convert relative number strings (+= or -=) to relative numbers. #7345
+                       if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+                               value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+                               // Fixes bug #9237
+                               type = "number";
+                       }
+
+                       // Make sure that NaN and null values aren't set. See: #7116
+                       if ( value == null || type === "number" && isNaN( value ) ) {
+                               return;
+                       }
+
+                       // If a number was passed in, add 'px' to the (except for certain CSS properties)
+                       if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+                               value += "px";
+                       }
+
+                       // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+                       // but it would mean to define eight (for every problematic property) identical functions
+                       if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+                               style[ name ] = "inherit";
+                       }
+
+                       // If a hook was provided, use that value, otherwise just set the specified value
+                       if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+                               // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+                               // Fixes bug #5509
+                               try {
+                                       style[ name ] = value;
+                               } catch(e) {}
+                       }
+
+               } else {
+                       // If a hook was provided get the non-computed value from there
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+                               return ret;
+                       }
+
+                       // Otherwise just get the value from the style object
+                       return style[ name ];
+               }
+       },
+
+       css: function( elem, name, extra, styles ) {
+               var num, val, hooks,
+                       origName = jQuery.camelCase( name );
+
+               // Make sure that we're working with the right name
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // If a hook was provided get the computed value from there
+               if ( hooks && "get" in hooks ) {
+                       val = hooks.get( elem, true, extra );
+               }
+
+               // Otherwise, if a way to get the computed value exists, use that
+               if ( val === undefined ) {
+                       val = curCSS( elem, name, styles );
+               }
+
+               //convert "normal" to computed value
+               if ( val === "normal" && name in cssNormalTransform ) {
+                       val = cssNormalTransform[ name ];
+               }
+
+               // Return, converting to number if forced or a qualifier was provided and val looks numeric
+               if ( extra === "" || extra ) {
+                       num = parseFloat( val );
+                       return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+               }
+               return val;
+       }
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+       getStyles = function( elem ) {
+               return window.getComputedStyle( elem, null );
+       };
+
+       curCSS = function( elem, name, _computed ) {
+               var width, minWidth, maxWidth,
+                       computed = _computed || getStyles( elem ),
+
+                       // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+                       ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+                       style = elem.style;
+
+               if ( computed ) {
+
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+                               ret = jQuery.style( elem, name );
+                       }
+
+                       // A tribute to the "awesome hack by Dean Edwards"
+                       // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+                       // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+                       // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+                       if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+                               // Remember the original values
+                               width = style.width;
+                               minWidth = style.minWidth;
+                               maxWidth = style.maxWidth;
+
+                               // Put in the new values to get a computed value out
+                               style.minWidth = style.maxWidth = style.width = ret;
+                               ret = computed.width;
+
+                               // Revert the changed values
+                               style.width = width;
+                               style.minWidth = minWidth;
+                               style.maxWidth = maxWidth;
+                       }
+               }
+
+               return ret;
+       };
+} else if ( document.documentElement.currentStyle ) {
+       getStyles = function( elem ) {
+               return elem.currentStyle;
+       };
+
+       curCSS = function( elem, name, _computed ) {
+               var left, rs, rsLeft,
+                       computed = _computed || getStyles( elem ),
+                       ret = computed ? computed[ name ] : undefined,
+                       style = elem.style;
+
+               // Avoid setting ret to empty string here
+               // so we don't default to auto
+               if ( ret == null && style && style[ name ] ) {
+                       ret = style[ name ];
+               }
+
+               // From the awesome hack by Dean Edwards
+               // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+               // If we're not dealing with a regular pixel number
+               // but a number that has a weird ending, we need to convert it to pixels
+               // but not position css attributes, as those are proportional to the parent element instead
+               // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+               if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+                       // Remember the original values
+                       left = style.left;
+                       rs = elem.runtimeStyle;
+                       rsLeft = rs && rs.left;
+
+                       // Put in the new values to get a computed value out
+                       if ( rsLeft ) {
+                               rs.left = elem.currentStyle.left;
+                       }
+                       style.left = name === "fontSize" ? "1em" : ret;
+                       ret = style.pixelLeft + "px";
+
+                       // Revert the changed values
+                       style.left = left;
+                       if ( rsLeft ) {
+                               rs.left = rsLeft;
+                       }
+               }
+
+               return ret === "" ? "auto" : ret;
+       };
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+       var matches = rnumsplit.exec( value );
+       return matches ?
+               // Guard against undefined "subtract", e.g., when used as in cssHooks
+               Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+               value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+       var i = extra === ( isBorderBox ? "border" : "content" ) ?
+               // If we already have the right measurement, avoid augmentation
+               4 :
+               // Otherwise initialize for horizontal or vertical properties
+               name === "width" ? 1 : 0,
+
+               val = 0;
+
+       for ( ; i < 4; i += 2 ) {
+               // both box models exclude margin, so add it if we want it
+               if ( extra === "margin" ) {
+                       val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+               }
+
+               if ( isBorderBox ) {
+                       // border-box includes padding, so remove it if we want content
+                       if ( extra === "content" ) {
+                               val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+                       }
+
+                       // at this point, extra isn't border nor margin, so remove border
+                       if ( extra !== "margin" ) {
+                               val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               } else {
+                       // at this point, extra isn't content, so add padding
+                       val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+                       // at this point, extra isn't content nor padding, so add border
+                       if ( extra !== "padding" ) {
+                               val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               }
+       }
+
+       return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+       // Start with offset property, which is equivalent to the border-box value
+       var valueIsBorderBox = true,
+               val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+               styles = getStyles( elem ),
+               isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+       // some non-html elements return undefined for offsetWidth, so check for null/undefined
+       // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+       // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+       if ( val <= 0 || val == null ) {
+               // Fall back to computed then uncomputed css if necessary
+               val = curCSS( elem, name, styles );
+               if ( val < 0 || val == null ) {
+                       val = elem.style[ name ];
+               }
+
+               // Computed unit is not pixels. Stop here and return.
+               if ( rnumnonpx.test(val) ) {
+                       return val;
+               }
+
+               // we need the check for style in case a browser which returns unreliable values
+               // for getComputedStyle silently falls back to the reliable elem.style
+               valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+               // Normalize "", auto, and prepare for extra
+               val = parseFloat( val ) || 0;
+       }
+
+       // use the active box-sizing model to add/subtract irrelevant styles
+       return ( val +
+               augmentWidthOrHeight(
+                       elem,
+                       name,
+                       extra || ( isBorderBox ? "border" : "content" ),
+                       valueIsBorderBox,
+                       styles
+               )
+       ) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+       var doc = document,
+               display = elemdisplay[ nodeName ];
+
+       if ( !display ) {
+               display = actualDisplay( nodeName, doc );
+
+               // If the simple way fails, read from inside an iframe
+               if ( display === "none" || !display ) {
+                       // Use the already-created iframe if possible
+                       iframe = ( iframe ||
+                               jQuery("<iframe frameborder='0' width='0' height='0'/>")
+                               .css( "cssText", "display:block !important" )
+                       ).appendTo( doc.documentElement );
+
+                       // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+                       doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+                       doc.write("<!doctype html><html><body>");
+                       doc.close();
+
+                       display = actualDisplay( nodeName, doc );
+                       iframe.detach();
+               }
+
+               // Store the correct default display
+               elemdisplay[ nodeName ] = display;
+       }
+
+       return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+       var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+               display = jQuery.css( elem[0], "display" );
+       elem.remove();
+       return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+       jQuery.cssHooks[ name ] = {
+               get: function( elem, computed, extra ) {
+                       if ( computed ) {
+                               // certain elements can have dimension info if we invisibly show them
+                               // however, it must have a current display style that would benefit from this
+                               return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+                                       jQuery.swap( elem, cssShow, function() {
+                                               return getWidthOrHeight( elem, name, extra );
+                                       }) :
+                                       getWidthOrHeight( elem, name, extra );
+                       }
+               },
+
+               set: function( elem, value, extra ) {
+                       var styles = extra && getStyles( elem );
+                       return setPositiveNumber( elem, value, extra ?
+                               augmentWidthOrHeight(
+                                       elem,
+                                       name,
+                                       extra,
+                                       jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+                                       styles
+                               ) : 0
+                       );
+               }
+       };
+});
+
+if ( !jQuery.support.opacity ) {
+       jQuery.cssHooks.opacity = {
+               get: function( elem, computed ) {
+                       // IE uses filters for opacity
+                       return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+                               ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+                               computed ? "1" : "";
+               },
+
+               set: function( elem, value ) {
+                       var style = elem.style,
+                               currentStyle = elem.currentStyle,
+                               opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+                               filter = currentStyle && currentStyle.filter || style.filter || "";
+
+                       // IE has trouble with opacity if it does not have layout
+                       // Force it by setting the zoom level
+                       style.zoom = 1;
+
+                       // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+                       // if value === "", then remove inline opacity #12685
+                       if ( ( value >= 1 || value === "" ) &&
+                                       jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+                                       style.removeAttribute ) {
+
+                               // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+                               // if "filter:" is present at all, clearType is disabled, we want to avoid this
+                               // style.removeAttribute is IE Only, but so apparently is this code path...
+                               style.removeAttribute( "filter" );
+
+                               // if there is no filter style applied in a css rule or unset inline opacity, we are done
+                               if ( value === "" || currentStyle && !currentStyle.filter ) {
+                                       return;
+                               }
+                       }
+
+                       // otherwise, set new filter values
+                       style.filter = ralpha.test( filter ) ?
+                               filter.replace( ralpha, opacity ) :
+                               filter + " " + opacity;
+               }
+       };
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+       if ( !jQuery.support.reliableMarginRight ) {
+               jQuery.cssHooks.marginRight = {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                                       // Work around by temporarily setting element display to inline-block
+                                       return jQuery.swap( elem, { "display": "inline-block" },
+                                               curCSS, [ elem, "marginRight" ] );
+                               }
+                       }
+               };
+       }
+
+       // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+       // getComputedStyle returns percent when specified for top/left/bottom/right
+       // rather than make the css module depend on the offset module, we just check for it here
+       if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+               jQuery.each( [ "top", "left" ], function( i, prop ) {
+                       jQuery.cssHooks[ prop ] = {
+                               get: function( elem, computed ) {
+                                       if ( computed ) {
+                                               computed = curCSS( elem, prop );
+                                               // if curCSS returns percentage, fallback to offset
+                                               return rnumnonpx.test( computed ) ?
+                                                       jQuery( elem ).position()[ prop ] + "px" :
+                                                       computed;
+                                       }
+                               }
+                       };
+               });
+       }
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.hidden = function( elem ) {
+               // Support: Opera <= 12.12
+               // Opera reports offsetWidths and offsetHeights less than zero on some elements
+               return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+                       (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+       };
+
+       jQuery.expr.filters.visible = function( elem ) {
+               return !jQuery.expr.filters.hidden( elem );
+       };
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+       margin: "",
+       padding: "",
+       border: "Width"
+}, function( prefix, suffix ) {
+       jQuery.cssHooks[ prefix + suffix ] = {
+               expand: function( value ) {
+                       var i = 0,
+                               expanded = {},
+
+                               // assumes a single number if not a string
+                               parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+                       for ( ; i < 4; i++ ) {
+                               expanded[ prefix + cssExpand[ i ] + suffix ] =
+                                       parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+                       }
+
+                       return expanded;
+               }
+       };
+
+       if ( !rmargin.test( prefix ) ) {
+               jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+       }
+});
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+       rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map(function(){
+                       // Can add propHook for "elements" to filter or add form elements
+                       var elements = jQuery.prop( this, "elements" );
+                       return elements ? jQuery.makeArray( elements ) : this;
+               })
+               .filter(function(){
+                       var type = this.type;
+                       // Use .is(":disabled") so that fieldset[disabled] works
+                       return this.name && !jQuery( this ).is( ":disabled" ) &&
+                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                               ( this.checked || !manipulation_rcheckableType.test( type ) );
+               })
+               .map(function( i, elem ){
+                       var val = jQuery( this ).val();
+
+                       return val == null ?
+                               null :
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val ){
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                                       }) :
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               }).get();
+       }
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, value ) {
+                       // If value is a function, invoke it and return its value
+                       value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+                       s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+               };
+
+       // Set traditional to true for jQuery <= 1.3.2 behavior.
+       if ( traditional === undefined ) {
+               traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+       }
+
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               });
+
+       } else {
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
+
+       // Return the resulting serialization
+       return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( jQuery.isArray( obj ) ) {
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+                               // Item is non-scalar (array or object), encode its numeric index.
+                               buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+                       }
+               });
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+jQuery.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( i, name ) {
+
+       // Handle event binding
+       jQuery.fn[ name ] = function( data, fn ) {
+               return arguments.length > 0 ?
+                       this.on( name, null, data, fn ) :
+                       this.trigger( name );
+       };
+});
+
+jQuery.fn.extend({
+       hover: function( fnOver, fnOut ) {
+               return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+       },
+
+       bind: function( types, data, fn ) {
+               return this.on( types, null, data, fn );
+       },
+       unbind: function( types, fn ) {
+               return this.off( types, null, fn );
+       },
+
+       delegate: function( selector, types, data, fn ) {
+               return this.on( types, selector, data, fn );
+       },
+       undelegate: function( selector, types, fn ) {
+               // ( namespace ) or ( selector, types [, fn] )
+               return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+       }
+});
+var
+       // Document location
+       ajaxLocParts,
+       ajaxLocation,
+       ajax_nonce = jQuery.now(),
+
+       ajax_rquery = /\?/,
+       rhash = /#.*$/,
+       rts = /([?&])_=[^&]*/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+       rnoContent = /^(?:GET|HEAD)$/,
+       rprotocol = /^\/\//,
+       rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+       // Keep a copy of the old load method
+       _load = jQuery.fn.load,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+       allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+       ajaxLocation = location.href;
+} catch( e ) {
+       // Use the href attribute of an A element
+       // since IE will modify it given document.location
+       ajaxLocation = document.createElement( "a" );
+       ajaxLocation.href = "";
+       ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               var dataType,
+                       i = 0,
+                       dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+               if ( jQuery.isFunction( func ) ) {
+                       // For each dataType in the dataTypeExpression
+                       while ( (dataType = dataTypes[i++]) ) {
+                               // Prepend if requested
+                               if ( dataType[0] === "+" ) {
+                                       dataType = dataType.slice( 1 ) || "*";
+                                       (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+                               // Otherwise append
+                               } else {
+                                       (structure[ dataType ] = structure[ dataType ] || []).push( func );
+                               }
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+       var inspected = {},
+               seekingTransport = ( structure === transports );
+
+       function inspect( dataType ) {
+               var selected;
+               inspected[ dataType ] = true;
+               jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+                       var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+                       if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+                               options.dataTypes.unshift( dataTypeOrTransport );
+                               inspect( dataTypeOrTransport );
+                               return false;
+                       } else if ( seekingTransport ) {
+                               return !( selected = dataTypeOrTransport );
+                       }
+               });
+               return selected;
+       }
+
+       return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+       var deep, key,
+               flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+       for ( key in src ) {
+               if ( src[ key ] !== undefined ) {
+                       ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+               }
+       }
+       if ( deep ) {
+               jQuery.extend( true, target, deep );
+       }
+
+       return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+       if ( typeof url !== "string" && _load ) {
+               return _load.apply( this, arguments );
+       }
+
+       var selector, response, type,
+               self = this,
+               off = url.indexOf(" ");
+
+       if ( off >= 0 ) {
+               selector = url.slice( off, url.length );
+               url = url.slice( 0, off );
+       }
+
+       // If it's a function
+       if ( jQuery.isFunction( params ) ) {
+
+               // We assume that it's the callback
+               callback = params;
+               params = undefined;
+
+       // Otherwise, build a param string
+       } else if ( params && typeof params === "object" ) {
+               type = "POST";
+       }
+
+       // If we have elements to modify, make the request
+       if ( self.length > 0 ) {
+               jQuery.ajax({
+                       url: url,
+
+                       // if "type" variable is undefined, then "GET" method will be used
+                       type: type,
+                       dataType: "html",
+                       data: params
+               }).done(function( responseText ) {
+
+                       // Save response for use in complete callback
+                       response = arguments;
+
+                       self.html( selector ?
+
+                               // If a selector was specified, locate the right elements in a dummy div
+                               // Exclude scripts to avoid IE 'Permission Denied' errors
+                               jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+                               // Otherwise use the full result
+                               responseText );
+
+               }).complete( callback && function( jqXHR, status ) {
+                       self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+               });
+       }
+
+       return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+       jQuery.fn[ type ] = function( fn ){
+               return this.on( type, fn );
+       };
+});
+
+jQuery.extend({
+
+       // Counter for holding the number of active queries
+       active: 0,
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       etag: {},
+
+       ajaxSettings: {
+               url: ajaxLocation,
+               type: "GET",
+               isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+               global: true,
+               processData: true,
+               async: true,
+               contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+               /*
+               timeout: 0,
+               data: null,
+               dataType: null,
+               username: null,
+               password: null,
+               cache: null,
+               throws: false,
+               traditional: false,
+               headers: {},
+               */
+
+               accepts: {
+                       "*": allTypes,
+                       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"
+               },
+
+               // Data converters
+               // Keys separate source (or catchall "*") and destination types with a single space
+               converters: {
+
+                       // Convert anything to text
+                       "* text": String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": jQuery.parseJSON,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               },
+
+               // For options that shouldn't be deep extended:
+               // you can add your own custom options here if
+               // and when you create one that shouldn't be
+               // deep extended (see ajaxExtend)
+               flatOptions: {
+                       url: true,
+                       context: true
+               }
+       },
+
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function( target, settings ) {
+               return settings ?
+
+                       // Building a settings object
+                       ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+                       // Extending ajaxSettings
+                       ajaxExtend( jQuery.ajaxSettings, target );
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var // Cross-domain detection vars
+                       parts,
+                       // Loop variable
+                       i,
+                       // URL without anti-cache param
+                       cacheURL,
+                       // Response headers as string
+                       responseHeadersString,
+                       // timeout handle
+                       timeoutTimer,
+
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+
+                       transport,
+                       // Response headers
+                       responseHeaders,
+                       // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+                       // Callbacks context
+                       callbackContext = s.context || s,
+                       // Context for global events is callbackContext if it is a DOM node or jQuery collection
+                       globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+                               jQuery( callbackContext ) :
+                               jQuery.event,
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery.Callbacks("once memory"),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+                       // The jqXHR state
+                       state = 0,
+                       // Default abort message
+                       strAbort = "canceled",
+                       // Fake xhr
+                       jqXHR = {
+                               readyState: 0,
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( state === 2 ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while ( (match = rheaders.exec( responseHeadersString )) ) {
+                                                               responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match == null ? null : match;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return state === 2 ? responseHeadersString : null;
+                               },
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       var lname = name.toLowerCase();
+                                       if ( !state ) {
+                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
+                               // Status-dependent callbacks
+                               statusCode: function( map ) {
+                                       var code;
+                                       if ( map ) {
+                                               if ( state < 2 ) {
+                                                       for ( code in map ) {
+                                                               // Lazy-add the new callback in a way that preserves old ones
+                                                               statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                                                       }
+                                               } else {
+                                                       // Execute the appropriate callbacks
+                                                       jqXHR.always( map[ jqXHR.status ] );
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       var finalText = statusText || strAbort;
+                                       if ( transport ) {
+                                               transport.abort( finalText );
+                                       }
+                                       done( 0, finalText );
+                                       return this;
+                               }
+                       };
+
+               // Attach deferreds
+               deferred.promise( jqXHR ).complete = completeDeferred.add;
+               jqXHR.success = jqXHR.done;
+               jqXHR.error = jqXHR.fail;
+
+               // Remove hash character (#7531: and string promotion)
+               // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+               // Handle falsy url in the settings object (#10093: consistency with old signature)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+               // Alias method option to type as per ticket #12004
+               s.type = options.method || options.type || s.method || s.type;
+
+               // Extract dataTypes list
+               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+               // A cross-domain request is in order when we have a protocol:host:port mismatch
+               if ( s.crossDomain == null ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!( parts &&
+                               ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+                       );
+               }
+
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
+
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+               // If request was aborted inside a prefilter, stop there
+               if ( state === 2 ) {
+                       return jqXHR;
+               }
+
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
+
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger("ajaxStart");
+               }
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
+
+               // Save the URL in case we're toying with the If-Modified-Since
+               // and/or If-None-Match header later on
+               cacheURL = s.url;
+
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
+
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+                               // #9682: remove data so that it's not used in an eventual retry
+                               delete s.data;
+                       }
+
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
+                               s.url = rts.test( cacheURL ) ?
+
+                                       // If there is already a '_' parameter, set its value
+                                       cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+                                       // Otherwise add one to the end
+                                       cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+                       }
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       if ( jQuery.lastModified[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+                       }
+                       if ( jQuery.etag[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+                       }
+               }
+
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+                               s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                       // Abort if not done already and return
+                       return jqXHR.abort();
+               }
+
+               // aborting is no longer a cancellation
+               strAbort = "abort";
+
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
+
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout(function() {
+                                       jqXHR.abort("timeout");
+                               }, s.timeout );
+                       }
+
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch ( e ) {
+                               // Propagate exception as error if not done
+                               if ( state < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       throw e;
+                               }
+                       }
+               }
+
+               // Callback for when everything is done
+               function done( status, nativeStatusText, responses, headers ) {
+                       var isSuccess, success, error, response, modified,
+                               statusText = nativeStatusText;
+
+                       // Called once
+                       if ( state === 2 ) {
+                               return;
+                       }
+
+                       // State is "done" now
+                       state = 2;
+
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               clearTimeout( timeoutTimer );
+                       }
+
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
+
+                       // Cache response headers
+                       responseHeadersString = headers || "";
+
+                       // Set readyState
+                       jqXHR.readyState = status > 0 ? 4 : 0;
+
+                       // Determine if successful
+                       isSuccess = status >= 200 && status < 300 || status === 304;
+
+                       // Get response data
+                       if ( responses ) {
+                               response = ajaxHandleResponses( s, jqXHR, responses );
+                       }
+
+                       // Convert no matter what (that way responseXXX fields are always set)
+                       response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+                       // If successful, handle type chaining
+                       if ( isSuccess ) {
+
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                               if ( s.ifModified ) {
+                                       modified = jqXHR.getResponseHeader("Last-Modified");
+                                       if ( modified ) {
+                                               jQuery.lastModified[ cacheURL ] = modified;
+                                       }
+                                       modified = jqXHR.getResponseHeader("etag");
+                                       if ( modified ) {
+                                               jQuery.etag[ cacheURL ] = modified;
+                                       }
+                               }
+
+                               // if no content
+                               if ( status === 204 || s.type === "HEAD" ) {
+                                       statusText = "nocontent";
+
+                               // if not modified
+                               } else if ( status === 304 ) {
+                                       statusText = "notmodified";
+
+                               // If we have data, let's convert it
+                               } else {
+                                       statusText = response.state;
+                                       success = response.data;
+                                       error = response.error;
+                                       isSuccess = !error;
+                               }
+                       } else {
+                               // We extract error from statusText
+                               // then normalize statusText and status for non-aborts
+                               error = statusText;
+                               if ( status || !statusText ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
+                       }
+
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
+
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+                                       [ jqXHR, s, isSuccess ? success : error ] );
+                       }
+
+                       // Complete
+                       completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger("ajaxStop");
+                               }
+                       }
+               }
+
+               return jqXHR;
+       },
+
+       getJSON: function( url, data, callback ) {
+               return jQuery.get( url, data, callback, "json" );
+       },
+
+       getScript: function( url, callback ) {
+               return jQuery.get( url, undefined, callback, "script" );
+       }
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+               // shift arguments if data argument was omitted
+               if ( jQuery.isFunction( data ) ) {
+                       type = type || callback;
+                       callback = data;
+                       data = undefined;
+               }
+
+               return jQuery.ajax({
+                       url: url,
+                       type: method,
+                       dataType: type,
+                       data: data,
+                       success: callback
+               });
+       };
+});
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+       var firstDataType, ct, finalDataType, type,
+               contents = s.contents,
+               dataTypes = s.dataTypes;
+
+       // Remove auto dataType and get content-type in the process
+       while( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+               }
+       }
+
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
+               }
+       }
+
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
+               }
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
+
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+       var conv2, current, conv, tmp, prev,
+               converters = {},
+               // Work with a copy of dataTypes in case we need to modify it for conversion
+               dataTypes = s.dataTypes.slice();
+
+       // Create converters map with lowercased keys
+       if ( dataTypes[ 1 ] ) {
+               for ( conv in s.converters ) {
+                       converters[ conv.toLowerCase() ] = s.converters[ conv ];
+               }
+       }
+
+       current = dataTypes.shift();
+
+       // Convert to each sequential dataType
+       while ( current ) {
+
+               if ( s.responseFields[ current ] ) {
+                       jqXHR[ s.responseFields[ current ] ] = response;
+               }
+
+               // Apply the dataFilter if provided
+               if ( !prev && isSuccess && s.dataFilter ) {
+                       response = s.dataFilter( response, s.dataType );
+               }
+
+               prev = current;
+               current = dataTypes.shift();
+
+               if ( current ) {
+
+                       // There's only work to do if current dataType is non-auto
+                       if ( current === "*" ) {
+
+                               current = prev;
+
+                       // Convert response if prev dataType is non-auto and differs from current
+                       } else if ( prev !== "*" && prev !== current ) {
+
+                               // Seek a direct converter
+                               conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+                               // If none found, seek a pair
+                               if ( !conv ) {
+                                       for ( conv2 in converters ) {
+
+                                               // If conv2 outputs current
+                                               tmp = conv2.split( " " );
+                                               if ( tmp[ 1 ] === current ) {
+
+                                                       // If prev can be converted to accepted input
+                                                       conv = converters[ prev + " " + tmp[ 0 ] ] ||
+                                                               converters[ "* " + tmp[ 0 ] ];
+                                                       if ( conv ) {
+                                                               // Condense equivalence converters
+                                                               if ( conv === true ) {
+                                                                       conv = converters[ conv2 ];
+
+                                                               // Otherwise, insert the intermediate dataType
+                                                               } else if ( converters[ conv2 ] !== true ) {
+                                                                       current = tmp[ 0 ];
+                                                                       dataTypes.unshift( tmp[ 1 ] );
+                                                               }
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Apply converter (if not an equivalence)
+                               if ( conv !== true ) {
+
+                                       // Unless errors are allowed to bubble, catch and return them
+                                       if ( conv && s[ "throws" ] ) {
+                                               response = conv( response );
+                                       } else {
+                                               try {
+                                                       response = conv( response );
+                                               } catch ( e ) {
+                                                       return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+       accepts: {
+               script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /(?:java|ecma)script/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
+               }
+       }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+               s.global = false;
+       }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+
+               var script,
+                       head = document.head || jQuery("head")[0] || document.documentElement;
+
+               return {
+
+                       send: function( _, callback ) {
+
+                               script = document.createElement("script");
+
+                               script.async = true;
+
+                               if ( s.scriptCharset ) {
+                                       script.charset = s.scriptCharset;
+                               }
+
+                               script.src = s.url;
+
+                               // Attach handlers for all browsers
+                               script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+                                       if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+                                               // Handle memory leak in IE
+                                               script.onload = script.onreadystatechange = null;
+
+                                               // Remove the script
+                                               if ( script.parentNode ) {
+                                                       script.parentNode.removeChild( script );
+                                               }
+
+                                               // Dereference the script
+                                               script = null;
+
+                                               // Callback if not abort
+                                               if ( !isAbort ) {
+                                                       callback( 200, "success" );
+                                               }
+                                       }
+                               };
+
+                               // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+                               // Use native DOM manipulation to avoid our domManip AJAX trickery
+                               head.insertBefore( script, head.firstChild );
+                       },
+
+                       abort: function() {
+                               if ( script ) {
+                                       script.onload( undefined, true );
+                               }
+                       }
+               };
+       }
+});
+var oldCallbacks = [],
+       rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+       jsonp: "callback",
+       jsonpCallback: function() {
+               var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+               this[ callback ] = true;
+               return callback;
+       }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var callbackName, overwritten, responseContainer,
+               jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+                       "url" :
+                       typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+               );
+
+       // Handle iff the expected data type is "jsonp" or we have a parameter to set
+       if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+               // Get callback name, remembering preexisting value associated with it
+               callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+                       s.jsonpCallback() :
+                       s.jsonpCallback;
+
+               // Insert callback into url or form data
+               if ( jsonProp ) {
+                       s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+               } else if ( s.jsonp !== false ) {
+                       s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+               }
+
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( callbackName + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
+
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Install callback
+               overwritten = window[ callbackName ];
+               window[ callbackName ] = function() {
+                       responseContainer = arguments;
+               };
+
+               // Clean-up function (fires after converters)
+               jqXHR.always(function() {
+                       // Restore preexisting value
+                       window[ callbackName ] = overwritten;
+
+                       // Save back as free
+                       if ( s[ callbackName ] ) {
+                               // make sure that re-using the options doesn't screw things around
+                               s.jsonpCallback = originalSettings.jsonpCallback;
+
+                               // save the callback name for future use
+                               oldCallbacks.push( callbackName );
+                       }
+
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+                               overwritten( responseContainer[ 0 ] );
+                       }
+
+                       responseContainer = overwritten = undefined;
+               });
+
+               // Delegate to script
+               return "script";
+       }
+});
+var xhrCallbacks, xhrSupported,
+       xhrId = 0,
+       // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+       xhrOnUnloadAbort = window.ActiveXObject && function() {
+               // Abort all pending requests
+               var key;
+               for ( key in xhrCallbacks ) {
+                       xhrCallbacks[ key ]( undefined, true );
+               }
+       };
+
+// Functions to create xhrs
+function createStandardXHR() {
+       try {
+               return new window.XMLHttpRequest();
+       } catch( e ) {}
+}
+
+function createActiveXHR() {
+       try {
+               return new window.ActiveXObject("Microsoft.XMLHTTP");
+       } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+       /* Microsoft failed to properly
+        * implement the XMLHttpRequest in IE7 (can't request local files),
+        * so we use the ActiveXObject when it is available
+        * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+        * we need a fallback.
+        */
+       function() {
+               return !this.isLocal && createStandardXHR() || createActiveXHR();
+       } :
+       // For all other browsers, use the standard XMLHttpRequest object
+       createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+       jQuery.ajaxTransport(function( s ) {
+               // Cross domain only allowed if supported through XMLHttpRequest
+               if ( !s.crossDomain || jQuery.support.cors ) {
+
+                       var callback;
+
+                       return {
+                               send: function( headers, complete ) {
+
+                                       // Get a new xhr
+                                       var handle, i,
+                                               xhr = s.xhr();
+
+                                       // Open the socket
+                                       // Passing null username, generates a login popup on Opera (#2865)
+                                       if ( s.username ) {
+                                               xhr.open( s.type, s.url, s.async, s.username, s.password );
+                                       } else {
+                                               xhr.open( s.type, s.url, s.async );
+                                       }
+
+                                       // Apply custom fields if provided
+                                       if ( s.xhrFields ) {
+                                               for ( i in s.xhrFields ) {
+                                                       xhr[ i ] = s.xhrFields[ i ];
+                                               }
+                                       }
+
+                                       // Override mime type if needed
+                                       if ( s.mimeType && xhr.overrideMimeType ) {
+                                               xhr.overrideMimeType( s.mimeType );
+                                       }
+
+                                       // X-Requested-With header
+                                       // For cross-domain requests, seeing as conditions for a preflight are
+                                       // akin to a jigsaw puzzle, we simply never set it to be sure.
+                                       // (it can always be set on a per-request basis or even using ajaxSetup)
+                                       // For same-domain requests, won't change header if already provided.
+                                       if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+                                               headers["X-Requested-With"] = "XMLHttpRequest";
+                                       }
+
+                                       // Need an extra try/catch for cross domain requests in Firefox 3
+                                       try {
+                                               for ( i in headers ) {
+                                                       xhr.setRequestHeader( i, headers[ i ] );
+                                               }
+                                       } catch( err ) {}
+
+                                       // Do send the request
+                                       // This may raise an exception which is actually
+                                       // handled in jQuery.ajax (so no try/catch here)
+                                       xhr.send( ( s.hasContent && s.data ) || null );
+
+                                       // Listener
+                                       callback = function( _, isAbort ) {
+                                               var status, responseHeaders, statusText, responses;
+
+                                               // Firefox throws exceptions when accessing properties
+                                               // of an xhr when a network error occurred
+                                               // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+                                               try {
+
+                                                       // Was never called and is aborted or complete
+                                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+                                                               // Only called once
+                                                               callback = undefined;
+
+                                                               // Do not keep as active anymore
+                                                               if ( handle ) {
+                                                                       xhr.onreadystatechange = jQuery.noop;
+                                                                       if ( xhrOnUnloadAbort ) {
+                                                                               delete xhrCallbacks[ handle ];
+                                                                       }
+                                                               }
+
+                                                               // If it's an abort
+                                                               if ( isAbort ) {
+                                                                       // Abort it manually if needed
+                                                                       if ( xhr.readyState !== 4 ) {
+                                                                               xhr.abort();
+                                                                       }
+                                                               } else {
+                                                                       responses = {};
+                                                                       status = xhr.status;
+                                                                       responseHeaders = xhr.getAllResponseHeaders();
+
+                                                                       // When requesting binary data, IE6-9 will throw an exception
+                                                                       // on any attempt to access responseText (#11426)
+                                                                       if ( typeof xhr.responseText === "string" ) {
+                                                                               responses.text = xhr.responseText;
+                                                                       }
+
+                                                                       // Firefox throws an exception when accessing
+                                                                       // statusText for faulty cross-domain requests
+                                                                       try {
+                                                                               statusText = xhr.statusText;
+                                                                       } catch( e ) {
+                                                                               // We normalize with Webkit giving an empty statusText
+                                                                               statusText = "";
+                                                                       }
+
+                                                                       // Filter status for non standard behaviors
+
+                                                                       // If the request is local and we have data: assume a success
+                                                                       // (success with no data won't get notified, that's the best we
+                                                                       // can do given current implementations)
+                                                                       if ( !status && s.isLocal && !s.crossDomain ) {
+                                                                               status = responses.text ? 200 : 404;
+                                                                       // IE - #1450: sometimes returns 1223 when it should be 204
+                                                                       } else if ( status === 1223 ) {
+                                                                               status = 204;
+                                                                       }
+                                                               }
+                                                       }
+                                               } catch( firefoxAccessException ) {
+                                                       if ( !isAbort ) {
+                                                               complete( -1, firefoxAccessException );
+                                                       }
+                                               }
+
+                                               // Call complete if needed
+                                               if ( responses ) {
+                                                       complete( status, statusText, responses, responseHeaders );
+                                               }
+                                       };
+
+                                       if ( !s.async ) {
+                                               // if we're in sync mode we fire the callback
+                                               callback();
+                                       } else if ( xhr.readyState === 4 ) {
+                                               // (IE6 & IE7) if it's in cache and has been
+                                               // retrieved directly we need to fire the callback
+                                               setTimeout( callback );
+                                       } else {
+                                               handle = ++xhrId;
+                                               if ( xhrOnUnloadAbort ) {
+                                                       // Create the active xhrs callbacks list if needed
+                                                       // and attach the unload handler
+                                                       if ( !xhrCallbacks ) {
+                                                               xhrCallbacks = {};
+                                                               jQuery( window ).unload( xhrOnUnloadAbort );
+                                                       }
+                                                       // Add to list of active xhrs callbacks
+                                                       xhrCallbacks[ handle ] = callback;
+                                               }
+                                               xhr.onreadystatechange = callback;
+                                       }
+                               },
+
+                               abort: function() {
+                                       if ( callback ) {
+                                               callback( undefined, true );
+                                       }
+                               }
+                       };
+               }
+       });
+}
+var fxNow, timerId,
+       rfxtypes = /^(?:toggle|show|hide)$/,
+       rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+       rrun = /queueHooks$/,
+       animationPrefilters = [ defaultPrefilter ],
+       tweeners = {
+               "*": [function( prop, value ) {
+                       var tween = this.createTween( prop, value ),
+                               target = tween.cur(),
+                               parts = rfxnum.exec( value ),
+                               unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+                               // Starting value computation is required for potential unit mismatches
+                               start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+                                       rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+                               scale = 1,
+                               maxIterations = 20;
+
+                       if ( start && start[ 3 ] !== unit ) {
+                               // Trust units reported by jQuery.css
+                               unit = unit || start[ 3 ];
+
+                               // Make sure we update the tween properties later on
+                               parts = parts || [];
+
+                               // Iteratively approximate from a nonzero starting point
+                               start = +target || 1;
+
+                               do {
+                                       // If previous iteration zeroed out, double until we get *something*
+                                       // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+                                       scale = scale || ".5";
+
+                                       // Adjust and apply
+                                       start = start / scale;
+                                       jQuery.style( tween.elem, prop, start + unit );
+
+                               // Update scale, tolerating zero or NaN from tween.cur()
+                               // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                               } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+                       }
+
+                       // Update tween properties
+                       if ( parts ) {
+                               start = tween.start = +start || +target || 0;
+                               tween.unit = unit;
+                               // If a +=/-= token was provided, we're doing a relative animation
+                               tween.end = parts[ 1 ] ?
+                                       start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+                                       +parts[ 2 ];
+                       }
+
+                       return tween;
+               }]
+       };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       setTimeout(function() {
+               fxNow = undefined;
+       });
+       return ( fxNow = jQuery.now() );
+}
+
+function createTween( value, prop, animation ) {
+       var tween,
+               collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+               index = 0,
+               length = collection.length;
+       for ( ; index < length; index++ ) {
+               if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+                       // we're done with this property
+                       return tween;
+               }
+       }
+}
+
+function Animation( elem, properties, options ) {
+       var result,
+               stopped,
+               index = 0,
+               length = animationPrefilters.length,
+               deferred = jQuery.Deferred().always( function() {
+                       // don't match elem in the :animated selector
+                       delete tick.elem;
+               }),
+               tick = function() {
+                       if ( stopped ) {
+                               return false;
+                       }
+                       var currentTime = fxNow || createFxNow(),
+                               remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+                               // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+                               temp = remaining / animation.duration || 0,
+                               percent = 1 - temp,
+                               index = 0,
+                               length = animation.tweens.length;
+
+                       for ( ; index < length ; index++ ) {
+                               animation.tweens[ index ].run( percent );
+                       }
+
+                       deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+                       if ( percent < 1 && length ) {
+                               return remaining;
+                       } else {
+                               deferred.resolveWith( elem, [ animation ] );
+                               return false;
+                       }
+               },
+               animation = deferred.promise({
+                       elem: elem,
+                       props: jQuery.extend( {}, properties ),
+                       opts: jQuery.extend( true, { specialEasing: {} }, options ),
+                       originalProperties: properties,
+                       originalOptions: options,
+                       startTime: fxNow || createFxNow(),
+                       duration: options.duration,
+                       tweens: [],
+                       createTween: function( prop, end ) {
+                               var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                                               animation.opts.specialEasing[ prop ] || animation.opts.easing );
+                               animation.tweens.push( tween );
+                               return tween;
+                       },
+                       stop: function( gotoEnd ) {
+                               var index = 0,
+                                       // if we are going to the end, we want to run all the tweens
+                                       // otherwise we skip this part
+                                       length = gotoEnd ? animation.tweens.length : 0;
+                               if ( stopped ) {
+                                       return this;
+                               }
+                               stopped = true;
+                               for ( ; index < length ; index++ ) {
+                                       animation.tweens[ index ].run( 1 );
+                               }
+
+                               // resolve when we played the last frame
+                               // otherwise, reject
+                               if ( gotoEnd ) {
+                                       deferred.resolveWith( elem, [ animation, gotoEnd ] );
+                               } else {
+                                       deferred.rejectWith( elem, [ animation, gotoEnd ] );
+                               }
+                               return this;
+                       }
+               }),
+               props = animation.props;
+
+       propFilter( props, animation.opts.specialEasing );
+
+       for ( ; index < length ; index++ ) {
+               result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+               if ( result ) {
+                       return result;
+               }
+       }
+
+       jQuery.map( props, createTween, animation );
+
+       if ( jQuery.isFunction( animation.opts.start ) ) {
+               animation.opts.start.call( elem, animation );
+       }
+
+       jQuery.fx.timer(
+               jQuery.extend( tick, {
+                       elem: elem,
+                       anim: animation,
+                       queue: animation.opts.queue
+               })
+       );
+
+       // attach callbacks from options
+       return animation.progress( animation.opts.progress )
+               .done( animation.opts.done, animation.opts.complete )
+               .fail( animation.opts.fail )
+               .always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+       var index, name, easing, value, hooks;
+
+       // camelCase, specialEasing and expand cssHook pass
+       for ( index in props ) {
+               name = jQuery.camelCase( index );
+               easing = specialEasing[ name ];
+               value = props[ index ];
+               if ( jQuery.isArray( value ) ) {
+                       easing = value[ 1 ];
+                       value = props[ index ] = value[ 0 ];
+               }
+
+               if ( index !== name ) {
+                       props[ name ] = value;
+                       delete props[ index ];
+               }
+
+               hooks = jQuery.cssHooks[ name ];
+               if ( hooks && "expand" in hooks ) {
+                       value = hooks.expand( value );
+                       delete props[ name ];
+
+                       // not quite $.extend, this wont overwrite keys already present.
+                       // also - reusing 'index' from above because we have the correct "name"
+                       for ( index in value ) {
+                               if ( !( index in props ) ) {
+                                       props[ index ] = value[ index ];
+                                       specialEasing[ index ] = easing;
+                               }
+                       }
+               } else {
+                       specialEasing[ name ] = easing;
+               }
+       }
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+       tweener: function( props, callback ) {
+               if ( jQuery.isFunction( props ) ) {
+                       callback = props;
+                       props = [ "*" ];
+               } else {
+                       props = props.split(" ");
+               }
+
+               var prop,
+                       index = 0,
+                       length = props.length;
+
+               for ( ; index < length ; index++ ) {
+                       prop = props[ index ];
+                       tweeners[ prop ] = tweeners[ prop ] || [];
+                       tweeners[ prop ].unshift( callback );
+               }
+       },
+
+       prefilter: function( callback, prepend ) {
+               if ( prepend ) {
+                       animationPrefilters.unshift( callback );
+               } else {
+                       animationPrefilters.push( callback );
+               }
+       }
+});
+
+function defaultPrefilter( elem, props, opts ) {
+       /* jshint validthis: true */
+       var prop, value, toggle, tween, hooks, oldfire,
+               anim = this,
+               orig = {},
+               style = elem.style,
+               hidden = elem.nodeType && isHidden( elem ),
+               dataShow = jQuery._data( elem, "fxshow" );
+
+       // handle queue: false promises
+       if ( !opts.queue ) {
+               hooks = jQuery._queueHooks( elem, "fx" );
+               if ( hooks.unqueued == null ) {
+                       hooks.unqueued = 0;
+                       oldfire = hooks.empty.fire;
+                       hooks.empty.fire = function() {
+                               if ( !hooks.unqueued ) {
+                                       oldfire();
+                               }
+                       };
+               }
+               hooks.unqueued++;
+
+               anim.always(function() {
+                       // doing this makes sure that the complete handler will be called
+                       // before this completes
+                       anim.always(function() {
+                               hooks.unqueued--;
+                               if ( !jQuery.queue( elem, "fx" ).length ) {
+                                       hooks.empty.fire();
+                               }
+                       });
+               });
+       }
+
+       // height/width overflow pass
+       if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+               // Make sure that nothing sneaks out
+               // Record all 3 overflow attributes because IE does not
+               // change the overflow attribute when overflowX and
+               // overflowY are set to the same value
+               opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+               // Set display property to inline-block for height/width
+               // animations on inline elements that are having width/height animated
+               if ( jQuery.css( elem, "display" ) === "inline" &&
+                               jQuery.css( elem, "float" ) === "none" ) {
+
+                       // inline-level elements accept inline-block;
+                       // block-level elements need to be inline with layout
+                       if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+                               style.display = "inline-block";
+
+                       } else {
+                               style.zoom = 1;
+                       }
+               }
+       }
+
+       if ( opts.overflow ) {
+               style.overflow = "hidden";
+               if ( !jQuery.support.shrinkWrapBlocks ) {
+                       anim.always(function() {
+                               style.overflow = opts.overflow[ 0 ];
+                               style.overflowX = opts.overflow[ 1 ];
+                               style.overflowY = opts.overflow[ 2 ];
+                       });
+               }
+       }
+
+
+       // show/hide pass
+       for ( prop in props ) {
+               value = props[ prop ];
+               if ( rfxtypes.exec( value ) ) {
+                       delete props[ prop ];
+                       toggle = toggle || value === "toggle";
+                       if ( value === ( hidden ? "hide" : "show" ) ) {
+                               continue;
+                       }
+                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+               }
+       }
+
+       if ( !jQuery.isEmptyObject( orig ) ) {
+               if ( dataShow ) {
+                       if ( "hidden" in dataShow ) {
+                               hidden = dataShow.hidden;
+                       }
+               } else {
+                       dataShow = jQuery._data( elem, "fxshow", {} );
+               }
+
+               // store state if its toggle - enables .stop().toggle() to "reverse"
+               if ( toggle ) {
+                       dataShow.hidden = !hidden;
+               }
+               if ( hidden ) {
+                       jQuery( elem ).show();
+               } else {
+                       anim.done(function() {
+                               jQuery( elem ).hide();
+                       });
+               }
+               anim.done(function() {
+                       var prop;
+                       jQuery._removeData( elem, "fxshow" );
+                       for ( prop in orig ) {
+                               jQuery.style( elem, prop, orig[ prop ] );
+                       }
+               });
+               for ( prop in orig ) {
+                       tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+                       if ( !( prop in dataShow ) ) {
+                               dataShow[ prop ] = tween.start;
+                               if ( hidden ) {
+                                       tween.end = tween.start;
+                                       tween.start = prop === "width" || prop === "height" ? 1 : 0;
+                               }
+                       }
+               }
+       }
+}
+
+function Tween( elem, options, prop, end, easing ) {
+       return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+       constructor: Tween,
+       init: function( elem, options, prop, end, easing, unit ) {
+               this.elem = elem;
+               this.prop = prop;
+               this.easing = easing || "swing";
+               this.options = options;
+               this.start = this.now = this.cur();
+               this.end = end;
+               this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+       },
+       cur: function() {
+               var hooks = Tween.propHooks[ this.prop ];
+
+               return hooks && hooks.get ?
+                       hooks.get( this ) :
+                       Tween.propHooks._default.get( this );
+       },
+       run: function( percent ) {
+               var eased,
+                       hooks = Tween.propHooks[ this.prop ];
+
+               if ( this.options.duration ) {
+                       this.pos = eased = jQuery.easing[ this.easing ](
+                               percent, this.options.duration * percent, 0, 1, this.options.duration
+                       );
+               } else {
+                       this.pos = eased = percent;
+               }
+               this.now = ( this.end - this.start ) * eased + this.start;
+
+               if ( this.options.step ) {
+                       this.options.step.call( this.elem, this.now, this );
+               }
+
+               if ( hooks && hooks.set ) {
+                       hooks.set( this );
+               } else {
+                       Tween.propHooks._default.set( this );
+               }
+               return this;
+       }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+       _default: {
+               get: function( tween ) {
+                       var result;
+
+                       if ( tween.elem[ tween.prop ] != null &&
+                               (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+                               return tween.elem[ tween.prop ];
+                       }
+
+                       // passing an empty string as a 3rd parameter to .css will automatically
+                       // attempt a parseFloat and fallback to a string if the parse fails
+                       // so, simple values such as "10px" are parsed to Float.
+                       // complex values such as "rotate(1rad)" are returned as is.
+                       result = jQuery.css( tween.elem, tween.prop, "" );
+                       // Empty strings, null, undefined and "auto" are converted to 0.
+                       return !result || result === "auto" ? 0 : result;
+               },
+               set: function( tween ) {
+                       // use step hook for back compat - use cssHook if its there - use .style if its
+                       // available and use plain properties where available
+                       if ( jQuery.fx.step[ tween.prop ] ) {
+                               jQuery.fx.step[ tween.prop ]( tween );
+                       } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+                               jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+                       } else {
+                               tween.elem[ tween.prop ] = tween.now;
+                       }
+               }
+       }
+};
+
+// Support: IE <=9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+       set: function( tween ) {
+               if ( tween.elem.nodeType && tween.elem.parentNode ) {
+                       tween.elem[ tween.prop ] = tween.now;
+               }
+       }
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+       var cssFn = jQuery.fn[ name ];
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return speed == null || typeof speed === "boolean" ?
+                       cssFn.apply( this, arguments ) :
+                       this.animate( genFx( name, true ), speed, easing, callback );
+       };
+});
+
+jQuery.fn.extend({
+       fadeTo: function( speed, to, easing, callback ) {
+
+               // show any hidden elements after setting opacity to 0
+               return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+                       // animate to the value specified
+                       .end().animate({ opacity: to }, speed, easing, callback );
+       },
+       animate: function( prop, speed, easing, callback ) {
+               var empty = jQuery.isEmptyObject( prop ),
+                       optall = jQuery.speed( speed, easing, callback ),
+                       doAnimation = function() {
+                               // Operate on a copy of prop so per-property easing won't be lost
+                               var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+                               // Empty animations, or finishing resolves immediately
+                               if ( empty || jQuery._data( this, "finish" ) ) {
+                                       anim.stop( true );
+                               }
+                       };
+                       doAnimation.finish = doAnimation;
+
+               return empty || optall.queue === false ?
+                       this.each( doAnimation ) :
+                       this.queue( optall.queue, doAnimation );
+       },
+       stop: function( type, clearQueue, gotoEnd ) {
+               var stopQueue = function( hooks ) {
+                       var stop = hooks.stop;
+                       delete hooks.stop;
+                       stop( gotoEnd );
+               };
+
+               if ( typeof type !== "string" ) {
+                       gotoEnd = clearQueue;
+                       clearQueue = type;
+                       type = undefined;
+               }
+               if ( clearQueue && type !== false ) {
+                       this.queue( type || "fx", [] );
+               }
+
+               return this.each(function() {
+                       var dequeue = true,
+                               index = type != null && type + "queueHooks",
+                               timers = jQuery.timers,
+                               data = jQuery._data( this );
+
+                       if ( index ) {
+                               if ( data[ index ] && data[ index ].stop ) {
+                                       stopQueue( data[ index ] );
+                               }
+                       } else {
+                               for ( index in data ) {
+                                       if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+                                               stopQueue( data[ index ] );
+                                       }
+                               }
+                       }
+
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+                                       timers[ index ].anim.stop( gotoEnd );
+                                       dequeue = false;
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // start the next in the queue if the last step wasn't forced
+                       // timers currently will call their complete callbacks, which will dequeue
+                       // but only if they were gotoEnd
+                       if ( dequeue || !gotoEnd ) {
+                               jQuery.dequeue( this, type );
+                       }
+               });
+       },
+       finish: function( type ) {
+               if ( type !== false ) {
+                       type = type || "fx";
+               }
+               return this.each(function() {
+                       var index,
+                               data = jQuery._data( this ),
+                               queue = data[ type + "queue" ],
+                               hooks = data[ type + "queueHooks" ],
+                               timers = jQuery.timers,
+                               length = queue ? queue.length : 0;
+
+                       // enable finishing flag on private data
+                       data.finish = true;
+
+                       // empty the queue first
+                       jQuery.queue( this, type, [] );
+
+                       if ( hooks && hooks.stop ) {
+                               hooks.stop.call( this, true );
+                       }
+
+                       // look for any active animations, and finish them
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+                                       timers[ index ].anim.stop( true );
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // look for any animations in the old queue and finish them
+                       for ( index = 0; index < length; index++ ) {
+                               if ( queue[ index ] && queue[ index ].finish ) {
+                                       queue[ index ].finish.call( this );
+                               }
+                       }
+
+                       // turn off finishing flag
+                       delete data.finish;
+               });
+       }
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+       var which,
+               attrs = { height: type },
+               i = 0;
+
+       // if we include width, step value is 1 to do all cssExpand values,
+       // if we don't include width, step value is 2 to skip over Left and Right
+       includeWidth = includeWidth? 1 : 0;
+       for( ; i < 4 ; i += 2 - includeWidth ) {
+               which = cssExpand[ i ];
+               attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+       }
+
+       if ( includeWidth ) {
+               attrs.opacity = attrs.width = type;
+       }
+
+       return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+       slideDown: genFx("show"),
+       slideUp: genFx("hide"),
+       slideToggle: genFx("toggle"),
+       fadeIn: { opacity: "show" },
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return this.animate( props, speed, easing, callback );
+       };
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+       var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+               complete: fn || !fn && easing ||
+                       jQuery.isFunction( speed ) && speed,
+               duration: speed,
+               easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+       };
+
+       opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+               opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+       // normalize opt.queue - true/undefined/null -> "fx"
+       if ( opt.queue == null || opt.queue === true ) {
+               opt.queue = "fx";
+       }
+
+       // Queueing
+       opt.old = opt.complete;
+
+       opt.complete = function() {
+               if ( jQuery.isFunction( opt.old ) ) {
+                       opt.old.call( this );
+               }
+
+               if ( opt.queue ) {
+                       jQuery.dequeue( this, opt.queue );
+               }
+       };
+
+       return opt;
+};
+
+jQuery.easing = {
+       linear: function( p ) {
+               return p;
+       },
+       swing: function( p ) {
+               return 0.5 - Math.cos( p*Math.PI ) / 2;
+       }
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+       var timer,
+               timers = jQuery.timers,
+               i = 0;
+
+       fxNow = jQuery.now();
+
+       for ( ; i < timers.length; i++ ) {
+               timer = timers[ i ];
+               // Checks the timer has not already been removed
+               if ( !timer() && timers[ i ] === timer ) {
+                       timers.splice( i--, 1 );
+               }
+       }
+
+       if ( !timers.length ) {
+               jQuery.fx.stop();
+       }
+       fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+       if ( timer() && jQuery.timers.push( timer ) ) {
+               jQuery.fx.start();
+       }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+       if ( !timerId ) {
+               timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+       }
+};
+
+jQuery.fx.stop = function() {
+       clearInterval( timerId );
+       timerId = null;
+};
+
+jQuery.fx.speeds = {
+       slow: 600,
+       fast: 200,
+       // Default speed
+       _default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+       jQuery.expr.filters.animated = function( elem ) {
+               return jQuery.grep(jQuery.timers, function( fn ) {
+                       return elem === fn.elem;
+               }).length;
+       };
+}
+jQuery.fn.offset = function( options ) {
+       if ( arguments.length ) {
+               return options === undefined ?
+                       this :
+                       this.each(function( i ) {
+                               jQuery.offset.setOffset( this, options, i );
+                       });
+       }
+
+       var docElem, win,
+               box = { top: 0, left: 0 },
+               elem = this[ 0 ],
+               doc = elem && elem.ownerDocument;
+
+       if ( !doc ) {
+               return;
+       }
+
+       docElem = doc.documentElement;
+
+       // Make sure it's not a disconnected DOM node
+       if ( !jQuery.contains( docElem, elem ) ) {
+               return box;
+       }
+
+       // If we don't have gBCR, just use 0,0 rather than error
+       // BlackBerry 5, iOS 3 (original iPhone)
+       if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+               box = elem.getBoundingClientRect();
+       }
+       win = getWindow( doc );
+       return {
+               top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
+               left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+       };
+};
+
+jQuery.offset = {
+
+       setOffset: function( elem, options, i ) {
+               var position = jQuery.css( elem, "position" );
+
+               // set position first, in-case top/left are set even on static elem
+               if ( position === "static" ) {
+                       elem.style.position = "relative";
+               }
+
+               var curElem = jQuery( elem ),
+                       curOffset = curElem.offset(),
+                       curCSSTop = jQuery.css( elem, "top" ),
+                       curCSSLeft = jQuery.css( elem, "left" ),
+                       calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+                       props = {}, curPosition = {}, curTop, curLeft;
+
+               // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+               if ( calculatePosition ) {
+                       curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
+               }
+
+               if ( jQuery.isFunction( options ) ) {
+                       options = options.call( elem, i, curOffset );
+               }
+
+               if ( options.top != null ) {
+                       props.top = ( options.top - curOffset.top ) + curTop;
+               }
+               if ( options.left != null ) {
+                       props.left = ( options.left - curOffset.left ) + curLeft;
+               }
+
+               if ( "using" in options ) {
+                       options.using.call( elem, props );
+               } else {
+                       curElem.css( props );
+               }
+       }
+};
+
+
+jQuery.fn.extend({
+
+       position: function() {
+               if ( !this[ 0 ] ) {
+                       return;
+               }
+
+               var offsetParent, offset,
+                       parentOffset = { top: 0, left: 0 },
+                       elem = this[ 0 ];
+
+               // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+               if ( jQuery.css( elem, "position" ) === "fixed" ) {
+                       // we assume that getBoundingClientRect is available when computed position is fixed
+                       offset = elem.getBoundingClientRect();
+               } else {
+                       // Get *real* offsetParent
+                       offsetParent = this.offsetParent();
+
+                       // Get correct offsets
+                       offset = this.offset();
+                       if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+                               parentOffset = offsetParent.offset();
+                       }
+
+                       // Add offsetParent borders
+                       parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+                       parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+               }
+
+               // Subtract parent offsets and element margins
+               // note: when an element has margin: auto the offsetLeft and marginLeft
+               // are the same in Safari causing offset.left to incorrectly be 0
+               return {
+                       top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+                       left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+               };
+       },
+
+       offsetParent: function() {
+               return this.map(function() {
+                       var offsetParent = this.offsetParent || docElem;
+                       while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+                               offsetParent = offsetParent.offsetParent;
+                       }
+                       return offsetParent || docElem;
+               });
+       }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+       var top = /Y/.test( prop );
+
+       jQuery.fn[ method ] = function( val ) {
+               return jQuery.access( this, function( elem, method, val ) {
+                       var win = getWindow( elem );
+
+                       if ( val === undefined ) {
+                               return win ? (prop in win) ? win[ prop ] :
+                                       win.document.documentElement[ method ] :
+                                       elem[ method ];
+                       }
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !top ? val : jQuery( win ).scrollLeft(),
+                                       top ? val : jQuery( win ).scrollTop()
+                               );
+
+                       } else {
+                               elem[ method ] = val;
+                       }
+               }, method, val, arguments.length, null );
+       };
+});
+
+function getWindow( elem ) {
+       return jQuery.isWindow( elem ) ?
+               elem :
+               elem.nodeType === 9 ?
+                       elem.defaultView || elem.parentWindow :
+                       false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+       jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+               // margin is only for outerHeight, outerWidth
+               jQuery.fn[ funcName ] = function( margin, value ) {
+                       var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+                               extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+                       return jQuery.access( this, function( elem, type, value ) {
+                               var doc;
+
+                               if ( jQuery.isWindow( elem ) ) {
+                                       // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+                                       // isn't a whole lot we can do. See pull request at this URL for discussion:
+                                       // https://github.com/jquery/jquery/pull/764
+                                       return elem.document.documentElement[ "client" + name ];
+                               }
+
+                               // Get document width or height
+                               if ( elem.nodeType === 9 ) {
+                                       doc = elem.documentElement;
+
+                                       // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+                                       // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+                                       return Math.max(
+                                               elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+                                               elem.body[ "offset" + name ], doc[ "offset" + name ],
+                                               doc[ "client" + name ]
+                                       );
+                               }
+
+                               return value === undefined ?
+                                       // Get width or height on the element, requesting but not forcing parseFloat
+                                       jQuery.css( elem, type, extra ) :
+
+                                       // Set width or height on the element
+                                       jQuery.style( elem, type, value, extra );
+                       }, type, chainable ? margin : undefined, chainable, null );
+               };
+       });
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+       return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+// })();
+if ( typeof module === "object" && module && typeof module.exports === "object" ) {
+       // Expose jQuery as module.exports in loaders that implement the Node
+       // module pattern (including browserify). Do not create the global, since
+       // the user will be storing it themselves locally, and globals are frowned
+       // upon in the Node module world.
+       module.exports = jQuery;
+} else {
+       // Otherwise expose jQuery to the global object as usual
+       window.jQuery = window.$ = jQuery;
+
+       // Register as a named AMD module, since jQuery can be concatenated with other
+       // files that may use define, but not via a proper concatenation script that
+       // understands anonymous AMD modules. A named AMD is safest and most robust
+       // way to register. Lowercase jquery is used because AMD module names are
+       // derived from file names, and jQuery is normally delivered in a lowercase
+       // file name. Do this after creating the global so that if an AMD module wants
+       // to call noConflict to hide this version of jQuery, it will work.
+       if ( typeof define === "function" && define.amd ) {
+               define( "jquery", [], function () { return jQuery; } );
+       }
+}
+
+})( window );
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_444444_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_444444_256x240.png
new file mode 100644 (file)
index 0000000..1df0745
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_444444_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_555555_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_555555_256x240.png
new file mode 100644 (file)
index 0000000..0b55938
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_555555_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777620_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777620_256x240.png
new file mode 100644 (file)
index 0000000..57da2a1
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777620_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777777_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777777_256x240.png
new file mode 100644 (file)
index 0000000..b5f6ac8
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_777777_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_cc0000_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_cc0000_256x240.png
new file mode 100644 (file)
index 0000000..d0fa9b7
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_cc0000_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_ffffff_256x240.png b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_ffffff_256x240.png
new file mode 100644 (file)
index 0000000..c964d9a
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/images/ui-icons_ffffff_256x240.png differ
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/index.html b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/index.html
new file mode 100644 (file)
index 0000000..b878272
--- /dev/null
@@ -0,0 +1,513 @@
+<!doctype html>
+<html lang="us">
+<head>
+       <meta charset="utf-8">
+       <title>jQuery UI Example Page</title>
+       <link href="jquery-ui.css" rel="stylesheet">
+       <style>
+       body{
+               font: 62.5% "Trebuchet MS", sans-serif;
+               margin: 50px;
+       }
+       .demoHeaders {
+               margin-top: 2em;
+       }
+       #dialog-link {
+               padding: .4em 1em .4em 20px;
+               text-decoration: none;
+               position: relative;
+       }
+       #dialog-link span.ui-icon {
+               margin: 0 5px 0 0;
+               position: absolute;
+               left: .2em;
+               top: 50%;
+               margin-top: -8px;
+       }
+       #icons {
+               margin: 0;
+               padding: 0;
+       }
+       #icons li {
+               margin: 2px;
+               position: relative;
+               padding: 4px 0;
+               cursor: pointer;
+               float: left;
+               list-style: none;
+       }
+       #icons span.ui-icon {
+               float: left;
+               margin: 0 4px;
+       }
+       .fakewindowcontain .ui-widget-overlay {
+               position: absolute;
+       }
+       select {
+               width: 200px;
+       }
+       </style>
+</head>
+<body>
+
+<h1>Welcome to jQuery UI!</h1>
+
+<div class="ui-widget">
+       <p>This page demonstrates the widgets and theme you selected in Download Builder. Please make sure you are using them with a compatible jQuery version.</p>
+</div>
+
+<h1>YOUR COMPONENTS:</h1>
+
+
+<!-- Accordion -->
+<h2 class="demoHeaders">Accordion</h2>
+<div id="accordion">
+       <h3>First</h3>
+       <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
+       <h3>Second</h3>
+       <div>Phasellus mattis tincidunt nibh.</div>
+       <h3>Third</h3>
+       <div>Nam dui erat, auctor a, dignissim quis.</div>
+</div>
+
+
+
+<!-- Autocomplete -->
+<h2 class="demoHeaders">Autocomplete</h2>
+<div>
+       <input id="autocomplete" title="type &quot;a&quot;">
+</div>
+
+
+
+<!-- Button -->
+<h2 class="demoHeaders">Button</h2>
+<button id="button">A button element</button>
+<form style="margin-top: 1em;">
+       <div id="radioset">
+               <input type="radio" id="radio1" name="radio"><label for="radio1">Choice 1</label>
+               <input type="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Choice 2</label>
+               <input type="radio" id="radio3" name="radio"><label for="radio3">Choice 3</label>
+       </div>
+</form>
+
+
+
+<!-- Tabs -->
+<h2 class="demoHeaders">Tabs</h2>
+<div id="tabs">
+       <ul>
+               <li><a href="#tabs-1">First</a></li>
+               <li><a href="#tabs-2">Second</a></li>
+               <li><a href="#tabs-3">Third</a></li>
+       </ul>
+       <div id="tabs-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
+       <div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
+       <div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
+</div>
+
+
+
+<!-- Dialog NOTE: Dialog is not generated by UI in this demo so it can be visually styled in themeroller-->
+<h2 class="demoHeaders">Dialog</h2>
+<p><a href="#" id="dialog-link" class="ui-state-default ui-corner-all"><span class="ui-icon ui-icon-newwin"></span>Open Dialog</a></p>
+
+<h2 class="demoHeaders">Overlay and Shadow Classes <em>(not currently used in UI widgets)</em></h2>
+<div style="position: relative; width: 96%; height: 200px; padding:1% 2%; overflow:hidden;" class="fakewindowcontain">
+       <p>Lorem ipsum dolor sit amet,  Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
+
+       <!-- ui-dialog -->
+       <div class="ui-overlay"><div class="ui-widget-overlay"></div><div class="ui-widget-shadow ui-corner-all" style="width: 302px; height: 152px; position: absolute; left: 50px; top: 30px;"></div></div>
+       <div style="position: absolute; width: 280px; height: 130px;left: 50px; top: 30px; padding: 10px;" class="ui-widget ui-widget-content ui-corner-all">
+               <div class="ui-dialog-content ui-widget-content" style="background: none; border: 0;">
+                       <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+               </div>
+       </div>
+
+</div>
+
+<!-- ui-dialog -->
+<div id="dialog" title="Dialog Title">
+       <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+</div>
+
+
+
+<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
+<ul id="icons" class="ui-widget ui-helper-clearfix">
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-n"><span class="ui-icon ui-icon-carat-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-ne"><span class="ui-icon ui-icon-carat-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-e"><span class="ui-icon ui-icon-carat-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-se"><span class="ui-icon ui-icon-carat-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-s"><span class="ui-icon ui-icon-carat-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-sw"><span class="ui-icon ui-icon-carat-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-w"><span class="ui-icon ui-icon-carat-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-nw"><span class="ui-icon ui-icon-carat-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-n-s"><span class="ui-icon ui-icon-carat-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-e-w"><span class="ui-icon ui-icon-carat-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-sw"><span class="ui-icon ui-icon-triangle-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-w"><span class="ui-icon ui-icon-triangle-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-nw"><span class="ui-icon ui-icon-triangle-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-s"><span class="ui-icon ui-icon-arrow-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-sw"><span class="ui-icon ui-icon-arrow-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-w"><span class="ui-icon ui-icon-arrow-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-e"><span class="ui-icon ui-icon-arrowstop-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-s"><span class="ui-icon ui-icon-arrowstop-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-w"><span class="ui-icon ui-icon-arrowstop-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-w"><span class="ui-icon ui-icon-arrowthick-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-nw"><span class="ui-icon ui-icon-arrowthick-1-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-n-s"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-w"><span class="ui-icon ui-icon-arrowthickstop-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-w"><span class="ui-icon ui-icon-arrowreturnthick-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-n"><span class="ui-icon ui-icon-arrowreturnthick-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-w"><span class="ui-icon ui-icon-arrowrefresh-1-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-n"><span class="ui-icon ui-icon-arrowrefresh-1-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-e"><span class="ui-icon ui-icon-arrowrefresh-1-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-shuffle"><span class="ui-icon ui-icon-shuffle"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-transfer-e-w"><span class="ui-icon ui-icon-transfer-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-transferthick-e-w"><span class="ui-icon ui-icon-transferthick-e-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-mail-open"><span class="ui-icon ui-icon-mail-open"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-suitcase"><span class="ui-icon ui-icon-suitcase"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-comment"><span class="ui-icon ui-icon-comment"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-tag"><span class="ui-icon ui-icon-tag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-home"><span class="ui-icon ui-icon-home"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-flag"><span class="ui-icon ui-icon-flag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-zoomin"><span class="ui-icon ui-icon-zoomin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-zoomout"><span class="ui-icon ui-icon-zoomout"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-search"><span class="ui-icon ui-icon-search"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-plus"><span class="ui-icon ui-icon-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-minus"><span class="ui-icon ui-icon-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-clipboard"><span class="ui-icon ui-icon-clipboard"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-copy"><span class="ui-icon ui-icon-copy"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-contact"><span class="ui-icon ui-icon-contact"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-image"><span class="ui-icon ui-icon-image"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-bullet"><span class="ui-icon ui-icon-bullet"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-radio-off"><span class="ui-icon ui-icon-radio-off"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-radio-on"><span class="ui-icon ui-icon-radio-on"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pin-w"><span class="ui-icon ui-icon-pin-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-seek-first"><span class="ui-icon ui-icon-seek-first"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-stop"><span class="ui-icon ui-icon-stop"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-eject"><span class="ui-icon ui-icon-eject"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-1"><span class="ui-icon ui-icon-battery-1"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-2"><span class="ui-icon ui-icon-battery-2"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-battery-3"><span class="ui-icon ui-icon-battery-3"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-n"><span class="ui-icon ui-icon-circle-triangle-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-e"><span class="ui-icon ui-icon-circle-arrow-e"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-s"><span class="ui-icon ui-icon-circle-arrow-s"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-minus"><span class="ui-icon ui-icon-circlesmall-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-close"><span class="ui-icon ui-icon-circlesmall-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-plus"><span class="ui-icon ui-icon-squaresmall-plus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-gripsmall-diagonal-se"><span class="ui-icon ui-icon-gripsmall-diagonal-se"></span></li>
+       <li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
+</ul>
+
+
+<!-- Slider -->
+<h2 class="demoHeaders">Slider</h2>
+<div id="slider"></div>
+
+
+
+<!-- Datepicker -->
+<h2 class="demoHeaders">Datepicker</h2>
+<div id="datepicker"></div>
+
+
+
+<!-- Progressbar -->
+<h2 class="demoHeaders">Progressbar</h2>
+<div id="progressbar"></div>
+
+
+
+<!-- Progressbar -->
+<h2 class="demoHeaders">Selectmenu</h2>
+<select id="selectmenu">
+       <option>Slower</option>
+       <option>Slow</option>
+       <option selected="selected">Medium</option>
+       <option>Fast</option>
+       <option>Faster</option>
+</select>
+
+
+
+<!-- Spinner -->
+<h2 class="demoHeaders">Spinner</h2>
+<input id="spinner">
+
+
+
+<!-- Menu -->
+<h2 class="demoHeaders">Menu</h2>
+<ul style="width:100px;" id="menu">
+       <li>Item 1</li>
+       <li>Item 2</li>
+       <li>Item 3
+               <ul>
+                       <li>Item 3-1</li>
+                       <li>Item 3-2</li>
+                       <li>Item 3-3</li>
+                       <li>Item 3-4</li>
+                       <li>Item 3-5</li>
+               </ul>
+       </li>
+       <li>Item 4</li>
+       <li>Item 5</li>
+</ul>
+
+
+
+<!-- Tooltip -->
+<h2 class="demoHeaders">Tooltip</h2>
+<p id="tooltip">
+       <a href="#" title="That&apos;s what this widget is">Tooltips</a> can be attached to any element. When you hover
+the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.
+</p>
+
+
+<!-- Highlight / Error -->
+<h2 class="demoHeaders">Highlight / Error</h2>
+<div class="ui-widget">
+       <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;">
+               <p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
+               <strong>Hey!</strong> Sample ui-state-highlight style.</p>
+       </div>
+</div>
+<br>
+<div class="ui-widget">
+       <div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
+               <p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
+               <strong>Alert:</strong> Sample ui-state-error style.</p>
+       </div>
+</div>
+
+<script src="external/jquery/jquery.js"></script>
+<script src="jquery-ui.js"></script>
+<script>
+
+$( "#accordion" ).accordion();
+
+
+
+var availableTags = [
+       "ActionScript",
+       "AppleScript",
+       "Asp",
+       "BASIC",
+       "C",
+       "C++",
+       "Clojure",
+       "COBOL",
+       "ColdFusion",
+       "Erlang",
+       "Fortran",
+       "Groovy",
+       "Haskell",
+       "Java",
+       "JavaScript",
+       "Lisp",
+       "Perl",
+       "PHP",
+       "Python",
+       "Ruby",
+       "Scala",
+       "Scheme"
+];
+$( "#autocomplete" ).autocomplete({
+       source: availableTags
+});
+
+
+
+$( "#button" ).button();
+$( "#radioset" ).buttonset();
+
+
+
+$( "#tabs" ).tabs();
+
+
+
+$( "#dialog" ).dialog({
+       autoOpen: false,
+       width: 400,
+       buttons: [
+               {
+                       text: "Ok",
+                       click: function() {
+                               $( this ).dialog( "close" );
+                       }
+               },
+               {
+                       text: "Cancel",
+                       click: function() {
+                               $( this ).dialog( "close" );
+                       }
+               }
+       ]
+});
+
+// Link to open the dialog
+$( "#dialog-link" ).click(function( event ) {
+       $( "#dialog" ).dialog( "open" );
+       event.preventDefault();
+});
+
+
+
+$( "#datepicker" ).datepicker({
+       inline: true
+});
+
+
+
+$( "#slider" ).slider({
+       range: true,
+       values: [ 17, 67 ]
+});
+
+
+
+$( "#progressbar" ).progressbar({
+       value: 20
+});
+
+
+
+$( "#spinner" ).spinner();
+
+
+
+$( "#menu" ).menu();
+
+
+
+$( "#tooltip" ).tooltip();
+
+
+
+$( "#selectmenu" ).selectmenu();
+
+
+// Hover states on the static widgets
+$( "#dialog-link, #icons li" ).hover(
+       function() {
+               $( this ).addClass( "ui-state-hover" );
+       },
+       function() {
+               $( this ).removeClass( "ui-state-hover" );
+       }
+);
+</script>
+</body>
+</html>
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.css
new file mode 100644 (file)
index 0000000..975aa1b
--- /dev/null
@@ -0,0 +1,1225 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+       display: none;
+}
+.ui-helper-hidden-accessible {
+       border: 0;
+       clip: rect(0 0 0 0);
+       height: 1px;
+       margin: -1px;
+       overflow: hidden;
+       padding: 0;
+       position: absolute;
+       width: 1px;
+}
+.ui-helper-reset {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       outline: 0;
+       line-height: 1.3;
+       text-decoration: none;
+       font-size: 100%;
+       list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+       content: "";
+       display: table;
+       border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+       clear: both;
+}
+.ui-helper-clearfix {
+       min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       left: 0;
+       position: absolute;
+       opacity: 0;
+       filter:Alpha(Opacity=0); /* support: IE8 */
+}
+
+.ui-front {
+       z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+       cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       display: block;
+       text-indent: -99999px;
+       overflow: hidden;
+       background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+       position: fixed;
+       top: 0;
+       left: 0;
+       width: 100%;
+       height: 100%;
+}
+.ui-accordion .ui-accordion-header {
+       display: block;
+       cursor: pointer;
+       position: relative;
+       margin: 2px 0 0 0;
+       padding: .5em .5em .5em .7em;
+       min-height: 0; /* support: IE7 */
+       font-size: 100%;
+}
+.ui-accordion .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+       position: absolute;
+       left: .5em;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+       padding: 1em 2.2em;
+       border-top: 0;
+       overflow: auto;
+}
+.ui-autocomplete {
+       position: absolute;
+       top: 0;
+       left: 0;
+       cursor: default;
+}
+.ui-button {
+       display: inline-block;
+       position: relative;
+       padding: 0;
+       line-height: normal;
+       margin-right: .1em;
+       cursor: pointer;
+       vertical-align: middle;
+       text-align: center;
+       overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+       text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+       width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+       width: 2.4em;
+}
+.ui-button-icons-only {
+       width: 3.4em;
+}
+button.ui-button-icons-only {
+       width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+       display: block;
+       line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+       padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+       padding: .4em;
+       text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+       padding-left: 2.1em;
+       padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+       padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+       position: absolute;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+       left: 50%;
+       margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+       left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+       right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+       margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+       margin-left: 0;
+       margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+       border: 0;
+       padding: 0;
+}
+.ui-datepicker {
+       width: 17em;
+       padding: .2em .2em 0;
+       display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+       position: relative;
+       padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+       position: absolute;
+       top: 2px;
+       width: 1.8em;
+       height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+       top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+       left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+       right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+       left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+       right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+       display: block;
+       position: absolute;
+       left: 50%;
+       margin-left: -8px;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+       margin: 0 2.3em;
+       line-height: 1.8em;
+       text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+       font-size: 1em;
+       margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+       width: 45%;
+}
+.ui-datepicker table {
+       width: 100%;
+       font-size: .9em;
+       border-collapse: collapse;
+       margin: 0 0 .4em;
+}
+.ui-datepicker th {
+       padding: .7em .3em;
+       text-align: center;
+       font-weight: bold;
+       border: 0;
+}
+.ui-datepicker td {
+       border: 0;
+       padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+       display: block;
+       padding: .2em;
+       text-align: right;
+       text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+       background-image: none;
+       margin: .7em 0 0 0;
+       padding: 0 .2em;
+       border-left: 0;
+       border-right: 0;
+       border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+       float: right;
+       margin: .5em .2em .4em;
+       cursor: pointer;
+       padding: .2em .6em .3em .6em;
+       width: auto;
+       overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+       float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+       width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+       float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+       width: 95%;
+       margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+       width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+       width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+       width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+       border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+       clear: left;
+}
+.ui-datepicker-row-break {
+       clear: both;
+       width: 100%;
+       font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+       direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+       right: 2px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+       left: 2px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+       right: 1px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+       left: 1px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+       clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+       float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+       float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+       border-right-width: 0;
+       border-left-width: 1px;
+}
+.ui-dialog {
+       overflow: hidden;
+       position: absolute;
+       top: 0;
+       left: 0;
+       padding: .2em;
+       outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+       padding: .4em 1em;
+       position: relative;
+}
+.ui-dialog .ui-dialog-title {
+       float: left;
+       margin: .1em 0;
+       white-space: nowrap;
+       width: 90%;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+       position: absolute;
+       right: .3em;
+       top: 50%;
+       width: 20px;
+       margin: -10px 0 0 0;
+       padding: 1px;
+       height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+       position: relative;
+       border: 0;
+       padding: .5em 1em;
+       background: none;
+       overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+       text-align: left;
+       border-width: 1px 0 0 0;
+       background-image: none;
+       margin-top: .5em;
+       padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+       float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+       margin: .5em .4em .5em 0;
+       cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+       width: 12px;
+       height: 12px;
+       right: -5px;
+       bottom: -5px;
+       background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+       cursor: move;
+}
+.ui-draggable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-menu {
+       list-style: none;
+       padding: 0;
+       margin: 0;
+       display: block;
+       outline: none;
+}
+.ui-menu .ui-menu {
+       position: absolute;
+}
+.ui-menu .ui-menu-item {
+       position: relative;
+       margin: 0;
+       padding: 3px 1em 3px .4em;
+       cursor: pointer;
+       min-height: 0; /* support: IE7 */
+       /* support: IE10, see #8844 */
+       list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
+}
+.ui-menu .ui-menu-divider {
+       margin: 5px 0;
+       height: 0;
+       font-size: 0;
+       line-height: 0;
+       border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-focus,
+.ui-menu .ui-state-active {
+       margin: -1px;
+}
+
+/* icon support */
+.ui-menu-icons {
+       position: relative;
+}
+.ui-menu-icons .ui-menu-item {
+       padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: .2em;
+       margin: auto 0;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+       left: auto;
+       right: 0;
+}
+.ui-progressbar {
+       height: 2em;
+       text-align: left;
+       overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+       margin: -1px;
+       height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+       background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
+       height: 100%;
+       filter: alpha(opacity=25); /* support: IE8 */
+       opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+       background-image: none;
+}
+.ui-resizable {
+       position: relative;
+}
+.ui-resizable-handle {
+       position: absolute;
+       font-size: 0.1px;
+       display: block;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+       display: none;
+}
+.ui-resizable-n {
+       cursor: n-resize;
+       height: 7px;
+       width: 100%;
+       top: -5px;
+       left: 0;
+}
+.ui-resizable-s {
+       cursor: s-resize;
+       height: 7px;
+       width: 100%;
+       bottom: -5px;
+       left: 0;
+}
+.ui-resizable-e {
+       cursor: e-resize;
+       width: 7px;
+       right: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-w {
+       cursor: w-resize;
+       width: 7px;
+       left: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-se {
+       cursor: se-resize;
+       width: 12px;
+       height: 12px;
+       right: 1px;
+       bottom: 1px;
+}
+.ui-resizable-sw {
+       cursor: sw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       bottom: -5px;
+}
+.ui-resizable-nw {
+       cursor: nw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       top: -5px;
+}
+.ui-resizable-ne {
+       cursor: ne-resize;
+       width: 9px;
+       height: 9px;
+       right: -5px;
+       top: -5px;
+}
+.ui-selectable {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-selectable-helper {
+       position: absolute;
+       z-index: 100;
+       border: 1px dotted black;
+}
+.ui-selectmenu-menu {
+       padding: 0;
+       margin: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+       overflow: auto;
+       /* Support: IE7 */
+       overflow-x: hidden;
+       padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+       font-size: 1em;
+       font-weight: bold;
+       line-height: 1.5;
+       padding: 2px 0.4em;
+       margin: 0.5em 0 0 0;
+       height: auto;
+       border: 0;
+}
+.ui-selectmenu-open {
+       display: block;
+}
+.ui-selectmenu-button {
+       display: inline-block;
+       overflow: hidden;
+       position: relative;
+       text-decoration: none;
+       cursor: pointer;
+}
+.ui-selectmenu-button span.ui-icon {
+       right: 0.5em;
+       left: auto;
+       margin-top: -8px;
+       position: absolute;
+       top: 50%;
+}
+.ui-selectmenu-button span.ui-selectmenu-text {
+       text-align: left;
+       padding: 0.4em 2.1em 0.4em 1em;
+       display: block;
+       line-height: 1.4;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.ui-slider {
+       position: relative;
+       text-align: left;
+}
+.ui-slider .ui-slider-handle {
+       position: absolute;
+       z-index: 2;
+       width: 1.2em;
+       height: 1.2em;
+       cursor: default;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-slider .ui-slider-range {
+       position: absolute;
+       z-index: 1;
+       font-size: .7em;
+       display: block;
+       border: 0;
+       background-position: 0 0;
+}
+
+/* support: IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+       filter: inherit;
+}
+
+.ui-slider-horizontal {
+       height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+       top: -.3em;
+       margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+       top: 0;
+       height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+       left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+       right: 0;
+}
+
+.ui-slider-vertical {
+       width: .8em;
+       height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+       left: -.3em;
+       margin-left: 0;
+       margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+       left: 0;
+       width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+       bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+       top: 0;
+}
+.ui-sortable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-spinner {
+       position: relative;
+       display: inline-block;
+       overflow: hidden;
+       padding: 0;
+       vertical-align: middle;
+}
+.ui-spinner-input {
+       border: none;
+       background: none;
+       color: inherit;
+       padding: 0;
+       margin: .2em 0;
+       vertical-align: middle;
+       margin-left: .4em;
+       margin-right: 22px;
+}
+.ui-spinner-button {
+       width: 16px;
+       height: 50%;
+       font-size: .5em;
+       padding: 0;
+       margin: 0;
+       text-align: center;
+       position: absolute;
+       cursor: default;
+       display: block;
+       overflow: hidden;
+       right: 0;
+}
+/* more specificity required here to override default borders */
+.ui-spinner a.ui-spinner-button {
+       border-top: none;
+       border-bottom: none;
+       border-right: none;
+}
+/* vertically center icon */
+.ui-spinner .ui-icon {
+       position: absolute;
+       margin-top: -8px;
+       top: 50%;
+       left: 0;
+}
+.ui-spinner-up {
+       top: 0;
+}
+.ui-spinner-down {
+       bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+       /* need to fix icons sprite */
+       background-position: -65px -16px;
+}
+.ui-tabs {
+       position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+       padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+       margin: 0;
+       padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+       list-style: none;
+       float: left;
+       position: relative;
+       top: 0;
+       margin: 1px .2em 0 0;
+       border-bottom-width: 0;
+       padding: 0;
+       white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+       float: left;
+       padding: .5em 1em;
+       text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+       margin-bottom: -1px;
+       padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+       cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+       cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+       display: block;
+       border-width: 0;
+       padding: 1em 1.4em;
+       background: none;
+}
+.ui-tooltip {
+       padding: 8px;
+       position: absolute;
+       z-index: 9999;
+       max-width: 300px;
+       -webkit-box-shadow: 0 0 5px #aaa;
+       box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+       border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+       font-family: Arial,Helvetica,sans-serif;
+       font-size: 1em;
+}
+.ui-widget .ui-widget {
+       font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+       font-family: Arial,Helvetica,sans-serif;
+       font-size: 1em;
+}
+.ui-widget-content {
+       border: 1px solid #dddddd;
+       background: #ffffff;
+       color: #333333;
+}
+.ui-widget-content a {
+       color: #333333;
+}
+.ui-widget-header {
+       border: 1px solid #dddddd;
+       background: #e9e9e9;
+       color: #333333;
+       font-weight: bold;
+}
+.ui-widget-header a {
+       color: #333333;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+       border: 1px solid #c5c5c5;
+       background: #f6f6f6;
+       font-weight: normal;
+       color: #454545;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+       color: #454545;
+       text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+       border: 1px solid #cccccc;
+       background: #ededed;
+       font-weight: normal;
+       color: #2b2b2b;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited {
+       color: #2b2b2b;
+       text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+       border: 1px solid #003eff;
+       background: #007fff;
+       font-weight: normal;
+       color: #ffffff;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+       color: #ffffff;
+       text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+       border: 1px solid #dad55e;
+       background: #fffa90;
+       color: #777620;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+       color: #777620;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+       border: 1px solid #f1a899;
+       background: #fddfdf;
+       color: #5f3f3f;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+       color: #5f3f3f;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+       color: #5f3f3f;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+       font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+       opacity: .7;
+       filter:Alpha(Opacity=70); /* support: IE8 */
+       font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+       opacity: .35;
+       filter:Alpha(Opacity=35); /* support: IE8 */
+       background-image: none;
+}
+.ui-state-disabled .ui-icon {
+       filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       width: 16px;
+       height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+       background-image: url("images/ui-icons_444444_256x240.png");
+}
+.ui-widget-header .ui-icon {
+       background-image: url("images/ui-icons_444444_256x240.png");
+}
+.ui-state-default .ui-icon {
+       background-image: url("images/ui-icons_777777_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+       background-image: url("images/ui-icons_555555_256x240.png");
+}
+.ui-state-active .ui-icon {
+       background-image: url("images/ui-icons_ffffff_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+       background-image: url("images/ui-icons_777620_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+       background-image: url("images/ui-icons_cc0000_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+       border-top-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+       border-top-right-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+       border-bottom-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+       border-bottom-right-radius: 3px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+       background: #aaaaaa;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+}
+.ui-widget-shadow {
+       margin: 0px 0 0 0px;
+       padding: 5px;
+       background: #666666;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+       border-radius: 8px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.js
new file mode 100644 (file)
index 0000000..b3c719c
--- /dev/null
@@ -0,0 +1,16608 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function( factory ) {
+       if ( typeof define === "function" && define.amd ) {
+
+               // AMD. Register as an anonymous module.
+               define([ "jquery" ], factory );
+       } else {
+
+               // Browser globals
+               factory( jQuery );
+       }
+}(function( $ ) {
+/*!
+ * jQuery UI Core 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/ui-core/
+ */
+
+
+// $.ui might exist from components with no dependencies, e.g., $.ui.position
+$.ui = $.ui || {};
+
+$.extend( $.ui, {
+       version: "1.11.3",
+
+       keyCode: {
+               BACKSPACE: 8,
+               COMMA: 188,
+               DELETE: 46,
+               DOWN: 40,
+               END: 35,
+               ENTER: 13,
+               ESCAPE: 27,
+               HOME: 36,
+               LEFT: 37,
+               PAGE_DOWN: 34,
+               PAGE_UP: 33,
+               PERIOD: 190,
+               RIGHT: 39,
+               SPACE: 32,
+               TAB: 9,
+               UP: 38
+       }
+});
+
+// plugins
+$.fn.extend({
+       scrollParent: function( includeHidden ) {
+               var position = this.css( "position" ),
+                       excludeStaticParent = position === "absolute",
+                       overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
+                       scrollParent = this.parents().filter( function() {
+                               var parent = $( this );
+                               if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+                                       return false;
+                               }
+                               return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
+                       }).eq( 0 );
+
+               return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
+       },
+
+       uniqueId: (function() {
+               var uuid = 0;
+
+               return function() {
+                       return this.each(function() {
+                               if ( !this.id ) {
+                                       this.id = "ui-id-" + ( ++uuid );
+                               }
+                       });
+               };
+       })(),
+
+       removeUniqueId: function() {
+               return this.each(function() {
+                       if ( /^ui-id-\d+$/.test( this.id ) ) {
+                               $( this ).removeAttr( "id" );
+                       }
+               });
+       }
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+       var map, mapName, img,
+               nodeName = element.nodeName.toLowerCase();
+       if ( "area" === nodeName ) {
+               map = element.parentNode;
+               mapName = map.name;
+               if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+                       return false;
+               }
+               img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
+               return !!img && visible( img );
+       }
+       return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
+               !element.disabled :
+               "a" === nodeName ?
+                       element.href || isTabIndexNotNaN :
+                       isTabIndexNotNaN) &&
+               // the element and all of its ancestors must be visible
+               visible( element );
+}
+
+function visible( element ) {
+       return $.expr.filters.visible( element ) &&
+               !$( element ).parents().addBack().filter(function() {
+                       return $.css( this, "visibility" ) === "hidden";
+               }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+       data: $.expr.createPseudo ?
+               $.expr.createPseudo(function( dataName ) {
+                       return function( elem ) {
+                               return !!$.data( elem, dataName );
+                       };
+               }) :
+               // support: jQuery <1.8
+               function( elem, i, match ) {
+                       return !!$.data( elem, match[ 3 ] );
+               },
+
+       focusable: function( element ) {
+               return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+       },
+
+       tabbable: function( element ) {
+               var tabIndex = $.attr( element, "tabindex" ),
+                       isTabIndexNaN = isNaN( tabIndex );
+               return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+       }
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+       $.each( [ "Width", "Height" ], function( i, name ) {
+               var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+                       type = name.toLowerCase(),
+                       orig = {
+                               innerWidth: $.fn.innerWidth,
+                               innerHeight: $.fn.innerHeight,
+                               outerWidth: $.fn.outerWidth,
+                               outerHeight: $.fn.outerHeight
+                       };
+
+               function reduce( elem, size, border, margin ) {
+                       $.each( side, function() {
+                               size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+                               if ( border ) {
+                                       size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+                               }
+                               if ( margin ) {
+                                       size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+                               }
+                       });
+                       return size;
+               }
+
+               $.fn[ "inner" + name ] = function( size ) {
+                       if ( size === undefined ) {
+                               return orig[ "inner" + name ].call( this );
+                       }
+
+                       return this.each(function() {
+                               $( this ).css( type, reduce( this, size ) + "px" );
+                       });
+               };
+
+               $.fn[ "outer" + name] = function( size, margin ) {
+                       if ( typeof size !== "number" ) {
+                               return orig[ "outer" + name ].call( this, size );
+                       }
+
+                       return this.each(function() {
+                               $( this).css( type, reduce( this, size, true, margin ) + "px" );
+                       });
+               };
+       });
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+       $.fn.removeData = (function( removeData ) {
+               return function( key ) {
+                       if ( arguments.length ) {
+                               return removeData.call( this, $.camelCase( key ) );
+                       } else {
+                               return removeData.call( this );
+                       }
+               };
+       })( $.fn.removeData );
+}
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.fn.extend({
+       focus: (function( orig ) {
+               return function( delay, fn ) {
+                       return typeof delay === "number" ?
+                               this.each(function() {
+                                       var elem = this;
+                                       setTimeout(function() {
+                                               $( elem ).focus();
+                                               if ( fn ) {
+                                                       fn.call( elem );
+                                               }
+                                       }, delay );
+                               }) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.focus ),
+
+       disableSelection: (function() {
+               var eventType = "onselectstart" in document.createElement( "div" ) ?
+                       "selectstart" :
+                       "mousedown";
+
+               return function() {
+                       return this.bind( eventType + ".ui-disableSelection", function( event ) {
+                               event.preventDefault();
+                       });
+               };
+       })(),
+
+       enableSelection: function() {
+               return this.unbind( ".ui-disableSelection" );
+       },
+
+       zIndex: function( zIndex ) {
+               if ( zIndex !== undefined ) {
+                       return this.css( "zIndex", zIndex );
+               }
+
+               if ( this.length ) {
+                       var elem = $( this[ 0 ] ), position, value;
+                       while ( elem.length && elem[ 0 ] !== document ) {
+                               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+                               // This makes behavior of this function consistent across browsers
+                               // WebKit always returns auto if the element is positioned
+                               position = elem.css( "position" );
+                               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                                       // IE returns 0 when zIndex is not specified
+                                       // other browsers return a string
+                                       // we ignore the case of nested elements with an explicit value of 0
+                                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                                       value = parseInt( elem.css( "zIndex" ), 10 );
+                                       if ( !isNaN( value ) && value !== 0 ) {
+                                               return value;
+                                       }
+                               }
+                               elem = elem.parent();
+                       }
+               }
+
+               return 0;
+       }
+});
+
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
+$.ui.plugin = {
+       add: function( module, option, set ) {
+               var i,
+                       proto = $.ui[ module ].prototype;
+               for ( i in set ) {
+                       proto.plugins[ i ] = proto.plugins[ i ] || [];
+                       proto.plugins[ i ].push( [ option, set[ i ] ] );
+               }
+       },
+       call: function( instance, name, args, allowDisconnected ) {
+               var i,
+                       set = instance.plugins[ name ];
+
+               if ( !set ) {
+                       return;
+               }
+
+               if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
+                       return;
+               }
+
+               for ( i = 0; i < set.length; i++ ) {
+                       if ( instance.options[ set[ i ][ 0 ] ] ) {
+                               set[ i ][ 1 ].apply( instance.element, args );
+                       }
+               }
+       }
+};
+
+
+/*!
+ * jQuery UI Widget 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/jQuery.widget/
+ */
+
+
+var widget_uuid = 0,
+       widget_slice = Array.prototype.slice;
+
+$.cleanData = (function( orig ) {
+       return function( elems ) {
+               var events, elem, i;
+               for ( i = 0; (elem = elems[i]) != null; i++ ) {
+                       try {
+
+                               // Only trigger remove when necessary to save time
+                               events = $._data( elem, "events" );
+                               if ( events && events.remove ) {
+                                       $( elem ).triggerHandler( "remove" );
+                               }
+
+                       // http://bugs.jquery.com/ticket/8235
+                       } catch ( e ) {}
+               }
+               orig( elems );
+       };
+})( $.cleanData );
+
+$.widget = function( name, base, prototype ) {
+       var fullName, existingConstructor, constructor, basePrototype,
+               // proxiedPrototype allows the provided prototype to remain unmodified
+               // so that it can be used as a mixin for multiple widgets (#8876)
+               proxiedPrototype = {},
+               namespace = name.split( "." )[ 0 ];
+
+       name = name.split( "." )[ 1 ];
+       fullName = namespace + "-" + name;
+
+       if ( !prototype ) {
+               prototype = base;
+               base = $.Widget;
+       }
+
+       // create selector for plugin
+       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+               return !!$.data( elem, fullName );
+       };
+
+       $[ namespace ] = $[ namespace ] || {};
+       existingConstructor = $[ namespace ][ name ];
+       constructor = $[ namespace ][ name ] = function( options, element ) {
+               // allow instantiation without "new" keyword
+               if ( !this._createWidget ) {
+                       return new constructor( options, element );
+               }
+
+               // allow instantiation without initializing for simple inheritance
+               // must use "new" keyword (the code above always passes args)
+               if ( arguments.length ) {
+                       this._createWidget( options, element );
+               }
+       };
+       // extend with the existing constructor to carry over any static properties
+       $.extend( constructor, existingConstructor, {
+               version: prototype.version,
+               // copy the object used to create the prototype in case we need to
+               // redefine the widget later
+               _proto: $.extend( {}, prototype ),
+               // track widgets that inherit from this widget in case this widget is
+               // redefined after a widget inherits from it
+               _childConstructors: []
+       });
+
+       basePrototype = new base();
+       // we need to make the options hash a property directly on the new instance
+       // otherwise we'll modify the options hash on the prototype that we're
+       // inheriting from
+       basePrototype.options = $.widget.extend( {}, basePrototype.options );
+       $.each( prototype, function( prop, value ) {
+               if ( !$.isFunction( value ) ) {
+                       proxiedPrototype[ prop ] = value;
+                       return;
+               }
+               proxiedPrototype[ prop ] = (function() {
+                       var _super = function() {
+                                       return base.prototype[ prop ].apply( this, arguments );
+                               },
+                               _superApply = function( args ) {
+                                       return base.prototype[ prop ].apply( this, args );
+                               };
+                       return function() {
+                               var __super = this._super,
+                                       __superApply = this._superApply,
+                                       returnValue;
+
+                               this._super = _super;
+                               this._superApply = _superApply;
+
+                               returnValue = value.apply( this, arguments );
+
+                               this._super = __super;
+                               this._superApply = __superApply;
+
+                               return returnValue;
+                       };
+               })();
+       });
+       constructor.prototype = $.widget.extend( basePrototype, {
+               // TODO: remove support for widgetEventPrefix
+               // always use the name + a colon as the prefix, e.g., draggable:start
+               // don't prefix for widgets that aren't DOM-based
+               widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
+       }, proxiedPrototype, {
+               constructor: constructor,
+               namespace: namespace,
+               widgetName: name,
+               widgetFullName: fullName
+       });
+
+       // If this widget is being redefined then we need to find all widgets that
+       // are inheriting from it and redefine all of them so that they inherit from
+       // the new version of this widget. We're essentially trying to replace one
+       // level in the prototype chain.
+       if ( existingConstructor ) {
+               $.each( existingConstructor._childConstructors, function( i, child ) {
+                       var childPrototype = child.prototype;
+
+                       // redefine the child widget using the same prototype that was
+                       // originally used, but inherit from the new version of the base
+                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+               });
+               // remove the list of existing child constructors from the old constructor
+               // so the old child constructors can be garbage collected
+               delete existingConstructor._childConstructors;
+       } else {
+               base._childConstructors.push( constructor );
+       }
+
+       $.widget.bridge( name, constructor );
+
+       return constructor;
+};
+
+$.widget.extend = function( target ) {
+       var input = widget_slice.call( arguments, 1 ),
+               inputIndex = 0,
+               inputLength = input.length,
+               key,
+               value;
+       for ( ; inputIndex < inputLength; inputIndex++ ) {
+               for ( key in input[ inputIndex ] ) {
+                       value = input[ inputIndex ][ key ];
+                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+                               // Clone objects
+                               if ( $.isPlainObject( value ) ) {
+                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
+                                               $.widget.extend( {}, target[ key ], value ) :
+                                               // Don't extend strings, arrays, etc. with objects
+                                               $.widget.extend( {}, value );
+                               // Copy everything else by reference
+                               } else {
+                                       target[ key ] = value;
+                               }
+                       }
+               }
+       }
+       return target;
+};
+
+$.widget.bridge = function( name, object ) {
+       var fullName = object.prototype.widgetFullName || name;
+       $.fn[ name ] = function( options ) {
+               var isMethodCall = typeof options === "string",
+                       args = widget_slice.call( arguments, 1 ),
+                       returnValue = this;
+
+               if ( isMethodCall ) {
+                       this.each(function() {
+                               var methodValue,
+                                       instance = $.data( this, fullName );
+                               if ( options === "instance" ) {
+                                       returnValue = instance;
+                                       return false;
+                               }
+                               if ( !instance ) {
+                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
+                                               "attempted to call method '" + options + "'" );
+                               }
+                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+                               }
+                               methodValue = instance[ options ].apply( instance, args );
+                               if ( methodValue !== instance && methodValue !== undefined ) {
+                                       returnValue = methodValue && methodValue.jquery ?
+                                               returnValue.pushStack( methodValue.get() ) :
+                                               methodValue;
+                                       return false;
+                               }
+                       });
+               } else {
+
+                       // Allow multiple hashes to be passed on init
+                       if ( args.length ) {
+                               options = $.widget.extend.apply( null, [ options ].concat(args) );
+                       }
+
+                       this.each(function() {
+                               var instance = $.data( this, fullName );
+                               if ( instance ) {
+                                       instance.option( options || {} );
+                                       if ( instance._init ) {
+                                               instance._init();
+                                       }
+                               } else {
+                                       $.data( this, fullName, new object( options, this ) );
+                               }
+                       });
+               }
+
+               return returnValue;
+       };
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+       widgetName: "widget",
+       widgetEventPrefix: "",
+       defaultElement: "<div>",
+       options: {
+               disabled: false,
+
+               // callbacks
+               create: null
+       },
+       _createWidget: function( options, element ) {
+               element = $( element || this.defaultElement || this )[ 0 ];
+               this.element = $( element );
+               this.uuid = widget_uuid++;
+               this.eventNamespace = "." + this.widgetName + this.uuid;
+
+               this.bindings = $();
+               this.hoverable = $();
+               this.focusable = $();
+
+               if ( element !== this ) {
+                       $.data( element, this.widgetFullName, this );
+                       this._on( true, this.element, {
+                               remove: function( event ) {
+                                       if ( event.target === element ) {
+                                               this.destroy();
+                                       }
+                               }
+                       });
+                       this.document = $( element.style ?
+                               // element within the document
+                               element.ownerDocument :
+                               // element is window or document
+                               element.document || element );
+                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+               }
+
+               this.options = $.widget.extend( {},
+                       this.options,
+                       this._getCreateOptions(),
+                       options );
+
+               this._create();
+               this._trigger( "create", null, this._getCreateEventData() );
+               this._init();
+       },
+       _getCreateOptions: $.noop,
+       _getCreateEventData: $.noop,
+       _create: $.noop,
+       _init: $.noop,
+
+       destroy: function() {
+               this._destroy();
+               // we can probably remove the unbind calls in 2.0
+               // all event bindings should go through this._on()
+               this.element
+                       .unbind( this.eventNamespace )
+                       .removeData( this.widgetFullName )
+                       // support: jquery <1.6.3
+                       // http://bugs.jquery.com/ticket/9413
+                       .removeData( $.camelCase( this.widgetFullName ) );
+               this.widget()
+                       .unbind( this.eventNamespace )
+                       .removeAttr( "aria-disabled" )
+                       .removeClass(
+                               this.widgetFullName + "-disabled " +
+                               "ui-state-disabled" );
+
+               // clean up events and states
+               this.bindings.unbind( this.eventNamespace );
+               this.hoverable.removeClass( "ui-state-hover" );
+               this.focusable.removeClass( "ui-state-focus" );
+       },
+       _destroy: $.noop,
+
+       widget: function() {
+               return this.element;
+       },
+
+       option: function( key, value ) {
+               var options = key,
+                       parts,
+                       curOption,
+                       i;
+
+               if ( arguments.length === 0 ) {
+                       // don't return a reference to the internal hash
+                       return $.widget.extend( {}, this.options );
+               }
+
+               if ( typeof key === "string" ) {
+                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+                       options = {};
+                       parts = key.split( "." );
+                       key = parts.shift();
+                       if ( parts.length ) {
+                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+                               for ( i = 0; i < parts.length - 1; i++ ) {
+                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+                                       curOption = curOption[ parts[ i ] ];
+                               }
+                               key = parts.pop();
+                               if ( arguments.length === 1 ) {
+                                       return curOption[ key ] === undefined ? null : curOption[ key ];
+                               }
+                               curOption[ key ] = value;
+                       } else {
+                               if ( arguments.length === 1 ) {
+                                       return this.options[ key ] === undefined ? null : this.options[ key ];
+                               }
+                               options[ key ] = value;
+                       }
+               }
+
+               this._setOptions( options );
+
+               return this;
+       },
+       _setOptions: function( options ) {
+               var key;
+
+               for ( key in options ) {
+                       this._setOption( key, options[ key ] );
+               }
+
+               return this;
+       },
+       _setOption: function( key, value ) {
+               this.options[ key ] = value;
+
+               if ( key === "disabled" ) {
+                       this.widget()
+                               .toggleClass( this.widgetFullName + "-disabled", !!value );
+
+                       // If the widget is becoming disabled, then nothing is interactive
+                       if ( value ) {
+                               this.hoverable.removeClass( "ui-state-hover" );
+                               this.focusable.removeClass( "ui-state-focus" );
+                       }
+               }
+
+               return this;
+       },
+
+       enable: function() {
+               return this._setOptions({ disabled: false });
+       },
+       disable: function() {
+               return this._setOptions({ disabled: true });
+       },
+
+       _on: function( suppressDisabledCheck, element, handlers ) {
+               var delegateElement,
+                       instance = this;
+
+               // no suppressDisabledCheck flag, shuffle arguments
+               if ( typeof suppressDisabledCheck !== "boolean" ) {
+                       handlers = element;
+                       element = suppressDisabledCheck;
+                       suppressDisabledCheck = false;
+               }
+
+               // no element argument, shuffle and use this.element
+               if ( !handlers ) {
+                       handlers = element;
+                       element = this.element;
+                       delegateElement = this.widget();
+               } else {
+                       element = delegateElement = $( element );
+                       this.bindings = this.bindings.add( element );
+               }
+
+               $.each( handlers, function( event, handler ) {
+                       function handlerProxy() {
+                               // allow widgets to customize the disabled handling
+                               // - disabled as an array instead of boolean
+                               // - disabled class as method for disabling individual parts
+                               if ( !suppressDisabledCheck &&
+                                               ( instance.options.disabled === true ||
+                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
+                                       return;
+                               }
+                               return ( typeof handler === "string" ? instance[ handler ] : handler )
+                                       .apply( instance, arguments );
+                       }
+
+                       // copy the guid so direct unbinding works
+                       if ( typeof handler !== "string" ) {
+                               handlerProxy.guid = handler.guid =
+                                       handler.guid || handlerProxy.guid || $.guid++;
+                       }
+
+                       var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
+                               eventName = match[1] + instance.eventNamespace,
+                               selector = match[2];
+                       if ( selector ) {
+                               delegateElement.delegate( selector, eventName, handlerProxy );
+                       } else {
+                               element.bind( eventName, handlerProxy );
+                       }
+               });
+       },
+
+       _off: function( element, eventName ) {
+               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
+                       this.eventNamespace;
+               element.unbind( eventName ).undelegate( eventName );
+
+               // Clear the stack to avoid memory leaks (#10056)
+               this.bindings = $( this.bindings.not( element ).get() );
+               this.focusable = $( this.focusable.not( element ).get() );
+               this.hoverable = $( this.hoverable.not( element ).get() );
+       },
+
+       _delay: function( handler, delay ) {
+               function handlerProxy() {
+                       return ( typeof handler === "string" ? instance[ handler ] : handler )
+                               .apply( instance, arguments );
+               }
+               var instance = this;
+               return setTimeout( handlerProxy, delay || 0 );
+       },
+
+       _hoverable: function( element ) {
+               this.hoverable = this.hoverable.add( element );
+               this._on( element, {
+                       mouseenter: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-hover" );
+                       },
+                       mouseleave: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-hover" );
+                       }
+               });
+       },
+
+       _focusable: function( element ) {
+               this.focusable = this.focusable.add( element );
+               this._on( element, {
+                       focusin: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-focus" );
+                       },
+                       focusout: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-focus" );
+                       }
+               });
+       },
+
+       _trigger: function( type, event, data ) {
+               var prop, orig,
+                       callback = this.options[ type ];
+
+               data = data || {};
+               event = $.Event( event );
+               event.type = ( type === this.widgetEventPrefix ?
+                       type :
+                       this.widgetEventPrefix + type ).toLowerCase();
+               // the original event may come from any element
+               // so we need to reset the target on the new event
+               event.target = this.element[ 0 ];
+
+               // copy original event properties over to the new event
+               orig = event.originalEvent;
+               if ( orig ) {
+                       for ( prop in orig ) {
+                               if ( !( prop in event ) ) {
+                                       event[ prop ] = orig[ prop ];
+                               }
+                       }
+               }
+
+               this.element.trigger( event, data );
+               return !( $.isFunction( callback ) &&
+                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+                       event.isDefaultPrevented() );
+       }
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+               if ( typeof options === "string" ) {
+                       options = { effect: options };
+               }
+               var hasOptions,
+                       effectName = !options ?
+                               method :
+                               options === true || typeof options === "number" ?
+                                       defaultEffect :
+                                       options.effect || defaultEffect;
+               options = options || {};
+               if ( typeof options === "number" ) {
+                       options = { duration: options };
+               }
+               hasOptions = !$.isEmptyObject( options );
+               options.complete = callback;
+               if ( options.delay ) {
+                       element.delay( options.delay );
+               }
+               if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+                       element[ method ]( options );
+               } else if ( effectName !== method && element[ effectName ] ) {
+                       element[ effectName ]( options.duration, options.easing, callback );
+               } else {
+                       element.queue(function( next ) {
+                               $( this )[ method ]();
+                               if ( callback ) {
+                                       callback.call( element[ 0 ] );
+                               }
+                               next();
+                       });
+               }
+       };
+});
+
+var widget = $.widget;
+
+
+/*!
+ * jQuery UI Mouse 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/mouse/
+ */
+
+
+var mouseHandled = false;
+$( document ).mouseup( function() {
+       mouseHandled = false;
+});
+
+var mouse = $.widget("ui.mouse", {
+       version: "1.11.3",
+       options: {
+               cancel: "input,textarea,button,select,option",
+               distance: 1,
+               delay: 0
+       },
+       _mouseInit: function() {
+               var that = this;
+
+               this.element
+                       .bind("mousedown." + this.widgetName, function(event) {
+                               return that._mouseDown(event);
+                       })
+                       .bind("click." + this.widgetName, function(event) {
+                               if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
+                                       $.removeData(event.target, that.widgetName + ".preventClickEvent");
+                                       event.stopImmediatePropagation();
+                                       return false;
+                               }
+                       });
+
+               this.started = false;
+       },
+
+       // TODO: make sure destroying one instance of mouse doesn't mess with
+       // other instances of mouse
+       _mouseDestroy: function() {
+               this.element.unbind("." + this.widgetName);
+               if ( this._mouseMoveDelegate ) {
+                       this.document
+                               .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
+                               .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
+               }
+       },
+
+       _mouseDown: function(event) {
+               // don't let more than one widget handle mouseStart
+               if ( mouseHandled ) {
+                       return;
+               }
+
+               this._mouseMoved = false;
+
+               // we may have missed mouseup (out of window)
+               (this._mouseStarted && this._mouseUp(event));
+
+               this._mouseDownEvent = event;
+
+               var that = this,
+                       btnIsLeft = (event.which === 1),
+                       // event.target.nodeName works around a bug in IE 8 with
+                       // disabled inputs (#7620)
+                       elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+                       return true;
+               }
+
+               this.mouseDelayMet = !this.options.delay;
+               if (!this.mouseDelayMet) {
+                       this._mouseDelayTimer = setTimeout(function() {
+                               that.mouseDelayMet = true;
+                       }, this.options.delay);
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted = (this._mouseStart(event) !== false);
+                       if (!this._mouseStarted) {
+                               event.preventDefault();
+                               return true;
+                       }
+               }
+
+               // Click event may never have fired (Gecko & Opera)
+               if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
+                       $.removeData(event.target, this.widgetName + ".preventClickEvent");
+               }
+
+               // these delegates are required to keep context
+               this._mouseMoveDelegate = function(event) {
+                       return that._mouseMove(event);
+               };
+               this._mouseUpDelegate = function(event) {
+                       return that._mouseUp(event);
+               };
+
+               this.document
+                       .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+                       .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+               event.preventDefault();
+
+               mouseHandled = true;
+               return true;
+       },
+
+       _mouseMove: function(event) {
+               // Only check for mouseups outside the document if you've moved inside the document
+               // at least once. This prevents the firing of mouseup in the case of IE<9, which will
+               // fire a mousemove event if content is placed under the cursor. See #7778
+               // Support: IE <9
+               if ( this._mouseMoved ) {
+                       // IE mouseup check - mouseup happened when mouse was out of window
+                       if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
+                               return this._mouseUp(event);
+
+                       // Iframe mouseup check - mouseup occurred in another document
+                       } else if ( !event.which ) {
+                               return this._mouseUp( event );
+                       }
+               }
+
+               if ( event.which || event.button ) {
+                       this._mouseMoved = true;
+               }
+
+               if (this._mouseStarted) {
+                       this._mouseDrag(event);
+                       return event.preventDefault();
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted =
+                               (this._mouseStart(this._mouseDownEvent, event) !== false);
+                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+               }
+
+               return !this._mouseStarted;
+       },
+
+       _mouseUp: function(event) {
+               this.document
+                       .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+                       .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+               if (this._mouseStarted) {
+                       this._mouseStarted = false;
+
+                       if (event.target === this._mouseDownEvent.target) {
+                               $.data(event.target, this.widgetName + ".preventClickEvent", true);
+                       }
+
+                       this._mouseStop(event);
+               }
+
+               mouseHandled = false;
+               return false;
+       },
+
+       _mouseDistanceMet: function(event) {
+               return (Math.max(
+                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
+                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
+                       ) >= this.options.distance
+               );
+       },
+
+       _mouseDelayMet: function(/* event */) {
+               return this.mouseDelayMet;
+       },
+
+       // These are placeholder methods, to be overriden by extending plugin
+       _mouseStart: function(/* event */) {},
+       _mouseDrag: function(/* event */) {},
+       _mouseStop: function(/* event */) {},
+       _mouseCapture: function(/* event */) { return true; }
+});
+
+
+/*!
+ * jQuery UI Position 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/position/
+ */
+
+(function() {
+
+$.ui = $.ui || {};
+
+var cachedScrollbarWidth, supportsOffsetFractions,
+       max = Math.max,
+       abs = Math.abs,
+       round = Math.round,
+       rhorizontal = /left|center|right/,
+       rvertical = /top|center|bottom/,
+       roffset = /[\+\-]\d+(\.[\d]+)?%?/,
+       rposition = /^\w+/,
+       rpercent = /%$/,
+       _position = $.fn.position;
+
+function getOffsets( offsets, width, height ) {
+       return [
+               parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
+               parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
+       ];
+}
+
+function parseCss( element, property ) {
+       return parseInt( $.css( element, property ), 10 ) || 0;
+}
+
+function getDimensions( elem ) {
+       var raw = elem[0];
+       if ( raw.nodeType === 9 ) {
+               return {
+                       width: elem.width(),
+                       height: elem.height(),
+                       offset: { top: 0, left: 0 }
+               };
+       }
+       if ( $.isWindow( raw ) ) {
+               return {
+                       width: elem.width(),
+                       height: elem.height(),
+                       offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
+               };
+       }
+       if ( raw.preventDefault ) {
+               return {
+                       width: 0,
+                       height: 0,
+                       offset: { top: raw.pageY, left: raw.pageX }
+               };
+       }
+       return {
+               width: elem.outerWidth(),
+               height: elem.outerHeight(),
+               offset: elem.offset()
+       };
+}
+
+$.position = {
+       scrollbarWidth: function() {
+               if ( cachedScrollbarWidth !== undefined ) {
+                       return cachedScrollbarWidth;
+               }
+               var w1, w2,
+                       div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
+                       innerDiv = div.children()[0];
+
+               $( "body" ).append( div );
+               w1 = innerDiv.offsetWidth;
+               div.css( "overflow", "scroll" );
+
+               w2 = innerDiv.offsetWidth;
+
+               if ( w1 === w2 ) {
+                       w2 = div[0].clientWidth;
+               }
+
+               div.remove();
+
+               return (cachedScrollbarWidth = w1 - w2);
+       },
+       getScrollInfo: function( within ) {
+               var overflowX = within.isWindow || within.isDocument ? "" :
+                               within.element.css( "overflow-x" ),
+                       overflowY = within.isWindow || within.isDocument ? "" :
+                               within.element.css( "overflow-y" ),
+                       hasOverflowX = overflowX === "scroll" ||
+                               ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
+                       hasOverflowY = overflowY === "scroll" ||
+                               ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
+               return {
+                       width: hasOverflowY ? $.position.scrollbarWidth() : 0,
+                       height: hasOverflowX ? $.position.scrollbarWidth() : 0
+               };
+       },
+       getWithinInfo: function( element ) {
+               var withinElement = $( element || window ),
+                       isWindow = $.isWindow( withinElement[0] ),
+                       isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
+               return {
+                       element: withinElement,
+                       isWindow: isWindow,
+                       isDocument: isDocument,
+                       offset: withinElement.offset() || { left: 0, top: 0 },
+                       scrollLeft: withinElement.scrollLeft(),
+                       scrollTop: withinElement.scrollTop(),
+
+                       // support: jQuery 1.6.x
+                       // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
+                       width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
+                       height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
+               };
+       }
+};
+
+$.fn.position = function( options ) {
+       if ( !options || !options.of ) {
+               return _position.apply( this, arguments );
+       }
+
+       // make a copy, we don't want to modify arguments
+       options = $.extend( {}, options );
+
+       var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
+               target = $( options.of ),
+               within = $.position.getWithinInfo( options.within ),
+               scrollInfo = $.position.getScrollInfo( within ),
+               collision = ( options.collision || "flip" ).split( " " ),
+               offsets = {};
+
+       dimensions = getDimensions( target );
+       if ( target[0].preventDefault ) {
+               // force left top to allow flipping
+               options.at = "left top";
+       }
+       targetWidth = dimensions.width;
+       targetHeight = dimensions.height;
+       targetOffset = dimensions.offset;
+       // clone to reuse original targetOffset later
+       basePosition = $.extend( {}, targetOffset );
+
+       // force my and at to have valid horizontal and vertical positions
+       // if a value is missing or invalid, it will be converted to center
+       $.each( [ "my", "at" ], function() {
+               var pos = ( options[ this ] || "" ).split( " " ),
+                       horizontalOffset,
+                       verticalOffset;
+
+               if ( pos.length === 1) {
+                       pos = rhorizontal.test( pos[ 0 ] ) ?
+                               pos.concat( [ "center" ] ) :
+                               rvertical.test( pos[ 0 ] ) ?
+                                       [ "center" ].concat( pos ) :
+                                       [ "center", "center" ];
+               }
+               pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
+               pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
+
+               // calculate offsets
+               horizontalOffset = roffset.exec( pos[ 0 ] );
+               verticalOffset = roffset.exec( pos[ 1 ] );
+               offsets[ this ] = [
+                       horizontalOffset ? horizontalOffset[ 0 ] : 0,
+                       verticalOffset ? verticalOffset[ 0 ] : 0
+               ];
+
+               // reduce to just the positions without the offsets
+               options[ this ] = [
+                       rposition.exec( pos[ 0 ] )[ 0 ],
+                       rposition.exec( pos[ 1 ] )[ 0 ]
+               ];
+       });
+
+       // normalize collision option
+       if ( collision.length === 1 ) {
+               collision[ 1 ] = collision[ 0 ];
+       }
+
+       if ( options.at[ 0 ] === "right" ) {
+               basePosition.left += targetWidth;
+       } else if ( options.at[ 0 ] === "center" ) {
+               basePosition.left += targetWidth / 2;
+       }
+
+       if ( options.at[ 1 ] === "bottom" ) {
+               basePosition.top += targetHeight;
+       } else if ( options.at[ 1 ] === "center" ) {
+               basePosition.top += targetHeight / 2;
+       }
+
+       atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
+       basePosition.left += atOffset[ 0 ];
+       basePosition.top += atOffset[ 1 ];
+
+       return this.each(function() {
+               var collisionPosition, using,
+                       elem = $( this ),
+                       elemWidth = elem.outerWidth(),
+                       elemHeight = elem.outerHeight(),
+                       marginLeft = parseCss( this, "marginLeft" ),
+                       marginTop = parseCss( this, "marginTop" ),
+                       collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
+                       collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
+                       position = $.extend( {}, basePosition ),
+                       myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
+
+               if ( options.my[ 0 ] === "right" ) {
+                       position.left -= elemWidth;
+               } else if ( options.my[ 0 ] === "center" ) {
+                       position.left -= elemWidth / 2;
+               }
+
+               if ( options.my[ 1 ] === "bottom" ) {
+                       position.top -= elemHeight;
+               } else if ( options.my[ 1 ] === "center" ) {
+                       position.top -= elemHeight / 2;
+               }
+
+               position.left += myOffset[ 0 ];
+               position.top += myOffset[ 1 ];
+
+               // if the browser doesn't support fractions, then round for consistent results
+               if ( !supportsOffsetFractions ) {
+                       position.left = round( position.left );
+                       position.top = round( position.top );
+               }
+
+               collisionPosition = {
+                       marginLeft: marginLeft,
+                       marginTop: marginTop
+               };
+
+               $.each( [ "left", "top" ], function( i, dir ) {
+                       if ( $.ui.position[ collision[ i ] ] ) {
+                               $.ui.position[ collision[ i ] ][ dir ]( position, {
+                                       targetWidth: targetWidth,
+                                       targetHeight: targetHeight,
+                                       elemWidth: elemWidth,
+                                       elemHeight: elemHeight,
+                                       collisionPosition: collisionPosition,
+                                       collisionWidth: collisionWidth,
+                                       collisionHeight: collisionHeight,
+                                       offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
+                                       my: options.my,
+                                       at: options.at,
+                                       within: within,
+                                       elem: elem
+                               });
+                       }
+               });
+
+               if ( options.using ) {
+                       // adds feedback as second argument to using callback, if present
+                       using = function( props ) {
+                               var left = targetOffset.left - position.left,
+                                       right = left + targetWidth - elemWidth,
+                                       top = targetOffset.top - position.top,
+                                       bottom = top + targetHeight - elemHeight,
+                                       feedback = {
+                                               target: {
+                                                       element: target,
+                                                       left: targetOffset.left,
+                                                       top: targetOffset.top,
+                                                       width: targetWidth,
+                                                       height: targetHeight
+                                               },
+                                               element: {
+                                                       element: elem,
+                                                       left: position.left,
+                                                       top: position.top,
+                                                       width: elemWidth,
+                                                       height: elemHeight
+                                               },
+                                               horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
+                                               vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
+                                       };
+                               if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
+                                       feedback.horizontal = "center";
+                               }
+                               if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
+                                       feedback.vertical = "middle";
+                               }
+                               if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
+                                       feedback.important = "horizontal";
+                               } else {
+                                       feedback.important = "vertical";
+                               }
+                               options.using.call( this, props, feedback );
+                       };
+               }
+
+               elem.offset( $.extend( position, { using: using } ) );
+       });
+};
+
+$.ui.position = {
+       fit: {
+               left: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
+                               outerWidth = within.width,
+                               collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+                               overLeft = withinOffset - collisionPosLeft,
+                               overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
+                               newOverRight;
+
+                       // element is wider than within
+                       if ( data.collisionWidth > outerWidth ) {
+                               // element is initially over the left side of within
+                               if ( overLeft > 0 && overRight <= 0 ) {
+                                       newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
+                                       position.left += overLeft - newOverRight;
+                               // element is initially over right side of within
+                               } else if ( overRight > 0 && overLeft <= 0 ) {
+                                       position.left = withinOffset;
+                               // element is initially over both left and right sides of within
+                               } else {
+                                       if ( overLeft > overRight ) {
+                                               position.left = withinOffset + outerWidth - data.collisionWidth;
+                                       } else {
+                                               position.left = withinOffset;
+                                       }
+                               }
+                       // too far left -> align with left edge
+                       } else if ( overLeft > 0 ) {
+                               position.left += overLeft;
+                       // too far right -> align with right edge
+                       } else if ( overRight > 0 ) {
+                               position.left -= overRight;
+                       // adjust based on position and margin
+                       } else {
+                               position.left = max( position.left - collisionPosLeft, position.left );
+                       }
+               },
+               top: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
+                               outerHeight = data.within.height,
+                               collisionPosTop = position.top - data.collisionPosition.marginTop,
+                               overTop = withinOffset - collisionPosTop,
+                               overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
+                               newOverBottom;
+
+                       // element is taller than within
+                       if ( data.collisionHeight > outerHeight ) {
+                               // element is initially over the top of within
+                               if ( overTop > 0 && overBottom <= 0 ) {
+                                       newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
+                                       position.top += overTop - newOverBottom;
+                               // element is initially over bottom of within
+                               } else if ( overBottom > 0 && overTop <= 0 ) {
+                                       position.top = withinOffset;
+                               // element is initially over both top and bottom of within
+                               } else {
+                                       if ( overTop > overBottom ) {
+                                               position.top = withinOffset + outerHeight - data.collisionHeight;
+                                       } else {
+                                               position.top = withinOffset;
+                                       }
+                               }
+                       // too far up -> align with top
+                       } else if ( overTop > 0 ) {
+                               position.top += overTop;
+                       // too far down -> align with bottom edge
+                       } else if ( overBottom > 0 ) {
+                               position.top -= overBottom;
+                       // adjust based on position and margin
+                       } else {
+                               position.top = max( position.top - collisionPosTop, position.top );
+                       }
+               }
+       },
+       flip: {
+               left: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.offset.left + within.scrollLeft,
+                               outerWidth = within.width,
+                               offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
+                               collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+                               overLeft = collisionPosLeft - offsetLeft,
+                               overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
+                               myOffset = data.my[ 0 ] === "left" ?
+                                       -data.elemWidth :
+                                       data.my[ 0 ] === "right" ?
+                                               data.elemWidth :
+                                               0,
+                               atOffset = data.at[ 0 ] === "left" ?
+                                       data.targetWidth :
+                                       data.at[ 0 ] === "right" ?
+                                               -data.targetWidth :
+                                               0,
+                               offset = -2 * data.offset[ 0 ],
+                               newOverRight,
+                               newOverLeft;
+
+                       if ( overLeft < 0 ) {
+                               newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
+                               if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
+                                       position.left += myOffset + atOffset + offset;
+                               }
+                       } else if ( overRight > 0 ) {
+                               newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
+                               if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
+                                       position.left += myOffset + atOffset + offset;
+                               }
+                       }
+               },
+               top: function( position, data ) {
+                       var within = data.within,
+                               withinOffset = within.offset.top + within.scrollTop,
+                               outerHeight = within.height,
+                               offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
+                               collisionPosTop = position.top - data.collisionPosition.marginTop,
+                               overTop = collisionPosTop - offsetTop,
+                               overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
+                               top = data.my[ 1 ] === "top",
+                               myOffset = top ?
+                                       -data.elemHeight :
+                                       data.my[ 1 ] === "bottom" ?
+                                               data.elemHeight :
+                                               0,
+                               atOffset = data.at[ 1 ] === "top" ?
+                                       data.targetHeight :
+                                       data.at[ 1 ] === "bottom" ?
+                                               -data.targetHeight :
+                                               0,
+                               offset = -2 * data.offset[ 1 ],
+                               newOverTop,
+                               newOverBottom;
+                       if ( overTop < 0 ) {
+                               newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
+                               if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
+                                       position.top += myOffset + atOffset + offset;
+                               }
+                       } else if ( overBottom > 0 ) {
+                               newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
+                               if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
+                                       position.top += myOffset + atOffset + offset;
+                               }
+                       }
+               }
+       },
+       flipfit: {
+               left: function() {
+                       $.ui.position.flip.left.apply( this, arguments );
+                       $.ui.position.fit.left.apply( this, arguments );
+               },
+               top: function() {
+                       $.ui.position.flip.top.apply( this, arguments );
+                       $.ui.position.fit.top.apply( this, arguments );
+               }
+       }
+};
+
+// fraction support test
+(function() {
+       var testElement, testElementParent, testElementStyle, offsetLeft, i,
+               body = document.getElementsByTagName( "body" )[ 0 ],
+               div = document.createElement( "div" );
+
+       //Create a "fake body" for testing based on method used in jQuery.support
+       testElement = document.createElement( body ? "div" : "body" );
+       testElementStyle = {
+               visibility: "hidden",
+               width: 0,
+               height: 0,
+               border: 0,
+               margin: 0,
+               background: "none"
+       };
+       if ( body ) {
+               $.extend( testElementStyle, {
+                       position: "absolute",
+                       left: "-1000px",
+                       top: "-1000px"
+               });
+       }
+       for ( i in testElementStyle ) {
+               testElement.style[ i ] = testElementStyle[ i ];
+       }
+       testElement.appendChild( div );
+       testElementParent = body || document.documentElement;
+       testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+       div.style.cssText = "position: absolute; left: 10.7432222px;";
+
+       offsetLeft = $( div ).offset().left;
+       supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
+
+       testElement.innerHTML = "";
+       testElementParent.removeChild( testElement );
+})();
+
+})();
+
+var position = $.ui.position;
+
+
+/*!
+ * jQuery UI Accordion 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/accordion/
+ */
+
+
+var accordion = $.widget( "ui.accordion", {
+       version: "1.11.3",
+       options: {
+               active: 0,
+               animate: {},
+               collapsible: false,
+               event: "click",
+               header: "> li > :first-child,> :not(li):even",
+               heightStyle: "auto",
+               icons: {
+                       activeHeader: "ui-icon-triangle-1-s",
+                       header: "ui-icon-triangle-1-e"
+               },
+
+               // callbacks
+               activate: null,
+               beforeActivate: null
+       },
+
+       hideProps: {
+               borderTopWidth: "hide",
+               borderBottomWidth: "hide",
+               paddingTop: "hide",
+               paddingBottom: "hide",
+               height: "hide"
+       },
+
+       showProps: {
+               borderTopWidth: "show",
+               borderBottomWidth: "show",
+               paddingTop: "show",
+               paddingBottom: "show",
+               height: "show"
+       },
+
+       _create: function() {
+               var options = this.options;
+               this.prevShow = this.prevHide = $();
+               this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
+                       // ARIA
+                       .attr( "role", "tablist" );
+
+               // don't allow collapsible: false and active: false / null
+               if ( !options.collapsible && (options.active === false || options.active == null) ) {
+                       options.active = 0;
+               }
+
+               this._processPanels();
+               // handle negative values
+               if ( options.active < 0 ) {
+                       options.active += this.headers.length;
+               }
+               this._refresh();
+       },
+
+       _getCreateEventData: function() {
+               return {
+                       header: this.active,
+                       panel: !this.active.length ? $() : this.active.next()
+               };
+       },
+
+       _createIcons: function() {
+               var icons = this.options.icons;
+               if ( icons ) {
+                       $( "<span>" )
+                               .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
+                               .prependTo( this.headers );
+                       this.active.children( ".ui-accordion-header-icon" )
+                               .removeClass( icons.header )
+                               .addClass( icons.activeHeader );
+                       this.headers.addClass( "ui-accordion-icons" );
+               }
+       },
+
+       _destroyIcons: function() {
+               this.headers
+                       .removeClass( "ui-accordion-icons" )
+                       .children( ".ui-accordion-header-icon" )
+                               .remove();
+       },
+
+       _destroy: function() {
+               var contents;
+
+               // clean up main element
+               this.element
+                       .removeClass( "ui-accordion ui-widget ui-helper-reset" )
+                       .removeAttr( "role" );
+
+               // clean up headers
+               this.headers
+                       .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
+                               "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-expanded" )
+                       .removeAttr( "aria-selected" )
+                       .removeAttr( "aria-controls" )
+                       .removeAttr( "tabIndex" )
+                       .removeUniqueId();
+
+               this._destroyIcons();
+
+               // clean up content panels
+               contents = this.headers.next()
+                       .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
+                               "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
+                       .css( "display", "" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-hidden" )
+                       .removeAttr( "aria-labelledby" )
+                       .removeUniqueId();
+
+               if ( this.options.heightStyle !== "content" ) {
+                       contents.css( "height", "" );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "active" ) {
+                       // _activate() will handle invalid values and update this.options
+                       this._activate( value );
+                       return;
+               }
+
+               if ( key === "event" ) {
+                       if ( this.options.event ) {
+                               this._off( this.headers, this.options.event );
+                       }
+                       this._setupEvents( value );
+               }
+
+               this._super( key, value );
+
+               // setting collapsible: false while collapsed; open first panel
+               if ( key === "collapsible" && !value && this.options.active === false ) {
+                       this._activate( 0 );
+               }
+
+               if ( key === "icons" ) {
+                       this._destroyIcons();
+                       if ( value ) {
+                               this._createIcons();
+                       }
+               }
+
+               // #5332 - opacity doesn't cascade to positioned elements in IE
+               // so we need to add the disabled class to the headers and panels
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+                       this.headers.add( this.headers.next() )
+                               .toggleClass( "ui-state-disabled", !!value );
+               }
+       },
+
+       _keydown: function( event ) {
+               if ( event.altKey || event.ctrlKey ) {
+                       return;
+               }
+
+               var keyCode = $.ui.keyCode,
+                       length = this.headers.length,
+                       currentIndex = this.headers.index( event.target ),
+                       toFocus = false;
+
+               switch ( event.keyCode ) {
+                       case keyCode.RIGHT:
+                       case keyCode.DOWN:
+                               toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+                               break;
+                       case keyCode.LEFT:
+                       case keyCode.UP:
+                               toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+                               break;
+                       case keyCode.SPACE:
+                       case keyCode.ENTER:
+                               this._eventHandler( event );
+                               break;
+                       case keyCode.HOME:
+                               toFocus = this.headers[ 0 ];
+                               break;
+                       case keyCode.END:
+                               toFocus = this.headers[ length - 1 ];
+                               break;
+               }
+
+               if ( toFocus ) {
+                       $( event.target ).attr( "tabIndex", -1 );
+                       $( toFocus ).attr( "tabIndex", 0 );
+                       toFocus.focus();
+                       event.preventDefault();
+               }
+       },
+
+       _panelKeyDown: function( event ) {
+               if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
+                       $( event.currentTarget ).prev().focus();
+               }
+       },
+
+       refresh: function() {
+               var options = this.options;
+               this._processPanels();
+
+               // was collapsed or no panel
+               if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
+                       options.active = false;
+                       this.active = $();
+               // active false only when collapsible is true
+               } else if ( options.active === false ) {
+                       this._activate( 0 );
+               // was active, but active panel is gone
+               } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+                       // all remaining panel are disabled
+                       if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
+                               options.active = false;
+                               this.active = $();
+                       // activate previous panel
+                       } else {
+                               this._activate( Math.max( 0, options.active - 1 ) );
+                       }
+               // was active, active panel still exists
+               } else {
+                       // make sure active index is correct
+                       options.active = this.headers.index( this.active );
+               }
+
+               this._destroyIcons();
+
+               this._refresh();
+       },
+
+       _processPanels: function() {
+               var prevHeaders = this.headers,
+                       prevPanels = this.panels;
+
+               this.headers = this.element.find( this.options.header )
+                       .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
+
+               this.panels = this.headers.next()
+                       .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
+                       .filter( ":not(.ui-accordion-content-active)" )
+                       .hide();
+
+               // Avoid memory leaks (#10056)
+               if ( prevPanels ) {
+                       this._off( prevHeaders.not( this.headers ) );
+                       this._off( prevPanels.not( this.panels ) );
+               }
+       },
+
+       _refresh: function() {
+               var maxHeight,
+                       options = this.options,
+                       heightStyle = options.heightStyle,
+                       parent = this.element.parent();
+
+               this.active = this._findActive( options.active )
+                       .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
+                       .removeClass( "ui-corner-all" );
+               this.active.next()
+                       .addClass( "ui-accordion-content-active" )
+                       .show();
+
+               this.headers
+                       .attr( "role", "tab" )
+                       .each(function() {
+                               var header = $( this ),
+                                       headerId = header.uniqueId().attr( "id" ),
+                                       panel = header.next(),
+                                       panelId = panel.uniqueId().attr( "id" );
+                               header.attr( "aria-controls", panelId );
+                               panel.attr( "aria-labelledby", headerId );
+                       })
+                       .next()
+                               .attr( "role", "tabpanel" );
+
+               this.headers
+                       .not( this.active )
+                       .attr({
+                               "aria-selected": "false",
+                               "aria-expanded": "false",
+                               tabIndex: -1
+                       })
+                       .next()
+                               .attr({
+                                       "aria-hidden": "true"
+                               })
+                               .hide();
+
+               // make sure at least one header is in the tab order
+               if ( !this.active.length ) {
+                       this.headers.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       this.active.attr({
+                               "aria-selected": "true",
+                               "aria-expanded": "true",
+                               tabIndex: 0
+                       })
+                       .next()
+                               .attr({
+                                       "aria-hidden": "false"
+                               });
+               }
+
+               this._createIcons();
+
+               this._setupEvents( options.event );
+
+               if ( heightStyle === "fill" ) {
+                       maxHeight = parent.height();
+                       this.element.siblings( ":visible" ).each(function() {
+                               var elem = $( this ),
+                                       position = elem.css( "position" );
+
+                               if ( position === "absolute" || position === "fixed" ) {
+                                       return;
+                               }
+                               maxHeight -= elem.outerHeight( true );
+                       });
+
+                       this.headers.each(function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       });
+
+                       this.headers.next()
+                               .each(function() {
+                                       $( this ).height( Math.max( 0, maxHeight -
+                                               $( this ).innerHeight() + $( this ).height() ) );
+                               })
+                               .css( "overflow", "auto" );
+               } else if ( heightStyle === "auto" ) {
+                       maxHeight = 0;
+                       this.headers.next()
+                               .each(function() {
+                                       maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
+                               })
+                               .height( maxHeight );
+               }
+       },
+
+       _activate: function( index ) {
+               var active = this._findActive( index )[ 0 ];
+
+               // trying to activate the already active panel
+               if ( active === this.active[ 0 ] ) {
+                       return;
+               }
+
+               // trying to collapse, simulate a click on the currently active header
+               active = active || this.active[ 0 ];
+
+               this._eventHandler({
+                       target: active,
+                       currentTarget: active,
+                       preventDefault: $.noop
+               });
+       },
+
+       _findActive: function( selector ) {
+               return typeof selector === "number" ? this.headers.eq( selector ) : $();
+       },
+
+       _setupEvents: function( event ) {
+               var events = {
+                       keydown: "_keydown"
+               };
+               if ( event ) {
+                       $.each( event.split( " " ), function( index, eventName ) {
+                               events[ eventName ] = "_eventHandler";
+                       });
+               }
+
+               this._off( this.headers.add( this.headers.next() ) );
+               this._on( this.headers, events );
+               this._on( this.headers.next(), { keydown: "_panelKeyDown" });
+               this._hoverable( this.headers );
+               this._focusable( this.headers );
+       },
+
+       _eventHandler: function( event ) {
+               var options = this.options,
+                       active = this.active,
+                       clicked = $( event.currentTarget ),
+                       clickedIsActive = clicked[ 0 ] === active[ 0 ],
+                       collapsing = clickedIsActive && options.collapsible,
+                       toShow = collapsing ? $() : clicked.next(),
+                       toHide = active.next(),
+                       eventData = {
+                               oldHeader: active,
+                               oldPanel: toHide,
+                               newHeader: collapsing ? $() : clicked,
+                               newPanel: toShow
+                       };
+
+               event.preventDefault();
+
+               if (
+                               // click on active header, but not collapsible
+                               ( clickedIsActive && !options.collapsible ) ||
+                               // allow canceling activation
+                               ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+                       return;
+               }
+
+               options.active = collapsing ? false : this.headers.index( clicked );
+
+               // when the call to ._toggle() comes after the class changes
+               // it causes a very odd bug in IE 8 (see #6720)
+               this.active = clickedIsActive ? $() : clicked;
+               this._toggle( eventData );
+
+               // switch classes
+               // corner classes on the previously active header stay after the animation
+               active.removeClass( "ui-accordion-header-active ui-state-active" );
+               if ( options.icons ) {
+                       active.children( ".ui-accordion-header-icon" )
+                               .removeClass( options.icons.activeHeader )
+                               .addClass( options.icons.header );
+               }
+
+               if ( !clickedIsActive ) {
+                       clicked
+                               .removeClass( "ui-corner-all" )
+                               .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
+                       if ( options.icons ) {
+                               clicked.children( ".ui-accordion-header-icon" )
+                                       .removeClass( options.icons.header )
+                                       .addClass( options.icons.activeHeader );
+                       }
+
+                       clicked
+                               .next()
+                               .addClass( "ui-accordion-content-active" );
+               }
+       },
+
+       _toggle: function( data ) {
+               var toShow = data.newPanel,
+                       toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
+
+               // handle activating a panel during the animation for another activation
+               this.prevShow.add( this.prevHide ).stop( true, true );
+               this.prevShow = toShow;
+               this.prevHide = toHide;
+
+               if ( this.options.animate ) {
+                       this._animate( toShow, toHide, data );
+               } else {
+                       toHide.hide();
+                       toShow.show();
+                       this._toggleComplete( data );
+               }
+
+               toHide.attr({
+                       "aria-hidden": "true"
+               });
+               toHide.prev().attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false"
+               });
+               // if we're switching panels, remove the old header from the tab order
+               // if we're opening from collapsed state, remove the previous header from the tab order
+               // if we're collapsing, then keep the collapsing header in the tab order
+               if ( toShow.length && toHide.length ) {
+                       toHide.prev().attr({
+                               "tabIndex": -1,
+                               "aria-expanded": "false"
+                       });
+               } else if ( toShow.length ) {
+                       this.headers.filter(function() {
+                               return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
+                       })
+                       .attr( "tabIndex", -1 );
+               }
+
+               toShow
+                       .attr( "aria-hidden", "false" )
+                       .prev()
+                               .attr({
+                                       "aria-selected": "true",
+                                       "aria-expanded": "true",
+                                       tabIndex: 0
+                               });
+       },
+
+       _animate: function( toShow, toHide, data ) {
+               var total, easing, duration,
+                       that = this,
+                       adjust = 0,
+                       down = toShow.length &&
+                               ( !toHide.length || ( toShow.index() < toHide.index() ) ),
+                       animate = this.options.animate || {},
+                       options = down && animate.down || animate,
+                       complete = function() {
+                               that._toggleComplete( data );
+                       };
+
+               if ( typeof options === "number" ) {
+                       duration = options;
+               }
+               if ( typeof options === "string" ) {
+                       easing = options;
+               }
+               // fall back from options to animation in case of partial down settings
+               easing = easing || options.easing || animate.easing;
+               duration = duration || options.duration || animate.duration;
+
+               if ( !toHide.length ) {
+                       return toShow.animate( this.showProps, duration, easing, complete );
+               }
+               if ( !toShow.length ) {
+                       return toHide.animate( this.hideProps, duration, easing, complete );
+               }
+
+               total = toShow.show().outerHeight();
+               toHide.animate( this.hideProps, {
+                       duration: duration,
+                       easing: easing,
+                       step: function( now, fx ) {
+                               fx.now = Math.round( now );
+                       }
+               });
+               toShow
+                       .hide()
+                       .animate( this.showProps, {
+                               duration: duration,
+                               easing: easing,
+                               complete: complete,
+                               step: function( now, fx ) {
+                                       fx.now = Math.round( now );
+                                       if ( fx.prop !== "height" ) {
+                                               adjust += fx.now;
+                                       } else if ( that.options.heightStyle !== "content" ) {
+                                               fx.now = Math.round( total - toHide.outerHeight() - adjust );
+                                               adjust = 0;
+                                       }
+                               }
+                       });
+       },
+
+       _toggleComplete: function( data ) {
+               var toHide = data.oldPanel;
+
+               toHide
+                       .removeClass( "ui-accordion-content-active" )
+                       .prev()
+                               .removeClass( "ui-corner-top" )
+                               .addClass( "ui-corner-all" );
+
+               // Work around for rendering bug in IE (#5421)
+               if ( toHide.length ) {
+                       toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
+               }
+               this._trigger( "activate", null, data );
+       }
+});
+
+
+/*!
+ * jQuery UI Menu 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/menu/
+ */
+
+
+var menu = $.widget( "ui.menu", {
+       version: "1.11.3",
+       defaultElement: "<ul>",
+       delay: 300,
+       options: {
+               icons: {
+                       submenu: "ui-icon-carat-1-e"
+               },
+               items: "> *",
+               menus: "ul",
+               position: {
+                       my: "left-1 top",
+                       at: "right top"
+               },
+               role: "menu",
+
+               // callbacks
+               blur: null,
+               focus: null,
+               select: null
+       },
+
+       _create: function() {
+               this.activeMenu = this.element;
+
+               // Flag used to prevent firing of the click handler
+               // as the event bubbles up through nested menus
+               this.mouseHandled = false;
+               this.element
+                       .uniqueId()
+                       .addClass( "ui-menu ui-widget ui-widget-content" )
+                       .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
+                       .attr({
+                               role: this.options.role,
+                               tabIndex: 0
+                       });
+
+               if ( this.options.disabled ) {
+                       this.element
+                               .addClass( "ui-state-disabled" )
+                               .attr( "aria-disabled", "true" );
+               }
+
+               this._on({
+                       // Prevent focus from sticking to links inside menu after clicking
+                       // them (focus should always stay on UL during navigation).
+                       "mousedown .ui-menu-item": function( event ) {
+                               event.preventDefault();
+                       },
+                       "click .ui-menu-item": function( event ) {
+                               var target = $( event.target );
+                               if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
+                                       this.select( event );
+
+                                       // Only set the mouseHandled flag if the event will bubble, see #9469.
+                                       if ( !event.isPropagationStopped() ) {
+                                               this.mouseHandled = true;
+                                       }
+
+                                       // Open submenu on click
+                                       if ( target.has( ".ui-menu" ).length ) {
+                                               this.expand( event );
+                                       } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
+
+                                               // Redirect focus to the menu
+                                               this.element.trigger( "focus", [ true ] );
+
+                                               // If the active item is on the top level, let it stay active.
+                                               // Otherwise, blur the active item since it is no longer visible.
+                                               if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
+                                                       clearTimeout( this.timer );
+                                               }
+                                       }
+                               }
+                       },
+                       "mouseenter .ui-menu-item": function( event ) {
+                               // Ignore mouse events while typeahead is active, see #10458.
+                               // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
+                               // is over an item in the menu
+                               if ( this.previousFilter ) {
+                                       return;
+                               }
+                               var target = $( event.currentTarget );
+                               // Remove ui-state-active class from siblings of the newly focused menu item
+                               // to avoid a jump caused by adjacent elements both having a class with a border
+                               target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
+                               this.focus( event, target );
+                       },
+                       mouseleave: "collapseAll",
+                       "mouseleave .ui-menu": "collapseAll",
+                       focus: function( event, keepActiveItem ) {
+                               // If there's already an active item, keep it active
+                               // If not, activate the first item
+                               var item = this.active || this.element.find( this.options.items ).eq( 0 );
+
+                               if ( !keepActiveItem ) {
+                                       this.focus( event, item );
+                               }
+                       },
+                       blur: function( event ) {
+                               this._delay(function() {
+                                       if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
+                                               this.collapseAll( event );
+                                       }
+                               });
+                       },
+                       keydown: "_keydown"
+               });
+
+               this.refresh();
+
+               // Clicks outside of a menu collapse any open menus
+               this._on( this.document, {
+                       click: function( event ) {
+                               if ( this._closeOnDocumentClick( event ) ) {
+                                       this.collapseAll( event );
+                               }
+
+                               // Reset the mouseHandled flag
+                               this.mouseHandled = false;
+                       }
+               });
+       },
+
+       _destroy: function() {
+               // Destroy (sub)menus
+               this.element
+                       .removeAttr( "aria-activedescendant" )
+                       .find( ".ui-menu" ).addBack()
+                               .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
+                               .removeAttr( "role" )
+                               .removeAttr( "tabIndex" )
+                               .removeAttr( "aria-labelledby" )
+                               .removeAttr( "aria-expanded" )
+                               .removeAttr( "aria-hidden" )
+                               .removeAttr( "aria-disabled" )
+                               .removeUniqueId()
+                               .show();
+
+               // Destroy menu items
+               this.element.find( ".ui-menu-item" )
+                       .removeClass( "ui-menu-item" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-disabled" )
+                       .removeUniqueId()
+                       .removeClass( "ui-state-hover" )
+                       .removeAttr( "tabIndex" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-haspopup" )
+                       .children().each( function() {
+                               var elem = $( this );
+                               if ( elem.data( "ui-menu-submenu-carat" ) ) {
+                                       elem.remove();
+                               }
+                       });
+
+               // Destroy menu dividers
+               this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
+       },
+
+       _keydown: function( event ) {
+               var match, prev, character, skip,
+                       preventDefault = true;
+
+               switch ( event.keyCode ) {
+               case $.ui.keyCode.PAGE_UP:
+                       this.previousPage( event );
+                       break;
+               case $.ui.keyCode.PAGE_DOWN:
+                       this.nextPage( event );
+                       break;
+               case $.ui.keyCode.HOME:
+                       this._move( "first", "first", event );
+                       break;
+               case $.ui.keyCode.END:
+                       this._move( "last", "last", event );
+                       break;
+               case $.ui.keyCode.UP:
+                       this.previous( event );
+                       break;
+               case $.ui.keyCode.DOWN:
+                       this.next( event );
+                       break;
+               case $.ui.keyCode.LEFT:
+                       this.collapse( event );
+                       break;
+               case $.ui.keyCode.RIGHT:
+                       if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
+                               this.expand( event );
+                       }
+                       break;
+               case $.ui.keyCode.ENTER:
+               case $.ui.keyCode.SPACE:
+                       this._activate( event );
+                       break;
+               case $.ui.keyCode.ESCAPE:
+                       this.collapse( event );
+                       break;
+               default:
+                       preventDefault = false;
+                       prev = this.previousFilter || "";
+                       character = String.fromCharCode( event.keyCode );
+                       skip = false;
+
+                       clearTimeout( this.filterTimer );
+
+                       if ( character === prev ) {
+                               skip = true;
+                       } else {
+                               character = prev + character;
+                       }
+
+                       match = this._filterMenuItems( character );
+                       match = skip && match.index( this.active.next() ) !== -1 ?
+                               this.active.nextAll( ".ui-menu-item" ) :
+                               match;
+
+                       // If no matches on the current filter, reset to the last character pressed
+                       // to move down the menu to the first item that starts with that character
+                       if ( !match.length ) {
+                               character = String.fromCharCode( event.keyCode );
+                               match = this._filterMenuItems( character );
+                       }
+
+                       if ( match.length ) {
+                               this.focus( event, match );
+                               this.previousFilter = character;
+                               this.filterTimer = this._delay(function() {
+                                       delete this.previousFilter;
+                               }, 1000 );
+                       } else {
+                               delete this.previousFilter;
+                       }
+               }
+
+               if ( preventDefault ) {
+                       event.preventDefault();
+               }
+       },
+
+       _activate: function( event ) {
+               if ( !this.active.is( ".ui-state-disabled" ) ) {
+                       if ( this.active.is( "[aria-haspopup='true']" ) ) {
+                               this.expand( event );
+                       } else {
+                               this.select( event );
+                       }
+               }
+       },
+
+       refresh: function() {
+               var menus, items,
+                       that = this,
+                       icon = this.options.icons.submenu,
+                       submenus = this.element.find( this.options.menus );
+
+               this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
+
+               // Initialize nested menus
+               submenus.filter( ":not(.ui-menu)" )
+                       .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
+                       .hide()
+                       .attr({
+                               role: this.options.role,
+                               "aria-hidden": "true",
+                               "aria-expanded": "false"
+                       })
+                       .each(function() {
+                               var menu = $( this ),
+                                       item = menu.parent(),
+                                       submenuCarat = $( "<span>" )
+                                               .addClass( "ui-menu-icon ui-icon " + icon )
+                                               .data( "ui-menu-submenu-carat", true );
+
+                               item
+                                       .attr( "aria-haspopup", "true" )
+                                       .prepend( submenuCarat );
+                               menu.attr( "aria-labelledby", item.attr( "id" ) );
+                       });
+
+               menus = submenus.add( this.element );
+               items = menus.find( this.options.items );
+
+               // Initialize menu-items containing spaces and/or dashes only as dividers
+               items.not( ".ui-menu-item" ).each(function() {
+                       var item = $( this );
+                       if ( that._isDivider( item ) ) {
+                               item.addClass( "ui-widget-content ui-menu-divider" );
+                       }
+               });
+
+               // Don't refresh list items that are already adapted
+               items.not( ".ui-menu-item, .ui-menu-divider" )
+                       .addClass( "ui-menu-item" )
+                       .uniqueId()
+                       .attr({
+                               tabIndex: -1,
+                               role: this._itemRole()
+                       });
+
+               // Add aria-disabled attribute to any disabled menu item
+               items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
+
+               // If the active item has been removed, blur the menu
+               if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+                       this.blur();
+               }
+       },
+
+       _itemRole: function() {
+               return {
+                       menu: "menuitem",
+                       listbox: "option"
+               }[ this.options.role ];
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "icons" ) {
+                       this.element.find( ".ui-menu-icon" )
+                               .removeClass( this.options.icons.submenu )
+                               .addClass( value.submenu );
+               }
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+               }
+               this._super( key, value );
+       },
+
+       focus: function( event, item ) {
+               var nested, focused;
+               this.blur( event, event && event.type === "focus" );
+
+               this._scrollIntoView( item );
+
+               this.active = item.first();
+               focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
+               // Only update aria-activedescendant if there's a role
+               // otherwise we assume focus is managed elsewhere
+               if ( this.options.role ) {
+                       this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
+               }
+
+               // Highlight active parent menu item, if any
+               this.active
+                       .parent()
+                       .closest( ".ui-menu-item" )
+                       .addClass( "ui-state-active" );
+
+               if ( event && event.type === "keydown" ) {
+                       this._close();
+               } else {
+                       this.timer = this._delay(function() {
+                               this._close();
+                       }, this.delay );
+               }
+
+               nested = item.children( ".ui-menu" );
+               if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
+                       this._startOpening(nested);
+               }
+               this.activeMenu = item.parent();
+
+               this._trigger( "focus", event, { item: item } );
+       },
+
+       _scrollIntoView: function( item ) {
+               var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
+               if ( this._hasScroll() ) {
+                       borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
+                       paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
+                       offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
+                       scroll = this.activeMenu.scrollTop();
+                       elementHeight = this.activeMenu.height();
+                       itemHeight = item.outerHeight();
+
+                       if ( offset < 0 ) {
+                               this.activeMenu.scrollTop( scroll + offset );
+                       } else if ( offset + itemHeight > elementHeight ) {
+                               this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
+                       }
+               }
+       },
+
+       blur: function( event, fromFocus ) {
+               if ( !fromFocus ) {
+                       clearTimeout( this.timer );
+               }
+
+               if ( !this.active ) {
+                       return;
+               }
+
+               this.active.removeClass( "ui-state-focus" );
+               this.active = null;
+
+               this._trigger( "blur", event, { item: this.active } );
+       },
+
+       _startOpening: function( submenu ) {
+               clearTimeout( this.timer );
+
+               // Don't open if already open fixes a Firefox bug that caused a .5 pixel
+               // shift in the submenu position when mousing over the carat icon
+               if ( submenu.attr( "aria-hidden" ) !== "true" ) {
+                       return;
+               }
+
+               this.timer = this._delay(function() {
+                       this._close();
+                       this._open( submenu );
+               }, this.delay );
+       },
+
+       _open: function( submenu ) {
+               var position = $.extend({
+                       of: this.active
+               }, this.options.position );
+
+               clearTimeout( this.timer );
+               this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
+                       .hide()
+                       .attr( "aria-hidden", "true" );
+
+               submenu
+                       .show()
+                       .removeAttr( "aria-hidden" )
+                       .attr( "aria-expanded", "true" )
+                       .position( position );
+       },
+
+       collapseAll: function( event, all ) {
+               clearTimeout( this.timer );
+               this.timer = this._delay(function() {
+                       // If we were passed an event, look for the submenu that contains the event
+                       var currentMenu = all ? this.element :
+                               $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
+
+                       // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
+                       if ( !currentMenu.length ) {
+                               currentMenu = this.element;
+                       }
+
+                       this._close( currentMenu );
+
+                       this.blur( event );
+                       this.activeMenu = currentMenu;
+               }, this.delay );
+       },
+
+       // With no arguments, closes the currently active menu - if nothing is active
+       // it closes all menus.  If passed an argument, it will search for menus BELOW
+       _close: function( startMenu ) {
+               if ( !startMenu ) {
+                       startMenu = this.active ? this.active.parent() : this.element;
+               }
+
+               startMenu
+                       .find( ".ui-menu" )
+                               .hide()
+                               .attr( "aria-hidden", "true" )
+                               .attr( "aria-expanded", "false" )
+                       .end()
+                       .find( ".ui-state-active" ).not( ".ui-state-focus" )
+                               .removeClass( "ui-state-active" );
+       },
+
+       _closeOnDocumentClick: function( event ) {
+               return !$( event.target ).closest( ".ui-menu" ).length;
+       },
+
+       _isDivider: function( item ) {
+
+               // Match hyphen, em dash, en dash
+               return !/[^\-\u2014\u2013\s]/.test( item.text() );
+       },
+
+       collapse: function( event ) {
+               var newItem = this.active &&
+                       this.active.parent().closest( ".ui-menu-item", this.element );
+               if ( newItem && newItem.length ) {
+                       this._close();
+                       this.focus( event, newItem );
+               }
+       },
+
+       expand: function( event ) {
+               var newItem = this.active &&
+                       this.active
+                               .children( ".ui-menu " )
+                               .find( this.options.items )
+                               .first();
+
+               if ( newItem && newItem.length ) {
+                       this._open( newItem.parent() );
+
+                       // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
+                       this._delay(function() {
+                               this.focus( event, newItem );
+                       });
+               }
+       },
+
+       next: function( event ) {
+               this._move( "next", "first", event );
+       },
+
+       previous: function( event ) {
+               this._move( "prev", "last", event );
+       },
+
+       isFirstItem: function() {
+               return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
+       },
+
+       isLastItem: function() {
+               return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
+       },
+
+       _move: function( direction, filter, event ) {
+               var next;
+               if ( this.active ) {
+                       if ( direction === "first" || direction === "last" ) {
+                               next = this.active
+                                       [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
+                                       .eq( -1 );
+                       } else {
+                               next = this.active
+                                       [ direction + "All" ]( ".ui-menu-item" )
+                                       .eq( 0 );
+                       }
+               }
+               if ( !next || !next.length || !this.active ) {
+                       next = this.activeMenu.find( this.options.items )[ filter ]();
+               }
+
+               this.focus( event, next );
+       },
+
+       nextPage: function( event ) {
+               var item, base, height;
+
+               if ( !this.active ) {
+                       this.next( event );
+                       return;
+               }
+               if ( this.isLastItem() ) {
+                       return;
+               }
+               if ( this._hasScroll() ) {
+                       base = this.active.offset().top;
+                       height = this.element.height();
+                       this.active.nextAll( ".ui-menu-item" ).each(function() {
+                               item = $( this );
+                               return item.offset().top - base - height < 0;
+                       });
+
+                       this.focus( event, item );
+               } else {
+                       this.focus( event, this.activeMenu.find( this.options.items )
+                               [ !this.active ? "first" : "last" ]() );
+               }
+       },
+
+       previousPage: function( event ) {
+               var item, base, height;
+               if ( !this.active ) {
+                       this.next( event );
+                       return;
+               }
+               if ( this.isFirstItem() ) {
+                       return;
+               }
+               if ( this._hasScroll() ) {
+                       base = this.active.offset().top;
+                       height = this.element.height();
+                       this.active.prevAll( ".ui-menu-item" ).each(function() {
+                               item = $( this );
+                               return item.offset().top - base + height > 0;
+                       });
+
+                       this.focus( event, item );
+               } else {
+                       this.focus( event, this.activeMenu.find( this.options.items ).first() );
+               }
+       },
+
+       _hasScroll: function() {
+               return this.element.outerHeight() < this.element.prop( "scrollHeight" );
+       },
+
+       select: function( event ) {
+               // TODO: It should never be possible to not have an active item at this
+               // point, but the tests don't trigger mouseenter before click.
+               this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
+               var ui = { item: this.active };
+               if ( !this.active.has( ".ui-menu" ).length ) {
+                       this.collapseAll( event, true );
+               }
+               this._trigger( "select", event, ui );
+       },
+
+       _filterMenuItems: function(character) {
+               var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
+                       regex = new RegExp( "^" + escapedCharacter, "i" );
+
+               return this.activeMenu
+                       .find( this.options.items )
+
+                       // Only match on items, not dividers or other content (#10571)
+                       .filter( ".ui-menu-item" )
+                       .filter(function() {
+                               return regex.test( $.trim( $( this ).text() ) );
+                       });
+       }
+});
+
+
+/*!
+ * jQuery UI Autocomplete 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/autocomplete/
+ */
+
+
+$.widget( "ui.autocomplete", {
+       version: "1.11.3",
+       defaultElement: "<input>",
+       options: {
+               appendTo: null,
+               autoFocus: false,
+               delay: 300,
+               minLength: 1,
+               position: {
+                       my: "left top",
+                       at: "left bottom",
+                       collision: "none"
+               },
+               source: null,
+
+               // callbacks
+               change: null,
+               close: null,
+               focus: null,
+               open: null,
+               response: null,
+               search: null,
+               select: null
+       },
+
+       requestIndex: 0,
+       pending: 0,
+
+       _create: function() {
+               // Some browsers only repeat keydown events, not keypress events,
+               // so we use the suppressKeyPress flag to determine if we've already
+               // handled the keydown event. #7269
+               // Unfortunately the code for & in keypress is the same as the up arrow,
+               // so we use the suppressKeyPressRepeat flag to avoid handling keypress
+               // events when we know the keydown event was used to modify the
+               // search term. #7799
+               var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
+                       nodeName = this.element[ 0 ].nodeName.toLowerCase(),
+                       isTextarea = nodeName === "textarea",
+                       isInput = nodeName === "input";
+
+               this.isMultiLine =
+                       // Textareas are always multi-line
+                       isTextarea ? true :
+                       // Inputs are always single-line, even if inside a contentEditable element
+                       // IE also treats inputs as contentEditable
+                       isInput ? false :
+                       // All other element types are determined by whether or not they're contentEditable
+                       this.element.prop( "isContentEditable" );
+
+               this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
+               this.isNewMenu = true;
+
+               this.element
+                       .addClass( "ui-autocomplete-input" )
+                       .attr( "autocomplete", "off" );
+
+               this._on( this.element, {
+                       keydown: function( event ) {
+                               if ( this.element.prop( "readOnly" ) ) {
+                                       suppressKeyPress = true;
+                                       suppressInput = true;
+                                       suppressKeyPressRepeat = true;
+                                       return;
+                               }
+
+                               suppressKeyPress = false;
+                               suppressInput = false;
+                               suppressKeyPressRepeat = false;
+                               var keyCode = $.ui.keyCode;
+                               switch ( event.keyCode ) {
+                               case keyCode.PAGE_UP:
+                                       suppressKeyPress = true;
+                                       this._move( "previousPage", event );
+                                       break;
+                               case keyCode.PAGE_DOWN:
+                                       suppressKeyPress = true;
+                                       this._move( "nextPage", event );
+                                       break;
+                               case keyCode.UP:
+                                       suppressKeyPress = true;
+                                       this._keyEvent( "previous", event );
+                                       break;
+                               case keyCode.DOWN:
+                                       suppressKeyPress = true;
+                                       this._keyEvent( "next", event );
+                                       break;
+                               case keyCode.ENTER:
+                                       // when menu is open and has focus
+                                       if ( this.menu.active ) {
+                                               // #6055 - Opera still allows the keypress to occur
+                                               // which causes forms to submit
+                                               suppressKeyPress = true;
+                                               event.preventDefault();
+                                               this.menu.select( event );
+                                       }
+                                       break;
+                               case keyCode.TAB:
+                                       if ( this.menu.active ) {
+                                               this.menu.select( event );
+                                       }
+                                       break;
+                               case keyCode.ESCAPE:
+                                       if ( this.menu.element.is( ":visible" ) ) {
+                                               if ( !this.isMultiLine ) {
+                                                       this._value( this.term );
+                                               }
+                                               this.close( event );
+                                               // Different browsers have different default behavior for escape
+                                               // Single press can mean undo or clear
+                                               // Double press in IE means clear the whole form
+                                               event.preventDefault();
+                                       }
+                                       break;
+                               default:
+                                       suppressKeyPressRepeat = true;
+                                       // search timeout should be triggered before the input value is changed
+                                       this._searchTimeout( event );
+                                       break;
+                               }
+                       },
+                       keypress: function( event ) {
+                               if ( suppressKeyPress ) {
+                                       suppressKeyPress = false;
+                                       if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+                                               event.preventDefault();
+                                       }
+                                       return;
+                               }
+                               if ( suppressKeyPressRepeat ) {
+                                       return;
+                               }
+
+                               // replicate some key handlers to allow them to repeat in Firefox and Opera
+                               var keyCode = $.ui.keyCode;
+                               switch ( event.keyCode ) {
+                               case keyCode.PAGE_UP:
+                                       this._move( "previousPage", event );
+                                       break;
+                               case keyCode.PAGE_DOWN:
+                                       this._move( "nextPage", event );
+                                       break;
+                               case keyCode.UP:
+                                       this._keyEvent( "previous", event );
+                                       break;
+                               case keyCode.DOWN:
+                                       this._keyEvent( "next", event );
+                                       break;
+                               }
+                       },
+                       input: function( event ) {
+                               if ( suppressInput ) {
+                                       suppressInput = false;
+                                       event.preventDefault();
+                                       return;
+                               }
+                               this._searchTimeout( event );
+                       },
+                       focus: function() {
+                               this.selectedItem = null;
+                               this.previous = this._value();
+                       },
+                       blur: function( event ) {
+                               if ( this.cancelBlur ) {
+                                       delete this.cancelBlur;
+                                       return;
+                               }
+
+                               clearTimeout( this.searching );
+                               this.close( event );
+                               this._change( event );
+                       }
+               });
+
+               this._initSource();
+               this.menu = $( "<ul>" )
+                       .addClass( "ui-autocomplete ui-front" )
+                       .appendTo( this._appendTo() )
+                       .menu({
+                               // disable ARIA support, the live region takes care of that
+                               role: null
+                       })
+                       .hide()
+                       .menu( "instance" );
+
+               this._on( this.menu.element, {
+                       mousedown: function( event ) {
+                               // prevent moving focus out of the text field
+                               event.preventDefault();
+
+                               // IE doesn't prevent moving focus even with event.preventDefault()
+                               // so we set a flag to know when we should ignore the blur event
+                               this.cancelBlur = true;
+                               this._delay(function() {
+                                       delete this.cancelBlur;
+                               });
+
+                               // clicking on the scrollbar causes focus to shift to the body
+                               // but we can't detect a mouseup or a click immediately afterward
+                               // so we have to track the next mousedown and close the menu if
+                               // the user clicks somewhere outside of the autocomplete
+                               var menuElement = this.menu.element[ 0 ];
+                               if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
+                                       this._delay(function() {
+                                               var that = this;
+                                               this.document.one( "mousedown", function( event ) {
+                                                       if ( event.target !== that.element[ 0 ] &&
+                                                                       event.target !== menuElement &&
+                                                                       !$.contains( menuElement, event.target ) ) {
+                                                               that.close();
+                                                       }
+                                               });
+                                       });
+                               }
+                       },
+                       menufocus: function( event, ui ) {
+                               var label, item;
+                               // support: Firefox
+                               // Prevent accidental activation of menu items in Firefox (#7024 #9118)
+                               if ( this.isNewMenu ) {
+                                       this.isNewMenu = false;
+                                       if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
+                                               this.menu.blur();
+
+                                               this.document.one( "mousemove", function() {
+                                                       $( event.target ).trigger( event.originalEvent );
+                                               });
+
+                                               return;
+                                       }
+                               }
+
+                               item = ui.item.data( "ui-autocomplete-item" );
+                               if ( false !== this._trigger( "focus", event, { item: item } ) ) {
+                                       // use value to match what will end up in the input, if it was a key event
+                                       if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
+                                               this._value( item.value );
+                                       }
+                               }
+
+                               // Announce the value in the liveRegion
+                               label = ui.item.attr( "aria-label" ) || item.value;
+                               if ( label && $.trim( label ).length ) {
+                                       this.liveRegion.children().hide();
+                                       $( "<div>" ).text( label ).appendTo( this.liveRegion );
+                               }
+                       },
+                       menuselect: function( event, ui ) {
+                               var item = ui.item.data( "ui-autocomplete-item" ),
+                                       previous = this.previous;
+
+                               // only trigger when focus was lost (click on menu)
+                               if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
+                                       this.element.focus();
+                                       this.previous = previous;
+                                       // #6109 - IE triggers two focus events and the second
+                                       // is asynchronous, so we need to reset the previous
+                                       // term synchronously and asynchronously :-(
+                                       this._delay(function() {
+                                               this.previous = previous;
+                                               this.selectedItem = item;
+                                       });
+                               }
+
+                               if ( false !== this._trigger( "select", event, { item: item } ) ) {
+                                       this._value( item.value );
+                               }
+                               // reset the term after the select event
+                               // this allows custom select handling to work properly
+                               this.term = this._value();
+
+                               this.close( event );
+                               this.selectedItem = item;
+                       }
+               });
+
+               this.liveRegion = $( "<span>", {
+                               role: "status",
+                               "aria-live": "assertive",
+                               "aria-relevant": "additions"
+                       })
+                       .addClass( "ui-helper-hidden-accessible" )
+                       .appendTo( this.document[ 0 ].body );
+
+               // turning off autocomplete prevents the browser from remembering the
+               // value when navigating through history, so we re-enable autocomplete
+               // if the page is unloaded before the widget is destroyed. #7790
+               this._on( this.window, {
+                       beforeunload: function() {
+                               this.element.removeAttr( "autocomplete" );
+                       }
+               });
+       },
+
+       _destroy: function() {
+               clearTimeout( this.searching );
+               this.element
+                       .removeClass( "ui-autocomplete-input" )
+                       .removeAttr( "autocomplete" );
+               this.menu.element.remove();
+               this.liveRegion.remove();
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "source" ) {
+                       this._initSource();
+               }
+               if ( key === "appendTo" ) {
+                       this.menu.element.appendTo( this._appendTo() );
+               }
+               if ( key === "disabled" && value && this.xhr ) {
+                       this.xhr.abort();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+
+               if ( element ) {
+                       element = element.jquery || element.nodeType ?
+                               $( element ) :
+                               this.document.find( element ).eq( 0 );
+               }
+
+               if ( !element || !element[ 0 ] ) {
+                       element = this.element.closest( ".ui-front" );
+               }
+
+               if ( !element.length ) {
+                       element = this.document[ 0 ].body;
+               }
+
+               return element;
+       },
+
+       _initSource: function() {
+               var array, url,
+                       that = this;
+               if ( $.isArray( this.options.source ) ) {
+                       array = this.options.source;
+                       this.source = function( request, response ) {
+                               response( $.ui.autocomplete.filter( array, request.term ) );
+                       };
+               } else if ( typeof this.options.source === "string" ) {
+                       url = this.options.source;
+                       this.source = function( request, response ) {
+                               if ( that.xhr ) {
+                                       that.xhr.abort();
+                               }
+                               that.xhr = $.ajax({
+                                       url: url,
+                                       data: request,
+                                       dataType: "json",
+                                       success: function( data ) {
+                                               response( data );
+                                       },
+                                       error: function() {
+                                               response([]);
+                                       }
+                               });
+                       };
+               } else {
+                       this.source = this.options.source;
+               }
+       },
+
+       _searchTimeout: function( event ) {
+               clearTimeout( this.searching );
+               this.searching = this._delay(function() {
+
+                       // Search if the value has changed, or if the user retypes the same value (see #7434)
+                       var equalValues = this.term === this._value(),
+                               menuVisible = this.menu.element.is( ":visible" ),
+                               modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
+
+                       if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
+                               this.selectedItem = null;
+                               this.search( null, event );
+                       }
+               }, this.options.delay );
+       },
+
+       search: function( value, event ) {
+               value = value != null ? value : this._value();
+
+               // always save the actual value, not the one passed as an argument
+               this.term = this._value();
+
+               if ( value.length < this.options.minLength ) {
+                       return this.close( event );
+               }
+
+               if ( this._trigger( "search", event ) === false ) {
+                       return;
+               }
+
+               return this._search( value );
+       },
+
+       _search: function( value ) {
+               this.pending++;
+               this.element.addClass( "ui-autocomplete-loading" );
+               this.cancelSearch = false;
+
+               this.source( { term: value }, this._response() );
+       },
+
+       _response: function() {
+               var index = ++this.requestIndex;
+
+               return $.proxy(function( content ) {
+                       if ( index === this.requestIndex ) {
+                               this.__response( content );
+                       }
+
+                       this.pending--;
+                       if ( !this.pending ) {
+                               this.element.removeClass( "ui-autocomplete-loading" );
+                       }
+               }, this );
+       },
+
+       __response: function( content ) {
+               if ( content ) {
+                       content = this._normalize( content );
+               }
+               this._trigger( "response", null, { content: content } );
+               if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
+                       this._suggest( content );
+                       this._trigger( "open" );
+               } else {
+                       // use ._close() instead of .close() so we don't cancel future searches
+                       this._close();
+               }
+       },
+
+       close: function( event ) {
+               this.cancelSearch = true;
+               this._close( event );
+       },
+
+       _close: function( event ) {
+               if ( this.menu.element.is( ":visible" ) ) {
+                       this.menu.element.hide();
+                       this.menu.blur();
+                       this.isNewMenu = true;
+                       this._trigger( "close", event );
+               }
+       },
+
+       _change: function( event ) {
+               if ( this.previous !== this._value() ) {
+                       this._trigger( "change", event, { item: this.selectedItem } );
+               }
+       },
+
+       _normalize: function( items ) {
+               // assume all items have the right format when the first item is complete
+               if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
+                       return items;
+               }
+               return $.map( items, function( item ) {
+                       if ( typeof item === "string" ) {
+                               return {
+                                       label: item,
+                                       value: item
+                               };
+                       }
+                       return $.extend( {}, item, {
+                               label: item.label || item.value,
+                               value: item.value || item.label
+                       });
+               });
+       },
+
+       _suggest: function( items ) {
+               var ul = this.menu.element.empty();
+               this._renderMenu( ul, items );
+               this.isNewMenu = true;
+               this.menu.refresh();
+
+               // size and position menu
+               ul.show();
+               this._resizeMenu();
+               ul.position( $.extend({
+                       of: this.element
+               }, this.options.position ) );
+
+               if ( this.options.autoFocus ) {
+                       this.menu.next();
+               }
+       },
+
+       _resizeMenu: function() {
+               var ul = this.menu.element;
+               ul.outerWidth( Math.max(
+                       // Firefox wraps long text (possibly a rounding bug)
+                       // so we add 1px to avoid the wrapping (#7513)
+                       ul.width( "" ).outerWidth() + 1,
+                       this.element.outerWidth()
+               ) );
+       },
+
+       _renderMenu: function( ul, items ) {
+               var that = this;
+               $.each( items, function( index, item ) {
+                       that._renderItemData( ul, item );
+               });
+       },
+
+       _renderItemData: function( ul, item ) {
+               return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
+       },
+
+       _renderItem: function( ul, item ) {
+               return $( "<li>" ).text( item.label ).appendTo( ul );
+       },
+
+       _move: function( direction, event ) {
+               if ( !this.menu.element.is( ":visible" ) ) {
+                       this.search( null, event );
+                       return;
+               }
+               if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
+                               this.menu.isLastItem() && /^next/.test( direction ) ) {
+
+                       if ( !this.isMultiLine ) {
+                               this._value( this.term );
+                       }
+
+                       this.menu.blur();
+                       return;
+               }
+               this.menu[ direction ]( event );
+       },
+
+       widget: function() {
+               return this.menu.element;
+       },
+
+       _value: function() {
+               return this.valueMethod.apply( this.element, arguments );
+       },
+
+       _keyEvent: function( keyEvent, event ) {
+               if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+                       this._move( keyEvent, event );
+
+                       // prevents moving cursor to beginning/end of the text field in some browsers
+                       event.preventDefault();
+               }
+       }
+});
+
+$.extend( $.ui.autocomplete, {
+       escapeRegex: function( value ) {
+               return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
+       },
+       filter: function( array, term ) {
+               var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
+               return $.grep( array, function( value ) {
+                       return matcher.test( value.label || value.value || value );
+               });
+       }
+});
+
+// live region extension, adding a `messages` option
+// NOTE: This is an experimental API. We are still investigating
+// a full solution for string manipulation and internationalization.
+$.widget( "ui.autocomplete", $.ui.autocomplete, {
+       options: {
+               messages: {
+                       noResults: "No search results.",
+                       results: function( amount ) {
+                               return amount + ( amount > 1 ? " results are" : " result is" ) +
+                                       " available, use up and down arrow keys to navigate.";
+                       }
+               }
+       },
+
+       __response: function( content ) {
+               var message;
+               this._superApply( arguments );
+               if ( this.options.disabled || this.cancelSearch ) {
+                       return;
+               }
+               if ( content && content.length ) {
+                       message = this.options.messages.results( content.length );
+               } else {
+                       message = this.options.messages.noResults;
+               }
+               this.liveRegion.children().hide();
+               $( "<div>" ).text( message ).appendTo( this.liveRegion );
+       }
+});
+
+var autocomplete = $.ui.autocomplete;
+
+
+/*!
+ * jQuery UI Button 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/button/
+ */
+
+
+var lastActive,
+       baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+       typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+       formResetHandler = function() {
+               var form = $( this );
+               setTimeout(function() {
+                       form.find( ":ui-button" ).button( "refresh" );
+               }, 1 );
+       },
+       radioGroup = function( radio ) {
+               var name = radio.name,
+                       form = radio.form,
+                       radios = $( [] );
+               if ( name ) {
+                       name = name.replace( /'/g, "\\'" );
+                       if ( form ) {
+                               radios = $( form ).find( "[name='" + name + "'][type=radio]" );
+                       } else {
+                               radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
+                                       .filter(function() {
+                                               return !this.form;
+                                       });
+                       }
+               }
+               return radios;
+       };
+
+$.widget( "ui.button", {
+       version: "1.11.3",
+       defaultElement: "<button>",
+       options: {
+               disabled: null,
+               text: true,
+               label: null,
+               icons: {
+                       primary: null,
+                       secondary: null
+               }
+       },
+       _create: function() {
+               this.element.closest( "form" )
+                       .unbind( "reset" + this.eventNamespace )
+                       .bind( "reset" + this.eventNamespace, formResetHandler );
+
+               if ( typeof this.options.disabled !== "boolean" ) {
+                       this.options.disabled = !!this.element.prop( "disabled" );
+               } else {
+                       this.element.prop( "disabled", this.options.disabled );
+               }
+
+               this._determineButtonType();
+               this.hasTitle = !!this.buttonElement.attr( "title" );
+
+               var that = this,
+                       options = this.options,
+                       toggleButton = this.type === "checkbox" || this.type === "radio",
+                       activeClass = !toggleButton ? "ui-state-active" : "";
+
+               if ( options.label === null ) {
+                       options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
+               }
+
+               this._hoverable( this.buttonElement );
+
+               this.buttonElement
+                       .addClass( baseClasses )
+                       .attr( "role", "button" )
+                       .bind( "mouseenter" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               if ( this === lastActive ) {
+                                       $( this ).addClass( "ui-state-active" );
+                               }
+                       })
+                       .bind( "mouseleave" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return;
+                               }
+                               $( this ).removeClass( activeClass );
+                       })
+                       .bind( "click" + this.eventNamespace, function( event ) {
+                               if ( options.disabled ) {
+                                       event.preventDefault();
+                                       event.stopImmediatePropagation();
+                               }
+                       });
+
+               // Can't use _focusable() because the element that receives focus
+               // and the element that gets the ui-state-focus class are different
+               this._on({
+                       focus: function() {
+                               this.buttonElement.addClass( "ui-state-focus" );
+                       },
+                       blur: function() {
+                               this.buttonElement.removeClass( "ui-state-focus" );
+                       }
+               });
+
+               if ( toggleButton ) {
+                       this.element.bind( "change" + this.eventNamespace, function() {
+                               that.refresh();
+                       });
+               }
+
+               if ( this.type === "checkbox" ) {
+                       this.buttonElement.bind( "click" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                       });
+               } else if ( this.type === "radio" ) {
+                       this.buttonElement.bind( "click" + this.eventNamespace, function() {
+                               if ( options.disabled ) {
+                                       return false;
+                               }
+                               $( this ).addClass( "ui-state-active" );
+                               that.buttonElement.attr( "aria-pressed", "true" );
+
+                               var radio = that.element[ 0 ];
+                               radioGroup( radio )
+                                       .not( radio )
+                                       .map(function() {
+                                               return $( this ).button( "widget" )[ 0 ];
+                                       })
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "false" );
+                       });
+               } else {
+                       this.buttonElement
+                               .bind( "mousedown" + this.eventNamespace, function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).addClass( "ui-state-active" );
+                                       lastActive = this;
+                                       that.document.one( "mouseup", function() {
+                                               lastActive = null;
+                                       });
+                               })
+                               .bind( "mouseup" + this.eventNamespace, function() {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       $( this ).removeClass( "ui-state-active" );
+                               })
+                               .bind( "keydown" + this.eventNamespace, function(event) {
+                                       if ( options.disabled ) {
+                                               return false;
+                                       }
+                                       if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
+                                               $( this ).addClass( "ui-state-active" );
+                                       }
+                               })
+                               // see #8559, we bind to blur here in case the button element loses
+                               // focus between keydown and keyup, it would be left in an "active" state
+                               .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
+                                       $( this ).removeClass( "ui-state-active" );
+                               });
+
+                       if ( this.buttonElement.is("a") ) {
+                               this.buttonElement.keyup(function(event) {
+                                       if ( event.keyCode === $.ui.keyCode.SPACE ) {
+                                               // TODO pass through original event correctly (just as 2nd argument doesn't work)
+                                               $( this ).click();
+                                       }
+                               });
+                       }
+               }
+
+               this._setOption( "disabled", options.disabled );
+               this._resetButton();
+       },
+
+       _determineButtonType: function() {
+               var ancestor, labelSelector, checked;
+
+               if ( this.element.is("[type=checkbox]") ) {
+                       this.type = "checkbox";
+               } else if ( this.element.is("[type=radio]") ) {
+                       this.type = "radio";
+               } else if ( this.element.is("input") ) {
+                       this.type = "input";
+               } else {
+                       this.type = "button";
+               }
+
+               if ( this.type === "checkbox" || this.type === "radio" ) {
+                       // we don't search against the document in case the element
+                       // is disconnected from the DOM
+                       ancestor = this.element.parents().last();
+                       labelSelector = "label[for='" + this.element.attr("id") + "']";
+                       this.buttonElement = ancestor.find( labelSelector );
+                       if ( !this.buttonElement.length ) {
+                               ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+                               this.buttonElement = ancestor.filter( labelSelector );
+                               if ( !this.buttonElement.length ) {
+                                       this.buttonElement = ancestor.find( labelSelector );
+                               }
+                       }
+                       this.element.addClass( "ui-helper-hidden-accessible" );
+
+                       checked = this.element.is( ":checked" );
+                       if ( checked ) {
+                               this.buttonElement.addClass( "ui-state-active" );
+                       }
+                       this.buttonElement.prop( "aria-pressed", checked );
+               } else {
+                       this.buttonElement = this.element;
+               }
+       },
+
+       widget: function() {
+               return this.buttonElement;
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-helper-hidden-accessible" );
+               this.buttonElement
+                       .removeClass( baseClasses + " ui-state-active " + typeClasses )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-pressed" )
+                       .html( this.buttonElement.find(".ui-button-text").html() );
+
+               if ( !this.hasTitle ) {
+                       this.buttonElement.removeAttr( "title" );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "disabled" ) {
+                       this.widget().toggleClass( "ui-state-disabled", !!value );
+                       this.element.prop( "disabled", !!value );
+                       if ( value ) {
+                               if ( this.type === "checkbox" || this.type === "radio" ) {
+                                       this.buttonElement.removeClass( "ui-state-focus" );
+                               } else {
+                                       this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
+                               }
+                       }
+                       return;
+               }
+               this._resetButton();
+       },
+
+       refresh: function() {
+               //See #8237 & #8828
+               var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
+
+               if ( isDisabled !== this.options.disabled ) {
+                       this._setOption( "disabled", isDisabled );
+               }
+               if ( this.type === "radio" ) {
+                       radioGroup( this.element[0] ).each(function() {
+                               if ( $( this ).is( ":checked" ) ) {
+                                       $( this ).button( "widget" )
+                                               .addClass( "ui-state-active" )
+                                               .attr( "aria-pressed", "true" );
+                               } else {
+                                       $( this ).button( "widget" )
+                                               .removeClass( "ui-state-active" )
+                                               .attr( "aria-pressed", "false" );
+                               }
+                       });
+               } else if ( this.type === "checkbox" ) {
+                       if ( this.element.is( ":checked" ) ) {
+                               this.buttonElement
+                                       .addClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "true" );
+                       } else {
+                               this.buttonElement
+                                       .removeClass( "ui-state-active" )
+                                       .attr( "aria-pressed", "false" );
+                       }
+               }
+       },
+
+       _resetButton: function() {
+               if ( this.type === "input" ) {
+                       if ( this.options.label ) {
+                               this.element.val( this.options.label );
+                       }
+                       return;
+               }
+               var buttonElement = this.buttonElement.removeClass( typeClasses ),
+                       buttonText = $( "<span></span>", this.document[0] )
+                               .addClass( "ui-button-text" )
+                               .html( this.options.label )
+                               .appendTo( buttonElement.empty() )
+                               .text(),
+                       icons = this.options.icons,
+                       multipleIcons = icons.primary && icons.secondary,
+                       buttonClasses = [];
+
+               if ( icons.primary || icons.secondary ) {
+                       if ( this.options.text ) {
+                               buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+                       }
+
+                       if ( icons.primary ) {
+                               buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+                       }
+
+                       if ( icons.secondary ) {
+                               buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+                       }
+
+                       if ( !this.options.text ) {
+                               buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+                               if ( !this.hasTitle ) {
+                                       buttonElement.attr( "title", $.trim( buttonText ) );
+                               }
+                       }
+               } else {
+                       buttonClasses.push( "ui-button-text-only" );
+               }
+               buttonElement.addClass( buttonClasses.join( " " ) );
+       }
+});
+
+$.widget( "ui.buttonset", {
+       version: "1.11.3",
+       options: {
+               items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
+       },
+
+       _create: function() {
+               this.element.addClass( "ui-buttonset" );
+       },
+
+       _init: function() {
+               this.refresh();
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "disabled" ) {
+                       this.buttons.button( "option", key, value );
+               }
+
+               this._super( key, value );
+       },
+
+       refresh: function() {
+               var rtl = this.element.css( "direction" ) === "rtl",
+                       allButtons = this.element.find( this.options.items ),
+                       existingButtons = allButtons.filter( ":ui-button" );
+
+               // Initialize new buttons
+               allButtons.not( ":ui-button" ).button();
+
+               // Refresh existing buttons
+               existingButtons.button( "refresh" );
+
+               this.buttons = allButtons
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+                               .filter( ":first" )
+                                       .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
+                               .end()
+                               .filter( ":last" )
+                                       .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
+                               .end()
+                       .end();
+       },
+
+       _destroy: function() {
+               this.element.removeClass( "ui-buttonset" );
+               this.buttons
+                       .map(function() {
+                               return $( this ).button( "widget" )[ 0 ];
+                       })
+                               .removeClass( "ui-corner-left ui-corner-right" )
+                       .end()
+                       .button( "destroy" );
+       }
+});
+
+var button = $.ui.button;
+
+
+/*!
+ * jQuery UI Datepicker 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/datepicker/
+ */
+
+
+$.extend($.ui, { datepicker: { version: "1.11.3" } });
+
+var datepicker_instActive;
+
+function datepicker_getZindex( elem ) {
+       var position, value;
+       while ( elem.length && elem[ 0 ] !== document ) {
+               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+               // This makes behavior of this function consistent across browsers
+               // WebKit always returns auto if the element is positioned
+               position = elem.css( "position" );
+               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                       // IE returns 0 when zIndex is not specified
+                       // other browsers return a string
+                       // we ignore the case of nested elements with an explicit value of 0
+                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                       value = parseInt( elem.css( "zIndex" ), 10 );
+                       if ( !isNaN( value ) && value !== 0 ) {
+                               return value;
+                       }
+               }
+               elem = elem.parent();
+       }
+
+       return 0;
+}
+/* Date picker manager.
+   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+   Settings for (groups of) date pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Datepicker() {
+       this._curInst = null; // The current instance in use
+       this._keyEvent = false; // If the last event was a key event
+       this._disabledInputs = []; // List of date picker inputs that have been disabled
+       this._datepickerShowing = false; // True if the popup picker is showing , false if not
+       this._inDialog = false; // True if showing within a "dialog", false if not
+       this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
+       this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
+       this._appendClass = "ui-datepicker-append"; // The name of the append marker class
+       this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
+       this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
+       this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
+       this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
+       this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
+       this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
+       this.regional = []; // Available regional settings, indexed by language code
+       this.regional[""] = { // Default regional settings
+               closeText: "Done", // Display text for close link
+               prevText: "Prev", // Display text for previous month link
+               nextText: "Next", // Display text for next month link
+               currentText: "Today", // Display text for current month link
+               monthNames: ["January","February","March","April","May","June",
+                       "July","August","September","October","November","December"], // Names of months for drop-down and formatting
+               monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
+               dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
+               dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
+               dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
+               weekHeader: "Wk", // Column header for week of the year
+               dateFormat: "mm/dd/yy", // See format options on parseDate
+               firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+               isRTL: false, // True if right-to-left language, false if left-to-right
+               showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+               yearSuffix: "" // Additional text to append to the year in the month headers
+       };
+       this._defaults = { // Global defaults for all the date picker instances
+               showOn: "focus", // "focus" for popup on focus,
+                       // "button" for trigger button, or "both" for either
+               showAnim: "fadeIn", // Name of jQuery animation for popup
+               showOptions: {}, // Options for enhanced animations
+               defaultDate: null, // Used when field is blank: actual date,
+                       // +/-number for offset from today, null for today
+               appendText: "", // Display text following the input box, e.g. showing the format
+               buttonText: "...", // Text for trigger button
+               buttonImage: "", // URL for trigger button image
+               buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+               hideIfNoPrevNext: false, // True to hide next/previous month links
+                       // if not applicable, false to just disable them
+               navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+               gotoCurrent: false, // True if today link goes back to current selection instead
+               changeMonth: false, // True if month can be selected directly, false if only prev/next
+               changeYear: false, // True if year can be selected directly, false if only prev/next
+               yearRange: "c-10:c+10", // Range of years to display in drop-down,
+                       // either relative to today's year (-nn:+nn), relative to currently displayed year
+                       // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+               showOtherMonths: false, // True to show dates in other months, false to leave blank
+               selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+               showWeek: false, // True to show week of the year, false to not show it
+               calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+                       // takes a Date and returns the number of the week for it
+               shortYearCutoff: "+10", // Short year values < this are in the current century,
+                       // > this are in the previous century,
+                       // string value starting with "+" for current year + value
+               minDate: null, // The earliest selectable date, or null for no limit
+               maxDate: null, // The latest selectable date, or null for no limit
+               duration: "fast", // Duration of display/closure
+               beforeShowDay: null, // Function that takes a date and returns an array with
+                       // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
+                       // [2] = cell title (optional), e.g. $.datepicker.noWeekends
+               beforeShow: null, // Function that takes an input field and
+                       // returns a set of custom settings for the date picker
+               onSelect: null, // Define a callback function when a date is selected
+               onChangeMonthYear: null, // Define a callback function when the month or year is changed
+               onClose: null, // Define a callback function when the datepicker is closed
+               numberOfMonths: 1, // Number of months to show at a time
+               showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+               stepMonths: 1, // Number of months to step back/forward
+               stepBigMonths: 12, // Number of months to step back/forward for the big links
+               altField: "", // Selector for an alternate field to store selected dates into
+               altFormat: "", // The date format to use for the alternate field
+               constrainInput: true, // The input is constrained by the current date format
+               showButtonPanel: false, // True to show button panel, false to not show it
+               autoSize: false, // True to size the input for the date format, false to leave as is
+               disabled: false // The initial disabled state
+       };
+       $.extend(this._defaults, this.regional[""]);
+       this.regional.en = $.extend( true, {}, this.regional[ "" ]);
+       this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
+       this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
+}
+
+$.extend(Datepicker.prototype, {
+       /* Class name added to elements to indicate already configured with a date picker. */
+       markerClassName: "hasDatepicker",
+
+       //Keep track of the maximum number of rows displayed (see #7043)
+       maxRows: 4,
+
+       // TODO rename to "widget" when switching to widget factory
+       _widgetDatepicker: function() {
+               return this.dpDiv;
+       },
+
+       /* Override the default settings for all instances of the date picker.
+        * @param  settings  object - the new settings to use as defaults (anonymous object)
+        * @return the manager object
+        */
+       setDefaults: function(settings) {
+               datepicker_extendRemove(this._defaults, settings || {});
+               return this;
+       },
+
+       /* Attach the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        * @param  settings  object - the new settings to use for this date picker instance (anonymous)
+        */
+       _attachDatepicker: function(target, settings) {
+               var nodeName, inline, inst;
+               nodeName = target.nodeName.toLowerCase();
+               inline = (nodeName === "div" || nodeName === "span");
+               if (!target.id) {
+                       this.uuid += 1;
+                       target.id = "dp" + this.uuid;
+               }
+               inst = this._newInst($(target), inline);
+               inst.settings = $.extend({}, settings || {});
+               if (nodeName === "input") {
+                       this._connectDatepicker(target, inst);
+               } else if (inline) {
+                       this._inlineDatepicker(target, inst);
+               }
+       },
+
+       /* Create a new instance object. */
+       _newInst: function(target, inline) {
+               var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
+               return {id: id, input: target, // associated target
+                       selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+                       drawMonth: 0, drawYear: 0, // month being drawn
+                       inline: inline, // is datepicker inline or not
+                       dpDiv: (!inline ? this.dpDiv : // presentation div
+                       datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
+       },
+
+       /* Attach the date picker to an input field. */
+       _connectDatepicker: function(target, inst) {
+               var input = $(target);
+               inst.append = $([]);
+               inst.trigger = $([]);
+               if (input.hasClass(this.markerClassName)) {
+                       return;
+               }
+               this._attachments(input, inst);
+               input.addClass(this.markerClassName).keydown(this._doKeyDown).
+                       keypress(this._doKeyPress).keyup(this._doKeyUp);
+               this._autoSize(inst);
+               $.data(target, "datepicker", inst);
+               //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
+               if( inst.settings.disabled ) {
+                       this._disableDatepicker( target );
+               }
+       },
+
+       /* Make attachments based on settings. */
+       _attachments: function(input, inst) {
+               var showOn, buttonText, buttonImage,
+                       appendText = this._get(inst, "appendText"),
+                       isRTL = this._get(inst, "isRTL");
+
+               if (inst.append) {
+                       inst.append.remove();
+               }
+               if (appendText) {
+                       inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
+                       input[isRTL ? "before" : "after"](inst.append);
+               }
+
+               input.unbind("focus", this._showDatepicker);
+
+               if (inst.trigger) {
+                       inst.trigger.remove();
+               }
+
+               showOn = this._get(inst, "showOn");
+               if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
+                       input.focus(this._showDatepicker);
+               }
+               if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
+                       buttonText = this._get(inst, "buttonText");
+                       buttonImage = this._get(inst, "buttonImage");
+                       inst.trigger = $(this._get(inst, "buttonImageOnly") ?
+                               $("<img/>").addClass(this._triggerClass).
+                                       attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+                               $("<button type='button'></button>").addClass(this._triggerClass).
+                                       html(!buttonImage ? buttonText : $("<img/>").attr(
+                                       { src:buttonImage, alt:buttonText, title:buttonText })));
+                       input[isRTL ? "before" : "after"](inst.trigger);
+                       inst.trigger.click(function() {
+                               if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
+                                       $.datepicker._hideDatepicker();
+                               } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
+                                       $.datepicker._hideDatepicker();
+                                       $.datepicker._showDatepicker(input[0]);
+                               } else {
+                                       $.datepicker._showDatepicker(input[0]);
+                               }
+                               return false;
+                       });
+               }
+       },
+
+       /* Apply the maximum length for the date format. */
+       _autoSize: function(inst) {
+               if (this._get(inst, "autoSize") && !inst.inline) {
+                       var findMax, max, maxI, i,
+                               date = new Date(2009, 12 - 1, 20), // Ensure double digits
+                               dateFormat = this._get(inst, "dateFormat");
+
+                       if (dateFormat.match(/[DM]/)) {
+                               findMax = function(names) {
+                                       max = 0;
+                                       maxI = 0;
+                                       for (i = 0; i < names.length; i++) {
+                                               if (names[i].length > max) {
+                                                       max = names[i].length;
+                                                       maxI = i;
+                                               }
+                                       }
+                                       return maxI;
+                               };
+                               date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
+                                       "monthNames" : "monthNamesShort"))));
+                               date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
+                                       "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
+                       }
+                       inst.input.attr("size", this._formatDate(inst, date).length);
+               }
+       },
+
+       /* Attach an inline date picker to a div. */
+       _inlineDatepicker: function(target, inst) {
+               var divSpan = $(target);
+               if (divSpan.hasClass(this.markerClassName)) {
+                       return;
+               }
+               divSpan.addClass(this.markerClassName).append(inst.dpDiv);
+               $.data(target, "datepicker", inst);
+               this._setDate(inst, this._getDefaultDate(inst), true);
+               this._updateDatepicker(inst);
+               this._updateAlternate(inst);
+               //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
+               if( inst.settings.disabled ) {
+                       this._disableDatepicker( target );
+               }
+               // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
+               // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
+               inst.dpDiv.css( "display", "block" );
+       },
+
+       /* Pop-up the date picker in a "dialog" box.
+        * @param  input element - ignored
+        * @param  date string or Date - the initial date to display
+        * @param  onSelect  function - the function to call when a date is selected
+        * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
+        * @param  pos int[2] - coordinates for the dialog's position within the screen or
+        *                                      event - with x/y coordinates or
+        *                                      leave empty for default (screen centre)
+        * @return the manager object
+        */
+       _dialogDatepicker: function(input, date, onSelect, settings, pos) {
+               var id, browserWidth, browserHeight, scrollX, scrollY,
+                       inst = this._dialogInst; // internal instance
+
+               if (!inst) {
+                       this.uuid += 1;
+                       id = "dp" + this.uuid;
+                       this._dialogInput = $("<input type='text' id='" + id +
+                               "' style='position: absolute; top: -100px; width: 0px;'/>");
+                       this._dialogInput.keydown(this._doKeyDown);
+                       $("body").append(this._dialogInput);
+                       inst = this._dialogInst = this._newInst(this._dialogInput, false);
+                       inst.settings = {};
+                       $.data(this._dialogInput[0], "datepicker", inst);
+               }
+               datepicker_extendRemove(inst.settings, settings || {});
+               date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
+               this._dialogInput.val(date);
+
+               this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+               if (!this._pos) {
+                       browserWidth = document.documentElement.clientWidth;
+                       browserHeight = document.documentElement.clientHeight;
+                       scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+                       scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+                       this._pos = // should use actual width/height below
+                               [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+               }
+
+               // move input on screen for focus, but hidden behind dialog
+               this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
+               inst.settings.onSelect = onSelect;
+               this._inDialog = true;
+               this.dpDiv.addClass(this._dialogClass);
+               this._showDatepicker(this._dialogInput[0]);
+               if ($.blockUI) {
+                       $.blockUI(this.dpDiv);
+               }
+               $.data(this._dialogInput[0], "datepicker", inst);
+               return this;
+       },
+
+       /* Detach a datepicker from its control.
+        * @param  target       element - the target input field or division or span
+        */
+       _destroyDatepicker: function(target) {
+               var nodeName,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               $.removeData(target, "datepicker");
+               if (nodeName === "input") {
+                       inst.append.remove();
+                       inst.trigger.remove();
+                       $target.removeClass(this.markerClassName).
+                               unbind("focus", this._showDatepicker).
+                               unbind("keydown", this._doKeyDown).
+                               unbind("keypress", this._doKeyPress).
+                               unbind("keyup", this._doKeyUp);
+               } else if (nodeName === "div" || nodeName === "span") {
+                       $target.removeClass(this.markerClassName).empty();
+               }
+
+               if ( datepicker_instActive === inst ) {
+                       datepicker_instActive = null;
+               }
+       },
+
+       /* Enable the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        */
+       _enableDatepicker: function(target) {
+               var nodeName, inline,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               if (nodeName === "input") {
+                       target.disabled = false;
+                       inst.trigger.filter("button").
+                               each(function() { this.disabled = false; }).end().
+                               filter("img").css({opacity: "1.0", cursor: ""});
+               } else if (nodeName === "div" || nodeName === "span") {
+                       inline = $target.children("." + this._inlineClass);
+                       inline.children().removeClass("ui-state-disabled");
+                       inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+                               prop("disabled", false);
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value === target ? null : value); }); // delete entry
+       },
+
+       /* Disable the date picker to a jQuery selection.
+        * @param  target       element - the target input field or division or span
+        */
+       _disableDatepicker: function(target) {
+               var nodeName, inline,
+                       $target = $(target),
+                       inst = $.data(target, "datepicker");
+
+               if (!$target.hasClass(this.markerClassName)) {
+                       return;
+               }
+
+               nodeName = target.nodeName.toLowerCase();
+               if (nodeName === "input") {
+                       target.disabled = true;
+                       inst.trigger.filter("button").
+                               each(function() { this.disabled = true; }).end().
+                               filter("img").css({opacity: "0.5", cursor: "default"});
+               } else if (nodeName === "div" || nodeName === "span") {
+                       inline = $target.children("." + this._inlineClass);
+                       inline.children().addClass("ui-state-disabled");
+                       inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+                               prop("disabled", true);
+               }
+               this._disabledInputs = $.map(this._disabledInputs,
+                       function(value) { return (value === target ? null : value); }); // delete entry
+               this._disabledInputs[this._disabledInputs.length] = target;
+       },
+
+       /* Is the first field in a jQuery collection disabled as a datepicker?
+        * @param  target       element - the target input field or division or span
+        * @return boolean - true if disabled, false if enabled
+        */
+       _isDisabledDatepicker: function(target) {
+               if (!target) {
+                       return false;
+               }
+               for (var i = 0; i < this._disabledInputs.length; i++) {
+                       if (this._disabledInputs[i] === target) {
+                               return true;
+                       }
+               }
+               return false;
+       },
+
+       /* Retrieve the instance data for the target control.
+        * @param  target  element - the target input field or division or span
+        * @return  object - the associated instance data
+        * @throws  error if a jQuery problem getting data
+        */
+       _getInst: function(target) {
+               try {
+                       return $.data(target, "datepicker");
+               }
+               catch (err) {
+                       throw "Missing instance data for this datepicker";
+               }
+       },
+
+       /* Update or retrieve the settings for a date picker attached to an input field or division.
+        * @param  target  element - the target input field or division or span
+        * @param  name object - the new settings to update or
+        *                              string - the name of the setting to change or retrieve,
+        *                              when retrieving also "all" for all instance settings or
+        *                              "defaults" for all global defaults
+        * @param  value   any - the new value for the setting
+        *                              (omit if above is an object or to retrieve a value)
+        */
+       _optionDatepicker: function(target, name, value) {
+               var settings, date, minDate, maxDate,
+                       inst = this._getInst(target);
+
+               if (arguments.length === 2 && typeof name === "string") {
+                       return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
+                               (inst ? (name === "all" ? $.extend({}, inst.settings) :
+                               this._get(inst, name)) : null));
+               }
+
+               settings = name || {};
+               if (typeof name === "string") {
+                       settings = {};
+                       settings[name] = value;
+               }
+
+               if (inst) {
+                       if (this._curInst === inst) {
+                               this._hideDatepicker();
+                       }
+
+                       date = this._getDateDatepicker(target, true);
+                       minDate = this._getMinMaxDate(inst, "min");
+                       maxDate = this._getMinMaxDate(inst, "max");
+                       datepicker_extendRemove(inst.settings, settings);
+                       // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+                       if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
+                               inst.settings.minDate = this._formatDate(inst, minDate);
+                       }
+                       if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
+                               inst.settings.maxDate = this._formatDate(inst, maxDate);
+                       }
+                       if ( "disabled" in settings ) {
+                               if ( settings.disabled ) {
+                                       this._disableDatepicker(target);
+                               } else {
+                                       this._enableDatepicker(target);
+                               }
+                       }
+                       this._attachments($(target), inst);
+                       this._autoSize(inst);
+                       this._setDate(inst, date);
+                       this._updateAlternate(inst);
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       // change method deprecated
+       _changeDatepicker: function(target, name, value) {
+               this._optionDatepicker(target, name, value);
+       },
+
+       /* Redraw the date picker attached to an input field or division.
+        * @param  target  element - the target input field or division or span
+        */
+       _refreshDatepicker: function(target) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._updateDatepicker(inst);
+               }
+       },
+
+       /* Set the dates for a jQuery selection.
+        * @param  target element - the target input field or division or span
+        * @param  date Date - the new date
+        */
+       _setDateDatepicker: function(target, date) {
+               var inst = this._getInst(target);
+               if (inst) {
+                       this._setDate(inst, date);
+                       this._updateDatepicker(inst);
+                       this._updateAlternate(inst);
+               }
+       },
+
+       /* Get the date(s) for the first entry in a jQuery selection.
+        * @param  target element - the target input field or division or span
+        * @param  noDefault boolean - true if no default date is to be used
+        * @return Date - the current date
+        */
+       _getDateDatepicker: function(target, noDefault) {
+               var inst = this._getInst(target);
+               if (inst && !inst.inline) {
+                       this._setDateFromField(inst, noDefault);
+               }
+               return (inst ? this._getDate(inst) : null);
+       },
+
+       /* Handle keystrokes. */
+       _doKeyDown: function(event) {
+               var onSelect, dateStr, sel,
+                       inst = $.datepicker._getInst(event.target),
+                       handled = true,
+                       isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
+
+               inst._keyEvent = true;
+               if ($.datepicker._datepickerShowing) {
+                       switch (event.keyCode) {
+                               case 9: $.datepicker._hideDatepicker();
+                                               handled = false;
+                                               break; // hide on tab out
+                               case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
+                                                                       $.datepicker._currentClass + ")", inst.dpDiv);
+                                               if (sel[0]) {
+                                                       $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
+                                               }
+
+                                               onSelect = $.datepicker._get(inst, "onSelect");
+                                               if (onSelect) {
+                                                       dateStr = $.datepicker._formatDate(inst);
+
+                                                       // trigger custom callback
+                                                       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
+                                               } else {
+                                                       $.datepicker._hideDatepicker();
+                                               }
+
+                                               return false; // don't submit the form
+                               case 27: $.datepicker._hideDatepicker();
+                                               break; // hide on escape
+                               case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       -$.datepicker._get(inst, "stepBigMonths") :
+                                                       -$.datepicker._get(inst, "stepMonths")), "M");
+                                               break; // previous month/year on page up/+ ctrl
+                               case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                       +$.datepicker._get(inst, "stepBigMonths") :
+                                                       +$.datepicker._get(inst, "stepMonths")), "M");
+                                               break; // next month/year on page down/+ ctrl
+                               case 35: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._clearDate(event.target);
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // clear on ctrl or command +end
+                               case 36: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._gotoToday(event.target);
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // current on ctrl or command +home
+                               case 37: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // -1 day on ctrl or command +left
+                                               if (event.originalEvent.altKey) {
+                                                       $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                               -$.datepicker._get(inst, "stepBigMonths") :
+                                                               -$.datepicker._get(inst, "stepMonths")), "M");
+                                               }
+                                               // next month/year on alt +left on Mac
+                                               break;
+                               case 38: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, -7, "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // -1 week on ctrl or command +up
+                               case 39: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               // +1 day on ctrl or command +right
+                                               if (event.originalEvent.altKey) {
+                                                       $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+                                                               +$.datepicker._get(inst, "stepBigMonths") :
+                                                               +$.datepicker._get(inst, "stepMonths")), "M");
+                                               }
+                                               // next month/year on alt +right
+                                               break;
+                               case 40: if (event.ctrlKey || event.metaKey) {
+                                                       $.datepicker._adjustDate(event.target, +7, "D");
+                                               }
+                                               handled = event.ctrlKey || event.metaKey;
+                                               break; // +1 week on ctrl or command +down
+                               default: handled = false;
+                       }
+               } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
+                       $.datepicker._showDatepicker(this);
+               } else {
+                       handled = false;
+               }
+
+               if (handled) {
+                       event.preventDefault();
+                       event.stopPropagation();
+               }
+       },
+
+       /* Filter entered characters - based on date format. */
+       _doKeyPress: function(event) {
+               var chars, chr,
+                       inst = $.datepicker._getInst(event.target);
+
+               if ($.datepicker._get(inst, "constrainInput")) {
+                       chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
+                       chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
+                       return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
+               }
+       },
+
+       /* Synchronise manual entry and field/alternate field. */
+       _doKeyUp: function(event) {
+               var date,
+                       inst = $.datepicker._getInst(event.target);
+
+               if (inst.input.val() !== inst.lastVal) {
+                       try {
+                               date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
+                                       (inst.input ? inst.input.val() : null),
+                                       $.datepicker._getFormatConfig(inst));
+
+                               if (date) { // only if valid
+                                       $.datepicker._setDateFromField(inst);
+                                       $.datepicker._updateAlternate(inst);
+                                       $.datepicker._updateDatepicker(inst);
+                               }
+                       }
+                       catch (err) {
+                       }
+               }
+               return true;
+       },
+
+       /* Pop-up the date picker for a given input field.
+        * If false returned from beforeShow event handler do not show.
+        * @param  input  element - the input field attached to the date picker or
+        *                                      event - if triggered by focus
+        */
+       _showDatepicker: function(input) {
+               input = input.target || input;
+               if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
+                       input = $("input", input.parentNode)[0];
+               }
+
+               if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
+                       return;
+               }
+
+               var inst, beforeShow, beforeShowSettings, isFixed,
+                       offset, showAnim, duration;
+
+               inst = $.datepicker._getInst(input);
+               if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
+                       $.datepicker._curInst.dpDiv.stop(true, true);
+                       if ( inst && $.datepicker._datepickerShowing ) {
+                               $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
+                       }
+               }
+
+               beforeShow = $.datepicker._get(inst, "beforeShow");
+               beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
+               if(beforeShowSettings === false){
+                       return;
+               }
+               datepicker_extendRemove(inst.settings, beforeShowSettings);
+
+               inst.lastVal = null;
+               $.datepicker._lastInput = input;
+               $.datepicker._setDateFromField(inst);
+
+               if ($.datepicker._inDialog) { // hide cursor
+                       input.value = "";
+               }
+               if (!$.datepicker._pos) { // position below input
+                       $.datepicker._pos = $.datepicker._findPos(input);
+                       $.datepicker._pos[1] += input.offsetHeight; // add the height
+               }
+
+               isFixed = false;
+               $(input).parents().each(function() {
+                       isFixed |= $(this).css("position") === "fixed";
+                       return !isFixed;
+               });
+
+               offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+               $.datepicker._pos = null;
+               //to avoid flashes on Firefox
+               inst.dpDiv.empty();
+               // determine sizing offscreen
+               inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
+               $.datepicker._updateDatepicker(inst);
+               // fix width for dynamic number of date pickers
+               // and adjust position before showing
+               offset = $.datepicker._checkOffset(inst, offset, isFixed);
+               inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+                       "static" : (isFixed ? "fixed" : "absolute")), display: "none",
+                       left: offset.left + "px", top: offset.top + "px"});
+
+               if (!inst.inline) {
+                       showAnim = $.datepicker._get(inst, "showAnim");
+                       duration = $.datepicker._get(inst, "duration");
+                       inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
+                       $.datepicker._datepickerShowing = true;
+
+                       if ( $.effects && $.effects.effect[ showAnim ] ) {
+                               inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
+                       } else {
+                               inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
+                       }
+
+                       if ( $.datepicker._shouldFocusInput( inst ) ) {
+                               inst.input.focus();
+                       }
+
+                       $.datepicker._curInst = inst;
+               }
+       },
+
+       /* Generate the date picker content. */
+       _updateDatepicker: function(inst) {
+               this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
+               datepicker_instActive = inst; // for delegate hover events
+               inst.dpDiv.empty().append(this._generateHTML(inst));
+               this._attachHandlers(inst);
+
+               var origyearshtml,
+                       numMonths = this._getNumberOfMonths(inst),
+                       cols = numMonths[1],
+                       width = 17,
+                       activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
+
+               if ( activeCell.length > 0 ) {
+                       datepicker_handleMouseover.apply( activeCell.get( 0 ) );
+               }
+
+               inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
+               if (cols > 1) {
+                       inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
+               }
+               inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
+                       "Class"]("ui-datepicker-multi");
+               inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
+                       "Class"]("ui-datepicker-rtl");
+
+               if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
+                       inst.input.focus();
+               }
+
+               // deffered render of the years select (to avoid flashes on Firefox)
+               if( inst.yearshtml ){
+                       origyearshtml = inst.yearshtml;
+                       setTimeout(function(){
+                               //assure that inst.yearshtml didn't change.
+                               if( origyearshtml === inst.yearshtml && inst.yearshtml ){
+                                       inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
+                               }
+                               origyearshtml = inst.yearshtml = null;
+                       }, 0);
+               }
+       },
+
+       // #6694 - don't focus the input if it's already focused
+       // this breaks the change event in IE
+       // Support: IE and jQuery <1.9
+       _shouldFocusInput: function( inst ) {
+               return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+       },
+
+       /* Check positioning to remain on screen. */
+       _checkOffset: function(inst, offset, isFixed) {
+               var dpWidth = inst.dpDiv.outerWidth(),
+                       dpHeight = inst.dpDiv.outerHeight(),
+                       inputWidth = inst.input ? inst.input.outerWidth() : 0,
+                       inputHeight = inst.input ? inst.input.outerHeight() : 0,
+                       viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
+                       viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
+
+               offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
+               offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
+               offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
+
+               // now check if datepicker is showing outside window viewport - move to a better place if so.
+               offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
+                       Math.abs(offset.left + dpWidth - viewWidth) : 0);
+               offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
+                       Math.abs(dpHeight + inputHeight) : 0);
+
+               return offset;
+       },
+
+       /* Find an object's position on the screen. */
+       _findPos: function(obj) {
+               var position,
+                       inst = this._getInst(obj),
+                       isRTL = this._get(inst, "isRTL");
+
+               while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
+                       obj = obj[isRTL ? "previousSibling" : "nextSibling"];
+               }
+
+               position = $(obj).offset();
+               return [position.left, position.top];
+       },
+
+       /* Hide the date picker from view.
+        * @param  input  element - the input field attached to the date picker
+        */
+       _hideDatepicker: function(input) {
+               var showAnim, duration, postProcess, onClose,
+                       inst = this._curInst;
+
+               if (!inst || (input && inst !== $.data(input, "datepicker"))) {
+                       return;
+               }
+
+               if (this._datepickerShowing) {
+                       showAnim = this._get(inst, "showAnim");
+                       duration = this._get(inst, "duration");
+                       postProcess = function() {
+                               $.datepicker._tidyDialog(inst);
+                       };
+
+                       // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
+                       if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
+                               inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
+                       } else {
+                               inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
+                                       (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
+                       }
+
+                       if (!showAnim) {
+                               postProcess();
+                       }
+                       this._datepickerShowing = false;
+
+                       onClose = this._get(inst, "onClose");
+                       if (onClose) {
+                               onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
+                       }
+
+                       this._lastInput = null;
+                       if (this._inDialog) {
+                               this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
+                               if ($.blockUI) {
+                                       $.unblockUI();
+                                       $("body").append(this.dpDiv);
+                               }
+                       }
+                       this._inDialog = false;
+               }
+       },
+
+       /* Tidy up after a dialog display. */
+       _tidyDialog: function(inst) {
+               inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
+       },
+
+       /* Close date picker if clicked elsewhere. */
+       _checkExternalClick: function(event) {
+               if (!$.datepicker._curInst) {
+                       return;
+               }
+
+               var $target = $(event.target),
+                       inst = $.datepicker._getInst($target[0]);
+
+               if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
+                               $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
+                               !$target.hasClass($.datepicker.markerClassName) &&
+                               !$target.closest("." + $.datepicker._triggerClass).length &&
+                               $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
+                       ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
+                               $.datepicker._hideDatepicker();
+               }
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustDate: function(id, offset, period) {
+               var target = $(id),
+                       inst = this._getInst(target[0]);
+
+               if (this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+               this._adjustInstDate(inst, offset +
+                       (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
+                       period);
+               this._updateDatepicker(inst);
+       },
+
+       /* Action for current link. */
+       _gotoToday: function(id) {
+               var date,
+                       target = $(id),
+                       inst = this._getInst(target[0]);
+
+               if (this._get(inst, "gotoCurrent") && inst.currentDay) {
+                       inst.selectedDay = inst.currentDay;
+                       inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+                       inst.drawYear = inst.selectedYear = inst.currentYear;
+               } else {
+                       date = new Date();
+                       inst.selectedDay = date.getDate();
+                       inst.drawMonth = inst.selectedMonth = date.getMonth();
+                       inst.drawYear = inst.selectedYear = date.getFullYear();
+               }
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Action for selecting a new month/year. */
+       _selectMonthYear: function(id, select, period) {
+               var target = $(id),
+                       inst = this._getInst(target[0]);
+
+               inst["selected" + (period === "M" ? "Month" : "Year")] =
+               inst["draw" + (period === "M" ? "Month" : "Year")] =
+                       parseInt(select.options[select.selectedIndex].value,10);
+
+               this._notifyChange(inst);
+               this._adjustDate(target);
+       },
+
+       /* Action for selecting a day. */
+       _selectDay: function(id, month, year, td) {
+               var inst,
+                       target = $(id);
+
+               if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
+                       return;
+               }
+
+               inst = this._getInst(target[0]);
+               inst.selectedDay = inst.currentDay = $("a", td).html();
+               inst.selectedMonth = inst.currentMonth = month;
+               inst.selectedYear = inst.currentYear = year;
+               this._selectDate(id, this._formatDate(inst,
+                       inst.currentDay, inst.currentMonth, inst.currentYear));
+       },
+
+       /* Erase the input field and hide the date picker. */
+       _clearDate: function(id) {
+               var target = $(id);
+               this._selectDate(target, "");
+       },
+
+       /* Update the input field with the selected date. */
+       _selectDate: function(id, dateStr) {
+               var onSelect,
+                       target = $(id),
+                       inst = this._getInst(target[0]);
+
+               dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+               if (inst.input) {
+                       inst.input.val(dateStr);
+               }
+               this._updateAlternate(inst);
+
+               onSelect = this._get(inst, "onSelect");
+               if (onSelect) {
+                       onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
+               } else if (inst.input) {
+                       inst.input.trigger("change"); // fire the change event
+               }
+
+               if (inst.inline){
+                       this._updateDatepicker(inst);
+               } else {
+                       this._hideDatepicker();
+                       this._lastInput = inst.input[0];
+                       if (typeof(inst.input[0]) !== "object") {
+                               inst.input.focus(); // restore focus
+                       }
+                       this._lastInput = null;
+               }
+       },
+
+       /* Update any alternate field to synchronise with the main field. */
+       _updateAlternate: function(inst) {
+               var altFormat, date, dateStr,
+                       altField = this._get(inst, "altField");
+
+               if (altField) { // update alternate field too
+                       altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
+                       date = this._getDate(inst);
+                       dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
+                       $(altField).each(function() { $(this).val(dateStr); });
+               }
+       },
+
+       /* Set as beforeShowDay function to prevent selection of weekends.
+        * @param  date  Date - the date to customise
+        * @return [boolean, string] - is this date selectable?, what is its CSS class?
+        */
+       noWeekends: function(date) {
+               var day = date.getDay();
+               return [(day > 0 && day < 6), ""];
+       },
+
+       /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+        * @param  date  Date - the date to get the week for
+        * @return  number - the number of the week within the year that contains this date
+        */
+       iso8601Week: function(date) {
+               var time,
+                       checkDate = new Date(date.getTime());
+
+               // Find Thursday of this week starting on Monday
+               checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
+
+               time = checkDate.getTime();
+               checkDate.setMonth(0); // Compare with Jan 1
+               checkDate.setDate(1);
+               return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+       },
+
+       /* Parse a string value into a date object.
+        * See formatDate below for the possible formats.
+        *
+        * @param  format string - the expected format of the date
+        * @param  value string - the date in the above format
+        * @param  settings Object - attributes include:
+        *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
+        *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
+        *                                      dayNames                string[7] - names of the days from Sunday (optional)
+        *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
+        *                                      monthNames              string[12] - names of the months (optional)
+        * @return  Date - the extracted date value or null if value is blank
+        */
+       parseDate: function (format, value, settings) {
+               if (format == null || value == null) {
+                       throw "Invalid arguments";
+               }
+
+               value = (typeof value === "object" ? value.toString() : value + "");
+               if (value === "") {
+                       return null;
+               }
+
+               var iFormat, dim, extra,
+                       iValue = 0,
+                       shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
+                       shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
+                               new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
+                       dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
+                       dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
+                       monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
+                       monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
+                       year = -1,
+                       month = -1,
+                       day = -1,
+                       doy = -1,
+                       literal = false,
+                       date,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       },
+                       // Extract a number from the string value
+                       getNumber = function(match) {
+                               var isDoubled = lookAhead(match),
+                                       size = (match === "@" ? 14 : (match === "!" ? 20 :
+                                       (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
+                                       minSize = (match === "y" ? size : 1),
+                                       digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
+                                       num = value.substring(iValue).match(digits);
+                               if (!num) {
+                                       throw "Missing number at position " + iValue;
+                               }
+                               iValue += num[0].length;
+                               return parseInt(num[0], 10);
+                       },
+                       // Extract a name from the string value and convert to an index
+                       getName = function(match, shortNames, longNames) {
+                               var index = -1,
+                                       names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
+                                               return [ [k, v] ];
+                                       }).sort(function (a, b) {
+                                               return -(a[1].length - b[1].length);
+                                       });
+
+                               $.each(names, function (i, pair) {
+                                       var name = pair[1];
+                                       if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
+                                               index = pair[0];
+                                               iValue += name.length;
+                                               return false;
+                                       }
+                               });
+                               if (index !== -1) {
+                                       return index + 1;
+                               } else {
+                                       throw "Unknown name at position " + iValue;
+                               }
+                       },
+                       // Confirm that a literal character matches the string value
+                       checkLiteral = function() {
+                               if (value.charAt(iValue) !== format.charAt(iFormat)) {
+                                       throw "Unexpected literal at position " + iValue;
+                               }
+                               iValue++;
+                       };
+
+               for (iFormat = 0; iFormat < format.length; iFormat++) {
+                       if (literal) {
+                               if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                       literal = false;
+                               } else {
+                                       checkLiteral();
+                               }
+                       } else {
+                               switch (format.charAt(iFormat)) {
+                                       case "d":
+                                               day = getNumber("d");
+                                               break;
+                                       case "D":
+                                               getName("D", dayNamesShort, dayNames);
+                                               break;
+                                       case "o":
+                                               doy = getNumber("o");
+                                               break;
+                                       case "m":
+                                               month = getNumber("m");
+                                               break;
+                                       case "M":
+                                               month = getName("M", monthNamesShort, monthNames);
+                                               break;
+                                       case "y":
+                                               year = getNumber("y");
+                                               break;
+                                       case "@":
+                                               date = new Date(getNumber("@"));
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case "!":
+                                               date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
+                                               year = date.getFullYear();
+                                               month = date.getMonth() + 1;
+                                               day = date.getDate();
+                                               break;
+                                       case "'":
+                                               if (lookAhead("'")){
+                                                       checkLiteral();
+                                               } else {
+                                                       literal = true;
+                                               }
+                                               break;
+                                       default:
+                                               checkLiteral();
+                               }
+                       }
+               }
+
+               if (iValue < value.length){
+                       extra = value.substr(iValue);
+                       if (!/^\s+/.test(extra)) {
+                               throw "Extra/unparsed characters found in date: " + extra;
+                       }
+               }
+
+               if (year === -1) {
+                       year = new Date().getFullYear();
+               } else if (year < 100) {
+                       year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+                               (year <= shortYearCutoff ? 0 : -100);
+               }
+
+               if (doy > -1) {
+                       month = 1;
+                       day = doy;
+                       do {
+                               dim = this._getDaysInMonth(year, month - 1);
+                               if (day <= dim) {
+                                       break;
+                               }
+                               month++;
+                               day -= dim;
+                       } while (true);
+               }
+
+               date = this._daylightSavingAdjust(new Date(year, month - 1, day));
+               if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
+                       throw "Invalid date"; // E.g. 31/02/00
+               }
+               return date;
+       },
+
+       /* Standard date formats. */
+       ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
+       COOKIE: "D, dd M yy",
+       ISO_8601: "yy-mm-dd",
+       RFC_822: "D, d M y",
+       RFC_850: "DD, dd-M-y",
+       RFC_1036: "D, d M y",
+       RFC_1123: "D, d M yy",
+       RFC_2822: "D, d M yy",
+       RSS: "D, d M y", // RFC 822
+       TICKS: "!",
+       TIMESTAMP: "@",
+       W3C: "yy-mm-dd", // ISO 8601
+
+       _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
+               Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
+
+       /* Format a date object into a string value.
+        * The format can be combinations of the following:
+        * d  - day of month (no leading zero)
+        * dd - day of month (two digit)
+        * o  - day of year (no leading zeros)
+        * oo - day of year (three digit)
+        * D  - day name short
+        * DD - day name long
+        * m  - month of year (no leading zero)
+        * mm - month of year (two digit)
+        * M  - month name short
+        * MM - month name long
+        * y  - year (two digit)
+        * yy - year (four digit)
+        * @ - Unix timestamp (ms since 01/01/1970)
+        * ! - Windows ticks (100ns since 01/01/0001)
+        * "..." - literal text
+        * '' - single quote
+        *
+        * @param  format string - the desired format of the date
+        * @param  date Date - the date value to format
+        * @param  settings Object - attributes include:
+        *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
+        *                                      dayNames                string[7] - names of the days from Sunday (optional)
+        *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
+        *                                      monthNames              string[12] - names of the months (optional)
+        * @return  string - the date in the above format
+        */
+       formatDate: function (format, date, settings) {
+               if (!date) {
+                       return "";
+               }
+
+               var iFormat,
+                       dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
+                       dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
+                       monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
+                       monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       },
+                       // Format a number, with leading zero if necessary
+                       formatNumber = function(match, value, len) {
+                               var num = "" + value;
+                               if (lookAhead(match)) {
+                                       while (num.length < len) {
+                                               num = "0" + num;
+                                       }
+                               }
+                               return num;
+                       },
+                       // Format a name, short or long as requested
+                       formatName = function(match, value, shortNames, longNames) {
+                               return (lookAhead(match) ? longNames[value] : shortNames[value]);
+                       },
+                       output = "",
+                       literal = false;
+
+               if (date) {
+                       for (iFormat = 0; iFormat < format.length; iFormat++) {
+                               if (literal) {
+                                       if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                               literal = false;
+                                       } else {
+                                               output += format.charAt(iFormat);
+                                       }
+                               } else {
+                                       switch (format.charAt(iFormat)) {
+                                               case "d":
+                                                       output += formatNumber("d", date.getDate(), 2);
+                                                       break;
+                                               case "D":
+                                                       output += formatName("D", date.getDay(), dayNamesShort, dayNames);
+                                                       break;
+                                               case "o":
+                                                       output += formatNumber("o",
+                                                               Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
+                                                       break;
+                                               case "m":
+                                                       output += formatNumber("m", date.getMonth() + 1, 2);
+                                                       break;
+                                               case "M":
+                                                       output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
+                                                       break;
+                                               case "y":
+                                                       output += (lookAhead("y") ? date.getFullYear() :
+                                                               (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
+                                                       break;
+                                               case "@":
+                                                       output += date.getTime();
+                                                       break;
+                                               case "!":
+                                                       output += date.getTime() * 10000 + this._ticksTo1970;
+                                                       break;
+                                               case "'":
+                                                       if (lookAhead("'")) {
+                                                               output += "'";
+                                                       } else {
+                                                               literal = true;
+                                                       }
+                                                       break;
+                                               default:
+                                                       output += format.charAt(iFormat);
+                                       }
+                               }
+                       }
+               }
+               return output;
+       },
+
+       /* Extract all possible characters from the date format. */
+       _possibleChars: function (format) {
+               var iFormat,
+                       chars = "",
+                       literal = false,
+                       // Check whether a format character is doubled
+                       lookAhead = function(match) {
+                               var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
+                               if (matches) {
+                                       iFormat++;
+                               }
+                               return matches;
+                       };
+
+               for (iFormat = 0; iFormat < format.length; iFormat++) {
+                       if (literal) {
+                               if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
+                                       literal = false;
+                               } else {
+                                       chars += format.charAt(iFormat);
+                               }
+                       } else {
+                               switch (format.charAt(iFormat)) {
+                                       case "d": case "m": case "y": case "@":
+                                               chars += "0123456789";
+                                               break;
+                                       case "D": case "M":
+                                               return null; // Accept anything
+                                       case "'":
+                                               if (lookAhead("'")) {
+                                                       chars += "'";
+                                               } else {
+                                                       literal = true;
+                                               }
+                                               break;
+                                       default:
+                                               chars += format.charAt(iFormat);
+                               }
+                       }
+               }
+               return chars;
+       },
+
+       /* Get a setting value, defaulting if necessary. */
+       _get: function(inst, name) {
+               return inst.settings[name] !== undefined ?
+                       inst.settings[name] : this._defaults[name];
+       },
+
+       /* Parse existing date and initialise date picker. */
+       _setDateFromField: function(inst, noDefault) {
+               if (inst.input.val() === inst.lastVal) {
+                       return;
+               }
+
+               var dateFormat = this._get(inst, "dateFormat"),
+                       dates = inst.lastVal = inst.input ? inst.input.val() : null,
+                       defaultDate = this._getDefaultDate(inst),
+                       date = defaultDate,
+                       settings = this._getFormatConfig(inst);
+
+               try {
+                       date = this.parseDate(dateFormat, dates, settings) || defaultDate;
+               } catch (event) {
+                       dates = (noDefault ? "" : dates);
+               }
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               inst.currentDay = (dates ? date.getDate() : 0);
+               inst.currentMonth = (dates ? date.getMonth() : 0);
+               inst.currentYear = (dates ? date.getFullYear() : 0);
+               this._adjustInstDate(inst);
+       },
+
+       /* Retrieve the default date shown on opening. */
+       _getDefaultDate: function(inst) {
+               return this._restrictMinMax(inst,
+                       this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
+       },
+
+       /* A date may be specified as an exact value or a relative one. */
+       _determineDate: function(inst, date, defaultDate) {
+               var offsetNumeric = function(offset) {
+                               var date = new Date();
+                               date.setDate(date.getDate() + offset);
+                               return date;
+                       },
+                       offsetString = function(offset) {
+                               try {
+                                       return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
+                                               offset, $.datepicker._getFormatConfig(inst));
+                               }
+                               catch (e) {
+                                       // Ignore
+                               }
+
+                               var date = (offset.toLowerCase().match(/^c/) ?
+                                       $.datepicker._getDate(inst) : null) || new Date(),
+                                       year = date.getFullYear(),
+                                       month = date.getMonth(),
+                                       day = date.getDate(),
+                                       pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
+                                       matches = pattern.exec(offset);
+
+                               while (matches) {
+                                       switch (matches[2] || "d") {
+                                               case "d" : case "D" :
+                                                       day += parseInt(matches[1],10); break;
+                                               case "w" : case "W" :
+                                                       day += parseInt(matches[1],10) * 7; break;
+                                               case "m" : case "M" :
+                                                       month += parseInt(matches[1],10);
+                                                       day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                                       break;
+                                               case "y": case "Y" :
+                                                       year += parseInt(matches[1],10);
+                                                       day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+                                                       break;
+                                       }
+                                       matches = pattern.exec(offset);
+                               }
+                               return new Date(year, month, day);
+                       },
+                       newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
+                               (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+
+               newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
+               if (newDate) {
+                       newDate.setHours(0);
+                       newDate.setMinutes(0);
+                       newDate.setSeconds(0);
+                       newDate.setMilliseconds(0);
+               }
+               return this._daylightSavingAdjust(newDate);
+       },
+
+       /* Handle switch to/from daylight saving.
+        * Hours may be non-zero on daylight saving cut-over:
+        * > 12 when midnight changeover, but then cannot generate
+        * midnight datetime, so jump to 1AM, otherwise reset.
+        * @param  date  (Date) the date to check
+        * @return  (Date) the corrected date
+        */
+       _daylightSavingAdjust: function(date) {
+               if (!date) {
+                       return null;
+               }
+               date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
+               return date;
+       },
+
+       /* Set the date(s) directly. */
+       _setDate: function(inst, date, noChange) {
+               var clear = !date,
+                       origMonth = inst.selectedMonth,
+                       origYear = inst.selectedYear,
+                       newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
+
+               inst.selectedDay = inst.currentDay = newDate.getDate();
+               inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+               inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+               if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
+                       this._notifyChange(inst);
+               }
+               this._adjustInstDate(inst);
+               if (inst.input) {
+                       inst.input.val(clear ? "" : this._formatDate(inst));
+               }
+       },
+
+       /* Retrieve the date(s) directly. */
+       _getDate: function(inst) {
+               var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
+                       this._daylightSavingAdjust(new Date(
+                       inst.currentYear, inst.currentMonth, inst.currentDay)));
+                       return startDate;
+       },
+
+       /* Attach the onxxx handlers.  These are declared statically so
+        * they work with static code transformers like Caja.
+        */
+       _attachHandlers: function(inst) {
+               var stepMonths = this._get(inst, "stepMonths"),
+                       id = "#" + inst.id.replace( /\\\\/g, "\\" );
+               inst.dpDiv.find("[data-handler]").map(function () {
+                       var handler = {
+                               prev: function () {
+                                       $.datepicker._adjustDate(id, -stepMonths, "M");
+                               },
+                               next: function () {
+                                       $.datepicker._adjustDate(id, +stepMonths, "M");
+                               },
+                               hide: function () {
+                                       $.datepicker._hideDatepicker();
+                               },
+                               today: function () {
+                                       $.datepicker._gotoToday(id);
+                               },
+                               selectDay: function () {
+                                       $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
+                                       return false;
+                               },
+                               selectMonth: function () {
+                                       $.datepicker._selectMonthYear(id, this, "M");
+                                       return false;
+                               },
+                               selectYear: function () {
+                                       $.datepicker._selectMonthYear(id, this, "Y");
+                                       return false;
+                               }
+                       };
+                       $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
+               });
+       },
+
+       /* Generate the HTML for the current state of the date picker. */
+       _generateHTML: function(inst) {
+               var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
+                       controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
+                       monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
+                       selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
+                       cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
+                       printDate, dRow, tbody, daySettings, otherMonth, unselectable,
+                       tempDate = new Date(),
+                       today = this._daylightSavingAdjust(
+                               new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
+                       isRTL = this._get(inst, "isRTL"),
+                       showButtonPanel = this._get(inst, "showButtonPanel"),
+                       hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
+                       navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
+                       numMonths = this._getNumberOfMonths(inst),
+                       showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
+                       stepMonths = this._get(inst, "stepMonths"),
+                       isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
+                       currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
+                               new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
+                       minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       drawMonth = inst.drawMonth - showCurrentAtPos,
+                       drawYear = inst.drawYear;
+
+               if (drawMonth < 0) {
+                       drawMonth += 12;
+                       drawYear--;
+               }
+               if (maxDate) {
+                       maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
+                               maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
+                       maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+                       while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
+                               drawMonth--;
+                               if (drawMonth < 0) {
+                                       drawMonth = 11;
+                                       drawYear--;
+                               }
+                       }
+               }
+               inst.drawMonth = drawMonth;
+               inst.drawYear = drawYear;
+
+               prevText = this._get(inst, "prevText");
+               prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+
+               prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
+                       "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
+                       " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
+                       (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
+
+               nextText = this._get(inst, "nextText");
+               nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
+                       this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
+                       this._getFormatConfig(inst)));
+
+               next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+                       "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
+                       " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
+                       (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
+
+               currentText = this._get(inst, "currentText");
+               gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
+               currentText = (!navigationAsDateFormat ? currentText :
+                       this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
+
+               controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
+                       this._get(inst, "closeText") + "</button>" : "");
+
+               buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
+                       (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
+                       ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
+
+               firstDay = parseInt(this._get(inst, "firstDay"),10);
+               firstDay = (isNaN(firstDay) ? 0 : firstDay);
+
+               showWeek = this._get(inst, "showWeek");
+               dayNames = this._get(inst, "dayNames");
+               dayNamesMin = this._get(inst, "dayNamesMin");
+               monthNames = this._get(inst, "monthNames");
+               monthNamesShort = this._get(inst, "monthNamesShort");
+               beforeShowDay = this._get(inst, "beforeShowDay");
+               showOtherMonths = this._get(inst, "showOtherMonths");
+               selectOtherMonths = this._get(inst, "selectOtherMonths");
+               defaultDate = this._getDefaultDate(inst);
+               html = "";
+               dow;
+               for (row = 0; row < numMonths[0]; row++) {
+                       group = "";
+                       this.maxRows = 4;
+                       for (col = 0; col < numMonths[1]; col++) {
+                               selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
+                               cornerClass = " ui-corner-all";
+                               calender = "";
+                               if (isMultiMonth) {
+                                       calender += "<div class='ui-datepicker-group";
+                                       if (numMonths[1] > 1) {
+                                               switch (col) {
+                                                       case 0: calender += " ui-datepicker-group-first";
+                                                               cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
+                                                       case numMonths[1]-1: calender += " ui-datepicker-group-last";
+                                                               cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
+                                                       default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
+                                               }
+                                       }
+                                       calender += "'>";
+                               }
+                               calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
+                                       (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
+                                       (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
+                                       this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+                                       row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
+                                       "</div><table class='ui-datepicker-calendar'><thead>" +
+                                       "<tr>";
+                               thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
+                               for (dow = 0; dow < 7; dow++) { // days of the week
+                                       day = (dow + firstDay) % 7;
+                                       thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
+                                               "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
+                               }
+                               calender += thead + "</tr></thead><tbody>";
+                               daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+                               if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
+                                       inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+                               }
+                               leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+                               curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
+                               numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
+                               this.maxRows = numRows;
+                               printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
+                               for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+                                       calender += "<tr>";
+                                       tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
+                                               this._get(inst, "calculateWeek")(printDate) + "</td>");
+                                       for (dow = 0; dow < 7; dow++) { // create date picker days
+                                               daySettings = (beforeShowDay ?
+                                                       beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
+                                               otherMonth = (printDate.getMonth() !== drawMonth);
+                                               unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
+                                                       (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+                                               tbody += "<td class='" +
+                                                       ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
+                                                       (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
+                                                       ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
+                                                       (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
+                                                       // or defaultDate is current printedDate and defaultDate is selectedDate
+                                                       " " + this._dayOverClass : "") + // highlight selected day
+                                                       (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
+                                                       (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
+                                                       (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
+                                                       (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
+                                                       ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
+                                                       (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
+                                                       (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
+                                                       (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
+                                                       (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
+                                                       (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
+                                                       (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
+                                                       "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
+                                               printDate.setDate(printDate.getDate() + 1);
+                                               printDate = this._daylightSavingAdjust(printDate);
+                                       }
+                                       calender += tbody + "</tr>";
+                               }
+                               drawMonth++;
+                               if (drawMonth > 11) {
+                                       drawMonth = 0;
+                                       drawYear++;
+                               }
+                               calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
+                                                       ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
+                               group += calender;
+                       }
+                       html += group;
+               }
+               html += buttonPanel;
+               inst._keyEvent = false;
+               return html;
+       },
+
+       /* Generate the month and year header. */
+       _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+                       secondary, monthNames, monthNamesShort) {
+
+               var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
+                       changeMonth = this._get(inst, "changeMonth"),
+                       changeYear = this._get(inst, "changeYear"),
+                       showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
+                       html = "<div class='ui-datepicker-title'>",
+                       monthHtml = "";
+
+               // month selection
+               if (secondary || !changeMonth) {
+                       monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
+               } else {
+                       inMinYear = (minDate && minDate.getFullYear() === drawYear);
+                       inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
+                       monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
+                       for ( month = 0; month < 12; month++) {
+                               if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
+                                       monthHtml += "<option value='" + month + "'" +
+                                               (month === drawMonth ? " selected='selected'" : "") +
+                                               ">" + monthNamesShort[month] + "</option>";
+                               }
+                       }
+                       monthHtml += "</select>";
+               }
+
+               if (!showMonthAfterYear) {
+                       html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
+               }
+
+               // year selection
+               if ( !inst.yearshtml ) {
+                       inst.yearshtml = "";
+                       if (secondary || !changeYear) {
+                               html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
+                       } else {
+                               // determine range of years to display
+                               years = this._get(inst, "yearRange").split(":");
+                               thisYear = new Date().getFullYear();
+                               determineYear = function(value) {
+                                       var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+                                               (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
+                                               parseInt(value, 10)));
+                                       return (isNaN(year) ? thisYear : year);
+                               };
+                               year = determineYear(years[0]);
+                               endYear = Math.max(year, determineYear(years[1] || ""));
+                               year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+                               endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+                               inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
+                               for (; year <= endYear; year++) {
+                                       inst.yearshtml += "<option value='" + year + "'" +
+                                               (year === drawYear ? " selected='selected'" : "") +
+                                               ">" + year + "</option>";
+                               }
+                               inst.yearshtml += "</select>";
+
+                               html += inst.yearshtml;
+                               inst.yearshtml = null;
+                       }
+               }
+
+               html += this._get(inst, "yearSuffix");
+               if (showMonthAfterYear) {
+                       html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
+               }
+               html += "</div>"; // Close datepicker_header
+               return html;
+       },
+
+       /* Adjust one of the date sub-fields. */
+       _adjustInstDate: function(inst, offset, period) {
+               var year = inst.drawYear + (period === "Y" ? offset : 0),
+                       month = inst.drawMonth + (period === "M" ? offset : 0),
+                       day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
+                       date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
+
+               inst.selectedDay = date.getDate();
+               inst.drawMonth = inst.selectedMonth = date.getMonth();
+               inst.drawYear = inst.selectedYear = date.getFullYear();
+               if (period === "M" || period === "Y") {
+                       this._notifyChange(inst);
+               }
+       },
+
+       /* Ensure a date is within any min/max bounds. */
+       _restrictMinMax: function(inst, date) {
+               var minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       newDate = (minDate && date < minDate ? minDate : date);
+               return (maxDate && newDate > maxDate ? maxDate : newDate);
+       },
+
+       /* Notify change of month/year. */
+       _notifyChange: function(inst) {
+               var onChange = this._get(inst, "onChangeMonthYear");
+               if (onChange) {
+                       onChange.apply((inst.input ? inst.input[0] : null),
+                               [inst.selectedYear, inst.selectedMonth + 1, inst]);
+               }
+       },
+
+       /* Determine the number of months to show. */
+       _getNumberOfMonths: function(inst) {
+               var numMonths = this._get(inst, "numberOfMonths");
+               return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
+       },
+
+       /* Determine the current maximum date - ensure no time components are set. */
+       _getMinMaxDate: function(inst, minMax) {
+               return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
+       },
+
+       /* Find the number of days in a given month. */
+       _getDaysInMonth: function(year, month) {
+               return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
+       },
+
+       /* Find the day of the week of the first of a month. */
+       _getFirstDayOfMonth: function(year, month) {
+               return new Date(year, month, 1).getDay();
+       },
+
+       /* Determines if we should allow a "next/prev" month display change. */
+       _canAdjustMonth: function(inst, offset, curYear, curMonth) {
+               var numMonths = this._getNumberOfMonths(inst),
+                       date = this._daylightSavingAdjust(new Date(curYear,
+                       curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
+
+               if (offset < 0) {
+                       date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+               }
+               return this._isInRange(inst, date);
+       },
+
+       /* Is the given date in the accepted range? */
+       _isInRange: function(inst, date) {
+               var yearSplit, currentYear,
+                       minDate = this._getMinMaxDate(inst, "min"),
+                       maxDate = this._getMinMaxDate(inst, "max"),
+                       minYear = null,
+                       maxYear = null,
+                       years = this._get(inst, "yearRange");
+                       if (years){
+                               yearSplit = years.split(":");
+                               currentYear = new Date().getFullYear();
+                               minYear = parseInt(yearSplit[0], 10);
+                               maxYear = parseInt(yearSplit[1], 10);
+                               if ( yearSplit[0].match(/[+\-].*/) ) {
+                                       minYear += currentYear;
+                               }
+                               if ( yearSplit[1].match(/[+\-].*/) ) {
+                                       maxYear += currentYear;
+                               }
+                       }
+
+               return ((!minDate || date.getTime() >= minDate.getTime()) &&
+                       (!maxDate || date.getTime() <= maxDate.getTime()) &&
+                       (!minYear || date.getFullYear() >= minYear) &&
+                       (!maxYear || date.getFullYear() <= maxYear));
+       },
+
+       /* Provide the configuration settings for formatting/parsing. */
+       _getFormatConfig: function(inst) {
+               var shortYearCutoff = this._get(inst, "shortYearCutoff");
+               shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
+                       new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+               return {shortYearCutoff: shortYearCutoff,
+                       dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
+                       monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
+       },
+
+       /* Format the given date for display. */
+       _formatDate: function(inst, day, month, year) {
+               if (!day) {
+                       inst.currentDay = inst.selectedDay;
+                       inst.currentMonth = inst.selectedMonth;
+                       inst.currentYear = inst.selectedYear;
+               }
+               var date = (day ? (typeof day === "object" ? day :
+                       this._daylightSavingAdjust(new Date(year, month, day))) :
+                       this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+               return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
+       }
+});
+
+/*
+ * Bind hover events for datepicker elements.
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
+ * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
+ */
+function datepicker_bindHover(dpDiv) {
+       var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
+       return dpDiv.delegate(selector, "mouseout", function() {
+                       $(this).removeClass("ui-state-hover");
+                       if (this.className.indexOf("ui-datepicker-prev") !== -1) {
+                               $(this).removeClass("ui-datepicker-prev-hover");
+                       }
+                       if (this.className.indexOf("ui-datepicker-next") !== -1) {
+                               $(this).removeClass("ui-datepicker-next-hover");
+                       }
+               })
+               .delegate( selector, "mouseover", datepicker_handleMouseover );
+}
+
+function datepicker_handleMouseover() {
+       if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
+               $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
+               $(this).addClass("ui-state-hover");
+               if (this.className.indexOf("ui-datepicker-prev") !== -1) {
+                       $(this).addClass("ui-datepicker-prev-hover");
+               }
+               if (this.className.indexOf("ui-datepicker-next") !== -1) {
+                       $(this).addClass("ui-datepicker-next-hover");
+               }
+       }
+}
+
+/* jQuery extend now ignores nulls! */
+function datepicker_extendRemove(target, props) {
+       $.extend(target, props);
+       for (var name in props) {
+               if (props[name] == null) {
+                       target[name] = props[name];
+               }
+       }
+       return target;
+}
+
+/* Invoke the datepicker functionality.
+   @param  options  string - a command, optionally followed by additional parameters or
+                                       Object - settings for attaching new datepicker functionality
+   @return  jQuery object */
+$.fn.datepicker = function(options){
+
+       /* Verify an empty collection wasn't passed - Fixes #6976 */
+       if ( !this.length ) {
+               return this;
+       }
+
+       /* Initialise the date picker. */
+       if (!$.datepicker.initialized) {
+               $(document).mousedown($.datepicker._checkExternalClick);
+               $.datepicker.initialized = true;
+       }
+
+       /* Append datepicker main container to body if not exist. */
+       if ($("#"+$.datepicker._mainDivId).length === 0) {
+               $("body").append($.datepicker.dpDiv);
+       }
+
+       var otherArgs = Array.prototype.slice.call(arguments, 1);
+       if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
+               return $.datepicker["_" + options + "Datepicker"].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       }
+       if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
+               return $.datepicker["_" + options + "Datepicker"].
+                       apply($.datepicker, [this[0]].concat(otherArgs));
+       }
+       return this.each(function() {
+               typeof options === "string" ?
+                       $.datepicker["_" + options + "Datepicker"].
+                               apply($.datepicker, [this].concat(otherArgs)) :
+                       $.datepicker._attachDatepicker(this, options);
+       });
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.11.3";
+
+var datepicker = $.datepicker;
+
+
+/*!
+ * jQuery UI Draggable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/draggable/
+ */
+
+
+$.widget("ui.draggable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "drag",
+       options: {
+               addClasses: true,
+               appendTo: "parent",
+               axis: false,
+               connectToSortable: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               iframeFix: false,
+               opacity: false,
+               refreshPositions: false,
+               revert: false,
+               revertDuration: 500,
+               scope: "default",
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               snap: false,
+               snapMode: "both",
+               snapTolerance: 20,
+               stack: false,
+               zIndex: false,
+
+               // callbacks
+               drag: null,
+               start: null,
+               stop: null
+       },
+       _create: function() {
+
+               if ( this.options.helper === "original" ) {
+                       this._setPositionRelative();
+               }
+               if (this.options.addClasses){
+                       this.element.addClass("ui-draggable");
+               }
+               if (this.options.disabled){
+                       this.element.addClass("ui-draggable-disabled");
+               }
+               this._setHandleClassName();
+
+               this._mouseInit();
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+               if ( key === "handle" ) {
+                       this._removeHandleClassName();
+                       this._setHandleClassName();
+               }
+       },
+
+       _destroy: function() {
+               if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
+                       this.destroyOnClear = true;
+                       return;
+               }
+               this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
+               this._removeHandleClassName();
+               this._mouseDestroy();
+       },
+
+       _mouseCapture: function(event) {
+               var o = this.options;
+
+               this._blurActiveElement( event );
+
+               // among others, prevent a drag on a resizable-handle
+               if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
+                       return false;
+               }
+
+               //Quit if we're not on a valid handle
+               this.handle = this._getHandle(event);
+               if (!this.handle) {
+                       return false;
+               }
+
+               this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
+
+               return true;
+
+       },
+
+       _blockFrames: function( selector ) {
+               this.iframeBlocks = this.document.find( selector ).map(function() {
+                       var iframe = $( this );
+
+                       return $( "<div>" )
+                               .css( "position", "absolute" )
+                               .appendTo( iframe.parent() )
+                               .outerWidth( iframe.outerWidth() )
+                               .outerHeight( iframe.outerHeight() )
+                               .offset( iframe.offset() )[ 0 ];
+               });
+       },
+
+       _unblockFrames: function() {
+               if ( this.iframeBlocks ) {
+                       this.iframeBlocks.remove();
+                       delete this.iframeBlocks;
+               }
+       },
+
+       _blurActiveElement: function( event ) {
+               var document = this.document[ 0 ];
+
+               // Only need to blur if the event occurred on the draggable itself, see #10527
+               if ( !this.handleElement.is( event.target ) ) {
+                       return;
+               }
+
+               // support: IE9
+               // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+               try {
+
+                       // Support: IE9, IE10
+                       // If the <body> is blurred, IE will switch windows, see #9520
+                       if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
+
+                               // Blur any element that currently has focus, see #4261
+                               $( document.activeElement ).blur();
+                       }
+               } catch ( error ) {}
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options;
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               this.helper.addClass("ui-draggable-dragging");
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               //If ddmanager is used for droppables, set the global draggable
+               if ($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Store the helper's css position
+               this.cssPosition = this.helper.css( "position" );
+               this.scrollParent = this.helper.scrollParent( true );
+               this.offsetParent = this.helper.offsetParent();
+               this.hasFixedAncestor = this.helper.parents().filter(function() {
+                               return $( this ).css( "position" ) === "fixed";
+                       }).length > 0;
+
+               //The element's absolute position on the page minus margins
+               this.positionAbs = this.element.offset();
+               this._refreshOffsets( event );
+
+               //Generate the original position
+               this.originalPosition = this.position = this._generatePosition( event, false );
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Set a containment if given in the options
+               this._setContainment();
+
+               //Trigger event + callbacks
+               if (this._trigger("start", event) === false) {
+                       this._clear();
+                       return false;
+               }
+
+               //Recache the helper size
+               this._cacheHelperProportions();
+
+               //Prepare the droppable offsets
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               // Reset helper's right/bottom css if they're set and set explicit width/height instead
+               // as this prevents resizing of elements with right/bottom set (see #7772)
+               this._normalizeRightBottom();
+
+               this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+               if ( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStart(this, event);
+               }
+
+               return true;
+       },
+
+       _refreshOffsets: function( event ) {
+               this.offset = {
+                       top: this.positionAbs.top - this.margins.top,
+                       left: this.positionAbs.left - this.margins.left,
+                       scroll: false,
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset()
+               };
+
+               this.offset.click = {
+                       left: event.pageX - this.offset.left,
+                       top: event.pageY - this.offset.top
+               };
+       },
+
+       _mouseDrag: function(event, noPropagation) {
+               // reset any necessary cached properties (see #5009)
+               if ( this.hasFixedAncestor ) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               //Compute the helpers position
+               this.position = this._generatePosition( event, true );
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Call plugins and callbacks and use the resulting position if something is returned
+               if (!noPropagation) {
+                       var ui = this._uiHash();
+                       if (this._trigger("drag", event, ui) === false) {
+                               this._mouseUp({});
+                               return false;
+                       }
+                       this.position = ui.position;
+               }
+
+               this.helper[ 0 ].style.left = this.position.left + "px";
+               this.helper[ 0 ].style.top = this.position.top + "px";
+
+               if ($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               //If we are using droppables, inform the manager about the drop
+               var that = this,
+                       dropped = false;
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       dropped = $.ui.ddmanager.drop(this, event);
+               }
+
+               //if a drop comes from outside (a sortable)
+               if (this.dropped) {
+                       dropped = this.dropped;
+                       this.dropped = false;
+               }
+
+               if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+                       $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+                               if (that._trigger("stop", event) !== false) {
+                                       that._clear();
+                               }
+                       });
+               } else {
+                       if (this._trigger("stop", event) !== false) {
+                               this._clear();
+                       }
+               }
+
+               return false;
+       },
+
+       _mouseUp: function( event ) {
+               this._unblockFrames();
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+               if ( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStop(this, event);
+               }
+
+               // Only need to focus if the event occurred on the draggable itself, see #10527
+               if ( this.handleElement.is( event.target ) ) {
+                       // The interaction is over; whether or not the click resulted in a drag, focus the element
+                       this.element.focus();
+               }
+
+               return $.ui.mouse.prototype._mouseUp.call(this, event);
+       },
+
+       cancel: function() {
+
+               if (this.helper.is(".ui-draggable-dragging")) {
+                       this._mouseUp({});
+               } else {
+                       this._clear();
+               }
+
+               return this;
+
+       },
+
+       _getHandle: function(event) {
+               return this.options.handle ?
+                       !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
+                       true;
+       },
+
+       _setHandleClassName: function() {
+               this.handleElement = this.options.handle ?
+                       this.element.find( this.options.handle ) : this.element;
+               this.handleElement.addClass( "ui-draggable-handle" );
+       },
+
+       _removeHandleClassName: function() {
+               this.handleElement.removeClass( "ui-draggable-handle" );
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helperIsFunction = $.isFunction( o.helper ),
+                       helper = helperIsFunction ?
+                               $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
+                               ( o.helper === "clone" ?
+                                       this.element.clone().removeAttr( "id" ) :
+                                       this.element );
+
+               if (!helper.parents("body").length) {
+                       helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
+               }
+
+               // http://bugs.jqueryui.com/ticket/9446
+               // a helper function can return the original element
+               // which wouldn't have been set to relative in _create
+               if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
+                       this._setPositionRelative();
+               }
+
+               if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
+                       helper.css("position", "absolute");
+               }
+
+               return helper;
+
+       },
+
+       _setPositionRelative: function() {
+               if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
+                       this.element[ 0 ].style.position = "relative";
+               }
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = { left: +obj[0], top: +obj[1] || 0 };
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _isRootNode: function( element ) {
+               return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
+       },
+
+       _getParentOffset: function() {
+
+               //Get the offsetParent and cache its position
+               var po = this.offsetParent.offset(),
+                       document = this.document[ 0 ];
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+               if ( this.cssPosition !== "relative" ) {
+                       return { top: 0, left: 0 };
+               }
+
+               var p = this.element.position(),
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+               return {
+                       top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+                       left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+               };
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.element.css("marginLeft"), 10) || 0),
+                       top: (parseInt(this.element.css("marginTop"), 10) || 0),
+                       right: (parseInt(this.element.css("marginRight"), 10) || 0),
+                       bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var isUserScrollable, c, ce,
+                       o = this.options,
+                       document = this.document[ 0 ];
+
+               this.relativeContainer = null;
+
+               if ( !o.containment ) {
+                       this.containment = null;
+                       return;
+               }
+
+               if ( o.containment === "window" ) {
+                       this.containment = [
+                               $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+                               $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+                               $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
+                               $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+                       ];
+                       return;
+               }
+
+               if ( o.containment === "document") {
+                       this.containment = [
+                               0,
+                               0,
+                               $( document ).width() - this.helperProportions.width - this.margins.left,
+                               ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+                       ];
+                       return;
+               }
+
+               if ( o.containment.constructor === Array ) {
+                       this.containment = o.containment;
+                       return;
+               }
+
+               if ( o.containment === "parent" ) {
+                       o.containment = this.helper[ 0 ].parentNode;
+               }
+
+               c = $( o.containment );
+               ce = c[ 0 ];
+
+               if ( !ce ) {
+                       return;
+               }
+
+               isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
+
+               this.containment = [
+                       ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
+                       ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
+                       ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
+                               ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
+                               ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
+                               this.helperProportions.width -
+                               this.margins.left -
+                               this.margins.right,
+                       ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
+                               ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
+                               ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
+                               this.helperProportions.height -
+                               this.margins.top -
+                               this.margins.bottom
+               ];
+               this.relativeContainer = c;
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if (!pos) {
+                       pos = this.position;
+               }
+
+               var mod = d === "absolute" ? 1 : -1,
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function( event, constrainPosition ) {
+
+               var containment, co, top, left,
+                       o = this.options,
+                       scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
+                       pageX = event.pageX,
+                       pageY = event.pageY;
+
+               // Cache the scroll
+               if ( !scrollIsRootNode || !this.offset.scroll ) {
+                       this.offset.scroll = {
+                               top: this.scrollParent.scrollTop(),
+                               left: this.scrollParent.scrollLeft()
+                       };
+               }
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               // If we are not dragging yet, we won't check for options
+               if ( constrainPosition ) {
+                       if ( this.containment ) {
+                               if ( this.relativeContainer ){
+                                       co = this.relativeContainer.offset();
+                                       containment = [
+                                               this.containment[ 0 ] + co.left,
+                                               this.containment[ 1 ] + co.top,
+                                               this.containment[ 2 ] + co.left,
+                                               this.containment[ 3 ] + co.top
+                                       ];
+                               } else {
+                                       containment = this.containment;
+                               }
+
+                               if (event.pageX - this.offset.click.left < containment[0]) {
+                                       pageX = containment[0] + this.offset.click.left;
+                               }
+                               if (event.pageY - this.offset.click.top < containment[1]) {
+                                       pageY = containment[1] + this.offset.click.top;
+                               }
+                               if (event.pageX - this.offset.click.left > containment[2]) {
+                                       pageX = containment[2] + this.offset.click.left;
+                               }
+                               if (event.pageY - this.offset.click.top > containment[3]) {
+                                       pageY = containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if (o.grid) {
+                               //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+                               top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+                               pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+                               pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+                       if ( o.axis === "y" ) {
+                               pageX = this.originalPageX;
+                       }
+
+                       if ( o.axis === "x" ) {
+                               pageY = this.originalPageY;
+                       }
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.top   -                                                                                               // Click offset (relative to the element)
+                               this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+                       ),
+                       left: (
+                               pageX -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+                       )
+               };
+
+       },
+
+       _clear: function() {
+               this.helper.removeClass("ui-draggable-dragging");
+               if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
+                       this.helper.remove();
+               }
+               this.helper = null;
+               this.cancelHelperRemoval = false;
+               if ( this.destroyOnClear ) {
+                       this.destroy();
+               }
+       },
+
+       _normalizeRightBottom: function() {
+               if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
+                       this.helper.width( this.helper.width() );
+                       this.helper.css( "right", "auto" );
+               }
+               if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
+                       this.helper.height( this.helper.height() );
+                       this.helper.css( "bottom", "auto" );
+               }
+       },
+
+       // From now on bulk stuff - mainly helpers
+
+       _trigger: function( type, event, ui ) {
+               ui = ui || this._uiHash();
+               $.ui.plugin.call( this, type, [ event, ui, this ], true );
+
+               // Absolute position and offset (see #6884 ) have to be recalculated after plugins
+               if ( /^(drag|start|stop)/.test( type ) ) {
+                       this.positionAbs = this._convertPositionTo( "absolute" );
+                       ui.offset = this.positionAbs;
+               }
+               return $.Widget.prototype._trigger.call( this, type, event, ui );
+       },
+
+       plugins: {},
+
+       _uiHash: function() {
+               return {
+                       helper: this.helper,
+                       position: this.position,
+                       originalPosition: this.originalPosition,
+                       offset: this.positionAbs
+               };
+       }
+
+});
+
+$.ui.plugin.add( "draggable", "connectToSortable", {
+       start: function( event, ui, draggable ) {
+               var uiSortable = $.extend( {}, ui, {
+                       item: draggable.element
+               });
+
+               draggable.sortables = [];
+               $( draggable.options.connectToSortable ).each(function() {
+                       var sortable = $( this ).sortable( "instance" );
+
+                       if ( sortable && !sortable.options.disabled ) {
+                               draggable.sortables.push( sortable );
+
+                               // refreshPositions is called at drag start to refresh the containerCache
+                               // which is used in drag. This ensures it's initialized and synchronized
+                               // with any changes that might have happened on the page since initialization.
+                               sortable.refreshPositions();
+                               sortable._trigger("activate", event, uiSortable);
+                       }
+               });
+       },
+       stop: function( event, ui, draggable ) {
+               var uiSortable = $.extend( {}, ui, {
+                       item: draggable.element
+               });
+
+               draggable.cancelHelperRemoval = false;
+
+               $.each( draggable.sortables, function() {
+                       var sortable = this;
+
+                       if ( sortable.isOver ) {
+                               sortable.isOver = 0;
+
+                               // Allow this sortable to handle removing the helper
+                               draggable.cancelHelperRemoval = true;
+                               sortable.cancelHelperRemoval = false;
+
+                               // Use _storedCSS To restore properties in the sortable,
+                               // as this also handles revert (#9675) since the draggable
+                               // may have modified them in unexpected ways (#8809)
+                               sortable._storedCSS = {
+                                       position: sortable.placeholder.css( "position" ),
+                                       top: sortable.placeholder.css( "top" ),
+                                       left: sortable.placeholder.css( "left" )
+                               };
+
+                               sortable._mouseStop(event);
+
+                               // Once drag has ended, the sortable should return to using
+                               // its original helper, not the shared helper from draggable
+                               sortable.options.helper = sortable.options._helper;
+                       } else {
+                               // Prevent this Sortable from removing the helper.
+                               // However, don't set the draggable to remove the helper
+                               // either as another connected Sortable may yet handle the removal.
+                               sortable.cancelHelperRemoval = true;
+
+                               sortable._trigger( "deactivate", event, uiSortable );
+                       }
+               });
+       },
+       drag: function( event, ui, draggable ) {
+               $.each( draggable.sortables, function() {
+                       var innermostIntersecting = false,
+                               sortable = this;
+
+                       // Copy over variables that sortable's _intersectsWith uses
+                       sortable.positionAbs = draggable.positionAbs;
+                       sortable.helperProportions = draggable.helperProportions;
+                       sortable.offset.click = draggable.offset.click;
+
+                       if ( sortable._intersectsWith( sortable.containerCache ) ) {
+                               innermostIntersecting = true;
+
+                               $.each( draggable.sortables, function() {
+                                       // Copy over variables that sortable's _intersectsWith uses
+                                       this.positionAbs = draggable.positionAbs;
+                                       this.helperProportions = draggable.helperProportions;
+                                       this.offset.click = draggable.offset.click;
+
+                                       if ( this !== sortable &&
+                                                       this._intersectsWith( this.containerCache ) &&
+                                                       $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
+                                               innermostIntersecting = false;
+                                       }
+
+                                       return innermostIntersecting;
+                               });
+                       }
+
+                       if ( innermostIntersecting ) {
+                               // If it intersects, we use a little isOver variable and set it once,
+                               // so that the move-in stuff gets fired only once.
+                               if ( !sortable.isOver ) {
+                                       sortable.isOver = 1;
+
+                                       sortable.currentItem = ui.helper
+                                               .appendTo( sortable.element )
+                                               .data( "ui-sortable-item", true );
+
+                                       // Store helper option to later restore it
+                                       sortable.options._helper = sortable.options.helper;
+
+                                       sortable.options.helper = function() {
+                                               return ui.helper[ 0 ];
+                                       };
+
+                                       // Fire the start events of the sortable with our passed browser event,
+                                       // and our own helper (so it doesn't create a new one)
+                                       event.target = sortable.currentItem[ 0 ];
+                                       sortable._mouseCapture( event, true );
+                                       sortable._mouseStart( event, true, true );
+
+                                       // Because the browser event is way off the new appended portlet,
+                                       // modify necessary variables to reflect the changes
+                                       sortable.offset.click.top = draggable.offset.click.top;
+                                       sortable.offset.click.left = draggable.offset.click.left;
+                                       sortable.offset.parent.left -= draggable.offset.parent.left -
+                                               sortable.offset.parent.left;
+                                       sortable.offset.parent.top -= draggable.offset.parent.top -
+                                               sortable.offset.parent.top;
+
+                                       draggable._trigger( "toSortable", event );
+
+                                       // Inform draggable that the helper is in a valid drop zone,
+                                       // used solely in the revert option to handle "valid/invalid".
+                                       draggable.dropped = sortable.element;
+
+                                       // Need to refreshPositions of all sortables in the case that
+                                       // adding to one sortable changes the location of the other sortables (#9675)
+                                       $.each( draggable.sortables, function() {
+                                               this.refreshPositions();
+                                       });
+
+                                       // hack so receive/update callbacks work (mostly)
+                                       draggable.currentItem = draggable.element;
+                                       sortable.fromOutside = draggable;
+                               }
+
+                               if ( sortable.currentItem ) {
+                                       sortable._mouseDrag( event );
+                                       // Copy the sortable's position because the draggable's can potentially reflect
+                                       // a relative position, while sortable is always absolute, which the dragged
+                                       // element has now become. (#8809)
+                                       ui.position = sortable.position;
+                               }
+                       } else {
+                               // If it doesn't intersect with the sortable, and it intersected before,
+                               // we fake the drag stop of the sortable, but make sure it doesn't remove
+                               // the helper by using cancelHelperRemoval.
+                               if ( sortable.isOver ) {
+
+                                       sortable.isOver = 0;
+                                       sortable.cancelHelperRemoval = true;
+
+                                       // Calling sortable's mouseStop would trigger a revert,
+                                       // so revert must be temporarily false until after mouseStop is called.
+                                       sortable.options._revert = sortable.options.revert;
+                                       sortable.options.revert = false;
+
+                                       sortable._trigger( "out", event, sortable._uiHash( sortable ) );
+                                       sortable._mouseStop( event, true );
+
+                                       // restore sortable behaviors that were modfied
+                                       // when the draggable entered the sortable area (#9481)
+                                       sortable.options.revert = sortable.options._revert;
+                                       sortable.options.helper = sortable.options._helper;
+
+                                       if ( sortable.placeholder ) {
+                                               sortable.placeholder.remove();
+                                       }
+
+                                       // Recalculate the draggable's offset considering the sortable
+                                       // may have modified them in unexpected ways (#8809)
+                                       draggable._refreshOffsets( event );
+                                       ui.position = draggable._generatePosition( event, true );
+
+                                       draggable._trigger( "fromSortable", event );
+
+                                       // Inform draggable that the helper is no longer in a valid drop zone
+                                       draggable.dropped = false;
+
+                                       // Need to refreshPositions of all sortables just in case removing
+                                       // from one sortable changes the location of other sortables (#9675)
+                                       $.each( draggable.sortables, function() {
+                                               this.refreshPositions();
+                                       });
+                               }
+                       }
+               });
+       }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+       start: function( event, ui, instance ) {
+               var t = $( "body" ),
+                       o = instance.options;
+
+               if (t.css("cursor")) {
+                       o._cursor = t.css("cursor");
+               }
+               t.css("cursor", o.cursor);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+               if (o._cursor) {
+                       $("body").css("cursor", o._cursor);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+       start: function( event, ui, instance ) {
+               var t = $( ui.helper ),
+                       o = instance.options;
+               if (t.css("opacity")) {
+                       o._opacity = t.css("opacity");
+               }
+               t.css("opacity", o.opacity);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+               if (o._opacity) {
+                       $(ui.helper).css("opacity", o._opacity);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+       start: function( event, ui, i ) {
+               if ( !i.scrollParentNotHidden ) {
+                       i.scrollParentNotHidden = i.helper.scrollParent( false );
+               }
+
+               if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
+                       i.overflowOffset = i.scrollParentNotHidden.offset();
+               }
+       },
+       drag: function( event, ui, i  ) {
+
+               var o = i.options,
+                       scrolled = false,
+                       scrollParent = i.scrollParentNotHidden[ 0 ],
+                       document = i.document[ 0 ];
+
+               if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
+                       if ( !o.axis || o.axis !== "x" ) {
+                               if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
+                                       scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
+                               } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
+                                       scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
+                               }
+                       }
+
+                       if ( !o.axis || o.axis !== "y" ) {
+                               if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
+                                       scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
+                               } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
+                                       scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
+                               }
+                       }
+
+               } else {
+
+                       if (!o.axis || o.axis !== "x") {
+                               if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+                               }
+                       }
+
+                       if (!o.axis || o.axis !== "y") {
+                               if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+                               }
+                       }
+
+               }
+
+               if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(i, event);
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+       start: function( event, ui, i ) {
+
+               var o = i.options;
+
+               i.snapElements = [];
+
+               $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
+                       var $t = $(this),
+                               $o = $t.offset();
+                       if (this !== i.element[0]) {
+                               i.snapElements.push({
+                                       item: this,
+                                       width: $t.outerWidth(), height: $t.outerHeight(),
+                                       top: $o.top, left: $o.left
+                               });
+                       }
+               });
+
+       },
+       drag: function( event, ui, inst ) {
+
+               var ts, bs, ls, rs, l, r, t, b, i, first,
+                       o = inst.options,
+                       d = o.snapTolerance,
+                       x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+                       y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+               for (i = inst.snapElements.length - 1; i >= 0; i--){
+
+                       l = inst.snapElements[i].left - inst.margins.left;
+                       r = l + inst.snapElements[i].width;
+                       t = inst.snapElements[i].top - inst.margins.top;
+                       b = t + inst.snapElements[i].height;
+
+                       if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
+                               if (inst.snapElements[i].snapping) {
+                                       (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                               }
+                               inst.snapElements[i].snapping = false;
+                               continue;
+                       }
+
+                       if (o.snapMode !== "inner") {
+                               ts = Math.abs(t - y2) <= d;
+                               bs = Math.abs(b - y1) <= d;
+                               ls = Math.abs(l - x2) <= d;
+                               rs = Math.abs(r - x1) <= d;
+                               if (ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
+                               }
+                               if (bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
+                               }
+                               if (ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
+                               }
+                               if (rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
+                               }
+                       }
+
+                       first = (ts || bs || ls || rs);
+
+                       if (o.snapMode !== "outer") {
+                               ts = Math.abs(t - y1) <= d;
+                               bs = Math.abs(b - y2) <= d;
+                               ls = Math.abs(l - x1) <= d;
+                               rs = Math.abs(r - x2) <= d;
+                               if (ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
+                               }
+                               if (bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
+                               }
+                               if (ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
+                               }
+                               if (rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
+                               }
+                       }
+
+                       if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
+                               (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                       }
+                       inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+       start: function( event, ui, instance ) {
+               var min,
+                       o = instance.options,
+                       group = $.makeArray($(o.stack)).sort(function(a, b) {
+                               return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
+                       });
+
+               if (!group.length) { return; }
+
+               min = parseInt($(group[0]).css("zIndex"), 10) || 0;
+               $(group).each(function(i) {
+                       $(this).css("zIndex", min + i);
+               });
+               this.css("zIndex", (min + group.length));
+       }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+       start: function( event, ui, instance ) {
+               var t = $( ui.helper ),
+                       o = instance.options;
+
+               if (t.css("zIndex")) {
+                       o._zIndex = t.css("zIndex");
+               }
+               t.css("zIndex", o.zIndex);
+       },
+       stop: function( event, ui, instance ) {
+               var o = instance.options;
+
+               if (o._zIndex) {
+                       $(ui.helper).css("zIndex", o._zIndex);
+               }
+       }
+});
+
+var draggable = $.ui.draggable;
+
+
+/*!
+ * jQuery UI Resizable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/resizable/
+ */
+
+
+$.widget("ui.resizable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "resize",
+       options: {
+               alsoResize: false,
+               animate: false,
+               animateDuration: "slow",
+               animateEasing: "swing",
+               aspectRatio: false,
+               autoHide: false,
+               containment: false,
+               ghost: false,
+               grid: false,
+               handles: "e,s,se",
+               helper: false,
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 10,
+               minWidth: 10,
+               // See #7960
+               zIndex: 90,
+
+               // callbacks
+               resize: null,
+               start: null,
+               stop: null
+       },
+
+       _num: function( value ) {
+               return parseInt( value, 10 ) || 0;
+       },
+
+       _isNumber: function( value ) {
+               return !isNaN( parseInt( value, 10 ) );
+       },
+
+       _hasScroll: function( el, a ) {
+
+               if ( $( el ).css( "overflow" ) === "hidden") {
+                       return false;
+               }
+
+               var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+                       has = false;
+
+               if ( el[ scroll ] > 0 ) {
+                       return true;
+               }
+
+               // TODO: determine which cases actually cause this to happen
+               // if the element doesn't have the scroll set, see if it's possible to
+               // set the scroll
+               el[ scroll ] = 1;
+               has = ( el[ scroll ] > 0 );
+               el[ scroll ] = 0;
+               return has;
+       },
+
+       _create: function() {
+
+               var n, i, handle, axis, hname,
+                       that = this,
+                       o = this.options;
+               this.element.addClass("ui-resizable");
+
+               $.extend(this, {
+                       _aspectRatio: !!(o.aspectRatio),
+                       aspectRatio: o.aspectRatio,
+                       originalElement: this.element,
+                       _proportionallyResizeElements: [],
+                       _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
+               });
+
+               // Wrap the element if it cannot hold child nodes
+               if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
+
+                       this.element.wrap(
+                               $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
+                                       position: this.element.css("position"),
+                                       width: this.element.outerWidth(),
+                                       height: this.element.outerHeight(),
+                                       top: this.element.css("top"),
+                                       left: this.element.css("left")
+                               })
+                       );
+
+                       this.element = this.element.parent().data(
+                               "ui-resizable", this.element.resizable( "instance" )
+                       );
+
+                       this.elementIsWrapper = true;
+
+                       this.element.css({
+                               marginLeft: this.originalElement.css("marginLeft"),
+                               marginTop: this.originalElement.css("marginTop"),
+                               marginRight: this.originalElement.css("marginRight"),
+                               marginBottom: this.originalElement.css("marginBottom")
+                       });
+                       this.originalElement.css({
+                               marginLeft: 0,
+                               marginTop: 0,
+                               marginRight: 0,
+                               marginBottom: 0
+                       });
+                       // support: Safari
+                       // Prevent Safari textarea resize
+                       this.originalResizeStyle = this.originalElement.css("resize");
+                       this.originalElement.css("resize", "none");
+
+                       this._proportionallyResizeElements.push( this.originalElement.css({
+                               position: "static",
+                               zoom: 1,
+                               display: "block"
+                       }) );
+
+                       // support: IE9
+                       // avoid IE jump (hard set the margin)
+                       this.originalElement.css({ margin: this.originalElement.css("margin") });
+
+                       this._proportionallyResize();
+               }
+
+               this.handles = o.handles ||
+                       ( !$(".ui-resizable-handle", this.element).length ?
+                               "e,s,se" : {
+                                       n: ".ui-resizable-n",
+                                       e: ".ui-resizable-e",
+                                       s: ".ui-resizable-s",
+                                       w: ".ui-resizable-w",
+                                       se: ".ui-resizable-se",
+                                       sw: ".ui-resizable-sw",
+                                       ne: ".ui-resizable-ne",
+                                       nw: ".ui-resizable-nw"
+                               } );
+
+               if (this.handles.constructor === String) {
+
+                       if ( this.handles === "all") {
+                               this.handles = "n,e,s,w,se,sw,ne,nw";
+                       }
+
+                       n = this.handles.split(",");
+                       this.handles = {};
+
+                       for (i = 0; i < n.length; i++) {
+
+                               handle = $.trim(n[i]);
+                               hname = "ui-resizable-" + handle;
+                               axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
+
+                               axis.css({ zIndex: o.zIndex });
+
+                               // TODO : What's going on here?
+                               if ("se" === handle) {
+                                       axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
+                               }
+
+                               this.handles[handle] = ".ui-resizable-" + handle;
+                               this.element.append(axis);
+                       }
+
+               }
+
+               this._renderAxis = function(target) {
+
+                       var i, axis, padPos, padWrapper;
+
+                       target = target || this.element;
+
+                       for (i in this.handles) {
+
+                               if (this.handles[i].constructor === String) {
+                                       this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
+                               }
+
+                               if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
+
+                                       axis = $(this.handles[i], this.element);
+
+                                       padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+                                       padPos = [ "padding",
+                                               /ne|nw|n/.test(i) ? "Top" :
+                                               /se|sw|s/.test(i) ? "Bottom" :
+                                               /^e$/.test(i) ? "Right" : "Left" ].join("");
+
+                                       target.css(padPos, padWrapper);
+
+                                       this._proportionallyResize();
+
+                               }
+
+                               // TODO: What's that good for? There's not anything to be executed left
+                               if (!$(this.handles[i]).length) {
+                                       continue;
+                               }
+                       }
+               };
+
+               // TODO: make renderAxis a prototype function
+               this._renderAxis(this.element);
+
+               this._handles = $(".ui-resizable-handle", this.element)
+                       .disableSelection();
+
+               this._handles.mouseover(function() {
+                       if (!that.resizing) {
+                               if (this.className) {
+                                       axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+                               }
+                               that.axis = axis && axis[1] ? axis[1] : "se";
+                       }
+               });
+
+               if (o.autoHide) {
+                       this._handles.hide();
+                       $(this.element)
+                               .addClass("ui-resizable-autohide")
+                               .mouseenter(function() {
+                                       if (o.disabled) {
+                                               return;
+                                       }
+                                       $(this).removeClass("ui-resizable-autohide");
+                                       that._handles.show();
+                               })
+                               .mouseleave(function() {
+                                       if (o.disabled) {
+                                               return;
+                                       }
+                                       if (!that.resizing) {
+                                               $(this).addClass("ui-resizable-autohide");
+                                               that._handles.hide();
+                                       }
+                               });
+               }
+
+               this._mouseInit();
+
+       },
+
+       _destroy: function() {
+
+               this._mouseDestroy();
+
+               var wrapper,
+                       _destroy = function(exp) {
+                               $(exp)
+                                       .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+                                       .removeData("resizable")
+                                       .removeData("ui-resizable")
+                                       .unbind(".resizable")
+                                       .find(".ui-resizable-handle")
+                                               .remove();
+                       };
+
+               // TODO: Unwrap at same DOM position
+               if (this.elementIsWrapper) {
+                       _destroy(this.element);
+                       wrapper = this.element;
+                       this.originalElement.css({
+                               position: wrapper.css("position"),
+                               width: wrapper.outerWidth(),
+                               height: wrapper.outerHeight(),
+                               top: wrapper.css("top"),
+                               left: wrapper.css("left")
+                       }).insertAfter( wrapper );
+                       wrapper.remove();
+               }
+
+               this.originalElement.css("resize", this.originalResizeStyle);
+               _destroy(this.originalElement);
+
+               return this;
+       },
+
+       _mouseCapture: function(event) {
+               var i, handle,
+                       capture = false;
+
+               for (i in this.handles) {
+                       handle = $(this.handles[i])[0];
+                       if (handle === event.target || $.contains(handle, event.target)) {
+                               capture = true;
+                       }
+               }
+
+               return !this.options.disabled && capture;
+       },
+
+       _mouseStart: function(event) {
+
+               var curleft, curtop, cursor,
+                       o = this.options,
+                       el = this.element;
+
+               this.resizing = true;
+
+               this._renderProxy();
+
+               curleft = this._num(this.helper.css("left"));
+               curtop = this._num(this.helper.css("top"));
+
+               if (o.containment) {
+                       curleft += $(o.containment).scrollLeft() || 0;
+                       curtop += $(o.containment).scrollTop() || 0;
+               }
+
+               this.offset = this.helper.offset();
+               this.position = { left: curleft, top: curtop };
+
+               this.size = this._helper ? {
+                               width: this.helper.width(),
+                               height: this.helper.height()
+                       } : {
+                               width: el.width(),
+                               height: el.height()
+                       };
+
+               this.originalSize = this._helper ? {
+                               width: el.outerWidth(),
+                               height: el.outerHeight()
+                       } : {
+                               width: el.width(),
+                               height: el.height()
+                       };
+
+               this.sizeDiff = {
+                       width: el.outerWidth() - el.width(),
+                       height: el.outerHeight() - el.height()
+               };
+
+               this.originalPosition = { left: curleft, top: curtop };
+               this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+               this.aspectRatio = (typeof o.aspectRatio === "number") ?
+                       o.aspectRatio :
+                       ((this.originalSize.width / this.originalSize.height) || 1);
+
+               cursor = $(".ui-resizable-" + this.axis).css("cursor");
+               $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
+
+               el.addClass("ui-resizable-resizing");
+               this._propagate("start", event);
+               return true;
+       },
+
+       _mouseDrag: function(event) {
+
+               var data, props,
+                       smp = this.originalMousePosition,
+                       a = this.axis,
+                       dx = (event.pageX - smp.left) || 0,
+                       dy = (event.pageY - smp.top) || 0,
+                       trigger = this._change[a];
+
+               this._updatePrevProperties();
+
+               if (!trigger) {
+                       return false;
+               }
+
+               data = trigger.apply(this, [ event, dx, dy ]);
+
+               this._updateVirtualBoundaries(event.shiftKey);
+               if (this._aspectRatio || event.shiftKey) {
+                       data = this._updateRatio(data, event);
+               }
+
+               data = this._respectSize(data, event);
+
+               this._updateCache(data);
+
+               this._propagate("resize", event);
+
+               props = this._applyChanges();
+
+               if ( !this._helper && this._proportionallyResizeElements.length ) {
+                       this._proportionallyResize();
+               }
+
+               if ( !$.isEmptyObject( props ) ) {
+                       this._updatePrevProperties();
+                       this._trigger( "resize", event, this.ui() );
+                       this._applyChanges();
+               }
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               this.resizing = false;
+               var pr, ista, soffseth, soffsetw, s, left, top,
+                       o = this.options, that = this;
+
+               if (this._helper) {
+
+                       pr = this._proportionallyResizeElements;
+                       ista = pr.length && (/textarea/i).test(pr[0].nodeName);
+                       soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
+                       soffsetw = ista ? 0 : that.sizeDiff.width;
+
+                       s = {
+                               width: (that.helper.width()  - soffsetw),
+                               height: (that.helper.height() - soffseth)
+                       };
+                       left = (parseInt(that.element.css("left"), 10) +
+                               (that.position.left - that.originalPosition.left)) || null;
+                       top = (parseInt(that.element.css("top"), 10) +
+                               (that.position.top - that.originalPosition.top)) || null;
+
+                       if (!o.animate) {
+                               this.element.css($.extend(s, { top: top, left: left }));
+                       }
+
+                       that.helper.height(that.size.height);
+                       that.helper.width(that.size.width);
+
+                       if (this._helper && !o.animate) {
+                               this._proportionallyResize();
+                       }
+               }
+
+               $("body").css("cursor", "auto");
+
+               this.element.removeClass("ui-resizable-resizing");
+
+               this._propagate("stop", event);
+
+               if (this._helper) {
+                       this.helper.remove();
+               }
+
+               return false;
+
+       },
+
+       _updatePrevProperties: function() {
+               this.prevPosition = {
+                       top: this.position.top,
+                       left: this.position.left
+               };
+               this.prevSize = {
+                       width: this.size.width,
+                       height: this.size.height
+               };
+       },
+
+       _applyChanges: function() {
+               var props = {};
+
+               if ( this.position.top !== this.prevPosition.top ) {
+                       props.top = this.position.top + "px";
+               }
+               if ( this.position.left !== this.prevPosition.left ) {
+                       props.left = this.position.left + "px";
+               }
+               if ( this.size.width !== this.prevSize.width ) {
+                       props.width = this.size.width + "px";
+               }
+               if ( this.size.height !== this.prevSize.height ) {
+                       props.height = this.size.height + "px";
+               }
+
+               this.helper.css( props );
+
+               return props;
+       },
+
+       _updateVirtualBoundaries: function(forceAspectRatio) {
+               var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
+                       o = this.options;
+
+               b = {
+                       minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
+                       maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+                       minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
+                       maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
+               };
+
+               if (this._aspectRatio || forceAspectRatio) {
+                       pMinWidth = b.minHeight * this.aspectRatio;
+                       pMinHeight = b.minWidth / this.aspectRatio;
+                       pMaxWidth = b.maxHeight * this.aspectRatio;
+                       pMaxHeight = b.maxWidth / this.aspectRatio;
+
+                       if (pMinWidth > b.minWidth) {
+                               b.minWidth = pMinWidth;
+                       }
+                       if (pMinHeight > b.minHeight) {
+                               b.minHeight = pMinHeight;
+                       }
+                       if (pMaxWidth < b.maxWidth) {
+                               b.maxWidth = pMaxWidth;
+                       }
+                       if (pMaxHeight < b.maxHeight) {
+                               b.maxHeight = pMaxHeight;
+                       }
+               }
+               this._vBoundaries = b;
+       },
+
+       _updateCache: function(data) {
+               this.offset = this.helper.offset();
+               if (this._isNumber(data.left)) {
+                       this.position.left = data.left;
+               }
+               if (this._isNumber(data.top)) {
+                       this.position.top = data.top;
+               }
+               if (this._isNumber(data.height)) {
+                       this.size.height = data.height;
+               }
+               if (this._isNumber(data.width)) {
+                       this.size.width = data.width;
+               }
+       },
+
+       _updateRatio: function( data ) {
+
+               var cpos = this.position,
+                       csize = this.size,
+                       a = this.axis;
+
+               if (this._isNumber(data.height)) {
+                       data.width = (data.height * this.aspectRatio);
+               } else if (this._isNumber(data.width)) {
+                       data.height = (data.width / this.aspectRatio);
+               }
+
+               if (a === "sw") {
+                       data.left = cpos.left + (csize.width - data.width);
+                       data.top = null;
+               }
+               if (a === "nw") {
+                       data.top = cpos.top + (csize.height - data.height);
+                       data.left = cpos.left + (csize.width - data.width);
+               }
+
+               return data;
+       },
+
+       _respectSize: function( data ) {
+
+               var o = this._vBoundaries,
+                       a = this.axis,
+                       ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
+                       ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+                       isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
+                       isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
+                       dw = this.originalPosition.left + this.originalSize.width,
+                       dh = this.position.top + this.size.height,
+                       cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+               if (isminw) {
+                       data.width = o.minWidth;
+               }
+               if (isminh) {
+                       data.height = o.minHeight;
+               }
+               if (ismaxw) {
+                       data.width = o.maxWidth;
+               }
+               if (ismaxh) {
+                       data.height = o.maxHeight;
+               }
+
+               if (isminw && cw) {
+                       data.left = dw - o.minWidth;
+               }
+               if (ismaxw && cw) {
+                       data.left = dw - o.maxWidth;
+               }
+               if (isminh && ch) {
+                       data.top = dh - o.minHeight;
+               }
+               if (ismaxh && ch) {
+                       data.top = dh - o.maxHeight;
+               }
+
+               // Fixing jump error on top/left - bug #2330
+               if (!data.width && !data.height && !data.left && data.top) {
+                       data.top = null;
+               } else if (!data.width && !data.height && !data.top && data.left) {
+                       data.left = null;
+               }
+
+               return data;
+       },
+
+       _getPaddingPlusBorderDimensions: function( element ) {
+               var i = 0,
+                       widths = [],
+                       borders = [
+                               element.css( "borderTopWidth" ),
+                               element.css( "borderRightWidth" ),
+                               element.css( "borderBottomWidth" ),
+                               element.css( "borderLeftWidth" )
+                       ],
+                       paddings = [
+                               element.css( "paddingTop" ),
+                               element.css( "paddingRight" ),
+                               element.css( "paddingBottom" ),
+                               element.css( "paddingLeft" )
+                       ];
+
+               for ( ; i < 4; i++ ) {
+                       widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
+                       widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
+               }
+
+               return {
+                       height: widths[ 0 ] + widths[ 2 ],
+                       width: widths[ 1 ] + widths[ 3 ]
+               };
+       },
+
+       _proportionallyResize: function() {
+
+               if (!this._proportionallyResizeElements.length) {
+                       return;
+               }
+
+               var prel,
+                       i = 0,
+                       element = this.helper || this.element;
+
+               for ( ; i < this._proportionallyResizeElements.length; i++) {
+
+                       prel = this._proportionallyResizeElements[i];
+
+                       // TODO: Seems like a bug to cache this.outerDimensions
+                       // considering that we are in a loop.
+                       if (!this.outerDimensions) {
+                               this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
+                       }
+
+                       prel.css({
+                               height: (element.height() - this.outerDimensions.height) || 0,
+                               width: (element.width() - this.outerDimensions.width) || 0
+                       });
+
+               }
+
+       },
+
+       _renderProxy: function() {
+
+               var el = this.element, o = this.options;
+               this.elementOffset = el.offset();
+
+               if (this._helper) {
+
+                       this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
+
+                       this.helper.addClass(this._helper).css({
+                               width: this.element.outerWidth() - 1,
+                               height: this.element.outerHeight() - 1,
+                               position: "absolute",
+                               left: this.elementOffset.left + "px",
+                               top: this.elementOffset.top + "px",
+                               zIndex: ++o.zIndex //TODO: Don't modify option
+                       });
+
+                       this.helper
+                               .appendTo("body")
+                               .disableSelection();
+
+               } else {
+                       this.helper = this.element;
+               }
+
+       },
+
+       _change: {
+               e: function(event, dx) {
+                       return { width: this.originalSize.width + dx };
+               },
+               w: function(event, dx) {
+                       var cs = this.originalSize, sp = this.originalPosition;
+                       return { left: sp.left + dx, width: cs.width - dx };
+               },
+               n: function(event, dx, dy) {
+                       var cs = this.originalSize, sp = this.originalPosition;
+                       return { top: sp.top + dy, height: cs.height - dy };
+               },
+               s: function(event, dx, dy) {
+                       return { height: this.originalSize.height + dy };
+               },
+               se: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments),
+                               this._change.e.apply(this, [ event, dx, dy ]));
+               },
+               sw: function(event, dx, dy) {
+                       return $.extend(this._change.s.apply(this, arguments),
+                               this._change.w.apply(this, [ event, dx, dy ]));
+               },
+               ne: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments),
+                               this._change.e.apply(this, [ event, dx, dy ]));
+               },
+               nw: function(event, dx, dy) {
+                       return $.extend(this._change.n.apply(this, arguments),
+                               this._change.w.apply(this, [ event, dx, dy ]));
+               }
+       },
+
+       _propagate: function(n, event) {
+               $.ui.plugin.call(this, n, [ event, this.ui() ]);
+               (n !== "resize" && this._trigger(n, event, this.ui()));
+       },
+
+       plugins: {},
+
+       ui: function() {
+               return {
+                       originalElement: this.originalElement,
+                       element: this.element,
+                       helper: this.helper,
+                       position: this.position,
+                       size: this.size,
+                       originalSize: this.originalSize,
+                       originalPosition: this.originalPosition
+               };
+       }
+
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "animate", {
+
+       stop: function( event ) {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       pr = that._proportionallyResizeElements,
+                       ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+                       soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
+                       soffsetw = ista ? 0 : that.sizeDiff.width,
+                       style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
+                       left = (parseInt(that.element.css("left"), 10) +
+                               (that.position.left - that.originalPosition.left)) || null,
+                       top = (parseInt(that.element.css("top"), 10) +
+                               (that.position.top - that.originalPosition.top)) || null;
+
+               that.element.animate(
+                       $.extend(style, top && left ? { top: top, left: left } : {}), {
+                               duration: o.animateDuration,
+                               easing: o.animateEasing,
+                               step: function() {
+
+                                       var data = {
+                                               width: parseInt(that.element.css("width"), 10),
+                                               height: parseInt(that.element.css("height"), 10),
+                                               top: parseInt(that.element.css("top"), 10),
+                                               left: parseInt(that.element.css("left"), 10)
+                                       };
+
+                                       if (pr && pr.length) {
+                                               $(pr[0]).css({ width: data.width, height: data.height });
+                                       }
+
+                                       // propagating resize, and updating values for each animation step
+                                       that._updateCache(data);
+                                       that._propagate("resize", event);
+
+                               }
+                       }
+               );
+       }
+
+});
+
+$.ui.plugin.add( "resizable", "containment", {
+
+       start: function() {
+               var element, p, co, ch, cw, width, height,
+                       that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       el = that.element,
+                       oc = o.containment,
+                       ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
+
+               if ( !ce ) {
+                       return;
+               }
+
+               that.containerElement = $( ce );
+
+               if ( /document/.test( oc ) || oc === document ) {
+                       that.containerOffset = {
+                               left: 0,
+                               top: 0
+                       };
+                       that.containerPosition = {
+                               left: 0,
+                               top: 0
+                       };
+
+                       that.parentData = {
+                               element: $( document ),
+                               left: 0,
+                               top: 0,
+                               width: $( document ).width(),
+                               height: $( document ).height() || document.body.parentNode.scrollHeight
+                       };
+               } else {
+                       element = $( ce );
+                       p = [];
+                       $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
+                               p[ i ] = that._num( element.css( "padding" + name ) );
+                       });
+
+                       that.containerOffset = element.offset();
+                       that.containerPosition = element.position();
+                       that.containerSize = {
+                               height: ( element.innerHeight() - p[ 3 ] ),
+                               width: ( element.innerWidth() - p[ 1 ] )
+                       };
+
+                       co = that.containerOffset;
+                       ch = that.containerSize.height;
+                       cw = that.containerSize.width;
+                       width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
+                       height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
+
+                       that.parentData = {
+                               element: ce,
+                               left: co.left,
+                               top: co.top,
+                               width: width,
+                               height: height
+                       };
+               }
+       },
+
+       resize: function( event ) {
+               var woset, hoset, isParent, isOffsetRelative,
+                       that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       co = that.containerOffset,
+                       cp = that.position,
+                       pRatio = that._aspectRatio || event.shiftKey,
+                       cop = {
+                               top: 0,
+                               left: 0
+                       },
+                       ce = that.containerElement,
+                       continueResize = true;
+
+               if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
+                       cop = co;
+               }
+
+               if ( cp.left < ( that._helper ? co.left : 0 ) ) {
+                       that.size.width = that.size.width +
+                               ( that._helper ?
+                                       ( that.position.left - co.left ) :
+                                       ( that.position.left - cop.left ) );
+
+                       if ( pRatio ) {
+                               that.size.height = that.size.width / that.aspectRatio;
+                               continueResize = false;
+                       }
+                       that.position.left = o.helper ? co.left : 0;
+               }
+
+               if ( cp.top < ( that._helper ? co.top : 0 ) ) {
+                       that.size.height = that.size.height +
+                               ( that._helper ?
+                                       ( that.position.top - co.top ) :
+                                       that.position.top );
+
+                       if ( pRatio ) {
+                               that.size.width = that.size.height * that.aspectRatio;
+                               continueResize = false;
+                       }
+                       that.position.top = that._helper ? co.top : 0;
+               }
+
+               isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
+               isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
+
+               if ( isParent && isOffsetRelative ) {
+                       that.offset.left = that.parentData.left + that.position.left;
+                       that.offset.top = that.parentData.top + that.position.top;
+               } else {
+                       that.offset.left = that.element.offset().left;
+                       that.offset.top = that.element.offset().top;
+               }
+
+               woset = Math.abs( that.sizeDiff.width +
+                       (that._helper ?
+                               that.offset.left - cop.left :
+                               (that.offset.left - co.left)) );
+
+               hoset = Math.abs( that.sizeDiff.height +
+                       (that._helper ?
+                               that.offset.top - cop.top :
+                               (that.offset.top - co.top)) );
+
+               if ( woset + that.size.width >= that.parentData.width ) {
+                       that.size.width = that.parentData.width - woset;
+                       if ( pRatio ) {
+                               that.size.height = that.size.width / that.aspectRatio;
+                               continueResize = false;
+                       }
+               }
+
+               if ( hoset + that.size.height >= that.parentData.height ) {
+                       that.size.height = that.parentData.height - hoset;
+                       if ( pRatio ) {
+                               that.size.width = that.size.height * that.aspectRatio;
+                               continueResize = false;
+                       }
+               }
+
+               if ( !continueResize ) {
+                       that.position.left = that.prevPosition.left;
+                       that.position.top = that.prevPosition.top;
+                       that.size.width = that.prevSize.width;
+                       that.size.height = that.prevSize.height;
+               }
+       },
+
+       stop: function() {
+               var that = $( this ).resizable( "instance" ),
+                       o = that.options,
+                       co = that.containerOffset,
+                       cop = that.containerPosition,
+                       ce = that.containerElement,
+                       helper = $( that.helper ),
+                       ho = helper.offset(),
+                       w = helper.outerWidth() - that.sizeDiff.width,
+                       h = helper.outerHeight() - that.sizeDiff.height;
+
+               if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
+                       $( this ).css({
+                               left: ho.left - cop.left - co.left,
+                               width: w,
+                               height: h
+                       });
+               }
+
+               if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
+                       $( this ).css({
+                               left: ho.left - cop.left - co.left,
+                               width: w,
+                               height: h
+                       });
+               }
+       }
+});
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+       start: function() {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       _store = function(exp) {
+                               $(exp).each(function() {
+                                       var el = $(this);
+                                       el.data("ui-resizable-alsoresize", {
+                                               width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+                                               left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
+                                       });
+                               });
+                       };
+
+               if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
+                       if (o.alsoResize.length) {
+                               o.alsoResize = o.alsoResize[0];
+                               _store(o.alsoResize);
+                       } else {
+                               $.each(o.alsoResize, function(exp) {
+                                       _store(exp);
+                               });
+                       }
+               } else {
+                       _store(o.alsoResize);
+               }
+       },
+
+       resize: function(event, ui) {
+               var that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       os = that.originalSize,
+                       op = that.originalPosition,
+                       delta = {
+                               height: (that.size.height - os.height) || 0,
+                               width: (that.size.width - os.width) || 0,
+                               top: (that.position.top - op.top) || 0,
+                               left: (that.position.left - op.left) || 0
+                       },
+
+                       _alsoResize = function(exp, c) {
+                               $(exp).each(function() {
+                                       var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
+                                               css = c && c.length ?
+                                                       c :
+                                                       el.parents(ui.originalElement[0]).length ?
+                                                               [ "width", "height" ] :
+                                                               [ "width", "height", "top", "left" ];
+
+                                       $.each(css, function(i, prop) {
+                                               var sum = (start[prop] || 0) + (delta[prop] || 0);
+                                               if (sum && sum >= 0) {
+                                                       style[prop] = sum || null;
+                                               }
+                                       });
+
+                                       el.css(style);
+                               });
+                       };
+
+               if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
+                       $.each(o.alsoResize, function(exp, c) {
+                               _alsoResize(exp, c);
+                       });
+               } else {
+                       _alsoResize(o.alsoResize);
+               }
+       },
+
+       stop: function() {
+               $(this).removeData("resizable-alsoresize");
+       }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+       start: function() {
+
+               var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
+
+               that.ghost = that.originalElement.clone();
+               that.ghost
+                       .css({
+                               opacity: 0.25,
+                               display: "block",
+                               position: "relative",
+                               height: cs.height,
+                               width: cs.width,
+                               margin: 0,
+                               left: 0,
+                               top: 0
+                       })
+                       .addClass("ui-resizable-ghost")
+                       .addClass(typeof o.ghost === "string" ? o.ghost : "");
+
+               that.ghost.appendTo(that.helper);
+
+       },
+
+       resize: function() {
+               var that = $(this).resizable( "instance" );
+               if (that.ghost) {
+                       that.ghost.css({
+                               position: "relative",
+                               height: that.size.height,
+                               width: that.size.width
+                       });
+               }
+       },
+
+       stop: function() {
+               var that = $(this).resizable( "instance" );
+               if (that.ghost && that.helper) {
+                       that.helper.get(0).removeChild(that.ghost.get(0));
+               }
+       }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+       resize: function() {
+               var outerDimensions,
+                       that = $(this).resizable( "instance" ),
+                       o = that.options,
+                       cs = that.size,
+                       os = that.originalSize,
+                       op = that.originalPosition,
+                       a = that.axis,
+                       grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
+                       gridX = (grid[0] || 1),
+                       gridY = (grid[1] || 1),
+                       ox = Math.round((cs.width - os.width) / gridX) * gridX,
+                       oy = Math.round((cs.height - os.height) / gridY) * gridY,
+                       newWidth = os.width + ox,
+                       newHeight = os.height + oy,
+                       isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
+                       isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
+                       isMinWidth = o.minWidth && (o.minWidth > newWidth),
+                       isMinHeight = o.minHeight && (o.minHeight > newHeight);
+
+               o.grid = grid;
+
+               if (isMinWidth) {
+                       newWidth += gridX;
+               }
+               if (isMinHeight) {
+                       newHeight += gridY;
+               }
+               if (isMaxWidth) {
+                       newWidth -= gridX;
+               }
+               if (isMaxHeight) {
+                       newHeight -= gridY;
+               }
+
+               if (/^(se|s|e)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+               } else if (/^(ne)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+                       that.position.top = op.top - oy;
+               } else if (/^(sw)$/.test(a)) {
+                       that.size.width = newWidth;
+                       that.size.height = newHeight;
+                       that.position.left = op.left - ox;
+               } else {
+                       if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
+                               outerDimensions = that._getPaddingPlusBorderDimensions( this );
+                       }
+
+                       if ( newHeight - gridY > 0 ) {
+                               that.size.height = newHeight;
+                               that.position.top = op.top - oy;
+                       } else {
+                               newHeight = gridY - outerDimensions.height;
+                               that.size.height = newHeight;
+                               that.position.top = op.top + os.height - newHeight;
+                       }
+                       if ( newWidth - gridX > 0 ) {
+                               that.size.width = newWidth;
+                               that.position.left = op.left - ox;
+                       } else {
+                               newWidth = gridX - outerDimensions.width;
+                               that.size.width = newWidth;
+                               that.position.left = op.left + os.width - newWidth;
+                       }
+               }
+       }
+
+});
+
+var resizable = $.ui.resizable;
+
+
+/*!
+ * jQuery UI Dialog 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/dialog/
+ */
+
+
+var dialog = $.widget( "ui.dialog", {
+       version: "1.11.3",
+       options: {
+               appendTo: "body",
+               autoOpen: true,
+               buttons: [],
+               closeOnEscape: true,
+               closeText: "Close",
+               dialogClass: "",
+               draggable: true,
+               hide: null,
+               height: "auto",
+               maxHeight: null,
+               maxWidth: null,
+               minHeight: 150,
+               minWidth: 150,
+               modal: false,
+               position: {
+                       my: "center",
+                       at: "center",
+                       of: window,
+                       collision: "fit",
+                       // Ensure the titlebar is always visible
+                       using: function( pos ) {
+                               var topOffset = $( this ).css( pos ).offset().top;
+                               if ( topOffset < 0 ) {
+                                       $( this ).css( "top", pos.top - topOffset );
+                               }
+                       }
+               },
+               resizable: true,
+               show: null,
+               title: null,
+               width: 300,
+
+               // callbacks
+               beforeClose: null,
+               close: null,
+               drag: null,
+               dragStart: null,
+               dragStop: null,
+               focus: null,
+               open: null,
+               resize: null,
+               resizeStart: null,
+               resizeStop: null
+       },
+
+       sizeRelatedOptions: {
+               buttons: true,
+               height: true,
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true,
+               width: true
+       },
+
+       resizableRelatedOptions: {
+               maxHeight: true,
+               maxWidth: true,
+               minHeight: true,
+               minWidth: true
+       },
+
+       _create: function() {
+               this.originalCss = {
+                       display: this.element[ 0 ].style.display,
+                       width: this.element[ 0 ].style.width,
+                       minHeight: this.element[ 0 ].style.minHeight,
+                       maxHeight: this.element[ 0 ].style.maxHeight,
+                       height: this.element[ 0 ].style.height
+               };
+               this.originalPosition = {
+                       parent: this.element.parent(),
+                       index: this.element.parent().children().index( this.element )
+               };
+               this.originalTitle = this.element.attr( "title" );
+               this.options.title = this.options.title || this.originalTitle;
+
+               this._createWrapper();
+
+               this.element
+                       .show()
+                       .removeAttr( "title" )
+                       .addClass( "ui-dialog-content ui-widget-content" )
+                       .appendTo( this.uiDialog );
+
+               this._createTitlebar();
+               this._createButtonPane();
+
+               if ( this.options.draggable && $.fn.draggable ) {
+                       this._makeDraggable();
+               }
+               if ( this.options.resizable && $.fn.resizable ) {
+                       this._makeResizable();
+               }
+
+               this._isOpen = false;
+
+               this._trackFocus();
+       },
+
+       _init: function() {
+               if ( this.options.autoOpen ) {
+                       this.open();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+               if ( element && (element.jquery || element.nodeType) ) {
+                       return $( element );
+               }
+               return this.document.find( element || "body" ).eq( 0 );
+       },
+
+       _destroy: function() {
+               var next,
+                       originalPosition = this.originalPosition;
+
+               this._destroyOverlay();
+
+               this.element
+                       .removeUniqueId()
+                       .removeClass( "ui-dialog-content ui-widget-content" )
+                       .css( this.originalCss )
+                       // Without detaching first, the following becomes really slow
+                       .detach();
+
+               this.uiDialog.stop( true, true ).remove();
+
+               if ( this.originalTitle ) {
+                       this.element.attr( "title", this.originalTitle );
+               }
+
+               next = originalPosition.parent.children().eq( originalPosition.index );
+               // Don't try to place the dialog next to itself (#8613)
+               if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
+                       next.before( this.element );
+               } else {
+                       originalPosition.parent.append( this.element );
+               }
+       },
+
+       widget: function() {
+               return this.uiDialog;
+       },
+
+       disable: $.noop,
+       enable: $.noop,
+
+       close: function( event ) {
+               var activeElement,
+                       that = this;
+
+               if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
+                       return;
+               }
+
+               this._isOpen = false;
+               this._focusedElement = null;
+               this._destroyOverlay();
+               this._untrackInstance();
+
+               if ( !this.opener.filter( ":focusable" ).focus().length ) {
+
+                       // support: IE9
+                       // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+                       try {
+                               activeElement = this.document[ 0 ].activeElement;
+
+                               // Support: IE9, IE10
+                               // If the <body> is blurred, IE will switch windows, see #4520
+                               if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
+
+                                       // Hiding a focused element doesn't trigger blur in WebKit
+                                       // so in case we have nothing to focus on, explicitly blur the active element
+                                       // https://bugs.webkit.org/show_bug.cgi?id=47182
+                                       $( activeElement ).blur();
+                               }
+                       } catch ( error ) {}
+               }
+
+               this._hide( this.uiDialog, this.options.hide, function() {
+                       that._trigger( "close", event );
+               });
+       },
+
+       isOpen: function() {
+               return this._isOpen;
+       },
+
+       moveToTop: function() {
+               this._moveToTop();
+       },
+
+       _moveToTop: function( event, silent ) {
+               var moved = false,
+                       zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
+                               return +$( this ).css( "z-index" );
+                       }).get(),
+                       zIndexMax = Math.max.apply( null, zIndicies );
+
+               if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
+                       this.uiDialog.css( "z-index", zIndexMax + 1 );
+                       moved = true;
+               }
+
+               if ( moved && !silent ) {
+                       this._trigger( "focus", event );
+               }
+               return moved;
+       },
+
+       open: function() {
+               var that = this;
+               if ( this._isOpen ) {
+                       if ( this._moveToTop() ) {
+                               this._focusTabbable();
+                       }
+                       return;
+               }
+
+               this._isOpen = true;
+               this.opener = $( this.document[ 0 ].activeElement );
+
+               this._size();
+               this._position();
+               this._createOverlay();
+               this._moveToTop( null, true );
+
+               // Ensure the overlay is moved to the top with the dialog, but only when
+               // opening. The overlay shouldn't move after the dialog is open so that
+               // modeless dialogs opened after the modal dialog stack properly.
+               if ( this.overlay ) {
+                       this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
+               }
+
+               this._show( this.uiDialog, this.options.show, function() {
+                       that._focusTabbable();
+                       that._trigger( "focus" );
+               });
+
+               // Track the dialog immediately upon openening in case a focus event
+               // somehow occurs outside of the dialog before an element inside the
+               // dialog is focused (#10152)
+               this._makeFocusTarget();
+
+               this._trigger( "open" );
+       },
+
+       _focusTabbable: function() {
+               // Set focus to the first match:
+               // 1. An element that was focused previously
+               // 2. First element inside the dialog matching [autofocus]
+               // 3. Tabbable element inside the content element
+               // 4. Tabbable element inside the buttonpane
+               // 5. The close button
+               // 6. The dialog itself
+               var hasFocus = this._focusedElement;
+               if ( !hasFocus ) {
+                       hasFocus = this.element.find( "[autofocus]" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.element.find( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
+               }
+               if ( !hasFocus.length ) {
+                       hasFocus = this.uiDialog;
+               }
+               hasFocus.eq( 0 ).focus();
+       },
+
+       _keepFocus: function( event ) {
+               function checkFocus() {
+                       var activeElement = this.document[0].activeElement,
+                               isActive = this.uiDialog[0] === activeElement ||
+                                       $.contains( this.uiDialog[0], activeElement );
+                       if ( !isActive ) {
+                               this._focusTabbable();
+                       }
+               }
+               event.preventDefault();
+               checkFocus.call( this );
+               // support: IE
+               // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
+               // so we check again later
+               this._delay( checkFocus );
+       },
+
+       _createWrapper: function() {
+               this.uiDialog = $("<div>")
+                       .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
+                               this.options.dialogClass )
+                       .hide()
+                       .attr({
+                               // Setting tabIndex makes the div focusable
+                               tabIndex: -1,
+                               role: "dialog"
+                       })
+                       .appendTo( this._appendTo() );
+
+               this._on( this.uiDialog, {
+                       keydown: function( event ) {
+                               if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+                                               event.keyCode === $.ui.keyCode.ESCAPE ) {
+                                       event.preventDefault();
+                                       this.close( event );
+                                       return;
+                               }
+
+                               // prevent tabbing out of dialogs
+                               if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
+                                       return;
+                               }
+                               var tabbables = this.uiDialog.find( ":tabbable" ),
+                                       first = tabbables.filter( ":first" ),
+                                       last = tabbables.filter( ":last" );
+
+                               if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
+                                       this._delay(function() {
+                                               first.focus();
+                                       });
+                                       event.preventDefault();
+                               } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
+                                       this._delay(function() {
+                                               last.focus();
+                                       });
+                                       event.preventDefault();
+                               }
+                       },
+                       mousedown: function( event ) {
+                               if ( this._moveToTop( event ) ) {
+                                       this._focusTabbable();
+                               }
+                       }
+               });
+
+               // We assume that any existing aria-describedby attribute means
+               // that the dialog content is marked up properly
+               // otherwise we brute force the content as the description
+               if ( !this.element.find( "[aria-describedby]" ).length ) {
+                       this.uiDialog.attr({
+                               "aria-describedby": this.element.uniqueId().attr( "id" )
+                       });
+               }
+       },
+
+       _createTitlebar: function() {
+               var uiDialogTitle;
+
+               this.uiDialogTitlebar = $( "<div>" )
+                       .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
+                       .prependTo( this.uiDialog );
+               this._on( this.uiDialogTitlebar, {
+                       mousedown: function( event ) {
+                               // Don't prevent click on close button (#8838)
+                               // Focusing a dialog that is partially scrolled out of view
+                               // causes the browser to scroll it into view, preventing the click event
+                               if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
+                                       // Dialog isn't getting focus when dragging (#8063)
+                                       this.uiDialog.focus();
+                               }
+                       }
+               });
+
+               // support: IE
+               // Use type="button" to prevent enter keypresses in textboxes from closing the
+               // dialog in IE (#9312)
+               this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
+                       .button({
+                               label: this.options.closeText,
+                               icons: {
+                                       primary: "ui-icon-closethick"
+                               },
+                               text: false
+                       })
+                       .addClass( "ui-dialog-titlebar-close" )
+                       .appendTo( this.uiDialogTitlebar );
+               this._on( this.uiDialogTitlebarClose, {
+                       click: function( event ) {
+                               event.preventDefault();
+                               this.close( event );
+                       }
+               });
+
+               uiDialogTitle = $( "<span>" )
+                       .uniqueId()
+                       .addClass( "ui-dialog-title" )
+                       .prependTo( this.uiDialogTitlebar );
+               this._title( uiDialogTitle );
+
+               this.uiDialog.attr({
+                       "aria-labelledby": uiDialogTitle.attr( "id" )
+               });
+       },
+
+       _title: function( title ) {
+               if ( !this.options.title ) {
+                       title.html( "&#160;" );
+               }
+               title.text( this.options.title );
+       },
+
+       _createButtonPane: function() {
+               this.uiDialogButtonPane = $( "<div>" )
+                       .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
+
+               this.uiButtonSet = $( "<div>" )
+                       .addClass( "ui-dialog-buttonset" )
+                       .appendTo( this.uiDialogButtonPane );
+
+               this._createButtons();
+       },
+
+       _createButtons: function() {
+               var that = this,
+                       buttons = this.options.buttons;
+
+               // if we already have a button pane, remove it
+               this.uiDialogButtonPane.remove();
+               this.uiButtonSet.empty();
+
+               if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
+                       this.uiDialog.removeClass( "ui-dialog-buttons" );
+                       return;
+               }
+
+               $.each( buttons, function( name, props ) {
+                       var click, buttonOptions;
+                       props = $.isFunction( props ) ?
+                               { click: props, text: name } :
+                               props;
+                       // Default to a non-submitting button
+                       props = $.extend( { type: "button" }, props );
+                       // Change the context for the click callback to be the main element
+                       click = props.click;
+                       props.click = function() {
+                               click.apply( that.element[ 0 ], arguments );
+                       };
+                       buttonOptions = {
+                               icons: props.icons,
+                               text: props.showText
+                       };
+                       delete props.icons;
+                       delete props.showText;
+                       $( "<button></button>", props )
+                               .button( buttonOptions )
+                               .appendTo( that.uiButtonSet );
+               });
+               this.uiDialog.addClass( "ui-dialog-buttons" );
+               this.uiDialogButtonPane.appendTo( this.uiDialog );
+       },
+
+       _makeDraggable: function() {
+               var that = this,
+                       options = this.options;
+
+               function filteredUi( ui ) {
+                       return {
+                               position: ui.position,
+                               offset: ui.offset
+                       };
+               }
+
+               this.uiDialog.draggable({
+                       cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
+                       handle: ".ui-dialog-titlebar",
+                       containment: "document",
+                       start: function( event, ui ) {
+                               $( this ).addClass( "ui-dialog-dragging" );
+                               that._blockFrames();
+                               that._trigger( "dragStart", event, filteredUi( ui ) );
+                       },
+                       drag: function( event, ui ) {
+                               that._trigger( "drag", event, filteredUi( ui ) );
+                       },
+                       stop: function( event, ui ) {
+                               var left = ui.offset.left - that.document.scrollLeft(),
+                                       top = ui.offset.top - that.document.scrollTop();
+
+                               options.position = {
+                                       my: "left top",
+                                       at: "left" + (left >= 0 ? "+" : "") + left + " " +
+                                               "top" + (top >= 0 ? "+" : "") + top,
+                                       of: that.window
+                               };
+                               $( this ).removeClass( "ui-dialog-dragging" );
+                               that._unblockFrames();
+                               that._trigger( "dragStop", event, filteredUi( ui ) );
+                       }
+               });
+       },
+
+       _makeResizable: function() {
+               var that = this,
+                       options = this.options,
+                       handles = options.resizable,
+                       // .ui-resizable has position: relative defined in the stylesheet
+                       // but dialogs have to use absolute or fixed positioning
+                       position = this.uiDialog.css("position"),
+                       resizeHandles = typeof handles === "string" ?
+                               handles :
+                               "n,e,s,w,se,sw,ne,nw";
+
+               function filteredUi( ui ) {
+                       return {
+                               originalPosition: ui.originalPosition,
+                               originalSize: ui.originalSize,
+                               position: ui.position,
+                               size: ui.size
+                       };
+               }
+
+               this.uiDialog.resizable({
+                       cancel: ".ui-dialog-content",
+                       containment: "document",
+                       alsoResize: this.element,
+                       maxWidth: options.maxWidth,
+                       maxHeight: options.maxHeight,
+                       minWidth: options.minWidth,
+                       minHeight: this._minHeight(),
+                       handles: resizeHandles,
+                       start: function( event, ui ) {
+                               $( this ).addClass( "ui-dialog-resizing" );
+                               that._blockFrames();
+                               that._trigger( "resizeStart", event, filteredUi( ui ) );
+                       },
+                       resize: function( event, ui ) {
+                               that._trigger( "resize", event, filteredUi( ui ) );
+                       },
+                       stop: function( event, ui ) {
+                               var offset = that.uiDialog.offset(),
+                                       left = offset.left - that.document.scrollLeft(),
+                                       top = offset.top - that.document.scrollTop();
+
+                               options.height = that.uiDialog.height();
+                               options.width = that.uiDialog.width();
+                               options.position = {
+                                       my: "left top",
+                                       at: "left" + (left >= 0 ? "+" : "") + left + " " +
+                                               "top" + (top >= 0 ? "+" : "") + top,
+                                       of: that.window
+                               };
+                               $( this ).removeClass( "ui-dialog-resizing" );
+                               that._unblockFrames();
+                               that._trigger( "resizeStop", event, filteredUi( ui ) );
+                       }
+               })
+               .css( "position", position );
+       },
+
+       _trackFocus: function() {
+               this._on( this.widget(), {
+                       focusin: function( event ) {
+                               this._makeFocusTarget();
+                               this._focusedElement = $( event.target );
+                       }
+               });
+       },
+
+       _makeFocusTarget: function() {
+               this._untrackInstance();
+               this._trackingInstances().unshift( this );
+       },
+
+       _untrackInstance: function() {
+               var instances = this._trackingInstances(),
+                       exists = $.inArray( this, instances );
+               if ( exists !== -1 ) {
+                       instances.splice( exists, 1 );
+               }
+       },
+
+       _trackingInstances: function() {
+               var instances = this.document.data( "ui-dialog-instances" );
+               if ( !instances ) {
+                       instances = [];
+                       this.document.data( "ui-dialog-instances", instances );
+               }
+               return instances;
+       },
+
+       _minHeight: function() {
+               var options = this.options;
+
+               return options.height === "auto" ?
+                       options.minHeight :
+                       Math.min( options.minHeight, options.height );
+       },
+
+       _position: function() {
+               // Need to show the dialog to get the actual offset in the position plugin
+               var isVisible = this.uiDialog.is( ":visible" );
+               if ( !isVisible ) {
+                       this.uiDialog.show();
+               }
+               this.uiDialog.position( this.options.position );
+               if ( !isVisible ) {
+                       this.uiDialog.hide();
+               }
+       },
+
+       _setOptions: function( options ) {
+               var that = this,
+                       resize = false,
+                       resizableOptions = {};
+
+               $.each( options, function( key, value ) {
+                       that._setOption( key, value );
+
+                       if ( key in that.sizeRelatedOptions ) {
+                               resize = true;
+                       }
+                       if ( key in that.resizableRelatedOptions ) {
+                               resizableOptions[ key ] = value;
+                       }
+               });
+
+               if ( resize ) {
+                       this._size();
+                       this._position();
+               }
+               if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+                       this.uiDialog.resizable( "option", resizableOptions );
+               }
+       },
+
+       _setOption: function( key, value ) {
+               var isDraggable, isResizable,
+                       uiDialog = this.uiDialog;
+
+               if ( key === "dialogClass" ) {
+                       uiDialog
+                               .removeClass( this.options.dialogClass )
+                               .addClass( value );
+               }
+
+               if ( key === "disabled" ) {
+                       return;
+               }
+
+               this._super( key, value );
+
+               if ( key === "appendTo" ) {
+                       this.uiDialog.appendTo( this._appendTo() );
+               }
+
+               if ( key === "buttons" ) {
+                       this._createButtons();
+               }
+
+               if ( key === "closeText" ) {
+                       this.uiDialogTitlebarClose.button({
+                               // Ensure that we always pass a string
+                               label: "" + value
+                       });
+               }
+
+               if ( key === "draggable" ) {
+                       isDraggable = uiDialog.is( ":data(ui-draggable)" );
+                       if ( isDraggable && !value ) {
+                               uiDialog.draggable( "destroy" );
+                       }
+
+                       if ( !isDraggable && value ) {
+                               this._makeDraggable();
+                       }
+               }
+
+               if ( key === "position" ) {
+                       this._position();
+               }
+
+               if ( key === "resizable" ) {
+                       // currently resizable, becoming non-resizable
+                       isResizable = uiDialog.is( ":data(ui-resizable)" );
+                       if ( isResizable && !value ) {
+                               uiDialog.resizable( "destroy" );
+                       }
+
+                       // currently resizable, changing handles
+                       if ( isResizable && typeof value === "string" ) {
+                               uiDialog.resizable( "option", "handles", value );
+                       }
+
+                       // currently non-resizable, becoming resizable
+                       if ( !isResizable && value !== false ) {
+                               this._makeResizable();
+                       }
+               }
+
+               if ( key === "title" ) {
+                       this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
+               }
+       },
+
+       _size: function() {
+               // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+               // divs will both have width and height set, so we need to reset them
+               var nonContentHeight, minContentHeight, maxContentHeight,
+                       options = this.options;
+
+               // Reset content sizing
+               this.element.show().css({
+                       width: "auto",
+                       minHeight: 0,
+                       maxHeight: "none",
+                       height: 0
+               });
+
+               if ( options.minWidth > options.width ) {
+                       options.width = options.minWidth;
+               }
+
+               // reset wrapper sizing
+               // determine the height of all the non-content elements
+               nonContentHeight = this.uiDialog.css({
+                               height: "auto",
+                               width: options.width
+                       })
+                       .outerHeight();
+               minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+               maxContentHeight = typeof options.maxHeight === "number" ?
+                       Math.max( 0, options.maxHeight - nonContentHeight ) :
+                       "none";
+
+               if ( options.height === "auto" ) {
+                       this.element.css({
+                               minHeight: minContentHeight,
+                               maxHeight: maxContentHeight,
+                               height: "auto"
+                       });
+               } else {
+                       this.element.height( Math.max( 0, options.height - nonContentHeight ) );
+               }
+
+               if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+                       this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
+               }
+       },
+
+       _blockFrames: function() {
+               this.iframeBlocks = this.document.find( "iframe" ).map(function() {
+                       var iframe = $( this );
+
+                       return $( "<div>" )
+                               .css({
+                                       position: "absolute",
+                                       width: iframe.outerWidth(),
+                                       height: iframe.outerHeight()
+                               })
+                               .appendTo( iframe.parent() )
+                               .offset( iframe.offset() )[0];
+               });
+       },
+
+       _unblockFrames: function() {
+               if ( this.iframeBlocks ) {
+                       this.iframeBlocks.remove();
+                       delete this.iframeBlocks;
+               }
+       },
+
+       _allowInteraction: function( event ) {
+               if ( $( event.target ).closest( ".ui-dialog" ).length ) {
+                       return true;
+               }
+
+               // TODO: Remove hack when datepicker implements
+               // the .ui-front logic (#8989)
+               return !!$( event.target ).closest( ".ui-datepicker" ).length;
+       },
+
+       _createOverlay: function() {
+               if ( !this.options.modal ) {
+                       return;
+               }
+
+               // We use a delay in case the overlay is created from an
+               // event that we're going to be cancelling (#2804)
+               var isOpening = true;
+               this._delay(function() {
+                       isOpening = false;
+               });
+
+               if ( !this.document.data( "ui-dialog-overlays" ) ) {
+
+                       // Prevent use of anchors and inputs
+                       // Using _on() for an event handler shared across many instances is
+                       // safe because the dialogs stack and must be closed in reverse order
+                       this._on( this.document, {
+                               focusin: function( event ) {
+                                       if ( isOpening ) {
+                                               return;
+                                       }
+
+                                       if ( !this._allowInteraction( event ) ) {
+                                               event.preventDefault();
+                                               this._trackingInstances()[ 0 ]._focusTabbable();
+                                       }
+                               }
+                       });
+               }
+
+               this.overlay = $( "<div>" )
+                       .addClass( "ui-widget-overlay ui-front" )
+                       .appendTo( this._appendTo() );
+               this._on( this.overlay, {
+                       mousedown: "_keepFocus"
+               });
+               this.document.data( "ui-dialog-overlays",
+                       (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
+       },
+
+       _destroyOverlay: function() {
+               if ( !this.options.modal ) {
+                       return;
+               }
+
+               if ( this.overlay ) {
+                       var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
+
+                       if ( !overlays ) {
+                               this.document
+                                       .unbind( "focusin" )
+                                       .removeData( "ui-dialog-overlays" );
+                       } else {
+                               this.document.data( "ui-dialog-overlays", overlays );
+                       }
+
+                       this.overlay.remove();
+                       this.overlay = null;
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Droppable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/droppable/
+ */
+
+
+$.widget( "ui.droppable", {
+       version: "1.11.3",
+       widgetEventPrefix: "drop",
+       options: {
+               accept: "*",
+               activeClass: false,
+               addClasses: true,
+               greedy: false,
+               hoverClass: false,
+               scope: "default",
+               tolerance: "intersect",
+
+               // callbacks
+               activate: null,
+               deactivate: null,
+               drop: null,
+               out: null,
+               over: null
+       },
+       _create: function() {
+
+               var proportions,
+                       o = this.options,
+                       accept = o.accept;
+
+               this.isover = false;
+               this.isout = true;
+
+               this.accept = $.isFunction( accept ) ? accept : function( d ) {
+                       return d.is( accept );
+               };
+
+               this.proportions = function( /* valueToWrite */ ) {
+                       if ( arguments.length ) {
+                               // Store the droppable's proportions
+                               proportions = arguments[ 0 ];
+                       } else {
+                               // Retrieve or derive the droppable's proportions
+                               return proportions ?
+                                       proportions :
+                                       proportions = {
+                                               width: this.element[ 0 ].offsetWidth,
+                                               height: this.element[ 0 ].offsetHeight
+                                       };
+                       }
+               };
+
+               this._addToManager( o.scope );
+
+               o.addClasses && this.element.addClass( "ui-droppable" );
+
+       },
+
+       _addToManager: function( scope ) {
+               // Add the reference and positions to the manager
+               $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
+               $.ui.ddmanager.droppables[ scope ].push( this );
+       },
+
+       _splice: function( drop ) {
+               var i = 0;
+               for ( ; i < drop.length; i++ ) {
+                       if ( drop[ i ] === this ) {
+                               drop.splice( i, 1 );
+                       }
+               }
+       },
+
+       _destroy: function() {
+               var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+               this._splice( drop );
+
+               this.element.removeClass( "ui-droppable ui-droppable-disabled" );
+       },
+
+       _setOption: function( key, value ) {
+
+               if ( key === "accept" ) {
+                       this.accept = $.isFunction( value ) ? value : function( d ) {
+                               return d.is( value );
+                       };
+               } else if ( key === "scope" ) {
+                       var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+                       this._splice( drop );
+                       this._addToManager( value );
+               }
+
+               this._super( key, value );
+       },
+
+       _activate: function( event ) {
+               var draggable = $.ui.ddmanager.current;
+               if ( this.options.activeClass ) {
+                       this.element.addClass( this.options.activeClass );
+               }
+               if ( draggable ){
+                       this._trigger( "activate", event, this.ui( draggable ) );
+               }
+       },
+
+       _deactivate: function( event ) {
+               var draggable = $.ui.ddmanager.current;
+               if ( this.options.activeClass ) {
+                       this.element.removeClass( this.options.activeClass );
+               }
+               if ( draggable ){
+                       this._trigger( "deactivate", event, this.ui( draggable ) );
+               }
+       },
+
+       _over: function( event ) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.hoverClass ) {
+                               this.element.addClass( this.options.hoverClass );
+                       }
+                       this._trigger( "over", event, this.ui( draggable ) );
+               }
+
+       },
+
+       _out: function( event ) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.hoverClass ) {
+                               this.element.removeClass( this.options.hoverClass );
+                       }
+                       this._trigger( "out", event, this.ui( draggable ) );
+               }
+
+       },
+
+       _drop: function( event, custom ) {
+
+               var draggable = custom || $.ui.ddmanager.current,
+                       childrenIntersection = false;
+
+               // Bail if draggable and droppable are same element
+               if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
+                       return false;
+               }
+
+               this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
+                       var inst = $( this ).droppable( "instance" );
+                       if (
+                               inst.options.greedy &&
+                               !inst.options.disabled &&
+                               inst.options.scope === draggable.options.scope &&
+                               inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
+                               $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
+                       ) { childrenIntersection = true; return false; }
+               });
+               if ( childrenIntersection ) {
+                       return false;
+               }
+
+               if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                       if ( this.options.activeClass ) {
+                               this.element.removeClass( this.options.activeClass );
+                       }
+                       if ( this.options.hoverClass ) {
+                               this.element.removeClass( this.options.hoverClass );
+                       }
+                       this._trigger( "drop", event, this.ui( draggable ) );
+                       return this.element;
+               }
+
+               return false;
+
+       },
+
+       ui: function( c ) {
+               return {
+                       draggable: ( c.currentItem || c.element ),
+                       helper: c.helper,
+                       position: c.position,
+                       offset: c.positionAbs
+               };
+       }
+
+});
+
+$.ui.intersect = (function() {
+       function isOverAxis( x, reference, size ) {
+               return ( x >= reference ) && ( x < ( reference + size ) );
+       }
+
+       return function( draggable, droppable, toleranceMode, event ) {
+
+               if ( !droppable.offset ) {
+                       return false;
+               }
+
+               var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
+                       y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
+                       x2 = x1 + draggable.helperProportions.width,
+                       y2 = y1 + draggable.helperProportions.height,
+                       l = droppable.offset.left,
+                       t = droppable.offset.top,
+                       r = l + droppable.proportions().width,
+                       b = t + droppable.proportions().height;
+
+               switch ( toleranceMode ) {
+               case "fit":
+                       return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
+               case "intersect":
+                       return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
+                               x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
+                               t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
+                               y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
+               case "pointer":
+                       return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
+               case "touch":
+                       return (
+                               ( y1 >= t && y1 <= b ) || // Top edge touching
+                               ( y2 >= t && y2 <= b ) || // Bottom edge touching
+                               ( y1 < t && y2 > b ) // Surrounded vertically
+                       ) && (
+                               ( x1 >= l && x1 <= r ) || // Left edge touching
+                               ( x2 >= l && x2 <= r ) || // Right edge touching
+                               ( x1 < l && x2 > r ) // Surrounded horizontally
+                       );
+               default:
+                       return false;
+               }
+       };
+})();
+
+/*
+       This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+       current: null,
+       droppables: { "default": [] },
+       prepareOffsets: function( t, event ) {
+
+               var i, j,
+                       m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
+                       type = event ? event.type : null, // workaround for #2317
+                       list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
+
+               droppablesLoop: for ( i = 0; i < m.length; i++ ) {
+
+                       // No disabled and non-accepted
+                       if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
+                               continue;
+                       }
+
+                       // Filter out elements in the current dragged item
+                       for ( j = 0; j < list.length; j++ ) {
+                               if ( list[ j ] === m[ i ].element[ 0 ] ) {
+                                       m[ i ].proportions().height = 0;
+                                       continue droppablesLoop;
+                               }
+                       }
+
+                       m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
+                       if ( !m[ i ].visible ) {
+                               continue;
+                       }
+
+                       // Activate the droppable if used directly from draggables
+                       if ( type === "mousedown" ) {
+                               m[ i ]._activate.call( m[ i ], event );
+                       }
+
+                       m[ i ].offset = m[ i ].element.offset();
+                       m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
+
+               }
+
+       },
+       drop: function( draggable, event ) {
+
+               var dropped = false;
+               // Create a copy of the droppables in case the list changes during the drop (#9116)
+               $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
+
+                       if ( !this.options ) {
+                               return;
+                       }
+                       if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
+                               dropped = this._drop.call( this, event ) || dropped;
+                       }
+
+                       if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
+                               this.isout = true;
+                               this.isover = false;
+                               this._deactivate.call( this, event );
+                       }
+
+               });
+               return dropped;
+
+       },
+       dragStart: function( draggable, event ) {
+               // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+               draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
+                       if ( !draggable.options.refreshPositions ) {
+                               $.ui.ddmanager.prepareOffsets( draggable, event );
+                       }
+               });
+       },
+       drag: function( draggable, event ) {
+
+               // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+               if ( draggable.options.refreshPositions ) {
+                       $.ui.ddmanager.prepareOffsets( draggable, event );
+               }
+
+               // Run through all droppables and check their positions based on specific tolerance options
+               $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
+
+                       if ( this.options.disabled || this.greedyChild || !this.visible ) {
+                               return;
+                       }
+
+                       var parentInstance, scope, parent,
+                               intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
+                               c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
+                       if ( !c ) {
+                               return;
+                       }
+
+                       if ( this.options.greedy ) {
+                               // find droppable parents with same scope
+                               scope = this.options.scope;
+                               parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
+                                       return $( this ).droppable( "instance" ).options.scope === scope;
+                               });
+
+                               if ( parent.length ) {
+                                       parentInstance = $( parent[ 0 ] ).droppable( "instance" );
+                                       parentInstance.greedyChild = ( c === "isover" );
+                               }
+                       }
+
+                       // we just moved into a greedy child
+                       if ( parentInstance && c === "isover" ) {
+                               parentInstance.isover = false;
+                               parentInstance.isout = true;
+                               parentInstance._out.call( parentInstance, event );
+                       }
+
+                       this[ c ] = true;
+                       this[c === "isout" ? "isover" : "isout"] = false;
+                       this[c === "isover" ? "_over" : "_out"].call( this, event );
+
+                       // we just moved out of a greedy child
+                       if ( parentInstance && c === "isout" ) {
+                               parentInstance.isout = false;
+                               parentInstance.isover = true;
+                               parentInstance._over.call( parentInstance, event );
+                       }
+               });
+
+       },
+       dragStop: function( draggable, event ) {
+               draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
+               // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+               if ( !draggable.options.refreshPositions ) {
+                       $.ui.ddmanager.prepareOffsets( draggable, event );
+               }
+       }
+};
+
+var droppable = $.ui.droppable;
+
+
+/*!
+ * jQuery UI Effects 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/effects-core/
+ */
+
+
+var dataSpace = "ui-effects-",
+
+       // Create a local jQuery because jQuery Color relies on it and the
+       // global may not exist with AMD and a custom build (#10199)
+       jQuery = $;
+
+$.effects = {
+       effect: {}
+};
+
+/*!
+ * jQuery Color Animations v2.1.2
+ * https://github.com/jquery/jquery-color
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * Date: Wed Jan 16 08:47:09 2013 -0600
+ */
+(function( jQuery, undefined ) {
+
+       var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
+
+       // plusequals test for += 100 -= 100
+       rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
+       // a set of RE's that can match strings and generate color tuples.
+       stringParsers = [ {
+                       re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ],
+                                       execResult[ 3 ],
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ] * 2.55,
+                                       execResult[ 2 ] * 2.55,
+                                       execResult[ 3 ] * 2.55,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       space: "hsla",
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ] / 100,
+                                       execResult[ 3 ] / 100,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               } ],
+
+       // jQuery.Color( )
+       color = jQuery.Color = function( color, green, blue, alpha ) {
+               return new jQuery.Color.fn.parse( color, green, blue, alpha );
+       },
+       spaces = {
+               rgba: {
+                       props: {
+                               red: {
+                                       idx: 0,
+                                       type: "byte"
+                               },
+                               green: {
+                                       idx: 1,
+                                       type: "byte"
+                               },
+                               blue: {
+                                       idx: 2,
+                                       type: "byte"
+                               }
+                       }
+               },
+
+               hsla: {
+                       props: {
+                               hue: {
+                                       idx: 0,
+                                       type: "degrees"
+                               },
+                               saturation: {
+                                       idx: 1,
+                                       type: "percent"
+                               },
+                               lightness: {
+                                       idx: 2,
+                                       type: "percent"
+                               }
+                       }
+               }
+       },
+       propTypes = {
+               "byte": {
+                       floor: true,
+                       max: 255
+               },
+               "percent": {
+                       max: 1
+               },
+               "degrees": {
+                       mod: 360,
+                       floor: true
+               }
+       },
+       support = color.support = {},
+
+       // element for support tests
+       supportElem = jQuery( "<p>" )[ 0 ],
+
+       // colors = jQuery.Color.names
+       colors,
+
+       // local aliases of functions called often
+       each = jQuery.each;
+
+// determine rgba support immediately
+supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
+support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
+
+// define cache name and alpha properties
+// for rgba and hsla spaces
+each( spaces, function( spaceName, space ) {
+       space.cache = "_" + spaceName;
+       space.props.alpha = {
+               idx: 3,
+               type: "percent",
+               def: 1
+       };
+});
+
+function clamp( value, prop, allowEmpty ) {
+       var type = propTypes[ prop.type ] || {};
+
+       if ( value == null ) {
+               return (allowEmpty || !prop.def) ? null : prop.def;
+       }
+
+       // ~~ is an short way of doing floor for positive numbers
+       value = type.floor ? ~~value : parseFloat( value );
+
+       // IE will pass in empty strings as value for alpha,
+       // which will hit this case
+       if ( isNaN( value ) ) {
+               return prop.def;
+       }
+
+       if ( type.mod ) {
+               // we add mod before modding to make sure that negatives values
+               // get converted properly: -10 -> 350
+               return (value + type.mod) % type.mod;
+       }
+
+       // for now all property types without mod have min and max
+       return 0 > value ? 0 : type.max < value ? type.max : value;
+}
+
+function stringParse( string ) {
+       var inst = color(),
+               rgba = inst._rgba = [];
+
+       string = string.toLowerCase();
+
+       each( stringParsers, function( i, parser ) {
+               var parsed,
+                       match = parser.re.exec( string ),
+                       values = match && parser.parse( match ),
+                       spaceName = parser.space || "rgba";
+
+               if ( values ) {
+                       parsed = inst[ spaceName ]( values );
+
+                       // if this was an rgba parse the assignment might happen twice
+                       // oh well....
+                       inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
+                       rgba = inst._rgba = parsed._rgba;
+
+                       // exit each( stringParsers ) here because we matched
+                       return false;
+               }
+       });
+
+       // Found a stringParser that handled it
+       if ( rgba.length ) {
+
+               // if this came from a parsed string, force "transparent" when alpha is 0
+               // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
+               if ( rgba.join() === "0,0,0,0" ) {
+                       jQuery.extend( rgba, colors.transparent );
+               }
+               return inst;
+       }
+
+       // named colors
+       return colors[ string ];
+}
+
+color.fn = jQuery.extend( color.prototype, {
+       parse: function( red, green, blue, alpha ) {
+               if ( red === undefined ) {
+                       this._rgba = [ null, null, null, null ];
+                       return this;
+               }
+               if ( red.jquery || red.nodeType ) {
+                       red = jQuery( red ).css( green );
+                       green = undefined;
+               }
+
+               var inst = this,
+                       type = jQuery.type( red ),
+                       rgba = this._rgba = [];
+
+               // more than 1 argument specified - assume ( red, green, blue, alpha )
+               if ( green !== undefined ) {
+                       red = [ red, green, blue, alpha ];
+                       type = "array";
+               }
+
+               if ( type === "string" ) {
+                       return this.parse( stringParse( red ) || colors._default );
+               }
+
+               if ( type === "array" ) {
+                       each( spaces.rgba.props, function( key, prop ) {
+                               rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
+                       });
+                       return this;
+               }
+
+               if ( type === "object" ) {
+                       if ( red instanceof color ) {
+                               each( spaces, function( spaceName, space ) {
+                                       if ( red[ space.cache ] ) {
+                                               inst[ space.cache ] = red[ space.cache ].slice();
+                                       }
+                               });
+                       } else {
+                               each( spaces, function( spaceName, space ) {
+                                       var cache = space.cache;
+                                       each( space.props, function( key, prop ) {
+
+                                               // if the cache doesn't exist, and we know how to convert
+                                               if ( !inst[ cache ] && space.to ) {
+
+                                                       // if the value was null, we don't need to copy it
+                                                       // if the key was alpha, we don't need to copy it either
+                                                       if ( key === "alpha" || red[ key ] == null ) {
+                                                               return;
+                                                       }
+                                                       inst[ cache ] = space.to( inst._rgba );
+                                               }
+
+                                               // this is the only case where we allow nulls for ALL properties.
+                                               // call clamp with alwaysAllowEmpty
+                                               inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
+                                       });
+
+                                       // everything defined but alpha?
+                                       if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
+                                               // use the default of 1
+                                               inst[ cache ][ 3 ] = 1;
+                                               if ( space.from ) {
+                                                       inst._rgba = space.from( inst[ cache ] );
+                                               }
+                                       }
+                               });
+                       }
+                       return this;
+               }
+       },
+       is: function( compare ) {
+               var is = color( compare ),
+                       same = true,
+                       inst = this;
+
+               each( spaces, function( _, space ) {
+                       var localCache,
+                               isCache = is[ space.cache ];
+                       if (isCache) {
+                               localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
+                               each( space.props, function( _, prop ) {
+                                       if ( isCache[ prop.idx ] != null ) {
+                                               same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
+                                               return same;
+                                       }
+                               });
+                       }
+                       return same;
+               });
+               return same;
+       },
+       _space: function() {
+               var used = [],
+                       inst = this;
+               each( spaces, function( spaceName, space ) {
+                       if ( inst[ space.cache ] ) {
+                               used.push( spaceName );
+                       }
+               });
+               return used.pop();
+       },
+       transition: function( other, distance ) {
+               var end = color( other ),
+                       spaceName = end._space(),
+                       space = spaces[ spaceName ],
+                       startColor = this.alpha() === 0 ? color( "transparent" ) : this,
+                       start = startColor[ space.cache ] || space.to( startColor._rgba ),
+                       result = start.slice();
+
+               end = end[ space.cache ];
+               each( space.props, function( key, prop ) {
+                       var index = prop.idx,
+                               startValue = start[ index ],
+                               endValue = end[ index ],
+                               type = propTypes[ prop.type ] || {};
+
+                       // if null, don't override start value
+                       if ( endValue === null ) {
+                               return;
+                       }
+                       // if null - use end
+                       if ( startValue === null ) {
+                               result[ index ] = endValue;
+                       } else {
+                               if ( type.mod ) {
+                                       if ( endValue - startValue > type.mod / 2 ) {
+                                               startValue += type.mod;
+                                       } else if ( startValue - endValue > type.mod / 2 ) {
+                                               startValue -= type.mod;
+                                       }
+                               }
+                               result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
+                       }
+               });
+               return this[ spaceName ]( result );
+       },
+       blend: function( opaque ) {
+               // if we are already opaque - return ourself
+               if ( this._rgba[ 3 ] === 1 ) {
+                       return this;
+               }
+
+               var rgb = this._rgba.slice(),
+                       a = rgb.pop(),
+                       blend = color( opaque )._rgba;
+
+               return color( jQuery.map( rgb, function( v, i ) {
+                       return ( 1 - a ) * blend[ i ] + a * v;
+               }));
+       },
+       toRgbaString: function() {
+               var prefix = "rgba(",
+                       rgba = jQuery.map( this._rgba, function( v, i ) {
+                               return v == null ? ( i > 2 ? 1 : 0 ) : v;
+                       });
+
+               if ( rgba[ 3 ] === 1 ) {
+                       rgba.pop();
+                       prefix = "rgb(";
+               }
+
+               return prefix + rgba.join() + ")";
+       },
+       toHslaString: function() {
+               var prefix = "hsla(",
+                       hsla = jQuery.map( this.hsla(), function( v, i ) {
+                               if ( v == null ) {
+                                       v = i > 2 ? 1 : 0;
+                               }
+
+                               // catch 1 and 2
+                               if ( i && i < 3 ) {
+                                       v = Math.round( v * 100 ) + "%";
+                               }
+                               return v;
+                       });
+
+               if ( hsla[ 3 ] === 1 ) {
+                       hsla.pop();
+                       prefix = "hsl(";
+               }
+               return prefix + hsla.join() + ")";
+       },
+       toHexString: function( includeAlpha ) {
+               var rgba = this._rgba.slice(),
+                       alpha = rgba.pop();
+
+               if ( includeAlpha ) {
+                       rgba.push( ~~( alpha * 255 ) );
+               }
+
+               return "#" + jQuery.map( rgba, function( v ) {
+
+                       // default to 0 when nulls exist
+                       v = ( v || 0 ).toString( 16 );
+                       return v.length === 1 ? "0" + v : v;
+               }).join("");
+       },
+       toString: function() {
+               return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
+       }
+});
+color.fn.parse.prototype = color.fn;
+
+// hsla conversions adapted from:
+// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
+
+function hue2rgb( p, q, h ) {
+       h = ( h + 1 ) % 1;
+       if ( h * 6 < 1 ) {
+               return p + ( q - p ) * h * 6;
+       }
+       if ( h * 2 < 1) {
+               return q;
+       }
+       if ( h * 3 < 2 ) {
+               return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
+       }
+       return p;
+}
+
+spaces.hsla.to = function( rgba ) {
+       if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
+               return [ null, null, null, rgba[ 3 ] ];
+       }
+       var r = rgba[ 0 ] / 255,
+               g = rgba[ 1 ] / 255,
+               b = rgba[ 2 ] / 255,
+               a = rgba[ 3 ],
+               max = Math.max( r, g, b ),
+               min = Math.min( r, g, b ),
+               diff = max - min,
+               add = max + min,
+               l = add * 0.5,
+               h, s;
+
+       if ( min === max ) {
+               h = 0;
+       } else if ( r === max ) {
+               h = ( 60 * ( g - b ) / diff ) + 360;
+       } else if ( g === max ) {
+               h = ( 60 * ( b - r ) / diff ) + 120;
+       } else {
+               h = ( 60 * ( r - g ) / diff ) + 240;
+       }
+
+       // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
+       // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
+       if ( diff === 0 ) {
+               s = 0;
+       } else if ( l <= 0.5 ) {
+               s = diff / add;
+       } else {
+               s = diff / ( 2 - add );
+       }
+       return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
+};
+
+spaces.hsla.from = function( hsla ) {
+       if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
+               return [ null, null, null, hsla[ 3 ] ];
+       }
+       var h = hsla[ 0 ] / 360,
+               s = hsla[ 1 ],
+               l = hsla[ 2 ],
+               a = hsla[ 3 ],
+               q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
+               p = 2 * l - q;
+
+       return [
+               Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
+               Math.round( hue2rgb( p, q, h ) * 255 ),
+               Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
+               a
+       ];
+};
+
+each( spaces, function( spaceName, space ) {
+       var props = space.props,
+               cache = space.cache,
+               to = space.to,
+               from = space.from;
+
+       // makes rgba() and hsla()
+       color.fn[ spaceName ] = function( value ) {
+
+               // generate a cache for this space if it doesn't exist
+               if ( to && !this[ cache ] ) {
+                       this[ cache ] = to( this._rgba );
+               }
+               if ( value === undefined ) {
+                       return this[ cache ].slice();
+               }
+
+               var ret,
+                       type = jQuery.type( value ),
+                       arr = ( type === "array" || type === "object" ) ? value : arguments,
+                       local = this[ cache ].slice();
+
+               each( props, function( key, prop ) {
+                       var val = arr[ type === "object" ? key : prop.idx ];
+                       if ( val == null ) {
+                               val = local[ prop.idx ];
+                       }
+                       local[ prop.idx ] = clamp( val, prop );
+               });
+
+               if ( from ) {
+                       ret = color( from( local ) );
+                       ret[ cache ] = local;
+                       return ret;
+               } else {
+                       return color( local );
+               }
+       };
+
+       // makes red() green() blue() alpha() hue() saturation() lightness()
+       each( props, function( key, prop ) {
+               // alpha is included in more than one space
+               if ( color.fn[ key ] ) {
+                       return;
+               }
+               color.fn[ key ] = function( value ) {
+                       var vtype = jQuery.type( value ),
+                               fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
+                               local = this[ fn ](),
+                               cur = local[ prop.idx ],
+                               match;
+
+                       if ( vtype === "undefined" ) {
+                               return cur;
+                       }
+
+                       if ( vtype === "function" ) {
+                               value = value.call( this, cur );
+                               vtype = jQuery.type( value );
+                       }
+                       if ( value == null && prop.empty ) {
+                               return this;
+                       }
+                       if ( vtype === "string" ) {
+                               match = rplusequals.exec( value );
+                               if ( match ) {
+                                       value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
+                               }
+                       }
+                       local[ prop.idx ] = value;
+                       return this[ fn ]( local );
+               };
+       });
+});
+
+// add cssHook and .fx.step function for each named hook.
+// accept a space separated string of properties
+color.hook = function( hook ) {
+       var hooks = hook.split( " " );
+       each( hooks, function( i, hook ) {
+               jQuery.cssHooks[ hook ] = {
+                       set: function( elem, value ) {
+                               var parsed, curElem,
+                                       backgroundColor = "";
+
+                               if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
+                                       value = color( parsed || value );
+                                       if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
+                                               curElem = hook === "backgroundColor" ? elem.parentNode : elem;
+                                               while (
+                                                       (backgroundColor === "" || backgroundColor === "transparent") &&
+                                                       curElem && curElem.style
+                                               ) {
+                                                       try {
+                                                               backgroundColor = jQuery.css( curElem, "backgroundColor" );
+                                                               curElem = curElem.parentNode;
+                                                       } catch ( e ) {
+                                                       }
+                                               }
+
+                                               value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
+                                                       backgroundColor :
+                                                       "_default" );
+                                       }
+
+                                       value = value.toRgbaString();
+                               }
+                               try {
+                                       elem.style[ hook ] = value;
+                               } catch ( e ) {
+                                       // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
+                               }
+                       }
+               };
+               jQuery.fx.step[ hook ] = function( fx ) {
+                       if ( !fx.colorInit ) {
+                               fx.start = color( fx.elem, hook );
+                               fx.end = color( fx.end );
+                               fx.colorInit = true;
+                       }
+                       jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
+               };
+       });
+
+};
+
+color.hook( stepHooks );
+
+jQuery.cssHooks.borderColor = {
+       expand: function( value ) {
+               var expanded = {};
+
+               each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
+                       expanded[ "border" + part + "Color" ] = value;
+               });
+               return expanded;
+       }
+};
+
+// Basic color names only.
+// Usage of any of the other color names requires adding yourself or including
+// jquery.color.svg-names.js.
+colors = jQuery.Color.names = {
+       // 4.1. Basic color keywords
+       aqua: "#00ffff",
+       black: "#000000",
+       blue: "#0000ff",
+       fuchsia: "#ff00ff",
+       gray: "#808080",
+       green: "#008000",
+       lime: "#00ff00",
+       maroon: "#800000",
+       navy: "#000080",
+       olive: "#808000",
+       purple: "#800080",
+       red: "#ff0000",
+       silver: "#c0c0c0",
+       teal: "#008080",
+       white: "#ffffff",
+       yellow: "#ffff00",
+
+       // 4.2.3. "transparent" color keyword
+       transparent: [ null, null, null, 0 ],
+
+       _default: "#ffffff"
+};
+
+})( jQuery );
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+(function() {
+
+var classAnimationActions = [ "add", "remove", "toggle" ],
+       shorthandStyles = {
+               border: 1,
+               borderBottom: 1,
+               borderColor: 1,
+               borderLeft: 1,
+               borderRight: 1,
+               borderTop: 1,
+               borderWidth: 1,
+               margin: 1,
+               padding: 1
+       };
+
+$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
+       $.fx.step[ prop ] = function( fx ) {
+               if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
+                       jQuery.style( fx.elem, prop, fx.end );
+                       fx.setAttr = true;
+               }
+       };
+});
+
+function getElementStyles( elem ) {
+       var key, len,
+               style = elem.ownerDocument.defaultView ?
+                       elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+                       elem.currentStyle,
+               styles = {};
+
+       if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
+               len = style.length;
+               while ( len-- ) {
+                       key = style[ len ];
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ $.camelCase( key ) ] = style[ key ];
+                       }
+               }
+       // support: Opera, IE <9
+       } else {
+               for ( key in style ) {
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ key ] = style[ key ];
+                       }
+               }
+       }
+
+       return styles;
+}
+
+function styleDifference( oldStyle, newStyle ) {
+       var diff = {},
+               name, value;
+
+       for ( name in newStyle ) {
+               value = newStyle[ name ];
+               if ( oldStyle[ name ] !== value ) {
+                       if ( !shorthandStyles[ name ] ) {
+                               if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
+                                       diff[ name ] = value;
+                               }
+                       }
+               }
+       }
+
+       return diff;
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+$.effects.animateClass = function( value, duration, easing, callback ) {
+       var o = $.speed( duration, easing, callback );
+
+       return this.queue( function() {
+               var animated = $( this ),
+                       baseClass = animated.attr( "class" ) || "",
+                       applyClassChange,
+                       allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
+
+               // map the animated objects to store the original styles.
+               allAnimations = allAnimations.map(function() {
+                       var el = $( this );
+                       return {
+                               el: el,
+                               start: getElementStyles( this )
+                       };
+               });
+
+               // apply class change
+               applyClassChange = function() {
+                       $.each( classAnimationActions, function(i, action) {
+                               if ( value[ action ] ) {
+                                       animated[ action + "Class" ]( value[ action ] );
+                               }
+                       });
+               };
+               applyClassChange();
+
+               // map all animated objects again - calculate new styles and diff
+               allAnimations = allAnimations.map(function() {
+                       this.end = getElementStyles( this.el[ 0 ] );
+                       this.diff = styleDifference( this.start, this.end );
+                       return this;
+               });
+
+               // apply original class
+               animated.attr( "class", baseClass );
+
+               // map all animated objects again - this time collecting a promise
+               allAnimations = allAnimations.map(function() {
+                       var styleInfo = this,
+                               dfd = $.Deferred(),
+                               opts = $.extend({}, o, {
+                                       queue: false,
+                                       complete: function() {
+                                               dfd.resolve( styleInfo );
+                                       }
+                               });
+
+                       this.el.animate( this.diff, opts );
+                       return dfd.promise();
+               });
+
+               // once all animations have completed:
+               $.when.apply( $, allAnimations.get() ).done(function() {
+
+                       // set the final class
+                       applyClassChange();
+
+                       // for each animated element,
+                       // clear all css properties that were animated
+                       $.each( arguments, function() {
+                               var el = this.el;
+                               $.each( this.diff, function(key) {
+                                       el.css( key, "" );
+                               });
+                       });
+
+                       // this is guarnteed to be there if you use jQuery.speed()
+                       // it also handles dequeuing the next anim...
+                       o.complete.call( animated[ 0 ] );
+               });
+       });
+};
+
+$.fn.extend({
+       addClass: (function( orig ) {
+               return function( classNames, speed, easing, callback ) {
+                       return speed ?
+                               $.effects.animateClass.call( this,
+                                       { add: classNames }, speed, easing, callback ) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.addClass ),
+
+       removeClass: (function( orig ) {
+               return function( classNames, speed, easing, callback ) {
+                       return arguments.length > 1 ?
+                               $.effects.animateClass.call( this,
+                                       { remove: classNames }, speed, easing, callback ) :
+                               orig.apply( this, arguments );
+               };
+       })( $.fn.removeClass ),
+
+       toggleClass: (function( orig ) {
+               return function( classNames, force, speed, easing, callback ) {
+                       if ( typeof force === "boolean" || force === undefined ) {
+                               if ( !speed ) {
+                                       // without speed parameter
+                                       return orig.apply( this, arguments );
+                               } else {
+                                       return $.effects.animateClass.call( this,
+                                               (force ? { add: classNames } : { remove: classNames }),
+                                               speed, easing, callback );
+                               }
+                       } else {
+                               // without force parameter
+                               return $.effects.animateClass.call( this,
+                                       { toggle: classNames }, force, speed, easing );
+                       }
+               };
+       })( $.fn.toggleClass ),
+
+       switchClass: function( remove, add, speed, easing, callback) {
+               return $.effects.animateClass.call( this, {
+                       add: add,
+                       remove: remove
+               }, speed, easing, callback );
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+(function() {
+
+$.extend( $.effects, {
+       version: "1.11.3",
+
+       // Saves a set of properties in a data storage
+       save: function( element, set ) {
+               for ( var i = 0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
+                       }
+               }
+       },
+
+       // Restores a set of previously saved properties from a data storage
+       restore: function( element, set ) {
+               var val, i;
+               for ( i = 0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               val = element.data( dataSpace + set[ i ] );
+                               // support: jQuery 1.6.2
+                               // http://bugs.jquery.com/ticket/9917
+                               // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
+                               // We can't differentiate between "" and 0 here, so we just assume
+                               // empty string since it's likely to be a more common value...
+                               if ( val === undefined ) {
+                                       val = "";
+                               }
+                               element.css( set[ i ], val );
+                       }
+               }
+       },
+
+       setMode: function( el, mode ) {
+               if (mode === "toggle") {
+                       mode = el.is( ":hidden" ) ? "show" : "hide";
+               }
+               return mode;
+       },
+
+       // Translates a [top,left] array into a baseline value
+       // this should be a little more flexible in the future to handle a string & hash
+       getBaseline: function( origin, original ) {
+               var y, x;
+               switch ( origin[ 0 ] ) {
+                       case "top": y = 0; break;
+                       case "middle": y = 0.5; break;
+                       case "bottom": y = 1; break;
+                       default: y = origin[ 0 ] / original.height;
+               }
+               switch ( origin[ 1 ] ) {
+                       case "left": x = 0; break;
+                       case "center": x = 0.5; break;
+                       case "right": x = 1; break;
+                       default: x = origin[ 1 ] / original.width;
+               }
+               return {
+                       x: x,
+                       y: y
+               };
+       },
+
+       // Wraps the element around a wrapper that copies position properties
+       createWrapper: function( element ) {
+
+               // if the element is already wrapped, return it
+               if ( element.parent().is( ".ui-effects-wrapper" )) {
+                       return element.parent();
+               }
+
+               // wrap the element
+               var props = {
+                               width: element.outerWidth(true),
+                               height: element.outerHeight(true),
+                               "float": element.css( "float" )
+                       },
+                       wrapper = $( "<div></div>" )
+                               .addClass( "ui-effects-wrapper" )
+                               .css({
+                                       fontSize: "100%",
+                                       background: "transparent",
+                                       border: "none",
+                                       margin: 0,
+                                       padding: 0
+                               }),
+                       // Store the size in case width/height are defined in % - Fixes #5245
+                       size = {
+                               width: element.width(),
+                               height: element.height()
+                       },
+                       active = document.activeElement;
+
+               // support: Firefox
+               // Firefox incorrectly exposes anonymous content
+               // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
+               try {
+                       active.id;
+               } catch ( e ) {
+                       active = document.body;
+               }
+
+               element.wrap( wrapper );
+
+               // Fixes #7595 - Elements lose focus when wrapped.
+               if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                       $( active ).focus();
+               }
+
+               wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
+
+               // transfer positioning properties to the wrapper
+               if ( element.css( "position" ) === "static" ) {
+                       wrapper.css({ position: "relative" });
+                       element.css({ position: "relative" });
+               } else {
+                       $.extend( props, {
+                               position: element.css( "position" ),
+                               zIndex: element.css( "z-index" )
+                       });
+                       $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
+                               props[ pos ] = element.css( pos );
+                               if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
+                                       props[ pos ] = "auto";
+                               }
+                       });
+                       element.css({
+                               position: "relative",
+                               top: 0,
+                               left: 0,
+                               right: "auto",
+                               bottom: "auto"
+                       });
+               }
+               element.css(size);
+
+               return wrapper.css( props ).show();
+       },
+
+       removeWrapper: function( element ) {
+               var active = document.activeElement;
+
+               if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+                       element.parent().replaceWith( element );
+
+                       // Fixes #7595 - Elements lose focus when wrapped.
+                       if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                               $( active ).focus();
+                       }
+               }
+
+               return element;
+       },
+
+       setTransition: function( element, list, factor, value ) {
+               value = value || {};
+               $.each( list, function( i, x ) {
+                       var unit = element.cssUnit( x );
+                       if ( unit[ 0 ] > 0 ) {
+                               value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
+                       }
+               });
+               return value;
+       }
+});
+
+// return an effect options object for the given parameters:
+function _normalizeArguments( effect, options, speed, callback ) {
+
+       // allow passing all options as the first parameter
+       if ( $.isPlainObject( effect ) ) {
+               options = effect;
+               effect = effect.effect;
+       }
+
+       // convert to an object
+       effect = { effect: effect };
+
+       // catch (effect, null, ...)
+       if ( options == null ) {
+               options = {};
+       }
+
+       // catch (effect, callback)
+       if ( $.isFunction( options ) ) {
+               callback = options;
+               speed = null;
+               options = {};
+       }
+
+       // catch (effect, speed, ?)
+       if ( typeof options === "number" || $.fx.speeds[ options ] ) {
+               callback = speed;
+               speed = options;
+               options = {};
+       }
+
+       // catch (effect, options, callback)
+       if ( $.isFunction( speed ) ) {
+               callback = speed;
+               speed = null;
+       }
+
+       // add options to effect
+       if ( options ) {
+               $.extend( effect, options );
+       }
+
+       speed = speed || options.duration;
+       effect.duration = $.fx.off ? 0 :
+               typeof speed === "number" ? speed :
+               speed in $.fx.speeds ? $.fx.speeds[ speed ] :
+               $.fx.speeds._default;
+
+       effect.complete = callback || options.complete;
+
+       return effect;
+}
+
+function standardAnimationOption( option ) {
+       // Valid standard speeds (nothing, number, named speed)
+       if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
+               return true;
+       }
+
+       // Invalid strings - treat as "normal" speed
+       if ( typeof option === "string" && !$.effects.effect[ option ] ) {
+               return true;
+       }
+
+       // Complete callback
+       if ( $.isFunction( option ) ) {
+               return true;
+       }
+
+       // Options hash (but not naming an effect)
+       if ( typeof option === "object" && !option.effect ) {
+               return true;
+       }
+
+       // Didn't match any standard API
+       return false;
+}
+
+$.fn.extend({
+       effect: function( /* effect, options, speed, callback */ ) {
+               var args = _normalizeArguments.apply( this, arguments ),
+                       mode = args.mode,
+                       queue = args.queue,
+                       effectMethod = $.effects.effect[ args.effect ];
+
+               if ( $.fx.off || !effectMethod ) {
+                       // delegate to the original method (e.g., .show()) if possible
+                       if ( mode ) {
+                               return this[ mode ]( args.duration, args.complete );
+                       } else {
+                               return this.each( function() {
+                                       if ( args.complete ) {
+                                               args.complete.call( this );
+                                       }
+                               });
+                       }
+               }
+
+               function run( next ) {
+                       var elem = $( this ),
+                               complete = args.complete,
+                               mode = args.mode;
+
+                       function done() {
+                               if ( $.isFunction( complete ) ) {
+                                       complete.call( elem[0] );
+                               }
+                               if ( $.isFunction( next ) ) {
+                                       next();
+                               }
+                       }
+
+                       // If the element already has the correct final state, delegate to
+                       // the core methods so the internal tracking of "olddisplay" works.
+                       if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
+                               elem[ mode ]();
+                               done();
+                       } else {
+                               effectMethod.call( elem[0], args, done );
+                       }
+               }
+
+               return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
+       },
+
+       show: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "show";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.show ),
+
+       hide: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "hide";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.hide ),
+
+       toggle: (function( orig ) {
+               return function( option ) {
+                       if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
+                               return orig.apply( this, arguments );
+                       } else {
+                               var args = _normalizeArguments.apply( this, arguments );
+                               args.mode = "toggle";
+                               return this.effect.call( this, args );
+                       }
+               };
+       })( $.fn.toggle ),
+
+       // helper functions
+       cssUnit: function(key) {
+               var style = this.css( key ),
+                       val = [];
+
+               $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
+                       if ( style.indexOf( unit ) > 0 ) {
+                               val = [ parseFloat( style ), unit ];
+                       }
+               });
+               return val;
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+(function() {
+
+// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
+
+var baseEasings = {};
+
+$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
+       baseEasings[ name ] = function( p ) {
+               return Math.pow( p, i + 2 );
+       };
+});
+
+$.extend( baseEasings, {
+       Sine: function( p ) {
+               return 1 - Math.cos( p * Math.PI / 2 );
+       },
+       Circ: function( p ) {
+               return 1 - Math.sqrt( 1 - p * p );
+       },
+       Elastic: function( p ) {
+               return p === 0 || p === 1 ? p :
+                       -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
+       },
+       Back: function( p ) {
+               return p * p * ( 3 * p - 2 );
+       },
+       Bounce: function( p ) {
+               var pow2,
+                       bounce = 4;
+
+               while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
+               return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
+       }
+});
+
+$.each( baseEasings, function( name, easeIn ) {
+       $.easing[ "easeIn" + name ] = easeIn;
+       $.easing[ "easeOut" + name ] = function( p ) {
+               return 1 - easeIn( 1 - p );
+       };
+       $.easing[ "easeInOut" + name ] = function( p ) {
+               return p < 0.5 ?
+                       easeIn( p * 2 ) / 2 :
+                       1 - easeIn( p * -2 + 2 ) / 2;
+       };
+});
+
+})();
+
+var effect = $.effects;
+
+
+/*!
+ * jQuery UI Effects Blind 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/blind-effect/
+ */
+
+
+var effectBlind = $.effects.effect.blind = function( o, done ) {
+       // Create element
+       var el = $( this ),
+               rvertical = /up|down|vertical/,
+               rpositivemotion = /up|left|vertical|horizontal/,
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               direction = o.direction || "up",
+               vertical = rvertical.test( direction ),
+               ref = vertical ? "height" : "width",
+               ref2 = vertical ? "top" : "left",
+               motion = rpositivemotion.test( direction ),
+               animation = {},
+               show = mode === "show",
+               wrapper, distance, margin;
+
+       // if already wrapped, the wrapper's properties are my property. #6245
+       if ( el.parent().is( ".ui-effects-wrapper" ) ) {
+               $.effects.save( el.parent(), props );
+       } else {
+               $.effects.save( el, props );
+       }
+       el.show();
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+
+       distance = wrapper[ ref ]();
+       margin = parseFloat( wrapper.css( ref2 ) ) || 0;
+
+       animation[ ref ] = show ? distance : 0;
+       if ( !motion ) {
+               el
+                       .css( vertical ? "bottom" : "right", 0 )
+                       .css( vertical ? "top" : "left", "auto" )
+                       .css({ position: "absolute" });
+
+               animation[ ref2 ] = show ? margin : distance + margin;
+       }
+
+       // start at 0 if we are showing
+       if ( show ) {
+               wrapper.css( ref, 0 );
+               if ( !motion ) {
+                       wrapper.css( ref2, margin + distance );
+               }
+       }
+
+       // Animate
+       wrapper.animate( animation, {
+               duration: o.duration,
+               easing: o.easing,
+               queue: false,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Bounce 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/bounce-effect/
+ */
+
+
+var effectBounce = $.effects.effect.bounce = function( o, done ) {
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+
+               // defaults:
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               hide = mode === "hide",
+               show = mode === "show",
+               direction = o.direction || "up",
+               distance = o.distance,
+               times = o.times || 5,
+
+               // number of internal animations
+               anims = times * 2 + ( show || hide ? 1 : 0 ),
+               speed = o.duration / anims,
+               easing = o.easing,
+
+               // utility:
+               ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+               motion = ( direction === "up" || direction === "left" ),
+               i,
+               upAnim,
+               downAnim,
+
+               // we will need to re-assemble the queue to stack our animations in place
+               queue = el.queue(),
+               queuelen = queue.length;
+
+       // Avoid touching opacity to prevent clearType and PNG issues in IE
+       if ( show || hide ) {
+               props.push( "opacity" );
+       }
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el ); // Create Wrapper
+
+       // default distance for the BIGGEST bounce is the outer Distance / 3
+       if ( !distance ) {
+               distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
+       }
+
+       if ( show ) {
+               downAnim = { opacity: 1 };
+               downAnim[ ref ] = 0;
+
+               // if we are showing, force opacity 0 and set the initial position
+               // then do the "first" animation
+               el.css( "opacity", 0 )
+                       .css( ref, motion ? -distance * 2 : distance * 2 )
+                       .animate( downAnim, speed, easing );
+       }
+
+       // start at the smallest distance if we are hiding
+       if ( hide ) {
+               distance = distance / Math.pow( 2, times - 1 );
+       }
+
+       downAnim = {};
+       downAnim[ ref ] = 0;
+       // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
+       for ( i = 0; i < times; i++ ) {
+               upAnim = {};
+               upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+               el.animate( upAnim, speed, easing )
+                       .animate( downAnim, speed, easing );
+
+               distance = hide ? distance * 2 : distance / 2;
+       }
+
+       // Last Bounce when Hiding
+       if ( hide ) {
+               upAnim = { opacity: 0 };
+               upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+               el.animate( upAnim, speed, easing );
+       }
+
+       el.queue(function() {
+               if ( hide ) {
+                       el.hide();
+               }
+               $.effects.restore( el, props );
+               $.effects.removeWrapper( el );
+               done();
+       });
+
+       // inject all the animations we just queued to be first in line (after "inprogress")
+       if ( queuelen > 1) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       el.dequeue();
+
+};
+
+
+/*!
+ * jQuery UI Effects Clip 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/clip-effect/
+ */
+
+
+var effectClip = $.effects.effect.clip = function( o, done ) {
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               direction = o.direction || "vertical",
+               vert = direction === "vertical",
+               size = vert ? "height" : "width",
+               position = vert ? "top" : "left",
+               animation = {},
+               wrapper, animate, distance;
+
+       // Save & Show
+       $.effects.save( el, props );
+       el.show();
+
+       // Create Wrapper
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+       animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
+       distance = animate[ size ]();
+
+       // Shift
+       if ( show ) {
+               animate.css( size, 0 );
+               animate.css( position, distance / 2 );
+       }
+
+       // Create Animation Object:
+       animation[ size ] = show ? distance : 0;
+       animation[ position ] = show ? 0 : distance / 2;
+
+       // Animate
+       animate.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( !show ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+
+};
+
+
+/*!
+ * jQuery UI Effects Drop 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/drop-effect/
+ */
+
+
+var effectDrop = $.effects.effect.drop = function( o, done ) {
+
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               direction = o.direction || "left",
+               ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+               motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
+               animation = {
+                       opacity: show ? 1 : 0
+               },
+               distance;
+
+       // Adjust
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+
+       distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
+
+       if ( show ) {
+               el
+                       .css( "opacity", 0 )
+                       .css( ref, motion === "pos" ? -distance : distance );
+       }
+
+       // Animation
+       animation[ ref ] = ( show ?
+               ( motion === "pos" ? "+=" : "-=" ) :
+               ( motion === "pos" ? "-=" : "+=" ) ) +
+               distance;
+
+       // Animate
+       el.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Explode 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/explode-effect/
+ */
+
+
+var effectExplode = $.effects.effect.explode = function( o, done ) {
+
+       var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
+               cells = rows,
+               el = $( this ),
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+
+               // show and then visibility:hidden the element before calculating offset
+               offset = el.show().css( "visibility", "hidden" ).offset(),
+
+               // width and height of a piece
+               width = Math.ceil( el.outerWidth() / cells ),
+               height = Math.ceil( el.outerHeight() / rows ),
+               pieces = [],
+
+               // loop
+               i, j, left, top, mx, my;
+
+       // children animate complete:
+       function childComplete() {
+               pieces.push( this );
+               if ( pieces.length === rows * cells ) {
+                       animComplete();
+               }
+       }
+
+       // clone the element for each row and cell.
+       for ( i = 0; i < rows ; i++ ) { // ===>
+               top = offset.top + i * height;
+               my = i - ( rows - 1 ) / 2 ;
+
+               for ( j = 0; j < cells ; j++ ) { // |||
+                       left = offset.left + j * width;
+                       mx = j - ( cells - 1 ) / 2 ;
+
+                       // Create a clone of the now hidden main element that will be absolute positioned
+                       // within a wrapper div off the -left and -top equal to size of our pieces
+                       el
+                               .clone()
+                               .appendTo( "body" )
+                               .wrap( "<div></div>" )
+                               .css({
+                                       position: "absolute",
+                                       visibility: "visible",
+                                       left: -j * width,
+                                       top: -i * height
+                               })
+
+                       // select the wrapper - make it overflow: hidden and absolute positioned based on
+                       // where the original was located +left and +top equal to the size of pieces
+                               .parent()
+                               .addClass( "ui-effects-explode" )
+                               .css({
+                                       position: "absolute",
+                                       overflow: "hidden",
+                                       width: width,
+                                       height: height,
+                                       left: left + ( show ? mx * width : 0 ),
+                                       top: top + ( show ? my * height : 0 ),
+                                       opacity: show ? 0 : 1
+                               }).animate({
+                                       left: left + ( show ? 0 : mx * width ),
+                                       top: top + ( show ? 0 : my * height ),
+                                       opacity: show ? 1 : 0
+                               }, o.duration || 500, o.easing, childComplete );
+               }
+       }
+
+       function animComplete() {
+               el.css({
+                       visibility: "visible"
+               });
+               $( pieces ).remove();
+               if ( !show ) {
+                       el.hide();
+               }
+               done();
+       }
+};
+
+
+/*!
+ * jQuery UI Effects Fade 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/fade-effect/
+ */
+
+
+var effectFade = $.effects.effect.fade = function( o, done ) {
+       var el = $( this ),
+               mode = $.effects.setMode( el, o.mode || "toggle" );
+
+       el.animate({
+               opacity: mode
+       }, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: done
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Fold 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/fold-effect/
+ */
+
+
+var effectFold = $.effects.effect.fold = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "hide" ),
+               show = mode === "show",
+               hide = mode === "hide",
+               size = o.size || 15,
+               percent = /([0-9]+)%/.exec( size ),
+               horizFirst = !!o.horizFirst,
+               widthFirst = show !== horizFirst,
+               ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
+               duration = o.duration / 2,
+               wrapper, distance,
+               animation1 = {},
+               animation2 = {};
+
+       $.effects.save( el, props );
+       el.show();
+
+       // Create Wrapper
+       wrapper = $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+       distance = widthFirst ?
+               [ wrapper.width(), wrapper.height() ] :
+               [ wrapper.height(), wrapper.width() ];
+
+       if ( percent ) {
+               size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
+       }
+       if ( show ) {
+               wrapper.css( horizFirst ? {
+                       height: 0,
+                       width: size
+               } : {
+                       height: size,
+                       width: 0
+               });
+       }
+
+       // Animation
+       animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
+       animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
+
+       // Animate
+       wrapper
+               .animate( animation1, duration, o.easing )
+               .animate( animation2, duration, o.easing, function() {
+                       if ( hide ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               });
+
+};
+
+
+/*!
+ * jQuery UI Effects Highlight 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/highlight-effect/
+ */
+
+
+var effectHighlight = $.effects.effect.highlight = function( o, done ) {
+       var elem = $( this ),
+               props = [ "backgroundImage", "backgroundColor", "opacity" ],
+               mode = $.effects.setMode( elem, o.mode || "show" ),
+               animation = {
+                       backgroundColor: elem.css( "backgroundColor" )
+               };
+
+       if (mode === "hide") {
+               animation.opacity = 0;
+       }
+
+       $.effects.save( elem, props );
+
+       elem
+               .show()
+               .css({
+                       backgroundImage: "none",
+                       backgroundColor: o.color || "#ffff99"
+               })
+               .animate( animation, {
+                       queue: false,
+                       duration: o.duration,
+                       easing: o.easing,
+                       complete: function() {
+                               if ( mode === "hide" ) {
+                                       elem.hide();
+                               }
+                               $.effects.restore( elem, props );
+                               done();
+                       }
+               });
+};
+
+
+/*!
+ * jQuery UI Effects Size 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/size-effect/
+ */
+
+
+var effectSize = $.effects.effect.size = function( o, done ) {
+
+       // Create element
+       var original, baseline, factor,
+               el = $( this ),
+               props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
+
+               // Always restore
+               props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
+
+               // Copy for children
+               props2 = [ "width", "height", "overflow" ],
+               cProps = [ "fontSize" ],
+               vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
+               hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
+
+               // Set options
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               restore = o.restore || mode !== "effect",
+               scale = o.scale || "both",
+               origin = o.origin || [ "middle", "center" ],
+               position = el.css( "position" ),
+               props = restore ? props0 : props1,
+               zero = {
+                       height: 0,
+                       width: 0,
+                       outerHeight: 0,
+                       outerWidth: 0
+               };
+
+       if ( mode === "show" ) {
+               el.show();
+       }
+       original = {
+               height: el.height(),
+               width: el.width(),
+               outerHeight: el.outerHeight(),
+               outerWidth: el.outerWidth()
+       };
+
+       if ( o.mode === "toggle" && mode === "show" ) {
+               el.from = o.to || zero;
+               el.to = o.from || original;
+       } else {
+               el.from = o.from || ( mode === "show" ? zero : original );
+               el.to = o.to || ( mode === "hide" ? zero : original );
+       }
+
+       // Set scaling factor
+       factor = {
+               from: {
+                       y: el.from.height / original.height,
+                       x: el.from.width / original.width
+               },
+               to: {
+                       y: el.to.height / original.height,
+                       x: el.to.width / original.width
+               }
+       };
+
+       // Scale the css box
+       if ( scale === "box" || scale === "both" ) {
+
+               // Vertical props scaling
+               if ( factor.from.y !== factor.to.y ) {
+                       props = props.concat( vProps );
+                       el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
+                       el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
+               }
+
+               // Horizontal props scaling
+               if ( factor.from.x !== factor.to.x ) {
+                       props = props.concat( hProps );
+                       el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
+                       el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
+               }
+       }
+
+       // Scale the content
+       if ( scale === "content" || scale === "both" ) {
+
+               // Vertical props scaling
+               if ( factor.from.y !== factor.to.y ) {
+                       props = props.concat( cProps ).concat( props2 );
+                       el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
+                       el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
+               }
+       }
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+       el.css( "overflow", "hidden" ).css( el.from );
+
+       // Adjust
+       if (origin) { // Calculate baseline shifts
+               baseline = $.effects.getBaseline( origin, original );
+               el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
+               el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
+               el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
+               el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
+       }
+       el.css( el.from ); // set top & left
+
+       // Animate
+       if ( scale === "content" || scale === "both" ) { // Scale the children
+
+               // Add margins/font-size
+               vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
+               hProps = hProps.concat([ "marginLeft", "marginRight" ]);
+               props2 = props0.concat(vProps).concat(hProps);
+
+               el.find( "*[width]" ).each( function() {
+                       var child = $( this ),
+                               c_original = {
+                                       height: child.height(),
+                                       width: child.width(),
+                                       outerHeight: child.outerHeight(),
+                                       outerWidth: child.outerWidth()
+                               };
+                       if (restore) {
+                               $.effects.save(child, props2);
+                       }
+
+                       child.from = {
+                               height: c_original.height * factor.from.y,
+                               width: c_original.width * factor.from.x,
+                               outerHeight: c_original.outerHeight * factor.from.y,
+                               outerWidth: c_original.outerWidth * factor.from.x
+                       };
+                       child.to = {
+                               height: c_original.height * factor.to.y,
+                               width: c_original.width * factor.to.x,
+                               outerHeight: c_original.height * factor.to.y,
+                               outerWidth: c_original.width * factor.to.x
+                       };
+
+                       // Vertical props scaling
+                       if ( factor.from.y !== factor.to.y ) {
+                               child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
+                               child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
+                       }
+
+                       // Horizontal props scaling
+                       if ( factor.from.x !== factor.to.x ) {
+                               child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
+                               child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
+                       }
+
+                       // Animate children
+                       child.css( child.from );
+                       child.animate( child.to, o.duration, o.easing, function() {
+
+                               // Restore children
+                               if ( restore ) {
+                                       $.effects.restore( child, props2 );
+                               }
+                       });
+               });
+       }
+
+       // Animate
+       el.animate( el.to, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( el.to.opacity === 0 ) {
+                               el.css( "opacity", el.from.opacity );
+                       }
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       if ( !restore ) {
+
+                               // we need to calculate our new positioning based on the scaling
+                               if ( position === "static" ) {
+                                       el.css({
+                                               position: "relative",
+                                               top: el.to.top,
+                                               left: el.to.left
+                                       });
+                               } else {
+                                       $.each([ "top", "left" ], function( idx, pos ) {
+                                               el.css( pos, function( _, str ) {
+                                                       var val = parseInt( str, 10 ),
+                                                               toRef = idx ? el.to.left : el.to.top;
+
+                                                       // if original was "auto", recalculate the new value from wrapper
+                                                       if ( str === "auto" ) {
+                                                               return toRef + "px";
+                                                       }
+
+                                                       return val + toRef + "px";
+                                               });
+                                       });
+                               }
+                       }
+
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+
+};
+
+
+/*!
+ * jQuery UI Effects Scale 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/scale-effect/
+ */
+
+
+var effectScale = $.effects.effect.scale = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               options = $.extend( true, {}, o ),
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               percent = parseInt( o.percent, 10 ) ||
+                       ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
+               direction = o.direction || "both",
+               origin = o.origin,
+               original = {
+                       height: el.height(),
+                       width: el.width(),
+                       outerHeight: el.outerHeight(),
+                       outerWidth: el.outerWidth()
+               },
+               factor = {
+                       y: direction !== "horizontal" ? (percent / 100) : 1,
+                       x: direction !== "vertical" ? (percent / 100) : 1
+               };
+
+       // We are going to pass this effect to the size effect:
+       options.effect = "size";
+       options.queue = false;
+       options.complete = done;
+
+       // Set default origin and restore for show/hide
+       if ( mode !== "effect" ) {
+               options.origin = origin || [ "middle", "center" ];
+               options.restore = true;
+       }
+
+       options.from = o.from || ( mode === "show" ? {
+               height: 0,
+               width: 0,
+               outerHeight: 0,
+               outerWidth: 0
+       } : original );
+       options.to = {
+               height: original.height * factor.y,
+               width: original.width * factor.x,
+               outerHeight: original.outerHeight * factor.y,
+               outerWidth: original.outerWidth * factor.x
+       };
+
+       // Fade option to support puff
+       if ( options.fade ) {
+               if ( mode === "show" ) {
+                       options.from.opacity = 0;
+                       options.to.opacity = 1;
+               }
+               if ( mode === "hide" ) {
+                       options.from.opacity = 1;
+                       options.to.opacity = 0;
+               }
+       }
+
+       // Animate
+       el.effect( options );
+
+};
+
+
+/*!
+ * jQuery UI Effects Puff 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/puff-effect/
+ */
+
+
+var effectPuff = $.effects.effect.puff = function( o, done ) {
+       var elem = $( this ),
+               mode = $.effects.setMode( elem, o.mode || "hide" ),
+               hide = mode === "hide",
+               percent = parseInt( o.percent, 10 ) || 150,
+               factor = percent / 100,
+               original = {
+                       height: elem.height(),
+                       width: elem.width(),
+                       outerHeight: elem.outerHeight(),
+                       outerWidth: elem.outerWidth()
+               };
+
+       $.extend( o, {
+               effect: "scale",
+               queue: false,
+               fade: true,
+               mode: mode,
+               complete: done,
+               percent: hide ? percent : 100,
+               from: hide ?
+                       original :
+                       {
+                               height: original.height * factor,
+                               width: original.width * factor,
+                               outerHeight: original.outerHeight * factor,
+                               outerWidth: original.outerWidth * factor
+                       }
+       });
+
+       elem.effect( o );
+};
+
+
+/*!
+ * jQuery UI Effects Pulsate 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/pulsate-effect/
+ */
+
+
+var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
+       var elem = $( this ),
+               mode = $.effects.setMode( elem, o.mode || "show" ),
+               show = mode === "show",
+               hide = mode === "hide",
+               showhide = ( show || mode === "hide" ),
+
+               // showing or hiding leaves of the "last" animation
+               anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
+               duration = o.duration / anims,
+               animateTo = 0,
+               queue = elem.queue(),
+               queuelen = queue.length,
+               i;
+
+       if ( show || !elem.is(":visible")) {
+               elem.css( "opacity", 0 ).show();
+               animateTo = 1;
+       }
+
+       // anims - 1 opacity "toggles"
+       for ( i = 1; i < anims; i++ ) {
+               elem.animate({
+                       opacity: animateTo
+               }, duration, o.easing );
+               animateTo = 1 - animateTo;
+       }
+
+       elem.animate({
+               opacity: animateTo
+       }, duration, o.easing);
+
+       elem.queue(function() {
+               if ( hide ) {
+                       elem.hide();
+               }
+               done();
+       });
+
+       // We just queued up "anims" animations, we need to put them next in the queue
+       if ( queuelen > 1 ) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       elem.dequeue();
+};
+
+
+/*!
+ * jQuery UI Effects Shake 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/shake-effect/
+ */
+
+
+var effectShake = $.effects.effect.shake = function( o, done ) {
+
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
+               mode = $.effects.setMode( el, o.mode || "effect" ),
+               direction = o.direction || "left",
+               distance = o.distance || 20,
+               times = o.times || 3,
+               anims = times * 2 + 1,
+               speed = Math.round( o.duration / anims ),
+               ref = (direction === "up" || direction === "down") ? "top" : "left",
+               positiveMotion = (direction === "up" || direction === "left"),
+               animation = {},
+               animation1 = {},
+               animation2 = {},
+               i,
+
+               // we will need to re-assemble the queue to stack our animations in place
+               queue = el.queue(),
+               queuelen = queue.length;
+
+       $.effects.save( el, props );
+       el.show();
+       $.effects.createWrapper( el );
+
+       // Animation
+       animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
+       animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
+       animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
+
+       // Animate
+       el.animate( animation, speed, o.easing );
+
+       // Shakes
+       for ( i = 1; i < times; i++ ) {
+               el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
+       }
+       el
+               .animate( animation1, speed, o.easing )
+               .animate( animation, speed / 2, o.easing )
+               .queue(function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               });
+
+       // inject all the animations we just queued to be first in line (after "inprogress")
+       if ( queuelen > 1) {
+               queue.splice.apply( queue,
+                       [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
+       }
+       el.dequeue();
+
+};
+
+
+/*!
+ * jQuery UI Effects Slide 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/slide-effect/
+ */
+
+
+var effectSlide = $.effects.effect.slide = function( o, done ) {
+
+       // Create element
+       var el = $( this ),
+               props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
+               mode = $.effects.setMode( el, o.mode || "show" ),
+               show = mode === "show",
+               direction = o.direction || "left",
+               ref = (direction === "up" || direction === "down") ? "top" : "left",
+               positiveMotion = (direction === "up" || direction === "left"),
+               distance,
+               animation = {};
+
+       // Adjust
+       $.effects.save( el, props );
+       el.show();
+       distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
+
+       $.effects.createWrapper( el ).css({
+               overflow: "hidden"
+       });
+
+       if ( show ) {
+               el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
+       }
+
+       // Animation
+       animation[ ref ] = ( show ?
+               ( positiveMotion ? "+=" : "-=") :
+               ( positiveMotion ? "-=" : "+=")) +
+               distance;
+
+       // Animate
+       el.animate( animation, {
+               queue: false,
+               duration: o.duration,
+               easing: o.easing,
+               complete: function() {
+                       if ( mode === "hide" ) {
+                               el.hide();
+                       }
+                       $.effects.restore( el, props );
+                       $.effects.removeWrapper( el );
+                       done();
+               }
+       });
+};
+
+
+/*!
+ * jQuery UI Effects Transfer 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/transfer-effect/
+ */
+
+
+var effectTransfer = $.effects.effect.transfer = function( o, done ) {
+       var elem = $( this ),
+               target = $( o.to ),
+               targetFixed = target.css( "position" ) === "fixed",
+               body = $("body"),
+               fixTop = targetFixed ? body.scrollTop() : 0,
+               fixLeft = targetFixed ? body.scrollLeft() : 0,
+               endPosition = target.offset(),
+               animation = {
+                       top: endPosition.top - fixTop,
+                       left: endPosition.left - fixLeft,
+                       height: target.innerHeight(),
+                       width: target.innerWidth()
+               },
+               startPosition = elem.offset(),
+               transfer = $( "<div class='ui-effects-transfer'></div>" )
+                       .appendTo( document.body )
+                       .addClass( o.className )
+                       .css({
+                               top: startPosition.top - fixTop,
+                               left: startPosition.left - fixLeft,
+                               height: elem.innerHeight(),
+                               width: elem.innerWidth(),
+                               position: targetFixed ? "fixed" : "absolute"
+                       })
+                       .animate( animation, o.duration, o.easing, function() {
+                               transfer.remove();
+                               done();
+                       });
+};
+
+
+/*!
+ * jQuery UI Progressbar 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/progressbar/
+ */
+
+
+var progressbar = $.widget( "ui.progressbar", {
+       version: "1.11.3",
+       options: {
+               max: 100,
+               value: 0,
+
+               change: null,
+               complete: null
+       },
+
+       min: 0,
+
+       _create: function() {
+               // Constrain initial value
+               this.oldValue = this.options.value = this._constrainedValue();
+
+               this.element
+                       .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .attr({
+                               // Only set static values, aria-valuenow and aria-valuemax are
+                               // set inside _refreshValue()
+                               role: "progressbar",
+                               "aria-valuemin": this.min
+                       });
+
+               this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
+                       .appendTo( this.element );
+
+               this._refreshValue();
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-valuemin" )
+                       .removeAttr( "aria-valuemax" )
+                       .removeAttr( "aria-valuenow" );
+
+               this.valueDiv.remove();
+       },
+
+       value: function( newValue ) {
+               if ( newValue === undefined ) {
+                       return this.options.value;
+               }
+
+               this.options.value = this._constrainedValue( newValue );
+               this._refreshValue();
+       },
+
+       _constrainedValue: function( newValue ) {
+               if ( newValue === undefined ) {
+                       newValue = this.options.value;
+               }
+
+               this.indeterminate = newValue === false;
+
+               // sanitize value
+               if ( typeof newValue !== "number" ) {
+                       newValue = 0;
+               }
+
+               return this.indeterminate ? false :
+                       Math.min( this.options.max, Math.max( this.min, newValue ) );
+       },
+
+       _setOptions: function( options ) {
+               // Ensure "value" option is set after other values (like max)
+               var value = options.value;
+               delete options.value;
+
+               this._super( options );
+
+               this.options.value = this._constrainedValue( value );
+               this._refreshValue();
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "max" ) {
+                       // Don't allow a max less than min
+                       value = Math.max( this.min, value );
+               }
+               if ( key === "disabled" ) {
+                       this.element
+                               .toggleClass( "ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+               }
+               this._super( key, value );
+       },
+
+       _percentage: function() {
+               return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
+       },
+
+       _refreshValue: function() {
+               var value = this.options.value,
+                       percentage = this._percentage();
+
+               this.valueDiv
+                       .toggle( this.indeterminate || value > this.min )
+                       .toggleClass( "ui-corner-right", value === this.options.max )
+                       .width( percentage.toFixed(0) + "%" );
+
+               this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
+
+               if ( this.indeterminate ) {
+                       this.element.removeAttr( "aria-valuenow" );
+                       if ( !this.overlayDiv ) {
+                               this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
+                       }
+               } else {
+                       this.element.attr({
+                               "aria-valuemax": this.options.max,
+                               "aria-valuenow": value
+                       });
+                       if ( this.overlayDiv ) {
+                               this.overlayDiv.remove();
+                               this.overlayDiv = null;
+                       }
+               }
+
+               if ( this.oldValue !== value ) {
+                       this.oldValue = value;
+                       this._trigger( "change" );
+               }
+               if ( value === this.options.max ) {
+                       this._trigger( "complete" );
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Selectable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/selectable/
+ */
+
+
+var selectable = $.widget("ui.selectable", $.ui.mouse, {
+       version: "1.11.3",
+       options: {
+               appendTo: "body",
+               autoRefresh: true,
+               distance: 0,
+               filter: "*",
+               tolerance: "touch",
+
+               // callbacks
+               selected: null,
+               selecting: null,
+               start: null,
+               stop: null,
+               unselected: null,
+               unselecting: null
+       },
+       _create: function() {
+               var selectees,
+                       that = this;
+
+               this.element.addClass("ui-selectable");
+
+               this.dragged = false;
+
+               // cache selectee children based on filter
+               this.refresh = function() {
+                       selectees = $(that.options.filter, that.element[0]);
+                       selectees.addClass("ui-selectee");
+                       selectees.each(function() {
+                               var $this = $(this),
+                                       pos = $this.offset();
+                               $.data(this, "selectable-item", {
+                                       element: this,
+                                       $element: $this,
+                                       left: pos.left,
+                                       top: pos.top,
+                                       right: pos.left + $this.outerWidth(),
+                                       bottom: pos.top + $this.outerHeight(),
+                                       startselected: false,
+                                       selected: $this.hasClass("ui-selected"),
+                                       selecting: $this.hasClass("ui-selecting"),
+                                       unselecting: $this.hasClass("ui-unselecting")
+                               });
+                       });
+               };
+               this.refresh();
+
+               this.selectees = selectees.addClass("ui-selectee");
+
+               this._mouseInit();
+
+               this.helper = $("<div class='ui-selectable-helper'></div>");
+       },
+
+       _destroy: function() {
+               this.selectees
+                       .removeClass("ui-selectee")
+                       .removeData("selectable-item");
+               this.element
+                       .removeClass("ui-selectable ui-selectable-disabled");
+               this._mouseDestroy();
+       },
+
+       _mouseStart: function(event) {
+               var that = this,
+                       options = this.options;
+
+               this.opos = [ event.pageX, event.pageY ];
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               this.selectees = $(options.filter, this.element[0]);
+
+               this._trigger("start", event);
+
+               $(options.appendTo).append(this.helper);
+               // position helper (lasso)
+               this.helper.css({
+                       "left": event.pageX,
+                       "top": event.pageY,
+                       "width": 0,
+                       "height": 0
+               });
+
+               if (options.autoRefresh) {
+                       this.refresh();
+               }
+
+               this.selectees.filter(".ui-selected").each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.startselected = true;
+                       if (!event.metaKey && !event.ctrlKey) {
+                               selectee.$element.removeClass("ui-selected");
+                               selectee.selected = false;
+                               selectee.$element.addClass("ui-unselecting");
+                               selectee.unselecting = true;
+                               // selectable UNSELECTING callback
+                               that._trigger("unselecting", event, {
+                                       unselecting: selectee.element
+                               });
+                       }
+               });
+
+               $(event.target).parents().addBack().each(function() {
+                       var doSelect,
+                               selectee = $.data(this, "selectable-item");
+                       if (selectee) {
+                               doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
+                               selectee.$element
+                                       .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+                                       .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+                               selectee.unselecting = !doSelect;
+                               selectee.selecting = doSelect;
+                               selectee.selected = doSelect;
+                               // selectable (UN)SELECTING callback
+                               if (doSelect) {
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               } else {
+                                       that._trigger("unselecting", event, {
+                                               unselecting: selectee.element
+                                       });
+                               }
+                               return false;
+                       }
+               });
+
+       },
+
+       _mouseDrag: function(event) {
+
+               this.dragged = true;
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               var tmp,
+                       that = this,
+                       options = this.options,
+                       x1 = this.opos[0],
+                       y1 = this.opos[1],
+                       x2 = event.pageX,
+                       y2 = event.pageY;
+
+               if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
+               if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
+               this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
+
+               this.selectees.each(function() {
+                       var selectee = $.data(this, "selectable-item"),
+                               hit = false;
+
+                       //prevent helper from being selected if appendTo: selectable
+                       if (!selectee || selectee.element === that.element[0]) {
+                               return;
+                       }
+
+                       if (options.tolerance === "touch") {
+                               hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+                       } else if (options.tolerance === "fit") {
+                               hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+                       }
+
+                       if (hit) {
+                               // SELECT
+                               if (selectee.selected) {
+                                       selectee.$element.removeClass("ui-selected");
+                                       selectee.selected = false;
+                               }
+                               if (selectee.unselecting) {
+                                       selectee.$element.removeClass("ui-unselecting");
+                                       selectee.unselecting = false;
+                               }
+                               if (!selectee.selecting) {
+                                       selectee.$element.addClass("ui-selecting");
+                                       selectee.selecting = true;
+                                       // selectable SELECTING callback
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               }
+                       } else {
+                               // UNSELECT
+                               if (selectee.selecting) {
+                                       if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               selectee.$element.addClass("ui-selected");
+                                               selectee.selected = true;
+                                       } else {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               if (selectee.startselected) {
+                                                       selectee.$element.addClass("ui-unselecting");
+                                                       selectee.unselecting = true;
+                                               }
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                               if (selectee.selected) {
+                                       if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selected");
+                                               selectee.selected = false;
+
+                                               selectee.$element.addClass("ui-unselecting");
+                                               selectee.unselecting = true;
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                       }
+               });
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+               var that = this;
+
+               this.dragged = false;
+
+               $(".ui-unselecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-unselecting");
+                       selectee.unselecting = false;
+                       selectee.startselected = false;
+                       that._trigger("unselected", event, {
+                               unselected: selectee.element
+                       });
+               });
+               $(".ui-selecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
+                       selectee.selecting = false;
+                       selectee.selected = true;
+                       selectee.startselected = true;
+                       that._trigger("selected", event, {
+                               selected: selectee.element
+                       });
+               });
+               this._trigger("stop", event);
+
+               this.helper.remove();
+
+               return false;
+       }
+
+});
+
+
+/*!
+ * jQuery UI Selectmenu 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/selectmenu
+ */
+
+
+var selectmenu = $.widget( "ui.selectmenu", {
+       version: "1.11.3",
+       defaultElement: "<select>",
+       options: {
+               appendTo: null,
+               disabled: null,
+               icons: {
+                       button: "ui-icon-triangle-1-s"
+               },
+               position: {
+                       my: "left top",
+                       at: "left bottom",
+                       collision: "none"
+               },
+               width: null,
+
+               // callbacks
+               change: null,
+               close: null,
+               focus: null,
+               open: null,
+               select: null
+       },
+
+       _create: function() {
+               var selectmenuId = this.element.uniqueId().attr( "id" );
+               this.ids = {
+                       element: selectmenuId,
+                       button: selectmenuId + "-button",
+                       menu: selectmenuId + "-menu"
+               };
+
+               this._drawButton();
+               this._drawMenu();
+
+               if ( this.options.disabled ) {
+                       this.disable();
+               }
+       },
+
+       _drawButton: function() {
+               var that = this;
+
+               // Associate existing label with the new button
+               this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
+               this._on( this.label, {
+                       click: function( event ) {
+                               this.button.focus();
+                               event.preventDefault();
+                       }
+               });
+
+               // Hide original select element
+               this.element.hide();
+
+               // Create button
+               this.button = $( "<span>", {
+                       "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
+                       tabindex: this.options.disabled ? -1 : 0,
+                       id: this.ids.button,
+                       role: "combobox",
+                       "aria-expanded": "false",
+                       "aria-autocomplete": "list",
+                       "aria-owns": this.ids.menu,
+                       "aria-haspopup": "true"
+               })
+                       .insertAfter( this.element );
+
+               $( "<span>", {
+                       "class": "ui-icon " + this.options.icons.button
+               })
+                       .prependTo( this.button );
+
+               this.buttonText = $( "<span>", {
+                       "class": "ui-selectmenu-text"
+               })
+                       .appendTo( this.button );
+
+               this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
+               this._resizeButton();
+
+               this._on( this.button, this._buttonEvents );
+               this.button.one( "focusin", function() {
+
+                       // Delay rendering the menu items until the button receives focus.
+                       // The menu may have already been rendered via a programmatic open.
+                       if ( !that.menuItems ) {
+                               that._refreshMenu();
+                       }
+               });
+               this._hoverable( this.button );
+               this._focusable( this.button );
+       },
+
+       _drawMenu: function() {
+               var that = this;
+
+               // Create menu
+               this.menu = $( "<ul>", {
+                       "aria-hidden": "true",
+                       "aria-labelledby": this.ids.button,
+                       id: this.ids.menu
+               });
+
+               // Wrap menu
+               this.menuWrap = $( "<div>", {
+                       "class": "ui-selectmenu-menu ui-front"
+               })
+                       .append( this.menu )
+                       .appendTo( this._appendTo() );
+
+               // Initialize menu widget
+               this.menuInstance = this.menu
+                       .menu({
+                               role: "listbox",
+                               select: function( event, ui ) {
+                                       event.preventDefault();
+
+                                       // support: IE8
+                                       // If the item was selected via a click, the text selection
+                                       // will be destroyed in IE
+                                       that._setSelection();
+
+                                       that._select( ui.item.data( "ui-selectmenu-item" ), event );
+                               },
+                               focus: function( event, ui ) {
+                                       var item = ui.item.data( "ui-selectmenu-item" );
+
+                                       // Prevent inital focus from firing and check if its a newly focused item
+                                       if ( that.focusIndex != null && item.index !== that.focusIndex ) {
+                                               that._trigger( "focus", event, { item: item } );
+                                               if ( !that.isOpen ) {
+                                                       that._select( item, event );
+                                               }
+                                       }
+                                       that.focusIndex = item.index;
+
+                                       that.button.attr( "aria-activedescendant",
+                                               that.menuItems.eq( item.index ).attr( "id" ) );
+                               }
+                       })
+                       .menu( "instance" );
+
+               // Adjust menu styles to dropdown
+               this.menu
+                       .addClass( "ui-corner-bottom" )
+                       .removeClass( "ui-corner-all" );
+
+               // Don't close the menu on mouseleave
+               this.menuInstance._off( this.menu, "mouseleave" );
+
+               // Cancel the menu's collapseAll on document click
+               this.menuInstance._closeOnDocumentClick = function() {
+                       return false;
+               };
+
+               // Selects often contain empty items, but never contain dividers
+               this.menuInstance._isDivider = function() {
+                       return false;
+               };
+       },
+
+       refresh: function() {
+               this._refreshMenu();
+               this._setText( this.buttonText, this._getSelectedItem().text() );
+               if ( !this.options.width ) {
+                       this._resizeButton();
+               }
+       },
+
+       _refreshMenu: function() {
+               this.menu.empty();
+
+               var item,
+                       options = this.element.find( "option" );
+
+               if ( !options.length ) {
+                       return;
+               }
+
+               this._parseOptions( options );
+               this._renderMenu( this.menu, this.items );
+
+               this.menuInstance.refresh();
+               this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
+
+               item = this._getSelectedItem();
+
+               // Update the menu to have the correct item focused
+               this.menuInstance.focus( null, item );
+               this._setAria( item.data( "ui-selectmenu-item" ) );
+
+               // Set disabled state
+               this._setOption( "disabled", this.element.prop( "disabled" ) );
+       },
+
+       open: function( event ) {
+               if ( this.options.disabled ) {
+                       return;
+               }
+
+               // If this is the first time the menu is being opened, render the items
+               if ( !this.menuItems ) {
+                       this._refreshMenu();
+               } else {
+
+                       // Menu clears focus on close, reset focus to selected item
+                       this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
+                       this.menuInstance.focus( null, this._getSelectedItem() );
+               }
+
+               this.isOpen = true;
+               this._toggleAttr();
+               this._resizeMenu();
+               this._position();
+
+               this._on( this.document, this._documentClick );
+
+               this._trigger( "open", event );
+       },
+
+       _position: function() {
+               this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
+       },
+
+       close: function( event ) {
+               if ( !this.isOpen ) {
+                       return;
+               }
+
+               this.isOpen = false;
+               this._toggleAttr();
+
+               this.range = null;
+               this._off( this.document );
+
+               this._trigger( "close", event );
+       },
+
+       widget: function() {
+               return this.button;
+       },
+
+       menuWidget: function() {
+               return this.menu;
+       },
+
+       _renderMenu: function( ul, items ) {
+               var that = this,
+                       currentOptgroup = "";
+
+               $.each( items, function( index, item ) {
+                       if ( item.optgroup !== currentOptgroup ) {
+                               $( "<li>", {
+                                       "class": "ui-selectmenu-optgroup ui-menu-divider" +
+                                               ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
+                                                       " ui-state-disabled" :
+                                                       "" ),
+                                       text: item.optgroup
+                               })
+                                       .appendTo( ul );
+
+                               currentOptgroup = item.optgroup;
+                       }
+
+                       that._renderItemData( ul, item );
+               });
+       },
+
+       _renderItemData: function( ul, item ) {
+               return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
+       },
+
+       _renderItem: function( ul, item ) {
+               var li = $( "<li>" );
+
+               if ( item.disabled ) {
+                       li.addClass( "ui-state-disabled" );
+               }
+               this._setText( li, item.label );
+
+               return li.appendTo( ul );
+       },
+
+       _setText: function( element, value ) {
+               if ( value ) {
+                       element.text( value );
+               } else {
+                       element.html( "&#160;" );
+               }
+       },
+
+       _move: function( direction, event ) {
+               var item, next,
+                       filter = ".ui-menu-item";
+
+               if ( this.isOpen ) {
+                       item = this.menuItems.eq( this.focusIndex );
+               } else {
+                       item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
+                       filter += ":not(.ui-state-disabled)";
+               }
+
+               if ( direction === "first" || direction === "last" ) {
+                       next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
+               } else {
+                       next = item[ direction + "All" ]( filter ).eq( 0 );
+               }
+
+               if ( next.length ) {
+                       this.menuInstance.focus( event, next );
+               }
+       },
+
+       _getSelectedItem: function() {
+               return this.menuItems.eq( this.element[ 0 ].selectedIndex );
+       },
+
+       _toggle: function( event ) {
+               this[ this.isOpen ? "close" : "open" ]( event );
+       },
+
+       _setSelection: function() {
+               var selection;
+
+               if ( !this.range ) {
+                       return;
+               }
+
+               if ( window.getSelection ) {
+                       selection = window.getSelection();
+                       selection.removeAllRanges();
+                       selection.addRange( this.range );
+
+               // support: IE8
+               } else {
+                       this.range.select();
+               }
+
+               // support: IE
+               // Setting the text selection kills the button focus in IE, but
+               // restoring the focus doesn't kill the selection.
+               this.button.focus();
+       },
+
+       _documentClick: {
+               mousedown: function( event ) {
+                       if ( !this.isOpen ) {
+                               return;
+                       }
+
+                       if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
+                               this.close( event );
+                       }
+               }
+       },
+
+       _buttonEvents: {
+
+               // Prevent text selection from being reset when interacting with the selectmenu (#10144)
+               mousedown: function() {
+                       var selection;
+
+                       if ( window.getSelection ) {
+                               selection = window.getSelection();
+                               if ( selection.rangeCount ) {
+                                       this.range = selection.getRangeAt( 0 );
+                               }
+
+                       // support: IE8
+                       } else {
+                               this.range = document.selection.createRange();
+                       }
+               },
+
+               click: function( event ) {
+                       this._setSelection();
+                       this._toggle( event );
+               },
+
+               keydown: function( event ) {
+                       var preventDefault = true;
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.TAB:
+                               case $.ui.keyCode.ESCAPE:
+                                       this.close( event );
+                                       preventDefault = false;
+                                       break;
+                               case $.ui.keyCode.ENTER:
+                                       if ( this.isOpen ) {
+                                               this._selectFocusedItem( event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.UP:
+                                       if ( event.altKey ) {
+                                               this._toggle( event );
+                                       } else {
+                                               this._move( "prev", event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.DOWN:
+                                       if ( event.altKey ) {
+                                               this._toggle( event );
+                                       } else {
+                                               this._move( "next", event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.SPACE:
+                                       if ( this.isOpen ) {
+                                               this._selectFocusedItem( event );
+                                       } else {
+                                               this._toggle( event );
+                                       }
+                                       break;
+                               case $.ui.keyCode.LEFT:
+                                       this._move( "prev", event );
+                                       break;
+                               case $.ui.keyCode.RIGHT:
+                                       this._move( "next", event );
+                                       break;
+                               case $.ui.keyCode.HOME:
+                               case $.ui.keyCode.PAGE_UP:
+                                       this._move( "first", event );
+                                       break;
+                               case $.ui.keyCode.END:
+                               case $.ui.keyCode.PAGE_DOWN:
+                                       this._move( "last", event );
+                                       break;
+                               default:
+                                       this.menu.trigger( event );
+                                       preventDefault = false;
+                       }
+
+                       if ( preventDefault ) {
+                               event.preventDefault();
+                       }
+               }
+       },
+
+       _selectFocusedItem: function( event ) {
+               var item = this.menuItems.eq( this.focusIndex );
+               if ( !item.hasClass( "ui-state-disabled" ) ) {
+                       this._select( item.data( "ui-selectmenu-item" ), event );
+               }
+       },
+
+       _select: function( item, event ) {
+               var oldIndex = this.element[ 0 ].selectedIndex;
+
+               // Change native select element
+               this.element[ 0 ].selectedIndex = item.index;
+               this._setText( this.buttonText, item.label );
+               this._setAria( item );
+               this._trigger( "select", event, { item: item } );
+
+               if ( item.index !== oldIndex ) {
+                       this._trigger( "change", event, { item: item } );
+               }
+
+               this.close( event );
+       },
+
+       _setAria: function( item ) {
+               var id = this.menuItems.eq( item.index ).attr( "id" );
+
+               this.button.attr({
+                       "aria-labelledby": id,
+                       "aria-activedescendant": id
+               });
+               this.menu.attr( "aria-activedescendant", id );
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "icons" ) {
+                       this.button.find( "span.ui-icon" )
+                               .removeClass( this.options.icons.button )
+                               .addClass( value.button );
+               }
+
+               this._super( key, value );
+
+               if ( key === "appendTo" ) {
+                       this.menuWrap.appendTo( this._appendTo() );
+               }
+
+               if ( key === "disabled" ) {
+                       this.menuInstance.option( "disabled", value );
+                       this.button
+                               .toggleClass( "ui-state-disabled", value )
+                               .attr( "aria-disabled", value );
+
+                       this.element.prop( "disabled", value );
+                       if ( value ) {
+                               this.button.attr( "tabindex", -1 );
+                               this.close();
+                       } else {
+                               this.button.attr( "tabindex", 0 );
+                       }
+               }
+
+               if ( key === "width" ) {
+                       this._resizeButton();
+               }
+       },
+
+       _appendTo: function() {
+               var element = this.options.appendTo;
+
+               if ( element ) {
+                       element = element.jquery || element.nodeType ?
+                               $( element ) :
+                               this.document.find( element ).eq( 0 );
+               }
+
+               if ( !element || !element[ 0 ] ) {
+                       element = this.element.closest( ".ui-front" );
+               }
+
+               if ( !element.length ) {
+                       element = this.document[ 0 ].body;
+               }
+
+               return element;
+       },
+
+       _toggleAttr: function() {
+               this.button
+                       .toggleClass( "ui-corner-top", this.isOpen )
+                       .toggleClass( "ui-corner-all", !this.isOpen )
+                       .attr( "aria-expanded", this.isOpen );
+               this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
+               this.menu.attr( "aria-hidden", !this.isOpen );
+       },
+
+       _resizeButton: function() {
+               var width = this.options.width;
+
+               if ( !width ) {
+                       width = this.element.show().outerWidth();
+                       this.element.hide();
+               }
+
+               this.button.outerWidth( width );
+       },
+
+       _resizeMenu: function() {
+               this.menu.outerWidth( Math.max(
+                       this.button.outerWidth(),
+
+                       // support: IE10
+                       // IE10 wraps long text (possibly a rounding bug)
+                       // so we add 1px to avoid the wrapping
+                       this.menu.width( "" ).outerWidth() + 1
+               ) );
+       },
+
+       _getCreateOptions: function() {
+               return { disabled: this.element.prop( "disabled" ) };
+       },
+
+       _parseOptions: function( options ) {
+               var data = [];
+               options.each(function( index, item ) {
+                       var option = $( item ),
+                               optgroup = option.parent( "optgroup" );
+                       data.push({
+                               element: option,
+                               index: index,
+                               value: option.val(),
+                               label: option.text(),
+                               optgroup: optgroup.attr( "label" ) || "",
+                               disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
+                       });
+               });
+               this.items = data;
+       },
+
+       _destroy: function() {
+               this.menuWrap.remove();
+               this.button.remove();
+               this.element.show();
+               this.element.removeUniqueId();
+               this.label.attr( "for", this.ids.element );
+       }
+});
+
+
+/*!
+ * jQuery UI Slider 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/slider/
+ */
+
+
+var slider = $.widget( "ui.slider", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "slide",
+
+       options: {
+               animate: false,
+               distance: 0,
+               max: 100,
+               min: 0,
+               orientation: "horizontal",
+               range: false,
+               step: 1,
+               value: 0,
+               values: null,
+
+               // callbacks
+               change: null,
+               slide: null,
+               start: null,
+               stop: null
+       },
+
+       // number of pages in a slider
+       // (how many times can you page up/down to go through the whole range)
+       numPages: 5,
+
+       _create: function() {
+               this._keySliding = false;
+               this._mouseSliding = false;
+               this._animateOff = true;
+               this._handleIndex = null;
+               this._detectOrientation();
+               this._mouseInit();
+               this._calculateNewMax();
+
+               this.element
+                       .addClass( "ui-slider" +
+                               " ui-slider-" + this.orientation +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all");
+
+               this._refresh();
+               this._setOption( "disabled", this.options.disabled );
+
+               this._animateOff = false;
+       },
+
+       _refresh: function() {
+               this._createRange();
+               this._createHandles();
+               this._setupEvents();
+               this._refreshValue();
+       },
+
+       _createHandles: function() {
+               var i, handleCount,
+                       options = this.options,
+                       existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
+                       handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
+                       handles = [];
+
+               handleCount = ( options.values && options.values.length ) || 1;
+
+               if ( existingHandles.length > handleCount ) {
+                       existingHandles.slice( handleCount ).remove();
+                       existingHandles = existingHandles.slice( 0, handleCount );
+               }
+
+               for ( i = existingHandles.length; i < handleCount; i++ ) {
+                       handles.push( handle );
+               }
+
+               this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
+
+               this.handle = this.handles.eq( 0 );
+
+               this.handles.each(function( i ) {
+                       $( this ).data( "ui-slider-handle-index", i );
+               });
+       },
+
+       _createRange: function() {
+               var options = this.options,
+                       classes = "";
+
+               if ( options.range ) {
+                       if ( options.range === true ) {
+                               if ( !options.values ) {
+                                       options.values = [ this._valueMin(), this._valueMin() ];
+                               } else if ( options.values.length && options.values.length !== 2 ) {
+                                       options.values = [ options.values[0], options.values[0] ];
+                               } else if ( $.isArray( options.values ) ) {
+                                       options.values = options.values.slice(0);
+                               }
+                       }
+
+                       if ( !this.range || !this.range.length ) {
+                               this.range = $( "<div></div>" )
+                                       .appendTo( this.element );
+
+                               classes = "ui-slider-range" +
+                               // note: this isn't the most fittingly semantic framework class for this element,
+                               // but worked best visually with a variety of themes
+                               " ui-widget-header ui-corner-all";
+                       } else {
+                               this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
+                                       // Handle range switching from true to min/max
+                                       .css({
+                                               "left": "",
+                                               "bottom": ""
+                                       });
+                       }
+
+                       this.range.addClass( classes +
+                               ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
+               } else {
+                       if ( this.range ) {
+                               this.range.remove();
+                       }
+                       this.range = null;
+               }
+       },
+
+       _setupEvents: function() {
+               this._off( this.handles );
+               this._on( this.handles, this._handleEvents );
+               this._hoverable( this.handles );
+               this._focusable( this.handles );
+       },
+
+       _destroy: function() {
+               this.handles.remove();
+               if ( this.range ) {
+                       this.range.remove();
+               }
+
+               this.element
+                       .removeClass( "ui-slider" +
+                               " ui-slider-horizontal" +
+                               " ui-slider-vertical" +
+                               " ui-widget" +
+                               " ui-widget-content" +
+                               " ui-corner-all" );
+
+               this._mouseDestroy();
+       },
+
+       _mouseCapture: function( event ) {
+               var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
+                       that = this,
+                       o = this.options;
+
+               if ( o.disabled ) {
+                       return false;
+               }
+
+               this.elementSize = {
+                       width: this.element.outerWidth(),
+                       height: this.element.outerHeight()
+               };
+               this.elementOffset = this.element.offset();
+
+               position = { x: event.pageX, y: event.pageY };
+               normValue = this._normValueFromMouse( position );
+               distance = this._valueMax() - this._valueMin() + 1;
+               this.handles.each(function( i ) {
+                       var thisDistance = Math.abs( normValue - that.values(i) );
+                       if (( distance > thisDistance ) ||
+                               ( distance === thisDistance &&
+                                       (i === that._lastChangedValue || that.values(i) === o.min ))) {
+                               distance = thisDistance;
+                               closestHandle = $( this );
+                               index = i;
+                       }
+               });
+
+               allowed = this._start( event, index );
+               if ( allowed === false ) {
+                       return false;
+               }
+               this._mouseSliding = true;
+
+               this._handleIndex = index;
+
+               closestHandle
+                       .addClass( "ui-state-active" )
+                       .focus();
+
+               offset = closestHandle.offset();
+               mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
+               this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+                       left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+                       top: event.pageY - offset.top -
+                               ( closestHandle.height() / 2 ) -
+                               ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
+                               ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
+                               ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
+               };
+
+               if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+                       this._slide( event, index, normValue );
+               }
+               this._animateOff = true;
+               return true;
+       },
+
+       _mouseStart: function() {
+               return true;
+       },
+
+       _mouseDrag: function( event ) {
+               var position = { x: event.pageX, y: event.pageY },
+                       normValue = this._normValueFromMouse( position );
+
+               this._slide( event, this._handleIndex, normValue );
+
+               return false;
+       },
+
+       _mouseStop: function( event ) {
+               this.handles.removeClass( "ui-state-active" );
+               this._mouseSliding = false;
+
+               this._stop( event, this._handleIndex );
+               this._change( event, this._handleIndex );
+
+               this._handleIndex = null;
+               this._clickOffset = null;
+               this._animateOff = false;
+
+               return false;
+       },
+
+       _detectOrientation: function() {
+               this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+       },
+
+       _normValueFromMouse: function( position ) {
+               var pixelTotal,
+                       pixelMouse,
+                       percentMouse,
+                       valueTotal,
+                       valueMouse;
+
+               if ( this.orientation === "horizontal" ) {
+                       pixelTotal = this.elementSize.width;
+                       pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
+               } else {
+                       pixelTotal = this.elementSize.height;
+                       pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
+               }
+
+               percentMouse = ( pixelMouse / pixelTotal );
+               if ( percentMouse > 1 ) {
+                       percentMouse = 1;
+               }
+               if ( percentMouse < 0 ) {
+                       percentMouse = 0;
+               }
+               if ( this.orientation === "vertical" ) {
+                       percentMouse = 1 - percentMouse;
+               }
+
+               valueTotal = this._valueMax() - this._valueMin();
+               valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+               return this._trimAlignValue( valueMouse );
+       },
+
+       _start: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+               return this._trigger( "start", event, uiHash );
+       },
+
+       _slide: function( event, index, newVal ) {
+               var otherVal,
+                       newValues,
+                       allowed;
+
+               if ( this.options.values && this.options.values.length ) {
+                       otherVal = this.values( index ? 0 : 1 );
+
+                       if ( ( this.options.values.length === 2 && this.options.range === true ) &&
+                                       ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
+                               ) {
+                               newVal = otherVal;
+                       }
+
+                       if ( newVal !== this.values( index ) ) {
+                               newValues = this.values();
+                               newValues[ index ] = newVal;
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal,
+                                       values: newValues
+                               } );
+                               otherVal = this.values( index ? 0 : 1 );
+                               if ( allowed !== false ) {
+                                       this.values( index, newVal );
+                               }
+                       }
+               } else {
+                       if ( newVal !== this.value() ) {
+                               // A slide can be canceled by returning false from the slide callback
+                               allowed = this._trigger( "slide", event, {
+                                       handle: this.handles[ index ],
+                                       value: newVal
+                               } );
+                               if ( allowed !== false ) {
+                                       this.value( newVal );
+                               }
+                       }
+               }
+       },
+
+       _stop: function( event, index ) {
+               var uiHash = {
+                       handle: this.handles[ index ],
+                       value: this.value()
+               };
+               if ( this.options.values && this.options.values.length ) {
+                       uiHash.value = this.values( index );
+                       uiHash.values = this.values();
+               }
+
+               this._trigger( "stop", event, uiHash );
+       },
+
+       _change: function( event, index ) {
+               if ( !this._keySliding && !this._mouseSliding ) {
+                       var uiHash = {
+                               handle: this.handles[ index ],
+                               value: this.value()
+                       };
+                       if ( this.options.values && this.options.values.length ) {
+                               uiHash.value = this.values( index );
+                               uiHash.values = this.values();
+                       }
+
+                       //store the last changed value index for reference when handles overlap
+                       this._lastChangedValue = index;
+
+                       this._trigger( "change", event, uiHash );
+               }
+       },
+
+       value: function( newValue ) {
+               if ( arguments.length ) {
+                       this.options.value = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, 0 );
+                       return;
+               }
+
+               return this._value();
+       },
+
+       values: function( index, newValue ) {
+               var vals,
+                       newValues,
+                       i;
+
+               if ( arguments.length > 1 ) {
+                       this.options.values[ index ] = this._trimAlignValue( newValue );
+                       this._refreshValue();
+                       this._change( null, index );
+                       return;
+               }
+
+               if ( arguments.length ) {
+                       if ( $.isArray( arguments[ 0 ] ) ) {
+                               vals = this.options.values;
+                               newValues = arguments[ 0 ];
+                               for ( i = 0; i < vals.length; i += 1 ) {
+                                       vals[ i ] = this._trimAlignValue( newValues[ i ] );
+                                       this._change( null, i );
+                               }
+                               this._refreshValue();
+                       } else {
+                               if ( this.options.values && this.options.values.length ) {
+                                       return this._values( index );
+                               } else {
+                                       return this.value();
+                               }
+                       }
+               } else {
+                       return this._values();
+               }
+       },
+
+       _setOption: function( key, value ) {
+               var i,
+                       valsLength = 0;
+
+               if ( key === "range" && this.options.range === true ) {
+                       if ( value === "min" ) {
+                               this.options.value = this._values( 0 );
+                               this.options.values = null;
+                       } else if ( value === "max" ) {
+                               this.options.value = this._values( this.options.values.length - 1 );
+                               this.options.values = null;
+                       }
+               }
+
+               if ( $.isArray( this.options.values ) ) {
+                       valsLength = this.options.values.length;
+               }
+
+               if ( key === "disabled" ) {
+                       this.element.toggleClass( "ui-state-disabled", !!value );
+               }
+
+               this._super( key, value );
+
+               switch ( key ) {
+                       case "orientation":
+                               this._detectOrientation();
+                               this.element
+                                       .removeClass( "ui-slider-horizontal ui-slider-vertical" )
+                                       .addClass( "ui-slider-" + this.orientation );
+                               this._refreshValue();
+
+                               // Reset positioning from previous orientation
+                               this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
+                               break;
+                       case "value":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               this._change( null, 0 );
+                               this._animateOff = false;
+                               break;
+                       case "values":
+                               this._animateOff = true;
+                               this._refreshValue();
+                               for ( i = 0; i < valsLength; i += 1 ) {
+                                       this._change( null, i );
+                               }
+                               this._animateOff = false;
+                               break;
+                       case "step":
+                       case "min":
+                       case "max":
+                               this._animateOff = true;
+                               this._calculateNewMax();
+                               this._refreshValue();
+                               this._animateOff = false;
+                               break;
+                       case "range":
+                               this._animateOff = true;
+                               this._refresh();
+                               this._animateOff = false;
+                               break;
+               }
+       },
+
+       //internal value getter
+       // _value() returns value trimmed by min and max, aligned by step
+       _value: function() {
+               var val = this.options.value;
+               val = this._trimAlignValue( val );
+
+               return val;
+       },
+
+       //internal values getter
+       // _values() returns array of values trimmed by min and max, aligned by step
+       // _values( index ) returns single value trimmed by min and max, aligned by step
+       _values: function( index ) {
+               var val,
+                       vals,
+                       i;
+
+               if ( arguments.length ) {
+                       val = this.options.values[ index ];
+                       val = this._trimAlignValue( val );
+
+                       return val;
+               } else if ( this.options.values && this.options.values.length ) {
+                       // .slice() creates a copy of the array
+                       // this copy gets trimmed by min and max and then returned
+                       vals = this.options.values.slice();
+                       for ( i = 0; i < vals.length; i += 1) {
+                               vals[ i ] = this._trimAlignValue( vals[ i ] );
+                       }
+
+                       return vals;
+               } else {
+                       return [];
+               }
+       },
+
+       // returns the step-aligned value that val is closest to, between (inclusive) min and max
+       _trimAlignValue: function( val ) {
+               if ( val <= this._valueMin() ) {
+                       return this._valueMin();
+               }
+               if ( val >= this._valueMax() ) {
+                       return this._valueMax();
+               }
+               var step = ( this.options.step > 0 ) ? this.options.step : 1,
+                       valModStep = (val - this._valueMin()) % step,
+                       alignValue = val - valModStep;
+
+               if ( Math.abs(valModStep) * 2 >= step ) {
+                       alignValue += ( valModStep > 0 ) ? step : ( -step );
+               }
+
+               // Since JavaScript has problems with large floats, round
+               // the final value to 5 digits after the decimal point (see #4124)
+               return parseFloat( alignValue.toFixed(5) );
+       },
+
+       _calculateNewMax: function() {
+               var max = this.options.max,
+                       min = this._valueMin(),
+                       step = this.options.step,
+                       aboveMin = Math.floor( ( max - min ) / step ) * step;
+               max = aboveMin + min;
+               this.max = parseFloat( max.toFixed( this._precision() ) );
+       },
+
+       _precision: function() {
+               var precision = this._precisionOf( this.options.step );
+               if ( this.options.min !== null ) {
+                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
+               }
+               return precision;
+       },
+
+       _precisionOf: function( num ) {
+               var str = num.toString(),
+                       decimal = str.indexOf( "." );
+               return decimal === -1 ? 0 : str.length - decimal - 1;
+       },
+
+       _valueMin: function() {
+               return this.options.min;
+       },
+
+       _valueMax: function() {
+               return this.max;
+       },
+
+       _refreshValue: function() {
+               var lastValPercent, valPercent, value, valueMin, valueMax,
+                       oRange = this.options.range,
+                       o = this.options,
+                       that = this,
+                       animate = ( !this._animateOff ) ? o.animate : false,
+                       _set = {};
+
+               if ( this.options.values && this.options.values.length ) {
+                       this.handles.each(function( i ) {
+                               valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
+                               _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                               $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+                               if ( that.options.range === true ) {
+                                       if ( that.orientation === "horizontal" ) {
+                                               if ( i === 0 ) {
+                                                       that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       } else {
+                                               if ( i === 0 ) {
+                                                       that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
+                                               }
+                                               if ( i === 1 ) {
+                                                       that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+                                               }
+                                       }
+                               }
+                               lastValPercent = valPercent;
+                       });
+               } else {
+                       value = this.value();
+                       valueMin = this._valueMin();
+                       valueMax = this._valueMax();
+                       valPercent = ( valueMax !== valueMin ) ?
+                                       ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+                                       0;
+                       _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+                       this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+                       if ( oRange === "min" && this.orientation === "horizontal" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "horizontal" ) {
+                               this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+                       if ( oRange === "min" && this.orientation === "vertical" ) {
+                               this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
+                       }
+                       if ( oRange === "max" && this.orientation === "vertical" ) {
+                               this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+                       }
+               }
+       },
+
+       _handleEvents: {
+               keydown: function( event ) {
+                       var allowed, curVal, newVal, step,
+                               index = $( event.target ).data( "ui-slider-handle-index" );
+
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.HOME:
+                               case $.ui.keyCode.END:
+                               case $.ui.keyCode.PAGE_UP:
+                               case $.ui.keyCode.PAGE_DOWN:
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       event.preventDefault();
+                                       if ( !this._keySliding ) {
+                                               this._keySliding = true;
+                                               $( event.target ).addClass( "ui-state-active" );
+                                               allowed = this._start( event, index );
+                                               if ( allowed === false ) {
+                                                       return;
+                                               }
+                                       }
+                                       break;
+                       }
+
+                       step = this.options.step;
+                       if ( this.options.values && this.options.values.length ) {
+                               curVal = newVal = this.values( index );
+                       } else {
+                               curVal = newVal = this.value();
+                       }
+
+                       switch ( event.keyCode ) {
+                               case $.ui.keyCode.HOME:
+                                       newVal = this._valueMin();
+                                       break;
+                               case $.ui.keyCode.END:
+                                       newVal = this._valueMax();
+                                       break;
+                               case $.ui.keyCode.PAGE_UP:
+                                       newVal = this._trimAlignValue(
+                                               curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
+                                       );
+                                       break;
+                               case $.ui.keyCode.PAGE_DOWN:
+                                       newVal = this._trimAlignValue(
+                                               curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
+                                       break;
+                               case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
+                                       if ( curVal === this._valueMax() ) {
+                                               return;
+                                       }
+                                       newVal = this._trimAlignValue( curVal + step );
+                                       break;
+                               case $.ui.keyCode.DOWN:
+                               case $.ui.keyCode.LEFT:
+                                       if ( curVal === this._valueMin() ) {
+                                               return;
+                                       }
+                                       newVal = this._trimAlignValue( curVal - step );
+                                       break;
+                       }
+
+                       this._slide( event, index, newVal );
+               },
+               keyup: function( event ) {
+                       var index = $( event.target ).data( "ui-slider-handle-index" );
+
+                       if ( this._keySliding ) {
+                               this._keySliding = false;
+                               this._stop( event, index );
+                               this._change( event, index );
+                               $( event.target ).removeClass( "ui-state-active" );
+                       }
+               }
+       }
+});
+
+
+/*!
+ * jQuery UI Sortable 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/sortable/
+ */
+
+
+var sortable = $.widget("ui.sortable", $.ui.mouse, {
+       version: "1.11.3",
+       widgetEventPrefix: "sort",
+       ready: false,
+       options: {
+               appendTo: "parent",
+               axis: false,
+               connectWith: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               dropOnEmpty: true,
+               forcePlaceholderSize: false,
+               forceHelperSize: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               items: "> *",
+               opacity: false,
+               placeholder: false,
+               revert: false,
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               scope: "default",
+               tolerance: "intersect",
+               zIndex: 1000,
+
+               // callbacks
+               activate: null,
+               beforeStop: null,
+               change: null,
+               deactivate: null,
+               out: null,
+               over: null,
+               receive: null,
+               remove: null,
+               sort: null,
+               start: null,
+               stop: null,
+               update: null
+       },
+
+       _isOverAxis: function( x, reference, size ) {
+               return ( x >= reference ) && ( x < ( reference + size ) );
+       },
+
+       _isFloating: function( item ) {
+               return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
+       },
+
+       _create: function() {
+
+               var o = this.options;
+               this.containerCache = {};
+               this.element.addClass("ui-sortable");
+
+               //Get the items
+               this.refresh();
+
+               //Let's determine if the items are being displayed horizontally
+               this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
+
+               //Let's determine the parent's offset
+               this.offset = this.element.offset();
+
+               //Initialize mouse events for interaction
+               this._mouseInit();
+
+               this._setHandleClassName();
+
+               //We're ready to go
+               this.ready = true;
+
+       },
+
+       _setOption: function( key, value ) {
+               this._super( key, value );
+
+               if ( key === "handle" ) {
+                       this._setHandleClassName();
+               }
+       },
+
+       _setHandleClassName: function() {
+               this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
+               $.each( this.items, function() {
+                       ( this.instance.options.handle ?
+                               this.item.find( this.instance.options.handle ) : this.item )
+                               .addClass( "ui-sortable-handle" );
+               });
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-sortable ui-sortable-disabled" )
+                       .find( ".ui-sortable-handle" )
+                               .removeClass( "ui-sortable-handle" );
+               this._mouseDestroy();
+
+               for ( var i = this.items.length - 1; i >= 0; i-- ) {
+                       this.items[i].item.removeData(this.widgetName + "-item");
+               }
+
+               return this;
+       },
+
+       _mouseCapture: function(event, overrideHandle) {
+               var currentItem = null,
+                       validHandle = false,
+                       that = this;
+
+               if (this.reverting) {
+                       return false;
+               }
+
+               if(this.options.disabled || this.options.type === "static") {
+                       return false;
+               }
+
+               //We have to refresh the items data once first
+               this._refreshItems(event);
+
+               //Find out if the clicked node (or one of its parents) is a actual item in this.items
+               $(event.target).parents().each(function() {
+                       if($.data(this, that.widgetName + "-item") === that) {
+                               currentItem = $(this);
+                               return false;
+                       }
+               });
+               if($.data(event.target, that.widgetName + "-item") === that) {
+                       currentItem = $(event.target);
+               }
+
+               if(!currentItem) {
+                       return false;
+               }
+               if(this.options.handle && !overrideHandle) {
+                       $(this.options.handle, currentItem).find("*").addBack().each(function() {
+                               if(this === event.target) {
+                                       validHandle = true;
+                               }
+                       });
+                       if(!validHandle) {
+                               return false;
+                       }
+               }
+
+               this.currentItem = currentItem;
+               this._removeCurrentsFromItems();
+               return true;
+
+       },
+
+       _mouseStart: function(event, overrideHandle, noActivation) {
+
+               var i, body,
+                       o = this.options;
+
+               this.currentContainer = this;
+
+               //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+               this.refreshPositions();
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Get the next scrolling parent
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.currentItem.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               // Only after we got the offset, we can change the helper's position to absolute
+               // TODO: Still need to figure out a way to make relative sorting possible
+               this.helper.css("position", "absolute");
+               this.cssPosition = this.helper.css("position");
+
+               //Generate the original position
+               this.originalPosition = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Cache the former DOM position
+               this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+               //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+               if(this.helper[0] !== this.currentItem[0]) {
+                       this.currentItem.hide();
+               }
+
+               //Create the placeholder
+               this._createPlaceholder();
+
+               //Set a containment if given in the options
+               if(o.containment) {
+                       this._setContainment();
+               }
+
+               if( o.cursor && o.cursor !== "auto" ) { // cursor option
+                       body = this.document.find( "body" );
+
+                       // support: IE
+                       this.storedCursor = body.css( "cursor" );
+                       body.css( "cursor", o.cursor );
+
+                       this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
+               }
+
+               if(o.opacity) { // opacity option
+                       if (this.helper.css("opacity")) {
+                               this._storedOpacity = this.helper.css("opacity");
+                       }
+                       this.helper.css("opacity", o.opacity);
+               }
+
+               if(o.zIndex) { // zIndex option
+                       if (this.helper.css("zIndex")) {
+                               this._storedZIndex = this.helper.css("zIndex");
+                       }
+                       this.helper.css("zIndex", o.zIndex);
+               }
+
+               //Prepare scrolling
+               if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
+                       this.overflowOffset = this.scrollParent.offset();
+               }
+
+               //Call callbacks
+               this._trigger("start", event, this._uiHash());
+
+               //Recache the helper size
+               if(!this._preserveHelperProportions) {
+                       this._cacheHelperProportions();
+               }
+
+
+               //Post "activate" events to possible containers
+               if( !noActivation ) {
+                       for ( i = this.containers.length - 1; i >= 0; i-- ) {
+                               this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
+                       }
+               }
+
+               //Prepare possible droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               this.dragging = true;
+
+               this.helper.addClass("ui-sortable-helper");
+               this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+               return true;
+
+       },
+
+       _mouseDrag: function(event) {
+               var i, item, itemElement, intersection,
+                       o = this.options,
+                       scrolled = false;
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               if (!this.lastPositionAbs) {
+                       this.lastPositionAbs = this.positionAbs;
+               }
+
+               //Do scrolling
+               if(this.options.scroll) {
+                       if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
+
+                               if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+                               } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+                               }
+
+                               if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+                               }
+
+                       } else {
+
+                               if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
+                               } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
+                               }
+
+                               if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
+                               } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
+                               }
+
+                       }
+
+                       if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                               $.ui.ddmanager.prepareOffsets(this, event);
+                       }
+               }
+
+               //Regenerate the absolute position used for position checks
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Set the helper position
+               if(!this.options.axis || this.options.axis !== "y") {
+                       this.helper[0].style.left = this.position.left+"px";
+               }
+               if(!this.options.axis || this.options.axis !== "x") {
+                       this.helper[0].style.top = this.position.top+"px";
+               }
+
+               //Rearrange
+               for (i = this.items.length - 1; i >= 0; i--) {
+
+                       //Cache variables and intersection, continue if no intersection
+                       item = this.items[i];
+                       itemElement = item.item[0];
+                       intersection = this._intersectsWithPointer(item);
+                       if (!intersection) {
+                               continue;
+                       }
+
+                       // Only put the placeholder inside the current Container, skip all
+                       // items from other containers. This works because when moving
+                       // an item from one container to another the
+                       // currentContainer is switched before the placeholder is moved.
+                       //
+                       // Without this, moving items in "sub-sortables" can cause
+                       // the placeholder to jitter between the outer and inner container.
+                       if (item.instance !== this.currentContainer) {
+                               continue;
+                       }
+
+                       // cannot intersect with itself
+                       // no useless actions that have been done before
+                       // no action if the item moved is the parent of the item checked
+                       if (itemElement !== this.currentItem[0] &&
+                               this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
+                               !$.contains(this.placeholder[0], itemElement) &&
+                               (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
+                       ) {
+
+                               this.direction = intersection === 1 ? "down" : "up";
+
+                               if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
+                                       this._rearrange(event, item);
+                               } else {
+                                       break;
+                               }
+
+                               this._trigger("change", event, this._uiHash());
+                               break;
+                       }
+               }
+
+               //Post events to containers
+               this._contactContainers(event);
+
+               //Interconnect with droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               //Call callbacks
+               this._trigger("sort", event, this._uiHash());
+
+               this.lastPositionAbs = this.positionAbs;
+               return false;
+
+       },
+
+       _mouseStop: function(event, noPropagation) {
+
+               if(!event) {
+                       return;
+               }
+
+               //If we are using droppables, inform the manager about the drop
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       $.ui.ddmanager.drop(this, event);
+               }
+
+               if(this.options.revert) {
+                       var that = this,
+                               cur = this.placeholder.offset(),
+                               axis = this.options.axis,
+                               animation = {};
+
+                       if ( !axis || axis === "x" ) {
+                               animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
+                       }
+                       if ( !axis || axis === "y" ) {
+                               animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
+                       }
+                       this.reverting = true;
+                       $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
+                               that._clear(event);
+                       });
+               } else {
+                       this._clear(event, noPropagation);
+               }
+
+               return false;
+
+       },
+
+       cancel: function() {
+
+               if(this.dragging) {
+
+                       this._mouseUp({ target: null });
+
+                       if(this.options.helper === "original") {
+                               this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+                       } else {
+                               this.currentItem.show();
+                       }
+
+                       //Post deactivating events to containers
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               this.containers[i]._trigger("deactivate", null, this._uiHash(this));
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", null, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               if (this.placeholder) {
+                       //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+                       if(this.placeholder[0].parentNode) {
+                               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+                       }
+                       if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
+                               this.helper.remove();
+                       }
+
+                       $.extend(this, {
+                               helper: null,
+                               dragging: false,
+                               reverting: false,
+                               _noFinalSort: null
+                       });
+
+                       if(this.domPosition.prev) {
+                               $(this.domPosition.prev).after(this.currentItem);
+                       } else {
+                               $(this.domPosition.parent).prepend(this.currentItem);
+                       }
+               }
+
+               return this;
+
+       },
+
+       serialize: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       str = [];
+               o = o || {};
+
+               $(items).each(function() {
+                       var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
+                       if (res) {
+                               str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
+                       }
+               });
+
+               if(!str.length && o.key) {
+                       str.push(o.key + "=");
+               }
+
+               return str.join("&");
+
+       },
+
+       toArray: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       ret = [];
+
+               o = o || {};
+
+               items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
+               return ret;
+
+       },
+
+       /* Be careful with the following core functions */
+       _intersectsWith: function(item) {
+
+               var x1 = this.positionAbs.left,
+                       x2 = x1 + this.helperProportions.width,
+                       y1 = this.positionAbs.top,
+                       y2 = y1 + this.helperProportions.height,
+                       l = item.left,
+                       r = l + item.width,
+                       t = item.top,
+                       b = t + item.height,
+                       dyClick = this.offset.click.top,
+                       dxClick = this.offset.click.left,
+                       isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
+                       isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
+                       isOverElement = isOverElementHeight && isOverElementWidth;
+
+               if ( this.options.tolerance === "pointer" ||
+                       this.options.forcePointerForContainers ||
+                       (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
+               ) {
+                       return isOverElement;
+               } else {
+
+                       return (l < x1 + (this.helperProportions.width / 2) && // Right Half
+                               x2 - (this.helperProportions.width / 2) < r && // Left Half
+                               t < y1 + (this.helperProportions.height / 2) && // Bottom Half
+                               y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+               }
+       },
+
+       _intersectsWithPointer: function(item) {
+
+               var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+                       isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+                       isOverElement = isOverElementHeight && isOverElementWidth,
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (!isOverElement) {
+                       return false;
+               }
+
+               return this.floating ?
+                       ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
+                       : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
+
+       },
+
+       _intersectsWithSides: function(item) {
+
+               var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+                       isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (this.floating && horizontalDirection) {
+                       return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
+               } else {
+                       return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
+               }
+
+       },
+
+       _getDragVerticalDirection: function() {
+               var delta = this.positionAbs.top - this.lastPositionAbs.top;
+               return delta !== 0 && (delta > 0 ? "down" : "up");
+       },
+
+       _getDragHorizontalDirection: function() {
+               var delta = this.positionAbs.left - this.lastPositionAbs.left;
+               return delta !== 0 && (delta > 0 ? "right" : "left");
+       },
+
+       refresh: function(event) {
+               this._refreshItems(event);
+               this._setHandleClassName();
+               this.refreshPositions();
+               return this;
+       },
+
+       _connectWith: function() {
+               var options = this.options;
+               return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
+       },
+
+       _getItemsAsjQuery: function(connected) {
+
+               var i, j, cur, inst,
+                       items = [],
+                       queries = [],
+                       connectWith = this._connectWith();
+
+               if(connectWith && connected) {
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i], this.document[0]);
+                               for ( j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
+                                       }
+                               }
+                       }
+               }
+
+               queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
+
+               function addItems() {
+                       items.push( this );
+               }
+               for (i = queries.length - 1; i >= 0; i--){
+                       queries[i][0].each( addItems );
+               }
+
+               return $(items);
+
+       },
+
+       _removeCurrentsFromItems: function() {
+
+               var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
+
+               this.items = $.grep(this.items, function (item) {
+                       for (var j=0; j < list.length; j++) {
+                               if(list[j] === item.item[0]) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               });
+
+       },
+
+       _refreshItems: function(event) {
+
+               this.items = [];
+               this.containers = [this];
+
+               var i, j, cur, inst, targetData, _queries, item, queriesLength,
+                       items = this.items,
+                       queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
+                       connectWith = this._connectWith();
+
+               if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i], this.document[0]);
+                               for (j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+                                               this.containers.push(inst);
+                                       }
+                               }
+                       }
+               }
+
+               for (i = queries.length - 1; i >= 0; i--) {
+                       targetData = queries[i][1];
+                       _queries = queries[i][0];
+
+                       for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+                               item = $(_queries[j]);
+
+                               item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
+
+                               items.push({
+                                       item: item,
+                                       instance: targetData,
+                                       width: 0, height: 0,
+                                       left: 0, top: 0
+                               });
+                       }
+               }
+
+       },
+
+       refreshPositions: function(fast) {
+
+               //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+               if(this.offsetParent && this.helper) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               var i, item, t, p;
+
+               for (i = this.items.length - 1; i >= 0; i--){
+                       item = this.items[i];
+
+                       //We ignore calculating positions of all connected containers when we're not over them
+                       if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
+                               continue;
+                       }
+
+                       t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+                       if (!fast) {
+                               item.width = t.outerWidth();
+                               item.height = t.outerHeight();
+                       }
+
+                       p = t.offset();
+                       item.left = p.left;
+                       item.top = p.top;
+               }
+
+               if(this.options.custom && this.options.custom.refreshContainers) {
+                       this.options.custom.refreshContainers.call(this);
+               } else {
+                       for (i = this.containers.length - 1; i >= 0; i--){
+                               p = this.containers[i].element.offset();
+                               this.containers[i].containerCache.left = p.left;
+                               this.containers[i].containerCache.top = p.top;
+                               this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+                               this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+                       }
+               }
+
+               return this;
+       },
+
+       _createPlaceholder: function(that) {
+               that = that || this;
+               var className,
+                       o = that.options;
+
+               if(!o.placeholder || o.placeholder.constructor === String) {
+                       className = o.placeholder;
+                       o.placeholder = {
+                               element: function() {
+
+                                       var nodeName = that.currentItem[0].nodeName.toLowerCase(),
+                                               element = $( "<" + nodeName + ">", that.document[0] )
+                                                       .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
+                                                       .removeClass("ui-sortable-helper");
+
+                                       if ( nodeName === "tr" ) {
+                                               that.currentItem.children().each(function() {
+                                                       $( "<td>&#160;</td>", that.document[0] )
+                                                               .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
+                                                               .appendTo( element );
+                                               });
+                                       } else if ( nodeName === "img" ) {
+                                               element.attr( "src", that.currentItem.attr( "src" ) );
+                                       }
+
+                                       if ( !className ) {
+                                               element.css( "visibility", "hidden" );
+                                       }
+
+                                       return element;
+                               },
+                               update: function(container, p) {
+
+                                       // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+                                       // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+                                       if(className && !o.forcePlaceholderSize) {
+                                               return;
+                                       }
+
+                                       //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+                                       if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
+                                       if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
+                               }
+                       };
+               }
+
+               //Create the placeholder
+               that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
+
+               //Append it after the actual current item
+               that.currentItem.after(that.placeholder);
+
+               //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+               o.placeholder.update(that, that.placeholder);
+
+       },
+
+       _contactContainers: function(event) {
+               var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
+                       innermostContainer = null,
+                       innermostIndex = null;
+
+               // get innermost container that intersects with item
+               for (i = this.containers.length - 1; i >= 0; i--) {
+
+                       // never consider a container that's located within the item itself
+                       if($.contains(this.currentItem[0], this.containers[i].element[0])) {
+                               continue;
+                       }
+
+                       if(this._intersectsWith(this.containers[i].containerCache)) {
+
+                               // if we've already found a container and it's more "inner" than this, then continue
+                               if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
+                                       continue;
+                               }
+
+                               innermostContainer = this.containers[i];
+                               innermostIndex = i;
+
+                       } else {
+                               // container doesn't intersect. trigger "out" event if necessary
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", event, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               // if no intersecting containers found, return
+               if(!innermostContainer) {
+                       return;
+               }
+
+               // move the item into the container if it's not there already
+               if(this.containers.length === 1) {
+                       if (!this.containers[innermostIndex].containerCache.over) {
+                               this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                               this.containers[innermostIndex].containerCache.over = 1;
+                       }
+               } else {
+
+                       //When entering a new container, we will find the item with the least distance and append our item near it
+                       dist = 10000;
+                       itemWithLeastDistance = null;
+                       floating = innermostContainer.floating || this._isFloating(this.currentItem);
+                       posProperty = floating ? "left" : "top";
+                       sizeProperty = floating ? "width" : "height";
+                       axis = floating ? "clientX" : "clientY";
+
+                       for (j = this.items.length - 1; j >= 0; j--) {
+                               if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
+                                       continue;
+                               }
+                               if(this.items[j].item[0] === this.currentItem[0]) {
+                                       continue;
+                               }
+
+                               cur = this.items[j].item.offset()[posProperty];
+                               nearBottom = false;
+                               if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
+                                       nearBottom = true;
+                               }
+
+                               if ( Math.abs( event[ axis ] - cur ) < dist ) {
+                                       dist = Math.abs( event[ axis ] - cur );
+                                       itemWithLeastDistance = this.items[ j ];
+                                       this.direction = nearBottom ? "up": "down";
+                               }
+                       }
+
+                       //Check if dropOnEmpty is enabled
+                       if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
+                               return;
+                       }
+
+                       if(this.currentContainer === this.containers[innermostIndex]) {
+                               if ( !this.currentContainer.containerCache.over ) {
+                                       this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
+                                       this.currentContainer.containerCache.over = 1;
+                               }
+                               return;
+                       }
+
+                       itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+                       this._trigger("change", event, this._uiHash());
+                       this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+                       this.currentContainer = this.containers[innermostIndex];
+
+                       //Update the placeholder
+                       this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                       this.containers[innermostIndex].containerCache.over = 1;
+               }
+
+
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
+
+               //Add the helper to the DOM if that didn't happen already
+               if(!helper.parents("body").length) {
+                       $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+               }
+
+               if(helper[0] === this.currentItem[0]) {
+                       this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+               }
+
+               if(!helper[0].style.width || o.forceHelperSize) {
+                       helper.width(this.currentItem.width());
+               }
+               if(!helper[0].style.height || o.forceHelperSize) {
+                       helper.height(this.currentItem.height());
+               }
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               // This needs to be actually done for all browsers, since pageX/pageY includes this information
+               // with an ugly IE fix
+               if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition === "relative") {
+                       var p = this.currentItem.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var ce, co, over,
+                       o = this.options;
+               if(o.containment === "parent") {
+                       o.containment = this.helper[0].parentNode;
+               }
+               if(o.containment === "document" || o.containment === "window") {
+                       this.containment = [
+                               0 - this.offset.relative.left - this.offset.parent.left,
+                               0 - this.offset.relative.top - this.offset.parent.top,
+                               o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
+                               (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+               if(!(/^(document|window|parent)$/).test(o.containment)) {
+                       ce = $(o.containment)[0];
+                       co = $(o.containment).offset();
+                       over = ($(ce).css("overflow") !== "hidden");
+
+                       this.containment = [
+                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) {
+                       pos = this.position;
+               }
+               var mod = d === "absolute" ? 1 : -1,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
+                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var top, left,
+                       o = this.options,
+                       pageX = event.pageX,
+                       pageY = event.pageY,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               // This is another very weird special case that only happens for relative elements:
+               // 1. If the css position is relative
+               // 2. and the scroll parent is the document or similar to the offset parent
+               // we have to refresh the relative offset during the scroll so there are no jumps
+               if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
+                       this.offset.relative = this._getRelativeOffset();
+               }
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+                       if(this.containment) {
+                               if(event.pageX - this.offset.click.left < this.containment[0]) {
+                                       pageX = this.containment[0] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top < this.containment[1]) {
+                                       pageY = this.containment[1] + this.offset.click.top;
+                               }
+                               if(event.pageX - this.offset.click.left > this.containment[2]) {
+                                       pageX = this.containment[2] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top > this.containment[3]) {
+                                       pageY = this.containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if(o.grid) {
+                               top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+                               pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+                               pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                         // The absolute mouse position
+                               this.offset.click.top -                                                                                                 // Click offset (relative to the element)
+                               this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX -                                                                                                                         // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _rearrange: function(event, i, a, hardRefresh) {
+
+               a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
+
+               //Various things done here to improve the performance:
+               // 1. we create a setTimeout, that calls refreshPositions
+               // 2. on the instance, we have a counter variable, that get's higher after every append
+               // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+               // 4. this lets only the last addition to the timeout stack through
+               this.counter = this.counter ? ++this.counter : 1;
+               var counter = this.counter;
+
+               this._delay(function() {
+                       if(counter === this.counter) {
+                               this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+                       }
+               });
+
+       },
+
+       _clear: function(event, noPropagation) {
+
+               this.reverting = false;
+               // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+               // everything else normalized again
+               var i,
+                       delayedTriggers = [];
+
+               // We first have to update the dom position of the actual currentItem
+               // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+               if(!this._noFinalSort && this.currentItem.parent().length) {
+                       this.placeholder.before(this.currentItem);
+               }
+               this._noFinalSort = null;
+
+               if(this.helper[0] === this.currentItem[0]) {
+                       for(i in this._storedCSS) {
+                               if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
+                                       this._storedCSS[i] = "";
+                               }
+                       }
+                       this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+               } else {
+                       this.currentItem.show();
+               }
+
+               if(this.fromOutside && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+               }
+               if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+               }
+
+               // Check if the items Container has Changed and trigger appropriate
+               // events.
+               if (this !== this.currentContainer) {
+                       if(!noPropagation) {
+                               delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
+                       }
+               }
+
+
+               //Post events to containers
+               function delayEvent( type, instance, container ) {
+                       return function( event ) {
+                               container._trigger( type, event, instance._uiHash( instance ) );
+                       };
+               }
+               for (i = this.containers.length - 1; i >= 0; i--){
+                       if (!noPropagation) {
+                               delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
+                       }
+                       if(this.containers[i].containerCache.over) {
+                               delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
+                               this.containers[i].containerCache.over = 0;
+                       }
+               }
+
+               //Do what was originally in plugins
+               if ( this.storedCursor ) {
+                       this.document.find( "body" ).css( "cursor", this.storedCursor );
+                       this.storedStylesheet.remove();
+               }
+               if(this._storedOpacity) {
+                       this.helper.css("opacity", this._storedOpacity);
+               }
+               if(this._storedZIndex) {
+                       this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
+               }
+
+               this.dragging = false;
+
+               if(!noPropagation) {
+                       this._trigger("beforeStop", event, this._uiHash());
+               }
+
+               //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+               if ( !this.cancelHelperRemoval ) {
+                       if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
+                               this.helper.remove();
+                       }
+                       this.helper = null;
+               }
+
+               if(!noPropagation) {
+                       for (i=0; i < delayedTriggers.length; i++) {
+                               delayedTriggers[i].call(this, event);
+                       } //Trigger all delayed events
+                       this._trigger("stop", event, this._uiHash());
+               }
+
+               this.fromOutside = false;
+               return !this.cancelHelperRemoval;
+
+       },
+
+       _trigger: function() {
+               if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+                       this.cancel();
+               }
+       },
+
+       _uiHash: function(_inst) {
+               var inst = _inst || this;
+               return {
+                       helper: inst.helper,
+                       placeholder: inst.placeholder || $([]),
+                       position: inst.position,
+                       originalPosition: inst.originalPosition,
+                       offset: inst.positionAbs,
+                       item: inst.currentItem,
+                       sender: _inst ? _inst.element : null
+               };
+       }
+
+});
+
+
+/*!
+ * jQuery UI Spinner 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/spinner/
+ */
+
+
+function spinner_modifier( fn ) {
+       return function() {
+               var previous = this.element.val();
+               fn.apply( this, arguments );
+               this._refresh();
+               if ( previous !== this.element.val() ) {
+                       this._trigger( "change" );
+               }
+       };
+}
+
+var spinner = $.widget( "ui.spinner", {
+       version: "1.11.3",
+       defaultElement: "<input>",
+       widgetEventPrefix: "spin",
+       options: {
+               culture: null,
+               icons: {
+                       down: "ui-icon-triangle-1-s",
+                       up: "ui-icon-triangle-1-n"
+               },
+               incremental: true,
+               max: null,
+               min: null,
+               numberFormat: null,
+               page: 10,
+               step: 1,
+
+               change: null,
+               spin: null,
+               start: null,
+               stop: null
+       },
+
+       _create: function() {
+               // handle string values that need to be parsed
+               this._setOption( "max", this.options.max );
+               this._setOption( "min", this.options.min );
+               this._setOption( "step", this.options.step );
+
+               // Only format if there is a value, prevents the field from being marked
+               // as invalid in Firefox, see #9573.
+               if ( this.value() !== "" ) {
+                       // Format the value, but don't constrain.
+                       this._value( this.element.val(), true );
+               }
+
+               this._draw();
+               this._on( this._events );
+               this._refresh();
+
+               // turning off autocomplete prevents the browser from remembering the
+               // value when navigating through history, so we re-enable autocomplete
+               // if the page is unloaded before the widget is destroyed. #7790
+               this._on( this.window, {
+                       beforeunload: function() {
+                               this.element.removeAttr( "autocomplete" );
+                       }
+               });
+       },
+
+       _getCreateOptions: function() {
+               var options = {},
+                       element = this.element;
+
+               $.each( [ "min", "max", "step" ], function( i, option ) {
+                       var value = element.attr( option );
+                       if ( value !== undefined && value.length ) {
+                               options[ option ] = value;
+                       }
+               });
+
+               return options;
+       },
+
+       _events: {
+               keydown: function( event ) {
+                       if ( this._start( event ) && this._keydown( event ) ) {
+                               event.preventDefault();
+                       }
+               },
+               keyup: "_stop",
+               focus: function() {
+                       this.previous = this.element.val();
+               },
+               blur: function( event ) {
+                       if ( this.cancelBlur ) {
+                               delete this.cancelBlur;
+                               return;
+                       }
+
+                       this._stop();
+                       this._refresh();
+                       if ( this.previous !== this.element.val() ) {
+                               this._trigger( "change", event );
+                       }
+               },
+               mousewheel: function( event, delta ) {
+                       if ( !delta ) {
+                               return;
+                       }
+                       if ( !this.spinning && !this._start( event ) ) {
+                               return false;
+                       }
+
+                       this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
+                       clearTimeout( this.mousewheelTimer );
+                       this.mousewheelTimer = this._delay(function() {
+                               if ( this.spinning ) {
+                                       this._stop( event );
+                               }
+                       }, 100 );
+                       event.preventDefault();
+               },
+               "mousedown .ui-spinner-button": function( event ) {
+                       var previous;
+
+                       // We never want the buttons to have focus; whenever the user is
+                       // interacting with the spinner, the focus should be on the input.
+                       // If the input is focused then this.previous is properly set from
+                       // when the input first received focus. If the input is not focused
+                       // then we need to set this.previous based on the value before spinning.
+                       previous = this.element[0] === this.document[0].activeElement ?
+                               this.previous : this.element.val();
+                       function checkFocus() {
+                               var isActive = this.element[0] === this.document[0].activeElement;
+                               if ( !isActive ) {
+                                       this.element.focus();
+                                       this.previous = previous;
+                                       // support: IE
+                                       // IE sets focus asynchronously, so we need to check if focus
+                                       // moved off of the input because the user clicked on the button.
+                                       this._delay(function() {
+                                               this.previous = previous;
+                                       });
+                               }
+                       }
+
+                       // ensure focus is on (or stays on) the text field
+                       event.preventDefault();
+                       checkFocus.call( this );
+
+                       // support: IE
+                       // IE doesn't prevent moving focus even with event.preventDefault()
+                       // so we set a flag to know when we should ignore the blur event
+                       // and check (again) if focus moved off of the input.
+                       this.cancelBlur = true;
+                       this._delay(function() {
+                               delete this.cancelBlur;
+                               checkFocus.call( this );
+                       });
+
+                       if ( this._start( event ) === false ) {
+                               return;
+                       }
+
+                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+               },
+               "mouseup .ui-spinner-button": "_stop",
+               "mouseenter .ui-spinner-button": function( event ) {
+                       // button will add ui-state-active if mouse was down while mouseleave and kept down
+                       if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
+                               return;
+                       }
+
+                       if ( this._start( event ) === false ) {
+                               return false;
+                       }
+                       this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+               },
+               // TODO: do we really want to consider this a stop?
+               // shouldn't we just stop the repeater and wait until mouseup before
+               // we trigger the stop event?
+               "mouseleave .ui-spinner-button": "_stop"
+       },
+
+       _draw: function() {
+               var uiSpinner = this.uiSpinner = this.element
+                       .addClass( "ui-spinner-input" )
+                       .attr( "autocomplete", "off" )
+                       .wrap( this._uiSpinnerHtml() )
+                       .parent()
+                               // add buttons
+                               .append( this._buttonHtml() );
+
+               this.element.attr( "role", "spinbutton" );
+
+               // button bindings
+               this.buttons = uiSpinner.find( ".ui-spinner-button" )
+                       .attr( "tabIndex", -1 )
+                       .button()
+                       .removeClass( "ui-corner-all" );
+
+               // IE 6 doesn't understand height: 50% for the buttons
+               // unless the wrapper has an explicit height
+               if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
+                               uiSpinner.height() > 0 ) {
+                       uiSpinner.height( uiSpinner.height() );
+               }
+
+               // disable spinner if element was already disabled
+               if ( this.options.disabled ) {
+                       this.disable();
+               }
+       },
+
+       _keydown: function( event ) {
+               var options = this.options,
+                       keyCode = $.ui.keyCode;
+
+               switch ( event.keyCode ) {
+               case keyCode.UP:
+                       this._repeat( null, 1, event );
+                       return true;
+               case keyCode.DOWN:
+                       this._repeat( null, -1, event );
+                       return true;
+               case keyCode.PAGE_UP:
+                       this._repeat( null, options.page, event );
+                       return true;
+               case keyCode.PAGE_DOWN:
+                       this._repeat( null, -options.page, event );
+                       return true;
+               }
+
+               return false;
+       },
+
+       _uiSpinnerHtml: function() {
+               return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
+       },
+
+       _buttonHtml: function() {
+               return "" +
+                       "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
+                               "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
+                       "</a>" +
+                       "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
+                               "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
+                       "</a>";
+       },
+
+       _start: function( event ) {
+               if ( !this.spinning && this._trigger( "start", event ) === false ) {
+                       return false;
+               }
+
+               if ( !this.counter ) {
+                       this.counter = 1;
+               }
+               this.spinning = true;
+               return true;
+       },
+
+       _repeat: function( i, steps, event ) {
+               i = i || 500;
+
+               clearTimeout( this.timer );
+               this.timer = this._delay(function() {
+                       this._repeat( 40, steps, event );
+               }, i );
+
+               this._spin( steps * this.options.step, event );
+       },
+
+       _spin: function( step, event ) {
+               var value = this.value() || 0;
+
+               if ( !this.counter ) {
+                       this.counter = 1;
+               }
+
+               value = this._adjustValue( value + step * this._increment( this.counter ) );
+
+               if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
+                       this._value( value );
+                       this.counter++;
+               }
+       },
+
+       _increment: function( i ) {
+               var incremental = this.options.incremental;
+
+               if ( incremental ) {
+                       return $.isFunction( incremental ) ?
+                               incremental( i ) :
+                               Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
+               }
+
+               return 1;
+       },
+
+       _precision: function() {
+               var precision = this._precisionOf( this.options.step );
+               if ( this.options.min !== null ) {
+                       precision = Math.max( precision, this._precisionOf( this.options.min ) );
+               }
+               return precision;
+       },
+
+       _precisionOf: function( num ) {
+               var str = num.toString(),
+                       decimal = str.indexOf( "." );
+               return decimal === -1 ? 0 : str.length - decimal - 1;
+       },
+
+       _adjustValue: function( value ) {
+               var base, aboveMin,
+                       options = this.options;
+
+               // make sure we're at a valid step
+               // - find out where we are relative to the base (min or 0)
+               base = options.min !== null ? options.min : 0;
+               aboveMin = value - base;
+               // - round to the nearest step
+               aboveMin = Math.round(aboveMin / options.step) * options.step;
+               // - rounding is based on 0, so adjust back to our base
+               value = base + aboveMin;
+
+               // fix precision from bad JS floating point math
+               value = parseFloat( value.toFixed( this._precision() ) );
+
+               // clamp the value
+               if ( options.max !== null && value > options.max) {
+                       return options.max;
+               }
+               if ( options.min !== null && value < options.min ) {
+                       return options.min;
+               }
+
+               return value;
+       },
+
+       _stop: function( event ) {
+               if ( !this.spinning ) {
+                       return;
+               }
+
+               clearTimeout( this.timer );
+               clearTimeout( this.mousewheelTimer );
+               this.counter = 0;
+               this.spinning = false;
+               this._trigger( "stop", event );
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "culture" || key === "numberFormat" ) {
+                       var prevValue = this._parse( this.element.val() );
+                       this.options[ key ] = value;
+                       this.element.val( this._format( prevValue ) );
+                       return;
+               }
+
+               if ( key === "max" || key === "min" || key === "step" ) {
+                       if ( typeof value === "string" ) {
+                               value = this._parse( value );
+                       }
+               }
+               if ( key === "icons" ) {
+                       this.buttons.first().find( ".ui-icon" )
+                               .removeClass( this.options.icons.up )
+                               .addClass( value.up );
+                       this.buttons.last().find( ".ui-icon" )
+                               .removeClass( this.options.icons.down )
+                               .addClass( value.down );
+               }
+
+               this._super( key, value );
+
+               if ( key === "disabled" ) {
+                       this.widget().toggleClass( "ui-state-disabled", !!value );
+                       this.element.prop( "disabled", !!value );
+                       this.buttons.button( value ? "disable" : "enable" );
+               }
+       },
+
+       _setOptions: spinner_modifier(function( options ) {
+               this._super( options );
+       }),
+
+       _parse: function( val ) {
+               if ( typeof val === "string" && val !== "" ) {
+                       val = window.Globalize && this.options.numberFormat ?
+                               Globalize.parseFloat( val, 10, this.options.culture ) : +val;
+               }
+               return val === "" || isNaN( val ) ? null : val;
+       },
+
+       _format: function( value ) {
+               if ( value === "" ) {
+                       return "";
+               }
+               return window.Globalize && this.options.numberFormat ?
+                       Globalize.format( value, this.options.numberFormat, this.options.culture ) :
+                       value;
+       },
+
+       _refresh: function() {
+               this.element.attr({
+                       "aria-valuemin": this.options.min,
+                       "aria-valuemax": this.options.max,
+                       // TODO: what should we do with values that can't be parsed?
+                       "aria-valuenow": this._parse( this.element.val() )
+               });
+       },
+
+       isValid: function() {
+               var value = this.value();
+
+               // null is invalid
+               if ( value === null ) {
+                       return false;
+               }
+
+               // if value gets adjusted, it's invalid
+               return value === this._adjustValue( value );
+       },
+
+       // update the value without triggering change
+       _value: function( value, allowAny ) {
+               var parsed;
+               if ( value !== "" ) {
+                       parsed = this._parse( value );
+                       if ( parsed !== null ) {
+                               if ( !allowAny ) {
+                                       parsed = this._adjustValue( parsed );
+                               }
+                               value = this._format( parsed );
+                       }
+               }
+               this.element.val( value );
+               this._refresh();
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass( "ui-spinner-input" )
+                       .prop( "disabled", false )
+                       .removeAttr( "autocomplete" )
+                       .removeAttr( "role" )
+                       .removeAttr( "aria-valuemin" )
+                       .removeAttr( "aria-valuemax" )
+                       .removeAttr( "aria-valuenow" );
+               this.uiSpinner.replaceWith( this.element );
+       },
+
+       stepUp: spinner_modifier(function( steps ) {
+               this._stepUp( steps );
+       }),
+       _stepUp: function( steps ) {
+               if ( this._start() ) {
+                       this._spin( (steps || 1) * this.options.step );
+                       this._stop();
+               }
+       },
+
+       stepDown: spinner_modifier(function( steps ) {
+               this._stepDown( steps );
+       }),
+       _stepDown: function( steps ) {
+               if ( this._start() ) {
+                       this._spin( (steps || 1) * -this.options.step );
+                       this._stop();
+               }
+       },
+
+       pageUp: spinner_modifier(function( pages ) {
+               this._stepUp( (pages || 1) * this.options.page );
+       }),
+
+       pageDown: spinner_modifier(function( pages ) {
+               this._stepDown( (pages || 1) * this.options.page );
+       }),
+
+       value: function( newVal ) {
+               if ( !arguments.length ) {
+                       return this._parse( this.element.val() );
+               }
+               spinner_modifier( this._value ).call( this, newVal );
+       },
+
+       widget: function() {
+               return this.uiSpinner;
+       }
+});
+
+
+/*!
+ * jQuery UI Tabs 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/tabs/
+ */
+
+
+var tabs = $.widget( "ui.tabs", {
+       version: "1.11.3",
+       delay: 300,
+       options: {
+               active: null,
+               collapsible: false,
+               event: "click",
+               heightStyle: "content",
+               hide: null,
+               show: null,
+
+               // callbacks
+               activate: null,
+               beforeActivate: null,
+               beforeLoad: null,
+               load: null
+       },
+
+       _isLocal: (function() {
+               var rhash = /#.*$/;
+
+               return function( anchor ) {
+                       var anchorUrl, locationUrl;
+
+                       // support: IE7
+                       // IE7 doesn't normalize the href property when set via script (#9317)
+                       anchor = anchor.cloneNode( false );
+
+                       anchorUrl = anchor.href.replace( rhash, "" );
+                       locationUrl = location.href.replace( rhash, "" );
+
+                       // decoding may throw an error if the URL isn't UTF-8 (#9518)
+                       try {
+                               anchorUrl = decodeURIComponent( anchorUrl );
+                       } catch ( error ) {}
+                       try {
+                               locationUrl = decodeURIComponent( locationUrl );
+                       } catch ( error ) {}
+
+                       return anchor.hash.length > 1 && anchorUrl === locationUrl;
+               };
+       })(),
+
+       _create: function() {
+               var that = this,
+                       options = this.options;
+
+               this.running = false;
+
+               this.element
+                       .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
+                       .toggleClass( "ui-tabs-collapsible", options.collapsible );
+
+               this._processTabs();
+               options.active = this._initialActive();
+
+               // Take disabling tabs via class attribute from HTML
+               // into account and update option properly.
+               if ( $.isArray( options.disabled ) ) {
+                       options.disabled = $.unique( options.disabled.concat(
+                               $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
+                                       return that.tabs.index( li );
+                               })
+                       ) ).sort();
+               }
+
+               // check for length avoids error when initializing empty list
+               if ( this.options.active !== false && this.anchors.length ) {
+                       this.active = this._findActive( options.active );
+               } else {
+                       this.active = $();
+               }
+
+               this._refresh();
+
+               if ( this.active.length ) {
+                       this.load( options.active );
+               }
+       },
+
+       _initialActive: function() {
+               var active = this.options.active,
+                       collapsible = this.options.collapsible,
+                       locationHash = location.hash.substring( 1 );
+
+               if ( active === null ) {
+                       // check the fragment identifier in the URL
+                       if ( locationHash ) {
+                               this.tabs.each(function( i, tab ) {
+                                       if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+                                               active = i;
+                                               return false;
+                                       }
+                               });
+                       }
+
+                       // check for a tab marked active via a class
+                       if ( active === null ) {
+                               active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
+                       }
+
+                       // no active tab, set to false
+                       if ( active === null || active === -1 ) {
+                               active = this.tabs.length ? 0 : false;
+                       }
+               }
+
+               // handle numbers: negative, out of range
+               if ( active !== false ) {
+                       active = this.tabs.index( this.tabs.eq( active ) );
+                       if ( active === -1 ) {
+                               active = collapsible ? false : 0;
+                       }
+               }
+
+               // don't allow collapsible: false and active: false
+               if ( !collapsible && active === false && this.anchors.length ) {
+                       active = 0;
+               }
+
+               return active;
+       },
+
+       _getCreateEventData: function() {
+               return {
+                       tab: this.active,
+                       panel: !this.active.length ? $() : this._getPanelForTab( this.active )
+               };
+       },
+
+       _tabKeydown: function( event ) {
+               var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
+                       selectedIndex = this.tabs.index( focusedTab ),
+                       goingForward = true;
+
+               if ( this._handlePageNav( event ) ) {
+                       return;
+               }
+
+               switch ( event.keyCode ) {
+                       case $.ui.keyCode.RIGHT:
+                       case $.ui.keyCode.DOWN:
+                               selectedIndex++;
+                               break;
+                       case $.ui.keyCode.UP:
+                       case $.ui.keyCode.LEFT:
+                               goingForward = false;
+                               selectedIndex--;
+                               break;
+                       case $.ui.keyCode.END:
+                               selectedIndex = this.anchors.length - 1;
+                               break;
+                       case $.ui.keyCode.HOME:
+                               selectedIndex = 0;
+                               break;
+                       case $.ui.keyCode.SPACE:
+                               // Activate only, no collapsing
+                               event.preventDefault();
+                               clearTimeout( this.activating );
+                               this._activate( selectedIndex );
+                               return;
+                       case $.ui.keyCode.ENTER:
+                               // Toggle (cancel delayed activation, allow collapsing)
+                               event.preventDefault();
+                               clearTimeout( this.activating );
+                               // Determine if we should collapse or activate
+                               this._activate( selectedIndex === this.options.active ? false : selectedIndex );
+                               return;
+                       default:
+                               return;
+               }
+
+               // Focus the appropriate tab, based on which key was pressed
+               event.preventDefault();
+               clearTimeout( this.activating );
+               selectedIndex = this._focusNextTab( selectedIndex, goingForward );
+
+               // Navigating with control/command key will prevent automatic activation
+               if ( !event.ctrlKey && !event.metaKey ) {
+
+                       // Update aria-selected immediately so that AT think the tab is already selected.
+                       // Otherwise AT may confuse the user by stating that they need to activate the tab,
+                       // but the tab will already be activated by the time the announcement finishes.
+                       focusedTab.attr( "aria-selected", "false" );
+                       this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
+
+                       this.activating = this._delay(function() {
+                               this.option( "active", selectedIndex );
+                       }, this.delay );
+               }
+       },
+
+       _panelKeydown: function( event ) {
+               if ( this._handlePageNav( event ) ) {
+                       return;
+               }
+
+               // Ctrl+up moves focus to the current tab
+               if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
+                       event.preventDefault();
+                       this.active.focus();
+               }
+       },
+
+       // Alt+page up/down moves focus to the previous/next tab (and activates)
+       _handlePageNav: function( event ) {
+               if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
+                       this._activate( this._focusNextTab( this.options.active - 1, false ) );
+                       return true;
+               }
+               if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
+                       this._activate( this._focusNextTab( this.options.active + 1, true ) );
+                       return true;
+               }
+       },
+
+       _findNextTab: function( index, goingForward ) {
+               var lastTabIndex = this.tabs.length - 1;
+
+               function constrain() {
+                       if ( index > lastTabIndex ) {
+                               index = 0;
+                       }
+                       if ( index < 0 ) {
+                               index = lastTabIndex;
+                       }
+                       return index;
+               }
+
+               while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
+                       index = goingForward ? index + 1 : index - 1;
+               }
+
+               return index;
+       },
+
+       _focusNextTab: function( index, goingForward ) {
+               index = this._findNextTab( index, goingForward );
+               this.tabs.eq( index ).focus();
+               return index;
+       },
+
+       _setOption: function( key, value ) {
+               if ( key === "active" ) {
+                       // _activate() will handle invalid values and update this.options
+                       this._activate( value );
+                       return;
+               }
+
+               if ( key === "disabled" ) {
+                       // don't use the widget factory's disabled handling
+                       this._setupDisabled( value );
+                       return;
+               }
+
+               this._super( key, value);
+
+               if ( key === "collapsible" ) {
+                       this.element.toggleClass( "ui-tabs-collapsible", value );
+                       // Setting collapsible: false while collapsed; open first panel
+                       if ( !value && this.options.active === false ) {
+                               this._activate( 0 );
+                       }
+               }
+
+               if ( key === "event" ) {
+                       this._setupEvents( value );
+               }
+
+               if ( key === "heightStyle" ) {
+                       this._setupHeightStyle( value );
+               }
+       },
+
+       _sanitizeSelector: function( hash ) {
+               return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+       },
+
+       refresh: function() {
+               var options = this.options,
+                       lis = this.tablist.children( ":has(a[href])" );
+
+               // get disabled tabs from class attribute from HTML
+               // this will get converted to a boolean if needed in _refresh()
+               options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
+                       return lis.index( tab );
+               });
+
+               this._processTabs();
+
+               // was collapsed or no tabs
+               if ( options.active === false || !this.anchors.length ) {
+                       options.active = false;
+                       this.active = $();
+               // was active, but active tab is gone
+               } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
+                       // all remaining tabs are disabled
+                       if ( this.tabs.length === options.disabled.length ) {
+                               options.active = false;
+                               this.active = $();
+                       // activate previous tab
+                       } else {
+                               this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
+                       }
+               // was active, active tab still exists
+               } else {
+                       // make sure active index is correct
+                       options.active = this.tabs.index( this.active );
+               }
+
+               this._refresh();
+       },
+
+       _refresh: function() {
+               this._setupDisabled( this.options.disabled );
+               this._setupEvents( this.options.event );
+               this._setupHeightStyle( this.options.heightStyle );
+
+               this.tabs.not( this.active ).attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false",
+                       tabIndex: -1
+               });
+               this.panels.not( this._getPanelForTab( this.active ) )
+                       .hide()
+                       .attr({
+                               "aria-hidden": "true"
+                       });
+
+               // Make sure one tab is in the tab order
+               if ( !this.active.length ) {
+                       this.tabs.eq( 0 ).attr( "tabIndex", 0 );
+               } else {
+                       this.active
+                               .addClass( "ui-tabs-active ui-state-active" )
+                               .attr({
+                                       "aria-selected": "true",
+                                       "aria-expanded": "true",
+                                       tabIndex: 0
+                               });
+                       this._getPanelForTab( this.active )
+                               .show()
+                               .attr({
+                                       "aria-hidden": "false"
+                               });
+               }
+       },
+
+       _processTabs: function() {
+               var that = this,
+                       prevTabs = this.tabs,
+                       prevAnchors = this.anchors,
+                       prevPanels = this.panels;
+
+               this.tablist = this._getList()
+                       .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+                       .attr( "role", "tablist" )
+
+                       // Prevent users from focusing disabled tabs via click
+                       .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
+                               if ( $( this ).is( ".ui-state-disabled" ) ) {
+                                       event.preventDefault();
+                               }
+                       })
+
+                       // support: IE <9
+                       // Preventing the default action in mousedown doesn't prevent IE
+                       // from focusing the element, so if the anchor gets focused, blur.
+                       // We don't have to worry about focusing the previously focused
+                       // element since clicking on a non-focusable element should focus
+                       // the body anyway.
+                       .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
+                               if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
+                                       this.blur();
+                               }
+                       });
+
+               this.tabs = this.tablist.find( "> li:has(a[href])" )
+                       .addClass( "ui-state-default ui-corner-top" )
+                       .attr({
+                               role: "tab",
+                               tabIndex: -1
+                       });
+
+               this.anchors = this.tabs.map(function() {
+                               return $( "a", this )[ 0 ];
+                       })
+                       .addClass( "ui-tabs-anchor" )
+                       .attr({
+                               role: "presentation",
+                               tabIndex: -1
+                       });
+
+               this.panels = $();
+
+               this.anchors.each(function( i, anchor ) {
+                       var selector, panel, panelId,
+                               anchorId = $( anchor ).uniqueId().attr( "id" ),
+                               tab = $( anchor ).closest( "li" ),
+                               originalAriaControls = tab.attr( "aria-controls" );
+
+                       // inline tab
+                       if ( that._isLocal( anchor ) ) {
+                               selector = anchor.hash;
+                               panelId = selector.substring( 1 );
+                               panel = that.element.find( that._sanitizeSelector( selector ) );
+                       // remote tab
+                       } else {
+                               // If the tab doesn't already have aria-controls,
+                               // generate an id by using a throw-away element
+                               panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
+                               selector = "#" + panelId;
+                               panel = that.element.find( selector );
+                               if ( !panel.length ) {
+                                       panel = that._createPanel( panelId );
+                                       panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
+                               }
+                               panel.attr( "aria-live", "polite" );
+                       }
+
+                       if ( panel.length) {
+                               that.panels = that.panels.add( panel );
+                       }
+                       if ( originalAriaControls ) {
+                               tab.data( "ui-tabs-aria-controls", originalAriaControls );
+                       }
+                       tab.attr({
+                               "aria-controls": panelId,
+                               "aria-labelledby": anchorId
+                       });
+                       panel.attr( "aria-labelledby", anchorId );
+               });
+
+               this.panels
+                       .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+                       .attr( "role", "tabpanel" );
+
+               // Avoid memory leaks (#10056)
+               if ( prevTabs ) {
+                       this._off( prevTabs.not( this.tabs ) );
+                       this._off( prevAnchors.not( this.anchors ) );
+                       this._off( prevPanels.not( this.panels ) );
+               }
+       },
+
+       // allow overriding how to find the list for rare usage scenarios (#7715)
+       _getList: function() {
+               return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
+       },
+
+       _createPanel: function( id ) {
+               return $( "<div>" )
+                       .attr( "id", id )
+                       .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+                       .data( "ui-tabs-destroy", true );
+       },
+
+       _setupDisabled: function( disabled ) {
+               if ( $.isArray( disabled ) ) {
+                       if ( !disabled.length ) {
+                               disabled = false;
+                       } else if ( disabled.length === this.anchors.length ) {
+                               disabled = true;
+                       }
+               }
+
+               // disable tabs
+               for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
+                       if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
+                               $( li )
+                                       .addClass( "ui-state-disabled" )
+                                       .attr( "aria-disabled", "true" );
+                       } else {
+                               $( li )
+                                       .removeClass( "ui-state-disabled" )
+                                       .removeAttr( "aria-disabled" );
+                       }
+               }
+
+               this.options.disabled = disabled;
+       },
+
+       _setupEvents: function( event ) {
+               var events = {};
+               if ( event ) {
+                       $.each( event.split(" "), function( index, eventName ) {
+                               events[ eventName ] = "_eventHandler";
+                       });
+               }
+
+               this._off( this.anchors.add( this.tabs ).add( this.panels ) );
+               // Always prevent the default action, even when disabled
+               this._on( true, this.anchors, {
+                       click: function( event ) {
+                               event.preventDefault();
+                       }
+               });
+               this._on( this.anchors, events );
+               this._on( this.tabs, { keydown: "_tabKeydown" } );
+               this._on( this.panels, { keydown: "_panelKeydown" } );
+
+               this._focusable( this.tabs );
+               this._hoverable( this.tabs );
+       },
+
+       _setupHeightStyle: function( heightStyle ) {
+               var maxHeight,
+                       parent = this.element.parent();
+
+               if ( heightStyle === "fill" ) {
+                       maxHeight = parent.height();
+                       maxHeight -= this.element.outerHeight() - this.element.height();
+
+                       this.element.siblings( ":visible" ).each(function() {
+                               var elem = $( this ),
+                                       position = elem.css( "position" );
+
+                               if ( position === "absolute" || position === "fixed" ) {
+                                       return;
+                               }
+                               maxHeight -= elem.outerHeight( true );
+                       });
+
+                       this.element.children().not( this.panels ).each(function() {
+                               maxHeight -= $( this ).outerHeight( true );
+                       });
+
+                       this.panels.each(function() {
+                               $( this ).height( Math.max( 0, maxHeight -
+                                       $( this ).innerHeight() + $( this ).height() ) );
+                       })
+                       .css( "overflow", "auto" );
+               } else if ( heightStyle === "auto" ) {
+                       maxHeight = 0;
+                       this.panels.each(function() {
+                               maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+                       }).height( maxHeight );
+               }
+       },
+
+       _eventHandler: function( event ) {
+               var options = this.options,
+                       active = this.active,
+                       anchor = $( event.currentTarget ),
+                       tab = anchor.closest( "li" ),
+                       clickedIsActive = tab[ 0 ] === active[ 0 ],
+                       collapsing = clickedIsActive && options.collapsible,
+                       toShow = collapsing ? $() : this._getPanelForTab( tab ),
+                       toHide = !active.length ? $() : this._getPanelForTab( active ),
+                       eventData = {
+                               oldTab: active,
+                               oldPanel: toHide,
+                               newTab: collapsing ? $() : tab,
+                               newPanel: toShow
+                       };
+
+               event.preventDefault();
+
+               if ( tab.hasClass( "ui-state-disabled" ) ||
+                               // tab is already loading
+                               tab.hasClass( "ui-tabs-loading" ) ||
+                               // can't switch durning an animation
+                               this.running ||
+                               // click on active header, but not collapsible
+                               ( clickedIsActive && !options.collapsible ) ||
+                               // allow canceling activation
+                               ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+                       return;
+               }
+
+               options.active = collapsing ? false : this.tabs.index( tab );
+
+               this.active = clickedIsActive ? $() : tab;
+               if ( this.xhr ) {
+                       this.xhr.abort();
+               }
+
+               if ( !toHide.length && !toShow.length ) {
+                       $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
+               }
+
+               if ( toShow.length ) {
+                       this.load( this.tabs.index( tab ), event );
+               }
+               this._toggle( event, eventData );
+       },
+
+       // handles show/hide for selecting tabs
+       _toggle: function( event, eventData ) {
+               var that = this,
+                       toShow = eventData.newPanel,
+                       toHide = eventData.oldPanel;
+
+               this.running = true;
+
+               function complete() {
+                       that.running = false;
+                       that._trigger( "activate", event, eventData );
+               }
+
+               function show() {
+                       eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
+
+                       if ( toShow.length && that.options.show ) {
+                               that._show( toShow, that.options.show, complete );
+                       } else {
+                               toShow.show();
+                               complete();
+                       }
+               }
+
+               // start out by hiding, then showing, then completing
+               if ( toHide.length && this.options.hide ) {
+                       this._hide( toHide, this.options.hide, function() {
+                               eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+                               show();
+                       });
+               } else {
+                       eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+                       toHide.hide();
+                       show();
+               }
+
+               toHide.attr( "aria-hidden", "true" );
+               eventData.oldTab.attr({
+                       "aria-selected": "false",
+                       "aria-expanded": "false"
+               });
+               // If we're switching tabs, remove the old tab from the tab order.
+               // If we're opening from collapsed state, remove the previous tab from the tab order.
+               // If we're collapsing, then keep the collapsing tab in the tab order.
+               if ( toShow.length && toHide.length ) {
+                       eventData.oldTab.attr( "tabIndex", -1 );
+               } else if ( toShow.length ) {
+                       this.tabs.filter(function() {
+                               return $( this ).attr( "tabIndex" ) === 0;
+                       })
+                       .attr( "tabIndex", -1 );
+               }
+
+               toShow.attr( "aria-hidden", "false" );
+               eventData.newTab.attr({
+                       "aria-selected": "true",
+                       "aria-expanded": "true",
+                       tabIndex: 0
+               });
+       },
+
+       _activate: function( index ) {
+               var anchor,
+                       active = this._findActive( index );
+
+               // trying to activate the already active panel
+               if ( active[ 0 ] === this.active[ 0 ] ) {
+                       return;
+               }
+
+               // trying to collapse, simulate a click on the current active header
+               if ( !active.length ) {
+                       active = this.active;
+               }
+
+               anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
+               this._eventHandler({
+                       target: anchor,
+                       currentTarget: anchor,
+                       preventDefault: $.noop
+               });
+       },
+
+       _findActive: function( index ) {
+               return index === false ? $() : this.tabs.eq( index );
+       },
+
+       _getIndex: function( index ) {
+               // meta-function to give users option to provide a href string instead of a numerical index.
+               if ( typeof index === "string" ) {
+                       index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
+               }
+
+               return index;
+       },
+
+       _destroy: function() {
+               if ( this.xhr ) {
+                       this.xhr.abort();
+               }
+
+               this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
+
+               this.tablist
+                       .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+                       .removeAttr( "role" );
+
+               this.anchors
+                       .removeClass( "ui-tabs-anchor" )
+                       .removeAttr( "role" )
+                       .removeAttr( "tabIndex" )
+                       .removeUniqueId();
+
+               this.tablist.unbind( this.eventNamespace );
+
+               this.tabs.add( this.panels ).each(function() {
+                       if ( $.data( this, "ui-tabs-destroy" ) ) {
+                               $( this ).remove();
+                       } else {
+                               $( this )
+                                       .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
+                                               "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
+                                       .removeAttr( "tabIndex" )
+                                       .removeAttr( "aria-live" )
+                                       .removeAttr( "aria-busy" )
+                                       .removeAttr( "aria-selected" )
+                                       .removeAttr( "aria-labelledby" )
+                                       .removeAttr( "aria-hidden" )
+                                       .removeAttr( "aria-expanded" )
+                                       .removeAttr( "role" );
+                       }
+               });
+
+               this.tabs.each(function() {
+                       var li = $( this ),
+                               prev = li.data( "ui-tabs-aria-controls" );
+                       if ( prev ) {
+                               li
+                                       .attr( "aria-controls", prev )
+                                       .removeData( "ui-tabs-aria-controls" );
+                       } else {
+                               li.removeAttr( "aria-controls" );
+                       }
+               });
+
+               this.panels.show();
+
+               if ( this.options.heightStyle !== "content" ) {
+                       this.panels.css( "height", "" );
+               }
+       },
+
+       enable: function( index ) {
+               var disabled = this.options.disabled;
+               if ( disabled === false ) {
+                       return;
+               }
+
+               if ( index === undefined ) {
+                       disabled = false;
+               } else {
+                       index = this._getIndex( index );
+                       if ( $.isArray( disabled ) ) {
+                               disabled = $.map( disabled, function( num ) {
+                                       return num !== index ? num : null;
+                               });
+                       } else {
+                               disabled = $.map( this.tabs, function( li, num ) {
+                                       return num !== index ? num : null;
+                               });
+                       }
+               }
+               this._setupDisabled( disabled );
+       },
+
+       disable: function( index ) {
+               var disabled = this.options.disabled;
+               if ( disabled === true ) {
+                       return;
+               }
+
+               if ( index === undefined ) {
+                       disabled = true;
+               } else {
+                       index = this._getIndex( index );
+                       if ( $.inArray( index, disabled ) !== -1 ) {
+                               return;
+                       }
+                       if ( $.isArray( disabled ) ) {
+                               disabled = $.merge( [ index ], disabled ).sort();
+                       } else {
+                               disabled = [ index ];
+                       }
+               }
+               this._setupDisabled( disabled );
+       },
+
+       load: function( index, event ) {
+               index = this._getIndex( index );
+               var that = this,
+                       tab = this.tabs.eq( index ),
+                       anchor = tab.find( ".ui-tabs-anchor" ),
+                       panel = this._getPanelForTab( tab ),
+                       eventData = {
+                               tab: tab,
+                               panel: panel
+                       };
+
+               // not remote
+               if ( this._isLocal( anchor[ 0 ] ) ) {
+                       return;
+               }
+
+               this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
+
+               // support: jQuery <1.8
+               // jQuery <1.8 returns false if the request is canceled in beforeSend,
+               // but as of 1.8, $.ajax() always returns a jqXHR object.
+               if ( this.xhr && this.xhr.statusText !== "canceled" ) {
+                       tab.addClass( "ui-tabs-loading" );
+                       panel.attr( "aria-busy", "true" );
+
+                       this.xhr
+                               .success(function( response ) {
+                                       // support: jQuery <1.8
+                                       // http://bugs.jquery.com/ticket/11778
+                                       setTimeout(function() {
+                                               panel.html( response );
+                                               that._trigger( "load", event, eventData );
+                                       }, 1 );
+                               })
+                               .complete(function( jqXHR, status ) {
+                                       // support: jQuery <1.8
+                                       // http://bugs.jquery.com/ticket/11778
+                                       setTimeout(function() {
+                                               if ( status === "abort" ) {
+                                                       that.panels.stop( false, true );
+                                               }
+
+                                               tab.removeClass( "ui-tabs-loading" );
+                                               panel.removeAttr( "aria-busy" );
+
+                                               if ( jqXHR === that.xhr ) {
+                                                       delete that.xhr;
+                                               }
+                                       }, 1 );
+                               });
+               }
+       },
+
+       _ajaxSettings: function( anchor, event, eventData ) {
+               var that = this;
+               return {
+                       url: anchor.attr( "href" ),
+                       beforeSend: function( jqXHR, settings ) {
+                               return that._trigger( "beforeLoad", event,
+                                       $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
+                       }
+               };
+       },
+
+       _getPanelForTab: function( tab ) {
+               var id = $( tab ).attr( "aria-controls" );
+               return this.element.find( this._sanitizeSelector( "#" + id ) );
+       }
+});
+
+
+/*!
+ * jQuery UI Tooltip 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/tooltip/
+ */
+
+
+var tooltip = $.widget( "ui.tooltip", {
+       version: "1.11.3",
+       options: {
+               content: function() {
+                       // support: IE<9, Opera in jQuery <1.7
+                       // .text() can't accept undefined, so coerce to a string
+                       var title = $( this ).attr( "title" ) || "";
+                       // Escape title, since we're going from an attribute to raw HTML
+                       return $( "<a>" ).text( title ).html();
+               },
+               hide: true,
+               // Disabled elements have inconsistent behavior across browsers (#8661)
+               items: "[title]:not([disabled])",
+               position: {
+                       my: "left top+15",
+                       at: "left bottom",
+                       collision: "flipfit flip"
+               },
+               show: true,
+               tooltipClass: null,
+               track: false,
+
+               // callbacks
+               close: null,
+               open: null
+       },
+
+       _addDescribedBy: function( elem, id ) {
+               var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
+               describedby.push( id );
+               elem
+                       .data( "ui-tooltip-id", id )
+                       .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
+       },
+
+       _removeDescribedBy: function( elem ) {
+               var id = elem.data( "ui-tooltip-id" ),
+                       describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
+                       index = $.inArray( id, describedby );
+
+               if ( index !== -1 ) {
+                       describedby.splice( index, 1 );
+               }
+
+               elem.removeData( "ui-tooltip-id" );
+               describedby = $.trim( describedby.join( " " ) );
+               if ( describedby ) {
+                       elem.attr( "aria-describedby", describedby );
+               } else {
+                       elem.removeAttr( "aria-describedby" );
+               }
+       },
+
+       _create: function() {
+               this._on({
+                       mouseover: "open",
+                       focusin: "open"
+               });
+
+               // IDs of generated tooltips, needed for destroy
+               this.tooltips = {};
+
+               // IDs of parent tooltips where we removed the title attribute
+               this.parents = {};
+
+               if ( this.options.disabled ) {
+                       this._disable();
+               }
+
+               // Append the aria-live region so tooltips announce correctly
+               this.liveRegion = $( "<div>" )
+                       .attr({
+                               role: "log",
+                               "aria-live": "assertive",
+                               "aria-relevant": "additions"
+                       })
+                       .addClass( "ui-helper-hidden-accessible" )
+                       .appendTo( this.document[ 0 ].body );
+       },
+
+       _setOption: function( key, value ) {
+               var that = this;
+
+               if ( key === "disabled" ) {
+                       this[ value ? "_disable" : "_enable" ]();
+                       this.options[ key ] = value;
+                       // disable element style changes
+                       return;
+               }
+
+               this._super( key, value );
+
+               if ( key === "content" ) {
+                       $.each( this.tooltips, function( id, tooltipData ) {
+                               that._updateContent( tooltipData.element );
+                       });
+               }
+       },
+
+       _disable: function() {
+               var that = this;
+
+               // close open tooltips
+               $.each( this.tooltips, function( id, tooltipData ) {
+                       var event = $.Event( "blur" );
+                       event.target = event.currentTarget = tooltipData.element[ 0 ];
+                       that.close( event, true );
+               });
+
+               // remove title attributes to prevent native tooltips
+               this.element.find( this.options.items ).addBack().each(function() {
+                       var element = $( this );
+                       if ( element.is( "[title]" ) ) {
+                               element
+                                       .data( "ui-tooltip-title", element.attr( "title" ) )
+                                       .removeAttr( "title" );
+                       }
+               });
+       },
+
+       _enable: function() {
+               // restore title attributes
+               this.element.find( this.options.items ).addBack().each(function() {
+                       var element = $( this );
+                       if ( element.data( "ui-tooltip-title" ) ) {
+                               element.attr( "title", element.data( "ui-tooltip-title" ) );
+                       }
+               });
+       },
+
+       open: function( event ) {
+               var that = this,
+                       target = $( event ? event.target : this.element )
+                               // we need closest here due to mouseover bubbling,
+                               // but always pointing at the same event target
+                               .closest( this.options.items );
+
+               // No element to show a tooltip for or the tooltip is already open
+               if ( !target.length || target.data( "ui-tooltip-id" ) ) {
+                       return;
+               }
+
+               if ( target.attr( "title" ) ) {
+                       target.data( "ui-tooltip-title", target.attr( "title" ) );
+               }
+
+               target.data( "ui-tooltip-open", true );
+
+               // kill parent tooltips, custom or native, for hover
+               if ( event && event.type === "mouseover" ) {
+                       target.parents().each(function() {
+                               var parent = $( this ),
+                                       blurEvent;
+                               if ( parent.data( "ui-tooltip-open" ) ) {
+                                       blurEvent = $.Event( "blur" );
+                                       blurEvent.target = blurEvent.currentTarget = this;
+                                       that.close( blurEvent, true );
+                               }
+                               if ( parent.attr( "title" ) ) {
+                                       parent.uniqueId();
+                                       that.parents[ this.id ] = {
+                                               element: this,
+                                               title: parent.attr( "title" )
+                                       };
+                                       parent.attr( "title", "" );
+                               }
+                       });
+               }
+
+               this._updateContent( target, event );
+       },
+
+       _updateContent: function( target, event ) {
+               var content,
+                       contentOption = this.options.content,
+                       that = this,
+                       eventType = event ? event.type : null;
+
+               if ( typeof contentOption === "string" ) {
+                       return this._open( event, target, contentOption );
+               }
+
+               content = contentOption.call( target[0], function( response ) {
+                       // ignore async response if tooltip was closed already
+                       if ( !target.data( "ui-tooltip-open" ) ) {
+                               return;
+                       }
+                       // IE may instantly serve a cached response for ajax requests
+                       // delay this call to _open so the other call to _open runs first
+                       that._delay(function() {
+                               // jQuery creates a special event for focusin when it doesn't
+                               // exist natively. To improve performance, the native event
+                               // object is reused and the type is changed. Therefore, we can't
+                               // rely on the type being correct after the event finished
+                               // bubbling, so we set it back to the previous value. (#8740)
+                               if ( event ) {
+                                       event.type = eventType;
+                               }
+                               this._open( event, target, response );
+                       });
+               });
+               if ( content ) {
+                       this._open( event, target, content );
+               }
+       },
+
+       _open: function( event, target, content ) {
+               var tooltipData, tooltip, events, delayedShow, a11yContent,
+                       positionOption = $.extend( {}, this.options.position );
+
+               if ( !content ) {
+                       return;
+               }
+
+               // Content can be updated multiple times. If the tooltip already
+               // exists, then just update the content and bail.
+               tooltipData = this._find( target );
+               if ( tooltipData ) {
+                       tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
+                       return;
+               }
+
+               // if we have a title, clear it to prevent the native tooltip
+               // we have to check first to avoid defining a title if none exists
+               // (we don't want to cause an element to start matching [title])
+               //
+               // We use removeAttr only for key events, to allow IE to export the correct
+               // accessible attributes. For mouse events, set to empty string to avoid
+               // native tooltip showing up (happens only when removing inside mouseover).
+               if ( target.is( "[title]" ) ) {
+                       if ( event && event.type === "mouseover" ) {
+                               target.attr( "title", "" );
+                       } else {
+                               target.removeAttr( "title" );
+                       }
+               }
+
+               tooltipData = this._tooltip( target );
+               tooltip = tooltipData.tooltip;
+               this._addDescribedBy( target, tooltip.attr( "id" ) );
+               tooltip.find( ".ui-tooltip-content" ).html( content );
+
+               // Support: Voiceover on OS X, JAWS on IE <= 9
+               // JAWS announces deletions even when aria-relevant="additions"
+               // Voiceover will sometimes re-read the entire log region's contents from the beginning
+               this.liveRegion.children().hide();
+               if ( content.clone ) {
+                       a11yContent = content.clone();
+                       a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
+               } else {
+                       a11yContent = content;
+               }
+               $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
+
+               function position( event ) {
+                       positionOption.of = event;
+                       if ( tooltip.is( ":hidden" ) ) {
+                               return;
+                       }
+                       tooltip.position( positionOption );
+               }
+               if ( this.options.track && event && /^mouse/.test( event.type ) ) {
+                       this._on( this.document, {
+                               mousemove: position
+                       });
+                       // trigger once to override element-relative positioning
+                       position( event );
+               } else {
+                       tooltip.position( $.extend({
+                               of: target
+                       }, this.options.position ) );
+               }
+
+               tooltip.hide();
+
+               this._show( tooltip, this.options.show );
+               // Handle tracking tooltips that are shown with a delay (#8644). As soon
+               // as the tooltip is visible, position the tooltip using the most recent
+               // event.
+               if ( this.options.show && this.options.show.delay ) {
+                       delayedShow = this.delayedShow = setInterval(function() {
+                               if ( tooltip.is( ":visible" ) ) {
+                                       position( positionOption.of );
+                                       clearInterval( delayedShow );
+                               }
+                       }, $.fx.interval );
+               }
+
+               this._trigger( "open", event, { tooltip: tooltip } );
+
+               events = {
+                       keyup: function( event ) {
+                               if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
+                                       var fakeEvent = $.Event(event);
+                                       fakeEvent.currentTarget = target[0];
+                                       this.close( fakeEvent, true );
+                               }
+                       }
+               };
+
+               // Only bind remove handler for delegated targets. Non-delegated
+               // tooltips will handle this in destroy.
+               if ( target[ 0 ] !== this.element[ 0 ] ) {
+                       events.remove = function() {
+                               this._removeTooltip( tooltip );
+                       };
+               }
+
+               if ( !event || event.type === "mouseover" ) {
+                       events.mouseleave = "close";
+               }
+               if ( !event || event.type === "focusin" ) {
+                       events.focusout = "close";
+               }
+               this._on( true, target, events );
+       },
+
+       close: function( event ) {
+               var tooltip,
+                       that = this,
+                       target = $( event ? event.currentTarget : this.element ),
+                       tooltipData = this._find( target );
+
+               // The tooltip may already be closed
+               if ( !tooltipData ) {
+                       return;
+               }
+
+               tooltip = tooltipData.tooltip;
+
+               // disabling closes the tooltip, so we need to track when we're closing
+               // to avoid an infinite loop in case the tooltip becomes disabled on close
+               if ( tooltipData.closing ) {
+                       return;
+               }
+
+               // Clear the interval for delayed tracking tooltips
+               clearInterval( this.delayedShow );
+
+               // only set title if we had one before (see comment in _open())
+               // If the title attribute has changed since open(), don't restore
+               if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
+                       target.attr( "title", target.data( "ui-tooltip-title" ) );
+               }
+
+               this._removeDescribedBy( target );
+
+               tooltipData.hiding = true;
+               tooltip.stop( true );
+               this._hide( tooltip, this.options.hide, function() {
+                       that._removeTooltip( $( this ) );
+               });
+
+               target.removeData( "ui-tooltip-open" );
+               this._off( target, "mouseleave focusout keyup" );
+
+               // Remove 'remove' binding only on delegated targets
+               if ( target[ 0 ] !== this.element[ 0 ] ) {
+                       this._off( target, "remove" );
+               }
+               this._off( this.document, "mousemove" );
+
+               if ( event && event.type === "mouseleave" ) {
+                       $.each( this.parents, function( id, parent ) {
+                               $( parent.element ).attr( "title", parent.title );
+                               delete that.parents[ id ];
+                       });
+               }
+
+               tooltipData.closing = true;
+               this._trigger( "close", event, { tooltip: tooltip } );
+               if ( !tooltipData.hiding ) {
+                       tooltipData.closing = false;
+               }
+       },
+
+       _tooltip: function( element ) {
+               var tooltip = $( "<div>" )
+                               .attr( "role", "tooltip" )
+                               .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
+                                       ( this.options.tooltipClass || "" ) ),
+                       id = tooltip.uniqueId().attr( "id" );
+
+               $( "<div>" )
+                       .addClass( "ui-tooltip-content" )
+                       .appendTo( tooltip );
+
+               tooltip.appendTo( this.document[0].body );
+
+               return this.tooltips[ id ] = {
+                       element: element,
+                       tooltip: tooltip
+               };
+       },
+
+       _find: function( target ) {
+               var id = target.data( "ui-tooltip-id" );
+               return id ? this.tooltips[ id ] : null;
+       },
+
+       _removeTooltip: function( tooltip ) {
+               tooltip.remove();
+               delete this.tooltips[ tooltip.attr( "id" ) ];
+       },
+
+       _destroy: function() {
+               var that = this;
+
+               // close open tooltips
+               $.each( this.tooltips, function( id, tooltipData ) {
+                       // Delegate to close method to handle common cleanup
+                       var event = $.Event( "blur" ),
+                               element = tooltipData.element;
+                       event.target = event.currentTarget = element[ 0 ];
+                       that.close( event, true );
+
+                       // Remove immediately; destroying an open tooltip doesn't use the
+                       // hide animation
+                       $( "#" + id ).remove();
+
+                       // Restore the title
+                       if ( element.data( "ui-tooltip-title" ) ) {
+                               // If the title attribute has changed since open(), don't restore
+                               if ( !element.attr( "title" ) ) {
+                                       element.attr( "title", element.data( "ui-tooltip-title" ) );
+                               }
+                               element.removeData( "ui-tooltip-title" );
+                       }
+               });
+               this.liveRegion.remove();
+       }
+});
+
+
+
+}));
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.css
new file mode 100644 (file)
index 0000000..3d024c3
--- /dev/null
@@ -0,0 +1,7 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#2b2b2b;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.js b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.min.js
new file mode 100644 (file)
index 0000000..760e149
--- /dev/null
@@ -0,0 +1,13 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}function s(e){for(var t,i;e.length&&e[0]!==document;){if(t=e.css("position"),("absolute"===t||"relative"===t||"fixed"===t)&&(i=parseInt(e.css("zIndex"),10),!isNaN(i)&&0!==i))return i;e=e.parent()}return 0}function n(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.regional.en=e.extend(!0,{},this.regional[""]),this.regional["en-US"]=e.extend(!0,{},this.regional.en),this.dpDiv=a(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",o)}function o(){e.datepicker._isDisabledDatepicker(v.inline?v.dpDiv.parent()[0]:v.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))}function r(t,i){e.extend(t,i);for(var s in i)null==i[s]&&(t[s]=i[s]);return t}function h(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var l=0,u=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,n=u.call(arguments,1),a=0,o=n.length;o>a;a++)for(i in n[a])s=n[a][i],n[a].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(n){var a="string"==typeof n,o=u.call(arguments,1),r=this;return a?this.each(function(){var i,a=e.data(this,s);return"instance"===n?(r=a,!1):a?e.isFunction(a[n])&&"_"!==n.charAt(0)?(i=a[n].apply(a,o),i!==a&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+n+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+n+"'")}):(o.length&&(n=e.widget.extend.apply(null,[n].concat(o))),this.each(function(){var t=e.data(this,s);t?(t.option(n||{}),t._init&&t._init()):e.data(this,s,new i(n,this))})),r}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=l++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var d=!1;e(document).mouseup(function(){d=!1}),e.widget("ui.mouse",{version:"1.11.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!d){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),d=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),d=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,i,s=e("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=s.children()[0];return e("body").append(s),t=a.offsetWidth,s.css("overflow","scroll"),i=a.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),n=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),n="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,a="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:a?e.position.scrollbarWidth():0,height:n?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:n,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s||n?i.width():i.outerWidth(),height:s||n?i.height():i.outerHeight()}}},e.fn.position=function(n){if(!n||!n.of)return f.apply(this,arguments);n=e.extend({},n);var p,m,g,v,y,b,_=e(n.of),x=e.position.getWithinInfo(n.within),w=e.position.getScrollInfo(x),k=(n.collision||"flip").split(" "),T={};return b=s(_),_[0].preventDefault&&(n.at="left top"),m=b.width,g=b.height,v=b.offset,y=e.extend({},v),e.each(["my","at"],function(){var e,t,i=(n[this]||"").split(" ");1===i.length&&(i=l.test(i[0])?i.concat(["center"]):u.test(i[0])?["center"].concat(i):["center","center"]),i[0]=l.test(i[0])?i[0]:"center",i[1]=u.test(i[1])?i[1]:"center",e=d.exec(i[0]),t=d.exec(i[1]),T[this]=[e?e[0]:0,t?t[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===n.at[0]?y.left+=m:"center"===n.at[0]&&(y.left+=m/2),"bottom"===n.at[1]?y.top+=g:"center"===n.at[1]&&(y.top+=g/2),p=t(T.at,m,g),y.left+=p[0],y.top+=p[1],this.each(function(){var s,l,u=e(this),d=u.outerWidth(),c=u.outerHeight(),f=i(this,"marginLeft"),b=i(this,"marginTop"),D=d+f+i(this,"marginRight")+w.width,S=c+b+i(this,"marginBottom")+w.height,M=e.extend({},y),C=t(T.my,u.outerWidth(),u.outerHeight());"right"===n.my[0]?M.left-=d:"center"===n.my[0]&&(M.left-=d/2),"bottom"===n.my[1]?M.top-=c:"center"===n.my[1]&&(M.top-=c/2),M.left+=C[0],M.top+=C[1],a||(M.left=h(M.left),M.top=h(M.top)),s={marginLeft:f,marginTop:b},e.each(["left","top"],function(t,i){e.ui.position[k[t]]&&e.ui.position[k[t]][i](M,{targetWidth:m,targetHeight:g,elemWidth:d,elemHeight:c,collisionPosition:s,collisionWidth:D,collisionHeight:S,offset:[p[0]+C[0],p[1]+C[1]],my:n.my,at:n.at,within:x,elem:u})}),n.using&&(l=function(e){var t=v.left-M.left,i=t+m-d,s=v.top-M.top,a=s+g-c,h={target:{element:_,left:v.left,top:v.top,width:m,height:g},element:{element:u,left:M.left,top:M.top,width:d,height:c},horizontal:0>i?"left":t>0?"right":"center",vertical:0>a?"top":s>0?"bottom":"middle"};d>m&&m>r(t+i)&&(h.horizontal="center"),c>g&&g>r(s+a)&&(h.vertical="middle"),h.important=o(r(t),r(i))>o(r(s),r(a))?"horizontal":"vertical",n.using.call(this,e,h)}),u.offset(e.extend(M,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=e.left-t.collisionPosition.marginLeft,h=n-r,l=r+t.collisionWidth-a-n;t.collisionWidth>a?h>0&&0>=l?(i=e.left+h+t.collisionWidth-a-n,e.left+=h-i):e.left=l>0&&0>=h?n:h>l?n+a-t.collisionWidth:n:h>0?e.left+=h:l>0?e.left-=l:e.left=o(e.left-r,e.left)},top:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollTop:s.offset.top,a=t.within.height,r=e.top-t.collisionPosition.marginTop,h=n-r,l=r+t.collisionHeight-a-n;t.collisionHeight>a?h>0&&0>=l?(i=e.top+h+t.collisionHeight-a-n,e.top+=h-i):e.top=l>0&&0>=h?n:h>l?n+a-t.collisionHeight:n:h>0?e.top+=h:l>0?e.top-=l:e.top=o(e.top-r,e.top)}},flip:{left:function(e,t){var i,s,n=t.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-o-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-o-a,(0>i||r(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>r(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,n=t.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-o-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-o-a,(0>s||r(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,(i>0||d>r(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,n,o,r=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)t.style[o]=s[o];t.appendChild(h),i=r||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",n=e(h).offset().left,a=n>10&&11>n,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.accordion",{version:"1.11.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),e=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&(this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)),void 0)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,s=this.headers.length,n=this.headers.index(t.target),a=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(e(t.target).attr("tabIndex",-1),e(a).attr("tabIndex",0),a.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var e=this.headers,t=this.panels;this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.panels=this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide(),t&&(this._off(e.not(this.headers)),this._off(t.not(this.panels)))},_refresh:function(){var t,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var t=e(this),i=t.uniqueId().attr("id"),s=t.next(),n=s.uniqueId().attr("id");t.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(t=n.height(),this.element.siblings(":visible").each(function(){var i=e(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(t-=i.outerHeight(!0))}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n[0]===s[0],o=a&&i.collapsible,r=o?e():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:o?e():n,newPanel:r};t.preventDefault(),a&&!i.collapsible||this._trigger("beforeActivate",t,l)===!1||(i.active=o?!1:this.headers.index(n),this.active=a?e():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),a||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,s=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,t):(s.hide(),i.show(),this._toggleComplete(t)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(e(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(e,t,i){var s,n,a,o=this,r=0,h=e.length&&(!t.length||e.index()<t.index()),l=this.options.animate||{},u=h&&l.down||l,d=function(){o._toggleComplete(i)};return"number"==typeof u&&(a=u),"string"==typeof u&&(n=u),n=n||u.easing||l.easing,a=a||u.duration||l.duration,t.length?e.length?(s=e.show().outerHeight(),t.animate(this.hideProps,{duration:a,easing:n,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(this.showProps,{duration:a,easing:n,complete:d,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?r+=i.now:"content"!==o.options.heightStyle&&(i.now=Math.round(s-t.outerHeight()-r),r=0)}}),void 0):t.animate(this.hideProps,a,n,d):e.animate(this.showProps,a,n,d)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.widget("ui.menu",{version:"1.11.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(e){e.preventDefault()},"click .ui-menu-item":function(t){var i=e(t.target);!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&e(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){if(!this.previousFilter){var i=e(t.currentTarget);i.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(t,i)
+}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.find(this.options.items).eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){this._closeOnDocumentClick(e)&&this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){var i,s,n,a,o=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:o=!1,s=this.previousFilter||"",n=String.fromCharCode(t.keyCode),a=!1,clearTimeout(this.filterTimer),n===s?a=!0:n=s+n,i=this._filterMenuItems(n),i=a&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(t.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(t,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}o&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(e):this.select(e))},refresh:function(){var t,i,s=this,n=this.options.icons.submenu,a=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),a.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),i=t.parent(),s=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);i.attr("aria-haspopup","true").prepend(s),t.attr("aria-labelledby",i.attr("id"))}),t=a.add(this.element),i=t.find(this.options.items),i.not(".ui-menu-item").each(function(){var t=e(this);s._isDivider(t)&&t.addClass("ui-widget-content ui-menu-divider")}),i.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){"icons"===e&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},focus:function(e,t){var i,s;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&e&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,n=t.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=t.outerHeight(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active}))},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(t){return!e(t.target).closest(".ui-menu").length},_isDivider:function(e){return!/[^\-\u2014\u2013\s]/.test(e.text())},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[t]()),this.focus(i,s)},nextPage:function(t){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-n}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(t),void 0)},previousPage:function(t){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+n>0}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items).first())),void 0):(this.next(t),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,i)},_filterMenuItems:function(t){var i=t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(e.trim(e(this).text()))})}}),e.widget("ui.autocomplete",{version:"1.11.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,void 0;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),void 0):(this._searchTimeout(e),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(e),this._change(e),void 0)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:n})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&e.trim(s).length&&(this.liveRegion.children().hide(),e("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,n){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){n(e)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),i=this.menu.element.is(":visible"),s=e.altKey||e.ctrlKey||e.metaKey||e.shiftKey;(!t||t&&!i&&!s)&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):void 0},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var t=++this.requestIndex;return e.proxy(function(e){t===this.requestIndex&&this.__response(e),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").text(i.label).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[e](t),void 0):(this.search(null,t),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.children().hide(),e("<div>").text(i).appendTo(this.liveRegion))}}),e.ui.autocomplete;var c,p="ui-button ui-widget ui-state-default ui-corner-all",f="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",m=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},g=function(t){var i=t.name,s=t.form,n=e([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?e(s).find("[name='"+i+"'][type=radio]"):e("[name='"+i+"'][type=radio]",t.ownerDocument).filter(function(){return!this.form})),n};e.widget("ui.button",{version:"1.11.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,m),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,i=this.options,s="checkbox"===this.type||"radio"===this.type,n=s?"":"ui-state-active";null===i.label&&(i.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(p).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){i.disabled||this===c&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){i.disabled||e(this).removeClass(n)}).bind("click"+this.eventNamespace,function(e){i.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),s&&this.element.bind("change"+this.eventNamespace,function(){t.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return i.disabled?!1:void 0}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(i.disabled)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var s=t.element[0];g(s).not(s).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return i.disabled?!1:(e(this).addClass("ui-state-active"),c=this,t.document.one("mouseup",function(){c=null}),void 0)}).bind("mouseup"+this.eventNamespace,function(){return i.disabled?!1:(e(this).removeClass("ui-state-active"),void 0)}).bind("keydown"+this.eventNamespace,function(t){return i.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),void 0)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",i.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(p+" ui-state-active "+f).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),t&&("checkbox"===this.type||"radio"===this.type?this.buttonElement.removeClass("ui-state-focus"):this.buttonElement.removeClass("ui-state-focus ui-state-active")),void 0):(this._resetButton(),void 0)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?g(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),void 0;var t=this.buttonElement.removeClass(f),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,a=[];s.primary||s.secondary?(this.options.text&&a.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(a.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):a.push("ui-button-text-only"),t.addClass(a.join(" "))}}),e.widget("ui.buttonset",{version:"1.11.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction"),i=this.element.find(this.options.items),s=i.filter(":ui-button");i.not(":ui-button").button(),s.button("refresh"),this.buttons=i.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}}),e.ui.button,e.extend(e.ui,{datepicker:{version:"1.11.3"}});var v;e.extend(n.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return r(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var s,n,a;s=t.nodeName.toLowerCase(),n="div"===s||"span"===s,t.id||(this.uuid+=1,t.id="dp"+this.uuid),a=this._newInst(e(t),n),a.settings=e.extend({},i||{}),"input"===s?this._connectDatepicker(t,a):n&&this._inlineDatepicker(t,a)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?a(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var s=e(t);i.append=e([]),i.trigger=e([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,"datepicker",i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var s,n,a,o=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),o&&(i.append=e("<span class='"+this._appendClass+"'>"+o+"</span>"),t[r?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&t.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),a=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:a,alt:n,title:n}):e("<button type='button'></button>").addClass(this._triggerClass).html(a?e("<img/>").attr({src:a,alt:n,title:n}):n)),t[r?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,s,n,a=new Date(2009,11,20),o=this._get(e,"dateFormat");o.match(/[DM]/)&&(t=function(e){for(i=0,s=0,n=0;e.length>n;n++)e[n].length>i&&(i=e[n].length,s=n);return s},a.setMonth(t(this._get(e,o.match(/MM/)?"monthNames":"monthNamesShort"))),a.setDate(t(this._get(e,o.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())),e.input.attr("size",this._formatDate(e,a).length)}},_inlineDatepicker:function(t,i){var s=e(t);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),e.data(t,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,s,n,a){var o,h,l,u,d,c=this._dialogInst;return c||(this.uuid+=1,o="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+o+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),c=this._dialogInst=this._newInst(this._dialogInput,!1),c.settings={},e.data(this._dialogInput[0],"datepicker",c)),r(c.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(c,i):i,this._dialogInput.val(i),this._pos=a?a.length?a:[a.pageX,a.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+u,l/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),c.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],"datepicker",c),this},_destroyDatepicker:function(t){var i,s=e(t),n=e.data(t,"datepicker");s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),v===n&&(v=null))},_enableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,a.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,s,n=e(t),a=e.data(t,"datepicker");n.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,a.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(t,i,s){var n,a,o,h,l=this._getInst(t);return 2===arguments.length&&"string"==typeof i?"defaults"===i?e.extend({},e.datepicker._defaults):l?"all"===i?e.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),a=this._getDateDatepicker(t,!0),o=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),r(l.settings,n),null!==o&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,o)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(t):this._enableDatepicker(t)),this._attachments(e(t),l),this._autoSize(l),this._setDate(l,a),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,s,n,a=e.datepicker._getInst(t.target),o=!0,r=a.dpDiv.is(".ui-datepicker-rtl");if(a._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),o=!1;break;case 13:return n=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",a.dpDiv),n[0]&&e.datepicker._selectDay(t.target,a.selectedMonth,a.selectedYear,n[0]),i=e.datepicker._get(a,"onSelect"),i?(s=e.datepicker._formatDate(a),i.apply(a.input?a.input[0]:null,[s,a])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),o=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),o=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?1:-1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(a,"stepBigMonths"):-e.datepicker._get(a,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),o=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,r?-1:1,"D"),o=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(a,"stepBigMonths"):+e.datepicker._get(a,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),o=t.ctrlKey||t.metaKey;break;default:o=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):o=!1;o&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(t){var i,s,n=e.datepicker._getInst(t.target);return e.datepicker._get(n,"constrainInput")?(i=e.datepicker._possibleChars(e.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==t.charCode?t.keyCode:t.charCode),t.ctrlKey||t.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0
+},_doKeyUp:function(t){var i,s=e.datepicker._getInst(t.target);if(s.input.val()!==s.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,e.datepicker._getFormatConfig(s)),i&&(e.datepicker._setDateFromField(s),e.datepicker._updateAlternate(s),e.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,n,a,o,h,l,u;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),n=e.datepicker._get(i,"beforeShow"),a=n?n.apply(t,[t,i]):{},a!==!1&&(r(i.settings,a),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),o=!1,e(t).parents().each(function(){return o|="fixed"===e(this).css("position"),!o}),h={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),h=e.datepicker._checkOffset(i,h,o),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":o?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),i.inline||(l=e.datepicker._get(i,"showAnim"),u=e.datepicker._get(i,"duration"),i.dpDiv.css("z-index",s(e(t))+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[l]?i.dpDiv.show(l,e.datepicker._get(i,"showOptions"),u):i.dpDiv[l||"show"](l?u:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,v=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t);var i,s=this._getNumberOfMonths(t),n=s[1],a=17,r=t.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&t.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),t.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,s){var n=t.dpDiv.outerWidth(),a=t.dpDiv.outerHeight(),o=t.input?t.input.outerWidth():0,r=t.input?t.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:e(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?n-o:0,i.left-=s&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=s&&i.top===t.input.offset().top+r?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+a>l&&l>a?Math.abs(a+r):0),i},_findPos:function(t){for(var i,s=this._getInst(t),n=this._get(s,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[n?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,s,n,a,o=this._curInst;!o||t&&o!==e.data(t,"datepicker")||this._datepickerShowing&&(i=this._get(o,"showAnim"),s=this._get(o,"duration"),n=function(){e.datepicker._tidyDialog(o)},e.effects&&(e.effects.effect[i]||e.effects[i])?o.dpDiv.hide(i,e.datepicker._get(o,"showOptions"),s,n):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,a=this._get(o,"onClose"),a&&a.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),s=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==s)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,s){var n=e(t),a=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(a,i+("M"===s?this._get(a,"showCurrentAtPos"):0),s),this._updateDatepicker(a))},_gotoToday:function(t){var i,s=e(t),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(t,i,s){var n=e(t),a=this._getInst(n[0]);a["selected"+("M"===s?"Month":"Year")]=a["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(a),this._adjustDate(n)},_selectDay:function(t,i,s,n){var a,o=e(t);e(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0])||(a=this._getInst(o[0]),a.selectedDay=a.currentDay=e("a",n).html(),a.selectedMonth=a.currentMonth=i,a.selectedYear=a.currentYear=s,this._selectDate(t,this._formatDate(a,a.currentDay,a.currentMonth,a.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var s,n=e(t),a=this._getInst(n[0]);i=null!=i?i:this._formatDate(a),a.input&&a.input.val(i),this._updateAlternate(a),s=this._get(a,"onSelect"),s?s.apply(a.input?a.input[0]:null,[i,a]):a.input&&a.input.trigger("change"),a.inline?this._updateDatepicker(a):(this._hideDatepicker(),this._lastInput=a.input[0],"object"!=typeof a.input[0]&&a.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,s,n,a=this._get(t,"altField");a&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),s=this._getDate(t),n=this.formatDate(i,s,this._getFormatConfig(t)),e(a).each(function(){e(this).val(n)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(t,i,s){if(null==t||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,a,o,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),d=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,c=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,m=-1,g=-1,v=-1,y=-1,b=!1,_=function(e){var i=t.length>n+1&&t.charAt(n+1)===e;return i&&n++,i},x=function(e){var t=_(e),s="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,n="y"===e?s:1,a=RegExp("^\\d{"+n+","+s+"}"),o=i.substring(h).match(a);if(!o)throw"Missing number at position "+h;return h+=o[0].length,parseInt(o[0],10)},w=function(t,s,n){var a=-1,o=e.map(_(t)?n:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(o,function(e,t){var s=t[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(a=t[0],h+=s.length,!1):void 0}),-1!==a)return a+1;throw"Unknown name at position "+h},k=function(){if(i.charAt(h)!==t.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;t.length>n;n++)if(b)"'"!==t.charAt(n)||_("'")?k():b=!1;else switch(t.charAt(n)){case"d":v=x("d");break;case"D":w("D",d,c);break;case"o":y=x("o");break;case"m":g=x("m");break;case"M":g=w("M",p,f);break;case"y":m=x("y");break;case"@":r=new Date(x("@")),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"!":r=new Date((x("!")-this._ticksTo1970)/1e4),m=r.getFullYear(),g=r.getMonth()+1,v=r.getDate();break;case"'":_("'")?k():b=!0;break;default:k()}if(i.length>h&&(o=i.substr(h),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),y>-1)for(g=1,v=y;;){if(a=this._getDaysInMonth(m,g-1),a>=v)break;g++,v-=a}if(r=this._daylightSavingAdjust(new Date(m,g-1,v)),r.getFullYear()!==m||r.getMonth()+1!==g||r.getDate()!==v)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,a=(i?i.dayNames:null)||this._defaults.dayNames,o=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(t){var i=e.length>s+1&&e.charAt(s+1)===t;return i&&s++,i},l=function(e,t,i){var s=""+t;if(h(e))for(;i>s.length;)s="0"+s;return s},u=function(e,t,i,s){return h(e)?s[t]:i[t]},d="",c=!1;if(t)for(s=0;e.length>s;s++)if(c)"'"!==e.charAt(s)||h("'")?d+=e.charAt(s):c=!1;else switch(e.charAt(s)){case"d":d+=l("d",t.getDate(),2);break;case"D":d+=u("D",t.getDay(),n,a);break;case"o":d+=l("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":d+=l("m",t.getMonth()+1,2);break;case"M":d+=u("M",t.getMonth(),o,r);break;case"y":d+=h("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":d+=t.getTime();break;case"!":d+=1e4*t.getTime()+this._ticksTo1970;break;case"'":h("'")?d+="'":c=!0;break;default:d+=e.charAt(s)}return d},_possibleChars:function(e){var t,i="",s=!1,n=function(i){var s=e.length>t+1&&e.charAt(t+1)===i;return s&&t++,s};for(t=0;e.length>t;t++)if(s)"'"!==e.charAt(t)||n("'")?i+=e.charAt(t):s=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,t){return void 0!==e.settings[t]?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),s=e.lastVal=e.input?e.input.val():null,n=this._getDefaultDate(e),a=n,o=this._getFormatConfig(e);try{a=this.parseDate(i,s,o)||n}catch(r){s=t?"":s}e.selectedDay=a.getDate(),e.drawMonth=e.selectedMonth=a.getMonth(),e.drawYear=e.selectedYear=a.getFullYear(),e.currentDay=s?a.getDate():0,e.currentMonth=s?a.getMonth():0,e.currentYear=s?a.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,s){var n=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},a=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,a=n.getFullYear(),o=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":o+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o));break;case"y":case"Y":a+=parseInt(l[1],10),r=Math.min(r,e.datepicker._getDaysInMonth(a,o))}l=h.exec(i)}return new Date(a,o,r)},o=null==i||""===i?s:"string"==typeof i?a(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return o=o&&"Invalid Date"==""+o?s:o,o&&(o.setHours(0),o.setMinutes(0),o.setSeconds(0),o.setMilliseconds(0)),this._daylightSavingAdjust(o)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var s=!t,n=e.selectedMonth,a=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),n===e.selectedMonth&&a===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(s?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),s="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(s,-i,"M")},next:function(){e.datepicker._adjustDate(s,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(s)},selectDay:function(){return e.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(s,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,s,n,a,o,r,h,l,u,d,c,p,f,m,g,v,y,b,_,x,w,k,T,D,S,M,C,N,A,I,P,z,H,F,E,O,j,W,L=new Date,R=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(e,"isRTL"),B=this._get(e,"showButtonPanel"),J=this._get(e,"hideIfNoPrevNext"),q=this._get(e,"navigationAsDateFormat"),K=this._getNumberOfMonths(e),V=this._get(e,"showCurrentAtPos"),U=this._get(e,"stepMonths"),Q=1!==K[0]||1!==K[1],G=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),X=this._getMinMaxDate(e,"min"),$=this._getMinMaxDate(e,"max"),Z=e.drawMonth-V,et=e.drawYear;if(0>Z&&(Z+=12,et--),$)for(t=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-K[0]*K[1]+1,$.getDate())),t=X&&X>t?X:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=q?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-U,1)),this._getFormatConfig(e)):i,s=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":J?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(e,"nextText"),n=q?this.formatDate(n,this._daylightSavingAdjust(new Date(et,Z+U,1)),this._getFormatConfig(e)):n,a=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":J?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",o=this._get(e,"currentText"),r=this._get(e,"gotoCurrent")&&e.currentDay?G:R,o=q?this.formatDate(o,r,this._getFormatConfig(e)):o,h=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(e,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+o+"</button>":"")+(Y?"":h)+"</div>":"",u=parseInt(this._get(e,"firstDay"),10),u=isNaN(u)?0:u,d=this._get(e,"showWeek"),c=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),f=this._get(e,"monthNames"),m=this._get(e,"monthNamesShort"),g=this._get(e,"beforeShowDay"),v=this._get(e,"showOtherMonths"),y=this._get(e,"selectOtherMonths"),b=this._getDefaultDate(e),_="",w=0;K[0]>w;w++){for(k="",this.maxRows=4,T=0;K[1]>T;T++){if(D=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),S=" ui-corner-all",M="",Q){if(M+="<div class='ui-datepicker-group",K[1]>1)switch(T){case 0:M+=" ui-datepicker-group-first",S=" ui-corner-"+(Y?"right":"left");break;case K[1]-1:M+=" ui-datepicker-group-last",S=" ui-corner-"+(Y?"left":"right");break;default:M+=" ui-datepicker-group-middle",S=""}M+="'>"}for(M+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+S+"'>"+(/all|left/.test(S)&&0===w?Y?a:s:"")+(/all|right/.test(S)&&0===w?Y?s:a:"")+this._generateMonthYearHeader(e,Z,et,X,$,w>0||T>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",C=d?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",x=0;7>x;x++)N=(x+u)%7,C+="<th scope='col'"+((x+u+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+c[N]+"'>"+p[N]+"</span></th>";for(M+=C+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),I=(this._getFirstDayOfMonth(et,Z)-u+7)%7,P=Math.ceil((I+A)/7),z=Q?this.maxRows>P?this.maxRows:P:P,this.maxRows=z,H=this._daylightSavingAdjust(new Date(et,Z,1-I)),F=0;z>F;F++){for(M+="<tr>",E=d?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(H)+"</td>":"",x=0;7>x;x++)O=g?g.apply(e.input?e.input[0]:null,[H]):[!0,""],j=H.getMonth()!==Z,W=j&&!y||!O[0]||X&&X>H||$&&H>$,E+="<td class='"+((x+u+6)%7>=5?" ui-datepicker-week-end":"")+(j?" ui-datepicker-other-month":"")+(H.getTime()===D.getTime()&&Z===e.selectedMonth&&e._keyEvent||b.getTime()===H.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(W?" "+this._unselectableClass+" ui-state-disabled":"")+(j&&!v?"":" "+O[1]+(H.getTime()===G.getTime()?" "+this._currentClass:"")+(H.getTime()===R.getTime()?" ui-datepicker-today":""))+"'"+(j&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(W?"":" data-handler='selectDay' data-event='click' data-month='"+H.getMonth()+"' data-year='"+H.getFullYear()+"'")+">"+(j&&!v?"&#xa0;":W?"<span class='ui-state-default'>"+H.getDate()+"</span>":"<a class='ui-state-default"+(H.getTime()===R.getTime()?" ui-state-highlight":"")+(H.getTime()===G.getTime()?" ui-state-active":"")+(j?" ui-priority-secondary":"")+"' href='#'>"+H.getDate()+"</a>")+"</td>",H.setDate(H.getDate()+1),H=this._daylightSavingAdjust(H);M+=E+"</tr>"}Z++,Z>11&&(Z=0,et++),M+="</tbody></table>"+(Q?"</div>"+(K[0]>0&&T===K[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),k+=M}_+=k}return _+=l,e._keyEvent=!1,_},_generateMonthYearHeader:function(e,t,i,s,n,a,o,r){var h,l,u,d,c,p,f,m,g=this._get(e,"changeMonth"),v=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",_="";if(a||!g)_+="<span class='ui-datepicker-month'>"+o[t]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,_+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",u=0;12>u;u++)(!h||u>=s.getMonth())&&(!l||n.getMonth()>=u)&&(_+="<option value='"+u+"'"+(u===t?" selected='selected'":"")+">"+r[u]+"</option>");_+="</select>"}if(y||(b+=_+(!a&&g&&v?"":"&#xa0;")),!e.yearshtml)if(e.yearshtml="",a||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(d=this._get(e,"yearRange").split(":"),c=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?c+parseInt(e,10):parseInt(e,10);return isNaN(t)?c:t},f=p(d[0]),m=Math.max(f,p(d[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=n?Math.min(m,n.getFullYear()):m,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)e.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";e.yearshtml+="</select>",b+=e.yearshtml,e.yearshtml=null}return b+=this._get(e,"yearSuffix"),y&&(b+=(!a&&g&&v?"":"&#xa0;")+_),b+="</div>"},_adjustInstDate:function(e,t,i){var s=e.drawYear+("Y"===i?t:0),n=e.drawMonth+("M"===i?t:0),a=Math.min(e.selectedDay,this._getDaysInMonth(s,n))+("D"===i?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(s,n,a)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),s=this._getMinMaxDate(e,"max"),n=i&&i>t?i:t;return s&&n>s?s:n},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,s){var n=this._getNumberOfMonths(e),a=this._daylightSavingAdjust(new Date(i,s+(0>t?t:n[0]*n[1]),1));return 0>t&&a.setDate(this._getDaysInMonth(a.getFullYear(),a.getMonth())),this._isInRange(e,a)},_isInRange:function(e,t){var i,s,n=this._getMinMaxDate(e,"min"),a=this._getMinMaxDate(e,"max"),o=null,r=null,h=this._get(e,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),o=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(o+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||t.getTime()>=n.getTime())&&(!a||t.getTime()<=a.getTime())&&(!o||t.getFullYear()>=o)&&(!r||r>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,s){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var n=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(s,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),n,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new n,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.11.3",e.datepicker,e.widget("ui.draggable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(t){var i=this.options;return this._blurActiveElement(t),this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=e(this);return e("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var i=this.document[0];if(this.handleElement.is(t.target))try{i.activeElement&&"body"!==i.activeElement.nodeName.toLowerCase()&&e(i.activeElement).blur()}catch(s){}},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===e(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._normalizeRightBottom(),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(e){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:e.pageX-this.offset.left,top:e.pageY-this.offset.top}},_mouseDrag:function(t,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper),n=s?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options,a=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,e(a).width()-this.helperProportions.width-this.margins.left,(e(a).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=e(n.containment),s=i[0],s&&(t=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)
+},_convertPositionTo:function(e,t){t||(t=this.position);var i="absolute"===e?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:t.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(e,t){var i,s,n,a,o=this.options,r=this._isRootNode(this.scrollParent[0]),h=e.pageX,l=e.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,h=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a),"y"===o.axis&&(h=this.originalPageX),"x"===o.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i,s){var n=e.extend({},i,{item:s.element});s.sortables=[],e(s.options.connectToSortable).each(function(){var i=e(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i,s){var n=e.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,e.each(s.sortables,function(){var e=this;e.isOver?(e.isOver=0,s.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,n))})},drag:function(t,i,s){e.each(s.sortables,function(){var n=!1,a=this;a.positionAbs=s.positionAbs,a.helperProportions=s.helperProportions,a.offset.click=s.offset.click,a._intersectsWith(a.containerCache)&&(n=!0,e.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==a&&this._intersectsWith(this.containerCache)&&e.contains(a.element[0],this.element[0])&&(n=!1),n})),n?(a.isOver||(a.isOver=1,a.currentItem=i.helper.appendTo(a.element).data("ui-sortable-item",!0),a.options._helper=a.options.helper,a.options.helper=function(){return i.helper[0]},t.target=a.currentItem[0],a._mouseCapture(t,!0),a._mouseStart(t,!0,!0),a.offset.click.top=s.offset.click.top,a.offset.click.left=s.offset.click.left,a.offset.parent.left-=s.offset.parent.left-a.offset.parent.left,a.offset.parent.top-=s.offset.parent.top-a.offset.parent.top,s._trigger("toSortable",t),s.dropped=a.element,e.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,a.fromOutside=s),a.currentItem&&(a._mouseDrag(t),i.position=a.position)):a.isOver&&(a.isOver=0,a.cancelHelperRemoval=!0,a.options._revert=a.options.revert,a.options.revert=!1,a._trigger("out",t,a._uiHash(a)),a._mouseStop(t,!0),a.options.revert=a.options._revert,a.options.helper=a.options._helper,a.placeholder&&a.placeholder.remove(),s._refreshOffsets(t),i.position=s._generatePosition(t,!0),s._trigger("fromSortable",t),s.dropped=!1,e.each(s.sortables,function(){this.refreshPositions()}))})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,i,s){var n=e("body"),a=s.options;n.css("cursor")&&(a._cursor=n.css("cursor")),n.css("cursor",a.cursor)},stop:function(t,i,s){var n=s.options;n._cursor&&e("body").css("cursor",n._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("opacity")&&(a._opacity=n.css("opacity")),n.css("opacity",a.opacity)},stop:function(t,i,s){var n=s.options;n._opacity&&e(i.helper).css("opacity",n._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,i,s){var n=s.options,a=!1,o=s.scrollParentNotHidden[0],r=s.document[0];o!==r&&"HTML"!==o.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+o.offsetHeight-t.pageY<n.scrollSensitivity?o.scrollTop=a=o.scrollTop+n.scrollSpeed:t.pageY-s.overflowOffset.top<n.scrollSensitivity&&(o.scrollTop=a=o.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+o.offsetWidth-t.pageX<n.scrollSensitivity?o.scrollLeft=a=o.scrollLeft+n.scrollSpeed:t.pageX-s.overflowOffset.left<n.scrollSensitivity&&(o.scrollLeft=a=o.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(t.pageY-e(r).scrollTop()<n.scrollSensitivity?a=e(r).scrollTop(e(r).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(r).scrollTop())<n.scrollSensitivity&&(a=e(r).scrollTop(e(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(t.pageX-e(r).scrollLeft()<n.scrollSensitivity?a=e(r).scrollLeft(e(r).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(r).scrollLeft())<n.scrollSensitivity&&(a=e(r).scrollLeft(e(r).scrollLeft()+n.scrollSpeed)))),a!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(s,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,i,s){var n=s.options;s.snapElements=[],e(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var t=e(this),i=t.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:i.top,left:i.left})})},drag:function(t,i,s){var n,a,o,r,h,l,u,d,c,p,f=s.options,m=f.snapTolerance,g=i.offset.left,v=g+s.helperProportions.width,y=i.offset.top,b=y+s.helperProportions.height;for(c=s.snapElements.length-1;c>=0;c--)h=s.snapElements[c].left-s.margins.left,l=h+s.snapElements[c].width,u=s.snapElements[c].top-s.margins.top,d=u+s.snapElements[c].height,h-m>v||g>l+m||u-m>b||y>d+m||!e.contains(s.snapElements[c].item.ownerDocument,s.snapElements[c].item)?(s.snapElements[c].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(n=m>=Math.abs(u-b),a=m>=Math.abs(d-y),o=m>=Math.abs(h-v),r=m>=Math.abs(l-g),n&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||a||o||r,"outer"!==f.snapMode&&(n=m>=Math.abs(u-y),a=m>=Math.abs(d-b),o=m>=Math.abs(h-g),r=m>=Math.abs(l-v),n&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d-s.helperProportions.height,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[c].snapping&&(n||a||o||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=n||a||o||r||p)}}),e.ui.plugin.add("draggable","stack",{start:function(t,i,s){var n,a=s.options,o=e.makeArray(e(a.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});o.length&&(n=parseInt(e(o[0]).css("zIndex"),10)||0,e(o).each(function(t){e(this).css("zIndex",n+t)}),this.css("zIndex",n+o.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("zIndex")&&(a._zIndex=n.css("zIndex")),n.css("zIndex",a.zIndex)},stop:function(t,i,s){var n=s.options;n._zIndex&&e(i.helper).css("zIndex",n._zIndex)}}),e.ui.draggable,e.widget("ui.resizable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(e){return parseInt(e,10)||0},_isNumber:function(e){return!isNaN(parseInt(e,10))},_hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return t[s]>0?!0:(t[s]=1,n=t[s]>0,t[s]=0,n)},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("<div class='ui-resizable-handle "+a+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=this.element.children(this.handles[i]).first().show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var i,s,n,a=this.options,o=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),a.containment&&(i+=e(a.containment).scrollLeft()||0,s+=e(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:o.width(),height:o.height()},this.originalSize=this._helper?{width:o.outerWidth(),height:o.outerHeight()}:{width:o.width(),height:o.height()},this.sizeDiff={width:o.outerWidth()-o.width(),height:o.outerHeight()-o.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===n?this.axis+"-resize":n),o.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var i,s,n=this.originalMousePosition,a=this.axis,o=t.pageX-n.left||0,r=t.pageY-n.top||0,h=this._change[a];return this._updatePrevProperties(),h?(i=h.apply(this,[t,o,r]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var e={};return this.position.top!==this.prevPosition.top&&(e.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(e.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(e.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(e.height=this.size.height+"px"),this.helper.css(e),e},_updateVirtualBoundaries:function(e){var t,i,s,n,a,o=this.options;a={minWidth:this._isNumber(o.minWidth)?o.minWidth:0,maxWidth:this._isNumber(o.maxWidth)?o.maxWidth:1/0,minHeight:this._isNumber(o.minHeight)?o.minHeight:0,maxHeight:this._isNumber(o.maxHeight)?o.maxHeight:1/0},(this._aspectRatio||e)&&(t=a.minHeight*this.aspectRatio,s=a.minWidth/this.aspectRatio,i=a.maxHeight*this.aspectRatio,n=a.maxWidth/this.aspectRatio,t>a.minWidth&&(a.minWidth=t),s>a.minHeight&&(a.minHeight=s),a.maxWidth>i&&(a.maxWidth=i),a.maxHeight>n&&(a.maxHeight=n)),this._vBoundaries=a},_updateCache:function(e){this.offset=this.helper.offset(),this._isNumber(e.left)&&(this.position.left=e.left),this._isNumber(e.top)&&(this.position.top=e.top),this._isNumber(e.height)&&(this.size.height=e.height),this._isNumber(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,i=this.size,s=this.axis;return this._isNumber(e.height)?e.width=e.height*this.aspectRatio:this._isNumber(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===s&&(e.left=t.left+(i.width-e.width),e.top=null),"nw"===s&&(e.top=t.top+(i.height-e.height),e.left=t.left+(i.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,i=this.axis,s=this._isNumber(e.width)&&t.maxWidth&&t.maxWidth<e.width,n=this._isNumber(e.height)&&t.maxHeight&&t.maxHeight<e.height,a=this._isNumber(e.width)&&t.minWidth&&t.minWidth>e.width,o=this._isNumber(e.height)&&t.minHeight&&t.minHeight>e.height,r=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,l=/sw|nw|w/.test(i),u=/nw|ne|n/.test(i);return a&&(e.width=t.minWidth),o&&(e.height=t.minHeight),s&&(e.width=t.maxWidth),n&&(e.height=t.maxHeight),a&&l&&(e.left=r-t.minWidth),s&&l&&(e.left=r-t.maxWidth),o&&u&&(e.top=h-t.minHeight),n&&u&&(e.top=h-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_getPaddingPlusBorderDimensions:function(e){for(var t=0,i=[],s=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],n=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];4>t;t++)i[t]=parseInt(s[t],10)||0,i[t]+=parseInt(n[t],10)||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e,t=0,i=this.helper||this.element;this._proportionallyResizeElements.length>t;t++)e=this._proportionallyResizeElements[t],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(e)),e.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,i,s,n,a,o,r,h=e(this).resizable("instance"),l=h.options,u=h.element,d=l.containment,c=d instanceof e?d.get(0):/parent/.test(d)?u.parent().get(0):d;c&&(h.containerElement=e(c),/document/.test(d)||d===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(c),i=[],e(["Top","Right","Left","Bottom"]).each(function(e,s){i[e]=h._num(t.css("padding"+s))}),h.containerOffset=t.offset(),h.containerPosition=t.position(),h.containerSize={height:t.innerHeight()-i[3],width:t.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,a=h.containerSize.width,o=h._hasScroll(c,"left")?c.scrollWidth:a,r=h._hasScroll(c)?c.scrollHeight:n,h.parentData={element:c,left:s.left,top:s.top,width:o,height:r}))},resize:function(t){var i,s,n,a,o=e(this).resizable("instance"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,d={top:0,left:0},c=o.containerElement,p=!0;c[0]!==document&&/static/.test(c.css("position"))&&(d=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-d.left),u&&(o.size.height=o.size.width/o.aspectRatio,p=!1),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio,p=!1),o.position.top=o._helper?h.top:0),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a?(o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top):(o.offset.left=o.element.offset().left,o.offset.top=o.element.offset().top),i=Math.abs(o.sizeDiff.width+(o._helper?o.offset.left-d.left:o.offset.left-h.left)),s=Math.abs(o.sizeDiff.height+(o._helper?o.offset.top-d.top:o.offset.top-h.top)),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio,p=!1)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio,p=!1)),p||(o.position.left=o.prevPosition.left,o.position.top=o.prevPosition.top,o.size.width=o.prevSize.width,o.size.height=o.prevSize.height)},stop:function(){var t=e(this).resizable("instance"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).resizable("instance"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(t,s){e(t).each(function(){var t=e(this),n=e(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var i=(n[t]||0)+(r[t]||0);i&&i>=0&&(a[t]=i||null)}),t.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):e.each(n.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t,i=e(this).resizable("instance"),s=i.options,n=i.size,a=i.originalSize,o=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,u=h[1]||1,d=Math.round((n.width-a.width)/l)*l,c=Math.round((n.height-a.height)/u)*u,p=a.width+d,f=a.height+c,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,v=s.minWidth&&s.minWidth>p,y=s.minHeight&&s.minHeight>f;s.grid=h,v&&(p+=l),y&&(f+=u),m&&(p-=l),g&&(f-=u),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=o.top-c):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=o.left-d):((0>=f-u||0>=p-l)&&(t=i._getPaddingPlusBorderDimensions(this)),f-u>0?(i.size.height=f,i.position.top=o.top-c):(f=u-t.height,i.size.height=f,i.position.top=o.top+a.height-f),p-l>0?(i.size.width=p,i.position.left=o.left-d):(p=l-t.width,i.size.width=p,i.position.left=o.left+a.width-p))}}),e.ui.resizable,e.widget("ui.dialog",{version:"1.11.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i,s=this;if(this._isOpen&&this._trigger("beforeClose",t)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&e(i).blur()}catch(n){}this._hide(this.uiDialog,this.options.hide,function(){s._trigger("close",t)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+e(this).css("z-index")}).get(),a=Math.max.apply(null,n);return a>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",a+1),s=!0),s&&!i&&this._trigger("focus",t),s},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var e=this._focusedElement;e||(e=this.element.find("[autofocus]")),e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),void 0;
+if(t.keyCode===e.ui.keyCode.TAB&&!t.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");t.target!==n[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==s[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){n.focus()}),t.preventDefault()):(this._delay(function(){s.focus()}),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html("&#160;"),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),void 0):(e.each(i,function(i,s){var n,a;s=e.isFunction(s)?{click:s,text:i}:s,s=e.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(t.element[0],arguments)},a={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,e("<button></button>",s).button(a).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,t(n))},drag:function(e,s){i._trigger("drag",e,t(s))},stop:function(n,a){var o=a.offset.left-i.document.scrollLeft(),r=a.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(o>=0?"+":"")+o+" "+"top"+(r>=0?"+":"")+r,of:i.window},e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,t(a))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,s=this.options,n=s.resizable,a=this.uiDialog.css("position"),o="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:o,start:function(s,n){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,t(n))},resize:function(e,s){i._trigger("resize",e,t(s))},stop:function(n,a){var o=i.uiDialog.offset(),r=o.left-i.document.scrollLeft(),h=o.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,t(a))}}).css("position",a)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=e(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),i=e.inArray(this,t);-1!==i&&t.splice(i,1)},_trackingInstances:function(){var e=this.document.data("ui-dialog-instances");return e||(e=[],this.document.data("ui-dialog-instances",e)),e},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};e.each(t,function(e,t){i._setOption(e,t),e in i.sizeRelatedOptions&&(s=!0),e in i.resizableRelatedOptions&&(n[e]=t)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,t){var i,s,n=this.uiDialog;"dialogClass"===e&&n.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=n.is(":data(ui-draggable)"),i&&!t&&n.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(s=n.is(":data(ui-resizable)"),s&&!t&&n.resizable("destroy"),s&&"string"==typeof t&&n.resizable("option","handles",t),s||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),e=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),t=Math.max(0,s.minHeight-e),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-e):"none","auto"===s.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=!0;this._delay(function(){t=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(e){t||this._allowInteraction(e)||(e.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var e=this.document.data("ui-dialog-overlays")-1;e?this.document.data("ui-dialog-overlays",e):this.document.unbind("focusin").removeData("ui-dialog-overlays"),this.overlay.remove(),this.overlay=null}}}),e.widget("ui.droppable",{version:"1.11.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(s)?s:function(e){return e.is(s)},this.proportions=function(){return arguments.length?(t=arguments[0],void 0):t?t:t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(t){e.ui.ddmanager.droppables[t]=e.ui.ddmanager.droppables[t]||[],e.ui.ddmanager.droppables[t].push(this)},_splice:function(e){for(var t=0;e.length>t;t++)e[t]===this&&e.splice(t,1)},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];this._splice(t),this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){if("accept"===t)this.accept=e.isFunction(i)?i:function(e){return e.is(i)};else if("scope"===t){var s=e.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(t,i)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=e(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(i,{offset:i.element.offset()}),i.options.tolerance,t)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(){function e(e,t,i){return e>=t&&t+i>e}return function(t,i,s,n){if(!i.offset)return!1;var a=(t.positionAbs||t.position.absolute).left+t.margins.left,o=(t.positionAbs||t.position.absolute).top+t.margins.top,r=a+t.helperProportions.width,h=o+t.helperProportions.height,l=i.offset.left,u=i.offset.top,d=l+i.proportions().width,c=u+i.proportions().height;switch(s){case"fit":return a>=l&&d>=r&&o>=u&&c>=h;case"intersect":return a+t.helperProportions.width/2>l&&d>r-t.helperProportions.width/2&&o+t.helperProportions.height/2>u&&c>h-t.helperProportions.height/2;case"pointer":return e(n.pageY,u,i.proportions().height)&&e(n.pageX,l,i.proportions().width);case"touch":return(o>=u&&c>=o||h>=u&&c>=h||u>o&&h>c)&&(a>=l&&d>=a||r>=l&&d>=r||l>a&&r>d);default:return!1}}}(),e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,n,a=e.ui.ddmanager.droppables[t.options.scope]||[],o=i?i.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||t&&!a[s].accept.call(a[s].element[0],t.currentItem||t.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions().height=0;continue e}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions({width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight}))}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=e.ui.intersect(t,this,this.options.tolerance,i),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return e(this).droppable("instance").options.scope===n}),a.length&&(s=e(a[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}},e.ui.droppable;var y="ui-effects-",b=e;e.effects={effect:{}},function(e,t){function i(e,t,i){var s=d[t.type]||{};return null==e?i||!t.def?null:t.def:(e=s.floor?~~e:parseFloat(e),isNaN(e)?t.def:s.mod?(e+s.mod)%s.mod:0>e?0:e>s.max?s.max:e)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(e,a){var o,r=a.re.exec(i),h=r&&a.parse(r),l=a.space||"rgba";return h?(o=s[l](h),s[u[l].cache]=o[u[l].cache],n=s._rgba=o._rgba,!1):t}),n.length?("0,0,0,0"===n.join()&&e.extend(n,a.transparent),s):a[i]}function n(e,t,i){return i=(i+1)%1,1>6*i?e+6*(t-e)*i:1>2*i?t:2>3*i?e+6*(t-e)*(2/3-i):e}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[2.55*e[1],2.55*e[2],2.55*e[3],e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],l=e.Color=function(t,i,s,n){return new e.Color.fn.parse(t,i,s,n)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},d={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},c=l.support={},p=e("<p>")[0],f=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",c.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(n,o,r,h){if(n===t)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=e(n).css(o),o=t);var d=this,c=e.type(n),p=this._rgba=[];return o!==t&&(n=[n,o,r,h],c="array"),"string"===c?this.parse(s(n)||a._default):"array"===c?(f(u.rgba.props,function(e,t){p[t.idx]=i(n[t.idx],t)}),this):"object"===c?(n instanceof l?f(u,function(e,t){n[t.cache]&&(d[t.cache]=n[t.cache].slice())}):f(u,function(t,s){var a=s.cache;f(s.props,function(e,t){if(!d[a]&&s.to){if("alpha"===e||null==n[e])return;d[a]=s.to(d._rgba)}d[a][t.idx]=i(n[e],t,!0)}),d[a]&&0>e.inArray(null,d[a].slice(0,3))&&(d[a][3]=1,s.from&&(d._rgba=s.from(d[a])))}),this):t},is:function(e){var i=l(e),s=!0,n=this;return f(u,function(e,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(e,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:t})),s}),s},_space:function(){var e=[],t=this;return f(u,function(i,s){t[s.cache]&&e.push(i)}),e.pop()},transition:function(e,t){var s=l(e),n=s._space(),a=u[n],o=0===this.alpha()?l("transparent"):this,r=o[a.cache]||a.to(o._rgba),h=r.slice();return s=s[a.cache],f(a.props,function(e,n){var a=n.idx,o=r[a],l=s[a],u=d[n.type]||{};null!==l&&(null===o?h[a]=l:(u.mod&&(l-o>u.mod/2?o+=u.mod:o-l>u.mod/2&&(o-=u.mod)),h[a]=i((l-o)*t+o,n)))}),this[n](h)},blend:function(t){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(t)._rgba;return l(e.map(i,function(e,t){return(1-s)*n[t]+s*e}))},toRgbaString:function(){var t="rgba(",i=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===i[3]&&(i.pop(),t="rgb("),t+i.join()+")"},toHslaString:function(){var t="hsla(",i=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&3>t&&(e=Math.round(100*e)+"%"),e});return 1===i[3]&&(i.pop(),t="hsl("),t+i.join()+")"},toHexString:function(t){var i=this._rgba.slice(),s=i.pop();return t&&i.push(~~(255*s)),"#"+e.map(i,function(e){return e=(e||0).toString(16),1===e.length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,i,s=e[0]/255,n=e[1]/255,a=e[2]/255,o=e[3],r=Math.max(s,n,a),h=Math.min(s,n,a),l=r-h,u=r+h,d=.5*u;return t=h===r?0:s===r?60*(n-a)/l+360:n===r?60*(a-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=d?l/u:l/(2-u),[Math.round(t)%360,i,d,null==o?1:o]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,i=e[1],s=e[2],a=e[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,t+1/3)),Math.round(255*n(r,o,t)),Math.round(255*n(r,o,t-1/3)),a]},f(u,function(s,n){var a=n.props,o=n.cache,h=n.to,u=n.from;l.fn[s]=function(s){if(h&&!this[o]&&(this[o]=h(this._rgba)),s===t)return this[o].slice();var n,r=e.type(s),d="array"===r||"object"===r?s:arguments,c=this[o].slice();return f(a,function(e,t){var s=d["object"===r?e:t.idx];null==s&&(s=c[t.idx]),c[t.idx]=i(s,t)}),u?(n=l(u(c)),n[o]=c,n):l(c)},f(a,function(t,i){l.fn[t]||(l.fn[t]=function(n){var a,o=e.type(n),h="alpha"===t?this._hsla?"hsla":"rgba":s,l=this[h](),u=l[i.idx];return"undefined"===o?u:("function"===o&&(n=n.call(this,u),o=e.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=u+parseFloat(a[2])*("+"===a[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(t){var i=t.split(" ");f(i,function(t,i){e.cssHooks[i]={set:function(t,n){var a,o,r="";if("transparent"!==n&&("string"!==e.type(n)||(a=s(n)))){if(n=l(a||n),!c.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?t.parentNode:t;(""===r||"transparent"===r)&&o&&o.style;)try{r=e.css(o,"backgroundColor"),o=o.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{t.style[i]=n}catch(h){}}},e.fx.step[i]=function(t){t.colorInit||(t.start=l(t.elem,i),t.end=l(t.end),t.colorInit=!0),e.cssHooks[i].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook(o),e.cssHooks.borderColor={expand:function(e){var t={};return f(["Top","Right","Bottom","Left"],function(i,s){t["border"+s+"Color"]=e}),t}},a=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(b),function(){function t(t){var i,s,n=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[e.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function i(t,i){var s,a,o={};for(s in i)a=i[s],t[s]!==a&&(n[s]||(e.fx.step[s]||!isNaN(parseFloat(a)))&&(o[s]=a));return o}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,i){e.fx.step[i]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(b.style(e.elem,i,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(n,a,o,r){var h=e.speed(a,o,r);return this.queue(function(){var a,o=e(this),r=o.attr("class")||"",l=h.children?o.find("*").addBack():o;l=l.map(function(){var i=e(this);return{el:i,start:t(this)}}),a=function(){e.each(s,function(e,t){n[t]&&o[t+"Class"](n[t])})},a(),l=l.map(function(){return this.end=t(this.el[0]),this.diff=i(this.start,this.end),this}),o.attr("class",r),l=l.map(function(){var t=this,i=e.Deferred(),s=e.extend({},h,{queue:!1,complete:function(){i.resolve(t)}});return this.el.animate(this.diff,s),i.promise()}),e.when.apply(e,l.get()).done(function(){a(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),h.complete.call(o[0])})})},e.fn.extend({addClass:function(t){return function(i,s,n,a){return s?e.effects.animateClass.call(this,{add:i},s,n,a):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(i,s,n,a){return arguments.length>1?e.effects.animateClass.call(this,{remove:i},s,n,a):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(t){return function(i,s,n,a,o){return"boolean"==typeof s||void 0===s?n?e.effects.animateClass.call(this,s?{add:i}:{remove:i},n,a,o):t.apply(this,arguments):e.effects.animateClass.call(this,{toggle:i},s,n,a)}}(e.fn.toggleClass),switchClass:function(t,i,s,n,a){return e.effects.animateClass.call(this,{add:i,remove:t},s,n,a)}})}(),function(){function t(t,i,s,n){return e.isPlainObject(t)&&(i=t,t=t.effect),t={effect:t},null==i&&(i={}),e.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||e.fx.speeds[i])&&(n=s,s=i,i={}),e.isFunction(s)&&(n=s,s=null),i&&e.extend(t,i),s=s||i.duration,t.duration=e.fx.off?0:"number"==typeof s?s:s in e.fx.speeds?e.fx.speeds[s]:e.fx.speeds._default,t.complete=n||i.complete,t}function i(t){return!t||"number"==typeof t||e.fx.speeds[t]?!0:"string"!=typeof t||e.effects.effect[t]?e.isFunction(t)?!0:"object"!=typeof t||t.effect?!1:!0:!0}e.extend(e.effects,{version:"1.11.3",save:function(e,t){for(var i=0;t.length>i;i++)null!==t[i]&&e.data(y+t[i],e[0].style[t[i]])},restore:function(e,t){var i,s;for(s=0;t.length>s;s++)null!==t[s]&&(i=e.data(y+t[s]),void 0===i&&(i=""),e.css(t[s],i))},setMode:function(e,t){return"toggle"===t&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var i,s;switch(e[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=e[0]/t.height}switch(e[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=e[1]/t.width}return{x:s,y:i}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var i={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},s=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:t.width(),height:t.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return t.wrap(s),(t[0]===a||e.contains(t[0],a))&&e(a).focus(),s=t.parent(),"static"===t.css("position")?(s.css({position:"relative"}),t.css({position:"relative"})):(e.extend(i,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,s){i[s]=t.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(n),s.css(i).show()},removeWrapper:function(t){var i=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===i||e.contains(t[0],i))&&e(i).focus()),t},setTransition:function(t,i,s,n){return n=n||{},e.each(i,function(e,i){var a=t.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),e.fn.extend({effect:function(){function i(t){function i(){e.isFunction(a)&&a.call(n[0]),e.isFunction(t)&&t()}var n=e(this),a=s.complete,r=s.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),i()):o.call(n[0],s,i)}var s=t.apply(this,arguments),n=s.mode,a=s.queue,o=e.effects.effect[s.effect];return e.fx.off||!o?n?this[n](s.duration,s.complete):this.each(function(){s.complete&&s.complete.call(this)}):a===!1?this.each(i):this.queue(a||"fx",i)},show:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(e.fn.show),hide:function(e){return function(s){if(i(s))return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(e.fn.hide),toggle:function(e){return function(s){if(i(s)||"boolean"==typeof s)return e.apply(this,arguments);var n=t.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(e.fn.toggle),cssUnit:function(t){var i=this.css(t),s=[];return e.each(["em","px","%","pt"],function(e,t){i.indexOf(t)>0&&(s=[parseFloat(i),t])}),s}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,i){t[i]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,i=4;((t=Math.pow(2,--i))-1)/11>e;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,i){e.easing["easeIn"+t]=i,e.easing["easeOut"+t]=function(e){return 1-i(1-e)},e.easing["easeInOut"+t]=function(e){return.5>e?i(2*e)/2:1-i(-2*e+2)/2}})}(),e.effects,e.effects.effect.blind=function(t,i){var s,n,a,o=e(this),r=/up|down|vertical/,h=/up|left|vertical|horizontal/,l=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(o,t.mode||"hide"),d=t.direction||"up",c=r.test(d),p=c?"height":"width",f=c?"top":"left",m=h.test(d),g={},v="show"===u;o.parent().is(".ui-effects-wrapper")?e.effects.save(o.parent(),l):e.effects.save(o,l),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n=s[p](),a=parseFloat(s.css(f))||0,g[p]=v?n:0,m||(o.css(c?"bottom":"right",0).css(c?"top":"left","auto").css({position:"absolute"}),g[f]=v?a:n+a),v&&(s.css(p,0),m||s.css(f,a+n)),s.animate(g,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){"hide"===u&&o.hide(),e.effects.restore(o,l),e.effects.removeWrapper(o),i()}})},e.effects.effect.bounce=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"effect"),l="hide"===h,u="show"===h,d=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(u||l?1:0),m=t.duration/f,g=t.easing,v="up"===d||"down"===d?"top":"left",y="up"===d||"left"===d,b=o.queue(),_=b.length;for((u||l)&&r.push("opacity"),e.effects.save(o,r),o.show(),e.effects.createWrapper(o),c||(c=o["top"===v?"outerHeight":"outerWidth"]()/3),u&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,y?2*-c:2*c).animate(a,m,g)),l&&(c/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g).animate(a,m,g),c=l?2*c:c/2;l&&(n={opacity:0},n[v]=(y?"-=":"+=")+c,o.animate(n,m,g)),o.queue(function(){l&&o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}),_>1&&b.splice.apply(b,[1,0].concat(b.splice(_,f+1))),o.dequeue()},e.effects.effect.clip=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(o,t.mode||"hide"),l="show"===h,u=t.direction||"vertical",d="vertical"===u,c=d?"height":"width",p=d?"top":"left",f={};e.effects.save(o,r),o.show(),s=e.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[c](),l&&(n.css(c,0),n.css(p,a/2)),f[c]=l?a:0,f[p]=l?0:a/2,n.animate(f,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){l||o.hide(),e.effects.restore(o,r),e.effects.removeWrapper(o),i()}})},e.effects.effect.drop=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","opacity","height","width"],o=e.effects.setMode(n,t.mode||"hide"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h?"pos":"neg",d={opacity:r?1:0};e.effects.save(n,a),n.show(),e.effects.createWrapper(n),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===u?-s:s),d[l]=(r?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.explode=function(t,i){function s(){b.push(this),b.length===d*c&&n()}function n(){p.css({visibility:"visible"}),e(b).remove(),m||p.hide(),i()}var a,o,r,h,l,u,d=t.pieces?Math.round(Math.sqrt(t.pieces)):3,c=d,p=e(this),f=e.effects.setMode(p,t.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/c),y=Math.ceil(p.outerHeight()/d),b=[];for(a=0;d>a;a++)for(h=g.top+a*y,u=a-(d-1)/2,o=0;c>o;o++)r=g.left+o*v,l=o-(c-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*y}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:y,left:r+(m?l*v:0),top:h+(m?u*y:0),opacity:m?0:1}).animate({left:r+(m?0:l*v),top:h+(m?0:u*y),opacity:m?1:0},t.duration||500,t.easing,s)},e.effects.effect.fade=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:t.duration,easing:t.easing,complete:i})},e.effects.effect.fold=function(t,i){var s,n,a=e(this),o=["position","top","bottom","left","right","height","width"],r=e.effects.setMode(a,t.mode||"hide"),h="show"===r,l="hide"===r,u=t.size||15,d=/([0-9]+)%/.exec(u),c=!!t.horizFirst,p=h!==c,f=p?["width","height"]:["height","width"],m=t.duration/2,g={},v={};e.effects.save(a,o),a.show(),s=e.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],d&&(u=parseInt(d[1],10)/100*n[l?0:1]),h&&s.css(c?{height:0,width:u}:{height:u,width:0}),g[f[0]]=h?n[0]:u,v[f[1]]=h?n[1]:0,s.animate(g,m,t.easing).animate(v,m,t.easing,function(){l&&a.hide(),e.effects.restore(a,o),e.effects.removeWrapper(a),i()})},e.effects.effect.highlight=function(t,i){var s=e(this),n=["backgroundImage","backgroundColor","opacity"],a=e.effects.setMode(s,t.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),e.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===a&&s.hide(),e.effects.restore(s,n),i()}})},e.effects.effect.size=function(t,i){var s,n,a,o=e(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],u=["fontSize"],d=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],c=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),f=t.restore||"effect"!==p,m=t.scale||"both",g=t.origin||["middle","center"],v=o.css("position"),y=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===t.mode&&"show"===p?(o.from=t.to||b,o.to=t.from||s):(o.from=t.from||("show"===p?b:s),o.to=t.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===m||"both"===m)&&(a.from.y!==a.to.y&&(y=y.concat(d),o.from=e.effects.setTransition(o,d,a.from.y,o.from),o.to=e.effects.setTransition(o,d,a.to.y,o.to)),a.from.x!==a.to.x&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,a.from.x,o.from),o.to=e.effects.setTransition(o,c,a.to.x,o.to))),("content"===m||"both"===m)&&a.from.y!==a.to.y&&(y=y.concat(u).concat(l),o.from=e.effects.setTransition(o,u,a.from.y,o.from),o.to=e.effects.setTransition(o,u,a.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),g&&(n=e.effects.getBaseline(g,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===m||"both"===m)&&(d=d.concat(["marginTop","marginBottom"]).concat(u),c=c.concat(["marginLeft","marginRight"]),l=r.concat(d).concat(c),o.find("*[width]").each(function(){var i=e(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};
+f&&e.effects.save(i,l),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=e.effects.setTransition(i,d,a.from.y,i.from),i.to=e.effects.setTransition(i,d,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=e.effects.setTransition(i,c,a.from.x,i.from),i.to=e.effects.setTransition(i,c,a.to.x,i.to)),i.css(i.from),i.animate(i.to,t.duration,t.easing,function(){f&&e.effects.restore(i,l)})})),o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),e.effects.restore(o,y),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,i){var s=parseInt(i,10),n=e?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),e.effects.removeWrapper(o),i()}})},e.effects.effect.scale=function(t,i){var s=e(this),n=e.extend(!0,{},t),a=e.effects.setMode(s,t.mode||"effect"),o=parseInt(t.percent,10)||(0===parseInt(t.percent,10)?0:"hide"===a?0:100),r=t.direction||"both",h=t.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},u={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=h||["middle","center"],n.restore=!0),n.from=t.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*u.y,width:l.width*u.x,outerHeight:l.outerHeight*u.y,outerWidth:l.outerWidth*u.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},e.effects.effect.puff=function(t,i){var s=e(this),n=e.effects.setMode(s,t.mode||"hide"),a="hide"===n,o=parseInt(t.percent,10)||150,r=o/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(t)},e.effects.effect.pulsate=function(t,i){var s,n=e(this),a=e.effects.setMode(n,t.mode||"show"),o="show"===a,r="hide"===a,h=o||"hide"===a,l=2*(t.times||5)+(h?1:0),u=t.duration/l,d=0,c=n.queue(),p=c.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),d=1),s=1;l>s;s++)n.animate({opacity:d},u,t.easing),d=1-d;n.animate({opacity:d},u,t.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&c.splice.apply(c,[1,0].concat(c.splice(p,l+1))),n.dequeue()},e.effects.effect.shake=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","height","width"],o=e.effects.setMode(n,t.mode||"effect"),r=t.direction||"left",h=t.distance||20,l=t.times||3,u=2*l+1,d=Math.round(t.duration/u),c="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},m={},g={},v=n.queue(),y=v.length;for(e.effects.save(n,a),n.show(),e.effects.createWrapper(n),f[c]=(p?"-=":"+=")+h,m[c]=(p?"+=":"-=")+2*h,g[c]=(p?"-=":"+=")+2*h,n.animate(f,d,t.easing),s=1;l>s;s++)n.animate(m,d,t.easing).animate(g,d,t.easing);n.animate(m,d,t.easing).animate(f,d/2,t.easing).queue(function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}),y>1&&v.splice.apply(v,[1,0].concat(v.splice(y,u+1))),n.dequeue()},e.effects.effect.slide=function(t,i){var s,n=e(this),a=["position","top","bottom","left","right","width","height"],o=e.effects.setMode(n,t.mode||"show"),r="show"===o,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h,d={};e.effects.save(n,a),n.show(),s=t.distance||n["top"===l?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,u?isNaN(s)?"-"+s:-s:s),d[l]=(r?u?"+=":"-=":u?"-=":"+=")+s,n.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===o&&n.hide(),e.effects.restore(n,a),e.effects.removeWrapper(n),i()}})},e.effects.effect.transfer=function(t,i){var s=e(this),n=e(t.to),a="fixed"===n.css("position"),o=e("body"),r=a?o.scrollTop():0,h=a?o.scrollLeft():0,l=n.offset(),u={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},d=s.offset(),c=e("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(t.className).css({top:d.top-r,left:d.left-h,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(u,t.duration,t.easing,function(){c.remove(),i()})},e.widget("ui.progressbar",{version:"1.11.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return void 0===e?this.options.value:(this.options.value=this._constrainedValue(e),this._refreshValue(),void 0)},_constrainedValue:function(e){return void 0===e&&(e=this.options.value),this.indeterminate=e===!1,"number"!=typeof e&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){"max"===e&&(t=Math.max(this.min,t)),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),e.widget("ui.selectable",e.ui.mouse,{version:"1.11.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,n=e.data(this,"selectable-item");return n?(s=!t.metaKey&&!t.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",t,{selecting:n.element}):i._trigger("unselecting",t,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=t.pageX,h=t.pageY;return a>r&&(i=r,r=a,a=i),o>h&&(i=h,h=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:h-o}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||a>i.right||i.top>h||o>i.bottom):"fit"===n.tolerance&&(l=i.left>a&&r>i.right&&i.top>o&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}}),e.widget("ui.selectmenu",{version:"1.11.3",defaultElement:"<select>",options:{appendTo:null,disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:null,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this.options.disabled&&this.disable()},_drawButton:function(){var t=this;this.label=e("label[for='"+this.ids.element+"']").attr("for",this.ids.button),this._on(this.label,{click:function(e){this.button.focus(),e.preventDefault()}}),this.element.hide(),this.button=e("<span>",{"class":"ui-selectmenu-button ui-widget ui-state-default ui-corner-all",tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true"}).insertAfter(this.element),e("<span>",{"class":"ui-icon "+this.options.icons.button}).prependTo(this.button),this.buttonText=e("<span>",{"class":"ui-selectmenu-text"}).appendTo(this.button),this._setText(this.buttonText,this.element.find("option:selected").text()),this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){t.menuItems||t._refreshMenu()}),this._hoverable(this.button),this._focusable(this.button)},_drawMenu:function(){var t=this;this.menu=e("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=e("<div>",{"class":"ui-selectmenu-menu ui-front"}).append(this.menu).appendTo(this._appendTo()),this.menuInstance=this.menu.menu({role:"listbox",select:function(e,i){e.preventDefault(),t._setSelection(),t._select(i.item.data("ui-selectmenu-item"),e)},focus:function(e,i){var s=i.item.data("ui-selectmenu-item");null!=t.focusIndex&&s.index!==t.focusIndex&&(t._trigger("focus",e,{item:s}),t.isOpen||t._select(s,e)),t.focusIndex=s.index,t.button.attr("aria-activedescendant",t.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menu.addClass("ui-corner-bottom").removeClass("ui-corner-all"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this._setText(this.buttonText,this._getSelectedItem().text()),this.options.width||this._resizeButton()},_refreshMenu:function(){this.menu.empty();var e,t=this.element.find("option");t.length&&(this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup"),e=this._getSelectedItem(),this.menuInstance.focus(null,e),this._setAria(e.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(e){this.options.disabled||(this.menuItems?(this.menu.find(".ui-state-focus").removeClass("ui-state-focus"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",e))},_position:function(){this.menuWrap.position(e.extend({of:this.button},this.options.position))},close:function(e){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",e))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderMenu:function(t,i){var s=this,n="";e.each(i,function(i,a){a.optgroup!==n&&(e("<li>",{"class":"ui-selectmenu-optgroup ui-menu-divider"+(a.element.parent("optgroup").prop("disabled")?" ui-state-disabled":""),text:a.optgroup}).appendTo(t),n=a.optgroup),s._renderItemData(t,a)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-selectmenu-item",t)},_renderItem:function(t,i){var s=e("<li>");return i.disabled&&s.addClass("ui-state-disabled"),this._setText(s,i.label),s.appendTo(t)},_setText:function(e,t){t?e.text(t):e.html("&#160;")},_move:function(e,t){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex):(i=this.menuItems.eq(this.element[0].selectedIndex),n+=":not(.ui-state-disabled)"),s="first"===e||"last"===e?i["first"===e?"prevAll":"nextAll"](n).eq(-1):i[e+"All"](n).eq(0),s.length&&this.menuInstance.focus(t,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex)},_toggle:function(e){this[this.isOpen?"close":"open"](e)},_setSelection:function(){var e;this.range&&(window.getSelection?(e=window.getSelection(),e.removeAllRanges(),e.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(t){this.isOpen&&(e(t.target).closest(".ui-selectmenu-menu, #"+this.ids.button).length||this.close(t))}},_buttonEvents:{mousedown:function(){var e;window.getSelection?(e=window.getSelection(),e.rangeCount&&(this.range=e.getRangeAt(0))):this.range=document.selection.createRange()},click:function(e){this._setSelection(),this._toggle(e)},keydown:function(t){var i=!0;switch(t.keyCode){case e.ui.keyCode.TAB:case e.ui.keyCode.ESCAPE:this.close(t),i=!1;break;case e.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case e.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case e.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case e.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case e.ui.keyCode.LEFT:this._move("prev",t);break;case e.ui.keyCode.RIGHT:this._move("next",t);break;case e.ui.keyCode.HOME:case e.ui.keyCode.PAGE_UP:this._move("first",t);break;case e.ui.keyCode.END:case e.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),i=!1}i&&t.preventDefault()}},_selectFocusedItem:function(e){var t=this.menuItems.eq(this.focusIndex);t.hasClass("ui-state-disabled")||this._select(t.data("ui-selectmenu-item"),e)},_select:function(e,t){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=e.index,this._setText(this.buttonText,e.label),this._setAria(e),this._trigger("select",t,{item:e}),e.index!==i&&this._trigger("change",t,{item:e}),this.close(t)},_setAria:function(e){var t=this.menuItems.eq(e.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(e,t){"icons"===e&&this.button.find("span.ui-icon").removeClass(this.options.icons.button).addClass(t.button),this._super(e,t),"appendTo"===e&&this.menuWrap.appendTo(this._appendTo()),"disabled"===e&&(this.menuInstance.option("disabled",t),this.button.toggleClass("ui-state-disabled",t).attr("aria-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)),"width"===e&&this._resizeButton()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_toggleAttr:function(){this.button.toggleClass("ui-corner-top",this.isOpen).toggleClass("ui-corner-all",!this.isOpen).attr("aria-expanded",this.isOpen),this.menuWrap.toggleClass("ui-selectmenu-open",this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var e=this.options.width;e||(e=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(e)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){return{disabled:this.element.prop("disabled")}},_parseOptions:function(t){var i=[];t.each(function(t,s){var n=e(s),a=n.parent("optgroup");i.push({element:n,index:t,value:n.val(),label:n.text(),optgroup:a.attr("label")||"",disabled:a.prop("disabled")||n.prop("disabled")})}),this.items=i},_destroy:function(){this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.label.attr("for",this.ids.element)}}),e.widget("ui.slider",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),a="<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",o=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),t=n.length;i>t;t++)o.push(a);this.handles=n.add(e(o.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)})},_createRange:function(){var t=this.options,i="";t.range?(t.range===!0&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:e.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=e("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===t.range||"max"===t.range?" ui-slider-range-"+t.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var i,s,n,a,o,r,h,l,u=this,d=this.options;return d.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:t.pageX,y:t.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var i=Math.abs(s-u.values(t));(n>i||n===i&&(t===u._lastChangedValue||u.values(t)===d.min))&&(n=i,a=e(this),o=t)}),r=this._start(t,o),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,a.addClass("ui-state-active").focus(),h=a.offset(),l=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:t.pageX-h.left-a.width()/2,top:t.pageY-h.top-a.height()/2-(parseInt(a.css("borderTopWidth"),10)||0)-(parseInt(a.css("borderBottomWidth"),10)||0)+(parseInt(a.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},i=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,i),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,i,s,n,a;return"horizontal"===this.orientation?(t=this.elementSize.width,i=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,i=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/t,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),a=this._valueMin()+s*n,this._trimAlignValue(a)},_start:function(e,t){var i={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("start",e,i)},_slide:function(e,t,i){var s,n,a;this.options.values&&this.options.values.length?(s=this.values(t?0:1),2===this.options.values.length&&this.options.range===!0&&(0===t&&i>s||1===t&&s>i)&&(i=s),i!==this.values(t)&&(n=this.values(),n[t]=i,a=this._trigger("slide",e,{handle:this.handles[t],value:i,values:n}),s=this.values(t?0:1),a!==!1&&this.values(t,i))):i!==this.value()&&(a=this._trigger("slide",e,{handle:this.handles[t],value:i}),a!==!1&&this.value(i))},_stop:function(e,t){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("stop",e,i)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._lastChangedValue=t,this._trigger("change",e,i)}},value:function(e){return arguments.length?(this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(t,i){var s,n,a;if(arguments.length>1)return this.options.values[t]=this._trimAlignValue(i),this._refreshValue(),this._change(null,t),void 0;if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();for(s=this.options.values,n=arguments[0],a=0;s.length>a;a+=1)s[a]=this._trimAlignValue(n[a]),this._change(null,a);this._refreshValue()},_setOption:function(t,i){var s,n=0;switch("range"===t&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),e.isArray(this.options.values)&&(n=this.options.values.length),"disabled"===t&&this.element.toggleClass("ui-state-disabled",!!i),this._super(t,i),t){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue(),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e)},_values:function(e){var t,i,s;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(e){if(this._valueMin()>=e)return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,i=(e-this._valueMin())%t,s=e-i;return 2*Math.abs(i)>=t&&(s+=i>0?t:-t),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var e=this.options.max,t=this._valueMin(),i=this.options.step,s=Math.floor((e-t)/i)*i;e=s+t,this.max=parseFloat(e.toFixed(this._precision()))},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshValue:function(){var t,i,s,n,a,o=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",e(this).stop(1,1)[l?"animate":"css"](u,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-t+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-t+"%"},{queue:!1,duration:r.animate}))),t=i}):(s=this.value(),n=this._valueMin(),a=this._valueMax(),i=a!==n?100*((s-n)/(a-n)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,r.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===o&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===o&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(t){var i,s,n,a,o=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,e(t.target).addClass("ui-state-active"),i=this._start(t,o),i===!1))return}switch(a=this.options.step,s=n=this.options.values&&this.options.values.length?this.values(o):this.value(),t.keyCode){case e.ui.keyCode.HOME:n=this._valueMin();break;case e.ui.keyCode.END:n=this._valueMax();break;case e.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+a);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-a)}this._slide(t,o,n)},keyup:function(t){var i=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,i),this._change(t,i),e(t.target).removeClass("ui-state-active"))}}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===e.axis||this._isFloating(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,a.widgetName+"-item")===a?(s=e(this),!1):void 0}),e.data(t.target,a.widgetName+"-item")===a&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=e("<style>*{ cursor: "+o.cursor+" !important; }</style>").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));
+return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<o.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+o.scrollSpeed:t.pageY-this.overflowOffset.top<o.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-o.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<o.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+o.scrollSpeed:t.pageX-this.overflowOffset.left<o.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-o.scrollSpeed)):(t.pageY-this.document.scrollTop()<o.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-o.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<o.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+o.scrollSpeed)),t.pageX-this.document.scrollLeft()<o.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-o.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<o.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+o.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>r&&h>s+l,c="y"===this.options.axis||t+u>a&&o>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return s?this.floating?a&&"right"===a||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(n=e(c[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(d.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=d.length-1;i>=0;i--)for(o=d[i][1],r=d[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?t.currentItem.children().each(function(){e("<td>&#160;</td>",t.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,d,c=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(c&&e.contains(this.containers[i].element[0],c.element[0]))continue;c=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=c.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",d=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[d]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[d]-h)&&(n=Math.abs(t[d]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.width():this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(a=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}}),e.widget("ui.spinner",{version:"1.11.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},i=this.element;return e.each(["min","max","step"],function(e,s){var n=i.attr(s);void 0!==n&&n.length&&(t[s]=n)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e),void 0)},mousewheel:function(e,t){if(t){if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()}},"mousedown .ui-spinner-button":function(t){function i(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(t)!==!1&&this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){return e(t.currentTarget).hasClass("ui-state-active")?this._start(t)===!1?!1:(this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*e.height())&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var i=this.options,s=e.ui.keyCode;switch(t.keyCode){case s.UP:return this._repeat(null,1,t),!0;case s.DOWN:return this._repeat(null,-1,t),!0;case s.PAGE_UP:return this._repeat(null,i.page,t),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return this.spinning||this._trigger("start",e)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(e,t,i){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,i)},e),this._spin(t*this.options.step,i)},_spin:function(e,t){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+e*this._increment(this.counter)),this.spinning&&this._trigger("spin",t,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(t){var i=this.options.incremental;return i?e.isFunction(i)?i(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_adjustValue:function(e){var t,i,s=this.options;return t=null!==s.min?s.min:0,i=e-t,i=Math.round(i/s.step)*s.step,e=t+i,e=parseFloat(e.toFixed(this._precision())),null!==s.max&&e>s.max?s.max:null!==s.min&&s.min>e?s.min:e},_stop:function(e){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e))},_setOption:function(e,t){if("culture"===e||"numberFormat"===e){var i=this._parse(this.element.val());return this.options[e]=t,this.element.val(this._format(i)),void 0}("max"===e||"min"===e||"step"===e)&&"string"==typeof t&&(t=this._parse(t)),"icons"===e&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(t.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(t.down)),this._super(e,t),"disabled"===e&&(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable"))},_setOptions:h(function(e){this._super(e)}),_parse:function(e){return"string"==typeof e&&""!==e&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),""===e||isNaN(e)?null:e},_format:function(e){return""===e?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var e=this.value();return null===e?!1:e===this._adjustValue(e)},_value:function(e,t){var i;""!==e&&(i=this._parse(e),null!==i&&(t||(i=this._adjustValue(i)),e=this._format(i))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:h(function(e){this._stepUp(e)}),_stepUp:function(e){this._start()&&(this._spin((e||1)*this.options.step),this._stop())},stepDown:h(function(e){this._stepDown(e)}),_stepDown:function(e){this._start()&&(this._spin((e||1)*-this.options.step),this._stop())},pageUp:h(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:h(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){return arguments.length?(h(this._value).call(this,e),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),e.widget("ui.tabs",{version:"1.11.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,n){return e(n).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),t.ctrlKey||t.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>n&&(t=0),0>t&&(t=n),t}for(var n=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()
+}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var n,a,o,r=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(n=s.hash,o=n.substring(1),a=t.element.find(t._sanitizeSelector(n))):(o=h.attr("aria-controls")||e({}).uniqueId()[0].id,n="#"+o,a=t.element.find(n),a.length||(a=t._createPanel(o),a.insertAfter(t.panels[i-1]||t.tablist)),a.attr("aria-live","polite")),a.length&&(t.panels=t.panels.add(a)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":o,"aria-labelledby":r}),a.attr("aria-labelledby",r)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,n=e(t.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?e():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:r?e():a,newPanel:h};t.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?e():a,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),t),this._toggle(t,u))},_toggle:function(t,i){function s(){a.running=!1,a._trigger("activate",t,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,n=this.tabs.eq(t),a=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),r={tab:n,panel:o};this._isLocal(a[0])||(this.xhr=e.ajax(this._ajaxSettings(a,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){o.html(e),s._trigger("load",i,r)},1)}).complete(function(e,t){setTimeout(function(){"abort"===t&&s.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,a){return n._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:a},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),e.widget("ui.tooltip",{version:"1.11.3",options:{content:function(){var t=e(this).attr("title")||"";return e("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_addDescribedBy:function(t,i){var s=(t.attr("aria-describedby")||"").split(/\s+/);s.push(i),t.data("ui-tooltip-id",i).attr("aria-describedby",e.trim(s.join(" ")))},_removeDescribedBy:function(t){var i=t.data("ui-tooltip-id"),s=(t.attr("aria-describedby")||"").split(/\s+/),n=e.inArray(i,s);-1!==n&&s.splice(n,1),t.removeData("ui-tooltip-id"),s=e.trim(s.join(" ")),s?t.attr("aria-describedby",s):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable(),this.liveRegion=e("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body)},_setOption:function(t,i){var s=this;return"disabled"===t?(this[i?"_disable":"_enable"](),this.options[t]=i,void 0):(this._super(t,i),"content"===t&&e.each(this.tooltips,function(e,t){s._updateContent(t.element)}),void 0)},_disable:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur");n.target=n.currentTarget=s.element[0],t.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var i=this,s=e(t?t.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&s.parents().each(function(){var t,s=e(this);s.data("ui-tooltip-open")&&(t=e.Event("blur"),t.target=t.currentTarget=this,i.close(t,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,t))},_updateContent:function(e,t){var i,s=this.options.content,n=this,a=t?t.type:null;return"string"==typeof s?this._open(t,e,s):(i=s.call(e[0],function(i){e.data("ui-tooltip-open")&&n._delay(function(){t&&(t.type=a),this._open(t,e,i)})}),i&&this._open(t,e,i),void 0)},_open:function(t,i,s){function n(e){u.of=e,o.is(":hidden")||o.position(u)}var a,o,r,h,l,u=e.extend({},this.options.position);if(s){if(a=this._find(i))return a.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(t&&"mouseover"===t.type?i.attr("title",""):i.removeAttr("title")),a=this._tooltip(i),o=a.tooltip,this._addDescribedBy(i,o.attr("id")),o.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),s.clone?(l=s.clone(),l.removeAttr("id").find("[id]").removeAttr("id")):l=s,e("<div>").html(l).appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:n}),n(t)):o.position(e.extend({of:i},this.options.position)),o.hide(),this._show(o,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){o.is(":visible")&&(n(u.of),clearInterval(h))},e.fx.interval)),this._trigger("open",t,{tooltip:o}),r={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var s=e.Event(t);s.currentTarget=i[0],this.close(s,!0)}}},i[0]!==this.element[0]&&(r.remove=function(){this._removeTooltip(o)}),t&&"mouseover"!==t.type||(r.mouseleave="close"),t&&"focusin"!==t.type||(r.focusout="close"),this._on(!0,i,r)}},close:function(t){var i,s=this,n=e(t?t.currentTarget:this.element),a=this._find(n);a&&(i=a.tooltip,a.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),a.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(e(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&e.each(this.parents,function(t,i){e(i.element).attr("title",i.title),delete s.parents[t]}),a.closing=!0,this._trigger("close",t,{tooltip:i}),a.hiding||(a.closing=!1)))},_tooltip:function(t){var i=e("<div>").attr("role","tooltip").addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||"")),s=i.uniqueId().attr("id");return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),this.tooltips[s]={element:t,tooltip:i}},_find:function(e){var t=e.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(i,s){var n=e.Event("blur"),a=s.element;n.target=n.currentTarget=a[0],t.close(n,!0),e("#"+i).remove(),a.data("ui-tooltip-title")&&(a.attr("title")||a.attr("title",a.data("ui-tooltip-title")),a.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}})});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.css
new file mode 100644 (file)
index 0000000..6a278af
--- /dev/null
@@ -0,0 +1,833 @@
+/*!
+ * jQuery UI CSS Framework 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/theming/
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+       display: none;
+}
+.ui-helper-hidden-accessible {
+       border: 0;
+       clip: rect(0 0 0 0);
+       height: 1px;
+       margin: -1px;
+       overflow: hidden;
+       padding: 0;
+       position: absolute;
+       width: 1px;
+}
+.ui-helper-reset {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       outline: 0;
+       line-height: 1.3;
+       text-decoration: none;
+       font-size: 100%;
+       list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+       content: "";
+       display: table;
+       border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+       clear: both;
+}
+.ui-helper-clearfix {
+       min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       left: 0;
+       position: absolute;
+       opacity: 0;
+       filter:Alpha(Opacity=0); /* support: IE8 */
+}
+
+.ui-front {
+       z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+       cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       display: block;
+       text-indent: -99999px;
+       overflow: hidden;
+       background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+       position: fixed;
+       top: 0;
+       left: 0;
+       width: 100%;
+       height: 100%;
+}
+.ui-accordion .ui-accordion-header {
+       display: block;
+       cursor: pointer;
+       position: relative;
+       margin: 2px 0 0 0;
+       padding: .5em .5em .5em .7em;
+       min-height: 0; /* support: IE7 */
+       font-size: 100%;
+}
+.ui-accordion .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+       padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+       position: absolute;
+       left: .5em;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+       padding: 1em 2.2em;
+       border-top: 0;
+       overflow: auto;
+}
+.ui-autocomplete {
+       position: absolute;
+       top: 0;
+       left: 0;
+       cursor: default;
+}
+.ui-button {
+       display: inline-block;
+       position: relative;
+       padding: 0;
+       line-height: normal;
+       margin-right: .1em;
+       cursor: pointer;
+       vertical-align: middle;
+       text-align: center;
+       overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+       text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+       width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+       width: 2.4em;
+}
+.ui-button-icons-only {
+       width: 3.4em;
+}
+button.ui-button-icons-only {
+       width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+       display: block;
+       line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+       padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+       padding: .4em;
+       text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+       padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+       padding-left: 2.1em;
+       padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+       padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+       position: absolute;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+       left: 50%;
+       margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+       left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+       right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+       margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+       margin-left: 0;
+       margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+       border: 0;
+       padding: 0;
+}
+.ui-datepicker {
+       width: 17em;
+       padding: .2em .2em 0;
+       display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+       position: relative;
+       padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+       position: absolute;
+       top: 2px;
+       width: 1.8em;
+       height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+       top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+       left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+       right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+       left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+       right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+       display: block;
+       position: absolute;
+       left: 50%;
+       margin-left: -8px;
+       top: 50%;
+       margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+       margin: 0 2.3em;
+       line-height: 1.8em;
+       text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+       font-size: 1em;
+       margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+       width: 45%;
+}
+.ui-datepicker table {
+       width: 100%;
+       font-size: .9em;
+       border-collapse: collapse;
+       margin: 0 0 .4em;
+}
+.ui-datepicker th {
+       padding: .7em .3em;
+       text-align: center;
+       font-weight: bold;
+       border: 0;
+}
+.ui-datepicker td {
+       border: 0;
+       padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+       display: block;
+       padding: .2em;
+       text-align: right;
+       text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+       background-image: none;
+       margin: .7em 0 0 0;
+       padding: 0 .2em;
+       border-left: 0;
+       border-right: 0;
+       border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+       float: right;
+       margin: .5em .2em .4em;
+       cursor: pointer;
+       padding: .2em .6em .3em .6em;
+       width: auto;
+       overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+       float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+       width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+       float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+       width: 95%;
+       margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+       width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+       width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+       width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+       border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+       clear: left;
+}
+.ui-datepicker-row-break {
+       clear: both;
+       width: 100%;
+       font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+       direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+       right: 2px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+       left: 2px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+       right: 1px;
+       left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+       left: 1px;
+       right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+       clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+       float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+       float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+       border-right-width: 0;
+       border-left-width: 1px;
+}
+.ui-dialog {
+       overflow: hidden;
+       position: absolute;
+       top: 0;
+       left: 0;
+       padding: .2em;
+       outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+       padding: .4em 1em;
+       position: relative;
+}
+.ui-dialog .ui-dialog-title {
+       float: left;
+       margin: .1em 0;
+       white-space: nowrap;
+       width: 90%;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+       position: absolute;
+       right: .3em;
+       top: 50%;
+       width: 20px;
+       margin: -10px 0 0 0;
+       padding: 1px;
+       height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+       position: relative;
+       border: 0;
+       padding: .5em 1em;
+       background: none;
+       overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+       text-align: left;
+       border-width: 1px 0 0 0;
+       background-image: none;
+       margin-top: .5em;
+       padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+       float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+       margin: .5em .4em .5em 0;
+       cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+       width: 12px;
+       height: 12px;
+       right: -5px;
+       bottom: -5px;
+       background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+       cursor: move;
+}
+.ui-draggable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-menu {
+       list-style: none;
+       padding: 0;
+       margin: 0;
+       display: block;
+       outline: none;
+}
+.ui-menu .ui-menu {
+       position: absolute;
+}
+.ui-menu .ui-menu-item {
+       position: relative;
+       margin: 0;
+       padding: 3px 1em 3px .4em;
+       cursor: pointer;
+       min-height: 0; /* support: IE7 */
+       /* support: IE10, see #8844 */
+       list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
+}
+.ui-menu .ui-menu-divider {
+       margin: 5px 0;
+       height: 0;
+       font-size: 0;
+       line-height: 0;
+       border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-focus,
+.ui-menu .ui-state-active {
+       margin: -1px;
+}
+
+/* icon support */
+.ui-menu-icons {
+       position: relative;
+}
+.ui-menu-icons .ui-menu-item {
+       padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: .2em;
+       margin: auto 0;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+       left: auto;
+       right: 0;
+}
+.ui-progressbar {
+       height: 2em;
+       text-align: left;
+       overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+       margin: -1px;
+       height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+       background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
+       height: 100%;
+       filter: alpha(opacity=25); /* support: IE8 */
+       opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+       background-image: none;
+}
+.ui-resizable {
+       position: relative;
+}
+.ui-resizable-handle {
+       position: absolute;
+       font-size: 0.1px;
+       display: block;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+       display: none;
+}
+.ui-resizable-n {
+       cursor: n-resize;
+       height: 7px;
+       width: 100%;
+       top: -5px;
+       left: 0;
+}
+.ui-resizable-s {
+       cursor: s-resize;
+       height: 7px;
+       width: 100%;
+       bottom: -5px;
+       left: 0;
+}
+.ui-resizable-e {
+       cursor: e-resize;
+       width: 7px;
+       right: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-w {
+       cursor: w-resize;
+       width: 7px;
+       left: -5px;
+       top: 0;
+       height: 100%;
+}
+.ui-resizable-se {
+       cursor: se-resize;
+       width: 12px;
+       height: 12px;
+       right: 1px;
+       bottom: 1px;
+}
+.ui-resizable-sw {
+       cursor: sw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       bottom: -5px;
+}
+.ui-resizable-nw {
+       cursor: nw-resize;
+       width: 9px;
+       height: 9px;
+       left: -5px;
+       top: -5px;
+}
+.ui-resizable-ne {
+       cursor: ne-resize;
+       width: 9px;
+       height: 9px;
+       right: -5px;
+       top: -5px;
+}
+.ui-selectable {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-selectable-helper {
+       position: absolute;
+       z-index: 100;
+       border: 1px dotted black;
+}
+.ui-selectmenu-menu {
+       padding: 0;
+       margin: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+       overflow: auto;
+       /* Support: IE7 */
+       overflow-x: hidden;
+       padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+       font-size: 1em;
+       font-weight: bold;
+       line-height: 1.5;
+       padding: 2px 0.4em;
+       margin: 0.5em 0 0 0;
+       height: auto;
+       border: 0;
+}
+.ui-selectmenu-open {
+       display: block;
+}
+.ui-selectmenu-button {
+       display: inline-block;
+       overflow: hidden;
+       position: relative;
+       text-decoration: none;
+       cursor: pointer;
+}
+.ui-selectmenu-button span.ui-icon {
+       right: 0.5em;
+       left: auto;
+       margin-top: -8px;
+       position: absolute;
+       top: 50%;
+}
+.ui-selectmenu-button span.ui-selectmenu-text {
+       text-align: left;
+       padding: 0.4em 2.1em 0.4em 1em;
+       display: block;
+       line-height: 1.4;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.ui-slider {
+       position: relative;
+       text-align: left;
+}
+.ui-slider .ui-slider-handle {
+       position: absolute;
+       z-index: 2;
+       width: 1.2em;
+       height: 1.2em;
+       cursor: default;
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-slider .ui-slider-range {
+       position: absolute;
+       z-index: 1;
+       font-size: .7em;
+       display: block;
+       border: 0;
+       background-position: 0 0;
+}
+
+/* support: IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+       filter: inherit;
+}
+
+.ui-slider-horizontal {
+       height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+       top: -.3em;
+       margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+       top: 0;
+       height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+       left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+       right: 0;
+}
+
+.ui-slider-vertical {
+       width: .8em;
+       height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+       left: -.3em;
+       margin-left: 0;
+       margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+       left: 0;
+       width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+       bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+       top: 0;
+}
+.ui-sortable-handle {
+       -ms-touch-action: none;
+       touch-action: none;
+}
+.ui-spinner {
+       position: relative;
+       display: inline-block;
+       overflow: hidden;
+       padding: 0;
+       vertical-align: middle;
+}
+.ui-spinner-input {
+       border: none;
+       background: none;
+       color: inherit;
+       padding: 0;
+       margin: .2em 0;
+       vertical-align: middle;
+       margin-left: .4em;
+       margin-right: 22px;
+}
+.ui-spinner-button {
+       width: 16px;
+       height: 50%;
+       font-size: .5em;
+       padding: 0;
+       margin: 0;
+       text-align: center;
+       position: absolute;
+       cursor: default;
+       display: block;
+       overflow: hidden;
+       right: 0;
+}
+/* more specificity required here to override default borders */
+.ui-spinner a.ui-spinner-button {
+       border-top: none;
+       border-bottom: none;
+       border-right: none;
+}
+/* vertically center icon */
+.ui-spinner .ui-icon {
+       position: absolute;
+       margin-top: -8px;
+       top: 50%;
+       left: 0;
+}
+.ui-spinner-up {
+       top: 0;
+}
+.ui-spinner-down {
+       bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+       /* need to fix icons sprite */
+       background-position: -65px -16px;
+}
+.ui-tabs {
+       position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+       padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+       margin: 0;
+       padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+       list-style: none;
+       float: left;
+       position: relative;
+       top: 0;
+       margin: 1px .2em 0 0;
+       border-bottom-width: 0;
+       padding: 0;
+       white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+       float: left;
+       padding: .5em 1em;
+       text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+       margin-bottom: -1px;
+       padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+       cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+       cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+       display: block;
+       border-width: 0;
+       padding: 1em 1.4em;
+       background: none;
+}
+.ui-tooltip {
+       padding: 8px;
+       position: absolute;
+       z-index: 9999;
+       max-width: 300px;
+       -webkit-box-shadow: 0 0 5px #aaa;
+       box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+       border-width: 2px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.structure.min.css
new file mode 100644 (file)
index 0000000..7495d8a
--- /dev/null
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.css
new file mode 100644 (file)
index 0000000..22a36bf
--- /dev/null
@@ -0,0 +1,410 @@
+/*!
+ * jQuery UI CSS Framework 1.11.3
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/theming/
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+       font-family: Arial,Helvetica,sans-serif;
+       font-size: 1em;
+}
+.ui-widget .ui-widget {
+       font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+       font-family: Arial,Helvetica,sans-serif;
+       font-size: 1em;
+}
+.ui-widget-content {
+       border: 1px solid #dddddd;
+       background: #ffffff;
+       color: #333333;
+}
+.ui-widget-content a {
+       color: #333333;
+}
+.ui-widget-header {
+       border: 1px solid #dddddd;
+       background: #e9e9e9;
+       color: #333333;
+       font-weight: bold;
+}
+.ui-widget-header a {
+       color: #333333;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+       border: 1px solid #c5c5c5;
+       background: #f6f6f6;
+       font-weight: normal;
+       color: #454545;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+       color: #454545;
+       text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+       border: 1px solid #cccccc;
+       background: #ededed;
+       font-weight: normal;
+       color: #2b2b2b;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited {
+       color: #2b2b2b;
+       text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+       border: 1px solid #003eff;
+       background: #007fff;
+       font-weight: normal;
+       color: #ffffff;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+       color: #ffffff;
+       text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+       border: 1px solid #dad55e;
+       background: #fffa90;
+       color: #777620;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+       color: #777620;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+       border: 1px solid #f1a899;
+       background: #fddfdf;
+       color: #5f3f3f;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+       color: #5f3f3f;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+       color: #5f3f3f;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+       font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+       opacity: .7;
+       filter:Alpha(Opacity=70); /* support: IE8 */
+       font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+       opacity: .35;
+       filter:Alpha(Opacity=35); /* support: IE8 */
+       background-image: none;
+}
+.ui-state-disabled .ui-icon {
+       filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+       width: 16px;
+       height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+       background-image: url("images/ui-icons_444444_256x240.png");
+}
+.ui-widget-header .ui-icon {
+       background-image: url("images/ui-icons_444444_256x240.png");
+}
+.ui-state-default .ui-icon {
+       background-image: url("images/ui-icons_777777_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+       background-image: url("images/ui-icons_555555_256x240.png");
+}
+.ui-state-active .ui-icon {
+       background-image: url("images/ui-icons_ffffff_256x240.png");
+}
+.ui-state-highlight .ui-icon {
+       background-image: url("images/ui-icons_777620_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+       background-image: url("images/ui-icons_cc0000_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+       border-top-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+       border-top-right-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+       border-bottom-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+       border-bottom-right-radius: 3px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+       background: #aaaaaa;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+}
+.ui-widget-shadow {
+       margin: 0px 0 0 0px;
+       padding: 5px;
+       background: #666666;
+       opacity: .3;
+       filter: Alpha(Opacity=30); /* support: IE8 */
+       border-radius: 8px;
+}
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.min.css b/src/main/resources/META-INF/resources/designer/lib/jquery-ui-1.11.3/jquery-ui.theme.min.css
new file mode 100644 (file)
index 0000000..9fd96c7
--- /dev/null
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.11.3 - 2015-02-12
+* http://jqueryui.com
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#2b2b2b;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery.highlight.js b/src/main/resources/META-INF/resources/designer/lib/jquery.highlight.js
new file mode 100644 (file)
index 0000000..9774874
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * jQuery Highlight plugin
+ *
+ * Based on highlight v3 by Johann Burkard
+ * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
+ *
+ * Code a little bit refactored and cleaned (in my humble opinion).
+ * Most important changes:
+ *  - has an option to highlight only entire words (wordsOnly - false by default),
+ *  - has an option to be case sensitive (caseSensitive - false by default)
+ *  - highlight element tag and class names can be specified in options
+ *
+ * Usage:
+ *   // wrap every occurrance of text 'lorem' in content
+ *   // with <span class='highlight'> (default options)
+ *   $('#content').highlight('lorem');
+ *
+ *   // search for and highlight more terms at once
+ *   // so you can save some time on traversing DOM
+ *   $('#content').highlight(['lorem', 'ipsum']);
+ *   $('#content').highlight('lorem ipsum');
+ *
+ *   // search only for entire word 'lorem'
+ *   $('#content').highlight('lorem', { wordsOnly: true });
+ *
+ *   // don't ignore case during search of term 'lorem'
+ *   $('#content').highlight('lorem', { caseSensitive: true });
+ *
+ *   // wrap every occurrance of term 'ipsum' in content
+ *   // with <em class='important'>
+ *   $('#content').highlight('ipsum', { element: 'em', className: 'important' });
+ *
+ *   // remove default highlight
+ *   $('#content').unhighlight();
+ *
+ *   // remove custom highlight
+ *   $('#content').unhighlight({ element: 'em', className: 'important' });
+ *
+ *
+ * Copyright (c) 2009 Bartek Szopka
+ *
+ * Licensed under MIT license.
+ *
+ */
+
+jQuery.extend({
+    highlight: function (node, re, nodeName, className) {
+        if (node.nodeType === 3) {
+            var match = node.data.match(re);
+            if (match) {
+                var highlight = document.createElement(nodeName || 'span');
+                highlight.className = className || 'highlight';
+                var wordNode = node.splitText(match.index);
+                wordNode.splitText(match[0].length);
+                var wordClone = wordNode.cloneNode(true);
+                highlight.appendChild(wordClone);
+                wordNode.parentNode.replaceChild(highlight, wordNode);
+                return 1; //skip added node in parent
+            }
+        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
+                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
+                !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
+            for (var i = 0; i < node.childNodes.length; i++) {
+                i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
+            }
+        }
+        return 0;
+    }
+});
+
+jQuery.fn.unhighlight = function (options) {
+    var settings = { className: 'highlight', element: 'span' };
+    jQuery.extend(settings, options);
+
+    return this.find(settings.element + "." + settings.className).each(function () {
+        var parent = this.parentNode;
+        parent.replaceChild(this.firstChild, this);
+        parent.normalize();
+    }).end();
+};
+
+jQuery.fn.highlight = function (words, options) {
+    var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
+    jQuery.extend(settings, options);
+    
+    if (words.constructor === String) {
+        words = [words];
+    }
+    words = jQuery.grep(words, function(word, i){
+      return word != '';
+    });
+    words = jQuery.map(words, function(word, i) {
+      return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+    });
+    if (words.length == 0) { return this; };
+
+    var flag = settings.caseSensitive ? "" : "i";
+    var pattern = "(" + words.join("|") + ")";
+    if (settings.wordsOnly) {
+        pattern = "\\b" + pattern + "\\b";
+    }
+    var re = new RegExp(pattern, flag);
+    
+    return this.each(function () {
+        jQuery.highlight(this, re, settings.element, settings.className);
+    });
+};
diff --git a/src/main/resources/META-INF/resources/designer/lib/jquery.min.js b/src/main/resources/META-INF/resources/designer/lib/jquery.min.js
new file mode 100644 (file)
index 0000000..73f33fb
--- /dev/null
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f
+}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="  <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)
+},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.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(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,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":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});
diff --git a/src/main/resources/META-INF/resources/designer/lib/loading-bar.js b/src/main/resources/META-INF/resources/designer/lib/loading-bar.js
new file mode 100644 (file)
index 0000000..eb56aa3
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * angular-loading-bar
+ *
+ * intercepts XHR requests and creates a loading bar.
+ * Based on the excellent nprogress work by rstacruz (more info in readme)
+ *
+ * (c) 2013 Wes Cruver
+ * License: MIT
+ */
+
+
+(function() {
+
+'use strict';
+
+// Alias the loading bar for various backwards compatibilities since the project has matured:
+angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']);
+angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']);
+
+
+/**
+ * loadingBarInterceptor service
+ *
+ * Registers itself as an Angular interceptor and listens for XHR requests.
+ */
+angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar'])
+  .config(['$httpProvider', function ($httpProvider) {
+
+    var interceptor = ['$q', '$cacheFactory', '$timeout', '$rootScope', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, cfpLoadingBar) {
+
+      /**
+       * The total number of requests made
+       */
+      var reqsTotal = 0;
+
+      /**
+       * The number of requests completed (either successfully or not)
+       */
+      var reqsCompleted = 0;
+
+      /**
+       * The amount of time spent fetching before showing the loading bar
+       */
+      var latencyThreshold = cfpLoadingBar.latencyThreshold;
+
+      /**
+       * $timeout handle for latencyThreshold
+       */
+      var startTimeout;
+
+
+      /**
+       * calls cfpLoadingBar.complete() which removes the
+       * loading bar from the DOM.
+       */
+      function setComplete() {
+        $timeout.cancel(startTimeout);
+        cfpLoadingBar.complete();
+        reqsCompleted = 0;
+        reqsTotal = 0;
+      }
+
+      /**
+       * Determine if the response has already been cached
+       * @param  {Object}  config the config option from the request
+       * @return {Boolean} retrns true if cached, otherwise false
+       */
+      function isCached(config) {
+        var cache;
+        var defaultCache = $cacheFactory.get('$http');
+        var defaults = $httpProvider.defaults;
+
+        // Choose the proper cache source. Borrowed from angular: $http service
+        if ((config.cache || defaults.cache) && config.cache !== false &&
+          (config.method === 'GET' || config.method === 'JSONP')) {
+            cache = angular.isObject(config.cache) ? config.cache
+              : angular.isObject(defaults.cache) ? defaults.cache
+              : defaultCache;
+        }
+
+        var cached = cache !== undefined ?
+          cache.get(config.url) !== undefined : false;
+
+        if (config.cached !== undefined && cached !== config.cached) {
+          return config.cached;
+        }
+        config.cached = cached;
+        return cached;
+      }
+
+
+      return {
+        'request': function(config) {
+          // Check to make sure this request hasn't already been cached and that
+          // the requester didn't explicitly ask us to ignore this request:
+          if (!config.ignoreLoadingBar && !isCached(config)) {
+            $rootScope.$broadcast('cfpLoadingBar:loading', {url: config.url});
+            /*if (reqsTotal === 0) {
+              startTimeout = $timeout(function() {
+                cfpLoadingBar.start();
+              }, latencyThreshold);
+            }*/
+            cfpLoadingBar.start();
+            reqsTotal++;
+            cfpLoadingBar.set(reqsCompleted / reqsTotal);
+          }
+          return config;
+        },
+
+        'response': function(response) {
+          if (!response.config.ignoreLoadingBar && !isCached(response.config)) {
+            reqsCompleted++;
+            $rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url, result: response});
+            if (reqsCompleted >= reqsTotal) {
+              setComplete();
+            } else {
+              cfpLoadingBar.set(reqsCompleted / reqsTotal);
+            }
+          }
+          return response;
+        },
+
+        'responseError': function(rejection) {
+          if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) {
+            reqsCompleted++;
+            $rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url, result: rejection});
+            if (reqsCompleted >= reqsTotal) {
+              setComplete();
+            } else {
+              cfpLoadingBar.set(reqsCompleted / reqsTotal);
+            }
+          }
+          return $q.reject(rejection);
+        }
+      };
+    }];
+
+    $httpProvider.interceptors.push(interceptor);
+  }]);
+
+
+/**
+ * Loading Bar
+ *
+ * This service handles adding and removing the actual element in the DOM.
+ * Generally, best practices for DOM manipulation is to take place in a
+ * directive, but because the element itself is injected in the DOM only upon
+ * XHR requests, and it's likely needed on every view, the best option is to
+ * use a service.
+ */
+angular.module('cfp.loadingBar', [])
+  .provider('cfpLoadingBar', function() {
+
+    this.includeSpinner = true;
+    this.includeBar = true;
+    this.latencyThreshold = 100;
+    this.startSize = 0.02;
+    this.parentSelector = 'body';
+    this.spinnerTemplate = '<div id="loading-bar-spinner"><div class="spinner-icon"></div></div>';
+    this.loadingBarTemplate = '<div id="loading-bar"><div class="bar"><div class="peg"></div></div></div>';
+
+    this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) {
+      var $animate;
+      var $parentSelector = this.parentSelector,
+        loadingBarContainer = angular.element(this.loadingBarTemplate),
+        loadingBar = loadingBarContainer.find('div').eq(0),
+        spinner = angular.element(this.spinnerTemplate);
+
+      var incTimeout,
+        completeTimeout,
+        started = false,
+        status = 0;
+
+      var includeSpinner = this.includeSpinner;
+      var includeBar = this.includeBar;
+      var startSize = this.startSize;
+
+      /**
+       * Inserts the loading bar element into the dom, and sets it to 2%
+       */
+      function _start() {
+        if (!$animate) {
+          $animate = $injector.get('$animate');
+        }
+
+        var $parent = $document.find($parentSelector).eq(0);
+        $timeout.cancel(completeTimeout);
+
+        // do not continually broadcast the started event:
+        if (started) {
+          return;
+        }
+
+        $rootScope.$broadcast('cfpLoadingBar:started');
+        started = true;
+
+        if (includeBar) {
+          $animate.enter(loadingBarContainer, $parent);
+        }
+
+        if (includeSpinner) {
+          $animate.enter(spinner, $parent);
+        }
+
+        _set(startSize);
+      }
+
+      /**
+       * Set the loading bar's width to a certain percent.
+       *
+       * @param n any value between 0 and 1
+       */
+      function _set(n) {
+        if (!started) {
+          return;
+        }
+        var pct = (n * 100) + '%';
+        loadingBar.css('width', pct);
+        status = n;
+
+        // increment loadingbar to give the illusion that there is always
+        // progress but make sure to cancel the previous timeouts so we don't
+        // have multiple incs running at the same time.
+        $timeout.cancel(incTimeout);
+        incTimeout = $timeout(function() {
+          _inc();
+        }, 250);
+      }
+
+      /**
+       * Increments the loading bar by a random amount
+       * but slows down as it progresses
+       */
+      function _inc() {
+        if (_status() >= 1) {
+          return;
+        }
+
+        var rnd = 0;
+
+        // TODO: do this mathmatically instead of through conditions
+
+        var stat = _status();
+        if (stat >= 0 && stat < 0.25) {
+          // Start out between 3 - 6% increments
+          rnd = (Math.random() * (5 - 3 + 1) + 3) / 100;
+        } else if (stat >= 0.25 && stat < 0.65) {
+          // increment between 0 - 3%
+          rnd = (Math.random() * 3) / 100;
+        } else if (stat >= 0.65 && stat < 0.9) {
+          // increment between 0 - 2%
+          rnd = (Math.random() * 2) / 100;
+        } else if (stat >= 0.9 && stat < 0.99) {
+          // finally, increment it .5 %
+          rnd = 0.005;
+        } else {
+          // after 99%, don't increment:
+          rnd = 0;
+        }
+
+        var pct = _status() + rnd;
+        _set(pct);
+      }
+
+      function _status() {
+        return status;
+      }
+
+      function _completeAnimation() {
+        status = 0;
+        started = false;
+      }
+
+      function _complete() {
+        if (!$animate) {
+          $animate = $injector.get('$animate');
+        }
+
+        $rootScope.$broadcast('cfpLoadingBar:completed');
+        _set(1);
+
+        $timeout.cancel(completeTimeout);
+
+        // Attempt to aggregate any start/complete calls within 500ms:
+        completeTimeout = $timeout(function() {
+          var promise = $animate.leave(loadingBarContainer, _completeAnimation);
+          if (promise && promise.then) {
+            promise.then(_completeAnimation);
+          }
+          $animate.leave(spinner);
+        }, 500);
+      }
+
+      return {
+        start            : _start,
+        set              : _set,
+        status           : _status,
+        inc              : _inc,
+        complete         : _complete,
+        includeSpinner   : this.includeSpinner,
+        latencyThreshold : this.latencyThreshold,
+        parentSelector   : this.parentSelector,
+        startSize        : this.startSize
+      };
+
+
+    }];     //
+  });       // wtf javascript. srsly
+})();       //
diff --git a/src/main/resources/META-INF/resources/designer/lib/lodash.min.js b/src/main/resources/META-INF/resources/designer/lib/lodash.min.js
new file mode 100644 (file)
index 0000000..85a9626
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * @license
+ * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
+ * Build: `lodash modern -o ./dist/lodash.js`
+ */
+;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:m+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:m+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true
+}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var i=e[u],a=r[u];if(i!==a){if(i>a||typeof i=="undefined")return 1;if(i<a||typeof a=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&i&&typeof i=="object")return false;for(u=f(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=f(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function i(n){return"\\"+U[n]
+}function a(){return h.pop()||[]}function f(){return g.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function l(n){n.length=0,h.length<_&&h.push(n)}function c(n){var t=n.l;t&&c(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,g.length<_&&g.push(n)}function p(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function s(e){function h(n,t,e){if(!n||!V[typeof n])return n;
+t=t&&typeof e=="undefined"?t:tt(t,e,3);for(var r=-1,u=V[typeof n]&&Fe(n),o=u?u.length:0;++r<o&&(e=u[r],false!==t(n[e],e,n)););return n}function g(n,t,e){var r;if(!n||!V[typeof n])return n;t=t&&typeof e=="undefined"?t:tt(t,e,3);for(r in n)if(false===t(n[r],r,n))break;return n}function _(n,t,e){var r,u=n,o=u;if(!u)return o;for(var i=arguments,a=0,f=typeof e=="number"?2:i.length;++a<f;)if((u=i[a])&&V[typeof u])for(var l=-1,c=V[typeof u]&&Fe(u),p=c?c.length:0;++l<p;)r=c[l],"undefined"==typeof o[r]&&(o[r]=u[r]);
+return o}function U(n,t,e){var r,u=n,o=u;if(!u)return o;var i=arguments,a=0,f=typeof e=="number"?2:i.length;if(3<f&&"function"==typeof i[f-2])var l=tt(i[--f-1],i[f--],2);else 2<f&&"function"==typeof i[f-1]&&(l=i[--f]);for(;++a<f;)if((u=i[a])&&V[typeof u])for(var c=-1,p=V[typeof u]&&Fe(u),s=p?p.length:0;++c<s;)r=p[c],o[r]=l?l(o[r],u[r]):u[r];return o}function H(n){var t,e=[];if(!n||!V[typeof n])return e;for(t in n)me.call(n,t)&&e.push(t);return e}function J(n){return n&&typeof n=="object"&&!Te(n)&&me.call(n,"__wrapped__")?n:new Q(n)
+}function Q(n,t){this.__chain__=!!t,this.__wrapped__=n}function X(n){function t(){if(r){var n=p(r);be.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return wt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return $e(t,n),t}function Z(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!wt(n))return n;var i=ce.call(n);if(!K[i])return n;var f=Ae[i];switch(i){case T:case F:return new f(+n);case W:case P:return new f(n);case z:return o=f(n.source,C.exec(n)),o.lastIndex=n.lastIndex,o
+}if(i=Te(n),t){var c=!r;r||(r=a()),u||(u=a());for(var s=r.length;s--;)if(r[s]==n)return u[s];o=i?f(n.length):{}}else o=i?p(n):U({},n);return i&&(me.call(n,"index")&&(o.index=n.index),me.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(i?St:h)(n,function(n,i){o[i]=Z(n,t,e,r,u)}),c&&(l(r),l(u)),o):o}function nt(n){return wt(n)?ke(n):{}}function tt(n,t,e){if(typeof n!="function")return Ut;if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(De.funcNames&&(r=!n.name),r=r||!De.funcDecomp,!r)){var u=ge.call(n);
+De.funcNames||(r=!O.test(u)),r||(r=E.test(u),$e(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=f?i:this;if(u){var h=p(u);be.apply(h,arguments)}return(o||c)&&(h||(h=p(arguments)),o&&be.apply(h,o),c&&h.length<a)?(r|=16,et([e,s?r:-4&r,h,null,i,a])):(h||(h=arguments),l&&(e=n[v]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),wt(h)?h:n):e.apply(n,h))
+}var e=n[0],r=n[1],u=n[2],o=n[3],i=n[4],a=n[5],f=1&r,l=2&r,c=4&r,s=8&r,v=e;return $e(t,n),t}function rt(e,r){var u=-1,i=st(),a=e?e.length:0,f=a>=b&&i===n,l=[];if(f){var p=o(r);p?(i=t,r=p):f=false}for(;++u<a;)p=e[u],0>i(r,p)&&l.push(p);return f&&c(r),l}function ut(n,t,e,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r<u;){var i=n[r];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Te(i)||yt(i))){t||(i=ut(i,t,e));var a=-1,f=i.length,l=o.length;for(o.length+=f;++a<f;)o[l++]=i[a]}else e||o.push(i)}return o
+}function ot(n,t,e,r,u,o){if(e){var i=e(n,t);if(typeof i!="undefined")return!!i}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&V[typeof n]||t&&V[typeof t]))return false;if(null==n||null==t)return n===t;var f=ce.call(n),c=ce.call(t);if(f==D&&(f=q),c==D&&(c=q),f!=c)return false;switch(f){case T:case F:return+n==+t;case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case z:case P:return n==oe(t)}if(c=f==$,!c){var p=me.call(n,"__wrapped__"),s=me.call(t,"__wrapped__");if(p||s)return ot(p?n.__wrapped__:n,s?t.__wrapped__:t,e,r,u,o);
+if(f!=q)return false;if(f=n.constructor,p=t.constructor,f!=p&&!(dt(f)&&f instanceof f&&dt(p)&&p instanceof p)&&"constructor"in n&&"constructor"in t)return false}for(f=!u,u||(u=a()),o||(o=a()),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,i=true;if(u.push(n),o.push(t),c){if(p=n.length,v=t.length,(i=v==p)||r)for(;v--;)if(c=p,s=t[v],r)for(;c--&&!(i=ot(n[c],s,e,r,u,o)););else if(!(i=ot(n[v],s,e,r,u,o)))break}else g(t,function(t,a,f){return me.call(f,a)?(v++,i=me.call(n,a)&&ot(n[a],t,e,r,u,o)):void 0}),i&&!r&&g(n,function(n,t,e){return me.call(e,t)?i=-1<--v:void 0
+});return u.pop(),o.pop(),f&&(l(u),l(o)),i}function it(n,t,e,r,u){(Te(t)?St:h)(t,function(t,o){var i,a,f=t,l=n[o];if(t&&((a=Te(t))||Pe(t))){for(f=r.length;f--;)if(i=r[f]==t){l=u[f];break}if(!i){var c;e&&(f=e(l,t),c=typeof f!="undefined")&&(l=f),c||(l=a?Te(l)?l:[]:Pe(l)?l:{}),r.push(t),u.push(l),c||it(l,t,e,r,u)}}else e&&(f=e(l,t),typeof f=="undefined"&&(f=t)),typeof f!="undefined"&&(l=f);n[o]=l})}function at(n,t){return n+he(Re()*(t-n+1))}function ft(e,r,u){var i=-1,f=st(),p=e?e.length:0,s=[],v=!r&&p>=b&&f===n,h=u||v?a():s;
+for(v&&(h=o(h),f=t);++i<p;){var g=e[i],y=u?u(g,i,e):g;(r?!i||h[h.length-1]!==y:0>f(h,y))&&((u||v)&&h.push(y),s.push(g))}return v?(l(h.k),c(h)):u&&l(h),s}function lt(n){return function(t,e,r){var u={};e=J.createCallback(e,r,3),r=-1;var o=t?t.length:0;if(typeof o=="number")for(;++r<o;){var i=t[r];n(u,i,e(i,r,t),t)}else h(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function ct(n,t,e,r,u,o){var i=1&t,a=4&t,f=16&t,l=32&t;if(!(2&t||dt(n)))throw new ie;f&&!e.length&&(t&=-17,f=e=false),l&&!r.length&&(t&=-33,l=r=false);
+var c=n&&n.__bindData__;return c&&true!==c?(c=p(c),c[2]&&(c[2]=p(c[2])),c[3]&&(c[3]=p(c[3])),!i||1&c[1]||(c[4]=u),!i&&1&c[1]&&(t|=8),!a||4&c[1]||(c[5]=o),f&&be.apply(c[2]||(c[2]=[]),e),l&&we.apply(c[3]||(c[3]=[]),r),c[1]|=t,ct.apply(null,c)):(1==t||17===t?X:et)([n,t,e,r,u,o])}function pt(n){return Be[n]}function st(){var t=(t=J.indexOf)===Wt?n:t;return t}function vt(n){return typeof n=="function"&&pe.test(n)}function ht(n){var t,e;return n&&ce.call(n)==q&&(t=n.constructor,!dt(t)||t instanceof t)?(g(n,function(n,t){e=t
+}),typeof e=="undefined"||me.call(n,e)):false}function gt(n){return We[n]}function yt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==D||false}function mt(n,t,e){var r=Fe(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function bt(n){var t=[];return g(n,function(n,e){dt(n)&&t.push(e)}),t.sort()}function _t(n){for(var t=-1,e=Fe(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function dt(n){return typeof n=="function"}function wt(n){return!(!n||!V[typeof n])
+}function jt(n){return typeof n=="number"||n&&typeof n=="object"&&ce.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&ce.call(n)==P||false}function xt(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;)u[t]=n[e[t]];return u}function Ct(n,t,e){var r=-1,u=st(),o=n?n.length:0,i=false;return e=(0>e?Ie(0,o+e):e)||0,Te(n)?i=-1<u(n,t,e):typeof o=="number"?i=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):h(n,function(n){return++r<e?void 0:!(i=n===t)}),i}function Ot(n,t,e){var r=true;t=J.createCallback(t,e,3),e=-1;
+var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&(r=!!t(n[e],e,n)););else h(n,function(n,e,u){return r=!!t(n,e,u)});return r}function Nt(n,t,e){var r=[];t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}else h(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){t=J.createCallback(t,e,3),e=-1;var r=n?n.length:0;if(typeof r!="number"){var u;return h(n,function(n,e,r){return t(n,e,r)?(u=n,false):void 0}),u}for(;++e<r;){var o=n[e];
+if(t(o,e,n))return o}}function St(n,t,e){var r=-1,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof u=="number")for(;++r<u&&false!==t(n[r],r,n););else h(n,t);return n}function Et(n,t,e){var r=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof r=="number")for(;r--&&false!==t(n[r],r,n););else{var u=Fe(n),r=u.length;h(n,function(n,e,o){return e=u?u[--r]:--r,t(o[e],e,o)})}return n}function Rt(n,t,e){var r=-1,u=n?n.length:0;if(t=J.createCallback(t,e,3),typeof u=="number")for(var o=Xt(u);++r<u;)o[r]=t(n[r],r,n);
+else o=[],h(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function At(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a>o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Dt(n,t,e,r){if(!n)return e;var u=3>arguments.length;t=J.createCallback(t,r,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n);else h(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)
+});return e}function $t(n,t,e,r){var u=3>arguments.length;return t=J.createCallback(t,r,4),Et(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Xt(typeof e=="number"?e:0);return St(n,function(n){var e=at(0,++t);r[t]=r[e],r[e]=n}),r}function Ft(n,t,e){var r;t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&!(r=t(n[e],e,n)););else h(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Bt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1;
+for(t=J.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[0]:v;return p(n,0,Se(Ie(0,r),u))}function Wt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Ie(0,u+r):r||0}else if(r)return r=zt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=J.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Ie(0,t);return p(n,r)}function zt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?J.createCallback(e,r,1):Ut,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;
+return u}function Pt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=J.createCallback(e,r,3)),ft(n,t,e)}function Kt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?At(Ve(n,"length")):0,r=Xt(0>e?0:e);++t<e;)r[t]=Ve(n,t);return r}function Lt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||Te(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?ct(n,17,p(arguments,2),null,t):ct(n,1,null,null,t)
+}function Vt(n,t,e){function r(){c&&ve(c),i=c=p=v,(g||h!==t)&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null))}function u(){var e=t-(Ue()-f);0<e?c=_e(u,e):(i&&ve(i),e=p,i=c=p=v,e&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null)))}var o,i,a,f,l,c,p,s=0,h=false,g=true;if(!dt(n))throw new ie;if(t=Ie(0,t)||0,true===e)var y=true,g=false;else wt(e)&&(y=e.leading,h="maxWait"in e&&(Ie(t,e.maxWait)||0),g="trailing"in e?e.trailing:g);return function(){if(o=arguments,f=Ue(),l=this,p=g&&(c||!y),false===h)var e=y&&!c;else{i||y||(s=f);var v=h-(f-s),m=0>=v;
+m?(i&&(i=ve(i)),s=f,a=n.apply(l,o)):i||(i=_e(r,v))}return m&&c?c=ve(c):c||t===h||(c=_e(u,t)),e&&(m=true,a=n.apply(l,o)),!m||c||i||(o=l=null),a}}function Ut(n){return n}function Gt(n,t,e){var r=true,u=t&&bt(t);t&&(e||u.length)||(null==e&&(e=t),o=Q,t=n,n=J,u=bt(t)),false===e?r=false:wt(e)&&"chain"in e&&(r=e.chain);var o=n,i=dt(o);St(u,function(e){var u=n[e]=t[e];i&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,i=[e];if(be.apply(i,arguments),i=u.apply(n,i),r||t){if(e===i&&wt(i))return this;
+i=new o(i),i.__chain__=t}return i})})}function Ht(){}function Jt(n){return function(t){return t[n]}}function Qt(){return this.__wrapped__}e=e?Y.defaults(G.Object(),e,Y.pick(G,A)):G;var Xt=e.Array,Yt=e.Boolean,Zt=e.Date,ne=e.Function,te=e.Math,ee=e.Number,re=e.Object,ue=e.RegExp,oe=e.String,ie=e.TypeError,ae=[],fe=re.prototype,le=e._,ce=fe.toString,pe=ue("^"+oe(ce).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),se=te.ceil,ve=e.clearTimeout,he=te.floor,ge=ne.prototype.toString,ye=vt(ye=re.getPrototypeOf)&&ye,me=fe.hasOwnProperty,be=ae.push,_e=e.setTimeout,de=ae.splice,we=ae.unshift,je=function(){try{var n={},t=vt(t=re.defineProperty)&&t,e=t(n,n,n)&&t
+}catch(r){}return e}(),ke=vt(ke=re.create)&&ke,xe=vt(xe=Xt.isArray)&&xe,Ce=e.isFinite,Oe=e.isNaN,Ne=vt(Ne=re.keys)&&Ne,Ie=te.max,Se=te.min,Ee=e.parseInt,Re=te.random,Ae={};Ae[$]=Xt,Ae[T]=Yt,Ae[F]=Zt,Ae[B]=ne,Ae[q]=re,Ae[W]=ee,Ae[z]=ue,Ae[P]=oe,Q.prototype=J.prototype;var De=J.support={};De.funcDecomp=!vt(e.a)&&E.test(s),De.funcNames=typeof ne.name=="string",J.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:J}},ke||(nt=function(){function n(){}return function(t){if(wt(t)){n.prototype=t;
+var r=new n;n.prototype=null}return r||e.Object()}}());var $e=je?function(n,t){M.value=t,je(n,"__bindData__",M)}:Ht,Te=xe||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==$||false},Fe=Ne?function(n){return wt(n)?Ne(n):[]}:H,Be={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},We=_t(Be),qe=ue("("+Fe(We).join("|")+")","g"),ze=ue("["+Fe(Be).join("")+"]","g"),Pe=ye?function(n){if(!n||ce.call(n)!=q)return false;var t=n.valueOf,e=vt(t)&&(e=ye(t))&&ye(e);return e?n==e||ye(n)==e:ht(n)
+}:ht,Ke=lt(function(n,t,e){me.call(n,e)?n[e]++:n[e]=1}),Le=lt(function(n,t,e){(me.call(n,e)?n[e]:n[e]=[]).push(t)}),Me=lt(function(n,t,e){n[e]=t}),Ve=Rt,Ue=vt(Ue=Zt.now)&&Ue||function(){return(new Zt).getTime()},Ge=8==Ee(d+"08")?Ee:function(n,t){return Ee(kt(n)?n.replace(I,""):n,t||0)};return J.after=function(n,t){if(!dt(t))throw new ie;return function(){return 1>--n?t.apply(this,arguments):void 0}},J.assign=U,J.at=function(n){for(var t=arguments,e=-1,r=ut(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Xt(t);++e<t;)u[e]=n[r[e]];
+return u},J.bind=Mt,J.bindAll=function(n){for(var t=1<arguments.length?ut(arguments,true,false,1):bt(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=ct(n[u],1,null,null,n)}return n},J.bindKey=function(n,t){return 2<arguments.length?ct(t,19,p(arguments,2),null,n):ct(t,3,null,null,n)},J.chain=function(n){return n=new Q(n),n.__chain__=true,n},J.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},J.compose=function(){for(var n=arguments,t=n.length;t--;)if(!dt(n[t]))throw new ie;
+return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},J.constant=function(n){return function(){return n}},J.countBy=Ke,J.create=function(n,t){var e=nt(n);return t?U(e,t):e},J.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e);if("object"!=r)return Jt(n);var u=Fe(n),o=u[0],i=n[o];return 1!=u.length||i!==i||wt(i)?function(t){for(var e=u.length,r=false;e--&&(r=ot(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],i===n&&(0!==i||1/i==1/n)
+}},J.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,ct(n,4,null,null,null,t)},J.debounce=Vt,J.defaults=_,J.defer=function(n){if(!dt(n))throw new ie;var t=p(arguments,1);return _e(function(){n.apply(v,t)},1)},J.delay=function(n,t){if(!dt(n))throw new ie;var e=p(arguments,2);return _e(function(){n.apply(v,e)},t)},J.difference=function(n){return rt(n,ut(arguments,true,true,1))},J.filter=Nt,J.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Rt(n,e,r)),ut(n,t)
+},J.forEach=St,J.forEachRight=Et,J.forIn=g,J.forInRight=function(n,t,e){var r=[];g(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},J.forOwn=h,J.forOwnRight=mt,J.functions=bt,J.groupBy=Le,J.indexBy=Me,J.initial=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return p(n,0,Se(Ie(0,u-r),u))},J.intersection=function(){for(var e=[],r=-1,u=arguments.length,i=a(),f=st(),p=f===n,s=a();++r<u;){var v=arguments[r];
+(Te(v)||yt(v))&&(e.push(v),i.push(p&&v.length>=b&&o(r?e[r]:s)))}var p=e[0],h=-1,g=p?p.length:0,y=[];n:for(;++h<g;){var m=i[0],v=p[h];if(0>(m?t(m,v):f(s,v))){for(r=u,(m||s).push(v);--r;)if(m=i[r],0>(m?t(m,v):f(e[r],v)))continue n;y.push(v)}}for(;u--;)(m=i[u])&&c(m);return l(i),l(s),y},J.invert=_t,J.invoke=function(n,t){var e=p(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,i=Xt(typeof o=="number"?o:0);return St(n,function(n){i[++r]=(u?t:n[t]).apply(n,e)}),i},J.keys=Fe,J.map=Rt,J.mapValues=function(n,t,e){var r={};
+return t=J.createCallback(t,e,3),h(n,function(n,e,u){r[e]=t(n,e,u)}),r},J.max=At,J.memoize=function(n,t){function e(){var r=e.cache,u=t?t.apply(this,arguments):m+arguments[0];return me.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!dt(n))throw new ie;return e.cache={},e},J.merge=function(n){var t=arguments,e=2;if(!wt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=p(arguments,1,e),u=-1,o=a(),i=a();++u<e;)it(n,t[u],r,o,i);
+return l(o),l(i),n},J.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a<o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n)});return o},J.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];g(n,function(n,t){u.push(t)});for(var u=rt(u,ut(arguments,true,false,1)),o=-1,i=u.length;++o<i;){var a=u[o];r[a]=n[a]}}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)||(r[e]=n)
+});return r},J.once=function(n){var t,e;if(!dt(n))throw new ie;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},J.pairs=function(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u},J.partial=function(n){return ct(n,16,p(arguments,1))},J.partialRight=function(n){return ct(n,32,null,p(arguments,1))},J.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ut(arguments,true,false,1),i=wt(n)?o.length:0;++u<i;){var a=o[u];a in n&&(r[a]=n[a])
+}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},J.pluck=Ve,J.property=Jt,J.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,i=t[e];++o<u;)n[o]===i&&(de.call(n,o--,1),u--);return n},J.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Ie(0,se((t-n)/(e||1)));for(var u=Xt(t);++r<t;)u[r]=n,n+=e;return u},J.reject=function(n,t,e){return t=J.createCallback(t,e,3),Nt(n,function(n,e,r){return!t(n,e,r)
+})},J.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=J.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),de.call(n,r--,1),u--);return o},J.rest=qt,J.shuffle=Tt,J.sortBy=function(n,t,e){var r=-1,o=Te(t),i=n?n.length:0,p=Xt(typeof i=="number"?i:0);for(o||(t=J.createCallback(t,e,3)),St(n,function(n,e,u){var i=p[++r]=f();o?i.m=Rt(t,function(t){return n[t]}):(i.m=a())[0]=t(n,e,u),i.n=r,i.o=n}),i=p.length,p.sort(u);i--;)n=p[i],p[i]=n.o,o||l(n.m),c(n);return p},J.tap=function(n,t){return t(n),n
+},J.throttle=function(n,t,e){var r=true,u=true;if(!dt(n))throw new ie;return false===e?r=false:wt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),L.leading=r,L.maxWait=t,L.trailing=u,Vt(n,t,L)},J.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Xt(n);for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},J.toArray=function(n){return n&&typeof n.length=="number"?p(n):xt(n)},J.transform=function(n,t,e,r){var u=Te(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=J.createCallback(t,r,4),(u?St:h)(n,function(n,r,u){return t(e,n,r,u)
+})),e},J.union=function(){return ft(ut(arguments,true,true))},J.uniq=Pt,J.values=xt,J.where=Nt,J.without=function(n){return rt(n,p(arguments,1))},J.wrap=function(n,t){return ct(t,16,[n])},J.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(Te(e)||yt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},J.zip=Kt,J.zipObject=Lt,J.collect=Rt,J.drop=qt,J.each=St,J.eachRight=Et,J.extend=U,J.methods=bt,J.object=Lt,J.select=Nt,J.tail=qt,J.unique=Pt,J.unzip=Kt,Gt(J),J.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Z(n,t,typeof e=="function"&&tt(e,r,1))
+},J.cloneDeep=function(n,t,e){return Z(n,true,typeof t=="function"&&tt(t,e,1))},J.contains=Ct,J.escape=function(n){return null==n?"":oe(n).replace(ze,pt)},J.every=Ot,J.find=It,J.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=J.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},J.findKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),h(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.findLast=function(n,t,e){var r;return t=J.createCallback(t,e,3),Et(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0
+}),r},J.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=J.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r;return-1},J.findLastKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),mt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.has=function(n,t){return n?me.call(n,t):false},J.identity=Ut,J.indexOf=Wt,J.isArguments=yt,J.isArray=Te,J.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&ce.call(n)==T||false},J.isDate=function(n){return n&&typeof n=="object"&&ce.call(n)==F||false
+},J.isElement=function(n){return n&&1===n.nodeType||false},J.isEmpty=function(n){var t=true;if(!n)return t;var e=ce.call(n),r=n.length;return e==$||e==P||e==D||e==q&&typeof r=="number"&&dt(n.splice)?!r:(h(n,function(){return t=false}),t)},J.isEqual=function(n,t,e,r){return ot(n,t,typeof e=="function"&&tt(e,r,2))},J.isFinite=function(n){return Ce(n)&&!Oe(parseFloat(n))},J.isFunction=dt,J.isNaN=function(n){return jt(n)&&n!=+n},J.isNull=function(n){return null===n},J.isNumber=jt,J.isObject=wt,J.isPlainObject=Pe,J.isRegExp=function(n){return n&&typeof n=="object"&&ce.call(n)==z||false
+},J.isString=kt,J.isUndefined=function(n){return typeof n=="undefined"},J.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Ie(0,r+e):Se(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},J.mixin=Gt,J.noConflict=function(){return e._=le,this},J.noop=Ht,J.now=Ue,J.parseInt=Ge,J.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Re(),Se(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):at(n,t)
+},J.reduce=Dt,J.reduceRight=$t,J.result=function(n,t){if(n){var e=n[t];return dt(e)?n[t]():e}},J.runInContext=s,J.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Fe(n).length},J.some=Ft,J.sortedIndex=zt,J.template=function(n,t,e){var r=J.templateSettings;n=oe(n||""),e=_({},e,r);var u,o=_({},e.imports,r.imports),r=Fe(o),o=xt(o),a=0,f=e.interpolate||S,l="__p+='",f=ue((e.escape||S).source+"|"+f.source+"|"+(f===N?x:S).source+"|"+(e.evaluate||S).source+"|$","g");n.replace(f,function(t,e,r,o,f,c){return r||(r=o),l+=n.slice(a,c).replace(R,i),e&&(l+="'+__e("+e+")+'"),f&&(u=true,l+="';"+f+";\n__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),a=c+t.length,t
+}),l+="';",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(w,""):l).replace(j,"$1").replace(k,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=ne(r,"return "+l).apply(v,o)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},J.unescape=function(n){return null==n?"":oe(n).replace(qe,gt)},J.uniqueId=function(n){var t=++y;return oe(null==n?"":n)+t
+},J.all=Ot,J.any=Ft,J.detect=It,J.findWhere=It,J.foldl=Dt,J.foldr=$t,J.include=Ct,J.inject=Dt,Gt(function(){var n={};return h(J,function(t,e){J.prototype[e]||(n[e]=t)}),n}(),false),J.first=Bt,J.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:v;return p(n,Ie(0,u-r))},J.sample=function(n,t,e){return n&&typeof n.length!="number"&&(n=xt(n)),null==t||e?n?n[at(0,n.length-1)]:v:(n=Tt(n),n.length=Se(Ie(0,t),n.length),n)
+},J.take=Bt,J.head=Bt,h(J,function(n,t){var e="sample"!==t;J.prototype[t]||(J.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new Q(o,u):o})}),J.VERSION="2.4.1",J.prototype.chain=function(){return this.__chain__=true,this},J.prototype.toString=function(){return oe(this.__wrapped__)},J.prototype.value=Qt,J.prototype.valueOf=Qt,St(["join","pop","shift"],function(n){var t=ae[n];J.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments);
+return n?new Q(e,n):e}}),St(["push","reverse","sort","unshift"],function(n){var t=ae[n];J.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),St(["concat","slice","splice"],function(n){var t=ae[n];J.prototype[n]=function(){return new Q(t.apply(this.__wrapped__,arguments),this.__chain__)}}),J}var v,h=[],g=[],y=0,m=+new Date+"",b=75,_=40,d=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",w=/\b__p\+='';/g,j=/\b(__p\+=)''\+/g,k=/(__e\(.*?\)|\b__t\))\+'';/g,x=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,C=/\w*$/,O=/^\s*function[ \n\r\t]+\w/,N=/<%=([\s\S]+?)%>/g,I=RegExp("^["+d+"]*0+(?=.$)"),S=/($^)/,E=/\bthis\b/,R=/['\n\r\t\u2028\u2029\\]/g,A="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),D="[object Arguments]",$="[object Array]",T="[object Boolean]",F="[object Date]",B="[object Function]",W="[object Number]",q="[object Object]",z="[object RegExp]",P="[object String]",K={};
+K[B]=false,K[D]=K[$]=K[T]=K[F]=K[W]=K[q]=K[z]=K[P]=true;var L={leading:false,maxWait:0,trailing:false},M={configurable:false,enumerable:false,value:null,writable:false},V={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},U={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},G=V[typeof window]&&window||this,H=V[typeof exports]&&exports&&!exports.nodeType&&exports,J=V[typeof module]&&module&&!module.nodeType&&module,Q=J&&J.exports===H&&H,X=V[typeof global]&&global;!X||X.global!==X&&X.window!==X||(G=X);
+var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G._=Y, define(function(){return Y})):H&&J?Q?(J.exports=Y)._=Y:H._=Y:G._=Y}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/modal.js b/src/main/resources/META-INF/resources/designer/lib/modal.js
new file mode 100644 (file)
index 0000000..a4ab332
--- /dev/null
@@ -0,0 +1,420 @@
+angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
+
+/**
+ * A helper, internal data structure that acts as a map but also allows getting / removing
+ * elements in the LIFO order
+ */
+  .factory('$$stackedMap', function () {
+    return {
+      createNew: function () {
+        var stack = [];
+
+        return {
+          add: function (key, value) {
+            stack.push({
+              key: key,
+              value: value
+            });
+          },
+          get: function (key) {
+            for (var i = 0; i < stack.length; i++) {
+              if (key == stack[i].key) {
+                return stack[i];
+              }
+            }
+          },
+          keys: function() {
+            var keys = [];
+            for (var i = 0; i < stack.length; i++) {
+              keys.push(stack[i].key);
+            }
+            return keys;
+          },
+          top: function () {
+            return stack[stack.length - 1];
+          },
+          remove: function (key) {
+            var idx = -1;
+            for (var i = 0; i < stack.length; i++) {
+              if (key == stack[i].key) {
+                idx = i;
+                break;
+              }
+            }
+            return stack.splice(idx, 1)[0];
+          },
+          removeTop: function () {
+            return stack.splice(stack.length - 1, 1)[0];
+          },
+          length: function () {
+            return stack.length;
+          }
+        };
+      }
+    };
+  })
+
+/**
+ * A helper directive for the $modal service. It creates a backdrop element.
+ */
+  .directive('modalBackdrop', ['$timeout', function ($timeout) {
+    return {
+      restrict: 'EA',
+      replace: true,
+      templateUrl: 'template/modal/backdrop.html',
+      link: function (scope, element, attrs) {
+        scope.backdropClass = attrs.backdropClass || '';
+
+        scope.animate = false;
+
+        //trigger CSS transitions
+        $timeout(function () {
+          scope.animate = true;
+        });
+      }
+    };
+  }])
+
+  .directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
+    return {
+      restrict: 'EA',
+      scope: {
+        index: '@',
+        animate: '='
+      },
+      replace: true,
+      transclude: true,
+      templateUrl: function(tElement, tAttrs) {
+        return tAttrs.templateUrl || 'template/modal/window.html';
+      },
+      link: function (scope, element, attrs) {
+        element.addClass(attrs.windowClass || '');
+        scope.size = attrs.size;
+
+        // moved from template to fix issue #2280
+        element.on('click', function(evt) {
+          scope.close(evt);
+        });
+
+        $timeout(function () {
+          // trigger CSS transitions
+          scope.animate = true;
+
+          /**
+           * Auto-focusing of a freshly-opened modal element causes any child elements
+           * with the autofocus attribute to lose focus. This is an issue on touch
+           * based devices which will show and then hide the onscreen keyboard.
+           * Attempts to refocus the autofocus element via JavaScript will not reopen
+           * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus
+           * the modal element if the modal does not contain an autofocus element.
+           */
+          if (!element[0].querySelectorAll('[autofocus]').length) {
+            element[0].focus();
+          }
+        });
+
+        scope.close = function (evt) {
+          var modal = $modalStack.getTop();
+          if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
+            evt.preventDefault();
+            evt.stopPropagation();
+            $modalStack.dismiss(modal.key, 'backdrop click');
+          }
+        };
+      }
+    };
+  }])
+
+  .directive('modalTransclude', function () {
+    return {
+      link: function($scope, $element, $attrs, controller, $transclude) {
+        $transclude($scope.$parent, function(clone) {
+          $element.empty();
+          $element.append(clone);
+        });
+      }
+    };
+  })
+
+  .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
+    function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
+
+      var OPENED_MODAL_CLASS = 'modal-open';
+
+      var backdropDomEl, backdropScope;
+      var openedWindows = $$stackedMap.createNew();
+      var $modalStack = {};
+
+      function backdropIndex() {
+        var topBackdropIndex = -1;
+        var opened = openedWindows.keys();
+        for (var i = 0; i < opened.length; i++) {
+          if (openedWindows.get(opened[i]).value.backdrop) {
+            topBackdropIndex = i;
+          }
+        }
+        return topBackdropIndex;
+      }
+
+      $rootScope.$watch(backdropIndex, function(newBackdropIndex){
+        if (backdropScope) {
+          backdropScope.index = newBackdropIndex;
+        }
+      });
+
+      function removeModalWindow(modalInstance) {
+
+        var body = $document.find('body').eq(0);
+        var modalWindow = openedWindows.get(modalInstance).value;
+
+        //clean up the stack
+        openedWindows.remove(modalInstance);
+
+        //remove window DOM element
+        removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, function() {
+          modalWindow.modalScope.$destroy();
+          body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
+          checkRemoveBackdrop();
+        });
+      }
+
+      function checkRemoveBackdrop() {
+          //remove backdrop if no longer needed
+          if (backdropDomEl && backdropIndex() == -1) {
+            var backdropScopeRef = backdropScope;
+            removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
+              backdropScopeRef.$destroy();
+              backdropScopeRef = null;
+            });
+            backdropDomEl = undefined;
+            backdropScope = undefined;
+          }
+      }
+
+      function removeAfterAnimate(domEl, scope, emulateTime, done) {
+        // Closing animation
+        scope.animate = false;
+
+        var transitionEndEventName = $transition.transitionEndEventName;
+        if (transitionEndEventName) {
+          // transition out
+          var timeout = $timeout(afterAnimating, emulateTime);
+
+          domEl.bind(transitionEndEventName, function () {
+            $timeout.cancel(timeout);
+            afterAnimating();
+            scope.$apply();
+          });
+        } else {
+          // Ensure this call is async
+          $timeout(afterAnimating);
+        }
+
+        function afterAnimating() {
+          if (afterAnimating.done) {
+            return;
+          }
+          afterAnimating.done = true;
+
+          domEl.remove();
+          if (done) {
+            done();
+          }
+        }
+      }
+
+      $document.bind('keydown', function (evt) {
+        var modal;
+
+        if (evt.which === 27) {
+          modal = openedWindows.top();
+          if (modal && modal.value.keyboard) {
+            evt.preventDefault();
+            $rootScope.$apply(function () {
+              $modalStack.dismiss(modal.key, 'escape key press');
+            });
+          }
+        }
+      });
+
+      $modalStack.open = function (modalInstance, modal) {
+
+        openedWindows.add(modalInstance, {
+          deferred: modal.deferred,
+          modalScope: modal.scope,
+          backdrop: modal.backdrop,
+          keyboard: modal.keyboard
+        });
+
+        var body = $document.find('body').eq(0),
+            currBackdropIndex = backdropIndex();
+
+        if (currBackdropIndex >= 0 && !backdropDomEl) {
+          backdropScope = $rootScope.$new(true);
+          backdropScope.index = currBackdropIndex;
+          var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
+          angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
+          backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
+          body.append(backdropDomEl);
+        }
+
+        var angularDomEl = angular.element('<div modal-window></div>');
+        angularDomEl.attr({
+          'template-url': modal.windowTemplateUrl,
+          'window-class': modal.windowClass,
+          'size': modal.size,
+          'index': openedWindows.length() - 1,
+          'animate': 'animate'
+        }).html(modal.content);
+
+        var modalDomEl = $compile(angularDomEl)(modal.scope);
+        openedWindows.top().value.modalDomEl = modalDomEl;
+        body.append(modalDomEl);
+        body.addClass(OPENED_MODAL_CLASS);
+      };
+
+      $modalStack.close = function (modalInstance, result) {
+        var modalWindow = openedWindows.get(modalInstance);
+        if (modalWindow) {
+          modalWindow.value.deferred.resolve(result);
+          removeModalWindow(modalInstance);
+        }
+      };
+
+      $modalStack.dismiss = function (modalInstance, reason) {
+        var modalWindow = openedWindows.get(modalInstance);
+        if (modalWindow) {
+          modalWindow.value.deferred.reject(reason);
+          removeModalWindow(modalInstance);
+        }
+      };
+
+      $modalStack.dismissAll = function (reason) {
+        var topModal = this.getTop();
+        while (topModal) {
+          this.dismiss(topModal.key, reason);
+          topModal = this.getTop();
+        }
+      };
+
+      $modalStack.getTop = function () {
+        return openedWindows.top();
+      };
+
+      return $modalStack;
+    }])
+
+  .provider('$modal', function () {
+
+    var $modalProvider = {
+      options: {
+        backdrop: true, //can be also false or 'static'
+        keyboard: true
+      },
+      $get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
+        function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
+
+          var $modal = {};
+
+          function getTemplatePromise(options) {
+            return options.template ? $q.when(options.template) :
+              $http.get(angular.isFunction(options.templateUrl) ? (options.templateUrl)() : options.templateUrl,
+                {cache: $templateCache}).then(function (result) {
+                  return result.data;
+              });
+          }
+
+          function getResolvePromises(resolves) {
+            var promisesArr = [];
+            angular.forEach(resolves, function (value) {
+              if (angular.isFunction(value) || angular.isArray(value)) {
+                promisesArr.push($q.when($injector.invoke(value)));
+              }
+            });
+            return promisesArr;
+          }
+
+          $modal.open = function (modalOptions) {
+
+            var modalResultDeferred = $q.defer();
+            var modalOpenedDeferred = $q.defer();
+
+            //prepare an instance of a modal to be injected into controllers and returned to a caller
+            var modalInstance = {
+              result: modalResultDeferred.promise,
+              opened: modalOpenedDeferred.promise,
+              close: function (result) {
+                $modalStack.close(modalInstance, result);
+              },
+              dismiss: function (reason) {
+                $modalStack.dismiss(modalInstance, reason);
+              }
+            };
+
+            //merge and clean up options
+            modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
+            modalOptions.resolve = modalOptions.resolve || {};
+
+            //verify options
+            if (!modalOptions.template && !modalOptions.templateUrl) {
+              throw new Error('One of template or templateUrl options is required.');
+            }
+
+            var templateAndResolvePromise =
+              $q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
+
+
+            templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
+
+              var modalScope = (modalOptions.scope || $rootScope).$new();
+              modalScope.$close = modalInstance.close;
+              modalScope.$dismiss = modalInstance.dismiss;
+
+              var ctrlInstance, ctrlLocals = {};
+              var resolveIter = 1;
+
+              //controllers
+              if (modalOptions.controller) {
+                ctrlLocals.$scope = modalScope;
+                ctrlLocals.$modalInstance = modalInstance;
+                angular.forEach(modalOptions.resolve, function (value, key) {
+                  ctrlLocals[key] = tplAndVars[resolveIter++];
+                });
+
+                ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
+                if (modalOptions.controllerAs) {
+                  modalScope[modalOptions.controllerAs] = ctrlInstance;
+                }
+              }
+
+              $modalStack.open(modalInstance, {
+                scope: modalScope,
+                deferred: modalResultDeferred,
+                content: tplAndVars[0],
+                backdrop: modalOptions.backdrop,
+                keyboard: modalOptions.keyboard,
+                backdropClass: modalOptions.backdropClass,
+                windowClass: modalOptions.windowClass,
+                windowTemplateUrl: modalOptions.windowTemplateUrl,
+                size: modalOptions.size
+              });
+
+            }, function resolveError(reason) {
+              modalResultDeferred.reject(reason);
+            });
+
+            templateAndResolvePromise.then(function () {
+              modalOpenedDeferred.resolve(true);
+            }, function () {
+              modalOpenedDeferred.reject(false);
+            });
+
+            return modalInstance;
+          };
+
+          return $modal;
+        }]
+    };
+
+    return $modalProvider;
+  });
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/moment.min.js b/src/main/resources/META-INF/resources/designer/lib/moment.min.js
new file mode 100644 (file)
index 0000000..024d488
--- /dev/null
@@ -0,0 +1,7 @@
+//! moment.js
+//! version : 2.9.0
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(a,b){return Bb.call(a,b)}function d(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function e(a){vb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}function f(a,b){var c=!0;return o(function(){return c&&(e(a),c=!1),b.apply(this,arguments)},b)}function g(a,b){sc[a]||(e(b),sc[a]=!0)}function h(a,b){return function(c){return r(a.call(this,c),b)}}function i(a,b){return function(c){return this.localeData().ordinal(a.call(this,c),b)}}function j(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function k(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function l(){}function m(a,b){b!==!1&&H(a),p(this,a),this._d=new Date(+a._d),uc===!1&&(uc=!0,vb.updateOffset(this),uc=!1)}function n(a){var b=A(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=vb.localeData(),this._bubble()}function o(a,b){for(var d in b)c(b,d)&&(a[d]=b[d]);return c(b,"toString")&&(a.toString=b.toString),c(b,"valueOf")&&(a.valueOf=b.valueOf),a}function p(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=b._pf),"undefined"!=typeof b._locale&&(a._locale=b._locale),Kb.length>0)for(c in Kb)d=Kb[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.length<b;)d="0"+d;return(e?c?"+":"":"-")+d}function s(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function t(a,b){var c;return b=M(b,a),a.isBefore(b)?c=s(a,b):(c=s(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c}function u(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(g(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=vb.duration(c,d),v(this,e,a),this}}function v(a,b,c,d){var e=b._milliseconds,f=b._days,g=b._months;d=null==d?!0:d,e&&a._d.setTime(+a._d+e*c),f&&pb(a,"Date",ob(a,"Date")+f*c),g&&nb(a,ob(a,"Month")+g*c),d&&vb.updateOffset(a,f||g)}function w(a){return"[object Array]"===Object.prototype.toString.call(a)}function x(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function y(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&C(a[d])!==C(b[d]))&&g++;return g+f}function z(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=lc[a]||mc[b]||b}return a}function A(a){var b,d,e={};for(d in a)c(a,d)&&(b=z(d),b&&(e[b]=a[d]));return e}function B(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}vb[b]=function(e,f){var g,h,i=vb._locale[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=vb().utc().set(d,a);return i.call(vb._locale,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function C(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function D(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function E(a,b,c){return jb(vb([a,11,31+b-c]),b,c).week}function F(a){return G(a)?366:365}function G(a){return a%4===0&&a%100!==0||a%400===0}function H(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[Db]<0||a._a[Db]>11?Db:a._a[Eb]<1||a._a[Eb]>D(a._a[Cb],a._a[Db])?Eb:a._a[Fb]<0||a._a[Fb]>24||24===a._a[Fb]&&(0!==a._a[Gb]||0!==a._a[Hb]||0!==a._a[Ib])?Fb:a._a[Gb]<0||a._a[Gb]>59?Gb:a._a[Hb]<0||a._a[Hb]>59?Hb:a._a[Ib]<0||a._a[Ib]>999?Ib:-1,a._pf._overflowDayOfYear&&(Cb>b||b>Eb)&&(b=Eb),a._pf.overflow=b)}function I(b){return null==b._isValid&&(b._isValid=!isNaN(b._d.getTime())&&b._pf.overflow<0&&!b._pf.empty&&!b._pf.invalidMonth&&!b._pf.nullInput&&!b._pf.invalidFormat&&!b._pf.userInvalidated,b._strict&&(b._isValid=b._isValid&&0===b._pf.charsLeftOver&&0===b._pf.unusedTokens.length&&b._pf.bigHour===a)),b._isValid}function J(a){return a?a.toLowerCase().replace("_","-"):a}function K(a){for(var b,c,d,e,f=0;f<a.length;){for(e=J(a[f]).split("-"),b=e.length,c=J(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=L(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&y(e,c,!0)>=b-1)break;b--}f++}return null}function L(a){var b=null;if(!Jb[a]&&Lb)try{b=vb.locale(),require("./locale/"+a),vb.locale(b)}catch(c){}return Jb[a]}function M(a,b){var c,d;return b._isUTC?(c=b.clone(),d=(vb.isMoment(a)||x(a)?+a:+vb(a))-+c,c._d.setTime(+c._d+d),vb.updateOffset(c,!1),c):vb(a).local()}function N(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function O(a){var b,c,d=a.match(Pb);for(b=0,c=d.length;c>b;b++)d[b]=rc[d[b]]?rc[d[b]]:N(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function P(a,b){return a.isValid()?(b=Q(b,a.localeData()),nc[b]||(nc[b]=O(b)),nc[b](a)):a.localeData().invalidDate()}function Q(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Qb.lastIndex=0;d>=0&&Qb.test(a);)a=a.replace(Qb,c),Qb.lastIndex=0,d-=1;return a}function R(a,b){var c,d=b._strict;switch(a){case"Q":return _b;case"DDDD":return bc;case"YYYY":case"GGGG":case"gggg":return d?cc:Tb;case"Y":case"G":case"g":return ec;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?dc:Ub;case"S":if(d)return _b;case"SS":if(d)return ac;case"SSS":if(d)return bc;case"DDD":return Sb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Wb;case"a":case"A":return b._locale._meridiemParse;case"x":return Zb;case"X":return $b;case"Z":case"ZZ":return Xb;case"T":return Yb;case"SSSS":return Vb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?ac:Rb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Rb;case"Do":return d?b._locale._ordinalParse:b._locale._ordinalParseLenient;default:return c=new RegExp($(Z(a.replace("\\","")),"i"))}}function S(a){a=a||"";var b=a.match(Xb)||[],c=b[b.length-1]||[],d=(c+"").match(jc)||["-",0,0],e=+(60*d[1])+C(d[2]);return"+"===d[0]?e:-e}function T(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[Db]=3*(C(b)-1));break;case"M":case"MM":null!=b&&(e[Db]=C(b)-1);break;case"MMM":case"MMMM":d=c._locale.monthsParse(b,a,c._strict),null!=d?e[Db]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[Eb]=C(b));break;case"Do":null!=b&&(e[Eb]=C(parseInt(b.match(/\d{1,2}/)[0],10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=C(b));break;case"YY":e[Cb]=vb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[Cb]=C(b);break;case"a":case"A":c._meridiem=b;break;case"h":case"hh":c._pf.bigHour=!0;case"H":case"HH":e[Fb]=C(b);break;case"m":case"mm":e[Gb]=C(b);break;case"s":case"ss":e[Hb]=C(b);break;case"S":case"SS":case"SSS":case"SSSS":e[Ib]=C(1e3*("0."+b));break;case"x":c._d=new Date(C(b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=S(b);break;case"dd":case"ddd":case"dddd":d=c._locale.weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=C(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=vb.parseTwoDigitYear(b)}}function U(a){var c,d,e,f,g,h,i;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[Cb],jb(vb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(g=a._locale._week.dow,h=a._locale._week.doy,d=b(c.gg,a._a[Cb],jb(vb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=kb(d,e,f,h,g),a._a[Cb]=i.year,a._dayOfYear=i.dayOfYear}function V(a){var c,d,e,f,g=[];if(!a._d){for(e=X(a),a._w&&null==a._a[Eb]&&null==a._a[Db]&&U(a),a._dayOfYear&&(f=b(a._a[Cb],e[Cb]),a._dayOfYear>F(f)&&(a._pf._overflowDayOfYear=!0),d=fb(f,0,a._dayOfYear),a._a[Db]=d.getUTCMonth(),a._a[Eb]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];24===a._a[Fb]&&0===a._a[Gb]&&0===a._a[Hb]&&0===a._a[Ib]&&(a._nextDay=!0,a._a[Fb]=0),a._d=(a._useUTC?fb:eb).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Fb]=24)}}function W(a){var b;a._d||(b=A(a._i),a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],V(a))}function X(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function Y(b){if(b._f===vb.ISO_8601)return void ab(b);b._a=[],b._pf.empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Q(b._f,b._locale).match(Pb)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(R(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&b._pf.unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),rc[f]?(d?b._pf.empty=!1:b._pf.unusedTokens.push(f),T(f,d,b)):b._strict&&!d&&b._pf.unusedTokens.push(f);b._pf.charsLeftOver=i-j,h.length>0&&b._pf.unusedInput.push(h),b._pf.bigHour===!0&&b._a[Fb]<=12&&(b._pf.bigHour=a),b._a[Fb]=k(b._locale,b._a[Fb],b._meridiem),V(b),H(b)}function Z(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function $(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function _(a){var b,c,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;f<a._f.length;f++)g=0,b=p({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._pf=d(),b._f=a._f[f],Y(b),I(b)&&(g+=b._pf.charsLeftOver,g+=10*b._pf.unusedTokens.length,b._pf.score=g,(null==e||e>g)&&(e=g,c=b));o(a,c||b)}function ab(a){var b,c,d=a._i,e=fc.exec(d);if(e){for(a._pf.iso=!0,b=0,c=hc.length;c>b;b++)if(hc[b][1].exec(d)){a._f=hc[b][0]+(e[6]||" ");break}for(b=0,c=ic.length;c>b;b++)if(ic[b][1].exec(d)){a._f+=ic[b][0];break}d.match(Xb)&&(a._f+="Z"),Y(a)}else a._isValid=!1}function bb(a){ab(a),a._isValid===!1&&(delete a._isValid,vb.createFromInputFallback(a))}function cb(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function db(b){var c,d=b._i;d===a?b._d=new Date:x(d)?b._d=new Date(+d):null!==(c=Mb.exec(d))?b._d=new Date(+c[1]):"string"==typeof d?bb(b):w(d)?(b._a=cb(d.slice(0),function(a){return parseInt(a,10)}),V(b)):"object"==typeof d?W(b):"number"==typeof d?b._d=new Date(d):vb.createFromInputFallback(b)}function eb(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function fb(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function gb(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function hb(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function ib(a,b,c){var d=vb.duration(a).abs(),e=Ab(d.as("s")),f=Ab(d.as("m")),g=Ab(d.as("h")),h=Ab(d.as("d")),i=Ab(d.as("M")),j=Ab(d.as("y")),k=e<oc.s&&["s",e]||1===f&&["m"]||f<oc.m&&["mm",f]||1===g&&["h"]||g<oc.h&&["hh",g]||1===h&&["d"]||h<oc.d&&["dd",h]||1===i&&["M"]||i<oc.M&&["MM",i]||1===j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,hb.apply({},k)}function jb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=vb(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function kb(a,b,c,d,e){var f,g,h=fb(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:F(a-1)+g}}function lb(b){var c,d=b._i,e=b._f;return b._locale=b._locale||vb.localeData(b._l),null===d||e===a&&""===d?vb.invalid({nullInput:!0}):("string"==typeof d&&(b._i=d=b._locale.preparse(d)),vb.isMoment(d)?new m(d,!0):(e?w(e)?_(b):Y(b):db(b),c=new m(b),c._nextDay&&(c.add(1,"d"),c._nextDay=a),c))}function mb(a,b){var c,d;if(1===b.length&&w(b[0])&&(b=b[0]),!b.length)return vb();for(c=b[0],d=1;d<b.length;++d)b[d][a](c)&&(c=b[d]);return c}function nb(a,b){var c;return"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),D(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function ob(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function pb(a,b,c){return"Month"===b?nb(a,c):a._d["set"+(a._isUTC?"UTC":"")+b](c)}function qb(a,b){return function(c){return null!=c?(pb(this,a,c),vb.updateOffset(this,b),this):ob(this,a)}}function rb(a){return 400*a/146097}function sb(a){return 146097*a/400}function tb(a){vb.duration.fn[a]=function(){return this._data[a]}}function ub(a){"undefined"==typeof ender&&(wb=zb.moment,zb.moment=a?f("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.",vb):vb)}for(var vb,wb,xb,yb="2.9.0",zb="undefined"==typeof global||"undefined"!=typeof window&&window!==global.window?this:global,Ab=Math.round,Bb=Object.prototype.hasOwnProperty,Cb=0,Db=1,Eb=2,Fb=3,Gb=4,Hb=5,Ib=6,Jb={},Kb=[],Lb="undefined"!=typeof module&&module&&module.exports,Mb=/^\/?Date\((\-?\d+)/i,Nb=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Ob=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Pb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,Qb=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Rb=/\d\d?/,Sb=/\d{1,3}/,Tb=/\d{1,4}/,Ub=/[+\-]?\d{1,6}/,Vb=/\d+/,Wb=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Xb=/Z|[\+\-]\d\d:?\d\d/gi,Yb=/T/i,Zb=/[\+\-]?\d+/,$b=/[\+\-]?\d+(\.\d{1,3})?/,_b=/\d/,ac=/\d\d/,bc=/\d{3}/,cc=/\d{4}/,dc=/[+-]?\d{6}/,ec=/[+-]?\d+/,fc=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,gc="YYYY-MM-DDTHH:mm:ssZ",hc=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],ic=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],jc=/([\+\-]|\d\d)/gi,kc=("Date|Hours|Minutes|Seconds|Milliseconds".split("|"),{Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6}),lc={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",Q:"quarter",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},mc={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},nc={},oc={s:45,m:45,h:22,d:26,M:11},pc="DDD w W M D d".split(" "),qc="M D H h m s w W".split(" "),rc={M:function(){return this.month()+1},MMM:function(a){return this.localeData().monthsShort(this,a)},MMMM:function(a){return this.localeData().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.localeData().weekdaysMin(this,a)},ddd:function(a){return this.localeData().weekdaysShort(this,a)},dddd:function(a){return this.localeData().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return r(this.year()%100,2)},YYYY:function(){return r(this.year(),4)},YYYYY:function(){return r(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+r(Math.abs(a),6)},gg:function(){return r(this.weekYear()%100,2)},gggg:function(){return r(this.weekYear(),4)},ggggg:function(){return r(this.weekYear(),5)},GG:function(){return r(this.isoWeekYear()%100,2)},GGGG:function(){return r(this.isoWeekYear(),4)},GGGGG:function(){return r(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return C(this.milliseconds()/100)},SS:function(){return r(C(this.milliseconds()/10),2)},SSS:function(){return r(this.milliseconds(),3)},SSSS:function(){return r(this.milliseconds(),3)},Z:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+":"+r(C(a)%60,2)},ZZ:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+r(C(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},x:function(){return this.valueOf()},X:function(){return this.unix()},Q:function(){return this.quarter()}},sc={},tc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"],uc=!1;pc.length;)xb=pc.pop(),rc[xb+"o"]=i(rc[xb],xb);for(;qc.length;)xb=qc.pop(),rc[xb+xb]=h(rc[xb],2);rc.DDDD=h(rc.DDD,3),o(l.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=vb.utc([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=vb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.apply(b,[c]):d},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",_ordinalParse:/\d{1,2}/,preparse:function(a){return a},postformat:function(a){return a},week:function(a){return jb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},firstDayOfWeek:function(){return this._week.dow},firstDayOfYear:function(){return this._week.doy},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),vb=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=c,g._l=e,g._strict=f,g._isUTC=!1,g._pf=d(),lb(g)},vb.suppressDeprecationWarnings=!1,vb.createFromInputFallback=f("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),vb.min=function(){var a=[].slice.call(arguments,0);return mb("isBefore",a)},vb.max=function(){var a=[].slice.call(arguments,0);return mb("isAfter",a)},vb.utc=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=c,g._strict=f,g._pf=d(),lb(g).utc()},vb.unix=function(a){return vb(1e3*a)},vb.duration=function(a,b){var d,e,f,g,h=a,i=null;return vb.isDuration(a)?h={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(h={},b?h[b]=a:h.milliseconds=a):(i=Nb.exec(a))?(d="-"===i[1]?-1:1,h={y:0,d:C(i[Eb])*d,h:C(i[Fb])*d,m:C(i[Gb])*d,s:C(i[Hb])*d,ms:C(i[Ib])*d}):(i=Ob.exec(a))?(d="-"===i[1]?-1:1,f=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*d},h={y:f(i[2]),M:f(i[3]),d:f(i[4]),h:f(i[5]),m:f(i[6]),s:f(i[7]),w:f(i[8])}):null==h?h={}:"object"==typeof h&&("from"in h||"to"in h)&&(g=t(vb(h.from),vb(h.to)),h={},h.ms=g.milliseconds,h.M=g.months),e=new n(h),vb.isDuration(a)&&c(a,"_locale")&&(e._locale=a._locale),e},vb.version=yb,vb.defaultFormat=gc,vb.ISO_8601=function(){},vb.momentProperties=Kb,vb.updateOffset=function(){},vb.relativeTimeThreshold=function(b,c){return oc[b]===a?!1:c===a?oc[b]:(oc[b]=c,!0)},vb.lang=f("moment.lang is deprecated. Use moment.locale instead.",function(a,b){return vb.locale(a,b)}),vb.locale=function(a,b){var c;return a&&(c="undefined"!=typeof b?vb.defineLocale(a,b):vb.localeData(a),c&&(vb.duration._locale=vb._locale=c)),vb._locale._abbr},vb.defineLocale=function(a,b){return null!==b?(b.abbr=a,Jb[a]||(Jb[a]=new l),Jb[a].set(b),vb.locale(a),Jb[a]):(delete Jb[a],null)},vb.langData=f("moment.langData is deprecated. Use moment.localeData instead.",function(a){return vb.localeData(a)}),vb.localeData=function(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return vb._locale;if(!w(a)){if(b=L(a))return b;a=[a]}return K(a)},vb.isMoment=function(a){return a instanceof m||null!=a&&c(a,"_isAMomentObject")},vb.isDuration=function(a){return a instanceof n};for(xb=tc.length-1;xb>=0;--xb)B(tc[xb]);vb.normalizeUnits=function(a){return z(a)},vb.invalid=function(a){var b=vb.utc(0/0);return null!=a?o(b._pf,a):b._pf.userInvalidated=!0,b},vb.parseZone=function(){return vb.apply(null,arguments).parseZone()},vb.parseTwoDigitYear=function(a){return C(a)+(C(a)>68?1900:2e3)},vb.isDate=x,o(vb.fn=m.prototype,{clone:function(){return vb(this)},valueOf:function(){return+this._d-6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=vb(this).utc();return 0<a.year()&&a.year()<=9999?"function"==typeof Date.prototype.toISOString?this.toDate().toISOString():P(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):P(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return I(this)},isDSTShifted:function(){return this._a?this.isValid()&&y(this._a,(this._isUTC?vb.utc(this._a):vb(this._a)).toArray())>0:!1},parsingFlags:function(){return o({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(a){return this.utcOffset(0,a)},local:function(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(this._dateUtcOffset(),"m")),this},format:function(a){var b=P(this,a||vb.defaultFormat);return this.localeData().postformat(b)},add:u(1,"add"),subtract:u(-1,"subtract"),diff:function(a,b,c){var d,e,f=M(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=z(b),"year"===b||"month"===b||"quarter"===b?(e=j(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:q(e)},from:function(a,b){return vb.duration({to:this,from:a}).locale(this.locale()).humanize(!b)},fromNow:function(a){return this.from(vb(),a)},calendar:function(a){var b=a||vb(),c=M(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this,vb(b)))},isLeapYear:function(){return G(this.year())},isDST:function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=gb(a,this.localeData()),this.add(a-b,"d")):b},month:qb("Month",!0),startOf:function(a){switch(a=z(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(b){return b=z(b),b===a||"millisecond"===b?this:this.startOf(b).add(1,"isoWeek"===b?"week":b).subtract(1,"ms")},isAfter:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+this>+a):(c=vb.isMoment(a)?+a:+vb(a),c<+this.clone().startOf(b))},isBefore:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+a>+this):(c=vb.isMoment(a)?+a:+vb(a),+this.clone().endOf(b)<c)},isBetween:function(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)},isSame:function(a,b){var c;return b=z(b||"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+this===+a):(c=+vb(a),+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))},min:f("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(a){return a=vb.apply(null,arguments),this>a?this:a}),max:f("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=vb.apply(null,arguments),a>this?this:a}),zone:f("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",function(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}),utcOffset:function(a,b){var c,d=this._offset||0;return null!=a?("string"==typeof a&&(a=S(a)),Math.abs(a)<16&&(a=60*a),!this._isUTC&&b&&(c=this._dateUtcOffset()),this._offset=a,this._isUTC=!0,null!=c&&this.add(c,"m"),d!==a&&(!b||this._changeInProgress?v(this,vb.duration(a-d,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,vb.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?d:this._dateUtcOffset()},isLocal:function(){return!this._isUTC},isUtcOffset:function(){return this._isUTC},isUtc:function(){return this._isUTC&&0===this._offset},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(S(this._i)),this},hasAlignedHourOffset:function(a){return a=a?vb(a).utcOffset():0,(this.utcOffset()-a)%60===0},daysInMonth:function(){return D(this.year(),this.month())},dayOfYear:function(a){var b=Ab((vb(this).startOf("day")-vb(this).startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=jb(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")},isoWeekYear:function(a){var b=jb(this,1,4).year;return null==a?b:this.add(a-b,"y")},week:function(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")},isoWeek:function(a){var b=jb(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")},weekday:function(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return E(this.year(),1,4)},weeksInYear:function(){var a=this.localeData()._week;return E(this.year(),a.dow,a.doy)},get:function(a){return a=z(a),this[a]()},set:function(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else a=z(a),"function"==typeof this[a]&&this[a](b);return this},locale:function(b){var c;return b===a?this._locale._abbr:(c=vb.localeData(b),null!=c&&(this._locale=c),this)},lang:f("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(b){return b===a?this.localeData():this.locale(b)}),localeData:function(){return this._locale},_dateUtcOffset:function(){return 15*-Math.round(this._d.getTimezoneOffset()/15)}}),vb.fn.millisecond=vb.fn.milliseconds=qb("Milliseconds",!1),vb.fn.second=vb.fn.seconds=qb("Seconds",!1),vb.fn.minute=vb.fn.minutes=qb("Minutes",!1),vb.fn.hour=vb.fn.hours=qb("Hours",!0),vb.fn.date=qb("Date",!0),vb.fn.dates=f("dates accessor is deprecated. Use date instead.",qb("Date",!0)),vb.fn.year=qb("FullYear",!0),vb.fn.years=f("years accessor is deprecated. Use year instead.",qb("FullYear",!0)),vb.fn.days=vb.fn.day,vb.fn.months=vb.fn.month,vb.fn.weeks=vb.fn.week,vb.fn.isoWeeks=vb.fn.isoWeek,vb.fn.quarters=vb.fn.quarter,vb.fn.toJSON=vb.fn.toISOString,vb.fn.isUTC=vb.fn.isUtc,o(vb.duration.fn=n.prototype,{_bubble:function(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;g.milliseconds=d%1e3,a=q(d/1e3),g.seconds=a%60,b=q(a/60),g.minutes=b%60,c=q(b/60),g.hours=c%24,e+=q(c/24),h=q(rb(e)),e-=q(sb(h)),f+=q(e/30),e%=30,h+=q(f/12),f%=12,g.days=e,g.months=f,g.years=h},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return q(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*C(this._months/12)
+},humanize:function(a){var b=ib(this,!a,this.localeData());return a&&(b=this.localeData().pastFuture(+this,b)),this.localeData().postformat(b)},add:function(a,b){var c=vb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=vb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=z(a),this[a.toLowerCase()+"s"]()},as:function(a){var b,c;if(a=z(a),"month"===a||"year"===a)return b=this._days+this._milliseconds/864e5,c=this._months+12*rb(b),"month"===a?c:c/12;switch(b=this._days+Math.round(sb(this._months/12)),a){case"week":return b/7+this._milliseconds/6048e5;case"day":return b+this._milliseconds/864e5;case"hour":return 24*b+this._milliseconds/36e5;case"minute":return 24*b*60+this._milliseconds/6e4;case"second":return 24*b*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*b*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+a)}},lang:vb.fn.lang,locale:vb.fn.locale,toIsoString:f("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"},localeData:function(){return this._locale},toJSON:function(){return this.toISOString()}}),vb.duration.fn.toString=vb.duration.fn.toISOString;for(xb in kc)c(kc,xb)&&tb(xb.toLowerCase());vb.duration.fn.asMilliseconds=function(){return this.as("ms")},vb.duration.fn.asSeconds=function(){return this.as("s")},vb.duration.fn.asMinutes=function(){return this.as("m")},vb.duration.fn.asHours=function(){return this.as("h")},vb.duration.fn.asDays=function(){return this.as("d")},vb.duration.fn.asWeeks=function(){return this.as("weeks")},vb.duration.fn.asMonths=function(){return this.as("M")},vb.duration.fn.asYears=function(){return this.as("y")},vb.locale("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===C(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),Lb?module.exports=vb:"function"==typeof define&&define.amd?(define(function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(zb.moment=wb),vb}),ub(!0)):ub()}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/multiselect.js b/src/main/resources/META-INF/resources/designer/lib/multiselect.js
new file mode 100644 (file)
index 0000000..9a50a18
--- /dev/null
@@ -0,0 +1,1716 @@
+/**
+ * Bootstrap Multiselect (https://github.com/davidstutz/bootstrap-multiselect)
+ *
+ * Apache License, Version 2.0:
+ * Copyright (c) 2012 - 2015 David Stutz
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a
+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * BSD 3-Clause License:
+ * Copyright (c) 2012 - 2015 David Stutz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    - Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *    - 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.
+ *    - Neither the name of David Stutz 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 HOLDER 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.
+ */
+!function ($) {
+    "use strict";// jshint ;_;
+
+    if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
+        ko.bindingHandlers.multiselect = {
+            after: ['options', 'value', 'selectedOptions', 'enable', 'disable'],
+
+            init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+                var $element = $(element);
+                var config = ko.toJS(valueAccessor());
+
+                $element.multiselect(config);
+
+                if (allBindings.has('options')) {
+                    var options = allBindings.get('options');
+                    if (ko.isObservable(options)) {
+                        ko.computed({
+                            read: function() {
+                                options();
+                                setTimeout(function() {
+                                    var ms = $element.data('multiselect');
+                                    if (ms)
+                                        ms.updateOriginalOptions();//Not sure how beneficial this is.
+                                    $element.multiselect('rebuild');
+                                }, 1);
+                            },
+                            disposeWhenNodeIsRemoved: element
+                        });
+                    }
+                }
+
+                //value and selectedOptions are two-way, so these will be triggered even by our own actions.
+                //It needs some way to tell if they are triggered because of us or because of outside change.
+                //It doesn't loop but it's a waste of processing.
+                if (allBindings.has('value')) {
+                    var value = allBindings.get('value');
+                    if (ko.isObservable(value)) {
+                        ko.computed({
+                            read: function() {
+                                value();
+                                setTimeout(function() {
+                                    $element.multiselect('refresh');
+                                }, 1);
+                            },
+                            disposeWhenNodeIsRemoved: element
+                        }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
+                    }
+                }
+
+                //Switched from arrayChange subscription to general subscription using 'refresh'.
+                //Not sure performance is any better using 'select' and 'deselect'.
+                if (allBindings.has('selectedOptions')) {
+                    var selectedOptions = allBindings.get('selectedOptions');
+                    if (ko.isObservable(selectedOptions)) {
+                        ko.computed({
+                            read: function() {
+                                selectedOptions();
+                                setTimeout(function() {
+                                    $element.multiselect('refresh');
+                                }, 1);
+                            },
+                            disposeWhenNodeIsRemoved: element
+                        }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
+                    }
+                }
+
+                var setEnabled = function (enable) {
+                    setTimeout(function () {
+                        if (enable)
+                            $element.multiselect('enable');
+                        else
+                            $element.multiselect('disable');
+                    });
+                };
+
+                if (allBindings.has('enable')) {
+                    var enable = allBindings.get('enable');
+                    if (ko.isObservable(enable)) {
+                        ko.computed({
+                            read: function () {
+                                setEnabled(enable());
+                            },
+                            disposeWhenNodeIsRemoved: element
+                        }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
+                    } else {
+                        setEnabled(enable);
+                    }
+                }
+
+                if (allBindings.has('disable')) {
+                    var disable = allBindings.get('disable');
+                    if (ko.isObservable(disable)) {
+                        ko.computed({
+                            read: function () {
+                                setEnabled(!disable());
+                            },
+                            disposeWhenNodeIsRemoved: element
+                        }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
+                    } else {
+                        setEnabled(!disable);
+                    }
+                }
+
+                ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+                    $element.multiselect('destroy');
+                });
+            },
+
+            update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
+                var $element = $(element);
+                var config = ko.toJS(valueAccessor());
+
+                $element.multiselect('setOptions', config);
+                $element.multiselect('rebuild');
+            }
+        };
+    }
+
+    function forEach(array, callback) {
+        for (var index = 0; index < array.length; ++index) {
+            callback(array[index], index);
+        }
+    }
+
+    /**
+     * Constructor to create a new multiselect using the given select.
+     *
+     * @param {jQuery} select
+     * @param {Object} options
+     * @returns {Multiselect}
+     */
+    function Multiselect(select, options) {
+
+        this.$select = $(select);
+        this.options = this.mergeOptions($.extend({}, options, this.$select.data()));
+
+        // Placeholder via data attributes
+        if (this.$select.attr("data-placeholder")) {
+            this.options.nonSelectedText = this.$select.data("placeholder");
+        }
+
+        // Initialization.
+        // We have to clone to create a new reference.
+        this.originalOptions = this.$select.clone()[0].options;
+        this.query = '';
+        this.searchTimeout = null;
+        this.lastToggledInput = null;
+
+        this.options.multiple = this.$select.attr('multiple') === "multiple";
+        this.options.onChange = $.proxy(this.options.onChange, this);
+        this.options.onSelectAll = $.proxy(this.options.onSelectAll, this);
+        this.options.onDeselectAll = $.proxy(this.options.onDeselectAll, this);
+        this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
+        this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
+        this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this);
+        this.options.onDropdownHidden = $.proxy(this.options.onDropdownHidden, this);
+        this.options.onInitialized = $.proxy(this.options.onInitialized, this);
+        this.options.onFiltering = $.proxy(this.options.onFiltering, this);
+
+        // Build select all if enabled.
+        this.buildContainer();
+        this.buildButton();
+        this.buildDropdown();
+        this.buildSelectAll();
+        this.buildDropdownOptions();
+        this.buildFilter();
+
+        this.updateButtonText();
+        this.updateSelectAll(true);
+
+        if (this.options.enableClickableOptGroups && this.options.multiple) {
+            this.updateOptGroups();
+        }
+
+        this.options.wasDisabled = this.$select.prop('disabled');
+        if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
+            this.disable();
+        }
+
+        this.$select.wrap('<span class="multiselect-native-select" />').after(this.$container);
+        this.options.onInitialized(this.$select, this.$container);
+    }
+
+    Multiselect.prototype = {
+
+        defaults: {
+            /**
+             * Default text function will either print 'None selected' in case no
+             * option is selected or a list of the selected options up to a length
+             * of 3 selected options.
+             *
+             * @param {jQuery} options
+             * @param {jQuery} select
+             * @returns {String}
+             */
+            buttonText: function(options, select) {
+                if (this.disabledText.length > 0
+                        && (select.prop('disabled') || (options.length == 0 && this.disableIfEmpty)))  {
+
+                    return this.disabledText;
+                }
+                else if (options.length === 0) {
+                    return this.nonSelectedText;
+                }
+                else if (this.allSelectedText
+                        && options.length === $('option', $(select)).length
+                        && $('option', $(select)).length !== 1
+                        && this.multiple) {
+
+                    if (this.selectAllNumber) {
+                        return this.allSelectedText + ' (' + options.length + ')';
+                    }
+                    else {
+                        return this.allSelectedText;
+                    }
+                }
+                else if (options.length > this.numberDisplayed) {
+                    return options.length + ' ' + this.nSelectedText;
+                }
+                else {
+                    var selected = '';
+                    var delimiter = this.delimiterText;
+
+                    options.each(function() {
+                        var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
+                        selected += label + delimiter;
+                    });
+
+                    return selected.substr(0, selected.length - this.delimiterText.length);
+                }
+            },
+            /**
+             * Updates the title of the button similar to the buttonText function.
+             *
+             * @param {jQuery} options
+             * @param {jQuery} select
+             * @returns {@exp;selected@call;substr}
+             */
+            buttonTitle: function(options, select) {
+                if (options.length === 0) {
+                    return this.nonSelectedText;
+                }
+                else {
+                    var selected = '';
+                    var delimiter = this.delimiterText;
+
+                    options.each(function () {
+                        var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
+                        selected += label + delimiter;
+                    });
+                    return selected.substr(0, selected.length - this.delimiterText.length);
+                }
+            },
+            checkboxName: function(option) {
+                return false; // no checkbox name
+            },
+            /**
+             * Create a label.
+             *
+             * @param {jQuery} element
+             * @returns {String}
+             */
+            optionLabel: function(element){
+                return $(element).attr('label') || $(element).text();
+            },
+            /**
+             * Create a class.
+             *
+             * @param {jQuery} element
+             * @returns {String}
+             */
+            optionClass: function(element) {
+                return $(element).attr('class') || '';
+            },
+            /**
+             * Triggered on change of the multiselect.
+             *
+             * Not triggered when selecting/deselecting options manually.
+             *
+             * @param {jQuery} option
+             * @param {Boolean} checked
+             */
+            onChange : function(option, checked) {
+
+            },
+            /**
+             * Triggered when the dropdown is shown.
+             *
+             * @param {jQuery} event
+             */
+            onDropdownShow: function(event) {
+
+            },
+            /**
+             * Triggered when the dropdown is hidden.
+             *
+             * @param {jQuery} event
+             */
+            onDropdownHide: function(event) {
+
+            },
+            /**
+             * Triggered after the dropdown is shown.
+             *
+             * @param {jQuery} event
+             */
+            onDropdownShown: function(event) {
+
+            },
+            /**
+             * Triggered after the dropdown is hidden.
+             *
+             * @param {jQuery} event
+             */
+            onDropdownHidden: function(event) {
+
+            },
+            /**
+             * Triggered on select all.
+             */
+            onSelectAll: function() {
+
+            },
+            /**
+             * Triggered on deselect all.
+             */
+            onDeselectAll: function() {
+
+            },
+            /**
+             * Triggered after initializing.
+             *
+             * @param {jQuery} $select
+             * @param {jQuery} $container
+             */
+            onInitialized: function($select, $container) {
+
+            },
+            /**
+             * Triggered on filtering.
+             *
+             * @param {jQuery} $filter
+             */
+            onFiltering: function($filter) {
+
+            },
+            enableHTML: false,
+            buttonClass: 'btn btn-default',
+            inheritClass: false,
+            buttonWidth: 'auto',
+            buttonContainer: '<div class="btn-group" />',
+            dropRight: false,
+            dropUp: false,
+            selectedClass: 'active',
+            // Maximum height of the dropdown menu.
+            // If maximum height is exceeded a scrollbar will be displayed.
+            maxHeight: false,
+            includeSelectAllOption: false,
+            includeSelectAllIfMoreThan: 0,
+            selectAllText: ' Select all',
+            selectAllValue: 'multiselect-all',
+            selectAllName: false,
+            selectAllNumber: true,
+            selectAllJustVisible: true,
+            enableFiltering: false,
+            enableCaseInsensitiveFiltering: false,
+            enableFullValueFiltering: false,
+            enableClickableOptGroups: false,
+            enableCollapsibleOptGroups: false,
+            filterPlaceholder: 'Search',
+            // possible options: 'text', 'value', 'both'
+            filterBehavior: 'text',
+            includeFilterClearBtn: true,
+            preventInputChangeEvent: false,
+            nonSelectedText: 'None selected',
+            nSelectedText: 'selected',
+            allSelectedText: 'All selected',
+            numberDisplayed: 3,
+            disableIfEmpty: false,
+            disabledText: '',
+            delimiterText: ', ',
+            templates: {
+                button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"><span class="multiselect-selected-text"></span> <b class="caret"></b></button>',
+                ul: '<ul class="multiselect-container dropdown-menu"></ul>',
+                filter: '<li class="multiselect-item multiselect-filter"><div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>',
+                filterClearBtn: '<span class="input-group-btn"><button class="btn btn-default multiselect-clear-filter" type="button"><i class="glyphicon glyphicon-remove-circle"></i></button></span>',
+                li: '<li><a tabindex="0"><label></label></a></li>',
+                divider: '<li class="multiselect-item divider"></li>',
+                liGroup: '<li class="multiselect-item multiselect-group"><label></label></li>'
+            }
+        },
+
+        constructor: Multiselect,
+
+        /**
+         * Builds the container of the multiselect.
+         */
+        buildContainer: function() {
+            this.$container = $(this.options.buttonContainer);
+            this.$container.on('show.bs.dropdown', this.options.onDropdownShow);
+            this.$container.on('hide.bs.dropdown', this.options.onDropdownHide);
+            this.$container.on('shown.bs.dropdown', this.options.onDropdownShown);
+            this.$container.on('hidden.bs.dropdown', this.options.onDropdownHidden);
+        },
+
+        /**
+         * Builds the button of the multiselect.
+         */
+        buildButton: function() {
+            this.$button = $(this.options.templates.button).addClass(this.options.buttonClass);
+            if (this.$select.attr('class') && this.options.inheritClass) {
+                this.$button.addClass(this.$select.attr('class'));
+            }
+            // Adopt active state.
+            if (this.$select.prop('disabled')) {
+                this.disable();
+            }
+            else {
+                this.enable();
+            }
+
+            // Manually add button width if set.
+            if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') {
+                this.$button.css({
+                    'width' : '100%', //this.options.buttonWidth,
+                    'overflow' : 'hidden',
+                    'text-overflow' : 'ellipsis'
+                });
+                this.$container.css({
+                    'width': this.options.buttonWidth
+                });
+            }
+
+            // Keep the tab index from the select.
+            var tabindex = this.$select.attr('tabindex');
+            if (tabindex) {
+                this.$button.attr('tabindex', tabindex);
+            }
+
+            this.$container.prepend(this.$button);
+        },
+
+        /**
+         * Builds the ul representing the dropdown menu.
+         */
+        buildDropdown: function() {
+
+            // Build ul.
+            this.$ul = $(this.options.templates.ul);
+
+            if (this.options.dropRight) {
+                this.$ul.addClass('pull-right');
+            }
+
+            // Set max height of dropdown menu to activate auto scrollbar.
+            if (this.options.maxHeight) {
+                // TODO: Add a class for this option to move the css declarations.
+                this.$ul.css({
+                    'max-height': this.options.maxHeight + 'px',
+                    'overflow-y': 'auto',
+                    'overflow-x': 'hidden'
+                });
+            }
+
+            if (this.options.dropUp) {
+
+                var height = Math.min(this.options.maxHeight, $('option[data-role!="divider"]', this.$select).length*26 + $('option[data-role="divider"]', this.$select).length*19 + (this.options.includeSelectAllOption ? 26 : 0) + (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering ? 44 : 0));
+                var moveCalc = height + 34;
+
+                this.$ul.css({
+                    'max-height': height + 'px',
+                    'overflow-y': 'auto',
+                    'overflow-x': 'hidden',
+                    'margin-top': "-" + moveCalc + 'px'
+                });
+            }
+
+            this.$container.append(this.$ul);
+        },
+
+        /**
+         * Build the dropdown options and binds all necessary events.
+         *
+         * Uses createDivider and createOptionValue to create the necessary options.
+         */
+        buildDropdownOptions: function() {
+
+            this.$select.children().each($.proxy(function(index, element) {
+
+                var $element = $(element);
+                // Support optgroups and options without a group simultaneously.
+                var tag = $element.prop('tagName')
+                    .toLowerCase();
+
+                if ($element.prop('value') === this.options.selectAllValue) {
+                    return;
+                }
+
+                if (tag === 'optgroup') {
+                    this.createOptgroup(element);
+                }
+                else if (tag === 'option') {
+
+                    if ($element.data('role') === 'divider') {
+                        this.createDivider();
+                    }
+                    else {
+                        this.createOptionValue(element);
+                    }
+
+                }
+
+                // Other illegal tags will be ignored.
+            }, this));
+
+            // Bind the change event on the dropdown elements.
+            $('li:not(.multiselect-group) input', this.$ul).on('change', $.proxy(function(event) {
+                var $target = $(event.target);
+
+                var checked = $target.prop('checked') || false;
+                var isSelectAllOption = $target.val() === this.options.selectAllValue;
+
+                // Apply or unapply the configured selected class.
+                if (this.options.selectedClass) {
+                    if (checked) {
+                        $target.closest('li')
+                            .addClass(this.options.selectedClass);
+                    }
+                    else {
+                        $target.closest('li')
+                            .removeClass(this.options.selectedClass);
+                    }
+                }
+
+                // Get the corresponding option.
+                var value = $target.val();
+                var $option = this.getOptionByValue(value);
+
+                var $optionsNotThis = $('option', this.$select).not($option);
+                var $checkboxesNotThis = $('input', this.$container).not($target);
+
+                if (isSelectAllOption) {
+
+                    if (checked) {
+                        this.selectAll(this.options.selectAllJustVisible, true);
+                    }
+                    else {
+                        this.deselectAll(this.options.selectAllJustVisible, true);
+                    }
+                }
+                else {
+                    if (checked) {
+                        $option.prop('selected', true);
+
+                        if (this.options.multiple) {
+                            // Simply select additional option.
+                            $option.prop('selected', true);
+                        }
+                        else {
+                            // Unselect all other options and corresponding checkboxes.
+                            if (this.options.selectedClass) {
+                                $($checkboxesNotThis).closest('li').removeClass(this.options.selectedClass);
+                            }
+
+                            $($checkboxesNotThis).prop('checked', false);
+                            $optionsNotThis.prop('selected', false);
+
+                            // It's a single selection, so close.
+                            this.$button.click();
+                        }
+
+                        if (this.options.selectedClass === "active") {
+                            $optionsNotThis.closest("a").css("outline", "");
+                        }
+                    }
+                    else {
+                        // Unselect option.
+                        $option.prop('selected', false);
+                    }
+
+                    // To prevent select all from firing onChange: #575
+                    this.options.onChange($option, checked);
+
+                    // Do not update select all or optgroups on select all change!
+                    this.updateSelectAll();
+
+                    if (this.options.enableClickableOptGroups && this.options.multiple) {
+                        this.updateOptGroups();
+                    }
+                }
+
+                this.$select.change();
+                this.updateButtonText();
+
+                if(this.options.preventInputChangeEvent) {
+                    return false;
+                }
+            }, this));
+
+            $('li a', this.$ul).on('mousedown', function(e) {
+                if (e.shiftKey) {
+                    // Prevent selecting text by Shift+click
+                    return false;
+                }
+            });
+
+            $('li a', this.$ul).on('touchstart click', $.proxy(function(event) {
+                event.stopPropagation();
+
+                var $target = $(event.target);
+
+                if (event.shiftKey && this.options.multiple) {
+                    if($target.is("label")){ // Handles checkbox selection manually (see https://github.com/davidstutz/bootstrap-multiselect/issues/431)
+                        event.preventDefault();
+                        $target = $target.find("input");
+                        $target.prop("checked", !$target.prop("checked"));
+                    }
+                    var checked = $target.prop('checked') || false;
+
+                    if (this.lastToggledInput !== null && this.lastToggledInput !== $target) { // Make sure we actually have a range
+                        var from = $target.closest("li").index();
+                        var to = this.lastToggledInput.closest("li").index();
+
+                        if (from > to) { // Swap the indices
+                            var tmp = to;
+                            to = from;
+                            from = tmp;
+                        }
+
+                        // Make sure we grab all elements since slice excludes the last index
+                        ++to;
+
+                        // Change the checkboxes and underlying options
+                        var range = this.$ul.find("li").slice(from, to).find("input");
+
+                        range.prop('checked', checked);
+
+                        if (this.options.selectedClass) {
+                            range.closest('li')
+                                .toggleClass(this.options.selectedClass, checked);
+                        }
+
+                        for (var i = 0, j = range.length; i < j; i++) {
+                            var $checkbox = $(range[i]);
+
+                            var $option = this.getOptionByValue($checkbox.val());
+
+                            $option.prop('selected', checked);
+                        }
+                    }
+
+                    // Trigger the select "change" event
+                    $target.trigger("change");
+                }
+
+                // Remembers last clicked option
+                if($target.is("input") && !$target.closest("li").is(".multiselect-item")){
+                    this.lastToggledInput = $target;
+                }
+
+                $target.blur();
+            }, this));
+
+            // Keyboard support.
+            this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
+                if ($('input[type="text"]', this.$container).is(':focus')) {
+                    return;
+                }
+
+                if (event.keyCode === 9 && this.$container.hasClass('open')) {
+                    this.$button.click();
+                }
+                else {
+                    var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible");
+
+                    if (!$items.length) {
+                        return;
+                    }
+
+                    var index = $items.index($items.filter(':focus'));
+
+                    // Navigation up.
+                    if (event.keyCode === 38 && index > 0) {
+                        index--;
+                    }
+                    // Navigate down.
+                    else if (event.keyCode === 40 && index < $items.length - 1) {
+                        index++;
+                    }
+                    else if (!~index) {
+                        index = 0;
+                    }
+
+                    var $current = $items.eq(index);
+                    $current.focus();
+
+                    if (event.keyCode === 32 || event.keyCode === 13) {
+                        var $checkbox = $current.find('input');
+
+                        $checkbox.prop("checked", !$checkbox.prop("checked"));
+                        $checkbox.change();
+                    }
+
+                    event.stopPropagation();
+                    event.preventDefault();
+                }
+            }, this));
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                $("li.multiselect-group input", this.$ul).on("change", $.proxy(function(event) {
+                    event.stopPropagation();
+
+                    var $target = $(event.target);
+                    var checked = $target.prop('checked') || false;
+
+                    var $li = $(event.target).closest('li');
+                    var $group = $li.nextUntil("li.multiselect-group")
+                        .not('.multiselect-filter-hidden')
+                        .not('.disabled');
+
+                    var $inputs = $group.find("input");
+
+                    var values = [];
+                    var $options = [];
+
+                    if (this.options.selectedClass) {
+                        if (checked) {
+                            $li.addClass(this.options.selectedClass);
+                        }
+                        else {
+                            $li.removeClass(this.options.selectedClass);
+                        }
+                    }
+
+                    $.each($inputs, $.proxy(function(index, input) {
+                        var value = $(input).val();
+                        var $option = this.getOptionByValue(value);
+
+                        if (checked) {
+                            $(input).prop('checked', true);
+                            $(input).closest('li')
+                                .addClass(this.options.selectedClass);
+
+                            $option.prop('selected', true);
+                        }
+                        else {
+                            $(input).prop('checked', false);
+                            $(input).closest('li')
+                                .removeClass(this.options.selectedClass);
+
+                            $option.prop('selected', false);
+                        }
+
+                        $options.push(this.getOptionByValue(value));
+                    }, this))
+
+                    // Cannot use select or deselect here because it would call updateOptGroups again.
+
+                    this.options.onChange($options, checked);
+
+                    this.updateButtonText();
+                    this.updateSelectAll();
+                }, this));
+            }
+
+            if (this.options.enableCollapsibleOptGroups && this.options.multiple) {
+                $("li.multiselect-group .caret-container", this.$ul).on("click", $.proxy(function(event) {
+                    var $li = $(event.target).closest('li');
+                    var $inputs = $li.nextUntil("li.multiselect-group")
+                            .not('.multiselect-filter-hidden');
+
+                    var visible = true;
+                    $inputs.each(function() {
+                        visible = visible && $(this).is(':visible');
+                    });
+
+                    if (visible) {
+                        $inputs.hide()
+                            .addClass('multiselect-collapsible-hidden');
+                    }
+                    else {
+                        $inputs.show()
+                            .removeClass('multiselect-collapsible-hidden');
+                    }
+                }, this));
+
+                $("li.multiselect-all", this.$ul).css('background', '#f3f3f3').css('border-bottom', '1px solid #eaeaea');
+                $("li.multiselect-all > a > label.checkbox", this.$ul).css('padding', '3px 20px 3px 35px');
+                $("li.multiselect-group > a > input", this.$ul).css('margin', '4px 0px 5px -20px');
+            }
+        },
+
+        /**
+         * Create an option using the given select option.
+         *
+         * @param {jQuery} element
+         */
+        createOptionValue: function(element) {
+            var $element = $(element);
+            if ($element.is(':selected')) {
+                $element.prop('selected', true);
+            }
+
+            // Support the label attribute on options.
+            var label = this.options.optionLabel(element);
+            var classes = this.options.optionClass(element);
+            var value = $element.val();
+            var inputType = this.options.multiple ? "checkbox" : "radio";
+
+            var $li = $(this.options.templates.li);
+            var $label = $('label', $li);
+            $label.addClass(inputType);
+            $li.addClass(classes);
+
+            if (this.options.enableHTML) {
+                $label.html(" " + label);
+            }
+            else {
+                $label.text(" " + label);
+            }
+
+            var $checkbox = $('<input/>').attr('type', inputType);
+
+            var name = this.options.checkboxName($element);
+            if (name) {
+                $checkbox.attr('name', name);
+            }
+
+            $label.prepend($checkbox);
+
+            var selected = $element.prop('selected') || false;
+            $checkbox.val(value);
+
+            if (value === this.options.selectAllValue) {
+                $li.addClass("multiselect-item multiselect-all");
+                $checkbox.parent().parent()
+                    .addClass('multiselect-all');
+            }
+
+            $label.attr('title', $element.attr('title'));
+
+            this.$ul.append($li);
+
+            if ($element.is(':disabled')) {
+                $checkbox.attr('disabled', 'disabled')
+                    .prop('disabled', true)
+                    .closest('a')
+                    .attr("tabindex", "-1")
+                    .closest('li')
+                    .addClass('disabled');
+            }
+
+            $checkbox.prop('checked', selected);
+
+            if (selected && this.options.selectedClass) {
+                $checkbox.closest('li')
+                    .addClass(this.options.selectedClass);
+            }
+        },
+
+        /**
+         * Creates a divider using the given select option.
+         *
+         * @param {jQuery} element
+         */
+        createDivider: function(element) {
+            var $divider = $(this.options.templates.divider);
+            this.$ul.append($divider);
+        },
+
+        /**
+         * Creates an optgroup.
+         *
+         * @param {jQuery} group
+         */
+        createOptgroup: function(group) {
+            var label = $(group).attr("label");
+            var value = $(group).attr("value");
+            var $li = $('<li class="multiselect-item multiselect-group"><a href="javascript:void(0);"><label><b></b></label></a></li>');
+
+            var classes = this.options.optionClass(group);
+            $li.addClass(classes);
+
+            if (this.options.enableHTML) {
+                $('label b', $li).html(" " + label);
+            }
+            else {
+                $('label b', $li).text(" " + label);
+            }
+
+            if (this.options.enableCollapsibleOptGroups && this.options.multiple) {
+                $('a', $li).append('<span class="caret-container"><b class="caret"></b></span>');
+            }
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                $('a label', $li).prepend('<input type="checkbox" value="' + value + '"/>');
+            }
+
+            if ($(group).is(':disabled')) {
+                $li.addClass('disabled');
+            }
+
+            this.$ul.append($li);
+
+            $("option", group).each($.proxy(function($, group) {
+                this.createOptionValue(group);
+            }, this))
+        },
+
+        /**
+         * Build the select all.
+         *
+         * Checks if a select all has already been created.
+         */
+        buildSelectAll: function() {
+            if (typeof this.options.selectAllValue === 'number') {
+                this.options.selectAllValue = this.options.selectAllValue.toString();
+            }
+
+            var alreadyHasSelectAll = this.hasSelectAll();
+
+            if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
+                    && $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) {
+
+                // Check whether to add a divider after the select all.
+                if (this.options.includeSelectAllDivider) {
+                    this.$ul.prepend($(this.options.templates.divider));
+                }
+
+                var $li = $(this.options.templates.li);
+                $('label', $li).addClass("checkbox");
+
+                if (this.options.enableHTML) {
+                    $('label', $li).html(" " + this.options.selectAllText);
+                }
+                else {
+                    $('label', $li).text(" " + this.options.selectAllText);
+                }
+
+                if (this.options.selectAllName) {
+                    $('label', $li).prepend('<input type="checkbox" name="' + this.options.selectAllName + '" />');
+                }
+                else {
+                    $('label', $li).prepend('<input type="checkbox" />');
+                }
+
+                var $checkbox = $('input', $li);
+                $checkbox.val(this.options.selectAllValue);
+
+                $li.addClass("multiselect-item multiselect-all");
+                $checkbox.parent().parent()
+                    .addClass('multiselect-all');
+
+                this.$ul.prepend($li);
+
+                $checkbox.prop('checked', false);
+            }
+        },
+
+        /**
+         * Builds the filter.
+         */
+        buildFilter: function() {
+
+            // Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength.
+            if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) {
+                var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering);
+
+                if (this.$select.find('option').length >= enableFilterLength) {
+
+                    this.$filter = $(this.options.templates.filter);
+                    $('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
+
+                    // Adds optional filter clear button
+                    if(this.options.includeFilterClearBtn) {
+                        var clearBtn = $(this.options.templates.filterClearBtn);
+                        clearBtn.on('click', $.proxy(function(event){
+                            clearTimeout(this.searchTimeout);
+
+                            this.$filter.find('.multiselect-search').val('');
+                            $('li', this.$ul).show().removeClass('multiselect-filter-hidden');
+
+                            this.updateSelectAll();
+
+                            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                                this.updateOptGroups();
+                            }
+
+                        }, this));
+                        this.$filter.find('.input-group').append(clearBtn);
+                    }
+
+                    this.$ul.prepend(this.$filter);
+
+                    this.$filter.val(this.query).on('click', function(event) {
+                        event.stopPropagation();
+                    }).on('input keydown', $.proxy(function(event) {
+                        // Cancel enter key default behaviour
+                        if (event.which === 13) {
+                          event.preventDefault();
+                      }
+
+                        // This is useful to catch "keydown" events after the browser has updated the control.
+                        clearTimeout(this.searchTimeout);
+
+                        this.searchTimeout = this.asyncFunction($.proxy(function() {
+
+                            if (this.query !== event.target.value) {
+                                this.query = event.target.value;
+
+                                var currentGroup, currentGroupVisible;
+                                $.each($('li', this.$ul), $.proxy(function(index, element) {
+                                    var value = $('input', element).length > 0 ? $('input', element).val() : "";
+                                    var text = $('label', element).text();
+
+                                    var filterCandidate = '';
+                                    if ((this.options.filterBehavior === 'text')) {
+                                        filterCandidate = text;
+                                    }
+                                    else if ((this.options.filterBehavior === 'value')) {
+                                        filterCandidate = value;
+                                    }
+                                    else if (this.options.filterBehavior === 'both') {
+                                        filterCandidate = text + '\n' + value;
+                                    }
+
+                                    if (value !== this.options.selectAllValue && text) {
+
+                                        // By default lets assume that element is not
+                                        // interesting for this search.
+                                        var showElement = false;
+
+                                        if (this.options.enableCaseInsensitiveFiltering) {
+                                            filterCandidate = filterCandidate.toLowerCase();
+                                            this.query = this.query.toLowerCase();
+                                        }
+
+                                        if (this.options.enableFullValueFiltering && this.options.filterBehavior !== 'both') {
+                                            var valueToMatch = filterCandidate.trim().substring(0, this.query.length);
+                                            if (this.query.indexOf(valueToMatch) > -1) {
+                                                showElement = true;
+                                            }
+                                        }
+                                        else if (filterCandidate.indexOf(this.query) > -1) {
+                                            showElement = true;
+                                        }
+
+                                        // Toggle current element (group or group item) according to showElement boolean.
+                                        $(element).toggle(showElement)
+                                            .toggleClass('multiselect-filter-hidden', !showElement);
+
+                                        // Differentiate groups and group items.
+                                        if ($(element).hasClass('multiselect-group')) {
+                                            // Remember group status.
+                                            currentGroup = element;
+                                            currentGroupVisible = showElement;
+                                        }
+                                        else {
+                                            // Show group name when at least one of its items is visible.
+                                            if (showElement) {
+                                                $(currentGroup).show()
+                                                    .removeClass('multiselect-filter-hidden');
+                                            }
+
+                                            // Show all group items when group name satisfies filter.
+                                            if (!showElement && currentGroupVisible) {
+                                                $(element).show()
+                                                    .removeClass('multiselect-filter-hidden');
+                                            }
+                                        }
+                                    }
+                                }, this));
+                            }
+
+                            this.updateSelectAll();
+
+                            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                                this.updateOptGroups();
+                            }
+
+                            this.options.onFiltering(event.target);
+
+                        }, this), 300, this);
+                    }, this));
+                }
+            }
+        },
+
+        /**
+         * Unbinds the whole plugin.
+         */
+        destroy: function() {
+            this.$container.remove();
+            this.$select.show();
+
+            // reset original state
+            this.$select.prop('disabled', this.options.wasDisabled);
+
+            this.$select.data('multiselect', null);
+        },
+
+        /**
+         * Refreshs the multiselect based on the selected options of the select.
+         */
+        refresh: function () {
+            var inputs = $.map($('li input', this.$ul), $);
+
+            $('option', this.$select).each($.proxy(function (index, element) {
+                var $elem = $(element);
+                var value = $elem.val();
+                var $input;
+                for (var i = inputs.length; 0 < i--; /**/) {
+                    if (value !== ($input = inputs[i]).val())
+                        continue; // wrong li
+
+                    if ($elem.is(':selected')) {
+                        $input.prop('checked', true);
+
+                        if (this.options.selectedClass) {
+                            $input.closest('li')
+                                .addClass(this.options.selectedClass);
+                        }
+                    }
+                    else {
+                        $input.prop('checked', false);
+
+                        if (this.options.selectedClass) {
+                            $input.closest('li')
+                                .removeClass(this.options.selectedClass);
+                        }
+                    }
+
+                    if ($elem.is(":disabled")) {
+                        $input.attr('disabled', 'disabled')
+                            .prop('disabled', true)
+                            .closest('li')
+                            .addClass('disabled');
+                    }
+                    else {
+                        $input.prop('disabled', false)
+                            .closest('li')
+                            .removeClass('disabled');
+                    }
+                    break; // assumes unique values
+                }
+            }, this));
+
+            this.updateButtonText();
+            this.updateSelectAll();
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+        },
+
+        /**
+         * Select all options of the given values.
+         *
+         * If triggerOnChange is set to true, the on change event is triggered if
+         * and only if one value is passed.
+         *
+         * @param {Array} selectValues
+         * @param {Boolean} triggerOnChange
+         */
+        select: function(selectValues, triggerOnChange) {
+            if(!$.isArray(selectValues)) {
+                selectValues = [selectValues];
+            }
+
+            for (var i = 0; i < selectValues.length; i++) {
+                var value = selectValues[i];
+
+                if (value === null || value === undefined) {
+                    continue;
+                }
+
+                var $option = this.getOptionByValue(value);
+                var $checkbox = this.getInputByValue(value);
+
+                if($option === undefined || $checkbox === undefined) {
+                    continue;
+                }
+
+                if (!this.options.multiple) {
+                    this.deselectAll(false);
+                }
+
+                if (this.options.selectedClass) {
+                    $checkbox.closest('li')
+                        .addClass(this.options.selectedClass);
+                }
+
+                $checkbox.prop('checked', true);
+                $option.prop('selected', true);
+
+                if (triggerOnChange) {
+                    this.options.onChange($option, true);
+                }
+            }
+
+            this.updateButtonText();
+            this.updateSelectAll();
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+        },
+
+        /**
+         * Clears all selected items.
+         */
+        clearSelection: function () {
+            this.deselectAll(false);
+            this.updateButtonText();
+            this.updateSelectAll();
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+        },
+
+        /**
+         * Deselects all options of the given values.
+         *
+         * If triggerOnChange is set to true, the on change event is triggered, if
+         * and only if one value is passed.
+         *
+         * @param {Array} deselectValues
+         * @param {Boolean} triggerOnChange
+         */
+        deselect: function(deselectValues, triggerOnChange) {
+            if(!$.isArray(deselectValues)) {
+                deselectValues = [deselectValues];
+            }
+
+            for (var i = 0; i < deselectValues.length; i++) {
+                var value = deselectValues[i];
+
+                if (value === null || value === undefined) {
+                    continue;
+                }
+
+                var $option = this.getOptionByValue(value);
+                var $checkbox = this.getInputByValue(value);
+
+                if($option === undefined || $checkbox === undefined) {
+                    continue;
+                }
+
+                if (this.options.selectedClass) {
+                    $checkbox.closest('li')
+                        .removeClass(this.options.selectedClass);
+                }
+
+                $checkbox.prop('checked', false);
+                $option.prop('selected', false);
+
+                if (triggerOnChange) {
+                    this.options.onChange($option, false);
+                }
+            }
+
+            this.updateButtonText();
+            this.updateSelectAll();
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+        },
+
+        /**
+         * Selects all enabled & visible options.
+         *
+         * If justVisible is true or not specified, only visible options are selected.
+         *
+         * @param {Boolean} justVisible
+         * @param {Boolean} triggerOnSelectAll
+         */
+        selectAll: function (justVisible, triggerOnSelectAll) {
+
+            var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
+            var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul);
+            var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible');
+
+            if(justVisible) {
+                $('input:enabled' , visibleLis).prop('checked', true);
+                visibleLis.addClass(this.options.selectedClass);
+
+                $('input:enabled' , visibleLis).each($.proxy(function(index, element) {
+                    var value = $(element).val();
+                    var option = this.getOptionByValue(value);
+                    $(option).prop('selected', true);
+                }, this));
+            }
+            else {
+                $('input:enabled' , allLis).prop('checked', true);
+                allLis.addClass(this.options.selectedClass);
+
+                $('input:enabled' , allLis).each($.proxy(function(index, element) {
+                    var value = $(element).val();
+                    var option = this.getOptionByValue(value);
+                    $(option).prop('selected', true);
+                }, this));
+            }
+
+            $('li input[value="' + this.options.selectAllValue + '"]', this.$ul).prop('checked', true);
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+
+            if (triggerOnSelectAll) {
+                this.options.onSelectAll();
+            }
+        },
+
+        /**
+         * Deselects all options.
+         *
+         * If justVisible is true or not specified, only visible options are deselected.
+         *
+         * @param {Boolean} justVisible
+         */
+        deselectAll: function (justVisible, triggerOnDeselectAll) {
+
+            var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
+            var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul);
+            var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible');
+
+            if(justVisible) {
+                $('input[type="checkbox"]:enabled' , visibleLis).prop('checked', false);
+                visibleLis.removeClass(this.options.selectedClass);
+
+                $('input[type="checkbox"]:enabled' , visibleLis).each($.proxy(function(index, element) {
+                    var value = $(element).val();
+                    var option = this.getOptionByValue(value);
+                    $(option).prop('selected', false);
+                }, this));
+            }
+            else {
+                $('input[type="checkbox"]:enabled' , allLis).prop('checked', false);
+                allLis.removeClass(this.options.selectedClass);
+
+                $('input[type="checkbox"]:enabled' , allLis).each($.proxy(function(index, element) {
+                    var value = $(element).val();
+                    var option = this.getOptionByValue(value);
+                    $(option).prop('selected', false);
+                }, this));
+            }
+
+            $('li input[value="' + this.options.selectAllValue + '"]', this.$ul).prop('checked', false);
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+
+            if (triggerOnDeselectAll) {
+                this.options.onDeselectAll();
+            }
+        },
+
+        /**
+         * Rebuild the plugin.
+         *
+         * Rebuilds the dropdown, the filter and the select all option.
+         */
+        rebuild: function() {
+            this.$ul.html('');
+
+            // Important to distinguish between radios and checkboxes.
+            this.options.multiple = this.$select.attr('multiple') === "multiple";
+
+            this.buildSelectAll();
+            this.buildDropdownOptions();
+            this.buildFilter();
+
+            this.updateButtonText();
+            this.updateSelectAll(true);
+
+            if (this.options.enableClickableOptGroups && this.options.multiple) {
+                this.updateOptGroups();
+            }
+
+            if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
+                this.disable();
+            }
+            else {
+                this.enable();
+            }
+
+            if (this.options.dropRight) {
+                this.$ul.addClass('pull-right');
+            }
+        },
+
+        /**
+         * The provided data will be used to build the dropdown.
+         */
+        dataprovider: function(dataprovider) {
+
+            var groupCounter = 0;
+            var $select = this.$select.empty();
+
+            $.each(dataprovider, function (index, option) {
+                var $tag;
+
+                if ($.isArray(option.children)) { // create optiongroup tag
+                    groupCounter++;
+
+                    $tag = $('<optgroup/>').attr({
+                        label: option.label || 'Group ' + groupCounter,
+                        disabled: !!option.disabled
+                    });
+
+                    forEach(option.children, function(subOption) { // add children option tags
+                        var attributes = {
+                            value: subOption.value,
+                            label: subOption.label || subOption.value,
+                            title: subOption.title,
+                            selected: !!subOption.selected,
+                            disabled: !!subOption.disabled
+                        };
+
+                        //Loop through attributes object and add key-value for each attribute
+                       for (var key in subOption.attributes) {
+                            attributes['data-' + key] = subOption.attributes[key];
+                       }
+                         //Append original attributes + new data attributes to option
+                        $tag.append($('<option/>').attr(attributes));
+                    });
+                }
+                else {
+
+                    var attributes = {
+                        'value': option.value,
+                        'label': option.label || option.value,
+                        'title': option.title,
+                        'class': option.class,
+                        'selected': !!option.selected,
+                        'disabled': !!option.disabled
+                    };
+                    //Loop through attributes object and add key-value for each attribute
+                    for (var key in option.attributes) {
+                      attributes['data-' + key] = option.attributes[key];
+                    }
+                    //Append original attributes + new data attributes to option
+                    $tag = $('<option/>').attr(attributes);
+
+                    $tag.text(option.label || option.value);
+                }
+
+                $select.append($tag);
+            });
+
+            this.rebuild();
+        },
+
+        /**
+         * Enable the multiselect.
+         */
+        enable: function() {
+            this.$select.prop('disabled', false);
+            this.$button.prop('disabled', false)
+                .removeClass('disabled');
+        },
+
+        /**
+         * Disable the multiselect.
+         */
+        disable: function() {
+            this.$select.prop('disabled', true);
+            this.$button.prop('disabled', true)
+                .addClass('disabled');
+        },
+
+        /**
+         * Set the options.
+         *
+         * @param {Array} options
+         */
+        setOptions: function(options) {
+            this.options = this.mergeOptions(options);
+        },
+
+        /**
+         * Merges the given options with the default options.
+         *
+         * @param {Array} options
+         * @returns {Array}
+         */
+        mergeOptions: function(options) {
+            return $.extend(true, {}, this.defaults, this.options, options);
+        },
+
+        /**
+         * Checks whether a select all checkbox is present.
+         *
+         * @returns {Boolean}
+         */
+        hasSelectAll: function() {
+            return $('li.multiselect-all', this.$ul).length > 0;
+        },
+
+        /**
+         * Update opt groups.
+         */
+        updateOptGroups: function() {
+            var $groups = $('li.multiselect-group', this.$ul)
+            var selectedClass = this.options.selectedClass;
+
+            $groups.each(function() {
+                var $options = $(this).nextUntil('li.multiselect-group')
+                    .not('.multiselect-filter-hidden')
+                    .not('.disabled');
+
+                var checked = true;
+                $options.each(function() {
+                    var $input = $('input', this);
+
+                    if (!$input.prop('checked')) {
+                        checked = false;
+                    }
+                });
+
+                if (selectedClass) {
+                    if (checked) {
+                        $(this).addClass(selectedClass);
+                    }
+                    else {
+                        $(this).removeClass(selectedClass);
+                    }
+                }
+
+                $('input', this).prop('checked', checked);
+            });
+        },
+
+        /**
+         * Updates the select all checkbox based on the currently displayed and selected checkboxes.
+         */
+        updateSelectAll: function(notTriggerOnSelectAll) {
+            if (this.hasSelectAll()) {
+                var allBoxes = $("li:not(.multiselect-item):not(.multiselect-filter-hidden):not(.multiselect-group):not(.disabled) input:enabled", this.$ul);
+                var allBoxesLength = allBoxes.length;
+                var checkedBoxesLength = allBoxes.filter(":checked").length;
+                var selectAllLi  = $("li.multiselect-all", this.$ul);
+                var selectAllInput = selectAllLi.find("input");
+
+                if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) {
+                    selectAllInput.prop("checked", true);
+                    selectAllLi.addClass(this.options.selectedClass);
+                }
+                else {
+                    selectAllInput.prop("checked", false);
+                    selectAllLi.removeClass(this.options.selectedClass);
+                }
+            }
+        },
+
+        /**
+         * Update the button text and its title based on the currently selected options.
+         */
+        updateButtonText: function() {
+            var options = this.getSelected();
+
+            // First update the displayed button text.
+            if (this.options.enableHTML) {
+                $('.multiselect .multiselect-selected-text', this.$container).html(this.options.buttonText(options, this.$select));
+            }
+            else {
+                $('.multiselect .multiselect-selected-text', this.$container).text(this.options.buttonText(options, this.$select));
+            }
+
+            // Now update the title attribute of the button.
+            $('.multiselect', this.$container).attr('title', this.options.buttonTitle(options, this.$select));
+        },
+
+        /**
+         * Get all selected options.
+         *
+         * @returns {jQUery}
+         */
+        getSelected: function() {
+            return $('option', this.$select).filter(":selected");
+        },
+
+        /**
+         * Gets a select option by its value.
+         *
+         * @param {String} value
+         * @returns {jQuery}
+         */
+        getOptionByValue: function (value) {
+
+            var options = $('option', this.$select);
+            var valueToCompare = value.toString();
+
+            for (var i = 0; i < options.length; i = i + 1) {
+                var option = options[i];
+                if (option.value === valueToCompare) {
+                    return $(option);
+                }
+            }
+        },
+
+        /**
+         * Get the input (radio/checkbox) by its value.
+         *
+         * @param {String} value
+         * @returns {jQuery}
+         */
+        getInputByValue: function (value) {
+
+            var checkboxes = $('li input:not(.multiselect-search)', this.$ul);
+            var valueToCompare = value.toString();
+
+            for (var i = 0; i < checkboxes.length; i = i + 1) {
+                var checkbox = checkboxes[i];
+                if (checkbox.value === valueToCompare) {
+                    return $(checkbox);
+                }
+            }
+        },
+
+        /**
+         * Used for knockout integration.
+         */
+        updateOriginalOptions: function() {
+            this.originalOptions = this.$select.clone()[0].options;
+        },
+
+        asyncFunction: function(callback, timeout, self) {
+            var args = Array.prototype.slice.call(arguments, 3);
+            return setTimeout(function() {
+                callback.apply(self || window, args);
+            }, timeout);
+        },
+
+        setAllSelectedText: function(allSelectedText) {
+            this.options.allSelectedText = allSelectedText;
+            this.updateButtonText();
+        }
+    };
+
+    $.fn.multiselect = function(option, parameter, extraOptions) {
+        return this.each(function() {
+            var data = $(this).data('multiselect');
+            var options = typeof option === 'object' && option;
+
+            // Initialize the multiselect.
+            if (!data) {
+                data = new Multiselect(this, options);
+                $(this).data('multiselect', data);
+            }
+
+            // Call multiselect method.
+            if (typeof option === 'string') {
+                data[option](parameter, extraOptions);
+
+                if (option === 'destroy') {
+                    $(this).data('multiselect', false);
+                }
+            }
+        });
+    };
+
+    $.fn.multiselect.Constructor = Multiselect;
+
+    $(function() {
+        $("select[data-role=multiselect]").multiselect();
+    });
+
+}(window.jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/owl.carousel.js b/src/main/resources/META-INF/resources/designer/lib/owl.carousel.js
new file mode 100644 (file)
index 0000000..f6ef78b
--- /dev/null
@@ -0,0 +1,3069 @@
+/**
+ * Owl carousel
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ * @todo Lazy Load Icon
+ * @todo prevent animationend bubling
+ * @todo itemsScaleUp
+ * @todo Test Zepto
+ * @todo stagePadding calculate wrong active classes
+ */
+;(function($, window, document, undefined) {
+
+       var drag, state, e;
+
+       /**
+        * Template for status information about drag and touch events.
+        * @private
+        */
+       drag = {
+               start: 0,
+               startX: 0,
+               startY: 0,
+               current: 0,
+               currentX: 0,
+               currentY: 0,
+               offsetX: 0,
+               offsetY: 0,
+               distance: null,
+               startTime: 0,
+               endTime: 0,
+               updatedX: 0,
+               targetEl: null
+       };
+
+       /**
+        * Template for some status informations.
+        * @private
+        */
+       state = {
+               isTouch: false,
+               isScrolling: false,
+               isSwiping: false,
+               direction: false,
+               inMotion: false
+       };
+
+       /**
+        * Event functions references.
+        * @private
+        */
+       e = {
+               _onDragStart: null,
+               _onDragMove: null,
+               _onDragEnd: null,
+               _transitionEnd: null,
+               _resizer: null,
+               _responsiveCall: null,
+               _goToLoop: null,
+               _checkVisibile: null
+       };
+
+       /**
+        * Creates a carousel.
+        * @class The Owl Carousel.
+        * @public
+        * @param {HTMLElement|jQuery} element - The element to create the carousel for.
+        * @param {Object} [options] - The options
+        */
+       function Owl(element, options) {
+
+               /**
+                * Current settings for the carousel.
+                * @public
+                */
+               this.settings = null;
+
+               /**
+                * Current options set by the caller including defaults.
+                * @public
+                */
+               this.options = $.extend({}, Owl.Defaults, options);
+
+               /**
+                * Plugin element.
+                * @public
+                */
+               this.$element = $(element);
+
+               /**
+                * Caches informations about drag and touch events.
+                */
+               this.drag = $.extend({}, drag);
+
+               /**
+                * Caches some status informations.
+                * @protected
+                */
+               this.state = $.extend({}, state);
+
+               /**
+                * @protected
+                * @todo Must be documented
+                */
+               this.e = $.extend({}, e);
+
+               /**
+                * References to the running plugins of this carousel.
+                * @protected
+                */
+               this._plugins = {};
+
+               /**
+                * Currently suppressed events to prevent them from beeing retriggered.
+                * @protected
+                */
+               this._supress = {};
+
+               /**
+                * Absolute current position.
+                * @protected
+                */
+               this._current = null;
+
+               /**
+                * Animation speed in milliseconds.
+                * @protected
+                */
+               this._speed = null;
+
+               /**
+                * Coordinates of all items in pixel.
+                * @todo The name of this member is missleading.
+                * @protected
+                */
+               this._coordinates = [];
+
+               /**
+                * Current breakpoint.
+                * @todo Real media queries would be nice.
+                * @protected
+                */
+               this._breakpoint = null;
+
+               /**
+                * Current width of the plugin element.
+                */
+               this._width = null;
+
+               /**
+                * All real items.
+                * @protected
+                */
+               this._items = [];
+
+               /**
+                * All cloned items.
+                * @protected
+                */
+               this._clones = [];
+
+               /**
+                * Merge values of all items.
+                * @todo Maybe this could be part of a plugin.
+                * @protected
+                */
+               this._mergers = [];
+
+               /**
+                * Invalidated parts within the update process.
+                * @protected
+                */
+               this._invalidated = {};
+
+               /**
+                * Ordered list of workers for the update process.
+                * @protected
+                */
+               this._pipe = [];
+
+               $.each(Owl.Plugins, $.proxy(function(key, plugin) {
+                       this._plugins[key[0].toLowerCase() + key.slice(1)]
+                               = new plugin(this);
+               }, this));
+
+               $.each(Owl.Pipe, $.proxy(function(priority, worker) {
+                       this._pipe.push({
+                               'filter': worker.filter,
+                               'run': $.proxy(worker.run, this)
+                       });
+               }, this));
+
+               this.setup();
+               this.initialize();
+       }
+
+       /**
+        * Default options for the carousel.
+        * @public
+        */
+       Owl.Defaults = {
+               items: 3,
+               loop: false,
+               center: false,
+
+               mouseDrag: true,
+               touchDrag: true,
+               pullDrag: true,
+               freeDrag: false,
+
+               margin: 0,
+               stagePadding: 0,
+
+               merge: false,
+               mergeFit: true,
+               autoWidth: false,
+
+               startPosition: 0,
+               rtl: false,
+
+               smartSpeed: 250,
+               fluidSpeed: false,
+               dragEndSpeed: false,
+
+               responsive: {},
+               responsiveRefreshRate: 200,
+               responsiveBaseElement: window,
+               responsiveClass: false,
+
+               fallbackEasing: 'swing',
+
+               info: false,
+
+               nestedItemSelector: false,
+               itemElement: 'div',
+               stageElement: 'div',
+
+               // Classes and Names
+               themeClass: 'owl-theme',
+               baseClass: 'owl-carousel',
+               itemClass: 'owl-item',
+               centerClass: 'center',
+               activeClass: 'active'
+       };
+
+       /**
+        * Enumeration for width.
+        * @public
+        * @readonly
+        * @enum {String}
+        */
+       Owl.Width = {
+               Default: 'default',
+               Inner: 'inner',
+               Outer: 'outer'
+       };
+
+       /**
+        * Contains all registered plugins.
+        * @public
+        */
+       Owl.Plugins = {};
+
+       /**
+        * Update pipe.
+        */
+       Owl.Pipe = [ {
+               filter: [ 'width', 'items', 'settings' ],
+               run: function(cache) {
+                       cache.current = this._items && this._items[this.relative(this._current)];
+               }
+       }, {
+               filter: [ 'items', 'settings' ],
+               run: function() {
+                       var cached = this._clones,
+                               clones = this.$stage.children('.cloned');
+
+                       if (clones.length !== cached.length || (!this.settings.loop && cached.length > 0)) {
+                               this.$stage.children('.cloned').remove();
+                               this._clones = [];
+                       }
+               }
+       }, {
+               filter: [ 'items', 'settings' ],
+               run: function() {
+                       var i, n,
+                               clones = this._clones,
+                               items = this._items,
+                               delta = this.settings.loop ? clones.length - Math.max(this.settings.items * 2, 4) : 0;
+
+                       for (i = 0, n = Math.abs(delta / 2); i < n; i++) {
+                               if (delta > 0) {
+                                       this.$stage.children().eq(items.length + clones.length - 1).remove();
+                                       clones.pop();
+                                       this.$stage.children().eq(0).remove();
+                                       clones.pop();
+                               } else {
+                                       clones.push(clones.length / 2);
+                                       this.$stage.append(items[clones[clones.length - 1]].clone().addClass('cloned'));
+                                       clones.push(items.length - 1 - (clones.length - 1) / 2);
+                                       this.$stage.prepend(items[clones[clones.length - 1]].clone().addClass('cloned'));
+                               }
+                       }
+               }
+       }, {
+               filter: [ 'width', 'items', 'settings' ],
+               run: function() {
+                       var rtl = (this.settings.rtl ? 1 : -1),
+                               width = (this.width() / this.settings.items).toFixed(3),
+                               coordinate = 0, merge, i, n;
+
+                       this._coordinates = [];
+                       for (i = 0, n = this._clones.length + this._items.length; i < n; i++) {
+                               merge = this._mergers[this.relative(i)];
+                               merge = (this.settings.mergeFit && Math.min(merge, this.settings.items)) || merge;
+                               coordinate += (this.settings.autoWidth ? this._items[this.relative(i)].width() + this.settings.margin : width * merge) * rtl;
+
+                               this._coordinates.push(coordinate);
+                       }
+               }
+       }, {
+               filter: [ 'width', 'items', 'settings' ],
+               run: function() {
+                       var i, n, width = (this.width() / this.settings.items).toFixed(3), css = {
+                               'width': Math.abs(this._coordinates[this._coordinates.length - 1]) + this.settings.stagePadding * 2,
+                               'padding-left': this.settings.stagePadding || '',
+                               'padding-right': this.settings.stagePadding || ''
+                       };
+
+                       this.$stage.css(css);
+
+                       css = { 'width': this.settings.autoWidth ? 'auto' : width - this.settings.margin };
+                       css[this.settings.rtl ? 'margin-left' : 'margin-right'] = this.settings.margin;
+
+                       if (!this.settings.autoWidth && $.grep(this._mergers, function(v) { return v > 1 }).length > 0) {
+                               for (i = 0, n = this._coordinates.length; i < n; i++) {
+                                       css.width = Math.abs(this._coordinates[i]) - Math.abs(this._coordinates[i - 1] || 0) - this.settings.margin;
+                                       this.$stage.children().eq(i).css(css);
+                               }
+                       } else {
+                               this.$stage.children().css(css);
+                       }
+               }
+       }, {
+               filter: [ 'width', 'items', 'settings' ],
+               run: function(cache) {
+                       cache.current && this.reset(this.$stage.children().index(cache.current));
+               }
+       }, {
+               filter: [ 'position' ],
+               run: function() {
+                       this.animate(this.coordinates(this._current));
+               }
+       }, {
+               filter: [ 'width', 'position', 'items', 'settings' ],
+               run: function() {
+                       var rtl = this.settings.rtl ? 1 : -1,
+                               padding = this.settings.stagePadding * 2,
+                               begin = this.coordinates(this.current()) + padding,
+                               end = begin + this.width() * rtl,
+                               inner, outer, matches = [], i, n;
+
+                       for (i = 0, n = this._coordinates.length; i < n; i++) {
+                               inner = this._coordinates[i - 1] || 0;
+                               outer = Math.abs(this._coordinates[i]) + padding * rtl;
+
+                               if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
+                                       || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
+                                       matches.push(i);
+                               }
+                       }
+
+                       this.$stage.children('.' + this.settings.activeClass).removeClass(this.settings.activeClass);
+                       this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass(this.settings.activeClass);
+
+                       if (this.settings.center) {
+                               this.$stage.children('.' + this.settings.centerClass).removeClass(this.settings.centerClass);
+                               this.$stage.children().eq(this.current()).addClass(this.settings.centerClass);
+                       }
+               }
+       } ];
+
+       /**
+        * Initializes the carousel.
+        * @protected
+        */
+       Owl.prototype.initialize = function() {
+               this.trigger('initialize');
+
+               this.$element
+                       .addClass(this.settings.baseClass)
+                       .addClass(this.settings.themeClass)
+                       .toggleClass('owl-rtl', this.settings.rtl);
+
+               // check support
+               this.browserSupport();
+
+               if (this.settings.autoWidth && this.state.imagesLoaded !== true) {
+                       var imgs, nestedSelector, width;
+                       imgs = this.$element.find('img');
+                       nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
+                       width = this.$element.children(nestedSelector).width();
+
+                       if (imgs.length && width <= 0) {
+                               this.preloadAutoWidthImages(imgs);
+                               return false;
+                       }
+               }
+
+               this.$element.addClass('owl-loading');
+
+               // create stage
+               this.$stage = $('<' + this.settings.stageElement + ' class="owl-stage"/>')
+                       .wrap('<div class="owl-stage-outer">');
+
+               // append stage
+               this.$element.append(this.$stage.parent());
+
+               // append content
+               this.replace(this.$element.children().not(this.$stage.parent()));
+
+               // set view width
+               this._width = this.$element.width();
+
+               // update view
+               this.refresh();
+
+               this.$element.removeClass('owl-loading').addClass('owl-loaded');
+
+               // attach generic events
+               this.eventsCall();
+
+               // attach generic events
+               this.internalEvents();
+
+               // attach custom control events
+               this.addTriggerableEvents();
+
+               this.trigger('initialized');
+       };
+
+       /**
+        * Setups the current settings.
+        * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
+        * @todo Support for media queries by using `matchMedia` would be nice.
+        * @public
+        */
+       Owl.prototype.setup = function() {
+               var viewport = this.viewport(),
+                       overwrites = this.options.responsive,
+                       match = -1,
+                       settings = null;
+
+               if (!overwrites) {
+                       settings = $.extend({}, this.options);
+               } else {
+                       $.each(overwrites, function(breakpoint) {
+                               if (breakpoint <= viewport && breakpoint > match) {
+                                       match = Number(breakpoint);
+                               }
+                       });
+
+                       settings = $.extend({}, this.options, overwrites[match]);
+                       delete settings.responsive;
+
+                       // responsive class
+                       if (settings.responsiveClass) {
+                               this.$element.attr('class', function(i, c) {
+                                       return c.replace(/\b owl-responsive-\S+/g, '');
+                               }).addClass('owl-responsive-' + match);
+                       }
+               }
+
+               if (this.settings === null || this._breakpoint !== match) {
+                       this.trigger('change', { property: { name: 'settings', value: settings } });
+                       this._breakpoint = match;
+                       this.settings = settings;
+                       this.invalidate('settings');
+                       this.trigger('changed', { property: { name: 'settings', value: this.settings } });
+               }
+       };
+
+       /**
+        * Updates option logic if necessery.
+        * @protected
+        */
+       Owl.prototype.optionsLogic = function() {
+               // Toggle Center class
+               this.$element.toggleClass('owl-center', this.settings.center);
+
+               // if items number is less than in body
+               if (this.settings.loop && this._items.length < this.settings.items) {
+                       this.settings.loop = false;
+               }
+
+               if (this.settings.autoWidth) {
+                       this.settings.stagePadding = false;
+                       this.settings.merge = false;
+               }
+       };
+
+       /**
+        * Prepares an item before add.
+        * @todo Rename event parameter `content` to `item`.
+        * @protected
+        * @returns {jQuery|HTMLElement} - The item container.
+        */
+       Owl.prototype.prepare = function(item) {
+               var event = this.trigger('prepare', { content: item });
+
+               if (!event.data) {
+                       event.data = $('<' + this.settings.itemElement + '/>')
+                               .addClass(this.settings.itemClass).append(item)
+               }
+
+               this.trigger('prepared', { content: event.data });
+
+               return event.data;
+       };
+
+       /**
+        * Updates the view.
+        * @public
+        */
+       Owl.prototype.update = function() {
+               var i = 0,
+                       n = this._pipe.length,
+                       filter = $.proxy(function(p) { return this[p] }, this._invalidated),
+                       cache = {};
+
+               while (i < n) {
+                       if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
+                               this._pipe[i].run(cache);
+                       }
+                       i++;
+               }
+
+               this._invalidated = {};
+       };
+
+       /**
+        * Gets the width of the view.
+        * @public
+        * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
+        * @returns {Number} - The width of the view in pixel.
+        */
+       Owl.prototype.width = function(dimension) {
+               dimension = dimension || Owl.Width.Default;
+               switch (dimension) {
+                       case Owl.Width.Inner:
+                       case Owl.Width.Outer:
+                               return this._width;
+                       default:
+                               return this._width - this.settings.stagePadding * 2 + this.settings.margin;
+               }
+       };
+
+       /**
+        * Refreshes the carousel primarily for adaptive purposes.
+        * @public
+        */
+       Owl.prototype.refresh = function() {
+               if (this._items.length === 0) {
+                       return false;
+               }
+
+               var start = new Date().getTime();
+
+               this.trigger('refresh');
+
+               this.setup();
+
+               this.optionsLogic();
+
+               // hide and show methods helps here to set a proper widths,
+               // this prevents scrollbar to be calculated in stage width
+               this.$stage.addClass('owl-refresh');
+
+               this.update();
+
+               this.$stage.removeClass('owl-refresh');
+
+               this.state.orientation = window.orientation;
+
+               this.watchVisibility();
+
+               this.trigger('refreshed');
+       };
+
+       /**
+        * Save internal event references and add event based functions.
+        * @protected
+        */
+       Owl.prototype.eventsCall = function() {
+               // Save events references
+               this.e._onDragStart = $.proxy(function(e) {
+                       this.onDragStart(e);
+               }, this);
+               this.e._onDragMove = $.proxy(function(e) {
+                       this.onDragMove(e);
+               }, this);
+               this.e._onDragEnd = $.proxy(function(e) {
+                       this.onDragEnd(e);
+               }, this);
+               this.e._onResize = $.proxy(function(e) {
+                       this.onResize(e);
+               }, this);
+               this.e._transitionEnd = $.proxy(function(e) {
+                       this.transitionEnd(e);
+               }, this);
+               this.e._preventClick = $.proxy(function(e) {
+                       this.preventClick(e);
+               }, this);
+       };
+
+       /**
+        * Checks window `resize` event.
+        * @protected
+        */
+       Owl.prototype.onThrottledResize = function() {
+               window.clearTimeout(this.resizeTimer);
+               this.resizeTimer = window.setTimeout(this.e._onResize, this.settings.responsiveRefreshRate);
+       };
+
+       /**
+        * Checks window `resize` event.
+        * @protected
+        */
+       Owl.prototype.onResize = function() {
+               if (!this._items.length) {
+                       return false;
+               }
+
+               if (this._width === this.$element.width()) {
+                       return false;
+               }
+
+               if (this.trigger('resize').isDefaultPrevented()) {
+                       return false;
+               }
+
+               this._width = this.$element.width();
+
+               this.invalidate('width');
+
+               this.refresh();
+
+               this.trigger('resized');
+       };
+
+       /**
+        * Checks for touch/mouse drag event type and add run event handlers.
+        * @protected
+        */
+       Owl.prototype.eventsRouter = function(event) {
+               var type = event.type;
+
+               if (type === "mousedown" || type === "touchstart") {
+                       this.onDragStart(event);
+               } else if (type === "mousemove" || type === "touchmove") {
+                       this.onDragMove(event);
+               } else if (type === "mouseup" || type === "touchend") {
+                       this.onDragEnd(event);
+               } else if (type === "touchcancel") {
+                       this.onDragEnd(event);
+               }
+       };
+
+       /**
+        * Checks for touch/mouse drag options and add necessery event handlers.
+        * @protected
+        */
+       Owl.prototype.internalEvents = function() {
+               var isTouch = isTouchSupport(),
+                       isTouchIE = isTouchSupportIE();
+
+               if (this.settings.mouseDrag){
+                       this.$stage.on('mousedown', $.proxy(function(event) { this.eventsRouter(event) }, this));
+                       this.$stage.on('dragstart', function() { return false });
+                       this.$stage.get(0).onselectstart = function() { return false };
+               } else {
+                       this.$element.addClass('owl-text-select-on');
+               }
+
+               if (this.settings.touchDrag && !isTouchIE){
+                       this.$stage.on('touchstart touchcancel', $.proxy(function(event) { this.eventsRouter(event) }, this));
+               }
+
+               // catch transitionEnd event
+               if (this.transitionEndVendor) {
+                       this.on(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd, false);
+               }
+
+               // responsive
+               if (this.settings.responsive !== false) {
+                       this.on(window, 'resize', $.proxy(this.onThrottledResize, this));
+               }
+       };
+
+       /**
+        * Handles touchstart/mousedown event.
+        * @protected
+        * @param {Event} event - The event arguments.
+        */
+       Owl.prototype.onDragStart = function(event) {
+               var ev, isTouchEvent, pageX, pageY, animatedPos;
+
+               ev = event.originalEvent || event || window.event;
+
+               // prevent right click
+               if (ev.which === 3 || this.state.isTouch) {
+                       return false;
+               }
+
+               if (ev.type === 'mousedown') {
+                       this.$stage.addClass('owl-grab');
+               }
+
+               this.trigger('drag');
+               this.drag.startTime = new Date().getTime();
+               this.speed(0);
+               this.state.isTouch = true;
+               this.state.isScrolling = false;
+               this.state.isSwiping = false;
+               this.drag.distance = 0;
+
+               pageX = getTouches(ev).x;
+               pageY = getTouches(ev).y;
+
+               // get stage position left
+               this.drag.offsetX = this.$stage.position().left;
+               this.drag.offsetY = this.$stage.position().top;
+
+               if (this.settings.rtl) {
+                       this.drag.offsetX = this.$stage.position().left + this.$stage.width() - this.width()
+                               + this.settings.margin;
+               }
+
+               // catch position // ie to fix
+               if (this.state.inMotion && this.support3d) {
+                       animatedPos = this.getTransformProperty();
+                       this.drag.offsetX = animatedPos;
+                       this.animate(animatedPos);
+                       this.state.inMotion = true;
+               } else if (this.state.inMotion && !this.support3d) {
+                       this.state.inMotion = false;
+                       return false;
+               }
+
+               this.drag.startX = pageX - this.drag.offsetX;
+               this.drag.startY = pageY - this.drag.offsetY;
+
+               this.drag.start = pageX - this.drag.startX;
+               this.drag.targetEl = ev.target || ev.srcElement;
+               this.drag.updatedX = this.drag.start;
+
+               // to do/check
+               // prevent links and images dragging;
+               if (this.drag.targetEl.tagName === "IMG" || this.drag.targetEl.tagName === "A") {
+                       this.drag.targetEl.draggable = false;
+               }
+
+               $(document).on('mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents', $.proxy(function(event) {this.eventsRouter(event)},this));
+       };
+
+       /**
+        * Handles the touchmove/mousemove events.
+        * @todo Simplify
+        * @protected
+        * @param {Event} event - The event arguments.
+        */
+       Owl.prototype.onDragMove = function(event) {
+               var ev, isTouchEvent, pageX, pageY, minValue, maxValue, pull;
+
+               if (!this.state.isTouch) {
+                       return;
+               }
+
+               if (this.state.isScrolling) {
+                       return;
+               }
+
+               ev = event.originalEvent || event || window.event;
+
+               pageX = getTouches(ev).x;
+               pageY = getTouches(ev).y;
+
+               // Drag Direction
+               this.drag.currentX = pageX - this.drag.startX;
+               this.drag.currentY = pageY - this.drag.startY;
+               this.drag.distance = this.drag.currentX - this.drag.offsetX;
+
+               // Check move direction
+               if (this.drag.distance < 0) {
+                       this.state.direction = this.settings.rtl ? 'right' : 'left';
+               } else if (this.drag.distance > 0) {
+                       this.state.direction = this.settings.rtl ? 'left' : 'right';
+               }
+               // Loop
+               if (this.settings.loop) {
+                       if (this.op(this.drag.currentX, '>', this.coordinates(this.minimum())) && this.state.direction === 'right') {
+                               this.drag.currentX -= (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
+                       } else if (this.op(this.drag.currentX, '<', this.coordinates(this.maximum())) && this.state.direction === 'left') {
+                               this.drag.currentX += (this.settings.center && this.coordinates(0)) - this.coordinates(this._items.length);
+                       }
+               } else {
+                       // pull
+                       minValue = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
+                       maxValue = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
+                       pull = this.settings.pullDrag ? this.drag.distance / 5 : 0;
+                       this.drag.currentX = Math.max(Math.min(this.drag.currentX, minValue + pull), maxValue + pull);
+               }
+
+               // Lock browser if swiping horizontal
+
+               if ((this.drag.distance > 8 || this.drag.distance < -8)) {
+                       if (ev.preventDefault !== undefined) {
+                               ev.preventDefault();
+                       } else {
+                               ev.returnValue = false;
+                       }
+                       this.state.isSwiping = true;
+               }
+
+               this.drag.updatedX = this.drag.currentX;
+
+               // Lock Owl if scrolling
+               if ((this.drag.currentY > 16 || this.drag.currentY < -16) && this.state.isSwiping === false) {
+                       this.state.isScrolling = true;
+                       this.drag.updatedX = this.drag.start;
+               }
+
+               this.animate(this.drag.updatedX);
+       };
+
+       /**
+        * Handles the touchend/mouseup events.
+        * @protected
+        */
+       Owl.prototype.onDragEnd = function(event) {
+               var compareTimes, distanceAbs, closest;
+
+               if (!this.state.isTouch) {
+                       return;
+               }
+
+               if (event.type === 'mouseup') {
+                       this.$stage.removeClass('owl-grab');
+               }
+
+               this.trigger('dragged');
+
+               // prevent links and images dragging;
+               this.drag.targetEl.removeAttribute("draggable");
+
+               // remove drag event listeners
+
+               this.state.isTouch = false;
+               this.state.isScrolling = false;
+               this.state.isSwiping = false;
+
+               // to check
+               if (this.drag.distance === 0 && this.state.inMotion !== true) {
+                       this.state.inMotion = false;
+                       return false;
+               }
+
+               // prevent clicks while scrolling
+
+               this.drag.endTime = new Date().getTime();
+               compareTimes = this.drag.endTime - this.drag.startTime;
+               distanceAbs = Math.abs(this.drag.distance);
+
+               // to test
+               if (distanceAbs > 3 || compareTimes > 300) {
+                       this.removeClick(this.drag.targetEl);
+               }
+
+               closest = this.closest(this.drag.updatedX);
+
+               this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
+               this.current(closest);
+               this.invalidate('position');
+               this.update();
+
+               // if pullDrag is off then fire transitionEnd event manually when stick
+               // to border
+               if (!this.settings.pullDrag && this.drag.updatedX === this.coordinates(closest)) {
+                       this.transitionEnd();
+               }
+
+               this.drag.distance = 0;
+
+               $(document).off('.owl.dragEvents');
+       };
+
+       /**
+        * Attaches `preventClick` to disable link while swipping.
+        * @protected
+        * @param {HTMLElement} [target] - The target of the `click` event.
+        */
+       Owl.prototype.removeClick = function(target) {
+               this.drag.targetEl = target;
+               $(target).on('click.preventClick', this.e._preventClick);
+               // to make sure click is removed:
+               window.setTimeout(function() {
+                       $(target).off('click.preventClick');
+               }, 300);
+       };
+
+       /**
+        * Suppresses click event.
+        * @protected
+        * @param {Event} ev - The event arguments.
+        */
+       Owl.prototype.preventClick = function(ev) {
+               if (ev.preventDefault) {
+                       ev.preventDefault();
+               } else {
+                       ev.returnValue = false;
+               }
+               if (ev.stopPropagation) {
+                       ev.stopPropagation();
+               }
+               $(ev.target).off('click.preventClick');
+       };
+
+       /**
+        * Catches stage position while animate (only CSS3).
+        * @protected
+        * @returns
+        */
+       Owl.prototype.getTransformProperty = function() {
+               var transform, matrix3d;
+
+               transform = window.getComputedStyle(this.$stage.get(0), null).getPropertyValue(this.vendorName + 'transform');
+               // var transform = this.$stage.css(this.vendorName + 'transform')
+               transform = transform.replace(/matrix(3d)?\(|\)/g, '').split(',');
+               matrix3d = transform.length === 16;
+
+               return matrix3d !== true ? transform[4] : transform[12];
+       };
+
+       /**
+        * Gets absolute position of the closest item for a coordinate.
+        * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
+        * @protected
+        * @param {Number} coordinate - The coordinate in pixel.
+        * @return {Number} - The absolute position of the closest item.
+        */
+       Owl.prototype.closest = function(coordinate) {
+               var position = -1, pull = 30, width = this.width(), coordinates = this.coordinates();
+
+               if (!this.settings.freeDrag) {
+                       // check closest item
+                       $.each(coordinates, $.proxy(function(index, value) {
+                               if (coordinate > value - pull && coordinate < value + pull) {
+                                       position = index;
+                               } else if (this.op(coordinate, '<', value)
+                                       && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
+                                       position = this.state.direction === 'left' ? index + 1 : index;
+                               }
+                               return position === -1;
+                       }, this));
+               }
+
+               if (!this.settings.loop) {
+                       // non loop boundries
+                       if (this.op(coordinate, '>', coordinates[this.minimum()])) {
+                               position = coordinate = this.minimum();
+                       } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
+                               position = coordinate = this.maximum();
+                       }
+               }
+
+               return position;
+       };
+
+       /**
+        * Animates the stage.
+        * @public
+        * @param {Number} coordinate - The coordinate in pixels.
+        */
+       Owl.prototype.animate = function(coordinate) {
+               this.trigger('translate');
+               this.state.inMotion = this.speed() > 0;
+
+               if (this.support3d) {
+                       this.$stage.css({
+                               transform: 'translate3d(' + coordinate + 'px' + ',0px, 0px)',
+                               transition: (this.speed() / 1000) + 's'
+                       });
+               } else if (this.state.isTouch) {
+                       this.$stage.css({
+                               left: coordinate + 'px'
+                       });
+               } else {
+                       this.$stage.animate({
+                               left: coordinate
+                       }, this.speed() / 1000, this.settings.fallbackEasing, $.proxy(function() {
+                               if (this.state.inMotion) {
+                                       this.transitionEnd();
+                               }
+                       }, this));
+               }
+       };
+
+       /**
+        * Sets the absolute position of the current item.
+        * @public
+        * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
+        * @returns {Number} - The absolute position of the current item.
+        */
+       Owl.prototype.current = function(position) {
+               if (position === undefined) {
+                       return this._current;
+               }
+
+               if (this._items.length === 0) {
+                       return undefined;
+               }
+
+               position = this.normalize(position);
+
+               if (this._current !== position) {
+                       var event = this.trigger('change', { property: { name: 'position', value: position } });
+
+                       if (event.data !== undefined) {
+                               position = this.normalize(event.data);
+                       }
+
+                       this._current = position;
+
+                       this.invalidate('position');
+
+                       this.trigger('changed', { property: { name: 'position', value: this._current } });
+               }
+
+               return this._current;
+       };
+
+       /**
+        * Invalidates the given part of the update routine.
+        * @param {String} part - The part to invalidate.
+        */
+       Owl.prototype.invalidate = function(part) {
+               this._invalidated[part] = true;
+       }
+
+       /**
+        * Resets the absolute position of the current item.
+        * @public
+        * @param {Number} position - The absolute position of the new item.
+        */
+       Owl.prototype.reset = function(position) {
+               position = this.normalize(position);
+
+               if (position === undefined) {
+                       return;
+               }
+
+               this._speed = 0;
+               this._current = position;
+
+               this.suppress([ 'translate', 'translated' ]);
+
+               this.animate(this.coordinates(position));
+
+               this.release([ 'translate', 'translated' ]);
+       };
+
+       /**
+        * Normalizes an absolute or a relative position for an item.
+        * @public
+        * @param {Number} position - The absolute or relative position to normalize.
+        * @param {Boolean} [relative=false] - Whether the given position is relative or not.
+        * @returns {Number} - The normalized position.
+        */
+       Owl.prototype.normalize = function(position, relative) {
+               var n = (relative ? this._items.length : this._items.length + this._clones.length);
+
+               if (!$.isNumeric(position) || n < 1) {
+                       return undefined;
+               }
+
+               if (this._clones.length) {
+                       position = ((position % n) + n) % n;
+               } else {
+                       position = Math.max(this.minimum(relative), Math.min(this.maximum(relative), position));
+               }
+
+               return position;
+       };
+
+       /**
+        * Converts an absolute position for an item into a relative position.
+        * @public
+        * @param {Number} position - The absolute position to convert.
+        * @returns {Number} - The converted position.
+        */
+       Owl.prototype.relative = function(position) {
+               position = this.normalize(position);
+               position = position - this._clones.length / 2;
+               return this.normalize(position, true);
+       };
+
+       /**
+        * Gets the maximum position for an item.
+        * @public
+        * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
+        * @returns {Number}
+        */
+       Owl.prototype.maximum = function(relative) {
+               var maximum, width, i = 0, coordinate,
+                       settings = this.settings;
+
+               if (relative) {
+                       return this._items.length - 1;
+               }
+
+               if (!settings.loop && settings.center) {
+                       maximum = this._items.length - 1;
+               } else if (!settings.loop && !settings.center) {
+                       maximum = this._items.length - settings.items;
+               } else if (settings.loop || settings.center) {
+                       maximum = this._items.length + settings.items;
+               } else if (settings.autoWidth || settings.merge) {
+                       revert = settings.rtl ? 1 : -1;
+                       width = this.$stage.width() - this.$element.width();
+                       while (coordinate = this.coordinates(i)) {
+                               if (coordinate * revert >= width) {
+                                       break;
+                               }
+                               maximum = ++i;
+                       }
+               } else {
+                       throw 'Can not detect maximum absolute position.'
+               }
+
+               return maximum;
+       };
+
+       /**
+        * Gets the minimum position for an item.
+        * @public
+        * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
+        * @returns {Number}
+        */
+       Owl.prototype.minimum = function(relative) {
+               if (relative) {
+                       return 0;
+               }
+
+               return this._clones.length / 2;
+       };
+
+       /**
+        * Gets an item at the specified relative position.
+        * @public
+        * @param {Number} [position] - The relative position of the item.
+        * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
+        */
+       Owl.prototype.items = function(position) {
+               if (position === undefined) {
+                       return this._items.slice();
+               }
+
+               position = this.normalize(position, true);
+               return this._items[position];
+       };
+
+       /**
+        * Gets an item at the specified relative position.
+        * @public
+        * @param {Number} [position] - The relative position of the item.
+        * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
+        */
+       Owl.prototype.mergers = function(position) {
+               if (position === undefined) {
+                       return this._mergers.slice();
+               }
+
+               position = this.normalize(position, true);
+               return this._mergers[position];
+       };
+
+       /**
+        * Gets the absolute positions of clones for an item.
+        * @public
+        * @param {Number} [position] - The relative position of the item.
+        * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
+        */
+       Owl.prototype.clones = function(position) {
+               var odd = this._clones.length / 2,
+                       even = odd + this._items.length,
+                       map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
+
+               if (position === undefined) {
+                       return $.map(this._clones, function(v, i) { return map(i) });
+               }
+
+               return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
+       };
+
+       /**
+        * Sets the current animation speed.
+        * @public
+        * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
+        * @returns {Number} - The current animation speed in milliseconds.
+        */
+       Owl.prototype.speed = function(speed) {
+               if (speed !== undefined) {
+                       this._speed = speed;
+               }
+
+               return this._speed;
+       };
+
+       /**
+        * Gets the coordinate of an item.
+        * @todo The name of this method is missleanding.
+        * @public
+        * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
+        * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
+        */
+       Owl.prototype.coordinates = function(position) {
+               var coordinate = null;
+
+               if (position === undefined) {
+                       return $.map(this._coordinates, $.proxy(function(coordinate, index) {
+                               return this.coordinates(index);
+                       }, this));
+               }
+
+               if (this.settings.center) {
+                       coordinate = this._coordinates[position];
+                       coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
+               } else {
+                       coordinate = this._coordinates[position - 1] || 0;
+               }
+
+               return coordinate;
+       };
+
+       /**
+        * Calculates the speed for a translation.
+        * @protected
+        * @param {Number} from - The absolute position of the start item.
+        * @param {Number} to - The absolute position of the target item.
+        * @param {Number} [factor=undefined] - The time factor in milliseconds.
+        * @returns {Number} - The time in milliseconds for the translation.
+        */
+       Owl.prototype.duration = function(from, to, factor) {
+               return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
+       };
+
+       /**
+        * Slides to the specified item.
+        * @public
+        * @param {Number} position - The position of the item.
+        * @param {Number} [speed] - The time in milliseconds for the transition.
+        */
+       Owl.prototype.to = function(position, speed) {
+               if (this.settings.loop) {
+                       var distance = position - this.relative(this.current()),
+                               revert = this.current(),
+                               before = this.current(),
+                               after = this.current() + distance,
+                               direction = before - after < 0 ? true : false,
+                               items = this._clones.length + this._items.length;
+
+                       if (after < this.settings.items && direction === false) {
+                               revert = before + this._items.length;
+                               this.reset(revert);
+                       } else if (after >= items - this.settings.items && direction === true) {
+                               revert = before - this._items.length;
+                               this.reset(revert);
+                       }
+                       window.clearTimeout(this.e._goToLoop);
+                       this.e._goToLoop = window.setTimeout($.proxy(function() {
+                               this.speed(this.duration(this.current(), revert + distance, speed));
+                               this.current(revert + distance);
+                               this.update();
+                       }, this), 30);
+               } else {
+                       this.speed(this.duration(this.current(), position, speed));
+                       this.current(position);
+                       this.update();
+               }
+       };
+
+       /**
+        * Slides to the next item.
+        * @public
+        * @param {Number} [speed] - The time in milliseconds for the transition.
+        */
+       Owl.prototype.next = function(speed) {
+               speed = speed || false;
+               this.to(this.relative(this.current()) + 1, speed);
+       };
+
+       /**
+        * Slides to the previous item.
+        * @public
+        * @param {Number} [speed] - The time in milliseconds for the transition.
+        */
+       Owl.prototype.prev = function(speed) {
+               speed = speed || false;
+               this.to(this.relative(this.current()) - 1, speed);
+       };
+
+       /**
+        * Handles the end of an animation.
+        * @protected
+        * @param {Event} event - The event arguments.
+        */
+       Owl.prototype.transitionEnd = function(event) {
+
+               // if css2 animation then event object is undefined
+               if (event !== undefined) {
+                       event.stopPropagation();
+
+                       // Catch only owl-stage transitionEnd event
+                       if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
+                               return false;
+                       }
+               }
+
+               this.state.inMotion = false;
+               this.trigger('translated');
+       };
+
+       /**
+        * Gets viewport width.
+        * @protected
+        * @return {Number} - The width in pixel.
+        */
+       Owl.prototype.viewport = function() {
+               var width;
+               if (this.options.responsiveBaseElement !== window) {
+                       width = $(this.options.responsiveBaseElement).width();
+               } else if (window.innerWidth) {
+                       width = window.innerWidth;
+               } else if (document.documentElement && document.documentElement.clientWidth) {
+                       width = document.documentElement.clientWidth;
+               } else {
+                       throw 'Can not detect viewport width.';
+               }
+               return width;
+       };
+
+       /**
+        * Replaces the current content.
+        * @public
+        * @param {HTMLElement|jQuery|String} content - The new content.
+        */
+       Owl.prototype.replace = function(content) {
+               this.$stage.empty();
+               this._items = [];
+
+               if (content) {
+                       content = (content instanceof jQuery) ? content : $(content);
+               }
+
+               if (this.settings.nestedItemSelector) {
+                       content = content.find('.' + this.settings.nestedItemSelector);
+               }
+
+               content.filter(function() {
+                       return this.nodeType === 1;
+               }).each($.proxy(function(index, item) {
+                       item = this.prepare(item);
+                       this.$stage.append(item);
+                       this._items.push(item);
+                       this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
+               }, this));
+
+               this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
+
+               this.invalidate('items');
+       };
+
+       /**
+        * Adds an item.
+        * @todo Use `item` instead of `content` for the event arguments.
+        * @public
+        * @param {HTMLElement|jQuery|String} content - The item content to add.
+        * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
+        */
+       Owl.prototype.add = function(content, position) {
+               position = position === undefined ? this._items.length : this.normalize(position, true);
+
+               this.trigger('add', { content: content, position: position });
+
+               if (this._items.length === 0 || position === this._items.length) {
+                       this.$stage.append(content);
+                       this._items.push(content);
+                       this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
+               } else {
+                       this._items[position].before(content);
+                       this._items.splice(position, 0, content);
+                       this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
+               }
+
+               this.invalidate('items');
+
+               this.trigger('added', { content: content, position: position });
+       };
+
+       /**
+        * Removes an item by its position.
+        * @todo Use `item` instead of `content` for the event arguments.
+        * @public
+        * @param {Number} position - The relative position of the item to remove.
+        */
+       Owl.prototype.remove = function(position) {
+               position = this.normalize(position, true);
+
+               if (position === undefined) {
+                       return;
+               }
+
+               this.trigger('remove', { content: this._items[position], position: position });
+
+               this._items[position].remove();
+               this._items.splice(position, 1);
+               this._mergers.splice(position, 1);
+
+               this.invalidate('items');
+
+               this.trigger('removed', { content: null, position: position });
+       };
+
+       /**
+        * Adds triggerable events.
+        * @protected
+        */
+       Owl.prototype.addTriggerableEvents = function() {
+               var handler = $.proxy(function(callback, event) {
+                       return $.proxy(function(e) {
+                               if (e.relatedTarget !== this) {
+                                       this.suppress([ event ]);
+                                       callback.apply(this, [].slice.call(arguments, 1));
+                                       this.release([ event ]);
+                               }
+                       }, this);
+               }, this);
+
+               $.each({
+                       'next': this.next,
+                       'prev': this.prev,
+                       'to': this.to,
+                       'destroy': this.destroy,
+                       'refresh': this.refresh,
+                       'replace': this.replace,
+                       'add': this.add,
+                       'remove': this.remove
+               }, $.proxy(function(event, callback) {
+                       this.$element.on(event + '.owl.carousel', handler(callback, event + '.owl.carousel'));
+               }, this));
+
+       };
+
+       /**
+        * Watches the visibility of the carousel element.
+        * @protected
+        */
+       Owl.prototype.watchVisibility = function() {
+
+               // test on zepto
+               if (!isElVisible(this.$element.get(0))) {
+                       this.$element.addClass('owl-hidden');
+                       window.clearInterval(this.e._checkVisibile);
+                       this.e._checkVisibile = window.setInterval($.proxy(checkVisible, this), 500);
+               }
+
+               function isElVisible(el) {
+                       return el.offsetWidth > 0 && el.offsetHeight > 0;
+               }
+
+               function checkVisible() {
+                       if (isElVisible(this.$element.get(0))) {
+                               this.$element.removeClass('owl-hidden');
+                               this.refresh();
+                               window.clearInterval(this.e._checkVisibile);
+                       }
+               }
+       };
+
+       /**
+        * Preloads images with auto width.
+        * @protected
+        * @todo Still to test
+        */
+       Owl.prototype.preloadAutoWidthImages = function(imgs) {
+               var loaded, that, $el, img;
+
+               loaded = 0;
+               that = this;
+               imgs.each(function(i, el) {
+                       $el = $(el);
+                       img = new Image();
+
+                       img.onload = function() {
+                               loaded++;
+                               $el.attr('src', img.src);
+                               $el.css('opacity', 1);
+                               if (loaded >= imgs.length) {
+                                       that.state.imagesLoaded = true;
+                                       that.initialize();
+                               }
+                       };
+
+                       img.src = $el.attr('src') || $el.attr('data-src') || $el.attr('data-src-retina');
+               });
+       };
+
+       /**
+        * Destroys the carousel.
+        * @public
+        */
+       Owl.prototype.destroy = function() {
+
+               if (this.$element.hasClass(this.settings.themeClass)) {
+                       this.$element.removeClass(this.settings.themeClass);
+               }
+
+               if (this.settings.responsive !== false) {
+                       $(window).off('resize.owl.carousel');
+               }
+
+               if (this.transitionEndVendor) {
+                       this.off(this.$stage.get(0), this.transitionEndVendor, this.e._transitionEnd);
+               }
+
+               for ( var i in this._plugins) {
+                       this._plugins[i].destroy();
+               }
+
+               if (this.settings.mouseDrag || this.settings.touchDrag) {
+                       this.$stage.off('mousedown touchstart touchcancel');
+                       $(document).off('.owl.dragEvents');
+                       this.$stage.get(0).onselectstart = function() {};
+                       this.$stage.off('dragstart', function() { return false });
+               }
+
+               // remove event handlers in the ".owl.carousel" namespace
+               this.$element.off('.owl');
+
+               this.$stage.children('.cloned').remove();
+               this.e = null;
+               this.$element.removeData('owlCarousel');
+
+               this.$stage.children().contents().unwrap();
+               this.$stage.children().unwrap();
+               this.$stage.unwrap();
+       };
+
+       /**
+        * Operators to calculate right-to-left and left-to-right.
+        * @protected
+        * @param {Number} [a] - The left side operand.
+        * @param {String} [o] - The operator.
+        * @param {Number} [b] - The right side operand.
+        */
+       Owl.prototype.op = function(a, o, b) {
+               var rtl = this.settings.rtl;
+               switch (o) {
+                       case '<':
+                               return rtl ? a > b : a < b;
+                       case '>':
+                               return rtl ? a < b : a > b;
+                       case '>=':
+                               return rtl ? a <= b : a >= b;
+                       case '<=':
+                               return rtl ? a >= b : a <= b;
+                       default:
+                               break;
+               }
+       };
+
+       /**
+        * Attaches to an internal event.
+        * @protected
+        * @param {HTMLElement} element - The event source.
+        * @param {String} event - The event name.
+        * @param {Function} listener - The event handler to attach.
+        * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
+        */
+       Owl.prototype.on = function(element, event, listener, capture) {
+               if (element.addEventListener) {
+                       element.addEventListener(event, listener, capture);
+               } else if (element.attachEvent) {
+                       element.attachEvent('on' + event, listener);
+               }
+       };
+
+       /**
+        * Detaches from an internal event.
+        * @protected
+        * @param {HTMLElement} element - The event source.
+        * @param {String} event - The event name.
+        * @param {Function} listener - The attached event handler to detach.
+        * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
+        */
+       Owl.prototype.off = function(element, event, listener, capture) {
+               if (element.removeEventListener) {
+                       element.removeEventListener(event, listener, capture);
+               } else if (element.detachEvent) {
+                       element.detachEvent('on' + event, listener);
+               }
+       };
+
+       /**
+        * Triggers an public event.
+        * @protected
+        * @param {String} name - The event name.
+        * @param {*} [data=null] - The event data.
+        * @param {String} [namespace=.owl.carousel] - The event namespace.
+        * @returns {Event} - The event arguments.
+        */
+       Owl.prototype.trigger = function(name, data, namespace) {
+               var status = {
+                       item: { count: this._items.length, index: this.current() }
+               }, handler = $.camelCase(
+                       $.grep([ 'on', name, namespace ], function(v) { return v })
+                               .join('-').toLowerCase()
+               ), event = $.Event(
+                       [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
+                       $.extend({ relatedTarget: this }, status, data)
+               );
+
+               if (!this._supress[name]) {
+                       $.each(this._plugins, function(name, plugin) {
+                               if (plugin.onTrigger) {
+                                       plugin.onTrigger(event);
+                               }
+                       });
+
+                       this.$element.trigger(event);
+
+                       if (this.settings && typeof this.settings[handler] === 'function') {
+                               this.settings[handler].apply(this, event);
+                       }
+               }
+
+               return event;
+       };
+
+       /**
+        * Suppresses events.
+        * @protected
+        * @param {Array.<String>} events - The events to suppress.
+        */
+       Owl.prototype.suppress = function(events) {
+               $.each(events, $.proxy(function(index, event) {
+                       this._supress[event] = true;
+               }, this));
+       }
+
+       /**
+        * Releases suppressed events.
+        * @protected
+        * @param {Array.<String>} events - The events to release.
+        */
+       Owl.prototype.release = function(events) {
+               $.each(events, $.proxy(function(index, event) {
+                       delete this._supress[event];
+               }, this));
+       }
+
+       /**
+        * Checks the availability of some browser features.
+        * @protected
+        */
+       Owl.prototype.browserSupport = function() {
+               this.support3d = isPerspective();
+
+               if (this.support3d) {
+                       this.transformVendor = isTransform();
+
+                       // take transitionend event name by detecting transition
+                       var endVendors = [ 'transitionend', 'webkitTransitionEnd', 'transitionend', 'oTransitionEnd' ];
+                       this.transitionEndVendor = endVendors[isTransition()];
+
+                       // take vendor name from transform name
+                       this.vendorName = this.transformVendor.replace(/Transform/i, '');
+                       this.vendorName = this.vendorName !== '' ? '-' + this.vendorName.toLowerCase() + '-' : '';
+               }
+
+               this.state.orientation = window.orientation;
+       };
+
+       /**
+        * Get touch/drag coordinats.
+        * @private
+        * @param {event} - mousedown/touchstart event
+        * @returns {object} - Contains X and Y of current mouse/touch position
+        */
+
+       function getTouches(event) {
+               if (event.touches !== undefined) {
+                       return {
+                               x: event.touches[0].pageX,
+                               y: event.touches[0].pageY
+                       };
+               }
+
+               if (event.touches === undefined) {
+                       if (event.pageX !== undefined) {
+                               return {
+                                       x: event.pageX,
+                                       y: event.pageY
+                               };
+                       }
+
+               if (event.pageX === undefined) {
+                       return {
+                                       x: event.clientX,
+                                       y: event.clientY
+                               };
+                       }
+               }
+       }
+
+       /**
+        * Checks for CSS support.
+        * @private
+        * @param {Array} array - The CSS properties to check for.
+        * @returns {Array} - Contains the supported CSS property name and its index or `false`.
+        */
+       function isStyleSupported(array) {
+               var p, s, fake = document.createElement('div'), list = array;
+               for (p in list) {
+                       s = list[p];
+                       if (typeof fake.style[s] !== 'undefined') {
+                               fake = null;
+                               return [ s, p ];
+                       }
+               }
+               return [ false ];
+       }
+
+       /**
+        * Checks for CSS transition support.
+        * @private
+        * @todo Realy bad design
+        * @returns {Number}
+        */
+       function isTransition() {
+               return isStyleSupported([ 'transition', 'WebkitTransition', 'MozTransition', 'OTransition' ])[1];
+       }
+
+       /**
+        * Checks for CSS transform support.
+        * @private
+        * @returns {String} The supported property name or false.
+        */
+       function isTransform() {
+               return isStyleSupported([ 'transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ])[0];
+       }
+
+       /**
+        * Checks for CSS perspective support.
+        * @private
+        * @returns {String} The supported property name or false.
+        */
+       function isPerspective() {
+               return isStyleSupported([ 'perspective', 'webkitPerspective', 'MozPerspective', 'OPerspective', 'MsPerspective' ])[0];
+       }
+
+       /**
+        * Checks wether touch is supported or not.
+        * @private
+        * @returns {Boolean}
+        */
+       function isTouchSupport() {
+               return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);
+       }
+
+       /**
+        * Checks wether touch is supported or not for IE.
+        * @private
+        * @returns {Boolean}
+        */
+       function isTouchSupportIE() {
+               return window.navigator.msPointerEnabled;
+       }
+
+       /**
+        * The jQuery Plugin for the Owl Carousel
+        * @public
+        */
+       $.fn.owlCarousel = function(options) {
+               return this.each(function() {
+                       if (!$(this).data('owlCarousel')) {
+                               $(this).data('owlCarousel', new Owl(this, options));
+                       }
+               });
+       };
+
+       /**
+        * The constructor for the jQuery Plugin
+        * @public
+        */
+       $.fn.owlCarousel.Constructor = Owl;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Lazy Plugin
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+       /**
+        * Creates the lazy plugin.
+        * @class The Lazy Plugin
+        * @param {Owl} carousel - The Owl Carousel
+        */
+       var Lazy = function(carousel) {
+
+               /**
+                * Reference to the core.
+                * @protected
+                * @type {Owl}
+                */
+               this._core = carousel;
+
+               /**
+                * Already loaded items.
+                * @protected
+                * @type {Array.<jQuery>}
+                */
+               this._loaded = [];
+
+               /**
+                * Event handlers.
+                * @protected
+                * @type {Object}
+                */
+               this._handlers = {
+                       'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
+                               if (!e.namespace) {
+                                       return;
+                               }
+
+                               if (!this._core.settings || !this._core.settings.lazyLoad) {
+                                       return;
+                               }
+
+                               if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
+                                       var settings = this._core.settings,
+                                               n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
+                                               i = ((settings.center && n * -1) || 0),
+                                               position = ((e.property && e.property.value) || this._core.current()) + i,
+                                               clones = this._core.clones().length,
+                                               load = $.proxy(function(i, v) { this.load(v) }, this);
+
+                                       while (i++ < n) {
+                                               this.load(clones / 2 + this._core.relative(position));
+                                               clones && $.each(this._core.clones(this._core.relative(position++)), load);
+                                       }
+                               }
+                       }, this)
+               };
+
+               // set the default options
+               this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
+
+               // register event handler
+               this._core.$element.on(this._handlers);
+       }
+
+       /**
+        * Default options.
+        * @public
+        */
+       Lazy.Defaults = {
+               lazyLoad: false
+       }
+
+       /**
+        * Loads all resources of an item at the specified position.
+        * @param {Number} position - The absolute position of the item.
+        * @protected
+        */
+       Lazy.prototype.load = function(position) {
+               var $item = this._core.$stage.children().eq(position),
+                       $elements = $item && $item.find('.owl-lazy');
+
+               if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
+                       return;
+               }
+
+               $elements.each($.proxy(function(index, element) {
+                       var $element = $(element), image,
+                               url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
+
+                       this._core.trigger('load', { element: $element, url: url }, 'lazy');
+
+                       if ($element.is('img')) {
+                               $element.one('load.owl.lazy', $.proxy(function() {
+                                       $element.css('opacity', 1);
+                                       this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
+                               }, this)).attr('src', url);
+                       } else {
+                               image = new Image();
+                               image.onload = $.proxy(function() {
+                                       $element.css({
+                                               'background-image': 'url(' + url + ')',
+                                               'opacity': '1'
+                                       });
+                                       this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
+                               }, this);
+                               image.src = url;
+                       }
+               }, this));
+
+               this._loaded.push($item.get(0));
+       }
+
+       /**
+        * Destroys the plugin.
+        * @public
+        */
+       Lazy.prototype.destroy = function() {
+               var handler, property;
+
+               for (handler in this.handlers) {
+                       this._core.$element.off(handler, this.handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       }
+
+       $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * AutoHeight Plugin
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+       /**
+        * Creates the auto height plugin.
+        * @class The Auto Height Plugin
+        * @param {Owl} carousel - The Owl Carousel
+        */
+       var AutoHeight = function(carousel) {
+               /**
+                * Reference to the core.
+                * @protected
+                * @type {Owl}
+                */
+               this._core = carousel;
+
+               /**
+                * All event handlers.
+                * @protected
+                * @type {Object}
+                */
+               this._handlers = {
+                       'initialized.owl.carousel': $.proxy(function() {
+                               if (this._core.settings.autoHeight) {
+                                       this.update();
+                               }
+                       }, this),
+                       'changed.owl.carousel': $.proxy(function(e) {
+                               if (this._core.settings.autoHeight && e.property.name == 'position'){
+                                       this.update();
+                               }
+                       }, this),
+                       'loaded.owl.lazy': $.proxy(function(e) {
+                               if (this._core.settings.autoHeight && e.element.closest('.' + this._core.settings.itemClass)
+                                       === this._core.$stage.children().eq(this._core.current())) {
+                                       this.update();
+                               }
+                       }, this)
+               };
+
+               // set default options
+               this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
+
+               // register event handlers
+               this._core.$element.on(this._handlers);
+       };
+
+       /**
+        * Default options.
+        * @public
+        */
+       AutoHeight.Defaults = {
+               autoHeight: false,
+               autoHeightClass: 'owl-height'
+       };
+
+       /**
+        * Updates the view.
+        */
+       AutoHeight.prototype.update = function() {
+               this._core.$stage.parent()
+                       .height(this._core.$stage.children().eq(this._core.current()).height())
+                       .addClass(this._core.settings.autoHeightClass);
+       };
+
+       AutoHeight.prototype.destroy = function() {
+               var handler, property;
+
+               for (handler in this._handlers) {
+                       this._core.$element.off(handler, this._handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       };
+
+       $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Video Plugin
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+       /**
+        * Creates the video plugin.
+        * @class The Video Plugin
+        * @param {Owl} carousel - The Owl Carousel
+        */
+       var Video = function(carousel) {
+               /**
+                * Reference to the core.
+                * @protected
+                * @type {Owl}
+                */
+               this._core = carousel;
+
+               /**
+                * Cache all video URLs.
+                * @protected
+                * @type {Object}
+                */
+               this._videos = {};
+
+               /**
+                * Current playing item.
+                * @protected
+                * @type {jQuery}
+                */
+               this._playing = null;
+
+               /**
+                * Whether this is in fullscreen or not.
+                * @protected
+                * @type {Boolean}
+                */
+               this._fullscreen = false;
+
+               /**
+                * All event handlers.
+                * @protected
+                * @type {Object}
+                */
+               this._handlers = {
+                       'resize.owl.carousel': $.proxy(function(e) {
+                               if (this._core.settings.video && !this.isInFullScreen()) {
+                                       e.preventDefault();
+                               }
+                       }, this),
+                       'refresh.owl.carousel changed.owl.carousel': $.proxy(function(e) {
+                               if (this._playing) {
+                                       this.stop();
+                               }
+                       }, this),
+                       'prepared.owl.carousel': $.proxy(function(e) {
+                               var $element = $(e.content).find('.owl-video');
+                               if ($element.length) {
+                                       $element.css('display', 'none');
+                                       this.fetch($element, $(e.content));
+                               }
+                       }, this)
+               };
+
+               // set default options
+               this._core.options = $.extend({}, Video.Defaults, this._core.options);
+
+               // register event handlers
+               this._core.$element.on(this._handlers);
+
+               this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
+                       this.play(e);
+               }, this));
+       };
+
+       /**
+        * Default options.
+        * @public
+        */
+       Video.Defaults = {
+               video: false,
+               videoHeight: false,
+               videoWidth: false
+       };
+
+       /**
+        * Gets the video ID and the type (YouTube/Vimeo only).
+        * @protected
+        * @param {jQuery} target - The target containing the video data.
+        * @param {jQuery} item - The item containing the video.
+        */
+       Video.prototype.fetch = function(target, item) {
+
+               var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
+                       id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
+                       width = target.attr('data-width') || this._core.settings.videoWidth,
+                       height = target.attr('data-height') || this._core.settings.videoHeight,
+                       url = target.attr('href');
+
+               if (url) {
+                       id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
+
+                       if (id[3].indexOf('youtu') > -1) {
+                               type = 'youtube';
+                       } else if (id[3].indexOf('vimeo') > -1) {
+                               type = 'vimeo';
+                       } else {
+                               throw new Error('Video URL not supported.');
+                       }
+                       id = id[6];
+               } else {
+                       throw new Error('Missing video URL.');
+               }
+
+               this._videos[url] = {
+                       type: type,
+                       id: id,
+                       width: width,
+                       height: height
+               };
+
+               item.attr('data-video', url);
+
+               this.thumbnail(target, this._videos[url]);
+       };
+
+       /**
+        * Creates video thumbnail.
+        * @protected
+        * @param {jQuery} target - The target containing the video data.
+        * @param {Object} info - The video info object.
+        * @see `fetch`
+        */
+       Video.prototype.thumbnail = function(target, video) {
+
+               var tnLink,
+                       icon,
+                       path,
+                       dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
+                       customTn = target.find('img'),
+                       srcType = 'src',
+                       lazyClass = '',
+                       settings = this._core.settings,
+                       create = function(path) {
+                               icon = '<div class="owl-video-play-icon"></div>';
+
+                               if (settings.lazyLoad) {
+                                       tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
+                               } else {
+                                       tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
+                               }
+                               target.after(tnLink);
+                               target.after(icon);
+                       };
+
+               // wrap video content into owl-video-wrapper div
+               target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
+
+               if (this._core.settings.lazyLoad) {
+                       srcType = 'data-src';
+                       lazyClass = 'owl-lazy';
+               }
+
+               // custom thumbnail
+               if (customTn.length) {
+                       create(customTn.attr(srcType));
+                       customTn.remove();
+                       return false;
+               }
+
+               if (video.type === 'youtube') {
+                       path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
+                       create(path);
+               } else if (video.type === 'vimeo') {
+                       $.ajax({
+                               type: 'GET',
+                               url: 'http://vimeo.com/api/v2/video/' + video.id + '.json',
+                               jsonp: 'callback',
+                               dataType: 'jsonp',
+                               success: function(data) {
+                                       path = data[0].thumbnail_large;
+                                       create(path);
+                               }
+                       });
+               }
+       };
+
+       /**
+        * Stops the current video.
+        * @public
+        */
+       Video.prototype.stop = function() {
+               this._core.trigger('stop', null, 'video');
+               this._playing.find('.owl-video-frame').remove();
+               this._playing.removeClass('owl-video-playing');
+               this._playing = null;
+       };
+
+       /**
+        * Starts the current video.
+        * @public
+        * @param {Event} ev - The event arguments.
+        */
+       Video.prototype.play = function(ev) {
+               this._core.trigger('play', null, 'video');
+
+               if (this._playing) {
+                       this.stop();
+               }
+
+               var target = $(ev.target || ev.srcElement),
+                       item = target.closest('.' + this._core.settings.itemClass),
+                       video = this._videos[item.attr('data-video')],
+                       width = video.width || '100%',
+                       height = video.height || this._core.$stage.height(),
+                       html, wrap;
+
+               if (video.type === 'youtube') {
+                       html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/'
+                               + video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
+               } else if (video.type === 'vimeo') {
+                       html = '<iframe src="http://player.vimeo.com/video/' + video.id + '?autoplay=1" width="' + width
+                               + '" height="' + height
+                               + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
+               }
+
+               item.addClass('owl-video-playing');
+               this._playing = item;
+
+               wrap = $('<div style="height:' + height + 'px; width:' + width + 'px" class="owl-video-frame">'
+                       + html + '</div>');
+               target.after(wrap);
+       };
+
+       /**
+        * Checks whether an video is currently in full screen mode or not.
+        * @todo Bad style because looks like a readonly method but changes members.
+        * @protected
+        * @returns {Boolean}
+        */
+       Video.prototype.isInFullScreen = function() {
+
+               // if Vimeo Fullscreen mode
+               var element = document.fullscreenElement || document.mozFullScreenElement
+                       || document.webkitFullscreenElement;
+
+               if (element && $(element).parent().hasClass('owl-video-frame')) {
+                       this._core.speed(0);
+                       this._fullscreen = true;
+               }
+
+               if (element && this._fullscreen && this._playing) {
+                       return false;
+               }
+
+               // comming back from fullscreen
+               if (this._fullscreen) {
+                       this._fullscreen = false;
+                       return false;
+               }
+
+               // check full screen mode and window orientation
+               if (this._playing) {
+                       if (this._core.state.orientation !== window.orientation) {
+                               this._core.state.orientation = window.orientation;
+                               return false;
+                       }
+               }
+
+               return true;
+       };
+
+       /**
+        * Destroys the plugin.
+        */
+       Video.prototype.destroy = function() {
+               var handler, property;
+
+               this._core.$element.off('click.owl.video');
+
+               for (handler in this._handlers) {
+                       this._core.$element.off(handler, this._handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       };
+
+       $.fn.owlCarousel.Constructor.Plugins.Video = Video;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Animate Plugin
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+       /**
+        * Creates the animate plugin.
+        * @class The Navigation Plugin
+        * @param {Owl} scope - The Owl Carousel
+        */
+       var Animate = function(scope) {
+               this.core = scope;
+               this.core.options = $.extend({}, Animate.Defaults, this.core.options);
+               this.swapping = true;
+               this.previous = undefined;
+               this.next = undefined;
+
+               this.handlers = {
+                       'change.owl.carousel': $.proxy(function(e) {
+                               if (e.property.name == 'position') {
+                                       this.previous = this.core.current();
+                                       this.next = e.property.value;
+                               }
+                       }, this),
+                       'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
+                               this.swapping = e.type == 'translated';
+                       }, this),
+                       'translate.owl.carousel': $.proxy(function(e) {
+                               if (this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
+                                       this.swap();
+                               }
+                       }, this)
+               };
+
+               this.core.$element.on(this.handlers);
+       };
+
+       /**
+        * Default options.
+        * @public
+        */
+       Animate.Defaults = {
+               animateOut: false,
+               animateIn: false
+       };
+
+       /**
+        * Toggles the animation classes whenever an translations starts.
+        * @protected
+        * @returns {Boolean|undefined}
+        */
+       Animate.prototype.swap = function() {
+
+               if (this.core.settings.items !== 1 || !this.core.support3d) {
+                       return;
+               }
+
+               this.core.speed(0);
+
+               var left,
+                       clear = $.proxy(this.clear, this),
+                       previous = this.core.$stage.children().eq(this.previous),
+                       next = this.core.$stage.children().eq(this.next),
+                       incoming = this.core.settings.animateIn,
+                       outgoing = this.core.settings.animateOut;
+
+               if (this.core.current() === this.previous) {
+                       return;
+               }
+
+               if (outgoing) {
+                       left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
+                       previous.css( { 'left': left + 'px' } )
+                               .addClass('animated owl-animated-out')
+                               .addClass(outgoing)
+                               .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
+               }
+
+               if (incoming) {
+                       next.addClass('animated owl-animated-in')
+                               .addClass(incoming)
+                               .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', clear);
+               }
+       };
+
+       Animate.prototype.clear = function(e) {
+               $(e.target).css( { 'left': '' } )
+                       .removeClass('animated owl-animated-out owl-animated-in')
+                       .removeClass(this.core.settings.animateIn)
+                       .removeClass(this.core.settings.animateOut);
+               this.core.transitionEnd();
+       }
+
+       /**
+        * Destroys the plugin.
+        * @public
+        */
+       Animate.prototype.destroy = function() {
+               var handler, property;
+
+               for (handler in this.handlers) {
+                       this.core.$element.off(handler, this.handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       };
+
+       $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Autoplay Plugin
+ * @version 2.0.0
+ * @author Bartosz Wojciechowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+       /**
+        * Creates the autoplay plugin.
+        * @class The Autoplay Plugin
+        * @param {Owl} scope - The Owl Carousel
+        */
+       var Autoplay = function(scope) {
+               this.core = scope;
+               this.core.options = $.extend({}, Autoplay.Defaults, this.core.options);
+
+               this.handlers = {
+                       'translated.owl.carousel refreshed.owl.carousel': $.proxy(function() {
+                               this.autoplay();
+                       }, this),
+                       'play.owl.autoplay': $.proxy(function(e, t, s) {
+                               this.play(t, s);
+                       }, this),
+                       'stop.owl.autoplay': $.proxy(function() {
+                               this.stop();
+                       }, this),
+                       'mouseover.owl.autoplay': $.proxy(function() {
+                               if (this.core.settings.autoplayHoverPause) {
+                                       this.pause();
+                               }
+                       }, this),
+                       'mouseleave.owl.autoplay': $.proxy(function() {
+                               if (this.core.settings.autoplayHoverPause) {
+                                       this.autoplay();
+                               }
+                       }, this)
+               };
+
+               this.core.$element.on(this.handlers);
+       };
+
+       /**
+        * Default options.
+        * @public
+        */
+       Autoplay.Defaults = {
+               autoplay: false,
+               autoplayTimeout: 5000,
+               autoplayHoverPause: false,
+               autoplaySpeed: false
+       };
+
+       /**
+        * @protected
+        * @todo Must be documented.
+        */
+       Autoplay.prototype.autoplay = function() {
+               if (this.core.settings.autoplay && !this.core.state.videoPlay) {
+                       window.clearInterval(this.interval);
+
+                       this.interval = window.setInterval($.proxy(function() {
+                               this.play();
+                       }, this), this.core.settings.autoplayTimeout);
+               } else {
+                       window.clearInterval(this.interval);
+               }
+       };
+
+       /**
+        * Starts the autoplay.
+        * @public
+        * @param {Number} [timeout] - ...
+        * @param {Number} [speed] - ...
+        * @returns {Boolean|undefined} - ...
+        * @todo Must be documented.
+        */
+       Autoplay.prototype.play = function(timeout, speed) {
+               // if tab is inactive - doesnt work in <IE10
+               if (document.hidden === true) {
+                       return;
+               }
+
+               if (this.core.state.isTouch || this.core.state.isScrolling
+                       || this.core.state.isSwiping || this.core.state.inMotion) {
+                       return;
+               }
+
+               if (this.core.settings.autoplay === false) {
+                       window.clearInterval(this.interval);
+                       return;
+               }
+
+               this.core.next(this.core.settings.autoplaySpeed);
+       };
+
+       /**
+        * Stops the autoplay.
+        * @public
+        */
+       Autoplay.prototype.stop = function() {
+               window.clearInterval(this.interval);
+       };
+
+       /**
+        * Pauses the autoplay.
+        * @public
+        */
+       Autoplay.prototype.pause = function() {
+               window.clearInterval(this.interval);
+       };
+
+       /**
+        * Destroys the plugin.
+        */
+       Autoplay.prototype.destroy = function() {
+               var handler, property;
+
+               window.clearInterval(this.interval);
+
+               for (handler in this.handlers) {
+                       this.core.$element.off(handler, this.handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       };
+
+       $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Navigation Plugin
+ * @version 2.0.0
+ * @author Artus Kolanowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+       'use strict';
+
+       /**
+        * Creates the navigation plugin.
+        * @class The Navigation Plugin
+        * @param {Owl} carousel - The Owl Carousel.
+        */
+       var Navigation = function(carousel) {
+               /**
+                * Reference to the core.
+                * @protected
+                * @type {Owl}
+                */
+               this._core = carousel;
+
+               /**
+                * Indicates whether the plugin is initialized or not.
+                * @protected
+                * @type {Boolean}
+                */
+               this._initialized = false;
+
+               /**
+                * The current paging indexes.
+                * @protected
+                * @type {Array}
+                */
+               this._pages = [];
+
+               /**
+                * All DOM elements of the user interface.
+                * @protected
+                * @type {Object}
+                */
+               this._controls = {};
+
+               /**
+                * Markup for an indicator.
+                * @protected
+                * @type {Array.<String>}
+                */
+               this._templates = [];
+
+               /**
+                * The carousel element.
+                * @type {jQuery}
+                */
+               this.$element = this._core.$element;
+
+               /**
+                * Overridden methods of the carousel.
+                * @protected
+                * @type {Object}
+                */
+               this._overrides = {
+                       next: this._core.next,
+                       prev: this._core.prev,
+                       to: this._core.to
+               };
+
+               /**
+                * All event handlers.
+                * @protected
+                * @type {Object}
+                */
+               this._handlers = {
+                       'prepared.owl.carousel': $.proxy(function(e) {
+                               if (this._core.settings.dotsData) {
+                                       this._templates.push($(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
+                               }
+                       }, this),
+                       'add.owl.carousel': $.proxy(function(e) {
+                               if (this._core.settings.dotsData) {
+                                       this._templates.splice(e.position, 0, $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot'));
+                               }
+                       }, this),
+                       'remove.owl.carousel prepared.owl.carousel': $.proxy(function(e) {
+                               if (this._core.settings.dotsData) {
+                                       this._templates.splice(e.position, 1);
+                               }
+                       }, this),
+                       'change.owl.carousel': $.proxy(function(e) {
+                               if (e.property.name == 'position') {
+                                       if (!this._core.state.revert && !this._core.settings.loop && this._core.settings.navRewind) {
+                                               var current = this._core.current(),
+                                                       maximum = this._core.maximum(),
+                                                       minimum = this._core.minimum();
+                                               e.data = e.property.value > maximum
+                                                       ? current >= maximum ? minimum : maximum
+                                                       : e.property.value < minimum ? maximum : e.property.value;
+                                       }
+                               }
+                       }, this),
+                       'changed.owl.carousel': $.proxy(function(e) {
+                               if (e.property.name == 'position') {
+                                       this.draw();
+                               }
+                       }, this),
+                       'refreshed.owl.carousel': $.proxy(function() {
+                               if (!this._initialized) {
+                                       this.initialize();
+                                       this._initialized = true;
+                               }
+                               this._core.trigger('refresh', null, 'navigation');
+                               this.update();
+                               this.draw();
+                               this._core.trigger('refreshed', null, 'navigation');
+                       }, this)
+               };
+
+               // set default options
+               this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
+
+               // register event handlers
+               this.$element.on(this._handlers);
+       }
+
+       /**
+        * Default options.
+        * @public
+        * @todo Rename `slideBy` to `navBy`
+        */
+       Navigation.Defaults = {
+               nav: false,
+               navRewind: true,
+               navText: [ 'prev', 'next' ],
+               navSpeed: false,
+               navElement: 'div',
+               navContainer: false,
+               navContainerClass: 'owl-nav',
+               navClass: [ 'owl-prev', 'owl-next' ],
+               slideBy: 1,
+               dotClass: 'owl-dot',
+               dotsClass: 'owl-dots',
+               dots: true,
+               dotsEach: false,
+               dotData: false,
+               dotsSpeed: false,
+               dotsContainer: false,
+               controlsClass: 'owl-controls'
+       }
+
+       /**
+        * Initializes the layout of the plugin and extends the carousel.
+        * @protected
+        */
+       Navigation.prototype.initialize = function() {
+               var $container, override,
+                       options = this._core.settings;
+
+               // create the indicator template
+               if (!options.dotsData) {
+                       this._templates = [ $('<div>')
+                               .addClass(options.dotClass)
+                               .append($('<span>'))
+                               .prop('outerHTML') ];
+               }
+
+               // create controls container if needed
+               if (!options.navContainer || !options.dotsContainer) {
+                       this._controls.$container = $('<div>')
+                               .addClass(options.controlsClass)
+                               .appendTo(this.$element);
+               }
+
+               // create DOM structure for absolute navigation
+               this._controls.$indicators = options.dotsContainer ? $(options.dotsContainer)
+                       : $('<div>').hide().addClass(options.dotsClass).appendTo(this._controls.$container);
+
+               this._controls.$indicators.on('click', 'div', $.proxy(function(e) {
+                       var index = $(e.target).parent().is(this._controls.$indicators)
+                               ? $(e.target).index() : $(e.target).parent().index();
+
+                       e.preventDefault();
+
+                       this.to(index, options.dotsSpeed);
+               }, this));
+
+               // create DOM structure for relative navigation
+               $container = options.navContainer ? $(options.navContainer)
+                       : $('<div>').addClass(options.navContainerClass).prependTo(this._controls.$container);
+
+               this._controls.$next = $('<' + options.navElement + '>');
+               this._controls.$previous = this._controls.$next.clone();
+
+               this._controls.$previous
+                       .addClass(options.navClass[0])
+                       .html(options.navText[0])
+                       .hide()
+                       .prependTo($container)
+                       .on('click', $.proxy(function(e) {
+                               this.prev(options.navSpeed);
+                       }, this));
+               this._controls.$next
+                       .addClass(options.navClass[1])
+                       .html(options.navText[1])
+                       .hide()
+                       .appendTo($container)
+                       .on('click', $.proxy(function(e) {
+                               this.next(options.navSpeed);
+                       }, this));
+
+               // override public methods of the carousel
+               for (override in this._overrides) {
+                       this._core[override] = $.proxy(this[override], this);
+               }
+       }
+
+       /**
+        * Destroys the plugin.
+        * @protected
+        */
+       Navigation.prototype.destroy = function() {
+               var handler, control, property, override;
+
+               for (handler in this._handlers) {
+                       this.$element.off(handler, this._handlers[handler]);
+               }
+               for (control in this._controls) {
+                       this._controls[control].remove();
+               }
+               for (override in this.overides) {
+                       this._core[override] = this._overrides[override];
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       }
+
+       /**
+        * Updates the internal state.
+        * @protected
+        */
+       Navigation.prototype.update = function() {
+               var i, j, k,
+                       options = this._core.settings,
+                       lower = this._core.clones().length / 2,
+                       upper = lower + this._core.items().length,
+                       size = options.center || options.autoWidth || options.dotData
+                               ? 1 : options.dotsEach || options.items;
+
+               if (options.slideBy !== 'page') {
+                       options.slideBy = Math.min(options.slideBy, options.items);
+               }
+
+               if (options.dots || options.slideBy == 'page') {
+                       this._pages = [];
+
+                       for (i = lower, j = 0, k = 0; i < upper; i++) {
+                               if (j >= size || j === 0) {
+                                       this._pages.push({
+                                               start: i - lower,
+                                               end: i - lower + size - 1
+                                       });
+                                       j = 0, ++k;
+                               }
+                               j += this._core.mergers(this._core.relative(i));
+                       }
+               }
+       }
+
+       /**
+        * Draws the user interface.
+        * @todo The option `dotData` wont work.
+        * @protected
+        */
+       Navigation.prototype.draw = function() {
+               var difference, i, html = '',
+                       options = this._core.settings,
+                       $items = this._core.$stage.children(),
+                       index = this._core.relative(this._core.current());
+
+               if (options.nav && !options.loop && !options.navRewind) {
+                       this._controls.$previous.toggleClass('disabled', index <= 0);
+                       this._controls.$next.toggleClass('disabled', index >= this._core.maximum());
+               }
+
+               this._controls.$previous.toggle(options.nav);
+               this._controls.$next.toggle(options.nav);
+
+               if (options.dots) {
+                       difference = this._pages.length - this._controls.$indicators.children().length;
+
+                       if (options.dotData && difference !== 0) {
+                               for (i = 0; i < this._controls.$indicators.children().length; i++) {
+                                       html += this._templates[this._core.relative(i)];
+                               }
+                               this._controls.$indicators.html(html);
+                       } else if (difference > 0) {
+                               html = new Array(difference + 1).join(this._templates[0]);
+                               this._controls.$indicators.append(html);
+                       } else if (difference < 0) {
+                               this._controls.$indicators.children().slice(difference).remove();
+                       }
+
+                       this._controls.$indicators.find('.active').removeClass('active');
+                       this._controls.$indicators.children().eq($.inArray(this.current(), this._pages)).addClass('active');
+               }
+
+               this._controls.$indicators.toggle(options.dots);
+       }
+
+       /**
+        * Extends event data.
+        * @protected
+        * @param {Event} event - The event object which gets thrown.
+        */
+       Navigation.prototype.onTrigger = function(event) {
+               var settings = this._core.settings;
+
+               event.page = {
+                       index: $.inArray(this.current(), this._pages),
+                       count: this._pages.length,
+                       size: settings && (settings.center || settings.autoWidth || settings.dotData
+                               ? 1 : settings.dotsEach || settings.items)
+               };
+       }
+
+       /**
+        * Gets the current page position of the carousel.
+        * @protected
+        * @returns {Number}
+        */
+       Navigation.prototype.current = function() {
+               var index = this._core.relative(this._core.current());
+               return $.grep(this._pages, function(o) {
+                       return o.start <= index && o.end >= index;
+               }).pop();
+       }
+
+       /**
+        * Gets the current succesor/predecessor position.
+        * @protected
+        * @returns {Number}
+        */
+       Navigation.prototype.getPosition = function(successor) {
+               var position, length,
+                       options = this._core.settings;
+
+               if (options.slideBy == 'page') {
+                       position = $.inArray(this.current(), this._pages);
+                       length = this._pages.length;
+                       successor ? ++position : --position;
+                       position = this._pages[((position % length) + length) % length].start;
+               } else {
+                       position = this._core.relative(this._core.current());
+                       length = this._core.items().length;
+                       successor ? position += options.slideBy : position -= options.slideBy;
+               }
+               return position;
+       }
+
+       /**
+        * Slides to the next item or page.
+        * @public
+        * @param {Number} [speed=false] - The time in milliseconds for the transition.
+        */
+       Navigation.prototype.next = function(speed) {
+               $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
+       }
+
+       /**
+        * Slides to the previous item or page.
+        * @public
+        * @param {Number} [speed=false] - The time in milliseconds for the transition.
+        */
+       Navigation.prototype.prev = function(speed) {
+               $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
+       }
+
+       /**
+        * Slides to the specified item or page.
+        * @public
+        * @param {Number} position - The position of the item or page.
+        * @param {Number} [speed] - The time in milliseconds for the transition.
+        * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
+        */
+       Navigation.prototype.to = function(position, speed, standard) {
+               var length;
+
+               if (!standard) {
+                       length = this._pages.length;
+                       $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
+               } else {
+                       $.proxy(this._overrides.to, this._core)(position, speed);
+               }
+       }
+
+       $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Hash Plugin
+ * @version 2.0.0
+ * @author Artus Kolanowski
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+       'use strict';
+
+       /**
+        * Creates the hash plugin.
+        * @class The Hash Plugin
+        * @param {Owl} carousel - The Owl Carousel
+        */
+       var Hash = function(carousel) {
+               /**
+                * Reference to the core.
+                * @protected
+                * @type {Owl}
+                */
+               this._core = carousel;
+
+               /**
+                * Hash table for the hashes.
+                * @protected
+                * @type {Object}
+                */
+               this._hashes = {};
+
+               /**
+                * The carousel element.
+                * @type {jQuery}
+                */
+               this.$element = this._core.$element;
+
+               /**
+                * All event handlers.
+                * @protected
+                * @type {Object}
+                */
+               this._handlers = {
+                       'initialized.owl.carousel': $.proxy(function() {
+                               if (this._core.settings.startPosition == 'URLHash') {
+                                       $(window).trigger('hashchange.owl.navigation');
+                               }
+                       }, this),
+                       'prepared.owl.carousel': $.proxy(function(e) {
+                               var hash = $(e.content).find('[data-hash]').andSelf('[data-hash]').attr('data-hash');
+                               this._hashes[hash] = e.content;
+                       }, this)
+               };
+
+               // set default options
+               this._core.options = $.extend({}, Hash.Defaults, this._core.options);
+
+               // register the event handlers
+               this.$element.on(this._handlers);
+
+               // register event listener for hash navigation
+               $(window).on('hashchange.owl.navigation', $.proxy(function() {
+                       var hash = window.location.hash.substring(1),
+                               items = this._core.$stage.children(),
+                               position = this._hashes[hash] && items.index(this._hashes[hash]) || 0;
+
+                       if (!hash) {
+                               return false;
+                       }
+
+                       this._core.to(position, false, true);
+               }, this));
+       }
+
+       /**
+        * Default options.
+        * @public
+        */
+       Hash.Defaults = {
+               URLhashListener: false
+       }
+
+       /**
+        * Destroys the plugin.
+        * @public
+        */
+       Hash.prototype.destroy = function() {
+               var handler, property;
+
+               $(window).off('hashchange.owl.navigation');
+
+               for (handler in this._handlers) {
+                       this._core.$element.off(handler, this._handlers[handler]);
+               }
+               for (property in Object.getOwnPropertyNames(this)) {
+                       typeof this[property] != 'function' && (this[property] = null);
+               }
+       }
+
+       $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
+
+})(window.Zepto || window.jQuery, window, document);
diff --git a/src/main/resources/META-INF/resources/designer/lib/owl.carousel.min.js b/src/main/resources/META-INF/resources/designer/lib/owl.carousel.min.js
new file mode 100644 (file)
index 0000000..f2a15f6
--- /dev/null
@@ -0,0 +1,2 @@
+!function(a,b,c,d){function e(b,c){this.settings=null,this.options=a.extend({},e.Defaults,c),this.$element=a(b),this.drag=a.extend({},m),this.state=a.extend({},n),this.e=a.extend({},o),this._plugins={},this._supress={},this._current=null,this._speed=null,this._coordinates=[],this._breakpoint=null,this._width=null,this._items=[],this._clones=[],this._mergers=[],this._invalidated={},this._pipe=[],a.each(e.Plugins,a.proxy(function(a,b){this._plugins[a[0].toLowerCase()+a.slice(1)]=new b(this)},this)),a.each(e.Pipe,a.proxy(function(b,c){this._pipe.push({filter:c.filter,run:a.proxy(c.run,this)})},this)),this.setup(),this.initialize()}function f(a){if(a.touches!==d)return{x:a.touches[0].pageX,y:a.touches[0].pageY};if(a.touches===d){if(a.pageX!==d)return{x:a.pageX,y:a.pageY};if(a.pageX===d)return{x:a.clientX,y:a.clientY}}}function g(a){var b,d,e=c.createElement("div"),f=a;for(b in f)if(d=f[b],"undefined"!=typeof e.style[d])return e=null,[d,b];return[!1]}function h(){return g(["transition","WebkitTransition","MozTransition","OTransition"])[1]}function i(){return g(["transform","WebkitTransform","MozTransform","OTransform","msTransform"])[0]}function j(){return g(["perspective","webkitPerspective","MozPerspective","OPerspective","MsPerspective"])[0]}function k(){return"ontouchstart"in b||!!navigator.msMaxTouchPoints}function l(){return b.navigator.msPointerEnabled}var m,n,o;m={start:0,startX:0,startY:0,current:0,currentX:0,currentY:0,offsetX:0,offsetY:0,distance:null,startTime:0,endTime:0,updatedX:0,targetEl:null},n={isTouch:!1,isScrolling:!1,isSwiping:!1,direction:!1,inMotion:!1},o={_onDragStart:null,_onDragMove:null,_onDragEnd:null,_transitionEnd:null,_resizer:null,_responsiveCall:null,_goToLoop:null,_checkVisibile:null},e.Defaults={items:3,loop:!1,center:!1,mouseDrag:!0,touchDrag:!0,pullDrag:!0,freeDrag:!1,margin:0,stagePadding:0,merge:!1,mergeFit:!0,autoWidth:!1,startPosition:0,rtl:!1,smartSpeed:250,fluidSpeed:!1,dragEndSpeed:!1,responsive:{},responsiveRefreshRate:200,responsiveBaseElement:b,responsiveClass:!1,fallbackEasing:"swing",info:!1,nestedItemSelector:!1,itemElement:"div",stageElement:"div",themeClass:"owl-theme",baseClass:"owl-carousel",itemClass:"owl-item",centerClass:"center",activeClass:"active"},e.Width={Default:"default",Inner:"inner",Outer:"outer"},e.Plugins={},e.Pipe=[{filter:["width","items","settings"],run:function(a){a.current=this._items&&this._items[this.relative(this._current)]}},{filter:["items","settings"],run:function(){var a=this._clones,b=this.$stage.children(".cloned");(b.length!==a.length||!this.settings.loop&&a.length>0)&&(this.$stage.children(".cloned").remove(),this._clones=[])}},{filter:["items","settings"],run:function(){var a,b,c=this._clones,d=this._items,e=this.settings.loop?c.length-Math.max(2*this.settings.items,4):0;for(a=0,b=Math.abs(e/2);b>a;a++)e>0?(this.$stage.children().eq(d.length+c.length-1).remove(),c.pop(),this.$stage.children().eq(0).remove(),c.pop()):(c.push(c.length/2),this.$stage.append(d[c[c.length-1]].clone().addClass("cloned")),c.push(d.length-1-(c.length-1)/2),this.$stage.prepend(d[c[c.length-1]].clone().addClass("cloned")))}},{filter:["width","items","settings"],run:function(){var a,b,c,d=this.settings.rtl?1:-1,e=(this.width()/this.settings.items).toFixed(3),f=0;for(this._coordinates=[],b=0,c=this._clones.length+this._items.length;c>b;b++)a=this._mergers[this.relative(b)],a=this.settings.mergeFit&&Math.min(a,this.settings.items)||a,f+=(this.settings.autoWidth?this._items[this.relative(b)].width()+this.settings.margin:e*a)*d,this._coordinates.push(f)}},{filter:["width","items","settings"],run:function(){var b,c,d=(this.width()/this.settings.items).toFixed(3),e={width:Math.abs(this._coordinates[this._coordinates.length-1])+2*this.settings.stagePadding,"padding-left":this.settings.stagePadding||"","padding-right":this.settings.stagePadding||""};if(this.$stage.css(e),e={width:this.settings.autoWidth?"auto":d-this.settings.margin},e[this.settings.rtl?"margin-left":"margin-right"]=this.settings.margin,!this.settings.autoWidth&&a.grep(this._mergers,function(a){return a>1}).length>0)for(b=0,c=this._coordinates.length;c>b;b++)e.width=Math.abs(this._coordinates[b])-Math.abs(this._coordinates[b-1]||0)-this.settings.margin,this.$stage.children().eq(b).css(e);else this.$stage.children().css(e)}},{filter:["width","items","settings"],run:function(a){a.current&&this.reset(this.$stage.children().index(a.current))}},{filter:["position"],run:function(){this.animate(this.coordinates(this._current))}},{filter:["width","position","items","settings"],run:function(){var a,b,c,d,e=this.settings.rtl?1:-1,f=2*this.settings.stagePadding,g=this.coordinates(this.current())+f,h=g+this.width()*e,i=[];for(c=0,d=this._coordinates.length;d>c;c++)a=this._coordinates[c-1]||0,b=Math.abs(this._coordinates[c])+f*e,(this.op(a,"<=",g)&&this.op(a,">",h)||this.op(b,"<",g)&&this.op(b,">",h))&&i.push(c);this.$stage.children("."+this.settings.activeClass).removeClass(this.settings.activeClass),this.$stage.children(":eq("+i.join("), :eq(")+")").addClass(this.settings.activeClass),this.settings.center&&(this.$stage.children("."+this.settings.centerClass).removeClass(this.settings.centerClass),this.$stage.children().eq(this.current()).addClass(this.settings.centerClass))}}],e.prototype.initialize=function(){if(this.trigger("initialize"),this.$element.addClass(this.settings.baseClass).addClass(this.settings.themeClass).toggleClass("owl-rtl",this.settings.rtl),this.browserSupport(),this.settings.autoWidth&&this.state.imagesLoaded!==!0){var b,c,e;if(b=this.$element.find("img"),c=this.settings.nestedItemSelector?"."+this.settings.nestedItemSelector:d,e=this.$element.children(c).width(),b.length&&0>=e)return this.preloadAutoWidthImages(b),!1}this.$element.addClass("owl-loading"),this.$stage=a("<"+this.settings.stageElement+' class="owl-stage"/>').wrap('<div class="owl-stage-outer">'),this.$element.append(this.$stage.parent()),this.replace(this.$element.children().not(this.$stage.parent())),this._width=this.$element.width(),this.refresh(),this.$element.removeClass("owl-loading").addClass("owl-loaded"),this.eventsCall(),this.internalEvents(),this.addTriggerableEvents(),this.trigger("initialized")},e.prototype.setup=function(){var b=this.viewport(),c=this.options.responsive,d=-1,e=null;c?(a.each(c,function(a){b>=a&&a>d&&(d=Number(a))}),e=a.extend({},this.options,c[d]),delete e.responsive,e.responsiveClass&&this.$element.attr("class",function(a,b){return b.replace(/\b owl-responsive-\S+/g,"")}).addClass("owl-responsive-"+d)):e=a.extend({},this.options),(null===this.settings||this._breakpoint!==d)&&(this.trigger("change",{property:{name:"settings",value:e}}),this._breakpoint=d,this.settings=e,this.invalidate("settings"),this.trigger("changed",{property:{name:"settings",value:this.settings}}))},e.prototype.optionsLogic=function(){this.$element.toggleClass("owl-center",this.settings.center),this.settings.loop&&this._items.length<this.settings.items&&(this.settings.loop=!1),this.settings.autoWidth&&(this.settings.stagePadding=!1,this.settings.merge=!1)},e.prototype.prepare=function(b){var c=this.trigger("prepare",{content:b});return c.data||(c.data=a("<"+this.settings.itemElement+"/>").addClass(this.settings.itemClass).append(b)),this.trigger("prepared",{content:c.data}),c.data},e.prototype.update=function(){for(var b=0,c=this._pipe.length,d=a.proxy(function(a){return this[a]},this._invalidated),e={};c>b;)(this._invalidated.all||a.grep(this._pipe[b].filter,d).length>0)&&this._pipe[b].run(e),b++;this._invalidated={}},e.prototype.width=function(a){switch(a=a||e.Width.Default){case e.Width.Inner:case e.Width.Outer:return this._width;default:return this._width-2*this.settings.stagePadding+this.settings.margin}},e.prototype.refresh=function(){if(0===this._items.length)return!1;(new Date).getTime();this.trigger("refresh"),this.setup(),this.optionsLogic(),this.$stage.addClass("owl-refresh"),this.update(),this.$stage.removeClass("owl-refresh"),this.state.orientation=b.orientation,this.watchVisibility(),this.trigger("refreshed")},e.prototype.eventsCall=function(){this.e._onDragStart=a.proxy(function(a){this.onDragStart(a)},this),this.e._onDragMove=a.proxy(function(a){this.onDragMove(a)},this),this.e._onDragEnd=a.proxy(function(a){this.onDragEnd(a)},this),this.e._onResize=a.proxy(function(a){this.onResize(a)},this),this.e._transitionEnd=a.proxy(function(a){this.transitionEnd(a)},this),this.e._preventClick=a.proxy(function(a){this.preventClick(a)},this)},e.prototype.onThrottledResize=function(){b.clearTimeout(this.resizeTimer),this.resizeTimer=b.setTimeout(this.e._onResize,this.settings.responsiveRefreshRate)},e.prototype.onResize=function(){return this._items.length?this._width===this.$element.width()?!1:this.trigger("resize").isDefaultPrevented()?!1:(this._width=this.$element.width(),this.invalidate("width"),this.refresh(),void this.trigger("resized")):!1},e.prototype.eventsRouter=function(a){var b=a.type;"mousedown"===b||"touchstart"===b?this.onDragStart(a):"mousemove"===b||"touchmove"===b?this.onDragMove(a):"mouseup"===b||"touchend"===b?this.onDragEnd(a):"touchcancel"===b&&this.onDragEnd(a)},e.prototype.internalEvents=function(){var c=(k(),l());this.settings.mouseDrag?(this.$stage.on("mousedown",a.proxy(function(a){this.eventsRouter(a)},this)),this.$stage.on("dragstart",function(){return!1}),this.$stage.get(0).onselectstart=function(){return!1}):this.$element.addClass("owl-text-select-on"),this.settings.touchDrag&&!c&&this.$stage.on("touchstart touchcancel",a.proxy(function(a){this.eventsRouter(a)},this)),this.transitionEndVendor&&this.on(this.$stage.get(0),this.transitionEndVendor,this.e._transitionEnd,!1),this.settings.responsive!==!1&&this.on(b,"resize",a.proxy(this.onThrottledResize,this))},e.prototype.onDragStart=function(d){var e,g,h,i;if(e=d.originalEvent||d||b.event,3===e.which||this.state.isTouch)return!1;if("mousedown"===e.type&&this.$stage.addClass("owl-grab"),this.trigger("drag"),this.drag.startTime=(new Date).getTime(),this.speed(0),this.state.isTouch=!0,this.state.isScrolling=!1,this.state.isSwiping=!1,this.drag.distance=0,g=f(e).x,h=f(e).y,this.drag.offsetX=this.$stage.position().left,this.drag.offsetY=this.$stage.position().top,this.settings.rtl&&(this.drag.offsetX=this.$stage.position().left+this.$stage.width()-this.width()+this.settings.margin),this.state.inMotion&&this.support3d)i=this.getTransformProperty(),this.drag.offsetX=i,this.animate(i),this.state.inMotion=!0;else if(this.state.inMotion&&!this.support3d)return this.state.inMotion=!1,!1;this.drag.startX=g-this.drag.offsetX,this.drag.startY=h-this.drag.offsetY,this.drag.start=g-this.drag.startX,this.drag.targetEl=e.target||e.srcElement,this.drag.updatedX=this.drag.start,("IMG"===this.drag.targetEl.tagName||"A"===this.drag.targetEl.tagName)&&(this.drag.targetEl.draggable=!1),a(c).on("mousemove.owl.dragEvents mouseup.owl.dragEvents touchmove.owl.dragEvents touchend.owl.dragEvents",a.proxy(function(a){this.eventsRouter(a)},this))},e.prototype.onDragMove=function(a){var c,e,g,h,i,j;this.state.isTouch&&(this.state.isScrolling||(c=a.originalEvent||a||b.event,e=f(c).x,g=f(c).y,this.drag.currentX=e-this.drag.startX,this.drag.currentY=g-this.drag.startY,this.drag.distance=this.drag.currentX-this.drag.offsetX,this.drag.distance<0?this.state.direction=this.settings.rtl?"right":"left":this.drag.distance>0&&(this.state.direction=this.settings.rtl?"left":"right"),this.settings.loop?this.op(this.drag.currentX,">",this.coordinates(this.minimum()))&&"right"===this.state.direction?this.drag.currentX-=(this.settings.center&&this.coordinates(0))-this.coordinates(this._items.length):this.op(this.drag.currentX,"<",this.coordinates(this.maximum()))&&"left"===this.state.direction&&(this.drag.currentX+=(this.settings.center&&this.coordinates(0))-this.coordinates(this._items.length)):(h=this.coordinates(this.settings.rtl?this.maximum():this.minimum()),i=this.coordinates(this.settings.rtl?this.minimum():this.maximum()),j=this.settings.pullDrag?this.drag.distance/5:0,this.drag.currentX=Math.max(Math.min(this.drag.currentX,h+j),i+j)),(this.drag.distance>8||this.drag.distance<-8)&&(c.preventDefault!==d?c.preventDefault():c.returnValue=!1,this.state.isSwiping=!0),this.drag.updatedX=this.drag.currentX,(this.drag.currentY>16||this.drag.currentY<-16)&&this.state.isSwiping===!1&&(this.state.isScrolling=!0,this.drag.updatedX=this.drag.start),this.animate(this.drag.updatedX)))},e.prototype.onDragEnd=function(b){var d,e,f;if(this.state.isTouch){if("mouseup"===b.type&&this.$stage.removeClass("owl-grab"),this.trigger("dragged"),this.drag.targetEl.removeAttribute("draggable"),this.state.isTouch=!1,this.state.isScrolling=!1,this.state.isSwiping=!1,0===this.drag.distance&&this.state.inMotion!==!0)return this.state.inMotion=!1,!1;this.drag.endTime=(new Date).getTime(),d=this.drag.endTime-this.drag.startTime,e=Math.abs(this.drag.distance),(e>3||d>300)&&this.removeClick(this.drag.targetEl),f=this.closest(this.drag.updatedX),this.speed(this.settings.dragEndSpeed||this.settings.smartSpeed),this.current(f),this.invalidate("position"),this.update(),this.settings.pullDrag||this.drag.updatedX!==this.coordinates(f)||this.transitionEnd(),this.drag.distance=0,a(c).off(".owl.dragEvents")}},e.prototype.removeClick=function(c){this.drag.targetEl=c,a(c).on("click.preventClick",this.e._preventClick),b.setTimeout(function(){a(c).off("click.preventClick")},300)},e.prototype.preventClick=function(b){b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopPropagation&&b.stopPropagation(),a(b.target).off("click.preventClick")},e.prototype.getTransformProperty=function(){var a,c;return a=b.getComputedStyle(this.$stage.get(0),null).getPropertyValue(this.vendorName+"transform"),a=a.replace(/matrix(3d)?\(|\)/g,"").split(","),c=16===a.length,c!==!0?a[4]:a[12]},e.prototype.closest=function(b){var c=-1,d=30,e=this.width(),f=this.coordinates();return this.settings.freeDrag||a.each(f,a.proxy(function(a,g){return b>g-d&&g+d>b?c=a:this.op(b,"<",g)&&this.op(b,">",f[a+1]||g-e)&&(c="left"===this.state.direction?a+1:a),-1===c},this)),this.settings.loop||(this.op(b,">",f[this.minimum()])?c=b=this.minimum():this.op(b,"<",f[this.maximum()])&&(c=b=this.maximum())),c},e.prototype.animate=function(b){this.trigger("translate"),this.state.inMotion=this.speed()>0,this.support3d?this.$stage.css({transform:"translate3d("+b+"px,0px, 0px)",transition:this.speed()/1e3+"s"}):this.state.isTouch?this.$stage.css({left:b+"px"}):this.$stage.animate({left:b},this.speed()/1e3,this.settings.fallbackEasing,a.proxy(function(){this.state.inMotion&&this.transitionEnd()},this))},e.prototype.current=function(a){if(a===d)return this._current;if(0===this._items.length)return d;if(a=this.normalize(a),this._current!==a){var b=this.trigger("change",{property:{name:"position",value:a}});b.data!==d&&(a=this.normalize(b.data)),this._current=a,this.invalidate("position"),this.trigger("changed",{property:{name:"position",value:this._current}})}return this._current},e.prototype.invalidate=function(a){this._invalidated[a]=!0},e.prototype.reset=function(a){a=this.normalize(a),a!==d&&(this._speed=0,this._current=a,this.suppress(["translate","translated"]),this.animate(this.coordinates(a)),this.release(["translate","translated"]))},e.prototype.normalize=function(b,c){var e=c?this._items.length:this._items.length+this._clones.length;return!a.isNumeric(b)||1>e?d:b=this._clones.length?(b%e+e)%e:Math.max(this.minimum(c),Math.min(this.maximum(c),b))},e.prototype.relative=function(a){return a=this.normalize(a),a-=this._clones.length/2,this.normalize(a,!0)},e.prototype.maximum=function(a){var b,c,d,e=0,f=this.settings;if(a)return this._items.length-1;if(!f.loop&&f.center)b=this._items.length-1;else if(f.loop||f.center)if(f.loop||f.center)b=this._items.length+f.items;else{if(!f.autoWidth&&!f.merge)throw"Can not detect maximum absolute position.";for(revert=f.rtl?1:-1,c=this.$stage.width()-this.$element.width();(d=this.coordinates(e))&&!(d*revert>=c);)b=++e}else b=this._items.length-f.items;return b},e.prototype.minimum=function(a){return a?0:this._clones.length/2},e.prototype.items=function(a){return a===d?this._items.slice():(a=this.normalize(a,!0),this._items[a])},e.prototype.mergers=function(a){return a===d?this._mergers.slice():(a=this.normalize(a,!0),this._mergers[a])},e.prototype.clones=function(b){var c=this._clones.length/2,e=c+this._items.length,f=function(a){return a%2===0?e+a/2:c-(a+1)/2};return b===d?a.map(this._clones,function(a,b){return f(b)}):a.map(this._clones,function(a,c){return a===b?f(c):null})},e.prototype.speed=function(a){return a!==d&&(this._speed=a),this._speed},e.prototype.coordinates=function(b){var c=null;return b===d?a.map(this._coordinates,a.proxy(function(a,b){return this.coordinates(b)},this)):(this.settings.center?(c=this._coordinates[b],c+=(this.width()-c+(this._coordinates[b-1]||0))/2*(this.settings.rtl?-1:1)):c=this._coordinates[b-1]||0,c)},e.prototype.duration=function(a,b,c){return Math.min(Math.max(Math.abs(b-a),1),6)*Math.abs(c||this.settings.smartSpeed)},e.prototype.to=function(c,d){if(this.settings.loop){var e=c-this.relative(this.current()),f=this.current(),g=this.current(),h=this.current()+e,i=0>g-h?!0:!1,j=this._clones.length+this._items.length;h<this.settings.items&&i===!1?(f=g+this._items.length,this.reset(f)):h>=j-this.settings.items&&i===!0&&(f=g-this._items.length,this.reset(f)),b.clearTimeout(this.e._goToLoop),this.e._goToLoop=b.setTimeout(a.proxy(function(){this.speed(this.duration(this.current(),f+e,d)),this.current(f+e),this.update()},this),30)}else this.speed(this.duration(this.current(),c,d)),this.current(c),this.update()},e.prototype.next=function(a){a=a||!1,this.to(this.relative(this.current())+1,a)},e.prototype.prev=function(a){a=a||!1,this.to(this.relative(this.current())-1,a)},e.prototype.transitionEnd=function(a){return a!==d&&(a.stopPropagation(),(a.target||a.srcElement||a.originalTarget)!==this.$stage.get(0))?!1:(this.state.inMotion=!1,void this.trigger("translated"))},e.prototype.viewport=function(){var d;if(this.options.responsiveBaseElement!==b)d=a(this.options.responsiveBaseElement).width();else if(b.innerWidth)d=b.innerWidth;else{if(!c.documentElement||!c.documentElement.clientWidth)throw"Can not detect viewport width.";d=c.documentElement.clientWidth}return d},e.prototype.replace=function(b){this.$stage.empty(),this._items=[],b&&(b=b instanceof jQuery?b:a(b)),this.settings.nestedItemSelector&&(b=b.find("."+this.settings.nestedItemSelector)),b.filter(function(){return 1===this.nodeType}).each(a.proxy(function(a,b){b=this.prepare(b),this.$stage.append(b),this._items.push(b),this._mergers.push(1*b.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)},this)),this.reset(a.isNumeric(this.settings.startPosition)?this.settings.startPosition:0),this.invalidate("items")},e.prototype.add=function(a,b){b=b===d?this._items.length:this.normalize(b,!0),this.trigger("add",{content:a,position:b}),0===this._items.length||b===this._items.length?(this.$stage.append(a),this._items.push(a),this._mergers.push(1*a.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)):(this._items[b].before(a),this._items.splice(b,0,a),this._mergers.splice(b,0,1*a.find("[data-merge]").andSelf("[data-merge]").attr("data-merge")||1)),this.invalidate("items"),this.trigger("added",{content:a,position:b})},e.prototype.remove=function(a){a=this.normalize(a,!0),a!==d&&(this.trigger("remove",{content:this._items[a],position:a}),this._items[a].remove(),this._items.splice(a,1),this._mergers.splice(a,1),this.invalidate("items"),this.trigger("removed",{content:null,position:a}))},e.prototype.addTriggerableEvents=function(){var b=a.proxy(function(b,c){return a.proxy(function(a){a.relatedTarget!==this&&(this.suppress([c]),b.apply(this,[].slice.call(arguments,1)),this.release([c]))},this)},this);a.each({next:this.next,prev:this.prev,to:this.to,destroy:this.destroy,refresh:this.refresh,replace:this.replace,add:this.add,remove:this.remove},a.proxy(function(a,c){this.$element.on(a+".owl.carousel",b(c,a+".owl.carousel"))},this))},e.prototype.watchVisibility=function(){function c(a){return a.offsetWidth>0&&a.offsetHeight>0}function d(){c(this.$element.get(0))&&(this.$element.removeClass("owl-hidden"),this.refresh(),b.clearInterval(this.e._checkVisibile))}c(this.$element.get(0))||(this.$element.addClass("owl-hidden"),b.clearInterval(this.e._checkVisibile),this.e._checkVisibile=b.setInterval(a.proxy(d,this),500))},e.prototype.preloadAutoWidthImages=function(b){var c,d,e,f;c=0,d=this,b.each(function(g,h){e=a(h),f=new Image,f.onload=function(){c++,e.attr("src",f.src),e.css("opacity",1),c>=b.length&&(d.state.imagesLoaded=!0,d.initialize())},f.src=e.attr("src")||e.attr("data-src")||e.attr("data-src-retina")})},e.prototype.destroy=function(){this.$element.hasClass(this.settings.themeClass)&&this.$element.removeClass(this.settings.themeClass),this.settings.responsive!==!1&&a(b).off("resize.owl.carousel"),this.transitionEndVendor&&this.off(this.$stage.get(0),this.transitionEndVendor,this.e._transitionEnd);for(var d in this._plugins)this._plugins[d].destroy();(this.settings.mouseDrag||this.settings.touchDrag)&&(this.$stage.off("mousedown touchstart touchcancel"),a(c).off(".owl.dragEvents"),this.$stage.get(0).onselectstart=function(){},this.$stage.off("dragstart",function(){return!1})),this.$element.off(".owl"),this.$stage.children(".cloned").remove(),this.e=null,this.$element.removeData("owlCarousel"),this.$stage.children().contents().unwrap(),this.$stage.children().unwrap(),this.$stage.unwrap()},e.prototype.op=function(a,b,c){var d=this.settings.rtl;switch(b){case"<":return d?a>c:c>a;case">":return d?c>a:a>c;case">=":return d?c>=a:a>=c;case"<=":return d?a>=c:c>=a}},e.prototype.on=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d):a.attachEvent&&a.attachEvent("on"+b,c)},e.prototype.off=function(a,b,c,d){a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent&&a.detachEvent("on"+b,c)},e.prototype.trigger=function(b,c,d){var e={item:{count:this._items.length,index:this.current()}},f=a.camelCase(a.grep(["on",b,d],function(a){return a}).join("-").toLowerCase()),g=a.Event([b,"owl",d||"carousel"].join(".").toLowerCase(),a.extend({relatedTarget:this},e,c));return this._supress[b]||(a.each(this._plugins,function(a,b){b.onTrigger&&b.onTrigger(g)}),this.$element.trigger(g),this.settings&&"function"==typeof this.settings[f]&&this.settings[f].apply(this,g)),g},e.prototype.suppress=function(b){a.each(b,a.proxy(function(a,b){this._supress[b]=!0},this))},e.prototype.release=function(b){a.each(b,a.proxy(function(a,b){delete this._supress[b]},this))},e.prototype.browserSupport=function(){if(this.support3d=j(),this.support3d){this.transformVendor=i();var a=["transitionend","webkitTransitionEnd","transitionend","oTransitionEnd"];this.transitionEndVendor=a[h()],this.vendorName=this.transformVendor.replace(/Transform/i,""),this.vendorName=""!==this.vendorName?"-"+this.vendorName.toLowerCase()+"-":""}this.state.orientation=b.orientation},a.fn.owlCarousel=function(b){return this.each(function(){a(this).data("owlCarousel")||a(this).data("owlCarousel",new e(this,b))})},a.fn.owlCarousel.Constructor=e}(window.Zepto||window.jQuery,window,document),function(a,b){var c=function(b){this._core=b,this._loaded=[],this._handlers={"initialized.owl.carousel change.owl.carousel":a.proxy(function(b){if(b.namespace&&this._core.settings&&this._core.settings.lazyLoad&&(b.property&&"position"==b.property.name||"initialized"==b.type))for(var c=this._core.settings,d=c.center&&Math.ceil(c.items/2)||c.items,e=c.center&&-1*d||0,f=(b.property&&b.property.value||this._core.current())+e,g=this._core.clones().length,h=a.proxy(function(a,b){this.load(b)},this);e++<d;)this.load(g/2+this._core.relative(f)),g&&a.each(this._core.clones(this._core.relative(f++)),h)},this)},this._core.options=a.extend({},c.Defaults,this._core.options),this._core.$element.on(this._handlers)};c.Defaults={lazyLoad:!1},c.prototype.load=function(c){var d=this._core.$stage.children().eq(c),e=d&&d.find(".owl-lazy");!e||a.inArray(d.get(0),this._loaded)>-1||(e.each(a.proxy(function(c,d){var e,f=a(d),g=b.devicePixelRatio>1&&f.attr("data-src-retina")||f.attr("data-src");this._core.trigger("load",{element:f,url:g},"lazy"),f.is("img")?f.one("load.owl.lazy",a.proxy(function(){f.css("opacity",1),this._core.trigger("loaded",{element:f,url:g},"lazy")},this)).attr("src",g):(e=new Image,e.onload=a.proxy(function(){f.css({"background-image":"url("+g+")",opacity:"1"}),this._core.trigger("loaded",{element:f,url:g},"lazy")},this),e.src=g)},this)),this._loaded.push(d.get(0)))},c.prototype.destroy=function(){var a,b;for(a in this.handlers)this._core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Lazy=c}(window.Zepto||window.jQuery,window,document),function(a){var b=function(c){this._core=c,this._handlers={"initialized.owl.carousel":a.proxy(function(){this._core.settings.autoHeight&&this.update()},this),"changed.owl.carousel":a.proxy(function(a){this._core.settings.autoHeight&&"position"==a.property.name&&this.update()},this),"loaded.owl.lazy":a.proxy(function(a){this._core.settings.autoHeight&&a.element.closest("."+this._core.settings.itemClass)===this._core.$stage.children().eq(this._core.current())&&this.update()},this)},this._core.options=a.extend({},b.Defaults,this._core.options),this._core.$element.on(this._handlers)};b.Defaults={autoHeight:!1,autoHeightClass:"owl-height"},b.prototype.update=function(){this._core.$stage.parent().height(this._core.$stage.children().eq(this._core.current()).height()).addClass(this._core.settings.autoHeightClass)},b.prototype.destroy=function(){var a,b;for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoHeight=b}(window.Zepto||window.jQuery,window,document),function(a,b,c){var d=function(b){this._core=b,this._videos={},this._playing=null,this._fullscreen=!1,this._handlers={"resize.owl.carousel":a.proxy(function(a){this._core.settings.video&&!this.isInFullScreen()&&a.preventDefault()},this),"refresh.owl.carousel changed.owl.carousel":a.proxy(function(){this._playing&&this.stop()},this),"prepared.owl.carousel":a.proxy(function(b){var c=a(b.content).find(".owl-video");c.length&&(c.css("display","none"),this.fetch(c,a(b.content)))},this)},this._core.options=a.extend({},d.Defaults,this._core.options),this._core.$element.on(this._handlers),this._core.$element.on("click.owl.video",".owl-video-play-icon",a.proxy(function(a){this.play(a)},this))};d.Defaults={video:!1,videoHeight:!1,videoWidth:!1},d.prototype.fetch=function(a,b){var c=a.attr("data-vimeo-id")?"vimeo":"youtube",d=a.attr("data-vimeo-id")||a.attr("data-youtube-id"),e=a.attr("data-width")||this._core.settings.videoWidth,f=a.attr("data-height")||this._core.settings.videoHeight,g=a.attr("href");if(!g)throw new Error("Missing video URL.");if(d=g.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/),d[3].indexOf("youtu")>-1)c="youtube";else{if(!(d[3].indexOf("vimeo")>-1))throw new Error("Video URL not supported.");c="vimeo"}d=d[6],this._videos[g]={type:c,id:d,width:e,height:f},b.attr("data-video",g),this.thumbnail(a,this._videos[g])},d.prototype.thumbnail=function(b,c){var d,e,f,g=c.width&&c.height?'style="width:'+c.width+"px;height:"+c.height+'px;"':"",h=b.find("img"),i="src",j="",k=this._core.settings,l=function(a){e='<div class="owl-video-play-icon"></div>',d=k.lazyLoad?'<div class="owl-video-tn '+j+'" '+i+'="'+a+'"></div>':'<div class="owl-video-tn" style="opacity:1;background-image:url('+a+')"></div>',b.after(d),b.after(e)};return b.wrap('<div class="owl-video-wrapper"'+g+"></div>"),this._core.settings.lazyLoad&&(i="data-src",j="owl-lazy"),h.length?(l(h.attr(i)),h.remove(),!1):void("youtube"===c.type?(f="http://img.youtube.com/vi/"+c.id+"/hqdefault.jpg",l(f)):"vimeo"===c.type&&a.ajax({type:"GET",url:"http://vimeo.com/api/v2/video/"+c.id+".json",jsonp:"callback",dataType:"jsonp",success:function(a){f=a[0].thumbnail_large,l(f)}}))},d.prototype.stop=function(){this._core.trigger("stop",null,"video"),this._playing.find(".owl-video-frame").remove(),this._playing.removeClass("owl-video-playing"),this._playing=null},d.prototype.play=function(b){this._core.trigger("play",null,"video"),this._playing&&this.stop();var c,d,e=a(b.target||b.srcElement),f=e.closest("."+this._core.settings.itemClass),g=this._videos[f.attr("data-video")],h=g.width||"100%",i=g.height||this._core.$stage.height();"youtube"===g.type?c='<iframe width="'+h+'" height="'+i+'" src="http://www.youtube.com/embed/'+g.id+"?autoplay=1&v="+g.id+'" frameborder="0" allowfullscreen></iframe>':"vimeo"===g.type&&(c='<iframe src="http://player.vimeo.com/video/'+g.id+'?autoplay=1" width="'+h+'" height="'+i+'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'),f.addClass("owl-video-playing"),this._playing=f,d=a('<div style="height:'+i+"px; width:"+h+'px" class="owl-video-frame">'+c+"</div>"),e.after(d)},d.prototype.isInFullScreen=function(){var d=c.fullscreenElement||c.mozFullScreenElement||c.webkitFullscreenElement;return d&&a(d).parent().hasClass("owl-video-frame")&&(this._core.speed(0),this._fullscreen=!0),d&&this._fullscreen&&this._playing?!1:this._fullscreen?(this._fullscreen=!1,!1):this._playing&&this._core.state.orientation!==b.orientation?(this._core.state.orientation=b.orientation,!1):!0},d.prototype.destroy=function(){var a,b;this._core.$element.off("click.owl.video");for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Video=d}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this.core=b,this.core.options=a.extend({},e.Defaults,this.core.options),this.swapping=!0,this.previous=d,this.next=d,this.handlers={"change.owl.carousel":a.proxy(function(a){"position"==a.property.name&&(this.previous=this.core.current(),this.next=a.property.value)},this),"drag.owl.carousel dragged.owl.carousel translated.owl.carousel":a.proxy(function(a){this.swapping="translated"==a.type},this),"translate.owl.carousel":a.proxy(function(){this.swapping&&(this.core.options.animateOut||this.core.options.animateIn)&&this.swap()},this)},this.core.$element.on(this.handlers)};e.Defaults={animateOut:!1,animateIn:!1},e.prototype.swap=function(){if(1===this.core.settings.items&&this.core.support3d){this.core.speed(0);var b,c=a.proxy(this.clear,this),d=this.core.$stage.children().eq(this.previous),e=this.core.$stage.children().eq(this.next),f=this.core.settings.animateIn,g=this.core.settings.animateOut;this.core.current()!==this.previous&&(g&&(b=this.core.coordinates(this.previous)-this.core.coordinates(this.next),d.css({left:b+"px"}).addClass("animated owl-animated-out").addClass(g).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",c)),f&&e.addClass("animated owl-animated-in").addClass(f).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",c))}},e.prototype.clear=function(b){a(b.target).css({left:""}).removeClass("animated owl-animated-out owl-animated-in").removeClass(this.core.settings.animateIn).removeClass(this.core.settings.animateOut),this.core.transitionEnd()},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))"function"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Animate=e}(window.Zepto||window.jQuery,window,document),function(a,b,c){var d=function(b){this.core=b,this.core.options=a.extend({},d.Defaults,this.core.options),this.handlers={"translated.owl.carousel refreshed.owl.carousel":a.proxy(function(){this.autoplay()
+},this),"play.owl.autoplay":a.proxy(function(a,b,c){this.play(b,c)},this),"stop.owl.autoplay":a.proxy(function(){this.stop()},this),"mouseover.owl.autoplay":a.proxy(function(){this.core.settings.autoplayHoverPause&&this.pause()},this),"mouseleave.owl.autoplay":a.proxy(function(){this.core.settings.autoplayHoverPause&&this.autoplay()},this)},this.core.$element.on(this.handlers)};d.Defaults={autoplay:!1,autoplayTimeout:5e3,autoplayHoverPause:!1,autoplaySpeed:!1},d.prototype.autoplay=function(){this.core.settings.autoplay&&!this.core.state.videoPlay?(b.clearInterval(this.interval),this.interval=b.setInterval(a.proxy(function(){this.play()},this),this.core.settings.autoplayTimeout)):b.clearInterval(this.interval)},d.prototype.play=function(){return c.hidden===!0||this.core.state.isTouch||this.core.state.isScrolling||this.core.state.isSwiping||this.core.state.inMotion?void 0:this.core.settings.autoplay===!1?void b.clearInterval(this.interval):void this.core.next(this.core.settings.autoplaySpeed)},d.prototype.stop=function(){b.clearInterval(this.interval)},d.prototype.pause=function(){b.clearInterval(this.interval)},d.prototype.destroy=function(){var a,c;b.clearInterval(this.interval);for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(c in Object.getOwnPropertyNames(this))"function"!=typeof this[c]&&(this[c]=null)},a.fn.owlCarousel.Constructor.Plugins.autoplay=d}(window.Zepto||window.jQuery,window,document),function(a){"use strict";var b=function(c){this._core=c,this._initialized=!1,this._pages=[],this._controls={},this._templates=[],this.$element=this._core.$element,this._overrides={next:this._core.next,prev:this._core.prev,to:this._core.to},this._handlers={"prepared.owl.carousel":a.proxy(function(b){this._core.settings.dotsData&&this._templates.push(a(b.content).find("[data-dot]").andSelf("[data-dot]").attr("data-dot"))},this),"add.owl.carousel":a.proxy(function(b){this._core.settings.dotsData&&this._templates.splice(b.position,0,a(b.content).find("[data-dot]").andSelf("[data-dot]").attr("data-dot"))},this),"remove.owl.carousel prepared.owl.carousel":a.proxy(function(a){this._core.settings.dotsData&&this._templates.splice(a.position,1)},this),"change.owl.carousel":a.proxy(function(a){if("position"==a.property.name&&!this._core.state.revert&&!this._core.settings.loop&&this._core.settings.navRewind){var b=this._core.current(),c=this._core.maximum(),d=this._core.minimum();a.data=a.property.value>c?b>=c?d:c:a.property.value<d?c:a.property.value}},this),"changed.owl.carousel":a.proxy(function(a){"position"==a.property.name&&this.draw()},this),"refreshed.owl.carousel":a.proxy(function(){this._initialized||(this.initialize(),this._initialized=!0),this._core.trigger("refresh",null,"navigation"),this.update(),this.draw(),this._core.trigger("refreshed",null,"navigation")},this)},this._core.options=a.extend({},b.Defaults,this._core.options),this.$element.on(this._handlers)};b.Defaults={nav:!1,navRewind:!0,navText:["prev","next"],navSpeed:!1,navElement:"div",navContainer:!1,navContainerClass:"owl-nav",navClass:["owl-prev","owl-next"],slideBy:1,dotClass:"owl-dot",dotsClass:"owl-dots",dots:!0,dotsEach:!1,dotData:!1,dotsSpeed:!1,dotsContainer:!1,controlsClass:"owl-controls"},b.prototype.initialize=function(){var b,c,d=this._core.settings;d.dotsData||(this._templates=[a("<div>").addClass(d.dotClass).append(a("<span>")).prop("outerHTML")]),d.navContainer&&d.dotsContainer||(this._controls.$container=a("<div>").addClass(d.controlsClass).appendTo(this.$element)),this._controls.$indicators=d.dotsContainer?a(d.dotsContainer):a("<div>").hide().addClass(d.dotsClass).appendTo(this._controls.$container),this._controls.$indicators.on("click","div",a.proxy(function(b){var c=a(b.target).parent().is(this._controls.$indicators)?a(b.target).index():a(b.target).parent().index();b.preventDefault(),this.to(c,d.dotsSpeed)},this)),b=d.navContainer?a(d.navContainer):a("<div>").addClass(d.navContainerClass).prependTo(this._controls.$container),this._controls.$next=a("<"+d.navElement+">"),this._controls.$previous=this._controls.$next.clone(),this._controls.$previous.addClass(d.navClass[0]).html(d.navText[0]).hide().prependTo(b).on("click",a.proxy(function(){this.prev(d.navSpeed)},this)),this._controls.$next.addClass(d.navClass[1]).html(d.navText[1]).hide().appendTo(b).on("click",a.proxy(function(){this.next(d.navSpeed)},this));for(c in this._overrides)this._core[c]=a.proxy(this[c],this)},b.prototype.destroy=function(){var a,b,c,d;for(a in this._handlers)this.$element.off(a,this._handlers[a]);for(b in this._controls)this._controls[b].remove();for(d in this.overides)this._core[d]=this._overrides[d];for(c in Object.getOwnPropertyNames(this))"function"!=typeof this[c]&&(this[c]=null)},b.prototype.update=function(){var a,b,c,d=this._core.settings,e=this._core.clones().length/2,f=e+this._core.items().length,g=d.center||d.autoWidth||d.dotData?1:d.dotsEach||d.items;if("page"!==d.slideBy&&(d.slideBy=Math.min(d.slideBy,d.items)),d.dots||"page"==d.slideBy)for(this._pages=[],a=e,b=0,c=0;f>a;a++)(b>=g||0===b)&&(this._pages.push({start:a-e,end:a-e+g-1}),b=0,++c),b+=this._core.mergers(this._core.relative(a))},b.prototype.draw=function(){var b,c,d="",e=this._core.settings,f=(this._core.$stage.children(),this._core.relative(this._core.current()));if(!e.nav||e.loop||e.navRewind||(this._controls.$previous.toggleClass("disabled",0>=f),this._controls.$next.toggleClass("disabled",f>=this._core.maximum())),this._controls.$previous.toggle(e.nav),this._controls.$next.toggle(e.nav),e.dots){if(b=this._pages.length-this._controls.$indicators.children().length,e.dotData&&0!==b){for(c=0;c<this._controls.$indicators.children().length;c++)d+=this._templates[this._core.relative(c)];this._controls.$indicators.html(d)}else b>0?(d=new Array(b+1).join(this._templates[0]),this._controls.$indicators.append(d)):0>b&&this._controls.$indicators.children().slice(b).remove();this._controls.$indicators.find(".active").removeClass("active"),this._controls.$indicators.children().eq(a.inArray(this.current(),this._pages)).addClass("active")}this._controls.$indicators.toggle(e.dots)},b.prototype.onTrigger=function(b){var c=this._core.settings;b.page={index:a.inArray(this.current(),this._pages),count:this._pages.length,size:c&&(c.center||c.autoWidth||c.dotData?1:c.dotsEach||c.items)}},b.prototype.current=function(){var b=this._core.relative(this._core.current());return a.grep(this._pages,function(a){return a.start<=b&&a.end>=b}).pop()},b.prototype.getPosition=function(b){var c,d,e=this._core.settings;return"page"==e.slideBy?(c=a.inArray(this.current(),this._pages),d=this._pages.length,b?++c:--c,c=this._pages[(c%d+d)%d].start):(c=this._core.relative(this._core.current()),d=this._core.items().length,b?c+=e.slideBy:c-=e.slideBy),c},b.prototype.next=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!0),b)},b.prototype.prev=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!1),b)},b.prototype.to=function(b,c,d){var e;d?a.proxy(this._overrides.to,this._core)(b,c):(e=this._pages.length,a.proxy(this._overrides.to,this._core)(this._pages[(b%e+e)%e].start,c))},a.fn.owlCarousel.Constructor.Plugins.Navigation=b}(window.Zepto||window.jQuery,window,document),function(a,b){"use strict";var c=function(d){this._core=d,this._hashes={},this.$element=this._core.$element,this._handlers={"initialized.owl.carousel":a.proxy(function(){"URLHash"==this._core.settings.startPosition&&a(b).trigger("hashchange.owl.navigation")},this),"prepared.owl.carousel":a.proxy(function(b){var c=a(b.content).find("[data-hash]").andSelf("[data-hash]").attr("data-hash");this._hashes[c]=b.content},this)},this._core.options=a.extend({},c.Defaults,this._core.options),this.$element.on(this._handlers),a(b).on("hashchange.owl.navigation",a.proxy(function(){var a=b.location.hash.substring(1),c=this._core.$stage.children(),d=this._hashes[a]&&c.index(this._hashes[a])||0;return a?void this._core.to(d,!1,!0):!1},this))};c.Defaults={URLhashListener:!1},c.prototype.destroy=function(){var c,d;a(b).off("hashchange.owl.navigation");for(c in this._handlers)this._core.$element.off(c,this._handlers[c]);for(d in Object.getOwnPropertyNames(this))"function"!=typeof this[d]&&(this[d]=null)},a.fn.owlCarousel.Constructor.Plugins.Hash=c}(window.Zepto||window.jQuery,window,document);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/excanvas.min.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/excanvas.min.js
new file mode 100644 (file)
index 0000000..12c74f7
--- /dev/null
@@ -0,0 +1 @@
+if(!document.createElement("canvas").getContext){(function(){var z=Math;var K=z.round;var J=z.sin;var U=z.cos;var b=z.abs;var k=z.sqrt;var D=10;var F=D/2;function T(){return this.context_||(this.context_=new W(this))}var O=Array.prototype.slice;function G(i,j,m){var Z=O.call(arguments,2);return function(){return i.apply(j,Z.concat(O.call(arguments)))}}function AD(Z){return String(Z).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function r(i){if(!i.namespaces.g_vml_){i.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!i.namespaces.g_o_){i.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!i.styleSheets.ex_canvas_){var Z=i.createStyleSheet();Z.owningElement.id="ex_canvas_";Z.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}r(document);var E={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=Z||document;i.createElement("canvas");i.attachEvent("onreadystatechange",G(this.init_,this,i))}},init_:function(m){var j=m.getElementsByTagName("canvas");for(var Z=0;Z<j.length;Z++){this.initElement(j[Z])}},initElement:function(i){if(!i.getContext){i.getContext=T;r(i.ownerDocument);i.innerHTML="";i.attachEvent("onpropertychange",S);i.attachEvent("onresize",w);var Z=i.attributes;if(Z.width&&Z.width.specified){i.style.width=Z.width.nodeValue+"px"}else{i.width=i.clientWidth}if(Z.height&&Z.height.specified){i.style.height=Z.height.nodeValue+"px"}else{i.height=i.clientHeight}}return i}};function S(i){var Z=i.srcElement;switch(i.propertyName){case"width":Z.getContext().clearRect();Z.style.width=Z.attributes.width.nodeValue+"px";Z.firstChild.style.width=Z.clientWidth+"px";break;case"height":Z.getContext().clearRect();Z.style.height=Z.attributes.height.nodeValue+"px";Z.firstChild.style.height=Z.clientHeight+"px";break}}function w(i){var Z=i.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}E.init();var I=[];for(var AC=0;AC<16;AC++){for(var AB=0;AB<16;AB++){I[AC*16+AB]=AC.toString(16)+AB.toString(16)}}function V(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(m,j){var i=V();for(var Z=0;Z<3;Z++){for(var AF=0;AF<3;AF++){var p=0;for(var AE=0;AE<3;AE++){p+=m[Z][AE]*j[AE][AF]}i[Z][AF]=p}}return i}function Q(i,Z){Z.fillStyle=i.fillStyle;Z.lineCap=i.lineCap;Z.lineJoin=i.lineJoin;Z.lineWidth=i.lineWidth;Z.miterLimit=i.miterLimit;Z.shadowBlur=i.shadowBlur;Z.shadowColor=i.shadowColor;Z.shadowOffsetX=i.shadowOffsetX;Z.shadowOffsetY=i.shadowOffsetY;Z.strokeStyle=i.strokeStyle;Z.globalAlpha=i.globalAlpha;Z.font=i.font;Z.textAlign=i.textAlign;Z.textBaseline=i.textBaseline;Z.arcScaleX_=i.arcScaleX_;Z.arcScaleY_=i.arcScaleY_;Z.lineScale_=i.lineScale_}var B={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function g(i){var m=i.indexOf("(",3);var Z=i.indexOf(")",m+1);var j=i.substring(m+1,Z).split(",");if(j.length==4&&i.substr(3,1)=="a"){alpha=Number(j[3])}else{j[3]=1}return j}function C(Z){return parseFloat(Z)/100}function N(i,j,Z){return Math.min(Z,Math.max(j,i))}function c(AF){var j,i,Z;h=parseFloat(AF[0])/360%360;if(h<0){h++}s=N(C(AF[1]),0,1);l=N(C(AF[2]),0,1);if(s==0){j=i=Z=l}else{var m=l<0.5?l*(1+s):l+s-l*s;var AE=2*l-m;j=A(AE,m,h+1/3);i=A(AE,m,h);Z=A(AE,m,h-1/3)}return"#"+I[Math.floor(j*255)]+I[Math.floor(i*255)]+I[Math.floor(Z*255)]}function A(i,Z,j){if(j<0){j++}if(j>1){j--}if(6*j<1){return i+(Z-i)*6*j}else{if(2*j<1){return Z}else{if(3*j<2){return i+(Z-i)*(2/3-j)*6}else{return i}}}}function Y(Z){var AE,p=1;Z=String(Z);if(Z.charAt(0)=="#"){AE=Z}else{if(/^rgb/.test(Z)){var m=g(Z);var AE="#",AF;for(var j=0;j<3;j++){if(m[j].indexOf("%")!=-1){AF=Math.floor(C(m[j])*255)}else{AF=Number(m[j])}AE+=I[N(AF,0,255)]}p=m[3]}else{if(/^hsl/.test(Z)){var m=g(Z);AE=c(m);p=m[3]}else{AE=B[Z]||Z}}}return{color:AE,alpha:p}}var L={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var f={};function X(Z){if(f[Z]){return f[Z]}var m=document.createElement("div");var j=m.style;try{j.font=Z}catch(i){}return f[Z]={style:j.fontStyle||L.style,variant:j.fontVariant||L.variant,weight:j.fontWeight||L.weight,size:j.fontSize||L.size,family:j.fontFamily||L.family}}function P(j,i){var Z={};for(var AF in j){Z[AF]=j[AF]}var AE=parseFloat(i.currentStyle.fontSize),m=parseFloat(j.size);if(typeof j.size=="number"){Z.size=j.size}else{if(j.size.indexOf("px")!=-1){Z.size=m}else{if(j.size.indexOf("em")!=-1){Z.size=AE*m}else{if(j.size.indexOf("%")!=-1){Z.size=(AE/100)*m}else{if(j.size.indexOf("pt")!=-1){Z.size=m/0.75}else{Z.size=AE}}}}}Z.size*=0.981;return Z}function AA(Z){return Z.style+" "+Z.variant+" "+Z.weight+" "+Z.size+"px "+Z.family}function t(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function W(i){this.m_=V();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=D*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var Z=i.ownerDocument.createElement("div");Z.style.width=i.clientWidth+"px";Z.style.height=i.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";i.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var M=W.prototype;M.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};M.beginPath=function(){this.currentPath_=[]};M.moveTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"moveTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.lineTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"lineTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.bezierCurveTo=function(j,i,AI,AH,AG,AE){var Z=this.getCoords_(AG,AE);var AF=this.getCoords_(j,i);var m=this.getCoords_(AI,AH);e(this,AF,m,Z)};function e(Z,m,j,i){Z.currentPath_.push({type:"bezierCurveTo",cp1x:m.x,cp1y:m.y,cp2x:j.x,cp2y:j.y,x:i.x,y:i.y});Z.currentX_=i.x;Z.currentY_=i.y}M.quadraticCurveTo=function(AG,j,i,Z){var AF=this.getCoords_(AG,j);var AE=this.getCoords_(i,Z);var AH={x:this.currentX_+2/3*(AF.x-this.currentX_),y:this.currentY_+2/3*(AF.y-this.currentY_)};var m={x:AH.x+(AE.x-this.currentX_)/3,y:AH.y+(AE.y-this.currentY_)/3};e(this,AH,m,AE)};M.arc=function(AJ,AH,AI,AE,i,j){AI*=D;var AN=j?"at":"wa";var AK=AJ+U(AE)*AI-F;var AM=AH+J(AE)*AI-F;var Z=AJ+U(i)*AI-F;var AL=AH+J(i)*AI-F;if(AK==Z&&!j){AK+=0.125}var m=this.getCoords_(AJ,AH);var AG=this.getCoords_(AK,AM);var AF=this.getCoords_(Z,AL);this.currentPath_.push({type:AN,x:m.x,y:m.y,radius:AI,xStart:AG.x,yStart:AG.y,xEnd:AF.x,yEnd:AF.y})};M.rect=function(j,i,Z,m){this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath()};M.strokeRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.stroke();this.currentPath_=p};M.fillRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.fill();this.currentPath_=p};M.createLinearGradient=function(i,m,Z,j){var p=new v("gradient");p.x0_=i;p.y0_=m;p.x1_=Z;p.y1_=j;return p};M.createRadialGradient=function(m,AE,j,i,p,Z){var AF=new v("gradientradial");AF.x0_=m;AF.y0_=AE;AF.r0_=j;AF.x1_=i;AF.y1_=p;AF.r1_=Z;return AF};M.drawImage=function(AO,j){var AH,AF,AJ,AV,AM,AK,AQ,AX;var AI=AO.runtimeStyle.width;var AN=AO.runtimeStyle.height;AO.runtimeStyle.width="auto";AO.runtimeStyle.height="auto";var AG=AO.width;var AT=AO.height;AO.runtimeStyle.width=AI;AO.runtimeStyle.height=AN;if(arguments.length==3){AH=arguments[1];AF=arguments[2];AM=AK=0;AQ=AJ=AG;AX=AV=AT}else{if(arguments.length==5){AH=arguments[1];AF=arguments[2];AJ=arguments[3];AV=arguments[4];AM=AK=0;AQ=AG;AX=AT}else{if(arguments.length==9){AM=arguments[1];AK=arguments[2];AQ=arguments[3];AX=arguments[4];AH=arguments[5];AF=arguments[6];AJ=arguments[7];AV=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AW=this.getCoords_(AH,AF);var m=AQ/2;var i=AX/2;var AU=[];var Z=10;var AE=10;AU.push(" <g_vml_:group",' coordsize="',D*Z,",",D*AE,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",AE,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var p=[];p.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",K(AW.x/D),",","Dy=",K(AW.y/D),"");var AS=AW;var AR=this.getCoords_(AH+AJ,AF);var AP=this.getCoords_(AH,AF+AV);var AL=this.getCoords_(AH+AJ,AF+AV);AS.x=z.max(AS.x,AR.x,AP.x,AL.x);AS.y=z.max(AS.y,AR.y,AP.y,AL.y);AU.push("padding:0 ",K(AS.x/D),"px ",K(AS.y/D),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",p.join(""),", sizingmethod='clip');")}else{AU.push("top:",K(AW.y/D),"px;left:",K(AW.x/D),"px;")}AU.push(' ">','<g_vml_:image src="',AO.src,'"',' style="width:',D*AJ,"px;"," height:",D*AV,'px"',' cropleft="',AM/AG,'"',' croptop="',AK/AT,'"',' cropright="',(AG-AM-AQ)/AG,'"',' cropbottom="',(AT-AK-AX)/AT,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AU.join(""))};M.stroke=function(AM){var m=10;var AN=10;var AE=5000;var AG={x:null,y:null};var AL={x:null,y:null};for(var AH=0;AH<this.currentPath_.length;AH+=AE){var AK=[];var AF=false;AK.push("<g_vml_:shape",' filled="',!!AM,'"',' style="position:absolute;width:',m,"px;height:",AN,'px;"',' coordorigin="0,0"',' coordsize="',D*m,",",D*AN,'"',' stroked="',!AM,'"',' path="');var AO=false;for(var AI=AH;AI<Math.min(AH+AE,this.currentPath_.length);AI++){if(AI%AE==0&&AI>0){AK.push(" m ",K(this.currentPath_[AI-1].x),",",K(this.currentPath_[AI-1].y))}var Z=this.currentPath_[AI];var AJ;switch(Z.type){case"moveTo":AJ=Z;AK.push(" m ",K(Z.x),",",K(Z.y));break;case"lineTo":AK.push(" l ",K(Z.x),",",K(Z.y));break;case"close":AK.push(" x ");Z=null;break;case"bezierCurveTo":AK.push(" c ",K(Z.cp1x),",",K(Z.cp1y),",",K(Z.cp2x),",",K(Z.cp2y),",",K(Z.x),",",K(Z.y));break;case"at":case"wa":AK.push(" ",Z.type," ",K(Z.x-this.arcScaleX_*Z.radius),",",K(Z.y-this.arcScaleY_*Z.radius)," ",K(Z.x+this.arcScaleX_*Z.radius),",",K(Z.y+this.arcScaleY_*Z.radius)," ",K(Z.xStart),",",K(Z.yStart)," ",K(Z.xEnd),",",K(Z.yEnd));break}if(Z){if(AG.x==null||Z.x<AG.x){AG.x=Z.x}if(AL.x==null||Z.x>AL.x){AL.x=Z.x}if(AG.y==null||Z.y<AG.y){AG.y=Z.y}if(AL.y==null||Z.y>AL.y){AL.y=Z.y}}}AK.push(' ">');if(!AM){R(this,AK)}else{a(this,AK,AG,AL)}AK.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",AK.join(""))}};function R(j,AE){var i=Y(j.strokeStyle);var m=i.color;var p=i.alpha*j.globalAlpha;var Z=j.lineScale_*j.lineWidth;if(Z<1){p*=Z}AE.push("<g_vml_:stroke",' opacity="',p,'"',' joinstyle="',j.lineJoin,'"',' miterlimit="',j.miterLimit,'"',' endcap="',t(j.lineCap),'"',' weight="',Z,'px"',' color="',m,'" />')}function a(AO,AG,Ah,AP){var AH=AO.fillStyle;var AY=AO.arcScaleX_;var AX=AO.arcScaleY_;var Z=AP.x-Ah.x;var m=AP.y-Ah.y;if(AH instanceof v){var AL=0;var Ac={x:0,y:0};var AU=0;var AK=1;if(AH.type_=="gradient"){var AJ=AH.x0_/AY;var j=AH.y0_/AX;var AI=AH.x1_/AY;var Aj=AH.y1_/AX;var Ag=AO.getCoords_(AJ,j);var Af=AO.getCoords_(AI,Aj);var AE=Af.x-Ag.x;var p=Af.y-Ag.y;AL=Math.atan2(AE,p)*180/Math.PI;if(AL<0){AL+=360}if(AL<0.000001){AL=0}}else{var Ag=AO.getCoords_(AH.x0_,AH.y0_);Ac={x:(Ag.x-Ah.x)/Z,y:(Ag.y-Ah.y)/m};Z/=AY*D;m/=AX*D;var Aa=z.max(Z,m);AU=2*AH.r0_/Aa;AK=2*AH.r1_/Aa-AU}var AS=AH.colors_;AS.sort(function(Ak,i){return Ak.offset-i.offset});var AN=AS.length;var AR=AS[0].color;var AQ=AS[AN-1].color;var AW=AS[0].alpha*AO.globalAlpha;var AV=AS[AN-1].alpha*AO.globalAlpha;var Ab=[];for(var Ae=0;Ae<AN;Ae++){var AM=AS[Ae];Ab.push(AM.offset*AK+AU+" "+AM.color)}AG.push('<g_vml_:fill type="',AH.type_,'"',' method="none" focus="100%"',' color="',AR,'"',' color2="',AQ,'"',' colors="',Ab.join(","),'"',' opacity="',AV,'"',' g_o_:opacity2="',AW,'"',' angle="',AL,'"',' focusposition="',Ac.x,",",Ac.y,'" />')}else{if(AH instanceof u){if(Z&&m){var AF=-Ah.x;var AZ=-Ah.y;AG.push("<g_vml_:fill",' position="',AF/Z*AY*AY,",",AZ/m*AX*AX,'"',' type="tile"',' src="',AH.src_,'" />')}}else{var Ai=Y(AO.fillStyle);var AT=Ai.color;var Ad=Ai.alpha*AO.globalAlpha;AG.push('<g_vml_:fill color="',AT,'" opacity="',Ad,'" />')}}}M.fill=function(){this.stroke(true)};M.closePath=function(){this.currentPath_.push({type:"close"})};M.getCoords_=function(j,i){var Z=this.m_;return{x:D*(j*Z[0][0]+i*Z[1][0]+Z[2][0])-F,y:D*(j*Z[0][1]+i*Z[1][1]+Z[2][1])-F}};M.save=function(){var Z={};Q(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=d(V(),this.m_)};M.restore=function(){if(this.aStack_.length){Q(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function H(Z){return isFinite(Z[0][0])&&isFinite(Z[0][1])&&isFinite(Z[1][0])&&isFinite(Z[1][1])&&isFinite(Z[2][0])&&isFinite(Z[2][1])}function y(i,Z,j){if(!H(Z)){return }i.m_=Z;if(j){var p=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];i.lineScale_=k(b(p))}}M.translate=function(j,i){var Z=[[1,0,0],[0,1,0],[j,i,1]];y(this,d(Z,this.m_),false)};M.rotate=function(i){var m=U(i);var j=J(i);var Z=[[m,j,0],[-j,m,0],[0,0,1]];y(this,d(Z,this.m_),false)};M.scale=function(j,i){this.arcScaleX_*=j;this.arcScaleY_*=i;var Z=[[j,0,0],[0,i,0],[0,0,1]];y(this,d(Z,this.m_),true)};M.transform=function(p,m,AF,AE,i,Z){var j=[[p,m,0],[AF,AE,0],[i,Z,1]];y(this,d(j,this.m_),true)};M.setTransform=function(AE,p,AG,AF,j,i){var Z=[[AE,p,0],[AG,AF,0],[j,i,1]];y(this,Z,true)};M.drawText_=function(AK,AI,AH,AN,AG){var AM=this.m_,AQ=1000,i=0,AP=AQ,AF={x:0,y:0},AE=[];var Z=P(X(this.font),this.element_);var j=AA(Z);var AR=this.element_.currentStyle;var p=this.textAlign.toLowerCase();switch(p){case"left":case"center":case"right":break;case"end":p=AR.direction=="ltr"?"right":"left";break;case"start":p=AR.direction=="rtl"?"right":"left";break;default:p="left"}switch(this.textBaseline){case"hanging":case"top":AF.y=Z.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":AF.y=-Z.size/2.25;break}switch(p){case"right":i=AQ;AP=0.05;break;case"center":i=AP=AQ/2;break}var AO=this.getCoords_(AI+AF.x,AH+AF.y);AE.push('<g_vml_:line from="',-i,' 0" to="',AP,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!AG,'" stroked="',!!AG,'" style="position:absolute;width:1px;height:1px;">');if(AG){R(this,AE)}else{a(this,AE,{x:-i,y:0},{x:AP,y:Z.size})}var AL=AM[0][0].toFixed(3)+","+AM[1][0].toFixed(3)+","+AM[0][1].toFixed(3)+","+AM[1][1].toFixed(3)+",0,0";var AJ=K(AO.x/D)+","+K(AO.y/D);AE.push('<g_vml_:skew on="t" matrix="',AL,'" ',' offset="',AJ,'" origin="',i,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',AD(AK),'" style="v-text-align:',p,";font:",AD(j),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",AE.join(""))};M.fillText=function(j,Z,m,i){this.drawText_(j,Z,m,i,false)};M.strokeText=function(j,Z,m,i){this.drawText_(j,Z,m,i,true)};M.measureText=function(j){if(!this.textMeasureEl_){var Z='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",Z);this.textMeasureEl_=this.element_.lastChild}var i=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(i.createTextNode(j));return{width:this.textMeasureEl_.offsetWidth}};M.clip=function(){};M.arcTo=function(){};M.createPattern=function(i,Z){return new u(i,Z)};function v(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}v.prototype.addColorStop=function(i,Z){Z=Y(Z);this.colors_.push({offset:i,color:Z.color,alpha:Z.alpha})};function u(i,Z){q(i);switch(Z){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=Z;break;default:n("SYNTAX_ERR")}this.src_=i.src;this.width_=i.width;this.height_=i.height}function n(Z){throw new o(Z)}function q(Z){if(!Z||Z.nodeType!=1||Z.tagName!="IMG"){n("TYPE_MISMATCH_ERR")}if(Z.readyState!="complete"){n("INVALID_STATE_ERR")}}function o(Z){this.code=this[Z];this.message=Z+": DOM Exception "+this.code}var x=o.prototype=new Error;x.INDEX_SIZE_ERR=1;x.DOMSTRING_SIZE_ERR=2;x.HIERARCHY_REQUEST_ERR=3;x.WRONG_DOCUMENT_ERR=4;x.INVALID_CHARACTER_ERR=5;x.NO_DATA_ALLOWED_ERR=6;x.NO_MODIFICATION_ALLOWED_ERR=7;x.NOT_FOUND_ERR=8;x.NOT_SUPPORTED_ERR=9;x.INUSE_ATTRIBUTE_ERR=10;x.INVALID_STATE_ERR=11;x.SYNTAX_ERR=12;x.INVALID_MODIFICATION_ERR=13;x.NAMESPACE_ERR=14;x.INVALID_ACCESS_ERR=15;x.VALIDATION_ERR=16;x.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=E;CanvasRenderingContext2D=W;CanvasGradient=v;CanvasPattern=u;DOMException=o})()};
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/flot-data.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/flot-data.js
new file mode 100644 (file)
index 0000000..3e92eb8
--- /dev/null
@@ -0,0 +1,1242 @@
+//Flot Line Chart
+$(document).ready(function() {
+    console.log("document ready");
+    var offset = 0;
+    plot();
+
+    function plot() {
+        var sin = [],
+            cos = [];
+        for (var i = 0; i < 12; i += 0.2) {
+            sin.push([i, Math.sin(i + offset)]);
+            cos.push([i, Math.cos(i + offset)]);
+        }
+
+        var options = {
+            series: {
+                lines: {
+                    show: true
+                },
+                points: {
+                    show: true
+                }
+            },
+            grid: {
+                hoverable: true //IMPORTANT! this is needed for tooltip to work
+            },
+            yaxis: {
+                min: -1.2,
+                max: 1.2
+            },
+            tooltip: true,
+            tooltipOpts: {
+                content: "'%s' of %x.1 is %y.4",
+                shifts: {
+                    x: -60,
+                    y: 25
+                }
+            }
+        };
+
+        var plotObj = $.plot($("#flot-line-chart"), [{
+                data: sin,
+                label: "sin(x)"
+            }, {
+                data: cos,
+                label: "cos(x)"
+            }],
+            options);
+    }
+});
+
+//Flot Pie Chart
+$(function() {
+
+    var data = [{
+        label: "Series 0",
+        data: 1
+    }, {
+        label: "Series 1",
+        data: 3
+    }, {
+        label: "Series 2",
+        data: 9
+    }, {
+        label: "Series 3",
+        data: 20
+    }];
+
+    var plotObj = $.plot($("#flot-pie-chart"), data, {
+        series: {
+            pie: {
+                show: true
+            }
+        },
+        grid: {
+            hoverable: true
+        },
+        tooltip: true,
+        tooltipOpts: {
+            content: "%p.0%, %s", // show percentages, rounding to 2 decimal places
+            shifts: {
+                x: 20,
+                y: 0
+            },
+            defaultTheme: false
+        }
+    });
+
+});
+
+//Flot Multiple Axes Line Chart
+$(function() {
+    var oilprices = [
+        [1167692400000, 61.05],
+        [1167778800000, 58.32],
+        [1167865200000, 57.35],
+        [1167951600000, 56.31],
+        [1168210800000, 55.55],
+        [1168297200000, 55.64],
+        [1168383600000, 54.02],
+        [1168470000000, 51.88],
+        [1168556400000, 52.99],
+        [1168815600000, 52.99],
+        [1168902000000, 51.21],
+        [1168988400000, 52.24],
+        [1169074800000, 50.48],
+        [1169161200000, 51.99],
+        [1169420400000, 51.13],
+        [1169506800000, 55.04],
+        [1169593200000, 55.37],
+        [1169679600000, 54.23],
+        [1169766000000, 55.42],
+        [1170025200000, 54.01],
+        [1170111600000, 56.97],
+        [1170198000000, 58.14],
+        [1170284400000, 58.14],
+        [1170370800000, 59.02],
+        [1170630000000, 58.74],
+        [1170716400000, 58.88],
+        [1170802800000, 57.71],
+        [1170889200000, 59.71],
+        [1170975600000, 59.89],
+        [1171234800000, 57.81],
+        [1171321200000, 59.06],
+        [1171407600000, 58.00],
+        [1171494000000, 57.99],
+        [1171580400000, 59.39],
+        [1171839600000, 59.39],
+        [1171926000000, 58.07],
+        [1172012400000, 60.07],
+        [1172098800000, 61.14],
+        [1172444400000, 61.39],
+        [1172530800000, 61.46],
+        [1172617200000, 61.79],
+        [1172703600000, 62.00],
+        [1172790000000, 60.07],
+        [1173135600000, 60.69],
+        [1173222000000, 61.82],
+        [1173308400000, 60.05],
+        [1173654000000, 58.91],
+        [1173740400000, 57.93],
+        [1173826800000, 58.16],
+        [1173913200000, 57.55],
+        [1173999600000, 57.11],
+        [1174258800000, 56.59],
+        [1174345200000, 59.61],
+        [1174518000000, 61.69],
+        [1174604400000, 62.28],
+        [1174860000000, 62.91],
+        [1174946400000, 62.93],
+        [1175032800000, 64.03],
+        [1175119200000, 66.03],
+        [1175205600000, 65.87],
+        [1175464800000, 64.64],
+        [1175637600000, 64.38],
+        [1175724000000, 64.28],
+        [1175810400000, 64.28],
+        [1176069600000, 61.51],
+        [1176156000000, 61.89],
+        [1176242400000, 62.01],
+        [1176328800000, 63.85],
+        [1176415200000, 63.63],
+        [1176674400000, 63.61],
+        [1176760800000, 63.10],
+        [1176847200000, 63.13],
+        [1176933600000, 61.83],
+        [1177020000000, 63.38],
+        [1177279200000, 64.58],
+        [1177452000000, 65.84],
+        [1177538400000, 65.06],
+        [1177624800000, 66.46],
+        [1177884000000, 64.40],
+        [1178056800000, 63.68],
+        [1178143200000, 63.19],
+        [1178229600000, 61.93],
+        [1178488800000, 61.47],
+        [1178575200000, 61.55],
+        [1178748000000, 61.81],
+        [1178834400000, 62.37],
+        [1179093600000, 62.46],
+        [1179180000000, 63.17],
+        [1179266400000, 62.55],
+        [1179352800000, 64.94],
+        [1179698400000, 66.27],
+        [1179784800000, 65.50],
+        [1179871200000, 65.77],
+        [1179957600000, 64.18],
+        [1180044000000, 65.20],
+        [1180389600000, 63.15],
+        [1180476000000, 63.49],
+        [1180562400000, 65.08],
+        [1180908000000, 66.30],
+        [1180994400000, 65.96],
+        [1181167200000, 66.93],
+        [1181253600000, 65.98],
+        [1181599200000, 65.35],
+        [1181685600000, 66.26],
+        [1181858400000, 68.00],
+        [1182117600000, 69.09],
+        [1182204000000, 69.10],
+        [1182290400000, 68.19],
+        [1182376800000, 68.19],
+        [1182463200000, 69.14],
+        [1182722400000, 68.19],
+        [1182808800000, 67.77],
+        [1182895200000, 68.97],
+        [1182981600000, 69.57],
+        [1183068000000, 70.68],
+        [1183327200000, 71.09],
+        [1183413600000, 70.92],
+        [1183586400000, 71.81],
+        [1183672800000, 72.81],
+        [1183932000000, 72.19],
+        [1184018400000, 72.56],
+        [1184191200000, 72.50],
+        [1184277600000, 74.15],
+        [1184623200000, 75.05],
+        [1184796000000, 75.92],
+        [1184882400000, 75.57],
+        [1185141600000, 74.89],
+        [1185228000000, 73.56],
+        [1185314400000, 75.57],
+        [1185400800000, 74.95],
+        [1185487200000, 76.83],
+        [1185832800000, 78.21],
+        [1185919200000, 76.53],
+        [1186005600000, 76.86],
+        [1186092000000, 76.00],
+        [1186437600000, 71.59],
+        [1186696800000, 71.47],
+        [1186956000000, 71.62],
+        [1187042400000, 71.00],
+        [1187301600000, 71.98],
+        [1187560800000, 71.12],
+        [1187647200000, 69.47],
+        [1187733600000, 69.26],
+        [1187820000000, 69.83],
+        [1187906400000, 71.09],
+        [1188165600000, 71.73],
+        [1188338400000, 73.36],
+        [1188511200000, 74.04],
+        [1188856800000, 76.30],
+        [1189116000000, 77.49],
+        [1189461600000, 78.23],
+        [1189548000000, 79.91],
+        [1189634400000, 80.09],
+        [1189720800000, 79.10],
+        [1189980000000, 80.57],
+        [1190066400000, 81.93],
+        [1190239200000, 83.32],
+        [1190325600000, 81.62],
+        [1190584800000, 80.95],
+        [1190671200000, 79.53],
+        [1190757600000, 80.30],
+        [1190844000000, 82.88],
+        [1190930400000, 81.66],
+        [1191189600000, 80.24],
+        [1191276000000, 80.05],
+        [1191362400000, 79.94],
+        [1191448800000, 81.44],
+        [1191535200000, 81.22],
+        [1191794400000, 79.02],
+        [1191880800000, 80.26],
+        [1191967200000, 80.30],
+        [1192053600000, 83.08],
+        [1192140000000, 83.69],
+        [1192399200000, 86.13],
+        [1192485600000, 87.61],
+        [1192572000000, 87.40],
+        [1192658400000, 89.47],
+        [1192744800000, 88.60],
+        [1193004000000, 87.56],
+        [1193090400000, 87.56],
+        [1193176800000, 87.10],
+        [1193263200000, 91.86],
+        [1193612400000, 93.53],
+        [1193698800000, 94.53],
+        [1193871600000, 95.93],
+        [1194217200000, 93.98],
+        [1194303600000, 96.37],
+        [1194476400000, 95.46],
+        [1194562800000, 96.32],
+        [1195081200000, 93.43],
+        [1195167600000, 95.10],
+        [1195426800000, 94.64],
+        [1195513200000, 95.10],
+        [1196031600000, 97.70],
+        [1196118000000, 94.42],
+        [1196204400000, 90.62],
+        [1196290800000, 91.01],
+        [1196377200000, 88.71],
+        [1196636400000, 88.32],
+        [1196809200000, 90.23],
+        [1196982000000, 88.28],
+        [1197241200000, 87.86],
+        [1197327600000, 90.02],
+        [1197414000000, 92.25],
+        [1197586800000, 90.63],
+        [1197846000000, 90.63],
+        [1197932400000, 90.49],
+        [1198018800000, 91.24],
+        [1198105200000, 91.06],
+        [1198191600000, 90.49],
+        [1198710000000, 96.62],
+        [1198796400000, 96.00],
+        [1199142000000, 99.62],
+        [1199314800000, 99.18],
+        [1199401200000, 95.09],
+        [1199660400000, 96.33],
+        [1199833200000, 95.67],
+        [1200351600000, 91.90],
+        [1200438000000, 90.84],
+        [1200524400000, 90.13],
+        [1200610800000, 90.57],
+        [1200956400000, 89.21],
+        [1201042800000, 86.99],
+        [1201129200000, 89.85],
+        [1201474800000, 90.99],
+        [1201561200000, 91.64],
+        [1201647600000, 92.33],
+        [1201734000000, 91.75],
+        [1202079600000, 90.02],
+        [1202166000000, 88.41],
+        [1202252400000, 87.14],
+        [1202338800000, 88.11],
+        [1202425200000, 91.77],
+        [1202770800000, 92.78],
+        [1202857200000, 93.27],
+        [1202943600000, 95.46],
+        [1203030000000, 95.46],
+        [1203289200000, 101.74],
+        [1203462000000, 98.81],
+        [1203894000000, 100.88],
+        [1204066800000, 99.64],
+        [1204153200000, 102.59],
+        [1204239600000, 101.84],
+        [1204498800000, 99.52],
+        [1204585200000, 99.52],
+        [1204671600000, 104.52],
+        [1204758000000, 105.47],
+        [1204844400000, 105.15],
+        [1205103600000, 108.75],
+        [1205276400000, 109.92],
+        [1205362800000, 110.33],
+        [1205449200000, 110.21],
+        [1205708400000, 105.68],
+        [1205967600000, 101.84],
+        [1206313200000, 100.86],
+        [1206399600000, 101.22],
+        [1206486000000, 105.90],
+        [1206572400000, 107.58],
+        [1206658800000, 105.62],
+        [1206914400000, 101.58],
+        [1207000800000, 100.98],
+        [1207173600000, 103.83],
+        [1207260000000, 106.23],
+        [1207605600000, 108.50],
+        [1207778400000, 110.11],
+        [1207864800000, 110.14],
+        [1208210400000, 113.79],
+        [1208296800000, 114.93],
+        [1208383200000, 114.86],
+        [1208728800000, 117.48],
+        [1208815200000, 118.30],
+        [1208988000000, 116.06],
+        [1209074400000, 118.52],
+        [1209333600000, 118.75],
+        [1209420000000, 113.46],
+        [1209592800000, 112.52],
+        [1210024800000, 121.84],
+        [1210111200000, 123.53],
+        [1210197600000, 123.69],
+        [1210543200000, 124.23],
+        [1210629600000, 125.80],
+        [1210716000000, 126.29],
+        [1211148000000, 127.05],
+        [1211320800000, 129.07],
+        [1211493600000, 132.19],
+        [1211839200000, 128.85],
+        [1212357600000, 127.76],
+        [1212703200000, 138.54],
+        [1212962400000, 136.80],
+        [1213135200000, 136.38],
+        [1213308000000, 134.86],
+        [1213653600000, 134.01],
+        [1213740000000, 136.68],
+        [1213912800000, 135.65],
+        [1214172000000, 134.62],
+        [1214258400000, 134.62],
+        [1214344800000, 134.62],
+        [1214431200000, 139.64],
+        [1214517600000, 140.21],
+        [1214776800000, 140.00],
+        [1214863200000, 140.97],
+        [1214949600000, 143.57],
+        [1215036000000, 145.29],
+        [1215381600000, 141.37],
+        [1215468000000, 136.04],
+        [1215727200000, 146.40],
+        [1215986400000, 145.18],
+        [1216072800000, 138.74],
+        [1216159200000, 134.60],
+        [1216245600000, 129.29],
+        [1216332000000, 130.65],
+        [1216677600000, 127.95],
+        [1216850400000, 127.95],
+        [1217282400000, 122.19],
+        [1217455200000, 124.08],
+        [1217541600000, 125.10],
+        [1217800800000, 121.41],
+        [1217887200000, 119.17],
+        [1217973600000, 118.58],
+        [1218060000000, 120.02],
+        [1218405600000, 114.45],
+        [1218492000000, 113.01],
+        [1218578400000, 116.00],
+        [1218751200000, 113.77],
+        [1219010400000, 112.87],
+        [1219096800000, 114.53],
+        [1219269600000, 114.98],
+        [1219356000000, 114.98],
+        [1219701600000, 116.27],
+        [1219788000000, 118.15],
+        [1219874400000, 115.59],
+        [1219960800000, 115.46],
+        [1220306400000, 109.71],
+        [1220392800000, 109.35],
+        [1220565600000, 106.23],
+        [1220824800000, 106.34]
+    ];
+    var exchangerates = [
+        [1167606000000, 0.7580],
+        [1167692400000, 0.7580],
+        [1167778800000, 0.75470],
+        [1167865200000, 0.75490],
+        [1167951600000, 0.76130],
+        [1168038000000, 0.76550],
+        [1168124400000, 0.76930],
+        [1168210800000, 0.76940],
+        [1168297200000, 0.76880],
+        [1168383600000, 0.76780],
+        [1168470000000, 0.77080],
+        [1168556400000, 0.77270],
+        [1168642800000, 0.77490],
+        [1168729200000, 0.77410],
+        [1168815600000, 0.77410],
+        [1168902000000, 0.77320],
+        [1168988400000, 0.77270],
+        [1169074800000, 0.77370],
+        [1169161200000, 0.77240],
+        [1169247600000, 0.77120],
+        [1169334000000, 0.7720],
+        [1169420400000, 0.77210],
+        [1169506800000, 0.77170],
+        [1169593200000, 0.77040],
+        [1169679600000, 0.7690],
+        [1169766000000, 0.77110],
+        [1169852400000, 0.7740],
+        [1169938800000, 0.77450],
+        [1170025200000, 0.77450],
+        [1170111600000, 0.7740],
+        [1170198000000, 0.77160],
+        [1170284400000, 0.77130],
+        [1170370800000, 0.76780],
+        [1170457200000, 0.76880],
+        [1170543600000, 0.77180],
+        [1170630000000, 0.77180],
+        [1170716400000, 0.77280],
+        [1170802800000, 0.77290],
+        [1170889200000, 0.76980],
+        [1170975600000, 0.76850],
+        [1171062000000, 0.76810],
+        [1171148400000, 0.7690],
+        [1171234800000, 0.7690],
+        [1171321200000, 0.76980],
+        [1171407600000, 0.76990],
+        [1171494000000, 0.76510],
+        [1171580400000, 0.76130],
+        [1171666800000, 0.76160],
+        [1171753200000, 0.76140],
+        [1171839600000, 0.76140],
+        [1171926000000, 0.76070],
+        [1172012400000, 0.76020],
+        [1172098800000, 0.76110],
+        [1172185200000, 0.76220],
+        [1172271600000, 0.76150],
+        [1172358000000, 0.75980],
+        [1172444400000, 0.75980],
+        [1172530800000, 0.75920],
+        [1172617200000, 0.75730],
+        [1172703600000, 0.75660],
+        [1172790000000, 0.75670],
+        [1172876400000, 0.75910],
+        [1172962800000, 0.75820],
+        [1173049200000, 0.75850],
+        [1173135600000, 0.76130],
+        [1173222000000, 0.76310],
+        [1173308400000, 0.76150],
+        [1173394800000, 0.760],
+        [1173481200000, 0.76130],
+        [1173567600000, 0.76270],
+        [1173654000000, 0.76270],
+        [1173740400000, 0.76080],
+        [1173826800000, 0.75830],
+        [1173913200000, 0.75750],
+        [1173999600000, 0.75620],
+        [1174086000000, 0.7520],
+        [1174172400000, 0.75120],
+        [1174258800000, 0.75120],
+        [1174345200000, 0.75170],
+        [1174431600000, 0.7520],
+        [1174518000000, 0.75110],
+        [1174604400000, 0.7480],
+        [1174690800000, 0.75090],
+        [1174777200000, 0.75310],
+        [1174860000000, 0.75310],
+        [1174946400000, 0.75270],
+        [1175032800000, 0.74980],
+        [1175119200000, 0.74930],
+        [1175205600000, 0.75040],
+        [1175292000000, 0.750],
+        [1175378400000, 0.74910],
+        [1175464800000, 0.74910],
+        [1175551200000, 0.74850],
+        [1175637600000, 0.74840],
+        [1175724000000, 0.74920],
+        [1175810400000, 0.74710],
+        [1175896800000, 0.74590],
+        [1175983200000, 0.74770],
+        [1176069600000, 0.74770],
+        [1176156000000, 0.74830],
+        [1176242400000, 0.74580],
+        [1176328800000, 0.74480],
+        [1176415200000, 0.7430],
+        [1176501600000, 0.73990],
+        [1176588000000, 0.73950],
+        [1176674400000, 0.73950],
+        [1176760800000, 0.73780],
+        [1176847200000, 0.73820],
+        [1176933600000, 0.73620],
+        [1177020000000, 0.73550],
+        [1177106400000, 0.73480],
+        [1177192800000, 0.73610],
+        [1177279200000, 0.73610],
+        [1177365600000, 0.73650],
+        [1177452000000, 0.73620],
+        [1177538400000, 0.73310],
+        [1177624800000, 0.73390],
+        [1177711200000, 0.73440],
+        [1177797600000, 0.73270],
+        [1177884000000, 0.73270],
+        [1177970400000, 0.73360],
+        [1178056800000, 0.73330],
+        [1178143200000, 0.73590],
+        [1178229600000, 0.73590],
+        [1178316000000, 0.73720],
+        [1178402400000, 0.7360],
+        [1178488800000, 0.7360],
+        [1178575200000, 0.7350],
+        [1178661600000, 0.73650],
+        [1178748000000, 0.73840],
+        [1178834400000, 0.73950],
+        [1178920800000, 0.74130],
+        [1179007200000, 0.73970],
+        [1179093600000, 0.73960],
+        [1179180000000, 0.73850],
+        [1179266400000, 0.73780],
+        [1179352800000, 0.73660],
+        [1179439200000, 0.740],
+        [1179525600000, 0.74110],
+        [1179612000000, 0.74060],
+        [1179698400000, 0.74050],
+        [1179784800000, 0.74140],
+        [1179871200000, 0.74310],
+        [1179957600000, 0.74310],
+        [1180044000000, 0.74380],
+        [1180130400000, 0.74430],
+        [1180216800000, 0.74430],
+        [1180303200000, 0.74430],
+        [1180389600000, 0.74340],
+        [1180476000000, 0.74290],
+        [1180562400000, 0.74420],
+        [1180648800000, 0.7440],
+        [1180735200000, 0.74390],
+        [1180821600000, 0.74370],
+        [1180908000000, 0.74370],
+        [1180994400000, 0.74290],
+        [1181080800000, 0.74030],
+        [1181167200000, 0.73990],
+        [1181253600000, 0.74180],
+        [1181340000000, 0.74680],
+        [1181426400000, 0.7480],
+        [1181512800000, 0.7480],
+        [1181599200000, 0.7490],
+        [1181685600000, 0.74940],
+        [1181772000000, 0.75220],
+        [1181858400000, 0.75150],
+        [1181944800000, 0.75020],
+        [1182031200000, 0.74720],
+        [1182117600000, 0.74720],
+        [1182204000000, 0.74620],
+        [1182290400000, 0.74550],
+        [1182376800000, 0.74490],
+        [1182463200000, 0.74670],
+        [1182549600000, 0.74580],
+        [1182636000000, 0.74270],
+        [1182722400000, 0.74270],
+        [1182808800000, 0.7430],
+        [1182895200000, 0.74290],
+        [1182981600000, 0.7440],
+        [1183068000000, 0.7430],
+        [1183154400000, 0.74220],
+        [1183240800000, 0.73880],
+        [1183327200000, 0.73880],
+        [1183413600000, 0.73690],
+        [1183500000000, 0.73450],
+        [1183586400000, 0.73450],
+        [1183672800000, 0.73450],
+        [1183759200000, 0.73520],
+        [1183845600000, 0.73410],
+        [1183932000000, 0.73410],
+        [1184018400000, 0.7340],
+        [1184104800000, 0.73240],
+        [1184191200000, 0.72720],
+        [1184277600000, 0.72640],
+        [1184364000000, 0.72550],
+        [1184450400000, 0.72580],
+        [1184536800000, 0.72580],
+        [1184623200000, 0.72560],
+        [1184709600000, 0.72570],
+        [1184796000000, 0.72470],
+        [1184882400000, 0.72430],
+        [1184968800000, 0.72440],
+        [1185055200000, 0.72350],
+        [1185141600000, 0.72350],
+        [1185228000000, 0.72350],
+        [1185314400000, 0.72350],
+        [1185400800000, 0.72620],
+        [1185487200000, 0.72880],
+        [1185573600000, 0.73010],
+        [1185660000000, 0.73370],
+        [1185746400000, 0.73370],
+        [1185832800000, 0.73240],
+        [1185919200000, 0.72970],
+        [1186005600000, 0.73170],
+        [1186092000000, 0.73150],
+        [1186178400000, 0.72880],
+        [1186264800000, 0.72630],
+        [1186351200000, 0.72630],
+        [1186437600000, 0.72420],
+        [1186524000000, 0.72530],
+        [1186610400000, 0.72640],
+        [1186696800000, 0.7270],
+        [1186783200000, 0.73120],
+        [1186869600000, 0.73050],
+        [1186956000000, 0.73050],
+        [1187042400000, 0.73180],
+        [1187128800000, 0.73580],
+        [1187215200000, 0.74090],
+        [1187301600000, 0.74540],
+        [1187388000000, 0.74370],
+        [1187474400000, 0.74240],
+        [1187560800000, 0.74240],
+        [1187647200000, 0.74150],
+        [1187733600000, 0.74190],
+        [1187820000000, 0.74140],
+        [1187906400000, 0.73770],
+        [1187992800000, 0.73550],
+        [1188079200000, 0.73150],
+        [1188165600000, 0.73150],
+        [1188252000000, 0.7320],
+        [1188338400000, 0.73320],
+        [1188424800000, 0.73460],
+        [1188511200000, 0.73280],
+        [1188597600000, 0.73230],
+        [1188684000000, 0.7340],
+        [1188770400000, 0.7340],
+        [1188856800000, 0.73360],
+        [1188943200000, 0.73510],
+        [1189029600000, 0.73460],
+        [1189116000000, 0.73210],
+        [1189202400000, 0.72940],
+        [1189288800000, 0.72660],
+        [1189375200000, 0.72660],
+        [1189461600000, 0.72540],
+        [1189548000000, 0.72420],
+        [1189634400000, 0.72130],
+        [1189720800000, 0.71970],
+        [1189807200000, 0.72090],
+        [1189893600000, 0.7210],
+        [1189980000000, 0.7210],
+        [1190066400000, 0.7210],
+        [1190152800000, 0.72090],
+        [1190239200000, 0.71590],
+        [1190325600000, 0.71330],
+        [1190412000000, 0.71050],
+        [1190498400000, 0.70990],
+        [1190584800000, 0.70990],
+        [1190671200000, 0.70930],
+        [1190757600000, 0.70930],
+        [1190844000000, 0.70760],
+        [1190930400000, 0.7070],
+        [1191016800000, 0.70490],
+        [1191103200000, 0.70120],
+        [1191189600000, 0.70110],
+        [1191276000000, 0.70190],
+        [1191362400000, 0.70460],
+        [1191448800000, 0.70630],
+        [1191535200000, 0.70890],
+        [1191621600000, 0.70770],
+        [1191708000000, 0.70770],
+        [1191794400000, 0.70770],
+        [1191880800000, 0.70910],
+        [1191967200000, 0.71180],
+        [1192053600000, 0.70790],
+        [1192140000000, 0.70530],
+        [1192226400000, 0.7050],
+        [1192312800000, 0.70550],
+        [1192399200000, 0.70550],
+        [1192485600000, 0.70450],
+        [1192572000000, 0.70510],
+        [1192658400000, 0.70510],
+        [1192744800000, 0.70170],
+        [1192831200000, 0.70],
+        [1192917600000, 0.69950],
+        [1193004000000, 0.69940],
+        [1193090400000, 0.70140],
+        [1193176800000, 0.70360],
+        [1193263200000, 0.70210],
+        [1193349600000, 0.70020],
+        [1193436000000, 0.69670],
+        [1193522400000, 0.6950],
+        [1193612400000, 0.6950],
+        [1193698800000, 0.69390],
+        [1193785200000, 0.6940],
+        [1193871600000, 0.69220],
+        [1193958000000, 0.69190],
+        [1194044400000, 0.69140],
+        [1194130800000, 0.68940],
+        [1194217200000, 0.68910],
+        [1194303600000, 0.69040],
+        [1194390000000, 0.6890],
+        [1194476400000, 0.68340],
+        [1194562800000, 0.68230],
+        [1194649200000, 0.68070],
+        [1194735600000, 0.68150],
+        [1194822000000, 0.68150],
+        [1194908400000, 0.68470],
+        [1194994800000, 0.68590],
+        [1195081200000, 0.68220],
+        [1195167600000, 0.68270],
+        [1195254000000, 0.68370],
+        [1195340400000, 0.68230],
+        [1195426800000, 0.68220],
+        [1195513200000, 0.68220],
+        [1195599600000, 0.67920],
+        [1195686000000, 0.67460],
+        [1195772400000, 0.67350],
+        [1195858800000, 0.67310],
+        [1195945200000, 0.67420],
+        [1196031600000, 0.67440],
+        [1196118000000, 0.67390],
+        [1196204400000, 0.67310],
+        [1196290800000, 0.67610],
+        [1196377200000, 0.67610],
+        [1196463600000, 0.67850],
+        [1196550000000, 0.68180],
+        [1196636400000, 0.68360],
+        [1196722800000, 0.68230],
+        [1196809200000, 0.68050],
+        [1196895600000, 0.67930],
+        [1196982000000, 0.68490],
+        [1197068400000, 0.68330],
+        [1197154800000, 0.68250],
+        [1197241200000, 0.68250],
+        [1197327600000, 0.68160],
+        [1197414000000, 0.67990],
+        [1197500400000, 0.68130],
+        [1197586800000, 0.68090],
+        [1197673200000, 0.68680],
+        [1197759600000, 0.69330],
+        [1197846000000, 0.69330],
+        [1197932400000, 0.69450],
+        [1198018800000, 0.69440],
+        [1198105200000, 0.69460],
+        [1198191600000, 0.69640],
+        [1198278000000, 0.69650],
+        [1198364400000, 0.69560],
+        [1198450800000, 0.69560],
+        [1198537200000, 0.6950],
+        [1198623600000, 0.69480],
+        [1198710000000, 0.69280],
+        [1198796400000, 0.68870],
+        [1198882800000, 0.68240],
+        [1198969200000, 0.67940],
+        [1199055600000, 0.67940],
+        [1199142000000, 0.68030],
+        [1199228400000, 0.68550],
+        [1199314800000, 0.68240],
+        [1199401200000, 0.67910],
+        [1199487600000, 0.67830],
+        [1199574000000, 0.67850],
+        [1199660400000, 0.67850],
+        [1199746800000, 0.67970],
+        [1199833200000, 0.680],
+        [1199919600000, 0.68030],
+        [1200006000000, 0.68050],
+        [1200092400000, 0.6760],
+        [1200178800000, 0.6770],
+        [1200265200000, 0.6770],
+        [1200351600000, 0.67360],
+        [1200438000000, 0.67260],
+        [1200524400000, 0.67640],
+        [1200610800000, 0.68210],
+        [1200697200000, 0.68310],
+        [1200783600000, 0.68420],
+        [1200870000000, 0.68420],
+        [1200956400000, 0.68870],
+        [1201042800000, 0.69030],
+        [1201129200000, 0.68480],
+        [1201215600000, 0.68240],
+        [1201302000000, 0.67880],
+        [1201388400000, 0.68140],
+        [1201474800000, 0.68140],
+        [1201561200000, 0.67970],
+        [1201647600000, 0.67690],
+        [1201734000000, 0.67650],
+        [1201820400000, 0.67330],
+        [1201906800000, 0.67290],
+        [1201993200000, 0.67580],
+        [1202079600000, 0.67580],
+        [1202166000000, 0.6750],
+        [1202252400000, 0.6780],
+        [1202338800000, 0.68330],
+        [1202425200000, 0.68560],
+        [1202511600000, 0.69030],
+        [1202598000000, 0.68960],
+        [1202684400000, 0.68960],
+        [1202770800000, 0.68820],
+        [1202857200000, 0.68790],
+        [1202943600000, 0.68620],
+        [1203030000000, 0.68520],
+        [1203116400000, 0.68230],
+        [1203202800000, 0.68130],
+        [1203289200000, 0.68130],
+        [1203375600000, 0.68220],
+        [1203462000000, 0.68020],
+        [1203548400000, 0.68020],
+        [1203634800000, 0.67840],
+        [1203721200000, 0.67480],
+        [1203807600000, 0.67470],
+        [1203894000000, 0.67470],
+        [1203980400000, 0.67480],
+        [1204066800000, 0.67330],
+        [1204153200000, 0.6650],
+        [1204239600000, 0.66110],
+        [1204326000000, 0.65830],
+        [1204412400000, 0.6590],
+        [1204498800000, 0.6590],
+        [1204585200000, 0.65810],
+        [1204671600000, 0.65780],
+        [1204758000000, 0.65740],
+        [1204844400000, 0.65320],
+        [1204930800000, 0.65020],
+        [1205017200000, 0.65140],
+        [1205103600000, 0.65140],
+        [1205190000000, 0.65070],
+        [1205276400000, 0.6510],
+        [1205362800000, 0.64890],
+        [1205449200000, 0.64240],
+        [1205535600000, 0.64060],
+        [1205622000000, 0.63820],
+        [1205708400000, 0.63820],
+        [1205794800000, 0.63410],
+        [1205881200000, 0.63440],
+        [1205967600000, 0.63780],
+        [1206054000000, 0.64390],
+        [1206140400000, 0.64780],
+        [1206226800000, 0.64810],
+        [1206313200000, 0.64810],
+        [1206399600000, 0.64940],
+        [1206486000000, 0.64380],
+        [1206572400000, 0.63770],
+        [1206658800000, 0.63290],
+        [1206745200000, 0.63360],
+        [1206831600000, 0.63330],
+        [1206914400000, 0.63330],
+        [1207000800000, 0.6330],
+        [1207087200000, 0.63710],
+        [1207173600000, 0.64030],
+        [1207260000000, 0.63960],
+        [1207346400000, 0.63640],
+        [1207432800000, 0.63560],
+        [1207519200000, 0.63560],
+        [1207605600000, 0.63680],
+        [1207692000000, 0.63570],
+        [1207778400000, 0.63540],
+        [1207864800000, 0.6320],
+        [1207951200000, 0.63320],
+        [1208037600000, 0.63280],
+        [1208124000000, 0.63310],
+        [1208210400000, 0.63420],
+        [1208296800000, 0.63210],
+        [1208383200000, 0.63020],
+        [1208469600000, 0.62780],
+        [1208556000000, 0.63080],
+        [1208642400000, 0.63240],
+        [1208728800000, 0.63240],
+        [1208815200000, 0.63070],
+        [1208901600000, 0.62770],
+        [1208988000000, 0.62690],
+        [1209074400000, 0.63350],
+        [1209160800000, 0.63920],
+        [1209247200000, 0.640],
+        [1209333600000, 0.64010],
+        [1209420000000, 0.63960],
+        [1209506400000, 0.64070],
+        [1209592800000, 0.64230],
+        [1209679200000, 0.64290],
+        [1209765600000, 0.64720],
+        [1209852000000, 0.64850],
+        [1209938400000, 0.64860],
+        [1210024800000, 0.64670],
+        [1210111200000, 0.64440],
+        [1210197600000, 0.64670],
+        [1210284000000, 0.65090],
+        [1210370400000, 0.64780],
+        [1210456800000, 0.64610],
+        [1210543200000, 0.64610],
+        [1210629600000, 0.64680],
+        [1210716000000, 0.64490],
+        [1210802400000, 0.6470],
+        [1210888800000, 0.64610],
+        [1210975200000, 0.64520],
+        [1211061600000, 0.64220],
+        [1211148000000, 0.64220],
+        [1211234400000, 0.64250],
+        [1211320800000, 0.64140],
+        [1211407200000, 0.63660],
+        [1211493600000, 0.63460],
+        [1211580000000, 0.6350],
+        [1211666400000, 0.63460],
+        [1211752800000, 0.63460],
+        [1211839200000, 0.63430],
+        [1211925600000, 0.63460],
+        [1212012000000, 0.63790],
+        [1212098400000, 0.64160],
+        [1212184800000, 0.64420],
+        [1212271200000, 0.64310],
+        [1212357600000, 0.64310],
+        [1212444000000, 0.64350],
+        [1212530400000, 0.6440],
+        [1212616800000, 0.64730],
+        [1212703200000, 0.64690],
+        [1212789600000, 0.63860],
+        [1212876000000, 0.63560],
+        [1212962400000, 0.6340],
+        [1213048800000, 0.63460],
+        [1213135200000, 0.6430],
+        [1213221600000, 0.64520],
+        [1213308000000, 0.64670],
+        [1213394400000, 0.65060],
+        [1213480800000, 0.65040],
+        [1213567200000, 0.65030],
+        [1213653600000, 0.64810],
+        [1213740000000, 0.64510],
+        [1213826400000, 0.6450],
+        [1213912800000, 0.64410],
+        [1213999200000, 0.64140],
+        [1214085600000, 0.64090],
+        [1214172000000, 0.64090],
+        [1214258400000, 0.64280],
+        [1214344800000, 0.64310],
+        [1214431200000, 0.64180],
+        [1214517600000, 0.63710],
+        [1214604000000, 0.63490],
+        [1214690400000, 0.63330],
+        [1214776800000, 0.63340],
+        [1214863200000, 0.63380],
+        [1214949600000, 0.63420],
+        [1215036000000, 0.6320],
+        [1215122400000, 0.63180],
+        [1215208800000, 0.6370],
+        [1215295200000, 0.63680],
+        [1215381600000, 0.63680],
+        [1215468000000, 0.63830],
+        [1215554400000, 0.63710],
+        [1215640800000, 0.63710],
+        [1215727200000, 0.63550],
+        [1215813600000, 0.6320],
+        [1215900000000, 0.62770],
+        [1215986400000, 0.62760],
+        [1216072800000, 0.62910],
+        [1216159200000, 0.62740],
+        [1216245600000, 0.62930],
+        [1216332000000, 0.63110],
+        [1216418400000, 0.6310],
+        [1216504800000, 0.63120],
+        [1216591200000, 0.63120],
+        [1216677600000, 0.63040],
+        [1216764000000, 0.62940],
+        [1216850400000, 0.63480],
+        [1216936800000, 0.63780],
+        [1217023200000, 0.63680],
+        [1217109600000, 0.63680],
+        [1217196000000, 0.63680],
+        [1217282400000, 0.6360],
+        [1217368800000, 0.6370],
+        [1217455200000, 0.64180],
+        [1217541600000, 0.64110],
+        [1217628000000, 0.64350],
+        [1217714400000, 0.64270],
+        [1217800800000, 0.64270],
+        [1217887200000, 0.64190],
+        [1217973600000, 0.64460],
+        [1218060000000, 0.64680],
+        [1218146400000, 0.64870],
+        [1218232800000, 0.65940],
+        [1218319200000, 0.66660],
+        [1218405600000, 0.66660],
+        [1218492000000, 0.66780],
+        [1218578400000, 0.67120],
+        [1218664800000, 0.67050],
+        [1218751200000, 0.67180],
+        [1218837600000, 0.67840],
+        [1218924000000, 0.68110],
+        [1219010400000, 0.68110],
+        [1219096800000, 0.67940],
+        [1219183200000, 0.68040],
+        [1219269600000, 0.67810],
+        [1219356000000, 0.67560],
+        [1219442400000, 0.67350],
+        [1219528800000, 0.67630],
+        [1219615200000, 0.67620],
+        [1219701600000, 0.67770],
+        [1219788000000, 0.68150],
+        [1219874400000, 0.68020],
+        [1219960800000, 0.6780],
+        [1220047200000, 0.67960],
+        [1220133600000, 0.68170],
+        [1220220000000, 0.68170],
+        [1220306400000, 0.68320],
+        [1220392800000, 0.68770],
+        [1220479200000, 0.69120],
+        [1220565600000, 0.69140],
+        [1220652000000, 0.70090],
+        [1220738400000, 0.70120],
+        [1220824800000, 0.7010],
+        [1220911200000, 0.70050]
+    ];
+
+    function euroFormatter(v, axis) {
+        return v.toFixed(axis.tickDecimals) + "€";
+    }
+
+    function doPlot(position) {
+        $.plot($("#flot-line-chart-multi"), [{
+            data: oilprices,
+            label: "Oil price ($)"
+        }, {
+            data: exchangerates,
+            label: "USD/EUR exchange rate",
+            yaxis: 2
+        }], {
+            xaxes: [{
+                mode: 'time'
+            }],
+            yaxes: [{
+                min: 0
+            }, {
+                // align if we are to the right
+                alignTicksWithAxis: position == "right" ? 1 : null,
+                position: position,
+                tickFormatter: euroFormatter
+            }],
+            legend: {
+                position: 'sw'
+            },
+            grid: {
+                hoverable: true //IMPORTANT! this is needed for tooltip to work
+            },
+            tooltip: true,
+            tooltipOpts: {
+                content: "%s for %x was %y",
+                xDateFormat: "%y-%0m-%0d",
+
+                onHover: function(flotItem, $tooltipEl) {
+                    // console.log(flotItem, $tooltipEl);
+                }
+            }
+
+        });
+    }
+
+    doPlot("right");
+
+    $("button").click(function() {
+        doPlot($(this).text());
+    });
+});
+
+//Flot Moving Line Chart
+
+$(function() {
+
+    var container = $("#flot-line-chart-moving");
+
+    // Determine how many data points to keep based on the placeholder's initial size;
+    // this gives us a nice high-res plot while avoiding more than one point per pixel.
+
+    var maximum = container.outerWidth() / 2 || 300;
+
+    //
+
+    var data = [];
+
+    function getRandomData() {
+
+        if (data.length) {
+            data = data.slice(1);
+        }
+
+        while (data.length < maximum) {
+            var previous = data.length ? data[data.length - 1] : 50;
+            var y = previous + Math.random() * 10 - 5;
+            data.push(y < 0 ? 0 : y > 100 ? 100 : y);
+        }
+
+        // zip the generated y values with the x values
+
+        var res = [];
+        for (var i = 0; i < data.length; ++i) {
+            res.push([i, data[i]])
+        }
+
+        return res;
+    }
+
+    //
+
+    series = [{
+        data: getRandomData(),
+        lines: {
+            fill: true
+        }
+    }];
+
+    //
+
+    var plot = $.plot(container, series, {
+        grid: {
+            borderWidth: 1,
+            minBorderMargin: 20,
+            labelMargin: 10,
+            backgroundColor: {
+                colors: ["#fff", "#e4f4f4"]
+            },
+            margin: {
+                top: 8,
+                bottom: 20,
+                left: 20
+            },
+            markings: function(axes) {
+                var markings = [];
+                var xaxis = axes.xaxis;
+                for (var x = Math.floor(xaxis.min); x < xaxis.max; x += xaxis.tickSize * 2) {
+                    markings.push({
+                        xaxis: {
+                            from: x,
+                            to: x + xaxis.tickSize
+                        },
+                        color: "rgba(232, 232, 255, 0.2)"
+                    });
+                }
+                return markings;
+            }
+        },
+        xaxis: {
+            tickFormatter: function() {
+                return "";
+            }
+        },
+        yaxis: {
+            min: 0,
+            max: 110
+        },
+        legend: {
+            show: true
+        }
+    });
+
+    // Update the random dataset at 25FPS for a smoothly-animating chart
+
+    setInterval(function updateRandom() {
+        series[0].data = getRandomData();
+        plot.setData(series);
+        plot.draw();
+    }, 40);
+
+});
+
+//Flot Bar Chart
+
+$(function() {
+
+    var barOptions = {
+        series: {
+            bars: {
+                show: true,
+                barWidth: 43200000
+            }
+        },
+        xaxis: {
+            mode: "time",
+            timeformat: "%m/%d",
+            minTickSize: [1, "day"]
+        },
+        grid: {
+            hoverable: true
+        },
+        legend: {
+            show: false
+        },
+        tooltip: true,
+        tooltipOpts: {
+            content: "x: %x, y: %y"
+        }
+    };
+    var barData = {
+        label: "bar",
+        data: [
+            [1354521600000, 1000],
+            [1355040000000, 2000],
+            [1355223600000, 3000],
+            [1355306400000, 4000],
+            [1355487300000, 5000],
+            [1355571900000, 6000]
+        ]
+    };
+    $.plot($("#flot-bar-chart"), [barData], barOptions);
+
+});
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.js
new file mode 100644 (file)
index 0000000..f38561b
--- /dev/null
@@ -0,0 +1,2599 @@
+/*! Javascript plotting library for jQuery, v. 0.7.
+ *
+ * Released under the MIT license by IOLA, December 2007.
+ *
+ */
+
+// first an inline dependency, jquery.colorhelpers.js, we inline it here
+// for convenience
+
+/* Plugin for jQuery for working with colors.
+ * 
+ * Version 1.1.
+ * 
+ * Inspiration from jQuery color animation plugin by John Resig.
+ *
+ * Released under the MIT license by Ole Laursen, October 2009.
+ *
+ * Examples:
+ *
+ *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
+ *   var c = $.color.extract($("#mydiv"), 'background-color');
+ *   console.log(c.r, c.g, c.b, c.a);
+ *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
+ *
+ * Note that .scale() and .add() return the same modified object
+ * instead of making a new one.
+ *
+ * V. 1.1: Fix error handling so e.g. parsing an empty string does
+ * produce a color rather than just crashing.
+ */ 
+(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
+
+// the actual Flot code
+(function($) {
+    function Plot(placeholder, data_, options_, plugins) {
+        // data is on the form:
+        //   [ series1, series2 ... ]
+        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
+        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
+        
+        var series = [],
+            options = {
+                // the color theme used for graphs
+                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
+                legend: {
+                    show: true,
+                    noColumns: 1, // number of colums in legend table
+                    labelFormatter: null, // fn: string -> string
+                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
+                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
+                    position: "ne", // position of default legend container within plot
+                    margin: 5, // distance from grid edge to default legend container within plot
+                    backgroundColor: null, // null means auto-detect
+                    backgroundOpacity: 0.85 // set to 0 to avoid background
+                },
+                xaxis: {
+                    show: null, // null = auto-detect, true = always, false = never
+                    position: "bottom", // or "top"
+                    mode: null, // null or "time"
+                    color: null, // base color, labels, ticks
+                    tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
+                    transform: null, // null or f: number -> number to transform axis
+                    inverseTransform: null, // if transform is set, this should be the inverse function
+                    min: null, // min. value to show, null means set automatically
+                    max: null, // max. value to show, null means set automatically
+                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
+                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
+                    tickFormatter: null, // fn: number -> string
+                    labelWidth: null, // size of tick labels in pixels
+                    labelHeight: null,
+                    reserveSpace: null, // whether to reserve space even if axis isn't shown
+                    tickLength: null, // size in pixels of ticks, or "full" for whole line
+                    alignTicksWithAxis: null, // axis number or null for no sync
+                    
+                    // mode specific options
+                    tickDecimals: null, // no. of decimals, null means auto
+                    tickSize: null, // number or [number, "unit"]
+                    minTickSize: null, // number or [number, "unit"]
+                    monthNames: null, // list of names of months
+                    timeformat: null, // format string to use
+                    twelveHourClock: false // 12 or 24 time in time mode
+                },
+                yaxis: {
+                    autoscaleMargin: 0.02,
+                    position: "left" // or "right"
+                },
+                xaxes: [],
+                yaxes: [],
+                series: {
+                    points: {
+                        show: false,
+                        radius: 3,
+                        lineWidth: 2, // in pixels
+                        fill: true,
+                        fillColor: "#ffffff",
+                        symbol: "circle" // or callback
+                    },
+                    lines: {
+                        // we don't put in show: false so we can see
+                        // whether lines were actively disabled 
+                        lineWidth: 2, // in pixels
+                        fill: false,
+                        fillColor: null,
+                        steps: false
+                    },
+                    bars: {
+                        show: false,
+                        lineWidth: 2, // in pixels
+                        barWidth: 1, // in units of the x axis
+                        fill: true,
+                        fillColor: null,
+                        align: "left", // or "center" 
+                        horizontal: false
+                    },
+                    shadowSize: 3
+                },
+                grid: {
+                    show: true,
+                    aboveData: false,
+                    color: "#545454", // primary color used for outline and labels
+                    backgroundColor: null, // null for transparent, else color
+                    borderColor: null, // set if different from the grid color
+                    tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
+                    labelMargin: 5, // in pixels
+                    axisMargin: 8, // in pixels
+                    borderWidth: 2, // in pixels
+                    minBorderMargin: null, // in pixels, null means taken from points radius
+                    markings: null, // array of ranges or fn: axes -> array of ranges
+                    markingsColor: "#f4f4f4",
+                    markingsLineWidth: 2,
+                    // interactive stuff
+                    clickable: false,
+                    hoverable: false,
+                    autoHighlight: true, // highlight in case mouse is near
+                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
+                },
+                hooks: {}
+            },
+        canvas = null,      // the canvas for the plot itself
+        overlay = null,     // canvas for interactive stuff on top of plot
+        eventHolder = null, // jQuery object that events should be bound to
+        ctx = null, octx = null,
+        xaxes = [], yaxes = [],
+        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
+        canvasWidth = 0, canvasHeight = 0,
+        plotWidth = 0, plotHeight = 0,
+        hooks = {
+            processOptions: [],
+            processRawData: [],
+            processDatapoints: [],
+            drawSeries: [],
+            draw: [],
+            bindEvents: [],
+            drawOverlay: [],
+            shutdown: []
+        },
+        plot = this;
+
+        // public functions
+        plot.setData = setData;
+        plot.setupGrid = setupGrid;
+        plot.draw = draw;
+        plot.getPlaceholder = function() { return placeholder; };
+        plot.getCanvas = function() { return canvas; };
+        plot.getPlotOffset = function() { return plotOffset; };
+        plot.width = function () { return plotWidth; };
+        plot.height = function () { return plotHeight; };
+        plot.offset = function () {
+            var o = eventHolder.offset();
+            o.left += plotOffset.left;
+            o.top += plotOffset.top;
+            return o;
+        };
+        plot.getData = function () { return series; };
+        plot.getAxes = function () {
+            var res = {}, i;
+            $.each(xaxes.concat(yaxes), function (_, axis) {
+                if (axis)
+                    res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
+            });
+            return res;
+        };
+        plot.getXAxes = function () { return xaxes; };
+        plot.getYAxes = function () { return yaxes; };
+        plot.c2p = canvasToAxisCoords;
+        plot.p2c = axisToCanvasCoords;
+        plot.getOptions = function () { return options; };
+        plot.highlight = highlight;
+        plot.unhighlight = unhighlight;
+        plot.triggerRedrawOverlay = triggerRedrawOverlay;
+        plot.pointOffset = function(point) {
+            return {
+                left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left),
+                top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top)
+            };
+        };
+        plot.shutdown = shutdown;
+        plot.resize = function () {
+            getCanvasDimensions();
+            resizeCanvas(canvas);
+            resizeCanvas(overlay);
+        };
+
+        // public attributes
+        plot.hooks = hooks;
+        
+        // initialize
+        initPlugins(plot);
+        parseOptions(options_);
+        setupCanvases();
+        setData(data_);
+        setupGrid();
+        draw();
+        bindEvents();
+
+
+        function executeHooks(hook, args) {
+            args = [plot].concat(args);
+            for (var i = 0; i < hook.length; ++i)
+                hook[i].apply(this, args);
+        }
+
+        function initPlugins() {
+            for (var i = 0; i < plugins.length; ++i) {
+                var p = plugins[i];
+                p.init(plot);
+                if (p.options)
+                    $.extend(true, options, p.options);
+            }
+        }
+        
+        function parseOptions(opts) {
+            var i;
+            
+            $.extend(true, options, opts);
+            
+            if (options.xaxis.color == null)
+                options.xaxis.color = options.grid.color;
+            if (options.yaxis.color == null)
+                options.yaxis.color = options.grid.color;
+            
+            if (options.xaxis.tickColor == null) // backwards-compatibility
+                options.xaxis.tickColor = options.grid.tickColor;
+            if (options.yaxis.tickColor == null) // backwards-compatibility
+                options.yaxis.tickColor = options.grid.tickColor;
+
+            if (options.grid.borderColor == null)
+                options.grid.borderColor = options.grid.color;
+            if (options.grid.tickColor == null)
+                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+            
+            // fill in defaults in axes, copy at least always the
+            // first as the rest of the code assumes it'll be there
+            for (i = 0; i < Math.max(1, options.xaxes.length); ++i)
+                options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]);
+            for (i = 0; i < Math.max(1, options.yaxes.length); ++i)
+                options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]);
+
+            // backwards compatibility, to be removed in future
+            if (options.xaxis.noTicks && options.xaxis.ticks == null)
+                options.xaxis.ticks = options.xaxis.noTicks;
+            if (options.yaxis.noTicks && options.yaxis.ticks == null)
+                options.yaxis.ticks = options.yaxis.noTicks;
+            if (options.x2axis) {
+                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
+                options.xaxes[1].position = "top";
+            }
+            if (options.y2axis) {
+                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
+                options.yaxes[1].position = "right";
+            }
+            if (options.grid.coloredAreas)
+                options.grid.markings = options.grid.coloredAreas;
+            if (options.grid.coloredAreasColor)
+                options.grid.markingsColor = options.grid.coloredAreasColor;
+            if (options.lines)
+                $.extend(true, options.series.lines, options.lines);
+            if (options.points)
+                $.extend(true, options.series.points, options.points);
+            if (options.bars)
+                $.extend(true, options.series.bars, options.bars);
+            if (options.shadowSize != null)
+                options.series.shadowSize = options.shadowSize;
+
+            // save options on axes for future reference
+            for (i = 0; i < options.xaxes.length; ++i)
+                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
+            for (i = 0; i < options.yaxes.length; ++i)
+                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
+
+            // add hooks from options
+            for (var n in hooks)
+                if (options.hooks[n] && options.hooks[n].length)
+                    hooks[n] = hooks[n].concat(options.hooks[n]);
+
+            executeHooks(hooks.processOptions, [options]);
+        }
+
+        function setData(d) {
+            series = parseData(d);
+            fillInSeriesOptions();
+            processData();
+        }
+        
+        function parseData(d) {
+            var res = [];
+            for (var i = 0; i < d.length; ++i) {
+                var s = $.extend(true, {}, options.series);
+
+                if (d[i].data != null) {
+                    s.data = d[i].data; // move the data instead of deep-copy
+                    delete d[i].data;
+
+                    $.extend(true, s, d[i]);
+
+                    d[i].data = s.data;
+                }
+                else
+                    s.data = d[i];
+                res.push(s);
+            }
+
+            return res;
+        }
+        
+        function axisNumber(obj, coord) {
+            var a = obj[coord + "axis"];
+            if (typeof a == "object") // if we got a real axis, extract number
+                a = a.n;
+            if (typeof a != "number")
+                a = 1; // default to first axis
+            return a;
+        }
+
+        function allAxes() {
+            // return flat array without annoying null entries
+            return $.grep(xaxes.concat(yaxes), function (a) { return a; });
+        }
+        
+        function canvasToAxisCoords(pos) {
+            // return an object with x/y corresponding to all used axes 
+            var res = {}, i, axis;
+            for (i = 0; i < xaxes.length; ++i) {
+                axis = xaxes[i];
+                if (axis && axis.used)
+                    res["x" + axis.n] = axis.c2p(pos.left);
+            }
+
+            for (i = 0; i < yaxes.length; ++i) {
+                axis = yaxes[i];
+                if (axis && axis.used)
+                    res["y" + axis.n] = axis.c2p(pos.top);
+            }
+            
+            if (res.x1 !== undefined)
+                res.x = res.x1;
+            if (res.y1 !== undefined)
+                res.y = res.y1;
+
+            return res;
+        }
+        
+        function axisToCanvasCoords(pos) {
+            // get canvas coords from the first pair of x/y found in pos
+            var res = {}, i, axis, key;
+
+            for (i = 0; i < xaxes.length; ++i) {
+                axis = xaxes[i];
+                if (axis && axis.used) {
+                    key = "x" + axis.n;
+                    if (pos[key] == null && axis.n == 1)
+                        key = "x";
+
+                    if (pos[key] != null) {
+                        res.left = axis.p2c(pos[key]);
+                        break;
+                    }
+                }
+            }
+            
+            for (i = 0; i < yaxes.length; ++i) {
+                axis = yaxes[i];
+                if (axis && axis.used) {
+                    key = "y" + axis.n;
+                    if (pos[key] == null && axis.n == 1)
+                        key = "y";
+
+                    if (pos[key] != null) {
+                        res.top = axis.p2c(pos[key]);
+                        break;
+                    }
+                }
+            }
+            
+            return res;
+        }
+        
+        function getOrCreateAxis(axes, number) {
+            if (!axes[number - 1])
+                axes[number - 1] = {
+                    n: number, // save the number for future reference
+                    direction: axes == xaxes ? "x" : "y",
+                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
+                };
+                
+            return axes[number - 1];
+        }
+
+        function fillInSeriesOptions() {
+            var i;
+            
+            // collect what we already got of colors
+            var neededColors = series.length,
+                usedColors = [],
+                assignedColors = [];
+            for (i = 0; i < series.length; ++i) {
+                var sc = series[i].color;
+                if (sc != null) {
+                    --neededColors;
+                    if (typeof sc == "number")
+                        assignedColors.push(sc);
+                    else
+                        usedColors.push($.color.parse(series[i].color));
+                }
+            }
+            
+            // we might need to generate more colors if higher indices
+            // are assigned
+            for (i = 0; i < assignedColors.length; ++i) {
+                neededColors = Math.max(neededColors, assignedColors[i] + 1);
+            }
+
+            // produce colors as needed
+            var colors = [], variation = 0;
+            i = 0;
+            while (colors.length < neededColors) {
+                var c;
+                if (options.colors.length == i) // check degenerate case
+                    c = $.color.make(100, 100, 100);
+                else
+                    c = $.color.parse(options.colors[i]);
+
+                // vary color if needed
+                var sign = variation % 2 == 1 ? -1 : 1;
+                c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2)
+
+                // FIXME: if we're getting to close to something else,
+                // we should probably skip this one
+                colors.push(c);
+                
+                ++i;
+                if (i >= options.colors.length) {
+                    i = 0;
+                    ++variation;
+                }
+            }
+
+            // fill in the options
+            var colori = 0, s;
+            for (i = 0; i < series.length; ++i) {
+                s = series[i];
+                
+                // assign colors
+                if (s.color == null) {
+                    s.color = colors[colori].toString();
+                    ++colori;
+                }
+                else if (typeof s.color == "number")
+                    s.color = colors[s.color].toString();
+
+                // turn on lines automatically in case nothing is set
+                if (s.lines.show == null) {
+                    var v, show = true;
+                    for (v in s)
+                        if (s[v] && s[v].show) {
+                            show = false;
+                            break;
+                        }
+                    if (show)
+                        s.lines.show = true;
+                }
+
+                // setup axes
+                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
+                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
+            }
+        }
+        
+        function processData() {
+            var topSentry = Number.POSITIVE_INFINITY,
+                bottomSentry = Number.NEGATIVE_INFINITY,
+                fakeInfinity = Number.MAX_VALUE,
+                i, j, k, m, length,
+                s, points, ps, x, y, axis, val, f, p;
+
+            function updateAxis(axis, min, max) {
+                if (min < axis.datamin && min != -fakeInfinity)
+                    axis.datamin = min;
+                if (max > axis.datamax && max != fakeInfinity)
+                    axis.datamax = max;
+            }
+
+            $.each(allAxes(), function (_, axis) {
+                // init axis
+                axis.datamin = topSentry;
+                axis.datamax = bottomSentry;
+                axis.used = false;
+            });
+            
+            for (i = 0; i < series.length; ++i) {
+                s = series[i];
+                s.datapoints = { points: [] };
+                
+                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
+            }
+            
+            // first pass: clean and copy data
+            for (i = 0; i < series.length; ++i) {
+                s = series[i];
+
+                var data = s.data, format = s.datapoints.format;
+
+                if (!format) {
+                    format = [];
+                    // find out how to copy
+                    format.push({ x: true, number: true, required: true });
+                    format.push({ y: true, number: true, required: true });
+
+                    if (s.bars.show || (s.lines.show && s.lines.fill)) {
+                        format.push({ y: true, number: true, required: false, defaultValue: 0 });
+                        if (s.bars.horizontal) {
+                            delete format[format.length - 1].y;
+                            format[format.length - 1].x = true;
+                        }
+                    }
+                    
+                    s.datapoints.format = format;
+                }
+
+                if (s.datapoints.pointsize != null)
+                    continue; // already filled in
+
+                s.datapoints.pointsize = format.length;
+                
+                ps = s.datapoints.pointsize;
+                points = s.datapoints.points;
+
+                insertSteps = s.lines.show && s.lines.steps;
+                s.xaxis.used = s.yaxis.used = true;
+                
+                for (j = k = 0; j < data.length; ++j, k += ps) {
+                    p = data[j];
+
+                    var nullify = p == null;
+                    if (!nullify) {
+                        for (m = 0; m < ps; ++m) {
+                            val = p[m];
+                            f = format[m];
+
+                            if (f) {
+                                if (f.number && val != null) {
+                                    val = +val; // convert to number
+                                    if (isNaN(val))
+                                        val = null;
+                                    else if (val == Infinity)
+                                        val = fakeInfinity;
+                                    else if (val == -Infinity)
+                                        val = -fakeInfinity;
+                                }
+
+                                if (val == null) {
+                                    if (f.required)
+                                        nullify = true;
+                                    
+                                    if (f.defaultValue != null)
+                                        val = f.defaultValue;
+                                }
+                            }
+                            
+                            points[k + m] = val;
+                        }
+                    }
+                    
+                    if (nullify) {
+                        for (m = 0; m < ps; ++m) {
+                            val = points[k + m];
+                            if (val != null) {
+                                f = format[m];
+                                // extract min/max info
+                                if (f.x)
+                                    updateAxis(s.xaxis, val, val);
+                                if (f.y)
+                                    updateAxis(s.yaxis, val, val);
+                            }
+                            points[k + m] = null;
+                        }
+                    }
+                    else {
+                        // a little bit of line specific stuff that
+                        // perhaps shouldn't be here, but lacking
+                        // better means...
+                        if (insertSteps && k > 0
+                            && points[k - ps] != null
+                            && points[k - ps] != points[k]
+                            && points[k - ps + 1] != points[k + 1]) {
+                            // copy the point to make room for a middle point
+                            for (m = 0; m < ps; ++m)
+                                points[k + ps + m] = points[k + m];
+
+                            // middle point has same y
+                            points[k + 1] = points[k - ps + 1];
+
+                            // we've added a point, better reflect that
+                            k += ps;
+                        }
+                    }
+                }
+            }
+
+            // give the hooks a chance to run
+            for (i = 0; i < series.length; ++i) {
+                s = series[i];
+                
+                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
+            }
+
+            // second pass: find datamax/datamin for auto-scaling
+            for (i = 0; i < series.length; ++i) {
+                s = series[i];
+                points = s.datapoints.points,
+                ps = s.datapoints.pointsize;
+
+                var xmin = topSentry, ymin = topSentry,
+                    xmax = bottomSentry, ymax = bottomSentry;
+                
+                for (j = 0; j < points.length; j += ps) {
+                    if (points[j] == null)
+                        continue;
+
+                    for (m = 0; m < ps; ++m) {
+                        val = points[j + m];
+                        f = format[m];
+                        if (!f || val == fakeInfinity || val == -fakeInfinity)
+                            continue;
+                        
+                        if (f.x) {
+                            if (val < xmin)
+                                xmin = val;
+                            if (val > xmax)
+                                xmax = val;
+                        }
+                        if (f.y) {
+                            if (val < ymin)
+                                ymin = val;
+                            if (val > ymax)
+                                ymax = val;
+                        }
+                    }
+                }
+                
+                if (s.bars.show) {
+                    // make sure we got room for the bar on the dancing floor
+                    var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
+                    if (s.bars.horizontal) {
+                        ymin += delta;
+                        ymax += delta + s.bars.barWidth;
+                    }
+                    else {
+                        xmin += delta;
+                        xmax += delta + s.bars.barWidth;
+                    }
+                }
+                
+                updateAxis(s.xaxis, xmin, xmax);
+                updateAxis(s.yaxis, ymin, ymax);
+            }
+
+            $.each(allAxes(), function (_, axis) {
+                if (axis.datamin == topSentry)
+                    axis.datamin = null;
+                if (axis.datamax == bottomSentry)
+                    axis.datamax = null;
+            });
+        }
+
+        function makeCanvas(skipPositioning, cls) {
+            var c = document.createElement('canvas');
+            c.className = cls;
+            c.width = canvasWidth;
+            c.height = canvasHeight;
+                    
+            if (!skipPositioning)
+                $(c).css({ position: 'absolute', left: 0, top: 0 });
+                
+            $(c).appendTo(placeholder);
+                
+            if (!c.getContext) // excanvas hack
+                c = window.G_vmlCanvasManager.initElement(c);
+
+            // used for resetting in case we get replotted
+            c.getContext("2d").save();
+            
+            return c;
+        }
+
+        function getCanvasDimensions() {
+            canvasWidth = placeholder.width();
+            canvasHeight = placeholder.height();
+            
+            if (canvasWidth <= 0 || canvasHeight <= 0)
+                throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
+        }
+
+        function resizeCanvas(c) {
+            // resizing should reset the state (excanvas seems to be
+            // buggy though)
+            if (c.width != canvasWidth)
+                c.width = canvasWidth;
+
+            if (c.height != canvasHeight)
+                c.height = canvasHeight;
+
+            // so try to get back to the initial state (even if it's
+            // gone now, this should be safe according to the spec)
+            var cctx = c.getContext("2d");
+            cctx.restore();
+
+            // and save again
+            cctx.save();
+        }
+        
+        function setupCanvases() {
+            var reused,
+                existingCanvas = placeholder.children("canvas.base"),
+                existingOverlay = placeholder.children("canvas.overlay");
+
+            if (existingCanvas.length == 0 || existingOverlay == 0) {
+                // init everything
+                
+                placeholder.html(""); // make sure placeholder is clear
+            
+                placeholder.css({ padding: 0 }); // padding messes up the positioning
+                
+                if (placeholder.css("position") == 'static')
+                    placeholder.css("position", "relative"); // for positioning labels and overlay
+
+                getCanvasDimensions();
+                
+                canvas = makeCanvas(true, "base");
+                overlay = makeCanvas(false, "overlay"); // overlay canvas for interactive features
+
+                reused = false;
+            }
+            else {
+                // reuse existing elements
+
+                canvas = existingCanvas.get(0);
+                overlay = existingOverlay.get(0);
+
+                reused = true;
+            }
+
+            ctx = canvas.getContext("2d");
+            octx = overlay.getContext("2d");
+
+            // we include the canvas in the event holder too, because IE 7
+            // sometimes has trouble with the stacking order
+            eventHolder = $([overlay, canvas]);
+
+            if (reused) {
+                // run shutdown in the old plot object
+                placeholder.data("plot").shutdown();
+
+                // reset reused canvases
+                plot.resize();
+                
+                // make sure overlay pixels are cleared (canvas is cleared when we redraw)
+                octx.clearRect(0, 0, canvasWidth, canvasHeight);
+                
+                // then whack any remaining obvious garbage left
+                eventHolder.unbind();
+                placeholder.children().not([canvas, overlay]).remove();
+            }
+
+            // save in case we get replotted
+            placeholder.data("plot", plot);
+        }
+
+        function bindEvents() {
+            // bind events
+            if (options.grid.hoverable) {
+                eventHolder.mousemove(onMouseMove);
+                eventHolder.mouseleave(onMouseLeave);
+            }
+
+            if (options.grid.clickable)
+                eventHolder.click(onClick);
+
+            executeHooks(hooks.bindEvents, [eventHolder]);
+        }
+
+        function shutdown() {
+            if (redrawTimeout)
+                clearTimeout(redrawTimeout);
+            
+            eventHolder.unbind("mousemove", onMouseMove);
+            eventHolder.unbind("mouseleave", onMouseLeave);
+            eventHolder.unbind("click", onClick);
+            
+            executeHooks(hooks.shutdown, [eventHolder]);
+        }
+
+        function setTransformationHelpers(axis) {
+            // set helper functions on the axis, assumes plot area
+            // has been computed already
+            
+            function identity(x) { return x; }
+            
+            var s, m, t = axis.options.transform || identity,
+                it = axis.options.inverseTransform;
+            
+            // precompute how much the axis is scaling a point
+            // in canvas space
+            if (axis.direction == "x") {
+                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
+                m = Math.min(t(axis.max), t(axis.min));
+            }
+            else {
+                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
+                s = -s;
+                m = Math.max(t(axis.max), t(axis.min));
+            }
+
+            // data point to canvas coordinate
+            if (t == identity) // slight optimization
+                axis.p2c = function (p) { return (p - m) * s; };
+            else
+                axis.p2c = function (p) { return (t(p) - m) * s; };
+            // canvas coordinate to data point
+            if (!it)
+                axis.c2p = function (c) { return m + c / s; };
+            else
+                axis.c2p = function (c) { return it(m + c / s); };
+        }
+
+        function measureTickLabels(axis) {
+            var opts = axis.options, i, ticks = axis.ticks || [], labels = [],
+                l, w = opts.labelWidth, h = opts.labelHeight, dummyDiv;
+
+            function makeDummyDiv(labels, width) {
+                return $('<div style="position:absolute;top:-10000px;' + width + 'font-size:smaller">' +
+                         '<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis">'
+                         + labels.join("") + '</div></div>')
+                    .appendTo(placeholder);
+            }
+            
+            if (axis.direction == "x") {
+                // to avoid measuring the widths of the labels (it's slow), we
+                // construct fixed-size boxes and put the labels inside
+                // them, we don't need the exact figures and the
+                // fixed-size box content is easy to center
+                if (w == null)
+                    w = Math.floor(canvasWidth / (ticks.length > 0 ? ticks.length : 1));
+
+                // measure x label heights
+                if (h == null) {
+                    labels = [];
+                    for (i = 0; i < ticks.length; ++i) {
+                        l = ticks[i].label;
+                        if (l)
+                            labels.push('<div class="tickLabel" style="float:left;width:' + w + 'px">' + l + '</div>');
+                    }
+
+                    if (labels.length > 0) {
+                        // stick them all in the same div and measure
+                        // collective height
+                        labels.push('<div style="clear:left"></div>');
+                        dummyDiv = makeDummyDiv(labels, "width:10000px;");
+                        h = dummyDiv.height();
+                        dummyDiv.remove();
+                    }
+                }
+            }
+            else if (w == null || h == null) {
+                // calculate y label dimensions
+                for (i = 0; i < ticks.length; ++i) {
+                    l = ticks[i].label;
+                    if (l)
+                        labels.push('<div class="tickLabel">' + l + '</div>');
+                }
+                
+                if (labels.length > 0) {
+                    dummyDiv = makeDummyDiv(labels, "");
+                    if (w == null)
+                        w = dummyDiv.children().width();
+                    if (h == null)
+                        h = dummyDiv.find("div.tickLabel").height();
+                    dummyDiv.remove();
+                }
+            }
+
+            if (w == null)
+                w = 0;
+            if (h == null)
+                h = 0;
+
+            axis.labelWidth = w;
+            axis.labelHeight = h;
+        }
+
+        function allocateAxisBoxFirstPhase(axis) {
+            // find the bounding box of the axis by looking at label
+            // widths/heights and ticks, make room by diminishing the
+            // plotOffset
+
+            var lw = axis.labelWidth,
+                lh = axis.labelHeight,
+                pos = axis.options.position,
+                tickLength = axis.options.tickLength,
+                axismargin = options.grid.axisMargin,
+                padding = options.grid.labelMargin,
+                all = axis.direction == "x" ? xaxes : yaxes,
+                index;
+
+            // determine axis margin
+            var samePosition = $.grep(all, function (a) {
+                return a && a.options.position == pos && a.reserveSpace;
+            });
+            if ($.inArray(axis, samePosition) == samePosition.length - 1)
+                axismargin = 0; // outermost
+
+            // determine tick length - if we're innermost, we can use "full"
+            if (tickLength == null)
+                tickLength = "full";
+
+            var sameDirection = $.grep(all, function (a) {
+                return a && a.reserveSpace;
+            });
+
+            var innermost = $.inArray(axis, sameDirection) == 0;
+            if (!innermost && tickLength == "full")
+                tickLength = 5;
+                
+            if (!isNaN(+tickLength))
+                padding += +tickLength;
+
+            // compute box
+            if (axis.direction == "x") {
+                lh += padding;
+                
+                if (pos == "bottom") {
+                    plotOffset.bottom += lh + axismargin;
+                    axis.box = { top: canvasHeight - plotOffset.bottom, height: lh };
+                }
+                else {
+                    axis.box = { top: plotOffset.top + axismargin, height: lh };
+                    plotOffset.top += lh + axismargin;
+                }
+            }
+            else {
+                lw += padding;
+                
+                if (pos == "left") {
+                    axis.box = { left: plotOffset.left + axismargin, width: lw };
+                    plotOffset.left += lw + axismargin;
+                }
+                else {
+                    plotOffset.right += lw + axismargin;
+                    axis.box = { left: canvasWidth - plotOffset.right, width: lw };
+                }
+            }
+
+             // save for future reference
+            axis.position = pos;
+            axis.tickLength = tickLength;
+            axis.box.padding = padding;
+            axis.innermost = innermost;
+        }
+
+        function allocateAxisBoxSecondPhase(axis) {
+            // set remaining bounding box coordinates
+            if (axis.direction == "x") {
+                axis.box.left = plotOffset.left;
+                axis.box.width = plotWidth;
+            }
+            else {
+                axis.box.top = plotOffset.top;
+                axis.box.height = plotHeight;
+            }
+        }
+        
+        function setupGrid() {
+            var i, axes = allAxes();
+
+            // first calculate the plot and axis box dimensions
+
+            $.each(axes, function (_, axis) {
+                axis.show = axis.options.show;
+                if (axis.show == null)
+                    axis.show = axis.used; // by default an axis is visible if it's got data
+                
+                axis.reserveSpace = axis.show || axis.options.reserveSpace;
+
+                setRange(axis);
+            });
+
+            allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });
+
+            plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
+            if (options.grid.show) {
+                $.each(allocatedAxes, function (_, axis) {
+                    // make the ticks
+                    setupTickGeneration(axis);
+                    setTicks(axis);
+                    snapRangeToTicks(axis, axis.ticks);
+
+                    // find labelWidth/Height for axis
+                    measureTickLabels(axis);
+                });
+
+                // with all dimensions in house, we can compute the
+                // axis boxes, start from the outside (reverse order)
+                for (i = allocatedAxes.length - 1; i >= 0; --i)
+                    allocateAxisBoxFirstPhase(allocatedAxes[i]);
+
+                // make sure we've got enough space for things that
+                // might stick out
+                var minMargin = options.grid.minBorderMargin;
+                if (minMargin == null) {
+                    minMargin = 0;
+                    for (i = 0; i < series.length; ++i)
+                        minMargin = Math.max(minMargin, series[i].points.radius + series[i].points.lineWidth/2);
+                }
+                    
+                for (var a in plotOffset) {
+                    plotOffset[a] += options.grid.borderWidth;
+                    plotOffset[a] = Math.max(minMargin, plotOffset[a]);
+                }
+            }
+            
+            plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
+            plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
+
+            // now we got the proper plotWidth/Height, we can compute the scaling
+            $.each(axes, function (_, axis) {
+                setTransformationHelpers(axis);
+            });
+
+            if (options.grid.show) {
+                $.each(allocatedAxes, function (_, axis) {
+                    allocateAxisBoxSecondPhase(axis);
+                });
+
+                insertAxisLabels();
+            }
+            
+            insertLegend();
+        }
+        
+        function setRange(axis) {
+            var opts = axis.options,
+                min = +(opts.min != null ? opts.min : axis.datamin),
+                max = +(opts.max != null ? opts.max : axis.datamax),
+                delta = max - min;
+
+            if (delta == 0.0) {
+                // degenerate case
+                var widen = max == 0 ? 1 : 0.01;
+
+                if (opts.min == null)
+                    min -= widen;
+                // always widen max if we couldn't widen min to ensure we
+                // don't fall into min == max which doesn't work
+                if (opts.max == null || opts.min != null)
+                    max += widen;
+            }
+            else {
+                // consider autoscaling
+                var margin = opts.autoscaleMargin;
+                if (margin != null) {
+                    if (opts.min == null) {
+                        min -= delta * margin;
+                        // make sure we don't go below zero if all values
+                        // are positive
+                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
+                            min = 0;
+                    }
+                    if (opts.max == null) {
+                        max += delta * margin;
+                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
+                            max = 0;
+                    }
+                }
+            }
+            axis.min = min;
+            axis.max = max;
+        }
+
+        function setupTickGeneration(axis) {
+            var opts = axis.options;
+                
+            // estimate number of ticks
+            var noTicks;
+            if (typeof opts.ticks == "number" && opts.ticks > 0)
+                noTicks = opts.ticks;
+            else
+                // heuristic based on the model a*sqrt(x) fitted to
+                // some data points that seemed reasonable
+                noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? canvasWidth : canvasHeight);
+
+            var delta = (axis.max - axis.min) / noTicks,
+                size, generator, unit, formatter, i, magn, norm;
+
+            if (opts.mode == "time") {
+                // pretty handling of time
+                
+                // map of app. size of time units in milliseconds
+                var timeUnitSize = {
+                    "second": 1000,
+                    "minute": 60 * 1000,
+                    "hour": 60 * 60 * 1000,
+                    "day": 24 * 60 * 60 * 1000,
+                    "month": 30 * 24 * 60 * 60 * 1000,
+                    "year": 365.2425 * 24 * 60 * 60 * 1000
+                };
+
+
+                // the allowed tick sizes, after 1 year we use
+                // an integer algorithm
+                var spec = [
+                    [1, "second"], [2, "second"], [5, "second"], [10, "second"],
+                    [30, "second"], 
+                    [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
+                    [30, "minute"], 
+                    [1, "hour"], [2, "hour"], [4, "hour"],
+                    [8, "hour"], [12, "hour"],
+                    [1, "day"], [2, "day"], [3, "day"],
+                    [0.25, "month"], [0.5, "month"], [1, "month"],
+                    [2, "month"], [3, "month"], [6, "month"],
+                    [1, "year"]
+                ];
+
+                var minSize = 0;
+                if (opts.minTickSize != null) {
+                    if (typeof opts.tickSize == "number")
+                        minSize = opts.tickSize;
+                    else
+                        minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
+                }
+
+                for (var i = 0; i < spec.length - 1; ++i)
+                    if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+                                 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
+                       && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
+                        break;
+                size = spec[i][0];
+                unit = spec[i][1];
+                
+                // special-case the possibility of several years
+                if (unit == "year") {
+                    magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
+                    norm = (delta / timeUnitSize.year) / magn;
+                    if (norm < 1.5)
+                        size = 1;
+                    else if (norm < 3)
+                        size = 2;
+                    else if (norm < 7.5)
+                        size = 5;
+                    else
+                        size = 10;
+
+                    size *= magn;
+                }
+
+                axis.tickSize = opts.tickSize || [size, unit];
+                
+                generator = function(axis) {
+                    var ticks = [],
+                        tickSize = axis.tickSize[0], unit = axis.tickSize[1],
+                        d = new Date(axis.min);
+                    
+                    var step = tickSize * timeUnitSize[unit];
+
+                    if (unit == "second")
+                        d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
+                    if (unit == "minute")
+                        d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
+                    if (unit == "hour")
+                        d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
+                    if (unit == "month")
+                        d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
+                    if (unit == "year")
+                        d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
+                    
+                    // reset smaller components
+                    d.setUTCMilliseconds(0);
+                    if (step >= timeUnitSize.minute)
+                        d.setUTCSeconds(0);
+                    if (step >= timeUnitSize.hour)
+                        d.setUTCMinutes(0);
+                    if (step >= timeUnitSize.day)
+                        d.setUTCHours(0);
+                    if (step >= timeUnitSize.day * 4)
+                        d.setUTCDate(1);
+                    if (step >= timeUnitSize.year)
+                        d.setUTCMonth(0);
+
+
+                    var carry = 0, v = Number.NaN, prev;
+                    do {
+                        prev = v;
+                        v = d.getTime();
+                        ticks.push(v);
+                        if (unit == "month") {
+                            if (tickSize < 1) {
+                                // a bit complicated - we'll divide the month
+                                // up but we need to take care of fractions
+                                // so we don't end up in the middle of a day
+                                d.setUTCDate(1);
+                                var start = d.getTime();
+                                d.setUTCMonth(d.getUTCMonth() + 1);
+                                var end = d.getTime();
+                                d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
+                                carry = d.getUTCHours();
+                                d.setUTCHours(0);
+                            }
+                            else
+                                d.setUTCMonth(d.getUTCMonth() + tickSize);
+                        }
+                        else if (unit == "year") {
+                            d.setUTCFullYear(d.getUTCFullYear() + tickSize);
+                        }
+                        else
+                            d.setTime(v + step);
+                    } while (v < axis.max && v != prev);
+
+                    return ticks;
+                };
+
+                formatter = function (v, axis) {
+                    var d = new Date(v);
+
+                    // first check global format
+                    if (opts.timeformat != null)
+                        return $.plot.formatDate(d, opts.timeformat, opts.monthNames);
+                    
+                    var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+                    var span = axis.max - axis.min;
+                    var suffix = (opts.twelveHourClock) ? " %p" : "";
+                    
+                    if (t < timeUnitSize.minute)
+                        fmt = "%h:%M:%S" + suffix;
+                    else if (t < timeUnitSize.day) {
+                        if (span < 2 * timeUnitSize.day)
+                            fmt = "%h:%M" + suffix;
+                        else
+                            fmt = "%b %d %h:%M" + suffix;
+                    }
+                    else if (t < timeUnitSize.month)
+                        fmt = "%b %d";
+                    else if (t < timeUnitSize.year) {
+                        if (span < timeUnitSize.year)
+                            fmt = "%b";
+                        else
+                            fmt = "%b %y";
+                    }
+                    else
+                        fmt = "%y";
+                    
+                    return $.plot.formatDate(d, fmt, opts.monthNames);
+                };
+            }
+            else {
+                // pretty rounding of base-10 numbers
+                var maxDec = opts.tickDecimals;
+                var dec = -Math.floor(Math.log(delta) / Math.LN10);
+                if (maxDec != null && dec > maxDec)
+                    dec = maxDec;
+
+                magn = Math.pow(10, -dec);
+                norm = delta / magn; // norm is between 1.0 and 10.0
+                
+                if (norm < 1.5)
+                    size = 1;
+                else if (norm < 3) {
+                    size = 2;
+                    // special case for 2.5, requires an extra decimal
+                    if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+                        size = 2.5;
+                        ++dec;
+                    }
+                }
+                else if (norm < 7.5)
+                    size = 5;
+                else
+                    size = 10;
+
+                size *= magn;
+                
+                if (opts.minTickSize != null && size < opts.minTickSize)
+                    size = opts.minTickSize;
+
+                axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
+                axis.tickSize = opts.tickSize || size;
+
+                generator = function (axis) {
+                    var ticks = [];
+
+                    // spew out all possible ticks
+                    var start = floorInBase(axis.min, axis.tickSize),
+                        i = 0, v = Number.NaN, prev;
+                    do {
+                        prev = v;
+                        v = start + i * axis.tickSize;
+                        ticks.push(v);
+                        ++i;
+                    } while (v < axis.max && v != prev);
+                    return ticks;
+                };
+
+                formatter = function (v, axis) {
+                    return v.toFixed(axis.tickDecimals);
+                };
+            }
+
+            if (opts.alignTicksWithAxis != null) {
+                var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
+                if (otherAxis && otherAxis.used && otherAxis != axis) {
+                    // consider snapping min/max to outermost nice ticks
+                    var niceTicks = generator(axis);
+                    if (niceTicks.length > 0) {
+                        if (opts.min == null)
+                            axis.min = Math.min(axis.min, niceTicks[0]);
+                        if (opts.max == null && niceTicks.length > 1)
+                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
+                    }
+                    
+                    generator = function (axis) {
+                        // copy ticks, scaled to this axis
+                        var ticks = [], v, i;
+                        for (i = 0; i < otherAxis.ticks.length; ++i) {
+                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
+                            v = axis.min + v * (axis.max - axis.min);
+                            ticks.push(v);
+                        }
+                        return ticks;
+                    };
+                    
+                    // we might need an extra decimal since forced
+                    // ticks don't necessarily fit naturally
+                    if (axis.mode != "time" && opts.tickDecimals == null) {
+                        var extraDec = Math.max(0, -Math.floor(Math.log(delta) / Math.LN10) + 1),
+                            ts = generator(axis);
+
+                        // only proceed if the tick interval rounded
+                        // with an extra decimal doesn't give us a
+                        // zero at end
+                        if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
+                            axis.tickDecimals = extraDec;
+                    }
+                }
+            }
+
+            axis.tickGenerator = generator;
+            if ($.isFunction(opts.tickFormatter))
+                axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
+            else
+                axis.tickFormatter = formatter;
+        }
+        
+        function setTicks(axis) {
+            var oticks = axis.options.ticks, ticks = [];
+            if (oticks == null || (typeof oticks == "number" && oticks > 0))
+                ticks = axis.tickGenerator(axis);
+            else if (oticks) {
+                if ($.isFunction(oticks))
+                    // generate the ticks
+                    ticks = oticks({ min: axis.min, max: axis.max });
+                else
+                    ticks = oticks;
+            }
+
+            // clean up/labelify the supplied ticks, copy them over
+            var i, v;
+            axis.ticks = [];
+            for (i = 0; i < ticks.length; ++i) {
+                var label = null;
+                var t = ticks[i];
+                if (typeof t == "object") {
+                    v = +t[0];
+                    if (t.length > 1)
+                        label = t[1];
+                }
+                else
+                    v = +t;
+                if (label == null)
+                    label = axis.tickFormatter(v, axis);
+                if (!isNaN(v))
+                    axis.ticks.push({ v: v, label: label });
+            }
+        }
+
+        function snapRangeToTicks(axis, ticks) {
+            if (axis.options.autoscaleMargin && ticks.length > 0) {
+                // snap to ticks
+                if (axis.options.min == null)
+                    axis.min = Math.min(axis.min, ticks[0].v);
+                if (axis.options.max == null && ticks.length > 1)
+                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
+            }
+        }
+      
+        function draw() {
+            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+
+            var grid = options.grid;
+
+            // draw background, if any
+            if (grid.show && grid.backgroundColor)
+                drawBackground();
+            
+            if (grid.show && !grid.aboveData)
+                drawGrid();
+
+            for (var i = 0; i < series.length; ++i) {
+                executeHooks(hooks.drawSeries, [ctx, series[i]]);
+                drawSeries(series[i]);
+            }
+
+            executeHooks(hooks.draw, [ctx]);
+            
+            if (grid.show && grid.aboveData)
+                drawGrid();
+        }
+
+        function extractRange(ranges, coord) {
+            var axis, from, to, key, axes = allAxes();
+
+            for (i = 0; i < axes.length; ++i) {
+                axis = axes[i];
+                if (axis.direction == coord) {
+                    key = coord + axis.n + "axis";
+                    if (!ranges[key] && axis.n == 1)
+                        key = coord + "axis"; // support x1axis as xaxis
+                    if (ranges[key]) {
+                        from = ranges[key].from;
+                        to = ranges[key].to;
+                        break;
+                    }
+                }
+            }
+
+            // backwards-compat stuff - to be removed in future
+            if (!ranges[key]) {
+                axis = coord == "x" ? xaxes[0] : yaxes[0];
+                from = ranges[coord + "1"];
+                to = ranges[coord + "2"];
+            }
+
+            // auto-reverse as an added bonus
+            if (from != null && to != null && from > to) {
+                var tmp = from;
+                from = to;
+                to = tmp;
+            }
+            
+            return { from: from, to: to, axis: axis };
+        }
+        
+        function drawBackground() {
+            ctx.save();
+            ctx.translate(plotOffset.left, plotOffset.top);
+
+            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
+            ctx.fillRect(0, 0, plotWidth, plotHeight);
+            ctx.restore();
+        }
+
+        function drawGrid() {
+            var i;
+            
+            ctx.save();
+            ctx.translate(plotOffset.left, plotOffset.top);
+
+            // draw markings
+            var markings = options.grid.markings;
+            if (markings) {
+                if ($.isFunction(markings)) {
+                    var axes = plot.getAxes();
+                    // xmin etc. is backwards compatibility, to be
+                    // removed in the future
+                    axes.xmin = axes.xaxis.min;
+                    axes.xmax = axes.xaxis.max;
+                    axes.ymin = axes.yaxis.min;
+                    axes.ymax = axes.yaxis.max;
+                    
+                    markings = markings(axes);
+                }
+
+                for (i = 0; i < markings.length; ++i) {
+                    var m = markings[i],
+                        xrange = extractRange(m, "x"),
+                        yrange = extractRange(m, "y");
+
+                    // fill in missing
+                    if (xrange.from == null)
+                        xrange.from = xrange.axis.min;
+                    if (xrange.to == null)
+                        xrange.to = xrange.axis.max;
+                    if (yrange.from == null)
+                        yrange.from = yrange.axis.min;
+                    if (yrange.to == null)
+                        yrange.to = yrange.axis.max;
+
+                    // clip
+                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
+                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
+                        continue;
+
+                    xrange.from = Math.max(xrange.from, xrange.axis.min);
+                    xrange.to = Math.min(xrange.to, xrange.axis.max);
+                    yrange.from = Math.max(yrange.from, yrange.axis.min);
+                    yrange.to = Math.min(yrange.to, yrange.axis.max);
+
+                    if (xrange.from == xrange.to && yrange.from == yrange.to)
+                        continue;
+
+                    // then draw
+                    xrange.from = xrange.axis.p2c(xrange.from);
+                    xrange.to = xrange.axis.p2c(xrange.to);
+                    yrange.from = yrange.axis.p2c(yrange.from);
+                    yrange.to = yrange.axis.p2c(yrange.to);
+                    
+                    if (xrange.from == xrange.to || yrange.from == yrange.to) {
+                        // draw line
+                        ctx.beginPath();
+                        ctx.strokeStyle = m.color || options.grid.markingsColor;
+                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
+                        ctx.moveTo(xrange.from, yrange.from);
+                        ctx.lineTo(xrange.to, yrange.to);
+                        ctx.stroke();
+                    }
+                    else {
+                        // fill area
+                        ctx.fillStyle = m.color || options.grid.markingsColor;
+                        ctx.fillRect(xrange.from, yrange.to,
+                                     xrange.to - xrange.from,
+                                     yrange.from - yrange.to);
+                    }
+                }
+            }
+            
+            // draw the ticks
+            var axes = allAxes(), bw = options.grid.borderWidth;
+
+            for (var j = 0; j < axes.length; ++j) {
+                var axis = axes[j], box = axis.box,
+                    t = axis.tickLength, x, y, xoff, yoff;
+                if (!axis.show || axis.ticks.length == 0)
+                    continue;
+                
+                ctx.strokeStyle = axis.options.tickColor || $.color.parse(axis.options.color).scale('a', 0.22).toString();
+                ctx.lineWidth = 1;
+
+                // find the edges
+                if (axis.direction == "x") {
+                    x = 0;
+                    if (t == "full")
+                        y = (axis.position == "top" ? 0 : plotHeight);
+                    else
+                        y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
+                }
+                else {
+                    y = 0;
+                    if (t == "full")
+                        x = (axis.position == "left" ? 0 : plotWidth);
+                    else
+                        x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
+                }
+                
+                // draw tick bar
+                if (!axis.innermost) {
+                    ctx.beginPath();
+                    xoff = yoff = 0;
+                    if (axis.direction == "x")
+                        xoff = plotWidth;
+                    else
+                        yoff = plotHeight;
+                    
+                    if (ctx.lineWidth == 1) {
+                        x = Math.floor(x) + 0.5;
+                        y = Math.floor(y) + 0.5;
+                    }
+
+                    ctx.moveTo(x, y);
+                    ctx.lineTo(x + xoff, y + yoff);
+                    ctx.stroke();
+                }
+
+                // draw ticks
+                ctx.beginPath();
+                for (i = 0; i < axis.ticks.length; ++i) {
+                    var v = axis.ticks[i].v;
+                    
+                    xoff = yoff = 0;
+
+                    if (v < axis.min || v > axis.max
+                        // skip those lying on the axes if we got a border
+                        || (t == "full" && bw > 0
+                            && (v == axis.min || v == axis.max)))
+                        continue;
+
+                    if (axis.direction == "x") {
+                        x = axis.p2c(v);
+                        yoff = t == "full" ? -plotHeight : t;
+                        
+                        if (axis.position == "top")
+                            yoff = -yoff;
+                    }
+                    else {
+                        y = axis.p2c(v);
+                        xoff = t == "full" ? -plotWidth : t;
+                        
+                        if (axis.position == "left")
+                            xoff = -xoff;
+                    }
+
+                    if (ctx.lineWidth == 1) {
+                        if (axis.direction == "x")
+                            x = Math.floor(x) + 0.5;
+                        else
+                            y = Math.floor(y) + 0.5;
+                    }
+
+                    ctx.moveTo(x, y);
+                    ctx.lineTo(x + xoff, y + yoff);
+                }
+                
+                ctx.stroke();
+            }
+            
+            
+            // draw border
+            if (bw) {
+                ctx.lineWidth = bw;
+                ctx.strokeStyle = options.grid.borderColor;
+                ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
+            }
+
+            ctx.restore();
+        }
+
+        function insertAxisLabels() {
+            placeholder.find(".tickLabels").remove();
+            
+            var html = ['<div class="tickLabels" style="font-size:smaller">'];
+
+            var axes = allAxes();
+            for (var j = 0; j < axes.length; ++j) {
+                var axis = axes[j], box = axis.box;
+                if (!axis.show)
+                    continue;
+                //debug: html.push('<div style="position:absolute;opacity:0.10;background-color:red;left:' + box.left + 'px;top:' + box.top + 'px;width:' + box.width +  'px;height:' + box.height + 'px"></div>')
+                html.push('<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis" style="color:' + axis.options.color + '">');
+                for (var i = 0; i < axis.ticks.length; ++i) {
+                    var tick = axis.ticks[i];
+                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
+                        continue;
+
+                    var pos = {}, align;
+                    
+                    if (axis.direction == "x") {
+                        align = "center";
+                        pos.left = Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2);
+                        if (axis.position == "bottom")
+                            pos.top = box.top + box.padding;
+                        else
+                            pos.bottom = canvasHeight - (box.top + box.height - box.padding);
+                    }
+                    else {
+                        pos.top = Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2);
+                        if (axis.position == "left") {
+                            pos.right = canvasWidth - (box.left + box.width - box.padding)
+                            align = "right";
+                        }
+                        else {
+                            pos.left = box.left + box.padding;
+                            align = "left";
+                        }
+                    }
+
+                    pos.width = axis.labelWidth;
+
+                    var style = ["position:absolute", "text-align:" + align ];
+                    for (var a in pos)
+                        style.push(a + ":" + pos[a] + "px")
+                    
+                    html.push('<div class="tickLabel" style="' + style.join(';') + '">' + tick.label + '</div>');
+                }
+                html.push('</div>');
+            }
+
+            html.push('</div>');
+
+            placeholder.append(html.join(""));
+        }
+
+        function drawSeries(series) {
+            if (series.lines.show)
+                drawSeriesLines(series);
+            if (series.bars.show)
+                drawSeriesBars(series);
+            if (series.points.show)
+                drawSeriesPoints(series);
+        }
+        
+        function drawSeriesLines(series) {
+            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
+                var points = datapoints.points,
+                    ps = datapoints.pointsize,
+                    prevx = null, prevy = null;
+                
+                ctx.beginPath();
+                for (var i = ps; i < points.length; i += ps) {
+                    var x1 = points[i - ps], y1 = points[i - ps + 1],
+                        x2 = points[i], y2 = points[i + 1];
+                    
+                    if (x1 == null || x2 == null)
+                        continue;
+
+                    // clip with ymin
+                    if (y1 <= y2 && y1 < axisy.min) {
+                        if (y2 < axisy.min)
+                            continue;   // line segment is outside
+                        // compute new intersection point
+                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y1 = axisy.min;
+                    }
+                    else if (y2 <= y1 && y2 < axisy.min) {
+                        if (y1 < axisy.min)
+                            continue;
+                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y2 = axisy.min;
+                    }
+
+                    // clip with ymax
+                    if (y1 >= y2 && y1 > axisy.max) {
+                        if (y2 > axisy.max)
+                            continue;
+                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y1 = axisy.max;
+                    }
+                    else if (y2 >= y1 && y2 > axisy.max) {
+                        if (y1 > axisy.max)
+                            continue;
+                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y2 = axisy.max;
+                    }
+
+                    // clip with xmin
+                    if (x1 <= x2 && x1 < axisx.min) {
+                        if (x2 < axisx.min)
+                            continue;
+                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x1 = axisx.min;
+                    }
+                    else if (x2 <= x1 && x2 < axisx.min) {
+                        if (x1 < axisx.min)
+                            continue;
+                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x2 = axisx.min;
+                    }
+
+                    // clip with xmax
+                    if (x1 >= x2 && x1 > axisx.max) {
+                        if (x2 > axisx.max)
+                            continue;
+                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x1 = axisx.max;
+                    }
+                    else if (x2 >= x1 && x2 > axisx.max) {
+                        if (x1 > axisx.max)
+                            continue;
+                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x2 = axisx.max;
+                    }
+
+                    if (x1 != prevx || y1 != prevy)
+                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+                    
+                    prevx = x2;
+                    prevy = y2;
+                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+                }
+                ctx.stroke();
+            }
+
+            function plotLineArea(datapoints, axisx, axisy) {
+                var points = datapoints.points,
+                    ps = datapoints.pointsize,
+                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+                    i = 0, top, areaOpen = false,
+                    ypos = 1, segmentStart = 0, segmentEnd = 0;
+
+                // we process each segment in two turns, first forward
+                // direction to sketch out top, then once we hit the
+                // end we go backwards to sketch the bottom
+                while (true) {
+                    if (ps > 0 && i > points.length + ps)
+                        break;
+
+                    i += ps; // ps is negative if going backwards
+
+                    var x1 = points[i - ps],
+                        y1 = points[i - ps + ypos],
+                        x2 = points[i], y2 = points[i + ypos];
+
+                    if (areaOpen) {
+                        if (ps > 0 && x1 != null && x2 == null) {
+                            // at turning point
+                            segmentEnd = i;
+                            ps = -ps;
+                            ypos = 2;
+                            continue;
+                        }
+
+                        if (ps < 0 && i == segmentStart + ps) {
+                            // done with the reverse sweep
+                            ctx.fill();
+                            areaOpen = false;
+                            ps = -ps;
+                            ypos = 1;
+                            i = segmentStart = segmentEnd + ps;
+                            continue;
+                        }
+                    }
+
+                    if (x1 == null || x2 == null)
+                        continue;
+
+                    // clip x values
+                    
+                    // clip with xmin
+                    if (x1 <= x2 && x1 < axisx.min) {
+                        if (x2 < axisx.min)
+                            continue;
+                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x1 = axisx.min;
+                    }
+                    else if (x2 <= x1 && x2 < axisx.min) {
+                        if (x1 < axisx.min)
+                            continue;
+                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x2 = axisx.min;
+                    }
+
+                    // clip with xmax
+                    if (x1 >= x2 && x1 > axisx.max) {
+                        if (x2 > axisx.max)
+                            continue;
+                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x1 = axisx.max;
+                    }
+                    else if (x2 >= x1 && x2 > axisx.max) {
+                        if (x1 > axisx.max)
+                            continue;
+                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+                        x2 = axisx.max;
+                    }
+
+                    if (!areaOpen) {
+                        // open area
+                        ctx.beginPath();
+                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
+                        areaOpen = true;
+                    }
+                    
+                    // now first check the case where both is outside
+                    if (y1 >= axisy.max && y2 >= axisy.max) {
+                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
+                        continue;
+                    }
+                    else if (y1 <= axisy.min && y2 <= axisy.min) {
+                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
+                        continue;
+                    }
+                    
+                    // else it's a bit more complicated, there might
+                    // be a flat maxed out rectangle first, then a
+                    // triangular cutout or reverse; to find these
+                    // keep track of the current x values
+                    var x1old = x1, x2old = x2;
+
+                    // clip the y values, without shortcutting, we
+                    // go through all cases in turn
+                    
+                    // clip with ymin
+                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
+                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y1 = axisy.min;
+                    }
+                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
+                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y2 = axisy.min;
+                    }
+
+                    // clip with ymax
+                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
+                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y1 = axisy.max;
+                    }
+                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
+                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+                        y2 = axisy.max;
+                    }
+
+                    // if the x value was changed we got a rectangle
+                    // to fill
+                    if (x1 != x1old) {
+                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
+                        // it goes to (x1, y1), but we fill that below
+                    }
+                    
+                    // fill triangular section, this sometimes result
+                    // in redundant points if (x1, y1) hasn't changed
+                    // from previous line to, but we just ignore that
+                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
+                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+
+                    // fill the other rectangle if it's there
+                    if (x2 != x2old) {
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
+                    }
+                }
+            }
+
+            ctx.save();
+            ctx.translate(plotOffset.left, plotOffset.top);
+            ctx.lineJoin = "round";
+
+            var lw = series.lines.lineWidth,
+                sw = series.shadowSize;
+            // FIXME: consider another form of shadow when filling is turned on
+            if (lw > 0 && sw > 0) {
+                // draw shadow as a thick and thin line with transparency
+                ctx.lineWidth = sw;
+                ctx.strokeStyle = "rgba(0,0,0,0.1)";
+                // position shadow at angle from the mid of line
+                var angle = Math.PI/18;
+                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
+                ctx.lineWidth = sw/2;
+                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
+            }
+
+            ctx.lineWidth = lw;
+            ctx.strokeStyle = series.color;
+            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
+            if (fillStyle) {
+                ctx.fillStyle = fillStyle;
+                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
+            }
+
+            if (lw > 0)
+                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
+            ctx.restore();
+        }
+
+        function drawSeriesPoints(series) {
+            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
+                var points = datapoints.points, ps = datapoints.pointsize;
+
+                for (var i = 0; i < points.length; i += ps) {
+                    var x = points[i], y = points[i + 1];
+                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+                        continue;
+                    
+                    ctx.beginPath();
+                    x = axisx.p2c(x);
+                    y = axisy.p2c(y) + offset;
+                    if (symbol == "circle")
+                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
+                    else
+                        symbol(ctx, x, y, radius, shadow);
+                    ctx.closePath();
+                    
+                    if (fillStyle) {
+                        ctx.fillStyle = fillStyle;
+                        ctx.fill();
+                    }
+                    ctx.stroke();
+                }
+            }
+            
+            ctx.save();
+            ctx.translate(plotOffset.left, plotOffset.top);
+
+            var lw = series.points.lineWidth,
+                sw = series.shadowSize,
+                radius = series.points.radius,
+                symbol = series.points.symbol;
+            if (lw > 0 && sw > 0) {
+                // draw shadow in two steps
+                var w = sw / 2;
+                ctx.lineWidth = w;
+                ctx.strokeStyle = "rgba(0,0,0,0.1)";
+                plotPoints(series.datapoints, radius, null, w + w/2, true,
+                           series.xaxis, series.yaxis, symbol);
+
+                ctx.strokeStyle = "rgba(0,0,0,0.2)";
+                plotPoints(series.datapoints, radius, null, w/2, true,
+                           series.xaxis, series.yaxis, symbol);
+            }
+
+            ctx.lineWidth = lw;
+            ctx.strokeStyle = series.color;
+            plotPoints(series.datapoints, radius,
+                       getFillStyle(series.points, series.color), 0, false,
+                       series.xaxis, series.yaxis, symbol);
+            ctx.restore();
+        }
+
+        function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
+            var left, right, bottom, top,
+                drawLeft, drawRight, drawTop, drawBottom,
+                tmp;
+
+            // in horizontal mode, we start the bar from the left
+            // instead of from the bottom so it appears to be
+            // horizontal rather than vertical
+            if (horizontal) {
+                drawBottom = drawRight = drawTop = true;
+                drawLeft = false;
+                left = b;
+                right = x;
+                top = y + barLeft;
+                bottom = y + barRight;
+
+                // account for negative bars
+                if (right < left) {
+                    tmp = right;
+                    right = left;
+                    left = tmp;
+                    drawLeft = true;
+                    drawRight = false;
+                }
+            }
+            else {
+                drawLeft = drawRight = drawTop = true;
+                drawBottom = false;
+                left = x + barLeft;
+                right = x + barRight;
+                bottom = b;
+                top = y;
+
+                // account for negative bars
+                if (top < bottom) {
+                    tmp = top;
+                    top = bottom;
+                    bottom = tmp;
+                    drawBottom = true;
+                    drawTop = false;
+                }
+            }
+           
+            // clip
+            if (right < axisx.min || left > axisx.max ||
+                top < axisy.min || bottom > axisy.max)
+                return;
+            
+            if (left < axisx.min) {
+                left = axisx.min;
+                drawLeft = false;
+            }
+
+            if (right > axisx.max) {
+                right = axisx.max;
+                drawRight = false;
+            }
+
+            if (bottom < axisy.min) {
+                bottom = axisy.min;
+                drawBottom = false;
+            }
+            
+            if (top > axisy.max) {
+                top = axisy.max;
+                drawTop = false;
+            }
+
+            left = axisx.p2c(left);
+            bottom = axisy.p2c(bottom);
+            right = axisx.p2c(right);
+            top = axisy.p2c(top);
+            
+            // fill the bar
+            if (fillStyleCallback) {
+                c.beginPath();
+                c.moveTo(left, bottom);
+                c.lineTo(left, top);
+                c.lineTo(right, top);
+                c.lineTo(right, bottom);
+                c.fillStyle = fillStyleCallback(bottom, top);
+                c.fill();
+            }
+
+            // draw outline
+            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
+                c.beginPath();
+
+                // FIXME: inline moveTo is buggy with excanvas
+                c.moveTo(left, bottom + offset);
+                if (drawLeft)
+                    c.lineTo(left, top + offset);
+                else
+                    c.moveTo(left, top + offset);
+                if (drawTop)
+                    c.lineTo(right, top + offset);
+                else
+                    c.moveTo(right, top + offset);
+                if (drawRight)
+                    c.lineTo(right, bottom + offset);
+                else
+                    c.moveTo(right, bottom + offset);
+                if (drawBottom)
+                    c.lineTo(left, bottom + offset);
+                else
+                    c.moveTo(left, bottom + offset);
+                c.stroke();
+            }
+        }
+        
+        function drawSeriesBars(series) {
+            function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
+                var points = datapoints.points, ps = datapoints.pointsize;
+                
+                for (var i = 0; i < points.length; i += ps) {
+                    if (points[i] == null)
+                        continue;
+                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
+                }
+            }
+
+            ctx.save();
+            ctx.translate(plotOffset.left, plotOffset.top);
+
+            // FIXME: figure out a way to add shadows (for instance along the right edge)
+            ctx.lineWidth = series.bars.lineWidth;
+            ctx.strokeStyle = series.color;
+            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
+            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
+            ctx.restore();
+        }
+
+        function getFillStyle(filloptions, seriesColor, bottom, top) {
+            var fill = filloptions.fill;
+            if (!fill)
+                return null;
+
+            if (filloptions.fillColor)
+                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
+            
+            var c = $.color.parse(seriesColor);
+            c.a = typeof fill == "number" ? fill : 0.4;
+            c.normalize();
+            return c.toString();
+        }
+        
+        function insertLegend() {
+            placeholder.find(".legend").remove();
+
+            if (!options.legend.show)
+                return;
+            
+            var fragments = [], rowStarted = false,
+                lf = options.legend.labelFormatter, s, label;
+            for (var i = 0; i < series.length; ++i) {
+                s = series[i];
+                label = s.label;
+                if (!label)
+                    continue;
+                
+                if (i % options.legend.noColumns == 0) {
+                    if (rowStarted)
+                        fragments.push('</tr>');
+                    fragments.push('<tr>');
+                    rowStarted = true;
+                }
+
+                if (lf)
+                    label = lf(label, s);
+                
+                fragments.push(
+                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
+                    '<td class="legendLabel">' + label + '</td>');
+            }
+            if (rowStarted)
+                fragments.push('</tr>');
+            
+            if (fragments.length == 0)
+                return;
+
+            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
+            if (options.legend.container != null)
+                $(options.legend.container).html(table);
+            else {
+                var pos = "",
+                    p = options.legend.position,
+                    m = options.legend.margin;
+                if (m[0] == null)
+                    m = [m, m];
+                if (p.charAt(0) == "n")
+                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
+                else if (p.charAt(0) == "s")
+                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
+                if (p.charAt(1) == "e")
+                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
+                else if (p.charAt(1) == "w")
+                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
+                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
+                if (options.legend.backgroundOpacity != 0.0) {
+                    // put in the transparent background
+                    // separately to avoid blended labels and
+                    // label boxes
+                    var c = options.legend.backgroundColor;
+                    if (c == null) {
+                        c = options.grid.backgroundColor;
+                        if (c && typeof c == "string")
+                            c = $.color.parse(c);
+                        else
+                            c = $.color.extract(legend, 'background-color');
+                        c.a = 1;
+                        c = c.toString();
+                    }
+                    var div = legend.children();
+                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
+                }
+            }
+        }
+
+
+        // interactive features
+        
+        var highlights = [],
+            redrawTimeout = null;
+        
+        // returns the data item the mouse is over, or null if none is found
+        function findNearbyItem(mouseX, mouseY, seriesFilter) {
+            var maxDistance = options.grid.mouseActiveRadius,
+                smallestDistance = maxDistance * maxDistance + 1,
+                item = null, foundPoint = false, i, j;
+
+            for (i = series.length - 1; i >= 0; --i) {
+                if (!seriesFilter(series[i]))
+                    continue;
+                
+                var s = series[i],
+                    axisx = s.xaxis,
+                    axisy = s.yaxis,
+                    points = s.datapoints.points,
+                    ps = s.datapoints.pointsize,
+                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+                    my = axisy.c2p(mouseY),
+                    maxx = maxDistance / axisx.scale,
+                    maxy = maxDistance / axisy.scale;
+
+                // with inverse transforms, we can't use the maxx/maxy
+                // optimization, sadly
+                if (axisx.options.inverseTransform)
+                    maxx = Number.MAX_VALUE;
+                if (axisy.options.inverseTransform)
+                    maxy = Number.MAX_VALUE;
+                
+                if (s.lines.show || s.points.show) {
+                    for (j = 0; j < points.length; j += ps) {
+                        var x = points[j], y = points[j + 1];
+                        if (x == null)
+                            continue;
+                        
+                        // For points and lines, the cursor must be within a
+                        // certain distance to the data point
+                        if (x - mx > maxx || x - mx < -maxx ||
+                            y - my > maxy || y - my < -maxy)
+                            continue;
+
+                        // We have to calculate distances in pixels, not in
+                        // data units, because the scales of the axes may be different
+                        var dx = Math.abs(axisx.p2c(x) - mouseX),
+                            dy = Math.abs(axisy.p2c(y) - mouseY),
+                            dist = dx * dx + dy * dy; // we save the sqrt
+
+                        // use <= to ensure last point takes precedence
+                        // (last generally means on top of)
+                        if (dist < smallestDistance) {
+                            smallestDistance = dist;
+                            item = [i, j / ps];
+                        }
+                    }
+                }
+                    
+                if (s.bars.show && !item) { // no other point can be nearby
+                    var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
+                        barRight = barLeft + s.bars.barWidth;
+                    
+                    for (j = 0; j < points.length; j += ps) {
+                        var x = points[j], y = points[j + 1], b = points[j + 2];
+                        if (x == null)
+                            continue;
+  
+                        // for a bar graph, the cursor must be inside the bar
+                        if (series[i].bars.horizontal ? 
+                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) && 
+                             my >= y + barLeft && my <= y + barRight) :
+                            (mx >= x + barLeft && mx <= x + barRight &&
+                             my >= Math.min(b, y) && my <= Math.max(b, y)))
+                                item = [i, j / ps];
+                    }
+                }
+            }
+
+            if (item) {
+                i = item[0];
+                j = item[1];
+                ps = series[i].datapoints.pointsize;
+                
+                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
+                         dataIndex: j,
+                         series: series[i],
+                         seriesIndex: i };
+            }
+            
+            return null;
+        }
+
+        function onMouseMove(e) {
+            if (options.grid.hoverable)
+                triggerClickHoverEvent("plothover", e,
+                                       function (s) { return s["hoverable"] != false; });
+        }
+
+        function onMouseLeave(e) {
+            if (options.grid.hoverable)
+                triggerClickHoverEvent("plothover", e,
+                                       function (s) { return false; });
+        }
+
+        function onClick(e) {
+            triggerClickHoverEvent("plotclick", e,
+                                   function (s) { return s["clickable"] != false; });
+        }
+
+        // trigger click or hover event (they send the same parameters
+        // so we share their code)
+        function triggerClickHoverEvent(eventname, event, seriesFilter) {
+            var offset = eventHolder.offset(),
+                canvasX = event.pageX - offset.left - plotOffset.left,
+                canvasY = event.pageY - offset.top - plotOffset.top,
+            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
+
+            pos.pageX = event.pageX;
+            pos.pageY = event.pageY;
+
+            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
+
+            if (item) {
+                // fill in mouse pos for any listeners out there
+                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
+                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
+            }
+
+            if (options.grid.autoHighlight) {
+                // clear auto-highlights
+                for (var i = 0; i < highlights.length; ++i) {
+                    var h = highlights[i];
+                    if (h.auto == eventname &&
+                        !(item && h.series == item.series &&
+                          h.point[0] == item.datapoint[0] &&
+                          h.point[1] == item.datapoint[1]))
+                        unhighlight(h.series, h.point);
+                }
+                
+                if (item)
+                    highlight(item.series, item.datapoint, eventname);
+            }
+            
+            placeholder.trigger(eventname, [ pos, item ]);
+        }
+
+        function triggerRedrawOverlay() {
+            if (!redrawTimeout)
+                redrawTimeout = setTimeout(drawOverlay, 30);
+        }
+
+        function drawOverlay() {
+            redrawTimeout = null;
+
+            // draw highlights
+            octx.save();
+            octx.clearRect(0, 0, canvasWidth, canvasHeight);
+            octx.translate(plotOffset.left, plotOffset.top);
+            
+            var i, hi;
+            for (i = 0; i < highlights.length; ++i) {
+                hi = highlights[i];
+
+                if (hi.series.bars.show)
+                    drawBarHighlight(hi.series, hi.point);
+                else
+                    drawPointHighlight(hi.series, hi.point);
+            }
+            octx.restore();
+            
+            executeHooks(hooks.drawOverlay, [octx]);
+        }
+        
+        function highlight(s, point, auto) {
+            if (typeof s == "number")
+                s = series[s];
+
+            if (typeof point == "number") {
+                var ps = s.datapoints.pointsize;
+                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
+            }
+
+            var i = indexOfHighlight(s, point);
+            if (i == -1) {
+                highlights.push({ series: s, point: point, auto: auto });
+
+                triggerRedrawOverlay();
+            }
+            else if (!auto)
+                highlights[i].auto = false;
+        }
+            
+        function unhighlight(s, point) {
+            if (s == null && point == null) {
+                highlights = [];
+                triggerRedrawOverlay();
+            }
+            
+            if (typeof s == "number")
+                s = series[s];
+
+            if (typeof point == "number")
+                point = s.data[point];
+
+            var i = indexOfHighlight(s, point);
+            if (i != -1) {
+                highlights.splice(i, 1);
+
+                triggerRedrawOverlay();
+            }
+        }
+        
+        function indexOfHighlight(s, p) {
+            for (var i = 0; i < highlights.length; ++i) {
+                var h = highlights[i];
+                if (h.series == s && h.point[0] == p[0]
+                    && h.point[1] == p[1])
+                    return i;
+            }
+            return -1;
+        }
+        
+        function drawPointHighlight(series, point) {
+            var x = point[0], y = point[1],
+                axisx = series.xaxis, axisy = series.yaxis;
+            
+            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+                return;
+            
+            var pointRadius = series.points.radius + series.points.lineWidth / 2;
+            octx.lineWidth = pointRadius;
+            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
+            var radius = 1.5 * pointRadius,
+                x = axisx.p2c(x),
+                y = axisy.p2c(y);
+            
+            octx.beginPath();
+            if (series.points.symbol == "circle")
+                octx.arc(x, y, radius, 0, 2 * Math.PI, false);
+            else
+                series.points.symbol(octx, x, y, radius, false);
+            octx.closePath();
+            octx.stroke();
+        }
+
+        function drawBarHighlight(series, point) {
+            octx.lineWidth = series.bars.lineWidth;
+            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
+            var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString();
+            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
+                    0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
+        }
+
+        function getColorOrGradient(spec, bottom, top, defaultColor) {
+            if (typeof spec == "string")
+                return spec;
+            else {
+                // assume this is a gradient spec; IE currently only
+                // supports a simple vertical gradient properly, so that's
+                // what we support too
+                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
+                
+                for (var i = 0, l = spec.colors.length; i < l; ++i) {
+                    var c = spec.colors[i];
+                    if (typeof c != "string") {
+                        var co = $.color.parse(defaultColor);
+                        if (c.brightness != null)
+                            co = co.scale('rgb', c.brightness)
+                        if (c.opacity != null)
+                            co.a *= c.opacity;
+                        c = co.toString();
+                    }
+                    gradient.addColorStop(i / (l - 1), c);
+                }
+                
+                return gradient;
+            }
+        }
+    }
+
+    $.plot = function(placeholder, data, options) {
+        //var t0 = new Date();
+        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
+        //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
+        return plot;
+    };
+
+    $.plot.version = "0.7";
+    
+    $.plot.plugins = [];
+
+    // returns a string with the date d formatted according to fmt
+    $.plot.formatDate = function(d, fmt, monthNames) {
+        var leftPad = function(n) {
+            n = "" + n;
+            return n.length == 1 ? "0" + n : n;
+        };
+        
+        var r = [];
+        var escape = false, padNext = false;
+        var hours = d.getUTCHours();
+        var isAM = hours < 12;
+        if (monthNames == null)
+            monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+
+        if (fmt.search(/%p|%P/) != -1) {
+            if (hours > 12) {
+                hours = hours - 12;
+            } else if (hours == 0) {
+                hours = 12;
+            }
+        }
+        for (var i = 0; i < fmt.length; ++i) {
+            var c = fmt.charAt(i);
+            
+            if (escape) {
+                switch (c) {
+                case 'h': c = "" + hours; break;
+                case 'H': c = leftPad(hours); break;
+                case 'M': c = leftPad(d.getUTCMinutes()); break;
+                case 'S': c = leftPad(d.getUTCSeconds()); break;
+                case 'd': c = "" + d.getUTCDate(); break;
+                case 'm': c = "" + (d.getUTCMonth() + 1); break;
+                case 'y': c = "" + d.getUTCFullYear(); break;
+                case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
+                case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
+                case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
+                case '0': c = ""; padNext = true; break;
+                }
+                if (c && padNext) {
+                    c = leftPad(c);
+                    padNext = false;
+                }
+                r.push(c);
+                if (!padNext)
+                    escape = false;
+            }
+            else {
+                if (c == "%")
+                    escape = true;
+                else
+                    r.push(c);
+            }
+        }
+        return r.join("");
+    };
+    
+    // round to nearby lower multiple of base
+    function floorInBase(n, base) {
+        return base * Math.floor(n / base);
+    }
+    
+})(jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.pie.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.pie.js
new file mode 100644 (file)
index 0000000..b46c03c
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+Flot plugin for rendering pie charts. The plugin assumes the data is 
+coming is as a single data value for each series, and each of those 
+values is a positive value or zero (negative numbers don't make 
+any sense and will cause strange effects). The data values do 
+NOT need to be passed in as percentage values because it 
+internally calculates the total and percentages.
+
+* Created by Brian Medendorp, June 2009
+* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
+
+* Changes:
+       2009-10-22: lineJoin set to round
+       2009-10-23: IE full circle fix, donut
+       2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
+       2009-11-17: Added IE hover capability submitted by Anthony Aragues
+       2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
+               
+
+Available options are:
+series: {
+       pie: {
+               show: true/false
+               radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
+               innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
+               startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
+               tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
+               offset: {
+                       top: integer value to move the pie up or down
+                       left: integer value to move the pie left or right, or 'auto'
+               },
+               stroke: {
+                       color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
+                       width: integer pixel width of the stroke
+               },
+               label: {
+                       show: true/false, or 'auto'
+                       formatter:  a user-defined function that modifies the text/style of the label text
+                       radius: 0-1 for percentage of fullsize, or a specified pixel length
+                       background: {
+                               color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
+                               opacity: 0-1
+                       },
+                       threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
+               },
+               combine: {
+                       threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
+                       color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
+                       label: any text value of what the combined slice should be labeled
+               }
+               highlight: {
+                       opacity: 0-1
+               }
+       }
+}
+
+More detail and specific examples can be found in the included HTML file.
+
+*/
+
+(function ($) 
+{
+       function init(plot) // this is the "body" of the plugin
+       {
+               var canvas = null;
+               var target = null;
+               var maxRadius = null;
+               var centerLeft = null;
+               var centerTop = null;
+               var total = 0;
+               var redraw = true;
+               var redrawAttempts = 10;
+               var shrink = 0.95;
+               var legendWidth = 0;
+               var processed = false;
+               var raw = false;
+               
+               // interactive variables        
+               var highlights = [];    
+       
+               // add hook to determine if pie plugin in enabled, and then perform necessary operations
+               plot.hooks.processOptions.push(checkPieEnabled);
+               plot.hooks.bindEvents.push(bindEvents); 
+
+               // check to see if the pie plugin is enabled
+               function checkPieEnabled(plot, options)
+               {
+                       if (options.series.pie.show)
+                       {
+                               //disable grid
+                               options.grid.show = false;
+                               
+                               // set labels.show
+                               if (options.series.pie.label.show=='auto')
+                                       if (options.legend.show)
+                                               options.series.pie.label.show = false;
+                                       else
+                                               options.series.pie.label.show = true;
+                               
+                               // set radius
+                               if (options.series.pie.radius=='auto')
+                                       if (options.series.pie.label.show)
+                                               options.series.pie.radius = 3/4;
+                                       else
+                                               options.series.pie.radius = 1;
+                                               
+                               // ensure sane tilt
+                               if (options.series.pie.tilt>1)
+                                       options.series.pie.tilt=1;
+                               if (options.series.pie.tilt<0)
+                                       options.series.pie.tilt=0;
+                       
+                               // add processData hook to do transformations on the data
+                               plot.hooks.processDatapoints.push(processDatapoints);
+                               plot.hooks.drawOverlay.push(drawOverlay);       
+                               
+                               // add draw hook
+                               plot.hooks.draw.push(draw);
+                       }
+               }
+       
+               // bind hoverable events
+               function bindEvents(plot, eventHolder)          
+               {               
+                       var options = plot.getOptions();
+                       
+                       if (options.series.pie.show && options.grid.hoverable)
+                               eventHolder.unbind('mousemove').mousemove(onMouseMove);
+                               
+                       if (options.series.pie.show && options.grid.clickable)
+                               eventHolder.unbind('click').click(onClick);
+               }       
+               
+
+               // debugging function that prints out an object
+               function alertObject(obj)
+               {
+                       var msg = '';
+                       function traverse(obj, depth)
+                       {
+                               if (!depth)
+                                       depth = 0;
+                               for (var i = 0; i < obj.length; ++i)
+                               {
+                                       for (var j=0; j<depth; j++)
+                                               msg += '\t';
+                               
+                                       if( typeof obj[i] == "object")
+                                       {       // its an object
+                                               msg += ''+i+':\n';
+                                               traverse(obj[i], depth+1);
+                                       }
+                                       else
+                                       {       // its a value
+                                               msg += ''+i+': '+obj[i]+'\n';
+                                       }
+                               }
+                       }
+                       traverse(obj);
+                       alert(msg);
+               }
+               
+               function calcTotal(data)
+               {
+                       for (var i = 0; i < data.length; ++i)
+                       {
+                               var item = parseFloat(data[i].data[0][1]);
+                               if (item)
+                                       total += item;
+                       }
+               }       
+               
+               function processDatapoints(plot, series, data, datapoints) 
+               {       
+                       if (!processed)
+                       {
+                               processed = true;
+                       
+                               canvas = plot.getCanvas();
+                               target = $(canvas).parent();
+                               options = plot.getOptions();
+                       
+                               plot.setData(combine(plot.getData()));
+                       }
+               }
+               
+               function setupPie()
+               {
+                       legendWidth = target.children().filter('.legend').children().width();
+               
+                       // calculate maximum radius and center point
+                       maxRadius =  Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
+                       centerTop = (canvas.height/2)+options.series.pie.offset.top;
+                       centerLeft = (canvas.width/2);
+                       
+                       if (options.series.pie.offset.left=='auto')
+                               if (options.legend.position.match('w'))
+                                       centerLeft += legendWidth/2;
+                               else
+                                       centerLeft -= legendWidth/2;
+                       else
+                               centerLeft += options.series.pie.offset.left;
+                                       
+                       if (centerLeft<maxRadius)
+                               centerLeft = maxRadius;
+                       else if (centerLeft>canvas.width-maxRadius)
+                               centerLeft = canvas.width-maxRadius;
+               }
+               
+               function fixData(data)
+               {
+                       for (var i = 0; i < data.length; ++i)
+                       {
+                               if (typeof(data[i].data)=='number')
+                                       data[i].data = [[1,data[i].data]];
+                               else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
+                               {
+                                       if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
+                                               data[i].label = data[i].data.label; // fix weirdness coming from flot
+                                       data[i].data = [[1,0]];
+                                       
+                               }
+                       }
+                       return data;
+               }
+               
+               function combine(data)
+               {
+                       data = fixData(data);
+                       calcTotal(data);
+                       var combined = 0;
+                       var numCombined = 0;
+                       var color = options.series.pie.combine.color;
+                       
+                       var newdata = [];
+                       for (var i = 0; i < data.length; ++i)
+                       {
+                               // make sure its a number
+                               data[i].data[0][1] = parseFloat(data[i].data[0][1]);
+                               if (!data[i].data[0][1])
+                                       data[i].data[0][1] = 0;
+                                       
+                               if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
+                               {
+                                       combined += data[i].data[0][1];
+                                       numCombined++;
+                                       if (!color)
+                                               color = data[i].color;
+                               }                               
+                               else
+                               {
+                                       newdata.push({
+                                               data: [[1,data[i].data[0][1]]], 
+                                               color: data[i].color, 
+                                               label: data[i].label,
+                                               angle: (data[i].data[0][1]*(Math.PI*2))/total,
+                                               percent: (data[i].data[0][1]/total*100)
+                                       });
+                               }
+                       }
+                       if (numCombined>0)
+                               newdata.push({
+                                       data: [[1,combined]], 
+                                       color: color, 
+                                       label: options.series.pie.combine.label,
+                                       angle: (combined*(Math.PI*2))/total,
+                                       percent: (combined/total*100)
+                               });
+                       return newdata;
+               }               
+               
+               function draw(plot, newCtx)
+               {
+                       if (!target) return; // if no series were passed
+                       ctx = newCtx;
+               
+                       setupPie();
+                       var slices = plot.getData();
+               
+                       var attempts = 0;
+                       while (redraw && attempts<redrawAttempts)
+                       {
+                               redraw = false;
+                               if (attempts>0)
+                                       maxRadius *= shrink;
+                               attempts += 1;
+                               clear();
+                               if (options.series.pie.tilt<=0.8)
+                                       drawShadow();
+                               drawPie();
+                       }
+                       if (attempts >= redrawAttempts) {
+                               clear();
+                               target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
+                       }
+                       
+                       if ( plot.setSeries && plot.insertLegend )
+                       {
+                               plot.setSeries(slices);
+                               plot.insertLegend();
+                       }
+                       
+                       // we're actually done at this point, just defining internal functions at this point
+                       
+                       function clear()
+                       {
+                               ctx.clearRect(0,0,canvas.width,canvas.height);
+                               target.children().filter('.pieLabel, .pieLabelBackground').remove();
+                       }
+                       
+                       function drawShadow()
+                       {
+                               var shadowLeft = 5;
+                               var shadowTop = 15;
+                               var edge = 10;
+                               var alpha = 0.02;
+                       
+                               // set radius
+                               if (options.series.pie.radius>1)
+                                       var radius = options.series.pie.radius;
+                               else
+                                       var radius = maxRadius * options.series.pie.radius;
+                                       
+                               if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
+                                       return; // shadow would be outside canvas, so don't draw it
+                       
+                               ctx.save();
+                               ctx.translate(shadowLeft,shadowTop);
+                               ctx.globalAlpha = alpha;
+                               ctx.fillStyle = '#000';
+
+                               // center and rotate to starting position
+                               ctx.translate(centerLeft,centerTop);
+                               ctx.scale(1, options.series.pie.tilt);
+                               
+                               //radius -= edge;
+                               for (var i=1; i<=edge; i++)
+                               {
+                                       ctx.beginPath();
+                                       ctx.arc(0,0,radius,0,Math.PI*2,false);
+                                       ctx.fill();
+                                       radius -= i;
+                               }       
+                               
+                               ctx.restore();
+                       }
+                       
+                       function drawPie()
+                       {
+                               startAngle = Math.PI*options.series.pie.startAngle;
+                               
+                               // set radius
+                               if (options.series.pie.radius>1)
+                                       var radius = options.series.pie.radius;
+                               else
+                                       var radius = maxRadius * options.series.pie.radius;
+                               
+                               // center and rotate to starting position
+                               ctx.save();
+                               ctx.translate(centerLeft,centerTop);
+                               ctx.scale(1, options.series.pie.tilt);
+                               //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
+                               
+                               // draw slices
+                               ctx.save();
+                               var currentAngle = startAngle;
+                               for (var i = 0; i < slices.length; ++i)
+                               {
+                                       slices[i].startAngle = currentAngle;
+                                       drawSlice(slices[i].angle, slices[i].color, true);
+                               }
+                               ctx.restore();
+                               
+                               // draw slice outlines
+                               ctx.save();
+                               ctx.lineWidth = options.series.pie.stroke.width;
+                               currentAngle = startAngle;
+                               for (var i = 0; i < slices.length; ++i)
+                                       drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
+                               ctx.restore();
+                                       
+                               // draw donut hole
+                               drawDonutHole(ctx);
+                               
+                               // draw labels
+                               if (options.series.pie.label.show)
+                                       drawLabels();
+                               
+                               // restore to original state
+                               ctx.restore();
+                               
+                               function drawSlice(angle, color, fill)
+                               {       
+                                       if (angle<=0)
+                                               return;
+                               
+                                       if (fill)
+                                               ctx.fillStyle = color;
+                                       else
+                                       {
+                                               ctx.strokeStyle = color;
+                                               ctx.lineJoin = 'round';
+                                       }
+                                               
+                                       ctx.beginPath();
+                                       if (Math.abs(angle - Math.PI*2) > 0.000000001)
+                                               ctx.moveTo(0,0); // Center of the pie
+                                       else if ($.browser.msie)
+                                               angle -= 0.0001;
+                                       //ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
+                                       ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
+                                       ctx.closePath();
+                                       //ctx.rotate(angle); // This doesn't work properly in Opera
+                                       currentAngle += angle;
+                                       
+                                       if (fill)
+                                               ctx.fill();
+                                       else
+                                               ctx.stroke();
+                               }
+                               
+                               function drawLabels()
+                               {
+                                       var currentAngle = startAngle;
+                                       
+                                       // set radius
+                                       if (options.series.pie.label.radius>1)
+                                               var radius = options.series.pie.label.radius;
+                                       else
+                                               var radius = maxRadius * options.series.pie.label.radius;
+                                       
+                                       for (var i = 0; i < slices.length; ++i)
+                                       {
+                                               if (slices[i].percent >= options.series.pie.label.threshold*100)
+                                                       drawLabel(slices[i], currentAngle, i);
+                                               currentAngle += slices[i].angle;
+                                       }
+                                       
+                                       function drawLabel(slice, startAngle, index)
+                                       {
+                                               if (slice.data[0][1]==0)
+                                                       return;
+                                                       
+                                               // format label text
+                                               var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
+                                               if (lf)
+                                                       text = lf(slice.label, slice);
+                                               else
+                                                       text = slice.label;
+                                               if (plf)
+                                                       text = plf(text, slice);
+                                                       
+                                               var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
+                                               var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
+                                               var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
+                                               
+                                               var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
+                                               target.append(html);
+                                               var label = target.children('#pieLabel'+index);
+                                               var labelTop = (y - label.height()/2);
+                                               var labelLeft = (x - label.width()/2);
+                                               label.css('top', labelTop);
+                                               label.css('left', labelLeft);
+                                               
+                                               // check to make sure that the label is not outside the canvas
+                                               if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
+                                                       redraw = true;
+                                               
+                                               if (options.series.pie.label.background.opacity != 0) {
+                                                       // put in the transparent background separately to avoid blended labels and label boxes
+                                                       var c = options.series.pie.label.background.color;
+                                                       if (c == null) {
+                                                               c = slice.color;
+                                                       }
+                                                       var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
+                                                       $('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
+                                               }
+                                       } // end individual label function
+                               } // end drawLabels function
+                       } // end drawPie function
+               } // end draw function
+               
+               // Placed here because it needs to be accessed from multiple locations 
+               function drawDonutHole(layer)
+               {
+                       // draw donut hole
+                       if(options.series.pie.innerRadius > 0)
+                       {
+                               // subtract the center
+                               layer.save();
+                               innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
+                               layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
+                               layer.beginPath();
+                               layer.fillStyle = options.series.pie.stroke.color;
+                               layer.arc(0,0,innerRadius,0,Math.PI*2,false);
+                               layer.fill();
+                               layer.closePath();
+                               layer.restore();
+                               
+                               // add inner stroke
+                               layer.save();
+                               layer.beginPath();
+                               layer.strokeStyle = options.series.pie.stroke.color;
+                               layer.arc(0,0,innerRadius,0,Math.PI*2,false);
+                               layer.stroke();
+                               layer.closePath();
+                               layer.restore();
+                               // TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
+                       }
+               }
+               
+               //-- Additional Interactive related functions --
+               
+               function isPointInPoly(poly, pt)
+               {
+                       for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
+                               ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
+                               && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
+                               && (c = !c);
+                       return c;
+               }
+               
+               function findNearbySlice(mouseX, mouseY)
+               {
+                       var slices = plot.getData(),
+                               options = plot.getOptions(),
+                               radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+                       
+                       for (var i = 0; i < slices.length; ++i) 
+                       {
+                               var s = slices[i];      
+                               
+                               if(s.pie.show)
+                               {
+                                       ctx.save();
+                                       ctx.beginPath();
+                                       ctx.moveTo(0,0); // Center of the pie
+                                       //ctx.scale(1, options.series.pie.tilt);        // this actually seems to break everything when here.
+                                       ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
+                                       ctx.closePath();
+                                       x = mouseX-centerLeft;
+                                       y = mouseY-centerTop;
+                                       if(ctx.isPointInPath)
+                                       {
+                                               if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
+                                               {
+                                                       //alert('found slice!');
+                                                       ctx.restore();
+                                                       return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
+                                               }
+                                       }
+                                       else
+                                       {
+                                               // excanvas for IE doesn;t support isPointInPath, this is a workaround. 
+                                               p1X = (radius * Math.cos(s.startAngle));
+                                               p1Y = (radius * Math.sin(s.startAngle));
+                                               p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
+                                               p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
+                                               p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
+                                               p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
+                                               p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
+                                               p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
+                                               p5X = (radius * Math.cos(s.startAngle+s.angle));
+                                               p5Y = (radius * Math.sin(s.startAngle+s.angle));
+                                               arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
+                                               arrPoint = [x,y];
+                                               // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
+                                               if(isPointInPoly(arrPoly, arrPoint))
+                                               {
+                                                       ctx.restore();
+                                                       return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
+                                               }                       
+                                       }
+                                       ctx.restore();
+                               }
+                       }
+                       
+                       return null;
+               }
+
+               function onMouseMove(e) 
+               {
+                       triggerClickHoverEvent('plothover', e);
+               }
+               
+        function onClick(e) 
+               {
+                       triggerClickHoverEvent('plotclick', e);
+        }
+
+               // trigger click or hover event (they send the same parameters so we share their code)
+               function triggerClickHoverEvent(eventname, e) 
+               {
+                       var offset = plot.offset(),
+                               canvasX = parseInt(e.pageX - offset.left),
+                               canvasY =  parseInt(e.pageY - offset.top),
+                               item = findNearbySlice(canvasX, canvasY);
+                       
+                       if (options.grid.autoHighlight) 
+                       {
+                               // clear auto-highlights
+                               for (var i = 0; i < highlights.length; ++i) 
+                               {
+                                       var h = highlights[i];
+                                       if (h.auto == eventname && !(item && h.series == item.series))
+                                               unhighlight(h.series);
+                               }
+                       }
+                       
+                       // highlight the slice
+                       if (item) 
+                           highlight(item.series, eventname);
+                               
+                       // trigger any hover bind events
+                       var pos = { pageX: e.pageX, pageY: e.pageY };
+                       target.trigger(eventname, [ pos, item ]);       
+               }
+
+               function highlight(s, auto) 
+               {
+                       if (typeof s == "number")
+                               s = series[s];
+
+                       var i = indexOfHighlight(s);
+                       if (i == -1) 
+                       {
+                               highlights.push({ series: s, auto: auto });
+                               plot.triggerRedrawOverlay();
+                       }
+                       else if (!auto)
+                               highlights[i].auto = false;
+               }
+
+               function unhighlight(s) 
+               {
+                       if (s == null) 
+                       {
+                               highlights = [];
+                               plot.triggerRedrawOverlay();
+                       }
+                       
+                       if (typeof s == "number")
+                               s = series[s];
+
+                       var i = indexOfHighlight(s);
+                       if (i != -1) 
+                       {
+                               highlights.splice(i, 1);
+                               plot.triggerRedrawOverlay();
+                       }
+               }
+
+               function indexOfHighlight(s) 
+               {
+                       for (var i = 0; i < highlights.length; ++i) 
+                       {
+                               var h = highlights[i];
+                               if (h.series == s)
+                                       return i;
+                       }
+                       return -1;
+               }
+
+               function drawOverlay(plot, octx) 
+               {
+                       //alert(options.series.pie.radius);
+                       var options = plot.getOptions();
+                       //alert(options.series.pie.radius);
+                       
+                       var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+                       octx.save();
+                       octx.translate(centerLeft, centerTop);
+                       octx.scale(1, options.series.pie.tilt);
+                       
+                       for (i = 0; i < highlights.length; ++i) 
+                               drawHighlight(highlights[i].series);
+                       
+                       drawDonutHole(octx);
+
+                       octx.restore();
+
+                       function drawHighlight(series) 
+                       {
+                               if (series.angle < 0) return;
+                               
+                               //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
+                               octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
+                               
+                               octx.beginPath();
+                               if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
+                                       octx.moveTo(0,0); // Center of the pie
+                               octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
+                               octx.closePath();
+                               octx.fill();
+                       }
+                       
+               }       
+               
+       } // end init (plugin body)
+       
+       // define pie specific options and their default values
+       var options = {
+               series: {
+                       pie: {
+                               show: false,
+                               radius: 'auto', // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
+                               innerRadius:0, /* for donut */
+                               startAngle: 3/2,
+                               tilt: 1,
+                               offset: {
+                                       top: 0,
+                                       left: 'auto'
+                               },
+                               stroke: {
+                                       color: '#FFF',
+                                       width: 1
+                               },
+                               label: {
+                                       show: 'auto',
+                                       formatter: function(label, slice){
+                                               return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
+                                       },      // formatter function
+                                       radius: 1,      // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
+                                       background: {
+                                               color: null,
+                                               opacity: 0
+                                       },
+                                       threshold: 0    // percentage at which to hide the label (i.e. the slice is too narrow)
+                               },
+                               combine: {
+                                       threshold: -1,  // percentage at which to combine little slices into one larger slice
+                                       color: null,    // color to give the new slice (auto-generated if null)
+                                       label: 'Other'  // label to give the new slice
+                               },
+                               highlight: {
+                                       //color: '#FFF',                // will add this functionality once parseColor is available
+                                       opacity: 0.5
+                               }
+                       }
+               }
+       };
+    
+       $.plot.plugins.push({
+               init: init,
+               options: options,
+               name: "pie",
+               version: "1.0"
+       });
+})(jQuery);
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.resize.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.resize.js
new file mode 100644 (file)
index 0000000..1178425
--- /dev/null
@@ -0,0 +1,60 @@
+/* Flot plugin for automatically redrawing plots as the placeholder resizes.
+
+Copyright (c) 2007-2013 IOLA and Ole Laursen.
+Licensed under the MIT license.
+
+It works by listening for changes on the placeholder div (through the jQuery
+resize event plugin) - if the size changes, it will redraw the plot.
+
+There are no options. If you need to disable the plugin for some plots, you
+can just fix the size of their placeholders.
+
+*/
+
+/* Inline dependency:
+ * jQuery resize event - v1.1 - 3/14/2010
+ * http://benalman.com/projects/jquery-resize-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
+
+(function ($) {
+    var options = { }; // no options
+
+    function init(plot) {
+        function onResize() {
+            var placeholder = plot.getPlaceholder();
+
+            // somebody might have hidden us and we can't plot
+            // when we don't have the dimensions
+            if (placeholder.width() == 0 || placeholder.height() == 0)
+                return;
+
+            plot.resize();
+            plot.setupGrid();
+            plot.draw();
+        }
+        
+        function bindEvents(plot, eventHolder) {
+            plot.getPlaceholder().resize(onResize);
+        }
+
+        function shutdown(plot, eventHolder) {
+            plot.getPlaceholder().unbind("resize", onResize);
+        }
+        
+        plot.hooks.bindEvents.push(bindEvents);
+        plot.hooks.shutdown.push(shutdown);
+    }
+    
+    $.plot.plugins.push({
+        init: init,
+        options: options,
+        name: 'resize',
+        version: '1.0'
+    });
+})(jQuery);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.tooltip.min.js b/src/main/resources/META-INF/resources/designer/lib/plugins/flot/jquery.flot.tooltip.min.js
new file mode 100644 (file)
index 0000000..09e3bbf
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * jquery.flot.tooltip
+ * 
+ * description: easy-to-use tooltips for Flot charts
+ * version: 0.6.2
+ * author: Krzysztof Urbas @krzysu [myviews.pl]
+ * website: https://github.com/krzysu/flot.tooltip
+ * 
+ * build on 2013-09-30
+ * released under MIT License, 2012
+*/ 
+(function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("<div />").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris-data.js b/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris-data.js
new file mode 100644 (file)
index 0000000..e5e23f6
--- /dev/null
@@ -0,0 +1,117 @@
+$(function() {
+
+    Morris.Area({
+        element: 'morris-area-chart',
+        data: [{
+            period: '2010 Q1',
+            iphone: 2666,
+            ipad: null,
+            itouch: 2647
+        }, {
+            period: '2010 Q2',
+            iphone: 2778,
+            ipad: 2294,
+            itouch: 2441
+        }, {
+            period: '2010 Q3',
+            iphone: 4912,
+            ipad: 1969,
+            itouch: 2501
+        }, {
+            period: '2010 Q4',
+            iphone: 3767,
+            ipad: 3597,
+            itouch: 5689
+        }, {
+            period: '2011 Q1',
+            iphone: 6810,
+            ipad: 1914,
+            itouch: 2293
+        }, {
+            period: '2011 Q2',
+            iphone: 5670,
+            ipad: 4293,
+            itouch: 1881
+        }, {
+            period: '2011 Q3',
+            iphone: 4820,
+            ipad: 3795,
+            itouch: 1588
+        }, {
+            period: '2011 Q4',
+            iphone: 15073,
+            ipad: 5967,
+            itouch: 5175
+        }, {
+            period: '2012 Q1',
+            iphone: 10687,
+            ipad: 4460,
+            itouch: 2028
+        }, {
+            period: '2012 Q2',
+            iphone: 8432,
+            ipad: 5713,
+            itouch: 1791
+        }],
+        xkey: 'period',
+        ykeys: ['iphone', 'ipad', 'itouch'],
+        labels: ['iPhone', 'iPad', 'iPod Touch'],
+        pointSize: 2,
+        hideHover: 'auto',
+        resize: true
+    });
+
+    Morris.Donut({
+        element: 'morris-donut-chart',
+        data: [{
+            label: "Download Sales",
+            value: 12
+        }, {
+            label: "In-Store Sales",
+            value: 30
+        }, {
+            label: "Mail-Order Sales",
+            value: 20
+        }],
+        resize: true
+    });
+
+    Morris.Bar({
+        element: 'morris-bar-chart',
+        data: [{
+            y: '2006',
+            a: 100,
+            b: 90
+        }, {
+            y: '2007',
+            a: 75,
+            b: 65
+        }, {
+            y: '2008',
+            a: 50,
+            b: 40
+        }, {
+            y: '2009',
+            a: 75,
+            b: 65
+        }, {
+            y: '2010',
+            a: 50,
+            b: 40
+        }, {
+            y: '2011',
+            a: 75,
+            b: 65
+        }, {
+            y: '2012',
+            a: 100,
+            b: 90
+        }],
+        xkey: 'y',
+        ykeys: ['a', 'b'],
+        labels: ['Series A', 'Series B'],
+        hideHover: 'auto',
+        resize: true
+    });
+
+});
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.js b/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.js
new file mode 100644 (file)
index 0000000..35ad207
--- /dev/null
@@ -0,0 +1,2113 @@
+/* @license
+morris.js v0.5.1
+Copyright 2014 Olly Smith All rights reserved.
+Licensed under the BSD-2-Clause License.
+*/
+
+
+(function() {
+  var $, Morris, minutesSpecHelper, secondsSpecHelper,
+    __slice = [].slice,
+    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+    __hasProp = {}.hasOwnProperty,
+    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+  Morris = window.Morris = {};
+
+  $ = jQuery;
+
+  Morris.EventEmitter = (function() {
+    function EventEmitter() {}
+
+    EventEmitter.prototype.on = function(name, handler) {
+      if (this.handlers == null) {
+        this.handlers = {};
+      }
+      if (this.handlers[name] == null) {
+        this.handlers[name] = [];
+      }
+      this.handlers[name].push(handler);
+      return this;
+    };
+
+    EventEmitter.prototype.fire = function() {
+      var args, handler, name, _i, _len, _ref, _results;
+      name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+      if ((this.handlers != null) && (this.handlers[name] != null)) {
+        _ref = this.handlers[name];
+        _results = [];
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          handler = _ref[_i];
+          _results.push(handler.apply(null, args));
+        }
+        return _results;
+      }
+    };
+
+    return EventEmitter;
+
+  })();
+
+  Morris.commas = function(num) {
+    var absnum, intnum, ret, strabsnum;
+    if (num != null) {
+      ret = num < 0 ? "-" : "";
+      absnum = Math.abs(num);
+      intnum = Math.floor(absnum).toFixed(0);
+      ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
+      strabsnum = absnum.toString();
+      if (strabsnum.length > intnum.length) {
+        ret += strabsnum.slice(intnum.length);
+      }
+      return ret;
+    } else {
+      return '-';
+    }
+  };
+
+  Morris.pad2 = function(number) {
+    return (number < 10 ? '0' : '') + number;
+  };
+
+  Morris.Grid = (function(_super) {
+    __extends(Grid, _super);
+
+    function Grid(options) {
+      this.hasToShow = __bind(this.hasToShow, this);
+      this.resizeHandler = __bind(this.resizeHandler, this);
+      var _this = this;
+      if (typeof options.element === 'string') {
+        this.el = $(document.getElementById(options.element));
+      } else {
+        this.el = $(options.element);
+      }
+      if ((this.el == null) || this.el.length === 0) {
+        throw new Error("Graph container element not found");
+      }
+      if (this.el.css('position') === 'static') {
+        this.el.css('position', 'relative');
+      }
+      this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);
+      if (typeof this.options.units === 'string') {
+        this.options.postUnits = options.units;
+      }
+      this.raphael = new Raphael(this.el[0]);
+      this.elementWidth = null;
+      this.elementHeight = null;
+      this.dirty = false;
+      this.selectFrom = null;
+      if (this.init) {
+        this.init();
+      }
+      this.setData(this.options.data);
+      this.el.bind('mousemove', function(evt) {
+        var left, offset, right, width, x;
+        offset = _this.el.offset();
+        x = evt.pageX - offset.left;
+        if (_this.selectFrom) {
+          left = _this.data[_this.hitTest(Math.min(x, _this.selectFrom))]._x;
+          right = _this.data[_this.hitTest(Math.max(x, _this.selectFrom))]._x;
+          width = right - left;
+          return _this.selectionRect.attr({
+            x: left,
+            width: width
+          });
+        } else {
+          return _this.fire('hovermove', x, evt.pageY - offset.top);
+        }
+      });
+      this.el.bind('mouseleave', function(evt) {
+        if (_this.selectFrom) {
+          _this.selectionRect.hide();
+          _this.selectFrom = null;
+        }
+        return _this.fire('hoverout');
+      });
+      this.el.bind('touchstart touchmove touchend', function(evt) {
+        var offset, touch;
+        touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];
+        offset = _this.el.offset();
+        return _this.fire('hovermove', touch.pageX - offset.left, touch.pageY - offset.top);
+      });
+      this.el.bind('click', function(evt) {
+        var offset;
+        offset = _this.el.offset();
+        return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);
+      });
+      if (this.options.rangeSelect) {
+        this.selectionRect = this.raphael.rect(0, 0, 0, this.el.innerHeight()).attr({
+          fill: this.options.rangeSelectColor,
+          stroke: false
+        }).toBack().hide();
+        this.el.bind('mousedown', function(evt) {
+          var offset;
+          offset = _this.el.offset();
+          return _this.startRange(evt.pageX - offset.left);
+        });
+        this.el.bind('mouseup', function(evt) {
+          var offset;
+          offset = _this.el.offset();
+          _this.endRange(evt.pageX - offset.left);
+          return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);
+        });
+      }
+      if (this.options.resize) {
+        $(window).bind('resize', function(evt) {
+          if (_this.timeoutId != null) {
+            window.clearTimeout(_this.timeoutId);
+          }
+          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);
+        });
+      }
+      this.el.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
+      if (this.postInit) {
+        this.postInit();
+      }
+    }
+
+    Grid.prototype.gridDefaults = {
+      dateFormat: null,
+      axes: true,
+      grid: true,
+      gridLineColor: '#aaa',
+      gridStrokeWidth: 0.5,
+      gridTextColor: '#888',
+      gridTextSize: 12,
+      gridTextFamily: 'sans-serif',
+      gridTextWeight: 'normal',
+      hideHover: false,
+      yLabelFormat: null,
+      xLabelAngle: 0,
+      numLines: 5,
+      padding: 25,
+      parseTime: true,
+      postUnits: '',
+      preUnits: '',
+      ymax: 'auto',
+      ymin: 'auto 0',
+      goals: [],
+      goalStrokeWidth: 1.0,
+      goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],
+      events: [],
+      eventStrokeWidth: 1.0,
+      eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502'],
+      rangeSelect: null,
+      rangeSelectColor: '#eef',
+      resize: false
+    };
+
+    Grid.prototype.setData = function(data, redraw) {
+      var e, flatEvents, from, idx, index, maxGoal, minGoal, ret, row, step, to, total, y, ykey, ymax, ymin, yval, _i, _len, _ref, _ref1;
+      if (redraw == null) {
+        redraw = true;
+      }
+      this.options.data = data;
+      if ((data == null) || data.length === 0) {
+        this.data = [];
+        this.raphael.clear();
+        if (this.hover != null) {
+          this.hover.hide();
+        }
+        return;
+      }
+      ymax = this.cumulative ? 0 : null;
+      ymin = this.cumulative ? 0 : null;
+      if (this.options.goals.length > 0) {
+        minGoal = Math.min.apply(Math, this.options.goals);
+        maxGoal = Math.max.apply(Math, this.options.goals);
+        ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;
+        ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;
+      }
+      this.data = (function() {
+        var _i, _len, _results;
+        _results = [];
+        for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {
+          row = data[index];
+          ret = {
+            src: row
+          };
+          ret.label = row[this.options.xkey];
+          if (this.options.parseTime) {
+            ret.x = Morris.parseDate(ret.label);
+            if (this.options.dateFormat) {
+              ret.label = this.options.dateFormat(ret.x);
+            } else if (typeof ret.label === 'number') {
+              ret.label = new Date(ret.label).toString();
+            }
+          } else {
+            ret.x = index;
+            if (this.options.xLabelFormat) {
+              ret.label = this.options.xLabelFormat(ret);
+            }
+          }
+          total = 0;
+          ret.y = (function() {
+            var _j, _len1, _ref, _results1;
+            _ref = this.options.ykeys;
+            _results1 = [];
+            for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {
+              ykey = _ref[idx];
+              yval = row[ykey];
+              if (typeof yval === 'string') {
+                yval = parseFloat(yval);
+              }
+              if ((yval != null) && typeof yval !== 'number') {
+                yval = null;
+              }
+              if ((yval != null) && this.hasToShow(idx)) {
+                if (this.cumulative) {
+                  total += yval;
+                } else {
+                  if (ymax != null) {
+                    ymax = Math.max(yval, ymax);
+                    ymin = Math.min(yval, ymin);
+                  } else {
+                    ymax = ymin = yval;
+                  }
+                }
+              }
+              if (this.cumulative && (total != null)) {
+                ymax = Math.max(total, ymax);
+                ymin = Math.min(total, ymin);
+              }
+              _results1.push(yval);
+            }
+            return _results1;
+          }).call(this);
+          _results.push(ret);
+        }
+        return _results;
+      }).call(this);
+      if (this.options.parseTime) {
+        this.data = this.data.sort(function(a, b) {
+          return (a.x > b.x) - (b.x > a.x);
+        });
+      }
+      this.xmin = this.data[0].x;
+      this.xmax = this.data[this.data.length - 1].x;
+      this.events = [];
+      if (this.options.events.length > 0) {
+        if (this.options.parseTime) {
+          _ref = this.options.events;
+          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+            e = _ref[_i];
+            if (e instanceof Array) {
+              from = e[0], to = e[1];
+              this.events.push([Morris.parseDate(from), Morris.parseDate(to)]);
+            } else {
+              this.events.push(Morris.parseDate(e));
+            }
+          }
+        } else {
+          this.events = this.options.events;
+        }
+        flatEvents = $.map(this.events, function(e) {
+          return e;
+        });
+        this.xmax = Math.max(this.xmax, Math.max.apply(Math, flatEvents));
+        this.xmin = Math.min(this.xmin, Math.min.apply(Math, flatEvents));
+      }
+      if (this.xmin === this.xmax) {
+        this.xmin -= 1;
+        this.xmax += 1;
+      }
+      this.ymin = this.yboundary('min', ymin);
+      this.ymax = this.yboundary('max', ymax);
+      if (this.ymin === this.ymax) {
+        if (ymin) {
+          this.ymin -= 1;
+        }
+        this.ymax += 1;
+      }
+      if (((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'y') || this.options.grid === true) {
+        if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {
+          this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);
+          this.ymin = Math.min(this.ymin, this.grid[0]);
+          this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);
+        } else {
+          step = (this.ymax - this.ymin) / (this.options.numLines - 1);
+          this.grid = (function() {
+            var _j, _ref2, _ref3, _results;
+            _results = [];
+            for (y = _j = _ref2 = this.ymin, _ref3 = this.ymax; step > 0 ? _j <= _ref3 : _j >= _ref3; y = _j += step) {
+              _results.push(y);
+            }
+            return _results;
+          }).call(this);
+        }
+      }
+      this.dirty = true;
+      if (redraw) {
+        return this.redraw();
+      }
+    };
+
+    Grid.prototype.yboundary = function(boundaryType, currentValue) {
+      var boundaryOption, suggestedValue;
+      boundaryOption = this.options["y" + boundaryType];
+      if (typeof boundaryOption === 'string') {
+        if (boundaryOption.slice(0, 4) === 'auto') {
+          if (boundaryOption.length > 5) {
+            suggestedValue = parseInt(boundaryOption.slice(5), 10);
+            if (currentValue == null) {
+              return suggestedValue;
+            }
+            return Math[boundaryType](currentValue, suggestedValue);
+          } else {
+            if (currentValue != null) {
+              return currentValue;
+            } else {
+              return 0;
+            }
+          }
+        } else {
+          return parseInt(boundaryOption, 10);
+        }
+      } else {
+        return boundaryOption;
+      }
+    };
+
+    Grid.prototype.autoGridLines = function(ymin, ymax, nlines) {
+      var gmax, gmin, grid, smag, span, step, unit, y, ymag;
+      span = ymax - ymin;
+      ymag = Math.floor(Math.log(span) / Math.log(10));
+      unit = Math.pow(10, ymag);
+      gmin = Math.floor(ymin / unit) * unit;
+      gmax = Math.ceil(ymax / unit) * unit;
+      step = (gmax - gmin) / (nlines - 1);
+      if (unit === 1 && step > 1 && Math.ceil(step) !== step) {
+        step = Math.ceil(step);
+        gmax = gmin + step * (nlines - 1);
+      }
+      if (gmin < 0 && gmax > 0) {
+        gmin = Math.floor(ymin / step) * step;
+        gmax = Math.ceil(ymax / step) * step;
+      }
+      if (step < 1) {
+        smag = Math.floor(Math.log(step) / Math.log(10));
+        grid = (function() {
+          var _i, _results;
+          _results = [];
+          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {
+            _results.push(parseFloat(y.toFixed(1 - smag)));
+          }
+          return _results;
+        })();
+      } else {
+        grid = (function() {
+          var _i, _results;
+          _results = [];
+          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {
+            _results.push(y);
+          }
+          return _results;
+        })();
+      }
+      return grid;
+    };
+
+    Grid.prototype._calc = function() {
+      var angle, bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1;
+      w = this.el.width();
+      h = this.el.height();
+      if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {
+        this.elementWidth = w;
+        this.elementHeight = h;
+        this.dirty = false;
+        this.left = this.options.padding;
+        this.right = this.elementWidth - this.options.padding;
+        this.top = this.options.padding;
+        this.bottom = this.elementHeight - this.options.padding;
+        if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') {
+          yLabelWidths = (function() {
+            var _i, _len, _ref1, _results;
+            _ref1 = this.grid;
+            _results = [];
+            for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+              gridLine = _ref1[_i];
+              _results.push(this.measureText(this.yAxisFormat(gridLine)).width);
+            }
+            return _results;
+          }).call(this);
+          if (!this.options.horizontal) {
+            this.left += Math.max.apply(Math, yLabelWidths);
+          } else {
+            this.bottom -= Math.max.apply(Math, yLabelWidths);
+          }
+        }
+        if ((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'x') {
+          if (!this.options.horizontal) {
+            angle = -this.options.xLabelAngle;
+          } else {
+            angle = -90;
+          }
+          bottomOffsets = (function() {
+            var _i, _ref2, _results;
+            _results = [];
+            for (i = _i = 0, _ref2 = this.data.length; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) {
+              _results.push(this.measureText(this.data[i].label, angle).height);
+            }
+            return _results;
+          }).call(this);
+          if (!this.options.horizontal) {
+            this.bottom -= Math.max.apply(Math, bottomOffsets);
+          } else {
+            this.left += Math.max.apply(Math, bottomOffsets);
+          }
+        }
+        this.width = Math.max(1, this.right - this.left);
+        this.height = Math.max(1, this.bottom - this.top);
+        if (!this.options.horizontal) {
+          this.dx = this.width / (this.xmax - this.xmin);
+          this.dy = this.height / (this.ymax - this.ymin);
+          this.yStart = this.bottom;
+          this.yEnd = this.top;
+          this.xStart = this.left;
+          this.xEnd = this.right;
+          this.xSize = this.width;
+          this.ySize = this.height;
+        } else {
+          this.dx = this.height / (this.xmax - this.xmin);
+          this.dy = this.width / (this.ymax - this.ymin);
+          this.yStart = this.left;
+          this.yEnd = this.right;
+          this.xStart = this.top;
+          this.xEnd = this.bottom;
+          this.xSize = this.height;
+          this.ySize = this.width;
+        }
+        if (this.calc) {
+          return this.calc();
+        }
+      }
+    };
+
+    Grid.prototype.transY = function(y) {
+      if (!this.options.horizontal) {
+        return this.bottom - (y - this.ymin) * this.dy;
+      } else {
+        return this.left + (y - this.ymin) * this.dy;
+      }
+    };
+
+    Grid.prototype.transX = function(x) {
+      if (this.data.length === 1) {
+        return (this.xStart + this.xEnd) / 2;
+      } else {
+        return this.xStart + (x - this.xmin) * this.dx;
+      }
+    };
+
+    Grid.prototype.redraw = function() {
+      this.raphael.clear();
+      this._calc();
+      this.drawGrid();
+      this.drawGoals();
+      this.drawEvents();
+      if (this.draw) {
+        return this.draw();
+      }
+    };
+
+    Grid.prototype.measureText = function(text, angle) {
+      var ret, tt;
+      if (angle == null) {
+        angle = 0;
+      }
+      tt = this.raphael.text(100, 100, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).rotate(angle);
+      ret = tt.getBBox();
+      tt.remove();
+      return ret;
+    };
+
+    Grid.prototype.yAxisFormat = function(label) {
+      return this.yLabelFormat(label, 0);
+    };
+
+    Grid.prototype.yLabelFormat = function(label, i) {
+      if (typeof this.options.yLabelFormat === 'function') {
+        return this.options.yLabelFormat(label, i);
+      } else {
+        return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;
+      }
+    };
+
+    Grid.prototype.getYAxisLabelX = function() {
+      return this.left - this.options.padding / 2;
+    };
+
+    Grid.prototype.drawGrid = function() {
+      var basePos, lineY, pos, _i, _len, _ref, _ref1, _ref2, _results;
+      if (this.options.grid === false && ((_ref = this.options.axes) !== true && _ref !== 'both' && _ref !== 'y')) {
+        return;
+      }
+      if (!this.options.horizontal) {
+        basePos = this.getYAxisLabelX();
+      } else {
+        basePos = this.getXAxisLabelY();
+      }
+      _ref1 = this.grid;
+      _results = [];
+      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+        lineY = _ref1[_i];
+        pos = this.transY(lineY);
+        if ((_ref2 = this.options.axes) === true || _ref2 === 'both' || _ref2 === 'y') {
+          if (!this.options.horizontal) {
+            this.drawYAxisLabel(basePos, pos, this.yAxisFormat(lineY));
+          } else {
+            this.drawXAxisLabel(pos, basePos, this.yAxisFormat(lineY));
+          }
+        }
+        if (this.options.grid) {
+          pos = Math.floor(pos) + 0.5;
+          if (!this.options.horizontal) {
+            _results.push(this.drawGridLine("M" + this.xStart + "," + pos + "H" + this.xEnd));
+          } else {
+            _results.push(this.drawGridLine("M" + pos + "," + this.xStart + "V" + this.xEnd));
+          }
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    Grid.prototype.drawGoals = function() {
+      var color, goal, i, _i, _len, _ref, _results;
+      _ref = this.options.goals;
+      _results = [];
+      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+        goal = _ref[i];
+        color = this.options.goalLineColors[i % this.options.goalLineColors.length];
+        _results.push(this.drawGoal(goal, color));
+      }
+      return _results;
+    };
+
+    Grid.prototype.drawEvents = function() {
+      var color, event, i, _i, _len, _ref, _results;
+      _ref = this.events;
+      _results = [];
+      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+        event = _ref[i];
+        color = this.options.eventLineColors[i % this.options.eventLineColors.length];
+        _results.push(this.drawEvent(event, color));
+      }
+      return _results;
+    };
+
+    Grid.prototype.drawGoal = function(goal, color) {
+      var path, y;
+      y = Math.floor(this.transY(goal)) + 0.5;
+      if (!this.options.horizontal) {
+        path = "M" + this.xStart + "," + y + "H" + this.xEnd;
+      } else {
+        path = "M" + y + "," + this.xStart + "V" + this.xEnd;
+      }
+      return this.raphael.path(path).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth);
+    };
+
+    Grid.prototype.drawEvent = function(event, color) {
+      var from, path, to, x;
+      if (event instanceof Array) {
+        from = event[0], to = event[1];
+        from = Math.floor(this.transX(from)) + 0.5;
+        to = Math.floor(this.transX(to)) + 0.5;
+        if (!this.options.horizontal) {
+          return this.raphael.rect(from, this.yEnd, to - from, this.yStart - this.yEnd).attr({
+            fill: color,
+            stroke: false
+          }).toBack();
+        } else {
+          return this.raphael.rect(this.yStart, from, this.yEnd - this.yStart, to - from).attr({
+            fill: color,
+            stroke: false
+          }).toBack();
+        }
+      } else {
+        x = Math.floor(this.transX(event)) + 0.5;
+        if (!this.options.horizontal) {
+          path = "M" + x + "," + this.yStart + "V" + this.yEnd;
+        } else {
+          path = "M" + this.yStart + "," + x + "H" + this.yEnd;
+        }
+        return this.raphael.path(path).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth);
+      }
+    };
+
+    Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {
+      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
+    };
+
+    Grid.prototype.drawGridLine = function(path) {
+      return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
+    };
+
+    Grid.prototype.startRange = function(x) {
+      this.hover.hide();
+      this.selectFrom = x;
+      return this.selectionRect.attr({
+        x: x,
+        width: 0
+      }).show();
+    };
+
+    Grid.prototype.endRange = function(x) {
+      var end, start;
+      if (this.selectFrom) {
+        start = Math.min(this.selectFrom, x);
+        end = Math.max(this.selectFrom, x);
+        this.options.rangeSelect.call(this.el, {
+          start: this.data[this.hitTest(start)].x,
+          end: this.data[this.hitTest(end)].x
+        });
+        return this.selectFrom = null;
+      }
+    };
+
+    Grid.prototype.resizeHandler = function() {
+      this.timeoutId = null;
+      this.raphael.setSize(this.el.width(), this.el.height());
+      return this.redraw();
+    };
+
+    Grid.prototype.hasToShow = function(i) {
+      return this.options.shown === true || this.options.shown[i] === true;
+    };
+
+    return Grid;
+
+  })(Morris.EventEmitter);
+
+  Morris.parseDate = function(date) {
+    var isecs, m, msecs, n, o, offsetmins, p, q, r, ret, secs;
+    if (typeof date === 'number') {
+      return date;
+    }
+    m = date.match(/^(\d+) Q(\d)$/);
+    n = date.match(/^(\d+)-(\d+)$/);
+    o = date.match(/^(\d+)-(\d+)-(\d+)$/);
+    p = date.match(/^(\d+) W(\d+)$/);
+    q = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/);
+    r = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/);
+    if (m) {
+      return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();
+    } else if (n) {
+      return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();
+    } else if (o) {
+      return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();
+    } else if (p) {
+      ret = new Date(parseInt(p[1], 10), 0, 1);
+      if (ret.getDay() !== 4) {
+        ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
+      }
+      return ret.getTime() + parseInt(p[2], 10) * 604800000;
+    } else if (q) {
+      if (!q[6]) {
+        return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();
+      } else {
+        offsetmins = 0;
+        if (q[6] !== 'Z') {
+          offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10);
+          if (q[7] === '+') {
+            offsetmins = 0 - offsetmins;
+          }
+        }
+        return Date.UTC(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10) + offsetmins);
+      }
+    } else if (r) {
+      secs = parseFloat(r[6]);
+      isecs = Math.floor(secs);
+      msecs = Math.round((secs - isecs) * 1000);
+      if (!r[8]) {
+        return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();
+      } else {
+        offsetmins = 0;
+        if (r[8] !== 'Z') {
+          offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10);
+          if (r[9] === '+') {
+            offsetmins = 0 - offsetmins;
+          }
+        }
+        return Date.UTC(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10) + offsetmins, isecs, msecs);
+      }
+    } else {
+      return new Date(parseInt(date, 10), 0, 1).getTime();
+    }
+  };
+
+  Morris.Hover = (function() {
+    Hover.defaults = {
+      "class": 'morris-hover morris-default-style'
+    };
+
+    function Hover(options) {
+      if (options == null) {
+        options = {};
+      }
+      this.options = $.extend({}, Morris.Hover.defaults, options);
+      this.el = $("<div class='" + this.options["class"] + "'></div>");
+      this.el.hide();
+      this.options.parent.append(this.el);
+    }
+
+    Hover.prototype.update = function(html, x, y, centre_y) {
+      if (!html) {
+        return this.hide();
+      } else {
+        this.html(html);
+        this.show();
+        return this.moveTo(x, y, centre_y);
+      }
+    };
+
+    Hover.prototype.html = function(content) {
+      return this.el.html(content);
+    };
+
+    Hover.prototype.moveTo = function(x, y, centre_y) {
+      var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top;
+      parentWidth = this.options.parent.innerWidth();
+      parentHeight = this.options.parent.innerHeight();
+      hoverWidth = this.el.outerWidth();
+      hoverHeight = this.el.outerHeight();
+      left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth);
+      if (y != null) {
+        if (centre_y === true) {
+          top = y - hoverHeight / 2;
+          if (top < 0) {
+            top = 0;
+          }
+        } else {
+          top = y - hoverHeight - 10;
+          if (top < 0) {
+            top = y + 10;
+            if (top + hoverHeight > parentHeight) {
+              top = parentHeight / 2 - hoverHeight / 2;
+            }
+          }
+        }
+      } else {
+        top = parentHeight / 2 - hoverHeight / 2;
+      }
+      return this.el.css({
+        left: left + "px",
+        top: parseInt(top) + "px"
+      });
+    };
+
+    Hover.prototype.show = function() {
+      return this.el.show();
+    };
+
+    Hover.prototype.hide = function() {
+      return this.el.hide();
+    };
+
+    return Hover;
+
+  })();
+
+  Morris.Line = (function(_super) {
+    __extends(Line, _super);
+
+    function Line(options) {
+      this.hilight = __bind(this.hilight, this);
+      this.onHoverOut = __bind(this.onHoverOut, this);
+      this.onHoverMove = __bind(this.onHoverMove, this);
+      this.onGridClick = __bind(this.onGridClick, this);
+      if (!(this instanceof Morris.Line)) {
+        return new Morris.Line(options);
+      }
+      Line.__super__.constructor.call(this, options);
+    }
+
+    Line.prototype.init = function() {
+      if (this.options.hideHover !== 'always') {
+        this.hover = new Morris.Hover({
+          parent: this.el
+        });
+        this.on('hovermove', this.onHoverMove);
+        this.on('hoverout', this.onHoverOut);
+        return this.on('gridclick', this.onGridClick);
+      }
+    };
+
+    Line.prototype.defaults = {
+      lineWidth: 3,
+      pointSize: 4,
+      lineColors: ['#0b62a4', '#7A92A3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],
+      pointStrokeWidths: [1],
+      pointStrokeColors: ['#ffffff'],
+      pointFillColors: [],
+      smooth: true,
+      shown: true,
+      xLabels: 'auto',
+      xLabelFormat: null,
+      xLabelMargin: 24,
+      hideHover: false,
+      trendLine: false,
+      trendLineWidth: 2,
+      trendLineColors: ['#689bc3', '#a2b3bf', '#64b764']
+    };
+
+    Line.prototype.calc = function() {
+      this.calcPoints();
+      return this.generatePaths();
+    };
+
+    Line.prototype.calcPoints = function() {
+      var row, y, _i, _len, _ref, _results;
+      _ref = this.data;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        row = _ref[_i];
+        row._x = this.transX(row.x);
+        row._y = (function() {
+          var _j, _len1, _ref1, _results1;
+          _ref1 = row.y;
+          _results1 = [];
+          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+            y = _ref1[_j];
+            if (y != null) {
+              _results1.push(this.transY(y));
+            } else {
+              _results1.push(y);
+            }
+          }
+          return _results1;
+        }).call(this);
+        _results.push(row._ymax = Math.min.apply(Math, [this.bottom].concat((function() {
+          var _j, _len1, _ref1, _results1;
+          _ref1 = row._y;
+          _results1 = [];
+          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+            y = _ref1[_j];
+            if (y != null) {
+              _results1.push(y);
+            }
+          }
+          return _results1;
+        })())));
+      }
+      return _results;
+    };
+
+    Line.prototype.hitTest = function(x) {
+      var index, r, _i, _len, _ref;
+      if (this.data.length === 0) {
+        return null;
+      }
+      _ref = this.data.slice(1);
+      for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
+        r = _ref[index];
+        if (x < (r._x + this.data[index]._x) / 2) {
+          break;
+        }
+      }
+      return index;
+    };
+
+    Line.prototype.onGridClick = function(x, y) {
+      var index;
+      index = this.hitTest(x);
+      return this.fire('click', index, this.data[index].src, x, y);
+    };
+
+    Line.prototype.onHoverMove = function(x, y) {
+      var index;
+      index = this.hitTest(x);
+      return this.displayHoverForRow(index);
+    };
+
+    Line.prototype.onHoverOut = function() {
+      if (this.options.hideHover !== false) {
+        return this.displayHoverForRow(null);
+      }
+    };
+
+    Line.prototype.displayHoverForRow = function(index) {
+      var _ref;
+      if (index != null) {
+        (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
+        return this.hilight(index);
+      } else {
+        this.hover.hide();
+        return this.hilight();
+      }
+    };
+
+    Line.prototype.hoverContentForRow = function(index) {
+      var content, j, row, y, _i, _len, _ref;
+      row = this.data[index];
+      content = $("<div class='morris-hover-row-label'>").text(row.label);
+      content = content.prop('outerHTML');
+      _ref = row.y;
+      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {
+        y = _ref[j];
+        if (this.options.labels[j] === false) {
+          continue;
+        }
+        content += "<div class='morris-hover-point' style='color: " + (this.colorFor(row, j, 'label')) + "'>\n  " + this.options.labels[j] + ":\n  " + (this.yLabelFormat(y, j)) + "\n</div>";
+      }
+      if (typeof this.options.hoverCallback === 'function') {
+        content = this.options.hoverCallback(index, this.options, content, row.src);
+      }
+      return [content, row._x, row._ymax];
+    };
+
+    Line.prototype.generatePaths = function() {
+      var coords, i, r, smooth;
+      return this.paths = (function() {
+        var _i, _ref, _ref1, _results;
+        _results = [];
+        for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+          smooth = typeof this.options.smooth === "boolean" ? this.options.smooth : (_ref1 = this.options.ykeys[i], __indexOf.call(this.options.smooth, _ref1) >= 0);
+          coords = (function() {
+            var _j, _len, _ref2, _results1;
+            _ref2 = this.data;
+            _results1 = [];
+            for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
+              r = _ref2[_j];
+              if (r._y[i] !== void 0) {
+                _results1.push({
+                  x: r._x,
+                  y: r._y[i]
+                });
+              }
+            }
+            return _results1;
+          }).call(this);
+          if (coords.length > 1) {
+            _results.push(Morris.Line.createPath(coords, smooth, this.bottom));
+          } else {
+            _results.push(null);
+          }
+        }
+        return _results;
+      }).call(this);
+    };
+
+    Line.prototype.draw = function() {
+      var _ref;
+      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {
+        this.drawXAxis();
+      }
+      this.drawSeries();
+      if (this.options.hideHover === false) {
+        return this.displayHoverForRow(this.data.length - 1);
+      }
+    };
+
+    Line.prototype.drawXAxis = function() {
+      var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,
+        _this = this;
+      ypos = this.bottom + this.options.padding / 2;
+      prevLabelMargin = null;
+      prevAngleMargin = null;
+      drawLabel = function(labelText, xpos) {
+        var label, labelBox, margin, offset, textBox;
+        label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);
+        textBox = label.getBBox();
+        label.transform("r" + (-_this.options.xLabelAngle));
+        labelBox = label.getBBox();
+        label.transform("t0," + (labelBox.height / 2) + "...");
+        if (_this.options.xLabelAngle !== 0) {
+          offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);
+          label.transform("t" + offset + ",0...");
+        }
+        labelBox = label.getBBox();
+        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
+          if (_this.options.xLabelAngle !== 0) {
+            margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);
+            prevAngleMargin = labelBox.x - margin;
+          }
+          return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;
+        } else {
+          return label.remove();
+        }
+      };
+      if (this.options.parseTime) {
+        if (this.data.length === 1 && this.options.xLabels === 'auto') {
+          labels = [[this.data[0].label, this.data[0].x]];
+        } else {
+          labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);
+        }
+      } else {
+        labels = (function() {
+          var _i, _len, _ref, _results;
+          _ref = this.data;
+          _results = [];
+          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+            row = _ref[_i];
+            _results.push([row.label, row.x]);
+          }
+          return _results;
+        }).call(this);
+      }
+      labels.reverse();
+      _results = [];
+      for (_i = 0, _len = labels.length; _i < _len; _i++) {
+        l = labels[_i];
+        _results.push(drawLabel(l[0], l[1]));
+      }
+      return _results;
+    };
+
+    Line.prototype.drawSeries = function() {
+      var i, _i, _j, _ref, _ref1, _results;
+      this.seriesPoints = [];
+      for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
+        if (this.hasToShow(i)) {
+          if (this.options.trendLine !== false && this.options.trendLine === true || this.options.trendLine[i] === true) {
+            this._drawTrendLine(i);
+          }
+          this._drawLineFor(i);
+        }
+      }
+      _results = [];
+      for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {
+        if (this.hasToShow(i)) {
+          _results.push(this._drawPointFor(i));
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    Line.prototype._drawPointFor = function(index) {
+      var circle, row, _i, _len, _ref, _results;
+      this.seriesPoints[index] = [];
+      _ref = this.data;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        row = _ref[_i];
+        circle = null;
+        if (row._y[index] != null) {
+          circle = this.drawLinePoint(row._x, row._y[index], this.colorFor(row, index, 'point'), index);
+        }
+        _results.push(this.seriesPoints[index].push(circle));
+      }
+      return _results;
+    };
+
+    Line.prototype._drawLineFor = function(index) {
+      var path;
+      path = this.paths[index];
+      if (path !== null) {
+        return this.drawLinePath(path, this.colorFor(null, index, 'line'), index);
+      }
+    };
+
+    Line.prototype._drawTrendLine = function(index) {
+      var a, b, data, datapoints, path, sum_x, sum_xx, sum_xy, sum_y, val, x, y, _i, _len, _ref;
+      sum_x = 0;
+      sum_y = 0;
+      sum_xx = 0;
+      sum_xy = 0;
+      datapoints = 0;
+      _ref = this.data;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        val = _ref[_i];
+        x = val.x;
+        y = val.y[index];
+        if (y === void 0) {
+          continue;
+        }
+        datapoints += 1;
+        sum_x += x;
+        sum_y += y;
+        sum_xx += x * x;
+        sum_xy += x * y;
+      }
+      a = (datapoints * sum_xy - sum_x * sum_y) / (datapoints * sum_xx - sum_x * sum_x);
+      b = (sum_y / datapoints) - ((a * sum_x) / datapoints);
+      data = [{}, {}];
+      data[0].x = this.transX(this.data[0].x);
+      data[0].y = this.transY(this.data[0].x * a + b);
+      data[1].x = this.transX(this.data[this.data.length - 1].x);
+      data[1].y = this.transY(this.data[this.data.length - 1].x * a + b);
+      path = Morris.Line.createPath(data, false, this.bottom);
+      return path = this.raphael.path(path).attr('stroke', this.colorFor(null, index, 'trendLine')).attr('stroke-width', this.options.trendLineWidth);
+    };
+
+    Line.createPath = function(coords, smooth, bottom) {
+      var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len;
+      path = "";
+      if (smooth) {
+        grads = Morris.Line.gradients(coords);
+      }
+      prevCoord = {
+        y: null
+      };
+      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {
+        coord = coords[i];
+        if (coord.y != null) {
+          if (prevCoord.y != null) {
+            if (smooth) {
+              g = grads[i];
+              lg = grads[i - 1];
+              ix = (coord.x - prevCoord.x) / 4;
+              x1 = prevCoord.x + ix;
+              y1 = Math.min(bottom, prevCoord.y + ix * lg);
+              x2 = coord.x - ix;
+              y2 = Math.min(bottom, coord.y - ix * g);
+              path += "C" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + coord.x + "," + coord.y;
+            } else {
+              path += "L" + coord.x + "," + coord.y;
+            }
+          } else {
+            if (!smooth || (grads[i] != null)) {
+              path += "M" + coord.x + "," + coord.y;
+            }
+          }
+        }
+        prevCoord = coord;
+      }
+      return path;
+    };
+
+    Line.gradients = function(coords) {
+      var coord, grad, i, nextCoord, prevCoord, _i, _len, _results;
+      grad = function(a, b) {
+        return (a.y - b.y) / (a.x - b.x);
+      };
+      _results = [];
+      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {
+        coord = coords[i];
+        if (coord.y != null) {
+          nextCoord = coords[i + 1] || {
+            y: null
+          };
+          prevCoord = coords[i - 1] || {
+            y: null
+          };
+          if ((prevCoord.y != null) && (nextCoord.y != null)) {
+            _results.push(grad(prevCoord, nextCoord));
+          } else if (prevCoord.y != null) {
+            _results.push(grad(prevCoord, coord));
+          } else if (nextCoord.y != null) {
+            _results.push(grad(coord, nextCoord));
+          } else {
+            _results.push(null);
+          }
+        } else {
+          _results.push(null);
+        }
+      }
+      return _results;
+    };
+
+    Line.prototype.hilight = function(index) {
+      var i, _i, _j, _ref, _ref1;
+      if (this.prevHilight !== null && this.prevHilight !== index) {
+        for (i = _i = 0, _ref = this.seriesPoints.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+          if (this.seriesPoints[i][this.prevHilight]) {
+            this.seriesPoints[i][this.prevHilight].animate(this.pointShrinkSeries(i));
+          }
+        }
+      }
+      if (index !== null && this.prevHilight !== index) {
+        for (i = _j = 0, _ref1 = this.seriesPoints.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
+          if (this.seriesPoints[i][index]) {
+            this.seriesPoints[i][index].animate(this.pointGrowSeries(i));
+          }
+        }
+      }
+      return this.prevHilight = index;
+    };
+
+    Line.prototype.colorFor = function(row, sidx, type) {
+      if (typeof this.options.lineColors === 'function') {
+        return this.options.lineColors.call(this, row, sidx, type);
+      } else if (type === 'point') {
+        return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length];
+      } else if (type === 'line') {
+        return this.options.lineColors[sidx % this.options.lineColors.length];
+      } else {
+        return this.options.trendLineColors[sidx % this.options.trendLineColors.length];
+      }
+    };
+
+    Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {
+      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);
+    };
+
+    Line.prototype.drawLinePath = function(path, lineColor, lineIndex) {
+      return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.lineWidthForSeries(lineIndex));
+    };
+
+    Line.prototype.drawLinePoint = function(xPos, yPos, pointColor, lineIndex) {
+      return this.raphael.circle(xPos, yPos, this.pointSizeForSeries(lineIndex)).attr('fill', pointColor).attr('stroke-width', this.pointStrokeWidthForSeries(lineIndex)).attr('stroke', this.pointStrokeColorForSeries(lineIndex));
+    };
+
+    Line.prototype.pointStrokeWidthForSeries = function(index) {
+      return this.options.pointStrokeWidths[index % this.options.pointStrokeWidths.length];
+    };
+
+    Line.prototype.pointStrokeColorForSeries = function(index) {
+      return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];
+    };
+
+    Line.prototype.lineWidthForSeries = function(index) {
+      if (this.options.lineWidth instanceof Array) {
+        return this.options.lineWidth[index % this.options.lineWidth.length];
+      } else {
+        return this.options.lineWidth;
+      }
+    };
+
+    Line.prototype.pointSizeForSeries = function(index) {
+      if (this.options.pointSize instanceof Array) {
+        return this.options.pointSize[index % this.options.pointSize.length];
+      } else {
+        return this.options.pointSize;
+      }
+    };
+
+    Line.prototype.pointGrowSeries = function(index) {
+      if (this.pointSizeForSeries(index) === 0) {
+        return;
+      }
+      return Raphael.animation({
+        r: this.pointSizeForSeries(index) + 3
+      }, 25, 'linear');
+    };
+
+    Line.prototype.pointShrinkSeries = function(index) {
+      return Raphael.animation({
+        r: this.pointSizeForSeries(index)
+      }, 25, 'linear');
+    };
+
+    return Line;
+
+  })(Morris.Grid);
+
+  Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {
+    var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;
+    ddensity = 200 * (dmax - dmin) / pxwidth;
+    d0 = new Date(dmin);
+    spec = Morris.LABEL_SPECS[specName];
+    if (spec === void 0) {
+      _ref = Morris.AUTO_LABEL_ORDER;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        name = _ref[_i];
+        s = Morris.LABEL_SPECS[name];
+        if (ddensity >= s.span) {
+          spec = s;
+          break;
+        }
+      }
+    }
+    if (spec === void 0) {
+      spec = Morris.LABEL_SPECS["second"];
+    }
+    if (xLabelFormat) {
+      spec = $.extend({}, spec, {
+        fmt: xLabelFormat
+      });
+    }
+    d = spec.start(d0);
+    ret = [];
+    while ((t = d.getTime()) <= dmax) {
+      if (t >= dmin) {
+        ret.push([spec.fmt(d), t]);
+      }
+      spec.incr(d);
+    }
+    return ret;
+  };
+
+  minutesSpecHelper = function(interval) {
+    return {
+      span: interval * 60 * 1000,
+      start: function(d) {
+        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
+      },
+      fmt: function(d) {
+        return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes()));
+      },
+      incr: function(d) {
+        return d.setUTCMinutes(d.getUTCMinutes() + interval);
+      }
+    };
+  };
+
+  secondsSpecHelper = function(interval) {
+    return {
+      span: interval * 1000,
+      start: function(d) {
+        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
+      },
+      fmt: function(d) {
+        return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds()));
+      },
+      incr: function(d) {
+        return d.setUTCSeconds(d.getUTCSeconds() + interval);
+      }
+    };
+  };
+
+  Morris.LABEL_SPECS = {
+    "decade": {
+      span: 172800000000,
+      start: function(d) {
+        return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);
+      },
+      fmt: function(d) {
+        return "" + (d.getFullYear());
+      },
+      incr: function(d) {
+        return d.setFullYear(d.getFullYear() + 10);
+      }
+    },
+    "year": {
+      span: 17280000000,
+      start: function(d) {
+        return new Date(d.getFullYear(), 0, 1);
+      },
+      fmt: function(d) {
+        return "" + (d.getFullYear());
+      },
+      incr: function(d) {
+        return d.setFullYear(d.getFullYear() + 1);
+      }
+    },
+    "month": {
+      span: 2419200000,
+      start: function(d) {
+        return new Date(d.getFullYear(), d.getMonth(), 1);
+      },
+      fmt: function(d) {
+        return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1));
+      },
+      incr: function(d) {
+        return d.setMonth(d.getMonth() + 1);
+      }
+    },
+    "week": {
+      span: 604800000,
+      start: function(d) {
+        return new Date(d.getFullYear(), d.getMonth(), d.getDate());
+      },
+      fmt: function(d) {
+        return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
+      },
+      incr: function(d) {
+        return d.setDate(d.getDate() + 7);
+      }
+    },
+    "day": {
+      span: 86400000,
+      start: function(d) {
+        return new Date(d.getFullYear(), d.getMonth(), d.getDate());
+      },
+      fmt: function(d) {
+        return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
+      },
+      incr: function(d) {
+        return d.setDate(d.getDate() + 1);
+      }
+    },
+    "hour": minutesSpecHelper(60),
+    "30min": minutesSpecHelper(30),
+    "15min": minutesSpecHelper(15),
+    "10min": minutesSpecHelper(10),
+    "5min": minutesSpecHelper(5),
+    "minute": minutesSpecHelper(1),
+    "30sec": secondsSpecHelper(30),
+    "15sec": secondsSpecHelper(15),
+    "10sec": secondsSpecHelper(10),
+    "5sec": secondsSpecHelper(5),
+    "second": secondsSpecHelper(1)
+  };
+
+  Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "week", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
+
+  Morris.Area = (function(_super) {
+    var areaDefaults;
+
+    __extends(Area, _super);
+
+    areaDefaults = {
+      fillOpacity: 'auto',
+      behaveLikeLine: false
+    };
+
+    function Area(options) {
+      var areaOptions;
+      if (!(this instanceof Morris.Area)) {
+        return new Morris.Area(options);
+      }
+      areaOptions = $.extend({}, areaDefaults, options);
+      this.cumulative = !areaOptions.behaveLikeLine;
+      if (areaOptions.fillOpacity === 'auto') {
+        areaOptions.fillOpacity = areaOptions.behaveLikeLine ? .8 : 1;
+      }
+      Area.__super__.constructor.call(this, areaOptions);
+    }
+
+    Area.prototype.calcPoints = function() {
+      var row, total, y, _i, _len, _ref, _results;
+      _ref = this.data;
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        row = _ref[_i];
+        row._x = this.transX(row.x);
+        total = 0;
+        row._y = (function() {
+          var _j, _len1, _ref1, _results1;
+          _ref1 = row.y;
+          _results1 = [];
+          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+            y = _ref1[_j];
+            if (this.options.behaveLikeLine) {
+              _results1.push(this.transY(y));
+            } else {
+              total += y || 0;
+              _results1.push(this.transY(total));
+            }
+          }
+          return _results1;
+        }).call(this);
+        _results.push(row._ymax = Math.max.apply(Math, row._y));
+      }
+      return _results;
+    };
+
+    Area.prototype.drawSeries = function() {
+      var i, range, _i, _j, _k, _len, _ref, _ref1, _results, _results1, _results2;
+      this.seriesPoints = [];
+      if (this.options.behaveLikeLine) {
+        range = (function() {
+          _results = [];
+          for (var _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
+          return _results;
+        }).apply(this);
+      } else {
+        range = (function() {
+          _results1 = [];
+          for (var _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; _ref1 <= 0 ? _j++ : _j--){ _results1.push(_j); }
+          return _results1;
+        }).apply(this);
+      }
+      _results2 = [];
+      for (_k = 0, _len = range.length; _k < _len; _k++) {
+        i = range[_k];
+        this._drawFillFor(i);
+        this._drawLineFor(i);
+        _results2.push(this._drawPointFor(i));
+      }
+      return _results2;
+    };
+
+    Area.prototype._drawFillFor = function(index) {
+      var path;
+      path = this.paths[index];
+      if (path !== null) {
+        path = path + ("L" + (this.transX(this.xmax)) + "," + this.bottom + "L" + (this.transX(this.xmin)) + "," + this.bottom + "Z");
+        return this.drawFilledPath(path, this.fillForSeries(index));
+      }
+    };
+
+    Area.prototype.fillForSeries = function(i) {
+      var color;
+      color = Raphael.rgb2hsl(this.colorFor(this.data[i], i, 'line'));
+      return Raphael.hsl(color.h, this.options.behaveLikeLine ? color.s * 0.9 : color.s * 0.75, Math.min(0.98, this.options.behaveLikeLine ? color.l * 1.2 : color.l * 1.25));
+    };
+
+    Area.prototype.drawFilledPath = function(path, fill) {
+      return this.raphael.path(path).attr('fill', fill).attr('fill-opacity', this.options.fillOpacity).attr('stroke', 'none');
+    };
+
+    return Area;
+
+  })(Morris.Line);
+
+  Morris.Bar = (function(_super) {
+    __extends(Bar, _super);
+
+    function Bar(options) {
+      this.onHoverOut = __bind(this.onHoverOut, this);
+      this.onHoverMove = __bind(this.onHoverMove, this);
+      this.onGridClick = __bind(this.onGridClick, this);
+      if (!(this instanceof Morris.Bar)) {
+        return new Morris.Bar(options);
+      }
+      Bar.__super__.constructor.call(this, $.extend({}, options, {
+        parseTime: false
+      }));
+    }
+
+    Bar.prototype.init = function() {
+      this.cumulative = this.options.stacked;
+      if (this.options.hideHover !== 'always') {
+        this.hover = new Morris.Hover({
+          parent: this.el
+        });
+        this.on('hovermove', this.onHoverMove);
+        this.on('hoverout', this.onHoverOut);
+        return this.on('gridclick', this.onGridClick);
+      }
+    };
+
+    Bar.prototype.defaults = {
+      barSizeRatio: 0.75,
+      barGap: 3,
+      barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],
+      barOpacity: 1.0,
+      barRadius: [0, 0, 0, 0],
+      xLabelMargin: 50,
+      horizontal: false,
+      shown: true
+    };
+
+    Bar.prototype.calc = function() {
+      var _ref;
+      this.calcBars();
+      if (this.options.hideHover === false) {
+        return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));
+      }
+    };
+
+    Bar.prototype.calcBars = function() {
+      var idx, row, y, _i, _len, _ref, _results;
+      _ref = this.data;
+      _results = [];
+      for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
+        row = _ref[idx];
+        row._x = this.xStart + this.xSize * (idx + 0.5) / this.data.length;
+        _results.push(row._y = (function() {
+          var _j, _len1, _ref1, _results1;
+          _ref1 = row.y;
+          _results1 = [];
+          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+            y = _ref1[_j];
+            if (y != null) {
+              _results1.push(this.transY(y));
+            } else {
+              _results1.push(null);
+            }
+          }
+          return _results1;
+        }).call(this));
+      }
+      return _results;
+    };
+
+    Bar.prototype.draw = function() {
+      var _ref;
+      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {
+        this.drawXAxis();
+      }
+      return this.drawSeries();
+    };
+
+    Bar.prototype.drawXAxis = function() {
+      var angle, basePos, i, label, labelBox, margin, maxSize, offset, prevAngleMargin, prevLabelMargin, row, size, startPos, textBox, _i, _ref, _results;
+      if (!this.options.horizontal) {
+        basePos = this.getXAxisLabelY();
+      } else {
+        basePos = this.getYAxisLabelX();
+      }
+      prevLabelMargin = null;
+      prevAngleMargin = null;
+      _results = [];
+      for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+        row = this.data[this.data.length - 1 - i];
+        if (!this.options.horizontal) {
+          label = this.drawXAxisLabel(row._x, basePos, row.label);
+        } else {
+          label = this.drawYAxisLabel(basePos, row._x - 0.5 * this.options.gridTextSize, row.label);
+        }
+        if (!this.options.horizontal) {
+          angle = this.options.xLabelAngle;
+        } else {
+          angle = 0;
+        }
+        textBox = label.getBBox();
+        label.transform("r" + (-angle));
+        labelBox = label.getBBox();
+        label.transform("t0," + (labelBox.height / 2) + "...");
+        if (angle !== 0) {
+          offset = -0.5 * textBox.width * Math.cos(angle * Math.PI / 180.0);
+          label.transform("t" + offset + ",0...");
+        }
+        if (!this.options.horizontal) {
+          startPos = labelBox.x;
+          size = labelBox.width;
+          maxSize = this.el.width();
+        } else {
+          startPos = labelBox.y;
+          size = labelBox.height;
+          maxSize = this.el.height();
+        }
+        if (((prevLabelMargin == null) || prevLabelMargin >= startPos + size || (prevAngleMargin != null) && prevAngleMargin >= startPos) && startPos >= 0 && (startPos + size) < maxSize) {
+          if (angle !== 0) {
+            margin = 1.25 * this.options.gridTextSize / Math.sin(angle * Math.PI / 180.0);
+            prevAngleMargin = startPos - margin;
+          }
+          if (!this.options.horizontal) {
+            _results.push(prevLabelMargin = startPos - this.options.xLabelMargin);
+          } else {
+            _results.push(prevLabelMargin = startPos);
+          }
+        } else {
+          _results.push(label.remove());
+        }
+      }
+      return _results;
+    };
+
+    Bar.prototype.getXAxisLabelY = function() {
+      return this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2);
+    };
+
+    Bar.prototype.drawSeries = function() {
+      var barWidth, bottom, groupWidth, i, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos, _i, _ref;
+      groupWidth = this.xSize / this.options.data.length;
+      if (this.options.stacked) {
+        numBars = 1;
+      } else {
+        numBars = 0;
+        for (i = _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+          if (this.hasToShow(i)) {
+            numBars += 1;
+          }
+        }
+      }
+      barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars;
+      if (this.options.barSize) {
+        barWidth = Math.min(barWidth, this.options.barSize);
+      }
+      spaceLeft = groupWidth - barWidth * numBars - this.options.barGap * (numBars - 1);
+      leftPadding = spaceLeft / 2;
+      zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null;
+      return this.bars = (function() {
+        var _j, _len, _ref1, _results;
+        _ref1 = this.data;
+        _results = [];
+        for (idx = _j = 0, _len = _ref1.length; _j < _len; idx = ++_j) {
+          row = _ref1[idx];
+          lastTop = 0;
+          _results.push((function() {
+            var _k, _len1, _ref2, _results1;
+            _ref2 = row._y;
+            _results1 = [];
+            for (sidx = _k = 0, _len1 = _ref2.length; _k < _len1; sidx = ++_k) {
+              ypos = _ref2[sidx];
+              if (!this.hasToShow(sidx)) {
+                continue;
+              }
+              if (ypos !== null) {
+                if (zeroPos) {
+                  top = Math.min(ypos, zeroPos);
+                  bottom = Math.max(ypos, zeroPos);
+                } else {
+                  top = ypos;
+                  bottom = this.bottom;
+                }
+                left = this.xStart + idx * groupWidth + leftPadding;
+                if (!this.options.stacked) {
+                  left += sidx * (barWidth + this.options.barGap);
+                }
+                size = bottom - top;
+                if (this.options.verticalGridCondition && this.options.verticalGridCondition(row.x)) {
+                  if (!this.options.horizontal) {
+                    this.drawBar(this.xStart + idx * groupWidth, this.yEnd, groupWidth, this.ySize, this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius);
+                  } else {
+                    this.drawBar(this.yStart, this.xStart + idx * groupWidth, this.ySize, groupWidth, this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius);
+                  }
+                }
+                if (this.options.stacked) {
+                  top -= lastTop;
+                }
+                if (!this.options.horizontal) {
+                  this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius);
+                  _results1.push(lastTop += size);
+                } else {
+                  this.drawBar(top, left, size, barWidth, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius);
+                  _results1.push(lastTop -= size);
+                }
+              } else {
+                _results1.push(null);
+              }
+            }
+            return _results1;
+          }).call(this));
+        }
+        return _results;
+      }).call(this);
+    };
+
+    Bar.prototype.colorFor = function(row, sidx, type) {
+      var r, s;
+      if (typeof this.options.barColors === 'function') {
+        r = {
+          x: row.x,
+          y: row.y[sidx],
+          label: row.label
+        };
+        s = {
+          index: sidx,
+          key: this.options.ykeys[sidx],
+          label: this.options.labels[sidx]
+        };
+        return this.options.barColors.call(this, r, s, type);
+      } else {
+        return this.options.barColors[sidx % this.options.barColors.length];
+      }
+    };
+
+    Bar.prototype.hitTest = function(x, y) {
+      var pos;
+      if (this.data.length === 0) {
+        return null;
+      }
+      if (!this.options.horizontal) {
+        pos = x;
+      } else {
+        pos = y;
+      }
+      pos = Math.max(Math.min(pos, this.xEnd), this.xStart);
+      return Math.min(this.data.length - 1, Math.floor((pos - this.xStart) / (this.xSize / this.data.length)));
+    };
+
+    Bar.prototype.onGridClick = function(x, y) {
+      var index;
+      index = this.hitTest(x, y);
+      return this.fire('click', index, this.data[index].src, x, y);
+    };
+
+    Bar.prototype.onHoverMove = function(x, y) {
+      var index, _ref;
+      index = this.hitTest(x, y);
+      return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
+    };
+
+    Bar.prototype.onHoverOut = function() {
+      if (this.options.hideHover !== false) {
+        return this.hover.hide();
+      }
+    };
+
+    Bar.prototype.hoverContentForRow = function(index) {
+      var content, j, row, x, y, _i, _len, _ref;
+      row = this.data[index];
+      content = $("<div class='morris-hover-row-label'>").text(row.label);
+      content = content.prop('outerHTML');
+      _ref = row.y;
+      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {
+        y = _ref[j];
+        if (this.options.labels[j] === false) {
+          continue;
+        }
+        content += "<div class='morris-hover-point' style='color: " + (this.colorFor(row, j, 'label')) + "'>\n  " + this.options.labels[j] + ":\n  " + (this.yLabelFormat(y, j)) + "\n</div>";
+      }
+      if (typeof this.options.hoverCallback === 'function') {
+        content = this.options.hoverCallback(index, this.options, content, row.src);
+      }
+      if (!this.options.horizontal) {
+        x = this.left + (index + 0.5) * this.width / this.data.length;
+        return [content, x];
+      } else {
+        x = this.left + 0.5 * this.width;
+        y = this.top + (index + 0.5) * this.height / this.data.length;
+        return [content, x, y, true];
+      }
+    };
+
+    Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {
+      var label;
+      return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);
+    };
+
+    Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor, opacity, radiusArray) {
+      var maxRadius, path;
+      maxRadius = Math.max.apply(Math, radiusArray);
+      if (maxRadius === 0 || maxRadius > height) {
+        path = this.raphael.rect(xPos, yPos, width, height);
+      } else {
+        path = this.raphael.path(this.roundedRect(xPos, yPos, width, height, radiusArray));
+      }
+      return path.attr('fill', barColor).attr('fill-opacity', opacity).attr('stroke', 'none');
+    };
+
+    Bar.prototype.roundedRect = function(x, y, w, h, r) {
+      if (r == null) {
+        r = [0, 0, 0, 0];
+      }
+      return ["M", x, r[0] + y, "Q", x, y, x + r[0], y, "L", x + w - r[1], y, "Q", x + w, y, x + w, y + r[1], "L", x + w, y + h - r[2], "Q", x + w, y + h, x + w - r[2], y + h, "L", x + r[3], y + h, "Q", x, y + h, x, y + h - r[3], "Z"];
+    };
+
+    return Bar;
+
+  })(Morris.Grid);
+
+  Morris.Donut = (function(_super) {
+    __extends(Donut, _super);
+
+    Donut.prototype.defaults = {
+      colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],
+      backgroundColor: '#FFFFFF',
+      labelColor: '#000000',
+      formatter: Morris.commas,
+      resize: false
+    };
+
+    function Donut(options) {
+      this.resizeHandler = __bind(this.resizeHandler, this);
+      this.select = __bind(this.select, this);
+      this.click = __bind(this.click, this);
+      var _this = this;
+      if (!(this instanceof Morris.Donut)) {
+        return new Morris.Donut(options);
+      }
+      this.options = $.extend({}, this.defaults, options);
+      if (typeof options.element === 'string') {
+        this.el = $(document.getElementById(options.element));
+      } else {
+        this.el = $(options.element);
+      }
+      if (this.el === null || this.el.length === 0) {
+        throw new Error("Graph placeholder not found.");
+      }
+      if (options.data === void 0 || options.data.length === 0) {
+        return;
+      }
+      this.raphael = new Raphael(this.el[0]);
+      if (this.options.resize) {
+        $(window).bind('resize', function(evt) {
+          if (_this.timeoutId != null) {
+            window.clearTimeout(_this.timeoutId);
+          }
+          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);
+        });
+      }
+      this.setData(options.data);
+    }
+
+    Donut.prototype.redraw = function() {
+      var C, cx, cy, i, idx, last, max_value, min, next, seg, total, value, w, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
+      this.raphael.clear();
+      cx = this.el.width() / 2;
+      cy = this.el.height() / 2;
+      w = (Math.min(cx, cy) - 10) / 3;
+      total = 0;
+      _ref = this.values;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        value = _ref[_i];
+        total += value;
+      }
+      min = 5 / (2 * w);
+      C = 1.9999 * Math.PI - min * this.data.length;
+      last = 0;
+      idx = 0;
+      this.segments = [];
+      _ref1 = this.values;
+      for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
+        value = _ref1[i];
+        next = last + min + C * (value / total);
+        seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.data[i].color || this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, idx, this.raphael);
+        seg.render();
+        this.segments.push(seg);
+        seg.on('hover', this.select);
+        seg.on('click', this.click);
+        last = next;
+        idx += 1;
+      }
+      this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, this.options.labelColor, 15, 800);
+      this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, this.options.labelColor, 14);
+      max_value = Math.max.apply(Math, this.values);
+      idx = 0;
+      _ref2 = this.values;
+      _results = [];
+      for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
+        value = _ref2[_k];
+        if (value === max_value) {
+          this.select(idx);
+          break;
+        }
+        _results.push(idx += 1);
+      }
+      return _results;
+    };
+
+    Donut.prototype.setData = function(data) {
+      var row;
+      this.data = data;
+      this.values = (function() {
+        var _i, _len, _ref, _results;
+        _ref = this.data;
+        _results = [];
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          row = _ref[_i];
+          _results.push(parseFloat(row.value));
+        }
+        return _results;
+      }).call(this);
+      return this.redraw();
+    };
+
+    Donut.prototype.click = function(idx) {
+      return this.fire('click', idx, this.data[idx]);
+    };
+
+    Donut.prototype.select = function(idx) {
+      var row, s, segment, _i, _len, _ref;
+      _ref = this.segments;
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        s = _ref[_i];
+        s.deselect();
+      }
+      segment = this.segments[idx];
+      segment.select();
+      row = this.data[idx];
+      return this.setLabels(row.label, this.options.formatter(row.value, row));
+    };
+
+    Donut.prototype.setLabels = function(label1, label2) {
+      var inner, maxHeightBottom, maxHeightTop, maxWidth, text1bbox, text1scale, text2bbox, text2scale;
+      inner = (Math.min(this.el.width() / 2, this.el.height() / 2) - 10) * 2 / 3;
+      maxWidth = 1.8 * inner;
+      maxHeightTop = inner / 2;
+      maxHeightBottom = inner / 3;
+      this.text1.attr({
+        text: label1,
+        transform: ''
+      });
+      text1bbox = this.text1.getBBox();
+      text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height);
+      this.text1.attr({
+        transform: "S" + text1scale + "," + text1scale + "," + (text1bbox.x + text1bbox.width / 2) + "," + (text1bbox.y + text1bbox.height)
+      });
+      this.text2.attr({
+        text: label2,
+        transform: ''
+      });
+      text2bbox = this.text2.getBBox();
+      text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height);
+      return this.text2.attr({
+        transform: "S" + text2scale + "," + text2scale + "," + (text2bbox.x + text2bbox.width / 2) + "," + text2bbox.y
+      });
+    };
+
+    Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {
+      var text;
+      text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', color);
+      if (fontWeight != null) {
+        text.attr('font-weight', fontWeight);
+      }
+      return text;
+    };
+
+    Donut.prototype.resizeHandler = function() {
+      this.timeoutId = null;
+      this.raphael.setSize(this.el.width(), this.el.height());
+      return this.redraw();
+    };
+
+    return Donut;
+
+  })(Morris.EventEmitter);
+
+  Morris.DonutSegment = (function(_super) {
+    __extends(DonutSegment, _super);
+
+    function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, index, raphael) {
+      this.cx = cx;
+      this.cy = cy;
+      this.inner = inner;
+      this.outer = outer;
+      this.color = color;
+      this.backgroundColor = backgroundColor;
+      this.index = index;
+      this.raphael = raphael;
+      this.deselect = __bind(this.deselect, this);
+      this.select = __bind(this.select, this);
+      this.sin_p0 = Math.sin(p0);
+      this.cos_p0 = Math.cos(p0);
+      this.sin_p1 = Math.sin(p1);
+      this.cos_p1 = Math.cos(p1);
+      this.is_long = (p1 - p0) > Math.PI ? 1 : 0;
+      this.path = this.calcSegment(this.inner + 3, this.inner + this.outer - 5);
+      this.selectedPath = this.calcSegment(this.inner + 3, this.inner + this.outer);
+      this.hilight = this.calcArc(this.inner);
+    }
+
+    DonutSegment.prototype.calcArcPoints = function(r) {
+      return [this.cx + r * this.sin_p0, this.cy + r * this.cos_p0, this.cx + r * this.sin_p1, this.cy + r * this.cos_p1];
+    };
+
+    DonutSegment.prototype.calcSegment = function(r1, r2) {
+      var ix0, ix1, iy0, iy1, ox0, ox1, oy0, oy1, _ref, _ref1;
+      _ref = this.calcArcPoints(r1), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];
+      _ref1 = this.calcArcPoints(r2), ox0 = _ref1[0], oy0 = _ref1[1], ox1 = _ref1[2], oy1 = _ref1[3];
+      return ("M" + ix0 + "," + iy0) + ("A" + r1 + "," + r1 + ",0," + this.is_long + ",0," + ix1 + "," + iy1) + ("L" + ox1 + "," + oy1) + ("A" + r2 + "," + r2 + ",0," + this.is_long + ",1," + ox0 + "," + oy0) + "Z";
+    };
+
+    DonutSegment.prototype.calcArc = function(r) {
+      var ix0, ix1, iy0, iy1, _ref;
+      _ref = this.calcArcPoints(r), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];
+      return ("M" + ix0 + "," + iy0) + ("A" + r + "," + r + ",0," + this.is_long + ",0," + ix1 + "," + iy1);
+    };
+
+    DonutSegment.prototype.render = function() {
+      var _this = this;
+      this.arc = this.drawDonutArc(this.hilight, this.color);
+      return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {
+        return _this.fire('hover', _this.index);
+      }, function() {
+        return _this.fire('click', _this.index);
+      });
+    };
+
+    DonutSegment.prototype.drawDonutArc = function(path, color) {
+      return this.raphael.path(path).attr({
+        stroke: color,
+        'stroke-width': 2,
+        opacity: 0
+      });
+    };
+
+    DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction, clickFunction) {
+      return this.raphael.path(path).attr({
+        fill: fillColor,
+        stroke: strokeColor,
+        'stroke-width': 3
+      }).hover(hoverFunction).click(clickFunction);
+    };
+
+    DonutSegment.prototype.select = function() {
+      if (!this.selected) {
+        this.seg.animate({
+          path: this.selectedPath
+        }, 150, '<>');
+        this.arc.animate({
+          opacity: 1
+        }, 150, '<>');
+        return this.selected = true;
+      }
+    };
+
+    DonutSegment.prototype.deselect = function() {
+      if (this.selected) {
+        this.seg.animate({
+          path: this.path
+        }, 150, '<>');
+        this.arc.animate({
+          opacity: 0
+        }, 150, '<>');
+        return this.selected = false;
+      }
+    };
+
+    return DonutSegment;
+
+  })(Morris.EventEmitter);
+
+}).call(this);
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.min.js b/src/main/resources/META-INF/resources/designer/lib/plugins/morris/morris.min.js
new file mode 100644 (file)
index 0000000..819cd67
--- /dev/null
@@ -0,0 +1,7 @@
+/* @license
+morris.js v0.5.1
+Copyright 2014 Olly Smith All rights reserved.
+Licensed under the BSD-2-Clause License.
+*/
+(function(){var a,b,c,d,e=[].slice,f=function(a,b){return function(){return a.apply(b,arguments)}},g={}.hasOwnProperty,h=function(a,b){function c(){this.constructor=a}for(var d in b)g.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},i=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};b=window.Morris={},a=jQuery,b.EventEmitter=function(){function a(){}return a.prototype.on=function(a,b){return null==this.handlers&&(this.handlers={}),null==this.handlers[a]&&(this.handlers[a]=[]),this.handlers[a].push(b),this},a.prototype.fire=function(){var a,b,c,d,f,g,h;if(c=arguments[0],a=2<=arguments.length?e.call(arguments,1):[],null!=this.handlers&&null!=this.handlers[c]){for(g=this.handlers[c],h=[],d=0,f=g.length;f>d;d++)b=g[d],h.push(b.apply(null,a));return h}},a}(),b.commas=function(a){var b,c,d,e;return null!=a?(d=0>a?"-":"",b=Math.abs(a),c=Math.floor(b).toFixed(0),d+=c.replace(/(?=(?:\d{3})+$)(?!^)/g,","),e=b.toString(),e.length>c.length&&(d+=e.slice(c.length)),d):"-"},b.pad2=function(a){return(10>a?"0":"")+a},b.Grid=function(c){function d(b){this.hasToShow=f(this.hasToShow,this),this.resizeHandler=f(this.resizeHandler,this);var c=this;if(this.el=a("string"==typeof b.element?document.getElementById(b.element):b.element),null==this.el||0===this.el.length)throw new Error("Graph container element not found");"static"===this.el.css("position")&&this.el.css("position","relative"),this.options=a.extend({},this.gridDefaults,this.defaults||{},b),"string"==typeof this.options.units&&(this.options.postUnits=b.units),this.raphael=new Raphael(this.el[0]),this.elementWidth=null,this.elementHeight=null,this.dirty=!1,this.selectFrom=null,this.init&&this.init(),this.setData(this.options.data),this.el.bind("mousemove",function(a){var b,d,e,f,g;return d=c.el.offset(),g=a.pageX-d.left,c.selectFrom?(b=c.data[c.hitTest(Math.min(g,c.selectFrom))]._x,e=c.data[c.hitTest(Math.max(g,c.selectFrom))]._x,f=e-b,c.selectionRect.attr({x:b,width:f})):c.fire("hovermove",g,a.pageY-d.top)}),this.el.bind("mouseleave",function(){return c.selectFrom&&(c.selectionRect.hide(),c.selectFrom=null),c.fire("hoverout")}),this.el.bind("touchstart touchmove touchend",function(a){var b,d;return d=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],b=c.el.offset(),c.fire("hovermove",d.pageX-b.left,d.pageY-b.top)}),this.el.bind("click",function(a){var b;return b=c.el.offset(),c.fire("gridclick",a.pageX-b.left,a.pageY-b.top)}),this.options.rangeSelect&&(this.selectionRect=this.raphael.rect(0,0,0,this.el.innerHeight()).attr({fill:this.options.rangeSelectColor,stroke:!1}).toBack().hide(),this.el.bind("mousedown",function(a){var b;return b=c.el.offset(),c.startRange(a.pageX-b.left)}),this.el.bind("mouseup",function(a){var b;return b=c.el.offset(),c.endRange(a.pageX-b.left),c.fire("hovermove",a.pageX-b.left,a.pageY-b.top)})),this.options.resize&&a(window).bind("resize",function(){return null!=c.timeoutId&&window.clearTimeout(c.timeoutId),c.timeoutId=window.setTimeout(c.resizeHandler,100)}),this.el.css("-webkit-tap-highlight-color","rgba(0,0,0,0)"),this.postInit&&this.postInit()}return h(d,c),d.prototype.gridDefaults={dateFormat:null,axes:!0,grid:!0,gridLineColor:"#aaa",gridStrokeWidth:.5,gridTextColor:"#888",gridTextSize:12,gridTextFamily:"sans-serif",gridTextWeight:"normal",hideHover:!1,yLabelFormat:null,xLabelAngle:0,numLines:5,padding:25,parseTime:!0,postUnits:"",preUnits:"",ymax:"auto",ymin:"auto 0",goals:[],goalStrokeWidth:1,goalLineColors:["#666633","#999966","#cc6666","#663333"],events:[],eventStrokeWidth:1,eventLineColors:["#005a04","#ccffbb","#3a5f0b","#005502"],rangeSelect:null,rangeSelectColor:"#eef",resize:!1},d.prototype.setData=function(c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y;if(null==d&&(d=!0),this.options.data=c,null==c||0===c.length)return this.data=[],this.raphael.clear(),void(null!=this.hover&&this.hover.hide());if(s=this.cumulative?0:null,t=this.cumulative?0:null,this.options.goals.length>0&&(k=Math.min.apply(Math,this.options.goals),j=Math.max.apply(Math,this.options.goals),t=null!=t?Math.min(t,k):k,s=null!=s?Math.max(s,j):j),this.data=function(){var a,d,e;for(e=[],i=a=0,d=c.length;d>a;i=++a)m=c[i],l={src:m},l.label=m[this.options.xkey],this.options.parseTime?(l.x=b.parseDate(l.label),this.options.dateFormat?l.label=this.options.dateFormat(l.x):"number"==typeof l.label&&(l.label=new Date(l.label).toString())):(l.x=i,this.options.xLabelFormat&&(l.label=this.options.xLabelFormat(l))),p=0,l.y=function(){var a,b,c,d;for(c=this.options.ykeys,d=[],h=a=0,b=c.length;b>a;h=++a)r=c[h],u=m[r],"string"==typeof u&&(u=parseFloat(u)),null!=u&&"number"!=typeof u&&(u=null),null!=u&&this.hasToShow(h)&&(this.cumulative?p+=u:null!=s?(s=Math.max(u,s),t=Math.min(u,t)):s=t=u),this.cumulative&&null!=p&&(s=Math.max(p,s),t=Math.min(p,t)),d.push(u);return d}.call(this),e.push(l);return e}.call(this),this.options.parseTime&&(this.data=this.data.sort(function(a,b){return(a.x>b.x)-(b.x>a.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.events=[],this.options.events.length>0){if(this.options.parseTime)for(x=this.options.events,v=0,w=x.length;w>v;v++)e=x[v],e instanceof Array?(g=e[0],o=e[1],this.events.push([b.parseDate(g),b.parseDate(o)])):this.events.push(b.parseDate(e));else this.events=this.options.events;f=a.map(this.events,function(a){return a}),this.xmax=Math.max(this.xmax,Math.max.apply(Math,f)),this.xmin=Math.min(this.xmin,Math.min.apply(Math,f))}return this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),this.ymin=this.yboundary("min",t),this.ymax=this.yboundary("max",s),this.ymin===this.ymax&&(t&&(this.ymin-=1),this.ymax+=1),((y=this.options.axes)===!0||"both"===y||"y"===y||this.options.grid===!0)&&(this.options.ymax===this.gridDefaults.ymax&&this.options.ymin===this.gridDefaults.ymin?(this.grid=this.autoGridLines(this.ymin,this.ymax,this.options.numLines),this.ymin=Math.min(this.ymin,this.grid[0]),this.ymax=Math.max(this.ymax,this.grid[this.grid.length-1])):(n=(this.ymax-this.ymin)/(this.options.numLines-1),this.grid=function(){var a,b,c,d;for(d=[],q=a=b=this.ymin,c=this.ymax;n>0?c>=a:a>=c;q=a+=n)d.push(q);return d}.call(this))),this.dirty=!0,d?this.redraw():void 0},d.prototype.yboundary=function(a,b){var c,d;return c=this.options["y"+a],"string"==typeof c?"auto"===c.slice(0,4)?c.length>5?(d=parseInt(c.slice(5),10),null==b?d:Math[a](b,d)):null!=b?b:0:parseInt(c,10):c},d.prototype.autoGridLines=function(a,b,c){var d,e,f,g,h,i,j,k,l;return h=b-a,l=Math.floor(Math.log(h)/Math.log(10)),j=Math.pow(10,l),e=Math.floor(a/j)*j,d=Math.ceil(b/j)*j,i=(d-e)/(c-1),1===j&&i>1&&Math.ceil(i)!==i&&(i=Math.ceil(i),d=e+i*(c-1)),0>e&&d>0&&(e=Math.floor(a/i)*i,d=Math.ceil(b/i)*i),1>i?(g=Math.floor(Math.log(i)/Math.log(10)),f=function(){var a,b;for(b=[],k=a=e;i>0?d>=a:a>=d;k=a+=i)b.push(parseFloat(k.toFixed(1-g)));return b}()):f=function(){var a,b;for(b=[],k=a=e;i>0?d>=a:a>=d;k=a+=i)b.push(k);return b}(),f},d.prototype._calc=function(){var a,b,c,d,e,f,g,h,i;return f=this.el.width(),d=this.el.height(),(this.elementWidth!==f||this.elementHeight!==d||this.dirty)&&(this.elementWidth=f,this.elementHeight=d,this.dirty=!1,this.left=this.options.padding,this.right=this.elementWidth-this.options.padding,this.top=this.options.padding,this.bottom=this.elementHeight-this.options.padding,((h=this.options.axes)===!0||"both"===h||"y"===h)&&(g=function(){var a,b,d,e;for(d=this.grid,e=[],a=0,b=d.length;b>a;a++)c=d[a],e.push(this.measureText(this.yAxisFormat(c)).width);return e}.call(this),this.options.horizontal?this.bottom-=Math.max.apply(Math,g):this.left+=Math.max.apply(Math,g)),((i=this.options.axes)===!0||"both"===i||"x"===i)&&(a=this.options.horizontal?-90:-this.options.xLabelAngle,b=function(){var b,c,d;for(d=[],e=b=0,c=this.data.length;c>=0?c>b:b>c;e=c>=0?++b:--b)d.push(this.measureText(this.data[e].label,a).height);return d}.call(this),this.options.horizontal?this.left+=Math.max.apply(Math,b):this.bottom-=Math.max.apply(Math,b)),this.width=Math.max(1,this.right-this.left),this.height=Math.max(1,this.bottom-this.top),this.options.horizontal?(this.dx=this.height/(this.xmax-this.xmin),this.dy=this.width/(this.ymax-this.ymin),this.yStart=this.left,this.yEnd=this.right,this.xStart=this.top,this.xEnd=this.bottom,this.xSize=this.height,this.ySize=this.width):(this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.ymax-this.ymin),this.yStart=this.bottom,this.yEnd=this.top,this.xStart=this.left,this.xEnd=this.right,this.xSize=this.width,this.ySize=this.height),this.calc)?this.calc():void 0},d.prototype.transY=function(a){return this.options.horizontal?this.left+(a-this.ymin)*this.dy:this.bottom-(a-this.ymin)*this.dy},d.prototype.transX=function(a){return 1===this.data.length?(this.xStart+this.xEnd)/2:this.xStart+(a-this.xmin)*this.dx},d.prototype.redraw=function(){return this.raphael.clear(),this._calc(),this.drawGrid(),this.drawGoals(),this.drawEvents(),this.draw?this.draw():void 0},d.prototype.measureText=function(a,b){var c,d;return null==b&&(b=0),d=this.raphael.text(100,100,a).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).rotate(b),c=d.getBBox(),d.remove(),c},d.prototype.yAxisFormat=function(a){return this.yLabelFormat(a,0)},d.prototype.yLabelFormat=function(a,c){return"function"==typeof this.options.yLabelFormat?this.options.yLabelFormat(a,c):""+this.options.preUnits+b.commas(a)+this.options.postUnits},d.prototype.getYAxisLabelX=function(){return this.left-this.options.padding/2},d.prototype.drawGrid=function(){var a,b,c,d,e,f,g,h,i;if(this.options.grid!==!1||(f=this.options.axes)===!0||"both"===f||"y"===f){for(a=this.options.horizontal?this.getXAxisLabelY():this.getYAxisLabelX(),g=this.grid,i=[],d=0,e=g.length;e>d;d++)b=g[d],c=this.transY(b),((h=this.options.axes)===!0||"both"===h||"y"===h)&&(this.options.horizontal?this.drawXAxisLabel(c,a,this.yAxisFormat(b)):this.drawYAxisLabel(a,c,this.yAxisFormat(b))),this.options.grid?(c=Math.floor(c)+.5,i.push(this.options.horizontal?this.drawGridLine("M"+c+","+this.xStart+"V"+this.xEnd):this.drawGridLine("M"+this.xStart+","+c+"H"+this.xEnd))):i.push(void 0);return i}},d.prototype.drawGoals=function(){var a,b,c,d,e,f,g;for(f=this.options.goals,g=[],c=d=0,e=f.length;e>d;c=++d)b=f[c],a=this.options.goalLineColors[c%this.options.goalLineColors.length],g.push(this.drawGoal(b,a));return g},d.prototype.drawEvents=function(){var a,b,c,d,e,f,g;for(f=this.events,g=[],c=d=0,e=f.length;e>d;c=++d)b=f[c],a=this.options.eventLineColors[c%this.options.eventLineColors.length],g.push(this.drawEvent(b,a));return g},d.prototype.drawGoal=function(a,b){var c,d;return d=Math.floor(this.transY(a))+.5,c=this.options.horizontal?"M"+d+","+this.xStart+"V"+this.xEnd:"M"+this.xStart+","+d+"H"+this.xEnd,this.raphael.path(c).attr("stroke",b).attr("stroke-width",this.options.goalStrokeWidth)},d.prototype.drawEvent=function(a,b){var c,d,e,f;return a instanceof Array?(c=a[0],e=a[1],c=Math.floor(this.transX(c))+.5,e=Math.floor(this.transX(e))+.5,this.options.horizontal?this.raphael.rect(this.yStart,c,this.yEnd-this.yStart,e-c).attr({fill:b,stroke:!1}).toBack():this.raphael.rect(c,this.yEnd,e-c,this.yStart-this.yEnd).attr({fill:b,stroke:!1}).toBack()):(f=Math.floor(this.transX(a))+.5,d=this.options.horizontal?"M"+this.yStart+","+f+"H"+this.yEnd:"M"+f+","+this.yStart+"V"+this.yEnd,this.raphael.path(d).attr("stroke",b).attr("stroke-width",this.options.eventStrokeWidth))},d.prototype.drawYAxisLabel=function(a,b,c){return this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor).attr("text-anchor","end")},d.prototype.drawGridLine=function(a){return this.raphael.path(a).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth)},d.prototype.startRange=function(a){return this.hover.hide(),this.selectFrom=a,this.selectionRect.attr({x:a,width:0}).show()},d.prototype.endRange=function(a){var b,c;return this.selectFrom?(c=Math.min(this.selectFrom,a),b=Math.max(this.selectFrom,a),this.options.rangeSelect.call(this.el,{start:this.data[this.hitTest(c)].x,end:this.data[this.hitTest(b)].x}),this.selectFrom=null):void 0},d.prototype.resizeHandler=function(){return this.timeoutId=null,this.raphael.setSize(this.el.width(),this.el.height()),this.redraw()},d.prototype.hasToShow=function(a){return this.options.shown===!0||this.options.shown[a]===!0},d}(b.EventEmitter),b.parseDate=function(a){var b,c,d,e,f,g,h,i,j,k,l;return"number"==typeof a?a:(c=a.match(/^(\d+) Q(\d)$/),e=a.match(/^(\d+)-(\d+)$/),f=a.match(/^(\d+)-(\d+)-(\d+)$/),h=a.match(/^(\d+) W(\d+)$/),i=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),j=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),c?new Date(parseInt(c[1],10),3*parseInt(c[2],10)-1,1).getTime():e?new Date(parseInt(e[1],10),parseInt(e[2],10)-1,1).getTime():f?new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10)).getTime():h?(k=new Date(parseInt(h[1],10),0,1),4!==k.getDay()&&k.setMonth(0,1+(4-k.getDay()+7)%7),k.getTime()+6048e5*parseInt(h[2],10)):i?i[6]?(g=0,"Z"!==i[6]&&(g=60*parseInt(i[8],10)+parseInt(i[9],10),"+"===i[7]&&(g=0-g)),Date.UTC(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)+g)):new Date(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)).getTime():j?(l=parseFloat(j[6]),b=Math.floor(l),d=Math.round(1e3*(l-b)),j[8]?(g=0,"Z"!==j[8]&&(g=60*parseInt(j[10],10)+parseInt(j[11],10),"+"===j[9]&&(g=0-g)),Date.UTC(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10)+g,b,d)):new Date(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10),b,d).getTime()):new Date(parseInt(a,10),0,1).getTime())},b.Hover=function(){function c(c){null==c&&(c={}),this.options=a.extend({},b.Hover.defaults,c),this.el=a("<div class='"+this.options["class"]+"'></div>"),this.el.hide(),this.options.parent.append(this.el)}return c.defaults={"class":"morris-hover morris-default-style"},c.prototype.update=function(a,b,c,d){return a?(this.html(a),this.show(),this.moveTo(b,c,d)):this.hide()},c.prototype.html=function(a){return this.el.html(a)},c.prototype.moveTo=function(a,b,c){var d,e,f,g,h,i;return h=this.options.parent.innerWidth(),g=this.options.parent.innerHeight(),e=this.el.outerWidth(),d=this.el.outerHeight(),f=Math.min(Math.max(0,a-e/2),h-e),null!=b?c===!0?(i=b-d/2,0>i&&(i=0)):(i=b-d-10,0>i&&(i=b+10,i+d>g&&(i=g/2-d/2))):i=g/2-d/2,this.el.css({left:f+"px",top:parseInt(i)+"px"})},c.prototype.show=function(){return this.el.show()},c.prototype.hide=function(){return this.el.hide()},c}(),b.Line=function(c){function d(a){return this.hilight=f(this.hilight,this),this.onHoverOut=f(this.onHoverOut,this),this.onHoverMove=f(this.onHoverMove,this),this.onGridClick=f(this.onGridClick,this),this instanceof b.Line?void d.__super__.constructor.call(this,a):new b.Line(a)}return h(d,c),d.prototype.init=function(){return"always"!==this.options.hideHover?(this.hover=new b.Hover({parent:this.el}),this.on("hovermove",this.onHoverMove),this.on("hoverout",this.onHoverOut),this.on("gridclick",this.onGridClick)):void 0},d.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointStrokeWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],smooth:!0,shown:!0,xLabels:"auto",xLabelFormat:null,xLabelMargin:24,hideHover:!1,trendLine:!1,trendLineWidth:2,trendLineColors:["#689bc3","#a2b3bf","#64b764"]},d.prototype.calc=function(){return this.calcPoints(),this.generatePaths()},d.prototype.calcPoints=function(){var a,b,c,d,e,f;for(e=this.data,f=[],c=0,d=e.length;d>c;c++)a=e[c],a._x=this.transX(a.x),a._y=function(){var c,d,e,f;for(e=a.y,f=[],c=0,d=e.length;d>c;c++)b=e[c],f.push(null!=b?this.transY(b):b);return f}.call(this),f.push(a._ymax=Math.min.apply(Math,[this.bottom].concat(function(){var c,d,e,f;for(e=a._y,f=[],c=0,d=e.length;d>c;c++)b=e[c],null!=b&&f.push(b);return f}())));return f},d.prototype.hitTest=function(a){var b,c,d,e,f;if(0===this.data.length)return null;for(f=this.data.slice(1),b=d=0,e=f.length;e>d&&(c=f[b],!(a<(c._x+this.data[b]._x)/2));b=++d);return b},d.prototype.onGridClick=function(a,b){var c;return c=this.hitTest(a),this.fire("click",c,this.data[c].src,a,b)},d.prototype.onHoverMove=function(a){var b;return b=this.hitTest(a),this.displayHoverForRow(b)},d.prototype.onHoverOut=function(){return this.options.hideHover!==!1?this.displayHoverForRow(null):void 0},d.prototype.displayHoverForRow=function(a){var b;return null!=a?((b=this.hover).update.apply(b,this.hoverContentForRow(a)),this.hilight(a)):(this.hover.hide(),this.hilight())},d.prototype.hoverContentForRow=function(b){var c,d,e,f,g,h,i;for(e=this.data[b],c=a("<div class='morris-hover-row-label'>").text(e.label),c=c.prop("outerHTML"),i=e.y,d=g=0,h=i.length;h>g;d=++g)f=i[d],this.options.labels[d]!==!1&&(c+="<div class='morris-hover-point' style='color: "+this.colorFor(e,d,"label")+"'>\n  "+this.options.labels[d]+":\n  "+this.yLabelFormat(f,d)+"\n</div>");return"function"==typeof this.options.hoverCallback&&(c=this.options.hoverCallback(b,this.options,c,e.src)),[c,e._x,e._ymax]},d.prototype.generatePaths=function(){var a,c,d,e;return this.paths=function(){var f,g,h,j;for(j=[],c=f=0,g=this.options.ykeys.length;g>=0?g>f:f>g;c=g>=0?++f:--f)e="boolean"==typeof this.options.smooth?this.options.smooth:(h=this.options.ykeys[c],i.call(this.options.smooth,h)>=0),a=function(){var a,b,e,f;for(e=this.data,f=[],a=0,b=e.length;b>a;a++)d=e[a],void 0!==d._y[c]&&f.push({x:d._x,y:d._y[c]});return f}.call(this),j.push(a.length>1?b.Line.createPath(a,e,this.bottom):null);return j}.call(this)},d.prototype.draw=function(){var a;return((a=this.options.axes)===!0||"both"===a||"x"===a)&&this.drawXAxis(),this.drawSeries(),this.options.hideHover===!1?this.displayHoverForRow(this.data.length-1):void 0},d.prototype.drawXAxis=function(){var a,c,d,e,f,g,h,i,j,k,l=this;for(h=this.bottom+this.options.padding/2,f=null,e=null,a=function(a,b){var c,d,g,i,j;return c=l.drawXAxisLabel(l.transX(b),h,a),j=c.getBBox(),c.transform("r"+-l.options.xLabelAngle),d=c.getBBox(),c.transform("t0,"+d.height/2+"..."),0!==l.options.xLabelAngle&&(i=-.5*j.width*Math.cos(l.options.xLabelAngle*Math.PI/180),c.transform("t"+i+",0...")),d=c.getBBox(),(null==f||f>=d.x+d.width||null!=e&&e>=d.x)&&d.x>=0&&d.x+d.width<l.el.width()?(0!==l.options.xLabelAngle&&(g=1.25*l.options.gridTextSize/Math.sin(l.options.xLabelAngle*Math.PI/180),e=d.x-g),f=d.x-l.options.xLabelMargin):c.remove()},d=this.options.parseTime?1===this.data.length&&"auto"===this.options.xLabels?[[this.data[0].label,this.data[0].x]]:b.labelSeries(this.xmin,this.xmax,this.width,this.options.xLabels,this.options.xLabelFormat):function(){var a,b,c,d;for(c=this.data,d=[],a=0,b=c.length;b>a;a++)g=c[a],d.push([g.label,g.x]);return d}.call(this),d.reverse(),k=[],i=0,j=d.length;j>i;i++)c=d[i],k.push(a(c[0],c[1]));return k},d.prototype.drawSeries=function(){var a,b,c,d,e,f;for(this.seriesPoints=[],a=b=d=this.options.ykeys.length-1;0>=d?0>=b:b>=0;a=0>=d?++b:--b)this.hasToShow(a)&&((this.options.trendLine!==!1&&this.options.trendLine===!0||this.options.trendLine[a]===!0)&&this._drawTrendLine(a),this._drawLineFor(a));for(f=[],a=c=e=this.options.ykeys.length-1;0>=e?0>=c:c>=0;a=0>=e?++c:--c)f.push(this.hasToShow(a)?this._drawPointFor(a):void 0);return f},d.prototype._drawPointFor=function(a){var b,c,d,e,f,g;for(this.seriesPoints[a]=[],f=this.data,g=[],d=0,e=f.length;e>d;d++)c=f[d],b=null,null!=c._y[a]&&(b=this.drawLinePoint(c._x,c._y[a],this.colorFor(c,a,"point"),a)),g.push(this.seriesPoints[a].push(b));return g},d.prototype._drawLineFor=function(a){var b;return b=this.paths[a],null!==b?this.drawLinePath(b,this.colorFor(null,a,"line"),a):void 0},d.prototype._drawTrendLine=function(a){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;for(h=0,k=0,i=0,j=0,f=0,q=this.data,o=0,p=q.length;p>o;o++)l=q[o],m=l.x,n=l.y[a],void 0!==n&&(f+=1,h+=m,k+=n,i+=m*m,j+=m*n);return c=(f*j-h*k)/(f*i-h*h),d=k/f-c*h/f,e=[{},{}],e[0].x=this.transX(this.data[0].x),e[0].y=this.transY(this.data[0].x*c+d),e[1].x=this.transX(this.data[this.data.length-1].x),e[1].y=this.transY(this.data[this.data.length-1].x*c+d),g=b.Line.createPath(e,!1,this.bottom),g=this.raphael.path(g).attr("stroke",this.colorFor(null,a,"trendLine")).attr("stroke-width",this.options.trendLineWidth)},d.createPath=function(a,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;for(k="",c&&(g=b.Line.gradients(a)),l={y:null},h=q=0,r=a.length;r>q;h=++q)e=a[h],null!=e.y&&(null!=l.y?c?(f=g[h],j=g[h-1],i=(e.x-l.x)/4,m=l.x+i,o=Math.min(d,l.y+i*j),n=e.x-i,p=Math.min(d,e.y-i*f),k+="C"+m+","+o+","+n+","+p+","+e.x+","+e.y):k+="L"+e.x+","+e.y:c&&null==g[h]||(k+="M"+e.x+","+e.y)),l=e;return k},d.gradients=function(a){var b,c,d,e,f,g,h,i;for(c=function(a,b){return(a.y-b.y)/(a.x-b.x)},i=[],d=g=0,h=a.length;h>g;d=++g)b=a[d],null!=b.y?(e=a[d+1]||{y:null},f=a[d-1]||{y:null},i.push(null!=f.y&&null!=e.y?c(f,e):null!=f.y?c(f,b):null!=e.y?c(b,e):null)):i.push(null);return i},d.prototype.hilight=function(a){var b,c,d,e,f;if(null!==this.prevHilight&&this.prevHilight!==a)for(b=c=0,e=this.seriesPoints.length-1;e>=0?e>=c:c>=e;b=e>=0?++c:--c)this.seriesPoints[b][this.prevHilight]&&this.seriesPoints[b][this.prevHilight].animate(this.pointShrinkSeries(b));if(null!==a&&this.prevHilight!==a)for(b=d=0,f=this.seriesPoints.length-1;f>=0?f>=d:d>=f;b=f>=0?++d:--d)this.seriesPoints[b][a]&&this.seriesPoints[b][a].animate(this.pointGrowSeries(b));return this.prevHilight=a},d.prototype.colorFor=function(a,b,c){return"function"==typeof this.options.lineColors?this.options.lineColors.call(this,a,b,c):"point"===c?this.options.pointFillColors[b%this.options.pointFillColors.length]||this.options.lineColors[b%this.options.lineColors.length]:"line"===c?this.options.lineColors[b%this.options.lineColors.length]:this.options.trendLineColors[b%this.options.trendLineColors.length]},d.prototype.drawXAxisLabel=function(a,b,c){return this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor)},d.prototype.drawLinePath=function(a,b,c){return this.raphael.path(a).attr("stroke",b).attr("stroke-width",this.lineWidthForSeries(c))},d.prototype.drawLinePoint=function(a,b,c,d){return this.raphael.circle(a,b,this.pointSizeForSeries(d)).attr("fill",c).attr("stroke-width",this.pointStrokeWidthForSeries(d)).attr("stroke",this.pointStrokeColorForSeries(d))},d.prototype.pointStrokeWidthForSeries=function(a){return this.options.pointStrokeWidths[a%this.options.pointStrokeWidths.length]},d.prototype.pointStrokeColorForSeries=function(a){return this.options.pointStrokeColors[a%this.options.pointStrokeColors.length]},d.prototype.lineWidthForSeries=function(a){return this.options.lineWidth instanceof Array?this.options.lineWidth[a%this.options.lineWidth.length]:this.options.lineWidth},d.prototype.pointSizeForSeries=function(a){return this.options.pointSize instanceof Array?this.options.pointSize[a%this.options.pointSize.length]:this.options.pointSize},d.prototype.pointGrowSeries=function(a){return 0!==this.pointSizeForSeries(a)?Raphael.animation({r:this.pointSizeForSeries(a)+3},25,"linear"):void 0},d.prototype.pointShrinkSeries=function(a){return Raphael.animation({r:this.pointSizeForSeries(a)},25,"linear")},d}(b.Grid),b.labelSeries=function(c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r;if(j=200*(d-c)/e,i=new Date(c),n=b.LABEL_SPECS[f],void 0===n)for(r=b.AUTO_LABEL_ORDER,p=0,q=r.length;q>p;p++)if(k=r[p],m=b.LABEL_SPECS[k],j>=m.span){n=m;break}for(void 0===n&&(n=b.LABEL_SPECS.second),g&&(n=a.extend({},n,{fmt:g})),h=n.start(i),l=[];(o=h.getTime())<=d;)o>=c&&l.push([n.fmt(h),o]),n.incr(h);return l},c=function(a){return{span:60*a*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())},incr:function(b){return b.setUTCMinutes(b.getUTCMinutes()+a)}}},d=function(a){return{span:1e3*a,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())+":"+b.pad2(a.getSeconds())},incr:function(b){return b.setUTCSeconds(b.getUTCSeconds()+a)}}},b.LABEL_SPECS={decade:{span:1728e8,start:function(a){return new Date(a.getFullYear()-a.getFullYear()%10,0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+10)}},year:{span:1728e7,start:function(a){return new Date(a.getFullYear(),0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+1)}},month:{span:24192e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),1)},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)},incr:function(a){return a.setMonth(a.getMonth()+1)}},week:{span:6048e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+7)}},day:{span:864e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+1)}},hour:c(60),"30min":c(30),"15min":c(15),"10min":c(10),"5min":c(5),minute:c(1),"30sec":d(30),"15sec":d(15),"10sec":d(10),"5sec":d(5),second:d(1)},b.AUTO_LABEL_ORDER=["decade","year","month","week","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],b.Area=function(c){function d(c){var f;return this instanceof b.Area?(f=a.extend({},e,c),this.cumulative=!f.behaveLikeLine,"auto"===f.fillOpacity&&(f.fillOpacity=f.behaveLikeLine?.8:1),void d.__super__.constructor.call(this,f)):new b.Area(c)}var e;return h(d,c),e={fillOpacity:"auto",behaveLikeLine:!1},d.prototype.calcPoints=function(){var a,b,c,d,e,f,g;for(f=this.data,g=[],d=0,e=f.length;e>d;d++)a=f[d],a._x=this.transX(a.x),b=0,a._y=function(){var d,e,f,g;for(f=a.y,g=[],d=0,e=f.length;e>d;d++)c=f[d],this.options.behaveLikeLine?g.push(this.transY(c)):(b+=c||0,g.push(this.transY(b)));return g}.call(this),g.push(a._ymax=Math.max.apply(Math,a._y));return g},d.prototype.drawSeries=function(){var a,b,c,d,e,f,g,h;for(this.seriesPoints=[],b=this.options.behaveLikeLine?function(){f=[];for(var a=0,b=this.options.ykeys.length-1;b>=0?b>=a:a>=b;b>=0?a++:a--)f.push(a);return f}.apply(this):function(){g=[];for(var a=e=this.options.ykeys.length-1;0>=e?0>=a:a>=0;0>=e?a++:a--)g.push(a);return g}.apply(this),h=[],c=0,d=b.length;d>c;c++)a=b[c],this._drawFillFor(a),this._drawLineFor(a),h.push(this._drawPointFor(a));return h},d.prototype._drawFillFor=function(a){var b;return b=this.paths[a],null!==b?(b+="L"+this.transX(this.xmax)+","+this.bottom+"L"+this.transX(this.xmin)+","+this.bottom+"Z",this.drawFilledPath(b,this.fillForSeries(a))):void 0},d.prototype.fillForSeries=function(a){var b;return b=Raphael.rgb2hsl(this.colorFor(this.data[a],a,"line")),Raphael.hsl(b.h,this.options.behaveLikeLine?.9*b.s:.75*b.s,Math.min(.98,this.options.behaveLikeLine?1.2*b.l:1.25*b.l))},d.prototype.drawFilledPath=function(a,b){return this.raphael.path(a).attr("fill",b).attr("fill-opacity",this.options.fillOpacity).attr("stroke","none")},d}(b.Line),b.Bar=function(c){function d(c){return this.onHoverOut=f(this.onHoverOut,this),this.onHoverMove=f(this.onHoverMove,this),this.onGridClick=f(this.onGridClick,this),this instanceof b.Bar?void d.__super__.constructor.call(this,a.extend({},c,{parseTime:!1})):new b.Bar(c)}return h(d,c),d.prototype.init=function(){return this.cumulative=this.options.stacked,"always"!==this.options.hideHover?(this.hover=new b.Hover({parent:this.el}),this.on("hovermove",this.onHoverMove),this.on("hoverout",this.onHoverOut),this.on("gridclick",this.onGridClick)):void 0},d.prototype.defaults={barSizeRatio:.75,barGap:3,barColors:["#0b62a4","#7a92a3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],barOpacity:1,barRadius:[0,0,0,0],xLabelMargin:50,horizontal:!1,shown:!0},d.prototype.calc=function(){var a;return this.calcBars(),this.options.hideHover===!1?(a=this.hover).update.apply(a,this.hoverContentForRow(this.data.length-1)):void 0},d.prototype.calcBars=function(){var a,b,c,d,e,f,g;for(f=this.data,g=[],a=d=0,e=f.length;e>d;a=++d)b=f[a],b._x=this.xStart+this.xSize*(a+.5)/this.data.length,g.push(b._y=function(){var a,d,e,f;for(e=b.y,f=[],a=0,d=e.length;d>a;a++)c=e[a],f.push(null!=c?this.transY(c):null);return f}.call(this));return g},d.prototype.draw=function(){var a;return((a=this.options.axes)===!0||"both"===a||"x"===a)&&this.drawXAxis(),this.drawSeries()},d.prototype.drawXAxis=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;for(b=this.options.horizontal?this.getYAxisLabelX():this.getXAxisLabelY(),j=null,i=null,q=[],c=o=0,p=this.data.length;p>=0?p>o:o>p;c=p>=0?++o:--o)k=this.data[this.data.length-1-c],d=this.options.horizontal?this.drawYAxisLabel(b,k._x-.5*this.options.gridTextSize,k.label):this.drawXAxisLabel(k._x,b,k.label),a=this.options.horizontal?0:this.options.xLabelAngle,n=d.getBBox(),d.transform("r"+-a),e=d.getBBox(),d.transform("t0,"+e.height/2+"..."),0!==a&&(h=-.5*n.width*Math.cos(a*Math.PI/180),d.transform("t"+h+",0...")),this.options.horizontal?(m=e.y,l=e.height,g=this.el.height()):(m=e.x,l=e.width,g=this.el.width()),(null==j||j>=m+l||null!=i&&i>=m)&&m>=0&&g>m+l?(0!==a&&(f=1.25*this.options.gridTextSize/Math.sin(a*Math.PI/180),i=m-f),q.push(this.options.horizontal?j=m:j=m-this.options.xLabelMargin)):q.push(d.remove());return q},d.prototype.getXAxisLabelY=function(){return this.bottom+(this.options.xAxisLabelTopPadding||this.options.padding/2)},d.prototype.drawSeries=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(c=this.xSize/this.options.data.length,this.options.stacked)i=1;else for(i=0,d=q=0,r=this.options.ykeys.length-1;r>=0?r>=q:q>=r;d=r>=0?++q:--q)this.hasToShow(d)&&(i+=1);return a=(c*this.options.barSizeRatio-this.options.barGap*(i-1))/i,this.options.barSize&&(a=Math.min(a,this.options.barSize)),m=c-a*i-this.options.barGap*(i-1),h=m/2,p=this.ymin<=0&&this.ymax>=0?this.transY(0):null,this.bars=function(){var d,i,m,q;for(m=this.data,q=[],e=d=0,i=m.length;i>d;e=++d)j=m[e],f=0,q.push(function(){var d,i,m,q;for(m=j._y,q=[],k=d=0,i=m.length;i>d;k=++d)o=m[k],this.hasToShow(k)&&(null!==o?(p?(n=Math.min(o,p),b=Math.max(o,p)):(n=o,b=this.bottom),g=this.xStart+e*c+h,this.options.stacked||(g+=k*(a+this.options.barGap)),l=b-n,this.options.verticalGridCondition&&this.options.verticalGridCondition(j.x)&&(this.options.horizontal?this.drawBar(this.yStart,this.xStart+e*c,this.ySize,c,this.options.verticalGridColor,this.options.verticalGridOpacity,this.options.barRadius):this.drawBar(this.xStart+e*c,this.yEnd,c,this.ySize,this.options.verticalGridColor,this.options.verticalGridOpacity,this.options.barRadius)),this.options.stacked&&(n-=f),this.options.horizontal?(this.drawBar(n,g,l,a,this.colorFor(j,k,"bar"),this.options.barOpacity,this.options.barRadius),q.push(f-=l)):(this.drawBar(g,n,a,l,this.colorFor(j,k,"bar"),this.options.barOpacity,this.options.barRadius),q.push(f+=l))):q.push(null));return q}.call(this));return q}.call(this)},d.prototype.colorFor=function(a,b,c){var d,e;return"function"==typeof this.options.barColors?(d={x:a.x,y:a.y[b],label:a.label},e={index:b,key:this.options.ykeys[b],label:this.options.labels[b]},this.options.barColors.call(this,d,e,c)):this.options.barColors[b%this.options.barColors.length]},d.prototype.hitTest=function(a,b){var c;return 0===this.data.length?null:(c=this.options.horizontal?b:a,c=Math.max(Math.min(c,this.xEnd),this.xStart),Math.min(this.data.length-1,Math.floor((c-this.xStart)/(this.xSize/this.data.length))))
+},d.prototype.onGridClick=function(a,b){var c;return c=this.hitTest(a,b),this.fire("click",c,this.data[c].src,a,b)},d.prototype.onHoverMove=function(a,b){var c,d;return c=this.hitTest(a,b),(d=this.hover).update.apply(d,this.hoverContentForRow(c))},d.prototype.onHoverOut=function(){return this.options.hideHover!==!1?this.hover.hide():void 0},d.prototype.hoverContentForRow=function(b){var c,d,e,f,g,h,i,j;for(e=this.data[b],c=a("<div class='morris-hover-row-label'>").text(e.label),c=c.prop("outerHTML"),j=e.y,d=h=0,i=j.length;i>h;d=++h)g=j[d],this.options.labels[d]!==!1&&(c+="<div class='morris-hover-point' style='color: "+this.colorFor(e,d,"label")+"'>\n  "+this.options.labels[d]+":\n  "+this.yLabelFormat(g,d)+"\n</div>");return"function"==typeof this.options.hoverCallback&&(c=this.options.hoverCallback(b,this.options,c,e.src)),this.options.horizontal?(f=this.left+.5*this.width,g=this.top+(b+.5)*this.height/this.data.length,[c,f,g,!0]):(f=this.left+(b+.5)*this.width/this.data.length,[c,f])},d.prototype.drawXAxisLabel=function(a,b,c){var d;return d=this.raphael.text(a,b,c).attr("font-size",this.options.gridTextSize).attr("font-family",this.options.gridTextFamily).attr("font-weight",this.options.gridTextWeight).attr("fill",this.options.gridTextColor)},d.prototype.drawBar=function(a,b,c,d,e,f,g){var h,i;return h=Math.max.apply(Math,g),i=0===h||h>d?this.raphael.rect(a,b,c,d):this.raphael.path(this.roundedRect(a,b,c,d,g)),i.attr("fill",e).attr("fill-opacity",f).attr("stroke","none")},d.prototype.roundedRect=function(a,b,c,d,e){return null==e&&(e=[0,0,0,0]),["M",a,e[0]+b,"Q",a,b,a+e[0],b,"L",a+c-e[1],b,"Q",a+c,b,a+c,b+e[1],"L",a+c,b+d-e[2],"Q",a+c,b+d,a+c-e[2],b+d,"L",a+e[3],b+d,"Q",a,b+d,a,b+d-e[3],"Z"]},d}(b.Grid),b.Donut=function(c){function d(c){this.resizeHandler=f(this.resizeHandler,this),this.select=f(this.select,this),this.click=f(this.click,this);var d=this;if(!(this instanceof b.Donut))return new b.Donut(c);if(this.options=a.extend({},this.defaults,c),this.el=a("string"==typeof c.element?document.getElementById(c.element):c.element),null===this.el||0===this.el.length)throw new Error("Graph placeholder not found.");void 0!==c.data&&0!==c.data.length&&(this.raphael=new Raphael(this.el[0]),this.options.resize&&a(window).bind("resize",function(){return null!=d.timeoutId&&window.clearTimeout(d.timeoutId),d.timeoutId=window.setTimeout(d.resizeHandler,100)}),this.setData(c.data))}return h(d,c),d.prototype.defaults={colors:["#0B62A4","#3980B5","#679DC6","#95BBD7","#B0CCE1","#095791","#095085","#083E67","#052C48","#042135"],backgroundColor:"#FFFFFF",labelColor:"#000000",formatter:b.commas,resize:!1},d.prototype.redraw=function(){var a,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;for(this.raphael.clear(),c=this.el.width()/2,d=this.el.height()/2,n=(Math.min(c,d)-10)/3,l=0,u=this.values,o=0,r=u.length;r>o;o++)m=u[o],l+=m;for(i=5/(2*n),a=1.9999*Math.PI-i*this.data.length,g=0,f=0,this.segments=[],v=this.values,e=p=0,s=v.length;s>p;e=++p)m=v[e],j=g+i+a*(m/l),k=new b.DonutSegment(c,d,2*n,n,g,j,this.data[e].color||this.options.colors[f%this.options.colors.length],this.options.backgroundColor,f,this.raphael),k.render(),this.segments.push(k),k.on("hover",this.select),k.on("click",this.click),g=j,f+=1;for(this.text1=this.drawEmptyDonutLabel(c,d-10,this.options.labelColor,15,800),this.text2=this.drawEmptyDonutLabel(c,d+10,this.options.labelColor,14),h=Math.max.apply(Math,this.values),f=0,w=this.values,x=[],q=0,t=w.length;t>q;q++){if(m=w[q],m===h){this.select(f);break}x.push(f+=1)}return x},d.prototype.setData=function(a){var b;return this.data=a,this.values=function(){var a,c,d,e;for(d=this.data,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(parseFloat(b.value));return e}.call(this),this.redraw()},d.prototype.click=function(a){return this.fire("click",a,this.data[a])},d.prototype.select=function(a){var b,c,d,e,f,g;for(g=this.segments,e=0,f=g.length;f>e;e++)c=g[e],c.deselect();return d=this.segments[a],d.select(),b=this.data[a],this.setLabels(b.label,this.options.formatter(b.value,b))},d.prototype.setLabels=function(a,b){var c,d,e,f,g,h,i,j;return c=2*(Math.min(this.el.width()/2,this.el.height()/2)-10)/3,f=1.8*c,e=c/2,d=c/3,this.text1.attr({text:a,transform:""}),g=this.text1.getBBox(),h=Math.min(f/g.width,e/g.height),this.text1.attr({transform:"S"+h+","+h+","+(g.x+g.width/2)+","+(g.y+g.height)}),this.text2.attr({text:b,transform:""}),i=this.text2.getBBox(),j=Math.min(f/i.width,d/i.height),this.text2.attr({transform:"S"+j+","+j+","+(i.x+i.width/2)+","+i.y})},d.prototype.drawEmptyDonutLabel=function(a,b,c,d,e){var f;return f=this.raphael.text(a,b,"").attr("font-size",d).attr("fill",c),null!=e&&f.attr("font-weight",e),f},d.prototype.resizeHandler=function(){return this.timeoutId=null,this.raphael.setSize(this.el.width(),this.el.height()),this.redraw()},d}(b.EventEmitter),b.DonutSegment=function(a){function b(a,b,c,d,e,g,h,i,j,k){this.cx=a,this.cy=b,this.inner=c,this.outer=d,this.color=h,this.backgroundColor=i,this.index=j,this.raphael=k,this.deselect=f(this.deselect,this),this.select=f(this.select,this),this.sin_p0=Math.sin(e),this.cos_p0=Math.cos(e),this.sin_p1=Math.sin(g),this.cos_p1=Math.cos(g),this.is_long=g-e>Math.PI?1:0,this.path=this.calcSegment(this.inner+3,this.inner+this.outer-5),this.selectedPath=this.calcSegment(this.inner+3,this.inner+this.outer),this.hilight=this.calcArc(this.inner)}return h(b,a),b.prototype.calcArcPoints=function(a){return[this.cx+a*this.sin_p0,this.cy+a*this.cos_p0,this.cx+a*this.sin_p1,this.cy+a*this.cos_p1]},b.prototype.calcSegment=function(a,b){var c,d,e,f,g,h,i,j,k,l;return k=this.calcArcPoints(a),c=k[0],e=k[1],d=k[2],f=k[3],l=this.calcArcPoints(b),g=l[0],i=l[1],h=l[2],j=l[3],"M"+c+","+e+("A"+a+","+a+",0,"+this.is_long+",0,"+d+","+f)+("L"+h+","+j)+("A"+b+","+b+",0,"+this.is_long+",1,"+g+","+i)+"Z"},b.prototype.calcArc=function(a){var b,c,d,e,f;return f=this.calcArcPoints(a),b=f[0],d=f[1],c=f[2],e=f[3],"M"+b+","+d+("A"+a+","+a+",0,"+this.is_long+",0,"+c+","+e)},b.prototype.render=function(){var a=this;return this.arc=this.drawDonutArc(this.hilight,this.color),this.seg=this.drawDonutSegment(this.path,this.color,this.backgroundColor,function(){return a.fire("hover",a.index)},function(){return a.fire("click",a.index)})},b.prototype.drawDonutArc=function(a,b){return this.raphael.path(a).attr({stroke:b,"stroke-width":2,opacity:0})},b.prototype.drawDonutSegment=function(a,b,c,d,e){return this.raphael.path(a).attr({fill:b,stroke:c,"stroke-width":3}).hover(d).click(e)},b.prototype.select=function(){return this.selected?void 0:(this.seg.animate({path:this.selectedPath},150,"<>"),this.arc.animate({opacity:1},150,"<>"),this.selected=!0)},b.prototype.deselect=function(){return this.selected?(this.seg.animate({path:this.path},150,"<>"),this.arc.animate({opacity:0},150,"<>"),this.selected=!1):void 0},b}(b.EventEmitter)}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/plugins/morris/raphael.min.js b/src/main/resources/META-INF/resources/designer/lib/plugins/morris/raphael.min.js
new file mode 100644 (file)
index 0000000..b40a005
--- /dev/null
@@ -0,0 +1,11 @@
+// â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”\90 \\
+// â”‚ Raphaël 2.1.2 - JavaScript Vector Library                          â”‚ \\
+// â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤ \\
+// â”‚ Copyright Â© 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com)    â”‚ \\
+// â”‚ Copyright Â© 2008-2012 Sencha Labs (http://sencha.com)              â”‚ \\
+// â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤ \\
+// â”‚ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
+// â””────────────────────────────────────────────────────────────────────┘ \\
+!function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g="*",h=function(){},i=function(a,b){return a-b},j={n:{}},k=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=k.listeners(a),j=0,l=[],m={},n=[],o=b;b=a,c=0;for(var p=0,q=h.length;q>p;p++)"zIndex"in h[p]&&(l.push(h[p].zIndex),h[p].zIndex<0&&(m[h[p].zIndex]=h[p]));for(l.sort(i);l[j]<0;)if(e=m[l[j++]],n.push(e.apply(d,g)),c)return c=f,n;for(p=0;q>p;p++)if(e=h[p],"zIndex"in e)if(e.zIndex==l[j]){if(n.push(e.apply(d,g)),c)break;do if(j++,e=m[l[j]],e&&n.push(e.apply(d,g)),c)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),c)break;return c=f,b=o,n.length?n:null};k._events=j,k.listeners=function(a){var b,c,d,e,h,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,h=m.length;h>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[g]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},k.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(f),d=j,e=0,g=c.length;g>e;e++)d=d.n,d=d.hasOwnProperty(c[e])&&d[c[e]]||(d[c[e]]={n:{}});for(d.f=d.f||[],e=0,g=d.f.length;g>e;e++)if(d.f[e]==b)return h;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},k.f=function(a){var b=[].slice.call(arguments,1);return function(){k.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},k.stop=function(){c=1},k.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},k.nts=function(){return b.split(f)},k.off=k.unbind=function(a,b){if(!a)return k._events=j={n:{}},void 0;var c,d,h,i,l,m,n,o=a.split(f),p=[j];for(i=0,l=o.length;l>i;i++)for(m=0;m<p.length;m+=h.length-2){if(h=[m,1],c=p[m].n,o[i]!=g)c[o[i]]&&h.push(c[o[i]]);else for(d in c)c[e](d)&&h.push(c[d]);p.splice.apply(p,h)}for(i=0,l=p.length;l>i;i++)for(c=p[i];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(d in c.n)if(c.n[e](d)&&c.n[d].f){var q=c.n[d].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[d].f}}else{delete c.f;for(d in c.n)c.n[e](d)&&c.n[d].f&&delete c.n[d].f}c=c.n}},k.once=function(a,b){var c=function(){return k.unbind(a,c),b.apply(this,arguments)};return k.on(a,c)},k.version=d,k.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=k:"undefined"!=typeof define?define("eve",[],function(){return k}):a.eve=k}(this),function(a,b){"function"==typeof define&&define.amd?define(["eve"],function(c){return b(a,c)}):b(a,a.eve)}(this,function(a,b){function c(a){if(c.is(a,"function"))return u?a():b.on("raphael.DOMload",a);if(c.is(a,V))return c._engine.create[D](c,a.splice(0,3+c.is(a[0],T))).add(a);var d=Array.prototype.slice.call(arguments,0);if(c.is(d[d.length-1],"function")){var e=d.pop();return u?e.call(c._engine.create[D](c,d)):b.on("raphael.DOMload",function(){e.call(c._engine.create[D](c,d))})}return c._engine.create[D](c,arguments)}function d(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=d(a[c]));return b}function e(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function f(a,b,c){function d(){var f=Array.prototype.slice.call(arguments,0),g=f.join("â\90€"),h=d.cache=d.cache||{},i=d.count=d.count||[];return h[z](g)?(e(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[D](b,f),c?c(h[g]):h[g])}return d}function g(){return this.hex}function h(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function i(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function j(a,b,c,d,e,f,g,h,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=i(q,a,c,e,g),s=i(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return k*o}function k(a,b,c,d,e,f,g,h,i){if(!(0>i||j(a,b,c,d,e,f,g,h)<i)){var k,l=1,m=l/2,n=l-m,o=.01;for(k=j(a,b,c,d,e,f,g,h,n);Q(k-i)>o;)m/=2,n+=(i>k?1:-1)*m,k=j(a,b,c,d,e,f,g,h,n);return n}}function l(a,b,c,d,e,f,g,h){if(!(O(a,c)<P(e,g)||P(a,c)>O(e,g)||O(b,d)<P(f,h)||P(b,d)>O(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+O(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+O(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+O(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+O(f,h).toFixed(2)))return{x:l,y:m}}}}function m(a,b,d){var e=c.bezierBBox(a),f=c.bezierBBox(b);if(!c.isBBoxIntersect(e,f))return d?0:[];for(var g=j.apply(0,a),h=j.apply(0,b),i=O(~~(g/5),1),k=O(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;i+1>q;q++){var r=c.findDotsAtSegment.apply(c,a.concat(q/i));m.push({x:r.x,y:r.y,t:q/i})}for(q=0;k+1>q;q++)r=c.findDotsAtSegment.apply(c,b.concat(q/k)),n.push({x:r.x,y:r.y,t:q/k});for(q=0;i>q;q++)for(var s=0;k>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=Q(u.x-t.x)<.001?"y":"x",y=Q(w.x-v.x)<.001?"y":"x",z=l(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+Q((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+Q((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:P(A,1),t2:P(B,1)}))}}return p}function n(a,b,d){a=c._path2curve(a),b=c._path2curve(b);for(var e,f,g,h,i,j,k,l,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0])e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=b.length;u>t;t++){var v=b[t];if("M"==v[0])g=k=v[1],h=l=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,l,k,l],g=k,h=l);var w=m(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function o(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function p(){return this.x+H+this.y+H+this.width+" Ã— "+this.height}function q(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,Q(f)<b)return e;if(h=(3*l*e+2*k)*e+j,Q(h)<1e-6)break;e-=f/h}if(c=0,d=1,e=a,c>e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),Q(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function r(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[z](e)&&(d[_(e)]=a[e],c.push(_(e)));c.sort(lb)}this.anim=d,this.top=c[c.length-1],this.percents=c}function s(a,d,e,f,g,h){e=_(e);var i,j,k,l,m,n,p=a.ms,r={},s={},t={};if(f)for(v=0,x=ic.length;x>v;v++){var u=ic[v];if(u.el.id==d.id&&u.anim==a){u.percent!=e?(ic.splice(v,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var v=0,x=a.percents.length;x>v;v++){if(a.percents[v]==e||a.percents[v]>f*a.top){e=a.percents[v],m=a.percents[v-1]||0,p=p/a.top*(e-m),l=a.percents[v+1],i=a.anim[e];break}f&&d.attr(a.anim[a.percents[v]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var y in i)if(i[z](y)&&(db[z](y)||d.paper.customAttributes[z](y)))switch(r[y]=d.attr(y),null==r[y]&&(r[y]=cb[y]),s[y]=i[y],db[y]){case T:t[y]=(s[y]-r[y])/p;break;case"colour":r[y]=c.getRGB(r[y]);var A=c.getRGB(s[y]);t[y]={r:(A.r-r[y].r)/p,g:(A.g-r[y].g)/p,b:(A.b-r[y].b)/p};break;case"path":var B=Kb(r[y],s[y]),C=B[1];for(r[y]=B[0],t[y]=[],v=0,x=r[y].length;x>v;v++){t[y][v]=[0];for(var D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(C[v][D]-r[y][v][D])/p}break;case"transform":var G=d._,H=Pb(G[y],s[y]);if(H)for(r[y]=H.from,s[y]=H.to,t[y]=[],t[y].real=!0,v=0,x=r[y].length;x>v;v++)for(t[y][v]=[r[y][v][0]],D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(s[y][v][D]-r[y][v][D])/p;else{var K=d.matrix||new o,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[y]=[K.a,K.b,K.c,K.d,K.e,K.f],Nb(L,s[y]),s[y]=L._.transform,t[y]=[(L.matrix.a-K.a)/p,(L.matrix.b-K.b)/p,(L.matrix.c-K.c)/p,(L.matrix.d-K.d)/p,(L.matrix.e-K.e)/p,(L.matrix.f-K.f)/p]}break;case"csv":var M=I(i[y])[J](w),N=I(r[y])[J](w);if("clip-rect"==y)for(r[y]=N,t[y]=[],v=N.length;v--;)t[y][v]=(M[v]-r[y][v])/p;s[y]=M;break;default:for(M=[][E](i[y]),N=[][E](r[y]),t[y]=[],v=d.paper.customAttributes[y].length;v--;)t[y][v]=((M[v]||0)-(N[v]||0))/p}var O=i.easing,P=c.easing_formulas[O];if(!P)if(P=I(O).match(Z),P&&5==P.length){var Q=P;P=function(a){return q(a,+Q[1],+Q[2],+Q[3],+Q[4],p)}}else P=nb;if(n=i.start||a.start||+new Date,u={anim:a,percent:e,timestamp:n,start:n+(a.del||0),status:0,initstatus:f||0,stop:!1,ms:p,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||a.times,origin:d.attr(),totalOrigin:g},ic.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-p*f,1==ic.length))return kc();k&&(u.start=new Date-u.ms*f),1==ic.length&&jc(kc)}b("raphael.anim.start."+d.id,d,a)}}function t(a){for(var b=0;b<ic.length;b++)ic[b].el.paper==a&&ic.splice(b--,1)}c.version="2.1.2",c.eve=b;var u,v,w=/[, ]+/,x={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},y=/\{(\d+)\}/g,z="hasOwnProperty",A={doc:document,win:a},B={was:Object.prototype[z].call(A.win,"Raphael"),is:A.win.Raphael},C=function(){this.ca=this.customAttributes={}},D="apply",E="concat",F="ontouchstart"in A.win||A.win.DocumentTouch&&A.doc instanceof DocumentTouch,G="",H=" ",I=String,J="split",K="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[J](H),L={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},M=I.prototype.toLowerCase,N=Math,O=N.max,P=N.min,Q=N.abs,R=N.pow,S=N.PI,T="number",U="string",V="array",W=Object.prototype.toString,X=(c._ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i),Y={NaN:1,Infinity:1,"-Infinity":1},Z=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,$=N.round,_=parseFloat,ab=parseInt,bb=I.prototype.toUpperCase,cb=c._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/","letter-spacing":0,opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0},db=c._availableAnimAttrs={blur:T,"clip-rect":"csv",cx:T,cy:T,fill:"colour","fill-opacity":T,"font-size":T,height:T,opacity:T,path:"path",r:T,rx:T,ry:T,stroke:"colour","stroke-opacity":T,"stroke-width":T,transform:"transform",width:T,x:T,y:T},eb=/[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,fb={hs:1,rg:1},gb=/,?([achlmqrstvxz]),?/gi,hb=/([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,ib=/([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi,jb=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi,kb=(c._radial_gradient=/^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,{}),lb=function(a,b){return _(a)-_(b)},mb=function(){},nb=function(a){return a},ob=c._rectPath=function(a,b,c,d,e){return e?[["M",a+e,b],["l",c-2*e,0],["a",e,e,0,0,1,e,e],["l",0,d-2*e],["a",e,e,0,0,1,-e,e],["l",2*e-c,0],["a",e,e,0,0,1,-e,-e],["l",0,2*e-d],["a",e,e,0,0,1,e,-e],["z"]]:[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]]},pb=function(a,b,c,d){return null==d&&(d=c),[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]]},qb=c._getPath={path:function(a){return a.attr("path")},circle:function(a){var b=a.attrs;return pb(b.cx,b.cy,b.r)},ellipse:function(a){var b=a.attrs;return pb(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=a.attrs;return ob(b.x,b.y,b.width,b.height,b.r)},image:function(a){var b=a.attrs;return ob(b.x,b.y,b.width,b.height)},text:function(a){var b=a._getBBox();return ob(b.x,b.y,b.width,b.height)},set:function(a){var b=a._getBBox();return ob(b.x,b.y,b.width,b.height)}},rb=c.mapPath=function(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=Kb(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(c._g=A,c.type=A.win.SVGAngle||A.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==c.type){var sb,tb=A.doc.createElement("div");if(tb.innerHTML='<v:shape adj="1"/>',sb=tb.firstChild,sb.style.behavior="url(#default#VML)",!sb||"object"!=typeof sb.adj)return c.type=G;tb=null}c.svg=!(c.vml="VML"==c.type),c._Paper=C,c.fn=v=C.prototype=c.prototype,c._id=0,c._oid=0,c.is=function(a,b){return b=M.call(b),"finite"==b?!Y[z](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||W.call(a).slice(8,-1).toLowerCase()==b},c.angle=function(a,b,d,e,f,g){if(null==f){var h=a-d,i=b-e;return h||i?(180+180*N.atan2(-i,-h)/S+360)%360:0}return c.angle(a,b,f,g)-c.angle(d,e,f,g)},c.rad=function(a){return a%360*S/180},c.deg=function(a){return 180*a/S%360},c.snapTo=function(a,b,d){if(d=c.is(d,"finite")?d:10,c.is(a,V)){for(var e=a.length;e--;)if(Q(a[e]-b)<=d)return a[e]}else{a=+a;var f=b%a;if(d>f)return b-f;if(f>a-d)return b-f+a}return b},c.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=0|16*N.random(),c="x"==a?b:8|3&b;return c.toString(16)}),c.setWindow=function(a){b("raphael.setWindow",c,A.win,a),A.win=a,A.doc=A.win.document,c._engine.initWin&&c._engine.initWin(A.win)};var ub=function(a){if(c.vml){var b,d=/^\s+|\s+$/g;try{var e=new ActiveXObject("htmlfile");e.write("<body>"),e.close(),b=e.body}catch(g){b=createPopup().document.body}var h=b.createTextRange();ub=f(function(a){try{b.style.color=I(a).replace(d,G);var c=h.queryCommandValue("ForeColor");return c=(255&c)<<16|65280&c|(16711680&c)>>>16,"#"+("000000"+c.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=A.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",A.doc.body.appendChild(i),ub=f(function(a){return i.style.color=a,A.doc.defaultView.getComputedStyle(i,G).getPropertyValue("color")})}return ub(a)},vb=function(){return"hsb("+[this.h,this.s,this.b]+")"},wb=function(){return"hsl("+[this.h,this.s,this.l]+")"},xb=function(){return this.hex},yb=function(a,b,d){if(null==b&&c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&c.is(a,U)){var e=c.getRGB(a);a=e.r,b=e.g,d=e.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},zb=function(a,b,d,e){a*=255,b*=255,d*=255;var f={r:a,g:b,b:d,hex:c.rgb(a,b,d),toString:xb};return c.is(e,"finite")&&(f.opacity=e),f};c.color=function(a){var b;return c.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):c.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):(c.is(a,"string")&&(a=c.getRGB(a)),c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=xb,a},c.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Q(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-Q(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.rgb2hsb=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=O(a,b,c),g=f-P(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=60*((d+360)%6)/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:vb}},c.rgb2hsl=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=O(a,b,c),h=P(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=60*((d+360)%6)/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:wb}},c._path2string=function(){return this.join(",").replace(gb,"$1")},c._preload=function(a,b){var c=A.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,A.doc.body.removeChild(this)},c.onerror=function(){A.doc.body.removeChild(this)},A.doc.body.appendChild(c),c.src=a},c.getRGB=f(function(a){if(!a||(a=I(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:g};!(fb[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=ub(a));var b,d,e,f,h,i,j=a.match(X);return j?(j[2]&&(e=ab(j[2].substring(5),16),d=ab(j[2].substring(3,5),16),b=ab(j[2].substring(1,3),16)),j[3]&&(e=ab((h=j[3].charAt(3))+h,16),d=ab((h=j[3].charAt(2))+h,16),b=ab((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100)),j[5]?(i=j[5][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsb2rgb(b,d,e,f)):j[6]?(i=j[6][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsl2rgb(b,d,e,f)):(j={r:b,g:d,b:e,toString:g},j.hex="#"+(16777216|e|d<<8|b<<16).toString(16).slice(1),c.is(f,"finite")&&(j.opacity=f),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g}},c),c.hsb=f(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=f(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=f(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),c.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},c.getColor.reset=function(){delete this.start},c.parsePathString=function(a){if(!a)return null;var b=Ab(a);if(b.arr)return Cb(b.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return c.is(a,V)&&c.is(a[0],V)&&(e=Cb(a)),e.length||I(a).replace(hb,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(jb,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][E](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g)e.push([b][E](f));else for(;f.length>=d[g]&&(e.push([b][E](f.splice(0,d[g]))),d[g]););}),e.toString=c._path2string,b.arr=Cb(e),e},c.parseTransformString=f(function(a){if(!a)return null;var b=[];return c.is(a,V)&&c.is(a[0],V)&&(b=Cb(a)),b.length||I(a).replace(ib,function(a,c,d){var e=[];M.call(c),d.replace(jb,function(a,b){b&&e.push(+b)}),b.push([c][E](e))}),b.toString=c._path2string,b});var Ab=function(a){var b=Ab.ps=Ab.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[z](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};c.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/S;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},c.bezierBBox=function(a,b,d,e,f,g,h,i){c.is(a,"array")||(a=[a,b,d,e,f,g,h,i]);var j=Jb.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},c.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},c.isBBoxIntersect=function(a,b){var d=c.isPointInsideBBox;return d(b,a.x,a.y)||d(b,a.x2,a.y)||d(b,a.x,a.y2)||d(b,a.x2,a.y2)||d(a,b.x,b.y)||d(a,b.x2,b.y)||d(a,b.x,b.y2)||d(a,b.x2,b.y2)||(a.x<b.x2&&a.x>b.x||b.x<a.x2&&b.x>a.x)&&(a.y<b.y2&&a.y>b.y||b.y<a.y2&&b.y>a.y)},c.pathIntersection=function(a,b){return n(a,b)},c.pathIntersectionNumber=function(a,b){return n(a,b,1)},c.isPointInsidePath=function(a,b,d){var e=c.pathBBox(a);return c.isPointInsideBBox(e,b,d)&&1==n(a,[["M",b,d],["H",e.x2+10]],1)%2},c._removedFactory=function(a){return function(){b("raphael.log",null,"Raphaël: you are calling to method â€œ"+a+"â€\9d of removed object",a)}};var Bb=c.pathBBox=function(a){var b=Ab(a);if(b.bbox)return d(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Kb(a);for(var c,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(c=a[i],"M"==c[0])e=c[1],f=c[2],g.push(e),h.push(f);else{var k=Jb(e,f,c[1],c[2],c[3],c[4],c[5],c[6]);g=g[E](k.min.x,k.max.x),h=h[E](k.min.y,k.max.y),e=c[5],f=c[6]}var l=P[D](0,g),m=P[D](0,h),n=O[D](0,g),o=O[D](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=d(r),r},Cb=function(a){var b=d(a);return b.toString=c._path2string,b},Db=c._pathToRelative=function(a){var b=Ab(a);if(b.rel)return Cb(b.rel);c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=M.call(m[0]))switch(l[0]=M.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=c._path2string,b.rel=Cb(d),d},Eb=c._pathToAbsolute=function(a){var b=Ab(a);if(b.abs)return Cb(b.abs);if(c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a)),!a||!a.length)return[["M",0,0]];var d=[],e=0,f=0,g=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],g=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=bb.call(l[0]))switch(k[0]=bb.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][E](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[E](h(p,m));break;case"M":g=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if("R"==l[0])p=[e,f][E](l.slice(1)),d.pop(),d=d[E](h(p,m)),k=["R"][E](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case"Z":e=g,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":g=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=c._path2string,b.abs=Cb(d),d},Fb=function(a,b,c,d){return[a,b,c,d,c,d]},Gb=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Hb=function(a,b,c,d,e,g,h,i,j,k){var l,m=120*S/180,n=S/180*(+e||0),o=[],p=f(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(S/180*e),N.sin(S/180*e),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=N.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*N.sqrt(Q((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=N.asin(((b-x)/d).toFixed(9)),z=N.asin(((j-x)/d).toFixed(9));y=w>a?S-y:y,z=w>i?S-z:z,0>y&&(y=2*S+y),0>z&&(z=2*S+z),h&&y>z&&(y-=2*S),!h&&z>y&&(z-=2*S)}var A=z-y;if(Q(A)>m){var B=z,C=i,D=j;z=y+m*(h&&z>y?1:-1),i=w+c*N.cos(z),j=x+d*N.sin(z),o=Hb(i,j,c,d,e,0,h,C,D,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),K=N.tan(A/4),L=4/3*c*K,M=4/3*d*K,O=[a,b],P=[a+L*G,b-M*F],R=[i+L*I,j-M*H],T=[i,j];if(P[0]=2*O[0]-P[0],P[1]=2*O[1]-P[1],k)return[P,R,T][E](o);o=[P,R,T][E](o).join()[J](",");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ib=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:R(j,3)*a+3*R(j,2)*i*c+3*j*i*i*e+R(i,3)*g,y:R(j,3)*b+3*R(j,2)*i*d+3*j*i*i*f+R(i,3)*h}},Jb=f(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:P[D](0,p),y:P[D](0,o)},max:{x:O[D](0,p),y:O[D](0,o)}}}),Kb=c._path2curve=f(function(a,b){var c=!b&&Ab(a);if(!b&&c.curve)return Cb(c.curve);for(var d=Eb(a),e=b&&Eb(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][E](Hb[D](0,[b.x,b.y][E](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][E](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][E](Gb(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][E](Gb(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][E](Fb(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][E](Fb(b.x,b.y,a[1],b.y));break;case"V":a=["C"][E](Fb(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][E](Fb(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)a.splice(b++,0,["C"][E](c.splice(0,6)));a.splice(b,1),l=O(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=O(d.length,e&&e.length||0))},k=0,l=O(d.length,e&&e.length||0);l>k;k++){d[k]=h(d[k],f),i(d,k),e&&(e[k]=h(e[k],g)),e&&i(e,k),j(d,e,f,g,k),j(e,d,g,f,k);var m=d[k],n=e&&e[k],o=m.length,p=e&&n.length;f.x=m[o-2],f.y=m[o-1],f.bx=_(m[o-4])||f.x,f.by=_(m[o-3])||f.y,g.bx=e&&(_(n[p-4])||g.x),g.by=e&&(_(n[p-3])||g.y),g.x=e&&n[p-2],g.y=e&&n[p-1]}return e||(c.curve=Cb(d)),e?[d,e]:d},null,Cb),Lb=(c._parseDots=f(function(a){for(var b=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=c.getRGB(g[1]),f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),b.push(f)}for(d=1,e=b.length-1;e>d;d++)if(!b[d].offset){for(var h=_(b[d-1].offset||0),i=0,j=d+1;e>j;j++)if(b[j].offset){i=b[j].offset;break}i||(i=100,j=e),i=_(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,b[d].offset=h+"%"}return b}),c._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Mb=(c._tofront=function(a,b){b.top!==a&&(Lb(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},c._toback=function(a,b){b.bottom!==a&&(Lb(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},c._insertafter=function(a,b,c){Lb(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},c._insertbefore=function(a,b,c){Lb(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},c.toMatrix=function(a,b){var c=Bb(a),d={_:{transform:G},getBBox:function(){return c}};return Nb(d,b),d.matrix}),Nb=(c.transformPath=function(a,b){return rb(a,Mb(a,b))},c._extractTransform=function(a,b){if(null==b)return a._.transform;b=I(b).replace(/\.{3}|\u2026/g,a._.transform||G);var d=c.parseTransformString(b),e=0,f=0,g=0,h=1,i=1,j=a._,k=new o;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var n,p,q,r,s,t=d[l],u=t.length,v=I(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(n=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-n,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ob=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Pb=c._equaliseTransform=function(a,b){b=I(b).replace(/\.{3}|\u2026/g,a),a=c.parseTransformString(a)||[],b=c.parseTransformString(b)||[];for(var d,e,f,g,h=O(a.length,b.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ob(b[k]),g=b[k]||Ob(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=O(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])
+}return{from:i,to:j}};c._getContainer=function(a,b,d,e){var f;return f=null!=e||c.is(a,"object")?a:A.doc.getElementById(a),null!=f?f.tagName?null==b?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:b,height:d}:{container:1,x:a,y:b,width:d,height:e}:void 0},c.pathToRelative=Db,c._engine={},c.path2curve=Kb,c.matrix=function(a,b,c,d,e,f){return new o(a,b,c,d,e,f)},function(a){function b(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var c=N.sqrt(b(a));a[0]&&(a[0]/=c),a[1]&&(a[1]/=c)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof o&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new o(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new o(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,b,d){a=c.rad(a),b=b||0,d=d||0;var e=+N.cos(a).toFixed(9),f=+N.sin(a).toFixed(9);this.add(e,f,-f,e,b,d),this.add(1,0,0,1,-b,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[I.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return c.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=N.sqrt(b(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=N.sqrt(b(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=c.deg(N.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=c.deg(N.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[J]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:G)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:G)+(b.rotate?"r"+[b.rotate,0,0]:G)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(o.prototype);var Qb=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);v.safari="Apple Computer, Inc."==navigator.vendor&&(Qb&&Qb[1]<4||"iP"==navigator.platform.slice(0,2))||"Google Inc."==navigator.vendor&&Qb&&Qb[1]<8?function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:mb;for(var Rb=function(){this.returnValue=!1},Sb=function(){return this.originalEvent.preventDefault()},Tb=function(){this.cancelBubble=!0},Ub=function(){return this.originalEvent.stopPropagation()},Vb=function(a){var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,c=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Wb=function(){return A.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Vb(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),F&&L[b]){var f=function(b){for(var e=Vb(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Sb,b.stopPropagation=Ub;break}return c.call(d,b,e.x,e.y)};a.addEventListener(L[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),F&&L[b]&&a.removeEventListener(L[b],e,!1),!0}}:A.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||A.win.event;var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,e=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Rb,a.stopPropagation=a.stopPropagation||Tb,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0}(),Xb=[],Yb=function(a){for(var c,d=a.clientX,e=a.clientY,f=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,g=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,h=Xb.length;h--;){if(c=Xb[h],F&&a.touches){for(var i,j=a.touches.length;j--;)if(i=a.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;A.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,A.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&b("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,b("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},Zb=function(a){c.unmousemove(Yb).unmouseup(Zb);for(var d,e=Xb.length;e--;)d=Xb[e],d.el._drag={},b("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,a);Xb=[]},$b=c.el={},_b=K.length;_b--;)!function(a){c[a]=$b[a]=function(b,d){return c.is(b,"function")&&(this.events=this.events||[],this.events.push({name:a,f:b,unbind:Wb(this.shape||this.node||A.doc,a,b,d||this)})),this},c["un"+a]=$b["un"+a]=function(b){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!c.is(b,"undefined")&&d[e].f!=b||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(K[_b]);$b.data=function(a,d){var e=kb[this.id]=kb[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(c.is(a,"object")){for(var f in a)a[z](f)&&this.data(f,a[f]);return this}return b("raphael.data.get."+this.id,this,e[a],a),e[a]}return e[a]=d,b("raphael.data.set."+this.id,this,d,a),this},$b.removeData=function(a){return null==a?kb[this.id]={}:kb[this.id]&&delete kb[this.id][a],this},$b.getData=function(){return d(kb[this.id]||{})},$b.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},$b.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var ac=[];$b.drag=function(a,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,m=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;if(this._drag.id=i.identifier,F&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Xb.length&&c.mousemove(Yb).mouseup(Zb),Xb.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("raphael.drag.start."+this.id,d),a&&b.on("raphael.drag.move."+this.id,a),e&&b.on("raphael.drag.end."+this.id,e),b("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},ac.push({el:this,start:i}),this.mousedown(i),this},$b.onDragOver=function(a){a?b.on("raphael.drag.over."+this.id,a):b.unbind("raphael.drag.over."+this.id)},$b.undrag=function(){for(var a=ac.length;a--;)ac[a].el==this&&(this.unmousedown(ac[a].start),ac.splice(a,1),b.unbind("raphael.drag.*."+this.id));!ac.length&&c.unmousemove(Yb).unmouseup(Zb),Xb=[]},v.circle=function(a,b,d){var e=c._engine.circle(this,a||0,b||0,d||0);return this.__set__&&this.__set__.push(e),e},v.rect=function(a,b,d,e,f){var g=c._engine.rect(this,a||0,b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.ellipse=function(a,b,d,e){var f=c._engine.ellipse(this,a||0,b||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},v.path=function(a){a&&!c.is(a,U)&&!c.is(a[0],V)&&(a+=G);var b=c._engine.path(c.format[D](c,arguments),this);return this.__set__&&this.__set__.push(b),b},v.image=function(a,b,d,e,f){var g=c._engine.image(this,a||"about:blank",b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.text=function(a,b,d){var e=c._engine.text(this,a||0,b||0,I(d));return this.__set__&&this.__set__.push(e),e},v.set=function(a){!c.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var b=new mc(a);return this.__set__&&this.__set__.push(b),b.paper=this,b.type="set",b},v.setStart=function(a){this.__set__=a||this.set()},v.setFinish=function(){var a=this.__set__;return delete this.__set__,a},v.setSize=function(a,b){return c._engine.setSize.call(this,a,b)},v.setViewBox=function(a,b,d,e,f){return c._engine.setViewBox.call(this,a,b,d,e,f)},v.top=v.bottom=null,v.raphael=c;var bc=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(A.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(A.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};v.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=A.doc.elementFromPoint(a,b);if(A.win.opera&&"svg"==e.tagName){var f=bc(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},v.getElementsByBBox=function(a){var b=this.set();return this.forEach(function(d){c.isBBoxIntersect(d.getBBox(),a)&&b.push(d)}),b},v.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},v.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},v.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},$b.isPointInside=function(a,b){var d=this.realPath=qb[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=c.transformPath(d,this.attr("transform"))),c.isPointInsidePath(d,a,b)},$b.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=qb[this.type](this),b.bboxwt=Bb(this.realPath),b.bboxwt.toString=p,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=qb[this.type](this)),b.bbox=Bb(rb(this.realPath,this.matrix)),b.bbox.toString=p,b.dirty=b.dirtyT=0),b.bbox)},$b.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},$b.glow=function(a){if("text"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||qb[this.type](this);f=this.matrix?rb(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var cc=function(a,b,d,e,f,g,h,i,l){return null==l?j(a,b,d,e,f,g,h,i):c.findDotsAtSegment(a,b,d,e,f,g,h,i,k(a,b,d,e,f,g,h,i,l))},dc=function(a,b){return function(d,e,f){d=Kb(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0])g=+i[1],h=+i[2];else{if(j=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(b&&!m.start){if(k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!b)return k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:b?m:c.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},ec=dc(1),fc=dc(),gc=dc(0,1);c.getTotalLength=ec,c.getPointAtLength=fc,c.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return gc(a,b).end;var d=gc(a,c,1);return b?gc(d,b).end:d},$b.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():ec(a)},$b.getPointAtLength=function(a){var b=this.getPath();if(b)return fc(b,a)},$b.getPath=function(){var a,b=c._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return b&&(a=b(this)),a},$b.getSubpath=function(a,b){var d=this.getPath();if(d)return c.getSubpath(d,a,b)};var hc=c.easing_formulas={linear:function(a){return a},"<":function(a){return R(a,1.7)},">":function(a){return R(a,.48)},"<>":function(a){var b=.48-a/1.04,c=N.sqrt(.1734+b*b),d=c-b,e=R(Q(d),1/3)*(0>d?-1:1),f=-c-b,g=R(Q(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:R(2,-10*a)*N.sin((a-.075)*2*S/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};hc.easeIn=hc["ease-in"]=hc["<"],hc.easeOut=hc["ease-out"]=hc[">"],hc.easeInOut=hc["ease-in-out"]=hc["<>"],hc["back-in"]=hc.backIn,hc["back-out"]=hc.backOut;var ic=[],jc=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},kc=function(){for(var a=+new Date,d=0;d<ic.length;d++){var e=ic[d];if(!e.el.removed&&!e.paused){var f,g,h=a-e.start,i=e.ms,j=e.easing,k=e.from,l=e.diff,m=e.to,n=(e.t,e.el),o={},p={};if(e.initstatus?(h=(e.initstatus*e.anim.top-e.prev)/(e.percent-e.prev)*i,e.status=e.initstatus,delete e.initstatus,e.stop&&ic.splice(d--,1)):e.status=(e.prev+(e.percent-e.prev)*(h/i))/e.anim.top,!(0>h))if(i>h){var q=j(h/i);for(var r in k)if(k[z](r)){switch(db[r]){case T:f=+k[r]+q*i*l[r];break;case"colour":f="rgb("+[lc($(k[r].r+q*i*l[r].r)),lc($(k[r].g+q*i*l[r].g)),lc($(k[r].b+q*i*l[r].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[r].length;u>t;t++){f[t]=[k[r][t][0]];for(var v=1,w=k[r][t].length;w>v;v++)f[t][v]=+k[r][t][v]+q*i*l[r][t][v];f[t]=f[t].join(H)}f=f.join(H);break;case"transform":if(l[r].real)for(f=[],t=0,u=k[r].length;u>t;t++)for(f[t]=[k[r][t][0]],v=1,w=k[r][t].length;w>v;v++)f[t][v]=k[r][t][v]+q*i*l[r][t][v];else{var x=function(a){return+k[r][a]+q*i*l[r][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case"csv":if("clip-rect"==r)for(f=[],t=4;t--;)f[t]=+k[r][t]+q*i*l[r][t];break;default:var y=[][E](k[r]);for(f=[],t=n.paper.customAttributes[r].length;t--;)f[t]=+y[t]+q*i*l[r][t]}o[r]=f}n.attr(o),function(a,c,d){setTimeout(function(){b("raphael.anim.frame."+a,c,d)})}(n.id,n,e.anim)}else{if(function(a,d,e){setTimeout(function(){b("raphael.anim.frame."+d.id,d,e),b("raphael.anim.finish."+d.id,d,e),c.is(a,"function")&&a.call(d)})}(e.callback,n,e.anim),n.attr(m),ic.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[z](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),s(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&s(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}c.svg&&n&&n.paper&&n.paper.safari(),ic.length&&jc(kc)},lc=function(a){return a>255?255:0>a?0:a};$b.animateWith=function(a,b,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof r?d:c.animation(d,e,f,g);s(i,h,i.percents[0],null,h.attr());for(var j=0,k=ic.length;k>j;j++)if(ic[j].anim==b&&ic[j].el==a){ic[k-1].start=ic[j].start;break}return h},$b.onAnimation=function(a){return a?b.on("raphael.anim.frame."+this.id,a):b.unbind("raphael.anim.frame."+this.id),this},r.prototype.delay=function(a){var b=new r(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},r.prototype.repeat=function(a){var b=new r(this.anim,this.ms);return b.del=this.del,b.times=N.floor(O(a,0))||1,b},c.animation=function(a,b,d,e){if(a instanceof r)return a;(c.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),b=+b||0;var f,g,h={};for(g in a)a[z](g)&&_(g)!=g&&_(g)+"%"!=g&&(f=!0,h[g]=a[g]);return f?(d&&(h.easing=d),e&&(h.callback=e),new r({100:h},b)):new r(a,b)},$b.animate=function(a,b,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof r?a:c.animation(a,b,d,e);return s(g,f,g.percents[0],null,f.attr()),f},$b.setTime=function(a,b){return a&&null!=b&&this.status(a,P(b,a.ms)/a.ms),this},$b.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return s(a,this,-1,P(b,1)),this;for(c=ic.length;c>f;f++)if(d=ic[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},$b.pause=function(a){for(var c=0;c<ic.length;c++)ic[c].el.id!=this.id||a&&ic[c].anim!=a||b("raphael.anim.pause."+this.id,this,ic[c].anim)!==!1&&(ic[c].paused=!0);return this},$b.resume=function(a){for(var c=0;c<ic.length;c++)if(ic[c].el.id==this.id&&(!a||ic[c].anim==a)){var d=ic[c];b("raphael.anim.resume."+this.id,this,d.anim)!==!1&&(delete d.paused,this.status(d.anim,d.status))}return this},$b.stop=function(a){for(var c=0;c<ic.length;c++)ic[c].el.id!=this.id||a&&ic[c].anim!=a||b("raphael.anim.stop."+this.id,this,ic[c].anim)!==!1&&ic.splice(c--,1);return this},b.on("raphael.remove",t),b.on("raphael.clear",t),$b.toString=function(){return"Raphaël’s object"};var mc=function(a){if(this.items=[],this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)!a[b]||a[b].constructor!=$b.constructor&&a[b].constructor!=mc||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},nc=mc.prototype;nc.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=$b.constructor&&a.constructor!=mc||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},nc.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},nc.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var oc in $b)$b[z](oc)&&(nc[oc]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][D](c,b)})}}(oc));return nc.attr=function(a,b){if(a&&c.is(a,V)&&c.is(a[0],"object"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,b);return this},nc.clear=function(){for(;this.length;)this.pop()},nc.splice=function(a,b){a=0>a?O(this.length+a,0):a,b=O(0,P(this.length-a,b));var c,d=[],e=[],f=[];for(c=2;c<arguments.length;c++)f.push(arguments[c]);for(c=0;b>c;c++)e.push(this[a+c]);for(;c<this.length-a;c++)d.push(this[a+c]);var g=f.length;for(c=0;c<g+d.length;c++)this.items[a+c]=this[a+c]=g>c?f[c]:d[c-g];for(c=this.items.length=this.length-=b-g;this[c];)delete this[c++];return new mc(e)},nc.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},nc.animate=function(a,b,d,e){(c.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=c.is(d,U)?d:g;var k=c.animation(a,b,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},nc.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},nc.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=P[D](0,a),b=P[D](0,b),c=O[D](0,c),d=O[D](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},nc.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},nc.toString=function(){return"Raphaël‘s set"},nc.glow=function(a){var b=this.paper.set();return this.forEach(function(c){var d=c.glow(a);null!=d&&d.forEach(function(a){b.push(a)})}),b},nc.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(console.log("runned"),c=!0,!1):void 0}),c},c.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[z](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=ab(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[z](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"},f.k)for(var g in f.k)f[z](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},v.getFont=function(a,b,d,e){if(e=e||"normal",d=d||"normal",b=+b||{normal:400,bold:700,lighter:300,bolder:800}[b]||400,c.fonts){var f=c.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,G)+"(\\s|$)","i");for(var h in c.fonts)if(c.fonts[z](h)&&g.test(h)){f=c.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=b||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},v.print=function(a,b,d,e,f,g,h,i){g=g||"middle",h=O(P(h||0,1),-1),i=O(P(i||1,3),1);var j,k=I(d)[J](G),l=0,m=0,n=G;if(c.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[J](w),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t])l=0,x=0,m=0,r+=q*i;else{var v=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(v.w||e.w)+(v.k&&v.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=c.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(b-s)/j]))}}return this.path(n).attr({fill:"#000",stroke:"none"})},v.add=function(a){if(c.is(a,"array"))for(var b,d=this.set(),e=0,f=a.length;f>e;e++)b=a[e]||{},x[z](b.type)&&d.push(this[b.type]().attr(b));return d},c.format=function(a,b){var d=c.is(b,V)?[0][E](b):arguments;return a&&c.is(a,U)&&d.length-1&&(a=a.replace(y,function(a,b){return null==d[++b]?G:d[b]})),a||G},c.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),c.ninja=function(){return B.was?A.win.Raphael=B.is:delete Raphael,c},c.st=nc,function(a,b,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):c.eve("raphael.DOMload")}null==a.readyState&&a.addEventListener&&(a.addEventListener(b,d=function(){a.removeEventListener(b,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()}(document,"DOMContentLoaded"),b.on("raphael.DOMload",function(){u=!0}),function(){if(c.svg){var a="hasOwnProperty",b=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=c.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};c.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e)e[a](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),b(e[f])):d.setAttribute(f,b(e[f])))}else d=c._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(a,e){var j="linear",k=a.id+e,m=.5,n=.5,o=a.node,p=a.paper,r=o.style,s=c._g.doc.getElementById(k);if(!s){if(e=b(e).replace(c._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(c.rad(t)),f.sin(c.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=c._parseDots(e);if(!w)return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),a.gradient&&k!=a.gradient.id&&(p.defs.removeChild(a.gradient),delete a.gradient),!a.gradient){s=q(j+"Gradient",{id:k}),a.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:a.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}}return q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=b(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;)switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y;c._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=c._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-E*u):(g=E*u,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=c.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-g):(g=0,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:c.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p)if(p[a](k)&&!p[k]){var F=c._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,c,d){if(c=u[b(c).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=c.length;h--;)g[h]=c[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[a](o)){if(!c._availableAttrs[a](o))continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"href":case"title":var u=q("title"),w=c._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u);break;case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var u=q("a");x.insertBefore(u,i),u.appendChild(i),x=u}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var z=b(p).split(j);if(4==z.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var A=q("clipPath"),B=q("rect");A.id=c.createUUID(),q(B,{x:z[0],y:z[1],width:z[2],height:z[3]}),A.appendChild(B),d.paper.defs.appendChild(A),q(i,{"clip-path":"url(#"+A.id+")"}),d.clip=B}if(!p){var C=i.getAttribute("clip-path");if(C){var D=c._g.doc.getElementById(C.replace(/(^url\(#|\)$)/g,l));D&&D.parentNode.removeChild(D),q(i,{"clip-path":l}),delete d.clip}}break;case"path":"path"==d.type&&(q(i,{d:p?k.path=c._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type)break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type)break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var E=b(p).match(c._ISURL);if(E){A=q("pattern");var F=q("image");A.id=c.createUUID(),q(A,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(F,{x:0,y:0,"xlink:href":E[1]}),A.appendChild(F),function(a){c._preload(E[1],function(){var b=this.offsetWidth,c=this.offsetHeight;q(a,{width:b,height:c}),q(F,{width:b,height:c}),d.paper.safari()})}(A),d.paper.defs.appendChild(A),q(i,{fill:"url(#"+A.id+")"}),d.pattern=A,d.pattern&&s(d);break}var G=c.getRGB(p);if(G.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var H=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(H){var I=H.getElementsByTagName("stop");q(I[I.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}}else delete f.gradient,delete k.gradient,!c.is(k.opacity,"undefined")&&c.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!c.is(k["fill-opacity"],"undefined")&&c.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});G[a]("opacity")&&q(i,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=c.getRGB(p),i.setAttribute(o,G.hex),"stroke"==o&&G[a]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p);break;case"opacity":k.gradient&&!k[a]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break}default:"font-size"==o&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[a]("text")||f[a]("font")||f[a]("font-size")||f[a]("x")||f[a]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(c._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;
+if(f[a]("text")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=b(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++)j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(c._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&c.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.matrix=c.matrix(),this.realPath=null,this.paper=b,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},A=c.el;z.prototype=A,A.constructor=z,c._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new z(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},A.rotate=function(a,c,e){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([["r",a,c,e]])),this},A.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this},A.translate=function(a,c){return this.removed?this:(a=b(a).split(j),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this.transform(this._.transform.concat([["t",a,c]])),this)},A.transform=function(b){var d=this._;if(null==b)return d.transform;if(c._extractTransform(this,b),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[a]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},A.hide=function(){return!this.removed&&this.paper.safari(this.node.style.display="none"),this},A.show=function(){return!this.removed&&this.paper.safari(this.node.style.display=""),this},A.remove=function(){if(!this.removed&&this.node.parentNode){var a=this.paper;a.__set__&&a.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&a.defs.removeChild(this.gradient),c._tear(this,a),"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.removeChild(this.node.parentNode):this.node.parentNode.removeChild(this.node);for(var b in this)this[b]="function"==typeof this[b]?c._removedFactory(b):null;this.removed=!0}},A._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}return a&&this.hide(),b},A.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if("fill"==b&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==b)return this._.transform;for(var g=b.split(j),h={},i=0,l=g.length;l>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return l-1?h:h[g[0]]}if(null==d&&c.is(b,"array")){for(h={},i=0,l=b.length;l>i;i++)h[b[i]]=this.attr(b[i]);return h}if(null!=d){var m={};m[b]=d}else null!=b&&c.is(b,"object")&&(m=b);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[a](n)&&m[a](n)&&c.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[a](p)&&(m[p]=o[p])}return w(this,m),this},A.toFront=function(){if(this.removed)return this;"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.appendChild(this.node.parentNode):this.node.parentNode.appendChild(this.node);var a=this.paper;return a.top!=this&&c._tofront(this,a),this},A.toBack=function(){if(this.removed)return this;var a=this.node.parentNode;return"a"==a.tagName.toLowerCase()?a.parentNode.insertBefore(this.node.parentNode,this.node.parentNode.parentNode.firstChild):a.firstChild!=this.node&&a.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper),this.paper,this},A.insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;return b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this},A.insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;return b.parentNode.insertBefore(this.node,b),c._insertbefore(this,a,this.paper),this},A.blur=function(a){var b=this;if(0!==+a){var d=q("filter"),e=q("feGaussianBlur");b.attrs.blur=a,d.id=c.createUUID(),q(e,{stdDeviation:+a||1.5}),d.appendChild(e),b.paper.defs.appendChild(d),b._blur=d,q(b.node,{filter:"url(#"+d.id+")"})}else b._blur&&(b._blur.parentNode.removeChild(b._blur),delete b._blur,delete b.attrs.blur),b.node.removeAttribute("filter");return b},c._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new z(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},c._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},c._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},c._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},c._engine.text=function(a,b,d,e){var f=q("text");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={x:b,y:d,"text-anchor":"middle",text:e,font:c._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},c._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a&&a.container,d=a.x,e=a.y,f=a.width,g=a.height;if(!b)throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),1==b?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",c._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i)),b=new c._Paper,b.width=f,b.height=g,b.canvas=i,b.clear(),b._left=b._top=0,h&&(b.renderfix=function(){}),b.renderfix(),b},c._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=g(c/this.width,d/this.height),j=this.top,l=e?"meet":"xMinYMin";for(null==a?(this._vbSize&&(i=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=i,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:l});i&&j;)h="stroke-width"in j.attrs?j.attrs["stroke-width"]:1,j.attr({"stroke-width":h}),j._.dirty=1,j._.dirtyT=1,j=j.prev;return this._viewBox=[a,b,c,d,!!e],this},c.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},c.prototype.clear=function(){c.eve("raphael.clear",this);for(var a=this.canvas;a.firstChild;)a.removeChild(a.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(c._g.doc.createTextNode("Created with Raphaël "+c.version)),a.appendChild(this.desc),a.appendChild(this.defs=q("defs"))},c.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null};var B=c.st;for(var C in A)A[a](C)&&!B[a](C)&&(B[C]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(C))}}(),function(){if(c.vml){var a="hasOwnProperty",b=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=c.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(a){var d=/[ahqstv]/gi,e=c._pathToAbsolute;if(b(a).match(d)&&(e=c._path2curve),d=/[clmz]/g,e==c._pathToAbsolute&&!b(a).match(d)){var g=b(a).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(a);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)}return g.join(n)},y=function(a,b,d){var e=c.matrix();return e.rotate(-a,.5,.5),{dx:e.x(b,d),dy:e.y(b,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility="visible"}};c.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,c,d){for(var e=b(c).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[a](t)&&(m[t]=i[t]);if(q&&(m.path=c._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~b(m.path).toLowerCase().indexOf("r")?c._pathToAbsolute(m.path):m.path),"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=c.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if("clip-rect"in i){var G=b(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||c._g.doc.createElement("div"),I=H.style;I.clip=c.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])}if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=b(i.fill).match(c._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],c._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=c.getRGB(i.fill).hex,K.src=o,K.type="solid",c.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=b(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+c.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")}l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=c.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),i["stroke-dasharray"]){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[a](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o}Q&&l.appendChild(P)}if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=b(s.textpath.string).replace(/</g,"&#60;").replace(/&/g,"&#38;").replace(/\n/g,"<br>"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=c.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0}s.textpath.style["v-text-kern"]=!0}},C=function(a,f,g){a.attrs=a.attrs||{};var h=(a.attrs,Math.pow),i="linear",j=".5 .5";if(a.attrs.gradient=f,f=b(f).replace(c._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=c._parseDots(f);if(!l)return null;if(a=a.shape||a.node,l.length){a.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),a.appendChild(g)}return 1},D=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=b,this.matrix=c.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},E=c.el;D.prototype=E,E.constructor=D,E.transform=function(a){if(null==a)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=a=b(a).replace(/\.{3}|\u2026/g,this._.transform||o)),c._extractTransform(this,f+a);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~b(this.attrs.fill).indexOf("-"),l=!b(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type)if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=b(h),i.offset=h.offset();return d&&(this._.transform=d),this},E.rotate=function(a,c,e){if(this.removed)return this;if(null!=a){if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,c,e]])),this}},E.translate=function(a,c){return this.removed?this:(a=b(a).split(k),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=c),this.transform(this._.transform.concat([["t",a,c]])),this)},E.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),c.eve.unbind("raphael.*.*."+this.id),c._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;this.removed=!0}},E.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if(b==j&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=b.split(k),h={},i=0,m=g.length;m>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&c.is(b,"array")){for(h={},i=0,m=b.length;m>i;i++)h[b[i]]=this.attr(b[i]);return h}var n;null!=d&&(n={},n[b]=d),null==d&&c.is(b,"object")&&(n=b);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[a](o)&&n[a](o)&&c.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[a](q)&&(n[q]=p[q])}n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&c._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper)),this)},E.insertAfter=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[a.length-1]),a.node.nextSibling?a.node.parentNode.insertBefore(this.node,a.node.nextSibling):a.node.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this)},E.insertBefore=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[0]),a.node.parentNode.insertBefore(this.node,a.node),c._insertbefore(this,a,this.paper),this)},E.blur=function(a){var b=this.node.runtimeStyle,d=b.filter;return d=d.replace(r,o),0!==+a?(this.attrs.blur=a,b.filter=d+n+m+".Blur(pixelradius="+(+a||1.5)+")",b.margin=c.format("-{0}px 0 0 -{0}px",f(+a||1.5))):(b.filter=d,b.margin=0,delete this.attrs.blur),this},c._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},c._engine.rect=function(a,b,d,e,f,g){var h=c._rectPath(b,d,e,f,g),i=a.path(h),j=i.attrs;return i.X=j.x=b,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},c._engine.ellipse=function(a,b,c,d,e){var f=a.path();return f.attrs,f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},c._engine.circle=function(a,b,c,d){var e=a.path();return e.attrs,e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},c._engine.image=function(a,b,d,e,f,g){var h=c._rectPath(d,e,f,g),i=a.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=b,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=b,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},c._engine.text=function(a,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=c.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=b(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,a),l={fill:"#000",stroke:"none",font:c._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=b(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),a.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},c._engine.setSize=function(a,b){var d=this.canvas.style;return this.width=a,this.height=b,a==+a&&(a+="px"),b==+b&&(b+="px"),d.width=a,d.height=b,d.clip="rect(0 "+a+" "+b+" 0)",this._viewBox&&c._engine.setViewBox.apply(this,this._viewBox),this},c._engine.setViewBox=function(a,b,d,e,f){c.eve("raphael.setViewBox",this,this._viewBox,[a,b,d,e,f]);var h,i,j=this.width,k=this.height,l=1/g(d/j,e/k);return f&&(h=k/e,i=j/d,j>d*h&&(a-=(j-d*h)/2/h),k>e*i&&(b-=(k-e*i)/2/i)),this._viewBox=[a,b,d,e,!!f],this._viewBoxShift={dx:-a,dy:-b,scale:l},this.forEach(function(a){a.transform("...")}),this};var F;c._engine.initWin=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("<rvml:"+a+' class="rvml">')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},c._engine.initWin(c._g.win),c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a.container,d=a.height,e=a.width,f=a.x,g=a.y;if(!b)throw new Error("VML container not found.");var h=new c._Paper,i=h.canvas=c._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=c._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=c.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==b?(c._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i),h.renderfix=function(){},h},c.prototype.clear=function(){c.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=c._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},c.prototype.remove=function(){c.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;return!0};var G=c.st;for(var H in E)E[a](H)&&!G[a](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}(),B.was?A.win.Raphael=c:Raphael=c,c});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/slick.js b/src/main/resources/META-INF/resources/designer/lib/slick.js
new file mode 100644 (file)
index 0000000..e302777
--- /dev/null
@@ -0,0 +1,2117 @@
+/*
+     _ _      _       _
+ ___| (_) ___| | __  (_)___
+/ __| | |/ __| |/ /  | / __|
+\__ \ | | (__|   < _ | \__ \
+|___/_|_|\___|_|\_(_)/ |___/
+                   |__/
+
+ Version: 1.3.15
+  Author: Ken Wheeler
+ Website: http://kenwheeler.github.io
+    Docs: http://kenwheeler.github.io/slick
+    Repo: http://github.com/kenwheeler/slick
+  Issues: http://github.com/kenwheeler/slick/issues
+
+ */
+
+/* global window, document, define, jQuery, setInterval, clearInterval */
+
+(function(factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (typeof exports !== 'undefined') {
+        module.exports = factory(require('jquery'));
+    } else {
+        factory(jQuery);
+    }
+
+}(function($) {
+    'use strict';
+    var Slick = window.Slick || {};
+
+    Slick = (function() {
+
+        var instanceUid = 0;
+
+        function Slick(element, settings) {
+
+            var _ = this,
+                responsiveSettings, breakpoint;
+
+            _.defaults = {
+                accessibility: true,
+                adaptiveHeight: false,
+                appendArrows: $(element),
+                appendDots: $(element),
+                arrows: true,
+                asNavFor: null,
+                prevArrow: '<button type="button" data-role="none" class="slick-prev">Previous</button>',
+                nextArrow: '<button type="button" data-role="none" class="slick-next">Next</button>',
+                autoplay: false,
+                autoplaySpeed: 3000,
+                centerMode: false,
+                centerPadding: '50px',
+                cssEase: 'ease',
+                customPaging: function(slider, i) {
+                    return '<button type="button" data-role="none">' + (i + 1) + '</button>';
+                },
+                dots: false,
+                dotsClass: 'slick-dots',
+                draggable: true,
+                easing: 'linear',
+                fade: false,
+                focusOnSelect: false,
+                infinite: true,
+                initialSlide: 0,
+                lazyLoad: 'ondemand',
+                onBeforeChange: null,
+                onAfterChange: null,
+                onInit: null,
+                onReInit: null,
+                onSetPosition: null,
+                pauseOnHover: true,
+                pauseOnDotsHover: false,
+                respondTo: 'window',
+                responsive: null,
+                rtl: false,
+                slide: 'div',
+                slidesToShow: 1,
+                slidesToScroll: 1,
+                speed: 500,
+                swipe: true,
+                swipeToSlide: false,
+                touchMove: true,
+                touchThreshold: 5,
+                useCSS: true,
+                variableWidth: false,
+                vertical: false,
+                waitForAnimate: true
+            };
+
+            _.initials = {
+                animating: false,
+                dragging: false,
+                autoPlayTimer: null,
+                currentDirection: 0,
+                currentLeft: null,
+                currentSlide: 0,
+                direction: 1,
+                $dots: null,
+                listWidth: null,
+                listHeight: null,
+                loadIndex: 0,
+                $nextArrow: null,
+                $prevArrow: null,
+                slideCount: null,
+                slideWidth: null,
+                $slideTrack: null,
+                $slides: null,
+                sliding: false,
+                slideOffset: 0,
+                swipeLeft: null,
+                $list: null,
+                touchObject: {},
+                transformsEnabled: false
+            };
+
+            $.extend(_, _.initials);
+
+            _.activeBreakpoint = null;
+            _.animType = null;
+            _.animProp = null;
+            _.breakpoints = [];
+            _.breakpointSettings = [];
+            _.cssTransitions = false;
+            _.paused = false;
+            _.positionProp = null;
+            _.respondTo = null;
+            _.shouldClick = true;
+            _.$slider = $(element);
+            _.$slidesCache = null;
+            _.transformType = null;
+            _.transitionType = null;
+            _.windowWidth = 0;
+            _.windowTimer = null;
+
+            _.options = $.extend({}, _.defaults, settings);
+
+            _.currentSlide = _.options.initialSlide;
+
+            _.originalSettings = _.options;
+            responsiveSettings = _.options.responsive || null;
+
+            if (responsiveSettings && responsiveSettings.length > -1) {
+                _.respondTo = _.options.respondTo || "window";
+                for (breakpoint in responsiveSettings) {
+                    if (responsiveSettings.hasOwnProperty(breakpoint)) {
+                        _.breakpoints.push(responsiveSettings[
+                            breakpoint].breakpoint);
+                        _.breakpointSettings[responsiveSettings[
+                            breakpoint].breakpoint] =
+                            responsiveSettings[breakpoint].settings;
+                    }
+                }
+                _.breakpoints.sort(function(a, b) {
+                    return b - a;
+                });
+            }
+
+            _.autoPlay = $.proxy(_.autoPlay, _);
+            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
+            _.changeSlide = $.proxy(_.changeSlide, _);
+            _.clickHandler = $.proxy(_.clickHandler, _);
+            _.selectHandler = $.proxy(_.selectHandler, _);
+            _.setPosition = $.proxy(_.setPosition, _);
+            _.swipeHandler = $.proxy(_.swipeHandler, _);
+            _.dragHandler = $.proxy(_.dragHandler, _);
+            _.keyHandler = $.proxy(_.keyHandler, _);
+            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
+
+            _.instanceUid = instanceUid++;
+
+            // A simple way to check for HTML strings
+            // Strict HTML recognition (must start with <)
+            // Extracted from jQuery v1.11 source
+            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
+
+            _.init();
+
+            _.checkResponsive();
+
+        }
+
+        return Slick;
+
+    }());
+
+    Slick.prototype.addSlide = function(markup, index, addBefore) {
+
+        var _ = this;
+
+        if (typeof(index) === 'boolean') {
+            addBefore = index;
+            index = null;
+        } else if (index < 0 || (index >= _.slideCount)) {
+            return false;
+        }
+
+        _.unload();
+
+        if (typeof(index) === 'number') {
+            if (index === 0 && _.$slides.length === 0) {
+                $(markup).appendTo(_.$slideTrack);
+            } else if (addBefore) {
+                $(markup).insertBefore(_.$slides.eq(index));
+            } else {
+                $(markup).insertAfter(_.$slides.eq(index));
+            }
+        } else {
+            if (addBefore === true) {
+                $(markup).prependTo(_.$slideTrack);
+            } else {
+                $(markup).appendTo(_.$slideTrack);
+            }
+        }
+
+        _.$slides = _.$slideTrack.children(this.options.slide);
+
+        _.$slideTrack.children(this.options.slide).detach();
+
+        _.$slideTrack.append(_.$slides);
+
+        _.$slides.each(function(index, element) {
+            $(element).attr("index",index);
+        });
+
+        _.$slidesCache = _.$slides;
+
+        _.reinit();
+
+    };
+
+    Slick.prototype.animateSlide = function(targetLeft, callback) {
+
+        var animProps = {}, _ = this;
+
+        if(_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
+            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
+            _.$list.animate({height: targetHeight},_.options.speed);
+        }
+
+        if (_.options.rtl === true && _.options.vertical === false) {
+            targetLeft = -targetLeft;
+        }
+        if (_.transformsEnabled === false) {
+            if (_.options.vertical === false) {
+                _.$slideTrack.animate({
+                    left: targetLeft
+                }, _.options.speed, _.options.easing, callback);
+            } else {
+                _.$slideTrack.animate({
+                    top: targetLeft
+                }, _.options.speed, _.options.easing, callback);
+            }
+
+        } else {
+
+            if (_.cssTransitions === false) {
+
+                $({
+                    animStart: _.currentLeft
+                }).animate({
+                    animStart: targetLeft
+                }, {
+                    duration: _.options.speed,
+                    easing: _.options.easing,
+                    step: function(now) {
+                        if (_.options.vertical === false) {
+                            animProps[_.animType] = 'translate(' +
+                                now + 'px, 0px)';
+                            _.$slideTrack.css(animProps);
+                        } else {
+                            animProps[_.animType] = 'translate(0px,' +
+                                now + 'px)';
+                            _.$slideTrack.css(animProps);
+                        }
+                    },
+                    complete: function() {
+                        if (callback) {
+                            callback.call();
+                        }
+                    }
+                });
+
+            } else {
+
+                _.applyTransition();
+
+                if (_.options.vertical === false) {
+                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
+                } else {
+                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
+                }
+                _.$slideTrack.css(animProps);
+
+                if (callback) {
+                    setTimeout(function() {
+
+                        _.disableTransition();
+
+                        callback.call();
+                    }, _.options.speed);
+                }
+
+            }
+
+        }
+
+    };
+
+    Slick.prototype.asNavFor = function(index) {
+        var _ = this, asNavFor = _.options.asNavFor != null ? $(_.options.asNavFor).getSlick() : null;
+        if(asNavFor != null) asNavFor.slideHandler(index, true);
+    };
+
+    Slick.prototype.applyTransition = function(slide) {
+
+        var _ = this,
+            transition = {};
+
+        if (_.options.fade === false) {
+            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
+        } else {
+            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
+        }
+
+        if (_.options.fade === false) {
+            _.$slideTrack.css(transition);
+        } else {
+            _.$slides.eq(slide).css(transition);
+        }
+
+    };
+
+    Slick.prototype.autoPlay = function() {
+
+        var _ = this;
+
+        if (_.autoPlayTimer) {
+            clearInterval(_.autoPlayTimer);
+        }
+
+        if (_.slideCount > _.options.slidesToShow && _.paused !== true) {
+            _.autoPlayTimer = setInterval(_.autoPlayIterator,
+                _.options.autoplaySpeed);
+        }
+
+    };
+
+    Slick.prototype.autoPlayClear = function() {
+
+        var _ = this;
+        if (_.autoPlayTimer) {
+            clearInterval(_.autoPlayTimer);
+        }
+
+    };
+
+    Slick.prototype.autoPlayIterator = function() {
+
+        var _ = this;
+
+        if (_.options.infinite === false) {
+
+            if (_.direction === 1) {
+
+                if ((_.currentSlide + 1) === _.slideCount -
+                    1) {
+                    _.direction = 0;
+                }
+
+                _.slideHandler(_.currentSlide + _.options.slidesToScroll);
+
+            } else {
+
+                if ((_.currentSlide - 1 === 0)) {
+
+                    _.direction = 1;
+
+                }
+
+                _.slideHandler(_.currentSlide - _.options.slidesToScroll);
+
+            }
+
+        } else {
+
+            _.slideHandler(_.currentSlide + _.options.slidesToScroll);
+
+        }
+
+    };
+
+    Slick.prototype.buildArrows = function() {
+
+        var _ = this;
+
+        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+
+            _.$prevArrow = $(_.options.prevArrow);
+            _.$nextArrow = $(_.options.nextArrow);
+
+            if (_.htmlExpr.test(_.options.prevArrow)) {
+                _.$prevArrow.appendTo(_.options.appendArrows);
+            }
+
+            if (_.htmlExpr.test(_.options.nextArrow)) {
+                _.$nextArrow.appendTo(_.options.appendArrows);
+            }
+
+            if (_.options.infinite !== true) {
+                _.$prevArrow.addClass('slick-disabled');
+            }
+
+        }
+
+    };
+
+    Slick.prototype.buildDots = function() {
+
+        var _ = this,
+            i, dotString;
+
+        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+            dotString = '<ul class="' + _.options.dotsClass + '">';
+
+            for (i = 0; i <= _.getDotCount(); i += 1) {
+                dotString += '<li>' + _.options.customPaging.call(this, _, i) + '</li>';
+            }
+
+            dotString += '</ul>';
+
+            _.$dots = $(dotString).appendTo(
+                _.options.appendDots);
+
+            _.$dots.find('li').first().addClass(
+                'slick-active');
+
+        }
+
+    };
+
+    Slick.prototype.buildOut = function() {
+
+        var _ = this;
+
+        _.$slides = _.$slider.children(_.options.slide +
+            ':not(.slick-cloned)').addClass(
+            'slick-slide');
+        _.slideCount = _.$slides.length;
+
+        _.$slides.each(function(index, element) {
+            $(element).attr("index",index);
+        });
+
+        _.$slidesCache = _.$slides;
+
+        _.$slider.addClass('slick-slider');
+
+        _.$slideTrack = (_.slideCount === 0) ?
+            $('<div class="slick-track"/>').appendTo(_.$slider) :
+            _.$slides.wrapAll('<div class="slick-track"/>').parent();
+
+        _.$list = _.$slideTrack.wrap(
+            '<div class="slick-list"/>').parent();
+        _.$slideTrack.css('opacity', 0);
+
+        if (_.options.centerMode === true) {
+            _.options.slidesToScroll = 1;
+        }
+
+        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
+
+        _.setupInfinite();
+
+        _.buildArrows();
+
+        _.buildDots();
+
+        _.updateDots();
+
+        if (_.options.accessibility === true) {
+            _.$list.prop('tabIndex', 0);
+        }
+
+        _.setSlideClasses(typeof this.currentSlide === 'number' ? this.currentSlide : 0);
+
+        if (_.options.draggable === true) {
+            _.$list.addClass('draggable');
+        }
+
+    };
+
+    Slick.prototype.checkResponsive = function() {
+
+        var _ = this,
+            breakpoint, targetBreakpoint, respondToWidth;
+        var sliderWidth = _.$slider.width();
+        var windowWidth = window.innerWidth || $(window).width();
+        if (_.respondTo === "window") {
+          respondToWidth = windowWidth;
+        } else if (_.respondTo === "slider") {
+          respondToWidth = sliderWidth;
+        } else if (_.respondTo === "min") {
+          respondToWidth = Math.min(windowWidth, sliderWidth);
+        }
+
+        if (_.originalSettings.responsive && _.originalSettings
+            .responsive.length > -1 && _.originalSettings.responsive !== null) {
+
+            targetBreakpoint = null;
+
+            for (breakpoint in _.breakpoints) {
+                if (_.breakpoints.hasOwnProperty(breakpoint)) {
+                    if (respondToWidth < _.breakpoints[breakpoint]) {
+                        targetBreakpoint = _.breakpoints[breakpoint];
+                    }
+                }
+            }
+
+            if (targetBreakpoint !== null) {
+                if (_.activeBreakpoint !== null) {
+                    if (targetBreakpoint !== _.activeBreakpoint) {
+                        _.activeBreakpoint =
+                            targetBreakpoint;
+                        _.options = $.extend({}, _.originalSettings,
+                            _.breakpointSettings[
+                                targetBreakpoint]);
+                        _.refresh();
+                    }
+                } else {
+                    _.activeBreakpoint = targetBreakpoint;
+                    _.options = $.extend({}, _.originalSettings,
+                        _.breakpointSettings[
+                            targetBreakpoint]);
+                    _.refresh();
+                }
+            } else {
+                if (_.activeBreakpoint !== null) {
+                    _.activeBreakpoint = null;
+                    _.options = _.originalSettings;
+                    _.refresh();
+                }
+            }
+
+        }
+
+    };
+
+    Slick.prototype.changeSlide = function(event, dontAnimate) {
+
+        var _ = this,
+            $target = $(event.target),
+            indexOffset, slideOffset, unevenOffset,navigables, prevNavigable;
+
+        // If target is a link, prevent default action.
+        $target.is('a') && event.preventDefault();
+
+        unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
+        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
+
+        switch (event.data.message) {
+
+            case 'previous':
+                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
+                if (_.slideCount > _.options.slidesToShow) {
+                    _.slideHandler(_.currentSlide  - slideOffset, false, dontAnimate);
+                }
+                break;
+
+            case 'next':
+                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
+                if (_.slideCount > _.options.slidesToShow) {
+                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
+                }
+                break;
+
+            case 'index':
+                var index = event.data.index === 0 ? 0 :
+                    event.data.index || $(event.target).parent().index() * _.options.slidesToScroll;
+
+                navigables = _.getNavigableIndexes();
+                prevNavigable = 0;
+                if(navigables[index] && navigables[index] === index) {
+                    if(index > navigables[navigables.length -1]){
+                        index = navigables[navigables.length -1];
+                    } else {
+                        for(var n in navigables) {
+                            if(index < navigables[n]) {
+                                index = prevNavigable;
+                                break;
+                            }
+                            prevNavigable = navigables[n];
+                        }
+                    }
+                }
+                _.slideHandler(index, false, dontAnimate);
+
+            default:
+                return;
+        }
+
+    };
+
+    Slick.prototype.clickHandler = function(event) {
+
+        var _ = this;
+
+        if(_.shouldClick === false) {
+            event.stopImmediatePropagation();
+            event.stopPropagation();
+            event.preventDefault();
+        }
+
+    }
+
+    Slick.prototype.destroy = function() {
+
+        var _ = this;
+
+        _.autoPlayClear();
+
+        _.touchObject = {};
+
+        $('.slick-cloned', _.$slider).remove();
+        if (_.$dots) {
+            _.$dots.remove();
+        }
+        if (_.$prevArrow && (typeof _.options.prevArrow !== 'object')) {
+            _.$prevArrow.remove();
+        }
+        if (_.$nextArrow && (typeof _.options.nextArrow !== 'object')) {
+            _.$nextArrow.remove();
+        }
+        if (_.$slides.parent().hasClass('slick-track')) {
+            _.$slides.unwrap().unwrap();
+        }
+
+        _.$slides.removeClass(
+            'slick-slide slick-active slick-center slick-visible')
+            .removeAttr('index')
+            .css({
+                position: '',
+                left: '',
+                top: '',
+                zIndex: '',
+                opacity: '',
+                width: ''
+            });
+
+        _.$slider.removeClass('slick-slider');
+        _.$slider.removeClass('slick-initialized');
+
+        _.$list.off('.slick');
+        $(window).off('.slick-' + _.instanceUid);
+        $(document).off('.slick-' + _.instanceUid);
+
+    };
+
+    Slick.prototype.disableTransition = function(slide) {
+
+        var _ = this,
+            transition = {};
+
+        transition[_.transitionType] = "";
+
+        if (_.options.fade === false) {
+            _.$slideTrack.css(transition);
+        } else {
+            _.$slides.eq(slide).css(transition);
+        }
+
+    };
+
+    Slick.prototype.fadeSlide = function(oldSlide, slideIndex, callback) {
+
+        var _ = this;
+
+        if (_.cssTransitions === false) {
+
+            _.$slides.eq(slideIndex).css({
+                zIndex: 1000
+            });
+
+            _.$slides.eq(slideIndex).animate({
+                opacity: 1
+            }, _.options.speed, _.options.easing, callback);
+
+            _.$slides.eq(oldSlide).animate({
+                opacity: 0
+            }, _.options.speed, _.options.easing);
+
+        } else {
+
+            _.applyTransition(slideIndex);
+            _.applyTransition(oldSlide);
+
+            _.$slides.eq(slideIndex).css({
+                opacity: 1,
+                zIndex: 1000
+            });
+
+            _.$slides.eq(oldSlide).css({
+                opacity: 0
+            });
+
+            if (callback) {
+                setTimeout(function() {
+
+                    _.disableTransition(slideIndex);
+                    _.disableTransition(oldSlide);
+
+                    callback.call();
+                }, _.options.speed);
+            }
+
+        }
+
+    };
+
+    Slick.prototype.filterSlides = function(filter) {
+
+        var _ = this;
+
+        if (filter !== null) {
+
+            _.unload();
+
+            _.$slideTrack.children(this.options.slide).detach();
+
+            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
+
+            _.reinit();
+
+        }
+
+    };
+
+    Slick.prototype.getCurrent = function() {
+
+        var _ = this;
+
+        return _.currentSlide;
+
+    };
+
+    Slick.prototype.getDotCount = function() {
+
+        var _ = this;
+
+        var breakPoint = 0;
+        var counter = 0;
+        var pagerQty = 0;
+
+        if(_.options.infinite === true) {
+            pagerQty = Math.ceil(_.slideCount / _.options.slidesToScroll);
+        } else {
+            while (breakPoint < _.slideCount){
+                ++pagerQty;
+                breakPoint = counter + _.options.slidesToShow;
+                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll  : _.options.slidesToShow;
+            }
+        }
+
+        return pagerQty - 1;
+
+    };
+
+    Slick.prototype.getLeft = function(slideIndex) {
+
+        var _ = this,
+            targetLeft,
+            verticalHeight,
+            verticalOffset = 0,
+            slideWidth,
+            targetSlide;
+
+        _.slideOffset = 0;
+        verticalHeight = _.$slides.first().outerHeight();
+
+        if (_.options.infinite === true) {
+            if (_.slideCount > _.options.slidesToShow) {
+                _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
+                verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
+            }
+            if (_.slideCount % _.options.slidesToScroll !== 0) {
+                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
+                    if(slideIndex > _.slideCount) {
+                        _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
+                        verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
+                    } else {
+                        _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
+                        verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
+                    }
+                }
+            }
+        } else {
+            if(slideIndex + _.options.slidesToShow > _.slideCount) {
+                _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
+                verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
+            }
+        }
+
+        if (_.slideCount <= _.options.slidesToShow){
+            _.slideOffset = 0;
+            verticalOffset = 0;
+        }
+
+        if (_.options.centerMode === true && _.options.infinite === true) {
+            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
+        } else if (_.options.centerMode === true) {
+            _.slideOffset = 0;
+            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
+        }
+
+        if (_.options.vertical === false) {
+            targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
+        } else {
+            targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
+        }
+
+        if (_.options.variableWidth === true) {
+
+            if(_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
+                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
+            } else {
+                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
+            }
+            targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
+            if (_.options.centerMode === true) {
+                if(_.options.infinite === false) {
+                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
+                } else {
+                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
+                }
+                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
+                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
+            }
+        }
+
+         // 1680
+
+        return targetLeft;
+
+    };
+
+    Slick.prototype.getNavigableIndexes = function() {
+
+        var _ = this;
+
+        var breakPoint = 0;
+        var counter = 0;
+        var indexes = [];
+
+        while (breakPoint < _.slideCount){
+            indexes.push(breakPoint);
+            breakPoint = counter + _.options.slidesToScroll;
+            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll  : _.options.slidesToShow;
+        }
+
+        return indexes;
+
+    };
+
+    Slick.prototype.getSlideCount = function() {
+
+        var _ = this, slidesTraversed;
+
+        if(_.options.swipeToSlide === true) {
+            var swipedSlide = null;
+            _.$slideTrack.find('.slick-slide').each(function(index, slide){
+                if (slide.offsetLeft + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
+                    swipedSlide = slide;
+                    return false;
+                }
+            });
+            slidesTraversed = Math.abs($(swipedSlide).attr('index') - _.currentSlide);
+            return slidesTraversed;
+        } else {
+            return _.options.slidesToScroll;
+        }
+
+    };
+
+    Slick.prototype.init = function() {
+
+        var _ = this;
+
+        if (!$(_.$slider).hasClass('slick-initialized')) {
+
+            $(_.$slider).addClass('slick-initialized');
+            _.buildOut();
+            _.setProps();
+            _.startLoad();
+            _.loadSlider();
+            _.initializeEvents();
+            _.updateArrows();
+            _.updateDots();
+        }
+
+        if (_.options.onInit !== null) {
+            _.options.onInit.call(this, _);
+        }
+
+    };
+
+    Slick.prototype.initArrowEvents = function() {
+
+        var _ = this;
+
+        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+            _.$prevArrow.on('click.slick', {
+                message: 'previous'
+            }, _.changeSlide);
+            _.$nextArrow.on('click.slick', {
+                message: 'next'
+            }, _.changeSlide);
+        }
+
+    };
+
+    Slick.prototype.initDotEvents = function() {
+
+        var _ = this;
+
+        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+            $('li', _.$dots).on('click.slick', {
+                message: 'index'
+            }, _.changeSlide);
+        }
+
+        if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.options.autoplay === true) {
+            $('li', _.$dots)
+                .on('mouseenter.slick', function(){
+                    _.paused = true;
+                    _.autoPlayClear();
+                })
+                .on('mouseleave.slick', function(){
+                    _.paused = false;
+                    _.autoPlay();
+                });
+        }
+
+    };
+
+    Slick.prototype.initializeEvents = function() {
+
+        var _ = this;
+
+        _.initArrowEvents();
+
+        _.initDotEvents();
+
+        _.$list.on('touchstart.slick mousedown.slick', {
+            action: 'start'
+        }, _.swipeHandler);
+        _.$list.on('touchmove.slick mousemove.slick', {
+            action: 'move'
+        }, _.swipeHandler);
+        _.$list.on('touchend.slick mouseup.slick', {
+            action: 'end'
+        }, _.swipeHandler);
+        _.$list.on('touchcancel.slick mouseleave.slick', {
+            action: 'end'
+        }, _.swipeHandler);
+
+        _.$list.on('click.slick', _.clickHandler);
+
+        if (_.options.pauseOnHover === true && _.options.autoplay === true) {
+            _.$list.on('mouseenter.slick', function(){
+                _.paused = true;
+                _.autoPlayClear();
+            });
+            _.$list.on('mouseleave.slick', function(){
+                _.paused = false;
+                _.autoPlay();
+            });
+        }
+
+        if(_.options.accessibility === true) {
+            _.$list.on('keydown.slick', _.keyHandler);
+        }
+
+        if(_.options.focusOnSelect === true) {
+            $(_.options.slide, _.$slideTrack).on('click.slick', _.selectHandler);
+        }
+
+        $(window).on('orientationchange.slick.slick-' + _.instanceUid, function() {
+            _.checkResponsive();
+            _.setPosition();
+        });
+
+        $(window).on('resize.slick.slick-' + _.instanceUid, function() {
+            if ($(window).width() !== _.windowWidth) {
+                clearTimeout(_.windowDelay);
+                _.windowDelay = window.setTimeout(function() {
+                    _.windowWidth = $(window).width();
+                    _.checkResponsive();
+                    _.setPosition();
+                }, 50);
+            }
+        });
+
+        $('*[draggable!=true]', _.$slideTrack).on('dragstart', function(e){ e.preventDefault(); })
+
+        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
+        $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
+
+    };
+
+    Slick.prototype.initUI = function() {
+
+        var _ = this;
+
+        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+
+            _.$prevArrow.show();
+            _.$nextArrow.show();
+
+        }
+
+        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+            _.$dots.show();
+
+        }
+
+        if (_.options.autoplay === true) {
+
+            _.autoPlay();
+
+        }
+
+    };
+
+    Slick.prototype.keyHandler = function(event) {
+
+        var _ = this;
+
+        if (event.keyCode === 37 && _.options.accessibility === true) {
+            _.changeSlide({
+                data: {
+                    message: 'previous'
+                }
+            });
+        } else if (event.keyCode === 39 && _.options.accessibility === true) {
+            _.changeSlide({
+                data: {
+                    message: 'next'
+                }
+            });
+        }
+
+    };
+
+    Slick.prototype.lazyLoad = function() {
+
+        var _ = this,
+            loadRange, cloneRange, rangeStart, rangeEnd;
+
+        function loadImages(imagesScope) {
+            $('img[data-lazy]', imagesScope).each(function() {
+                var image = $(this),
+                    imageSource = $(this).attr('data-lazy');
+
+                image
+                  .load(function() { image.animate({ opacity: 1 }, 200); })
+                  .css({ opacity: 0 })
+                  .attr('src', imageSource)
+                  .removeAttr('data-lazy')
+                  .removeClass('slick-loading');
+            });
+        }
+
+        if (_.options.centerMode === true) {
+            if (_.options.infinite === true) {
+                rangeStart = _.currentSlide + (_.options.slidesToShow/2 + 1);
+                rangeEnd = rangeStart + _.options.slidesToShow + 2;
+            } else {
+                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow/2 + 1));
+                rangeEnd = 2 + (_.options.slidesToShow/2 + 1) + _.currentSlide;
+            }
+        } else {
+            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
+            rangeEnd = rangeStart + _.options.slidesToShow;
+            if (_.options.fade === true ) {
+                if(rangeStart > 0) rangeStart--;
+                if(rangeEnd <= _.slideCount) rangeEnd++;
+            }
+        }
+
+        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
+        loadImages(loadRange);
+
+          if (_.slideCount <= _.options.slidesToShow){
+              cloneRange = _.$slider.find('.slick-slide')
+              loadImages(cloneRange)
+          }else
+        if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
+            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
+            loadImages(cloneRange)
+        } else if (_.currentSlide === 0) {
+            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
+            loadImages(cloneRange);
+        }
+
+    };
+
+    Slick.prototype.loadSlider = function() {
+
+        var _ = this;
+
+        _.setPosition();
+
+        _.$slideTrack.css({
+            opacity: 1
+        });
+
+        _.$slider.removeClass('slick-loading');
+
+        _.initUI();
+
+        if (_.options.lazyLoad === 'progressive') {
+            _.progressiveLazyLoad();
+        }
+
+    };
+
+    Slick.prototype.postSlide = function(index) {
+
+        var _ = this;
+
+        if (_.options.onAfterChange !== null) {
+            _.options.onAfterChange.call(this, _, index);
+        }
+
+        _.animating = false;
+
+        _.setPosition();
+
+        _.swipeLeft = null;
+
+        if (_.options.autoplay === true && _.paused === false) {
+            _.autoPlay();
+        }
+
+    };
+
+    Slick.prototype.progressiveLazyLoad = function() {
+
+        var _ = this,
+            imgCount, targetImage;
+
+        imgCount = $('img[data-lazy]', _.$slider).length;
+
+        if (imgCount > 0) {
+            targetImage = $('img[data-lazy]', _.$slider).first();
+            targetImage.attr('src', targetImage.attr('data-lazy')).removeClass('slick-loading').load(function() {
+                targetImage.removeAttr('data-lazy');
+                _.progressiveLazyLoad();
+            })
+         .error(function () {
+          targetImage.removeAttr('data-lazy');
+          _.progressiveLazyLoad();
+         });
+        }
+
+    };
+
+    Slick.prototype.refresh = function() {
+
+        var _ = this,
+            currentSlide = _.currentSlide;
+
+        _.destroy();
+
+        $.extend(_, _.initials);
+
+        _.init();
+
+        _.changeSlide({
+            data: {
+                message: 'index',
+                index: currentSlide,
+            }
+        }, true);
+
+    };
+
+    Slick.prototype.reinit = function() {
+
+        var _ = this;
+
+        _.$slides = _.$slideTrack.children(_.options.slide).addClass(
+            'slick-slide');
+
+        _.slideCount = _.$slides.length;
+
+        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
+            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
+        }
+
+        if (_.slideCount <= _.options.slidesToShow) {
+            _.currentSlide = 0;
+        }
+
+        _.setProps();
+
+        _.setupInfinite();
+
+        _.buildArrows();
+
+        _.updateArrows();
+
+        _.initArrowEvents();
+
+        _.buildDots();
+
+        _.updateDots();
+
+        _.initDotEvents();
+
+        if(_.options.focusOnSelect === true) {
+            $(_.options.slide, _.$slideTrack).on('click.slick', _.selectHandler);
+        }
+
+        _.setSlideClasses(0);
+
+        _.setPosition();
+
+        if (_.options.onReInit !== null) {
+            _.options.onReInit.call(this, _);
+        }
+
+    };
+
+    Slick.prototype.removeSlide = function(index, removeBefore, removeAll) {
+
+        var _ = this;
+
+        if (typeof(index) === 'boolean') {
+            removeBefore = index;
+            index = removeBefore === true ? 0 : _.slideCount - 1;
+        } else {
+            index = removeBefore === true ? --index : index;
+        }
+
+        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
+            return false;
+        }
+
+        _.unload();
+
+        if(removeAll === true) {
+            _.$slideTrack.children().remove();
+        } else {
+            _.$slideTrack.children(this.options.slide).eq(index).remove();
+        }
+
+        _.$slides = _.$slideTrack.children(this.options.slide);
+
+        _.$slideTrack.children(this.options.slide).detach();
+
+        _.$slideTrack.append(_.$slides);
+
+        _.$slidesCache = _.$slides;
+
+        _.reinit();
+
+    };
+
+    Slick.prototype.setCSS = function(position) {
+
+        var _ = this,
+            positionProps = {}, x, y;
+
+        if (_.options.rtl === true) {
+            position = -position;
+        }
+        x = _.positionProp == 'left' ? position + 'px' : '0px';
+        y = _.positionProp == 'top' ? position + 'px' : '0px';
+
+        positionProps[_.positionProp] = position;
+
+        if (_.transformsEnabled === false) {
+            _.$slideTrack.css(positionProps);
+        } else {
+            positionProps = {};
+            if (_.cssTransitions === false) {
+                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
+                _.$slideTrack.css(positionProps);
+            } else {
+                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
+                _.$slideTrack.css(positionProps);
+            }
+        }
+
+    };
+
+    Slick.prototype.setDimensions = function() {
+
+        var _ = this;
+
+        if (_.options.vertical === false) {
+            if (_.options.centerMode === true) {
+                _.$list.css({
+                    padding: ('0px ' + _.options.centerPadding)
+                });
+            }
+        } else {
+            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
+            if (_.options.centerMode === true) {
+                _.$list.css({
+                    padding: (_.options.centerPadding + ' 0px')
+                });
+            }
+        }
+
+        _.listWidth = _.$list.width();
+        _.listHeight = _.$list.height();
+
+
+        if(_.options.vertical === false && _.options.variableWidth === false) {
+            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
+            _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
+
+        } else if (_.options.variableWidth === true) {
+            var trackWidth = 0;
+            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
+            _.$slideTrack.children('.slick-slide').each(function(){
+                trackWidth += Math.ceil($(this).outerWidth(true));
+            });
+            _.$slideTrack.width(Math.ceil(trackWidth) + 1);
+        } else {
+            _.slideWidth = Math.ceil(_.listWidth);
+            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
+        }
+
+        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
+        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
+
+    };
+
+    Slick.prototype.setFade = function() {
+
+        var _ = this,
+            targetLeft;
+
+        _.$slides.each(function(index, element) {
+            targetLeft = (_.slideWidth * index) * -1;
+            if (_.options.rtl === true) {
+                $(element).css({
+                    position: 'relative',
+                    right: targetLeft,
+                    top: 0,
+                    zIndex: 800,
+                    opacity: 0
+                });
+            } else {
+                $(element).css({
+                    position: 'relative',
+                    left: targetLeft,
+                    top: 0,
+                    zIndex: 800,
+                    opacity: 0
+                });
+            }
+        });
+
+        _.$slides.eq(_.currentSlide).css({
+            zIndex: 900,
+            opacity: 1
+        });
+
+    };
+
+    Slick.prototype.setHeight = function() {
+
+        var _ = this;
+
+        if(_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
+            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
+            _.$list.css('height', targetHeight);
+        }
+
+    };
+
+    Slick.prototype.setPosition = function() {
+
+        var _ = this;
+
+        _.setDimensions();
+
+        _.setHeight();
+
+        if (_.options.fade === false) {
+            _.setCSS(_.getLeft(_.currentSlide));
+        } else {
+            _.setFade();
+        }
+
+        if (_.options.onSetPosition !== null) {
+            _.options.onSetPosition.call(this, _);
+        }
+
+    };
+
+    Slick.prototype.setProps = function() {
+
+        var _ = this,
+            bodyStyle = document.body.style;
+
+        _.positionProp = _.options.vertical === true ? 'top' : 'left';
+
+        if (_.positionProp === 'top') {
+            _.$slider.addClass('slick-vertical');
+        } else {
+            _.$slider.removeClass('slick-vertical');
+        }
+
+        if (bodyStyle.WebkitTransition !== undefined ||
+            bodyStyle.MozTransition !== undefined ||
+            bodyStyle.msTransition !== undefined) {
+            if(_.options.useCSS === true) {
+                _.cssTransitions = true;
+            }
+        }
+
+        if (bodyStyle.OTransform !== undefined) {
+            _.animType = 'OTransform';
+            _.transformType = "-o-transform";
+            _.transitionType = 'OTransition';
+            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
+        }
+        if (bodyStyle.MozTransform !== undefined) {
+            _.animType = 'MozTransform';
+            _.transformType = "-moz-transform";
+            _.transitionType = 'MozTransition';
+            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
+        }
+        if (bodyStyle.webkitTransform !== undefined) {
+            _.animType = 'webkitTransform';
+            _.transformType = "-webkit-transform";
+            _.transitionType = 'webkitTransition';
+            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
+        }
+        if (bodyStyle.msTransform !== undefined) {
+            _.animType = 'msTransform';
+            _.transformType = "-ms-transform";
+            _.transitionType = 'msTransition';
+            if (bodyStyle.msTransform === undefined) _.animType = false;
+        }
+        if (bodyStyle.transform !== undefined && _.animType !== false) {
+            _.animType = 'transform';
+            _.transformType = "transform";
+            _.transitionType = 'transition';
+        }
+        _.transformsEnabled = (_.animType !== null && _.animType !== false);
+
+    };
+
+
+    Slick.prototype.setSlideClasses = function(index) {
+
+        var _ = this,
+            centerOffset, allSlides, indexOffset, remainder;
+
+        _.$slider.find('.slick-slide').removeClass('slick-active').removeClass('slick-center');
+        allSlides = _.$slider.find('.slick-slide');
+
+        if (_.options.centerMode === true) {
+
+            centerOffset = Math.floor(_.options.slidesToShow / 2);
+
+            if(_.options.infinite === true) {
+
+                if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
+                    _.$slides.slice(index - centerOffset, index + centerOffset + 1).addClass('slick-active');
+                } else {
+                    indexOffset = _.options.slidesToShow + index;
+                    allSlides.slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2).addClass('slick-active');
+                }
+
+                if (index === 0) {
+                    allSlides.eq(allSlides.length - 1 - _.options.slidesToShow).addClass('slick-center');
+                } else if (index === _.slideCount - 1) {
+                    allSlides.eq(_.options.slidesToShow).addClass('slick-center');
+                }
+
+            }
+
+            _.$slides.eq(index).addClass('slick-center');
+
+        } else {
+
+            if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
+                _.$slides.slice(index, index + _.options.slidesToShow).addClass('slick-active');
+            } else if ( allSlides.length <= _.options.slidesToShow ) {
+                allSlides.addClass('slick-active');
+            } else {
+                remainder = _.slideCount%_.options.slidesToShow;
+                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
+                if(_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
+                    allSlides.slice(indexOffset-(_.options.slidesToShow-remainder), indexOffset + remainder).addClass('slick-active');
+                } else {
+                    allSlides.slice(indexOffset, indexOffset + _.options.slidesToShow).addClass('slick-active');
+                }
+            }
+
+        }
+
+        if (_.options.lazyLoad === 'ondemand') {
+            _.lazyLoad();
+        }
+
+    };
+
+    Slick.prototype.setupInfinite = function() {
+
+        var _ = this,
+            i, slideIndex, infiniteCount;
+
+        if (_.options.fade === true) {
+            _.options.centerMode = false;
+        }
+
+        if (_.options.infinite === true && _.options.fade === false) {
+
+            slideIndex = null;
+
+            if (_.slideCount > _.options.slidesToShow) {
+
+                if (_.options.centerMode === true) {
+                    infiniteCount = _.options.slidesToShow + 1;
+                } else {
+                    infiniteCount = _.options.slidesToShow;
+                }
+
+                for (i = _.slideCount; i > (_.slideCount -
+                    infiniteCount); i -= 1) {
+                    slideIndex = i - 1;
+                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
+                        .attr('index', slideIndex-_.slideCount)
+                        .prependTo(_.$slideTrack).addClass('slick-cloned');
+                }
+                for (i = 0; i < infiniteCount; i += 1) {
+                    slideIndex = i;
+                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
+                        .attr('index', slideIndex+_.slideCount)
+                        .appendTo(_.$slideTrack).addClass('slick-cloned');
+                }
+                _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
+                    $(this).attr('id', '');
+                });
+
+            }
+
+        }
+
+    };
+
+    Slick.prototype.selectHandler = function(event) {
+
+        var _ = this;
+        var index = parseInt($(event.target).parents('.slick-slide').attr("index"));
+        if(!index) index = 0;
+
+        if(_.slideCount <= _.options.slidesToShow){
+            _.$slider.find('.slick-slide').removeClass('slick-active');
+            _.$slides.eq(index).addClass('slick-active');
+            if(_.options.centerMode === true) {
+                _.$slider.find('.slick-slide').removeClass('slick-center');
+                _.$slides.eq(index).addClass('slick-center');
+            }
+            _.asNavFor(index);
+            return;
+        }
+        _.slideHandler(index);
+
+    };
+
+    Slick.prototype.slideHandler = function(index,sync,dontAnimate) {
+
+        var targetSlide, animSlide, oldSlide, slideLeft, unevenOffset, targetLeft = null,
+            _ = this;
+
+        sync = sync || false;
+
+        if (_.animating === true && _.options.waitForAnimate === true) {
+            return;
+        }
+
+        if (_.options.fade === true && _.currentSlide === index) {
+            return;
+        }
+
+        if (_.slideCount <= _.options.slidesToShow) {
+            return;
+        }
+
+        if (sync === false) {
+            _.asNavFor(index);
+        }
+
+        targetSlide = index;
+        targetLeft = _.getLeft(targetSlide);
+        slideLeft = _.getLeft(_.currentSlide);
+
+        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
+
+        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
+            if(_.options.fade === false) {
+                targetSlide = _.currentSlide;
+                if(dontAnimate!==true) {
+                    _.animateSlide(slideLeft, function() {
+                        _.postSlide(targetSlide);
+                    });
+                } else {
+                    _.postSlide(targetSlide);
+                }
+            }
+            return;
+        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
+            if(_.options.fade === false) {
+                targetSlide = _.currentSlide;
+                if(dontAnimate!==true) {
+                    _.animateSlide(slideLeft, function() {
+                        _.postSlide(targetSlide);
+                    });
+                } else {
+                    _.postSlide(targetSlide);
+                }
+            }
+            return;
+        }
+
+        if (_.options.autoplay === true) {
+            clearInterval(_.autoPlayTimer);
+        }
+
+        if (targetSlide < 0) {
+            if (_.slideCount % _.options.slidesToScroll !== 0) {
+                animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
+            } else {
+                animSlide = _.slideCount + targetSlide;
+            }
+        } else if (targetSlide >= _.slideCount) {
+            if (_.slideCount % _.options.slidesToScroll !== 0) {
+                animSlide = 0;
+            } else {
+                animSlide = targetSlide - _.slideCount;
+            }
+        } else {
+            animSlide = targetSlide;
+        }
+
+        _.animating = true;
+
+        if (_.options.onBeforeChange !== null && index !== _.currentSlide) {
+            _.options.onBeforeChange.call(this, _, _.currentSlide, animSlide);
+        }
+
+        oldSlide = _.currentSlide;
+        _.currentSlide = animSlide;
+
+        _.setSlideClasses(_.currentSlide);
+
+        _.updateDots();
+        _.updateArrows();
+
+        if (_.options.fade === true) {
+            if(dontAnimate!==true) {
+                _.fadeSlide(oldSlide,animSlide, function() {
+                    _.postSlide(animSlide);
+                });
+            } else {
+                _.postSlide(animSlide);
+            }
+            return;
+        }
+
+        if(dontAnimate!==true) {
+            _.animateSlide(targetLeft, function() {
+                _.postSlide(animSlide);
+            });
+        } else {
+            _.postSlide(animSlide);
+        }
+
+    };
+
+    Slick.prototype.startLoad = function() {
+
+        var _ = this;
+
+        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+
+            _.$prevArrow.hide();
+            _.$nextArrow.hide();
+
+        }
+
+        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+            _.$dots.hide();
+
+        }
+
+        _.$slider.addClass('slick-loading');
+
+    };
+
+    Slick.prototype.swipeDirection = function() {
+
+        var xDist, yDist, r, swipeAngle, _ = this;
+
+        xDist = _.touchObject.startX - _.touchObject.curX;
+        yDist = _.touchObject.startY - _.touchObject.curY;
+        r = Math.atan2(yDist, xDist);
+
+        swipeAngle = Math.round(r * 180 / Math.PI);
+        if (swipeAngle < 0) {
+            swipeAngle = 360 - Math.abs(swipeAngle);
+        }
+
+        if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
+            return (_.options.rtl === false ? 'left' : 'right');
+        }
+        if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
+            return (_.options.rtl === false ? 'left' : 'right');
+        }
+        if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
+            return (_.options.rtl === false ? 'right' : 'left');
+        }
+
+        return 'vertical';
+
+    };
+
+    Slick.prototype.swipeEnd = function(event) {
+
+        var _ = this, slideCount;
+
+        _.dragging = false;
+
+        _.shouldClick = (_.touchObject.swipeLength > 10) ? false : true;
+
+        if (_.touchObject.curX === undefined) {
+            return false;
+        }
+
+        if (_.touchObject.swipeLength >= _.touchObject.minSwipe) {
+
+            switch (_.swipeDirection()) {
+                case 'left':
+                    _.slideHandler(_.currentSlide + _.getSlideCount());
+                    _.currentDirection = 0;
+                    _.touchObject = {};
+                    break;
+
+                case 'right':
+                    _.slideHandler(_.currentSlide - _.getSlideCount());
+                    _.currentDirection = 1;
+                    _.touchObject = {};
+                    break;
+            }
+        } else {
+            if(_.touchObject.startX !== _.touchObject.curX) {
+                _.slideHandler(_.currentSlide);
+                _.touchObject = {};
+            }
+        }
+
+    };
+
+    Slick.prototype.swipeHandler = function(event) {
+
+        var _ = this;
+
+        if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
+           return;
+        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
+           return;
+        }
+
+        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
+            event.originalEvent.touches.length : 1;
+
+        _.touchObject.minSwipe = _.listWidth / _.options
+            .touchThreshold;
+
+        switch (event.data.action) {
+
+            case 'start':
+                _.swipeStart(event);
+                break;
+
+            case 'move':
+                _.swipeMove(event);
+                break;
+
+            case 'end':
+                _.swipeEnd(event);
+                break;
+
+        }
+
+    };
+
+    Slick.prototype.swipeMove = function(event) {
+
+        var _ = this,
+            curLeft, swipeDirection, positionOffset, touches;
+
+        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
+
+        if (!_.dragging || touches && touches.length !== 1) {
+            return false;
+        }
+
+        curLeft = _.getLeft(_.currentSlide);
+
+        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
+        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
+
+        _.touchObject.swipeLength = Math.round(Math.sqrt(
+            Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
+
+        swipeDirection = _.swipeDirection();
+
+        if (swipeDirection === 'vertical') {
+            return;
+        }
+
+        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
+            event.preventDefault();
+        }
+
+        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
+
+        if (_.options.vertical === false) {
+            _.swipeLeft = curLeft + _.touchObject.swipeLength * positionOffset;
+        } else {
+            _.swipeLeft = curLeft + (_.touchObject
+                .swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
+        }
+
+        if (_.options.fade === true || _.options.touchMove === false) {
+            return false;
+        }
+
+        if (_.animating === true) {
+            _.swipeLeft = null;
+            return false;
+        }
+
+        _.setCSS(_.swipeLeft);
+
+    };
+
+    Slick.prototype.swipeStart = function(event) {
+
+        var _ = this,
+            touches;
+
+        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
+            _.touchObject = {};
+            return false;
+        }
+
+        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
+            touches = event.originalEvent.touches[0];
+        }
+
+        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
+        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
+
+        _.dragging = true;
+
+    };
+
+    Slick.prototype.unfilterSlides = function() {
+
+        var _ = this;
+
+        if (_.$slidesCache !== null) {
+
+            _.unload();
+
+            _.$slideTrack.children(this.options.slide).detach();
+
+            _.$slidesCache.appendTo(_.$slideTrack);
+
+            _.reinit();
+
+        }
+
+    };
+
+    Slick.prototype.unload = function() {
+
+        var _ = this;
+
+        $('.slick-cloned', _.$slider).remove();
+        if (_.$dots) {
+            _.$dots.remove();
+        }
+        if (_.$prevArrow && (typeof _.options.prevArrow !== 'object')) {
+            _.$prevArrow.remove();
+        }
+        if (_.$nextArrow && (typeof _.options.nextArrow !== 'object')) {
+            _.$nextArrow.remove();
+        }
+        _.$slides.removeClass(
+            'slick-slide slick-active slick-visible').css('width', '');
+
+    };
+
+    Slick.prototype.updateArrows = function() {
+
+        var _ = this, centerOffset;
+
+        centerOffset = Math.floor(_.options.slidesToShow / 2)
+
+        if (_.options.arrows === true && _.options.infinite !==
+            true && _.slideCount > _.options.slidesToShow) {
+            _.$prevArrow.removeClass('slick-disabled');
+            _.$nextArrow.removeClass('slick-disabled');
+            if (_.currentSlide === 0) {
+                _.$prevArrow.addClass('slick-disabled');
+                _.$nextArrow.removeClass('slick-disabled');
+            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
+                _.$nextArrow.addClass('slick-disabled');
+                _.$prevArrow.removeClass('slick-disabled');
+            } else if (_.currentSlide > _.slideCount - _.options.slidesToShow + centerOffset  && _.options.centerMode === true) {
+                _.$nextArrow.addClass('slick-disabled');
+                _.$prevArrow.removeClass('slick-disabled');
+            }
+        }
+
+    };
+
+    Slick.prototype.updateDots = function() {
+
+        var _ = this;
+
+        if (_.$dots !== null) {
+
+            _.$dots.find('li').removeClass('slick-active');
+            _.$dots.find('li').eq(Math.floor(_.currentSlide / _.options.slidesToScroll)).addClass('slick-active');
+
+        }
+
+    };
+
+    $.fn.slick = function(options) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick = new Slick(element, options);
+
+        });
+    };
+
+    $.fn.slickAdd = function(slide, slideIndex, addBefore) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.addSlide(slide, slideIndex, addBefore);
+
+        });
+    };
+
+    $.fn.slickCurrentSlide = function() {
+        var _ = this;
+        return _.get(0).slick.getCurrent();
+    };
+
+    $.fn.slickFilter = function(filter) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.filterSlides(filter);
+
+        });
+    };
+
+    $.fn.slickGoTo = function(slide, dontAnimate) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.changeSlide({
+                data: {
+                    message: 'index',
+                    index: parseInt(slide)
+                }
+            }, dontAnimate);
+
+        });
+    };
+
+    $.fn.slickNext = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.changeSlide({
+                data: {
+                    message: 'next'
+                }
+            });
+
+        });
+    };
+
+    $.fn.slickPause = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.autoPlayClear();
+            element.slick.paused = true;
+
+        });
+    };
+
+    $.fn.slickPlay = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.paused = false;
+            element.slick.autoPlay();
+
+        });
+    };
+
+    $.fn.slickPrev = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.changeSlide({
+                data: {
+                    message: 'previous'
+                }
+            });
+
+        });
+    };
+
+    $.fn.slickRemove = function(slideIndex, removeBefore) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.removeSlide(slideIndex, removeBefore);
+
+        });
+    };
+
+    $.fn.slickRemoveAll = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.removeSlide(null, null, true);
+
+        });
+    };
+
+    $.fn.slickGetOption = function(option) {
+        var _ = this;
+        return _.get(0).slick.options[option];
+    };
+
+    $.fn.slickSetOption = function(option, value, refresh) {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.options[option] = value;
+
+            if (refresh === true) {
+                element.slick.unload();
+                element.slick.reinit();
+            }
+
+        });
+    };
+
+    $.fn.slickUnfilter = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+            element.slick.unfilterSlides();
+
+        });
+    };
+
+    $.fn.unslick = function() {
+        var _ = this;
+        return _.each(function(index, element) {
+
+          if (element.slick) {
+            element.slick.destroy();
+          }
+
+        });
+    };
+
+    $.fn.getSlick = function() {
+        var s = null;
+        var _ = this;
+        _.each(function(index, element) {
+            s = element.slick;
+        });
+
+        return s;
+    };
+
+}));
diff --git a/src/main/resources/META-INF/resources/designer/lib/translate-substitution.js b/src/main/resources/META-INF/resources/designer/lib/translate-substitution.js
new file mode 100644 (file)
index 0000000..7722ad9
--- /dev/null
@@ -0,0 +1,60 @@
+//== Translate Substitute Module =============================================//
+
+/**
+ * For those not using Angular-Translate (pascalprecht.translate), this will sub
+ * in for it so we don't have to include Angular-Translate if we don't want to.
+ */
+
+var translateSubMod = angular.module('translate.sub',[]);
+
+       /**
+        * $translate Service
+        * Sets up a $translateProvider service to use in your module's config
+        * function.  $translate.Provider syntax is the same as Angular-Translate,
+        * use $translate.Provider.translations(lang,obj) to change the defaults
+        * for modal button, header and message text.
+        */
+       translateSubMod.provider('$translate',[function(){
+               var _translations = []; // object of key/value translation pairs
+               var _current = 'en-US'; // default language
+
+               /**
+                * Translations
+                * Set the internal object of translation key/value pairs.
+                */
+               this.translations = function(lang,obj){
+                       if(angular.isDefined(lang) && angular.isDefined(obj)){
+                               _translations[lang] = angular.copy(obj);
+                               _current = lang;
+                       }
+               }; // end translations
+
+               this.$get = [function(){
+                       return {
+                               /**
+                                * Instant
+                                * Retrieve the translation for the given key, if key not found
+                                * return an empty string.
+                                * Example: $translate.instant('DIALOGS_OK');
+                                */
+                               instant : function(what){
+                                       if(angular.isDefined(what) && angular.isDefined(_translations[_current][what]))
+                                               return _translations[_current][what];
+                                       else
+                                               return '';
+                               } // end instant
+                       }; // end return 
+               }]; // end $get
+
+       }]); // end $translate
+
+       /**
+        * Translate Filter
+        * For use in an Angular template.  
+        * Example: {{"DIALOGS_CLOSE" | translate}}
+        */
+       translateSubMod.filter('translate',['$translate',function($translate){
+               return function(what){
+                       return $translate.instant(what);
+               };
+       }]); // end translate / translate.sub
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-bootstrap-tpls.js b/src/main/resources/META-INF/resources/designer/lib/ui-bootstrap-tpls.js
new file mode 100644 (file)
index 0000000..ff66da3
--- /dev/null
@@ -0,0 +1,3677 @@
+/*
+ * angular-ui-bootstrap
+ * http://angular-ui.github.io/bootstrap/
+
+ * Version: 0.10.0 - 2014-01-13
+ * License: MIT
+ */
+angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
+angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]);
+angular.module('ui.bootstrap.transition', [])
+
+/**
+ * $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
+ * @param  {DOMElement} element  The DOMElement that will be animated.
+ * @param  {string|object|function} trigger  The thing that will cause the transition to start:
+ *   - As a string, it represents the css class to be added to the element.
+ *   - As an object, it represents a hash of style attributes to be applied to the element.
+ *   - As a function, it represents a function to be called that will cause the transition to occur.
+ * @return {Promise}  A promise that is resolved when the transition finishes.
+ */
+.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
+
+  var $transition = function(element, trigger, options) {
+    options = options || {};
+    var deferred = $q.defer();
+    var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"];
+
+    var transitionEndHandler = function(event) {
+      $rootScope.$apply(function() {
+        element.unbind(endEventName, transitionEndHandler);
+        deferred.resolve(element);
+      });
+    };
+
+    if (endEventName) {
+      element.bind(endEventName, transitionEndHandler);
+    }
+
+    // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
+    $timeout(function() {
+      if ( angular.isString(trigger) ) {
+        element.addClass(trigger);
+      } else if ( angular.isFunction(trigger) ) {
+        trigger(element);
+      } else if ( angular.isObject(trigger) ) {
+        element.css(trigger);
+      }
+      //If browser does not support transitions, instantly resolve
+      if ( !endEventName ) {
+        deferred.resolve(element);
+      }
+    });
+
+    // Add our custom cancel function to the promise that is returned
+    // We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
+    // i.e. it will therefore never raise a transitionEnd event for that transition
+    deferred.promise.cancel = function() {
+      if ( endEventName ) {
+        element.unbind(endEventName, transitionEndHandler);
+      }
+      deferred.reject('Transition cancelled');
+    };
+
+    return deferred.promise;
+  };
+
+  // Work out the name of the transitionEnd event
+  var transElement = document.createElement('trans');
+  var transitionEndEventNames = {
+    'WebkitTransition': 'webkitTransitionEnd',
+    'MozTransition': 'transitionend',
+    'OTransition': 'oTransitionEnd',
+    'transition': 'transitionend'
+  };
+  var animationEndEventNames = {
+    'WebkitTransition': 'webkitAnimationEnd',
+    'MozTransition': 'animationend',
+    'OTransition': 'oAnimationEnd',
+    'transition': 'animationend'
+  };
+  function findEndEventName(endEventNames) {
+    for (var name in endEventNames){
+      if (transElement.style[name] !== undefined) {
+        return endEventNames[name];
+      }
+    }
+  }
+  $transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
+  $transition.animationEndEventName = findEndEventName(animationEndEventNames);
+  return $transition;
+}]);
+
+angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition'])
+
+  .directive('collapse', ['$transition', function ($transition, $timeout) {
+
+    return {
+      link: function (scope, element, attrs) {
+
+        var initialAnimSkip = true;
+        var currentTransition;
+
+        function doTransition(change) {
+          var newTransition = $transition(element, change);
+          if (currentTransition) {
+            currentTransition.cancel();
+          }
+          currentTransition = newTransition;
+          newTransition.then(newTransitionDone, newTransitionDone);
+          return newTransition;
+
+          function newTransitionDone() {
+            // Make sure it's this transition, otherwise, leave it alone.
+            if (currentTransition === newTransition) {
+              currentTransition = undefined;
+            }
+          }
+        }
+
+        function expand() {
+          if (initialAnimSkip) {
+            initialAnimSkip = false;
+            expandDone();
+          } else {
+            element.removeClass('collapse').addClass('collapsing');
+            doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone);
+          }
+        }
+
+        function expandDone() {
+          element.removeClass('collapsing');
+          element.addClass('collapse in');
+          element.css({height: 'auto'});
+        }
+
+        function collapse() {
+          if (initialAnimSkip) {
+            initialAnimSkip = false;
+            collapseDone();
+            element.css({height: 0});
+          } else {
+            // CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
+            element.css({ height: element[0].scrollHeight + 'px' });
+            //trigger reflow so a browser realizes that height was updated from auto to a specific value
+            var x = element[0].offsetWidth;
+
+            element.removeClass('collapse in').addClass('collapsing');
+
+            doTransition({ height: 0 }).then(collapseDone);
+          }
+        }
+
+        function collapseDone() {
+          element.removeClass('collapsing');
+          element.addClass('collapse');
+        }
+
+        scope.$watch(attrs.collapse, function (shouldCollapse) {
+          if (shouldCollapse) {
+            collapse();
+          } else {
+            expand();
+          }
+        });
+      }
+    };
+  }]);
+
+angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
+
+.constant('accordionConfig', {
+  closeOthers: true
+})
+
+.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {
+
+  // This array keeps track of the accordion groups
+  this.groups = [];
+
+  // Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
+  this.closeOthers = function(openGroup) {
+    var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
+    if ( closeOthers ) {
+      angular.forEach(this.groups, function (group) {
+        if ( group !== openGroup ) {
+          group.isOpen = false;
+        }
+      });
+    }
+  };
+  
+  // This is called from the accordion-group directive to add itself to the accordion
+  this.addGroup = function(groupScope) {
+    var that = this;
+    this.groups.push(groupScope);
+
+    groupScope.$on('$destroy', function (event) {
+      that.removeGroup(groupScope);
+    });
+  };
+
+  // This is called from the accordion-group directive when to remove itself
+  this.removeGroup = function(group) {
+    var index = this.groups.indexOf(group);
+    if ( index !== -1 ) {
+      this.groups.splice(this.groups.indexOf(group), 1);
+    }
+  };
+
+}])
+
+// The accordion directive simply sets up the directive controller
+// and adds an accordion CSS class to itself element.
+.directive('accordion', function () {
+  return {
+    restrict:'EA',
+    controller:'AccordionController',
+    transclude: true,
+    replace: false,
+    templateUrl: 'template/accordion/accordion.html'
+  };
+})
+
+// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
+.directive('accordionGroup', ['$parse', function($parse) {
+  return {
+    require:'^accordion',         // We need this directive to be inside an accordion
+    restrict:'EA',
+    transclude:true,              // It transcludes the contents of the directive into the template
+    replace: true,                // The element containing the directive will be replaced with the template
+    templateUrl:'template/accordion/accordion-group.html',
+    scope:{ heading:'@' },        // Create an isolated scope and interpolate the heading attribute onto this scope
+    controller: function() {
+      this.setHeading = function(element) {
+        this.heading = element;
+      };
+    },
+    link: function(scope, element, attrs, accordionCtrl) {
+      var getIsOpen, setIsOpen;
+
+      accordionCtrl.addGroup(scope);
+
+      scope.isOpen = false;
+      
+      if ( attrs.isOpen ) {
+        getIsOpen = $parse(attrs.isOpen);
+        setIsOpen = getIsOpen.assign;
+
+        scope.$parent.$watch(getIsOpen, function(value) {
+          scope.isOpen = !!value;
+        });
+      }
+
+      scope.$watch('isOpen', function(value) {
+        if ( value ) {
+          accordionCtrl.closeOthers(scope);
+        }
+        if ( setIsOpen ) {
+          setIsOpen(scope.$parent, value);
+        }
+      });
+    }
+  };
+}])
+
+// Use accordion-heading below an accordion-group to provide a heading containing HTML
+// <accordion-group>
+//   <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
+// </accordion-group>
+.directive('accordionHeading', function() {
+  return {
+    restrict: 'EA',
+    transclude: true,   // Grab the contents to be used as the heading
+    template: '',       // In effect remove this element!
+    replace: true,
+    require: '^accordionGroup',
+    compile: function(element, attr, transclude) {
+      return function link(scope, element, attr, accordionGroupCtrl) {
+        // Pass the heading to the accordion-group controller
+        // so that it can be transcluded into the right place in the template
+        // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
+        accordionGroupCtrl.setHeading(transclude(scope, function() {}));
+      };
+    }
+  };
+})
+
+// Use in the accordion-group template to indicate where you want the heading to be transcluded
+// You must provide the property on the accordion-group controller that will hold the transcluded element
+// <div class="accordion-group">
+//   <div class="accordion-heading" ><a ... accordion-transclude="heading">...</a></div>
+//   ...
+// </div>
+.directive('accordionTransclude', function() {
+  return {
+    require: '^accordionGroup',
+    link: function(scope, element, attr, controller) {
+      scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
+        if ( heading ) {
+          element.html('');
+          element.append(heading);
+        }
+      });
+    }
+  };
+});
+
+angular.module("ui.bootstrap.alert", [])
+
+.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
+  $scope.closeable = 'close' in $attrs;
+}])
+
+.directive('alert', function () {
+  return {
+    restrict:'EA',
+    controller:'AlertController',
+    templateUrl:'template/alert/alert.html',
+    transclude:true,
+    replace:true,
+    scope: {
+      type: '=',
+      close: '&'
+    }
+  };
+});
+
+angular.module('ui.bootstrap.bindHtml', [])
+
+  .directive('bindHtmlUnsafe', function () {
+    return function (scope, element, attr) {
+      element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
+      scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
+        element.html(value || '');
+      });
+    };
+  });
+angular.module('ui.bootstrap.buttons', [])
+
+.constant('buttonConfig', {
+  activeClass: 'active',
+  toggleEvent: 'click'
+})
+
+.controller('ButtonsController', ['buttonConfig', function(buttonConfig) {
+  this.activeClass = buttonConfig.activeClass || 'active';
+  this.toggleEvent = buttonConfig.toggleEvent || 'click';
+}])
+
+.directive('btnRadio', function () {
+  return {
+    require: ['btnRadio', 'ngModel'],
+    controller: 'ButtonsController',
+    link: function (scope, element, attrs, ctrls) {
+      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
+
+      //model -> UI
+      ngModelCtrl.$render = function () {
+        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.btnRadio)));
+      };
+
+      //ui->model
+      element.bind(buttonsCtrl.toggleEvent, function () {
+        if (!element.hasClass(buttonsCtrl.activeClass)) {
+          scope.$apply(function () {
+            ngModelCtrl.$setViewValue(scope.$eval(attrs.btnRadio));
+            ngModelCtrl.$render();
+          });
+        }
+      });
+    }
+  };
+})
+
+.directive('btnCheckbox', function () {
+  return {
+    require: ['btnCheckbox', 'ngModel'],
+    controller: 'ButtonsController',
+    link: function (scope, element, attrs, ctrls) {
+      var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
+
+      function getTrueValue() {
+        return getCheckboxValue(attrs.btnCheckboxTrue, true);
+      }
+
+      function getFalseValue() {
+        return getCheckboxValue(attrs.btnCheckboxFalse, false);
+      }
+      
+      function getCheckboxValue(attributeValue, defaultValue) {
+        var val = scope.$eval(attributeValue);
+        return angular.isDefined(val) ? val : defaultValue;
+      }
+
+      //model -> UI
+      ngModelCtrl.$render = function () {
+        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
+      };
+
+      //ui->model
+      element.bind(buttonsCtrl.toggleEvent, function () {
+        scope.$apply(function () {
+          ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
+          ngModelCtrl.$render();
+        });
+      });
+    }
+  };
+});
+
+/**
+* @ngdoc overview
+* @name ui.bootstrap.carousel
+*
+* @description
+* AngularJS version of an image carousel.
+*
+*/
+angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
+.controller('CarouselController', ['$scope', '$timeout', '$transition', '$q', function ($scope, $timeout, $transition, $q) {
+  var self = this,
+    slides = self.slides = [],
+    currentIndex = -1,
+    currentTimeout, isPlaying;
+  self.currentSlide = null;
+
+  var destroyed = false;
+  /* direction: "prev" or "next" */
+  self.select = function(nextSlide, direction) {
+    var nextIndex = slides.indexOf(nextSlide);
+    //Decide direction if it's not given
+    if (direction === undefined) {
+      direction = nextIndex > currentIndex ? "next" : "prev";
+    }
+    if (nextSlide && nextSlide !== self.currentSlide) {
+      if ($scope.$currentTransition) {
+        $scope.$currentTransition.cancel();
+        //Timeout so ng-class in template has time to fix classes for finished slide
+        $timeout(goNext);
+      } else {
+        goNext();
+      }
+    }
+    function goNext() {
+      // Scope has been destroyed, stop here.
+      if (destroyed) { return; }
+      //If we have a slide to transition from and we have a transition type and we're allowed, go
+      if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
+        //We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
+        nextSlide.$element.addClass(direction);
+        var reflow = nextSlide.$element[0].offsetWidth; //force reflow
+
+        //Set all other slides to stop doing their stuff for the new transition
+        angular.forEach(slides, function(slide) {
+          angular.extend(slide, {direction: '', entering: false, leaving: false, active: false});
+        });
+        angular.extend(nextSlide, {direction: direction, active: true, entering: true});
+        angular.extend(self.currentSlide||{}, {direction: direction, leaving: true});
+
+        $scope.$currentTransition = $transition(nextSlide.$element, {});
+        //We have to create new pointers inside a closure since next & current will change
+        (function(next,current) {
+          $scope.$currentTransition.then(
+            function(){ transitionDone(next, current); },
+            function(){ transitionDone(next, current); }
+          );
+        }(nextSlide, self.currentSlide));
+      } else {
+        transitionDone(nextSlide, self.currentSlide);
+      }
+      self.currentSlide = nextSlide;
+      currentIndex = nextIndex;
+      //every time you change slides, reset the timer
+      restartTimer();
+    }
+    function transitionDone(next, current) {
+      angular.extend(next, {direction: '', active: true, leaving: false, entering: false});
+      angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false});
+      $scope.$currentTransition = null;
+    }
+  };
+  $scope.$on('$destroy', function () {
+    destroyed = true;
+  });
+
+  /* Allow outside people to call indexOf on slides array */
+  self.indexOfSlide = function(slide) {
+    return slides.indexOf(slide);
+  };
+
+  $scope.next = function() {
+    var newIndex = (currentIndex + 1) % slides.length;
+
+    //Prevent this user-triggered transition from occurring if there is already one in progress
+    if (!$scope.$currentTransition) {
+      return self.select(slides[newIndex], 'next');
+    }
+  };
+
+  $scope.prev = function() {
+    var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
+
+    //Prevent this user-triggered transition from occurring if there is already one in progress
+    if (!$scope.$currentTransition) {
+      return self.select(slides[newIndex], 'prev');
+    }
+  };
+
+  $scope.select = function(slide) {
+    self.select(slide);
+  };
+
+  $scope.isActive = function(slide) {
+     return self.currentSlide === slide;
+  };
+
+  $scope.slides = function() {
+    return slides;
+  };
+
+  $scope.$watch('interval', restartTimer);
+  $scope.$on('$destroy', resetTimer);
+
+  function restartTimer() {
+    resetTimer();
+    var interval = +$scope.interval;
+    if (!isNaN(interval) && interval>=0) {
+      currentTimeout = $timeout(timerFn, interval);
+    }
+  }
+
+  function resetTimer() {
+    if (currentTimeout) {
+      $timeout.cancel(currentTimeout);
+      currentTimeout = null;
+    }
+  }
+
+  function timerFn() {
+    if (isPlaying) {
+      $scope.next();
+      restartTimer();
+    } else {
+      $scope.pause();
+    }
+  }
+
+  $scope.play = function() {
+    if (!isPlaying) {
+      isPlaying = true;
+      restartTimer();
+    }
+  };
+  $scope.pause = function() {
+    if (!$scope.noPause) {
+      isPlaying = false;
+      resetTimer();
+    }
+  };
+
+  self.addSlide = function(slide, element) {
+    slide.$element = element;
+    slides.push(slide);
+    //if this is the first slide or the slide is set to active, select it
+    if(slides.length === 1 || slide.active) {
+      self.select(slides[slides.length-1]);
+      if (slides.length == 1) {
+        $scope.play();
+      }
+    } else {
+      slide.active = false;
+    }
+  };
+
+  self.removeSlide = function(slide) {
+    //get the index of the slide inside the carousel
+    var index = slides.indexOf(slide);
+    slides.splice(index, 1);
+    if (slides.length > 0 && slide.active) {
+      if (index >= slides.length) {
+        self.select(slides[index-1]);
+      } else {
+        self.select(slides[index]);
+      }
+    } else if (currentIndex > index) {
+      currentIndex--;
+    }
+  };
+
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.carousel.directive:carousel
+ * @restrict EA
+ *
+ * @description
+ * Carousel is the outer container for a set of image 'slides' to showcase.
+ *
+ * @param {number=} interval The time, in milliseconds, that it will take the carousel to go to the next slide.
+ * @param {boolean=} noTransition Whether to disable transitions on the carousel.
+ * @param {boolean=} noPause Whether to disable pausing on the carousel (by default, the carousel interval pauses on hover).
+ *
+ * @example
+<example module="ui.bootstrap">
+  <file name="index.html">
+    <carousel>
+      <slide>
+        <img src="http://placekitten.com/150/150" style="margin:auto;">
+        <div class="carousel-caption">
+          <p>Beautiful!</p>
+        </div>
+      </slide>
+      <slide>
+        <img src="http://placekitten.com/100/150" style="margin:auto;">
+        <div class="carousel-caption">
+          <p>D'aww!</p>
+        </div>
+      </slide>
+    </carousel>
+  </file>
+  <file name="demo.css">
+    .carousel-indicators {
+      top: auto;
+      bottom: 15px;
+    }
+  </file>
+</example>
+ */
+.directive('carousel', [function() {
+  return {
+    restrict: 'EA',
+    transclude: true,
+    replace: true,
+    controller: 'CarouselController',
+    require: 'carousel',
+    templateUrl: 'template/carousel/carousel.html',
+    scope: {
+      interval: '=',
+      noTransition: '=',
+      noPause: '='
+    }
+  };
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.carousel.directive:slide
+ * @restrict EA
+ *
+ * @description
+ * Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}.  Must be placed as a child of a carousel element.
+ *
+ * @param {boolean=} active Model binding, whether or not this slide is currently active.
+ *
+ * @example
+<example module="ui.bootstrap">
+  <file name="index.html">
+<div ng-controller="CarouselDemoCtrl">
+  <carousel>
+    <slide ng-repeat="slide in slides" active="slide.active">
+      <img ng-src="{{slide.image}}" style="margin:auto;">
+      <div class="carousel-caption">
+        <h4>Slide {{$index}}</h4>
+        <p>{{slide.text}}</p>
+      </div>
+    </slide>
+  </carousel>
+  <div class="row-fluid">
+    <div class="span6">
+      <ul>
+        <li ng-repeat="slide in slides">
+          <button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button>
+          {{$index}}: {{slide.text}}
+        </li>
+      </ul>
+      <a class="btn" ng-click="addSlide()">Add Slide</a>
+    </div>
+    <div class="span6">
+      Interval, in milliseconds: <input type="number" ng-model="myInterval">
+      <br />Enter a negative number to stop the interval.
+    </div>
+  </div>
+</div>
+  </file>
+  <file name="script.js">
+function CarouselDemoCtrl($scope) {
+  $scope.myInterval = 5000;
+  var slides = $scope.slides = [];
+  $scope.addSlide = function() {
+    var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
+    slides.push({
+      image: 'http://placekitten.com/' + newWidth + '/200',
+      text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
+        ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
+    });
+  };
+  for (var i=0; i<4; i++) $scope.addSlide();
+}
+  </file>
+  <file name="demo.css">
+    .carousel-indicators {
+      top: auto;
+      bottom: 15px;
+    }
+  </file>
+</example>
+*/
+
+.directive('slide', ['$parse', function($parse) {
+  return {
+    require: '^carousel',
+    restrict: 'EA',
+    transclude: true,
+    replace: true,
+    templateUrl: 'template/carousel/slide.html',
+    scope: {
+    },
+    link: function (scope, element, attrs, carouselCtrl) {
+      //Set up optional 'active' = binding
+      if (attrs.active) {
+        var getActive = $parse(attrs.active);
+        var setActive = getActive.assign;
+        var lastValue = scope.active = getActive(scope.$parent);
+        scope.$watch(function parentActiveWatch() {
+          var parentActive = getActive(scope.$parent);
+
+          if (parentActive !== scope.active) {
+            // we are out of sync and need to copy
+            if (parentActive !== lastValue) {
+              // parent changed and it has precedence
+              lastValue = scope.active = parentActive;
+            } else {
+              // if the parent can be assigned then do so
+              setActive(scope.$parent, parentActive = lastValue = scope.active);
+            }
+          }
+          return parentActive;
+        });
+      }
+
+      carouselCtrl.addSlide(scope, element);
+      //when the scope is destroyed then remove the slide from the current slides array
+      scope.$on('$destroy', function() {
+        carouselCtrl.removeSlide(scope);
+      });
+
+      scope.$watch('active', function(active) {
+        if (active) {
+          carouselCtrl.select(scope);
+        }
+      });
+    }
+  };
+}]);
+
+angular.module('ui.bootstrap.position', [])
+
+/**
+ * A set of utility methods that can be use to retrieve position of DOM elements.
+ * It is meant to be used where we need to absolute-position DOM elements in
+ * relation to other, existing elements (this is the case for tooltips, popovers,
+ * typeahead suggestions etc.).
+ */
+  .factory('$position', ['$document', '$window', function ($document, $window) {
+
+    function getStyle(el, cssprop) {
+      if (el.currentStyle) { //IE
+        return el.currentStyle[cssprop];
+      } else if ($window.getComputedStyle) {
+        return $window.getComputedStyle(el)[cssprop];
+      }
+      // finally try and get inline style
+      return el.style[cssprop];
+    }
+
+    /**
+     * Checks if a given element is statically positioned
+     * @param element - raw DOM element
+     */
+    function isStaticPositioned(element) {
+      return (getStyle(element, "position") || 'static' ) === 'static';
+    }
+
+    /**
+     * returns the closest, non-statically positioned parentOffset of a given element
+     * @param element
+     */
+    var parentOffsetEl = function (element) {
+      var docDomEl = $document[0];
+      var offsetParent = element.offsetParent || docDomEl;
+      while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
+        offsetParent = offsetParent.offsetParent;
+      }
+      return offsetParent || docDomEl;
+    };
+
+    return {
+      /**
+       * Provides read-only equivalent of jQuery's position function:
+       * http://api.jquery.com/position/
+       */
+      position: function (element) {
+        var elBCR = this.offset(element);
+        var offsetParentBCR = { top: 0, left: 0 };
+        var offsetParentEl = parentOffsetEl(element[0]);
+        if (offsetParentEl != $document[0]) {
+          offsetParentBCR = this.offset(angular.element(offsetParentEl));
+          offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
+          offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
+        }
+
+        var boundingClientRect = element[0].getBoundingClientRect();
+        return {
+          width: boundingClientRect.width || element.prop('offsetWidth'),
+          height: boundingClientRect.height || element.prop('offsetHeight'),
+          top: elBCR.top - offsetParentBCR.top,
+          left: elBCR.left - offsetParentBCR.left
+        };
+      },
+
+      /**
+       * Provides read-only equivalent of jQuery's offset function:
+       * http://api.jquery.com/offset/
+       */
+      offset: function (element) {
+        var boundingClientRect = element[0].getBoundingClientRect();
+        return {
+          width: boundingClientRect.width || element.prop('offsetWidth'),
+          height: boundingClientRect.height || element.prop('offsetHeight'),
+          top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop),
+          left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft  || $document[0].documentElement.scrollLeft)
+        };
+      }
+    };
+  }]);
+
+angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
+
+.constant('datepickerConfig', {
+  dayFormat: 'dd',
+  monthFormat: 'MMMM',
+  yearFormat: 'yyyy',
+  dayHeaderFormat: 'EEE',
+  dayTitleFormat: 'MMMM yyyy',
+  monthTitleFormat: 'yyyy',
+  showWeeks: true,
+  startingDay: 0,
+  yearRange: 20,
+  minDate: null,
+  maxDate: null
+})
+
+.controller('DatepickerController', ['$scope', '$attrs', 'dateFilter', 'datepickerConfig', function($scope, $attrs, dateFilter, dtConfig) {
+  var format = {
+    day:        getValue($attrs.dayFormat,        dtConfig.dayFormat),
+    month:      getValue($attrs.monthFormat,      dtConfig.monthFormat),
+    year:       getValue($attrs.yearFormat,       dtConfig.yearFormat),
+    dayHeader:  getValue($attrs.dayHeaderFormat,  dtConfig.dayHeaderFormat),
+    dayTitle:   getValue($attrs.dayTitleFormat,   dtConfig.dayTitleFormat),
+    monthTitle: getValue($attrs.monthTitleFormat, dtConfig.monthTitleFormat)
+  },
+  startingDay = getValue($attrs.startingDay,      dtConfig.startingDay),
+  yearRange =   getValue($attrs.yearRange,        dtConfig.yearRange);
+
+  this.minDate = dtConfig.minDate ? new Date(dtConfig.minDate) : null;
+  this.maxDate = dtConfig.maxDate ? new Date(dtConfig.maxDate) : null;
+
+  function getValue(value, defaultValue) {
+    return angular.isDefined(value) ? $scope.$parent.$eval(value) : defaultValue;
+  }
+
+  function getDaysInMonth( year, month ) {
+    return new Date(year, month, 0).getDate();
+  }
+
+  function getDates(startDate, n) {
+    var dates = new Array(n);
+    var current = startDate, i = 0;
+    while (i < n) {
+      dates[i++] = new Date(current);
+      current.setDate( current.getDate() + 1 );
+    }
+    return dates;
+  }
+
+  function makeDate(date, format, isSelected, isSecondary) {
+    return { date: date, label: dateFilter(date, format), selected: !!isSelected, secondary: !!isSecondary };
+  }
+
+  this.modes = [
+    {
+      name: 'day',
+      getVisibleDates: function(date, selected) {
+        var year = date.getFullYear(), month = date.getMonth(), firstDayOfMonth = new Date(year, month, 1);
+        var difference = startingDay - firstDayOfMonth.getDay(),
+        numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference,
+        firstDate = new Date(firstDayOfMonth), numDates = 0;
+
+        if ( numDisplayedFromPreviousMonth > 0 ) {
+          firstDate.setDate( - numDisplayedFromPreviousMonth + 1 );
+          numDates += numDisplayedFromPreviousMonth; // Previous
+        }
+        numDates += getDaysInMonth(year, month + 1); // Current
+        numDates += (7 - numDates % 7) % 7; // Next
+
+        var days = getDates(firstDate, numDates), labels = new Array(7);
+        for (var i = 0; i < numDates; i ++) {
+          var dt = new Date(days[i]);
+          days[i] = makeDate(dt, format.day, (selected && selected.getDate() === dt.getDate() && selected.getMonth() === dt.getMonth() && selected.getFullYear() === dt.getFullYear()), dt.getMonth() !== month);
+        }
+        for (var j = 0; j < 7; j++) {
+          labels[j] = dateFilter(days[j].date, format.dayHeader);
+        }
+        return { objects: days, title: dateFilter(date, format.dayTitle), labels: labels };
+      },
+      compare: function(date1, date2) {
+        return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) );
+      },
+      split: 7,
+      step: { months: 1 }
+    },
+    {
+      name: 'month',
+      getVisibleDates: function(date, selected) {
+        var months = new Array(12), year = date.getFullYear();
+        for ( var i = 0; i < 12; i++ ) {
+          var dt = new Date(year, i, 1);
+          months[i] = makeDate(dt, format.month, (selected && selected.getMonth() === i && selected.getFullYear() === year));
+        }
+        return { objects: months, title: dateFilter(date, format.monthTitle) };
+      },
+      compare: function(date1, date2) {
+        return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
+      },
+      split: 3,
+      step: { years: 1 }
+    },
+    {
+      name: 'year',
+      getVisibleDates: function(date, selected) {
+        var years = new Array(yearRange), year = date.getFullYear(), startYear = parseInt((year - 1) / yearRange, 10) * yearRange + 1;
+        for ( var i = 0; i < yearRange; i++ ) {
+          var dt = new Date(startYear + i, 0, 1);
+          years[i] = makeDate(dt, format.year, (selected && selected.getFullYear() === dt.getFullYear()));
+        }
+        return { objects: years, title: [years[0].label, years[yearRange - 1].label].join(' - ') };
+      },
+      compare: function(date1, date2) {
+        return date1.getFullYear() - date2.getFullYear();
+      },
+      split: 5,
+      step: { years: yearRange }
+    }
+  ];
+
+  this.isDisabled = function(date, mode) {
+    var currentMode = this.modes[mode || 0];
+    return ((this.minDate && currentMode.compare(date, this.minDate) < 0) || (this.maxDate && currentMode.compare(date, this.maxDate) > 0) || ($scope.dateDisabled && $scope.dateDisabled({date: date, mode: currentMode.name})));
+  };
+}])
+
+.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', '$log', function (dateFilter, $parse, datepickerConfig, $log) {
+  return {
+    restrict: 'EA',
+    replace: true,
+    templateUrl: 'template/datepicker/datepicker.html',
+    scope: {
+      dateDisabled: '&'
+    },
+    require: ['datepicker', '?^ngModel'],
+    controller: 'DatepickerController',
+    link: function(scope, element, attrs, ctrls) {
+      var datepickerCtrl = ctrls[0], ngModel = ctrls[1];
+
+      if (!ngModel) {
+        return; // do nothing if no ng-model
+      }
+
+      // Configuration parameters
+      var mode = 0, selected = new Date(), showWeeks = datepickerConfig.showWeeks;
+
+      if (attrs.showWeeks) {
+        scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
+          showWeeks = !! value;
+          updateShowWeekNumbers();
+        });
+      } else {
+        updateShowWeekNumbers();
+      }
+
+      if (attrs.min) {
+        scope.$parent.$watch($parse(attrs.min), function(value) {
+          datepickerCtrl.minDate = value ? new Date(value) : null;
+          refill();
+        });
+      }
+      if (attrs.max) {
+        scope.$parent.$watch($parse(attrs.max), function(value) {
+          datepickerCtrl.maxDate = value ? new Date(value) : null;
+          refill();
+        });
+      }
+
+      function updateShowWeekNumbers() {
+        scope.showWeekNumbers = mode === 0 && showWeeks;
+      }
+
+      // Split array into smaller arrays
+      function split(arr, size) {
+        var arrays = [];
+        while (arr.length > 0) {
+          arrays.push(arr.splice(0, size));
+        }
+        return arrays;
+      }
+
+      function refill( updateSelected ) {
+        var date = null, valid = true;
+
+        if ( ngModel.$modelValue ) {
+          date = new Date( ngModel.$modelValue );
+
+          if ( isNaN(date) ) {
+            valid = false;
+            $log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
+          } else if ( updateSelected ) {
+            selected = date;
+          }
+        }
+        ngModel.$setValidity('date', valid);
+
+        var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
+        angular.forEach(data.objects, function(obj) {
+          obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
+        });
+
+        ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));
+
+        scope.rows = split(data.objects, currentMode.split);
+        scope.labels = data.labels || [];
+        scope.title = data.title;
+      }
+
+      function setMode(value) {
+        mode = value;
+        updateShowWeekNumbers();
+        refill();
+      }
+
+      ngModel.$render = function() {
+        refill( true );
+      };
+
+      scope.select = function( date ) {
+        if ( mode === 0 ) {
+          var dt = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
+          dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
+          ngModel.$setViewValue( dt );
+          refill( true );
+        } else {
+          selected = date;
+          setMode( mode - 1 );
+        }
+      };
+      scope.move = function(direction) {
+        var step = datepickerCtrl.modes[mode].step;
+        selected.setMonth( selected.getMonth() + direction * (step.months || 0) );
+        selected.setFullYear( selected.getFullYear() + direction * (step.years || 0) );
+        refill();
+      };
+      scope.toggleMode = function() {
+        setMode( (mode + 1) % datepickerCtrl.modes.length );
+      };
+      scope.getWeekNumber = function(row) {
+        return ( mode === 0 && scope.showWeekNumbers && row.length === 7 ) ? getISO8601WeekNumber(row[0].date) : null;
+      };
+
+      function getISO8601WeekNumber(date) {
+        var checkDate = new Date(date);
+        checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday
+        var time = checkDate.getTime();
+        checkDate.setMonth(0); // Compare with Jan 1
+        checkDate.setDate(1);
+        return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+      }
+    }
+  };
+}])
+
+.constant('datepickerPopupConfig', {
+  dateFormat: 'yyyy-MM-dd',
+  currentText: 'Today',
+  toggleWeeksText: 'Weeks',
+  clearText: 'Clear',
+  closeText: 'Done',
+  closeOnDateSelection: true,
+  appendToBody: false,
+  showButtonBar: true
+})
+
+.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'datepickerPopupConfig', 'datepickerConfig',
+function ($compile, $parse, $document, $position, dateFilter, datepickerPopupConfig, datepickerConfig) {
+  return {
+    restrict: 'EA',
+    require: 'ngModel',
+    link: function(originalScope, element, attrs, ngModel) {
+      var scope = originalScope.$new(), // create a child scope so we are not polluting original one
+          dateFormat,
+          closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? originalScope.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
+          appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? originalScope.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
+
+      attrs.$observe('datepickerPopup', function(value) {
+          dateFormat = value || datepickerPopupConfig.dateFormat;
+          ngModel.$render();
+      });
+
+      scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? originalScope.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
+
+      originalScope.$on('$destroy', function() {
+        $popup.remove();
+        scope.$destroy();
+      });
+
+      attrs.$observe('currentText', function(text) {
+        scope.currentText = angular.isDefined(text) ? text : datepickerPopupConfig.currentText;
+      });
+      attrs.$observe('toggleWeeksText', function(text) {
+        scope.toggleWeeksText = angular.isDefined(text) ? text : datepickerPopupConfig.toggleWeeksText;
+      });
+      attrs.$observe('clearText', function(text) {
+        scope.clearText = angular.isDefined(text) ? text : datepickerPopupConfig.clearText;
+      });
+      attrs.$observe('closeText', function(text) {
+        scope.closeText = angular.isDefined(text) ? text : datepickerPopupConfig.closeText;
+      });
+
+      var getIsOpen, setIsOpen;
+      if ( attrs.isOpen ) {
+        getIsOpen = $parse(attrs.isOpen);
+        setIsOpen = getIsOpen.assign;
+
+        originalScope.$watch(getIsOpen, function updateOpen(value) {
+          scope.isOpen = !! value;
+        });
+      }
+      scope.isOpen = getIsOpen ? getIsOpen(originalScope) : false; // Initial state
+
+      function setOpen( value ) {
+        if (setIsOpen) {
+          setIsOpen(originalScope, !!value);
+        } else {
+          scope.isOpen = !!value;
+        }
+      }
+
+      var documentClickBind = function(event) {
+        if (scope.isOpen && event.target !== element[0]) {
+          scope.$apply(function() {
+            setOpen(false);
+          });
+        }
+      };
+
+      var elementFocusBind = function() {
+        scope.$apply(function() {
+          setOpen( true );
+        });
+      };
+
+      // popup element used to display calendar
+      var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
+      popupEl.attr({
+        'ng-model': 'date',
+        'ng-change': 'dateSelection()'
+      });
+      var datepickerEl = angular.element(popupEl.children()[0]),
+          datepickerOptions = {};
+      if (attrs.datepickerOptions) {
+        datepickerOptions = originalScope.$eval(attrs.datepickerOptions);
+        datepickerEl.attr(angular.extend({}, datepickerOptions));
+      }
+
+      // TODO: reverse from dateFilter string to Date object
+      function parseDate(viewValue) {
+        if (!viewValue) {
+          ngModel.$setValidity('date', true);
+          return null;
+        } else if (angular.isDate(viewValue)) {
+          ngModel.$setValidity('date', true);
+          return viewValue;
+        } else if (angular.isString(viewValue)) {
+          var date = new Date(viewValue);
+          if (isNaN(date)) {
+            ngModel.$setValidity('date', false);
+            return undefined;
+          } else {
+            ngModel.$setValidity('date', true);
+            return date;
+          }
+        } else {
+          ngModel.$setValidity('date', false);
+          return undefined;
+        }
+      }
+      ngModel.$parsers.unshift(parseDate);
+
+      // Inner change
+      scope.dateSelection = function(dt) {
+        if (angular.isDefined(dt)) {
+          scope.date = dt;
+        }
+        ngModel.$setViewValue(scope.date);
+        ngModel.$render();
+
+        if (closeOnDateSelection) {
+          setOpen( false );
+        }
+      };
+
+      element.bind('input change keyup', function() {
+        scope.$apply(function() {
+          scope.date = ngModel.$modelValue;
+        });
+      });
+
+      // Outter change
+      ngModel.$render = function() {
+        var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
+        element.val(date);
+        scope.date = ngModel.$modelValue;
+      };
+
+      function addWatchableAttribute(attribute, scopeProperty, datepickerAttribute) {
+        if (attribute) {
+          originalScope.$watch($parse(attribute), function(value){
+            scope[scopeProperty] = value;
+          });
+          datepickerEl.attr(datepickerAttribute || scopeProperty, scopeProperty);
+        }
+      }
+      addWatchableAttribute(attrs.min, 'min');
+      addWatchableAttribute(attrs.max, 'max');
+      if (attrs.showWeeks) {
+        addWatchableAttribute(attrs.showWeeks, 'showWeeks', 'show-weeks');
+      } else {
+        scope.showWeeks = 'show-weeks' in datepickerOptions ? datepickerOptions['show-weeks'] : datepickerConfig.showWeeks;
+        datepickerEl.attr('show-weeks', 'showWeeks');
+      }
+      if (attrs.dateDisabled) {
+        datepickerEl.attr('date-disabled', attrs.dateDisabled);
+      }
+
+      function updatePosition() {
+        scope.position = appendToBody ? $position.offset(element) : $position.position(element);
+        scope.position.top = scope.position.top + element.prop('offsetHeight');
+      }
+
+      var documentBindingInitialized = false, elementFocusInitialized = false;
+      scope.$watch('isOpen', function(value) {
+        if (value) {
+          updatePosition();
+          $document.bind('click', documentClickBind);
+          if(elementFocusInitialized) {
+            element.unbind('focus', elementFocusBind);
+          }
+          element[0].focus();
+          documentBindingInitialized = true;
+        } else {
+          if(documentBindingInitialized) {
+            $document.unbind('click', documentClickBind);
+          }
+          element.bind('focus', elementFocusBind);
+          elementFocusInitialized = true;
+        }
+
+        if ( setIsOpen ) {
+          setIsOpen(originalScope, value);
+        }
+      });
+
+      scope.today = function() {
+        scope.dateSelection(new Date());
+      };
+      scope.clear = function() {
+        scope.dateSelection(null);
+      };
+
+      var $popup = $compile(popupEl)(scope);
+      if ( appendToBody ) {
+        $document.find('body').append($popup);
+      } else {
+        element.after($popup);
+      }
+    }
+  };
+}])
+
+.directive('datepickerPopupWrap', function() {
+  return {
+    restrict:'EA',
+    replace: true,
+    transclude: true,
+    templateUrl: 'template/datepicker/popup.html',
+    link:function (scope, element, attrs) {
+      element.bind('click', function(event) {
+        event.preventDefault();
+        event.stopPropagation();
+      });
+    }
+  };
+});
+
+/*
+ * dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
+ * @restrict class or attribute
+ * @example:
+   <li class="dropdown">
+     <a class="dropdown-toggle">My Dropdown Menu</a>
+     <ul class="dropdown-menu">
+       <li ng-repeat="choice in dropChoices">
+         <a ng-href="{{choice.href}}">{{choice.text}}</a>
+       </li>
+     </ul>
+   </li>
+ */
+
+angular.module('ui.bootstrap.dropdownToggle', []).directive('dropdownToggle', ['$document', '$location', function ($document, $location) {
+  var openElement = null,
+      closeMenu   = angular.noop;
+  return {
+    restrict: 'CA',
+    link: function(scope, element, attrs) {
+      scope.$watch('$location.path', function() { closeMenu(); });
+      element.parent().bind('click', function() { closeMenu(); });
+      element.bind('click', function (event) {
+
+        var elementWasOpen = (element === openElement);
+
+        event.preventDefault();
+        event.stopPropagation();
+
+        if (!!openElement) {
+          closeMenu();
+        }
+
+        if (!elementWasOpen && !element.hasClass('disabled') && !element.prop('disabled')) {
+          element.parent().addClass('open');
+          openElement = element;
+          closeMenu = function (event) {
+            if (event) {
+              event.preventDefault();
+              event.stopPropagation();
+            }
+            $document.unbind('click', closeMenu);
+            element.parent().removeClass('open');
+            closeMenu = angular.noop;
+            openElement = null;
+          };
+          $document.bind('click', closeMenu);
+        }
+      });
+    }
+  };
+}]);
+
+angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
+
+/**
+ * A helper, internal data structure that acts as a map but also allows getting / removing
+ * elements in the LIFO order
+ */
+  .factory('$$stackedMap', function () {
+    return {
+      createNew: function () {
+        var stack = [];
+
+        return {
+          add: function (key, value) {
+            stack.push({
+              key: key,
+              value: value
+            });
+          },
+          get: function (key) {
+            for (var i = 0; i < stack.length; i++) {
+              if (key == stack[i].key) {
+                return stack[i];
+              }
+            }
+          },
+          keys: function() {
+            var keys = [];
+            for (var i = 0; i < stack.length; i++) {
+              keys.push(stack[i].key);
+            }
+            return keys;
+          },
+          top: function () {
+            return stack[stack.length - 1];
+          },
+          remove: function (key) {
+            var idx = -1;
+            for (var i = 0; i < stack.length; i++) {
+              if (key == stack[i].key) {
+                idx = i;
+                break;
+              }
+            }
+            return stack.splice(idx, 1)[0];
+          },
+          removeTop: function () {
+            return stack.splice(stack.length - 1, 1)[0];
+          },
+          length: function () {
+            return stack.length;
+          }
+        };
+      }
+    };
+  })
+
+/**
+ * A helper directive for the $modal service. It creates a backdrop element.
+ */
+  .directive('modalBackdrop', ['$timeout', function ($timeout) {
+    return {
+      restrict: 'EA',
+      replace: true,
+      templateUrl: 'template/modal/backdrop.html',
+      link: function (scope) {
+
+        scope.animate = false;
+
+        //trigger CSS transitions
+        $timeout(function () {
+          scope.animate = true;
+        });
+      }
+    };
+  }])
+
+  .directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
+    return {
+      restrict: 'EA',
+      scope: {
+        index: '@',
+        animate: '='
+      },
+      replace: true,
+      transclude: true,
+      templateUrl: 'template/modal/window.html',
+      link: function (scope, element, attrs) {
+        scope.windowClass = attrs.windowClass || '';
+
+        $timeout(function () {
+          // trigger CSS transitions
+          scope.animate = true;
+          // focus a freshly-opened modal
+          element[0].focus();
+        });
+
+        scope.close = function (evt) {
+          var modal = $modalStack.getTop();
+          if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
+            evt.preventDefault();
+            evt.stopPropagation();
+            $modalStack.dismiss(modal.key, 'backdrop click');
+          }
+        };
+      }
+    };
+  }])
+
+  .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
+    function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
+
+      var OPENED_MODAL_CLASS = 'modal-open';
+
+      var backdropDomEl, backdropScope;
+      var openedWindows = $$stackedMap.createNew();
+      var $modalStack = {};
+
+      function backdropIndex() {
+        var topBackdropIndex = -1;
+        var opened = openedWindows.keys();
+        for (var i = 0; i < opened.length; i++) {
+          if (openedWindows.get(opened[i]).value.backdrop) {
+            topBackdropIndex = i;
+          }
+        }
+        return topBackdropIndex;
+      }
+
+      $rootScope.$watch(backdropIndex, function(newBackdropIndex){
+        if (backdropScope) {
+          backdropScope.index = newBackdropIndex;
+        }
+      });
+
+      function removeModalWindow(modalInstance) {
+
+        var body = $document.find('body').eq(0);
+        var modalWindow = openedWindows.get(modalInstance).value;
+
+        //clean up the stack
+        openedWindows.remove(modalInstance);
+
+        //remove window DOM element
+        removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, checkRemoveBackdrop);
+        body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
+      }
+
+      function checkRemoveBackdrop() {
+          //remove backdrop if no longer needed
+          if (backdropDomEl && backdropIndex() == -1) {
+            var backdropScopeRef = backdropScope;
+            removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
+              backdropScopeRef.$destroy();
+              backdropScopeRef = null;
+            });
+            backdropDomEl = undefined;
+            backdropScope = undefined;
+          }
+      }
+
+      function removeAfterAnimate(domEl, scope, emulateTime, done) {
+        // Closing animation
+        scope.animate = false;
+
+        var transitionEndEventName = $transition.transitionEndEventName;
+        if (transitionEndEventName) {
+          // transition out
+          var timeout = $timeout(afterAnimating, emulateTime);
+
+          domEl.bind(transitionEndEventName, function () {
+            $timeout.cancel(timeout);
+            afterAnimating();
+            scope.$apply();
+          });
+        } else {
+          // Ensure this call is async
+          $timeout(afterAnimating, 0);
+        }
+
+        function afterAnimating() {
+          if (afterAnimating.done) {
+            return;
+          }
+          afterAnimating.done = true;
+
+          domEl.remove();
+          if (done) {
+            done();
+          }
+        }
+      }
+
+      $document.bind('keydown', function (evt) {
+        var modal;
+
+        if (evt.which === 27) {
+          modal = openedWindows.top();
+          if (modal && modal.value.keyboard) {
+            $rootScope.$apply(function () {
+              $modalStack.dismiss(modal.key);
+            });
+          }
+        }
+      });
+
+      $modalStack.open = function (modalInstance, modal) {
+
+        openedWindows.add(modalInstance, {
+          deferred: modal.deferred,
+          modalScope: modal.scope,
+          backdrop: modal.backdrop,
+          keyboard: modal.keyboard
+        });
+
+        var body = $document.find('body').eq(0),
+            currBackdropIndex = backdropIndex();
+
+        if (currBackdropIndex >= 0 && !backdropDomEl) {
+          backdropScope = $rootScope.$new(true);
+          backdropScope.index = currBackdropIndex;
+          backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
+          body.append(backdropDomEl);
+        }
+          
+        var angularDomEl = angular.element('<div modal-window></div>');
+        angularDomEl.attr('window-class', modal.windowClass);
+        angularDomEl.attr('index', openedWindows.length() - 1);
+        angularDomEl.attr('animate', 'animate');
+        angularDomEl.html(modal.content);
+
+        var modalDomEl = $compile(angularDomEl)(modal.scope);
+        openedWindows.top().value.modalDomEl = modalDomEl;
+        body.append(modalDomEl);
+        body.addClass(OPENED_MODAL_CLASS);
+      };
+
+      $modalStack.close = function (modalInstance, result) {
+        var modalWindow = openedWindows.get(modalInstance).value;
+        if (modalWindow) {
+          modalWindow.deferred.resolve(result);
+          removeModalWindow(modalInstance);
+        }
+      };
+
+      $modalStack.dismiss = function (modalInstance, reason) {
+        var modalWindow = openedWindows.get(modalInstance).value;
+        if (modalWindow) {
+          modalWindow.deferred.reject(reason);
+          removeModalWindow(modalInstance);
+        }
+      };
+
+      $modalStack.dismissAll = function (reason) {
+        var topModal = this.getTop();
+        while (topModal) {
+          this.dismiss(topModal.key, reason);
+          topModal = this.getTop();
+        }
+      };
+
+      $modalStack.getTop = function () {
+        return openedWindows.top();
+      };
+
+      return $modalStack;
+    }])
+
+  .provider('$modal', function () {
+
+    var $modalProvider = {
+      options: {
+        backdrop: true, //can be also false or 'static'
+        keyboard: true
+      },
+      $get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
+        function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
+
+          var $modal = {};
+
+          function getTemplatePromise(options) {
+            return options.template ? $q.when(options.template) :
+              $http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
+                return result.data;
+              });
+          }
+
+          function getResolvePromises(resolves) {
+            var promisesArr = [];
+            angular.forEach(resolves, function (value, key) {
+              if (angular.isFunction(value) || angular.isArray(value)) {
+                promisesArr.push($q.when($injector.invoke(value)));
+              }
+            });
+            return promisesArr;
+          }
+
+          $modal.open = function (modalOptions) {
+
+            var modalResultDeferred = $q.defer();
+            var modalOpenedDeferred = $q.defer();
+
+            //prepare an instance of a modal to be injected into controllers and returned to a caller
+            var modalInstance = {
+              result: modalResultDeferred.promise,
+              opened: modalOpenedDeferred.promise,
+              close: function (result) {
+                $modalStack.close(modalInstance, result);
+              },
+              dismiss: function (reason) {
+                $modalStack.dismiss(modalInstance, reason);
+              }
+            };
+
+            //merge and clean up options
+            modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
+            modalOptions.resolve = modalOptions.resolve || {};
+
+            //verify options
+            if (!modalOptions.template && !modalOptions.templateUrl) {
+              throw new Error('One of template or templateUrl options is required.');
+            }
+
+            var templateAndResolvePromise =
+              $q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
+
+
+            templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
+
+              var modalScope = (modalOptions.scope || $rootScope).$new();
+              modalScope.$close = modalInstance.close;
+              modalScope.$dismiss = modalInstance.dismiss;
+
+              var ctrlInstance, ctrlLocals = {};
+              var resolveIter = 1;
+
+              //controllers
+              if (modalOptions.controller) {
+                ctrlLocals.$scope = modalScope;
+                ctrlLocals.$modalInstance = modalInstance;
+                angular.forEach(modalOptions.resolve, function (value, key) {
+                  ctrlLocals[key] = tplAndVars[resolveIter++];
+                });
+
+                ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
+              }
+
+              $modalStack.open(modalInstance, {
+                scope: modalScope,
+                deferred: modalResultDeferred,
+                content: tplAndVars[0],
+                backdrop: modalOptions.backdrop,
+                keyboard: modalOptions.keyboard,
+                windowClass: modalOptions.windowClass
+              });
+
+            }, function resolveError(reason) {
+              modalResultDeferred.reject(reason);
+            });
+
+            templateAndResolvePromise.then(function () {
+              modalOpenedDeferred.resolve(true);
+            }, function () {
+              modalOpenedDeferred.reject(false);
+            });
+
+            return modalInstance;
+          };
+
+          return $modal;
+        }]
+    };
+
+    return $modalProvider;
+  });
+
+angular.module('ui.bootstrap.pagination', [])
+
+.controller('PaginationController', ['$scope', '$attrs', '$parse', '$interpolate', function ($scope, $attrs, $parse, $interpolate) {
+  var self = this,
+      setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
+
+  this.init = function(defaultItemsPerPage) {
+    if ($attrs.itemsPerPage) {
+      $scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
+        self.itemsPerPage = parseInt(value, 10);
+        $scope.totalPages = self.calculateTotalPages();
+      });
+    } else {
+      this.itemsPerPage = defaultItemsPerPage;
+    }
+  };
+
+  this.noPrevious = function() {
+    return this.page === 1;
+  };
+  this.noNext = function() {
+    return this.page === $scope.totalPages;
+  };
+
+  this.isActive = function(page) {
+    return this.page === page;
+  };
+
+  this.calculateTotalPages = function() {
+    var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
+    return Math.max(totalPages || 0, 1);
+  };
+
+  this.getAttributeValue = function(attribute, defaultValue, interpolate) {
+    return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
+  };
+
+  this.render = function() {
+    this.page = parseInt($scope.page, 10) || 1;
+    if (this.page > 0 && this.page <= $scope.totalPages) {
+      $scope.pages = this.getPages(this.page, $scope.totalPages);
+    }
+  };
+
+  $scope.selectPage = function(page) {
+    if ( ! self.isActive(page) && page > 0 && page <= $scope.totalPages) {
+      $scope.page = page;
+      $scope.onSelectPage({ page: page });
+    }
+  };
+
+  $scope.$watch('page', function() {
+    self.render();
+  });
+
+  $scope.$watch('totalItems', function() {
+    $scope.totalPages = self.calculateTotalPages();
+  });
+
+  $scope.$watch('totalPages', function(value) {
+    setNumPages($scope.$parent, value); // Readonly variable
+
+    if ( self.page > value ) {
+      $scope.selectPage(value);
+    } else {
+      self.render();
+    }
+  });
+}])
+
+.constant('paginationConfig', {
+  itemsPerPage: 10,
+  boundaryLinks: false,
+  directionLinks: true,
+  firstText: 'First',
+  previousText: 'Previous',
+  nextText: 'Next',
+  lastText: 'Last',
+  rotate: true
+})
+
+.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
+  return {
+    restrict: 'EA',
+    scope: {
+      page: '=',
+      totalItems: '=',
+      onSelectPage:' &'
+    },
+    controller: 'PaginationController',
+    templateUrl: 'template/pagination/pagination.html',
+    replace: true,
+    link: function(scope, element, attrs, paginationCtrl) {
+
+      // Setup configuration parameters
+      var maxSize,
+      boundaryLinks  = paginationCtrl.getAttributeValue(attrs.boundaryLinks,  config.boundaryLinks      ),
+      directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks     ),
+      firstText      = paginationCtrl.getAttributeValue(attrs.firstText,      config.firstText,     true),
+      previousText   = paginationCtrl.getAttributeValue(attrs.previousText,   config.previousText,  true),
+      nextText       = paginationCtrl.getAttributeValue(attrs.nextText,       config.nextText,      true),
+      lastText       = paginationCtrl.getAttributeValue(attrs.lastText,       config.lastText,      true),
+      rotate         = paginationCtrl.getAttributeValue(attrs.rotate,         config.rotate);
+
+      paginationCtrl.init(config.itemsPerPage);
+
+      if (attrs.maxSize) {
+        scope.$parent.$watch($parse(attrs.maxSize), function(value) {
+          maxSize = parseInt(value, 10);
+          paginationCtrl.render();
+        });
+      }
+
+      // Create page object used in template
+      function makePage(number, text, isActive, isDisabled) {
+        return {
+          number: number,
+          text: text,
+          active: isActive,
+          disabled: isDisabled
+        };
+      }
+
+      paginationCtrl.getPages = function(currentPage, totalPages) {
+        var pages = [];
+
+        // Default page limits
+        var startPage = 1, endPage = totalPages;
+        var isMaxSized = ( angular.isDefined(maxSize) && maxSize < totalPages );
+
+        // recompute if maxSize
+        if ( isMaxSized ) {
+          if ( rotate ) {
+            // Current page is displayed in the middle of the visible ones
+            startPage = Math.max(currentPage - Math.floor(maxSize/2), 1);
+            endPage   = startPage + maxSize - 1;
+
+            // Adjust if limit is exceeded
+            if (endPage > totalPages) {
+              endPage   = totalPages;
+              startPage = endPage - maxSize + 1;
+            }
+          } else {
+            // Visible pages are paginated with maxSize
+            startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1;
+
+            // Adjust last page if limit is exceeded
+            endPage = Math.min(startPage + maxSize - 1, totalPages);
+          }
+        }
+
+        // Add page number links
+        for (var number = startPage; number <= endPage; number++) {
+          var page = makePage(number, number, paginationCtrl.isActive(number), false);
+          pages.push(page);
+        }
+
+        // Add links to move between page sets
+        if ( isMaxSized && ! rotate ) {
+          if ( startPage > 1 ) {
+            var previousPageSet = makePage(startPage - 1, '...', false, false);
+            pages.unshift(previousPageSet);
+          }
+
+          if ( endPage < totalPages ) {
+            var nextPageSet = makePage(endPage + 1, '...', false, false);
+            pages.push(nextPageSet);
+          }
+        }
+
+        // Add previous & next links
+        if (directionLinks) {
+          var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
+          pages.unshift(previousPage);
+
+          var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
+          pages.push(nextPage);
+        }
+
+        // Add first & last links
+        if (boundaryLinks) {
+          var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
+          pages.unshift(firstPage);
+
+          var lastPage = makePage(totalPages, lastText, false, paginationCtrl.noNext());
+          pages.push(lastPage);
+        }
+
+        return pages;
+      };
+    }
+  };
+}])
+
+.constant('pagerConfig', {
+  itemsPerPage: 10,
+  previousText: '« Previous',
+  nextText: 'Next »',
+  align: true
+})
+
+.directive('pager', ['pagerConfig', function(config) {
+  return {
+    restrict: 'EA',
+    scope: {
+      page: '=',
+      totalItems: '=',
+      onSelectPage:' &'
+    },
+    controller: 'PaginationController',
+    templateUrl: 'template/pagination/pager.html',
+    replace: true,
+    link: function(scope, element, attrs, paginationCtrl) {
+
+      // Setup configuration parameters
+      var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
+      nextText         = paginationCtrl.getAttributeValue(attrs.nextText,     config.nextText,     true),
+      align            = paginationCtrl.getAttributeValue(attrs.align,        config.align);
+
+      paginationCtrl.init(config.itemsPerPage);
+
+      // Create page object used in template
+      function makePage(number, text, isDisabled, isPrevious, isNext) {
+        return {
+          number: number,
+          text: text,
+          disabled: isDisabled,
+          previous: ( align && isPrevious ),
+          next: ( align && isNext )
+        };
+      }
+
+      paginationCtrl.getPages = function(currentPage) {
+        return [
+          makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
+          makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
+        ];
+      };
+    }
+  };
+}]);
+
+/**
+ * The following features are still outstanding: animation as a
+ * function, placement as a function, inside, support for more triggers than
+ * just mouse enter/leave, html tooltips, and selector delegation.
+ */
+angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap.bindHtml' ] )
+
+/**
+ * The $tooltip service creates tooltip- and popover-like directives as well as
+ * houses global options for them.
+ */
+.provider( '$tooltip', function () {
+  // The default options tooltip and popover.
+  var defaultOptions = {
+    placement: 'top',
+    animation: true,
+    popupDelay: 0
+  };
+
+  // Default hide triggers for each show trigger
+  var triggerMap = {
+    'mouseenter': 'mouseleave',
+    'click': 'click',
+    'focus': 'blur'
+  };
+
+  // The options specified to the provider globally.
+  var globalOptions = {};
+  
+  /**
+   * `options({})` allows global configuration of all tooltips in the
+   * application.
+   *
+   *   var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {
+   *     // place tooltips left instead of top by default
+   *     $tooltipProvider.options( { placement: 'left' } );
+   *   });
+   */
+       this.options = function( value ) {
+               angular.extend( globalOptions, value );
+       };
+
+  /**
+   * This allows you to extend the set of trigger mappings available. E.g.:
+   *
+   *   $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
+   */
+  this.setTriggers = function setTriggers ( triggers ) {
+    angular.extend( triggerMap, triggers );
+  };
+
+  /**
+   * This is a helper function for translating camel-case to snake-case.
+   */
+  function snake_case(name){
+    var regexp = /[A-Z]/g;
+    var separator = '-';
+    return name.replace(regexp, function(letter, pos) {
+      return (pos ? separator : '') + letter.toLowerCase();
+    });
+  }
+
+  /**
+   * Returns the actual instance of the $tooltip service.
+   * TODO support multiple triggers
+   */
+  this.$get = [ '$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $parse, $document, $position, $interpolate ) {
+    return function $tooltip ( type, prefix, defaultTriggerShow ) {
+      var options = angular.extend( {}, defaultOptions, globalOptions );
+
+      /**
+       * Returns an object of show and hide triggers.
+       *
+       * If a trigger is supplied,
+       * it is used to show the tooltip; otherwise, it will use the `trigger`
+       * option passed to the `$tooltipProvider.options` method; else it will
+       * default to the trigger supplied to this directive factory.
+       *
+       * The hide trigger is based on the show trigger. If the `trigger` option
+       * was passed to the `$tooltipProvider.options` method, it will use the
+       * mapped trigger from `triggerMap` or the passed trigger if the map is
+       * undefined; otherwise, it uses the `triggerMap` value of the show
+       * trigger; else it will just use the show trigger.
+       */
+      function getTriggers ( trigger ) {
+        var show = trigger || options.trigger || defaultTriggerShow;
+        var hide = triggerMap[show] || show;
+        return {
+          show: show,
+          hide: hide
+        };
+      }
+
+      var directiveName = snake_case( type );
+
+      var startSym = $interpolate.startSymbol();
+      var endSym = $interpolate.endSymbol();
+      var template = 
+        '<div '+ directiveName +'-popup '+
+          'title="'+startSym+'tt_title'+endSym+'" '+
+          'content="'+startSym+'tt_content'+endSym+'" '+
+          'placement="'+startSym+'tt_placement'+endSym+'" '+
+          'animation="tt_animation" '+
+          'is-open="tt_isOpen"'+
+          '>'+
+        '</div>';
+
+      return {
+        restrict: 'EA',
+        scope: true,
+        compile: function (tElem, tAttrs) {
+          var tooltipLinker = $compile( template );
+
+          return function link ( scope, element, attrs ) {
+            var tooltip;
+            var transitionTimeout;
+            var popupTimeout;
+            var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
+            var triggers = getTriggers( undefined );
+            var hasRegisteredTriggers = false;
+            var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
+
+            var positionTooltip = function (){
+              var position,
+                ttWidth,
+                ttHeight,
+                ttPosition;
+              // Get the position of the directive element.
+              position = appendToBody ? $position.offset( element ) : $position.position( element );
+
+              // Get the height and width of the tooltip so we can center it.
+              ttWidth = tooltip.prop( 'offsetWidth' );
+              ttHeight = tooltip.prop( 'offsetHeight' );
+
+              // Calculate the tooltip's top and left coordinates to center it with
+              // this directive.
+              switch ( scope.tt_placement ) {
+                case 'right':
+                  ttPosition = {
+                    top: position.top + position.height / 2 - ttHeight / 2,
+                    left: position.left + position.width
+                  };
+                  break;
+                case 'bottom':
+                  ttPosition = {
+                    top: position.top + position.height,
+                    left: position.left + position.width / 2 - ttWidth / 2
+                  };
+                  break;
+                case 'left':
+                  ttPosition = {
+                    top: position.top + position.height / 2 - ttHeight / 2,
+                    left: position.left - ttWidth
+                  };
+                  break;
+                default:
+                  ttPosition = {
+                    top: position.top - ttHeight,
+                    left: position.left + position.width / 2 - ttWidth / 2
+                  };
+                  break;
+              }
+
+              ttPosition.top += 'px';
+              ttPosition.left += 'px';
+
+              // Now set the calculated positioning.
+              tooltip.css( ttPosition );
+
+            };
+
+            // By default, the tooltip is not open.
+            // TODO add ability to start tooltip opened
+            scope.tt_isOpen = false;
+
+            function toggleTooltipBind () {
+              if ( ! scope.tt_isOpen ) {
+                showTooltipBind();
+              } else {
+                hideTooltipBind();
+              }
+            }
+
+            // Show the tooltip with delay if specified, otherwise show it immediately
+            function showTooltipBind() {
+              if(hasEnableExp && !scope.$eval(attrs[prefix+'Enable'])) {
+                return;
+              }
+              if ( scope.tt_popupDelay ) {
+                popupTimeout = $timeout( show, scope.tt_popupDelay, false );
+                popupTimeout.then(function(reposition){reposition();});
+              } else {
+                show()();
+              }
+            }
+
+            function hideTooltipBind () {
+              scope.$apply(function () {
+                hide();
+              });
+            }
+
+            // Show the tooltip popup element.
+            function show() {
+
+
+              // Don't show empty tooltips.
+              if ( ! scope.tt_content ) {
+                return angular.noop;
+              }
+
+              createTooltip();
+
+              // If there is a pending remove transition, we must cancel it, lest the
+              // tooltip be mysteriously removed.
+              if ( transitionTimeout ) {
+                $timeout.cancel( transitionTimeout );
+              }
+
+              // Set the initial positioning.
+              tooltip.css({ top: 0, left: 0, display: 'block' });
+
+              // Now we add it to the DOM because need some info about it. But it's not 
+              // visible yet anyway.
+              if ( appendToBody ) {
+                  $document.find( 'body' ).append( tooltip );
+              } else {
+                element.after( tooltip );
+              }
+
+              positionTooltip();
+
+              // And show the tooltip.
+              scope.tt_isOpen = true;
+              scope.$digest(); // digest required as $apply is not called
+
+              // Return positioning function as promise callback for correct
+              // positioning after draw.
+              return positionTooltip;
+            }
+
+            // Hide the tooltip popup element.
+            function hide() {
+              // First things first: we don't show it anymore.
+              scope.tt_isOpen = false;
+
+              //if tooltip is going to be shown after delay, we must cancel this
+              $timeout.cancel( popupTimeout );
+
+              // And now we remove it from the DOM. However, if we have animation, we 
+              // need to wait for it to expire beforehand.
+              // FIXME: this is a placeholder for a port of the transitions library.
+              if ( scope.tt_animation ) {
+                transitionTimeout = $timeout(removeTooltip, 500);
+              } else {
+                removeTooltip();
+              }
+            }
+
+            function createTooltip() {
+              // There can only be one tooltip element per directive shown at once.
+              if (tooltip) {
+                removeTooltip();
+              }
+              tooltip = tooltipLinker(scope, function () {});
+
+              // Get contents rendered into the tooltip
+              scope.$digest();
+            }
+
+            function removeTooltip() {
+              if (tooltip) {
+                tooltip.remove();
+                tooltip = null;
+              }
+            }
+
+            /**
+             * Observe the relevant attributes.
+             */
+            attrs.$observe( type, function ( val ) {
+              scope.tt_content = val;
+
+              if (!val && scope.tt_isOpen ) {
+                hide();
+              }
+            });
+
+            attrs.$observe( prefix+'Title', function ( val ) {
+              scope.tt_title = val;
+            });
+
+            attrs.$observe( prefix+'Placement', function ( val ) {
+              scope.tt_placement = angular.isDefined( val ) ? val : options.placement;
+            });
+
+            attrs.$observe( prefix+'PopupDelay', function ( val ) {
+              var delay = parseInt( val, 10 );
+              scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
+            });
+
+            var unregisterTriggers = function() {
+              if (hasRegisteredTriggers) {
+                element.unbind( triggers.show, showTooltipBind );
+                element.unbind( triggers.hide, hideTooltipBind );
+              }
+            };
+
+            attrs.$observe( prefix+'Trigger', function ( val ) {
+              unregisterTriggers();
+
+              triggers = getTriggers( val );
+
+              if ( triggers.show === triggers.hide ) {
+                element.bind( triggers.show, toggleTooltipBind );
+              } else {
+                element.bind( triggers.show, showTooltipBind );
+                element.bind( triggers.hide, hideTooltipBind );
+              }
+
+              hasRegisteredTriggers = true;
+            });
+
+            var animation = scope.$eval(attrs[prefix + 'Animation']);
+            scope.tt_animation = angular.isDefined(animation) ? !!animation : options.animation;
+
+            attrs.$observe( prefix+'AppendToBody', function ( val ) {
+              appendToBody = angular.isDefined( val ) ? $parse( val )( scope ) : appendToBody;
+            });
+
+            // if a tooltip is attached to <body> we need to remove it on
+            // location change as its parent scope will probably not be destroyed
+            // by the change.
+            if ( appendToBody ) {
+              scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess () {
+              if ( scope.tt_isOpen ) {
+                hide();
+              }
+            });
+            }
+
+            // Make sure tooltip is destroyed and removed.
+            scope.$on('$destroy', function onDestroyTooltip() {
+              $timeout.cancel( transitionTimeout );
+              $timeout.cancel( popupTimeout );
+              unregisterTriggers();
+              removeTooltip();
+            });
+          };
+        }
+      };
+    };
+  }];
+})
+
+.directive( 'tooltipPopup', function () {
+  return {
+    restrict: 'EA',
+    replace: true,
+    scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
+    templateUrl: 'template/tooltip/tooltip-popup.html'
+  };
+})
+
+.directive( 'tooltip', [ '$tooltip', function ( $tooltip ) {
+  return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
+}])
+
+.directive( 'tooltipHtmlUnsafePopup', function () {
+  return {
+    restrict: 'EA',
+    replace: true,
+    scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
+    templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
+  };
+})
+
+.directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) {
+  return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' );
+}]);
+
+/**
+ * The following features are still outstanding: popup delay, animation as a
+ * function, placement as a function, inside, support for more triggers than
+ * just mouse enter/leave, html popovers, and selector delegatation.
+ */
+angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
+
+.directive( 'popoverPopup', function () {
+  return {
+    restrict: 'EA',
+    replace: true,
+    scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
+    templateUrl: 'template/popover/popover.html'
+  };
+})
+
+.directive( 'popover', [ '$tooltip', function ( $tooltip ) {
+  return $tooltip( 'popover', 'popover', 'click' );
+}]);
+
+angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
+
+.constant('progressConfig', {
+  animate: true,
+  max: 100
+})
+
+.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', '$transition', function($scope, $attrs, progressConfig, $transition) {
+    var self = this,
+        bars = [],
+        max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max,
+        animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
+
+    this.addBar = function(bar, element) {
+        var oldValue = 0, index = bar.$parent.$index;
+        if ( angular.isDefined(index) &&  bars[index] ) {
+            oldValue = bars[index].value;
+        }
+        bars.push(bar);
+
+        this.update(element, bar.value, oldValue);
+
+        bar.$watch('value', function(value, oldValue) {
+            if (value !== oldValue) {
+                self.update(element, value, oldValue);
+            }
+        });
+
+        bar.$on('$destroy', function() {
+            self.removeBar(bar);
+        });
+    };
+
+    // Update bar element width
+    this.update = function(element, newValue, oldValue) {
+        var percent = this.getPercentage(newValue);
+
+        if (animate) {
+            element.css('width', this.getPercentage(oldValue) + '%');
+            $transition(element, {width: percent + '%'});
+        } else {
+            element.css({'transition': 'none', 'width': percent + '%'});
+        }
+    };
+
+    this.removeBar = function(bar) {
+        bars.splice(bars.indexOf(bar), 1);
+    };
+
+    this.getPercentage = function(value) {
+        return Math.round(100 * value / max);
+    };
+}])
+
+.directive('progress', function() {
+    return {
+        restrict: 'EA',
+        replace: true,
+        transclude: true,
+        controller: 'ProgressController',
+        require: 'progress',
+        scope: {},
+        template: '<div class="progress" ng-transclude></div>'
+        //templateUrl: 'template/progressbar/progress.html' // Works in AngularJS 1.2
+    };
+})
+
+.directive('bar', function() {
+    return {
+        restrict: 'EA',
+        replace: true,
+        transclude: true,
+        require: '^progress',
+        scope: {
+            value: '=',
+            type: '@'
+        },
+        templateUrl: 'template/progressbar/bar.html',
+        link: function(scope, element, attrs, progressCtrl) {
+            progressCtrl.addBar(scope, element);
+        }
+    };
+})
+
+.directive('progressbar', function() {
+    return {
+        restrict: 'EA',
+        replace: true,
+        transclude: true,
+        controller: 'ProgressController',
+        scope: {
+            value: '=',
+            type: '@'
+        },
+        templateUrl: 'template/progressbar/progressbar.html',
+        link: function(scope, element, attrs, progressCtrl) {
+            progressCtrl.addBar(scope, angular.element(element.children()[0]));
+        }
+    };
+});
+angular.module('ui.bootstrap.rating', [])
+
+.constant('ratingConfig', {
+  max: 5,
+  stateOn: null,
+  stateOff: null
+})
+
+.controller('RatingController', ['$scope', '$attrs', '$parse', 'ratingConfig', function($scope, $attrs, $parse, ratingConfig) {
+
+  this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
+  this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
+  this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
+
+  this.createRateObjects = function(states) {
+    var defaultOptions = {
+      stateOn: this.stateOn,
+      stateOff: this.stateOff
+    };
+
+    for (var i = 0, n = states.length; i < n; i++) {
+      states[i] = angular.extend({ index: i }, defaultOptions, states[i]);
+    }
+    return states;
+  };
+
+  // Get objects used in template
+  $scope.range = angular.isDefined($attrs.ratingStates) ?  this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));
+
+  $scope.rate = function(value) {
+    if ( $scope.value !== value && !$scope.readonly ) {
+      $scope.value = value;
+    }
+  };
+
+  $scope.enter = function(value) {
+    if ( ! $scope.readonly ) {
+      $scope.val = value;
+    }
+    $scope.onHover({value: value});
+  };
+
+  $scope.reset = function() {
+    $scope.val = angular.copy($scope.value);
+    $scope.onLeave();
+  };
+
+  $scope.$watch('value', function(value) {
+    $scope.val = value;
+  });
+
+  $scope.readonly = false;
+  if ($attrs.readonly) {
+    $scope.$parent.$watch($parse($attrs.readonly), function(value) {
+      $scope.readonly = !!value;
+    });
+  }
+}])
+
+.directive('rating', function() {
+  return {
+    restrict: 'EA',
+    scope: {
+      value: '=',
+      onHover: '&',
+      onLeave: '&'
+    },
+    controller: 'RatingController',
+    templateUrl: 'template/rating/rating.html',
+    replace: true
+  };
+});
+
+/**
+ * @ngdoc overview
+ * @name ui.bootstrap.tabs
+ *
+ * @description
+ * AngularJS version of the tabs directive.
+ */
+
+angular.module('ui.bootstrap.tabs', [])
+
+.controller('TabsetController', ['$scope', function TabsetCtrl($scope) {
+  var ctrl = this,
+      tabs = ctrl.tabs = $scope.tabs = [];
+
+  ctrl.select = function(tab) {
+    angular.forEach(tabs, function(tab) {
+      tab.active = false;
+    });
+    tab.active = true;
+  };
+
+  ctrl.addTab = function addTab(tab) {
+    tabs.push(tab);
+    if (tabs.length === 1 || tab.active) {
+      ctrl.select(tab);
+    }
+  };
+
+  ctrl.removeTab = function removeTab(tab) {
+    var index = tabs.indexOf(tab);
+    //Select a new tab if the tab to be removed is selected
+    if (tab.active && tabs.length > 1) {
+      //If this is the last tab, select the previous tab. else, the next tab.
+      var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
+      ctrl.select(tabs[newActiveIndex]);
+    }
+    tabs.splice(index, 1);
+  };
+}])
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tabset
+ * @restrict EA
+ *
+ * @description
+ * Tabset is the outer container for the tabs directive
+ *
+ * @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
+ * @param {boolean=} justified Whether or not to use justified styling for the tabs.
+ *
+ * @example
+<example module="ui.bootstrap">
+  <file name="index.html">
+    <tabset>
+      <tab heading="Tab 1"><b>First</b> Content!</tab>
+      <tab heading="Tab 2"><i>Second</i> Content!</tab>
+    </tabset>
+    <hr />
+    <tabset vertical="true">
+      <tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
+      <tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
+    </tabset>
+    <tabset justified="true">
+      <tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab>
+      <tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab>
+    </tabset>
+  </file>
+</example>
+ */
+.directive('tabset', function() {
+  return {
+    restrict: 'EA',
+    transclude: true,
+    replace: true,
+    scope: {},
+    controller: 'TabsetController',
+    templateUrl: 'template/tabs/tabset.html',
+    link: function(scope, element, attrs) {
+      scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
+      scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
+      scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
+    }
+  };
+})
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tab
+ * @restrict EA
+ *
+ * @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}.
+ * @param {string=} select An expression to evaluate when the tab is selected.
+ * @param {boolean=} active A binding, telling whether or not this tab is selected.
+ * @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
+ *
+ * @description
+ * Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
+ *
+ * @example
+<example module="ui.bootstrap">
+  <file name="index.html">
+    <div ng-controller="TabsDemoCtrl">
+      <button class="btn btn-small" ng-click="items[0].active = true">
+        Select item 1, using active binding
+      </button>
+      <button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
+        Enable/disable item 2, using disabled binding
+      </button>
+      <br />
+      <tabset>
+        <tab heading="Tab 1">First Tab</tab>
+        <tab select="alertMe()">
+          <tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
+          Second Tab, with alert callback and html heading!
+        </tab>
+        <tab ng-repeat="item in items"
+          heading="{{item.title}}"
+          disabled="item.disabled"
+          active="item.active">
+          {{item.content}}
+        </tab>
+      </tabset>
+    </div>
+  </file>
+  <file name="script.js">
+    function TabsDemoCtrl($scope) {
+      $scope.items = [
+        { title:"Dynamic Title 1", content:"Dynamic Item 0" },
+        { title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
+      ];
+
+      $scope.alertMe = function() {
+        setTimeout(function() {
+          alert("You've selected the alert tab!");
+        });
+      };
+    };
+  </file>
+</example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ui.bootstrap.tabs.directive:tabHeading
+ * @restrict EA
+ *
+ * @description
+ * Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
+ *
+ * @example
+<example module="ui.bootstrap">
+  <file name="index.html">
+    <tabset>
+      <tab>
+        <tab-heading><b>HTML</b> in my titles?!</tab-heading>
+        And some content, too!
+      </tab>
+      <tab>
+        <tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
+        That's right.
+      </tab>
+    </tabset>
+  </file>
+</example>
+ */
+.directive('tab', ['$parse', function($parse) {
+  return {
+    require: '^tabset',
+    restrict: 'EA',
+    replace: true,
+    templateUrl: 'template/tabs/tab.html',
+    transclude: true,
+    scope: {
+      heading: '@',
+      onSelect: '&select', //This callback is called in contentHeadingTransclude
+                          //once it inserts the tab's content into the dom
+      onDeselect: '&deselect'
+    },
+    controller: function() {
+      //Empty controller so other directives can require being 'under' a tab
+    },
+    compile: function(elm, attrs, transclude) {
+      return function postLink(scope, elm, attrs, tabsetCtrl) {
+        var getActive, setActive;
+        if (attrs.active) {
+          getActive = $parse(attrs.active);
+          setActive = getActive.assign;
+          scope.$parent.$watch(getActive, function updateActive(value, oldVal) {
+            // Avoid re-initializing scope.active as it is already initialized
+            // below. (watcher is called async during init with value ===
+            // oldVal)
+            if (value !== oldVal) {
+              scope.active = !!value;
+            }
+          });
+          scope.active = getActive(scope.$parent);
+        } else {
+          setActive = getActive = angular.noop;
+        }
+
+        scope.$watch('active', function(active) {
+          // Note this watcher also initializes and assigns scope.active to the
+          // attrs.active expression.
+          setActive(scope.$parent, active);
+          if (active) {
+            tabsetCtrl.select(scope);
+            scope.onSelect();
+          } else {
+            scope.onDeselect();
+          }
+        });
+
+        scope.disabled = false;
+        if ( attrs.disabled ) {
+          scope.$parent.$watch($parse(attrs.disabled), function(value) {
+            scope.disabled = !! value;
+          });
+        }
+
+        scope.select = function() {
+          if ( ! scope.disabled ) {
+            scope.active = true;
+          }
+        };
+
+        tabsetCtrl.addTab(scope);
+        scope.$on('$destroy', function() {
+          tabsetCtrl.removeTab(scope);
+        });
+
+
+        //We need to transclude later, once the content container is ready.
+        //when this link happens, we're inside a tab heading.
+        scope.$transcludeFn = transclude;
+      };
+    }
+  };
+}])
+
+.directive('tabHeadingTransclude', [function() {
+  return {
+    restrict: 'A',
+    require: '^tab',
+    link: function(scope, elm, attrs, tabCtrl) {
+      scope.$watch('headingElement', function updateHeadingElement(heading) {
+        if (heading) {
+          elm.html('');
+          elm.append(heading);
+        }
+      });
+    }
+  };
+}])
+
+.directive('tabContentTransclude', function() {
+  return {
+    restrict: 'A',
+    require: '^tabset',
+    link: function(scope, elm, attrs) {
+      var tab = scope.$eval(attrs.tabContentTransclude);
+
+      //Now our tab is ready to be transcluded: both the tab heading area
+      //and the tab content area are loaded.  Transclude 'em both.
+      tab.$transcludeFn(tab.$parent, function(contents) {
+        angular.forEach(contents, function(node) {
+          if (isTabHeading(node)) {
+            //Let tabHeadingTransclude know.
+            tab.headingElement = node;
+          } else {
+            elm.append(node);
+          }
+        });
+      });
+    }
+  };
+  function isTabHeading(node) {
+    return node.tagName &&  (
+      node.hasAttribute('tab-heading') ||
+      node.hasAttribute('data-tab-heading') ||
+      node.tagName.toLowerCase() === 'tab-heading' ||
+      node.tagName.toLowerCase() === 'data-tab-heading'
+    );
+  }
+})
+
+;
+
+angular.module('ui.bootstrap.timepicker', [])
+
+.constant('timepickerConfig', {
+  hourStep: 1,
+  minuteStep: 1,
+  showMeridian: true,
+  meridians: null,
+  readonlyInput: false,
+  mousewheel: true
+})
+
+.directive('timepicker', ['$parse', '$log', 'timepickerConfig', '$locale', function ($parse, $log, timepickerConfig, $locale) {
+  return {
+    restrict: 'EA',
+    require:'?^ngModel',
+    replace: true,
+    scope: {},
+    templateUrl: 'template/timepicker/timepicker.html',
+    link: function(scope, element, attrs, ngModel) {
+      if ( !ngModel ) {
+        return; // do nothing if no ng-model
+      }
+
+      var selected = new Date(),
+          meridians = angular.isDefined(attrs.meridians) ? scope.$parent.$eval(attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS;
+
+      var hourStep = timepickerConfig.hourStep;
+      if (attrs.hourStep) {
+        scope.$parent.$watch($parse(attrs.hourStep), function(value) {
+          hourStep = parseInt(value, 10);
+        });
+      }
+
+      var minuteStep = timepickerConfig.minuteStep;
+      if (attrs.minuteStep) {
+        scope.$parent.$watch($parse(attrs.minuteStep), function(value) {
+          minuteStep = parseInt(value, 10);
+        });
+      }
+
+      // 12H / 24H mode
+      scope.showMeridian = timepickerConfig.showMeridian;
+      if (attrs.showMeridian) {
+        scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
+          scope.showMeridian = !!value;
+
+          if ( ngModel.$error.time ) {
+            // Evaluate from template
+            var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
+            if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
+              selected.setHours( hours );
+              refresh();
+            }
+          } else {
+            updateTemplate();
+          }
+        });
+      }
+
+      // Get scope.hours in 24H mode if valid
+      function getHoursFromTemplate ( ) {
+        var hours = parseInt( scope.hours, 10 );
+        var valid = ( scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
+        if ( !valid ) {
+          return undefined;
+        }
+
+        if ( scope.showMeridian ) {
+          if ( hours === 12 ) {
+            hours = 0;
+          }
+          if ( scope.meridian === meridians[1] ) {
+            hours = hours + 12;
+          }
+        }
+        return hours;
+      }
+
+      function getMinutesFromTemplate() {
+        var minutes = parseInt(scope.minutes, 10);
+        return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined;
+      }
+
+      function pad( value ) {
+        return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
+      }
+
+      // Input elements
+      var inputs = element.find('input'), hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
+
+      // Respond on mousewheel spin
+      var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
+      if ( mousewheel ) {
+
+        var isScrollingUp = function(e) {
+          if (e.originalEvent) {
+            e = e.originalEvent;
+          }
+          //pick correct delta variable depending on event
+          var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
+          return (e.detail || delta > 0);
+        };
+
+        hoursInputEl.bind('mousewheel wheel', function(e) {
+          scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
+          e.preventDefault();
+        });
+
+        minutesInputEl.bind('mousewheel wheel', function(e) {
+          scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
+          e.preventDefault();
+        });
+      }
+
+      scope.readonlyInput = (angular.isDefined(attrs.readonlyInput)) ? scope.$eval(attrs.readonlyInput) : timepickerConfig.readonlyInput;
+      if ( ! scope.readonlyInput ) {
+
+        var invalidate = function(invalidHours, invalidMinutes) {
+          ngModel.$setViewValue( null );
+          ngModel.$setValidity('time', false);
+          if (angular.isDefined(invalidHours)) {
+            scope.invalidHours = invalidHours;
+          }
+          if (angular.isDefined(invalidMinutes)) {
+            scope.invalidMinutes = invalidMinutes;
+          }
+        };
+
+        scope.updateHours = function() {
+          var hours = getHoursFromTemplate();
+
+          if ( angular.isDefined(hours) ) {
+            selected.setHours( hours );
+            refresh( 'h' );
+          } else {
+            invalidate(true);
+          }
+        };
+
+        hoursInputEl.bind('blur', function(e) {
+          if ( !scope.validHours && scope.hours < 10) {
+            scope.$apply( function() {
+              scope.hours = pad( scope.hours );
+            });
+          }
+        });
+
+        scope.updateMinutes = function() {
+          var minutes = getMinutesFromTemplate();
+
+          if ( angular.isDefined(minutes) ) {
+            selected.setMinutes( minutes );
+            refresh( 'm' );
+          } else {
+            invalidate(undefined, true);
+          }
+        };
+
+        minutesInputEl.bind('blur', function(e) {
+          if ( !scope.invalidMinutes && scope.minutes < 10 ) {
+            scope.$apply( function() {
+              scope.minutes = pad( scope.minutes );
+            });
+          }
+        });
+      } else {
+        scope.updateHours = angular.noop;
+        scope.updateMinutes = angular.noop;
+      }
+
+      ngModel.$render = function() {
+        var date = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : null;
+
+        if ( isNaN(date) ) {
+          ngModel.$setValidity('time', false);
+          $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
+        } else {
+          if ( date ) {
+            selected = date;
+          }
+          makeValid();
+          updateTemplate();
+        }
+      };
+
+      // Call internally when we know that model is valid.
+      function refresh( keyboardChange ) {
+        makeValid();
+        ngModel.$setViewValue( new Date(selected) );
+        updateTemplate( keyboardChange );
+      }
+
+      function makeValid() {
+        ngModel.$setValidity('time', true);
+        scope.invalidHours = false;
+        scope.invalidMinutes = false;
+      }
+
+      function updateTemplate( keyboardChange ) {
+        var hours = selected.getHours(), minutes = selected.getMinutes();
+
+        if ( scope.showMeridian ) {
+          hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system
+        }
+        scope.hours =  keyboardChange === 'h' ? hours : pad(hours);
+        scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
+        scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
+      }
+
+      function addMinutes( minutes ) {
+        var dt = new Date( selected.getTime() + minutes * 60000 );
+        selected.setHours( dt.getHours(), dt.getMinutes() );
+        refresh();
+      }
+
+      scope.incrementHours = function() {
+        addMinutes( hourStep * 60 );
+      };
+      scope.decrementHours = function() {
+        addMinutes( - hourStep * 60 );
+      };
+      scope.incrementMinutes = function() {
+        addMinutes( minuteStep );
+      };
+      scope.decrementMinutes = function() {
+        addMinutes( - minuteStep );
+      };
+      scope.toggleMeridian = function() {
+        addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) );
+      };
+    }
+  };
+}]);
+
+angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
+
+/**
+ * A helper service that can parse typeahead's syntax (string provided by users)
+ * Extracted to a separate service for ease of unit testing
+ */
+  .factory('typeaheadParser', ['$parse', function ($parse) {
+
+  //                      00000111000000000000022200000000000000003333333333333330000000000044000
+  var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
+
+  return {
+    parse:function (input) {
+
+      var match = input.match(TYPEAHEAD_REGEXP), modelMapper, viewMapper, source;
+      if (!match) {
+        throw new Error(
+          "Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_'" +
+            " but got '" + input + "'.");
+      }
+
+      return {
+        itemName:match[3],
+        source:$parse(match[4]),
+        viewMapper:$parse(match[2] || match[1]),
+        modelMapper:$parse(match[1])
+      };
+    }
+  };
+}])
+
+  .directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
+    function ($compile, $parse, $q, $timeout, $document, $position, typeaheadParser) {
+
+  var HOT_KEYS = [9, 13, 27, 38, 40];
+
+  return {
+    require:'ngModel',
+    link:function (originalScope, element, attrs, modelCtrl) {
+
+      //SUPPORTED ATTRIBUTES (OPTIONS)
+
+      //minimal no of characters that needs to be entered before typeahead kicks-in
+      var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
+
+      //minimal wait time after last character typed before typehead kicks-in
+      var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
+
+      //should it restrict model values to the ones selected from the popup only?
+      var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;
+
+      //binding to a variable that indicates if matches are being retrieved asynchronously
+      var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;
+
+      //a callback executed when a match is selected
+      var onSelectCallback = $parse(attrs.typeaheadOnSelect);
+
+      var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
+
+      var appendToBody =  attrs.typeaheadAppendToBody ? $parse(attrs.typeaheadAppendToBody) : false;
+
+      //INTERNAL VARIABLES
+
+      //model setter executed upon match selection
+      var $setModelValue = $parse(attrs.ngModel).assign;
+
+      //expressions used by typeahead
+      var parserResult = typeaheadParser.parse(attrs.typeahead);
+
+      var hasFocus;
+
+      //pop-up element used to display matches
+      var popUpEl = angular.element('<div typeahead-popup></div>');
+      popUpEl.attr({
+        matches: 'matches',
+        active: 'activeIdx',
+        select: 'select(activeIdx)',
+        query: 'query',
+        position: 'position'
+      });
+      //custom item template
+      if (angular.isDefined(attrs.typeaheadTemplateUrl)) {
+        popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
+      }
+
+      //create a child scope for the typeahead directive so we are not polluting original scope
+      //with typeahead-specific data (matches, query etc.)
+      var scope = originalScope.$new();
+      originalScope.$on('$destroy', function(){
+        scope.$destroy();
+      });
+
+      var resetMatches = function() {
+        scope.matches = [];
+        scope.activeIdx = -1;
+      };
+
+      var getMatchesAsync = function(inputValue) {
+
+        var locals = {$viewValue: inputValue};
+        isLoadingSetter(originalScope, true);
+        $q.when(parserResult.source(originalScope, locals)).then(function(matches) {
+
+          //it might happen that several async queries were in progress if a user were typing fast
+          //but we are interested only in responses that correspond to the current view value
+          if (inputValue === modelCtrl.$viewValue && hasFocus) {
+            if (matches.length > 0) {
+
+              scope.activeIdx = 0;
+              scope.matches.length = 0;
+
+              //transform labels
+              for(var i=0; i<matches.length; i++) {
+                locals[parserResult.itemName] = matches[i];
+                scope.matches.push({
+                  label: parserResult.viewMapper(scope, locals),
+                  model: matches[i]
+                });
+              }
+
+              scope.query = inputValue;
+              //position pop-up with matches - we need to re-calculate its position each time we are opening a window
+              //with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
+              //due to other elements being rendered
+              scope.position = appendToBody ? $position.offset(element) : $position.position(element);
+              scope.position.top = scope.position.top + element.prop('offsetHeight');
+
+            } else {
+              resetMatches();
+            }
+            isLoadingSetter(originalScope, false);
+          }
+        }, function(){
+          resetMatches();
+          isLoadingSetter(originalScope, false);
+        });
+      };
+
+      resetMatches();
+
+      //we need to propagate user's query so we can higlight matches
+      scope.query = undefined;
+
+      //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later 
+      var timeoutPromise;
+
+      //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
+      //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
+      modelCtrl.$parsers.unshift(function (inputValue) {
+
+        hasFocus = true;
+
+        if (inputValue && inputValue.length >= minSearch) {
+          if (waitTime > 0) {
+            if (timeoutPromise) {
+              $timeout.cancel(timeoutPromise);//cancel previous timeout
+            }
+            timeoutPromise = $timeout(function () {
+              getMatchesAsync(inputValue);
+            }, waitTime);
+          } else {
+            getMatchesAsync(inputValue);
+          }
+        } else {
+          isLoadingSetter(originalScope, false);
+          resetMatches();
+        }
+
+        if (isEditable) {
+          return inputValue;
+        } else {
+          if (!inputValue) {
+            // Reset in case user had typed something previously.
+            modelCtrl.$setValidity('editable', true);
+            return inputValue;
+          } else {
+            modelCtrl.$setValidity('editable', false);
+            return undefined;
+          }
+        }
+      });
+
+      modelCtrl.$formatters.push(function (modelValue) {
+
+        var candidateViewValue, emptyViewValue;
+        var locals = {};
+
+        if (inputFormatter) {
+
+          locals['$model'] = modelValue;
+          return inputFormatter(originalScope, locals);
+
+        } else {
+
+          //it might happen that we don't have enough info to properly render input value
+          //we need to check for this situation and simply return model value if we can't apply custom formatting
+          locals[parserResult.itemName] = modelValue;
+          candidateViewValue = parserResult.viewMapper(originalScope, locals);
+          locals[parserResult.itemName] = undefined;
+          emptyViewValue = parserResult.viewMapper(originalScope, locals);
+
+          return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue;
+        }
+      });
+
+      scope.select = function (activeIdx) {
+        //called from within the $digest() cycle
+        var locals = {};
+        var model, item;
+
+        locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
+        model = parserResult.modelMapper(originalScope, locals);
+        $setModelValue(originalScope, model);
+        modelCtrl.$setValidity('editable', true);
+
+        onSelectCallback(originalScope, {
+          $item: item,
+          $model: model,
+          $label: parserResult.viewMapper(originalScope, locals)
+        });
+
+        resetMatches();
+
+        //return focus to the input element if a mach was selected via a mouse click event
+        element[0].focus();
+      };
+
+      //bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)
+      element.bind('keydown', function (evt) {
+
+        //typeahead is open and an "interesting" key was pressed
+        if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
+          return;
+        }
+
+        evt.preventDefault();
+
+        if (evt.which === 40) {
+          scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
+          scope.$digest();
+
+        } else if (evt.which === 38) {
+          scope.activeIdx = (scope.activeIdx ? scope.activeIdx : scope.matches.length) - 1;
+          scope.$digest();
+
+        } else if (evt.which === 13 || evt.which === 9) {
+          scope.$apply(function () {
+            scope.select(scope.activeIdx);
+          });
+
+        } else if (evt.which === 27) {
+          evt.stopPropagation();
+
+          resetMatches();
+          scope.$digest();
+        }
+      });
+
+      element.bind('blur', function (evt) {
+        hasFocus = false;
+      });
+
+      // Keep reference to click handler to unbind it.
+      var dismissClickHandler = function (evt) {
+        if (element[0] !== evt.target) {
+          resetMatches();
+          scope.$digest();
+        }
+      };
+
+      $document.bind('click', dismissClickHandler);
+
+      originalScope.$on('$destroy', function(){
+        $document.unbind('click', dismissClickHandler);
+      });
+
+      var $popup = $compile(popUpEl)(scope);
+      if ( appendToBody ) {
+        $document.find('body').append($popup);
+      } else {
+        element.after($popup);
+      }
+    }
+  };
+
+}])
+
+  .directive('typeaheadPopup', function () {
+    return {
+      restrict:'EA',
+      scope:{
+        matches:'=',
+        query:'=',
+        active:'=',
+        position:'=',
+        select:'&'
+      },
+      replace:true,
+      templateUrl:'template/typeahead/typeahead-popup.html',
+      link:function (scope, element, attrs) {
+
+        scope.templateUrl = attrs.templateUrl;
+
+        scope.isOpen = function () {
+          return scope.matches.length > 0;
+        };
+
+        scope.isActive = function (matchIdx) {
+          return scope.active == matchIdx;
+        };
+
+        scope.selectActive = function (matchIdx) {
+          scope.active = matchIdx;
+        };
+
+        scope.selectMatch = function (activeIdx) {
+          scope.select({activeIdx:activeIdx});
+        };
+      }
+    };
+  })
+
+  .directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) {
+    return {
+      restrict:'EA',
+      scope:{
+        index:'=',
+        match:'=',
+        query:'='
+      },
+      link:function (scope, element, attrs) {
+        var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html';
+        $http.get(tplUrl, {cache: $templateCache}).success(function(tplContent){
+           element.replaceWith($compile(tplContent.trim())(scope));
+        });
+      }
+    };
+  }])
+
+  .filter('typeaheadHighlight', function() {
+
+    function escapeRegexp(queryToEscape) {
+      return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
+    }
+
+    return function(matchItem, query) {
+      return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
+    };
+  });
+angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/accordion/accordion-group.html",
+    "<div class=\"panel panel-default\">\n" +
+    "  <div class=\"panel-heading\">\n" +
+    "    <h4 class=\"panel-title\">\n" +
+    "      <a class=\"accordion-toggle\" ng-click=\"isOpen = !isOpen\" accordion-transclude=\"heading\">{{heading}}</a>\n" +
+    "    </h4>\n" +
+    "  </div>\n" +
+    "  <div class=\"panel-collapse\" collapse=\"!isOpen\">\n" +
+    "    <div class=\"panel-body\" ng-transclude></div>\n" +
+    "  </div>\n" +
+    "</div>");
+}]);
+
+angular.module("template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/accordion/accordion.html",
+    "<div class=\"panel-group\" ng-transclude></div>");
+}]);
+
+angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/alert/alert.html",
+    "<div class='alert' ng-class='\"alert-\" + (type || \"warning\")'>\n" +
+    "    <button ng-show='closeable' type='button' class='close' ng-click='close()'>&times;</button>\n" +
+    "    <div ng-transclude></div>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/carousel/carousel.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/carousel/carousel.html",
+    "<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\">\n" +
+    "    <ol class=\"carousel-indicators\" ng-show=\"slides().length > 1\">\n" +
+    "        <li ng-repeat=\"slide in slides()\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\"></li>\n" +
+    "    </ol>\n" +
+    "    <div class=\"carousel-inner\" ng-transclude></div>\n" +
+    "    <a class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides().length > 1\"><span class=\"icon-prev\"></span></a>\n" +
+    "    <a class=\"right carousel-control\" ng-click=\"next()\" ng-show=\"slides().length > 1\"><span class=\"icon-next\"></span></a>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/carousel/slide.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/carousel/slide.html",
+    "<div ng-class=\"{\n" +
+    "    'active': leaving || (active && !entering),\n" +
+    "    'prev': (next || active) && direction=='prev',\n" +
+    "    'next': (next || active) && direction=='next',\n" +
+    "    'right': direction=='prev',\n" +
+    "    'left': direction=='next'\n" +
+    "  }\" class=\"item text-center\" ng-transclude></div>\n" +
+    "");
+}]);
+
+angular.module("template/datepicker/datepicker.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/datepicker/datepicker.html",
+    "<table>\n" +
+    "  <thead>\n" +
+    "    <tr>\n" +
+    "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
+    "      <th colspan=\"{{rows[0].length - 2 + showWeekNumbers}}\"><button type=\"button\" class=\"btn btn-default btn-sm btn-block\" ng-click=\"toggleMode()\"><strong>{{title}}</strong></button></th>\n" +
+    "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
+    "    </tr>\n" +
+    "    <tr ng-show=\"labels.length > 0\" class=\"h6\">\n" +
+    "      <th ng-show=\"showWeekNumbers\" class=\"text-center\">#</th>\n" +
+    "      <th ng-repeat=\"label in labels\" class=\"text-center\">{{label}}</th>\n" +
+    "    </tr>\n" +
+    "  </thead>\n" +
+    "  <tbody>\n" +
+    "    <tr ng-repeat=\"row in rows\">\n" +
+    "      <td ng-show=\"showWeekNumbers\" class=\"text-center\"><em>{{ getWeekNumber(row) }}</em></td>\n" +
+    "      <td ng-repeat=\"dt in row\" class=\"text-center\">\n" +
+    "        <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'btn-info': dt.selected}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{'text-muted': dt.secondary}\">{{dt.label}}</span></button>\n" +
+    "      </td>\n" +
+    "    </tr>\n" +
+    "  </tbody>\n" +
+    "</table>\n" +
+    "");
+}]);
+
+angular.module("template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/datepicker/popup.html",
+    "<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
+    "  <li ng-transclude></li>\n" +
+    "  <li ng-show=\"showButtonBar\" style=\"padding:10px 9px 2px\">\n" +
+    "          <span class=\"btn-group\">\n" +
+    "                  <button type=\"button\" class=\"btn btn-sm btn-info\" ng-click=\"today()\">{{currentText}}</button>\n" +
+    "                  <button type=\"button\" class=\"btn btn-sm btn-default\" ng-click=\"showWeeks = ! showWeeks\" ng-class=\"{active: showWeeks}\">{{toggleWeeksText}}</button>\n" +
+    "                  <button type=\"button\" class=\"btn btn-sm btn-danger\" ng-click=\"clear()\">{{clearText}}</button>\n" +
+    "          </span>\n" +
+    "          <button type=\"button\" class=\"btn btn-sm btn-success pull-right\" ng-click=\"isOpen = false\">{{closeText}}</button>\n" +
+    "  </li>\n" +
+    "</ul>\n" +
+    "");
+}]);
+
+angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/modal/backdrop.html",
+    "<div class=\"modal-backdrop fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1040 + index*10}\"></div>");
+}]);
+
+angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/modal/window.html",
+    "<div tabindex=\"-1\" class=\"modal fade {{ windowClass }}\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
+    "    <div class=\"modal-dialog\"><div class=\"modal-content\" ng-transclude></div></div>\n" +
+    "</div>");
+}]);
+
+angular.module("template/pagination/pager.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/pagination/pager.html",
+    "<ul class=\"pager\">\n" +
+    "  <li ng-repeat=\"page in pages\" ng-class=\"{disabled: page.disabled, previous: page.previous, next: page.next}\"><a ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
+    "</ul>");
+}]);
+
+angular.module("template/pagination/pagination.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/pagination/pagination.html",
+    "<ul class=\"pagination\">\n" +
+    "  <li ng-repeat=\"page in pages\" ng-class=\"{active: page.active, disabled: page.disabled}\"><a ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
+    "</ul>");
+}]);
+
+angular.module("template/tooltip/tooltip-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/tooltip/tooltip-html-unsafe-popup.html",
+    "<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
+    "  <div class=\"tooltip-arrow\"></div>\n" +
+    "  <div class=\"tooltip-inner\" bind-html-unsafe=\"content\"></div>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/tooltip/tooltip-popup.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/tooltip/tooltip-popup.html",
+    "<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
+    "  <div class=\"tooltip-arrow\"></div>\n" +
+    "  <div class=\"tooltip-inner\" ng-bind=\"content\"></div>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/popover/popover.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/popover/popover.html",
+    "<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
+    "  <div class=\"arrow\"></div>\n" +
+    "\n" +
+    "  <div class=\"popover-inner\">\n" +
+    "      <h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" +
+    "      <div class=\"popover-content\" ng-bind=\"content\"></div>\n" +
+    "  </div>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/progressbar/bar.html",
+    "<div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" ng-transclude></div>");
+}]);
+
+angular.module("template/progressbar/progress.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/progressbar/progress.html",
+    "<div class=\"progress\" ng-transclude></div>");
+}]);
+
+angular.module("template/progressbar/progressbar.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/progressbar/progressbar.html",
+    "<div class=\"progress\"><div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" ng-transclude></div></div>");
+}]);
+
+angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/rating/rating.html",
+    "<span ng-mouseleave=\"reset()\">\n" +
+    "    <i ng-repeat=\"r in range\" ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" class=\"glyphicon\" ng-class=\"$index < val && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')\"></i>\n" +
+    "</span>");
+}]);
+
+angular.module("template/tabs/tab.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/tabs/tab.html",
+    "<li ng-class=\"{active: active, disabled: disabled}\">\n" +
+    "  <a ng-click=\"select()\" tab-heading-transclude>{{heading}}</a>\n" +
+    "</li>\n" +
+    "");
+}]);
+
+angular.module("template/tabs/tabset-titles.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/tabs/tabset-titles.html",
+    "<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n" +
+    "</ul>\n" +
+    "");
+}]);
+
+angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/tabs/tabset.html",
+    "\n" +
+    "<div class=\"tabbable\">\n" +
+    "  <ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
+    "  <div class=\"tab-content\">\n" +
+    "    <div class=\"tab-pane\" \n" +
+    "         ng-repeat=\"tab in tabs\" \n" +
+    "         ng-class=\"{active: tab.active}\"\n" +
+    "         tab-content-transclude=\"tab\">\n" +
+    "    </div>\n" +
+    "  </div>\n" +
+    "</div>\n" +
+    "");
+}]);
+
+angular.module("template/timepicker/timepicker.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/timepicker/timepicker.html",
+    "<table>\n" +
+    "  <tbody>\n" +
+    "          <tr class=\"text-center\">\n" +
+    "                  <td><a ng-click=\"incrementHours()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
+    "                  <td>&nbsp;</td>\n" +
+    "                  <td><a ng-click=\"incrementMinutes()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
+    "                  <td ng-show=\"showMeridian\"></td>\n" +
+    "          </tr>\n" +
+    "          <tr>\n" +
+    "                  <td style=\"width:50px;\" class=\"form-group\" ng-class=\"{'has-error': invalidHours}\">\n" +
+    "                          <input type=\"text\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"form-control text-center\" ng-mousewheel=\"incrementHours()\" ng-readonly=\"readonlyInput\" maxlength=\"2\">\n" +
+    "                  </td>\n" +
+    "                  <td>:</td>\n" +
+    "                  <td style=\"width:50px;\" class=\"form-group\" ng-class=\"{'has-error': invalidMinutes}\">\n" +
+    "                          <input type=\"text\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"form-control text-center\" ng-readonly=\"readonlyInput\" maxlength=\"2\">\n" +
+    "                  </td>\n" +
+    "                  <td ng-show=\"showMeridian\"><button type=\"button\" class=\"btn btn-default text-center\" ng-click=\"toggleMeridian()\">{{meridian}}</button></td>\n" +
+    "          </tr>\n" +
+    "          <tr class=\"text-center\">\n" +
+    "                  <td><a ng-click=\"decrementHours()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
+    "                  <td>&nbsp;</td>\n" +
+    "                  <td><a ng-click=\"decrementMinutes()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
+    "                  <td ng-show=\"showMeridian\"></td>\n" +
+    "          </tr>\n" +
+    "  </tbody>\n" +
+    "</table>\n" +
+    "");
+}]);
+
+angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/typeahead/typeahead-match.html",
+    "<a tabindex=\"-1\" bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a>");
+}]);
+
+angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
+  $templateCache.put("template/typeahead/typeahead-popup.html",
+    "<ul class=\"dropdown-menu\" ng-style=\"{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
+    "    <li ng-repeat=\"match in matches\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\">\n" +
+    "        <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
+    "    </li>\n" +
+    "</ul>");
+}]);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.js
new file mode 100644 (file)
index 0000000..c3c3dcd
--- /dev/null
@@ -0,0 +1,13034 @@
+/*! ui-grid - v3.0.0-rc.3 - 2014-09-25
+* Copyright (c) 2014 ; License: MIT */
+(function () {
+  'use strict';
+  angular.module('ui.grid.i18n', []);
+  angular.module('ui.grid', ['ui.grid.i18n']);
+})();
+(function () {
+  'use strict';
+  angular.module('ui.grid').constant('uiGridConstants', {
+    CUSTOM_FILTERS: /CUSTOM_FILTERS/g,
+    COL_FIELD: /COL_FIELD/g,
+    DISPLAY_CELL_TEMPLATE: /DISPLAY_CELL_TEMPLATE/g,
+    TEMPLATE_REGEXP: /<.+>/,
+    FUNC_REGEXP: /(\([^)]*\))?$/,
+    DOT_REGEXP: /\./g,
+    APOS_REGEXP: /'/g,
+    BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,
+    COL_CLASS_PREFIX: 'ui-grid-col',
+    events: {
+      GRID_SCROLL: 'uiGridScroll',
+      COLUMN_MENU_SHOWN: 'uiGridColMenuShown',
+      ITEM_DRAGGING: 'uiGridItemDragStart' // For any item being dragged
+    },
+    // copied from http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html
+    keymap: {
+      TAB: 9,
+      STRG: 17,
+      CTRL: 17,
+      CTRLRIGHT: 18,
+      CTRLR: 18,
+      SHIFT: 16,
+      RETURN: 13,
+      ENTER: 13,
+      BACKSPACE: 8,
+      BCKSP: 8,
+      ALT: 18,
+      ALTR: 17,
+      ALTRIGHT: 17,
+      SPACE: 32,
+      WIN: 91,
+      MAC: 91,
+      FN: null,
+      UP: 38,
+      DOWN: 40,
+      LEFT: 37,
+      RIGHT: 39,
+      ESC: 27,
+      DEL: 46,
+      F1: 112,
+      F2: 113,
+      F3: 114,
+      F4: 115,
+      F5: 116,
+      F6: 117,
+      F7: 118,
+      F8: 119,
+      F9: 120,
+      F10: 121,
+      F11: 122,
+      F12: 123
+    },
+    ASC: 'asc',
+    DESC: 'desc',
+    filter: {
+      STARTS_WITH: 2,
+      ENDS_WITH: 4,
+      EXACT: 8,
+      CONTAINS: 16,
+      GREATER_THAN: 32,
+      GREATER_THAN_OR_EQUAL: 64,
+      LESS_THAN: 128,
+      LESS_THAN_OR_EQUAL: 256,
+      NOT_EQUAL: 512
+    },
+
+    aggregationTypes: {
+      sum: 2,
+      count: 4,
+      avg: 8,
+      min: 16,
+      max: 32
+    },
+
+    // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them?
+    CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', '฿', '₫']
+  });
+
+})();
+angular.module('ui.grid').directive('uiGridCell', ['$compile', '$log', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $log, $parse, gridUtil, uiGridConstants) {
+  var uiGridCell = {
+    priority: 0,
+    scope: false,
+    require: '?^uiGrid',
+    compile: function() {
+      return {
+        pre: function($scope, $elm, $attrs, uiGridCtrl) {
+          function compileTemplate() {
+            var compiledElementFn = $scope.col.compiledElementFn;
+
+            compiledElementFn($scope, function(clonedElement, scope) {
+              $elm.append(clonedElement);
+            });
+          }
+
+          // If the grid controller is present, use it to get the compiled cell template function
+          if (uiGridCtrl) {
+             compileTemplate();
+          }
+          // No controller, compile the element manually (for unit tests)
+          else {
+            var html = $scope.col.cellTemplate
+              .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)');
+            var cellElement = $compile(html)($scope);
+            $elm.append(cellElement);
+          }
+        },
+        post: function($scope, $elm, $attrs, uiGridCtrl) {
+          $elm.addClass($scope.col.getColClass(false));
+          if ($scope.col.cellClass) {
+            //var contents = angular.element($elm[0].getElementsByClassName('ui-grid-cell-contents'));
+            var contents = $elm;
+            if (angular.isFunction($scope.col.cellClass)) {
+              contents.addClass($scope.col.cellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex));
+            }
+            else {
+              contents.addClass($scope.col.cellClass);
+            }
+          }
+        }
+      };
+    }
+  };
+
+  return uiGridCell;
+}]);
+
+
+(function(){
+
+angular.module('ui.grid').directive('uiGridColumnMenu', ['$log', '$timeout', '$window', '$document', '$injector', 'gridUtil', 'uiGridConstants', 'i18nService', function ($log, $timeout, $window, $document, $injector, gridUtil, uiGridConstants, i18nService) {
+
+  var uiGridColumnMenu = {
+    priority: 0,
+    scope: true,
+    require: '?^uiGrid',
+    templateUrl: 'ui-grid/uiGridColumnMenu',
+    replace: true,
+    link: function ($scope, $elm, $attrs, uiGridCtrl) {
+      gridUtil.enableAnimations($elm);
+
+      $scope.grid = uiGridCtrl.grid;
+
+      var self = this;
+
+      // Store a reference to this link/controller in the main uiGrid controller
+      // to allow showMenu later
+      uiGridCtrl.columnMenuScope = $scope;
+
+      // Save whether we're shown or not so the columns can check
+      self.shown = $scope.menuShown = false;
+
+      // Put asc and desc sort directions in scope
+      $scope.asc = uiGridConstants.ASC;
+      $scope.desc = uiGridConstants.DESC;
+
+      // $scope.i18n = i18nService;
+
+      // Get the grid menu element. We'll use it to calculate positioning
+      $scope.menu = $elm[0].querySelectorAll('.ui-grid-menu');
+
+      // Get the inner menu part. It's what slides up/down
+      $scope.inner = $elm[0].querySelectorAll('.ui-grid-menu-inner');
+
+      /**
+       * @ngdoc boolean
+       * @name enableSorting
+       * @propertyOf ui.grid.class:GridOptions.columnDef
+       * @description (optional) True by default. When enabled, this setting adds sort
+       * widgets to the column header, allowing sorting of the data in the individual column.
+       */
+      $scope.sortable = function() {
+        if (uiGridCtrl.grid.options.enableSorting && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableSorting) {
+          return true;
+        }
+        else {
+          return false;
+        }
+      };
+
+      /**
+       * @ngdoc boolean
+       * @name enableFiltering
+       * @propertyOf ui.grid.class:GridOptions.columnDef
+       * @description (optional) True by default. When enabled, this setting adds filter
+       * widgets to the column header, allowing filtering of the data in the individual column.
+       */
+      $scope.filterable = function() {
+        if (uiGridCtrl.grid.options.enableFiltering && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableFiltering) {
+          return true;
+        }
+        else {
+          return false;
+        }
+      };
+      
+      var defaultMenuItems = [
+        // NOTE: disabling this in favor of a little filter text box
+        // Column filter input
+        // {
+        //   templateUrl: 'ui-grid/uiGridColumnFilter',
+        //   action: function($event) {
+        //     $event.stopPropagation();
+        //     $scope.filterColumn($event);
+        //   },
+        //   cancel: function ($event) {
+        //     $event.stopPropagation();
+
+        //     $scope.col.filter = {};
+        //   },
+        //   shown: function () {
+        //     return filterable();
+        //   }
+        // },
+        {
+          title: i18nService.getSafeText('sort.ascending'),
+          icon: 'ui-grid-icon-sort-alt-up',
+          action: function($event) {
+            $event.stopPropagation();
+            $scope.sortColumn($event, uiGridConstants.ASC);
+          },
+          shown: function () {
+            return $scope.sortable();
+          },
+          active: function() {
+            return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === uiGridConstants.ASC);
+          }
+        },
+        {
+          title: i18nService.getSafeText('sort.descending'),
+          icon: 'ui-grid-icon-sort-alt-down',
+          action: function($event) {
+            $event.stopPropagation();
+            $scope.sortColumn($event, uiGridConstants.DESC);
+          },
+          shown: function() {
+            return $scope.sortable();
+          },
+          active: function() {
+            return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === uiGridConstants.DESC);
+          }
+        },
+        {
+          title: i18nService.getSafeText('sort.remove'),
+          icon: 'ui-grid-icon-cancel',
+          action: function ($event) {
+            $event.stopPropagation();
+            $scope.unsortColumn();
+          },
+          shown: function() {
+            return ($scope.sortable() && typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' && typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null);
+          }
+        },
+        {
+          title: i18nService.getSafeText('column.hide'),
+          icon: 'ui-grid-icon-cancel',
+          action: function ($event) {
+            $event.stopPropagation();
+            $scope.hideColumn();
+          }
+        }
+      ];
+
+      // Set the menu items for use with the column menu. Let's the user specify extra menu items per column if they want.
+      $scope.menuItems = defaultMenuItems;
+      $scope.$watch('col.menuItems', function (n, o) {
+        if (typeof(n) !== 'undefined' && n && angular.isArray(n)) {
+          n.forEach(function (item) {
+            if (typeof(item.context) === 'undefined' || !item.context) {
+              item.context = {};
+            }
+            item.context.col = $scope.col;
+          });
+
+          $scope.menuItems = defaultMenuItems.concat(n);
+        }
+        else {
+          $scope.menuItems = defaultMenuItems;
+        }
+      });
+
+      var $animate;
+      try {
+        $animate = $injector.get('$animate');
+      }
+      catch (e) {
+        $log.info('$animate service not found (ngAnimate not add as a dependency?), menu animations will not occur');
+      }
+
+      // Show the menu
+      $scope.showMenu = function(column, $columnElement) {
+        // Swap to this column
+        //   note - store a reference to this column in 'self' so the columns can check whether they're the shown column or not
+        self.col = $scope.col = column;
+
+        // Remove an existing document click handler
+        $document.off('click', documentClick);
+
+        /* Reposition the menu below this column's element */
+        var left = $columnElement[0].offsetLeft;
+        var top = $columnElement[0].offsetTop;
+
+        // Get the grid scrollLeft
+        var offset = 0;
+        if (column.grid.options.offsetLeft) {
+          offset = column.grid.options.offsetLeft;
+        }
+
+        var height = gridUtil.elementHeight($columnElement, true);
+        var width = gridUtil.elementWidth($columnElement, true);
+
+        // Flag for whether we're hidden for showing via $animate
+        var hidden = false;
+
+        // Re-position the menu AFTER it's been shown, so we can calculate the width correctly.
+        function reposition() {
+          $timeout(function() {
+            if (hidden && $animate) {
+              $animate.removeClass($scope.inner, 'ng-hide');
+              self.shown = $scope.menuShown = true;
+              $scope.$broadcast('show-menu');
+            }
+            else if (angular.element($scope.inner).hasClass('ng-hide')) {
+              angular.element($scope.inner).removeClass('ng-hide');
+            }
+
+            // var containerScrollLeft = $columnelement
+            var containerId = column.renderContainer ? column.renderContainer : 'body';
+            var renderContainer = column.grid.renderContainers[containerId];
+            // var containerScrolLeft = renderContainer.prevScrollLeft;
+
+            // It's possible that the render container of the column we're attaching to is offset from the grid (i.e. pinned containers), we
+            //   need to get the different in the offsetLeft between the render container and the grid
+            var renderContainerElm = gridUtil.closestElm($columnElement, '.ui-grid-render-container');
+            var renderContainerOffset = renderContainerElm.offsetLeft - $scope.grid.element[0].offsetLeft;
+
+            var containerScrolLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft;
+
+            var myWidth = gridUtil.elementWidth($scope.menu, true);
+
+            // TODO(c0bra): use padding-left/padding-right based on document direction (ltr/rtl), place menu on proper side
+            // Get the column menu right padding
+            var paddingRight = parseInt(angular.element($scope.menu).css('padding-right'), 10);
+
+            // $log.debug('position', left + ' + ' + width + ' - ' + myWidth + ' + ' + paddingRight);
+
+            $elm.css('left', (left + renderContainerOffset - containerScrolLeft + width - myWidth + paddingRight) + 'px');
+            $elm.css('top', (top + height) + 'px');
+
+            // Hide the menu on a click on the document
+            $document.on('click', documentClick);
+          });
+        }
+
+        if ($scope.menuShown && $animate) {
+          // Animate closing the menu on the current column, then animate it opening on the other column
+          $animate.addClass($scope.inner, 'ng-hide', reposition);
+          hidden = true;
+        }
+        else {
+          self.shown = $scope.menuShown = true;
+          $scope.$broadcast('show-menu');
+          reposition();
+        }
+      };
+
+      // Hide the menu
+      $scope.hideMenu = function() {
+        delete self.col;
+        delete $scope.col;
+        self.shown = $scope.menuShown = false;
+        $scope.$broadcast('hide-menu');
+      };
+
+      // Prevent clicks on the menu from bubbling up to the document and making it hide prematurely
+      // $elm.on('click', function (event) {
+      //   event.stopPropagation();
+      // });
+
+      function documentClick() {
+        $scope.$apply($scope.hideMenu);
+        $document.off('click', documentClick);
+      }
+      
+      function resizeHandler() {
+        $scope.$apply($scope.hideMenu);
+      }
+      angular.element($window).bind('resize', resizeHandler);
+
+      $scope.$on('$destroy', $scope.$on(uiGridConstants.events.GRID_SCROLL, function(evt, args) {
+        $scope.hideMenu();
+        // if (!$scope.$$phase) { $scope.$apply(); }
+      }));
+
+      $scope.$on('$destroy', $scope.$on(uiGridConstants.events.ITEM_DRAGGING, function(evt, args) {
+        $scope.hideMenu();
+        // if (!$scope.$$phase) { $scope.$apply(); }
+      }));
+
+      $scope.$on('$destroy', function() {
+        angular.element($window).off('resize', resizeHandler);
+        $document.off('click', documentClick);
+      });
+
+      /* Column methods */
+      $scope.sortColumn = function (event, dir) {
+        event.stopPropagation();
+
+        uiGridCtrl.grid.sortColumn($scope.col, dir, true)
+          .then(function () {
+            uiGridCtrl.grid.refresh();
+            $scope.hideMenu();
+          });
+      };
+
+      $scope.unsortColumn = function () {
+        $scope.col.unsort();
+
+        uiGridCtrl.grid.refresh();
+        $scope.hideMenu();
+      };
+
+      $scope.hideColumn = function () {
+        $scope.col.colDef.visible = false;
+
+        uiGridCtrl.grid.refresh();
+        $scope.hideMenu();
+      };
+    },
+    controller: ['$scope', function ($scope) {
+      var self = this;
+      
+      $scope.$watch('menuItems', function (n, o) {
+        self.menuItems = n;
+      });
+    }]
+  };
+
+  return uiGridColumnMenu;
+
+}]);
+
+})();
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridFooterCell', ['$log', '$timeout', 'gridUtil', '$compile', function ($log, $timeout, gridUtil, $compile) {
+    var uiGridFooterCell = {
+      priority: 0,
+      scope: {
+        col: '=',
+        row: '=',
+        renderIndex: '='
+      },
+      replace: true,
+      require: '^uiGrid',
+      compile: function compile(tElement, tAttrs, transclude) {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            function compileTemplate(template) {
+              gridUtil.getTemplate(template).then(function (contents) {
+                var linkFunction = $compile(contents);
+                var html = linkFunction($scope);
+                $elm.append(html);
+              });
+            }
+
+            //compile the footer template
+            if ($scope.col.footerCellTemplate) {
+              //compile the custom template
+              compileTemplate($scope.col.footerCellTemplate);
+            }
+            else {
+              //use default template
+              compileTemplate('ui-grid/uiGridFooterCell');
+            }
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            //$elm.addClass($scope.col.getColClass(false));
+            $scope.grid = uiGridCtrl.grid;
+
+            $elm.addClass($scope.col.getColClass(false));
+          }
+        };
+      }
+    };
+
+    return uiGridFooterCell;
+  }]);
+
+})();
+
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridFooter', ['$log', '$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($log, $templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
+    var defaultTemplate = 'ui-grid/ui-grid-footer';
+
+    return {
+      restrict: 'EA',
+      replace: true,
+      // priority: 1000,
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: true,
+      compile: function ($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+
+            containerCtrl.footer = $elm;
+
+            var footerTemplate = ($scope.grid.options.footerTemplate) ? $scope.grid.options.footerTemplate : defaultTemplate;
+            gridUtil.getTemplate(footerTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+
+                var newElm = $compile(template)($scope);
+                $elm.append(newElm);
+
+                if (containerCtrl) {
+                  // Inject a reference to the footer viewport (if it exists) into the grid controller for use in the horizontal scroll handler below
+                  var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
+
+                  if (footerViewport) {
+                    containerCtrl.footerViewport = footerViewport;
+                  }
+                }
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $log.debug('ui-grid-footer link');
+
+            var grid = uiGridCtrl.grid;
+
+            // Don't animate footer cells
+            gridUtil.disableAnimations($elm);
+
+            containerCtrl.footer = $elm;
+
+            var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
+            if (footerViewport) {
+              containerCtrl.footerViewport = footerViewport;
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridGroupPanel', ["$compile", "uiGridConstants", "gridUtil", function($compile, uiGridConstants, gridUtil) {
+    var defaultTemplate = 'ui-grid/ui-grid-group-panel';
+
+    return {
+      restrict: 'EA',
+      replace: true,
+      require: '?^uiGrid',
+      scope: false,
+      compile: function($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            var groupPanelTemplate = $scope.grid.options.groupPanelTemplate  || defaultTemplate;
+
+             gridUtil.getTemplate(groupPanelTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+                
+                var newElm = $compile(template)($scope);
+                $elm.append(newElm);
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            $elm.bind('$destroy', function() {
+              // scrollUnbinder();
+            });
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$compile', '$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 
+  function ($log, $compile, $timeout, $window, $document, gridUtil, uiGridConstants) {
+    // Do stuff after mouse has been down this many ms on the header cell
+    var mousedownTimeout = 500;
+
+    var uiGridHeaderCell = {
+      priority: 0,
+      scope: {
+        col: '=',
+        row: '=',
+        renderIndex: '='
+      },
+      require: '?^uiGrid',
+      replace: true,
+      compile: function() {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            var cellHeader = $compile($scope.col.headerCellTemplate)($scope);
+            $elm.append(cellHeader);
+          },
+          
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            $scope.grid = uiGridCtrl.grid;
+            
+            /**
+             * @ngdoc event
+             * @name filterChanged
+             * @eventOf  ui.grid.core.api:PublicApi
+             * @description  is raised after the filter is changed.  The nature
+             * of the watch expression doesn't allow notification of what changed,
+             * so the receiver of this event will need to re-extract the filter 
+             * conditions from the columns.
+             * 
+             */
+            if (!$scope.grid.api.core.raise.filterChanged){
+              $scope.grid.api.registerEvent( 'core', 'filterChanged' );
+            }
+                        
+    
+            $elm.addClass($scope.col.getColClass(false));
+    // shane - No need for watch now that we trackby col name
+    //        $scope.$watch('col.index', function (newValue, oldValue) {
+    //          if (newValue === oldValue) { return; }
+    //          var className = $elm.attr('class');
+    //          className = className.replace(uiGridConstants.COL_CLASS_PREFIX + oldValue, uiGridConstants.COL_CLASS_PREFIX + newValue);
+    //          $elm.attr('class', className);
+    //        });
+    
+            // Hide the menu by default
+            $scope.menuShown = false;
+    
+            // Put asc and desc sort directions in scope
+            $scope.asc = uiGridConstants.ASC;
+            $scope.desc = uiGridConstants.DESC;
+    
+            // Store a reference to menu element
+            var $colMenu = angular.element( $elm[0].querySelectorAll('.ui-grid-header-cell-menu') );
+    
+            var $contentsElm = angular.element( $elm[0].querySelectorAll('.ui-grid-cell-contents') );
+    
+            // Figure out whether this column is sortable or not
+            if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) {
+              $scope.sortable = true;
+            }
+            else {
+              $scope.sortable = false;
+            }
+    
+            if (uiGridCtrl.grid.options.enableFiltering && $scope.col.enableFiltering) {
+              $scope.filterable = true;
+            }
+            else {
+              $scope.filterable = false;
+            }
+    
+            function handleClick(evt) {
+              // If the shift key is being held down, add this column to the sort
+              var add = false;
+              if (evt.shiftKey) {
+                add = true;
+              }
+    
+              // Sort this column then rebuild the grid's rows
+              uiGridCtrl.grid.sortColumn($scope.col, add)
+                .then(function () {
+                  if (uiGridCtrl.columnMenuScope) { uiGridCtrl.columnMenuScope.hideMenu(); }
+                  uiGridCtrl.grid.refresh();
+                });
+            }
+    
+            // Long-click (for mobile)
+            var cancelMousedownTimeout;
+            var mousedownStartTime = 0;
+            $contentsElm.on('mousedown', function(event) {
+              if (typeof(event.originalEvent) !== 'undefined' && event.originalEvent !== undefined) {
+                event = event.originalEvent;
+              }
+    
+              // Don't show the menu if it's not the left button
+              if (event.button && event.button !== 0) {
+                return;
+              }
+    
+              mousedownStartTime = (new Date()).getTime();
+    
+              cancelMousedownTimeout = $timeout(function() { }, mousedownTimeout);
+    
+              cancelMousedownTimeout.then(function () {
+                uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
+              });
+            });
+    
+            $contentsElm.on('mouseup', function () {
+              $timeout.cancel(cancelMousedownTimeout);
+            });
+    
+            $scope.toggleMenu = function($event) {
+              $event.stopPropagation();
+    
+              // If the menu is already showing...
+              if (uiGridCtrl.columnMenuScope.menuShown) {
+                // ... and we're the column the menu is on...
+                if (uiGridCtrl.columnMenuScope.col === $scope.col) {
+                  // ... hide it
+                  uiGridCtrl.columnMenuScope.hideMenu();
+                }
+                // ... and we're NOT the column the menu is on
+                else {
+                  // ... move the menu to our column
+                  uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
+                }
+              }
+              // If the menu is NOT showing
+              else {
+                // ... show it on our column
+                uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
+              }
+            };
+    
+            // If this column is sortable, add a click event handler
+            if ($scope.sortable) {
+              $contentsElm.on('click', function(evt) {
+                evt.stopPropagation();
+    
+                $timeout.cancel(cancelMousedownTimeout);
+    
+                var mousedownEndTime = (new Date()).getTime();
+                var mousedownTime = mousedownEndTime - mousedownStartTime;
+    
+                if (mousedownTime > mousedownTimeout) {
+                  // long click, handled above with mousedown
+                }
+                else {
+                  // short click
+                  handleClick(evt);
+                }
+              });
+    
+              $scope.$on('$destroy', function () {
+                // Cancel any pending long-click timeout
+                $timeout.cancel(cancelMousedownTimeout);
+              });
+            }
+    
+            if ($scope.filterable) {
+              var filterDeregisters = [];
+              angular.forEach($scope.col.filters, function(filter, i) {
+                filterDeregisters.push($scope.$watch('col.filters[' + i + '].term', function(n, o) {
+                  uiGridCtrl.grid.api.core.raise.filterChanged();
+                  uiGridCtrl.grid.refresh()
+                    .then(function () {
+                      if (uiGridCtrl.prevScrollArgs && uiGridCtrl.prevScrollArgs.y && uiGridCtrl.prevScrollArgs.y.percentage) {
+                         uiGridCtrl.fireScrollingEvent({ y: { percentage: uiGridCtrl.prevScrollArgs.y.percentage } });
+                      }
+                      // uiGridCtrl.fireEvent('force-vertical-scroll');
+                    });
+                }));  
+              });
+              $scope.$on('$destroy', function() {
+                angular.forEach(filterDeregisters, function(filterDeregister) {
+                  filterDeregister();
+                });
+              });
+            }
+          }
+        };
+      }
+    };
+
+    return uiGridHeaderCell;
+  }]);
+
+})();
+
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridHeader', ['$log', '$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function($log, $templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
+    var defaultTemplate = 'ui-grid/ui-grid-header';
+    var emptyTemplate = 'ui-grid/ui-grid-no-header';
+
+    return {
+      restrict: 'EA',
+      // templateUrl: 'ui-grid/ui-grid-header',
+      replace: true,
+      // priority: 1000,
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: true,
+      compile: function($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+
+            containerCtrl.header = $elm;
+            containerCtrl.colContainer.header = $elm;
+
+            /**
+             * @ngdoc property
+             * @name hideHeader
+             * @propertyOf ui.grid.class:GridOptions
+             * @description Null by default. When set to true, this setting will replace the
+             * standard header template with '<div></div>', resulting in no header being shown.
+             */
+            
+            var headerTemplate;
+            if ($scope.grid.options.hideHeader){
+              headerTemplate = emptyTemplate;
+            } else {
+              headerTemplate = ($scope.grid.options.headerTemplate) ? $scope.grid.options.headerTemplate : defaultTemplate;            
+            }
+
+             gridUtil.getTemplate(headerTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+                
+                var newElm = $compile(template)($scope);
+                $elm.append(newElm);
+
+                if (containerCtrl) {
+                  // Inject a reference to the header viewport (if it exists) into the grid controller for use in the horizontal scroll handler below
+                  var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
+
+                  if (headerViewport) {
+                    containerCtrl.headerViewport = headerViewport;
+                  }
+                }
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $log.debug('ui-grid-header link');
+
+            var grid = uiGridCtrl.grid;
+
+            // Don't animate header cells
+            gridUtil.disableAnimations($elm);
+
+            function updateColumnWidths() {
+              var asterisksArray = [],
+                  percentArray = [],
+                  manualArray = [],
+                  asteriskNum = 0,
+                  totalWidth = 0;
+
+              // Get the width of the viewport
+              var availableWidth = containerCtrl.colContainer.getViewportWidth();
+
+              if (typeof(uiGridCtrl.grid.verticalScrollbarWidth) !== 'undefined' && uiGridCtrl.grid.verticalScrollbarWidth !== undefined && uiGridCtrl.grid.verticalScrollbarWidth > 0) {
+                availableWidth = availableWidth + uiGridCtrl.grid.verticalScrollbarWidth;
+              }
+
+              // The total number of columns
+              // var equalWidthColumnCount = columnCount = uiGridCtrl.grid.options.columnDefs.length;
+              // var equalWidth = availableWidth / equalWidthColumnCount;
+
+              // The last column we processed
+              var lastColumn;
+
+              var manualWidthSum = 0;
+
+              var canvasWidth = 0;
+
+              var ret = '';
+
+
+              // uiGridCtrl.grid.columns.forEach(function(column, i) {
+
+              var columnCache = containerCtrl.colContainer.visibleColumnCache;
+
+              columnCache.forEach(function(column, i) {
+                // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; left: ' + left + 'px; }';
+                //var colWidth = (typeof(c.width) !== 'undefined' && c.width !== undefined) ? c.width : equalWidth;
+
+                // Skip hidden columns
+                if (!column.visible) { return; }
+
+                var colWidth,
+                    isPercent = false;
+
+                if (!angular.isNumber(column.width)) {
+                  isPercent = isNaN(column.width) ? gridUtil.endsWith(column.width, "%") : false;
+                }
+
+                if (angular.isString(column.width) && column.width.indexOf('*') !== -1) { //  we need to save it until the end to do the calulations on the remaining width.
+                  asteriskNum = parseInt(asteriskNum + column.width.length, 10);
+                  
+                  asterisksArray.push(column);
+                }
+                else if (isPercent) { // If the width is a percentage, save it until the very last.
+                  percentArray.push(column);
+                }
+                else if (angular.isNumber(column.width)) {
+                  manualWidthSum = parseInt(manualWidthSum + column.width, 10);
+                  
+                  canvasWidth = parseInt(canvasWidth, 10) + parseInt(column.width, 10);
+
+                  column.drawnWidth = column.width;
+
+                  // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + column.width + 'px; }';
+                }
+              });
+
+              // Get the remaining width (available width subtracted by the manual widths sum)
+              var remainingWidth = availableWidth - manualWidthSum;
+
+              var i, column, colWidth;
+
+              if (percentArray.length > 0) {
+                // Pre-process to make sure they're all within any min/max values
+                for (i = 0; i < percentArray.length; i++) {
+                  column = percentArray[i];
+
+                  var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+
+                  colWidth = parseInt(percent * remainingWidth, 10);
+
+                  if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+                    colWidth = column.colDef.minWidth;
+
+                    remainingWidth = remainingWidth - colWidth;
+
+                    canvasWidth += colWidth;
+                    column.drawnWidth = colWidth;
+
+                    // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+                    // Remove this element from the percent array so it's not processed below
+                    percentArray.splice(i, 1);
+                  }
+                  else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+                    colWidth = column.colDef.maxWidth;
+
+                    remainingWidth = remainingWidth - colWidth;
+
+                    canvasWidth += colWidth;
+                    column.drawnWidth = colWidth;
+
+                    // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+                    // Remove this element from the percent array so it's not processed below
+                    percentArray.splice(i, 1);
+                  }
+                }
+
+                percentArray.forEach(function(column) {
+                  var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+                  var colWidth = parseInt(percent * remainingWidth, 10);
+
+                  canvasWidth += colWidth;
+
+                  column.drawnWidth = colWidth;
+
+                  // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+                });
+              }
+
+              if (asterisksArray.length > 0) {
+                var asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+                 // Pre-process to make sure they're all within any min/max values
+                for (i = 0; i < asterisksArray.length; i++) {
+                  column = asterisksArray[i];
+
+                  colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+                  if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+                    colWidth = column.colDef.minWidth;
+
+                    remainingWidth = remainingWidth - colWidth;
+                    asteriskNum--;
+
+                    canvasWidth += colWidth;
+                    column.drawnWidth = colWidth;
+
+                    // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+                    lastColumn = column;
+
+                    // Remove this element from the percent array so it's not processed below
+                    asterisksArray.splice(i, 1);
+                  }
+                  else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+                    colWidth = column.colDef.maxWidth;
+
+                    remainingWidth = remainingWidth - colWidth;
+                    asteriskNum--;
+
+                    canvasWidth += colWidth;
+                    column.drawnWidth = colWidth;
+
+                    // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+                    // Remove this element from the percent array so it's not processed below
+                    asterisksArray.splice(i, 1);
+                  }
+                }
+
+                // Redo the asterisk value, as we may have removed columns due to width constraints
+                asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+                asterisksArray.forEach(function(column) {
+                  var colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+                  canvasWidth += colWidth;
+
+                  column.drawnWidth = colWidth;
+
+                  // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+                });
+              }
+
+              // If the grid width didn't divide evenly into the column widths and we have pixels left over, dole them out to the columns one by one to make everything fit
+              var leftoverWidth = availableWidth - parseInt(canvasWidth, 10);
+
+              if (leftoverWidth > 0 && canvasWidth > 0 && canvasWidth < availableWidth) {
+                var variableColumn = false;
+                // uiGridCtrl.grid.columns.forEach(function(col) {
+                columnCache.forEach(function(col) {
+                  if (col.width && !angular.isNumber(col.width)) {
+                    variableColumn = true;
+                  }
+                });
+
+                if (variableColumn) {
+                  var remFn = function (column) {
+                    if (leftoverWidth > 0) {
+                      column.drawnWidth = column.drawnWidth + 1;
+                      canvasWidth = canvasWidth + 1;
+                      leftoverWidth--;
+                    }
+                  };
+                  while (leftoverWidth > 0) {
+                    columnCache.forEach(remFn);
+                  }
+                }
+              }
+
+              if (canvasWidth < availableWidth) {
+                canvasWidth = availableWidth;
+              }
+
+              // Build the CSS
+              // uiGridCtrl.grid.columns.forEach(function (column) {
+              columnCache.forEach(function (column) {
+                ret = ret + column.getColClassDefinition();
+              });
+
+              // Add the vertical scrollbar width back in to the canvas width, it's taken out in getCanvasWidth
+              if (grid.verticalScrollbarWidth) {
+                canvasWidth = canvasWidth + grid.verticalScrollbarWidth;
+              }
+              // canvasWidth = canvasWidth + 1;
+
+              containerCtrl.colContainer.canvasWidth = parseInt(canvasWidth, 10);
+
+              // Return the styles back to buildStyles which pops them into the `customStyles` scope variable
+              return ret;
+            }
+            
+            containerCtrl.header = $elm;
+            
+            var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
+            if (headerViewport) {
+              containerCtrl.headerViewport = headerViewport;
+            }
+
+            //todo: remove this if by injecting gridCtrl into unit tests
+            if (uiGridCtrl) {
+              uiGridCtrl.grid.registerStyleComputation({
+                priority: 5,
+                func: updateColumnWidths
+              });
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+
+/**
+ * @ngdoc directive
+ * @name ui.grid.directive:uiGridColumnMenu
+ * @element style
+ * @restrict A
+ *
+ * @description
+ * Allows us to interpolate expressions in `<style>` elements. Angular doesn't do this by default as it can/will/might? break in IE8.
+ *
+ * @example
+ <doc:example module="app">
+ <doc:source>
+ <script>
+ var app = angular.module('app', ['ui.grid']);
+
+ app.controller('MainCtrl', ['$scope', function ($scope) {
+   
+ }]);
+ </script>
+
+ <div ng-controller="MainCtrl">
+   <div ui-grid-menu shown="true"  ></div>
+ </div>
+ </doc:source>
+ <doc:scenario>
+ </doc:scenario>
+ </doc:example>
+ */
+angular.module('ui.grid')
+
+.directive('uiGridMenu', ['$log', '$compile', '$timeout', '$window', '$document', 'gridUtil', function ($log, $compile, $timeout, $window, $document, gridUtil) {
+  var uiGridMenu = {
+    priority: 0,
+    scope: {
+      // shown: '&',
+      menuItems: '=',
+      autoHide: '=?'
+    },
+    require: '?^uiGrid',
+    templateUrl: 'ui-grid/uiGridMenu',
+    replace: false,
+    link: function ($scope, $elm, $attrs, uiGridCtrl) {
+      gridUtil.enableAnimations($elm);
+
+      if (typeof($scope.autoHide) === 'undefined' || $scope.autoHide === undefined) {
+        $scope.autoHide = true;
+      }
+
+      if ($scope.autoHide) {
+        angular.element($window).on('resize', $scope.hideMenu);
+      }
+
+      $scope.$on('hide-menu', function () {
+        $scope.shown = false;
+      });
+
+      $scope.$on('show-menu', function () {
+        $scope.shown = true;
+      });
+
+      $scope.$on('$destroy', function() {
+        angular.element($window).off('resize', $scope.hideMenu);
+      });
+    },
+    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
+      var self = this;
+
+      self.hideMenu = $scope.hideMenu = function() {
+        $scope.shown = false;
+      };
+
+      function documentClick() {
+        $scope.$apply(function () {
+          self.hideMenu();
+          angular.element(document).off('click', documentClick);
+        });
+      }
+
+      self.showMenu = $scope.showMenu = function() {
+        $scope.shown = true;
+
+        // Turn off an existing dpcument click handler
+        angular.element(document).off('click', documentClick);
+
+        // Turn on the document click handler, but in a timeout so it doesn't apply to THIS click if there is one
+        $timeout(function() {
+          angular.element(document).on('click', documentClick);
+        });
+      };
+
+      $scope.$on('$destroy', function () {
+        angular.element(document).off('click', documentClick);
+      });
+    }]
+  };
+
+  return uiGridMenu;
+}])
+
+.directive('uiGridMenuItem', ['$log', 'gridUtil', '$compile', 'i18nService', function ($log, gridUtil, $compile, i18nService) {
+  var uiGridMenuItem = {
+    priority: 0,
+    scope: {
+      title: '=',
+      active: '=',
+      action: '=',
+      icon: '=',
+      shown: '=',
+      context: '=',
+      templateUrl: '='
+    },
+    require: ['?^uiGrid', '^uiGridMenu'],
+    templateUrl: 'ui-grid/uiGridMenuItem',
+    replace: true,
+    compile: function($elm, $attrs) {
+      return {
+        pre: function ($scope, $elm, $attrs, controllers) {
+          var uiGridCtrl = controllers[0],
+              uiGridMenuCtrl = controllers[1];
+          
+          if ($scope.templateUrl) {
+            gridUtil.getTemplate($scope.templateUrl)
+                .then(function (contents) {
+                  var template = angular.element(contents);
+                    
+                  var newElm = $compile(template)($scope);
+                  $elm.replaceWith(newElm);
+                });
+          }
+        },
+        post: function ($scope, $elm, $attrs, controllers) {
+          var uiGridCtrl = controllers[0],
+              uiGridMenuCtrl = controllers[1];
+
+          // TODO(c0bra): validate that shown and active are functions if they're defined. An exception is already thrown above this though
+          // if (typeof($scope.shown) !== 'undefined' && $scope.shown && typeof($scope.shown) !== 'function') {
+          //   throw new TypeError("$scope.shown is defined but not a function");
+          // }
+          if (typeof($scope.shown) === 'undefined' || $scope.shown === null) {
+            $scope.shown = function() { return true; };
+          }
+
+          $scope.itemShown = function () {
+            var context = {};
+            if ($scope.context) {
+              context.context = $scope.context;
+            }
+
+            if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
+              context.grid = uiGridCtrl.grid;
+            }
+
+            return $scope.shown.call(context);
+          };
+
+          $scope.itemAction = function($event,title) {
+            $log.debug('itemAction');
+            $event.stopPropagation();
+
+            if (typeof($scope.action) === 'function') {
+              var context = {};
+
+              if ($scope.context) {
+                context.context = $scope.context;
+              }
+
+              // Add the grid to the function call context if the uiGrid controller is present
+              if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
+                context.grid = uiGridCtrl.grid;
+              }
+
+              $scope.action.call(context, $event, title);
+
+              uiGridMenuCtrl.hideMenu();
+            }
+          };
+
+          $scope.i18n = i18nService.get();
+        }
+      };
+    }
+  };
+
+  return uiGridMenuItem;
+}]);
+
+})();
+(function () {
+// 'use strict';
+
+  angular.module('ui.grid').directive('uiGridNativeScrollbar', ['$log', '$timeout', '$document', 'uiGridConstants', 'gridUtil',
+    function ($log, $timeout, $document, uiGridConstants, gridUtil) {
+    var scrollBarWidth = gridUtil.getScrollbarWidth();
+    scrollBarWidth = scrollBarWidth > 0 ? scrollBarWidth : 17;
+
+    // If the browser is IE, add 1px to the scrollbar container, otherwise scroll events won't work right (in IE11 at least)
+    var browser = gridUtil.detectBrowser();
+    if (browser === 'ie') {
+      scrollBarWidth = scrollBarWidth + 1;
+    }
+
+    return {
+      scope: {
+        type: '@'
+      },
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      link: function ($scope, $elm, $attrs, controllers) {
+        var uiGridCtrl = controllers[0];
+        var containerCtrl = controllers[1];
+        var rowContainer = containerCtrl.rowContainer;
+        var colContainer = containerCtrl.colContainer;
+        var grid = uiGridCtrl.grid;
+
+        var contents = angular.element('<div class="contents">&nbsp;</div>');
+
+        $elm.addClass('ui-grid-native-scrollbar');
+
+        var previousScrollPosition;
+
+        var elmMaxScroll = 0;
+
+        if ($scope.type === 'vertical') {
+          // Update the width based on native scrollbar width
+          $elm.css('width', scrollBarWidth + 'px');
+
+          $elm.addClass('vertical');
+
+          grid.verticalScrollbarWidth = scrollBarWidth;
+          colContainer.verticalScrollbarWidth = scrollBarWidth;
+
+          // Save the initial scroll position for use in scroll events
+          previousScrollPosition = $elm[0].scrollTop;
+        }
+        else if ($scope.type === 'horizontal') {
+          // Update the height based on native scrollbar height
+          $elm.css('height', scrollBarWidth + 'px');
+
+          $elm.addClass('horizontal');
+
+          // Save this scrollbar's dimension in the grid properties
+          grid.horizontalScrollbarHeight = scrollBarWidth;
+          rowContainer.horizontalScrollbarHeight = scrollBarWidth;
+
+          // Save the initial scroll position for use in scroll events
+          previousScrollPosition = gridUtil.normalizeScrollLeft($elm);
+        }
+
+        // Save the contents elm inside the scrollbar elm so it sizes correctly
+        $elm.append(contents);
+
+        // Get the relevant element dimension now that the contents are in it
+        if ($scope.type === 'vertical') {
+          elmMaxScroll = gridUtil.elementHeight($elm);
+        }
+        else if ($scope.type === 'horizontal') {
+          elmMaxScroll = gridUtil.elementWidth($elm);
+        }
+
+        function updateNativeVerticalScrollbar() {
+          // Get the height that the scrollbar should have
+          var height = rowContainer.getViewportHeight();
+
+          // Update the vertical scrollbar's content height so it's the same as the canvas
+          var contentHeight = rowContainer.getCanvasHeight();
+
+          // TODO(c0bra): set scrollbar `top` by height of header row
+          // var headerHeight = gridUtil.outerElementHeight(containerCtrl.header);
+          var headerHeight = colContainer.headerHeight ? colContainer.headerHeight : grid.headerHeight;
+
+          // $log.debug('headerHeight in scrollbar', headerHeight);
+
+          // var ret = '.grid' + uiGridCtrl.grid.id + ' .ui-grid-native-scrollbar.vertical .contents { height: ' + h + 'px; }';
+          var ret = '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.vertical .contents { height: ' + contentHeight + 'px; }';
+          ret += '\n .grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.vertical { height: ' + height + 'px; top: ' + headerHeight + 'px}';
+
+          elmMaxScroll = contentHeight;
+
+          return ret;
+        }
+
+        // Get the grid's bottom border height (TODO(c0bra): need to account for footer here!)
+        var gridElm = gridUtil.closestElm($elm, '.ui-grid');
+        var gridBottomBorder = gridUtil.getBorderSize(gridElm, 'bottom');
+
+        function updateNativeHorizontalScrollbar() {
+          var w = colContainer.getCanvasWidth();
+
+          // Scrollbar needs to be negatively positioned beyond the bottom of the relatively-positioned render container
+          var bottom = (scrollBarWidth * -1) + gridBottomBorder;
+          if (grid.options.showFooter) {
+            bottom -= 1;
+          }
+          var ret = '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.horizontal { bottom: ' + bottom + 'px; }';
+          ret += '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.horizontal .contents { width: ' + w + 'px; }';
+
+          elmMaxScroll = w;
+
+          return ret;
+        }
+
+        // NOTE: priority 6 so they run after the column widths update, which in turn update the canvas width
+        if ($scope.type === 'vertical') {
+          grid.registerStyleComputation({
+            priority: 6,
+            func: updateNativeVerticalScrollbar
+          });
+        }
+        else if ($scope.type === 'horizontal') {
+          grid.registerStyleComputation({
+            priority: 6,
+            func: updateNativeHorizontalScrollbar
+          });
+        }
+
+
+        $scope.scrollSource = null;
+
+        function scrollEvent(evt) {
+          if ($scope.type === 'vertical') {
+            grid.flagScrollingVertically();
+            var newScrollTop = $elm[0].scrollTop;
+
+            var yDiff = previousScrollPosition - newScrollTop;
+
+            var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+            // Subtract the h. scrollbar height from the vertical length if it's present
+            if (grid.horizontalScrollbarHeight && grid.horizontalScrollbarHeight > 0) {
+              vertScrollLength = vertScrollLength - uiGridCtrl.grid.horizontalScrollbarHeight;
+            }
+
+            var vertScrollPercentage = newScrollTop / vertScrollLength;
+
+            if (vertScrollPercentage > 1) {
+              vertScrollPercentage = 1;
+            }
+            if (vertScrollPercentage < 0) {
+              vertScrollPercentage = 0;
+            }
+
+            var yArgs = {
+              target: $elm,
+              y: {
+                percentage: vertScrollPercentage
+              }
+            };
+
+            // If the source of this scroll is defined (i.e., not us, then don't fire the scroll event because we'll be re-triggering)
+            if (!$scope.scrollSource) {
+              uiGridCtrl.fireScrollingEvent(yArgs);
+            }
+            else {
+              // Reset the scroll source for the next scroll event
+              $scope.scrollSource = null;
+            }
+
+            previousScrollPosition = newScrollTop;
+          }
+          else if ($scope.type === 'horizontal') {
+            grid.flagScrollingHorizontally();
+            // var newScrollLeft = $elm[0].scrollLeft;
+            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);
+
+            var xDiff = previousScrollPosition - newScrollLeft;
+
+            var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+            var horizScrollPercentage = newScrollLeft / horizScrollLength;
+
+            var xArgs = {
+              target: $elm,
+              x: {
+                percentage: horizScrollPercentage
+              }
+            };
+
+            // If the source of this scroll is defined (i.e., not us, then don't fire the scroll event because we'll be re-triggering)
+            if (!$scope.scrollSource) {
+              uiGridCtrl.fireScrollingEvent(xArgs);
+            }
+            else {
+              // Reset the scroll source for the next scroll event
+              $scope.scrollSource = null;
+            }
+
+            previousScrollPosition = newScrollLeft;
+          }
+        }
+
+        $elm.on('scroll', scrollEvent);
+
+        $elm.on('$destroy', function () {
+          $elm.off('scroll');
+        });
+
+        function gridScroll(evt, args) {
+          // Don't listen to our own scroll event!
+          if (args.target && (args.target === $elm || angular.element(args.target).hasClass('ui-grid-native-scrollbar'))) {
+            return;
+          }
+
+          // Set the source of the scroll event in our scope so it's available in our 'scroll' event handler
+          $scope.scrollSource = args.target;
+
+          if ($scope.type === 'vertical') {
+            if (args.y && typeof(args.y.percentage) !== 'undefined' && args.y.percentage !== undefined) {
+              grid.flagScrollingVertically();
+              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+              var newScrollTop = Math.max(0, args.y.percentage * vertScrollLength);
+
+              $elm[0].scrollTop = newScrollTop;
+
+
+            }
+          }
+          else if ($scope.type === 'horizontal') {
+            if (args.x && typeof(args.x.percentage) !== 'undefined' && args.x.percentage !== undefined) {
+              grid.flagScrollingHorizontally();
+              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+              var newScrollLeft = Math.max(0, args.x.percentage * horizScrollLength);
+
+              // $elm[0].scrollLeft = newScrollLeft;
+              $elm[0].scrollLeft = gridUtil.denormalizeScrollLeft($elm, newScrollLeft);
+            }
+          }
+        }
+
+        var gridScrollDereg = $scope.$on(uiGridConstants.events.GRID_SCROLL, gridScroll);
+        $scope.$on('$destroy', gridScrollDereg);
+
+
+
+      }
+    };
+  }]);
+})();
+(function () {
+  'use strict';
+
+  var module = angular.module('ui.grid');
+  
+  module.directive('uiGridRenderContainer', ['$log', '$timeout', '$document', 'uiGridConstants', 'gridUtil',
+    function($log, $timeout, $document, uiGridConstants, GridUtil) {
+    return {
+      replace: true,
+      transclude: true,
+      templateUrl: 'ui-grid/uiGridRenderContainer',
+      require: ['^uiGrid', 'uiGridRenderContainer'],
+      scope: {
+        containerId: '=',
+        rowContainerName: '=',
+        colContainerName: '=',
+        bindScrollHorizontal: '=',
+        bindScrollVertical: '=',
+        enableScrollbars: '='
+      },
+      controller: 'uiGridRenderContainer as RenderContainer',
+      compile: function () {
+        return {
+          pre: function prelink($scope, $elm, $attrs, controllers) {
+            $log.debug('render container ' + $scope.containerId + ' pre-link');
+
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = $scope.grid = uiGridCtrl.grid;
+
+            // Verify that the render container for this element exists
+            if (!$scope.rowContainerName) {
+              throw "No row render container name specified";
+            }
+            if (!$scope.colContainerName) {
+              throw "No column render container name specified";
+            }
+
+            if (!grid.renderContainers[$scope.rowContainerName]) {
+              throw "Row render container '" + $scope.rowContainerName + "' is not registered.";
+            }
+            if (!grid.renderContainers[$scope.colContainerName]) {
+              throw "Column render container '" + $scope.colContainerName + "' is not registered.";
+            }
+
+            var rowContainer = $scope.rowContainer = grid.renderContainers[$scope.rowContainerName];
+            var colContainer = $scope.colContainer = grid.renderContainers[$scope.colContainerName];
+            
+            containerCtrl.containerId = $scope.containerId;
+            containerCtrl.rowContainer = rowContainer;
+            containerCtrl.colContainer = colContainer;
+          },
+          post: function postlink($scope, $elm, $attrs, controllers) {
+            $log.debug('render container ' + $scope.containerId + ' post-link');
+
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = uiGridCtrl.grid;
+            var rowContainer = containerCtrl.rowContainer;
+            var colContainer = containerCtrl.colContainer;
+
+            // Put the container name on this element as a class
+            $elm.addClass('ui-grid-render-container-' + $scope.containerId);
+
+            // Bind to left/right-scroll events
+            var scrollUnbinder;
+            if ($scope.bindScrollHorizontal || $scope.bindScrollVertical) {
+              scrollUnbinder = $scope.$on(uiGridConstants.events.GRID_SCROLL, scrollHandler);
+            }
+
+            function scrollHandler (evt, args) {
+              // Vertical scroll
+              if (args.y && $scope.bindScrollVertical) {
+                containerCtrl.prevScrollArgs = args;
+
+                var scrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                // Add the height of the native horizontal scrollbar, if it's there. Otherwise it will mask over the final row
+                if (grid.horizontalScrollbarHeight && grid.horizontalScrollbarHeight > 0) {
+                  scrollLength = scrollLength + grid.horizontalScrollbarHeight;
+                }
+
+                var oldScrollTop = containerCtrl.viewport[0].scrollTop;
+                
+                var scrollYPercentage;
+                if (typeof(args.y.percentage) !== 'undefined' && args.y.percentage !== undefined) {
+                  scrollYPercentage = args.y.percentage;
+                }
+                else if (typeof(args.y.pixels) !== 'undefined' && args.y.pixels !== undefined) {
+                  scrollYPercentage = args.y.percentage = (oldScrollTop + args.y.pixels) / scrollLength;
+                  // $log.debug('y.percentage', args.y.percentage);
+                }
+                else {
+                  throw new Error("No percentage or pixel value provided for scroll event Y axis");
+                }
+
+                var newScrollTop = Math.max(0, scrollYPercentage * scrollLength);
+
+                containerCtrl.viewport[0].scrollTop = newScrollTop;
+                
+                // TOOD(c0bra): what's this for?
+                // grid.options.offsetTop = newScrollTop;
+
+                containerCtrl.prevScrollArgs.y.pixels = newScrollTop - oldScrollTop;
+              }
+
+              // Horizontal scroll
+              if (args.x && $scope.bindScrollHorizontal) {
+                containerCtrl.prevScrollArgs = args;
+
+                var scrollWidth = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                // var oldScrollLeft = containerCtrl.viewport[0].scrollLeft;
+                var oldScrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);
+
+                var scrollXPercentage;
+                if (typeof(args.x.percentage) !== 'undefined' && args.x.percentage !== undefined) {
+                  scrollXPercentage = args.x.percentage;
+                }
+                else if (typeof(args.x.pixels) !== 'undefined' && args.x.pixels !== undefined) {
+                  scrollXPercentage = args.x.percentage = (oldScrollLeft + args.x.pixels) / scrollWidth;
+                }
+                else {
+                  throw new Error("No percentage or pixel value provided for scroll event X axis");
+                }
+
+                var newScrollLeft = Math.max(0, scrollXPercentage * scrollWidth);
+                
+                // uiGridCtrl.adjustScrollHorizontal(newScrollLeft, scrollXPercentage);
+
+                // containerCtrl.viewport[0].scrollLeft = newScrollLeft;
+                containerCtrl.viewport[0].scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.viewport, newScrollLeft);
+
+                containerCtrl.prevScrollLeft = newScrollLeft;
+
+                if (containerCtrl.headerViewport) {
+                  // containerCtrl.headerViewport.scrollLeft = newScrollLeft;
+                  containerCtrl.headerViewport.scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.headerViewport, newScrollLeft);
+                }
+
+                if (containerCtrl.footerViewport) {
+                  // containerCtrl.footerViewport.scrollLeft = newScrollLeft;
+                  containerCtrl.footerViewport.scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.footerViewport, newScrollLeft);
+                }
+
+                // uiGridCtrl.grid.options.offsetLeft = newScrollLeft;
+
+                containerCtrl.prevScrollArgs.x.pixels = newScrollLeft - oldScrollLeft;
+              }
+            }
+
+            // Scroll the render container viewport when the mousewheel is used
+            $elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
+              // use wheelDeltaY
+              evt.preventDefault();
+
+              var newEvent = GridUtil.normalizeWheelEvent(evt);
+
+              var args = { target: $elm };
+              if (newEvent.deltaY !== 0) {
+                var scrollYAmount = newEvent.deltaY * -120;
+
+                // Get the scroll percentage
+                var scrollYPercentage = (containerCtrl.viewport[0].scrollTop + scrollYAmount) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                // Keep scrollPercentage within the range 0-1.
+                if (scrollYPercentage < 0) { scrollYPercentage = 0; }
+                else if (scrollYPercentage > 1) { scrollYPercentage = 1; }
+
+                args.y = { percentage: scrollYPercentage, pixels: scrollYAmount };
+              }
+              if (newEvent.deltaX !== 0) {
+                var scrollXAmount = newEvent.deltaX * -120;
+
+                // Get the scroll percentage
+                var scrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);
+                var scrollXPercentage = (scrollLeft + scrollXAmount) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                // Keep scrollPercentage within the range 0-1.
+                if (scrollXPercentage < 0) { scrollXPercentage = 0; }
+                else if (scrollXPercentage > 1) { scrollXPercentage = 1; }
+
+                args.x = { percentage: scrollXPercentage, pixels: scrollXAmount };
+              }
+              
+              uiGridCtrl.fireScrollingEvent(args);
+            });
+            
+
+            var startY = 0,
+            startX = 0,
+            scrollTopStart = 0,
+            scrollLeftStart = 0,
+            directionY = 1,
+            directionX = 1,
+            moveStart;
+
+            function touchmove(event) {
+              if (event.originalEvent) {
+                event = event.originalEvent;
+              }
+
+              event.preventDefault();
+
+              var deltaX, deltaY, newX, newY;
+              newX = event.targetTouches[0].screenX;
+              newY = event.targetTouches[0].screenY;
+              deltaX = -(newX - startX);
+              deltaY = -(newY - startY);
+
+              directionY = (deltaY < 1) ? -1 : 1;
+              directionX = (deltaX < 1) ? -1 : 1;
+
+              deltaY *= 2;
+              deltaX *= 2;
+
+              var args = { target: event.target };
+
+              if (deltaY !== 0) {
+                var scrollYPercentage = (scrollTopStart + deltaY) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                if (scrollYPercentage > 1) { scrollYPercentage = 1; }
+                else if (scrollYPercentage < 0) { scrollYPercentage = 0; }
+
+                args.y = { percentage: scrollYPercentage, pixels: deltaY };
+              }
+              if (deltaX !== 0) {
+                var scrollXPercentage = (scrollLeftStart + deltaX) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                if (scrollXPercentage > 1) { scrollXPercentage = 1; }
+                else if (scrollXPercentage < 0) { scrollXPercentage = 0; }
+
+                args.x = { percentage: scrollXPercentage, pixels: deltaX };
+              }
+
+              uiGridCtrl.fireScrollingEvent(args);
+            }
+            
+            function touchend(event) {
+              if (event.originalEvent) {
+                event = event.originalEvent;
+              }
+
+              event.preventDefault();
+
+              $document.unbind('touchmove', touchmove);
+              $document.unbind('touchend', touchend);
+              $document.unbind('touchcancel', touchend);
+
+              // Get the distance we moved on the Y axis
+              var scrollTopEnd = containerCtrl.viewport[0].scrollTop;
+              var scrollLeftEnd = containerCtrl.viewport[0].scrollTop;
+              var deltaY = Math.abs(scrollTopEnd - scrollTopStart);
+              var deltaX = Math.abs(scrollLeftEnd - scrollLeftStart);
+
+              // Get the duration it took to move this far
+              var moveDuration = (new Date()) - moveStart;
+
+              // Scale the amount moved by the time it took to move it (i.e. quicker, longer moves == more scrolling after the move is over)
+              var moveYScale = deltaY / moveDuration;
+              var moveXScale = deltaX / moveDuration;
+
+              var decelerateInterval = 63; // 1/16th second
+              var decelerateCount = 8; // == 1/2 second
+              var scrollYLength = 120 * directionY * moveYScale;
+              var scrollXLength = 120 * directionX * moveXScale;
+
+              function decelerate() {
+                $timeout(function() {
+                  var args = { target: event.target };
+
+                  if (scrollYLength !== 0) {
+                    var scrollYPercentage = (containerCtrl.viewport[0].scrollTop + scrollYLength) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                    args.y = { percentage: scrollYPercentage, pixels: scrollYLength };
+                  }
+
+                  if (scrollXLength !== 0) {
+                    var scrollXPercentage = (containerCtrl.viewport[0].scrollLeft + scrollXLength) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+                    args.x = { percentage: scrollXPercentage, pixels: scrollXLength };
+                  }
+
+                  uiGridCtrl.fireScrollingEvent(args);
+
+                  decelerateCount = decelerateCount -1;
+                  scrollYLength = scrollYLength / 2;
+                  scrollXLength = scrollXLength / 2;
+
+                  if (decelerateCount > 0) {
+                    decelerate();
+                  }
+                  else {
+                    uiGridCtrl.scrollbars.forEach(function (sbar) {
+                      sbar.removeClass('ui-grid-scrollbar-visible');
+                      sbar.removeClass('ui-grid-scrolling');
+                    });
+                  }
+                }, decelerateInterval);
+              }
+
+              // decelerate();
+            }
+
+            if (GridUtil.isTouchEnabled()) {
+              $elm.bind('touchstart', function (event) {
+                if (event.originalEvent) {
+                  event = event.originalEvent;
+                }
+
+                event.preventDefault();
+
+                uiGridCtrl.scrollbars.forEach(function (sbar) {
+                  sbar.addClass('ui-grid-scrollbar-visible');
+                  sbar.addClass('ui-grid-scrolling');
+                });
+
+                moveStart = new Date();
+                startY = event.targetTouches[0].screenY;
+                startX = event.targetTouches[0].screenX;
+                scrollTopStart = containerCtrl.viewport[0].scrollTop;
+                scrollLeftStart = containerCtrl.viewport[0].scrollLeft;
+                
+                $document.on('touchmove', touchmove);
+                $document.on('touchend touchcancel', touchend);
+              });
+            }
+
+            $elm.bind('$destroy', function() {
+              scrollUnbinder();
+              $elm.unbind('keydown');
+
+              ['touchstart', 'touchmove', 'touchend','keydown', 'wheel', 'mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'].forEach(function (eventName) {
+                $elm.unbind(eventName);
+              });
+            });
+            
+            // TODO(c0bra): Handle resizing the inner canvas based on the number of elements
+            function update() {
+              var ret = '';
+
+              var canvasWidth = colContainer.getCanvasWidth();
+              var viewportWidth = colContainer.getViewportWidth();
+
+              var canvasHeight = rowContainer.getCanvasHeight();
+              var viewportHeight = rowContainer.getViewportHeight();
+
+              var headerViewportWidth = colContainer.getHeaderViewportWidth();
+              var footerViewportWidth = colContainer.getHeaderViewportWidth();
+              
+              // Set canvas dimensions
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-canvas { width: ' + canvasWidth + 'px; height: ' + canvasHeight + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-canvas { width: ' + canvasWidth + 'px; }';
+              
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-viewport { width: ' + viewportWidth + 'px; height: ' + viewportHeight + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-viewport { width: ' + headerViewportWidth + 'px; }';
+
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-footer-canvas { width: ' + canvasWidth + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-footer-viewport { width: ' + footerViewportWidth + 'px; }';
+              // Update
+
+              return ret;
+            }
+            
+            uiGridCtrl.grid.registerStyleComputation({
+              priority: 6,
+              func: update
+            });
+          }
+        };
+      }
+    };
+
+  }]);
+
+  module.controller('uiGridRenderContainer', ['$scope', '$log', function ($scope, $log) {
+    var self = this;
+
+    self.rowStyle = function (index) {
+      var renderContainer = $scope.grid.renderContainers[$scope.containerId];
+
+      var styles = {};
+      
+      if (!renderContainer.disableRowOffset) {
+        if (index === 0 && self.currentTopRow !== 0) {
+          // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered
+          var hiddenRowWidth = ($scope.rowContainer.currentTopRow) *
+            $scope.rowContainer.visibleRowCache[$scope.rowContainer.currentTopRow].height;
+
+          // return { 'margin-top': hiddenRowWidth + 'px' };
+          styles['margin-top'] = hiddenRowWidth + 'px';
+        }
+      }
+      
+      if (!renderContainer.disableColumnOffset && $scope.colContainer.currentFirstColumn !== 0) {
+        if ($scope.grid.isRTL()) {
+          styles['margin-right'] = $scope.colContainer.columnOffset + 'px';
+        }
+        else {
+          styles['margin-left'] = $scope.colContainer.columnOffset + 'px';
+        }
+      }
+
+      return styles;
+    };
+
+    self.columnStyle = function (index) {
+      var renderContainer = $scope.grid.renderContainers[$scope.containerId];
+
+      var self = this;
+
+      if (!renderContainer.disableColumnOffset) {
+        if (index === 0 && $scope.colContainer.currentFirstColumn !== 0) {
+          var offset = $scope.colContainer.columnOffset;
+
+          if ($scope.grid.isRTL()) {
+            return { 'margin-right': offset + 'px' };
+          }
+          else {
+            return { 'margin-left': offset + 'px' }; 
+          }
+        }
+      }
+
+      return null;
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridRow', ['$log', function($log) {
+    return {
+      replace: true,
+      // priority: 2001,
+      // templateUrl: 'ui-grid/ui-grid-row',
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: {
+         row: '=uiGridRow',
+         //rowRenderIndex is added to scope to give the true visual index of the row to any directives that need it
+         rowRenderIndex: '='
+      },
+      compile: function() {
+        return {
+          pre: function($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = uiGridCtrl.grid;
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+
+            grid.getRowTemplateFn.then(function (templateFn) {
+              templateFn($scope, function(clonedElement, scope) {
+                $elm.replaceWith(clonedElement);
+              });
+            });
+          },
+          post: function($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            //add optional reference to externalScopes function to scope
+            //so it can be retrieved in lower elements
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+// 'use strict';
+
+  /**
+   * @ngdoc directive
+   * @name ui.grid.directive:uiGridStyle
+   * @element style
+   * @restrict A
+   *
+   * @description
+   * Allows us to interpolate expressions in `<style>` elements. Angular doesn't do this by default as it can/will/might? break in IE8.
+   *
+   * @example
+   <doc:example module="app">
+   <doc:source>
+   <script>
+   var app = angular.module('app', ['ui.grid']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.myStyle = '.blah { border: 1px solid }';
+        }]);
+   </script>
+
+   <div ng-controller="MainCtrl">
+   <style ui-grid-style>{{ myStyle }}</style>
+   <span class="blah">I am in a box.</span>
+   </div>
+   </doc:source>
+   <doc:scenario>
+   it('should apply the right class to the element', function () {
+        element(by.css('.blah')).getCssValue('border')
+          .then(function(c) {
+            expect(c).toContain('1px solid');
+          });
+      });
+   </doc:scenario>
+   </doc:example>
+   */
+
+
+  angular.module('ui.grid').directive('uiGridStyle', ['$log', '$interpolate', function($log, $interpolate) {
+    return {
+      // restrict: 'A',
+      // priority: 1000,
+      // require: '?^uiGrid',
+      link: function($scope, $elm, $attrs, uiGridCtrl) {
+        $log.debug('ui-grid-style link');
+        // if (uiGridCtrl === undefined) {
+        //    $log.warn('[ui-grid-style link] uiGridCtrl is undefined!');
+        // }
+
+        var interpolateFn = $interpolate($elm.text(), true);
+
+        if (interpolateFn) {
+          $scope.$watch(interpolateFn, function(value) {
+            $elm.text(value);
+          });
+        }
+
+          // uiGridCtrl.recalcRowStyles = function() {
+          //   var offset = (scope.options.offsetTop || 0) - (scope.options.excessRows * scope.options.rowHeight);
+          //   var rowHeight = scope.options.rowHeight;
+
+          //   var ret = '';
+          //   var rowStyleCount = uiGridCtrl.minRowsToRender() + (scope.options.excessRows * 2);
+          //   for (var i = 1; i <= rowStyleCount; i++) {
+          //     ret = ret + ' .grid' + scope.gridId + ' .ui-grid-row:nth-child(' + i + ') { top: ' + offset + 'px; }';
+          //     offset = offset + rowHeight;
+          //   }
+
+          //   scope.rowStyles = ret;
+          // };
+
+          // uiGridCtrl.styleComputions.push(uiGridCtrl.recalcRowStyles);
+
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridViewport', ['$log', 'gridUtil',
+    function($log, gridUtil) {
+      return {
+        replace: true,
+        scope: {},
+        templateUrl: 'ui-grid/uiGridViewport',
+        require: ['^uiGrid', '^uiGridRenderContainer'],
+        link: function($scope, $elm, $attrs, controllers) {
+          $log.debug('viewport post-link');
+
+          var uiGridCtrl = controllers[0];
+          var containerCtrl = controllers[1];
+
+          $scope.containerCtrl = containerCtrl;
+
+          var rowContainer = containerCtrl.rowContainer;
+          var colContainer = containerCtrl.colContainer;
+
+          var grid = uiGridCtrl.grid;
+
+          $scope.grid = uiGridCtrl.grid;
+
+          // Put the containers in scope so we can get rows and columns from them
+          $scope.rowContainer = containerCtrl.rowContainer;
+          $scope.colContainer = containerCtrl.colContainer;
+
+          // Register this viewport with its container 
+          containerCtrl.viewport = $elm;
+
+          $elm.on('scroll', function (evt) {
+            var newScrollTop = $elm[0].scrollTop;
+            // var newScrollLeft = $elm[0].scrollLeft;
+            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);
+
+            // Handle RTL here
+
+            if (newScrollLeft !== colContainer.prevScrollLeft) {
+              var xDiff = newScrollLeft - colContainer.prevScrollLeft;
+
+              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+              var horizScrollPercentage = newScrollLeft / horizScrollLength;
+
+              colContainer.adjustScrollHorizontal(newScrollLeft, horizScrollPercentage);
+            }
+
+            if (newScrollTop !== rowContainer.prevScrollTop) {
+              var yDiff = newScrollTop - rowContainer.prevScrollTop;
+
+              // uiGridCtrl.fireScrollingEvent({ y: { pixels: diff } });
+              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+              // var vertScrollPercentage = (uiGridCtrl.prevScrollTop + yDiff) / vertScrollLength;
+              var vertScrollPercentage = newScrollTop / vertScrollLength;
+
+              if (vertScrollPercentage > 1) { vertScrollPercentage = 1; }
+              if (vertScrollPercentage < 0) { vertScrollPercentage = 0; }
+              
+              rowContainer.adjustScrollVertical(newScrollTop, vertScrollPercentage);
+            }
+          });
+        }
+      };
+    }
+  ]);
+
+})();
+(function() {
+
+angular.module('ui.grid')
+.directive('uiGridVisible', function uiGridVisibleAction() {
+  return function ($scope, $elm, $attr) {
+    $scope.$watch($attr.uiGridVisible, function (visible) {
+        // $elm.css('visibility', visible ? 'visible' : 'hidden');
+        $elm[visible ? 'removeClass' : 'addClass']('ui-grid-invisible');
+    });
+  };
+});
+
+})();
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').controller('uiGridController', ['$scope', '$element', '$attrs', '$log', 'gridUtil', '$q', 'uiGridConstants',
+                    '$templateCache', 'gridClassFactory', '$timeout', '$parse', '$compile',
+    function ($scope, $elm, $attrs, $log, gridUtil, $q, uiGridConstants,
+              $templateCache, gridClassFactory, $timeout, $parse, $compile) {
+      $log.debug('ui-grid controller');
+
+      var self = this;
+
+      // Extend options with ui-grid attribute reference
+      self.grid = gridClassFactory.createGrid($scope.uiGrid);
+      $elm.addClass('grid' + self.grid.id);
+      self.grid.rtl = $elm.css('direction') === 'rtl';
+
+
+      //add optional reference to externalScopes function to controller
+      //so it can be retrieved in lower elements that have isolate scope
+      self.getExternalScopes = $scope.getExternalScopes;
+
+      // angular.extend(self.grid.options, );
+
+      //all properties of grid are available on scope
+      $scope.grid = self.grid;
+
+      if ($attrs.uiGridColumns) {
+        $attrs.$observe('uiGridColumns', function(value) {
+          self.grid.options.columnDefs = value;
+          self.grid.buildColumns()
+            .then(function(){
+              self.grid.preCompileCellTemplates();
+
+              self.grid.refreshCanvas(true);
+            });
+        });
+      }
+
+
+      var dataWatchCollectionDereg;
+      if (angular.isString($scope.uiGrid.data)) {
+        dataWatchCollectionDereg = $scope.$parent.$watchCollection($scope.uiGrid.data, dataWatchFunction);
+      }
+      else {
+        dataWatchCollectionDereg = $scope.$parent.$watchCollection(function() { return $scope.uiGrid.data; }, dataWatchFunction);
+      }
+
+      var columnDefWatchCollectionDereg = $scope.$parent.$watchCollection(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction);
+
+      function columnDefsWatchFunction(n, o) {
+        if (n && n !== o) {
+          self.grid.options.columnDefs = n;
+          self.grid.buildColumns()
+            .then(function(){
+
+              self.grid.preCompileCellTemplates();
+
+              self.grid.refreshCanvas(true);
+            });
+        }
+      }
+
+      function dataWatchFunction(n) {
+        // $log.debug('dataWatch fired');
+        var promises = [];
+
+        if (n) {
+          if (self.grid.columns.length === 0) {
+            $log.debug('loading cols in dataWatchFunction');
+            if (!$attrs.uiGridColumns && self.grid.options.columnDefs.length === 0) {
+              self.grid.buildColumnDefsFromData(n);
+            }
+            promises.push(self.grid.buildColumns()
+              .then(function() {
+                self.grid.preCompileCellTemplates();}
+            ));
+          }
+          $q.all(promises).then(function() {
+            self.grid.modifyRows(n)
+              .then(function () {
+                // if (self.viewport) {
+                  self.grid.redrawInPlace();
+                // }
+
+                $scope.$evalAsync(function() {
+                  self.grid.refreshCanvas(true);
+                });
+              });
+          });
+        }
+      }
+
+
+      $scope.$on('$destroy', function() {
+        dataWatchCollectionDereg();
+        columnDefWatchCollectionDereg();
+      });
+
+      $scope.$watch(function () { return self.grid.styleComputations; }, function() {
+        self.grid.refreshCanvas(true);
+      });
+
+
+      /* Event Methods */
+
+      //todo: throttle this event?
+      self.fireScrollingEvent = function(args) {
+        $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
+      };
+
+      self.fireEvent = function(eventName, args) {
+        // Add the grid to the event arguments if it's not there
+        if (typeof(args) === 'undefined' || args === undefined) {
+          args = {};
+        }
+
+        if (typeof(args.grid) === 'undefined' || args.grid === undefined) {
+          args.grid = self.grid;
+        }
+
+        $scope.$broadcast(eventName, args);
+      };
+
+      self.innerCompile = function innerCompile(elm) {
+        $compile(elm)($scope);
+      };
+
+    }]);
+
+/**
+ *  @ngdoc directive
+ *  @name ui.grid.directive:uiGrid
+ *  @element div
+ *  @restrict EA
+ *  @param {Object} uiGrid Options for the grid to use
+ *  @param {Object=} external-scopes Add external-scopes='someScopeObjectYouNeed' attribute so you can access
+ *            your scopes from within any custom templatedirective.  You access by $scope.getExternalScopes() function
+ *
+ *  @description Create a very basic grid.
+ *
+ *  @example
+    <example module="app">
+      <file name="app.js">
+        var app = angular.module('app', ['ui.grid']);
+
+        app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.data = [
+            { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+          ];
+        }]);
+      </file>
+      <file name="index.html">
+        <div ng-controller="MainCtrl">
+          <div ui-grid="{ data: data }"></div>
+        </div>
+      </file>
+    </example>
+ */
+angular.module('ui.grid').directive('uiGrid',
+  [
+    '$log',
+    '$compile',
+    '$templateCache',
+    'gridUtil',
+    '$window',
+    function(
+      $log,
+      $compile,
+      $templateCache,
+      gridUtil,
+      $window
+      ) {
+      return {
+        templateUrl: 'ui-grid/ui-grid',
+        scope: {
+          uiGrid: '=',
+          getExternalScopes: '&?externalScopes' //optional functionwrapper around any needed external scope instances
+        },
+        replace: true,
+        transclude: true,
+        controller: 'uiGridController',
+        compile: function () {
+          return {
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+              $log.debug('ui-grid postlink');
+
+              var grid = uiGridCtrl.grid;
+
+              // Initialize scrollbars (TODO: move to controller??)
+              uiGridCtrl.scrollbars = [];
+
+              //todo: assume it is ok to communicate that rendering is complete??
+              grid.renderingComplete();
+
+              grid.element = $elm;
+
+              grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
+
+              // Default canvasWidth to the grid width, in case we don't get any column definitions to calculate it from
+              grid.canvasWidth = uiGridCtrl.grid.gridWidth;
+
+              grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+
+              // If the grid isn't tall enough to fit a single row, it's kind of useless. Resize it to fit a minimum number of rows
+              if (grid.gridHeight < grid.options.rowHeight) {
+                // Figure out the new height
+                var newHeight = grid.options.minRowsToShow * grid.options.rowHeight;
+
+                $elm.css('height', newHeight + 'px');
+
+                grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+              }
+
+              // Run initial canvas refresh
+              grid.refreshCanvas();
+
+              //add pinned containers for row headers support
+              //moved from pinning feature
+              var left = angular.element('<div ng-if="grid.hasLeftContainer()" style="width: 0" ui-grid-pinned-container="\'left\'"></div>');
+              $elm.prepend(left);
+              uiGridCtrl.innerCompile(left);
+
+              var right = angular.element('<div  ng-if="grid.hasRightContainer()" style="width: 0" ui-grid-pinned-container="\'right\'"></div>');
+              $elm.append(right);
+              uiGridCtrl.innerCompile(right);
+
+
+              //if we add a left container after render, we need to watch and react
+              $scope.$watch(function () { return grid.hasLeftContainer();}, function (newValue, oldValue) {
+                if (newValue === oldValue) {
+                  return;
+                }
+
+                //todo: remove this code.  it was commented out after moving from pinning because body is already float:left
+//                var bodyContainer = angular.element($elm[0].querySelectorAll('[container-id="body"]'));
+//                if (newValue){
+//                  bodyContainer.attr('style', 'float: left; position: inherit');
+//                }
+//                else {
+//                  bodyContainer.attr('style', 'float: left; position: relative');
+//                }
+
+                grid.refreshCanvas(true);
+              });
+
+              //if we add a right container after render, we need to watch and react
+              $scope.$watch(function () { return grid.hasRightContainer();}, function (newValue, oldValue) {
+                if (newValue === oldValue) {
+                  return;
+                }
+                grid.refreshCanvas(true);
+              });
+
+
+              // Resize the grid on window resize events
+              function gridResize($event) {
+                grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
+                grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+
+                grid.queueRefresh();
+              }
+
+              angular.element($window).on('resize', gridResize);
+
+              // Unbind from window resize events when the grid is destroyed
+              $elm.on('$destroy', function () {
+                angular.element($window).off('resize', gridResize);
+              });
+            }
+          };
+        }
+      };
+    }
+  ]);
+
+})();
+
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridPinnedContainer', ['$log', function ($log) {
+    return {
+      restrict: 'EA',
+      replace: true,
+      template: '<div class="ui-grid-pinned-container"><div ui-grid-render-container container-id="side" row-container-name="\'body\'" col-container-name="side" bind-scroll-vertical="true" class="{{ side }} ui-grid-render-container-{{ side }}"></div></div>',
+      scope: {
+        side: '=uiGridPinnedContainer'
+      },
+      require: '^uiGrid',
+      compile: function compile() {
+        return {
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            $log.debug('ui-grid-pinned-container ' + $scope.side + ' link');
+
+            var grid = uiGridCtrl.grid;
+
+            var myWidth = 0;
+
+            $elm.addClass('ui-grid-pinned-container-' + $scope.side);
+
+            function updateContainerDimensions() {
+              // $log.debug('update ' + $scope.side + ' dimensions');
+
+              var ret = '';
+
+              // Column containers
+              if ($scope.side === 'left' || $scope.side === 'right') {
+                var cols = grid.renderContainers[$scope.side].visibleColumnCache;
+                var width = 0;
+                for (var i = 0; i < cols.length; i++) {
+                  var col = cols[i];
+                  width += col.drawnWidth;
+                }
+
+                myWidth = width;
+
+                // $log.debug('myWidth', myWidth);
+
+                // TODO(c0bra): Subtract sum of col widths from grid viewport width and update it
+                $elm.attr('style', null);
+
+                var myHeight = grid.renderContainers.body.getViewportHeight(); // + grid.horizontalScrollbarHeight;
+
+                ret += '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ', .grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ' .ui-grid-render-container-' + $scope.side + ' .ui-grid-viewport { width: ' + myWidth + 'px; height: ' + myHeight + 'px; } ';
+              }
+
+              return ret;
+            }
+
+            grid.renderContainers.body.registerViewportAdjuster(function (adjustment) {
+              // Subtract our own width
+              adjustment.width -= myWidth;
+
+              return adjustment;
+            });
+
+            // Register style computation to adjust for columns in `side`'s render container
+            grid.registerStyleComputation({
+              priority: 15,
+              func: updateContainerDimensions
+            });
+          }
+        };
+      }
+    };
+  }]);
+})();
+(function(){
+
+angular.module('ui.grid')
+.factory('Grid', ['$log', '$q', '$compile', '$parse', 'gridUtil', 'uiGridConstants', 'GridOptions', 'GridColumn', 'GridRow', 'GridApi', 'rowSorter', 'rowSearcher', 'GridRenderContainer', '$timeout',
+    function($log, $q, $compile, $parse, gridUtil, uiGridConstants, GridOptions, GridColumn, GridRow, GridApi, rowSorter, rowSearcher, GridRenderContainer, $timeout) {
+
+/**
+ * @ngdoc object
+ * @name ui.grid.core.api:PublicApi
+ * @description Public Api for the core grid features
+ *
+ */
+
+
+/**
+   * @ngdoc function
+   * @name ui.grid.class:Grid
+   * @description Grid is the main viewModel.  Any properties or methods needed to maintain state are defined in
+ * * this prototype.  One instance of Grid is created per Grid directive instance.
+   * @param {object} options Object map of options to pass into the grid. An 'id' property is expected.
+   */
+  var Grid = function Grid(options) {
+    var self = this;
+  // Get the id out of the options, then remove it
+  if (options !== undefined && typeof(options.id) !== 'undefined' && options.id) {
+    if (!/^[_a-zA-Z0-9-]+$/.test(options.id)) {
+      throw new Error("Grid id '" + options.id + '" is invalid. It must follow CSS selector syntax rules.');
+    }
+  }
+  else {
+    throw new Error('No ID provided. An ID must be given when creating a grid.');
+  }
+
+  self.id = options.id;
+  delete options.id;
+
+  // Get default options
+  self.options = new GridOptions();
+
+  // Extend the default options with what we were passed in
+  angular.extend(self.options, options);
+
+  self.headerHeight = self.options.headerRowHeight;
+  self.footerHeight = self.options.showFooter === true ? self.options.footerRowHeight : 0;
+
+  self.rtl = false;
+  self.gridHeight = 0;
+  self.gridWidth = 0;
+  self.columnBuilders = [];
+  self.rowBuilders = [];
+  self.rowsProcessors = [];
+  self.columnsProcessors = [];
+  self.styleComputations = [];
+  self.viewportAdjusters = [];
+  self.rowHeaderColumns = [];
+
+  // self.visibleRowCache = [];
+
+  // Set of 'render' containers for self grid, which can render sets of rows
+  self.renderContainers = {};
+
+  // Create a
+  self.renderContainers.body = new GridRenderContainer('body', self);
+
+  self.cellValueGetterCache = {};
+
+  // Cached function to use with custom row templates
+  self.getRowTemplateFn = null;
+
+
+  //representation of the rows on the grid.
+  //these are wrapped references to the actual data rows (options.data)
+  self.rows = [];
+
+  //represents the columns on the grid
+  self.columns = [];
+
+  /**
+   * @ngdoc boolean
+   * @name isScrollingVertically
+   * @propertyOf ui.grid.class:Grid
+   * @description set to true when Grid is scrolling vertically. Set to false via debounced method
+   */
+  self.isScrollingVertically = false;
+
+  /**
+   * @ngdoc boolean
+   * @name isScrollingHorizontally
+   * @propertyOf ui.grid.class:Grid
+   * @description set to true when Grid is scrolling horizontally. Set to false via debounced method
+   */
+  self.isScrollingHorizontally = false;
+
+  var debouncedVertical = gridUtil.debounce(function () {
+    self.isScrollingVertically = false;
+  }, 300);
+
+  var debouncedHorizontal = gridUtil.debounce(function () {
+    self.isScrollingHorizontally = false;
+  }, 300);
+
+
+  /**
+   * @ngdoc function
+   * @name flagScrollingVertically
+   * @methodOf ui.grid.class:Grid
+   * @description sets isScrollingVertically to true and sets it to false in a debounced function
+   */
+  self.flagScrollingVertically = function() {
+    self.isScrollingVertically = true;
+    debouncedVertical();
+  };
+
+  /**
+   * @ngdoc function
+   * @name flagScrollingHorizontally
+   * @methodOf ui.grid.class:Grid
+   * @description sets isScrollingHorizontally to true and sets it to false in a debounced function
+   */
+  self.flagScrollingHorizontally = function() {
+    self.isScrollingHorizontally = true;
+    debouncedHorizontal();
+  };
+
+
+
+  self.api = new GridApi(self);
+
+  /**
+   * @ngdoc function
+   * @name refresh
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Refresh the rendered grid on screen.
+   * 
+   */
+  self.api.registerMethod( 'core', 'refresh', this.refresh );
+
+  /**
+   * @ngdoc function
+   * @name refreshRows
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Refresh the rendered grid on screen?  Note: not functional at present
+   * @returns {promise} promise that is resolved when render completes?
+   * 
+   */
+  self.api.registerMethod( 'core', 'refreshRows', this.refreshRows );
+
+
+  /**
+   * @ngdoc function
+   * @name sortChanged
+   * @methodOf  ui.grid.core.api:PublicApi
+   * @description The sort criteria on one or more columns has
+   * changed.  Provides as parameters the grid and the output of
+   * getColumnSorting, which is an array of gridColumns
+   * that have sorting on them, sorted in priority order. 
+   * 
+   * @param {Grid} grid the grid
+   * @param {array} sortColumns an array of columns with 
+   * sorts on them, in priority order
+   * 
+   * @example
+   * <pre>
+   *      gridApi.core.on.sortChanged( grid, sortColumns );
+   * </pre>
+   */
+  self.api.registerEvent( 'core', 'sortChanged' );
+};
+
+    /**
+     * @ngdoc function
+     * @name isRTL
+     * @methodOf ui.grid.class:Grid
+     * @description Returns true if grid is RightToLeft
+     */
+    Grid.prototype.isRTL = function () {
+      return this.rtl;
+    };
+
+
+      /**
+   * @ngdoc function
+   * @name registerColumnBuilder
+   * @methodOf ui.grid.class:Grid
+   * @description When the build creates columns from column definitions, the columnbuilders will be called to add
+   * additional properties to the column.
+   * @param {function(colDef, col, gridOptions)} columnsProcessor function to be called
+   */
+  Grid.prototype.registerColumnBuilder = function registerColumnBuilder(columnBuilder) {
+    this.columnBuilders.push(columnBuilder);
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildColumnDefsFromData
+   * @methodOf ui.grid.class:Grid
+   * @description Populates columnDefs from the provided data
+   * @param {function(colDef, col, gridOptions)} rowBuilder function to be called
+   */
+  Grid.prototype.buildColumnDefsFromData = function (dataRows){
+    this.options.columnDefs =  gridUtil.getColumnsFromData(dataRows,  this.options.excludeProperties);
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerRowBuilder
+   * @methodOf ui.grid.class:Grid
+   * @description When the build creates rows from gridOptions.data, the rowBuilders will be called to add
+   * additional properties to the row.
+   * @param {function(colDef, col, gridOptions)} rowBuilder function to be called
+   */
+  Grid.prototype.registerRowBuilder = function registerRowBuilder(rowBuilder) {
+    this.rowBuilders.push(rowBuilder);
+  };
+
+  /**
+   * @ngdoc function
+   * @name getColumn
+   * @methodOf ui.grid.class:Grid
+   * @description returns a grid column for the column name
+   * @param {string} name column name
+   */
+  Grid.prototype.getColumn = function getColumn(name) {
+    var columns = this.columns.filter(function (column) {
+      return column.colDef.name === name;
+    });
+    return columns.length > 0 ? columns[0] : null;
+  };
+
+  /**
+   * @ngdoc function
+   * @name getColDef
+   * @methodOf ui.grid.class:Grid
+   * @description returns a grid colDef for the column name
+   * @param {string} name column.field
+   */
+  Grid.prototype.getColDef = function getColDef(name) {
+    var colDefs = this.options.columnDefs.filter(function (colDef) {
+      return colDef.name === name;
+    });
+    return colDefs.length > 0 ? colDefs[0] : null;
+  };
+
+  /**
+   * @ngdoc function
+   * @name assignTypes
+   * @methodOf ui.grid.class:Grid
+   * @description uses the first row of data to assign colDef.type for any types not defined.
+   */
+  /**
+   * @ngdoc property
+   * @name type
+   * @propertyOf ui.grid.class:GridOptions.columnDef
+   * @description the type of the column, used in sorting.  If not provided then the 
+   * grid will guess the type.  Add this only if the grid guessing is not to your
+   * satisfaction.  Refer to {@link ui.grid.service:GridUtil.guessType gridUtil.guessType} for
+   * a list of values the grid knows about.
+   *
+   */
+  Grid.prototype.assignTypes = function(){
+    var self = this;
+    self.options.columnDefs.forEach(function (colDef, index) {
+
+      //Assign colDef type if not specified
+      if (!colDef.type) {
+        var col = new GridColumn(colDef, index, self);
+        var firstRow = self.rows.length > 0 ? self.rows[0] : null;
+        if (firstRow) {
+          colDef.type = gridUtil.guessType(self.getCellValue(firstRow, col));
+        }
+        else {
+          $log.log('Unable to assign type from data, so defaulting to string');
+          colDef.type = 'string';
+        }
+      }
+    });
+  };
+
+  /**
+  * @ngdoc function
+  * @name addRowHeaderColumn
+  * @methodOf ui.grid.class:Grid
+  * @description adds a row header column to the grid
+  * @param {object} column def
+  */
+  Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef) {
+    var self = this;
+    //self.createLeftContainer();
+    var rowHeaderCol = new GridColumn(colDef, self.rowHeaderColumns.length + 1, self);
+    rowHeaderCol.isRowHeader = true;
+    if (self.isRTL()) {
+      self.createRightContainer();
+      rowHeaderCol.renderContainer = 'right';
+    }
+    else {
+      self.createLeftContainer();
+      rowHeaderCol.renderContainer = 'left';
+    }
+
+    self.columnBuilders[0](colDef,rowHeaderCol,self.gridOptions)
+      .then(function(){
+        rowHeaderCol.enableFiltering = false;
+        rowHeaderCol.enableSorting = false;
+        self.rowHeaderColumns.push(rowHeaderCol);
+      });
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildColumns
+   * @methodOf ui.grid.class:Grid
+   * @description creates GridColumn objects from the columnDefinition.  Calls each registered
+   * columnBuilder to further process the column
+   * @returns {Promise} a promise to load any needed column resources
+   */
+  Grid.prototype.buildColumns = function buildColumns() {
+    $log.debug('buildColumns');
+    var self = this;
+    var builderPromises = [];
+    var offset = self.rowHeaderColumns.length;
+
+    //add row header columns to the grid columns array
+    angular.forEach(self.rowHeaderColumns, function (rowHeaderColumn) {
+      offset++;
+      self.columns.push(rowHeaderColumn);
+    });
+
+    // Synchronize self.columns with self.options.columnDefs so that columns can also be removed.
+    if (self.columns.length > self.options.columnDefs.length) {
+      self.columns.forEach(function (column, index) {
+        if (!self.getColDef(column.name)) {
+          self.columns.splice(index, 1);
+        }
+      });
+    }
+
+    self.options.columnDefs.forEach(function (colDef, index) {
+      self.preprocessColDef(colDef);
+      var col = self.getColumn(colDef.name);
+
+      if (!col) {
+        col = new GridColumn(colDef, index + offset, self);
+        self.columns.push(col);
+      }
+      else {
+        col.updateColumnDef(colDef, col.index);
+      }
+
+      self.columnBuilders.forEach(function (builder) {
+        builderPromises.push(builder.call(self, colDef, col, self.options));
+      });
+    });
+
+    return $q.all(builderPromises);
+  };
+
+/**
+ * @ngdoc function
+ * @name preCompileCellTemplates
+ * @methodOf ui.grid.class:Grid
+ * @description precompiles all cell templates
+ */
+  Grid.prototype.preCompileCellTemplates = function() {
+        this.columns.forEach(function (col) {
+          var html = col.cellTemplate.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)');
+
+          var compiledElementFn = $compile(html);
+          col.compiledElementFn = compiledElementFn;
+        });
+  };
+
+  /**
+   * @ngdoc function
+   * @name createLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description creates the left render container if it doesn't already exist
+   */
+  Grid.prototype.createLeftContainer = function() {
+    if (!this.hasLeftContainer()) {
+      this.renderContainers.left = new GridRenderContainer('left', this, { disableColumnOffset: true });
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name createRightContainer
+   * @methodOf ui.grid.class:Grid
+   * @description creates the right render container if it doesn't already exist
+   */
+  Grid.prototype.createRightContainer = function() {
+    if (!this.hasRightContainer()) {
+      this.renderContainers.right = new GridRenderContainer('right', this, { disableColumnOffset: true });
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name hasLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description returns true if leftContainer exists
+   */
+  Grid.prototype.hasLeftContainer = function() {
+    return this.renderContainers.left !== undefined;
+  };
+
+  /**
+   * @ngdoc function
+   * @name hasLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description returns true if rightContainer exists
+   */
+  Grid.prototype.hasRightContainer = function() {
+    return this.renderContainers.right !== undefined;
+  };
+
+
+      /**
+   * undocumented function
+   * @name preprocessColDef
+   * @methodOf ui.grid.class:Grid
+   * @description defaults the name property from field to maintain backwards compatibility with 2.x
+   * validates that name or field is present
+   */
+  Grid.prototype.preprocessColDef = function preprocessColDef(colDef) {
+    if (!colDef.field && !colDef.name) {
+      throw new Error('colDef.name or colDef.field property is required');
+    }
+
+    //maintain backwards compatibility with 2.x
+    //field was required in 2.x.  now name is required
+    if (colDef.name === undefined && colDef.field !== undefined) {
+      colDef.name = colDef.field;
+    }
+
+  };
+
+  // Return a list of items that exist in the `n` array but not the `o` array. Uses optional property accessors passed as third & fourth parameters
+  Grid.prototype.newInN = function newInN(o, n, oAccessor, nAccessor) {
+    var self = this;
+
+    var t = [];
+    for (var i=0; i<n.length; i++) {
+      var nV = nAccessor ? n[i][nAccessor] : n[i];
+      
+      var found = false;
+      for (var j=0; j<o.length; j++) {
+        var oV = oAccessor ? o[j][oAccessor] : o[j];
+        if (self.options.rowEquality(nV, oV)) {
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        t.push(nV);
+      }
+    }
+    
+    return t;
+  };
+
+    /**
+     * @ngdoc function
+     * @name getRow
+     * @methodOf ui.grid.class:Grid
+     * @description returns the GridRow that contains the rowEntity
+     * @param {object} rowEntity the gridOptions.data array element instance
+     */
+    Grid.prototype.getRow = function getRow(rowEntity) {
+      var rows = this.rows.filter(function (row) {
+        return row.entity === rowEntity;
+      });
+      return rows.length > 0 ? rows[0] : null;
+    };
+
+
+      /**
+   * @ngdoc function
+   * @name modifyRows
+   * @methodOf ui.grid.class:Grid
+   * @description creates or removes GridRow objects from the newRawData array.  Calls each registered
+   * rowBuilder to further process the row
+   *
+   * Rows are identified using the gridOptions.rowEquality function
+   */
+  Grid.prototype.modifyRows = function modifyRows(newRawData) {
+    var self = this,
+        i,
+        newRow;
+
+    if (self.rows.length === 0 && newRawData.length > 0) {
+      if (self.options.enableRowHashing) {
+        if (!self.rowHashMap) {
+          self.createRowHashMap();
+        }
+
+        for (i=0; i<newRawData.length; i++) {
+          newRow = newRawData[i];
+
+          self.rowHashMap.put(newRow, {
+            i: i,
+            entity: newRow
+          });
+        }
+      }
+
+      self.addRows(newRawData);
+      //now that we have data, it is save to assign types to colDefs
+      self.assignTypes();
+    }
+    else if (newRawData.length > 0) {
+      var unfoundNewRows, unfoundOldRows, unfoundNewRowsToFind;
+
+      // If row hashing is turned on
+      if (self.options.enableRowHashing) {
+        // Array of new rows that haven't been found in the old rowset
+        unfoundNewRows = [];
+        // Array of new rows that we explicitly HAVE to search for manually in the old row set. They cannot be looked up by their identity (because it doesn't exist).
+        unfoundNewRowsToFind = [];
+        // Map of rows that have been found in the new rowset
+        var foundOldRows = {};
+        // Array of old rows that have NOT been found in the new rowset
+        unfoundOldRows = [];
+
+        // Create the row HashMap if it doesn't exist already
+        if (!self.rowHashMap) {
+          self.createRowHashMap();
+        }
+        var rowhash = self.rowHashMap;
+        
+        // Make sure every new row has a hash
+        for (i = 0; i < newRawData.length; i++) {
+          newRow = newRawData[i];
+
+          // Flag this row as needing to be manually found if it didn't come in with a $$hashKey
+          var mustFind = false;
+          if (!self.options.getRowIdentity(newRow)) {
+            mustFind = true;
+          }
+
+          // See if the new row is already in the rowhash
+          var found = rowhash.get(newRow);
+          // If so...
+          if (found) {
+            // See if it's already being used by as GridRow
+            if (found.row) {
+              // If so, mark this new row as being found
+              foundOldRows[self.options.rowIdentity(newRow)] = true;
+            }
+          }
+          else {
+            // Put the row in the hashmap with the index it corresponds to
+            rowhash.put(newRow, {
+              i: i,
+              entity: newRow
+            });
+            
+            // This row has to be searched for manually in the old row set
+            if (mustFind) {
+              unfoundNewRowsToFind.push(newRow);
+            }
+            else {
+              unfoundNewRows.push(newRow);
+            }
+          }
+        }
+
+        // Build the list of unfound old rows
+        for (i = 0; i < self.rows.length; i++) {
+          var row = self.rows[i];
+          var hash = self.options.rowIdentity(row.entity);
+          if (!foundOldRows[hash]) {
+            unfoundOldRows.push(row);
+          }
+        }
+      }
+
+      // Look for new rows
+      var newRows = unfoundNewRows || [];
+
+      // The unfound new rows is either `unfoundNewRowsToFind`, if row hashing is turned on, or straight `newRawData` if it isn't
+      var unfoundNew = (unfoundNewRowsToFind || newRawData);
+
+      // Search for real new rows in `unfoundNew` and concat them onto `newRows`
+      newRows = newRows.concat(self.newInN(self.rows, unfoundNew, 'entity'));
+      
+      self.addRows(newRows); 
+      
+      var deletedRows = self.getDeletedRows((unfoundOldRows || self.rows), newRawData);
+
+      for (i = 0; i < deletedRows.length; i++) {
+        if (self.options.enableRowHashing) {
+          self.rowHashMap.remove(deletedRows[i].entity);
+        }
+
+        self.rows.splice( self.rows.indexOf(deletedRows[i]), 1 );
+      }
+    }
+    // Empty data set
+    else {
+      // Reset the row HashMap
+      self.createRowHashMap();
+
+      // Reset the rows length!
+      self.rows.length = 0;
+    }
+    
+    var p1 = $q.when(self.processRowsProcessors(self.rows))
+      .then(function (renderableRows) {
+        return self.setVisibleRows(renderableRows);
+      });
+
+    var p2 = $q.when(self.processColumnsProcessors(self.columns))
+      .then(function (renderableColumns) {
+        return self.setVisibleColumns(renderableColumns);
+      });
+
+    return $q.all([p1, p2]);
+  };
+
+  Grid.prototype.getDeletedRows = function(oldRows, newRows) {
+    var self = this;
+
+    var olds = oldRows.filter(function (oldRow) {
+      return !newRows.some(function (newItem) {
+        return self.options.rowEquality(newItem, oldRow.entity);
+      });
+    });
+    // var olds = self.newInN(newRows, oldRows, null, 'entity');
+    // dump('olds', olds);
+    return olds;
+  };
+
+  /**
+   * Private Undocumented Method
+   * @name addRows
+   * @methodOf ui.grid.class:Grid
+   * @description adds the newRawData array of rows to the grid and calls all registered
+   * rowBuilders. this keyword will reference the grid
+   */
+  Grid.prototype.addRows = function addRows(newRawData) {
+    var self = this;
+
+    var existingRowCount = self.rows.length;
+    for (var i=0; i < newRawData.length; i++) {
+      var newRow = self.processRowBuilders(new GridRow(newRawData[i], i + existingRowCount, self));
+
+      if (self.options.enableRowHashing) {
+        var found = self.rowHashMap.get(newRow.entity);
+        if (found) {
+          found.row = newRow;
+        }
+      }
+
+      self.rows.push(newRow);
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name processRowBuilders
+   * @methodOf ui.grid.class:Grid
+   * @description processes all RowBuilders for the gridRow
+   * @param {GridRow} gridRow reference to gridRow
+   * @returns {GridRow} the gridRow with all additional behavior added
+   */
+  Grid.prototype.processRowBuilders = function processRowBuilders(gridRow) {
+    var self = this;
+
+    self.rowBuilders.forEach(function (builder) {
+      builder.call(self, gridRow, self.gridOptions);
+    });
+
+    return gridRow;
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerStyleComputation
+   * @methodOf ui.grid.class:Grid
+   * @description registered a styleComputation function
+   * 
+   * If the function returns a value it will be appended into the grid's `<style>` block
+   * @param {function($scope)} styleComputation function
+   */
+  Grid.prototype.registerStyleComputation = function registerStyleComputation(styleComputationInfo) {
+    this.styleComputations.push(styleComputationInfo);
+  };
+
+
+  // NOTE (c0bra): We already have rowBuilders. I think these do exactly the same thing...
+  // Grid.prototype.registerRowFilter = function(filter) {
+  //   // TODO(c0bra): validate filter?
+
+  //   this.rowFilters.push(filter);
+  // };
+
+  // Grid.prototype.removeRowFilter = function(filter) {
+  //   var idx = this.rowFilters.indexOf(filter);
+
+  //   if (typeof(idx) !== 'undefined' && idx !== undefined) {
+  //     this.rowFilters.slice(idx, 1);
+  //   }
+  // };
+  
+  // Grid.prototype.processRowFilters = function(rows) {
+  //   var self = this;
+  //   self.rowFilters.forEach(function (filter) {
+  //     filter.call(self, rows);
+  //   });
+  // };
+
+
+  /**
+   * @ngdoc function
+   * @name registerRowsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableRows)} rows processor function
+   * @returns {Array[GridRow]} Updated renderable rows
+   * @description
+
+     Register a "rows processor" function. When the rows are updated,
+     the grid calls each registered "rows processor", which has a chance
+     to alter the set of rows (sorting, etc) as long as the count is not
+     modified.
+   */
+  Grid.prototype.registerRowsProcessor = function registerRowsProcessor(processor) {
+    if (!angular.isFunction(processor)) {
+      throw 'Attempt to register non-function rows processor: ' + processor;
+    }
+
+    this.rowsProcessors.push(processor);
+  };
+
+  /**
+   * @ngdoc function
+   * @name removeRowsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableRows)} rows processor function
+   * @description Remove a registered rows processor
+   */
+  Grid.prototype.removeRowsProcessor = function removeRowsProcessor(processor) {
+    var idx = this.rowsProcessors.indexOf(processor);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.rowsProcessors.splice(idx, 1);
+    }
+  };
+  
+  /**
+   * Private Undocumented Method
+   * @name processRowsProcessors
+   * @methodOf ui.grid.class:Grid
+   * @param {Array[GridRow]} The array of "renderable" rows
+   * @param {Array[GridColumn]} The array of columns
+   * @description Run all the registered rows processors on the array of renderable rows
+   */
+  Grid.prototype.processRowsProcessors = function processRowsProcessors(renderableRows) {
+    var self = this;
+
+    // Create a shallow copy of the rows so that we can safely sort them without altering the original grid.rows sort order
+    var myRenderableRows = renderableRows.slice(0);
+    
+    // self.rowsProcessors.forEach(function (processor) {
+    //   myRenderableRows = processor.call(self, myRenderableRows, self.columns);
+
+    //   if (!renderableRows) {
+    //     throw "Processor at index " + i + " did not return a set of renderable rows";
+    //   }
+
+    //   if (!angular.isArray(renderableRows)) {
+    //     throw "Processor at index " + i + " did not return an array";
+    //   }
+
+    //   i++;
+    // });
+
+    // Return myRenderableRows with no processing if we have no rows processors 
+    if (self.rowsProcessors.length === 0) {
+      return $q.when(myRenderableRows);
+    }
+  
+    // Counter for iterating through rows processors
+    var i = 0;
+    
+    // Promise for when we're done with all the processors
+    var finished = $q.defer();
+
+    // This function will call the processor in self.rowsProcessors at index 'i', and then
+    //   when done will call the next processor in the list, using the output from the processor
+    //   at i as the argument for 'renderedRowsToProcess' on the next iteration.
+    //  
+    //   If we're at the end of the list of processors, we resolve our 'finished' callback with
+    //   the result.
+    function startProcessor(i, renderedRowsToProcess) {
+      // Get the processor at 'i'
+      var processor = self.rowsProcessors[i];
+
+      // Call the processor, passing in the rows to process and the current columns
+      //   (note: it's wrapped in $q.when() in case the processor does not return a promise)
+      return $q.when( processor.call(self, renderedRowsToProcess, self.columns) )
+        .then(function handleProcessedRows(processedRows) {
+          // Check for errors
+          if (!processedRows) {
+            throw "Processor at index " + i + " did not return a set of renderable rows";
+          }
+
+          if (!angular.isArray(processedRows)) {
+            throw "Processor at index " + i + " did not return an array";
+          }
+
+          // Processor is done, increment the counter
+          i++;
+
+          // If we're not done with the processors, call the next one
+          if (i <= self.rowsProcessors.length - 1) {
+            return startProcessor(i, processedRows);
+          }
+          // We're done! Resolve the 'finished' promise
+          else {
+            finished.resolve(processedRows);
+          }
+        });
+    }
+
+    // Start on the first processor
+    startProcessor(0, myRenderableRows);
+    
+    return finished.promise;
+  };
+
+  Grid.prototype.setVisibleRows = function setVisibleRows(rows) {
+    // $log.debug('setVisibleRows');
+
+    var self = this;
+
+    //var newVisibleRowCache = [];
+
+    // Reset all the render container row caches
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      container.visibleRowCache.length = 0;
+    }
+    
+    // rows.forEach(function (row) {
+    for (var ri = 0; ri < rows.length; ri++) {
+      var row = rows[ri];
+
+      // If the row is visible
+      if (row.visible) {
+        // newVisibleRowCache.push(row);
+
+        // If the row has a container specified
+        if (typeof(row.renderContainer) !== 'undefined' && row.renderContainer) {
+          self.renderContainers[row.renderContainer].visibleRowCache.push(row);
+        }
+        // If not, put it into the body container
+        else {
+          self.renderContainers.body.visibleRowCache.push(row);
+        }
+      }
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerColumnsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableColumns)} rows processor function
+   * @returns {Array[GridColumn]} Updated renderable columns
+   * @description
+
+     Register a "columns processor" function. When the columns are updated,
+     the grid calls each registered "columns processor", which has a chance
+     to alter the set of columns, as long as the count is not modified.
+   */
+  Grid.prototype.registerColumnsProcessor = function registerColumnsProcessor(processor) {
+    if (!angular.isFunction(processor)) {
+      throw 'Attempt to register non-function rows processor: ' + processor;
+    }
+
+    this.columnsProcessors.push(processor);
+  };
+
+  Grid.prototype.removeColumnsProcessor = function removeColumnsProcessor(processor) {
+    var idx = this.columnsProcessors.indexOf(processor);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.columnsProcessors.splice(idx, 1);
+    }
+  };
+
+  Grid.prototype.processColumnsProcessors = function processColumnsProcessors(renderableColumns) {
+    var self = this;
+
+    // Create a shallow copy of the rows so that we can safely sort them without altering the original grid.rows sort order
+    var myRenderableColumns = renderableColumns.slice(0);
+
+    // Return myRenderableRows with no processing if we have no rows processors 
+    if (self.columnsProcessors.length === 0) {
+      return $q.when(myRenderableColumns);
+    }
+  
+    // Counter for iterating through rows processors
+    var i = 0;
+    
+    // Promise for when we're done with all the processors
+    var finished = $q.defer();
+
+    // This function will call the processor in self.rowsProcessors at index 'i', and then
+    //   when done will call the next processor in the list, using the output from the processor
+    //   at i as the argument for 'renderedRowsToProcess' on the next iteration.
+    //  
+    //   If we're at the end of the list of processors, we resolve our 'finished' callback with
+    //   the result.
+    function startProcessor(i, renderedColumnsToProcess) {
+      // Get the processor at 'i'
+      var processor = self.columnsProcessors[i];
+
+      // Call the processor, passing in the rows to process and the current columns
+      //   (note: it's wrapped in $q.when() in case the processor does not return a promise)
+      return $q.when( processor.call(self, renderedColumnsToProcess, self.rows) )
+        .then(function handleProcessedRows(processedColumns) {
+          // Check for errors
+          if (!processedColumns) {
+            throw "Processor at index " + i + " did not return a set of renderable rows";
+          }
+
+          if (!angular.isArray(processedColumns)) {
+            throw "Processor at index " + i + " did not return an array";
+          }
+
+          // Processor is done, increment the counter
+          i++;
+
+          // If we're not done with the processors, call the next one
+          if (i <= self.columnsProcessors.length - 1) {
+            return startProcessor(i, myRenderableColumns);
+          }
+          // We're done! Resolve the 'finished' promise
+          else {
+            finished.resolve(myRenderableColumns);
+          }
+        });
+    }
+
+    // Start on the first processor
+    startProcessor(0, myRenderableColumns);
+    
+    return finished.promise;
+  };
+
+  Grid.prototype.setVisibleColumns = function setVisibleColumns(columns) {
+    // $log.debug('setVisibleColumns');
+
+    var self = this;
+
+    // Reset all the render container row caches
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      container.visibleColumnCache.length = 0;
+    }
+
+    for (var ci = 0; ci < columns.length; ci++) {
+      var column = columns[ci];
+
+      // If the column is visible
+      if (column.visible) {
+        // If the column has a container specified
+        if (typeof(column.renderContainer) !== 'undefined' && column.renderContainer) {
+          self.renderContainers[column.renderContainer].visibleColumnCache.push(column);
+        }
+        // If not, put it into the body container
+        else {
+          self.renderContainers.body.visibleColumnCache.push(column);
+        }
+      }
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name handleWindowResize
+   * @methodOf ui.grid.class:Grid
+   * @description Triggered when the browser window resizes; automatically resizes the grid
+   */
+  Grid.prototype.handleWindowResize = function handleWindowResize($event) {
+    var self = this;
+
+    self.gridWidth = gridUtil.elementWidth(self.element);
+    self.gridHeight = gridUtil.elementHeight(self.element);
+
+    self.queueRefresh();
+  };
+
+  /**
+   * @ngdoc function
+   * @name queueRefresh
+   * @methodOf ui.grid.class:Grid
+   * @description todo: @c0bra can you document this method?
+   */
+  Grid.prototype.queueRefresh = function queueRefresh() {
+    var self = this;
+    if (self.refreshCanceller) {
+      $timeout.cancel(self.refreshCanceller);
+    }
+
+    self.refreshCanceller = $timeout(function () {
+      self.refreshCanvas(true);
+    });
+
+    self.refreshCanceller.then(function () {
+      self.refreshCanceller = null;
+    });
+
+    return self.refreshCanceller;
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildStyles
+   * @methodOf ui.grid.class:Grid
+   * @description calls each styleComputation function
+   */
+  // TODO: this used to take $scope, but couldn't see that it was used
+  Grid.prototype.buildStyles = function buildStyles() {
+    // $log.debug('buildStyles');
+
+    var self = this;
+    
+    self.customStyles = '';
+
+    self.styleComputations
+      .sort(function(a, b) {
+        if (a.priority === null) { return 1; }
+        if (b.priority === null) { return -1; }
+        if (a.priority === null && b.priority === null) { return 0; }
+        return a.priority - b.priority;
+      })
+      .forEach(function (compInfo) {
+        // this used to provide $scope as a second parameter, but I couldn't find any 
+        // style builders that used it, so removed it as part of moving to grid from controller
+        var ret = compInfo.func.call(self);
+
+        if (angular.isString(ret)) {
+          self.customStyles += '\n' + ret;
+        }
+      });
+  };
+
+
+  Grid.prototype.minColumnsToRender = function minColumnsToRender() {
+    var self = this;
+    var viewport = this.getViewportWidth();
+
+    var min = 0;
+    var totalWidth = 0;
+    self.columns.forEach(function(col, i) {
+      if (totalWidth < viewport) {
+        totalWidth += col.drawnWidth;
+        min++;
+      }
+      else {
+        var currWidth = 0;
+        for (var j = i; j >= i - min; j--) {
+          currWidth += self.columns[j].drawnWidth;
+        }
+        if (currWidth < viewport) {
+          min++;
+        }
+      }
+    });
+
+    return min;
+  };
+
+  Grid.prototype.getBodyHeight = function getBodyHeight() {
+    // Start with the viewportHeight
+    var bodyHeight = this.getViewportHeight();
+
+    // Add the horizontal scrollbar height if there is one
+    if (typeof(this.horizontalScrollbarHeight) !== 'undefined' && this.horizontalScrollbarHeight !== undefined && this.horizontalScrollbarHeight > 0) {
+      bodyHeight = bodyHeight + this.horizontalScrollbarHeight;
+    }
+
+    return bodyHeight;
+  };
+
+  // NOTE: viewport drawable height is the height of the grid minus the header row height (including any border)
+  // TODO(c0bra): account for footer height
+  Grid.prototype.getViewportHeight = function getViewportHeight() {
+    var self = this;
+
+    var viewPortHeight = this.gridHeight - this.headerHeight - this.footerHeight;
+
+    // Account for native horizontal scrollbar, if present
+    if (typeof(this.horizontalScrollbarHeight) !== 'undefined' && this.horizontalScrollbarHeight !== undefined && this.horizontalScrollbarHeight > 0) {
+      viewPortHeight = viewPortHeight - this.horizontalScrollbarHeight;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortHeight = viewPortHeight + adjustment.height;
+
+    // $log.debug('viewPortHeight', viewPortHeight);
+
+    return viewPortHeight;
+  };
+
+  Grid.prototype.getViewportWidth = function getViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = this.gridWidth;
+
+    if (typeof(this.verticalScrollbarWidth) !== 'undefined' && this.verticalScrollbarWidth !== undefined && this.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth - this.verticalScrollbarWidth;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortWidth = viewPortWidth + adjustment.width;
+
+    // $log.debug('getviewPortWidth', viewPortWidth);
+
+    return viewPortWidth;
+  };
+
+  Grid.prototype.getHeaderViewportWidth = function getHeaderViewportWidth() {
+    var viewPortWidth = this.getViewportWidth();
+
+    if (typeof(this.verticalScrollbarWidth) !== 'undefined' && this.verticalScrollbarWidth !== undefined && this.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth + this.verticalScrollbarWidth;
+    }
+
+    return viewPortWidth;
+  };
+
+  Grid.prototype.registerViewportAdjuster = function registerViewportAdjuster(func) {
+    this.viewportAdjusters.push(func);
+  };
+
+  Grid.prototype.removeViewportAdjuster = function registerViewportAdjuster(func) {
+    var idx = this.viewportAdjusters.indexOf(func);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.viewportAdjusters.splice(idx, 1);
+    }
+  };
+
+  Grid.prototype.getViewportAdjustment = function getViewportAdjustment() {
+    var self = this;
+
+    var adjustment = { height: 0, width: 0 };
+
+    self.viewportAdjusters.forEach(function (func) {
+      adjustment = func.call(this, adjustment);
+    });
+
+    return adjustment;
+  };
+
+  Grid.prototype.getVisibleRowCount = function getVisibleRowCount() {
+    // var count = 0;
+
+    // this.rows.forEach(function (row) {
+    //   if (row.visible) {
+    //     count++;
+    //   }
+    // });
+
+    // return this.visibleRowCache.length;
+    return this.renderContainers.body.visibleRowCache.length;
+  };
+
+   Grid.prototype.getVisibleRows = function getVisibleRows() {
+    return this.renderContainers.body.visibleRowCache;
+   };
+
+  Grid.prototype.getVisibleColumnCount = function getVisibleColumnCount() {
+    // var count = 0;
+
+    // this.rows.forEach(function (row) {
+    //   if (row.visible) {
+    //     count++;
+    //   }
+    // });
+
+    // return this.visibleRowCache.length;
+    return this.renderContainers.body.visibleColumnCache.length;
+  };
+
+
+  Grid.prototype.searchRows = function searchRows(renderableRows) {
+    return rowSearcher.search(this, renderableRows, this.columns);
+  };
+
+  Grid.prototype.sortByColumn = function sortByColumn(renderableRows) {
+    return rowSorter.sort(this, renderableRows, this.columns);
+  };
+
+  Grid.prototype.getCellValue = function getCellValue(row, col){
+    var self = this;
+
+    if (!self.cellValueGetterCache[col.colDef.name]) {
+      self.cellValueGetterCache[col.colDef.name] = $parse(row.getEntityQualifiedColField(col));
+    }
+
+    return self.cellValueGetterCache[col.colDef.name](row);
+  };
+
+  
+  Grid.prototype.getNextColumnSortPriority = function getNextColumnSortPriority() {
+    var self = this,
+        p = 0;
+
+    self.columns.forEach(function (col) {
+      if (col.sort && col.sort.priority && col.sort.priority > p) {
+        p = col.sort.priority;
+      }
+    });
+
+    return p + 1;
+  };
+
+  /**
+   * @ngdoc function
+   * @name resetColumnSorting
+   * @methodOf ui.grid.class:Grid
+   * @description Return the columns that the grid is currently being sorted by
+   * @param {GridColumn} [excludedColumn] Optional GridColumn to exclude from having its sorting reset
+   */
+  Grid.prototype.resetColumnSorting = function resetColumnSorting(excludeCol) {
+    var self = this;
+
+    self.columns.forEach(function (col) {
+      if (col !== excludeCol) {
+        col.sort = {};
+      }
+    });
+  };
+
+  /**
+   * @ngdoc function
+   * @name getColumnSorting
+   * @methodOf ui.grid.class:Grid
+   * @description Return the columns that the grid is currently being sorted by
+   * @returns {Array[GridColumn]} An array of GridColumn objects
+   */
+  Grid.prototype.getColumnSorting = function getColumnSorting() {
+    var self = this;
+
+    var sortedCols = [], myCols;
+
+    // Iterate through all the columns, sorted by priority
+    // Make local copy of column list, because sorting is in-place and we do not want to
+    // change the original sequence of columns
+    myCols = self.columns.slice(0);
+    myCols.sort(rowSorter.prioritySort).forEach(function (col) {
+      if (col.sort && typeof(col.sort.direction) !== 'undefined' && col.sort.direction && (col.sort.direction === uiGridConstants.ASC || col.sort.direction === uiGridConstants.DESC)) {
+        sortedCols.push(col);
+      }
+    });
+
+    return sortedCols;
+  };
+
+  /**
+   * @ngdoc function
+   * @name sortColumn
+   * @methodOf ui.grid.class:Grid
+   * @description Set the sorting on a given column, optionally resetting any existing sorting on the Grid.
+   * Emits the sortChanged event whenever the sort criteria are changed.
+   * @param {GridColumn} column Column to set the sorting on
+   * @param {uiGridConstants.ASC|uiGridConstants.DESC} [direction] Direction to sort by, either descending or ascending.
+   *   If not provided, the column will iterate through the sort directions: ascending, descending, unsorted.
+   * @param {boolean} [add] Add this column to the sorting. If not provided or set to `false`, the Grid will reset any existing sorting and sort
+   *   by this column only
+   * @returns {Promise} A resolved promise that supplies the column.
+   */
+  
+  Grid.prototype.sortColumn = function sortColumn(column, directionOrAdd, add) {
+    var self = this,
+        direction = null;
+
+    if (typeof(column) === 'undefined' || !column) {
+      throw new Error('No column parameter provided');
+    }
+
+    // Second argument can either be a direction or whether to add this column to the existing sort.
+    //   If it's a boolean, it's an add, otherwise, it's a direction
+    if (typeof(directionOrAdd) === 'boolean') {
+      add = directionOrAdd;
+    }
+    else {
+      direction = directionOrAdd;
+    }
+    
+    if (!add) {
+      self.resetColumnSorting(column);
+      column.sort.priority = 0;
+    }
+    else {
+      column.sort.priority = self.getNextColumnSortPriority();
+    }
+
+    if (!direction) {
+      // Figure out the sort direction
+      if (column.sort.direction && column.sort.direction === uiGridConstants.ASC) {
+        column.sort.direction = uiGridConstants.DESC;
+      }
+      else if (column.sort.direction && column.sort.direction === uiGridConstants.DESC) {
+        column.sort.direction = null;
+      }
+      else {
+        column.sort.direction = uiGridConstants.ASC;
+      }
+    }
+    else {
+      column.sort.direction = direction;
+    }
+    
+    self.api.core.raise.sortChanged( self, self.getColumnSorting() );
+
+    return $q.when(column);
+  };
+  
+  /**
+   * communicate to outside world that we are done with initial rendering
+   */
+  Grid.prototype.renderingComplete = function(){
+    if (angular.isFunction(this.options.onRegisterApi)) {
+      this.options.onRegisterApi(this.api);
+    }
+    this.api.core.raise.renderingComplete( this.api );
+  };
+
+  Grid.prototype.createRowHashMap = function createRowHashMap() {
+    var self = this;
+
+    var hashMap = new RowHashMap();
+    hashMap.grid = self;
+
+    self.rowHashMap = hashMap;
+  };
+  
+  
+  /**
+   * @ngdoc function
+   * @name refresh
+   * @methodOf ui.grid.class:Grid
+   * @description Refresh the rendered grid on screen.
+   * 
+   */
+  Grid.prototype.refresh = function refresh() {
+    $log.debug('grid refresh');
+    
+    var self = this;
+    
+    var p1 = self.processRowsProcessors(self.rows).then(function (renderableRows) {
+      self.setVisibleRows(renderableRows);
+    });
+
+    var p2 = self.processColumnsProcessors(self.columns).then(function (renderableColumns) {
+      self.setVisibleColumns(renderableColumns);
+    });
+
+    return $q.all([p1, p2]).then(function () {
+      self.redrawInPlace();
+
+      self.refreshCanvas(true);
+    });
+  };  
+  
+  /**
+   * @ngdoc function
+   * @name refreshRows
+   * @methodOf ui.grid.class:Grid
+   * @description Refresh the rendered rows on screen?  Note: not functional at present 
+   * @returns {promise} promise that is resolved when render completes?
+   * 
+   */
+  Grid.prototype.refreshRows = function refreshRows() {
+    var self = this;
+    
+    return self.processRowsProcessors(self.rows)
+      .then(function (renderableRows) {
+        self.setVisibleRows(renderableRows);
+
+        // TODO: this method doesn't exist, so clearly refreshRows doesn't work.
+        self.redrawRows();
+
+        self.refreshCanvas();
+      });
+  };
+
+  /**
+   * @ngdoc function
+   * @name redrawCanvas
+   * @methodOf ui.grid.class:Grid
+   * @description TBD
+   * @params {object} buildStyles optional parameter.  Use TBD
+   * @returns {promise} promise that is resolved when the canvas
+   * has been refreshed
+   * 
+   */
+  Grid.prototype.refreshCanvas = function(buildStyles) {
+    var self = this;
+    
+    if (buildStyles) {
+      self.buildStyles();
+    }
+
+    var p = $q.defer();
+
+    // Get all the header heights
+    var containerHeadersToRecalc = [];
+    for (var containerId in self.renderContainers) {
+      if (self.renderContainers.hasOwnProperty(containerId)) {
+        var container = self.renderContainers[containerId];
+
+        if (container.header) {
+          containerHeadersToRecalc.push(container);
+        }
+      }
+    }
+
+    if (containerHeadersToRecalc.length > 0) {
+      // Putting in a timeout as it's not calculating after the grid element is rendered and filled out
+      $timeout(function() {
+        // var oldHeaderHeight = self.grid.headerHeight;
+        // self.grid.headerHeight = gridUtil.outerElementHeight(self.header);
+
+        var rebuildStyles = false;
+
+        // Get all the header heights
+        for (var i = 0; i < containerHeadersToRecalc.length; i++) {
+          var container = containerHeadersToRecalc[i];
+
+          if (container.header) {
+            var oldHeaderHeight = container.headerHeight;
+            var headerHeight = gridUtil.outerElementHeight(container.header);
+            container.headerHeight = headerHeight;
+
+            if (oldHeaderHeight !== headerHeight) {
+              rebuildStyles = true;
+            }
+          }
+        }
+
+        // Rebuild styles if the header height has changed
+        //   The header height is used in body/viewport calculations and those are then used in other styles so we need it to be available
+        if (buildStyles && rebuildStyles) {
+          self.buildStyles();
+        }
+
+        p.resolve();
+      });
+    }
+    else {
+      // Timeout still needs to be here to trigger digest after styles have been rebuilt
+      $timeout(function() {
+        p.resolve();
+      });
+    }
+
+    return p.promise;
+  };
+
+
+  /**
+   * @ngdoc function
+   * @name redrawCanvas
+   * @methodOf ui.grid.class:Grid
+   * @description Redraw the rows and columns based on our current scroll position
+   * 
+   */
+  Grid.prototype.redrawInPlace = function redrawInPlace() {
+    // $log.debug('redrawInPlace');
+    
+    var self = this;
+
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      // $log.debug('redrawing container', i);
+
+      container.adjustRows(container.prevScrollTop, null);
+      container.adjustColumns(container.prevScrollLeft, null);
+    }
+  };
+
+
+  // Blatantly stolen from Angular as it isn't exposed (yet? 2.0?)
+  function RowHashMap() {}
+
+  RowHashMap.prototype = {
+    /**
+     * Store key value pair
+     * @param key key to store can be any type
+     * @param value value to store can be any type
+     */
+    put: function(key, value) {
+      this[this.grid.options.rowIdentity(key)] = value;
+    },
+
+    /**
+     * @param key
+     * @returns {Object} the value for the key
+     */
+    get: function(key) {
+      return this[this.grid.options.rowIdentity(key)];
+    },
+
+    /**
+     * Remove the key/value pair
+     * @param key
+     */
+    remove: function(key) {
+      var value = this[key = this.grid.options.rowIdentity(key)];
+      delete this[key];
+      return value;
+    }
+  };
+
+
+
+  return Grid;
+
+}]);
+
+})();
+
+(function () {
+
+  angular.module('ui.grid')
+    .factory('GridApi', ['$log', '$q', '$rootScope', 'gridUtil', 'uiGridConstants',
+      function ($log, $q, $rootScope, gridUtil, uiGridConstants) {
+        /**
+         * @ngdoc function
+         * @name ui.grid.class:GridApi
+         * @description GridApi provides the ability to register public methods events inside the grid and allow
+         * for other components to use the api via featureName.methodName and featureName.on.eventName(function(args){}
+         * @param {object} grid grid that owns api
+         */
+        var GridApi = function GridApi(grid) {
+          this.grid = grid;
+          this.listeners = [];
+          
+          /**
+           * @ngdoc function
+           * @name renderingComplete
+           * @methodOf  ui.grid.core.api:PublicApi
+           * @description Rendering is complete, called at the same
+           * time as `onRegisterApi`, but provides a way to obtain
+           * that same event within features without stopping end
+           * users from getting at the onRegisterApi method.
+           * 
+           * Included in gridApi so that it's always there - otherwise
+           * there is still a timing problem with when a feature can
+           * call this. 
+           * 
+           * @param {GridApi} gridApi the grid api, as normally 
+           * returned in the onRegisterApi method
+           * 
+           * @example
+           * <pre>
+           *      gridApi.core.on.renderingComplete( grid );
+           * </pre>
+           */
+          this.registerEvent( 'core', 'renderingComplete' );
+        };
+
+        /**
+         * @ngdoc function
+         * @name ui.grid.class:suppressEvents
+         * @methodOf ui.grid.class:GridApi
+         * @description Used to execute a function while disabling the specified event listeners.
+         * Disables the listenerFunctions, executes the callbackFn, and then enables
+         * the listenerFunctions again
+         * @param {object} listenerFuncs listenerFunc or array of listenerFuncs to suppress. These must be the same
+         * functions that were used in the .on.eventName method
+         * @param {object} callBackFn function to execute
+         * @example
+         * <pre>
+         *    var navigate = function (newRowCol, oldRowCol){
+         *       //do something on navigate
+         *    }
+         *
+         *    gridApi.cellNav.on.navigate(scope,navigate);
+         *
+         *
+         *    //call the scrollTo event and suppress our navigate listener
+         *    //scrollTo will still raise the event for other listeners
+         *    gridApi.suppressEvents(navigate, function(){
+         *       gridApi.cellNav.scrollTo(aRow, aCol);
+         *    });
+         *
+         * </pre>
+         */
+        GridApi.prototype.suppressEvents = function (listenerFuncs, callBackFn) {
+          var self = this;
+          var listeners = angular.isArray(listenerFuncs) ? listenerFuncs : [listenerFuncs];
+
+          //find all registered listeners
+          var foundListeners = [];
+          listeners.forEach(function (l) {
+            foundListeners = self.listeners.filter(function (lstnr) {
+              return l === lstnr.handler;
+            });
+          });
+
+          //deregister all the listeners
+          foundListeners.forEach(function(l){
+            l.dereg();
+          });
+
+          callBackFn();
+
+          //reregister all the listeners
+          foundListeners.forEach(function(l){
+              l.dereg = registerEventWithAngular(l.scope, l.eventId, l.handler, self.grid);
+          });
+
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerEvent
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers a new event for the given feature
+         * @param {string} featureName name of the feature that raises the event
+         * @param {string} eventName  name of the event
+         */
+        GridApi.prototype.registerEvent = function (featureName, eventName) {
+          var self = this;
+          if (!self[featureName]) {
+            self[featureName] = {};
+          }
+
+          var feature = self[featureName];
+          if (!feature.on) {
+            feature.on = {};
+            feature.raise = {};
+          }
+
+          var eventId = self.grid.id + featureName + eventName;
+
+          $log.log('Creating raise event method ' + featureName + '.raise.' + eventName);
+          feature.raise[eventName] = function () {
+            $rootScope.$broadcast.apply($rootScope, [eventId].concat(Array.prototype.slice.call(arguments)));
+          };
+
+          $log.log('Creating on event method ' + featureName + '.on.' + eventName);
+          feature.on[eventName] = function (scope, handler) {
+            var dereg = registerEventWithAngular(scope, eventId, handler, self.grid);
+
+            //track our listener so we can turn off and on
+            var listener = {handler: handler, dereg: dereg, eventId: eventId, scope: scope};
+            self.listeners.push(listener);
+
+            //destroy tracking when scope is destroyed
+            //wanted to remove the listener from the array but angular does
+            //strange things in scope.$destroy so I could not access the listener array
+            scope.$on('$destroy', function() {
+              listener.dereg = null;
+              listener.handler = null;
+              listener.eventId = null;
+              listener.scope = null;
+            });
+          };
+        };
+
+        function registerEventWithAngular(scope, eventId, handler, grid) {
+          return scope.$on(eventId, function (event) {
+            var args = Array.prototype.slice.call(arguments);
+            args.splice(0, 1); //remove evt argument
+            handler.apply(grid.api, args);
+          });
+        }
+
+        /**
+         * @ngdoc function
+         * @name registerEventsFromObject
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers features and events from a simple objectMap.
+         * eventObjectMap must be in this format (multiple features allowed)
+         * <pre>
+         * {featureName:
+         *        {
+         *          eventNameOne:function(args){},
+         *          eventNameTwo:function(args){}
+         *        }
+         *  }
+         * </pre>
+         * @param {object} eventObjectMap map of feature/event names
+         */
+        GridApi.prototype.registerEventsFromObject = function (eventObjectMap) {
+          var self = this;
+          var features = [];
+          angular.forEach(eventObjectMap, function (featProp, featPropName) {
+            var feature = {name: featPropName, events: []};
+            angular.forEach(featProp, function (prop, propName) {
+              feature.events.push(propName);
+            });
+            features.push(feature);
+          });
+
+          features.forEach(function (feature) {
+            feature.events.forEach(function (event) {
+              self.registerEvent(feature.name, event);
+            });
+          });
+
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerMethod
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers a new event for the given feature
+         * @param {string} featureName name of the feature
+         * @param {string} methodName  name of the method
+         * @param {object} callBackFn function to execute
+         * @param {object} thisArg binds callBackFn 'this' to thisArg.  Defaults to gridApi.grid
+         */
+        GridApi.prototype.registerMethod = function (featureName, methodName, callBackFn, thisArg) {
+          if (!this[featureName]) {
+            this[featureName] = {};
+          }
+
+          var feature = this[featureName];
+
+          feature[methodName] = gridUtil.createBoundedWrapper(thisArg || this.grid, callBackFn);
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerMethodsFromObject
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers features and methods from a simple objectMap.
+         * eventObjectMap must be in this format (multiple features allowed)
+         * <br>
+         * {featureName:
+         *        {
+         *          methodNameOne:function(args){},
+         *          methodNameTwo:function(args){}
+         *        }
+         * @param {object} eventObjectMap map of feature/event names
+         * @param {object} thisArg binds this to thisArg for all functions.  Defaults to gridApi.grid
+         */
+        GridApi.prototype.registerMethodsFromObject = function (methodMap, thisArg) {
+          var self = this;
+          var features = [];
+          angular.forEach(methodMap, function (featProp, featPropName) {
+            var feature = {name: featPropName, methods: []};
+            angular.forEach(featProp, function (prop, propName) {
+              feature.methods.push({name: propName, fn: prop});
+            });
+            features.push(feature);
+          });
+
+          features.forEach(function (feature) {
+            feature.methods.forEach(function (method) {
+              self.registerMethod(feature.name, method.name, method.fn, thisArg);
+            });
+          });
+
+        };
+        
+        return GridApi;
+
+      }]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+.factory('GridColumn', ['gridUtil', 'uiGridConstants', function(gridUtil, uiGridConstants) {
+
+  /**
+   * @ngdoc function
+   * @name ui.grid.class:GridColumn
+   * @description Represents the viewModel for each column.  Any state or methods needed for a Grid Column
+   * are defined on this prototype
+   * @param {ColDef} colDef Column definition.
+   * @param {number} index the current position of the column in the array
+   * @param {Grid} grid reference to the grid
+   */
+   
+   /**
+    * ******************************************************************************************
+    * PaulL1: Ugly hack here in documentation.  These properties are clearly properties of GridColumn, 
+    * and need to be noted as such for those extending and building ui-grid itself.
+    * However, from an end-developer perspective, they interact with all these through columnDefs,
+    * and they really need to be documented there.  I feel like they're relatively static, and
+    * I can't find an elegant way for ngDoc to reference to both....so I've duplicated each
+    * comment block.  Ugh.
+    * 
+    */
+
+   /** 
+    * @ngdoc property
+    * @name name
+    * @propertyOf ui.grid.class:GridColumn
+    * @description (mandatory) each column should have a name, although for backward
+    * compatibility with 2.x name can be omitted if field is present
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name name
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description (mandatory) each column should have a name, although for backward
+    * compatibility with 2.x name can be omitted if field is present
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name displayName
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Column name that will be shown in the header.  If displayName is not
+    * provided then one is generated using the name.
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name displayName
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Column name that will be shown in the header.  If displayName is not
+    * provided then one is generated using the name.
+    *
+    */
+       
+    /** 
+    * @ngdoc property
+    * @name field
+    * @propertyOf ui.grid.class:GridColumn
+    * @description field must be provided if you wish to bind to a 
+    * property in the data source.  Should be an angular expression that evaluates against grid.options.data 
+    * array element.  Can be a complex expression: <code>employee.address.city</code>, or can be a function: <code>employee.getFullAddress()</code>.
+    * See the angular docs on binding expressions.
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name field
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description field must be provided if you wish to bind to a 
+    * property in the data source.  Should be an angular expression that evaluates against grid.options.data 
+    * array element.  Can be a complex expression: <code>employee.address.city</code>, or can be a function: <code>employee.getFullAddress()</code>.
+    * See the angular docs on binding expressions.
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name filter
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Filter on this column.  
+    * @example
+    * <pre>{ term: 'text', condition: uiGridConstants.filter.STARTS_WITH, placeholder: 'type to filter...' }</pre>
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name filter
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Specify a single filter field on this column.
+    * @example
+    * <pre>$scope.gridOptions.columnDefs = [ 
+    *   {
+    *     field: 'field1',
+    *     filter: {
+    *       condition: uiGridConstants.filter.STARTS_WITH,
+    *       placeholder: 'starts with...'
+    *     }
+    *   }
+    * ]; </pre>
+    *
+    */
+    
+   
+  function GridColumn(colDef, index, grid) {
+    var self = this;
+
+    self.grid = grid;
+    colDef.index = index;
+
+    self.updateColumnDef(colDef);
+  }
+
+  GridColumn.prototype.setPropertyOrDefault = function (colDef, propName, defaultValue) {
+    var self = this;
+
+    // Use the column definition filter if we were passed it
+    if (typeof(colDef[propName]) !== 'undefined' && colDef[propName]) {
+      self[propName] = colDef[propName];
+    }
+    // Otherwise use our own if it's set
+    else if (typeof(self[propName]) !== 'undefined') {
+      self[propName] = self[propName];
+    }
+    // Default to empty object for the filter
+    else {
+      self[propName] = defaultValue ? defaultValue : {};
+    }
+  };
+
+  
+  
+   /** 
+    * @ngdoc property
+    * @name width
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the column width.  Can be either 
+    * a number or a percentage, or an * for auto.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', width: 100},
+    *                                          { field: 'field2', width: '20%'},
+    *                                          { field: 'field3', width: '*' }]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name minWidth
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the minimum column width.  Should be a number.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', minWidth: 100}]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name maxWidth
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the maximum column width.  Should be a number.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', maxWidth: 100}]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name visible
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets whether or not the column is visible
+    * </br>Default is true
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ 
+    *     { field: 'field1', visible: true},
+    *     { field: 'field2', visible: false }
+    *   ]; </pre>
+    *
+    */
+   
+  /**
+   * @ngdoc property
+   * @name sort
+   * @propertyOf ui.grid.class:GridOptions.columnDef
+   * @description Can be used to set the sort direction for the column, values are
+   * uiGridConstants.ASC or uiGridConstants.DESC
+   * @example
+   * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', sort: { direction: uiGridConstants.ASC }}] </pre>
+   */
+  
+
+    /** 
+    * @ngdoc property
+    * @name sortingAlgorithm
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Algorithm to use for sorting this column. Takes 'a' and 'b' parameters 
+    * like any normal sorting function.
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name sortingAlgorithm
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Algorithm to use for sorting this column. Takes 'a' and 'b' parameters 
+    * like any normal sorting function.
+    *
+    */
+      
+   /** 
+    * @ngdoc array
+    * @name filters
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Specify multiple filter fields.
+    * @example
+    * <pre>$scope.gridOptions.columnDefs = [ 
+    *   {
+    *     field: 'field1', filters: [
+    *       {
+    *         condition: uiGridConstants.filter.STARTS_WITH,
+    *         placeholder: 'starts with...'
+    *       },
+    *       {
+    *         condition: uiGridConstants.filter.ENDS_WITH,
+    *         placeholder: 'ends with...'
+    *       }
+    *     ]
+    *   }
+    * ]; </pre>
+    *
+    * 
+    */ 
+   
+   /** 
+    * @ngdoc array
+    * @name filters
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Filters for this column. Includes 'term' property bound to filter input elements.
+    * @example
+    * <pre>[
+    *   {
+    *     term: 'foo', // ngModel for <input>
+    *     condition: uiGridConstants.filter.STARTS_WITH,
+    *     placeholder: 'starts with...'
+    *   },
+    *   {
+    *     term: 'baz',
+    *     condition: uiGridConstants.filter.ENDS_WITH,
+    *     placeholder: 'ends with...'
+    *   }
+    * ] </pre>
+    *
+    * 
+    */   
+
+   /** 
+    * @ngdoc array
+    * @name menuItems
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description used to add menu items to a column.  Refer to the tutorial on this 
+    * functionality.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ 
+    *   { field: 'field1', menuItems: [
+    *     {
+    *       title: 'Outer Scope Alert',
+    *       icon: 'ui-grid-icon-info-circled',
+    *       action: function($event) {
+    *         this.context.blargh(); // $scope.blargh() would work too, this is just an example
+    *       },
+    *       context: $scope
+    *     },
+    *     {
+    *       title: 'Grid ID',
+    *       action: function() {
+    *         alert('Grid ID: ' + this.grid.id);
+    *       }
+    *     }
+    *   ] }]; </pre>
+    *
+    */   
+  GridColumn.prototype.updateColumnDef = function(colDef, index) {
+    var self = this;
+
+    self.colDef = colDef;
+
+    //position of column
+    self.index = (typeof(index) === 'undefined') ? colDef.index : index;
+
+    if (colDef.name === undefined) {
+      throw new Error('colDef.name is required for column at index ' + self.index);
+    }
+
+    var parseErrorMsg = "Cannot parse column width '" + colDef.width + "' for column named '" + colDef.name + "'";
+
+    // If width is not defined, set it to a single star
+    if (gridUtil.isNullOrUndefined(colDef.width)) {
+      self.width = '*';
+    }
+    else {
+      // If the width is not a number
+      if (!angular.isNumber(colDef.width)) {
+        // See if it ends with a percent
+        if (gridUtil.endsWith(colDef.width, '%')) {
+          // If so we should be able to parse the non-percent-sign part to a number
+          var percentStr = colDef.width.replace(/%/g, '');
+          var percent = parseInt(percentStr, 10);
+          if (isNaN(percent)) {
+            throw new Error(parseErrorMsg);
+          }
+          self.width = colDef.width;
+        }
+        // And see if it's a number string
+        else if (colDef.width.match(/^(\d+)$/)) {
+          self.width = parseInt(colDef.width.match(/^(\d+)$/)[1], 10);
+        }
+        // Otherwise it should be a string of asterisks
+        else if (!colDef.width.match(/^\*+$/)) {
+          throw new Error(parseErrorMsg);
+        }
+      }
+      // Is a number, use it as the width
+      else {
+        self.width = colDef.width;
+      }
+    }
+
+    // Remove this column from the grid sorting
+    GridColumn.prototype.unsort = function () {
+      this.sort = {};
+    };
+
+    self.minWidth = !colDef.minWidth ? 50 : colDef.minWidth;
+    self.maxWidth = !colDef.maxWidth ? 9000 : colDef.maxWidth;
+
+    //use field if it is defined; name if it is not
+    self.field = (colDef.field === undefined) ? colDef.name : colDef.field;
+
+    // Use colDef.displayName as long as it's not undefined, otherwise default to the field name
+    self.displayName = (colDef.displayName === undefined) ? gridUtil.readableColumnName(colDef.name) : colDef.displayName;
+
+    //self.originalIndex = index;
+
+    self.aggregationType = angular.isDefined(colDef.aggregationType) ? colDef.aggregationType : null;
+    self.footerCellTemplate = angular.isDefined(colDef.footerCellTemplate) ? colDef.footerCellTemplate : null;
+
+    /**
+     * @ngdoc property
+     * @name cellClass
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description cellClass can be a string specifying the class to append to a cell
+     * or it can be a function(row,rowRenderIndex, col, colRenderIndex) that returns a class name
+     *
+     */
+    self.cellClass = colDef.cellClass;
+
+
+    /**
+     * @ngdoc property
+     * @name cellFilter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description cellFilter is a filter to apply to the content of each cell
+     * @example
+     * <pre>
+     *   gridOptions.columnDefs[0].cellFilter = 'date'
+     *
+     */
+    self.cellFilter = colDef.cellFilter ? colDef.cellFilter : "";
+
+    /**
+     * @ngdoc property
+     * @name headerCellFilter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description headerCellFilter is a filter to apply to the content of the column header
+     * @example
+     * <pre>
+     *   gridOptions.columnDefs[0].headerCellFilter = 'translate'
+     *
+     */
+    self.headerCellFilter = colDef.headerCellFilter ? colDef.headerCellFilter : "";
+
+    self.visible = gridUtil.isNullOrUndefined(colDef.visible) || colDef.visible;
+
+    self.headerClass = colDef.headerClass;
+    //self.cursor = self.sortable ? 'pointer' : 'default';
+
+    self.visible = true;
+
+    // Turn on sorting by default
+    self.enableSorting = typeof(colDef.enableSorting) !== 'undefined' ? colDef.enableSorting : true;
+    self.sortingAlgorithm = colDef.sortingAlgorithm;
+
+    // Turn on filtering by default (it's disabled by default at the Grid level)
+    self.enableFiltering = typeof(colDef.enableFiltering) !== 'undefined' ? colDef.enableFiltering : true;
+
+    // self.menuItems = colDef.menuItems;
+    self.setPropertyOrDefault(colDef, 'menuItems', []);
+
+    // Use the column definition sort if we were passed it
+    self.setPropertyOrDefault(colDef, 'sort');
+
+    // Set up default filters array for when one is not provided.
+    //   In other words, this (in column def):
+    //   
+    //       filter: { term: 'something', flags: {}, condition: [CONDITION] }
+    //       
+    //   is just shorthand for this:
+    //   
+    //       filters: [{ term: 'something', flags: {}, condition: [CONDITION] }]
+    //       
+    var defaultFilters = [];
+    if (colDef.filter) {
+      defaultFilters.push(colDef.filter);
+    }
+    else if (self.enableFiltering && self.grid.options.enableFiltering) {
+      // Add an empty filter definition object, which will
+      // translate to a guessed condition and no pre-populated
+      // value for the filter <input>.
+      defaultFilters.push({});
+    }
+
+    /**
+     * @ngdoc object
+     * @name ui.grid.class:GridOptions.columnDef.filter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description An object defining filtering for a column.
+     */    
+
+    /**
+     * @ngdoc property
+     * @name condition
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description Defines how rows are chosen as matching the filter term. This can be set to
+     * one of the constants in uiGridConstants.filter, or you can supply a custom filter function
+     * that gets passed the following arguments: [searchTerm, cellValue, row, column].
+     */
+    
+    /**
+     * @ngdoc property
+     * @name term
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description If set, the filter field will be pre-populated
+     * with this value.
+     */
+
+    /**
+     * @ngdoc property
+     * @name placeholder
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description String that will be set to the <input>.placeholder attribute.
+     */
+
+    /*
+
+      self.filters = [
+        {
+          term: 'search term'
+          condition: uiGridConstants.filter.CONTAINS,
+          placeholder: 'my placeholder',
+          flags: {
+            caseSensitive: true
+          }
+        }
+      ]
+
+    */
+
+    self.setPropertyOrDefault(colDef, 'filter');
+    self.setPropertyOrDefault(colDef, 'filters', defaultFilters);
+  };
+
+
+
+
+    /**
+     * @ngdoc function
+     * @name getColClass
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the class name for the column
+     * @param {bool} prefixDot  if true, will return .className instead of className
+     */
+    GridColumn.prototype.getColClass = function (prefixDot) {
+      var cls = uiGridConstants.COL_CLASS_PREFIX + this.index;
+
+      return prefixDot ? '.' + cls : cls;
+    };
+
+    /**
+     * @ngdoc function
+     * @name getColClassDefinition
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the class definition for th column
+     */
+    GridColumn.prototype.getColClassDefinition = function () {
+      return ' .grid' + this.grid.id + ' ' + this.getColClass(true) + ' { width: ' + this.drawnWidth + 'px; }';
+    };
+
+    /**
+     * @ngdoc function
+     * @name getRenderContainer
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the render container object that this column belongs to.
+     *
+     * Columns will be default be in the `body` render container if they aren't allocated to one specifically.
+     */
+    GridColumn.prototype.getRenderContainer = function getRenderContainer() {
+      var self = this;
+
+      var containerId = self.renderContainer;
+
+      if (containerId === null || containerId === '' || containerId === undefined) {
+        containerId = 'body';
+      }
+
+      return self.grid.renderContainers[containerId];
+    };
+
+    /**
+     * @ngdoc function
+     * @name showColumn
+     * @methodOf ui.grid.class:GridColumn
+     * @description Makes the column visible by setting colDef.visible = true
+     */
+    GridColumn.prototype.showColumn = function() {
+        this.colDef.visible = true;
+    };
+
+    /**
+     * @ngdoc function
+     * @name hideColumn
+     * @methodOf ui.grid.class:GridColumn
+     * @description Hides the column by setting colDef.visible = false
+     */
+    GridColumn.prototype.hideColumn = function() {
+        this.colDef.visible = false;
+    };
+
+    /**
+     * @ngdoc function
+     * @name getAggregationValue
+     * @methodOf ui.grid.class:GridColumn
+     * @description gets the aggregation value based on the aggregation type for this column
+     */
+    GridColumn.prototype.getAggregationValue = function () {
+      var self = this;
+      var result = 0;
+      var visibleRows = self.grid.getVisibleRows();
+      var cellValues = [];
+      angular.forEach(visibleRows, function (row) {
+        var cellValue = self.grid.getCellValue(row, self);
+        if (angular.isNumber(cellValue)) {
+          cellValues.push(cellValue);
+        }
+      });
+      if (angular.isFunction(self.aggregationType)) {
+        return self.aggregationType(visibleRows, self);
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.count) {
+        //TODO: change to i18n
+        return 'total rows: ' + self.grid.getVisibleRowCount();
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.sum) {
+        angular.forEach(cellValues, function (value) {
+          result += value;
+        });
+        //TODO: change to i18n
+        return 'total: ' + result;
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.avg) {
+        angular.forEach(cellValues, function (value) {
+          result += value;
+        });
+        result = result / cellValues.length;
+        //TODO: change to i18n
+        return 'avg: ' + result;
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.min) {
+        return 'min: ' + Math.min.apply(null, cellValues);
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.max) {
+        return 'max: ' + Math.max.apply(null, cellValues);
+      }
+      else {
+        return null;
+      }
+    };
+
+    return GridColumn;
+  }]);
+
+})();
+
+  (function(){
+
+angular.module('ui.grid')
+.factory('GridOptions', ['gridUtil', function(gridUtil) {
+
+  /**
+   * @ngdoc function
+   * @name ui.grid.class:GridOptions
+   * @description Default GridOptions class.  GridOptions are defined by the application developer and overlaid
+   * over this object.  Setting gridOptions within your controller is the most common method for an application 
+   * developer to configure the behaviour of their ui-grid
+   * 
+   * @example To define your gridOptions within your controller:
+   * <pre>$scope.gridOptions = {
+   *   data: $scope.myData,
+   *   columnDefs: [ 
+   *     { name: 'field1', displayName: 'pretty display name' },
+   *     { name: 'field2', visible: false }
+   *  ]
+   * };</pre>
+   * 
+   * You can then use this within your html template, when you define your grid:
+   * <pre>&lt;div ui-grid="gridOptions"&gt;&lt;/div&gt;</pre>
+   *
+   * To provide default options for all of the grids within your application, use an angular
+   * decorator to modify the GridOptions factory.
+   * <pre>app.config(function($provide){
+   *    $provide.decorator('GridOptions',function($delegate){
+   *      return function(){
+   *        var defaultOptions = new $delegate();
+   *        defaultOptions.excludeProperties = ['id' ,'$$hashKey'];
+   *        return defaultOptions;
+   *      };
+   *    })
+   *  })</pre>
+   */
+  function GridOptions() {
+
+    this.onRegisterApi = angular.noop();
+
+    /**
+     * @ngdoc object
+     * @name data
+     * @propertyOf ui.grid.class:GridOptions
+     * @description (mandatory) Array of data to be rendered into the grid, providing the data source or data binding for 
+     * the grid.  The most common case is an array of objects, where each object has a number of attributes.
+     * Each attribute automatically becomes a column in your grid.  This array could, for example, be sourced from
+     * an angularJS $resource query request.  The array can also contain complex objects.
+     * 
+     */
+    this.data = [];
+
+    /**
+     * @ngdoc array
+     * @name columnDefs
+     * @propertyOf  ui.grid.class:GridOptions
+     * @description Array of columnDef objects.  Only required property is name.
+     * The individual options available in columnDefs are documented in the
+     * {@link ui.grid.class:GridOptions.columnDef columnDef} section
+     * </br>_field property can be used in place of name for backwards compatibility with 2.x_
+     *  @example
+     *
+     * <pre>var columnDefs = [{name:'field1'}, {name:'field2'}];</pre>
+     *
+     */
+    this.columnDefs = [];
+
+    /**
+     * @ngdoc object
+     * @name ui.grid.class:GridOptions.columnDef
+     * @description Definition / configuration of an individual column, which would typically be
+     * one of many column definitions within the gridOptions.columnDefs array
+     * @example
+     * <pre>{name:'field1', field: 'field1', filter: { term: 'xxx' }}</pre>
+     *
+     */
+
+        
+    /**
+     * @ngdoc array
+     * @name excludeProperties
+     * @propertyOf  ui.grid.class:GridOptions
+     * @description Array of property names in data to ignore when auto-generating column names.  Provides the
+     * inverse of columnDefs - columnDefs is a list of columns to include, excludeProperties is a list of columns
+     * to exclude. 
+     * 
+     * If columnDefs is defined, this will be ignored.
+     * 
+     * Defaults to ['$$hashKey']
+     */
+    
+    this.excludeProperties = ['$$hashKey'];
+
+    /**
+     * @ngdoc boolean
+     * @name enableRowHashing
+     * @propertyOf ui.grid.class:GridOptions
+     * @description True by default. When enabled, this setting allows uiGrid to add
+     * `$$hashKey`-type properties (similar to Angular) to elements in the `data` array. This allows
+     * the grid to maintain state while vastly speeding up the process of altering `data` by adding/moving/removing rows.
+     * 
+     * Note that this DOES add properties to your data that you may not want, but they are stripped out when using `angular.toJson()`. IF
+     * you do not want this at all you can disable this setting but you will take a performance hit if you are using large numbers of rows
+     * and are altering the data set often.
+     */
+    this.enableRowHashing = true;
+
+    /**
+     * @ngdoc function
+     * @name rowIdentity
+     * @methodOf ui.grid.class:GridOptions
+     * @description This function is used to get and, if necessary, set the value uniquely identifying this row.
+     * 
+     * By default it returns the `$$hashKey` property if it exists. If it doesn't it uses gridUtil.nextUid() to generate one
+     */
+    this.rowIdentity = function rowIdentity(row) {
+        return gridUtil.hashKey(row);
+    };
+
+    /**
+     * @ngdoc function
+     * @name getRowIdentity
+     * @methodOf ui.grid.class:GridOptions
+     * @description This function returns the identity value uniquely identifying this row.
+     * 
+     * By default it returns the `$$hashKey` property but can be overridden to use any property or set of properties you want.
+     */
+    this.getRowIdentity = function getRowIdentity(row) {
+        return row.$$hashKey;
+    };
+
+    this.headerRowHeight = 30;
+    this.rowHeight = 30;
+    this.maxVisibleRowCount = 200;
+
+    /**
+     * @ngdoc integer
+     * @name minRowsToShow
+     * @propertyOf ui.grid.class:GridOptions
+     * @description Minimum number of rows to show when the grid doesn't have a defined height. Defaults to "10".
+     */
+    this.minRowsToShow = 10;
+
+    this.showFooter = false;
+    this.footerRowHeight = 30;
+
+    this.columnWidth = 50;
+    this.maxVisibleColumnCount = 200;
+
+    // Turn virtualization on when number of data elements goes over this number
+    this.virtualizationThreshold = 20;
+
+    this.columnVirtualizationThreshold = 10;
+
+    // Extra rows to to render outside of the viewport
+    this.excessRows = 4;
+    this.scrollThreshold = 4;
+
+    // Extra columns to to render outside of the viewport
+    this.excessColumns = 4;
+    this.horizontalScrollThreshold = 2;
+
+    /**
+     * @ngdoc boolean
+     * @name enableSorting
+     * @propertyOf ui.grid.class:GridOptions
+     * @description True by default. When enabled, this setting adds sort
+     * widgets to the column headers, allowing sorting of the data for the entire grid.
+     * Sorting can then be disabled on individual columns using the columnDefs.
+     */
+    this.enableSorting = true;
+
+    /**
+     * @ngdoc boolean
+     * @name enableFiltering
+     * @propertyOf ui.grid.class:GridOptions
+     * @description False by default. When enabled, this setting adds filter 
+     * boxes to each column header, allowing filtering within the column for the entire grid.
+     * Filtering can then be disabled on individual columns using the columnDefs. 
+     */
+    this.enableFiltering = false;
+
+    /**
+     * @ngdoc boolean
+     * @name enableColumnMenu
+     * @propertyOf ui.grid.class:GridOptions
+     * @description True by default. When enabled, this setting displays a column
+     * menu within each column.
+     */
+    this.enableColumnMenu = true;
+
+    /**
+     * @ngdoc boolean
+     * @name enableScrollbars
+     * @propertyOf ui.grid.class:GridOptions
+     * @description True by default. When enabled, this settings enable vertical
+     * and horizontal scrollbar for grid.
+     */
+    this.enableScrollbars = true;
+
+    // Columns can't be smaller than 10 pixels
+    this.minimumColumnSize = 10;
+
+    /**
+     * @ngdoc function
+     * @name rowEquality
+     * @methodOf ui.grid.class:GridOptions
+     * @description By default, rows are compared using object equality.  This option can be overridden
+     * to compare on any data item property or function
+     * @param {object} entityA First Data Item to compare
+     * @param {object} entityB Second Data Item to compare
+     */
+    this.rowEquality = function(entityA, entityB) {
+      return entityA === entityB;
+    };
+
+    /**
+     * @ngdoc string
+     * @name headerTemplate
+     * @propertyOf ui.grid.class:GridOptions
+     * @description Null by default. When provided, this setting uses a custom header
+     * template, rather than the default template. Can be set to either the name of a template file:
+     * <pre>  $scope.gridOptions.headerTemplate = 'header_template.html';</pre>
+     * inline html 
+     * <pre>  $scope.gridOptions.headerTemplate = '<div class="ui-grid-top-panel" style="text-align: center">I am a Custom Grid Header</div>'</pre>
+     * or the id of a precompiled template (TBD how to use this).  
+     * </br>Refer to the custom header tutorial for more information.
+     * If you want no header at all, you can set to an empty div:
+     * <pre>  $scope.gridOptions.headerTemplate = '<div></div>';</pre>
+     * 
+     * If you want to only have a static header, then you can set to static content.  If
+     * you want to tailor the existing column headers, then you should look at the
+     * current 'ui-grid-header.html' template in github as your starting point.
+     * 
+     */
+    this.headerTemplate = null;
+
+    /**
+     * @ngdoc string
+     * @name footerTemplate
+     * @propertyOf ui.grid.class:GridOptions
+     * @description (optional) Null by default. When provided, this setting uses a custom footer
+     * template. Can be set to either the name of a template file 'footer_template.html', inline html
+     * <pre>'<div class="ui-grid-bottom-panel" style="text-align: center">I am a Custom Grid Footer</div>'</pre>, or the id
+     * of a precompiled template (TBD how to use this).  Refer to the custom footer tutorial for more information.
+     */
+    this.footerTemplate = null;
+
+    /**
+     * @ngdoc string
+     * @name rowTemplate
+     * @propertyOf ui.grid.class:GridOptions
+     * @description 'ui-grid/ui-grid-row' by default. When provided, this setting uses a 
+     * custom row template.  Can be set to either the name of a template file:
+     * <pre> $scope.gridOptions.rowTemplate = 'row_template.html';</pre>
+     * inline html 
+     * <pre>  $scope.gridOptions.rowTemplate = '<div style="background-color: aquamarine" ng-click="getExternalScopes().fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';</pre>
+     * or the id of a precompiled template (TBD how to use this) can be provided.  
+     * </br>Refer to the custom row template tutorial for more information.
+     */
+    this.rowTemplate = 'ui-grid/ui-grid-row';
+  }
+
+  return GridOptions;
+
+}]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+.factory('GridRenderContainer', ['$log', 'gridUtil', function($log, gridUtil) {
+  function GridRenderContainer(name, grid, options) {
+    var self = this;
+
+    // if (gridUtil.type(grid) !== 'Grid') {
+    //   throw new Error('Grid argument is not a Grid object');
+    // }
+
+    self.name = name;
+
+    self.grid = grid;
+    
+    // self.rowCache = [];
+    // self.columnCache = [];
+
+    self.visibleRowCache = [];
+    self.visibleColumnCache = [];
+
+    self.renderedRows = [];
+    self.renderedColumns = [];
+
+    self.prevScrollTop = 0;
+    self.prevScrolltopPercentage = 0;
+    self.prevRowScrollIndex = 0;
+
+    self.prevScrollLeft = 0;
+    self.prevScrollleftPercentage = 0;
+    self.prevColumnScrollIndex = 0;
+
+    self.columnStyles = "";
+
+    self.viewportAdjusters = [];
+
+    if (options && angular.isObject(options)) {
+      angular.extend(self, options);
+    }
+
+    grid.registerStyleComputation({
+      priority: 5,
+      func: function () {
+        return self.columnStyles;
+      }
+    });
+  }
+
+  // GridRenderContainer.prototype.addRenderable = function addRenderable(renderable) {
+  //   this.renderables.push(renderable);
+  // };
+
+  GridRenderContainer.prototype.reset = function reset() {
+    // this.rowCache.length = 0;
+    // this.columnCache.length = 0;
+
+    this.visibleColumnCache.length = 0;
+    this.visibleRowCache.length = 0;
+
+    this.renderedRows.length = 0;
+    this.renderedColumns.length = 0;
+  };
+
+  // TODO(c0bra): calculate size?? Should this be in a stackable directive?
+
+  GridRenderContainer.prototype.minRowsToRender = function minRowsToRender() {
+    var self = this;
+    var minRows = 0;
+    var rowAddedHeight = 0;
+    var viewPortHeight = self.getViewportHeight();
+    for (var i = self.visibleRowCache.length - 1; rowAddedHeight < viewPortHeight && i >= 0; i--) {
+      rowAddedHeight += self.visibleRowCache[i].height;
+      minRows++;
+    }
+    return minRows;
+  };
+
+  GridRenderContainer.prototype.minColumnsToRender = function minColumnsToRender() {
+    var self = this;
+    var viewportWidth = this.getViewportWidth();
+
+    var min = 0;
+    var totalWidth = 0;
+    // self.columns.forEach(function(col, i) {
+    for (var i = 0; i < self.visibleColumnCache.length; i++) {
+      var col = self.visibleColumnCache[i];
+
+      if (totalWidth < viewportWidth) {
+        totalWidth += col.drawnWidth;
+        min++;
+      }
+      else {
+        var currWidth = 0;
+        for (var j = i; j >= i - min; j--) {
+          currWidth += self.visibleColumnCache[j].drawnWidth;
+        }
+        if (currWidth < viewportWidth) {
+          min++;
+        }
+      }
+    }
+
+    return min;
+  };
+
+  GridRenderContainer.prototype.getVisibleRowCount = function getVisibleRowCount() {
+    return this.visibleRowCache.length;
+  };
+
+  GridRenderContainer.prototype.registerViewportAdjuster = function registerViewportAdjuster(func) {
+    this.viewportAdjusters.push(func);
+  };
+
+  GridRenderContainer.prototype.removeViewportAdjuster = function registerViewportAdjuster(func) {
+    var idx = this.viewportAdjusters.indexOf(func);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.viewportAdjusters.splice(idx, 1);
+    }
+  };
+
+  GridRenderContainer.prototype.getViewportAdjustment = function getViewportAdjustment() {
+    var self = this;
+
+    var adjustment = { height: 0, width: 0 };
+
+    self.viewportAdjusters.forEach(function (func) {
+      adjustment = func.call(this, adjustment);
+    });
+
+    return adjustment;
+  };
+
+  GridRenderContainer.prototype.getViewportHeight = function getViewportHeight() {
+    var self = this;
+
+    var headerHeight = (self.headerHeight) ? self.headerHeight : self.grid.headerHeight;
+
+    var viewPortHeight = self.grid.gridHeight - headerHeight - self.grid.footerHeight;
+
+    // Account for native horizontal scrollbar, if present
+    if (typeof(self.horizontalScrollbarHeight) !== 'undefined' && self.horizontalScrollbarHeight !== undefined && self.horizontalScrollbarHeight > 0) {
+      viewPortHeight = viewPortHeight - self.horizontalScrollbarHeight;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortHeight = viewPortHeight + adjustment.height;
+
+    return viewPortHeight;
+  };
+
+  GridRenderContainer.prototype.getViewportWidth = function getViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = self.grid.gridWidth;
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth - self.grid.verticalScrollbarWidth;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortWidth = viewPortWidth + adjustment.width;
+
+    return viewPortWidth;
+  };
+
+  GridRenderContainer.prototype.getHeaderViewportWidth = function getHeaderViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = this.getViewportWidth();
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth + self.grid.verticalScrollbarWidth;
+    }
+
+    // var adjustment = self.getViewportAdjustment();
+    // viewPortWidth = viewPortWidth + adjustment.width;
+
+    return viewPortWidth;
+  };
+
+  GridRenderContainer.prototype.getCanvasHeight = function getCanvasHeight() {
+    var self = this;
+
+    var ret =  0;
+
+    self.visibleRowCache.forEach(function(row){
+      ret += row.height;
+    });
+
+    if (typeof(self.grid.horizontalScrollbarHeight) !== 'undefined' && self.grid.horizontalScrollbarHeight !== undefined && self.grid.horizontalScrollbarHeight > 0) {
+      ret = ret - self.grid.horizontalScrollbarHeight;
+    }
+
+    return ret;
+  };
+
+  GridRenderContainer.prototype.getCanvasWidth = function getCanvasWidth() {
+    var self = this;
+
+    var ret = self.canvasWidth;
+
+    if (typeof(self.verticalScrollbarWidth) !== 'undefined' && self.verticalScrollbarWidth !== undefined && self.verticalScrollbarWidth > 0) {
+      ret = ret - self.verticalScrollbarWidth;
+    }
+
+    return ret;
+  };
+
+  GridRenderContainer.prototype.setRenderedRows = function setRenderedRows(newRows) {
+    this.renderedRows.length = newRows.length;
+    for (var i = 0; i < newRows.length; i++) {
+      this.renderedRows[i] = newRows[i];
+    }
+  };
+
+  GridRenderContainer.prototype.setRenderedColumns = function setRenderedColumns(newColumns) {
+    var self = this;
+
+    // OLD:
+    this.renderedColumns.length = newColumns.length;
+    for (var i = 0; i < newColumns.length; i++) {
+      this.renderedColumns[i] = newColumns[i];
+    }
+    
+    this.updateColumnOffset();
+  };
+
+  GridRenderContainer.prototype.updateColumnOffset = function updateColumnOffset() {
+    // Calculate the width of the columns on the left side that are no longer rendered.
+    //  That will be the offset for the columns as we scroll horizontally.
+    var hiddenColumnsWidth = 0;
+    for (var i = 0; i < this.currentFirstColumn; i++) {
+      hiddenColumnsWidth += this.visibleColumnCache[i].drawnWidth;
+    }
+
+    this.columnOffset = hiddenColumnsWidth;
+  };
+
+  GridRenderContainer.prototype.adjustScrollVertical = function adjustScrollVertical(scrollTop, scrollPercentage, force) {
+    if (this.prevScrollTop === scrollTop && !force) {
+      return;
+    }
+
+    scrollTop = this.getCanvasHeight() * scrollPercentage;
+
+    this.adjustRows(scrollTop, scrollPercentage);
+
+    this.prevScrollTop = scrollTop;
+    this.prevScrolltopPercentage = scrollPercentage;
+
+    this.grid.queueRefresh();
+  };
+
+  GridRenderContainer.prototype.adjustScrollHorizontal = function adjustScrollHorizontal(scrollLeft, scrollPercentage, force) {
+    if (this.prevScrollLeft === scrollLeft && !force) {
+      return;
+    }
+
+    // scrollLeft = uiGridCtrl.canvas[0].scrollWidth * scrollPercentage;
+    scrollLeft = this.getCanvasWidth() * scrollPercentage;
+
+    //$log.debug('scrollPercentage', scrollPercentage);
+
+    this.adjustColumns(scrollLeft, scrollPercentage);
+
+    this.prevScrollLeft = scrollLeft;
+    this.prevScrollleftPercentage = scrollPercentage;
+
+    this.grid.queueRefresh();
+  };
+
+  GridRenderContainer.prototype.adjustRows = function adjustRows(scrollTop, scrollPercentage) {
+    var self = this;
+
+    var minRows = self.minRowsToRender();
+
+    var rowCache = self.visibleRowCache;
+
+    var maxRowIndex = rowCache.length - minRows;
+    self.maxRowIndex = maxRowIndex;
+
+    var curRowIndex = self.prevRowScrollIndex;
+
+    // Calculate the scroll percentage according to the scrollTop location, if no percentage was provided
+    if ((typeof(scrollPercentage) === 'undefined' || scrollPercentage === null) && scrollTop) {
+      scrollPercentage = scrollTop / self.getCanvasHeight();
+    }
+    
+    var rowIndex = Math.ceil(Math.min(maxRowIndex, maxRowIndex * scrollPercentage));
+
+    // Define a max row index that we can't scroll past
+    if (rowIndex > maxRowIndex) {
+      rowIndex = maxRowIndex;
+    }
+    
+    var newRange = [];
+    if (rowCache.length > self.grid.options.virtualizationThreshold) {
+      // Have we hit the threshold going down?
+      if (self.prevScrollTop < scrollTop && rowIndex < self.prevRowScrollIndex + self.grid.options.scrollThreshold && rowIndex < maxRowIndex) {
+        return;
+      }
+      //Have we hit the threshold going up?
+      if (self.prevScrollTop > scrollTop && rowIndex > self.prevRowScrollIndex - self.grid.options.scrollThreshold && rowIndex < maxRowIndex) {
+        return;
+      }
+
+      var rangeStart = Math.max(0, rowIndex - self.grid.options.excessRows);
+      var rangeEnd = Math.min(rowCache.length, rowIndex + minRows + self.grid.options.excessRows);
+
+      newRange = [rangeStart, rangeEnd];
+    }
+    else {
+      var maxLen = self.visibleRowCache.length;
+      newRange = [0, Math.max(maxLen, minRows + self.grid.options.excessRows)];
+    }
+
+    self.updateViewableRowRange(newRange);
+
+    self.prevRowScrollIndex = rowIndex;
+  };
+
+  GridRenderContainer.prototype.adjustColumns = function adjustColumns(scrollLeft, scrollPercentage) {
+    var self = this;
+
+    var minCols = self.minColumnsToRender();
+
+    var columnCache = self.visibleColumnCache;
+    var maxColumnIndex = columnCache.length - minCols;
+
+    // Calculate the scroll percentage according to the scrollTop location, if no percentage was provided
+    if ((typeof(scrollPercentage) === 'undefined' || scrollPercentage === null) && scrollLeft) {
+      scrollPercentage = scrollLeft / self.getCanvasWidth();
+    }
+
+    var colIndex = Math.ceil(Math.min(maxColumnIndex, maxColumnIndex * scrollPercentage));
+
+    // Define a max row index that we can't scroll past
+    if (colIndex > maxColumnIndex) {
+      colIndex = maxColumnIndex;
+    }
+    
+    var newRange = [];
+    if (columnCache.length > self.grid.options.columnVirtualizationThreshold && self.getCanvasWidth() > self.getViewportWidth()) {
+      // Have we hit the threshold going down?
+      if (self.prevScrollLeft < scrollLeft && colIndex < self.prevColumnScrollIndex + self.grid.options.horizontalScrollThreshold && colIndex < maxColumnIndex) {
+        return;
+      }
+      //Have we hit the threshold going up?
+      if (self.prevScrollLeft > scrollLeft && colIndex > self.prevColumnScrollIndex - self.grid.options.horizontalScrollThreshold && colIndex < maxColumnIndex) {
+        return;
+      }
+
+      var rangeStart = Math.max(0, colIndex - self.grid.options.excessColumns);
+      var rangeEnd = Math.min(columnCache.length, colIndex + minCols + self.grid.options.excessColumns);
+
+      newRange = [rangeStart, rangeEnd];
+    }
+    else {
+      var maxLen = self.visibleColumnCache.length;
+
+      newRange = [0, Math.max(maxLen, minCols + self.grid.options.excessColumns)];
+    }
+    
+    self.updateViewableColumnRange(newRange);
+
+    self.prevColumnScrollIndex = colIndex;
+  };
+
+  // Method for updating the visible rows
+  GridRenderContainer.prototype.updateViewableRowRange = function updateViewableRowRange(renderedRange) {
+    // Slice out the range of rows from the data
+    // var rowArr = uiGridCtrl.grid.rows.slice(renderedRange[0], renderedRange[1]);
+    var rowArr = this.visibleRowCache.slice(renderedRange[0], renderedRange[1]);
+
+    // Define the top-most rendered row
+    this.currentTopRow = renderedRange[0];
+
+    // TODO(c0bra): make this method!
+    this.setRenderedRows(rowArr);
+  };
+
+  // Method for updating the visible columns
+  GridRenderContainer.prototype.updateViewableColumnRange = function updateViewableColumnRange(renderedRange) {
+    // Slice out the range of rows from the data
+    // var columnArr = uiGridCtrl.grid.columns.slice(renderedRange[0], renderedRange[1]);
+    var columnArr = this.visibleColumnCache.slice(renderedRange[0], renderedRange[1]);
+
+    // Define the left-most rendered columns
+    this.currentFirstColumn = renderedRange[0];
+
+    this.setRenderedColumns(columnArr);
+  };
+
+  GridRenderContainer.prototype.rowStyle = function (index) {
+    var self = this;
+
+    var styles = {};
+    
+    if (index === 0 && self.currentTopRow !== 0) {
+      // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered
+      var hiddenRowWidth = (self.currentTopRow) * self.grid.options.rowHeight;
+
+      // return { 'margin-top': hiddenRowWidth + 'px' };
+      styles['margin-top'] = hiddenRowWidth + 'px';
+    }
+
+    if (self.currentFirstColumn !== 0) {
+      if (self.grid.isRTL()) {
+        styles['margin-right'] = self.columnOffset + 'px';
+      }
+      else {
+        styles['margin-left'] = self.columnOffset + 'px';
+      }
+    }
+
+    return styles;
+  };
+
+  GridRenderContainer.prototype.columnStyle = function (index) {
+    var self = this;
+    
+    if (index === 0 && self.currentFirstColumn !== 0) {
+      var offset = self.columnOffset;
+
+      if (self.grid.isRTL()) {
+        return { 'margin-right': offset + 'px' };
+      }
+      else {
+        return { 'margin-left': offset + 'px' };
+      }
+    }
+
+    return null;
+  };
+
+  GridRenderContainer.prototype.updateColumnWidths = function () {
+    var self = this;
+
+    var asterisksArray = [],
+        percentArray = [],
+        manualArray = [],
+        asteriskNum = 0,
+        totalWidth = 0;
+
+    // Get the width of the viewport
+    var availableWidth = self.getViewportWidth();
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      availableWidth = availableWidth + self.grid.verticalScrollbarWidth;
+    }
+
+    // The total number of columns
+    // var equalWidthColumnCount = columnCount = uiGridCtrl.grid.options.columnDefs.length;
+    // var equalWidth = availableWidth / equalWidthColumnCount;
+
+    // The last column we processed
+    var lastColumn;
+
+    var manualWidthSum = 0;
+
+    var canvasWidth = 0;
+
+    var ret = '';
+
+
+    // uiGridCtrl.grid.columns.forEach(function(column, i) {
+
+    var columnCache = self.visibleColumnCache;
+
+    columnCache.forEach(function(column, i) {
+      // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; left: ' + left + 'px; }';
+      //var colWidth = (typeof(c.width) !== 'undefined' && c.width !== undefined) ? c.width : equalWidth;
+
+      // Skip hidden columns
+      if (!column.visible) { return; }
+
+      var colWidth,
+          isPercent = false;
+
+      if (!angular.isNumber(column.width)) {
+        isPercent = isNaN(column.width) ? gridUtil.endsWith(column.width, "%") : false;
+      }
+
+      if (angular.isString(column.width) && column.width.indexOf('*') !== -1) { //  we need to save it until the end to do the calulations on the remaining width.
+        asteriskNum = parseInt(asteriskNum + column.width.length, 10);
+        
+        asterisksArray.push(column);
+      }
+      else if (isPercent) { // If the width is a percentage, save it until the very last.
+        percentArray.push(column);
+      }
+      else if (angular.isNumber(column.width)) {
+        manualWidthSum = parseInt(manualWidthSum + column.width, 10);
+        
+        canvasWidth = parseInt(canvasWidth, 10) + parseInt(column.width, 10);
+
+        column.drawnWidth = column.width;
+
+        // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + column.width + 'px; }';
+      }
+    });
+
+    // Get the remaining width (available width subtracted by the manual widths sum)
+    var remainingWidth = availableWidth - manualWidthSum;
+
+    var i, column, colWidth;
+
+    if (percentArray.length > 0) {
+      // Pre-process to make sure they're all within any min/max values
+      for (i = 0; i < percentArray.length; i++) {
+        column = percentArray[i];
+
+        var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+
+        colWidth = parseInt(percent * remainingWidth, 10);
+
+        if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+          colWidth = column.colDef.minWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+          // Remove this element from the percent array so it's not processed below
+          percentArray.splice(i, 1);
+        }
+        else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+          colWidth = column.colDef.maxWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+          // Remove this element from the percent array so it's not processed below
+          percentArray.splice(i, 1);
+        }
+      }
+
+      percentArray.forEach(function(column) {
+        var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+        var colWidth = parseInt(percent * remainingWidth, 10);
+
+        canvasWidth += colWidth;
+
+        column.drawnWidth = colWidth;
+
+        // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+      });
+    }
+
+    if (asterisksArray.length > 0) {
+      var asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+       // Pre-process to make sure they're all within any min/max values
+      for (i = 0; i < asterisksArray.length; i++) {
+        column = asterisksArray[i];
+
+        colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+        if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+          colWidth = column.colDef.minWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+          asteriskNum--;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+          lastColumn = column;
+
+          // Remove this element from the percent array so it's not processed below
+          asterisksArray.splice(i, 1);
+        }
+        else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+          colWidth = column.colDef.maxWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+          asteriskNum--;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+
+          // Remove this element from the percent array so it's not processed below
+          asterisksArray.splice(i, 1);
+        }
+      }
+
+      // Redo the asterisk value, as we may have removed columns due to width constraints
+      asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+      asterisksArray.forEach(function(column) {
+        var colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+        canvasWidth += colWidth;
+
+        column.drawnWidth = colWidth;
+
+        // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + column.index + ' { width: ' + colWidth + 'px; }';
+      });
+    }
+
+    // If the grid width didn't divide evenly into the column widths and we have pixels left over, dole them out to the columns one by one to make everything fit
+    var leftoverWidth = availableWidth - parseInt(canvasWidth, 10);
+
+    if (leftoverWidth > 0 && canvasWidth > 0 && canvasWidth < availableWidth) {
+      var variableColumn = false;
+      // uiGridCtrl.grid.columns.forEach(function(col) {
+      columnCache.forEach(function(col) {
+        if (col.width && !angular.isNumber(col.width)) {
+          variableColumn = true;
+        }
+      });
+
+      if (variableColumn) {
+        var remFn = function (column) {
+          if (leftoverWidth > 0) {
+            column.drawnWidth = column.drawnWidth + 1;
+            canvasWidth = canvasWidth + 1;
+            leftoverWidth--;
+          }
+        };
+        while (leftoverWidth > 0) {
+          columnCache.forEach(remFn);
+        }
+      }
+    }
+
+    if (canvasWidth < availableWidth) {
+      canvasWidth = availableWidth;
+    }
+
+    // Build the CSS
+    columnCache.forEach(function (column) {
+      ret = ret + column.getColClassDefinition();
+    });
+
+    // Add the vertical scrollbar width back in to the canvas width, it's taken out in getCanvasWidth
+    if (self.grid.verticalScrollbarWidth) {
+      canvasWidth = canvasWidth + self.grid.verticalScrollbarWidth;
+    }
+    // canvasWidth = canvasWidth + 1;
+
+    self.canvasWidth = parseInt(canvasWidth, 10);
+
+    // Return the styles back to buildStyles which pops them into the `customStyles` scope variable
+    // return ret;
+
+    // Set this render container's column styles so they can be used in style computation
+    this.columnStyles = ret;
+  };
+
+  return GridRenderContainer;
+}]);
+
+})();
+(function(){
+
+angular.module('ui.grid')
+.factory('GridRow', ['gridUtil', function(gridUtil) {
+
+   /**
+   * @ngdoc function
+   * @name ui.grid.class:GridRow
+   * @description GridRow is the viewModel for one logical row on the grid.  A grid Row is not necessarily a one-to-one
+   * relation to gridOptions.data.
+   * @param {object} entity the array item from GridOptions.data
+   * @param {number} index the current position of the row in the array
+   * @param {Grid} reference to the parent grid
+   */
+  function GridRow(entity, index, grid) {
+
+     /**
+      *  @ngdoc object
+      *  @name grid
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description A reference back to the grid
+      */
+     this.grid = grid;
+
+     /**
+      *  @ngdoc object
+      *  @name entity
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description A reference to an item in gridOptions.data[]
+      */
+    this.entity = entity;
+
+     /**
+      *  @ngdoc object
+      *  @name index
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description the index of the GridRow. It should always be unique and immutable
+      */
+    this.index = index;
+
+
+     /**
+      *  @ngdoc object
+      *  @name uid
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description  UniqueId of row
+      */
+     this.uid = gridUtil.nextUid();
+
+     /**
+      *  @ngdoc object
+      *  @name visible
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description If true, the row will be rendered
+      */
+    // Default to true
+    this.visible = true;
+
+  /**
+    *  @ngdoc object
+    *  @name height
+    *  @propertyOf  ui.grid.class:GridRow
+    *  @description height of each individual row
+    */
+    this.height = grid.options.rowHeight;
+
+    /**
+     * @ngdoc function
+     * @name setRowInvisible
+     * @methodOf  ui.grid.core.api:PublicApi
+     * @description Sets an override on the row to make it always invisible,
+     * which will override any filtering or other visibility calculations.  
+     * If the row is currently visible then sets it to invisible and calls
+     * both grid refresh and emits the rowsVisibleChanged event
+     * @param {object} rowEntity gridOptions.data[] array instance
+     */
+    if (!this.grid.api.core.setRowInvisible){
+      this.grid.api.registerMethod( 'core', 'setRowInvisible', this.setRowInvisible );
+    }
+
+    /**
+     * @ngdoc function
+     * @name clearRowInvisible
+     * @methodOf  ui.grid.core.api:PublicApi
+     * @description Clears any override on visibility for the row so that it returns to 
+     * using normal filtering and other visibility calculations.  
+     * If the row is currently invisible then sets it to visible and calls
+     * both grid refresh and emits the rowsVisibleChanged event
+     * TODO: if a filter is active then we can't just set it to visible?
+     * @param {object} rowEntity gridOptions.data[] array instance
+     */
+    if (!this.grid.api.core.clearRowInvisible){
+      this.grid.api.registerMethod( 'core', 'clearRowInvisible', this.clearRowInvisible );
+    }
+
+    /**
+     * @ngdoc function
+     * @name getVisibleRows
+     * @methodOf  ui.grid.core.api:PublicApi
+     * @description Returns all visible rows
+     * @param {Grid} grid the grid you want to get visible rows from
+     * @returns {array} an array of gridRow 
+     */
+    if (!this.grid.api.core.getVisibleRows){
+      this.grid.api.registerMethod( 'core', 'getVisibleRows', this.getVisibleRows );
+    }
+    
+    /**
+     * @ngdoc event
+     * @name rowsVisibleChanged
+     * @eventOf  ui.grid.core.api:PublicApi
+     * @description  is raised after the rows that are visible
+     * change.  The filtering is zero-based, so it isn't possible
+     * to say which rows changed (unlike in the selection feature).
+     * We can plausibly know which row was changed when setRowInvisible
+     * is called, but in that situation the user already knows which row
+     * they changed.  When a filter runs we don't know what changed, 
+     * and that is the one that would have been useful.
+     * 
+     */
+    if (!this.grid.api.core.raise.rowsVisibleChanged){
+      this.grid.api.registerEvent( 'core', 'rowsVisibleChanged' );
+    }
+    
+  }
+
+  /**
+   * @ngdoc function
+   * @name getQualifiedColField
+   * @methodOf ui.grid.class:GridRow
+   * @description returns the qualified field name as it exists on scope
+   * ie: row.entity.fieldA
+   * @param {GridCol} col column instance
+   * @returns {string} resulting name that can be evaluated on scope
+   */
+  GridRow.prototype.getQualifiedColField = function(col) {
+    return 'row.' + this.getEntityQualifiedColField(col);
+  };
+
+    /**
+     * @ngdoc function
+     * @name getEntityQualifiedColField
+     * @methodOf ui.grid.class:GridRow
+     * @description returns the qualified field name minus the row path
+     * ie: entity.fieldA
+     * @param {GridCol} col column instance
+     * @returns {string} resulting name that can be evaluated against a row
+     */
+  GridRow.prototype.getEntityQualifiedColField = function(col) {
+    return gridUtil.preEval('entity.' + col.field);
+  };
+  
+  
+  /**
+   * @ngdoc function
+   * @name setRowInvisible
+   * @methodOf  ui.grid.class:GridRow
+   * @description Sets an override on the row that forces it to always
+   * be invisible, and if the row is currently visible then marks it
+   * as invisible and refreshes the grid.  Emits the rowsVisibleChanged
+   * event if it changed the row visibility
+   * @param {GridRow} row row to force invisible, needs to be a GridRow,
+   * which can be found from your data entity using grid.findRow
+   */
+  GridRow.prototype.setRowInvisible = function (row) {
+    if (row !== null) {
+      row.forceInvisible = true;
+      
+      if ( row.visible ){
+        row.visible = false;
+        row.grid.refresh();
+        row.grid.api.core.raise.rowsVisibleChanged();
+      }
+    }        
+  };
+
+  /**
+   * @ngdoc function
+   * @name clearRowInvisible
+   * @methodOf ui.grid.class:GridRow
+   * @description Clears any override on the row visibility, returning it 
+   * to normal visibility calculations.  If the row is currently invisible
+   * then sets it to visible and calls refresh and emits the rowsVisibleChanged
+   * event
+   * TODO: if filter in action, then is this right?
+   * @param {GridRow} row row clear force invisible, needs to be a GridRow,
+   * which can be found from your data entity using grid.findRow
+   */
+  GridRow.prototype.clearRowInvisible = function (row) {
+    if (row !== null) {
+      row.forceInvisible = false;
+      
+      if ( !row.visible ){
+        row.visible = true;
+        row.grid.refresh();
+        row.grid.api.core.raise.rowsVisibleChanged();
+      }
+    }        
+  };
+
+  /**
+   * @ngdoc function
+   * @name getVisibleRows
+   * @methodOf ui.grid.class:GridRow
+   * @description Returns all the visible rows
+   * @param {Grid} grid the grid to return rows from
+   * @returns {array} rows that are currently visible, returns the
+   * GridRows rather than gridRow.entity
+   * TODO: should this come from visible row cache instead?
+   */
+  GridRow.prototype.getVisibleRows = function ( grid ) {
+    return grid.rows.filter(function (row) {
+      return row.visible;
+    });
+  };  
+
+  return GridRow;
+}]);
+
+})();
+(function () {
+  'use strict';
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.service:gridClassFactory
+   *
+   *  @description factory to return dom specific instances of a grid
+   *
+   */
+  angular.module('ui.grid').service('gridClassFactory', ['gridUtil', '$q', '$compile', '$templateCache', 'uiGridConstants', '$log', 'Grid', 'GridColumn', 'GridRow',
+    function (gridUtil, $q, $compile, $templateCache, uiGridConstants, $log, Grid, GridColumn, GridRow) {
+
+      var service = {
+        /**
+         * @ngdoc method
+         * @name createGrid
+         * @methodOf ui.grid.service:gridClassFactory
+         * @description Creates a new grid instance. Each instance will have a unique id
+         * @param {object} options An object map of options to pass into the created grid instance.
+         * @returns {Grid} grid
+         */
+        createGrid : function(options) {
+          options = (typeof(options) !== 'undefined') ? options: {};
+          options.id = gridUtil.newId();
+          var grid = new Grid(options);
+
+          // NOTE/TODO: rowTemplate should always be defined...
+          if (grid.options.rowTemplate) {
+            var rowTemplateFnPromise = $q.defer();
+            grid.getRowTemplateFn = rowTemplateFnPromise.promise;
+            
+            gridUtil.getTemplate(grid.options.rowTemplate)
+              .then(
+                function (template) {
+                  var rowTemplateFn = $compile(template);
+                  rowTemplateFnPromise.resolve(rowTemplateFn);
+                },
+                function (res) {
+                  // Todo handle response error here?
+                  throw new Error("Couldn't fetch/use row template '" + grid.options.rowTemplate + "'");
+                });
+          }
+
+          grid.registerColumnBuilder(service.defaultColumnBuilder);
+
+          // Reset all rows to visible initially
+          grid.registerRowsProcessor(function allRowsVisible(rows) {
+            rows.forEach(function (row) {
+              row.visible = !row.forceInvisible;
+            });
+
+            return rows;
+          });
+
+          grid.registerColumnsProcessor(function allColumnsVisible(columns) {
+            columns.forEach(function (column) {
+              column.visible = true;
+            });
+
+            return columns;
+          });
+
+          grid.registerColumnsProcessor(function(renderableColumns) {
+              renderableColumns.forEach(function (column) {
+                  if (column.colDef.visible === false) {
+                      column.visible = false;
+                  }
+              });
+
+              return renderableColumns;
+          });
+
+
+
+          if (grid.options.enableFiltering) {
+            grid.registerRowsProcessor(grid.searchRows);
+          }
+
+          // Register the default row processor, it sorts rows by selected columns
+          if (grid.options.externalSort && angular.isFunction(grid.options.externalSort)) {
+            grid.registerRowsProcessor(grid.options.externalSort);
+          }
+          else {
+            grid.registerRowsProcessor(grid.sortByColumn);
+          }
+
+          return grid;
+        },
+
+        /**
+         * @ngdoc function
+         * @name defaultColumnBuilder
+         * @methodOf ui.grid.service:gridClassFactory
+         * @description Processes designTime column definitions and applies them to col for the
+         *              core grid features
+         * @param {object} colDef reference to column definition
+         * @param {GridColumn} col reference to gridCol
+         * @param {object} gridOptions reference to grid options
+         */
+        defaultColumnBuilder: function (colDef, col, gridOptions) {
+
+          var templateGetPromises = [];
+
+          /**
+           * @ngdoc property
+           * @name headerCellTemplate
+           * @propertyOf ui.grid.class:GridOptions.columnDef
+           * @description a custom template for the header for this column.  The default
+           * is ui-grid/uiGridHeaderCell
+           *
+           */
+          if (!colDef.headerCellTemplate) {
+            colDef.headerCellTemplate = 'ui-grid/uiGridHeaderCell';
+          }
+
+          /**
+           * @ngdoc property
+           * @name cellTemplate
+           * @propertyOf ui.grid.class:GridOptions.columnDef
+           * @description a custom template for each cell in this column.  The default
+           * is ui-grid/uiGridCell
+           *
+           */
+          if (!colDef.cellTemplate) {
+            colDef.cellTemplate = 'ui-grid/uiGridCell';
+          }
+
+          templateGetPromises.push(gridUtil.getTemplate(colDef.cellTemplate)
+            .then(
+              function (template) {
+                col.cellTemplate = template.replace(uiGridConstants.CUSTOM_FILTERS, col.cellFilter ? "|" + col.cellFilter : "");
+              },
+              function (res) {
+                throw new Error("Couldn't fetch/use colDef.cellTemplate '" + colDef.cellTemplate + "'");
+              })
+          );
+
+
+          templateGetPromises.push(gridUtil.getTemplate(colDef.headerCellTemplate)
+              .then(
+              function (template) {
+                col.headerCellTemplate = template.replace(uiGridConstants.CUSTOM_FILTERS, col.headerCellFilter ? "|" + col.headerCellFilter : "");
+              },
+              function (res) {
+                throw new Error("Couldn't fetch/use colDef.headerCellTemplate '" + colDef.headerCellTemplate + "'");
+              })
+          );
+
+          return $q.all(templateGetPromises);
+        }
+
+      };
+
+      //class definitions (moved to separate factories)
+
+      return service;
+    }]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+function escapeRegExp(str) {
+  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+}
+
+function QuickCache() {
+  var c = function(get, set) {
+    // Return the cached value of 'get' if it's stored
+    if (get && c.cache[get]) {
+      return c.cache[get];
+    }
+    // Otherwise set it and return it
+    else if (get && set) {
+      c.cache[get] = set;
+      return c.cache[get];
+    }
+    else {
+      return undefined;
+    }
+  };
+
+  c.cache = {};
+
+  c.clear = function () {
+    c.cache = {};
+  };
+
+  return c;
+}
+
+/**
+ *  @ngdoc service
+ *  @name ui.grid.service:rowSearcher
+ *
+ *  @description Service for searching/filtering rows based on column value conditions.
+ */
+module.service('rowSearcher', ['$log', 'uiGridConstants', function ($log, uiGridConstants) {
+  var defaultCondition = uiGridConstants.filter.STARTS_WITH;
+
+  var rowSearcher = {};
+
+  // rowSearcher.searchColumn = function searchColumn(condition, item) {
+  //   var result;
+
+  //   var col = self.fieldMap[condition.columnDisplay];
+
+  //   if (!col) {
+  //       return false;
+  //   }
+  //   var sp = col.cellFilter.split(':');
+  //   var filter = col.cellFilter ? $filter(sp[0]) : null;
+  //   var value = item[condition.column] || item[col.field.split('.')[0]];
+  //   if (value === null || value === undefined) {
+  //       return false;
+  //   }
+  //   if (typeof filter === "function") {
+  //       var filterResults = filter(typeof value === "object" ? evalObject(value, col.field) : value, sp[1]).toString();
+  //       result = condition.regex.test(filterResults);
+  //   }
+  //   else {
+  //       result = condition.regex.test(typeof value === "object" ? evalObject(value, col.field).toString() : value.toString());
+  //   }
+  //   if (result) {
+  //       return true;
+  //   }
+  //   return false;
+  // };
+
+  /**
+   * @ngdoc function
+   * @name getTerm
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Get the term from a filter
+   * Trims leading and trailing whitespace
+   * @param {object} filter object to use
+   * @returns {object} Parsed term
+   */
+  rowSearcher.getTerm = function getTerm(filter) {
+    if (typeof(filter.term) === 'undefined') { return filter.term; }
+    
+    var term = filter.term;
+
+    // Strip leading and trailing whitespace if the term is a string
+    if (typeof(term) === 'string') {
+      term = term.trim();
+    }
+
+    return term;
+  };
+
+  /**
+   * @ngdoc function
+   * @name stripTerm
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Remove leading and trailing asterisk (*) from the filter's term
+   * @param {object} filter object to use
+   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
+   */
+  rowSearcher.stripTerm = function stripTerm(filter) {
+    var term = rowSearcher.getTerm(filter);
+
+    if (typeof(term) === 'string') {
+      return escapeRegExp(term.replace(/(^\*|\*$)/g, ''));
+    }
+    else {
+      return term;
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name guessCondition
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Guess the condition for a filter based on its term
+   * <br>
+   * Defaults to STARTS_WITH. Uses CONTAINS for strings beginning and ending with *s (*bob*).
+   * Uses STARTS_WITH for strings ending with * (bo*). Uses ENDS_WITH for strings starting with * (*ob).
+   * @param {object} filter object to use
+   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
+   */
+  rowSearcher.guessCondition = function guessCondition(filter) {
+    if (typeof(filter.term) === 'undefined' || !filter.term) {
+      return defaultCondition;
+    }
+
+    var term = rowSearcher.getTerm(filter);
+    
+    // Term starts with and ends with a *, use 'contains' condition
+    // if (/^\*[\s\S]+?\*$/.test(term)) {
+    //   return uiGridConstants.filter.CONTAINS;
+    // }
+    // // Term starts with a *, use 'ends with' condition
+    // else if (/^\*/.test(term)) {
+    //   return uiGridConstants.filter.ENDS_WITH;
+    // }
+    // // Term ends with a *, use 'starts with' condition
+    // else if (/\*$/.test(term)) {
+    //   return uiGridConstants.filter.STARTS_WITH;
+    // }
+    // // Default to default condition
+    // else {
+    //   return defaultCondition;
+    // }
+
+    // If the term has *s then turn it into a regex
+    if (/\*/.test(term)) {
+      var regexpFlags = '';
+      if (!filter.flags || !filter.flags.caseSensitive) {
+        regexpFlags += 'i';
+      }
+
+      var reText = term.replace(/(\\)?\*/g, function ($0, $1) { return $1 ? $0 : '[\\s\\S]*?'; });
+      return new RegExp('^' + reText + '$', regexpFlags);
+    }
+    // Otherwise default to default condition
+    else {
+      return defaultCondition;
+    }
+  };
+
+  rowSearcher.runColumnFilter = function runColumnFilter(grid, row, column, termCache, i, filter) {
+    // Cache typeof condition
+    var conditionType = typeof(filter.condition);
+
+    // Default to CONTAINS condition
+    if (conditionType === 'undefined' || !filter.condition) {
+      filter.condition = uiGridConstants.filter.CONTAINS;
+    }
+
+    // Term to search for.
+    var term = rowSearcher.stripTerm(filter);
+
+    if (term === null || term === undefined || term === '') {
+      return true;
+    }
+
+    // Get the column value for this row
+    var value = grid.getCellValue(row, column);
+
+    var regexpFlags = '';
+    if (!filter.flags || !filter.flags.caseSensitive) {
+      regexpFlags += 'i';
+    }
+
+    var cacheId = column.field + i;
+
+    // If the filter's condition is a RegExp, then use it
+    if (filter.condition instanceof RegExp) {
+      if (!filter.condition.test(value)) {
+        return false;
+      }
+    }
+    // If the filter's condition is a function, run it
+    else if (conditionType === 'function') {
+      return filter.condition(term, value, row, column);
+    }
+    else if (filter.condition === uiGridConstants.filter.STARTS_WITH) {
+      var startswithRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp('^' + term, regexpFlags));
+
+      if (!startswithRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.ENDS_WITH) {
+      var endswithRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp(term + '$', regexpFlags));
+
+      if (!endswithRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.CONTAINS) {
+      var containsRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp(term, regexpFlags));
+
+      if (!containsRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.EXACT) {
+      var exactRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId,  new RegExp('^' + term + '$', regexpFlags));
+
+      if (!exactRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.GREATER_THAN) {
+      if (value <= term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.GREATER_THAN_OR_EQUAL) {
+      if (value < term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.LESS_THAN) {
+      if (value >= term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.LESS_THAN_OR_EQUAL) {
+      if (value > term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.NOT_EQUAL) {
+      if (!angular.equals(value, term)) {
+        return false;
+      }
+    }
+
+    return true;
+  };
+
+  /**
+   * @ngdoc boolean
+   * @name useExternalFiltering
+   * @propertyOf ui.grid.class:GridOptions
+   * @description False by default. When enabled, this setting suppresses the internal filtering.
+   * All UI logic will still operate, allowing filter conditions to be set and modified.
+   * 
+   * The external filter logic can listen for the `filterChange` event, which fires whenever
+   * a filter has been adjusted.
+   */
+  /**
+   * @ngdoc function
+   * @name searchColumn
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Process filters on a given column against a given row. If the row meets the conditions on all the filters, return true.
+   * @param {Grid} grid Grid to search in
+   * @param {GridRow} row Row to search on
+   * @param {GridCol} column Column with the filters to use
+   * @returns {boolean} Whether the column matches or not.
+   */
+  rowSearcher.searchColumn = function searchColumn(grid, row, column, termCache) {
+    var filters = [];
+
+    if (grid.options.useExternalFiltering) {
+      return true;
+    }
+    
+    if (typeof(column.filters) !== 'undefined' && column.filters && column.filters.length > 0) {
+      filters = column.filters;
+    } else {
+      // If filters array is not there, assume no filters for this column. 
+      // This array should have been built in GridColumn::updateColumnDef.
+      return true;
+    }
+    
+    for (var i in filters) {
+      var filter = filters[i];
+
+      /*
+        filter: {
+          term: 'blah', // Search term to search for, could be a string, integer, etc.
+          condition: uiGridConstants.filter.CONTAINS // Type of match to do. Defaults to CONTAINS (i.e. looking in a string), but could be EXACT, GREATER_THAN, etc.
+          flags: { // Flags for the conditions
+            caseSensitive: false // Case-sensitivity defaults to false
+          }
+        }
+      */
+     
+      // Check for when no condition is supplied. In this case, guess the condition
+      // to use based on the filter's term. Cache this result.
+      if (!filter.condition) {
+        // Cache custom conditions, building the RegExp takes time
+        var conditionCacheId = 'cond-' + column.field + '-' + filter.term;
+        var condition = termCache(conditionCacheId) ? termCache(conditionCacheId) : termCache(conditionCacheId, rowSearcher.guessCondition(filter));
+
+        // Create a surrogate filter so as not to change
+        // the actual columnDef.filters.
+        filter = {
+          // Copy over the search term
+          term: filter.term,
+          // Use the guessed condition
+          condition: condition,
+          // Set flags, using passed flags if present
+          flags: angular.extend({
+            caseSensitive: false
+          }, filter.flags)
+        };
+      }
+
+      var ret = rowSearcher.runColumnFilter(grid, row, column, termCache, i, filter);
+      if (!ret) {
+        return false;
+      }
+    }
+
+    return true;
+    // }
+    // else {
+    //   // No filter conditions, default to true
+    //   return true;
+    // }
+  };
+
+  /**
+   * @ngdoc function
+   * @name search
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Run a search across
+   * @param {Grid} grid Grid instance to search inside
+   * @param {Array[GridRow]} rows GridRows to filter
+   * @param {Array[GridColumn]} columns GridColumns with filters to process
+   */
+  rowSearcher.search = function search(grid, rows, columns) {
+    // Don't do anything if we weren't passed any rows
+    if (!rows) {
+      return;
+    }
+
+    // Create a term cache
+    var termCache = new QuickCache();
+
+    // Build filtered column list
+    var filterCols = [];
+    columns.forEach(function (col) {
+      if (typeof(col.filters) !== 'undefined' && col.filters.length > 0) {
+        filterCols.push(col);
+      }
+      else if (typeof(col.filter) !== 'undefined' && col.filter && typeof(col.filter.term) !== 'undefined' && col.filter.term) {
+        filterCols.push(col);
+      }
+    });
+    
+    if (filterCols.length > 0) {
+      filterCols.forEach(function foreachFilterCol(col) {
+        rows.forEach(function foreachRow(row) {
+          if (row.forceInvisible || !rowSearcher.searchColumn(grid, row, col, termCache)) {
+            row.visible = false;
+          }
+        });
+      });
+      
+      grid.api.core.raise.rowsVisibleChanged();
+
+      // rows.forEach(function (row) {
+      //   var matchesAllColumns = true;
+
+      //   for (var i in filterCols) {
+      //     var col = filterCols[i];
+
+      //     if (!rowSearcher.searchColumn(grid, row, col, termCache)) {
+      //       matchesAllColumns = false;
+
+      //       // Stop processing other terms
+      //       break;
+      //     }
+      //   }
+
+      //   // Row doesn't match all the terms, don't display it
+      //   if (!matchesAllColumns) {
+      //     row.visible = false;
+      //   }
+      //   else {
+      //     row.visible = true;
+      //   }
+      // });
+    }
+
+    // Reset the term cache
+    termCache.clear();
+
+    return rows;
+  };
+
+  return rowSearcher;
+}]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+/**
+ * @ngdoc object
+ * @name ui.grid.class:RowSorter
+ * @description RowSorter provides the default sorting mechanisms, 
+ * including guessing column types and applying appropriate sort 
+ * algorithms
+ * 
+ */ 
+
+module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGridConstants) {
+  var currencyRegexStr = 
+    '(' +
+    uiGridConstants.CURRENCY_SYMBOLS
+      .map(function (a) { return '\\' + a; }) // Escape all the currency symbols ($ at least will jack up this regex)
+      .join('|') + // Join all the symbols together with |s
+    ')?';
+
+  // /^[-+]?[£$¤¥]?[\d,.]+%?$/
+  var numberStrRegex = new RegExp('^[-+]?' + currencyRegexStr + '[\\d,.]+' + currencyRegexStr + '%?$');
+
+  var rowSorter = {
+    // Cache of sorting functions. Once we create them, we don't want to keep re-doing it
+    //   this takes a piece of data from the cell and tries to determine its type and what sorting
+    //   function to use for it
+    colSortFnCache: []
+  };
+
+  // Guess which sort function to use on this item
+  rowSorter.guessSortFn = function guessSortFn(itemType) {
+
+    // Check for numbers and booleans
+    switch (itemType) {
+      case "number":
+        return rowSorter.sortNumber;
+      case "boolean":
+        return rowSorter.sortBool;
+      case "string":
+        return rowSorter.sortAlpha;
+      case "date":
+        return rowSorter.sortDate;
+      case "object":
+        return rowSorter.basicSort;
+      default:
+        throw new Error('No sorting function found for type:' + itemType);
+    }
+  };
+
+  // Basic sorting function
+  rowSorter.basicSort = function basicSort(a, b) {
+      if (a === b) {
+          return 0;
+      }
+      if (a < b) {
+          return -1;
+      }
+      return 1;
+  };
+
+  // Number sorting function
+  rowSorter.sortNumber = function sortNumber(a, b) {
+      return a - b;
+  };
+
+  rowSorter.sortNumberStr = function sortNumberStr(a, b) {
+    var numA, // The parsed number form of 'a'
+        numB, // The parsed number form of 'b'
+        badA = false,
+        badB = false;
+
+    // Try to parse 'a' to a float
+    numA = parseFloat(a.replace(/[^0-9.-]/g, ''));
+
+    // If 'a' couldn't be parsed to float, flag it as bad
+    if (isNaN(numA)) {
+        badA = true;
+    }
+
+    // Try to parse 'b' to a float
+    numB = parseFloat(b.replace(/[^0-9.-]/g, ''));
+
+    // If 'b' couldn't be parsed to float, flag it as bad
+    if (isNaN(numB)) {
+        badB = true;
+    }
+
+    // We want bad ones to get pushed to the bottom... which effectively is "greater than"
+    if (badA && badB) {
+        return 0;
+    }
+
+    if (badA) {
+        return 1;
+    }
+
+    if (badB) {
+        return -1;
+    }
+
+    return numA - numB;
+  };
+
+  // String sorting function
+  rowSorter.sortAlpha = function sortAlpha(a, b) {
+    var strA = a.toLowerCase(),
+        strB = b.toLowerCase();
+
+    return strA === strB ? 0 : (strA < strB ? -1 : 1);
+  };
+
+  // Date sorting function
+  rowSorter.sortDate = function sortDate(a, b) {
+    var timeA = a.getTime(),
+        timeB = b.getTime();
+
+    return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1);
+  };
+
+  // Boolean sorting function
+  rowSorter.sortBool = function sortBool(a, b) {
+    if (a && b) {
+      return 0;
+    }
+
+    if (!a && !b) {
+      return 0;
+    }
+    else {
+      return a ? 1 : -1;
+    }
+  };
+
+  rowSorter.getSortFn = function getSortFn(grid, col, rows) {
+    var sortFn, item;
+
+    // See if we already figured out what to use to sort the column and have it in the cache
+    if (rowSorter.colSortFnCache[col.colDef.name]) {
+      sortFn = rowSorter.colSortFnCache[col.colDef.name];
+    }
+    // If the column has its OWN sorting algorithm, use that
+    else if (col.sortingAlgorithm !== undefined) {
+      sortFn = col.sortingAlgorithm;
+      rowSorter.colSortFnCache[col.colDef.name] = col.sortingAlgorithm;
+    }
+    // Try and guess what sort function to use
+    else {
+      // Guess the sort function
+      sortFn = rowSorter.guessSortFn(col.colDef.type);
+
+      // If we found a sort function, cache it
+      if (sortFn) {
+        rowSorter.colSortFnCache[col.colDef.name] = sortFn;
+      }
+      else {
+        // We assign the alpha sort because anything that is null/undefined will never get passed to
+        // the actual sorting function. It will get caught in our null check and returned to be sorted
+        // down to the bottom
+        sortFn = rowSorter.sortAlpha;
+      }
+    }
+
+    return sortFn;
+  };
+
+  rowSorter.prioritySort = function (a, b) {
+    // Both columns have a sort priority
+    if (a.sort.priority !== undefined && b.sort.priority !== undefined) {
+      // A is higher priority
+      if (a.sort.priority < b.sort.priority) {
+        return -1;
+      }
+      // Equal
+      else if (a.sort.priority === b.sort.priority) {
+        return 0;
+      }
+      // B is higher
+      else {
+        return 1;
+      }
+    }
+    // Only A has a priority
+    else if (a.sort.priority) {
+      return -1;
+    }
+    // Only B has a priority
+    else if (b.sort.priority) {
+      return 1;
+    }
+    // Neither has a priority
+    else {
+      return 0;
+    }
+  };
+
+  /**
+   * @ngdoc object
+   * @name useExternalSorting
+   * @propertyOf ui.grid.class:GridOptions
+   * @description Prevents the internal sorting from executing.  Events will
+   * still be fired when the sort changes, and the sort information on
+   * the columns will be updated, allowing an external sorter (for example,
+   * server sorting) to be implemented.  Defaults to false. 
+   * 
+   */
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sort
+   * @description sorts the grid 
+   * @param {Object} grid the grid itself
+   * @param {Object} rows the rows to be sorted
+   * @param {Object} columns the columns in which to look
+   * for sort criteria
+   */
+  rowSorter.sort = function rowSorterSort(grid, rows, columns) {
+    // first make sure we are even supposed to do work
+    if (!rows) {
+      return;
+    }
+    
+    if (grid.options.useExternalSorting){
+      return rows;
+    }
+
+    // Build the list of columns to sort by
+    var sortCols = [];
+    columns.forEach(function (col) {
+      if (col.sort && col.sort.direction && (col.sort.direction === uiGridConstants.ASC || col.sort.direction === uiGridConstants.DESC)) {
+        sortCols.push(col);
+      }
+    });
+
+    // Sort the "sort columns" by their sort priority
+    sortCols = sortCols.sort(rowSorter.prioritySort);
+
+    // Now rows to sort by, maintain original order
+    if (sortCols.length === 0) {
+      return rows;
+    }
+    
+    // Re-usable variables
+    var col, direction;
+
+    // IE9-11 HACK.... the 'rows' variable would be empty where we call rowSorter.getSortFn(...) below. We have to use a separate reference
+    // var d = data.slice(0);
+    var r = rows.slice(0);
+
+    // Now actually sort the data
+    return rows.sort(function rowSortFn(rowA, rowB) {
+      var tem = 0,
+          idx = 0,
+          sortFn;
+
+      while (tem === 0 && idx < sortCols.length) {
+        // grab the metadata for the rest of the logic
+        col = sortCols[idx];
+        direction = sortCols[idx].sort.direction;
+
+        sortFn = rowSorter.getSortFn(grid, col, r);
+        
+        var propA = grid.getCellValue(rowA, col);
+        var propB = grid.getCellValue(rowB, col);
+
+        // We want to allow zero values to be evaluated in the sort function
+        if ((!propA && propA !== 0) || (!propB && propB !== 0)) {
+          // We want to force nulls and such to the bottom when we sort... which effectively is "greater than"
+          if (!propB && !propA) {
+            tem = 0;
+          }
+          else if (!propA) {
+            tem = 1;
+          }
+          else if (!propB) {
+            tem = -1;
+          }
+        }
+        else {
+          tem = sortFn(propA, propB);
+        }
+
+        idx++;
+      }
+
+      // Made it this far, we don't have to worry about null & undefined
+      if (direction === uiGridConstants.ASC) {
+        return tem;
+      } else {
+        return 0 - tem;
+      }
+    });
+  };
+
+  return rowSorter;
+}]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+
+function getStyles (elem) {
+  return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
+}
+
+var rnumnonpx = new RegExp( "^(" + (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source + ")(?!px)[a-z%]+$", "i" ),
+    // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+    rdisplayswap = /^(block|none|table(?!-c[ea]).+)/,
+    cssShow = { position: "absolute", visibility: "hidden", display: "block" };
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+  var i = extra === ( isBorderBox ? 'border' : 'content' ) ?
+          // If we already have the right measurement, avoid augmentation
+          4 :
+          // Otherwise initialize for horizontal or vertical properties
+          name === 'width' ? 1 : 0,
+
+          val = 0;
+
+  var sides = ['Top', 'Right', 'Bottom', 'Left'];
+  
+  for ( ; i < 4; i += 2 ) {
+    var side = sides[i];
+    // dump('side', side);
+
+    // both box models exclude margin, so add it if we want it
+    if ( extra === 'margin' ) {
+      var marg = parseFloat(styles[extra + side]);
+      if (!isNaN(marg)) {
+        val += marg;
+      }
+    }
+    // dump('val1', val);
+
+    if ( isBorderBox ) {
+      // border-box includes padding, so remove it if we want content
+      if ( extra === 'content' ) {
+        var padd = parseFloat(styles['padding' + side]);
+        if (!isNaN(padd)) {
+          val -= padd;
+          // dump('val2', val);
+        }
+      }
+
+      // at this point, extra isn't border nor margin, so remove border
+      if ( extra !== 'margin' ) {
+        var bordermarg = parseFloat(styles['border' + side + 'Width']);
+        if (!isNaN(bordermarg)) {
+          val -= bordermarg;
+          // dump('val3', val);
+        }
+      }
+    }
+    else {
+      // at this point, extra isn't content, so add padding
+      var nocontentPad = parseFloat(styles['padding' + side]);
+      if (!isNaN(nocontentPad)) {
+        val += nocontentPad;
+        // dump('val4', val);
+      }
+
+      // at this point, extra isn't content nor padding, so add border
+      if ( extra !== 'padding') {
+        var nocontentnopad = parseFloat(styles['border' + side + 'Width']);
+        if (!isNaN(nocontentnopad)) {
+          val += nocontentnopad;
+          // dump('val5', val);
+        }
+      }
+    }
+  }
+
+  // dump('augVal', val);
+
+  return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+  // Start with offset property, which is equivalent to the border-box value
+  var valueIsBorderBox = true,
+          val = name === 'width' ? elem.offsetWidth : elem.offsetHeight,
+          styles = getStyles(elem),
+          isBorderBox = styles['boxSizing'] === 'border-box';
+
+  // some non-html elements return undefined for offsetWidth, so check for null/undefined
+  // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+  // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+  if ( val <= 0 || val == null ) {
+    // Fall back to computed then uncomputed css if necessary
+    val = styles[name];
+    if ( val < 0 || val == null ) {
+      val = elem.style[ name ];
+    }
+
+    // Computed unit is not pixels. Stop here and return.
+    if ( rnumnonpx.test(val) ) {
+      return val;
+    }
+
+    // we need the check for style in case a browser which returns unreliable values
+    // for getComputedStyle silently falls back to the reliable elem.style
+    valueIsBorderBox = isBorderBox &&
+            ( true || val === elem.style[ name ] ); // use 'true' instead of 'support.boxSizingReliable()'
+
+    // Normalize "", auto, and prepare for extra
+    val = parseFloat( val ) || 0;
+  }
+
+  // use the active box-sizing model to add/subtract irrelevant styles
+  var ret = ( val +
+    augmentWidthOrHeight(
+      elem,
+      name,
+      extra || ( isBorderBox ? "border" : "content" ),
+      valueIsBorderBox,
+      styles
+    )
+  );
+
+  // dump('ret', ret, val);
+  return ret;
+}
+
+var uid = ['0', '0', '0'];
+var uidPrefix = 'uiGrid-';
+
+/**
+ *  @ngdoc service
+ *  @name ui.grid.service:GridUtil
+ *  
+ *  @description Grid utility functions
+ */
+module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', 'uiGridConstants',
+  function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, uiGridConstants) {
+  var s = {
+
+    /**
+     * @ngdoc method
+     * @name createBoundedWrapper
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {object} Object to bind 'this' to
+     * @param {method} Method to bind
+     * @returns {Function} The wrapper that performs the binding
+     *
+     * @description
+     * Binds given method to given object.
+     *
+     * By means of a wrapper, ensures that ``method`` is always bound to
+     * ``object`` regardless of its calling environment.
+     * Iow, inside ``method``, ``this`` always points to ``object``.
+     *
+     * See http://alistapart.com/article/getoutbindingsituations
+     *
+     */
+    createBoundedWrapper: function(object, method) {
+        return function() {
+            return method.apply(object, arguments);
+        };
+    },
+
+
+    /**
+     * @ngdoc method
+     * @name readableColumnName
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {string} columnName Column name as a string
+     * @returns {string} Column name appropriately capitalized and split apart
+     *
+       @example
+       <example module="app">
+        <file name="app.js">
+          var app = angular.module('app', ['ui.grid']);
+
+          app.controller('MainCtrl', ['$scope', 'gridUtil', function ($scope, gridUtil) {
+            $scope.name = 'firstName';
+            $scope.columnName = function(name) {
+              return gridUtil.readableColumnName(name);
+            };
+          }]);
+        </file>
+        <file name="index.html">
+          <div ng-controller="MainCtrl">
+            <strong>Column name:</strong> <input ng-model="name" />
+            <br>
+            <strong>Output:</strong> <span ng-bind="columnName(name)"></span>
+          </div>
+        </file>
+      </example>
+     */
+    readableColumnName: function (columnName) {
+      // Convert underscores to spaces
+      if (typeof(columnName) === 'undefined' || columnName === undefined || columnName === null) { return columnName; }
+
+      if (typeof(columnName) !== 'string') {
+        columnName = String(columnName);
+      }
+
+      return columnName.replace(/_+/g, ' ')
+        // Replace a completely all-capsed word with a first-letter-capitalized version
+        .replace(/^[A-Z]+$/, function (match) {
+          return angular.lowercase(angular.uppercase(match.charAt(0)) + match.slice(1));
+        })
+        // Capitalize the first letter of words
+        .replace(/(\w+)/g, function (match) {
+          return angular.uppercase(match.charAt(0)) + match.slice(1);
+        })
+        // Put a space in between words that have partial capilizations (i.e. 'firstName' becomes 'First Name')
+        // .replace(/([A-Z]|[A-Z]\w+)([A-Z])/g, "$1 $2");
+        // .replace(/(\w+?|\w)([A-Z])/g, "$1 $2");
+        .replace(/(\w+?(?=[A-Z]))/g, '$1 ');
+    },
+
+    /**
+     * @ngdoc method
+     * @name getColumnsFromData
+     * @methodOf ui.grid.service:GridUtil
+     * @description Return a list of column names, given a data set
+     *
+     * @param {string} data Data array for grid
+     * @returns {Object} Column definitions with field accessor and column name
+     *
+     * @example
+       <pre>
+         var data = [
+           { firstName: 'Bob', lastName: 'Jones' },
+           { firstName: 'Frank', lastName: 'Smith' }
+         ];
+
+         var columnDefs = GridUtil.getColumnsFromData(data, excludeProperties);
+
+         columnDefs == [
+          {
+            field: 'firstName',
+            name: 'First Name'
+          },
+          {
+            field: 'lastName',
+            name: 'Last Name'
+          }
+         ];
+       </pre>
+     */
+    getColumnsFromData: function (data, excludeProperties) {
+      var columnDefs = [];
+
+      if (!data || typeof(data[0]) === 'undefined' || data[0] === undefined) { return []; }
+      if (angular.isUndefined(excludeProperties)) { excludeProperties = []; }
+
+      var item = data[0];
+      
+      angular.forEach(item,function (prop, propName) {
+        if ( excludeProperties.indexOf(propName) === -1){
+          columnDefs.push({
+            name: propName
+          });
+        }
+      });
+
+      return columnDefs;
+    },
+
+    /**
+     * @ngdoc method
+     * @name newId
+     * @methodOf ui.grid.service:GridUtil
+     * @description Return a unique ID string
+     *
+     * @returns {string} Unique string
+     *
+     * @example
+       <pre>
+        var id = GridUtil.newId();
+
+        # 1387305700482;
+       </pre>
+     */
+    newId: (function() {
+      var seedId = new Date().getTime();
+      return function() {
+          return seedId += 1;
+      };
+    })(),
+
+
+    /**
+     * @ngdoc method
+     * @name getTemplate
+     * @methodOf ui.grid.service:GridUtil
+     * @description Get's template from cache / element / url
+     *
+     * @param {string|element|promise} Either a string representing the template id, a string representing the template url,
+     *   an jQuery/Angualr element, or a promise that returns the template contents to use.
+     * @returns {object} a promise resolving to template contents
+     *
+     * @example
+     <pre>
+     GridUtil.getTemplate(url).then(function (contents) {
+          alert(contents);
+        })
+     </pre>
+     */
+    getTemplate: function (template) {
+      // Try to fetch the template out of the templateCache
+      if ($templateCache.get(template)) {
+        return $q.when($templateCache.get(template));
+      }
+
+      // See if the template is itself a promise
+      if (template.hasOwnProperty('then')) {
+        return template;
+      }
+
+      // If the template is an element, return the element
+      try {
+        if (angular.element(template).length > 0) {
+          return $q.when(template);
+        }
+      }
+      catch (err){
+        //do nothing; not valid html
+      }
+
+      $log.debug('Fetching url', template);
+
+      // Default to trying to fetch the template as a url with $http
+      return $http({ method: 'GET', url: template})
+        .then(
+          function (result) {
+            var templateHtml = result.data.trim();
+            //put in templateCache for next call
+            $templateCache.put(template, templateHtml);
+            return templateHtml;
+          },
+          function (err) {
+            throw new Error("Could not get template " + template + ": " + err);
+          }
+        );
+    },
+
+    /**
+     * @ngdoc method
+     * @name guessType
+     * @methodOf ui.grid.service:GridUtil
+     * @description guesses the type of an argument
+     *
+     * @param {string/number/bool/object} item variable to examine
+     * @returns {string} one of the following
+     * 'string'
+     * 'boolean'
+     * 'number'
+     * 'date'
+     * 'object'
+     */
+    guessType : function (item) {
+      var itemType = typeof(item);
+
+      // Check for numbers and booleans
+      switch (itemType) {
+        case "number":
+        case "boolean":
+        case "string":
+          return itemType;
+        default:
+          if (angular.isDate(item)) {
+            return "date";
+          }
+          return "object";
+      }
+    },
+
+
+  /**
+    * @ngdoc method
+    * @name elementWidth
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element DOM element
+    * @param {string} [extra] Optional modifier for calculation. Use 'margin' to account for margins on element
+    *
+    * @returns {number} Element width in pixels, accounting for any borders, etc.
+    */
+    elementWidth: function (elem) {
+      
+    },
+
+    /**
+    * @ngdoc method
+    * @name elementHeight
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element DOM element
+    * @param {string} [extra] Optional modifier for calculation. Use 'margin' to account for margins on element
+    *
+    * @returns {number} Element height in pixels, accounting for any borders, etc.
+    */
+    elementHeight: function (elem) {
+      
+    },
+
+    // Thanks to http://stackoverflow.com/a/13382873/888165
+    getScrollbarWidth: function() {
+        var outer = document.createElement("div");
+        outer.style.visibility = "hidden";
+        outer.style.width = "100px";
+        outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
+
+        document.body.appendChild(outer);
+
+        var widthNoScroll = outer.offsetWidth;
+        // force scrollbars
+        outer.style.overflow = "scroll";
+
+        // add innerdiv
+        var inner = document.createElement("div");
+        inner.style.width = "100%";
+        outer.appendChild(inner);        
+
+        var widthWithScroll = inner.offsetWidth;
+
+        // remove divs
+        outer.parentNode.removeChild(outer);
+
+        return widthNoScroll - widthWithScroll;
+    },
+
+    swap: function( elem, options, callback, args ) {
+      var ret, name,
+              old = {};
+
+      // Remember the old values, and insert the new ones
+      for ( name in options ) {
+        old[ name ] = elem.style[ name ];
+        elem.style[ name ] = options[ name ];
+      }
+
+      ret = callback.apply( elem, args || [] );
+
+      // Revert the old values
+      for ( name in options ) {
+        elem.style[ name ] = old[ name ];
+      }
+
+      return ret;
+    },
+
+    fakeElement: function( elem, options, callback, args ) {
+      var ret, name,
+          newElement = angular.element(elem).clone()[0];
+
+      for ( name in options ) {
+        newElement.style[ name ] = options[ name ];
+      }
+
+      angular.element(document.body).append(newElement);
+
+      ret = callback.call( newElement, newElement );
+
+      angular.element(newElement).remove();
+
+      return ret;
+    },
+
+    /**
+    * @ngdoc method
+    * @name normalizeWheelEvent
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {event} event A mouse wheel event
+    *
+    * @returns {event} A normalized event
+    *
+    * @description
+    * Given an event from this list:
+    *
+    * `wheel, mousewheel, DomMouseScroll, MozMousePixelScroll`
+    *
+    * "normalize" it
+    * so that it stays consistent no matter what browser it comes from (i.e. scale it correctly and make sure the direction is right.)
+    */
+    normalizeWheelEvent: function (event) {
+      // var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
+      // var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'];
+      var lowestDelta, lowestDeltaXY;
+      
+      var orgEvent   = event || window.event,
+          args       = [].slice.call(arguments, 1),
+          delta      = 0,
+          deltaX     = 0,
+          deltaY     = 0,
+          absDelta   = 0,
+          absDeltaXY = 0,
+          fn;
+
+      // event = $.event.fix(orgEvent);
+      // event.type = 'mousewheel';
+
+      // NOTE: jQuery masks the event and stores it in the event as originalEvent
+      if (orgEvent.originalEvent) {
+        orgEvent = orgEvent.originalEvent;
+      }
+
+      // Old school scrollwheel delta
+      if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; }
+      if ( orgEvent.detail )     { delta = orgEvent.detail * -1; }
+
+      // At a minimum, setup the deltaY to be delta
+      deltaY = delta;
+
+      // Firefox < 17 related to DOMMouseScroll event
+      if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+          deltaY = 0;
+          deltaX = delta * -1;
+      }
+
+      // New school wheel delta (wheel event)
+      if ( orgEvent.deltaY ) {
+          deltaY = orgEvent.deltaY * -1;
+          delta  = deltaY;
+      }
+      if ( orgEvent.deltaX ) {
+          deltaX = orgEvent.deltaX;
+          delta  = deltaX * -1;
+      }
+
+      // Webkit
+      if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; }
+      if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX; }
+
+      // Look for lowest delta to normalize the delta values
+      absDelta = Math.abs(delta);
+      if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; }
+      absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX));
+      if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; }
+
+      // Get a whole value for the deltas
+      fn     = delta > 0 ? 'floor' : 'ceil';
+      delta  = Math[fn](delta  / lowestDelta);
+      deltaX = Math[fn](deltaX / lowestDeltaXY);
+      deltaY = Math[fn](deltaY / lowestDeltaXY);
+
+      return {
+        delta: delta,
+        deltaX: deltaX,
+        deltaY: deltaY
+      };
+    },
+
+    // Stolen from Modernizr
+    // TODO: make this, and everythign that flows from it, robust
+    //http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
+    isTouchEnabled: function() {
+      var bool;
+
+      if (('ontouchstart' in $window) || $window.DocumentTouch && $document instanceof DocumentTouch) {
+        bool = true;
+      }
+
+      return bool;
+    },
+
+    isNullOrUndefined: function(obj) {
+      if (obj === undefined || obj === null) {
+        return true;
+      }
+      return false;
+    },
+
+    endsWith: function(str, suffix) {
+      if (!str || !suffix || typeof str !== "string") {
+        return false;
+      }
+      return str.indexOf(suffix, str.length - suffix.length) !== -1;
+    },
+
+    // Shim requestAnimationFrame
+    requestAnimationFrame: $window.requestAnimationFrame && $window.requestAnimationFrame.bind($window) ||
+                           $window.webkitRequestAnimationFrame && $window.webkitRequestAnimationFrame.bind($window) ||
+                           function(fn) {
+                             return $timeout(fn, 10, false);
+                           },
+
+    numericAndNullSort: function (a, b) {
+      if (a === null) { return 1; }
+      if (b === null) { return -1; }
+      if (a === null && b === null) { return 0; }
+      return a - b;
+    },
+
+    // Disable ngAnimate animations on an element
+    disableAnimations: function (element) {
+      var $animate;
+      try {
+        $animate = $injector.get('$animate');
+        $animate.enabled(false, element);
+      }
+      catch (e) {}
+    },
+
+    enableAnimations: function (element) {
+      var $animate;
+      try {
+        $animate = $injector.get('$animate');
+        $animate.enabled(true, element);
+      }
+      catch (e) {}
+    },
+
+    // Blatantly stolen from Angular as it isn't exposed (yet. 2.0 maybe?)
+    nextUid: function nextUid() {
+      var index = uid.length;
+      var digit;
+
+      while (index) {
+        index--;
+        digit = uid[index].charCodeAt(0);
+        if (digit === 57 /*'9'*/) {
+          uid[index] = 'A';
+          return uidPrefix + uid.join('');
+        }
+        if (digit === 90  /*'Z'*/) {
+          uid[index] = '0';
+        } else {
+          uid[index] = String.fromCharCode(digit + 1);
+          return uidPrefix + uid.join('');
+        }
+      }
+      uid.unshift('0');
+
+      return uidPrefix + uid.join('');
+    },
+
+    // Blatantly stolen from Angular as it isn't exposed (yet. 2.0 maybe?)
+    hashKey: function hashKey(obj) {
+      var objType = typeof obj,
+          key;
+
+      if (objType === 'object' && obj !== null) {
+        if (typeof (key = obj.$$hashKey) === 'function') {
+          // must invoke on object to keep the right this
+          key = obj.$$hashKey();
+        }
+        else if (typeof(obj.$$hashKey) !== 'undefined' && obj.$$hashKey) {
+          key = obj.$$hashKey;
+        }
+        else if (key === undefined) {
+          key = obj.$$hashKey = s.nextUid();
+        }
+      }
+      else {
+        key = obj;
+      }
+
+      return objType + ':' + key;
+    }
+
+    // setHashKey: function setHashKey(obj, h) {
+    //   if (h) {
+    //     obj.$$hashKey = h;
+    //   }
+    //   else {
+    //     delete obj.$$hashKey;
+    //   }
+    // }
+  };
+
+  ['width', 'height'].forEach(function (name) {
+    var capsName = angular.uppercase(name.charAt(0)) + name.substr(1);
+    s['element' + capsName] = function (elem, extra) {
+      var e = elem;
+      if (typeof(e.length) !== 'undefined' && e.length) {
+        e = elem[0];
+      }
+
+      if (e) {
+        var styles = getStyles(e);
+        return e.offsetWidth === 0 && rdisplayswap.test(styles.display) ?
+                  s.fakeElement(e, cssShow, function(newElm) {
+                    return getWidthOrHeight( newElm, name, extra );
+                  }) :
+                  getWidthOrHeight( e, name, extra );
+      }
+      else {
+        return null;
+      }
+    };
+
+    s['outerElement' + capsName] = function (elem, margin) {
+      return elem ? s['element' + capsName].call(this, elem, margin ? 'margin' : 'border') : null;
+    };
+  });
+
+  // http://stackoverflow.com/a/24107550/888165
+  s.closestElm = function closestElm(el, selector) {
+    if (typeof(el.length) !== 'undefined' && el.length) {
+      el = el[0];
+    }
+
+    var matchesFn;
+
+    // find vendor prefix
+    ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
+        if (typeof document.body[fn] === 'function') {
+            matchesFn = fn;
+            return true;
+        }
+        return false;
+    });
+
+    // traverse parents
+    var parent;
+    while (el !== null) {
+      parent = el.parentElement;
+      if (parent !== null && parent[matchesFn](selector)) {
+          return parent;
+      }
+      el = parent;
+    }
+
+    return null;
+  };
+
+  s.type = function (obj) {
+    var text = Function.prototype.toString.call(obj.constructor);
+    return text.match(/function (.*?)\(/)[1];
+  };
+
+  s.getBorderSize = function getBorderSize(elem, borderType) {
+    if (typeof(elem.length) !== 'undefined' && elem.length) {
+      elem = elem[0];
+    }
+
+    var styles = getStyles(elem);
+
+    if (borderType) {
+      borderType = 'border-' + borderType;
+    }
+    else {
+      borderType = 'border';
+    }
+
+    var val = parseInt(styles[borderType], 10);
+
+    if (isNaN(val)) {
+      return 0;
+    }
+    else {
+      return val;
+    }
+  };
+
+  // http://stackoverflow.com/a/22948274/888165
+  // TODO: Opera? Mobile?
+  s.detectBrowser = function detectBrowser() {
+    var userAgent = $window.navigator.userAgent;
+
+    var browsers = {chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer|trident\//i};
+
+    for (var key in browsers) {
+      if (browsers[key].test(userAgent)) {
+        return key;
+      }
+    }
+
+    return 'unknown';
+  };
+
+  /**
+    * @ngdoc method
+    * @name normalizeScrollLeft
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element The element to get the `scrollLeft` from.
+    *
+    * @returns {int} A normalized scrollLeft value for the current browser.
+    *
+    * @description
+    * Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method normalizes them
+    */
+  s.normalizeScrollLeft = function normalizeScrollLeft(element) {
+    if (typeof(element.length) !== 'undefined' && element.length) {
+      element = element[0];
+    }
+
+    var browser = s.detectBrowser();
+
+    var scrollLeft = element.scrollLeft;
+
+    var dir = angular.element(element).css('direction');
+
+    // IE stays normal in RTL
+    if (browser === 'ie') {
+      return scrollLeft;
+    }
+    // Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
+    else if (browser === 'chrome') {
+      if (dir === 'rtl') {
+        // Get the max scroll for the element
+        var maxScrollLeft = element.scrollWidth - element.clientWidth;
+
+        // Subtract the current scroll amount from the max scroll
+        return maxScrollLeft - scrollLeft;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    // Firefox goes negative!
+    else if (browser === 'firefox') {
+      return Math.abs(scrollLeft);
+    }
+    else {
+      // TODO(c0bra): Handle other browsers? Android? iOS? Opera?
+      return scrollLeft;
+    }
+  };
+
+  /**
+  * @ngdoc method
+  * @name normalizeScrollLeft
+  * @methodOf ui.grid.service:GridUtil
+  *
+  * @param {element} element The element to normalize the `scrollLeft` value for
+  * @param {int} scrollLeft The `scrollLeft` value to denormalize.
+  *
+  * @returns {int} A normalized scrollLeft value for the current browser.
+  *
+  * @description
+  * Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method denormalizes a value for the current browser.
+  */
+  s.denormalizeScrollLeft = function denormalizeScrollLeft(element, scrollLeft) {
+    if (typeof(element.length) !== 'undefined' && element.length) {
+      element = element[0];
+    }
+
+    var browser = s.detectBrowser();
+
+    var dir = angular.element(element).css('direction');
+
+    // IE stays normal in RTL
+    if (browser === 'ie') {
+      return scrollLeft;
+    }
+    // Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
+    else if (browser === 'chrome') {
+      if (dir === 'rtl') {
+        // Get the max scroll for the element
+        var maxScrollLeft = element.scrollWidth - element.clientWidth;
+
+        // Subtract the current scroll amount from the max scroll
+        return maxScrollLeft - scrollLeft;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    // Firefox goes negative!
+    else if (browser === 'firefox') {
+      if (dir === 'rtl') {
+        return scrollLeft * -1;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    else {
+      // TODO(c0bra): Handle other browsers? Android? iOS? Opera?
+      return scrollLeft;
+    }
+  };
+
+    /**
+     * @ngdoc method
+     * @name preEval
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {string} path Path to evaluate
+     *
+     * @returns {string} A path that is normalized.
+     *
+     * @description
+     * Takes a field path and converts it to bracket notation to allow for special characters in path
+     * @example
+     * <pre>
+     * gridUtil.preEval('property') == 'property'
+     * gridUtil.preEval('nested.deep.prop-erty') = "nested['deep']['prop-erty']"
+     * </pre>
+     */
+  s.preEval = function (path) {
+    var m = uiGridConstants.BRACKET_REGEXP.exec(path);
+    if (m) {
+      return (m[1] ? s.preEval(m[1]) : m[1]) + m[2] + (m[3] ? s.preEval(m[3]) : m[3]);
+    } else {
+      path = path.replace(uiGridConstants.APOS_REGEXP, '\\\'');
+      var parts = path.split(uiGridConstants.DOT_REGEXP);
+      var preparsed = [parts.shift()];    // first item must be var notation, thus skip
+      angular.forEach(parts, function (part) {
+        preparsed.push(part.replace(uiGridConstants.FUNC_REGEXP, '\']$1'));
+      });
+      return preparsed.join('[\'');
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name debounce
+   * @methodOf ui.grid.service:GridUtil
+   *
+   * @param {function} func function to debounce
+   * @param {number} wait milliseconds to delay
+   * @param {bool} immediate execute before delay
+   *
+   * @returns {function} A function that can be executed as debounced function
+   *
+   * @description
+   * Copied from https://github.com/shahata/angular-debounce
+   * Takes a function, decorates it to execute only 1 time after multiple calls, and returns the decorated function
+   * @example
+   * <pre>
+   * var debouncedFunc =  gridUtil.debounce(function(){alert('debounced');}, 500);
+   * debouncedFunc();
+   * debouncedFunc();
+   * debouncedFunc();
+   * </pre>
+   */
+  s.debounce =  function (func, wait, immediate) {
+    var timeout, args, context, result;
+    function debounce() {
+      /* jshint validthis:true */
+      context = this;
+      args = arguments;
+      var later = function () {
+        timeout = null;
+        if (!immediate) {
+          result = func.apply(context, args);
+        }
+      };
+      var callNow = immediate && !timeout;
+      if (timeout) {
+        $timeout.cancel(timeout);
+      }
+      timeout = $timeout(later, wait);
+      if (callNow) {
+        result = func.apply(context, args);
+      }
+      return result;
+    }
+    debounce.cancel = function () {
+      $timeout.cancel(timeout);
+      timeout = null;
+    };
+    return debounce;
+  };
+
+  return s;
+}]);
+
+// Add 'px' to the end of a number string if it doesn't have it already
+module.filter('px', function() {
+  return function(str) {
+    if (str.match(/^[\d\.]+$/)) {
+      return str + 'px';
+    }
+    else {
+      return str;
+    }
+  };
+});
+
+})();
+
+(function(){
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('da', {
+          aggregate:{
+            label: 'artikler'
+          },
+          groupPanel:{
+            description: 'Grupér rækker udfra en kolonne ved at trække dens overskift hertil.'
+          },
+          search:{
+            placeholder: 'Søg...',
+            showingItems: 'Viste rækker:',
+            selectedItems: 'Valgte rækker:',
+            totalItems: 'Rækker totalt:',
+            size: 'Side størrelse:',
+            first: 'Første side',
+            next: 'Næste side',
+            previous: 'Forrige side',
+            last: 'Sidste side'
+          },
+          menu:{
+            text: 'Vælg kolonner:',
+          },
+          column: {
+            hide: 'Skjul kolonne'
+          }
+        });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('de', {
+        aggregate: {
+          label: 'eintrag'
+        },
+        groupPanel: {
+          description: 'Ziehen Sie eine Spaltenüberschrift hierhin um nach dieser Spalte zu gruppieren.'
+        },
+        search: {
+          placeholder: 'Suche...',
+          showingItems: 'Zeige Einträge:',
+          selectedItems: 'Ausgewählte Einträge:',
+          totalItems: 'Einträge gesamt:',
+          size: 'Einträge pro Seite:',
+          first: 'Erste Seite',
+          next: 'Nächste Seite',
+          previous: 'Vorherige Seite',
+          last: 'Letzte Seite'
+        },
+        menu: {
+          text: 'Spalten auswählen:'
+        },
+        column: {
+          hide: 'Spalte ausblenden'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('en', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'Drag a column header here and drop it to group by that column.'
+        },
+        search: {
+          placeholder: 'Search...',
+          showingItems: 'Showing Items:',
+          selectedItems: 'Selected Items:',
+          totalItems: 'Total Items:',
+          size: 'Page Size:',
+          first: 'First Page',
+          next: 'Next Page',
+          previous: 'Previous Page',
+          last: 'Last Page'
+        },
+        menu: {
+          text: 'Choose Columns:'
+        },
+        sort: {
+          ascending: 'Sort Ascending',
+          descending: 'Sort Descending',
+          remove: 'Remove Sort'
+        },
+        column: {
+          hide: 'Hide Column'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('es', {
+        aggregate: {
+          label: 'Artículos'
+        },
+        groupPanel: {
+          description: 'Arrastre un encabezado de columna aquí y soltarlo para agrupar por esa columna.'
+        },
+        search: {
+          placeholder: 'Buscar...',
+          showingItems: 'Artículos Mostrando:',
+          selectedItems: 'Artículos Seleccionados:',
+          totalItems: 'Artículos Totales:',
+          size: 'Tamaño de Página:',
+          first: 'Primera Página',
+          next: 'Página Siguiente',
+          previous: 'Página Anterior',
+          last: 'Última Página'
+        },
+        menu: {
+          text: 'Elegir columnas:'
+        },
+        column: {
+          hide: 'Ocultar la columna'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('fa', {
+        aggregate: {
+          label: 'موردها'
+        },
+        groupPanel: {
+          description: 'یک عنوان ستون اینجا را بردار و به گروهی از آن ستون بیانداز.'
+        },
+        search: {
+          placeholder: 'جستجو...',
+          showingItems: 'نمایش موردها:',
+          selectedItems: 'موردهای انتخاب\u200cشده:',
+          totalItems: 'همهٔ موردها:',
+          size: 'اندازهٔ صفحه:',
+          first: 'صفحهٔ اول',
+          next: 'صفحهٔ بعد',
+          previous: 'صفحهٔ قبل',
+          last: 'آخرین صفحه'
+        },
+        menu: {
+          text: 'انتخاب ستون\u200cها:'
+        },
+        column: {
+          hide: 'ستون پنهان کن'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('fr', {
+        aggregate: {
+          label: 'articles'
+        },
+        groupPanel: {
+          description: 'Faites glisser un en-tête de colonne ici et déposez-le vers un groupe par cette colonne.'
+        },
+        search: {
+          placeholder: 'Recherche...',
+          showingItems: 'Articles Affichage des:',
+          selectedItems: 'Éléments Articles:',
+          totalItems: 'Nombre total d\'articles:',
+          size: 'Taille de page:',
+          first: 'Première page',
+          next: 'Page Suivante',
+          previous: 'Page précédente',
+          last: 'Dernière page'
+        },
+        menu: {
+          text: 'Choisir des colonnes:'
+        },
+        column: {
+          hide: 'Colonne de peau'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+    angular.module('ui.grid').config(['$provide', function ($provide) {
+        $provide.decorator('i18nService', ['$delegate', function ($delegate) {
+            $delegate.add('he', {
+                aggregate: {
+                    label: 'items'
+                },
+                groupPanel: {
+                    description: 'גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו.'
+                },
+                search: {
+                    placeholder: 'חפש...',
+                    showingItems: 'מציג:',
+                    selectedItems: 'סה"כ נבחרו:',
+                    totalItems: 'סה"כ רשומות:',
+                    size: 'תוצאות בדף:',
+                    first: 'דף ראשון',
+                    next: 'דף הבא',
+                    previous: 'דף קודם',
+                    last: 'דף אחרון'
+                },
+                menu: {
+                    text: 'בחר עמודות:'
+                },
+                sort: {
+                    ascending: 'סדר עולה',
+                    descending: 'סדר יורד',
+                    remove: 'בטל'
+                },
+                column: {
+                  hide: 'טור הסתר'
+                }
+            });
+            return $delegate;
+        }]);
+    }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('nl', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'Sleep hier een kolomnaam heen om op te groeperen.'
+        },
+        search: {
+          placeholder: 'Zoeken...',
+          showingItems: 'Getoonde items:',
+          selectedItems: 'Geselecteerde items:',
+          totalItems: 'Totaal aantal items:',
+          size: 'Items per pagina:',
+          first: 'Eerste pagina',
+          next: 'Volgende pagina',
+          previous: 'Vorige pagina',
+          last: 'Laatste pagina'
+        },
+        menu: {
+          text: 'Kies kolommen:'
+        },
+        sort: {
+          ascending: 'Sorteer oplopend',
+          descending: 'Sorteer aflopend',
+          remove: 'Verwijder sortering'
+        },
+        column: {
+          hide: 'Kolom te verbergen'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('pt-br', {
+        aggregate: {
+          label: 'itens'
+        },
+        groupPanel: {
+          description: 'Arraste e solte uma coluna aqui para agrupar por essa coluna'
+        },
+        search: {
+          placeholder: 'Procurar...',
+          showingItems: 'Mostrando os Itens:',
+          selectedItems: 'Items Selecionados:',
+          totalItems: 'Total de Itens:',
+          size: 'Tamanho da Página:',
+          first: 'Primeira Página',
+          next: 'Próxima Página',
+          previous: 'Página Anterior',
+          last: 'Última Página'
+        },
+        menu: {
+          text: 'Selecione as colunas:'
+        },
+        column: {
+          hide: 'Esconder coluna'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('ru', {
+        aggregate: {
+          label: 'элементы'
+        },
+        groupPanel: {
+          description: 'Для группировки по столбцу перетащите сюда его название.'
+        },
+        search: {
+          placeholder: 'Поиск...',
+          showingItems: 'Показать элементы:',
+          selectedItems: 'Выбранные элементы:',
+          totalItems: 'Всего элементов:',
+          size: 'Размер страницы:',
+          first: 'Первая страница',
+          next: 'Следующая страница',
+          previous: 'Предыдущая страница',
+          last: 'Последняя страница'
+        },
+        menu: {
+          text: 'Выбрать столбцы:'
+        },
+        sort: {
+          ascending: 'По возрастанию',
+          descending: 'По убыванию',
+          remove: 'Убрать сортировку'
+        },
+        column: {
+          hide: 'спрятать столбец'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+angular.module('ui.grid').config(['$provide', function($provide) {
+$provide.decorator('i18nService', ['$delegate', function($delegate) {
+$delegate.add('sk', {
+aggregate: {
+label: 'items'
+},
+groupPanel: {
+description: 'Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca.'
+},
+search: {
+placeholder: 'Hľadaj...',
+showingItems: 'Zobrazujem položky:',
+selectedItems: 'Vybraté položky:',
+totalItems: 'Počet položiek:',
+size: 'Počet:',
+first: 'Prvá strana',
+next: 'Ďalšia strana',
+previous: 'Predchádzajúca strana',
+last: 'Posledná strana'
+},
+menu: {
+text: 'Vyberte stĺpce:'
+},
+sort: {
+ascending: 'Zotriediť vzostupne',
+descending: 'Zotriediť zostupne',
+remove: 'Vymazať triedenie'
+}
+});
+return $delegate;
+}]);
+}]);
+})();
+
+/**
+ * @ngdoc overview
+ * @name ui.grid.i18n
+ * @description
+ *
+ *  # ui.grid.i18n
+ * This module provides i18n functions to ui.grid and any application that wants to use it
+
+ *
+ * <div doc-module-components="ui.grid.i18n"></div>
+ */
+
+(function () {
+  var DIRECTIVE_ALIASES = ['uiT', 'uiTranslate'];
+  var FILTER_ALIASES = ['t', 'uiTranslate'];
+
+  var module = angular.module('ui.grid.i18n');
+
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.i18n.constant:i18nConstants
+   *
+   *  @description constants available in i18n module
+   */
+  module.constant('i18nConstants', {
+    MISSING: '[MISSING]',
+    UPDATE_EVENT: '$uiI18n',
+
+    LOCALE_DIRECTIVE_ALIAS: 'uiI18n',
+    // default to english
+    DEFAULT_LANG: 'en'
+  });
+
+//    module.config(['$provide', function($provide) {
+//        $provide.decorator('i18nService', ['$delegate', function($delegate) {}])}]);
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.i18n.service:i18nService
+   *
+   *  @description Services for i18n
+   */
+  module.service('i18nService', ['$log', 'i18nConstants', '$rootScope',
+    function ($log, i18nConstants, $rootScope) {
+
+      var langCache = {
+        _langs: {},
+        current: null,
+        get: function (lang) {
+          return this._langs[lang.toLowerCase()];
+        },
+        add: function (lang, strings) {
+          var lower = lang.toLowerCase();
+          if (!this._langs[lower]) {
+            this._langs[lower] = {};
+          }
+          angular.extend(this._langs[lower], strings);
+        },
+        getAllLangs: function () {
+          var langs = [];
+          if (!this._langs) {
+            return langs;
+          }
+
+          for (var key in this._langs) {
+            langs.push(key);
+          }
+
+          return langs;
+        },
+        setCurrent: function (lang) {
+          this.current = lang.toLowerCase();
+        },
+        getCurrentLang: function () {
+          return this.current;
+        }
+      };
+
+      var service = {
+
+        /**
+         * @ngdoc service
+         * @name add
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  Adds the languages and strings to the cache. Decorate this service to
+         * add more translation strings
+         * @param {string} lang language to add
+         * @param {object} stringMaps of strings to add grouped by property names
+         * @example
+         * <pre>
+         *      i18nService.add('en', {
+         *         aggregate: {
+         *                 label1: 'items',
+         *                 label2: 'some more items'
+         *                 }
+         *         },
+         *         groupPanel: {
+         *              description: 'Drag a column header here and drop it to group by that column.'
+         *           }
+         *      }
+         * </pre>
+         */
+        add: function (langs, stringMaps) {
+          if (typeof(langs) === 'object') {
+            angular.forEach(langs, function (lang) {
+              if (lang) {
+                langCache.add(lang, stringMaps);
+              }
+            });
+          } else {
+            langCache.add(langs, stringMaps);
+          }
+        },
+
+        /**
+         * @ngdoc service
+         * @name getAllLangs
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  return all currently loaded languages
+         * @returns {array} string
+         */
+        getAllLangs: function () {
+          return langCache.getAllLangs();
+        },
+
+        /**
+         * @ngdoc service
+         * @name get
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  return all currently loaded languages
+         * @param {string} lang to return.  If not specified, returns current language
+         * @returns {object} the translation string maps for the language
+         */
+        get: function (lang) {
+          var language = lang ? lang : service.getCurrentLang();
+          return langCache.get(language);
+        },
+
+        /**
+         * @ngdoc service
+         * @name getSafeText
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  returns the text specified in the path or a Missing text if text is not found
+         * @param {string} path property path to use for retrieving text from string map
+         * @param {string} lang to return.  If not specified, returns current language
+         * @returns {object} the translation for the path
+         * @example
+         * <pre>
+         * i18nService.getSafeText('sort.ascending')
+         * </pre>
+         */
+        getSafeText: function (path, lang) {
+          var language = lang ? lang : service.getCurrentLang();
+          var trans = langCache.get(language);
+
+          if (!trans) {
+            return i18nConstants.MISSING;
+          }
+
+          var paths = path.split('.');
+          var current = trans;
+
+          for (var i = 0; i < paths.length; ++i) {
+            if (current[paths[i]] === undefined || current[paths[i]] === null) {
+              return i18nConstants.MISSING;
+            } else {
+              current = current[paths[i]];
+            }
+          }
+
+          return current;
+
+        },
+
+        /**
+         * @ngdoc service
+         * @name setCurrentLang
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description sets the current language to use in the application
+         * $broadcasts the Update_Event on the $rootScope
+         * @param {string} lang to set
+         * @example
+         * <pre>
+         * i18nService.setCurrentLang('fr');
+         * </pre>
+         */
+
+        setCurrentLang: function (lang) {
+          if (lang) {
+            langCache.setCurrent(lang);
+            $rootScope.$broadcast(i18nConstants.UPDATE_EVENT);
+          }
+        },
+
+        /**
+         * @ngdoc service
+         * @name getCurrentLang
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description returns the current language used in the application
+         */
+        getCurrentLang: function () {
+          var lang = langCache.getCurrentLang();
+          if (!lang) {
+            lang = i18nConstants.DEFAULT_LANG;
+            langCache.setCurrent(lang);
+          }
+          return lang;
+        }
+
+      };
+
+      return service;
+
+    }]);
+
+  var localeDirective = function (i18nService, i18nConstants) {
+    return {
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs) {
+            var alias = i18nConstants.LOCALE_DIRECTIVE_ALIAS;
+            // check for watchable property
+            var lang = $scope.$eval($attrs[alias]);
+            if (lang) {
+              $scope.$watch($attrs[alias], function () {
+                i18nService.setCurrentLang(lang);
+              });
+            } else if ($attrs.$$observers) {
+              $attrs.$observe(alias, function () {
+                i18nService.setCurrentLang($attrs[alias] || i18nConstants.DEFAULT_LANG);
+              });
+            }
+          }
+        };
+      }
+    };
+  };
+
+  module.directive('uiI18n', ['i18nService', 'i18nConstants', localeDirective]);
+
+  // directive syntax
+  var uitDirective = function ($parse, i18nService, i18nConstants) {
+    return {
+      restrict: 'EA',
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs) {
+            var alias1 = DIRECTIVE_ALIASES[0],
+              alias2 = DIRECTIVE_ALIASES[1];
+            var token = $attrs[alias1] || $attrs[alias2] || $elm.html();
+            var missing = i18nConstants.MISSING + token;
+            var observer;
+            if ($attrs.$$observers) {
+              var prop = $attrs[alias1] ? alias1 : alias2;
+              observer = $attrs.$observe(prop, function (result) {
+                if (result) {
+                  $elm.html($parse(result)(i18nService.getCurrentLang()) || missing);
+                }
+              });
+            }
+            var getter = $parse(token);
+            var listener = $scope.$on(i18nConstants.UPDATE_EVENT, function (evt) {
+              if (observer) {
+                observer($attrs[alias1] || $attrs[alias2]);
+              } else {
+                // set text based on i18n current language
+                $elm.html(getter(i18nService.get()) || missing);
+              }
+            });
+            $scope.$on('$destroy', listener);
+
+            $elm.html(getter(i18nService.get()) || missing);
+          }
+        };
+      }
+    };
+  };
+
+  DIRECTIVE_ALIASES.forEach(function (alias) {
+    module.directive(alias, ['$parse', 'i18nService', 'i18nConstants', uitDirective]);
+  });
+
+  // optional filter syntax
+  var uitFilter = function ($parse, i18nService, i18nConstants) {
+    return function (data) {
+      var getter = $parse(data);
+      // set text based on i18n current language
+      return getter(i18nService.get()) || i18nConstants.MISSING + data;
+    };
+  };
+
+  FILTER_ALIASES.forEach(function (alias) {
+    module.filter(alias, ['$parse', 'i18nService', 'i18nConstants', uitFilter]);
+  });
+
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('zh-cn', {
+        aggregate: {
+          label: '条目'
+        },
+        groupPanel: {
+          description: '拖曳表头到此处以进行分组'
+        },
+        search: {
+          placeholder: '搜索...',
+          showingItems: '当前显示条目:',
+          selectedItems: '选中条目:',
+          totalItems: '条目总数:',
+          size: '每页显示数:',
+          first: '回到首页',
+          next: '下一页',
+          previous: '上一页',
+          last: '前往尾页'
+        },
+        menu: {
+          text: '数据分组与选择列:'
+        },
+        column: {
+          hide: '隐藏列'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('zh-tw', {
+        aggregate: {
+          label: '筆'
+        },
+        groupPanel: {
+          description: '拖拉表頭到此處以進行分組'
+        },
+        search: {
+          placeholder: '搜尋...',
+          showingItems: '目前顯示筆數:',
+          selectedItems: '選取筆數:',
+          totalItems: '總筆數:',
+          size: '每頁顯示:',
+          first: '第一頁',
+          next: '下一頁',
+          previous: '上一頁',
+          last: '最後頁'
+        },
+        menu: {
+          text: '選擇欄位:'
+        },
+        column: {
+          hide: '隐藏列'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function() {
+  'use strict';
+  /**
+   *  @ngdoc overview
+   *  @name ui.grid.autoResize
+   *
+   *  @description 
+   *
+   *  #ui.grid.autoResize
+   *  This module provides auto-resizing functionality to ui-grid
+   *
+   */
+  var module = angular.module('ui.grid.autoResize', ['ui.grid']);
+  
+
+  module.directive('uiGridAutoResize', ['$log', '$timeout', 'gridUtil', function ($log, $timeout, gridUtil) {
+    return {
+      require: 'uiGrid',
+      scope: false,
+      link: function ($scope, $elm, $attrs, uiGridCtrl) {
+        var prevGridWidth, prevGridHeight;
+
+        function getDimensions() {
+          prevGridHeight = gridUtil.elementHeight($elm);
+          prevGridWidth = gridUtil.elementWidth($elm);
+        }
+
+        // Initialize the dimensions
+        getDimensions();
+
+        var canceler;
+        function startTimeout() {
+          $timeout.cancel(canceler);
+
+          canceler = $timeout(function () {
+            var newGridHeight = gridUtil.elementHeight($elm);
+            var newGridWidth = gridUtil.elementWidth($elm);
+
+            if (newGridHeight !== prevGridHeight || newGridWidth !== prevGridWidth) {
+              uiGridCtrl.grid.gridHeight = newGridHeight;
+              uiGridCtrl.grid.gridWidth = newGridWidth;
+
+              uiGridCtrl.grid.queueRefresh()
+                .then(function () {
+                  getDimensions();
+
+                  startTimeout();
+                });
+            }
+            else {
+              startTimeout();
+            }
+          }, 250);
+        }
+
+        startTimeout();
+
+        $scope.$on('$destroy', function() {
+          $timeout.cancel(canceler);
+        });
+      }
+    };
+  }]);
+})();
+(function () {
+  'use strict';
+  var module = angular.module('ui.grid.cellNav', ['ui.grid']);
+
+  function RowCol(row, col) {
+    this.row = row;
+    this.col = col;
+  }
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.cellNav.constant:uiGridCellNavConstants
+   *
+   *  @description constants available in cellNav
+   */
+  module.constant('uiGridCellNavConstants', {
+    FEATURE_NAME : 'gridCellNav',
+    CELL_NAV_EVENT: 'cellNav',
+    direction: {LEFT: 0, RIGHT: 1, UP: 2, DOWN: 3}
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.cellNav.service:uiGridCellNavService
+   *
+   *  @description Services for cell navigation features. If you don't like the key maps we use,
+   *  or the direction cells navigation, override with a service decorator (see angular docs)
+   */
+  module.service('uiGridCellNavService', ['$log', 'uiGridConstants', 'uiGridCellNavConstants', '$q',
+    function ($log, uiGridConstants, uiGridCellNavConstants, $q) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+          grid.registerColumnBuilder(service.cellNavColumnBuilder);
+
+          //create variables for state
+          grid.cellNav = {};
+          grid.cellNav.lastRowCol = null;
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.cellNav.api:PublicApi
+           *
+           *  @description Public Api for cellNav feature
+           */
+          var publicApi = {
+            events: {
+              cellNav : {
+                /**
+                 * @ngdoc event
+                 * @name navigate
+                 * @eventOf  ui.grid.cellNav.api:PublicApi
+                 * @description raised when the active cell is changed
+                 * <pre>
+                 *      gridApi.cellNav.on.navigate(scope,function(newRowcol, oldRowCol){})
+                 * </pre>
+                 * @param {object} newRowCol new position
+                 * @param {object} oldRowCol old position
+                 */
+                navigate : function(newRowCol, oldRowCol){}
+              }
+            },
+            methods: {
+              cellNav: {
+                /**
+                 * @ngdoc function
+                 * @name scrollTo
+                 * @methodOf  ui.grid.cellNav.api:PublicApi
+                 * @description brings the specified row and column into view
+                 * @param {Grid} grid the grid you'd like to act upon, usually available
+                 * from gridApi.grid
+                 * @param {object} $scope a scope we can broadcast events from
+                 * @param {object} rowEntity gridOptions.data[] array instance to make visible
+                 * @param {object} colDef to make visible
+                 */
+                scrollTo: function (grid, $scope, rowEntity, colDef) {
+                  service.scrollTo(grid, $scope, rowEntity, colDef);
+                },
+                /**
+                 * @ngdoc function
+                 * @name getFocusedCell
+                 * @methodOf  ui.grid.cellNav.api:PublicApi
+                 * @description returns the current (or last if Grid does not have focus) focused row and column
+                 * <br> value is null if no selection has occurred
+                 */
+                getFocusedCell: function () {
+                  return grid.cellNav.lastRowCol;
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+
+        /**
+         * @ngdoc service
+         * @name getDirection
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description  determines which direction to for a given keyDown event
+         * @returns {uiGridCellNavConstants.direction} direction
+         */
+        getDirection: function (evt) {
+          if (evt.keyCode === uiGridConstants.keymap.LEFT ||
+            (evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey)) {
+            return uiGridCellNavConstants.direction.LEFT;
+          }
+          if (evt.keyCode === uiGridConstants.keymap.RIGHT ||
+            evt.keyCode === uiGridConstants.keymap.TAB) {
+            return uiGridCellNavConstants.direction.RIGHT;
+          }
+
+          if (evt.keyCode === uiGridConstants.keymap.UP ||
+            (evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey)) {
+            return uiGridCellNavConstants.direction.UP;
+          }
+
+          if (evt.keyCode === uiGridConstants.keymap.DOWN ||
+            evt.keyCode === uiGridConstants.keymap.ENTER) {
+            return uiGridCellNavConstants.direction.DOWN;
+          }
+
+          return null;
+        },
+
+        /**
+         * @ngdoc service
+         * @name getNextRowCol
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description  returns the next row and column for a given direction
+         * columns that are not focusable are skipped
+         * @param {object} direction navigation direction
+         * @param {Grid} grid current grid
+         * @param {GridRow} curRow Gridrow
+         * @param {GridCol} curCol Gridcol
+         * @returns {uiGridCellNavConstants.direction} rowCol object
+         */
+        getNextRowCol: function (direction, grid, curRow, curCol) {
+          switch (direction) {
+            case uiGridCellNavConstants.direction.LEFT:
+              return service.getRowColLeft(grid.rows, grid.columns, curRow, curCol);
+            case uiGridCellNavConstants.direction.RIGHT:
+              return service.getRowColRight(grid.rows, grid.columns, curRow, curCol);
+            case uiGridCellNavConstants.direction.UP:
+              return service.getRowColUp(grid.rows, grid.columns, curRow, curCol);
+            case uiGridCellNavConstants.direction.DOWN:
+              return service.getRowColDown(grid.rows, grid.columns, curRow, curCol);
+          }
+        },
+
+        getRowColLeft: function (rows, cols, curRow, curCol) {
+          var colIndex = service.getNextColIndexLeft(cols, curCol);
+
+          if (colIndex > curCol.index) {
+            if (curRow.index === 0) {
+              return new RowCol(curRow, cols[colIndex]); //return same row
+            }
+            else {
+              //up one row and far right column
+              return new RowCol(rows[curRow.index - 1], cols[colIndex]);
+            }
+          }
+          else {
+            return new RowCol(curRow, cols[colIndex]);
+          }
+        },
+
+        getRowColRight: function (rows, cols, curRow, curCol) {
+          var colIndex = service.getNextColIndexRight(cols, curCol);
+
+          if (colIndex < curCol.index) {
+            if (curRow.index === rows.length - 1) {
+              return new RowCol(curRow, cols[colIndex]); //return same row
+            }
+            else {
+              //down one row and far left column
+              return new RowCol(rows[curRow.index + 1], cols[colIndex]);
+            }
+          }
+          else {
+            return new RowCol(curRow, cols[colIndex]);
+          }
+        },
+
+        getNextColIndexLeft: function (cols, curCol) {
+          //start with next col to the left or the end of the array if curCol is the first col
+          var i = curCol.index === 0 ? cols.length - 1 : curCol.index - 1;
+
+          //find first focusable column to the left
+          //circle around to the end of the array if no col is found
+          while (i !== curCol.index) {
+            if (cols[i].colDef.allowCellFocus) {
+              break;
+            }
+            i--;
+            //go to end of array if at the beginning
+            if (i === -1) {
+              i = cols.length - 1;
+            }
+          }
+
+          return i;
+        },
+
+        getNextColIndexRight: function (cols, curCol) {
+          //start with next col to the right or the beginning of the array if curCol is the last col
+          var i = curCol.index === cols.length - 1 ? 0 : curCol.index + 1;
+
+          //find first focusable column to the right
+          //circle around to the beginning of the array if no col is found
+          while (i !== curCol.index) {
+            if (cols[i].colDef.allowCellFocus) {
+              break;
+            }
+            i++;
+            //go to end of array if at the beginning
+            if (i > cols.length - 1) {
+              i = 0;
+            }
+          }
+
+          return i;
+        },
+
+        getRowColUp: function (rows, cols, curRow, curCol) {
+          //if curCol is not focusable, then we need to find a focusable column to the right
+          //this shouldn't ever happen in the grid, but we handle it anyway
+          var colIndex = curCol.colDef.allowCellFocus ? curCol.index : service.getNextColIndexRight(cols, curCol);
+
+
+          if (curRow.index === 0) {
+            return new RowCol(curRow, cols[colIndex]); //return same row
+          }
+          else {
+            //up one row
+            return new RowCol(rows[curRow.index - 1], cols[colIndex]);
+          }
+        },
+
+        getRowColDown: function (rows, cols, curRow, curCol) {
+          //if curCol is not focusable, then we need to find a focusable column to the right
+          //this shouldn't ever happen in the grid, but we handle it anyway
+          var colIndex = curCol.colDef.allowCellFocus ? curCol.index : service.getNextColIndexRight(cols, curCol);
+
+
+          if (curRow.index === rows.length - 1) {
+            return new RowCol(curRow, cols[colIndex]); //return same row
+          }
+          else {
+            //down one row
+            return new RowCol(rows[curRow.index + 1], cols[colIndex]);
+          }
+        },
+
+        /**
+         * @ngdoc service
+         * @name cellNavColumnBuilder
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description columnBuilder function that adds cell navigation properties to grid column
+         * @returns {promise} promise that will load any needed templates when resolved
+         */
+        cellNavColumnBuilder: function (colDef, col, gridOptions) {
+          var promises = [];
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.cellNav.api:ColumnDef
+           *
+           *  @description Column Definitions for cellNav feature, these are available to be 
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name allowCellFocus
+           *  @propertyOf  ui.grid.cellNav.api:ColumnDef
+           *  @description Enable focus on a cell.  
+           *  <br/>Defaults to true
+           */
+          colDef.allowCellFocus = colDef.allowCellFocus === undefined ? true : colDef.allowCellFocus ;
+
+          return $q.all(promises);
+        },
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name scrollVerticallyTo
+         * @description Scroll the grid vertically such that the specified
+         * row is in view
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {object} $scope a scope we can broadcast events from
+         * @param {object} rowEntity gridOptions.data[] array instance to make visible
+         * @param {object} colDef to make visible
+         */
+        scrollTo: function (grid, $scope, rowEntity, colDef) {
+          var args = {};
+          
+          if ( rowEntity !== null ){
+            var row = grid.getRow(rowEntity);
+            if ( row ) { 
+              args.y = { percentage: row.index / grid.renderContainers.body.visibleRowCache.length }; 
+            }
+          }
+          
+          if ( colDef !== null ){
+            var col = grid.getColumn(colDef.name ? colDef.name : colDef.field);
+            if ( col ) {
+              args.x = { percentage: this.getLeftWidth(grid, col.index) / this.getLeftWidth(grid, grid.renderContainers.body.visibleColumnCache.length - 1) };              
+            }
+          }
+          
+          if ( args.y || args.x ){
+            $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
+          }
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name getLeftWidth
+         * @description Get the current drawn width of the columns in the 
+         * grid up to and including the numbered column
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {object} colIndex the column to total up to and including
+         */
+        getLeftWidth: function( grid, colIndex ){
+          var width = 0;
+          
+          if ( !colIndex ){ return; }
+          
+          for ( var i=0; i <= colIndex; i++ ){
+            if ( grid.renderContainers.body.visibleColumnCache[i].drawnWidth ){
+              width += grid.renderContainers.body.visibleColumnCache[i].drawnWidth;
+            } 
+          }
+          return width;
+        }
+
+      };
+
+      return service;
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.cellNav.directive:uiCellNav
+   *  @element div
+   *  @restrict EA
+   *
+   *  @description Adds cell navigation features to the grid columns
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name'},
+        {name: 'title'}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-cellnav></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridCellnav', ['$log', 'uiGridCellNavService', 'uiGridCellNavConstants',
+    function ($log, uiGridCellNavService, uiGridCellNavConstants) {
+      return {
+        replace: true,
+        priority: -150,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+
+              var grid = uiGridCtrl.grid;
+              uiGridCellNavService.initializeGrid(grid);
+
+              uiGridCtrl.cellNav = {};
+
+              //  $log.debug('uiGridEdit preLink');
+              uiGridCtrl.cellNav.broadcastCellNav = function (newRowCol) {
+                $scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT, newRowCol);
+                uiGridCtrl.cellNav.broadcastFocus(newRowCol.row, newRowCol.col);
+              };
+
+              uiGridCtrl.cellNav.broadcastFocus = function (row, col) {
+                if (grid.cellNav.lastRowCol === null || (grid.cellNav.lastRowCol.row !== row || grid.cellNav.lastRowCol.col !== col)) {
+                  var newRowCol = new RowCol(row, col);
+                  grid.api.cellNav.raise.navigate(newRowCol, grid.cellNav.lastRowCol);
+                  grid.cellNav.lastRowCol = newRowCol;
+                }
+              };
+
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.cellNav.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *  @description Stacks on top of ui.grid.uiGridCell to provide cell navigation
+   */
+  module.directive('uiGridCell', ['uiGridCellNavService', '$log', 'uiGridCellNavConstants',
+    function (uiGridCellNavService, $log, uiGridCellNavConstants) {
+      return {
+        priority: -150, // run after default uiGridCell directive and ui.grid.edit uiGridCell
+        restrict: 'A',
+        require: '^uiGrid',
+        scope: false,
+        link: function ($scope, $elm, $attrs, uiGridCtrl) {
+          if (!$scope.col.colDef.allowCellFocus) {
+             return;
+          }
+
+          setTabEnabled();
+
+          $elm.on('keydown', function (evt) {
+            var direction = uiGridCellNavService.getDirection(evt);
+            if (direction === null) {
+              return true;
+            }
+
+            var rowCol = uiGridCellNavService.getNextRowCol(direction, $scope.grid, $scope.row, $scope.col);
+
+            //$log.debug('next row ' + rowCol.row.index + ' next Col ' + rowCol.col.colDef.name);
+            uiGridCtrl.cellNav.broadcastCellNav(rowCol);
+            setTabEnabled();
+
+            return false;
+          });
+
+          $elm.find('div').on('focus', function (evt) {
+            uiGridCtrl.cellNav.broadcastFocus($scope.row, $scope.col);
+          });
+
+          $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function(evt,rowCol){
+             if (rowCol.row === $scope.row &&
+               rowCol.col === $scope.col){
+               // $log.debug('Setting focus on Row ' + rowCol.row.index + ' Col ' + rowCol.col.colDef.name);
+                setFocused();
+             }
+          });
+
+          function setTabEnabled(){
+            $elm.find('div').attr("tabindex", -1);
+          }
+
+          function setFocused(){
+            var div = $elm.find('div');
+            div[0].focus();
+            div.attr("tabindex", 0);
+          }
+
+        }
+      };
+    }]);
+
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.edit
+   * @description
+   *
+   *  # ui.grid.edit
+   * This module provides cell editing capability to ui.grid. The goal was to emulate keying data in a spreadsheet via
+   * a keyboard.
+   * <br/>
+   * <br/>
+   * To really get the full spreadsheet-like data entry, the ui.grid.cellNav module should be used. This will allow the
+   * user to key data and then tab, arrow, or enter to the cells beside or below.
+   *
+   * <div doc-module-components="ui.grid.edit"></div>
+   */
+
+  var module = angular.module('ui.grid.edit', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.edit.constant:uiGridEditConstants
+   *
+   *  @description constants available in edit module
+   */
+  module.constant('uiGridEditConstants', {
+    EDITABLE_CELL_TEMPLATE: /EDITABLE_CELL_TEMPLATE/g,
+    //must be lowercase because template bulder converts to lower
+    EDITABLE_CELL_DIRECTIVE: /editable_cell_directive/g,
+    events: {
+      BEGIN_CELL_EDIT: 'uiGridEventBeginCellEdit',
+      END_CELL_EDIT: 'uiGridEventEndCellEdit',
+      CANCEL_CELL_EDIT: 'uiGridEventCancelCellEdit'
+    }
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.edit.service:uiGridEditService
+   *
+   *  @description Services for editing features
+   */
+  module.service('uiGridEditService', ['$log', '$q', '$templateCache', 'uiGridConstants', 'gridUtil',
+    function ($log, $q, $templateCache, uiGridConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          service.defaultGridOptions(grid.options);
+
+          grid.registerColumnBuilder(service.editColumnBuilder);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:PublicApi
+           *
+           *  @description Public Api for edit feature
+           */
+          var publicApi = {
+            events: {
+              edit: {
+                /**
+                 * @ngdoc event
+                 * @name afterCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing is complete
+                 * <pre>
+                 *      gridApi.edit.on.afterCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 * @param {object} newValue new value
+                 * @param {object} oldValue old value
+                 */
+                afterCellEdit: function (rowEntity, colDef, newValue, oldValue) {
+                },
+                /**
+                 * @ngdoc event
+                 * @name beginCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing starts on a cell
+                 * <pre>
+                 *      gridApi.edit.on.beginCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 */
+                beginCellEdit: function (rowEntity, colDef) {
+                },
+                /**
+                 * @ngdoc event
+                 * @name cancelCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing is cancelled on a cell
+                 * <pre>
+                 *      gridApi.edit.on.cancelCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 */
+                cancelCellEdit: function (rowEntity, colDef) {
+                }                
+              }
+            },
+            methods: {
+              edit: { }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+          //grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:GridOptions
+           *
+           *  @description Options for configuring the edit feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEdit
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If defined, sets the default value for the editable flag on each individual colDefs 
+           *  if their individual enableCellEdit configuration is not defined. Defaults to undefined.  
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name cellEditableCondition
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If specified, either a value or function to be used by all columns before editing.  
+           *  If falsy, then editing of cell is not allowed.
+           *  @example
+           *  <pre>
+           *  function($scope){
+           *    //use $scope.row.entity and $scope.col.colDef to determine if editing is allowed
+           *    return true;
+           *  }
+           *  </pre>
+           */
+          gridOptions.cellEditableCondition = gridOptions.cellEditableCondition === undefined ? true : gridOptions.cellEditableCondition;
+
+          /**
+           *  @ngdoc object
+           *  @name editableCellTemplate
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If specified, cellTemplate to use as the editor for all columns.  
+           *  <br/> defaults to 'ui-grid/cellTextEditor'
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEditOnFocus
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If true, then editor is invoked as soon as cell receives focus. Default false.
+           *  <br/>_requires cellNav feature and the edit feature to be enabled_
+           */
+            //enableCellEditOnFocus can only be used if cellnav module is used
+          gridOptions.enableCellEditOnFocus = gridOptions.enableCellEditOnFocus === undefined ?
+            false: gridOptions.enableCellEditOnFocus;
+        },
+
+        /**
+         * @ngdoc service
+         * @name editColumnBuilder
+         * @methodOf ui.grid.edit.service:uiGridEditService
+         * @description columnBuilder function that adds edit properties to grid column
+         * @returns {promise} promise that will load any needed templates when resolved
+         */
+        editColumnBuilder: function (colDef, col, gridOptions) {
+
+          var promises = [];
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:ColumnDef
+           *
+           *  @description Column Definition for edit feature, these are available to be 
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEdit
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description enable editing on column
+           */
+          colDef.enableCellEdit = colDef.enableCellEdit === undefined ? (gridOptions.enableCellEdit === undefined ?
+            (colDef.type !== 'object'):gridOptions.enableCellEdit) : colDef.enableCellEdit;
+
+          /**
+           *  @ngdoc object
+           *  @name cellEditableCondition
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description If specified, either a value or function evaluated before editing cell.  If falsy, then editing of cell is not allowed.
+           *  @example 
+           *  <pre>
+           *  function($scope){
+           *    //use $scope.row.entity and $scope.col.colDef to determine if editing is allowed
+           *    return true;
+           *  }
+           *  </pre>
+           */
+          colDef.cellEditableCondition = colDef.cellEditableCondition === undefined ? gridOptions.cellEditableCondition :  colDef.cellEditableCondition;
+
+          /**
+           *  @ngdoc object
+           *  @name editableCellTemplate
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description cell template to be used when editing this column. Can be Url or text template
+           *  <br/>Defaults to gridOptions.editableCellTemplate
+           */
+          if (colDef.enableCellEdit) {
+            colDef.editableCellTemplate = colDef.editableCellTemplate || gridOptions.editableCellTemplate || 'ui-grid/cellEditor';
+
+            promises.push(gridUtil.getTemplate(colDef.editableCellTemplate)
+              .then(
+              function (template) {
+                col.editableCellTemplate = template;
+              },
+              function (res) {
+                // Todo handle response error here?
+                throw new Error("Couldn't fetch/use colDef.editableCellTemplate '" + colDef.editableCellTemplate + "'");
+              }));
+          }
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEditOnFocus
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @requires ui.grid.cellNav
+           *  @description If true, then editor is invoked as soon as cell receives focus. Default false.
+           *  <br>_requires both the cellNav feature and the edit feature to be enabled_
+           */
+            //enableCellEditOnFocus can only be used if cellnav module is used
+          colDef.enableCellEditOnFocus = colDef.enableCellEditOnFocus === undefined ? gridOptions.enableCellEditOnFocus : colDef.enableCellEditOnFocus;
+
+          return $q.all(promises);
+        },
+
+        /**
+         * @ngdoc service
+         * @name isStartEditKey
+         * @methodOf ui.grid.edit.service:uiGridEditService
+         * @description  Determines if a keypress should start editing.  Decorate this service to override with your
+         * own key events.  See service decorator in angular docs.
+         * @param {Event} evt keydown event
+         * @returns {boolean} true if an edit should start
+         */
+        isStartEditKey: function (evt) {
+          if (evt.keyCode === uiGridConstants.keymap.LEFT ||
+            (evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey) ||
+
+            evt.keyCode === uiGridConstants.keymap.RIGHT ||
+            evt.keyCode === uiGridConstants.keymap.TAB ||
+
+            evt.keyCode === uiGridConstants.keymap.UP ||
+            (evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey) ||
+
+            evt.keyCode === uiGridConstants.keymap.DOWN ||
+            evt.keyCode === uiGridConstants.keymap.ENTER) {
+            return false;
+
+          }
+          return true;
+        }
+
+
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEdit
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds editing features to the ui-grid directive.
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name', enableCellEdit: true},
+        {name: 'title', enableCellEdit: true}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-edit></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridEdit', ['$log', 'uiGridEditService', function ($log, uiGridEditService) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            uiGridEditService.initializeGrid(uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+          }
+        };
+      }
+    };
+  }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Stacks on top of ui.grid.uiGridCell to provide in-line editing capabilities to the cell
+   *  Editing Actions.
+   *
+   *  Binds edit start events to the uiGridCell element.  When the events fire, the gridCell element is appended
+   *  with the columnDef.editableCellTemplate element ('cellEditor.html' by default).
+   *
+   *  The editableCellTemplate should respond to uiGridEditConstants.events.BEGIN\_CELL\_EDIT angular event
+   *  and do the initial steps needed to edit the cell (setfocus on input element, etc).
+   *
+   *  When the editableCellTemplate recognizes that the editing is ended (blur event, Enter key, etc.)
+   *  it should emit the uiGridEditConstants.events.END\_CELL\_EDIT event.
+   *
+   *  If editableCellTemplate recognizes that the editing has been cancelled (esc key)
+   *  it should emit the uiGridEditConstants.events.CANCEL\_CELL\_EDIT event.  The original value
+   *  will be set back on the model by the uiGridCell directive.
+   *
+   *  Events that invoke editing:
+   *    - dblclick
+   *    - F2 keydown (when using cell selection)
+   *
+   *  Events that end editing:
+   *    - Dependent on the specific editableCellTemplate
+   *    - Standards should be blur and enter keydown
+   *
+   *  Events that cancel editing:
+   *    - Dependent on the specific editableCellTemplate
+   *    - Standards should be Esc keydown
+   *
+   *  Grid Events that end editing:
+   *    - uiGridConstants.events.GRID_SCROLL
+   *
+   */
+  module.directive('uiGridCell',
+    ['$compile', 'uiGridConstants', 'uiGridEditConstants', '$log', '$parse', 'uiGridEditService',
+      function ($compile, uiGridConstants, uiGridEditConstants, $log, $parse, uiGridEditService) {
+        return {
+          priority: -100, // run after default uiGridCell directive
+          restrict: 'A',
+          scope: false,
+          link: function ($scope, $elm, $attrs) {
+            if (!$scope.col.colDef.enableCellEdit) {
+              return;
+            }
+
+            var html;
+            var origCellValue;
+            var inEdit = false;
+            var isFocusedBeforeEdit = false;
+            var cellModel;
+
+            registerBeginEditEvents();
+
+            function registerBeginEditEvents() {
+              $elm.on('dblclick', beginEdit);
+              $elm.on('keydown', beginEditKeyDown);
+              if ($scope.col.colDef.enableCellEditOnFocus) {
+                $elm.find('div').on('focus', beginEditFocus);
+              }
+            }
+
+            function cancelBeginEditEvents() {
+              $elm.off('dblclick', beginEdit);
+              $elm.off('keydown', beginEditKeyDown);
+              if ($scope.col.colDef.enableCellEditOnFocus) {
+                $elm.find('div').off('focus', beginEditFocus);
+              }
+            }
+
+            function beginEditFocus(evt) {
+              evt.stopPropagation();
+              beginEdit();
+            }
+
+            function beginEditKeyDown(evt) {
+              if (uiGridEditService.isStartEditKey(evt)) {
+                beginEdit();
+              }
+            }
+
+            function shouldEdit(col, row) {
+              return !row.isSaving && 
+                ( angular.isFunction(col.colDef.cellEditableCondition) ?
+                    col.colDef.cellEditableCondition($scope) :
+                    col.colDef.cellEditableCondition );
+            }
+
+
+            /**
+             *  @ngdoc property
+             *  @name editDropdownOptionsArray
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description an array of values in the format
+             *  [ {id: xxx, value: xxx} ], which is populated
+             *  into the edit dropdown
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownIdLabel
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description the label for the "id" field
+             *  in the editDropdownOptionsArray.  Defaults
+             *  to 'id'
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownValueLabel
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description the label for the "value" field
+             *  in the editDropdownOptionsArray.  Defaults
+             *  to 'value'
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownFilter
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description A filter that you would like to apply to the values in the options list
+             *  of the dropdown.  For example if you were using angular-translate you might set this
+             *  to `'translate'`
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status', editDropdownFilter: 'translate' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            function beginEdit() {
+              if (!shouldEdit($scope.col, $scope.row)) {
+                return;
+              }
+
+              cellModel = $parse($scope.row.getQualifiedColField($scope.col));
+              //get original value from the cell
+              origCellValue = cellModel($scope);
+
+              html = $scope.col.editableCellTemplate;
+              html = html.replace(uiGridConstants.COL_FIELD, $scope.row.getQualifiedColField($scope.col));
+              
+              var optionFilter = $scope.col.colDef.editDropdownFilter ? '|' + $scope.col.colDef.editDropdownFilter : ''; 
+              html = html.replace(uiGridConstants.CUSTOM_FILTERS, optionFilter);
+
+              $scope.inputType = 'text';
+              switch ($scope.col.colDef.type){
+                case 'boolean':
+                  $scope.inputType = 'checkbox';
+                  break;
+                case 'number':
+                  $scope.inputType = 'number';
+                  break;
+                case 'date':
+                  $scope.inputType = 'date';
+                  break;
+              }
+              
+              $scope.editDropdownOptionsArray = $scope.col.colDef.editDropdownOptionsArray;
+              $scope.editDropdownIdLabel = $scope.col.colDef.editDropdownIdLabel ? $scope.col.colDef.editDropdownIdLabel : 'id';  
+              $scope.editDropdownValueLabel = $scope.col.colDef.editDropdownValueLabel ? $scope.col.colDef.editDropdownValueLabel : 'value';  
+
+              var cellElement;
+              $scope.$apply(function () {
+                  inEdit = true;
+                  cancelBeginEditEvents();
+                  cellElement = $compile(html)($scope.$new());
+                  var gridCellContentsEl = angular.element($elm.children()[0]);
+                  isFocusedBeforeEdit = gridCellContentsEl.hasClass(':focus');
+                  gridCellContentsEl.addClass('ui-grid-cell-contents-hidden');
+                  $elm.append(cellElement);
+                }
+              );
+
+              //stop editing when grid is scrolled
+              var deregOnGridScroll = $scope.$on(uiGridConstants.events.GRID_SCROLL, function () {
+                endEdit(true);
+                $scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
+                deregOnGridScroll();
+              });
+
+              //end editing
+              var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function (evt, retainFocus) {
+                endEdit(retainFocus);
+                $scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
+                deregOnEndCellEdit();
+              });
+
+              //cancel editing
+              var deregOnCancelCellEdit = $scope.$on(uiGridEditConstants.events.CANCEL_CELL_EDIT, function () {
+                cancelEdit();
+                deregOnCancelCellEdit();
+              });
+
+              $scope.$broadcast(uiGridEditConstants.events.BEGIN_CELL_EDIT);
+              $scope.grid.api.edit.raise.beginCellEdit($scope.row.entity, $scope.col.colDef);
+            }
+
+            function endEdit(retainFocus) {
+              if (!inEdit) {
+                return;
+              }
+              var gridCellContentsEl = angular.element($elm.children()[0]);
+              //remove edit element
+              angular.element($elm.children()[1]).remove();
+              gridCellContentsEl.removeClass('ui-grid-cell-contents-hidden');
+              if (retainFocus && isFocusedBeforeEdit) {
+                gridCellContentsEl.focus();
+              }
+              isFocusedBeforeEdit = false;
+              inEdit = false;
+              registerBeginEditEvents();
+            }
+
+            function cancelEdit() {
+              if (!inEdit) {
+                return;
+              }
+              cellModel.assign($scope, origCellValue);
+              $scope.$apply();
+
+              $scope.grid.api.edit.raise.cancelCellEdit($scope.row.entity, $scope.col.colDef);
+              endEdit(true);
+            }
+
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEditor
+   *  @element div
+   *  @restrict A
+   *
+   *  @description input editor directive for editable fields.
+   *  Provides EndEdit and CancelEdit events
+   *
+   *  Events that end editing:
+   *     blur and enter keydown
+   *
+   *  Events that cancel editing:
+   *    - Esc keydown
+   *
+   */
+  module.directive('uiGridEditor',
+    ['uiGridConstants', 'uiGridEditConstants',
+      function (uiGridConstants, uiGridEditConstants) {
+        return {
+          scope: true,
+          compile: function () {
+            return {
+              pre: function ($scope, $elm, $attrs) {
+
+              },
+              post: function ($scope, $elm, $attrs) {
+
+                //set focus at start of edit
+                $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
+                  $elm[0].focus();
+                  $elm[0].select();
+                  $elm.on('blur', function (evt) {
+                    $scope.stopEdit(evt);
+                  });
+                });
+
+               
+               $scope.deepEdit = false;
+               
+               $scope.stopEdit = function (evt) {
+                  if ($scope.inputForm && !$scope.inputForm.$valid) {
+                    evt.stopPropagation();
+                    $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                  }
+                  else {
+                    $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
+                  }
+                  $scope.deepEdit = false;
+                };
+
+                $elm.on('click', function (evt) {
+                  $scope.deepEdit = true;
+                });
+
+                $elm.on('keydown', function (evt) {
+                  switch (evt.keyCode) {
+                    case uiGridConstants.keymap.ESC:
+                      evt.stopPropagation();
+                      $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                      break;
+                    case uiGridConstants.keymap.ENTER: // Enter (Leave Field)
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.TAB:
+                      $scope.stopEdit(evt);
+                      break;
+                  }
+
+                  if ($scope.deepEdit) {
+                    switch (evt.keyCode) {
+                      case uiGridConstants.keymap.LEFT:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.RIGHT:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.UP:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.DOWN:
+                        evt.stopPropagation();
+                        break;
+                    }
+                  }
+
+                  return true;
+                });
+              }
+            };
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:input
+   *  @element input
+   *  @restrict E
+   *
+   *  @description directive to provide binding between input[date] value and ng-model for angular 1.2
+   *  It is similar to input[date] directive of angular 1.3
+   *
+   *  Supported date format for input is 'yyyy-MM-dd'
+   *  The directive will set the $valid property of input element and the enclosing form to false if
+   *  model is invalid date or value of input is entered wrong.
+   *
+   */
+    module.directive('input', ['$filter', function ($filter) {
+      function parseDateString(dateString) {
+        if ('undefined' === typeof dateString || '' === dateString) {
+          return null;
+        }
+        var parts = dateString.split('-');
+        if (3 !== parts.length) {
+          return null;
+        }
+        var year = parseInt(parts[0], 10);
+        var month = parseInt(parts[1], 10);
+        var day = parseInt(parts[2], 10);
+
+        if (month < 1 || year < 1 || day < 1) {
+          return null;
+        }
+        return new Date(year, (month - 1), day);
+      }
+      return {
+        restrict: 'E',
+        require: '?ngModel',
+        link: function (scope, element, attrs, ngModel) {
+
+          if (angular.version.minor === 2 && attrs.type && 'date' === attrs.type && ngModel) {
+
+            ngModel.$formatters.push(function (modelValue) {
+              ngModel.$setValidity(null,(!modelValue || !isNaN(modelValue.getTime())));
+              return $filter('date')(modelValue, 'yyyy-MM-dd');
+            });
+
+            ngModel.$parsers.push(function (viewValue) {
+              if (viewValue && viewValue.length > 0) {
+                var dateValue = parseDateString(viewValue);
+                ngModel.$setValidity(null, (dateValue && !isNaN(dateValue.getTime())));
+                return dateValue;
+              }
+              else {
+                ngModel.$setValidity(null, true);
+                return null;
+              }
+            });
+          }
+        }
+      };
+    }]);
+    
+    
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEditDropdown
+   *  @element div
+   *  @restrict A
+   *
+   *  @description dropdown editor for editable fields.
+   *  Provides EndEdit and CancelEdit events
+   *
+   *  Events that end editing:
+   *     blur and enter keydown, and any left/right nav
+   *
+   *  Events that cancel editing:
+   *    - Esc keydown
+   *
+   */
+  module.directive('uiGridEditDropdown',
+    ['uiGridConstants', 'uiGridEditConstants',
+      function (uiGridConstants, uiGridEditConstants) {
+        return {
+          scope: true,
+          compile: function () {
+            return {
+              pre: function ($scope, $elm, $attrs) {
+
+              },
+              post: function ($scope, $elm, $attrs) {
+
+                //set focus at start of edit
+                $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
+                  $elm[0].focus();
+                  $elm[0].style.width = ($elm[0].parentElement.offsetWidth - 1) + 'px';
+                  $elm.on('blur', function (evt) {
+                    $scope.stopEdit(evt);
+                  });
+                });
+
+               
+                $scope.stopEdit = function (evt) {
+                  // no need to validate a dropdown - invalid values shouldn't be
+                  // available in the list
+                  $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
+                };
+
+                $elm.on('keydown', function (evt) {
+                  switch (evt.keyCode) {
+                    case uiGridConstants.keymap.ESC:
+                      evt.stopPropagation();
+                      $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                      break;
+                    case uiGridConstants.keymap.ENTER: // Enter (Leave Field)
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.LEFT:
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.RIGHT:
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.UP:
+                      evt.stopPropagation();
+                      break;
+                    case uiGridConstants.keymap.DOWN:
+                      evt.stopPropagation();
+                      break;
+                    case uiGridConstants.keymap.TAB:
+                      $scope.stopEdit(evt);
+                      break;
+                  }
+                  return true;
+                });
+              }
+            };
+          }
+        };
+      }]);    
+
+})();
+
+(function () {
+  'use strict';
+
+  var module = angular.module('ui.grid.expandable', ['ui.grid']);
+
+  module.service('uiGridExpandableService', ['gridUtil', '$log', '$compile', function (gridUtil, $log, $compile) {
+    var service = {
+      initializeGrid: function (grid) {
+        var publicApi = {
+          events: {
+            expandable: {
+              rowExpandedStateChanged: function (scope, row) {
+              }
+            }
+          },
+          methods: {
+            expandable: {
+              toggleRowExpansion: function (rowEntity) {
+                var row = grid.getRow(rowEntity);
+                if (row !== null) {
+                  service.toggleRowExpansion(grid, row);
+                }
+              },
+              expandAllRows: function() {
+                service.expandAllRows(grid);
+              },
+              collapseAllRows: function() {
+                service.collapseAllRows(grid);
+              }
+            }
+          }
+        };
+        grid.api.registerEventsFromObject(publicApi.events);
+        grid.api.registerMethodsFromObject(publicApi.methods);
+      },
+      toggleRowExpansion: function (grid, row) {
+        row.isExpanded = !row.isExpanded;
+
+        if (row.isExpanded) {
+          row.height = row.grid.options.rowHeight + grid.options.expandable.expandableRowHeight;
+        }
+        else {
+          row.height = row.grid.options.rowHeight;
+        }
+
+        grid.api.expandable.raise.rowExpandedStateChanged(row);
+      },
+      expandAllRows: function(grid, $scope) {
+        angular.forEach(grid.renderContainers.body.visibleRowCache, function(row) {
+          if (!row.isExpanded) {
+            service.toggleRowExpansion(grid, row);
+          }
+        });
+        grid.refresh();
+      },
+      collapseAllRows: function(grid) {
+        angular.forEach(grid.renderContainers.body.visibleRowCache, function(row) {
+          if (row.isExpanded) {
+            service.toggleRowExpansion(grid, row);
+          }
+        });
+        grid.refresh();
+      }
+    };
+    return service;
+  }]);
+
+  module.directive('uiGridExpandable', ['$log', 'uiGridExpandableService', '$templateCache',
+    function ($log, uiGridExpandableService, $templateCache) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              var expandableRowHeaderColDef = {name: 'expandableButtons', width: 40};
+              expandableRowHeaderColDef.cellTemplate = $templateCache.get('ui-grid/expandableRowHeader');
+              uiGridCtrl.grid.addRowHeaderColumn(expandableRowHeaderColDef);
+              uiGridExpandableService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridExpandableRow',
+  ['uiGridExpandableService', '$timeout', '$log', '$compile', 'uiGridConstants','gridUtil','$interval',
+    function (uiGridExpandableService, $timeout, $log, $compile, uiGridConstants, gridUtil, $interval) {
+
+      return {
+        replace: false,
+        priority: 0,
+        scope: false,
+
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              gridUtil.getTemplate($scope.grid.options.expandable.rowExpandableTemplate).then(
+                function (template) {
+                  var expandedRowElement = $compile(template)($scope);
+                  $elm.append(expandedRowElement);
+                  $scope.row.expandedRendered = true;
+              });
+            },
+
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+              $scope.$on('$destroy', function() {
+                $scope.row.expandedRendered = false;
+              });
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridRow',
+    ['$compile', '$log', '$templateCache',
+      function ($compile, $log, $templateCache) {
+        return {
+          priority: -200,
+          scope: false,
+          compile: function ($elm, $attrs) {
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+                $scope.expandableRow = {};
+
+                $scope.expandableRow.shouldRenderExpand = function () {
+                  var ret = $scope.colContainer.name === 'body' &&  $scope.row.isExpanded && (!$scope.grid.isScrollingVertically || $scope.row.expandedRendered);
+                  return ret;
+                };
+
+                $scope.expandableRow.shouldRenderFiller = function () {
+                  var ret = $scope.row.isExpanded && ( $scope.colContainer.name !== 'body' || ($scope.grid.isScrollingVertically && !$scope.row.expandedRendered));
+                  return ret;
+                };
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+  module.directive('uiGridViewport',
+    ['$compile', '$log', '$templateCache',
+      function ($compile, $log, $templateCache) {
+        return {
+          priority: -200,
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+            var expandedRowFillerElement = $templateCache.get('ui-grid/expandableScrollFiller');
+            var expandedRowElement = $templateCache.get('ui-grid/expandableRow');
+            rowRepeatDiv.append(expandedRowElement);
+            rowRepeatDiv.append(expandedRowFillerElement);
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.exporter
+   * @description
+   *
+   *  # ui.grid.exporter
+   * This module provides the ability to exporter data from the grid.  
+   * 
+   * Data can be exported in a range of formats, and all data, visible 
+   * data, or selected rows can be exported, with all columns or visible
+   * columns.
+   * 
+   * No UI is provided, the caller should provide their own UI/buttons 
+   * as appropriate.
+   * 
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.exporter"></div>
+   */
+
+  var module = angular.module('ui.grid.exporter', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.exporter.constant:uiGridExporterConstants
+   *
+   *  @description constants available in exporter module
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name ALL
+   * @description export all data, including data not visible.  Can
+   * be set for either rowTypes or colTypes
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name VISIBLE
+   * @description export only visible data, including data not visible.  Can
+   * be set for either rowTypes or colTypes
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name SELECTED
+   * @description export all data, including data not visible.  Can
+   * be set only for rowTypes, selection of only some columns is 
+   * not supported
+   */
+  module.constant('uiGridExporterConstants', {
+    featureName: 'exporter',
+    ALL: 'all',
+    VISIBLE: 'visible',
+    SELECTED: 'selected',
+    CSV_CONTENT: 'CSV_CONTENT',
+    LINK_LABEL: 'LINK_LABEL',
+    BUTTON_LABEL: 'BUTTON_LABEL'
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.exporter.service:uiGridExporterService
+   *
+   *  @description Services for exporter feature
+   */
+  module.service('uiGridExporterService', ['$log', '$q', 'uiGridExporterConstants', 'gridUtil', '$compile',
+    function ($log, $q, uiGridExporterConstants, gridUtil, $compile) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          //add feature namespace and any properties to grid for needed state
+          grid.exporter = {};
+          this.defaultGridOptions(grid.options);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.exporter.api:PublicApi
+           *
+           *  @description Public Api for exporter feature
+           */
+          var publicApi = {
+            events: {
+              exporter: {
+              }
+            },
+            methods: {
+              exporter: {
+                /**
+                 * @ngdoc function
+                 * @name csvExport
+                 * @methodOf  ui.grid.exporter.api:PublicApi
+                 * @description Exports rows from the grid in csv format, 
+                 * the data exported is selected based on the provided options
+                 * @param {string} rowTypes which rows to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+                 * uiGridExporterConstants.SELECTED
+                 * @param {string} colTypes which columns to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE
+                 * @param {element} $elm (Optional) A UI element into which the
+                 * resulting download link will be placed. 
+                 */
+                csvExport: function (rowTypes, colTypes, $elm) {
+                  service.csvExport(grid, rowTypes, colTypes, $elm);
+                },
+                /**
+                 * @ngdoc function
+                 * @name pdfExport
+                 * @methodOf  ui.grid.exporter.api:PublicApi
+                 * @description Exports rows from the grid in pdf format, 
+                 * the data exported is selected based on the provided options
+                 * Note that this function has a dependency on pdfMake, all
+                 * going well this has been installed for you.
+                 * The resulting pdf opens in a new browser window.
+                 * @param {string} rowTypes which rows to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+                 * uiGridExporterConstants.SELECTED
+                 * @param {string} colTypes which columns to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE
+                 */
+                pdfExport: function (rowTypes, colTypes) {
+                  service.pdfExport(grid, rowTypes, colTypes);
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+          //default option to true unless it was explicitly set to false
+          /**
+           * @ngdoc object
+           * @name ui.grid.exporter.api:GridOptions
+           *
+           * @description GridOptions for selection feature, these are available to be  
+           * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           * @ngdoc object
+           * @name exporterSuppressButton
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description Don't show the export menu button, implying the user
+           * will roll their own UI for calling the exporter
+           * <br/>Defaults to false
+           */
+          gridOptions.exporterSuppressButton = gridOptions.exporterSuppressButton === true;
+          /**
+           * @ngdoc object
+           * @name exporterLinkTemplate
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A custom template to use for the resulting
+           * link (for csv export)
+           * <br/>Defaults to ui-grid/csvLink
+           */
+          gridOptions.exporterLinkTemplate = gridOptions.exporterLinkTemplate ? gridOptions.exporterLinkTemplate : 'ui-grid/csvLink';
+          /**
+           * @ngdoc object
+           * @name exporterHeaderTemplate
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A custom template to use for the header
+           * section, containing the button and csv download link.  Not
+           * needed if you've set suppressButton and are providing a custom
+           * $elm into which the download link will go.
+           * <br/>Defaults to ui-grid/exporterHeader
+           */
+          gridOptions.exporterHeaderTemplate = gridOptions.exporterHeaderTemplate ? gridOptions.exporterHeaderTemplate : 'ui-grid/exporterHeader';
+          /**
+           * @ngdoc object
+           * @name exporterLinkLabel
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The text to show on the CSV download
+           * link
+           * <br/>Defaults to 'Download CSV'
+           */
+          gridOptions.exporterLinkLabel = gridOptions.exporterLinkLabel ? gridOptions.exporterLinkLabel : 'Download CSV';
+          /**
+           * @ngdoc object
+           * @name exporterButtonLabel
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The text to show on the exporter menu button
+           * link
+           * <br/>Defaults to 'Export'
+           */
+          gridOptions.exporterButtonLabel = gridOptions.exporterButtonLabel ? gridOptions.exporterButtonLabel : 'Export';
+          /**
+           * @ngdoc object
+           * @name exporterPdfDefaultStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The default style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     fontSize: 11
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfDefaultStyle = gridOptions.exporterPdfDefaultStyle ? gridOptions.exporterPdfDefaultStyle : { fontSize: 11 };
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The table style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     margin: [0, 5, 0, 15]
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfTableStyle = gridOptions.exporterPdfTableStyle ? gridOptions.exporterPdfTableStyle : { margin: [0, 5, 0, 15] };
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableHeaderStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The tableHeader style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     bold: true,
+           *     fontSize: 12,
+           *     color: 'black'
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfTableHeaderStyle = gridOptions.exporterPdfTableHeaderStyle ? gridOptions.exporterPdfTableHeaderStyle : { bold: true, fontSize: 12, color: 'black' };
+          /**
+           * @ngdoc object
+           * @name exporterPdfOrientation
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The orientation, should be a valid pdfMake value,
+           * 'landscape' or 'portrait'
+           * <br/>Defaults to landscape
+           */
+          gridOptions.exporterPdfOrientation = gridOptions.exporterPdfOrientation ? gridOptions.exporterPdfOrientation : 'landscape';
+          /**
+           * @ngdoc object
+           * @name exporterPdfPageSize
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The orientation, should be a valid pdfMake
+           * paper size, usually 'A4' or 'LETTER'
+           * {@link https://github.com/bpampuch/pdfmake/blob/master/src/standardPageSizes.js pdfMake page sizes}
+           * <br/>Defaults to A4
+           */
+          gridOptions.exporterPdfPageSize = gridOptions.exporterPdfPageSize ? gridOptions.exporterPdfPageSize : 'A4';
+          /**
+           * @ngdoc object
+           * @name exporterPdfMaxGridWidth
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The maxium grid width - the current grid width 
+           * will be scaled to match this, with any fixed width columns
+           * being adjusted accordingly.
+           * <br/>Defaults to 720 (for A4 landscape), use 670 for LETTER 
+           */
+          gridOptions.exporterPdfMaxGridWidth = gridOptions.exporterPdfMaxGridWidth ? gridOptions.exporterPdfMaxGridWidth : 720;
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableLayout
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A tableLayout in pdfMake format, 
+           * controls gridlines and the like.  We use the default
+           * layout usually.
+           * <br/>Defaults to null, which means no layout 
+           */
+
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name showMenu
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Shows the grid menu with exporter content,
+         * allowing the user to select export options 
+         * @param {Grid} grid the grid from which data should be exported
+         */
+        showMenu: function ( grid ) {
+          grid.exporter.$scope.menuItems = [
+            {
+              title: 'Export all data as csv',
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.ALL, uiGridExporterConstants.ALL );
+              }
+            },
+            {
+              title: 'Export visible data as csv',
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.VISIBLE, uiGridExporterConstants.VISIBLE );
+              }
+            },
+            {
+              title: 'Export selected data as csv',
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.SELECTED, uiGridExporterConstants.VISIBLE );
+              }
+            },
+            {
+              title: 'Export all data as pdf',
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.ALL, uiGridExporterConstants.ALL );
+              }
+            },
+            {
+              title: 'Export visible data as pdf',
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.VISIBLE, uiGridExporterConstants.VISIBLE );
+              }
+            },
+            {
+              title: 'Export selected data as pdf',
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.SELECTED, uiGridExporterConstants.VISIBLE );
+              }
+            }
+          ];
+          
+          grid.exporter.$scope.$broadcast('toggleExporterMenu');          
+        },
+        
+
+        /**
+         * @ngdoc function
+         * @name csvExport
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Exports rows from the grid in csv format, 
+         * the data exported is selected based on the provided options
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {element} $elm (Optional) A UI element into which the
+         * resulting download link will be placed. 
+         */
+        csvExport: function (grid, rowTypes, colTypes, $elm) {
+          var exportColumnHeaders = this.getColumnHeaders(grid, colTypes);
+          var exportData = this.getData(grid, rowTypes, colTypes);
+          var csvContent = this.formatAsCsv(exportColumnHeaders, exportData);
+          this.renderCsvLink(grid, csvContent, $elm);
+          
+          // this.grid.exporter.$scope.$broadcast('clearExporterMenu');
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name getColumnHeaders
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Gets the column headers from the grid to use
+         * as a title row for the exported file, all headers have 
+         * headerCellFilters applied as appropriate.
+         * 
+         * TODO: filters
+         * 
+         * Column headers are an array of objects, each object has
+         * name, displayName, width and align attributes.  Only name is
+         * used for csv, all attributes are used for pdf.
+         * 
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        getColumnHeaders: function (grid, colTypes) {
+          var headers = [];
+          angular.forEach(grid.columns, function( gridCol, index ) {
+            if (gridCol.visible || colTypes === uiGridExporterConstants.ALL){
+              headers.push({
+                name: gridCol.field,
+                displayName: gridCol.displayName,
+                // TODO: should we do something to normalise here if too wide?
+                width: gridCol.drawnWidth ? gridCol.drawnWidth : gridCol.width,
+                // TODO: if/when we have an alignment attribute, use it here
+                align: gridCol.colDef.type === 'number' ? 'right' : 'left'
+              });
+            }
+          });
+          
+          return headers;
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name getData
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Gets data from the grid based on the provided options,
+         * all cells have cellFilters applied as appropriate
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        getData: function (grid, rowTypes, colTypes) {
+          var data = [];
+          
+          var rows;
+          
+          switch ( rowTypes ) {
+            case uiGridExporterConstants.ALL:
+              rows = grid.rows; 
+              break;
+            case uiGridExporterConstants.VISIBLE:
+              rows = grid.getVisibleRows();
+              break;
+            case uiGridExporterConstants.SELECTED:
+              if ( grid.api.selection ){
+                rows = grid.api.selection.getSelectedGridRows();
+              } else {
+                $log.error('selection feature must be enabled to allow selected rows to be exported');
+              }
+              break;
+          }
+          
+          if ( uiGridExporterConstants.ALL ) {
+            angular.forEach(rows, function( row, index ) {
+
+              var extractedRow = [];
+              angular.forEach(grid.columns, function( gridCol, index ) {
+                if (gridCol.visible || colTypes === uiGridExporterConstants.ALL){
+                  extractedRow.push(grid.getCellValue(row, gridCol));
+                }
+              });
+              
+              data.push(extractedRow);
+            });
+            
+            return data;
+          }
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name formatAsCSV
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Formats the column headers and data as a CSV, 
+         * and sends that data to the user
+         * @param {array} exportColumnHeaders an array of column headers, 
+         * where each header is an object with name, width and maybe alignment
+         * @param {array} exportData an array of rows, where each row is
+         * an array of column data
+         * @returns {string} csv the formatted csv as a string
+         */
+        formatAsCsv: function (exportColumnHeaders, exportData) {
+          var self = this;
+          
+          var bareHeaders = exportColumnHeaders.map(function(header){return header.displayName;});
+          
+          var csv = self.formatRowAsCsv(this)(bareHeaders) + '\n';
+          
+          csv += exportData.map(this.formatRowAsCsv(this)).join('\n');
+          
+          return csv;
+        },
+
+        /**
+         * @ngdoc function
+         * @name formatRowAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a csv field, including
+         * quotes around the value
+         * @param {exporterService} exporter pass in exporter 
+         * @param {array} row the row to be turned into a csv string
+         * @returns {string} a csv-ified version of the row
+         */
+        formatRowAsCsv: function ( exporter ) {
+          return function( row ) {
+            return row.map(exporter.formatFieldAsCsv).join(',');
+          };
+        },
+        
+        /**
+         * @ngdoc function
+         * @name formatFieldAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a csv field, including
+         * quotes around the value
+         * @param {field} field the field to be turned into a csv string,
+         * may be of any type
+         * @returns {string} a csv-ified version of the field
+         */
+        formatFieldAsCsv: function (field) {
+          if (field == null) { // we want to catch anything null-ish, hence just == not ===
+            return '';
+          }
+          if (typeof(field) === 'number') {
+            return field;
+          }
+          if (typeof(field) === 'boolean') {
+            return (field ? 'TRUE' : 'FALSE') ;
+          }
+          if (typeof(field) === 'string') {
+            return '"' + field.replace(/"/g,'""') + '"';
+          }
+
+          return JSON.stringify(field);        
+        },
+
+        /**
+         * @ngdoc function
+         * @name renderCsvLink
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Creates a download link with the csv content, 
+         * putting it into the default exporter element, or into the element
+         * passed in if provided
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} csvContent the csv content that we'd like to 
+         * make available as a download link
+         * @param {element} $elm (Optional) A UI element into which the
+         * resulting download link will be placed.  If not provided, the
+         * link is put into the default exporter element. 
+         */
+        renderCsvLink: function (grid, csvContent, $elm) {
+          var targetElm = $elm ? $elm : angular.element( grid.exporter.gridElm[0].querySelectorAll('.ui-grid-exporter-csv-link') );
+          if ( angular.element( targetElm[0].querySelectorAll('.ui-grid-exporter-csv-link-span')) ) {
+            angular.element( targetElm[0].querySelectorAll('.ui-grid-exporter-csv-link-span')).remove();
+          }
+          
+          var linkTemplate = gridUtil.getTemplate(grid.options.exporterLinkTemplate)
+          .then(function (contents) {
+            contents = contents.replace(uiGridExporterConstants.LINK_LABEL, grid.options.exporterLinkLabel);
+            contents = contents.replace(uiGridExporterConstants.CSV_CONTENT, encodeURIComponent(csvContent));
+          
+            var template = angular.element(contents);
+            
+            var newElm = $compile(template)(grid.exporter.$scope);
+            targetElm.append(newElm);
+          });
+          
+        },
+        
+        /**
+         * @ngdoc function
+         * @name pdfExport
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Exports rows from the grid in pdf format, 
+         * the data exported is selected based on the provided options.
+         * Note that this function has a dependency on jsPDF, which must
+         * be either included as a script on your page, or downloaded and
+         * served as part of your site.  The resulting pdf opens in a new
+         * browser window.
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        pdfExport: function (grid, rowTypes, colTypes) {
+          var exportColumnHeaders = this.getColumnHeaders(grid, colTypes);
+          var exportData = this.getData(grid, rowTypes, colTypes);
+          var docDefinition = this.prepareAsPdf(grid, exportColumnHeaders, exportData);
+          
+          pdfMake.createPdf(docDefinition).open();
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name renderAsPdf
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders the data into a pdf, and opens that pdf.
+         * 
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {array} exportColumnHeaders an array of column headers, 
+         * where each header is an object with name, width and maybe alignment
+         * @param {array} exportData an array of rows, where each row is
+         * an array of column data
+         * @returns {object} a pdfMake format document definition, ready 
+         * for generation
+         */        
+        prepareAsPdf: function(grid, exportColumnHeaders, exportData) {
+          var headerWidths = this.calculatePdfHeaderWidths( grid, exportColumnHeaders );
+          
+          var headerColumns = exportColumnHeaders.map( function( header ) {
+            return { text: header.displayName, style: 'tableHeader' }; 
+          });
+          
+          var stringData = exportData.map(this.formatRowAsPdf(this));
+          
+          var allData = [headerColumns].concat(stringData);
+          
+          var docDefinition = {
+            pageOrientation: grid.options.exporterPdfOrientation,
+            content: [{
+              style: 'tableStyle',
+              table: {
+                headerRows: 1,
+                widths: headerWidths,
+                body: allData 
+              }
+            }],
+            styles: {
+              tableStyle: grid.options.exporterPdfTableStyle,
+              tableHeader: grid.options.exporterPdfTableHeaderStyle,
+            },
+            defaultStyle: grid.options.exporterPdfDefaultStyle
+          };
+          
+          if ( grid.options.exporterPdfLayout ){
+            docDefinition.layout = grid.options.exporterPdfLayout;
+          }
+          
+          return docDefinition;
+          
+        },
+        
+                
+        /**
+         * @ngdoc function
+         * @name calculatePdfHeaderWidths
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Determines the column widths base on the 
+         * widths we got from the grid.  If the column is drawn
+         * then we have a drawnWidth.  If the column is not visible
+         * then we have '*', 'x%' or a width.  When columns are
+         * not visible they don't contribute to the overall gridWidth,
+         * so we need to adjust to allow for extra columns
+         * 
+         * Our basic heuristic is to take the current gridWidth, plus 
+         * numeric columns and call this the base gridwidth.
+         * 
+         * To that we add 100 for any '*' column, and x% of the base gridWidth
+         * for any column that is a %
+         *  
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {object} exportHeaders array of header information 
+         * @returns {object} an array of header widths
+         */
+        calculatePdfHeaderWidths: function ( grid, exportHeaders ) {
+          var baseGridWidth = 0;
+          angular.forEach(exportHeaders, function(value){
+            if (typeof(value.width) === 'number'){
+              baseGridWidth += value.width;
+            }
+          });
+          
+          var extraColumns = 0;
+          angular.forEach(exportHeaders, function(value){
+            if (value.width === '*'){
+              extraColumns += 100;
+            }
+            if (typeof(value.width) === 'string' && value.width.match(/(\d)*%/)) {
+              var percent = parseInt(value.width.match(/(\d)*%/)[0]);
+              
+              value.width = baseGridWidth * percent / 100;
+              extraColumns += value.width;
+            }
+          });
+          
+          var gridWidth = baseGridWidth + extraColumns;
+          
+          return exportHeaders.map(function( header ) {
+            return header.width === '*' ? header.width : header.width * grid.options.exporterPdfMaxGridWidth / gridWidth;
+          });
+          
+        },
+        
+        /**
+         * @ngdoc function
+         * @name formatRowAsPdf
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a row in a format consumable by PDF,
+         * mainly meaning casting everything to a string
+         * @param {exporterService} exporter pass in exporter 
+         * @param {array} row the row to be turned into a csv string
+         * @returns {string} a csv-ified version of the row
+         */
+        formatRowAsPdf: function ( exporter ) {
+          return function( row ) {
+            return row.map(exporter.formatFieldAsPdfString);
+          };
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name formatFieldAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a pdf-able field, which
+         * is different from a csv field only in that strings don't have quotes
+         * around them
+         * @param {field} field the field to be turned into a pdf string,
+         * may be of any type
+         * @returns {string} a string-ified version of the field
+         */
+        formatFieldAsPdfString: function (field) {
+          if (field == null) { // we want to catch anything null-ish, hence just == not ===
+            return '';
+          }
+          if (typeof(field) === 'number') {
+            return field.toString();
+          }
+          if (typeof(field) === 'boolean') {
+            return (field ? 'TRUE' : 'FALSE') ;
+          }
+          if (typeof(field) === 'string') {
+            return field.replace(/"/g,'""');
+          }
+
+          return JSON.stringify(field).replace(/^"/,'').replace(/"$/,'');        
+        }
+      };
+
+      return service;
+
+    }
+  ]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.exporter.directive:uiGridExporter
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds exporter features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.gridOptions = {
+        columnDefs: [
+          {name: 'name', enableCellEdit: true},
+          {name: 'title', enableCellEdit: true}
+        ],
+        data: $scope.data
+      };
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="gridOptions" ui-grid-exporter></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridExporter', ['$log', 'uiGridExporterConstants', 'uiGridExporterService', 'gridUtil', '$compile',
+    function ($log, uiGridExporterConstants, uiGridExporterService, gridUtil, $compile) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              uiGridExporterService.initializeGrid(uiGridCtrl.grid);
+              uiGridCtrl.grid.exporter.$scope = $scope;
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }
+  ]);
+})();
+(function() {
+  'use strict';
+  /**
+   *  @ngdoc overview
+   *  @name ui.grid.infiniteScroll
+   *
+   *  @description 
+   *
+   *   #ui.grid.infiniteScroll
+   * This module provides infinite scroll functionality to ui-grid
+   *
+   */
+  var module = angular.module('ui.grid.infiniteScroll', ['ui.grid']);
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+   *
+   *  @description Service for infinite scroll features
+   */
+  module.service('uiGridInfiniteScrollService', ['gridUtil', '$log', '$compile', '$timeout', function (gridUtil, $log, $compile, $timeout) {
+    
+    var service = {
+
+      /**
+       * @ngdoc function
+       * @name initializeGrid
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This method register events and methods into grid public API
+       */
+
+      initializeGrid: function(grid) {
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.infiniteScroll.api:PublicAPI
+         *
+         *  @description Public API for infinite scroll feature
+         */
+        var publicApi = {
+          events: {
+            infiniteScroll: {
+
+              /**
+               * @ngdoc event
+               * @name needLoadMoreData
+               * @eventOf ui.grid.infiniteScroll.api:PublicAPI
+               * @description This event fires when scroll reached bottom percentage of grid
+               * and needs to load data
+               */
+
+              needLoadMoreData: function ($scope, fn) {
+              }
+            }
+          },
+          methods: {
+            infiniteScroll: {
+
+              /**
+               * @ngdoc function
+               * @name dataLoaded
+               * @methodOf ui.grid.infiniteScroll.api:PublicAPI
+               * @description This function is used as a promise when data finished loading.
+               * See infinite_scroll ngdoc for example of usage
+               */
+
+              dataLoaded: function() {
+                grid.options.loadTimout = false;
+              }
+            }
+          }
+        };
+        grid.options.loadTimout = false;
+        grid.api.registerEventsFromObject(publicApi.events);
+        grid.api.registerMethodsFromObject(publicApi.methods);
+      },
+
+      /**
+       * @ngdoc function
+       * @name loadData
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This function fires 'needLoadMoreData' event
+       */
+
+      loadData: function (grid) {
+          grid.api.infiniteScroll.raise.needLoadMoreData();
+          grid.options.loadTimout = true;
+      },
+
+      /**
+       * @ngdoc function
+       * @name checkScroll
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This function checks scroll position inside grid and 
+       * calls 'loadData' function when scroll reaches 'infiniteScrollPercentage'
+       */
+
+      checkScroll: function(grid, scrollTop) {
+
+        /* Take infiniteScrollPercentage value or use 20% as default */
+        var infiniteScrollPercentage = grid.options.infiniteScrollPercentage ? grid.options.infiniteScrollPercentage : 20; 
+
+        if (!grid.options.loadTimout && scrollTop <= infiniteScrollPercentage) {
+          this.loadData(grid);
+          return true;
+        }
+        return false;
+      }
+      /**
+      * @ngdoc property
+      * @name infiniteScrollPercentage
+      * @propertyOf ui.grid.class:GridOptions
+      * @description This setting controls at what percentage of the scroll more data
+      * is requested by the infinite scroll
+      */
+    };
+    return service;
+  }]);
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.infiniteScroll.directive:uiGridInfiniteScroll
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds infinite scroll features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.infiniteScroll']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Alex', car: 'Toyota' },
+            { name: 'Sam', car: 'Lexus' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name'},
+        {name: 'car'}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-infinite-scroll="20"></div>
+   </div>
+   </file>
+   </example>
+   */
+  
+  module.directive('uiGridInfiniteScroll', ['$log', 'uiGridInfiniteScrollService',
+    function ($log, uiGridInfiniteScrollService) {
+      return {
+        priority: -200,
+        scope: false,
+        require: '^uiGrid',
+        compile: function($scope, $elm, $attr){
+          return { 
+            pre: function($scope, $elm, $attr, uiGridCtrl) {
+              uiGridInfiniteScrollService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function($scope, $elm, $attr) {
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridViewport',
+    ['$compile', '$log', 'uiGridInfiniteScrollService', 'uiGridConstants', 
+      function ($compile, $log, uiGridInfiniteScrollService, uiGridConstants) {
+        return {
+          priority: -200,
+          scope: false,
+          link: function ($scope, $elm, $attr){
+            $scope.$on(uiGridConstants.events.GRID_SCROLL, function(evt, args) {
+
+              var percentage = 100 - (args.y.percentage * 100);
+              uiGridInfiniteScrollService.checkScroll($scope.grid, percentage);
+            });
+          }
+        };
+      }]);
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.pinning
+   * @description
+   *
+   *  # ui.grid.pinning
+   * This module provides column pinning to the end user via menu options in the column header
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.pinning"></div>
+   */
+
+  var module = angular.module('ui.grid.pinning', ['ui.grid']);
+
+  module.config(['$provide', function ($provide) {
+    $provide.decorator('i18nService', ['$delegate', function ($delegate) {
+      $delegate.add('en',
+        { pinning: {
+            pinLeft: 'Pin Left',
+            pinRight: 'Pin Right',
+            unpin: 'Unpin'
+          }
+        }
+      );
+
+      return $delegate;
+    }]);
+  }]);
+
+  module.service('uiGridPinningService', ['$log', 'GridRenderContainer', 'i18nService', function ($log, GridRenderContainer, i18nService) {
+    var service = {
+
+      initializeGrid: function (grid) {
+        service.defaultGridOptions(grid.options);
+
+        // Register a column builder to add new menu items for pinning left and right
+        grid.registerColumnBuilder(service.pinningColumnBuilder);
+      },
+
+      defaultGridOptions: function (gridOptions) {
+        //default option to true unless it was explicitly set to false
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.pinning.api:GridOptions
+         *
+         *  @description GridOptions for pinning feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enableRowSelection
+         *  @propertyOf  ui.grid.pinning.api:GridOptions
+         *  @description Enable pinning for the entire grid.  
+         *  <br/>Defaults to true
+         */
+        gridOptions.enablePinning = gridOptions.enablePinning !== false;
+
+      },
+
+      pinningColumnBuilder: function (colDef, col, gridOptions) {
+        //default to true unless gridOptions or colDef is explicitly false
+
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.pinning.api:ColumnDef
+         *
+         *  @description ColumnDef for pinning feature, these are available to be 
+         *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enablePinning
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Enable pinning for the individual column.  
+         *  <br/>Defaults to true
+         */
+        colDef.enablePinning = colDef.enablePinning === undefined ? gridOptions.enablePinning : colDef.enablePinning;
+
+
+        /**
+         *  @ngdoc object
+         *  @name pinnedLeft
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Column is pinned left when grid is rendered
+         *  <br/>Defaults to false
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name pinnedRight
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Column is pinned right when grid is rendered
+         *  <br/>Defaults to false
+         */
+        if (colDef.pinnedLeft) {
+          col.renderContainer = 'left';
+          col.grid.createLeftContainer();
+        }
+        else if (colDef.pinnedRight) {
+          col.renderContainer = 'right';
+          col.grid.createRightContainer();
+        }
+
+        if (!colDef.enablePinning) {
+          return;
+        }
+
+        var pinColumnLeftAction = {
+          title: i18nService.get().pinning.pinLeft,
+          icon: 'ui-grid-icon-left-open',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'left';
+          },
+          action: function () {
+            this.context.col.renderContainer = 'left';
+            this.context.col.grid.createLeftContainer();
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        var pinColumnRightAction = {
+          title: i18nService.get().pinning.pinRight,
+          icon: 'ui-grid-icon-right-open',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'right';
+          },
+          action: function () {
+            this.context.col.renderContainer = 'right';
+            this.context.col.grid.createRightContainer();
+
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        var removePinAction = {
+          title: i18nService.get().pinning.unpin,
+          icon: 'ui-grid-icon-cancel',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) !== 'undefined' && this.context.col.renderContainer !== null && this.context.col.renderContainer !== 'body';
+          },
+          action: function () {
+            this.context.col.renderContainer = null;
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        col.menuItems.push(pinColumnLeftAction);
+        col.menuItems.push(pinColumnRightAction);
+        col.menuItems.push(removePinAction);
+      }
+    };
+
+    return service;
+  }]);
+
+  module.directive('uiGridPinning', ['$log', 'uiGridPinningService',
+    function ($log, uiGridPinningService) {
+      return {
+        require: 'uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              uiGridPinningService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+
+})();
+(function(){
+  'use strict';
+
+  var module = angular.module('ui.grid.resizeColumns', ['ui.grid']);
+
+  module.constant('columnBounds', {
+    minWidth: 35
+  });
+
+
+  module.service('uiGridResizeColumnsService', ['$log','$q',
+    function ($log,$q) {
+
+      var service = {
+        defaultGridOptions: function(gridOptions){
+          //default option to true unless it was explicitly set to false
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.resizeColumns.api:GridOptions
+           *
+           *  @description GridOptions for resizeColumns feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableColumnResizing
+           *  @propertyOf  ui.grid.resizeColumns.api:GridOptions
+           *  @description Enable column resizing on the entire grid 
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableColumnResizing = gridOptions.enableColumnResizing !== false;
+
+          //legacy support
+          //use old name if it is explicitly false
+          if (gridOptions.enableColumnResize === false){
+            gridOptions.enableColumnResizing = false;
+          }
+        },
+
+        colResizerColumnBuilder: function (colDef, col, gridOptions) {
+
+          var promises = [];
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.resizeColumns.api:ColumnDef
+           *
+           *  @description ColumnDef for resizeColumns feature, these are available to be 
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableColumnResizing
+           *  @propertyOf  ui.grid.resizeColumns.api:ColumnDef
+           *  @description Enable column resizing on an individual column
+           *  <br/>Defaults to GridOptions.enableColumnResizing
+           */
+          //default to true unless gridOptions or colDef is explicitly false
+          colDef.enableColumnResizing = colDef.enableColumnResizing === undefined ? gridOptions.enableColumnResizing : colDef.enableColumnResizing;
+
+
+          //legacy support of old option name
+          if (colDef.enableColumnResize === false){
+            colDef.enableColumnResizing = false;
+          }
+
+          return $q.all(promises);
+        }
+      };
+
+      return service;
+
+    }]);
+
+
+  /**
+   * @ngdoc directive
+   * @name ui.grid.resizeColumns.directive:uiGridResizeColumns
+   * @element div
+   * @restrict A
+   * @description
+   * Enables resizing for all columns on the grid. If, for some reason, you want to use the ui-grid-resize-columns directive, but not allow column resizing, you can explicitly set the
+   * option to false. This prevents resizing for the entire grid, regardless of individual columnDef options.
+   *
+   * @example
+   <doc:example module="app">
+   <doc:source>
+   <script>
+   var app = angular.module('app', ['ui.grid', 'ui.grid.resizeColumns']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.gridOpts = {
+            data: [
+              { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
+              { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
+              { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
+              { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
+            ]
+          };
+        }]);
+   </script>
+
+   <div ng-controller="MainCtrl">
+   <div class="testGrid" ui-grid="gridOpts" ui-grid-resize-columns ></div>
+   </div>
+   </doc:source>
+   <doc:scenario>
+
+   </doc:scenario>
+   </doc:example>
+   */
+  module.directive('uiGridResizeColumns', ['$log', 'uiGridResizeColumnsService', function ($log, uiGridResizeColumnsService) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+
+            uiGridResizeColumnsService.defaultGridOptions(uiGridCtrl.grid.options);
+            uiGridCtrl.grid.registerColumnBuilder( uiGridResizeColumnsService.colResizerColumnBuilder);
+
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+          }
+        };
+      }
+    };
+  }]);
+
+  // Extend the uiGridHeaderCell directive
+  module.directive('uiGridHeaderCell', ['$log', '$templateCache', '$compile', '$q', function ($log, $templateCache, $compile, $q) {
+    return {
+      // Run after the original uiGridHeaderCell
+      priority: -10,
+      require: '^uiGrid',
+      // scope: false,
+      compile: function() {
+        return {
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+           if (uiGridCtrl.grid.options.enableColumnResizing) {
+              var renderIndexDefer = $q.defer();
+
+              $attrs.$observe('renderIndex', function (n, o) {
+                $scope.renderIndex = $scope.$eval(n);
+
+                renderIndexDefer.resolve();
+              });
+
+              renderIndexDefer.promise.then(function() {
+                var columnResizerElm = $templateCache.get('ui-grid/columnResizer');
+
+                var resizerLeft = angular.element(columnResizerElm).clone();
+                var resizerRight = angular.element(columnResizerElm).clone();
+
+                resizerLeft.attr('position', 'left');
+                resizerRight.attr('position', 'right');
+
+                var col = $scope.col;
+                var renderContainer = col.getRenderContainer();
+
+
+                // Get the column to the left of this one
+                var otherCol = renderContainer.renderedColumns[$scope.renderIndex - 1];
+
+                // Don't append the left resizer if this is the first column or the column to the left of this one has resizing disabled
+                if (otherCol && $scope.col.index !== 0 && otherCol.colDef.enableColumnResizing !== false) {
+                  $elm.prepend(resizerLeft);
+                }
+                
+                // Don't append the right resizer if this column has resizing disabled
+                //if ($scope.col.index !== $scope.grid.renderedColumns.length - 1 && $scope.col.colDef.enableColumnResizing !== false) {
+                if ($scope.col.colDef.enableColumnResizing !== false) {
+                  $elm.append(resizerRight);
+                }
+
+                $compile(resizerLeft)($scope);
+                $compile(resizerRight)($scope);
+              });
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+
+  
+  /**
+   * @ngdoc directive
+   * @name ui.grid.resizeColumns.directive:uiGridColumnResizer
+   * @element div
+   * @restrict A
+   *
+   * @description
+   * Draggable handle that controls column resizing.
+   * 
+   * @example
+   <doc:example module="app">
+     <doc:source>
+       <script>
+        var app = angular.module('app', ['ui.grid', 'ui.grid.resizeColumns']);
+
+        app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.gridOpts = {
+            enableColumnResizing: true,
+            data: [
+              { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
+              { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
+              { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
+              { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
+            ]
+          };
+        }]);
+       </script>
+
+       <div ng-controller="MainCtrl">
+        <div class="testGrid" ui-grid="gridOpts"></div>
+       </div>
+     </doc:source>
+     <doc:scenario>
+      // TODO: e2e specs?
+        // TODO: Obey minWidth and maxWIdth;
+
+      // TODO: post-resize a horizontal scroll event should be fired
+     </doc:scenario>
+   </doc:example>
+   */  
+  module.directive('uiGridColumnResizer', ['$log', '$document', 'gridUtil', 'uiGridConstants', 'columnBounds', function ($log, $document, gridUtil, uiGridConstants, columnBounds) {
+    var resizeOverlay = angular.element('<div class="ui-grid-resize-overlay"></div>');
+
+    var resizer = {
+      priority: 0,
+      scope: {
+        col: '=',
+        position: '@',
+        renderIndex: '='
+      },
+      require: '?^uiGrid',
+      link: function ($scope, $elm, $attrs, uiGridCtrl) {
+        var startX = 0,
+            x = 0,
+            gridLeft = 0;
+
+        if ($scope.position === 'left') {
+          $elm.addClass('left');
+        }
+        else if ($scope.position === 'right') {
+          $elm.addClass('right');
+        }
+
+        // Resize all the other columns around col
+        function resizeAroundColumn(col) {
+          // Get this column's render container
+          var renderContainer = col.getRenderContainer();
+
+          renderContainer.visibleColumnCache.forEach(function (column) {
+            // Skip the column we just resized
+            if (column.index === col.index) { return; }
+            
+            var colDef = column.colDef;
+            if (!colDef.width || (angular.isString(colDef.width) && (colDef.width.indexOf('*') !== -1 || colDef.width.indexOf('%') !== -1))) {
+              colDef.width = column.drawnWidth;
+            }
+          });
+        }
+
+        // Build the columns then refresh the grid canvas
+        //   takes an argument representing the diff along the X-axis that the resize had
+        function buildColumnsAndRefresh(xDiff) {
+          // Build the columns
+          uiGridCtrl.grid.buildColumns()
+            .then(function() {
+              // Then refresh the grid canvas, rebuilding the styles so that the scrollbar updates its size
+              uiGridCtrl.grid.refreshCanvas(true);
+            });
+        }
+
+        function mousemove(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.preventDefault();
+
+          x = event.clientX - gridLeft;
+
+          if (x < 0) { x = 0; }
+          else if (x > uiGridCtrl.grid.gridWidth) { x = uiGridCtrl.grid.gridWidth; }
+
+          // The other column to resize (the one next to this one)
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+          var otherCol;
+          if ($scope.position === 'left') {
+            // Get the column to the left of this one
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+          }
+
+          // Don't resize if it's disabled on this column
+          if (col.colDef.enableColumnResizing === false) {
+            return;
+          }
+
+          if (!uiGridCtrl.grid.element.hasClass('column-resizing')) {
+            uiGridCtrl.grid.element.addClass('column-resizing');
+          }
+
+          // Get the diff along the X axis
+          var xDiff = x - startX;
+
+          // Get the width that this mouse would give the column
+          var newWidth = col.drawnWidth + xDiff;
+
+          // If the new width would be less than the column's allowably minimum width, don't allow it
+          if (col.colDef.minWidth && newWidth < col.colDef.minWidth) {
+            x = x + (col.colDef.minWidth - newWidth);
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && newWidth < columnBounds.minWidth) {
+            x = x + (col.colDef.minWidth - newWidth);
+          }
+          else if (col.colDef.maxWidth && newWidth > col.colDef.maxWidth) {
+            x = x + (col.colDef.maxWidth - newWidth);
+          }
+          
+          resizeOverlay.css({ left: x + 'px' });
+
+          uiGridCtrl.fireEvent(uiGridConstants.events.ITEM_DRAGGING);
+        }
+
+        function mouseup(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.preventDefault();
+
+          uiGridCtrl.grid.element.removeClass('column-resizing');
+
+          resizeOverlay.remove();
+
+          // Resize the column
+          x = event.clientX - gridLeft;
+          var xDiff = x - startX;
+
+          if (xDiff === 0) {
+            $document.off('mouseup', mouseup);
+            $document.off('mousemove', mousemove);
+            return;
+          }
+
+          // The other column to resize (the one next to this one)
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+
+          var otherCol;
+          if ($scope.position === 'left') {
+            // Get the column to the left of this one
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+          }
+
+          // Don't resize if it's disabled on this column
+          if (col.colDef.enableColumnResizing === false) {
+            return;
+          }
+
+          // Get the new width
+          var newWidth = col.drawnWidth + xDiff;
+
+          // If the new width is less than the minimum width, make it the minimum width
+          if (col.colDef.minWidth && newWidth < col.colDef.minWidth) {
+            newWidth = col.colDef.minWidth;
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && newWidth < columnBounds.minWidth) {
+            newWidth = columnBounds.minWidth;
+          }
+          // 
+          if (col.colDef.maxWidth && newWidth > col.colDef.maxWidth) {
+            newWidth = col.colDef.maxWidth;
+          }
+          
+          col.colDef.width = newWidth;
+
+          // All other columns because fixed to their drawn width, if they aren't already
+          resizeAroundColumn(col);
+
+          buildColumnsAndRefresh(xDiff);
+
+          $document.off('mouseup', mouseup);
+          $document.off('mousemove', mousemove);
+        }
+
+        $elm.on('mousedown', function(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.stopPropagation();
+
+          // Get the left offset of the grid
+          // gridLeft = uiGridCtrl.grid.element[0].offsetLeft;
+          gridLeft = uiGridCtrl.grid.element[0].getBoundingClientRect().left;
+
+          // Get the starting X position, which is the X coordinate of the click minus the grid's offset
+          startX = event.clientX - gridLeft;
+
+          // Append the resizer overlay
+          uiGridCtrl.grid.element.append(resizeOverlay);
+
+          // Place the resizer overlay at the start position
+          resizeOverlay.css({ left: startX });
+
+          // Add handlers for mouse move and up events
+          $document.on('mouseup', mouseup);
+          $document.on('mousemove', mousemove);
+        });
+
+        // On doubleclick, resize to fit all rendered cells
+        $elm.on('dblclick', function(event, args) {
+          event.stopPropagation();
+
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+
+          var otherCol, multiplier;
+
+          // If we're the left-positioned resizer then we need to resize the column to the left of our column, and not our column itself
+          if ($scope.position === 'left') {
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+            multiplier = 1;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+            multiplier = -1;
+          }
+
+          // Go through the rendered rows and find out the max size for the data in this column
+          var maxWidth = 0;
+          var xDiff = 0;
+
+          // Get the parent render container element
+          var renderContainerElm = gridUtil.closestElm($elm, '.ui-grid-render-container');
+
+          // Get the cell contents so we measure correctly. For the header cell we have to account for the sort icon and the menu buttons, if present
+          var cells = renderContainerElm.querySelectorAll('.' + uiGridConstants.COL_CLASS_PREFIX + col.index + ' .ui-grid-cell-contents');
+          Array.prototype.forEach.call(cells, function (cell) {
+              // Get the cell width
+              // $log.debug('width', gridUtil.elementWidth(cell));
+
+              // Account for the menu button if it exists
+              var menuButton;
+              if (angular.element(cell).parent().hasClass('ui-grid-header-cell')) {
+                menuButton = angular.element(cell).parent()[0].querySelectorAll('.ui-grid-column-menu-button');
+              }
+
+              gridUtil.fakeElement(cell, {}, function(newElm) {
+                // Make the element float since it's a div and can expand to fill its container
+                var e = angular.element(newElm);
+                e.attr('style', 'float: left');
+
+                var width = gridUtil.elementWidth(e);
+
+                if (menuButton) {
+                  var menuButtonWidth = gridUtil.elementWidth(menuButton);
+                  width = width + menuButtonWidth;
+                }
+
+                if (width > maxWidth) {
+                  maxWidth = width;
+                  xDiff = maxWidth - width;
+                }
+              });
+            });
+
+          // If the new width is less than the minimum width, make it the minimum width
+          if (col.colDef.minWidth && maxWidth < col.colDef.minWidth) {
+            maxWidth = col.colDef.minWidth;
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && maxWidth < columnBounds.minWidth) {
+            maxWidth = columnBounds.minWidth;
+          }
+          // 
+          if (col.colDef.maxWidth && maxWidth > col.colDef.maxWidth) {
+            maxWidth = col.colDef.maxWidth;
+          }
+
+          col.colDef.width = maxWidth;
+          
+          // All other columns because fixed to their drawn width, if they aren't already
+          resizeAroundColumn(col);
+
+          buildColumnsAndRefresh(xDiff);
+        });
+
+        $elm.on('$destroy', function() {
+          $elm.off('mousedown');
+          $elm.off('dblclick');
+          $document.off('mousemove', mousemove);
+          $document.off('mouseup', mouseup);
+        });
+      }
+    };
+
+    return resizer;
+  }]);
+
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.rowEdit
+   * @description
+   *
+   *  # ui.grid.rowEdit
+   * This module extends the edit feature to provide tracking and saving of rows
+   * of data.  The tutorial provides more information on how this feature is best
+   * used {@link tutorial/205_row_editable here}.
+   * <br/>
+   * This feature depends on usage of the ui-grid-edit feature, and also benefits
+   * from use of ui-grid-cellNav to provide the full spreadsheet-like editing 
+   * experience
+   * 
+   */
+
+  var module = angular.module('ui.grid.rowEdit', ['ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.rowEdit.constant:uiGridRowEditConstants
+   *
+   *  @description constants available in row edit module
+   */
+  module.constant('uiGridRowEditConstants', {
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.rowEdit.service:uiGridRowEditService
+   *
+   *  @description Services for row editing features
+   */
+  module.service('uiGridRowEditService', ['$interval', '$log', '$q', 'uiGridConstants', 'uiGridRowEditConstants', 'gridUtil', 
+    function ($interval, $log, $q, uiGridConstants, uiGridRowEditConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (scope, grid) {
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.rowEdit.api:PublicApi
+           *
+           *  @description Public Api for rowEdit feature
+           */
+          var publicApi = {
+            events: {
+              rowEdit: {
+                /**
+                 * @ngdoc event
+                 * @eventOf ui.grid.rowEdit.api:PublicApi
+                 * @name saveRow
+                 * @description raised when a row is ready for saving.  Once your
+                 * row has saved you may need to use angular.extend to update the
+                 * data entity with any changed data from your save (for example, 
+                 * lock version information if you're using optimistic locking,
+                 * or last update time/user information).
+                 * 
+                 * Your method should call setSavePromise somewhere in the body before
+                 * returning control.  The feature will then wait, with the gridRow greyed out 
+                 * whilst this promise is being resolved.
+                 * 
+                 * <pre>
+                 *      gridApi.rowEdit.on.saveRow(scope,function(rowEntity){})
+                 * </pre>
+                 * and somewhere within the event handler:
+                 * <pre>
+                 *      gridApi.rowEdit.setSavePromise( grid, rowEntity, savePromise)
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @returns {promise} Your saveRow method should return a promise, the
+                 * promise should either be resolved (implying successful save), or 
+                 * rejected (implying an error).
+                 */
+                saveRow: function (rowEntity) {
+                }
+              }
+            },
+            methods: {
+              rowEdit: {
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name setSavePromise
+                 * @description Sets the promise associated with the row save, mandatory that
+                 * the saveRow event handler calls this method somewhere before returning.
+                 * <pre>
+                 *      gridApi.rowEdit.setSavePromise(grid, rowEntity)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be returned
+                 * @param {object} rowEntity a data row from the grid for which a save has
+                 * been initiated
+                 * @param {promise} savePromise the promise that will be resolved when the
+                 * save is successful, or rejected if the save fails
+                 * 
+                 */
+                setSavePromise: function (grid, rowEntity, savePromise) {
+                  service.setSavePromise(grid, rowEntity, savePromise);
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name getDirtyRows
+                 * @description Returns all currently dirty rows
+                 * <pre>
+                 *      gridApi.rowEdit.getDirtyRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be returned
+                 * @returns {array} An array of gridRows that are currently dirty
+                 * 
+                 */
+                getDirtyRows: function (grid) {
+                  return grid.rowEditDirtyRows;
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name getErrorRows
+                 * @description Returns all currently errored rows
+                 * <pre>
+                 *      gridApi.rowEdit.getErrorRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which errored rows should be returned
+                 * @returns {array} An array of gridRows that are currently in error
+                 * 
+                 */
+                getErrorRows: function (grid) {
+                  return grid.rowEditErrorRows;
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name flushDirtyRows
+                 * @description Triggers a save event for all currently dirty rows, could
+                 * be used where user presses a save button or navigates away from the page
+                 * <pre>
+                 *      gridApi.rowEdit.flushDirtyRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be flushed
+                 * @returns {promise} a promise that represents the aggregate of all
+                 * of the individual save promises - i.e. it will be resolved when all
+                 * the individual save promises have been resolved.
+                 * 
+                 */
+                flushDirtyRows: function (grid) {
+                  return service.flushDirtyRows(grid);
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+          grid.api.registerMethodsFromObject(publicApi.methods);
+          
+          grid.api.core.on.renderingComplete( scope, function ( gridApi ) {
+            grid.api.edit.on.afterCellEdit( scope, service.endEditCell );
+            grid.api.edit.on.beginCellEdit( scope, service.beginEditCell );
+            grid.api.edit.on.cancelCellEdit( scope, service.cancelEditCell );
+            
+            if ( grid.api.cellNav ) {
+              grid.api.cellNav.on.navigate( scope, service.navigate );
+            }              
+          });
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.rowEdit.api:GridOptions
+           *
+           *  @description Options for configuring the rowEdit feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name saveRow
+         * @description  Returns a function that saves the specified row from the grid,
+         * and returns a promise
+         * @param {object} grid the grid for which dirty rows should be flushed
+         * @param {GridRow} gridRow the row that should be saved
+         * @returns {function} the saveRow function returns a function.  That function
+         * in turn, when called, returns a promise relating to the save callback
+         */
+        saveRow: function ( grid, gridRow ) {
+          var self = this;
+
+          return function() {
+            gridRow.isSaving = true;
+
+            var promise = grid.api.rowEdit.raise.saveRow( gridRow.entity );
+            
+            if ( gridRow.rowEditSavePromise ){
+              gridRow.rowEditSavePromise.then( self.processSuccessPromise( grid, gridRow ), self.processErrorPromise( grid, gridRow ));
+            } else {
+              $log.log( 'A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise' );
+            }
+            return promise;
+          };
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf  ui.grid.rowEdit.service:uiGridRowEditService
+         * @name setSavePromise
+         * @description Sets the promise associated with the row save, mandatory that
+         * the saveRow event handler calls this method somewhere before returning.
+         * <pre>
+         *      gridApi.rowEdit.setSavePromise(grid, rowEntity)
+         * </pre>
+         * @param {object} grid the grid for which dirty rows should be returned
+         * @param {object} rowEntity a data row from the grid for which a save has
+         * been initiated
+         * @param {promise} savePromise the promise that will be resolved when the
+         * save is successful, or rejected if the save fails
+         * 
+         */
+        setSavePromise: function (grid, rowEntity, savePromise) {
+          var gridRow = grid.getRow( rowEntity );
+          gridRow.rowEditSavePromise = savePromise;
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name processSuccessPromise
+         * @description  Returns a function that processes the successful
+         * resolution of a save promise  
+         * @param {object} grid the grid for which the promise should be processed
+         * @param {GridRow} gridRow the row that has been saved
+         * @returns {function} the success handling function
+         */
+        processSuccessPromise: function ( grid, gridRow ) {
+          var self = this;
+          
+          return function() {
+            delete gridRow.isSaving;
+            delete gridRow.isDirty;
+            delete gridRow.isError;
+            delete gridRow.rowEditSaveTimer;
+            self.removeRow( grid.rowEditErrorRows, gridRow );
+            self.removeRow( grid.rowEditDirtyRows, gridRow );
+          };
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name processErrorPromise
+         * @description  Returns a function that processes the failed
+         * resolution of a save promise  
+         * @param {object} grid the grid for which the promise should be processed
+         * @param {GridRow} gridRow the row that is now in error
+         * @returns {function} the error handling function
+         */
+        processErrorPromise: function ( grid, gridRow ) {
+          return function() {
+            delete gridRow.isSaving;
+            delete gridRow.rowEditSaveTimer;
+
+            gridRow.isError = true;
+            
+            if (!grid.rowEditErrorRows){
+              grid.rowEditErrorRows = [];
+            }
+            grid.rowEditErrorRows.push( gridRow );
+          };
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name removeRow
+         * @description  Removes a row from a cache of rows - either
+         * grid.rowEditErrorRows or grid.rowEditDirtyRows.  If the row
+         * is not present silently does nothing. 
+         * @param {array} rowArray the array from which to remove the row
+         * @param {GridRow} gridRow the row that should be removed
+         */
+        removeRow: function( rowArray, removeGridRow ){
+          angular.forEach( rowArray, function( gridRow, index ){
+            if ( gridRow.uid === removeGridRow.uid ){
+              rowArray.splice( index, 1);
+            }
+          });
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name flushDirtyRows
+         * @description Triggers a save event for all currently dirty rows, could
+         * be used where user presses a save button or navigates away from the page
+         * <pre>
+         *      gridApi.rowEdit.flushDirtyRows(grid)
+         * </pre>
+         * @param {object} grid the grid for which dirty rows should be flushed
+         * @returns {promise} a promise that represents the aggregate of all
+         * of the individual save promises - i.e. it will be resolved when all
+         * the individual save promises have been resolved.
+         * 
+         */
+        flushDirtyRows: function(grid){
+          var promises = [];
+          angular.forEach(grid.rowEditDirtyRows, function( gridRow ){
+            service.saveRow( grid, gridRow )();
+            promises.push( gridRow.rowEditSavePromise );
+          });
+          
+          return $q.all( promises );
+        },
+        
+        
+        /**
+         * @ngdoc property
+         * @propertyOf ui.grid.rowEdit.api:GridOptions
+         * @name rowEditWaitInterval
+         * @description How long the grid should wait for another change on this row
+         * before triggering a save (in milliseconds)
+         * 
+         * @example
+         * Setting the wait interval to 4 seconds
+         * <pre>
+         *   $scope.gridOptions = { rowEditWaitInterval: 4000 }
+         * </pre>
+         * 
+         */
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name endEditCell
+         * @description Receives an afterCellEdit event from the edit function,
+         * and sets flags as appropriate.  Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi. 
+         * @param {object} rowEntity the data entity for which the cell
+         * was edited
+         */        
+        endEditCell: function( rowEntity, colDef, newValue, previousValue ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ $log.log( 'Unable to find rowEntity in grid data, dirty flag cannot be set' ); return; }
+
+          if ( newValue !== previousValue || gridRow.isDirty ){
+            if ( !grid.rowEditDirtyRows ){
+              grid.rowEditDirtyRows = [];
+            }
+            
+            if ( !gridRow.isDirty ){
+              gridRow.isDirty = true;
+              grid.rowEditDirtyRows.push( gridRow );
+            }
+            
+            delete gridRow.isError;
+            
+            service.considerSetTimer( grid, gridRow );
+          }
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name beginEditCell
+         * @description Receives a beginCellEdit event from the edit function,
+         * and cancels any rowEditSaveTimers if present, as the user is still editing
+         * this row.  Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi. 
+         * @param {object} rowEntity the data entity for which the cell
+         * editing has commenced
+         */
+        beginEditCell: function( rowEntity, colDef ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ $log.log( 'Unable to find rowEntity in grid data, timer cannot be cancelled' ); return; }
+          
+          service.cancelTimer( grid, gridRow );
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name cancelEditCell
+         * @description Receives a cancelCellEdit event from the edit function,
+         * and if the row was already dirty, restarts the save timer.  If the row
+         * was not already dirty, then it's not dirty now either and does nothing.
+         * 
+         * Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi.
+         *  
+         * @param {object} rowEntity the data entity for which the cell
+         * editing was cancelled
+         */        
+        cancelEditCell: function( rowEntity, colDef ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ $log.log( 'Unable to find rowEntity in grid data, timer cannot be set' ); return; }
+          
+          service.considerSetTimer( grid, gridRow );
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name navigate
+         * @description cellNav tells us that the selected cell has changed.  If
+         * the new row had a timer running, then stop it similar to in a beginCellEdit
+         * call.  If the old row is dirty and not the same as the new row, then 
+         * start a timer on it.
+         * @param {object} newRowCol the row and column that were selected
+         * @param {object} oldRowCol the row and column that was left
+         * 
+         */
+        navigate: function( newRowCol, oldRowCol ){
+          var grid = this.grid;
+          if ( newRowCol.row.rowEditSaveTimer ){
+            service.cancelTimer( grid, newRowCol.row );
+          }
+
+          if ( oldRowCol && oldRowCol.row && oldRowCol.row !== newRowCol.row ){
+            service.considerSetTimer( grid, oldRowCol.row );
+          }
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name considerSetTimer
+         * @description Consider setting a timer on this row (if it is dirty).  if there is a timer running 
+         * on the row and the row isn't currently saving, cancel it, using cancelTimer, then if the row is 
+         * dirty and not currently saving then set a new timer
+         * @param {object} grid the grid for which we are processing
+         * @param {GridRow} gridRow the row for which the timer should be adjusted
+         * 
+         */
+        considerSetTimer: function( grid, gridRow ){
+          service.cancelTimer( grid, gridRow );
+          
+          if ( gridRow.isDirty && !gridRow.isSaving ){
+            var waitTime = grid.options.rowEditWaitInterval ? grid.options.rowEditWaitInterval : 2000;
+            gridRow.rowEditSaveTimer = $interval( service.saveRow( grid, gridRow ), waitTime, 1);
+          }
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name cancelTimer
+         * @description cancel the $interval for any timer running on this row
+         * then delete the timer itself
+         * @param {object} grid the grid for which we are processing
+         * @param {GridRow} gridRow the row for which the timer should be adjusted
+         * 
+         */
+        cancelTimer: function( grid, gridRow ){
+          if ( gridRow.rowEditSaveTimer && !gridRow.isSaving ){
+            $interval.cancel(gridRow.rowEditSaveTimer);
+            delete gridRow.rowEditSaveTimer;
+          }
+        }
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.rowEdit.directive:uiGridEdit
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds row editing features to the ui-grid-edit directive.
+   *
+   */
+  module.directive('uiGridRowEdit', ['$log', 'uiGridRowEditService', 'uiGridEditConstants', 
+  function ($log, uiGridRowEditService, uiGridEditConstants) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            uiGridRowEditService.initializeGrid($scope, uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {            
+          }
+        };
+      }
+    };
+  }]);
+
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.rowEdit.directive:uiGridViewport
+   *  @element div
+   *
+   *  @description Stacks on top of ui.grid.uiGridViewport to alter the attributes used
+   *  for the grid row to allow coloring of saving and error rows
+   */
+  module.directive('uiGridViewport',
+    ['$compile', 'uiGridConstants', '$log', '$parse',
+      function ($compile, uiGridConstants, $log, $parse) {
+        return {
+          priority: -200, // run after default  directive
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+            rowRepeatDiv.attr("ng-class", "{'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}");
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.selection
+   * @description
+   *
+   *  # ui.grid.selection
+   * This module provides row selection
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.selection"></div>
+   */
+
+  var module = angular.module('ui.grid.selection', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.selection.constant:uiGridSelectionConstants
+   *
+   *  @description constants available in selection module
+   */
+  module.constant('uiGridSelectionConstants', {
+    featureName: "selection"
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.selection.service:uiGridSelectionService
+   *
+   *  @description Services for selection features
+   */
+  module.service('uiGridSelectionService', ['$log', '$q', '$templateCache', 'uiGridSelectionConstants', 'gridUtil',
+    function ($log, $q, $templateCache, uiGridSelectionConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          //add feature namespace and any properties to grid for needed state
+          grid.selection = {};
+          grid.selection.lastSelectedRow = null;
+
+          service.defaultGridOptions(grid.options);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.selection.api:PublicApi
+           *
+           *  @description Public Api for selection feature
+           */
+          var publicApi = {
+            events: {
+              selection: {
+                /**
+                 * @ngdoc event
+                 * @name rowSelectionChanged
+                 * @eventOf  ui.grid.selection.api:PublicApi
+                 * @description  is raised after the row.isSelected state is changed
+                 * @param {GridRow} row the row that was selected/deselected
+                 */
+                rowSelectionChanged: function (scope, row) {
+                }
+              }
+            },
+            methods: {
+              selection: {
+                /**
+                 * @ngdoc function
+                 * @name toggleRowSelection
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Toggles data row as selected or unselected
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                toggleRowSelection: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectRow
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Select the data row
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                selectRow: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null && !row.isSelected) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name unSelectRow
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description UnSelect the data row
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                unSelectRow: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null && row.isSelected) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectAllRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Selects all rows.  Does nothing if multiSelect = false
+                 */
+                selectAllRows: function () {
+                  if (grid.options.multiSelect === false) {
+                    return;
+                  }
+
+                  grid.rows.forEach(function (row) {
+                    row.isSelected = true;
+                  });
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectAllVisibleRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Selects all visible rows.  Does nothing if multiSelect = false
+                 */
+                selectAllVisibleRows: function () {
+                  if (grid.options.multiSelect === false) {
+                    return;
+                  }
+
+                  grid.rows.forEach(function (row) {
+                    if (row.visible) {
+                      row.isSelected = true;
+                    } else {
+                      row.isSelected = false;
+                    }
+                  });
+                },
+                /**
+                 * @ngdoc function
+                 * @name clearSelectedRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Unselects all rows
+                 */
+                clearSelectedRows: function () {
+                  service.clearSelectedRows(grid);
+                },
+                /**
+                 * @ngdoc function
+                 * @name getSelectedRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description returns all selectedRow's entity references
+                 */
+                getSelectedRows: function () {
+                  return service.getSelectedRows(grid).map(function (gridRow) {
+                    return gridRow.entity;
+                  });
+                },
+                /**
+                 * @ngdoc function
+                 * @name getSelectedGridRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description returns all selectedRow's as gridRows
+                 */
+                getSelectedGridRows: function () {
+                  return service.getSelectedRows(grid);
+                },
+                /**
+                 * @ngdoc function
+                 * @name setMultiSelect
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Sets the current gridOption.multiSelect to true or false
+                 * @param {bool} multiSelect true to allow multiple rows
+                 */
+                setMultiSelect: function (multiSelect) {
+                  grid.options.multiSelect = multiSelect;
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+          //default option to true unless it was explicitly set to false
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.selection.api:GridOptions
+           *
+           *  @description GridOptions for selection feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableRowSelection
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable row selection for entire grid.
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableRowSelection = gridOptions.enableRowSelection !== false;
+          /**
+           *  @ngdoc object
+           *  @name multiSelect
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable multiple row selection for entire grid
+           *  <br/>Defaults to true
+           */
+          gridOptions.multiSelect = gridOptions.multiSelect !== false;
+          /**
+           *  @ngdoc object
+           *  @name enableRowHeaderSelection
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable a row header to be used for selection
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableRowHeaderSelection = gridOptions.enableRowHeaderSelection !== false;
+        },
+
+        /**
+         * @ngdoc function
+         * @name toggleRowSelection
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Toggles row as selected or unselected
+         * @param {Grid} grid grid object
+         * @param {GridRow} row row to select or deselect
+         * @param {bool} multiSelect if false, only one row at time can be selected
+         */
+        toggleRowSelection: function (grid, row, multiSelect) {
+          var selected = row.isSelected;
+          if (!multiSelect && !selected) {
+            service.clearSelectedRows(grid);
+          }
+          row.isSelected = !selected;
+          if (row.isSelected === true) {
+            grid.selection.lastSelectedRow = row;
+          }
+          grid.api.selection.raise.rowSelectionChanged(row);
+        },
+        /**
+         * @ngdoc function
+         * @name shiftSelect
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description selects a group of rows from the last selected row using the shift key
+         * @param {Grid} grid grid object
+         * @param {GridRow} clicked row
+         * @param {bool} multiSelect if false, does nothing this is for multiSelect only
+         */
+        shiftSelect: function (grid, row, multiSelect) {
+          if (!multiSelect) {
+            return;
+          }
+          var selectedRows = service.getSelectedRows(grid);
+          var fromRow = selectedRows.length > 0 ? grid.renderContainers.body.visibleRowCache.indexOf(grid.selection.lastSelectedRow) : 0;
+          var toRow = grid.renderContainers.body.visibleRowCache.indexOf(row);
+          //reverse select direction
+          if (fromRow > toRow) {
+            var tmp = fromRow;
+            fromRow = toRow;
+            toRow = tmp;
+          }
+          for (var i = fromRow; i <= toRow; i++) {
+            var rowToSelect = grid.renderContainers.body.visibleRowCache[i];
+            if (rowToSelect) {
+              rowToSelect.isSelected = true;
+              grid.selection.lastSelectedRow = rowToSelect;
+              grid.api.selection.raise.rowSelectionChanged(rowToSelect);
+            }
+          }
+        },
+        /**
+         * @ngdoc function
+         * @name getSelectedRows
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Returns all the selected rows
+         * @param {Grid} grid grid object
+         */
+        getSelectedRows: function (grid) {
+          return grid.rows.filter(function (row) {
+            return row.isSelected;
+          });
+        },
+
+        /**
+         * @ngdoc function
+         * @name clearSelectedRows
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Clears all selected rows
+         * @param {Grid} grid grid object
+         */
+        clearSelectedRows: function (grid) {
+          service.getSelectedRows(grid).forEach(function (row) {
+            row.isSelected = false;
+            grid.api.selection.raise.rowSelectionChanged(row);
+          });
+        }
+
+
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridSelection
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds selection features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name', enableCellEdit: true},
+        {name: 'title', enableCellEdit: true}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-selection></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridSelection', ['$log', 'uiGridSelectionConstants', 'uiGridSelectionService', '$templateCache',
+    function ($log, uiGridSelectionConstants, uiGridSelectionService, $templateCache) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              uiGridSelectionService.initializeGrid(uiGridCtrl.grid);
+              if (uiGridCtrl.grid.options.enableRowHeaderSelection) {
+                var cellTemplate = 'ui-grid/selectionRowHeader';
+                var selectionRowHeaderDef = { name: 'selectionRowHeaderCol', displayName: '', width: 30, cellTemplate: cellTemplate};
+                uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef);
+              }
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridSelectionRowHeaderButtons', ['$log', '$templateCache', 'uiGridSelectionService',
+    function ($log, $templateCache, uiGridSelectionService) {
+      return {
+        replace: true,
+        restrict: 'E',
+        template: $templateCache.get('ui-grid/selectionRowHeaderButtons'),
+        scope: true,
+        require: '^uiGrid',
+        link: function($scope, $elm, $attrs, uiGridCtrl) {
+          var self = uiGridCtrl.grid;
+          $scope.selectButtonClick = function(row, evt) {
+            if (evt.shiftKey) {
+              uiGridSelectionService.shiftSelect(self, row, self.options.multiSelect);
+
+            }
+            else {
+              uiGridSelectionService.toggleRowSelection(self, row, self.options.multiSelect);
+            }
+          };
+        }
+      };
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridViewport
+   *  @element div
+   *
+   *  @description Stacks on top of ui.grid.uiGridViewport to alter the attributes used
+   *  for the grid row
+   */
+  module.directive('uiGridViewport',
+    ['$compile', 'uiGridConstants', 'uiGridSelectionConstants', '$log', '$parse', 'uiGridSelectionService',
+      function ($compile, uiGridConstants, uiGridSelectionConstants, $log, $parse, uiGridSelectionService) {
+        return {
+          priority: -200, // run after default  directive
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+            rowRepeatDiv.attr("ng-class", "{'ui-grid-row-selected': row.isSelected}");
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Stacks on top of ui.grid.uiGridCell to provide selection feature
+   */
+  module.directive('uiGridCell',
+    ['$compile', 'uiGridConstants', 'uiGridSelectionConstants', '$log', '$parse', 'uiGridSelectionService',
+      function ($compile, uiGridConstants, uiGridSelectionConstants, $log, $parse, uiGridSelectionService) {
+        return {
+          priority: -200, // run after default uiGridCell directive
+          restrict: 'A',
+          scope: false,
+          link: function ($scope, $elm, $attrs) {
+
+            if ($scope.grid.options.enableRowSelection && !$scope.grid.options.enableRowHeaderSelection) {
+              $elm.addClass('ui-grid-disable-selection');
+              registerRowSelectionEvents();
+            }
+
+            function registerRowSelectionEvents() {
+              $elm.on('click', function (evt) {
+                if (evt.shiftKey) {
+                  uiGridSelectionService.shiftSelect($scope.grid, $scope.row, $scope.grid.options.multiSelect);
+
+                }
+                else {
+                  uiGridSelectionService.toggleRowSelection($scope.grid, $scope.row, $scope.grid.options.multiSelect);
+                }
+                $scope.$apply();
+              });
+            }
+          }
+        };
+      }]);
+
+})();
+angular.module('ui.grid').run(['$templateCache', function($templateCache) {
+  'use strict';
+
+  $templateCache.put('ui-grid/ui-grid-footer',
+    "<div class=\"ui-grid-footer-panel\"><div ui-grid-group-panel ng-show=\"grid.options.showGroupPanel\"></div><div class=\"ui-grid-footer ui-grid-footer-viewport\"><div class=\"ui-grid-footer-canvas\"><div ng-repeat=\"col in colContainer.renderedColumns track by col.colDef.name\" ui-grid-footer-cell col=\"col\" render-index=\"$index\" class=\"ui-grid-footer-cell clearfix\" ng-style=\"$index === 0 && colContainer.columnStyle($index)\"></div></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-group-panel',
+    "<div class=\"ui-grid-group-panel\"><div ui-t=\"groupPanel.description\" class=\"description\" ng-show=\"groupings.length == 0\"></div><ul ng-show=\"groupings.length > 0\" class=\"ngGroupList\"><li class=\"ngGroupItem\" ng-repeat=\"group in configGroups\"><span class=\"ngGroupElement\"><span class=\"ngGroupName\">{{group.displayName}} <span ng-click=\"removeGroup($index)\" class=\"ngRemoveGroup\">x</span></span> <span ng-hide=\"$last\" class=\"ngGroupArrow\"></span></span></li></ul></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-header',
+    "<div class=\"ui-grid-top-panel\"><div ui-grid-group-panel ng-show=\"grid.options.showGroupPanel\"></div><div class=\"ui-grid-header ui-grid-header-viewport\"><div class=\"ui-grid-header-canvas\"><div class=\"ui-grid-header-cell clearfix\" ng-repeat=\"col in colContainer.renderedColumns track by col.colDef.name\" ui-grid-header-cell col=\"col\" render-index=\"$index\" ng-style=\"$index === 0 && colContainer.columnStyle($index)\"></div></div></div><div ui-grid-menu></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-no-header',
+    "<div class=\"ui-grid-top-panel\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-row',
+    "<div ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" ui-grid-cell></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid',
+    "<div ui-i18n=\"en\" class=\"ui-grid\"><!-- TODO (c0bra): add \"scoped\" attr here, eventually? --><style ui-grid-style>.grid{{ grid.id }} {\n" +
+    "      /* Styles for the grid */\n" +
+    "    }\n" +
+    "\n" +
+    "    .grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {\n" +
+    "      height: {{ grid.options.rowHeight }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    .grid{{ grid.id }} .ui-grid-row:last-child .ui-grid-cell {\n" +
+    "      border-bottom-width: {{ ((grid.getTotalRowHeight() < grid.getViewportHeight()) && '1') || '0' }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    {{ grid.verticalScrollbarStyles }}\n" +
+    "    {{ grid.horizontalScrollbarStyles }}\n" +
+    "\n" +
+    "    .ui-grid[dir=rtl] .ui-grid-viewport {\n" +
+    "      padding-left: {{ grid.verticalScrollbarWidth }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    {{ grid.customStyles }}</style><div ui-grid-render-container container-id=\"'body'\" col-container-name=\"'body'\" row-container-name=\"'body'\" bind-scroll-horizontal=\"true\" bind-scroll-vertical=\"true\" enable-scrollbars=\"grid.options.enableScrollbars\"></div><div ui-grid-column-menu ng-if=\"grid.options.enableColumnMenu\"></div><div ng-transclude></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridCell',
+    "<div class=\"ui-grid-cell-contents\">{{COL_FIELD CUSTOM_FILTERS}}</div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridColumnFilter',
+    "<li class=\"ui-grid-menu-item ui-grid-clearfix ui-grid-column-filter\" ng-show=\"itemShown()\" ng-click=\"$event.stopPropagation();\"><div class=\"input-container\"><input class=\"column-filter-input\" type=\"text\" ng-model=\"item.model\" placeholder=\"{{ i18n.search.placeholder }}\"><div class=\"column-filter-cancel-icon-container\"><i class=\"ui-grid-filter-cancel ui-grid-icon-cancel column-filter-cancel-icon\">&nbsp;</i></div></div><div style=\"button-container\" ng-click=\"item.action($event)\"><div class=\"ui-grid-button\"><i class=\"ui-grid-icon-search\">&nbsp;</i></div></div></li>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridColumnMenu',
+    "<div class=\"ui-grid-column-menu\"><div ui-grid-menu menu-items=\"menuItems\"><!-- <div class=\"ui-grid-column-menu\">\n" +
+    "    <div class=\"inner\" ng-show=\"menuShown\">\n" +
+    "      <ul>\n" +
+    "        <div ng-show=\"grid.options.enableSorting\">\n" +
+    "          <li ng-click=\"sortColumn($event, asc)\" ng-class=\"{ 'selected' : col.sort.direction == asc }\"><i class=\"ui-grid-icon-sort-alt-up\"></i> Sort Ascending</li>\n" +
+    "          <li ng-click=\"sortColumn($event, desc)\" ng-class=\"{ 'selected' : col.sort.direction == desc }\"><i class=\"ui-grid-icon-sort-alt-down\"></i> Sort Descending</li>\n" +
+    "          <li ng-show=\"col.sort.direction\" ng-click=\"unsortColumn()\"><i class=\"ui-grid-icon-cancel\"></i> Remove Sort</li>\n" +
+    "        </div>\n" +
+    "      </ul>\n" +
+    "    </div>\n" +
+    "  </div> --></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridFooterCell',
+    "<div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><div>{{ col.getAggregationValue() }}</div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridHeaderCell',
+    "<div ng-class=\"{ 'sortable': sortable }\"><div class=\"ui-grid-vertical-bar\">&nbsp;</div><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\">{{ col.displayName CUSTOM_FILTERS }} <span ui-grid-visible=\"col.sort.direction\" ng-class=\"{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }\">&nbsp;</span></div><div ng-if=\"grid.options.enableColumnMenu && !col.isRowHeader\" class=\"ui-grid-column-menu-button\" ng-click=\"toggleMenu($event)\"><i class=\"ui-grid-icon-angle-down\">&nbsp;<i></i></i></div><div ng-if=\"filterable\" class=\"ui-grid-filter-container\" ng-repeat=\"colFilter in col.filters\"><input type=\"text\" class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-click=\"$event.stopPropagation()\" ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\"><div class=\"ui-grid-filter-button\" ng-click=\"colFilter.term = null\"><i class=\"ui-grid-icon-cancel right\" ng-show=\"!!colFilter.term\">&nbsp;</i> <!-- use !! because angular interprets 'f' as false --></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridMenu',
+    "<div class=\"ui-grid-menu\"><div class=\"ui-grid-menu-inner\" ng-show=\"shown\"><ul class=\"ui-grid-menu-items\"><li ng-repeat=\"item in menuItems\" ui-grid-menu-item action=\"item.action\" title=\"item.title\" active=\"item.active\" icon=\"item.icon\" shown=\"item.shown\" context=\"item.context\" template-url=\"item.templateUrl\"></li></ul></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridMenuItem',
+    "<li class=\"ui-grid-menu-item\" ng-click=\"itemAction($event, title)\" ng-show=\"itemShown()\" ng-class=\"{ 'ui-grid-menu-item-active' : active() }\"><i ng-class=\"icon\"></i> {{ title }}</li>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridRenderContainer',
+    "<div class=\"ui-grid-render-container\"><div ui-grid-header></div><div ui-grid-viewport></div><div ui-grid-footer ng-if=\"grid.options.showFooter\"></div><!-- native scrolling --><div ui-grid-native-scrollbar ng-if=\"enableScrollbars\" type=\"vertical\"></div><div ui-grid-native-scrollbar ng-if=\"enableScrollbars\" type=\"horizontal\"></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridViewport',
+    "<div class=\"ui-grid-viewport\"><div class=\"ui-grid-canvas\"><div ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by row.uid\" class=\"ui-grid-row\" ng-style=\"containerCtrl.rowStyle(rowRenderIndex)\"><div ui-grid-row=\"row\" row-render-index=\"rowRenderIndex\"></div></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/cellEditor',
+    "<div><form name=\"inputForm\"><input type=\"{{inputType}}\" ng-class=\"'colt' + col.index\" ui-grid-editor ng-model=\"COL_FIELD\"></form></div>"
+  );
+
+
+  $templateCache.put('ui-grid/dropdownEditor',
+    "<div><form name=\"inputForm\"><select ng-class=\"'colt' + col.index\" ui-grid-edit-dropdown ng-model=\"COL_FIELD\" ng-options=\"field[editDropdownIdLabel] as field[editDropdownValueLabel] CUSTOM_FILTERS for field in editDropdownOptionsArray\"></select></form></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableRow',
+    "<div ui-grid-expandable-row ng-if=\"expandableRow.shouldRenderExpand()\" class=\"expandableRow\" style=\"float:left;margin-top: 1px;margin-bottom: 1px\" ng-style=\"{width: (grid.renderContainers.body.getCanvasWidth() - grid.verticalScrollbarWidth)\n" +
+    "     ,height: grid.options.expandable.expandableRowHeight}\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableRowHeader',
+    "<div class=\"ui-grid-row-header-cell uiGridExpandableButtonsCell\"><div class=\"ui-grid-cell-contents\"><i ng-class=\"{'ui-grid-icon-plus-squared':!row.isExpanded, 'ui-grid-icon-minus-squared':row.isExpanded}\" ng-click=\"grid.api.expandable.toggleRowExpansion(row.entity)\"></i></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableScrollFiller',
+    "<div ng-if=\"expandableRow.shouldRenderFiller()\" style=\"float:left;margin-top: 2px;margin-bottom: 2px\" ng-style=\"{width: (grid.getViewportWidth())\n" +
+    "     ,height: grid.options.expandable.expandableRowHeight, 'margin-left': grid.options.rowHeader.rowHeaderWidth}\"><i class=\"ui-grid-icon-spin5 ui-grid-animate-spin\" ng-style=\"{'margin-top': ( grid.options.expandable.expandableRowHeight/2 - 5),\n" +
+    "            'margin-left':((grid.getViewportWidth() - grid.options.rowHeader.rowHeaderWidth)/2 - 5)}\"></i></div>"
+  );
+
+
+  $templateCache.put('ui-grid/csvLink',
+    "<span class=\"ui-grid-exporter-csv-link-span\"><a href=\"data:text/csv;charset=UTF-8,CSV_CONTENT\">LINK_LABEL</a></span>"
+  );
+
+
+  $templateCache.put('ui-grid/columnResizer',
+    "<div ui-grid-column-resizer ng-if=\"grid.options.enableColumnResizing\" class=\"ui-grid-column-resizer\" col=\"col\" position=\"right\" render-index=\"renderIndex\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionRowHeader',
+    "<div class=\"ui-grid-row-header-cell ui-grid-disable-selection\"><div class=\"ui-grid-cell-contents\"><ui-grid-selection-row-header-buttons></ui-grid-selection-row-header-buttons></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionRowHeaderButtons',
+    "<div class=\"ui-grid-selection-row-header-buttons ui-grid-icon-ok\" ng-class=\"{'ui-grid-row-selected': row.isSelected}\" ng-click=\"selectButtonClick(row, $event)\">&nbsp;</div>"
+  );
+
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.min.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid-stable.min.js
new file mode 100644 (file)
index 0000000..84b4ab8
--- /dev/null
@@ -0,0 +1,7 @@
+/*! ui-grid - v3.0.0-rc.3 - 2014-09-25
+* Copyright (c) 2014 ; License: MIT */
+!function(){"use strict";angular.module("ui.grid.i18n",[]),angular.module("ui.grid",["ui.grid.i18n"])}(),function(){"use strict";angular.module("ui.grid").constant("uiGridConstants",{CUSTOM_FILTERS:/CUSTOM_FILTERS/g,COL_FIELD:/COL_FIELD/g,DISPLAY_CELL_TEMPLATE:/DISPLAY_CELL_TEMPLATE/g,TEMPLATE_REGEXP:/<.+>/,FUNC_REGEXP:/(\([^)]*\))?$/,DOT_REGEXP:/\./g,APOS_REGEXP:/'/g,BRACKET_REGEXP:/^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,COL_CLASS_PREFIX:"ui-grid-col",events:{GRID_SCROLL:"uiGridScroll",COLUMN_MENU_SHOWN:"uiGridColMenuShown",ITEM_DRAGGING:"uiGridItemDragStart"},keymap:{TAB:9,STRG:17,CTRL:17,CTRLRIGHT:18,CTRLR:18,SHIFT:16,RETURN:13,ENTER:13,BACKSPACE:8,BCKSP:8,ALT:18,ALTR:17,ALTRIGHT:17,SPACE:32,WIN:91,MAC:91,FN:null,UP:38,DOWN:40,LEFT:37,RIGHT:39,ESC:27,DEL:46,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123},ASC:"asc",DESC:"desc",filter:{STARTS_WITH:2,ENDS_WITH:4,EXACT:8,CONTAINS:16,GREATER_THAN:32,GREATER_THAN_OR_EQUAL:64,LESS_THAN:128,LESS_THAN_OR_EQUAL:256,NOT_EQUAL:512},aggregationTypes:{sum:2,count:4,avg:8,min:16,max:32},CURRENCY_SYMBOLS:["ƒ","$","£","$","¤","¥","៛","₩","₱","฿","₫"]})}(),angular.module("ui.grid").directive("uiGridCell",["$compile","$log","$parse","gridUtil","uiGridConstants",function(a,b,c,d,e){var f={priority:0,scope:!1,require:"?^uiGrid",compile:function(){return{pre:function(b,c,d,f){function g(){var a=b.col.compiledElementFn;a(b,function(a){c.append(a)})}if(f)g();else{var h=b.col.cellTemplate.replace(e.COL_FIELD,"grid.getCellValue(row, col)"),i=a(h)(b);c.append(i)}},post:function(a,b){if(b.addClass(a.col.getColClass(!1)),a.col.cellClass){var c=b;c.addClass(angular.isFunction(a.col.cellClass)?a.col.cellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.cellClass)}}}}};return f}]),function(){angular.module("ui.grid").directive("uiGridColumnMenu",["$log","$timeout","$window","$document","$injector","gridUtil","uiGridConstants","i18nService",function(a,b,c,d,e,f,g,h){var i={priority:0,scope:!0,require:"?^uiGrid",templateUrl:"ui-grid/uiGridColumnMenu",replace:!0,link:function(i,j,k,l){function m(){i.$apply(i.hideMenu),d.off("click",m)}function n(){i.$apply(i.hideMenu)}f.enableAnimations(j),i.grid=l.grid;var o=this;l.columnMenuScope=i,o.shown=i.menuShown=!1,i.asc=g.ASC,i.desc=g.DESC,i.menu=j[0].querySelectorAll(".ui-grid-menu"),i.inner=j[0].querySelectorAll(".ui-grid-menu-inner"),i.sortable=function(){return l.grid.options.enableSorting&&"undefined"!=typeof i.col&&i.col&&i.col.enableSorting?!0:!1},i.filterable=function(){return l.grid.options.enableFiltering&&"undefined"!=typeof i.col&&i.col&&i.col.enableFiltering?!0:!1};var p=[{title:h.getSafeText("sort.ascending"),icon:"ui-grid-icon-sort-alt-up",action:function(a){a.stopPropagation(),i.sortColumn(a,g.ASC)},shown:function(){return i.sortable()},active:function(){return"undefined"!=typeof i.col&&"undefined"!=typeof i.col.sort&&"undefined"!=typeof i.col.sort.direction&&i.col.sort.direction===g.ASC}},{title:h.getSafeText("sort.descending"),icon:"ui-grid-icon-sort-alt-down",action:function(a){a.stopPropagation(),i.sortColumn(a,g.DESC)},shown:function(){return i.sortable()},active:function(){return"undefined"!=typeof i.col&&"undefined"!=typeof i.col.sort&&"undefined"!=typeof i.col.sort.direction&&i.col.sort.direction===g.DESC}},{title:h.getSafeText("sort.remove"),icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),i.unsortColumn()},shown:function(){return i.sortable()&&"undefined"!=typeof i.col&&"undefined"!=typeof i.col.sort&&"undefined"!=typeof i.col.sort.direction&&null!==i.col.sort.direction}},{title:h.getSafeText("column.hide"),icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),i.hideColumn()}}];i.menuItems=p,i.$watch("col.menuItems",function(a){"undefined"!=typeof a&&a&&angular.isArray(a)?(a.forEach(function(a){"undefined"!=typeof a.context&&a.context||(a.context={}),a.context.col=i.col}),i.menuItems=p.concat(a)):i.menuItems=p});var q;try{q=e.get("$animate")}catch(r){a.info("$animate service not found (ngAnimate not add as a dependency?), menu animations will not occur")}i.showMenu=function(a,c){function e(){b(function(){p&&q?(q.removeClass(i.inner,"ng-hide"),o.shown=i.menuShown=!0,i.$broadcast("show-menu")):angular.element(i.inner).hasClass("ng-hide")&&angular.element(i.inner).removeClass("ng-hide");var b=a.renderContainer?a.renderContainer:"body",e=(a.grid.renderContainers[b],f.closestElm(c,".ui-grid-render-container")),k=e.offsetLeft-i.grid.element[0].offsetLeft,r=e.querySelectorAll(".ui-grid-viewport")[0].scrollLeft,s=f.elementWidth(i.menu,!0),t=parseInt(angular.element(i.menu).css("padding-right"),10);j.css("left",g+k-r+n-s+t+"px"),j.css("top",h+l+"px"),d.on("click",m)})}o.col=i.col=a,d.off("click",m);var g=c[0].offsetLeft,h=c[0].offsetTop,k=0;a.grid.options.offsetLeft&&(k=a.grid.options.offsetLeft);var l=f.elementHeight(c,!0),n=f.elementWidth(c,!0),p=!1;i.menuShown&&q?(q.addClass(i.inner,"ng-hide",e),p=!0):(o.shown=i.menuShown=!0,i.$broadcast("show-menu"),e())},i.hideMenu=function(){delete o.col,delete i.col,o.shown=i.menuShown=!1,i.$broadcast("hide-menu")},angular.element(c).bind("resize",n),i.$on("$destroy",i.$on(g.events.GRID_SCROLL,function(){i.hideMenu()})),i.$on("$destroy",i.$on(g.events.ITEM_DRAGGING,function(){i.hideMenu()})),i.$on("$destroy",function(){angular.element(c).off("resize",n),d.off("click",m)}),i.sortColumn=function(a,b){a.stopPropagation(),l.grid.sortColumn(i.col,b,!0).then(function(){l.grid.refresh(),i.hideMenu()})},i.unsortColumn=function(){i.col.unsort(),l.grid.refresh(),i.hideMenu()},i.hideColumn=function(){i.col.colDef.visible=!1,l.grid.refresh(),i.hideMenu()}},controller:["$scope",function(a){var b=this;a.$watch("menuItems",function(a){b.menuItems=a})}]};return i}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooterCell",["$log","$timeout","gridUtil","$compile",function(a,b,c,d){var e={priority:0,scope:{col:"=",row:"=",renderIndex:"="},replace:!0,require:"^uiGrid",compile:function(){return{pre:function(a,b){function e(e){c.getTemplate(e).then(function(c){var e=d(c),f=e(a);b.append(f)})}e(a.col.footerCellTemplate?a.col.footerCellTemplate:"ui-grid/uiGridFooterCell")},post:function(a,b,c,d){a.grid=d.grid,b.addClass(a.col.getColClass(!1))}}}};return e}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooter",["$log","$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){var f="ui-grid/ui-grid-footer";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,b,d,g){var h=g[0],i=g[1];a.grid=h.grid,a.colContainer=i.colContainer,i.footer=b;var j=a.grid.options.footerTemplate?a.grid.options.footerTemplate:f;e.getTemplate(j).then(function(d){var e=angular.element(d),f=c(e)(a);if(b.append(f),i){var g=b[0].getElementsByClassName("ui-grid-footer-viewport")[0];g&&(i.footerViewport=g)}})},post:function(b,c,d,f){var g=f[0],h=f[1];a.debug("ui-grid-footer link");g.grid;e.disableAnimations(c),h.footer=c;var i=c[0].getElementsByClassName("ui-grid-footer-viewport")[0];i&&(h.footerViewport=i)}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGroupPanel",["$compile","uiGridConstants","gridUtil",function(a,b,c){var d="ui-grid/ui-grid-group-panel";return{restrict:"EA",replace:!0,require:"?^uiGrid",scope:!1,compile:function(){return{pre:function(b,e){var f=b.grid.options.groupPanelTemplate||d;c.getTemplate(f).then(function(c){var d=angular.element(c),f=a(d)(b);e.append(f)})},post:function(a,b){b.bind("$destroy",function(){})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeaderCell",["$log","$compile","$timeout","$window","$document","gridUtil","uiGridConstants",function(a,b,c,d,e,f,g){var h=500,i={priority:0,scope:{col:"=",row:"=",renderIndex:"="},require:"?^uiGrid",replace:!0,compile:function(){return{pre:function(a,c){var d=b(a.col.headerCellTemplate)(a);c.append(d)},post:function(a,b,d,e){function f(b){var c=!1;b.shiftKey&&(c=!0),e.grid.sortColumn(a.col,c).then(function(){e.columnMenuScope&&e.columnMenuScope.hideMenu(),e.grid.refresh()})}a.grid=e.grid,a.grid.api.core.raise.filterChanged||a.grid.api.registerEvent("core","filterChanged"),b.addClass(a.col.getColClass(!1)),a.menuShown=!1,a.asc=g.ASC,a.desc=g.DESC;var i=(angular.element(b[0].querySelectorAll(".ui-grid-header-cell-menu")),angular.element(b[0].querySelectorAll(".ui-grid-cell-contents")));a.sortable=e.grid.options.enableSorting&&a.col.enableSorting?!0:!1,a.filterable=e.grid.options.enableFiltering&&a.col.enableFiltering?!0:!1;var j,k=0;if(i.on("mousedown",function(d){"undefined"!=typeof d.originalEvent&&void 0!==d.originalEvent&&(d=d.originalEvent),d.button&&0!==d.button||(k=(new Date).getTime(),j=c(function(){},h),j.then(function(){e.columnMenuScope.showMenu(a.col,b)}))}),i.on("mouseup",function(){c.cancel(j)}),a.toggleMenu=function(c){c.stopPropagation(),e.columnMenuScope.menuShown&&e.columnMenuScope.col===a.col?e.columnMenuScope.hideMenu():e.columnMenuScope.showMenu(a.col,b)},a.sortable&&(i.on("click",function(a){a.stopPropagation(),c.cancel(j);var b=(new Date).getTime(),d=b-k;d>h||f(a)}),a.$on("$destroy",function(){c.cancel(j)})),a.filterable){var l=[];angular.forEach(a.col.filters,function(b,c){l.push(a.$watch("col.filters["+c+"].term",function(){e.grid.api.core.raise.filterChanged(),e.grid.refresh().then(function(){e.prevScrollArgs&&e.prevScrollArgs.y&&e.prevScrollArgs.y.percentage&&e.fireScrollingEvent({y:{percentage:e.prevScrollArgs.y.percentage}})})}))}),a.$on("$destroy",function(){angular.forEach(l,function(a){a()})})}}}}};return i}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeader",["$log","$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d,e){var f="ui-grid/ui-grid-header",g="ui-grid/ui-grid-no-header";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,b,d,h){var i=h[0],j=h[1];a.grid=i.grid,a.colContainer=j.colContainer,j.header=b,j.colContainer.header=b;var k;k=a.grid.options.hideHeader?g:a.grid.options.headerTemplate?a.grid.options.headerTemplate:f,e.getTemplate(k).then(function(d){var e=angular.element(d),f=c(e)(a);if(b.append(f),j){var g=b[0].getElementsByClassName("ui-grid-header-viewport")[0];g&&(j.headerViewport=g)}})},post:function(b,c,d,f){function g(){var a=[],b=[],c=0,d=i.colContainer.getViewportWidth();"undefined"!=typeof h.grid.verticalScrollbarWidth&&void 0!==h.grid.verticalScrollbarWidth&&h.grid.verticalScrollbarWidth>0&&(d+=h.grid.verticalScrollbarWidth);var f,g=0,k=0,l="",m=i.colContainer.visibleColumnCache;m.forEach(function(d){if(d.visible){var f=!1;angular.isNumber(d.width)||(f=isNaN(d.width)?e.endsWith(d.width,"%"):!1),angular.isString(d.width)&&-1!==d.width.indexOf("*")?(c=parseInt(c+d.width.length,10),a.push(d)):f?b.push(d):angular.isNumber(d.width)&&(g=parseInt(g+d.width,10),k=parseInt(k,10)+parseInt(d.width,10),d.drawnWidth=d.width)}});var n,o,p,q=d-g;if(b.length>0){for(n=0;n<b.length;n++){o=b[n];var r=parseInt(o.width.replace(/%/g,""),10)/100;p=parseInt(r*q,10),o.colDef.minWidth&&p<o.colDef.minWidth?(p=o.colDef.minWidth,q-=p,k+=p,o.drawnWidth=p,b.splice(n,1)):o.colDef.maxWidth&&p>o.colDef.maxWidth&&(p=o.colDef.maxWidth,q-=p,k+=p,o.drawnWidth=p,b.splice(n,1))}b.forEach(function(a){var b=parseInt(a.width.replace(/%/g,""),10)/100,c=parseInt(b*q,10);k+=c,a.drawnWidth=c})}if(a.length>0){var s=parseInt(q/c,10);for(n=0;n<a.length;n++)o=a[n],p=parseInt(s*o.width.length,10),o.colDef.minWidth&&p<o.colDef.minWidth?(p=o.colDef.minWidth,q-=p,c--,k+=p,o.drawnWidth=p,f=o,a.splice(n,1)):o.colDef.maxWidth&&p>o.colDef.maxWidth&&(p=o.colDef.maxWidth,q-=p,c--,k+=p,o.drawnWidth=p,a.splice(n,1));s=parseInt(q/c,10),a.forEach(function(a){var b=parseInt(s*a.width.length,10);k+=b,a.drawnWidth=b})}var t=d-parseInt(k,10);if(t>0&&k>0&&d>k){var u=!1;if(m.forEach(function(a){a.width&&!angular.isNumber(a.width)&&(u=!0)}),u)for(var v=function(a){t>0&&(a.drawnWidth=a.drawnWidth+1,k+=1,t--)};t>0;)m.forEach(v)}return d>k&&(k=d),m.forEach(function(a){l+=a.getColClassDefinition()}),j.verticalScrollbarWidth&&(k+=j.verticalScrollbarWidth),i.colContainer.canvasWidth=parseInt(k,10),l}var h=f[0],i=f[1];a.debug("ui-grid-header link");var j=h.grid;e.disableAnimations(c),i.header=c;var k=c[0].getElementsByClassName("ui-grid-header-viewport")[0];k&&(i.headerViewport=k),h&&h.grid.registerStyleComputation({priority:5,func:g})}}}}}])}(),function(){angular.module("ui.grid").directive("uiGridMenu",["$log","$compile","$timeout","$window","$document","gridUtil",function(a,b,c,d,e,f){var g={priority:0,scope:{menuItems:"=",autoHide:"=?"},require:"?^uiGrid",templateUrl:"ui-grid/uiGridMenu",replace:!1,link:function(a,b){f.enableAnimations(b),("undefined"==typeof a.autoHide||void 0===a.autoHide)&&(a.autoHide=!0),a.autoHide&&angular.element(d).on("resize",a.hideMenu),a.$on("hide-menu",function(){a.shown=!1}),a.$on("show-menu",function(){a.shown=!0}),a.$on("$destroy",function(){angular.element(d).off("resize",a.hideMenu)})},controller:["$scope","$element","$attrs",function(a){function b(){a.$apply(function(){d.hideMenu(),angular.element(document).off("click",b)})}var d=this;d.hideMenu=a.hideMenu=function(){a.shown=!1},d.showMenu=a.showMenu=function(){a.shown=!0,angular.element(document).off("click",b),c(function(){angular.element(document).on("click",b)})},a.$on("$destroy",function(){angular.element(document).off("click",b)})}]};return g}]).directive("uiGridMenuItem",["$log","gridUtil","$compile","i18nService",function(a,b,c,d){var e={priority:0,scope:{title:"=",active:"=",action:"=",icon:"=",shown:"=",context:"=",templateUrl:"="},require:["?^uiGrid","^uiGridMenu"],templateUrl:"ui-grid/uiGridMenuItem",replace:!0,compile:function(){return{pre:function(a,d,e,f){f[0],f[1];a.templateUrl&&b.getTemplate(a.templateUrl).then(function(b){var e=angular.element(b),f=c(e)(a);d.replaceWith(f)})},post:function(b,c,e,f){var g=f[0],h=f[1];("undefined"==typeof b.shown||null===b.shown)&&(b.shown=function(){return!0}),b.itemShown=function(){var a={};return b.context&&(a.context=b.context),"undefined"!=typeof g&&g&&(a.grid=g.grid),b.shown.call(a)},b.itemAction=function(c,d){if(a.debug("itemAction"),c.stopPropagation(),"function"==typeof b.action){var e={};b.context&&(e.context=b.context),"undefined"!=typeof g&&g&&(e.grid=g.grid),b.action.call(e,c,d),h.hideMenu()}},b.i18n=d.get()}}}};return e}])}(),function(){angular.module("ui.grid").directive("uiGridNativeScrollbar",["$log","$timeout","$document","uiGridConstants","gridUtil",function(a,b,c,d,e){var f=e.getScrollbarWidth();f=f>0?f:17;var g=e.detectBrowser();return"ie"===g&&(f+=1),{scope:{type:"@"},require:["^uiGrid","^uiGridRenderContainer"],link:function(a,b,c,g){function h(){var a=n.getViewportHeight(),b=n.getCanvasHeight(),c=o.headerHeight?o.headerHeight:p.headerHeight,d=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.vertical .contents { height: "+b+"px; }";return d+="\n .grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.vertical { height: "+a+"px; top: "+c+"px}",s=b,d}function i(){var a=o.getCanvasWidth(),b=-1*f+u;p.options.showFooter&&(b-=1);var c=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.horizontal { bottom: "+b+"px; }";return c+=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.horizontal .contents { width: "+a+"px; }",s=a,c}function j(){if("vertical"===a.type){p.flagScrollingVertically();var c=b[0].scrollTop,d=n.getCanvasHeight()-n.getViewportHeight();p.horizontalScrollbarHeight&&p.horizontalScrollbarHeight>0&&(d-=l.grid.horizontalScrollbarHeight);var f=c/d;f>1&&(f=1),0>f&&(f=0);var g={target:b,y:{percentage:f}};a.scrollSource?a.scrollSource=null:l.fireScrollingEvent(g),r=c}else if("horizontal"===a.type){p.flagScrollingHorizontally();var h=e.normalizeScrollLeft(b),i=o.getCanvasWidth()-o.getViewportWidth(),j=h/i,k={target:b,x:{percentage:j}};a.scrollSource?a.scrollSource=null:l.fireScrollingEvent(k),r=h}}function k(c,d){if(!d.target||d.target!==b&&!angular.element(d.target).hasClass("ui-grid-native-scrollbar"))if(a.scrollSource=d.target,"vertical"===a.type){if(d.y&&"undefined"!=typeof d.y.percentage&&void 0!==d.y.percentage){p.flagScrollingVertically();var f=n.getCanvasHeight()-n.getViewportHeight(),g=Math.max(0,d.y.percentage*f);b[0].scrollTop=g}}else if("horizontal"===a.type&&d.x&&"undefined"!=typeof d.x.percentage&&void 0!==d.x.percentage){p.flagScrollingHorizontally();var h=o.getCanvasWidth()-o.getViewportWidth(),i=Math.max(0,d.x.percentage*h);b[0].scrollLeft=e.denormalizeScrollLeft(b,i)}}var l=g[0],m=g[1],n=m.rowContainer,o=m.colContainer,p=l.grid,q=angular.element('<div class="contents">&nbsp;</div>');b.addClass("ui-grid-native-scrollbar");var r,s=0;"vertical"===a.type?(b.css("width",f+"px"),b.addClass("vertical"),p.verticalScrollbarWidth=f,o.verticalScrollbarWidth=f,r=b[0].scrollTop):"horizontal"===a.type&&(b.css("height",f+"px"),b.addClass("horizontal"),p.horizontalScrollbarHeight=f,n.horizontalScrollbarHeight=f,r=e.normalizeScrollLeft(b)),b.append(q),"vertical"===a.type?s=e.elementHeight(b):"horizontal"===a.type&&(s=e.elementWidth(b));var t=e.closestElm(b,".ui-grid"),u=e.getBorderSize(t,"bottom");"vertical"===a.type?p.registerStyleComputation({priority:6,func:h}):"horizontal"===a.type&&p.registerStyleComputation({priority:6,func:i}),a.scrollSource=null,b.on("scroll",j),b.on("$destroy",function(){b.off("scroll")});var v=a.$on(d.events.GRID_SCROLL,k);a.$on("$destroy",v)}}}])}(),function(){"use strict";var a=angular.module("ui.grid");a.directive("uiGridRenderContainer",["$log","$timeout","$document","uiGridConstants","gridUtil",function(a,b,c,d,e){return{replace:!0,transclude:!0,templateUrl:"ui-grid/uiGridRenderContainer",require:["^uiGrid","uiGridRenderContainer"],scope:{containerId:"=",rowContainerName:"=",colContainerName:"=",bindScrollHorizontal:"=",bindScrollVertical:"=",enableScrollbars:"="},controller:"uiGridRenderContainer as RenderContainer",compile:function(){return{pre:function(b,c,d,e){a.debug("render container "+b.containerId+" pre-link");var f=e[0],g=e[1],h=b.grid=f.grid;if(!b.rowContainerName)throw"No row render container name specified";if(!b.colContainerName)throw"No column render container name specified";if(!h.renderContainers[b.rowContainerName])throw"Row render container '"+b.rowContainerName+"' is not registered.";if(!h.renderContainers[b.colContainerName])throw"Column render container '"+b.colContainerName+"' is not registered.";var i=b.rowContainer=h.renderContainers[b.rowContainerName],j=b.colContainer=h.renderContainers[b.colContainerName];g.containerId=b.containerId,g.rowContainer=i,g.colContainer=j},post:function(b,f,g,h){function i(a,c){if(c.y&&b.bindScrollVertical){n.prevScrollArgs=c;var d=p.getCanvasHeight()-p.getViewportHeight();o.horizontalScrollbarHeight&&o.horizontalScrollbarHeight>0&&(d+=o.horizontalScrollbarHeight);var f,g=n.viewport[0].scrollTop;if("undefined"!=typeof c.y.percentage&&void 0!==c.y.percentage)f=c.y.percentage;else{if("undefined"==typeof c.y.pixels||void 0===c.y.pixels)throw new Error("No percentage or pixel value provided for scroll event Y axis");f=c.y.percentage=(g+c.y.pixels)/d}var h=Math.max(0,f*d);n.viewport[0].scrollTop=h,n.prevScrollArgs.y.pixels=h-g}if(c.x&&b.bindScrollHorizontal){n.prevScrollArgs=c;var i,j=q.getCanvasWidth()-q.getViewportWidth(),k=e.normalizeScrollLeft(n.viewport);if("undefined"!=typeof c.x.percentage&&void 0!==c.x.percentage)i=c.x.percentage;else{if("undefined"==typeof c.x.pixels||void 0===c.x.pixels)throw new Error("No percentage or pixel value provided for scroll event X axis");i=c.x.percentage=(k+c.x.pixels)/j}var l=Math.max(0,i*j);n.viewport[0].scrollLeft=e.denormalizeScrollLeft(n.viewport,l),n.prevScrollLeft=l,n.headerViewport&&(n.headerViewport.scrollLeft=e.denormalizeScrollLeft(n.headerViewport,l)),n.footerViewport&&(n.footerViewport.scrollLeft=e.denormalizeScrollLeft(n.footerViewport,l)),n.prevScrollArgs.x.pixels=l-k}}function j(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault();var b,c,d,e;d=a.targetTouches[0].screenX,e=a.targetTouches[0].screenY,b=-(d-u),c=-(e-t),x=1>c?-1:1,y=1>b?-1:1,c*=2,b*=2;var f={target:a.target};if(0!==c){var g=(v+c)/(p.getCanvasHeight()-p.getViewportHeight());g>1?g=1:0>g&&(g=0),f.y={percentage:g,pixels:c}}if(0!==b){var h=(w+b)/(q.getCanvasWidth()-q.getViewportWidth());h>1?h=1:0>h&&(h=0),f.x={percentage:h,pixels:b}}m.fireScrollingEvent(f)}function k(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),c.unbind("touchmove",j),c.unbind("touchend",k),c.unbind("touchcancel",k);{var b=n.viewport[0].scrollTop,d=n.viewport[0].scrollTop;Math.abs(b-v),Math.abs(d-w),new Date-s}}function l(){var a="",c=q.getCanvasWidth(),d=q.getViewportWidth(),e=p.getCanvasHeight(),f=p.getViewportHeight(),g=q.getHeaderViewportWidth(),h=q.getHeaderViewportWidth();return a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-canvas { width: "+c+"px; height: "+e+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-header-canvas { width: "+c+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-viewport { width: "+d+"px; height: "+f+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-header-viewport { width: "+g+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-footer-canvas { width: "+c+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+b.containerId+" .ui-grid-footer-viewport { width: "+h+"px; }"}a.debug("render container "+b.containerId+" post-link");var m=h[0],n=h[1],o=m.grid,p=n.rowContainer,q=n.colContainer;f.addClass("ui-grid-render-container-"+b.containerId);var r;(b.bindScrollHorizontal||b.bindScrollVertical)&&(r=b.$on(d.events.GRID_SCROLL,i)),f.bind("wheel mousewheel DomMouseScroll MozMousePixelScroll",function(a){a.preventDefault();var b=e.normalizeWheelEvent(a),c={target:f};if(0!==b.deltaY){var d=-120*b.deltaY,g=(n.viewport[0].scrollTop+d)/(p.getCanvasHeight()-p.getViewportHeight());0>g?g=0:g>1&&(g=1),c.y={percentage:g,pixels:d}}if(0!==b.deltaX){var h=-120*b.deltaX,i=e.normalizeScrollLeft(n.viewport),j=(i+h)/(q.getCanvasWidth()-q.getViewportWidth());0>j?j=0:j>1&&(j=1),c.x={percentage:j,pixels:h}}m.fireScrollingEvent(c)});var s,t=0,u=0,v=0,w=0,x=1,y=1;e.isTouchEnabled()&&f.bind("touchstart",function(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),m.scrollbars.forEach(function(a){a.addClass("ui-grid-scrollbar-visible"),a.addClass("ui-grid-scrolling")}),s=new Date,t=a.targetTouches[0].screenY,u=a.targetTouches[0].screenX,v=n.viewport[0].scrollTop,w=n.viewport[0].scrollLeft,c.on("touchmove",j),c.on("touchend touchcancel",k)}),f.bind("$destroy",function(){r(),f.unbind("keydown"),["touchstart","touchmove","touchend","keydown","wheel","mousewheel","DomMouseScroll","MozMousePixelScroll"].forEach(function(a){f.unbind(a)})}),m.grid.registerStyleComputation({priority:6,func:l})}}}}}]),a.controller("uiGridRenderContainer",["$scope","$log",function(a){var b=this;b.rowStyle=function(c){var d=a.grid.renderContainers[a.containerId],e={};if(!d.disableRowOffset&&0===c&&0!==b.currentTopRow){var f=a.rowContainer.currentTopRow*a.rowContainer.visibleRowCache[a.rowContainer.currentTopRow].height;e["margin-top"]=f+"px"}return d.disableColumnOffset||0===a.colContainer.currentFirstColumn||(a.grid.isRTL()?e["margin-right"]=a.colContainer.columnOffset+"px":e["margin-left"]=a.colContainer.columnOffset+"px"),e},b.columnStyle=function(b){var c=a.grid.renderContainers[a.containerId];if(!c.disableColumnOffset&&0===b&&0!==a.colContainer.currentFirstColumn){var d=a.colContainer.columnOffset;return a.grid.isRTL()?{"margin-right":d+"px"}:{"margin-left":d+"px"}}return null}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridRow",["$log",function(){return{replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:{row:"=uiGridRow",rowRenderIndex:"="},compile:function(){return{pre:function(a,b,c,d){var e=d[0],f=d[1],g=e.grid;a.grid=e.grid,a.colContainer=f.colContainer,g.getRowTemplateFn.then(function(c){c(a,function(a){b.replaceWith(a)})})},post:function(a,b,c,d){{var e=d[0];d[1]}a.getExternalScopes=e.getExternalScopes}}}}}])}(),function(){angular.module("ui.grid").directive("uiGridStyle",["$log","$interpolate",function(a,b){return{link:function(c,d){a.debug("ui-grid-style link");var e=b(d.text(),!0);e&&c.$watch(e,function(a){d.text(a)})}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridViewport",["$log","gridUtil",function(a,b){return{replace:!0,scope:{},templateUrl:"ui-grid/uiGridViewport",require:["^uiGrid","^uiGridRenderContainer"],link:function(c,d,e,f){a.debug("viewport post-link");var g=f[0],h=f[1];c.containerCtrl=h;{var i=h.rowContainer,j=h.colContainer;g.grid}c.grid=g.grid,c.rowContainer=h.rowContainer,c.colContainer=h.colContainer,h.viewport=d,d.on("scroll",function(){var a=d[0].scrollTop,c=b.normalizeScrollLeft(d);if(c!==j.prevScrollLeft){var e=(c-j.prevScrollLeft,j.getCanvasWidth()-j.getViewportWidth()),f=c/e;j.adjustScrollHorizontal(c,f)}if(a!==i.prevScrollTop){var g=(a-i.prevScrollTop,i.getCanvasHeight()-i.getViewportHeight()),h=a/g;h>1&&(h=1),0>h&&(h=0),i.adjustScrollVertical(a,h)}})}}}])}(),function(){angular.module("ui.grid").directive("uiGridVisible",function(){return function(a,b,c){a.$watch(c.uiGridVisible,function(a){b[a?"removeClass":"addClass"]("ui-grid-invisible")})}})}(),function(){"use strict";angular.module("ui.grid").controller("uiGridController",["$scope","$element","$attrs","$log","gridUtil","$q","uiGridConstants","$templateCache","gridClassFactory","$timeout","$parse","$compile",function(a,b,c,d,e,f,g,h,i,j,k,l){function m(a,b){a&&a!==b&&(o.grid.options.columnDefs=a,o.grid.buildColumns().then(function(){o.grid.preCompileCellTemplates(),o.grid.refreshCanvas(!0)}))}function n(b){var e=[];b&&(0===o.grid.columns.length&&(d.debug("loading cols in dataWatchFunction"),c.uiGridColumns||0!==o.grid.options.columnDefs.length||o.grid.buildColumnDefsFromData(b),e.push(o.grid.buildColumns().then(function(){o.grid.preCompileCellTemplates()}))),f.all(e).then(function(){o.grid.modifyRows(b).then(function(){o.grid.redrawInPlace(),a.$evalAsync(function(){o.grid.refreshCanvas(!0)})})}))}d.debug("ui-grid controller");var o=this;o.grid=i.createGrid(a.uiGrid),b.addClass("grid"+o.grid.id),o.grid.rtl="rtl"===b.css("direction"),o.getExternalScopes=a.getExternalScopes,a.grid=o.grid,c.uiGridColumns&&c.$observe("uiGridColumns",function(a){o.grid.options.columnDefs=a,o.grid.buildColumns().then(function(){o.grid.preCompileCellTemplates(),o.grid.refreshCanvas(!0)})});var p;p=angular.isString(a.uiGrid.data)?a.$parent.$watchCollection(a.uiGrid.data,n):a.$parent.$watchCollection(function(){return a.uiGrid.data},n);var q=a.$parent.$watchCollection(function(){return a.uiGrid.columnDefs},m);a.$on("$destroy",function(){p(),q()}),a.$watch(function(){return o.grid.styleComputations},function(){o.grid.refreshCanvas(!0)}),o.fireScrollingEvent=function(b){a.$broadcast(g.events.GRID_SCROLL,b)},o.fireEvent=function(b,c){("undefined"==typeof c||void 0===c)&&(c={}),("undefined"==typeof c.grid||void 0===c.grid)&&(c.grid=o.grid),a.$broadcast(b,c)},o.innerCompile=function(b){l(b)(a)}}]),angular.module("ui.grid").directive("uiGrid",["$log","$compile","$templateCache","gridUtil","$window",function(a,b,c,d,e){return{templateUrl:"ui-grid/ui-grid",scope:{uiGrid:"=",getExternalScopes:"&?externalScopes"},replace:!0,transclude:!0,controller:"uiGridController",compile:function(){return{post:function(b,c,f,g){function h(){i.gridWidth=b.gridWidth=d.elementWidth(c),i.gridHeight=b.gridHeight=d.elementHeight(c),i.queueRefresh()}a.debug("ui-grid postlink");var i=g.grid;if(g.scrollbars=[],i.renderingComplete(),i.element=c,i.gridWidth=b.gridWidth=d.elementWidth(c),i.canvasWidth=g.grid.gridWidth,i.gridHeight=b.gridHeight=d.elementHeight(c),i.gridHeight<i.options.rowHeight){var j=i.options.minRowsToShow*i.options.rowHeight;c.css("height",j+"px"),i.gridHeight=b.gridHeight=d.elementHeight(c)}i.refreshCanvas();var k=angular.element('<div ng-if="grid.hasLeftContainer()" style="width: 0" ui-grid-pinned-container="\'left\'"></div>');c.prepend(k),g.innerCompile(k);var l=angular.element('<div  ng-if="grid.hasRightContainer()" style="width: 0" ui-grid-pinned-container="\'right\'"></div>');c.append(l),g.innerCompile(l),b.$watch(function(){return i.hasLeftContainer()},function(a,b){a!==b&&i.refreshCanvas(!0)}),b.$watch(function(){return i.hasRightContainer()},function(a,b){a!==b&&i.refreshCanvas(!0)}),angular.element(e).on("resize",h),c.on("$destroy",function(){angular.element(e).off("resize",h)})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridPinnedContainer",["$log",function(a){return{restrict:"EA",replace:!0,template:'<div class="ui-grid-pinned-container"><div ui-grid-render-container container-id="side" row-container-name="\'body\'" col-container-name="side" bind-scroll-vertical="true" class="{{ side }} ui-grid-render-container-{{ side }}"></div></div>',scope:{side:"=uiGridPinnedContainer"},require:"^uiGrid",compile:function(){return{post:function(b,c,d,e){function f(){var a="";if("left"===b.side||"right"===b.side){for(var d=g.renderContainers[b.side].visibleColumnCache,e=0,f=0;f<d.length;f++){var i=d[f];e+=i.drawnWidth}h=e,c.attr("style",null);var j=g.renderContainers.body.getViewportHeight();a+=".grid"+g.id+" .ui-grid-pinned-container-"+b.side+", .grid"+g.id+" .ui-grid-pinned-container-"+b.side+" .ui-grid-render-container-"+b.side+" .ui-grid-viewport { width: "+h+"px; height: "+j+"px; } "}return a}a.debug("ui-grid-pinned-container "+b.side+" link");var g=e.grid,h=0;c.addClass("ui-grid-pinned-container-"+b.side),g.renderContainers.body.registerViewportAdjuster(function(a){return a.width-=h,a}),g.registerStyleComputation({priority:15,func:f})}}}}}])}(),function(){angular.module("ui.grid").factory("Grid",["$log","$q","$compile","$parse","gridUtil","uiGridConstants","GridOptions","GridColumn","GridRow","GridApi","rowSorter","rowSearcher","GridRenderContainer","$timeout",function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){function o(){}var p=function(a){var b=this;if(void 0===a||"undefined"==typeof a.id||!a.id)throw new Error("No ID provided. An ID must be given when creating a grid.");if(!/^[_a-zA-Z0-9-]+$/.test(a.id))throw new Error("Grid id '"+a.id+'" is invalid. It must follow CSS selector syntax rules.');b.id=a.id,delete a.id,b.options=new g,angular.extend(b.options,a),b.headerHeight=b.options.headerRowHeight,b.footerHeight=b.options.showFooter===!0?b.options.footerRowHeight:0,b.rtl=!1,b.gridHeight=0,b.gridWidth=0,b.columnBuilders=[],b.rowBuilders=[],b.rowsProcessors=[],b.columnsProcessors=[],b.styleComputations=[],b.viewportAdjusters=[],b.rowHeaderColumns=[],b.renderContainers={},b.renderContainers.body=new m("body",b),b.cellValueGetterCache={},b.getRowTemplateFn=null,b.rows=[],b.columns=[],b.isScrollingVertically=!1,b.isScrollingHorizontally=!1;var c=e.debounce(function(){b.isScrollingVertically=!1},300),d=e.debounce(function(){b.isScrollingHorizontally=!1},300);b.flagScrollingVertically=function(){b.isScrollingVertically=!0,c()},b.flagScrollingHorizontally=function(){b.isScrollingHorizontally=!0,d()},b.api=new j(b),b.api.registerMethod("core","refresh",this.refresh),b.api.registerMethod("core","refreshRows",this.refreshRows),b.api.registerEvent("core","sortChanged")};return p.prototype.isRTL=function(){return this.rtl},p.prototype.registerColumnBuilder=function(a){this.columnBuilders.push(a)},p.prototype.buildColumnDefsFromData=function(a){this.options.columnDefs=e.getColumnsFromData(a,this.options.excludeProperties)},p.prototype.registerRowBuilder=function(a){this.rowBuilders.push(a)},p.prototype.getColumn=function(a){var b=this.columns.filter(function(b){return b.colDef.name===a
+});return b.length>0?b[0]:null},p.prototype.getColDef=function(a){var b=this.options.columnDefs.filter(function(b){return b.name===a});return b.length>0?b[0]:null},p.prototype.assignTypes=function(){var b=this;b.options.columnDefs.forEach(function(c,d){if(!c.type){var f=new h(c,d,b),g=b.rows.length>0?b.rows[0]:null;g?c.type=e.guessType(b.getCellValue(g,f)):(a.log("Unable to assign type from data, so defaulting to string"),c.type="string")}})},p.prototype.addRowHeaderColumn=function(a){var b=this,c=new h(a,b.rowHeaderColumns.length+1,b);c.isRowHeader=!0,b.isRTL()?(b.createRightContainer(),c.renderContainer="right"):(b.createLeftContainer(),c.renderContainer="left"),b.columnBuilders[0](a,c,b.gridOptions).then(function(){c.enableFiltering=!1,c.enableSorting=!1,b.rowHeaderColumns.push(c)})},p.prototype.buildColumns=function(){a.debug("buildColumns");var c=this,d=[],e=c.rowHeaderColumns.length;return angular.forEach(c.rowHeaderColumns,function(a){e++,c.columns.push(a)}),c.columns.length>c.options.columnDefs.length&&c.columns.forEach(function(a,b){c.getColDef(a.name)||c.columns.splice(b,1)}),c.options.columnDefs.forEach(function(a,b){c.preprocessColDef(a);var f=c.getColumn(a.name);f?f.updateColumnDef(a,f.index):(f=new h(a,b+e,c),c.columns.push(f)),c.columnBuilders.forEach(function(b){d.push(b.call(c,a,f,c.options))})}),b.all(d)},p.prototype.preCompileCellTemplates=function(){this.columns.forEach(function(a){var b=a.cellTemplate.replace(f.COL_FIELD,"grid.getCellValue(row, col)"),d=c(b);a.compiledElementFn=d})},p.prototype.createLeftContainer=function(){this.hasLeftContainer()||(this.renderContainers.left=new m("left",this,{disableColumnOffset:!0}))},p.prototype.createRightContainer=function(){this.hasRightContainer()||(this.renderContainers.right=new m("right",this,{disableColumnOffset:!0}))},p.prototype.hasLeftContainer=function(){return void 0!==this.renderContainers.left},p.prototype.hasRightContainer=function(){return void 0!==this.renderContainers.right},p.prototype.preprocessColDef=function(a){if(!a.field&&!a.name)throw new Error("colDef.name or colDef.field property is required");void 0===a.name&&void 0!==a.field&&(a.name=a.field)},p.prototype.newInN=function(a,b,c,d){for(var e=this,f=[],g=0;g<b.length;g++){for(var h=d?b[g][d]:b[g],i=!1,j=0;j<a.length;j++){var k=c?a[j][c]:a[j];if(e.options.rowEquality(h,k)){i=!0;break}}i||f.push(h)}return f},p.prototype.getRow=function(a){var b=this.rows.filter(function(b){return b.entity===a});return b.length>0?b[0]:null},p.prototype.modifyRows=function(a){var c,d,e=this;if(0===e.rows.length&&a.length>0){if(e.options.enableRowHashing)for(e.rowHashMap||e.createRowHashMap(),c=0;c<a.length;c++)d=a[c],e.rowHashMap.put(d,{i:c,entity:d});e.addRows(a),e.assignTypes()}else if(a.length>0){var f,g,h;if(e.options.enableRowHashing){f=[],h=[];var i={};g=[],e.rowHashMap||e.createRowHashMap();var j=e.rowHashMap;for(c=0;c<a.length;c++){d=a[c];var k=!1;e.options.getRowIdentity(d)||(k=!0);var l=j.get(d);l?l.row&&(i[e.options.rowIdentity(d)]=!0):(j.put(d,{i:c,entity:d}),k?h.push(d):f.push(d))}for(c=0;c<e.rows.length;c++){var m=e.rows[c],n=e.options.rowIdentity(m.entity);i[n]||g.push(m)}}var o=f||[],p=h||a;o=o.concat(e.newInN(e.rows,p,"entity")),e.addRows(o);var q=e.getDeletedRows(g||e.rows,a);for(c=0;c<q.length;c++)e.options.enableRowHashing&&e.rowHashMap.remove(q[c].entity),e.rows.splice(e.rows.indexOf(q[c]),1)}else e.createRowHashMap(),e.rows.length=0;var r=b.when(e.processRowsProcessors(e.rows)).then(function(a){return e.setVisibleRows(a)}),s=b.when(e.processColumnsProcessors(e.columns)).then(function(a){return e.setVisibleColumns(a)});return b.all([r,s])},p.prototype.getDeletedRows=function(a,b){var c=this,d=a.filter(function(a){return!b.some(function(b){return c.options.rowEquality(b,a.entity)})});return d},p.prototype.addRows=function(a){for(var b=this,c=b.rows.length,d=0;d<a.length;d++){var e=b.processRowBuilders(new i(a[d],d+c,b));if(b.options.enableRowHashing){var f=b.rowHashMap.get(e.entity);f&&(f.row=e)}b.rows.push(e)}},p.prototype.processRowBuilders=function(a){var b=this;return b.rowBuilders.forEach(function(c){c.call(b,a,b.gridOptions)}),a},p.prototype.registerStyleComputation=function(a){this.styleComputations.push(a)},p.prototype.registerRowsProcessor=function(a){if(!angular.isFunction(a))throw"Attempt to register non-function rows processor: "+a;this.rowsProcessors.push(a)},p.prototype.removeRowsProcessor=function(a){var b=this.rowsProcessors.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.rowsProcessors.splice(b,1)},p.prototype.processRowsProcessors=function(a){function c(a,e){var g=d.rowsProcessors[a];return b.when(g.call(d,e,d.columns)).then(function(b){if(!b)throw"Processor at index "+a+" did not return a set of renderable rows";if(!angular.isArray(b))throw"Processor at index "+a+" did not return an array";return a++,a<=d.rowsProcessors.length-1?c(a,b):void f.resolve(b)})}var d=this,e=a.slice(0);if(0===d.rowsProcessors.length)return b.when(e);var f=b.defer();return c(0,e),f.promise},p.prototype.setVisibleRows=function(a){var b=this;for(var c in b.renderContainers){var d=b.renderContainers[c];d.visibleRowCache.length=0}for(var e=0;e<a.length;e++){var f=a[e];f.visible&&("undefined"!=typeof f.renderContainer&&f.renderContainer?b.renderContainers[f.renderContainer].visibleRowCache.push(f):b.renderContainers.body.visibleRowCache.push(f))}},p.prototype.registerColumnsProcessor=function(a){if(!angular.isFunction(a))throw"Attempt to register non-function rows processor: "+a;this.columnsProcessors.push(a)},p.prototype.removeColumnsProcessor=function(a){var b=this.columnsProcessors.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.columnsProcessors.splice(b,1)},p.prototype.processColumnsProcessors=function(a){function c(a,g){var h=d.columnsProcessors[a];return b.when(h.call(d,g,d.rows)).then(function(b){if(!b)throw"Processor at index "+a+" did not return a set of renderable rows";if(!angular.isArray(b))throw"Processor at index "+a+" did not return an array";return a++,a<=d.columnsProcessors.length-1?c(a,e):void f.resolve(e)})}var d=this,e=a.slice(0);if(0===d.columnsProcessors.length)return b.when(e);var f=b.defer();return c(0,e),f.promise},p.prototype.setVisibleColumns=function(a){var b=this;for(var c in b.renderContainers){var d=b.renderContainers[c];d.visibleColumnCache.length=0}for(var e=0;e<a.length;e++){var f=a[e];f.visible&&("undefined"!=typeof f.renderContainer&&f.renderContainer?b.renderContainers[f.renderContainer].visibleColumnCache.push(f):b.renderContainers.body.visibleColumnCache.push(f))}},p.prototype.handleWindowResize=function(){var a=this;a.gridWidth=e.elementWidth(a.element),a.gridHeight=e.elementHeight(a.element),a.queueRefresh()},p.prototype.queueRefresh=function(){var a=this;return a.refreshCanceller&&n.cancel(a.refreshCanceller),a.refreshCanceller=n(function(){a.refreshCanvas(!0)}),a.refreshCanceller.then(function(){a.refreshCanceller=null}),a.refreshCanceller},p.prototype.buildStyles=function(){var a=this;a.customStyles="",a.styleComputations.sort(function(a,b){return null===a.priority?1:null===b.priority?-1:null===a.priority&&null===b.priority?0:a.priority-b.priority}).forEach(function(b){var c=b.func.call(a);angular.isString(c)&&(a.customStyles+="\n"+c)})},p.prototype.minColumnsToRender=function(){var a=this,b=this.getViewportWidth(),c=0,d=0;return a.columns.forEach(function(e,f){if(b>d)d+=e.drawnWidth,c++;else{for(var g=0,h=f;h>=f-c;h--)g+=a.columns[h].drawnWidth;b>g&&c++}}),c},p.prototype.getBodyHeight=function(){var a=this.getViewportHeight();return"undefined"!=typeof this.horizontalScrollbarHeight&&void 0!==this.horizontalScrollbarHeight&&this.horizontalScrollbarHeight>0&&(a+=this.horizontalScrollbarHeight),a},p.prototype.getViewportHeight=function(){var a=this,b=this.gridHeight-this.headerHeight-this.footerHeight;"undefined"!=typeof this.horizontalScrollbarHeight&&void 0!==this.horizontalScrollbarHeight&&this.horizontalScrollbarHeight>0&&(b-=this.horizontalScrollbarHeight);var c=a.getViewportAdjustment();return b+=c.height},p.prototype.getViewportWidth=function(){var a=this,b=this.gridWidth;"undefined"!=typeof this.verticalScrollbarWidth&&void 0!==this.verticalScrollbarWidth&&this.verticalScrollbarWidth>0&&(b-=this.verticalScrollbarWidth);var c=a.getViewportAdjustment();return b+=c.width},p.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return"undefined"!=typeof this.verticalScrollbarWidth&&void 0!==this.verticalScrollbarWidth&&this.verticalScrollbarWidth>0&&(a+=this.verticalScrollbarWidth),a},p.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},p.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.viewportAdjusters.splice(b,1)},p.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},p.prototype.getVisibleRowCount=function(){return this.renderContainers.body.visibleRowCache.length},p.prototype.getVisibleRows=function(){return this.renderContainers.body.visibleRowCache},p.prototype.getVisibleColumnCount=function(){return this.renderContainers.body.visibleColumnCache.length},p.prototype.searchRows=function(a){return l.search(this,a,this.columns)},p.prototype.sortByColumn=function(a){return k.sort(this,a,this.columns)},p.prototype.getCellValue=function(a,b){var c=this;return c.cellValueGetterCache[b.colDef.name]||(c.cellValueGetterCache[b.colDef.name]=d(a.getEntityQualifiedColField(b))),c.cellValueGetterCache[b.colDef.name](a)},p.prototype.getNextColumnSortPriority=function(){var a=this,b=0;return a.columns.forEach(function(a){a.sort&&a.sort.priority&&a.sort.priority>b&&(b=a.sort.priority)}),b+1},p.prototype.resetColumnSorting=function(a){var b=this;b.columns.forEach(function(b){b!==a&&(b.sort={})})},p.prototype.getColumnSorting=function(){var a,b=this,c=[];return a=b.columns.slice(0),a.sort(k.prioritySort).forEach(function(a){a.sort&&"undefined"!=typeof a.sort.direction&&a.sort.direction&&(a.sort.direction===f.ASC||a.sort.direction===f.DESC)&&c.push(a)}),c},p.prototype.sortColumn=function(a,c,d){var e=this,g=null;if("undefined"==typeof a||!a)throw new Error("No column parameter provided");return"boolean"==typeof c?d=c:g=c,d?a.sort.priority=e.getNextColumnSortPriority():(e.resetColumnSorting(a),a.sort.priority=0),a.sort.direction=g?g:a.sort.direction&&a.sort.direction===f.ASC?f.DESC:a.sort.direction&&a.sort.direction===f.DESC?null:f.ASC,e.api.core.raise.sortChanged(e,e.getColumnSorting()),b.when(a)},p.prototype.renderingComplete=function(){angular.isFunction(this.options.onRegisterApi)&&this.options.onRegisterApi(this.api),this.api.core.raise.renderingComplete(this.api)},p.prototype.createRowHashMap=function(){var a=this,b=new o;b.grid=a,a.rowHashMap=b},p.prototype.refresh=function(){a.debug("grid refresh");var c=this,d=c.processRowsProcessors(c.rows).then(function(a){c.setVisibleRows(a)}),e=c.processColumnsProcessors(c.columns).then(function(a){c.setVisibleColumns(a)});return b.all([d,e]).then(function(){c.redrawInPlace(),c.refreshCanvas(!0)})},p.prototype.refreshRows=function(){var a=this;return a.processRowsProcessors(a.rows).then(function(b){a.setVisibleRows(b),a.redrawRows(),a.refreshCanvas()})},p.prototype.refreshCanvas=function(a){var c=this;a&&c.buildStyles();var d=b.defer(),f=[];for(var g in c.renderContainers)if(c.renderContainers.hasOwnProperty(g)){var h=c.renderContainers[g];h.header&&f.push(h)}return n(f.length>0?function(){for(var b=!1,g=0;g<f.length;g++){var h=f[g];if(h.header){var i=h.headerHeight,j=e.outerElementHeight(h.header);h.headerHeight=j,i!==j&&(b=!0)}}a&&b&&c.buildStyles(),d.resolve()}:function(){d.resolve()}),d.promise},p.prototype.redrawInPlace=function(){var a=this;for(var b in a.renderContainers){var c=a.renderContainers[b];c.adjustRows(c.prevScrollTop,null),c.adjustColumns(c.prevScrollLeft,null)}},o.prototype={put:function(a,b){this[this.grid.options.rowIdentity(a)]=b},get:function(a){return this[this.grid.options.rowIdentity(a)]},remove:function(a){var b=this[a=this.grid.options.rowIdentity(a)];return delete this[a],b}},p}])}(),function(){angular.module("ui.grid").factory("GridApi",["$log","$q","$rootScope","gridUtil","uiGridConstants",function(a,b,c,d){function e(a,b,c,d){return a.$on(b,function(){var a=Array.prototype.slice.call(arguments);a.splice(0,1),c.apply(d.api,a)})}var f=function(a){this.grid=a,this.listeners=[],this.registerEvent("core","renderingComplete")};return f.prototype.suppressEvents=function(a,b){var c=this,d=angular.isArray(a)?a:[a],f=[];d.forEach(function(a){f=c.listeners.filter(function(b){return a===b.handler})}),f.forEach(function(a){a.dereg()}),b(),f.forEach(function(a){a.dereg=e(a.scope,a.eventId,a.handler,c.grid)})},f.prototype.registerEvent=function(b,d){var f=this;f[b]||(f[b]={});var g=f[b];g.on||(g.on={},g.raise={});var h=f.grid.id+b+d;a.log("Creating raise event method "+b+".raise."+d),g.raise[d]=function(){c.$broadcast.apply(c,[h].concat(Array.prototype.slice.call(arguments)))},a.log("Creating on event method "+b+".on."+d),g.on[d]=function(a,b){var c=e(a,h,b,f.grid),d={handler:b,dereg:c,eventId:h,scope:a};f.listeners.push(d),a.$on("$destroy",function(){d.dereg=null,d.handler=null,d.eventId=null,d.scope=null})}},f.prototype.registerEventsFromObject=function(a){var b=this,c=[];angular.forEach(a,function(a,b){var d={name:b,events:[]};angular.forEach(a,function(a,b){d.events.push(b)}),c.push(d)}),c.forEach(function(a){a.events.forEach(function(c){b.registerEvent(a.name,c)})})},f.prototype.registerMethod=function(a,b,c,e){this[a]||(this[a]={});var f=this[a];f[b]=d.createBoundedWrapper(e||this.grid,c)},f.prototype.registerMethodsFromObject=function(a,b){var c=this,d=[];angular.forEach(a,function(a,b){var c={name:b,methods:[]};angular.forEach(a,function(a,b){c.methods.push({name:b,fn:a})}),d.push(c)}),d.forEach(function(a){a.methods.forEach(function(d){c.registerMethod(a.name,d.name,d.fn,b)})})},f}])}(),function(){angular.module("ui.grid").factory("GridColumn",["gridUtil","uiGridConstants",function(a,b){function c(a,b,c){var d=this;d.grid=c,a.index=b,d.updateColumnDef(a)}return c.prototype.setPropertyOrDefault=function(a,b,c){var d=this;d[b]="undefined"!=typeof a[b]&&a[b]?a[b]:"undefined"!=typeof d[b]?d[b]:c?c:{}},c.prototype.updateColumnDef=function(b,d){var e=this;if(e.colDef=b,e.index="undefined"==typeof d?b.index:d,void 0===b.name)throw new Error("colDef.name is required for column at index "+e.index);var f="Cannot parse column width '"+b.width+"' for column named '"+b.name+"'";if(a.isNullOrUndefined(b.width))e.width="*";else if(angular.isNumber(b.width))e.width=b.width;else if(a.endsWith(b.width,"%")){var g=b.width.replace(/%/g,""),h=parseInt(g,10);if(isNaN(h))throw new Error(f);e.width=b.width}else if(b.width.match(/^(\d+)$/))e.width=parseInt(b.width.match(/^(\d+)$/)[1],10);else if(!b.width.match(/^\*+$/))throw new Error(f);c.prototype.unsort=function(){this.sort={}},e.minWidth=b.minWidth?b.minWidth:50,e.maxWidth=b.maxWidth?b.maxWidth:9e3,e.field=void 0===b.field?b.name:b.field,e.displayName=void 0===b.displayName?a.readableColumnName(b.name):b.displayName,e.aggregationType=angular.isDefined(b.aggregationType)?b.aggregationType:null,e.footerCellTemplate=angular.isDefined(b.footerCellTemplate)?b.footerCellTemplate:null,e.cellClass=b.cellClass,e.cellFilter=b.cellFilter?b.cellFilter:"",e.headerCellFilter=b.headerCellFilter?b.headerCellFilter:"",e.visible=a.isNullOrUndefined(b.visible)||b.visible,e.headerClass=b.headerClass,e.visible=!0,e.enableSorting="undefined"!=typeof b.enableSorting?b.enableSorting:!0,e.sortingAlgorithm=b.sortingAlgorithm,e.enableFiltering="undefined"!=typeof b.enableFiltering?b.enableFiltering:!0,e.setPropertyOrDefault(b,"menuItems",[]),e.setPropertyOrDefault(b,"sort");var i=[];b.filter?i.push(b.filter):e.enableFiltering&&e.grid.options.enableFiltering&&i.push({}),e.setPropertyOrDefault(b,"filter"),e.setPropertyOrDefault(b,"filters",i)},c.prototype.getColClass=function(a){var c=b.COL_CLASS_PREFIX+this.index;return a?"."+c:c},c.prototype.getColClassDefinition=function(){return" .grid"+this.grid.id+" "+this.getColClass(!0)+" { width: "+this.drawnWidth+"px; }"},c.prototype.getRenderContainer=function(){var a=this,b=a.renderContainer;return(null===b||""===b||void 0===b)&&(b="body"),a.grid.renderContainers[b]},c.prototype.showColumn=function(){this.colDef.visible=!0},c.prototype.hideColumn=function(){this.colDef.visible=!1},c.prototype.getAggregationValue=function(){var a=this,c=0,d=a.grid.getVisibleRows(),e=[];return angular.forEach(d,function(b){var c=a.grid.getCellValue(b,a);angular.isNumber(c)&&e.push(c)}),angular.isFunction(a.aggregationType)?a.aggregationType(d,a):a.aggregationType===b.aggregationTypes.count?"total rows: "+a.grid.getVisibleRowCount():a.aggregationType===b.aggregationTypes.sum?(angular.forEach(e,function(a){c+=a}),"total: "+c):a.aggregationType===b.aggregationTypes.avg?(angular.forEach(e,function(a){c+=a}),c/=e.length,"avg: "+c):a.aggregationType===b.aggregationTypes.min?"min: "+Math.min.apply(null,e):a.aggregationType===b.aggregationTypes.max?"max: "+Math.max.apply(null,e):null},c}])}(),function(){angular.module("ui.grid").factory("GridOptions",["gridUtil",function(a){function b(){this.onRegisterApi=angular.noop(),this.data=[],this.columnDefs=[],this.excludeProperties=["$$hashKey"],this.enableRowHashing=!0,this.rowIdentity=function(b){return a.hashKey(b)},this.getRowIdentity=function(a){return a.$$hashKey},this.headerRowHeight=30,this.rowHeight=30,this.maxVisibleRowCount=200,this.minRowsToShow=10,this.showFooter=!1,this.footerRowHeight=30,this.columnWidth=50,this.maxVisibleColumnCount=200,this.virtualizationThreshold=20,this.columnVirtualizationThreshold=10,this.excessRows=4,this.scrollThreshold=4,this.excessColumns=4,this.horizontalScrollThreshold=2,this.enableSorting=!0,this.enableFiltering=!1,this.enableColumnMenu=!0,this.enableScrollbars=!0,this.minimumColumnSize=10,this.rowEquality=function(a,b){return a===b},this.headerTemplate=null,this.footerTemplate=null,this.rowTemplate="ui-grid/ui-grid-row"}return b}])}(),function(){angular.module("ui.grid").factory("GridRenderContainer",["$log","gridUtil",function(a,b){function c(a,b,c){var d=this;d.name=a,d.grid=b,d.visibleRowCache=[],d.visibleColumnCache=[],d.renderedRows=[],d.renderedColumns=[],d.prevScrollTop=0,d.prevScrolltopPercentage=0,d.prevRowScrollIndex=0,d.prevScrollLeft=0,d.prevScrollleftPercentage=0,d.prevColumnScrollIndex=0,d.columnStyles="",d.viewportAdjusters=[],c&&angular.isObject(c)&&angular.extend(d,c),b.registerStyleComputation({priority:5,func:function(){return d.columnStyles}})}return c.prototype.reset=function(){this.visibleColumnCache.length=0,this.visibleRowCache.length=0,this.renderedRows.length=0,this.renderedColumns.length=0},c.prototype.minRowsToRender=function(){for(var a=this,b=0,c=0,d=a.getViewportHeight(),e=a.visibleRowCache.length-1;d>c&&e>=0;e--)c+=a.visibleRowCache[e].height,b++;return b},c.prototype.minColumnsToRender=function(){for(var a=this,b=this.getViewportWidth(),c=0,d=0,e=0;e<a.visibleColumnCache.length;e++){var f=a.visibleColumnCache[e];if(b>d)d+=f.drawnWidth,c++;else{for(var g=0,h=e;h>=e-c;h--)g+=a.visibleColumnCache[h].drawnWidth;b>g&&c++}}return c},c.prototype.getVisibleRowCount=function(){return this.visibleRowCache.length},c.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},c.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.viewportAdjusters.splice(b,1)},c.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},c.prototype.getViewportHeight=function(){var a=this,b=a.headerHeight?a.headerHeight:a.grid.headerHeight,c=a.grid.gridHeight-b-a.grid.footerHeight;"undefined"!=typeof a.horizontalScrollbarHeight&&void 0!==a.horizontalScrollbarHeight&&a.horizontalScrollbarHeight>0&&(c-=a.horizontalScrollbarHeight);var d=a.getViewportAdjustment();return c+=d.height},c.prototype.getViewportWidth=function(){var a=this,b=a.grid.gridWidth;"undefined"!=typeof a.grid.verticalScrollbarWidth&&void 0!==a.grid.verticalScrollbarWidth&&a.grid.verticalScrollbarWidth>0&&(b-=a.grid.verticalScrollbarWidth);var c=a.getViewportAdjustment();return b+=c.width},c.prototype.getHeaderViewportWidth=function(){var a=this,b=this.getViewportWidth();return"undefined"!=typeof a.grid.verticalScrollbarWidth&&void 0!==a.grid.verticalScrollbarWidth&&a.grid.verticalScrollbarWidth>0&&(b+=a.grid.verticalScrollbarWidth),b},c.prototype.getCanvasHeight=function(){var a=this,b=0;return a.visibleRowCache.forEach(function(a){b+=a.height}),"undefined"!=typeof a.grid.horizontalScrollbarHeight&&void 0!==a.grid.horizontalScrollbarHeight&&a.grid.horizontalScrollbarHeight>0&&(b-=a.grid.horizontalScrollbarHeight),b},c.prototype.getCanvasWidth=function(){var a=this,b=a.canvasWidth;return"undefined"!=typeof a.verticalScrollbarWidth&&void 0!==a.verticalScrollbarWidth&&a.verticalScrollbarWidth>0&&(b-=a.verticalScrollbarWidth),b},c.prototype.setRenderedRows=function(a){this.renderedRows.length=a.length;for(var b=0;b<a.length;b++)this.renderedRows[b]=a[b]},c.prototype.setRenderedColumns=function(a){this.renderedColumns.length=a.length;for(var b=0;b<a.length;b++)this.renderedColumns[b]=a[b];this.updateColumnOffset()},c.prototype.updateColumnOffset=function(){for(var a=0,b=0;b<this.currentFirstColumn;b++)a+=this.visibleColumnCache[b].drawnWidth;this.columnOffset=a},c.prototype.adjustScrollVertical=function(a,b,c){(this.prevScrollTop!==a||c)&&(a=this.getCanvasHeight()*b,this.adjustRows(a,b),this.prevScrollTop=a,this.prevScrolltopPercentage=b,this.grid.queueRefresh())},c.prototype.adjustScrollHorizontal=function(a,b,c){(this.prevScrollLeft!==a||c)&&(a=this.getCanvasWidth()*b,this.adjustColumns(a,b),this.prevScrollLeft=a,this.prevScrollleftPercentage=b,this.grid.queueRefresh())},c.prototype.adjustRows=function(a,b){var c=this,d=c.minRowsToRender(),e=c.visibleRowCache,f=e.length-d;c.maxRowIndex=f;c.prevRowScrollIndex;"undefined"!=typeof b&&null!==b||!a||(b=a/c.getCanvasHeight());var g=Math.ceil(Math.min(f,f*b));g>f&&(g=f);var h=[];if(e.length>c.grid.options.virtualizationThreshold){if(c.prevScrollTop<a&&g<c.prevRowScrollIndex+c.grid.options.scrollThreshold&&f>g)return;if(c.prevScrollTop>a&&g>c.prevRowScrollIndex-c.grid.options.scrollThreshold&&f>g)return;var i=Math.max(0,g-c.grid.options.excessRows),j=Math.min(e.length,g+d+c.grid.options.excessRows);h=[i,j]}else{var k=c.visibleRowCache.length;h=[0,Math.max(k,d+c.grid.options.excessRows)]}c.updateViewableRowRange(h),c.prevRowScrollIndex=g},c.prototype.adjustColumns=function(a,b){var c=this,d=c.minColumnsToRender(),e=c.visibleColumnCache,f=e.length-d;"undefined"!=typeof b&&null!==b||!a||(b=a/c.getCanvasWidth());var g=Math.ceil(Math.min(f,f*b));g>f&&(g=f);var h=[];if(e.length>c.grid.options.columnVirtualizationThreshold&&c.getCanvasWidth()>c.getViewportWidth()){if(c.prevScrollLeft<a&&g<c.prevColumnScrollIndex+c.grid.options.horizontalScrollThreshold&&f>g)return;if(c.prevScrollLeft>a&&g>c.prevColumnScrollIndex-c.grid.options.horizontalScrollThreshold&&f>g)return;var i=Math.max(0,g-c.grid.options.excessColumns),j=Math.min(e.length,g+d+c.grid.options.excessColumns);h=[i,j]}else{var k=c.visibleColumnCache.length;h=[0,Math.max(k,d+c.grid.options.excessColumns)]}c.updateViewableColumnRange(h),c.prevColumnScrollIndex=g},c.prototype.updateViewableRowRange=function(a){var b=this.visibleRowCache.slice(a[0],a[1]);this.currentTopRow=a[0],this.setRenderedRows(b)},c.prototype.updateViewableColumnRange=function(a){var b=this.visibleColumnCache.slice(a[0],a[1]);this.currentFirstColumn=a[0],this.setRenderedColumns(b)},c.prototype.rowStyle=function(a){var b=this,c={};if(0===a&&0!==b.currentTopRow){var d=b.currentTopRow*b.grid.options.rowHeight;c["margin-top"]=d+"px"}return 0!==b.currentFirstColumn&&(b.grid.isRTL()?c["margin-right"]=b.columnOffset+"px":c["margin-left"]=b.columnOffset+"px"),c},c.prototype.columnStyle=function(a){var b=this;if(0===a&&0!==b.currentFirstColumn){var c=b.columnOffset;return b.grid.isRTL()?{"margin-right":c+"px"}:{"margin-left":c+"px"}}return null},c.prototype.updateColumnWidths=function(){var a=this,c=[],d=[],e=0,f=a.getViewportWidth();"undefined"!=typeof a.grid.verticalScrollbarWidth&&void 0!==a.grid.verticalScrollbarWidth&&a.grid.verticalScrollbarWidth>0&&(f+=a.grid.verticalScrollbarWidth);var g,h=0,i=0,j="",k=a.visibleColumnCache;k.forEach(function(a){if(a.visible){var f=!1;angular.isNumber(a.width)||(f=isNaN(a.width)?b.endsWith(a.width,"%"):!1),angular.isString(a.width)&&-1!==a.width.indexOf("*")?(e=parseInt(e+a.width.length,10),c.push(a)):f?d.push(a):angular.isNumber(a.width)&&(h=parseInt(h+a.width,10),i=parseInt(i,10)+parseInt(a.width,10),a.drawnWidth=a.width)}});var l,m,n,o=f-h;if(d.length>0){for(l=0;l<d.length;l++){m=d[l];var p=parseInt(m.width.replace(/%/g,""),10)/100;n=parseInt(p*o,10),m.colDef.minWidth&&n<m.colDef.minWidth?(n=m.colDef.minWidth,o-=n,i+=n,m.drawnWidth=n,d.splice(l,1)):m.colDef.maxWidth&&n>m.colDef.maxWidth&&(n=m.colDef.maxWidth,o-=n,i+=n,m.drawnWidth=n,d.splice(l,1))}d.forEach(function(a){var b=parseInt(a.width.replace(/%/g,""),10)/100,c=parseInt(b*o,10);i+=c,a.drawnWidth=c})}if(c.length>0){var q=parseInt(o/e,10);for(l=0;l<c.length;l++)m=c[l],n=parseInt(q*m.width.length,10),m.colDef.minWidth&&n<m.colDef.minWidth?(n=m.colDef.minWidth,o-=n,e--,i+=n,m.drawnWidth=n,g=m,c.splice(l,1)):m.colDef.maxWidth&&n>m.colDef.maxWidth&&(n=m.colDef.maxWidth,o-=n,e--,i+=n,m.drawnWidth=n,c.splice(l,1));q=parseInt(o/e,10),c.forEach(function(a){var b=parseInt(q*a.width.length,10);i+=b,a.drawnWidth=b})}var r=f-parseInt(i,10);if(r>0&&i>0&&f>i){var s=!1;if(k.forEach(function(a){a.width&&!angular.isNumber(a.width)&&(s=!0)}),s)for(var t=function(a){r>0&&(a.drawnWidth=a.drawnWidth+1,i+=1,r--)};r>0;)k.forEach(t)}f>i&&(i=f),k.forEach(function(a){j+=a.getColClassDefinition()}),a.grid.verticalScrollbarWidth&&(i+=a.grid.verticalScrollbarWidth),a.canvasWidth=parseInt(i,10),this.columnStyles=j},c}])}(),function(){angular.module("ui.grid").factory("GridRow",["gridUtil",function(a){function b(b,c,d){this.grid=d,this.entity=b,this.index=c,this.uid=a.nextUid(),this.visible=!0,this.height=d.options.rowHeight,this.grid.api.core.setRowInvisible||this.grid.api.registerMethod("core","setRowInvisible",this.setRowInvisible),this.grid.api.core.clearRowInvisible||this.grid.api.registerMethod("core","clearRowInvisible",this.clearRowInvisible),this.grid.api.core.getVisibleRows||this.grid.api.registerMethod("core","getVisibleRows",this.getVisibleRows),this.grid.api.core.raise.rowsVisibleChanged||this.grid.api.registerEvent("core","rowsVisibleChanged")}return b.prototype.getQualifiedColField=function(a){return"row."+this.getEntityQualifiedColField(a)},b.prototype.getEntityQualifiedColField=function(b){return a.preEval("entity."+b.field)},b.prototype.setRowInvisible=function(a){null!==a&&(a.forceInvisible=!0,a.visible&&(a.visible=!1,a.grid.refresh(),a.grid.api.core.raise.rowsVisibleChanged()))},b.prototype.clearRowInvisible=function(a){null!==a&&(a.forceInvisible=!1,a.visible||(a.visible=!0,a.grid.refresh(),a.grid.api.core.raise.rowsVisibleChanged()))},b.prototype.getVisibleRows=function(a){return a.rows.filter(function(a){return a.visible})},b}])}(),function(){"use strict";angular.module("ui.grid").service("gridClassFactory",["gridUtil","$q","$compile","$templateCache","uiGridConstants","$log","Grid","GridColumn","GridRow",function(a,b,c,d,e,f,g){var h={createGrid:function(d){d="undefined"!=typeof d?d:{},d.id=a.newId();var e=new g(d);if(e.options.rowTemplate){var f=b.defer();e.getRowTemplateFn=f.promise,a.getTemplate(e.options.rowTemplate).then(function(a){var b=c(a);f.resolve(b)},function(){throw new Error("Couldn't fetch/use row template '"+e.options.rowTemplate+"'")})}return e.registerColumnBuilder(h.defaultColumnBuilder),e.registerRowsProcessor(function(a){return a.forEach(function(a){a.visible=!a.forceInvisible}),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.visible=!0}),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.colDef.visible===!1&&(a.visible=!1)}),a}),e.options.enableFiltering&&e.registerRowsProcessor(e.searchRows),e.registerRowsProcessor(e.options.externalSort&&angular.isFunction(e.options.externalSort)?e.options.externalSort:e.sortByColumn),e},defaultColumnBuilder:function(c,d){var f=[];return c.headerCellTemplate||(c.headerCellTemplate="ui-grid/uiGridHeaderCell"),c.cellTemplate||(c.cellTemplate="ui-grid/uiGridCell"),f.push(a.getTemplate(c.cellTemplate).then(function(a){d.cellTemplate=a.replace(e.CUSTOM_FILTERS,d.cellFilter?"|"+d.cellFilter:"")},function(){throw new Error("Couldn't fetch/use colDef.cellTemplate '"+c.cellTemplate+"'")})),f.push(a.getTemplate(c.headerCellTemplate).then(function(a){d.headerCellTemplate=a.replace(e.CUSTOM_FILTERS,d.headerCellFilter?"|"+d.headerCellFilter:"")},function(){throw new Error("Couldn't fetch/use colDef.headerCellTemplate '"+c.headerCellTemplate+"'")})),b.all(f)}};return h}])}(),function(){function a(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function b(){var a=function(b,c){return b&&a.cache[b]?a.cache[b]:b&&c?(a.cache[b]=c,a.cache[b]):void 0};return a.cache={},a.clear=function(){a.cache={}},a}var c=angular.module("ui.grid");c.service("rowSearcher",["$log","uiGridConstants",function(c,d){var e=d.filter.STARTS_WITH,f={};return f.getTerm=function(a){if("undefined"==typeof a.term)return a.term;var b=a.term;return"string"==typeof b&&(b=b.trim()),b},f.stripTerm=function(b){var c=f.getTerm(b);return"string"==typeof c?a(c.replace(/(^\*|\*$)/g,"")):c},f.guessCondition=function(a){if("undefined"==typeof a.term||!a.term)return e;var b=f.getTerm(a);if(/\*/.test(b)){var c="";a.flags&&a.flags.caseSensitive||(c+="i");var d=b.replace(/(\\)?\*/g,function(a,b){return b?a:"[\\s\\S]*?"});return new RegExp("^"+d+"$",c)}return e},f.runColumnFilter=function(a,b,c,e,g,h){var i=typeof h.condition;"undefined"!==i&&h.condition||(h.condition=d.filter.CONTAINS);var j=f.stripTerm(h);if(null===j||void 0===j||""===j)return!0;var k=a.getCellValue(b,c),l="";h.flags&&h.flags.caseSensitive||(l+="i");var m=c.field+g;if(h.condition instanceof RegExp){if(!h.condition.test(k))return!1}else{if("function"===i)return h.condition(j,k,b,c);if(h.condition===d.filter.STARTS_WITH){var n=e(m)?e(m):e(m,new RegExp("^"+j,l));if(!n.test(k))return!1}else if(h.condition===d.filter.ENDS_WITH){var o=e(m)?e(m):e(m,new RegExp(j+"$",l));if(!o.test(k))return!1}else if(h.condition===d.filter.CONTAINS){var p=e(m)?e(m):e(m,new RegExp(j,l));if(!p.test(k))return!1}else if(h.condition===d.filter.EXACT){var q=e(m)?e(m):e(m,new RegExp("^"+j+"$",l));if(!q.test(k))return!1}else if(h.condition===d.filter.GREATER_THAN){if(j>=k)return!1}else if(h.condition===d.filter.GREATER_THAN_OR_EQUAL){if(j>k)return!1}else if(h.condition===d.filter.LESS_THAN){if(k>=j)return!1}else if(h.condition===d.filter.LESS_THAN_OR_EQUAL){if(k>j)return!1}else if(h.condition===d.filter.NOT_EQUAL&&!angular.equals(k,j))return!1}return!0},f.searchColumn=function(a,b,c,d){var e=[];if(a.options.useExternalFiltering)return!0;if(!("undefined"!=typeof c.filters&&c.filters&&c.filters.length>0))return!0;e=c.filters;for(var g in e){var h=e[g];if(!h.condition){var i="cond-"+c.field+"-"+h.term,j=d(i)?d(i):d(i,f.guessCondition(h));h={term:h.term,condition:j,flags:angular.extend({caseSensitive:!1},h.flags)}}var k=f.runColumnFilter(a,b,c,d,g,h);if(!k)return!1}return!0},f.search=function(a,c,d){if(c){var e=new b,g=[];return d.forEach(function(a){"undefined"!=typeof a.filters&&a.filters.length>0?g.push(a):"undefined"!=typeof a.filter&&a.filter&&"undefined"!=typeof a.filter.term&&a.filter.term&&g.push(a)}),g.length>0&&(g.forEach(function(b){c.forEach(function(c){(c.forceInvisible||!f.searchColumn(a,c,b,e))&&(c.visible=!1)})}),a.api.core.raise.rowsVisibleChanged()),e.clear(),c
+}},f}])}(),function(){var a=angular.module("ui.grid");a.service("rowSorter",["$parse","uiGridConstants",function(a,b){var c="("+b.CURRENCY_SYMBOLS.map(function(a){return"\\"+a}).join("|")+")?",d=(new RegExp("^[-+]?"+c+"[\\d,.]+"+c+"%?$"),{colSortFnCache:[]});return d.guessSortFn=function(a){switch(a){case"number":return d.sortNumber;case"boolean":return d.sortBool;case"string":return d.sortAlpha;case"date":return d.sortDate;case"object":return d.basicSort;default:throw new Error("No sorting function found for type:"+a)}},d.basicSort=function(a,b){return a===b?0:b>a?-1:1},d.sortNumber=function(a,b){return a-b},d.sortNumberStr=function(a,b){var c,d,e=!1,f=!1;return c=parseFloat(a.replace(/[^0-9.-]/g,"")),isNaN(c)&&(e=!0),d=parseFloat(b.replace(/[^0-9.-]/g,"")),isNaN(d)&&(f=!0),e&&f?0:e?1:f?-1:c-d},d.sortAlpha=function(a,b){var c=a.toLowerCase(),d=b.toLowerCase();return c===d?0:d>c?-1:1},d.sortDate=function(a,b){var c=a.getTime(),d=b.getTime();return c===d?0:d>c?-1:1},d.sortBool=function(a,b){return a&&b?0:a||b?a?1:-1:0},d.getSortFn=function(a,b){var c;return d.colSortFnCache[b.colDef.name]?c=d.colSortFnCache[b.colDef.name]:void 0!==b.sortingAlgorithm?(c=b.sortingAlgorithm,d.colSortFnCache[b.colDef.name]=b.sortingAlgorithm):(c=d.guessSortFn(b.colDef.type),c?d.colSortFnCache[b.colDef.name]=c:c=d.sortAlpha),c},d.prioritySort=function(a,b){return void 0!==a.sort.priority&&void 0!==b.sort.priority?a.sort.priority<b.sort.priority?-1:a.sort.priority===b.sort.priority?0:1:a.sort.priority?-1:b.sort.priority?1:0},d.sort=function(a,c,e){if(c){if(a.options.useExternalSorting)return c;var f=[];if(e.forEach(function(a){a.sort&&a.sort.direction&&(a.sort.direction===b.ASC||a.sort.direction===b.DESC)&&f.push(a)}),f=f.sort(d.prioritySort),0===f.length)return c;var g,h,i=c.slice(0);return c.sort(function(c,e){for(var j,k=0,l=0;0===k&&l<f.length;){g=f[l],h=f[l].sort.direction,j=d.getSortFn(a,g,i);var m=a.getCellValue(c,g),n=a.getCellValue(e,g);!m&&0!==m||!n&&0!==n?n||m?m?n||(k=-1):k=1:k=0:k=j(m,n),l++}return h===b.ASC?k:0-k})}},d}])}(),function(){function a(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)}function b(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0,h=["Top","Right","Bottom","Left"];4>f;f+=2){var i=h[f];if("margin"===c){var j=parseFloat(e[c+i]);isNaN(j)||(g+=j)}if(d){if("content"===c){var k=parseFloat(e["padding"+i]);isNaN(k)||(g-=k)}if("margin"!==c){var l=parseFloat(e["border"+i+"Width"]);isNaN(l)||(g-=l)}}else{var m=parseFloat(e["padding"+i]);if(isNaN(m)||(g+=m),"padding"!==c){var n=parseFloat(e["border"+i+"Width"]);isNaN(n)||(g+=n)}}}return g}function c(c,d,f){var g=!0,h="width"===d?c.offsetWidth:c.offsetHeight,i=a(c),j="border-box"===i.boxSizing;if(0>=h||null==h){if(h=i[d],(0>h||null==h)&&(h=c.style[d]),e.test(h))return h;g=j&&!0,h=parseFloat(h)||0}var k=h+b(c,d,f||(j?"border":"content"),g,i);return k}var d=angular.module("ui.grid"),e=new RegExp("^("+/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source+")(?!px)[a-z%]+$","i"),f=/^(block|none|table(?!-c[ea]).+)/,g={position:"absolute",visibility:"hidden",display:"block"},h=["0","0","0"],i="uiGrid-";d.service("gridUtil",["$log","$window","$document","$http","$templateCache","$timeout","$injector","$q","uiGridConstants",function(b,d,e,j,k,l,m,n,o){var p={createBoundedWrapper:function(a,b){return function(){return b.apply(a,arguments)}},readableColumnName:function(a){return"undefined"==typeof a||void 0===a||null===a?a:("string"!=typeof a&&(a=String(a)),a.replace(/_+/g," ").replace(/^[A-Z]+$/,function(a){return angular.lowercase(angular.uppercase(a.charAt(0))+a.slice(1))}).replace(/(\w+)/g,function(a){return angular.uppercase(a.charAt(0))+a.slice(1)}).replace(/(\w+?(?=[A-Z]))/g,"$1 "))},getColumnsFromData:function(a,b){var c=[];if(!a||"undefined"==typeof a[0]||void 0===a[0])return[];angular.isUndefined(b)&&(b=[]);var d=a[0];return angular.forEach(d,function(a,d){-1===b.indexOf(d)&&c.push({name:d})}),c},newId:function(){var a=(new Date).getTime();return function(){return a+=1}}(),getTemplate:function(a){if(k.get(a))return n.when(k.get(a));if(a.hasOwnProperty("then"))return a;try{if(angular.element(a).length>0)return n.when(a)}catch(c){}return b.debug("Fetching url",a),j({method:"GET",url:a}).then(function(b){var c=b.data.trim();return k.put(a,c),c},function(b){throw new Error("Could not get template "+a+": "+b)})},guessType:function(a){var b=typeof a;switch(b){case"number":case"boolean":case"string":return b;default:return angular.isDate(a)?"date":"object"}},elementWidth:function(){},elementHeight:function(){},getScrollbarWidth:function(){var a=document.createElement("div");a.style.visibility="hidden",a.style.width="100px",a.style.msOverflowStyle="scrollbar",document.body.appendChild(a);var b=a.offsetWidth;a.style.overflow="scroll";var c=document.createElement("div");c.style.width="100%",a.appendChild(c);var d=c.offsetWidth;return a.parentNode.removeChild(a),b-d},swap:function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},fakeElement:function(a,b,c){var d,e,f=angular.element(a).clone()[0];for(e in b)f.style[e]=b[e];return angular.element(document.body).append(f),d=c.call(f,f),angular.element(f).remove(),d},normalizeWheelEvent:function(a){var b,c,d,e=a||window.event,f=([].slice.call(arguments,1),0),g=0,h=0,i=0,j=0;return e.originalEvent&&(e=e.originalEvent),e.wheelDelta&&(f=e.wheelDelta),e.detail&&(f=-1*e.detail),h=f,void 0!==e.axis&&e.axis===e.HORIZONTAL_AXIS&&(h=0,g=-1*f),e.deltaY&&(h=-1*e.deltaY,f=h),e.deltaX&&(g=e.deltaX,f=-1*g),void 0!==e.wheelDeltaY&&(h=e.wheelDeltaY),void 0!==e.wheelDeltaX&&(g=e.wheelDeltaX),i=Math.abs(f),(!b||b>i)&&(b=i),j=Math.max(Math.abs(h),Math.abs(g)),(!c||c>j)&&(c=j),d=f>0?"floor":"ceil",f=Math[d](f/b),g=Math[d](g/c),h=Math[d](h/c),{delta:f,deltaX:g,deltaY:h}},isTouchEnabled:function(){var a;return("ontouchstart"in d||d.DocumentTouch&&e instanceof DocumentTouch)&&(a=!0),a},isNullOrUndefined:function(a){return void 0===a||null===a?!0:!1},endsWith:function(a,b){return a&&b&&"string"==typeof a?-1!==a.indexOf(b,a.length-b.length):!1},requestAnimationFrame:d.requestAnimationFrame&&d.requestAnimationFrame.bind(d)||d.webkitRequestAnimationFrame&&d.webkitRequestAnimationFrame.bind(d)||function(a){return l(a,10,!1)},numericAndNullSort:function(a,b){return null===a?1:null===b?-1:null===a&&null===b?0:a-b},disableAnimations:function(a){var b;try{b=m.get("$animate"),b.enabled(!1,a)}catch(c){}},enableAnimations:function(a){var b;try{b=m.get("$animate"),b.enabled(!0,a)}catch(c){}},nextUid:function(){for(var a,b=h.length;b;){if(b--,a=h[b].charCodeAt(0),57===a)return h[b]="A",i+h.join("");if(90!==a)return h[b]=String.fromCharCode(a+1),i+h.join("");h[b]="0"}return h.unshift("0"),i+h.join("")},hashKey:function(a){var b,c=typeof a;return"object"===c&&null!==a?"function"==typeof(b=a.$$hashKey)?b=a.$$hashKey():"undefined"!=typeof a.$$hashKey&&a.$$hashKey?b=a.$$hashKey:void 0===b&&(b=a.$$hashKey=p.nextUid()):b=a,c+":"+b}};return["width","height"].forEach(function(b){var d=angular.uppercase(b.charAt(0))+b.substr(1);p["element"+d]=function(d,e){var h=d;if("undefined"!=typeof h.length&&h.length&&(h=d[0]),h){var i=a(h);return 0===h.offsetWidth&&f.test(i.display)?p.fakeElement(h,g,function(a){return c(a,b,e)}):c(h,b,e)}return null},p["outerElement"+d]=function(a,b){return a?p["element"+d].call(this,a,b?"margin":"border"):null}}),p.closestElm=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c;["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"].some(function(a){return"function"==typeof document.body[a]?(c=a,!0):!1});for(var d;null!==a;){if(d=a.parentElement,null!==d&&d[c](b))return d;a=d}return null},p.type=function(a){var b=Function.prototype.toString.call(a.constructor);return b.match(/function (.*?)\(/)[1]},p.getBorderSize=function(b,c){"undefined"!=typeof b.length&&b.length&&(b=b[0]);var d=a(b);c=c?"border-"+c:"border";var e=parseInt(d[c],10);return isNaN(e)?0:e},p.detectBrowser=function(){var a=d.navigator.userAgent,b={chrome:/chrome/i,safari:/safari/i,firefox:/firefox/i,ie:/internet explorer|trident\//i};for(var c in b)if(b[c].test(a))return c;return"unknown"},p.normalizeScrollLeft=function(a){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var b=p.detectBrowser(),c=a.scrollLeft,d=angular.element(a).css("direction");if("ie"===b)return c;if("chrome"===b){if("rtl"===d){var e=a.scrollWidth-a.clientWidth;return e-c}return c}return"firefox"===b?Math.abs(c):c},p.denormalizeScrollLeft=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c=p.detectBrowser(),d=angular.element(a).css("direction");if("ie"===c)return b;if("chrome"===c){if("rtl"===d){var e=a.scrollWidth-a.clientWidth;return e-b}return b}return"firefox"===c&&"rtl"===d?-1*b:b},p.preEval=function(a){var b=o.BRACKET_REGEXP.exec(a);if(b)return(b[1]?p.preEval(b[1]):b[1])+b[2]+(b[3]?p.preEval(b[3]):b[3]);a=a.replace(o.APOS_REGEXP,"\\'");var c=a.split(o.DOT_REGEXP),d=[c.shift()];return angular.forEach(c,function(a){d.push(a.replace(o.FUNC_REGEXP,"']$1"))}),d.join("['")},p.debounce=function(a,b,c){function d(){g=this,f=arguments;var d=function(){e=null,c||(h=a.apply(g,f))},i=c&&!e;return e&&l.cancel(e),e=l(d,b),i&&(h=a.apply(g,f)),h}var e,f,g,h;return d.cancel=function(){l.cancel(e),e=null},d},p}]),d.filter("px",function(){return function(a){return a.match(/^[\d\.]+$/)?a+"px":a}})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("da",{aggregate:{label:"artikler"},groupPanel:{description:"Grupér rækker udfra en kolonne ved at trække dens overskift hertil."},search:{placeholder:"Søg...",showingItems:"Viste rækker:",selectedItems:"Valgte rækker:",totalItems:"Rækker totalt:",size:"Side størrelse:",first:"Første side",next:"Næste side",previous:"Forrige side",last:"Sidste side"},menu:{text:"Vælg kolonner:"},column:{hide:"Skjul kolonne"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("de",{aggregate:{label:"eintrag"},groupPanel:{description:"Ziehen Sie eine Spaltenüberschrift hierhin um nach dieser Spalte zu gruppieren."},search:{placeholder:"Suche...",showingItems:"Zeige Einträge:",selectedItems:"Ausgewählte Einträge:",totalItems:"Einträge gesamt:",size:"Einträge pro Seite:",first:"Erste Seite",next:"Nächste Seite",previous:"Vorherige Seite",last:"Letzte Seite"},menu:{text:"Spalten auswählen:"},column:{hide:"Spalte ausblenden"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("en",{aggregate:{label:"items"},groupPanel:{description:"Drag a column header here and drop it to group by that column."},search:{placeholder:"Search...",showingItems:"Showing Items:",selectedItems:"Selected Items:",totalItems:"Total Items:",size:"Page Size:",first:"First Page",next:"Next Page",previous:"Previous Page",last:"Last Page"},menu:{text:"Choose Columns:"},sort:{ascending:"Sort Ascending",descending:"Sort Descending",remove:"Remove Sort"},column:{hide:"Hide Column"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("es",{aggregate:{label:"Artículos"},groupPanel:{description:"Arrastre un encabezado de columna aquí y soltarlo para agrupar por esa columna."},search:{placeholder:"Buscar...",showingItems:"Artículos Mostrando:",selectedItems:"Artículos Seleccionados:",totalItems:"Artículos Totales:",size:"Tamaño de Página:",first:"Primera Página",next:"Página Siguiente",previous:"Página Anterior",last:"Última Página"},menu:{text:"Elegir columnas:"},column:{hide:"Ocultar la columna"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fa",{aggregate:{label:"موردها"},groupPanel:{description:"یک عنوان ستون اینجا را بردار و به گروهی از آن ستون بیانداز."},search:{placeholder:"جستجو...",showingItems:"نمایش موردها:",selectedItems:"موردهای انتخاب‌شده:",totalItems:"همهٔ موردها:",size:"اندازهٔ صفحه:",first:"صفحهٔ اول",next:"صفحهٔ بعد",previous:"صفحهٔ قبل",last:"آخرین صفحه"},menu:{text:"انتخاب ستون‌ها:"},column:{hide:"ستون پنهان کن"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fr",{aggregate:{label:"articles"},groupPanel:{description:"Faites glisser un en-tête de colonne ici et déposez-le vers un groupe par cette colonne."},search:{placeholder:"Recherche...",showingItems:"Articles Affichage des:",selectedItems:"Éléments Articles:",totalItems:"Nombre total d'articles:",size:"Taille de page:",first:"Première page",next:"Page Suivante",previous:"Page précédente",last:"Dernière page"},menu:{text:"Choisir des colonnes:"},column:{hide:"Colonne de peau"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("he",{aggregate:{label:"items"},groupPanel:{description:"גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו."},search:{placeholder:"חפש...",showingItems:"מציג:",selectedItems:'סה"כ נבחרו:',totalItems:'סה"כ רשומות:',size:"תוצאות בדף:",first:"דף ראשון",next:"דף הבא",previous:"דף קודם",last:"דף אחרון"},menu:{text:"בחר עמודות:"},sort:{ascending:"סדר עולה",descending:"סדר יורד",remove:"בטל"},column:{hide:"טור הסתר"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("nl",{aggregate:{label:"items"},groupPanel:{description:"Sleep hier een kolomnaam heen om op te groeperen."},search:{placeholder:"Zoeken...",showingItems:"Getoonde items:",selectedItems:"Geselecteerde items:",totalItems:"Totaal aantal items:",size:"Items per pagina:",first:"Eerste pagina",next:"Volgende pagina",previous:"Vorige pagina",last:"Laatste pagina"},menu:{text:"Kies kolommen:"},sort:{ascending:"Sorteer oplopend",descending:"Sorteer aflopend",remove:"Verwijder sortering"},column:{hide:"Kolom te verbergen"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt-br",{aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Items Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},column:{hide:"Esconder coluna"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ru",{aggregate:{label:"элементы"},groupPanel:{description:"Для группировки по столбцу перетащите сюда его название."},search:{placeholder:"Поиск...",showingItems:"Показать элементы:",selectedItems:"Выбранные элементы:",totalItems:"Всего элементов:",size:"Размер страницы:",first:"Первая страница",next:"Следующая страница",previous:"Предыдущая страница",last:"Последняя страница"},menu:{text:"Выбрать столбцы:"},sort:{ascending:"По возрастанию",descending:"По убыванию",remove:"Убрать сортировку"},column:{hide:"спрятать столбец"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sk",{aggregate:{label:"items"},groupPanel:{description:"Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca."},search:{placeholder:"Hľadaj...",showingItems:"Zobrazujem položky:",selectedItems:"Vybraté položky:",totalItems:"Počet položiek:",size:"Počet:",first:"Prvá strana",next:"Ďalšia strana",previous:"Predchádzajúca strana",last:"Posledná strana"},menu:{text:"Vyberte stĺpce:"},sort:{ascending:"Zotriediť vzostupne",descending:"Zotriediť zostupne",remove:"Vymazať triedenie"}}),a}])}])}(),function(){var a=["uiT","uiTranslate"],b=["t","uiTranslate"],c=angular.module("ui.grid.i18n");c.constant("i18nConstants",{MISSING:"[MISSING]",UPDATE_EVENT:"$uiI18n",LOCALE_DIRECTIVE_ALIAS:"uiI18n",DEFAULT_LANG:"en"}),c.service("i18nService",["$log","i18nConstants","$rootScope",function(a,b,c){var d={_langs:{},current:null,get:function(a){return this._langs[a.toLowerCase()]},add:function(a,b){var c=a.toLowerCase();this._langs[c]||(this._langs[c]={}),angular.extend(this._langs[c],b)},getAllLangs:function(){var a=[];if(!this._langs)return a;for(var b in this._langs)a.push(b);return a},setCurrent:function(a){this.current=a.toLowerCase()},getCurrentLang:function(){return this.current}},e={add:function(a,b){"object"==typeof a?angular.forEach(a,function(a){a&&d.add(a,b)}):d.add(a,b)},getAllLangs:function(){return d.getAllLangs()},get:function(a){var b=a?a:e.getCurrentLang();return d.get(b)},getSafeText:function(a,c){var f=c?c:e.getCurrentLang(),g=d.get(f);if(!g)return b.MISSING;for(var h=a.split("."),i=g,j=0;j<h.length;++j){if(void 0===i[h[j]]||null===i[h[j]])return b.MISSING;i=i[h[j]]}return i},setCurrentLang:function(a){a&&(d.setCurrent(a),c.$broadcast(b.UPDATE_EVENT))},getCurrentLang:function(){var a=d.getCurrentLang();return a||(a=b.DEFAULT_LANG,d.setCurrent(a)),a}};return e}]);var d=function(a,b){return{compile:function(){return{pre:function(c,d,e){var f=b.LOCALE_DIRECTIVE_ALIAS,g=c.$eval(e[f]);g?c.$watch(e[f],function(){a.setCurrentLang(g)}):e.$$observers&&e.$observe(f,function(){a.setCurrentLang(e[f]||b.DEFAULT_LANG)})}}}}};c.directive("uiI18n",["i18nService","i18nConstants",d]);var e=function(b,c,d){return{restrict:"EA",compile:function(){return{pre:function(e,f,g){var h,i=a[0],j=a[1],k=g[i]||g[j]||f.html(),l=d.MISSING+k;if(g.$$observers){var m=g[i]?i:j;h=g.$observe(m,function(a){a&&f.html(b(a)(c.getCurrentLang())||l)})}var n=b(k),o=e.$on(d.UPDATE_EVENT,function(){h?h(g[i]||g[j]):f.html(n(c.get())||l)});e.$on("$destroy",o),f.html(n(c.get())||l)}}}}};a.forEach(function(a){c.directive(a,["$parse","i18nService","i18nConstants",e])});var f=function(a,b,c){return function(d){var e=a(d);return e(b.get())||c.MISSING+d}};b.forEach(function(a){c.filter(a,["$parse","i18nService","i18nConstants",f])})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("zh-cn",{aggregate:{label:"条目"},groupPanel:{description:"拖曳表头到此处以进行分组"},search:{placeholder:"搜索...",showingItems:"当前显示条目:",selectedItems:"选中条目:",totalItems:"条目总数:",size:"每页显示数:",first:"回到首页",next:"下一页",previous:"上一页",last:"前往尾页"},menu:{text:"数据分组与选择列:"},column:{hide:"隐藏列"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("zh-tw",{aggregate:{label:"筆"},groupPanel:{description:"拖拉表頭到此處以進行分組"},search:{placeholder:"搜尋...",showingItems:"目前顯示筆數:",selectedItems:"選取筆數:",totalItems:"總筆數:",size:"每頁顯示:",first:"第一頁",next:"下一頁",previous:"上一頁",last:"最後頁"},menu:{text:"選擇欄位:"},column:{hide:"隐藏列"}}),a}])}])}(),function(){"use strict";var a=angular.module("ui.grid.autoResize",["ui.grid"]);a.directive("uiGridAutoResize",["$log","$timeout","gridUtil",function(a,b,c){return{require:"uiGrid",scope:!1,link:function(a,d,e,f){function g(){j=c.elementHeight(d),i=c.elementWidth(d)}function h(){b.cancel(k),k=b(function(){var a=c.elementHeight(d),b=c.elementWidth(d);a!==j||b!==i?(f.grid.gridHeight=a,f.grid.gridWidth=b,f.grid.queueRefresh().then(function(){g(),h()})):h()},250)}var i,j;g();var k;h(),a.$on("$destroy",function(){b.cancel(k)})}}}])}(),function(){"use strict";function a(a,b){this.row=a,this.col=b}var b=angular.module("ui.grid.cellNav",["ui.grid"]);b.constant("uiGridCellNavConstants",{FEATURE_NAME:"gridCellNav",CELL_NAV_EVENT:"cellNav",direction:{LEFT:0,RIGHT:1,UP:2,DOWN:3}}),b.service("uiGridCellNavService",["$log","uiGridConstants","uiGridCellNavConstants","$q",function(b,c,d,e){var f={initializeGrid:function(a){a.registerColumnBuilder(f.cellNavColumnBuilder),a.cellNav={},a.cellNav.lastRowCol=null;var b={events:{cellNav:{navigate:function(){}}},methods:{cellNav:{scrollTo:function(a,b,c,d){f.scrollTo(a,b,c,d)},getFocusedCell:function(){return a.cellNav.lastRowCol}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},getDirection:function(a){return a.keyCode===c.keymap.LEFT||a.keyCode===c.keymap.TAB&&a.shiftKey?d.direction.LEFT:a.keyCode===c.keymap.RIGHT||a.keyCode===c.keymap.TAB?d.direction.RIGHT:a.keyCode===c.keymap.UP||a.keyCode===c.keymap.ENTER&&a.shiftKey?d.direction.UP:a.keyCode===c.keymap.DOWN||a.keyCode===c.keymap.ENTER?d.direction.DOWN:null},getNextRowCol:function(a,b,c,e){switch(a){case d.direction.LEFT:return f.getRowColLeft(b.rows,b.columns,c,e);case d.direction.RIGHT:return f.getRowColRight(b.rows,b.columns,c,e);case d.direction.UP:return f.getRowColUp(b.rows,b.columns,c,e);case d.direction.DOWN:return f.getRowColDown(b.rows,b.columns,c,e)}},getRowColLeft:function(b,c,d,e){var g=f.getNextColIndexLeft(c,e);return g>e.index?0===d.index?new a(d,c[g]):new a(b[d.index-1],c[g]):new a(d,c[g])},getRowColRight:function(b,c,d,e){var g=f.getNextColIndexRight(c,e);return g<e.index?d.index===b.length-1?new a(d,c[g]):new a(b[d.index+1],c[g]):new a(d,c[g])},getNextColIndexLeft:function(a,b){for(var c=0===b.index?a.length-1:b.index-1;c!==b.index&&!a[c].colDef.allowCellFocus;)c--,-1===c&&(c=a.length-1);return c},getNextColIndexRight:function(a,b){for(var c=b.index===a.length-1?0:b.index+1;c!==b.index&&!a[c].colDef.allowCellFocus;)c++,c>a.length-1&&(c=0);return c},getRowColUp:function(b,c,d,e){var g=e.colDef.allowCellFocus?e.index:f.getNextColIndexRight(c,e);return 0===d.index?new a(d,c[g]):new a(b[d.index-1],c[g])},getRowColDown:function(b,c,d,e){var g=e.colDef.allowCellFocus?e.index:f.getNextColIndexRight(c,e);return d.index===b.length-1?new a(d,c[g]):new a(b[d.index+1],c[g])},cellNavColumnBuilder:function(a){var b=[];return a.allowCellFocus=void 0===a.allowCellFocus?!0:a.allowCellFocus,e.all(b)},scrollTo:function(a,b,d,e){var f={};if(null!==d){var g=a.getRow(d);g&&(f.y={percentage:g.index/a.renderContainers.body.visibleRowCache.length})}if(null!==e){var h=a.getColumn(e.name?e.name:e.field);h&&(f.x={percentage:this.getLeftWidth(a,h.index)/this.getLeftWidth(a,a.renderContainers.body.visibleColumnCache.length-1)})}(f.y||f.x)&&b.$broadcast(c.events.GRID_SCROLL,f)},getLeftWidth:function(a,b){var c=0;if(b){for(var d=0;b>=d;d++)a.renderContainers.body.visibleColumnCache[d].drawnWidth&&(c+=a.renderContainers.body.visibleColumnCache[d].drawnWidth);return c}}};return f}]),b.directive("uiGridCellnav",["$log","uiGridCellNavService","uiGridCellNavConstants",function(b,c,d){return{replace:!0,priority:-150,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(b,e,f,g){var h=g.grid;c.initializeGrid(h),g.cellNav={},g.cellNav.broadcastCellNav=function(a){b.$broadcast(d.CELL_NAV_EVENT,a),g.cellNav.broadcastFocus(a.row,a.col)},g.cellNav.broadcastFocus=function(b,c){if(null===h.cellNav.lastRowCol||h.cellNav.lastRowCol.row!==b||h.cellNav.lastRowCol.col!==c){var d=new a(b,c);h.api.cellNav.raise.navigate(d,h.cellNav.lastRowCol),h.cellNav.lastRowCol=d}}},post:function(){}}}}}]),b.directive("uiGridCell",["uiGridCellNavService","$log","uiGridCellNavConstants",function(a,b,c){return{priority:-150,restrict:"A",require:"^uiGrid",scope:!1,link:function(b,d,e,f){function g(){d.find("div").attr("tabindex",-1)}function h(){var a=d.find("div");a[0].focus(),a.attr("tabindex",0)}b.col.colDef.allowCellFocus&&(g(),d.on("keydown",function(c){var d=a.getDirection(c);if(null===d)return!0;var e=a.getNextRowCol(d,b.grid,b.row,b.col);return f.cellNav.broadcastCellNav(e),g(),!1}),d.find("div").on("focus",function(){f.cellNav.broadcastFocus(b.row,b.col)}),b.$on(c.CELL_NAV_EVENT,function(a,c){c.row===b.row&&c.col===b.col&&h()}))}}}])}(),function(){"use strict";var a=angular.module("ui.grid.edit",["ui.grid"]);a.constant("uiGridEditConstants",{EDITABLE_CELL_TEMPLATE:/EDITABLE_CELL_TEMPLATE/g,EDITABLE_CELL_DIRECTIVE:/editable_cell_directive/g,events:{BEGIN_CELL_EDIT:"uiGridEventBeginCellEdit",END_CELL_EDIT:"uiGridEventEndCellEdit",CANCEL_CELL_EDIT:"uiGridEventCancelCellEdit"}}),a.service("uiGridEditService",["$log","$q","$templateCache","uiGridConstants","gridUtil",function(a,b,c,d,e){var f={initializeGrid:function(a){f.defaultGridOptions(a.options),a.registerColumnBuilder(f.editColumnBuilder);var b={events:{edit:{afterCellEdit:function(){},beginCellEdit:function(){},cancelCellEdit:function(){}}},methods:{edit:{}}};a.api.registerEventsFromObject(b.events)},defaultGridOptions:function(a){a.cellEditableCondition=void 0===a.cellEditableCondition?!0:a.cellEditableCondition,a.enableCellEditOnFocus=void 0===a.enableCellEditOnFocus?!1:a.enableCellEditOnFocus},editColumnBuilder:function(a,c,d){var f=[];return a.enableCellEdit=void 0===a.enableCellEdit?void 0===d.enableCellEdit?"object"!==a.type:d.enableCellEdit:a.enableCellEdit,a.cellEditableCondition=void 0===a.cellEditableCondition?d.cellEditableCondition:a.cellEditableCondition,a.enableCellEdit&&(a.editableCellTemplate=a.editableCellTemplate||d.editableCellTemplate||"ui-grid/cellEditor",f.push(e.getTemplate(a.editableCellTemplate).then(function(a){c.editableCellTemplate=a},function(){throw new Error("Couldn't fetch/use colDef.editableCellTemplate '"+a.editableCellTemplate+"'")}))),a.enableCellEditOnFocus=void 0===a.enableCellEditOnFocus?d.enableCellEditOnFocus:a.enableCellEditOnFocus,b.all(f)},isStartEditKey:function(a){return a.keyCode===d.keymap.LEFT||a.keyCode===d.keymap.TAB&&a.shiftKey||a.keyCode===d.keymap.RIGHT||a.keyCode===d.keymap.TAB||a.keyCode===d.keymap.UP||a.keyCode===d.keymap.ENTER&&a.shiftKey||a.keyCode===d.keymap.DOWN||a.keyCode===d.keymap.ENTER?!1:!0}};return f}]),a.directive("uiGridEdit",["$log","uiGridEditService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(){}}}}}]),a.directive("uiGridCell",["$compile","uiGridConstants","uiGridEditConstants","$log","$parse","uiGridEditService",function(a,b,c,d,e,f){return{priority:-100,restrict:"A",scope:!1,link:function(d,g){function h(){g.on("dblclick",m),g.on("keydown",k),d.col.colDef.enableCellEditOnFocus&&g.find("div").on("focus",j)}function i(){g.off("dblclick",m),g.off("keydown",k),d.col.colDef.enableCellEditOnFocus&&g.find("div").off("focus",j)}function j(a){a.stopPropagation(),m()}function k(a){f.isStartEditKey(a)&&m()}function l(a,b){return!b.isSaving&&(angular.isFunction(a.colDef.cellEditableCondition)?a.colDef.cellEditableCondition(d):a.colDef.cellEditableCondition)}function m(){if(l(d.col,d.row)){r=e(d.row.getQualifiedColField(d.col)),q=r(d),p=d.col.editableCellTemplate,p=p.replace(b.COL_FIELD,d.row.getQualifiedColField(d.col));var f=d.col.colDef.editDropdownFilter?"|"+d.col.colDef.editDropdownFilter:"";switch(p=p.replace(b.CUSTOM_FILTERS,f),d.inputType="text",d.col.colDef.type){case"boolean":d.inputType="checkbox";break;case"number":d.inputType="number";break;case"date":d.inputType="date"}d.editDropdownOptionsArray=d.col.colDef.editDropdownOptionsArray,d.editDropdownIdLabel=d.col.colDef.editDropdownIdLabel?d.col.colDef.editDropdownIdLabel:"id",d.editDropdownValueLabel=d.col.colDef.editDropdownValueLabel?d.col.colDef.editDropdownValueLabel:"value";var h;d.$apply(function(){s=!0,i(),h=a(p)(d.$new());var b=angular.element(g.children()[0]);t=b.hasClass(":focus"),b.addClass("ui-grid-cell-contents-hidden"),g.append(h)});var j=d.$on(b.events.GRID_SCROLL,function(){n(!0),d.grid.api.edit.raise.afterCellEdit(d.row.entity,d.col.colDef,r(d),q),j()}),k=d.$on(c.events.END_CELL_EDIT,function(a,b){n(b),d.grid.api.edit.raise.afterCellEdit(d.row.entity,d.col.colDef,r(d),q),k()}),m=d.$on(c.events.CANCEL_CELL_EDIT,function(){o(),m()});d.$broadcast(c.events.BEGIN_CELL_EDIT),d.grid.api.edit.raise.beginCellEdit(d.row.entity,d.col.colDef)}}function n(a){if(s){var b=angular.element(g.children()[0]);angular.element(g.children()[1]).remove(),b.removeClass("ui-grid-cell-contents-hidden"),a&&t&&b.focus(),t=!1,s=!1,h()}}function o(){s&&(r.assign(d,q),d.$apply(),d.grid.api.edit.raise.cancelCellEdit(d.row.entity,d.col.colDef),n(!0))}if(d.col.colDef.enableCellEdit){var p,q,r,s=!1,t=!1;h()}}}}]),a.directive("uiGridEditor",["uiGridConstants","uiGridEditConstants",function(a,b){return{scope:!0,compile:function(){return{pre:function(){},post:function(c,d){c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].select(),d.on("blur",function(a){c.stopEdit(a)})}),c.deepEdit=!1,c.stopEdit=function(a){c.inputForm&&!c.inputForm.$valid?(a.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT)):c.$emit(b.events.END_CELL_EDIT),c.deepEdit=!1},d.on("click",function(){c.deepEdit=!0}),d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT);break;case a.keymap.ENTER:c.stopEdit(d);break;case a.keymap.TAB:c.stopEdit(d)}if(c.deepEdit)switch(d.keyCode){case a.keymap.LEFT:d.stopPropagation();break;case a.keymap.RIGHT:d.stopPropagation();break;case a.keymap.UP:d.stopPropagation();break;case a.keymap.DOWN:d.stopPropagation()}return!0})}}}}}]),a.directive("input",["$filter",function(a){function b(a){if("undefined"==typeof a||""===a)return null;var b=a.split("-");if(3!==b.length)return null;var c=parseInt(b[0],10),d=parseInt(b[1],10),e=parseInt(b[2],10);return 1>d||1>c||1>e?null:new Date(c,d-1,e)}return{restrict:"E",require:"?ngModel",link:function(c,d,e,f){2===angular.version.minor&&e.type&&"date"===e.type&&f&&(f.$formatters.push(function(b){return f.$setValidity(null,!b||!isNaN(b.getTime())),a("date")(b,"yyyy-MM-dd")}),f.$parsers.push(function(a){if(a&&a.length>0){var c=b(a);return f.$setValidity(null,c&&!isNaN(c.getTime())),c}return f.$setValidity(null,!0),null}))}}}]),a.directive("uiGridEditDropdown",["uiGridConstants","uiGridEditConstants",function(a,b){return{scope:!0,compile:function(){return{pre:function(){},post:function(c,d){c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].style.width=d[0].parentElement.offsetWidth-1+"px",d.on("blur",function(a){c.stopEdit(a)})}),c.stopEdit=function(){c.$emit(b.events.END_CELL_EDIT)},d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT);break;case a.keymap.ENTER:c.stopEdit(d);break;case a.keymap.LEFT:c.stopEdit(d);break;case a.keymap.RIGHT:c.stopEdit(d);break;case a.keymap.UP:d.stopPropagation();break;case a.keymap.DOWN:d.stopPropagation();break;case a.keymap.TAB:c.stopEdit(d)}return!0})}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.expandable",["ui.grid"]);a.service("uiGridExpandableService",["gridUtil","$log","$compile",function(){var a={initializeGrid:function(b){var c={events:{expandable:{rowExpandedStateChanged:function(){}}},methods:{expandable:{toggleRowExpansion:function(c){var d=b.getRow(c);null!==d&&a.toggleRowExpansion(b,d)},expandAllRows:function(){a.expandAllRows(b)},collapseAllRows:function(){a.collapseAllRows(b)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods)},toggleRowExpansion:function(a,b){b.isExpanded=!b.isExpanded,b.height=b.isExpanded?b.grid.options.rowHeight+a.options.expandable.expandableRowHeight:b.grid.options.rowHeight,a.api.expandable.raise.rowExpandedStateChanged(b)},expandAllRows:function(b){angular.forEach(b.renderContainers.body.visibleRowCache,function(c){c.isExpanded||a.toggleRowExpansion(b,c)}),b.refresh()},collapseAllRows:function(b){angular.forEach(b.renderContainers.body.visibleRowCache,function(c){c.isExpanded&&a.toggleRowExpansion(b,c)}),b.refresh()}};return a}]),a.directive("uiGridExpandable",["$log","uiGridExpandableService","$templateCache",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,d,e,f){var g={name:"expandableButtons",width:40};
+g.cellTemplate=c.get("ui-grid/expandableRowHeader"),f.grid.addRowHeaderColumn(g),b.initializeGrid(f.grid)},post:function(){}}}}}]),a.directive("uiGridExpandableRow",["uiGridExpandableService","$timeout","$log","$compile","uiGridConstants","gridUtil","$interval",function(a,b,c,d,e,f){return{replace:!1,priority:0,scope:!1,compile:function(){return{pre:function(a,b){f.getTemplate(a.grid.options.expandable.rowExpandableTemplate).then(function(c){var e=d(c)(a);b.append(e),a.row.expandedRendered=!0})},post:function(a){a.$on("$destroy",function(){a.row.expandedRendered=!1})}}}}}]),a.directive("uiGridRow",["$compile","$log","$templateCache",function(){return{priority:-200,scope:!1,compile:function(){return{pre:function(a){a.expandableRow={},a.expandableRow.shouldRenderExpand=function(){var b="body"===a.colContainer.name&&a.row.isExpanded&&(!a.grid.isScrollingVertically||a.row.expandedRendered);return b},a.expandableRow.shouldRenderFiller=function(){var b=a.row.isExpanded&&("body"!==a.colContainer.name||a.grid.isScrollingVertically&&!a.row.expandedRendered);return b}},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","$log","$templateCache",function(a,b,c){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]),d=c.get("ui-grid/expandableScrollFiller"),e=c.get("ui-grid/expandableRow");return b.append(e),b.append(d),{pre:function(){},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.exporter",["ui.grid"]);a.constant("uiGridExporterConstants",{featureName:"exporter",ALL:"all",VISIBLE:"visible",SELECTED:"selected",CSV_CONTENT:"CSV_CONTENT",LINK_LABEL:"LINK_LABEL",BUTTON_LABEL:"BUTTON_LABEL"}),a.service("uiGridExporterService",["$log","$q","uiGridExporterConstants","gridUtil","$compile",function(a,b,c,d,e){var f={initializeGrid:function(a){a.exporter={},this.defaultGridOptions(a.options);var b={events:{exporter:{}},methods:{exporter:{csvExport:function(b,c,d){f.csvExport(a,b,c,d)},pdfExport:function(b,c){f.pdfExport(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},defaultGridOptions:function(a){a.exporterSuppressButton=a.exporterSuppressButton===!0,a.exporterLinkTemplate=a.exporterLinkTemplate?a.exporterLinkTemplate:"ui-grid/csvLink",a.exporterHeaderTemplate=a.exporterHeaderTemplate?a.exporterHeaderTemplate:"ui-grid/exporterHeader",a.exporterLinkLabel=a.exporterLinkLabel?a.exporterLinkLabel:"Download CSV",a.exporterButtonLabel=a.exporterButtonLabel?a.exporterButtonLabel:"Export",a.exporterPdfDefaultStyle=a.exporterPdfDefaultStyle?a.exporterPdfDefaultStyle:{fontSize:11},a.exporterPdfTableStyle=a.exporterPdfTableStyle?a.exporterPdfTableStyle:{margin:[0,5,0,15]},a.exporterPdfTableHeaderStyle=a.exporterPdfTableHeaderStyle?a.exporterPdfTableHeaderStyle:{bold:!0,fontSize:12,color:"black"},a.exporterPdfOrientation=a.exporterPdfOrientation?a.exporterPdfOrientation:"landscape",a.exporterPdfPageSize=a.exporterPdfPageSize?a.exporterPdfPageSize:"A4",a.exporterPdfMaxGridWidth=a.exporterPdfMaxGridWidth?a.exporterPdfMaxGridWidth:720},showMenu:function(a){a.exporter.$scope.menuItems=[{title:"Export all data as csv",action:function(){this.grid.api.exporter.csvExport(c.ALL,c.ALL)}},{title:"Export visible data as csv",action:function(){this.grid.api.exporter.csvExport(c.VISIBLE,c.VISIBLE)}},{title:"Export selected data as csv",action:function(){this.grid.api.exporter.csvExport(c.SELECTED,c.VISIBLE)}},{title:"Export all data as pdf",action:function(){this.grid.api.exporter.pdfExport(c.ALL,c.ALL)}},{title:"Export visible data as pdf",action:function(){this.grid.api.exporter.pdfExport(c.VISIBLE,c.VISIBLE)}},{title:"Export selected data as pdf",action:function(){this.grid.api.exporter.pdfExport(c.SELECTED,c.VISIBLE)}}],a.exporter.$scope.$broadcast("toggleExporterMenu")},csvExport:function(a,b,c,d){var e=this.getColumnHeaders(a,c),f=this.getData(a,b,c),g=this.formatAsCsv(e,f);this.renderCsvLink(a,g,d)},getColumnHeaders:function(a,b){var d=[];return angular.forEach(a.columns,function(a){(a.visible||b===c.ALL)&&d.push({name:a.field,displayName:a.displayName,width:a.drawnWidth?a.drawnWidth:a.width,align:"number"===a.colDef.type?"right":"left"})}),d},getData:function(b,d,e){var f,g=[];switch(d){case c.ALL:f=b.rows;break;case c.VISIBLE:f=b.getVisibleRows();break;case c.SELECTED:b.api.selection?f=b.api.selection.getSelectedGridRows():a.error("selection feature must be enabled to allow selected rows to be exported")}return c.ALL?(angular.forEach(f,function(a){var d=[];angular.forEach(b.columns,function(f){(f.visible||e===c.ALL)&&d.push(b.getCellValue(a,f))}),g.push(d)}),g):void 0},formatAsCsv:function(a,b){var c=this,d=a.map(function(a){return a.displayName}),e=c.formatRowAsCsv(this)(d)+"\n";return e+=b.map(this.formatRowAsCsv(this)).join("\n")},formatRowAsCsv:function(a){return function(b){return b.map(a.formatFieldAsCsv).join(",")}},formatFieldAsCsv:function(a){return null==a?"":"number"==typeof a?a:"boolean"==typeof a?a?"TRUE":"FALSE":"string"==typeof a?'"'+a.replace(/"/g,'""')+'"':JSON.stringify(a)},renderCsvLink:function(a,b,f){var g=f?f:angular.element(a.exporter.gridElm[0].querySelectorAll(".ui-grid-exporter-csv-link"));angular.element(g[0].querySelectorAll(".ui-grid-exporter-csv-link-span"))&&angular.element(g[0].querySelectorAll(".ui-grid-exporter-csv-link-span")).remove();d.getTemplate(a.options.exporterLinkTemplate).then(function(d){d=d.replace(c.LINK_LABEL,a.options.exporterLinkLabel),d=d.replace(c.CSV_CONTENT,encodeURIComponent(b));var f=angular.element(d),h=e(f)(a.exporter.$scope);g.append(h)})},pdfExport:function(a,b,c){var d=this.getColumnHeaders(a,c),e=this.getData(a,b,c),f=this.prepareAsPdf(a,d,e);pdfMake.createPdf(f).open()},prepareAsPdf:function(a,b,c){var d=this.calculatePdfHeaderWidths(a,b),e=b.map(function(a){return{text:a.displayName,style:"tableHeader"}}),f=c.map(this.formatRowAsPdf(this)),g=[e].concat(f),h={pageOrientation:a.options.exporterPdfOrientation,content:[{style:"tableStyle",table:{headerRows:1,widths:d,body:g}}],styles:{tableStyle:a.options.exporterPdfTableStyle,tableHeader:a.options.exporterPdfTableHeaderStyle},defaultStyle:a.options.exporterPdfDefaultStyle};return a.options.exporterPdfLayout&&(h.layout=a.options.exporterPdfLayout),h},calculatePdfHeaderWidths:function(a,b){var c=0;angular.forEach(b,function(a){"number"==typeof a.width&&(c+=a.width)});var d=0;angular.forEach(b,function(a){if("*"===a.width&&(d+=100),"string"==typeof a.width&&a.width.match(/(\d)*%/)){var b=parseInt(a.width.match(/(\d)*%/)[0]);a.width=c*b/100,d+=a.width}});var e=c+d;return b.map(function(b){return"*"===b.width?b.width:b.width*a.options.exporterPdfMaxGridWidth/e})},formatRowAsPdf:function(a){return function(b){return b.map(a.formatFieldAsPdfString)}},formatFieldAsPdfString:function(a){return null==a?"":"number"==typeof a?a.toString():"boolean"==typeof a?a?"TRUE":"FALSE":"string"==typeof a?a.replace(/"/g,'""'):JSON.stringify(a).replace(/^"/,"").replace(/"$/,"")}};return f}]),a.directive("uiGridExporter",["$log","uiGridExporterConstants","uiGridExporterService","gridUtil","$compile",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,b,d,e){c.initializeGrid(e.grid),e.grid.exporter.$scope=a},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.infiniteScroll",["ui.grid"]);a.service("uiGridInfiniteScrollService",["gridUtil","$log","$compile","$timeout",function(){var a={initializeGrid:function(a){var b={events:{infiniteScroll:{needLoadMoreData:function(){}}},methods:{infiniteScroll:{dataLoaded:function(){a.options.loadTimout=!1}}}};a.options.loadTimout=!1,a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},loadData:function(a){a.api.infiniteScroll.raise.needLoadMoreData(),a.options.loadTimout=!0},checkScroll:function(a,b){var c=a.options.infiniteScrollPercentage?a.options.infiniteScrollPercentage:20;return!a.options.loadTimout&&c>=b?(this.loadData(a),!0):!1}};return a}]),a.directive("uiGridInfiniteScroll",["$log","uiGridInfiniteScrollService",function(a,b){return{priority:-200,scope:!1,require:"^uiGrid",compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","$log","uiGridInfiniteScrollService","uiGridConstants",function(a,b,c,d){return{priority:-200,scope:!1,link:function(a){a.$on(d.events.GRID_SCROLL,function(b,d){var e=100-100*d.y.percentage;c.checkScroll(a.grid,e)})}}}])}(),function(){"use strict";var a=angular.module("ui.grid.pinning",["ui.grid"]);a.config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("en",{pinning:{pinLeft:"Pin Left",pinRight:"Pin Right",unpin:"Unpin"}}),a}])}]),a.service("uiGridPinningService",["$log","GridRenderContainer","i18nService",function(a,b,c){var d={initializeGrid:function(a){d.defaultGridOptions(a.options),a.registerColumnBuilder(d.pinningColumnBuilder)},defaultGridOptions:function(a){a.enablePinning=a.enablePinning!==!1},pinningColumnBuilder:function(a,b,d){if(a.enablePinning=void 0===a.enablePinning?d.enablePinning:a.enablePinning,a.pinnedLeft?(b.renderContainer="left",b.grid.createLeftContainer()):a.pinnedRight&&(b.renderContainer="right",b.grid.createRightContainer()),a.enablePinning){var e={title:c.get().pinning.pinLeft,icon:"ui-grid-icon-left-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"left"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer="left",this.context.col.grid.createLeftContainer(),b.grid.refresh().then(function(){b.grid.refresh()})}},f={title:c.get().pinning.pinRight,icon:"ui-grid-icon-right-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"right"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer="right",this.context.col.grid.createRightContainer(),b.grid.refresh().then(function(){b.grid.refresh()})}},g={title:c.get().pinning.unpin,icon:"ui-grid-icon-cancel",shown:function(){return"undefined"!=typeof this.context.col.renderContainer&&null!==this.context.col.renderContainer&&"body"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer=null,b.grid.refresh().then(function(){b.grid.refresh()})}};b.menuItems.push(e),b.menuItems.push(f),b.menuItems.push(g)}}};return d}]),a.directive("uiGridPinning",["$log","uiGridPinningService",function(a,b){return{require:"uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.resizeColumns",["ui.grid"]);a.constant("columnBounds",{minWidth:35}),a.service("uiGridResizeColumnsService",["$log","$q",function(a,b){var c={defaultGridOptions:function(a){a.enableColumnResizing=a.enableColumnResizing!==!1,a.enableColumnResize===!1&&(a.enableColumnResizing=!1)},colResizerColumnBuilder:function(a,c,d){var e=[];return a.enableColumnResizing=void 0===a.enableColumnResizing?d.enableColumnResizing:a.enableColumnResizing,a.enableColumnResize===!1&&(a.enableColumnResizing=!1),b.all(e)}};return c}]),a.directive("uiGridResizeColumns",["$log","uiGridResizeColumnsService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.defaultGridOptions(e.grid.options),e.grid.registerColumnBuilder(b.colResizerColumnBuilder)},post:function(){}}}}}]),a.directive("uiGridHeaderCell",["$log","$templateCache","$compile","$q",function(a,b,c,d){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,e,f,g){if(g.grid.options.enableColumnResizing){var h=d.defer();f.$observe("renderIndex",function(b){a.renderIndex=a.$eval(b),h.resolve()}),h.promise.then(function(){var d=b.get("ui-grid/columnResizer"),f=angular.element(d).clone(),g=angular.element(d).clone();f.attr("position","left"),g.attr("position","right");var h=a.col,i=h.getRenderContainer(),j=i.renderedColumns[a.renderIndex-1];j&&0!==a.col.index&&j.colDef.enableColumnResizing!==!1&&e.prepend(f),a.col.colDef.enableColumnResizing!==!1&&e.append(g),c(f)(a),c(g)(a)})}}}}}}]),a.directive("uiGridColumnResizer",["$log","$document","gridUtil","uiGridConstants","columnBounds",function(a,b,c,d,e){var f=angular.element('<div class="ui-grid-resize-overlay"></div>'),g={priority:0,scope:{col:"=",position:"@",renderIndex:"="},require:"?^uiGrid",link:function(a,g,h,i){function j(a){var b=a.getRenderContainer();b.visibleColumnCache.forEach(function(b){if(b.index!==a.index){var c=b.colDef;(!c.width||angular.isString(c.width)&&(-1!==c.width.indexOf("*")||-1!==c.width.indexOf("%")))&&(c.width=b.drawnWidth)}})}function k(){i.grid.buildColumns().then(function(){i.grid.refreshCanvas(!0)})}function l(b){b.originalEvent&&(b=b.originalEvent),b.preventDefault(),o=b.clientX-p,0>o?o=0:o>i.grid.gridWidth&&(o=i.grid.gridWidth);var c,g=a.col,h=g.getRenderContainer();if("left"===a.position?(g=h.renderedColumns[a.renderIndex-1],c=a.col):"right"===a.position&&(c=h.renderedColumns[a.renderIndex+1]),g.colDef.enableColumnResizing!==!1){i.grid.element.hasClass("column-resizing")||i.grid.element.addClass("column-resizing");var j=o-n,k=g.drawnWidth+j;g.colDef.minWidth&&k<g.colDef.minWidth?o+=g.colDef.minWidth-k:!g.colDef.minWidth&&e.minWidth&&k<e.minWidth?o+=g.colDef.minWidth-k:g.colDef.maxWidth&&k>g.colDef.maxWidth&&(o+=g.colDef.maxWidth-k),f.css({left:o+"px"}),i.fireEvent(d.events.ITEM_DRAGGING)}}function m(c){c.originalEvent&&(c=c.originalEvent),c.preventDefault(),i.grid.element.removeClass("column-resizing"),f.remove(),o=c.clientX-p;var d=o-n;if(0===d)return b.off("mouseup",m),void b.off("mousemove",l);var g,h=a.col,q=h.getRenderContainer();if("left"===a.position?(h=q.renderedColumns[a.renderIndex-1],g=a.col):"right"===a.position&&(g=q.renderedColumns[a.renderIndex+1]),h.colDef.enableColumnResizing!==!1){var r=h.drawnWidth+d;h.colDef.minWidth&&r<h.colDef.minWidth?r=h.colDef.minWidth:!h.colDef.minWidth&&e.minWidth&&r<e.minWidth&&(r=e.minWidth),h.colDef.maxWidth&&r>h.colDef.maxWidth&&(r=h.colDef.maxWidth),h.colDef.width=r,j(h),k(d),b.off("mouseup",m),b.off("mousemove",l)}}var n=0,o=0,p=0;"left"===a.position?g.addClass("left"):"right"===a.position&&g.addClass("right"),g.on("mousedown",function(a){a.originalEvent&&(a=a.originalEvent),a.stopPropagation(),p=i.grid.element[0].getBoundingClientRect().left,n=a.clientX-p,i.grid.element.append(f),f.css({left:n}),b.on("mouseup",m),b.on("mousemove",l)}),g.on("dblclick",function(b){b.stopPropagation();var f,h,i=a.col,l=i.getRenderContainer();"left"===a.position?(i=l.renderedColumns[a.renderIndex-1],f=a.col,h=1):"right"===a.position&&(f=l.renderedColumns[a.renderIndex+1],f=l.renderedColumns[a.renderIndex+1],h=-1);var m=0,n=0,o=c.closestElm(g,".ui-grid-render-container"),p=o.querySelectorAll("."+d.COL_CLASS_PREFIX+i.index+" .ui-grid-cell-contents");Array.prototype.forEach.call(p,function(a){var b;angular.element(a).parent().hasClass("ui-grid-header-cell")&&(b=angular.element(a).parent()[0].querySelectorAll(".ui-grid-column-menu-button")),c.fakeElement(a,{},function(a){var d=angular.element(a);d.attr("style","float: left");var e=c.elementWidth(d);if(b){var f=c.elementWidth(b);e+=f}e>m&&(m=e,n=m-e)})}),i.colDef.minWidth&&m<i.colDef.minWidth?m=i.colDef.minWidth:!i.colDef.minWidth&&e.minWidth&&m<e.minWidth&&(m=e.minWidth),i.colDef.maxWidth&&m>i.colDef.maxWidth&&(m=i.colDef.maxWidth),i.colDef.width=m,j(i),k(n)}),g.on("$destroy",function(){g.off("mousedown"),g.off("dblclick"),b.off("mousemove",l),b.off("mouseup",m)})}};return g}])}(),function(){"use strict";var a=angular.module("ui.grid.rowEdit",["ui.grid","ui.grid.edit","ui.grid.cellNav"]);a.constant("uiGridRowEditConstants",{}),a.service("uiGridRowEditService",["$interval","$log","$q","uiGridConstants","uiGridRowEditConstants","gridUtil",function(a,b,c){var d={initializeGrid:function(a,b){var c={events:{rowEdit:{saveRow:function(){}}},methods:{rowEdit:{setSavePromise:function(a,b,c){d.setSavePromise(a,b,c)},getDirtyRows:function(a){return a.rowEditDirtyRows},getErrorRows:function(a){return a.rowEditErrorRows},flushDirtyRows:function(a){return d.flushDirtyRows(a)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.api.core.on.renderingComplete(a,function(){b.api.edit.on.afterCellEdit(a,d.endEditCell),b.api.edit.on.beginCellEdit(a,d.beginEditCell),b.api.edit.on.cancelCellEdit(a,d.cancelEditCell),b.api.cellNav&&b.api.cellNav.on.navigate(a,d.navigate)})},defaultGridOptions:function(){},saveRow:function(a,c){var d=this;return function(){c.isSaving=!0;var e=a.api.rowEdit.raise.saveRow(c.entity);return c.rowEditSavePromise?c.rowEditSavePromise.then(d.processSuccessPromise(a,c),d.processErrorPromise(a,c)):b.log("A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise"),e}},setSavePromise:function(a,b,c){var d=a.getRow(b);d.rowEditSavePromise=c},processSuccessPromise:function(a,b){var c=this;return function(){delete b.isSaving,delete b.isDirty,delete b.isError,delete b.rowEditSaveTimer,c.removeRow(a.rowEditErrorRows,b),c.removeRow(a.rowEditDirtyRows,b)}},processErrorPromise:function(a,b){return function(){delete b.isSaving,delete b.rowEditSaveTimer,b.isError=!0,a.rowEditErrorRows||(a.rowEditErrorRows=[]),a.rowEditErrorRows.push(b)}},removeRow:function(a,b){angular.forEach(a,function(c,d){c.uid===b.uid&&a.splice(d,1)})},flushDirtyRows:function(a){var b=[];return angular.forEach(a.rowEditDirtyRows,function(c){d.saveRow(a,c)(),b.push(c.rowEditSavePromise)}),c.all(b)},endEditCell:function(a,c,e,f){var g=this.grid,h=g.getRow(a);return h?void((e!==f||h.isDirty)&&(g.rowEditDirtyRows||(g.rowEditDirtyRows=[]),h.isDirty||(h.isDirty=!0,g.rowEditDirtyRows.push(h)),delete h.isError,d.considerSetTimer(g,h))):void b.log("Unable to find rowEntity in grid data, dirty flag cannot be set")},beginEditCell:function(a){var c=this.grid,e=c.getRow(a);return e?void d.cancelTimer(c,e):void b.log("Unable to find rowEntity in grid data, timer cannot be cancelled")},cancelEditCell:function(a){var c=this.grid,e=c.getRow(a);return e?void d.considerSetTimer(c,e):void b.log("Unable to find rowEntity in grid data, timer cannot be set")},navigate:function(a,b){var c=this.grid;a.row.rowEditSaveTimer&&d.cancelTimer(c,a.row),b&&b.row&&b.row!==a.row&&d.considerSetTimer(c,b.row)},considerSetTimer:function(b,c){if(d.cancelTimer(b,c),c.isDirty&&!c.isSaving){var e=b.options.rowEditWaitInterval?b.options.rowEditWaitInterval:2e3;c.rowEditSaveTimer=a(d.saveRow(b,c),e,1)}},cancelTimer:function(b,c){c.rowEditSaveTimer&&!c.isSaving&&(a.cancel(c.rowEditSaveTimer),delete c.rowEditSaveTimer)}};return d}]),a.directive("uiGridRowEdit",["$log","uiGridRowEditService","uiGridEditConstants",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","$log","$parse",function(){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]);return b.attr("ng-class","{'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}"),{pre:function(){},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.selection",["ui.grid"]);a.constant("uiGridSelectionConstants",{featureName:"selection"}),a.service("uiGridSelectionService",["$log","$q","$templateCache","uiGridSelectionConstants","gridUtil",function(){var a={initializeGrid:function(b){b.selection={},b.selection.lastSelectedRow=null,a.defaultGridOptions(b.options);var c={events:{selection:{rowSelectionChanged:function(){}}},methods:{selection:{toggleRowSelection:function(c){var d=b.getRow(c);null!==d&&a.toggleRowSelection(b,d,b.options.multiSelect)},selectRow:function(c){var d=b.getRow(c);null===d||d.isSelected||a.toggleRowSelection(b,d,b.options.multiSelect)},unSelectRow:function(c){var d=b.getRow(c);null!==d&&d.isSelected&&a.toggleRowSelection(b,d,b.options.multiSelect)},selectAllRows:function(){b.options.multiSelect!==!1&&b.rows.forEach(function(a){a.isSelected=!0})},selectAllVisibleRows:function(){b.options.multiSelect!==!1&&b.rows.forEach(function(a){a.isSelected=a.visible?!0:!1})},clearSelectedRows:function(){a.clearSelectedRows(b)},getSelectedRows:function(){return a.getSelectedRows(b).map(function(a){return a.entity})},getSelectedGridRows:function(){return a.getSelectedRows(b)},setMultiSelect:function(a){b.options.multiSelect=a}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableRowSelection=a.enableRowSelection!==!1,a.multiSelect=a.multiSelect!==!1,a.enableRowHeaderSelection=a.enableRowHeaderSelection!==!1},toggleRowSelection:function(b,c,d){var e=c.isSelected;d||e||a.clearSelectedRows(b),c.isSelected=!e,c.isSelected===!0&&(b.selection.lastSelectedRow=c),b.api.selection.raise.rowSelectionChanged(c)},shiftSelect:function(b,c,d){if(d){var e=a.getSelectedRows(b),f=e.length>0?b.renderContainers.body.visibleRowCache.indexOf(b.selection.lastSelectedRow):0,g=b.renderContainers.body.visibleRowCache.indexOf(c);if(f>g){var h=f;f=g,g=h}for(var i=f;g>=i;i++){var j=b.renderContainers.body.visibleRowCache[i];j&&(j.isSelected=!0,b.selection.lastSelectedRow=j,b.api.selection.raise.rowSelectionChanged(j))}}},getSelectedRows:function(a){return a.rows.filter(function(a){return a.isSelected})},clearSelectedRows:function(b){a.getSelectedRows(b).forEach(function(a){a.isSelected=!1,b.api.selection.raise.rowSelectionChanged(a)})}};return a}]),a.directive("uiGridSelection",["$log","uiGridSelectionConstants","uiGridSelectionService","$templateCache",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,b,d,e){if(c.initializeGrid(e.grid),e.grid.options.enableRowHeaderSelection){var f="ui-grid/selectionRowHeader",g={name:"selectionRowHeaderCol",displayName:"",width:30,cellTemplate:f};e.grid.addRowHeaderColumn(g)}},post:function(){}}}}}]),a.directive("uiGridSelectionRowHeaderButtons",["$log","$templateCache","uiGridSelectionService",function(a,b,c){return{replace:!0,restrict:"E",template:b.get("ui-grid/selectionRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,b,d,e){var f=e.grid;a.selectButtonClick=function(a,b){b.shiftKey?c.shiftSelect(f,a,f.options.multiSelect):c.toggleRowSelection(f,a,f.options.multiSelect)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","uiGridSelectionConstants","$log","$parse","uiGridSelectionService",function(){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]);return b.attr("ng-class","{'ui-grid-row-selected': row.isSelected}"),{pre:function(){},post:function(){}}}}}]),a.directive("uiGridCell",["$compile","uiGridConstants","uiGridSelectionConstants","$log","$parse","uiGridSelectionService",function(a,b,c,d,e,f){return{priority:-200,restrict:"A",scope:!1,link:function(a,b){function c(){b.on("click",function(b){b.shiftKey?f.shiftSelect(a.grid,a.row,a.grid.options.multiSelect):f.toggleRowSelection(a.grid,a.row,a.grid.options.multiSelect),a.$apply()})}a.grid.options.enableRowSelection&&!a.grid.options.enableRowHeaderSelection&&(b.addClass("ui-grid-disable-selection"),c())}}}])}(),angular.module("ui.grid").run(["$templateCache",function(a){"use strict";a.put("ui-grid/ui-grid-footer",'<div class="ui-grid-footer-panel"><div ui-grid-group-panel ng-show="grid.options.showGroupPanel"></div><div class="ui-grid-footer ui-grid-footer-viewport"><div class="ui-grid-footer-canvas"><div ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ui-grid-footer-cell col="col" render-index="$index" class="ui-grid-footer-cell clearfix" ng-style="$index === 0 && colContainer.columnStyle($index)"></div></div></div></div>'),a.put("ui-grid/ui-grid-group-panel",'<div class="ui-grid-group-panel"><div ui-t="groupPanel.description" class="description" ng-show="groupings.length == 0"></div><ul ng-show="groupings.length > 0" class="ngGroupList"><li class="ngGroupItem" ng-repeat="group in configGroups"><span class="ngGroupElement"><span class="ngGroupName">{{group.displayName}} <span ng-click="removeGroup($index)" class="ngRemoveGroup">x</span></span> <span ng-hide="$last" class="ngGroupArrow"></span></span></li></ul></div>'),a.put("ui-grid/ui-grid-header",'<div class="ui-grid-top-panel"><div ui-grid-group-panel ng-show="grid.options.showGroupPanel"></div><div class="ui-grid-header ui-grid-header-viewport"><div class="ui-grid-header-canvas"><div class="ui-grid-header-cell clearfix" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ui-grid-header-cell col="col" render-index="$index" ng-style="$index === 0 && colContainer.columnStyle($index)"></div></div></div><div ui-grid-menu></div></div>'),a.put("ui-grid/ui-grid-no-header",'<div class="ui-grid-top-panel"></div>'),a.put("ui-grid/ui-grid-row",'<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader }" ui-grid-cell></div>'),a.put("ui-grid/ui-grid",'<div ui-i18n="en" class="ui-grid"><!-- TODO (c0bra): add "scoped" attr here, eventually? --><style ui-grid-style>.grid{{ grid.id }} {\n      /* Styles for the grid */\n    }\n\n    .grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {\n      height: {{ grid.options.rowHeight }}px;\n    }\n\n    .grid{{ grid.id }} .ui-grid-row:last-child .ui-grid-cell {\n      border-bottom-width: {{ ((grid.getTotalRowHeight() < grid.getViewportHeight()) && \'1\') || \'0\' }}px;\n    }\n\n    {{ grid.verticalScrollbarStyles }}\n    {{ grid.horizontalScrollbarStyles }}\n\n    .ui-grid[dir=rtl] .ui-grid-viewport {\n      padding-left: {{ grid.verticalScrollbarWidth }}px;\n    }\n\n    {{ grid.customStyles }}</style><div ui-grid-render-container container-id="\'body\'" col-container-name="\'body\'" row-container-name="\'body\'" bind-scroll-horizontal="true" bind-scroll-vertical="true" enable-scrollbars="grid.options.enableScrollbars"></div><div ui-grid-column-menu ng-if="grid.options.enableColumnMenu"></div><div ng-transclude></div></div>'),a.put("ui-grid/uiGridCell",'<div class="ui-grid-cell-contents">{{COL_FIELD CUSTOM_FILTERS}}</div>'),a.put("ui-grid/uiGridColumnFilter",'<li class="ui-grid-menu-item ui-grid-clearfix ui-grid-column-filter" ng-show="itemShown()" ng-click="$event.stopPropagation();"><div class="input-container"><input class="column-filter-input" type="text" ng-model="item.model" placeholder="{{ i18n.search.placeholder }}"><div class="column-filter-cancel-icon-container"><i class="ui-grid-filter-cancel ui-grid-icon-cancel column-filter-cancel-icon">&nbsp;</i></div></div><div style="button-container" ng-click="item.action($event)"><div class="ui-grid-button"><i class="ui-grid-icon-search">&nbsp;</i></div></div></li>'),a.put("ui-grid/uiGridColumnMenu",'<div class="ui-grid-column-menu"><div ui-grid-menu menu-items="menuItems"><!-- <div class="ui-grid-column-menu">\n    <div class="inner" ng-show="menuShown">\n      <ul>\n        <div ng-show="grid.options.enableSorting">\n          <li ng-click="sortColumn($event, asc)" ng-class="{ \'selected\' : col.sort.direction == asc }"><i class="ui-grid-icon-sort-alt-up"></i> Sort Ascending</li>\n          <li ng-click="sortColumn($event, desc)" ng-class="{ \'selected\' : col.sort.direction == desc }"><i class="ui-grid-icon-sort-alt-down"></i> Sort Descending</li>\n          <li ng-show="col.sort.direction" ng-click="unsortColumn()"><i class="ui-grid-icon-cancel"></i> Remove Sort</li>\n        </div>\n      </ul>\n    </div>\n  </div> --></div></div>'),a.put("ui-grid/uiGridFooterCell",'<div class="ui-grid-cell-contents" col-index="renderIndex"><div>{{ col.getAggregationValue() }}</div></div>'),a.put("ui-grid/uiGridHeaderCell",'<div ng-class="{ \'sortable\': sortable }"><div class="ui-grid-vertical-bar">&nbsp;</div><div class="ui-grid-cell-contents" col-index="renderIndex">{{ col.displayName CUSTOM_FILTERS }} <span ui-grid-visible="col.sort.direction" ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }">&nbsp;</span></div><div ng-if="grid.options.enableColumnMenu && !col.isRowHeader" class="ui-grid-column-menu-button" ng-click="toggleMenu($event)"><i class="ui-grid-icon-angle-down">&nbsp;<i></i></i></div><div ng-if="filterable" class="ui-grid-filter-container" ng-repeat="colFilter in col.filters"><input type="text" class="ui-grid-filter-input" ng-model="colFilter.term" ng-click="$event.stopPropagation()" ng-attr-placeholder="{{colFilter.placeholder || \'\'}}"><div class="ui-grid-filter-button" ng-click="colFilter.term = null"><i class="ui-grid-icon-cancel right" ng-show="!!colFilter.term">&nbsp;</i> <!-- use !! because angular interprets \'f\' as false --></div></div></div>'),a.put("ui-grid/uiGridMenu",'<div class="ui-grid-menu"><div class="ui-grid-menu-inner" ng-show="shown"><ul class="ui-grid-menu-items"><li ng-repeat="item in menuItems" ui-grid-menu-item action="item.action" title="item.title" active="item.active" icon="item.icon" shown="item.shown" context="item.context" template-url="item.templateUrl"></li></ul></div></div>'),a.put("ui-grid/uiGridMenuItem",'<li class="ui-grid-menu-item" ng-click="itemAction($event, title)" ng-show="itemShown()" ng-class="{ \'ui-grid-menu-item-active\' : active() }"><i ng-class="icon"></i> {{ title }}</li>'),a.put("ui-grid/uiGridRenderContainer",'<div class="ui-grid-render-container"><div ui-grid-header></div><div ui-grid-viewport></div><div ui-grid-footer ng-if="grid.options.showFooter"></div><!-- native scrolling --><div ui-grid-native-scrollbar ng-if="enableScrollbars" type="vertical"></div><div ui-grid-native-scrollbar ng-if="enableScrollbars" type="horizontal"></div></div>'),a.put("ui-grid/uiGridViewport",'<div class="ui-grid-viewport"><div class="ui-grid-canvas"><div ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by row.uid" class="ui-grid-row" ng-style="containerCtrl.rowStyle(rowRenderIndex)"><div ui-grid-row="row" row-render-index="rowRenderIndex"></div></div></div></div>'),a.put("ui-grid/cellEditor",'<div><form name="inputForm"><input type="{{inputType}}" ng-class="\'colt\' + col.index" ui-grid-editor ng-model="COL_FIELD"></form></div>'),a.put("ui-grid/dropdownEditor",'<div><form name="inputForm"><select ng-class="\'colt\' + col.index" ui-grid-edit-dropdown ng-model="COL_FIELD" ng-options="field[editDropdownIdLabel] as field[editDropdownValueLabel] CUSTOM_FILTERS for field in editDropdownOptionsArray"></select></form></div>'),a.put("ui-grid/expandableRow",'<div ui-grid-expandable-row ng-if="expandableRow.shouldRenderExpand()" class="expandableRow" style="float:left;margin-top: 1px;margin-bottom: 1px" ng-style="{width: (grid.renderContainers.body.getCanvasWidth() - grid.verticalScrollbarWidth)\n     ,height: grid.options.expandable.expandableRowHeight}"></div>'),a.put("ui-grid/expandableRowHeader",'<div class="ui-grid-row-header-cell uiGridExpandableButtonsCell"><div class="ui-grid-cell-contents"><i ng-class="{\'ui-grid-icon-plus-squared\':!row.isExpanded, \'ui-grid-icon-minus-squared\':row.isExpanded}" ng-click="grid.api.expandable.toggleRowExpansion(row.entity)"></i></div></div>'),a.put("ui-grid/expandableScrollFiller",'<div ng-if="expandableRow.shouldRenderFiller()" style="float:left;margin-top: 2px;margin-bottom: 2px" ng-style="{width: (grid.getViewportWidth())\n     ,height: grid.options.expandable.expandableRowHeight, \'margin-left\': grid.options.rowHeader.rowHeaderWidth}"><i class="ui-grid-icon-spin5 ui-grid-animate-spin" ng-style="{\'margin-top\': ( grid.options.expandable.expandableRowHeight/2 - 5),\n            \'margin-left\':((grid.getViewportWidth() - grid.options.rowHeader.rowHeaderWidth)/2 - 5)}"></i></div>'),a.put("ui-grid/csvLink",'<span class="ui-grid-exporter-csv-link-span"><a href="data:text/csv;charset=UTF-8,CSV_CONTENT">LINK_LABEL</a></span>'),a.put("ui-grid/columnResizer",'<div ui-grid-column-resizer ng-if="grid.options.enableColumnResizing" class="ui-grid-column-resizer" col="col" position="right" render-index="renderIndex"></div>'),a.put("ui-grid/selectionRowHeader",'<div class="ui-grid-row-header-cell ui-grid-disable-selection"><div class="ui-grid-cell-contents"><ui-grid-selection-row-header-buttons></ui-grid-selection-row-header-buttons></div></div>'),a.put("ui-grid/selectionRowHeaderButtons",'<div class="ui-grid-selection-row-header-buttons ui-grid-icon-ok" ng-class="{\'ui-grid-row-selected\': row.isSelected}" ng-click="selectButtonClick(row, $event)">&nbsp;</div>')
+}]);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.js
new file mode 100644 (file)
index 0000000..6bec936
--- /dev/null
@@ -0,0 +1,18014 @@
+/*! ui-grid - v3.0.0-rc.16-234dd76 - 2014-11-22
+* Copyright (c) 2014 ; License: MIT */
+(function () {
+  'use strict';
+  angular.module('ui.grid.i18n', []);
+  angular.module('ui.grid', ['ui.grid.i18n']);
+})();
+(function () {
+  'use strict';
+  angular.module('ui.grid').constant('uiGridConstants', {
+    LOG_DEBUG_MESSAGES: true,
+    LOG_WARN_MESSAGES: true,
+    LOG_ERROR_MESSAGES: true,
+    CUSTOM_FILTERS: /CUSTOM_FILTERS/g,
+    COL_FIELD: /COL_FIELD/g,
+    MODEL_COL_FIELD: /MODEL_COL_FIELD/g,
+    DISPLAY_CELL_TEMPLATE: /DISPLAY_CELL_TEMPLATE/g,
+    TEMPLATE_REGEXP: /<.+>/,
+    FUNC_REGEXP: /(\([^)]*\))?$/,
+    DOT_REGEXP: /\./g,
+    APOS_REGEXP: /'/g,
+    BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,
+    COL_CLASS_PREFIX: 'ui-grid-col',
+    events: {
+      GRID_SCROLL: 'uiGridScroll',
+      COLUMN_MENU_SHOWN: 'uiGridColMenuShown',
+      ITEM_DRAGGING: 'uiGridItemDragStart' // For any item being dragged
+    },
+    // copied from http://www.lsauer.com/2011/08/javascript-keymap-keycodes-in-json.html
+    keymap: {
+      TAB: 9,
+      STRG: 17,
+      CTRL: 17,
+      CTRLRIGHT: 18,
+      CTRLR: 18,
+      SHIFT: 16,
+      RETURN: 13,
+      ENTER: 13,
+      BACKSPACE: 8,
+      BCKSP: 8,
+      ALT: 18,
+      ALTR: 17,
+      ALTRIGHT: 17,
+      SPACE: 32,
+      WIN: 91,
+      MAC: 91,
+      FN: null,
+      UP: 38,
+      DOWN: 40,
+      LEFT: 37,
+      RIGHT: 39,
+      ESC: 27,
+      DEL: 46,
+      F1: 112,
+      F2: 113,
+      F3: 114,
+      F4: 115,
+      F5: 116,
+      F6: 117,
+      F7: 118,
+      F8: 119,
+      F9: 120,
+      F10: 121,
+      F11: 122,
+      F12: 123
+    },
+    ASC: 'asc',
+    DESC: 'desc',
+    filter: {
+      STARTS_WITH: 2,
+      ENDS_WITH: 4,
+      EXACT: 8,
+      CONTAINS: 16,
+      GREATER_THAN: 32,
+      GREATER_THAN_OR_EQUAL: 64,
+      LESS_THAN: 128,
+      LESS_THAN_OR_EQUAL: 256,
+      NOT_EQUAL: 512
+    },
+
+    aggregationTypes: {
+      sum: 2,
+      count: 4,
+      avg: 8,
+      min: 16,
+      max: 32
+    },
+
+    // TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them?
+    CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', '฿', '₫'],
+    
+    dataChange: {
+      ALL: 'all',
+      EDIT: 'edit',
+      ROW: 'row',
+      COLUMN: 'column'
+    },
+    scrollbars: {
+      NEVER: 0,
+      ALWAYS: 1,
+      WHEN_NEEDED: 2
+    }
+  });
+
+})();
+angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUtil', 'uiGridConstants', function ($compile, $parse, gridUtil, uiGridConstants) {
+  var uiGridCell = {
+    priority: 0,
+    scope: false,
+    require: '?^uiGrid',
+    compile: function() {
+      return {
+        pre: function($scope, $elm, $attrs, uiGridCtrl) {
+          function compileTemplate() {
+            var compiledElementFn = $scope.col.compiledElementFn;
+
+            compiledElementFn($scope, function(clonedElement, scope) {
+              $elm.append(clonedElement);
+            });
+          }
+
+          // If the grid controller is present, use it to get the compiled cell template function
+          if (uiGridCtrl && $scope.col.compiledElementFn) {
+             compileTemplate();
+          }
+          // No controller, compile the element manually (for unit tests)
+          else {
+            if ( uiGridCtrl && !$scope.col.compiledElementFn ){
+              // gridUtil.logError('Render has been called before precompile.  Please log a ui-grid issue');  
+
+              $scope.col.getCompiledElementFn()
+                .then(function (compiledElementFn) {
+                  compiledElementFn($scope, function(clonedElement, scope) {
+                    $elm.append(clonedElement);
+                  });
+                });
+            }
+            else {
+              var html = $scope.col.cellTemplate
+                .replace(uiGridConstants.MODEL_COL_FIELD, 'row.entity.' + gridUtil.preEval($scope.col.field))
+                .replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)');
+
+              var cellElement = $compile(html)($scope);
+              $elm.append(cellElement);
+            }
+          }
+        },
+        post: function($scope, $elm, $attrs, uiGridCtrl) {
+          $elm.addClass($scope.col.getColClass(false));
+
+          var classAdded;
+          var updateClass = function( grid ){
+            var contents = $elm;
+            if ( classAdded ){
+              contents.removeClass( classAdded );
+              classAdded = null;
+            }
+
+            if (angular.isFunction($scope.col.cellClass)) {
+              classAdded = $scope.col.cellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
+            }
+            else {
+              classAdded = $scope.col.cellClass;
+            }
+            contents.addClass(classAdded);
+          };
+
+          if ($scope.col.cellClass) {
+            updateClass();
+          }
+          
+          // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs
+          var watchUid = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN, uiGridConstants.dataChange.EDIT]);
+          
+          var deregisterFunction = function() {
+           $scope.grid.deregisterDataChangeCallback( watchUid ); 
+          };
+          
+          $scope.$on( '$destroy', deregisterFunction );
+        }
+      };
+    }
+  };
+
+  return uiGridCell;
+}]);
+
+
+(function(){
+
+angular.module('ui.grid')
+.service('uiGridColumnMenuService', [ 'i18nService', 'uiGridConstants', 'gridUtil', 
+function ( i18nService, uiGridConstants, gridUtil ) {
+/**
+ *  @ngdoc service
+ *  @name ui.grid.service:uiGridColumnMenuService
+ *
+ *  @description Services for working with column menus, factored out
+ *  to make the code easier to understand
+ */
+
+  var service = {
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name initialize
+     * @description  Sets defaults, puts a reference to the $scope on 
+     * the uiGridController
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * @param {controller} uiGridCtrl the uiGridController for the grid
+     * we're on
+     * 
+     */
+    initialize: function( $scope, uiGridCtrl ){
+      $scope.grid = uiGridCtrl.grid;
+
+      // Store a reference to this link/controller in the main uiGrid controller
+      // to allow showMenu later
+      uiGridCtrl.columnMenuScope = $scope;
+      
+      // Save whether we're shown or not so the columns can check
+      $scope.menuShown = false;
+    },
+    
+    
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name setColMenuItemWatch
+     * @description  Setup a watch on $scope.col.menuItems, and update
+     * menuItems based on this.  $scope.col needs to be set by the column
+     * before calling the menu.
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * @param {controller} uiGridCtrl the uiGridController for the grid
+     * we're on
+     * 
+     */    
+    setColMenuItemWatch: function ( $scope ){
+      var deregFunction = $scope.$watch('col.menuItems', function (n, o) {
+        if (typeof(n) !== 'undefined' && n && angular.isArray(n)) {
+          n.forEach(function (item) {
+            if (typeof(item.context) === 'undefined' || !item.context) {
+              item.context = {};
+            }
+            item.context.col = $scope.col;
+          });
+
+          $scope.menuItems = $scope.defaultMenuItems.concat(n);
+        }
+        else {
+          $scope.menuItems = $scope.defaultMenuItems;
+        }
+      }); 
+      
+      $scope.$on( '$destroy', deregFunction );     
+    },
+
+
+    /**
+     * @ngdoc boolean
+     * @name enableSorting
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description (optional) True by default. When enabled, this setting adds sort
+     * widgets to the column header, allowing sorting of the data in the individual column.
+     */
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name sortable
+     * @description  determines whether this column is sortable
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * 
+     */    
+    sortable: function( $scope ) {
+      if ( $scope.grid.options.enableSorting && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableSorting) {
+        return true;
+      }
+      else {
+        return false;
+      }
+    },
+    
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name isActiveSort
+     * @description  determines whether the requested sort direction is current active, to 
+     * allow highlighting in the menu
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * @param {string} direction the direction that we'd have selected for us to be active
+     * 
+     */  
+    isActiveSort: function( $scope, direction ){
+      return (typeof($scope.col) !== 'undefined' && typeof($scope.col.sort) !== 'undefined' && 
+              typeof($scope.col.sort.direction) !== 'undefined' && $scope.col.sort.direction === direction);
+      
+    },
+    
+    /**
+     * @ngdoc boolean
+     * @name suppressRemoveSort
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description (optional) False by default. When enabled, this setting hides the removeSort option
+     * in the menu.
+     */
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name suppressRemoveSort
+     * @description  determines whether we should suppress the removeSort option
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * 
+     */  
+    suppressRemoveSort: function( $scope ) {
+      if ($scope.col && $scope.col.colDef && $scope.col.colDef.suppressRemoveSort) {
+        return true;
+      }
+      else {
+        return false;
+      }
+    },       
+
+
+    /**
+     * @ngdoc boolean
+     * @name enableHiding
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description (optional) True by default. When set to false, this setting prevents a user from hiding the column
+     * using the column menu or the grid menu.
+     */
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name hideable
+     * @description  determines whether a column can be hidden, by checking the enableHiding columnDef option
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * 
+     */  
+    hideable: function( $scope ) {
+      if (typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.colDef && $scope.col.colDef.enableHiding === false ) {
+        return false;
+      }
+      else {
+        return true;
+      }
+    },     
+
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name getDefaultMenuItems
+     * @description  returns the default menu items for a column menu
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * 
+     */     
+    getDefaultMenuItems: function( $scope ){
+      return [
+        {
+          title: i18nService.getSafeText('sort.ascending'),
+          icon: 'ui-grid-icon-sort-alt-up',
+          action: function($event) {
+            $event.stopPropagation();
+            $scope.sortColumn($event, uiGridConstants.ASC);
+          },
+          shown: function () {
+            return service.sortable( $scope );
+          },
+          active: function() {
+            return service.isActiveSort( $scope, uiGridConstants.ASC);
+          }
+        },
+        {
+          title: i18nService.getSafeText('sort.descending'),
+          icon: 'ui-grid-icon-sort-alt-down',
+          action: function($event) {
+            $event.stopPropagation();
+            $scope.sortColumn($event, uiGridConstants.DESC);
+          },
+          shown: function() {
+            return service.sortable( $scope );
+          },
+          active: function() {
+            return service.isActiveSort( $scope, uiGridConstants.DESC);
+          }
+        },
+        {
+          title: i18nService.getSafeText('sort.remove'),
+          icon: 'ui-grid-icon-cancel',
+          action: function ($event) {
+            $event.stopPropagation();
+            $scope.unsortColumn();
+          },
+          shown: function() {
+            return service.sortable( $scope ) && 
+                   typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' && 
+                   typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null &&
+                  !service.suppressRemoveSort( $scope );
+          }
+        },
+        {
+          title: i18nService.getSafeText('column.hide'),
+          icon: 'ui-grid-icon-cancel',
+          shown: function() {
+            return service.hideable( $scope );
+          },
+          action: function ($event) {
+            $event.stopPropagation();
+            $scope.hideColumn();
+          }
+        }
+      ];
+    },
+    
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name getColumnElementPosition
+     * @description  gets the position information needed to place the column
+     * menu below the column header
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * @param {GridCol} column the column we want to position below
+     * @param {element} $columnElement the column element we want to position below
+     * @returns {hash} containing left, top, offset, height, width
+     * 
+     */  
+    getColumnElementPosition: function( $scope, column, $columnElement ){
+      var positionData = {};
+      positionData.left = $columnElement[0].offsetLeft;
+      positionData.top = $columnElement[0].offsetTop;
+
+      // Get the grid scrollLeft
+      positionData.offset = 0;
+      if (column.grid.options.offsetLeft) {
+        positionData.offset = column.grid.options.offsetLeft;
+      }
+
+      positionData.height = gridUtil.elementHeight($columnElement, true);
+      positionData.width = gridUtil.elementWidth($columnElement, true);
+      
+      return positionData;
+    },
+    
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:uiGridColumnMenuService
+     * @name repositionMenu
+     * @description  Reposition the menu below the new column.  If the menu has no child nodes 
+     * (i.e. it's not currently visible) then we guess it's width at 100, we'll be called again
+     * later to fix it
+     * @param {$scope} $scope the $scope from the uiGridColumnMenu
+     * @param {GridCol} column the column we want to position below
+     * @param {hash} positionData a hash containing left, top, offset, height, width
+     * @param {element} $elm the column menu element that we want to reposition
+     * @param {element} $columnElement the column element that we want to reposition underneath
+     * 
+     */  
+    repositionMenu: function( $scope, column, positionData, $elm, $columnElement ) {
+      var menu = $elm[0].querySelectorAll('.ui-grid-menu');
+      var containerId = column.renderContainer ? column.renderContainer : 'body';
+      var renderContainer = column.grid.renderContainers[containerId];
+
+      // It's possible that the render container of the column we're attaching to is 
+      // offset from the grid (i.e. pinned containers), we need to get the difference in the offsetLeft 
+      // between the render container and the grid
+      var renderContainerElm = gridUtil.closestElm($columnElement, '.ui-grid-render-container');
+      var renderContainerOffset = renderContainerElm.getBoundingClientRect().left - $scope.grid.element[0].getBoundingClientRect().left;
+
+      var containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft;
+
+      // default value the last width for _this_ column, otherwise last width for _any_ column, otherwise default to 170
+      var myWidth = column.lastMenuWidth ? column.lastMenuWidth : ( $scope.lastMenuWidth ? $scope.lastMenuWidth : 170);
+      var paddingRight = column.lastMenuPaddingRight ? column.lastMenuPaddingRight : ( $scope.lastMenuPaddingRight ? $scope.lastMenuPaddingRight : 10);
+      
+      if ( menu.length !== 0 ){
+        var mid = menu[0].querySelectorAll('.ui-grid-menu-mid'); 
+        if ( mid.length !== 0 && !angular.element(mid).hasClass('ng-hide') ) {
+          myWidth = gridUtil.elementWidth(menu, true);
+          $scope.lastMenuWidth = myWidth;
+          column.lastMenuWidth = myWidth;
+  
+          // TODO(c0bra): use padding-left/padding-right based on document direction (ltr/rtl), place menu on proper side
+          // Get the column menu right padding
+          paddingRight = parseInt(gridUtil.getStyles(angular.element(menu)[0])['paddingRight'], 10);
+          $scope.lastMenuPaddingRight = paddingRight;
+          column.lastMenuPaddingRight = paddingRight;
+        }
+      }
+      
+      var left = positionData.left + renderContainerOffset - containerScrollLeft + positionData.width - myWidth + paddingRight;
+      if (left < positionData.offset){
+        left = positionData.offset;
+      }
+
+      $elm.css('left', left + 'px');
+      $elm.css('top', (positionData.top + positionData.height) + 'px');
+    }    
+
+  };
+  
+  return service;
+}])
+
+
+.directive('uiGridColumnMenu', ['$timeout', 'gridUtil', 'uiGridConstants', 'uiGridColumnMenuService', 
+function ($timeout, gridUtil, uiGridConstants, uiGridColumnMenuService) {
+/**
+ * @ngdoc directive
+ * @name ui.grid.directive:uiGridColumnMenu
+ * @description  Provides the column menu framework, leverages uiGridMenu underneath
+ * 
+ */
+
+  var uiGridColumnMenu = {
+    priority: 0,
+    scope: true,
+    require: '?^uiGrid',
+    templateUrl: 'ui-grid/uiGridColumnMenu',
+    replace: true,
+    link: function ($scope, $elm, $attrs, uiGridCtrl) {
+      var self = this;
+      
+      uiGridColumnMenuService.initialize( $scope, uiGridCtrl );
+
+      $scope.defaultMenuItems = uiGridColumnMenuService.getDefaultMenuItems( $scope );
+
+      // Set the menu items for use with the column menu. The user can later add additional items via the watch
+      $scope.menuItems = $scope.defaultMenuItems;
+      uiGridColumnMenuService.setColMenuItemWatch( $scope );
+
+  
+      /**
+       * @ngdoc method
+       * @methodOf ui.grid.directive:uiGridColumnMenu
+       * @name showMenu
+       * @description Shows the column menu.  If the menu is already displayed it
+       * calls the menu to ask it to hide (it will animate), then it repositions the menu
+       * to the right place whilst hidden (it will make an assumption on menu width), 
+       * then it asks the menu to show (it will animate), then it repositions the menu again 
+       * once we can calculate it's size.
+       * @param {GridCol} column the column we want to position below
+       * @param {element} $columnElement the column element we want to position below
+       */
+      $scope.showMenu = function(column, $columnElement, event) {
+        // Swap to this column
+        $scope.col = column;
+
+        // Get the position information for the column element
+        var colElementPosition = uiGridColumnMenuService.getColumnElementPosition( $scope, column, $columnElement );
+
+        if ($scope.menuShown) {
+          // we want to hide, then reposition, then show, but we want to wait for animations
+          // we set a variable, and then rely on the menu-hidden event to call the reposition and show
+          $scope.colElement = $columnElement;
+          $scope.colElementPosition = colElementPosition;
+          $scope.hideThenShow = true;
+
+          $scope.$broadcast('hide-menu', { originalEvent: event });
+        } else {
+          self.shown = $scope.menuShown = true;
+          uiGridColumnMenuService.repositionMenu( $scope, column, colElementPosition, $elm, $columnElement );
+
+          $scope.colElement = $columnElement;
+          $scope.colElementPosition = colElementPosition;
+          $scope.$broadcast('show-menu', { originalEvent: event });
+        } 
+
+      };
+
+
+      /**
+       * @ngdoc method
+       * @methodOf ui.grid.directive:uiGridColumnMenu
+       * @name hideMenu
+       * @description Hides the column menu.
+       * @param {boolean} broadcastTrigger true if we were triggered by a broadcast
+       * from the menu itself - in which case don't broadcast again as we'll get
+       * an infinite loop
+       */
+      $scope.hideMenu = function( broadcastTrigger ) {
+        // delete $scope.col;
+        $scope.menuShown = false;
+        
+        if ( !broadcastTrigger ){
+          $scope.$broadcast('hide-menu');
+        }
+      };
+
+      
+      $scope.$on('menu-hidden', function() {
+        if ( $scope.hideThenShow ){
+          delete $scope.hideThenShow;
+
+          uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement );
+          $scope.$broadcast('show-menu');
+
+          $scope.menuShown = true;
+        } else {
+          $scope.hideMenu( true );
+        }
+      });
+      
+      $scope.$on('menu-shown', function() {
+        $timeout( function() {
+          uiGridColumnMenuService.repositionMenu( $scope, $scope.col, $scope.colElementPosition, $elm, $scope.colElement );
+          delete $scope.colElementPosition;
+          delete $scope.columnElement;
+        }, 200);
+      });
+
+      /* Column methods */
+      $scope.sortColumn = function (event, dir) {
+        event.stopPropagation();
+
+        $scope.grid.sortColumn($scope.col, dir, true)
+          .then(function () {
+            $scope.grid.refresh();
+            $scope.hideMenu();
+          });
+      };
+
+      $scope.unsortColumn = function () {
+        $scope.col.unsort();
+
+        $scope.grid.refresh();
+        $scope.hideMenu();
+      };
+
+      $scope.hideColumn = function () {
+        $scope.col.colDef.visible = false;
+
+        $scope.grid.refresh();
+        $scope.hideMenu();
+      };
+    },
+    
+    
+    
+    controller: ['$scope', function ($scope) {
+      var self = this;
+      
+      $scope.$watch('menuItems', function (n, o) {
+        self.menuItems = n;
+      });
+    }]
+  };
+
+  return uiGridColumnMenu;
+
+}]);
+
+})();
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridFooterCell', ['$timeout', 'gridUtil', 'uiGridConstants', '$compile',
+  function ($timeout, gridUtil, uiGridConstants, $compile) {
+    var uiGridFooterCell = {
+      priority: 0,
+      scope: {
+        col: '=',
+        row: '=',
+        renderIndex: '='
+      },
+      replace: true,
+      require: '^uiGrid',
+      compile: function compile(tElement, tAttrs, transclude) {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            function compileTemplate(template) {
+              gridUtil.getTemplate(template).then(function (contents) {
+                var linkFunction = $compile(contents);
+                var html = linkFunction($scope);
+                $elm.append(html);
+              });
+            }
+
+            //compile the footer template
+            if ($scope.col.footerCellTemplate) {
+              //compile the custom template
+              compileTemplate($scope.col.footerCellTemplate);
+            }
+            else {
+              //use default template
+              compileTemplate('ui-grid/uiGridFooterCell');
+            }
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            //$elm.addClass($scope.col.getColClass(false));
+            $scope.grid = uiGridCtrl.grid;
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+
+            $elm.addClass($scope.col.getColClass(false));
+
+            // apply any footerCellClass
+            var classAdded;
+            var updateClass = function( grid ){
+              var contents = $elm;
+              if ( classAdded ){
+                contents.removeClass( classAdded );
+                classAdded = null;
+              }
+  
+              if (angular.isFunction($scope.col.footerCellClass)) {
+                classAdded = $scope.col.footerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
+              }
+              else {
+                classAdded = $scope.col.footerCellClass;
+              }
+              contents.addClass(classAdded);
+            };
+  
+            if ($scope.col.footerCellClass) {
+              updateClass();
+            }
+
+            // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs
+            var watchUid = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN]);
+
+            $scope.$on( '$destroy', function() {
+              $scope.grid.deregisterDataChangeCallback( watchUid ); 
+            });
+          }
+        };
+      }
+    };
+
+    return uiGridFooterCell;
+  }]);
+
+})();
+
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridFooter', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function ($templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
+    var defaultTemplate = 'ui-grid/ui-grid-footer';
+
+    return {
+      restrict: 'EA',
+      replace: true,
+      // priority: 1000,
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: true,
+      compile: function ($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+
+            containerCtrl.footer = $elm;
+
+            var footerTemplate = ($scope.grid.options.footerTemplate) ? $scope.grid.options.footerTemplate : defaultTemplate;
+            gridUtil.getTemplate(footerTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+
+                var newElm = $compile(template)($scope);
+                $elm.append(newElm);
+
+                if (containerCtrl) {
+                  // Inject a reference to the footer viewport (if it exists) into the grid controller for use in the horizontal scroll handler below
+                  var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
+
+                  if (footerViewport) {
+                    containerCtrl.footerViewport = footerViewport;
+                  }
+                }
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            // gridUtil.logDebug('ui-grid-footer link');
+
+            var grid = uiGridCtrl.grid;
+
+            // Don't animate footer cells
+            gridUtil.disableAnimations($elm);
+
+            containerCtrl.footer = $elm;
+
+            var footerViewport = $elm[0].getElementsByClassName('ui-grid-footer-viewport')[0];
+            if (footerViewport) {
+              containerCtrl.footerViewport = footerViewport;
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridGroupPanel', ["$compile", "uiGridConstants", "gridUtil", function($compile, uiGridConstants, gridUtil) {
+    var defaultTemplate = 'ui-grid/ui-grid-group-panel';
+
+    return {
+      restrict: 'EA',
+      replace: true,
+      require: '?^uiGrid',
+      scope: false,
+      compile: function($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            var groupPanelTemplate = $scope.grid.options.groupPanelTemplate  || defaultTemplate;
+
+             gridUtil.getTemplate(groupPanelTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+                
+                var newElm = $compile(template)($scope);
+                $elm.append(newElm);
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            $elm.bind('$destroy', function() {
+              // scrollUnbinder();
+            });
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridHeaderCell', ['$compile', '$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 
+  function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants) {
+    // Do stuff after mouse has been down this many ms on the header cell
+    var mousedownTimeout = 500;
+
+    var uiGridHeaderCell = {
+      priority: 0,
+      scope: {
+        col: '=',
+        row: '=',
+        renderIndex: '='
+      },
+      require: ['?^uiGrid', '^uiGridRenderContainer'],
+      replace: true,
+      compile: function() {
+        return {
+          pre: function ($scope, $elm, $attrs) {
+            var cellHeader = $compile($scope.col.headerCellTemplate)($scope);
+            $elm.append(cellHeader);
+          },
+          
+          post: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var renderContainerCtrl = controllers[1];
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+
+            $scope.renderContainer = uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId];
+            
+            $elm.addClass($scope.col.getColClass(false));
+    
+            // Hide the menu by default
+            $scope.menuShown = false;
+    
+            // Put asc and desc sort directions in scope
+            $scope.asc = uiGridConstants.ASC;
+            $scope.desc = uiGridConstants.DESC;
+    
+            // Store a reference to menu element
+            var $colMenu = angular.element( $elm[0].querySelectorAll('.ui-grid-header-cell-menu') );
+    
+            var $contentsElm = angular.element( $elm[0].querySelectorAll('.ui-grid-cell-contents') );
+    
+
+            // apply any headerCellClass
+            var classAdded;
+            var updateClass = function( grid ){
+              var contents = $elm;
+              if ( classAdded ){
+                contents.removeClass( classAdded );
+                classAdded = null;
+              }
+  
+              if (angular.isFunction($scope.col.headerCellClass)) {
+                classAdded = $scope.col.headerCellClass($scope.grid, $scope.row, $scope.col, $scope.rowRenderIndex, $scope.colRenderIndex);
+              }
+              else {
+                classAdded = $scope.col.headerCellClass;
+              }
+              contents.addClass(classAdded);
+            };
+  
+            if ($scope.col.headerCellClass) {
+              updateClass();
+            }
+            
+            // Register a data change watch that would get triggered whenever someone edits a cell or modifies column defs
+            var watchUid = $scope.grid.registerDataChangeCallback( updateClass, [uiGridConstants.dataChange.COLUMN]);
+
+            var deregisterFunction = function() {
+              $scope.grid.deregisterDataChangeCallback( watchUid ); 
+            };
+
+            $scope.$on( '$destroy', deregisterFunction );            
+
+
+            // Figure out whether this column is sortable or not
+            if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) {
+              $scope.sortable = true;
+            }
+            else {
+              $scope.sortable = false;
+            }
+    
+            if (uiGridCtrl.grid.options.enableFiltering && $scope.col.enableFiltering) {
+              $scope.filterable = true;
+            }
+            else {
+              $scope.filterable = false;
+            }
+    
+            function handleClick(evt) {
+              // If the shift key is being held down, add this column to the sort
+              var add = false;
+              if (evt.shiftKey) {
+                add = true;
+              }
+    
+              // Sort this column then rebuild the grid's rows
+              uiGridCtrl.grid.sortColumn($scope.col, add)
+                .then(function () {
+                  if (uiGridCtrl.columnMenuScope) { uiGridCtrl.columnMenuScope.hideMenu(); }
+                  uiGridCtrl.grid.refresh();
+                });
+            }
+    
+            /**
+            * @ngdoc property
+            * @name enableColumnMenu
+            * @propertyOf ui.grid.class:GridOptions.columnDef
+            * @description if column menus are enabled, controls the column menus for this specific
+            * column (i.e. if gridOptions.enableColumnMenus, then you can control column menus
+            * using this option. If gridOptions.enableColumnMenus === false then you get no column
+            * menus irrespective of the value of this option ).  Defaults to true.
+            *
+            */
+            /**
+            * @ngdoc property
+            * @name enableColumnMenus
+            * @propertyOf ui.grid.class:GridOptions.columnDef
+            * @description Override for column menus everywhere - if set to false then you get no
+            * column menus.  Defaults to true.
+            *
+            */
+
+            // Long-click (for mobile)
+            var cancelMousedownTimeout;
+            var mousedownStartTime = 0;
+            $contentsElm.on('mousedown touchstart', function(event) {
+              if (typeof(event.originalEvent) !== 'undefined' && event.originalEvent !== undefined) {
+                event = event.originalEvent;
+              }
+    
+              // Don't show the menu if it's not the left button
+              if (event.button && event.button !== 0) {
+                return;
+              }
+    
+              mousedownStartTime = (new Date()).getTime();
+    
+              cancelMousedownTimeout = $timeout(function() { }, mousedownTimeout);
+    
+              cancelMousedownTimeout.then(function () {
+                if ($scope.col.grid.options && $scope.col.grid.options.enableColumnMenus !== false && 
+                    $scope.col.colDef && $scope.col.colDef.enableColumnMenu !== false) {
+                  uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm, event);
+                }
+              });
+            });
+    
+            $contentsElm.on('mouseup touchend', function () {
+              $timeout.cancel(cancelMousedownTimeout);
+            });
+
+            $scope.$on('$destroy', function () {
+              $contentsElm.off('mousedown touchstart');
+            });
+
+
+            $scope.toggleMenu = function($event) {
+              $event.stopPropagation();
+    
+              // If the menu is already showing...
+              if (uiGridCtrl.columnMenuScope.menuShown) {
+                // ... and we're the column the menu is on...
+                if (uiGridCtrl.columnMenuScope.col === $scope.col) {
+                  // ... hide it
+                  uiGridCtrl.columnMenuScope.hideMenu();
+                }
+                // ... and we're NOT the column the menu is on
+                else {
+                  // ... move the menu to our column
+                  uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
+                }
+              }
+              // If the menu is NOT showing
+              else {
+                // ... show it on our column
+                uiGridCtrl.columnMenuScope.showMenu($scope.col, $elm);
+              }
+            };
+    
+            // If this column is sortable, add a click event handler
+            if ($scope.sortable) {
+              $contentsElm.on('click touchend', function(evt) {
+                evt.stopPropagation();
+    
+                $timeout.cancel(cancelMousedownTimeout);
+    
+                var mousedownEndTime = (new Date()).getTime();
+                var mousedownTime = mousedownEndTime - mousedownStartTime;
+    
+                if (mousedownTime > mousedownTimeout) {
+                  // long click, handled above with mousedown
+                }
+                else {
+                  // short click
+                  handleClick(evt);
+                }
+              });
+    
+              $scope.$on('$destroy', function () {
+                // Cancel any pending long-click timeout
+                $timeout.cancel(cancelMousedownTimeout);
+              });
+            }
+    
+            if ($scope.filterable) {
+              var filterDeregisters = [];
+              angular.forEach($scope.col.filters, function(filter, i) {
+                filterDeregisters.push($scope.$watch('col.filters[' + i + '].term', function(n, o) {
+                  if (n !== o) {
+                    uiGridCtrl.grid.api.core.raise.filterChanged();
+                    uiGridCtrl.grid.refresh()
+                      .then(function () {
+                        if (uiGridCtrl.prevScrollArgs && uiGridCtrl.prevScrollArgs.y && uiGridCtrl.prevScrollArgs.y.percentage) {
+                           uiGridCtrl.fireScrollingEvent({ y: { percentage: uiGridCtrl.prevScrollArgs.y.percentage } });
+                        }
+                        // uiGridCtrl.fireEvent('force-vertical-scroll');
+                      });
+                  }
+                }));  
+              });
+              $scope.$on('$destroy', function() {
+                angular.forEach(filterDeregisters, function(filterDeregister) {
+                  filterDeregister();
+                });
+              });
+            }
+          }
+        };
+      }
+    };
+
+    return uiGridHeaderCell;
+  }]);
+
+})();
+
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridHeader', ['$templateCache', '$compile', 'uiGridConstants', 'gridUtil', '$timeout', function($templateCache, $compile, uiGridConstants, gridUtil, $timeout) {
+    var defaultTemplate = 'ui-grid/ui-grid-header';
+    var emptyTemplate = 'ui-grid/ui-grid-no-header';
+
+    return {
+      restrict: 'EA',
+      // templateUrl: 'ui-grid/ui-grid-header',
+      replace: true,
+      // priority: 1000,
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: true,
+      compile: function($elm, $attrs) {
+        return {
+          pre: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+
+            containerCtrl.header = $elm;
+            containerCtrl.colContainer.header = $elm;
+
+            /**
+             * @ngdoc property
+             * @name hideHeader
+             * @propertyOf ui.grid.class:GridOptions
+             * @description Null by default. When set to true, this setting will replace the
+             * standard header template with '<div></div>', resulting in no header being shown.
+             */
+            
+            var headerTemplate;
+            if ($scope.grid.options.hideHeader){
+              headerTemplate = emptyTemplate;
+            } else {
+              headerTemplate = ($scope.grid.options.headerTemplate) ? $scope.grid.options.headerTemplate : defaultTemplate;            
+            }
+
+             gridUtil.getTemplate(headerTemplate)
+              .then(function (contents) {
+                var template = angular.element(contents);
+                
+                var newElm = $compile(template)($scope);
+                $elm.replaceWith(newElm);
+
+                // Replace the reference to the container's header element with this new element
+                containerCtrl.header = newElm;
+                containerCtrl.colContainer.header = newElm;
+
+                // And update $elm to be the new element
+                $elm = newElm;
+
+                if (containerCtrl) {
+                  // Inject a reference to the header viewport (if it exists) into the grid controller for use in the horizontal scroll handler below
+                  var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
+
+                  if (headerViewport) {
+                    containerCtrl.headerViewport = headerViewport;
+                  }
+                }
+              });
+          },
+
+          post: function ($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            // gridUtil.logDebug('ui-grid-header link');
+
+            var grid = uiGridCtrl.grid;
+
+            // Don't animate header cells
+            gridUtil.disableAnimations($elm);
+
+            function updateColumnWidths() {
+              // Get the width of the viewport
+              var availableWidth = containerCtrl.colContainer.getViewportWidth();
+
+              if (typeof(uiGridCtrl.grid.verticalScrollbarWidth) !== 'undefined' && uiGridCtrl.grid.verticalScrollbarWidth !== undefined && uiGridCtrl.grid.verticalScrollbarWidth > 0) {
+                availableWidth = availableWidth + uiGridCtrl.grid.verticalScrollbarWidth;
+              }
+
+              // The total number of columns
+              // var equalWidthColumnCount = columnCount = uiGridCtrl.grid.options.columnDefs.length;
+              // var equalWidth = availableWidth / equalWidthColumnCount;
+
+              var columnCache = containerCtrl.colContainer.visibleColumnCache,
+                  canvasWidth = 0,
+                  asteriskNum = 0,
+                  oneAsterisk = 0,
+                  leftoverWidth = availableWidth,
+                  hasVariableWidth = false;
+              
+              var getColWidth = function(column){
+                if (column.widthType === "manual"){ 
+                  return +column.width; 
+                }
+                else if (column.widthType === "percent"){ 
+                  return parseInt(column.width.replace(/%/g, ''), 10) * availableWidth / 100;
+                }
+                else if (column.widthType === "auto"){
+                  // leftOverWidth is subtracted from after each call to this
+                  // function so we need to calculate oneAsterisk size only once
+                  if (oneAsterisk === 0) {
+                    oneAsterisk = parseInt(leftoverWidth / asteriskNum, 10);
+                  }
+                  return column.width.length * oneAsterisk; 
+                }
+              };
+              
+              // Populate / determine column width types:
+              columnCache.forEach(function(column){
+                column.widthType = null;
+                if (isFinite(+column.width)){
+                  column.widthType = "manual";
+                }
+                else if (gridUtil.endsWith(column.width, "%")){
+                  column.widthType = "percent";
+                  hasVariableWidth = true;
+                }
+                else if (angular.isString(column.width) && column.width.indexOf('*') !== -1){
+                  column.widthType = "auto";
+                  asteriskNum += column.width.length;
+                  hasVariableWidth = true;
+                }
+              });
+              
+              // For sorting, calculate width from first to last:
+              var colWidthPriority = ["manual", "percent", "auto"];
+              columnCache.filter(function(column){
+                // Only draw visible items with a widthType
+                return (column.visible && column.widthType); 
+              }).sort(function(a,b){
+                // Calculate widths in order, so that manual comes first, etc.
+                return colWidthPriority.indexOf(a.widthType) - colWidthPriority.indexOf(b.widthType);
+              }).forEach(function(column){
+                // Calculate widths:
+                var colWidth = getColWidth(column);
+                if (column.minWidth){
+                  colWidth = Math.max(colWidth, column.minWidth);
+                }
+                if (column.maxWidth){
+                  colWidth = Math.min(colWidth, column.maxWidth);
+                }
+                column.drawnWidth = Math.floor(colWidth);
+                canvasWidth += column.drawnWidth;
+                leftoverWidth -= column.drawnWidth;
+              });
+
+              // If the grid width didn't divide evenly into the column widths and we have pixels left over, dole them out to the columns one by one to make everything fit
+              if (hasVariableWidth && leftoverWidth > 0 && canvasWidth > 0 && canvasWidth < availableWidth) {
+                var remFn = function (column) {
+                  if (leftoverWidth > 0 && (column.widthType === "auto" || column.widthType === "percent")) {
+                    column.drawnWidth = column.drawnWidth + 1;
+                    canvasWidth = canvasWidth + 1;
+                    leftoverWidth--;
+                  }
+                };
+                var prevLeftover = 0;
+                do {
+                  prevLeftover = leftoverWidth;
+                  columnCache.forEach(remFn);
+                } while (leftoverWidth > 0 && leftoverWidth !== prevLeftover );
+              }
+              canvasWidth = Math.max(canvasWidth, availableWidth);
+
+              // Build the CSS
+              // uiGridCtrl.grid.columns.forEach(function (column) {
+              var ret = '';
+              columnCache.forEach(function (column) {
+                ret = ret + column.getColClassDefinition();
+              });
+
+              // Add the vertical scrollbar width back in to the canvas width, it's taken out in getViewportWidth
+              if (grid.verticalScrollbarWidth) {
+                canvasWidth = canvasWidth + grid.verticalScrollbarWidth;
+              }
+              // canvasWidth = canvasWidth + 1;
+
+              // if we have a grid menu, then we prune the width of the last column header
+              // to allow room for the button whilst still getting to the column menu
+              if (columnCache.length > 0) { // && grid.options.enableGridMenu) {
+                columnCache[columnCache.length - 1].headerWidth = columnCache[columnCache.length - 1].drawnWidth - 30;
+              }
+
+              containerCtrl.colContainer.canvasWidth = parseInt(canvasWidth, 10);
+
+              // Return the styles back to buildStyles which pops them into the `customStyles` scope variable
+              return ret;
+            }
+            
+            containerCtrl.header = $elm;
+            
+            var headerViewport = $elm[0].getElementsByClassName('ui-grid-header-viewport')[0];
+            if (headerViewport) {
+              containerCtrl.headerViewport = headerViewport;
+            }
+
+            //todo: remove this if by injecting gridCtrl into unit tests
+            if (uiGridCtrl) {
+              uiGridCtrl.grid.registerStyleComputation({
+                priority: 5,
+                func: updateColumnWidths
+              });
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+.service('uiGridGridMenuService', [ 'gridUtil', 'i18nService', function( gridUtil, i18nService ) {
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.gridMenuService
+   *
+   *  @description Methods for working with the grid menu
+   */
+
+  var service = {
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.gridMenuService
+     * @name initialize
+     * @description Sets up the gridMenu. Most importantly, sets our
+     * scope onto the grid object as grid.gridMenuScope, allowing us
+     * to operate when passed only the grid.  Second most importantly, 
+     * we register the 'addToGridMenu' and 'removeFromGridMenu' methods
+     * on the core api.
+     * @param {$scope} $scope the scope of this gridMenu
+     * @param {Grid} grid the grid to which this gridMenu is associated
+     */
+    initialize: function( $scope, grid ){
+      grid.gridMenuScope = $scope;
+      $scope.grid = grid;
+      $scope.registeredMenuItems = [];
+      
+      // not certain this is needed, but would be bad to create a memory leak
+      $scope.$on('$destroy', function() {
+        if ( $scope.grid && $scope.grid.gridMenuScope ){
+          $scope.grid.gridMenuScope = null;
+        }
+        if ( $scope.grid ){
+          $scope.grid = null;
+        }
+        if ( $scope.registeredMenuItems ){
+          $scope.registeredMenuItems = null;
+        }
+      });
+      
+      $scope.registeredMenuItems = [];
+
+      /**
+       * @ngdoc function
+       * @name addToGridMenu
+       * @methodOf ui.grid.core.api:PublicApi
+       * @description add items to the grid menu.  Used by features
+       * to add their menu items if they are enabled, can also be used by
+       * end users to add menu items.  This method has the advantage of allowing
+       * remove again, which can simplify management of which items are included
+       * in the menu when.  (Noting that in most cases the shown and active functions
+       * provide a better way to handle visibility of menu items)
+       * @param {Grid} grid the grid on which we are acting
+       * @param {array} items menu items in the format as described in the tutorial, with 
+       * the added note that if you want to use remove you must also specify an `id` field,
+       * which is provided when you want to remove an item.  The id should be unique.
+       * 
+       */
+      grid.api.registerMethod( 'core', 'addToGridMenu', service.addToGridMenu );
+  
+      /**
+       * @ngdoc function
+       * @name removeFromGridMenu
+       * @methodOf ui.grid.core.api:PublicApi
+       * @description Remove an item from the grid menu based on a provided id. Assumes
+       * that the id is unique, removes only the last instance of that id. Does nothing if
+       * the specified id is not found
+       * @param {Grid} grid the grid on which we are acting
+       * @param {string} id the id we'd like to remove from the menu
+       * 
+       */
+      grid.api.registerMethod( 'core', 'removeFromGridMenu', service.removeFromGridMenu );
+    },
+    
+    /**
+     * @ngdoc function
+     * @name addToGridMenu
+     * @propertyOf ui.grid.class:GridOptions
+     * @description add items to the grid menu.  Used by features
+     * to add their menu items if they are enabled, can also be used by
+     * end users to add menu items.  This method has the advantage of allowing
+     * remove again, which can simplify management of which items are included
+     * in the menu when.  (Noting that in most cases the shown and active functions
+     * provide a better way to handle visibility of menu items)
+     * @param {Grid} grid the grid on which we are acting
+     * @param {array} items menu items in the format as described in the tutorial, with 
+     * the added note that if you want to use remove you must also specify an `id` field,
+     * which is provided when you want to remove an item.  The id should be unique.
+     * 
+     */
+    addToGridMenu: function( grid, menuItems ) {
+      if ( !angular.isArray( menuItems ) ) {
+        gridUtil.logError( 'addToGridMenu: menuItems must be an array, and is not, not adding any items');
+      } else {
+        if ( grid.gridMenuScope ){
+          grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems ? grid.gridMenuScope.registeredMenuItems : [];
+          grid.gridMenuScope.registeredMenuItems = grid.gridMenuScope.registeredMenuItems.concat( menuItems );
+        } else {
+          gridUtil.logError( 'Asked to addToGridMenu, but gridMenuScope not present.  Timing issue?  Please log issue with ui-grid');
+        }
+      }  
+    },
+    
+
+    /**
+     * @ngdoc function
+     * @name removeFromGridMenu
+     * @methodOf ui.grid.core.api:PublicApi
+     * @description Remove an item from the grid menu based on a provided id.  Assumes
+     * that the id is unique, removes only the last instance of that id.  Does nothing if
+     * the specified id is not found.  If there is no gridMenuScope or registeredMenuItems
+     * then do nothing silently - the desired result is those menu items not be present and they
+     * aren't.
+     * @param {Grid} grid the grid on which we are acting
+     * @param {string} id the id we'd like to remove from the menu
+     * 
+     */    
+    removeFromGridMenu: function( grid, id ){
+      var foundIndex = -1;
+      
+      if ( grid && grid.gridMenuScope ){
+        grid.gridMenuScope.registeredMenuItems.forEach( function( value, index ) {
+          if ( value.id === id ){
+            if (foundIndex > -1) {
+              gridUtil.logError( 'removeFromGridMenu: found multiple items with the same id, removing only the last' );
+            } else {
+              
+              foundIndex = index;
+            }
+          }
+        });
+      }
+
+      if ( foundIndex > -1 ){
+        grid.gridMenuScope.registeredMenuItems.splice( foundIndex, 1 );
+      }
+    },
+    
+        
+    /**
+     * @ngdoc array
+     * @name gridMenuCustomItems
+     * @propertyOf ui.grid.class:GridOptions
+     * @description (optional) An array of menu items that should be added to
+     * the gridMenu.  Follow the format documented in the tutorial for column
+     * menu customisation.  The context provided to the action function will 
+     * include context.grid.  An alternative if working with dynamic menus is to use the 
+     * provided api - core.addToGridMenu and core.removeFromGridMenu, which handles
+     * some of the management of items for you.
+     * 
+     */
+    /**
+     * @ngdoc boolean
+     * @name gridMenuShowHideColumns
+     * @propertyOf ui.grid.class:GridOptions
+     * @description true by default, whether the grid menu should allow hide/show
+     * of columns
+     * 
+     */
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.gridMenuService
+     * @name getMenuItems
+     * @description Decides the menu items to show in the menu.  This is a
+     * combination of:
+     * 
+     * - the default menu items that are always included, 
+     * - any menu items that have been provided through the addMenuItem api. These
+     *   are typically added by features within the grid
+     * - any menu items included in grid.options.gridMenuCustomItems.  These can be
+     *   changed dynamically, as they're always recalculated whenever we show the
+     *   menu
+     * @param {$scope} $scope the scope of this gridMenu, from which we can find all 
+     * the information that we need
+     * @returns {array} an array of menu items that can be shown 
+     */
+    getMenuItems: function( $scope ) {
+      var menuItems = [
+        // this is where we add any menu items we want to always include
+      ];
+      
+      if ( $scope.grid.options.gridMenuCustomItems ){
+        if ( !angular.isArray( $scope.grid.options.gridMenuCustomItems ) ){ 
+          gridUtil.logError( 'gridOptions.gridMenuCustomItems must be an array, and is not'); 
+        } else {
+          menuItems = menuItems.concat( $scope.grid.options.gridMenuCustomItems );
+        }
+      }
+  
+      menuItems = menuItems.concat( $scope.registeredMenuItems );
+      
+      if ( $scope.grid.options.gridMenuShowHideColumns !== false ){
+        menuItems = menuItems.concat( service.showHideColumns( $scope ) );
+      }
+      
+      return menuItems;
+    },
+    
+    
+    /**
+     * @ngdoc array
+     * @name gridMenuTitleFilter
+     * @propertyOf ui.grid.class:GridOptions
+     * @description (optional) A function that takes a title string 
+     * (usually the col.displayName), and converts it into a display value.  The function
+     * must return either a string or a promise.
+     * 
+     * Used for internationalization of the grid menu column names - for angular-translate
+     * you can pass $translate as the function, for i18nService you can pass getSafeText as the 
+     * function
+     * @example
+     * <pre>
+     *   gridOptions = {
+     *     gridMenuTitleFilter: $translate
+     *   }
+     * </pre>
+     */
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.gridMenuService
+     * @name showHideColumns
+     * @description Adds two menu items for each of the columns in columnDefs.  One
+     * menu item for hide, one menu item for show.  Each is visible when appropriate
+     * (show when column is not visible, hide when column is visible).  Each toggles
+     * the visible property on the columnDef using toggleColumnVisibility
+     * @param {$scope} $scope of a gridMenu, which contains a reference to the grid
+     */
+    showHideColumns: function( $scope ){
+      var showHideColumns = [];
+      if ( !$scope.grid.options.columnDefs || $scope.grid.options.columnDefs.length === 0 || $scope.grid.columns.length === 0 ) {
+        return showHideColumns;
+      }
+      
+      // add header for columns
+      showHideColumns.push({
+        title: i18nService.getSafeText('gridMenu.columns')
+      });
+      
+      $scope.grid.options.gridMenuTitleFilter = $scope.grid.options.gridMenuTitleFilter ? $scope.grid.options.gridMenuTitleFilter : function( title ) { return title; };  
+      
+      $scope.grid.options.columnDefs.forEach( function( colDef, index ){
+        if ( colDef.enableHiding !== false ){
+          // add hide menu item - shows an OK icon as we only show when column is already visible
+          var menuItem = {
+            icon: 'ui-grid-icon-ok',
+            action: function($event) {
+              $event.stopPropagation();
+              service.toggleColumnVisibility( this.context.gridCol );
+            },
+            shown: function() {
+              return this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined;
+            },
+            context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }
+          };
+          service.setMenuItemTitle( menuItem, colDef, $scope.grid );
+          showHideColumns.push( menuItem );
+
+          // add show menu item - shows no icon as we only show when column is invisible
+          menuItem = {
+            icon: 'ui-grid-icon-cancel',
+            action: function($event) {
+              $event.stopPropagation();
+              service.toggleColumnVisibility( this.context.gridCol );
+            },
+            shown: function() {
+              return !(this.context.gridCol.colDef.visible === true || this.context.gridCol.colDef.visible === undefined);
+            },
+            context: { gridCol: $scope.grid.getColumn(colDef.name || colDef.field) }
+          };
+          service.setMenuItemTitle( menuItem, colDef, $scope.grid );
+          showHideColumns.push( menuItem );
+        }
+      });
+      return showHideColumns;
+    },
+    
+    
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.gridMenuService
+     * @name setMenuItemTitle
+     * @description Handles the response from gridMenuTitleFilter, adding it directly to the menu
+     * item if it returns a string, otherwise waiting for the promise to resolve or reject then
+     * putting the result into the title 
+     * @param {object} menuItem the menuItem we want to put the title on
+     * @param {object} colDef the colDef from which we can get displayName, name or field
+     * @param {Grid} grid the grid, from which we can get the options.gridMenuTitleFilter
+     * 
+     */
+    setMenuItemTitle: function( menuItem, colDef, grid ){
+      var title = grid.options.gridMenuTitleFilter( colDef.displayName || colDef.name || colDef.field );
+      
+      if ( typeof(title) === 'string' ){
+        menuItem.title = title;
+      } else if ( title.then ){
+        // must be a promise
+        menuItem.title = "";
+        title.then( function( successValue ) {
+          menuItem.title = successValue;
+        }, function( errorValue ) {
+          menuItem.title = errorValue;
+        });
+      } else {
+        gridUtil.logError('Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config');
+        menuItem.title = 'badconfig';
+      }
+    },
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.gridMenuService
+     * @name toggleColumnVisibility
+     * @description Toggles the visibility of an individual column.  Expects to be
+     * provided a context that has on it a gridColumn, which is the column that
+     * we'll operate upon.  We change the visibility, and refresh the grid as appropriate
+     * @param {GridCol} gridCol the column that we want to toggle
+     * 
+     */
+    toggleColumnVisibility: function( gridCol ) {
+      gridCol.colDef.visible = !( gridCol.colDef.visible === true || gridCol.colDef.visible === undefined ); 
+      
+      gridCol.grid.refresh();
+    }
+  };
+  
+  return service;
+}])
+
+
+
+.directive('uiGridMenuButton', ['gridUtil', 'uiGridConstants', 'uiGridGridMenuService', 
+function (gridUtil, uiGridConstants, uiGridGridMenuService) {
+
+  return {
+    priority: 0,
+    scope: true,
+    require: ['?^uiGrid'],
+    templateUrl: 'ui-grid/ui-grid-menu-button',
+    replace: true,
+
+
+    link: function ($scope, $elm, $attrs, controllers) {
+      var uiGridCtrl = controllers[0];
+
+      uiGridGridMenuService.initialize($scope, uiGridCtrl.grid);
+      
+      $scope.shown = false;
+
+      $scope.toggleMenu = function () {
+        if ( $scope.shown ){
+          $scope.$broadcast('hide-menu');
+          $scope.shown = false;
+        } else {
+          $scope.menuItems = uiGridGridMenuService.getMenuItems( $scope );
+          $scope.$broadcast('show-menu');
+          $scope.shown = true;
+        }
+      };
+      
+      $scope.$on('menu-hidden', function() {
+        $scope.shown = false;
+      });
+    }
+  };
+
+}]);
+
+})();
+(function(){
+
+/**
+ * @ngdoc directive
+ * @name ui.grid.directive:uiGridColumnMenu
+ * @element style
+ * @restrict A
+ *
+ * @description
+ * Allows us to interpolate expressions in `<style>` elements. Angular doesn't do this by default as it can/will/might? break in IE8.
+ *
+ * @example
+ <doc:example module="app">
+ <doc:source>
+ <script>
+ var app = angular.module('app', ['ui.grid']);
+
+ app.controller('MainCtrl', ['$scope', function ($scope) {
+   
+ }]);
+ </script>
+
+ <div ng-controller="MainCtrl">
+   <div ui-grid-menu shown="true"  ></div>
+ </div>
+ </doc:source>
+ <doc:scenario>
+ </doc:scenario>
+ </doc:example>
+ */
+angular.module('ui.grid')
+
+.directive('uiGridMenu', ['$compile', '$timeout', '$window', '$document', 'gridUtil', 'uiGridConstants', 
+function ($compile, $timeout, $window, $document, gridUtil, uiGridConstants) {
+  var uiGridMenu = {
+    priority: 0,
+    scope: {
+      // shown: '&',
+      menuItems: '=',
+      autoHide: '=?'
+    },
+    require: '?^uiGrid',
+    templateUrl: 'ui-grid/uiGridMenu',
+    replace: false,
+    link: function ($scope, $elm, $attrs, uiGridCtrl) {
+      var self = this;
+      var menuMid;
+      var $animate;
+     
+    // *** Show/Hide functions ******
+      self.showMenu = $scope.showMenu = function(event, args) {
+        if ( !$scope.shown ){
+
+          /*
+           * In order to animate cleanly we remove the ng-if, wait a digest cycle, then
+           * animate the removal of the ng-hide.  We can't successfully (so far as I can tell)
+           * animate removal of the ng-if, as the menu items aren't there yet.  And we don't want
+           * to rely on ng-show only, as that leaves elements in the DOM that are needlessly evaluated
+           * on scroll events.
+           * 
+           * Note when testing animation that animations don't run on the tutorials.  When debugging it looks
+           * like they do, but angular has a default $animate provider that is just a stub, and that's what's
+           * being called.  ALso don't be fooled by the fact that your browser has actually loaded the 
+           * angular-translate.js, it's not using it.  You need to test animations in an external application. 
+           */
+          $scope.shown = true;
+
+          $timeout( function() {
+            $scope.shownMid = true;
+            $scope.$emit('menu-shown');
+          });
+        } else if ( !$scope.shownMid ) {
+          // we're probably doing a hide then show, so we don't need to wait for ng-if
+          $scope.shownMid = true;
+          $scope.$emit('menu-shown');
+        }
+
+        var docEventType = 'click';
+        if (args && args.originalEvent && args.originalEvent.type && args.originalEvent.type === 'touchstart') {
+          docEventType = args.originalEvent.type;
+        }
+
+        // Turn off an existing document click handler
+        angular.element(document).off('click touchstart', applyHideMenu);
+
+        // Turn on the document click handler, but in a timeout so it doesn't apply to THIS click if there is one
+        $timeout(function() {
+          angular.element(document).on(docEventType, applyHideMenu);
+        });
+      };
+
+
+      self.hideMenu = $scope.hideMenu = function(event, args) {
+        if ( $scope.shown ){
+          /*
+           * In order to animate cleanly we animate the addition of ng-hide, then use a $timeout to
+           * set the ng-if (shown = false) after the animation runs.  In theory we can cascade off the
+           * callback on the addClass method, but it is very unreliable with unit tests for no discernable reason.
+           *   
+           * The user may have clicked on the menu again whilst
+           * we're waiting, so we check that the mid isn't shown before applying the ng-if.
+           */
+          $scope.shownMid = false;
+          $timeout( function() {
+            if ( !$scope.shownMid ){
+              $scope.shown = false;
+              $scope.$emit('menu-hidden');
+            }
+          }, 200);
+        }
+
+        angular.element(document).off('click touchstart', applyHideMenu);
+      };
+
+      $scope.$on('hide-menu', function (event, args) {
+        $scope.hideMenu(event, args);
+      });
+
+      $scope.$on('show-menu', function (event, args) {
+        $scope.showMenu(event, args);
+      });
+
+      
+    // *** Auto hide when click elsewhere ******
+      var applyHideMenu = function(){
+        if ($scope.shown) {
+          $scope.$apply(function () {
+            $scope.hideMenu();
+          });
+        }
+      };
+    
+      if (typeof($scope.autoHide) === 'undefined' || $scope.autoHide === undefined) {
+        $scope.autoHide = true;
+      }
+
+      if ($scope.autoHide) {
+        angular.element($window).on('resize', applyHideMenu);
+      }
+
+      $scope.$on('$destroy', function () {
+        angular.element(document).off('click touchstart', applyHideMenu);
+      });
+      
+
+      $scope.$on('$destroy', function() {
+        angular.element($window).off('resize', applyHideMenu);
+      });
+
+      $scope.$on('$destroy', $scope.$on(uiGridConstants.events.GRID_SCROLL, applyHideMenu ));
+
+      $scope.$on('$destroy', $scope.$on(uiGridConstants.events.ITEM_DRAGGING, applyHideMenu ));
+    },
+    
+    
+    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
+      var self = this;
+    }]
+  };
+
+  return uiGridMenu;
+}])
+
+.directive('uiGridMenuItem', ['gridUtil', '$compile', 'i18nService', function (gridUtil, $compile, i18nService) {
+  var uiGridMenuItem = {
+    priority: 0,
+    scope: {
+      title: '=',
+      active: '=',
+      action: '=',
+      icon: '=',
+      shown: '=',
+      context: '=',
+      templateUrl: '='
+    },
+    require: ['?^uiGrid', '^uiGridMenu'],
+    templateUrl: 'ui-grid/uiGridMenuItem',
+    replace: true,
+    compile: function($elm, $attrs) {
+      return {
+        pre: function ($scope, $elm, $attrs, controllers) {
+          var uiGridCtrl = controllers[0],
+              uiGridMenuCtrl = controllers[1];
+          
+          if ($scope.templateUrl) {
+            gridUtil.getTemplate($scope.templateUrl)
+                .then(function (contents) {
+                  var template = angular.element(contents);
+                    
+                  var newElm = $compile(template)($scope);
+                  $elm.replaceWith(newElm);
+                });
+          }
+        },
+        post: function ($scope, $elm, $attrs, controllers) {
+          var uiGridCtrl = controllers[0],
+              uiGridMenuCtrl = controllers[1];
+
+          // TODO(c0bra): validate that shown and active are functions if they're defined. An exception is already thrown above this though
+          // if (typeof($scope.shown) !== 'undefined' && $scope.shown && typeof($scope.shown) !== 'function') {
+          //   throw new TypeError("$scope.shown is defined but not a function");
+          // }
+          if (typeof($scope.shown) === 'undefined' || $scope.shown === null) {
+            $scope.shown = function() { return true; };
+          }
+
+          $scope.itemShown = function () {
+            var context = {};
+            if ($scope.context) {
+              context.context = $scope.context;
+            }
+
+            if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
+              context.grid = uiGridCtrl.grid;
+            }
+
+            return $scope.shown.call(context);
+          };
+
+          $scope.itemAction = function($event,title) {
+            // gridUtil.logDebug('itemAction');
+            $event.stopPropagation();
+
+            if (typeof($scope.action) === 'function') {
+              var context = {};
+
+              if ($scope.context) {
+                context.context = $scope.context;
+              }
+
+              // Add the grid to the function call context if the uiGrid controller is present
+              if (typeof(uiGridCtrl) !== 'undefined' && uiGridCtrl) {
+                context.grid = uiGridCtrl.grid;
+              }
+
+              $scope.action.call(context, $event, title);
+
+              $scope.$emit('hide-menu');
+            }
+          };
+
+          $scope.i18n = i18nService.get();
+        }
+      };
+    }
+  };
+
+  return uiGridMenuItem;
+}]);
+
+})();
+(function () {
+// 'use strict';
+
+  angular.module('ui.grid').directive('uiGridNativeScrollbar', ['$timeout', '$document', 'uiGridConstants', 'gridUtil',
+    function ($timeout, $document, uiGridConstants, gridUtil) {
+    var scrollBarWidth = gridUtil.getScrollbarWidth();
+
+    // scrollBarWidth = scrollBarWidth > 0 ? scrollBarWidth : 17;
+    if (!angular.isNumber(scrollBarWidth)) {
+      scrollBarWidth = 0;
+    }
+
+    // If the browser is IE, add 1px to the scrollbar container, otherwise scroll events won't work right (in IE11 at least)
+    var browser = gridUtil.detectBrowser();
+    if (browser === 'ie') {
+      scrollBarWidth = scrollBarWidth + 1;
+    }
+
+    return {
+      scope: {
+        type: '@'
+      },
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      link: function ($scope, $elm, $attrs, controllers) {
+        var uiGridCtrl = controllers[0];
+        var containerCtrl = controllers[1];
+        var rowContainer = containerCtrl.rowContainer;
+        var colContainer = containerCtrl.colContainer;
+        var grid = uiGridCtrl.grid;
+
+        var contents = angular.element('<div class="contents">&nbsp;</div>');
+
+        $elm.addClass('ui-grid-native-scrollbar');
+
+        var previousScrollPosition;
+
+        var elmMaxScroll = 0;
+
+        if ($scope.type === 'vertical') {
+          // Update the width based on native scrollbar width
+          $elm.css('width', scrollBarWidth + 'px');
+
+          $elm.addClass('vertical');
+
+          grid.verticalScrollbarWidth = grid.options.enableVerticalScrollbar === uiGridConstants.scrollbars.WHEN_NEEDED ? 0 : scrollBarWidth;
+          colContainer.verticalScrollbarWidth = grid.verticalScrollbarWidth;
+
+          // Save the initial scroll position for use in scroll events
+          previousScrollPosition = $elm[0].scrollTop;
+        }
+        else if ($scope.type === 'horizontal') {
+          // Update the height based on native scrollbar height
+          $elm.css('height', scrollBarWidth + 'px');
+
+          $elm.addClass('horizontal');
+
+          // Save this scrollbar's dimension in the grid properties
+          grid.horizontalScrollbarHeight = grid.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.WHEN_NEEDED ? 0 : scrollBarWidth;
+          rowContainer.horizontalScrollbarHeight = grid.horizontalScrollbarHeight;
+
+          // Save the initial scroll position for use in scroll events
+          previousScrollPosition = gridUtil.normalizeScrollLeft($elm);
+        }
+
+        // Save the contents elm inside the scrollbar elm so it sizes correctly
+        $elm.append(contents);
+
+        // Get the relevant element dimension now that the contents are in it
+        if ($scope.type === 'vertical') {
+          elmMaxScroll = gridUtil.elementHeight($elm);
+        }
+        else if ($scope.type === 'horizontal') {
+          elmMaxScroll = gridUtil.elementWidth($elm);
+        }
+
+        function updateNativeVerticalScrollbar() {
+          // Get the height that the scrollbar should have
+          var height = rowContainer.getViewportHeight();
+
+          // Update the vertical scrollbar's content height so it's the same as the canvas
+          var contentHeight = rowContainer.getCanvasHeight();
+
+          // TODO(c0bra): set scrollbar `top` by height of header row
+          // var headerHeight = gridUtil.outerElementHeight(containerCtrl.header);
+          var headerHeight = colContainer.headerHeight ? colContainer.headerHeight : grid.headerHeight;
+
+          // gridUtil.logDebug('headerHeight in scrollbar', headerHeight);
+
+          var ondemand  = grid.options.enableVerticalScrollbar === uiGridConstants.scrollbars.WHEN_NEEDED ? "overflow-y:auto;" : "";
+          // var ret = '.grid' + uiGridCtrl.grid.id + ' .ui-grid-native-scrollbar.vertical .contents { height: ' + h + 'px; }';
+          var ret = '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.vertical .contents { height: ' + contentHeight + 'px; }';
+          ret += '\n .grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.vertical { height: ' + height + 'px; top: ' + headerHeight + 'px;' +ondemand +'}';
+
+          elmMaxScroll = contentHeight;
+
+          return ret;
+        }
+
+        // Get the grid's bottom border height (TODO(c0bra): need to account for footer here!)
+        var gridElm = gridUtil.closestElm($elm, '.ui-grid');
+        var gridBottomBorder = gridUtil.getBorderSize(gridElm, 'bottom');
+
+        function updateNativeHorizontalScrollbar() {
+          var w = colContainer.getCanvasWidth();
+
+          var bottom = gridBottomBorder;
+          if (grid.options.showFooter) {
+            bottom -= 1;
+          }
+          
+          var adjustment = colContainer.getViewportAdjustment();
+          bottom -= adjustment.height;
+          
+          var ondemand = grid.options.enableHorizontalScrollbar === uiGridConstants.scrollbars.WHEN_NEEDED ? "overflow-x:auto" : "";
+          var ret = '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.horizontal { bottom: ' + bottom + 'px;' +ondemand + ' }';
+          ret += '.grid' + grid.id + ' .ui-grid-render-container-' + containerCtrl.containerId + ' .ui-grid-native-scrollbar.horizontal .contents { width: ' + w + 'px; }';
+
+          elmMaxScroll = w;
+
+          return ret;
+        }
+
+        // NOTE: priority 6 so they run after the column widths update, which in turn update the canvas width
+        if ($scope.type === 'vertical') {
+          grid.registerStyleComputation({
+            priority: 6,
+            func: updateNativeVerticalScrollbar
+          });
+        }
+        else if ($scope.type === 'horizontal') {
+          grid.registerStyleComputation({
+            priority: 6,
+            func: updateNativeHorizontalScrollbar
+          });
+        }
+
+
+        $scope.scrollSource = null;
+
+        function scrollEvent(evt) {
+          if ($scope.type === 'vertical') {
+            grid.flagScrollingVertically();
+            var newScrollTop = $elm[0].scrollTop;
+
+            var yDiff = previousScrollPosition - newScrollTop;
+
+            var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+            // Subtract the h. scrollbar height from the vertical length if it's present
+            if (grid.horizontalScrollbarHeight && grid.horizontalScrollbarHeight > 0) {
+              vertScrollLength = vertScrollLength - uiGridCtrl.grid.horizontalScrollbarHeight;
+            }
+
+            var vertScrollPercentage = newScrollTop / vertScrollLength;
+
+            if (vertScrollPercentage > 1) {
+              vertScrollPercentage = 1;
+            }
+            if (vertScrollPercentage < 0) {
+              vertScrollPercentage = 0;
+            }
+
+            var yArgs = {
+              target: $elm,
+              y: {
+                percentage: vertScrollPercentage
+              }
+            };
+
+            // If the source of this scroll is defined (i.e., not us, then don't fire the scroll event because we'll be re-triggering)
+            if (!$scope.scrollSource) {
+              uiGridCtrl.fireScrollingEvent(yArgs);
+            }
+            else {
+              // Reset the scroll source for the next scroll event
+              $scope.scrollSource = null;
+            }
+
+            previousScrollPosition = newScrollTop;
+          }
+          else if ($scope.type === 'horizontal') {
+            grid.flagScrollingHorizontally();
+            // var newScrollLeft = $elm[0].scrollLeft;
+            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);
+
+            var xDiff = previousScrollPosition - newScrollLeft;
+
+            var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+            var horizScrollPercentage = newScrollLeft / horizScrollLength;
+
+            var xArgs = {
+              target: $elm,
+              x: {
+                percentage: horizScrollPercentage
+              }
+            };
+
+            // If the source of this scroll is defined (i.e., not us, then don't fire the scroll event because we'll be re-triggering)
+            if (!$scope.scrollSource) {
+              uiGridCtrl.fireScrollingEvent(xArgs);
+            }
+            else {
+              // Reset the scroll source for the next scroll event
+              $scope.scrollSource = null;
+            }
+
+            previousScrollPosition = newScrollLeft;
+          }
+        }
+
+        $elm.on('scroll', scrollEvent);
+
+        $elm.on('$destroy', function () {
+          $elm.off('scroll');
+        });
+
+        function gridScroll(evt, args) {
+          // Don't listen to our own scroll event!
+          if (args.target && (args.target === $elm || angular.element(args.target).hasClass('ui-grid-native-scrollbar'))) {
+            return;
+          }
+
+          // Set the source of the scroll event in our scope so it's available in our 'scroll' event handler
+          $scope.scrollSource = args.target;
+
+          if ($scope.type === 'vertical') {
+            if (args.y && typeof(args.y.percentage) !== 'undefined' && args.y.percentage !== undefined) {
+              grid.flagScrollingVertically();
+              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+              var newScrollTop = Math.max(0, args.y.percentage * vertScrollLength);
+
+              $elm[0].scrollTop = newScrollTop;
+
+
+            }
+          }
+          else if ($scope.type === 'horizontal') {
+            if (args.x && typeof(args.x.percentage) !== 'undefined' && args.x.percentage !== undefined) {
+              grid.flagScrollingHorizontally();
+              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+              var newScrollLeft = Math.max(0, args.x.percentage * horizScrollLength);
+
+              // $elm[0].scrollLeft = newScrollLeft;
+              $elm[0].scrollLeft = gridUtil.denormalizeScrollLeft($elm, newScrollLeft);
+            }
+          }
+        }
+
+        var gridScrollDereg = $scope.$on(uiGridConstants.events.GRID_SCROLL, gridScroll);
+        $scope.$on('$destroy', gridScrollDereg);
+
+
+
+      }
+    };
+  }]);
+})();
+(function () {
+  'use strict';
+
+  var module = angular.module('ui.grid');
+  
+  module.directive('uiGridRenderContainer', ['$timeout', '$document', 'uiGridConstants', 'gridUtil',
+    function($timeout, $document, uiGridConstants, GridUtil) {
+    return {
+      replace: true,
+      transclude: true,
+      templateUrl: 'ui-grid/uiGridRenderContainer',
+      require: ['^uiGrid', 'uiGridRenderContainer'],
+      scope: {
+        containerId: '=',
+        rowContainerName: '=',
+        colContainerName: '=',
+        bindScrollHorizontal: '=',
+        bindScrollVertical: '=',
+        enableVerticalScrollbar: '=',
+        enableHorizontalScrollbar: '='
+      },
+      controller: 'uiGridRenderContainer as RenderContainer',
+      compile: function () {
+        return {
+          pre: function prelink($scope, $elm, $attrs, controllers) {
+            // gridUtil.logDebug('render container ' + $scope.containerId + ' pre-link');
+
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = $scope.grid = uiGridCtrl.grid;
+
+            // Verify that the render container for this element exists
+            if (!$scope.rowContainerName) {
+              throw "No row render container name specified";
+            }
+            if (!$scope.colContainerName) {
+              throw "No column render container name specified";
+            }
+
+            if (!grid.renderContainers[$scope.rowContainerName]) {
+              throw "Row render container '" + $scope.rowContainerName + "' is not registered.";
+            }
+            if (!grid.renderContainers[$scope.colContainerName]) {
+              throw "Column render container '" + $scope.colContainerName + "' is not registered.";
+            }
+
+            var rowContainer = $scope.rowContainer = grid.renderContainers[$scope.rowContainerName];
+            var colContainer = $scope.colContainer = grid.renderContainers[$scope.colContainerName];
+            
+            containerCtrl.containerId = $scope.containerId;
+            containerCtrl.rowContainer = rowContainer;
+            containerCtrl.colContainer = colContainer;
+          },
+          post: function postlink($scope, $elm, $attrs, controllers) {
+            // gridUtil.logDebug('render container ' + $scope.containerId + ' post-link');
+
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = uiGridCtrl.grid;
+            var rowContainer = containerCtrl.rowContainer;
+            var colContainer = containerCtrl.colContainer;
+
+            var renderContainer = grid.renderContainers[$scope.containerId];
+
+            // Put the container name on this element as a class
+            $elm.addClass('ui-grid-render-container-' + $scope.containerId);
+
+            // Bind to left/right-scroll events
+            var scrollUnbinder;
+            if ($scope.bindScrollHorizontal || $scope.bindScrollVertical) {
+              scrollUnbinder = $scope.$on(uiGridConstants.events.GRID_SCROLL, scrollHandler);
+            }
+
+            function scrollHandler (evt, args) {
+              // Vertical scroll
+              if (args.y && $scope.bindScrollVertical) {
+                containerCtrl.prevScrollArgs = args;
+
+                var scrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                // Add the height of the native horizontal scrollbar, if it's there. Otherwise it will mask over the final row
+                if (grid.horizontalScrollbarHeight && grid.horizontalScrollbarHeight > 0) {
+                  scrollLength = scrollLength + grid.horizontalScrollbarHeight;
+                }
+
+                var oldScrollTop = containerCtrl.viewport[0].scrollTop;
+                
+                var scrollYPercentage;
+                if (typeof(args.y.percentage) !== 'undefined' && args.y.percentage !== undefined) {
+                  scrollYPercentage = args.y.percentage;
+                }
+                else if (typeof(args.y.pixels) !== 'undefined' && args.y.pixels !== undefined) {
+                  scrollYPercentage = args.y.percentage = (oldScrollTop + args.y.pixels) / scrollLength;
+                  // gridUtil.logDebug('y.percentage', args.y.percentage);
+                }
+                else {
+                  throw new Error("No percentage or pixel value provided for scroll event Y axis");
+                }
+
+                var newScrollTop = Math.max(0, scrollYPercentage * scrollLength);
+
+                containerCtrl.viewport[0].scrollTop = newScrollTop;
+                
+                // TOOD(c0bra): what's this for?
+                // grid.options.offsetTop = newScrollTop;
+
+                containerCtrl.prevScrollArgs.y.pixels = newScrollTop - oldScrollTop;
+              }
+
+              // Horizontal scroll
+              if (args.x && $scope.bindScrollHorizontal) {
+                containerCtrl.prevScrollArgs = args;
+
+                var scrollWidth = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                // var oldScrollLeft = containerCtrl.viewport[0].scrollLeft;
+                var oldScrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);
+
+                var scrollXPercentage;
+                if (typeof(args.x.percentage) !== 'undefined' && args.x.percentage !== undefined) {
+                  scrollXPercentage = args.x.percentage;
+                }
+                else if (typeof(args.x.pixels) !== 'undefined' && args.x.pixels !== undefined) {
+                  scrollXPercentage = args.x.percentage = (oldScrollLeft + args.x.pixels) / scrollWidth;
+                }
+                else {
+                  throw new Error("No percentage or pixel value provided for scroll event X axis");
+                }
+
+                var newScrollLeft = Math.max(0, scrollXPercentage * scrollWidth);
+                
+                // uiGridCtrl.adjustScrollHorizontal(newScrollLeft, scrollXPercentage);
+
+                // containerCtrl.viewport[0].scrollLeft = newScrollLeft;
+                containerCtrl.viewport[0].scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.viewport, newScrollLeft);
+
+                containerCtrl.prevScrollLeft = newScrollLeft;
+
+                if (containerCtrl.headerViewport) {
+                  // containerCtrl.headerViewport.scrollLeft = newScrollLeft;
+                  containerCtrl.headerViewport.scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.headerViewport, newScrollLeft);
+                }
+
+                if (containerCtrl.footerViewport) {
+                  // containerCtrl.footerViewport.scrollLeft = newScrollLeft;
+                  containerCtrl.footerViewport.scrollLeft = GridUtil.denormalizeScrollLeft(containerCtrl.footerViewport, newScrollLeft);
+                }
+
+                // uiGridCtrl.grid.options.offsetLeft = newScrollLeft;
+
+                containerCtrl.prevScrollArgs.x.pixels = newScrollLeft - oldScrollLeft;
+              }
+            }
+
+            // Scroll the render container viewport when the mousewheel is used
+            $elm.bind('wheel mousewheel DomMouseScroll MozMousePixelScroll', function(evt) {
+              // use wheelDeltaY
+              evt.preventDefault();
+
+              var newEvent = GridUtil.normalizeWheelEvent(evt);
+
+              var args = { target: $elm };
+              if (newEvent.deltaY !== 0) {
+                var scrollYAmount = newEvent.deltaY * -120;
+
+                // Get the scroll percentage
+                var scrollYPercentage = (containerCtrl.viewport[0].scrollTop + scrollYAmount) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                // Keep scrollPercentage within the range 0-1.
+                if (scrollYPercentage < 0) { scrollYPercentage = 0; }
+                else if (scrollYPercentage > 1) { scrollYPercentage = 1; }
+
+                args.y = { percentage: scrollYPercentage, pixels: scrollYAmount };
+              }
+              if (newEvent.deltaX !== 0) {
+                var scrollXAmount = newEvent.deltaX * -120;
+
+                // Get the scroll percentage
+                var scrollLeft = GridUtil.normalizeScrollLeft(containerCtrl.viewport);
+                var scrollXPercentage = (scrollLeft + scrollXAmount) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                // Keep scrollPercentage within the range 0-1.
+                if (scrollXPercentage < 0) { scrollXPercentage = 0; }
+                else if (scrollXPercentage > 1) { scrollXPercentage = 1; }
+
+                args.x = { percentage: scrollXPercentage, pixels: scrollXAmount };
+              }
+              
+              uiGridCtrl.fireScrollingEvent(args);
+            });
+            
+
+            var startY = 0,
+            startX = 0,
+            scrollTopStart = 0,
+            scrollLeftStart = 0,
+            directionY = 1,
+            directionX = 1,
+            moveStart;
+
+            function touchmove(event) {
+              if (event.originalEvent) {
+                event = event.originalEvent;
+              }
+
+              event.preventDefault();
+
+              var deltaX, deltaY, newX, newY;
+              newX = event.targetTouches[0].screenX;
+              newY = event.targetTouches[0].screenY;
+              deltaX = -(newX - startX);
+              deltaY = -(newY - startY);
+
+              directionY = (deltaY < 1) ? -1 : 1;
+              directionX = (deltaX < 1) ? -1 : 1;
+
+              deltaY *= 2;
+              deltaX *= 2;
+
+              var args = { target: event.target };
+
+              if (deltaY !== 0) {
+                var scrollYPercentage = (scrollTopStart + deltaY) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                if (scrollYPercentage > 1) { scrollYPercentage = 1; }
+                else if (scrollYPercentage < 0) { scrollYPercentage = 0; }
+
+                args.y = { percentage: scrollYPercentage, pixels: deltaY };
+              }
+              if (deltaX !== 0) {
+                var scrollXPercentage = (scrollLeftStart + deltaX) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+
+                if (scrollXPercentage > 1) { scrollXPercentage = 1; }
+                else if (scrollXPercentage < 0) { scrollXPercentage = 0; }
+
+                args.x = { percentage: scrollXPercentage, pixels: deltaX };
+              }
+
+              uiGridCtrl.fireScrollingEvent(args);
+            }
+            
+            function touchend(event) {
+              if (event.originalEvent) {
+                event = event.originalEvent;
+              }
+
+              event.preventDefault();
+
+              $document.unbind('touchmove', touchmove);
+              $document.unbind('touchend', touchend);
+              $document.unbind('touchcancel', touchend);
+
+              // Get the distance we moved on the Y axis
+              var scrollTopEnd = containerCtrl.viewport[0].scrollTop;
+              var scrollLeftEnd = containerCtrl.viewport[0].scrollTop;
+              var deltaY = Math.abs(scrollTopEnd - scrollTopStart);
+              var deltaX = Math.abs(scrollLeftEnd - scrollLeftStart);
+
+              // Get the duration it took to move this far
+              var moveDuration = (new Date()) - moveStart;
+
+              // Scale the amount moved by the time it took to move it (i.e. quicker, longer moves == more scrolling after the move is over)
+              var moveYScale = deltaY / moveDuration;
+              var moveXScale = deltaX / moveDuration;
+
+              var decelerateInterval = 63; // 1/16th second
+              var decelerateCount = 8; // == 1/2 second
+              var scrollYLength = 120 * directionY * moveYScale;
+              var scrollXLength = 120 * directionX * moveXScale;
+
+              function decelerate() {
+                $timeout(function() {
+                  var args = { target: event.target };
+
+                  if (scrollYLength !== 0) {
+                    var scrollYPercentage = (containerCtrl.viewport[0].scrollTop + scrollYLength) / (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+
+                    args.y = { percentage: scrollYPercentage, pixels: scrollYLength };
+                  }
+
+                  if (scrollXLength !== 0) {
+                    var scrollXPercentage = (containerCtrl.viewport[0].scrollLeft + scrollXLength) / (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+                    args.x = { percentage: scrollXPercentage, pixels: scrollXLength };
+                  }
+
+                  uiGridCtrl.fireScrollingEvent(args);
+
+                  decelerateCount = decelerateCount -1;
+                  scrollYLength = scrollYLength / 2;
+                  scrollXLength = scrollXLength / 2;
+
+                  if (decelerateCount > 0) {
+                    decelerate();
+                  }
+                  else {
+                    uiGridCtrl.scrollbars.forEach(function (sbar) {
+                      sbar.removeClass('ui-grid-scrollbar-visible');
+                      sbar.removeClass('ui-grid-scrolling');
+                    });
+                  }
+                }, decelerateInterval);
+              }
+
+              decelerate();
+            }
+
+            if (GridUtil.isTouchEnabled()) {
+              $elm.bind('touchstart', function (event) {
+                if (event.originalEvent) {
+                  event = event.originalEvent;
+                }
+
+                event.preventDefault();
+
+                uiGridCtrl.scrollbars.forEach(function (sbar) {
+                  sbar.addClass('ui-grid-scrollbar-visible');
+                  sbar.addClass('ui-grid-scrolling');
+                });
+
+                moveStart = new Date();
+                startY = event.targetTouches[0].screenY;
+                startX = event.targetTouches[0].screenX;
+                scrollTopStart = containerCtrl.viewport[0].scrollTop;
+                scrollLeftStart = containerCtrl.viewport[0].scrollLeft;
+                
+                $document.on('touchmove', touchmove);
+                $document.on('touchend touchcancel', touchend);
+              });
+            }
+
+            $elm.bind('$destroy', function() {
+              scrollUnbinder();
+              $elm.unbind('keydown');
+
+              ['touchstart', 'touchmove', 'touchend','keydown', 'wheel', 'mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'].forEach(function (eventName) {
+                $elm.unbind(eventName);
+              });
+            });
+            
+            // TODO(c0bra): Handle resizing the inner canvas based on the number of elements
+            function update() {
+              var ret = '';
+
+              var canvasWidth = colContainer.getCanvasWidth();
+              var viewportWidth = colContainer.getViewportWidth();
+
+              var canvasHeight = rowContainer.getCanvasHeight();
+              var viewportHeight = rowContainer.getViewportHeight();
+
+              var headerViewportWidth = colContainer.getHeaderViewportWidth();
+              var footerViewportWidth = colContainer.getHeaderViewportWidth();
+              
+              // Set canvas dimensions
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-canvas { width: ' + canvasWidth + 'px; height: ' + canvasHeight + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-canvas { width: ' + canvasWidth + 'px; }';
+              
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-viewport { width: ' + viewportWidth + 'px; height: ' + viewportHeight + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-viewport { width: ' + headerViewportWidth + 'px; }';
+
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-footer-canvas { width: ' + canvasWidth + 'px; }';
+              ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-footer-viewport { width: ' + footerViewportWidth + 'px; }';
+
+              // If the render container has an "explicit" header height (such as in the case that its header is smaller than the other headers and needs to be explicitly set to be the same, ue thae)
+              if (renderContainer.explicitHeaderHeight !== undefined && renderContainer.explicitHeaderHeight !== null && renderContainer.explicitHeaderHeight > 0) {
+                ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-cell { height: ' + renderContainer.explicitHeaderHeight + 'px; }';
+              }
+              // Otherwise if the render container has an INNER header height, use that on the header cells (so that all the header cells are the same height and those that have less elements don't have undersized borders)
+              else if (renderContainer.innerHeaderHeight !== undefined && renderContainer.innerHeaderHeight !== null && renderContainer.innerHeaderHeight > 0) {
+                ret += '\n .grid' + uiGridCtrl.grid.id + ' .ui-grid-render-container-' + $scope.containerId + ' .ui-grid-header-cell { height: ' + renderContainer.innerHeaderHeight + 'px; }';
+              }
+
+              return ret;
+            }
+            
+            uiGridCtrl.grid.registerStyleComputation({
+              priority: 6,
+              func: update
+            });
+          }
+        };
+      }
+    };
+
+  }]);
+
+  module.controller('uiGridRenderContainer', ['$scope', 'gridUtil', function ($scope, gridUtil) {
+    var self = this;
+
+    self.rowStyle = function (index) {
+      var renderContainer = $scope.grid.renderContainers[$scope.containerId];
+
+      var styles = {};
+      
+      if (!renderContainer.disableRowOffset) {
+        if (index === 0 && self.currentTopRow !== 0) {
+          // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered
+          var hiddenRowWidth = ($scope.rowContainer.currentTopRow) *
+            $scope.rowContainer.visibleRowCache[$scope.rowContainer.currentTopRow].height;
+
+          // return { 'margin-top': hiddenRowWidth + 'px' };
+          styles['margin-top'] = hiddenRowWidth + 'px';
+        }
+      }
+      
+      if (!renderContainer.disableColumnOffset && $scope.colContainer.currentFirstColumn !== 0) {
+        if ($scope.grid.isRTL()) {
+          styles['margin-right'] = $scope.colContainer.columnOffset + 'px';
+        }
+        else {
+          styles['margin-left'] = $scope.colContainer.columnOffset + 'px';
+        }
+      }
+
+      return styles;
+    };
+
+    self.columnStyle = function (index) {
+      var renderContainer = $scope.grid.renderContainers[$scope.containerId];
+
+      var self = this;
+
+      if (!renderContainer.disableColumnOffset) {
+        if (index === 0 && $scope.colContainer.currentFirstColumn !== 0) {
+          var offset = $scope.colContainer.columnOffset;
+
+          if ($scope.grid.isRTL()) {
+            return { 'margin-right': offset + 'px' };
+          }
+          else {
+            return { 'margin-left': offset + 'px' }; 
+          }
+        }
+      }
+
+      return null;
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridRow', ['gridUtil', function(gridUtil) {
+    return {
+      replace: true,
+      // priority: 2001,
+      // templateUrl: 'ui-grid/ui-grid-row',
+      require: ['^uiGrid', '^uiGridRenderContainer'],
+      scope: {
+         row: '=uiGridRow',
+         //rowRenderIndex is added to scope to give the true visual index of the row to any directives that need it
+         rowRenderIndex: '='
+      },
+      compile: function() {
+        return {
+          pre: function($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            var grid = uiGridCtrl.grid;
+
+            $scope.grid = uiGridCtrl.grid;
+            $scope.colContainer = containerCtrl.colContainer;
+
+            grid.getRowTemplateFn.then(function (templateFn) {
+              templateFn($scope, function(clonedElement, scope) {
+                $elm.replaceWith(clonedElement);
+              });
+            });
+          },
+          post: function($scope, $elm, $attrs, controllers) {
+            var uiGridCtrl = controllers[0];
+            var containerCtrl = controllers[1];
+
+            //add optional reference to externalScopes function to scope
+            //so it can be retrieved in lower elements
+            $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
+          }
+        };
+      }
+    };
+  }]);
+
+})();
+(function(){
+// 'use strict';
+
+  /**
+   * @ngdoc directive
+   * @name ui.grid.directive:uiGridStyle
+   * @element style
+   * @restrict A
+   *
+   * @description
+   * Allows us to interpolate expressions in `<style>` elements. Angular doesn't do this by default as it can/will/might? break in IE8.
+   *
+   * @example
+   <doc:example module="app">
+   <doc:source>
+   <script>
+   var app = angular.module('app', ['ui.grid']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.myStyle = '.blah { border: 1px solid }';
+        }]);
+   </script>
+
+   <div ng-controller="MainCtrl">
+   <style ui-grid-style>{{ myStyle }}</style>
+   <span class="blah">I am in a box.</span>
+   </div>
+   </doc:source>
+   <doc:scenario>
+   it('should apply the right class to the element', function () {
+        element(by.css('.blah')).getCssValue('border')
+          .then(function(c) {
+            expect(c).toContain('1px solid');
+          });
+      });
+   </doc:scenario>
+   </doc:example>
+   */
+
+
+  angular.module('ui.grid').directive('uiGridStyle', ['gridUtil', '$interpolate', function(gridUtil, $interpolate) {
+    return {
+      // restrict: 'A',
+      // priority: 1000,
+      // require: '?^uiGrid',
+      link: function($scope, $elm, $attrs, uiGridCtrl) {
+        // gridUtil.logDebug('ui-grid-style link');
+        // if (uiGridCtrl === undefined) {
+        //    gridUtil.logWarn('[ui-grid-style link] uiGridCtrl is undefined!');
+        // }
+
+        var interpolateFn = $interpolate($elm.text(), true);
+
+        if (interpolateFn) {
+          $scope.$watch(interpolateFn, function(value) {
+            $elm.text(value);
+          });
+        }
+
+          // uiGridCtrl.recalcRowStyles = function() {
+          //   var offset = (scope.options.offsetTop || 0) - (scope.options.excessRows * scope.options.rowHeight);
+          //   var rowHeight = scope.options.rowHeight;
+
+          //   var ret = '';
+          //   var rowStyleCount = uiGridCtrl.minRowsToRender() + (scope.options.excessRows * 2);
+          //   for (var i = 1; i <= rowStyleCount; i++) {
+          //     ret = ret + ' .grid' + scope.gridId + ' .ui-grid-row:nth-child(' + i + ') { top: ' + offset + 'px; }';
+          //     offset = offset + rowHeight;
+          //   }
+
+          //   scope.rowStyles = ret;
+          // };
+
+          // uiGridCtrl.styleComputions.push(uiGridCtrl.recalcRowStyles);
+
+      }
+    };
+  }]);
+
+})();
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridViewport', ['gridUtil',
+    function(gridUtil) {
+      return {
+        replace: true,
+        scope: {},
+        templateUrl: 'ui-grid/uiGridViewport',
+        require: ['^uiGrid', '^uiGridRenderContainer'],
+        link: function($scope, $elm, $attrs, controllers) {
+          // gridUtil.logDebug('viewport post-link');
+
+          var uiGridCtrl = controllers[0];
+          var containerCtrl = controllers[1];
+
+          $scope.containerCtrl = containerCtrl;
+
+          var rowContainer = containerCtrl.rowContainer;
+          var colContainer = containerCtrl.colContainer;
+
+          var grid = uiGridCtrl.grid;
+
+          $scope.grid = uiGridCtrl.grid;
+
+          // Put the containers in scope so we can get rows and columns from them
+          $scope.rowContainer = containerCtrl.rowContainer;
+          $scope.colContainer = containerCtrl.colContainer;
+
+          // Register this viewport with its container 
+          containerCtrl.viewport = $elm;
+
+          $elm.on('scroll', function (evt) {
+            var newScrollTop = $elm[0].scrollTop;
+            // var newScrollLeft = $elm[0].scrollLeft;
+            var newScrollLeft = gridUtil.normalizeScrollLeft($elm);
+            var horizScrollPercentage = -1;
+            var vertScrollPercentage = -1;
+
+            // Handle RTL here
+
+            if (newScrollLeft !== colContainer.prevScrollLeft) {
+              var xDiff = newScrollLeft - colContainer.prevScrollLeft;
+
+              var horizScrollLength = (colContainer.getCanvasWidth() - colContainer.getViewportWidth());
+              horizScrollPercentage = newScrollLeft / horizScrollLength;
+
+              colContainer.adjustScrollHorizontal(newScrollLeft, horizScrollPercentage);
+            }
+
+            if (newScrollTop !== rowContainer.prevScrollTop) {
+              var yDiff = newScrollTop - rowContainer.prevScrollTop;
+
+              // uiGridCtrl.fireScrollingEvent({ y: { pixels: diff } });
+              var vertScrollLength = (rowContainer.getCanvasHeight() - rowContainer.getViewportHeight());
+              // var vertScrollPercentage = (uiGridCtrl.prevScrollTop + yDiff) / vertScrollLength;
+              vertScrollPercentage = newScrollTop / vertScrollLength;
+
+              if (vertScrollPercentage > 1) { vertScrollPercentage = 1; }
+              if (vertScrollPercentage < 0) { vertScrollPercentage = 0; }
+              
+              rowContainer.adjustScrollVertical(newScrollTop, vertScrollPercentage);
+            }
+            
+            if ( !$scope.grid.isScrollingVertically && !$scope.grid.isScrollingHorizontally ){
+              // viewport scroll that didn't come from fireScrollEvent, so fire a scroll to keep 
+              // the header in sync
+              var args = {};
+              if ( horizScrollPercentage > -1 ){
+                args.x = { percentage: horizScrollPercentage };
+              }
+
+              if ( vertScrollPercentage > -1 ){
+                args.y = { percentage: vertScrollPercentage };
+              }
+              uiGridCtrl.fireScrollingEvent(args); 
+            }
+          });
+        }
+      };
+    }
+  ]);
+
+})();
+(function() {
+
+angular.module('ui.grid')
+.directive('uiGridVisible', function uiGridVisibleAction() {
+  return function ($scope, $elm, $attr) {
+    $scope.$watch($attr.uiGridVisible, function (visible) {
+        // $elm.css('visibility', visible ? 'visible' : 'hidden');
+        $elm[visible ? 'removeClass' : 'addClass']('ui-grid-invisible');
+    });
+  };
+});
+
+})();
+(function () {
+  'use strict';
+
+  angular.module('ui.grid').controller('uiGridController', ['$scope', '$element', '$attrs', 'gridUtil', '$q', 'uiGridConstants',
+                    '$templateCache', 'gridClassFactory', '$timeout', '$parse', '$compile',
+    function ($scope, $elm, $attrs, gridUtil, $q, uiGridConstants,
+              $templateCache, gridClassFactory, $timeout, $parse, $compile) {
+      // gridUtil.logDebug('ui-grid controller');
+
+      var self = this;
+
+      // Extend options with ui-grid attribute reference
+      self.grid = gridClassFactory.createGrid($scope.uiGrid);
+      $elm.addClass('grid' + self.grid.id);
+      self.grid.rtl = gridUtil.getStyles($elm[0])['direction'] === 'rtl';
+
+
+      //add optional reference to externalScopes function to controller
+      //so it can be retrieved in lower elements that have isolate scope
+      self.getExternalScopes = $scope.getExternalScopes;
+
+      // angular.extend(self.grid.options, );
+
+      //all properties of grid are available on scope
+      $scope.grid = self.grid;
+
+      if ($attrs.uiGridColumns) {
+        $attrs.$observe('uiGridColumns', function(value) {
+          self.grid.options.columnDefs = value;
+          self.grid.buildColumns()
+            .then(function(){
+              self.grid.preCompileCellTemplates();
+
+              self.grid.refreshCanvas(true);
+            });
+        });
+      }
+
+
+      var dataWatchCollectionDereg;
+      if (angular.isString($scope.uiGrid.data)) {
+        dataWatchCollectionDereg = $scope.$parent.$watchCollection($scope.uiGrid.data, dataWatchFunction);
+      }
+      else {
+        dataWatchCollectionDereg = $scope.$parent.$watchCollection(function() { return $scope.uiGrid.data; }, dataWatchFunction);
+      }
+
+      var columnDefWatchCollectionDereg = $scope.$parent.$watchCollection(function() { return $scope.uiGrid.columnDefs; }, columnDefsWatchFunction);
+
+      function columnDefsWatchFunction(n, o) {
+        if (n && n !== o) {
+          self.grid.options.columnDefs = n;
+          self.grid.buildColumns()
+            .then(function(){
+
+              self.grid.preCompileCellTemplates();
+
+              self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN);
+            });
+        }
+      }
+
+      function dataWatchFunction(newData) {
+        // gridUtil.logDebug('dataWatch fired');
+        var promises = [];
+        
+        if (newData) {
+          if (
+            // If we have no columns (i.e. columns length is either 0 or equal to the number of row header columns, which don't count because they're created automatically)
+            self.grid.columns.length === (self.grid.rowHeaderColumns ? self.grid.rowHeaderColumns.length : 0) &&
+            // ... and we don't have a ui-grid-columns attribute, which would define columns for us
+            !$attrs.uiGridColumns &&
+            // ... and we have no pre-defined columns
+            self.grid.options.columnDefs.length === 0 &&
+            // ... but we DO have data
+            newData.length > 0
+          ) {
+            // ... then build the column definitions from the data that we have
+            self.grid.buildColumnDefsFromData(newData);
+          }
+
+          // If we either have some columns defined, or some data defined
+          if (self.grid.options.columnDefs.length > 0 || newData.length > 0) {
+            // Build the column set, then pre-compile the column cell templates
+            promises.push(self.grid.buildColumns()
+              .then(function() {
+                self.grid.preCompileCellTemplates();
+              }));
+          }
+
+          $q.all(promises).then(function() {
+            self.grid.modifyRows(newData)
+              .then(function () {
+                // if (self.viewport) {
+                  self.grid.redrawInPlace();
+                // }
+
+                $scope.$evalAsync(function() {
+                  self.grid.refreshCanvas(true);
+                  self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.ROW);
+                });
+              });
+          });
+        }
+      }
+
+
+      $scope.$on('$destroy', function() {
+        dataWatchCollectionDereg();
+        columnDefWatchCollectionDereg();
+      });
+
+      $scope.$watch(function () { return self.grid.styleComputations; }, function() {
+        self.grid.refreshCanvas(true);
+      });
+
+
+      /* Event Methods */
+
+      self.fireScrollingEvent = gridUtil.throttle(function(args) {
+        $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
+      }, self.grid.options.scrollThrottle, {trailing: true});
+
+      self.fireEvent = function(eventName, args) {
+        // Add the grid to the event arguments if it's not there
+        if (typeof(args) === 'undefined' || args === undefined) {
+          args = {};
+        }
+
+        if (typeof(args.grid) === 'undefined' || args.grid === undefined) {
+          args.grid = self.grid;
+        }
+
+        $scope.$broadcast(eventName, args);
+      };
+
+      self.innerCompile = function innerCompile(elm) {
+        $compile(elm)($scope);
+      };
+
+    }]);
+
+/**
+ *  @ngdoc directive
+ *  @name ui.grid.directive:uiGrid
+ *  @element div
+ *  @restrict EA
+ *  @param {Object} uiGrid Options for the grid to use
+ *  @param {Object=} external-scopes Add external-scopes='someScopeObjectYouNeed' attribute so you can access
+ *            your scopes from within any custom templatedirective.  You access by $scope.getExternalScopes() function
+ *
+ *  @description Create a very basic grid.
+ *
+ *  @example
+    <example module="app">
+      <file name="app.js">
+        var app = angular.module('app', ['ui.grid']);
+
+        app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.data = [
+            { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+          ];
+        }]);
+      </file>
+      <file name="index.html">
+        <div ng-controller="MainCtrl">
+          <div ui-grid="{ data: data }"></div>
+        </div>
+      </file>
+    </example>
+ */
+angular.module('ui.grid').directive('uiGrid',
+  [
+    '$compile',
+    '$templateCache',
+    'gridUtil',
+    '$window',
+    function(
+      $compile,
+      $templateCache,
+      gridUtil,
+      $window
+      ) {
+      return {
+        templateUrl: 'ui-grid/ui-grid',
+        scope: {
+          uiGrid: '=',
+          getExternalScopes: '&?externalScopes' //optional functionwrapper around any needed external scope instances
+        },
+        replace: true,
+        transclude: true,
+        controller: 'uiGridController',
+        compile: function () {
+          return {
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+              // gridUtil.logDebug('ui-grid postlink');
+
+              var grid = uiGridCtrl.grid;
+
+              // Initialize scrollbars (TODO: move to controller??)
+              uiGridCtrl.scrollbars = [];
+
+              //todo: assume it is ok to communicate that rendering is complete??
+              grid.renderingComplete();
+
+              grid.element = $elm;
+
+              grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
+
+              // Default canvasWidth to the grid width, in case we don't get any column definitions to calculate it from
+              grid.canvasWidth = uiGridCtrl.grid.gridWidth;
+
+              grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+
+              // If the grid isn't tall enough to fit a single row, it's kind of useless. Resize it to fit a minimum number of rows
+              if (grid.gridHeight < grid.options.rowHeight) {
+                // Figure out the new height
+                var contentHeight = grid.options.minRowsToShow * grid.options.rowHeight;
+                var headerHeight = grid.options.hideHeader ? 0 : grid.options.headerRowHeight;
+                var footerHeight = grid.options.showFooter ? grid.options.footerRowHeight : 0;
+                var scrollbarHeight = grid.options.enableScrollbars ? gridUtil.getScrollbarWidth() : 0;
+
+                var maxNumberOfFilters = 0;
+                // Calculates the maximum number of filters in the columns
+                angular.forEach(grid.options.columnDefs, function(col) {
+                  if (col.hasOwnProperty('filter')) {
+                    if (maxNumberOfFilters < 1) {
+                        maxNumberOfFilters = 1;
+                    }
+                  }
+                  else if (col.hasOwnProperty('filters')) {
+                    if (maxNumberOfFilters < col.filters.length) {
+                        maxNumberOfFilters = col.filters.length;
+                    }
+                  }
+                });
+                var filterHeight = maxNumberOfFilters * headerHeight;
+
+                var newHeight = headerHeight + contentHeight + footerHeight + scrollbarHeight + filterHeight;
+
+                $elm.css('height', newHeight + 'px');
+
+                grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+              }
+
+              // Run initial canvas refresh
+              grid.refreshCanvas();
+
+              //add pinned containers for row headers support
+              //moved from pinning feature
+              var left = angular.element('<div ng-if="grid.hasLeftContainer()" style="width: 0" ui-grid-pinned-container="\'left\'"></div>');
+              $elm.prepend(left);
+              uiGridCtrl.innerCompile(left);
+
+              var right = angular.element('<div  ng-if="grid.hasRightContainer()" style="width: 0" ui-grid-pinned-container="\'right\'"></div>');
+              $elm.append(right);
+              uiGridCtrl.innerCompile(right);
+
+
+              //if we add a left container after render, we need to watch and react
+              $scope.$watch(function () { return grid.hasLeftContainer();}, function (newValue, oldValue) {
+                if (newValue === oldValue) {
+                  return;
+                }
+
+                //todo: remove this code.  it was commented out after moving from pinning because body is already float:left
+//                var bodyContainer = angular.element($elm[0].querySelectorAll('[container-id="body"]'));
+//                if (newValue){
+//                  bodyContainer.attr('style', 'float: left; position: inherit');
+//                }
+//                else {
+//                  bodyContainer.attr('style', 'float: left; position: relative');
+//                }
+
+                grid.refreshCanvas(true);
+              });
+
+              //if we add a right container after render, we need to watch and react
+              $scope.$watch(function () { return grid.hasRightContainer();}, function (newValue, oldValue) {
+                if (newValue === oldValue) {
+                  return;
+                }
+                grid.refreshCanvas(true);
+              });
+
+
+              // Resize the grid on window resize events
+              function gridResize($event) {
+                grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
+                grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
+
+                grid.queueRefresh();
+              }
+
+              angular.element($window).on('resize', gridResize);
+
+              // Unbind from window resize events when the grid is destroyed
+              $elm.on('$destroy', function () {
+                angular.element($window).off('resize', gridResize);
+              });
+            }
+          };
+        }
+      };
+    }
+  ]);
+
+})();
+
+(function(){
+  'use strict';
+
+  angular.module('ui.grid').directive('uiGridPinnedContainer', ['gridUtil', function (gridUtil) {
+    return {
+      restrict: 'EA',
+      replace: true,
+      template: '<div class="ui-grid-pinned-container"><div ui-grid-render-container container-id="side" row-container-name="\'body\'" col-container-name="side" bind-scroll-vertical="true" class="{{ side }} ui-grid-render-container-{{ side }}"></div></div>',
+      scope: {
+        side: '=uiGridPinnedContainer'
+      },
+      require: '^uiGrid',
+      compile: function compile() {
+        return {
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            // gridUtil.logDebug('ui-grid-pinned-container ' + $scope.side + ' link');
+
+            var grid = uiGridCtrl.grid;
+
+            var myWidth = 0;
+
+            $elm.addClass('ui-grid-pinned-container-' + $scope.side);
+
+            function updateContainerWidth() {
+              if ($scope.side === 'left' || $scope.side === 'right') {
+                var cols = grid.renderContainers[$scope.side].visibleColumnCache;
+                var width = 0;
+                for (var i = 0; i < cols.length; i++) {
+                  var col = cols[i];
+                  width += col.drawnWidth;
+                }
+
+                myWidth = width;
+              }              
+            }
+            
+            function updateContainerDimensions() {
+              // gridUtil.logDebug('update ' + $scope.side + ' dimensions');
+
+              var ret = '';
+              
+              // Column containers
+              if ($scope.side === 'left' || $scope.side === 'right') {
+                updateContainerWidth();
+
+                // gridUtil.logDebug('myWidth', myWidth);
+
+                // TODO(c0bra): Subtract sum of col widths from grid viewport width and update it
+                $elm.attr('style', null);
+
+                var myHeight = grid.renderContainers.body.getViewportHeight(); // + grid.horizontalScrollbarHeight;
+
+                ret += '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ', .grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ' .ui-grid-render-container-' + $scope.side + ' .ui-grid-viewport { width: ' + myWidth + 'px; height: ' + myHeight + 'px; } ';
+              }
+
+              return ret;
+            }
+
+            grid.renderContainers.body.registerViewportAdjuster(function (adjustment) {
+              if ( myWidth === 0 ){
+                updateContainerWidth();
+              }
+              // Subtract our own width
+              adjustment.width -= myWidth;
+
+              return adjustment;
+            });
+
+            // Register style computation to adjust for columns in `side`'s render container
+            grid.registerStyleComputation({
+              priority: 15,
+              func: updateContainerDimensions
+            });
+          }
+        };
+      }
+    };
+  }]);
+})();
+(function(){
+
+angular.module('ui.grid')
+.factory('Grid', ['$q', '$compile', '$parse', 'gridUtil', 'uiGridConstants', 'GridOptions', 'GridColumn', 'GridRow', 'GridApi', 'rowSorter', 'rowSearcher', 'GridRenderContainer', '$timeout',
+    function($q, $compile, $parse, gridUtil, uiGridConstants, GridOptions, GridColumn, GridRow, GridApi, rowSorter, rowSearcher, GridRenderContainer, $timeout) {
+
+/**
+ * @ngdoc object
+ * @name ui.grid.core.api:PublicApi
+ * @description Public Api for the core grid features
+ *
+ */
+
+/**
+   * @ngdoc function
+   * @name ui.grid.class:Grid
+   * @description Grid is the main viewModel.  Any properties or methods needed to maintain state are defined in
+ * * this prototype.  One instance of Grid is created per Grid directive instance.
+   * @param {object} options Object map of options to pass into the grid. An 'id' property is expected.
+   */
+  var Grid = function Grid(options) {
+    var self = this;
+  // Get the id out of the options, then remove it
+  if (options !== undefined && typeof(options.id) !== 'undefined' && options.id) {
+    if (!/^[_a-zA-Z0-9-]+$/.test(options.id)) {
+      throw new Error("Grid id '" + options.id + '" is invalid. It must follow CSS selector syntax rules.');
+    }
+  }
+  else {
+    throw new Error('No ID provided. An ID must be given when creating a grid.');
+  }
+
+  self.id = options.id;
+  delete options.id;
+
+  // Get default options
+  self.options = GridOptions.initialize( options );
+
+  self.headerHeight = self.options.headerRowHeight;
+  self.footerHeight = self.options.showFooter === true ? self.options.footerRowHeight : 0;
+
+  self.rtl = false;
+  self.gridHeight = 0;
+  self.gridWidth = 0;
+  self.columnBuilders = [];
+  self.rowBuilders = [];
+  self.rowsProcessors = [];
+  self.columnsProcessors = [];
+  self.styleComputations = [];
+  self.viewportAdjusters = [];
+  self.rowHeaderColumns = [];
+  self.dataChangeCallbacks = {};
+
+  // self.visibleRowCache = [];
+
+  // Set of 'render' containers for self grid, which can render sets of rows
+  self.renderContainers = {};
+
+  // Create a
+  self.renderContainers.body = new GridRenderContainer('body', self);
+
+  self.cellValueGetterCache = {};
+
+  // Cached function to use with custom row templates
+  self.getRowTemplateFn = null;
+
+
+  //representation of the rows on the grid.
+  //these are wrapped references to the actual data rows (options.data)
+  self.rows = [];
+
+  //represents the columns on the grid
+  self.columns = [];
+
+  /**
+   * @ngdoc boolean
+   * @name isScrollingVertically
+   * @propertyOf ui.grid.class:Grid
+   * @description set to true when Grid is scrolling vertically. Set to false via debounced method
+   */
+  self.isScrollingVertically = false;
+
+  /**
+   * @ngdoc boolean
+   * @name isScrollingHorizontally
+   * @propertyOf ui.grid.class:Grid
+   * @description set to true when Grid is scrolling horizontally. Set to false via debounced method
+   */
+  self.isScrollingHorizontally = false;
+
+  var debouncedVertical = gridUtil.debounce(function () {
+    self.isScrollingVertically = false;
+  }, 300);
+
+  var debouncedHorizontal = gridUtil.debounce(function () {
+    self.isScrollingHorizontally = false;
+  }, 300);
+
+
+  /**
+   * @ngdoc function
+   * @name flagScrollingVertically
+   * @methodOf ui.grid.class:Grid
+   * @description sets isScrollingVertically to true and sets it to false in a debounced function
+   */
+  self.flagScrollingVertically = function() {
+    self.isScrollingVertically = true;
+    debouncedVertical();
+  };
+
+  /**
+   * @ngdoc function
+   * @name flagScrollingHorizontally
+   * @methodOf ui.grid.class:Grid
+   * @description sets isScrollingHorizontally to true and sets it to false in a debounced function
+   */
+  self.flagScrollingHorizontally = function() {
+    self.isScrollingHorizontally = true;
+    debouncedHorizontal();
+  };
+
+
+
+  self.api = new GridApi(self);
+
+  /**
+   * @ngdoc function
+   * @name refresh
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Refresh the rendered grid on screen.
+   * 
+   */
+  self.api.registerMethod( 'core', 'refresh', this.refresh );
+
+  /**
+   * @ngdoc function
+   * @name refreshRows
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Refresh the rendered grid on screen?  Note: not functional at present
+   * @returns {promise} promise that is resolved when render completes?
+   * 
+   */
+  self.api.registerMethod( 'core', 'refreshRows', this.refreshRows );
+
+  /**
+   * @ngdoc function
+   * @name handleWindowResize
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Trigger a grid resize, normally this would be picked
+   * up by a watch on window size, but in some circumstances it is necessary
+   * to call this manually
+   * @returns {promise} promise that is resolved when render completes?
+   * 
+   */
+  self.api.registerMethod( 'core', 'handleWindowResize', this.handleWindowResize );
+
+
+  /**
+   * @ngdoc function
+   * @name addRowHeaderColumn
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description adds a row header column to the grid
+   * @param {object} column def
+   * 
+   */
+  self.api.registerMethod( 'core', 'addRowHeaderColumn', this.addRowHeaderColumn );
+
+
+  /**
+   * @ngdoc function
+   * @name sortHandleNulls
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description A null handling method that can be used when building custom sort
+   * functions
+   * @example
+   * <pre>
+   *   mySortFn = function(a, b) {
+   *   var nulls = $scope.gridApi.core.sortHandleNulls(a, b);
+   *   if ( nulls !== null ){
+   *     return nulls;
+   *   } else {
+   *     // your code for sorting here
+   *   };
+   * </pre>
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} null if there were no nulls/undefineds, otherwise returns
+   * a sort value that should be passed back from the sort function
+   * 
+   */
+  self.api.registerMethod( 'core', 'sortHandleNulls', rowSorter.handleNulls );
+
+
+  /**
+   * @ngdoc function
+   * @name sortChanged
+   * @methodOf  ui.grid.core.api:PublicApi
+   * @description The sort criteria on one or more columns has
+   * changed.  Provides as parameters the grid and the output of
+   * getColumnSorting, which is an array of gridColumns
+   * that have sorting on them, sorted in priority order. 
+   * 
+   * @param {Grid} grid the grid
+   * @param {array} sortColumns an array of columns with 
+   * sorts on them, in priority order
+   * 
+   * @example
+   * <pre>
+   *      gridApi.core.on.sortChanged( grid, sortColumns );
+   * </pre>
+   */
+  self.api.registerEvent( 'core', 'sortChanged' );
+
+  /**
+   * @ngdoc method
+   * @name notifyDataChange
+   * @methodOf ui.grid.core.api:PublicApi
+   * @description Notify the grid that a data or config change has occurred,
+   * where that change isn't something the grid was otherwise noticing.  This 
+   * might be particularly relevant where you've changed values within the data
+   * and you'd like cell classes to be re-evaluated, or changed config within 
+   * the columnDef and you'd like headerCellClasses to be re-evaluated.
+   * @param {Grid} grid the grid
+   * @param {string} type one of the 
+   * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN), which tells
+   * us which refreshes to fire.
+   * 
+   */
+  self.api.registerMethod( 'core', 'notifyDataChange', this.notifyDataChange );
+  
+  self.registerDataChangeCallback( self.columnRefreshCallback, [uiGridConstants.dataChange.COLUMN]);
+  self.registerDataChangeCallback( self.processRowsCallback, [uiGridConstants.dataChange.EDIT]);
+};
+
+    /**
+     * @ngdoc function
+     * @name isRTL
+     * @methodOf ui.grid.class:Grid
+     * @description Returns true if grid is RightToLeft
+     */
+    Grid.prototype.isRTL = function () {
+      return this.rtl;
+    };
+
+
+      /**
+   * @ngdoc function
+   * @name registerColumnBuilder
+   * @methodOf ui.grid.class:Grid
+   * @description When the build creates columns from column definitions, the columnbuilders will be called to add
+   * additional properties to the column.
+   * @param {function(colDef, col, gridOptions)} columnsProcessor function to be called
+   */
+  Grid.prototype.registerColumnBuilder = function registerColumnBuilder(columnBuilder) {
+    this.columnBuilders.push(columnBuilder);
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildColumnDefsFromData
+   * @methodOf ui.grid.class:Grid
+   * @description Populates columnDefs from the provided data
+   * @param {function(colDef, col, gridOptions)} rowBuilder function to be called
+   */
+  Grid.prototype.buildColumnDefsFromData = function (dataRows){
+    this.options.columnDefs =  gridUtil.getColumnsFromData(dataRows,  this.options.excludeProperties);
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerRowBuilder
+   * @methodOf ui.grid.class:Grid
+   * @description When the build creates rows from gridOptions.data, the rowBuilders will be called to add
+   * additional properties to the row.
+   * @param {function(row, gridOptions)} rowBuilder function to be called
+   */
+  Grid.prototype.registerRowBuilder = function registerRowBuilder(rowBuilder) {
+    this.rowBuilders.push(rowBuilder);
+  };
+
+
+  /**
+   * @ngdoc function
+   * @name registerDataChangeCallback
+   * @methodOf ui.grid.class:Grid
+   * @description When a data change occurs, the data change callbacks of the specified type
+   * will be called.  The rules are:
+   * 
+   * - when the data watch fires, that is considered a ROW change (the data watch only notices
+   *   added or removed rows)
+   * - when the api is called to inform us of a change, the declared type of that change is used
+   * - when a cell edit completes, the EDIT callbacks are triggered
+   * - when the columnDef watch fires, the COLUMN callbacks are triggered
+   * 
+   * For a given event:
+   * - ALL calls ROW, EDIT, COLUMN and ALL callbacks
+   * - ROW calls ROW and ALL callbacks
+   * - EDIT calls EDIT and ALL callbacks
+   * - COLUMN calls COLUMN and ALL callbacks
+   * 
+   * @param {function(grid)} callback function to be called
+   * @param {array} types the types of data change you want to be informed of.  Values from 
+   * the uiGridConstants.dataChange values ( ALL, EDIT, ROW, COLUMN ).  Optional and defaults to
+   * ALL 
+   * @returns {string} uid of the callback, can be used to deregister it again
+   */
+  Grid.prototype.registerDataChangeCallback = function registerDataChangeCallback(callback, types) {
+    var uid = gridUtil.nextUid();
+    if ( !types ){
+      types = [uiGridConstants.dataChange.ALL];
+    }
+    if ( !Array.isArray(types)){
+      gridUtil.logError("Expected types to be an array or null in registerDataChangeCallback, value passed was: " + types );
+    }
+    this.dataChangeCallbacks[uid] = { callback: callback, types: types };
+    return uid;
+  };
+
+  /**
+   * @ngdoc function
+   * @name deregisterDataChangeCallback
+   * @methodOf ui.grid.class:Grid
+   * @description Delete the callback identified by the id.
+   * @param {string} uid the uid of the function that is to be deregistered
+   */
+  Grid.prototype.deregisterDataChangeCallback = function deregisterDataChangeCallback(uid) {
+    delete this.dataChangeCallbacks[uid];
+  };
+
+  /**
+   * @ngdoc function
+   * @name callDataChangeCallbacks
+   * @methodOf ui.grid.class:Grid
+   * @description Calls the callbacks based on the type of data change that
+   * has occurred. Always calls the ALL callbacks, calls the ROW, EDIT, and COLUMN callbacks if the 
+   * event type is matching, or if the type is ALL.
+   * @param {number} type the type of event that occurred - one of the 
+   * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN)
+   */
+  Grid.prototype.callDataChangeCallbacks = function callDataChangeCallbacks(type, options) {
+    angular.forEach( this.dataChangeCallbacks, function( callback, uid ){
+      if ( callback.types.indexOf( uiGridConstants.dataChange.ALL ) !== -1 ||
+           callback.types.indexOf( type ) !== -1 ||
+           type === uiGridConstants.dataChange.ALL ) {
+        callback.callback( this );
+      }
+    }, this);
+  };
+  
+  /**
+   * @ngdoc function
+   * @name notifyDataChange
+   * @methodOf ui.grid.class:Grid
+   * @description Notifies us that a data change has occurred, used in the public
+   * api for users to tell us when they've changed data or some other event that 
+   * our watches cannot pick up
+   * @param {Grid} grid the grid
+   * @param {string} type the type of event that occurred - one of the 
+   * uiGridConstants.dataChange values (ALL, ROW, EDIT, COLUMN)
+   */
+  Grid.prototype.notifyDataChange = function notifyDataChange(grid, type) {
+    var constants = uiGridConstants.dataChange;
+    if ( type === constants.ALL || 
+         type === constants.COLUMN ||
+         type === constants.EDIT ||
+         type === constants.ROW ){
+      grid.callDataChangeCallbacks( type );
+    } else {
+      gridUtil.logError("Notified of a data change, but the type was not recognised, so no action taken, type was: " + type);
+    }
+  };
+  
+  
+  /**
+   * @ngdoc function
+   * @name columnRefreshCallback
+   * @methodOf ui.grid.class:Grid
+   * @description refreshes the grid when a column refresh
+   * is notified, which triggers handling of the visible flag. 
+   * This is called on uiGridConstants.dataChange.COLUMN, and is 
+   * registered as a dataChangeCallback in grid.js
+   * @param {string} name column name
+   */
+  Grid.prototype.columnRefreshCallback = function columnRefreshCallback( grid ){
+    grid.refresh();
+  };
+    
+
+  /**
+   * @ngdoc function
+   * @name processRowsCallback
+   * @methodOf ui.grid.class:Grid
+   * @description calls the row processors, specifically
+   * intended to reset the sorting when an edit is called,
+   * registered as a dataChangeCallback on uiGridConstants.dataChange.EDIT
+   * @param {string} name column name
+   */
+  Grid.prototype.processRowsCallback = function processRowsCallback( grid ){
+    grid.refreshRows();
+  };
+    
+
+  /**
+   * @ngdoc function
+   * @name getColumn
+   * @methodOf ui.grid.class:Grid
+   * @description returns a grid column for the column name
+   * @param {string} name column name
+   */
+  Grid.prototype.getColumn = function getColumn(name) {
+    var columns = this.columns.filter(function (column) {
+      return column.colDef.name === name;
+    });
+    return columns.length > 0 ? columns[0] : null;
+  };
+
+  /**
+   * @ngdoc function
+   * @name getColDef
+   * @methodOf ui.grid.class:Grid
+   * @description returns a grid colDef for the column name
+   * @param {string} name column.field
+   */
+  Grid.prototype.getColDef = function getColDef(name) {
+    var colDefs = this.options.columnDefs.filter(function (colDef) {
+      return colDef.name === name;
+    });
+    return colDefs.length > 0 ? colDefs[0] : null;
+  };
+
+  /**
+   * @ngdoc function
+   * @name assignTypes
+   * @methodOf ui.grid.class:Grid
+   * @description uses the first row of data to assign colDef.type for any types not defined.
+   */
+  /**
+   * @ngdoc property
+   * @name type
+   * @propertyOf ui.grid.class:GridOptions.columnDef
+   * @description the type of the column, used in sorting.  If not provided then the 
+   * grid will guess the type.  Add this only if the grid guessing is not to your
+   * satisfaction.  Refer to {@link ui.grid.service:GridUtil.guessType gridUtil.guessType} for
+   * a list of values the grid knows about.
+   *
+   */
+  Grid.prototype.assignTypes = function(){
+    var self = this;
+    self.options.columnDefs.forEach(function (colDef, index) {
+
+      //Assign colDef type if not specified
+      if (!colDef.type) {
+        var col = new GridColumn(colDef, index, self);
+        var firstRow = self.rows.length > 0 ? self.rows[0] : null;
+        if (firstRow) {
+          colDef.type = gridUtil.guessType(self.getCellValue(firstRow, col));
+        }
+        else {
+          gridUtil.logWarn('Unable to assign type from data, so defaulting to string');
+          colDef.type = 'string';
+        }
+      }
+    });
+  };
+
+  /**
+  * @ngdoc function
+  * @name addRowHeaderColumn
+  * @methodOf ui.grid.class:Grid
+  * @description adds a row header column to the grid
+  * @param {object} column def
+  */
+  Grid.prototype.addRowHeaderColumn = function addRowHeaderColumn(colDef) {
+    var self = this;
+    //self.createLeftContainer();
+    var rowHeaderCol = new GridColumn(colDef, self.rowHeaderColumns.length, self);
+    rowHeaderCol.isRowHeader = true;
+    if (self.isRTL()) {
+      self.createRightContainer();
+      rowHeaderCol.renderContainer = 'right';
+    }
+    else {
+      self.createLeftContainer();
+      rowHeaderCol.renderContainer = 'left';
+    }
+
+    // relies on the default column builder being first in array, as it is instantiated
+    // as part of grid creation
+    self.columnBuilders[0](colDef,rowHeaderCol,self.options)
+      .then(function(){
+        rowHeaderCol.enableFiltering = false;
+        rowHeaderCol.enableSorting = false;
+        rowHeaderCol.enableHiding = false;
+        self.rowHeaderColumns.push(rowHeaderCol);
+        self.buildColumns()
+          .then( function() {
+            self.preCompileCellTemplates();
+            self.handleWindowResize();
+          });
+      });
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildColumns
+   * @methodOf ui.grid.class:Grid
+   * @description creates GridColumn objects from the columnDefinition.  Calls each registered
+   * columnBuilder to further process the column
+   * @returns {Promise} a promise to load any needed column resources
+   */
+  Grid.prototype.buildColumns = function buildColumns() {
+    // gridUtil.logDebug('buildColumns');
+    var self = this;
+    var builderPromises = [];
+    var headerOffset = self.rowHeaderColumns.length;
+    var i;
+
+    // Remove any columns for which a columnDef cannot be found
+    // Deliberately don't use forEach, as it doesn't like splice being called in the middle
+    // Also don't cache columns.length, as it will change during this operation
+    for (i = 0; i < self.columns.length; i++){
+      if (!self.getColDef(self.columns[i].name)) {
+        self.columns.splice(i, 1);
+        i--;
+      }
+    }
+
+    //add row header columns to the grid columns array _after_ columns without columnDefs have been removed
+    self.rowHeaderColumns.forEach(function (rowHeaderColumn) {
+      self.columns.unshift(rowHeaderColumn);
+    });
+
+
+    // look at each column def, and update column properties to match.  If the column def
+    // doesn't have a column, then splice in a new gridCol
+    self.options.columnDefs.forEach(function (colDef, index) {
+      self.preprocessColDef(colDef);
+      var col = self.getColumn(colDef.name);
+
+      if (!col) {
+        col = new GridColumn(colDef, gridUtil.nextUid(), self);
+        self.columns.splice(index + headerOffset, 0, col);
+      }
+      else {
+        col.updateColumnDef(colDef);
+      }
+
+      self.columnBuilders.forEach(function (builder) {
+        builderPromises.push(builder.call(self, colDef, col, self.options));
+      });
+    });
+    
+    return $q.all(builderPromises);
+  };
+
+/**
+ * @ngdoc function
+ * @name preCompileCellTemplates
+ * @methodOf ui.grid.class:Grid
+ * @description precompiles all cell templates
+ */
+  Grid.prototype.preCompileCellTemplates = function() {
+    var self = this;
+    this.columns.forEach(function (col) {
+      var html = col.cellTemplate.replace(uiGridConstants.MODEL_COL_FIELD, self.getQualifiedColField(col));
+      html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)');
+
+
+      var compiledElementFn = $compile(html);
+      col.compiledElementFn = compiledElementFn;
+
+      if (col.compiledElementFnDefer) {
+        col.compiledElementFnDefer.resolve(col.compiledElementFn);
+      }
+    });
+  };
+
+  /**
+   * @ngdoc function
+   * @name getGridQualifiedColField
+   * @methodOf ui.grid.class:Grid
+   * @description Returns the $parse-able accessor for a column within its $scope
+   * @param {GridColumn} col col object
+   */
+  Grid.prototype.getQualifiedColField = function (col) {
+    return 'row.entity.' + gridUtil.preEval(col.field);
+  };
+
+  /**
+   * @ngdoc function
+   * @name createLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description creates the left render container if it doesn't already exist
+   */
+  Grid.prototype.createLeftContainer = function() {
+    if (!this.hasLeftContainer()) {
+      this.renderContainers.left = new GridRenderContainer('left', this, { disableColumnOffset: true });
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name createRightContainer
+   * @methodOf ui.grid.class:Grid
+   * @description creates the right render container if it doesn't already exist
+   */
+  Grid.prototype.createRightContainer = function() {
+    if (!this.hasRightContainer()) {
+      this.renderContainers.right = new GridRenderContainer('right', this, { disableColumnOffset: true });
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name hasLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description returns true if leftContainer exists
+   */
+  Grid.prototype.hasLeftContainer = function() {
+    return this.renderContainers.left !== undefined;
+  };
+
+  /**
+   * @ngdoc function
+   * @name hasLeftContainer
+   * @methodOf ui.grid.class:Grid
+   * @description returns true if rightContainer exists
+   */
+  Grid.prototype.hasRightContainer = function() {
+    return this.renderContainers.right !== undefined;
+  };
+
+
+      /**
+   * undocumented function
+   * @name preprocessColDef
+   * @methodOf ui.grid.class:Grid
+   * @description defaults the name property from field to maintain backwards compatibility with 2.x
+   * validates that name or field is present
+   */
+  Grid.prototype.preprocessColDef = function preprocessColDef(colDef) {
+    if (!colDef.field && !colDef.name) {
+      throw new Error('colDef.name or colDef.field property is required');
+    }
+
+    //maintain backwards compatibility with 2.x
+    //field was required in 2.x.  now name is required
+    if (colDef.name === undefined && colDef.field !== undefined) {
+      colDef.name = colDef.field;
+    }
+
+  };
+
+  // Return a list of items that exist in the `n` array but not the `o` array. Uses optional property accessors passed as third & fourth parameters
+  Grid.prototype.newInN = function newInN(o, n, oAccessor, nAccessor) {
+    var self = this;
+
+    var t = [];
+    for (var i = 0; i < n.length; i++) {
+      var nV = nAccessor ? n[i][nAccessor] : n[i];
+      
+      var found = false;
+      for (var j = 0; j < o.length; j++) {
+        var oV = oAccessor ? o[j][oAccessor] : o[j];
+        if (self.options.rowEquality(nV, oV)) {
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        t.push(nV);
+      }
+    }
+    
+    return t;
+  };
+
+    /**
+     * @ngdoc function
+     * @name getRow
+     * @methodOf ui.grid.class:Grid
+     * @description returns the GridRow that contains the rowEntity
+     * @param {object} rowEntity the gridOptions.data array element instance
+     */
+    Grid.prototype.getRow = function getRow(rowEntity) {
+      var rows = this.rows.filter(function (row) {
+        return row.entity === rowEntity;
+      });
+      return rows.length > 0 ? rows[0] : null;
+    };
+
+
+      /**
+   * @ngdoc function
+   * @name modifyRows
+   * @methodOf ui.grid.class:Grid
+   * @description creates or removes GridRow objects from the newRawData array.  Calls each registered
+   * rowBuilder to further process the row
+   *
+   * Rows are identified using the gridOptions.rowEquality function
+   */
+  Grid.prototype.modifyRows = function modifyRows(newRawData) {
+    var self = this,
+        i,
+        rowhash,
+        found,
+        newRow;
+    if ((self.options.useExternalSorting || self.getColumnSorting().length === 0) && newRawData.length > 0) {
+        var oldRowHash = self.rowHashMap;
+        if (!oldRowHash) {
+           oldRowHash = {get: function(){return null;}};
+        }
+        self.createRowHashMap();
+        rowhash = self.rowHashMap;
+        var wasEmpty = self.rows.length === 0;
+        self.rows.length = 0;
+        for (i = 0; i < newRawData.length; i++) {
+            var newRawRow = newRawData[i];
+            found = oldRowHash.get(newRawRow);
+            if (found) {
+              newRow = found.row; 
+            }
+            else {
+              newRow = self.processRowBuilders(new GridRow(newRawRow, i, self));
+            }
+            self.rows.push(newRow);
+            rowhash.put(newRawRow, {
+                i: i,
+                entity: newRawRow,
+                row:newRow
+            });
+        }
+        //now that we have data, it is save to assign types to colDefs
+        if (wasEmpty) {
+           self.assignTypes();
+        }
+    } else {
+    if (self.rows.length === 0 && newRawData.length > 0) {
+      if (self.options.enableRowHashing) {
+        if (!self.rowHashMap) {
+          self.createRowHashMap();
+        }
+
+        for (i = 0; i < newRawData.length; i++) {
+          newRow = newRawData[i];
+
+          self.rowHashMap.put(newRow, {
+            i: i,
+            entity: newRow
+          });
+        }
+      }
+
+      self.addRows(newRawData);
+      //now that we have data, it is save to assign types to colDefs
+      self.assignTypes();
+    }
+    else if (newRawData.length > 0) {
+      var unfoundNewRows, unfoundOldRows, unfoundNewRowsToFind;
+
+      // If row hashing is turned on
+      if (self.options.enableRowHashing) {
+        // Array of new rows that haven't been found in the old rowset
+        unfoundNewRows = [];
+        // Array of new rows that we explicitly HAVE to search for manually in the old row set. They cannot be looked up by their identity (because it doesn't exist).
+        unfoundNewRowsToFind = [];
+        // Map of rows that have been found in the new rowset
+        var foundOldRows = {};
+        // Array of old rows that have NOT been found in the new rowset
+        unfoundOldRows = [];
+
+        // Create the row HashMap if it doesn't exist already
+        if (!self.rowHashMap) {
+          self.createRowHashMap();
+        }
+        rowhash = self.rowHashMap;
+        
+        // Make sure every new row has a hash
+        for (i = 0; i < newRawData.length; i++) {
+          newRow = newRawData[i];
+
+          // Flag this row as needing to be manually found if it didn't come in with a $$hashKey
+          var mustFind = false;
+          if (!self.options.getRowIdentity(newRow)) {
+            mustFind = true;
+          }
+
+          // See if the new row is already in the rowhash
+          found = rowhash.get(newRow);
+          // If so...
+          if (found) {
+            // See if it's already being used by as GridRow
+            if (found.row) {
+              // If so, mark this new row as being found
+              foundOldRows[self.options.rowIdentity(newRow)] = true;
+            }
+          }
+          else {
+            // Put the row in the hashmap with the index it corresponds to
+            rowhash.put(newRow, {
+              i: i,
+              entity: newRow
+            });
+            
+            // This row has to be searched for manually in the old row set
+            if (mustFind) {
+              unfoundNewRowsToFind.push(newRow);
+            }
+            else {
+              unfoundNewRows.push(newRow);
+            }
+          }
+        }
+
+        // Build the list of unfound old rows
+        for (i = 0; i < self.rows.length; i++) {
+          var row = self.rows[i];
+          var hash = self.options.rowIdentity(row.entity);
+          if (!foundOldRows[hash]) {
+            unfoundOldRows.push(row);
+          }
+        }
+      }
+
+      // Look for new rows
+      var newRows = unfoundNewRows || [];
+
+      // The unfound new rows is either `unfoundNewRowsToFind`, if row hashing is turned on, or straight `newRawData` if it isn't
+      var unfoundNew = (unfoundNewRowsToFind || newRawData);
+
+      // Search for real new rows in `unfoundNew` and concat them onto `newRows`
+      newRows = newRows.concat(self.newInN(self.rows, unfoundNew, 'entity'));
+      
+      self.addRows(newRows); 
+      
+      var deletedRows = self.getDeletedRows((unfoundOldRows || self.rows), newRawData);
+
+      for (i = 0; i < deletedRows.length; i++) {
+        if (self.options.enableRowHashing) {
+          self.rowHashMap.remove(deletedRows[i].entity);
+        }
+
+        self.rows.splice( self.rows.indexOf(deletedRows[i]), 1 );
+      }
+    }
+    // Empty data set
+    else {
+      // Reset the row HashMap
+      self.createRowHashMap();
+
+      // Reset the rows length!
+      self.rows.length = 0;
+    }
+    }
+    
+    var p1 = $q.when(self.processRowsProcessors(self.rows))
+      .then(function (renderableRows) {
+        return self.setVisibleRows(renderableRows);
+      });
+
+    var p2 = $q.when(self.processColumnsProcessors(self.columns))
+      .then(function (renderableColumns) {
+        return self.setVisibleColumns(renderableColumns);
+      });
+
+    return $q.all([p1, p2]);
+  };
+
+  Grid.prototype.getDeletedRows = function(oldRows, newRows) {
+    var self = this;
+
+    var olds = oldRows.filter(function (oldRow) {
+      return !newRows.some(function (newItem) {
+        return self.options.rowEquality(newItem, oldRow.entity);
+      });
+    });
+    // var olds = self.newInN(newRows, oldRows, null, 'entity');
+    // dump('olds', olds);
+    return olds;
+  };
+
+  /**
+   * Private Undocumented Method
+   * @name addRows
+   * @methodOf ui.grid.class:Grid
+   * @description adds the newRawData array of rows to the grid and calls all registered
+   * rowBuilders. this keyword will reference the grid
+   */
+  Grid.prototype.addRows = function addRows(newRawData) {
+    var self = this;
+
+    var existingRowCount = self.rows.length;
+    for (var i = 0; i < newRawData.length; i++) {
+      var newRow = self.processRowBuilders(new GridRow(newRawData[i], i + existingRowCount, self));
+
+      if (self.options.enableRowHashing) {
+        var found = self.rowHashMap.get(newRow.entity);
+        if (found) {
+          found.row = newRow;
+        }
+      }
+
+      self.rows.push(newRow);
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name processRowBuilders
+   * @methodOf ui.grid.class:Grid
+   * @description processes all RowBuilders for the gridRow
+   * @param {GridRow} gridRow reference to gridRow
+   * @returns {GridRow} the gridRow with all additional behavior added
+   */
+  Grid.prototype.processRowBuilders = function processRowBuilders(gridRow) {
+    var self = this;
+
+    self.rowBuilders.forEach(function (builder) {
+      builder.call(self, gridRow, self.options);
+    });
+
+    return gridRow;
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerStyleComputation
+   * @methodOf ui.grid.class:Grid
+   * @description registered a styleComputation function
+   * 
+   * If the function returns a value it will be appended into the grid's `<style>` block
+   * @param {function($scope)} styleComputation function
+   */
+  Grid.prototype.registerStyleComputation = function registerStyleComputation(styleComputationInfo) {
+    this.styleComputations.push(styleComputationInfo);
+  };
+
+
+  // NOTE (c0bra): We already have rowBuilders. I think these do exactly the same thing...
+  // Grid.prototype.registerRowFilter = function(filter) {
+  //   // TODO(c0bra): validate filter?
+
+  //   this.rowFilters.push(filter);
+  // };
+
+  // Grid.prototype.removeRowFilter = function(filter) {
+  //   var idx = this.rowFilters.indexOf(filter);
+
+  //   if (typeof(idx) !== 'undefined' && idx !== undefined) {
+  //     this.rowFilters.slice(idx, 1);
+  //   }
+  // };
+  
+  // Grid.prototype.processRowFilters = function(rows) {
+  //   var self = this;
+  //   self.rowFilters.forEach(function (filter) {
+  //     filter.call(self, rows);
+  //   });
+  // };
+
+
+  /**
+   * @ngdoc function
+   * @name registerRowsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableRows)} rows processor function
+   * @returns {Array[GridRow]} Updated renderable rows
+   * @description
+
+     Register a "rows processor" function. When the rows are updated,
+     the grid calls each registered "rows processor", which has a chance
+     to alter the set of rows (sorting, etc) as long as the count is not
+     modified.
+   */
+  Grid.prototype.registerRowsProcessor = function registerRowsProcessor(processor) {
+    if (!angular.isFunction(processor)) {
+      throw 'Attempt to register non-function rows processor: ' + processor;
+    }
+
+    this.rowsProcessors.push(processor);
+  };
+
+  /**
+   * @ngdoc function
+   * @name removeRowsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableRows)} rows processor function
+   * @description Remove a registered rows processor
+   */
+  Grid.prototype.removeRowsProcessor = function removeRowsProcessor(processor) {
+    var idx = this.rowsProcessors.indexOf(processor);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.rowsProcessors.splice(idx, 1);
+    }
+  };
+  
+  /**
+   * Private Undocumented Method
+   * @name processRowsProcessors
+   * @methodOf ui.grid.class:Grid
+   * @param {Array[GridRow]} The array of "renderable" rows
+   * @param {Array[GridColumn]} The array of columns
+   * @description Run all the registered rows processors on the array of renderable rows
+   */
+  Grid.prototype.processRowsProcessors = function processRowsProcessors(renderableRows) {
+    var self = this;
+
+    // Create a shallow copy of the rows so that we can safely sort them without altering the original grid.rows sort order
+    var myRenderableRows = renderableRows.slice(0);
+    
+    // self.rowsProcessors.forEach(function (processor) {
+    //   myRenderableRows = processor.call(self, myRenderableRows, self.columns);
+
+    //   if (!renderableRows) {
+    //     throw "Processor at index " + i + " did not return a set of renderable rows";
+    //   }
+
+    //   if (!angular.isArray(renderableRows)) {
+    //     throw "Processor at index " + i + " did not return an array";
+    //   }
+
+    //   i++;
+    // });
+
+    // Return myRenderableRows with no processing if we have no rows processors 
+    if (self.rowsProcessors.length === 0) {
+      return $q.when(myRenderableRows);
+    }
+  
+    // Counter for iterating through rows processors
+    var i = 0;
+    
+    // Promise for when we're done with all the processors
+    var finished = $q.defer();
+
+    // This function will call the processor in self.rowsProcessors at index 'i', and then
+    //   when done will call the next processor in the list, using the output from the processor
+    //   at i as the argument for 'renderedRowsToProcess' on the next iteration.
+    //  
+    //   If we're at the end of the list of processors, we resolve our 'finished' callback with
+    //   the result.
+    function startProcessor(i, renderedRowsToProcess) {
+      // Get the processor at 'i'
+      var processor = self.rowsProcessors[i];
+
+      // Call the processor, passing in the rows to process and the current columns
+      //   (note: it's wrapped in $q.when() in case the processor does not return a promise)
+      return $q.when( processor.call(self, renderedRowsToProcess, self.columns) )
+        .then(function handleProcessedRows(processedRows) {
+          // Check for errors
+          if (!processedRows) {
+            throw "Processor at index " + i + " did not return a set of renderable rows";
+          }
+
+          if (!angular.isArray(processedRows)) {
+            throw "Processor at index " + i + " did not return an array";
+          }
+
+          // Processor is done, increment the counter
+          i++;
+
+          // If we're not done with the processors, call the next one
+          if (i <= self.rowsProcessors.length - 1) {
+            return startProcessor(i, processedRows);
+          }
+          // We're done! Resolve the 'finished' promise
+          else {
+            finished.resolve(processedRows);
+          }
+        });
+    }
+
+    // Start on the first processor
+    startProcessor(0, myRenderableRows);
+    
+    return finished.promise;
+  };
+
+  Grid.prototype.setVisibleRows = function setVisibleRows(rows) {
+    // gridUtil.logDebug('setVisibleRows');
+
+    var self = this;
+
+    //var newVisibleRowCache = [];
+
+    // Reset all the render container row caches
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      container.visibleRowCache.length = 0;
+    }
+    
+    // rows.forEach(function (row) {
+    for (var ri = 0; ri < rows.length; ri++) {
+      var row = rows[ri];
+
+      // If the row is visible
+      if (row.visible) {
+        // newVisibleRowCache.push(row);
+
+        // If the row has a container specified
+        if (typeof(row.renderContainer) !== 'undefined' && row.renderContainer) {
+          self.renderContainers[row.renderContainer].visibleRowCache.push(row);
+        }
+        // If not, put it into the body container
+        else {
+          self.renderContainers.body.visibleRowCache.push(row);
+        }
+      }
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerColumnsProcessor
+   * @methodOf ui.grid.class:Grid
+   * @param {function(renderableColumns)} rows processor function
+   * @returns {Array[GridColumn]} Updated renderable columns
+   * @description
+
+     Register a "columns processor" function. When the columns are updated,
+     the grid calls each registered "columns processor", which has a chance
+     to alter the set of columns, as long as the count is not modified.
+   */
+  Grid.prototype.registerColumnsProcessor = function registerColumnsProcessor(processor) {
+    if (!angular.isFunction(processor)) {
+      throw 'Attempt to register non-function rows processor: ' + processor;
+    }
+
+    this.columnsProcessors.push(processor);
+  };
+
+  Grid.prototype.removeColumnsProcessor = function removeColumnsProcessor(processor) {
+    var idx = this.columnsProcessors.indexOf(processor);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.columnsProcessors.splice(idx, 1);
+    }
+  };
+
+  Grid.prototype.processColumnsProcessors = function processColumnsProcessors(renderableColumns) {
+    var self = this;
+
+    // Create a shallow copy of the rows so that we can safely sort them without altering the original grid.rows sort order
+    var myRenderableColumns = renderableColumns.slice(0);
+
+    // Return myRenderableRows with no processing if we have no rows processors 
+    if (self.columnsProcessors.length === 0) {
+      return $q.when(myRenderableColumns);
+    }
+  
+    // Counter for iterating through rows processors
+    var i = 0;
+    
+    // Promise for when we're done with all the processors
+    var finished = $q.defer();
+
+    // This function will call the processor in self.rowsProcessors at index 'i', and then
+    //   when done will call the next processor in the list, using the output from the processor
+    //   at i as the argument for 'renderedRowsToProcess' on the next iteration.
+    //  
+    //   If we're at the end of the list of processors, we resolve our 'finished' callback with
+    //   the result.
+    function startProcessor(i, renderedColumnsToProcess) {
+      // Get the processor at 'i'
+      var processor = self.columnsProcessors[i];
+
+      // Call the processor, passing in the rows to process and the current columns
+      //   (note: it's wrapped in $q.when() in case the processor does not return a promise)
+      return $q.when( processor.call(self, renderedColumnsToProcess, self.rows) )
+        .then(function handleProcessedRows(processedColumns) {
+          // Check for errors
+          if (!processedColumns) {
+            throw "Processor at index " + i + " did not return a set of renderable rows";
+          }
+
+          if (!angular.isArray(processedColumns)) {
+            throw "Processor at index " + i + " did not return an array";
+          }
+
+          // Processor is done, increment the counter
+          i++;
+
+          // If we're not done with the processors, call the next one
+          if (i <= self.columnsProcessors.length - 1) {
+            return startProcessor(i, myRenderableColumns);
+          }
+          // We're done! Resolve the 'finished' promise
+          else {
+            finished.resolve(myRenderableColumns);
+          }
+        });
+    }
+
+    // Start on the first processor
+    startProcessor(0, myRenderableColumns);
+    
+    return finished.promise;
+  };
+
+  Grid.prototype.setVisibleColumns = function setVisibleColumns(columns) {
+    // gridUtil.logDebug('setVisibleColumns');
+
+    var self = this;
+
+    // Reset all the render container row caches
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      container.visibleColumnCache.length = 0;
+    }
+
+    for (var ci = 0; ci < columns.length; ci++) {
+      var column = columns[ci];
+
+      // If the column is visible
+      if (column.visible) {
+        // If the column has a container specified
+        if (typeof(column.renderContainer) !== 'undefined' && column.renderContainer) {
+          self.renderContainers[column.renderContainer].visibleColumnCache.push(column);
+        }
+        // If not, put it into the body container
+        else {
+          self.renderContainers.body.visibleColumnCache.push(column);
+        }
+      }
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name handleWindowResize
+   * @methodOf ui.grid.class:Grid
+   * @description Triggered when the browser window resizes; automatically resizes the grid
+   */
+  Grid.prototype.handleWindowResize = function handleWindowResize($event) {
+    var self = this;
+
+    self.gridWidth = gridUtil.elementWidth(self.element);
+    self.gridHeight = gridUtil.elementHeight(self.element);
+
+    self.queueRefresh();
+  };
+
+  /**
+   * @ngdoc function
+   * @name queueRefresh
+   * @methodOf ui.grid.class:Grid
+   * @description todo: @c0bra can you document this method?
+   */
+  Grid.prototype.queueRefresh = function queueRefresh() {
+    var self = this;
+
+    if (self.refreshCanceller) {
+      $timeout.cancel(self.refreshCanceller);
+    }
+
+    self.refreshCanceller = $timeout(function () {
+      self.refreshCanvas(true);
+    });
+
+    self.refreshCanceller.then(function () {
+      self.refreshCanceller = null;
+    });
+
+    return self.refreshCanceller;
+  };
+
+  /**
+   * @ngdoc function
+   * @name buildStyles
+   * @methodOf ui.grid.class:Grid
+   * @description calls each styleComputation function
+   */
+  // TODO: this used to take $scope, but couldn't see that it was used
+  Grid.prototype.buildStyles = function buildStyles() {
+    // gridUtil.logDebug('buildStyles');
+
+    var self = this;
+    
+    self.customStyles = '';
+
+    self.styleComputations
+      .sort(function(a, b) {
+        if (a.priority === null) { return 1; }
+        if (b.priority === null) { return -1; }
+        if (a.priority === null && b.priority === null) { return 0; }
+        return a.priority - b.priority;
+      })
+      .forEach(function (compInfo) {
+        // this used to provide $scope as a second parameter, but I couldn't find any 
+        // style builders that used it, so removed it as part of moving to grid from controller
+        var ret = compInfo.func.call(self);
+
+        if (angular.isString(ret)) {
+          self.customStyles += '\n' + ret;
+        }
+      });
+  };
+
+
+  Grid.prototype.minColumnsToRender = function minColumnsToRender() {
+    var self = this;
+    var viewport = this.getViewportWidth();
+
+    var min = 0;
+    var totalWidth = 0;
+    self.columns.forEach(function(col, i) {
+      if (totalWidth < viewport) {
+        totalWidth += col.drawnWidth;
+        min++;
+      }
+      else {
+        var currWidth = 0;
+        for (var j = i; j >= i - min; j--) {
+          currWidth += self.columns[j].drawnWidth;
+        }
+        if (currWidth < viewport) {
+          min++;
+        }
+      }
+    });
+
+    return min;
+  };
+
+  Grid.prototype.getBodyHeight = function getBodyHeight() {
+    // Start with the viewportHeight
+    var bodyHeight = this.getViewportHeight();
+
+    // Add the horizontal scrollbar height if there is one
+    if (typeof(this.horizontalScrollbarHeight) !== 'undefined' && this.horizontalScrollbarHeight !== undefined && this.horizontalScrollbarHeight > 0) {
+      bodyHeight = bodyHeight + this.horizontalScrollbarHeight;
+    }
+
+    return bodyHeight;
+  };
+
+  // NOTE: viewport drawable height is the height of the grid minus the header row height (including any border)
+  // TODO(c0bra): account for footer height
+  Grid.prototype.getViewportHeight = function getViewportHeight() {
+    var self = this;
+
+    var viewPortHeight = this.gridHeight - this.headerHeight - this.footerHeight;
+
+    // Account for native horizontal scrollbar, if present
+    if (typeof(this.horizontalScrollbarHeight) !== 'undefined' && this.horizontalScrollbarHeight !== undefined && this.horizontalScrollbarHeight > 0) {
+      viewPortHeight = viewPortHeight - this.horizontalScrollbarHeight;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortHeight = viewPortHeight + adjustment.height;
+
+    // gridUtil.logDebug('viewPortHeight', viewPortHeight);
+
+    return viewPortHeight;
+  };
+
+  Grid.prototype.getViewportWidth = function getViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = this.gridWidth;
+
+    if (typeof(this.verticalScrollbarWidth) !== 'undefined' && this.verticalScrollbarWidth !== undefined && this.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth - this.verticalScrollbarWidth;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortWidth = viewPortWidth + adjustment.width;
+
+    // gridUtil.logDebug('getviewPortWidth', viewPortWidth);
+
+    return viewPortWidth;
+  };
+
+  Grid.prototype.getHeaderViewportWidth = function getHeaderViewportWidth() {
+    var viewPortWidth = this.getViewportWidth();
+
+    if (typeof(this.verticalScrollbarWidth) !== 'undefined' && this.verticalScrollbarWidth !== undefined && this.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth + this.verticalScrollbarWidth;
+    }
+
+    return viewPortWidth;
+  };
+
+  Grid.prototype.registerViewportAdjuster = function registerViewportAdjuster(func) {
+    this.viewportAdjusters.push(func);
+  };
+
+  Grid.prototype.removeViewportAdjuster = function registerViewportAdjuster(func) {
+    var idx = this.viewportAdjusters.indexOf(func);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.viewportAdjusters.splice(idx, 1);
+    }
+  };
+
+  Grid.prototype.getViewportAdjustment = function getViewportAdjustment() {
+    var self = this;
+
+    var adjustment = { height: 0, width: 0 };
+
+    self.viewportAdjusters.forEach(function (func) {
+      adjustment = func.call(this, adjustment);
+    });
+
+    return adjustment;
+  };
+
+  Grid.prototype.getVisibleRowCount = function getVisibleRowCount() {
+    // var count = 0;
+
+    // this.rows.forEach(function (row) {
+    //   if (row.visible) {
+    //     count++;
+    //   }
+    // });
+
+    // return this.visibleRowCache.length;
+    return this.renderContainers.body.visibleRowCache.length;
+  };
+
+   Grid.prototype.getVisibleRows = function getVisibleRows() {
+    return this.renderContainers.body.visibleRowCache;
+   };
+
+  Grid.prototype.getVisibleColumnCount = function getVisibleColumnCount() {
+    // var count = 0;
+
+    // this.rows.forEach(function (row) {
+    //   if (row.visible) {
+    //     count++;
+    //   }
+    // });
+
+    // return this.visibleRowCache.length;
+    return this.renderContainers.body.visibleColumnCache.length;
+  };
+
+
+  Grid.prototype.searchRows = function searchRows(renderableRows) {
+    return rowSearcher.search(this, renderableRows, this.columns);
+  };
+
+  Grid.prototype.sortByColumn = function sortByColumn(renderableRows) {
+    return rowSorter.sort(this, renderableRows, this.columns);
+  };
+
+  /**
+   * @ngdoc function
+   * @name getCellValue
+   * @methodOf ui.grid.class:Grid
+   * @description Gets the value of a cell for a particular row and column
+   * @param {GridRow} row Row to access
+   * @param {GridColumn} col Column to access
+   */
+  Grid.prototype.getCellValue = function getCellValue(row, col){
+    var self = this;
+
+    if (!self.cellValueGetterCache[col.colDef.name]) {
+      self.cellValueGetterCache[col.colDef.name] = $parse(row.getEntityQualifiedColField(col));
+    }
+
+    return self.cellValueGetterCache[col.colDef.name](row);
+  };
+
+  
+  Grid.prototype.getNextColumnSortPriority = function getNextColumnSortPriority() {
+    var self = this,
+        p = 0;
+
+    self.columns.forEach(function (col) {
+      if (col.sort && col.sort.priority && col.sort.priority > p) {
+        p = col.sort.priority;
+      }
+    });
+
+    return p + 1;
+  };
+
+  /**
+   * @ngdoc function
+   * @name resetColumnSorting
+   * @methodOf ui.grid.class:Grid
+   * @description Return the columns that the grid is currently being sorted by
+   * @param {GridColumn} [excludedColumn] Optional GridColumn to exclude from having its sorting reset
+   */
+  Grid.prototype.resetColumnSorting = function resetColumnSorting(excludeCol) {
+    var self = this;
+
+    self.columns.forEach(function (col) {
+      if (col !== excludeCol) {
+        col.sort = {};
+      }
+    });
+  };
+
+  /**
+   * @ngdoc function
+   * @name getColumnSorting
+   * @methodOf ui.grid.class:Grid
+   * @description Return the columns that the grid is currently being sorted by
+   * @returns {Array[GridColumn]} An array of GridColumn objects
+   */
+  Grid.prototype.getColumnSorting = function getColumnSorting() {
+    var self = this;
+
+    var sortedCols = [], myCols;
+
+    // Iterate through all the columns, sorted by priority
+    // Make local copy of column list, because sorting is in-place and we do not want to
+    // change the original sequence of columns
+    myCols = self.columns.slice(0);
+    myCols.sort(rowSorter.prioritySort).forEach(function (col) {
+      if (col.sort && typeof(col.sort.direction) !== 'undefined' && col.sort.direction && (col.sort.direction === uiGridConstants.ASC || col.sort.direction === uiGridConstants.DESC)) {
+        sortedCols.push(col);
+      }
+    });
+
+    return sortedCols;
+  };
+
+  /**
+   * @ngdoc function
+   * @name sortColumn
+   * @methodOf ui.grid.class:Grid
+   * @description Set the sorting on a given column, optionally resetting any existing sorting on the Grid.
+   * Emits the sortChanged event whenever the sort criteria are changed.
+   * @param {GridColumn} column Column to set the sorting on
+   * @param {uiGridConstants.ASC|uiGridConstants.DESC} [direction] Direction to sort by, either descending or ascending.
+   *   If not provided, the column will iterate through the sort directions: ascending, descending, unsorted.
+   * @param {boolean} [add] Add this column to the sorting. If not provided or set to `false`, the Grid will reset any existing sorting and sort
+   *   by this column only
+   * @returns {Promise} A resolved promise that supplies the column.
+   */
+  
+  Grid.prototype.sortColumn = function sortColumn(column, directionOrAdd, add) {
+    var self = this,
+        direction = null;
+
+    if (typeof(column) === 'undefined' || !column) {
+      throw new Error('No column parameter provided');
+    }
+
+    // Second argument can either be a direction or whether to add this column to the existing sort.
+    //   If it's a boolean, it's an add, otherwise, it's a direction
+    if (typeof(directionOrAdd) === 'boolean') {
+      add = directionOrAdd;
+    }
+    else {
+      direction = directionOrAdd;
+    }
+    
+    if (!add) {
+      self.resetColumnSorting(column);
+      column.sort.priority = 0;
+    }
+    else {
+      column.sort.priority = self.getNextColumnSortPriority();
+    }
+
+    if (!direction) {
+      // Figure out the sort direction
+      if (column.sort.direction && column.sort.direction === uiGridConstants.ASC) {
+        column.sort.direction = uiGridConstants.DESC;
+      }
+      else if (column.sort.direction && column.sort.direction === uiGridConstants.DESC) {
+        if ( column.colDef && column.colDef.suppressRemoveSort ){
+          column.sort.direction = uiGridConstants.ASC;
+        } else {
+          column.sort.direction = null;
+        }
+      }
+      else {
+        column.sort.direction = uiGridConstants.ASC;
+      }
+    }
+    else {
+      column.sort.direction = direction;
+    }
+    
+    self.api.core.raise.sortChanged( self, self.getColumnSorting() );
+
+    return $q.when(column);
+  };
+  
+  /**
+   * communicate to outside world that we are done with initial rendering
+   */
+  Grid.prototype.renderingComplete = function(){
+    if (angular.isFunction(this.options.onRegisterApi)) {
+      this.options.onRegisterApi(this.api);
+    }
+    this.api.core.raise.renderingComplete( this.api );
+  };
+
+  Grid.prototype.createRowHashMap = function createRowHashMap() {
+    var self = this;
+
+    var hashMap = new RowHashMap();
+    hashMap.grid = self;
+
+    self.rowHashMap = hashMap;
+  };
+  
+  
+  /**
+   * @ngdoc function
+   * @name refresh
+   * @methodOf ui.grid.class:Grid
+   * @description Refresh the rendered grid on screen.
+   * 
+   */
+  Grid.prototype.refresh = function refresh() {
+    gridUtil.logDebug('grid refresh');
+    
+    var self = this;
+    
+    var p1 = self.processRowsProcessors(self.rows).then(function (renderableRows) {
+      self.setVisibleRows(renderableRows);
+    });
+
+    var p2 = self.processColumnsProcessors(self.columns).then(function (renderableColumns) {
+      self.setVisibleColumns(renderableColumns);
+    });
+
+    return $q.all([p1, p2]).then(function () {
+      self.redrawInPlace();
+
+      self.refreshCanvas(true);
+    });
+  };  
+  
+  /**
+   * @ngdoc function
+   * @name refreshRows
+   * @methodOf ui.grid.class:Grid
+   * @description Refresh the rendered rows on screen?  Note: not functional at present 
+   * @returns {promise} promise that is resolved when render completes?
+   * 
+   */
+  Grid.prototype.refreshRows = function refreshRows() {
+    var self = this;
+    
+    return self.processRowsProcessors(self.rows)
+      .then(function (renderableRows) {
+        self.setVisibleRows(renderableRows);
+
+        self.redrawInPlace();
+
+        self.refreshCanvas( true );
+      });
+  };
+
+  /**
+   * @ngdoc function
+   * @name redrawCanvas
+   * @methodOf ui.grid.class:Grid
+   * @description TBD
+   * @params {object} buildStyles optional parameter.  Use TBD
+   * @returns {promise} promise that is resolved when the canvas
+   * has been refreshed
+   * 
+   */
+  Grid.prototype.refreshCanvas = function(buildStyles) {
+    var self = this;
+    
+    if (buildStyles) {
+      self.buildStyles();
+    }
+
+    var p = $q.defer();
+
+    // Get all the header heights
+    var containerHeadersToRecalc = [];
+    for (var containerId in self.renderContainers) {
+      if (self.renderContainers.hasOwnProperty(containerId)) {
+        var container = self.renderContainers[containerId];
+
+        // Skip containers that have no canvasWidth set yet
+        if (container.canvasWidth === null || isNaN(container.canvasWidth)) {
+          continue;
+        }
+
+        if (container.header) {
+          containerHeadersToRecalc.push(container);
+        }
+      }
+    }
+
+    if (containerHeadersToRecalc.length > 0) {
+      // Putting in a timeout as it's not calculating after the grid element is rendered and filled out
+      $timeout(function() {
+        // var oldHeaderHeight = self.grid.headerHeight;
+        // self.grid.headerHeight = gridUtil.outerElementHeight(self.header);
+
+        var rebuildStyles = false;
+
+        // Get all the header heights
+        var maxHeight = 0;
+        var i, container;
+        for (i = 0; i < containerHeadersToRecalc.length; i++) {
+          container = containerHeadersToRecalc[i];
+
+          // Skip containers that have no canvasWidth set yet
+          if (container.canvasWidth === null || isNaN(container.canvasWidth)) {
+            continue;
+          }
+
+          if (container.header) {
+            var oldHeaderHeight = container.headerHeight;
+            var headerHeight = gridUtil.outerElementHeight(container.header);
+
+            container.headerHeight = parseInt(headerHeight, 10);
+
+            if (oldHeaderHeight !== headerHeight) {
+              rebuildStyles = true;
+            }
+
+            // Get the "inner" header height, that is the height minus the top and bottom borders, if present. We'll use it to make sure all the headers have a consistent height
+            var topBorder = gridUtil.getBorderSize(container.header, 'top');
+            var bottomBorder = gridUtil.getBorderSize(container.header, 'bottom');
+            var innerHeaderHeight = parseInt(headerHeight - topBorder - bottomBorder, 10);
+
+            innerHeaderHeight  = innerHeaderHeight < 0 ? 0 : innerHeaderHeight;
+
+            container.innerHeaderHeight = innerHeaderHeight;
+
+            // Save the largest header height for use later
+            if (innerHeaderHeight > maxHeight) {
+              maxHeight = innerHeaderHeight;
+            }
+          }
+        }
+
+        // Go through all the headers
+        for (i = 0; i < containerHeadersToRecalc.length; i++) {
+          container = containerHeadersToRecalc[i];
+
+          // If this header's height is less than another header's height, then explicitly set it so they're the same and one isn't all offset and weird looking
+          if (container.headerHeight < maxHeight) {
+            container.explicitHeaderHeight = maxHeight;
+          }
+        }
+
+        // Rebuild styles if the header height has changed
+        //   The header height is used in body/viewport calculations and those are then used in other styles so we need it to be available
+        if (buildStyles && rebuildStyles) {
+          self.buildStyles();
+        }
+
+        p.resolve();
+      });
+    }
+    else {
+      // Timeout still needs to be here to trigger digest after styles have been rebuilt
+      $timeout(function() {
+        p.resolve();
+      });
+    }
+
+    return p.promise;
+  };
+
+
+  /**
+   * @ngdoc function
+   * @name redrawCanvas
+   * @methodOf ui.grid.class:Grid
+   * @description Redraw the rows and columns based on our current scroll position
+   * 
+   */
+  Grid.prototype.redrawInPlace = function redrawInPlace() {
+    // gridUtil.logDebug('redrawInPlace');
+    
+    var self = this;
+
+    for (var i in self.renderContainers) {
+      var container = self.renderContainers[i];
+
+      // gridUtil.logDebug('redrawing container', i);
+
+      container.adjustRows(container.prevScrollTop, null);
+      container.adjustColumns(container.prevScrollLeft, null);
+    }
+  };
+
+
+  // Blatantly stolen from Angular as it isn't exposed (yet? 2.0?)
+  function RowHashMap() {}
+
+  RowHashMap.prototype = {
+    /**
+     * Store key value pair
+     * @param key key to store can be any type
+     * @param value value to store can be any type
+     */
+    put: function(key, value) {
+      this[this.grid.options.rowIdentity(key)] = value;
+    },
+
+    /**
+     * @param key
+     * @returns {Object} the value for the key
+     */
+    get: function(key) {
+      return this[this.grid.options.rowIdentity(key)];
+    },
+
+    /**
+     * Remove the key/value pair
+     * @param key
+     */
+    remove: function(key) {
+      var value = this[key = this.grid.options.rowIdentity(key)];
+      delete this[key];
+      return value;
+    }
+  };
+
+
+
+  return Grid;
+
+}]);
+
+})();
+
+(function () {
+
+  angular.module('ui.grid')
+    .factory('GridApi', ['$q', '$rootScope', 'gridUtil', 'uiGridConstants', 'GridRow', 'uiGridGridMenuService',
+      function ($q, $rootScope, gridUtil, uiGridConstants, GridRow, uiGridGridMenuService) {
+        /**
+         * @ngdoc function
+         * @name ui.grid.class:GridApi
+         * @description GridApi provides the ability to register public methods events inside the grid and allow
+         * for other components to use the api via featureName.methodName and featureName.on.eventName(function(args){}
+         * @param {object} grid grid that owns api
+         */
+        var GridApi = function GridApi(grid) {
+          this.grid = grid;
+          this.listeners = [];
+          
+          /**
+           * @ngdoc function
+           * @name renderingComplete
+           * @methodOf  ui.grid.core.api:PublicApi
+           * @description Rendering is complete, called at the same
+           * time as `onRegisterApi`, but provides a way to obtain
+           * that same event within features without stopping end
+           * users from getting at the onRegisterApi method.
+           * 
+           * Included in gridApi so that it's always there - otherwise
+           * there is still a timing problem with when a feature can
+           * call this. 
+           * 
+           * @param {GridApi} gridApi the grid api, as normally 
+           * returned in the onRegisterApi method
+           * 
+           * @example
+           * <pre>
+           *      gridApi.core.on.renderingComplete( grid );
+           * </pre>
+           */
+          this.registerEvent( 'core', 'renderingComplete' );
+
+          /**
+           * @ngdoc event
+           * @name filterChanged
+           * @eventOf  ui.grid.core.api:PublicApi
+           * @description  is raised after the filter is changed.  The nature
+           * of the watch expression doesn't allow notification of what changed,
+           * so the receiver of this event will need to re-extract the filter 
+           * conditions from the columns.
+           * 
+           */
+          this.registerEvent( 'core', 'filterChanged' );
+
+          /**
+           * @ngdoc function
+           * @name setRowInvisible
+           * @methodOf  ui.grid.core.api:PublicApi
+           * @description Sets an override on the row to make it always invisible,
+           * which will override any filtering or other visibility calculations.  
+           * If the row is currently visible then sets it to invisible and calls
+           * both grid refresh and emits the rowsVisibleChanged event
+           * @param {object} rowEntity gridOptions.data[] array instance
+           */
+          this.registerMethod( 'core', 'setRowInvisible', GridRow.prototype.setRowInvisible );
+      
+          /**
+           * @ngdoc function
+           * @name clearRowInvisible
+           * @methodOf  ui.grid.core.api:PublicApi
+           * @description Clears any override on visibility for the row so that it returns to 
+           * using normal filtering and other visibility calculations.  
+           * If the row is currently invisible then sets it to visible and calls
+           * both grid refresh and emits the rowsVisibleChanged event
+           * TODO: if a filter is active then we can't just set it to visible?
+           * @param {object} rowEntity gridOptions.data[] array instance
+           */
+          this.registerMethod( 'core', 'clearRowInvisible', GridRow.prototype.clearRowInvisible );
+      
+          /**
+           * @ngdoc function
+           * @name getVisibleRows
+           * @methodOf  ui.grid.core.api:PublicApi
+           * @description Returns all visible rows
+           * @param {Grid} grid the grid you want to get visible rows from
+           * @returns {array} an array of gridRow 
+           */
+          this.registerMethod( 'core', 'getVisibleRows', this.grid.getVisibleRows );
+          
+          /**
+           * @ngdoc event
+           * @name rowsVisibleChanged
+           * @eventOf  ui.grid.core.api:PublicApi
+           * @description  is raised after the rows that are visible
+           * change.  The filtering is zero-based, so it isn't possible
+           * to say which rows changed (unlike in the selection feature).
+           * We can plausibly know which row was changed when setRowInvisible
+           * is called, but in that situation the user already knows which row
+           * they changed.  When a filter runs we don't know what changed, 
+           * and that is the one that would have been useful.
+           * 
+           */
+          this.registerEvent( 'core', 'rowsVisibleChanged' );
+        };
+
+        /**
+         * @ngdoc function
+         * @name ui.grid.class:suppressEvents
+         * @methodOf ui.grid.class:GridApi
+         * @description Used to execute a function while disabling the specified event listeners.
+         * Disables the listenerFunctions, executes the callbackFn, and then enables
+         * the listenerFunctions again
+         * @param {object} listenerFuncs listenerFunc or array of listenerFuncs to suppress. These must be the same
+         * functions that were used in the .on.eventName method
+         * @param {object} callBackFn function to execute
+         * @example
+         * <pre>
+         *    var navigate = function (newRowCol, oldRowCol){
+         *       //do something on navigate
+         *    }
+         *
+         *    gridApi.cellNav.on.navigate(scope,navigate);
+         *
+         *
+         *    //call the scrollTo event and suppress our navigate listener
+         *    //scrollTo will still raise the event for other listeners
+         *    gridApi.suppressEvents(navigate, function(){
+         *       gridApi.cellNav.scrollTo(aRow, aCol);
+         *    });
+         *
+         * </pre>
+         */
+        GridApi.prototype.suppressEvents = function (listenerFuncs, callBackFn) {
+          var self = this;
+          var listeners = angular.isArray(listenerFuncs) ? listenerFuncs : [listenerFuncs];
+
+          //find all registered listeners
+          var foundListeners = [];
+          listeners.forEach(function (l) {
+            foundListeners = self.listeners.filter(function (lstnr) {
+              return l === lstnr.handler;
+            });
+          });
+
+          //deregister all the listeners
+          foundListeners.forEach(function(l){
+            l.dereg();
+          });
+
+          callBackFn();
+
+          //reregister all the listeners
+          foundListeners.forEach(function(l){
+              l.dereg = registerEventWithAngular(l.scope, l.eventId, l.handler, self.grid);
+          });
+
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerEvent
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers a new event for the given feature
+         * @param {string} featureName name of the feature that raises the event
+         * @param {string} eventName  name of the event
+         */
+        GridApi.prototype.registerEvent = function (featureName, eventName) {
+          var self = this;
+          if (!self[featureName]) {
+            self[featureName] = {};
+          }
+
+          var feature = self[featureName];
+          if (!feature.on) {
+            feature.on = {};
+            feature.raise = {};
+          }
+
+          var eventId = self.grid.id + featureName + eventName;
+
+          // gridUtil.logDebug('Creating raise event method ' + featureName + '.raise.' + eventName);
+          feature.raise[eventName] = function () {
+            $rootScope.$broadcast.apply($rootScope, [eventId].concat(Array.prototype.slice.call(arguments)));
+          };
+
+          // gridUtil.logDebug('Creating on event method ' + featureName + '.on.' + eventName);
+          feature.on[eventName] = function (scope, handler) {
+            var dereg = registerEventWithAngular(scope, eventId, handler, self.grid);
+
+            //track our listener so we can turn off and on
+            var listener = {handler: handler, dereg: dereg, eventId: eventId, scope: scope};
+            self.listeners.push(listener);
+
+            //destroy tracking when scope is destroyed
+            //wanted to remove the listener from the array but angular does
+            //strange things in scope.$destroy so I could not access the listener array
+            scope.$on('$destroy', function() {
+              listener.dereg = null;
+              listener.handler = null;
+              listener.eventId = null;
+              listener.scope = null;
+            });
+          };
+        };
+
+        function registerEventWithAngular(scope, eventId, handler, grid) {
+          return scope.$on(eventId, function (event) {
+            var args = Array.prototype.slice.call(arguments);
+            args.splice(0, 1); //remove evt argument
+            handler.apply(grid.api, args);
+          });
+        }
+
+        /**
+         * @ngdoc function
+         * @name registerEventsFromObject
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers features and events from a simple objectMap.
+         * eventObjectMap must be in this format (multiple features allowed)
+         * <pre>
+         * {featureName:
+         *        {
+         *          eventNameOne:function(args){},
+         *          eventNameTwo:function(args){}
+         *        }
+         *  }
+         * </pre>
+         * @param {object} eventObjectMap map of feature/event names
+         */
+        GridApi.prototype.registerEventsFromObject = function (eventObjectMap) {
+          var self = this;
+          var features = [];
+          angular.forEach(eventObjectMap, function (featProp, featPropName) {
+            var feature = {name: featPropName, events: []};
+            angular.forEach(featProp, function (prop, propName) {
+              feature.events.push(propName);
+            });
+            features.push(feature);
+          });
+
+          features.forEach(function (feature) {
+            feature.events.forEach(function (event) {
+              self.registerEvent(feature.name, event);
+            });
+          });
+
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerMethod
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers a new event for the given feature
+         * @param {string} featureName name of the feature
+         * @param {string} methodName  name of the method
+         * @param {object} callBackFn function to execute
+         * @param {object} thisArg binds callBackFn 'this' to thisArg.  Defaults to gridApi.grid
+         */
+        GridApi.prototype.registerMethod = function (featureName, methodName, callBackFn, thisArg) {
+          if (!this[featureName]) {
+            this[featureName] = {};
+          }
+
+          var feature = this[featureName];
+
+          feature[methodName] = gridUtil.createBoundedWrapper(thisArg || this.grid, callBackFn);
+        };
+
+        /**
+         * @ngdoc function
+         * @name registerMethodsFromObject
+         * @methodOf ui.grid.class:GridApi
+         * @description Registers features and methods from a simple objectMap.
+         * eventObjectMap must be in this format (multiple features allowed)
+         * <br>
+         * {featureName:
+         *        {
+         *          methodNameOne:function(args){},
+         *          methodNameTwo:function(args){}
+         *        }
+         * @param {object} eventObjectMap map of feature/event names
+         * @param {object} thisArg binds this to thisArg for all functions.  Defaults to gridApi.grid
+         */
+        GridApi.prototype.registerMethodsFromObject = function (methodMap, thisArg) {
+          var self = this;
+          var features = [];
+          angular.forEach(methodMap, function (featProp, featPropName) {
+            var feature = {name: featPropName, methods: []};
+            angular.forEach(featProp, function (prop, propName) {
+              feature.methods.push({name: propName, fn: prop});
+            });
+            features.push(feature);
+          });
+
+          features.forEach(function (feature) {
+            feature.methods.forEach(function (method) {
+              self.registerMethod(feature.name, method.name, method.fn, thisArg);
+            });
+          });
+
+        };
+        
+        return GridApi;
+
+      }]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+.factory('GridColumn', ['gridUtil', 'uiGridConstants', 'i18nService', function(gridUtil, uiGridConstants, i18nService) {
+
+  /**
+   * @ngdoc function
+   * @name ui.grid.class:GridColumn
+   * @description Represents the viewModel for each column.  Any state or methods needed for a Grid Column
+   * are defined on this prototype
+   * @param {ColDef} colDef Column definition.
+   * @param {number} index the current position of the column in the array
+   * @param {Grid} grid reference to the grid
+   */
+   
+   /**
+    * ******************************************************************************************
+    * PaulL1: Ugly hack here in documentation.  These properties are clearly properties of GridColumn, 
+    * and need to be noted as such for those extending and building ui-grid itself.
+    * However, from an end-developer perspective, they interact with all these through columnDefs,
+    * and they really need to be documented there.  I feel like they're relatively static, and
+    * I can't find an elegant way for ngDoc to reference to both....so I've duplicated each
+    * comment block.  Ugh.
+    * 
+    */
+
+   /** 
+    * @ngdoc property
+    * @name name
+    * @propertyOf ui.grid.class:GridColumn
+    * @description (mandatory) each column should have a name, although for backward
+    * compatibility with 2.x name can be omitted if field is present
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name name
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description (mandatory) each column should have a name, although for backward
+    * compatibility with 2.x name can be omitted if field is present
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name displayName
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Column name that will be shown in the header.  If displayName is not
+    * provided then one is generated using the name.
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name displayName
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Column name that will be shown in the header.  If displayName is not
+    * provided then one is generated using the name.
+    *
+    */
+       
+    /** 
+    * @ngdoc property
+    * @name field
+    * @propertyOf ui.grid.class:GridColumn
+    * @description field must be provided if you wish to bind to a 
+    * property in the data source.  Should be an angular expression that evaluates against grid.options.data 
+    * array element.  Can be a complex expression: <code>employee.address.city</code>, or can be a function: <code>employee.getFullAddress()</code>.
+    * See the angular docs on binding expressions.
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name field
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description field must be provided if you wish to bind to a 
+    * property in the data source.  Should be an angular expression that evaluates against grid.options.data 
+    * array element.  Can be a complex expression: <code>employee.address.city</code>, or can be a function: <code>employee.getFullAddress()</code>.
+    * See the angular docs on binding expressions.
+    *
+    */
+    
+    /** 
+    * @ngdoc property
+    * @name filter
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Filter on this column.  
+    * @example
+    * <pre>{ term: 'text', condition: uiGridConstants.filter.STARTS_WITH, placeholder: 'type to filter...' }</pre>
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name filter
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Specify a single filter field on this column.
+    * @example
+    * <pre>$scope.gridOptions.columnDefs = [ 
+    *   {
+    *     field: 'field1',
+    *     filter: {
+    *       condition: uiGridConstants.filter.STARTS_WITH,
+    *       placeholder: 'starts with...'
+    *     }
+    *   }
+    * ]; </pre>
+    *
+    */
+    
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:GridColumn
+   * @name GridColumn
+   * @description Initializes a gridColumn
+   * @param {ColumnDef} colDef the column def to associate with this column
+   * @param {number} uid the unique and immutable uid we'd like to allocate to this column
+   * @param {Grid} grid the grid we'd like to create this column in
+   */ 
+  function GridColumn(colDef, uid, grid) {
+    var self = this;
+
+    self.grid = grid;
+    self.uid = uid;
+
+    self.updateColumnDef(colDef);
+  }
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:GridColumn
+   * @name setPropertyOrDefault
+   * @description Sets a property on the column using the passed in columnDef, and
+   * setting the defaultValue if the value cannot be found on the colDef
+   * @param {ColumnDef} colDef the column def to look in for the property value
+   * @param {string} propName the property name we'd like to set
+   * @param {object} defaultValue the value to use if the colDef doesn't provide the setting
+   */ 
+  GridColumn.prototype.setPropertyOrDefault = function (colDef, propName, defaultValue) {
+    var self = this;
+
+    // Use the column definition filter if we were passed it
+    if (typeof(colDef[propName]) !== 'undefined' && colDef[propName]) {
+      self[propName] = colDef[propName];
+    }
+    // Otherwise use our own if it's set
+    else if (typeof(self[propName]) !== 'undefined') {
+      self[propName] = self[propName];
+    }
+    // Default to empty object for the filter
+    else {
+      self[propName] = defaultValue ? defaultValue : {};
+    }
+  };
+
+  
+  
+   /** 
+    * @ngdoc property
+    * @name width
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the column width.  Can be either 
+    * a number or a percentage, or an * for auto.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', width: 100},
+    *                                          { field: 'field2', width: '20%'},
+    *                                          { field: 'field3', width: '*' }]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name minWidth
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the minimum column width.  Should be a number.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', minWidth: 100}]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name maxWidth
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets the maximum column width.  Should be a number.
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', maxWidth: 100}]; </pre>
+    *
+    */
+
+   /** 
+    * @ngdoc property
+    * @name visible
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description sets whether or not the column is visible
+    * </br>Default is true
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ 
+    *     { field: 'field1', visible: true},
+    *     { field: 'field2', visible: false }
+    *   ]; </pre>
+    *
+    */
+   
+  /**
+   * @ngdoc property
+   * @name sort
+   * @propertyOf ui.grid.class:GridOptions.columnDef
+   * @description Can be used to set the sort direction for the column, values are
+   * uiGridConstants.ASC or uiGridConstants.DESC
+   * @example
+   * <pre>  $scope.gridOptions.columnDefs = [ { field: 'field1', sort: { direction: uiGridConstants.ASC }}] </pre>
+   */
+  
+
+    /** 
+    * @ngdoc property
+    * @name sortingAlgorithm
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Algorithm to use for sorting this column. Takes 'a' and 'b' parameters 
+    * like any normal sorting function.
+    *
+    */
+
+    /** 
+    * @ngdoc property
+    * @name sortingAlgorithm
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Algorithm to use for sorting this column. Takes 'a' and 'b' parameters 
+    * like any normal sorting function.
+    *
+    */
+      
+   /** 
+    * @ngdoc array
+    * @name filters
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description Specify multiple filter fields.
+    * @example
+    * <pre>$scope.gridOptions.columnDefs = [ 
+    *   {
+    *     field: 'field1', filters: [
+    *       {
+    *         condition: uiGridConstants.filter.STARTS_WITH,
+    *         placeholder: 'starts with...'
+    *       },
+    *       {
+    *         condition: uiGridConstants.filter.ENDS_WITH,
+    *         placeholder: 'ends with...'
+    *       }
+    *     ]
+    *   }
+    * ]; </pre>
+    *
+    * 
+    */ 
+   
+   /** 
+    * @ngdoc array
+    * @name filters
+    * @propertyOf ui.grid.class:GridColumn
+    * @description Filters for this column. Includes 'term' property bound to filter input elements.
+    * @example
+    * <pre>[
+    *   {
+    *     term: 'foo', // ngModel for <input>
+    *     condition: uiGridConstants.filter.STARTS_WITH,
+    *     placeholder: 'starts with...'
+    *   },
+    *   {
+    *     term: 'baz',
+    *     condition: uiGridConstants.filter.ENDS_WITH,
+    *     placeholder: 'ends with...'
+    *   }
+    * ] </pre>
+    *
+    * 
+    */   
+
+   /** 
+    * @ngdoc array
+    * @name menuItems
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description used to add menu items to a column.  Refer to the tutorial on this 
+    * functionality.  A number of settings are supported:
+    * 
+    * - title: controls the title that is displayed in the menu
+    * - icon: the icon shown alongside that title
+    * - action: the method to call when the menu is clicked
+    * - shown: a function to evaluate to determine whether or not to show the item
+    * - active: a function to evaluate to determine whether or not the item is currently selected
+    * - context: context to pass to the action function??
+    * @example
+    * <pre>  $scope.gridOptions.columnDefs = [ 
+    *   { field: 'field1', menuItems: [
+    *     {
+    *       title: 'Outer Scope Alert',
+    *       icon: 'ui-grid-icon-info-circled',
+    *       action: function($event) {
+    *         this.context.blargh(); // $scope.blargh() would work too, this is just an example
+    *       },
+    *       shown: function() { return true; },
+    *       active: function() { return true; },
+    *       context: $scope
+    *     },
+    *     {
+    *       title: 'Grid ID',
+    *       action: function() {
+    *         alert('Grid ID: ' + this.grid.id);
+    *       }
+    *     }
+    *   ] }]; </pre>
+    *
+    */   
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:GridColumn
+   * @name updateColumnDef
+   * @description Moves settings from the columnDef down onto the column,
+   * and sets properties as appropriate
+   * @param {ColumnDef} colDef the column def to look in for the property value
+   */ 
+  GridColumn.prototype.updateColumnDef = function(colDef) {
+    var self = this;
+
+    self.colDef = colDef;
+
+    if (colDef.name === undefined) {
+      throw new Error('colDef.name is required for column at index ' + self.grid.options.columnDefs.indexOf(colDef));
+    }
+    
+    var parseErrorMsg = "Cannot parse column width '" + colDef.width + "' for column named '" + colDef.name + "'";
+
+    // If width is not defined, set it to a single star
+    if (gridUtil.isNullOrUndefined(self.width) || !angular.isNumber(self.width)) {
+      if (gridUtil.isNullOrUndefined(colDef.width)) {
+        self.width = '*';
+      }
+      else {
+        // If the width is not a number
+        if (!angular.isNumber(colDef.width)) {
+          // See if it ends with a percent
+          if (gridUtil.endsWith(colDef.width, '%')) {
+            // If so we should be able to parse the non-percent-sign part to a number
+            var percentStr = colDef.width.replace(/%/g, '');
+            var percent = parseInt(percentStr, 10);
+            if (isNaN(percent)) {
+              throw new Error(parseErrorMsg);
+            }
+            self.width = colDef.width;
+          }
+          // And see if it's a number string
+          else if (colDef.width.match(/^(\d+)$/)) {
+            self.width = parseInt(colDef.width.match(/^(\d+)$/)[1], 10);
+          }
+          // Otherwise it should be a string of asterisks
+          else if (colDef.width.match(/^\*+$/)) {
+            self.width = colDef.width;
+          }
+          // No idea, throw an Error
+          else {
+            throw new Error(parseErrorMsg);
+          }
+        }
+        // Is a number, use it as the width
+        else {
+          self.width = colDef.width;
+        }
+      }
+    }
+
+    // Remove this column from the grid sorting
+    GridColumn.prototype.unsort = function () {
+      this.sort = {};
+      self.grid.api.core.raise.sortChanged( self, self.grid.getColumnSorting() );
+    };
+
+    self.minWidth = !colDef.minWidth ? 30 : colDef.minWidth;
+    self.maxWidth = !colDef.maxWidth ? 9000 : colDef.maxWidth;
+
+    //use field if it is defined; name if it is not
+    self.field = (colDef.field === undefined) ? colDef.name : colDef.field;
+    
+    if ( typeof( self.field ) !== 'string' ){
+      gridUtil.logError( 'Field is not a string, this is likely to break the code, Field is: ' + self.field );
+    }
+    
+    self.name = colDef.name;
+
+    // Use colDef.displayName as long as it's not undefined, otherwise default to the field name
+    self.displayName = (colDef.displayName === undefined) ? gridUtil.readableColumnName(colDef.name) : colDef.displayName;
+
+    //self.originalIndex = index;
+
+    self.aggregationType = angular.isDefined(colDef.aggregationType) ? colDef.aggregationType : null;
+    self.footerCellTemplate = angular.isDefined(colDef.footerCellTemplate) ? colDef.footerCellTemplate : null;
+
+    /**
+     * @ngdoc property
+     * @name footerCellClass
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description footerCellClass can be a string specifying the class to append to a cell
+     * or it can be a function(row,rowRenderIndex, col, colRenderIndex) that returns a class name
+     *
+     */
+    self.footerCellClass = colDef.footerCellClass;
+
+    /**
+     * @ngdoc property
+     * @name cellClass
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description cellClass can be a string specifying the class to append to a cell
+     * or it can be a function(row,rowRenderIndex, col, colRenderIndex) that returns a class name
+     *
+     */
+    self.cellClass = colDef.cellClass;
+
+    /**
+     * @ngdoc property
+     * @name headerCellClass
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description headerCellClass can be a string specifying the class to append to a cell
+     * or it can be a function(row,rowRenderIndex, col, colRenderIndex) that returns a class name
+     *
+     */
+    self.headerCellClass = colDef.headerCellClass;
+
+    /**
+     * @ngdoc property
+     * @name cellFilter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description cellFilter is a filter to apply to the content of each cell
+     * @example
+     * <pre>
+     *   gridOptions.columnDefs[0].cellFilter = 'date'
+     *
+     */
+    self.cellFilter = colDef.cellFilter ? colDef.cellFilter : "";
+
+    /**
+     * @ngdoc property
+     * @name headerCellFilter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description headerCellFilter is a filter to apply to the content of the column header
+     * @example
+     * <pre>
+     *   gridOptions.columnDefs[0].headerCellFilter = 'translate'
+     *
+     */
+    self.headerCellFilter = colDef.headerCellFilter ? colDef.headerCellFilter : "";
+
+    self.visible = gridUtil.isNullOrUndefined(colDef.visible) || colDef.visible;
+
+    self.headerClass = colDef.headerClass;
+    //self.cursor = self.sortable ? 'pointer' : 'default';
+
+    self.visible = true;
+
+    // Turn on sorting by default
+    self.enableSorting = typeof(colDef.enableSorting) !== 'undefined' ? colDef.enableSorting : true;
+    self.sortingAlgorithm = colDef.sortingAlgorithm;
+
+    // Turn on filtering by default (it's disabled by default at the Grid level)
+    self.enableFiltering = typeof(colDef.enableFiltering) !== 'undefined' ? colDef.enableFiltering : true;
+
+    // self.menuItems = colDef.menuItems;
+    self.setPropertyOrDefault(colDef, 'menuItems', []);
+
+    // Use the column definition sort if we were passed it
+    self.setPropertyOrDefault(colDef, 'sort');
+
+    // Set up default filters array for when one is not provided.
+    //   In other words, this (in column def):
+    //   
+    //       filter: { term: 'something', flags: {}, condition: [CONDITION] }
+    //       
+    //   is just shorthand for this:
+    //   
+    //       filters: [{ term: 'something', flags: {}, condition: [CONDITION] }]
+    //       
+    var defaultFilters = [];
+    if (colDef.filter) {
+      defaultFilters.push(colDef.filter);
+    }
+    else if (self.enableFiltering && self.grid.options.enableFiltering) {
+      // Add an empty filter definition object, which will
+      // translate to a guessed condition and no pre-populated
+      // value for the filter <input>.
+      defaultFilters.push({});
+    }
+
+    /**
+     * @ngdoc object
+     * @name ui.grid.class:GridOptions.columnDef.filter
+     * @propertyOf ui.grid.class:GridOptions.columnDef
+     * @description An object defining filtering for a column.
+     */    
+
+    /**
+     * @ngdoc property
+     * @name condition
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description Defines how rows are chosen as matching the filter term. This can be set to
+     * one of the constants in uiGridConstants.filter, or you can supply a custom filter function
+     * that gets passed the following arguments: [searchTerm, cellValue, row, column].
+     */
+    
+    /**
+     * @ngdoc property
+     * @name term
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description If set, the filter field will be pre-populated
+     * with this value.
+     */
+
+    /**
+     * @ngdoc property
+     * @name placeholder
+     * @propertyOf ui.grid.class:GridOptions.columnDef.filter
+     * @description String that will be set to the <input>.placeholder attribute.
+     */
+
+    /*
+
+      self.filters = [
+        {
+          term: 'search term'
+          condition: uiGridConstants.filter.CONTAINS,
+          placeholder: 'my placeholder',
+          flags: {
+            caseSensitive: true
+          }
+        }
+      ]
+
+    */
+
+    self.setPropertyOrDefault(colDef, 'filter');
+    self.setPropertyOrDefault(colDef, 'filters', defaultFilters);
+  };
+
+
+
+
+    /**
+     * @ngdoc function
+     * @name getColClass
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the class name for the column
+     * @param {bool} prefixDot  if true, will return .className instead of className
+     */
+    GridColumn.prototype.getColClass = function (prefixDot) {
+      var cls = uiGridConstants.COL_CLASS_PREFIX + this.uid;
+
+      return prefixDot ? '.' + cls : cls;
+    };
+
+    /**
+     * @ngdoc function
+     * @name getColClassDefinition
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the class definition for th column
+     */
+    GridColumn.prototype.getColClassDefinition = function () {
+      return ' .grid' + this.grid.id + ' ' + this.getColClass(true) + ' { width: ' + this.drawnWidth + 'px; }';
+    };
+
+    /**
+     * @ngdoc function
+     * @name getRenderContainer
+     * @methodOf ui.grid.class:GridColumn
+     * @description Returns the render container object that this column belongs to.
+     *
+     * Columns will be default be in the `body` render container if they aren't allocated to one specifically.
+     */
+    GridColumn.prototype.getRenderContainer = function getRenderContainer() {
+      var self = this;
+
+      var containerId = self.renderContainer;
+
+      if (containerId === null || containerId === '' || containerId === undefined) {
+        containerId = 'body';
+      }
+
+      return self.grid.renderContainers[containerId];
+    };
+
+    /**
+     * @ngdoc function
+     * @name showColumn
+     * @methodOf ui.grid.class:GridColumn
+     * @description Makes the column visible by setting colDef.visible = true
+     */
+    GridColumn.prototype.showColumn = function() {
+        this.colDef.visible = true;
+    };
+
+    /**
+     * @ngdoc function
+     * @name hideColumn
+     * @methodOf ui.grid.class:GridColumn
+     * @description Hides the column by setting colDef.visible = false
+     */
+    GridColumn.prototype.hideColumn = function() {
+        this.colDef.visible = false;
+    };
+
+    /**
+     * @ngdoc function
+     * @name getAggregationValue
+     * @methodOf ui.grid.class:GridColumn
+     * @description gets the aggregation value based on the aggregation type for this column
+     */
+    GridColumn.prototype.getAggregationValue = function () {
+      var self = this;
+      var result = 0;
+      var visibleRows = self.grid.getVisibleRows();
+      var cellValues = [];
+      angular.forEach(visibleRows, function (row) {
+        var cellValue = self.grid.getCellValue(row, self);
+        if (angular.isNumber(cellValue)) {
+          cellValues.push(cellValue);
+        }
+      });
+      if (angular.isFunction(self.aggregationType)) {
+        return self.aggregationType(visibleRows, self);
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.count) {
+        return self.getAggregationText('aggregation.count', self.grid.getVisibleRowCount());
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.sum) {
+        angular.forEach(cellValues, function (value) {
+          result += value;
+        });
+        return self.getAggregationText('aggregation.sum', result);
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.avg) {
+        angular.forEach(cellValues, function (value) {
+          result += value;
+        });
+        result = result / cellValues.length;
+        return self.getAggregationText('aggregation.avg', result);
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.min) {
+        return self.getAggregationText('aggregation.min', Math.min.apply(null, cellValues));
+      }
+      else if (self.aggregationType === uiGridConstants.aggregationTypes.max) {
+        return self.getAggregationText('aggregation.max', Math.max.apply(null, cellValues));
+      }
+      else {
+        return '\u00A0';
+      }
+    };
+    
+   /** 
+    * @ngdoc property
+    * @name aggregationHideLabel
+    * @propertyOf ui.grid.class:GridOptions.columnDef
+    * @description defaults to false, if set to true hides the label text
+    * in the aggregation footer, so only the value is displayed.
+    *
+    */
+    /**
+     * @ngdoc function
+     * @name getAggregationText
+     * @methodOf ui.grid.class:GridColumn
+     * @description converts the aggregation value into a text string, including 
+     * i18n and deciding whether or not to display based on colDef.aggregationHideLabel
+     * 
+     * @param {string} label the i18n lookup value to use for the column label
+     * @param {number} value the calculated aggregate value for this column
+     * 
+     */
+    GridColumn.prototype.getAggregationText = function ( label, value ) {
+      var self = this;
+      if ( self.colDef.aggregationHideLabel ){
+        return value;
+      } else {
+        return i18nService.getSafeText(label) + value;
+      }
+    };
+
+    GridColumn.prototype.getCellTemplate = function () {
+      var self = this;
+
+      return self.cellTemplatePromise;
+    };
+
+    GridColumn.prototype.getCompiledElementFn = function () {
+      var self = this;
+      
+      return self.compiledElementFnDefer.promise;
+    };
+
+    return GridColumn;
+  }]);
+
+})();
+
+  (function(){
+
+angular.module('ui.grid')
+.factory('GridOptions', ['gridUtil','uiGridConstants', function(gridUtil,uiGridConstants) {
+
+  /**
+   * @ngdoc function
+   * @name ui.grid.class:GridOptions
+   * @description Default GridOptions class.  GridOptions are defined by the application developer and overlaid
+   * over this object.  Setting gridOptions within your controller is the most common method for an application 
+   * developer to configure the behaviour of their ui-grid
+   * 
+   * @example To define your gridOptions within your controller:
+   * <pre>$scope.gridOptions = {
+   *   data: $scope.myData,
+   *   columnDefs: [ 
+   *     { name: 'field1', displayName: 'pretty display name' },
+   *     { name: 'field2', visible: false }
+   *  ]
+   * };</pre>
+   * 
+   * You can then use this within your html template, when you define your grid:
+   * <pre>&lt;div ui-grid="gridOptions"&gt;&lt;/div&gt;</pre>
+   *
+   * To provide default options for all of the grids within your application, use an angular
+   * decorator to modify the GridOptions factory.
+   * <pre>app.config(function($provide){
+   *    $provide.decorator('GridOptions',function($delegate){
+   *      return function(){
+   *        var defaultOptions = new $delegate();
+   *        defaultOptions.excludeProperties = ['id' ,'$$hashKey'];
+   *        return defaultOptions;
+   *      };
+   *    })
+   *  })</pre>
+   */
+  return {
+    initialize: function( baseOptions ){
+      baseOptions.onRegisterApi = baseOptions.onRegisterApi || angular.noop();
+  
+      /**
+       * @ngdoc object
+       * @name data
+       * @propertyOf ui.grid.class:GridOptions
+       * @description (mandatory) Array of data to be rendered into the grid, providing the data source or data binding for 
+       * the grid.  The most common case is an array of objects, where each object has a number of attributes.
+       * Each attribute automatically becomes a column in your grid.  This array could, for example, be sourced from
+       * an angularJS $resource query request.  The array can also contain complex objects.
+       * 
+       */
+      baseOptions.data = baseOptions.data || [];
+  
+      /**
+       * @ngdoc array
+       * @name columnDefs
+       * @propertyOf  ui.grid.class:GridOptions
+       * @description Array of columnDef objects.  Only required property is name.
+       * The individual options available in columnDefs are documented in the
+       * {@link ui.grid.class:GridOptions.columnDef columnDef} section
+       * </br>_field property can be used in place of name for backwards compatibility with 2.x_
+       *  @example
+       *
+       * <pre>var columnDefs = [{name:'field1'}, {name:'field2'}];</pre>
+       *
+       */
+      baseOptions.columnDefs = baseOptions.columnDefs || [];
+  
+      /**
+       * @ngdoc object
+       * @name ui.grid.class:GridOptions.columnDef
+       * @description Definition / configuration of an individual column, which would typically be
+       * one of many column definitions within the gridOptions.columnDefs array
+       * @example
+       * <pre>{name:'field1', field: 'field1', filter: { term: 'xxx' }}</pre>
+       *
+       */
+  
+          
+      /**
+       * @ngdoc array
+       * @name excludeProperties
+       * @propertyOf  ui.grid.class:GridOptions
+       * @description Array of property names in data to ignore when auto-generating column names.  Provides the
+       * inverse of columnDefs - columnDefs is a list of columns to include, excludeProperties is a list of columns
+       * to exclude. 
+       * 
+       * If columnDefs is defined, this will be ignored.
+       * 
+       * Defaults to ['$$hashKey']
+       */
+      
+      baseOptions.excludeProperties = baseOptions.excludeProperties || ['$$hashKey'];
+  
+      /**
+       * @ngdoc boolean
+       * @name enableRowHashing
+       * @propertyOf ui.grid.class:GridOptions
+       * @description True by default. When enabled, this setting allows uiGrid to add
+       * `$$hashKey`-type properties (similar to Angular) to elements in the `data` array. This allows
+       * the grid to maintain state while vastly speeding up the process of altering `data` by adding/moving/removing rows.
+       * 
+       * Note that this DOES add properties to your data that you may not want, but they are stripped out when using `angular.toJson()`. IF
+       * you do not want this at all you can disable this setting but you will take a performance hit if you are using large numbers of rows
+       * and are altering the data set often.
+       */
+      baseOptions.enableRowHashing = baseOptions.enableRowHashing !== false;
+  
+      /**
+       * @ngdoc function
+       * @name rowIdentity
+       * @methodOf ui.grid.class:GridOptions
+       * @description This function is used to get and, if necessary, set the value uniquely identifying this row.
+       * 
+       * By default it returns the `$$hashKey` property if it exists. If it doesn't it uses gridUtil.nextUid() to generate one
+       */
+      baseOptions.rowIdentity = baseOptions.rowIdentity || function rowIdentity(row) {
+        return gridUtil.hashKey(row);
+      };
+  
+      /**
+       * @ngdoc function
+       * @name getRowIdentity
+       * @methodOf ui.grid.class:GridOptions
+       * @description This function returns the identity value uniquely identifying this row.
+       * 
+       * By default it returns the `$$hashKey` property but can be overridden to use any property or set of properties you want.
+       */
+      baseOptions.getRowIdentity = baseOptions.getRowIdentity || function getRowIdentity(row) {
+        return row.$$hashKey;
+      };
+  
+      /**
+       * @ngdoc property
+       * @name headerRowHeight
+       * @propertyOf ui.grid.class:GridOptions
+       * @description The height of the header in pixels, defaults to 30
+       *
+       */
+      baseOptions.headerRowHeight = typeof(baseOptions.headerRowHeight) !== "undefined" ? baseOptions.headerRowHeight : 30;
+
+      /**
+       * @ngdoc property
+       * @name rowHeight
+       * @propertyOf ui.grid.class:GridOptions
+       * @description The height of the row in pixels, defaults to 30
+       *
+       */
+      baseOptions.rowHeight = baseOptions.rowHeight || 30;
+      
+      /**
+       * @ngdoc property
+       * @name maxVisibleRowCount
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Defaults to 200
+       *
+       */
+      baseOptions.maxVisibleRowCount = baseOptions.maxVisibleRowCount || 200;
+  
+      /**
+       * @ngdoc integer
+       * @name minRowsToShow
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Minimum number of rows to show when the grid doesn't have a defined height. Defaults to "10".
+       */
+      baseOptions.minRowsToShow = typeof(baseOptions.minRowsToShow) !== "undefined" ? baseOptions.minRowsToShow : 10;
+  
+      /**
+       * @ngdoc property
+       * @name showFooter
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Whether or not to show the footer, defaults to false
+       *
+       */
+      baseOptions.showFooter = baseOptions.showFooter === true;
+
+      /**
+       * @ngdoc property
+       * @name footerRowHeight
+       * @propertyOf ui.grid.class:GridOptions
+       * @description The height of the footer in pixels
+       *
+       */
+      baseOptions.footerRowHeight = typeof(baseOptions.footerRowHeight) !== "undefined" ? baseOptions.footerRowHeight : 30;
+  
+      baseOptions.columnWidth = typeof(baseOptions.columnWidth) !== "undefined" ? baseOptions.columnWidth : 50;
+
+      /**
+       * @ngdoc property
+       * @name maxVisibleColumnCount
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Defaults to 200
+       *
+       */
+      baseOptions.maxVisibleColumnCount = typeof(baseOptions.maxVisibleColumnCount) !== "undefined" ? baseOptions.maxVisibleColumnCount : 200;
+  
+      /**
+       * @ngdoc property
+       * @name virtualizationThreshold
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Turn virtualization on when number of data elements goes over this number, defaults to 20
+       */
+      baseOptions.virtualizationThreshold = typeof(baseOptions.virtualizationThreshold) !== "undefined" ? baseOptions.virtualizationThreshold : 20;
+  
+      /**
+       * @ngdoc property
+       * @name columnVirtualizationThreshold
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Turn virtualization on when number of columns goes over this number, defaults to 10
+       */
+      baseOptions.columnVirtualizationThreshold = typeof(baseOptions.columnVirtualizationThreshold) !== "undefined" ? baseOptions.columnVirtualizationThreshold : 10;
+  
+      /**
+       * @ngdoc property
+       * @name excessRows
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Extra rows to to render outside of the viewport, which helps with smoothness of scrolling.
+       * Defaults to 4
+       */
+      baseOptions.excessRows = typeof(baseOptions.excessRows) !== "undefined" ? baseOptions.excessRows : 4;
+      /**
+       * @ngdoc property
+       * @name scrollThreshold
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Defaults to 4
+       */
+      baseOptions.scrollThreshold = typeof(baseOptions.scrollThreshold) !== "undefined" ? baseOptions.scrollThreshold : 4;
+  
+      /**
+       * @ngdoc property
+       * @name excessColumns
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Extra columns to to render outside of the viewport, which helps with smoothness of scrolling.
+       * Defaults to 4
+       */
+      baseOptions.excessColumns = typeof(baseOptions.excessColumns) !== "undefined" ? baseOptions.excessColumns : 4;
+      /**
+       * @ngdoc property
+       * @name horizontalScrollThreshold
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Defaults to 4
+       */
+      baseOptions.horizontalScrollThreshold = typeof(baseOptions.horizontalScrollThreshold) !== "undefined" ? baseOptions.horizontalScrollThreshold : 2;
+  
+      /**
+       * @ngdoc property
+       * @name scrollThrottle
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Default time to throttle scroll events to, defaults to 70ms
+       */
+      baseOptions.scrollThrottle = typeof(baseOptions.scrollThrottle) !== "undefined" ? baseOptions.scrollThrottle : 70;
+  
+      /**
+       * @ngdoc boolean
+       * @name enableSorting
+       * @propertyOf ui.grid.class:GridOptions
+       * @description True by default. When enabled, this setting adds sort
+       * widgets to the column headers, allowing sorting of the data for the entire grid.
+       * Sorting can then be disabled on individual columns using the columnDefs.
+       */
+      baseOptions.enableSorting = baseOptions.enableSorting !== false;
+  
+      /**
+       * @ngdoc boolean
+       * @name enableFiltering
+       * @propertyOf ui.grid.class:GridOptions
+       * @description False by default. When enabled, this setting adds filter 
+       * boxes to each column header, allowing filtering within the column for the entire grid.
+       * Filtering can then be disabled on individual columns using the columnDefs. 
+       */
+      baseOptions.enableFiltering = baseOptions.enableFiltering === true;
+  
+      /**
+       * @ngdoc boolean
+       * @name enableColumnMenus
+       * @propertyOf ui.grid.class:GridOptions
+       * @description True by default. When enabled, this setting displays a column
+       * menu within each column.
+       */
+      baseOptions.enableColumnMenus = baseOptions.enableColumnMenus !== false;
+  
+      /**
+       * @ngdoc boolean
+       * @name enableVerticalScrollbar
+       * @propertyOf ui.grid.class:GridOptions
+       * @description uiGridConstants.scrollbars.ALWAYS by default. This settings controls the vertical scrollbar for the grid.
+       * Supported values: uiGridConstants.scrollbars.ALWAYS, uiGridConstants.scrollbars.NEVER, uiGridConstants.scrollbars.WHEN_NEEDED.
+       */
+      baseOptions.enableVerticalScrollbar = typeof(baseOptions.enableVerticalScrollbar) !== "undefined" ? baseOptions.enableVerticalScrollbar : uiGridConstants.scrollbars.ALWAYS;
+      
+      /**
+       * @ngdoc boolean
+       * @name enableHorizontalScrollbar
+       * @propertyOf ui.grid.class:GridOptions
+       * @description uiGridConstants.scrollbars.ALWAYS by default. This settings controls the horizontal scrollbar for the grid.
+       * Supported values: uiGridConstants.scrollbars.ALWAYS, uiGridConstants.scrollbars.NEVER, uiGridConstants.scrollbars.WHEN_NEEDED.
+       */
+      baseOptions.enableHorizontalScrollbar = typeof(baseOptions.enableHorizontalScrollbar) !== "undefined" ? baseOptions.enableHorizontalScrollbar : uiGridConstants.scrollbars.ALWAYS;
+  
+      /**
+       * @ngdoc boolean
+       * @name minimumColumnSize
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Columns can't be smaller than this, defaults to 10 pixels
+       */
+      baseOptions.minimumColumnSize = typeof(baseOptions.minimumColumnSize) !== "undefined" ? baseOptions.minimumColumnSize : 10;
+  
+      /**
+       * @ngdoc function
+       * @name rowEquality
+       * @methodOf ui.grid.class:GridOptions
+       * @description By default, rows are compared using object equality.  This option can be overridden
+       * to compare on any data item property or function
+       * @param {object} entityA First Data Item to compare
+       * @param {object} entityB Second Data Item to compare
+       */
+      baseOptions.rowEquality = baseOptions.rowEquality || function(entityA, entityB) {
+        return entityA === entityB;
+      };
+  
+      /**
+       * @ngdoc string
+       * @name headerTemplate
+       * @propertyOf ui.grid.class:GridOptions
+       * @description Null by default. When provided, this setting uses a custom header
+       * template, rather than the default template. Can be set to either the name of a template file:
+       * <pre>  $scope.gridOptions.headerTemplate = 'header_template.html';</pre>
+       * inline html 
+       * <pre>  $scope.gridOptions.headerTemplate = '<div class="ui-grid-top-panel" style="text-align: center">I am a Custom Grid Header</div>'</pre>
+       * or the id of a precompiled template (TBD how to use this).  
+       * </br>Refer to the custom header tutorial for more information.
+       * If you want no header at all, you can set to an empty div:
+       * <pre>  $scope.gridOptions.headerTemplate = '<div></div>';</pre>
+       * 
+       * If you want to only have a static header, then you can set to static content.  If
+       * you want to tailor the existing column headers, then you should look at the
+       * current 'ui-grid-header.html' template in github as your starting point.
+       * 
+       */
+      baseOptions.headerTemplate = baseOptions.headerTemplate || null;
+  
+      /**
+       * @ngdoc string
+       * @name footerTemplate
+       * @propertyOf ui.grid.class:GridOptions
+       * @description (optional) Null by default. When provided, this setting uses a custom footer
+       * template. Can be set to either the name of a template file 'footer_template.html', inline html
+       * <pre>'<div class="ui-grid-bottom-panel" style="text-align: center">I am a Custom Grid Footer</div>'</pre>, or the id
+       * of a precompiled template (TBD how to use this).  Refer to the custom footer tutorial for more information.
+       */
+      baseOptions.footerTemplate = baseOptions.footerTemplate || null;
+  
+      /**
+       * @ngdoc string
+       * @name rowTemplate
+       * @propertyOf ui.grid.class:GridOptions
+       * @description 'ui-grid/ui-grid-row' by default. When provided, this setting uses a 
+       * custom row template.  Can be set to either the name of a template file:
+       * <pre> $scope.gridOptions.rowTemplate = 'row_template.html';</pre>
+       * inline html 
+       * <pre>  $scope.gridOptions.rowTemplate = '<div style="background-color: aquamarine" ng-click="getExternalScopes().fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';</pre>
+       * or the id of a precompiled template (TBD how to use this) can be provided.  
+       * </br>Refer to the custom row template tutorial for more information.
+       */
+      baseOptions.rowTemplate = baseOptions.rowTemplate || 'ui-grid/ui-grid-row';
+      
+      return baseOptions;
+    }     
+  };
+
+
+}]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+  
+  /**
+   * @ngdoc function
+   * @name ui.grid.class:GridRenderContainer
+   * @description The grid has render containers, allowing the ability to have pinned columns.  If the grid
+   * is right-to-left then there may be a right render container, if left-to-right then there may 
+   * be a left render container.  There is always a body render container.
+   * @param {string} name The name of the render container ('body', 'left', or 'right')
+   * @param {Grid} grid the grid the render container is in
+   * @param {object} options the render container options
+   */
+.factory('GridRenderContainer', ['gridUtil', function(gridUtil) {
+  function GridRenderContainer(name, grid, options) {
+    var self = this;
+
+    // if (gridUtil.type(grid) !== 'Grid') {
+    //   throw new Error('Grid argument is not a Grid object');
+    // }
+
+    self.name = name;
+
+    self.grid = grid;
+    
+    // self.rowCache = [];
+    // self.columnCache = [];
+
+    self.visibleRowCache = [];
+    self.visibleColumnCache = [];
+
+    self.renderedRows = [];
+    self.renderedColumns = [];
+
+    self.prevScrollTop = 0;
+    self.prevScrolltopPercentage = 0;
+    self.prevRowScrollIndex = 0;
+
+    self.prevScrollLeft = 0;
+    self.prevScrollleftPercentage = 0;
+    self.prevColumnScrollIndex = 0;
+
+    self.columnStyles = "";
+
+    self.viewportAdjusters = [];
+
+    if (options && angular.isObject(options)) {
+      angular.extend(self, options);
+    }
+
+    grid.registerStyleComputation({
+      priority: 5,
+      func: function () {
+        return self.columnStyles;
+      }
+    });
+  }
+
+  // GridRenderContainer.prototype.addRenderable = function addRenderable(renderable) {
+  //   this.renderables.push(renderable);
+  // };
+
+  GridRenderContainer.prototype.reset = function reset() {
+    // this.rowCache.length = 0;
+    // this.columnCache.length = 0;
+
+    this.visibleColumnCache.length = 0;
+    this.visibleRowCache.length = 0;
+
+    this.renderedRows.length = 0;
+    this.renderedColumns.length = 0;
+  };
+
+  // TODO(c0bra): calculate size?? Should this be in a stackable directive?
+
+  GridRenderContainer.prototype.minRowsToRender = function minRowsToRender() {
+    var self = this;
+    var minRows = 0;
+    var rowAddedHeight = 0;
+    var viewPortHeight = self.getViewportHeight();
+    for (var i = self.visibleRowCache.length - 1; rowAddedHeight < viewPortHeight && i >= 0; i--) {
+      rowAddedHeight += self.visibleRowCache[i].height;
+      minRows++;
+    }
+    return minRows;
+  };
+
+  GridRenderContainer.prototype.minColumnsToRender = function minColumnsToRender() {
+    var self = this;
+    var viewportWidth = this.getViewportWidth();
+
+    var min = 0;
+    var totalWidth = 0;
+    // self.columns.forEach(function(col, i) {
+    for (var i = 0; i < self.visibleColumnCache.length; i++) {
+      var col = self.visibleColumnCache[i];
+
+      if (totalWidth < viewportWidth) {
+        totalWidth += col.drawnWidth ? col.drawnWidth : 0;
+        min++;
+      }
+      else {
+        var currWidth = 0;
+        for (var j = i; j >= i - min; j--) {
+          currWidth += self.visibleColumnCache[j].drawnWidth ? self.visibleColumnCache[j].drawnWidth : 0;
+        }
+        if (currWidth < viewportWidth) {
+          min++;
+        }
+      }
+    }
+
+    return min;
+  };
+
+  GridRenderContainer.prototype.getVisibleRowCount = function getVisibleRowCount() {
+    return this.visibleRowCache.length;
+  };
+
+  /**
+   * @ngdoc function
+   * @name registerViewportAdjuster
+   * @methodOf ui.grid.class:GridRenderContainer
+   * @description Registers an adjuster to the render container's available width or height.  Adjusters are used
+   * to tell the render container that there is something else consuming space, and to adjust it's size
+   * appropriately.  
+   * @param {function} func the adjuster function we want to register
+   */
+
+  GridRenderContainer.prototype.registerViewportAdjuster = function registerViewportAdjuster(func) {
+    this.viewportAdjusters.push(func);
+  };
+
+  /**
+   * @ngdoc function
+   * @name removeViewportAdjuster
+   * @methodOf ui.grid.class:GridRenderContainer
+   * @description Removes an adjuster, should be used when your element is destroyed
+   * @param {function} func the adjuster function we want to remove
+   */
+  GridRenderContainer.prototype.removeViewportAdjuster = function registerViewportAdjuster(func) {
+    var idx = this.viewportAdjusters.indexOf(func);
+
+    if (typeof(idx) !== 'undefined' && idx !== undefined) {
+      this.viewportAdjusters.splice(idx, 1);
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name getViewportAdjustment
+   * @methodOf ui.grid.class:GridRenderContainer
+   * @description Gets the adjustment based on the viewportAdjusters.  
+   * @returns {object} a hash of { height: x, width: y }.  Usually the values will be negative
+   */
+  GridRenderContainer.prototype.getViewportAdjustment = function getViewportAdjustment() {
+    var self = this;
+
+    var adjustment = { height: 0, width: 0 };
+
+    self.viewportAdjusters.forEach(function (func) {
+      adjustment = func.call(this, adjustment);
+    });
+
+    return adjustment;
+  };
+
+  GridRenderContainer.prototype.getViewportHeight = function getViewportHeight() {
+    var self = this;
+
+    var headerHeight = (self.headerHeight) ? self.headerHeight : self.grid.headerHeight;
+
+    var viewPortHeight = self.grid.gridHeight - headerHeight - self.grid.footerHeight;
+
+    // Account for native horizontal scrollbar, if present
+    if (typeof(self.horizontalScrollbarHeight) !== 'undefined' && self.horizontalScrollbarHeight !== undefined && self.horizontalScrollbarHeight > 0) {
+      viewPortHeight = viewPortHeight - self.horizontalScrollbarHeight;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortHeight = viewPortHeight + adjustment.height;
+
+    return viewPortHeight;
+  };
+
+  GridRenderContainer.prototype.getViewportWidth = function getViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = self.grid.gridWidth;
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth - self.grid.verticalScrollbarWidth;
+    }
+
+    var adjustment = self.getViewportAdjustment();
+    
+    viewPortWidth = viewPortWidth + adjustment.width;
+
+    return viewPortWidth;
+  };
+
+  GridRenderContainer.prototype.getHeaderViewportWidth = function getHeaderViewportWidth() {
+    var self = this;
+
+    var viewPortWidth = this.getViewportWidth();
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      viewPortWidth = viewPortWidth + self.grid.verticalScrollbarWidth;
+    }
+
+    // var adjustment = self.getViewportAdjustment();
+    // viewPortWidth = viewPortWidth + adjustment.width;
+
+    return viewPortWidth;
+  };
+
+  GridRenderContainer.prototype.getCanvasHeight = function getCanvasHeight() {
+    var self = this;
+
+    var ret =  0;
+
+    self.visibleRowCache.forEach(function(row){
+      ret += row.height;
+    });
+
+    if (typeof(self.grid.horizontalScrollbarHeight) !== 'undefined' && self.grid.horizontalScrollbarHeight !== undefined && self.grid.horizontalScrollbarHeight > 0) {
+      ret = ret - self.grid.horizontalScrollbarHeight;
+    }
+
+    return ret;
+  };
+
+  GridRenderContainer.prototype.getCanvasWidth = function getCanvasWidth() {
+    var self = this;
+
+    var ret = self.canvasWidth;
+
+    if (typeof(self.verticalScrollbarWidth) !== 'undefined' && self.verticalScrollbarWidth !== undefined && self.verticalScrollbarWidth > 0) {
+      ret = ret - self.verticalScrollbarWidth;
+    }
+
+    return ret;
+  };
+
+  GridRenderContainer.prototype.setRenderedRows = function setRenderedRows(newRows) {
+    this.renderedRows.length = newRows.length;
+    for (var i = 0; i < newRows.length; i++) {
+      this.renderedRows[i] = newRows[i];
+    }
+  };
+
+  GridRenderContainer.prototype.setRenderedColumns = function setRenderedColumns(newColumns) {
+    var self = this;
+
+    // OLD:
+    this.renderedColumns.length = newColumns.length;
+    for (var i = 0; i < newColumns.length; i++) {
+      this.renderedColumns[i] = newColumns[i];
+    }
+    
+    this.updateColumnOffset();
+  };
+
+  GridRenderContainer.prototype.updateColumnOffset = function updateColumnOffset() {
+    // Calculate the width of the columns on the left side that are no longer rendered.
+    //  That will be the offset for the columns as we scroll horizontally.
+    var hiddenColumnsWidth = 0;
+    for (var i = 0; i < this.currentFirstColumn; i++) {
+      hiddenColumnsWidth += this.visibleColumnCache[i].drawnWidth;
+    }
+
+    this.columnOffset = hiddenColumnsWidth;
+  };
+
+  GridRenderContainer.prototype.adjustScrollVertical = function adjustScrollVertical(scrollTop, scrollPercentage, force) {
+    if (this.prevScrollTop === scrollTop && !force) {
+      return;
+    }
+
+    if (typeof(scrollTop) === 'undefined' || scrollTop === undefined || scrollTop === null) {
+      scrollTop = (this.getCanvasHeight() - this.getCanvasWidth()) * scrollPercentage;
+    }
+
+    this.adjustRows(scrollTop, scrollPercentage);
+
+    this.prevScrollTop = scrollTop;
+    this.prevScrolltopPercentage = scrollPercentage;
+
+    this.grid.queueRefresh();
+  };
+
+  GridRenderContainer.prototype.adjustScrollHorizontal = function adjustScrollHorizontal(scrollLeft, scrollPercentage, force) {
+    if (this.prevScrollLeft === scrollLeft && !force) {
+      return;
+    }
+
+    if (typeof(scrollLeft) === 'undefined' || scrollLeft === undefined || scrollLeft === null) {
+      scrollLeft = (this.getCanvasWidth() - this.getViewportWidth()) * scrollPercentage;
+    }
+
+    this.adjustColumns(scrollLeft, scrollPercentage);
+
+    this.prevScrollLeft = scrollLeft;
+    this.prevScrollleftPercentage = scrollPercentage;
+
+    this.grid.queueRefresh();
+  };
+
+  GridRenderContainer.prototype.adjustRows = function adjustRows(scrollTop, scrollPercentage) {
+    var self = this;
+
+    var minRows = self.minRowsToRender();
+
+    var rowCache = self.visibleRowCache;
+
+    var maxRowIndex = rowCache.length - minRows;
+    self.maxRowIndex = maxRowIndex;
+
+    var curRowIndex = self.prevRowScrollIndex;
+
+    // Calculate the scroll percentage according to the scrollTop location, if no percentage was provided
+    if ((typeof(scrollPercentage) === 'undefined' || scrollPercentage === null) && scrollTop) {
+      scrollPercentage = scrollTop / self.getCanvasHeight();
+    }
+    
+    var rowIndex = Math.ceil(Math.min(maxRowIndex, maxRowIndex * scrollPercentage));
+
+    // Define a max row index that we can't scroll past
+    if (rowIndex > maxRowIndex) {
+      rowIndex = maxRowIndex;
+    }
+    
+    var newRange = [];
+    if (rowCache.length > self.grid.options.virtualizationThreshold) {
+      // Have we hit the threshold going down?
+      if (self.prevScrollTop < scrollTop && rowIndex < self.prevRowScrollIndex + self.grid.options.scrollThreshold && rowIndex < maxRowIndex) {
+        return;
+      }
+      //Have we hit the threshold going up?
+      if (self.prevScrollTop > scrollTop && rowIndex > self.prevRowScrollIndex - self.grid.options.scrollThreshold && rowIndex < maxRowIndex) {
+        return;
+      }
+
+      var rangeStart = Math.max(0, rowIndex - self.grid.options.excessRows);
+      var rangeEnd = Math.min(rowCache.length, rowIndex + minRows + self.grid.options.excessRows);
+
+      newRange = [rangeStart, rangeEnd];
+    }
+    else {
+      var maxLen = self.visibleRowCache.length;
+      newRange = [0, Math.max(maxLen, minRows + self.grid.options.excessRows)];
+    }
+
+    self.updateViewableRowRange(newRange);
+
+    self.prevRowScrollIndex = rowIndex;
+  };
+
+  GridRenderContainer.prototype.adjustColumns = function adjustColumns(scrollLeft, scrollPercentage) {
+    var self = this;
+
+    var minCols = self.minColumnsToRender();
+
+    var columnCache = self.visibleColumnCache;
+    var maxColumnIndex = columnCache.length - minCols;
+
+    // Calculate the scroll percentage according to the scrollTop location, if no percentage was provided
+    if ((typeof(scrollPercentage) === 'undefined' || scrollPercentage === null) && scrollLeft) {
+      scrollPercentage = scrollLeft / self.getCanvasWidth();
+    }
+
+    var colIndex = Math.ceil(Math.min(maxColumnIndex, maxColumnIndex * scrollPercentage));
+
+    // Define a max row index that we can't scroll past
+    if (colIndex > maxColumnIndex) {
+      colIndex = maxColumnIndex;
+    }
+    
+    var newRange = [];
+    if (columnCache.length > self.grid.options.columnVirtualizationThreshold && self.getCanvasWidth() > self.getViewportWidth()) {
+      // Have we hit the threshold going down?
+      if (self.prevScrollLeft < scrollLeft && colIndex < self.prevColumnScrollIndex + self.grid.options.horizontalScrollThreshold && colIndex < maxColumnIndex) {
+        return;
+      }
+      //Have we hit the threshold going up?
+      if (self.prevScrollLeft > scrollLeft && colIndex > self.prevColumnScrollIndex - self.grid.options.horizontalScrollThreshold && colIndex < maxColumnIndex) {
+        return;
+      }
+
+      var rangeStart = Math.max(0, colIndex - self.grid.options.excessColumns);
+      var rangeEnd = Math.min(columnCache.length, colIndex + minCols + self.grid.options.excessColumns);
+
+      newRange = [rangeStart, rangeEnd];
+    }
+    else {
+      var maxLen = self.visibleColumnCache.length;
+
+      newRange = [0, Math.max(maxLen, minCols + self.grid.options.excessColumns)];
+    }
+    
+    self.updateViewableColumnRange(newRange);
+
+    self.prevColumnScrollIndex = colIndex;
+  };
+
+  // Method for updating the visible rows
+  GridRenderContainer.prototype.updateViewableRowRange = function updateViewableRowRange(renderedRange) {
+    // Slice out the range of rows from the data
+    // var rowArr = uiGridCtrl.grid.rows.slice(renderedRange[0], renderedRange[1]);
+    var rowArr = this.visibleRowCache.slice(renderedRange[0], renderedRange[1]);
+
+    // Define the top-most rendered row
+    this.currentTopRow = renderedRange[0];
+
+    // TODO(c0bra): make this method!
+    this.setRenderedRows(rowArr);
+  };
+
+  // Method for updating the visible columns
+  GridRenderContainer.prototype.updateViewableColumnRange = function updateViewableColumnRange(renderedRange) {
+    // Slice out the range of rows from the data
+    // var columnArr = uiGridCtrl.grid.columns.slice(renderedRange[0], renderedRange[1]);
+    var columnArr = this.visibleColumnCache.slice(renderedRange[0], renderedRange[1]);
+
+    // Define the left-most rendered columns
+    this.currentFirstColumn = renderedRange[0];
+
+    this.setRenderedColumns(columnArr);
+  };
+
+  GridRenderContainer.prototype.rowStyle = function (index) {
+    var self = this;
+
+    var styles = {};
+    
+    if (index === 0 && self.currentTopRow !== 0) {
+      // The row offset-top is just the height of the rows above the current top-most row, which are no longer rendered
+      var hiddenRowWidth = (self.currentTopRow) * self.grid.options.rowHeight;
+
+      // return { 'margin-top': hiddenRowWidth + 'px' };
+      styles['margin-top'] = hiddenRowWidth + 'px';
+    }
+
+    if (self.currentFirstColumn !== 0) {
+      if (self.grid.isRTL()) {
+        styles['margin-right'] = self.columnOffset + 'px';
+      }
+      else {
+        styles['margin-left'] = self.columnOffset + 'px';
+      }
+    }
+
+    return styles;
+  };
+
+  GridRenderContainer.prototype.columnStyle = function (index) {
+    var self = this;
+    
+    if (index === 0 && self.currentFirstColumn !== 0) {
+      var offset = self.columnOffset;
+
+      if (self.grid.isRTL()) {
+        return { 'margin-right': offset + 'px' };
+      }
+      else {
+        return { 'margin-left': offset + 'px' };
+      }
+    }
+
+    return null;
+  };
+
+  GridRenderContainer.prototype.updateColumnWidths = function () {
+    var self = this;
+
+    var asterisksArray = [],
+        percentArray = [],
+        manualArray = [],
+        asteriskNum = 0,
+        totalWidth = 0;
+
+    // Get the width of the viewport
+    var availableWidth = self.getViewportWidth();
+
+    if (typeof(self.grid.verticalScrollbarWidth) !== 'undefined' && self.grid.verticalScrollbarWidth !== undefined && self.grid.verticalScrollbarWidth > 0) {
+      availableWidth = availableWidth + self.grid.verticalScrollbarWidth;
+    }
+
+    // The total number of columns
+    // var equalWidthColumnCount = columnCount = uiGridCtrl.grid.options.columnDefs.length;
+    // var equalWidth = availableWidth / equalWidthColumnCount;
+
+    // The last column we processed
+    var lastColumn;
+
+    var manualWidthSum = 0;
+
+    var canvasWidth = 0;
+
+    var ret = '';
+
+
+    // uiGridCtrl.grid.columns.forEach(function(column, i) {
+
+    var columnCache = self.visibleColumnCache;
+
+    columnCache.forEach(function(column, i) {
+      // ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; left: ' + left + 'px; }';
+      //var colWidth = (typeof(c.width) !== 'undefined' && c.width !== undefined) ? c.width : equalWidth;
+
+      // Skip hidden columns
+      if (!column.visible) { return; }
+
+      var colWidth,
+          isPercent = false;
+
+      if (!angular.isNumber(column.width)) {
+        isPercent = isNaN(column.width) && gridUtil.endsWith(column.width, "%");
+      }
+
+      if (angular.isString(column.width) && column.width.indexOf('*') !== -1) { //  we need to save it until the end to do the calulations on the remaining width.
+        asteriskNum = parseInt(asteriskNum + column.width.length, 10);
+        
+        asterisksArray.push(column);
+      }
+      else if (isPercent) { // If the width is a percentage, save it until the very last.
+        percentArray.push(column);
+      }
+      else if (angular.isNumber(column.width)) {
+        manualWidthSum = parseInt(manualWidthSum + column.width, 10);
+        
+        canvasWidth = parseInt(canvasWidth, 10) + parseInt(column.width, 10);
+
+        column.drawnWidth = column.width;
+      }
+    });
+
+    // Get the remaining width (available width subtracted by the manual widths sum)
+    var remainingWidth = availableWidth - manualWidthSum;
+
+    var i, column, colWidth;
+
+    if (percentArray.length > 0) {
+      // Pre-process to make sure they're all within any min/max values
+      for (i = 0; i < percentArray.length; i++) {
+        column = percentArray[i];
+
+        var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+
+        colWidth = parseInt(percent * remainingWidth, 10);
+
+        if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+          colWidth = column.colDef.minWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // Remove this element from the percent array so it's not processed below
+          percentArray.splice(i, 1);
+        }
+        else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+          colWidth = column.colDef.maxWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // Remove this element from the percent array so it's not processed below
+          percentArray.splice(i, 1);
+        }
+      }
+
+      percentArray.forEach(function(column) {
+        var percent = parseInt(column.width.replace(/%/g, ''), 10) / 100;
+        var colWidth = parseInt(percent * remainingWidth, 10);
+
+        canvasWidth += colWidth;
+
+        column.drawnWidth = colWidth;
+      });
+    }
+
+    if (asterisksArray.length > 0) {
+      var asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+       // Pre-process to make sure they're all within any min/max values
+      for (i = 0; i < asterisksArray.length; i++) {
+        column = asterisksArray[i];
+
+        colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+        if (column.colDef.minWidth && colWidth < column.colDef.minWidth) {
+          colWidth = column.colDef.minWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+          asteriskNum--;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          lastColumn = column;
+
+          // Remove this element from the percent array so it's not processed below
+          asterisksArray.splice(i, 1);
+        }
+        else if (column.colDef.maxWidth && colWidth > column.colDef.maxWidth) {
+          colWidth = column.colDef.maxWidth;
+
+          remainingWidth = remainingWidth - colWidth;
+          asteriskNum--;
+
+          canvasWidth += colWidth;
+          column.drawnWidth = colWidth;
+
+          // Remove this element from the percent array so it's not processed below
+          asterisksArray.splice(i, 1);
+        }
+      }
+
+      // Redo the asterisk value, as we may have removed columns due to width constraints
+      asteriskVal = parseInt(remainingWidth / asteriskNum, 10);
+
+      asterisksArray.forEach(function(column) {
+        var colWidth = parseInt(asteriskVal * column.width.length, 10);
+
+        canvasWidth += colWidth;
+
+        column.drawnWidth = colWidth;
+      });
+    }
+
+    // If the grid width didn't divide evenly into the column widths and we have pixels left over, dole them out to the columns one by one to make everything fit
+    var leftoverWidth = availableWidth - parseInt(canvasWidth, 10);
+
+    if (leftoverWidth > 0 && canvasWidth > 0 && canvasWidth < availableWidth) {
+      var variableColumn = false;
+      // uiGridCtrl.grid.columns.forEach(function(col) {
+      columnCache.forEach(function(col) {
+        if (col.width && !angular.isNumber(col.width)) {
+          variableColumn = true;
+        }
+      });
+
+      if (variableColumn) {
+        var remFn = function (column) {
+          if (leftoverWidth > 0) {
+            column.drawnWidth = column.drawnWidth + 1;
+            canvasWidth = canvasWidth + 1;
+            leftoverWidth--;
+          }
+        };
+        while (leftoverWidth > 0) {
+          columnCache.forEach(remFn);
+        }
+      }
+    }
+
+    if (canvasWidth < availableWidth) {
+      canvasWidth = availableWidth;
+    }
+
+    // Build the CSS
+    columnCache.forEach(function (column) {
+      ret = ret + column.getColClassDefinition();
+    });
+
+    // Add the vertical scrollbar width back in to the canvas width, it's taken out in getCanvasWidth
+    if (self.grid.verticalScrollbarWidth) {
+      canvasWidth = canvasWidth + self.grid.verticalScrollbarWidth;
+    }
+    // canvasWidth = canvasWidth + 1;
+
+    self.canvasWidth = parseInt(canvasWidth, 10);
+
+    // Return the styles back to buildStyles which pops them into the `customStyles` scope variable
+    // return ret;
+
+    // Set this render container's column styles so they can be used in style computation
+    this.columnStyles = ret;
+  };
+
+  return GridRenderContainer;
+}]);
+
+})();
+
+(function(){
+
+angular.module('ui.grid')
+.factory('GridRow', ['gridUtil', function(gridUtil) {
+
+   /**
+   * @ngdoc function
+   * @name ui.grid.class:GridRow
+   * @description GridRow is the viewModel for one logical row on the grid.  A grid Row is not necessarily a one-to-one
+   * relation to gridOptions.data.
+   * @param {object} entity the array item from GridOptions.data
+   * @param {number} index the current position of the row in the array
+   * @param {Grid} reference to the parent grid
+   */
+  function GridRow(entity, index, grid) {
+
+     /**
+      *  @ngdoc object
+      *  @name grid
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description A reference back to the grid
+      */
+     this.grid = grid;
+
+     /**
+      *  @ngdoc object
+      *  @name entity
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description A reference to an item in gridOptions.data[]
+      */
+    this.entity = entity;
+
+     /**
+      *  @ngdoc object
+      *  @name uid
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description  UniqueId of row
+      */
+     this.uid = gridUtil.nextUid();
+
+     /**
+      *  @ngdoc object
+      *  @name visible
+      *  @propertyOf  ui.grid.class:GridRow
+      *  @description If true, the row will be rendered
+      */
+    // Default to true
+    this.visible = true;
+
+  /**
+    *  @ngdoc object
+    *  @name height
+    *  @propertyOf  ui.grid.class:GridRow
+    *  @description height of each individual row
+    */
+    this.height = grid.options.rowHeight;
+  }
+
+  /**
+   * @ngdoc function
+   * @name getQualifiedColField
+   * @methodOf ui.grid.class:GridRow
+   * @description returns the qualified field name as it exists on scope
+   * ie: row.entity.fieldA
+   * @param {GridCol} col column instance
+   * @returns {string} resulting name that can be evaluated on scope
+   */
+  GridRow.prototype.getQualifiedColField = function(col) {
+    return 'row.' + this.getEntityQualifiedColField(col);
+  };
+
+    /**
+     * @ngdoc function
+     * @name getEntityQualifiedColField
+     * @methodOf ui.grid.class:GridRow
+     * @description returns the qualified field name minus the row path
+     * ie: entity.fieldA
+     * @param {GridCol} col column instance
+     * @returns {string} resulting name that can be evaluated against a row
+     */
+  GridRow.prototype.getEntityQualifiedColField = function(col) {
+    return gridUtil.preEval('entity.' + col.field);
+  };
+  
+  
+  /**
+   * @ngdoc function
+   * @name setRowInvisible
+   * @methodOf  ui.grid.class:GridRow
+   * @description Sets an override on the row that forces it to always
+   * be invisible, and if the row is currently visible then marks it
+   * as invisible and refreshes the grid.  Emits the rowsVisibleChanged
+   * event if it changed the row visibility
+   * @param {GridRow} row row to force invisible, needs to be a GridRow,
+   * which can be found from your data entity using grid.findRow
+   */
+  GridRow.prototype.setRowInvisible = function (row) {
+    if (row !== null) {
+      row.forceInvisible = true;
+      
+      if ( row.visible ){
+        row.visible = false;
+        row.grid.refresh();
+        row.grid.api.core.raise.rowsVisibleChanged();
+      }
+    }        
+  };
+
+  /**
+   * @ngdoc function
+   * @name clearRowInvisible
+   * @methodOf ui.grid.class:GridRow
+   * @description Clears any override on the row visibility, returning it 
+   * to normal visibility calculations.  If the row is currently invisible
+   * then sets it to visible and calls refresh and emits the rowsVisibleChanged
+   * event
+   * TODO: if filter in action, then is this right?
+   * @param {GridRow} row row clear force invisible, needs to be a GridRow,
+   * which can be found from your data entity using grid.findRow
+   */
+  GridRow.prototype.clearRowInvisible = function (row) {
+    if (row !== null) {
+      row.forceInvisible = false;
+      
+      if ( !row.visible ){
+        row.visible = true;
+        row.grid.refresh();
+        row.grid.api.core.raise.rowsVisibleChanged();
+      }
+    }        
+  };
+
+  return GridRow;
+}]);
+
+})();
+(function () {
+  'use strict';
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.service:gridClassFactory
+   *
+   *  @description factory to return dom specific instances of a grid
+   *
+   */
+  angular.module('ui.grid').service('gridClassFactory', ['gridUtil', '$q', '$compile', '$templateCache', 'uiGridConstants', 'Grid', 'GridColumn', 'GridRow',
+    function (gridUtil, $q, $compile, $templateCache, uiGridConstants, Grid, GridColumn, GridRow) {
+
+      var service = {
+        /**
+         * @ngdoc method
+         * @name createGrid
+         * @methodOf ui.grid.service:gridClassFactory
+         * @description Creates a new grid instance. Each instance will have a unique id
+         * @param {object} options An object map of options to pass into the created grid instance.
+         * @returns {Grid} grid
+         */
+        createGrid : function(options) {
+          options = (typeof(options) !== 'undefined') ? options : {};
+          options.id = gridUtil.newId();
+          var grid = new Grid(options);
+
+          // NOTE/TODO: rowTemplate should always be defined...
+          if (grid.options.rowTemplate) {
+            var rowTemplateFnPromise = $q.defer();
+            grid.getRowTemplateFn = rowTemplateFnPromise.promise;
+            
+            gridUtil.getTemplate(grid.options.rowTemplate)
+              .then(
+                function (template) {
+                  var rowTemplateFn = $compile(template);
+                  rowTemplateFnPromise.resolve(rowTemplateFn);
+                },
+                function (res) {
+                  // Todo handle response error here?
+                  throw new Error("Couldn't fetch/use row template '" + grid.options.rowTemplate + "'");
+                });
+          }
+
+          grid.registerColumnBuilder(service.defaultColumnBuilder);
+
+          // Reset all rows to visible initially
+          grid.registerRowsProcessor(function allRowsVisible(rows) {
+            rows.forEach(function (row) {
+              row.visible = !row.forceInvisible;
+            });
+
+            return rows;
+          });
+
+          grid.registerColumnsProcessor(function allColumnsVisible(columns) {
+            columns.forEach(function (column) {
+              column.visible = true;
+            });
+
+            return columns;
+          });
+
+          grid.registerColumnsProcessor(function(renderableColumns) {
+              renderableColumns.forEach(function (column) {
+                  if (column.colDef.visible === false) {
+                      column.visible = false;
+                  }
+              });
+
+              return renderableColumns;
+          });
+
+
+
+          if (grid.options.enableFiltering) {
+            grid.registerRowsProcessor(grid.searchRows);
+          }
+
+          // Register the default row processor, it sorts rows by selected columns
+          if (grid.options.externalSort && angular.isFunction(grid.options.externalSort)) {
+            grid.registerRowsProcessor(grid.options.externalSort);
+          }
+          else {
+            grid.registerRowsProcessor(grid.sortByColumn);
+          }
+
+          return grid;
+        },
+
+        /**
+         * @ngdoc function
+         * @name defaultColumnBuilder
+         * @methodOf ui.grid.service:gridClassFactory
+         * @description Processes designTime column definitions and applies them to col for the
+         *              core grid features
+         * @param {object} colDef reference to column definition
+         * @param {GridColumn} col reference to gridCol
+         * @param {object} gridOptions reference to grid options
+         */
+        defaultColumnBuilder: function (colDef, col, gridOptions) {
+
+          var templateGetPromises = [];
+
+          /**
+           * @ngdoc property
+           * @name headerCellTemplate
+           * @propertyOf ui.grid.class:GridOptions.columnDef
+           * @description a custom template for the header for this column.  The default
+           * is ui-grid/uiGridHeaderCell
+           *
+           */
+          if (!colDef.headerCellTemplate) {
+            col.providedHeaderCellTemplate = 'ui-grid/uiGridHeaderCell';
+          } else {
+            col.providedHeaderCellTemplate = colDef.headerCellTemplate;
+          }
+
+          /**
+           * @ngdoc property
+           * @name cellTemplate
+           * @propertyOf ui.grid.class:GridOptions.columnDef
+           * @description a custom template for each cell in this column.  The default
+           * is ui-grid/uiGridCell.  If you are using the cellNav feature, this template
+           * must contain a div that can receive focus.
+           *
+           */
+          if (!colDef.cellTemplate) {
+            col.providedCellTemplate = 'ui-grid/uiGridCell';
+          } else {
+            col.providedCellTemplate = colDef.cellTemplate;
+          }
+
+          col.cellTemplatePromise = gridUtil.getTemplate(col.providedCellTemplate);
+          templateGetPromises.push(col.cellTemplatePromise
+            .then(
+              function (template) {
+                col.cellTemplate = template.replace(uiGridConstants.CUSTOM_FILTERS, col.cellFilter ? "|" + col.cellFilter : "");
+              },
+              function (res) {
+                throw new Error("Couldn't fetch/use colDef.cellTemplate '" + colDef.cellTemplate + "'");
+              })
+          );
+
+          templateGetPromises.push(gridUtil.getTemplate(col.providedHeaderCellTemplate)
+              .then(
+              function (template) {
+                col.headerCellTemplate = template.replace(uiGridConstants.CUSTOM_FILTERS, col.headerCellFilter ? "|" + col.headerCellFilter : "");
+              },
+              function (res) {
+                throw new Error("Couldn't fetch/use colDef.headerCellTemplate '" + colDef.headerCellTemplate + "'");
+              })
+          );
+
+          // Create a promise for the compiled element function
+          col.compiledElementFnDefer = $q.defer();
+
+          return $q.all(templateGetPromises);
+        }
+
+      };
+
+      //class definitions (moved to separate factories)
+
+      return service;
+    }]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+function escapeRegExp(str) {
+  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+}
+
+function QuickCache() {
+  var c = function(get, set) {
+    // Return the cached value of 'get' if it's stored
+    if (get && c.cache[get]) {
+      return c.cache[get];
+    }
+    // Otherwise set it and return it
+    else if (get && set) {
+      c.cache[get] = set;
+      return c.cache[get];
+    }
+    else {
+      return undefined;
+    }
+  };
+
+  c.cache = {};
+
+  c.clear = function () {
+    c.cache = {};
+  };
+
+  return c;
+}
+
+/**
+ *  @ngdoc service
+ *  @name ui.grid.service:rowSearcher
+ *
+ *  @description Service for searching/filtering rows based on column value conditions.
+ */
+module.service('rowSearcher', ['gridUtil', 'uiGridConstants', function (gridUtil, uiGridConstants) {
+  var defaultCondition = uiGridConstants.filter.STARTS_WITH;
+
+  var rowSearcher = {};
+
+  // rowSearcher.searchColumn = function searchColumn(condition, item) {
+  //   var result;
+
+  //   var col = self.fieldMap[condition.columnDisplay];
+
+  //   if (!col) {
+  //       return false;
+  //   }
+  //   var sp = col.cellFilter.split(':');
+  //   var filter = col.cellFilter ? $filter(sp[0]) : null;
+  //   var value = item[condition.column] || item[col.field.split('.')[0]];
+  //   if (value === null || value === undefined) {
+  //       return false;
+  //   }
+  //   if (typeof filter === "function") {
+  //       var filterResults = filter(typeof value === "object" ? evalObject(value, col.field) : value, sp[1]).toString();
+  //       result = condition.regex.test(filterResults);
+  //   }
+  //   else {
+  //       result = condition.regex.test(typeof value === "object" ? evalObject(value, col.field).toString() : value.toString());
+  //   }
+  //   if (result) {
+  //       return true;
+  //   }
+  //   return false;
+  // };
+
+  /**
+   * @ngdoc function
+   * @name getTerm
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Get the term from a filter
+   * Trims leading and trailing whitespace
+   * @param {object} filter object to use
+   * @returns {object} Parsed term
+   */
+  rowSearcher.getTerm = function getTerm(filter) {
+    if (typeof(filter.term) === 'undefined') { return filter.term; }
+    
+    var term = filter.term;
+
+    // Strip leading and trailing whitespace if the term is a string
+    if (typeof(term) === 'string') {
+      term = term.trim();
+    }
+
+    return term;
+  };
+
+  /**
+   * @ngdoc function
+   * @name stripTerm
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Remove leading and trailing asterisk (*) from the filter's term
+   * @param {object} filter object to use
+   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
+   */
+  rowSearcher.stripTerm = function stripTerm(filter) {
+    var term = rowSearcher.getTerm(filter);
+
+    if (typeof(term) === 'string') {
+      return escapeRegExp(term.replace(/(^\*|\*$)/g, ''));
+    }
+    else {
+      return term;
+    }
+  };
+
+  /**
+   * @ngdoc function
+   * @name guessCondition
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Guess the condition for a filter based on its term
+   * <br>
+   * Defaults to STARTS_WITH. Uses CONTAINS for strings beginning and ending with *s (*bob*).
+   * Uses STARTS_WITH for strings ending with * (bo*). Uses ENDS_WITH for strings starting with * (*ob).
+   * @param {object} filter object to use
+   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
+   */
+  rowSearcher.guessCondition = function guessCondition(filter) {
+    if (typeof(filter.term) === 'undefined' || !filter.term) {
+      return defaultCondition;
+    }
+
+    var term = rowSearcher.getTerm(filter);
+    
+    // Term starts with and ends with a *, use 'contains' condition
+    // if (/^\*[\s\S]+?\*$/.test(term)) {
+    //   return uiGridConstants.filter.CONTAINS;
+    // }
+    // // Term starts with a *, use 'ends with' condition
+    // else if (/^\*/.test(term)) {
+    //   return uiGridConstants.filter.ENDS_WITH;
+    // }
+    // // Term ends with a *, use 'starts with' condition
+    // else if (/\*$/.test(term)) {
+    //   return uiGridConstants.filter.STARTS_WITH;
+    // }
+    // // Default to default condition
+    // else {
+    //   return defaultCondition;
+    // }
+
+    // If the term has *s then turn it into a regex
+    if (/\*/.test(term)) {
+      var regexpFlags = '';
+      if (!filter.flags || !filter.flags.caseSensitive) {
+        regexpFlags += 'i';
+      }
+
+      var reText = term.replace(/(\\)?\*/g, function ($0, $1) { return $1 ? $0 : '[\\s\\S]*?'; });
+      return new RegExp('^' + reText + '$', regexpFlags);
+    }
+    // Otherwise default to default condition
+    else {
+      return defaultCondition;
+    }
+  };
+
+  rowSearcher.runColumnFilter = function runColumnFilter(grid, row, column, termCache, i, filter) {
+    // Cache typeof condition
+    var conditionType = typeof(filter.condition);
+
+    // Default to CONTAINS condition
+    if (conditionType === 'undefined' || !filter.condition) {
+      filter.condition = uiGridConstants.filter.CONTAINS;
+    }
+
+    // Term to search for.
+    var term = rowSearcher.stripTerm(filter);
+
+    if (term === null || term === undefined || term === '') {
+      return true;
+    }
+
+    // Get the column value for this row
+    var value = grid.getCellValue(row, column);
+
+    var regexpFlags = '';
+    if (!filter.flags || !filter.flags.caseSensitive) {
+      regexpFlags += 'i';
+    }
+
+    var cacheId = column.field + i;
+
+    // If the filter's condition is a RegExp, then use it
+    if (filter.condition instanceof RegExp) {
+      if (!filter.condition.test(value)) {
+        return false;
+      }
+    }
+    // If the filter's condition is a function, run it
+    else if (conditionType === 'function') {
+      return filter.condition(term, value, row, column);
+    }
+    else if (filter.condition === uiGridConstants.filter.STARTS_WITH) {
+      var startswithRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp('^' + term, regexpFlags));
+
+      if (!startswithRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.ENDS_WITH) {
+      var endswithRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp(term + '$', regexpFlags));
+
+      if (!endswithRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.CONTAINS) {
+      var containsRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId, new RegExp(term, regexpFlags));
+
+      if (!containsRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.EXACT) {
+      var exactRE = termCache(cacheId) ? termCache(cacheId) : termCache(cacheId,  new RegExp('^' + term + '$', regexpFlags));
+
+      if (!exactRE.test(value)) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.GREATER_THAN) {
+      if (value <= term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.GREATER_THAN_OR_EQUAL) {
+      if (value < term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.LESS_THAN) {
+      if (value >= term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.LESS_THAN_OR_EQUAL) {
+      if (value > term) {
+        return false;
+      }
+    }
+    else if (filter.condition === uiGridConstants.filter.NOT_EQUAL) {
+      if (!angular.equals(value, term)) {
+        return false;
+      }
+    }
+
+    return true;
+  };
+
+  /**
+   * @ngdoc boolean
+   * @name useExternalFiltering
+   * @propertyOf ui.grid.class:GridOptions
+   * @description False by default. When enabled, this setting suppresses the internal filtering.
+   * All UI logic will still operate, allowing filter conditions to be set and modified.
+   * 
+   * The external filter logic can listen for the `filterChange` event, which fires whenever
+   * a filter has been adjusted.
+   */
+  /**
+   * @ngdoc function
+   * @name searchColumn
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Process filters on a given column against a given row. If the row meets the conditions on all the filters, return true.
+   * @param {Grid} grid Grid to search in
+   * @param {GridRow} row Row to search on
+   * @param {GridCol} column Column with the filters to use
+   * @returns {boolean} Whether the column matches or not.
+   */
+  rowSearcher.searchColumn = function searchColumn(grid, row, column, termCache) {
+    var filters = [];
+
+    if (grid.options.useExternalFiltering) {
+      return true;
+    }
+    
+    if (typeof(column.filters) !== 'undefined' && column.filters && column.filters.length > 0) {
+      filters = column.filters;
+    } else {
+      // If filters array is not there, assume no filters for this column. 
+      // This array should have been built in GridColumn::updateColumnDef.
+      return true;
+    }
+    
+    for (var i in filters) {
+      var filter = filters[i];
+
+      /*
+        filter: {
+          term: 'blah', // Search term to search for, could be a string, integer, etc.
+          condition: uiGridConstants.filter.CONTAINS // Type of match to do. Defaults to CONTAINS (i.e. looking in a string), but could be EXACT, GREATER_THAN, etc.
+          flags: { // Flags for the conditions
+            caseSensitive: false // Case-sensitivity defaults to false
+          }
+        }
+      */
+     
+      // Check for when no condition is supplied. In this case, guess the condition
+      // to use based on the filter's term. Cache this result.
+      if (!filter.condition) {
+        // Cache custom conditions, building the RegExp takes time
+        var conditionCacheId = 'cond-' + column.field + '-' + filter.term;
+        var condition = termCache(conditionCacheId) ? termCache(conditionCacheId) : termCache(conditionCacheId, rowSearcher.guessCondition(filter));
+
+        // Create a surrogate filter so as not to change
+        // the actual columnDef.filters.
+        filter = {
+          // Copy over the search term
+          term: filter.term,
+          // Use the guessed condition
+          condition: condition,
+          // Set flags, using passed flags if present
+          flags: angular.extend({
+            caseSensitive: false
+          }, filter.flags)
+        };
+      }
+
+      var ret = rowSearcher.runColumnFilter(grid, row, column, termCache, i, filter);
+      if (!ret) {
+        return false;
+      }
+    }
+
+    return true;
+    // }
+    // else {
+    //   // No filter conditions, default to true
+    //   return true;
+    // }
+  };
+
+  /**
+   * @ngdoc function
+   * @name search
+   * @methodOf ui.grid.service:rowSearcher
+   * @description Run a search across
+   * @param {Grid} grid Grid instance to search inside
+   * @param {Array[GridRow]} rows GridRows to filter
+   * @param {Array[GridColumn]} columns GridColumns with filters to process
+   */
+  rowSearcher.search = function search(grid, rows, columns) {
+    // Don't do anything if we weren't passed any rows
+    if (!rows) {
+      return;
+    }
+
+    // Create a term cache
+    var termCache = new QuickCache();
+
+    // Build filtered column list
+    var filterCols = [];
+    columns.forEach(function (col) {
+      if (typeof(col.filters) !== 'undefined' && col.filters.length > 0) {
+        filterCols.push(col);
+      }
+      else if (typeof(col.filter) !== 'undefined' && col.filter && typeof(col.filter.term) !== 'undefined' && col.filter.term) {
+        filterCols.push(col);
+      }
+    });
+    
+    if (filterCols.length > 0) {
+      filterCols.forEach(function foreachFilterCol(col) {
+        rows.forEach(function foreachRow(row) {
+          if (row.forceInvisible || !rowSearcher.searchColumn(grid, row, col, termCache)) {
+            row.visible = false;
+          }
+        });
+      });
+
+      if (grid.api.core.raise.rowsVisibleChanged) {
+        grid.api.core.raise.rowsVisibleChanged();
+      }
+
+      // rows.forEach(function (row) {
+      //   var matchesAllColumns = true;
+
+      //   for (var i in filterCols) {
+      //     var col = filterCols[i];
+
+      //     if (!rowSearcher.searchColumn(grid, row, col, termCache)) {
+      //       matchesAllColumns = false;
+
+      //       // Stop processing other terms
+      //       break;
+      //     }
+      //   }
+
+      //   // Row doesn't match all the terms, don't display it
+      //   if (!matchesAllColumns) {
+      //     row.visible = false;
+      //   }
+      //   else {
+      //     row.visible = true;
+      //   }
+      // });
+    }
+
+    // Reset the term cache
+    termCache.clear();
+
+    return rows;
+  };
+
+  return rowSearcher;
+}]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+/**
+ * @ngdoc object
+ * @name ui.grid.class:RowSorter
+ * @description RowSorter provides the default sorting mechanisms, 
+ * including guessing column types and applying appropriate sort 
+ * algorithms
+ * 
+ */ 
+
+module.service('rowSorter', ['$parse', 'uiGridConstants', function ($parse, uiGridConstants) {
+  var currencyRegexStr = 
+    '(' +
+    uiGridConstants.CURRENCY_SYMBOLS
+      .map(function (a) { return '\\' + a; }) // Escape all the currency symbols ($ at least will jack up this regex)
+      .join('|') + // Join all the symbols together with |s
+    ')?';
+
+  // /^[-+]?[£$¤¥]?[\d,.]+%?$/
+  var numberStrRegex = new RegExp('^[-+]?' + currencyRegexStr + '[\\d,.]+' + currencyRegexStr + '%?$');
+
+  var rowSorter = {
+    // Cache of sorting functions. Once we create them, we don't want to keep re-doing it
+    //   this takes a piece of data from the cell and tries to determine its type and what sorting
+    //   function to use for it
+    colSortFnCache: []
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name guessSortFn
+   * @description Assigns a sort function to use based on the itemType in the column
+   * @param {string} itemType one of 'number', 'boolean', 'string', 'date', 'object'.  And
+   * error will be thrown for any other type.
+   * @returns {function} a sort function that will sort that type
+   */
+  rowSorter.guessSortFn = function guessSortFn(itemType) {
+    switch (itemType) {
+      case "number":
+        return rowSorter.sortNumber;
+      case "boolean":
+        return rowSorter.sortBool;
+      case "string":
+        return rowSorter.sortAlpha;
+      case "date":
+        return rowSorter.sortDate;
+      case "object":
+        return rowSorter.basicSort;
+      default:
+        throw new Error('No sorting function found for type:' + itemType);
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name handleNulls
+   * @description Sorts nulls and undefined to the bottom (top when
+   * descending).  Called by each of the internal sorters before
+   * attempting to sort.  Note that this method is available on the core api
+   * via gridApi.core.sortHandleNulls
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} null if there were no nulls/undefineds, otherwise returns
+   * a sort value that should be passed back from the sort function
+   */
+  rowSorter.handleNulls = function handleNulls(a, b) {
+    // We want to allow zero values and false values to be evaluated in the sort function
+    if ((!a && a !== 0 && a !== false) || (!b && b !== 0 && b !== false)) {
+      // We want to force nulls and such to the bottom when we sort... which effectively is "greater than"
+      if ((!a && a !== 0 && a !== false) && (!b && b !== 0 && b !== false)) {
+        return 0;
+      }
+      else if (!a && a !== 0 && a !== false) {
+        return 1;
+      }
+      else if (!b && b !== 0 && b !== false) {
+        return -1;
+      }
+    }
+    return null;
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name basicSort
+   * @description Sorts any values that provide the < method, including strings
+   * or numbers.  Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.basicSort = function basicSort(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      if (a === b) {
+        return 0;
+      }
+      if (a < b) {
+        return -1;
+      }
+      return 1;
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sortNumber
+   * @description Sorts numerical values.  Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.sortNumber = function sortNumber(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      return a - b;
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sortNumberStr
+   * @description Sorts numerical values that are stored in a string (i.e. parses them to numbers first).  
+   * Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.sortNumberStr = function sortNumberStr(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      var numA, // The parsed number form of 'a'
+          numB, // The parsed number form of 'b'
+          badA = false,
+          badB = false;
+  
+      // Try to parse 'a' to a float
+      numA = parseFloat(a.replace(/[^0-9.-]/g, ''));
+  
+      // If 'a' couldn't be parsed to float, flag it as bad
+      if (isNaN(numA)) {
+          badA = true;
+      }
+  
+      // Try to parse 'b' to a float
+      numB = parseFloat(b.replace(/[^0-9.-]/g, ''));
+  
+      // If 'b' couldn't be parsed to float, flag it as bad
+      if (isNaN(numB)) {
+          badB = true;
+      }
+  
+      // We want bad ones to get pushed to the bottom... which effectively is "greater than"
+      if (badA && badB) {
+          return 0;
+      }
+  
+      if (badA) {
+          return 1;
+      }
+  
+      if (badB) {
+          return -1;
+      }
+  
+      return numA - numB;
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sortAlpha
+   * @description Sorts string values. Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.sortAlpha = function sortAlpha(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      var strA = a.toLowerCase(),
+          strB = b.toLowerCase();
+  
+      return strA === strB ? 0 : (strA < strB ? -1 : 1);
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sortDate
+   * @description Sorts date values. Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.sortDate = function sortDate(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      var timeA = a.getTime(),
+          timeB = b.getTime();
+  
+      return timeA === timeB ? 0 : (timeA < timeB ? -1 : 1);
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sortBool
+   * @description Sorts boolean values, true is considered larger than false. 
+   * Handles nulls and undefined through calling handleNulls 
+   * @param {object} a sort value a
+   * @param {object} b sort value b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.sortBool = function sortBool(a, b) {
+    var nulls = rowSorter.handleNulls(a, b);
+    if ( nulls !== null ){
+      return nulls;
+    } else {
+      if (a && b) {
+        return 0;
+      }
+  
+      if (!a && !b) {
+        return 0;
+      }
+      else {
+        return a ? 1 : -1;
+      }
+    }
+  };
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name getSortFn
+   * @description Get the sort function for the column.  Looks first in 
+   * rowSorter.colSortFnCache using the column name, failing that it
+   * looks at col.sortingAlgorithm (and puts it in the cache), failing that
+   * it guesses the sort algorithm based on the data type.
+   * 
+   * The cache currently seems a bit pointless, as none of the work we do is
+   * processor intensive enough to need caching.  Presumably in future we might
+   * inspect the row data itself to guess the sort function, and in that case
+   * it would make sense to have a cache, the infrastructure is in place to allow
+   * that.
+   * 
+   * @param {Grid} grid the grid to consider
+   * @param {GridCol} col the column to find a function for
+   * @param {array} rows an array of grid rows.  Currently unused, but presumably in future
+   * we might inspect the rows themselves to decide what sort of data might be there
+   * @returns {function} the sort function chosen for the column
+   */
+  rowSorter.getSortFn = function getSortFn(grid, col, rows) {
+    var sortFn, item;
+
+    // See if we already figured out what to use to sort the column and have it in the cache
+    if (rowSorter.colSortFnCache[col.colDef.name]) {
+      sortFn = rowSorter.colSortFnCache[col.colDef.name];
+    }
+    // If the column has its OWN sorting algorithm, use that
+    else if (col.sortingAlgorithm !== undefined) {
+      sortFn = col.sortingAlgorithm;
+      rowSorter.colSortFnCache[col.colDef.name] = col.sortingAlgorithm;
+    }
+    // Try and guess what sort function to use
+    else {
+      // Guess the sort function
+      sortFn = rowSorter.guessSortFn(col.colDef.type);
+
+      // If we found a sort function, cache it
+      if (sortFn) {
+        rowSorter.colSortFnCache[col.colDef.name] = sortFn;
+      }
+      else {
+        // We assign the alpha sort because anything that is null/undefined will never get passed to
+        // the actual sorting function. It will get caught in our null check and returned to be sorted
+        // down to the bottom
+        sortFn = rowSorter.sortAlpha;
+      }
+    }
+
+    return sortFn;
+  };
+
+
+
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name prioritySort
+   * @description Used where multiple columns are present in the sort criteria,
+   * we determine which column should take precedence in the sort by sorting
+   * the columns based on their sort.priority
+   * 
+   * @param {gridColumn} a column a
+   * @param {gridColumn} b column b
+   * @returns {number} normal sort function, returns -ve, 0, +ve
+   */
+  rowSorter.prioritySort = function (a, b) {
+    // Both columns have a sort priority
+    if (a.sort.priority !== undefined && b.sort.priority !== undefined) {
+      // A is higher priority
+      if (a.sort.priority < b.sort.priority) {
+        return -1;
+      }
+      // Equal
+      else if (a.sort.priority === b.sort.priority) {
+        return 0;
+      }
+      // B is higher
+      else {
+        return 1;
+      }
+    }
+    // Only A has a priority
+    else if (a.sort.priority || a.sort.priority === 0) {
+      return -1;
+    }
+    // Only B has a priority
+    else if (b.sort.priority || b.sort.priority === 0) {
+      return 1;
+    }
+    // Neither has a priority
+    else {
+      return 0;
+    }
+  };
+
+
+  /**
+   * @ngdoc object
+   * @name useExternalSorting
+   * @propertyOf ui.grid.class:GridOptions
+   * @description Prevents the internal sorting from executing.  Events will
+   * still be fired when the sort changes, and the sort information on
+   * the columns will be updated, allowing an external sorter (for example,
+   * server sorting) to be implemented.  Defaults to false. 
+   * 
+   */
+  /**
+   * @ngdoc method
+   * @methodOf ui.grid.class:RowSorter
+   * @name sort
+   * @description sorts the grid 
+   * @param {Object} grid the grid itself
+   * @param {Object} rows the rows to be sorted
+   * @param {Object} columns the columns in which to look
+   * for sort criteria
+   */
+  rowSorter.sort = function rowSorterSort(grid, rows, columns) {
+    // first make sure we are even supposed to do work
+    if (!rows) {
+      return;
+    }
+    
+    if (grid.options.useExternalSorting){
+      return rows;
+    }
+
+    // Build the list of columns to sort by
+    var sortCols = [];
+    columns.forEach(function (col) {
+      if (col.sort && col.sort.direction && (col.sort.direction === uiGridConstants.ASC || col.sort.direction === uiGridConstants.DESC)) {
+        sortCols.push(col);
+      }
+    });
+
+    // Sort the "sort columns" by their sort priority
+    sortCols = sortCols.sort(rowSorter.prioritySort);
+
+    // Now rows to sort by, maintain original order
+    if (sortCols.length === 0) {
+      return rows;
+    }
+    
+    // Re-usable variables
+    var col, direction;
+
+    // IE9-11 HACK.... the 'rows' variable would be empty where we call rowSorter.getSortFn(...) below. We have to use a separate reference
+    // var d = data.slice(0);
+    var r = rows.slice(0);
+
+    // Now actually sort the data
+    return rows.sort(function rowSortFn(rowA, rowB) {
+      var tem = 0,
+          idx = 0,
+          sortFn;
+
+      while (tem === 0 && idx < sortCols.length) {
+        // grab the metadata for the rest of the logic
+        col = sortCols[idx];
+        direction = sortCols[idx].sort.direction;
+
+        sortFn = rowSorter.getSortFn(grid, col, r);
+        
+        var propA = grid.getCellValue(rowA, col);
+        var propB = grid.getCellValue(rowB, col);
+
+        tem = sortFn(propA, propB);
+
+        idx++;
+      }
+
+      // Made it this far, we don't have to worry about null & undefined
+      if (direction === uiGridConstants.ASC) {
+        return tem;
+      } else {
+        return 0 - tem;
+      }
+    });
+  };
+
+  return rowSorter;
+}]);
+
+})();
+(function() {
+
+var module = angular.module('ui.grid');
+
+function getStyles (elem) {
+  var e = elem;
+  if (typeof(e.length) !== 'undefined' && e.length) {
+    e = elem[0];
+  }
+
+  return e.ownerDocument.defaultView.getComputedStyle(e, null);
+}
+
+var rnumnonpx = new RegExp( "^(" + (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source + ")(?!px)[a-z%]+$", "i" ),
+    // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+    rdisplayswap = /^(block|none|table(?!-c[ea]).+)/,
+    cssShow = { position: "absolute", visibility: "hidden", display: "block" };
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+  var i = extra === ( isBorderBox ? 'border' : 'content' ) ?
+          // If we already have the right measurement, avoid augmentation
+          4 :
+          // Otherwise initialize for horizontal or vertical properties
+          name === 'width' ? 1 : 0,
+
+          val = 0;
+
+  var sides = ['Top', 'Right', 'Bottom', 'Left'];
+  
+  for ( ; i < 4; i += 2 ) {
+    var side = sides[i];
+    // dump('side', side);
+
+    // both box models exclude margin, so add it if we want it
+    if ( extra === 'margin' ) {
+      var marg = parseFloat(styles[extra + side]);
+      if (!isNaN(marg)) {
+        val += marg;
+      }
+    }
+    // dump('val1', val);
+
+    if ( isBorderBox ) {
+      // border-box includes padding, so remove it if we want content
+      if ( extra === 'content' ) {
+        var padd = parseFloat(styles['padding' + side]);
+        if (!isNaN(padd)) {
+          val -= padd;
+          // dump('val2', val);
+        }
+      }
+
+      // at this point, extra isn't border nor margin, so remove border
+      if ( extra !== 'margin' ) {
+        var bordermarg = parseFloat(styles['border' + side + 'Width']);
+        if (!isNaN(bordermarg)) {
+          val -= bordermarg;
+          // dump('val3', val);
+        }
+      }
+    }
+    else {
+      // at this point, extra isn't content, so add padding
+      var nocontentPad = parseFloat(styles['padding' + side]);
+      if (!isNaN(nocontentPad)) {
+        val += nocontentPad;
+        // dump('val4', val);
+      }
+
+      // at this point, extra isn't content nor padding, so add border
+      if ( extra !== 'padding') {
+        var nocontentnopad = parseFloat(styles['border' + side + 'Width']);
+        if (!isNaN(nocontentnopad)) {
+          val += nocontentnopad;
+          // dump('val5', val);
+        }
+      }
+    }
+  }
+
+  // dump('augVal', val);
+
+  return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+  // Start with offset property, which is equivalent to the border-box value
+  var valueIsBorderBox = true,
+          val,
+          styles = getStyles(elem),
+          isBorderBox = styles['boxSizing'] === 'border-box';
+
+  // some non-html elements return undefined for offsetWidth, so check for null/undefined
+  // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+  // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+  if ( val <= 0 || val == null ) {
+    // Fall back to computed then uncomputed css if necessary
+    val = styles[name];
+    if ( val < 0 || val == null ) {
+      val = elem.style[ name ];
+    }
+
+    // Computed unit is not pixels. Stop here and return.
+    if ( rnumnonpx.test(val) ) {
+      return val;
+    }
+
+    // we need the check for style in case a browser which returns unreliable values
+    // for getComputedStyle silently falls back to the reliable elem.style
+    valueIsBorderBox = isBorderBox &&
+            ( true || val === elem.style[ name ] ); // use 'true' instead of 'support.boxSizingReliable()'
+
+    // Normalize "", auto, and prepare for extra
+    val = parseFloat( val ) || 0;
+  }
+
+  // use the active box-sizing model to add/subtract irrelevant styles
+  var ret = ( val +
+    augmentWidthOrHeight(
+      elem,
+      name,
+      extra || ( isBorderBox ? "border" : "content" ),
+      valueIsBorderBox,
+      styles
+    )
+  );
+
+  // dump('ret', ret, val);
+  return ret;
+}
+
+var uid = ['0', '0', '0'];
+var uidPrefix = 'uiGrid-';
+
+/**
+ *  @ngdoc service
+ *  @name ui.grid.service:GridUtil
+ *  
+ *  @description Grid utility functions
+ */
+module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', '$interpolate', 'uiGridConstants',
+  function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, $interpolate, uiGridConstants) {
+  var s = {
+
+    getStyles: getStyles,
+
+    /**
+     * @ngdoc method
+     * @name createBoundedWrapper
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {object} Object to bind 'this' to
+     * @param {method} Method to bind
+     * @returns {Function} The wrapper that performs the binding
+     *
+     * @description
+     * Binds given method to given object.
+     *
+     * By means of a wrapper, ensures that ``method`` is always bound to
+     * ``object`` regardless of its calling environment.
+     * Iow, inside ``method``, ``this`` always points to ``object``.
+     *
+     * See http://alistapart.com/article/getoutbindingsituations
+     *
+     */
+    createBoundedWrapper: function(object, method) {
+        return function() {
+            return method.apply(object, arguments);
+        };
+    },
+
+
+    /**
+     * @ngdoc method
+     * @name readableColumnName
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {string} columnName Column name as a string
+     * @returns {string} Column name appropriately capitalized and split apart
+     *
+       @example
+       <example module="app">
+        <file name="app.js">
+          var app = angular.module('app', ['ui.grid']);
+
+          app.controller('MainCtrl', ['$scope', 'gridUtil', function ($scope, gridUtil) {
+            $scope.name = 'firstName';
+            $scope.columnName = function(name) {
+              return gridUtil.readableColumnName(name);
+            };
+          }]);
+        </file>
+        <file name="index.html">
+          <div ng-controller="MainCtrl">
+            <strong>Column name:</strong> <input ng-model="name" />
+            <br>
+            <strong>Output:</strong> <span ng-bind="columnName(name)"></span>
+          </div>
+        </file>
+      </example>
+     */
+    readableColumnName: function (columnName) {
+      // Convert underscores to spaces
+      if (typeof(columnName) === 'undefined' || columnName === undefined || columnName === null) { return columnName; }
+
+      if (typeof(columnName) !== 'string') {
+        columnName = String(columnName);
+      }
+
+      return columnName.replace(/_+/g, ' ')
+        // Replace a completely all-capsed word with a first-letter-capitalized version
+        .replace(/^[A-Z]+$/, function (match) {
+          return angular.lowercase(angular.uppercase(match.charAt(0)) + match.slice(1));
+        })
+        // Capitalize the first letter of words
+        .replace(/(\w+)/g, function (match) {
+          return angular.uppercase(match.charAt(0)) + match.slice(1);
+        })
+        // Put a space in between words that have partial capilizations (i.e. 'firstName' becomes 'First Name')
+        // .replace(/([A-Z]|[A-Z]\w+)([A-Z])/g, "$1 $2");
+        // .replace(/(\w+?|\w)([A-Z])/g, "$1 $2");
+        .replace(/(\w+?(?=[A-Z]))/g, '$1 ');
+    },
+
+    /**
+     * @ngdoc method
+     * @name getColumnsFromData
+     * @methodOf ui.grid.service:GridUtil
+     * @description Return a list of column names, given a data set
+     *
+     * @param {string} data Data array for grid
+     * @returns {Object} Column definitions with field accessor and column name
+     *
+     * @example
+       <pre>
+         var data = [
+           { firstName: 'Bob', lastName: 'Jones' },
+           { firstName: 'Frank', lastName: 'Smith' }
+         ];
+
+         var columnDefs = GridUtil.getColumnsFromData(data, excludeProperties);
+
+         columnDefs == [
+          {
+            field: 'firstName',
+            name: 'First Name'
+          },
+          {
+            field: 'lastName',
+            name: 'Last Name'
+          }
+         ];
+       </pre>
+     */
+    getColumnsFromData: function (data, excludeProperties) {
+      var columnDefs = [];
+
+      if (!data || typeof(data[0]) === 'undefined' || data[0] === undefined) { return []; }
+      if (angular.isUndefined(excludeProperties)) { excludeProperties = []; }
+
+      var item = data[0];
+      
+      angular.forEach(item,function (prop, propName) {
+        if ( excludeProperties.indexOf(propName) === -1){
+          columnDefs.push({
+            name: propName
+          });
+        }
+      });
+
+      return columnDefs;
+    },
+
+    /**
+     * @ngdoc method
+     * @name newId
+     * @methodOf ui.grid.service:GridUtil
+     * @description Return a unique ID string
+     *
+     * @returns {string} Unique string
+     *
+     * @example
+       <pre>
+        var id = GridUtil.newId();
+
+        # 1387305700482;
+       </pre>
+     */
+    newId: (function() {
+      var seedId = new Date().getTime();
+      return function() {
+          return seedId += 1;
+      };
+    })(),
+
+
+    /**
+     * @ngdoc method
+     * @name getTemplate
+     * @methodOf ui.grid.service:GridUtil
+     * @description Get's template from cache / element / url
+     *
+     * @param {string|element|promise} Either a string representing the template id, a string representing the template url,
+     *   an jQuery/Angualr element, or a promise that returns the template contents to use.
+     * @returns {object} a promise resolving to template contents
+     *
+     * @example
+     <pre>
+     GridUtil.getTemplate(url).then(function (contents) {
+          alert(contents);
+        })
+     </pre>
+     */
+    getTemplate: function (template) {
+      // Try to fetch the template out of the templateCache
+      if ($templateCache.get(template)) {
+        return s.postProcessTemplate($templateCache.get(template));
+      }
+
+      // See if the template is itself a promise
+      if (template.hasOwnProperty('then')) {
+        return template.then(s.postProcessTemplate);
+      }
+
+      // If the template is an element, return the element
+      try {
+        if (angular.element(template).length > 0) {
+          return $q.when(template).then(s.postProcessTemplate);
+        }
+      }
+      catch (err){
+        //do nothing; not valid html
+      }
+
+      s.logDebug('fetching url', template);
+
+      // Default to trying to fetch the template as a url with $http
+      return $http({ method: 'GET', url: template})
+        .then(
+          function (result) {
+            var templateHtml = result.data.trim();
+            //put in templateCache for next call
+            $templateCache.put(template, templateHtml);
+            return templateHtml;
+          },
+          function (err) {
+            throw new Error("Could not get template " + template + ": " + err);
+          }
+        )
+        .then(s.postProcessTemplate);
+    },
+
+    // 
+    postProcessTemplate: function (template) {
+      var startSym = $interpolate.startSymbol(),
+          endSym = $interpolate.endSymbol();
+
+      // If either of the interpolation symbols have been changed, we need to alter this template
+      if (startSym !== '{{' || endSym !== '}}') {
+        template = template.replace(/\{\{/g, startSym);
+        template = template.replace(/\}\}/g, endSym);
+      }
+
+      return $q.when(template);
+    },
+
+    /**
+     * @ngdoc method
+     * @name guessType
+     * @methodOf ui.grid.service:GridUtil
+     * @description guesses the type of an argument
+     *
+     * @param {string/number/bool/object} item variable to examine
+     * @returns {string} one of the following
+     * 'string'
+     * 'boolean'
+     * 'number'
+     * 'date'
+     * 'object'
+     */
+    guessType : function (item) {
+      var itemType = typeof(item);
+
+      // Check for numbers and booleans
+      switch (itemType) {
+        case "number":
+        case "boolean":
+        case "string":
+          return itemType;
+        default:
+          if (angular.isDate(item)) {
+            return "date";
+          }
+          return "object";
+      }
+    },
+
+
+  /**
+    * @ngdoc method
+    * @name elementWidth
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element DOM element
+    * @param {string} [extra] Optional modifier for calculation. Use 'margin' to account for margins on element
+    *
+    * @returns {number} Element width in pixels, accounting for any borders, etc.
+    */
+    elementWidth: function (elem) {
+      
+    },
+
+    /**
+    * @ngdoc method
+    * @name elementHeight
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element DOM element
+    * @param {string} [extra] Optional modifier for calculation. Use 'margin' to account for margins on element
+    *
+    * @returns {number} Element height in pixels, accounting for any borders, etc.
+    */
+    elementHeight: function (elem) {
+      
+    },
+
+    // Thanks to http://stackoverflow.com/a/13382873/888165
+    getScrollbarWidth: function() {
+        var outer = document.createElement("div");
+        outer.style.visibility = "hidden";
+        outer.style.width = "100px";
+        outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
+
+        document.body.appendChild(outer);
+
+        var widthNoScroll = outer.offsetWidth;
+        // force scrollbars
+        outer.style.overflow = "scroll";
+
+        // add innerdiv
+        var inner = document.createElement("div");
+        inner.style.width = "100%";
+        outer.appendChild(inner);        
+
+        var widthWithScroll = inner.offsetWidth;
+
+        // remove divs
+        outer.parentNode.removeChild(outer);
+
+        return widthNoScroll - widthWithScroll;
+    },
+
+    swap: function( elem, options, callback, args ) {
+      var ret, name,
+              old = {};
+
+      // Remember the old values, and insert the new ones
+      for ( name in options ) {
+        old[ name ] = elem.style[ name ];
+        elem.style[ name ] = options[ name ];
+      }
+
+      ret = callback.apply( elem, args || [] );
+
+      // Revert the old values
+      for ( name in options ) {
+        elem.style[ name ] = old[ name ];
+      }
+
+      return ret;
+    },
+
+    fakeElement: function( elem, options, callback, args ) {
+      var ret, name,
+          newElement = angular.element(elem).clone()[0];
+
+      for ( name in options ) {
+        newElement.style[ name ] = options[ name ];
+      }
+
+      angular.element(document.body).append(newElement);
+
+      ret = callback.call( newElement, newElement );
+
+      angular.element(newElement).remove();
+
+      return ret;
+    },
+
+    /**
+    * @ngdoc method
+    * @name normalizeWheelEvent
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {event} event A mouse wheel event
+    *
+    * @returns {event} A normalized event
+    *
+    * @description
+    * Given an event from this list:
+    *
+    * `wheel, mousewheel, DomMouseScroll, MozMousePixelScroll`
+    *
+    * "normalize" it
+    * so that it stays consistent no matter what browser it comes from (i.e. scale it correctly and make sure the direction is right.)
+    */
+    normalizeWheelEvent: function (event) {
+      // var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
+      // var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'];
+      var lowestDelta, lowestDeltaXY;
+      
+      var orgEvent   = event || window.event,
+          args       = [].slice.call(arguments, 1),
+          delta      = 0,
+          deltaX     = 0,
+          deltaY     = 0,
+          absDelta   = 0,
+          absDeltaXY = 0,
+          fn;
+
+      // event = $.event.fix(orgEvent);
+      // event.type = 'mousewheel';
+
+      // NOTE: jQuery masks the event and stores it in the event as originalEvent
+      if (orgEvent.originalEvent) {
+        orgEvent = orgEvent.originalEvent;
+      }
+
+      // Old school scrollwheel delta
+      if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; }
+      if ( orgEvent.detail )     { delta = orgEvent.detail * -1; }
+
+      // At a minimum, setup the deltaY to be delta
+      deltaY = delta;
+
+      // Firefox < 17 related to DOMMouseScroll event
+      if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+          deltaY = 0;
+          deltaX = delta * -1;
+      }
+
+      // New school wheel delta (wheel event)
+      if ( orgEvent.deltaY ) {
+          deltaY = orgEvent.deltaY * -1;
+          delta  = deltaY;
+      }
+      if ( orgEvent.deltaX ) {
+          deltaX = orgEvent.deltaX;
+          delta  = deltaX * -1;
+      }
+
+      // Webkit
+      if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; }
+      if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX; }
+
+      // Look for lowest delta to normalize the delta values
+      absDelta = Math.abs(delta);
+      if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; }
+      absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX));
+      if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; }
+
+      // Get a whole value for the deltas
+      fn     = delta > 0 ? 'floor' : 'ceil';
+      delta  = Math[fn](delta  / lowestDelta);
+      deltaX = Math[fn](deltaX / lowestDeltaXY);
+      deltaY = Math[fn](deltaY / lowestDeltaXY);
+
+      return {
+        delta: delta,
+        deltaX: deltaX,
+        deltaY: deltaY
+      };
+    },
+
+    // Stolen from Modernizr
+    // TODO: make this, and everythign that flows from it, robust
+    //http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
+    isTouchEnabled: function() {
+      var bool;
+
+      if (('ontouchstart' in $window) || $window.DocumentTouch && $document instanceof DocumentTouch) {
+        bool = true;
+      }
+
+      return bool;
+    },
+
+    isNullOrUndefined: function(obj) {
+      if (obj === undefined || obj === null) {
+        return true;
+      }
+      return false;
+    },
+
+    endsWith: function(str, suffix) {
+      if (!str || !suffix || typeof str !== "string") {
+        return false;
+      }
+      return str.indexOf(suffix, str.length - suffix.length) !== -1;
+    },
+
+    arrayContainsObjectWithProperty: function(array, propertyName, propertyValue) {
+        var found = false;
+        angular.forEach(array, function (object) {
+            if (object[propertyName] === propertyValue) {
+                found = true;
+            }
+        });
+        return found;
+    },
+
+    // Shim requestAnimationFrame
+    requestAnimationFrame: $window.requestAnimationFrame && $window.requestAnimationFrame.bind($window) ||
+                           $window.webkitRequestAnimationFrame && $window.webkitRequestAnimationFrame.bind($window) ||
+                           function(fn) {
+                             return $timeout(fn, 10, false);
+                           },
+
+    numericAndNullSort: function (a, b) {
+      if (a === null) { return 1; }
+      if (b === null) { return -1; }
+      if (a === null && b === null) { return 0; }
+      return a - b;
+    },
+
+    // Disable ngAnimate animations on an element
+    disableAnimations: function (element) {
+      var $animate;
+      try {
+        $animate = $injector.get('$animate');
+        $animate.enabled(false, element);
+      }
+      catch (e) {}
+    },
+
+    enableAnimations: function (element) {
+      var $animate;
+      try {
+        $animate = $injector.get('$animate');
+        $animate.enabled(true, element);
+        return $animate;
+      }
+      catch (e) {}
+    },
+
+    // Blatantly stolen from Angular as it isn't exposed (yet. 2.0 maybe?)
+    nextUid: function nextUid() {
+      var index = uid.length;
+      var digit;
+
+      while (index) {
+        index--;
+        digit = uid[index].charCodeAt(0);
+        if (digit === 57 /*'9'*/) {
+          uid[index] = 'A';
+          return uidPrefix + uid.join('');
+        }
+        if (digit === 90  /*'Z'*/) {
+          uid[index] = '0';
+        } else {
+          uid[index] = String.fromCharCode(digit + 1);
+          return uidPrefix + uid.join('');
+        }
+      }
+      uid.unshift('0');
+
+      return uidPrefix + uid.join('');
+    },
+
+    // Blatantly stolen from Angular as it isn't exposed (yet. 2.0 maybe?)
+    hashKey: function hashKey(obj) {
+      var objType = typeof obj,
+          key;
+
+      if (objType === 'object' && obj !== null) {
+        if (typeof (key = obj.$$hashKey) === 'function') {
+          // must invoke on object to keep the right this
+          key = obj.$$hashKey();
+        }
+        else if (typeof(obj.$$hashKey) !== 'undefined' && obj.$$hashKey) {
+          key = obj.$$hashKey;
+        }
+        else if (key === undefined) {
+          key = obj.$$hashKey = s.nextUid();
+        }
+      }
+      else {
+        key = obj;
+      }
+
+      return objType + ':' + key;
+    },
+
+    resetUids: function () {
+      uid = ['0', '0', '0'];
+    },
+    
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:GridUtil
+     * @name logError
+     * @description wraps the $log method, allowing us to choose different
+     * treatment within ui-grid if we so desired.  At present we only log
+     * error messages if uiGridConstants.LOG_ERROR_MESSAGES is set to true
+     * @param {string} logMessage message to be logged to the console
+     * 
+     */
+    logError: function( logMessage ){
+      if ( uiGridConstants.LOG_ERROR_MESSAGES ){
+        $log.error( logMessage );
+      }
+    },
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:GridUtil
+     * @name logWarn
+     * @description wraps the $log method, allowing us to choose different
+     * treatment within ui-grid if we so desired.  At present we only log
+     * warning messages if uiGridConstants.LOG_WARN_MESSAGES is set to true
+     * @param {string} logMessage message to be logged to the console
+     * 
+     */
+    logWarn: function( logMessage ){
+      if ( uiGridConstants.LOG_WARN_MESSAGES ){
+        $log.warn( logMessage );
+      }
+    },
+
+    /**
+     * @ngdoc method
+     * @methodOf ui.grid.service:GridUtil
+     * @name logDebug
+     * @description wraps the $log method, allowing us to choose different
+     * treatment within ui-grid if we so desired.  At present we only log
+     * debug messages if uiGridConstants.LOG_DEBUG_MESSAGES is set to true
+     * 
+     */
+    logDebug: function() {
+      if ( uiGridConstants.LOG_DEBUG_MESSAGES ){
+        $log.debug.apply($log, arguments);
+      }
+    }
+
+  };
+
+  ['width', 'height'].forEach(function (name) {
+    var capsName = angular.uppercase(name.charAt(0)) + name.substr(1);
+    s['element' + capsName] = function (elem, extra) {
+      var e = elem;
+      if (e && typeof(e.length) !== 'undefined' && e.length) {
+        e = elem[0];
+      }
+
+      if (e) {
+        var styles = getStyles(e);
+        return e.offsetWidth === 0 && rdisplayswap.test(styles.display) ?
+                  s.fakeElement(e, cssShow, function(newElm) {
+                    return getWidthOrHeight( newElm, name, extra );
+                  }) :
+                  getWidthOrHeight( e, name, extra );
+      }
+      else {
+        return null;
+      }
+    };
+
+    s['outerElement' + capsName] = function (elem, margin) {
+      return elem ? s['element' + capsName].call(this, elem, margin ? 'margin' : 'border') : null;
+    };
+  });
+
+  // http://stackoverflow.com/a/24107550/888165
+  s.closestElm = function closestElm(el, selector) {
+    if (typeof(el.length) !== 'undefined' && el.length) {
+      el = el[0];
+    }
+
+    var matchesFn;
+
+    // find vendor prefix
+    ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
+        if (typeof document.body[fn] === 'function') {
+            matchesFn = fn;
+            return true;
+        }
+        return false;
+    });
+
+    // traverse parents
+    var parent;
+    while (el !== null) {
+      parent = el.parentElement;
+      if (parent !== null && parent[matchesFn](selector)) {
+          return parent;
+      }
+      el = parent;
+    }
+
+    return null;
+  };
+
+  s.type = function (obj) {
+    var text = Function.prototype.toString.call(obj.constructor);
+    return text.match(/function (.*?)\(/)[1];
+  };
+
+  s.getBorderSize = function getBorderSize(elem, borderType) {
+    if (typeof(elem.length) !== 'undefined' && elem.length) {
+      elem = elem[0];
+    }
+
+    var styles = getStyles(elem);
+
+    // If a specific border is supplied, like 'top', read the 'borderTop' style property
+    if (borderType) {
+      borderType = 'border' + borderType.charAt(0).toUpperCase() + borderType.slice(1);
+    }
+    else {
+      borderType = 'border';
+    }
+
+    borderType += 'Width';
+
+    var val = parseInt(styles[borderType], 10);
+
+    if (isNaN(val)) {
+      return 0;
+    }
+    else {
+      return val;
+    }
+  };
+
+  // http://stackoverflow.com/a/22948274/888165
+  // TODO: Opera? Mobile?
+  s.detectBrowser = function detectBrowser() {
+    var userAgent = $window.navigator.userAgent;
+
+    var browsers = {chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer|trident\//i};
+
+    for (var key in browsers) {
+      if (browsers[key].test(userAgent)) {
+        return key;
+      }
+    }
+
+    return 'unknown';
+  };
+
+  /**
+    * @ngdoc method
+    * @name normalizeScrollLeft
+    * @methodOf ui.grid.service:GridUtil
+    *
+    * @param {element} element The element to get the `scrollLeft` from.
+    *
+    * @returns {int} A normalized scrollLeft value for the current browser.
+    *
+    * @description
+    * Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method normalizes them
+    */
+  s.normalizeScrollLeft = function normalizeScrollLeft(element) {
+    if (typeof(element.length) !== 'undefined' && element.length) {
+      element = element[0];
+    }
+
+    var browser = s.detectBrowser();
+
+    var scrollLeft = element.scrollLeft;
+    
+    var dir = s.getStyles(element)['direction'];
+
+    // IE stays normal in RTL
+    if (browser === 'ie') {
+      return scrollLeft;
+    }
+    // Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
+    else if (browser === 'chrome') {
+      if (dir === 'rtl') {
+        // Get the max scroll for the element
+        var maxScrollLeft = element.scrollWidth - element.clientWidth;
+
+        // Subtract the current scroll amount from the max scroll
+        return maxScrollLeft - scrollLeft;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    // Firefox goes negative!
+    else if (browser === 'firefox') {
+      return Math.abs(scrollLeft);
+    }
+    else {
+      // TODO(c0bra): Handle other browsers? Android? iOS? Opera?
+      return scrollLeft;
+    }
+  };
+
+  /**
+  * @ngdoc method
+  * @name normalizeScrollLeft
+  * @methodOf ui.grid.service:GridUtil
+  *
+  * @param {element} element The element to normalize the `scrollLeft` value for
+  * @param {int} scrollLeft The `scrollLeft` value to denormalize.
+  *
+  * @returns {int} A normalized scrollLeft value for the current browser.
+  *
+  * @description
+  * Browsers currently handle RTL in different ways, resulting in inconsistent scrollLeft values. This method denormalizes a value for the current browser.
+  */
+  s.denormalizeScrollLeft = function denormalizeScrollLeft(element, scrollLeft) {
+    if (typeof(element.length) !== 'undefined' && element.length) {
+      element = element[0];
+    }
+
+    var browser = s.detectBrowser();
+
+    var dir = s.getStyles(element)['direction'];
+
+    // IE stays normal in RTL
+    if (browser === 'ie') {
+      return scrollLeft;
+    }
+    // Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
+    else if (browser === 'chrome') {
+      if (dir === 'rtl') {
+        // Get the max scroll for the element
+        var maxScrollLeft = element.scrollWidth - element.clientWidth;
+
+        // Subtract the current scroll amount from the max scroll
+        return maxScrollLeft - scrollLeft;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    // Firefox goes negative!
+    else if (browser === 'firefox') {
+      if (dir === 'rtl') {
+        return scrollLeft * -1;
+      }
+      else {
+        return scrollLeft;
+      }
+    }
+    else {
+      // TODO(c0bra): Handle other browsers? Android? iOS? Opera?
+      return scrollLeft;
+    }
+  };
+
+    /**
+     * @ngdoc method
+     * @name preEval
+     * @methodOf ui.grid.service:GridUtil
+     *
+     * @param {string} path Path to evaluate
+     *
+     * @returns {string} A path that is normalized.
+     *
+     * @description
+     * Takes a field path and converts it to bracket notation to allow for special characters in path
+     * @example
+     * <pre>
+     * gridUtil.preEval('property') == 'property'
+     * gridUtil.preEval('nested.deep.prop-erty') = "nested['deep']['prop-erty']"
+     * </pre>
+     */
+  s.preEval = function (path) {
+    var m = uiGridConstants.BRACKET_REGEXP.exec(path);
+    if (m) {
+      return (m[1] ? s.preEval(m[1]) : m[1]) + m[2] + (m[3] ? s.preEval(m[3]) : m[3]);
+    } else {
+      path = path.replace(uiGridConstants.APOS_REGEXP, '\\\'');
+      var parts = path.split(uiGridConstants.DOT_REGEXP);
+      var preparsed = [parts.shift()];    // first item must be var notation, thus skip
+      angular.forEach(parts, function (part) {
+        preparsed.push(part.replace(uiGridConstants.FUNC_REGEXP, '\']$1'));
+      });
+      return preparsed.join('[\'');
+    }
+  };
+
+  /**
+   * @ngdoc method
+   * @name debounce
+   * @methodOf ui.grid.service:GridUtil
+   *
+   * @param {function} func function to debounce
+   * @param {number} wait milliseconds to delay
+   * @param {bool} immediate execute before delay
+   *
+   * @returns {function} A function that can be executed as debounced function
+   *
+   * @description
+   * Copied from https://github.com/shahata/angular-debounce
+   * Takes a function, decorates it to execute only 1 time after multiple calls, and returns the decorated function
+   * @example
+   * <pre>
+   * var debouncedFunc =  gridUtil.debounce(function(){alert('debounced');}, 500);
+   * debouncedFunc();
+   * debouncedFunc();
+   * debouncedFunc();
+   * </pre>
+   */
+  s.debounce =  function (func, wait, immediate) {
+    var timeout, args, context, result;
+    function debounce() {
+      /* jshint validthis:true */
+      context = this;
+      args = arguments;
+      var later = function () {
+        timeout = null;
+        if (!immediate) {
+          result = func.apply(context, args);
+        }
+      };
+      var callNow = immediate && !timeout;
+      if (timeout) {
+        $timeout.cancel(timeout);
+      }
+      timeout = $timeout(later, wait);
+      if (callNow) {
+        result = func.apply(context, args);
+      }
+      return result;
+    }
+    debounce.cancel = function () {
+      $timeout.cancel(timeout);
+      timeout = null;
+    };
+    return debounce;
+  };
+
+  /**
+   * @ngdoc method
+   * @name throttle
+   * @methodOf ui.grid.service:GridUtil
+   *
+   * @param {function} func function to throttle
+   * @param {number} wait milliseconds to delay after first trigger
+   * @param {Object} params to use in throttle.
+   *
+   * @returns {function} A function that can be executed as throttled function
+   *
+   * @description
+   * Adapted from debounce function (above)
+   * Potential keys for Params Object are:
+   *    trailing (bool) - whether to trigger after throttle time ends if called multiple times
+   * @example
+   * <pre>
+   * var throttledFunc =  gridUtil.throttle(function(){console.log('throttled');}, 500, {trailing: true});
+   * throttledFunc(); //=> logs throttled
+   * throttledFunc(); //=> queues attempt to log throttled for ~500ms (since trailing param is truthy)
+   * throttledFunc(); //=> updates arguments to keep most-recent request, but does not do anything else.
+   * </pre>
+   */
+  s.throttle = function(func, wait, options){
+    options = options || {};
+    var lastCall = 0, queued = null, context, args;
+
+    function runFunc(endDate){
+      lastCall = +new Date();
+      func.apply(context, args);
+      $timeout(function(){ queued = null; }, 0);
+    }
+
+    return function(){
+      /* jshint validthis:true */
+      context = this;
+      args = arguments;
+      if (queued === null){
+        var sinceLast = +new Date() - lastCall;
+        if (sinceLast > wait){
+          runFunc();
+        }
+        else if (options.trailing){
+          queued = $timeout(runFunc, wait - sinceLast);
+        }
+      }
+    };
+  };
+
+  return s;
+}]);
+
+// Add 'px' to the end of a number string if it doesn't have it already
+module.filter('px', function() {
+  return function(str) {
+    if (str.match(/^[\d\.]+$/)) {
+      return str + 'px';
+    }
+    else {
+      return str;
+    }
+  };
+});
+
+})();
+
+(function(){
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('da', {
+        aggregate:{
+          label: 'artikler'
+        },
+        groupPanel:{
+          description: 'Grupér rækker udfra en kolonne ved at trække dens overskift hertil.'
+        },
+        search:{
+          placeholder: 'Søg...',
+          showingItems: 'Viste rækker:',
+          selectedItems: 'Valgte rækker:',
+          totalItems: 'Rækker totalt:',
+          size: 'Side størrelse:',
+          first: 'Første side',
+          next: 'Næste side',
+          previous: 'Forrige side',
+          last: 'Sidste side'
+        },
+        menu:{
+          text: 'Vælg kolonner:'
+        },
+        column: {
+          hide: 'Skjul kolonne'
+        },
+        aggregation: {
+          count: 'samlede rækker: ',
+          sum: 'smalede: ',
+          avg: 'gns: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function ($provide) {
+    $provide.decorator('i18nService', ['$delegate', function ($delegate) {
+      $delegate.add('de', {
+        aggregate: {
+          label: 'eintrag'
+        },
+        groupPanel: {
+          description: 'Ziehen Sie eine Spaltenüberschrift hierhin, um nach dieser Spalte zu gruppieren.'
+        },
+        search: {
+          placeholder: 'Suche...',
+          showingItems: 'Zeige Einträge:',
+          selectedItems: 'Ausgewählte Einträge:',
+          totalItems: 'Einträge gesamt:',
+          size: 'Einträge pro Seite:',
+          first: 'Erste Seite',
+          next: 'Nächste Seite',
+          previous: 'Vorherige Seite',
+          last: 'Letzte Seite'
+        },
+        menu: {
+          text: 'Spalten auswählen:'
+        },
+        sort: {
+          ascending: 'aufsteigend sortieren',
+          descending: 'absteigend sortieren',
+          remove: 'Sortierung zurücksetzen'
+        },
+        column: {
+          hide: 'Spalte ausblenden'
+        },
+        aggregation: {
+          count: 'Zeilen insgesamt: ',
+          sum: 'gesamt: ',
+          avg: 'Durchschnitt: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Spalten:',
+          importerTitle: 'Datei importieren',
+          exporterAllAsCsv: 'Alle Daten als CSV exportieren',
+          exporterVisibleAsCsv: 'sichtbare Daten als CSV exportieren',
+          exporterSelectedAsCsv: 'markierte Daten als CSV exportieren',
+          exporterAllAsPdf: 'Alle Daten als PDF exportieren',
+          exporterVisibleAsPdf: 'sichtbare Daten als PDF exportieren',
+          exporterSelectedAsPdf: 'markierte Daten als CSV exportieren'
+        },
+        importer: {
+          noHeaders: 'Es konnten keine Spaltennamen ermittelt werden. Sind in der Datei Spaltendefinitionen enthalten?',
+          noObjects: 'Es konnten keine Zeileninformationen gelesen werden, Sind in der Datei außer den Spaltendefinitionen auch Daten enthalten?',
+          invalidCsv: 'Die Datei konnte nicht eingelesen werden, ist es eine gültige CSV-Datei?',
+          invalidJson: 'Die Datei konnte nicht eingelesen werden. Enthält sie gültiges JSON?',
+          jsonNotArray: 'Die importierte JSON-Datei muß ein Array enthalten. Breche Import ab.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('en', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'Drag a column header here and drop it to group by that column.'
+        },
+        search: {
+          placeholder: 'Search...',
+          showingItems: 'Showing Items:',
+          selectedItems: 'Selected Items:',
+          totalItems: 'Total Items:',
+          size: 'Page Size:',
+          first: 'First Page',
+          next: 'Next Page',
+          previous: 'Previous Page',
+          last: 'Last Page'
+        },
+        menu: {
+          text: 'Choose Columns:'
+        },
+        sort: {
+          ascending: 'Sort Ascending',
+          descending: 'Sort Descending',
+          remove: 'Remove Sort'
+        },
+        column: {
+          hide: 'Hide Column'
+        },
+        aggregation: {
+          count: 'total rows: ',
+          sum: 'total: ',
+          avg: 'avg: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        pinning: {
+         pinLeft: 'Pin Left',
+          pinRight: 'Pin Right',
+          unpin: 'Unpin'
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        },
+        paging: {
+          sizes: 'items per page',
+          totalItems: 'items'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('es', {
+        aggregate: {
+          label: 'Artículos'
+        },
+        groupPanel: {
+          description: 'Arrastre un encabezado de columna aquí y suéltelo para agrupar por esa columna.'
+        },
+        search: {
+          placeholder: 'Buscar...',
+          showingItems: 'Artículos Mostrados:',
+          selectedItems: 'Artículos Seleccionados:',
+          totalItems: 'Artículos Totales:',
+          size: 'Tamaño de Página:',
+          first: 'Primera Página',
+          next: 'Página Siguiente',
+          previous: 'Página Anterior',
+          last: 'Última Página'
+        },
+        menu: {
+          text: 'Elegir columnas:'
+        },
+        sort: {
+          ascending: 'Orden Ascendente',
+          descending: 'Orden Descendente',
+          remove: 'Sin Ordenar'
+        },
+        column: {
+          hide: 'Ocultar la columna'
+        },
+        aggregation: {
+          count: 'filas totales: ',
+          sum: 'total: ',
+          avg: 'media: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        pinning: {
+          pinLeft: 'Fijar a la Izquierda',
+          pinRight: 'Fijar a la Derecha',
+          unpin: 'Quitar Fijación'
+        },
+        gridMenu: {
+          columns: 'Columnas:',
+          importerTitle: 'Importar archivo',
+          exporterAllAsCsv: 'Exportar todo como csv',
+          exporterVisibleAsCsv: 'Exportar vista como csv',
+          exporterSelectedAsCsv: 'Exportar selección como csv',
+          exporterAllAsPdf: 'Exportar todo como pdf',
+          exporterVisibleAsPdf: 'Exportar vista como pdf',
+          exporterSelectedAsPdf: 'Exportar selección como pdf'
+        },
+        importer: {
+          noHeaders: 'No fue posible derivar los nombres de las columnas, ¿tiene encabezados el archivo?',
+          noObjects: 'No fue posible obtener registros, ¿contiene datos el archivo, aparte de los encabezados?',
+          invalidCsv: 'No fue posible procesar el archivo, ¿es un CSV válido?',
+          invalidJson: 'No fue posible procesar el archivo, ¿es un Json válido?',
+          jsonNotArray: 'El archivo json importado debe contener un array, abortando.'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('fa', {
+        aggregate: {
+          label: 'موردها'
+        },
+        groupPanel: {
+          description: 'یک عنوان ستون اینجا را بردار و به گروهی از آن ستون بیانداز.'
+        },
+        search: {
+          placeholder: 'جستجو...',
+          showingItems: 'نمایش موردها:',
+          selectedItems: 'موردهای انتخاب\u200cشده:',
+          totalItems: 'همهٔ موردها:',
+          size: 'اندازهٔ صفحه:',
+          first: 'صفحهٔ اول',
+          next: 'صفحهٔ بعد',
+          previous: 'صفحهٔ قبل',
+          last: 'آخرین صفحه'
+        },
+        menu: {
+          text: 'انتخاب ستون\u200cها:'
+        },
+        column: {
+          hide: 'ستون پنهان کن'
+        },
+        aggregation: {
+          count: 'total rows: ',
+          sum: 'total: ',
+          avg: 'avg: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('fi', {
+        aggregate: {
+          label: 'rivit'
+        },
+        groupPanel: {
+          description: 'Raahaa ja pudota otsikko tähän ryhmittääksesi sarakkeen mukaan.'
+        },
+        search: {
+          placeholder: 'Hae...',
+          showingItems: 'Näytetään rivejä:',
+          selectedItems: 'Valitut rivit:',
+          totalItems: 'Rivejä yht.:',
+          size: 'Näytä:',
+          first: 'Ensimmäinen sivu',
+          next: 'Seuraava sivu',
+          previous: 'Edellinen sivu',
+          last: 'Viimeinen sivu'
+        },
+        menu: {
+          text: 'Valitse sarakkeet:'
+        },
+        sort: {
+          ascending: 'Järjestä nouseva',
+          descending: 'Järjestä laskeva',
+          remove: 'Poista järjestys'
+        },
+        column: {
+          hide: 'Piilota sarake'
+        },
+        aggregation: {
+          count: 'Rivejä yht.: ',
+          sum: 'Summa: ',
+          avg: 'K.a.: ',
+          min: 'Min: ',
+          max: 'Max: '
+        },
+        pinning: {
+         pinLeft: 'Lukitse vasemmalle',
+          pinRight: 'Lukitse oikealle',
+          unpin: 'Poista lukitus'
+        },
+        gridMenu: {
+          columns: 'Sarakkeet:',
+          importerTitle: 'Tuo tiedosto',
+          exporterAllAsCsv: 'Vie tiedot csv-muodossa',
+          exporterVisibleAsCsv: 'Vie näkyvä tieto csv-muodossa',
+          exporterSelectedAsCsv: 'Vie valittu tieto csv-muodossa',
+          exporterAllAsPdf: 'Vie tiedot pdf-muodossa',
+          exporterVisibleAsPdf: 'Vie näkyvä tieto pdf-muodossa',
+          exporterSelectedAsPdf: 'Vie valittu tieto pdf-muodossa'
+        },
+        importer: {
+          noHeaders: 'Sarakkeen nimiä ei voitu päätellä, onko tiedostossa otsikkoriviä?',
+          noObjects: 'Tietoja ei voitu lukea, onko tiedostossa muuta kuin otsikkot?',
+          invalidCsv: 'Tiedostoa ei voitu käsitellä, oliko se CSV-muodossa?',
+          invalidJson: 'Tiedostoa ei voitu käsitellä, oliko se JSON-muodossa?',
+          jsonNotArray: 'Tiedosto ei sisältänyt taulukkoa, lopetetaan.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('fr', {
+        aggregate: {
+          label: 'articles'
+        },
+        groupPanel: {
+          description: 'Faites glisser un en-tête de colonne ici et déposez-le vers un groupe par cette colonne.'
+        },
+        search: {
+          placeholder: 'Recherche...',
+          showingItems: 'Articles Affichage des:',
+          selectedItems: 'Éléments Articles:',
+          totalItems: 'Nombre total d\'articles:',
+          size: 'Taille de page:',
+          first: 'Première page',
+          next: 'Page Suivante',
+          previous: 'Page précédente',
+          last: 'Dernière page'
+        },
+        menu: {
+          text: 'Choisir des colonnes:'
+        },
+        sort: {
+          ascending: 'Trier par ordre croissant',
+          descending: 'Trier par ordre décroissant',
+          remove: 'Enlever le tri'
+        },
+        column: {
+          hide: 'Cacher la colonne'
+        },
+        aggregation: {
+          count: 'total lignes: ',
+          sum: 'total: ',
+          avg: 'moy: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        pinning: {
+          pinLeft: 'Épingler à gauche',
+          pinRight: 'Épingler à droite',
+          unpin: 'Détacher'
+        },
+        gridMenu: {
+          columns: 'Colonnes:',
+          importerTitle: 'Importer un fichier',
+          exporterAllAsCsv: 'Exporter toutes les données en CSV',
+          exporterVisibleAsCsv: 'Exporter les données visibles en CSV',
+          exporterSelectedAsCsv: 'Exporter les données sélectionnées en CSV',
+          exporterAllAsPdf: 'Exporter toutes les données en PDF',
+          exporterVisibleAsPdf: 'Exporter les données visibles en PDF',
+          exporterSelectedAsPdf: 'Exporter les données sélectionnées en PDF'
+        },
+        importer: {
+          noHeaders: 'Impossible de déterminer le nom des colonnes, le fichier possède-t-il un en-tête ?',
+          noObjects: 'Aucun objet trouvé, le fichier possède-t-il des données autres que l\'en-tête ?',
+          invalidCsv: 'Le fichier n\'a pas pu être traité, le CSV est-il valide ?',
+          invalidJson: 'Le fichier n\'a pas pu être traité, le JSON est-il valide ?',
+          jsonNotArray: 'Le fichier JSON importé doit contenir un tableau. Abandon.'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function ($provide) {
+    $provide.decorator('i18nService', ['$delegate', function ($delegate) {
+      $delegate.add('he', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו.'
+        },
+        search: {
+          placeholder: 'חפש...',
+          showingItems: 'מציג:',
+          selectedItems: 'סה"כ נבחרו:',
+          totalItems: 'סה"כ רשומות:',
+          size: 'תוצאות בדף:',
+          first: 'דף ראשון',
+          next: 'דף הבא',
+          previous: 'דף קודם',
+          last: 'דף אחרון'
+        },
+        menu: {
+          text: 'בחר עמודות:'
+        },
+        sort: {
+          ascending: 'סדר עולה',
+          descending: 'סדר יורד',
+          remove: 'בטל'
+        },
+        column: {
+          hide: 'טור הסתר'
+        },
+        aggregation: {
+          count: 'total rows: ',
+          sum: 'total: ',
+          avg: 'avg: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('it', {
+        aggregate: {
+          label: 'elementi'
+        },
+        groupPanel: {
+          description: 'Trascina un\'intestazione all\'interno del gruppo della colonna.'
+        },
+        search: {
+          placeholder: 'Ricerca...',
+          showingItems: 'Mostra:',
+          selectedItems: 'Selezionati:',
+          totalItems: 'Totali:',
+          size: 'Tot Pagine:',
+          first: 'Prima',
+          next: 'Prossima',
+          previous: 'Precedente',
+          last: 'Ultima'
+        },
+        menu: {
+          text: 'Scegli le colonne:'
+        },
+        sort: {
+          ascending: 'Asc.',
+          descending: 'Desc.',
+          remove: 'Annulla ordinamento'
+        },
+        column: {
+          hide: 'Nascondi'
+        },
+        aggregation: {
+          count: 'righe totali: ',
+          sum: 'tot: ',
+          avg: 'media: ',
+          min: 'minimo: ',
+          max: 'massimo: '
+        },
+        pinning: {
+         pinLeft: 'Blocca a sx',
+          pinRight: 'Blocca a dx',
+          unpin: 'Blocca in alto'
+        },
+        gridMenu: {
+          columns: 'Colonne:',
+          importerTitle: 'Importa',
+          exporterAllAsCsv: 'Esporta tutti i dati in CSV',
+          exporterVisibleAsCsv: 'Esporta i dati visibili in CSV',
+          exporterSelectedAsCsv: 'Esporta i dati selezionati in CSV',
+          exporterAllAsPdf: 'Esporta tutti i dati in PDF',
+          exporterVisibleAsPdf: 'Esporta i dati visibili in PDF',
+          exporterSelectedAsPdf: 'Esporta i dati selezionati in PDF'
+        },
+        importer: {
+          noHeaders: 'Impossibile reperire i nomi delle colonne, sicuro che siano indicati all\'interno del file?',
+          noObjects: 'Impossibile reperire gli oggetti, sicuro che siano indicati all\'interno del file?',
+          invalidCsv: 'Impossibile elaborare il file, sicuro che sia un CSV?',
+          invalidJson: 'Impossibile elaborare il file, sicuro che sia un JSON valido?',
+          jsonNotArray: 'Errore! Il file JSON da importare deve contenere un array.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('nl', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'Sleep hier een kolomnaam heen om op te groeperen.'
+        },
+        search: {
+          placeholder: 'Zoeken...',
+          showingItems: 'Getoonde items:',
+          selectedItems: 'Geselecteerde items:',
+          totalItems: 'Totaal aantal items:',
+          size: 'Items per pagina:',
+          first: 'Eerste pagina',
+          next: 'Volgende pagina',
+          previous: 'Vorige pagina',
+          last: 'Laatste pagina'
+        },
+        menu: {
+          text: 'Kies kolommen:'
+        },
+        sort: {
+          ascending: 'Sorteer oplopend',
+          descending: 'Sorteer aflopend',
+          remove: 'Verwijder sortering'
+        },
+        column: {
+          hide: 'Verberg kolom'
+        },
+        aggregation: {
+          count: 'Aantal rijen: ',
+          sum: 'Som: ',
+          avg: 'Gemiddelde: ',
+          min: 'Min: ',
+          max: 'Max: '
+        },
+        pinning: {
+          pinLeft: 'Zet links vast',
+          pinRight: 'Zet rechts vast',
+          unpin: 'Maak los'
+        },
+        gridMenu: {
+          columns: 'Kolommen:',
+          importerTitle: 'Importeer bestand',
+          exporterAllAsCsv: 'Exporteer alle data als csv',
+          exporterVisibleAsCsv: 'Exporteer zichtbare data als csv',
+          exporterSelectedAsCsv: 'Exporteer geselecteerde data als csv',
+          exporterAllAsPdf: 'Exporteer alle data als pdf',
+          exporterVisibleAsPdf: 'Exporteer zichtbare data als pdf',
+          exporterSelectedAsPdf: 'Exporteer geselecteerde data als pdf'
+        },
+        importer: {
+          noHeaders: 'Kolomnamen kunnen niet worden afgeleid. Heeft het bestand een header?',
+          noObjects: 'Objecten kunnen niet worden afgeleid. Bevat het bestand data naast de headers?',
+          invalidCsv: 'Het bestand kan niet verwerkt worden. Is het een valide csv bestand?',
+          invalidJson: 'Het bestand kan niet verwerkt worden. Is het valide json?',
+          jsonNotArray: 'Het json bestand moet een array bevatten. De actie wordt geannuleerd.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('pt-br', {
+        aggregate: {
+          label: 'itens'
+        },
+        groupPanel: {
+          description: 'Arraste e solte uma coluna aqui para agrupar por essa coluna'
+        },
+        search: {
+          placeholder: 'Procurar...',
+          showingItems: 'Mostrando os Itens:',
+          selectedItems: 'Items Selecionados:',
+          totalItems: 'Total de Itens:',
+          size: 'Tamanho da Página:',
+          first: 'Primeira Página',
+          next: 'Próxima Página',
+          previous: 'Página Anterior',
+          last: 'Última Página'
+        },
+        menu: {
+          text: 'Selecione as colunas:'
+        },
+        sort: {
+          ascending: 'Ordenar Ascendente',
+          descending: 'Ordenar Descendente',
+          remove: 'Remover Ordenação'
+        },
+        column: {
+          hide: 'Esconder coluna'
+        },
+        aggregation: {
+          count: 'total de linhas: ',
+          sum: 'total: ',
+          avg: 'med: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        pinning: {
+          pinLeft: 'Fixar Esquerda',
+          pinRight: 'Fixar Direita',
+          unpin: 'Desprender'
+        },
+        gridMenu: {
+          columns: 'Colunas:',
+          exporterAllAsCsv: 'Exportar todos os dados como csv',
+          exporterVisibleAsCsv: 'Exportar dados visíveis como csv',
+          exporterSelectedAsCsv: 'Exportar dados selecionados como csv',
+          exporterAllAsPdf: 'Exportar todos os dados como pdf',
+          exporterVisibleAsPdf: 'Exportar dados visíveis como pdf',
+          exporterSelectedAsPdf: 'Exportar dados selecionados como pdf'
+        },
+        importer: {
+          noHeaders: 'Nomes de colunas não puderam ser derivados. O arquivo tem um cabeçalho?',
+          noObjects: 'Objetos não puderam ser derivados. Havia dados no arquivo, além dos cabeçalhos?',
+          invalidCsv: 'Arquivo não pode ser processado. É um CSV válido?',
+          invalidJson: 'Arquivo não pode ser processado. É um Json válido?',
+          jsonNotArray: 'Arquivo json importado tem que conter um array. Abortando.'
+        }
+      });
+      return $delegate;
+    }]);
+}]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('ru', {
+        aggregate: {
+          label: 'элементы'
+        },
+        groupPanel: {
+          description: 'Для группировки по столбцу перетащите сюда его название.'
+        },
+        search: {
+          placeholder: 'Поиск...',
+          showingItems: 'Показать элементы:',
+          selectedItems: 'Выбранные элементы:',
+          totalItems: 'Всего элементов:',
+          size: 'Размер страницы:',
+          first: 'Первая страница',
+          next: 'Следующая страница',
+          previous: 'Предыдущая страница',
+          last: 'Последняя страница'
+        },
+        menu: {
+          text: 'Выбрать столбцы:'
+        },
+        sort: {
+          ascending: 'По возрастанию',
+          descending: 'По убыванию',
+          remove: 'Убрать сортировку'
+        },
+        column: {
+          hide: 'спрятать столбец'
+        },
+        aggregation: {
+          count: 'total rows: ',
+          sum: 'total: ',
+          avg: 'avg: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('sk', {
+        aggregate: {
+          label: 'items'
+        },
+        groupPanel: {
+          description: 'Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca.'
+        },
+        search: {
+          placeholder: 'Hľadaj...',
+          showingItems: 'Zobrazujem položky:',
+          selectedItems: 'Vybraté položky:',
+          totalItems: 'Počet položiek:',
+          size: 'Počet:',
+          first: 'Prvá strana',
+          next: 'Ďalšia strana',
+          previous: 'Predchádzajúca strana',
+          last: 'Posledná strana'
+        },
+        menu: {
+          text: 'Vyberte stĺpce:'
+        },
+        sort: {
+          ascending: 'Zotriediť vzostupne',
+          descending: 'Zotriediť zostupne',
+          remove: 'Vymazať triedenie'
+        },
+        aggregation: {
+          count: 'total rows: ',
+          sum: 'total: ',
+          avg: 'avg: ',
+          min: 'min: ',
+          max: 'max: '
+        },
+        gridMenu: {
+          columns: 'Columns:',
+          importerTitle: 'Import file',
+          exporterAllAsCsv: 'Export all data as csv',
+          exporterVisibleAsCsv: 'Export visible data as csv',
+          exporterSelectedAsCsv: 'Export selected data as csv',
+          exporterAllAsPdf: 'Export all data as pdf',
+          exporterVisibleAsPdf: 'Export visible data as pdf',
+          exporterSelectedAsPdf: 'Export selected data as pdf'
+        },
+        importer: {
+          noHeaders: 'Column names were unable to be derived, does the file have a header?',
+          noObjects: 'Objects were not able to be derived, was there data in the file other than headers?',
+          invalidCsv: 'File was unable to be processed, is it valid CSV?',
+          invalidJson: 'File was unable to be processed, is it valid Json?',
+          jsonNotArray: 'Imported json file must contain an array, aborting.'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+(function () {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('sv', {
+        aggregate: {
+          label: 'Artiklar'
+        },
+        groupPanel: {
+          description: 'Dra en kolumnrubrik hit och släpp den för att gruppera efter den kolumnen.'
+        },
+        search: {
+          placeholder: 'Sök...',
+          showingItems: 'Visar artiklar:',
+          selectedItems: 'Valda artiklar:',
+          totalItems: 'Antal artiklar:',
+          size: 'Sidstorlek:',
+          first: 'Första sidan',
+          next: 'Nästa sida',
+          previous: 'Föregående sida',
+          last: 'Sista sidan'
+        },
+        menu: {
+          text: 'Välj kolumner:'
+        },
+        sort: {
+          ascending: 'Sortera stigande',
+          descending: 'Sortera fallande',
+          remove: 'Inaktivera sortering'
+        },
+        column: {
+          hide: 'Göm kolumn'
+        },
+        aggregation: {
+          count: 'Antal rader: ',
+          sum: 'Summa: ',
+          avg: 'Genomsnitt: ',
+          min: 'Min: ',
+          max: 'Max: '
+        },
+        pinning: {
+          pinLeft: 'Fäst vänster',
+          pinRight: 'Fäst höger',
+          unpin: 'Lösgör'
+        },
+        gridMenu: {
+          columns: 'Kolumner:',
+          importerTitle: 'Importera fil',
+          exporterAllAsCsv: 'Exportera all data som CSV',
+          exporterVisibleAsCsv: 'Exportera synlig data som CSV',
+          exporterSelectedAsCsv: 'Exportera markerad data som CSV',
+          exporterAllAsPdf: 'Exportera all data som PDF',
+          exporterVisibleAsPdf: 'Exportera synlig data som PDF',
+          exporterSelectedAsPdf: 'Exportera markerad data som PDF'
+        },
+        importer: {
+          noHeaders: 'Kolumnnamn kunde inte härledas. Har filen ett sidhuvud?',
+          noObjects: 'Objekt kunde inte härledas. Har filen data undantaget sidhuvud?',
+          invalidCsv: 'Filen kunde inte behandlas, är den en giltig CSV?',
+          invalidJson: 'Filen kunde inte behandlas, är den en giltig JSON?',
+          jsonNotArray: 'Importerad JSON-fil måste innehålla ett fält. Import avbruten.'
+        },
+        paging: {
+          sizes: 'Artiklar per sida',
+          totalItems: 'Artiklar'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+/**
+ * @ngdoc overview
+ * @name ui.grid.i18n
+ * @description
+ *
+ *  # ui.grid.i18n
+ * This module provides i18n functions to ui.grid and any application that wants to use it
+
+ *
+ * <div doc-module-components="ui.grid.i18n"></div>
+ */
+
+(function () {
+  var DIRECTIVE_ALIASES = ['uiT', 'uiTranslate'];
+  var FILTER_ALIASES = ['t', 'uiTranslate'];
+
+  var module = angular.module('ui.grid.i18n');
+
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.i18n.constant:i18nConstants
+   *
+   *  @description constants available in i18n module
+   */
+  module.constant('i18nConstants', {
+    MISSING: '[MISSING]',
+    UPDATE_EVENT: '$uiI18n',
+
+    LOCALE_DIRECTIVE_ALIAS: 'uiI18n',
+    // default to english
+    DEFAULT_LANG: 'en'
+  });
+
+//    module.config(['$provide', function($provide) {
+//        $provide.decorator('i18nService', ['$delegate', function($delegate) {}])}]);
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.i18n.service:i18nService
+   *
+   *  @description Services for i18n
+   */
+  module.service('i18nService', ['$log', 'i18nConstants', '$rootScope',
+    function ($log, i18nConstants, $rootScope) {
+
+      var langCache = {
+        _langs: {},
+        current: null,
+        get: function (lang) {
+          return this._langs[lang.toLowerCase()];
+        },
+        add: function (lang, strings) {
+          var lower = lang.toLowerCase();
+          if (!this._langs[lower]) {
+            this._langs[lower] = {};
+          }
+          angular.extend(this._langs[lower], strings);
+        },
+        getAllLangs: function () {
+          var langs = [];
+          if (!this._langs) {
+            return langs;
+          }
+
+          for (var key in this._langs) {
+            langs.push(key);
+          }
+
+          return langs;
+        },
+        setCurrent: function (lang) {
+          this.current = lang.toLowerCase();
+        },
+        getCurrentLang: function () {
+          return this.current;
+        }
+      };
+
+      var service = {
+
+        /**
+         * @ngdoc service
+         * @name add
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  Adds the languages and strings to the cache. Decorate this service to
+         * add more translation strings
+         * @param {string} lang language to add
+         * @param {object} stringMaps of strings to add grouped by property names
+         * @example
+         * <pre>
+         *      i18nService.add('en', {
+         *         aggregate: {
+         *                 label1: 'items',
+         *                 label2: 'some more items'
+         *                 }
+         *         },
+         *         groupPanel: {
+         *              description: 'Drag a column header here and drop it to group by that column.'
+         *           }
+         *      }
+         * </pre>
+         */
+        add: function (langs, stringMaps) {
+          if (typeof(langs) === 'object') {
+            angular.forEach(langs, function (lang) {
+              if (lang) {
+                langCache.add(lang, stringMaps);
+              }
+            });
+          } else {
+            langCache.add(langs, stringMaps);
+          }
+        },
+
+        /**
+         * @ngdoc service
+         * @name getAllLangs
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  return all currently loaded languages
+         * @returns {array} string
+         */
+        getAllLangs: function () {
+          return langCache.getAllLangs();
+        },
+
+        /**
+         * @ngdoc service
+         * @name get
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  return all currently loaded languages
+         * @param {string} lang to return.  If not specified, returns current language
+         * @returns {object} the translation string maps for the language
+         */
+        get: function (lang) {
+          var language = lang ? lang : service.getCurrentLang();
+          return langCache.get(language);
+        },
+
+        /**
+         * @ngdoc service
+         * @name getSafeText
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description  returns the text specified in the path or a Missing text if text is not found
+         * @param {string} path property path to use for retrieving text from string map
+         * @param {string} lang to return.  If not specified, returns current language
+         * @returns {object} the translation for the path
+         * @example
+         * <pre>
+         * i18nService.getSafeText('sort.ascending')
+         * </pre>
+         */
+        getSafeText: function (path, lang) {
+          var language = lang ? lang : service.getCurrentLang();
+          var trans = langCache.get(language);
+
+          if (!trans) {
+            return i18nConstants.MISSING;
+          }
+
+          var paths = path.split('.');
+          var current = trans;
+
+          for (var i = 0; i < paths.length; ++i) {
+            if (current[paths[i]] === undefined || current[paths[i]] === null) {
+              return i18nConstants.MISSING;
+            } else {
+              current = current[paths[i]];
+            }
+          }
+
+          return current;
+
+        },
+
+        /**
+         * @ngdoc service
+         * @name setCurrentLang
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description sets the current language to use in the application
+         * $broadcasts the Update_Event on the $rootScope
+         * @param {string} lang to set
+         * @example
+         * <pre>
+         * i18nService.setCurrentLang('fr');
+         * </pre>
+         */
+
+        setCurrentLang: function (lang) {
+          if (lang) {
+            langCache.setCurrent(lang);
+            $rootScope.$broadcast(i18nConstants.UPDATE_EVENT);
+          }
+        },
+
+        /**
+         * @ngdoc service
+         * @name getCurrentLang
+         * @methodOf ui.grid.i18n.service:i18nService
+         * @description returns the current language used in the application
+         */
+        getCurrentLang: function () {
+          var lang = langCache.getCurrentLang();
+          if (!lang) {
+            lang = i18nConstants.DEFAULT_LANG;
+            langCache.setCurrent(lang);
+          }
+          return lang;
+        }
+
+      };
+
+      return service;
+
+    }]);
+
+  var localeDirective = function (i18nService, i18nConstants) {
+    return {
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs) {
+            var alias = i18nConstants.LOCALE_DIRECTIVE_ALIAS;
+            // check for watchable property
+            var lang = $scope.$eval($attrs[alias]);
+            if (lang) {
+              $scope.$watch($attrs[alias], function () {
+                i18nService.setCurrentLang(lang);
+              });
+            } else if ($attrs.$$observers) {
+              $attrs.$observe(alias, function () {
+                i18nService.setCurrentLang($attrs[alias] || i18nConstants.DEFAULT_LANG);
+              });
+            }
+          }
+        };
+      }
+    };
+  };
+
+  module.directive('uiI18n', ['i18nService', 'i18nConstants', localeDirective]);
+
+  // directive syntax
+  var uitDirective = function ($parse, i18nService, i18nConstants) {
+    return {
+      restrict: 'EA',
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs) {
+            var alias1 = DIRECTIVE_ALIASES[0],
+              alias2 = DIRECTIVE_ALIASES[1];
+            var token = $attrs[alias1] || $attrs[alias2] || $elm.html();
+            var missing = i18nConstants.MISSING + token;
+            var observer;
+            if ($attrs.$$observers) {
+              var prop = $attrs[alias1] ? alias1 : alias2;
+              observer = $attrs.$observe(prop, function (result) {
+                if (result) {
+                  $elm.html($parse(result)(i18nService.getCurrentLang()) || missing);
+                }
+              });
+            }
+            var getter = $parse(token);
+            var listener = $scope.$on(i18nConstants.UPDATE_EVENT, function (evt) {
+              if (observer) {
+                observer($attrs[alias1] || $attrs[alias2]);
+              } else {
+                // set text based on i18n current language
+                $elm.html(getter(i18nService.get()) || missing);
+              }
+            });
+            $scope.$on('$destroy', listener);
+
+            $elm.html(getter(i18nService.get()) || missing);
+          }
+        };
+      }
+    };
+  };
+
+  angular.forEach( DIRECTIVE_ALIASES, function ( alias ) {
+    module.directive( alias, ['$parse', 'i18nService', 'i18nConstants', uitDirective] );
+  } );
+
+  // optional filter syntax
+  var uitFilter = function ($parse, i18nService, i18nConstants) {
+    return function (data) {
+      var getter = $parse(data);
+      // set text based on i18n current language
+      return getter(i18nService.get()) || i18nConstants.MISSING + data;
+    };
+  };
+
+  angular.forEach( FILTER_ALIASES, function ( alias ) {
+    module.filter( alias, ['$parse', 'i18nService', 'i18nConstants', uitFilter] );
+  } );
+
+
+})();
+(function() {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('zh-cn', {
+        aggregate: {
+          label: '行'
+        },
+        groupPanel: {
+          description: '拖曳表头到此处进行分组'
+        },
+        search: {
+          placeholder: '查找',
+          showingItems: '已显示行数:',
+          selectedItems: '已选择行数:',
+          totalItems: '总行数:',
+          size: '每页显示行数:',
+          first: '首页',
+          next: '下一页',
+          previous: '上一页',
+          last: '末页'
+        },
+        menu: {
+          text: '选择列:'
+        },
+        sort: {
+          ascending: '升序',
+          descending: '降序',
+          remove: '取消排序'
+        },
+        column: {
+          hide: '隐藏列'
+        },
+        aggregation: {
+          count: '计数:',
+          sum: '求和:',
+          avg: '均值:',
+          min: '最小值:',
+          max: '最大值:'
+        },
+        pinning: {
+          pinLeft: '左侧固定',
+          pinRight: '右侧固定',
+          unpin: '取消固定'
+        },
+        gridMenu: {
+          columns: '列:',
+          importerTitle: '导入文件',
+          exporterAllAsCsv: '导出全部数据到CSV',
+          exporterVisibleAsCsv: '导出可见数据到CSV',
+          exporterSelectedAsCsv: '导出已选数据到CSV',
+          exporterAllAsPdf: '导出全部数据到PDF',
+          exporterVisibleAsPdf: '导出可见数据到PDF',
+          exporterSelectedAsPdf: '导出已选数据到PDF'
+        },
+        importer: {
+          noHeaders: '无法获取列名,确定文件包含表头?',
+          noObjects: '无法获取数据,确定文件包含数据?',
+          invalidCsv: '无法处理文件,确定是合法的CSV文件?',
+          invalidJson: '无法处理文件,确定是合法的JSON文件?',
+          jsonNotArray: '导入的文件不是JSON数组!'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+(function() {
+  angular.module('ui.grid').config(['$provide', function($provide) {
+    $provide.decorator('i18nService', ['$delegate', function($delegate) {
+      $delegate.add('zh-tw', {
+        aggregate: {
+          label: '行'
+        },
+        groupPanel: {
+          description: '拖曳表頭到此處進行分組'
+        },
+        search: {
+          placeholder: '查找',
+          showingItems: '已顯示行數:',
+          selectedItems: '已選擇行數:',
+          totalItems: '總行數:',
+          size: '每頁顯示行數:',
+          first: '首頁',
+          next: '下壹頁',
+          previous: '上壹頁',
+          last: '末頁'
+        },
+        menu: {
+          text: '選擇列:'
+        },
+        sort: {
+          ascending: '升序',
+          descending: '降序',
+          remove: '取消排序'
+        },
+        column: {
+          hide: '隱藏列'
+        },
+        aggregation: {
+          count: '計數:',
+          sum: '求和:',
+          avg: '均值:',
+          min: '最小值:',
+          max: '最大值:'
+        },
+        pinning: {
+          pinLeft: '左側固定',
+          pinRight: '右側固定',
+          unpin: '取消固定'
+        },
+        gridMenu: {
+          columns: '列:',
+          importerTitle: '導入文件',
+          exporterAllAsCsv: '導出全部數據到CSV',
+          exporterVisibleAsCsv: '導出可見數據到CSV',
+          exporterSelectedAsCsv: '導出已選數據到CSV',
+          exporterAllAsPdf: '導出全部數據到PDF',
+          exporterVisibleAsPdf: '導出可見數據到PDF',
+          exporterSelectedAsPdf: '導出已選數據到PDF'
+        },
+        importer: {
+          noHeaders: '無法獲取列名,確定文件包含表頭?',
+          noObjects: '無法獲取數據,確定文件包含數據?',
+          invalidCsv: '無法處理文件,確定是合法的CSV文件?',
+          invalidJson: '無法處理文件,確定是合法的JSON文件?',
+          jsonNotArray: '導入的文件不是JSON數組!'
+        }
+      });
+      return $delegate;
+    }]);
+  }]);
+})();
+
+(function() {
+  'use strict';
+  /**
+   *  @ngdoc overview
+   *  @name ui.grid.autoResize
+   *
+   *  @description 
+   *
+   *  #ui.grid.autoResize
+   *  This module provides auto-resizing functionality to ui-grid
+   *
+   */
+  var module = angular.module('ui.grid.autoResize', ['ui.grid']);
+  
+
+  module.directive('uiGridAutoResize', ['$timeout', 'gridUtil', function ($timeout, gridUtil) {
+    return {
+      require: 'uiGrid',
+      scope: false,
+      link: function ($scope, $elm, $attrs, uiGridCtrl) {
+        var prevGridWidth, prevGridHeight;
+
+        function getDimensions() {
+          prevGridHeight = gridUtil.elementHeight($elm);
+          prevGridWidth = gridUtil.elementWidth($elm);
+        }
+
+        // Initialize the dimensions
+        getDimensions();
+
+        var canceler;
+        function startTimeout() {
+          $timeout.cancel(canceler);
+
+          canceler = $timeout(function () {
+            var newGridHeight = gridUtil.elementHeight($elm);
+            var newGridWidth = gridUtil.elementWidth($elm);
+
+            if (newGridHeight !== prevGridHeight || newGridWidth !== prevGridWidth) {
+              uiGridCtrl.grid.gridHeight = newGridHeight;
+              uiGridCtrl.grid.gridWidth = newGridWidth;
+
+              uiGridCtrl.grid.refresh()
+                .then(function () {
+                  getDimensions();
+
+                  startTimeout();
+                });
+            }
+            else {
+              startTimeout();
+            }
+          }, 250);
+        }
+
+        startTimeout();
+
+        $scope.$on('$destroy', function() {
+          $timeout.cancel(canceler);
+        });
+      }
+    };
+  }]);
+})();
+(function () {
+  'use strict';
+  var module = angular.module('ui.grid.cellNav', ['ui.grid']);
+
+  function RowCol(row, col) {
+    this.row = row;
+    this.col = col;
+  }
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.cellNav.constant:uiGridCellNavConstants
+   *
+   *  @description constants available in cellNav
+   */
+  module.constant('uiGridCellNavConstants', {
+    FEATURE_NAME: 'gridCellNav',
+    CELL_NAV_EVENT: 'cellNav',
+    direction: {LEFT: 0, RIGHT: 1, UP: 2, DOWN: 3},
+    EVENT_TYPE: {
+      KEYDOWN: 0,
+      CLICK: 1
+    }
+  });
+
+
+  module.factory('uiGridCellNavFactory', ['gridUtil', 'uiGridConstants', 'uiGridCellNavConstants', '$q',
+    function (gridUtil, uiGridConstants, uiGridCellNavConstants, $q) {
+      /**
+       *  @ngdoc object
+       *  @name ui.grid.cellNav.object:CellNav
+       *  @description returns a CellNav prototype function
+       *  @param {object} rowContainer container for rows
+       *  @param {object} colContainer parent column container
+       *  @param {object} leftColContainer column container to the left of parent
+       *  @param {object} rightColContainer column container to the right of parent
+       */
+      var UiGridCellNav = function UiGridCellNav(rowContainer, colContainer, leftColContainer, rightColContainer) {
+        this.rows = rowContainer.visibleRowCache;
+        this.columns = colContainer.visibleColumnCache;
+        this.leftColumns = leftColContainer ? leftColContainer.visibleColumnCache : [];
+        this.rightColumns = rightColContainer ? rightColContainer.visibleColumnCache : [];
+      };
+
+      /** returns focusable columns of all containers */
+      UiGridCellNav.prototype.getFocusableCols = function () {
+        var allColumns = this.leftColumns.concat(this.columns, this.rightColumns);
+
+        return allColumns.filter(function (col) {
+          return col.colDef.allowCellFocus;
+        });
+      };
+
+      UiGridCellNav.prototype.getNextRowCol = function (direction, curRow, curCol) {
+        switch (direction) {
+          case uiGridCellNavConstants.direction.LEFT:
+            return this.getRowColLeft(curRow, curCol);
+          case uiGridCellNavConstants.direction.RIGHT:
+            return this.getRowColRight(curRow, curCol);
+          case uiGridCellNavConstants.direction.UP:
+            return this.getRowColUp(curRow, curCol);
+          case uiGridCellNavConstants.direction.DOWN:
+            return this.getRowColDown(curRow, curCol);
+        }
+
+      };
+
+      UiGridCellNav.prototype.getRowColLeft = function (curRow, curCol) {
+        var focusableCols = this.getFocusableCols();
+        var curColIndex = focusableCols.indexOf(curCol);
+        var curRowIndex = this.rows.indexOf(curRow);
+
+        //could not find column in focusable Columns so set it to 1
+        if (curColIndex === -1) {
+          curColIndex = 1;
+        }
+
+        var nextColIndex = curColIndex === 0 ? focusableCols.length - 1 : curColIndex - 1;
+
+        //get column to left
+        if (nextColIndex > curColIndex) {
+          if (curRowIndex === 0) {
+            return new RowCol(curRow, focusableCols[nextColIndex]); //return same row
+          }
+          else {
+            //up one row and far right column
+            return new RowCol(this.rows[curRowIndex - 1], focusableCols[nextColIndex]);
+          }
+        }
+        else {
+          return new RowCol(curRow, focusableCols[nextColIndex]);
+        }
+      };
+
+      UiGridCellNav.prototype.getRowColRight = function (curRow, curCol) {
+        var focusableCols = this.getFocusableCols();
+        var curColIndex = focusableCols.indexOf(curCol);
+        var curRowIndex = this.rows.indexOf(curRow);
+
+        //could not find column in focusable Columns so set it to 0
+        if (curColIndex === -1) {
+          curColIndex = 0;
+        }
+        var nextColIndex = curColIndex === focusableCols.length - 1 ? 0 : curColIndex + 1;
+
+        if (nextColIndex < curColIndex) {
+          if (curRowIndex === this.rows.length - 1) {
+            return new RowCol(curRow, focusableCols[nextColIndex]); //return same row
+          }
+          else {
+            //down one row and far left column
+            return new RowCol(this.rows[curRowIndex + 1], focusableCols[nextColIndex]);
+          }
+        }
+        else {
+          return new RowCol(curRow, focusableCols[nextColIndex]);
+        }
+      };
+
+      UiGridCellNav.prototype.getRowColDown = function (curRow, curCol) {
+        var focusableCols = this.getFocusableCols();
+        var curColIndex = focusableCols.indexOf(curCol);
+        var curRowIndex = this.rows.indexOf(curRow);
+
+        //could not find column in focusable Columns so set it to 0
+        if (curColIndex === -1) {
+          curColIndex = 0;
+        }
+
+        if (curRowIndex === this.rows.length - 1) {
+          return new RowCol(curRow, focusableCols[curColIndex]); //return same row
+        }
+        else {
+          //down one row
+          return new RowCol(this.rows[curRowIndex + 1], focusableCols[curColIndex]);
+        }
+      };
+
+      UiGridCellNav.prototype.getRowColUp = function (curRow, curCol) {
+        var focusableCols = this.getFocusableCols();
+        var curColIndex = focusableCols.indexOf(curCol);
+        var curRowIndex = this.rows.indexOf(curRow);
+
+        //could not find column in focusable Columns so set it to 0
+        if (curColIndex === -1) {
+          curColIndex = 0;
+        }
+
+        if (curRowIndex === 0) {
+          return new RowCol(curRow, focusableCols[curColIndex]); //return same row
+        }
+        else {
+          //up one row
+          return new RowCol(this.rows[curRowIndex - 1], focusableCols[curColIndex]);
+        }
+      };
+
+      return UiGridCellNav;
+    }]);
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.cellNav.service:uiGridCellNavService
+   *
+   *  @description Services for cell navigation features. If you don't like the key maps we use,
+   *  or the direction cells navigation, override with a service decorator (see angular docs)
+   */
+  module.service('uiGridCellNavService', ['gridUtil', 'uiGridConstants', 'uiGridCellNavConstants', '$q', 'uiGridCellNavFactory',
+    function (gridUtil, uiGridConstants, uiGridCellNavConstants, $q, UiGridCellNav) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+          grid.registerColumnBuilder(service.cellNavColumnBuilder);
+
+          //create variables for state
+          grid.cellNav = {};
+          grid.cellNav.lastRowCol = null;
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.cellNav.api:PublicApi
+           *
+           *  @description Public Api for cellNav feature
+           */
+          var publicApi = {
+            events: {
+              cellNav: {
+                /**
+                 * @ngdoc event
+                 * @name navigate
+                 * @eventOf  ui.grid.cellNav.api:PublicApi
+                 * @description raised when the active cell is changed
+                 * <pre>
+                 *      gridApi.cellNav.on.navigate(scope,function(newRowcol, oldRowCol){})
+                 * </pre>
+                 * @param {object} newRowCol new position
+                 * @param {object} oldRowCol old position
+                 */
+                navigate: function (newRowCol, oldRowCol) {
+                }
+              }
+            },
+            methods: {
+              cellNav: {
+                /**
+                 * @ngdoc function
+                 * @name scrollTo
+                 * @methodOf  ui.grid.cellNav.api:PublicApi
+                 * @description brings the specified row and column into view
+                 * @param {Grid} grid the grid you'd like to act upon, usually available
+                 * from gridApi.grid
+                 * @param {object} $scope a scope we can broadcast events from
+                 * @param {object} rowEntity gridOptions.data[] array instance to make visible
+                 * @param {object} colDef to make visible
+                 */
+                scrollTo: function (grid, $scope, rowEntity, colDef) {
+                  service.scrollTo(grid, $scope, rowEntity, colDef);
+                },
+
+                /**
+                 * @ngdoc function
+                 * @name getFocusedCell
+                 * @methodOf  ui.grid.cellNav.api:PublicApi
+                 * @description returns the current (or last if Grid does not have focus) focused row and column
+                 * <br> value is null if no selection has occurred
+                 */
+                getFocusedCell: function () {
+                  return grid.cellNav.lastRowCol;
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        /**
+         * @ngdoc service
+         * @name decorateRenderContainers
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description  decorates grid renderContainers with cellNav functions
+         */
+        decorateRenderContainers: function (grid) {
+
+          var rightContainer = grid.hasRightContainer() ? grid.renderContainers.right : null;
+          var leftContainer = grid.hasLeftContainer() ? grid.renderContainers.left : null;
+
+          if (leftContainer !== null) {
+            grid.renderContainers.left.cellNav = new UiGridCellNav(grid.renderContainers.body, leftContainer, rightContainer, grid.renderContainers.body);
+          }
+          if (rightContainer !== null) {
+            grid.renderContainers.right.cellNav = new UiGridCellNav(grid.renderContainers.body, rightContainer, grid.renderContainers.body, leftContainer);
+          }
+
+          grid.renderContainers.body.cellNav = new UiGridCellNav(grid.renderContainers.body, grid.renderContainers.body, leftContainer, rightContainer);
+        },
+
+        /**
+         * @ngdoc service
+         * @name getDirection
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description  determines which direction to for a given keyDown event
+         * @returns {uiGridCellNavConstants.direction} direction
+         */
+        getDirection: function (evt) {
+          if (evt.keyCode === uiGridConstants.keymap.LEFT ||
+            (evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey)) {
+            return uiGridCellNavConstants.direction.LEFT;
+          }
+          if (evt.keyCode === uiGridConstants.keymap.RIGHT ||
+            evt.keyCode === uiGridConstants.keymap.TAB) {
+            return uiGridCellNavConstants.direction.RIGHT;
+          }
+
+          if (evt.keyCode === uiGridConstants.keymap.UP ||
+            (evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey)) {
+            return uiGridCellNavConstants.direction.UP;
+          }
+
+          if (evt.keyCode === uiGridConstants.keymap.DOWN ||
+            evt.keyCode === uiGridConstants.keymap.ENTER) {
+            return uiGridCellNavConstants.direction.DOWN;
+          }
+
+          return null;
+        },
+
+        /**
+         * @ngdoc service
+         * @name cellNavColumnBuilder
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @description columnBuilder function that adds cell navigation properties to grid column
+         * @returns {promise} promise that will load any needed templates when resolved
+         */
+        cellNavColumnBuilder: function (colDef, col, gridOptions) {
+          var promises = [];
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.cellNav.api:ColumnDef
+           *
+           *  @description Column Definitions for cellNav feature, these are available to be
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name allowCellFocus
+           *  @propertyOf  ui.grid.cellNav.api:ColumnDef
+           *  @description Enable focus on a cell.
+           *  <br/>Defaults to true
+           */
+          colDef.allowCellFocus = colDef.allowCellFocus === undefined ? true : colDef.allowCellFocus;
+
+          return $q.all(promises);
+        },
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name scrollTo
+         * @description Scroll the grid such that the specified
+         * row and column is in view
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {object} $scope a scope we can broadcast events from
+         * @param {object} rowEntity gridOptions.data[] array instance to make visible
+         * @param {object} colDef to make visible
+         */
+        scrollTo: function (grid, $scope, rowEntity, colDef) {
+          var gridRow = null, gridCol = null;
+
+          if (rowEntity !== null) {
+            gridRow = grid.getRow(rowEntity);
+          }
+
+          if (colDef !== null) {
+            gridCol = grid.getColumn(colDef.name ? colDef.name : colDef.field);
+          }
+          this.scrollToInternal(grid, $scope, gridRow, gridCol);
+        },
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name scrollToInternal
+         * @description Like scrollTo, but takes gridRow and gridCol.
+         * In calculating the scroll height we have to deal with wanting
+         * 0% for the first row, and 100% for the last row.  Normal maths
+         * for a 10 row list would return 1/10 = 10% for the first row, so 
+         * we need to tweak the numbers to add an extra 10% somewhere.  The
+         * formula if we're trying to get to row 0 in a 10 row list (assuming our
+         * index is zero based, so the last row is row 9) is:
+         * <pre>
+         *   0 + 0 / 10 = 0%
+         * </pre>
+         * 
+         * To get to row 9 (i.e. the last row) in the same list, we want to 
+         * go to:
+         * <pre>
+         *  ( 9 + 1 ) / 10 = 100%
+         * </pre>
+         * So we need to apportion one whole row within the overall grid scroll, 
+         * the formula is:
+         * <pre>
+         *   ( index + ( index / (total rows - 1) ) / total rows
+         * </pre>
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {object} $scope a scope we can broadcast events from
+         * @param {GridRow} gridRow row to make visible
+         * @param {GridCol} gridCol column to make visible
+         */
+        scrollToInternal: function (grid, $scope, gridRow, gridCol) {
+          var args = {};
+
+          if (gridRow !== null) {
+            var seekRowIndex = grid.renderContainers.body.visibleRowCache.indexOf(gridRow);
+            var totalRows = grid.renderContainers.body.visibleRowCache.length;
+            var percentage = ( seekRowIndex + ( seekRowIndex / ( totalRows - 1 ) ) ) / totalRows;
+            args.y = { percentage:  percentage  };
+          }
+
+          if (gridCol !== null) {
+            args.x = { percentage: this.getLeftWidth(grid, gridCol) / this.getLeftWidth(grid, grid.renderContainers.body.visibleColumnCache[grid.renderContainers.body.visibleColumnCache.length - 1] ) };
+          }
+
+          if (args.y || args.x) {
+            $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
+          }
+        },
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name scrollToIfNecessary
+         * @description Scrolls the grid to make a certain row and column combo visible,
+         *   in the case that it is not completely visible on the screen already.
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {object} $scope a scope we can broadcast events from
+         * @param {GridRow} gridRow row to make visible
+         * @param {GridCol} gridCol column to make visible
+         */
+        scrollToIfNecessary: function (grid, $scope, gridRow, gridCol) {
+          var args = {};
+
+          // Alias the visible row and column caches 
+          var visRowCache = grid.renderContainers.body.visibleRowCache;
+          var visColCache = grid.renderContainers.body.visibleColumnCache;
+
+          /*-- Get the top, left, right, and bottom "scrolled" edges of the grid --*/
+
+          // The top boundary is the current Y scroll position PLUS the header height, because the header can obscure rows when the grid is scrolled downwards
+          var topBound = grid.renderContainers.body.prevScrollTop + grid.headerHeight;
+
+          // Don't the let top boundary be less than 0
+          topBound = (topBound < 0) ? 0 : topBound;
+
+          // The left boundary is the current X scroll position
+          var leftBound = grid.renderContainers.body.prevScrollLeft;
+
+          // The bottom boundary is the current Y scroll position, plus the height of the grid, but minus the header height.
+          //   Basically this is the viewport height added on to the scroll position
+          var bottomBound = grid.renderContainers.body.prevScrollTop + grid.gridHeight - grid.headerHeight;
+
+          // If there's a horizontal scrollbar, remove its height from the bottom boundary, otherwise we'll be letting it obscure rows
+          if (grid.horizontalScrollbarHeight) {
+            bottomBound = bottomBound - grid.horizontalScrollbarHeight;
+          }
+
+          // The right position is the current X scroll position minus the grid width
+          var rightBound = grid.renderContainers.body.prevScrollLeft + grid.gridWidth;
+
+          // If there's a vertical scrollbar, subtract it from the right boundary or we'll allow it to obscure cells
+          if (grid.verticalScrollbarWidth) {
+            rightBound = rightBound - grid.verticalScrollbarWidth;
+          }
+
+          // We were given a row to scroll to
+          if (gridRow !== null) {
+            // This is the index of the row we want to scroll to, within the list of rows that can be visible
+            var seekRowIndex = visRowCache.indexOf(gridRow);
+            
+            // Total vertical scroll length of the grid
+            var scrollLength = (grid.renderContainers.body.getCanvasHeight() - grid.renderContainers.body.getViewportHeight());
+
+            // Add the height of the native horizontal scrollbar to the scroll length, if it's there. Otherwise it will mask over the final row
+            if (grid.horizontalScrollbarHeight && grid.horizontalScrollbarHeight > 0) {
+              scrollLength = scrollLength + grid.horizontalScrollbarHeight;
+            }
+
+            // This is the minimum amount of pixels we need to scroll vertical in order to see this row.
+            var pixelsToSeeRow = ((seekRowIndex + 1) * grid.options.rowHeight);
+
+            // Don't let the pixels required to see the row be less than zero
+            pixelsToSeeRow = (pixelsToSeeRow < 0) ? 0 : pixelsToSeeRow;
+
+            var scrollPixels, percentage;
+
+            // If the scroll position we need to see the row is LESS than the top boundary, i.e. obscured above the top of the grid...
+            if (pixelsToSeeRow < topBound) {
+              // Get the different between the top boundary and the required scroll position and subtract it from the current scroll position\
+              //   to get the full position we need
+              scrollPixels = grid.renderContainers.body.prevScrollTop - (topBound - pixelsToSeeRow);
+
+              // Turn the scroll position into a percentage and make it an argument for a scroll event
+              percentage = scrollPixels / scrollLength;
+              args.y = { percentage: percentage  };
+            }
+            // Otherwise if the scroll position we need to see the row is MORE than the bottom boundary, i.e. obscured below the bottom of the grid...
+            else if (pixelsToSeeRow > bottomBound) {
+              // Get the different between the bottom boundary and the required scroll position and add it to the current scroll position
+              //   to get the full position we need
+              scrollPixels = pixelsToSeeRow - bottomBound + grid.renderContainers.body.prevScrollTop;
+
+              // Turn the scroll position into a percentage and make it an argument for a scroll event
+              percentage = scrollPixels / scrollLength;
+              args.y = { percentage: percentage  };
+            }
+          }
+
+          // We were given a column to scroll to
+          if (gridCol !== null) {
+            // This is the index of the row we want to scroll to, within the list of rows that can be visible
+            var seekColumnIndex = visColCache.indexOf(gridCol);
+            
+            // Total vertical scroll length of the grid
+            var horizScrollLength = (grid.renderContainers.body.getCanvasWidth() - grid.renderContainers.body.getViewportWidth());
+
+            // Add the height of the native horizontal scrollbar to the scroll length, if it's there. Otherwise it will mask over the final row
+            // if (grid.verticalScrollbarWidth && grid.verticalScrollbarWidth > 0) {
+            //   horizScrollLength = horizScrollLength + grid.verticalScrollbarWidth;
+            // }
+
+            // This is the minimum amount of pixels we need to scroll vertical in order to see this column
+            var columnLeftEdge = 0;
+            for (var i = 0; i < seekColumnIndex; i++) {
+              var col = visColCache[i];
+              columnLeftEdge += col.drawnWidth;
+            }
+            columnLeftEdge = (columnLeftEdge < 0) ? 0 : columnLeftEdge;
+
+            var columnRightEdge = columnLeftEdge + gridCol.drawnWidth;
+
+            // Don't let the pixels required to see the column be less than zero
+            columnRightEdge = (columnRightEdge < 0) ? 0 : columnRightEdge;
+
+            var horizScrollPixels, horizPercentage;
+
+            // If the scroll position we need to see the row is LESS than the top boundary, i.e. obscured above the top of the grid...
+            if (columnLeftEdge < leftBound) {
+              // Get the different between the top boundary and the required scroll position and subtract it from the current scroll position\
+              //   to get the full position we need
+              horizScrollPixels = grid.renderContainers.body.prevScrollLeft - (leftBound - columnLeftEdge);
+
+              // Turn the scroll position into a percentage and make it an argument for a scroll event
+              horizPercentage = horizScrollPixels / horizScrollLength;
+              horizPercentage = (horizPercentage > 1) ? 1 : horizPercentage;
+              args.x = { percentage: horizPercentage  };
+            }
+            // Otherwise if the scroll position we need to see the row is MORE than the bottom boundary, i.e. obscured below the bottom of the grid...
+            else if (columnRightEdge > rightBound) {
+              // Get the different between the bottom boundary and the required scroll position and add it to the current scroll position
+              //   to get the full position we need
+              horizScrollPixels = columnRightEdge - rightBound + grid.renderContainers.body.prevScrollLeft;
+
+              // Turn the scroll position into a percentage and make it an argument for a scroll event
+              horizPercentage = horizScrollPixels / horizScrollLength;
+              horizPercentage = (horizPercentage > 1) ? 1 : horizPercentage;
+              args.x = { percentage: horizPercentage  };
+            }
+          }
+
+          // If we need to scroll on either the x or y axes, fire a scroll event
+          if (args.y || args.x) {
+            $scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
+          }
+        },
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.cellNav.service:uiGridCellNavService
+         * @name getLeftWidth
+         * @description Get the current drawn width of the columns in the
+         * grid up to the numbered column, and add an apportionment for the
+         * column that we're on.  So if we are on column 0, we want to scroll
+         * 0% (i.e. exclude this column from calc).  If we're on the last column
+         * we want to scroll to 100% (i.e. include this column in the calc). So
+         * we include (thisColIndex / totalNumberCols) % of this column width
+         * @param {Grid} grid the grid you'd like to act upon, usually available
+         * from gridApi.grid
+         * @param {gridCol} upToCol the column to total up to and including
+         */
+        getLeftWidth: function (grid, upToCol) {
+          var width = 0;
+
+          if (!upToCol) {
+            return width;
+          }
+          
+          var lastIndex = grid.renderContainers.body.visibleColumnCache.indexOf( upToCol );
+          
+          // total column widths up-to but not including the passed in column
+          grid.renderContainers.body.visibleColumnCache.forEach( function( col, index ) {
+            if ( index < lastIndex ){
+              width += col.drawnWidth;  
+            }
+          });
+          
+          // pro-rata the final column based on % of total columns.
+          var percentage = lastIndex === 0 ? 0 : (lastIndex + 1) / grid.renderContainers.body.visibleColumnCache.length;
+          width += upToCol.drawnWidth * percentage;
+           
+          return width;
+        }
+      };
+
+      return service;
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.cellNav.directive:uiCellNav
+   *  @element div
+   *  @restrict EA
+   *
+   *  @description Adds cell navigation features to the grid columns
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name'},
+        {name: 'title'}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-cellnav></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridCellnav', ['gridUtil', 'uiGridCellNavService', 'uiGridCellNavConstants',
+    function (gridUtil, uiGridCellNavService, uiGridCellNavConstants) {
+      return {
+        replace: true,
+        priority: -150,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+
+              var grid = uiGridCtrl.grid;
+              uiGridCellNavService.initializeGrid(grid);
+
+              uiGridCtrl.cellNav = {};
+
+              uiGridCtrl.cellNav.focusCell = function (row, col) {
+                uiGridCtrl.cellNav.broadcastCellNav({ row: row, col: col });
+              };
+
+              //  gridUtil.logDebug('uiGridEdit preLink');
+              uiGridCtrl.cellNav.broadcastCellNav = function (newRowCol) {
+                $scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT, newRowCol);
+                uiGridCtrl.cellNav.broadcastFocus(newRowCol);
+              };
+
+              uiGridCtrl.cellNav.broadcastFocus = function (rowCol) {
+                var row = rowCol.row,
+                    col = rowCol.col;
+
+                if (grid.cellNav.lastRowCol === null || (grid.cellNav.lastRowCol.row !== row || grid.cellNav.lastRowCol.col !== col)) {
+                  var newRowCol = new RowCol(row, col);
+                  grid.api.cellNav.raise.navigate(newRowCol, grid.cellNav.lastRowCol);
+                  grid.cellNav.lastRowCol = newRowCol;
+                }
+              };
+
+              uiGridCtrl.cellNav.handleKeyDown = function (evt) {
+                var direction = uiGridCellNavService.getDirection(evt);
+                if (direction === null) {
+                  return true;
+                }
+
+                var containerId = 'body';
+                if (evt.uiGridTargetRenderContainerId) {
+                  containerId = evt.uiGridTargetRenderContainerId;
+                }
+
+                // Get the last-focused row+col combo
+                var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
+                if (lastRowCol) {
+                  // Figure out which new row+combo we're navigating to
+                  var rowCol = uiGridCtrl.grid.renderContainers[containerId].cellNav.getNextRowCol(direction, lastRowCol.row, lastRowCol.col);
+
+                  rowCol.eventType = uiGridCellNavConstants.EVENT_TYPE.KEYDOWN;
+
+                  // Broadcast the navigation
+                  uiGridCtrl.cellNav.broadcastCellNav(rowCol);
+
+                  // Scroll to the new cell, if it's not completely visible within the render container's viewport
+                  uiGridCellNavService.scrollToIfNecessary(grid, $scope, rowCol.row, rowCol.col);
+
+                  evt.stopPropagation();
+                  evt.preventDefault();
+
+                  return false;
+                }
+              };
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridRenderContainer', ['$timeout', '$document', 'gridUtil', 'uiGridConstants', 'uiGridCellNavService', 'uiGridCellNavConstants',
+    function ($timeout, $document, gridUtil, uiGridConstants, uiGridCellNavService, uiGridCellNavConstants) {
+      return {
+        replace: true,
+        priority: -99999, //this needs to run very last
+        require: ['^uiGrid', 'uiGridRenderContainer'],
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            },
+            post: function ($scope, $elm, $attrs, controllers) {
+              var uiGridCtrl = controllers[0],
+                  renderContainerCtrl = controllers[1];
+
+              var containerId = renderContainerCtrl.containerId;
+
+              var grid = uiGridCtrl.grid;
+
+              // Needs to run last after all renderContainers are built
+              uiGridCellNavService.decorateRenderContainers(grid);
+
+              // Let the render container be focus-able
+              $elm.attr("tabindex", -1);
+
+              // Bind to keydown events in the render container
+              $elm.on('keydown', function (evt) {
+                evt.uiGridTargetRenderContainerId = containerId;
+                return uiGridCtrl.cellNav.handleKeyDown(evt);
+              });
+
+              // When there's a scroll event we need to make sure to re-focus the right row, because the cell contents may have changed
+              $scope.$on(uiGridConstants.events.GRID_SCROLL, function (evt, args) {
+                // Skip if there's no currently-focused cell
+                if (uiGridCtrl.grid.api.cellNav.getFocusedCell() == null) {
+                  return;
+                }
+
+                // We have to wrap in TWO timeouts so that we run AFTER the scroll event is resolved.
+                $timeout(function () {
+                  $timeout(function () {
+                    // Get the last row+col combo
+                    var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
+
+                    // If the body element becomes active, re-focus on the render container so we can capture cellNav events again.
+                    //   NOTE: this happens when we navigate LET from the left-most cell (RIGHT from the right-most) and have to re-render a new
+                    //   set of cells. The cell element we are navigating to doesn't exist and focus gets lost. This will re-capture it, imperfectly...
+                    if ($document.activeElement === $document.body) {
+                      $elm[0].focus();
+                    }
+
+                    // Re-broadcast a cellNav event so we re-focus the right cell
+                    uiGridCtrl.cellNav.broadcastCellNav(lastRowCol);
+                  });
+                });
+              });
+            }
+          };
+        }
+      };
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.cellNav.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *  @description Stacks on top of ui.grid.uiGridCell to provide cell navigation
+   */
+  module.directive('uiGridCell', ['$timeout', '$document', 'uiGridCellNavService', 'gridUtil', 'uiGridCellNavConstants', 'uiGridConstants',
+    function ($timeout, $document, uiGridCellNavService, gridUtil, uiGridCellNavConstants, uiGridConstants) {
+      return {
+        priority: -150, // run after default uiGridCell directive and ui.grid.edit uiGridCell
+        restrict: 'A',
+        require: '^uiGrid',
+        scope: false,
+        link: function ($scope, $elm, $attrs, uiGridCtrl) {
+          if (!$scope.col.colDef.allowCellFocus) {
+            return;
+          }
+
+          setTabEnabled();
+          
+          // When a cell is clicked, broadcast a cellNav event saying that this row+col combo is now focused
+          $elm.find('div').on('click', function (evt) {
+            uiGridCtrl.cellNav.broadcastCellNav(new RowCol($scope.row, $scope.col));
+
+            evt.stopPropagation();
+          });
+
+          // This event is fired for all cells.  If the cell matches, then focus is set
+          $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function (evt, rowCol) {
+            if (rowCol.row === $scope.row &&
+              rowCol.col === $scope.col) {
+              setFocused();
+
+              // This cellNav event came from a keydown event so we can safely refocus
+              if (rowCol.hasOwnProperty('eventType') && rowCol.eventType === uiGridCellNavConstants.EVENT_TYPE.KEYDOWN) {
+                $elm.find('div')[0].focus();
+              }
+            }
+            else {
+              clearFocus();
+            }
+          });
+
+          function setTabEnabled() {
+            $elm.find('div').attr("tabindex", -1);
+          }
+
+          function setFocused() {
+            var div = $elm.find('div');
+            div.addClass('ui-grid-cell-focus');
+          }
+
+          function clearFocus() {
+            var div = $elm.find('div');
+            div.removeClass('ui-grid-cell-focus');
+          }
+
+          $scope.$on('$destroy', function () {
+            $elm.find('div').off('click');
+          });
+        }
+      };
+    }]);
+
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.edit
+   * @description
+   *
+   *  # ui.grid.edit
+   * This module provides cell editing capability to ui.grid. The goal was to emulate keying data in a spreadsheet via
+   * a keyboard.
+   * <br/>
+   * <br/>
+   * To really get the full spreadsheet-like data entry, the ui.grid.cellNav module should be used. This will allow the
+   * user to key data and then tab, arrow, or enter to the cells beside or below.
+   *
+   * <div doc-module-components="ui.grid.edit"></div>
+   */
+
+  var module = angular.module('ui.grid.edit', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.edit.constant:uiGridEditConstants
+   *
+   *  @description constants available in edit module
+   */
+  module.constant('uiGridEditConstants', {
+    EDITABLE_CELL_TEMPLATE: /EDITABLE_CELL_TEMPLATE/g,
+    //must be lowercase because template bulder converts to lower
+    EDITABLE_CELL_DIRECTIVE: /editable_cell_directive/g,
+    events: {
+      BEGIN_CELL_EDIT: 'uiGridEventBeginCellEdit',
+      END_CELL_EDIT: 'uiGridEventEndCellEdit',
+      CANCEL_CELL_EDIT: 'uiGridEventCancelCellEdit'
+    }
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.edit.service:uiGridEditService
+   *
+   *  @description Services for editing features
+   */
+  module.service('uiGridEditService', ['$q', '$templateCache', 'uiGridConstants', 'gridUtil',
+    function ($q, $templateCache, uiGridConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          service.defaultGridOptions(grid.options);
+
+          grid.registerColumnBuilder(service.editColumnBuilder);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:PublicApi
+           *
+           *  @description Public Api for edit feature
+           */
+          var publicApi = {
+            events: {
+              edit: {
+                /**
+                 * @ngdoc event
+                 * @name afterCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing is complete
+                 * <pre>
+                 *      gridApi.edit.on.afterCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 * @param {object} newValue new value
+                 * @param {object} oldValue old value
+                 */
+                afterCellEdit: function (rowEntity, colDef, newValue, oldValue) {
+                },
+                /**
+                 * @ngdoc event
+                 * @name beginCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing starts on a cell
+                 * <pre>
+                 *      gridApi.edit.on.beginCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 */
+                beginCellEdit: function (rowEntity, colDef) {
+                },
+                /**
+                 * @ngdoc event
+                 * @name cancelCellEdit
+                 * @eventOf  ui.grid.edit.api:PublicApi
+                 * @description raised when cell editing is cancelled on a cell
+                 * <pre>
+                 *      gridApi.edit.on.cancelCellEdit(scope,function(rowEntity, colDef){})
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @param {object} colDef the column that was edited
+                 */
+                cancelCellEdit: function (rowEntity, colDef) {
+                }                
+              }
+            },
+            methods: {
+              edit: { }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+          //grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:GridOptions
+           *
+           *  @description Options for configuring the edit feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEdit
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If defined, sets the default value for the editable flag on each individual colDefs 
+           *  if their individual enableCellEdit configuration is not defined. Defaults to undefined.  
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name cellEditableCondition
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If specified, either a value or function to be used by all columns before editing.  
+           *  If falsy, then editing of cell is not allowed.
+           *  @example
+           *  <pre>
+           *  function($scope){
+           *    //use $scope.row.entity and $scope.col.colDef to determine if editing is allowed
+           *    return true;
+           *  }
+           *  </pre>
+           */
+          gridOptions.cellEditableCondition = gridOptions.cellEditableCondition === undefined ? true : gridOptions.cellEditableCondition;
+
+          /**
+           *  @ngdoc object
+           *  @name editableCellTemplate
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If specified, cellTemplate to use as the editor for all columns.  
+           *  <br/> defaults to 'ui-grid/cellTextEditor'
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEditOnFocus
+           *  @propertyOf  ui.grid.edit.api:GridOptions
+           *  @description If true, then editor is invoked as soon as cell receives focus. Default false.
+           *  <br/>_requires cellNav feature and the edit feature to be enabled_
+           */
+            //enableCellEditOnFocus can only be used if cellnav module is used
+          gridOptions.enableCellEditOnFocus = gridOptions.enableCellEditOnFocus === undefined ? false : gridOptions.enableCellEditOnFocus;
+        },
+
+        /**
+         * @ngdoc service
+         * @name editColumnBuilder
+         * @methodOf ui.grid.edit.service:uiGridEditService
+         * @description columnBuilder function that adds edit properties to grid column
+         * @returns {promise} promise that will load any needed templates when resolved
+         */
+        editColumnBuilder: function (colDef, col, gridOptions) {
+
+          var promises = [];
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.edit.api:ColumnDef
+           *
+           *  @description Column Definition for edit feature, these are available to be 
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEdit
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description enable editing on column
+           */
+          colDef.enableCellEdit = colDef.enableCellEdit === undefined ? (gridOptions.enableCellEdit === undefined ?
+            (colDef.type !== 'object') : gridOptions.enableCellEdit) : colDef.enableCellEdit;
+
+          /**
+           *  @ngdoc object
+           *  @name cellEditableCondition
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description If specified, either a value or function evaluated before editing cell.  If falsy, then editing of cell is not allowed.
+           *  @example 
+           *  <pre>
+           *  function($scope){
+           *    //use $scope.row.entity and $scope.col.colDef to determine if editing is allowed
+           *    return true;
+           *  }
+           *  </pre>
+           */
+          colDef.cellEditableCondition = colDef.cellEditableCondition === undefined ? gridOptions.cellEditableCondition :  colDef.cellEditableCondition;
+
+          /**
+           *  @ngdoc object
+           *  @name editableCellTemplate
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @description cell template to be used when editing this column. Can be Url or text template
+           *  <br/>Defaults to gridOptions.editableCellTemplate
+           */
+          if (colDef.enableCellEdit) {
+            colDef.editableCellTemplate = colDef.editableCellTemplate || gridOptions.editableCellTemplate || 'ui-grid/cellEditor';
+
+            promises.push(gridUtil.getTemplate(colDef.editableCellTemplate)
+              .then(
+              function (template) {
+                col.editableCellTemplate = template;
+              },
+              function (res) {
+                // Todo handle response error here?
+                throw new Error("Couldn't fetch/use colDef.editableCellTemplate '" + colDef.editableCellTemplate + "'");
+              }));
+          }
+
+          /**
+           *  @ngdoc object
+           *  @name enableCellEditOnFocus
+           *  @propertyOf  ui.grid.edit.api:ColumnDef
+           *  @requires ui.grid.cellNav
+           *  @description If true, then editor is invoked as soon as cell receives focus. Default false.
+           *  <br>_requires both the cellNav feature and the edit feature to be enabled_
+           */
+            //enableCellEditOnFocus can only be used if cellnav module is used
+          colDef.enableCellEditOnFocus = colDef.enableCellEditOnFocus === undefined ? gridOptions.enableCellEditOnFocus : colDef.enableCellEditOnFocus;
+
+          return $q.all(promises);
+        },
+
+        /**
+         * @ngdoc service
+         * @name isStartEditKey
+         * @methodOf ui.grid.edit.service:uiGridEditService
+         * @description  Determines if a keypress should start editing.  Decorate this service to override with your
+         * own key events.  See service decorator in angular docs.
+         * @param {Event} evt keydown event
+         * @returns {boolean} true if an edit should start
+         */
+        isStartEditKey: function (evt) {
+          if (evt.keyCode === uiGridConstants.keymap.LEFT ||
+            (evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey) ||
+
+            evt.keyCode === uiGridConstants.keymap.RIGHT ||
+            evt.keyCode === uiGridConstants.keymap.TAB ||
+
+            evt.keyCode === uiGridConstants.keymap.UP ||
+            (evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey) ||
+
+            evt.keyCode === uiGridConstants.keymap.DOWN ||
+            evt.keyCode === uiGridConstants.keymap.ENTER) {
+            return false;
+
+          }
+          return true;
+        }
+
+
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEdit
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds editing features to the ui-grid directive.
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name', enableCellEdit: true},
+        {name: 'title', enableCellEdit: true}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-edit></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridEdit', ['gridUtil', 'uiGridEditService', function (gridUtil, uiGridEditService) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            uiGridEditService.initializeGrid(uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+          }
+        };
+      }
+    };
+  }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Stacks on top of ui.grid.uiGridCell to provide in-line editing capabilities to the cell
+   *  Editing Actions.
+   *
+   *  Binds edit start events to the uiGridCell element.  When the events fire, the gridCell element is appended
+   *  with the columnDef.editableCellTemplate element ('cellEditor.html' by default).
+   *
+   *  The editableCellTemplate should respond to uiGridEditConstants.events.BEGIN\_CELL\_EDIT angular event
+   *  and do the initial steps needed to edit the cell (setfocus on input element, etc).
+   *
+   *  When the editableCellTemplate recognizes that the editing is ended (blur event, Enter key, etc.)
+   *  it should emit the uiGridEditConstants.events.END\_CELL\_EDIT event.
+   *
+   *  If editableCellTemplate recognizes that the editing has been cancelled (esc key)
+   *  it should emit the uiGridEditConstants.events.CANCEL\_CELL\_EDIT event.  The original value
+   *  will be set back on the model by the uiGridCell directive.
+   *
+   *  Events that invoke editing:
+   *    - dblclick
+   *    - F2 keydown (when using cell selection)
+   *
+   *  Events that end editing:
+   *    - Dependent on the specific editableCellTemplate
+   *    - Standards should be blur and enter keydown
+   *
+   *  Events that cancel editing:
+   *    - Dependent on the specific editableCellTemplate
+   *    - Standards should be Esc keydown
+   *
+   *  Grid Events that end editing:
+   *    - uiGridConstants.events.GRID_SCROLL
+   *
+   */
+  module.directive('uiGridCell',
+    ['$compile', '$injector', 'uiGridConstants', 'uiGridEditConstants', 'gridUtil', '$parse', 'uiGridEditService',
+      function ($compile, $injector, uiGridConstants, uiGridEditConstants, gridUtil, $parse, uiGridEditService) {
+        return {
+          priority: -100, // run after default uiGridCell directive
+          restrict: 'A',
+          scope: false,
+          require: '?^uiGrid',
+          link: function ($scope, $elm, $attrs, uiGridCtrl) {
+            if (!$scope.col.colDef.enableCellEdit) {
+              return;
+            }
+
+            var html;
+            var origCellValue;
+            var inEdit = false;
+            var isFocusedBeforeEdit = false;
+            var cellModel;
+
+            registerBeginEditEvents();
+
+            function registerBeginEditEvents() {
+              $elm.on('dblclick', beginEdit);
+              $elm.on('keydown', beginEditKeyDown);
+              if ($scope.col.colDef.enableCellEditOnFocus) {
+                $elm.find('div').on('focus', beginEditFocus);
+              }
+            }
+
+            function cancelBeginEditEvents() {
+              $elm.off('dblclick', beginEdit);
+              $elm.off('keydown', beginEditKeyDown);
+              if ($scope.col.colDef.enableCellEditOnFocus) {
+                $elm.find('div').off('focus', beginEditFocus);
+              }
+            }
+
+            function beginEditFocus(evt) {
+              // gridUtil.logDebug('begin edit');
+              if (uiGridCtrl && uiGridCtrl.cellNav) {
+                // NOTE(c0bra): This is causing a loop where focusCell causes beginEditFocus to be called....
+                uiGridCtrl.cellNav.focusCell($scope.row, $scope.col);
+              }
+
+              evt.stopPropagation();
+              beginEdit();
+            }
+
+            // If the cellNagv module is installed and we can get the uiGridCellNavConstants value injected,
+            //   then if the column has enableCellEditOnFocus set to true, we need to listen for cellNav events
+            //   to this cell and start editing when the "focus" reaches us
+            try {
+              var uiGridCellNavConstants = $injector.get('uiGridCellNavConstants');
+
+              if ($scope.col.colDef.enableCellEditOnFocus) {
+                $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function (evt, rowCol) {
+                  if (rowCol.row === $scope.row && rowCol.col === $scope.col) {
+                    beginEdit();
+                  }
+                  else {
+                    endEdit();
+                  }
+                });
+              }
+            }
+            catch (e) {}
+
+            function beginEditKeyDown(evt) {
+              if (uiGridEditService.isStartEditKey(evt)) {
+                beginEdit();
+              }
+            }
+
+            function shouldEdit(col, row) {
+              return !row.isSaving && 
+                ( angular.isFunction(col.colDef.cellEditableCondition) ?
+                    col.colDef.cellEditableCondition($scope) :
+                    col.colDef.cellEditableCondition );
+            }
+
+
+            /**
+             *  @ngdoc property
+             *  @name editDropdownOptionsArray
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description an array of values in the format
+             *  [ {id: xxx, value: xxx} ], which is populated
+             *  into the edit dropdown
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownIdLabel
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description the label for the "id" field
+             *  in the editDropdownOptionsArray.  Defaults
+             *  to 'id'
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownValueLabel
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description the label for the "value" field
+             *  in the editDropdownOptionsArray.  Defaults
+             *  to 'value'
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            /**
+             *  @ngdoc property
+             *  @name editDropdownFilter
+             *  @propertyOf ui.grid.edit.api:ColumnDef
+             *  @description A filter that you would like to apply to the values in the options list
+             *  of the dropdown.  For example if you were using angular-translate you might set this
+             *  to `'translate'`
+             *  @example
+             *  <pre>
+             *    $scope.gridOptions = { 
+             *      columnDefs: [
+             *        {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor', 
+             *          editDropdownOptionsArray: [{code: 1, status: 'active'}, {code: 2, status: 'inactive'}],
+             *          editDropdownIdLabel: 'code', editDropdownValueLabel: 'status', editDropdownFilter: 'translate' }
+             *      ],
+             *  </pre>
+             * 
+             */
+            function beginEdit() {
+              // If we are already editing, then just skip this so we don't try editing twice...
+              if (inEdit) {
+                return;
+              }
+
+              if (!shouldEdit($scope.col, $scope.row)) {
+                return;
+              }
+
+              cellModel = $parse($scope.row.getQualifiedColField($scope.col));
+              //get original value from the cell
+              origCellValue = cellModel($scope);
+
+              html = $scope.col.editableCellTemplate;
+              html = html.replace(uiGridConstants.MODEL_COL_FIELD, $scope.row.getQualifiedColField($scope.col));
+              
+              var optionFilter = $scope.col.colDef.editDropdownFilter ? '|' + $scope.col.colDef.editDropdownFilter : ''; 
+              html = html.replace(uiGridConstants.CUSTOM_FILTERS, optionFilter);
+
+              $scope.inputType = 'text';
+              switch ($scope.col.colDef.type){
+                case 'boolean':
+                  $scope.inputType = 'checkbox';
+                  break;
+                case 'number':
+                  $scope.inputType = 'number';
+                  break;
+                case 'date':
+                  $scope.inputType = 'date';
+                  break;
+              }
+              
+              $scope.editDropdownOptionsArray = $scope.col.colDef.editDropdownOptionsArray;
+              $scope.editDropdownIdLabel = $scope.col.colDef.editDropdownIdLabel ? $scope.col.colDef.editDropdownIdLabel : 'id';  
+              $scope.editDropdownValueLabel = $scope.col.colDef.editDropdownValueLabel ? $scope.col.colDef.editDropdownValueLabel : 'value';  
+
+              var cellElement;
+              $scope.$apply(function () {
+                inEdit = true;
+                cancelBeginEditEvents();
+                var cellElement = angular.element(html);
+                $elm.append(cellElement);
+                $compile(cellElement)($scope.$new());
+                var gridCellContentsEl = angular.element($elm.children()[0]);
+                isFocusedBeforeEdit = gridCellContentsEl.hasClass('ui-grid-cell-focus');
+                gridCellContentsEl.addClass('ui-grid-cell-contents-hidden');
+              });
+
+              //stop editing when grid is scrolled
+              var deregOnGridScroll = $scope.$on(uiGridConstants.events.GRID_SCROLL, function () {
+                endEdit(true);
+                $scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
+                deregOnGridScroll();
+              });
+
+              //end editing
+              var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function (evt, retainFocus) {
+                endEdit(retainFocus);
+                $scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
+                deregOnEndCellEdit();
+              });
+
+              //cancel editing
+              var deregOnCancelCellEdit = $scope.$on(uiGridEditConstants.events.CANCEL_CELL_EDIT, function () {
+                cancelEdit();
+                deregOnCancelCellEdit();
+              });
+
+              $scope.$broadcast(uiGridEditConstants.events.BEGIN_CELL_EDIT);
+              $scope.grid.api.edit.raise.beginCellEdit($scope.row.entity, $scope.col.colDef);
+            }
+
+            function endEdit(retainFocus) {
+              if (!inEdit) {
+                return;
+              }
+              var gridCellContentsEl = angular.element($elm.children()[0]);
+              //remove edit element
+              angular.element($elm.children()[1]).remove();
+              gridCellContentsEl.removeClass('ui-grid-cell-contents-hidden');
+              if (retainFocus && isFocusedBeforeEdit) {
+                gridCellContentsEl[0].focus();
+              }
+              isFocusedBeforeEdit = false;
+              inEdit = false;
+              registerBeginEditEvents();
+              $scope.grid.api.core.notifyDataChange( $scope.grid, uiGridConstants.dataChange.EDIT );
+            }
+
+            function cancelEdit() {
+              if (!inEdit) {
+                return;
+              }
+              cellModel.assign($scope, origCellValue);
+              $scope.$apply();
+
+              $scope.grid.api.edit.raise.cancelCellEdit($scope.row.entity, $scope.col.colDef);
+              endEdit(true);
+            }
+
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEditor
+   *  @element div
+   *  @restrict A
+   *
+   *  @description input editor directive for editable fields.
+   *  Provides EndEdit and CancelEdit events
+   *
+   *  Events that end editing:
+   *     blur and enter keydown
+   *
+   *  Events that cancel editing:
+   *    - Esc keydown
+   *
+   */
+  module.directive('uiGridEditor',
+    ['uiGridConstants', 'uiGridEditConstants',
+      function (uiGridConstants, uiGridEditConstants) {
+        return {
+          scope: true,
+          require: ['?^uiGrid', '?^uiGridRenderContainer'],
+          compile: function () {
+            return {
+              pre: function ($scope, $elm, $attrs) {
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+                var uiGridCtrl, renderContainerCtrl;
+                if (controllers[0]) { uiGridCtrl = controllers[0]; }
+                if (controllers[1]) { renderContainerCtrl = controllers[1]; }
+
+                //set focus at start of edit
+                $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
+                  $elm[0].focus();
+                  $elm[0].select();
+                  $elm.on('blur', function (evt) {
+                    $scope.stopEdit(evt);
+                  });
+                });
+
+               
+               $scope.deepEdit = false;
+               
+               $scope.stopEdit = function (evt) {
+                  if ($scope.inputForm && !$scope.inputForm.$valid) {
+                    evt.stopPropagation();
+                    $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                  }
+                  else {
+                    $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
+                  }
+                  $scope.deepEdit = false;
+                };
+
+                $elm.on('click', function (evt) {
+                  $scope.deepEdit = true;
+                });
+
+                $elm.on('keydown', function (evt) {
+                  switch (evt.keyCode) {
+                    case uiGridConstants.keymap.ESC:
+                      evt.stopPropagation();
+                      $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                      break;
+                    case uiGridConstants.keymap.ENTER: // Enter (Leave Field)
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.TAB:
+                      $scope.stopEdit(evt);
+                      break;
+                  }
+
+                  if ($scope.deepEdit) {
+                    switch (evt.keyCode) {
+                      case uiGridConstants.keymap.LEFT:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.RIGHT:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.UP:
+                        evt.stopPropagation();
+                        break;
+                      case uiGridConstants.keymap.DOWN:
+                        evt.stopPropagation();
+                        break;
+                    }
+                  }
+                  // Pass the keydown event off to the cellNav service, if it exists
+                  else if (uiGridCtrl && uiGridCtrl.hasOwnProperty('cellNav') && renderContainerCtrl) {
+                    evt.uiGridTargetRenderContainerId = renderContainerCtrl.containerId;
+                    uiGridCtrl.cellNav.handleKeyDown(evt);
+                  }
+
+                  return true;
+                });
+              }
+            };
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:input
+   *  @element input
+   *  @restrict E
+   *
+   *  @description directive to provide binding between input[date] value and ng-model for angular 1.2
+   *  It is similar to input[date] directive of angular 1.3
+   *
+   *  Supported date format for input is 'yyyy-MM-dd'
+   *  The directive will set the $valid property of input element and the enclosing form to false if
+   *  model is invalid date or value of input is entered wrong.
+   *
+   */
+    module.directive('input', ['$filter', function ($filter) {
+      function parseDateString(dateString) {
+        if (typeof(dateString) === 'undefined' || dateString === '') {
+          return null;
+        }
+        var parts = dateString.split('-');
+        if (parts.length !== 3) {
+          return null;
+        }
+        var year = parseInt(parts[0], 10);
+        var month = parseInt(parts[1], 10);
+        var day = parseInt(parts[2], 10);
+
+        if (month < 1 || year < 1 || day < 1) {
+          return null;
+        }
+        return new Date(year, (month - 1), day);
+      }
+      return {
+        restrict: 'E',
+        require: '?ngModel',
+        link: function (scope, element, attrs, ngModel) {
+
+          if (angular.version.minor === 2 && attrs.type && attrs.type === 'date' && ngModel) {
+
+            ngModel.$formatters.push(function (modelValue) {
+              ngModel.$setValidity(null,(!modelValue || !isNaN(modelValue.getTime())));
+              return $filter('date')(modelValue, 'yyyy-MM-dd');
+            });
+
+            ngModel.$parsers.push(function (viewValue) {
+              if (viewValue && viewValue.length > 0) {
+                var dateValue = parseDateString(viewValue);
+                ngModel.$setValidity(null, (dateValue && !isNaN(dateValue.getTime())));
+                return dateValue;
+              }
+              else {
+                ngModel.$setValidity(null, true);
+                return null;
+              }
+            });
+          }
+        }
+      };
+    }]);
+    
+    
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.edit.directive:uiGridEditDropdown
+   *  @element div
+   *  @restrict A
+   *
+   *  @description dropdown editor for editable fields.
+   *  Provides EndEdit and CancelEdit events
+   *
+   *  Events that end editing:
+   *     blur and enter keydown, and any left/right nav
+   *
+   *  Events that cancel editing:
+   *    - Esc keydown
+   *
+   */
+  module.directive('uiGridEditDropdown',
+    ['uiGridConstants', 'uiGridEditConstants',
+      function (uiGridConstants, uiGridEditConstants) {
+        return {
+          scope: true,
+          compile: function () {
+            return {
+              pre: function ($scope, $elm, $attrs) {
+
+              },
+              post: function ($scope, $elm, $attrs) {
+
+                //set focus at start of edit
+                $scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
+                  $elm[0].focus();
+                  $elm[0].style.width = ($elm[0].parentElement.offsetWidth - 1) + 'px';
+                  $elm.on('blur', function (evt) {
+                    $scope.stopEdit(evt);
+                  });
+                });
+
+               
+                $scope.stopEdit = function (evt) {
+                  // no need to validate a dropdown - invalid values shouldn't be
+                  // available in the list
+                  $scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
+                };
+
+                $elm.on('keydown', function (evt) {
+                  switch (evt.keyCode) {
+                    case uiGridConstants.keymap.ESC:
+                      evt.stopPropagation();
+                      $scope.$emit(uiGridEditConstants.events.CANCEL_CELL_EDIT);
+                      break;
+                    case uiGridConstants.keymap.ENTER: // Enter (Leave Field)
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.LEFT:
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.RIGHT:
+                      $scope.stopEdit(evt);
+                      break;
+                    case uiGridConstants.keymap.UP:
+                      evt.stopPropagation();
+                      break;
+                    case uiGridConstants.keymap.DOWN:
+                      evt.stopPropagation();
+                      break;
+                    case uiGridConstants.keymap.TAB:
+                      $scope.stopEdit(evt);
+                      break;
+                  }
+                  return true;
+                });
+              }
+            };
+          }
+        };
+      }]);    
+
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.expandable
+   * @description
+   *
+   *  # ui.grid.expandable
+   * This module provides the ability to create subgrids with the ability to expand a row
+   * to show the subgrid.
+   *
+   * <div doc-module-components="ui.grid.expandable"></div>
+   */
+  var module = angular.module('ui.grid.expandable', ['ui.grid']);
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.edit.service:uiGridExpandableService
+   *
+   *  @description Services for the expandable grid
+   */
+  module.service('uiGridExpandableService', ['gridUtil', '$compile', function (gridUtil, $compile) {
+    var service = {
+      initializeGrid: function (grid) {
+        
+        /**
+         *  @ngdoc object
+         *  @name enableExpandable
+         *  @propertyOf  ui.grid.expandable.api:GridOptions
+         *  @description Whether or not to use expandable feature, allows you to turn off expandable on specific grids
+         *  within your application, or in specific modes on _this_ grid. Defaults to true.  
+         *  @example
+         *  <pre>
+         *    $scope.gridOptions = {
+         *      enableExpandable: false
+         *    }
+         *  </pre>  
+         */
+        grid.options.enableExpandable = grid.options.enableExpandable !== false;
+        
+        /**
+         *  @ngdoc object
+         *  @name expandableRowHeight
+         *  @propertyOf  ui.grid.expandable.api:GridOptions
+         *  @description Height in pixels of the expanded subgrid.  Defaults to
+         *  150
+         *  @example
+         *  <pre>
+         *    $scope.gridOptions = {
+         *      expandableRowHeight: 150
+         *    }
+         *  </pre>  
+         */
+        grid.options.expandableRowHeight = grid.options.expandableRowHeight || 150;
+
+        /**
+         *  @ngdoc object
+         *  @name expandableRowTemplate
+         *  @propertyOf  ui.grid.expandable.api:GridOptions
+         *  @description Mandatory. The template for your expanded row
+         *  @example
+         *  <pre>
+         *    $scope.gridOptions = {
+         *      expandableRowTemplate: 'expandableRowTemplate.html'
+         *    }
+         *  </pre>  
+         */
+        if ( grid.options.enableExpandable && !grid.options.expandableRowTemplate ){
+          gridUtil.logError( 'You have not set the expandableRowTemplate, disabling expandable module' );
+          grid.options.enableExpandable = false;
+        }
+
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.expandable.api:PublicApi
+         *
+         *  @description Public Api for expandable feature
+         */
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.expandable.api:GridOptions
+         *
+         *  @description Options for configuring the expandable feature, these are available to be  
+         *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+
+        var publicApi = {
+          events: {
+            expandable: {
+              /**
+               * @ngdoc event
+               * @name rowExpandedStateChanged
+               * @eventOf  ui.grid.expandable.api:PublicApi
+               * @description raised when cell editing is complete
+               * <pre>
+               *      gridApi.expandable.on.rowExpandedStateChanged(scope,function(row){})
+               * </pre>
+               * @param {GridRow} row the row that was expanded
+               */
+              rowExpandedStateChanged: function (scope, row) {
+              }
+            }
+          },
+          
+          methods: {
+            expandable: {
+              /**
+               * @ngdoc method
+               * @name toggleRowExpansion
+               * @methodOf  ui.grid.expandable.api:PublicApi
+               * @description Toggle a specific row
+               * <pre>
+               *      gridApi.expandable.toggleRowExpansion(rowEntity);
+               * </pre>
+               * @param {object} rowEntity the data entity for the row you want to expand
+               */              
+              toggleRowExpansion: function (rowEntity) {
+                var row = grid.getRow(rowEntity);
+                if (row !== null) {
+                  service.toggleRowExpansion(grid, row);
+                }
+              },
+
+              /**
+               * @ngdoc method
+               * @name expandAllRows
+               * @methodOf  ui.grid.expandable.api:PublicApi
+               * @description Expand all subgrids.
+               * <pre>
+               *      gridApi.expandable.expandAllRows();
+               * </pre>
+               */              
+              expandAllRows: function() {
+                service.expandAllRows(grid);
+              },
+
+              /**
+               * @ngdoc method
+               * @name collapseAllRows
+               * @methodOf  ui.grid.expandable.api:PublicApi
+               * @description Collapse all subgrids.
+               * <pre>
+               *      gridApi.expandable.collapseAllRows();
+               * </pre>
+               */              
+              collapseAllRows: function() {
+                service.collapseAllRows(grid);
+              }
+            }
+          }
+        };
+        grid.api.registerEventsFromObject(publicApi.events);
+        grid.api.registerMethodsFromObject(publicApi.methods);
+      },
+      
+      toggleRowExpansion: function (grid, row) {
+        row.isExpanded = !row.isExpanded;
+
+        if (row.isExpanded) {
+          row.height = row.grid.options.rowHeight + grid.options.expandableRowHeight; 
+        }
+        else {
+          row.height = row.grid.options.rowHeight;
+        }
+
+        grid.api.expandable.raise.rowExpandedStateChanged(row);
+      },
+      
+      expandAllRows: function(grid, $scope) {
+        angular.forEach(grid.renderContainers.body.visibleRowCache, function(row) {
+          if (!row.isExpanded) {
+            service.toggleRowExpansion(grid, row);
+          }
+        });
+        grid.refresh();
+      },
+      
+      collapseAllRows: function(grid) {
+        angular.forEach(grid.renderContainers.body.visibleRowCache, function(row) {
+          if (row.isExpanded) {
+            service.toggleRowExpansion(grid, row);
+          }
+        });
+        grid.refresh();
+      }
+    };
+    return service;
+  }]);
+
+  /**
+   *  @ngdoc object
+   *  @name enableExpandableRowHeader
+   *  @propertyOf  ui.grid.expandable.api:GridOptions
+   *  @description Show a rowHeader to provide the expandable buttons.  If set to false then implies
+   *  you're going to use a custom method for expanding and collapsing the subgrids. Defaults to true.
+   *  @example
+   *  <pre>
+   *    $scope.gridOptions = {
+   *      enableExpandableRowHeader: false
+   *    }
+   *  </pre>  
+   */
+  module.directive('uiGridExpandable', ['uiGridExpandableService', '$templateCache',
+    function (uiGridExpandableService, $templateCache) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              if ( uiGridCtrl.grid.options.enableExpandableRowHeader !== false ) {
+                var expandableRowHeaderColDef = {name: 'expandableButtons', width: 40};
+                expandableRowHeaderColDef.cellTemplate = $templateCache.get('ui-grid/expandableRowHeader');
+                uiGridCtrl.grid.addRowHeaderColumn(expandableRowHeaderColDef);
+              }
+              uiGridExpandableService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridExpandableRow',
+  ['uiGridExpandableService', '$timeout', '$compile', 'uiGridConstants','gridUtil','$interval', '$log',
+    function (uiGridExpandableService, $timeout, $compile, uiGridConstants, gridUtil, $interval, $log) {
+
+      return {
+        replace: false,
+        priority: 0,
+        scope: false,
+
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              gridUtil.getTemplate($scope.grid.options.expandableRowTemplate).then(
+                function (template) {
+                  if ($scope.grid.options.expandableRowScope) {
+                    var expandableRowScope = $scope.grid.options.expandableRowScope;
+                    for (var property in expandableRowScope) {
+                      if (expandableRowScope.hasOwnProperty(property)) {
+                        $scope[property] = expandableRowScope[property];
+                      }
+                    }
+                  }
+                  var expandedRowElement = $compile(template)($scope);
+                  $elm.append(expandedRowElement);
+                  $scope.row.expandedRendered = true;
+              });
+            },
+
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+              $scope.$on('$destroy', function() {
+                $scope.row.expandedRendered = false;
+              });
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridRow',
+    ['$compile', 'gridUtil', '$templateCache',
+      function ($compile, gridUtil, $templateCache) {
+        return {
+          priority: -200,
+          scope: false,
+          compile: function ($elm, $attrs) {
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+                $scope.expandableRow = {};
+
+                $scope.expandableRow.shouldRenderExpand = function () {
+                  var ret = $scope.colContainer.name === 'body' &&  $scope.grid.options.enableExpandable !== false && $scope.row.isExpanded && (!$scope.grid.isScrollingVertically || $scope.row.expandedRendered);
+                  return ret;
+                };
+
+                $scope.expandableRow.shouldRenderFiller = function () {
+                  var ret = $scope.row.isExpanded && ( $scope.colContainer.name !== 'body' || ($scope.grid.isScrollingVertically && !$scope.row.expandedRendered));
+                  return ret;
+                };
+
+                  function updateRowContainerWidth() {
+                      var grid = $scope.grid;
+                      var colWidth = 0;
+                      angular.forEach(grid.columns, function (column) {
+                          if (column.renderContainer === 'left') {
+                            colWidth += column.width;
+                          }
+                      });
+                      colWidth = Math.floor(colWidth);
+                      return '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.colContainer.name + ', .grid' + grid.id +
+                          ' .ui-grid-pinned-container-' + $scope.colContainer.name + ' .ui-grid-render-container-' + $scope.colContainer.name +
+                          ' .ui-grid-viewport .ui-grid-canvas .ui-grid-row { width: ' + colWidth + 'px; }';
+                  }
+
+                  if ($scope.colContainer.name === 'left') {
+                      $scope.grid.registerStyleComputation({
+                          priority: 15,
+                          func: updateRowContainerWidth
+                      });
+                  }
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+  module.directive('uiGridViewport',
+    ['$compile', 'gridUtil', '$templateCache',
+      function ($compile, gridUtil, $templateCache) {
+        return {
+          priority: -200,
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+            var expandedRowFillerElement = $templateCache.get('ui-grid/expandableScrollFiller');
+            var expandedRowElement = $templateCache.get('ui-grid/expandableRow');
+            rowRepeatDiv.append(expandedRowElement);
+            rowRepeatDiv.append(expandedRowFillerElement);
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+})();
+
+/* global console */
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.exporter
+   * @description
+   *
+   *  # ui.grid.exporter
+   * This module provides the ability to exporter data from the grid.  
+   * 
+   * Data can be exported in a range of formats, and all data, visible 
+   * data, or selected rows can be exported, with all columns or visible
+   * columns.
+   * 
+   * No UI is provided, the caller should provide their own UI/buttons 
+   * as appropriate, or enable the gridMenu
+   * 
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.exporter"></div>
+   */
+
+  var module = angular.module('ui.grid.exporter', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.exporter.constant:uiGridExporterConstants
+   *
+   *  @description constants available in exporter module
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name ALL
+   * @description export all data, including data not visible.  Can
+   * be set for either rowTypes or colTypes
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name VISIBLE
+   * @description export only visible data, including data not visible.  Can
+   * be set for either rowTypes or colTypes
+   */
+  /**
+   * @ngdoc property
+   * @propertyOf ui.grid.exporter.constant:uiGridExporterConstants
+   * @name SELECTED
+   * @description export all data, including data not visible.  Can
+   * be set only for rowTypes, selection of only some columns is 
+   * not supported
+   */
+  module.constant('uiGridExporterConstants', {
+    featureName: 'exporter',
+    ALL: 'all',
+    VISIBLE: 'visible',
+    SELECTED: 'selected',
+    CSV_CONTENT: 'CSV_CONTENT',
+    LINK_LABEL: 'LINK_LABEL',
+    BUTTON_LABEL: 'BUTTON_LABEL'
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.exporter.service:uiGridExporterService
+   *
+   *  @description Services for exporter feature
+   */
+  module.service('uiGridExporterService', ['$q', 'uiGridExporterConstants', 'uiGridSelectionConstants', 'gridUtil', '$compile', '$interval', 'i18nService',
+    function ($q, uiGridExporterConstants, uiGridSelectionConstants, gridUtil, $compile, $interval, i18nService) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          //add feature namespace and any properties to grid for needed state
+          grid.exporter = {};
+          this.defaultGridOptions(grid.options);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.exporter.api:PublicApi
+           *
+           *  @description Public Api for exporter feature
+           */
+          var publicApi = {
+            events: {
+              exporter: {
+              }
+            },
+            methods: {
+              exporter: {
+                /**
+                 * @ngdoc function
+                 * @name csvExport
+                 * @methodOf  ui.grid.exporter.api:PublicApi
+                 * @description Exports rows from the grid in csv format, 
+                 * the data exported is selected based on the provided options
+                 * @param {string} rowTypes which rows to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+                 * uiGridExporterConstants.SELECTED
+                 * @param {string} colTypes which columns to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE
+                 * @param {element} $elm (Optional) A UI element into which the
+                 * resulting download link will be placed. 
+                 */
+                csvExport: function (rowTypes, colTypes, $elm) {
+                  service.csvExport(grid, rowTypes, colTypes, $elm);
+                },
+                /**
+                 * @ngdoc function
+                 * @name pdfExport
+                 * @methodOf  ui.grid.exporter.api:PublicApi
+                 * @description Exports rows from the grid in pdf format, 
+                 * the data exported is selected based on the provided options
+                 * Note that this function has a dependency on pdfMake, all
+                 * going well this has been installed for you.
+                 * The resulting pdf opens in a new browser window.
+                 * @param {string} rowTypes which rows to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+                 * uiGridExporterConstants.SELECTED
+                 * @param {string} colTypes which columns to export, valid values are
+                 * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE
+                 */
+                pdfExport: function (rowTypes, colTypes) {
+                  service.pdfExport(grid, rowTypes, colTypes);
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+          
+          if (grid.api.core.addToGridMenu){
+            service.addToMenu( grid );
+          } else {
+            // order of registration is not guaranteed, register in a little while
+            $interval( function() {
+              if (grid.api.core.addToGridMenu){
+                service.addToMenu( grid );
+              }              
+            }, 100, 1);
+          }
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+          //default option to true unless it was explicitly set to false
+          /**
+           * @ngdoc object
+           * @name ui.grid.exporter.api:GridOptions
+           *
+           * @description GridOptions for selection feature, these are available to be  
+           * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+          /**
+           * @ngdoc object
+           * @name ui.grid.exporter.api:GridOptions.columnDef
+           * @description ColumnDef settings for exporter
+           */
+          /**
+           * @ngdoc object
+           * @name exporterSuppressMenu
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description Don't show the export menu button, implying the user
+           * will roll their own UI for calling the exporter
+           * <br/>Defaults to false
+           */
+          gridOptions.exporterSuppressMenu = gridOptions.exporterSuppressMenu === true;
+          /**
+           * @ngdoc object
+           * @name exporterLinkTemplate
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A custom template to use for the resulting
+           * link (for csv export)
+           * <br/>Defaults to ui-grid/csvLink
+           */
+          gridOptions.exporterLinkTemplate = gridOptions.exporterLinkTemplate ? gridOptions.exporterLinkTemplate : 'ui-grid/csvLink';
+          /**
+           * @ngdoc object
+           * @name exporterHeaderTemplate
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A custom template to use for the header
+           * section, containing the button and csv download link.  Not
+           * needed if you've set suppressButton and are providing a custom
+           * $elm into which the download link will go.
+           * <br/>Defaults to ui-grid/exporterHeader
+           */
+          gridOptions.exporterHeaderTemplate = gridOptions.exporterHeaderTemplate ? gridOptions.exporterHeaderTemplate : 'ui-grid/exporterHeader';
+          /**
+           * @ngdoc object
+           * @name exporterLinkLabel
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The text to show on the CSV download
+           * link
+           * <br/>Defaults to 'Download CSV'
+           */
+          gridOptions.exporterLinkLabel = gridOptions.exporterLinkLabel ? gridOptions.exporterLinkLabel : 'Download CSV';
+          /**
+           * @ngdoc object
+           * @name exporterMenuLabel
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The text to show on the exporter menu button
+           * link
+           * <br/>Defaults to 'Export'
+           */
+          gridOptions.exporterMenuLabel = gridOptions.exporterMenuLabel ? gridOptions.exporterMenuLabel : 'Export';
+          /**
+           * @ngdoc object
+           * @name exporterSuppressColumns
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description Columns that should not be exported.  The selectionRowHeader is already automatically
+           * suppressed, but if you had a button column or some other "system" column that shouldn't be shown in the
+           * output then add it in this list.  You should provide an array of column names.
+           * <br/>Defaults to: []
+           * <pre>
+           *   gridOptions.exporterSuppressColumns = [ 'buttons' ];
+           * </pre>
+           */
+          gridOptions.exporterSuppressColumns = gridOptions.exporterSuppressColumns ? gridOptions.exporterSuppressColumns : [];
+          /**
+           * @ngdoc object
+           * @name exporterCsvColumnSeparator
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The character to use as column separator
+           * link
+           * <br/>Defaults to ','
+           */
+          gridOptions.exporterCsvColumnSeparator = gridOptions.exporterCsvColumnSeparator ? gridOptions.exporterCsvColumnSeparator : ',';
+          /**
+           * @ngdoc object
+           * @name exporterPdfDefaultStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The default style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     fontSize: 11
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfDefaultStyle = gridOptions.exporterPdfDefaultStyle ? gridOptions.exporterPdfDefaultStyle : { fontSize: 11 };
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The table style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     margin: [0, 5, 0, 15]
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfTableStyle = gridOptions.exporterPdfTableStyle ? gridOptions.exporterPdfTableStyle : { margin: [0, 5, 0, 15] };
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableHeaderStyle
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The tableHeader style in pdfMake format
+           * <br/>Defaults to:
+           * <pre>
+           *   {
+           *     bold: true,
+           *     fontSize: 12,
+           *     color: 'black'
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterPdfTableHeaderStyle = gridOptions.exporterPdfTableHeaderStyle ? gridOptions.exporterPdfTableHeaderStyle : { bold: true, fontSize: 12, color: 'black' };
+          /**
+           * @ngdoc object
+           * @name exporterPdfHeader
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The header section for pdf exports.  Can be
+           * simple text:
+           * <pre>
+           *   gridOptions.exporterPdfHeader = 'My Header';
+           * </pre>
+           * Can be a more complex object in pdfMake format:
+           * <pre>
+           *   gridOptions.exporterPdfHeader = {
+           *     columns: [
+           *       'Left part',
+           *       { text: 'Right part', alignment: 'right' }
+           *     ]
+           *   };
+           * </pre>
+           * Or can be a function, allowing page numbers and the like
+           * <pre>
+           *   gridOptions.exporterPdfHeader: function(currentPage, pageCount) { return currentPage.toString() + ' of ' + pageCount; };
+           * </pre>
+           */
+          gridOptions.exporterPdfHeader = gridOptions.exporterPdfHeader ? gridOptions.exporterPdfHeader : null;
+          /**
+           * @ngdoc object
+           * @name exporterPdfFooter
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The header section for pdf exports.  Can be
+           * simple text:
+           * <pre>
+           *   gridOptions.exporterPdfFooter = 'My Footer';
+           * </pre>
+           * Can be a more complex object in pdfMake format:
+           * <pre>
+           *   gridOptions.exporterPdfFooter = {
+           *     columns: [
+           *       'Left part',
+           *       { text: 'Right part', alignment: 'right' }
+           *     ]
+           *   };
+           * </pre>
+           * Or can be a function, allowing page numbers and the like
+           * <pre>
+           *   gridOptions.exporterPdfFooter: function(currentPage, pageCount) { return currentPage.toString() + ' of ' + pageCount; };
+           * </pre>
+           */
+          gridOptions.exporterPdfFooter = gridOptions.exporterPdfFooter ? gridOptions.exporterPdfFooter : null;
+          /**
+           * @ngdoc object
+           * @name exporterPdfOrientation
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The orientation, should be a valid pdfMake value,
+           * 'landscape' or 'portrait'
+           * <br/>Defaults to landscape
+           */
+          gridOptions.exporterPdfOrientation = gridOptions.exporterPdfOrientation ? gridOptions.exporterPdfOrientation : 'landscape';
+          /**
+           * @ngdoc object
+           * @name exporterPdfPageSize
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The orientation, should be a valid pdfMake
+           * paper size, usually 'A4' or 'LETTER'
+           * {@link https://github.com/bpampuch/pdfmake/blob/master/src/standardPageSizes.js pdfMake page sizes}
+           * <br/>Defaults to A4
+           */
+          gridOptions.exporterPdfPageSize = gridOptions.exporterPdfPageSize ? gridOptions.exporterPdfPageSize : 'A4';
+          /**
+           * @ngdoc object
+           * @name exporterPdfMaxGridWidth
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description The maxium grid width - the current grid width 
+           * will be scaled to match this, with any fixed width columns
+           * being adjusted accordingly.
+           * <br/>Defaults to 720 (for A4 landscape), use 670 for LETTER 
+           */
+          gridOptions.exporterPdfMaxGridWidth = gridOptions.exporterPdfMaxGridWidth ? gridOptions.exporterPdfMaxGridWidth : 720;
+          /**
+           * @ngdoc object
+           * @name exporterPdfTableLayout
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A tableLayout in pdfMake format, 
+           * controls gridlines and the like.  We use the default
+           * layout usually.
+           * <br/>Defaults to null, which means no layout 
+           */
+
+          /**
+           * @ngdoc object
+           * @name exporterMenuCsv
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description Add csv export menu items to the ui-grid grid menu, if it's present.  Defaults to true.
+           */
+          gridOptions.exporterMenuCsv = gridOptions.exporterMenuCsv !== undefined ? gridOptions.exporterMenuCsv : true;
+
+          /**
+           * @ngdoc object
+           * @name exporterMenuPdf
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description Add pdf export menu items to the ui-grid grid menu, if it's present.  Defaults to true.
+           */
+          gridOptions.exporterMenuPdf = gridOptions.exporterMenuPdf !== undefined ? gridOptions.exporterMenuPdf : true;
+          
+          /**
+           * @ngdoc object
+           * @name exporterPdfCustomFormatter
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A custom callback routine that changes the pdf document, adding any
+           * custom styling or content that is supported by pdfMake.  Takes in the complete docDefinition, and
+           * must return an updated docDefinition ready for pdfMake.
+           * @example
+           * In this example we add a style to the style array, so that we can use it in our
+           * footer definition.
+           * <pre>
+           *   gridOptions.exporterPdfCustomFormatter = function ( docDefinition ) {
+           *     docDefinition.styles.footerStyle = { bold: true, fontSize: 10 };
+           *     return docDefinition;
+           *   }
+           * 
+           *   gridOptions.exporterPdfFooter = { text: 'My footer', style: 'footerStyle' }
+           * </pre>
+           */
+          gridOptions.exporterPdfCustomFormatter = ( gridOptions.exporterPdfCustomFormatter && typeof( gridOptions.exporterPdfCustomFormatter ) === 'function' ) ? gridOptions.exporterPdfCustomFormatter : function ( docDef ) { return docDef; };
+          
+          /**
+           * @ngdoc object
+           * @name exporterHeaderFilter
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A function to apply to the header displayNames before exporting.  Useful for internationalisation,
+           * for example if you were using angular-translate you'd set this to `$translate.instant`.  Note that this
+           * call must be synchronous, it cannot be a call that returns a promise.
+           * @example
+           * <pre>
+           *   gridOptions.exporterHeaderFilter = function( displayName ){ return 'col: ' + displayName; };
+           * </pre>
+           * OR
+           * <pre>
+           *   gridOptions.exporterHeaderFilter = $translate.instant;
+           * </pre>
+           */
+
+          /**
+           * @ngdoc function
+           * @name exporterFieldCallback
+           * @propertyOf  ui.grid.exporter.api:GridOptions
+           * @description A function to call for each field before exporting it.  Allows 
+           * massaging of raw data into a display format, for example if you have applied 
+           * filters to convert codes into decodes, or you require
+           * a specific date format in the exported content.
+           * 
+           * The method is called once for each field exported, and provides the grid, the
+           * gridCol and the GridRow for you to use as context in massaging the data.
+           * 
+           * Note that the format of the passed in value is along the lines of:
+           * <pre>
+           *   { value: 'cellValue', alignment: 'left' }
+           * </pre>
+           * 
+           * Your returned value needs to follow that format.
+           * 
+           * @param {Grid} grid provides the grid in case you have need of it
+           * @param {GridRow} row the row from which the data comes
+           * @param {GridCol} col the column from which the data comes
+           * @param {object} value the value for your massaging
+           * @returns {object} you must return the massaged value ready for exporting
+           * 
+           * @example
+           * <pre>
+           *   gridOptions.exporterFieldCallback = function ( grid, row, col, value ){
+           *     if ( col.name === 'status' ){
+           *       value = { value: decodeStatus( value ) };
+           *     }
+           *     return value;
+           *   }
+           * </pre>
+           */
+          gridOptions.exporterFieldCallback = gridOptions.exporterFieldCallback ? gridOptions.exporterFieldCallback : function( grid, row, col, value ) { return value; };
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name addToMenu
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Adds export items to the grid menu,
+         * allowing the user to select export options 
+         * @param {Grid} grid the grid from which data should be exported
+         */
+        addToMenu: function ( grid ) {
+          grid.api.core.addToGridMenu( grid, [
+            {
+              title: i18nService.getSafeText('gridMenu.exporterAllAsCsv'),
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.ALL, uiGridExporterConstants.ALL );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuCsv; 
+              }
+            },
+            {
+              title: i18nService.getSafeText('gridMenu.exporterVisibleAsCsv'),
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.VISIBLE, uiGridExporterConstants.VISIBLE );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuCsv; 
+              }
+            },
+            {
+              title: i18nService.getSafeText('gridMenu.exporterSelectedAsCsv'),
+              action: function ($event) {
+                this.grid.api.exporter.csvExport( uiGridExporterConstants.SELECTED, uiGridExporterConstants.VISIBLE );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuCsv &&
+                       ( this.grid.api.selection && this.grid.api.selection.getSelectedRows().length > 0 ); 
+              }
+            },
+            {
+              title: i18nService.getSafeText('gridMenu.exporterAllAsPdf'),
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.ALL, uiGridExporterConstants.ALL );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuPdf; 
+              }
+            },
+            {
+              title: i18nService.getSafeText('gridMenu.exporterVisibleAsPdf'),
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.VISIBLE, uiGridExporterConstants.VISIBLE );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuPdf; 
+              }
+            },
+            {
+              title: i18nService.getSafeText('gridMenu.exporterSelectedAsPdf'),
+              action: function ($event) {
+                this.grid.api.exporter.pdfExport( uiGridExporterConstants.SELECTED, uiGridExporterConstants.VISIBLE );
+              },
+              shown: function() {
+                return this.grid.options.exporterMenuPdf &&
+                       ( this.grid.api.selection && this.grid.api.selection.getSelectedRows().length > 0 ); 
+              }
+            }
+          ]);
+        },
+        
+
+        /**
+         * @ngdoc object
+         * @name exporterCsvLinkElement
+         * @propertyOf  ui.grid.exporter.api:GridOptions
+         * @description The element that the csv link should be placed into.
+         * Mandatory if using the native UI.
+         */
+        /**
+         * @ngdoc function
+         * @name csvExport
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Exports rows from the grid in csv format, 
+         * the data exported is selected based on the provided options
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {element} $elm (Optional) A UI element into which the
+         * resulting download link will be placed. 
+         */
+        csvExport: function (grid, rowTypes, colTypes, $elm) {
+          var exportColumnHeaders = this.getColumnHeaders(grid, colTypes);
+          var exportData = this.getData(grid, rowTypes, colTypes);
+          var csvContent = this.formatAsCsv(exportColumnHeaders, exportData, grid.options.exporterCsvColumnSeparator);
+          
+          if ( !$elm && grid.options.exporterCsvLinkElement ){
+            $elm = grid.options.exporterCsvLinkElement;
+          }
+          
+          if ( $elm ){
+            this.renderCsvLink(grid, csvContent, $elm);
+          } else {
+            gridUtil.logError( 'Exporter asked to export as csv, but no element provided.  Perhaps you should set gridOptions.exporterCsvLinkElement?')
+;          }
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name getColumnHeaders
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Gets the column headers from the grid to use
+         * as a title row for the exported file, all headers have 
+         * headerCellFilters applied as appropriate.
+         * 
+         * Column headers are an array of objects, each object has
+         * name, displayName, width and align attributes.  Only name is
+         * used for csv, all attributes are used for pdf.
+         * 
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        getColumnHeaders: function (grid, colTypes) {
+          var headers = [];
+          angular.forEach(grid.columns, function( gridCol, index ) {
+            if ( (gridCol.visible || colTypes === uiGridExporterConstants.ALL ) && 
+                 gridCol.name !== uiGridSelectionConstants.selectionRowHeaderColName &&
+                 grid.options.exporterSuppressColumns.indexOf( gridCol.name ) === -1 ){
+              headers.push({
+                name: gridCol.field,
+                displayName: grid.options.exporterHeaderFilter ? grid.options.exporterHeaderFilter(gridCol.displayName) : gridCol.displayName,
+                width: gridCol.drawnWidth ? gridCol.drawnWidth : gridCol.width,
+                align: gridCol.colDef.type === 'number' ? 'right' : 'left'
+              });
+            }
+          });
+          
+          return headers;
+        },
+        
+        
+        /** 
+         * @ngdoc property
+         * @propertyOf ui.grid.exporter.api:GridOptions.columnDef
+         * @name exporterPdfAlign
+         * @description the alignment you'd like for this specific column when
+         * exported into a pdf.  Can be 'left', 'right', 'center' or any other
+         * valid pdfMake alignment option.
+         */
+        /**
+         * @ngdoc function
+         * @name getData
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Gets data from the grid based on the provided options,
+         * all cells have cellFilters applied as appropriate
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        getData: function (grid, rowTypes, colTypes) {
+          var data = [];
+          
+          var rows;
+          
+          switch ( rowTypes ) {
+            case uiGridExporterConstants.ALL:
+              rows = grid.rows; 
+              break;
+            case uiGridExporterConstants.VISIBLE:
+              rows = grid.getVisibleRows();
+              break;
+            case uiGridExporterConstants.SELECTED:
+              if ( grid.api.selection ){
+                rows = grid.api.selection.getSelectedGridRows();
+              } else {
+                gridUtil.logError('selection feature must be enabled to allow selected rows to be exported');
+              }
+              break;
+          }
+          
+          angular.forEach(rows, function( row, index ) {
+
+            var extractedRow = [];
+            angular.forEach(grid.columns, function( gridCol, index ) {
+            if ( (gridCol.visible || colTypes === uiGridExporterConstants.ALL ) && 
+                 gridCol.name !== uiGridSelectionConstants.selectionRowHeaderColName &&
+                 grid.options.exporterSuppressColumns.indexOf( gridCol.name ) === -1 ){
+                var extractedField = { value: grid.options.exporterFieldCallback( grid, row, gridCol, grid.getCellValue( row, gridCol ) ) };
+                if ( gridCol.colDef.exporterPdfAlign ) {
+                  extractedField.alignment = gridCol.colDef.exporterPdfAlign;                 
+                }
+                extractedRow.push(extractedField);
+              }
+            });
+            
+            data.push(extractedRow);
+          });
+          
+          return data;
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name formatAsCSV
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Formats the column headers and data as a CSV, 
+         * and sends that data to the user
+         * @param {array} exportColumnHeaders an array of column headers, 
+         * where each header is an object with name, width and maybe alignment
+         * @param {array} exportData an array of rows, where each row is
+         * an array of column data
+         * @returns {string} csv the formatted csv as a string
+         */
+        formatAsCsv: function (exportColumnHeaders, exportData, separator) {
+          var self = this;
+          
+          var bareHeaders = exportColumnHeaders.map(function(header){return { value: header.displayName };});
+          
+          var csv = self.formatRowAsCsv(this, separator)(bareHeaders) + '\n';
+          
+          csv += exportData.map(this.formatRowAsCsv(this, separator)).join('\n');
+          
+          return csv;
+        },
+
+        /**
+         * @ngdoc function
+         * @name formatRowAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a csv field, including
+         * quotes around the value
+         * @param {exporterService} exporter pass in exporter 
+         * @param {array} row the row to be turned into a csv string
+         * @returns {string} a csv-ified version of the row
+         */
+        formatRowAsCsv: function (exporter, separator) {
+          return function (row) {
+            return row.map(exporter.formatFieldAsCsv).join(separator);
+          };
+        },
+        
+        /**
+         * @ngdoc function
+         * @name formatFieldAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a csv field, including
+         * quotes around the value
+         * @param {field} field the field to be turned into a csv string,
+         * may be of any type
+         * @returns {string} a csv-ified version of the field
+         */
+        formatFieldAsCsv: function (field) {
+          if (field.value == null) { // we want to catch anything null-ish, hence just == not ===
+            return '';
+          }
+          if (typeof(field.value) === 'number') {
+            return field.value;
+          }
+          if (typeof(field.value) === 'boolean') {
+            return (field.value ? 'TRUE' : 'FALSE') ;
+          }
+          if (typeof(field.value) === 'string') {
+            return '"' + field.value.replace(/"/g,'""') + '"';
+          }
+
+          return JSON.stringify(field.value);        
+        },
+
+        /**
+         * @ngdoc function
+         * @name renderCsvLink
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Creates a download link with the csv content, 
+         * putting it into the default exporter element, or into the element
+         * passed in if provided
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} csvContent the csv content that we'd like to 
+         * make available as a download link
+         * @param {element} $elm (Optional) A UI element into which the
+         * resulting download link will be placed.  If not provided, the
+         * link is put into the default exporter element. 
+         */
+        renderCsvLink: function (grid, csvContent, $elm) {
+          var targetElm = $elm ? $elm : angular.element( grid.exporter.gridElm[0].querySelectorAll('.ui-grid-exporter-csv-link') );
+          if ( angular.element( targetElm[0].querySelectorAll('.ui-grid-exporter-csv-link-span')) ) {
+            angular.element( targetElm[0].querySelectorAll('.ui-grid-exporter-csv-link-span')).remove();
+          }
+          
+          var linkTemplate = gridUtil.getTemplate(grid.options.exporterLinkTemplate)
+          .then(function (contents) {
+
+              var template = angular.element(contents);
+
+              template.children("a").html(
+                  template.children("a").html().replace(
+                      uiGridExporterConstants.LINK_LABEL, grid.options.exporterLinkLabel));
+
+              template.children("a").attr("href", 
+                  template.children("a").attr("href").replace(
+                      uiGridExporterConstants.CSV_CONTENT, encodeURIComponent(csvContent)));
+            
+            var newElm = $compile(template)(grid.exporter.$scope);
+            targetElm.append(newElm);
+          });
+          
+        },
+        
+        /**
+         * @ngdoc function
+         * @name pdfExport
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Exports rows from the grid in pdf format, 
+         * the data exported is selected based on the provided options.
+         * Note that this function has a dependency on pdfMake, which must
+         * be installed.  The resulting pdf opens in a new
+         * browser window.
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {string} rowTypes which rows to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         * @param {string} colTypes which columns to export, valid values are
+         * uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE,
+         * uiGridExporterConstants.SELECTED
+         */
+        pdfExport: function (grid, rowTypes, colTypes) {
+          var exportColumnHeaders = this.getColumnHeaders(grid, colTypes);
+          var exportData = this.getData(grid, rowTypes, colTypes);
+          var docDefinition = this.prepareAsPdf(grid, exportColumnHeaders, exportData);
+          
+          pdfMake.createPdf(docDefinition).open();
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name renderAsPdf
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders the data into a pdf, and opens that pdf.
+         * 
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {array} exportColumnHeaders an array of column headers, 
+         * where each header is an object with name, width and maybe alignment
+         * @param {array} exportData an array of rows, where each row is
+         * an array of column data
+         * @returns {object} a pdfMake format document definition, ready 
+         * for generation
+         */        
+        prepareAsPdf: function(grid, exportColumnHeaders, exportData) {
+          var headerWidths = this.calculatePdfHeaderWidths( grid, exportColumnHeaders );
+          
+          var headerColumns = exportColumnHeaders.map( function( header ) {
+            return { text: header.displayName, style: 'tableHeader' }; 
+          });
+          
+          var stringData = exportData.map(this.formatRowAsPdf(this));
+          
+          var allData = [headerColumns].concat(stringData);
+          
+          var docDefinition = {
+            pageOrientation: grid.options.exporterPdfOrientation,
+            pageSize: grid.options.exporterPdfPageSize,
+            content: [{
+              style: 'tableStyle',
+              table: {
+                headerRows: 1,
+                widths: headerWidths,
+                body: allData 
+              }
+            }],
+            styles: {
+              tableStyle: grid.options.exporterPdfTableStyle,
+              tableHeader: grid.options.exporterPdfTableHeaderStyle
+            },
+            defaultStyle: grid.options.exporterPdfDefaultStyle
+          };
+          
+          if ( grid.options.exporterPdfLayout ){
+            docDefinition.layout = grid.options.exporterPdfLayout;
+          }
+          
+          if ( grid.options.exporterPdfHeader ){
+            docDefinition.content.unshift( grid.options.exporterPdfHeader );
+          }
+          
+          if ( grid.options.exporterPdfFooter ){
+            docDefinition.content.push( grid.options.exporterPdfFooter );
+          }
+          
+          if ( grid.options.exporterPdfCustomFormatter ){
+            docDefinition = grid.options.exporterPdfCustomFormatter( docDefinition );
+          }
+          return docDefinition;
+          
+        },
+        
+                
+        /**
+         * @ngdoc function
+         * @name calculatePdfHeaderWidths
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Determines the column widths base on the 
+         * widths we got from the grid.  If the column is drawn
+         * then we have a drawnWidth.  If the column is not visible
+         * then we have '*', 'x%' or a width.  When columns are
+         * not visible they don't contribute to the overall gridWidth,
+         * so we need to adjust to allow for extra columns
+         * 
+         * Our basic heuristic is to take the current gridWidth, plus 
+         * numeric columns and call this the base gridwidth.
+         * 
+         * To that we add 100 for any '*' column, and x% of the base gridWidth
+         * for any column that is a %
+         *  
+         * @param {Grid} grid the grid from which data should be exported
+         * @param {object} exportHeaders array of header information 
+         * @returns {object} an array of header widths
+         */
+        calculatePdfHeaderWidths: function ( grid, exportHeaders ) {
+          var baseGridWidth = 0;
+          angular.forEach(exportHeaders, function(value){
+            if (typeof(value.width) === 'number'){
+              baseGridWidth += value.width;
+            }
+          });
+          
+          var extraColumns = 0;
+          angular.forEach(exportHeaders, function(value){
+            if (value.width === '*'){
+              extraColumns += 100;
+            }
+            if (typeof(value.width) === 'string' && value.width.match(/(\d)*%/)) {
+              var percent = parseInt(value.width.match(/(\d)*%/)[0]);
+              
+              value.width = baseGridWidth * percent / 100;
+              extraColumns += value.width;
+            }
+          });
+          
+          var gridWidth = baseGridWidth + extraColumns;
+          
+          return exportHeaders.map(function( header ) {
+            return header.width === '*' ? header.width : header.width * grid.options.exporterPdfMaxGridWidth / gridWidth;
+          });
+          
+        },
+        
+        /**
+         * @ngdoc function
+         * @name formatRowAsPdf
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a row in a format consumable by PDF,
+         * mainly meaning casting everything to a string
+         * @param {exporterService} exporter pass in exporter 
+         * @param {array} row the row to be turned into a csv string
+         * @returns {string} a csv-ified version of the row
+         */
+        formatRowAsPdf: function ( exporter ) {
+          return function( row ) {
+            return row.map(exporter.formatFieldAsPdfString);
+          };
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name formatFieldAsCsv
+         * @methodOf  ui.grid.exporter.service:uiGridExporterService
+         * @description Renders a single field as a pdf-able field, which
+         * is different from a csv field only in that strings don't have quotes
+         * around them
+         * @param {field} field the field to be turned into a pdf string,
+         * may be of any type
+         * @returns {string} a string-ified version of the field
+         */
+        formatFieldAsPdfString: function (field) {
+          var returnVal;
+          if (field.value == null) { // we want to catch anything null-ish, hence just == not ===
+            returnVal = '';
+          } else if (typeof(field.value) === 'number') {
+            returnVal = field.value.toString();
+          } else if (typeof(field.value) === 'boolean') {
+            returnVal = (field.value ? 'TRUE' : 'FALSE') ;
+          } else if (typeof(field.value) === 'string') {
+            returnVal = field.value.replace(/"/g,'""');
+          } else {
+            returnVal = JSON.stringify(field.value).replace(/^"/,'').replace(/"$/,'');        
+          }
+          
+          if (field.alignment && typeof(field.alignment) === 'string' ){
+            returnVal = { text: returnVal, alignment: field.alignment };
+          }
+          
+          return returnVal;
+        }
+      };
+
+      return service;
+
+    }
+  ]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.exporter.directive:uiGridExporter
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds exporter features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.exporter']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.gridOptions = {
+        enableGridMenu: true,
+        exporterMenuCsv: false,
+        columnDefs: [
+          {name: 'name', enableCellEdit: true},
+          {name: 'title', enableCellEdit: true}
+        ],
+        data: $scope.data
+      };
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="gridOptions" ui-grid-exporter></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridExporter', ['uiGridExporterConstants', 'uiGridExporterService', 'gridUtil', '$compile',
+    function (uiGridExporterConstants, uiGridExporterService, gridUtil, $compile) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        link: function ($scope, $elm, $attrs, uiGridCtrl) {
+          uiGridExporterService.initializeGrid(uiGridCtrl.grid);
+          uiGridCtrl.grid.exporter.$scope = $scope;
+        }
+      };
+    }
+  ]);
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.importer
+   * @description
+   *
+   *  # ui.grid.importer
+   * This module provides the ability to import data into the grid. It
+   * uses the column defs to work out which data belongs in which column, 
+   * and creates entities from a configured class (typically a $resource).
+   * 
+   * If the rowEdit feature is enabled, it also calls save on those newly 
+   * created objects, and then displays any errors in the imported data.  
+   * 
+   * Currently the importer imports only CSV and json files, although provision has been
+   * made to process other file formats, and these can be added over time.  
+   * 
+   * For json files, the properties within each object in the json must match the column names
+   * (to put it another way, the importer doesn't process the json, it just copies the objects
+   * within the json into a new instance of the specified object type)
+   * 
+   * For CSV import, the default column identification relies on each column in the
+   * header row matching a column.name or column.displayName. Optionally, a column identification 
+   * callback can be used.  This allows matching using other attributes, which is particularly
+   * useful if your application has internationalised column headings (i.e. the headings that 
+   * the user sees don't match the column names).
+   * 
+   * The importer makes use of the grid menu as the UI for requesting an
+   * import. 
+   *
+   * <div ui-grid-importer></div>
+   */
+
+  var module = angular.module('ui.grid.importer', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.importer.constant:uiGridImporterConstants
+   *
+   *  @description constants available in importer module
+   */
+
+  module.constant('uiGridImporterConstants', {
+    featureName: 'importer'
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.importer.service:uiGridImporterService
+   *
+   *  @description Services for importer feature
+   */
+  module.service('uiGridImporterService', ['$q', 'uiGridConstants', 'uiGridImporterConstants', 'gridUtil', '$compile', '$interval', 'i18nService', '$window',
+    function ($q, uiGridConstants, uiGridImporterConstants, gridUtil, $compile, $interval, i18nService, $window) {
+
+      var service = {
+
+        initializeGrid: function ($scope, grid) {
+
+          //add feature namespace and any properties to grid for needed state
+          grid.importer = {
+            $scope: $scope 
+          };
+          
+          this.defaultGridOptions(grid.options);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.importer.api:PublicApi
+           *
+           *  @description Public Api for importer feature
+           */
+          var publicApi = {
+            events: {
+              importer: {
+              }
+            },
+            methods: {
+              importer: {
+                /**
+                 * @ngdoc function
+                 * @name importFile
+                 * @methodOf  ui.grid.importer.api:PublicApi
+                 * @description Imports a file into the grid using the file object 
+                 * provided.  Bypasses the grid menu
+                 * @param {Grid} grid the grid we're importing into
+                 * @param {File} fileObject the file we want to import, as a javascript
+                 * File object
+                 */
+                importFile: function ( grid, fileObject ) {
+                  service.importFile( grid, fileObject );
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+          if ( grid.options.enableImporter && grid.options.importerShowMenu ){
+            if ( grid.api.core.addToGridMenu ){
+              service.addToMenu( grid );
+            } else {
+              // order of registration is not guaranteed, register in a little while
+              $interval( function() {
+                if (grid.api.core.addToGridMenu){
+                  service.addToMenu( grid );
+                }             
+              }, 100, 1);
+            }
+          }
+        },
+        
+
+        defaultGridOptions: function (gridOptions) {
+          //default option to true unless it was explicitly set to false
+          /**
+           * @ngdoc object
+           * @name ui.grid.importer.api:GridOptions
+           *
+           * @description GridOptions for importer feature, these are available to be  
+           * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           * @ngdoc property
+           * @propertyOf ui.grid.importer.api:GridOptions
+           * @name enableImporter
+           * @description Whether or not importer is enabled.  Automatically set
+           * to false if the user's browser does not support the required fileApi.
+           * Otherwise defaults to true.
+           * 
+           */
+          if (gridOptions.enableImporter  || gridOptions.enableImporter === undefined) {
+            if ( !($window.hasOwnProperty('File') && $window.hasOwnProperty('FileReader') && $window.hasOwnProperty('FileList') && $window.hasOwnProperty('Blob')) ) {
+              gridUtil.logError('The File APIs are not fully supported in this browser, grid importer cannot be used.');
+              gridOptions.enableImporter = false;
+            } else {
+              gridOptions.enableImporter = true;
+            }
+          } else {
+            gridOptions.enableImporter = false;
+          }
+          
+          /**
+           * @ngdoc method
+           * @name importerProcessHeaders
+           * @methodOf ui.grid.importer.api:GridOptions
+           * @description A callback function that will process headers using custom
+           * logic.  Set this callback function if the headers that your user will provide in their 
+           * import file don't necessarily match the grid header or field names.  This might commonly
+           * occur where your application is internationalised, and therefore the field names
+           * that the user recognises are in a different language than the field names that
+           * ui-grid knows about.
+           * 
+           * Defaults to the internal `processHeaders` method, which seeks to match using both
+           * displayName and column.name.  Any non-matching columns are discarded.
+           * 
+           * Your callback routine should respond by processing the header array, and returning an array
+           * of matching column names.  A null value in any given position means "don't import this column"
+           * 
+           * <pre>
+           *      gridOptions.importerProcessHeaders: function( headerArray ) {
+           *        var myHeaderColumns = [];
+           *        var thisCol;
+           *        headerArray.forEach( function( value, index ) {
+           *          thisCol = mySpecialLookupFunction( value );
+           *          myHeaderColumns.push( thisCol.name ); 
+           *        });
+           *        
+           *        return myHeaderCols;
+           *      })
+           * </pre>
+           * @param {Grid} grid the grid we're importing into
+           * @param {array} headerArray an array of the text from the first row of the csv file,
+           * which you need to match to column.names
+           * @returns {array} array of matching column names, in the same order as the headerArray
+           * 
+           */
+          gridOptions.importerProcessHeaders = gridOptions.importerProcessHeaders || service.processHeaders;
+
+          /**
+           * @ngdoc method
+           * @name importerHeaderFilter
+           * @methodOf ui.grid.importer.api:GridOptions
+           * @description A callback function that will filter (usually translate) a single
+           * header.  Used when you want to match the passed in column names to the column
+           * displayName after the header filter.
+           * 
+           * Your callback routine needs to return the filtered header value. 
+           * <pre>
+           *      gridOptions.importerHeaderFilter: function( displayName ) {
+           *        return $translate.instant( displayName );
+           *      })
+           * </pre>
+           * 
+           * or:
+           * <pre>
+           *      gridOptions.importerHeaderFilter: $translate.instant
+           * </pre>
+           * @param {string} displayName the displayName that we'd like to translate
+           * @returns {string} the translated name
+           * 
+           */
+          gridOptions.importerHeaderFilter = gridOptions.importerHeaderFilter || function( displayName ) { return displayName; };
+
+          /**
+           * @ngdoc method
+           * @name importerErrorCallback
+           * @methodOf ui.grid.importer.api:GridOptions
+           * @description A callback function that provides custom error handling, rather
+           * than the standard grid behaviour of an alert box and a console message.  You 
+           * might use this to internationalise the console log messages, or to write to a 
+           * custom logging routine that returned errors to the server.
+           * 
+           * <pre>
+           *      gridOptions.importerErrorCallback: function( grid, errorKey, consoleMessage, context ) {
+           *        myUserDisplayRoutine( errorKey );
+           *        myLoggingRoutine( consoleMessage, context );
+           *      })
+           * </pre>
+           * @param {Grid} grid the grid we're importing into, may be useful if you're positioning messages
+           * in some way
+           * @param {string} errorKey one of the i18n keys the importer can return - importer.noHeaders, 
+           * importer.noObjects, importer.invalidCsv, importer.invalidJson, importer.jsonNotArray
+           * @param {string} consoleMessage the English console message that importer would have written
+           * @param {object} context the context data that importer would have appended to that console message,
+           * often the file content itself or the element that is in error
+           * 
+           */
+          if ( !gridOptions.importerErrorCallback ||  typeof(gridOptions.importerErrorCallback) !== 'function' ){
+            delete gridOptions.importerErrorCallback;  
+          }
+
+          /**
+           * @ngdoc method
+           * @name importerDataAddCallback
+           * @methodOf ui.grid.importer.api:GridOptions
+           * @description A mandatory callback function that adds data to the source data array.  The grid
+           * generally doesn't add rows to the source data array, it is tidier to handle this through a user
+           * callback.
+           * 
+           * <pre>
+           *      gridOptions.importerDataAddCallback: function( grid, newObjects ) {
+           *        $scope.myData = $scope.myData.concat( newObjects );
+           *      })
+           * </pre>
+           * @param {Grid} grid the grid we're importing into, may be useful in some way
+           * @param {array} newObjects an array of new objects that you should add to your data
+           * 
+           */
+          if ( gridOptions.enableImporter === true && !gridOptions.importerDataAddCallback ) {
+            gridUtil.logError("You have not set an importerDataAddCallback, importer is disabled");
+            gridOptions.enableImporter = false;
+          }
+                    
+          /**
+           * @ngdoc object
+           * @name importerNewObject
+           * @propertyOf  ui.grid.importer.api:GridOptions
+           * @description An object on which we call `new` to create each new row before inserting it into
+           * the data array.  Typically this would be a $resource entity, which means that if you're using 
+           * the rowEdit feature, you can directly call save on this entity when the save event is triggered.
+           * 
+           * Defaults to a vanilla javascript object
+           * 
+           * @example
+           * <pre>
+           *   gridOptions.importerNewObject = MyRes;
+           * </pre>
+           * 
+           */
+
+          /**
+           * @ngdoc property
+           * @propertyOf ui.grid.importer.api:GridOptions
+           * @name importerShowMenu
+           * @description Whether or not to show an item in the grid menu.  Defaults to true.
+           * 
+           */
+          gridOptions.importerShowMenu = gridOptions.importerShowMenu !== false;
+          
+          /**
+           * @ngdoc method
+           * @methodOf ui.grid.importer.api:GridOptions
+           * @name importerObjectCallback
+           * @description A callback that massages the data for each object.  For example,
+           * you might have data stored as a code value, but display the decode.  This callback
+           * can be used to change the decoded value back into a code.  Defaults to doing nothing.
+           * @param {Grid} grid in case you need it
+           * @param {object} newObject the new object as importer has created it, modify it
+           * then return the modified version
+           * @returns {object} the modified object
+           * @example
+           * <pre>
+           *   gridOptions.importerObjectCallback = function ( grid, newObject ) {
+           *     switch newObject.status {
+           *       case 'Active':
+           *         newObject.status = 1;
+           *         break;
+           *       case 'Inactive':
+           *         newObject.status = 2;
+           *         break;
+           *     }
+           *     return newObject;
+           *   };
+           * </pre>
+           */
+          gridOptions.importerObjectCallback = gridOptions.importerObjectCallback || function( grid, newObject ) { return newObject; };
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name addToMenu
+         * @methodOf  ui.grid.importer.service:uiGridImporterService
+         * @description Adds import menu item to the grid menu,
+         * allowing the user to request import of a file 
+         * @param {Grid} grid the grid into which data should be imported
+         */
+        addToMenu: function ( grid ) {
+          grid.api.core.addToGridMenu( grid, [
+            {
+              title: i18nService.getSafeText('gridMenu.importerTitle')
+            },
+            {
+              templateUrl: 'ui-grid/importerMenuItemContainer',
+              action: function ($event) {
+                this.grid.api.importer.importAFile( grid );
+              }
+            }
+          ]);
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name importThisFile
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Imports the provided file into the grid using the file object 
+         * provided.  Bypasses the grid menu
+         * @param {Grid} grid the grid we're importing into
+         * @param {File} fileObject the file we want to import, as returned from the File
+         * javascript object
+         */
+        importThisFile: function ( grid, fileObject ) {
+          if (!fileObject){
+            gridUtil.logError( 'No file object provided to importThisFile, should be impossible, aborting');
+            return;
+          }
+          
+          var reader = new FileReader();
+          
+          switch ( fileObject.type ){
+            case 'application/json':
+              reader.onload = service.importJsonClosure( grid );
+              break;
+            default:
+              reader.onload = service.importCsvClosure( grid );
+              break;
+          }
+          
+          reader.readAsText( fileObject );
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name importJson
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Creates a function that imports a json file into the grid.
+         * The json data is imported into new objects of type `gridOptions.importerNewObject`,
+         * and ift he rowEdit feature is enabled the rows are marked as dirty
+         * @param {Grid} grid the grid we want to import into
+         * @param {FileObject} importFile the file that we want to import, as 
+         * a FileObject
+         */
+        importJsonClosure: function( grid ) {
+          return function( importFile ){
+            var newObjects = [];
+            var newObject;
+            
+            angular.forEach( service.parseJson( grid, importFile ), function( value, index ) {
+              newObject = service.newObject( grid );
+              angular.extend( newObject, value );
+              newObject = grid.options.importerObjectCallback( grid, newObject );
+              newObjects.push( newObject );
+            });
+            
+            service.addObjects( grid, newObjects );
+            
+          };
+        },
+
+
+        /**
+         * @ngdoc function
+         * @name parseJson
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Parses a json file, returns the parsed data.
+         * Displays an error if file doesn't parse
+         * @param {Grid} grid the grid that we want to import into 
+         * @param {FileObject} importFile the file that we want to import, as 
+         * a FileObject
+         * @returns {array} array of objects from the imported json
+         */
+        parseJson: function( grid, importFile ){
+          var loadedObjects;
+          try {
+            loadedObjects = JSON.parse( importFile.target.result );
+          } catch (e) {
+            service.alertError( grid, 'importer.invalidJson', 'File could not be processed, is it valid json? Content was: ', importFile.target.result );
+            return;
+          }
+          
+          if ( !Array.isArray( loadedObjects ) ){
+            service.alertError( grid, 'importer.jsonNotarray', 'Import failed, file is not an array, file was: ', importFile.target.result );
+            return [];
+          } else {
+            return loadedObjects;
+          }
+        },
+        
+        
+        
+        /**
+         * @ngdoc function
+         * @name importCsvClosure
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Creates a function that imports a csv file into the grid
+         * (allowing it to be used in the reader.onload event)
+         * @param {Grid} grid the grid that we want to import into 
+         * @param {FileObject} importFile the file that we want to import, as 
+         * a file object
+         */
+        importCsvClosure: function( grid ) {
+          return function( importFile ){
+            var importArray = service.parseCsv( importFile );
+            if ( !importArray || importArray.length < 1 ){ 
+              service.alertError( grid, 'importer.invalidCsv', 'File could not be processed, is it valid csv? Content was: ', importFile.target.result );
+              return; 
+            }
+            
+            var newObjects = service.createCsvObjects( grid, importArray );
+            if ( !newObjects || newObjects.length === 0 ){
+              service.alertError( grid, 'importer.noObjects', 'Objects were not able to be derived, content was: ', importFile.target.result );
+              return;
+            }
+            
+            service.addObjects( grid, newObjects );
+          };
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name parseCsv
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Parses a csv file into an array of arrays, with the first
+         * array being the headers, and the remaining arrays being the data.
+         * The logic for this comes from https://github.com/thetalecrafter/excel.js/blob/master/src/csv.js, 
+         * which is noted as being under the MIT license.  The code is modified to pass the jscs yoda condition
+         * checker
+         * @param {FileObject} importFile the file that we want to import, as a 
+         * file object
+         */
+        parseCsv: function( importFile ) {
+          var csv = importFile.target.result;
+          
+          // use the CSV-JS library to parse
+          return CSV.parse(csv);
+        },
+        
+
+        /**
+         * @ngdoc function
+         * @name createCsvObjects
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Converts an array of arrays (representing the csv file)
+         * into a set of objects.  Uses the provided `gridOptions.importerNewObject`
+         * to create the objects, and maps the header row into the individual columns 
+         * using either `gridOptions.importerProcessHeaders`, or by using a native method
+         * of matching to either the displayName, column name or column field of
+         * the columns in the column defs.  The resulting objects will have attributes
+         * that are named based on the column.field or column.name, in that order.
+         * @param {Grid} grid the grid that we want to import into 
+         * @param {FileObject} importFile the file that we want to import, as a 
+         * file object
+         */
+        createCsvObjects: function( grid, importArray ){
+          // pull off header row and turn into headers
+          var headerMapping = grid.options.importerProcessHeaders( grid, importArray.shift() );
+          if ( !headerMapping || headerMapping.length === 0 ){
+            service.alertError( grid, 'importer.noHeaders', 'Column names could not be derived, content was: ', importArray );
+            return [];
+          }
+          
+          var newObjects = [];
+          var newObject;
+          angular.forEach( importArray, function( row, index ) {
+            newObject = service.newObject( grid );
+            angular.forEach( row, function( field, index ){
+              if ( headerMapping[index] !== null ){
+                newObject[ headerMapping[index] ] = field;
+              }
+            });
+            newObject = grid.options.importerObjectCallback( grid, newObject );
+            newObjects.push( newObject );
+          });
+          
+          return newObjects;
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name processHeaders
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Determines the columns that the header row from
+         * a csv (or other) file represents.
+         * @param {Grid} grid the grid we're importing into
+         * @param {array} headerRow the header row that we wish to match against
+         * the column definitions
+         * @returns {array} an array of the attribute names that should be used
+         * for that column, based on matching the headers or creating the headers
+         * 
+         */
+        processHeaders: function( grid, headerRow ) {
+          var headers = [];
+          if ( !grid.options.columnDefs || grid.options.columnDefs.length === 0 ){
+            // we are going to create new columnDefs for all these columns, so just remove
+            // spaces from the names to create fields
+            angular.forEach( headerRow, function( value, index ) {
+              headers.push( value.replace( /[^0-9a-zA-Z\-_]/g, '_' ) );
+            });
+            return headers;
+          } else {
+            var lookupHash = service.flattenColumnDefs( grid, grid.options.columnDefs );
+            angular.forEach( headerRow, function( value, index ) {
+              if ( lookupHash[value] ) {
+                headers.push( lookupHash[value] );
+              } else if ( lookupHash[ value.toLowerCase() ] ) {
+                headers.push( lookupHash[ value.toLowerCase() ] );
+              } else {
+                headers.push( null );
+              }
+            });
+            return headers;
+          }
+        },
+        
+        
+        /**
+         * @name flattenColumnDefs
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Runs through the column defs and creates a hash of
+         * the displayName, name and field, and of each of those values forced to lower case,
+         * with each pointing to the field or name
+         * (whichever is present).  Used to lookup column headers and decide what 
+         * attribute name to give to the resulting field. 
+         * @param {Grid} grid the grid we're importing into
+         * @param {array} columnDefs the columnDefs that we should flatten
+         * @returns {hash} the flattened version of the column def information, allowing
+         * us to look up a value by `flattenedHash[ headerValue ]`
+         */
+        flattenColumnDefs: function( grid, columnDefs ){
+          var flattenedHash = {};
+          angular.forEach( columnDefs, function( columnDef, index) {
+            if ( columnDef.name ){
+              flattenedHash[ columnDef.name ] = columnDef.field || columnDef.name;
+              flattenedHash[ columnDef.name.toLowerCase() ] = columnDef.field || columnDef.name;
+            }
+            
+            if ( columnDef.field ){
+              flattenedHash[ columnDef.field ] = columnDef.field || columnDef.name;
+              flattenedHash[ columnDef.field.toLowerCase() ] = columnDef.field || columnDef.name;
+            }
+            
+            if ( columnDef.displayName ){
+              flattenedHash[ columnDef.displayName ] = columnDef.field || columnDef.name;
+              flattenedHash[ columnDef.displayName.toLowerCase() ] = columnDef.field || columnDef.name;
+            }
+            
+            if ( columnDef.displayName && grid.options.importerHeaderFilter ){
+              flattenedHash[ grid.options.importerHeaderFilter(columnDef.displayName) ] = columnDef.field || columnDef.name;
+              flattenedHash[ grid.options.importerHeaderFilter(columnDef.displayName).toLowerCase() ] = columnDef.field || columnDef.name;
+            }
+          });
+          
+          return flattenedHash;
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name addObjects
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Inserts our new objects into the grid data, and
+         * sets the rows to dirty if the rowEdit feature is being used
+         * 
+         * Does this by registering a watch on dataChanges, which essentially
+         * is waiting on the result of the grid data watch, and downstream processing.
+         * 
+         * When the callback is called, it deregisters itself - we don't want to run
+         * again next time data is added.
+         * 
+         * If we never get called, we deregister on destroy.
+         * 
+         * @param {Grid} grid the grid we're importing into
+         * @param {array} newObjects the objects we want to insert into the grid data
+         * @returns {object} the new object
+         */
+        addObjects: function( grid, newObjects, $scope ){
+          if ( grid.api.rowEdit ){
+            var callbackId = grid.registerDataChangeCallback( function() {
+              grid.api.rowEdit.setRowsDirty( grid, newObjects );
+              grid.deregisterDataChangeCallback( callbackId );
+            }, [uiGridConstants.dataChange.ROW] );
+            
+            var deregisterClosure = function() {
+              grid.deregisterDataChangeCallback( callbackId );
+            };
+  
+            grid.importer.$scope.$on( '$destroy', deregisterClosure );
+          }
+
+          grid.importer.$scope.$apply( grid.options.importerDataAddCallback( grid, newObjects ) );
+          
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name newObject
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Makes a new object based on `gridOptions.importerNewObject`,
+         * or based on an empty object if not present
+         * @param {Grid} grid the grid we're importing into
+         * @returns {object} the new object
+         */
+        newObject: function( grid ){
+          if ( typeof(grid.options) !== "undefined" && typeof(grid.options.importerNewObject) !== "undefined" ){
+            return new grid.options.importerNewObject();
+          } else {
+            return {};
+          }
+        },
+        
+        
+        /**
+         * @ngdoc function
+         * @name alertError
+         * @methodOf ui.grid.importer.service:uiGridImporterService
+         * @description Provides an internationalised user alert for the failure,
+         * and logs a console message including diagnostic content.
+         * Optionally, if the the `gridOptions.importerErrorCallback` routine
+         * is defined, then calls that instead, allowing user specified error routines
+         * @param {Grid} grid the grid we're importing into
+         * @param {array} headerRow the header row that we wish to match against
+         * the column definitions
+         */
+        alertError: function( grid, alertI18nToken, consoleMessage, context ){
+          if ( grid.options.importerErrorCallback ){
+            grid.options.importerErrorCallback( grid, alertI18nToken, consoleMessage, context );
+          } else {
+            $window.alert(i18nService.getSafeText( alertI18nToken )); 
+            gridUtil.logError(consoleMessage + context ); 
+          }
+        }
+      };
+
+      return service;
+
+    }
+  ]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.importer.directive:uiGridImporter
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds importer features to grid
+   *
+   */
+  module.directive('uiGridImporter', ['uiGridImporterConstants', 'uiGridImporterService', 'gridUtil', '$compile',
+    function (uiGridImporterConstants, uiGridImporterService, gridUtil, $compile) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        link: function ($scope, $elm, $attrs, uiGridCtrl) {
+          uiGridImporterService.initializeGrid($scope, uiGridCtrl.grid);
+        }
+      };
+    }
+  ]);
+  
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.importer.directive:uiGridImporterMenuItem
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Handles the processing from the importer menu item - once a file is
+   *  selected
+   *
+   */
+  module.directive('uiGridImporterMenuItem', ['uiGridImporterConstants', 'uiGridImporterService', 'gridUtil', '$compile',
+    function (uiGridImporterConstants, uiGridImporterService, gridUtil, $compile) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        templateUrl: 'ui-grid/importerMenuItem',
+        link: function ($scope, $elm, $attrs, uiGridCtrl) {
+          var handleFileSelect = function( event ){
+            if (event.srcElement.files.length === 1) {
+              var fileObject = event.srcElement.files[0];
+              uiGridImporterService.importThisFile( grid, fileObject );
+              event.srcElement.form.reset();
+            }
+          };
+
+          var fileChooser = $elm[0].querySelectorAll('.ui-grid-importer-file-chooser');
+          var grid = uiGridCtrl.grid;
+          
+          if ( fileChooser.length !== 1 ){
+            gridUtil.logError('Found > 1 or < 1 file choosers within the menu item, error, cannot continue');
+          } else {
+            fileChooser[0].addEventListener('change', handleFileSelect, false);  // TODO: why the false on the end?  Google  
+          }
+        }
+      };
+    }
+  ]);  
+})();
+(function() {
+  'use strict';
+  /**
+   *  @ngdoc overview
+   *  @name ui.grid.infiniteScroll
+   *
+   *  @description
+   *
+   *   #ui.grid.infiniteScroll
+   * This module provides infinite scroll functionality to ui-grid
+   *
+   */
+  var module = angular.module('ui.grid.infiniteScroll', ['ui.grid']);
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+   *
+   *  @description Service for infinite scroll features
+   */
+  module.service('uiGridInfiniteScrollService', ['gridUtil', '$compile', '$timeout', function (gridUtil, $compile, $timeout) {
+
+    var service = {
+
+      /**
+       * @ngdoc function
+       * @name initializeGrid
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This method register events and methods into grid public API
+       */
+
+      initializeGrid: function(grid) {
+        service.defaultGridOptions(grid.options);
+
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.infiniteScroll.api:PublicAPI
+         *
+         *  @description Public API for infinite scroll feature
+         */
+        var publicApi = {
+          events: {
+            infiniteScroll: {
+
+              /**
+               * @ngdoc event
+               * @name needLoadMoreData
+               * @eventOf ui.grid.infiniteScroll.api:PublicAPI
+               * @description This event fires when scroll reached bottom percentage of grid
+               * and needs to load data
+               */
+
+              needLoadMoreData: function ($scope, fn) {
+              }
+            }
+          },
+          methods: {
+            infiniteScroll: {
+
+              /**
+               * @ngdoc function
+               * @name dataLoaded
+               * @methodOf ui.grid.infiniteScroll.api:PublicAPI
+               * @description This function is used as a promise when data finished loading.
+               * See infinite_scroll ngdoc for example of usage
+               */
+
+              dataLoaded: function() {
+                grid.options.loadTimout = false;
+              }
+            }
+          }
+        };
+        grid.options.loadTimout = false;
+        grid.api.registerEventsFromObject(publicApi.events);
+        grid.api.registerMethodsFromObject(publicApi.methods);
+      },
+      defaultGridOptions: function (gridOptions) {
+        //default option to true unless it was explicitly set to false
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.infiniteScroll.api:GridOptions
+         *
+         *  @description GridOptions for infinite scroll feature, these are available to be
+         *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enableInfiniteScroll
+         *  @propertyOf  ui.grid.infiniteScroll.api:GridOptions
+         *  @description Enable infinite scrolling for this grid
+         *  <br/>Defaults to true
+         */
+        gridOptions.enableInfiniteScroll = gridOptions.enableInfiniteScroll !== false;
+      },
+
+
+      /**
+       * @ngdoc function
+       * @name loadData
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This function fires 'needLoadMoreData' event
+       */
+
+      loadData: function (grid) {
+               grid.options.loadTimout = true;
+        grid.api.infiniteScroll.raise.needLoadMoreData();        
+      },
+
+      /**
+       * @ngdoc function
+       * @name checkScroll
+       * @methodOf ui.grid.infiniteScroll.service:uiGridInfiniteScrollService
+       * @description This function checks scroll position inside grid and
+       * calls 'loadData' function when scroll reaches 'infiniteScrollPercentage'
+       */
+
+      checkScroll: function(grid, scrollTop) {
+
+        /* Take infiniteScrollPercentage value or use 20% as default */
+        var infiniteScrollPercentage = grid.options.infiniteScrollPercentage ? grid.options.infiniteScrollPercentage : 20;
+
+        if (!grid.options.loadTimout && scrollTop <= infiniteScrollPercentage) {
+          this.loadData(grid);
+          return true;
+        }
+        return false;
+      }
+      /**
+       * @ngdoc property
+       * @name infiniteScrollPercentage
+       * @propertyOf ui.grid.class:GridOptions
+       * @description This setting controls at what percentage of the scroll more data
+       * is requested by the infinite scroll
+       */
+    };
+    return service;
+  }]);
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.infiniteScroll.directive:uiGridInfiniteScroll
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds infinite scroll features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.infiniteScroll']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Alex', car: 'Toyota' },
+            { name: 'Sam', car: 'Lexus' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name'},
+        {name: 'car'}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-infinite-scroll="20"></div>
+   </div>
+   </file>
+   </example>
+   */
+
+  module.directive('uiGridInfiniteScroll', ['uiGridInfiniteScrollService',
+    function (uiGridInfiniteScrollService) {
+      return {
+        priority: -200,
+        scope: false,
+        require: '^uiGrid',
+        compile: function($scope, $elm, $attr){
+          return {
+            pre: function($scope, $elm, $attr, uiGridCtrl) {
+              uiGridInfiniteScrollService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function($scope, $elm, $attr) {
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridViewport',
+    ['$compile', 'gridUtil', 'uiGridInfiniteScrollService', 'uiGridConstants',
+      function ($compile, gridUtil, uiGridInfiniteScrollService, uiGridConstants) {
+        return {
+          priority: -200,
+          scope: false,
+          link: function ($scope, $elm, $attr){
+            if ($scope.grid.options.enableInfiniteScroll) {
+              $scope.$on(uiGridConstants.events.GRID_SCROLL, function (evt, args) {
+                if (args.y) {
+                  var percentage = 100 - (args.y.percentage * 100);
+                  uiGridInfiniteScrollService.checkScroll($scope.grid, percentage);
+                }
+              });
+            }
+          }
+        };
+      }]);
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.moveColumns
+   * @description
+   * # ui.grid.moveColumns
+   * This module provides column moving capability to ui.grid. It enables to change the position of columns.
+   * <div doc-module-components="ui.grid.moveColumns"></div>
+   */
+  var module = angular.module('ui.grid.moveColumns', ['ui.grid']);
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.moveColumns.service:uiGridMoveColumnService
+   *  @description Service for column moving feature.
+   */
+  module.service('uiGridMoveColumnService', ['$q', '$timeout', '$log', function ($q, $timeout, $log) {
+
+    var service = {
+      initializeGrid: function (grid) {
+        var self = this;
+        this.registerPublicApi(grid);
+        this.defaultGridOptions(grid.options);
+        grid.registerColumnBuilder(self.movableColumnBuilder);
+      },
+      registerPublicApi: function (grid) {
+        var self = this;
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.moveColumns.api:PublicApi
+         *  @description Public Api for column moving feature.
+         */
+        var publicApi = {
+          events: {
+            /**
+             * @ngdoc event
+             * @name columnPositionChanged
+             * @eventOf  ui.grid.moveColumns.api:PublicApi
+             * @description raised when column is moved
+             * <pre>
+             *      gridApi.colMovable.on.columnPositionChanged(scope,function(colDef, originalPosition, newPosition){})
+             * </pre>
+             * @param {object} colDef the column that was moved
+             * @param {integer} originalPosition of the column
+             * @param {integer} finalPosition of the column
+             */
+            colMovable: {
+              columnPositionChanged: function (colDef, originalPosition, newPosition) {
+              }
+            }
+          },
+          methods: {
+            /**
+             * @ngdoc method
+             * @name moveColumn
+             * @methodOf  ui.grid.moveColumns.api:PublicApi
+             * @description Method can be used to change column position.
+             * <pre>
+             *      gridApi.colMovable.on.moveColumn(oldPosition, newPosition)
+             * </pre>
+             * @param {integer} originalPosition of the column
+             * @param {integer} finalPosition of the column
+             */
+            colMovable: {
+              moveColumn: function (originalPosition, finalPosition) {
+                self.redrawColumnAtPosition(grid, originalPosition, finalPosition);
+              }
+            }
+          }
+        };
+        grid.api.registerEventsFromObject(publicApi.events);
+        grid.api.registerMethodsFromObject(publicApi.methods);
+      },
+      defaultGridOptions: function (gridOptions) {
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.moveColumns.api:GridOptions
+         *
+         *  @description Options for configuring the move column feature, these are available to be
+         *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+        /**
+         *  @ngdoc object
+         *  @name enableColumnMoving
+         *  @propertyOf  ui.grid.moveColumns.api:GridOptions
+         *  @description If defined, sets the default value for the colMovable flag on each individual colDefs
+         *  if their individual enableColumnMoving configuration is not defined. Defaults to true.
+         */
+        gridOptions.enableColumnMoving = gridOptions.enableColumnMoving !== false;
+      },
+      movableColumnBuilder: function (colDef, col, gridOptions) {
+        var promises = [];
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.moveColumns.api:ColumnDef
+         *
+         *  @description Column Definition for move column feature, these are available to be
+         *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+         */
+        /**
+         *  @ngdoc object
+         *  @name enableColumnMoving
+         *  @propertyOf  ui.grid.moveColumns.api:ColumnDef
+         *  @description Enable column moving for the column.
+         */
+        colDef.enableColumnMoving = colDef.enableColumnMoving === undefined ? gridOptions.enableColumnMoving
+          : colDef.enableColumnMoving;
+        return $q.all(promises);
+      },
+      redrawColumnAtPosition: function (grid, originalPosition, newPosition) {
+        var columns = grid.columns;
+
+        //Function to find column position for a render index, ths is needed to take care of
+        // invisible columns and row headers
+        var findPositionForRenderIndex = function (index) {
+          var position = index;
+          for (var i = 0; i <= position; i++) {
+            if ((angular.isDefined(columns[i].colDef.visible) && columns[i].colDef.visible === false)) {
+              position++;
+            }
+          }
+          return position;
+        };
+
+        originalPosition = findPositionForRenderIndex(originalPosition);
+        newPosition = findPositionForRenderIndex(newPosition);
+        var originalColumn = columns[originalPosition];
+        if (originalColumn.colDef.enableColumnMoving) {
+          if (originalPosition > newPosition) {
+            for (var i1 = originalPosition; i1 > newPosition; i1--) {
+              columns[i1] = columns[i1 - 1];
+            }
+          }
+          else if (newPosition > originalPosition) {
+            for (var i2 = originalPosition; i2 < newPosition; i2++) {
+              columns[i2] = columns[i2 + 1];
+            }
+          }
+          columns[newPosition] = originalColumn;
+          $timeout(function () {
+            grid.refresh();
+            grid.api.colMovable.raise.columnPositionChanged(originalColumn.colDef, originalPosition, newPosition);
+          });
+        }
+      }
+    };
+    return service;
+  }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.moveColumns.directive:uiGridMoveColumns
+   *  @element div
+   *  @restrict A
+   *  @description Adds column moving features to the ui-grid directive.
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.moveColumns']);
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+        $scope.data = [
+          { name: 'Bob', title: 'CEO', age: 45 },
+          { name: 'Frank', title: 'Lowly Developer', age: 25 },
+          { name: 'Jenny', title: 'Highly Developer', age: 35 }
+        ];
+        $scope.columnDefs = [
+          {name: 'name'},
+          {name: 'title'},
+          {name: 'age'}
+        ];
+      }]);
+   </file>
+   <file name="main.css">
+   .grid {
+      width: 100%;
+      height: 150px;
+    }
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div class="grid" ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-move-columns></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridMoveColumns', ['uiGridMoveColumnService', function (uiGridMoveColumnService) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            uiGridMoveColumnService.initializeGrid(uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+          }
+        };
+      }
+    };
+  }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.moveColumns.directive:uiGridHeaderCell
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Stacks on top of ui.grid.uiGridHeaderCell to provide capability to be able to move it to reposition column.
+   *
+   *  On receiving mouseDown event headerCell is cloned, now as the mouse moves the cloned header cell also moved in the grid.
+   *  In case the moving cloned header cell reaches the left or right extreme of grid, grid scrolling is triggered (if horizontal scroll exists).
+   *  On mouseUp event column is repositioned at position where mouse is released and coned header cell is removed.
+   *
+   *  Events that invoke cloning of header cell:
+   *    - mousedown
+   *
+   *  Events that invoke movement of cloned header cell:
+   *    - mousemove
+   *
+   *  Events that invoke repositioning of column:
+   *    - mouseup
+   */
+  module.directive('uiGridHeaderCell', ['$q', 'gridUtil', 'uiGridMoveColumnService', '$document',
+    function ($q, gridUtil, uiGridMoveColumnService, $document) {
+      return {
+        priority: -10,
+        require: '^uiGrid',
+        compile: function () {
+          return {
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+              if ($scope.col.colDef.enableColumnMoving) {
+
+                var mouseDownHandler = function (evt) {
+                  if (evt.target.className !== 'ui-grid-icon-angle-down' && evt.target.tagName !== 'I') {
+
+                    //Cloning header cell and appending to current header cell.
+                    var movingElm = $elm.clone();
+                    $elm.append(movingElm);
+
+                    //Left of cloned element should be aligned to original header cell.
+                    movingElm.addClass('movingColumn');
+                    var movingElementStyles = {};
+                    var gridLeft = $scope.grid.element[0].getBoundingClientRect().left;
+                    var elmLeft = $elm[0].getBoundingClientRect().left;
+                    movingElementStyles.left = (elmLeft - gridLeft) + 'px';
+                    var gridRight = $scope.grid.element[0].getBoundingClientRect().right;
+                    var elmRight = $elm[0].getBoundingClientRect().right;
+                    var reducedWidth;
+                    if (elmRight > gridRight) {
+                      reducedWidth = $scope.col.drawnWidth + (gridRight - elmRight);
+                      movingElementStyles.width = reducedWidth + 'px';
+                    }
+                    //movingElementStyles.visibility = 'hidden';
+                    movingElm.css(movingElementStyles);
+
+                    //Setting some variables required for calculations.
+                    var previousMouseX = evt.pageX;
+                    var totalMouseMovement = 0;
+                    var rightMoveLimit = gridLeft + $scope.grid.getViewportWidth() - $scope.grid.verticalScrollbarWidth;
+
+                    //Clone element should move horizontally with mouse.
+                    var mouseMoveHandler = function (evt) {
+                      uiGridCtrl.fireEvent('hide-menu');
+                      var currentElmLeft = movingElm[0].getBoundingClientRect().left - 1;
+                      var currentElmRight = movingElm[0].getBoundingClientRect().right;
+                      var changeValue = evt.pageX - previousMouseX;
+                      var newElementLeft;
+                      if (gridUtil.detectBrowser() === 'ie') {
+                        newElementLeft = currentElmLeft + changeValue;
+                      }
+                      else {
+                        newElementLeft = currentElmLeft - gridLeft + changeValue;
+                      }
+                      newElementLeft = newElementLeft < rightMoveLimit ? newElementLeft : rightMoveLimit;
+                      if ((currentElmLeft >= gridLeft || changeValue > 0) && (currentElmRight <= rightMoveLimit || changeValue < 0)) {
+                        movingElm.css({visibility: 'visible', 'left': newElementLeft + 'px'});
+                      }
+                      else {
+                        changeValue *= 5;
+                        uiGridCtrl.fireScrollingEvent({ x: { pixels: changeValue * 2.5} });
+                      }
+                      totalMouseMovement += changeValue;
+                      previousMouseX = evt.pageX;
+                      if (reducedWidth < $scope.col.drawnWidth) {
+                        reducedWidth += Math.abs(changeValue);
+                        movingElm.css({'width': reducedWidth + 'px'});
+                      }
+                    };
+
+                    // On scope destroy, remove the mouse event handlers from the document body
+                    $scope.$on('$destroy', function () {
+                      $document.off('mousemove', mouseMoveHandler);
+                      $document.off('mouseup', mouseUpHandler);
+                    });
+
+                    $document.on('mousemove', mouseMoveHandler);
+                    var mouseUpHandler = function (evt) {
+                      var renderIndexDefer = $q.defer();
+
+                      var renderIndex;
+                      $attrs.$observe('renderIndex', function (n, o) {
+                        renderIndex = $scope.$eval(n);
+                        renderIndexDefer.resolve();
+                      });
+
+                      renderIndexDefer.promise.then(function () {
+
+                        //Remove the cloned element on mouse up.
+                        if (movingElm) {
+                          movingElm.remove();
+                        }
+
+                        var renderedColumns = $scope.grid.renderContainers['body'].renderedColumns;
+
+                        //This method will calculate the number of columns hidden in lift due to scroll
+                        //renderContainer.prevColumnScrollIndex could also have been used but this is more accurate
+                        var scrolledColumnCount = 0;
+                        var columns = $scope.grid.columns;
+                        for (var i = 0; i < columns.length; i++) {
+                          if (columns[i].colDef.name !== renderedColumns[0].colDef.name) {
+                            scrolledColumnCount++;
+                          }
+                          else {
+                            break;
+                          }
+                        }
+
+                        //Case where column should be moved to a position on its left
+                        if (totalMouseMovement < 0) {
+                          var totalColumnsLeftWidth = 0;
+                          for (var il = renderIndex - 1; il >= 0; il--) {
+                            totalColumnsLeftWidth += renderedColumns[il].drawnWidth;
+                            if (totalColumnsLeftWidth > Math.abs(totalMouseMovement)) {
+                              uiGridMoveColumnService.redrawColumnAtPosition
+                              ($scope.grid, scrolledColumnCount + renderIndex, scrolledColumnCount + il + 1);
+                              break;
+                            }
+                          }
+                          //Case where column should be moved to beginning of the grid.
+                          if (totalColumnsLeftWidth < Math.abs(totalMouseMovement)) {
+                            uiGridMoveColumnService.redrawColumnAtPosition
+                            ($scope.grid, scrolledColumnCount + renderIndex, scrolledColumnCount + 0);
+                          }
+                        }
+                        //Case where column should be moved to a position on its right
+                        else if (totalMouseMovement > 0) {
+                          var totalColumnsRightWidth = 0;
+                          for (var ir = renderIndex + 1; ir < renderedColumns.length; ir++) {
+                            totalColumnsRightWidth += renderedColumns[ir].drawnWidth;
+                            if (totalColumnsRightWidth > totalMouseMovement) {
+                              uiGridMoveColumnService.redrawColumnAtPosition
+                              ($scope.grid, scrolledColumnCount + renderIndex, scrolledColumnCount + ir - 1);
+                              break;
+                            }
+                          }
+                          //Case where column should be moved to end of the grid.
+                          if (totalColumnsRightWidth < totalMouseMovement) {
+                            uiGridMoveColumnService.redrawColumnAtPosition
+                            ($scope.grid, scrolledColumnCount + renderIndex, scrolledColumnCount + renderedColumns.length - 1);
+                          }
+                        }
+                        else if (totalMouseMovement === 0) {
+                          if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) {
+                            //sort the current column
+                            var add = false;
+                            if (evt.shiftKey) {
+                              add = true;
+                            }
+
+                            // Sort this column then rebuild the grid's rows
+                            uiGridCtrl.grid.sortColumn($scope.col, add)
+                              .then(function () {
+                                if (uiGridCtrl.columnMenuScope) {
+                                  uiGridCtrl.columnMenuScope.hideMenu();
+                                }
+                                uiGridCtrl.grid.refresh();
+                              });
+                          }
+                        }
+
+                        $document.off('mousemove', mouseMoveHandler);
+                        $document.off('mouseup', mouseUpHandler);
+                      });
+                    };
+
+                    $document.on('mouseup', mouseUpHandler);
+                  }
+                };
+
+                $elm.on('mousedown', mouseDownHandler);
+              }
+            }
+          };
+        }
+      };
+    }]);
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.pagination
+   *
+   * @description
+   *
+   * #ui.grid.pagination
+   * This module provides pagination support to ui-grid
+   */
+  var module = angular.module('ui.grid.pagination', ['ui.grid']);
+
+  /**
+   * @ngdoc service
+   * @name ui.grid.pagination.service:uiGridPaginationService
+   *
+   * @description Service for the pagination feature
+   */
+  module.service('uiGridPaginationService', function () {
+    var service = {
+
+      /**
+       * @ngdoc method
+       * @name initializeGrid
+       * @methodOf ui.grid.pagination.service:uiGridPaginationService
+       * @description Attaches the service to a certain grid
+       * @param {Grid} grid The grid we want to work with
+       */
+      initializeGrid: function (grid) {
+        service.defaultGridOptions(grid.options);
+        grid.pagination = {page: 1, totalPages: 1};
+
+        /**
+         * @ngdoc object
+         * @name ui.grid.pagination.api:PublicAPI
+         *
+         * @description Public API for the pagination feature
+         */
+        var publicApi = {
+          methods: {
+            pagination: {
+              /**
+               * @ngdoc method
+               * @name getPage
+               * @methodOf ui.grid.pagination.api:PublicAPI
+               * @description Returns the number of the current page
+               */
+              getPage: function () {
+                return grid.pagination.page;
+              },
+              /**
+               * @ngdoc method
+               * @name getTotalPages
+               * @methodOf ui.grid.pagination.api:PublicAPI
+               * @description Returns the total number of pages
+               */
+              getTotalPages: function () {
+                return grid.pagination.totalPages;
+              },
+              /**
+               * @ngdoc method
+               * @name nextPage
+               * @methodOf ui.grid.pagination.api:PublicAPI
+               * @description Moves to the next page, if possible
+               */
+              nextPage: function () {
+                grid.pagination.page++;
+                grid.refresh();
+              },
+              /**
+               * @ngdoc method
+               * @name previousPage
+               * @methodOf ui.grid.pagination.api:PublicAPI
+               * @description Moves to the previous page, if we're not on the first page
+               */
+              previousPage: function () {
+                grid.pagination.page = Math.max(1, grid.pagination.page - 1);
+                grid.refresh();
+              },
+              seek: function (page) {
+                if (!angular.isNumber(page) || page < 1) {
+                  throw 'Invalid page number: ' + page;
+                }
+
+                grid.pagination.page = page;
+                grid.refresh();
+              }
+            }
+          }
+        };
+        grid.api.registerMethodsFromObject(publicApi.methods);
+        grid.registerRowsProcessor(function (renderableRows) {
+          if (!grid.options.enablePagination) {
+            return renderableRows;
+          }
+          grid.pagination.totalPages = Math.max(
+            1,
+            Math.ceil(renderableRows.length / grid.options.rowsPerPage)
+          );
+
+          var firstRow = (grid.pagination.page - 1) * grid.options.rowsPerPage;
+          if (firstRow >= renderableRows.length) {
+            grid.pagination.page = grid.pagination.totalPages;
+            firstRow = (grid.pagination.page - 1) * grid.options.rowsPerPage;
+          }
+
+          return renderableRows.slice(
+            firstRow,
+            firstRow + grid.options.rowsPerPage
+          );
+        });
+      },
+
+      defaultGridOptions: function (gridOptions) {
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.pagination.api:GridOptions
+         *
+         *  @description GridOptions for the pagination feature, these are available to be
+         *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enablePagination
+         *  @propertyOf  ui.grid.pagination.api:GridOptions
+         *  @description Enable pagination for this grid
+         *  <br/>Defaults to true
+         */
+        gridOptions.enablePagination = gridOptions.enablePagination !== false;
+
+        /**
+         *  @ngdoc object
+         *  @name rowsPerPage
+         *  @propertyOf  ui.grid.pagination.api:GridOptions
+         *  @description The number of rows that should be displayed per page
+         *  <br/>Defaults to 10
+         */
+        gridOptions.rowsPerPage = angular.isNumber(gridOptions.rowsPerPage) ? gridOptions.rowsPerPage : 10;
+      }
+    };
+
+    return service;
+  });
+
+  /**
+   * @ngdoc directive
+   * @name ui.grid.pagination.directive:uiGridPagination
+   * @element div
+   * @restrict A
+   *
+   * @description Adds pagination support to a grid.
+   */
+  module.directive('uiGridPagination', ['uiGridPaginationService', function (uiGridPaginationService) {
+    return {
+      priority: -400,
+      scope: false,
+      require: '^uiGrid',
+      link: {
+        pre: function (scope, element, attrs, uiGridCtrl) {
+          uiGridPaginationService.initializeGrid(uiGridCtrl.grid);
+        }
+      }
+    };
+  }]);
+})();
+
+(function() {
+  'use strict';
+  /**
+   * @ngdoc overview
+   * @name ui.grid.paging
+   *
+   * @description
+   *
+   * #ui.grid.paging
+   * This module provides paging support to ui-grid
+   */
+   
+  var module = angular.module('ui.grid.paging', ['ui.grid']);
+
+  /**
+   * @ngdoc service
+   * @name ui.grid.paging.service:uiGridPagingService
+   *
+   * @description Service for the paging feature
+   */
+  module.service('uiGridPagingService', ['gridUtil', 
+    function (gridUtil) {
+      var service = {
+      /**
+       * @ngdoc method
+       * @name initializeGrid
+       * @methodOf ui.grid.paging.service:uiGridPagingService
+       * @description Attaches the service to a certain grid
+       * @param {Grid} grid The grid we want to work with
+       */
+        initializeGrid: function (grid) {
+          service.defaultGridOptions(grid.options);
+
+          /**
+          * @ngdoc object
+          * @name ui.grid.paging.api:PublicAPI
+          *
+          * @description Public API for the paging feature
+          */
+          var publicApi = {
+            events: {
+              paging: {
+              /**
+               * @ngdoc event
+               * @name pagingChanged
+               * @eventOf ui.grid.paging.api:PublicAPI
+               * @description This event fires when the pageSize or currentPage changes
+               * @param {currentPage} requested page number
+               * @param {pageSize} requested page size 
+               */
+                pagingChanged: function (currentPage, pageSize) { }
+              }
+            },
+            methods: {
+              paging: {
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+          grid.api.registerMethodsFromObject(publicApi.methods);
+          grid.registerRowsProcessor(function (renderableRows) {
+            if (grid.options.useExternalPaging || !grid.options.enablePaging) {
+              return renderableRows;
+            }
+            //client side paging
+            var pageSize = parseInt(grid.options.pagingPageSize, 10);
+            var currentPage = parseInt(grid.options.pagingCurrentPage, 10);
+
+            var firstRow = (currentPage - 1) * pageSize;
+            return renderableRows.slice(firstRow, firstRow + pageSize);
+          });
+
+        },
+        defaultGridOptions: function (gridOptions) {
+          /**
+           * @ngdoc property
+           * @name enablePaging
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Enables paging, defaults to true
+           */
+          gridOptions.enablePaging = gridOptions.enablePaging !== false;
+          /**
+           * @ngdoc property
+           * @name useExternalPaging
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Disables client side paging. When true, handle the pagingChanged event and set data and totalItems
+           * defaults to false
+           */           
+          gridOptions.useExternalPaging = gridOptions.useExternalPaging === true;
+          /**
+           * @ngdoc property
+           * @name totalItems
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Total number of items, set automatically when client side paging, needs set by user for server side paging
+           */
+          if (gridUtil.isNullOrUndefined(gridOptions.totalItems)) {
+            gridOptions.totalItems = 0;
+          }
+          /**
+           * @ngdoc property
+           * @name pagingPageSizes
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Array of page sizes
+           * defaults to [250, 500, 1000]
+           */
+          if (gridUtil.isNullOrUndefined(gridOptions.pagingPageSizes)) {
+            gridOptions.pagingPageSizes = [250, 500, 1000];
+          }
+          /**
+           * @ngdoc property
+           * @name pagingPageSize
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Page size
+           * defaults to the first item in pagingPageSizes, or 0 if pagingPageSizes is empty
+           */
+          if (gridUtil.isNullOrUndefined(gridOptions.pagingPageSize)) {
+            if (gridOptions.pagingPageSizes.length > 0) {
+              gridOptions.pagingPageSize = gridOptions.pagingPageSizes[0];
+            } else {              
+              gridOptions.pagingPageSize = 0;
+            }
+          }
+          /**
+           * @ngdoc property
+           * @name pagingCurrentPage
+           * @propertyOf ui.grid.class:GridOptions
+           * @description Current page number
+           * default 1
+           */
+          if (gridUtil.isNullOrUndefined(gridOptions.pagingCurrentPage)) {
+            gridOptions.pagingCurrentPage = 1;
+          }
+        },
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.paging.service:uiGridPagingService
+         * @name uiGridPagingService
+         * @description  Raises pagingChanged and calls refresh for client side paging
+         * @param {grid} the grid for which the paging changed
+         * @param {currentPage} requested page number
+         * @param {pageSize} requested page size 
+         */
+        onPagingChanged: function (grid, currentPage, pageSize) {
+            grid.api.paging.raise.pagingChanged(currentPage, pageSize);
+            if (!grid.options.useExternalPaging) {
+              grid.refresh(); //client side paging
+            }
+        }
+      };
+      
+      return service;
+    }
+  ]);
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.paging.directive:uiGridPaging
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds paging features to grid
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.paging']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Alex', car: 'Toyota' },
+        { name: 'Sam', car: 'Lexus' },
+        { name: 'Joe', car: 'Dodge' },
+        { name: 'Bob', car: 'Buick' },
+        { name: 'Cindy', car: 'Ford' },
+        { name: 'Brian', car: 'Audi' },
+        { name: 'Malcom', car: 'Mercedes Benz' },
+        { name: 'Dave', car: 'Ford' },
+        { name: 'Stacey', car: 'Audi' },
+        { name: 'Amy', car: 'Acura' },
+        { name: 'Scott', car: 'Toyota' },
+        { name: 'Ryan', car: 'BMW' },
+      ];
+
+      $scope.gridOptions = {
+        data: 'data',
+        pagingPageSizes: [5, 10, 25],
+        pagingPageSize: 5,
+        columnDefs: [
+          {name: 'name'},
+          {name: 'car'}
+        ];
+       }
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="gridOptions" ui-grid-paging></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridPaging', ['gridUtil', 'uiGridPagingService', 
+    function (gridUtil, uiGridPagingService) {
+    /**
+     * @ngdoc property
+     * @name pagingTemplate
+     * @propertyOf ui.grid.class:GridOptions
+     * @description a custom template for the pager.  The default
+     * is ui-grid/ui-grid-paging
+     */
+      var defaultTemplate = 'ui-grid/ui-grid-paging';
+
+      return {
+        priority: -200,
+        scope: false,
+        require: 'uiGrid',
+        compile: function ($scope, $elm, $attr, uiGridCtrl) {
+          return {
+            pre: function ($scope, $elm, $attr, uiGridCtrl) {
+
+              uiGridPagingService.initializeGrid(uiGridCtrl.grid);
+
+              var pagingTemplate = uiGridCtrl.grid.options.pagingTemplate || defaultTemplate;
+              gridUtil.getTemplate(pagingTemplate)
+                .then(function (contents) {
+                  var template = angular.element(contents);
+                  $elm.append(template);
+                  uiGridCtrl.innerCompile(template);
+                });
+            },
+            post: function ($scope, $elm, $attr, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }
+  ]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.paging.directive:uiGridPager
+   *  @element div
+   *
+   *  @description Panel for handling paging
+   */
+  module.directive('uiGridPager', ['uiGridPagingService', 'uiGridConstants', 'gridUtil', 'i18nService',
+    function (uiGridPagingService, uiGridConstants, gridUtil, i18nService) {
+      return {
+        priority: -200,
+        scope: true,
+        require: '^uiGrid',
+        link: function ($scope, $elm, $attr, uiGridCtrl) {
+
+          $scope.sizesLabel = i18nService.getSafeText('paging.sizes');
+          $scope.totalItemsLabel = i18nService.getSafeText('paging.totalItems');
+          
+          var options = $scope.grid.options;
+          
+          uiGridCtrl.grid.renderContainers.body.registerViewportAdjuster(function (adjustment) {
+            adjustment.height = adjustment.height - gridUtil.elementHeight($elm);
+            return adjustment;
+          });
+          
+          uiGridCtrl.grid.registerDataChangeCallback(function (grid) {
+            if (!grid.options.useExternalPaging) {
+              grid.options.totalItems = grid.rows.length;
+            }
+          }, [uiGridConstants.dataChange.ROW]);
+
+          var setShowing = function () {
+            $scope.showingLow = ((options.pagingCurrentPage - 1) * options.pagingPageSize) + 1;
+            $scope.showingHigh = Math.min(options.pagingCurrentPage * options.pagingPageSize, options.totalItems);
+          };
+
+          var getMaxPages = function () {
+            return (options.totalItems === 0) ? 1 : Math.ceil(options.totalItems / options.pagingPageSize);
+          };
+
+          var deregT = $scope.$watch('grid.options.totalItems + grid.options.pagingPageSize', function () {
+              $scope.currentMaxPages = getMaxPages();
+              setShowing();
+            }
+          );
+
+          var deregP = $scope.$watch('grid.options.pagingCurrentPage + grid.options.pagingPageSize', function (newValues, oldValues) {
+              if (newValues === oldValues) { 
+                return; 
+              }
+
+              if (!angular.isNumber(options.pagingCurrentPage) || options.pagingCurrentPage < 1) {
+                options.pagingCurrentPage = 1;
+                return;
+              }
+
+              if (options.totalItems > 0 && options.pagingCurrentPage > getMaxPages()) {
+                options.pagingCurrentPage = getMaxPages();
+                return;
+              }
+
+              setShowing();
+              uiGridPagingService.onPagingChanged($scope.grid, options.pagingCurrentPage, options.pagingPageSize);
+            }
+          );
+
+          $scope.$on('$destroy', function() {
+            deregT();
+            deregP();
+          });
+
+          $scope.pageForward = function () {
+            if (options.totalItems > 0) {
+              options.pagingCurrentPage = Math.min(options.pagingCurrentPage + 1, $scope.currentMaxPages);
+            } else {
+              options.pagingCurrentPage++;
+            }
+          };
+
+          $scope.pageBackward = function () {
+            options.pagingCurrentPage = Math.max(options.pagingCurrentPage - 1, 1);
+          };
+
+          $scope.pageToFirst = function () {
+            options.pagingCurrentPage = 1;
+          };
+
+          $scope.pageToLast = function () {
+            options.pagingCurrentPage = $scope.currentMaxPages;
+          };
+
+          $scope.cantPageForward = function () {
+            if (options.totalItems > 0) {
+              return options.pagingCurrentPage >= $scope.currentMaxPages;
+            } else {
+              return options.data.length < 1;
+            }
+          };
+          
+          $scope.cantPageToLast = function () {
+            if (options.totalItems > 0) {
+              return $scope.cantPageForward();
+            } else {
+              return true;
+            }
+          };
+          
+          $scope.cantPageBackward = function () {
+            return options.pagingCurrentPage <= 1;
+          };
+        }
+      };
+    }
+  ]);
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.pinning
+   * @description
+   *
+   *  # ui.grid.pinning
+   * This module provides column pinning to the end user via menu options in the column header
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.pinning"></div>
+   */
+
+  var module = angular.module('ui.grid.pinning', ['ui.grid']);
+
+  module.service('uiGridPinningService', ['gridUtil', 'GridRenderContainer', 'i18nService', function (gridUtil, GridRenderContainer, i18nService) {
+    var service = {
+
+      initializeGrid: function (grid) {
+        service.defaultGridOptions(grid.options);
+
+        // Register a column builder to add new menu items for pinning left and right
+        grid.registerColumnBuilder(service.pinningColumnBuilder);
+      },
+
+      defaultGridOptions: function (gridOptions) {
+        //default option to true unless it was explicitly set to false
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.pinning.api:GridOptions
+         *
+         *  @description GridOptions for pinning feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enableRowSelection
+         *  @propertyOf  ui.grid.pinning.api:GridOptions
+         *  @description Enable pinning for the entire grid.  
+         *  <br/>Defaults to true
+         */
+        gridOptions.enablePinning = gridOptions.enablePinning !== false;
+
+      },
+
+      pinningColumnBuilder: function (colDef, col, gridOptions) {
+        //default to true unless gridOptions or colDef is explicitly false
+
+        /**
+         *  @ngdoc object
+         *  @name ui.grid.pinning.api:ColumnDef
+         *
+         *  @description ColumnDef for pinning feature, these are available to be 
+         *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name enablePinning
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Enable pinning for the individual column.  
+         *  <br/>Defaults to true
+         */
+        colDef.enablePinning = colDef.enablePinning === undefined ? gridOptions.enablePinning : colDef.enablePinning;
+
+
+        /**
+         *  @ngdoc object
+         *  @name pinnedLeft
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Column is pinned left when grid is rendered
+         *  <br/>Defaults to false
+         */
+
+        /**
+         *  @ngdoc object
+         *  @name pinnedRight
+         *  @propertyOf  ui.grid.pinning.api:ColumnDef
+         *  @description Column is pinned right when grid is rendered
+         *  <br/>Defaults to false
+         */
+        if (colDef.pinnedLeft) {
+          if (col.width === '*') {
+            // Need to refresh so the width can be calculated.
+            col.grid.refresh()
+                .then(function () {
+                    col.renderContainer = 'left';
+                    // Need to calculate the width. If col.drawnWidth is used instead then the width
+                    // will be 100% if it's the first column, 50% if it's the second etc.
+                    col.width = col.grid.canvasWidth / col.grid.columns.length;
+                    col.grid.createLeftContainer();
+            });
+          }
+          else {
+            col.renderContainer = 'left';
+            col.grid.createLeftContainer();
+          }
+        }
+        else if (colDef.pinnedRight) {
+            if (col.width === '*') {
+                // Need to refresh so the width can be calculated.
+                col.grid.refresh()
+                    .then(function () {
+                        col.renderContainer = 'right';
+                        // Need to calculate the width. If col.drawnWidth is used instead then the width
+                        // will be 100% if it's the first column, 50% if it's the second etc.
+                        col.width = col.grid.canvasWidth / col.grid.columns.length;
+                        col.grid.createRightContainer();
+                    });
+            }
+            else {
+                col.renderContainer = 'right';
+                col.grid.createRightContainer();
+            }
+        }
+
+        if (!colDef.enablePinning) {
+          return;
+        }
+
+        var pinColumnLeftAction = {
+          name: 'ui.grid.pinning.pinLeft',
+          title: i18nService.get().pinning.pinLeft,
+          icon: 'ui-grid-icon-left-open',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'left';
+          },
+          action: function () {
+            this.context.col.renderContainer = 'left';
+            this.context.col.width = this.context.col.drawnWidth;
+            this.context.col.grid.createLeftContainer();
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        var pinColumnRightAction = {
+          name: 'ui.grid.pinning.pinRight',
+          title: i18nService.get().pinning.pinRight,
+          icon: 'ui-grid-icon-right-open',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) === 'undefined' || !this.context.col.renderContainer || this.context.col.renderContainer !== 'right';
+          },
+          action: function () {
+            this.context.col.renderContainer = 'right';
+            this.context.col.width = this.context.col.drawnWidth;
+            this.context.col.grid.createRightContainer();
+
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        var removePinAction = {
+          name: 'ui.grid.pinning.unpin',
+          title: i18nService.get().pinning.unpin,
+          icon: 'ui-grid-icon-cancel',
+          shown: function () {
+            return typeof(this.context.col.renderContainer) !== 'undefined' && this.context.col.renderContainer !== null && this.context.col.renderContainer !== 'body';
+          },
+          action: function () {
+            this.context.col.renderContainer = null;
+
+            // Need to call refresh twice; once to move our column over to the new render container and then
+            //   a second time to update the grid viewport dimensions with our adjustments
+            col.grid.refresh()
+              .then(function () {
+                col.grid.refresh();
+              });
+          }
+        };
+
+        if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.pinning.pinLeft')) {
+          col.menuItems.push(pinColumnLeftAction);
+        }
+        if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.pinning.pinRight')) {
+          col.menuItems.push(pinColumnRightAction);
+        }
+        if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.pinning.unpin')) {
+          col.menuItems.push(removePinAction);
+        }
+      }
+    };
+
+    return service;
+  }]);
+
+  module.directive('uiGridPinning', ['gridUtil', 'uiGridPinningService',
+    function (gridUtil, uiGridPinningService) {
+      return {
+        require: 'uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              uiGridPinningService.initializeGrid(uiGridCtrl.grid);
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+            }
+          };
+        }
+      };
+    }]);
+
+
+})();
+
+(function(){
+  'use strict';
+
+  var module = angular.module('ui.grid.resizeColumns', ['ui.grid']);
+
+  module.constant('columnBounds', {
+    minWidth: 35
+  });
+
+
+  module.service('uiGridResizeColumnsService', ['gridUtil', '$q', '$timeout',
+    function (gridUtil, $q, $timeout) {
+
+      var service = {
+        defaultGridOptions: function(gridOptions){
+          //default option to true unless it was explicitly set to false
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.resizeColumns.api:GridOptions
+           *
+           *  @description GridOptions for resizeColumns feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableColumnResizing
+           *  @propertyOf  ui.grid.resizeColumns.api:GridOptions
+           *  @description Enable column resizing on the entire grid 
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableColumnResizing = gridOptions.enableColumnResizing !== false;
+
+          //legacy support
+          //use old name if it is explicitly false
+          if (gridOptions.enableColumnResize === false){
+            gridOptions.enableColumnResizing = false;
+          }
+        },
+
+        colResizerColumnBuilder: function (colDef, col, gridOptions) {
+
+          var promises = [];
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.resizeColumns.api:ColumnDef
+           *
+           *  @description ColumnDef for resizeColumns feature, these are available to be 
+           *  set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableColumnResizing
+           *  @propertyOf  ui.grid.resizeColumns.api:ColumnDef
+           *  @description Enable column resizing on an individual column
+           *  <br/>Defaults to GridOptions.enableColumnResizing
+           */
+          //default to true unless gridOptions or colDef is explicitly false
+          colDef.enableColumnResizing = colDef.enableColumnResizing === undefined ? gridOptions.enableColumnResizing : colDef.enableColumnResizing;
+
+
+          //legacy support of old option name
+          if (colDef.enableColumnResize === false){
+            colDef.enableColumnResizing = false;
+          }
+
+          return $q.all(promises);
+        },
+        
+        registerPublicApi: function (grid) {
+            /**
+             *  @ngdoc object
+             *  @name ui.grid.resizeColumns.api:PublicApi
+             *  @description Public Api for column resize feature.
+             */
+            var publicApi = {
+              events: {
+                /**
+                 * @ngdoc event
+                 * @name columnSizeChanged
+                 * @eventOf  ui.grid.resizeColumns.api:PublicApi
+                 * @description raised when column is resized
+                 * <pre>
+                 *      gridApi.colResizable.on.columnSizeChanged(scope,function(colDef, deltaChange){})
+                 * </pre>
+                 * @param {object} colDef the column that was resized
+                 * @param {integer} delta of the column size change
+                 */
+                colResizable: {
+                  columnSizeChanged: function (colDef, deltaChange) {
+                  }
+                }
+              }
+            };
+            grid.api.registerEventsFromObject(publicApi.events);
+        },
+        
+        fireColumnSizeChanged: function (grid, colDef, deltaChange) {
+          $timeout(function () {
+            grid.api.colResizable.raise.columnSizeChanged(colDef, deltaChange);
+          });
+        }
+      };
+
+      return service;
+
+    }]);
+
+
+  /**
+   * @ngdoc directive
+   * @name ui.grid.resizeColumns.directive:uiGridResizeColumns
+   * @element div
+   * @restrict A
+   * @description
+   * Enables resizing for all columns on the grid. If, for some reason, you want to use the ui-grid-resize-columns directive, but not allow column resizing, you can explicitly set the
+   * option to false. This prevents resizing for the entire grid, regardless of individual columnDef options.
+   *
+   * @example
+   <doc:example module="app">
+   <doc:source>
+   <script>
+   var app = angular.module('app', ['ui.grid', 'ui.grid.resizeColumns']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.gridOpts = {
+            data: [
+              { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
+              { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
+              { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
+              { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
+            ]
+          };
+        }]);
+   </script>
+
+   <div ng-controller="MainCtrl">
+   <div class="testGrid" ui-grid="gridOpts" ui-grid-resize-columns ></div>
+   </div>
+   </doc:source>
+   <doc:scenario>
+
+   </doc:scenario>
+   </doc:example>
+   */
+  module.directive('uiGridResizeColumns', ['gridUtil', 'uiGridResizeColumnsService', function (gridUtil, uiGridResizeColumnsService) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {            
+            uiGridResizeColumnsService.defaultGridOptions(uiGridCtrl.grid.options);
+            uiGridCtrl.grid.registerColumnBuilder( uiGridResizeColumnsService.colResizerColumnBuilder);
+            uiGridResizeColumnsService.registerPublicApi(uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+          }
+        };
+      }
+    };
+  }]);
+
+  // Extend the uiGridHeaderCell directive
+  module.directive('uiGridHeaderCell', ['gridUtil', '$templateCache', '$compile', '$q', function (gridUtil, $templateCache, $compile, $q) {
+    return {
+      // Run after the original uiGridHeaderCell
+      priority: -10,
+      require: '^uiGrid',
+      // scope: false,
+      compile: function() {
+        return {
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {
+           if (uiGridCtrl.grid.options.enableColumnResizing) {
+              var renderIndexDefer = $q.defer();
+
+              $attrs.$observe('renderIndex', function (n, o) {
+                $scope.renderIndex = $scope.$eval(n);
+
+                renderIndexDefer.resolve();
+              });
+
+              renderIndexDefer.promise.then(function() {
+                var columnResizerElm = $templateCache.get('ui-grid/columnResizer');
+
+                var resizerLeft = angular.element(columnResizerElm).clone();
+                var resizerRight = angular.element(columnResizerElm).clone();
+
+                resizerLeft.attr('position', 'left');
+                resizerRight.attr('position', 'right');
+
+                var col = $scope.col;
+                var renderContainer = col.getRenderContainer();
+
+
+                // Get the column to the left of this one
+                var otherCol = renderContainer.renderedColumns[$scope.renderIndex - 1];
+
+                // Don't append the left resizer if this is the first column or the column to the left of this one has resizing disabled
+                if (otherCol && renderContainer.visibleColumnCache.indexOf($scope.col) !== 0 && otherCol.colDef.enableColumnResizing !== false) {
+                  $elm.prepend(resizerLeft);
+                  $compile(resizerLeft)($scope);
+                }
+                
+                // Don't append the right resizer if this column has resizing disabled
+                if ($scope.col.colDef.enableColumnResizing !== false) {
+                  $elm.append(resizerRight);
+                  $compile(resizerRight)($scope);
+                }
+              });
+            }
+          }
+        };
+      }
+    };
+  }]);
+
+
+  
+  /**
+   * @ngdoc directive
+   * @name ui.grid.resizeColumns.directive:uiGridColumnResizer
+   * @element div
+   * @restrict A
+   *
+   * @description
+   * Draggable handle that controls column resizing.
+   * 
+   * @example
+   <doc:example module="app">
+     <doc:source>
+       <script>
+        var app = angular.module('app', ['ui.grid', 'ui.grid.resizeColumns']);
+
+        app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.gridOpts = {
+            enableColumnResizing: true,
+            data: [
+              { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
+              { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
+              { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
+              { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
+            ]
+          };
+        }]);
+       </script>
+
+       <div ng-controller="MainCtrl">
+        <div class="testGrid" ui-grid="gridOpts"></div>
+       </div>
+     </doc:source>
+     <doc:scenario>
+      // TODO: e2e specs?
+        // TODO: Obey minWidth and maxWIdth;
+
+      // TODO: post-resize a horizontal scroll event should be fired
+     </doc:scenario>
+   </doc:example>
+   */  
+  module.directive('uiGridColumnResizer', ['$document', 'gridUtil', 'uiGridConstants', 'columnBounds', 'uiGridResizeColumnsService', function ($document, gridUtil, uiGridConstants, columnBounds, uiGridResizeColumnsService) {
+    var resizeOverlay = angular.element('<div class="ui-grid-resize-overlay"></div>');
+
+    var resizer = {
+      priority: 0,
+      scope: {
+        col: '=',
+        position: '@',
+        renderIndex: '='
+      },
+      require: '?^uiGrid',
+      link: function ($scope, $elm, $attrs, uiGridCtrl) {
+        var startX = 0,
+            x = 0,
+            gridLeft = 0,
+            rtlMultiplier = 1;
+
+        //when in RTL mode reverse the direction using the rtlMultiplier and change the position to left
+        if (uiGridCtrl.grid.isRTL()) {
+          $scope.position = 'left';
+          rtlMultiplier = -1;
+        }
+
+        if ($scope.position === 'left') {
+          $elm.addClass('left');
+        }
+        else if ($scope.position === 'right') {
+          $elm.addClass('right');
+        }
+
+        // Resize all the other columns around col
+        function resizeAroundColumn(col) {
+          // Get this column's render container
+          var renderContainer = col.getRenderContainer();
+
+          renderContainer.visibleColumnCache.forEach(function (column) {
+            // Skip the column we just resized
+            if (column === col) { return; }
+            
+            var colDef = column.colDef;
+            if (!colDef.width || (angular.isString(colDef.width) && (colDef.width.indexOf('*') !== -1 || colDef.width.indexOf('%') !== -1))) {
+              column.width = column.drawnWidth;
+            }
+          });
+        }
+
+        // Build the columns then refresh the grid canvas
+        //   takes an argument representing the diff along the X-axis that the resize had
+        function buildColumnsAndRefresh(xDiff) {
+          // Build the columns
+          uiGridCtrl.grid.buildColumns()
+            .then(function() {
+              // Then refresh the grid canvas, rebuilding the styles so that the scrollbar updates its size
+              uiGridCtrl.grid.refreshCanvas(true);
+            });
+        }
+
+        function mousemove(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.preventDefault();
+
+          x = event.clientX - gridLeft;
+
+          if (x < 0) { x = 0; }
+          else if (x > uiGridCtrl.grid.gridWidth) { x = uiGridCtrl.grid.gridWidth; }
+
+          // The other column to resize (the one next to this one)
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+          var otherCol;
+          if ($scope.position === 'left') {
+            // Get the column to the left of this one
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+          }
+
+          // Don't resize if it's disabled on this column
+          if (col.colDef.enableColumnResizing === false) {
+            return;
+          }
+
+          if (!uiGridCtrl.grid.element.hasClass('column-resizing')) {
+            uiGridCtrl.grid.element.addClass('column-resizing');
+          }
+
+          // Get the diff along the X axis
+          var xDiff = x - startX;
+
+          // Get the width that this mouse would give the column
+          var newWidth = parseInt(col.drawnWidth + xDiff * rtlMultiplier, 10);
+
+          // If the new width would be less than the column's allowably minimum width, don't allow it
+          if (col.colDef.minWidth && newWidth < col.colDef.minWidth) {
+            x = x + (col.colDef.minWidth - newWidth) * rtlMultiplier;
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && newWidth < columnBounds.minWidth) {
+            x = x + (col.colDef.minWidth - newWidth);
+          }
+          else if (col.colDef.maxWidth && newWidth > col.colDef.maxWidth) {
+            x = x + (col.colDef.maxWidth - newWidth) * rtlMultiplier;
+          }
+          
+          resizeOverlay.css({ left: x + 'px' });
+
+          uiGridCtrl.fireEvent(uiGridConstants.events.ITEM_DRAGGING);
+        }
+
+        function mouseup(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.preventDefault();
+
+          uiGridCtrl.grid.element.removeClass('column-resizing');
+
+          resizeOverlay.remove();
+
+          // Resize the column
+          x = event.clientX - gridLeft;
+          var xDiff = x - startX;
+
+          if (xDiff === 0) {
+            $document.off('mouseup', mouseup);
+            $document.off('mousemove', mousemove);
+            return;
+          }
+
+          // The other column to resize (the one next to this one)
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+
+          var otherCol;
+          if ($scope.position === 'left') {
+            // Get the column to the left of this one
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+          }
+
+          // Don't resize if it's disabled on this column
+          if (col.colDef.enableColumnResizing === false) {
+            return;
+          }
+
+          // Get the new width
+          var newWidth = parseInt(col.drawnWidth + xDiff * rtlMultiplier, 10);
+
+          // If the new width is less than the minimum width, make it the minimum width
+          if (col.colDef.minWidth && newWidth < col.colDef.minWidth) {
+            newWidth = col.colDef.minWidth;
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && newWidth < columnBounds.minWidth) {
+            newWidth = columnBounds.minWidth;
+          }
+          // 
+          if (col.colDef.maxWidth && newWidth > col.colDef.maxWidth) {
+            newWidth = col.colDef.maxWidth;
+          }
+          
+          col.width = newWidth;
+
+          // All other columns because fixed to their drawn width, if they aren't already
+          resizeAroundColumn(col);
+
+          buildColumnsAndRefresh(xDiff);
+
+          uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
+
+          $document.off('mouseup', mouseup);
+          $document.off('mousemove', mousemove);
+        }
+
+        $elm.on('mousedown', function(event, args) {
+          if (event.originalEvent) { event = event.originalEvent; }
+          event.stopPropagation();
+
+          // Get the left offset of the grid
+          // gridLeft = uiGridCtrl.grid.element[0].offsetLeft;
+          gridLeft = uiGridCtrl.grid.element[0].getBoundingClientRect().left;
+
+          // Get the starting X position, which is the X coordinate of the click minus the grid's offset
+          startX = event.clientX - gridLeft;
+
+          // Append the resizer overlay
+          uiGridCtrl.grid.element.append(resizeOverlay);
+
+          // Place the resizer overlay at the start position
+          resizeOverlay.css({ left: startX });
+
+          // Add handlers for mouse move and up events
+          $document.on('mouseup', mouseup);
+          $document.on('mousemove', mousemove);
+        });
+
+        // On doubleclick, resize to fit all rendered cells
+        $elm.on('dblclick', function(event, args) {
+          event.stopPropagation();
+
+          var col = $scope.col;
+          var renderContainer = col.getRenderContainer();
+
+          var otherCol, multiplier;
+
+          // If we're the left-positioned resizer then we need to resize the column to the left of our column, and not our column itself
+          if ($scope.position === 'left') {
+            col = renderContainer.renderedColumns[$scope.renderIndex - 1];
+            otherCol = $scope.col;
+            multiplier = 1;
+          }
+          else if ($scope.position === 'right') {
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+            otherCol = renderContainer.renderedColumns[$scope.renderIndex + 1];
+            multiplier = -1;
+          }
+
+          // Go through the rendered rows and find out the max size for the data in this column
+          var maxWidth = 0;
+          var xDiff = 0;
+
+          // Get the parent render container element
+          var renderContainerElm = gridUtil.closestElm($elm, '.ui-grid-render-container');
+
+          // Get the cell contents so we measure correctly. For the header cell we have to account for the sort icon and the menu buttons, if present
+          var cells = renderContainerElm.querySelectorAll('.' + uiGridConstants.COL_CLASS_PREFIX + col.uid + ' .ui-grid-cell-contents');
+          Array.prototype.forEach.call(cells, function (cell) {
+              // Get the cell width
+              // gridUtil.logDebug('width', gridUtil.elementWidth(cell));
+
+              // Account for the menu button if it exists
+              var menuButton;
+              if (angular.element(cell).parent().hasClass('ui-grid-header-cell')) {
+                menuButton = angular.element(cell).parent()[0].querySelectorAll('.ui-grid-column-menu-button');
+              }
+
+              gridUtil.fakeElement(cell, {}, function(newElm) {
+                // Make the element float since it's a div and can expand to fill its container
+                var e = angular.element(newElm);
+                e.attr('style', 'float: left');
+
+                var width = gridUtil.elementWidth(e);
+
+                if (menuButton) {
+                  var menuButtonWidth = gridUtil.elementWidth(menuButton);
+                  width = width + menuButtonWidth;
+                }
+
+                if (width > maxWidth) {
+                  maxWidth = width;
+                  xDiff = maxWidth - width;
+                }
+              });
+            });
+
+          // If the new width is less than the minimum width, make it the minimum width
+          if (col.colDef.minWidth && maxWidth < col.colDef.minWidth) {
+            maxWidth = col.colDef.minWidth;
+          }
+          else if (!col.colDef.minWidth && columnBounds.minWidth && maxWidth < columnBounds.minWidth) {
+            maxWidth = columnBounds.minWidth;
+          }
+          // 
+          if (col.colDef.maxWidth && maxWidth > col.colDef.maxWidth) {
+            maxWidth = col.colDef.maxWidth;
+          }
+
+          col.width = parseInt(maxWidth, 10);
+          
+          // All other columns because fixed to their drawn width, if they aren't already
+          resizeAroundColumn(col);
+
+          buildColumnsAndRefresh(xDiff);
+          
+          uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
+        });
+
+        $elm.on('$destroy', function() {
+          $elm.off('mousedown');
+          $elm.off('dblclick');
+          $document.off('mousemove', mousemove);
+          $document.off('mouseup', mouseup);
+        });
+      }
+    };
+
+    return resizer;
+  }]);
+
+})();
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.rowEdit
+   * @description
+   *
+   *  # ui.grid.rowEdit
+   * This module extends the edit feature to provide tracking and saving of rows
+   * of data.  The tutorial provides more information on how this feature is best
+   * used {@link tutorial/205_row_editable here}.
+   * <br/>
+   * This feature depends on usage of the ui-grid-edit feature, and also benefits
+   * from use of ui-grid-cellNav to provide the full spreadsheet-like editing 
+   * experience
+   * 
+   */
+
+  var module = angular.module('ui.grid.rowEdit', ['ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.rowEdit.constant:uiGridRowEditConstants
+   *
+   *  @description constants available in row edit module
+   */
+  module.constant('uiGridRowEditConstants', {
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.rowEdit.service:uiGridRowEditService
+   *
+   *  @description Services for row editing features
+   */
+  module.service('uiGridRowEditService', ['$interval', '$q', 'uiGridConstants', 'uiGridRowEditConstants', 'gridUtil', 
+    function ($interval, $q, uiGridConstants, uiGridRowEditConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (scope, grid) {
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.rowEdit.api:PublicApi
+           *
+           *  @description Public Api for rowEdit feature
+           */
+          
+          grid.rowEdit = {};
+          
+          var publicApi = {
+            events: {
+              rowEdit: {
+                /**
+                 * @ngdoc event
+                 * @eventOf ui.grid.rowEdit.api:PublicApi
+                 * @name saveRow
+                 * @description raised when a row is ready for saving.  Once your
+                 * row has saved you may need to use angular.extend to update the
+                 * data entity with any changed data from your save (for example, 
+                 * lock version information if you're using optimistic locking,
+                 * or last update time/user information).
+                 * 
+                 * Your method should call setSavePromise somewhere in the body before
+                 * returning control.  The feature will then wait, with the gridRow greyed out 
+                 * whilst this promise is being resolved.
+                 * 
+                 * <pre>
+                 *      gridApi.rowEdit.on.saveRow(scope,function(rowEntity){})
+                 * </pre>
+                 * and somewhere within the event handler:
+                 * <pre>
+                 *      gridApi.rowEdit.setSavePromise( grid, rowEntity, savePromise)
+                 * </pre>
+                 * @param {object} rowEntity the options.data element that was edited
+                 * @returns {promise} Your saveRow method should return a promise, the
+                 * promise should either be resolved (implying successful save), or 
+                 * rejected (implying an error).
+                 */
+                saveRow: function (rowEntity) {
+                }
+              }
+            },
+            methods: {
+              rowEdit: {
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name setSavePromise
+                 * @description Sets the promise associated with the row save, mandatory that
+                 * the saveRow event handler calls this method somewhere before returning.
+                 * <pre>
+                 *      gridApi.rowEdit.setSavePromise(grid, rowEntity)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be returned
+                 * @param {object} rowEntity a data row from the grid for which a save has
+                 * been initiated
+                 * @param {promise} savePromise the promise that will be resolved when the
+                 * save is successful, or rejected if the save fails
+                 * 
+                 */
+                setSavePromise: function (grid, rowEntity, savePromise) {
+                  service.setSavePromise(grid, rowEntity, savePromise);
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name getDirtyRows
+                 * @description Returns all currently dirty rows
+                 * <pre>
+                 *      gridApi.rowEdit.getDirtyRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be returned
+                 * @returns {array} An array of gridRows that are currently dirty
+                 * 
+                 */
+                getDirtyRows: function (grid) {
+                  return grid.rowEdit.dirtyRows ? grid.rowEdit.dirtyRows : [];
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name getErrorRows
+                 * @description Returns all currently errored rows
+                 * <pre>
+                 *      gridApi.rowEdit.getErrorRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which errored rows should be returned
+                 * @returns {array} An array of gridRows that are currently in error
+                 * 
+                 */
+                getErrorRows: function (grid) {
+                  return grid.rowEdit.errorRows ? grid.rowEdit.errorRows : [];
+                },
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name flushDirtyRows
+                 * @description Triggers a save event for all currently dirty rows, could
+                 * be used where user presses a save button or navigates away from the page
+                 * <pre>
+                 *      gridApi.rowEdit.flushDirtyRows(grid)
+                 * </pre>
+                 * @param {object} grid the grid for which dirty rows should be flushed
+                 * @returns {promise} a promise that represents the aggregate of all
+                 * of the individual save promises - i.e. it will be resolved when all
+                 * the individual save promises have been resolved.
+                 * 
+                 */
+                flushDirtyRows: function (grid) {
+                  return service.flushDirtyRows(grid);
+                },
+                
+                /**
+                 * @ngdoc method
+                 * @methodOf ui.grid.rowEdit.api:PublicApi
+                 * @name setRowsDirty
+                 * @description Sets each of the rows passed in dataRows
+                 * to be dirty.  note that if you have only just inserted the
+                 * rows into your data you will need to wait for a $digest cycle
+                 * before the gridRows are present - so often you would wrap this
+                 * call in a $interval or $timeout
+                 * <pre>
+                 *      $interval( function() {
+                 *        gridApi.rowEdit.setRowsDirty(grid, myDataRows);
+                 *      }, 0, 1);
+                 * </pre>
+                 * @param {object} grid the grid for which rows should be set dirty
+                 * @param {array} dataRows the data entities for which the gridRows
+                 * should be set dirty.  
+                 * 
+                 */
+                setRowsDirty: function (grid, dataRows) {
+                  service.setRowsDirty(grid, dataRows);
+                }
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+          grid.api.registerMethodsFromObject(publicApi.methods);
+          
+          grid.api.core.on.renderingComplete( scope, function ( gridApi ) {
+            grid.api.edit.on.afterCellEdit( scope, service.endEditCell );
+            grid.api.edit.on.beginCellEdit( scope, service.beginEditCell );
+            grid.api.edit.on.cancelCellEdit( scope, service.cancelEditCell );
+            
+            if ( grid.api.cellNav ) {
+              grid.api.cellNav.on.navigate( scope, service.navigate );
+            }              
+          });
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.rowEdit.api:GridOptions
+           *
+           *  @description Options for configuring the rowEdit feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name saveRow
+         * @description  Returns a function that saves the specified row from the grid,
+         * and returns a promise
+         * @param {object} grid the grid for which dirty rows should be flushed
+         * @param {GridRow} gridRow the row that should be saved
+         * @returns {function} the saveRow function returns a function.  That function
+         * in turn, when called, returns a promise relating to the save callback
+         */
+        saveRow: function ( grid, gridRow ) {
+          var self = this;
+
+          return function() {
+            gridRow.isSaving = true;
+
+            var promise = grid.api.rowEdit.raise.saveRow( gridRow.entity );
+            
+            if ( gridRow.rowEditSavePromise ){
+              gridRow.rowEditSavePromise.then( self.processSuccessPromise( grid, gridRow ), self.processErrorPromise( grid, gridRow ));
+            } else {
+              gridUtil.logError( 'A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise' );
+            }
+            return promise;
+          };
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf  ui.grid.rowEdit.service:uiGridRowEditService
+         * @name setSavePromise
+         * @description Sets the promise associated with the row save, mandatory that
+         * the saveRow event handler calls this method somewhere before returning.
+         * <pre>
+         *      gridApi.rowEdit.setSavePromise(grid, rowEntity)
+         * </pre>
+         * @param {object} grid the grid for which dirty rows should be returned
+         * @param {object} rowEntity a data row from the grid for which a save has
+         * been initiated
+         * @param {promise} savePromise the promise that will be resolved when the
+         * save is successful, or rejected if the save fails
+         * 
+         */
+        setSavePromise: function (grid, rowEntity, savePromise) {
+          var gridRow = grid.getRow( rowEntity );
+          gridRow.rowEditSavePromise = savePromise;
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name processSuccessPromise
+         * @description  Returns a function that processes the successful
+         * resolution of a save promise  
+         * @param {object} grid the grid for which the promise should be processed
+         * @param {GridRow} gridRow the row that has been saved
+         * @returns {function} the success handling function
+         */
+        processSuccessPromise: function ( grid, gridRow ) {
+          var self = this;
+          
+          return function() {
+            delete gridRow.isSaving;
+            delete gridRow.isDirty;
+            delete gridRow.isError;
+            delete gridRow.rowEditSaveTimer;
+            self.removeRow( grid.rowEdit.errorRows, gridRow );
+            self.removeRow( grid.rowEdit.dirtyRows, gridRow );
+          };
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name processErrorPromise
+         * @description  Returns a function that processes the failed
+         * resolution of a save promise  
+         * @param {object} grid the grid for which the promise should be processed
+         * @param {GridRow} gridRow the row that is now in error
+         * @returns {function} the error handling function
+         */
+        processErrorPromise: function ( grid, gridRow ) {
+          return function() {
+            delete gridRow.isSaving;
+            delete gridRow.rowEditSaveTimer;
+
+            gridRow.isError = true;
+            
+            if (!grid.rowEdit.errorRows){
+              grid.rowEdit.errorRows = [];
+            }
+            if (!service.isRowPresent( grid.rowEdit.errorRows, gridRow ) ){
+              grid.rowEdit.errorRows.push( gridRow );
+            }
+          };
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name removeRow
+         * @description  Removes a row from a cache of rows - either
+         * grid.rowEdit.errorRows or grid.rowEdit.dirtyRows.  If the row
+         * is not present silently does nothing. 
+         * @param {array} rowArray the array from which to remove the row
+         * @param {GridRow} gridRow the row that should be removed
+         */
+        removeRow: function( rowArray, removeGridRow ){
+          angular.forEach( rowArray, function( gridRow, index ){
+            if ( gridRow.uid === removeGridRow.uid ){
+              rowArray.splice( index, 1);
+            }
+          });
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name isRowPresent
+         * @description  Checks whether a row is already present
+         * in the given array 
+         * @param {array} rowArray the array in which to look for the row
+         * @param {GridRow} gridRow the row that should be looked for
+         */
+        isRowPresent: function( rowArray, removeGridRow ){
+          var present = false;
+          angular.forEach( rowArray, function( gridRow, index ){
+            if ( gridRow.uid === removeGridRow.uid ){
+              present = true;
+            }
+          });
+          return present;
+        },
+
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name flushDirtyRows
+         * @description Triggers a save event for all currently dirty rows, could
+         * be used where user presses a save button or navigates away from the page
+         * <pre>
+         *      gridApi.rowEdit.flushDirtyRows(grid)
+         * </pre>
+         * @param {object} grid the grid for which dirty rows should be flushed
+         * @returns {promise} a promise that represents the aggregate of all
+         * of the individual save promises - i.e. it will be resolved when all
+         * the individual save promises have been resolved.
+         * 
+         */
+        flushDirtyRows: function(grid){
+          var promises = [];
+          angular.forEach(grid.rowEdit.dirtyRows, function( gridRow ){
+            service.saveRow( grid, gridRow )();
+            promises.push( gridRow.rowEditSavePromise );
+          });
+          
+          return $q.all( promises );
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name endEditCell
+         * @description Receives an afterCellEdit event from the edit function,
+         * and sets flags as appropriate.  Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi. 
+         * @param {object} rowEntity the data entity for which the cell
+         * was edited
+         */        
+        endEditCell: function( rowEntity, colDef, newValue, previousValue ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ gridUtil.logError( 'Unable to find rowEntity in grid data, dirty flag cannot be set' ); return; }
+
+          if ( newValue !== previousValue || gridRow.isDirty ){
+            if ( !grid.rowEdit.dirtyRows ){
+              grid.rowEdit.dirtyRows = [];
+            }
+            
+            if ( !gridRow.isDirty ){
+              gridRow.isDirty = true;
+              grid.rowEdit.dirtyRows.push( gridRow );
+            }
+            
+            delete gridRow.isError;
+            
+            service.considerSetTimer( grid, gridRow );
+          }
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name beginEditCell
+         * @description Receives a beginCellEdit event from the edit function,
+         * and cancels any rowEditSaveTimers if present, as the user is still editing
+         * this row.  Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi. 
+         * @param {object} rowEntity the data entity for which the cell
+         * editing has commenced
+         */
+        beginEditCell: function( rowEntity, colDef ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ gridUtil.logError( 'Unable to find rowEntity in grid data, timer cannot be cancelled' ); return; }
+          
+          service.cancelTimer( grid, gridRow );
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name cancelEditCell
+         * @description Receives a cancelCellEdit event from the edit function,
+         * and if the row was already dirty, restarts the save timer.  If the row
+         * was not already dirty, then it's not dirty now either and does nothing.
+         * 
+         * Only the rowEntity parameter
+         * is processed, although other params are available.  Grid
+         * is automatically provided by the gridApi.
+         *  
+         * @param {object} rowEntity the data entity for which the cell
+         * editing was cancelled
+         */        
+        cancelEditCell: function( rowEntity, colDef ){
+          var grid = this.grid;
+          var gridRow = grid.getRow( rowEntity );
+          if ( !gridRow ){ gridUtil.logError( 'Unable to find rowEntity in grid data, timer cannot be set' ); return; }
+          
+          service.considerSetTimer( grid, gridRow );
+        },
+        
+        
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name navigate
+         * @description cellNav tells us that the selected cell has changed.  If
+         * the new row had a timer running, then stop it similar to in a beginCellEdit
+         * call.  If the old row is dirty and not the same as the new row, then 
+         * start a timer on it.
+         * @param {object} newRowCol the row and column that were selected
+         * @param {object} oldRowCol the row and column that was left
+         * 
+         */
+        navigate: function( newRowCol, oldRowCol ){
+          var grid = this.grid;
+          if ( newRowCol.row.rowEditSaveTimer ){
+            service.cancelTimer( grid, newRowCol.row );
+          }
+
+          if ( oldRowCol && oldRowCol.row && oldRowCol.row !== newRowCol.row ){
+            service.considerSetTimer( grid, oldRowCol.row );
+          }
+        },
+        
+        
+        /**
+         * @ngdoc property
+         * @propertyOf ui.grid.rowEdit.api:GridOptions
+         * @name rowEditWaitInterval
+         * @description How long the grid should wait for another change on this row
+         * before triggering a save (in milliseconds).  If set to -1, then saves are 
+         * never triggered by timer (implying that the user will call flushDirtyRows() 
+         * manually)
+         * 
+         * @example
+         * Setting the wait interval to 4 seconds
+         * <pre>
+         *   $scope.gridOptions = { rowEditWaitInterval: 4000 }
+         * </pre>
+         * 
+         */
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name considerSetTimer
+         * @description Consider setting a timer on this row (if it is dirty).  if there is a timer running 
+         * on the row and the row isn't currently saving, cancel it, using cancelTimer, then if the row is 
+         * dirty and not currently saving then set a new timer
+         * @param {object} grid the grid for which we are processing
+         * @param {GridRow} gridRow the row for which the timer should be adjusted
+         * 
+         */
+        considerSetTimer: function( grid, gridRow ){
+          service.cancelTimer( grid, gridRow );
+          
+          if ( gridRow.isDirty && !gridRow.isSaving ){
+            if ( grid.options.rowEditWaitInterval !== -1 ){
+              var waitTime = grid.options.rowEditWaitInterval ? grid.options.rowEditWaitInterval : 2000;
+              gridRow.rowEditSaveTimer = $interval( service.saveRow( grid, gridRow ), waitTime, 1);
+            }
+          }
+        },
+        
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.service:uiGridRowEditService
+         * @name cancelTimer
+         * @description cancel the $interval for any timer running on this row
+         * then delete the timer itself
+         * @param {object} grid the grid for which we are processing
+         * @param {GridRow} gridRow the row for which the timer should be adjusted
+         * 
+         */
+        cancelTimer: function( grid, gridRow ){
+          if ( gridRow.rowEditSaveTimer && !gridRow.isSaving ){
+            $interval.cancel(gridRow.rowEditSaveTimer);
+            delete gridRow.rowEditSaveTimer;
+          }
+        },
+
+
+        /**
+         * @ngdoc method
+         * @methodOf ui.grid.rowEdit.api:PublicApi
+         * @name setRowsDirty
+         * @description Sets each of the rows passed in dataRows
+         * to be dirty.  note that if you have only just inserted the
+         * rows into your data you will need to wait for a $digest cycle
+         * before the gridRows are present - so often you would wrap this
+         * call in a $interval or $timeout
+         * <pre>
+         *      $interval( function() {
+         *        gridApi.rowEdit.setRowsDirty(grid, myDataRows);
+         *      }, 0, 1);
+         * </pre>
+         * @param {object} grid the grid for which rows should be set dirty
+         * @param {array} dataRows the data entities for which the gridRows
+         * should be set dirty.  
+         * 
+         */
+        setRowsDirty: function( grid, myDataRows ) {
+          var gridRow;
+          myDataRows.forEach( function( value, index ){
+            gridRow = grid.getRow( value );
+            if ( gridRow ){
+              if ( !grid.rowEdit.dirtyRows ){
+                grid.rowEdit.dirtyRows = [];
+              }
+              
+              if ( !gridRow.isDirty ){
+                gridRow.isDirty = true;
+                grid.rowEdit.dirtyRows.push( gridRow );
+              }
+              
+              delete gridRow.isError;
+              
+              service.considerSetTimer( grid, gridRow );
+            } else {
+              gridUtil.logError( "requested row not found in rowEdit.setRowsDirty, row was: " + value );
+            }
+          });
+        }
+        
+        
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.rowEdit.directive:uiGridEdit
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds row editing features to the ui-grid-edit directive.
+   *
+   */
+  module.directive('uiGridRowEdit', ['gridUtil', 'uiGridRowEditService', 'uiGridEditConstants', 
+  function (gridUtil, uiGridRowEditService, uiGridEditConstants) {
+    return {
+      replace: true,
+      priority: 0,
+      require: '^uiGrid',
+      scope: false,
+      compile: function () {
+        return {
+          pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+            uiGridRowEditService.initializeGrid($scope, uiGridCtrl.grid);
+          },
+          post: function ($scope, $elm, $attrs, uiGridCtrl) {            
+          }
+        };
+      }
+    };
+  }]);
+
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.rowEdit.directive:uiGridViewport
+   *  @element div
+   *
+   *  @description Stacks on top of ui.grid.uiGridViewport to alter the attributes used
+   *  for the grid row to allow coloring of saving and error rows
+   */
+  module.directive('uiGridViewport',
+    ['$compile', 'uiGridConstants', 'gridUtil', '$parse',
+      function ($compile, uiGridConstants, gridUtil, $parse) {
+        return {
+          priority: -200, // run after default  directive
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+            
+            var existingNgClass = rowRepeatDiv.attr("ng-class");
+            var newNgClass = '';
+            if ( existingNgClass ) {
+              newNgClass = existingNgClass.slice(0, -1) + ", 'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}";
+            } else {
+              newNgClass = "{'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}";
+            }
+            rowRepeatDiv.attr("ng-class", newNgClass);
+
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+})();
+
+(function () {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name ui.grid.selection
+   * @description
+   *
+   *  # ui.grid.selection
+   * This module provides row selection
+   * <br/>
+   * <br/>
+   *
+   * <div doc-module-components="ui.grid.selection"></div>
+   */
+
+  var module = angular.module('ui.grid.selection', ['ui.grid']);
+
+  /**
+   *  @ngdoc object
+   *  @name ui.grid.selection.constant:uiGridSelectionConstants
+   *
+   *  @description constants available in selection module
+   */
+  module.constant('uiGridSelectionConstants', {
+    featureName: "selection",
+    selectionRowHeaderColName: 'selectionRowHeaderCol'
+  });
+
+  /**
+   *  @ngdoc service
+   *  @name ui.grid.selection.service:uiGridSelectionService
+   *
+   *  @description Services for selection features
+   */
+  module.service('uiGridSelectionService', ['$q', '$templateCache', 'uiGridSelectionConstants', 'gridUtil',
+    function ($q, $templateCache, uiGridSelectionConstants, gridUtil) {
+
+      var service = {
+
+        initializeGrid: function (grid) {
+
+          //add feature namespace and any properties to grid for needed state
+          grid.selection = {};
+          grid.selection.lastSelectedRow = null;
+          grid.selection.selectAll = false;
+
+          service.defaultGridOptions(grid.options);
+
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.selection.api:PublicApi
+           *
+           *  @description Public Api for selection feature
+           */
+          var publicApi = {
+            events: {
+              selection: {
+                /**
+                 * @ngdoc event
+                 * @name rowSelectionChanged
+                 * @eventOf  ui.grid.selection.api:PublicApi
+                 * @description  is raised after the row.isSelected state is changed
+                 * @param {GridRow} row the row that was selected/deselected
+                 */
+                rowSelectionChanged: function (scope, row) {
+                },
+                /**
+                 * @ngdoc event
+                 * @name rowSelectionChangedBatch
+                 * @eventOf  ui.grid.selection.api:PublicApi
+                 * @description  is raised after the row.isSelected state is changed
+                 * in bulk, if the `enableSelectionBatchEvent` option is set to true
+                 * (which it is by default).  This allows more efficient processing 
+                 * of bulk events.
+                 * @param {array} rows the rows that were selected/deselected
+                 */
+                rowSelectionChangedBatch: function (scope, rows) {
+                }
+              }
+            },
+            methods: {
+              selection: {
+                /**
+                 * @ngdoc function
+                 * @name toggleRowSelection
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Toggles data row as selected or unselected
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                toggleRowSelection: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect, grid.options.noUnselect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectRow
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Select the data row
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                selectRow: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null && !row.isSelected) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect, grid.options.noUnselect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectRowByVisibleIndex
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Select the specified row by visible index (i.e. if you
+                 * specify row 0 you'll get the first visible row selected).  In this context
+                 * visible means of those rows that are theoretically visible (i.e. not filtered),
+                 * rather than rows currently rendered on the screen.
+                 * @param {number} index index within the rowsVisible array
+                 */
+                selectRowByVisibleIndex: function ( rowNum ) {
+                  var row = grid.renderContainers.body.visibleRowCache[rowNum];
+                  if (row !== null && !row.isSelected) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect, grid.options.noUnselect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name unSelectRow
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description UnSelect the data row
+                 * @param {object} rowEntity gridOptions.data[] array instance
+                 */
+                unSelectRow: function (rowEntity) {
+                  var row = grid.getRow(rowEntity);
+                  if (row !== null && row.isSelected) {
+                    service.toggleRowSelection(grid, row, grid.options.multiSelect, grid.options.noUnselect);
+                  }
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectAllRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Selects all rows.  Does nothing if multiSelect = false
+                 */
+                selectAllRows: function () {
+                  if (grid.options.multiSelect === false) {
+                    return;
+                  }
+
+                  var changedRows = [];
+                  grid.rows.forEach(function (row) {
+                    if ( !row.isSelected ){
+                      row.isSelected = true;
+                      service.decideRaiseSelectionEvent( grid, row, changedRows );
+                    }
+                  });
+                  service.decideRaiseSelectionBatchEvent( grid, changedRows );
+                },
+                /**
+                 * @ngdoc function
+                 * @name selectAllVisibleRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Selects all visible rows.  Does nothing if multiSelect = false
+                 */
+                selectAllVisibleRows: function () {
+                  if (grid.options.multiSelect === false) {
+                    return;
+                  }
+
+                  var changedRows = [];
+                  grid.rows.forEach(function (row) {
+                    if (row.visible) {
+                      if (!row.isSelected){
+                        row.isSelected = true;
+                        service.decideRaiseSelectionEvent( grid, row, changedRows );
+                      }
+                    } else {
+                      if (row.isSelected){
+                        row.isSelected = false;
+                        service.decideRaiseSelectionEvent( grid, row, changedRows );
+                      }
+                    }
+                  });
+                  service.decideRaiseSelectionBatchEvent( grid, changedRows );
+                },
+                /**
+                 * @ngdoc function
+                 * @name clearSelectedRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Unselects all rows
+                 */
+                clearSelectedRows: function () {
+                  service.clearSelectedRows(grid);
+                },
+                /**
+                 * @ngdoc function
+                 * @name getSelectedRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description returns all selectedRow's entity references
+                 */
+                getSelectedRows: function () {
+                  return service.getSelectedRows(grid).map(function (gridRow) {
+                    return gridRow.entity;
+                  });
+                },
+                /**
+                 * @ngdoc function
+                 * @name getSelectedGridRows
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description returns all selectedRow's as gridRows
+                 */
+                getSelectedGridRows: function () {
+                  return service.getSelectedRows(grid);
+                },
+                /**
+                 * @ngdoc function
+                 * @name setMultiSelect
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Sets the current gridOption.multiSelect to true or false
+                 * @param {bool} multiSelect true to allow multiple rows
+                 */
+                setMultiSelect: function (multiSelect) {
+                  grid.options.multiSelect = multiSelect;
+                },
+                /**
+                 * @ngdoc function
+                 * @name setModifierKeysToMultiSelect
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Sets the current gridOption.modifierKeysToMultiSelect to true or false
+                 * @param {bool} modifierKeysToMultiSelect true to only allow multiple rows when using ctrlKey or shiftKey is used
+                 */
+                setModifierKeysToMultiSelect: function (modifierKeysToMultiSelect) {
+                  grid.options.modifierKeysToMultiSelect = modifierKeysToMultiSelect;
+                },
+                /**
+                 * @ngdoc function
+                 * @name getSelectAllState
+                 * @methodOf  ui.grid.selection.api:PublicApi
+                 * @description Returns whether or not the selectAll checkbox is currently ticked.  The
+                 * grid doesn't automatically select rows when you add extra data - so when you add data
+                 * you need to explicitly check whether the selectAll is set, and then call setVisible rows
+                 * if it is
+                 */
+                getSelectAllState: function () {
+                  return grid.selection.selectAll;
+                }
+                
+              }
+            }
+          };
+
+          grid.api.registerEventsFromObject(publicApi.events);
+
+          grid.api.registerMethodsFromObject(publicApi.methods);
+
+        },
+
+        defaultGridOptions: function (gridOptions) {
+          //default option to true unless it was explicitly set to false
+          /**
+           *  @ngdoc object
+           *  @name ui.grid.selection.api:GridOptions
+           *
+           *  @description GridOptions for selection feature, these are available to be  
+           *  set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
+           */
+
+          /**
+           *  @ngdoc object
+           *  @name enableRowSelection
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable row selection for entire grid.
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableRowSelection = gridOptions.enableRowSelection !== false;
+          /**
+           *  @ngdoc object
+           *  @name multiSelect
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable multiple row selection for entire grid
+           *  <br/>Defaults to true
+           */
+          gridOptions.multiSelect = gridOptions.multiSelect !== false;
+          /**
+           *  @ngdoc object
+           *  @name noUnselect
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Prevent a row from being unselected.  Works in conjunction
+           *  with `multiselect = false` and `gridApi.selection.selectRow()` to allow
+           *  you to create a single selection only grid - a row is always selected, you
+           *  can only select different rows, you can't unselect the row.
+           *  <br/>Defaults to false
+           */
+          gridOptions.noUnselect = gridOptions.noUnselect === true;
+          /**
+           *  @ngdoc object
+           *  @name modifierKeysToMultiSelect
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable multiple row selection only when using the ctrlKey or shiftKey. Requires multiSelect to be true.
+           *  <br/>Defaults to false
+           */
+          gridOptions.modifierKeysToMultiSelect = gridOptions.modifierKeysToMultiSelect === true;
+          /**
+           *  @ngdoc object
+           *  @name enableRowHeaderSelection
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable a row header to be used for selection
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableRowHeaderSelection = gridOptions.enableRowHeaderSelection !== false;
+          /**
+           *  @ngdoc object
+           *  @name enableSelectAll
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description Enable the select all checkbox at the top of the selectionRowHeader
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableSelectAll = gridOptions.enableSelectAll !== false;
+          /**
+           *  @ngdoc object
+           *  @name enableSelectionBatchEvent
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description If selected rows are changed in bulk, either via the API or
+           *  via the selectAll checkbox, then a separate event is fired.  Setting this
+           *  option to false will cause the rowSelectionChanged event to be called multiple times
+           *  instead  
+           *  <br/>Defaults to true
+           */
+          gridOptions.enableSelectionBatchEvent = gridOptions.enableSelectionBatchEvent !== false;
+          /**
+           *  @ngdoc object
+           *  @name selectionRowHeaderWidth
+           *  @propertyOf  ui.grid.selection.api:GridOptions
+           *  @description can be used to set a custom width for the row header selection column
+           *  <br/>Defaults to 30px
+           */
+          gridOptions.selectionRowHeaderWidth = angular.isDefined(gridOptions.selectionRowHeaderWidth) ? gridOptions.selectionRowHeaderWidth : 30;
+        },
+
+        /**
+         * @ngdoc function
+         * @name toggleRowSelection
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Toggles row as selected or unselected
+         * @param {Grid} grid grid object
+         * @param {GridRow} row row to select or deselect
+         * @param {bool} multiSelect if false, only one row at time can be selected
+         * @param {bool} noUnselect if true then rows cannot be unselected
+         */
+        toggleRowSelection: function (grid, row, multiSelect, noUnselect) {
+          var selected = row.isSelected;
+
+          if (!multiSelect && !selected) {
+            service.clearSelectedRows(grid);
+          } else if (!multiSelect && selected) {
+            var selectedRows = service.getSelectedRows(grid);
+            if (selectedRows.length > 1) {
+              selected = false; // Enable reselect of the row
+              service.clearSelectedRows(grid);
+            }
+          }
+          
+          if (selected && noUnselect){
+            // don't deselect the row 
+          } else {
+            row.isSelected = !selected;
+            if (row.isSelected === true) {
+              grid.selection.lastSelectedRow = row;
+            }
+            grid.api.selection.raise.rowSelectionChanged(row);
+          }
+        },
+        /**
+         * @ngdoc function
+         * @name shiftSelect
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description selects a group of rows from the last selected row using the shift key
+         * @param {Grid} grid grid object
+         * @param {GridRow} clicked row
+         * @param {bool} multiSelect if false, does nothing this is for multiSelect only
+         */
+        shiftSelect: function (grid, row, multiSelect) {
+          if (!multiSelect) {
+            return;
+          }
+          var selectedRows = service.getSelectedRows(grid);
+          var fromRow = selectedRows.length > 0 ? grid.renderContainers.body.visibleRowCache.indexOf(grid.selection.lastSelectedRow) : 0;
+          var toRow = grid.renderContainers.body.visibleRowCache.indexOf(row);
+          //reverse select direction
+          if (fromRow > toRow) {
+            var tmp = fromRow;
+            fromRow = toRow;
+            toRow = tmp;
+          }
+          
+          var changedRows = [];
+          for (var i = fromRow; i <= toRow; i++) {
+            var rowToSelect = grid.renderContainers.body.visibleRowCache[i];
+            if (rowToSelect) {
+              if ( !rowToSelect.isSelected ){
+                rowToSelect.isSelected = true;
+                grid.selection.lastSelectedRow = rowToSelect;
+                service.decideRaiseSelectionEvent( grid, rowToSelect, changedRows );
+              }
+            }
+          }
+          service.decideRaiseSelectionBatchEvent( grid, changedRows );
+        },
+        /**
+         * @ngdoc function
+         * @name getSelectedRows
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Returns all the selected rows
+         * @param {Grid} grid grid object
+         */
+        getSelectedRows: function (grid) {
+          return grid.rows.filter(function (row) {
+            return row.isSelected;
+          });
+        },
+
+        /**
+         * @ngdoc function
+         * @name clearSelectedRows
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Clears all selected rows
+         * @param {Grid} grid grid object
+         */
+        clearSelectedRows: function (grid) {
+          var changedRows = [];
+          service.getSelectedRows(grid).forEach(function (row) {
+            if ( row.isSelected ){
+              row.isSelected = false;
+              service.decideRaiseSelectionEvent( grid, row, changedRows );
+            }
+          });
+          service.decideRaiseSelectionBatchEvent( grid, changedRows );
+        },
+        
+        /**
+         * @ngdoc function
+         * @name decideRaiseSelectionEvent
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Decides whether to raise a single event or a batch event
+         * @param {Grid} grid grid object
+         * @param {GridRow} row row that has changed
+         * @param {array} changedRows an array to which we can append the changed
+         * row if we're doing batch events
+         */
+        decideRaiseSelectionEvent: function( grid, row, changedRows ){
+          if ( !grid.options.enableSelectionBatchEvent ){
+            grid.api.selection.raise.rowSelectionChanged(row);
+          } else {
+            changedRows.push(row);
+          }
+        },
+        
+        /**
+         * @ngdoc function
+         * @name raiseSelectionEvent
+         * @methodOf  ui.grid.selection.service:uiGridSelectionService
+         * @description Decides whether we need to raise a batch event, and 
+         * raises it if we do.
+         * @param {Grid} grid grid object
+         * @param {array} changedRows an array of changed rows, only populated
+         * if we're doing batch events
+         */
+        decideRaiseSelectionBatchEvent: function( grid, changedRows ){
+          if ( changedRows.length > 0 ){
+            grid.api.selection.raise.rowSelectionChangedBatch(changedRows);
+          }
+        }        
+      };
+
+      return service;
+
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridSelection
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Adds selection features to grid
+   *
+   *  @example
+   <example module="app">
+   <file name="app.js">
+   var app = angular.module('app', ['ui.grid', 'ui.grid.selection']);
+
+   app.controller('MainCtrl', ['$scope', function ($scope) {
+      $scope.data = [
+        { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+      ];
+
+      $scope.columnDefs = [
+        {name: 'name', enableCellEdit: true},
+        {name: 'title', enableCellEdit: true}
+      ];
+    }]);
+   </file>
+   <file name="index.html">
+   <div ng-controller="MainCtrl">
+   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-selection></div>
+   </div>
+   </file>
+   </example>
+   */
+  module.directive('uiGridSelection', ['uiGridSelectionConstants', 'uiGridSelectionService', '$templateCache',
+    function (uiGridSelectionConstants, uiGridSelectionService, $templateCache) {
+      return {
+        replace: true,
+        priority: 0,
+        require: '^uiGrid',
+        scope: false,
+        compile: function () {
+          return {
+            pre: function ($scope, $elm, $attrs, uiGridCtrl) {
+              uiGridSelectionService.initializeGrid(uiGridCtrl.grid);
+              if (uiGridCtrl.grid.options.enableRowHeaderSelection) {
+                var selectionRowHeaderDef = {
+                  name: uiGridSelectionConstants.selectionRowHeaderColName,
+                  displayName: '',
+                  width:  uiGridCtrl.grid.options.selectionRowHeaderWidth,
+                  cellTemplate: 'ui-grid/selectionRowHeader',
+                  headerCellTemplate: 'ui-grid/selectionHeaderCell',
+                  enableColumnResizing: false,
+                  enableColumnMenu: false
+                };
+
+                uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef);
+              }
+            },
+            post: function ($scope, $elm, $attrs, uiGridCtrl) {
+
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridSelectionRowHeaderButtons', ['$templateCache', 'uiGridSelectionService',
+    function ($templateCache, uiGridSelectionService) {
+      return {
+        replace: true,
+        restrict: 'E',
+        template: $templateCache.get('ui-grid/selectionRowHeaderButtons'),
+        scope: true,
+        require: '^uiGrid',
+        link: function($scope, $elm, $attrs, uiGridCtrl) {
+          var self = uiGridCtrl.grid;
+          $scope.selectButtonClick = function(row, evt) {
+            if (evt.shiftKey) {
+              uiGridSelectionService.shiftSelect(self, row, self.options.multiSelect);
+            }
+            else if (evt.ctrlKey || evt.metaKey) {
+              uiGridSelectionService.toggleRowSelection(self, row, self.options.multiSelect, self.options.noUnselect); 
+            }
+            else {
+              uiGridSelectionService.toggleRowSelection(self, row, (self.options.multiSelect && !self.options.modifierKeysToMultiSelect), self.options.noUnselect);
+            }
+          };
+        }
+      };
+    }]);
+
+  module.directive('uiGridSelectionSelectAllButtons', ['$templateCache', 'uiGridSelectionService',
+    function ($templateCache, uiGridSelectionService) {
+      return {
+        replace: true,
+        restrict: 'E',
+        template: $templateCache.get('ui-grid/selectionSelectAllButtons'),
+        scope: false,
+        link: function($scope, $elm, $attrs, uiGridCtrl) {
+          var self = $scope.col.grid;
+          
+          $scope.headerButtonClick = function(row, evt) {
+            if ( self.selection.selectAll ){
+              uiGridSelectionService.clearSelectedRows(self);
+              if ( self.options.noUnselect ){
+                self.api.selection.selectRowByVisibleIndex(0);
+              }
+              self.selection.selectAll = false;
+            } else {
+              if ( self.options.multiSelect ){
+                self.api.selection.selectAllVisibleRows();
+                self.selection.selectAll = true;
+              }
+            }
+          };
+        }
+      };
+    }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridViewport
+   *  @element div
+   *
+   *  @description Stacks on top of ui.grid.uiGridViewport to alter the attributes used
+   *  for the grid row
+   */
+  module.directive('uiGridViewport',
+    ['$compile', 'uiGridConstants', 'uiGridSelectionConstants', 'gridUtil', '$parse', 'uiGridSelectionService',
+      function ($compile, uiGridConstants, uiGridSelectionConstants, gridUtil, $parse, uiGridSelectionService) {
+        return {
+          priority: -200, // run after default  directive
+          scope: false,
+          compile: function ($elm, $attrs) {
+            var rowRepeatDiv = angular.element($elm.children().children()[0]);
+
+            var existingNgClass = rowRepeatDiv.attr("ng-class");
+            var newNgClass = '';
+            if ( existingNgClass ) {
+              newNgClass = existingNgClass.slice(0, -1) + ",'ui-grid-row-selected': row.isSelected}";
+            } else {
+              newNgClass = "{'ui-grid-row-selected': row.isSelected}";
+            }
+            rowRepeatDiv.attr("ng-class", newNgClass);
+
+            return {
+              pre: function ($scope, $elm, $attrs, controllers) {
+
+              },
+              post: function ($scope, $elm, $attrs, controllers) {
+              }
+            };
+          }
+        };
+      }]);
+
+  /**
+   *  @ngdoc directive
+   *  @name ui.grid.selection.directive:uiGridCell
+   *  @element div
+   *  @restrict A
+   *
+   *  @description Stacks on top of ui.grid.uiGridCell to provide selection feature
+   */
+  module.directive('uiGridCell',
+    ['$compile', 'uiGridConstants', 'uiGridSelectionConstants', 'gridUtil', '$parse', 'uiGridSelectionService',
+      function ($compile, uiGridConstants, uiGridSelectionConstants, gridUtil, $parse, uiGridSelectionService) {
+        return {
+          priority: -200, // run after default uiGridCell directive
+          restrict: 'A',
+          scope: false,
+          link: function ($scope, $elm, $attrs) {
+
+            if ($scope.grid.options.enableRowSelection && !$scope.grid.options.enableRowHeaderSelection) {
+              $elm.addClass('ui-grid-disable-selection');
+              registerRowSelectionEvents();
+            }
+
+            function registerRowSelectionEvents() {
+              var touchStartTime = 0;
+              var touchTimeout = 300;
+              var selectCells = function(evt){
+                if (evt.shiftKey) {
+                  uiGridSelectionService.shiftSelect($scope.grid, $scope.row, $scope.grid.options.multiSelect);
+                }
+                else if (evt.ctrlKey || evt.metaKey) {
+                  uiGridSelectionService.toggleRowSelection($scope.grid, $scope.row, $scope.grid.options.multiSelect, $scope.grid.options.noUnselect);
+                }
+                else {
+                  uiGridSelectionService.toggleRowSelection($scope.grid, $scope.row, ($scope.grid.options.multiSelect && !$scope.grid.options.modifierKeysToMultiSelect), $scope.grid.options.noUnselect);
+                }
+                $scope.$apply();
+              };
+
+              $elm.on('touchstart', function(event) {
+                touchStartTime = (new Date()).getTime();
+              });
+
+              $elm.on('touchend', function (evt) {
+                var touchEndTime = (new Date()).getTime();
+                var touchTime = touchEndTime - touchStartTime;
+
+                if (touchTime < touchTimeout ) {
+                  // short touch
+                  selectCells(evt);
+                }
+              });
+
+              $elm.on('click', function (evt) {
+                selectCells(evt);
+              });
+            }
+          }
+        };
+      }]);
+
+})();
+
+angular.module('ui.grid').run(['$templateCache', function($templateCache) {
+  'use strict';
+
+  $templateCache.put('ui-grid/ui-grid-footer',
+    "<div class=\"ui-grid-footer-panel\"><div ui-grid-group-panel ng-show=\"grid.options.showGroupPanel\"></div><div class=\"ui-grid-footer ui-grid-footer-viewport\"><div class=\"ui-grid-footer-canvas\"><div ng-repeat=\"col in colContainer.renderedColumns track by col.colDef.name\" ui-grid-footer-cell col=\"col\" render-index=\"$index\" class=\"ui-grid-footer-cell clearfix\" ng-style=\"$index === 0 && colContainer.columnStyle($index)\"></div></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-group-panel',
+    "<div class=\"ui-grid-group-panel\"><div ui-t=\"groupPanel.description\" class=\"description\" ng-show=\"groupings.length == 0\"></div><ul ng-show=\"groupings.length > 0\" class=\"ngGroupList\"><li class=\"ngGroupItem\" ng-repeat=\"group in configGroups\"><span class=\"ngGroupElement\"><span class=\"ngGroupName\">{{group.displayName}} <span ng-click=\"removeGroup($index)\" class=\"ngRemoveGroup\">x</span></span> <span ng-hide=\"$last\" class=\"ngGroupArrow\"></span></span></li></ul></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-header',
+    "<div class=\"ui-grid-header\"><div class=\"ui-grid-top-panel\"><div ui-grid-group-panel ng-show=\"grid.options.showGroupPanel\"></div><div class=\"ui-grid-header-viewport\"><div class=\"ui-grid-header-canvas\"><div class=\"ui-grid-header-cell clearfix\" ng-repeat=\"col in colContainer.renderedColumns track by col.colDef.name\" ui-grid-header-cell col=\"col\" render-index=\"$index\" ng-style=\"$index === 0 && colContainer.columnStyle($index)\"></div></div></div><div ui-grid-menu></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-menu-button',
+    "<div class=\"ui-grid-menu-button\" ng-click=\"toggleMenu()\"><div class=\"ui-grid-icon-container\"><i class=\"ui-grid-icon-menu\">&nbsp;</i></div><div ui-grid-menu menu-items=\"menuItems\"></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-no-header',
+    "<div class=\"ui-grid-top-panel\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-row',
+    "<div ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" ui-grid-cell></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid',
+    "<div ui-i18n=\"en\" class=\"ui-grid\"><!-- TODO (c0bra): add \"scoped\" attr here, eventually? --><style ui-grid-style>.grid{{ grid.id }} {\n" +
+    "      /* Styles for the grid */\n" +
+    "    }\n" +
+    "\n" +
+    "    .grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {\n" +
+    "      height: {{ grid.options.rowHeight }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    .grid{{ grid.id }} .ui-grid-row:last-child .ui-grid-cell {\n" +
+    "      border-bottom-width: {{ ((grid.getTotalRowHeight() < grid.getViewportHeight()) && '1') || '0' }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    {{ grid.verticalScrollbarStyles }}\n" +
+    "    {{ grid.horizontalScrollbarStyles }}\n" +
+    "\n" +
+    "    .ui-grid[dir=rtl] .ui-grid-viewport {\n" +
+    "      padding-left: {{ grid.verticalScrollbarWidth }}px;\n" +
+    "    }\n" +
+    "\n" +
+    "    {{ grid.customStyles }}</style><div ui-grid-menu-button ng-if=\"grid.options.enableGridMenu\"></div><div ui-grid-render-container container-id=\"'body'\" col-container-name=\"'body'\" row-container-name=\"'body'\" bind-scroll-horizontal=\"true\" bind-scroll-vertical=\"true\" enable-horizontal-scrollbar=\"grid.options.enableHorizontalScrollbar\" enable-vertical-scrollbar=\"grid.options.enableVerticalScrollbar\"></div><div ui-grid-column-menu ng-if=\"grid.options.enableColumnMenus\"></div><div ng-transclude></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridCell',
+    "<div class=\"ui-grid-cell-contents\">{{COL_FIELD CUSTOM_FILTERS}}</div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridColumnFilter',
+    "<li class=\"ui-grid-menu-item ui-grid-clearfix ui-grid-column-filter\" ng-show=\"itemShown()\" ng-click=\"$event.stopPropagation();\"><div class=\"input-container\"><input class=\"column-filter-input\" type=\"text\" ng-model=\"item.model\" placeholder=\"{{ i18n.search.placeholder }}\"><div class=\"column-filter-cancel-icon-container\"><i class=\"ui-grid-filter-cancel ui-grid-icon-cancel column-filter-cancel-icon\">&nbsp;</i></div></div><div style=\"button-container\" ng-click=\"item.action($event)\"><div class=\"ui-grid-button\"><i class=\"ui-grid-icon-search\">&nbsp;</i></div></div></li>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridColumnMenu',
+    "<div class=\"ui-grid-column-menu\"><div ui-grid-menu menu-items=\"menuItems\"><!-- <div class=\"ui-grid-column-menu\">\n" +
+    "    <div class=\"inner\" ng-show=\"menuShown\">\n" +
+    "      <ul>\n" +
+    "        <div ng-show=\"grid.options.enableSorting\">\n" +
+    "          <li ng-click=\"sortColumn($event, asc)\" ng-class=\"{ 'selected' : col.sort.direction == asc }\"><i class=\"ui-grid-icon-sort-alt-up\"></i> Sort Ascending</li>\n" +
+    "          <li ng-click=\"sortColumn($event, desc)\" ng-class=\"{ 'selected' : col.sort.direction == desc }\"><i class=\"ui-grid-icon-sort-alt-down\"></i> Sort Descending</li>\n" +
+    "          <li ng-show=\"col.sort.direction\" ng-click=\"unsortColumn()\"><i class=\"ui-grid-icon-cancel\"></i> Remove Sort</li>\n" +
+    "        </div>\n" +
+    "      </ul>\n" +
+    "    </div>\n" +
+    "  </div> --></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridFooterCell',
+    "<div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><div>{{ col.getAggregationValue() }}</div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridHeaderCell',
+    "<div ng-class=\"{ 'sortable': sortable }\"><div class=\"ui-grid-vertical-bar\">&nbsp;</div><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><span>{{ col.displayName CUSTOM_FILTERS }}</span> <span ui-grid-visible=\"col.sort.direction\" ng-class=\"{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }\">&nbsp;</span></div><div class=\"ui-grid-column-menu-button\" ng-if=\"grid.options.enableColumnMenus && !col.isRowHeader  && col.colDef.enableColumnMenu !== false\" class=\"ui-grid-column-menu-button\" ng-click=\"toggleMenu($event)\"><i class=\"ui-grid-icon-angle-down\">&nbsp;</i></div><div ng-if=\"filterable\" class=\"ui-grid-filter-container\" ng-repeat=\"colFilter in col.filters\"><input type=\"text\" class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-click=\"$event.stopPropagation()\" ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\"><div class=\"ui-grid-filter-button\" ng-click=\"colFilter.term = null\"><i class=\"ui-grid-icon-cancel\" ng-show=\"!!colFilter.term\">&nbsp;</i><!-- use !! because angular interprets 'f' as false --></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridMenu',
+    "<div class=\"ui-grid-menu\" ng-if=\"shown\"><div class=\"ui-grid-menu-mid\" ng-show=\"shownMid\"><div class=\"ui-grid-menu-inner\"><ul class=\"ui-grid-menu-items\"><li ng-repeat=\"item in menuItems\" ui-grid-menu-item action=\"item.action\" title=\"item.title\" active=\"item.active\" icon=\"item.icon\" shown=\"item.shown\" context=\"item.context\" template-url=\"item.templateUrl\"></li></ul></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridMenuItem',
+    "<li class=\"ui-grid-menu-item\" ng-click=\"itemAction($event, title)\" ng-show=\"itemShown()\" ng-class=\"{ 'ui-grid-menu-item-active' : active() }\"><i ng-class=\"icon\"></i> {{ title }}</li>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridRenderContainer',
+    "<div class=\"ui-grid-render-container\"><div ui-grid-header></div><div ui-grid-viewport></div><div ui-grid-footer ng-if=\"grid.options.showFooter\"></div><!-- native scrolling --><div ui-grid-native-scrollbar ng-if=\"enableVerticalScrollbar\" type=\"vertical\"></div><div ui-grid-native-scrollbar ng-if=\"enableHorizontalScrollbar\" type=\"horizontal\"></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/uiGridViewport',
+    "<div class=\"ui-grid-viewport\"><div class=\"ui-grid-canvas\"><div ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by $index\" class=\"ui-grid-row\" ng-style=\"containerCtrl.rowStyle(rowRenderIndex)\"><div ui-grid-row=\"row\" row-render-index=\"rowRenderIndex\"></div></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/cellEditor',
+    "<div><form name=\"inputForm\"><input type=\"{{inputType}}\" ng-class=\"'colt' + col.uid\" ui-grid-editor ng-model=\"MODEL_COL_FIELD\"></form></div>"
+  );
+
+
+  $templateCache.put('ui-grid/dropdownEditor',
+    "<div><form name=\"inputForm\"><select ng-class=\"'colt' + col.uid\" ui-grid-edit-dropdown ng-model=\"MODEL_COL_FIELD\" ng-options=\"field[editDropdownIdLabel] as field[editDropdownValueLabel] CUSTOM_FILTERS for field in editDropdownOptionsArray\"></select></form></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableRow',
+    "<div ui-grid-expandable-row ng-if=\"expandableRow.shouldRenderExpand()\" class=\"expandableRow\" style=\"float:left; margin-top: 1px; margin-bottom: 1px\" ng-style=\"{width: (grid.renderContainers.body.getCanvasWidth() - grid.verticalScrollbarWidth) + 'px'\n" +
+    "     , height: grid.options.expandableRowHeight + 'px'}\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableRowHeader',
+    "<div class=\"ui-grid-row-header-cell ui-grid-expandable-buttons-cell\"><div class=\"ui-grid-cell-contents\"><i ng-class=\"{ 'ui-grid-icon-plus-squared' : !row.isExpanded, 'ui-grid-icon-minus-squared' : row.isExpanded }\" ng-click=\"grid.api.expandable.toggleRowExpansion(row.entity)\"></i></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/expandableScrollFiller',
+    "<div ng-if=\"expandableRow.shouldRenderFiller()\" style=\"float:left; margin-top: 2px; margin-bottom: 2px\" ng-style=\"{ width: (grid.getViewportWidth()) + 'px',\n" +
+    "              height: grid.options.expandableRowHeight + 'px', 'margin-left': grid.options.rowHeader.rowHeaderWidth + 'px' }\"><i class=\"ui-grid-icon-spin5 ui-grid-animate-spin\" ng-style=\"{ 'margin-top': ( grid.options.expandableRowHeight/2 - 5) + 'px',\n" +
+    "            'margin-left' : ((grid.getViewportWidth() - grid.options.rowHeader.rowHeaderWidth)/2 - 5) + 'px' }\"></i></div>"
+  );
+
+
+  $templateCache.put('ui-grid/csvLink',
+    "<span class=\"ui-grid-exporter-csv-link-span\"><a href=\"data:text/csv;charset=UTF-8,CSV_CONTENT\">LINK_LABEL</a></span>"
+  );
+
+
+  $templateCache.put('ui-grid/importerMenuItem',
+    "<li class=\"ui-grid-menu-item\"><form><input class=\"ui-grid-importer-file-chooser\" type=\"file\" id=\"files\" name=\"files[]\"></form></li>"
+  );
+
+
+  $templateCache.put('ui-grid/importerMenuItemContainer',
+    "<div ui-grid-importer-menu-item></div>"
+  );
+
+
+  $templateCache.put('ui-grid/ui-grid-paging',
+    "<div class=\"ui-grid-pager-panel\" ui-grid-pager><div class=\"ui-grid-pager-container\"><div class=\"ui-grid-pager-control\"><button type=\"button\" ng-click=\"pageToFirst()\" ng-disabled=\"cantPageBackward()\"><div class=\"first-triangle\"><div class=\"first-bar\"></div></div></button> <button type=\"button\" ng-click=\"pageBackward()\" ng-disabled=\"cantPageBackward()\"><div class=\"first-triangle prev-triangle\"></div></button> <input type=\"number\" ng-model=\"grid.options.pagingCurrentPage\" min=\"1\" max=\"{{currentMaxPages}}\" required> <span class=\"ui-grid-pager-max-pages-number\" ng-show=\"currentMaxPages > 0\">/ {{currentMaxPages}}</span> <button type=\"button\" ng-click=\"pageForward()\" ng-disabled=\"cantPageForward()\"><div class=\"last-triangle next-triangle\"></div></button> <button type=\"button\" ng-click=\"pageToLast()\" ng-disabled=\"cantPageToLast()\"><div class=\"last-triangle\"><div class=\"last-bar\"></div></div></button></div><div class=\"ui-grid-pager-row-count-picker\"><select ng-model=\"grid.options.pagingPageSize\" ng-options=\"o as o for o in grid.options.pagingPageSizes\"></select><span class=\"ui-grid-pager-row-count-label\">&nbsp;{{sizesLabel}}</span></div></div><div class=\"ui-grid-pager-count-container\"><div class=\"ui-grid-pager-count\"><span ng-show=\"grid.options.totalItems > 0\">{{showingLow}} - {{showingHigh}} of {{grid.options.totalItems}} {{totalItemsLabel}}</span></div></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/columnResizer',
+    "<div ui-grid-column-resizer ng-if=\"grid.options.enableColumnResizing\" class=\"ui-grid-column-resizer\" col=\"col\" position=\"right\" render-index=\"renderIndex\"></div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionHeaderCell',
+    "<div><div class=\"ui-grid-vertical-bar\">&nbsp;</div><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><ui-grid-selection-select-all-buttons ng-if=\"grid.options.enableSelectAll\"></ui-grid-selection-select-all-buttons></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionRowHeader',
+    "<div class=\"ui-grid-row-header-cell ui-grid-disable-selection\"><div class=\"ui-grid-cell-contents\"><ui-grid-selection-row-header-buttons></ui-grid-selection-row-header-buttons></div></div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionRowHeaderButtons',
+    "<div class=\"ui-grid-selection-row-header-buttons ui-grid-icon-ok\" ng-class=\"{'ui-grid-row-selected': row.isSelected}\" ng-click=\"selectButtonClick(row, $event)\">&nbsp;</div>"
+  );
+
+
+  $templateCache.put('ui-grid/selectionSelectAllButtons',
+    "<div class=\"ui-grid-selection-row-header-buttons ui-grid-icon-ok\" ng-class=\"{'ui-grid-all-selected': grid.selection.selectAll}\" ng-click=\"headerButtonClick($event)\">&nbsp;</div>"
+  );
+
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.min.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid-unstable.min.js
new file mode 100644 (file)
index 0000000..680a65a
--- /dev/null
@@ -0,0 +1,8 @@
+/*! ui-grid - v3.0.0-rc.16-234dd76 - 2014-11-22
+* Copyright (c) 2014 ; License: MIT */
+!function(){"use strict";angular.module("ui.grid.i18n",[]),angular.module("ui.grid",["ui.grid.i18n"])}(),function(){"use strict";angular.module("ui.grid").constant("uiGridConstants",{LOG_DEBUG_MESSAGES:!0,LOG_WARN_MESSAGES:!0,LOG_ERROR_MESSAGES:!0,CUSTOM_FILTERS:/CUSTOM_FILTERS/g,COL_FIELD:/COL_FIELD/g,MODEL_COL_FIELD:/MODEL_COL_FIELD/g,DISPLAY_CELL_TEMPLATE:/DISPLAY_CELL_TEMPLATE/g,TEMPLATE_REGEXP:/<.+>/,FUNC_REGEXP:/(\([^)]*\))?$/,DOT_REGEXP:/\./g,APOS_REGEXP:/'/g,BRACKET_REGEXP:/^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,COL_CLASS_PREFIX:"ui-grid-col",events:{GRID_SCROLL:"uiGridScroll",COLUMN_MENU_SHOWN:"uiGridColMenuShown",ITEM_DRAGGING:"uiGridItemDragStart"},keymap:{TAB:9,STRG:17,CTRL:17,CTRLRIGHT:18,CTRLR:18,SHIFT:16,RETURN:13,ENTER:13,BACKSPACE:8,BCKSP:8,ALT:18,ALTR:17,ALTRIGHT:17,SPACE:32,WIN:91,MAC:91,FN:null,UP:38,DOWN:40,LEFT:37,RIGHT:39,ESC:27,DEL:46,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123},ASC:"asc",DESC:"desc",filter:{STARTS_WITH:2,ENDS_WITH:4,EXACT:8,CONTAINS:16,GREATER_THAN:32,GREATER_THAN_OR_EQUAL:64,LESS_THAN:128,LESS_THAN_OR_EQUAL:256,NOT_EQUAL:512},aggregationTypes:{sum:2,count:4,avg:8,min:16,max:32},CURRENCY_SYMBOLS:["ƒ","$","£","$","¤","¥","៛","₩","₱","฿","₫"],dataChange:{ALL:"all",EDIT:"edit",ROW:"row",COLUMN:"column"},scrollbars:{NEVER:0,ALWAYS:1,WHEN_NEEDED:2}})}(),angular.module("ui.grid").directive("uiGridCell",["$compile","$parse","gridUtil","uiGridConstants",function(a,b,c,d){var e={priority:0,scope:!1,require:"?^uiGrid",compile:function(){return{pre:function(b,e,f,g){function h(){var a=b.col.compiledElementFn;a(b,function(a){e.append(a)})}if(g&&b.col.compiledElementFn)h();else if(g&&!b.col.compiledElementFn)b.col.getCompiledElementFn().then(function(a){a(b,function(a){e.append(a)})});else{var i=b.col.cellTemplate.replace(d.MODEL_COL_FIELD,"row.entity."+c.preEval(b.col.field)).replace(d.COL_FIELD,"grid.getCellValue(row, col)"),j=a(i)(b);e.append(j)}},post:function(a,b){b.addClass(a.col.getColClass(!1));var c,e=function(){var d=b;c&&(d.removeClass(c),c=null),c=angular.isFunction(a.col.cellClass)?a.col.cellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.cellClass,d.addClass(c)};a.col.cellClass&&e();var f=a.grid.registerDataChangeCallback(e,[d.dataChange.COLUMN,d.dataChange.EDIT]),g=function(){a.grid.deregisterDataChangeCallback(f)};a.$on("$destroy",g)}}}};return e}]),function(){angular.module("ui.grid").service("uiGridColumnMenuService",["i18nService","uiGridConstants","gridUtil",function(a,b,c){var d={initialize:function(a,b){a.grid=b.grid,b.columnMenuScope=a,a.menuShown=!1},setColMenuItemWatch:function(a){var b=a.$watch("col.menuItems",function(b){"undefined"!=typeof b&&b&&angular.isArray(b)?(b.forEach(function(b){"undefined"!=typeof b.context&&b.context||(b.context={}),b.context.col=a.col}),a.menuItems=a.defaultMenuItems.concat(b)):a.menuItems=a.defaultMenuItems});a.$on("$destroy",b)},sortable:function(a){return a.grid.options.enableSorting&&"undefined"!=typeof a.col&&a.col&&a.col.enableSorting?!0:!1},isActiveSort:function(a,b){return"undefined"!=typeof a.col&&"undefined"!=typeof a.col.sort&&"undefined"!=typeof a.col.sort.direction&&a.col.sort.direction===b},suppressRemoveSort:function(a){return a.col&&a.col.colDef&&a.col.colDef.suppressRemoveSort?!0:!1},hideable:function(a){return"undefined"!=typeof a.col&&a.col&&a.col.colDef&&a.col.colDef.enableHiding===!1?!1:!0},getDefaultMenuItems:function(c){return[{title:a.getSafeText("sort.ascending"),icon:"ui-grid-icon-sort-alt-up",action:function(a){a.stopPropagation(),c.sortColumn(a,b.ASC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.ASC)}},{title:a.getSafeText("sort.descending"),icon:"ui-grid-icon-sort-alt-down",action:function(a){a.stopPropagation(),c.sortColumn(a,b.DESC)},shown:function(){return d.sortable(c)},active:function(){return d.isActiveSort(c,b.DESC)}},{title:a.getSafeText("sort.remove"),icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),c.unsortColumn()},shown:function(){return d.sortable(c)&&"undefined"!=typeof c.col&&"undefined"!=typeof c.col.sort&&"undefined"!=typeof c.col.sort.direction&&null!==c.col.sort.direction&&!d.suppressRemoveSort(c)}},{title:a.getSafeText("column.hide"),icon:"ui-grid-icon-cancel",shown:function(){return d.hideable(c)},action:function(a){a.stopPropagation(),c.hideColumn()}}]},getColumnElementPosition:function(a,b,d){var e={};return e.left=d[0].offsetLeft,e.top=d[0].offsetTop,e.offset=0,b.grid.options.offsetLeft&&(e.offset=b.grid.options.offsetLeft),e.height=c.elementHeight(d,!0),e.width=c.elementWidth(d,!0),e},repositionMenu:function(a,b,d,e,f){var g=e[0].querySelectorAll(".ui-grid-menu"),h=b.renderContainer?b.renderContainer:"body",i=(b.grid.renderContainers[h],c.closestElm(f,".ui-grid-render-container")),j=i.getBoundingClientRect().left-a.grid.element[0].getBoundingClientRect().left,k=i.querySelectorAll(".ui-grid-viewport")[0].scrollLeft,l=b.lastMenuWidth?b.lastMenuWidth:a.lastMenuWidth?a.lastMenuWidth:170,m=b.lastMenuPaddingRight?b.lastMenuPaddingRight:a.lastMenuPaddingRight?a.lastMenuPaddingRight:10;if(0!==g.length){var n=g[0].querySelectorAll(".ui-grid-menu-mid");0===n.length||angular.element(n).hasClass("ng-hide")||(l=c.elementWidth(g,!0),a.lastMenuWidth=l,b.lastMenuWidth=l,m=parseInt(c.getStyles(angular.element(g)[0]).paddingRight,10),a.lastMenuPaddingRight=m,b.lastMenuPaddingRight=m)}var o=d.left+j-k+d.width-l+m;o<d.offset&&(o=d.offset),e.css("left",o+"px"),e.css("top",d.top+d.height+"px")}};return d}]).directive("uiGridColumnMenu",["$timeout","gridUtil","uiGridConstants","uiGridColumnMenuService",function(a,b,c,d){var e={priority:0,scope:!0,require:"?^uiGrid",templateUrl:"ui-grid/uiGridColumnMenu",replace:!0,link:function(b,c,e,f){var g=this;d.initialize(b,f),b.defaultMenuItems=d.getDefaultMenuItems(b),b.menuItems=b.defaultMenuItems,d.setColMenuItemWatch(b),b.showMenu=function(a,e,f){b.col=a;var h=d.getColumnElementPosition(b,a,e);b.menuShown?(b.colElement=e,b.colElementPosition=h,b.hideThenShow=!0,b.$broadcast("hide-menu",{originalEvent:f})):(g.shown=b.menuShown=!0,d.repositionMenu(b,a,h,c,e),b.colElement=e,b.colElementPosition=h,b.$broadcast("show-menu",{originalEvent:f}))},b.hideMenu=function(a){b.menuShown=!1,a||b.$broadcast("hide-menu")},b.$on("menu-hidden",function(){b.hideThenShow?(delete b.hideThenShow,d.repositionMenu(b,b.col,b.colElementPosition,c,b.colElement),b.$broadcast("show-menu"),b.menuShown=!0):b.hideMenu(!0)}),b.$on("menu-shown",function(){a(function(){d.repositionMenu(b,b.col,b.colElementPosition,c,b.colElement),delete b.colElementPosition,delete b.columnElement},200)}),b.sortColumn=function(a,c){a.stopPropagation(),b.grid.sortColumn(b.col,c,!0).then(function(){b.grid.refresh(),b.hideMenu()})},b.unsortColumn=function(){b.col.unsort(),b.grid.refresh(),b.hideMenu()},b.hideColumn=function(){b.col.colDef.visible=!1,b.grid.refresh(),b.hideMenu()}},controller:["$scope",function(a){var b=this;a.$watch("menuItems",function(a){b.menuItems=a})}]};return e}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooterCell",["$timeout","gridUtil","uiGridConstants","$compile",function(a,b,c,d){var e={priority:0,scope:{col:"=",row:"=",renderIndex:"="},replace:!0,require:"^uiGrid",compile:function(){return{pre:function(a,c){function e(e){b.getTemplate(e).then(function(b){var e=d(b),f=e(a);c.append(f)})}e(a.col.footerCellTemplate?a.col.footerCellTemplate:"ui-grid/uiGridFooterCell")},post:function(a,b,d,e){a.grid=e.grid,a.getExternalScopes=e.getExternalScopes,b.addClass(a.col.getColClass(!1));var f,g=function(){var c=b;f&&(c.removeClass(f),f=null),f=angular.isFunction(a.col.footerCellClass)?a.col.footerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.footerCellClass,c.addClass(f)};a.col.footerCellClass&&g();var h=a.grid.registerDataChangeCallback(g,[c.dataChange.COLUMN]);a.$on("$destroy",function(){a.grid.deregisterDataChangeCallback(h)})}}}};return e}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridFooter",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d){var e="ui-grid/ui-grid-footer";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,c,f,g){var h=g[0],i=g[1];a.grid=h.grid,a.colContainer=i.colContainer,a.getExternalScopes=h.getExternalScopes,i.footer=c;var j=a.grid.options.footerTemplate?a.grid.options.footerTemplate:e;d.getTemplate(j).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.append(f),i){var g=c[0].getElementsByClassName("ui-grid-footer-viewport")[0];g&&(i.footerViewport=g)}})},post:function(a,b,c,e){{var f=e[0],g=e[1];f.grid}d.disableAnimations(b),g.footer=b;var h=b[0].getElementsByClassName("ui-grid-footer-viewport")[0];h&&(g.footerViewport=h)}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridGroupPanel",["$compile","uiGridConstants","gridUtil",function(a,b,c){var d="ui-grid/ui-grid-group-panel";return{restrict:"EA",replace:!0,require:"?^uiGrid",scope:!1,compile:function(){return{pre:function(b,e){var f=b.grid.options.groupPanelTemplate||d;c.getTemplate(f).then(function(c){var d=angular.element(c),f=a(d)(b);e.append(f)})},post:function(a,b){b.bind("$destroy",function(){})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeaderCell",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants",function(a,b,c,d,e,f){var g=500,h={priority:0,scope:{col:"=",row:"=",renderIndex:"="},require:["?^uiGrid","^uiGridRenderContainer"],replace:!0,compile:function(){return{pre:function(b,c){var d=a(b.col.headerCellTemplate)(b);c.append(d)},post:function(a,c,d,e){function h(b){var c=!1;b.shiftKey&&(c=!0),i.grid.sortColumn(a.col,c).then(function(){i.columnMenuScope&&i.columnMenuScope.hideMenu(),i.grid.refresh()})}var i=e[0],j=e[1];a.grid=i.grid,a.getExternalScopes=i.getExternalScopes,a.renderContainer=i.grid.renderContainers[j.containerId],c.addClass(a.col.getColClass(!1)),a.menuShown=!1,a.asc=f.ASC,a.desc=f.DESC;var k,l=(angular.element(c[0].querySelectorAll(".ui-grid-header-cell-menu")),angular.element(c[0].querySelectorAll(".ui-grid-cell-contents"))),m=function(){var b=c;k&&(b.removeClass(k),k=null),k=angular.isFunction(a.col.headerCellClass)?a.col.headerCellClass(a.grid,a.row,a.col,a.rowRenderIndex,a.colRenderIndex):a.col.headerCellClass,b.addClass(k)};a.col.headerCellClass&&m();var n=a.grid.registerDataChangeCallback(m,[f.dataChange.COLUMN]),o=function(){a.grid.deregisterDataChangeCallback(n)};a.$on("$destroy",o),a.sortable=i.grid.options.enableSorting&&a.col.enableSorting?!0:!1,a.filterable=i.grid.options.enableFiltering&&a.col.enableFiltering?!0:!1;var p,q=0;if(l.on("mousedown touchstart",function(d){"undefined"!=typeof d.originalEvent&&void 0!==d.originalEvent&&(d=d.originalEvent),d.button&&0!==d.button||(q=(new Date).getTime(),p=b(function(){},g),p.then(function(){a.col.grid.options&&a.col.grid.options.enableColumnMenus!==!1&&a.col.colDef&&a.col.colDef.enableColumnMenu!==!1&&i.columnMenuScope.showMenu(a.col,c,d)}))}),l.on("mouseup touchend",function(){b.cancel(p)}),a.$on("$destroy",function(){l.off("mousedown touchstart")}),a.toggleMenu=function(b){b.stopPropagation(),i.columnMenuScope.menuShown&&i.columnMenuScope.col===a.col?i.columnMenuScope.hideMenu():i.columnMenuScope.showMenu(a.col,c)},a.sortable&&(l.on("click touchend",function(a){a.stopPropagation(),b.cancel(p);var c=(new Date).getTime(),d=c-q;d>g||h(a)}),a.$on("$destroy",function(){b.cancel(p)})),a.filterable){var r=[];angular.forEach(a.col.filters,function(b,c){r.push(a.$watch("col.filters["+c+"].term",function(a,b){a!==b&&(i.grid.api.core.raise.filterChanged(),i.grid.refresh().then(function(){i.prevScrollArgs&&i.prevScrollArgs.y&&i.prevScrollArgs.y.percentage&&i.fireScrollingEvent({y:{percentage:i.prevScrollArgs.y.percentage}})}))}))}),a.$on("$destroy",function(){angular.forEach(r,function(a){a()})})}}}}};return h}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridHeader",["$templateCache","$compile","uiGridConstants","gridUtil","$timeout",function(a,b,c,d){var e="ui-grid/ui-grid-header",f="ui-grid/ui-grid-no-header";return{restrict:"EA",replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:!0,compile:function(){return{pre:function(a,c,g,h){var i=h[0],j=h[1];a.grid=i.grid,a.colContainer=j.colContainer,a.getExternalScopes=i.getExternalScopes,j.header=c,j.colContainer.header=c;var k;k=a.grid.options.hideHeader?f:a.grid.options.headerTemplate?a.grid.options.headerTemplate:e,d.getTemplate(k).then(function(d){var e=angular.element(d),f=b(e)(a);if(c.replaceWith(f),j.header=f,j.colContainer.header=f,c=f,j){var g=c[0].getElementsByClassName("ui-grid-header-viewport")[0];g&&(j.headerViewport=g)}})},post:function(a,b,c,e){function f(){var a=h.colContainer.getViewportWidth();"undefined"!=typeof g.grid.verticalScrollbarWidth&&void 0!==g.grid.verticalScrollbarWidth&&g.grid.verticalScrollbarWidth>0&&(a+=g.grid.verticalScrollbarWidth);var b=h.colContainer.visibleColumnCache,c=0,e=0,f=0,j=a,k=!1,l=function(b){return"manual"===b.widthType?+b.width:"percent"===b.widthType?parseInt(b.width.replace(/%/g,""),10)*a/100:"auto"===b.widthType?(0===f&&(f=parseInt(j/e,10)),b.width.length*f):void 0};b.forEach(function(a){a.widthType=null,isFinite(+a.width)?a.widthType="manual":d.endsWith(a.width,"%")?(a.widthType="percent",k=!0):angular.isString(a.width)&&-1!==a.width.indexOf("*")&&(a.widthType="auto",e+=a.width.length,k=!0)});var m=["manual","percent","auto"];if(b.filter(function(a){return a.visible&&a.widthType}).sort(function(a,b){return m.indexOf(a.widthType)-m.indexOf(b.widthType)}).forEach(function(a){var b=l(a);a.minWidth&&(b=Math.max(b,a.minWidth)),a.maxWidth&&(b=Math.min(b,a.maxWidth)),a.drawnWidth=Math.floor(b),c+=a.drawnWidth,j-=a.drawnWidth}),k&&j>0&&c>0&&a>c){var n=function(a){j>0&&("auto"===a.widthType||"percent"===a.widthType)&&(a.drawnWidth=a.drawnWidth+1,c+=1,j--)},o=0;do o=j,b.forEach(n);while(j>0&&j!==o)}c=Math.max(c,a);var p="";return b.forEach(function(a){p+=a.getColClassDefinition()}),i.verticalScrollbarWidth&&(c+=i.verticalScrollbarWidth),b.length>0&&(b[b.length-1].headerWidth=b[b.length-1].drawnWidth-30),h.colContainer.canvasWidth=parseInt(c,10),p}var g=e[0],h=e[1],i=g.grid;d.disableAnimations(b),h.header=b;var j=b[0].getElementsByClassName("ui-grid-header-viewport")[0];j&&(h.headerViewport=j),g&&g.grid.registerStyleComputation({priority:5,func:f})}}}}}])}(),function(){angular.module("ui.grid").service("uiGridGridMenuService",["gridUtil","i18nService",function(a,b){var c={initialize:function(a,b){b.gridMenuScope=a,a.grid=b,a.registeredMenuItems=[],a.$on("$destroy",function(){a.grid&&a.grid.gridMenuScope&&(a.grid.gridMenuScope=null),a.grid&&(a.grid=null),a.registeredMenuItems&&(a.registeredMenuItems=null)}),a.registeredMenuItems=[],b.api.registerMethod("core","addToGridMenu",c.addToGridMenu),b.api.registerMethod("core","removeFromGridMenu",c.removeFromGridMenu)},addToGridMenu:function(b,c){angular.isArray(c)?b.gridMenuScope?(b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems?b.gridMenuScope.registeredMenuItems:[],b.gridMenuScope.registeredMenuItems=b.gridMenuScope.registeredMenuItems.concat(c)):a.logError("Asked to addToGridMenu, but gridMenuScope not present.  Timing issue?  Please log issue with ui-grid"):a.logError("addToGridMenu: menuItems must be an array, and is not, not adding any items")},removeFromGridMenu:function(b,c){var d=-1;b&&b.gridMenuScope&&b.gridMenuScope.registeredMenuItems.forEach(function(b,e){b.id===c&&(d>-1?a.logError("removeFromGridMenu: found multiple items with the same id, removing only the last"):d=e)}),d>-1&&b.gridMenuScope.registeredMenuItems.splice(d,1)},getMenuItems:function(b){var d=[];return b.grid.options.gridMenuCustomItems&&(angular.isArray(b.grid.options.gridMenuCustomItems)?d=d.concat(b.grid.options.gridMenuCustomItems):a.logError("gridOptions.gridMenuCustomItems must be an array, and is not")),d=d.concat(b.registeredMenuItems),b.grid.options.gridMenuShowHideColumns!==!1&&(d=d.concat(c.showHideColumns(b))),d},showHideColumns:function(a){var d=[];return a.grid.options.columnDefs&&0!==a.grid.options.columnDefs.length&&0!==a.grid.columns.length?(d.push({title:b.getSafeText("gridMenu.columns")}),a.grid.options.gridMenuTitleFilter=a.grid.options.gridMenuTitleFilter?a.grid.options.gridMenuTitleFilter:function(a){return a},a.grid.options.columnDefs.forEach(function(b){if(b.enableHiding!==!1){var e={icon:"ui-grid-icon-ok",action:function(a){a.stopPropagation(),c.toggleColumnVisibility(this.context.gridCol)},shown:function(){return this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible},context:{gridCol:a.grid.getColumn(b.name||b.field)}};c.setMenuItemTitle(e,b,a.grid),d.push(e),e={icon:"ui-grid-icon-cancel",action:function(a){a.stopPropagation(),c.toggleColumnVisibility(this.context.gridCol)},shown:function(){return!(this.context.gridCol.colDef.visible===!0||void 0===this.context.gridCol.colDef.visible)},context:{gridCol:a.grid.getColumn(b.name||b.field)}},c.setMenuItemTitle(e,b,a.grid),d.push(e)}}),d):d},setMenuItemTitle:function(b,c,d){var e=d.options.gridMenuTitleFilter(c.displayName||c.name||c.field);"string"==typeof e?b.title=e:e.then?(b.title="",e.then(function(a){b.title=a},function(a){b.title=a})):(a.logError("Expected gridMenuTitleFilter to return a string or a promise, it has returned neither, bad config"),b.title="badconfig")},toggleColumnVisibility:function(a){a.colDef.visible=!(a.colDef.visible===!0||void 0===a.colDef.visible),a.grid.refresh()}};return c}]).directive("uiGridMenuButton",["gridUtil","uiGridConstants","uiGridGridMenuService",function(a,b,c){return{priority:0,scope:!0,require:["?^uiGrid"],templateUrl:"ui-grid/ui-grid-menu-button",replace:!0,link:function(a,b,d,e){var f=e[0];c.initialize(a,f.grid),a.shown=!1,a.toggleMenu=function(){a.shown?(a.$broadcast("hide-menu"),a.shown=!1):(a.menuItems=c.getMenuItems(a),a.$broadcast("show-menu"),a.shown=!0)},a.$on("menu-hidden",function(){a.shown=!1})}}}])}(),function(){angular.module("ui.grid").directive("uiGridMenu",["$compile","$timeout","$window","$document","gridUtil","uiGridConstants",function(a,b,c,d,e,f){var g={priority:0,scope:{menuItems:"=",autoHide:"=?"},require:"?^uiGrid",templateUrl:"ui-grid/uiGridMenu",replace:!1,link:function(a){var d=this;d.showMenu=a.showMenu=function(c,d){a.shown?a.shownMid||(a.shownMid=!0,a.$emit("menu-shown")):(a.shown=!0,b(function(){a.shownMid=!0,a.$emit("menu-shown")}));var f="click";d&&d.originalEvent&&d.originalEvent.type&&"touchstart"===d.originalEvent.type&&(f=d.originalEvent.type),angular.element(document).off("click touchstart",e),b(function(){angular.element(document).on(f,e)})},d.hideMenu=a.hideMenu=function(){a.shown&&(a.shownMid=!1,b(function(){a.shownMid||(a.shown=!1,a.$emit("menu-hidden"))},200)),angular.element(document).off("click touchstart",e)},a.$on("hide-menu",function(b,c){a.hideMenu(b,c)}),a.$on("show-menu",function(b,c){a.showMenu(b,c)});var e=function(){a.shown&&a.$apply(function(){a.hideMenu()})};("undefined"==typeof a.autoHide||void 0===a.autoHide)&&(a.autoHide=!0),a.autoHide&&angular.element(c).on("resize",e),a.$on("$destroy",function(){angular.element(document).off("click touchstart",e)}),a.$on("$destroy",function(){angular.element(c).off("resize",e)}),a.$on("$destroy",a.$on(f.events.GRID_SCROLL,e)),a.$on("$destroy",a.$on(f.events.ITEM_DRAGGING,e))},controller:["$scope","$element","$attrs",function(){}]};return g}]).directive("uiGridMenuItem",["gridUtil","$compile","i18nService",function(a,b,c){var d={priority:0,scope:{title:"=",active:"=",action:"=",icon:"=",shown:"=",context:"=",templateUrl:"="},require:["?^uiGrid","^uiGridMenu"],templateUrl:"ui-grid/uiGridMenuItem",replace:!0,compile:function(){return{pre:function(c,d,e,f){f[0],f[1];c.templateUrl&&a.getTemplate(c.templateUrl).then(function(a){var e=angular.element(a),f=b(e)(c);d.replaceWith(f)})},post:function(a,b,d,e){{var f=e[0];e[1]}("undefined"==typeof a.shown||null===a.shown)&&(a.shown=function(){return!0}),a.itemShown=function(){var b={};return a.context&&(b.context=a.context),"undefined"!=typeof f&&f&&(b.grid=f.grid),a.shown.call(b)},a.itemAction=function(b,c){if(b.stopPropagation(),"function"==typeof a.action){var d={};a.context&&(d.context=a.context),"undefined"!=typeof f&&f&&(d.grid=f.grid),a.action.call(d,b,c),a.$emit("hide-menu")}},a.i18n=c.get()}}}};return d}])}(),function(){angular.module("ui.grid").directive("uiGridNativeScrollbar",["$timeout","$document","uiGridConstants","gridUtil",function(a,b,c,d){var e=d.getScrollbarWidth();angular.isNumber(e)||(e=0);var f=d.detectBrowser();return"ie"===f&&(e+=1),{scope:{type:"@"},require:["^uiGrid","^uiGridRenderContainer"],link:function(a,b,f,g){function h(){var a=n.getViewportHeight(),b=n.getCanvasHeight(),d=o.headerHeight?o.headerHeight:p.headerHeight,e=p.options.enableVerticalScrollbar===c.scrollbars.WHEN_NEEDED?"overflow-y:auto;":"",f=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.vertical .contents { height: "+b+"px; }";return f+="\n .grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.vertical { height: "+a+"px; top: "+d+"px;"+e+"}",s=b,f}function i(){var a=o.getCanvasWidth(),b=u;p.options.showFooter&&(b-=1);var d=o.getViewportAdjustment();b-=d.height;var e=p.options.enableHorizontalScrollbar===c.scrollbars.WHEN_NEEDED?"overflow-x:auto":"",f=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.horizontal { bottom: "+b+"px;"+e+" }";return f+=".grid"+p.id+" .ui-grid-render-container-"+m.containerId+" .ui-grid-native-scrollbar.horizontal .contents { width: "+a+"px; }",s=a,f}function j(){if("vertical"===a.type){p.flagScrollingVertically();var c=b[0].scrollTop,e=n.getCanvasHeight()-n.getViewportHeight();p.horizontalScrollbarHeight&&p.horizontalScrollbarHeight>0&&(e-=l.grid.horizontalScrollbarHeight);var f=c/e;f>1&&(f=1),0>f&&(f=0);var g={target:b,y:{percentage:f}};a.scrollSource?a.scrollSource=null:l.fireScrollingEvent(g),r=c}else if("horizontal"===a.type){p.flagScrollingHorizontally();var h=d.normalizeScrollLeft(b),i=o.getCanvasWidth()-o.getViewportWidth(),j=h/i,k={target:b,x:{percentage:j}};a.scrollSource?a.scrollSource=null:l.fireScrollingEvent(k),r=h}}function k(c,e){if(!e.target||e.target!==b&&!angular.element(e.target).hasClass("ui-grid-native-scrollbar"))if(a.scrollSource=e.target,"vertical"===a.type){if(e.y&&"undefined"!=typeof e.y.percentage&&void 0!==e.y.percentage){p.flagScrollingVertically();var f=n.getCanvasHeight()-n.getViewportHeight(),g=Math.max(0,e.y.percentage*f);b[0].scrollTop=g}}else if("horizontal"===a.type&&e.x&&"undefined"!=typeof e.x.percentage&&void 0!==e.x.percentage){p.flagScrollingHorizontally();var h=o.getCanvasWidth()-o.getViewportWidth(),i=Math.max(0,e.x.percentage*h);b[0].scrollLeft=d.denormalizeScrollLeft(b,i)}}var l=g[0],m=g[1],n=m.rowContainer,o=m.colContainer,p=l.grid,q=angular.element('<div class="contents">&nbsp;</div>');b.addClass("ui-grid-native-scrollbar");var r,s=0;"vertical"===a.type?(b.css("width",e+"px"),b.addClass("vertical"),p.verticalScrollbarWidth=p.options.enableVerticalScrollbar===c.scrollbars.WHEN_NEEDED?0:e,o.verticalScrollbarWidth=p.verticalScrollbarWidth,r=b[0].scrollTop):"horizontal"===a.type&&(b.css("height",e+"px"),b.addClass("horizontal"),p.horizontalScrollbarHeight=p.options.enableHorizontalScrollbar===c.scrollbars.WHEN_NEEDED?0:e,n.horizontalScrollbarHeight=p.horizontalScrollbarHeight,r=d.normalizeScrollLeft(b)),b.append(q),"vertical"===a.type?s=d.elementHeight(b):"horizontal"===a.type&&(s=d.elementWidth(b));var t=d.closestElm(b,".ui-grid"),u=d.getBorderSize(t,"bottom");"vertical"===a.type?p.registerStyleComputation({priority:6,func:h}):"horizontal"===a.type&&p.registerStyleComputation({priority:6,func:i}),a.scrollSource=null,b.on("scroll",j),b.on("$destroy",function(){b.off("scroll")});var v=a.$on(c.events.GRID_SCROLL,k);a.$on("$destroy",v)}}}])}(),function(){"use strict";var a=angular.module("ui.grid");a.directive("uiGridRenderContainer",["$timeout","$document","uiGridConstants","gridUtil",function(a,b,c,d){return{replace:!0,transclude:!0,templateUrl:"ui-grid/uiGridRenderContainer",require:["^uiGrid","uiGridRenderContainer"],scope:{containerId:"=",rowContainerName:"=",colContainerName:"=",bindScrollHorizontal:"=",bindScrollVertical:"=",enableVerticalScrollbar:"=",enableHorizontalScrollbar:"="},controller:"uiGridRenderContainer as RenderContainer",compile:function(){return{pre:function(a,b,c,d){var e=d[0],f=d[1],g=a.grid=e.grid;if(!a.rowContainerName)throw"No row render container name specified";if(!a.colContainerName)throw"No column render container name specified";if(!g.renderContainers[a.rowContainerName])throw"Row render container '"+a.rowContainerName+"' is not registered.";if(!g.renderContainers[a.colContainerName])throw"Column render container '"+a.colContainerName+"' is not registered.";var h=a.rowContainer=g.renderContainers[a.rowContainerName],i=a.colContainer=g.renderContainers[a.colContainerName];f.containerId=a.containerId,f.rowContainer=h,f.colContainer=i},post:function(e,f,g,h){function i(a,b){if(b.y&&e.bindScrollVertical){n.prevScrollArgs=b;var c=p.getCanvasHeight()-p.getViewportHeight();o.horizontalScrollbarHeight&&o.horizontalScrollbarHeight>0&&(c+=o.horizontalScrollbarHeight);var f,g=n.viewport[0].scrollTop;if("undefined"!=typeof b.y.percentage&&void 0!==b.y.percentage)f=b.y.percentage;else{if("undefined"==typeof b.y.pixels||void 0===b.y.pixels)throw new Error("No percentage or pixel value provided for scroll event Y axis");f=b.y.percentage=(g+b.y.pixels)/c}var h=Math.max(0,f*c);n.viewport[0].scrollTop=h,n.prevScrollArgs.y.pixels=h-g}if(b.x&&e.bindScrollHorizontal){n.prevScrollArgs=b;var i,j=q.getCanvasWidth()-q.getViewportWidth(),k=d.normalizeScrollLeft(n.viewport);if("undefined"!=typeof b.x.percentage&&void 0!==b.x.percentage)i=b.x.percentage;else{if("undefined"==typeof b.x.pixels||void 0===b.x.pixels)throw new Error("No percentage or pixel value provided for scroll event X axis");i=b.x.percentage=(k+b.x.pixels)/j}var l=Math.max(0,i*j);n.viewport[0].scrollLeft=d.denormalizeScrollLeft(n.viewport,l),n.prevScrollLeft=l,n.headerViewport&&(n.headerViewport.scrollLeft=d.denormalizeScrollLeft(n.headerViewport,l)),n.footerViewport&&(n.footerViewport.scrollLeft=d.denormalizeScrollLeft(n.footerViewport,l)),n.prevScrollArgs.x.pixels=l-k}}function j(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault();var b,c,d,e;d=a.targetTouches[0].screenX,e=a.targetTouches[0].screenY,b=-(d-v),c=-(e-u),y=1>c?-1:1,z=1>b?-1:1,c*=2,b*=2;var f={target:a.target};if(0!==c){var g=(w+c)/(p.getCanvasHeight()-p.getViewportHeight());g>1?g=1:0>g&&(g=0),f.y={percentage:g,pixels:c}}if(0!==b){var h=(x+b)/(q.getCanvasWidth()-q.getViewportWidth());h>1?h=1:0>h&&(h=0),f.x={percentage:h,pixels:b}}m.fireScrollingEvent(f)}function k(c){function d(){a(function(){var a={target:c.target};if(0!==u){var b=(n.viewport[0].scrollTop+u)/(p.getCanvasHeight()-p.getViewportHeight());a.y={percentage:b,pixels:u}}if(0!==v){var e=(n.viewport[0].scrollLeft+v)/(q.getCanvasWidth()-q.getViewportWidth());a.x={percentage:e,pixels:v}}m.fireScrollingEvent(a),s-=1,u/=2,v/=2,s>0?d():m.scrollbars.forEach(function(a){a.removeClass("ui-grid-scrollbar-visible"),a.removeClass("ui-grid-scrolling")})},r)}c.originalEvent&&(c=c.originalEvent),c.preventDefault(),b.unbind("touchmove",j),b.unbind("touchend",k),b.unbind("touchcancel",k);var e=n.viewport[0].scrollTop,f=n.viewport[0].scrollTop,g=Math.abs(e-w),h=Math.abs(f-x),i=new Date-t,l=g/i,o=h/i,r=63,s=8,u=120*y*l,v=120*z*o;d()}function l(){var a="",b=q.getCanvasWidth(),c=q.getViewportWidth(),d=p.getCanvasHeight(),f=p.getViewportHeight(),g=q.getHeaderViewportWidth(),h=q.getHeaderViewportWidth();return a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-canvas { width: "+b+"px; height: "+d+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-header-canvas { width: "+b+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-viewport { width: "+c+"px; height: "+f+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-header-viewport { width: "+g+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-footer-canvas { width: "+b+"px; }",a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-footer-viewport { width: "+h+"px; }",void 0!==r.explicitHeaderHeight&&null!==r.explicitHeaderHeight&&r.explicitHeaderHeight>0?a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-header-cell { height: "+r.explicitHeaderHeight+"px; }":void 0!==r.innerHeaderHeight&&null!==r.innerHeaderHeight&&r.innerHeaderHeight>0&&(a+="\n .grid"+m.grid.id+" .ui-grid-render-container-"+e.containerId+" .ui-grid-header-cell { height: "+r.innerHeaderHeight+"px; }"),a}var m=h[0],n=h[1],o=m.grid,p=n.rowContainer,q=n.colContainer,r=o.renderContainers[e.containerId];f.addClass("ui-grid-render-container-"+e.containerId);var s;(e.bindScrollHorizontal||e.bindScrollVertical)&&(s=e.$on(c.events.GRID_SCROLL,i)),f.bind("wheel mousewheel DomMouseScroll MozMousePixelScroll",function(a){a.preventDefault();var b=d.normalizeWheelEvent(a),c={target:f};if(0!==b.deltaY){var e=-120*b.deltaY,g=(n.viewport[0].scrollTop+e)/(p.getCanvasHeight()-p.getViewportHeight());0>g?g=0:g>1&&(g=1),c.y={percentage:g,pixels:e}}if(0!==b.deltaX){var h=-120*b.deltaX,i=d.normalizeScrollLeft(n.viewport),j=(i+h)/(q.getCanvasWidth()-q.getViewportWidth());0>j?j=0:j>1&&(j=1),c.x={percentage:j,pixels:h}}m.fireScrollingEvent(c)});var t,u=0,v=0,w=0,x=0,y=1,z=1;d.isTouchEnabled()&&f.bind("touchstart",function(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),m.scrollbars.forEach(function(a){a.addClass("ui-grid-scrollbar-visible"),a.addClass("ui-grid-scrolling")}),t=new Date,u=a.targetTouches[0].screenY,v=a.targetTouches[0].screenX,w=n.viewport[0].scrollTop,x=n.viewport[0].scrollLeft,b.on("touchmove",j),b.on("touchend touchcancel",k)}),f.bind("$destroy",function(){s(),f.unbind("keydown"),["touchstart","touchmove","touchend","keydown","wheel","mousewheel","DomMouseScroll","MozMousePixelScroll"].forEach(function(a){f.unbind(a)})}),m.grid.registerStyleComputation({priority:6,func:l})}}}}}]),a.controller("uiGridRenderContainer",["$scope","gridUtil",function(a){var b=this;b.rowStyle=function(c){var d=a.grid.renderContainers[a.containerId],e={};if(!d.disableRowOffset&&0===c&&0!==b.currentTopRow){var f=a.rowContainer.currentTopRow*a.rowContainer.visibleRowCache[a.rowContainer.currentTopRow].height;e["margin-top"]=f+"px"}return d.disableColumnOffset||0===a.colContainer.currentFirstColumn||(a.grid.isRTL()?e["margin-right"]=a.colContainer.columnOffset+"px":e["margin-left"]=a.colContainer.columnOffset+"px"),e},b.columnStyle=function(b){var c=a.grid.renderContainers[a.containerId];if(!c.disableColumnOffset&&0===b&&0!==a.colContainer.currentFirstColumn){var d=a.colContainer.columnOffset;return a.grid.isRTL()?{"margin-right":d+"px"}:{"margin-left":d+"px"}}return null}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridRow",["gridUtil",function(){return{replace:!0,require:["^uiGrid","^uiGridRenderContainer"],scope:{row:"=uiGridRow",rowRenderIndex:"="},compile:function(){return{pre:function(a,b,c,d){var e=d[0],f=d[1],g=e.grid;a.grid=e.grid,a.colContainer=f.colContainer,g.getRowTemplateFn.then(function(c){c(a,function(a){b.replaceWith(a)})})},post:function(a,b,c,d){{var e=d[0];d[1]}a.getExternalScopes=e.getExternalScopes}}}}}])}(),function(){angular.module("ui.grid").directive("uiGridStyle",["gridUtil","$interpolate",function(a,b){return{link:function(a,c){var d=b(c.text(),!0);d&&a.$watch(d,function(a){c.text(a)})}}}])}(),function(){"use strict";
+angular.module("ui.grid").directive("uiGridViewport",["gridUtil",function(a){return{replace:!0,scope:{},templateUrl:"ui-grid/uiGridViewport",require:["^uiGrid","^uiGridRenderContainer"],link:function(b,c,d,e){var f=e[0],g=e[1];b.containerCtrl=g;{var h=g.rowContainer,i=g.colContainer;f.grid}b.grid=f.grid,b.rowContainer=g.rowContainer,b.colContainer=g.colContainer,g.viewport=c,c.on("scroll",function(){var d=c[0].scrollTop,e=a.normalizeScrollLeft(c),g=-1,j=-1;if(e!==i.prevScrollLeft){var k=(e-i.prevScrollLeft,i.getCanvasWidth()-i.getViewportWidth());g=e/k,i.adjustScrollHorizontal(e,g)}if(d!==h.prevScrollTop){var l=(d-h.prevScrollTop,h.getCanvasHeight()-h.getViewportHeight());j=d/l,j>1&&(j=1),0>j&&(j=0),h.adjustScrollVertical(d,j)}if(!b.grid.isScrollingVertically&&!b.grid.isScrollingHorizontally){var m={};g>-1&&(m.x={percentage:g}),j>-1&&(m.y={percentage:j}),f.fireScrollingEvent(m)}})}}}])}(),function(){angular.module("ui.grid").directive("uiGridVisible",function(){return function(a,b,c){a.$watch(c.uiGridVisible,function(a){b[a?"removeClass":"addClass"]("ui-grid-invisible")})}})}(),function(){"use strict";angular.module("ui.grid").controller("uiGridController",["$scope","$element","$attrs","gridUtil","$q","uiGridConstants","$templateCache","gridClassFactory","$timeout","$parse","$compile",function(a,b,c,d,e,f,g,h,i,j,k){function l(a,b){a&&a!==b&&(n.grid.options.columnDefs=a,n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates(),n.grid.callDataChangeCallbacks(f.dataChange.COLUMN)}))}function m(b){var d=[];b&&(n.grid.columns.length===(n.grid.rowHeaderColumns?n.grid.rowHeaderColumns.length:0)&&!c.uiGridColumns&&0===n.grid.options.columnDefs.length&&b.length>0&&n.grid.buildColumnDefsFromData(b),(n.grid.options.columnDefs.length>0||b.length>0)&&d.push(n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates()})),e.all(d).then(function(){n.grid.modifyRows(b).then(function(){n.grid.redrawInPlace(),a.$evalAsync(function(){n.grid.refreshCanvas(!0),n.grid.callDataChangeCallbacks(f.dataChange.ROW)})})}))}var n=this;n.grid=h.createGrid(a.uiGrid),b.addClass("grid"+n.grid.id),n.grid.rtl="rtl"===d.getStyles(b[0]).direction,n.getExternalScopes=a.getExternalScopes,a.grid=n.grid,c.uiGridColumns&&c.$observe("uiGridColumns",function(a){n.grid.options.columnDefs=a,n.grid.buildColumns().then(function(){n.grid.preCompileCellTemplates(),n.grid.refreshCanvas(!0)})});var o;o=angular.isString(a.uiGrid.data)?a.$parent.$watchCollection(a.uiGrid.data,m):a.$parent.$watchCollection(function(){return a.uiGrid.data},m);var p=a.$parent.$watchCollection(function(){return a.uiGrid.columnDefs},l);a.$on("$destroy",function(){o(),p()}),a.$watch(function(){return n.grid.styleComputations},function(){n.grid.refreshCanvas(!0)}),n.fireScrollingEvent=d.throttle(function(b){a.$broadcast(f.events.GRID_SCROLL,b)},n.grid.options.scrollThrottle,{trailing:!0}),n.fireEvent=function(b,c){("undefined"==typeof c||void 0===c)&&(c={}),("undefined"==typeof c.grid||void 0===c.grid)&&(c.grid=n.grid),a.$broadcast(b,c)},n.innerCompile=function(b){k(b)(a)}}]),angular.module("ui.grid").directive("uiGrid",["$compile","$templateCache","gridUtil","$window",function(a,b,c,d){return{templateUrl:"ui-grid/ui-grid",scope:{uiGrid:"=",getExternalScopes:"&?externalScopes"},replace:!0,transclude:!0,controller:"uiGridController",compile:function(){return{post:function(a,b,e,f){function g(){h.gridWidth=a.gridWidth=c.elementWidth(b),h.gridHeight=a.gridHeight=c.elementHeight(b),h.queueRefresh()}var h=f.grid;if(f.scrollbars=[],h.renderingComplete(),h.element=b,h.gridWidth=a.gridWidth=c.elementWidth(b),h.canvasWidth=f.grid.gridWidth,h.gridHeight=a.gridHeight=c.elementHeight(b),h.gridHeight<h.options.rowHeight){var i=h.options.minRowsToShow*h.options.rowHeight,j=h.options.hideHeader?0:h.options.headerRowHeight,k=h.options.showFooter?h.options.footerRowHeight:0,l=h.options.enableScrollbars?c.getScrollbarWidth():0,m=0;angular.forEach(h.options.columnDefs,function(a){a.hasOwnProperty("filter")?1>m&&(m=1):a.hasOwnProperty("filters")&&m<a.filters.length&&(m=a.filters.length)});var n=m*j,o=j+i+k+l+n;b.css("height",o+"px"),h.gridHeight=a.gridHeight=c.elementHeight(b)}h.refreshCanvas();var p=angular.element('<div ng-if="grid.hasLeftContainer()" style="width: 0" ui-grid-pinned-container="\'left\'"></div>');b.prepend(p),f.innerCompile(p);var q=angular.element('<div  ng-if="grid.hasRightContainer()" style="width: 0" ui-grid-pinned-container="\'right\'"></div>');b.append(q),f.innerCompile(q),a.$watch(function(){return h.hasLeftContainer()},function(a,b){a!==b&&h.refreshCanvas(!0)}),a.$watch(function(){return h.hasRightContainer()},function(a,b){a!==b&&h.refreshCanvas(!0)}),angular.element(d).on("resize",g),b.on("$destroy",function(){angular.element(d).off("resize",g)})}}}}}])}(),function(){"use strict";angular.module("ui.grid").directive("uiGridPinnedContainer",["gridUtil",function(){return{restrict:"EA",replace:!0,template:'<div class="ui-grid-pinned-container"><div ui-grid-render-container container-id="side" row-container-name="\'body\'" col-container-name="side" bind-scroll-vertical="true" class="{{ side }} ui-grid-render-container-{{ side }}"></div></div>',scope:{side:"=uiGridPinnedContainer"},require:"^uiGrid",compile:function(){return{post:function(a,b,c,d){function e(){if("left"===a.side||"right"===a.side){for(var b=g.renderContainers[a.side].visibleColumnCache,c=0,d=0;d<b.length;d++){var e=b[d];c+=e.drawnWidth}h=c}}function f(){var c="";if("left"===a.side||"right"===a.side){e(),b.attr("style",null);var d=g.renderContainers.body.getViewportHeight();c+=".grid"+g.id+" .ui-grid-pinned-container-"+a.side+", .grid"+g.id+" .ui-grid-pinned-container-"+a.side+" .ui-grid-render-container-"+a.side+" .ui-grid-viewport { width: "+h+"px; height: "+d+"px; } "}return c}var g=d.grid,h=0;b.addClass("ui-grid-pinned-container-"+a.side),g.renderContainers.body.registerViewportAdjuster(function(a){return 0===h&&e(),a.width-=h,a}),g.registerStyleComputation({priority:15,func:f})}}}}}])}(),function(){angular.module("ui.grid").factory("Grid",["$q","$compile","$parse","gridUtil","uiGridConstants","GridOptions","GridColumn","GridRow","GridApi","rowSorter","rowSearcher","GridRenderContainer","$timeout",function(a,b,c,d,e,f,g,h,i,j,k,l,m){function n(){}var o=function(a){var b=this;if(void 0===a||"undefined"==typeof a.id||!a.id)throw new Error("No ID provided. An ID must be given when creating a grid.");if(!/^[_a-zA-Z0-9-]+$/.test(a.id))throw new Error("Grid id '"+a.id+'" is invalid. It must follow CSS selector syntax rules.');b.id=a.id,delete a.id,b.options=f.initialize(a),b.headerHeight=b.options.headerRowHeight,b.footerHeight=b.options.showFooter===!0?b.options.footerRowHeight:0,b.rtl=!1,b.gridHeight=0,b.gridWidth=0,b.columnBuilders=[],b.rowBuilders=[],b.rowsProcessors=[],b.columnsProcessors=[],b.styleComputations=[],b.viewportAdjusters=[],b.rowHeaderColumns=[],b.dataChangeCallbacks={},b.renderContainers={},b.renderContainers.body=new l("body",b),b.cellValueGetterCache={},b.getRowTemplateFn=null,b.rows=[],b.columns=[],b.isScrollingVertically=!1,b.isScrollingHorizontally=!1;var c=d.debounce(function(){b.isScrollingVertically=!1},300),g=d.debounce(function(){b.isScrollingHorizontally=!1},300);b.flagScrollingVertically=function(){b.isScrollingVertically=!0,c()},b.flagScrollingHorizontally=function(){b.isScrollingHorizontally=!0,g()},b.api=new i(b),b.api.registerMethod("core","refresh",this.refresh),b.api.registerMethod("core","refreshRows",this.refreshRows),b.api.registerMethod("core","handleWindowResize",this.handleWindowResize),b.api.registerMethod("core","addRowHeaderColumn",this.addRowHeaderColumn),b.api.registerMethod("core","sortHandleNulls",j.handleNulls),b.api.registerEvent("core","sortChanged"),b.api.registerMethod("core","notifyDataChange",this.notifyDataChange),b.registerDataChangeCallback(b.columnRefreshCallback,[e.dataChange.COLUMN]),b.registerDataChangeCallback(b.processRowsCallback,[e.dataChange.EDIT])};return o.prototype.isRTL=function(){return this.rtl},o.prototype.registerColumnBuilder=function(a){this.columnBuilders.push(a)},o.prototype.buildColumnDefsFromData=function(a){this.options.columnDefs=d.getColumnsFromData(a,this.options.excludeProperties)},o.prototype.registerRowBuilder=function(a){this.rowBuilders.push(a)},o.prototype.registerDataChangeCallback=function(a,b){var c=d.nextUid();return b||(b=[e.dataChange.ALL]),Array.isArray(b)||d.logError("Expected types to be an array or null in registerDataChangeCallback, value passed was: "+b),this.dataChangeCallbacks[c]={callback:a,types:b},c},o.prototype.deregisterDataChangeCallback=function(a){delete this.dataChangeCallbacks[a]},o.prototype.callDataChangeCallbacks=function(a){angular.forEach(this.dataChangeCallbacks,function(b){(-1!==b.types.indexOf(e.dataChange.ALL)||-1!==b.types.indexOf(a)||a===e.dataChange.ALL)&&b.callback(this)},this)},o.prototype.notifyDataChange=function(a,b){var c=e.dataChange;b===c.ALL||b===c.COLUMN||b===c.EDIT||b===c.ROW?a.callDataChangeCallbacks(b):d.logError("Notified of a data change, but the type was not recognised, so no action taken, type was: "+b)},o.prototype.columnRefreshCallback=function(a){a.refresh()},o.prototype.processRowsCallback=function(a){a.refreshRows()},o.prototype.getColumn=function(a){var b=this.columns.filter(function(b){return b.colDef.name===a});return b.length>0?b[0]:null},o.prototype.getColDef=function(a){var b=this.options.columnDefs.filter(function(b){return b.name===a});return b.length>0?b[0]:null},o.prototype.assignTypes=function(){var a=this;a.options.columnDefs.forEach(function(b,c){if(!b.type){var e=new g(b,c,a),f=a.rows.length>0?a.rows[0]:null;f?b.type=d.guessType(a.getCellValue(f,e)):(d.logWarn("Unable to assign type from data, so defaulting to string"),b.type="string")}})},o.prototype.addRowHeaderColumn=function(a){var b=this,c=new g(a,b.rowHeaderColumns.length,b);c.isRowHeader=!0,b.isRTL()?(b.createRightContainer(),c.renderContainer="right"):(b.createLeftContainer(),c.renderContainer="left"),b.columnBuilders[0](a,c,b.options).then(function(){c.enableFiltering=!1,c.enableSorting=!1,c.enableHiding=!1,b.rowHeaderColumns.push(c),b.buildColumns().then(function(){b.preCompileCellTemplates(),b.handleWindowResize()})})},o.prototype.buildColumns=function(){var b,c=this,e=[],f=c.rowHeaderColumns.length;for(b=0;b<c.columns.length;b++)c.getColDef(c.columns[b].name)||(c.columns.splice(b,1),b--);return c.rowHeaderColumns.forEach(function(a){c.columns.unshift(a)}),c.options.columnDefs.forEach(function(a,b){c.preprocessColDef(a);var h=c.getColumn(a.name);h?h.updateColumnDef(a):(h=new g(a,d.nextUid(),c),c.columns.splice(b+f,0,h)),c.columnBuilders.forEach(function(b){e.push(b.call(c,a,h,c.options))})}),a.all(e)},o.prototype.preCompileCellTemplates=function(){var a=this;this.columns.forEach(function(c){var d=c.cellTemplate.replace(e.MODEL_COL_FIELD,a.getQualifiedColField(c));d=d.replace(e.COL_FIELD,"grid.getCellValue(row, col)");var f=b(d);c.compiledElementFn=f,c.compiledElementFnDefer&&c.compiledElementFnDefer.resolve(c.compiledElementFn)})},o.prototype.getQualifiedColField=function(a){return"row.entity."+d.preEval(a.field)},o.prototype.createLeftContainer=function(){this.hasLeftContainer()||(this.renderContainers.left=new l("left",this,{disableColumnOffset:!0}))},o.prototype.createRightContainer=function(){this.hasRightContainer()||(this.renderContainers.right=new l("right",this,{disableColumnOffset:!0}))},o.prototype.hasLeftContainer=function(){return void 0!==this.renderContainers.left},o.prototype.hasRightContainer=function(){return void 0!==this.renderContainers.right},o.prototype.preprocessColDef=function(a){if(!a.field&&!a.name)throw new Error("colDef.name or colDef.field property is required");void 0===a.name&&void 0!==a.field&&(a.name=a.field)},o.prototype.newInN=function(a,b,c,d){for(var e=this,f=[],g=0;g<b.length;g++){for(var h=d?b[g][d]:b[g],i=!1,j=0;j<a.length;j++){var k=c?a[j][c]:a[j];if(e.options.rowEquality(h,k)){i=!0;break}}i||f.push(h)}return f},o.prototype.getRow=function(a){var b=this.rows.filter(function(b){return b.entity===a});return b.length>0?b[0]:null},o.prototype.modifyRows=function(b){var c,d,e,f,g=this;if((g.options.useExternalSorting||0===g.getColumnSorting().length)&&b.length>0){var i=g.rowHashMap;i||(i={get:function(){return null}}),g.createRowHashMap(),d=g.rowHashMap;var j=0===g.rows.length;for(g.rows.length=0,c=0;c<b.length;c++){var k=b[c];e=i.get(k),f=e?e.row:g.processRowBuilders(new h(k,c,g)),g.rows.push(f),d.put(k,{i:c,entity:k,row:f})}j&&g.assignTypes()}else if(0===g.rows.length&&b.length>0){if(g.options.enableRowHashing)for(g.rowHashMap||g.createRowHashMap(),c=0;c<b.length;c++)f=b[c],g.rowHashMap.put(f,{i:c,entity:f});g.addRows(b),g.assignTypes()}else if(b.length>0){var l,m,n;if(g.options.enableRowHashing){l=[],n=[];var o={};for(m=[],g.rowHashMap||g.createRowHashMap(),d=g.rowHashMap,c=0;c<b.length;c++){f=b[c];var p=!1;g.options.getRowIdentity(f)||(p=!0),e=d.get(f),e?e.row&&(o[g.options.rowIdentity(f)]=!0):(d.put(f,{i:c,entity:f}),p?n.push(f):l.push(f))}for(c=0;c<g.rows.length;c++){var q=g.rows[c],r=g.options.rowIdentity(q.entity);o[r]||m.push(q)}}var s=l||[],t=n||b;s=s.concat(g.newInN(g.rows,t,"entity")),g.addRows(s);var u=g.getDeletedRows(m||g.rows,b);for(c=0;c<u.length;c++)g.options.enableRowHashing&&g.rowHashMap.remove(u[c].entity),g.rows.splice(g.rows.indexOf(u[c]),1)}else g.createRowHashMap(),g.rows.length=0;var v=a.when(g.processRowsProcessors(g.rows)).then(function(a){return g.setVisibleRows(a)}),w=a.when(g.processColumnsProcessors(g.columns)).then(function(a){return g.setVisibleColumns(a)});return a.all([v,w])},o.prototype.getDeletedRows=function(a,b){var c=this,d=a.filter(function(a){return!b.some(function(b){return c.options.rowEquality(b,a.entity)})});return d},o.prototype.addRows=function(a){for(var b=this,c=b.rows.length,d=0;d<a.length;d++){var e=b.processRowBuilders(new h(a[d],d+c,b));if(b.options.enableRowHashing){var f=b.rowHashMap.get(e.entity);f&&(f.row=e)}b.rows.push(e)}},o.prototype.processRowBuilders=function(a){var b=this;return b.rowBuilders.forEach(function(c){c.call(b,a,b.options)}),a},o.prototype.registerStyleComputation=function(a){this.styleComputations.push(a)},o.prototype.registerRowsProcessor=function(a){if(!angular.isFunction(a))throw"Attempt to register non-function rows processor: "+a;this.rowsProcessors.push(a)},o.prototype.removeRowsProcessor=function(a){var b=this.rowsProcessors.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.rowsProcessors.splice(b,1)},o.prototype.processRowsProcessors=function(b){function c(b,e){var g=d.rowsProcessors[b];return a.when(g.call(d,e,d.columns)).then(function(a){if(!a)throw"Processor at index "+b+" did not return a set of renderable rows";if(!angular.isArray(a))throw"Processor at index "+b+" did not return an array";return b++,b<=d.rowsProcessors.length-1?c(b,a):void f.resolve(a)})}var d=this,e=b.slice(0);if(0===d.rowsProcessors.length)return a.when(e);var f=a.defer();return c(0,e),f.promise},o.prototype.setVisibleRows=function(a){var b=this;for(var c in b.renderContainers){var d=b.renderContainers[c];d.visibleRowCache.length=0}for(var e=0;e<a.length;e++){var f=a[e];f.visible&&("undefined"!=typeof f.renderContainer&&f.renderContainer?b.renderContainers[f.renderContainer].visibleRowCache.push(f):b.renderContainers.body.visibleRowCache.push(f))}},o.prototype.registerColumnsProcessor=function(a){if(!angular.isFunction(a))throw"Attempt to register non-function rows processor: "+a;this.columnsProcessors.push(a)},o.prototype.removeColumnsProcessor=function(a){var b=this.columnsProcessors.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.columnsProcessors.splice(b,1)},o.prototype.processColumnsProcessors=function(b){function c(b,g){var h=d.columnsProcessors[b];return a.when(h.call(d,g,d.rows)).then(function(a){if(!a)throw"Processor at index "+b+" did not return a set of renderable rows";if(!angular.isArray(a))throw"Processor at index "+b+" did not return an array";return b++,b<=d.columnsProcessors.length-1?c(b,e):void f.resolve(e)})}var d=this,e=b.slice(0);if(0===d.columnsProcessors.length)return a.when(e);var f=a.defer();return c(0,e),f.promise},o.prototype.setVisibleColumns=function(a){var b=this;for(var c in b.renderContainers){var d=b.renderContainers[c];d.visibleColumnCache.length=0}for(var e=0;e<a.length;e++){var f=a[e];f.visible&&("undefined"!=typeof f.renderContainer&&f.renderContainer?b.renderContainers[f.renderContainer].visibleColumnCache.push(f):b.renderContainers.body.visibleColumnCache.push(f))}},o.prototype.handleWindowResize=function(){var a=this;a.gridWidth=d.elementWidth(a.element),a.gridHeight=d.elementHeight(a.element),a.queueRefresh()},o.prototype.queueRefresh=function(){var a=this;return a.refreshCanceller&&m.cancel(a.refreshCanceller),a.refreshCanceller=m(function(){a.refreshCanvas(!0)}),a.refreshCanceller.then(function(){a.refreshCanceller=null}),a.refreshCanceller},o.prototype.buildStyles=function(){var a=this;a.customStyles="",a.styleComputations.sort(function(a,b){return null===a.priority?1:null===b.priority?-1:null===a.priority&&null===b.priority?0:a.priority-b.priority}).forEach(function(b){var c=b.func.call(a);angular.isString(c)&&(a.customStyles+="\n"+c)})},o.prototype.minColumnsToRender=function(){var a=this,b=this.getViewportWidth(),c=0,d=0;return a.columns.forEach(function(e,f){if(b>d)d+=e.drawnWidth,c++;else{for(var g=0,h=f;h>=f-c;h--)g+=a.columns[h].drawnWidth;b>g&&c++}}),c},o.prototype.getBodyHeight=function(){var a=this.getViewportHeight();return"undefined"!=typeof this.horizontalScrollbarHeight&&void 0!==this.horizontalScrollbarHeight&&this.horizontalScrollbarHeight>0&&(a+=this.horizontalScrollbarHeight),a},o.prototype.getViewportHeight=function(){var a=this,b=this.gridHeight-this.headerHeight-this.footerHeight;"undefined"!=typeof this.horizontalScrollbarHeight&&void 0!==this.horizontalScrollbarHeight&&this.horizontalScrollbarHeight>0&&(b-=this.horizontalScrollbarHeight);var c=a.getViewportAdjustment();return b+=c.height},o.prototype.getViewportWidth=function(){var a=this,b=this.gridWidth;"undefined"!=typeof this.verticalScrollbarWidth&&void 0!==this.verticalScrollbarWidth&&this.verticalScrollbarWidth>0&&(b-=this.verticalScrollbarWidth);var c=a.getViewportAdjustment();return b+=c.width},o.prototype.getHeaderViewportWidth=function(){var a=this.getViewportWidth();return"undefined"!=typeof this.verticalScrollbarWidth&&void 0!==this.verticalScrollbarWidth&&this.verticalScrollbarWidth>0&&(a+=this.verticalScrollbarWidth),a},o.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},o.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.viewportAdjusters.splice(b,1)},o.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},o.prototype.getVisibleRowCount=function(){return this.renderContainers.body.visibleRowCache.length},o.prototype.getVisibleRows=function(){return this.renderContainers.body.visibleRowCache},o.prototype.getVisibleColumnCount=function(){return this.renderContainers.body.visibleColumnCache.length},o.prototype.searchRows=function(a){return k.search(this,a,this.columns)},o.prototype.sortByColumn=function(a){return j.sort(this,a,this.columns)},o.prototype.getCellValue=function(a,b){var d=this;return d.cellValueGetterCache[b.colDef.name]||(d.cellValueGetterCache[b.colDef.name]=c(a.getEntityQualifiedColField(b))),d.cellValueGetterCache[b.colDef.name](a)},o.prototype.getNextColumnSortPriority=function(){var a=this,b=0;return a.columns.forEach(function(a){a.sort&&a.sort.priority&&a.sort.priority>b&&(b=a.sort.priority)}),b+1},o.prototype.resetColumnSorting=function(a){var b=this;b.columns.forEach(function(b){b!==a&&(b.sort={})})},o.prototype.getColumnSorting=function(){var a,b=this,c=[];return a=b.columns.slice(0),a.sort(j.prioritySort).forEach(function(a){a.sort&&"undefined"!=typeof a.sort.direction&&a.sort.direction&&(a.sort.direction===e.ASC||a.sort.direction===e.DESC)&&c.push(a)}),c},o.prototype.sortColumn=function(b,c,d){var f=this,g=null;if("undefined"==typeof b||!b)throw new Error("No column parameter provided");return"boolean"==typeof c?d=c:g=c,d?b.sort.priority=f.getNextColumnSortPriority():(f.resetColumnSorting(b),b.sort.priority=0),b.sort.direction=g?g:b.sort.direction&&b.sort.direction===e.ASC?e.DESC:b.sort.direction&&b.sort.direction===e.DESC?b.colDef&&b.colDef.suppressRemoveSort?e.ASC:null:e.ASC,f.api.core.raise.sortChanged(f,f.getColumnSorting()),a.when(b)},o.prototype.renderingComplete=function(){angular.isFunction(this.options.onRegisterApi)&&this.options.onRegisterApi(this.api),this.api.core.raise.renderingComplete(this.api)},o.prototype.createRowHashMap=function(){var a=this,b=new n;b.grid=a,a.rowHashMap=b},o.prototype.refresh=function(){d.logDebug("grid refresh");var b=this,c=b.processRowsProcessors(b.rows).then(function(a){b.setVisibleRows(a)}),e=b.processColumnsProcessors(b.columns).then(function(a){b.setVisibleColumns(a)});return a.all([c,e]).then(function(){b.redrawInPlace(),b.refreshCanvas(!0)})},o.prototype.refreshRows=function(){var a=this;return a.processRowsProcessors(a.rows).then(function(b){a.setVisibleRows(b),a.redrawInPlace(),a.refreshCanvas(!0)})},o.prototype.refreshCanvas=function(b){var c=this;b&&c.buildStyles();var e=a.defer(),f=[];for(var g in c.renderContainers)if(c.renderContainers.hasOwnProperty(g)){var h=c.renderContainers[g];if(null===h.canvasWidth||isNaN(h.canvasWidth))continue;h.header&&f.push(h)}return m(f.length>0?function(){var a,g,h=!1,i=0;for(a=0;a<f.length;a++)if(g=f[a],null!==g.canvasWidth&&!isNaN(g.canvasWidth)&&g.header){var j=g.headerHeight,k=d.outerElementHeight(g.header);g.headerHeight=parseInt(k,10),j!==k&&(h=!0);var l=d.getBorderSize(g.header,"top"),m=d.getBorderSize(g.header,"bottom"),n=parseInt(k-l-m,10);n=0>n?0:n,g.innerHeaderHeight=n,n>i&&(i=n)}for(a=0;a<f.length;a++)g=f[a],g.headerHeight<i&&(g.explicitHeaderHeight=i);b&&h&&c.buildStyles(),e.resolve()}:function(){e.resolve()}),e.promise},o.prototype.redrawInPlace=function(){var a=this;for(var b in a.renderContainers){var c=a.renderContainers[b];c.adjustRows(c.prevScrollTop,null),c.adjustColumns(c.prevScrollLeft,null)}},n.prototype={put:function(a,b){this[this.grid.options.rowIdentity(a)]=b},get:function(a){return this[this.grid.options.rowIdentity(a)]},remove:function(a){var b=this[a=this.grid.options.rowIdentity(a)];return delete this[a],b}},o}])}(),function(){angular.module("ui.grid").factory("GridApi",["$q","$rootScope","gridUtil","uiGridConstants","GridRow","uiGridGridMenuService",function(a,b,c,d,e){function f(a,b,c,d){return a.$on(b,function(){var a=Array.prototype.slice.call(arguments);a.splice(0,1),c.apply(d.api,a)})}var g=function(a){this.grid=a,this.listeners=[],this.registerEvent("core","renderingComplete"),this.registerEvent("core","filterChanged"),this.registerMethod("core","setRowInvisible",e.prototype.setRowInvisible),this.registerMethod("core","clearRowInvisible",e.prototype.clearRowInvisible),this.registerMethod("core","getVisibleRows",this.grid.getVisibleRows),this.registerEvent("core","rowsVisibleChanged")};return g.prototype.suppressEvents=function(a,b){var c=this,d=angular.isArray(a)?a:[a],e=[];d.forEach(function(a){e=c.listeners.filter(function(b){return a===b.handler})}),e.forEach(function(a){a.dereg()}),b(),e.forEach(function(a){a.dereg=f(a.scope,a.eventId,a.handler,c.grid)})},g.prototype.registerEvent=function(a,c){var d=this;d[a]||(d[a]={});var e=d[a];e.on||(e.on={},e.raise={});var g=d.grid.id+a+c;e.raise[c]=function(){b.$broadcast.apply(b,[g].concat(Array.prototype.slice.call(arguments)))},e.on[c]=function(a,b){var c=f(a,g,b,d.grid),e={handler:b,dereg:c,eventId:g,scope:a};d.listeners.push(e),a.$on("$destroy",function(){e.dereg=null,e.handler=null,e.eventId=null,e.scope=null})}},g.prototype.registerEventsFromObject=function(a){var b=this,c=[];angular.forEach(a,function(a,b){var d={name:b,events:[]};angular.forEach(a,function(a,b){d.events.push(b)}),c.push(d)}),c.forEach(function(a){a.events.forEach(function(c){b.registerEvent(a.name,c)})})},g.prototype.registerMethod=function(a,b,d,e){this[a]||(this[a]={});var f=this[a];f[b]=c.createBoundedWrapper(e||this.grid,d)},g.prototype.registerMethodsFromObject=function(a,b){var c=this,d=[];angular.forEach(a,function(a,b){var c={name:b,methods:[]};angular.forEach(a,function(a,b){c.methods.push({name:b,fn:a})}),d.push(c)}),d.forEach(function(a){a.methods.forEach(function(d){c.registerMethod(a.name,d.name,d.fn,b)})})},g}])}(),function(){angular.module("ui.grid").factory("GridColumn",["gridUtil","uiGridConstants","i18nService",function(a,b,c){function d(a,b,c){var d=this;d.grid=c,d.uid=b,d.updateColumnDef(a)}return d.prototype.setPropertyOrDefault=function(a,b,c){var d=this;d[b]="undefined"!=typeof a[b]&&a[b]?a[b]:"undefined"!=typeof d[b]?d[b]:c?c:{}},d.prototype.updateColumnDef=function(b){var c=this;if(c.colDef=b,void 0===b.name)throw new Error("colDef.name is required for column at index "+c.grid.options.columnDefs.indexOf(b));var e="Cannot parse column width '"+b.width+"' for column named '"+b.name+"'";if(a.isNullOrUndefined(c.width)||!angular.isNumber(c.width))if(a.isNullOrUndefined(b.width))c.width="*";else if(angular.isNumber(b.width))c.width=b.width;else if(a.endsWith(b.width,"%")){var f=b.width.replace(/%/g,""),g=parseInt(f,10);if(isNaN(g))throw new Error(e);c.width=b.width}else if(b.width.match(/^(\d+)$/))c.width=parseInt(b.width.match(/^(\d+)$/)[1],10);else{if(!b.width.match(/^\*+$/))throw new Error(e);c.width=b.width}d.prototype.unsort=function(){this.sort={},c.grid.api.core.raise.sortChanged(c,c.grid.getColumnSorting())},c.minWidth=b.minWidth?b.minWidth:30,c.maxWidth=b.maxWidth?b.maxWidth:9e3,c.field=void 0===b.field?b.name:b.field,"string"!=typeof c.field&&a.logError("Field is not a string, this is likely to break the code, Field is: "+c.field),c.name=b.name,c.displayName=void 0===b.displayName?a.readableColumnName(b.name):b.displayName,c.aggregationType=angular.isDefined(b.aggregationType)?b.aggregationType:null,c.footerCellTemplate=angular.isDefined(b.footerCellTemplate)?b.footerCellTemplate:null,c.footerCellClass=b.footerCellClass,c.cellClass=b.cellClass,c.headerCellClass=b.headerCellClass,c.cellFilter=b.cellFilter?b.cellFilter:"",c.headerCellFilter=b.headerCellFilter?b.headerCellFilter:"",c.visible=a.isNullOrUndefined(b.visible)||b.visible,c.headerClass=b.headerClass,c.visible=!0,c.enableSorting="undefined"!=typeof b.enableSorting?b.enableSorting:!0,c.sortingAlgorithm=b.sortingAlgorithm,c.enableFiltering="undefined"!=typeof b.enableFiltering?b.enableFiltering:!0,c.setPropertyOrDefault(b,"menuItems",[]),c.setPropertyOrDefault(b,"sort");var h=[];b.filter?h.push(b.filter):c.enableFiltering&&c.grid.options.enableFiltering&&h.push({}),c.setPropertyOrDefault(b,"filter"),c.setPropertyOrDefault(b,"filters",h)},d.prototype.getColClass=function(a){var c=b.COL_CLASS_PREFIX+this.uid;return a?"."+c:c},d.prototype.getColClassDefinition=function(){return" .grid"+this.grid.id+" "+this.getColClass(!0)+" { width: "+this.drawnWidth+"px; }"},d.prototype.getRenderContainer=function(){var a=this,b=a.renderContainer;return(null===b||""===b||void 0===b)&&(b="body"),a.grid.renderContainers[b]},d.prototype.showColumn=function(){this.colDef.visible=!0},d.prototype.hideColumn=function(){this.colDef.visible=!1},d.prototype.getAggregationValue=function(){var a=this,c=0,d=a.grid.getVisibleRows(),e=[];return angular.forEach(d,function(b){var c=a.grid.getCellValue(b,a);angular.isNumber(c)&&e.push(c)}),angular.isFunction(a.aggregationType)?a.aggregationType(d,a):a.aggregationType===b.aggregationTypes.count?a.getAggregationText("aggregation.count",a.grid.getVisibleRowCount()):a.aggregationType===b.aggregationTypes.sum?(angular.forEach(e,function(a){c+=a}),a.getAggregationText("aggregation.sum",c)):a.aggregationType===b.aggregationTypes.avg?(angular.forEach(e,function(a){c+=a}),c/=e.length,a.getAggregationText("aggregation.avg",c)):a.aggregationType===b.aggregationTypes.min?a.getAggregationText("aggregation.min",Math.min.apply(null,e)):a.aggregationType===b.aggregationTypes.max?a.getAggregationText("aggregation.max",Math.max.apply(null,e)):" "},d.prototype.getAggregationText=function(a,b){var d=this;return d.colDef.aggregationHideLabel?b:c.getSafeText(a)+b},d.prototype.getCellTemplate=function(){var a=this;return a.cellTemplatePromise},d.prototype.getCompiledElementFn=function(){var a=this;return a.compiledElementFnDefer.promise},d}])}(),function(){angular.module("ui.grid").factory("GridOptions",["gridUtil","uiGridConstants",function(a,b){return{initialize:function(c){return c.onRegisterApi=c.onRegisterApi||angular.noop(),c.data=c.data||[],c.columnDefs=c.columnDefs||[],c.excludeProperties=c.excludeProperties||["$$hashKey"],c.enableRowHashing=c.enableRowHashing!==!1,c.rowIdentity=c.rowIdentity||function(b){return a.hashKey(b)},c.getRowIdentity=c.getRowIdentity||function(a){return a.$$hashKey},c.headerRowHeight="undefined"!=typeof c.headerRowHeight?c.headerRowHeight:30,c.rowHeight=c.rowHeight||30,c.maxVisibleRowCount=c.maxVisibleRowCount||200,c.minRowsToShow="undefined"!=typeof c.minRowsToShow?c.minRowsToShow:10,c.showFooter=c.showFooter===!0,c.footerRowHeight="undefined"!=typeof c.footerRowHeight?c.footerRowHeight:30,c.columnWidth="undefined"!=typeof c.columnWidth?c.columnWidth:50,c.maxVisibleColumnCount="undefined"!=typeof c.maxVisibleColumnCount?c.maxVisibleColumnCount:200,c.virtualizationThreshold="undefined"!=typeof c.virtualizationThreshold?c.virtualizationThreshold:20,c.columnVirtualizationThreshold="undefined"!=typeof c.columnVirtualizationThreshold?c.columnVirtualizationThreshold:10,c.excessRows="undefined"!=typeof c.excessRows?c.excessRows:4,c.scrollThreshold="undefined"!=typeof c.scrollThreshold?c.scrollThreshold:4,c.excessColumns="undefined"!=typeof c.excessColumns?c.excessColumns:4,c.horizontalScrollThreshold="undefined"!=typeof c.horizontalScrollThreshold?c.horizontalScrollThreshold:2,c.scrollThrottle="undefined"!=typeof c.scrollThrottle?c.scrollThrottle:70,c.enableSorting=c.enableSorting!==!1,c.enableFiltering=c.enableFiltering===!0,c.enableColumnMenus=c.enableColumnMenus!==!1,c.enableVerticalScrollbar="undefined"!=typeof c.enableVerticalScrollbar?c.enableVerticalScrollbar:b.scrollbars.ALWAYS,c.enableHorizontalScrollbar="undefined"!=typeof c.enableHorizontalScrollbar?c.enableHorizontalScrollbar:b.scrollbars.ALWAYS,c.minimumColumnSize="undefined"!=typeof c.minimumColumnSize?c.minimumColumnSize:10,c.rowEquality=c.rowEquality||function(a,b){return a===b},c.headerTemplate=c.headerTemplate||null,c.footerTemplate=c.footerTemplate||null,c.rowTemplate=c.rowTemplate||"ui-grid/ui-grid-row",c}}}])}(),function(){angular.module("ui.grid").factory("GridRenderContainer",["gridUtil",function(a){function b(a,b,c){var d=this;d.name=a,d.grid=b,d.visibleRowCache=[],d.visibleColumnCache=[],d.renderedRows=[],d.renderedColumns=[],d.prevScrollTop=0,d.prevScrolltopPercentage=0,d.prevRowScrollIndex=0,d.prevScrollLeft=0,d.prevScrollleftPercentage=0,d.prevColumnScrollIndex=0,d.columnStyles="",d.viewportAdjusters=[],c&&angular.isObject(c)&&angular.extend(d,c),b.registerStyleComputation({priority:5,func:function(){return d.columnStyles}})}return b.prototype.reset=function(){this.visibleColumnCache.length=0,this.visibleRowCache.length=0,this.renderedRows.length=0,this.renderedColumns.length=0},b.prototype.minRowsToRender=function(){for(var a=this,b=0,c=0,d=a.getViewportHeight(),e=a.visibleRowCache.length-1;d>c&&e>=0;e--)c+=a.visibleRowCache[e].height,b++;return b},b.prototype.minColumnsToRender=function(){for(var a=this,b=this.getViewportWidth(),c=0,d=0,e=0;e<a.visibleColumnCache.length;e++){var f=a.visibleColumnCache[e];if(b>d)d+=f.drawnWidth?f.drawnWidth:0,c++;else{for(var g=0,h=e;h>=e-c;h--)g+=a.visibleColumnCache[h].drawnWidth?a.visibleColumnCache[h].drawnWidth:0;b>g&&c++}}return c},b.prototype.getVisibleRowCount=function(){return this.visibleRowCache.length
+},b.prototype.registerViewportAdjuster=function(a){this.viewportAdjusters.push(a)},b.prototype.removeViewportAdjuster=function(a){var b=this.viewportAdjusters.indexOf(a);"undefined"!=typeof b&&void 0!==b&&this.viewportAdjusters.splice(b,1)},b.prototype.getViewportAdjustment=function(){var a=this,b={height:0,width:0};return a.viewportAdjusters.forEach(function(a){b=a.call(this,b)}),b},b.prototype.getViewportHeight=function(){var a=this,b=a.headerHeight?a.headerHeight:a.grid.headerHeight,c=a.grid.gridHeight-b-a.grid.footerHeight;"undefined"!=typeof a.horizontalScrollbarHeight&&void 0!==a.horizontalScrollbarHeight&&a.horizontalScrollbarHeight>0&&(c-=a.horizontalScrollbarHeight);var d=a.getViewportAdjustment();return c+=d.height},b.prototype.getViewportWidth=function(){var a=this,b=a.grid.gridWidth;"undefined"!=typeof a.grid.verticalScrollbarWidth&&void 0!==a.grid.verticalScrollbarWidth&&a.grid.verticalScrollbarWidth>0&&(b-=a.grid.verticalScrollbarWidth);var c=a.getViewportAdjustment();return b+=c.width},b.prototype.getHeaderViewportWidth=function(){var a=this,b=this.getViewportWidth();return"undefined"!=typeof a.grid.verticalScrollbarWidth&&void 0!==a.grid.verticalScrollbarWidth&&a.grid.verticalScrollbarWidth>0&&(b+=a.grid.verticalScrollbarWidth),b},b.prototype.getCanvasHeight=function(){var a=this,b=0;return a.visibleRowCache.forEach(function(a){b+=a.height}),"undefined"!=typeof a.grid.horizontalScrollbarHeight&&void 0!==a.grid.horizontalScrollbarHeight&&a.grid.horizontalScrollbarHeight>0&&(b-=a.grid.horizontalScrollbarHeight),b},b.prototype.getCanvasWidth=function(){var a=this,b=a.canvasWidth;return"undefined"!=typeof a.verticalScrollbarWidth&&void 0!==a.verticalScrollbarWidth&&a.verticalScrollbarWidth>0&&(b-=a.verticalScrollbarWidth),b},b.prototype.setRenderedRows=function(a){this.renderedRows.length=a.length;for(var b=0;b<a.length;b++)this.renderedRows[b]=a[b]},b.prototype.setRenderedColumns=function(a){this.renderedColumns.length=a.length;for(var b=0;b<a.length;b++)this.renderedColumns[b]=a[b];this.updateColumnOffset()},b.prototype.updateColumnOffset=function(){for(var a=0,b=0;b<this.currentFirstColumn;b++)a+=this.visibleColumnCache[b].drawnWidth;this.columnOffset=a},b.prototype.adjustScrollVertical=function(a,b,c){(this.prevScrollTop!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasHeight()-this.getCanvasWidth())*b),this.adjustRows(a,b),this.prevScrollTop=a,this.prevScrolltopPercentage=b,this.grid.queueRefresh())},b.prototype.adjustScrollHorizontal=function(a,b,c){(this.prevScrollLeft!==a||c)&&(("undefined"==typeof a||void 0===a||null===a)&&(a=(this.getCanvasWidth()-this.getViewportWidth())*b),this.adjustColumns(a,b),this.prevScrollLeft=a,this.prevScrollleftPercentage=b,this.grid.queueRefresh())},b.prototype.adjustRows=function(a,b){var c=this,d=c.minRowsToRender(),e=c.visibleRowCache,f=e.length-d;c.maxRowIndex=f;c.prevRowScrollIndex;"undefined"!=typeof b&&null!==b||!a||(b=a/c.getCanvasHeight());var g=Math.ceil(Math.min(f,f*b));g>f&&(g=f);var h=[];if(e.length>c.grid.options.virtualizationThreshold){if(c.prevScrollTop<a&&g<c.prevRowScrollIndex+c.grid.options.scrollThreshold&&f>g)return;if(c.prevScrollTop>a&&g>c.prevRowScrollIndex-c.grid.options.scrollThreshold&&f>g)return;var i=Math.max(0,g-c.grid.options.excessRows),j=Math.min(e.length,g+d+c.grid.options.excessRows);h=[i,j]}else{var k=c.visibleRowCache.length;h=[0,Math.max(k,d+c.grid.options.excessRows)]}c.updateViewableRowRange(h),c.prevRowScrollIndex=g},b.prototype.adjustColumns=function(a,b){var c=this,d=c.minColumnsToRender(),e=c.visibleColumnCache,f=e.length-d;"undefined"!=typeof b&&null!==b||!a||(b=a/c.getCanvasWidth());var g=Math.ceil(Math.min(f,f*b));g>f&&(g=f);var h=[];if(e.length>c.grid.options.columnVirtualizationThreshold&&c.getCanvasWidth()>c.getViewportWidth()){if(c.prevScrollLeft<a&&g<c.prevColumnScrollIndex+c.grid.options.horizontalScrollThreshold&&f>g)return;if(c.prevScrollLeft>a&&g>c.prevColumnScrollIndex-c.grid.options.horizontalScrollThreshold&&f>g)return;var i=Math.max(0,g-c.grid.options.excessColumns),j=Math.min(e.length,g+d+c.grid.options.excessColumns);h=[i,j]}else{var k=c.visibleColumnCache.length;h=[0,Math.max(k,d+c.grid.options.excessColumns)]}c.updateViewableColumnRange(h),c.prevColumnScrollIndex=g},b.prototype.updateViewableRowRange=function(a){var b=this.visibleRowCache.slice(a[0],a[1]);this.currentTopRow=a[0],this.setRenderedRows(b)},b.prototype.updateViewableColumnRange=function(a){var b=this.visibleColumnCache.slice(a[0],a[1]);this.currentFirstColumn=a[0],this.setRenderedColumns(b)},b.prototype.rowStyle=function(a){var b=this,c={};if(0===a&&0!==b.currentTopRow){var d=b.currentTopRow*b.grid.options.rowHeight;c["margin-top"]=d+"px"}return 0!==b.currentFirstColumn&&(b.grid.isRTL()?c["margin-right"]=b.columnOffset+"px":c["margin-left"]=b.columnOffset+"px"),c},b.prototype.columnStyle=function(a){var b=this;if(0===a&&0!==b.currentFirstColumn){var c=b.columnOffset;return b.grid.isRTL()?{"margin-right":c+"px"}:{"margin-left":c+"px"}}return null},b.prototype.updateColumnWidths=function(){var b=this,c=[],d=[],e=0,f=b.getViewportWidth();"undefined"!=typeof b.grid.verticalScrollbarWidth&&void 0!==b.grid.verticalScrollbarWidth&&b.grid.verticalScrollbarWidth>0&&(f+=b.grid.verticalScrollbarWidth);var g,h=0,i=0,j="",k=b.visibleColumnCache;k.forEach(function(b){if(b.visible){var f=!1;angular.isNumber(b.width)||(f=isNaN(b.width)&&a.endsWith(b.width,"%")),angular.isString(b.width)&&-1!==b.width.indexOf("*")?(e=parseInt(e+b.width.length,10),c.push(b)):f?d.push(b):angular.isNumber(b.width)&&(h=parseInt(h+b.width,10),i=parseInt(i,10)+parseInt(b.width,10),b.drawnWidth=b.width)}});var l,m,n,o=f-h;if(d.length>0){for(l=0;l<d.length;l++){m=d[l];var p=parseInt(m.width.replace(/%/g,""),10)/100;n=parseInt(p*o,10),m.colDef.minWidth&&n<m.colDef.minWidth?(n=m.colDef.minWidth,o-=n,i+=n,m.drawnWidth=n,d.splice(l,1)):m.colDef.maxWidth&&n>m.colDef.maxWidth&&(n=m.colDef.maxWidth,o-=n,i+=n,m.drawnWidth=n,d.splice(l,1))}d.forEach(function(a){var b=parseInt(a.width.replace(/%/g,""),10)/100,c=parseInt(b*o,10);i+=c,a.drawnWidth=c})}if(c.length>0){var q=parseInt(o/e,10);for(l=0;l<c.length;l++)m=c[l],n=parseInt(q*m.width.length,10),m.colDef.minWidth&&n<m.colDef.minWidth?(n=m.colDef.minWidth,o-=n,e--,i+=n,m.drawnWidth=n,g=m,c.splice(l,1)):m.colDef.maxWidth&&n>m.colDef.maxWidth&&(n=m.colDef.maxWidth,o-=n,e--,i+=n,m.drawnWidth=n,c.splice(l,1));q=parseInt(o/e,10),c.forEach(function(a){var b=parseInt(q*a.width.length,10);i+=b,a.drawnWidth=b})}var r=f-parseInt(i,10);if(r>0&&i>0&&f>i){var s=!1;if(k.forEach(function(a){a.width&&!angular.isNumber(a.width)&&(s=!0)}),s)for(var t=function(a){r>0&&(a.drawnWidth=a.drawnWidth+1,i+=1,r--)};r>0;)k.forEach(t)}f>i&&(i=f),k.forEach(function(a){j+=a.getColClassDefinition()}),b.grid.verticalScrollbarWidth&&(i+=b.grid.verticalScrollbarWidth),b.canvasWidth=parseInt(i,10),this.columnStyles=j},b}])}(),function(){angular.module("ui.grid").factory("GridRow",["gridUtil",function(a){function b(b,c,d){this.grid=d,this.entity=b,this.uid=a.nextUid(),this.visible=!0,this.height=d.options.rowHeight}return b.prototype.getQualifiedColField=function(a){return"row."+this.getEntityQualifiedColField(a)},b.prototype.getEntityQualifiedColField=function(b){return a.preEval("entity."+b.field)},b.prototype.setRowInvisible=function(a){null!==a&&(a.forceInvisible=!0,a.visible&&(a.visible=!1,a.grid.refresh(),a.grid.api.core.raise.rowsVisibleChanged()))},b.prototype.clearRowInvisible=function(a){null!==a&&(a.forceInvisible=!1,a.visible||(a.visible=!0,a.grid.refresh(),a.grid.api.core.raise.rowsVisibleChanged()))},b}])}(),function(){"use strict";angular.module("ui.grid").service("gridClassFactory",["gridUtil","$q","$compile","$templateCache","uiGridConstants","Grid","GridColumn","GridRow",function(a,b,c,d,e,f){var g={createGrid:function(d){d="undefined"!=typeof d?d:{},d.id=a.newId();var e=new f(d);if(e.options.rowTemplate){var h=b.defer();e.getRowTemplateFn=h.promise,a.getTemplate(e.options.rowTemplate).then(function(a){var b=c(a);h.resolve(b)},function(){throw new Error("Couldn't fetch/use row template '"+e.options.rowTemplate+"'")})}return e.registerColumnBuilder(g.defaultColumnBuilder),e.registerRowsProcessor(function(a){return a.forEach(function(a){a.visible=!a.forceInvisible}),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.visible=!0}),a}),e.registerColumnsProcessor(function(a){return a.forEach(function(a){a.colDef.visible===!1&&(a.visible=!1)}),a}),e.options.enableFiltering&&e.registerRowsProcessor(e.searchRows),e.registerRowsProcessor(e.options.externalSort&&angular.isFunction(e.options.externalSort)?e.options.externalSort:e.sortByColumn),e},defaultColumnBuilder:function(c,d){var f=[];return d.providedHeaderCellTemplate=c.headerCellTemplate?c.headerCellTemplate:"ui-grid/uiGridHeaderCell",d.providedCellTemplate=c.cellTemplate?c.cellTemplate:"ui-grid/uiGridCell",d.cellTemplatePromise=a.getTemplate(d.providedCellTemplate),f.push(d.cellTemplatePromise.then(function(a){d.cellTemplate=a.replace(e.CUSTOM_FILTERS,d.cellFilter?"|"+d.cellFilter:"")},function(){throw new Error("Couldn't fetch/use colDef.cellTemplate '"+c.cellTemplate+"'")})),f.push(a.getTemplate(d.providedHeaderCellTemplate).then(function(a){d.headerCellTemplate=a.replace(e.CUSTOM_FILTERS,d.headerCellFilter?"|"+d.headerCellFilter:"")},function(){throw new Error("Couldn't fetch/use colDef.headerCellTemplate '"+c.headerCellTemplate+"'")})),d.compiledElementFnDefer=b.defer(),b.all(f)}};return g}])}(),function(){function a(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function b(){var a=function(b,c){return b&&a.cache[b]?a.cache[b]:b&&c?(a.cache[b]=c,a.cache[b]):void 0};return a.cache={},a.clear=function(){a.cache={}},a}var c=angular.module("ui.grid");c.service("rowSearcher",["gridUtil","uiGridConstants",function(c,d){var e=d.filter.STARTS_WITH,f={};return f.getTerm=function(a){if("undefined"==typeof a.term)return a.term;var b=a.term;return"string"==typeof b&&(b=b.trim()),b},f.stripTerm=function(b){var c=f.getTerm(b);return"string"==typeof c?a(c.replace(/(^\*|\*$)/g,"")):c},f.guessCondition=function(a){if("undefined"==typeof a.term||!a.term)return e;var b=f.getTerm(a);if(/\*/.test(b)){var c="";a.flags&&a.flags.caseSensitive||(c+="i");var d=b.replace(/(\\)?\*/g,function(a,b){return b?a:"[\\s\\S]*?"});return new RegExp("^"+d+"$",c)}return e},f.runColumnFilter=function(a,b,c,e,g,h){var i=typeof h.condition;"undefined"!==i&&h.condition||(h.condition=d.filter.CONTAINS);var j=f.stripTerm(h);if(null===j||void 0===j||""===j)return!0;var k=a.getCellValue(b,c),l="";h.flags&&h.flags.caseSensitive||(l+="i");var m=c.field+g;if(h.condition instanceof RegExp){if(!h.condition.test(k))return!1}else{if("function"===i)return h.condition(j,k,b,c);if(h.condition===d.filter.STARTS_WITH){var n=e(m)?e(m):e(m,new RegExp("^"+j,l));if(!n.test(k))return!1}else if(h.condition===d.filter.ENDS_WITH){var o=e(m)?e(m):e(m,new RegExp(j+"$",l));if(!o.test(k))return!1}else if(h.condition===d.filter.CONTAINS){var p=e(m)?e(m):e(m,new RegExp(j,l));if(!p.test(k))return!1}else if(h.condition===d.filter.EXACT){var q=e(m)?e(m):e(m,new RegExp("^"+j+"$",l));if(!q.test(k))return!1}else if(h.condition===d.filter.GREATER_THAN){if(j>=k)return!1}else if(h.condition===d.filter.GREATER_THAN_OR_EQUAL){if(j>k)return!1}else if(h.condition===d.filter.LESS_THAN){if(k>=j)return!1}else if(h.condition===d.filter.LESS_THAN_OR_EQUAL){if(k>j)return!1}else if(h.condition===d.filter.NOT_EQUAL&&!angular.equals(k,j))return!1}return!0},f.searchColumn=function(a,b,c,d){var e=[];if(a.options.useExternalFiltering)return!0;if(!("undefined"!=typeof c.filters&&c.filters&&c.filters.length>0))return!0;e=c.filters;for(var g in e){var h=e[g];if(!h.condition){var i="cond-"+c.field+"-"+h.term,j=d(i)?d(i):d(i,f.guessCondition(h));h={term:h.term,condition:j,flags:angular.extend({caseSensitive:!1},h.flags)}}var k=f.runColumnFilter(a,b,c,d,g,h);if(!k)return!1}return!0},f.search=function(a,c,d){if(c){var e=new b,g=[];return d.forEach(function(a){"undefined"!=typeof a.filters&&a.filters.length>0?g.push(a):"undefined"!=typeof a.filter&&a.filter&&"undefined"!=typeof a.filter.term&&a.filter.term&&g.push(a)}),g.length>0&&(g.forEach(function(b){c.forEach(function(c){(c.forceInvisible||!f.searchColumn(a,c,b,e))&&(c.visible=!1)})}),a.api.core.raise.rowsVisibleChanged&&a.api.core.raise.rowsVisibleChanged()),e.clear(),c}},f}])}(),function(){var a=angular.module("ui.grid");a.service("rowSorter",["$parse","uiGridConstants",function(a,b){var c="("+b.CURRENCY_SYMBOLS.map(function(a){return"\\"+a}).join("|")+")?",d=(new RegExp("^[-+]?"+c+"[\\d,.]+"+c+"%?$"),{colSortFnCache:[]});return d.guessSortFn=function(a){switch(a){case"number":return d.sortNumber;case"boolean":return d.sortBool;case"string":return d.sortAlpha;case"date":return d.sortDate;case"object":return d.basicSort;default:throw new Error("No sorting function found for type:"+a)}},d.handleNulls=function(a,b){if(!a&&0!==a&&a!==!1||!b&&0!==b&&b!==!1){if(!a&&0!==a&&a!==!1&&!b&&0!==b&&b!==!1)return 0;if(!a&&0!==a&&a!==!1)return 1;if(!b&&0!==b&&b!==!1)return-1}return null},d.basicSort=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a===b?0:b>a?-1:1},d.sortNumber=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a-b},d.sortNumberStr=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e,f,g=!1,h=!1;return e=parseFloat(a.replace(/[^0-9.-]/g,"")),isNaN(e)&&(g=!0),f=parseFloat(b.replace(/[^0-9.-]/g,"")),isNaN(f)&&(h=!0),g&&h?0:g?1:h?-1:e-f},d.sortAlpha=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e=a.toLowerCase(),f=b.toLowerCase();return e===f?0:f>e?-1:1},d.sortDate=function(a,b){var c=d.handleNulls(a,b);if(null!==c)return c;var e=a.getTime(),f=b.getTime();return e===f?0:f>e?-1:1},d.sortBool=function(a,b){var c=d.handleNulls(a,b);return null!==c?c:a&&b?0:a||b?a?1:-1:0},d.getSortFn=function(a,b){var c;return d.colSortFnCache[b.colDef.name]?c=d.colSortFnCache[b.colDef.name]:void 0!==b.sortingAlgorithm?(c=b.sortingAlgorithm,d.colSortFnCache[b.colDef.name]=b.sortingAlgorithm):(c=d.guessSortFn(b.colDef.type),c?d.colSortFnCache[b.colDef.name]=c:c=d.sortAlpha),c},d.prioritySort=function(a,b){return void 0!==a.sort.priority&&void 0!==b.sort.priority?a.sort.priority<b.sort.priority?-1:a.sort.priority===b.sort.priority?0:1:a.sort.priority||0===a.sort.priority?-1:b.sort.priority||0===b.sort.priority?1:0},d.sort=function(a,c,e){if(c){if(a.options.useExternalSorting)return c;var f=[];if(e.forEach(function(a){a.sort&&a.sort.direction&&(a.sort.direction===b.ASC||a.sort.direction===b.DESC)&&f.push(a)}),f=f.sort(d.prioritySort),0===f.length)return c;var g,h,i=c.slice(0);return c.sort(function(c,e){for(var j,k=0,l=0;0===k&&l<f.length;){g=f[l],h=f[l].sort.direction,j=d.getSortFn(a,g,i);var m=a.getCellValue(c,g),n=a.getCellValue(e,g);k=j(m,n),l++}return h===b.ASC?k:0-k})}},d}])}(),function(){function a(a){var b=a;return"undefined"!=typeof b.length&&b.length&&(b=a[0]),b.ownerDocument.defaultView.getComputedStyle(b,null)}function b(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0,h=["Top","Right","Bottom","Left"];4>f;f+=2){var i=h[f];if("margin"===c){var j=parseFloat(e[c+i]);isNaN(j)||(g+=j)}if(d){if("content"===c){var k=parseFloat(e["padding"+i]);isNaN(k)||(g-=k)}if("margin"!==c){var l=parseFloat(e["border"+i+"Width"]);isNaN(l)||(g-=l)}}else{var m=parseFloat(e["padding"+i]);if(isNaN(m)||(g+=m),"padding"!==c){var n=parseFloat(e["border"+i+"Width"]);isNaN(n)||(g+=n)}}}return g}function c(c,d,f){var g,h=!0,i=a(c),j="border-box"===i.boxSizing;if(0>=g||null==g){if(g=i[d],(0>g||null==g)&&(g=c.style[d]),e.test(g))return g;h=j&&!0,g=parseFloat(g)||0}var k=g+b(c,d,f||(j?"border":"content"),h,i);return k}var d=angular.module("ui.grid"),e=new RegExp("^("+/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source+")(?!px)[a-z%]+$","i"),f=/^(block|none|table(?!-c[ea]).+)/,g={position:"absolute",visibility:"hidden",display:"block"},h=["0","0","0"],i="uiGrid-";d.service("gridUtil",["$log","$window","$document","$http","$templateCache","$timeout","$injector","$q","$interpolate","uiGridConstants",function(b,d,e,j,k,l,m,n,o,p){var q={getStyles:a,createBoundedWrapper:function(a,b){return function(){return b.apply(a,arguments)}},readableColumnName:function(a){return"undefined"==typeof a||void 0===a||null===a?a:("string"!=typeof a&&(a=String(a)),a.replace(/_+/g," ").replace(/^[A-Z]+$/,function(a){return angular.lowercase(angular.uppercase(a.charAt(0))+a.slice(1))}).replace(/(\w+)/g,function(a){return angular.uppercase(a.charAt(0))+a.slice(1)}).replace(/(\w+?(?=[A-Z]))/g,"$1 "))},getColumnsFromData:function(a,b){var c=[];if(!a||"undefined"==typeof a[0]||void 0===a[0])return[];angular.isUndefined(b)&&(b=[]);var d=a[0];return angular.forEach(d,function(a,d){-1===b.indexOf(d)&&c.push({name:d})}),c},newId:function(){var a=(new Date).getTime();return function(){return a+=1}}(),getTemplate:function(a){if(k.get(a))return q.postProcessTemplate(k.get(a));if(a.hasOwnProperty("then"))return a.then(q.postProcessTemplate);try{if(angular.element(a).length>0)return n.when(a).then(q.postProcessTemplate)}catch(b){}return q.logDebug("fetching url",a),j({method:"GET",url:a}).then(function(b){var c=b.data.trim();return k.put(a,c),c},function(b){throw new Error("Could not get template "+a+": "+b)}).then(q.postProcessTemplate)},postProcessTemplate:function(a){var b=o.startSymbol(),c=o.endSymbol();return("{{"!==b||"}}"!==c)&&(a=a.replace(/\{\{/g,b),a=a.replace(/\}\}/g,c)),n.when(a)},guessType:function(a){var b=typeof a;switch(b){case"number":case"boolean":case"string":return b;default:return angular.isDate(a)?"date":"object"}},elementWidth:function(){},elementHeight:function(){},getScrollbarWidth:function(){var a=document.createElement("div");a.style.visibility="hidden",a.style.width="100px",a.style.msOverflowStyle="scrollbar",document.body.appendChild(a);var b=a.offsetWidth;a.style.overflow="scroll";var c=document.createElement("div");c.style.width="100%",a.appendChild(c);var d=c.offsetWidth;return a.parentNode.removeChild(a),b-d},swap:function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},fakeElement:function(a,b,c){var d,e,f=angular.element(a).clone()[0];for(e in b)f.style[e]=b[e];return angular.element(document.body).append(f),d=c.call(f,f),angular.element(f).remove(),d},normalizeWheelEvent:function(a){var b,c,d,e=a||window.event,f=([].slice.call(arguments,1),0),g=0,h=0,i=0,j=0;return e.originalEvent&&(e=e.originalEvent),e.wheelDelta&&(f=e.wheelDelta),e.detail&&(f=-1*e.detail),h=f,void 0!==e.axis&&e.axis===e.HORIZONTAL_AXIS&&(h=0,g=-1*f),e.deltaY&&(h=-1*e.deltaY,f=h),e.deltaX&&(g=e.deltaX,f=-1*g),void 0!==e.wheelDeltaY&&(h=e.wheelDeltaY),void 0!==e.wheelDeltaX&&(g=e.wheelDeltaX),i=Math.abs(f),(!b||b>i)&&(b=i),j=Math.max(Math.abs(h),Math.abs(g)),(!c||c>j)&&(c=j),d=f>0?"floor":"ceil",f=Math[d](f/b),g=Math[d](g/c),h=Math[d](h/c),{delta:f,deltaX:g,deltaY:h}},isTouchEnabled:function(){var a;return("ontouchstart"in d||d.DocumentTouch&&e instanceof DocumentTouch)&&(a=!0),a},isNullOrUndefined:function(a){return void 0===a||null===a?!0:!1},endsWith:function(a,b){return a&&b&&"string"==typeof a?-1!==a.indexOf(b,a.length-b.length):!1},arrayContainsObjectWithProperty:function(a,b,c){var d=!1;return angular.forEach(a,function(a){a[b]===c&&(d=!0)}),d},requestAnimationFrame:d.requestAnimationFrame&&d.requestAnimationFrame.bind(d)||d.webkitRequestAnimationFrame&&d.webkitRequestAnimationFrame.bind(d)||function(a){return l(a,10,!1)},numericAndNullSort:function(a,b){return null===a?1:null===b?-1:null===a&&null===b?0:a-b},disableAnimations:function(a){var b;try{b=m.get("$animate"),b.enabled(!1,a)}catch(c){}},enableAnimations:function(a){var b;try{return b=m.get("$animate"),b.enabled(!0,a),b}catch(c){}},nextUid:function(){for(var a,b=h.length;b;){if(b--,a=h[b].charCodeAt(0),57===a)return h[b]="A",i+h.join("");if(90!==a)return h[b]=String.fromCharCode(a+1),i+h.join("");h[b]="0"}return h.unshift("0"),i+h.join("")},hashKey:function(a){var b,c=typeof a;return"object"===c&&null!==a?"function"==typeof(b=a.$$hashKey)?b=a.$$hashKey():"undefined"!=typeof a.$$hashKey&&a.$$hashKey?b=a.$$hashKey:void 0===b&&(b=a.$$hashKey=q.nextUid()):b=a,c+":"+b},resetUids:function(){h=["0","0","0"]},logError:function(a){p.LOG_ERROR_MESSAGES&&b.error(a)},logWarn:function(a){p.LOG_WARN_MESSAGES&&b.warn(a)},logDebug:function(){p.LOG_DEBUG_MESSAGES&&b.debug.apply(b,arguments)}};return["width","height"].forEach(function(b){var d=angular.uppercase(b.charAt(0))+b.substr(1);q["element"+d]=function(d,e){var h=d;if(h&&"undefined"!=typeof h.length&&h.length&&(h=d[0]),h){var i=a(h);return 0===h.offsetWidth&&f.test(i.display)?q.fakeElement(h,g,function(a){return c(a,b,e)}):c(h,b,e)}return null},q["outerElement"+d]=function(a,b){return a?q["element"+d].call(this,a,b?"margin":"border"):null}}),q.closestElm=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c;["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"].some(function(a){return"function"==typeof document.body[a]?(c=a,!0):!1});for(var d;null!==a;){if(d=a.parentElement,null!==d&&d[c](b))return d;a=d}return null},q.type=function(a){var b=Function.prototype.toString.call(a.constructor);return b.match(/function (.*?)\(/)[1]},q.getBorderSize=function(b,c){"undefined"!=typeof b.length&&b.length&&(b=b[0]);var d=a(b);c=c?"border"+c.charAt(0).toUpperCase()+c.slice(1):"border",c+="Width";var e=parseInt(d[c],10);return isNaN(e)?0:e},q.detectBrowser=function(){var a=d.navigator.userAgent,b={chrome:/chrome/i,safari:/safari/i,firefox:/firefox/i,ie:/internet explorer|trident\//i};for(var c in b)if(b[c].test(a))return c;return"unknown"},q.normalizeScrollLeft=function(a){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var b=q.detectBrowser(),c=a.scrollLeft,d=q.getStyles(a).direction;if("ie"===b)return c;if("chrome"===b){if("rtl"===d){var e=a.scrollWidth-a.clientWidth;return e-c}return c}return"firefox"===b?Math.abs(c):c},q.denormalizeScrollLeft=function(a,b){"undefined"!=typeof a.length&&a.length&&(a=a[0]);var c=q.detectBrowser(),d=q.getStyles(a).direction;if("ie"===c)return b;if("chrome"===c){if("rtl"===d){var e=a.scrollWidth-a.clientWidth;return e-b}return b}return"firefox"===c&&"rtl"===d?-1*b:b},q.preEval=function(a){var b=p.BRACKET_REGEXP.exec(a);if(b)return(b[1]?q.preEval(b[1]):b[1])+b[2]+(b[3]?q.preEval(b[3]):b[3]);a=a.replace(p.APOS_REGEXP,"\\'");var c=a.split(p.DOT_REGEXP),d=[c.shift()];return angular.forEach(c,function(a){d.push(a.replace(p.FUNC_REGEXP,"']$1"))}),d.join("['")},q.debounce=function(a,b,c){function d(){g=this,f=arguments;var d=function(){e=null,c||(h=a.apply(g,f))},i=c&&!e;return e&&l.cancel(e),e=l(d,b),i&&(h=a.apply(g,f)),h}var e,f,g,h;return d.cancel=function(){l.cancel(e),e=null},d},q.throttle=function(a,b,c){function d(){g=+new Date,a.apply(e,f),l(function(){h=null},0)}c=c||{};var e,f,g=0,h=null;return function(){if(e=this,f=arguments,null===h){var a=+new Date-g;a>b?d():c.trailing&&(h=l(d,b-a))}}},q}]),d.filter("px",function(){return function(a){return a.match(/^[\d\.]+$/)?a+"px":a}})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("da",{aggregate:{label:"artikler"},groupPanel:{description:"Grupér rækker udfra en kolonne ved at trække dens overskift hertil."},search:{placeholder:"Søg...",showingItems:"Viste rækker:",selectedItems:"Valgte rækker:",totalItems:"Rækker totalt:",size:"Side størrelse:",first:"Første side",next:"Næste side",previous:"Forrige side",last:"Sidste side"},menu:{text:"Vælg kolonner:"},column:{hide:"Skjul kolonne"},aggregation:{count:"samlede rækker: ",sum:"smalede: ",avg:"gns: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("de",{aggregate:{label:"eintrag"},groupPanel:{description:"Ziehen Sie eine Spaltenüberschrift hierhin, um nach dieser Spalte zu gruppieren."},search:{placeholder:"Suche...",showingItems:"Zeige Einträge:",selectedItems:"Ausgewählte Einträge:",totalItems:"Einträge gesamt:",size:"Einträge pro Seite:",first:"Erste Seite",next:"Nächste Seite",previous:"Vorherige Seite",last:"Letzte Seite"},menu:{text:"Spalten auswählen:"},sort:{ascending:"aufsteigend sortieren",descending:"absteigend sortieren",remove:"Sortierung zurücksetzen"},column:{hide:"Spalte ausblenden"},aggregation:{count:"Zeilen insgesamt: ",sum:"gesamt: ",avg:"Durchschnitt: ",min:"min: ",max:"max: "},gridMenu:{columns:"Spalten:",importerTitle:"Datei importieren",exporterAllAsCsv:"Alle Daten als CSV exportieren",exporterVisibleAsCsv:"sichtbare Daten als CSV exportieren",exporterSelectedAsCsv:"markierte Daten als CSV exportieren",exporterAllAsPdf:"Alle Daten als PDF exportieren",exporterVisibleAsPdf:"sichtbare Daten als PDF exportieren",exporterSelectedAsPdf:"markierte Daten als CSV exportieren"},importer:{noHeaders:"Es konnten keine Spaltennamen ermittelt werden. Sind in der Datei Spaltendefinitionen enthalten?",noObjects:"Es konnten keine Zeileninformationen gelesen werden, Sind in der Datei außer den Spaltendefinitionen auch Daten enthalten?",invalidCsv:"Die Datei konnte nicht eingelesen werden, ist es eine gültige CSV-Datei?",invalidJson:"Die Datei konnte nicht eingelesen werden. Enthält sie gültiges JSON?",jsonNotArray:"Die importierte JSON-Datei muß ein Array enthalten. Breche Import ab."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("en",{aggregate:{label:"items"},groupPanel:{description:"Drag a column header here and drop it to group by that column."},search:{placeholder:"Search...",showingItems:"Showing Items:",selectedItems:"Selected Items:",totalItems:"Total Items:",size:"Page Size:",first:"First Page",next:"Next Page",previous:"Previous Page",last:"Last Page"},menu:{text:"Choose Columns:"},sort:{ascending:"Sort Ascending",descending:"Sort Descending",remove:"Remove Sort"},column:{hide:"Hide Column"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Pin Left",pinRight:"Pin Right",unpin:"Unpin"},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."},paging:{sizes:"items per page",totalItems:"items"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("es",{aggregate:{label:"Artículos"},groupPanel:{description:"Arrastre un encabezado de columna aquí y suéltelo para agrupar por esa columna."},search:{placeholder:"Buscar...",showingItems:"Artículos Mostrados:",selectedItems:"Artículos Seleccionados:",totalItems:"Artículos Totales:",size:"Tamaño de Página:",first:"Primera Página",next:"Página Siguiente",previous:"Página Anterior",last:"Última Página"},menu:{text:"Elegir columnas:"},sort:{ascending:"Orden Ascendente",descending:"Orden Descendente",remove:"Sin Ordenar"},column:{hide:"Ocultar la columna"},aggregation:{count:"filas totales: ",sum:"total: ",avg:"media: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fijar a la Izquierda",pinRight:"Fijar a la Derecha",unpin:"Quitar Fijación"},gridMenu:{columns:"Columnas:",importerTitle:"Importar archivo",exporterAllAsCsv:"Exportar todo como csv",exporterVisibleAsCsv:"Exportar vista como csv",exporterSelectedAsCsv:"Exportar selección como csv",exporterAllAsPdf:"Exportar todo como pdf",exporterVisibleAsPdf:"Exportar vista como pdf",exporterSelectedAsPdf:"Exportar selección como pdf"},importer:{noHeaders:"No fue posible derivar los nombres de las columnas, ¿tiene encabezados el archivo?",noObjects:"No fue posible obtener registros, ¿contiene datos el archivo, aparte de los encabezados?",invalidCsv:"No fue posible procesar el archivo, ¿es un CSV válido?",invalidJson:"No fue posible procesar el archivo, ¿es un Json válido?",jsonNotArray:"El archivo json importado debe contener un array, abortando."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fa",{aggregate:{label:"موردها"},groupPanel:{description:"یک عنوان ستون اینجا را بردار و به گروهی از آن ستون بیانداز."},search:{placeholder:"جستجو...",showingItems:"نمایش موردها:",selectedItems:"موردهای انتخاب‌شده:",totalItems:"همهٔ موردها:",size:"اندازهٔ صفحه:",first:"صفحهٔ اول",next:"صفحهٔ بعد",previous:"صفحهٔ قبل",last:"آخرین صفحه"},menu:{text:"انتخاب ستون‌ها:"},column:{hide:"ستون پنهان کن"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fi",{aggregate:{label:"rivit"},groupPanel:{description:"Raahaa ja pudota otsikko tähän ryhmittääksesi sarakkeen mukaan."},search:{placeholder:"Hae...",showingItems:"Näytetään rivejä:",selectedItems:"Valitut rivit:",totalItems:"Rivejä yht.:",size:"Näytä:",first:"Ensimmäinen sivu",next:"Seuraava sivu",previous:"Edellinen sivu",last:"Viimeinen sivu"},menu:{text:"Valitse sarakkeet:"},sort:{ascending:"Järjestä nouseva",descending:"Järjestä laskeva",remove:"Poista järjestys"},column:{hide:"Piilota sarake"},aggregation:{count:"Rivejä yht.: ",sum:"Summa: ",avg:"K.a.: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Lukitse vasemmalle",pinRight:"Lukitse oikealle",unpin:"Poista lukitus"},gridMenu:{columns:"Sarakkeet:",importerTitle:"Tuo tiedosto",exporterAllAsCsv:"Vie tiedot csv-muodossa",exporterVisibleAsCsv:"Vie näkyvä tieto csv-muodossa",exporterSelectedAsCsv:"Vie valittu tieto csv-muodossa",exporterAllAsPdf:"Vie tiedot pdf-muodossa",exporterVisibleAsPdf:"Vie näkyvä tieto pdf-muodossa",exporterSelectedAsPdf:"Vie valittu tieto pdf-muodossa"},importer:{noHeaders:"Sarakkeen nimiä ei voitu päätellä, onko tiedostossa otsikkoriviä?",noObjects:"Tietoja ei voitu lukea, onko tiedostossa muuta kuin otsikkot?",invalidCsv:"Tiedostoa ei voitu käsitellä, oliko se CSV-muodossa?",invalidJson:"Tiedostoa ei voitu käsitellä, oliko se JSON-muodossa?",jsonNotArray:"Tiedosto ei sisältänyt taulukkoa, lopetetaan."}}),a
+}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("fr",{aggregate:{label:"articles"},groupPanel:{description:"Faites glisser un en-tête de colonne ici et déposez-le vers un groupe par cette colonne."},search:{placeholder:"Recherche...",showingItems:"Articles Affichage des:",selectedItems:"Éléments Articles:",totalItems:"Nombre total d'articles:",size:"Taille de page:",first:"Première page",next:"Page Suivante",previous:"Page précédente",last:"Dernière page"},menu:{text:"Choisir des colonnes:"},sort:{ascending:"Trier par ordre croissant",descending:"Trier par ordre décroissant",remove:"Enlever le tri"},column:{hide:"Cacher la colonne"},aggregation:{count:"total lignes: ",sum:"total: ",avg:"moy: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Épingler à gauche",pinRight:"Épingler à droite",unpin:"Détacher"},gridMenu:{columns:"Colonnes:",importerTitle:"Importer un fichier",exporterAllAsCsv:"Exporter toutes les données en CSV",exporterVisibleAsCsv:"Exporter les données visibles en CSV",exporterSelectedAsCsv:"Exporter les données sélectionnées en CSV",exporterAllAsPdf:"Exporter toutes les données en PDF",exporterVisibleAsPdf:"Exporter les données visibles en PDF",exporterSelectedAsPdf:"Exporter les données sélectionnées en PDF"},importer:{noHeaders:"Impossible de déterminer le nom des colonnes, le fichier possède-t-il un en-tête ?",noObjects:"Aucun objet trouvé, le fichier possède-t-il des données autres que l'en-tête ?",invalidCsv:"Le fichier n'a pas pu être traité, le CSV est-il valide ?",invalidJson:"Le fichier n'a pas pu être traité, le JSON est-il valide ?",jsonNotArray:"Le fichier JSON importé doit contenir un tableau. Abandon."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("he",{aggregate:{label:"items"},groupPanel:{description:"גרור עמודה לכאן ושחרר בכדי לקבץ עמודה זו."},search:{placeholder:"חפש...",showingItems:"מציג:",selectedItems:'סה"כ נבחרו:',totalItems:'סה"כ רשומות:',size:"תוצאות בדף:",first:"דף ראשון",next:"דף הבא",previous:"דף קודם",last:"דף אחרון"},menu:{text:"בחר עמודות:"},sort:{ascending:"סדר עולה",descending:"סדר יורד",remove:"בטל"},column:{hide:"טור הסתר"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("it",{aggregate:{label:"elementi"},groupPanel:{description:"Trascina un'intestazione all'interno del gruppo della colonna."},search:{placeholder:"Ricerca...",showingItems:"Mostra:",selectedItems:"Selezionati:",totalItems:"Totali:",size:"Tot Pagine:",first:"Prima",next:"Prossima",previous:"Precedente",last:"Ultima"},menu:{text:"Scegli le colonne:"},sort:{ascending:"Asc.",descending:"Desc.",remove:"Annulla ordinamento"},column:{hide:"Nascondi"},aggregation:{count:"righe totali: ",sum:"tot: ",avg:"media: ",min:"minimo: ",max:"massimo: "},pinning:{pinLeft:"Blocca a sx",pinRight:"Blocca a dx",unpin:"Blocca in alto"},gridMenu:{columns:"Colonne:",importerTitle:"Importa",exporterAllAsCsv:"Esporta tutti i dati in CSV",exporterVisibleAsCsv:"Esporta i dati visibili in CSV",exporterSelectedAsCsv:"Esporta i dati selezionati in CSV",exporterAllAsPdf:"Esporta tutti i dati in PDF",exporterVisibleAsPdf:"Esporta i dati visibili in PDF",exporterSelectedAsPdf:"Esporta i dati selezionati in PDF"},importer:{noHeaders:"Impossibile reperire i nomi delle colonne, sicuro che siano indicati all'interno del file?",noObjects:"Impossibile reperire gli oggetti, sicuro che siano indicati all'interno del file?",invalidCsv:"Impossibile elaborare il file, sicuro che sia un CSV?",invalidJson:"Impossibile elaborare il file, sicuro che sia un JSON valido?",jsonNotArray:"Errore! Il file JSON da importare deve contenere un array."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("nl",{aggregate:{label:"items"},groupPanel:{description:"Sleep hier een kolomnaam heen om op te groeperen."},search:{placeholder:"Zoeken...",showingItems:"Getoonde items:",selectedItems:"Geselecteerde items:",totalItems:"Totaal aantal items:",size:"Items per pagina:",first:"Eerste pagina",next:"Volgende pagina",previous:"Vorige pagina",last:"Laatste pagina"},menu:{text:"Kies kolommen:"},sort:{ascending:"Sorteer oplopend",descending:"Sorteer aflopend",remove:"Verwijder sortering"},column:{hide:"Verberg kolom"},aggregation:{count:"Aantal rijen: ",sum:"Som: ",avg:"Gemiddelde: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Zet links vast",pinRight:"Zet rechts vast",unpin:"Maak los"},gridMenu:{columns:"Kolommen:",importerTitle:"Importeer bestand",exporterAllAsCsv:"Exporteer alle data als csv",exporterVisibleAsCsv:"Exporteer zichtbare data als csv",exporterSelectedAsCsv:"Exporteer geselecteerde data als csv",exporterAllAsPdf:"Exporteer alle data als pdf",exporterVisibleAsPdf:"Exporteer zichtbare data als pdf",exporterSelectedAsPdf:"Exporteer geselecteerde data als pdf"},importer:{noHeaders:"Kolomnamen kunnen niet worden afgeleid. Heeft het bestand een header?",noObjects:"Objecten kunnen niet worden afgeleid. Bevat het bestand data naast de headers?",invalidCsv:"Het bestand kan niet verwerkt worden. Is het een valide csv bestand?",invalidJson:"Het bestand kan niet verwerkt worden. Is het valide json?",jsonNotArray:"Het json bestand moet een array bevatten. De actie wordt geannuleerd."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("pt-br",{aggregate:{label:"itens"},groupPanel:{description:"Arraste e solte uma coluna aqui para agrupar por essa coluna"},search:{placeholder:"Procurar...",showingItems:"Mostrando os Itens:",selectedItems:"Items Selecionados:",totalItems:"Total de Itens:",size:"Tamanho da Página:",first:"Primeira Página",next:"Próxima Página",previous:"Página Anterior",last:"Última Página"},menu:{text:"Selecione as colunas:"},sort:{ascending:"Ordenar Ascendente",descending:"Ordenar Descendente",remove:"Remover Ordenação"},column:{hide:"Esconder coluna"},aggregation:{count:"total de linhas: ",sum:"total: ",avg:"med: ",min:"min: ",max:"max: "},pinning:{pinLeft:"Fixar Esquerda",pinRight:"Fixar Direita",unpin:"Desprender"},gridMenu:{columns:"Colunas:",exporterAllAsCsv:"Exportar todos os dados como csv",exporterVisibleAsCsv:"Exportar dados visíveis como csv",exporterSelectedAsCsv:"Exportar dados selecionados como csv",exporterAllAsPdf:"Exportar todos os dados como pdf",exporterVisibleAsPdf:"Exportar dados visíveis como pdf",exporterSelectedAsPdf:"Exportar dados selecionados como pdf"},importer:{noHeaders:"Nomes de colunas não puderam ser derivados. O arquivo tem um cabeçalho?",noObjects:"Objetos não puderam ser derivados. Havia dados no arquivo, além dos cabeçalhos?",invalidCsv:"Arquivo não pode ser processado. É um CSV válido?",invalidJson:"Arquivo não pode ser processado. É um Json válido?",jsonNotArray:"Arquivo json importado tem que conter um array. Abortando."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("ru",{aggregate:{label:"элементы"},groupPanel:{description:"Для группировки по столбцу перетащите сюда его название."},search:{placeholder:"Поиск...",showingItems:"Показать элементы:",selectedItems:"Выбранные элементы:",totalItems:"Всего элементов:",size:"Размер страницы:",first:"Первая страница",next:"Следующая страница",previous:"Предыдущая страница",last:"Последняя страница"},menu:{text:"Выбрать столбцы:"},sort:{ascending:"По возрастанию",descending:"По убыванию",remove:"Убрать сортировку"},column:{hide:"спрятать столбец"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sk",{aggregate:{label:"items"},groupPanel:{description:"Pretiahni sem názov stĺpca pre zoskupenie podľa toho stĺpca."},search:{placeholder:"Hľadaj...",showingItems:"Zobrazujem položky:",selectedItems:"Vybraté položky:",totalItems:"Počet položiek:",size:"Počet:",first:"Prvá strana",next:"Ďalšia strana",previous:"Predchádzajúca strana",last:"Posledná strana"},menu:{text:"Vyberte stĺpce:"},sort:{ascending:"Zotriediť vzostupne",descending:"Zotriediť zostupne",remove:"Vymazať triedenie"},aggregation:{count:"total rows: ",sum:"total: ",avg:"avg: ",min:"min: ",max:"max: "},gridMenu:{columns:"Columns:",importerTitle:"Import file",exporterAllAsCsv:"Export all data as csv",exporterVisibleAsCsv:"Export visible data as csv",exporterSelectedAsCsv:"Export selected data as csv",exporterAllAsPdf:"Export all data as pdf",exporterVisibleAsPdf:"Export visible data as pdf",exporterSelectedAsPdf:"Export selected data as pdf"},importer:{noHeaders:"Column names were unable to be derived, does the file have a header?",noObjects:"Objects were not able to be derived, was there data in the file other than headers?",invalidCsv:"File was unable to be processed, is it valid CSV?",invalidJson:"File was unable to be processed, is it valid Json?",jsonNotArray:"Imported json file must contain an array, aborting."}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("sv",{aggregate:{label:"Artiklar"},groupPanel:{description:"Dra en kolumnrubrik hit och släpp den för att gruppera efter den kolumnen."},search:{placeholder:"Sök...",showingItems:"Visar artiklar:",selectedItems:"Valda artiklar:",totalItems:"Antal artiklar:",size:"Sidstorlek:",first:"Första sidan",next:"Nästa sida",previous:"Föregående sida",last:"Sista sidan"},menu:{text:"Välj kolumner:"},sort:{ascending:"Sortera stigande",descending:"Sortera fallande",remove:"Inaktivera sortering"},column:{hide:"Göm kolumn"},aggregation:{count:"Antal rader: ",sum:"Summa: ",avg:"Genomsnitt: ",min:"Min: ",max:"Max: "},pinning:{pinLeft:"Fäst vänster",pinRight:"Fäst höger",unpin:"Lösgör"},gridMenu:{columns:"Kolumner:",importerTitle:"Importera fil",exporterAllAsCsv:"Exportera all data som CSV",exporterVisibleAsCsv:"Exportera synlig data som CSV",exporterSelectedAsCsv:"Exportera markerad data som CSV",exporterAllAsPdf:"Exportera all data som PDF",exporterVisibleAsPdf:"Exportera synlig data som PDF",exporterSelectedAsPdf:"Exportera markerad data som PDF"},importer:{noHeaders:"Kolumnnamn kunde inte härledas. Har filen ett sidhuvud?",noObjects:"Objekt kunde inte härledas. Har filen data undantaget sidhuvud?",invalidCsv:"Filen kunde inte behandlas, är den en giltig CSV?",invalidJson:"Filen kunde inte behandlas, är den en giltig JSON?",jsonNotArray:"Importerad JSON-fil måste innehålla ett fält. Import avbruten."},paging:{sizes:"Artiklar per sida",totalItems:"Artiklar"}}),a}])}])}(),function(){var a=["uiT","uiTranslate"],b=["t","uiTranslate"],c=angular.module("ui.grid.i18n");c.constant("i18nConstants",{MISSING:"[MISSING]",UPDATE_EVENT:"$uiI18n",LOCALE_DIRECTIVE_ALIAS:"uiI18n",DEFAULT_LANG:"en"}),c.service("i18nService",["$log","i18nConstants","$rootScope",function(a,b,c){var d={_langs:{},current:null,get:function(a){return this._langs[a.toLowerCase()]},add:function(a,b){var c=a.toLowerCase();this._langs[c]||(this._langs[c]={}),angular.extend(this._langs[c],b)},getAllLangs:function(){var a=[];if(!this._langs)return a;for(var b in this._langs)a.push(b);return a},setCurrent:function(a){this.current=a.toLowerCase()},getCurrentLang:function(){return this.current}},e={add:function(a,b){"object"==typeof a?angular.forEach(a,function(a){a&&d.add(a,b)}):d.add(a,b)},getAllLangs:function(){return d.getAllLangs()},get:function(a){var b=a?a:e.getCurrentLang();return d.get(b)},getSafeText:function(a,c){var f=c?c:e.getCurrentLang(),g=d.get(f);if(!g)return b.MISSING;for(var h=a.split("."),i=g,j=0;j<h.length;++j){if(void 0===i[h[j]]||null===i[h[j]])return b.MISSING;i=i[h[j]]}return i},setCurrentLang:function(a){a&&(d.setCurrent(a),c.$broadcast(b.UPDATE_EVENT))},getCurrentLang:function(){var a=d.getCurrentLang();return a||(a=b.DEFAULT_LANG,d.setCurrent(a)),a}};return e}]);var d=function(a,b){return{compile:function(){return{pre:function(c,d,e){var f=b.LOCALE_DIRECTIVE_ALIAS,g=c.$eval(e[f]);g?c.$watch(e[f],function(){a.setCurrentLang(g)}):e.$$observers&&e.$observe(f,function(){a.setCurrentLang(e[f]||b.DEFAULT_LANG)})}}}}};c.directive("uiI18n",["i18nService","i18nConstants",d]);var e=function(b,c,d){return{restrict:"EA",compile:function(){return{pre:function(e,f,g){var h,i=a[0],j=a[1],k=g[i]||g[j]||f.html(),l=d.MISSING+k;if(g.$$observers){var m=g[i]?i:j;h=g.$observe(m,function(a){a&&f.html(b(a)(c.getCurrentLang())||l)})}var n=b(k),o=e.$on(d.UPDATE_EVENT,function(){h?h(g[i]||g[j]):f.html(n(c.get())||l)});e.$on("$destroy",o),f.html(n(c.get())||l)}}}}};angular.forEach(a,function(a){c.directive(a,["$parse","i18nService","i18nConstants",e])});var f=function(a,b,c){return function(d){var e=a(d);return e(b.get())||c.MISSING+d}};angular.forEach(b,function(a){c.filter(a,["$parse","i18nService","i18nConstants",f])})}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("zh-cn",{aggregate:{label:"行"},groupPanel:{description:"拖曳表头到此处进行分组"},search:{placeholder:"查找",showingItems:"已显示行数:",selectedItems:"已选择行数:",totalItems:"总行数:",size:"每页显示行数:",first:"首页",next:"下一页",previous:"上一页",last:"末页"},menu:{text:"选择列:"},sort:{ascending:"升序",descending:"降序",remove:"取消排序"},column:{hide:"隐藏列"},aggregation:{count:"计数:",sum:"求和:",avg:"均值:",min:"最小值:",max:"最大值:"},pinning:{pinLeft:"左侧固定",pinRight:"右侧固定",unpin:"取消固定"},gridMenu:{columns:"列:",importerTitle:"导入文件",exporterAllAsCsv:"导出全部数据到CSV",exporterVisibleAsCsv:"导出可见数据到CSV",exporterSelectedAsCsv:"导出已选数据到CSV",exporterAllAsPdf:"导出全部数据到PDF",exporterVisibleAsPdf:"导出可见数据到PDF",exporterSelectedAsPdf:"导出已选数据到PDF"},importer:{noHeaders:"无法获取列名,确定文件包含表头?",noObjects:"无法获取数据,确定文件包含数据?",invalidCsv:"无法处理文件,确定是合法的CSV文件?",invalidJson:"无法处理文件,确定是合法的JSON文件?",jsonNotArray:"导入的文件不是JSON数组!"}}),a}])}])}(),function(){angular.module("ui.grid").config(["$provide",function(a){a.decorator("i18nService",["$delegate",function(a){return a.add("zh-tw",{aggregate:{label:"行"},groupPanel:{description:"拖曳表頭到此處進行分組"},search:{placeholder:"查找",showingItems:"已顯示行數:",selectedItems:"已選擇行數:",totalItems:"總行數:",size:"每頁顯示行數:",first:"首頁",next:"下壹頁",previous:"上壹頁",last:"末頁"},menu:{text:"選擇列:"},sort:{ascending:"升序",descending:"降序",remove:"取消排序"},column:{hide:"隱藏列"},aggregation:{count:"計數:",sum:"求和:",avg:"均值:",min:"最小值:",max:"最大值:"},pinning:{pinLeft:"左側固定",pinRight:"右側固定",unpin:"取消固定"},gridMenu:{columns:"列:",importerTitle:"導入文件",exporterAllAsCsv:"導出全部數據到CSV",exporterVisibleAsCsv:"導出可見數據到CSV",exporterSelectedAsCsv:"導出已選數據到CSV",exporterAllAsPdf:"導出全部數據到PDF",exporterVisibleAsPdf:"導出可見數據到PDF",exporterSelectedAsPdf:"導出已選數據到PDF"},importer:{noHeaders:"無法獲取列名,確定文件包含表頭?",noObjects:"無法獲取數據,確定文件包含數據?",invalidCsv:"無法處理文件,確定是合法的CSV文件?",invalidJson:"無法處理文件,確定是合法的JSON文件?",jsonNotArray:"導入的文件不是JSON數組!"}}),a}])}])}(),function(){"use strict";var a=angular.module("ui.grid.autoResize",["ui.grid"]);a.directive("uiGridAutoResize",["$timeout","gridUtil",function(a,b){return{require:"uiGrid",scope:!1,link:function(c,d,e,f){function g(){j=b.elementHeight(d),i=b.elementWidth(d)}function h(){a.cancel(k),k=a(function(){var a=b.elementHeight(d),c=b.elementWidth(d);a!==j||c!==i?(f.grid.gridHeight=a,f.grid.gridWidth=c,f.grid.refresh().then(function(){g(),h()})):h()},250)}var i,j;g();var k;h(),c.$on("$destroy",function(){a.cancel(k)})}}}])}(),function(){"use strict";function a(a,b){this.row=a,this.col=b}var b=angular.module("ui.grid.cellNav",["ui.grid"]);b.constant("uiGridCellNavConstants",{FEATURE_NAME:"gridCellNav",CELL_NAV_EVENT:"cellNav",direction:{LEFT:0,RIGHT:1,UP:2,DOWN:3},EVENT_TYPE:{KEYDOWN:0,CLICK:1}}),b.factory("uiGridCellNavFactory",["gridUtil","uiGridConstants","uiGridCellNavConstants","$q",function(b,c,d){var e=function(a,b,c,d){this.rows=a.visibleRowCache,this.columns=b.visibleColumnCache,this.leftColumns=c?c.visibleColumnCache:[],this.rightColumns=d?d.visibleColumnCache:[]};return e.prototype.getFocusableCols=function(){var a=this.leftColumns.concat(this.columns,this.rightColumns);return a.filter(function(a){return a.colDef.allowCellFocus})},e.prototype.getNextRowCol=function(a,b,c){switch(a){case d.direction.LEFT:return this.getRowColLeft(b,c);case d.direction.RIGHT:return this.getRowColRight(b,c);case d.direction.UP:return this.getRowColUp(b,c);case d.direction.DOWN:return this.getRowColDown(b,c)}},e.prototype.getRowColLeft=function(b,c){var d=this.getFocusableCols(),e=d.indexOf(c),f=this.rows.indexOf(b);-1===e&&(e=1);var g=0===e?d.length-1:e-1;return g>e?0===f?new a(b,d[g]):new a(this.rows[f-1],d[g]):new a(b,d[g])},e.prototype.getRowColRight=function(b,c){var d=this.getFocusableCols(),e=d.indexOf(c),f=this.rows.indexOf(b);-1===e&&(e=0);var g=e===d.length-1?0:e+1;return e>g?f===this.rows.length-1?new a(b,d[g]):new a(this.rows[f+1],d[g]):new a(b,d[g])},e.prototype.getRowColDown=function(b,c){var d=this.getFocusableCols(),e=d.indexOf(c),f=this.rows.indexOf(b);return-1===e&&(e=0),f===this.rows.length-1?new a(b,d[e]):new a(this.rows[f+1],d[e])},e.prototype.getRowColUp=function(b,c){var d=this.getFocusableCols(),e=d.indexOf(c),f=this.rows.indexOf(b);return-1===e&&(e=0),0===f?new a(b,d[e]):new a(this.rows[f-1],d[e])},e}]),b.service("uiGridCellNavService",["gridUtil","uiGridConstants","uiGridCellNavConstants","$q","uiGridCellNavFactory",function(a,b,c,d,e){var f={initializeGrid:function(a){a.registerColumnBuilder(f.cellNavColumnBuilder),a.cellNav={},a.cellNav.lastRowCol=null;var b={events:{cellNav:{navigate:function(){}}},methods:{cellNav:{scrollTo:function(a,b,c,d){f.scrollTo(a,b,c,d)},getFocusedCell:function(){return a.cellNav.lastRowCol}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods)},decorateRenderContainers:function(a){var b=a.hasRightContainer()?a.renderContainers.right:null,c=a.hasLeftContainer()?a.renderContainers.left:null;null!==c&&(a.renderContainers.left.cellNav=new e(a.renderContainers.body,c,b,a.renderContainers.body)),null!==b&&(a.renderContainers.right.cellNav=new e(a.renderContainers.body,b,a.renderContainers.body,c)),a.renderContainers.body.cellNav=new e(a.renderContainers.body,a.renderContainers.body,c,b)},getDirection:function(a){return a.keyCode===b.keymap.LEFT||a.keyCode===b.keymap.TAB&&a.shiftKey?c.direction.LEFT:a.keyCode===b.keymap.RIGHT||a.keyCode===b.keymap.TAB?c.direction.RIGHT:a.keyCode===b.keymap.UP||a.keyCode===b.keymap.ENTER&&a.shiftKey?c.direction.UP:a.keyCode===b.keymap.DOWN||a.keyCode===b.keymap.ENTER?c.direction.DOWN:null},cellNavColumnBuilder:function(a){var b=[];return a.allowCellFocus=void 0===a.allowCellFocus?!0:a.allowCellFocus,d.all(b)},scrollTo:function(a,b,c,d){var e=null,f=null;null!==c&&(e=a.getRow(c)),null!==d&&(f=a.getColumn(d.name?d.name:d.field)),this.scrollToInternal(a,b,e,f)},scrollToInternal:function(a,c,d,e){var f={};if(null!==d){var g=a.renderContainers.body.visibleRowCache.indexOf(d),h=a.renderContainers.body.visibleRowCache.length,i=(g+g/(h-1))/h;f.y={percentage:i}}null!==e&&(f.x={percentage:this.getLeftWidth(a,e)/this.getLeftWidth(a,a.renderContainers.body.visibleColumnCache[a.renderContainers.body.visibleColumnCache.length-1])}),(f.y||f.x)&&c.$broadcast(b.events.GRID_SCROLL,f)},scrollToIfNecessary:function(a,c,d,e){var f={},g=a.renderContainers.body.visibleRowCache,h=a.renderContainers.body.visibleColumnCache,i=a.renderContainers.body.prevScrollTop+a.headerHeight;i=0>i?0:i;var j=a.renderContainers.body.prevScrollLeft,k=a.renderContainers.body.prevScrollTop+a.gridHeight-a.headerHeight;a.horizontalScrollbarHeight&&(k-=a.horizontalScrollbarHeight);var l=a.renderContainers.body.prevScrollLeft+a.gridWidth;if(a.verticalScrollbarWidth&&(l-=a.verticalScrollbarWidth),null!==d){var m=g.indexOf(d),n=a.renderContainers.body.getCanvasHeight()-a.renderContainers.body.getViewportHeight();a.horizontalScrollbarHeight&&a.horizontalScrollbarHeight>0&&(n+=a.horizontalScrollbarHeight);var o=(m+1)*a.options.rowHeight;o=0>o?0:o;var p,q;i>o?(p=a.renderContainers.body.prevScrollTop-(i-o),q=p/n,f.y={percentage:q}):o>k&&(p=o-k+a.renderContainers.body.prevScrollTop,q=p/n,f.y={percentage:q})}if(null!==e){for(var r=h.indexOf(e),s=a.renderContainers.body.getCanvasWidth()-a.renderContainers.body.getViewportWidth(),t=0,u=0;r>u;u++){var v=h[u];t+=v.drawnWidth}t=0>t?0:t;var w=t+e.drawnWidth;w=0>w?0:w;var x,y;j>t?(x=a.renderContainers.body.prevScrollLeft-(j-t),y=x/s,y=y>1?1:y,f.x={percentage:y}):w>l&&(x=w-l+a.renderContainers.body.prevScrollLeft,y=x/s,y=y>1?1:y,f.x={percentage:y})}(f.y||f.x)&&c.$broadcast(b.events.GRID_SCROLL,f)},getLeftWidth:function(a,b){var c=0;if(!b)return c;var d=a.renderContainers.body.visibleColumnCache.indexOf(b);a.renderContainers.body.visibleColumnCache.forEach(function(a,b){d>b&&(c+=a.drawnWidth)});var e=0===d?0:(d+1)/a.renderContainers.body.visibleColumnCache.length;return c+=b.drawnWidth*e}};return f}]),b.directive("uiGridCellnav",["gridUtil","uiGridCellNavService","uiGridCellNavConstants",function(b,c,d){return{replace:!0,priority:-150,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(b,e,f,g){var h=g.grid;c.initializeGrid(h),g.cellNav={},g.cellNav.focusCell=function(a,b){g.cellNav.broadcastCellNav({row:a,col:b})},g.cellNav.broadcastCellNav=function(a){b.$broadcast(d.CELL_NAV_EVENT,a),g.cellNav.broadcastFocus(a)},g.cellNav.broadcastFocus=function(b){var c=b.row,d=b.col;if(null===h.cellNav.lastRowCol||h.cellNav.lastRowCol.row!==c||h.cellNav.lastRowCol.col!==d){var e=new a(c,d);h.api.cellNav.raise.navigate(e,h.cellNav.lastRowCol),h.cellNav.lastRowCol=e}},g.cellNav.handleKeyDown=function(a){var e=c.getDirection(a);if(null===e)return!0;var f="body";a.uiGridTargetRenderContainerId&&(f=a.uiGridTargetRenderContainerId);var i=g.grid.api.cellNav.getFocusedCell();if(i){var j=g.grid.renderContainers[f].cellNav.getNextRowCol(e,i.row,i.col);return j.eventType=d.EVENT_TYPE.KEYDOWN,g.cellNav.broadcastCellNav(j),c.scrollToIfNecessary(h,b,j.row,j.col),a.stopPropagation(),a.preventDefault(),!1}}},post:function(){}}}}}]),b.directive("uiGridRenderContainer",["$timeout","$document","gridUtil","uiGridConstants","uiGridCellNavService","uiGridCellNavConstants",function(a,b,c,d,e){return{replace:!0,priority:-99999,require:["^uiGrid","uiGridRenderContainer"],scope:!1,compile:function(){return{pre:function(){},post:function(c,f,g,h){var i=h[0],j=h[1],k=j.containerId,l=i.grid;e.decorateRenderContainers(l),f.attr("tabindex",-1),f.on("keydown",function(a){return a.uiGridTargetRenderContainerId=k,i.cellNav.handleKeyDown(a)}),c.$on(d.events.GRID_SCROLL,function(){null!=i.grid.api.cellNav.getFocusedCell()&&a(function(){a(function(){var a=i.grid.api.cellNav.getFocusedCell();b.activeElement===b.body&&f[0].focus(),i.cellNav.broadcastCellNav(a)})})})}}}}}]),b.directive("uiGridCell",["$timeout","$document","uiGridCellNavService","gridUtil","uiGridCellNavConstants","uiGridConstants",function(b,c,d,e,f){return{priority:-150,restrict:"A",require:"^uiGrid",scope:!1,link:function(b,c,d,e){function g(){c.find("div").attr("tabindex",-1)}function h(){var a=c.find("div");a.addClass("ui-grid-cell-focus")}function i(){var a=c.find("div");a.removeClass("ui-grid-cell-focus")}b.col.colDef.allowCellFocus&&(g(),c.find("div").on("click",function(c){e.cellNav.broadcastCellNav(new a(b.row,b.col)),c.stopPropagation()}),b.$on(f.CELL_NAV_EVENT,function(a,d){d.row===b.row&&d.col===b.col?(h(),d.hasOwnProperty("eventType")&&d.eventType===f.EVENT_TYPE.KEYDOWN&&c.find("div")[0].focus()):i()}),b.$on("$destroy",function(){c.find("div").off("click")}))}}}])}(),function(){"use strict";var a=angular.module("ui.grid.edit",["ui.grid"]);a.constant("uiGridEditConstants",{EDITABLE_CELL_TEMPLATE:/EDITABLE_CELL_TEMPLATE/g,EDITABLE_CELL_DIRECTIVE:/editable_cell_directive/g,events:{BEGIN_CELL_EDIT:"uiGridEventBeginCellEdit",END_CELL_EDIT:"uiGridEventEndCellEdit",CANCEL_CELL_EDIT:"uiGridEventCancelCellEdit"}}),a.service("uiGridEditService",["$q","$templateCache","uiGridConstants","gridUtil",function(a,b,c,d){var e={initializeGrid:function(a){e.defaultGridOptions(a.options),a.registerColumnBuilder(e.editColumnBuilder);var b={events:{edit:{afterCellEdit:function(){},beginCellEdit:function(){},cancelCellEdit:function(){}}},methods:{edit:{}}};a.api.registerEventsFromObject(b.events)},defaultGridOptions:function(a){a.cellEditableCondition=void 0===a.cellEditableCondition?!0:a.cellEditableCondition,a.enableCellEditOnFocus=void 0===a.enableCellEditOnFocus?!1:a.enableCellEditOnFocus},editColumnBuilder:function(b,c,e){var f=[];return b.enableCellEdit=void 0===b.enableCellEdit?void 0===e.enableCellEdit?"object"!==b.type:e.enableCellEdit:b.enableCellEdit,b.cellEditableCondition=void 0===b.cellEditableCondition?e.cellEditableCondition:b.cellEditableCondition,b.enableCellEdit&&(b.editableCellTemplate=b.editableCellTemplate||e.editableCellTemplate||"ui-grid/cellEditor",f.push(d.getTemplate(b.editableCellTemplate).then(function(a){c.editableCellTemplate=a},function(){throw new Error("Couldn't fetch/use colDef.editableCellTemplate '"+b.editableCellTemplate+"'")}))),b.enableCellEditOnFocus=void 0===b.enableCellEditOnFocus?e.enableCellEditOnFocus:b.enableCellEditOnFocus,a.all(f)},isStartEditKey:function(a){return a.keyCode===c.keymap.LEFT||a.keyCode===c.keymap.TAB&&a.shiftKey||a.keyCode===c.keymap.RIGHT||a.keyCode===c.keymap.TAB||a.keyCode===c.keymap.UP||a.keyCode===c.keymap.ENTER&&a.shiftKey||a.keyCode===c.keymap.DOWN||a.keyCode===c.keymap.ENTER?!1:!0}};return e}]),a.directive("uiGridEdit",["gridUtil","uiGridEditService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(){}}}}}]),a.directive("uiGridCell",["$compile","$injector","uiGridConstants","uiGridEditConstants","gridUtil","$parse","uiGridEditService",function(a,b,c,d,e,f,g){return{priority:-100,restrict:"A",scope:!1,require:"?^uiGrid",link:function(e,h,i,j){function k(){h.on("dblclick",p),h.on("keydown",n),e.col.colDef.enableCellEditOnFocus&&h.find("div").on("focus",m)}function l(){h.off("dblclick",p),h.off("keydown",n),e.col.colDef.enableCellEditOnFocus&&h.find("div").off("focus",m)}function m(a){j&&j.cellNav&&j.cellNav.focusCell(e.row,e.col),a.stopPropagation(),p()}function n(a){g.isStartEditKey(a)&&p()}function o(a,b){return!b.isSaving&&(angular.isFunction(a.colDef.cellEditableCondition)?a.colDef.cellEditableCondition(e):a.colDef.cellEditableCondition)}function p(){if(!v&&o(e.col,e.row)){u=f(e.row.getQualifiedColField(e.col)),t=u(e),s=e.col.editableCellTemplate,s=s.replace(c.MODEL_COL_FIELD,e.row.getQualifiedColField(e.col));var b=e.col.colDef.editDropdownFilter?"|"+e.col.colDef.editDropdownFilter:"";switch(s=s.replace(c.CUSTOM_FILTERS,b),e.inputType="text",e.col.colDef.type){case"boolean":e.inputType="checkbox";break;case"number":e.inputType="number";break;case"date":e.inputType="date"}e.editDropdownOptionsArray=e.col.colDef.editDropdownOptionsArray,e.editDropdownIdLabel=e.col.colDef.editDropdownIdLabel?e.col.colDef.editDropdownIdLabel:"id",e.editDropdownValueLabel=e.col.colDef.editDropdownValueLabel?e.col.colDef.editDropdownValueLabel:"value";e.$apply(function(){v=!0,l();var b=angular.element(s);h.append(b),a(b)(e.$new());var c=angular.element(h.children()[0]);w=c.hasClass("ui-grid-cell-focus"),c.addClass("ui-grid-cell-contents-hidden")});var g=e.$on(c.events.GRID_SCROLL,function(){q(!0),e.grid.api.edit.raise.afterCellEdit(e.row.entity,e.col.colDef,u(e),t),g()}),i=e.$on(d.events.END_CELL_EDIT,function(a,b){q(b),e.grid.api.edit.raise.afterCellEdit(e.row.entity,e.col.colDef,u(e),t),i()}),j=e.$on(d.events.CANCEL_CELL_EDIT,function(){r(),j()});e.$broadcast(d.events.BEGIN_CELL_EDIT),e.grid.api.edit.raise.beginCellEdit(e.row.entity,e.col.colDef)}}function q(a){if(v){var b=angular.element(h.children()[0]);angular.element(h.children()[1]).remove(),b.removeClass("ui-grid-cell-contents-hidden"),a&&w&&b[0].focus(),w=!1,v=!1,k(),e.grid.api.core.notifyDataChange(e.grid,c.dataChange.EDIT)}}function r(){v&&(u.assign(e,t),e.$apply(),e.grid.api.edit.raise.cancelCellEdit(e.row.entity,e.col.colDef),q(!0))}if(e.col.colDef.enableCellEdit){var s,t,u,v=!1,w=!1;k();try{var x=b.get("uiGridCellNavConstants");e.col.colDef.enableCellEditOnFocus&&e.$on(x.CELL_NAV_EVENT,function(a,b){b.row===e.row&&b.col===e.col?p():q()})}catch(y){}}}}}]),a.directive("uiGridEditor",["uiGridConstants","uiGridEditConstants",function(a,b){return{scope:!0,require:["?^uiGrid","?^uiGridRenderContainer"],compile:function(){return{pre:function(){},post:function(c,d,e,f){var g,h;f[0]&&(g=f[0]),f[1]&&(h=f[1]),c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].select(),d.on("blur",function(a){c.stopEdit(a)})}),c.deepEdit=!1,c.stopEdit=function(a){c.inputForm&&!c.inputForm.$valid?(a.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT)):c.$emit(b.events.END_CELL_EDIT),c.deepEdit=!1},d.on("click",function(){c.deepEdit=!0}),d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT);break;case a.keymap.ENTER:c.stopEdit(d);break;case a.keymap.TAB:c.stopEdit(d)}if(c.deepEdit)switch(d.keyCode){case a.keymap.LEFT:d.stopPropagation();break;case a.keymap.RIGHT:d.stopPropagation();break;case a.keymap.UP:d.stopPropagation();break;case a.keymap.DOWN:d.stopPropagation()}else g&&g.hasOwnProperty("cellNav")&&h&&(d.uiGridTargetRenderContainerId=h.containerId,g.cellNav.handleKeyDown(d));return!0})}}}}}]),a.directive("input",["$filter",function(a){function b(a){if("undefined"==typeof a||""===a)return null;var b=a.split("-");if(3!==b.length)return null;var c=parseInt(b[0],10),d=parseInt(b[1],10),e=parseInt(b[2],10);return 1>d||1>c||1>e?null:new Date(c,d-1,e)}return{restrict:"E",require:"?ngModel",link:function(c,d,e,f){2===angular.version.minor&&e.type&&"date"===e.type&&f&&(f.$formatters.push(function(b){return f.$setValidity(null,!b||!isNaN(b.getTime())),a("date")(b,"yyyy-MM-dd")}),f.$parsers.push(function(a){if(a&&a.length>0){var c=b(a);return f.$setValidity(null,c&&!isNaN(c.getTime())),c}return f.$setValidity(null,!0),null}))}}}]),a.directive("uiGridEditDropdown",["uiGridConstants","uiGridEditConstants",function(a,b){return{scope:!0,compile:function(){return{pre:function(){},post:function(c,d){c.$on(b.events.BEGIN_CELL_EDIT,function(){d[0].focus(),d[0].style.width=d[0].parentElement.offsetWidth-1+"px",d.on("blur",function(a){c.stopEdit(a)
+})}),c.stopEdit=function(){c.$emit(b.events.END_CELL_EDIT)},d.on("keydown",function(d){switch(d.keyCode){case a.keymap.ESC:d.stopPropagation(),c.$emit(b.events.CANCEL_CELL_EDIT);break;case a.keymap.ENTER:c.stopEdit(d);break;case a.keymap.LEFT:c.stopEdit(d);break;case a.keymap.RIGHT:c.stopEdit(d);break;case a.keymap.UP:d.stopPropagation();break;case a.keymap.DOWN:d.stopPropagation();break;case a.keymap.TAB:c.stopEdit(d)}return!0})}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.expandable",["ui.grid"]);a.service("uiGridExpandableService",["gridUtil","$compile",function(a){var b={initializeGrid:function(c){c.options.enableExpandable=c.options.enableExpandable!==!1,c.options.expandableRowHeight=c.options.expandableRowHeight||150,c.options.enableExpandable&&!c.options.expandableRowTemplate&&(a.logError("You have not set the expandableRowTemplate, disabling expandable module"),c.options.enableExpandable=!1);var d={events:{expandable:{rowExpandedStateChanged:function(){}}},methods:{expandable:{toggleRowExpansion:function(a){var d=c.getRow(a);null!==d&&b.toggleRowExpansion(c,d)},expandAllRows:function(){b.expandAllRows(c)},collapseAllRows:function(){b.collapseAllRows(c)}}}};c.api.registerEventsFromObject(d.events),c.api.registerMethodsFromObject(d.methods)},toggleRowExpansion:function(a,b){b.isExpanded=!b.isExpanded,b.height=b.isExpanded?b.grid.options.rowHeight+a.options.expandableRowHeight:b.grid.options.rowHeight,a.api.expandable.raise.rowExpandedStateChanged(b)},expandAllRows:function(a){angular.forEach(a.renderContainers.body.visibleRowCache,function(c){c.isExpanded||b.toggleRowExpansion(a,c)}),a.refresh()},collapseAllRows:function(a){angular.forEach(a.renderContainers.body.visibleRowCache,function(c){c.isExpanded&&b.toggleRowExpansion(a,c)}),a.refresh()}};return b}]),a.directive("uiGridExpandable",["uiGridExpandableService","$templateCache",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,d,e,f){if(f.grid.options.enableExpandableRowHeader!==!1){var g={name:"expandableButtons",width:40};g.cellTemplate=b.get("ui-grid/expandableRowHeader"),f.grid.addRowHeaderColumn(g)}a.initializeGrid(f.grid)},post:function(){}}}}}]),a.directive("uiGridExpandableRow",["uiGridExpandableService","$timeout","$compile","uiGridConstants","gridUtil","$interval","$log",function(a,b,c,d,e){return{replace:!1,priority:0,scope:!1,compile:function(){return{pre:function(a,b){e.getTemplate(a.grid.options.expandableRowTemplate).then(function(d){if(a.grid.options.expandableRowScope){var e=a.grid.options.expandableRowScope;for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}var g=c(d)(a);b.append(g),a.row.expandedRendered=!0})},post:function(a){a.$on("$destroy",function(){a.row.expandedRendered=!1})}}}}}]),a.directive("uiGridRow",["$compile","gridUtil","$templateCache",function(){return{priority:-200,scope:!1,compile:function(){return{pre:function(a){function b(){var b=a.grid,c=0;return angular.forEach(b.columns,function(a){"left"===a.renderContainer&&(c+=a.width)}),c=Math.floor(c),".grid"+b.id+" .ui-grid-pinned-container-"+a.colContainer.name+", .grid"+b.id+" .ui-grid-pinned-container-"+a.colContainer.name+" .ui-grid-render-container-"+a.colContainer.name+" .ui-grid-viewport .ui-grid-canvas .ui-grid-row { width: "+c+"px; }"}a.expandableRow={},a.expandableRow.shouldRenderExpand=function(){var b="body"===a.colContainer.name&&a.grid.options.enableExpandable!==!1&&a.row.isExpanded&&(!a.grid.isScrollingVertically||a.row.expandedRendered);return b},a.expandableRow.shouldRenderFiller=function(){var b=a.row.isExpanded&&("body"!==a.colContainer.name||a.grid.isScrollingVertically&&!a.row.expandedRendered);return b},"left"===a.colContainer.name&&a.grid.registerStyleComputation({priority:15,func:b})},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","gridUtil","$templateCache",function(a,b,c){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]),d=c.get("ui-grid/expandableScrollFiller"),e=c.get("ui-grid/expandableRow");return b.append(e),b.append(d),{pre:function(){},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.exporter",["ui.grid"]);a.constant("uiGridExporterConstants",{featureName:"exporter",ALL:"all",VISIBLE:"visible",SELECTED:"selected",CSV_CONTENT:"CSV_CONTENT",LINK_LABEL:"LINK_LABEL",BUTTON_LABEL:"BUTTON_LABEL"}),a.service("uiGridExporterService",["$q","uiGridExporterConstants","uiGridSelectionConstants","gridUtil","$compile","$interval","i18nService",function(a,b,c,d,e,f,g){var h={initializeGrid:function(a){a.exporter={},this.defaultGridOptions(a.options);var b={events:{exporter:{}},methods:{exporter:{csvExport:function(b,c,d){h.csvExport(a,b,c,d)},pdfExport:function(b,c){h.pdfExport(a,b,c)}}}};a.api.registerEventsFromObject(b.events),a.api.registerMethodsFromObject(b.methods),a.api.core.addToGridMenu?h.addToMenu(a):f(function(){a.api.core.addToGridMenu&&h.addToMenu(a)},100,1)},defaultGridOptions:function(a){a.exporterSuppressMenu=a.exporterSuppressMenu===!0,a.exporterLinkTemplate=a.exporterLinkTemplate?a.exporterLinkTemplate:"ui-grid/csvLink",a.exporterHeaderTemplate=a.exporterHeaderTemplate?a.exporterHeaderTemplate:"ui-grid/exporterHeader",a.exporterLinkLabel=a.exporterLinkLabel?a.exporterLinkLabel:"Download CSV",a.exporterMenuLabel=a.exporterMenuLabel?a.exporterMenuLabel:"Export",a.exporterSuppressColumns=a.exporterSuppressColumns?a.exporterSuppressColumns:[],a.exporterCsvColumnSeparator=a.exporterCsvColumnSeparator?a.exporterCsvColumnSeparator:",",a.exporterPdfDefaultStyle=a.exporterPdfDefaultStyle?a.exporterPdfDefaultStyle:{fontSize:11},a.exporterPdfTableStyle=a.exporterPdfTableStyle?a.exporterPdfTableStyle:{margin:[0,5,0,15]},a.exporterPdfTableHeaderStyle=a.exporterPdfTableHeaderStyle?a.exporterPdfTableHeaderStyle:{bold:!0,fontSize:12,color:"black"},a.exporterPdfHeader=a.exporterPdfHeader?a.exporterPdfHeader:null,a.exporterPdfFooter=a.exporterPdfFooter?a.exporterPdfFooter:null,a.exporterPdfOrientation=a.exporterPdfOrientation?a.exporterPdfOrientation:"landscape",a.exporterPdfPageSize=a.exporterPdfPageSize?a.exporterPdfPageSize:"A4",a.exporterPdfMaxGridWidth=a.exporterPdfMaxGridWidth?a.exporterPdfMaxGridWidth:720,a.exporterMenuCsv=void 0!==a.exporterMenuCsv?a.exporterMenuCsv:!0,a.exporterMenuPdf=void 0!==a.exporterMenuPdf?a.exporterMenuPdf:!0,a.exporterPdfCustomFormatter=a.exporterPdfCustomFormatter&&"function"==typeof a.exporterPdfCustomFormatter?a.exporterPdfCustomFormatter:function(a){return a},a.exporterFieldCallback=a.exporterFieldCallback?a.exporterFieldCallback:function(a,b,c,d){return d}},addToMenu:function(a){a.api.core.addToGridMenu(a,[{title:g.getSafeText("gridMenu.exporterAllAsCsv"),action:function(){this.grid.api.exporter.csvExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuCsv}},{title:g.getSafeText("gridMenu.exporterVisibleAsCsv"),action:function(){this.grid.api.exporter.csvExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv}},{title:g.getSafeText("gridMenu.exporterSelectedAsCsv"),action:function(){this.grid.api.exporter.csvExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuCsv&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0}},{title:g.getSafeText("gridMenu.exporterAllAsPdf"),action:function(){this.grid.api.exporter.pdfExport(b.ALL,b.ALL)},shown:function(){return this.grid.options.exporterMenuPdf}},{title:g.getSafeText("gridMenu.exporterVisibleAsPdf"),action:function(){this.grid.api.exporter.pdfExport(b.VISIBLE,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf}},{title:g.getSafeText("gridMenu.exporterSelectedAsPdf"),action:function(){this.grid.api.exporter.pdfExport(b.SELECTED,b.VISIBLE)},shown:function(){return this.grid.options.exporterMenuPdf&&this.grid.api.selection&&this.grid.api.selection.getSelectedRows().length>0}}])},csvExport:function(a,b,c,e){var f=this.getColumnHeaders(a,c),g=this.getData(a,b,c),h=this.formatAsCsv(f,g,a.options.exporterCsvColumnSeparator);!e&&a.options.exporterCsvLinkElement&&(e=a.options.exporterCsvLinkElement),e?this.renderCsvLink(a,h,e):d.logError("Exporter asked to export as csv, but no element provided.  Perhaps you should set gridOptions.exporterCsvLinkElement?")},getColumnHeaders:function(a,d){var e=[];return angular.forEach(a.columns,function(f){!f.visible&&d!==b.ALL||f.name===c.selectionRowHeaderColName||-1!==a.options.exporterSuppressColumns.indexOf(f.name)||e.push({name:f.field,displayName:a.options.exporterHeaderFilter?a.options.exporterHeaderFilter(f.displayName):f.displayName,width:f.drawnWidth?f.drawnWidth:f.width,align:"number"===f.colDef.type?"right":"left"})}),e},getData:function(a,e,f){var g,h=[];switch(e){case b.ALL:g=a.rows;break;case b.VISIBLE:g=a.getVisibleRows();break;case b.SELECTED:a.api.selection?g=a.api.selection.getSelectedGridRows():d.logError("selection feature must be enabled to allow selected rows to be exported")}return angular.forEach(g,function(d){var e=[];angular.forEach(a.columns,function(g){if((g.visible||f===b.ALL)&&g.name!==c.selectionRowHeaderColName&&-1===a.options.exporterSuppressColumns.indexOf(g.name)){var h={value:a.options.exporterFieldCallback(a,d,g,a.getCellValue(d,g))};g.colDef.exporterPdfAlign&&(h.alignment=g.colDef.exporterPdfAlign),e.push(h)}}),h.push(e)}),h},formatAsCsv:function(a,b,c){var d=this,e=a.map(function(a){return{value:a.displayName}}),f=d.formatRowAsCsv(this,c)(e)+"\n";return f+=b.map(this.formatRowAsCsv(this,c)).join("\n")},formatRowAsCsv:function(a,b){return function(c){return c.map(a.formatFieldAsCsv).join(b)}},formatFieldAsCsv:function(a){return null==a.value?"":"number"==typeof a.value?a.value:"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?'"'+a.value.replace(/"/g,'""')+'"':JSON.stringify(a.value)},renderCsvLink:function(a,c,f){var g=f?f:angular.element(a.exporter.gridElm[0].querySelectorAll(".ui-grid-exporter-csv-link"));angular.element(g[0].querySelectorAll(".ui-grid-exporter-csv-link-span"))&&angular.element(g[0].querySelectorAll(".ui-grid-exporter-csv-link-span")).remove();d.getTemplate(a.options.exporterLinkTemplate).then(function(d){var f=angular.element(d);f.children("a").html(f.children("a").html().replace(b.LINK_LABEL,a.options.exporterLinkLabel)),f.children("a").attr("href",f.children("a").attr("href").replace(b.CSV_CONTENT,encodeURIComponent(c)));var h=e(f)(a.exporter.$scope);g.append(h)})},pdfExport:function(a,b,c){var d=this.getColumnHeaders(a,c),e=this.getData(a,b,c),f=this.prepareAsPdf(a,d,e);pdfMake.createPdf(f).open()},prepareAsPdf:function(a,b,c){var d=this.calculatePdfHeaderWidths(a,b),e=b.map(function(a){return{text:a.displayName,style:"tableHeader"}}),f=c.map(this.formatRowAsPdf(this)),g=[e].concat(f),h={pageOrientation:a.options.exporterPdfOrientation,pageSize:a.options.exporterPdfPageSize,content:[{style:"tableStyle",table:{headerRows:1,widths:d,body:g}}],styles:{tableStyle:a.options.exporterPdfTableStyle,tableHeader:a.options.exporterPdfTableHeaderStyle},defaultStyle:a.options.exporterPdfDefaultStyle};return a.options.exporterPdfLayout&&(h.layout=a.options.exporterPdfLayout),a.options.exporterPdfHeader&&h.content.unshift(a.options.exporterPdfHeader),a.options.exporterPdfFooter&&h.content.push(a.options.exporterPdfFooter),a.options.exporterPdfCustomFormatter&&(h=a.options.exporterPdfCustomFormatter(h)),h},calculatePdfHeaderWidths:function(a,b){var c=0;angular.forEach(b,function(a){"number"==typeof a.width&&(c+=a.width)});var d=0;angular.forEach(b,function(a){if("*"===a.width&&(d+=100),"string"==typeof a.width&&a.width.match(/(\d)*%/)){var b=parseInt(a.width.match(/(\d)*%/)[0]);a.width=c*b/100,d+=a.width}});var e=c+d;return b.map(function(b){return"*"===b.width?b.width:b.width*a.options.exporterPdfMaxGridWidth/e})},formatRowAsPdf:function(a){return function(b){return b.map(a.formatFieldAsPdfString)}},formatFieldAsPdfString:function(a){var b;return b=null==a.value?"":"number"==typeof a.value?a.value.toString():"boolean"==typeof a.value?a.value?"TRUE":"FALSE":"string"==typeof a.value?a.value.replace(/"/g,'""'):JSON.stringify(a.value).replace(/^"/,"").replace(/"$/,""),a.alignment&&"string"==typeof a.alignment&&(b={text:b,alignment:a.alignment}),b}};return h}]),a.directive("uiGridExporter",["uiGridExporterConstants","uiGridExporterService","gridUtil","$compile",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(e.grid),e.grid.exporter.$scope=a}}}])}(),function(){"use strict";var a=angular.module("ui.grid.importer",["ui.grid"]);a.constant("uiGridImporterConstants",{featureName:"importer"}),a.service("uiGridImporterService",["$q","uiGridConstants","uiGridImporterConstants","gridUtil","$compile","$interval","i18nService","$window",function(a,b,c,d,e,f,g,h){var i={initializeGrid:function(a,b){b.importer={$scope:a},this.defaultGridOptions(b.options);var c={events:{importer:{}},methods:{importer:{importFile:function(a,b){i.importFile(a,b)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.options.enableImporter&&b.options.importerShowMenu&&(b.api.core.addToGridMenu?i.addToMenu(b):f(function(){b.api.core.addToGridMenu&&i.addToMenu(b)},100,1))},defaultGridOptions:function(a){a.enableImporter||void 0===a.enableImporter?h.hasOwnProperty("File")&&h.hasOwnProperty("FileReader")&&h.hasOwnProperty("FileList")&&h.hasOwnProperty("Blob")?a.enableImporter=!0:(d.logError("The File APIs are not fully supported in this browser, grid importer cannot be used."),a.enableImporter=!1):a.enableImporter=!1,a.importerProcessHeaders=a.importerProcessHeaders||i.processHeaders,a.importerHeaderFilter=a.importerHeaderFilter||function(a){return a},a.importerErrorCallback&&"function"==typeof a.importerErrorCallback||delete a.importerErrorCallback,a.enableImporter!==!0||a.importerDataAddCallback||(d.logError("You have not set an importerDataAddCallback, importer is disabled"),a.enableImporter=!1),a.importerShowMenu=a.importerShowMenu!==!1,a.importerObjectCallback=a.importerObjectCallback||function(a,b){return b}},addToMenu:function(a){a.api.core.addToGridMenu(a,[{title:g.getSafeText("gridMenu.importerTitle")},{templateUrl:"ui-grid/importerMenuItemContainer",action:function(){this.grid.api.importer.importAFile(a)}}])},importThisFile:function(a,b){if(!b)return void d.logError("No file object provided to importThisFile, should be impossible, aborting");var c=new FileReader;switch(b.type){case"application/json":c.onload=i.importJsonClosure(a);break;default:c.onload=i.importCsvClosure(a)}c.readAsText(b)},importJsonClosure:function(a){return function(b){var c,d=[];angular.forEach(i.parseJson(a,b),function(b){c=i.newObject(a),angular.extend(c,b),c=a.options.importerObjectCallback(a,c),d.push(c)}),i.addObjects(a,d)}},parseJson:function(a,b){var c;try{c=JSON.parse(b.target.result)}catch(d){return void i.alertError(a,"importer.invalidJson","File could not be processed, is it valid json? Content was: ",b.target.result)}return Array.isArray(c)?c:(i.alertError(a,"importer.jsonNotarray","Import failed, file is not an array, file was: ",b.target.result),[])},importCsvClosure:function(a){return function(b){var c=i.parseCsv(b);if(!c||c.length<1)return void i.alertError(a,"importer.invalidCsv","File could not be processed, is it valid csv? Content was: ",b.target.result);var d=i.createCsvObjects(a,c);return d&&0!==d.length?void i.addObjects(a,d):void i.alertError(a,"importer.noObjects","Objects were not able to be derived, content was: ",b.target.result)}},parseCsv:function(a){var b=a.target.result;return CSV.parse(b)},createCsvObjects:function(a,b){var c=a.options.importerProcessHeaders(a,b.shift());if(!c||0===c.length)return i.alertError(a,"importer.noHeaders","Column names could not be derived, content was: ",b),[];var d,e=[];return angular.forEach(b,function(b){d=i.newObject(a),angular.forEach(b,function(a,b){null!==c[b]&&(d[c[b]]=a)}),d=a.options.importerObjectCallback(a,d),e.push(d)}),e},processHeaders:function(a,b){var c=[];if(a.options.columnDefs&&0!==a.options.columnDefs.length){var d=i.flattenColumnDefs(a,a.options.columnDefs);return angular.forEach(b,function(a){c.push(d[a]?d[a]:d[a.toLowerCase()]?d[a.toLowerCase()]:null)}),c}return angular.forEach(b,function(a){c.push(a.replace(/[^0-9a-zA-Z\-_]/g,"_"))}),c},flattenColumnDefs:function(a,b){var c={};return angular.forEach(b,function(b){b.name&&(c[b.name]=b.field||b.name,c[b.name.toLowerCase()]=b.field||b.name),b.field&&(c[b.field]=b.field||b.name,c[b.field.toLowerCase()]=b.field||b.name),b.displayName&&(c[b.displayName]=b.field||b.name,c[b.displayName.toLowerCase()]=b.field||b.name),b.displayName&&a.options.importerHeaderFilter&&(c[a.options.importerHeaderFilter(b.displayName)]=b.field||b.name,c[a.options.importerHeaderFilter(b.displayName).toLowerCase()]=b.field||b.name)}),c},addObjects:function(a,c){if(a.api.rowEdit){var d=a.registerDataChangeCallback(function(){a.api.rowEdit.setRowsDirty(a,c),a.deregisterDataChangeCallback(d)},[b.dataChange.ROW]),e=function(){a.deregisterDataChangeCallback(d)};a.importer.$scope.$on("$destroy",e)}a.importer.$scope.$apply(a.options.importerDataAddCallback(a,c))},newObject:function(a){return"undefined"!=typeof a.options&&"undefined"!=typeof a.options.importerNewObject?new a.options.importerNewObject:{}},alertError:function(a,b,c,e){a.options.importerErrorCallback?a.options.importerErrorCallback(a,b,c,e):(h.alert(g.getSafeText(b)),d.logError(c+e))}};return i}]),a.directive("uiGridImporter",["uiGridImporterConstants","uiGridImporterService","gridUtil","$compile",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,link:function(a,c,d,e){b.initializeGrid(a,e.grid)}}}]),a.directive("uiGridImporterMenuItem",["uiGridImporterConstants","uiGridImporterService","gridUtil","$compile",function(a,b,c){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,templateUrl:"ui-grid/importerMenuItem",link:function(a,d,e,f){var g=function(a){if(1===a.srcElement.files.length){var c=a.srcElement.files[0];b.importThisFile(i,c),a.srcElement.form.reset()}},h=d[0].querySelectorAll(".ui-grid-importer-file-chooser"),i=f.grid;1!==h.length?c.logError("Found > 1 or < 1 file choosers within the menu item, error, cannot continue"):h[0].addEventListener("change",g,!1)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.infiniteScroll",["ui.grid"]);a.service("uiGridInfiniteScrollService",["gridUtil","$compile","$timeout",function(){var a={initializeGrid:function(b){a.defaultGridOptions(b.options);var c={events:{infiniteScroll:{needLoadMoreData:function(){}}},methods:{infiniteScroll:{dataLoaded:function(){b.options.loadTimout=!1}}}};b.options.loadTimout=!1,b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableInfiniteScroll=a.enableInfiniteScroll!==!1},loadData:function(a){a.options.loadTimout=!0,a.api.infiniteScroll.raise.needLoadMoreData()},checkScroll:function(a,b){var c=a.options.infiniteScrollPercentage?a.options.infiniteScrollPercentage:20;return!a.options.loadTimout&&c>=b?(this.loadData(a),!0):!1}};return a}]),a.directive("uiGridInfiniteScroll",["uiGridInfiniteScrollService",function(a){return{priority:-200,scope:!1,require:"^uiGrid",compile:function(){return{pre:function(b,c,d,e){a.initializeGrid(e.grid)},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","gridUtil","uiGridInfiniteScrollService","uiGridConstants",function(a,b,c,d){return{priority:-200,scope:!1,link:function(a){a.grid.options.enableInfiniteScroll&&a.$on(d.events.GRID_SCROLL,function(b,d){if(d.y){var e=100-100*d.y.percentage;c.checkScroll(a.grid,e)}})}}}])}(),function(){"use strict";var a=angular.module("ui.grid.moveColumns",["ui.grid"]);a.service("uiGridMoveColumnService",["$q","$timeout","$log",function(a,b){var c={initializeGrid:function(a){var b=this;this.registerPublicApi(a),this.defaultGridOptions(a.options),a.registerColumnBuilder(b.movableColumnBuilder)},registerPublicApi:function(a){var b=this,c={events:{colMovable:{columnPositionChanged:function(){}}},methods:{colMovable:{moveColumn:function(c,d){b.redrawColumnAtPosition(a,c,d)}}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableColumnMoving=a.enableColumnMoving!==!1},movableColumnBuilder:function(b,c,d){var e=[];return b.enableColumnMoving=void 0===b.enableColumnMoving?d.enableColumnMoving:b.enableColumnMoving,a.all(e)},redrawColumnAtPosition:function(a,c,d){var e=a.columns,f=function(a){for(var b=a,c=0;b>=c;c++)angular.isDefined(e[c].colDef.visible)&&e[c].colDef.visible===!1&&b++;return b};c=f(c),d=f(d);var g=e[c];if(g.colDef.enableColumnMoving){if(c>d)for(var h=c;h>d;h--)e[h]=e[h-1];else if(d>c)for(var i=c;d>i;i++)e[i]=e[i+1];e[d]=g,b(function(){a.refresh(),a.api.colMovable.raise.columnPositionChanged(g.colDef,c,d)})}}};return c}]),a.directive("uiGridMoveColumns",["uiGridMoveColumnService",function(a){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(b,c,d,e){a.initializeGrid(e.grid)},post:function(){}}}}}]),a.directive("uiGridHeaderCell",["$q","gridUtil","uiGridMoveColumnService","$document",function(a,b,c,d){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(e,f,g,h){if(e.col.colDef.enableColumnMoving){var i=function(i){if("ui-grid-icon-angle-down"!==i.target.className&&"I"!==i.target.tagName){var j=f.clone();f.append(j),j.addClass("movingColumn");var k={},l=e.grid.element[0].getBoundingClientRect().left,m=f[0].getBoundingClientRect().left;k.left=m-l+"px";var n,o=e.grid.element[0].getBoundingClientRect().right,p=f[0].getBoundingClientRect().right;p>o&&(n=e.col.drawnWidth+(o-p),k.width=n+"px"),j.css(k);var q=i.pageX,r=0,s=l+e.grid.getViewportWidth()-e.grid.verticalScrollbarWidth,t=function(a){h.fireEvent("hide-menu");var c,d=j[0].getBoundingClientRect().left-1,f=j[0].getBoundingClientRect().right,g=a.pageX-q;c="ie"===b.detectBrowser()?d+g:d-l+g,c=s>c?c:s,(d>=l||g>0)&&(s>=f||0>g)?j.css({visibility:"visible",left:c+"px"}):(g*=5,h.fireScrollingEvent({x:{pixels:2.5*g}})),r+=g,q=a.pageX,n<e.col.drawnWidth&&(n+=Math.abs(g),j.css({width:n+"px"}))};e.$on("$destroy",function(){d.off("mousemove",t),d.off("mouseup",u)}),d.on("mousemove",t);var u=function(b){var f,i=a.defer();g.$observe("renderIndex",function(a){f=e.$eval(a),i.resolve()}),i.promise.then(function(){j&&j.remove();for(var a=e.grid.renderContainers.body.renderedColumns,g=0,i=e.grid.columns,k=0;k<i.length&&i[k].colDef.name!==a[0].colDef.name;k++)g++;if(0>r){for(var l=0,m=f-1;m>=0;m--)if(l+=a[m].drawnWidth,l>Math.abs(r)){c.redrawColumnAtPosition(e.grid,g+f,g+m+1);break}l<Math.abs(r)&&c.redrawColumnAtPosition(e.grid,g+f,g+0)}else if(r>0){for(var n=0,o=f+1;o<a.length;o++)if(n+=a[o].drawnWidth,n>r){c.redrawColumnAtPosition(e.grid,g+f,g+o-1);break}r>n&&c.redrawColumnAtPosition(e.grid,g+f,g+a.length-1)}else if(0===r&&h.grid.options.enableSorting&&e.col.enableSorting){var p=!1;b.shiftKey&&(p=!0),h.grid.sortColumn(e.col,p).then(function(){h.columnMenuScope&&h.columnMenuScope.hideMenu(),h.grid.refresh()})}d.off("mousemove",t),d.off("mouseup",u)})};d.on("mouseup",u)}};f.on("mousedown",i)}}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.pagination",["ui.grid"]);a.service("uiGridPaginationService",function(){var a={initializeGrid:function(b){a.defaultGridOptions(b.options),b.pagination={page:1,totalPages:1};var c={methods:{pagination:{getPage:function(){return b.pagination.page},getTotalPages:function(){return b.pagination.totalPages},nextPage:function(){b.pagination.page++,b.refresh()},previousPage:function(){b.pagination.page=Math.max(1,b.pagination.page-1),b.refresh()},seek:function(a){if(!angular.isNumber(a)||1>a)throw"Invalid page number: "+a;b.pagination.page=a,b.refresh()}}}};b.api.registerMethodsFromObject(c.methods),b.registerRowsProcessor(function(a){if(!b.options.enablePagination)return a;b.pagination.totalPages=Math.max(1,Math.ceil(a.length/b.options.rowsPerPage));var c=(b.pagination.page-1)*b.options.rowsPerPage;return c>=a.length&&(b.pagination.page=b.pagination.totalPages,c=(b.pagination.page-1)*b.options.rowsPerPage),a.slice(c,c+b.options.rowsPerPage)})},defaultGridOptions:function(a){a.enablePagination=a.enablePagination!==!1,a.rowsPerPage=angular.isNumber(a.rowsPerPage)?a.rowsPerPage:10}};return a}),a.directive("uiGridPagination",["uiGridPaginationService",function(a){return{priority:-400,scope:!1,require:"^uiGrid",link:{pre:function(b,c,d,e){a.initializeGrid(e.grid)}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.paging",["ui.grid"]);a.service("uiGridPagingService",["gridUtil",function(a){var b={initializeGrid:function(a){b.defaultGridOptions(a.options);var c={events:{paging:{pagingChanged:function(){}}},methods:{paging:{}}};a.api.registerEventsFromObject(c.events),a.api.registerMethodsFromObject(c.methods),a.registerRowsProcessor(function(b){if(a.options.useExternalPaging||!a.options.enablePaging)return b;var c=parseInt(a.options.pagingPageSize,10),d=parseInt(a.options.pagingCurrentPage,10),e=(d-1)*c;return b.slice(e,e+c)})},defaultGridOptions:function(b){b.enablePaging=b.enablePaging!==!1,b.useExternalPaging=b.useExternalPaging===!0,a.isNullOrUndefined(b.totalItems)&&(b.totalItems=0),a.isNullOrUndefined(b.pagingPageSizes)&&(b.pagingPageSizes=[250,500,1e3]),a.isNullOrUndefined(b.pagingPageSize)&&(b.pagingPageSize=b.pagingPageSizes.length>0?b.pagingPageSizes[0]:0),a.isNullOrUndefined(b.pagingCurrentPage)&&(b.pagingCurrentPage=1)},onPagingChanged:function(a,b,c){a.api.paging.raise.pagingChanged(b,c),a.options.useExternalPaging||a.refresh()}};return b}]),a.directive("uiGridPaging",["gridUtil","uiGridPagingService",function(a,b){var c="ui-grid/ui-grid-paging";return{priority:-200,scope:!1,require:"uiGrid",compile:function(){return{pre:function(d,e,f,g){b.initializeGrid(g.grid);var h=g.grid.options.pagingTemplate||c;a.getTemplate(h).then(function(a){var b=angular.element(a);e.append(b),g.innerCompile(b)})},post:function(){}}}}}]),a.directive("uiGridPager",["uiGridPagingService","uiGridConstants","gridUtil","i18nService",function(a,b,c,d){return{priority:-200,scope:!0,require:"^uiGrid",link:function(e,f,g,h){e.sizesLabel=d.getSafeText("paging.sizes"),e.totalItemsLabel=d.getSafeText("paging.totalItems");var i=e.grid.options;h.grid.renderContainers.body.registerViewportAdjuster(function(a){return a.height=a.height-c.elementHeight(f),a}),h.grid.registerDataChangeCallback(function(a){a.options.useExternalPaging||(a.options.totalItems=a.rows.length)},[b.dataChange.ROW]);var j=function(){e.showingLow=(i.pagingCurrentPage-1)*i.pagingPageSize+1,e.showingHigh=Math.min(i.pagingCurrentPage*i.pagingPageSize,i.totalItems)},k=function(){return 0===i.totalItems?1:Math.ceil(i.totalItems/i.pagingPageSize)},l=e.$watch("grid.options.totalItems + grid.options.pagingPageSize",function(){e.currentMaxPages=k(),j()}),m=e.$watch("grid.options.pagingCurrentPage + grid.options.pagingPageSize",function(b,c){if(b!==c){if(!angular.isNumber(i.pagingCurrentPage)||i.pagingCurrentPage<1)return void(i.pagingCurrentPage=1);if(i.totalItems>0&&i.pagingCurrentPage>k())return void(i.pagingCurrentPage=k());j(),a.onPagingChanged(e.grid,i.pagingCurrentPage,i.pagingPageSize)}});e.$on("$destroy",function(){l(),m()}),e.pageForward=function(){i.totalItems>0?i.pagingCurrentPage=Math.min(i.pagingCurrentPage+1,e.currentMaxPages):i.pagingCurrentPage++},e.pageBackward=function(){i.pagingCurrentPage=Math.max(i.pagingCurrentPage-1,1)},e.pageToFirst=function(){i.pagingCurrentPage=1},e.pageToLast=function(){i.pagingCurrentPage=e.currentMaxPages},e.cantPageForward=function(){return i.totalItems>0?i.pagingCurrentPage>=e.currentMaxPages:i.data.length<1},e.cantPageToLast=function(){return i.totalItems>0?e.cantPageForward():!0},e.cantPageBackward=function(){return i.pagingCurrentPage<=1}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.pinning",["ui.grid"]);a.service("uiGridPinningService",["gridUtil","GridRenderContainer","i18nService",function(a,b,c){var d={initializeGrid:function(a){d.defaultGridOptions(a.options),a.registerColumnBuilder(d.pinningColumnBuilder)},defaultGridOptions:function(a){a.enablePinning=a.enablePinning!==!1},pinningColumnBuilder:function(b,d,e){if(b.enablePinning=void 0===b.enablePinning?e.enablePinning:b.enablePinning,b.pinnedLeft?"*"===d.width?d.grid.refresh().then(function(){d.renderContainer="left",d.width=d.grid.canvasWidth/d.grid.columns.length,d.grid.createLeftContainer()}):(d.renderContainer="left",d.grid.createLeftContainer()):b.pinnedRight&&("*"===d.width?d.grid.refresh().then(function(){d.renderContainer="right",d.width=d.grid.canvasWidth/d.grid.columns.length,d.grid.createRightContainer()}):(d.renderContainer="right",d.grid.createRightContainer())),b.enablePinning){var f={name:"ui.grid.pinning.pinLeft",title:c.get().pinning.pinLeft,icon:"ui-grid-icon-left-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"left"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer="left",this.context.col.width=this.context.col.drawnWidth,this.context.col.grid.createLeftContainer(),d.grid.refresh().then(function(){d.grid.refresh()})}},g={name:"ui.grid.pinning.pinRight",title:c.get().pinning.pinRight,icon:"ui-grid-icon-right-open",shown:function(){return"undefined"==typeof this.context.col.renderContainer||!this.context.col.renderContainer||"right"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer="right",this.context.col.width=this.context.col.drawnWidth,this.context.col.grid.createRightContainer(),d.grid.refresh().then(function(){d.grid.refresh()})}},h={name:"ui.grid.pinning.unpin",title:c.get().pinning.unpin,icon:"ui-grid-icon-cancel",shown:function(){return"undefined"!=typeof this.context.col.renderContainer&&null!==this.context.col.renderContainer&&"body"!==this.context.col.renderContainer},action:function(){this.context.col.renderContainer=null,d.grid.refresh().then(function(){d.grid.refresh()})}};a.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.pinning.pinLeft")||d.menuItems.push(f),a.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.pinning.pinRight")||d.menuItems.push(g),a.arrayContainsObjectWithProperty(d.menuItems,"name","ui.grid.pinning.unpin")||d.menuItems.push(h)}}};return d}]),a.directive("uiGridPinning",["gridUtil","uiGridPinningService",function(a,b){return{require:"uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(e.grid)},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.resizeColumns",["ui.grid"]);a.constant("columnBounds",{minWidth:35}),a.service("uiGridResizeColumnsService",["gridUtil","$q","$timeout",function(a,b,c){var d={defaultGridOptions:function(a){a.enableColumnResizing=a.enableColumnResizing!==!1,a.enableColumnResize===!1&&(a.enableColumnResizing=!1)},colResizerColumnBuilder:function(a,c,d){var e=[];return a.enableColumnResizing=void 0===a.enableColumnResizing?d.enableColumnResizing:a.enableColumnResizing,a.enableColumnResize===!1&&(a.enableColumnResizing=!1),b.all(e)},registerPublicApi:function(a){var b={events:{colResizable:{columnSizeChanged:function(){}}}};a.api.registerEventsFromObject(b.events)},fireColumnSizeChanged:function(a,b,d){c(function(){a.api.colResizable.raise.columnSizeChanged(b,d)})}};return d}]),a.directive("uiGridResizeColumns",["gridUtil","uiGridResizeColumnsService",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.defaultGridOptions(e.grid.options),e.grid.registerColumnBuilder(b.colResizerColumnBuilder),b.registerPublicApi(e.grid)},post:function(){}}}}}]),a.directive("uiGridHeaderCell",["gridUtil","$templateCache","$compile","$q",function(a,b,c,d){return{priority:-10,require:"^uiGrid",compile:function(){return{post:function(a,e,f,g){if(g.grid.options.enableColumnResizing){var h=d.defer();
+f.$observe("renderIndex",function(b){a.renderIndex=a.$eval(b),h.resolve()}),h.promise.then(function(){var d=b.get("ui-grid/columnResizer"),f=angular.element(d).clone(),g=angular.element(d).clone();f.attr("position","left"),g.attr("position","right");var h=a.col,i=h.getRenderContainer(),j=i.renderedColumns[a.renderIndex-1];j&&0!==i.visibleColumnCache.indexOf(a.col)&&j.colDef.enableColumnResizing!==!1&&(e.prepend(f),c(f)(a)),a.col.colDef.enableColumnResizing!==!1&&(e.append(g),c(g)(a))})}}}}}}]),a.directive("uiGridColumnResizer",["$document","gridUtil","uiGridConstants","columnBounds","uiGridResizeColumnsService",function(a,b,c,d,e){var f=angular.element('<div class="ui-grid-resize-overlay"></div>'),g={priority:0,scope:{col:"=",position:"@",renderIndex:"="},require:"?^uiGrid",link:function(g,h,i,j){function k(a){var b=a.getRenderContainer();b.visibleColumnCache.forEach(function(b){if(b!==a){var c=b.colDef;(!c.width||angular.isString(c.width)&&(-1!==c.width.indexOf("*")||-1!==c.width.indexOf("%")))&&(b.width=b.drawnWidth)}})}function l(){j.grid.buildColumns().then(function(){j.grid.refreshCanvas(!0)})}function m(a){a.originalEvent&&(a=a.originalEvent),a.preventDefault(),p=a.clientX-q,0>p?p=0:p>j.grid.gridWidth&&(p=j.grid.gridWidth);var b,e=g.col,h=e.getRenderContainer();if("left"===g.position?(e=h.renderedColumns[g.renderIndex-1],b=g.col):"right"===g.position&&(b=h.renderedColumns[g.renderIndex+1]),e.colDef.enableColumnResizing!==!1){j.grid.element.hasClass("column-resizing")||j.grid.element.addClass("column-resizing");var i=p-o,k=parseInt(e.drawnWidth+i*r,10);e.colDef.minWidth&&k<e.colDef.minWidth?p+=(e.colDef.minWidth-k)*r:!e.colDef.minWidth&&d.minWidth&&k<d.minWidth?p+=e.colDef.minWidth-k:e.colDef.maxWidth&&k>e.colDef.maxWidth&&(p+=(e.colDef.maxWidth-k)*r),f.css({left:p+"px"}),j.fireEvent(c.events.ITEM_DRAGGING)}}function n(b){b.originalEvent&&(b=b.originalEvent),b.preventDefault(),j.grid.element.removeClass("column-resizing"),f.remove(),p=b.clientX-q;var c=p-o;if(0===c)return a.off("mouseup",n),void a.off("mousemove",m);var h,i=g.col,s=i.getRenderContainer();if("left"===g.position?(i=s.renderedColumns[g.renderIndex-1],h=g.col):"right"===g.position&&(h=s.renderedColumns[g.renderIndex+1]),i.colDef.enableColumnResizing!==!1){var t=parseInt(i.drawnWidth+c*r,10);i.colDef.minWidth&&t<i.colDef.minWidth?t=i.colDef.minWidth:!i.colDef.minWidth&&d.minWidth&&t<d.minWidth&&(t=d.minWidth),i.colDef.maxWidth&&t>i.colDef.maxWidth&&(t=i.colDef.maxWidth),i.width=t,k(i),l(c),e.fireColumnSizeChanged(j.grid,i.colDef,c),a.off("mouseup",n),a.off("mousemove",m)}}var o=0,p=0,q=0,r=1;j.grid.isRTL()&&(g.position="left",r=-1),"left"===g.position?h.addClass("left"):"right"===g.position&&h.addClass("right"),h.on("mousedown",function(b){b.originalEvent&&(b=b.originalEvent),b.stopPropagation(),q=j.grid.element[0].getBoundingClientRect().left,o=b.clientX-q,j.grid.element.append(f),f.css({left:o}),a.on("mouseup",n),a.on("mousemove",m)}),h.on("dblclick",function(a){a.stopPropagation();var f,i,m=g.col,n=m.getRenderContainer();"left"===g.position?(m=n.renderedColumns[g.renderIndex-1],f=g.col,i=1):"right"===g.position&&(f=n.renderedColumns[g.renderIndex+1],f=n.renderedColumns[g.renderIndex+1],i=-1);var o=0,p=0,q=b.closestElm(h,".ui-grid-render-container"),r=q.querySelectorAll("."+c.COL_CLASS_PREFIX+m.uid+" .ui-grid-cell-contents");Array.prototype.forEach.call(r,function(a){var c;angular.element(a).parent().hasClass("ui-grid-header-cell")&&(c=angular.element(a).parent()[0].querySelectorAll(".ui-grid-column-menu-button")),b.fakeElement(a,{},function(a){var d=angular.element(a);d.attr("style","float: left");var e=b.elementWidth(d);if(c){var f=b.elementWidth(c);e+=f}e>o&&(o=e,p=o-e)})}),m.colDef.minWidth&&o<m.colDef.minWidth?o=m.colDef.minWidth:!m.colDef.minWidth&&d.minWidth&&o<d.minWidth&&(o=d.minWidth),m.colDef.maxWidth&&o>m.colDef.maxWidth&&(o=m.colDef.maxWidth),m.width=parseInt(o,10),k(m),l(p),e.fireColumnSizeChanged(j.grid,m.colDef,p)}),h.on("$destroy",function(){h.off("mousedown"),h.off("dblclick"),a.off("mousemove",m),a.off("mouseup",n)})}};return g}])}(),function(){"use strict";var a=angular.module("ui.grid.rowEdit",["ui.grid","ui.grid.edit","ui.grid.cellNav"]);a.constant("uiGridRowEditConstants",{}),a.service("uiGridRowEditService",["$interval","$q","uiGridConstants","uiGridRowEditConstants","gridUtil",function(a,b,c,d,e){var f={initializeGrid:function(a,b){b.rowEdit={};var c={events:{rowEdit:{saveRow:function(){}}},methods:{rowEdit:{setSavePromise:function(a,b,c){f.setSavePromise(a,b,c)},getDirtyRows:function(a){return a.rowEdit.dirtyRows?a.rowEdit.dirtyRows:[]},getErrorRows:function(a){return a.rowEdit.errorRows?a.rowEdit.errorRows:[]},flushDirtyRows:function(a){return f.flushDirtyRows(a)},setRowsDirty:function(a,b){f.setRowsDirty(a,b)}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods),b.api.core.on.renderingComplete(a,function(){b.api.edit.on.afterCellEdit(a,f.endEditCell),b.api.edit.on.beginCellEdit(a,f.beginEditCell),b.api.edit.on.cancelCellEdit(a,f.cancelEditCell),b.api.cellNav&&b.api.cellNav.on.navigate(a,f.navigate)})},defaultGridOptions:function(){},saveRow:function(a,b){var c=this;return function(){b.isSaving=!0;var d=a.api.rowEdit.raise.saveRow(b.entity);return b.rowEditSavePromise?b.rowEditSavePromise.then(c.processSuccessPromise(a,b),c.processErrorPromise(a,b)):e.logError("A promise was not returned when saveRow event was raised, either nobody is listening to event, or event handler did not return a promise"),d}},setSavePromise:function(a,b,c){var d=a.getRow(b);d.rowEditSavePromise=c},processSuccessPromise:function(a,b){var c=this;return function(){delete b.isSaving,delete b.isDirty,delete b.isError,delete b.rowEditSaveTimer,c.removeRow(a.rowEdit.errorRows,b),c.removeRow(a.rowEdit.dirtyRows,b)}},processErrorPromise:function(a,b){return function(){delete b.isSaving,delete b.rowEditSaveTimer,b.isError=!0,a.rowEdit.errorRows||(a.rowEdit.errorRows=[]),f.isRowPresent(a.rowEdit.errorRows,b)||a.rowEdit.errorRows.push(b)}},removeRow:function(a,b){angular.forEach(a,function(c,d){c.uid===b.uid&&a.splice(d,1)})},isRowPresent:function(a,b){var c=!1;return angular.forEach(a,function(a){a.uid===b.uid&&(c=!0)}),c},flushDirtyRows:function(a){var c=[];return angular.forEach(a.rowEdit.dirtyRows,function(b){f.saveRow(a,b)(),c.push(b.rowEditSavePromise)}),b.all(c)},endEditCell:function(a,b,c,d){var g=this.grid,h=g.getRow(a);return h?void((c!==d||h.isDirty)&&(g.rowEdit.dirtyRows||(g.rowEdit.dirtyRows=[]),h.isDirty||(h.isDirty=!0,g.rowEdit.dirtyRows.push(h)),delete h.isError,f.considerSetTimer(g,h))):void e.logError("Unable to find rowEntity in grid data, dirty flag cannot be set")},beginEditCell:function(a){var b=this.grid,c=b.getRow(a);return c?void f.cancelTimer(b,c):void e.logError("Unable to find rowEntity in grid data, timer cannot be cancelled")},cancelEditCell:function(a){var b=this.grid,c=b.getRow(a);return c?void f.considerSetTimer(b,c):void e.logError("Unable to find rowEntity in grid data, timer cannot be set")},navigate:function(a,b){var c=this.grid;a.row.rowEditSaveTimer&&f.cancelTimer(c,a.row),b&&b.row&&b.row!==a.row&&f.considerSetTimer(c,b.row)},considerSetTimer:function(b,c){if(f.cancelTimer(b,c),c.isDirty&&!c.isSaving&&-1!==b.options.rowEditWaitInterval){var d=b.options.rowEditWaitInterval?b.options.rowEditWaitInterval:2e3;c.rowEditSaveTimer=a(f.saveRow(b,c),d,1)}},cancelTimer:function(b,c){c.rowEditSaveTimer&&!c.isSaving&&(a.cancel(c.rowEditSaveTimer),delete c.rowEditSaveTimer)},setRowsDirty:function(a,b){var c;b.forEach(function(b){c=a.getRow(b),c?(a.rowEdit.dirtyRows||(a.rowEdit.dirtyRows=[]),c.isDirty||(c.isDirty=!0,a.rowEdit.dirtyRows.push(c)),delete c.isError,f.considerSetTimer(a,c)):e.logError("requested row not found in rowEdit.setRowsDirty, row was: "+b)})}};return f}]),a.directive("uiGridRowEdit",["gridUtil","uiGridRowEditService","uiGridEditConstants",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(a,c,d,e){b.initializeGrid(a,e.grid)},post:function(){}}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","gridUtil","$parse",function(){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]),c=b.attr("ng-class"),d="";return d=c?c.slice(0,-1)+", 'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}":"{'ui-grid-row-dirty': row.isDirty, 'ui-grid-row-saving': row.isSaving, 'ui-grid-row-error': row.isError}",b.attr("ng-class",d),{pre:function(){},post:function(){}}}}}])}(),function(){"use strict";var a=angular.module("ui.grid.selection",["ui.grid"]);a.constant("uiGridSelectionConstants",{featureName:"selection",selectionRowHeaderColName:"selectionRowHeaderCol"}),a.service("uiGridSelectionService",["$q","$templateCache","uiGridSelectionConstants","gridUtil",function(){var a={initializeGrid:function(b){b.selection={},b.selection.lastSelectedRow=null,b.selection.selectAll=!1,a.defaultGridOptions(b.options);var c={events:{selection:{rowSelectionChanged:function(){},rowSelectionChangedBatch:function(){}}},methods:{selection:{toggleRowSelection:function(c){var d=b.getRow(c);null!==d&&a.toggleRowSelection(b,d,b.options.multiSelect,b.options.noUnselect)},selectRow:function(c){var d=b.getRow(c);null===d||d.isSelected||a.toggleRowSelection(b,d,b.options.multiSelect,b.options.noUnselect)},selectRowByVisibleIndex:function(c){var d=b.renderContainers.body.visibleRowCache[c];null===d||d.isSelected||a.toggleRowSelection(b,d,b.options.multiSelect,b.options.noUnselect)},unSelectRow:function(c){var d=b.getRow(c);null!==d&&d.isSelected&&a.toggleRowSelection(b,d,b.options.multiSelect,b.options.noUnselect)},selectAllRows:function(){if(b.options.multiSelect!==!1){var c=[];b.rows.forEach(function(d){d.isSelected||(d.isSelected=!0,a.decideRaiseSelectionEvent(b,d,c))}),a.decideRaiseSelectionBatchEvent(b,c)}},selectAllVisibleRows:function(){if(b.options.multiSelect!==!1){var c=[];b.rows.forEach(function(d){d.visible?d.isSelected||(d.isSelected=!0,a.decideRaiseSelectionEvent(b,d,c)):d.isSelected&&(d.isSelected=!1,a.decideRaiseSelectionEvent(b,d,c))}),a.decideRaiseSelectionBatchEvent(b,c)}},clearSelectedRows:function(){a.clearSelectedRows(b)},getSelectedRows:function(){return a.getSelectedRows(b).map(function(a){return a.entity})},getSelectedGridRows:function(){return a.getSelectedRows(b)},setMultiSelect:function(a){b.options.multiSelect=a},setModifierKeysToMultiSelect:function(a){b.options.modifierKeysToMultiSelect=a},getSelectAllState:function(){return b.selection.selectAll}}}};b.api.registerEventsFromObject(c.events),b.api.registerMethodsFromObject(c.methods)},defaultGridOptions:function(a){a.enableRowSelection=a.enableRowSelection!==!1,a.multiSelect=a.multiSelect!==!1,a.noUnselect=a.noUnselect===!0,a.modifierKeysToMultiSelect=a.modifierKeysToMultiSelect===!0,a.enableRowHeaderSelection=a.enableRowHeaderSelection!==!1,a.enableSelectAll=a.enableSelectAll!==!1,a.enableSelectionBatchEvent=a.enableSelectionBatchEvent!==!1,a.selectionRowHeaderWidth=angular.isDefined(a.selectionRowHeaderWidth)?a.selectionRowHeaderWidth:30},toggleRowSelection:function(b,c,d,e){var f=c.isSelected;if(d||f){if(!d&&f){var g=a.getSelectedRows(b);g.length>1&&(f=!1,a.clearSelectedRows(b))}}else a.clearSelectedRows(b);f&&e||(c.isSelected=!f,c.isSelected===!0&&(b.selection.lastSelectedRow=c),b.api.selection.raise.rowSelectionChanged(c))},shiftSelect:function(b,c,d){if(d){var e=a.getSelectedRows(b),f=e.length>0?b.renderContainers.body.visibleRowCache.indexOf(b.selection.lastSelectedRow):0,g=b.renderContainers.body.visibleRowCache.indexOf(c);if(f>g){var h=f;f=g,g=h}for(var i=[],j=f;g>=j;j++){var k=b.renderContainers.body.visibleRowCache[j];k&&(k.isSelected||(k.isSelected=!0,b.selection.lastSelectedRow=k,a.decideRaiseSelectionEvent(b,k,i)))}a.decideRaiseSelectionBatchEvent(b,i)}},getSelectedRows:function(a){return a.rows.filter(function(a){return a.isSelected})},clearSelectedRows:function(b){var c=[];a.getSelectedRows(b).forEach(function(d){d.isSelected&&(d.isSelected=!1,a.decideRaiseSelectionEvent(b,d,c))}),a.decideRaiseSelectionBatchEvent(b,c)},decideRaiseSelectionEvent:function(a,b,c){a.options.enableSelectionBatchEvent?c.push(b):a.api.selection.raise.rowSelectionChanged(b)},decideRaiseSelectionBatchEvent:function(a,b){b.length>0&&a.api.selection.raise.rowSelectionChangedBatch(b)}};return a}]),a.directive("uiGridSelection",["uiGridSelectionConstants","uiGridSelectionService","$templateCache",function(a,b){return{replace:!0,priority:0,require:"^uiGrid",scope:!1,compile:function(){return{pre:function(c,d,e,f){if(b.initializeGrid(f.grid),f.grid.options.enableRowHeaderSelection){var g={name:a.selectionRowHeaderColName,displayName:"",width:f.grid.options.selectionRowHeaderWidth,cellTemplate:"ui-grid/selectionRowHeader",headerCellTemplate:"ui-grid/selectionHeaderCell",enableColumnResizing:!1,enableColumnMenu:!1};f.grid.addRowHeaderColumn(g)}},post:function(){}}}}}]),a.directive("uiGridSelectionRowHeaderButtons",["$templateCache","uiGridSelectionService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionRowHeaderButtons"),scope:!0,require:"^uiGrid",link:function(a,c,d,e){var f=e.grid;a.selectButtonClick=function(a,c){c.shiftKey?b.shiftSelect(f,a,f.options.multiSelect):c.ctrlKey||c.metaKey?b.toggleRowSelection(f,a,f.options.multiSelect,f.options.noUnselect):b.toggleRowSelection(f,a,f.options.multiSelect&&!f.options.modifierKeysToMultiSelect,f.options.noUnselect)}}}}]),a.directive("uiGridSelectionSelectAllButtons",["$templateCache","uiGridSelectionService",function(a,b){return{replace:!0,restrict:"E",template:a.get("ui-grid/selectionSelectAllButtons"),scope:!1,link:function(a){var c=a.col.grid;a.headerButtonClick=function(){c.selection.selectAll?(b.clearSelectedRows(c),c.options.noUnselect&&c.api.selection.selectRowByVisibleIndex(0),c.selection.selectAll=!1):c.options.multiSelect&&(c.api.selection.selectAllVisibleRows(),c.selection.selectAll=!0)}}}}]),a.directive("uiGridViewport",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService",function(){return{priority:-200,scope:!1,compile:function(a){var b=angular.element(a.children().children()[0]),c=b.attr("ng-class"),d="";return d=c?c.slice(0,-1)+",'ui-grid-row-selected': row.isSelected}":"{'ui-grid-row-selected': row.isSelected}",b.attr("ng-class",d),{pre:function(){},post:function(){}}}}}]),a.directive("uiGridCell",["$compile","uiGridConstants","uiGridSelectionConstants","gridUtil","$parse","uiGridSelectionService",function(a,b,c,d,e,f){return{priority:-200,restrict:"A",scope:!1,link:function(a,b){function c(){var c=0,d=300,e=function(b){b.shiftKey?f.shiftSelect(a.grid,a.row,a.grid.options.multiSelect):b.ctrlKey||b.metaKey?f.toggleRowSelection(a.grid,a.row,a.grid.options.multiSelect,a.grid.options.noUnselect):f.toggleRowSelection(a.grid,a.row,a.grid.options.multiSelect&&!a.grid.options.modifierKeysToMultiSelect,a.grid.options.noUnselect),a.$apply()};b.on("touchstart",function(){c=(new Date).getTime()}),b.on("touchend",function(a){var b=(new Date).getTime(),f=b-c;d>f&&e(a)}),b.on("click",function(a){e(a)})}a.grid.options.enableRowSelection&&!a.grid.options.enableRowHeaderSelection&&(b.addClass("ui-grid-disable-selection"),c())}}}])}(),angular.module("ui.grid").run(["$templateCache",function(a){"use strict";a.put("ui-grid/ui-grid-footer",'<div class="ui-grid-footer-panel"><div ui-grid-group-panel ng-show="grid.options.showGroupPanel"></div><div class="ui-grid-footer ui-grid-footer-viewport"><div class="ui-grid-footer-canvas"><div ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ui-grid-footer-cell col="col" render-index="$index" class="ui-grid-footer-cell clearfix" ng-style="$index === 0 && colContainer.columnStyle($index)"></div></div></div></div>'),a.put("ui-grid/ui-grid-group-panel",'<div class="ui-grid-group-panel"><div ui-t="groupPanel.description" class="description" ng-show="groupings.length == 0"></div><ul ng-show="groupings.length > 0" class="ngGroupList"><li class="ngGroupItem" ng-repeat="group in configGroups"><span class="ngGroupElement"><span class="ngGroupName">{{group.displayName}} <span ng-click="removeGroup($index)" class="ngRemoveGroup">x</span></span> <span ng-hide="$last" class="ngGroupArrow"></span></span></li></ul></div>'),a.put("ui-grid/ui-grid-header",'<div class="ui-grid-header"><div class="ui-grid-top-panel"><div ui-grid-group-panel ng-show="grid.options.showGroupPanel"></div><div class="ui-grid-header-viewport"><div class="ui-grid-header-canvas"><div class="ui-grid-header-cell clearfix" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" ui-grid-header-cell col="col" render-index="$index" ng-style="$index === 0 && colContainer.columnStyle($index)"></div></div></div><div ui-grid-menu></div></div></div>'),a.put("ui-grid/ui-grid-menu-button",'<div class="ui-grid-menu-button" ng-click="toggleMenu()"><div class="ui-grid-icon-container"><i class="ui-grid-icon-menu">&nbsp;</i></div><div ui-grid-menu menu-items="menuItems"></div></div>'),a.put("ui-grid/ui-grid-no-header",'<div class="ui-grid-top-panel"></div>'),a.put("ui-grid/ui-grid-row",'<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader }" ui-grid-cell></div>'),a.put("ui-grid/ui-grid",'<div ui-i18n="en" class="ui-grid"><!-- TODO (c0bra): add "scoped" attr here, eventually? --><style ui-grid-style>.grid{{ grid.id }} {\n      /* Styles for the grid */\n    }\n\n    .grid{{ grid.id }} .ui-grid-row, .grid{{ grid.id }} .ui-grid-cell, .grid{{ grid.id }} .ui-grid-cell .ui-grid-vertical-bar {\n      height: {{ grid.options.rowHeight }}px;\n    }\n\n    .grid{{ grid.id }} .ui-grid-row:last-child .ui-grid-cell {\n      border-bottom-width: {{ ((grid.getTotalRowHeight() < grid.getViewportHeight()) && \'1\') || \'0\' }}px;\n    }\n\n    {{ grid.verticalScrollbarStyles }}\n    {{ grid.horizontalScrollbarStyles }}\n\n    .ui-grid[dir=rtl] .ui-grid-viewport {\n      padding-left: {{ grid.verticalScrollbarWidth }}px;\n    }\n\n    {{ grid.customStyles }}</style><div ui-grid-menu-button ng-if="grid.options.enableGridMenu"></div><div ui-grid-render-container container-id="\'body\'" col-container-name="\'body\'" row-container-name="\'body\'" bind-scroll-horizontal="true" bind-scroll-vertical="true" enable-horizontal-scrollbar="grid.options.enableHorizontalScrollbar" enable-vertical-scrollbar="grid.options.enableVerticalScrollbar"></div><div ui-grid-column-menu ng-if="grid.options.enableColumnMenus"></div><div ng-transclude></div></div>'),a.put("ui-grid/uiGridCell",'<div class="ui-grid-cell-contents">{{COL_FIELD CUSTOM_FILTERS}}</div>'),a.put("ui-grid/uiGridColumnFilter",'<li class="ui-grid-menu-item ui-grid-clearfix ui-grid-column-filter" ng-show="itemShown()" ng-click="$event.stopPropagation();"><div class="input-container"><input class="column-filter-input" type="text" ng-model="item.model" placeholder="{{ i18n.search.placeholder }}"><div class="column-filter-cancel-icon-container"><i class="ui-grid-filter-cancel ui-grid-icon-cancel column-filter-cancel-icon">&nbsp;</i></div></div><div style="button-container" ng-click="item.action($event)"><div class="ui-grid-button"><i class="ui-grid-icon-search">&nbsp;</i></div></div></li>'),a.put("ui-grid/uiGridColumnMenu",'<div class="ui-grid-column-menu"><div ui-grid-menu menu-items="menuItems"><!-- <div class="ui-grid-column-menu">\n    <div class="inner" ng-show="menuShown">\n      <ul>\n        <div ng-show="grid.options.enableSorting">\n          <li ng-click="sortColumn($event, asc)" ng-class="{ \'selected\' : col.sort.direction == asc }"><i class="ui-grid-icon-sort-alt-up"></i> Sort Ascending</li>\n          <li ng-click="sortColumn($event, desc)" ng-class="{ \'selected\' : col.sort.direction == desc }"><i class="ui-grid-icon-sort-alt-down"></i> Sort Descending</li>\n          <li ng-show="col.sort.direction" ng-click="unsortColumn()"><i class="ui-grid-icon-cancel"></i> Remove Sort</li>\n        </div>\n      </ul>\n    </div>\n  </div> --></div></div>'),a.put("ui-grid/uiGridFooterCell",'<div class="ui-grid-cell-contents" col-index="renderIndex"><div>{{ col.getAggregationValue() }}</div></div>'),a.put("ui-grid/uiGridHeaderCell",'<div ng-class="{ \'sortable\': sortable }"><div class="ui-grid-vertical-bar">&nbsp;</div><div class="ui-grid-cell-contents" col-index="renderIndex"><span>{{ col.displayName CUSTOM_FILTERS }}</span> <span ui-grid-visible="col.sort.direction" ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }">&nbsp;</span></div><div class="ui-grid-column-menu-button" ng-if="grid.options.enableColumnMenus && !col.isRowHeader  && col.colDef.enableColumnMenu !== false" class="ui-grid-column-menu-button" ng-click="toggleMenu($event)"><i class="ui-grid-icon-angle-down">&nbsp;</i></div><div ng-if="filterable" class="ui-grid-filter-container" ng-repeat="colFilter in col.filters"><input type="text" class="ui-grid-filter-input" ng-model="colFilter.term" ng-click="$event.stopPropagation()" ng-attr-placeholder="{{colFilter.placeholder || \'\'}}"><div class="ui-grid-filter-button" ng-click="colFilter.term = null"><i class="ui-grid-icon-cancel" ng-show="!!colFilter.term">&nbsp;</i><!-- use !! because angular interprets \'f\' as false --></div></div></div>'),a.put("ui-grid/uiGridMenu",'<div class="ui-grid-menu" ng-if="shown"><div class="ui-grid-menu-mid" ng-show="shownMid"><div class="ui-grid-menu-inner"><ul class="ui-grid-menu-items"><li ng-repeat="item in menuItems" ui-grid-menu-item action="item.action" title="item.title" active="item.active" icon="item.icon" shown="item.shown" context="item.context" template-url="item.templateUrl"></li></ul></div></div></div>'),a.put("ui-grid/uiGridMenuItem",'<li class="ui-grid-menu-item" ng-click="itemAction($event, title)" ng-show="itemShown()" ng-class="{ \'ui-grid-menu-item-active\' : active() }"><i ng-class="icon"></i> {{ title }}</li>'),a.put("ui-grid/uiGridRenderContainer",'<div class="ui-grid-render-container"><div ui-grid-header></div><div ui-grid-viewport></div><div ui-grid-footer ng-if="grid.options.showFooter"></div><!-- native scrolling --><div ui-grid-native-scrollbar ng-if="enableVerticalScrollbar" type="vertical"></div><div ui-grid-native-scrollbar ng-if="enableHorizontalScrollbar" type="horizontal"></div></div>'),a.put("ui-grid/uiGridViewport",'<div class="ui-grid-viewport"><div class="ui-grid-canvas"><div ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index" class="ui-grid-row" ng-style="containerCtrl.rowStyle(rowRenderIndex)"><div ui-grid-row="row" row-render-index="rowRenderIndex"></div></div></div></div>'),a.put("ui-grid/cellEditor",'<div><form name="inputForm"><input type="{{inputType}}" ng-class="\'colt\' + col.uid" ui-grid-editor ng-model="MODEL_COL_FIELD"></form></div>'),a.put("ui-grid/dropdownEditor",'<div><form name="inputForm"><select ng-class="\'colt\' + col.uid" ui-grid-edit-dropdown ng-model="MODEL_COL_FIELD" ng-options="field[editDropdownIdLabel] as field[editDropdownValueLabel] CUSTOM_FILTERS for field in editDropdownOptionsArray"></select></form></div>'),a.put("ui-grid/expandableRow",'<div ui-grid-expandable-row ng-if="expandableRow.shouldRenderExpand()" class="expandableRow" style="float:left; margin-top: 1px; margin-bottom: 1px" ng-style="{width: (grid.renderContainers.body.getCanvasWidth() - grid.verticalScrollbarWidth) + \'px\'\n     , height: grid.options.expandableRowHeight + \'px\'}"></div>'),a.put("ui-grid/expandableRowHeader",'<div class="ui-grid-row-header-cell ui-grid-expandable-buttons-cell"><div class="ui-grid-cell-contents"><i ng-class="{ \'ui-grid-icon-plus-squared\' : !row.isExpanded, \'ui-grid-icon-minus-squared\' : row.isExpanded }" ng-click="grid.api.expandable.toggleRowExpansion(row.entity)"></i></div></div>'),a.put("ui-grid/expandableScrollFiller","<div ng-if=\"expandableRow.shouldRenderFiller()\" style=\"float:left; margin-top: 2px; margin-bottom: 2px\" ng-style=\"{ width: (grid.getViewportWidth()) + 'px',\n              height: grid.options.expandableRowHeight + 'px', 'margin-left': grid.options.rowHeader.rowHeaderWidth + 'px' }\"><i class=\"ui-grid-icon-spin5 ui-grid-animate-spin\" ng-style=\"{ 'margin-top': ( grid.options.expandableRowHeight/2 - 5) + 'px',\n            'margin-left' : ((grid.getViewportWidth() - grid.options.rowHeader.rowHeaderWidth)/2 - 5) + 'px' }\"></i></div>"),a.put("ui-grid/csvLink",'<span class="ui-grid-exporter-csv-link-span"><a href="data:text/csv;charset=UTF-8,CSV_CONTENT">LINK_LABEL</a></span>'),a.put("ui-grid/importerMenuItem",'<li class="ui-grid-menu-item"><form><input class="ui-grid-importer-file-chooser" type="file" id="files" name="files[]"></form></li>'),a.put("ui-grid/importerMenuItemContainer","<div ui-grid-importer-menu-item></div>"),a.put("ui-grid/ui-grid-paging",'<div class="ui-grid-pager-panel" ui-grid-pager><div class="ui-grid-pager-container"><div class="ui-grid-pager-control"><button type="button" ng-click="pageToFirst()" ng-disabled="cantPageBackward()"><div class="first-triangle"><div class="first-bar"></div></div></button> <button type="button" ng-click="pageBackward()" ng-disabled="cantPageBackward()"><div class="first-triangle prev-triangle"></div></button> <input type="number" ng-model="grid.options.pagingCurrentPage" min="1" max="{{currentMaxPages}}" required> <span class="ui-grid-pager-max-pages-number" ng-show="currentMaxPages > 0">/ {{currentMaxPages}}</span> <button type="button" ng-click="pageForward()" ng-disabled="cantPageForward()"><div class="last-triangle next-triangle"></div></button> <button type="button" ng-click="pageToLast()" ng-disabled="cantPageToLast()"><div class="last-triangle"><div class="last-bar"></div></div></button></div><div class="ui-grid-pager-row-count-picker"><select ng-model="grid.options.pagingPageSize" ng-options="o as o for o in grid.options.pagingPageSizes"></select><span class="ui-grid-pager-row-count-label">&nbsp;{{sizesLabel}}</span></div></div><div class="ui-grid-pager-count-container"><div class="ui-grid-pager-count"><span ng-show="grid.options.totalItems > 0">{{showingLow}} - {{showingHigh}} of {{grid.options.totalItems}} {{totalItemsLabel}}</span></div></div></div>'),a.put("ui-grid/columnResizer",'<div ui-grid-column-resizer ng-if="grid.options.enableColumnResizing" class="ui-grid-column-resizer" col="col" position="right" render-index="renderIndex"></div>'),a.put("ui-grid/selectionHeaderCell",'<div><div class="ui-grid-vertical-bar">&nbsp;</div><div class="ui-grid-cell-contents" col-index="renderIndex"><ui-grid-selection-select-all-buttons ng-if="grid.options.enableSelectAll"></ui-grid-selection-select-all-buttons></div></div>'),a.put("ui-grid/selectionRowHeader",'<div class="ui-grid-row-header-cell ui-grid-disable-selection"><div class="ui-grid-cell-contents"><ui-grid-selection-row-header-buttons></ui-grid-selection-row-header-buttons></div></div>'),a.put("ui-grid/selectionRowHeaderButtons",'<div class="ui-grid-selection-row-header-buttons ui-grid-icon-ok" ng-class="{\'ui-grid-row-selected\': row.isSelected}" ng-click="selectButtonClick(row, $event)">&nbsp;</div>'),a.put("ui-grid/selectionSelectAllButtons",'<div class="ui-grid-selection-row-header-buttons ui-grid-icon-ok" ng-class="{\'ui-grid-all-selected\': grid.selection.selectAll}" ng-click="headerButtonClick($event)">&nbsp;</div>')}]);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid.js
new file mode 100644 (file)
index 0000000..55bb3c2
--- /dev/null
@@ -0,0 +1,787 @@
+/*! ui-grid - v2.0.7-g7aeb576 - 2013-12-18
+* Copyright (c) 2013 ; Licensed MIT */
+(function(){
+'use strict';
+
+var app = angular.module('ui.grid.body', []);
+
+app.directive('uiGridBody', ['$log', 'GridUtil', function($log, GridUtil) {
+  return {
+    replace: true,
+    priority: 1000,
+    templateUrl: 'ui-grid/ui-grid-body',
+    require: '?^uiGrid',
+    scope: {
+      tableClass: '=uiGridTableClass'
+    },
+    link: function(scope, elm, attrs, uiGridCtrl) {
+      $log.debug('body postlink scope', scope.$id);
+
+      if (uiGridCtrl === undefined) {
+        $log.warn('[ui-grid-body] uiGridCtrl is undefined!');
+      }
+
+      if (uiGridCtrl && typeof(uiGridCtrl.columns) !== 'undefined' && uiGridCtrl.columns) {
+        scope.columns = uiGridCtrl.columns;
+      }
+      if (uiGridCtrl && typeof(uiGridCtrl.gridData) !== 'undefined' && uiGridCtrl.gridData) {
+        scope.gridData = uiGridCtrl.gridData;
+      }
+    }
+  };
+}]);
+
+})();
+(function(){
+'use strict';
+
+var app = angular.module('ui.grid.header', ['ui.grid.util']);
+
+app.directive('uiGridHeader', ['$log', '$templateCache', '$compile', 'GridUtil', function($log, $templateCache, $compile, GridUtil) {
+  return {
+    restrict: 'EA',
+    // templateUrl: 'ui-grid/ui-grid-header',
+    // replace: true,
+    priority: 1000,
+    require: '?^uiGrid',
+    scope: {
+      tableClass: '=uiGridTableClass'
+    },
+    compile: function (elm, attrs) {
+      $log.debug('header compile');
+
+      // If the contents of the grid element are empty, use the default grid template
+      var tmpl;
+      if (elm.html() === '' || /^\s*$/.test(elm.html())) {
+        tmpl = $templateCache.get('ui-grid/ui-grid-header');
+      }
+
+      var preLink = function (scope, elm, attrs) {
+        $log.debug('header prelink scope', scope.$id);
+
+        if (tmpl) {
+          elm.append(tmpl);
+        }
+        $compile(elm.contents())(scope);
+      };
+
+      var postLink = function(scope, elm, attrs, uiGridCtrl) {
+        $log.debug('header postlink scope', scope.$id);
+
+        if (uiGridCtrl === undefined) {
+          $log.warn('[ui-grid-header] uiGridCtrl is undefined!');
+        }
+
+        // Get the column defs from the parent grid controller
+        if (uiGridCtrl && typeof(uiGridCtrl.columns) !== 'undefined' && uiGridCtrl.columns) {
+          scope.columns = uiGridCtrl.columns;
+        }
+
+        // if (tmpl) {
+        //   elm.append(tmpl);
+        //   $compile(elm.contents())(scope);
+        // }
+
+        // scope.$watch('columns', function(n, o) {
+        //    $log.debug('columns change', n, o);
+        //    var contents = elm.contents();
+        //    $compile(contents)(scope);
+        // });
+      };
+
+      return {
+        pre: preLink,
+        post: postLink
+      };
+    }
+  };
+}]);
+
+})();
+(function(){
+// 'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ui.grid.style.directive:uiGridStyle
+ * @element style
+ * @restrict A
+ *
+ * @description
+ * Allows us to interpolate expressions in `<style>` elements. Angular doesn't do this by default as it can/will/might? break in IE8.
+ *
+ * @example
+   <example module="app">
+     <file name="app.js">
+       var app = angular.module('app', ['ui.grid']);
+       
+       app.controller('MainCtrl', ['$scope', function ($scope) {
+         $scope.myStyle = '.blah { color: red }';
+       }]);
+     </file>
+     <file name="index.html">
+       <div ng-controller="MainCtrl">
+         <style ui-grid-style>{{ myStyle }}</style>
+         <span class="blah">I am red.</span>
+       </div>
+     </file>
+   </example>
+ */
+
+var app = angular.module('ui.grid.style', []);
+
+app.directive('uiGridStyle', ['$interpolate', '$sce', function($interpolate, $sce) {
+  return {
+    // restrict: 'A',
+    priority: 1000,
+    link: function(scope, element) {
+      var interpolateFn = $interpolate(element.text(), true);
+
+      if (interpolateFn) {
+        scope.$watch(interpolateFn, function(value) {
+          element.text(value);
+        });
+      }
+    }
+  };
+}]);
+
+})();
+(function(){
+'use strict';
+
+var app = angular.module('ui.grid', ['ui.grid.header', 'ui.grid.body', 'ui.grid.style', 'ui.virtual-repeat']);
+
+/**
+ *  @ngdoc directive
+ *  @name ui.grid.directive:uiGrid
+ *  @element div
+ *  @restrict EA
+ *  @param {array} uiGrid Array of rows to display in the grid
+ *  
+ *  @description Create a very basic grid.
+ *
+ *  @example
+    <example module="app">
+      <file name="app.js">
+        var app = angular.module('app', ['ui.grid']);
+
+        app.controller('MainCtrl', ['$scope', function ($scope) {
+          $scope.data = [
+            { name: 'Bob', title: 'CEO' },
+            { name: 'Frank', title: 'Lowly Developer' }
+          ];
+        }]);
+      </file>
+      <file name="index.html">
+        <div ng-controller="MainCtrl">
+          <div ui-grid="data"></div>
+        </div>
+      </file>
+    </example>
+ */
+app.directive('uiGrid',
+  [
+    '$compile',
+    '$templateCache',
+    '$log',
+    'GridUtil',
+  function(
+    $compile,
+    $templateCache,
+    $log,
+    GridUtil
+  ) {
+
+    function preLink(scope, elm, attrs) {
+      var options = scope.uiGrid;
+
+      // Create an ID for this grid
+      scope.gridId = GridUtil.newId();
+
+      // Get the grid dimensions from the element
+
+      // Initialize the grid
+
+      // Get the column definitions
+        // Put a watch on them
+
+      console.log('gridId', scope.gridId);
+
+      elm.on('$destroy', function() {
+        // Remove columnDefs watch
+      });
+    }
+    
+    return {
+      templateUrl: 'ui-grid/ui-grid',
+      scope: {
+        uiGrid: '='
+      },
+      compile: function () {
+        return {
+          pre: preLink
+        };
+      },
+      controller: function ($scope, $element, $attrs) {
+        
+      }
+    };
+  }
+]);
+
+})();
+(function(){
+'use strict';
+  
+// (part of the sf.virtualScroll module).
+var mod = angular.module('ui.virtual-repeat', []);
+
+var DONT_WORK_AS_VIEWPORTS = ['TABLE', 'TBODY', 'THEAD', 'TR', 'TFOOT'];
+var DONT_WORK_AS_CONTENT = ['TABLE', 'TBODY', 'THEAD', 'TR', 'TFOOT'];
+var DONT_SET_DISPLAY_BLOCK = ['TABLE', 'TBODY', 'THEAD', 'TR', 'TFOOT'];
+
+// Utility to clip to range
+function clip(value, min, max){
+  if (angular.isArray(value)) {
+    return angular.forEach(value, function(v) {
+      return clip(v, min, max);
+    });
+  }
+
+  return Math.max(min, Math.min(value, max));
+}
+
+mod.directive('uiVirtualRepeat', ['$log', '$rootElement', function($log, $rootElement){
+
+  // Turn the expression supplied to the directive:
+  //
+  //     a in b
+  //
+  // into `{ value: "a", collection: "b" }`
+  function parseRepeatExpression(expression) {
+    var match = expression.match(/^\s*([\$\w]+)\s+in\s+([\S\s]*)$/);
+    if (! match) {
+      throw new Error("Expected uiVirtualRepeat in form of '_item_ in _collection_' but got '" + expression + "'.");
+    }
+    return {
+      value: match[1],
+      collection: match[2]
+    };
+  }
+
+  // Utility to filter out elements by tag name
+  function isTagNameInList(element, list) {
+    var t,
+        tag = element.tagName.toUpperCase();
+
+    for (t = 0; t < list.length; t++) {
+      if (list[t] === tag) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  // Utility to find the viewport/content elements given the start element:
+  function findViewportAndContent(startElement) {
+    /*jshint eqeqeq:false, curly:false */
+    var root = $rootElement[0];
+    var e, n;
+
+    // Somewhere between the grandparent and the root node
+    for (e = startElement.parent().parent()[0]; e !== root; e = e.parentNode) {
+      // is an element
+      if (e.nodeType != 1) break;
+      // that isn't in the blacklist (tables etc.),
+      if (isTagNameInList(e, DONT_WORK_AS_VIEWPORTS)) continue;
+      // has a single child element (the content),
+      if (e.childElementCount != 1) continue;
+      // which is not in the blacklist
+      if (isTagNameInList(e.firstElementChild, DONT_WORK_AS_CONTENT)) continue;
+      // and no text.
+      for (n = e.firstChild; n; n = n.nextSibling) {
+        if (n.nodeType == 3 && /\S/g.test(n.textContent)) {
+          break;
+        }
+      }
+
+      if (n == null) {
+        // That element should work as a viewport.
+        return {
+          viewport: angular.element(e),
+          content: angular.element(e.firstElementChild)
+        };
+      }
+    }
+
+    throw new Error("No suitable viewport element");
+  }
+
+  // Apply explicit height and overflow styles to the viewport element.
+  //
+  // If the viewport has a max-height (inherited or otherwise), set max-height.
+  // Otherwise, set height from the current computed value or use
+  // window.innerHeight as a fallback
+  //
+  function setViewportCSS(viewport) {
+    var viewportCSS = {'overflow': 'auto'};
+
+    var style = window.getComputedStyle ?
+                window.getComputedStyle(viewport[0]) :
+                viewport[0].currentStyle;
+
+    var maxHeight = style && style.getPropertyValue('max-height');
+    var height = style && style.getPropertyValue('height');
+
+    if (maxHeight && maxHeight !== '0px') {
+      viewportCSS.maxHeight = maxHeight;
+    }
+    else if (height && height !== '0px') {
+      viewportCSS.height = height;
+    }
+    else {
+      viewportCSS.height = window.innerHeight;
+    }
+
+    viewport.css(viewportCSS);
+  }
+
+  // Apply explicit styles to the content element to prevent pesky padding
+  // or borders messing with our calculations:
+  function setContentCSS(content) {
+    var contentCSS = {
+      margin: 0,
+      padding: 0,
+      border: 0,
+      'box-sizing': 'border-box'
+    };
+
+    content.css(contentCSS);
+  }
+
+  // TODO: compute outerHeight (padding + border unless box-sizing is border)
+  function computeRowHeight(element) {
+    var style = window.getComputedStyle ?
+                window.getComputedStyle(element) :
+                element.currentStyle;
+
+    var maxHeight = style && style.getPropertyValue('max-height');
+    var height = style && style.getPropertyValue('height');
+
+    if (height && height !== '0px' && height !== 'auto') {
+      // $log.info('Row height is "%s" from css height', height);
+    }
+    else if (maxHeight && maxHeight !== '0px' && maxHeight !== 'none') {
+      height = maxHeight;
+      // $log.info('Row height is "%s" from css max-height', height);
+    }
+    else if (element.clientHeight) {
+      height = element.clientHeight + 'px';
+      // $log.info('Row height is "%s" from client height', height);
+    }
+    else {
+      //throw new Error("Unable to compute height of row");
+      return;
+    }
+
+    angular.element(element).css('height', height);
+
+    return parseInt(height, 10);
+  }
+
+  // The compile gathers information about the declaration. There's not much
+  // else we could do in the compile step as we need a viewport parent that
+  // is exculsively ours - this is only available at link time.
+  function uiVirtualRepeatCompile(element, attr, linker) {
+    var ident = parseRepeatExpression(attr.uiVirtualRepeat);
+    
+    // ----
+
+    // Set up the initial value for our watch expression (which is just the
+    // start and length of the active rows and the collection length) and
+    // adds a listener to handle child scopes based on the active rows.
+    function sfVirtualRepeatPostLink(scope, iterStartElement, attrs) {
+
+      var rendered = [];
+          scope.rendered = rendered;
+
+      var rowHeight = 0;
+      var sticky = false;
+      var dom = findViewportAndContent(iterStartElement);
+      // The list structure is controlled by a few simple (visible) variables:
+      var state = 'ngModel' in attrs ? scope.$eval(attrs.ngModel) : {};
+      //  - The index of the first active element
+      state.firstActive = 0;
+      //  - The index of the first visible element
+      state.firstVisible = 0;
+      //  - The number of elements visible in the viewport.
+      state.visible = 0;
+      // - The number of active elements
+      state.active = 0;
+      // - The total number of elements
+      state.total = 0;
+      // - The point at which we add new elements
+      state.lowWater = state.lowWater || 10;
+      // - The point at which we remove old elements
+      state.highWater = state.highWater || 20;
+      // TODO: now watch the water marks
+
+      setContentCSS(dom.content);
+      setViewportCSS(dom.viewport);
+      // When the user scrolls, we move the `state.firstActive`
+      dom.viewport.bind('scroll', sfVirtualRepeatOnScroll);
+
+      // The watch on the collection is just a watch on the length of the
+      // collection. We don't care if the content changes.
+      scope.$watch(sfVirtualRepeatWatchExpression, sfVirtualRepeatListener, true);
+
+      // and that's the link done! All the action is in the handlers...
+      
+      // ----
+
+      // Apply explicit styles to the item element
+      function setElementCSS(element) {
+        var elementCSS = {
+          // no margin or it'll screw up the height calculations.
+          margin: '0'
+        };
+
+        if (!isTagNameInList(element[0], DONT_SET_DISPLAY_BLOCK)) {
+          // display: block if it's safe to do so
+          elementCSS.display = 'block';
+        }
+
+        if (rowHeight) {
+          elementCSS.height = rowHeight + 'px';
+        }
+
+        element.css(elementCSS);
+      }
+
+      function makeNewScope (idx, collection, containerScope) {
+        var childScope = containerScope.$new();
+        childScope[ident.value] = collection[idx];
+        childScope.$index = idx;
+        childScope.$first = (idx === 0);
+        childScope.$last = (idx === (collection.length - 1));
+        childScope.$middle = !(childScope.$first || childScope.$last);
+        childScope.$watch(function updateChildScopeItem(){
+          childScope[ident.value] = collection[idx];
+        });
+        return childScope;
+      }
+
+      function addElements (start, end, collection, containerScope, insPoint) {
+        var frag = document.createDocumentFragment();
+        var newElements = [], element, idx, childScope;
+
+        for (idx = start; idx !== end; idx++) {
+          childScope = makeNewScope(idx, collection, containerScope);
+          element = linker(childScope, angular.noop);
+          setElementCSS(element);
+          newElements.push(element);
+          frag.appendChild(element[0]);
+        }
+
+        insPoint.after(frag);
+        return newElements;
+      }
+
+      function recomputeActive() {
+        // We want to set the start to the low water mark unless the current
+        // start is already between the low and high water marks.
+        var start = clip(state.firstActive, state.firstVisible - state.lowWater, state.firstVisible - state.highWater);
+        // Similarly for the end
+        var end = clip(state.firstActive + state.active,
+                       state.firstVisible + state.visible + state.lowWater,
+                       state.firstVisible + state.visible + state.highWater );
+        state.firstActive = Math.max(0, start);
+        state.active = Math.min(end, state.total) - state.firstActive;
+      }
+
+      function sfVirtualRepeatOnScroll(evt) {
+        if (!rowHeight) {
+          return;
+        }
+
+        // Enter the angular world for the state change to take effect.
+        scope.$apply(function() {
+          state.firstVisible = Math.floor(evt.target.scrollTop / rowHeight);
+          state.visible = Math.ceil(dom.viewport[0].clientHeight / rowHeight);
+
+          // $log.log('scroll to row %o', state.firstVisible);
+          sticky = evt.target.scrollTop + evt.target.clientHeight >= evt.target.scrollHeight;
+
+          recomputeActive();
+          // $log.log(' state is now %o', state);
+          // $log.log(' sticky = %o', sticky);
+        });
+      }
+
+      function sfVirtualRepeatWatchExpression(scope) {
+        var coll = scope.$eval(ident.collection);
+
+        if (coll.length !== state.total) {
+          state.total = coll.length;
+          recomputeActive();
+        }
+
+        return {
+          start: state.firstActive,
+          active: state.active,
+          len: coll.length
+        };
+      }
+
+      function destroyActiveElements (action, count) {
+        var dead,
+            ii,
+            remover = Array.prototype[action];
+
+        for (ii = 0; ii < count; ii++) {
+          dead = remover.call(rendered);
+          dead.scope().$destroy();
+          dead.remove();
+        }
+      }
+
+      // When the watch expression for the repeat changes, we may need to add
+      // and remove scopes and elements
+      function sfVirtualRepeatListener(newValue, oldValue, scope) {
+        var oldEnd = oldValue.start + oldValue.active,
+            collection = scope.$eval(ident.collection),
+            newElements;
+
+        if (newValue === oldValue) {
+          // $log.info('initial listen');
+          newElements = addElements(newValue.start, oldEnd, collection, scope, iterStartElement);
+          rendered = newElements;
+
+          if (rendered.length) {
+            rowHeight = computeRowHeight(newElements[0][0]);
+          }
+        }
+        else {
+          var newEnd = newValue.start + newValue.active;
+          var forward = newValue.start >= oldValue.start;
+          var delta = forward ? newValue.start - oldValue.start
+                              : oldValue.start - newValue.start;
+          var endDelta = newEnd >= oldEnd ? newEnd - oldEnd : oldEnd - newEnd;
+          var contiguous = delta < (forward ? oldValue.active : newValue.active);
+          // $log.info('change by %o,%o rows %s', delta, endDelta, forward ? 'forward' : 'backward');
+
+          if (!contiguous) {
+            // $log.info('non-contiguous change');
+            destroyActiveElements('pop', rendered.length);
+            rendered = addElements(newValue.start, newEnd, collection, scope, iterStartElement);
+          }
+          else {
+            if (forward) {
+              // $log.info('need to remove from the top');
+              destroyActiveElements('shift', delta);
+            }
+            else if (delta) {
+              // $log.info('need to add at the top');
+              newElements = addElements(
+                newValue.start,
+                oldValue.start,
+                collection, scope, iterStartElement);
+              rendered = newElements.concat(rendered);
+            }
+
+            if (newEnd < oldEnd) {
+              // $log.info('need to remove from the bottom');
+              destroyActiveElements('pop', oldEnd - newEnd);
+            }
+            else if (endDelta) {
+              var lastElement = rendered[rendered.length-1];
+              // $log.info('need to add to the bottom');
+              newElements = addElements(
+                oldEnd,
+                newEnd,
+                collection, scope, lastElement);
+
+              rendered = rendered.concat(newElements);
+            }
+          }
+
+          if (!rowHeight && rendered.length) {
+            rowHeight = computeRowHeight(rendered[0][0]);
+          }
+
+          dom.content.css({'padding-top': newValue.start * rowHeight + 'px'});
+        }
+
+        dom.content.css({'height': newValue.len * rowHeight + 'px'});
+
+        if (sticky) {
+          dom.viewport[0].scrollTop = dom.viewport[0].clientHeight + dom.viewport[0].scrollHeight;
+        }
+
+        scope.rendered = rendered;
+      }
+
+      return;
+    }
+
+    return {
+      post: sfVirtualRepeatPostLink
+    };
+  }
+
+  var directive =  {
+    require: '?ngModel',
+    transclude: 'element',
+    priority: 1000,
+    // terminal: true,
+    compile: uiVirtualRepeatCompile,
+    controller: ['$scope', function ($scope) {
+      this.visibleRows = 0;
+      this.visibleRows = this.visibleRows + 1;
+    }]
+  };
+
+  return directive;
+}]);
+
+}());
+(function() {
+
+var app = angular.module('ui.grid.util', []);
+
+/**
+ *  @ngdoc service
+ *  @name ui.grid.util.service:GridUtil
+ *  
+ *  @description Grid utility functions
+ */
+app.service('GridUtil', function () {
+
+  var s = {
+
+    /**
+     * @ngdoc method
+     * @name readableColumnName
+     * @methodOf ui.grid.util.service:GridUtil
+     *
+     * @param {string} columnName Column name as a string
+     * @returns {string} Column name appropriately capitalized and split apart
+     *
+       @example
+       <example module="app">
+        <file name="app.js">
+          var app = angular.module('app', ['ui.grid.util']);
+
+          app.controller('MainCtrl', ['$scope', 'GridUtil', function ($scope, GridUtil) {
+            $scope.name = 'firstName';
+            $scope.columnName = function(name) {
+              return GridUtil.readableColumnName(name);
+            };
+          }]);
+        </file>
+        <file name="index.html">
+          <div ng-controller="MainCtrl">
+            <strong>Column name:</strong> <input ng-model="name" />
+            <br>
+            <strong>Output:</strong> <span ng-bind="columnName(name)"></span>
+          </div>
+        </file>
+      </example>
+     */
+    readableColumnName: function (columnName) {
+      // Convert underscores to spaces
+      if (typeof(columnName) === 'undefined' || columnName === undefined || columnName === null) { return columnName; }
+
+      if (typeof(columnName) !== 'string') {
+        columnName = String(columnName);
+      }
+
+      return columnName.replace(/_+/g, ' ')
+        // Replace a completely all-capsed word with a first-letter-capitalized version
+        .replace(/^[A-Z]+$/, function (match) {
+          return angular.lowercase(angular.uppercase(match.charAt(0)) + match.slice(1));
+        })
+        // Capitalize the first letter of words
+        .replace(/(\w+)/g, function (match) {
+          return angular.uppercase(match.charAt(0)) + match.slice(1);
+        })
+        // Put a space in between words that have partial capilizations (i.e. 'firstName' becomes 'First Name')
+        // .replace(/([A-Z]|[A-Z]\w+)([A-Z])/g, "$1 $2");
+        // .replace(/(\w+?|\w)([A-Z])/g, "$1 $2");
+        .replace(/(\w+?(?=[A-Z]))/g, '$1 ');
+    },
+
+    /**
+     * @ngdoc method
+     * @name getColumnsFromData
+     * @methodOf ui.grid.util.service:GridUtil
+     * @description Return a list of column names, given a data set
+     *
+     * @param {string} data Data array for grid
+     * @returns {Object} Column definitions with field accessor and column name
+     *
+     * @example
+       <pre>
+         var data = [
+           { firstName: 'Bob', lastName: 'Jones' },
+           { firstName: 'Frank', lastName: 'Smith' }
+         ];
+
+         var columnDefs = GridUtil.getColumnsFromData(data);
+
+         columnDefs == [
+          {
+            field: 'firstName',
+            name: 'First Name'
+          },
+          {
+            field: 'lastName',
+            name: 'Last Name'
+          }
+         ];
+       </pre>
+     */
+    getColumnsFromData: function (data) {
+      var columnDefs = [];
+
+      var item = data[0];
+      
+      angular.forEach(item, function (prop, propName) {
+        columnDefs.push({
+          field: propName,
+          name: s.readableColumnName(propName)
+        });
+      });
+
+      return columnDefs;
+    },
+
+    /**
+     * @ngdoc method
+     * @name newId
+     * @methodOf ui.grid.util.service:GridUtil
+     * @description Return a unique ID string
+     *
+     * @returns {string} Unique string
+     *
+     * @example
+       <pre>
+        var id = GridUtil.newId();
+
+        # 1387305700482;
+       </pre>
+     */
+    newId: (function() {
+      var seedId = new Date().getTime();
+      return function() {
+          return seedId += 1;
+      };
+    })(),
+  };
+
+  return s;
+});
+
+})();
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/ui-grid.min.js b/src/main/resources/META-INF/resources/designer/lib/ui-grid.min.js
new file mode 100644 (file)
index 0000000..832ad8e
--- /dev/null
@@ -0,0 +1,3 @@
+/*! ui-grid - v2.0.7-g7aeb576 - 2013-12-18
+* Copyright (c) 2013 ; Licensed MIT */
+!function(){"use strict";var a=angular.module("ui.grid.body",[]);a.directive("uiGridBody",["$log","GridUtil",function(a){return{replace:!0,priority:1e3,templateUrl:"ui-grid/ui-grid-body",require:"?^uiGrid",scope:{tableClass:"=uiGridTableClass"},link:function(b,c,d,e){a.debug("body postlink scope",b.$id),void 0===e&&a.warn("[ui-grid-body] uiGridCtrl is undefined!"),e&&"undefined"!=typeof e.columns&&e.columns&&(b.columns=e.columns),e&&"undefined"!=typeof e.gridData&&e.gridData&&(b.gridData=e.gridData)}}}])}(),function(){"use strict";var a=angular.module("ui.grid.header",["ui.grid.util"]);a.directive("uiGridHeader",["$log","$templateCache","$compile","GridUtil",function(a,b,c){return{restrict:"EA",priority:1e3,require:"?^uiGrid",scope:{tableClass:"=uiGridTableClass"},compile:function(d){a.debug("header compile");var e;(""===d.html()||/^\s*$/.test(d.html()))&&(e=b.get("ui-grid/ui-grid-header"));var f=function(b,d){a.debug("header prelink scope",b.$id),e&&d.append(e),c(d.contents())(b)},g=function(b,c,d,e){a.debug("header postlink scope",b.$id),void 0===e&&a.warn("[ui-grid-header] uiGridCtrl is undefined!"),e&&"undefined"!=typeof e.columns&&e.columns&&(b.columns=e.columns)};return{pre:f,post:g}}}}])}(),function(){var a=angular.module("ui.grid.style",[]);a.directive("uiGridStyle",["$interpolate","$sce",function(a){return{priority:1e3,link:function(b,c){var d=a(c.text(),!0);d&&b.$watch(d,function(a){c.text(a)})}}}])}(),function(){"use strict";var a=angular.module("ui.grid",["ui.grid.header","ui.grid.body","ui.grid.style","ui.virtual-repeat"]);a.directive("uiGrid",["$compile","$templateCache","$log","GridUtil",function(a,b,c,d){function e(a,b){a.uiGrid;a.gridId=d.newId(),console.log("gridId",a.gridId),b.on("$destroy",function(){})}return{templateUrl:"ui-grid/ui-grid",scope:{uiGrid:"="},compile:function(){return{pre:e}},controller:function(){}}}])}(),function(){"use strict";function a(b,c,d){return angular.isArray(b)?angular.forEach(b,function(b){return a(b,c,d)}):Math.max(c,Math.min(b,d))}var b=angular.module("ui.virtual-repeat",[]),c=["TABLE","TBODY","THEAD","TR","TFOOT"],d=["TABLE","TBODY","THEAD","TR","TFOOT"],e=["TABLE","TBODY","THEAD","TR","TFOOT"];b.directive("uiVirtualRepeat",["$log","$rootElement",function(b,f){function g(a){var b=a.match(/^\s*([\$\w]+)\s+in\s+([\S\s]*)$/);if(!b)throw new Error("Expected uiVirtualRepeat in form of '_item_ in _collection_' but got '"+a+"'.");return{value:b[1],collection:b[2]}}function h(a,b){var c,d=a.tagName.toUpperCase();for(c=0;c<b.length;c++)if(b[c]===d)return!0;return!1}function i(a){var b,e,g=f[0];for(b=a.parent().parent()[0];b!==g&&1==b.nodeType;b=b.parentNode)if(!h(b,c)&&1==b.childElementCount&&!h(b.firstElementChild,d)){for(e=b.firstChild;e&&(3!=e.nodeType||!/\S/g.test(e.textContent));e=e.nextSibling);if(null==e)return{viewport:angular.element(b),content:angular.element(b.firstElementChild)}}throw new Error("No suitable viewport element")}function j(a){var b={overflow:"auto"},c=window.getComputedStyle?window.getComputedStyle(a[0]):a[0].currentStyle,d=c&&c.getPropertyValue("max-height"),e=c&&c.getPropertyValue("height");d&&"0px"!==d?b.maxHeight=d:b.height=e&&"0px"!==e?e:window.innerHeight,a.css(b)}function k(a){var b={margin:0,padding:0,border:0,"box-sizing":"border-box"};a.css(b)}function l(a){var b=window.getComputedStyle?window.getComputedStyle(a):a.currentStyle,c=b&&b.getPropertyValue("max-height"),d=b&&b.getPropertyValue("height");if(d&&"0px"!==d&&"auto"!==d);else if(c&&"0px"!==c&&"none"!==c)d=c;else{if(!a.clientHeight)return;d=a.clientHeight+"px"}return angular.element(a).css("height",d),parseInt(d,10)}function m(b,c,d){function f(b,c,f){function g(a){var b={margin:"0"};h(a[0],e)||(b.display="block"),v&&(b.height=v+"px"),a.css(b)}function n(a,b,c){var d=c.$new();return d[m.value]=b[a],d.$index=a,d.$first=0===a,d.$last=a===b.length-1,d.$middle=!(d.$first||d.$last),d.$watch(function(){d[m.value]=b[a]}),d}function o(a,b,c,e,f){var h,i,j,k=document.createDocumentFragment(),l=[];for(i=a;i!==b;i++)j=n(i,c,e),h=d(j,angular.noop),g(h),l.push(h),k.appendChild(h[0]);return f.after(k),l}function p(){var b=a(y.firstActive,y.firstVisible-y.lowWater,y.firstVisible-y.highWater),c=a(y.firstActive+y.active,y.firstVisible+y.visible+y.lowWater,y.firstVisible+y.visible+y.highWater);y.firstActive=Math.max(0,b),y.active=Math.min(c,y.total)-y.firstActive}function q(a){v&&b.$apply(function(){y.firstVisible=Math.floor(a.target.scrollTop/v),y.visible=Math.ceil(x.viewport[0].clientHeight/v),w=a.target.scrollTop+a.target.clientHeight>=a.target.scrollHeight,p()})}function r(a){var b=a.$eval(m.collection);return b.length!==y.total&&(y.total=b.length,p()),{start:y.firstActive,active:y.active,len:b.length}}function s(a,b){var c,d,e=Array.prototype[a];for(d=0;b>d;d++)c=e.call(u),c.scope().$destroy(),c.remove()}function t(a,b,d){var e,f=b.start+b.active,g=d.$eval(m.collection);if(a===b)e=o(a.start,f,g,d,c),u=e,u.length&&(v=l(e[0][0]));else{var h=a.start+a.active,i=a.start>=b.start,j=i?a.start-b.start:b.start-a.start,k=h>=f?h-f:f-h,n=j<(i?b.active:a.active);if(n){if(i?s("shift",j):j&&(e=o(a.start,b.start,g,d,c),u=e.concat(u)),f>h)s("pop",f-h);else if(k){var p=u[u.length-1];e=o(f,h,g,d,p),u=u.concat(e)}}else s("pop",u.length),u=o(a.start,h,g,d,c);!v&&u.length&&(v=l(u[0][0])),x.content.css({"padding-top":a.start*v+"px"})}x.content.css({height:a.len*v+"px"}),w&&(x.viewport[0].scrollTop=x.viewport[0].clientHeight+x.viewport[0].scrollHeight),d.rendered=u}var u=[];b.rendered=u;var v=0,w=!1,x=i(c),y="ngModel"in f?b.$eval(f.ngModel):{};y.firstActive=0,y.firstVisible=0,y.visible=0,y.active=0,y.total=0,y.lowWater=y.lowWater||10,y.highWater=y.highWater||20,k(x.content),j(x.viewport),x.viewport.bind("scroll",q),b.$watch(r,t,!0)}var m=g(c.uiVirtualRepeat);return{post:f}}var n={require:"?ngModel",transclude:"element",priority:1e3,compile:m,controller:["$scope",function(){this.visibleRows=0,this.visibleRows=this.visibleRows+1}]};return n}])}(),function(){var a=angular.module("ui.grid.util",[]);a.service("GridUtil",function(){var a={readableColumnName:function(a){return"undefined"==typeof a||void 0===a||null===a?a:("string"!=typeof a&&(a=String(a)),a.replace(/_+/g," ").replace(/^[A-Z]+$/,function(a){return angular.lowercase(angular.uppercase(a.charAt(0))+a.slice(1))}).replace(/(\w+)/g,function(a){return angular.uppercase(a.charAt(0))+a.slice(1)}).replace(/(\w+?(?=[A-Z]))/g,"$1 "))},getColumnsFromData:function(b){var c=[],d=b[0];return angular.forEach(d,function(b,d){c.push({field:d,name:a.readableColumnName(d)})}),c},newId:function(){var a=(new Date).getTime();return function(){return a+=1}}()};return a})}();
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/lib/xml2json.min.js b/src/main/resources/META-INF/resources/designer/lib/xml2json.min.js
new file mode 100644 (file)
index 0000000..14c5e90
--- /dev/null
@@ -0,0 +1 @@
+(function(a,b){if(typeof define==="function"&&define.amd){define([],b);}else{if(typeof exports==="object"){module.exports=b();}else{a.X2JS=b();}}}(this,function(){return function(z){var t="1.2.0";z=z||{};i();u();function i(){if(z.escapeMode===undefined){z.escapeMode=true;}z.attributePrefix=z.attributePrefix||"_";z.arrayAccessForm=z.arrayAccessForm||"none";z.emptyNodeForm=z.emptyNodeForm||"text";if(z.enableToStringFunc===undefined){z.enableToStringFunc=true;}z.arrayAccessFormPaths=z.arrayAccessFormPaths||[];if(z.skipEmptyTextNodesForObj===undefined){z.skipEmptyTextNodesForObj=true;}if(z.stripWhitespaces===undefined){z.stripWhitespaces=true;}z.datetimeAccessFormPaths=z.datetimeAccessFormPaths||[];if(z.useDoubleQuotes===undefined){z.useDoubleQuotes=false;}z.xmlElementsFilter=z.xmlElementsFilter||[];z.jsonPropertiesFilter=z.jsonPropertiesFilter||[];if(z.keepCData===undefined){z.keepCData=false;}}var h={ELEMENT_NODE:1,TEXT_NODE:3,CDATA_SECTION_NODE:4,COMMENT_NODE:8,DOCUMENT_NODE:9};function u(){}function x(B){var C=B.localName;if(C==null){C=B.baseName;}if(C==null||C==""){C=B.nodeName;}return C;}function r(B){return B.prefix;}function s(B){if(typeof(B)=="string"){return B.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;");}else{return B;}}function k(B){return B.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&amp;/g,"&");}function w(C,F,D,E){var B=0;for(;B<C.length;B++){var G=C[B];if(typeof G==="string"){if(G==E){break;}}else{if(G instanceof RegExp){if(G.test(E)){break;}}else{if(typeof G==="function"){if(G(F,D,E)){break;}}}}}return B!=C.length;}function n(D,B,C){switch(z.arrayAccessForm){case"property":if(!(D[B] instanceof Array)){D[B+"_asArray"]=[D[B]];}else{D[B+"_asArray"]=D[B];}break;}if(!(D[B] instanceof Array)&&z.arrayAccessFormPaths.length>0){if(w(z.arrayAccessFormPaths,D,B,C)){D[B]=[D[B]];}}}function a(G){var E=G.split(/[-T:+Z]/g);var F=new Date(E[0],E[1]-1,E[2]);var D=E[5].split(".");F.setHours(E[3],E[4],D[0]);if(D.length>1){F.setMilliseconds(D[1]);}if(E[6]&&E[7]){var C=E[6]*60+Number(E[7]);var B=/\d\d-\d\d:\d\d$/.test(G)?"-":"+";C=0+(B=="-"?-1*C:C);F.setMinutes(F.getMinutes()-C-F.getTimezoneOffset());}else{if(G.indexOf("Z",G.length-1)!==-1){F=new Date(Date.UTC(F.getFullYear(),F.getMonth(),F.getDate(),F.getHours(),F.getMinutes(),F.getSeconds(),F.getMilliseconds()));}}return F;}function q(D,B,C){if(z.datetimeAccessFormPaths.length>0){var E=C.split(".#")[0];if(w(z.datetimeAccessFormPaths,D,B,E)){return a(D);}else{return D;}}else{return D;}}function b(E,C,B,D){if(C==h.ELEMENT_NODE&&z.xmlElementsFilter.length>0){return w(z.xmlElementsFilter,E,B,D);}else{return true;}}function A(D,J){if(D.nodeType==h.DOCUMENT_NODE){var K=new Object;var B=D.childNodes;for(var L=0;L<B.length;L++){var C=B.item(L);if(C.nodeType==h.ELEMENT_NODE){var I=x(C);K[I]=A(C,I);}}return K;}else{if(D.nodeType==h.ELEMENT_NODE){var K=new Object;K.__cnt=0;var B=D.childNodes;for(var L=0;L<B.length;L++){var C=B.item(L);var I=x(C);if(C.nodeType!=h.COMMENT_NODE){var H=J+"."+I;if(b(K,C.nodeType,I,H)){K.__cnt++;if(K[I]==null){K[I]=A(C,H);n(K,I,H);}else{if(K[I]!=null){if(!(K[I] instanceof Array)){K[I]=[K[I]];n(K,I,H);}}(K[I])[K[I].length]=A(C,H);}}}}for(var E=0;E<D.attributes.length;E++){var F=D.attributes.item(E);K.__cnt++;K[z.attributePrefix+F.name]=F.value;}var G=r(D);if(G!=null&&G!=""){K.__cnt++;K.__prefix=G;}if(K["#text"]!=null){K.__text=K["#text"];if(K.__text instanceof Array){K.__text=K.__text.join("\n");}if(z.stripWhitespaces){K.__text=K.__text.trim();}delete K["#text"];if(z.arrayAccessForm=="property"){delete K["#text_asArray"];}K.__text=q(K.__text,I,J+"."+I);}if(K["#cdata-section"]!=null){K.__cdata=K["#cdata-section"];delete K["#cdata-section"];if(z.arrayAccessForm=="property"){delete K["#cdata-section_asArray"];}}if(K.__cnt==0&&z.emptyNodeForm=="text"){K="";}else{if(K.__cnt==1&&K.__text!=null){K=K.__text;}else{if(K.__cnt==1&&K.__cdata!=null&&!z.keepCData){K=K.__cdata;}else{if(K.__cnt>1&&K.__text!=null&&z.skipEmptyTextNodesForObj){if((z.stripWhitespaces&&K.__text=="")||(K.__text.trim()=="")){delete K.__text;}}}}}delete K.__cnt;if(z.enableToStringFunc&&(K.__text!=null||K.__cdata!=null)){K.toString=function(){return(this.__text!=null?this.__text:"")+(this.__cdata!=null?this.__cdata:"");};}return K;}else{if(D.nodeType==h.TEXT_NODE||D.nodeType==h.CDATA_SECTION_NODE){return D.nodeValue;}}}}function o(I,F,H,C){var E="<"+((I!=null&&I.__prefix!=null)?(I.__prefix+":"):"")+F;if(H!=null){for(var G=0;G<H.length;G++){var D=H[G];var B=I[D];if(z.escapeMode){B=s(B);}E+=" "+D.substr(z.attributePrefix.length)+"=";if(z.useDoubleQuotes){E+='"'+B+'"';}else{E+="'"+B+"'";}}}if(!C){E+=">";}else{E+="/>";}return E;}function j(C,B){return"</"+(C.__prefix!=null?(C.__prefix+":"):"")+B+">";}function v(C,B){return C.indexOf(B,C.length-B.length)!==-1;}function y(C,B){if((z.arrayAccessForm=="property"&&v(B.toString(),("_asArray")))||B.toString().indexOf(z.attributePrefix)==0||B.toString().indexOf("__")==0||(C[B] instanceof Function)){return true;}else{return false;}}function m(D){var C=0;if(D instanceof Object){for(var B in D){if(y(D,B)){continue;}C++;}}return C;}function l(D,B,C){return z.jsonPropertiesFilter.length==0||C==""||w(z.jsonPropertiesFilter,D,B,C);}function c(D){var C=[];if(D instanceof Object){for(var B in D){if(B.toString().indexOf("__")==-1&&B.toString().indexOf(z.attributePrefix)==0){C.push(B);}}}return C;}function g(C){var B="";if(C.__cdata!=null){B+="<![CDATA["+C.__cdata+"]]>";}if(C.__text!=null){if(z.escapeMode){B+=s(C.__text);}else{B+=C.__text;}}return B;}function d(C){var B="";if(C instanceof Object){B+=g(C);}else{if(C!=null){if(z.escapeMode){B+=s(C);}else{B+=C;}}}return B;}function p(C,B){if(C===""){return B;}else{return C+"."+B;}}function f(D,G,F,E){var B="";if(D.length==0){B+=o(D,G,F,true);}else{for(var C=0;C<D.length;C++){B+=o(D[C],G,c(D[C]),false);B+=e(D[C],p(E,G));B+=j(D[C],G);}}return B;}function e(I,H){var B="";var F=m(I);if(F>0){for(var E in I){if(y(I,E)||(H!=""&&!l(I,E,p(H,E)))){continue;}var D=I[E];var G=c(D);if(D==null||D==undefined){B+=o(D,E,G,true);}else{if(D instanceof Object){if(D instanceof Array){B+=f(D,E,G,H);}else{if(D instanceof Date){B+=o(D,E,G,false);B+=D.toISOString();B+=j(D,E);}else{var C=m(D);if(C>0||D.__text!=null||D.__cdata!=null){B+=o(D,E,G,false);B+=e(D,p(H,E));B+=j(D,E);}else{B+=o(D,E,G,true);}}}}else{B+=o(D,E,G,false);B+=d(D);B+=j(D,E);}}}}B+=d(I);return B;}this.parseXmlString=function(D){var F=window.ActiveXObject||"ActiveXObject" in window;if(D===undefined){return null;}var E;if(window.DOMParser){var G=new window.DOMParser();var B=null;if(!F){try{B=G.parseFromString("INVALID","text/xml").getElementsByTagName("parsererror")[0].namespaceURI;}catch(C){B=null;}}try{E=G.parseFromString(D,"text/xml");if(B!=null&&E.getElementsByTagNameNS(B,"parsererror").length>0){E=null;}}catch(C){E=null;}}else{if(D.indexOf("<?")==0){D=D.substr(D.indexOf("?>")+2);}E=new ActiveXObject("Microsoft.XMLDOM");E.async="false";E.loadXML(D);}return E;};this.asArray=function(B){if(B===undefined||B==null){return[];}else{if(B instanceof Array){return B;}else{return[B];}}};this.toXmlDateTime=function(B){if(B instanceof Date){return B.toISOString();}else{if(typeof(B)==="number"){return new Date(B).toISOString();}else{return null;}}};this.asDateTime=function(B){if(typeof(B)=="string"){return a(B);}else{return B;}};this.xml2json=function(B){return A(B);};this.xml_str2json=function(B){var C=this.parseXmlString(B);if(C!=null){return this.xml2json(C);}else{return null;}};this.json2xml_str=function(B){return e(B,"");};this.json2xml=function(C){var B=this.json2xml_str(C);return this.parseXmlString(B);};this.getVersion=function(){return t;};};}));
diff --git a/src/main/resources/META-INF/resources/designer/modeler/Gruntfile.js b/src/main/resources/META-INF/resources/designer/modeler/Gruntfile.js
new file mode 100644 (file)
index 0000000..8d76446
--- /dev/null
@@ -0,0 +1,127 @@
+module.exports = function(grunt) {
+
+  require('load-grunt-tasks')(grunt);
+
+  var path = require('path');
+
+  /**
+   * Resolve external project resource as file path
+   */
+  function resolvePath(project, file) {
+    return path.join(path.dirname(require.resolve(project)), file);
+  }
+
+  // project configuration
+  grunt.initConfig({
+    pkg: grunt.file.readJSON('package.json'),
+
+    config: {
+      sources: 'app',
+      dist: 'dist'
+    },
+
+    jshint: {
+      src: [
+        ['<%=config.sources %>']
+      ],
+      options: {
+        jshintrc: true
+      }
+    },
+
+    browserify: {
+      options: {
+        browserifyOptions: {
+          // make sure we do not include browser shims unnecessarily
+          builtins: false,
+          insertGlobalVars: {
+            process: function () {
+                return 'undefined';
+            },
+            Buffer: function () {
+                return 'undefined';
+            }
+          }
+        },
+        transform: [ 'brfs' ]
+      },
+      watch: {
+        options: {
+          watch: true
+        },
+        files: {
+          '<%= config.dist %>/index.js': [ '<%= config.sources %>/**/*.js' ]
+        }
+      },
+      app: {
+        files: {
+          '<%= config.dist %>/index.js': [ '<%= config.sources %>/**/*.js' ]
+        }
+      }
+    },
+    copy: {
+      diagram_js: {
+        files: [
+          {
+            src: resolvePath('diagram-js', 'assets/diagram-js.css'),
+            dest: '<%= config.dist %>/css/diagram-js.css'
+          }
+        ]
+      },
+      bpmn_js: {
+        files: [
+          {
+            expand: true,
+            cwd: resolvePath('bpmn-js', 'assets'),
+            src: ['**/*.*', '!**/*.js'],
+            dest: '<%= config.dist %>/vendor'
+          }
+        ]
+      },
+      app: {
+        files: [
+          {
+            expand: true,
+            cwd: '<%= config.sources %>/',
+            src: ['**/*.*', '!**/*.js'],
+            dest: '<%= config.dist %>'
+          }
+        ]
+      }
+    },
+    watch: {
+      samples: {
+        files: [ '<%= config.sources %>/**/*.*' ],
+        tasks: [ 'copy:app' ]
+      },
+    },
+    connect: {
+      options: {
+        port: 9013,
+        livereload: 9014,
+        hostname: 'localhost'
+      },
+      livereload: {
+        options: {
+          open: true,
+          base: [
+            '<%= config.dist %>'
+          ]
+        }
+      }
+    }
+  });
+
+  // tasks
+
+  grunt.registerTask('build', [ 'copy', 'browserify:app' ]);
+
+  grunt.registerTask('auto-build', [
+    'copy',
+    'browserify:watch',
+    'connect:livereload',
+    'watch'
+  ]);
+
+  grunt.registerTask('default', [ 'jshint', 'build' ]);
+};
diff --git a/src/main/resources/META-INF/resources/designer/modeler/README.md b/src/main/resources/META-INF/resources/designer/modeler/README.md
new file mode 100644 (file)
index 0000000..2aa9c55
--- /dev/null
@@ -0,0 +1,36 @@
+# bpmn-js Modeler Example
+
+This example uses [bpmn-js](https://github.com/bpmn-io/bpmn-js) to implement a modeler for BPMN 2.0 process diagrams. It serves as the basis of the bpmn-js demo application available at [demo.bpmn.io](http://demo.bpmn.io).
+
+## About
+
+This example is a node-style web application that builds a user interface around the bpmn-js BPMN 2.0 modeler.
+
+![demo application screenshot](https://raw.githubusercontent.com/bpmn-io/bpmn-js-examples/master/modeler/docs/screenshot.png "Screenshot of the example application")
+
+
+## Building
+
+You need a [NodeJS](http://nodejs.org) development stack with [npm](https://npmjs.org) and [grunt](http://gruntjs.com) installed to build the project.
+
+To install all project dependencies execute
+
+```
+npm install
+```
+
+Build the application (including [bpmn-js](https://github.com/bpmn-io/bpmn-js)) using [browserify](http://browserify.org) via
+
+```
+grunt
+```
+
+You may also spawn a development setup by executing
+
+```
+grunt auto-build
+```
+
+Both tasks generate the distribution ready client-side modeler application into the `dist` folder.
+
+Serve the application locally or via a web server (nginx, apache, embedded).
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/designer/modeler/dist/css/app.css b/src/main/resources/META-INF/resources/designer/modeler/dist/css/app.css
new file mode 100644 (file)
index 0000000..7fe4159
--- /dev/null
@@ -0,0 +1,96 @@
+* {
+  box-sizing: border-box;
+}
+
+body, html {
+
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+  font-size: 12px;
+
+  height: 100%;
+  padding: 0;
+  margin: 0;
+}
+
+a:link {
+  text-decoration: none;
+}
+
+.content,
+.content > div {
+  width: 100%;
+  height: 100%;
+}
+
+.content > .message {
+  text-align: center;
+  display: table;
+
+  font-size: 16px;
+  color: #111;
+}
+
+.content > .message .note {
+  vertical-align: middle;
+  text-align: center;
+  display: table-cell;
+}
+
+.content .error .details {
+  max-width: 500px;
+  font-size: 12px;
+  margin: 20px auto;
+  text-align: left;
+}
+
+.content .error pre {
+  border: solid 1px #CCC;
+  background: #EEE;
+  padding: 10px;
+}
+
+.content:not(.with-error) .error,
+.content.with-error .intro,
+.content.with-diagram .intro {
+  display: none;
+}
+
+
+.content .canvas,
+.content.with-error .canvas {
+  visibility: hidden;
+}
+
+.content.with-diagram .canvas {
+  visibility: visible;
+}
+
+.buttons {
+  position: fixed;
+  bottom: 20px;
+  left: 20px;
+
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+
+.buttons > li {
+  display: inline-block;
+  margin-right: 10px;
+}
+.buttons > li > a {
+  background: #DDD;
+  border: solid 1px #666;
+  display: inline-block;
+  padding: 5px;
+}
+
+.buttons a {
+  opacity: 0.3;
+}
+
+.buttons a.active {
+  opacity: 1.0;
+}
diff --git a/src/main/resources/META-INF/resources/designer/modeler/dist/css/diagram-js.css b/src/main/resources/META-INF/resources/designer/modeler/dist/css/diagram-js.css
new file mode 100644 (file)
index 0000000..8e502b8
--- /dev/null
@@ -0,0 +1,460 @@
+/**
+ * outline styles
+ */
+
+.djs-outline {
+  fill: none;
+  visibility: hidden;
+}
+
+.djs-element.hover .djs-outline,
+.djs-element.selected .djs-outline {
+  visibility: visible;
+  shape-rendering: crispEdges;
+  stroke-dasharray: 3,3;
+}
+
+.djs-element.selected .djs-outline {
+  stroke: #8888FF;
+  stroke-width: 1px;
+}
+
+.djs-element.hover .djs-outline {
+  stroke: #FF8888;
+  stroke-width: 1px;
+}
+
+.djs-shape.connect-ok .djs-visual > :nth-child(1) {
+  fill: #54FF00 /* light-green */ !important;
+  fill-opacity: 0.2;
+}
+
+.djs-shape.connect-not-ok .djs-visual > :nth-child(1),
+.djs-shape.drop-not-ok .djs-visual > :nth-child(1) {
+  fill: #E56283 /* light-red */ !important;
+  fill-opacity: 0.2;
+}
+
+svg.drop-not-ok {
+  background: rgba(229, 98, 131, 0.2) /* light-red */ !important;
+}
+
+.djs-connection.connect-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-ok .djs-visual > :nth-child(1) {
+  stroke: #90DD5F /* light-green */ !important;
+}
+
+.djs-connection.connect-not-ok .djs-visual > :nth-child(1),
+.djs-connection.drop-not-ok .djs-visual > :nth-child(1) {
+  stroke: #E56283 /* light-red */ !important;
+}
+
+.drop-not-ok,
+.connect-not-ok {
+  cursor: not-allowed;
+}
+
+
+/**
+* Selection box style
+*
+*/
+.djs-lasso-overlay {
+  fill: rgb(255, 116, 0);
+  fill-opacity: 0.1;
+
+  stroke-dasharray: 5 1 3 1;
+  stroke: rgb(255, 116, 0);
+
+  shape-rendering: crispEdges;
+  pointer-events: none;
+}
+
+/**
+ * Resize styles
+ */
+.djs-resize-overlay {
+  fill: white;
+  fill-opacity: 0.8;
+
+  stroke-dasharray: 5 1 3 1;
+  stroke: rgb(255, 116, 0);
+
+  pointer-events: none;
+}
+
+.djs-resizer-hit {
+  fill: none;
+  pointer-events: all;
+}
+
+.djs-resizer-visual {
+  fill: white;
+  stroke-width: 1px;
+  stroke: black;
+  shape-rendering: crispEdges;
+  stroke-opacity: 0.2;
+}
+
+.djs-cursor-resize-nwse,
+.djs-resizer-nw,
+.djs-resizer-se {
+  cursor: nwse-resize;
+}
+
+.djs-cursor-resize-nesw,
+.djs-resizer-ne,
+.djs-resizer-sw {
+  cursor: nesw-resize;
+}
+
+.djs-shape.djs-resizing > .djs-outline {
+  visibility: hidden !important;
+}
+
+.djs-shape.djs-resizing > .djs-resizer {
+  visibility: hidden;
+}
+
+.djs-dragger > .djs-resizer {
+  visibility: hidden;
+}
+
+/**
+ * drag styles
+ */
+.djs-dragger {
+  fill: white;
+  fill-opacity: 0.6;
+  stroke: #333;
+}
+
+.djs-dragger .djs-visual > :first-child {
+  stroke: rgb(255, 116, 0) !important;
+}
+
+.djs-dragging {
+  opacity: 0.3;
+}
+
+.djs-dragging,
+.djs-dragging > * {
+  pointer-events: none !important;
+}
+
+.djs-dragging .djs-context-pad,
+.djs-dragging .djs-outline {
+  display: none !important;
+}
+
+/**
+ * no pointer events for visual
+ */
+.djs-visual,
+.djs-outline {
+  pointer-events: none;
+}
+
+/**
+ * all pointer events for hit shape
+ */
+.djs-shape .djs-hit {
+  pointer-events: all;
+}
+
+.djs-connection .djs-hit {
+  pointer-events: stroke;
+}
+
+/**
+ * shape / connection basic styles
+ */
+.djs-connection .djs-visual {
+  stroke-width: 2px;
+  fill: none;
+}
+
+.djs-cursor-grabbing {
+  cursor: -webkit-grabbing;
+  cursor: -moz-grabbing;
+  cursor: grabbing;
+}
+
+.djs-cursor-crosshair {
+  cursor: crosshair;
+}
+
+.djs-cursor-move {
+  cursor: move;
+}
+
+.djs-cursor-resize-ns {
+  cursor: ns-resize;
+}
+
+.djs-cursor-resize-ew {
+  cursor: ew-resize;
+}
+
+
+/**
+ * snapping
+ */
+.djs-snap-line {
+  stroke: rgb(255, 195, 66);
+  stroke: rgba(255, 195, 66, 0.50);
+  stroke-linecap: round;
+  stroke-width: 2px;
+  pointer-events: none;
+}
+
+/**
+ * snapping
+ */
+.djs-crosshair {
+  stroke: #555;
+  stroke-linecap: round;
+  stroke-width: 1px;
+  pointer-events: none;
+  shape-rendering: crispEdges;
+  stroke-dasharray: 5, 5;
+}
+
+/**
+ * palette
+ */
+
+.djs-palette {
+  position:relative;
+  left: 20px;
+  top: 20px;
+}
+
+.djs-palette:not(.open) {
+  overflow: hidden;
+}
+
+.djs-palette .entry,
+.djs-palette .djs-palette-toggle {
+  width: 46px;
+  height: 246px;
+  /* line-height: 46px; */
+}
+
+.djs-palette .separator {
+  margin: 3px 5px 5px 5px;
+  border: solid 1px #DDD;
+  border-radius: 1px;
+};
+
+.djs-palette .entry:before {
+  vertical-align: middle;
+}
+
+.djs-palette .djs-palette-toggle {
+  cursor: pointer;
+}
+
+.djs-palette .entry,
+.djs-palette .djs-palette-toggle {
+  color: #333;
+  font-size: 30px;
+
+  text-align: center;
+}
+
+.djs-palette.open .djs-palette-toggle {
+  height: 10px;
+}
+
+.djs-palette:not(.open) .djs-palette-entries {
+  display: none;
+}
+
+.djs-palette .djs-palette-toggle:hover {
+  /*background: #666;*/
+}
+
+.djs-palette .entry:hover {
+  color: rgb(255, 116, 0);
+}
+
+/**
+ * context-pad
+ */
+.djs-overlay-context-pad {
+  width: 72px;
+}
+
+.djs-context-pad {
+  position: absolute;
+  display: none;
+  pointer-events: none;
+}
+
+.djs-context-pad .entry {
+  width: 22px;
+  height: 22px;
+  text-align: center;
+  display: inline-block;
+  font-size: 22px;
+  margin: 0 2px 2px 0;
+
+  border-radius: 3px;
+
+  cursor: default;
+
+  background-color: rgba(255,255,255, 0.85);
+  box-shadow: 0 0 2px 1px rgba(255,255,255, 0.85);
+
+  pointer-events: all;
+}
+
+.djs-context-pad .entry:before {
+  vertical-align: top;
+}
+
+.djs-context-pad .entry:hover {
+  background: rgb(255, 252, 176);
+}
+
+.djs-context-pad.open {
+  display: block;
+}
+
+.djs-popup-entry {
+  font-size: 20px;
+  line-height: 20px;
+  padding: 2px 10px 2px 5px;
+  background-color: rgba(255,255,255, 0.85);
+  white-space: nowrap;
+}
+
+.djs-popup-entry:hover {
+  background: rgb(255, 252, 176);
+}
+
+.djs-popup-entry > span {
+  font-size: 14px;
+  margin-left: 5px;
+
+  vertical-align: middle;
+}
+
+.djs-popup-entry:before {
+  vertical-align: middle;
+}
+
+/**
+ * popup / palette styles
+ */
+.djs-popup, .djs-palette {
+  background: #FAFAFA;
+  border: solid 1px #CCC;
+  border-radius: 2px;
+  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
+}
+
+/**
+ * touch
+ */
+
+.djs-shape,
+.djs-connection {
+  touch-action: none;
+}
+
+.djs-bendpoint {
+  display: none;
+}
+
+/**
+ * bendpoints
+ */
+.djs-bendpoint .djs-visual {
+  pointer-events: none;
+  fill: rgba(255, 255, 121, 0.8);
+  stroke-width: 1px;
+  stroke-opacity: 0.5;
+  stroke: black;
+}
+
+.djs-bendpoint:hover,
+.djs-bendpoints.hover .djs-bendpoint,
+.djs-bendpoints.selected .djs-bendpoint {
+  display: block;
+}
+
+.djs-bendpoints:not(.hover) .floating {
+  display: none;
+}
+
+.djs-bendpoint:hover .djs-visual,
+.djs-bendpoint.floating .djs-visual {
+  fill: yellow;
+}
+
+.djs-bendpoint.floating .djs-hit {
+  pointer-events: none;
+}
+
+.djs-bendpoint .djs-hit {
+  pointer-events: all;
+  fill: none;
+}
+
+.djs-updating,
+.djs-updating > * {
+  pointer-events: none !important;
+}
+
+.djs-updating .djs-context-pad,
+.djs-updating .djs-outline,
+.djs-updating .djs-bendpoint,
+.connect-ok .djs-bendpoint,
+.connect-not-ok .djs-bendpoint,
+.drop-ok .djs-bendpoint,
+.drop-not-ok .djs-bendpoint {
+  display: none !important;
+}
+.djs-outline-no-property-saved {
+       stroke:red;
+       stroke-width:5;
+}
+.djs-bendpoint.djs-dragging {
+  display: block;
+  opacity: 1.0;
+}
+
+.djs-bendpoint.djs-dragging .djs-visual {
+  fill: yellow;
+}
+
+
+/**
+ * tooltips
+ */
+.djs-tooltip-error {
+  font-size: 11px;
+  line-height: 18px;
+  text-align: left;
+
+  padding: 5px;
+
+  opacity: 0.7;
+}
+
+.djs-tooltip-error > * {
+  width: 160px;
+
+  background: rgb(252, 236, 240);
+  color: rgb(158, 76, 76);
+  padding: 3px 7px;
+  box-shadow: 0 1px 3px rgba(0,0,0, 0.2);
+  border-radius: 5px;
+  border-left: solid 5px rgb(174, 73, 73);
+}
+
+.djs-tooltip-error:hover {
+  opacity: 1;
+}
diff --git a/src/main/resources/META-INF/resources/designer/modeler/dist/index.html b/src/main/resources/META-INF/resources/designer/modeler/dist/index.html
new file mode 100644 (file)
index 0000000..80e5cda
--- /dev/null
@@ -0,0 +1,76 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<html>
+<head>
+    <title>bpmn-js modeler demo</title>
+    <link rel="stylesheet" href="css/diagram-js.css"/>
+    <link rel="stylesheet" href="vendor/bpmn-font/css/bpmn-embedded.css"/>
+    <link rel="stylesheet" href="css/app.css"/>
+    <script type="text/javascript" src="./scripts/app.js"></script>
+</head>
+<body>
+
+<button id="uploadmodel" style="display:none"></button>
+<button id="openmodel" style="display:none"></button>
+<div class="content" id="js-drop-zone" id="div_content" ng-app="clds-app" ng-controller="MenuCtrl">
+    <div class="message error">
+        <div class="note">
+            <p>Ooops, we could not display the Closed Loop Model.</p>
+            <div class="details">
+                <span>cause of the problem</span>
+                <pre></pre>
+            </div>
+        </div>
+    </div>
+
+    <div class="canvas" id="js-canvas"></div>
+</div>
+
+<ul class="buttons">
+    <li>
+        <a id="js-download-diagram" href title="download BPMN diagram">
+            UTM diagram
+        </a>
+    </li>
+    <li>
+        <a id="js-download-svg" href title="download as SVG image">
+            SVG image
+        </a>
+    </li>
+    <li>
+        <div>
+            Import Diagram:
+            <input type="file" id="fileInput">
+        </div>
+    </li>
+    <li>
+        <div>
+            <a id="file_generate_test_case" href title="Generate Test Case">
+                Generate Test Cases
+            </a>
+        </div>
+</ul>
+</body>
+<script src="index.js"></script>
+</html>
diff --git a/src/main/resources/META-INF/resources/designer/modeler/package.json b/src/main/resources/META-INF/resources/designer/modeler/package.json
new file mode 100644 (file)
index 0000000..b835ab9
--- /dev/null
@@ -0,0 +1,40 @@
+{
+  "name": "bpmn-js-example-modeler",
+  "version": "0.0.0",
+  "description": "A simple modeler built with bpmn-js",
+  "main": "app/index.js",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/bpmn-io/bpmn-js-examples"
+  },
+  "keywords": [
+    "bpmnjs-example"
+  ],
+  "author": {
+    "name": "Nico Rehwaldt",
+    "url": "https://github.com/nikku"
+  },
+  "contributors": [
+    {
+      "name": "bpmn.io contributors",
+      "url": "https://github.com/bpmn-io"
+    }
+  ],
+  "license": "MIT",
+  "devDependencies": {
+    "brfs": "^1.2.0",
+    "grunt": "~0.4.4",
+    "grunt-browserify": "^3.3.0",
+    "grunt-contrib-watch": "~0.5.0",
+    "grunt-contrib-connect": "~0.6.0",
+    "grunt-contrib-jshint": "~0.7.2",
+    "grunt-contrib-copy": "~0.5.0",
+    "load-grunt-tasks": "~0.3.0"
+  },
+  "dependencies": {
+    "bpmn-js": "^0.10.0",
+    "diagram-js": "^0.10.0",
+    "jquery": "^2.1.1",
+    "lodash": "^3.0.0"
+  }
+}
diff --git a/src/main/resources/META-INF/resources/designer/page_under_construction.html b/src/main/resources/META-INF/resources/designer/page_under_construction.html
new file mode 100644 (file)
index 0000000..338ef6f
--- /dev/null
@@ -0,0 +1,42 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+     <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+      
+     <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+      <p dir="ltr">&nbsp;</p>
+    <div class="container-fluid">
+      <div  class="row" > <!-- start content -->
+        <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12  ">
+           <div ><img style ="display: block;margin-left: auto;margin-right: auto"src="images/page_under_construction.png" border="0"  title="" /></div> 
+                 
+        </div>
+      </div>
+    </div>
+       
+       
diff --git a/src/main/resources/META-INF/resources/designer/partials/default-include.html b/src/main/resources/META-INF/resources/designer/partials/default-include.html
new file mode 100644 (file)
index 0000000..146c283
--- /dev/null
@@ -0,0 +1,106 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="defaltinclude" id="defaultPage" class ="container-fluid"  ng-controller="MenuCtrl">
+<div attribute-test="defaltincludeh" id="navbar" class="navbar-collapse collapse ">    
+        <ul attribute-test="defaltincludeh" class="nav navbar-nav">
+        <li class="active dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Project <!-- <span class="caret"></span> --></a>           
+           <ul class="dropdown-menu">
+             <li><a href="#" ng-click="createNewProject()">Create New Project</a></li>
+             <li><a href="#">Open Existing Project</a></li>
+             <li><a href="#">Save Project</a></li>
+             <li><a href="#">Save as Project</a></li>
+             <li><a href="#">Import Schema</a></li>
+             <li><a href="#">Define/Modify Schema</a></li>
+          </ul>
+        </li>
+       <li class="active dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Model <!-- <span class="caret"></span> --></a>   
+             <ul class="dropdown-menu">
+             <li><a href="#">Activity Palette</a></li>
+             <li><a href="#">Define Action/Condition</a></li>
+             <li><a href="#">Map Requirement</a></li>
+             <li><a href="#">Map TestCase Name</a></li>
+             <li><a href="#">Map TestCase Description</a></li>
+             <li><a href="#">Map Expected Result</a></li>
+          </ul>            
+       </li>  
+         <li class="active dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Test Set <!-- <span class="caret"></span> --></a>   
+             <ul class="dropdown-menu">
+             <li><a href="#">Generate Test Cases</a></li>
+             <li><a href="#">Review/Validate Test Cases</a></li>
+             <li><a href="#">Export Test cases</a></li>            
+          </ul>            
+       </li>  
+             
+        <li class="active dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">View<!-- <span class="caret"></span> --></a>   
+             <ul class="dropdown-menu">
+             <li><a href="#">Project Explorer</a></li>
+             <li><a href="#">Palette</a></li>
+             <li><a href="#">Canvas</a></li>
+             <li><a href="#">Properties</a></li>             
+          </ul>            
+       </li>  
+             
+         <li class="active dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Help <!-- <span class="caret"></span> --></a>  
+              <ul class="dropdown-menu">
+             <li><a href="http://wiki.onap.org/CLAMP-PLACEHOLDER-TO-BE-REPLACED" target="_blank">Wiki</a></li>
+             <li><a href="#" ng-click="contactUs()">Contact Us</a></li>
+             </ul>
+         </li>
+      </ul>
+                                      
+     </div>
+       <div>
+               <table style="width: 95%; margin-left: 24px">
+                       <tbody>
+                               <tr>
+                                       <th>Project Explorer</th>
+                                       <th>Modelling - Canvas</th>
+                                       <th>Modelling - Properties</th>
+                               </tr>
+                               <tr>
+                                       <td>
+                                               <div style="height: 700px"></div>
+                                       </td>
+                                       <td>
+                                               <div style="height: 700px"></div>
+                                       </td>
+                                       <td>
+                                               <div style="height: 700px"></div>
+                                       </td>
+                               </tr>
+
+
+                       </tbody>
+               </table>
+
+       </div>
+
+
+
+
+
+       <!-- <div ng-view=""></div> -->
+
+</div>                 
diff --git a/src/main/resources/META-INF/resources/designer/partials/grid.html b/src/main/resources/META-INF/resources/designer/partials/grid.html
new file mode 100644 (file)
index 0000000..93afa08
--- /dev/null
@@ -0,0 +1,35 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+  
+    
+    
+    
+   
+   
+<div attribute-test="grid" class="container-fluid">
+   <div attribute-test="grid" class="row-fluid">
+               <div class="col-lg-12">
+                       <div ui-grid="gridOptions" ui-grid-cellNav  ui-grid-pinning ui-grid-selection ui-grid-paging ui-grid-resize-columns class="grid"></div>
+               </div>
+    </div>    
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/partials/invalid_login.html b/src/main/resources/META-INF/resources/designer/partials/invalid_login.html
new file mode 100644 (file)
index 0000000..7c279c0
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<div attribute-test="invalidlogin" class="warning">
+       <h2>CSP Authentication not available for {{host}}.</h2>
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/partials/menu.html b/src/main/resources/META-INF/resources/designer/partials/menu.html
new file mode 100644 (file)
index 0000000..dd4dae4
--- /dev/null
@@ -0,0 +1,190 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.navbar-custom {
+       background-color: #229922;
+       color: #ffffff;
+       border-radius: 0;
+}
+
+.red {
+       color: red;
+}
+
+.logo {
+       font-family: 'Trebuchet MS', cursive;
+       font-size: 20px;
+       font-weight: 500;
+       text-align: center;
+}
+
+.logo_name {
+       display: block;
+       float: left;
+       font-family: 'Trebuchet MS', cursive;
+       font-size: 15px;
+       font-weight: 500;
+       height: 50px;
+       text-align: center;
+}
+
+.ThisLink {
+       pointer-events: none;
+       cursor: default;
+       disabled: true;
+       /*   background-color:#e7e7e7; */
+       color: #A09B9B !important;
+}
+
+.ThisLink a.blur:hover,.ThisLink a.blur:focus {
+       color: #933;
+}
+
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+</style>
+
+<nav attribute-test="menu" class="navbar navbar-default navbar-fixed-top" role="navigation"
+       style="margin-left: 2px; margin-right: 2px;">
+
+       <div attribute-test="menuc" class="container-fluid">
+
+               <div class="col-md-4 col-lg-4">
+                       <img class="onap_logo" src="images/logo_onap_2017.png" height="50px"
+                               width="234px" style="display: inline-block; float: left">
+                       <div class="navbar-brand logo" ng-href=""
+                               style="display: inline-block; float: left">
+                               &nbsp;&nbsp;<b>Closed Loop Definition</b>
+                       </div>
+               </div>
+
+
+               <div style="float: right; padding-right: 50px;"
+                       class="col-md-2 navbar-header navbar-primary navbar-fixed-right hidden-sm hidden-md hidden-lg">
+                       <button type="button" class="navbar-toggle collapsed"
+                               data-toggle="collapse" data-target="#navbar" aria-expanded="false"
+                               aria-controls="navbar">
+                               <span class="icon-bar"></span> <span class="icon-bar"></span> <span
+                                       class="icon-bar"></span>
+                       </button>
+                       <a class="navbar-brand" ng-href=""></a>
+               </div>
+
+               <div id="navbar" class="navbar-collapse collapse col-md-10 col-lg-10">
+                       <ul class="nav navbar-nav">
+
+                               <li class="dropdown" ng-repeat="dropDownName in keyList"
+                                       style="height: inherit"><a active-link="active"
+                                       class="dropdown-toggle dropdownTitle" role="button"
+                                       data-toggle="dropdown"
+                                       style="height: inherit; font-weight: bold; color: #000">{{dropDownName}}
+                                               <span class="caret"></span>
+                               </a>
+                                       <ul class="dropdown-menu" role="menu">
+                                               
+                                               <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name==='Create CL'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-click="emptyMenuClick(section.link,section.name)">{{section.name}}</a>
+                                               </li>
+                                               
+                                               <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name==='Open CL'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-click="emptyMenuClick(section.link,section.name)">{{section.name}}</a>
+                                               </li>
+                                               
+                                               <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name==='Create Template'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-click="emptyMenuClick(section.link,section.name)">{{section.name}}</a>
+                                               </li>
+                                               
+                                               <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name==='Open Template'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-click="emptyMenuClick(section.link,section.name)">{{section.name}}</a>
+                                               </li>
+                                                                                       
+                                               <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name != 'Create CL' && section.name != 'Create Template' && section.name != 'Open CL' && section.name != 'Open Template' && section.name != 'ONAP User Guide - Design Overview' && section.name != 'ONAP User Guide - Closed Loop Design' && section.name != 'ONAP User Guide - CLAMP'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-click="emptyMenuClick(section.link,section.name)"
+                                                       class="ThisLink">{{section.name}}</a>
+                                          </li>
+                                          
+                                          <li ng-repeat="section in tabs[dropDownName]"
+                                                       ng-if="section.name == 'ONAP User Guide - Design Overview' || section.name == 'ONAP User Guide - Closed Loop Design' || section.name == 'ONAP User Guide - CLAMP'"><a
+                                                       id="{{section.name}}" role="presentation"
+                                                       ng-href="{{section.link}}"
+                                                       target="_blank"
+                                                       >{{section.name}}</a>
+                                          </li>
+
+                                       </ul></li>
+
+                       </ul>
+
+               </div>
+
+
+
+               <div attribute-test="menuid" id="navbar" class="navbar-collapse collapse pull-right">
+                       <ul class="nav navbar-nav">
+                               <li class="dropdown" style="height: inherit"><a
+                                       class="navbar-brand logo_name" active-link="active"
+                                       class="dropdown-toggle dropdownTitle" role="button"
+                                       data-toggle="dropdown" style="height: inherit;">Hello:
+                                               {{loginuser}} </a></li>
+                       </ul>
+               </div>
+
+       </div>
+</nav>
diff --git a/src/main/resources/META-INF/resources/designer/partials/ng-grid.html b/src/main/resources/META-INF/resources/designer/partials/ng-grid.html
new file mode 100644 (file)
index 0000000..385c4c4
--- /dev/null
@@ -0,0 +1,25 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<table attribute-test="ng-grid" class="flexme4" style="display: none"></table>
diff --git a/src/main/resources/META-INF/resources/designer/partials/please_wait.html b/src/main/resources/META-INF/resources/designer/partials/please_wait.html
new file mode 100644 (file)
index 0000000..8068e4c
--- /dev/null
@@ -0,0 +1,28 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<div attribute-test="pleasewait">
+       <h1>Please Wait.....{{urlparam}}</h1>
+
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/Collector_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/Collector_properties.html
new file mode 100644 (file)
index 0000000..7537f72
--- /dev/null
@@ -0,0 +1,122 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+    .fileUpload {
+        position: relative;
+        overflow: hidden;
+        margin: 10px;
+    }
+    .fileUpload input.upload {
+        position: absolute;
+        top: 0;
+        right: 0;
+        margin: 0;
+        padding: 0;
+        font-size: 20px;
+        cursor: pointer;
+        opacity: 0;
+        filter: alpha(opacity=0);
+        float:left;
+    }
+    .fileDisplay {
+
+        display: inline-block;
+        overflow: hidden;
+        float: right;
+        margin-left: 0px;
+        z-index: initial;
+        text-align: center;
+        margin-top: 17px;
+    }
+
+
+</style>
+
+
+<div attribute-test="collectorproperties" id="configure-widgets"  >
+    <div attribute-test="cldsopentemplateh" class="modal-header">
+        <button type="button" class="close" ng-click="close(false)" aria-hidden="true" style="margin-top: -3px">&times;</button>
+        <h4>Collector</h4>
+    </div>
+    <div attribute-test="cldsopentemplateb" class="modal-body" style="height: 280px">
+        <div style="height: 10px">
+        </div>
+        <form id="saveProps" class="form-horizontal">
+
+            <div>
+                <div class="form-group">
+                    <label for="schemaLocation" class="col-sm-4 control-label">Topic Publishes</label>
+
+                    <div class="col-sm-8">
+                        <select class="form-control" focus="true" name="topicPublishes"  id="topicPublishes">
+                            <!--  <option value="volvo">volvo</option>
+                            <option value="saab">saab</option>
+                            <option value="opel">opel</option> -->
+                        </select>
+                    </div>
+                </div>
+                
+                
+            </div>
+
+        </form>
+
+    </div>
+    <div class="modal-footer">
+        <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+        <button  id="savePropsBtn" class="btn btn-primary">Close</button>
+        <button ng-click="close(true)" id="close_button" class="btn btn-primary">Cancel</button>
+
+    </div>
+    <script>
+    loadPropertyWindow("collector");
+    var el=elementMap[lastElementSelected];
+    if(el!==undefined){
+        for(var i=0;i<el.length;i++){
+            
+            $("#"+el[i].name).val(el[i].value);
+        }
+
+
+    }
+    $("#saveProps").on('submit', function (event) {
+        console.log("clicksaveprop");
+        //alert("lol");
+        //console.log($(this).serializeArray()[0].name);
+        saveProperties($(this).serializeArray())
+        event.preventDefault();
+
+        $("#close_button").click();
+
+    })
+    $("#savePropsBtn").click(function (event) {
+        console.log("savepropbtn");
+        //alert($("#CProp_Target").val())
+        //alert(las)
+        $("#saveProps").submit();
+    })
+</script>
+</div>
+
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/ConfirmRevertChanges.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/ConfirmRevertChanges.html
new file mode 100644 (file)
index 0000000..7c5d837
--- /dev/null
@@ -0,0 +1,47 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="confirmrevertchanges" id="configure-widgets">
+       <div attribute-test="confirmrevertchangesh" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Create Model</h4>
+       </div>
+       <div attribute-test="confirmrevertchangesh" class="modal-body" style="height: 150px">
+               <div style="height: 30px"></div>
+
+                       
+                               <label for="modelName" class="col-sm-3 control-label">Revert Changes for Model:</label>
+                               <span ng-bind="utmModels.name"></span>
+                               
+                                       <input type="hidden" class="form-control" id="modelName" name="modelName" ng-value="utmModels.name">
+                       
+               
+       </div>
+       <div class="modal-footer">
+
+               <button ng-click="revertChanges()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern || nameinUse" class="btn btn-primary">Revert</button>
+               <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+       </div>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html
new file mode 100644 (file)
index 0000000..7adeb1b
--- /dev/null
@@ -0,0 +1,749 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+#deletePolicy{
+       height:34px;
+       background-color:#dddd;
+}
+
+.disabled{
+       background-color: #dddd;
+}
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+
+.form-group {
+/*     height:24px; */
+/*     box-sizing:border-box; */
+       margin-bottom:20px;
+}
+
+.glyphicon-search{
+       position:absolute; 
+       padding: 25px 12px;
+}
+
+label{
+       text-align:right;
+       vertical-align:middle;
+}
+
+.leftPolicyPanel{
+       padding: 0 10px 0 0;
+}
+
+#createNewPolicy{
+       height:34px;
+       width:120px; /*84*/
+       background-color:#f2bfab;
+}
+
+#pname{
+       height:28px; 
+       margin-left:-5px;
+}
+
+.policyPanel{
+       background-color: #f5f5f5;
+       padding: 10px 5px;
+}
+
+#policySearch{
+       height: 33px;
+       font-size: 12px;
+       padding: 2px 2px 2px 30px;
+       margin-bottom: 5px;
+       width:100%;
+}
+#policyTable{
+       cursor: pointer;
+       width:100%;
+}
+
+#policyTable tr{
+       border-bottom: 1px solid #ddd;
+       border-collapse: collapse;
+       text-align: left;
+       font-size: 12px;
+       font-weight: normal;
+}
+
+#policyTable td{
+       padding: 8px 10px;
+}
+
+#policyTable tr.highlight{
+       background-color: #f5f5f5;
+       font-weight: bold;
+       font-size: 13px;
+}
+
+#policyTableHolder{
+       height:200px; 
+       width: 100%; 
+       overflow:auto;
+}
+
+#timeout{
+       height:28px; 
+       margin-left:10px;
+}
+
+</style>
+
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+               var selectLength = document.querySelectorAll(".disabled-block-container .tab-close-popup");
+               if(selectLength && selectLength.length>0){
+                       for(var i = 0; i< selectLength.length ; i++){
+                               selectLength[i].disabled = true;
+                       }       
+               }
+
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+</script>
+
+
+       <div attribute-test="policywindowproperties" id="configure-widgets" 
+               class="disabled-block-container">
+       <div attribute-test="policywindowpropertiesh" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Operational Policy</h4>
+       </div>  
+       
+       
+       <div class="container">
+       <div attribute-test="policywindowpropertiesb" class="modal-body row">
+               
+               <div class="leftPolicyPanel">
+                       <div class="panel panel-default">
+                               <i class="glyphicon glyphicon-search"></i>
+                               <input type="text" id="policySearch" onkeyup="searchPolicyList()"
+                                       placeholder="Search ...">
+                               <div id="policyTableHolder">
+                                       <table id="policyTable"></table>
+                               </div>
+                       </div>
+                       <div style="float:left">
+                               <button type="button" id="createNewPolicy" class="btn btn-sm">New Policy</button></span>
+                       </div>
+                       <div style="float:right">
+                               <button type="button" id="deletePolicy" class="btn btn-sm glyphicon glyphicon-trash" disabled></button></span>
+                       </div>
+               </div>
+               
+               <div class="panel panel-default col-sm-9 policyPanel" style="display:none;">
+                       <form id="Timeoutform" class="form-horizontal">
+                               <div>
+                                       <div class="form-group clearfix row">
+                                               <label style="margin-top:5px;" class="col-sm-2">Name</label>
+                                               <input type="text" id="pname"; name="pname"; class="col-sm-4"></span>
+                                               
+                                               <label for="userID" class="col-sm-3" style="margin-top:5px; padding:0px;">Overall Time Limit</label>
+                                               <input type="text" class="col-sm-2" id="timeout" name="timeout">
+                                       </div>
+                               </div>
+                       </form>
+                       <div class="panel-heading" style="background-color: white;">
+                               <ul id="nav_Tabs" class="nav nav-tabs">
+                                       <li class><a id="add_one_more" href="#desc_tab"><span
+                                                       class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
+                               </ul>
+                       </div>
+                       <div class="panel-body">
+                               <div class="tab-content">
+                                       <div id="properties_tab" class="tab-pane fade in active"></div>
+                               </div>
+                       </div>
+               </div>
+               
+               <span id="formSpan" style="display: none">
+                       <form class="saveProps" class="form-horizontal">
+                               <div>
+                                       <div class="form-group clearfix" >
+                                               <label for="recipe" class="col-sm-4 control-label" >Recipe</label>
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" name="recipe" id="recipe" enableFilter="false"></select>
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="maxRetries" class="col-sm-4 control-label">
+                                                       Max Retries</label>
+                                               <div class="col-sm-8">
+                                                       <input type="number" min="0" class="form-control" id="maxRetries"
+                                                               name="maxRetries"> </input>
+                                               </div>
+                                       </div>
+                                       <br />
+                                       <div class="form-group clearfix" >
+                                               <label for="retryTimeLimit" class="col-sm-4 control-label" >
+                                                       Retry Time Limit</label>
+                                               <div class="col-sm-8">
+                                                       <input type="number" min="0" class="form-control" id="retryTimeLimit"
+                                                               name="retryTimeLimit"></input>
+                                               </div>
+                                       </div>
+                                       <div hidden class="form-group clearfix">
+                                               <label for="_id" class="col-sm-4 control-label">
+                                                       PolicyID</label>
+                                               <div class="col-sm-8">
+                                                       <input type="text" onkeydown="return false;"  class="form-control" id="_id"
+                                                               name="_id" value=""></input>
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="parentPolicy" class="col-sm-4 control-label">
+                                                       Parent Policy</label>
+                                               <div class="col-sm-8">
+                                                       <select  class="form-control" id="parentPolicy"
+                                                               name="parentPolicy" enableFilter="false"><option value=""></option></select>
+                                               </div>
+                                       </div>                  
+                                       <div class="form-group clearfix">
+                                               <label for="parentPolicyConditions" class="col-sm-4 control-label">
+                                                       Parent Policy Conditions</label>
+                                               <div class="col-sm-8">
+                                                       <select  class="form-control" id="parentPolicyConditions"
+                                                               name="parentPolicyConditions" multiple size=2></select>
+                                               </div>
+                                       </div>
+                               </div>
+                       </form>
+               </span>
+       </div>
+       </div>
+
+       <div attribute-test="policywindowpropertiesf" class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button id="savePropsBtn" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+       </div>
+       
+       <script>
+               //Basically this method will add a new form. All forms share the same class. When you want one form to show(active form) the other forms get the 
+               // css attribute display:none
+               $("#add_one_more").click(function(event) {
+                       event.preventDefault();
+                       add_one_more();
+                       setMultiSelect();
+               });
+               loadPropertyWindow("policy")
+               
+               // by default, parentPolicyConditions is disabled
+               $("#parentPolicyConditions").prop('disabled', 'disabled');
+               var parent_policy={}
+               var policy_ids={}
+               var loadingId=false;
+               var allPolicies={};
+               
+               //Grab saved values for dropdowns
+               var obj = elementMap[lastElementSelected];
+               
+               if (!($.isEmptyObject(obj))){
+                       allPolicies = jQuery.extend({}, obj);                   
+                       for (var x in allPolicies){
+                               $("#policyTable").prepend("<tr id='"+x+"'><td>"+x+"</td></tr>");
+                       }
+               }
+               
+               //load recipes for a chosen policy
+               function disperseConfig(policyObj, id){
+                       //remove old gui forms
+                       for (var i=1; i<($(".formId").length + 1); i++){
+                               $("#go_properties_tab"+i).parent().remove();
+                       }
+                       $(".formId").remove();
+                       
+                       if (policyObj !== undefined) {
+                               var el = policyObj[id][2]['policyConfigurations']
+                               for (var i = 0; i < el.length; i++) {
+                                       loadingId=true;
+                                       var num = add_one_more();
+                                       loadingId=false;
+                                       for (var j = 0; j < el[i].length; j++) {
+                                               if(el[i][j].hasOwnProperty("name")){
+                                                       $("#formId" + num + " #" + el[i][j].name).val(
+                                                                       el[i][j].value);
+                                                       if(el[i][j].name==="_id")
+                                                               policy_ids["#formId" + num]=el[i][j].value
+                                                       if(el[i][j].name==='parentPolicy')
+                                                               parent_policy[num]=el[i][j].value 
+                                                       if(el[i][j].name==='recipe' && el[i][j].value.toString()!==''){
+                                                               $("#go_properties_tab"+num).text(el[i][j].value)
+                                                       }       
+                                               }
+                                       }
+                               }
+                               
+                               //Adding all the ids for parent policy options
+                               for(var i=1;i<=$(".formId").length;i++){
+                                       for(k in policy_ids){
+                                               if($("#formId"+i+" #_id").val()!==policy_ids[k].toString()  && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
+                                                       $("#formId"+i+" #parentPolicy").append("<option value=\""+policy_ids[k]+"\">" +$(k+" #recipe").val()+"</option>");
+                                               }
+                                       }
+                               }
+                               
+                               for(k in parent_policy){
+                                       $("#formId"+k+" #parentPolicy").val(parent_policy[k]);
+                                       // force the change event
+                                       $("#formId"+k+" #parentPolicy").change();
+                               }
+                               
+                               if(policyObj[id][0] && policyObj[id][1]){
+                                       $("#" + policyObj[id][0].name).val(policyObj[id][0].value);
+                                       $("#" + policyObj[id][1].name).val(policyObj[id][1].value);
+                               }
+                       }
+                       
+                       setMultiSelect();
+               }
+               
+               
+               //This is ensure there are no repeated keys in the map
+               function noRepeats(form) {
+                       //triggered per policy.
+                       var select = {};
+                       for (var i = 0; i < form.length; i++) {
+                               if (select[form[i].name] === undefined)
+                                       select[form[i].name] = []
+                               select[form[i].name].push(form[i].value);
+                       }
+                       var arr = []
+                       for (s in select) {
+                               var f = {}
+                               f.name = s
+                               f.value = select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+               
+               $("#savePropsBtn").click(function(event) {
+
+                       //Saves edits
+                       if ($("#policyTable .highlight").length > 0){
+                               saveLastPolicyLocally($("#policyTable .highlight").attr("id"));
+                       }
+                       
+                       //Removes outdated (deleted) policies by checking against left menu
+                       var finalSaveList = {};
+                       $("#policyTable td").each(function(){
+                               var tableVal = $(this).text();
+                               if (tableVal in allPolicies){
+                                       finalSaveList[tableVal] = allPolicies[tableVal];
+                               }
+                       });
+                       
+                       saveProperties(finalSaveList);
+                       $("#close_button").click();
+               })              
+
+               function add_one_more() {
+                       $("#nav_Tabs li").removeClass("active");
+                       
+                       //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
+                       var form = $($("#formSpan").children()[0]).clone()
+                       var count = 0;
+                       //Each new tab will have the formId class attached to it. This way we can track how many forms we currently have out there and assign listeners to them
+                       if ($(".formId").length > 0) {
+                               var greatest = 0;
+                               var s = $(".formId");
+                               for (var i = 0; i < s.length; i++) {
+                                       if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
+                                               greatest = parseInt($(s[i]).attr("id").substring(6))
+                                       }
+                               }
+                               count = greatest + 1;
+                               $("#properties_tab").append(
+                                               ('<span class="formId" id="formId'+count+'"></span>'));
+                       } else {
+                               count++;
+                               $("#properties_tab").append(
+                                               '<span class="formId" id="formId1"></span>');
+                       }
+                       
+                       //$(form).find("#policyName").val("Recipe "+makid(2))
+                       //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
+                       //alert($(form).find("#_id").val())
+                       //policyNameChangeListener(form)
+                       $("#add_one_more")
+                                       .parent()
+                                       .before(
+                                                       ' <li class="active"><a id="go_properties_tab'+count+'">Policy</a><button id="tab_close'+count+'" type="button" class="close tab-close-popup" aria-hidden="true" style="margin-top: -30px;margin-right: 5px">&times;</button></li>');
+                       $("#formId" + count).append(form);
+                       $(".formId").not($("#formId" + count)).css("display", "none")
+                       addCustListen(count)
+                       addTabListen(count)
+                       // This is for when the process is not loading from map but being created
+                       if(!loadingId){
+                               var l=makeid()
+                               $(form).find("#_id").val(l)
+                               policy_ids["#formId" + count]=l
+                               var answers={}
+                               
+                               for(var i=1;i<=greatestIdNum();i++){
+                                       if($("#formId"+i).length>0){
+
+                                               answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val()
+                                               $("#formId"+i+" #parentPolicy").empty();
+                                               for(k in policy_ids){
+                                                       if($("#formId"+i+" #_id").val().toString()!==policy_ids[k] && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
+                                                               $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"''> "+$(k+" #recipe").val()+"</option>")
+                                                       }
+                                               }
+                                               $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
+                                       }
+                               }
+                               for(k in answers){
+                                       $(k).val(answers[k])
+                               }
+                       }
+                       return count;
+               }
+               
+               function add_new_policy(issueNewNames) {        
+                       //remove old gui forms
+                       for (var i=1; i<($(".formId").length + 1); i++){
+                               $("#go_properties_tab"+i).parent().remove();
+                       }
+                       $(".formId").remove();
+                       
+                       //Reset header
+                       var ms = new Date().getTime();
+                       var defPolName = "Policy" + ms;
+                       $("#pname").val(defPolName);
+                       $("#timeout").val(defaults_props.policy.timeout);
+                       
+                       //FormSpan contains a block of the form that is not being displayed. We will create clones of that and add them to tabs
+                       var form = $($("#formSpan").children()[0]).clone()
+                       var count = 0;
+                       //Each new tab will have the formId class attached to it. This way we can track how many forms we currently have out there and assign listeners to them
+                       if ($(".formId").length > 0) {
+                               var greatest = 0;
+                               var s = $(".formId");
+                               //for every recipe
+                               for (var i = 0; i < s.length; i++) {
+                                       if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
+                                               greatest = parseInt($(s[i]).attr("id").substring(6))
+                                       }
+                               }
+                               count = greatest + 1;
+                               $("#properties_tab").append(
+                                               ('<span class="formId" id="formId'+count+'"></span>'));
+                       } else {
+                               count++;
+                               $("#properties_tab").append(
+                                               '<span class="formId" id="formId1"></span>');
+                       }
+                       
+                       //$(form).find("#policyName").val("Recipe "+makid(2))
+                       //TODO change up how we auto assign policyName. There could be the case where we do this and it will have repeats
+                       //alert($(form).find("#_id").val())
+                       //policyNameChangeListener(form)
+                       $("#add_one_more")
+                                       .parent()
+                                       .before(
+                                                       ' <li class="active"><a id="go_properties_tab'+count+'">Policy</a><button id="tab_close'+count+'" type="button" class="close tab-close-popup" aria-hidden="true" style="margin-top: -30px;margin-right: 5px">&times;</button></li>');
+                       $("#formId" + count).append(form);
+                       $(".formId").not($("#formId" + count)).css("display", "none")
+                       addCustListen(count)
+                       addTabListen(count)
+                       // This is for when the process is not loading from map but being created
+                       if(!loadingId){
+                               var l=makeid()
+                               $(form).find("#_id").val(l)
+                               policy_ids["#formId" + count]=l
+                               var answers={}
+                               
+                               for(var i=1;i<=greatestIdNum();i++){
+                                       if($("#formId"+i).length>0){
+
+                                               answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val()
+                                               $("#formId"+i+" #parentPolicy").empty();
+                                               for(k in policy_ids){
+                                                       if($("#formId"+i+" #_id").val().toString()!==policy_ids[k] && $(k+" #recipe").val()!==undefined && $(k+" #recipe").val()!==""){
+                                                               $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"''> "+$(k+" #recipe").val()+"</option>")
+                                                       }
+                                               }
+                                               $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
+                                       }
+                               }
+                               for(k in answers){
+                                       $(k).val(answers[k])
+                               }
+                       }
+                       
+                       
+                       
+                       setMultiSelect();
+                       return defPolName;
+               }
+               
+       
+               //listener will change the tab name to the recipe
+               function addTabListen(count){
+                       $("#formId"+count+" #recipe").on("change",function(){
+                               if($("#formId"+count+" #recipe").val().toString()!==""){
+                                       $('#go_properties_tab' + count).text($("#formId"+count+" #recipe").val())
+                               }
+                               else
+                                       $('#go_properties_tab' + count).text("Policy");
+                               
+                               var answers={}
+                               
+                               for(var i=1;i<=greatestIdNum();i++){
+                                       if($("#formId"+i).length>0){
+                                               
+                                               answers["#formId"+i+" #parentPolicy"]=$("#formId"+i+" #parentPolicy").val()
+                                               $("#formId"+i+" #parentPolicy").empty();
+                                               
+                                               for(k in policy_ids){
+                                                       if($("#formId"+i+" #_id").val().toString()!==policy_ids[k] && $(k+" #recipe").val()!=='undefined' && $(k+" #recipe").val()!==""){
+                                                               $("#formId"+i+" #parentPolicy").append("<option value='"+policy_ids[k]+"''> "+$(k+" #recipe").val()+"</option>")
+                                                       }
+                                               }
+                                               $("#formId"+i+" #parentPolicy").prepend("<option value=''></option>")
+                                       }
+                               }
+                               for(k in answers){
+                                       $(k).val(answers[k])
+                               }
+                       })
+                       
+                       // disable parentPolicyConditions when a parentPolicy is not selected
+                       $("#formId"+count+" #parentPolicy").on("change",function(){
+                               if($("#formId"+count+" #parentPolicy").val().toString()==""){
+                                       // deselect all options
+                                       $("#formId"+count+" #parentPolicyConditions option:selected").prop("selected", false);
+                                       // disable the select box
+                                       $("#formId"+count+" #parentPolicyConditions").prop('disabled', 'disabled');
+                               } else {
+                                       $("#formId"+count+" #parentPolicyConditions").prop('disabled', false);
+                               }
+                       })
+               }
+               
+               
+               function addCustListen(count) {
+                       $('#go_properties_tab' + count).click(function(event) {
+                               $("#nav_Tabs li").removeClass("active");
+                               $(this).parent().addClass("active");
+                               $("#formId" + count).css("display", "")
+                               $(".formId").not($("#formId" + count)).css("display", "none")
+
+                       })
+                       $('#tab_close' + count).click(function(event) {
+                               if(document.getElementById("timeout").disabled){
+                                       return false;
+                               }
+                               $(this).parent().remove();
+                               for(var i=1;i<=greatestIdNum();i++){
+                                       if(     $("#formId"+i).length>0){
+                                               //alert("fudge")
+                                               if(i!==count ){
+                                                       if(     $("#formId"+i+" #parentPolicy").val()===$("#formId"+count+" #_id").val().toString())
+                                                               $("#formId"+i+" #parentPolicy").val("")
+                                                       $("#formId"+i+" #parentPolicy option[value='"+$("#formId"+count+" #_id").val().toString()+"']").remove();
+                                               }
+                                       }
+                               }
+                               delete policy_ids["#formId" + count + " #_id"]
+                               $("#formId" + count).remove();
+                       })
+               }
+               
+               function greatestIdNum(){
+                       var greatest = 0;
+                       var s = $(".formId");
+                       for (var i = 0; i < s.length; i++) {
+                               if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
+                                       greatest = parseInt($(s[i]).attr("id").substring(6))
+                               }
+                       }
+                       return greatest;
+               }
+               
+               //Generate random id for each policy
+               //Also made sure ids couldnt be repeated
+               function makeid(num)
+               {
+                       
+                   var text = "";
+                   var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+                       if(num==null)
+                               num=7;
+                   for( var i=0; i < 7; i++ )
+                       text += possible.charAt(Math.floor(Math.random() * possible.length));
+                   var hasValue=false;
+                   for(k in policy_ids){
+                       if(text===policy_ids[k])
+                               hasValue=true
+                   }
+                   if (hasValue)
+                               return makeid(num);
+                       else
+                               return text
+               }
+               
+               var ParentPolicy=function(id,name){
+                       this.id=id
+                       this.name=name
+               }
+               
+               //Policy table search filter
+               function searchPolicyList() {
+                       var search = document.getElementById("policySearch");
+                       var row = document.getElementsByTagName("td");
+                       for (var i=0; i<row.length; i++){
+                               if (row[i].innerHTML.toUpperCase().indexOf(search.value.toUpperCase()) > -1){
+                                       row[i].style.display = "";
+                               } else {
+                                       row[i].style.display = "none";
+                               }
+                       }
+               }
+               
+               function saveLastPolicyLocally(lastPolicyId){
+                       var polForm = []
+                       
+                       var properties = $(".saveProps").not("#formSpan .saveProps")
+                       var timeoutForm = $("#Timeoutform").serializeArray();
+                       
+                       for (var i=0; i<timeoutForm.length; i++){
+                               polForm.push(timeoutForm[i]);
+                       }
+                       
+                       var d = {}
+                       d["policyConfigurations"] = [];
+                       for (var i = 0; i < properties.length; i++) {
+                               var ser = $(properties[i]).serializeArray();
+                               var s = noRepeats(ser)
+                               d["policyConfigurations"].push(s);
+                       }
+                       polForm.push(d);
+                       allPolicies[lastPolicyId] = polForm;
+               }
+               
+               $("#deletePolicy").on('click', function(){
+                       var deleteId = $("#policyTable .highlight").attr("id");
+                       delete allPolicies.deleteId;
+                       $("#policyTable .highlight").remove();
+                       expandTable();
+               });
+               
+               $('#policyTable').on('click', 'tr', function(event) {
+                       startNextItem();
+                       
+                       $(this).addClass('highlight').siblings().removeClass('highlight');
+                       disperseConfig(allPolicies, $(this).attr("id"));
+               });
+               
+               $('#createNewPolicy').on('click', function(){
+                       startNextItem();
+                       
+                       var defPolName = add_new_policy();
+                       
+                       if (("#policyTable .highlight").length > 0){
+                               $('#policyTable tr.highlight').removeClass('highlight');
+                       }
+            $("#policyTable").prepend("<tr class='highlight' id='" +defPolName+ "''><td>"+defPolName+"</td></tr>");
+               });
+               
+               function startNextItem(){
+                       //save last item before transitioning
+                       var lastItem = $("#policyTable .highlight");
+                       if (lastItem.length > 0){
+                               saveLastPolicyLocally($("#pname").val());
+                               
+                               lastItem.attr("id",$("#pname").val());
+                               $("#"+lastItem.attr("id")+" td").html($("#pname").val());
+                       } else{
+                               collapseTable();
+                       }
+                       
+                       //allow deleting
+                       if ($("#deletePolicy").prop("disabled")){
+                               $("#deletePolicy").prop("disabled", false);
+                       }
+               }
+               
+               //Show table panel only
+               function expandTable(){
+                       $(".policyPanel").css("display","none");
+                       $(".leftPolicyPanel").removeClass("col-sm-3");
+                       $(".glyphicon-search").css("padding", "25px 12px");
+                       if (!($("#deletePolicy").prop("disabled"))){
+                               $("#deletePolicy").prop("disabled", true);
+                       }
+               }
+               
+               //Show both menus
+               function collapseTable(){
+                       $(".leftPolicyPanel").addClass("col-sm-3");
+                       $(".glyphicon-search").css("padding", "10px 12px");
+                       $(".policyPanel").css("display","unset");
+               }
+                       
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/Template_model.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/Template_model.html
new file mode 100644 (file)
index 0000000..9c97d59
--- /dev/null
@@ -0,0 +1,133 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+    .fileUpload {
+        position: relative;
+        overflow: hidden;
+        margin: 10px;
+    }
+    .fileUpload input.upload {
+        position: absolute;
+        top: 0;
+        right: 0;
+        margin: 0;
+        padding: 0;
+        font-size: 20px;
+        cursor: pointer;
+        opacity: 0;
+        filter: alpha(opacity=0);
+        float:left;
+    }
+    .fileDisplay {
+
+        display: inline-block;
+        overflow: hidden;
+        float: right;
+        margin-left: 0px;
+        z-index: initial;
+        text-align: center;
+        margin-top: 17px;
+    }
+
+
+</style>
+
+
+<div attribute-test="templatemodel" id="configure-widgets"  >
+    <div attribute-test="templatemodelh" class="modal-header">
+        <button type="button" class="close" ng-click="close(false)" aria-hidden="true" style="margin-top: -3px">&times;</button>
+        <h4>'Template'</h4>
+    </div>
+    <div class="modal-body" style="height: 280px">
+        <div style="height: 10px">
+        </div>
+        <form id="saveProps" name="t" class="form-horizontal">
+
+            <div>
+                <div class="form-group">
+                    <label for="schemaLocation" class="col-sm-4 control-label">ID</label>
+
+                    <div class="col-sm-8">
+                        <input class="form-control" type="text" focus="true" name="_id"  id="_id" readonly>
+                           <div hidden id="warnings_">Special Characters are not allowed in template id.</span> <!-- <span ng-show="nameinUse" style="color: red"> Model Name Already In Use</span> --></div>
+                        </input>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+    <div attribute-test="templatemodelf" class="modal-footer">
+        <button  id="savePropsBtn" class="btn btn-primary" ng-disabled="t._id.$error.pattern" >Close</button>
+        <button ng-click="close(true)" id="close_button" class="btn btn-primary">Cancel</button>
+
+    </div>
+    <script>
+    loadPropertyWindow("template");
+    var el=elementMap[lastElementSelected];
+    //console.log(el)
+    //console.log(lastElementSelected)
+    //$("#id").val("lolololol")
+   // $('.modal-header > h4').html($('.djs-visual > text').val());
+    if(el!==undefined){
+       
+        for(var i=0;i<el.length;i++){   
+               console.log(el.length)
+               console.log(el[i].name)
+               console.log(el[i].value)
+            $("#"+el[i].name).val(el[i].value);
+        }
+    }
+     $("#_id").keyup(function(){
+        var pattern=/^\s*[\w\-]*\s*$/
+        if( !pattern.test($(this).val()) && !$(this).is("[disabled]")){
+            $("#savePropsBtn").attr("disabled","");
+            $("#warnings_").removeAttr("hidden")
+            console.log("remove hidden")
+        }
+        else{
+            //console.log($(this).is("[disabled]"))
+            console.log("add hidden ")
+            if($("#savePropsBtn").is("[disabled]")){
+                $("#savePropsBtn").removeAttr("disabled");
+                 $("#warnings_").attr("hidden", "");
+            console.log("add hidden if")
+            }
+           
+        }
+    })
+    
+    $("#saveProps").on('submit', function (event) {
+       //console.log(lastElementSelected)
+        saveProperties($(this).serializeArray())
+        event.preventDefault();
+        $("#close_button").click();
+    })
+    
+    $("#savePropsBtn").click(function (event) {
+        $("#saveProps").submit();
+    })
+</script>
+</div>
+
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_model_off_Template.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_model_off_Template.html
new file mode 100644 (file)
index 0000000..09aba13
--- /dev/null
@@ -0,0 +1,89 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="cldsmodelofftemplate" id="configure-widgets">
+    <div  attribute-test="cldsmodelofftemplate" class="modal-header">
+        <button type="button" class="close" ng-click="close(false)" aria-hidden="true" style="margin-top: -3px">&times;</button>
+        <h4>Model Creation</h4>
+    </div>
+    <div attribute-test="cldsmodelofftemplate" class="modal-body" >
+        <div style="height: 30px"></div>
+        <button class="btn btn-primary btn-xs" ng-click="setTypeModel('template')">Template</button>
+        <button class="btn btn-primary btn-xs" ng-click=" setTypeModel('clone')">Clone</button>
+        <div ng-show="error.flag">{{error.message}} </div>
+        <div ng-switch on="typeModel">
+            <div ng-switch-when="template">
+                <form name="model" class="form-horizontal" novalidate>
+                    <div class="form-group">
+                        <label for="modelName" class="col-sm-3 control-label">Model Name</label>
+                        <div class="col-sm-8">
+                            <input type="text" class="form-control" id="modelName" name="modelName" ng-model="modelName" placeholder="Model Name" ng-change="checkExisting();" autofocus="autofocus" ng-pattern="/^\s*[\w\-]*\s*$/" required ng-trim="true">
+                            <div role="alert"><span ng-show="model.modelName.$error.pattern" style="color: red">Special Characters are not allowed in Model name.</span> <span ng-show="nameinUse" style="color: red"> Model Name Already In Use</span></div>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="modelName" class="col-sm-3 control-label">Templates</label>
+                        <div class="col-sm-8">
+                            <select class="form-control" id="templateName" name="templateName" autofocus="autofocus" required ng-trim="true">
+                                <option ng-repeat="x in templateNamel" value="{{x}}">{{x}}</option>
+                            </select>
+                        </div>
+                    </div>
+                </form>
+            </div>
+            <div ng-switch-when="clone">
+                <form name="model" class="form-horizontal" novalidate>
+                    <div class="form-group">
+                        <label for="modelName" class="col-sm-3 control-label">Model Name</label>
+                        <div class="col-sm-8">
+                            <input type="text" class="form-control" id="modelName" name="modelName" ng-model="modelName" placeholder="Model Name" ng-change="checkExisting()" autofocus="autofocus" ng-pattern="/^\s*[\w\-]*\s*$/" required ng-trim="true">
+                            <div role="alert"><span ng-show="model.modelName.$error.pattern" style="color: red">Special Characters are not allowed in Model name.</span> <span ng-show="nameinUse" style="color: red"> Model Name Already In Use</span></div>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="modelName" class="col-sm-3 control-label">Clone</label>
+                        <div class="col-sm-8">
+                            <select class="form-control" id="modelList" name="modelList" autofocus="autofocus" required ng-trim="true">
+                                <option ng-repeat="x in modelNamel" value="{{x}}">{{x}}</option>
+                            </select>
+                        </div>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+    <div ng-switch on="typeModel">
+        <div ng-switch-when="template">
+            <div class="modal-footer">
+                <button ng-click="createNewModelOffTemplate(model)" class="btn btn-primary" ng-disabled="spcl || nameinUse" class="btn btn-primary">Create</button>
+                <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+            </div>
+        </div>
+        <div ng-switch-when="clone">
+            <div class="modal-footer">
+                <button ng-click="cloneModel()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern || nameinUse" class="btn btn-primary">Clone</button>
+                <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_template.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_create_template.html
new file mode 100644 (file)
index 0000000..632b0ee
--- /dev/null
@@ -0,0 +1,51 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="cldscreatetemplate" id="configure-widgets">
+       <div attribute-test="cldscreatetemplate1" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Create Template</h4>
+       </div>
+       <div attribute-test="cldscreatetemplate2" class="modal-body" style="height: 150px">
+               <div style="height: 30px"></div>
+               <div ng-show="error.flag">{{error.message}} </div>
+
+       <form attribute-test="cldscreatetemplate3" name="model" class="form-horizontal">
+                       <div class="form-group">
+                               <label for="modelName" class="col-sm-3 control-label">Template Name</label>
+                               <div class="col-sm-8">
+                                       <input type="text" class="form-control" id="modelName" name="modelName"
+                                               ng-model="modelName" placeholder="Model Name" ng-change="checkExisting()" autofocus="autofocus" ng-pattern="/^\s*[\w\-]*\s*$/" required ng-trim="true">
+                                               <div role="alert"><span ng-show="model.modelName.$error.pattern" style="color: red">Special Characters are not allowed in Model name.</span> <span ng-show="nameinUse" style="color: red"> Model Name Already In Use</span></div>
+                               </div>
+                       </div>
+               </form>
+       </div>
+       <div class="modal-footer">
+
+               <button ng-click="createNewTemplate()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern || nameinUse" class="btn btn-primary">OK</button>
+               <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+       </div>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_modelling.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_modelling.html
new file mode 100644 (file)
index 0000000..3f7192e
--- /dev/null
@@ -0,0 +1,839 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.Row1 {
+       display: table;
+       width: 100%;
+       table-layout: fixed;
+       border-spacing: 0px;
+}
+
+.Column1 {
+       display: table-cell;
+}
+.visible
+{
+display:none;
+}
+
+.table-tree{
+       border: 0px solid black;
+    table-layout: fixed;
+       width: 600px;
+}
+.selectedFile{
+background-color: #337ab7;
+color: #fff;
+}
+
+.selectedcolor{
+color:#0000FF;
+}
+.td-label-tree {
+       border: 0px solid black;
+    overflow: hidden;
+    width: 250px;
+    vertical-align: bottom;
+}
+
+.table-level1-tree{
+       border: 0px solid black;
+    table-layout: fixed;
+    width: 580px;
+}
+
+.td-level1-label-tree {
+    overflow: hidden;
+    width: 230px;
+}
+
+.table-level2-tree{
+    table-layout: fixed;
+    width: 560px;
+}
+
+.td-level2-label-tree {
+    overflow: hidden;
+    width: 210px;
+}
+
+.table-level3-tree{
+    table-layout: fixed;
+    width: 540px;
+}
+
+.td-level3-label-tree {
+    overflow: hidden;
+    width: 190px;
+}
+
+.table-level4-tree{
+    table-layout: fixed;
+    width: 520px;
+}
+
+.td-level4-label-tree {
+    overflow: hidden;
+    width: 170px;
+}
+
+.table-level5-tree{
+    table-layout: fixed;
+    width: 500px;
+}
+
+.td-level5-label-tree {
+    overflow: hidden;
+    width: 150px;
+}
+
+.table-level6-tree{
+    table-layout: fixed;
+    width: 480px;
+}
+
+.td-level6-label-tree {
+    overflow: hidden;
+    width: 130px;
+}
+
+.table-level7-tree{
+    table-layout: fixed;
+    width: 460px;
+}
+
+.td-level7-label-tree {
+    overflow: hidden;
+    width: 110px;
+}
+
+.table-level8-tree{
+    table-layout: fixed;
+    width: 440px;
+}
+
+.td-level8-label-tree {
+    overflow: hidden;
+    width: 90px;
+}
+
+
+.table-level9-tree{
+    table-layout: fixed;
+    width: 420px;
+}
+
+.td-level9-label-tree {
+    overflow: hidden;
+    width: 70px;
+}
+
+
+.table-level10-tree{
+    table-layout: fixed;
+    width: 400px;
+}
+
+.td-level10-label-tree {
+    overflow: hidden;
+    width: 50px;
+}
+
+
+.td-default_value-tree {
+       border: 0px solid black;
+    overflow: hidden;
+    width: 180px !important;
+    vertical-align: bottom; 
+    text-align: left !important;    
+}
+
+.td-blank{
+width: 30px;
+
+}
+
+.td-button{
+width: 14px;
+}
+
+.td-tree {
+       border: 0px solid black;
+    overflow: hidden;
+    width: 100px;
+    vertical-align: top;
+    text-align: center !important;
+}
+
+/* #contextmenu-node{
+    position: absolute;
+    background-color: white;
+    border: solid #CCCCCC 1px;
+    margin-left:60px;   
+}
+
+.contextmenu-item{
+    margin: 0.5em;
+    padding-left: 0.5em;
+    display: block;
+    padding: 3px 20px;
+    clear: both;
+    font-weight: normal;
+    line-height: 1.42857143;
+    color: #333;
+    white-space: nowrap;
+}
+
+.contextmenu-item:hover{
+    background-color: #3c8dbc;
+    cursor: default;
+    color:#fff;
+}
+ */
+ #contextmenu-node{
+    position: absolute;
+    background-color: white;
+    border: solid #CCCCCC 1px;
+    margin-top:-60px;
+  
+}
+
+.contextmenu-item{
+    margin: 0.5em;
+    padding-left: 0.5em;
+    display: block;
+    padding: 3px 20px;
+    clear: both;
+    font-weight: normal;
+    line-height: 1.42857143;
+    color: #333;
+    white-space: nowrap;
+}
+
+.contextmenu-item:hover{
+    background-color: #3c8dbc;
+    cursor: default;
+    color:#fff;
+}
+
+</style>
+<div attribute-test="cldsmodelling" class="container-fluid" ng-controller="ActivityModellingCtrl" style="height: 90vh;margin:0;padding:0;overflow: hidden;">
+       <div id="utm-splitter" class="k-content"  style="height: 90vh;overflow: hidden;">
+       <!-- clds: size 0% rather than 30% -->
+       <!-- div id="UTMdashboard" kendo-splitter
+               k-panes="[  { collapsible: true, collapsedSize: '0%',size:'30%'},{}]"
+               k-orientation="orientation" k-rebind="orientation"
+               ng-class="{hidden:testsetgendashboard}" style="height: 90vh;overflow: hidden;margin-left: 2px;margin-right: 2px;" -->
+       <div attribute-test="cldsmodelling2" id="UTMdashboard" kendo-splitter
+               k-panes="[  { collapsible: true, collapsedSize: '0%',size:'0%'},{}]"
+               k-orientation="orientation" k-rebind="orientation"
+               ng-class="{hidden:testsetgendashboard}" style="height: 90vh;overflow: hidden;margin-left: 2px;margin-right: 2px;">
+               <div style="display: none;" id="projectExplorer">
+               <!-- clds: remove project explorer - use display: none -->
+               <!-- div style="width: 30%; height: 90vh;overflow: hidden;" id="projectExplorer" -->
+                       <div class="panel panel-primary">
+                               <div class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span>Project Explorer</span>
+                                               </span> <span class="pull-right" ng-click="showUTMView=!showUTMView"><i
+                                                       ng-class="showUTMView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showUTMView,chaldean:showUTMView}">
+                                       <div class="panel-body" style="height: 79vh; overflow: auto;">
+                                               <div ng-if="projectName != null" >
+                                                       <div>
+                                                               <h6>
+                                                                       <span class="pull-left"
+                                                                               ng-click="showUTMViewMain=!showUTMViewMain"> <i
+                                                                               ng-class="showUTMViewMain == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i>
+                                                                       </span> <b>{{projectName}} </b>
+                                                               </h6>
+
+
+                                                       </div>
+                                                       <div style="margin-left: 5px"
+                                                               ng-class="{hidden:showUTMViewMain,chaldean:showUTMViewMain}">
+
+                                                               <div>
+                                                                       <h6>
+                                                                               <span class="pull-left"
+                                                                                       ng-click="showUTMViewModel=!showUTMViewModel"> <i
+                                                                                       ng-class="showUTMViewModel == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                                                                               </i>
+                                                                               </span><b>Model</b>
+                                                                       </h6>
+                                                               </div>
+                                                               <div style="margin-left: 15px"
+                                                                       ng-class="{hidden:showUTMViewModel,chaldean:showUTMViewModel}">                                                                 
+                                                                       
+                                                                       <div id="div_models" ng-include="'model_renderer.html'">
+                                                                               
+                                                                       </div>
+                                                               </div>
+
+                                                               <div>
+                                                                       <h6>
+                                                                               <span class="pull-left"
+                                                                                       ng-click="showUTMViewService=!showUTMViewService"> <i
+                                                                                       ng-class="showUTMViewService == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                                                                               </i>
+                                                                               </span><b>Service</b>
+                                                                       </h6>
+                                                               </div>
+
+                                                               <div style="margin-left: 10px"
+                                                                       ng-class="{hidden:showUTMViewService,chaldean:showUTMViewService}">
+
+                                                                       <div style="width: 190px;">
+                                                                               <h6>
+                                                                                       <span class="pull-left"
+                                                                                               ng-click="showUTMViewDtl=!showUTMViewDtl"> <i
+                                                                                               ng-class="showUTMViewDtl == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                       </i>
+                                                                                       </span><b>Service Details</b>
+                                                                               </h6>
+                                                                       </div>
+
+                                                                       <div style="margin-left: 10px"
+                                                                               ng-class="{hidden:!showUTMViewDtl,chaldean:!showUTMViewDtl}">
+
+
+                                                                               <div ng-show="serviceInfo != null">
+                                                                                       <h6>
+                                                                                               <span class="pull-left"
+                                                                                                       ng-click="showUTMViewServiceName=!showUTMViewServiceName">
+                                                                                                       <i
+                                                                                                       ng-class="showUTMViewServiceName == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                               </span><b>Service Name</b>
+                                                                                       </h6>
+                                                                                       <div style="margin-left: 10px"
+                                                                                               ng-class="{hidden:!showUTMViewServiceName,chaldean:!showUTMViewServiceName}">
+                                                                                               <div style="margin-left: 10px">
+                                                                                                       {{serviceInfo.service.name}}</div>
+                                                                                       </div>
+
+                                                                               </div>
+
+                                                                               <div ng-show="serviceInfo != null">
+                                                                                       <h6>
+                                                                                               <span class="pull-left"
+                                                                                                       ng-click="showUTMViewPortName=!showUTMViewPortName">
+                                                                                                       <i
+                                                                                                       ng-class="showUTMViewPortName == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                               </span><b>Port Name</b>
+                                                                                       </h6>
+                                                                                       <div style="margin-left: 10px"
+                                                                                               ng-class="{hidden:!showUTMViewPortName,chaldean:!showUTMViewPortName}">
+                                                                                               <div style="margin-left: 10px">
+                                                                                                       {{serviceInfo.service.ports[0].name}}</div>
+                                                                                       </div>
+                                                                               </div>
+
+                                                                               <div ng-show="serviceInfo != null">
+                                                                                       <h6>
+                                                                                               <span class="pull-left"
+                                                                                                       ng-click="showUTMViewBindingName=!showUTMViewBindingName">
+                                                                                                       <i
+                                                                                                       ng-class="showUTMViewBindingName == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                               </span><b> Binding Name</b>
+                                                                                       </h6>
+                                                                                       <div style="margin-left: 10px"
+                                                                                               ng-class="{hidden:!showUTMViewBindingName,chaldean:!showUTMViewBindingName}">
+                                                                                               <div style="margin-left: 10px">
+                                                                                                       {{serviceInfo.bindingInfo.binding.name}}</div>
+                                                                                       </div>
+                                                                               </div>
+
+                                                                               <div ng-show="serviceInfo != null">
+                                                                                       <h6>
+                                                                                               <span class="pull-left"
+                                                                                                       ng-click="showUTMViewBindingPortType=!showUTMViewBindingPortType">
+                                                                                                       <i ng-class="showUTMViewBindingPortType == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                               </span><b>Binding Port Type</b>
+                                                                                       </h6>
+                                                                                       <div style="margin-left: 10px"
+                                                                                               ng-class="{hidden:!showUTMViewBindingPortType,chaldean:!showUTMViewBindingPortType}">
+                                                                                               <div style="margin-left: 10px">
+                                                                                                       {{serviceInfo.bindingInfo.portTypeInfo.portType.name}}</div>
+                                                                                       </div>
+                                                                               </div>
+
+                                                                               <div ng-show="serviceInfo != null">
+                                                                                       <h6>
+                                                                                               <span class="pull-left"
+                                                                                                       ng-click="showUTMViewOperation=!showUTMViewOperation">
+                                                                                                       <i
+                                                                                                       ng-class="showUTMViewOperation == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                               </span><b>Operation Name</b>
+                                                                                       </h6>
+                                                                                       <div style="margin-left: 10px"
+                                                                                               ng-class="{hidden:!showUTMViewOperation,chaldean:!showUTMViewOperation}">
+                                                                                               <div style="margin-left: 10px">
+                                                                                                       {{serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].operation.name}}</div>
+                                                                                       </div>
+                                                                               </div>
+                                                                       </div>
+
+                                                                       <table class="table-tree">
+                                                                               <tr>
+                                                                                       <td class="td-label-tree" style="margin-top: 30px;">
+                                                                                           <table>
+                                                                                              <tr>
+                                                                                                   <td>   </td>
+                                                                                              </tr>
+                                                                                              <tr>
+                                                                                                   <td>   </td>
+                                                                                              </tr>
+                                                                                              <tr>
+                                                                                                  <td>
+                                                                                                      <h6>
+                                                                                                                          <span class="pull-left"      ng-click="showUTMViewInput=!showUTMViewInput"> 
+                                                                                                                                       <i ng-class="showUTMViewInput == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                                                                                                                                       </i>
+                                                                                                                         </span>
+                                                                                                                         <b>Service Input</b>
+                                                                                                                 </h6>
+                                                                                                  </td>
+                                                                                              </tr>                                                                                        
+                                                                                           </table>
+                                                                                       </td>
+                                                                                       
+                                                                                       <td class="td-default_value-tree" >
+                                                                                           <table  style="margin-top: 30px;">
+                                                                                              <tr>
+                                                                                                  <td></td>
+                                                                                              </tr>
+                                                                                              <tr>
+                                                                                                  <td></td>
+                                                                                              </tr>
+                                                                                              
+                                                                                              <tr>
+                                                                                                  <td class="td-blank"></td>   
+                                                                                              </tr>
+                                                                                           </table>
+                                                                                       </td>
+                                                                                       
+                                                                                       <td>
+                                                                                               <div ng-show="isModel">
+                                                                                                       <table style="margin-top: -10px;width: 260px;margin-left: -116px;">
+                                                                                                               <tr>
+                                                                                                                       <td class="td-default_value-tree">
+                                                                                                                               <input type="radio" ng-model="utmModelSchemaExtension.radioSelection"
+                                                                                                                                               ng-click="requiredOnly()"
+                                                                                                                                               value="Required Only"><b>Required Only</b>
+                                                                                                                       </td>                                                                   
+                                                                                                                       
+                                                                                                                       
+                                                                                                                       <!-- <td class="td-default_value-tree">
+                                                                                                                           <h6> <b>Default Value</b></h6>                      
+                                                                                                                       </td> -->
+                                                                                                                       
+                                                                                                               </tr>
+                                                                                                               <tr>
+                                                                                                                                                                                               
+                                                                                                                       <td style="text-align: left;" class="td-default_value-tree">
+                                                                                                                               <input type="radio" ng-model="utmModelSchemaExtension.radioSelection"
+                                                                                                                                                       ng-click="selectAll()"
+                                                                                                                                                       value="Select All"> <b>Select All</b>
+                                                                                                                       </td>
+                                                                                                                       <td></td>
+                                                                                                                       
+                                                                                                               </tr>
+                                                                                                               <tr>
+                                                                                                                                                                                                       
+                                                                                                                       <td style="text-align: left;" class="td-default_value-tree">
+                                                                                                                               <input type="radio" ng-model="utmModelSchemaExtension.radioSelection"
+                                                                                                                                               ng-click="unSelectAll()"
+                                                                                                                                               value="Unselect All">  <b>Unselect All</b>
+                                                                                                                       </td>
+                                                                                                                       
+                                                                                                                       
+                                                                                                                       <td></td>
+                                                                                                               </tr>
+                                                                                                       </table>                                                                                                                
+                                                                                               </div>
+                                                                                       </td>
+                                                                                       
+                                                                                       <!-- <td class="td-blank"></td>
+                                                                                       <td class="td-blank"></td> -->
+                                                                                       <td class="td-default_value-tree">
+                                                                                                                           <h6> <b>Default Value</b></h6>                      
+                                                                                                                       </td>
+                                                                                       
+                                                                                       
+                                                                                       
+                                                                                       
+                                                                                       
+                                                                               </tr>
+                                                                   </table>
+                                                                       <div style="margin-left: 20px;margin-top: -12px;"
+                                                                               ng-class="{hidden:showUTMViewInput,chaldean:showUTMViewInput}">
+                                                                       
+                                                                               <div ng-show="serviceInputPartInfo.length>0" >                                                                          
+                                                                                       <h6>
+                                                                                       <!-- <div ng-repeat="inputInfo in serviceInputPartInfo">        
+                                                                                                        inputInfo :: {{inputInfo}}                                                              
+                                                                                               <div ng-repeat="schemaElement in inputInfo.schemaElements"   ng-include="'service_tree_element_renderer.html'" ng-init="currentElementName= inputInfo.part.name;parentName='ServiceInput'; parentElement=inputInfo; heirarchyLevel=1">
+                                                                                                 
+                                                                                               </div>
+                                                                                                                                                                               
+                                                                                               </div> -->
+                                                                                               <div ng-repeat="inputInfo in serviceInputPartInfo">
+                                                                                                       <div class="inputInfoClass" ng-init="currentElementName= inputInfo.part.name;parentName='ServiceInput'; parentElement=inputInfo; heirarchyLevel=1;infoType=inputInfo"></div>
+                                                                                               </div>  
+                                                                                       </h6>
+                                                                                       
+                                                                               </div>
+                                                                       
+                                                                       </div>
+
+                                                                       <table class="table-tree" style="margin-top: -12px;>
+                                                                               <tr>
+                                                                                       <td class="td-label-tree">
+                                                                                               <h6>
+                                                                                                       <span class="pull-left"
+                                                                                                                       ng-click="showUTMViewOutput=!showUTMViewOutput"> 
+                                                                                                               <i
+                                                                                                                       ng-class="showUTMViewOutput == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                                                                                                               </i>
+                                                                                                       </span>
+                                                                                                       <b>Service Output</b>
+                                                                                               </h6>
+                                                                                       </td>
+                                                                                       
+                                                                                       <td class="td-default_value-tree">
+                                                                                       </td>
+                                                                                       <td class="td-tree">
+                                                                                       </td>
+                                                                               </tr>
+                                                               </table>
+                                                                       <div style="margin-left: 20px;"
+                                                                               ng-class="{hidden:showUTMViewOutput,chaldean:showUTMViewOutput}">
+                                                                               <div ng-show="serviceOutputPartInfo.length>0" style="width: 250px">
+                                                                                       <h6>
+                                                                                       <!-- <div ng-repeat="outputInfo in serviceOutputPartInfo" >
+                                                                                                 outputInfo::: {{outputInfo}}
+                                                                                               <div ng-repeat="schemaElement in outputInfo.schemaElements" ng-include="'service_tree_element_renderer.html'" ng-init="currentElementName=outputInfo.part.name;parentName='ServiceOutput'; parentElement=outputInfo; heirarchyLevel=1">
+                                                                                                       </div>
+                                                                                               </div> -->      
+                                                                                               <div ng-repeat="outputInfo in serviceOutputPartInfo">
+                                                                                                       <div class="inputInfoClass" ng-init="currentElementName=outputInfo.part.name;parentName='ServiceOutput'; parentElement=outputInfo; heirarchyLevel=1; infoType=outputInfo"></div>
+                                                                                               </div>  
+                                                                                       </h6>
+                                                                               </div>
+                                                                       </div>
+                                                               
+                                                                       <table class="table-tree" style="margin-top: -12px;">
+                                                                               <tr>
+                                                                                       <td class="td-label-tree" >
+                                                                                               <h6>
+                                                                                                       <span class="pull-left"
+                                                                                                               ng-click="showUTMViewFault=!showUTMViewFault"> 
+                                                                                                               <i ng-class="showUTMViewFault == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                                                                                                               </i>
+                                                                                                       </span>
+                                                                                                       <b>Service Fault</b>
+                                                                                               </h6>
+                                                                                       </td>
+                                                                                       <td class="td-default_value-tree">
+                                                                                       </td>
+                                                                                       <td class="td-tree">
+                                                                                       </td>
+                                                                               </tr>
+                                                               </table>
+                                                                       <div style="margin-left: 20px;"
+                                                                               ng-class="{hidden:showUTMViewFault,chaldean:showUTMViewFault}">
+                                                                               
+                                                                               <div ng-show="servicefaultPartInfo.length>0" style="width: 250px">
+                                                                                       <h6>
+                                                                                       <!-- <div ng-repeat="faultInfo in servicefaultPartInfo" style="margin-top: -12px;">
+                                                                                       faultInfo ::::{{faultInfo}}
+                                                                                               <div ng-repeat="schemaElement in faultInfo.schemaElements" ng-include="'service_tree_element_renderer.html'" ng-init="currentElementName=faultInfo.schemaElements[0].name;parentName='ServiceFault'; parentElement=faultInfo; heirarchyLevel=1">
+                                                                                                       </div>
+                                                                                               </div>   -->
+                                                                                               <div ng-repeat="faultInfo in servicefaultPartInfo">
+                                                                                                       <div class="inputInfoClass" ng-init="currentElementName=faultInfo.part.name;parentName='ServiceFault'; parentElement=faultInfo; heirarchyLevel=1; infoType=faultInfo"></div>
+                                                                                               </div>  
+                                                                                       </h6>
+                                                                               </div>
+                                                                       </div>  
+                                                               </div>
+                                                               
+                                                       
+                                                               <div>
+                                                                       <div>
+                                                                               <h6>
+                                                                                       <span class="pull-left"
+                                                                                               ng-click="showUTMViewTestSet=!showUTMViewTestSet"> 
+                                                                                               <i
+                                                                                               ng-class="showUTMViewTestSet == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                                                               </i>
+                                                                                       </span>
+                                                                                       <b ng-click="selectActivityTestSet()">Test Set</b>
+                                                                               </h6>
+                                                                       </div>
+                                                                       <div style="margin-left: 15px;"
+                                                                                       ng-class="{hidden:!showUTMViewTestSet,chaldean:!showUTMViewTestSet}">
+                                                                               <div ng-show=" modeltestset.activityTestCases.length>0" style="width: 250px">
+                                                                                       <div ng-repeat="activityTestCase in modeltestset.activityTestCases">
+                                                                                       
+                                                                                               <div ng-if="activityTestCase.version ==null">
+                                                                                               <h6>
+                                                                                                       <div ng-mouseover="selectTC(activityTestCase)"><b id="{{activityTestCase.testCaseName}}" data-stuff='{{activityTestCase}}' data-model='{{utmModels}}' class="TCS" style="cursor:pointer;">{{activityTestCase.testCaseName}}</b></div>
+                                                                                       </h6>
+                                                                                       </div>
+                                                                                       <div ng-if="activityTestCase.version !=null">
+                                                                                               <h6>
+                                                                                                       <div ng-mouseover="selectTC(activityTestCase)"><b id="{{activityTestCase.testCaseName}}" data-stuff='{{activityTestCase}}' data-model='{{utmModels}}' class="TCS" style="cursor:pointer;">{{activityTestCase.testCaseName + "_" + activityTestCase.version}}</b></div>
+                                                                                       </h6>
+                                                                                       </div>
+                                                                                       </div>  
+                                                                               </div>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+
+
+               <!-- clds: width 100 instead of 70 -->
+               <div style="width: 100%;height:90vh" id="activity_modeler">
+               <!-- div style="width: 70%;height:90vh" id="activity_modeler" -->
+
+                       <div class="panel panel-primary">
+                               <div class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span id="modeler_name">Closed Loop Modeler</span>
+
+                                               </span> <span class="pull-right" ng-click="showTDRView=!showTDRView"><i
+                                                       ng-class="showTDRView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showTDRView,chaldean:showTDRView}">
+                                       <div style="height: 83.5vh; width: 100%;">
+                                               <div class="panel-body" style="height: 83.5vh;padding: 0px;">
+                                                       <div  id="paletteDiv" style="width: 100%;height: 83.5vh;"
+                                                               ng-show="isPalette" ng-include="'./modeler/dist/index.html'">
+
+                                                       </div>
+                        
+                            <!--Commented becoz i m not able to find the htmls-->
+                                               <!-- <div  ng-show="isTestset && !isPalette && !isRequirementCoverage" style="width: 100%;height: 83.5vh;" ng-include src="'partials/portfolios/generate_testset.html'" ></div>
+                                               <div  ng-show="!isTestset && !isPalette && isRequirementCoverage" style="width: 100%;height: 83.5vh;" ng-include src="'partials/portfolios/requirement_coverage.html'" ></div> -->
+                                 </div>
+                        
+                                       </div>
+
+                               </div>
+                       </div>
+
+               </div>
+
+               <!-- <div id="propertyExplorer" style="width: 20%;height:90vh" >
+
+                       <div class="panel panel-primary">
+                               <div class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span>Property Explorer</span>
+
+                                               </span> <span class="pull-right" ng-click="showTDRView=!showTDRView"><i
+                                                       ng-class="showTDRView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showTDRView,chaldean:showTDRView}">
+                                       <div class="panel-body" style="height: 79vh; overflow: auto;">
+                                       
+                                  
+                                       
+                               <div id="propertyDiv"  ng-show="ispropertyExplorer" ng-include  src="'./partials/portfolios/Property_Explorer.html'"></div>
+               
+                                 
+                               </div>
+                       </div>
+
+               </div>
+
+       </div> -->
+       
+  </div>                                                               
+</div>
+<div ng-show ="isResult">      </div>
+<script type="text/ng-template"  id="service_tree_element_renderer.html">
+   
+
+
+       <div ng-show="schemaElement.complexType != null">
+
+       
+               <div ng-if="currentElementName == ''">
+                       <div ng-init="currentElementName = schemaElement.complexType.name">
+                               
+                       </div>
+               </div>  
+  
+      <div ng-init="ParentKey=parentName + '_' + currentElementName + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : ''); parElement=schemaElement;tableStyle='table-level' + heirarchyLevel + '-tree'; tdLabelStyle='td-level' + heirarchyLevel + '-label-tree'; heirLevel=heirarchyLevel ;">             
+               
+               <table class="{{tableStyle}}"> <tr>
+               <td class="{{tdLabelStyle}}">
+               <span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">
+                       <i
+                       ng-class="showUTMViewMsgHeader == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                       </i>
+               </span>
+               <b>     
+                               {{currentElementName}}   
+                                       
+               </b>
+        </td>
+       <td class="td-tree"></td>
+       <td class="td-tree"></td>
+       <td class="td-tree"></td>
+       <td class="td-blank"></td>      
+       <td class="td-default_value-tree"> </td>
+       
+      </tr></table>
+       
+       
+               <div style="margin-left: 10px"
+                               ng-class="{hidden:showUTMViewMsgHeader,chaldean:showUTMViewMsgHeader}">
+
+                       <div style="margin-left: 10px"
+                                       ng-repeat="schemaElement in schemaElement.elements"  ng-init="currentElementName=objectName;parentName=ParentKey; parentElement=parElement; heirarchyLevel = heirLevel + 1" ng-include="'service_tree_element_renderer.html'">
+
+                       </div>
+               </div>
+
+      </div>
+       </div>
+
+       <div ng-show="schemaElement.element.name != null">
+      <div  ng-init = "elementKey=parentName + '_' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : ''); tableStyle='table-level' + heirarchyLevel + '-tree'; tdLabelStyle='td-level' + heirarchyLevel +'-label-tree'" id="elementKey">
+                   <table class="{{tableStyle}}"> 
+                               <tr>
+                                       <td style="text-align: left;vertical-align: top;" class="{{tdLabelStyle}}">
+                                        <div ng-mouseover="getContextMenu(schemaElement,elementKey)" context-menu="myContextDiv">      
+                                               <span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader" ng-style="(schemaElement.type.recursive ||schemaElement.list) && {'color':'#0000FF'} || {'color': '#444444'}">
+                                                       <i ng-class="showUTMViewMsgHeader == true ?'fa fa-minus-circle':'fa fa-plus-circle'">
+                                                       </i>                                                                    
+                                                       {{schemaElement.element.name}}                          
+                                               </span>
+                                         </div>                                                        
+                                       </td>
+                       
+                       <div ng-if= "repeatableHeirarchicalElementMap !=null">
+                               <div ng-if="repeatableHeirarchicalElementMap[elementKey] != null">
+                                       <div ng-repeat="repeatableElement in repeatableHeirarchicalElementMap[elementKey].repeatableElements">
+                                               <div ng-init="addRepeatableElement1(schemaElement, parentElement, elementKey, $index)">
+                                               </div>
+                                       </div>
+                                       <div ng-repeat="heirarchicalElement in repeatableHeirarchicalElementMap[elementKey].heirarchicalElements">
+                                               <div ng-init="addHierarchicalElement1(schemaElement, parentElement, elementKey, $index)">
+                                               </div>
+                                       </div>
+                               </div>
+                       </div>
+                              
+                       <td class="td-blank"></td>
+                       
+                       <td style="text-align: right;" class="td-tree">
+                       <div ng-show="schemaElement.type.complexType == null">
+                                                  <input type="checkbox" id="{{elementKey + '_checkbox'}}" ng-model="utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked" ng-init="requiredValues[elementKey]=schemaElement.element.minOccurs;utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked=(utmModelSchemaExtension.radioSelection == 'Required Only' && schemaElement.element.minOccurs !=0) || utmModelSchemaExtension.radioSelection == 'Select All' || utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked" ng-change="onChange()"/>
+                       </div>                        
+                       </td>
+                       <td class="td-blank"></td>
+                       <td class="td-blank"></td>
+                       <td style="text-align:center;word-wrap: break-word" class="td-default_value-tree"><label id="{{elementKey + '_label'}}"/>{{utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].defaultValue}}</td>
+                       </tr></table> 
+            <div style="margin-left: 10px"
+                               ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">
+               <div ng-if = "schemaElement.type != null && schemaElement.type.restriction != null">
+                                       <div ng-repeat="object in filteredObjects = (schemaElement.type.restriction.minExclusivesAndMinInclusivesAndMaxExclusives | filter: {name : 'enumeration'})">
+                                               {{object.value.value}}
+                              </div>
+               </div>                  
+               </div>      
+      </div>
+       </div>
+       <div ng-show="schemaElement.type.complexType != null">  
+      <div ng-init="parKey=parentName + '_' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : ''); heirLevel=heirarchyLevel; parElement=schemaElement">                
+                       <div style="margin-left: 10px"
+                               ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">
+                 
+                       <div style="margin-left: 10px"
+                                       ng-repeat="schemaElement in schemaElement.type.elements"  ng-init="currentElementName=schemaElement.element.name;parentName=parKey; parentElement=parElement; heirarchyLevel=heirLevel+1 ;" ng-include="'service_tree_element_renderer.html'">
+                       </div>
+               </div>
+     </div>
+       </div>
+       
+</script>
+
+<script type="text/ng-template" id="model_renderer.html">
+
+<div ng-show="utmModels != null && utmModels.name != null">
+      <div>            
+               <table class="{{tableStyle}}"> <tr>
+                       <td class="{{tdLabelStyle}}">
+                               <span class="pull-left" ng-click="showUTMViewModel=!showUTMViewModel">
+                               <i
+                               ng-class="showUTMViewModel == true ?'fa fa-plus-circle':'fa fa-minus-circle'">
+                               </i>
+                               </span>                         
+               </td>
+            <td>
+                               <b>
+                    <label ng-click="onSelectActivityModel($event.target.attributes.data.value)"  data="{{utmModels.name}}" class="models" style="cursor:pointer;width:260px;" id="{{utmModels.name}}" ng-right-click="createSubModel(utmModels)" context-menu="mySubModelContext"> {{utmModels.name}} </label>
+                               </b>
+            </td>    
+                       <td class="td-tree"></td>       
+                       <td class="td-default_value-tree"> </td>        
+               </tr></table>       
+                               <div style="margin-left: 10px"
+                               ng-class="{hidden:showUTMViewModel,chaldean:showUTMViewModel}">
+                                       <div style="margin-left: 10px"
+                                               ng-repeat="utmModels in utmModels.subModels" ng-include="'model_renderer.html'">
+
+                                       </div>
+                               </div>
+               </div>
+               </div>
+</script>
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_model.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_model.html
new file mode 100644 (file)
index 0000000..7af1d59
--- /dev/null
@@ -0,0 +1,61 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="cldsopenmodel" id="configure-widgets">
+       <div attribute-test="cldsopenmodel1" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Open Model</h4>
+       </div>
+       <div attribute-test="cldsopenmodel2" class="modal-body" style="height: 150px">
+               <div style="height: 30px"></div>
+
+       <form name="model" class="form-horizontal">
+                       <div class="form-group">
+                               <label for="modelName" class="col-sm-3 control-label">Model     Name</label>
+                               <div class="col-sm-8">
+                                       <select class="form-control" id="modelName" name="modelName"
+                                                autofocus="autofocus" required ng-trim="true">
+                                               <option ng-repeat="x in modelNamel" value="{{x}}">{{x}}</option>
+                                               </select>
+                                               <div role="alert"><span ng-show="model.modelName.$error.pattern" style="color: red">Special Characters are not allowed in Model name.</span></div>
+                               </div>
+                       </div>
+                       <div class="form-group">
+                               <label for="modelName" class="col-sm-3 control-label">Read Only</label>
+                               <div class="col-sm-8">
+                                       <input type="checkbox" class="form-control" id="readOnly"  name="readOnly"></input>
+                               </div>
+                       </div>
+               </form>
+       </div>
+       <div class="modal-footer">
+
+               <button ng-click="openModel()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern" class="btn btn-primary">OK</button>
+               <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+       </div>
+       <script>
+               
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_template.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/clds_open_template.html
new file mode 100644 (file)
index 0000000..e824a7e
--- /dev/null
@@ -0,0 +1,72 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="cldsopentemplate" id="configure-widgets">
+       <div attribute-test="cldsopentemplate2" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Open Template</h4>
+       </div>
+       <div attribute-test="cldsopentemplate" class="modal-body" style="height: 150px">
+               <div style="height: 30px"></div>
+
+       <form name="model" class="form-horizontal">
+                       <div class="form-group">
+                               <label for="modelName" class="col-sm-3 control-label">Model     Name</label>
+                               <div class="col-sm-8">
+                                       <select class="form-control" id="modelName" name="modelName"
+                                                autofocus="autofocus" required ng-trim="true">
+                                               <option ng-repeat="x in modelNamel" value="{{x}}">{{x}}</option>
+                                               </select>
+                                               <div role="alert"><span ng-show="model.modelName.$error.pattern" style="color: red">Special Characters are not allowed in Model name.</span></div>
+                               </div>
+                       </div>
+               </form>
+       </div>
+       <div class="modal-footer">
+
+               <button ng-click="openTemplate()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern" class="btn btn-primary">OK</button>
+               <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+       </div>
+       <script>
+       
+       /*$.get("/restservices/clds/v1/jaxrsClds/clds/model-names",function(data) {
+               var mySelect = $('#modelName');
+               mySelect.empty();
+               mySelect.append("<option value=''>New Diagram</option>")
+               var map={}
+               for(var i=0;i<data.length;i++){
+                       map[i]=data[i].value
+               }
+               console.log(map)
+               $.each(map, function(val, text) {
+                   mySelect.append(
+                       $('<option></option>').val(text).html(text)
+                   );
+               });
+               
+               console.log(data)
+       })*/
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/confirmation_window.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/confirmation_window.html
new file mode 100644 (file)
index 0000000..67d1ac7
--- /dev/null
@@ -0,0 +1,46 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="confirmationwindow" id="configure-widgets">
+       <div attribute-test="confirmationwindowh" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Create Model</h4>
+       </div>
+       <div attribute-test="confirmationwindowb" class="modal-body" style="height: 150px">
+               <div style="height: 30px"></div>
+
+                       
+                               <label for="modelName" class="col-sm-3 control-label">Close the current activity(Will not be saved)</label>
+                               
+                                       <input type="hidden" class="form-control" id="modelName" name="modelName" ng-value="action">
+                       
+               
+       </div>
+       <div class="modal-footer">
+
+               <button ng-click="closeDiagram()" class="btn btn-primary" ng-disabled="model.modelName.$error.pattern || nameinUse" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" class="btn btn-primary">Cancel</button>
+       </div>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/dashboard.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/dashboard.html
new file mode 100644 (file)
index 0000000..42713c8
--- /dev/null
@@ -0,0 +1,96 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="dashboard" class="container-fluid" style="height: 87vh;">
+
+       <div  attribute-test="dashboard" id="UTMdashboard" style="width: 100%;height:87vh;display:inline-flex;" ng-class="{hidden:testsetgendashboard}">
+               <div style="width: 30%;display:inline;height:87vh;">
+
+                       <div attribute-test="dashboard" class="panel panel-primary" style="height: 87vh">
+                               <div attribute-test="dashboardh" class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span>Project Explorer</span>
+                                               </span> <span class="pull-right" ng-click="showUTMView=!showUTMView"><i
+                                                       ng-class="showUTMView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showUTMView,chaldean:showUTMView}">
+                               <div style="height: 82vh"></div>
+                                               </div>
+                               </div>
+                       </div>
+       
+               <div attribute-test="dashboard" style="width: 70%;margin-left: 1%;">
+
+                       <div class="panel panel-primary" style="height: 87vh">
+                               <div class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span >Modeler</span>
+                                                       
+                                               </span> <span class="pull-right" ng-click="showTDRView=!showTDRView"><i
+                                                       ng-class="showTDRView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showTDRView,chaldean:showTDRView}">
+                                       <div class="panel-body" style="height: 82vh;">
+                                               <div style="height: 82vh"></div>
+                                               </div>
+
+                                       </div>
+                               </div>
+
+                       </div>
+                       
+                       <!-- <div style="width: 20%;margin-left: 1%;margin-right: -12px;">
+
+                       <div class="panel panel-primary" style="height: 87vh">
+                               <div class="panel-heading">
+                                       <div style="color: white;">
+
+                                               <span class="pull-left"> <span>Property Explorer</span>
+                                                       
+                                               </span> <span class="pull-right" ng-click="showTDRView=!showTDRView"><i
+                                                       ng-class="showTDRView == true ?'fa fa-plus-circle':'fa fa-minus-circle'"></i></span>
+                                       </div>
+
+                                       <div class="clearfix"></div>
+                               </div>
+                               <div ng-class="{hidden:showTDRView,chaldean:showTDRView}">
+                                       <div class="panel-body" style="height: 82vh;">
+                                               <div style="height: 82vh"></div>
+                                               </div>
+
+                                       </div>
+                               </div>
+
+                       </div> -->
+
+       </div> 
+       
+       
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/global_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/global_properties.html
new file mode 100644 (file)
index 0000000..e6f20e0
--- /dev/null
@@ -0,0 +1,262 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+ #paramsWarn {
+      display: none;
+}
+</style>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+
+</script>
+
+
+<div id="configure-widgets">
+       <div class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Model Properties</h4>
+       </div>
+       <div class="modal-body" style="height: 280px">
+               <div style="height: 10px"></div>
+               <form id="saveProps" >
+                               <div class="alert alert-danger" role="alert" id='paramsWarn'> 
+                                                       <strong>Ooops!</strong> Unable to load properties for <span id='servName'>. Would you like to</span>
+                                                       <a href="javascript:void(0);" class="btn-link"  id='paramsRetry'>Retry </a> /
+                                                       <a href="javascript:void(0);" class="btn-link" id='paramsCancel'>Cancel</a>
+                                               </div>
+                                               <div>                                   
+                                       
+                                       <div class="form-group clearfix">
+                                               <label for="services" class="col-sm-4 control-label" >Services</label>
+       
+                                               <div class="col-sm-8">
+                                                       <select  class="form-control" 
+                                                               name="service" id="service" >
+<!--                                                            <option ng-repeat="(key, value) in services" value="{{key}}">{{value}}</option>  -->
+                                                       </select>
+                                               </div>
+                                       </div>
+                                       <div class="form-group">
+                                               <label for="vf" class="col-sm-4 control-label">
+                                                       Resource-VF</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="vf" name="vf" >
+
+                                                       </select>
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group">
+                                               <label for="location" class="col-sm-4 control-label">
+                                                       Location</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="location" name="location" multiple size=2>
+
+                                                       </select>
+
+                                               </div>
+                                       </div>
+                               </div>
+
+               </form>
+       <i hidden id="ridinSpinners" class="fa fa-spinner fa-spin" style="display:none;width:100%;text-align:center;font-size:24px;color:black;"></i>
+
+       </div>
+       <div class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button id="savePropsBtn" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+
+       </div>
+  <!-- <select id="vUSP_vfc" disabled hidden></select>
+       <select id="vUSP_location" disabled hidden></select>
+       <select id="vUSP_recipe" disabled hidden></select>
+       <select id="vUSP_vf" disabled hidden></select>
+       
+       <select id="Trinity_vfc" disabled hidden></select>
+       <select id="Trinity_location" disabled hidden></select>
+       <select id="Trinity_recipe" disabled hidden></select>
+       <select id="Trinity_vf" disabled hidden></select>
+       
+       
+       <select id="vSCP_vfc" disabled hidden></select>
+       <select id="vSCP_location" disabled hidden></select>
+       <select id="vSCP_recipe" disabled hidden></select>
+       <select id="vSCP_vf" disabled hidden></select>
+       
+       <select id="vProbes_vfc" disabled hidden></select>
+       <select id="vProbes_location" disabled hidden></select>
+       <select id="vProbes_recipe" disabled hidden></select>   
+       <select id="vProbes_vf" disabled hidden></select>       -->
+       
+
+       <script> 
+//             $.ajax({
+//                     async:false,
+//                 dataType: "json",
+//                 url: '/restservices/clds/v1/jaxrsClds/clds/asdc/services/',
+//                 success: function(data){
+//                     vf_Services=data;
+//                 },
+//                 error:function(s,a,err){
+//                     console.log(err)
+//                     console.log(s)
+//                     console.log(a)
+//                 },
+//                 timeout:100000
+//             });
+//             var services=vf_Services.service
+//             console.log(elementMap["global"])
+//             for(k in services){
+//                     console.log("lol")
+//                     $("#service").append("<option value="+k+">"+services[k]+"</option>")
+//             }
+//             loadSharedPropertyByService()
+//             var el = elementMap["global"];
+//             $("#status").val($("#activity_modeler").text())
+//             if (el !== undefined) {
+//                     for (var i = 0; i < el.length; i++) {
+//                             $("#" + el[i].name).val(el[i].value);
+//                     }
+//             }   
+
+
+      
+
+         (function () {
+                       
+                   var previous;
+                   $("#paramsWarn").hide();
+                   /*Below service method is called for checking the service is being loaded or not*/
+                       loadSharedPropertyByService();
+
+                   $("#service").on('focus', function () {
+                       // Store the current value on focus and on change
+                       previous = this.value;
+                       
+                   }).change(function(){
+                               $("#ridinSpinners").css("display","")
+                               var bool=loadSharedPropertyByService($(this).val())
+                               $("#ridinSpinners").css("display","none")
+                               if(!bool)
+                                       $(this).val(previous)
+                   });
+                       $("#paramsRetry").on('click', function () {
+                               //$("#paramsWarn").hide();
+                               var currentValue = $("#service").val() == null ? previous : $("#service").val();
+                               $("#ridinSpinners").css("display","")
+                               var bool=loadSharedPropertyByService(currentValue);
+                               $("#ridinSpinners").css("display","none")
+                       });
+                       $("#paramsCancel").on('click', function () {
+                               loadSharedPropertyByServiceProperties();
+                               $("#paramsWarn").hide();
+                               
+                       });
+               })();
+//             $("#service").on("change",function(){
+//                     $("#ridinSpinners").css("display","")
+//                     loadSharedPropertyByService($(this).val())
+//                     $("#ridinSpinners").css("display","none")
+//             })
+               function noRepeats(form){
+                       var select={};
+                       for(var i=0;i<form.length;i++){
+                               if(form[i].hasOwnProperty("name")){
+                                               if(select[form[i].name]===undefined)
+                                                       select[form[i].name]=[]
+                                               select[form[i].name].push(form[i].value);
+                                       }
+                       }
+                       var arr=[]
+                       for(s in select){
+                               var f={}
+                               f.name=s
+                               f.value=select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+               
+               $("#saveProps").on('submit', function(event) {
+                       saveGlobalProperties(noRepeats($(this).serializeArray()))
+                       event.preventDefault();
+                       
+                       $("#close_button").click();
+
+               })
+               $("#savePropsBtn").click(function(event) {
+                       //alert($("#CProp_Target").val())
+                       $("#saveProps").submit();
+               })
+
+
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/global_template_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/global_template_properties.html
new file mode 100644 (file)
index 0000000..48a1a75
--- /dev/null
@@ -0,0 +1,167 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+</style>
+
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+</script>
+
+
+<div attribute-test="globaltemplateproperties" id="configure-widgets">
+       <div class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Template Properties</h4>
+       </div>
+       <div class="modal-body" style="height: 280px">
+               <div style="height: 10px"></div>
+               <form id="saveProps" >
+                               <div>
+                                       <div class="form-group">
+                                               <label for="service" class="col-sm-4 control-label"> YAML</label>
+
+                                               <div class="col-sm-8">
+                                                       <textarea  class="form-control" id="service"
+                                                               name="service"></textarea>
+
+                                               </div>
+                                       </div>                                  
+                               </div>
+
+               </form>
+       
+
+       </div>
+       <div class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button id="savePropsBtn" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+
+       </div>
+
+
+       <!-- <select id="vUSP_vfc" disabled hidden></select>
+       <select id="vUSP_location" disabled hidden></select>
+       <select id="vUSP_recipe" disabled hidden></select>
+       <select id="vUSP_vf" disabled hidden></select>
+       
+       <select id="Trinity_vfc" disabled hidden></select>
+       <select id="Trinity_location" disabled hidden></select>
+       <select id="Trinity_recipe" disabled hidden></select>
+       <select id="Trinity_vf" disabled hidden></select>
+       
+       
+       <select id="vSCP_vfc" disabled hidden></select>
+       <select id="vSCP_location" disabled hidden></select>
+       <select id="vSCP_recipe" disabled hidden></select>
+       <select id="vSCP_vf" disabled hidden></select>
+       
+       <select id="vProbes_vfc" disabled hidden></select>
+       <select id="vProbes_location" disabled hidden></select>
+       <select id="vProbes_recipe" disabled hidden></select>   
+       <select id="vProbes_vf" disabled hidden></select>
+ -->
+
+               
+       <script>
+               loadPropertyWindow("global")
+               var el = elementMap["global"];
+               if (el !== undefined) {
+                       for (var i = 0; i < el.length; i++) {
+                               
+                               $("#" + el[i].name).val(el[i].value);
+                       }
+               }
+               function noRepeats(form){
+                       var select={};
+                       for(var i=0;i<form.length;i++){
+                               if(select[form[i].name]===undefined)
+                                       select[form[i].name]=[]
+                               select[form[i].name].push(form[i].value);
+                       }
+                       var arr=[]
+                       for(s in select){
+                               var f={}
+                               f.name=s
+                               f.value=select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+               $("#saveProps").on('submit', function(event) {
+                       saveGlobalProperties(noRepeats($(this).serializeArray()))
+                       event.preventDefault();
+                       
+                       $("#close_button").click();
+
+               })
+               $("#savePropsBtn").click(function(event) {
+                       //alert($("#CProp_Target").val())
+                       $("#saveProps").submit();
+               })
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/refresh_asdc.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/refresh_asdc.html
new file mode 100644 (file)
index 0000000..947e419
--- /dev/null
@@ -0,0 +1,190 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+#paramsWarnrefresh {
+    display: none;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+</style>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+</script>
+
+
+<div attribute-test="refreshasdc" id="configure-widgets">
+       <div attribute-test="refreshasdch" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Model Properties</h4>
+       </div>
+       <div class="modal-body" style="height: 280px">
+               <div style="height: 10px"></div>
+               <div class="alert alert-danger refreshASDC" role="alert" id='paramsWarnrefresh'> 
+                                                       <strong>Ooops!</strong> Unable to load properties for <span id='servName'>. Would you like to</span>
+                                                       <a href="javascript:void(0);" ng-click="paramsRetry();" class="btn-link"  id='paramsRetry'>Retry </a> /
+                                                       <a href="javascript:void(0);" ng-click="paramsCancel();" class="btn-link" id='paramsCancel'>Cancel</a>
+                                               </div>
+               <form id="saveProps" >
+                               <div>                           
+                                       
+                                       <div class="form-group">
+                                               <label for="services" class="col-sm-4 control-label" >Refresh ASDC services?</label>
+       
+                       
+                                       </div>
+                                       
+                               </div>
+
+               </form>
+       <i hidden id="ridinSpinners" class="fa fa-spinner fa-spin" style="display:none;width:100%;text-align:center;font-size:24px;color:black;"></i>
+
+       </div>
+       <div attribute-test="refreshasdcf" class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button ng-click="refreshASDC()" class="btn btn-primary">refresh</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+
+       </div>  
+       <script>
+//             $.ajax({
+//                     async:false,
+//                 dataType: "json",
+//                 url: '/services/clds-designer/v1/jaxrsClds/clds/asdc/services/',
+//                 success: function(data){
+//                     vf_Services=data;
+//                 },
+//                 error:function(s,a,err){
+//                     console.log(err)
+//                     console.log(s)
+//                     console.log(a)
+//                 },
+//                 timeout:100000
+//             });
+//             var services=vf_Services.service
+//             console.log(elementMap["global"])
+//             for(k in services){
+//                     console.log("lol")
+//                     $("#service").append("<option value="+k+">"+services[k]+"</option>")
+//             }
+//             loadSharedPropertyByService()
+//             var el = elementMap["global"];
+//             $("#status").val($("#activity_modeler").text())
+//             if (el !== undefined) {
+//                     for (var i = 0; i < el.length; i++) {
+//                             $("#" + el[i].name).val(el[i].value);
+//                     }
+//             }
+               var previous;
+               (function () {      
+               
+                   $("#service").on('focus', function () {
+                       // Store the current value on focus and on change
+                       previous = this.value;
+                       console.log("hello")
+                   }).change(function(){
+                               $("#ridinSpinners").css("display","")
+                               var bool=loadSharedPropertyByService($(this).val())
+                               $("#ridinSpinners").css("display","none")
+                               if(!bool)
+                                       $(this).val(previous)
+                       });
+
+               })();
+//             $("#service").on("change",function(){
+//                     $("#ridinSpinners").css("display","")
+//                     loadSharedPropertyByService($(this).val())
+//                     $("#ridinSpinners").css("display","none")
+//             })
+               function noRepeats(form){
+                       var select={};
+                       for(var i=0;i<form.length;i++){
+                               if(select[form[i].name]===undefined)
+                                       select[form[i].name]=[]
+                               select[form[i].name].push(form[i].value);
+                       }
+                       var arr=[]
+                       for(s in select){
+                               var f={}
+                               f.name=s
+                               f.value=select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+               
+               $("#saveProps").on('submit', function(event) {
+                       saveGlobalProperties(noRepeats($(this).serializeArray()))
+                       event.preventDefault();
+                       
+                       $("#close_button").click();
+
+               })
+               $("#savePropsBtn").click(function(event) {
+                       //alert($("#CProp_Target").val())
+                       $("#saveProps").submit();
+               })
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/running_instances.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/running_instances.html
new file mode 100644 (file)
index 0000000..1117c16
--- /dev/null
@@ -0,0 +1,67 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+table, th, td {
+   border: 1px solid black;
+   padding:2px 5px 2px 5px;
+   font-size:120%;
+   
+}
+th{
+background-color:#5D99D8;
+}
+tr:nth-child(2n){
+background-color:#D2DDEF;
+}
+</style>
+<div attribute-test="runningInstances" id="configure-widgets">
+
+       <div attribute-test="runningInstancesh" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>Running Instances</h4>
+       </div>
+       <div class="modal-body" style="" align="center">
+               <div style="height: 30px"></div>
+
+                       
+                               <table id="runningTable">
+                               <tr><th>NAME</th><th>LOCATION</th><th>STATUS</th><th>VIEW</th></tr>
+                               
+                               </table>
+                       
+               
+       </div>
+       <div attribute-test="runningInstancesf" class="modal-footer">
+               <button ng-click="close(true)" class="btn btn-primary">Close</button>
+       </div>
+       <script>
+       console.log(runningInstances)
+       for(var key in runningInstances){
+               $("#runningTable").append("<tr><td>"+runningInstances[key].vmName+"</td>"+"<td>"+runningInstances[key].location+"</td>"+"<td>"+runningInstances[key].status+"</td>"+"<td>"+runningInstances[key].view+"</td>");
+       }
+       
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/save_confirmation.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/save_confirmation.html
new file mode 100644 (file)
index 0000000..46ef7de
--- /dev/null
@@ -0,0 +1,36 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="saveconfirmation" id="configure-widgets">
+    <div attribute-test="saveconfirmationh" class="modal-header">
+        <button type="button" class="close" ng-click="close(false)" aria-hidden="true" style="margin-top: -3px">&times;</button>
+        <h4>Create Model</h4>
+    </div>
+    <div class="modal-body" style="height: 150px">
+        Please save your changes before proceeding to your next step.
+    </div>
+    <div attribute-test="saveconfirmationf" class="modal-footer">
+        <button ng-click="Ok()" class="btn btn-primary">Ok</button>
+        <button ng-click="close()" class="btn btn-primary">Cancel</button>
+    </div>
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/stringMatch_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/stringMatch_properties.html
new file mode 100644 (file)
index 0000000..4b5d22b
--- /dev/null
@@ -0,0 +1,585 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+
+.form-group {
+       /*      height:24px; */
+       /*      box-sizing:border-box; */
+       margin-bottom: 20px;
+       
+}
+ #paramsWarn {
+      display: none;
+}
+
+label{text-align:right;
+ padding-top:8px;
+ } 
+
+
+</style>
+
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+               var selectLength =  document.querySelectorAll(".disabled-block-container .tab-close-popup");
+               if(selectLength && selectLength.length>0){
+                       for(var i = 0; i< selectLength.length ; i++){
+                               selectLength[i].disabled = true;
+                       }       
+               }
+                       
+
+
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+</script>
+
+
+<div attribute-test="stringmatchproperties" id="configure-widgets"  class="disabled-block-container">
+       <div attribute-test="stringmatchpropertiesh" class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>String Matching Micro Service</h4>
+       </div>
+       <div attribute-test="stringmatchpropertiesb" class="modal-body">
+       <div class="alert alert-danger" role="alert" id='paramsWarn'> 
+                                                       <strong>Ooops!</strong> Unable to load properties for <span id='servName'>. Would you like to</span>
+                                                       <a href="javascript:void(0);" class="btn-link"  id='paramsRetry'>Retry </a> /
+                                                       <a href="javascript:void(0);" class="btn-link" id='paramsCancel'>Cancel</a>
+                                               </div>
+               <div style="height: 10px"></div>
+               <div class="panel panel-default">
+                       <form id="topicPublish" class="form-horizontal">
+                               <div>
+
+                                       <div class="form-group">
+                                               <label for="userID" class="col-sm-4 control-label"> Topic
+                                                       Publishes</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="topicPublishes"
+                                                               name="topicPublishes">
+                                                       </select>
+                                               </div>
+                                       </div>
+                               </div>
+                       </form>
+                       <div class="panel-heading">
+                               <ul id="nav_Tabs" class="nav nav-tabs">
+                                       <li class><a id="add_one_more" href="#desc_tab"><span
+                                                       class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
+                               </ul>
+                       </div>
+                       <div class="panel-body">
+                               <div class="tab-content">
+                                       <div id="properties_tab" class="tab-pane fade in active"></div>
+
+                               </div>
+
+                       </div>
+               </div>
+               <span id="formSpan" style="display: none">
+                       <form class="saveProps" class="form-horizontal clearfix">
+                               <div>
+                                       <div class="form-group clearfix">
+                                               <label for="aaiMatchingFields" class="col-sm-4 control-label">AAI
+                                                       Fields Matching </label>
+                                               <div class="col-sm-8">
+                                                       <select type="text" class="form-control "
+                                                               name="aaiMatchingFields" id="aaiMatchingFields" multiple="" size=2></select>
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="aaiSendFields" class="col-sm-4 control-label">
+                                                       AAI Fields Send (Select Multiple)</label>
+
+                                               <div class="col-sm-8 ">
+                                                       <select class="form-control"
+                                                               id="aaiSendFields" name="aaiSendFields" multiple size=2>
+
+                                                       </select>
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="groupNumber" class="col-sm-4 control-label">
+                                                       Resource-Group</label>
+
+                                               <div class="col-sm-8">
+                                                       <input type="number" class="form-control" id="groupNumber" name="groupNumber" min="0" >
+
+                                                       </input>
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="vfc" class="col-sm-4 control-label">
+                                                       Resource-VFC</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="vfc" name="vfc">
+
+                                                       </select>
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="alarmCondition" class="col-sm-4 control-label">
+                                                       Alarm Condition</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="alarmCondition"
+                                                               name="alarmCondition"></select>
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="eventSeverity" class="col-sm-4 control-label">
+                                                       Event Severity</label>
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="eventSeverity"
+                                                               name="eventSeverity" enableFilter="false"></select>
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="eventSourceType" class="col-sm-4 control-label">
+                                                       Event Source Type</label>
+                                               <div class="col-sm-8">
+                                                       <input type="text" class="form-control" id="eventSourceType"
+                                                               name="eventSourceType" readOnly  ></input>
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group clearfix">
+                                               <label for="timeWindow" class="col-sm-4 control-label">
+                                                       Time Window</label>
+
+                                               <div class="col-sm-8">
+                                                       <input type="number" min="0" class="form-control" id="timeWindow"
+                                                               name="timeWindow" />
+
+
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="ageLimit" class="col-sm-4 control-label"> Age
+                                                       Limit</label>
+
+                                               <div class="col-sm-8">
+                                                       <input type="number" min="0" class="form-control" id="ageLimit"
+                                                               name="ageLimit" />
+                                               </div>
+                                       </div>
+                                       <div class="form-group clearfix">
+                                               <label for="createClosedLoopEventId"
+                                                       class="col-sm-4 control-label"> Create CL Event ID</label>
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="createClosedLoopEventId"
+                                                               name="createClosedLoopEventId" enableFilter="false">
+                                                       </select>
+
+                                               </div>
+                                       </div>
+
+                                       <div class="form-group clearfix">
+                                               <label for="outputEventName" class="col-sm-4 control-label">
+                                                       Output Event Name</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="outputEventName" 
+                                                               name="outputEventName" enableFilter="false"></select>
+
+                                               </div>
+                                       </div>
+                               </div>
+                       </form>
+               </span>
+       </div>
+
+       <div attribute-test="stringmatchpropertiesf" class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button id="savePropsBtn" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+
+       </div>
+       <script>
+               //Basically this method will add a new form. All forms share the same class. When you want one form to show(active form) the other forms get the 
+               // css attribute display:none
+               $("#paramsRetry").on('click', function () {
+                       $("#paramsWarn").hide();
+                       $("#ridinSpinners").css("display","")
+                       var bool=loadSharedPropertyByService();
+                       $("#ridinSpinners").css("display","none")
+               });
+               $("#paramsCancel").on('click', function () {
+                       loadSharedPropertyByServiceProperties();
+                       $("#paramsWarn").hide();
+                       
+               });
+
+
+
+               $("#add_one_more").click(function(event) {
+                       //alert("lol");
+                       event.preventDefault();
+                       add_one_more();
+                       //I have uncomment the below code becoz there is no refreshItems method.
+                       
+                       //refreshItems();
+                       setMultiSelect();
+       
+               })
+               loadPropertyWindow("string_match")
+               setASDCFields();
+               var arr = elementMap[lastElementSelected];
+               var vfc_temp=""
+               var alarm_conditions_temp=""
+               var event_severity_temp=""
+               var event_type_source_temp=""
+               if (arr !== undefined && arr[1]!==undefined) {
+                       var el = arr[1]['serviceConfigurations']
+                       for (var i = 0; i < el.length; i++) {
+                               var num = add_one_more();
+                               for (var j = 0; j < el[i].length; j++) {
+                                       if (el[i][j]["stringSet"] !== undefined) {
+                                               var ss = el[i][j]["stringSet"]
+                                               for (var o = 0; o < ss.length; o++) {
+                                                       if(ss[o].hasOwnProperty("name")){
+                                                               if(ss[o].name==="alarmCondition"){
+                                                                       alarm_conditions_temp=ss[o].value
+                                                               }else if(ss[o].name==="eventSeverity"){
+                                                                       event_severity_temp=ss[o].value;
+                                                               }else if(ss[o].name==="eventSourceType"){
+                                                                       event_type_source_temp=ss[o].value;
+                                                               }
+                                                               else 
+                                                               $("#formId" + num + " #" + ss[o].name).val(ss[o].value);        
+                                                       }
+                                                       
+                                               }
+                                       }else if(el[i][j].hasOwnProperty("name") && el[i][j].name==="vfc"){
+                                               //alert(el[i][j].value)
+                                               vfc_temp=el[i][j].value
+                                       }
+                                       else {
+                                               if(el[i][j].hasOwnProperty("name")){
+                                                       $("#formId" + num + " #" + el[i][j].name).val(
+                                                                       el[i][j].value);
+                                               }
+                                       }
+                               }
+                               changeTab(num);
+                               set_vfc_alarm_event(num)
+                               vfc_temp=""
+                               alarm_conditions_temp=""
+                               event_severity_temp=""
+                               event_type_source_temp=""
+
+                       }
+                       if(arr[0] &&  arr[0][0] &&  arr[0][0].name){
+                               $("#" + arr[0][0].name).val(arr[0][0].value);
+                       }
+
+               }
+               
+               //this will populate alarmcondition,vfc,eventtypesource if they are saved in elementmap
+               function set_vfc_alarm_event (count){
+                       //alert("lol")
+                       //alert(alarm_conditions_temp)
+                       //alert(alarm_conditions_temp!=="" && alarm_conditions_temp!==undefined)
+                       if(vfc_temp!=="" && vfc_temp!==undefined){
+                               $("#formId"+count+" #vfc").val(vfc_temp)
+                               
+                               if(alarm_conditions_temp!=="" && alarm_conditions_temp!==undefined){
+                                       setAlarmConditions(vfc_temp,count)
+                                       $("#formId"+count+" #alarmCondition").val(alarm_conditions_temp)
+                                       
+                                       if(event_severity_temp!=="" && event_severity_temp!==undefined){
+                                               setEventSourceType(alarm_conditions_temp,count)
+                                               $("#formId"+count+" #eventSeverity").val(event_severity_temp)
+                                               if(event_type_source_temp!=="" && event_type_source_temp!==undefined){
+                                                       $("#formId"+count+" #eventSourceType").val(event_type_source_temp)
+                                               }
+                                       }
+                                       if(event_type_source_temp!=="" && event_type_source_temp!==undefined){
+                                               setEventSourceType(alarm_conditions_temp,count)
+                                               $("#formId"+count+" #eventSourceType").val(event_type_source_temp)
+                                               if(event_severity_temp!=="" && event_severity_temp!==undefined){
+                                                       $("#formId"+count+" #eventSeverity").val(event_severity_temp)
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       
+               }
+               
+               
+               function noRepeats(form) {
+                       var select = {};
+                       for (var i = 0; i < form.length; i++) {
+                               if(form[i].hasOwnProperty("name")){
+                               if (select[form[i].name] === undefined)
+                                       select[form[i].name] = []
+                               select[form[i].name].push(form[i].value);
+                       }
+                       }
+                       var arr = []
+                       for (s in select) {
+                               var f = {}
+                               f.name = s
+                               f.value = select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+               function setStringSet(form) {
+                       var arr = []
+                       var alarmCondition = {}
+                       var eventSeverity = {}
+                       var eventSourceType = {}
+                       for (var i = 0; i < form.length; i++) {
+                               if (form[i].name === "alarmCondition") {
+                                       alarmCondition = form[i]
+                               } else if (form[i].name === "eventSeverity") {
+                                       eventSeverity = form[i];
+                               } else if (form[i].name === "eventSourceType") {
+                                       eventSourceType = form[i];
+                               } else {
+
+                                       arr.push(form[i])
+                               }
+
+                       }
+                       var stringSet = {};
+                       stringSet['stringSet'] = []
+                       stringSet['stringSet'].push(alarmCondition);
+                       stringSet['stringSet'].push(eventSeverity);
+                       stringSet['stringSet'].push(eventSourceType);
+                       arr.push(stringSet)
+
+                       return arr;
+               }
+               $("#savePropsBtn").click(function(event) {
+
+                       var form = []
+                       var properties = $(".saveProps").not("#formSpan .saveProps")
+                       var topicP = $("#topicPublish").serializeArray()
+                       form.push(topicP)
+                       var d = {}
+                       d["serviceConfigurations"] = [];
+
+                       for (var i = 0; i < properties.length; i++) {
+                               var ser = $(properties[i]).serializeArray();
+                               var s = noRepeats(ser)
+                               var newSer = setStringSet(s)
+
+                               d["serviceConfigurations"].push(newSer)
+                       }
+                       form.push(d)
+                       saveProperties(form)
+
+                       $("#close_button").click();
+
+               })
+               
+               
+               
+               
+               
+               function add_one_more() {
+                       $("#nav_Tabs li").removeClass("active");
+                       var form = $($("#formSpan").children()[0]).clone()
+                       var count = 0;
+                       //alert($(".formId").length>0)
+                       if ($(".formId").length > 0) {
+                               var greatest = 0;
+                               var s = $(".formId");
+                               //alert("here1")
+                               for (var i = 0; i < s.length; i++) {
+                                       if (parseInt($(s[i]).attr("id").substring(6)) > greatest) {
+                                               greatest = parseInt($(s[i]).attr("id").substring(6))
+                                       }
+                               }
+                               count = greatest + 1;
+                               //alert(count)
+                               $("#properties_tab").append(
+                                               ('<span class="formId" id="formId'+count+'"></span>'));
+                       } else {
+                               //alert("here2")
+                               count++;
+                               $("#properties_tab").append(
+                                               '<span class="formId" id="formId1"></span>');
+                       }
+                       $("#add_one_more")
+                                       .parent()
+                                       .before(
+                                                       ' <li class="active"><a id="go_properties_tab'+count+'">Condition</a><button id="tab_close'+count+'" type="button" class="close tab-close-popup" aria-hidden="true" style="margin-top: -30px;margin-right: 5px">&times;</button></li>');
+                       $("#formId" + count).append(form);
+                       $(".formId").not($("#formId" + count)).css("display", "none")
+                       addCustListen(count)
+                       addEventNameList(count)
+                       add_vfc_alarm_event_listener(count);
+                       return count;
+               }
+
+               function addCustListen(count) {
+                       $('#go_properties_tab' + count).click(function(event) {
+                               $("#nav_Tabs li").removeClass("active");
+                               $(this).parent().addClass("active");
+                               $("#formId" + count).css("display", "")
+                               $(".formId").not($("#formId" + count)).css("display", "none")
+
+                       })
+                       $('#tab_close' + count).click(function(event) {
+                               if(document.getElementById("topicPublishes").disabled){
+                                       return false;
+                               }
+                               $(this).parent().remove();
+                               $("#formId" + count).remove();
+                       })
+               }
+
+               function changeTab(count){
+                       var output = $('#formId' + count + " #outputEventName");
+                       var group = $('#formId' + count + " #groupNumber");
+                       var outputValue="";
+                       var groupValue="";
+                       if(output.val()!=="")
+                               outputValue=output.val();
+                       if(output.val()!=="" && group.val()!=="")
+                               groupValue=group.val()+":";
+                       else if(group.val()!=="")
+                               groupValue=group.val();
+                       
+                       var tabText="Condition"
+                       if(groupValue+outputValue!=="")
+                               tabText=groupValue+outputValue;
+                       $("#go_properties_tab" + count).text(tabText);  
+               }
+               
+               function addEventNameList(count) {
+                       
+                       $('#formId' + count + " #outputEventName").on('change',function(){changeTab(count)})
+                       $('#formId' + count + " #groupNumber").on('change',function(){changeTab(count)});
+
+               }
+               
+               
+function setAlarmConditions(vfcID, count){
+       var alarmCondition={}
+       
+       if($("#formId"+count+" #vfc").val()!==""){
+               if(vf_Services['shared'] && vf_Services['shared']['byVfc'] && vf_Services['shared']['byVfc'][vfcID]){
+                       alarmCondition=vf_Services['shared']['byVfc'][vfcID]['alarmCondition']  
+               }
+               
+       }
+       
+       $("#formId"+count+" #alarmCondition").empty();
+       $("#formId"+count+" #alarmCondition").append("<option value=\"\"></opton>")
+        if(alarmCondition && _.keys(alarmCondition).length>0){
+               for(key in alarmCondition){
+                       var safestring = $('<div>').text(key).html();
+                       $("#formId"+count+" #alarmCondition").append("<option value='"+safestring+"'>"+alarmCondition[key]+"</opton>")          
+               }
+       }
+}
+
+function setEventSourceType(alarm, count){
+       var eventSourceTypSeverity={}
+       if($("#formId"+count+" #alarmCondition").val()!==""){
+               if(vf_Services && vf_Services['shared'] && vf_Services['shared']['byAlarmCondition'] && vf_Services['shared']['byAlarmCondition'][alarm]){
+                       eventSourceTypSeverity=vf_Services['shared']['byAlarmCondition'][alarm] 
+               }
+               
+       }
+       
+       $("#formId"+count+" #eventSourceType").val(eventSourceTypSeverity.eventSourceType);
+       $("#formId"+count+" #eventSeverity").val(eventSourceTypSeverity.eventSeverity);
+       
+}
+function add_vfc_alarm_event_listener(count) {
+                       
+        $("#formId"+count+" #vfc").on('focus', function () {
+               // Store the current value on focus and on change
+               previous = this.value;
+           }).change(function(){
+                       
+                       setAlarmConditions($("#formId"+count+" #vfc").val(), count);
+                       $("#formId"+count+" #eventSourceType").val("");
+                       $("#formId"+count+" #eventSeverity").val("")
+
+               });
+        
+        $("#formId"+count+" #alarmCondition").on('focus', function () {
+               // Store the current value on focus and on change
+               previous = this.value;
+           }).change(function(){
+                       
+                       
+               setEventSourceType($("#formId"+count+" #alarmCondition").val().toString(),count);
+               });
+               };
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/tca_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/tca_properties.html
new file mode 100644 (file)
index 0000000..c0bbe3b
--- /dev/null
@@ -0,0 +1,392 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<style>
+.fileUpload {
+       position: relative;
+       overflow: hidden;
+       margin: 10px;
+}
+
+.fileUpload input.upload {
+       position: absolute;
+       top: 0;
+       right: 0;
+       margin: 0;
+       padding: 0;
+       font-size: 20px;
+       cursor: pointer;
+       opacity: 0;
+       filter: alpha(opacity = 0);
+       float: left;
+}
+
+.fileDisplay {
+       display: inline-block;
+       overflow: hidden;
+       float: right;
+       margin-left: 0px;
+       z-index: initial;
+       text-align: center;
+       margin-top: 17px;
+}
+
+.form-group {
+       margin-bottom:20px;
+}
+
+</style>
+
+<script type="text/javascript">
+       function disablefile() {
+
+               document.getElementById("fileUpload").disabled = true;
+
+       }
+
+       function disableSVN() {
+               var selectLength =  document.querySelectorAll(".disabled-block-container .tab-close-popup");
+               if(selectLength && selectLength.length>0){
+                       for(var i = 0; i< selectLength.length ; i++){
+                               selectLength[i].disabled = true;
+                       }       
+               }
+       
+               document.getElementById("schemaLocation").disabled = true;
+               document.getElementById("userID").disabled = true;
+               document.getElementById("password").disabled = true;
+
+       }
+</script>
+
+
+<div id="configure-widgets" class="disabled-block-container">
+       <div class="modal-header">
+               <button type="button" class="close" ng-click="close(false)"
+                       aria-hidden="true" style="margin-top: -3px">&times;</button>
+               <h4>TCA Micro Services</h4>
+       </div>
+       <div class="modal-body">
+               <div style="height: 10px"></div>
+               <div class="panel panel-default">
+                       <form id="topicPublish" class="form-horizontal">
+                               <div>
+
+                                       <div class="form-group">
+                                               <label for="userID" class="col-sm-4 control-label"> Topic Publishes</label>
+
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="topicPublishes"
+                                                               name="topicPublishes">
+                                                       </select>
+                                               </div>
+                                       </div>
+                               </div>
+                       </form>
+                       <div class="panel-heading">
+                               <ul id="nav_Tabs" class="nav nav-tabs">
+                                       <li class><a id="add_one_more" href="#desc_tab"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></a></li>
+                               </ul>
+                       </div>
+                       <div class="panel-body">
+                               <div class="tab-content">
+                                       <div id="properties_tab" class="tab-pane fade in active"></div>
+
+                               </div>
+
+                       </div>
+               </div>
+               <span id="formSpan" style="display: none">
+                       <form class="saveProps" class="form-horizontal">
+                               <div>
+
+                                       <div class="form-group">
+                                               <label class="col-sm-4 control-label">Field Path / Counter</label>
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="fieldPath" name="fieldPath"></select>
+                                               </div>
+                                       </div>
+                                       <div class="form-group">
+                                               <label class="col-sm-4 control-label">Threshold</label>
+                                               <div class="col-sm-8">
+                                                       <input type="number" min="0" class="form-control" 
+                                                               name="threshold" id="threshold">
+                                                       </input>
+                                               </div>
+                                       </div>
+                                       
+                                       
+                                       <div class="form-group">
+                                               <label class="col-sm-4 control-label">Operator</label>
+                                               <div class="col-sm-8">
+                                                       <select class="form-control" id="operator" name="operator"></select>
+                                               </div>
+                                       </div>
+                                       
+                                       
+
+                                       <div class="form-group">
+                                               <label class="col-sm-4 control-label">Ops Policy</label>
+
+                                               <div class="col-sm-8">
+                                                       <select  class="form-control" id="opsPolicy" name="opsPolicy" 
+                                                       enableFilter="false" ></select>
+                                               </div>
+                                       </div>
+                               </div>
+
+                       </form>
+               </span>
+       </div>
+
+       <div class="modal-footer">
+               <!--<button ng-click="reset()" class="btn btn-primary" style="float:left">Reset</button>-->
+               <button id="savePropsBtn" class="btn btn-primary">Close</button>
+               <button ng-click="close(true)" id="close_button"
+                       class="btn btn-primary">Cancel</button>
+
+       </div>
+       <script>
+               //Basically this method will add a new form. All forms share the same class. When you want one form to show(active form) the other forms get the 
+               // css attribute display:none
+               $("#add_one_more").click(function(event) {              
+                       event.preventDefault();
+                       add_one_more(); 
+                       setMultiSelect();
+               })
+               loadPropertyWindow("tca")
+               setASDCFields();
+               var arr = elementMap[lastElementSelected];
+               var vfc_temp=""
+               var alarm_conditions_temp=""
+               var event_severity_temp=""
+               var event_type_source_temp=""
+               if (arr !== undefined) {
+                       //arr[0]
+                       var el=arr[1]['serviceConfigurations']
+                       for (var i = 0; i < el.length; i++) {
+                               var num=add_one_more();
+                               for(var j=0;j<el[i].length;j++){
+                                       if(el[i][j].name==="vfc"){
+                                               vfc_temp=el[i][j].value
+                                       }else if(el[i][j].name==="alarmCondition"){
+                                               alarm_conditions_temp=el[i][j].value
+                                       }else if(el[i][j].name==="eventSeverity"){
+                                               event_severity_temp=el[i][j].value;
+                                       }else if(el[i][j].name==="eventSourceType"){
+                                               event_type_source_temp=el[i][j].value;
+                                       }
+                                       else
+                                               $("#formId"+num+" #" + el[i][j].name).val(el[i][j].value);
+                                       
+                                       
+                               }
+                               
+                               set_vfc_alarm_event(num)
+                               vfc_temp=""
+                               alarm_conditions_temp=""
+                               event_severity_temp=""
+                               event_type_source_temp=""
+                               
+                       }
+                       
+                       $("#"+ arr[0][0].name).val(arr[0][0].value);
+                       
+                       
+               }
+
+               function set_vfc_alarm_event (count){
+                       if(vfc_temp!=="" && vfc_temp!==undefined){
+                               $("#formId"+count+" #vfc").val(vfc_temp)
+                               
+                               if(alarm_conditions_temp!=="" && alarm_conditions_temp!==undefined){
+                                       setAlarmConditions(vfc_temp,count)
+                                       $("#formId"+count+" #alarmCondition").val(alarm_conditions_temp)
+
+                                       if(event_severity_temp!=="" && event_severity_temp!==undefined){
+                                               setEventSourceType(alarm_conditions_temp,count)
+                                               $("#formId"+count+" #eventSeverity").val(event_severity_temp)
+                                               if(event_type_source_temp!=="" && event_type_source_temp!==undefined){
+                                                       $("#formId"+count+" #eventSourceType").val(event_type_source_temp)
+                                               }
+                                       }
+                                       if(event_type_source_temp!=="" && event_type_source_temp!==undefined){
+                                               setEventSourceType(alarm_conditions_temp,count)
+                                               $("#formId"+count+" #eventSourceType").val(event_type_source_temp)
+                                               if(event_severity_temp!=="" && event_severity_temp!==undefined){
+                                                       $("#formId"+count+" #eventSeverity").val(event_severity_temp)
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       
+               }
+
+               
+               function noRepeats(form){
+                       var select={};
+                       for(var i=0;i<form.length;i++){
+                               if(select[form[i].name]===undefined)
+                                       select[form[i].name]=[]
+                               select[form[i].name].push(form[i].value);
+                       }
+                       var arr=[]
+                       for(s in select){
+                               var f={}
+                               f.name=s
+                               f.value=select[s]
+                               arr.push(f)
+                       }
+                       return arr
+               }
+       
+               $("#savePropsBtn").click(function(event) {
+                       var form=[]
+                       var properties=$(".saveProps").not("#formSpan .saveProps")
+                       var topicP=$("#topicPublish").serializeArray()
+                       form.push(topicP)
+                       var d={}
+                       d["serviceConfigurations"]=[];
+                       
+                       for(var i=0;i<properties.length;i++){
+                               var ser=$(properties[i]).serializeArray();
+                               var s=noRepeats(ser)
+                               
+
+                               d["serviceConfigurations"].push(s)
+                       }
+                       form.push(d)
+                       saveProperties(form)
+
+                       $("#close_button").click();
+                       
+               })
+               
+               
+               function add_one_more(){
+                       $("#nav_Tabs li").removeClass("active");
+                       var form=$($("#formSpan").children()[0]).clone()
+                       var count=0;
+                       if($(".formId").length>0){
+                               var greatest=0;
+                               var s=$(".formId");
+                               for(var i=0;i<s.length; i++){
+                                       if(parseInt($(s[i]).attr("id").substring(6))>greatest){
+                                               greatest=parseInt($(s[i]).attr("id").substring(6))
+                                       }
+                               }
+                               count=greatest+1;
+                               $("#properties_tab").append(('<span class="formId" id="formId'+count+'"></span>'));
+                       }else{
+                               count++;
+                               $("#properties_tab").append('<span class="formId" id="formId1"></span>');
+                       }
+                       $("#add_one_more").parent().before(' <li class="active"><a id="go_properties_tab'+count+'">Condition</a><button id="tab_close'+count+'" type="button" class="close tab-close-popup" aria-hidden="true" style="margin-top: -30px;margin-right: 5px">&times;</button></li>');
+                       $("#formId"+count).append(form);
+                       $(".formId").not($("#formId"+count)).css("display","none")
+                       addCustListen(count)
+                       add_vfc_alarm_event_listener(count)
+                       return count;
+               }
+
+               function addCustListen(count) {
+                       $('#go_properties_tab' + count).click(function(event) {
+                               $("#nav_Tabs li").removeClass("active");
+                               $(this).parent().addClass("active");
+                               $("#formId"+count).css("display","")
+                               $(".formId").not($("#formId"+count)).css("display","none")
+
+                       })
+                       $('#tab_close'+count).click(function(event){
+                               if(document.getElementById("topicPublishes").disabled){
+                                       return false;
+                               }
+                               $(this).parent().remove();
+                               $("#formId"+count).remove();
+                       })
+               }
+
+function setAlarmConditions(vfcID, count){
+        var alarmCondition={}
+
+        /*if($("#formId"+count+" #vfc").val()!=="")
+                alarmCondition=vf_Services['shared']['byVfc'][vfcID]['alarmCondition']*/
+
+        if($("#formId"+count+" #vfc").val()!==""){
+               if(vf_Services && vf_Services['shared'] && vf_Services['shared']['byVfc'] && vf_Services['shared']['byVfc'][vfcID]){
+                       alarmCondition=vf_Services['shared']['byVfc'][vfcID]['alarmCondition']; 
+               }
+        }
+
+        $("#formId"+count+" #alarmCondition").empty();
+        $("#formId"+count+" #alarmCondition").append("<option value=\"\"></opton>")
+        if(alarmCondition && _.keys(alarmCondition).length>0){
+                       for(key in alarmCondition){
+                               var safestring = $('<div>').text(key).html();
+                               $("#formId"+count+" #alarmCondition").append("<option value='"+safestring+"'>"+alarmCondition[key]+"</opton>")
+
+                   }   
+        }
+        
+}
+
+function setEventSourceType(alarm, count){
+        var eventSourceTypSeverity={}
+        if($("#formId"+count+" #alarmCondition").val()!=="") {
+               if(vf_Services && vf_Services['shared'] && vf_Services['shared']['byAlarmCondition'] && vf_Services['shared']['byAlarmCondition'][alarm]){
+
+                eventSourceTypSeverity=vf_Services['shared']['byAlarmCondition'][alarm]
+               }
+        }
+
+        $("#formId"+count+" #eventSourceType").val(eventSourceTypSeverity.eventSourceType);
+        $("#formId"+count+" #eventSeverity").val(eventSourceTypSeverity.eventSeverity);
+
+}
+
+               function add_vfc_alarm_event_listener(count) {
+                                       
+                        $("#formId"+count+" #vfc").on('focus', function () {
+                               // Store the current value on focus and on change
+                               previous = this.value;
+                           }).change(function(){
+                                       
+                                       setAlarmConditions($("#formId"+count+" #vfc").val(), count);
+                                       $("#formId"+count+" #eventSourceType").val("");
+                                       $("#formId"+count+" #eventSeverity").val("")
+
+                               });
+                        
+                        $("#formId"+count+" #alarmCondition").on('focus', function () {
+                               // Store the current value on focus and on change
+                               previous = this.value;
+                           }).change(function(){
+                                       
+                                       
+                               setEventSourceType($("#formId"+count+" #alarmCondition").val().toString(),count);
+                               });
+                               };
+       </script>
+</div>
+
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/text_area_modal.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/text_area_modal.html
new file mode 100644 (file)
index 0000000..553772b
--- /dev/null
@@ -0,0 +1,38 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<div attribute-test="textAreaModel" id="myModal">
+    <div attribute-test="textAreaModelh" class="modal-header">
+        <button type="button" class="close" ng-click="close(true)" aria-hidden="true" style="margin-top: -3px">&times;</button>
+        <h4>{{textAreaTitle}}</h4>
+    </div>
+    <div attribute-test="textAreaModelb" class="modal-body" style="height: 200px">
+        <textarea focus-me id="mytextarea" ng-model="textAreaModel" style="min-width: 100%; min-height: 100%"></textarea>
+    </div>
+    <div attribute-test="textAreaModelf" class="modal-footer">
+       <button type="button" class="btn btn-primary" ng-click="close(true)">OK</button>
+        <!-- <button type="button" class="btn btn-primary" ng-click="testnotif()">Alert</button> -->
+    </div>
+</div>
+  
+  
diff --git a/src/main/resources/META-INF/resources/designer/scripts/ActivityModellingCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/ActivityModellingCtrl.js
new file mode 100644 (file)
index 0000000..9529ad4
--- /dev/null
@@ -0,0 +1,927 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.directive( "contextMenu", function($compile){
+    console.log("contextMenu");
+    contextMenu = {};
+    contextMenu.restrict = "AE";
+    contextMenu.link = function( lScope, lElem, lAttr ){
+        console.log("link");
+        lElem.on("contextmenu", function (e) {
+            console.log("contextmenu");
+            e.preventDefault(); 
+            lElem.append( $compile( lScope[ lAttr.contextMenu ])(lScope) );
+            $("#contextmenu-node").css("left", e.clientX);
+            $("#contextmenu-node").css("top", e.clientY);            
+        });
+        lElem.on("mouseleave", function(e){
+            console.log("mouseleave");
+            if($("#contextmenu-node") )
+                $("#contextmenu-node").remove();
+        });
+        lElem.on("click", function(e){
+        console.log("click"); 
+            if($("#contextmenu-node") )
+                $("#contextmenu-node").remove();
+        });
+    };
+    return contextMenu;
+});
+
+app.directive('ngRightClick', function($parse) {
+    console.log("ngRightClick");
+    console.log("ngRightClick");
+    return function(scope, element, attrs) {
+        console.log("returnfunction");
+        var fn = $parse(attrs.ngRightClick);
+        element.bind('contextmenu', function(event) {
+            console.log("contextmenu");
+            scope.$apply(function() {
+                console.log("apply");
+                event.preventDefault();
+                fn(scope, {$event:event});
+            });
+        });
+    };
+});
+
+app.directive('inputInfoClass', function ($compile) {
+    console.log("inputInfoClass");
+  return {
+      restrict: "C",
+      replace: true,
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         scope.sourceExplorer = 'AM';
+         angular.forEach(scope.infoType.schemaElements, function(value, key){
+            console.log("schemaElement");
+                 
+                 scope.schemaElement = value;
+                 
+                 if(scope.schemaElement.complexType != null){
+                         if(scope.currentElementName == ''){
+                                 scope.currentElementName = scope.schemaElement.complexType.name;
+                         }
+                         
+                         scope.ParentKey = scope.parentName + '_' + scope.currentElementName;
+                         if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                                 scope.ParentKey = scope.ParentKey + scope.schemaElement.repeatableHierarchicalPrefix; 
+                         }
+                         scope.parElement = scope.schemaElement;
+                         scope.tableStyle = 'table-level' + scope.heirarchyLevel + '-tree'; 
+                         scope.tdLabelStyle = 'td-level' + scope.heirarchyLevel + '-label-tree'; 
+                         scope.heirLevel = scope.heirarchyLevel;
+                         
+                         elementHTML = elementHTML + '<div ng-show="schemaElement.complexType != null">';
+                         elementHTML = elementHTML + '<table class="{{tableStyle}}"> <tr>';
+                         elementHTML = elementHTML + '<td class="{{tdLabelStyle}}">';
+                         elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                         elementHTML = elementHTML + '<i ng-class="showUTMViewMsgHeader == true ?\'fa fa-plus-circle\':\'fa fa-minus-circle\'"></i>';
+                         elementHTML = elementHTML + '</span>';
+                         elementHTML = elementHTML + '<b>{{currentElementName}}</b>';
+                         elementHTML = elementHTML + '</td>';
+                         elementHTML = elementHTML + '<td class="td-tree"></td>';
+                         elementHTML = elementHTML + '<td class="td-tree"></td>';
+                         elementHTML = elementHTML + '<td class="td-tree"></td>';
+                         elementHTML = elementHTML + '<td class="td-blank"></td>';
+                         elementHTML = elementHTML + '<td class="td-default_value-tree"> </td>';
+                         elementHTML = elementHTML + '</tr></table>';
+                         elementHTML = elementHTML + '<div style="margin-left: 10px" ng-class="{hidden:showUTMViewMsgHeader,chaldean:showUTMViewMsgHeader}">';
+                         elementHTML = elementHTML + '<div class="inputInfoClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.elements"></div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         var x = angular.element(elementHTML);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+             });
+         
+      }
+  }
+});
+
+app.directive('inputInfoClassMember', function ($compile, $timeout) {
+    console.log("inputInfoClassMember");
+  return {
+      restrict: "C",
+
+      link: function(scope,element,attrs){
+        console.log("link");
+         
+         var elementHTML = '';
+         
+         scope.currentElementName=scope.objectName;
+         scope.parentName=scope.ParentKey; 
+         scope.parentElement=scope.parElement; 
+         scope.heirarchyLevel = scope.heirLevel + 1;
+         if(scope.schemaElement.element.name != null){
+                 
+                 scope.elementKey=scope.parentName + '_' + scope.schemaElement.element.name;
+                 if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                         scope.elementKey = scope.elementKey + scope.schemaElement.repeatableHierarchicalPrefix;
+                 }
+                 scope.tableStyle='table-level' + scope.heirarchyLevel + '-tree'; 
+                 scope.tdLabelStyle='td-level' + scope.heirarchyLevel +'-label-tree';
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         scope.showUTMViewMsgHeader = false;
+                         
+                 }else{
+                         scope.showUTMViewMsgHeader = true;
+                         if(scope.schemaElement.element.simpleType != null){
+                                 if(scope.schemaElement.element.simpleType.restriction != null){
+                                         if(scope.schemaElement.element.simpleType.restriction.minExclusivesAndMinInclusivesAndMaxExclusives != null){
+                                                 angular.forEach(scope.schemaElement.element.simpleType.restriction.minExclusivesAndMinInclusivesAndMaxExclusives, function(value, key){
+                                                        if(value.name!=null){
+                                                                if((value.name).indexOf('enumeration') > -1){
+                                                                        scope.showUTMViewMsgHeader = false;
+                                                                }
+                                                        }
+                                                 });
+                                         }
+                                 }
+                         }
+                 }
+                 
+                 elementHTML = elementHTML + '<div ng-show="schemaElement.element.name != null">';
+                 elementHTML = elementHTML + '<div id="elementKey">';
+                 elementHTML = elementHTML + '<table class="{{tableStyle}}"> ';
+                 elementHTML = elementHTML + '<tr>';
+                 elementHTML = elementHTML + '<td style="text-align: left;vertical-align: top;" class="{{tdLabelStyle}}">';
+                 elementHTML = elementHTML + '<div ng-mouseover="getContextMenu(schemaElement,elementKey)" context-menu="myContextDiv">';
+                 elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader" ng-style="(schemaElement.type.recursive ||schemaElement.list) && {\'color\':\'#0000FF\'} || {\'color\': \'#444444\'}">';
+                 elementHTML = elementHTML + '<i expandable ng-class="showUTMViewMsgHeader == true ?\'fa fa-minus-circle\':\'fa fa-plus-circle\'"></i>';
+                 elementHTML = elementHTML + '{{schemaElement.element.name}}  ';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '</span>';
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '</td>';
+                 
+                 if(scope.repeatableHeirarchicalElementMap !=null){
+                         elementHTML = elementHTML + '<div ng-if= "repeatableHeirarchicalElementMap !=null">';
+                         elementHTML = elementHTML + '<div ng-if="repeatableHeirarchicalElementMap[elementKey] != null">';
+                         elementHTML = elementHTML + '<div ng-repeat="repeatableElement in repeatableHeirarchicalElementMap[elementKey].repeatableElements">';
+                         elementHTML = elementHTML + '<div ng-init="addRepeatableElement1(schemaElement, parentElement, elementKey, $index)"></div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-repeat="heirarchicalElement in repeatableHeirarchicalElementMap[elementKey].heirarchicalElements">';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-init="addHierarchicalElement1(schemaElement, parentElement, elementKey, $index)"></div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                 }
+                 
+                 elementHTML = elementHTML + '<td class="td-blank"></td>';
+                 elementHTML = elementHTML + '<td style="text-align: right;" class="td-tree">';
+                 if(scope.schemaElement.type.complexType == null){
+                         elementHTML = elementHTML + '<div><input type="checkbox" id="{{elementKey + \'_checkbox\'}}" ng-model="utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked" ng-init="requiredValues[elementKey]=schemaElement.element.minOccurs;utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked=(utmModelSchemaExtension.radioSelection == \'Required Only\' && schemaElement.element.minOccurs !=0) || utmModelSchemaExtension.radioSelection == \'Select All\' || utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].checked" ng-change="onChange()"/></div>'
+                 }
+                 
+                 elementHTML = elementHTML + '</td>';
+                 elementHTML = elementHTML + '<td style="text-align:center;word-wrap: break-word" class="td-default_value-tree"><label id="{{elementKey + \'_label\'}}"/>{{utmModelSchemaExtension.utmSchemaExtentionMap[elementKey].defaultValue}}</td>';
+                 elementHTML = elementHTML + '</tr>';
+                 elementHTML = elementHTML + '</table>';
+                 elementHTML = elementHTML + '<div style="margin-left: 10px" ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">';
+                 
+                 if(scope.schemaElement.type != null && scope.schemaElement.type.restriction != null){
+                         elementHTML = elementHTML + '<div ng-if = "schemaElement.type != null && schemaElement.type.restriction != null">';
+                         elementHTML = elementHTML + '<div ng-repeat="object in filteredObjects = (schemaElement.type.restriction.minExclusivesAndMinInclusivesAndMaxExclusives | filter: {name : \'enumeration\'})">';
+                         elementHTML = elementHTML + '{{object.value.value}}';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                 }
+                 
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '</div>';
+                 
+                 var x = angular.element(elementHTML);
+                element.append(x);
+                $compile(x)(scope);
+                
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         if(scope.schemaElement.repeatableHierarchicalPrefix!=null){
+                         }
+                         var elementHTML2 = '<div ng-show="schemaElement.type.complexType != null">'
+                         elementHTML2 = elementHTML2 + '<div ng-init="parKey=parentName + \'_\' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\'); heirLevel=heirarchyLevel; parElement=schemaElement; ParentKey=ParentKey+\'_\'+schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\');">'
+                         elementHTML2 = elementHTML2 + '<div style="margin-left: 10px" ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">'
+                         if(scope.schemaElement.repeatableHierarchicalPrefix!=null){
+                                 elementHTML2 = elementHTML2 + '<div id="{{parKey}}"></div>'
+                         }else{
+                                 elementHTML2 = elementHTML2 + '<div id="{{parKey}}"></div>'
+                         }
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>';
+                         var x = angular.element(elementHTML2);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+                 
+         }
+         
+      }
+  }
+  
+  
+});
+
+app.directive('expandable', function ($compile) {
+    console.log("expandable");
+  return {
+      restrict: "AE",
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         element.bind("click", function(){
+            console.log("bindclick");
+                //console.log('directive clicked!!!');
+                //console.log(scope.sourceExplorer);
+                //console.log(scope.parKey);
+                
+                var test1 = document.getElementById(scope.parKey);
+                
+                if(test1 != null){
+                        if((test1.getElementsByTagName('div') != null)&&(scope.schemaElement.type.elements != null)){
+                
+                                var htmlCount = test1.getElementsByTagName('div').length;
+                                var schemaElementCount = scope.schemaElement.type.elements.length;
+                                //console.log(htmlCount);
+                                //console.log(schemaElementCount);
+                                
+                                if(htmlCount<schemaElementCount){
+                                        var x = angular.element(test1).append('<div class="inputInfoClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.type.elements" ng-init="currentElementName=schemaElement.element.name;parentName=parKey; parentElement=parElement; heirarchyLevel=heirLevel+1 ;"></div>');
+                                    $compile(x)(angular.element('#'+scope.parKey).scope());
+                                }
+                        }
+                }
+                
+                var cElements = document.getElementsByClassName(scope.sourceExplorer+'_'+scope.parKey);
+                if(cElements != null){
+                        
+                        for(var i=0; i<cElements.length; i++) {
+                                if((cElements[i].getElementsByTagName('div') != null)&&(scope.schemaElement.type.elements != null)){
+                                        var htmlCount = cElements[i].getElementsByTagName('div').length;
+                                var schemaElementCount = scope.schemaElement.type.elements.length;
+                                //console.log(htmlCount);
+                                //console.log(schemaElementCount);
+                                //console.log(cElements[i]);
+                                if(htmlCount<schemaElementCount){
+                                        var x = '';
+                                        if(scope.sourceExplorer=='SDV'){
+                                                x = angular.element(cElements[i]).append('<div class="inputInfoDVClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.type.elements" ng-init="currentElementName=schemaElement.element.name;parentName=parKey; parentElement=parElement; heirarchyLevel=heirLevel+1 ;"></div>');
+                                        }else if(scope.sourceExplorer=='PE'){
+                                                x = angular.element(cElements[i]).append('<div class="inputInfoPropertyClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.type.elements" ng-init="currentElementName=schemaElement.element.name;parentName=parKey; parentElement=parElement; heirarchyLevel=heirLevel+1 ;"></div>');
+                                        }else if(scope.sourceExplorer=='USU'||scope.sourceExplorer=='USC'){
+                                                x = angular.element(cElements[i]).append('<div class="inputInfoUpgradeClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.type.elements" ng-init="currentElementName=schemaElement.element.name;parentName=parKey; parentElement=parElement; heirarchyLevel=heirLevel+1 ;"></div>');
+                                        }
+                                        
+                                    $compile(x)(angular.element('.'+scope.sourceExplorer+'_'+scope.parKey).scope());
+                                }
+                                }
+                        }
+                }
+         });
+      }
+  }
+});
+
+
+app.controller('ActivityModellingCtrl', ['$scope', '$rootScope', '$location','dialogs', '$filter','Datafactory','soapRequestService', function($scope,$rootScope, $location,dialogs,$filter,Datafactory,soapRequestService){
+       
+       console.log("ActivityModellingCtrl");
+       $scope.count=0;
+       $scope.depth=0;
+       $scope.parentElementList=[];
+       $scope.schemaElementKeyMap={};
+       $scope.isVisible = false;
+       $rootScope.countElementKeyMap={};
+       $rootScope.depthElementKeyMap={};
+       $rootScope.isHorR = true;
+       $rootScope.requiredValues = {};
+       
+       $scope.utmModelSchemaExtension = {};
+       $rootScope.repeatableHeirarchicalElementMap = {};
+       
+       
+       
+
+       $rootScope.initProjectExplorer = function () {
+               console.log("initProjectExplorer");
+               if(map_model_repeatable_heirarchical_elements[selected_model] != null) {
+                       $rootScope.repeatableHeirarchicalElementMap = map_model_repeatable_heirarchical_elements[selected_model];
+                       ////console.log("$scope.repeatableHeirarchicalElementMap :: " + $rootScope.repeatableHeirarchicalElementMap);
+               }
+                       
+               
+               ////console.log("$rootScope.utmModelSchemaExtension :: " + JSON.stringify(list_model_schema_extensions[selected_model]));
+               if(list_model_schema_extensions[selected_model] != null) {
+                       $scope.utmModelSchemaExtension = list_model_schema_extensions[selected_model];
+                       if($scope.utmModelSchemaExtension.radioSelection == null || $scope.utmModelSchemaExtension.radioSelection == '')
+                               $scope.utmModelSchemaExtension.radioSelection = 'Required Only';
+               }
+       };
+       
+       $rootScope.initProjectExplorer();
+       
+       $scope.onChange= function(){
+        console.log("onChange");
+               
+               list_model_schema_extensions[selected_model] = $scope.utmModelSchemaExtension;
+               
+       };
+       
+       $rootScope.requiredOnly = function(){
+        console.log("requiredOnly");
+               for (var key in $scope.utmModelSchemaExtension.utmSchemaExtentionMap) {
+                       
+                       ////console.log(key);
+                       
+                       if ($scope.utmModelSchemaExtension.utmSchemaExtentionMap.hasOwnProperty(key)) {                         
+                               //$scope.utmModelSchemaExtension.utmSchemaExtentionMap[key].checked = $scope.utmModelSchemaExtension.radioSelection == "Required Only" && $rootScope.requiredValues[key] != 0;
+                               $scope.utmModelSchemaExtension.utmSchemaExtentionMap[key].checked =  $rootScope.requiredValues[key] != 0;
+                       }
+               }
+               angular.forEach($scope.utmModelSchemaExtension.utmSchemaExtentionMap, function(value, key) {
+            console.log("forEach");
+                         //console.log(key + ': ' + value);
+               });
+       };
+       
+       $rootScope.selectAll = function(){
+        console.log("selectAll");
+               for (var key in $scope.utmModelSchemaExtension.utmSchemaExtentionMap) {
+                       
+                       if ($scope.utmModelSchemaExtension.utmSchemaExtentionMap.hasOwnProperty(key)) {
+                               
+                               $scope.utmModelSchemaExtension.utmSchemaExtentionMap[key].checked = true;
+                               
+                       }
+               }
+       };
+       
+       
+       $rootScope.unSelectAll = function(){
+        console.log("unSelectAll");
+               for (var key in $scope.utmModelSchemaExtension.utmSchemaExtentionMap) {
+                       
+                       if ($scope.utmModelSchemaExtension.utmSchemaExtentionMap.hasOwnProperty(key)) {
+                               
+                               $scope.utmModelSchemaExtension.utmSchemaExtentionMap[key].checked = false;
+                               
+                       }
+               }
+       };
+       
+/*     $scope.generatedXML = function(xmlValue){
+       $scope.generatedXMLVal=xmlValue;
+       var dlg = dialogs.create('partials/portfolios/generatedXML.html','generateXMLCtrl',{},{size:'lg',keyboard: true,backdrop: true,windowClass: 'my-class'});
+               
+    };*/
+       
+       //Functionality for Hierarchical Elements
+       $scope.addHierarchicalElement1 = function(schemaElement, parentElement, elementKey, index){
+        console.log("addHeirarchicalElement1");
+               if($rootScope.isHorR){
+               //console.log("Entering addHeirarchicalElement1");
+               $scope.clonedSchemaElement={};
+               angular.copy(schemaElement, $scope.clonedSchemaElement);
+               
+               if($scope.clonedSchemaElement.repeatableHierarchicalPrefix == null)
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "";
+               
+               //Remove any Heirarchical/Repeatable Elements in the ClonedSchemaElement
+               for(var i=0;i<schemaElement.type.elements.length;i++) {
+                       if(schemaElement.type.elements[i].element.name.indexOf(schemaElement.element.name) != -1) {
+                               $scope.clonedSchemaElement.type.elements.splice(i,(schemaElement.type.elements.length-i));
+                               break;
+                       }
+               }
+               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = (index+1);
+               
+                       schemaElement.type.elements.push($scope.clonedSchemaElement);
+               }
+               
+       }
+       
+       //Functionality for Hierarchical Elements
+       $scope.addHierarchicalElement = function(schemaElement, parentElement, elementKey){
+        console.log("addHierarchicalElement");
+               $rootScope.isHorR = false;
+               $scope.clonedSchemaElement={};
+               angular.copy(schemaElement, $scope.clonedSchemaElement);
+               
+               if($scope.clonedSchemaElement.repeatableHierarchicalPrefix == null)
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "";
+               
+               //Remove any Heirarchical/Repeatable Elements in the ClonedSchemaElement
+               for(var i=0;i<schemaElement.type.elements.length;i++) {
+                       if(schemaElement.type.elements[i].element.name.indexOf(schemaElement.element.name) != -1) {
+                               $scope.clonedSchemaElement.type.elements.splice(i,(schemaElement.type.elements.length-i));
+                               break;
+                       }
+               }
+               
+               schemaElement.type.elements.push($scope.clonedSchemaElement);
+               
+               if(list_model_repeatable_heirarchical_elements[selected_model] == null) {
+                       list_model_repeatable_heirarchical_elements[selected_model] = {};
+                       list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements = [];
+               }
+               
+               if(map_model_repeatable_heirarchical_elements[selected_model] == null)
+                       map_model_repeatable_heirarchical_elements[selected_model] = {};
+               
+               if(map_model_repeatable_heirarchical_elements[selected_model][elementKey] == null) {
+                       $scope.repeatableHeirachicalSchemaElement = {};
+                       $scope.repeatableHeirachicalSchemaElement.elementKey = elementKey;
+                       
+                       var count = list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements.length;
+                       list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements[count] = $scope.repeatableHeirachicalSchemaElement;
+                       
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "1";
+                       $scope.repeatableHeirachicalSchemaElementChild = {};
+                       $scope.repeatableHeirachicalSchemaElementChild.elementKey = elementKey+'_'+ schemaElement.element.name + $scope.clonedSchemaElement.repeatableHierarchicalPrefix;
+                       
+                       $scope.repeatableHeirachicalSchemaElement.heirarchicalElements = [];
+                       $scope.repeatableHeirachicalSchemaElement.heirarchicalElements[0] = $scope.repeatableHeirachicalSchemaElementChild; 
+                       
+                       map_model_repeatable_heirarchical_elements[selected_model][elementKey] = $scope.repeatableHeirachicalSchemaElement;
+                       map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementChild.elementKey] = $scope.repeatableHeirachicalSchemaElementChild;
+               } else {
+                       if(map_model_repeatable_heirarchical_elements[selected_model][elementKey].heirarchicalElements == null) {
+                               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "1";
+                               $scope.repeatableHeirachicalSchemaElementChild = {};
+                               $scope.repeatableHeirachicalSchemaElementChild.elementKey = elementKey+'_'+schemaElement.element.name + $scope.clonedSchemaElement.repeatableHierarchicalPrefix;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].heirarchicalElements = [];
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].heirarchicalElements[0] = $scope.repeatableHeirachicalSchemaElementChild;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementChild.elementKey] = $scope.repeatableHeirachicalSchemaElementChild;
+                       } else {
+                               var count = map_model_repeatable_heirarchical_elements[selected_model][elementKey].heirarchicalElements.length;
+                               
+                               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = ""+(count+1);
+                               $scope.repeatableHeirachicalSchemaElementChild = {};
+                               $scope.repeatableHeirachicalSchemaElementChild.elementKey = elementKey+'_'+schemaElement.element.name + $scope.clonedSchemaElement.repeatableHierarchicalPrefix;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].heirarchicalElements[count] = $scope.repeatableHeirachicalSchemaElementChild;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementChild.elementKey] = $scope.repeatableHeirachicalSchemaElementChild;
+                       }
+               }
+       };
+       
+       $scope.addRepeatableElement1 = function(schemaElement, parentElement, elementKey, index){
+        console.log("addRepeatableElement1");
+               if($rootScope.isHorR == true){
+               $scope.clonedSchemaElement={};
+               angular.copy(schemaElement, $scope.clonedSchemaElement);
+               
+               if($scope.clonedSchemaElement.repeatableHierarchicalPrefix == null)
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "";
+               
+               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = $scope.clonedSchemaElement.repeatableHierarchicalPrefix +"-"+(index+1);               
+               
+               $scope.childElements = {};
+               if(parentElement.type != null && parentElement.type.elements != null) {
+                       $scope.childElements = parentElement.type.elements;
+               } else if (parentElement.elements != null) {
+                       $scope.childElements = parentElement.elements;
+               }
+               
+                       if(schemaElement.type.complexType != null){
+                               for(var i=0;i<$scope.childElements.length;i++){
+                                       if(angular.equals($scope.childElements[i],schemaElement)){      
+                                               //console.log("Complex Element List Match :" +$scope.childElements[i]);
+                                               $scope.childElements.splice((i+1),0,$scope.clonedSchemaElement);
+                                               break;
+                                       }
+                               }
+                       } else if(schemaElement.element.name !=null) {
+                               for(var j=0;j<$scope.childElements.length;j++){
+                                       if(angular.equals($scope.childElements[j],schemaElement)){                              
+                                               //console.log("Element List Match :" +$scope.childElements[j]);                            
+                                               $scope.childElements.splice((j+1),0,$scope.clonedSchemaElement);                          
+                                               break;
+                                       }
+                               }
+                       }
+                       
+               }
+               
+       };
+       
+       $scope.getContextMenu = function(schemaElement,elementKey){
+       console.log("getContextMenu");
+               $scope.myContextDiv ="";
+               if(schemaElement.type.recursive && schemaElement.list){
+                       if(schemaElement.repeatableHierarchicalPrefix != null){
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addHierarchicalElement(schemaElement, parentElement, elementKey)'> Add Hierarchical Element </li><li  class='contextmenu-item'  ng-click='addRepeatableElement(schemaElement, parentElement, elementKey)'> Add Repeatable Element </li><li class='contextmenu-item' ng-click='removeElement(schemaElement, parentElement, elementKey)'>Remove Element</li></ul>";
+                       }else{
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addHierarchicalElement(schemaElement, parentElement, elementKey)'> Add Hierarchical Element </li><li  class='contextmenu-item'  ng-click='addRepeatableElement(schemaElement, parentElement, elementKey)'> Add Repeatable Element </li></ul>";
+                       }                       
+               }else if(schemaElement.type.recursive){
+                       if(schemaElement.repeatableHierarchicalPrefix != null){
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addHierarchicalElement(schemaElement, parentElement, elementKey)'> Add Hierarchical Element </li><li class='contextmenu-item' ng-click='removeElement(schemaElement, parentElement, elementKey)'>Remove Element</li></ul>";
+                       }else{
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addHierarchicalElement(schemaElement, parentElement, elementKey)'> Add Hierarchical Element </li></ul>";
+                       }
+               }else if(schemaElement.list){                   
+                       if(schemaElement.repeatableHierarchicalPrefix != null){
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addRepeatableElement(schemaElement, parentElement, elementKey)'> Add Repeatable Element </li><li class='contextmenu-item' ng-click='removeElement(schemaElement, parentElement, elementKey)'>Remove Element</li></ul>";
+                       }else{
+                               $scope.myContextDiv = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='addRepeatableElement(schemaElement, parentElement, elementKey)'> Add Repeatable Element </li></ul>";
+                       }
+               }else{
+                       $scope.myContextDiv ="";
+               }
+               
+       };
+       
+       $scope.createSubModel = function(utmModels){
+       console.log("createSubModel");          
+               $scope.mySubModelContext ="";
+               console.log("utmModels name::"+utmModels.name);
+               selected_model = utmModels.name ;
+               changecolor(utmModels.name);
+               isModelfrmClick = true;         
+               $scope.mySubModelContext = "<ul id='contextmenu-node' ><li class='contextmenu-item'  ng-click='createModel()'> Add Sub Model</li><li class='contextmenu-item'  ng-click='renameModel()'> Rename Model</li></ul>";
+                       
+       };
+       
+       function changecolor(selected_model){
+               console.log("changecolor");
+               var i = 0;
+           $(".models").each(function(i){
+            console.log("changecolor");
+           var model_value = $(this).text().trim();
+           if(model_value == selected_model || model_value == ""){
+               $(this).addClass("selectedcolor");
+           }else {
+               $(this).removeClass("selectedcolor"); 
+           }  
+              i++; 
+           });
+       };
+               
+       /*$scope.renameModel = function(){
+        console.log("renameModel");
+               
+               console.log("renameModel");
+               
+               var dlg = dialogs.create('partials/portfolios/rename_model.html','CreateModelCtrl',{},{size:'lg',keyboard: true,backdrop: true,windowClass: 'my-class'});
+               dlg.result.then(function(name){ 
+        console.log("dlg.result");                     
+                   
+               },function(){
+                       console.log("...empty");
+               });
+               
+       
+       };*/
+       
+       
+       $scope.addRepeatableElement = function(schemaElement, parentElement, elementKey){ 
+       console.log("addRepeatableElement");            
+               $rootScope.isHorR = false;
+               $scope.clonedSchemaElement={};
+               angular.copy(schemaElement, $scope.clonedSchemaElement);
+
+               if($scope.clonedSchemaElement.repeatableHierarchicalPrefix == null)
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = "";
+               
+               //Remove any Heirarchical/Repeatable Elements in the ClonedSchemaElement
+               if(schemaElement.type.complexType != null){
+               for(var i=0;i<schemaElement.type.elements.length;i++) {
+                       if(schemaElement.type.elements[i].element.name.indexOf(schemaElement.element.name) != -1) {
+                               $scope.clonedSchemaElement.type.elements.splice(i,(schemaElement.type.elements.length-i));
+                               break;
+                       }
+               }
+               }
+               
+               $scope.childElements = {};
+               if(parentElement.type != null && parentElement.type.elements != null) {
+                       $scope.childElements = parentElement.type.elements;
+               } else if (parentElement.elements != null) {
+                       $scope.childElements = parentElement.elements;
+               }
+               
+               if(schemaElement.type.complexType != null){
+                       for(var i=0;i<$scope.childElements.length;i++){
+                               if(angular.equals($scope.childElements[i],schemaElement)){      
+                                       //console.log("Complex Element List Match :" +$scope.childElements[i]);
+                                       $scope.childElements.splice((i+1),0,$scope.clonedSchemaElement);
+                                       break;
+                               }
+                       }
+               } else if(schemaElement.element.name !=null) {                  
+                       for(var j=0;j<$scope.childElements.length;j++){
+                               if(angular.equals($scope.childElements[j],schemaElement)){                              
+                                       //console.log("Element List Match :" +$scope.childElements[j]);                            
+                                       $scope.childElements.splice((j+1),0,$scope.clonedSchemaElement);                          
+                                       break;
+                               }
+                       }
+               }
+               
+               if(list_model_repeatable_heirarchical_elements[selected_model] == null) {
+                       list_model_repeatable_heirarchical_elements[selected_model] = {};
+                       list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements = [];
+               }
+               
+               if(map_model_repeatable_heirarchical_elements[selected_model] == null)
+                       map_model_repeatable_heirarchical_elements[selected_model] = {};
+               
+               if(map_model_repeatable_heirarchical_elements[selected_model][elementKey] == null) {
+                       $scope.repeatableHeirachicalSchemaElement = {};
+                       $scope.repeatableHeirachicalSchemaElement.elementKey = elementKey;
+                       
+                       var count = list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements.length;
+                       list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements[count] = $scope.repeatableHeirachicalSchemaElement;
+
+                       $scope.clonedSchemaElement.repeatableHierarchicalPrefix = $scope.clonedSchemaElement.repeatableHierarchicalPrefix +"-" + 1;
+                       $scope.repeatableHeirachicalSchemaElementClone = {};
+                       $scope.repeatableHeirachicalSchemaElementClone.elementKey = elementKey +  "-" +1;
+                       
+                       $scope.repeatableHeirachicalSchemaElement.repeatableElements = [];
+                       $scope.repeatableHeirachicalSchemaElement.repeatableElements[0] = $scope.repeatableHeirachicalSchemaElementClone; 
+                       
+                       map_model_repeatable_heirarchical_elements[selected_model][elementKey] = $scope.repeatableHeirachicalSchemaElement;
+                       map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementClone.elementKey] = $scope.repeatableHeirachicalSchemaElementClone;
+               } else {
+                       if(map_model_repeatable_heirarchical_elements[selected_model][elementKey].repeatableElements == null) {
+                               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = $scope.clonedSchemaElement.repeatableHierarchicalPrefix+"-"+1;
+                               $scope.repeatableHeirachicalSchemaElementClone = {};
+                               $scope.repeatableHeirachicalSchemaElementClone.elementKey = elementKey + "-" +1;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].repeatableElements = [];
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].repeatableElements[0] = $scope.repeatableHeirachicalSchemaElementClone;
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementClone.elementKey] = $scope.repeatableHeirachicalSchemaElementClone;
+                       } else {
+                               var count = map_model_repeatable_heirarchical_elements[selected_model][elementKey].repeatableElements.length;
+
+                               $scope.clonedSchemaElement.repeatableHierarchicalPrefix = $scope.clonedSchemaElement.repeatableHierarchicalPrefix+"-"+(count+1);
+                               $scope.repeatableHeirachicalSchemaElementClone = {};
+                               $scope.repeatableHeirachicalSchemaElementClone.elementKey = elementKey + "-" + (count+1);
+                               
+                               map_model_repeatable_heirarchical_elements[selected_model][elementKey].repeatableElements[count] = $scope.repeatableHeirachicalSchemaElementClone;                              
+                               map_model_repeatable_heirarchical_elements[selected_model][$scope.repeatableHeirachicalSchemaElementClone.elementKey] = $scope.repeatableHeirachicalSchemaElementClone;
+                       }
+               }
+       };
+       $scope.removeElement = function(schemaElement, parentElement, elementKey){
+        console.log("removeElement");
+               $scope.index =0;                
+               if(parentElement.type != null && parentElement.type.elements != null) {
+                       $scope.childElements = parentElement.type.elements;
+               } else if (parentElement.elements != null) {
+                       $scope.childElements = parentElement.elements;
+               }
+               
+               if(schemaElement.type.complexType != null){
+                       for(var i=0;i<$scope.childElements.length;i++){
+                               if(angular.equals($scope.childElements[i],schemaElement)){      
+                                       //console.log("Complex Element List Match :" +$scope.childElements[i]);
+                                       $scope.childElements.splice(i,1);
+                                       $scope.index =i;
+                                       break;
+                               }
+                       }
+               } else if(schemaElement.element.name !=null) {                  
+                       for(var j=0;j<$scope.childElements.length;j++){
+                               if(angular.equals($scope.childElements[j],schemaElement)){                              
+                                       //console.log("Element List Match :" +$scope.childElements[j]);                            
+                                       $scope.childElements.splice(j,1);       
+                                       $scope.index= j;
+                                       break;
+                               }
+                       }
+               }
+               
+               /*if(parentElement.complexType != null){
+                        var index = parentElement.elements.indexOf(schemaElement);
+                        parentElement.elements.splice(index, 1);  
+               }
+               else{
+                       var index = parentElement.type.elements.indexOf(schemaElement);
+                       parentElement.type.elements.splice(index, 1);   
+               }*/
+               
+               
+               if(list_model_repeatable_heirarchical_elements[selected_model] != null)
+                {
+                       for(var i=0;i<list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements.length;i++){
+                               if(list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements[i].elementKey.indexOf(schemaElement.element.name) > -1){
+                                       $scope.removeRepeatableHeirarchicalMap(selected_model,list_model_repeatable_heirarchical_elements[selected_model].repeatableHeirachicalSchemaElements[i],elementKey);
+                               }
+                       }
+                       
+               }
+                       
+       };      
+       
+       
+       $scope.removeRepeatableHeirarchicalMap= function(modelName,repeatableHeirachicalSchemaElement,elementKey){              
+               console.log("removeRepeatableHeirarchicalMap");
+        //console.log("child element length:"+$scope.childElements.length);
+               $scope.repeatableElements = repeatableHeirachicalSchemaElement.repeatableElements;
+               $scope.heirarchicalElements = repeatableHeirachicalSchemaElement.heirarchicalElements;
+                               
+               for(var j=0;j<$scope.repeatableElements.length;j++) {
+                       if(angular.equals($scope.repeatableElements[j].elementKey,elementKey)){                         
+                               map_model_repeatable_heirarchical_elements[modelName][repeatableHeirachicalSchemaElement.elementKey].repeatableElements.splice(j,1);
+                               break;
+                       }
+                       
+                       if($scope.repeatableElements[j].repeatableElements.length >0 || $scope.repeatableElements[j].heirarchicalElements.length >0 ){
+                               if($scope.heirarchicalElements.length == 0){
+                                       $scope.removeRepeatableHeirarchicalMap(modelName,$scope.repeatableElements[j],elementKey);      
+                               }else{
+                                       
+                                       if($scope.repeatableElements[j].heirarchicalElements.length > 0){
+                                               for(var i=0 ;i<$scope.repeatableElements[j].heirarchicalElements.length;i++){
+                                                       if(angular.equals($scope.repeatableElements[j].heirarchicalElements[i].elementKey,elementKey)){
+                                                               $scope.removeRepeatableHeirarchicalMap(modelName,$scope.repeatableElements[j],elementKey);
+                                                       }
+                                               }
+                                       }
+                                       if($scope.repeatableElements[j].repeatableElements.length > 0){
+                                               for(var q=0 ;q<$scope.repeatableElements[j].repeatableElements.length;q++){
+                                                       if(angular.equals($scope.repeatableElements[j].repeatableElements[q].elementKey,elementKey)){
+                                                               $scope.removeRepeatableHeirarchicalMap(modelName,$scope.repeatableElements[j],elementKey);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }       
+               }       
+               
+               for(var k=0;k<$scope.heirarchicalElements.length;k++) {                 
+                       if(angular.equals($scope.heirarchicalElements[k].elementKey,elementKey)){
+                               var count  = $scope.heirarchicalElements[k].repeatableElements.length;
+                               $scope.childElements.splice($scope.index,count);
+                               map_model_repeatable_heirarchical_elements[modelName][repeatableHeirachicalSchemaElement.elementKey].heirarchicalElements.splice(k,1);
+                               break;
+                       }
+                       $scope.removeRepeatableHeirarchicalMap(modelName,$scope.heirarchicalElements[k],elementKey);
+               }
+               
+       };
+       
+       
+       
+       //Tst functions
+       
+       
+       //Generate and Download tst
+       $scope.generateTST = function(index){
+               console.log("generateTST");
+               Datafactory.setSelectedTestCase($rootScope.modeltestset.activityTestCases[index]);
+               
+               var tstInput={};
+               console.log("inside generateTST() method");
+               var generateTSTUrl ="/utm-service/soa_integration/generateTST";
+               var tempActivityTestcase= {};
+               angular.copy(Datafactory.getSelectedTestCase(),tempActivityTestcase);
+               
+               tstInput.activityTestCase = tempActivityTestcase;
+               
+               if(tstInput.activityTestCase.version != null){
+                       var newTestCaseName = tstInput.activityTestCase.testCaseName + "_"+ tstInput.activityTestCase.version;
+                       tstInput.activityTestCase.testCaseName = newTestCaseName;
+                       
+               }
+                       
+               tstInput.projectPreferenceInfo =  Datafactory.getProjectPreferenceInfo();
+               tstInput.environmentData =  $rootScope.environmentData;
+               tstInput.writeFileToolList=Datafactory.getWriteFileDataList();
+               tstInput.fileStreamWriterList=Datafactory.getFileStreamWriterList();
+               tstInput.commonPythonScriptList = Datafactory.getCommonPythonScriptList();
+               
+               
+               soapRequestService.generateTst(tstInput, generateTSTUrl)
+               .then(function(pars) {
+            console.log("pars");
+                       
+                       
+                       var dlg = dialogs.confirm('Message','Do you want to download TST file?');
+                       dlg.result.then(function(btn){
+                console.log("btn");
+                       $scope.confirmed = 'You confirmed "Yes."';
+                       var downloadTSTUrl ="/utm-service/soa_integration/downloadTST";
+                       
+                       soapRequestService.downloadTst(pars, tstInput.activityTestCase.testCaseName, downloadTSTUrl)
+                       .then(function(results) {
+                console.log("results");
+                               
+                               var sets=results.data;
+                        console.log("Sets value"+sets);            
+                    var headerValue=results.headers;
+                    
+                    var fileName=results.config.data.tstName + ".tst";
+                    console.log("Filename "+fileName);
+                    
+                    var hiddenElement = document.createElement('a');
+                    var objectUrl = URL.createObjectURL(results.data);
+                               
+                            hiddenElement.href = objectUrl;
+                                hiddenElement.download = fileName;
+                                
+                        hiddenElement.target = '_blank';
+                        document.body.appendChild(hiddenElement);
+                        hiddenElement.click(); 
+                        document.body.removeChild(hiddenElement);
+                        
+                       });
+                       },function(btn){
+                console.log("btn");
+                       $scope.confirmed = 'You confirmed "No."';
+                       });
+                       
+               },
+               function(data) {
+            console.log("data");
+
+               });
+               
+               
+       }
+       
+       //Execute and display tst results
+       /*$scope.executeTst = function(index){
+               console.log("executeTst");
+               Datafactory.setSelectedTestCase($rootScope.modeltestset.activityTestCases[index]);
+               
+               var tstInput={};
+               console.log("inside generateTST() method");
+               var executeTSTUrl ="/utm-service/soa_integration/executeTST";
+               var tempActivityTestcase= {};
+               angular.copy(Datafactory.getSelectedTestCase(),tempActivityTestcase);
+               
+               tstInput.activityTestCase = tempActivityTestcase;
+               
+               if(tstInput.activityTestCase.version != null){
+                       var newTestCaseName = tstInput.activityTestCase.testCaseName + "_"+ tstInput.activityTestCase.version;
+                       tstInput.activityTestCase.testCaseName = newTestCaseName;
+                       
+               }
+                       
+               tstInput.projectPreferenceInfo =  Datafactory.getProjectPreferenceInfo();
+               tstInput.environmentData =  $rootScope.environmentData;
+               tstInput.writeFileToolList=Datafactory.getWriteFileDataList();
+               tstInput.fileStreamWriterList=Datafactory.getFileStreamWriterList();
+               tstInput.commonPythonScriptList = Datafactory.getCommonPythonScriptList();
+               
+               
+               soapRequestService.generateTst(tstInput, executeTSTUrl)
+               .then(function(pars) {
+            console.log("pars");
+                       
+                       if(pars != null || pars != undefined){
+                       
+                       Datafactory.setExecuteResultset(pars);
+                       
+                       var dlg = dialogs.create('partials/SOA/execute-request.html','executeRequestCtrl',{},{size:'lg',keyboard: true,backdrop: true,windowClass: 'my-class'});
+                       }
+                       else{
+                               dialogs.error("Some error occured during execution of tst file");
+                       }
+                               
+                       
+                       });
+                       
+               
+               
+               
+       }*/
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/AlertService.js b/src/main/resources/META-INF/resources/designer/scripts/AlertService.js
new file mode 100644 (file)
index 0000000..fb791da
--- /dev/null
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('alertService', [function () {
+       console.log("/////////////alertService");
+       this.alertMessage=function(msg,typeNumber){
+               var typeMessage="";
+               switch(typeNumber){
+                       case 1:
+                               typeMessage="success";
+                               break;
+                       case 2:
+                               typeMessage="info";
+                               break;
+                       case 3:
+                               typeMessage="warning";
+                               break;
+                       case 4:
+                               typeMessage="danger";
+                               break;
+                       default:
+                               typeMessage="info";
+               }
+               $("#activity_modeler").prepend('<div id="alert_message_" style="postion:absolute;left:25;width:50%;" class="alert alert-'+typeMessage+'">'+msg+'</div>')
+               setTimeout(function(){
+               console.log("setTimeout");
+                $("#alert_message_").slideUp(500);}, 3000);
+
+               
+       }
+ }]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/AutosaveProjectCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/AutosaveProjectCtrl.js
new file mode 100644 (file)
index 0000000..02297d7
--- /dev/null
@@ -0,0 +1,125 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+function AutosaveProject($scope,$rootScope,$resource, $http, $timeout, $location, $interval, $q, Datafactory) 
+{      
+    console.log("//////////Autosaveproject");  
+       $scope.saveProjectToUrl = function(UTMMDTProject,svnUploadURL){
+           console.log("saveProjectURL");   
+       console.log('Autosaveproject Enter == ' + new Date().getTime());
+       console.log(new Date());
+       var def = $q.defer();
+       
+        $http.post(svnUploadURL, UTMMDTProject)
+        .success(function(data){ 
+        console.log("success");        
+               def.resolve(data);
+        })
+        .error(function(data){ 
+        console.log("error");                        
+                       def.reject("Autosave unsuccessful");
+        });
+        
+        return def.promise;        
+       
+    };
+       
+       $scope.autosave = function(){
+               console.log("autosave");
+               
+               var saveProjectURL = "/utm-service/project_administration/autoSaveProject";
+               
+               var UTMProjectExplorer = {};
+               UTMProjectExplorer.projectName = $rootScope.projectName;
+               UTMProjectExplorer.utmModels = $rootScope.utmModels;
+               UTMProjectExplorer.revision = autoSaveRevision;
+               UTMProjectExplorer.utmDepthValueMap = $rootScope.depthElementKeyMap;
+               UTMProjectExplorer.utmCountValueMap = $rootScope.countElementKeyMap;
+
+               var utm_models = [];
+               $rootScope.populateUTMModelArray(utm_models,$rootScope.utmModels);                      
+                                                                               
+               var UTMMDTProject = {};
+               UTMMDTProject.utmProjectExplorer = UTMProjectExplorer;
+               UTMMDTProject.utmModels = utm_models;           
+               UTMMDTProject.almqcdata = $rootScope.almqcData;         
+               UTMMDTProject.wsdlInfo = null;
+               UTMMDTProject.schemaLocation = null;
+               
+               if ($rootScope.wsdlInfo != null) {
+                       UTMMDTProject.schemaLocation = $rootScope.wsdlInfo.schemaLocation;
+                       UTMMDTProject.oldSchemaLocation = $rootScope.wsdlInfo.oldSchemaLocation;
+                       UTMMDTProject.schemaUpgradedFlag = $rootScope.wsdlInfo.schemaUpgradedFlag;
+               }
+
+               UTMMDTProject.revision=$rootScope.revision;
+               console.log(UTMMDTProject.revision);
+               
+               UTMMDTProject.checkOutPath=$rootScope.checkOutPath;
+               UTMMDTProject.oldNewModelNameMap = old_new_model_name;          
+               UTMMDTProject.automationDetails={};
+               
+               UTMMDTProject.automationDetails.projectPreferenceInfo =  Datafactory.getProjectPreferenceInfo();
+               UTMMDTProject.automationDetails.environmentData =  $rootScope.environmentData;
+               UTMMDTProject.automationDetails.pythonScriptList =  Datafactory.getCommonPythonScriptList();
+               UTMMDTProject.automationDetails.dbToolRequestList =  Datafactory.getDbToolProjectLevelList();                                   
+               UTMMDTProject.automationDetails.runtimePythonScriptList =  Datafactory.getRuntimePythonScriptProjectLevelList();
+               UTMMDTProject.automationDetails.xmlValidatorList =  Datafactory.getXmlValidatorList();
+               UTMMDTProject.automationDetails.fileWriterList =  Datafactory.getWriteFileDataList();
+               UTMMDTProject.automationDetails.fileStreamWriterList =  Datafactory.getFileStreamWriterList();
+               
+               
+               
+               if($rootScope.openedProject != null){
+                       console.log('opened project...')                        
+                       var existingData = JSON.stringify($rootScope.openedProject);
+                       var currentgData = JSON.stringify(UTMMDTProject);                       
+                       if(angular.equals(existingData, currentgData)){
+                               //do nothing
+                               console.log('No changes found.');
+                       }else{
+                               console.log('Changes found.');
+                               $scope.saveProjectToUrl(UTMMDTProject,saveProjectURL)
+                               .then(function(pars) {  
+                               console.log("");                                
+                               },
+                               function(data) {
+                                       
+                               });
+                       }
+                       
+               }else{
+                       console.log('autosaving project...')
+                       $scope.saveProjectToUrl(UTMMDTProject,saveProjectURL)
+                       .then(function(pars) {
+                               
+                       },
+                       function(data) {
+                               
+                       });
+               }               
+               
+       }
+       
+       $scope.autosave();
+}
diff --git a/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js b/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js
new file mode 100644 (file)
index 0000000..c0d4f8a
--- /dev/null
@@ -0,0 +1,326 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('cldsModelService', ['alertService','$http', '$q', function (alertService,$http, $q) {
+       console.log("/////////////cldsModelService");
+       function checkIfElementType(name){
+
+               //This will open the methods located in the app.js
+               if(name.toLowerCase().indexOf("stringmatch")>=0)
+                       StringMatchWindow();
+               else if(name.toLowerCase().indexOf("tca")>=0)
+                       TCAWindow();
+               else if(name.toLowerCase().indexOf("collector")>=0)
+                       CollectorsWindow();
+               else if(name.toLowerCase().indexOf("policy")>=0)
+                       PolicyWindow();
+               
+       }
+       this.getASDCServices = function(){
+       
+       console.log("getASDCServices");
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/clds/asdc/services/";                
+       
+        $http.get(svcUrl)
+        .success(function(data){               
+               def.resolve(data);   
+               
+               
+        })
+        .error(function(data){                       
+                       def.reject("Asdc Services not found");
+                       
+        });
+        
+        return def.promise;
+    };
+    
+    this.getRunningInstances=function(resouseInput){
+      console.log("getRunningInstances");
+       var def = $q.defer();
+       var sets = [];
+       
+       //Look in scripts/common_variables.html to get utmModel name
+       
+    // var svcUrl = "/restservices/clds/v1/clds/model/roncl003";                
+       var svcUrl = "/restservices/clds/v1/clds/model/" + resouseInput;                
+       
+       $http.get(svcUrl)
+       .success(function(data){                
+               def.resolve(data);   
+               
+               
+       })
+       .error(function(data){                        
+               def.reject("Asdc Services not found");
+               
+       });
+        
+       return def.promise;
+       
+       // return [{"name":"asbg0003vm001","location":"SNANTXCA","status":"Running","view":"KPI"},{"name":"asbg0003vm002","location":"SNANTXCA","status":"Running","view":"KPI"},{"name":"asbg0003vm003","location":"SNANTXCA","status":"Running","view":"KPI"},{"name":"asbg0003vm004","location":"SNANTXCA","status":"Stopped","view":"KPI"}]
+    }
+    
+this.getASDCService = function(uuid){
+       console.log("getASDCService");
+       
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/clds/asdc/services/" + uuid;                
+       
+        $http.get(svcUrl)
+        .success(function(data){   
+               def.resolve(data);              
+               
+        })
+        .error(function(data){                       
+                       def.reject("ASDC service not found");
+        });
+        
+        return def.promise;
+    };
+    this.getModel = function(modelName){
+       
+       console.log("getModel");
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/clds/model/" + modelName;                
+       
+        $http.get(svcUrl)
+        .success(function(data){               
+               def.resolve(data);              
+               
+        })
+        .error(function(data){                       
+                       def.reject("Open Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.getSavedModel=function(){
+      console.log("getSavedModel");
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/clds/model-names";                
+       
+        $http.get(svcUrl)
+        .success(function(data){               
+               def.resolve(data);              
+               
+        })
+        .error(function(data){                       
+                       def.reject("Open Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.setModel = function(modelName, controlNamePrefixIn, bpmnTextIn, propTextIn){
+       
+       console.log("setModel");
+       var def = $q.defer();
+       var sets = [];
+
+       var svcUrl = "/restservices/clds/v1/clds/model/" + modelName;        
+        var svcRequest = {name: modelName, controlNamePrefix: controlNamePrefixIn, bpmnText: bpmnTextIn, propText: propTextIn};
+        
+       
+        $http.put(svcUrl, svcRequest)
+        .success(function(data){               
+               def.resolve(data);              
+               
+        })
+        .error(function(data){                       
+                       def.reject("Save Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.processAction = function(uiAction, modelName, controlNamePrefixIn, bpmnTextIn, propTextIn,svgXmlIn,templateName){
+       
+       console.log("processAction");
+       var def = $q.defer();
+       var sets = [];
+       console.log("Generated SVG xml File...");
+       //console.log(svgXmlIn);
+       var svcUrl = "/restservices/clds/v1/clds/";        
+       var svcAction = uiAction.toLowerCase();
+       if ( svcAction == "save" || svcAction == "refresh" ) {
+               svcUrl = svcUrl + "model/" + modelName;
+       } else if ( svcAction == "test" ) {
+               svcUrl = svcUrl + "action/submit/" + modelName + "?test=true";
+       } else {
+               svcUrl = svcUrl + "action/" + svcAction + "/" + modelName;
+       }
+       
+        var svcRequest = {name: modelName, controlNamePrefix: controlNamePrefixIn, bpmnText: bpmnTextIn, propText: propTextIn, imageText:svgXmlIn, templateName:templateName};      
+       console.log(svcRequest)
+        $http.put(svcUrl, svcRequest)
+        .success(function(data){
+               def.resolve(data);   
+          alertService.alertMessage("Action Successful:"+uiAction,1)           
+               
+        })
+        .error(function(data){  
+               alertService.alertMessage("Action Failure:"+uiAction,2);
+                       //def           alertService.alertMessage("Action Successful:"+uiAction,1);
+                       def.reject(svcAction + " not successful");
+        });
+        
+        return def.promise;
+    };
+    this.checkPermittedActionCd = function(permittedActionCd, menuText, actionCd){
+      console.log("checkPermittedActionCd");
+               if ( permittedActionCd.indexOf(actionCd) > -1 ) {
+                       document.getElementById(menuText).classList.remove('ThisLink');
+               } else {
+                       document.getElementById(menuText).classList.add('ThisLink');
+               }
+    };        
+    this.processActionResponse = function(modelName, pars){
+      console.log("processActionResponse");
+       // populate control name (prefix and uuid here)
+               var controlNamePrefix = pars.controlNamePrefix;
+               var controlNameUuid = pars.controlNameUuid;
+               
+       
+        
+        var headerText = "Closed Loop Modeler - " + modelName;
+        if ( controlNameUuid != null ) {
+               var actionCd = pars.event.actionCd;
+               var actionStateCd = pars.event.actionStateCd;
+               //headerText = headerText + " [" + controlNamePrefix + controlNameUuid + "] [" + actionCd + ":" + actionStateCd + "]";
+               headerText = headerText + " [" + controlNamePrefix + controlNameUuid + "]";
+               console.log("MINA PARS TEST " + headerText + " ----- " + controlNamePrefix + " ----- " + controlNameUuid + "  ----- " + pars);
+        }
+               
+       document.getElementById("modeler_name").textContent = headerText;
+       setStatus(pars)
+       disableBPMNAddSVG(pars);
+        this.enableDisableMenuOptions(pars);
+               
+               
+    };
+    
+    this.processRefresh=function(pars){
+      console.log("processRefresh");
+       setStatus(pars);
+    }
+    function setStatus(pars){
+      console.log("setStatus");
+       var status = pars.status;
+       // apply color to status
+               var statusColor='white';
+               if(status.trim()==="DESIGN"){
+                       statusColor='gray'
+               } else if(status.trim()==="DISTRIBUTED"){
+                       statusColor='blue'
+               } else if(status.trim()==="ACTIVE"){
+                       statusColor='green'
+               } else if(status.trim()==="STOPPED"){
+                       statusColor='red'
+               } else if(status.trim()==="DELETING"){
+                       statusColor='pink'
+               } else if(status.trim()==="ERROR"){
+                       statusColor='orange'
+               } else if(status.trim()==="UNKNOWN"){
+                       statusColor='blue'
+               } else{
+                       statusColor=null;
+               }
+               
+
+               var statusMsg='<span style="background-color:' + statusColor + ';-moz-border-radius: 50px;      -webkit-border-radius: 50px;    border-radius: 50px;">&nbsp;&nbsp;&nbsp;'+status+'&nbsp;&nbsp;&nbsp;</span>';
+               // display status
+               if ($("#status_clds").length>=1)
+                       $("#status_clds").remove();
+               $("#activity_modeler").append('<span id="status_clds" style="position: absolute;  left: 61%;top: 51px; font-size:20px;">Status: '+statusMsg+'</span>');
+
+               
+    }
+    function disableBPMNAddSVG(pars){
+      console.log("disableBPMNAddSVG");
+       var svg=pars.imageText.substring(pars.imageText.indexOf("<svg"))
+       if($("#svgContainer").length>0)
+                       $("#svgContainer").remove();
+               $("#js-canvas").append("<span id=\"svgContainer\">"+svg+"</span>");
+        /* added code for height width viewBox */
+        $("#svgContainer svg").removeAttr("height");
+        $("#svgContainer svg").removeAttr('viewBox');
+        $("#svgContainer svg").removeAttr('width');
+        
+        $("#svgContainer svg").attr('width','100%');
+        $("#svgContainer svg").attr('height','100%');
+
+               $("#svgContainer").click(function(event){
+                       console.log($(event.target).parent().html())
+                       console.log($($(event.target).parent()).attr("data-element-id"))
+                       var name=$($(event.target).parent()).attr("data-element-id")
+                       lastElementSelected=$($(event.target).parent()).attr("data-element-id")
+                       checkIfElementType(name)
+                       
+               })
+        $(".bjs-container").attr("hidden","");
+    }
+    this.enableDisableMenuOptions=function(pars){
+      console.log("enableDisableMenuOptions");
+       var permittedActionCd = pars.permittedActionCd;
+       // enable menu options
+       document.getElementById('Save CL').classList.remove('ThisLink');
+       document.getElementById('Test').classList.remove('ThisLink');
+       document.getElementById('Properties CL').classList.remove('ThisLink');
+       document.getElementById('Refresh Status').classList.remove('ThisLink');
+       document.getElementById('Revert Model Changes').classList.remove('ThisLink');
+       document.getElementById('Close Model').classList.remove('ThisLink');
+       document.getElementById('Refresh ASDC').classList.remove('ThisLink');
+       document.getElementById('Running Instances').classList.remove('ThisLink');
+       
+       //disable template options for save/properties
+       document.getElementById('Save Template').classList.add('ThisLink');
+       document.getElementById('Template Properties').classList.add('ThisLink');
+       document.getElementById('Revert Template Changes').classList.add('ThisLink');
+       document.getElementById('Close Template').classList.add('ThisLink');
+
+       
+               // enable/disable menu options based on permittedActionCd list
+               this.checkPermittedActionCd(permittedActionCd, 'Submit', 'SUBMIT');
+               this.checkPermittedActionCd(permittedActionCd, 'Resubmit', 'RESUBMIT');
+               this.checkPermittedActionCd(permittedActionCd, 'Update', 'UPDATE');
+               this.checkPermittedActionCd(permittedActionCd, 'Delete', 'DELETE');
+               this.checkPermittedActionCd(permittedActionCd, 'Stop', 'STOP');
+               this.checkPermittedActionCd(permittedActionCd, 'Restart', 'RESTART');
+    }
+    
+   
+    this.getASDCServices().then(function(pars){
+      console.log("getASDCServices");
+       var services=pars.service;
+       asdc_Services=services
+    });
+    
+ }]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/CldsOpenModelCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/CldsOpenModelCtrl.js
new file mode 100644 (file)
index 0000000..d58dcb9
--- /dev/null
@@ -0,0 +1,366 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('CldsOpenModelCtrl',
+       ['$scope', '$rootScope', '$modalInstance','cldsModelService', '$location', 'dialogs','cldsTemplateService',
+               function($scope, $rootScope, $modalInstance, cldsModelService, $location,dialogs,cldsTemplateService) {
+                       console.log("/////////CldsOpenModelCtrl");
+                       $scope.typeModel='template';
+                       $scope.error = {
+                               flag : false,
+                               message: ""
+                       };      
+                       
+                       cldsModelService.getSavedModel().then(function(pars) {
+                               
+                               $scope.modelNamel=[]
+                               for(var i=0;i<pars.length;i++){
+                                       $scope.modelNamel.push(pars[i].value);           
+                               }
+                               setTimeout(function(){
+                       console.log("setTimeout");
+
+                    setMultiSelect(); }, 100);
+                               
+                       });
+
+                       $scope.paramsRetry = function() {
+                               //$("#paramsWarn").hide();
+                               var currentValue = $("#service").val() == null ? previous : $("#service").val();
+                               $("#ridinSpinners").css("display","")
+                               loadSharedPropertyByService(currentValue,true,callBack);
+                               $("#ridinSpinners").css("display","none")
+                       };
+                        $scope.paramsCancel =function() {
+                               loadSharedPropertyByServiceProperties(callBack);
+                               $("#paramsWarnrefresh").hide();
+                               
+                       };
+
+                       function completeClose(){
+                                       //if(flag)      {
+                                               $scope.close();
+                                       //}
+                               }
+                       
+                       function callBack(flag){
+                                       if(flag)        {
+                                               $scope.close();
+                                       }
+                               }
+                       $scope.refreshASDC=function(){
+                               console.log("refreshASDC");
+                               $("#ridinSpinners").css("display","")
+                               var bool=loadSharedPropertyByService(undefined,true,callBack);
+                               $("#ridinSpinners").css("display","none");
+                               
+                               
+                       }
+                       
+                       cldsTemplateService.getSavedTemplate().then(function(pars) {
+
+                               
+                               $scope.templateNamel=[]
+                               for(var i=0;i<pars.length;i++){
+                                       $scope.templateNamel.push(pars[i].value);
+                                       
+                               }
+                               
+                       });
+                       function contains(a, obj) {
+                               console.log("contains");
+                           var i = a&& a.length>0 ? a.length : 0;
+                           while (i--) {
+                              if (a[i].toLowerCase() === obj.toLowerCase()) {
+                                  return true;
+                              }
+                           }
+                           return false;
+                       }
+                       $scope.checkExisting=function(){
+                               console.log("checkExisting");
+                               var name = $('#modelName').val();                                                               
+                               if(contains($scope.modelNamel,name)){
+                                       $scope.nameinUse=true;
+                               }else{
+                                       $scope.nameinUse=false;
+                               }
+                               specialCharacters();
+                       }
+                        function specialCharacters (){
+                               console.log("specialCharacters");
+                               $scope.spcl = false;
+                               if(angular.element("#modelName") && 
+                                       angular.element("#modelName").scope().model.$error.pattern && 
+                                       angular.element("#modelName").scope().model.$error.pattern.length>0){
+                                       $scope.spcl =  true;
+                               }
+                       }
+
+                       $scope.setTypeModel=function(_type){
+                               $scope.error.flag = false;
+                               console.log("setTypeModel");
+                               $scope.typeModel=_type;
+                       }
+                       
+                       $scope.close = function(){
+                               console.log("close");
+                               $rootScope.isNewClosed = false;
+                               $modalInstance.close("closed");
+                       };
+                       $scope.createNewModelOffTemplate=function(formModel){
+                               console.log("createNewModelOffTemplate");
+                               console.log(formModel);
+                               reloadDefaultVariables(false)
+                               var modelName = document.getElementById("modelName").value;
+                               var templateName=document.getElementById("templateName").value;
+                               console.log("openModel: modelName=" + modelName);      
+                               console.log("Template: templateName=" + templateName); 
+                               if(!modelName){
+                                       $scope.error.flag =true;
+                                       $scope.error.message = "Please enter any closed template name for proceeding";
+                                   return false;
+                               }
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+
+                               cldsTemplateService.getTemplate( templateName ).then(function(pars) {
+                               console.log("openModel: pars=" + pars);
+                               
+                               var tempImageText=pars.imageText
+                               var bpmnText=pars.bpmnText
+                               pars={}
+                               
+                               pars.imageText=tempImageText
+                               pars.status= "DESIGN";
+                               pars.permittedActionCd= ["SUBMIT"];
+                               cldsModelService.processActionResponse(modelName, pars);
+                               
+                               
+                               selected_template= templateName
+                               selected_model = modelName;
+                               
+                               // set model bpmn and open diagram
+                               $rootScope.isPalette = true;
+                               modelXML = bpmnText;
+                               visibility_model();
+                       },
+                       function(data) {
+                               //alert("getModel failed");
+                       });
+       
+                               $modalInstance.close("closed");
+                       
+                       }
+                       
+                       $scope.cloneModel=function(){
+                               console.log("cloneModel");
+                               reloadDefaultVariables(false)
+                               var modelName = document.getElementById("modelName").value;
+                               var originalModel=document.getElementById("modelList").value;
+                               console.log("openModel: modelName=" + modelName);   
+                               if(!modelName){
+                                       $scope.error.flag =true;
+                                       $scope.error.message = "Please enter any name for proceeding";
+                                   return false;
+                               }   
+                               
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+
+                               cldsModelService.getModel( originalModel ).then(function(pars) {
+                               console.log("openModel: pars=" + pars);
+                               
+                               // process data returned
+                               var bpmnText = pars.bpmnText;
+                               var propText = pars.propText;
+                               var status = pars.status;
+                               var controlNamePrefix = pars.controlNamePrefix;
+                               var controlNameUuid = pars.controlNameUuid;
+                               selected_template=pars.templateName;
+                               pars.status="DESIGN";
+                               pars.controlNameUuid="";
+                               cldsModelService.processActionResponse(modelName, pars);
+                               
+                               // deserialize model properties
+                               if ( propText == null ) {
+                               console.log("openModel: propText is null");
+                               } else {
+                               console.log("openModel: propText=" + propText);
+                                       elementMap =  JSON.parse(propText);
+                               }
+
+                               selected_model = modelName;
+                               
+                               // set model bpmn and open diagram
+                               $rootScope.isPalette = true;
+                               modelXML = bpmnText;
+                               visibility_model();
+                       },
+                       function(data) {
+                               //alert("getModel failed");
+                       });
+       
+                               $modalInstance.close("closed");
+                       }
+                       $scope.createNewModel=function(){
+                               console.log("createNewModel");
+                               reloadDefaultVariables(false)
+                               var modelName = document.getElementById("modelName").value;
+                               console.log("openModel: modelName=" + modelName);      
+                               
+                               // BEGIN env
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+                       // enable appropriate menu options
+                       var pars = {status: "DESIGN", permittedActionCd: ["SUBMIT"]};
+                       
+                               cldsModelService.processActionResponse(modelName, pars);
+                       
+                               selected_model = modelName;
+
+                               // set model bpmn and open diagram
+                       $rootScope.isPalette = true;
+
+               var initialDiagram =
+                       '<?xml version="1.0" encoding="UTF-8"?>' +
+                       '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+                       'xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" ' +
+                       'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" ' +
+                       'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' +
+                       'targetNamespace="http://bpmn.io/schema/bpmn" ' +
+                       'id="Definitions_1">' +
+                       '<bpmn:process id="Process_1" isExecutable="false">' +
+                       '<bpmn:startEvent id="StartEvent_1"/>' +
+                       '</bpmn:process>' +
+                       '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' +
+                       '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' +
+                       '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' +
+                       '<dc:Bounds x="50" y="162" width="36" height="36" />' +
+                       '</bpmndi:BPMNShape>' +
+                       '</bpmndi:BPMNPlane>' +
+                       '</bpmndi:BPMNDiagram>' +
+                       '</bpmn:definitions>';
+                       
+                       modelXML = initialDiagram;
+                       visibility_model();
+                       $modalInstance.close("closed");
+                       }
+                       $scope.revertChanges=function(){
+                               console.log("revertChanges");
+                               $scope.openModel();
+                       }
+                       $scope.openModel = function(){
+                               console.log("openModel");
+                               reloadDefaultVariables(false)
+                               var readonly;
+                               if(document.getElementById("readOnly")){
+                                       readOnly=document.getElementById("readOnly").checked;   
+                               }
+                               
+                               console.log("readonly seen ")
+                               console.log(readOnly)
+                               var modelName = document.getElementById("modelName").value;
+                               console.log("openModel: modelName=" + modelName);      
+                               
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+
+                               cldsModelService.getModel( modelName ).then(function(pars) {
+                               console.log("openModel: pars=" + pars);
+                               console.log(pars)
+                               // process data returned
+                               var bpmnText = pars.bpmnText;
+                               var propText = pars.propText;
+                               var status = pars.status;
+                               var controlNamePrefix = pars.controlNamePrefix;
+                               var controlNameUuid = pars.controlNameUuid;
+                               selected_template=pars.templateName
+                               cldsModelService.processActionResponse(modelName, pars);
+                               
+                               // deserialize model properties
+                               if ( propText == null ) {
+                               console.log("openModel: propText is null");
+                               } else {
+                               console.log("openModel: propText=" + propText);
+                                       elementMap =  JSON.parse(propText);
+                               }
+
+                               selected_model = modelName;
+                               
+                               // set model bpmn and open diagram
+                               $rootScope.isPalette = true;
+                               modelXML = bpmnText;
+                               visibility_model();
+                       },
+                       function(data) {
+                               //alert("getModel failed");
+                       });
+       
+                               $modalInstance.close("closed");
+                       };
+
+                       setMultiSelect();
+               }
+       ]
+);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/CldsOpenTemplateCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/CldsOpenTemplateCtrl.js
new file mode 100644 (file)
index 0000000..bde63c9
--- /dev/null
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('CldsOpenTemplateCtrl',
+       ['$scope', '$rootScope', '$modalInstance','$window','cldsTemplateService', '$location', 'dialogs',
+               function($scope, $rootScope, $modalInstance,$window, cldsTemplateService, $location,dialogs) {
+                       console.log("////////////CldsOpenTemplateCtrl");        
+                       $scope.error = {
+                               flag : false,
+                               message: ""
+                       };                                      
+                       cldsTemplateService.getSavedTemplate().then(function(pars) {
+                               //alert("lol")
+                               //////////mySelect.empty();
+                               $scope.modelNamel=[]
+                               for(var i=0;i<pars.length;i++){
+                                       $scope.modelNamel.push(pars[i].value);
+                                       
+                                       //console.log($scope.modelNamel[i])
+                               }
+                               setTimeout(function(){
+                       console.log("setTimeout");
+
+                    setMultiSelect(); }, 100);
+                               
+                               
+                       });
+                       function contains(a, obj) {
+                               console.log("contains");
+                           var i = a.length;
+                           while (i--) {
+                              if (a[i].toLowerCase() === obj.toLowerCase()) {
+                                  return true;
+                              }
+                           }
+                           return false;
+                       }
+                       $scope.checkExisting=function(){
+                               console.log("checkExisting");
+                               var name = $('#modelName').val();
+                               //alert(name)
+                               //console.log($scope.modelNamel)
+                               if(contains($scope.modelNamel,name)){
+                                       $scope.nameinUse=true;
+                               }else{
+                                       $scope.nameinUse=false;
+                               }
+
+                       }
+                       
+                       $scope.closeDiagram=function(){
+                               console.log("closeDiagram");
+                               $window.location.reload();
+                       }
+                       
+                       
+                       
+                       $scope.createNewTemplate=function(){
+                               console.log("createNewTemplate");
+                               reloadDefaultVariables(true)
+                               if($(".bjs-container").is("[hidden]")){
+                                       $(".bjs-container").removeAttr("hidden");
+                                       $("#svgContainer").remove();
+                               }
+                               var modelName = document.getElementById("modelName").value;
+                               if(!modelName){
+                                       $scope.error.flag =true;
+                                       $scope.error.message = "Please enter any name for proceeding";
+                                   return false;
+                               }
+                               
+                               console.log("openModel: modelName=" + modelName);      
+                               
+                               // BEGIN env
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+                       // enable appropriate menu options - non are available for templates...
+                       //var pars = {status: "DESIGN", permittedActionCd: ["DISTRIBUTE"]};
+                               var pars={}
+                       pars.controlNamePrefix=""
+                       pars.controlNameUuid=""
+                       pars.event={}
+                       pars.event.actionStateCD=""
+                       pars.newTemplate = true
+                               cldsTemplateService.processActionResponse(modelName, pars);
+                       
+                               selected_model = modelName;
+
+                               // set model bpmn and open diagram
+                       $rootScope.isPalette = true;
+
+               var initialDiagram =
+                       '<?xml version="1.0" encoding="UTF-8"?>' +
+                       '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+                       'xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" ' +
+                       'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" ' +
+                       'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' +
+                       'targetNamespace="http://bpmn.io/schema/bpmn" ' +
+                       'id="Definitions_1">' +
+                       '<bpmn:process id="Process_1" isExecutable="false">' +
+                       '<bpmn:startEvent id="StartEvent_1"/>' +
+                       '</bpmn:process>' +
+                       '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' +
+                       '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' +
+                       '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' +
+                       '<dc:Bounds x="50" y="162" width="36" height="36" />' +
+                       '</bpmndi:BPMNShape>' +
+                       '</bpmndi:BPMNPlane>' +
+                       '</bpmndi:BPMNDiagram>' +
+                       '</bpmn:definitions>';
+                       
+                       modelXML = initialDiagram;
+                       visibility_model();
+                       $modalInstance.close("closed");
+                       }
+                       
+                       $scope.revertChanges=function(){
+                               console.log("revertChanges");
+                               $scope.openTemplate();
+                       }
+                       $scope.close=function(){
+                               console.log("close");
+                               $rootScope.isNew = false;
+                               $modalInstance.close("closed");
+                       }
+                       $scope.openTemplate = function() {
+                               console.log("openTemplate");
+                               reloadDefaultVariables(true)
+                               if($(".bjs-container").is("[hidden]")){
+                                       $(".bjs-container").removeAttr("hidden");
+                                       $("#svgContainer").remove();
+                               }
+                               var modelName = document.getElementById("modelName").value;
+                               console.log("openModel: modelName=" + modelName);    
+                               if($scope.modelNamel.includes(document.getElementById("modelName").value)){
+
+                               }
+                               
+                               // init UTM items
+                               $scope.utmModelsArray = [];
+                               $scope.selectedParent = {};
+                               $scope.currentUTMModel = {};
+                               $scope.currentUTMModel.selectedParent = {};
+                               $rootScope.oldUTMModels =[];
+                               $rootScope.projectName="clds_default_project";          
+                               var utmModels = {};
+                               utmModels.name = modelName;
+                               utmModels.subModels = [];
+                               $rootScope.utmModels = utmModels;
+                               
+
+                               cldsTemplateService.getTemplate( modelName ).then(function(pars) {
+                               console.log("openModel: pars=");
+                               console.log(pars)
+                               // process data returned
+                               var bpmnText = pars.bpmnText;
+                               var propText = pars.propText;
+                               var status = pars.status;
+                               var controlNamePrefix = pars.controlNamePrefix;
+                               var controlNameUuid = pars.controlNameUuid;
+                               
+                               cldsTemplateService.processActionResponse(modelName, pars);
+                               
+                               // deserialize model properties
+                               console.log("prop text")
+                               console.log(propText)
+                               if ( propText == null ) {
+                               console.log("openModel: propText is null");
+                               } else {
+                               console.log("openModel: propText=" + propText);
+                                       elementMap =  JSON.parse(propText);
+                               }
+
+                               selected_model = modelName;
+                               
+                               // set model bpmn and open diagram
+                               $rootScope.isPalette = true;
+                               modelXML = bpmnText;
+                               visibility_model();
+                       },
+                       function(data) {
+                               console.log("data");
+                               //alert("getModel failed");
+                       });
+       
+                               $modalInstance.close("closed");
+                       };
+                       
+               }
+       ]
+);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/CldsTemplateService.js b/src/main/resources/META-INF/resources/designer/scripts/CldsTemplateService.js
new file mode 100644 (file)
index 0000000..3d43138
--- /dev/null
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('cldsTemplateService', ['alertService', '$http', '$q', function (alertService, $http, $q) {
+    this.getTemplate = function(templateName){
+       
+       console.log("///////////////cldsTemplateService");
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/cldsTempate/template/" + templateName;                
+       
+        $http.get(svcUrl)
+        .success(function(data){ 
+        console.log("success");        
+               def.resolve(data);              
+               
+        })
+        .error(function(data){  
+        console.log("error");                        
+                       def.reject("Open Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.getSavedTemplate=function(){
+        console.log("getSavedTemplate");
+       var def = $q.defer();
+       var sets = [];
+       
+       var svcUrl = "/restservices/clds/v1/cldsTempate/template-names";                
+       
+        $http.get(svcUrl)
+        .success(function(data){
+        console.log("success");                
+               def.resolve(data);              
+               
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject("Open Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.setTemplate = function(templateName, controlNamePrefixIn, bpmnTextIn, propTextIn){
+       
+       console.log("setTemplate");
+       var def = $q.defer();
+       var sets = [];
+
+       var svcUrl = "/restservices/clds/v1/clds/model/" + modelName;        
+        var svcRequest = {name: templateName, controlNamePrefix: controlNamePrefixIn, bpmnText: bpmnTextIn, propText: propTextIn};
+        
+       
+        $http.put(svcUrl, svcRequest)
+        .success(function(data){ 
+        console.log("success");        
+               def.resolve(data);              
+               
+        })
+        .error(function(data){ 
+        console.log("error");                        
+                       def.reject("Save Model not successful");
+        });
+        
+        return def.promise;
+    };
+    this.processAction = function(uiAction, templateName, controlNamePrefixIn, bpmnTextIn, propTextIn,svgXmlIn){
+       
+       console.log("processAction");
+       var def = $q.defer();
+       var sets = [];
+       console.log("Generated SVG xml File...");
+       console.log(propTextIn);
+       var svcUrl = "/restservices/clds/v1/cldsTempate/template/"+templateName;        
+               
+        var svcRequest = {name: templateName, controlNamePrefix: controlNamePrefixIn, bpmnText: bpmnTextIn, propText: propTextIn, imageText:svgXmlIn};      
+        $http.put(svcUrl, svcRequest)
+        .success(function(data){
+        console.log("success");                
+               def.resolve(data);              
+               alertService.alertMessage("Action Successful:"+uiAction,1)
+
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject(" not successful");
+               alertService.alertMessage("Action Failure:"+uiAction,2)
+
+        });
+        
+        return def.promise;
+    };
+    this.checkPermittedActionCd = function(permittedActionCd, menuText, actionCd){
+        console.log("checkPermittedActionCd");
+               if ( permittedActionCd.indexOf(actionCd) > -1 ) {
+                       document.getElementById(menuText).classList.remove('ThisLink');
+               } else {
+                       document.getElementById(menuText).classList.add('ThisLink');
+               }
+    };        
+    this.processActionResponse = function(templateName, pars){
+        console.log("processActionResponse");
+       // populate control name (prefix and uuid here)
+               var controlNamePrefix = pars.controlNamePrefix;
+               var controlNameUuid = pars.controlNameUuid;
+        
+        var headerText = "Closed Loop Modeler - " + templateName;
+        if ( controlNameUuid != null ) {
+               var actionCd = pars.event.actionCd;
+               var actionStateCd = pars.event.actionStateCd;
+//             headerText = headerText + " [" + controlNamePrefix + controlNameUuid + "] [" + actionCd + ":" + actionStateCd + "]";
+               headerText = headerText + " [" + controlNamePrefix + controlNameUuid + "]";
+        }
+               
+       document.getElementById("modeler_name").textContent = headerText;
+
+               
+               // enable menu options
+               document.getElementById('Save Template').classList.remove('ThisLink');
+       document.getElementById('Template Properties').classList.remove('ThisLink');
+       document.getElementById('Test').classList.remove('ThisLink');
+        if(!pars.newTemplate){
+            document.getElementById('Revert Template Changes').classList.remove('ThisLink');    
+        }      
+       document.getElementById('Close Template').classList.remove('ThisLink');
+       
+       document.getElementById('Refresh Status').classList.remove('ThisLink');
+       //disable save/properties for model
+       document.getElementById('Save CL').classList.add('ThisLink');
+       document.getElementById('Properties CL').classList.add('ThisLink');
+       document.getElementById('Revert Model Changes').classList.add('ThisLink');
+       document.getElementById('Close Model').classList.add('ThisLink');
+       document.getElementById('Refresh ASDC').classList.add('ThisLink');
+       document.getElementById('Running Instances').classList.add('ThisLink');
+
+               
+    };        
+ }]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/DashboardCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/DashboardCtrl.js
new file mode 100644 (file)
index 0000000..0fdf5db
--- /dev/null
@@ -0,0 +1,696 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+
+function DashboardCtrl($scope,$rootScope,$resource, $http, $timeout, $location, $interval, $q, Datafactory) 
+{
+       console.log("//////////////DashboardCtrl");
+       $scope.autosaveInterval = 1800000;
+       $scope.testsetgendashboard = false;
+       $rootScope.isModel = false;
+       $rootScope.isPalette = false;
+       $rootScope.isTestSet = false;  
+       $rootScope.isRequirementCoverage = false;
+       $rootScope.ispropertyExplorer = false;
+       $rootScope.parameters;
+       $scope.orientation ="horizontal";
+       $rootScope.ispropertyExplorer = false;
+       $rootScope.isActive =true;
+       $rootScope.models=[];
+       $scope.selectedParent={};
+       $rootScope.utmModels={};
+       $rootScope.selectedModelName;
+       $rootScope.dialogName="";
+       
+
+       $interval( function(){
+       console.log("interval"); 
+               AutosaveProject($scope,$rootScope,$resource, $http, $timeout, $location, $interval, $q, Datafactory);
+               }, $scope.autosaveInterval);
+       
+       
+       $rootScope.onSelectActivityModel =function(obj)
+    {
+       console.log("onSelectActivityModel");
+       
+               $rootScope.isPalette = true;
+               $rootScope.isTestSet = false;  
+               $rootScope.isRequirementCoverage = false;
+               $rootScope.ispropertyExplorer = false;
+       //document.getElementById('propertyExplorer').classList.remove('visible');
+       
+       //$( "#propertyExplorer" ).prev().css( "display" ,"block");
+               $( "#activity_modeler" ).prev().css( "display", "block" );
+               $( 'div' ).find('.k-expand-next').click();
+          
+               if(obj == undefined){
+                       document.getElementById("modeler_name").textContent="Activity Modeler" ;
+               }else{
+                       selected_model=obj;
+               document.getElementById("modeler_name").textContent="Activity Modeler"+"  - "+ selected_model ;                 
+               }
+               
+               $rootScope.modelName = selected_model;
+        
+        $rootScope.modeltestset = list_model_test_sets[selected_model];
+        if(list_model_schema_extensions[selected_model] == null){
+               if(list_model_schema_extensions[$rootScope.utmModels.name] != null) {
+                       list_model_schema_extensions[selected_model] = jQuery.extend(true, {}, list_model_schema_extensions[$rootScope.utmModels.name]);
+               } else { 
+                       list_model_schema_extensions[selected_model] = {};
+               }
+        }
+
+               $rootScope.initProjectExplorer();
+        
+        visibility_model();
+        changecolor(selected_model);
+        
+       
+    };
+    $scope.selectActivityTestSet =function()
+    {
+       console.log("selectActivityTestSet");
+       $rootScope.isPalette = false;
+       $rootScope.isRequirementCoverage = false;
+               $rootScope.isTestset = true;
+               document.getElementById("modeler_name").textContent="UTM Test Set";
+               //document.getElementById('propertyExplorer').classList.add('visible');
+               //$( "#propertyExplorer" ).prev().css( "display" ,"none");
+               $( 'div' ).find('.k-collapse-next').click();
+               $rootScope.modeltestset = list_model_test_sets[selected_model];
+               $rootScope.$apply();
+               
+    };
+       $scope.showPalette= function(){
+               console.log("showPalette");
+               //alert("showPalette()");
+               $rootScope.isModel = true;
+       //      $rootScope.isPalette = true;
+               
+       };
+       
+       //$scope.initialShow=false;
+                       
+       if("/testsetgendashboard"==$location.url())
+       {
+               $scope.testsetgendashboard = true;
+               
+               
+               $rootScope.total_users = 0;
+               $scope.showUserView = true;
+               $scope.showTestExecution = true;
+               //$rootScope.total_accounts = 606;
+               $scope.showAccountView = true;
+
+               $rootScope.total_creation_times = 0;
+               $rootScope.success_rate_percent = 0;//(((data.data[0].value*1.0)/(data.data[0].value+data.data[1].value))*100).toFixed();
+               $rootScope.total_accounts = 0;
+               $scope.showCreation_timeView = true;
+               $scope.showSuccess_ratePercent = true;
+               
+               
+               //$scope.generalMessages= "This section will show general messages/alerts.";
+               $scope.gridHeaderMessages= "TestData Self-Service: Select TestCase and Click on Run button!!!";
+               
+               //Filters' JS
+
+                   $scope.dt = new Date();
+                 $scope.clear = function () {
+                       console.log("clear");
+                   $scope.dt = null;
+                 };
+
+                 // Disable weekend selection
+                 $scope.disabled = function(date, mode) {
+                       console.log("disabled");
+                   return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
+                 };
+
+                 $scope.toggleMin = function() {
+                       console.log("toggleMin");
+                   $scope.minDate = $scope.minDate ? null : new Date();
+                 };
+                 $scope.toggleMin();
+
+                 $scope.open2 = function($event) {
+                       console.log("open2");
+                         $event.preventDefault();
+                   $event.stopPropagation();
+                   console.log(' herro: is the value of opened');
+                   $scope.opened = true;
+                   console.log($scope.opened + ' is the value of opened');
+                 };
+
+                 $scope.dateOptions = {
+                   formatYear: 'yy',
+                   startingDay: 1
+                 };
+
+                 $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
+                 $scope.format = $scope.formats[0];
+                 
+                 $scope.disabled = function(date, mode) 
+                 {
+                       console.log("disabled");
+               return ( mode === 'day' && ( date.getDay() === -1 || date.getDay() === 7 ) );
+             };
+
+              $scope.maxDate = new Date();
+
+
+                $scope.open = function($event,opened) {
+                       console.log("open");
+                     $event.preventDefault();
+                     $event.stopPropagation();
+
+                     $scope[opened] = true;
+                   };
+
+
+              $scope.dateOptions = {
+              'year-format': "'yy'",
+              'starting-day': 1
+              };
+              
+              $scope.date = "29-December-2014";
+              $scope.date2 = new Date();
+              
+              $scope.printDate = function()
+              {
+                  console.log("printDate");
+              };
+                               
+       };
+       
+       
+       
+       
+       
+       $scope.returnObjectArray = function(arrayObj)
+       {
+               console.log("returnObjectArray");
+               var newArrayObj = [];
+               
+               angular.forEach(arrayObj, function(value, key) 
+               {
+                       console.log("arrayObj");
+                       newArrayObj.push({"data":value});
+               });
+               
+               return newArrayObj;
+       };
+       
+        
+       $scope.returnTestScenarioTstObjectArray = function(arrayObj)
+        {
+         console.log("returnTestScenarioTstObjectArray");
+         var newArrayObj = [];
+         
+         angular.forEach(arrayObj, function(value, key) 
+         {
+               console.log("arrayObj");
+                 if( value.testScenarioInstances !=undefined && value.testScenarioInstances.length !=0){
+                         var tempLabel = value.testScenarioInstances[0].label.split(":");
+                               newArrayObj.push({"data":tempLabel[0]});
+                 }
+                       
+         });
+         
+         return newArrayObj;
+        };
+
+       
+       
+
+       $scope.returnOverRiddenObjectArray = function(arrayObj)
+       {
+               console.log("returnOverRiddenObjectArray");
+               var newArrayObj = [];
+               
+               angular.forEach(arrayObj, function(value, key) 
+               {
+                       console.log("arrayObj");
+                       newArrayObj.push({"data":value.name});
+               });
+               
+               return newArrayObj;
+       };
+       
+       
+       
+       
+       $rootScope.filterRouter = 'partials/DashboardFilters.html';
+       $scope.isActivePROD = true;
+       $scope.isActiveQC = false;
+       $rootScope.reload = function(env)
+       {
+                       console.log("reload");
+       };
+
+       $scope.showTDSSView = true;
+       
+       $scope.ReLoadDashboardFromViewResetComboBox = function(type, amount)//('Users','All') ('Accounts','All') ('Creation_times','All')
+       {
+               console.log("ReLoadDashboardFromViewResetComboBox");
+       };
+       
+       
+       
+       //////////////////////////////////
+       
+       $scope.total_tdr_team_selected_model = [];
+       $scope.total_tdr_users_selected_model = [];
+       $scope.total_tdr_requests_selected_model = [];
+       $scope.total_tdr_entities_selected_model = [];
+       
+       $scope.reloadTDRDashboard = function(name)
+       {
+               console.log("reloadTDRDashboard");
+               var url = "/testdata-service/test-data-request/dashboard/counts.json?";
+                               
+               $http.get(url+params).success(function(data)
+               {
+                       console.log("success");
+                       $scope.total_tdr_team_count = data.result.dashboardCountModel.teams;
+                       $scope.total_tdr_users_count = data.result.dashboardCountModel.users;
+                       $scope.total_tdr_requests_count = data.result.dashboardCountModel.requests;
+                       $scope.total_tdr_entities_count = data.result.dashboardCountModel.entities;
+                       
+                       
+                       if("team"!=name)
+                       {
+                               $scope.total_tdr_team_array = $scope.returnObjectArray(data.result.tdrDashboardModel.teams);    
+                               $scope.TDRTeamGridId.api().clear().draw();
+                               $scope.TDRTeamGridId.fnAddData($scope.total_tdr_team_array);
+                       }
+                       
+                       
+                       if("users"!=name)
+                       {
+                               $scope.total_tdr_users_array = $scope.returnObjectArray(data.result.tdrDashboardModel.users);
+                               $scope.TDRUserGridId.api().clear().draw();
+                               $scope.TDRUserGridId.fnAddData($scope.total_tdr_users_array);
+                       }
+                               
+                       if("status"!=name)
+                       {
+                               $scope.total_tdr_entities_array = $scope.returnObjectArray(data.result.tdrDashboardModel.entities);
+                               $scope.TDREntitiesGridId.api().clear().draw();
+                               $scope.TDREntitiesGridId.fnAddData($scope.total_tdr_entities_array);
+                       }
+                       
+                       if("request"!=name)
+                       {
+                               $scope.total_tdr_requests_array = $scope.returnObjectArray(data.result.tdrDashboardModel.requests);
+                               $scope.TDRNumberGridId.api().clear().draw();
+                               $scope.TDRNumberGridId.fnAddData($scope.total_tdr_requests_array);
+                       }                       
+               });
+               
+       };
+       
+       
+       $scope.loadTDRDashboard = function()
+       {
+               console.log("loadTDRDashboard");
+               $rootScope.launch('wait'); 
+               
+               /* api jobs */
+               var apiJobUrl = "/utm-service/em/jobs?timezoneOffset=420";
+                
+               $http.get(apiJobUrl).success(function(data)
+               {
+                       console.log("success");
+                       $scope.total_test_scenario_count = data.length;
+                       
+
+                       $scope.TDRNumberGridId = $('#TDRNumberGridId').dataTable( {
+                               "serverSide": false,
+                               "aoColumns": [
+
+                                     {   "sTitle": "","mDataProp": null, "sWidth": "20px", "bSortable": false},
+                                     {   "sTitle":"Total TestScenarios","mDataProp": "data","bSortable": true}                                                      
+                         ],
+                               //"columns": [{"data":   "data"}],
+                         "order": [[ 1, "asc" ]],
+                               "bPaginate": false,
+                               "bFilter": false, 
+                               "bInfo": false,
+                           "bAutoWidth": false,
+                           "bScrollCollapse": false,
+                          "bLengthChange":false,
+                          "bJQueryUI": true,
+                          "search": {"caseInsensitive": true},
+                          "scrollY": "200px",
+                      "scrollX": "100%",
+                      "sScrollXInner": "100%",
+                          "fnCreatedRow": function( nRow, aData, iDataIndex ) 
+                          {
+                               console.log("fnCreatedRow");
+                               $(nRow).children("td").css("overflow", "hidden");
+                               $(nRow).children("td").css("white-space", "nowrap");
+                               $(nRow).children("td").css("text-overflow", "ellipsis");
+                               
+                               var found = false;              
+                               
+                               angular.forEach($scope.total_tdr_requests_selected_model, function (value) 
+                       {
+                               console.log("total_tdr_requests_selected_model");
+                                               if(aData.data==value.id)
+                                               {
+                                                       found=true;
+                                               }
+                       });
+                               
+                               if(found)
+                               {
+                                       $('td:eq(0)', nRow).html( '<span class="tdr_checkbox tdr_checkbox_glyphicon_glyphicon_ok glyphicon glyphicon-ok" id="'+aData.data+'"></span>');
+                               }
+                               else
+                               {
+                                       $('td:eq(0)', nRow).html( '<span class="tdr_checkbox tdr_checkbox_glyphicon_glyphicon_unchecked glyphicon glyphicon-unchecked" id="'+aData.data+'"></span>');
+                               }
+                               
+                               
+                           }
+                   } );
+                       
+                       $scope.total_tdr_requests_array = $scope.returnOverRiddenObjectArray(data);
+                       
+                       if($scope.total_tdr_requests_array.length > 0)
+                       {
+                               $scope.TDRNumberGridId.fnAddData($scope.total_tdr_requests_array);      
+                       }
+                       
+                       
+                       
+                                               
+                       
+                       $('#TDRNumberGridId tbody').on( 'click', 'td', function () 
+                       {
+                               console.log("click");
+                               var position = $scope.TDRNumberGridId.fnGetPosition(this); // getting the clicked row position                          
+                       
+                        if(position[1]==1)
+                        {
+                                
+                                       var valueX = this.innerHTML;
+                               
+                               $('.tdr_checkbox').each(function(i, obj) 
+                               {        
+                                       console.log("tdr_checkbox");
+                                       var uncheck = $(obj).hasClass( "glyphicon-unchecked");
+                                       
+                                       if(valueX==obj.id && uncheck)
+                                       {
+                                               $(obj).attr('class','tdr_checkbox tdr_checkbox_glyphicon_glyphicon_ok glyphicon glyphicon-ok');
+                                       }                                       
+                                       else if(valueX==obj.id && !uncheck)
+                                       {
+                                               $(obj).attr('class','tdr_checkbox tdr_checkbox_glyphicon_glyphicon_unchecked glyphicon glyphicon-unchecked');
+                                       }                                                                                       
+                               });
+                               
+                               
+                                if($('.tdr_checkbox_glyphicon_glyphicon_ok').length <= 0)
+                                    {
+                                        $scope.total_tdr_requests_selected_model = [];                                  
+                                        $scope.total_tdr_requests_selected_model.push({'id':'All'});                                    
+                                }
+                                else
+                                        {
+                                        $scope.total_tdr_requests_selected_model = [];
+                                        
+                                               $('.tdr_checkbox_glyphicon_glyphicon_ok').each(function(i, obj) 
+                                       {       
+                                               console.log("tdr_checkbox_glyphicon_glyphicon_ok");
+                                                       $scope.total_tdr_requests_selected_model.push({'id':obj.id});
+                                       });
+                                               
+                                        }
+                        }              
+                        else
+                        {
+                               var valueX = this.innerHTML.substring(this.innerHTML.indexOf("id=\"")+4,this.innerHTML.length-9);
+                               
+                               $('.tdr_checkbox').each(function(i, obj) 
+                                       {        
+                                               console.log("tdr_checkbox");
+                                       var uncheck = $(obj).hasClass( "glyphicon-unchecked");
+                                       
+                                       if(valueX==obj.id && uncheck)
+                                       {
+                                               $(obj).attr('class','tdr_checkbox tdr_checkbox_glyphicon_glyphicon_ok glyphicon glyphicon-ok');
+                                       }                                       
+                                       else if(valueX==obj.id && !uncheck)
+                                       {
+                                               $(obj).attr('class','tdr_checkbox tdr_checkbox_glyphicon_glyphicon_unchecked glyphicon glyphicon-unchecked');
+                                       }
+                                                                                       
+                                        });
+                               
+                               
+                                if($('.tdr_checkbox_glyphicon_glyphicon_ok').length <= 0)
+                                    {
+                                        $scope.total_tdr_requests_selected_model = [];                                  
+                                        $scope.total_tdr_requests_selected_model.push({'id':'All'});   
+                                }
+                                else
+                                        { 
+                                        $scope.total_tdr_requests_selected_model = [];
+                                               $('.tdr_checkbox_glyphicon_glyphicon_ok').each(function(i, obj) 
+                                       {        
+                                               console.log("tdr_checkbox_glyphicon_glyphicon_ok");
+                                                       $scope.total_tdr_requests_selected_model.push({'id':obj.id});   
+                                       });
+                                        }
+                        }
+
+                        $scope.reloadTDRDashboard('request');
+                       });
+                       //$scope.initialShow=true;
+                       $rootScope.$broadcast('dialogs.wait.complete');
+                       
+               
+               });
+               
+       };
+               
+
+       
+       $scope.getCommaSeparatedString = function(json) 
+       { 
+               console.log("getCommaSeparatedString");
+               if(json==undefined || json==null)
+               {
+                       return "All";
+               }
+               
+               var result = "";
+               var found =false;
+               
+               for (var dString in json) 
+               { 
+                       result += json[dString].id + ",";
+                       found=true;
+               }
+                               
+               var res = result.match(/All,/g);
+               
+               if(res!=null && result.split(",").length > 1)
+               {
+                       result = result.replace("All,", "");
+               }
+                               
+               if(!found || result=="")
+               {
+                       return "All";
+               }
+               
+               return result.replace(/,(\s+)?$/, '');
+       };
+       
+       
+       /*if("/dashboard"==$location.url())
+       {
+               $scope.loadTDRDashboard();
+       }*/
+       
+       
+       
+       $scope.reloadTDRDashboardFromReset = function(name)
+       {
+               console.log("reloadTDRDashboardFromReset");
+               var url = "/testdata-service/test-data-request/dashboard/counts.json?";
+               var params = "teams="+$scope.getCommaSeparatedString($scope.total_tdr_team_selected_model);
+               params = params + "&users="+$scope.getCommaSeparatedString($scope.total_tdr_users_selected_model); 
+               params = params + "&requests="+$scope.getCommaSeparatedString($scope.total_tdr_requests_selected_model);
+               params = params + "&status="+$scope.getCommaSeparatedString($scope.total_tdr_entities_selected_model);
+                               
+               $http.get(url+params).success(function(data)
+               {
+                       console.log("success");
+                       $scope.total_tdr_team_count = data.result.dashboardCountModel.teams;
+                       $scope.total_tdr_users_count = data.result.dashboardCountModel.users;
+                       $scope.total_tdr_requests_count = data.result.dashboardCountModel.requests;
+                       $scope.total_tdr_entities_count = data.result.dashboardCountModel.entities;
+                       
+                       $scope.total_tdr_team_array = $scope.returnObjectArray(data.result.tdrDashboardModel.teams);    
+                       $scope.TDRTeamGridId.api().clear().draw();
+                       $scope.TDRTeamGridId.fnAddData($scope.total_tdr_team_array);
+                       
+                       $scope.total_tdr_users_array = $scope.returnObjectArray(data.result.tdrDashboardModel.users);
+                       $scope.TDRUserGridId.api().clear().draw();
+                       $scope.TDRUserGridId.fnAddData($scope.total_tdr_users_array);
+                       
+                       $scope.total_tdr_entities_array = $scope.returnObjectArray(data.result.tdrDashboardModel.entities);                     
+                       $scope.TDREntitiesGridId.api().clear().draw();
+                       $scope.TDREntitiesGridId.fnAddData($scope.total_tdr_entities_array);
+                       
+                       $scope.total_tdr_requests_array = $scope.returnObjectArray(data.result.tdrDashboardModel.requests);
+                       $scope.TDRNumberGridId.api().clear().draw();
+                       $scope.TDRNumberGridId.fnAddData($scope.total_tdr_requests_array);                                              
+               });
+               
+       };
+       
+       
+       $scope.ReLoadTDRDashboard = function(name)
+       {
+               console.log("ReLoadTDRDashboard");
+               if("team"==name)
+               {
+                       $scope.total_tdr_team_selected_model = [];
+               }               
+               
+               if("users"==name)
+               {
+                       $scope.total_tdr_users_selected_model = [];
+               }
+                       
+               if("status"==name)
+               {
+                       $scope.total_tdr_entities_selected_model = [];
+               }
+               
+               if("request"==name)
+               {
+                       $scope.total_tdr_requests_selected_model = [];
+               }       
+               
+               $scope.reloadTDRDashboardFromReset(name);
+               
+       };
+       
+       $rootScope.populateUTMModelArray= function(utm_models,utmModels){
+               console.log("populateUTMModelArray");
+               var modelName =utmModels.name;
+               if (utmModels != null && utmModels.name != null) {
+                       if($rootScope.oldUTMModels != null  && $rootScope.oldUTMModels.length > 0){
+                               for(var i=0 ;i<$rootScope.oldUTMModels.length;i++ ){
+                                       var tempOldName  = $rootScope.oldUTMModels[i];
+                                       console.log("new model name from map:"+old_new_model_name[tempOldName]);
+                                       if( utmModels.name ==  old_new_model_name[tempOldName]){
+                                               modelName = $rootScope.oldUTMModels[i];
+                                       }       
+                               }       
+                       }
+                       var utm_model = {};
+                       utm_model.modelName = utmModels.name;
+                       utm_model.modelXML = list_models[modelName];
+                       utm_model.repeatableHeirachicalSchemaElements = {};
+                       utm_model.repeatableHeirachicalSchemaElements = list_model_repeatable_heirarchical_elements[modelName];
+                       
+                       utm_model.testManagementDetails = {};
+                       utm_model.testManagementDetails = list_model_test_management_details[modelName];
+                       
+                       var activitytestset={};
+                       activitytestset.invalidModelException=null;
+                       activitytestset.serviceName=serviceName;
+                       activitytestset.activityTestCases=[];
+                       if (list_model_test_sets[modelName] != null && list_model_test_sets[modelName].activityTestCases != null) {
+                               activitytestset.activityTestCases=angular.copy(list_model_test_sets[modelName].activityTestCases);
+                       }       
+                       utm_model.activityTestSet = activitytestset;
+                       
+                       utm_model.utmPropertyExplorer = {};
+                       utm_model.utmPropertyExplorer.pathDetailsList = [];
+                       if (list_model_path_details[modelName] != null) {
+                               utm_model.utmPropertyExplorer.pathDetailsList = angular.copy(list_model_path_details[modelName]);
+                       }
+                       
+                       utm_model.utmModelSchemaExtention = {};
+                       utm_model.utmModelSchemaExtention.utmSchemaExtentionMap = {};
+                       if (list_model_schema_extensions[modelName] != null) {
+                               utm_model.utmModelSchemaExtention = angular.copy(list_model_schema_extensions[modelName]);
+                       }
+                       
+                       utm_models.push(utm_model);
+                       if(utmModels.subModels != null && utmModels.subModels.length>0){                                
+                               for(var i=0 ; i<utmModels.subModels.length;i++) {
+                                       var subModel = {};
+                                       subModel = utmModels.subModels[i];
+                                       $scope.populateUTMModelArray(utm_models,subModel);
+                                }
+                       }
+               }
+       };
+       
+       
+       /*$scope.getPallette = function(){
+               alert("nothing");
+                               createNewDiagram();
+                               alert("after");
+       };*/
+       
+       
+}
+function changecolor(selected_model)
+{
+       console.log("changecolor");
+       
+       var i = 0;
+       //var modelNames =[];
+       
+    $(".models").each(function(i){
+       console.log("each");
+    var model_value = $(this).text().trim();
+    //modelName.push(model_value);
+    if(model_value == selected_model || model_value == "")
+    {
+        $(this).addClass("selectedcolor");
+    }
+    else
+    {
+        $(this).removeClass("selectedcolor");
+        
+    }
+        
+       i++; 
+    });
+}
+
+
diff --git a/src/main/resources/META-INF/resources/designer/scripts/ExportFileCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/ExportFileCtrl.js
new file mode 100644 (file)
index 0000000..72fe83e
--- /dev/null
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('exportCtrl', ['$scope', '$rootScope','exportService','dialogs', function($scope,$rootScope,exportService,dialogs){
+    console.log("exportCtrl");
+       
+       
+$scope.exportfile = function(format) {
+    console.log("//////////exportfile");
+
+       console.log("exporting data inside exportfile function...."); 
+               
+               var formatValue=format;
+               $rootScope.exportFormat = format;               
+               var testsetValue=$rootScope.testset;     
+        
+        var exporturl = "/utm-service/testset_export/exportTestSet";
+                
+        exportService.exportToUrl(testsetValue, formatValue, exporturl)
+        .then(function(results) {
+            console.log("results");
+               
+                var sets=results.data;
+                console.log("Sets value"+sets);            
+             var headerValue=results.headers;
+             var fileName=headerValue.filename;
+             console.log("Filename Server value"+fileName);
+                       
+            
+                               var hiddenElement = document.createElement('a');
+
+                               if (angular.equals($rootScope.exportFormat,"Excel")) {
+                                       
+                                       var blob = new Blob([sets], {type: "application/vnd.ms-excel"});
+                           var objectUrl = URL.createObjectURL(blob);
+                               //alert("EXCEL Format");
+                               hiddenElement.href = objectUrl;
+                               hiddenElement.download = fileName;
+                       } else if (angular.equals($rootScope.exportFormat,"NIST")) {
+                               //alert("NIST Format");
+                       hiddenElement.href = 'data:attachment/nist,' + encodeURI(sets);
+                       hiddenElement.download = fileName;
+               } else {
+                                       //alert("CSV Format");
+                               hiddenElement.href = 'data:attachment/csv,' + encodeURI(sets);
+                               hiddenElement.download = fileName;
+               }               
+                   
+                   hiddenElement.target = '_blank';
+                   hiddenElement.click();      
+        },
+        function(data) {
+            console.log("data");
+               //alert("File upload failed and parameters not returned");
+        });
+    };
+    
+   /* $rootScope.exportUTMTestSet = function() {
+        console.log("exportUTMTestSet");
+       
+       
+       var dlg = dialogs.create('partials/portfolios/export_almqc_data.html','exportALMQCCtrl',{},{size:'xlg',keyboard: true,backdrop: true,windowClass: 'my-class'});
+               dlg.result.then(function(name){
+            console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });*/
+       
+
+       /*console.log("exporting data inside exportUTMTestSet function...."); 
+               
+                               
+               var testsetValue=$rootScope.modeltestset;     
+        
+        var exporturl = "/utm-service/testset_export/exportMDTTestSet";
+                
+        exportService.exportToUTMTestSet(testsetValue, exporturl)
+        .then(function(results) {
+               
+                var sets=results.data;
+                console.log("Sets value"+sets);            
+             var headerValue=results.headers;
+             var fileName="UTMTestSet";
+             //console.log("Filename Server value"+fileName);
+                        var hiddenElement = document.createElement('a');       
+                        var blob = new Blob([sets], {type: "application/vnd.ms-excel"});
+                    var objectUrl = URL.createObjectURL(blob);
+               //alert("EXCEL Format");
+                hiddenElement.href = objectUrl;
+                hiddenElement.download = fileName; 
+                hiddenElement.target = '_blank';
+                hiddenElement.click();         
+        },
+        function(data) {
+               //alert("File upload failed and parameters not returned");
+        });
+    };*/
+    
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/ExportFileService.js b/src/main/resources/META-INF/resources/designer/scripts/ExportFileService.js
new file mode 100644 (file)
index 0000000..ee54cfc
--- /dev/null
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('exportService', ['$http', '$q', function ($http, $q) {
+    console.log("/////////exportService");
+    this.exportToUrl = function(testsetValue, formatValue, exporturl){
+        console.log("exportToUrl");
+               
+       var def = $q.defer();
+       var sets = [];
+        var testExportRequest = {testSet: testsetValue, format: formatValue};
+               
+        if (angular.equals(formatValue,"Excel")) {
+       
+        $http({
+            url: exporturl,     method: "POST",     data: testExportRequest, //this is your json data string     headers: {
+             responseType: 'arraybuffer' }).success(function (data, status, headers, config) {
+                console.log("success");
+               /*sets = data;
+               def.resolve(data);*/
+                
+                var results = [];
+                 results.data = data;
+                 results.headers = headers();
+                 results.status = status;
+                 results.config = config;
+                 def.resolve(results); 
+        })
+        .error(function(data){
+            console.log("data");
+                     
+                       def.reject("Export file not successful");
+        });
+        }
+        else {
+                 $http.post(exporturl, testExportRequest)
+            .success(function(data, status, headers, config){
+                console.log("function");
+                               
+               var results = [];
+                results.data = data;
+                results.headers = headers();
+                results.status = status;
+                results.config = config;
+
+                def.resolve(results); 
+               //alert("Data in success without scope and q_def for scope parametes :: " + parameters);'Content-type': 'application/json',
+            }) 
+            .error(function(data){
+                console.log("data");
+                       //alert("Data in error :: " + data);      
+                       def.reject("Export file not successful");
+            });
+        }
+        return def.promise;
+    };
+    
+    this.exportToUTMTestSet = function(almqcExport, exporturl){
+    console.log("exportToUTMTestSet");         
+       var def = $q.defer();
+       var sets = [];
+        //var almqcExport =  almqcExport;       
+        $http({
+            url: exporturl,     method: "POST",     data: almqcExport,
+             responseType: 'arraybuffer' }).success(function (data, status, headers, config) {
+             console.log("success");                    
+                var results = [];
+                 results.data = data;
+                 results.headers = headers();
+                 results.status = status;
+                 results.config = config;
+                 def.resolve(results); 
+        })
+        .error(function(data){
+            console.log("data");
+                     
+                       def.reject("Export file not successful");
+        });        
+        
+        return def.promise;
+    };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/FileUploadCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/FileUploadCtrl.js
new file mode 100644 (file)
index 0000000..d1f606e
--- /dev/null
@@ -0,0 +1,261 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('fileUploadCtrl', ['$scope', '$rootScope','fileUpload', function($scope, $rootScope,fileUpload){
+    console.log("///////////fileUploadCtrl");
+       $rootScope.isAllOption = false;
+       
+    $scope.uploadSchemaFile = function(element){
+        console.log("uploadSchemaFile");
+         $scope.$apply(function($scope) {
+            console.log("apply");
+       $rootScope.isStatic = true;     
+       $rootScope.isAllOption = true;          
+       $scope.requiredval= true;       
+       $rootScope.rightTabName ="UTM Build Configuration";
+       $rootScope.testSet = null;
+       $scope.parameters = null;       
+       $scope.constraints =null;
+       $scope.relations =null;
+       if($rootScope.isStatic == true){
+                       document.getElementById('buidConfigBtn').style.visibility  = "hidden";
+               }
+       
+        var file = element.files[0];/*$scope.requestSchemaFile;*/
+        console.log('file is ' + JSON.stringify(file));        
+        $rootScope.file_type="Schema";
+        
+        var uploadUrl = "/utm-service/schema_upload/uploadSchema";
+        
+       //alert("uploadFile file::"+file + " :: " + uploadUrl);
+        
+        fileUpload.uploadFileToUrl(file, uploadUrl)
+        .then(function(pars) {
+            console.log("uploadFileToUrl");
+               
+               $rootScope.SUT =  pars;
+               console.log("file name :"+pars.name);
+               $scope.fileName = pars.name;
+               $scope.parameters = pars.parameters;
+               
+               var param = pars.parameters;
+               
+               var paramarray = pars.parameters;
+               var parArray1=[];
+               for(var i=0;i<paramarray.length;i++){
+                       parArray1.push(paramarray[i].required);
+               }
+               
+               $scope.parArray=parArray1;
+               $scope.constraints =pars.constraints;
+               $scope.relations =pars.relations;
+               var  con  = $scope.constraints;
+               $scope.required=pars.required;
+               $scope.required='Required Only';
+        },
+        function(data) {
+            console.log("data");
+               //alert("File upload failed and parameters not returned");
+        });
+        
+        
+        angular.forEach(
+                   angular.element("input[type='file']"),
+                   function(inputElem) {
+                    console.log("inputElem");
+                     angular.element(inputElem).val(null);
+                   });
+        
+         });
+    };
+    
+//-----For Required Radio button functionality
+    
+
+    $scope.requiredonly= function(){
+        console.log("requiredonly");
+       //var tempArray = $rootScope.SUT;
+       //var tempParam = tempArray.parameters;
+       //alert("testParam.length:"+tempParam.length);
+       var parameter=$scope.parArray;
+
+       
+       var param=$scope.parameters; 
+       
+       var i=0;
+
+       $('.req').each(function(){
+            console.log(".req");
+                           var newID='requiredval'+i;
+                           //jQuery(this).prev("req").attr("requiredval", "newID");
+                           //$(this).attr("requiredval","newID");
+                           //var newval=$(this).val(newID);
+                           var newval=$(this).attr('id',newID);
+                           console.log("Angular id: "+newval);
+                           if(i<param.length){
+                               document.getElementById(newID).disabled=false;
+                           if (parameter[i]){
+                               param[i].required=parameter[i];
+                                       //document.getElementById(newID).disabled=true;
+                                       document.getElementById(newID).checked=true;
+                                       }
+                                       else{
+                                       param[i].required=parameter[i]; 
+                                       //document.getElementById(newID).disabled=false;
+                                       document.getElementById(newID).checked=false;
+                               }
+                           }
+                           i++;
+                       });
+    };
+    
+
+    $scope.allrequired= function(){
+        console.log("allrequired");
+       var param=$scope.parameters;
+       var i=0;
+       $('.req').each(function(){
+            console.log("req");
+               var newID='requiredval'+i;
+                           //jQuery(this).prev("req").attr("requiredval", "newID");
+                           //$(this).attr("requiredval","newID");
+                           //var newval=$(this).val(newID);
+                           var newval=$(this).attr('id',newID);
+                           console.log("Angular id: "+newval);
+                           if(i<param.length){
+                               param[i].required=true;
+                               document.getElementById(newID).checked=true;
+                               document.getElementById(newID).disabled=true;
+                   }
+                   i++;
+               });
+
+      };
+
+    
+$scope.uploadSUTFile = function(element){
+console.log("uploadSUTFile");  
+       $scope.$apply(function($scope) {
+        console.log("apply");
+            $rootScope.isAllOption = false;
+            $rootScope.isStatic = true;            
+            $scope.requiredval= false;      
+            $rootScope.rightTabName ="UTM Build Configuration";
+                $rootScope.testSet = null;
+                
+               if($rootScope.isStatic == true){
+                       document.getElementById('buidConfigBtn').style.visibility  = "hidden";
+               }
+        var file = element.files[0];/*$scope.requestFile;*/
+        
+        console.log('file is ' + JSON.stringify(file));
+        
+        $rootScope.file_type="SUT";
+        
+        var uploadUrl = "/utm-service/sut_upload/uploadSUT";
+        
+        fileUpload.uploadFileToUrl(file, uploadUrl)
+        .then(function(pars) {
+            console.log("uploadFileToUrl");
+               $rootScope.SUT =  pars;
+               console.log("file name :"+pars.name);
+               $scope.fileName = pars.name;
+               $scope.parameters = pars.parameters;
+               
+               $scope.constraints =pars.constraints;
+               $scope.relations =pars.relations;
+               var  con  = $scope.constraints;
+        },
+        function(data) {
+            console.log("data");
+               //alert("File upload failed and parameters not returned");
+        });
+        angular.forEach(
+                   angular.element("input[type='file']"),
+                   function(inputElem) {
+                    console.log("inputElem");
+                     angular.element(inputElem).val(null);
+                   });
+        
+         
+        
+       });
+    };
+    
+    $scope.buildConfig = function(){
+    console.log("buildConfig");        
+       $rootScope.isStatic = true;     
+       $rootScope.rightTabName ="UTM Build Configuration";
+       document.getElementById('buidConfigBtn').style.visibility  = "hidden";
+       $rootScope.testset = null;
+               
+       
+    };
+    
+  /*  $scope.close = function(){
+       $modalInstance.close('closed');
+    };
+    
+    $scope.importSchema= function(){   
+        var file = $scope.requestFile;
+         console.log('file is ' + JSON.stringify(file));
+         var uploadUrl = "/utm-service/schema_upload/uploadSchema";
+         fileUpload.uploadFileToUrl(file, uploadUrl)
+         .then(function(pars) {                
+               $rootScope.SUT =  pars;
+               console.log("file name :"+pars.name);
+               $scope.fileName = pars.name;
+               $scope.parameters = pars.parameters;            
+               var param = pars.parameters;
+         },
+         function(data) {
+               //alert("File upload failed and parameters not returned");
+         });
+
+               
+    }; */
+    
+
+
+    
+    
+}]);
+
+function clearFileInput(id) 
+{ 
+    console.log("clearFileInput");
+    var oldInput = document.getElementById(id); 
+
+    var newInput = document.createElement("input"); 
+
+    newInput.type = "file"; 
+    newInput.id = oldInput.id; 
+    newInput.name = oldInput.name; 
+    newInput.className = oldInput.className; 
+    newInput.style.cssText = oldInput.style.cssText; 
+    // TODO: copy any other relevant attributes 
+
+    oldInput.parentNode.replaceChild(newInput, oldInput); 
+}
+
diff --git a/src/main/resources/META-INF/resources/designer/scripts/FileUploadService.js b/src/main/resources/META-INF/resources/designer/scripts/FileUploadService.js
new file mode 100644 (file)
index 0000000..7cfa7a9
--- /dev/null
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.directive('fileModel', ['$parse', function ($parse) {
+    console.log("////////fileModel");
+    return {
+        restrict: 'A',
+        link: function(scope, element, attrs) {   
+        console.log("link");           
+            var model = $parse(attrs.fileModel);
+               //alert("uploadFileToUrl directive model :: " + model);
+            var modelSetter = model.assign;
+            
+            element.bind('change', function(){
+                console.log("change");
+                scope.$apply(function(){
+                console.log("apply");                  
+                    modelSetter(scope, element[0].files[0]);
+                });
+            });
+        }
+    };
+}]);
+
+
+app.service('fileUpload', ['$http', '$q', function ($http, $q) {
+    console.log("fileUpload");
+    this.uploadFileToUrl = function(file, uploadUrl){
+        console.log("uploadFileToUrl");
+       //alert("uploadFileToUrl file :: " + file + " :: url::" + uploadUrl);
+       
+       var def = $q.defer();
+       var pars = [];
+       
+        var fd = new FormData();
+        fd.append('requestFile', file);
+        $http.post(uploadUrl, fd, {
+            transformRequest: angular.identity,            
+            headers: {'Content-Type': undefined}
+        })
+        .success(function(data){
+        console.log("success");                
+               pars = data;
+               def.resolve(data);              
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject("Upload file not successful");
+        });
+        
+        return def.promise;
+    };
+    
+    this.uploadFile = function(path,inputFile,uploadURL){
+        console.log("uploadFile");
+       var def = $q.defer();
+       var pars = [];
+       
+        var fd = new FormData();
+        fd.append('requestFile', inputFile);
+        fd.append('path',path)
+        $http.post(uploadURL, fd, {
+            transformRequest: angular.identity,            
+            headers: {'Content-Type': undefined}
+        })
+        .success(function(data){ 
+        console.log("success");        
+               pars = data;
+               def.resolve(data);              
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject("Upload file not successful");
+        });
+        
+        return def.promise;
+       
+    };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/GlobalPropertiesCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/GlobalPropertiesCtrl.js
new file mode 100644 (file)
index 0000000..efd127f
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('GlobalPropertiesCtrl',
+       ['$scope', '$rootScope', '$modalInstance','cldsModelService', '$location', 'dialogs','cldsTemplateService',
+               function($scope, $rootScope, $modalInstance, cldsModelService, $location,dialogs,cldsTemplateService) {
+               console.log("////////GlobalPropertiesCtrl");                                                    
+                       //cldsModelService.getASDCServices().then(function(pars) {
+                       $scope.$watch('name', function(newValue, oldValue) {
+                               console.log("name");
+                               if(readOnly){
+                                       $("select,input,.nav-tabs .close").attr("disabled","");
+                               }
+                               var services=asdc_Services
+                               console.log(asdc_Services)
+                               setASDCFields()
+                               for(k in services){
+                                       $("#service").append("<option value="+k+">"+services[k]+"</option>")
+                               }
+                               var el = elementMap["global"];
+                               console.log(elementMap["global"])
+                               if (el !== undefined) {
+                                       for (var i = 0; i < el.length; i++) {
+                                               $("#" + el[i].name).val(el[i].value);
+                                       }
+                               }
+                               setMultiSelect();
+                       });
+                       $scope.retry = function(){
+                               console.log("retry");
+                               
+                       }
+                       $scope.close = function() {
+                               console.log("close");
+                               $modalInstance.close("closed");
+                       };
+               }
+       ]
+);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/ImportSchemaCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/ImportSchemaCtrl.js
new file mode 100644 (file)
index 0000000..839eefe
--- /dev/null
@@ -0,0 +1,315 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('ImportSchemaCtrl', ['$scope', '$rootScope','$modalInstance','data','svnservice', 'fileUpload','dialogs', function($scope,$rootScope,$modalInstance,data,svnservice,fileUpload,dialogs){
+       console.log("//////ImportSchemaCtrl");
+    $rootScope.serviceInfo;
+       $rootScope.serviceInput;
+       $rootScope.serviceOutput;
+       $rootScope.serviceFault;
+       $rootScope.serviceInputPartInfo;
+       $rootScope.schemElemant1;
+       
+       $rootScope.updateServiceInfo;
+       $rootScope.updateServiceInput;
+       $rootScope.updateServiceOutput;
+       $rootScope.updateServiceFault;
+       $rootScope.updateServiceInputPartInfo;
+       $rootScope.updateSchemElemant1;
+       
+       $scope.init = function() {
+        console.log("init");
+               $scope.schemaLocation = 'svn://svnrepo:3690';
+               $scope.upgrade_schemaLocation = 'svn://svnrepo:3690';
+               $scope.userID = 'user_id';
+               $scope.password = 'password';
+       };
+       
+       $scope.init();
+        
+
+       $scope.close = function(){
+    console.log("close");              
+               $modalInstance.close("closed");
+       };
+       $rootScope.file_path;
+       
+       
+       $scope.importSchema= function(){
+    console.log("importSchema");               
+               isImportSchema = true;
+               var file=$rootScope.file_path; 
+               //alert("file:"+schemaFile);
+        //console.log('file is ' + JSON.stringify(file)); 
+        var userID = document.getElementById("userID").value;
+        var password = document.getElementById("password").value;        
+        var svnURL = document.getElementById("schemaLocation").value;
+        var schemaLocation = document.getElementById("schemaLocation").value;
+        
+        if( schemaLocation &&  userID && password && document.getElementById("schemaLocation").disabled== false)
+        {
+               $scope.schemaLocation=schemaLocation;
+               $scope.userID=userID;
+               $scope.password=password;
+
+               document.getElementById("fileUpload").disabled = true;  
+            
+               var svnUploadURL = "/utm-service/schema_upload/svnUploadWSDL";
+          
+               svnservice.SVNToUrl(schemaLocation, userID, password,svnURL,svnUploadURL)
+                       .then(function(pars) {
+                    console.log("pars");
+                               document.getElementById('Upgrade Schema Version').classList.remove('ThisLink');
+                               document.getElementById('Set Default Values').classList.remove('ThisLink');
+                               $rootScope.wsdlInfo = angular.fromJson(pars);
+                               $rootScope.serviceInfo =  $rootScope.wsdlInfo.serviceInfo;
+                               serviceName = $rootScope.serviceInfo.service.name;
+                               $rootScope.schemaLocation=$rootScope.wsdlInfo.schemaLocation;
+                               $rootScope.serviceInput = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage;
+                               $rootScope.serviceInputPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage.partInfo;
+                               
+                               $rootScope.serviceOutput = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage;
+                       $rootScope.serviceOutputPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage.partInfo;
+                       
+                       $rootScope.servicefault = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage;
+                       $rootScope.servicefaultPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage.partInfo;
+                               
+                               //alert("serviceInputPartInfo :: " + JSON.stringify($rootScope.serviceInputPartInfo));
+                       
+                       $rootScope.inputSchemaServiceInputPartInfo=[];
+                       $rootScope.inputSchemaServiceOutputPartInfo=[];
+                       $rootScope.inputSchemaServicefaultPartInfo=[];
+                       
+                       
+                        
+                     angular.copy($rootScope.serviceInputPartInfo, $rootScope.inputSchemaServiceInputPartInfo);
+                     
+                     angular.copy($rootScope.serviceOutputPartInfo, $rootScope.inputSchemaServiceOutputPartInfo);
+                     
+                     angular.copy($rootScope.servicefaultPartInfo, $rootScope.inputSchemaServicefaultPartInfo);
+                     
+                               $rootScope.isModel = true;
+                       },
+                       function(data) {
+                    console.log("data");
+                               //alert("File upload failed and parameters not returned");
+                       });
+        } else  {
+               var uploadUrl = "/utm-service/schema_upload/uploadWSDL";
+            
+            fileUpload.uploadFileToUrl(file, uploadUrl)
+            .then(function(pars) {
+                console.log("pars");
+               document.getElementById('Upgrade Schema Version').classList.remove('ThisLink');
+               document.getElementById('Set Default Values').classList.remove('ThisLink');
+               //document.getElementById('Define/Modify Schema').classList.remove('ThisLink');
+               $rootScope.wsdlInfo = angular.fromJson(pars);
+               $rootScope.serviceInfo =  $rootScope.wsdlInfo.serviceInfo;
+               serviceName = $rootScope.serviceInfo.service.name;
+               
+               $rootScope.serviceInput = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage;
+               $rootScope.serviceInputPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage.partInfo;
+               
+               //alert("Input Part Info :: " + JSON.stringify($rootScope.serviceInputPartInfo));
+               //alert("Input Part 1 Info :: " + JSON.stringify($rootScope.serviceInputPartInfo[1]));
+               
+               //alert("Input Element :: " + JSON.stringify($rootScope.serviceInputPartInfo[1].schemaElements[1].elements[0]));
+               
+               $rootScope.serviceOutput = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage;
+               $rootScope.serviceOutputPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage.partInfo;
+               
+               $rootScope.servicefault = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage;
+               $rootScope.servicefaultPartInfo = $rootScope.serviceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage.partInfo;
+               
+               //alert("servicefaultPartInfo :: " + JSON.stringify($rootScope.servicefaultPartInfo));
+               
+               $rootScope.inputSchemaServiceInputPartInfo=[];
+               $rootScope.inputSchemaServiceOutputPartInfo=[];
+               $rootScope.inputSchemaServicefaultPartInfo=[];
+               
+               
+                
+                 angular.copy($rootScope.serviceInputPartInfo, $rootScope.inputSchemaServiceInputPartInfo);
+                 
+                 angular.copy($rootScope.serviceOutputPartInfo, $rootScope.inputSchemaServiceOutputPartInfo);
+                 
+                 angular.copy($rootScope.servicefaultPartInfo, $rootScope.inputSchemaServicefaultPartInfo);
+            
+               $rootScope.isModel = true;              
+               },
+            function(data) {
+                console.log("data");
+               
+            });
+        }
+        
+       
+        
+        
+        
+               $modalInstance.close("closed");
+       };
+       
+        $scope.setFile = function(element) {
+        console.log("setFile");
+                
+         $scope.$apply(function($scope) {
+            console.log("apply");
+             $scope.theFile = element.files[0];
+             $rootScope.fileName =$scope.theFile.name;
+            var file =element.files[0]; 
+            $rootScope.file_path = file;
+        
+               //$modalInstance.close("closed");
+            
+             angular.element(document.getElementById('fileUpload')).val(null);
+               
+         });
+     };
+     
+     $scope.setUpgradeFile = function(element) {
+                console.log("setUpgradeFile");
+         $scope.$apply(function($scope) {
+            console.log("apply");
+             $scope.theUpgradeFile = element.files[0];
+             $rootScope.upgradeFileName =$scope.theUpgradeFile.name;
+            //alert("fname1"+$rootScope.upgradeFileName);
+            var file =element.files[0]; 
+            $rootScope.file_path = file;
+        
+               //$modalInstance.close("closed");
+            
+             angular.element(document.getElementById('fileUpload')).val(null);
+               
+         });
+     };
+     
+     
+     
+     $scope.reset = function(){
+        console.log("reset");
+        document.getElementById("fileUpload").disabled = false;
+        document.getElementById("schemaLocation").disabled = false;
+        document.getElementById("userID").disabled = false;
+        document.getElementById("password").disabled = false;
+        
+        document.getElementById("schemaLocation").value='';
+         
+         document.getElementById("userID").value='';
+         document.getElementById("password").value='';
+         $scope.theFile = null;
+         angular.element(document.getElementById('fileUpload')).val(null);
+       
+        
+     };
+     
+     $scope.upgradeSchema = function(){
+        console.log("upgradeSchema");
+        //alert("inside upgrade schema");
+                var file=$rootScope.file_path; 
+               //alert("file:"+schemaFile);
+         //console.log('file is ' + JSON.stringify(file)); 
+         var userID = document.getElementById("userID").value;
+         var password = document.getElementById("password").value;
+         var schemaLocation = document.getElementById("upgradeSchemaLocation").value;
+         var svnURL = document.getElementById("upgradeSchemaLocation").value;
+         console.log("after");
+         $rootScope.Currentmappedvalues = [];
+         if( schemaLocation &&  userID && password && document.getElementById("upgradeSchemaLocation").disabled== false)
+         {
+               $scope.schemaLocation=schemaLocation;
+               $scope.userID=userID;
+               $scope.password=password;
+               
+               document.getElementById("fileUpload").disabled = true;  
+             
+               var svnUploadURL = "/utm-service/schema_upload/svnUploadWSDL";
+           
+               svnservice.SVNToUrl(schemaLocation, userID, password,svnURL,svnUploadURL)
+                       .then(function(pars) {
+                    console.log("pars");
+                               $rootScope.updateWsdlInfo = angular.fromJson(pars);
+                               $rootScope.updateServiceInfo =  $rootScope.updateWsdlInfo.serviceInfo;
+                               $rootScope.schemaLocation=$rootScope.updateWsdlInfo.schemaLocation;
+                               $rootScope.updateServiceInput = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage;
+                               $rootScope.updateServiceInputPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage.partInfo;
+                               
+                               $rootScope.updateServiceOutput = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage;
+                       $rootScope.updateServiceOutputPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage.partInfo;
+                       
+                       $rootScope.updateServicefault = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage;
+                       $rootScope.updateServicefaultPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage.partInfo;
+                               
+                               //alert("serviceInputPartInfo :: " + JSON.stringify($rootScope.serviceInputPartInfo));
+         
+                               //$rootScope.isModel = true;
+                       },
+                       function(data) {
+                    console.log("data");
+                               //alert("File upload failed and parameters not returned");
+                       });
+         } else  {
+               var uploadUrl = "/utm-service/schema_upload/uploadWSDL";
+             
+             fileUpload.uploadFileToUrl(file, uploadUrl)
+             .then(function(pars) {
+                console.log("pars");
+               
+                       $rootScope.updateWsdlInfo = angular.fromJson(pars);
+               //      alert("wsdlinfo:"+$rootScope.updateWsdlInfo);
+               $rootScope.updateServiceInfo =  $rootScope.updateWsdlInfo.serviceInfo;
+               
+               $rootScope.updateServiceInput = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage;
+               $rootScope.updateServiceInputPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].inputMessage.partInfo;
+               
+               $rootScope.updateServiceOutput = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage;
+               $rootScope.updateServiceOutputPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].outputMessage.partInfo;
+               
+               $rootScope.updateServicefault = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage;
+               $rootScope.updateServicefaultPartInfo = $rootScope.updateServiceInfo.bindingInfo.portTypeInfo.operationInfo[0].faultMessage.partInfo;
+               
+               //alert("servicefaultPartInfo :: " + JSON.stringify($rootScope.servicefaultPartInfo));
+               
+             
+               //$rootScope.isModel = true;                    
+               },
+             function(data) {
+                console.log("data");
+               
+             });
+         }
+        
+               $modalInstance.close("closed");
+               
+               var dlg = dialogs.create('partials/portfolios/upgrade_schema_dtls.html','UpgradeSchemaCtrl',{},{size:'xlg',keyboard: true,backdrop: true,windowClass: 'my-class'});
+               dlg.result.then(function(name){
+            console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });
+       
+        
+     };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/SetDefaultValueCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/SetDefaultValueCtrl.js
new file mode 100644 (file)
index 0000000..4aaf595
--- /dev/null
@@ -0,0 +1,206 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.directive('inputInfoDVClass', function ($compile) {
+    console.log("/////////////inputInfoDVClass");
+  return {
+      restrict: "C",
+      replace: true,
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         scope.sourceExplorer = 'SDV';
+         angular.forEach(scope.infoType.schemaElements, function(value, key){
+            console.log("schemaElement");
+                 
+                 scope.schemaElement = value;
+                 
+                 if(scope.schemaElement.complexType != null){
+                         if(scope.currentElementName == ''){
+                                 scope.currentElementName = scope.schemaElement.complexType.name;
+                         }
+                         
+                         scope.ParentKey = scope.parentName + '_' + scope.currentElementName;
+                         if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                                 scope.ParentKey = scope.ParentKey + scope.schemaElement.repeatableHierarchicalPrefix; 
+                         }
+                         scope.parElement = scope.schemaElement;
+                         scope.tableStyle = 'table-level' + scope.heirarchyLevel + '-tree'; 
+                         scope.tdLabelStyle = 'td-level' + scope.heirarchyLevel + '-label-tree'; 
+                         scope.heirLevel = scope.heirarchyLevel;
+                         
+                         elementHTML = elementHTML + '<div ng-show="schemaElement.complexType != null">';
+                         elementHTML = elementHTML + '<table class="{{tableStyle}}"> <tr>';
+                         elementHTML = elementHTML + '<td class="{{tdLabelStyle}}">';
+                         elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                         elementHTML = elementHTML + '<i ng-class="showUTMViewMsgHeader == true ?\'fa fa-plus-circle\':\'fa fa-minus-circle\'"></i>';
+                         elementHTML = elementHTML + '</span>';
+                         elementHTML = elementHTML + '<b>{{currentElementName}}</b>';
+                         elementHTML = elementHTML + '</td>';
+                         elementHTML = elementHTML + '</tr></table>';
+                         elementHTML = elementHTML + '<div style="margin-left: 10px" ng-class="{hidden:showUTMViewMsgHeader,chaldean:showUTMViewMsgHeader}">';
+                         elementHTML = elementHTML + '<div class="inputInfoDVClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.elements"></div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         var x = angular.element(elementHTML);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+             });
+         
+      }
+  }
+});
+
+app.directive('inputInfoDVClassMember', function ($compile) {
+    console.log("inputInfoDVClassMember");
+  return {
+      restrict: "C",
+
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         
+         scope.currentElementName=scope.objectName;
+         scope.parentName=scope.ParentKey; 
+         scope.parentElement=scope.parElement; 
+         scope.heirarchyLevel = scope.heirLevel + 1;
+         
+         if(scope.schemaElement.element.name != null){
+                 
+                 scope.elementKey=scope.parentName + '_' + scope.schemaElement.element.name;
+                 if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                         scope.elementKey = scope.elementKey + scope.schemaElement.repeatableHierarchicalPrefix;
+                 }
+                 scope.tableStyle='table-level' + scope.heirarchyLevel + '-tree'; 
+                 scope.tdLabelStyle='td-level' + scope.heirarchyLevel +'-label-tree';
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         scope.showUTMViewMsgHeader = false;
+                         
+                 }else{
+                         scope.showUTMViewMsgHeader = true;
+                         
+                 }
+                 
+                 elementHTML = elementHTML + '<div ng-show="schemaElement.element.name != null">';
+                 elementHTML = elementHTML + '<div id="elementKey">';
+                 //console.log(scope.utmSchemaExts);
+                 elementHTML = elementHTML + '<div ng-show = "schemaElement.type.complexType != null || utmSchemaExts[elementKey].checked">';
+                 elementHTML = elementHTML + '<table class="{{tableStyle}}"> ';
+                 elementHTML = elementHTML + '<tr>';
+                 elementHTML = elementHTML + '<td style="text-align: left;vertical-align: top;" class="{{tdLabelStyle}}">';
+                 elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                 elementHTML = elementHTML + '<i expandable ng-class="showUTMViewMsgHeader == true ?\'fa fa-minus-circle\':\'fa fa-plus-circle\'"></i>';
+                 elementHTML = elementHTML + '{{schemaElement.element.name}}  ';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '</span>';
+                 elementHTML = elementHTML + '</td>';
+                 
+                 elementHTML = elementHTML + '<td style="width: 70px"></td>';
+                 elementHTML = elementHTML + '<td style="width: 40px; float: left;">';
+                 if(scope.schemaElement.type.complexType == null){
+                         elementHTML = elementHTML + '<div ng-show="schemaElement.type.complexType == null">';
+                         elementHTML = elementHTML + '<div ng-repeat="object in filteredObjects = (schemaElement.type.restriction.minExclusivesAndMinInclusivesAndMaxExclusives | filter: {name : \'enumeration\'})"></div>';
+                         elementHTML = elementHTML + '<div ng-if="filteredObjects.length > 0" class="defaultSelect">';
+                         elementHTML = elementHTML + '<input type="text" id="{{elementKey}}" class="defaultVal" ng-model="utmSchemaExts[elementKey].defaultValue" style="width:220px;"/>';
+                         elementHTML = elementHTML + '<select  style="width: 240px;" id="{{elementKey}}" onchange="this.previousElementSibling.value=this.value;"  ng-model="utmSchemaExts[elementKey].defaultValue" ng-options="filteredObject.value.value as filteredObject.value.value for filteredObject in filteredObjects">';
+                         elementHTML = elementHTML + '<option value=""></option>';
+                         elementHTML = elementHTML + '</select>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-if="filteredObjects == null || filteredObjects.length == 0">';
+                         elementHTML = elementHTML + '<div ng-if="schemaElement.type != null && schemaElement.type==\'boolean\'">';
+                         elementHTML = elementHTML + '<div style="display: inline-flex">';
+                         elementHTML = elementHTML + '<input type="radio" name="{{elementKey}}" id="{{elementKey}}" value="true" ng-model="utmSchemaExts[elementKey].defaultValue">True <span style="width:20px;"></span>';
+                         elementHTML = elementHTML + '<input type="radio" name="{{elementKey}}" id="{{elementKey}}" value="false" ng-model="utmSchemaExts[elementKey].defaultValue">False';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-if="schemaElement.type == null || schemaElement.type != \'boolean\'">';
+                         elementHTML = elementHTML + '<input type="text"  id="{{elementKey}}"  style="width: 240px;" class="defaultVal" ng-model="utmSchemaExts[elementKey].defaultValue"/>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                 }
+                 
+                 elementHTML = elementHTML + '</td>';
+                 
+                 elementHTML = elementHTML + '</tr>';
+                 elementHTML = elementHTML + '<br/>';
+                 elementHTML = elementHTML + '</table>';
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '</div>';
+                 
+                 var x = angular.element(elementHTML);
+                element.append(x);
+                $compile(x)(scope);
+                 
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         var elementHTML2 = '<div ng-show="schemaElement.type.complexType != null">'
+                         elementHTML2 = elementHTML2 + '<div ng-init="parKey=parentName + \'_\' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\'); heirLevel=heirarchyLevel; parElement=schemaElement; ParentKey=ParentKey+\'_\'+schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\')">'
+                         elementHTML2 = elementHTML2 + '<div style="margin-left: 10px" ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">'
+                         elementHTML2 = elementHTML2 + '<div class="{{sourceExplorer+\'_\'+parKey}}"></div>'
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>';
+                         var x = angular.element(elementHTML2);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+                 
+         }
+
+      }
+  }
+});
+
+/*app.controller('SetDefaultValueCtrl', ['$scope', '$rootScope','$modalInstance','$location', function($scope,$rootScope,$modalInstance,$location){
+    console.log("SetDefaultValueCtrl");
+       $scope.utmSchemaExts = {};
+       
+       $scope.init = function () {
+    console.log("init");               
+               //console.log("$rootScope.defValuesObject :: " + JSON.stringify(list_model_schema_extensions[selected_model]));
+               if(list_model_schema_extensions[selected_model] != null && list_model_schema_extensions[selected_model].utmSchemaExtentionMap != null) {
+                       $scope.utmSchemaExts = list_model_schema_extensions[selected_model].utmSchemaExtentionMap;
+                       $scope.previous_utmSchemaExts = angular.copy($scope.utmSchemaExts);
+                       //console.log("$scope.defaultValuesObject :: " + $scope.utmSchemaExts);
+               }
+       };
+       
+       $scope.init();
+       
+       $scope.setDefaultValue= function(){     
+        console.log("setDefaultValue");
+               list_model_schema_extensions[selected_model].utmSchemaExtentionMap = $scope.utmSchemaExts;
+               $rootScope.isModel = true;
+               $modalInstance.close("closed");         
+       };
+
+       $scope.close = function(){
+        console.log("close");
+               list_model_schema_extensions[selected_model].utmSchemaExtentionMap = $scope.previous_utmSchemaExts;
+               $modalInstance.close("closed");
+       };
+}]);*/
diff --git a/src/main/resources/META-INF/resources/designer/scripts/UpgradeSchemaCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/UpgradeSchemaCtrl.js
new file mode 100644 (file)
index 0000000..21646f7
--- /dev/null
@@ -0,0 +1,560 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+var elementKeys = [];
+
+app.directive('inputInfoUpgradeClass', function ($compile) {
+    console.log("////UpgradeSchemaCtrl");
+  return {
+      restrict: "C",
+      replace: true,
+      link: function(scope,element,attrs){
+          var elementHTML = '';
+          angular.forEach(scope.infoType.schemaElements, function(value, key){
+              
+              scope.schemaElement = value;
+              
+              if(scope.schemaElement.complexType != null){
+                  if(scope.currentElementName == ''){
+                      scope.currentElementName = scope.schemaElement.complexType.name;
+                  }
+                  
+                  scope.ParentKey = scope.parentName + '_' + scope.currentElementName;
+                  if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                      scope.ParentKey = scope.ParentKey + scope.schemaElement.repeatableHierarchicalPrefix; 
+                  }
+                  scope.parElement = scope.schemaElement;
+                  scope.tableStyle = 'table-level' + scope.heirarchyLevel + '-tree'; 
+                  scope.tdLabelStyle = 'td-level' + scope.heirarchyLevel + '-label-tree'; 
+                  scope.heirLevel = scope.heirarchyLevel;
+                  
+                  elementHTML = elementHTML + '<div ng-show="schemaElement.complexType != null">';
+                  elementHTML = elementHTML + '<table class="{{tableStyle}}"> <tr>';
+                  elementHTML = elementHTML + '<td class="{{tdLabelStyle}}">';
+                  elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                  elementHTML = elementHTML + '<i ng-class="showUTMViewMsgHeader == true ?\'fa fa-plus-circle\':\'fa fa-minus-circle\'"></i>';
+                  elementHTML = elementHTML + '</span>';
+                  elementHTML = elementHTML + '<b>{{currentElementName}}</b>';
+                  elementHTML = elementHTML + '</td>';
+                  elementHTML = elementHTML + '<td class="td-tree"></td>';
+                  elementHTML = elementHTML + '<td class="td-default_value-tree"> </td>';
+                  elementHTML = elementHTML + '</tr></table>';
+                  elementHTML = elementHTML + '<div style="margin-left: 10px" ng-class="{hidden:showUTMViewMsgHeader,chaldean:showUTMViewMsgHeader}">';
+                  elementHTML = elementHTML + '<div class="inputInfoUpgradeClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.elements"></div>';
+                  elementHTML = elementHTML + '</div>';
+                  elementHTML = elementHTML + '</div>';
+                  var x = angular.element(elementHTML);
+                    element.append(x);
+                    $compile(x)(scope);
+              }
+          });
+          
+      }
+  }
+});
+
+app.directive('inputInfoUpgradeClassMember', function ($compile) {
+  return {
+      restrict: "C",
+
+      link: function(scope,element,attrs){
+          var elementHTML = '';
+          
+          scope.currentElementName=scope.objectName;
+          scope.parentName=scope.ParentKey; 
+          scope.parentElement=scope.parElement; 
+          scope.heirarchyLevel = scope.heirLevel + 1;
+          
+          if(scope.schemaElement.element.name != null){
+              
+              scope.elementKey=scope.parentName + '_' + scope.schemaElement.element.name;
+              if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                  scope.elementKey = scope.elementKey + scope.schemaElement.repeatableHierarchicalPrefix;
+              }
+              scope.tableStyle='table-level' + scope.heirarchyLevel + '-tree'; 
+              scope.tdLabelStyle='td-level' + scope.heirarchyLevel +'-label-tree';
+              
+              if(scope.schemaElement.type.complexType != null){
+                  scope.showUTMViewMsgHeader = false;
+                  
+              }else{
+                  scope.showUTMViewMsgHeader = true;
+                  
+              }
+              
+              elementHTML = elementHTML + '<div ng-show="schemaElement.element.name != null">';
+              elementHTML = elementHTML + '<table class="{{tableStyle}}"> ';
+              elementHTML = elementHTML + '<tr>';
+              elementHTML = elementHTML + '<td style="text-align: left;vertical-align: top;" class="{{tdLabelStyle}}">';
+              elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+              elementHTML = elementHTML + '<div style="display:inline">';
+              elementHTML = elementHTML + '<input type="radio" name={{radioName}} id="{{elementKey}}" value={{schemaElement.element.name}}>';
+              elementHTML = elementHTML + '</div>';
+              elementHTML = elementHTML + '<i expandable ng-class="showUTMViewMsgHeader == true ?\'fa fa-minus-circle\':\'fa fa-plus-circle\'"></i>';
+              elementHTML = elementHTML + '{{schemaElement.element.name}}  ';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '</span>';
+              elementHTML = elementHTML + '<div ng-init="complexMapElements(elementKey,schemaElement,radioName)"></div>';
+              elementHTML = elementHTML + '</td>';
+              
+              elementHTML = elementHTML + '</tr>';
+              elementHTML = elementHTML + '</table>';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '';
+              elementHTML = elementHTML + '</div>';
+              
+              var x = angular.element(elementHTML);
+                element.append(x);
+                $compile(x)(scope);
+              
+              
+              if(scope.schemaElement.type.complexType != null){
+                  var elementHTML2 = '<div ng-show="schemaElement.type.complexType != null">'
+                  elementHTML2 = elementHTML2 + '<div ng-init="parKey=parentName + \'_\' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\'); heirLevel=heirarchyLevel; parElement=schemaElement; ParentKey=ParentKey+\'_\'+schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\')">'
+                  elementHTML2 = elementHTML2 + '<div style="margin-left: 10px" ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">'
+                  elementHTML2 = elementHTML2 + '<div class="{{sourceExplorer+\'_\'+parKey}}"></div>'
+                  elementHTML2 = elementHTML2 + '</div>'
+                  elementHTML2 = elementHTML2 + '</div>'
+                  elementHTML2 = elementHTML2 + '</div>';
+                  var x = angular.element(elementHTML2);
+                    element.append(x);
+                    $compile(x)(scope);
+              }
+              
+          }
+
+      }
+  }
+});
+
+app.controller(
+                'UpgradeSchemaCtrl',
+                [
+                        '$scope',
+                        '$rootScope',
+                        '$modalInstance',
+                        'dialogs',
+                        function($scope, $rootScope, $modalInstance,dialogs) {
+
+                            $rootScope.Currentmappedvalues = [];
+                            $scope.utmSchemaExts = {};
+                            
+                            $scope.callFromMap=false;
+                            $scope.oldMapValFlag=false;
+                            
+                            $scope.complexMappedValuesOld = {};
+                            $scope.complexMappedValuesNew = {};
+                            var allCurrentElementKeyArray=[];
+                            
+                            $scope.checkedValues = {};
+                            var checkedElementValueArray=[];
+                            
+                            
+                            $scope.complexMapElements = function(elementKey,schemaElement,radioName) {
+                                if (schemaElement.complexType != null || (schemaElement.type != null && schemaElement.type.complexType != null)) {
+                                    if(radioName=="oldChk")
+                                        $scope.complexMappedValuesOld[elementKey]=schemaElement;
+                                    else if(radioName=="newChk")
+                                        $scope.complexMappedValuesNew[elementKey]=schemaElement;
+                                }
+                                if(elementKey != null)
+                                    allCurrentElementKeyArray.push(elementKey);
+                            
+                            };
+                            
+                            $scope.mapElements = function() {
+                                
+                                var oldVal = $('input[name=oldChk]:checked')
+                                        .val();
+                                var newVal = $('input[name=newChk]:checked')
+                                        .val();
+                                var oldId = $('input[name=oldChk]:checked')
+                                        .attr('id');
+                                var newId = $('input[name=newChk]:checked')
+                                        .attr('id');
+                                $scope.mappedvalues = {};
+                                
+                                $scope.checkedValues.oldVal=oldVal;
+                                $scope.checkedValues.newVal=newVal;
+                                
+                                checkedElementValueArray.push($scope.checkedValues);
+                                
+                                
+                                $scope.oldMappedvaluesKeyArray = [];
+                                $scope.newMappedvaluesKeyArray = [];
+                                $scope.oldmappedvaluesArray = [];
+                                $scope.newMappedvaluesArray = [];
+                                
+                                if($scope.complexMappedValuesOld[oldId] != null && $scope.complexMappedValuesNew[newId] != null){
+                                    $scope.matchType='';
+                                    $scope.matchType=$scope.compareElements($scope.complexMappedValuesOld[oldId],$scope.complexMappedValuesNew[newId]);
+                                    if($scope.matchType == "true"){
+                                        console.log("Element Type Matches and eligible for upgrade schema");
+                                        
+                                        $scope.callFromMap=true;
+                                        for (var i = 0; i < $scope.complexMappedValuesOld[oldId].type.elements.length; i++) {
+                                            $scope.oldMapValFlag=true;
+                                            getElementkeys(oldId, $scope.complexMappedValuesOld[oldId].type.elements[i]);
+                                        }
+                                        
+                                        for (var j = 0; j < $scope.complexMappedValuesNew[newId].type.elements.length; j++) {
+                                            $scope.oldMapValFlag=false;
+                                            getElementkeys(newId, $scope.complexMappedValuesNew[newId].type.elements[j]);
+                                        }
+                                        
+                                        for (var k = 0; k < $scope.oldmappedvaluesArray.length; k++) {
+                                            
+                                            $scope.mappedvalues = {};
+                                            
+                                            $scope.mappedvalues.oldvalue = $scope.oldmappedvaluesArray[k];
+                                            $scope.mappedvalues.newvalue = $scope.newMappedvaluesArray[k];
+                                            $scope.mappedvalues.oldidvalue = $scope.oldMappedvaluesKeyArray[k];
+                                            $scope.mappedvalues.newidvalue = $scope.newMappedvaluesKeyArray[k];
+                                            $rootScope.Currentmappedvalues
+                                                    .push($scope.mappedvalues);
+                                        }
+                                    }
+                                    else if($scope.matchType == "false")    {
+                                        
+                                        dialogs.error('Invalid Selection Error','The mapping of the selected elements is invalid. Please select valid complex elements for Upgrade Schema');
+                                            
+                                    }
+                                    
+                                    
+                                }
+                                else if(($scope.complexMappedValuesOld[oldId] == null && $scope.complexMappedValuesNew[newId] != null) || ($scope.complexMappedValuesOld[oldId] != null && $scope.complexMappedValuesNew[newId] == null)){
+                                        
+                                    dialogs.error('Invalid Selection Error','The mapping of the selected elements is invalid. Please select valid complex elements for Upgrade Schema');
+                                }
+                                else{
+                                    
+                                $scope.mappedvalues.oldvalue = oldVal;
+                                $scope.mappedvalues.newvalue = newVal;
+                                $scope.mappedvalues.oldidvalue = oldId;
+                                $scope.mappedvalues.newidvalue = newId;
+                                $rootScope.Currentmappedvalues
+                                        .push($scope.mappedvalues);
+                                }
+                                $rootScope.checkRepeatable = false;
+
+                            };
+                            
+                            //Utility Method to compare Object Structure of Complex Type Elements before upgrade schema
+                            $scope.compareElements = function(oldElement, newElement) {
+                                
+                                if (oldElement.type.complexType !=null && newElement.type.complexType !=null) {
+                                    if (oldElement.type.elements.length==newElement.type.elements.length) {
+                                        for (var i = 0; i < oldElement.type.elements.length; i++) {
+                                            if(oldElement.type.elements[i].type.complexType !=null && newElement.type.elements[i].type.complexType !=null){
+                                                $scope.compareElements(oldElement.type.elements[i], newElement.type.elements[i]);
+                                            
+                                            }else if(oldElement.type.elements[i].type.complexType ==null && newElement.type.elements[i].type.complexType !=null){
+                                                $scope.matchType="false";
+                                                return $scope.matchType;
+                                            }
+                                            if($scope.matchType == "false")
+                                                return $scope.matchType;
+                                            }
+                                        for (var i = 0; i < newElement.type.elements.length; i++) {
+                                            if(newElement.type.elements[i].type.complexType !=null && oldElement.type.elements[i].type.complexType !=null){
+                                                $scope.compareElements(newElement.type.elements[i], oldElement.type.elements[i]);
+                                            }else if(newElement.type.elements[i].type.complexType ==null && oldElement.type.elements[i].type.complexType !=null){
+                                                $scope.matchType="false";
+                                                return $scope.matchType;
+                                            }
+                                            if($scope.matchType == "false")
+                                                return $scope.matchType;
+                                            }
+                                        $scope.matchType="true";
+                                        return $scope.matchType;
+                                    }
+                                    else
+                                        $scope.matchType="false";
+                                        return $scope.matchType;
+                                        
+                                }
+                                
+                            };
+
+
+                            $scope.checkRepeatableElement = function(
+                                    elementKey, key) {
+
+                                if (elementKey != key)
+                                    $rootScope.checkRepeatable = true;
+
+                            };
+
+                            $scope.upgradeSchema = function() {
+                                //console.log("List Model Path Details before Upgrade Schema :: " + JSON.stringify(list_model_path_details[selected_model]));
+                                
+                                $scope.callFromMap=false;
+                                $rootScope.isHorR = true;
+                                
+                                $rootScope.repeatableHeirarchicalElementMap = map_model_repeatable_heirarchical_elements[selected_model];
+                                
+                                //Checking Repeatable Hierarchical elements mapping and changing elementkey if repeatable hierarchical is mapped
+                                for (var key in $rootScope.repeatableHeirarchicalElementMap) {
+                                    for(var i=0;i<allCurrentElementKeyArray.length;i++){
+                                        if(allCurrentElementKeyArray[i].indexOf(key) > -1)
+                                            elementKeys.push(allCurrentElementKeyArray[i]);
+                                    }
+                                    for (var j = 0; j< checkedElementValueArray.length; j++) {
+                                        var currentCheckedMappedvalue = checkedElementValueArray[j];    
+                                        if (key.indexOf(currentCheckedMappedvalue.oldVal) > -1){
+                                            
+                                            var newObject=JSON.stringify($rootScope.repeatableHeirarchicalElementMap);
+                                            
+                                            var oldvalue=currentCheckedMappedvalue.oldVal;
+                                            var newvalue=currentCheckedMappedvalue.newVal;
+                                            
+                                            var modObject= newObject.replace(oldvalue, newvalue);
+                                        
+                                            $rootScope.repeatableHeirarchicalElementMap=angular.fromJson(modObject);
+                                            
+                                            /*for (var k = 0; k < elementKeys.length; k++) {
+                                                
+                                                if (elementKeys[k].indexOf(currentCheckedMappedvalue.oldVal) > -1){
+                                                    
+                                                elementKeys[k]=elementKeys[k].replace(oldvalue, newvalue);
+                                                    
+                                                }
+                                                
+                                            }*/
+                                            
+                                        }
+                                    }
+                                    
+                                }
+                                
+                                
+                                $scope.oldSchemaLocation = $rootScope.wsdlInfo.schemaLocation;
+                                $rootScope.wsdlInfo = $rootScope.updateWsdlInfo;
+                                $rootScope.wsdlInfo.schemaUpgradedFlag = true;
+                                $rootScope.wsdlInfo.oldSchemaLocation = $scope.oldSchemaLocation;
+                                
+                                $rootScope.serviceInfo = $rootScope.updateServiceInfo;
+                                $rootScope.schemaLocation = $rootScope.updateWsdlInfo.schemaLocation;
+                                $rootScope.serviceInput = $rootScope.updateServiceInput;
+                                $rootScope.serviceInputPartInfo = $rootScope.updateServiceInputPartInfo;
+                                
+                                $rootScope.inputSchemaServiceInputPartInfo=[];
+                                $rootScope.inputSchemaServiceOutputPartInfo=[];
+                                $rootScope.inputSchemaServicefaultPartInfo=[];
+                                angular.copy($rootScope.serviceInputPartInfo, $rootScope.inputSchemaServiceInputPartInfo);
+                                angular.copy($rootScope.serviceOutputPartInfo, $rootScope.inputSchemaServiceOutputPartInfo);
+                                angular.copy($rootScope.servicefaultPartInfo, $rootScope.inputSchemaServicefaultPartInfo);
+
+                                //Form all the element keys of the Upgraded Schema so that to know the attibutes removed                                
+                                for (var i = 0; i < $rootScope.serviceInputPartInfo.length; i++) {
+                                    for (var j = 0; j < $rootScope.serviceInputPartInfo[i].schemaElements.length; j++) {
+                                        getElementkeys(
+                                                'ServiceInput',
+                                                $rootScope.serviceInputPartInfo[i].schemaElements[j]);
+                                    }
+                                }
+                                $rootScope.serviceOutput = $rootScope.updateServiceOutput;
+                                $rootScope.serviceOutputPartInfo = $rootScope.updateServiceOutputPartInfo;
+                                for (var i = 0; i < $rootScope.serviceOutputPartInfo.length; i++) {
+                                    for (var j = 0; j < $rootScope.serviceOutputPartInfo[i].schemaElements.length; j++) {
+                                        getElementkeys(
+                                                'ServiceOutput',
+                                                $rootScope.serviceOutputPartInfo[i].schemaElements[j]);
+                                    }
+                                }
+                                $rootScope.servicefault = $rootScope.updateServicefault;
+                                $rootScope.servicefaultPartInfo = $rootScope.updateServicefaultPartInfo;
+                                for (var i = 0; i < $rootScope.servicefaultPartInfo.length; i++) {
+                                    for (var j = 0; j < $rootScope.servicefaultPartInfo[i].schemaElements.length; j++) {
+                                        getElementkeys(
+                                                'ServiceFault',
+                                                $rootScope.servicefaultPartInfo[i].schemaElements[j]);
+                                    }
+                                }
+                                console.log("mapped values of current"+ JSON.stringify($rootScope.Currentmappedvalues));
+                                
+                                //For each model in the project
+                                // a) For the mapped elements
+                                //       i) replace the old ids with new ids for the Schema Extensions
+                                //      ii) replace the old ids with new ids for the Path Details
+                                // b) For the deleted attributes in the Upgraded schema 
+                                //       i) Remove the ids from Schema Extensions
+                                //      ii) Remove the ids from Path Details
+                                for(var modelIndex=0; modelIndex < $rootScope.models.length; modelIndex++) {
+                                    var current_model = $rootScope.models[modelIndex];
+                                    $scope.utmSchemaExts = list_model_schema_extensions[current_model].utmSchemaExtentionMap;
+                                    $scope.pathDetailsArray = list_model_path_details[current_model];
+                                
+                                    for (var i = 0; i < $rootScope.Currentmappedvalues.length; i++) {
+                                        $scope.mappedvalues = $rootScope.Currentmappedvalues[i];
+    
+                                        if($scope.utmSchemaExts != null) {
+                                            $scope.utmSchemaExts[$scope.mappedvalues.newidvalue] = $scope.utmSchemaExts[$scope.mappedvalues.oldidvalue];
+                                            if($scope.mappedvalues.newidvalue != $scope.mappedvalues.oldidvalue)
+                                                delete $scope.utmSchemaExts[$scope.mappedvalues.oldidvalue];
+                                        }
+                                        
+                                        if($scope.pathDetailsArray != null && $scope.pathDetailsArray.length > 0 ) {
+                                            for (var k = 0; k < $scope.pathDetailsArray.length; k++) {
+                                                $scope.pathDetails = $scope.pathDetailsArray[k];
+                                                
+                                                if ($scope.pathDetails != null) {
+                                                    for (var j = 0; j < $scope.pathDetails.decisionIdentifiers.length; j++) {
+                                                        if($scope.pathDetails.decisionIdentifiers[j].elementValues[$scope.mappedvalues.oldidvalue] != null)
+                                                            $scope.pathDetails.decisionIdentifiers[j].elementValues[$scope.mappedvalues.newidvalue] = $scope.pathDetails.decisionIdentifiers[j].elementValues[$scope.mappedvalues.oldidvalue];
+                                                        if($scope.mappedvalues.newidvalue != $scope.mappedvalues.oldidvalue)
+                                                            delete $scope.pathDetails.decisionIdentifiers[j].elementValues[$scope.mappedvalues.oldidvalue];
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                    
+                                    $scope.schemenExts = angular.copy($scope.utmSchemaExts);
+    
+                                    //If an attribute is removed from upgraded schema, remove that attribute related details from SchemaExtensions
+                                    Object.keys($scope.schemenExts).forEach(
+                                        function(key) {
+                                            var key_isavailable = false;
+                                            for (var j = 0; j < elementKeys.length; j++) {
+                                                
+                                                /*for (var m = 0; m < checkedElementValueArray.length; m++) {
+                                                    
+                                                    var currentCheckedMappedvalue = checkedElementValueArray[m];
+                                                    if ((key.indexOf(currentCheckedMappedvalue.oldVal) > -1) && (currentCheckedMappedvalue.oldVal != currentCheckedMappedvalue.newVal)){
+                                                    
+                                                        var oldvalue=currentCheckedMappedvalue.oldVal;
+                                                        var newvalue=currentCheckedMappedvalue.newVal;
+                                                        
+                                                        key= key.replace(oldvalue, newvalue);
+                                                        
+                                                        elementKeys.push(key);
+                                                    
+                                                        //list_model_schema_extensions[current_model].utmSchemaExtentionMap=angular.fromJson(newUTMSchemaExtentionMapObject);
+                                                    }
+                                                }*/
+                                                
+                                                if (elementKeys[j] === key) {
+                                                    key_isavailable = true;
+                                                }
+                                            }
+                                            if (!key_isavailable) {
+                                                //Implement this later. Commented this as this is wiping out all the Repeatable/Heirarchical values
+                                                //delete $scope.utmSchemaExts[key];
+                                            }
+                                        }
+                                    );
+                                    
+                                    //If an attribute is removed from upgraded schema, remove that attribute related details from PathDetails
+                                    if($scope.pathDetailsArray != null && $scope.pathDetailsArray.length > 0 ) {
+                                        for (var k = 0; k < $scope.pathDetailsArray.length; k++) {
+                                            $scope.pathDetails = $scope.pathDetailsArray[k];
+    
+                                            for (var j = 0; j < $scope.pathDetails.decisionIdentifiers.length; j++) {
+                                                $scope.decisionElementValues = angular.copy($scope.pathDetails.decisionIdentifiers[j].elementValues);
+                                                Object.keys($scope.decisionElementValues).forEach(
+                                                    function(key) {
+                                                        var key_isavailable = false;
+                                                        for (var l = 0; l < elementKeys.length; l++) {
+                                                            
+                                                            /*for (var m = 0; m < checkedElementValueArray.length; m++) {
+                                                                
+                                                                var currentCheckedMappedvalue = checkedElementValueArray[m];
+                                                                if ((key.indexOf(currentCheckedMappedvalue.oldVal) > -1) && (currentCheckedMappedvalue.oldVal != currentCheckedMappedvalue.newVal)){
+                                                                
+                                                                    var oldvalue=currentCheckedMappedvalue.oldVal;
+                                                                    var newvalue=currentCheckedMappedvalue.newVal;
+                                                                    
+                                                                    key= key.replace(oldvalue, newvalue);
+                                                                
+                                                                    //list_model_schema_extensions[current_model].utmSchemaExtentionMap=angular.fromJson(newUTMSchemaExtentionMapObject);
+                                                                }
+                                                            }*/
+                                                            if (elementKeys[l] === key) {
+                                                                key_isavailable = true;
+                                                            }
+                                                        }
+                                                        if (!key_isavailable) {
+                                                            //Implement this later. Commented this as this is wiping out all the Repeatable/Heirarchical values
+                                                            //delete $scope.pathDetails.decisionIdentifiers[j].elementValues[key];
+                                                        }
+                                                    }
+                                                );
+                                            }
+                                        }
+                                    }
+    
+                                    //console.log("List Model Path Details after Upgrade Schema :: " + JSON.stringify(list_model_path_details[current_model]));
+                                    //console.log("UTMSchema Extension after Upgrade Schema :: "    + JSON.stringify($scope.utmSchemaExts));
+                                    
+                                }
+                                $modalInstance.close("closed");
+                            };
+                            
+                            $scope.close = function() {
+
+                                $modalInstance.close("closed");
+                            };
+                            
+                            
+                            function getElementkeys(parentname, schemaelement) {
+                                if (schemaelement.complexType != null) {
+                                    var parentkey = parentname + "_" + schemaelement.complexType.name;
+                                    for (var i = 0; i < schemaelement.elements.length; i++) {
+                                        getElementkeys(parentkey, schemaelement.elements[i]);
+                                    }
+                                }
+                                if (schemaelement.element != null && schemaelement.element.name != null) {
+                                    var elementKey = parentname + '_' + schemaelement.element.name;
+                                    
+                                    if(!$scope.callFromMap){
+                                        elementKeys.push(elementKey);
+                                    }
+                                    else{
+                                        if($scope.oldMapValFlag){
+                                            $scope.oldmappedvaluesArray.push(schemaelement.element.name);
+                                            $scope.oldMappedvaluesKeyArray.push(elementKey);
+                                        }
+                                        else{
+                                            
+                                            $scope.newMappedvaluesArray.push(schemaelement.element.name);
+                                            $scope.newMappedvaluesKeyArray.push(elementKey);
+                                        }
+                                    }
+                                        
+                                    
+                                    
+                                }
+                                if (schemaelement.type != null && schemaelement.type.complexType != null) {
+                                    var parentkey = parentname + '_' + schemaelement.element.name;
+                                    for (var i = 0; i < schemaelement.type.elements.length; i++) {
+                                        getElementkeys(parentkey, schemaelement.type.elements[i]);
+                                    }
+                                }
+                            }
+
+                        }]);
+
diff --git a/src/main/resources/META-INF/resources/designer/scripts/aOnBoot.js b/src/main/resources/META-INF/resources/designer/scripts/aOnBoot.js
new file mode 100644 (file)
index 0000000..6c58570
--- /dev/null
@@ -0,0 +1,334 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+//When element is first created it should have a red box because it hasn't been edited
+function newElementProcessor(id) {
+    if ($('g[data-element-id="' + id + '"]').length > 0) {
+
+        var _idNode = $('g[data-element-id="' + id + '"]')
+        _idNode.children("rect").each(function() {
+            if ($(this).attr('class') === 'djs-outline') {
+                $(this).attr('class', "djs-outline-no-property-saved")
+                $(this).attr('fill', 'red')
+            }
+        });
+
+    }
+}
+
+function saveProperties(form) {
+    elementMap[lastElementSelected] = form;
+    totalJsonProperties = JSON.stringify(elementMap);
+    
+    //Take off the red border because the element has been edited
+    if ($('g[data-element-id="' + lastElementSelected + '"]').length > 0) {
+        var _idNode = $('g[data-element-id="' + lastElementSelected + '"]')
+        _idNode.children("rect").each(function() {
+            if ($(this).attr('class') === 'djs-outline-no-property-saved') {
+                $(this).attr('class', "djs-outline")
+                $(this).attr('fill', 'none')
+            }
+        });
+    }
+}
+
+function saveGlobalProperties(form) {
+    elementMap["global"] = form;
+}
+var isObject = function(a) {
+    return (!!a) && (a.constructor === Object);
+};
+
+function loadPropertyWindow(type) {    
+    if (readOnly) {
+        if ($("#add_one_more").length == 1) {
+            $("#add_one_more").off();
+            $("#add_one_more").click(function(event) {
+                event.preventDefault();
+            })
+        }
+        $("select,input").attr("disabled", "");
+    }
+
+    var props = defaults_props[type];
+    
+    for (p in props) {
+        if (isObject(props[p])) {
+            var mySelect = $('#' + p);
+            $.each(props[p], function(val, text) {
+                mySelect.append(
+                    $('<option></option>').val(val).html(text)
+                );
+            });
+        } else {
+               if (p=="pname"){
+                       var ms = new Date().getTime();
+                       props[p] = "Policy" + ms;
+               }
+            $("#" + p).val(props[p])
+        }
+    }
+    setTimeout(function(){
+
+     setMultiSelect(type); }, 100);
+     
+}
+
+function setMultiSelect() {
+    $("select").each(function(index, mySelect) {
+        if ($(mySelect).parents(".multiselect-native-select") &&
+            $(mySelect).parents(".multiselect-native-select").length < 1) {
+            if (!$(mySelect).attr("multiple")) {
+                if ($(mySelect).attr("enableFilter")) {
+                    $(mySelect).multiselect({
+                        numberDisplayed: 1,
+                        maxHeight: 200
+                    });
+                } else {
+                    $(mySelect).multiselect({
+                        numberDisplayed: 1,
+                        enableFiltering: true,
+                        maxHeight: 200
+                    });
+                }
+                
+            } else {
+                $(mySelect).multiselect({
+                    numberDisplayed: 1,
+                    includeSelectAllOption: true,
+                    enableFiltering: true,
+                    maxHeight: 200,
+                    enableCaseInsensitiveFiltering: true
+                });
+            }
+
+        } else if ($(mySelect).parents(".multiselect-native-select") &&
+            $(mySelect).parents(".multiselect-native-select").length > 0) {
+            var selectDrop = $(mySelect).parent(".multiselect-native-select").find("select");
+            $(mySelect).parent(".multiselect-native-select").parent().html(selectDrop);
+            if (!$(mySelect).attr("multiple")) {
+                if ($(mySelect).attr("enableFilter")) {
+                    $(mySelect).multiselect({
+                        numberDisplayed: 1,
+                        maxHeight: 200
+                    });
+                } else {
+                    $(mySelect).multiselect({
+                        numberDisplayed: 1,
+                        enableFiltering: true,
+                        maxHeight: 200
+                    });
+                }
+            } else {
+                $(mySelect).multiselect({
+                    numberDisplayed: 1,
+                    includeSelectAllOption: true,
+                    enableFiltering: true,
+                    maxHeight: 200,
+                    enableCaseInsensitiveFiltering: true
+                });
+            }
+        }
+    });
+    //refeshMultiSelect();
+}
+function loadSharedPropertyByService(onChangeUUID,refresh, callBack) {
+    var uuid = onChangeUUID
+    if (uuid === undefined){
+        uuid = elementMap["global"] && elementMap["global"].length>0 ? 
+        elementMap["global"][0].value : "";
+    } else if (uuid === "") {
+        vf_Services = null
+        if ($("#vf").length > 0)
+            $("#vf").empty();
+        if ($("#location").length > 0)
+            $("#location").empty();
+        if ($("#alarmCondition").length > 0)
+            $("#alarmCondition").empty();
+        return true;
+    }
+    var share = null,
+    serviceUrl = '/restservices/clds/v1/clds/properties/' + uuid;
+    if(refresh){
+        serviceUrl = '/restservices/clds/v1/clds/properties/' + uuid +'?refresh=true';
+    }
+
+    $.ajax({
+        async: false,
+        dataType: "json",
+        url: serviceUrl,
+        success: function(data) {
+            vf_Services = data;
+            setASDCFields()
+             if(refresh){
+             $("#paramsWarnrefresh").hide();   
+            }
+             if($("#paramsWarn")){
+                $("#paramsWarn").hide();
+            }
+            if(callBack && _.isFunction(callBack)){
+                callBack(true);
+            }
+        },
+        error: function(s, a, err) {
+            if(refresh){
+             $("#paramsWarnrefresh").show();   
+            }
+            if($("#paramsWarn")){
+                $("#paramsWarn").show();    
+            }
+            
+            $('#servName').text($("#service option:selected").text());
+            if(callBack && _.isFunction(callBack)){
+                callBack(false);
+            }
+            console.log(err)
+            console.log(s)
+            console.log(a)
+        },
+        timeout: 100000
+
+    });
+    //vf_Services=share['shared']['byService'][uuid];
+    //location_values = share['global']['location'];
+}
+
+function loadSharedPropertyByServiceProperties(callBack) {
+    $.ajax({
+        async: false,
+        dataType: "json",
+        url: '/restservices/clds/v1/clds/properties/',
+        success: function(data) {
+            vf_Services = data;
+            setASDCFields();
+            if(callBack && _.isFunction(callBack)){
+                callBack(true);
+            }
+        },
+        error: function(s, a, err) {
+            $('#servName').text($("#service option:selected").text());
+            if(callBack && _.isFunction(callBack)){
+                callBack(false);
+            }
+        },
+        timeout: 100000
+
+    });
+}
+
+function setASDCFields() {
+    if (vf_Services === null || vf_Services === undefined) {
+        loadSharedPropertyByService()
+    } else {
+        try {
+            $("#vf").empty();
+            $("#location").empty();
+            $("#vfc").empty();
+            $("#paramsWarn").hide();
+            var uuid = Object.keys(vf_Services['shared']['byService'])[0];
+            var vf_values = vf_Services['shared']['byService'][uuid] &&
+                vf_Services['shared']['byService'][uuid]['vf'] &&
+                               _.keys(vf_Services['shared']['byService'][uuid]['vf']).length > 0  ?
+                vf_Services['shared']['byService'][uuid]['vf'] : null;
+            var selectedVF = {}
+            for (let e in elementMap["global"]) {
+                if (elementMap['global'][e].name === "vf") {
+                    selectedVF = elementMap['global'][e].value[0]
+                }
+            }
+            var location_values = vf_Services['global']['location'];
+            var vfc_values2 = selectedVF &&
+                vf_Services['shared']['byVf'][selectedVF] &&
+                vf_Services['shared']['byVf'][selectedVF]['vfc'] &&
+                 _.keys(vf_Services['shared']['byVf'][selectedVF]['vfc']).length > 0 ?
+                vf_Services['shared']['byVf'][selectedVF]['vfc'] : null;
+
+            if (vf_values) {
+                for (key in vf_values) {
+                    if ($("#vf").length > 0) {
+                        $("#vf").append("<option value=\"" + key + "\">" + vf_values[key] + "</opton>")
+                    }
+                }
+            } 
+            if (location_values) {
+                for (key in location_values) {
+                    if ($("#location").length > 0) {
+                        $("#location").append("<option value=\"" + key + "\">" + location_values[key] + "</opton>")
+                    }
+                }
+            }            
+            if (vfc_values2) {
+               $("#vfc").append("<option value=\"\"></opton>");
+                for (key in vfc_values2) {
+                    if ($("#vfc").length > 0) {
+                        $("#vfc").append("<option value=\"" + key.split("\"").join("") + "\">" + vfc_values2[key] + "</opton>")
+                    }
+                }
+            }
+            if($("#vfc").length > 0 && !vfc_values2){
+                               showWarn();
+            }
+            if($("#vf").length > 0 && !vf_values){
+                       showWarn();     
+            }
+            if($("#location").length > 0 && !location_values){
+               showWarn();
+            }
+
+            function showWarn() {
+                $("#paramsWarn").show();
+                $('#servName').text($("#service option:selected").text());
+            }
+        } catch (e) {
+            console.log(e)
+        }
+    }
+}
+
+//Typically used when opening a new model/template
+function reloadDefaultVariables(isTemp) {
+    isTemplate = isTemp;
+    vf_Services = null;
+    readOnly = false;
+    runningInstances = {}
+}
+
+$(window).load(function() {
+    $.ajax({
+        dataType: "json",
+        url: '/restservices/clds/v1/clds/properties',
+        success: function(data) {
+            console.log("success");
+            defaults_props = data;
+        },
+        error: function(s, a, err) {
+            console.log(err)
+            console.log(s)
+            console.log(a)
+        },
+        timeout: 100000
+    });
+
+
+
+})
diff --git a/src/main/resources/META-INF/resources/designer/scripts/app.js b/src/main/resources/META-INF/resources/designer/scripts/app.js
new file mode 100644 (file)
index 0000000..3d8e30e
--- /dev/null
@@ -0,0 +1,1426 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+/* App Module */
+
+var app = angular.module('clds-app', ['ngRoute', 
+                                          'ngResource',
+                                          'angularjs-dropdown-multiselect',
+                                          'angularjs-dropdown-multiselect-new',
+                                          'hljs',
+                                          'ui.bootstrap',
+                                          'angular-loading-bar', 
+                                          'ngAnimate',
+                                          'dialogs.main',
+                                          'ui.grid', 
+                                          'ui.grid.resizeColumns',
+                                          'ui.grid.paging',
+                                          'ui.grid.selection',
+                                          'ui.grid.cellNav',
+                                          'ui.grid.pinning',
+                                          'ngSanitize',
+                                          'ngCookies',
+                                          'ui.bootstrap.modal',
+                                          'ui.grid.exporter',
+                                          'angucomplete',
+                                          'kendo.directives'
+                                          ])
+.config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) 
+{
+       console.log("///////////////cfpLoadingBarProvider");
+    cfpLoadingBarProvider.includeBar = true;
+    cfpLoadingBarProvider.includeSpinner = true;
+  }])
+.config(function ($httpProvider) {
+       console.log("config");
+         $httpProvider.responseInterceptors.push('myHttpInterceptor');
+
+         var spinnerFunction = function spinnerFunction(data, headersGetter) 
+         {
+               console.log("spinnerFunction");
+               return data;
+         };
+
+         $httpProvider.defaults.transformRequest.push(spinnerFunction);
+})
+.config(['$routeProvider','$locationProvider', '$compileProvider','cfpLoadingBarProvider',function(
+                               $routeProvider, 
+                               $locationProvider,
+                               cfpLoadingBarProvider,
+                               $timeout,
+                               dialogs,
+                               $cookies) 
+{
+       console.log("$routeProvider','$locationProvider', '$compileProvider','cfpLoadingBarProvider'")
+  $locationProvider.html5Mode(false);
+  //alert("App.js");
+     
+       $routeProvider.
+       when('/otherwise', {templateUrl: 'partials/please_wait.html', controller: QueryParamsHandlerCtrl }).
+       //when('/dashboard_submit', { templateUrl: 'partials/portfolios/dashboard_submit.html', controller: CreateNewPrjCtrl }).
+       when('/dashboard', { templateUrl: 'partials/portfolios/clds_modelling.html', controller: DashboardCtrl }).
+       //when('/dashboard_upload', { templateUrl: 'partials/portfolios/dashboard_upload.html', controller: DashboardCtrl }).
+       when('/activity_modelling', { templateUrl: 'partials/portfolios/clds_modelling.html', controller: DashboardCtrl }).
+       when('/authenticate', { templateUrl: 'authenticate.html', controller: AuthenticateCtrl }).
+       when('/invalidlogin', { templateUrl: 'partials/invalid_login.html', controller: PageUnderConstructionCtrl }).
+       otherwise({redirectTo: '/otherwise'});
+  
+}]).controller('dialogCtrl',function($scope,$rootScope,$timeout,dialogs){
+       
+       //-- Variables --//
+       console.log("dialogCtrl");
+       $scope.lang = 'en-US';
+       $scope.language = 'English';
+
+       var _progress = 100;
+       
+       $scope.name = '';
+       $scope.confirmed = 'No confirmation yet!';
+       
+       $scope.custom = {
+               val: 'Initial Value'
+       };
+       
+       //-- Listeners & Watchers --//
+
+       $scope.$watch('lang',function(val,old){
+               console.log("lang");
+               switch(val){
+                       case 'en-US':
+                               $scope.language = 'English';
+                               break;
+                       case 'es':
+                               $scope.language = 'Spanish';
+                               break;
+               }
+       });
+
+       //-- Methods --//
+$rootScope.testCaseRequirements=[];
+$rootScope.validTestRequirements=[];
+/*$rootScope.testCaseValue=[];*/
+       $scope.setLanguage = function(lang)
+       {
+               console.log("setLanguage");
+
+               $scope.lang = lang;
+               $translate.use(lang);
+       };
+
+       $rootScope.launch = function(which){
+               console.log("launch");
+               switch(which){
+                       case 'error':
+                               dialogs.error();
+                               break;
+                       case 'wait':
+                               //var dlg = dialogs.wait(undefined,undefined,_progress);
+                               //_fakeWaitProgress();
+                               break;
+                       case 'customwait':
+                               //var dlg = dialogs.wait('Custom Wait Header','Custom Wait Message',_progress);
+                               //_fakeWaitProgress();
+                               break;
+                       case 'notify':
+                               dialogs.notify();
+                               break;
+                       case 'confirm':
+                               var dlg = dialogs.confirm();
+                               dlg.result.then(function(btn){
+                                       console.log("dlg.result");
+                                       $scope.confirmed = 'You confirmed "Yes."';
+                               },function(btn){
+                                       console.log("btn");
+                                       $scope.confirmed = 'You confirmed "No."';
+                               });
+                               break;
+                       case 'custom':
+                               var dlg = dialogs.create('/dialogs/custom.html','customDialogCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                               dlg.result.then(function(name){
+                                       console.log("dlg.result");
+                                       $scope.name = name;
+                               },function(){
+                                       console.log("custom");
+                                       if(angular.equals($scope.name,''))
+                                               $scope.name = 'You did not enter in your name!';
+                               });
+                               break;
+                       case 'custom2':
+                               var dlg = dialogs.create('/dialogs/custom2.html','customDialogCtrl2',$scope.custom,{size:'lg'});
+                               break;
+                       case 'custom3':
+                               var dlg = dialogs.notify('Message','All is not supported, Please select interface(s)/version(s) to fetch real time federated coverage report.');
+                               break;
+                       case 'custom4':
+                               var dlg = dialogs.confirm('Message','You are about to fetch real time federated coverage report.This may take sometime!!!.');
+                               dlg.result.then(function(btn){
+                                       console.log("dlg.result");
+                                       $scope.confirmed = 'You confirmed "Yes."';
+                               },function(btn){
+                                       console.log("btn");
+                                       $scope.confirmed = 'You confirmed "No."';
+                               });
+                               break;
+                       case 'custom5':
+                               var dlg = dialogs.notify('Success','Request has been successfully processed.');
+                               break;
+                       case 'custom6':
+                               var dlg = dialogs.notify('Message','Please type Testscenario Name');
+                               break;
+               }
+       }; // end launch
+       
+       var _fakeWaitProgress = function()
+       {
+               console.log("_fakeWaitProgress");
+               $timeout(function()
+               {
+                       console.log("timeout");
+                       if(_progress < 100)
+                       {
+                               _progress += 33;
+                               $rootScope.$broadcast('dialogs.wait.progress',{'progress' : _progress});
+                               _fakeWaitProgress();
+                       }
+                       else
+                       {
+                               $rootScope.$broadcast('dialogs.wait.complete');
+                               _progress = 0;
+                       }
+               },1000);
+       };
+}).controller('MenuCtrl',['$scope', '$rootScope','$timeout','dialogs','$location','MenuService','Datafactory',
+'userPreferencesService','cldsModelService','cldsTemplateService',function($scope,$rootScope,$timeout,dialogs,
+       $location, MenuService,Datafactory,userPreferencesService,cldsModelService,cldsTemplateService)
+{      
+       console.log("MenuCtrl");
+       $rootScope.screenName="Universal Test Modeler";
+       $rootScope.testSet = null;
+       $rootScope.isNew= false;
+       var testingType="";
+       $rootScope.contactUs= function()
+       {
+               console.log("contactUs");
+               var link = "mailto:onap-discuss@lists.onap.org?subject=CLAMP&body=Please send us suggestions or feature enhancements or defect. If possible, please send us the steps to replicate any defect.";
+               window.location.href = link;
+       };
+       
+$scope.emptyMenuClick = function(value, name) {
+    if ($rootScope.isNew && (name != "Save Template" && name != "Close Template" &&
+            name != "Template Properties")) {
+        saveConfirmationNotificationPopUp();
+    } else if ($rootScope.isNewClosed && name != "Save CL" && name != "Close Model" &&
+        name != "Properties CL") {
+        saveConfirmationNotificationPopUp();
+    } else {
+        isSaveCheck(name);
+    }
+
+    function saveConfirmationNotificationPopUp() {
+        $scope.saveConfirmationNotificationPopUp(function(data) {
+            console.log("saveConfirmationNotificationPopUp");
+            if (data) {
+                if ($rootScope.isNewClosed) {
+                    isSaveCheck("Save CL");
+                } else {
+                    isSaveCheck("Save Template");
+                }
+                $rootScope.isNewClosed = false;
+                $rootScope.isNew = false;
+            } else {
+                return false;
+            }
+        });
+    }
+
+    function isSaveCheck(name) {
+        console.log("isSaveCheck");
+        if (name == "Wiki") {
+            window.open(value);
+        } else if (name == "Contact Us") {
+            $rootScope.contactUs();
+        } else if (name == "Revert Template Changes") {
+            $scope.cldsRevertTemplate();
+        } else if (name == "Revert Model Changes") {
+            $scope.cldsRevertModel();
+        } else if (name == "Create Template") {
+            $rootScope.isNew = true;
+            $scope.cldsCreateTemplate();
+        } else if (name == "Open Template") {
+            $scope.cldsOpenTemplate();
+        } else if (name == "Save Template") {
+            $scope.cldsTemplatePerformAction("SAVE");
+            $rootScope.isNewClosed = false;
+            $rootScope.isNew = false;
+        } else if (name == "Template Properties") {
+            $scope.cldsOpenTemplateProperties();
+        } else if (name == "Close Model" || name == "Close Template") {
+            $scope.cldsClose();
+        } else if (name == "Refresh ASDC") {
+            $scope.cldsRefreshASDC();
+        } else if (name == "Create CL") {
+            $rootScope.isNewClosed = true;
+            $scope.cldsCreateModel();
+        } else if (name == "Open CL") {
+            $scope.cldsOpenModel();
+        } else if (name == "Save CL") {
+            $rootScope.isNewClosed = false;
+            $rootScope.isNew = false;
+            $scope.cldsPerformAction("SAVE");
+        } else if (name == "Test") {
+            $scope.cldsPerformAction("TEST");
+        } else if (name == "Submit") {
+            $scope.cldsConfirmPerformAction("SUBMIT");
+        } else if (name == "Resubmit") {
+            $scope.cldsConfirmPerformAction("RESUBMIT");
+        } else if (name == "Update") {
+            $scope.cldsConfirmPerformAction("UPDATE");
+        } else if (name == "Delete") {
+            $scope.cldsConfirmPerformAction("DELETE");
+        } else if (name == "Stop") {
+            $scope.cldsConfirmPerformAction("STOP");
+        } else if (name == "Restart") {
+            $scope.cldsConfirmPerformAction("RESTART");
+        } else if (name == "Refresh Status") {
+            $scope.cldsPerformAction("REFRESH");
+        } else if (name == "Properties CL") {
+            $scope.cldsOpenModelProperties();
+        } else if (name === "Running Instances") {
+            $scope.cldsShowRunningInstances();
+        } else {
+            $rootScope.screenName = name;
+            $scope.updatebreadcrumb(value);
+            $location.path(value);
+        }
+    }
+};
+
+       
+       
+       
+       $rootScope.impAlerts= function()
+       {
+               console.log("impAlerts");
+       };
+       
+       $scope.tabs = {         
+                                       "Template": [
+                                            {
+                                                link: "/cldsCreateTemplate",
+                                            name: "Create Template"
+                                            }, {
+                                                    link: "/cldsOpenTemplate",
+                                                    name: "Open Template"
+                                    }, {
+                                       link: "/cldsSaveTemplate",
+                                       name: "Save Template"                      
+                                            },
+                                            {
+                                                link: "/cldsOpenTemplateProperties",
+                                            name: "Template Properties"
+                                            },
+                                            {
+                                                link: "/RevertChanges",
+                                            name: "Revert Template Changes"
+                                            },
+                                            {
+                                                link: "/Close",
+                                            name: "Close Template"
+                                            }
+                                        ],
+                                   
+                                "Closed Loop": [
+                                            {
+                                                link: "/cldsCreateModel",
+                                            name: "Create CL"
+                                            }, {
+                                                    link: "/cldsOpenModel",
+                                                    name: "Open CL"
+                                    }, {
+                                       link: "/cldsSaveModel",
+                                       name: "Save CL"                    
+                                            },
+                                            {
+                                                link: "/cldsOpenModelProperties",
+                                            name: "Properties CL"
+                                            },
+                                            {
+                                                link: "/RevertChanges",
+                                            name: "Revert Model Changes"
+                                            },
+                                            {
+                                                link: "/Close",
+                                            name: "Close Model"
+                                            }
+                                        ],    
+                                "Manage": [
+                                                {
+                                                    link: "/cldsTestActivate",
+                                                    name: "Test"
+                                   },
+                                   {
+                                       link: "/cldsSubmit",
+                                       name: "Submit"                     
+                                            },
+                                    {
+                                       link: "/cldsResubmit",
+                                       name: "Resubmit"                           
+                                            },
+                                    {
+                                       link: "/cldsUpdate",
+                                       name: "Update"                     
+                                            },
+                                    {
+                                       link: "/cldsStop",
+                                       name: "Stop"                       
+                                            },
+                                    {
+                                       link: "/cldsRestart",
+                                       name: "Restart"                    
+                                            },
+                                    {
+                                       link: "/cldsDelete",
+                                       name: "Delete"                     
+                                            }
+                                        ],   
+                                        "View": [
+                                               {
+                                                    link: "/refreshStatus",
+                                                    name: "Refresh Status"
+                                   },
+                                   {
+                                       link:"/refreshASDCProperties",
+                                       name:"Refresh ASDC"
+                                   },
+                                   {
+                                       link:"/viewRunningInstances",
+                                       name:"Running Instances"
+                                   }
+                                                        ],   
+                                "Help": [
+                                   {
+                                       link: "http://wiki.onap.org",
+                                       name: "Wiki"
+                                   }, {
+                                       link: "/contact_us",
+                                       name: "Contact Us"                         
+                                   }
+                                   
+                                   
+                                ]
+        };
+
+       
+        if (!Object.keys) 
+        {
+            Object.keys = function(obj) 
+            {
+               console.log("keys");
+               console.log("keys");
+                var keys = [];
+
+                for (var i in obj) {
+                    if (obj.hasOwnProperty(i)) {
+                        keys.push(i);
+                    }
+                }
+
+                return keys;
+            };
+            $scope.keyList = Object.keys($scope.tabs);
+        } else
+        {
+            $scope.keyList = Object.keys($scope.tabs);
+        }
+        
+        $scope.updatebreadcrumb = function(path)
+        {     
+               console.log("updatebreadcrumb");
+               var currentURL = $location.path();              
+               if(path!=undefined)
+               {
+                currentURL = path;
+               }                       
+               
+               if(currentURL=="/dashboard")
+            {
+               $rootScope.screenName = "Universal Test Modeler";
+               $rootScope.parentMenu = "Home";
+               $rootScope.rightTabName="UTM Build Configuration";
+            }
+               /*else if(currentURL=="/quicksearch")
+            {
+               $rootScope.screenName = "Quick Search";
+               $rootScope.parentMenu = "Home";
+            }*/
+            else
+            {
+               var found = false;
+               
+               angular.forEach($scope.keyList, function(value, key) 
+               {
+                       console.log("foreachfunction");
+                       if(!found)
+                       {
+                               $rootScope.parentMenu = value;
+                               
+                           angular.forEach($scope.tabs[value], function(value, key) 
+                               {
+                                       console.log("tebvalue");
+                               if(currentURL==value.link)
+                               {
+                                       $rootScope.screenName=value.name;
+                                       found=true;
+                               }                         
+                               });
+                       }
+               });
+            }
+        };
+        
+        $scope.updatebreadcrumb();
+        
+        $scope.createNewProject = function(){  
+            console.log("createNewProject");
+               if($rootScope.projectName != null){
+                       var dlg = dialogs.confirm('Message','Do you want to over-write  the project ?');
+               
+                               dlg.result.then(function(btn){
+                                       console.log("dlg.result");
+                                       $scope.clearProject();
+                                       var dlg1 = dialogs.create('partials/portfolios/create_new_project.html','CreateNewPrjCtrl',{},{size:'sm',keyboard: true,backdrop: false,windowClass: 'my-class'});
+                               dlg1.result.then(function(name){
+                                       console.log("dlg.result");
+                                       //$scope.name = name;
+                               },function(){
+                                       console.log("emptyfunction");
+                                       //if(angular.equals($scope.name,''))
+                                               //$scope.name = 'You did not enter in your name!';
+                               });     
+                               },function(btn){
+                                       console.log("btn");
+                                       //$modalInstance.close("closed");
+                               });
+                       
+               }else{
+                       var dlg = dialogs.create('partials/portfolios/create_new_project.html','CreateNewPrjCtrl',{},{size:'lg',keyboard: true,backdrop: false,windowClass: 'my-class'});
+                       dlg.result.then(function(name){
+                               console.log("dlg.result");
+                               //$scope.name = name;
+                       },function(){
+                               console.log("emptyfunction");
+                               //if(angular.equals($scope.name,''))
+                                       //$scope.name = 'You did not enter in your name!';
+                       });     
+                       
+               }
+        };
+        
+        $scope.clearProject= function(){ 
+            console.log("clearProject");
+               $rootScope.projectName= null;
+               $rootScope.revision = -1;
+               //$rootScope.models.length=0;
+               $rootScope.utmModels=$rootScope.$new(true);
+               $rootScope.serviceInfo = $rootScope.$new(true);
+               $rootScope.serviceInfo= null;
+               $rootScope.serviceInputPartInfo = $rootScope.$new(true);
+               $rootScope.serviceOutputPartInfo=$rootScope.$new(true);
+               $rootScope.servicefaultPartInfo =$rootScope.$new(true);
+               $rootScope.isModel = false;
+               $("#paletteDiv").load('./modeler/dist/index.html');  
+               $rootScope.isPalette = false;      
+               $rootScope.isTestset = false;
+               $rootScope.isRequirementCoverage = false;
+               $rootScope.ispropertyExplorer = false;
+         //    $("#propertyDiv").load('./partials/portfolios/Property_Explorer.html');
+               $rootScope.modelName="";
+               //document.getElementById('propertyExplorer').classList.remove('visible');
+               document.getElementById("modeler_name").textContent="Activity Modeler";
+               //$( "#propertyExplorer" ).prev().css( "display", "block" );
+               $( "#activity_modeler" ).prev().css( "display", "block" );
+               $( 'div' ).find('.k-expand-next').click();
+        
+               $rootScope.$apply();
+                       
+        };
+        
+        $scope.homePage=function(){
+               console.log("homePage");
+               $location.path('/dashboard');
+        };
+       $scope.propertyExplorerErrorMessage = function(msg)
+       {
+                   console.log("propertyExplorerErrorMessage");
+          var dlg = dialogs.notify('Error',msg);
+       }
+       
+       //$scope.fromTstMultipleFlag=false;
+        /*onclicking of review testset / generate testset */
+        $scope.generateTestSet=function(testingType){
+               console.log("generateTestSet");
+               var errorMessage="";
+               var generateTestSetMDTURL = "/utm-service/test_generation/generateMDTTestSet";
+               
+                       var UTMProjectExplorer = {};
+                       UTMProjectExplorer.projectName = $rootScope.projectName;
+                       UTMProjectExplorer.utmModels = $rootScope.utmModels;
+                       
+                       UTMProjectExplorer.utmDepthValueMap = $rootScope.depthElementKeyMap;
+                       UTMProjectExplorer.utmCountValueMap = $rootScope.countElementKeyMap;
+
+               var utmMDTRequest = {};
+               utmMDTRequest.mainProcessName = selected_model;
+                       var utm_models = [];
+                       $rootScope.populateUTMModelArray(utm_models,$rootScope.utmModels);                      
+                       utmMDTRequest.utmModels = utm_models;
+                       
+                       utmMDTRequest.testingType=testingType;
+               
+                       utmMDTRequest.utmProjectExplorer = UTMProjectExplorer;
+                       if ($rootScope.wsdlInfo != null) {
+                               utmMDTRequest.schemaLocation = $rootScope.wsdlInfo.schemaLocation;                                      
+                       }
+                       
+                       utmMDTRequest.dbToolRequests = Datafactory.getDbToolProjectLevelList();
+                       utmMDTRequest.runtimePythonScriptProjectLevelList = Datafactory.getRuntimePythonScriptProjectLevelList();
+                       utmMDTRequest.xmlValidatorList = Datafactory.getXmlValidatorList();
+                       utmMDTRequest.modelPreferenceInfo = Datafactory.getModelPreferenceInfo();
+               MenuService.generateMDTTestSet(utmMDTRequest, generateTestSetMDTURL)
+               .then(function(pars) {
+                       list_model_test_sets[selected_model] = pars;
+                       
+                       //populate test sets of other models
+                       for(var i = 0; i < utm_models.length; i++){
+                               var model_test_set = {};
+                               model_test_set.activityTestCases = [];
+                               model_test_set.invalidModelException = pars.invalidModelException;
+                               model_test_set.serviceName = pars.serviceName;
+                               for(var y = 0; y < pars.activityTestCases.length; y++){
+                                       for(var z = 0; z < pars.activityTestCases[y].modelElements.length; z++){
+                                               if(pars.activityTestCases[y].modelElements[z].modelName == utm_models[i].modelName){
+                                                       model_test_set.activityTestCases.push(pars.activityTestCases[y]);
+                                                       break;
+                                               }
+                                       }
+                               }
+                               list_model_test_sets[utm_models[i].modelName] = model_test_set;
+                       }
+                       
+                       list_model_test_sets[selected_model] = pars;
+
+                       if(pars.invalidModelException.invalidModelElementExceptions.length>0){
+                               for(var i=0;i<pars.invalidModelException.invalidModelElementExceptions.length;i++){
+                                       errorMessage = errorMessage +"\n"+"["+(i+1)+"]." + " "+pars.invalidModelException.invalidModelElementExceptions[i].message+"\n";
+                                       console.log("error Message:"+errorMessage);
+                               }
+                               
+                               var dlg = dialogs.notify('Failure',errorMessage);
+                               
+                       }else{
+                               
+                               $rootScope.modeltestset = pars; 
+                               
+                               if(!$scope.fromTstMultipleFlag){
+                               $rootScope.isPalette = false;
+                               $rootScope.isTestset = true;
+                               $rootScope.isRequirementCoverage = false;
+                               document.getElementById("modeler_name").textContent="UTM Test Set";
+                               //document.getElementById('propertyExplorer').classList.add('visible');
+                               $('div').find('.k-collapse-next').click();
+                               //$( "#propertyExplorer" ).prev().css( "display", "none" );
+                               //$rootScope.$apply();
+                               document.getElementById("Review/Validate Test Set").classList.remove('ThisLink');
+                       
+                               document.getElementById("Export to Excel").classList.remove('ThisLink');
+                               /*document.getElementById("Export Test Set").classList.remove('ThisLink');*/
+                               document.getElementById("Test Case / Requirement Coverage").classList.remove('ThisLink');
+                               //$rootScope.$apply();
+                       }
+               }
+                       
+               },
+               function(data) {
+                       console.log("data");
+
+               });
+               
+                       
+        };
+        $scope.reviewTestSet=function(){
+
+                       console.log("reviewTestSet");
+                               $rootScope.modeltestset = list_model_test_sets[selected_model];
+                               
+                               $rootScope.isPalette = false;
+                               $rootScope.isTestset = true;
+                               $rootScope.isRequirementCoverage = false;
+                               document.getElementById("modeler_name").textContent="UTM Test Set";
+                               //document.getElementById('propertyExplorer').classList.add('visible');
+                               
+                               //$( "#propertyExplorer" ).prev().css( "display", "none" );
+                               $('div').find('.k-collapse-next').click();
+                               console.log($rootScope.modeltestset);
+                               //$rootScope.$apply();
+               
+               
+                       
+        };
+        $scope.requirementCoverage=function(){
+               console.log("requirementCoverage");
+               $rootScope.testCaseRequirements=[];
+               $rootScope.validTestRequirementArray=[];
+               $rootScope.validTestRequirements={};        
+               $rootScope.modeltestset = list_model_test_sets[selected_model];         
+               var allPathDetails=[]; 
+               $scope.currentSelectedModel = {};
+               $scope.getPathDetails($rootScope.utmModels,selected_model);
+               $scope.populatePathDetails(allPathDetails,$scope.currentSelectedModel);
+               $rootScope.pathDetailsList = list_model_path_details[selected_model];
+               /*for(var p=0;p<100;p++){
+                               $rootScope.testCaseRequirements.push("Requirement"+p);  
+                       }
+               for(var p=0;p<100;p++){
+                       $rootScope.testCaseValue.push("TestCase"+p);                            
+               }*/
+               for(var x=0;x<allPathDetails.length;x++){                       
+                       var tempPathDetails = allPathDetails[x];   
+                       if(tempPathDetails != null){
+                               for (var i = 0; i < tempPathDetails.length; i++) {
+                                       var pathDetails = tempPathDetails[i];                           
+                                       if(pathDetails.requirement !=='' && pathDetails.requirement !== null ){                                 
+                                               $rootScope.testCaseRequirements.push(pathDetails.requirement);
+                                       }
+               
+                                       /*for (var j = 0; j < pathDetails.decisionIdentifiers.length; j++) {
+                                         if(pathDetails.decisionIdentifiers[j].requirement !== '' && pathDetails.decisionIdentifiers[j].requirement !== null){                                         
+                                               $rootScope.testCaseRequirements.push(pathDetails.decisionIdentifiers[j].requirement);
+                                         }
+                                       }*/
+                   }
+                       }
+                       
+        }
+               /*console.log("path details "+JSON.stringify($rootScope.pathDetailsList));
+               console.log("modeltestset "+$rootScope.modeltestset);*/
+               for(var p=0;p<$rootScope.modeltestset.activityTestCases.length;p++)
+                       {
+                                                               var activityTestCases = $rootScope.modeltestset.activityTestCases[p];
+                                                               if (activityTestCases.mappedRequirements !=null) {
+                                                               for (var i = 0; i < activityTestCases.mappedRequirements.length; i++) {
+                                                                       //$rootScope.testCaseRequirements
+                                                                       //.push(activityTestCases.mappedRequirements[i]);
+                                                                       var testCaseNames = $rootScope.validTestRequirements[activityTestCases.mappedRequirements[i]];
+                                                                       if(testCaseNames == null){
+                                                                               testCaseNames = [];
+                                                                       }
+                                                                       if(activityTestCases.version !=null)
+                                                                               var testCase= activityTestCases.testCaseName + "_" +activityTestCases.version;
+                                                                       else
+                                                                               var testCase= activityTestCases.testCaseName;
+                                                                       testCaseNames.push(testCase);
+                                                                       $rootScope.validTestRequirements[activityTestCases.mappedRequirements[i]]=testCaseNames;
+                                                               }
+                                                       }
+                       }
+               
+               
+               
+               
+               
+               
+                               $rootScope.isPalette = false;
+                               $rootScope.isTestset = false;
+                               $rootScope.isRequirementCoverage = true;
+                               document.getElementById("modeler_name").textContent="Test Case / Requirement Coverage";
+                               //document.getElementById('propertyExplorer').classList.add('visible');
+                               console.log("modeltestset"+JSON.stringify($rootScope.modeltestset));
+                               //$( "#propertyExplorer" ).prev().css( "display", "none" );
+                               $('div').find('.k-collapse-next').click();
+                               //$rootScope.$apply();
+               
+               
+                       
+        };
+        
+        
+        
+        
+        $scope.activityModelling = function(){
+               console.log(".activityModelling");
+               //window.open("./bpmn-js-examples-master/modeler/dist/index.html", "_self");
+       // $location.path('/activity_modelling');
+        };
+        /*$scope.openProject = function(){
+               $location.path('/dashboard_upload');
+        };*/
+        $rootScope.cldsOpenTemplateProperties=function(){
+               console.log("cldsOpenTemplateProperties");
+               var dlg = dialogs.create('partials/portfolios/global_template_properties.html','CldsOpenTemplateCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.modelName =modelName;
+                       //$("#" + selected_model).addClass("selectedcolor");
+                               //alert ("model name:"+$scope.modelName);
+                       },function(){
+                               console.log("....emptyfunction");
+                               //if(angular.equals($scope.name,''))
+                                       //$scope.name = 'You did not enter in your name!';
+                       });     
+        }
+        
+        $scope.cldsShowRunningInstances=function(){
+               console.log("cldsShowRunningInstances");
+               var localInstances;
+               var modelName = selected_model;
+               var dlg;
+               cldsModelService.getRunningInstances(modelName).then(function(pars) {
+                       console.log("getRunningInstances");
+                               localInstances = pars;
+                               angular.forEach(localInstances.cldsModelInstanceList , function(element){
+                                       console.log("cldsModelInstanceList");
+                                       element.status = "Stopped";
+                                       if ( localInstances.status == "ACTIVE" ) {
+                                               element.status = "Running";
+                                       }
+                                       element.view = "";
+                               });
+                               runningInstances = localInstances.cldsModelInstanceList;
+                               dlg = dialogs.create('partials/portfolios/running_instances.html','CldsOpenModelCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                               dlg.result.then(function(name){
+                                       console.log("dlg.ressult");
+                       //$scope.name = name;
+                       },function(){
+                               console.log("...emptyfunction");
+                               //if(angular.equals($scope.name,''))
+                                       //$scope.name = 'You did not enter in your name!';
+                       });                                     
+                       },
+                       function(data) {
+                               console.log("data");
+                               //alert("setModel failed:  " + data);
+                       });             
+                       
+               
+        };
+        
+        $scope.cldsClose = function(){
+               console.log("cldsClose");
+               var dlg = dialogs.create('partials/portfolios/confirmation_window.html','CldsOpenTemplateCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                       
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+        };
+        $scope.cldsOpenTemplate = function(){
+               console.log("cldsOpenTemplate");
+               var dlg = dialogs.create('partials/portfolios/clds_open_template.html','CldsOpenTemplateCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                       
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+        };
+        $scope.saveConfirmationNotificationPopUp = function(callBack) {
+               console.log("saveConfirmationNotificationPopUp");
+                   var dlg = dialogs.create('partials/portfolios/save_confirmation.html', 'saveConfirmationModalPopUpCtrl', { closable: true, draggable: true }, { size: 'lg', keyboard: true, backdrop: 'static', windowClass: 'my-class' });
+
+                   dlg.result.then(function(name) {
+                       console.log("OK");
+                       console.log("MINA TEST OK BUTTON: " + callBack);
+                       callBack("OK");
+                   }, function() {
+                       console.log("CANCEL");
+                       callBack(null);
+                   });
+
+               };
+        $scope.cldsCreateTemplate=function(){
+               console.log("cldsCreateTemplate");
+               var dlg = dialogs.create('partials/portfolios/clds_create_template.html','CldsOpenTemplateCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+  
+        };
+        $scope.cldsRefreshASDC=function(){
+               console.log("cldsRefreshASDC");
+               var dlg = dialogs.create('partials/portfolios/refresh_asdc.html','CldsOpenModelCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emtptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+        }
+        $scope.cldsRevertModel=function(){
+               console.log("cldsRevertModel");
+               var dlg = dialogs.create('partials/portfolios/ConfirmRevertChanges.html','CldsOpenModelCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+  
+        };
+        
+        $scope.cldsRevertTemplate=function(){
+               console.log("cldsRevertTemplate");
+               var dlg = dialogs.create('partials/portfolios/ConfirmRevertChanges.html','CldsOpenTemplateCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("..emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+  
+        };
+        $scope.cldsTemplatePerformAction = function(uiAction){
+               console.log("cldsTemplatePerformAction");
+                       var modelName = selected_model;
+                       var controlNamePrefix = "ClosedLoop-";
+                       var bpmnText = modelXML;
+                       // serialize model properties
+                       var propText =  JSON.stringify(elementMap);     
+
+                       console.log("Generateing svg image");
+                       var svgXml = "";
+                       console.log(abootDiagram.saveSVG({format:true},function(err,xml){
+
+                               if(err)
+                               console.log("error")
+                               else
+                               console.log(xml)
+                               svgXml = xml;
+                               }));
+                       console.log("cldsTemplatePerformAction: " + uiAction + " modelName=" + modelName);      
+                       console.log("cldsTemplatePerformAction: " + uiAction + " controlNamePrefix=" + controlNamePrefix);      
+                       console.log("cldsTemplatePerformAction: " + uiAction + " bpmnText=" + bpmnText);      
+                       console.log("cldsTemplatePerformAction: " + uiAction + " propText=" + propText);      
+                       cldsTemplateService.processAction( uiAction, modelName, controlNamePrefix, bpmnText, propText,svgXml).then(function(pars) {
+                               console.log("processAction");
+                               console.log("cldsTemplatePerformAction: pars=" + pars);
+                               cldsTemplateService.processActionResponse(modelName, pars);
+                       },
+                       function(data) {
+                               console.log(".....emptyfunction");
+                               //alert("setModel failed:  " + data);
+                       });
+        };  
+        
+        
+        
+        $rootScope.cldsOpenModelProperties=function(){
+               console.log("cldsOpenModelProperties");
+               var dlg = dialogs.create('partials/portfolios/global_properties.html','GlobalPropertiesCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.modelName =modelName;
+                       //$("#" + selected_model).addClass("selectedcolor");
+                               //alert ("model name:"+$scope.modelName);
+                       },function(){
+                               console.log("...emptyfunction");
+                               //if(angular.equals($scope.name,''))
+                                       //$scope.name = 'You did not enter in your name!';
+                       });     
+        }
+        $scope.cldsOpenModel = function(){
+               console.log("cldsOpenModel");
+               var dlg = dialogs.create('partials/portfolios/clds_open_model.html','CldsOpenModelCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                       
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+        };
+        $scope.cldsCreateModel=function(){
+               console.log("cldsCreateModel");
+               var dlg = dialogs.create('partials/portfolios/clds_create_model_off_Template.html','CldsOpenModelCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               
+               dlg.result.then(function(name){
+                       console.log("dlg.result");
+                       //$scope.name = name;
+               },function(){
+                       console.log("...emptyfunction");
+                       //if(angular.equals($scope.name,''))
+                               //$scope.name = 'You did not enter in your name!';
+               });     
+  
+        };
+        $scope.cldsPerformAction = function(uiAction){
+               console.log("cldsPerformAction");
+                       var modelName = selected_model;
+                       var controlNamePrefix = "ClosedLoop-";
+                       var bpmnText = modelXML;
+                       // serialize model properties
+                       var propText =  JSON.stringify(elementMap);     
+                       var templateName=selected_template
+                       console.log("Generateing svg image");
+                       var svgXml = "";
+                       console.log(abootDiagram.saveSVG({format:true},function(err,xml){
+                               if(err)
+                               console.log("error")
+                               else
+                               console.log(xml)
+                               svgXml = xml;
+                               }));
+                       console.log("cldsPerformAction: " + uiAction + " modelName=" + modelName);      
+                       console.log("cldsPerformAction: " + uiAction + " controlNamePrefix=" + controlNamePrefix);      
+                       console.log("cldsPerformAction: " + uiAction + " bpmnText=" + bpmnText);      
+                       console.log("cldsPerformAction: " + uiAction + " propText=" + propText);      
+                       cldsModelService.processAction( uiAction, modelName, controlNamePrefix, bpmnText, propText,svgXml,templateName).then(function(pars) {
+                               console.log("cldsPerformAction: pars=" + pars);
+                               cldsModelService.processRefresh(pars);
+                       },
+                       function(data) {
+                               console.log("data");
+                               //alert("setModel failed:  " + data);
+                       });
+        };   
+        
+       $scope.cldsConfirmPerformAction = function(uiAction){
+
+       console.log("cldsConfirmPerformAction");
+               var dlg = dialogs.confirm('Message', 'Do you want to ' + uiAction.toLowerCase() + ' the closed loop?');
+               dlg.result.then(function (btn) {
+                       console.log("dlg.result");
+                       $scope.cldsPerformAction(uiAction);
+               }, function (btn) {
+                       console.log("btn");
+                //$modalInstance.close("closed");
+            });
+        }; 
+      
+        $scope.CollectorsWindow = function (collectorsWin) {
+               console.log("CollectorsWindow");
+
+            if (isTemplate){
+               var dlg = dialogs.create('partials/portfolios/Template_model.html','ImportSchemaCtrl',collectorsWin,{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                dlg.result.then(function(name){
+                       console.log("dlg.result");
+
+                },function(){
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+            }
+            else{
+                var dlg = dialogs.create('partials/portfolios/Collector_properties.html','ImportSchemaCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                dlg.result.then(function(name){
+                       console.log("dlg.result");
+
+                },function(){
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+
+            }
+
+        };
+        $scope.StringMatchWindow = function (stringMatch) {
+               console.log("StringMatchWindow");
+               if (isTemplate){
+               var dlg = dialogs.create('partials/portfolios/Template_model.html','ImportSchemaCtrl',stringMatch,{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                dlg.result.then(function(name){
+                       console.log("dlg.result");
+
+                },function(){
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+            }
+            else{
+
+                var dlg = dialogs.create('partials/portfolios/stringMatch_properties.html','ImportSchemaCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+
+                dlg.result.then(function(name){
+                       console.log("dlg.result");
+                    //$scope.name = name;
+                },function(){
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+
+            }
+        };
+
+        $scope.TCAWindow = function (tca) {
+               if (isTemplate){
+               var dlg = dialogs.create('partials/portfolios/Template_model.html','ImportSchemaCtrl',tca,{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                dlg.result.then(function(name){
+                },function(){
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+            }
+            else{
+                var dlg = dialogs.create('partials/portfolios/tca_properties.html','ImportSchemaCtrl',{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+
+                dlg.result.then(function(name){
+                    //$scope.name = name;
+                },function(){
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+            }
+        };
+        
+        $scope.PolicyWindow=function (policy) {
+               console.log("PolicyWindow");
+               if (isTemplate){
+               var dlg = dialogs.create('partials/portfolios/Template_model.html','ImportSchemaCtrl',policy,{closable:true,draggable:true},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+                dlg.result.then(function(name){
+                       console.log("dlg.result");
+
+                },function(){
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+            }
+            else {
+                var dlg = dialogs.create('partials/portfolios/PolicyWindow_properties.html', 'ImportSchemaCtrl', {
+                    closable: true,
+                    draggable: true
+                }, {size: 'lg', keyboard: true, backdrop: 'static', windowClass: 'my-class'});
+
+                dlg.result.then(function (name) {
+                       console.log("dlg.result");
+                    //$scope.name = name;
+                }, function () {
+                       console.log("...emptyfunction");
+                    //if(angular.equals($scope.name,''))
+                    //$scope.name = 'You did not enter in your name!';
+                });
+
+            }
+        };
+       
+        
+      
+        
+        $scope.populatePathDetails= function(allPathDetails,utmModels){
+        console.log("populatePathDetails");            
+               if (utmModels != null && utmModels.name != null) {
+                       var pathDetails = {};                           
+                       pathDetails = list_model_path_details[utmModels.name];
+                       allPathDetails.push(pathDetails);
+                       if(utmModels.subModels != null && utmModels.subModels.length>0){                                
+                               for(var i=0 ; i<utmModels.subModels.length;i++) {
+                                       var subModel = {};
+                                       subModel = utmModels.subModels[i];
+                                       $scope.populatePathDetails(allPathDetails,subModel);
+                                }
+                       }
+                       
+               }
+       };      
+       
+       $scope.getPathDetails= function(utmModels,selectedModelName) { 
+          console.log("getPathDetails");               
+               if (utmModels != null && utmModels.name != null && utmModels.name===selectedModelName){
+                       $scope.currentSelectedModel = utmModels;
+               }else if(utmModels.subModels != null && utmModels.subModels.length>0){                          
+                               for(var i=0 ; i<utmModels.subModels.length;i++) {
+                                       var subModel = {};
+                                       subModel = utmModels.subModels[i];
+                                       $scope.getPathDetails(subModel,selectedModelName);
+                                }
+                       }
+                               
+       };
+        
+        
+        
+}]);
+
+app.service('MenuService', ['$http', '$q', function ($http, $q) {
+       console.log("MenuService");
+    this.generateMDTTestSet = function(utmMDTRequest, generateTestSetMDTURL){
+
+       console.log("generateMDTTestSet");
+       //alert("In generateMDTTestSet :: " + JSON.stringify(utmMDTRequest));
+       var def = $q.defer();
+       var sets = [];
+       
+        $http.post(generateTestSetMDTURL, utmMDTRequest)
+        .success(function(data){ 
+        console.log("success");        
+               sets = data;
+               def.resolve(data);              
+               
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject("GenerateMDTTestSet not successful");
+        });
+        
+        return def.promise;
+    };
+}]);
+
+app.directive('focus',
+               function($timeout) {
+                       console.log("focus");
+       return {
+               scope : {
+                       trigger : '@focus'
+               },
+               link : function(scope, element) {
+                       scope.$watch('trigger', function(value) {
+                               console.log("trigger");
+                               if (value === "true") {
+                                       $timeout(function() {
+                                               console.log("timeout");
+                                               element[0].focus();
+                                       });
+                               }
+                       });
+               }
+       };
+}
+); 
+app.directive('draggable', function($document) {
+       console.log("draggable");
+  return function(scope, element, attr) {
+       console.log("return");
+    var startX = 0, startY = 0, x = 0, y = 0;
+    element.css({
+     position: 'relative',
+     
+     backgroundColor: 'white',
+     cursor: 'move',
+     display: 'block',
+     
+    });
+    element.on('mousedown', function(event) {
+       console.log("mousedown");
+      // Prevent default dragging of selected content
+      //event.preventDefault();
+      startX = event.screenX - x;
+      startY = event.screenY - y;
+      $document.on('mousemove', mousemove);
+      $document.on('mouseup', mouseup);
+    });
+
+    function mousemove(event) {
+       console.log("mousemove");
+      y = event.screenY - startY;
+      x = event.screenX - startX;
+      element.css({
+        top: y + 'px',
+        left:  x + 'px'
+      });
+    }
+
+    function mouseup() {
+       console.log("mouseup");
+      $document.off('mousemove', mousemove);
+      $document.off('mouseup', mouseup);
+    }
+  };
+});
+
+app.factory('myHttpInterceptor', function ($q, $window) 
+{
+       console.log("myHttpInterceptor");
+         return function (promise) 
+         {
+               console.log("promise");
+           return promise.then(function (response) 
+           {
+               console.log("response");
+             return response;
+           }, 
+           function (response) 
+           {   
+               console.log("response");
+             return $q.reject(response);
+           });
+         };
+});
+
+
+
+app.run(['$route', function($route)  {
+       console.log("route");
+         $route.reload();
+}]);
+function TestCtrl($scope) {
+       console.log("TestCtrl");
+    $scope.msg = "Hello from a controller method.";
+    $scope.returnHello = function() {
+       console.log("returnHello");
+        return $scope.msg ; 
+    }
+}
+function importshema()
+{
+       console.log("importshema");
+
+       angular.element(document.getElementById('navbar')).scope().importSchema();
+       
+}
+
+function CollectorsWindow(collectorsWin) {
+       console.log("CollectorsWindow");
+
+    angular.element(document.getElementById('navbar')).scope().CollectorsWindow(collectorsWin);
+
+}
+
+function F5Window() {
+       console.log("F5Window");
+
+    angular.element(document.getElementById('navbar')).scope().F5Window();
+
+}
+
+function StringMatchWindow(stringMatch) {
+       console.log("StringMatchWindow");
+
+    angular.element(document.getElementById('navbar')).scope().StringMatchWindow(stringMatch);
+
+}
+function TCAWindow(tca) {
+
+    angular.element(document.getElementById('navbar')).scope().TCAWindow(tca);
+
+}
+function GOCWindow() {
+       console.log("GOCWindow");
+
+    angular.element(document.getElementById('navbar')).scope().GOCWindow();
+
+}
+function PolicyWindow(PolicyWin) {
+       console.log("PolicyWin");
+    angular.element(document.getElementById('navbar')).scope().PolicyWindow(PolicyWin);
+
+}
+
+
+
+function pathDetails(bpmnElementID,bpmnElementName,pathIdentifiers)
+{
+       console.log("pathDetails");
+
+       angular.element(document.getElementById('navbar')).scope().pathDetails(bpmnElementID,bpmnElementName,pathIdentifiers);
+       
+}
+function setdefaultvalue()
+{
+       console.log("setDefaultValue");
+
+       angular.element(document.getElementById('navbar')).scope().setDefaultValue();
+       
+}
+function upgradeSchemaVersion()
+{
+       console.log("upgradeSchemaVersion");
+
+       angular.element(document.getElementById('navbar')).scope().upgradeSchemaVersion();
+       
+}
+function saveProject()
+{
+       console.log("saveProject");
+
+       angular.element(document.getElementById('navbar')).scope().saveProject();
+       
+}
+function modifySchema()
+{
+       console.log("modifySchema");
+
+       angular.element(document.getElementById('navbar')).scope().modifySchema();
+       
+}
+
+function definePID()
+{
+       console.log("definePID");
+
+       angular.element(document.getElementById('navbar')).scope().definePID();
+       
+}
+function defineServiceAcronym()
+{
+       console.log("defineServiceAcronym");
+
+       angular.element(document.getElementById('navbar')).scope().defineServiceAcronym();
+       
+}
+function errorProperty(msg)
+{
+       console.log("errorProperty");
+       angular.element(document.getElementById('navbar')).scope().propertyExplorerErrorMessage(msg);
+}
+function invisiblepropertyExplorer()
+{
+       console.log("invisiblepropertyExplorer");
+       
+       angular.element(document.getElementById('navbar')).scope().invisibleproperty();
+}
+function updateDecisionLabel(originalLabel, newLabel)
+{
+       console.log("updateDecisionLabel");
+       angular.element(document.getElementById('navbar')).scope().updateDecisionLabels(originalLabel, newLabel);
+}
diff --git a/src/main/resources/META-INF/resources/designer/scripts/authcontroller.js b/src/main/resources/META-INF/resources/designer/scripts/authcontroller.js
new file mode 100644 (file)
index 0000000..fe3a7fd
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+
+function AuthenticateCtrl($scope,$rootScope, $resource, $http, $location,$cookies) 
+{
+       console.log("//////////AuthenticateCtrl"); 
+       $scope.getInclude = function() 
+       { 
+               console.log("getInclude"); 
+               return "utmdashboard.html"; 
+       }; 
+       $scope.authenticate = function() 
+       { 
+               console.log("authenticate"); 
+
+               $rootScope.isAuth = true; 
+               $rootScope.loginuser = "somebody"; 
+               $rootScope.loginemailid = "somebody@somewhere.com"; 
+               $rootScope.attuid  = "m12349"; 
+       };
+}
diff --git a/src/main/resources/META-INF/resources/designer/scripts/commonService.js b/src/main/resources/META-INF/resources/designer/scripts/commonService.js
new file mode 100644 (file)
index 0000000..bef4941
--- /dev/null
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('commonservice', ['$http', '$q', function ($http, $q) {
+       console.log("///////commonservice");
+       
+       /*$scope.close = function(){
+               $modalInstance.close("closed");
+       };*/
+       
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/common_variables.js b/src/main/resources/META-INF/resources/designer/scripts/common_variables.js
new file mode 100644 (file)
index 0000000..ad0e414
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+var uploadfile=null;
+var modelXML = '';
+var list_models = {};
+var selected_model = '';
+var selected_template='';
+var list_model_test_sets={};
+var list_model_path_details={};
+var list_model_schema_extensions={};
+var list_model_test_management_details={};
+var isImportSchema=false;
+var selected_decison_element='';
+var selected_element_name = '';
+var list_model_repeatable_heirarchical_elements={};
+var map_model_repeatable_heirarchical_elements={};
+var serviceName=null;
+var workspaceType='env';
+var environment_selected_file_id ='';
+var old_new_model_name={};
+var isModelRenamed = false;
+var isModelfrmClick = false;
+var autoSaveRevision =-1;
+var commandStackList = [];
+
+var defaults_props=null
+var elementMap={}
+var lastElementSelected=null
+var isTemplate=null;
+var vf_Services=null;
+var asdc_Services=null;
+var readOnly=false;//for when the user select read only on clamp app
+var runningInstances={}
diff --git a/src/main/resources/META-INF/resources/designer/scripts/dataFactory.js b/src/main/resources/META-INF/resources/designer/scripts/dataFactory.js
new file mode 100644 (file)
index 0000000..5a2e24d
--- /dev/null
@@ -0,0 +1,191 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.factory('Datafactory', function () {
+    console.log("/////////Datafactory");
+
+    var dbDataList = [];
+    var checkBoxListActivitytestCase=[];
+    var generateTstMultipleFlag="";
+    var writeFileDataList=[];
+    var fileStreamWriterList=[];
+    var xmlValidatorList=[];
+    var xmlAsserter={};
+    var runtimePythonScriptList=[];
+    var xmlValidatorDecisionLevel=[];
+    var runtimePythonScriptProjectLevelList=[];
+    var commonPythonScriptList=[];
+    var dbToolProjectLevelList=[];
+    var soapClientOption={};
+       var selectedTestCase={};
+       var executeResultset={};
+       var projectPreferenceInfo={};
+       var modelPreferenceInfo ={};
+    
+
+    return {
+        getDbDataList: function () {
+            console.log("getDbDataList");
+            return dbDataList;
+        },
+        setDbDataList: function (dbRequestList) {
+            console.log("setDbDataList");
+               dbDataList = dbRequestList;
+        },
+        getCheckBoxListActivitytestCase: function () {
+            console.log("getCheckBoxListActivitytestCase");
+            return checkBoxListActivitytestCase;
+        },
+        setCheckBoxListActivitytestCase: function (checkBoxListTestCase) {
+            console.log("setCheckBoxListActivitytestCase");
+               checkBoxListActivitytestCase = checkBoxListTestCase;
+        },
+        getGenerateTstMultipleFlag: function () {
+            console.log("getGenerateTstMultipleFlag");
+            return generateTstMultipleFlag;
+        },
+        setGenerateTstMultipleFlag: function (generateTstFlag) {
+            console.log("setGenerateTstMultipleFlag");
+               generateTstMultipleFlag = generateTstFlag;
+        },
+        getWriteFileDataList: function () {
+            console.log("getWriteFileDataList");
+            return writeFileDataList;
+        },
+        setWriteFileDataList: function (writeFileDataListData) {
+            console.log("setWriteFileDataList");
+               writeFileDataList = writeFileDataListData;
+        },
+        getFileStreamWriterList: function () {
+            console.log("getFileStreamWriterList");
+            return fileStreamWriterList;
+        },
+        setFileStreamWriterList: function (fileStreamWriterData) {
+            console.log("setFileStreamWriterList");
+               fileStreamWriterList = fileStreamWriterData;
+        },
+        getXmlValidatorList: function () {
+            console.log("getXmlValidatorList");
+            return xmlValidatorList;
+        },
+        setXmlValidatorList: function (xmlValidatorListData) {
+            console.log("setXmlValidatorList");
+               xmlValidatorList = xmlValidatorListData;
+        },
+        getXmlAsserter: function () {
+            console.log("getXmlAsserter");
+            return xmlAsserter;
+        },
+        setXmlAsserter: function (xmlAsserterData) {
+            console.log("setXmlAsserter");
+               xmlAsserter = xmlAsserterData;
+        },
+        getRuntimePythonScriptList: function () {
+            console.log("getRuntimePythonScriptList");
+            return runtimePythonScriptList;
+        },
+        setRuntimePythonScriptList: function (runtimePythonScriptListData) {
+            console.log("setRuntimePythonScriptList");
+               runtimePythonScriptList = runtimePythonScriptListData;
+        },
+        getXmlValidatorDecisionLevel: function(){
+            console.log("getXmlValidatorDecisionLevel");
+               return xmlValidatorDecisionLevel;
+        },
+        setXmlValidatorDecisionLevel:function(xmlValidatorDecisionLevelData){
+            console.log("setXmlValidatorDecisionLevel");
+               xmlValidatorDecisionLevel=xmlValidatorDecisionLevelData;
+        },
+        getRuntimePythonScriptProjectLevelList: function () {
+            console.log("getRuntimePythonScriptProjectLevelList");
+            return runtimePythonScriptProjectLevelList;
+        },
+        setRuntimePythonScriptProjectLevelList: function (runtimePythonScriptListData) {
+            console.log("setRuntimePythonScriptProjectLevelList");
+               runtimePythonScriptProjectLevelList = runtimePythonScriptListData;
+        },
+        
+        getCommonPythonScriptList: function () {
+            console.log("getCommonPythonScriptList");
+            return commonPythonScriptList;
+        },
+        setCommonPythonScriptList: function (commonPythonScriptListData) {
+            console.log("setCommonPythonScriptList");
+               commonPythonScriptList = commonPythonScriptListData;
+        },
+        
+        getDbToolProjectLevelList: function () {
+            console.log("getDbToolProjectLevelList");
+            return dbToolProjectLevelList;
+        },
+        setDbToolProjectLevelList: function (dbToolProjectLevelListData) {
+            console.log("setDbToolProjectLevelList");
+               dbToolProjectLevelList = dbToolProjectLevelListData;
+        },
+        getSoapClientOption: function () {
+            console.log("getSoapClientOption");
+            return soapClientOption;
+        },
+        setSoapClientOption: function (soapClientOptionData) {
+            console.log("setSoapClientOption");
+               soapClientOption = soapClientOptionData;
+        },
+               getSelectedTestCase: function () {
+            console.log("getSelectedTestCase");
+            return selectedTestCase;
+        },
+        setSelectedTestCase: function (selectedTestCaseData) {
+            console.log("setSelectedTestCase");
+               selectedTestCase = selectedTestCaseData;
+        },
+        
+        getExecuteResultset: function () {
+            console.log("getExecuteResultset");
+            return executeResultset;
+        },
+        setExecuteResultset: function (executeResultsetData) {
+            console.log("setExecuteResultset");
+               executeResultset = executeResultsetData;
+        },
+        
+        getProjectPreferenceInfo: function () {
+            console.log("getProjectPreferenceInfo");
+            return projectPreferenceInfo;
+        },
+        setProjectPreferenceInfo: function (projectPreferenceInfoData) {
+            console.log("setProjectPreferenceInfo");
+               projectPreferenceInfo = projectPreferenceInfoData;
+        },
+        
+        getModelPreferenceInfo: function () {
+            console.log("getModelPreferenceInfo");
+            return modelPreferenceInfo;
+        },
+        setModelPreferenceInfo: function (modelPreferenceInfoData) {
+            console.log("setModelPreferenceInfo");
+               modelPreferenceInfo = modelPreferenceInfoData;
+        }
+        
+        
+    };
+});
diff --git a/src/main/resources/META-INF/resources/designer/scripts/importSchemaService.js b/src/main/resources/META-INF/resources/designer/scripts/importSchemaService.js
new file mode 100644 (file)
index 0000000..cf73530
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('svnservice', ['$http', '$q', function ($http, $q) {
+    console.log("//////svnservice");
+    this.SVNToUrl = function(schemaLocation, userID, password,svnURL,svnUploadURL){
+        console.log("SVNToUrl");
+       
+       
+       var def = $q.defer();
+       var sets = [];
+       
+        var svnRequest = {schemaLocation: schemaLocation, userID: userID, password: password,svnURL:svnURL};
+        
+       
+        $http.post(svnUploadURL, svnRequest)
+        .success(function(data){  
+        console.log("success");        
+               pars = data;
+               def.resolve(data);              
+               
+        })
+        .error(function(data){  
+        console.log("error");                        
+                       def.reject("SVN Import not successful");
+        });
+        
+        return def.promise;
+    };
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/kendo.custom.min.js b/src/main/resources/META-INF/resources/designer/scripts/kendo.custom.min.js
new file mode 100644 (file)
index 0000000..a75ceaa
--- /dev/null
@@ -0,0 +1,20 @@
+/*!
+ * Copyright 2017 Telerik AD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+!function(e,define){define("kendo.core.min",["jquery"],e)}(function(){return function(e,t,n){function i(){}function r(e,t){if(t)return"'"+e.split("'").join("\\'").split('\\"').join('\\\\\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")+"'";var n=e.charAt(0),i=e.substring(1);return"="===n?"+("+i+")+":":"===n?"+$kendoHtmlEncode("+i+")+":";"+e+";$kendoOutput+="}function o(e,t,n){return e+="",t=t||2,n=t-e.length,n?W[t].substring(0,n)+e:e}function a(e){var t=e.css(ve.support.transitions.css+"box-shadow")||e.css("box-shadow"),n=t?t.match(ze)||[0,0,0,0,0]:[0,0,0,0,0],i=xe.max(+n[3],+(n[4]||0));return{left:-n[1]+i,right:+n[1]+i,bottom:+n[2]+i}}function s(t,n){var i,r,o,a,s,l,u,c=Te.browser,d=ve._outerWidth,f=ve._outerHeight;return t.parent().hasClass("k-animation-container")?(l=t.parent(".k-animation-container"),u=l[0].style,l.is(":hidden")&&l.show(),i=Se.test(u.width)||Se.test(u.height),i||l.css({width:d(t),height:f(t),boxSizing:"content-box",mozBoxSizing:"content-box",webkitBoxSizing:"content-box"})):(r=t[0].style.width,o=t[0].style.height,a=Se.test(r),s=Se.test(o),i=a||s,!a&&(!n||n&&r)&&(r=d(t)),!s&&(!n||n&&o)&&(o=f(t)),t.wrap(e("<div/>").addClass("k-animation-container").css({width:r,height:o})),i&&t.css({width:"100%",height:"100%",boxSizing:"border-box",mozBoxSizing:"border-box",webkitBoxSizing:"border-box"})),c.msie&&xe.floor(c.version)<=7&&(t.css({zoom:1}),t.children(".k-menu").width(t.width())),t.parent()}function l(e){var t=1,n=arguments.length;for(t=1;t<n;t++)u(e,arguments[t]);return e}function u(e,t){var n,i,r,o,a,s=ve.data.ObservableArray,l=ve.data.LazyObservableArray,c=ve.data.DataSource,d=ve.data.HierarchicalDataSource;for(n in t)i=t[n],r=typeof i,o=r===$e&&null!==i?i.constructor:null,o&&o!==Array&&o!==s&&o!==l&&o!==c&&o!==d&&o!==RegExp?i instanceof Date?e[n]=new Date(i.getTime()):O(i.clone)?e[n]=i.clone():(a=e[n],e[n]=typeof a===$e?a||{}:{},u(e[n],i)):r!==Ne&&(e[n]=i);return e}function c(e,t,i){for(var r in t)if(t.hasOwnProperty(r)&&t[r].test(e))return r;return i!==n?i:e}function d(e){return e.replace(/([a-z][A-Z])/g,function(e){return e.charAt(0)+"-"+e.charAt(1).toLowerCase()})}function f(e){return e.replace(/\-(\w)/g,function(e,t){return t.toUpperCase()})}function p(t,n){var i,r={};return document.defaultView&&document.defaultView.getComputedStyle?(i=document.defaultView.getComputedStyle(t,""),n&&e.each(n,function(e,t){r[t]=i.getPropertyValue(t)})):(i=t.currentStyle,n&&e.each(n,function(e,t){r[t]=i[f(t)]})),ve.size(r)||(r=i),r}function h(e){if(e&&e.className&&"string"==typeof e.className&&e.className.indexOf("k-auto-scrollable")>-1)return!0;var t=p(e,["overflow"]).overflow;return"auto"==t||"scroll"==t}function m(t,i){var r,o=Te.browser.webkit,a=Te.browser.mozilla,s=t instanceof e?t[0]:t;if(t)return r=Te.isRtl(t),i===n?r&&o?s.scrollWidth-s.clientWidth-s.scrollLeft:Math.abs(s.scrollLeft):(s.scrollLeft=r&&o?s.scrollWidth-s.clientWidth-i:r&&a?-i:i,n)}function g(e){var t,n=0;for(t in e)e.hasOwnProperty(t)&&"toJSON"!=t&&n++;return n}function v(e,n,i){var r,o,a;return n||(n="offset"),r=e[n](),o={top:r.top,right:r.right,bottom:r.bottom,left:r.left},Te.browser.msie&&(Te.pointers||Te.msPointers)&&!i&&(a=Te.isRtl(e)?1:-1,o.top-=t.pageYOffset+a*document.documentElement.scrollTop,o.left-=t.pageXOffset+a*document.documentElement.scrollLeft),o}function y(e){var t={};return be("string"==typeof e?e.split(" "):e,function(e){t[e]=this}),t}function b(e){return new ve.effects.Element(e)}function w(e,t,n,i){return typeof e===Pe&&(O(t)&&(i=t,t=400,n=!1),O(n)&&(i=n,n=!1),typeof t===He&&(n=t,t=400),e={effects:e,duration:t,reverse:n,complete:i}),ye({effects:{},duration:400,reverse:!1,init:_e,teardown:_e,hide:!1},e,{completeCallback:e.complete,complete:_e})}function k(t,n,i,r,o){for(var a,s=0,l=t.length;s<l;s++)a=e(t[s]),a.queue(function(){U.promise(a,w(n,i,r,o))});return t}function _(e,t,n,i){return t&&(t=t.split(" "),be(t,function(t,n){e.toggleClass(n,i)})),e}function x(e){return(""+e).replace(j,"&amp;").replace(q,"&lt;").replace(G,"&gt;").replace(Y,"&quot;").replace(J,"&#39;")}function M(e,t){var i;return 0===t.indexOf("data")&&(t=t.substring(4),t=t.charAt(0).toLowerCase()+t.substring(1)),t=t.replace(re,"-$1"),i=e.getAttribute("data-"+ve.ns+t),null===i?i=n:"null"===i?i=null:"true"===i?i=!0:"false"===i?i=!1:De.test(i)?i=parseFloat(i):ne.test(i)&&!ie.test(i)&&(i=Function("return ("+i+")")()),i}function T(t,i){var r,o,a={};for(r in i)o=M(t,r),o!==n&&(te.test(r)&&(o="string"==typeof o?ve.template(e("#"+o).html()):t.getAttribute(r)),a[r]=o);return a}function S(t,n){return e.contains(t,n)?-1:1}function E(){var t=e(this);return e.inArray(t.attr("data-"+ve.ns+"role"),["slider","rangeslider"])>-1||t.is(":visible")}function z(e,t){var n=e.nodeName.toLowerCase();return(/input|select|textarea|button|object/.test(n)?!e.disabled:"a"===n?e.href||t:t)&&D(e)}function D(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}function C(e,t){return new C.fn.init(e,t)}var P,O,$,A,H,N,L,I,F,V,R,W,B,U,j,q,Y,J,G,Q,X,Z,K,ee,te,ne,ie,re,oe,ae,se,le,ue,ce,de,fe,pe,he,me,ge,ve=t.kendo=t.kendo||{cultures:{}},ye=e.extend,be=e.each,we=e.isArray,ke=e.proxy,_e=e.noop,xe=Math,Me=t.JSON||{},Te={},Se=/%/,Ee=/\{(\d+)(:[^\}]+)?\}/g,ze=/(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+)?/i,De=/^(\+|-?)\d+(\.?)\d*$/,Ce="function",Pe="string",Oe="number",$e="object",Ae="null",He="boolean",Ne="undefined",Le={},Ie={},Fe=[].slice;ve.version="2017.2.619".replace(/^\s+|\s+$/g,""),i.extend=function(e){var t,n,i=function(){},r=this,o=e&&e.init?e.init:function(){r.apply(this,arguments)};i.prototype=r.prototype,n=o.fn=o.prototype=new i;for(t in e)n[t]=null!=e[t]&&e[t].constructor===Object?ye(!0,{},i.prototype[t],e[t]):e[t];return n.constructor=o,o.extend=r.extend,o},i.prototype._initOptions=function(e){this.options=l({},this.options,e)},O=ve.isFunction=function(e){return"function"==typeof e},$=function(){this._defaultPrevented=!0},A=function(){return this._defaultPrevented===!0},H=i.extend({init:function(){this._events={}},bind:function(e,t,i){var r,o,a,s,l,u=this,c=typeof e===Pe?[e]:e,d=typeof t===Ce;if(t===n){for(r in e)u.bind(r,e[r]);return u}for(r=0,o=c.length;r<o;r++)e=c[r],s=d?t:t[e],s&&(i&&(a=s,s=function(){u.unbind(e,s),a.apply(u,arguments)},s.original=a),l=u._events[e]=u._events[e]||[],l.push(s));return u},one:function(e,t){return this.bind(e,t,!0)},first:function(e,t){var n,i,r,o,a=this,s=typeof e===Pe?[e]:e,l=typeof t===Ce;for(n=0,i=s.length;n<i;n++)e=s[n],r=l?t:t[e],r&&(o=a._events[e]=a._events[e]||[],o.unshift(r));return a},trigger:function(e,t){var n,i,r=this,o=r._events[e];if(o){for(t=t||{},t.sender=r,t._defaultPrevented=!1,t.preventDefault=$,t.isDefaultPrevented=A,o=o.slice(),n=0,i=o.length;n<i;n++)o[n].call(r,t);return t._defaultPrevented===!0}return!1},unbind:function(e,t){var i,r=this,o=r._events[e];if(e===n)r._events={};else if(o)if(t)for(i=o.length-1;i>=0;i--)o[i]!==t&&o[i].original!==t||o.splice(i,1);else r._events[e]=[];return r}}),N=/^\w+/,L=/\$\{([^}]*)\}/g,I=/\\\}/g,F=/__CURLY__/g,V=/\\#/g,R=/__SHARP__/g,W=["","0","00","000","0000"],P={paramName:"data",useWithBlock:!0,render:function(e,t){var n,i,r="";for(n=0,i=t.length;n<i;n++)r+=e(t[n]);return r},compile:function(e,t){var n,i,o,a=ye({},this,t),s=a.paramName,l=s.match(N)[0],u=a.useWithBlock,c="var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;";if(O(e))return e;for(c+=u?"with("+s+"){":"",c+="$kendoOutput=",i=e.replace(I,"__CURLY__").replace(L,"#=$kendoHtmlEncode($1)#").replace(F,"}").replace(V,"__SHARP__").split("#"),o=0;o<i.length;o++)c+=r(i[o],o%2===0);c+=u?";}":";",c+="return $kendoOutput;",c=c.replace(R,"#");try{return n=Function(l,c),n._slotCount=Math.floor(i.length/2),n}catch(d){throw Error(ve.format("Invalid template:'{0}' Generated code:'{1}'",e,c))}}},function(){function e(e){return a.lastIndex=0,a.test(e)?'"'+e.replace(a,function(e){var t=s[e];return typeof t===Pe?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function t(o,a){var s,u,c,d,f,p,h=n,m=a[o];if(m&&typeof m===$e&&typeof m.toJSON===Ce&&(m=m.toJSON(o)),typeof r===Ce&&(m=r.call(a,o,m)),p=typeof m,p===Pe)return e(m);if(p===Oe)return isFinite(m)?m+"":Ae;if(p===He||p===Ae)return m+"";if(p===$e){if(!m)return Ae;if(n+=i,f=[],"[object Array]"===l.apply(m)){for(d=m.length,s=0;s<d;s++)f[s]=t(s,m)||Ae;return c=0===f.length?"[]":n?"[\n"+n+f.join(",\n"+n)+"\n"+h+"]":"["+f.join(",")+"]",n=h,c}if(r&&typeof r===$e)for(d=r.length,s=0;s<d;s++)typeof r[s]===Pe&&(u=r[s],c=t(u,m),c&&f.push(e(u)+(n?": ":":")+c));else for(u in m)Object.hasOwnProperty.call(m,u)&&(c=t(u,m),c&&f.push(e(u)+(n?": ":":")+c));return c=0===f.length?"{}":n?"{\n"+n+f.join(",\n"+n)+"\n"+h+"}":"{"+f.join(",")+"}",n=h,c}}var n,i,r,a=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,s={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},l={}.toString;typeof Date.prototype.toJSON!==Ce&&(Date.prototype.toJSON=function(){var e=this;return isFinite(e.valueOf())?o(e.getUTCFullYear(),4)+"-"+o(e.getUTCMonth()+1)+"-"+o(e.getUTCDate())+"T"+o(e.getUTCHours())+":"+o(e.getUTCMinutes())+":"+o(e.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}),typeof Me.stringify!==Ce&&(Me.stringify=function(e,o,a){var s;if(n="",i="",typeof a===Oe)for(s=0;s<a;s+=1)i+=" ";else typeof a===Pe&&(i=a);if(r=o,o&&typeof o!==Ce&&(typeof o!==$e||typeof o.length!==Oe))throw Error("JSON.stringify");return t("",{"":e})})}(),function(){function t(e){if(e){if(e.numberFormat)return e;if(typeof e===Pe){var t=ve.cultures;return t[e]||t[e.split("-")[0]]||null}return null}return null}function i(e){return e&&(e=t(e)),e||ve.cultures.current}function r(e,t,r){r=i(r);var a=r.calendars.standard,s=a.days,l=a.months;return t=a.patterns[t]||t,t.replace(c,function(t){var i,r,u;return"d"===t?r=e.getDate():"dd"===t?r=o(e.getDate()):"ddd"===t?r=s.namesAbbr[e.getDay()]:"dddd"===t?r=s.names[e.getDay()]:"M"===t?r=e.getMonth()+1:"MM"===t?r=o(e.getMonth()+1):"MMM"===t?r=l.namesAbbr[e.getMonth()]:"MMMM"===t?r=l.names[e.getMonth()]:"yy"===t?r=o(e.getFullYear()%100):"yyyy"===t?r=o(e.getFullYear(),4):"h"===t?r=e.getHours()%12||12:"hh"===t?r=o(e.getHours()%12||12):"H"===t?r=e.getHours():"HH"===t?r=o(e.getHours()):"m"===t?r=e.getMinutes():"mm"===t?r=o(e.getMinutes()):"s"===t?r=e.getSeconds():"ss"===t?r=o(e.getSeconds()):"f"===t?r=xe.floor(e.getMilliseconds()/100):"ff"===t?(r=e.getMilliseconds(),r>99&&(r=xe.floor(r/10)),r=o(r)):"fff"===t?r=o(e.getMilliseconds(),3):"tt"===t?r=e.getHours()<12?a.AM[0]:a.PM[0]:"zzz"===t?(i=e.getTimezoneOffset(),u=i<0,r=(""+xe.abs(i/60)).split(".")[0],i=xe.abs(i)-60*r,r=(u?"+":"-")+o(r),r+=":"+o(i)):"zz"!==t&&"z"!==t||(r=e.getTimezoneOffset()/60,u=r<0,r=(""+xe.abs(r)).split(".")[0],r=(u?"+":"-")+("zz"===t?o(r):r)),r!==n?r:t.slice(1,t.length-1)})}function a(e,t,r){r=i(r);var o,a,u,c,w,k,_,x,M,T,S,E,z,D,C,P,O,$,A,H,N,L,I,F=r.numberFormat,V=F[m],R=F.decimals,W=F.pattern[0],B=[],U=e<0,j=h,q=h,Y=-1;if(e===n)return h;if(!isFinite(e))return e;if(!t)return r.name.length?e.toLocaleString():""+e;if(w=d.exec(t)){if(t=w[1].toLowerCase(),a="c"===t,u="p"===t,(a||u)&&(F=a?F.currency:F.percent,V=F[m],R=F.decimals,o=F.symbol,W=F.pattern[U?0:1]),c=w[2],c&&(R=+c),"e"===t)return c?e.toExponential(R):e.toExponential();if(u&&(e*=100),e=l(e,R),U=e<0,e=e.split(m),k=e[0],_=e[1],U&&(k=k.substring(1)),q=s(k,0,k.length,F),_&&(q+=V+_),"n"===t&&!U)return q;for(e=h,T=0,S=W.length;T<S;T++)E=W.charAt(T),e+="n"===E?q:"$"===E||"%"===E?o:E;return e}if(U&&(e=-e),(t.indexOf("'")>-1||t.indexOf('"')>-1||t.indexOf("\\")>-1)&&(t=t.replace(f,function(e){var t=e.charAt(0).replace("\\",""),n=e.slice(1).replace(t,"");return B.push(n),b})),t=t.split(";"),U&&t[1])t=t[1],D=!0;else if(0===e){if(t=t[2]||t[0],t.indexOf(v)==-1&&t.indexOf(y)==-1)return t}else t=t[0];if(H=t.indexOf("%"),N=t.indexOf("$"),u=H!=-1,a=N!=-1,u&&(e*=100),a&&"\\"===t[N-1]&&(t=t.split("\\").join(""),a=!1),(a||u)&&(F=a?F.currency:F.percent,V=F[m],R=F.decimals,o=F.symbol),z=t.indexOf(g)>-1,z&&(t=t.replace(p,h)),C=t.indexOf(m),S=t.length,C!=-1?(_=(""+e).split("e"),_=_[1]?l(e,Math.abs(_[1])):_[0],_=_.split(m)[1]||h,O=t.lastIndexOf(y)-C,P=t.lastIndexOf(v)-C,$=O>-1,A=P>-1,T=_.length,$||A||(t=t.substring(0,C)+t.substring(C+1),S=t.length,C=-1,T=0),$&&O>P?T=O:P>O&&(A&&T>P?T=P:$&&T<O&&(T=O)),T>-1&&(e=l(e,T))):e=l(e),P=t.indexOf(v),L=O=t.indexOf(y),Y=P==-1&&O!=-1?O:P!=-1&&O==-1?P:P>O?O:P,P=t.lastIndexOf(v),O=t.lastIndexOf(y),I=P==-1&&O!=-1?O:P!=-1&&O==-1?P:P>O?P:O,Y==S&&(I=Y),Y!=-1){for(q=(""+e).split(m),k=q[0],_=q[1]||h,x=k.length,M=_.length,U&&e*-1>=0&&(U=!1),e=t.substring(0,Y),U&&!D&&(e+="-"),T=Y;T<S;T++){if(E=t.charAt(T),C==-1){if(I-T<x){e+=k;break}}else if(O!=-1&&O<T&&(j=h),C-T<=x&&C-T>-1&&(e+=k,T=C),C===T){e+=(_?V:h)+_,T+=I-C+1;continue}E===y?(e+=E,j=E):E===v&&(e+=j)}if(z&&(e=s(e,Y+(U&&!D?1:0),Math.max(I,x+Y),F)),I>=Y&&(e+=t.substring(I+1)),a||u){for(q=h,T=0,S=e.length;T<S;T++)E=e.charAt(T),q+="$"===E||"%"===E?o:E;e=q}if(S=B.length)for(T=0;T<S;T++)e=e.replace(b,B[T])}return e}var s,l,u,c=/dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|zzz|zz|z|"[^"]*"|'[^']*'/g,d=/^(n|c|p|e)(\d*)$/i,f=/(\\.)|(['][^']*[']?)|(["][^"]*["]?)/g,p=/\,/g,h="",m=".",g=",",v="#",y="0",b="??",w="en-US",k={}.toString;ve.cultures["en-US"]={name:w,numberFormat:{pattern:["-n"],decimals:2,",":",",".":".",groupSize:[3],percent:{pattern:["-n %","n %"],decimals:2,",":",",".":".",groupSize:[3],symbol:"%"},currency:{name:"US Dollar",abbr:"USD",pattern:["($n)","$n"],decimals:2,",":",",".":".",groupSize:[3],symbol:"$"}},calendars:{standard:{days:{names:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],namesAbbr:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],namesShort:["Su","Mo","Tu","We","Th","Fr","Sa"]},months:{names:["January","February","March","April","May","June","July","August","September","October","November","December"],namesAbbr:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},AM:["AM","am","AM"],PM:["PM","pm","PM"],patterns:{d:"M/d/yyyy",D:"dddd, MMMM dd, yyyy",F:"dddd, MMMM dd, yyyy h:mm:ss tt",g:"M/d/yyyy h:mm tt",G:"M/d/yyyy h:mm:ss tt",m:"MMMM dd",M:"MMMM dd",s:"yyyy'-'MM'-'ddTHH':'mm':'ss",t:"h:mm tt",T:"h:mm:ss tt",u:"yyyy'-'MM'-'dd HH':'mm':'ss'Z'",y:"MMMM, yyyy",Y:"MMMM, yyyy"},"/":"/",":":":",firstDay:0,twoDigitYearMax:2029}}},ve.culture=function(e){var i,r=ve.cultures;return e===n?r.current:(i=t(e)||r[w],i.calendar=i.calendars.standard,r.current=i,n)},ve.findCulture=t,ve.getCulture=i,ve.culture(w),s=function(e,t,i,r){var o,a,s,l,u,c,d=e.indexOf(r[m]),f=r.groupSize.slice(),p=f.shift();if(i=d!==-1?d:i+1,o=e.substring(t,i),a=o.length,a>=p){for(s=a,l=[];s>-1;)if(u=o.substring(s-p,s),u&&l.push(u),s-=p,c=f.shift(),p=c!==n?c:p,0===p){l.push(o.substring(0,s));break}o=l.reverse().join(r[g]),e=e.substring(0,t)+o+e.substring(i)}return e},l=function(e,t){return t=t||0,e=(""+e).split("e"),e=Math.round(+(e[0]+"e"+(e[1]?+e[1]+t:t))),e=(""+e).split("e"),e=+(e[0]+"e"+(e[1]?+e[1]-t:-t)),e.toFixed(Math.min(t,20))},u=function(e,t,i){if(t){if("[object Date]"===k.call(e))return r(e,t,i);if(typeof e===Oe)return a(e,t,i)}return e!==n?e:""},ve.format=function(e){var t=arguments;return e.replace(Ee,function(e,n,i){var r=t[parseInt(n,10)+1];return u(r,i?i.substring(1):"")})},ve._extractFormat=function(e){return"{0:"===e.slice(0,3)&&(e=e.slice(3,e.length-1)),e},ve._activeElement=function(){try{return document.activeElement}catch(e){return document.documentElement.activeElement}},ve._round=l,ve._outerWidth=function(t,n){return e(t).outerWidth(n||!1)||0},ve._outerHeight=function(t,n){return e(t).outerHeight(n||!1)||0},ve.toString=u}(),function(){function t(e,t,n){return!(e>=t&&e<=n)}function i(e){return e.charAt(0)}function r(t){return e.map(t,i)}function o(e,t){t||23!==e.getHours()||e.setHours(e.getHours()+2)}function a(e){for(var t=0,n=e.length,i=[];t<n;t++)i[t]=(e[t]+"").toLowerCase();return i}function s(e){var t,n={};for(t in e)n[t]=a(e[t]);return n}function l(e,i,a){if(!e)return null;var l,u,c,d,f,m,g,v,y,w,k,_,x,M=function(e){for(var t=0;i[N]===e;)t++,N++;return t>0&&(N-=1),t},T=function(t){var n=b[t]||RegExp("^\\d{1,"+t+"}"),i=e.substr(L,t).match(n);return i?(i=i[0],L+=i.length,parseInt(i,10)):null},S=function(t,n){for(var i,r,o,a=0,s=t.length,l=0,u=0;a<s;a++)i=t[a],r=i.length,o=e.substr(L,r),n&&(o=o.toLowerCase()),o==i&&r>l&&(l=r,u=a);return l?(L+=l,u+1):null},E=function(){var t=!1;return e.charAt(L)===i[N]&&(L++,t=!0),t},z=a.calendars.standard,D=null,C=null,P=null,O=null,$=null,A=null,H=null,N=0,L=0,I=!1,F=new Date,V=z.twoDigitYearMax||2029,R=F.getFullYear();for(i||(i="d"),d=z.patterns[i],d&&(i=d),i=i.split(""),c=i.length;N<c;N++)if(l=i[N],I)"'"===l?I=!1:E();else if("d"===l){if(u=M("d"),z._lowerDays||(z._lowerDays=s(z.days)),null!==P&&u>2)continue;if(P=u<3?T(2):S(z._lowerDays[3==u?"namesAbbr":"names"],!0),null===P||t(P,1,31))return null}else if("M"===l){if(u=M("M"),z._lowerMonths||(z._lowerMonths=s(z.months)),C=u<3?T(2):S(z._lowerMonths[3==u?"namesAbbr":"names"],!0),null===C||t(C,1,12))return null;C-=1}else if("y"===l){if(u=M("y"),D=T(u),null===D)return null;2==u&&("string"==typeof V&&(V=R+parseInt(V,10)),D=R-R%100+D,D>V&&(D-=100))}else if("h"===l){if(M("h"),O=T(2),12==O&&(O=0),null===O||t(O,0,11))return null}else if("H"===l){if(M("H"),O=T(2),null===O||t(O,0,23))return null}else if("m"===l){if(M("m"),$=T(2),null===$||t($,0,59))return null}else if("s"===l){if(M("s"),A=T(2),null===A||t(A,0,59))return null}else if("f"===l){if(u=M("f"),x=e.substr(L,u).match(b[3]),H=T(u),null!==H&&(H=parseFloat("0."+x[0],10),H=ve._round(H,3),H*=1e3),null===H||t(H,0,999))return null}else if("t"===l){if(u=M("t"),v=z.AM,y=z.PM,1===u&&(v=r(v),y=r(y)),f=S(y),!f&&!S(v))return null}else if("z"===l){if(m=!0,u=M("z"),"Z"===e.substr(L,1)){E();continue}if(g=e.substr(L,6).match(u>2?h:p),!g)return null;if(g=g[0].split(":"),w=g[0],k=g[1],!k&&w.length>3&&(L=w.length-2,k=w.substring(L),w=w.substring(0,L)),w=parseInt(w,10),t(w,-12,13))return null;if(u>2&&(k=parseInt(k,10),isNaN(k)||t(k,0,59)))return null}else if("'"===l)I=!0,E();else if(!E())return null;return _=null!==O||null!==$||A||null,null===D&&null===C&&null===P&&_?(D=R,C=F.getMonth(),P=F.getDate()):(null===D&&(D=R),null===P&&(P=1)),f&&O<12&&(O+=12),m?(w&&(O+=-w),k&&($+=-k),e=new Date(Date.UTC(D,C,P,O,$,A,H))):(e=new Date(D,C,P,O,$,A,H),o(e,O)),D<100&&e.setFullYear(D),e.getDate()!==P&&m===n?null:e}function u(e){var t="-"===e.substr(0,1)?-1:1;return e=e.substring(1),e=60*parseInt(e.substr(0,2),10)+parseInt(e.substring(2),10),t*e}function c(e){var t,n,i,r=xe.max(v.length,y.length),o=e.calendar.patterns,a=[];for(i=0;i<r;i++){for(t=v[i],n=0;n<t.length;n++)a.push(o[t[n]]);a=a.concat(y[i])}return a}var d=/\u00A0/g,f=/[eE][\-+]?[0-9]+/,p=/[+|\-]\d{1,2}/,h=/[+|\-]\d{1,2}:?\d{2}/,m=/^\/Date\((.*?)\)\/$/,g=/[+-]\d*/,v=[[],["G","g","F"],["D","d","y","m","T","t"]],y=[["yyyy-MM-ddTHH:mm:ss.fffffffzzz","yyyy-MM-ddTHH:mm:ss.fffffff","yyyy-MM-ddTHH:mm:ss.fffzzz","yyyy-MM-ddTHH:mm:ss.fff","ddd MMM dd yyyy HH:mm:ss","yyyy-MM-ddTHH:mm:sszzz","yyyy-MM-ddTHH:mmzzz","yyyy-MM-ddTHH:mmzz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm:ss"],["yyyy-MM-ddTHH:mm","yyyy-MM-dd HH:mm","yyyy/MM/dd HH:mm"],["yyyy/MM/dd","yyyy-MM-dd","HH:mm:ss","HH:mm"]],b={2:/^\d{1,2}/,3:/^\d{1,3}/,4:/^\d{4}/},w={}.toString;ve.parseDate=function(e,t,n){var i,r,o,a;if("[object Date]"===w.call(e))return e;if(i=0,r=null,e&&0===e.indexOf("/D")&&(r=m.exec(e)))return r=r[1],a=g.exec(r.substring(1)),r=new Date(parseInt(r,10)),a&&(a=u(a[0]),r=ve.timezone.apply(r,0),r=ve.timezone.convert(r,0,-1*a)),r;for(n=ve.getCulture(n),t||(t=c(n)),t=we(t)?t:[t],o=t.length;i<o;i++)if(r=l(e,t[i],n))return r;return r},ve.parseInt=function(e,t){var n=ve.parseFloat(e,t);return n&&(n=0|n),n},ve.parseFloat=function(e,t,n){if(!e&&0!==e)return null;if(typeof e===Oe)return e;e=""+e,t=ve.getCulture(t);var i,r,o=t.numberFormat,a=o.percent,s=o.currency,l=s.symbol,u=a.symbol,c=e.indexOf("-");return f.test(e)?(e=parseFloat(e.replace(o["."],".")),isNaN(e)&&(e=null),e):c>0?null:(c=c>-1,e.indexOf(l)>-1||n&&n.toLowerCase().indexOf("c")>-1?(o=s,i=o.pattern[0].replace("$",l).split("n"),e.indexOf(i[0])>-1&&e.indexOf(i[1])>-1&&(e=e.replace(i[0],"").replace(i[1],""),c=!0)):e.indexOf(u)>-1&&(r=!0,o=a,l=u),e=e.replace("-","").replace(l,"").replace(d," ").split(o[","].replace(d," ")).join("").replace(o["."],"."),e=parseFloat(e),isNaN(e)?e=null:c&&(e*=-1),e&&r&&(e/=100),e)}}(),function(){var i,r,o,a,s,l,u,d,f;Te._scrollbar=n,Te.scrollbar=function(e){if(isNaN(Te._scrollbar)||e){var t,n=document.createElement("div");return n.style.cssText="overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block",n.innerHTML="&nbsp;",document.body.appendChild(n),Te._scrollbar=t=n.offsetWidth-n.scrollWidth,document.body.removeChild(n),t}return Te._scrollbar},Te.isRtl=function(t){return e(t).closest(".k-rtl").length>0},i=document.createElement("table");try{i.innerHTML="<tr><td></td></tr>",Te.tbodyInnerHtml=!0}catch(p){Te.tbodyInnerHtml=!1}Te.touch="ontouchstart"in t,r=document.documentElement.style,o=Te.transitions=!1,a=Te.transforms=!1,s="HTMLElement"in t?HTMLElement.prototype:[],Te.hasHW3D="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix||"MozPerspective"in r||"msPerspective"in r,Te.cssFlexbox="flexWrap"in r||"WebkitFlexWrap"in r||"msFlexWrap"in r,be(["Moz","webkit","O","ms"],function(){var e,t=""+this,n=typeof i.style[t+"Transition"]===Pe;if(n||typeof i.style[t+"Transform"]===Pe)return e=t.toLowerCase(),a={css:"ms"!=e?"-"+e+"-":"",prefix:t,event:"o"===e||"webkit"===e?e:""},n&&(o=a,o.event=o.event?o.event+"TransitionEnd":"transitionend"),!1}),i=null,Te.transforms=a,Te.transitions=o,Te.devicePixelRatio=t.devicePixelRatio===n?1:t.devicePixelRatio;try{Te.screenWidth=t.outerWidth||t.screen?t.screen.availWidth:t.innerWidth,Te.screenHeight=t.outerHeight||t.screen?t.screen.availHeight:t.innerHeight}catch(p){Te.screenWidth=t.screen.availWidth,Te.screenHeight=t.screen.availHeight}Te.detectOS=function(e){var n,i,r=!1,o=[],a=!/mobile safari/i.test(e),s={wp:/(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/,fire:/(Silk)\/(\d+)\.(\d+(\.\d+)?)/,android:/(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.(\d+(\.\d+)?)/,iphone:/(iPhone|iPod).*OS\s+(\d+)[\._]([\d\._]+)/,ipad:/(iPad).*OS\s+(\d+)[\._]([\d_]+)/,meego:/(MeeGo).+NokiaBrowser\/(\d+)\.([\d\._]+)/,webos:/(webOS)\/(\d+)\.(\d+(\.\d+)?)/,blackberry:/(BlackBerry|BB10).*?Version\/(\d+)\.(\d+(\.\d+)?)/,playbook:/(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/,windows:/(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/,tizen:/(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i,sailfish:/(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i,ffos:/(Mobile).*rv:(\d+)\.(\d+(\.\d+)?).*Firefox/},l={ios:/^i(phone|pad|pod)$/i,android:/^android|fire$/i,blackberry:/^blackberry|playbook/i,windows:/windows/,wp:/wp/,flat:/sailfish|ffos|tizen/i,meego:/meego/},u={tablet:/playbook|ipad|fire/i},d={omini:/Opera\sMini/i,omobile:/Opera\sMobi/i,firefox:/Firefox|Fennec/i,mobilesafari:/version\/.*safari/i,ie:/MSIE|Windows\sPhone/i,chrome:/chrome|crios/i,webkit:/webkit/i};for(i in s)if(s.hasOwnProperty(i)&&(o=e.match(s[i]))){if("windows"==i&&"plugins"in navigator)return!1;r={},r.device=i,r.tablet=c(i,u,!1),r.browser=c(e,d,"default"),r.name=c(i,l),r[r.name]=!0,r.majorVersion=o[2],r.minorVersion=o[3].replace("_","."),n=r.minorVersion.replace(".","").substr(0,2),r.flatVersion=r.majorVersion+n+Array(3-(n.length<3?n.length:2)).join("0"),r.cordova=typeof t.PhoneGap!==Ne||typeof t.cordova!==Ne,r.appMode=t.navigator.standalone||/file|local|wmapp/.test(t.location.protocol)||r.cordova,r.android&&(Te.devicePixelRatio<1.5&&r.flatVersion<400||a)&&(Te.screenWidth>800||Te.screenHeight>800)&&(r.tablet=i);break}return r},l=Te.mobileOS=Te.detectOS(navigator.userAgent),Te.wpDevicePixelRatio=l.wp?screen.width/320:0,Te.hasNativeScrolling=!1,(l.ios||l.android&&l.majorVersion>2||l.wp)&&(Te.hasNativeScrolling=l),Te.delayedClick=function(){if(Te.touch){if(l.ios)return!0;if(l.android)return!Te.browser.chrome||!(Te.browser.version<32)&&!(e("meta[name=viewport]").attr("content")||"").match(/user-scalable=no/i)}return!1},Te.mouseAndTouchPresent=Te.touch&&!(Te.mobileOS.ios||Te.mobileOS.android),Te.detectBrowser=function(e){var t,n=!1,i=[],r={edge:/(edge)[ \/]([\w.]+)/i,webkit:/(chrome)[ \/]([\w.]+)/i,safari:/(webkit)[ \/]([\w.]+)/i,opera:/(opera)(?:.*version|)[ \/]([\w.]+)/i,msie:/(msie\s|trident.*? rv:)([\w.]+)/i,mozilla:/(mozilla)(?:.*? rv:([\w.]+)|)/i};for(t in r)if(r.hasOwnProperty(t)&&(i=e.match(r[t]))){n={},n[t]=!0,n[i[1].toLowerCase().split(" ")[0].split("/")[0]]=!0,n.version=parseInt(document.documentMode||i[2],10);break}return n},Te.browser=Te.detectBrowser(navigator.userAgent),Te.detectClipboardAccess=function(){var e={copy:!!document.queryCommandSupported&&document.queryCommandSupported("copy"),cut:!!document.queryCommandSupported&&document.queryCommandSupported("cut"),paste:!!document.queryCommandSupported&&document.queryCommandSupported("paste")};return Te.browser.chrome&&(e.paste=!1,Te.browser.version>=43&&(e.copy=!0,e.cut=!0)),e},Te.clipboard=Te.detectClipboardAccess(),Te.zoomLevel=function(){var e,n,i;try{return e=Te.browser,n=0,i=document.documentElement,e.msie&&11==e.version&&i.scrollHeight>i.clientHeight&&!Te.touch&&(n=Te.scrollbar()),Te.touch?i.clientWidth/t.innerWidth:e.msie&&e.version>=10?((top||t).document.documentElement.offsetWidth+n)/(top||t).innerWidth:1}catch(r){return 1}},Te.cssBorderSpacing=n!==r.borderSpacing&&!(Te.browser.msie&&Te.browser.version<8),function(t){var n="",i=e(document.documentElement),r=parseInt(t.version,10);t.msie?n="ie":t.mozilla?n="ff":t.safari?n="safari":t.webkit?n="webkit":t.opera?n="opera":t.edge&&(n="edge"),n&&(n="k-"+n+" k-"+n+r),Te.mobileOS&&(n+=" k-mobile"),Te.cssFlexbox||(n+=" k-no-flexbox"),i.addClass(n)}(Te.browser),Te.eventCapture=document.documentElement.addEventListener,u=document.createElement("input"),Te.placeholder="placeholder"in u,Te.propertyChangeEvent="onpropertychange"in u,Te.input=function(){for(var e,t=["number","date","time","month","week","datetime","datetime-local"],n=t.length,i="test",r={},o=0;o<n;o++)e=t[o],u.setAttribute("type",e),u.value=i,r[e.replace("-","")]="text"!==u.type&&u.value!==i;return r}(),u.style.cssText="float:left;",Te.cssFloat=!!u.style.cssFloat,u=null,Te.stableSort=function(){var e,t=513,n=[{index:0,field:"b"}];for(e=1;e<t;e++)n.push({index:e,field:"a"});return n.sort(function(e,t){return e.field>t.field?1:e.field<t.field?-1:0}),1===n[0].index}(),Te.matchesSelector=s.webkitMatchesSelector||s.mozMatchesSelector||s.msMatchesSelector||s.oMatchesSelector||s.matchesSelector||s.matches||function(t){for(var n=document.querySelectorAll?(this.parentNode||document).querySelectorAll(t)||[]:e(t),i=n.length;i--;)if(n[i]==this)return!0;return!1},Te.pushState=t.history&&t.history.pushState,d=document.documentMode,Te.hashChange="onhashchange"in t&&!(Te.browser.msie&&(!d||d<=8)),Te.customElements="registerElement"in t.document,f=Te.browser.chrome,Te.msPointers=!f&&t.MSPointerEvent,Te.pointers=!f&&t.PointerEvent,Te.kineticScrollNeeded=l&&(Te.touch||Te.msPointers||Te.pointers)}(),B={left:{reverse:"right"},right:{reverse:"left"},down:{reverse:"up"},up:{reverse:"down"},top:{reverse:"bottom"},bottom:{reverse:"top"},"in":{reverse:"out"},out:{reverse:"in"}},U={},e.extend(U,{enabled:!0,Element:function(t){this.element=e(t)},promise:function(e,t){e.is(":visible")||e.css({display:e.data("olddisplay")||"block"}).css("display"),t.hide&&e.data("olddisplay",e.css("display")).hide(),t.init&&t.init(),t.completeCallback&&t.completeCallback(e),e.dequeue()},disable:function(){this.enabled=!1,this.promise=this.promiseShim},enable:function(){this.enabled=!0,this.promise=this.animatedPromise}}),U.promiseShim=U.promise,"kendoAnimate"in e.fn||ye(e.fn,{kendoStop:function(e,t){return this.stop(e,t)},kendoAnimate:function(e,t,n,i){return k(this,e,t,n,i)},kendoAddClass:function(e,t){return ve.toggleClass(this,e,t,!0)},kendoRemoveClass:function(e,t){return ve.toggleClass(this,e,t,!1)},kendoToggleClass:function(e,t,n){return ve.toggleClass(this,e,t,n)}}),j=/&/g,q=/</g,Y=/"/g,J=/'/g,G=/>/g,Q=function(e){return e.target},Te.touch&&(Q=function(e){var t="originalEvent"in e?e.originalEvent.changedTouches:"changedTouches"in e?e.changedTouches:null;return t?document.elementFromPoint(t[0].clientX,t[0].clientY):e.target},be(["swipe","swipeLeft","swipeRight","swipeUp","swipeDown","doubleTap","tap"],function(t,n){e.fn[n]=function(e){return this.bind(n,e)}})),Te.touch?Te.mobileOS?(Te.mousedown="touchstart",Te.mouseup="touchend",Te.mousemove="touchmove",Te.mousecancel="touchcancel",Te.click="touchend",Te.resize="orientationchange"):(Te.mousedown="mousedown touchstart",Te.mouseup="mouseup touchend",Te.mousemove="mousemove touchmove",Te.mousecancel="mouseleave touchcancel",Te.click="click",Te.resize="resize"):Te.pointers?(Te.mousemove="pointermove",Te.mousedown="pointerdown",Te.mouseup="pointerup",Te.mousecancel="pointercancel",Te.click="pointerup",Te.resize="orientationchange resize"):Te.msPointers?(Te.mousemove="MSPointerMove",Te.mousedown="MSPointerDown",Te.mouseup="MSPointerUp",Te.mousecancel="MSPointerCancel",Te.click="MSPointerUp",Te.resize="orientationchange resize"):(Te.mousemove="mousemove",Te.mousedown="mousedown",Te.mouseup="mouseup",Te.mousecancel="mouseleave",Te.click="click",Te.resize="resize"),X=function(e,t){var n,i,r,o,a=t||"d",s=1;for(i=0,r=e.length;i<r;i++)o=e[i],""!==o&&(n=o.indexOf("["),0!==n&&(n==-1?o="."+o:(s++,o="."+o.substring(0,n)+" || {})"+o.substring(n))),s++,a+=o+(i<r-1?" || {})":")"));return Array(s).join("(")+a},Z=/^([a-z]+:)?\/\//i,ye(ve,{widgets:[],_widgetRegisteredCallbacks:[],ui:ve.ui||{},fx:ve.fx||b,effects:ve.effects||U,mobile:ve.mobile||{},data:ve.data||{},dataviz:ve.dataviz||{},drawing:ve.drawing||{},spreadsheet:{messages:{}},keys:{INSERT:45,DELETE:46,BACKSPACE:8,TAB:9,ENTER:13,ESC:27,LEFT:37,UP:38,RIGHT:39,DOWN:40,END:35,HOME:36,SPACEBAR:32,PAGEUP:33,PAGEDOWN:34,F2:113,F10:121,F12:123,NUMPAD_PLUS:107,NUMPAD_MINUS:109,NUMPAD_DOT:110},support:ve.support||Te,animate:ve.animate||k,ns:"",attr:function(e){return"data-"+ve.ns+e},getShadows:a,wrap:s,deepExtend:l,getComputedStyles:p,webComponents:ve.webComponents||[],isScrollable:h,scrollLeft:m,size:g,toCamelCase:f,toHyphens:d,getOffset:ve.getOffset||v,parseEffects:ve.parseEffects||y,toggleClass:ve.toggleClass||_,directions:ve.directions||B,Observable:H,Class:i,Template:P,template:ke(P.compile,P),render:ke(P.render,P),stringify:ke(Me.stringify,Me),eventTarget:Q,htmlEncode:x,isLocalUrl:function(e){return e&&!Z.test(e)},expr:function(e,t,n){return e=e||"",typeof t==Pe&&(n=t,t=!1),n=n||"d",e&&"["!==e.charAt(0)&&(e="."+e),t?(e=e.replace(/"([^.]*)\.([^"]*)"/g,'"$1_$DOT$_$2"'),e=e.replace(/'([^.]*)\.([^']*)'/g,"'$1_$DOT$_$2'"),e=X(e.split("."),n),e=e.replace(/_\$DOT\$_/g,".")):e=n+e,e},getter:function(e,t){var n=e+t;return Le[n]=Le[n]||Function("d","return "+ve.expr(e,t))},setter:function(e){return Ie[e]=Ie[e]||Function("d,value",ve.expr(e)+"=value")},accessor:function(e){return{get:ve.getter(e),set:ve.setter(e)}},guid:function(){var e,t,n="";for(e=0;e<32;e++)t=16*xe.random()|0,8!=e&&12!=e&&16!=e&&20!=e||(n+="-"),n+=(12==e?4:16==e?3&t|8:t).toString(16);return n},roleSelector:function(e){return e.replace(/(\S+)/g,"["+ve.attr("role")+"=$1],").slice(0,-1)},directiveSelector:function(e){var t,n=e.split(" ");if(n)for(t=0;t<n.length;t++)"view"!=n[t]&&(n[t]=n[t].replace(/(\w*)(view|bar|strip|over)$/,"$1-$2"));return n.join(" ").replace(/(\S+)/g,"kendo-mobile-$1,").slice(0,-1)},triggeredByInput:function(e){return/^(label|input|textarea|select)$/i.test(e.target.tagName)},onWidgetRegistered:function(e){for(var t=0,n=ve.widgets.length;t<n;t++)e(ve.widgets[t]);ve._widgetRegisteredCallbacks.push(e)},logToConsole:function(e,i){var r=t.console;!ve.suppressLog&&n!==r&&r.log&&r[i||"log"](e)}}),K=H.extend({init:function(e,t){var n,i=this;i.element=ve.jQuery(e).handler(i),i.angular("init",t),
+H.fn.init.call(i),n=t?t.dataSource:null,n&&(t=ye({},t,{dataSource:{}})),t=i.options=ye(!0,{},i.options,t),n&&(t.dataSource=n),i.element.attr(ve.attr("role"))||i.element.attr(ve.attr("role"),(t.name||"").toLowerCase()),i.element.data("kendo"+t.prefix+t.name,i),i.bind(i.events,t)},events:[],options:{prefix:""},_hasBindingTarget:function(){return!!this.element[0].kendoBindingTarget},_tabindex:function(e){e=e||this.wrapper;var t=this.element,n="tabindex",i=e.attr(n)||t.attr(n);t.removeAttr(n),e.attr(n,isNaN(i)?0:i)},setOptions:function(t){this._setEvents(t),e.extend(this.options,t)},_setEvents:function(e){for(var t,n=this,i=0,r=n.events.length;i<r;i++)t=n.events[i],n.options[t]&&e[t]&&n.unbind(t,n.options[t]);n.bind(n.events,e)},resize:function(e){var t=this.getSize(),n=this._size;(e||(t.width>0||t.height>0)&&(!n||t.width!==n.width||t.height!==n.height))&&(this._size=t,this._resize(t,e),this.trigger("resize",t))},getSize:function(){return ve.dimensions(this.element)},size:function(e){return e?(this.setSize(e),n):this.getSize()},setSize:e.noop,_resize:e.noop,destroy:function(){var e=this;e.element.removeData("kendo"+e.options.prefix+e.options.name),e.element.removeData("handler"),e.unbind()},_destroy:function(){this.destroy()},angular:function(){},_muteAngularRebind:function(e){this._muteRebind=!0,e.call(this),this._muteRebind=!1}}),ee=K.extend({dataItems:function(){return this.dataSource.flatView()},_angularItems:function(t){var n=this;n.angular(t,function(){return{elements:n.items(),data:e.map(n.dataItems(),function(e){return{dataItem:e}})}})}}),ve.dimensions=function(e,t){var n=e[0];return t&&e.css(t),{width:n.offsetWidth,height:n.offsetHeight}},ve.notify=_e,te=/template$/i,ne=/^\s*(?:\{(?:.|\r\n|\n)*\}|\[(?:.|\r\n|\n)*\])\s*$/,ie=/^\{(\d+)(:[^\}]+)?\}|^\[[A-Za-z_]+\]$/,re=/([A-Z])/g,ve.initWidget=function(i,r,o){var a,s,l,u,c,d,f,p,h,m,g,v,y;if(o?o.roles&&(o=o.roles):o=ve.ui.roles,i=i.nodeType?i:i[0],d=i.getAttribute("data-"+ve.ns+"role")){h=d.indexOf(".")===-1,l=h?o[d]:ve.getter(d)(t),g=e(i).data(),v=l?"kendo"+l.fn.options.prefix+l.fn.options.name:"",m=h?RegExp("^kendo.*"+d+"$","i"):RegExp("^"+v+"$","i");for(y in g)if(y.match(m)){if(y!==v)return g[y];a=g[y]}if(l){for(p=M(i,"dataSource"),r=e.extend({},T(i,l.fn.options),r),p&&(r.dataSource=typeof p===Pe?ve.getter(p)(t):p),u=0,c=l.fn.events.length;u<c;u++)s=l.fn.events[u],f=M(i,s),f!==n&&(r[s]=ve.getter(f)(t));return a?e.isEmptyObject(r)||a.setOptions(r):a=new l(i,r),a}}},ve.rolesFromNamespaces=function(e){var t,n,i=[];for(e[0]||(e=[ve.ui,ve.dataviz.ui]),t=0,n=e.length;t<n;t++)i[t]=e[t].roles;return ye.apply(null,[{}].concat(i.reverse()))},ve.init=function(t){var n=ve.rolesFromNamespaces(Fe.call(arguments,1));e(t).find("[data-"+ve.ns+"role]").addBack().each(function(){ve.initWidget(this,{},n)})},ve.destroy=function(t){e(t).find("[data-"+ve.ns+"role]").addBack().each(function(){var t,n=e(this).data();for(t in n)0===t.indexOf("kendo")&&typeof n[t].destroy===Ce&&n[t].destroy()})},ve.resize=function(t,n){var i,r=e(t).find("[data-"+ve.ns+"role]").addBack().filter(E);r.length&&(i=e.makeArray(r),i.sort(S),e.each(i,function(){var t=ve.widgetInstance(e(this));t&&t.resize(n)}))},ve.parseOptions=T,ye(ve.ui,{Widget:K,DataBoundWidget:ee,roles:{},progress:function(t,n){var i,r,o,a,s=t.find(".k-loading-mask"),l=ve.support,u=l.browser;n?s.length||(i=l.isRtl(t),r=i?"right":"left",a=t.scrollLeft(),o=u.webkit&&i?t[0].scrollWidth-t.width()-2*a:0,s=e("<div class='k-loading-mask'><span class='k-loading-text'>"+ve.ui.progress.messages.loading+"</span><div class='k-loading-image'/><div class='k-loading-color'/></div>").width("100%").height("100%").css("top",t.scrollTop()).css(r,Math.abs(a)+o).prependTo(t)):s&&s.remove()},plugin:function(t,i,r){var o,a,s,l,u=t.fn.options.name;for(i=i||ve.ui,r=r||"",i[u]=t,i.roles[u.toLowerCase()]=t,o="getKendo"+r+u,u="kendo"+r+u,a={name:u,widget:t,prefix:r||""},ve.widgets.push(a),s=0,l=ve._widgetRegisteredCallbacks.length;s<l;s++)ve._widgetRegisteredCallbacks[s](a);e.fn[u]=function(i){var r,o=this;return typeof i===Pe?(r=Fe.call(arguments,1),this.each(function(){var t,a,s=e.data(this,u);if(!s)throw Error(ve.format("Cannot call method '{0}' of {1} before it is initialized",i,u));if(t=s[i],typeof t!==Ce)throw Error(ve.format("Cannot find method '{0}' of {1}",i,u));if(a=t.apply(s,r),a!==n)return o=a,!1})):this.each(function(){return new t(this,i)}),o},e.fn[u].widget=t,e.fn[o]=function(){return this.data(u)}}}),ve.ui.progress.messages={loading:"Loading..."},oe={bind:function(){return this},nullObject:!0,options:{}},ae=K.extend({init:function(e,t){K.fn.init.call(this,e,t),this.element.autoApplyNS(),this.wrapper=this.element,this.element.addClass("km-widget")},destroy:function(){K.fn.destroy.call(this),this.element.kendoDestroy()},options:{prefix:"Mobile"},events:[],view:function(){var e=this.element.closest(ve.roleSelector("view splitview modalview drawer"));return ve.widgetInstance(e,ve.mobile.ui)||oe},viewHasNativeScrolling:function(){var e=this.view();return e&&e.options.useNativeScrolling},container:function(){var e=this.element.closest(ve.roleSelector("view layout modalview drawer splitview"));return ve.widgetInstance(e.eq(0),ve.mobile.ui)||oe}}),ye(ve.mobile,{init:function(e){ve.init(e,ve.mobile.ui,ve.ui,ve.dataviz.ui)},appLevelNativeScrolling:function(){return ve.mobile.application&&ve.mobile.application.options&&ve.mobile.application.options.useNativeScrolling},roles:{},ui:{Widget:ae,DataBoundWidget:ee.extend(ae.prototype),roles:{},plugin:function(e){ve.ui.plugin(e,ve.mobile.ui,"Mobile")}}}),l(ve.dataviz,{init:function(e){ve.init(e,ve.dataviz.ui)},ui:{roles:{},themes:{},views:[],plugin:function(e){ve.ui.plugin(e,ve.dataviz.ui)}},roles:{}}),ve.touchScroller=function(t,n){return n||(n={}),n.useNative=!0,e(t).map(function(t,i){return i=e(i),!(!Te.kineticScrollNeeded||!ve.mobile.ui.Scroller||i.data("kendoMobileScroller"))&&(i.kendoMobileScroller(n),i.data("kendoMobileScroller"))})[0]},ve.preventDefault=function(e){e.preventDefault()},ve.widgetInstance=function(e,n){var i,r,o,a,s=e.data(ve.ns+"role"),l=[];if(s){if("content"===s&&(s="scroller"),n)if(n[0])for(i=0,r=n.length;i<r;i++)l.push(n[i].roles[s]);else l.push(n.roles[s]);else l=[ve.ui.roles[s],ve.dataviz.ui.roles[s],ve.mobile.ui.roles[s]];for(s.indexOf(".")>=0&&(l=[ve.getter(s)(t)]),i=0,r=l.length;i<r;i++)if(o=l[i],o&&(a=e.data("kendo"+o.fn.options.prefix+o.fn.options.name)))return a}},ve.onResize=function(n){var i=n;return Te.mobileOS.android&&(i=function(){setTimeout(n,600)}),e(t).on(Te.resize,i),i},ve.unbindResize=function(n){e(t).off(Te.resize,n)},ve.attrValue=function(e,t){return e.data(ve.ns+t)},ve.days={Sunday:0,Monday:1,Tuesday:2,Wednesday:3,Thursday:4,Friday:5,Saturday:6},e.extend(e.expr[":"],{kendoFocusable:function(t){var n=e.attr(t,"tabindex");return z(t,!isNaN(n)&&n>-1)}}),se=["mousedown","mousemove","mouseenter","mouseleave","mouseover","mouseout","mouseup","click"],le="label, input, [data-rel=external]",ue={setupMouseMute:function(){var t,n=0,i=se.length,r=document.documentElement;if(!ue.mouseTrap&&Te.eventCapture)for(ue.mouseTrap=!0,ue.bustClick=!1,ue.captureMouse=!1,t=function(t){ue.captureMouse&&("click"===t.type?ue.bustClick&&!e(t.target).is(le)&&(t.preventDefault(),t.stopPropagation()):t.stopPropagation())};n<i;n++)r.addEventListener(se[n],t,!0)},muteMouse:function(e){ue.captureMouse=!0,e.data.bustClick&&(ue.bustClick=!0),clearTimeout(ue.mouseTrapTimeoutID)},unMuteMouse:function(){clearTimeout(ue.mouseTrapTimeoutID),ue.mouseTrapTimeoutID=setTimeout(function(){ue.captureMouse=!1,ue.bustClick=!1},400)}},ce={down:"touchstart mousedown",move:"mousemove touchmove",up:"mouseup touchend touchcancel",cancel:"mouseleave touchcancel"},Te.touch&&(Te.mobileOS.ios||Te.mobileOS.android)?ce={down:"touchstart",move:"touchmove",up:"touchend touchcancel",cancel:"touchcancel"}:Te.pointers?ce={down:"pointerdown",move:"pointermove",up:"pointerup",cancel:"pointercancel pointerleave"}:Te.msPointers&&(ce={down:"MSPointerDown",move:"MSPointerMove",up:"MSPointerUp",cancel:"MSPointerCancel MSPointerLeave"}),!Te.msPointers||"onmspointerenter"in t||e.each({MSPointerEnter:"MSPointerOver",MSPointerLeave:"MSPointerOut"},function(t,n){e.event.special[t]={delegateType:n,bindType:n,handle:function(t){var i,r=this,o=t.relatedTarget,a=t.handleObj;return o&&(o===r||e.contains(r,o))||(t.type=a.origType,i=a.handler.apply(this,arguments),t.type=n),i}}}),de=function(e){return ce[e]||e},fe=/([^ ]+)/g,ve.applyEventMap=function(e,t){return e=e.replace(fe,de),t&&(e=e.replace(fe,"$1."+t)),e},pe=e.fn.on,ye(!0,C,e),C.fn=C.prototype=new e,C.fn.constructor=C,C.fn.init=function(t,n){return n&&n instanceof e&&!(n instanceof C)&&(n=C(n)),e.fn.init.call(this,t,n,he)},C.fn.init.prototype=C.fn,he=C(document),ye(C.fn,{handler:function(e){return this.data("handler",e),this},autoApplyNS:function(e){return this.data("kendoNS",e||ve.guid()),this},on:function(){var e,t,n,i,r,o,a=this,s=a.data("kendoNS");return 1===arguments.length?pe.call(a,arguments[0]):(e=a,t=Fe.call(arguments),typeof t[t.length-1]===Ne&&t.pop(),n=t[t.length-1],i=ve.applyEventMap(t[0],s),Te.mouseAndTouchPresent&&i.search(/mouse|click/)>-1&&this[0]!==document.documentElement&&(ue.setupMouseMute(),r=2===t.length?null:t[1],o=i.indexOf("click")>-1&&i.indexOf("touchend")>-1,pe.call(this,{touchstart:ue.muteMouse,touchend:ue.unMuteMouse},r,{bustClick:o})),typeof n===Pe&&(e=a.data("handler"),n=e[n],t[t.length-1]=function(t){n.call(e,t)}),t[0]=i,pe.apply(a,t),a)},kendoDestroy:function(e){return e=e||this.data("kendoNS"),e&&this.off("."+e),this}}),ve.jQuery=C,ve.eventMap=ce,ve.timezone=function(){function e(e,t){var n,i,r,o=t[3],a=t[4],s=t[5],l=t[8];return l||(t[8]=l={}),l[e]?l[e]:(isNaN(a)?0===a.indexOf("last")?(n=new Date(Date.UTC(e,c[o]+1,1,s[0]-24,s[1],s[2],0)),i=d[a.substr(4,3)],r=n.getUTCDay(),n.setUTCDate(n.getUTCDate()+i-r-(i>r?7:0))):a.indexOf(">=")>=0&&(n=new Date(Date.UTC(e,c[o],a.substr(5),s[0],s[1],s[2],0)),i=d[a.substr(0,3)],r=n.getUTCDay(),n.setUTCDate(n.getUTCDate()+i-r+(i<r?7:0))):n=new Date(Date.UTC(e,c[o],a,s[0],s[1],s[2],0)),l[e]=n)}function t(t,n,i){var r,o,a,s;return(n=n[i])?(a=new Date(t).getUTCFullYear(),n=jQuery.grep(n,function(e){var t=e[0],n=e[1];return t<=a&&(n>=a||t==a&&"only"==n||"max"==n)}),n.push(t),n.sort(function(t,n){return"number"!=typeof t&&(t=+e(a,t)),"number"!=typeof n&&(n=+e(a,n)),t-n}),s=n[jQuery.inArray(t,n)-1]||n[n.length-1],isNaN(s)?s:null):(r=i.split(":"),o=0,r.length>1&&(o=60*r[0]+ +r[1]),[-1e6,"max","-","Jan",1,[0,0,0],o,"-"])}function n(e,t,n){var i,r,o,a=t[n];if("string"==typeof a&&(a=t[a]),!a)throw Error('Timezone "'+n+'" is either incorrect, or kendo.timezones.min.js is not included.');for(i=a.length-1;i>=0&&(r=a[i][3],!(r&&e>r));i--);if(o=a[i+1],!o)throw Error('Timezone "'+n+'" not found on '+e+".");return o}function i(e,i,r,o){typeof e!=Oe&&(e=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()));var a=n(e,i,o);return{zone:a,rule:t(e,r,a[1])}}function r(e,t){var n,r,o;return"Etc/UTC"==t||"Etc/GMT"==t?0:(n=i(e,this.zones,this.rules,t),r=n.zone,o=n.rule,ve.parseFloat(o?r[0]-o[6]:r[0]))}function o(e,t){var n=i(e,this.zones,this.rules,t),r=n.zone,o=n.rule,a=r[2];return a.indexOf("/")>=0?a.split("/")[o&&+o[6]?1:0]:a.indexOf("%s")>=0?a.replace("%s",o&&"-"!=o[7]?o[7]:""):a}function a(e,t,n){var i,r;return typeof t==Pe&&(t=this.offset(e,t)),typeof n==Pe&&(n=this.offset(e,n)),i=e.getTimezoneOffset(),e=new Date(e.getTime()+6e4*(t-n)),r=e.getTimezoneOffset(),new Date(e.getTime()+6e4*(r-i))}function s(e,t){return this.convert(e,e.getTimezoneOffset(),t)}function l(e,t){return this.convert(e,t,e.getTimezoneOffset())}function u(e){return this.apply(new Date(e),"Etc/UTC")}var c={Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11},d={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};return{zones:{},rules:{},offset:r,convert:a,apply:s,remove:l,abbr:o,toLocalDate:u}}(),ve.date=function(){function e(e,t){return 0===t&&23===e.getHours()&&(e.setHours(e.getHours()+2),!0)}function t(t,n,i){var r=t.getHours();i=i||1,n=(n-t.getDay()+7*i)%7,t.setDate(t.getDate()+n),e(t,r)}function n(e,n,i){return e=new Date(e),t(e,n,i),e}function i(e){return new Date(e.getFullYear(),e.getMonth(),1)}function r(e){var t=new Date(e.getFullYear(),e.getMonth()+1,0),n=i(e),r=Math.abs(t.getTimezoneOffset()-n.getTimezoneOffset());return r&&t.setHours(n.getHours()+r/60),t}function o(e,t){return 1!==t?p(n(e,t,-1),4):p(e,4-(e.getDay()||7))}function a(e,t){var n=new Date(e.getFullYear(),0,1,(-6)),i=o(e,t),r=i.getTime()-n.getTime(),a=Math.floor(r/w);return 1+Math.floor(a/7)}function s(e,t){var n=p(e,-7),i=p(e,7),r=a(e,t);return 0===r?a(n,t)+1:53===r&&a(i,t)>1?1:r}function l(t){return t=new Date(t.getFullYear(),t.getMonth(),t.getDate(),0,0,0),e(t,0),t}function u(e){return Date.UTC(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())}function c(e){return e.getTime()-l(e)}function d(e,t,n){var i,r=c(t),o=c(n);return!e||r==o||(t>=n&&(n+=w),i=c(e),r>i&&(i+=w),o<r&&(o+=w),i>=r&&i<=o)}function f(e,t,n){var i,r=t.getTime(),o=n.getTime();return r>=o&&(o+=w),i=e.getTime(),i>=r&&i<=o}function p(t,n){var i=t.getHours();return t=new Date(t),h(t,n*w),e(t,i),t}function h(e,t,n){var i,r=e.getTimezoneOffset();e.setTime(e.getTime()+t),n||(i=e.getTimezoneOffset()-r,e.setTime(e.getTime()+i*b))}function m(t,n){return t=new Date(ve.date.getDate(t).getTime()+ve.date.getMilliseconds(n)),e(t,n.getHours()),t}function g(){return l(new Date)}function v(e){return l(e).getTime()==g().getTime()}function y(e){var t=new Date(1980,1,1,0,0,0);return e&&t.setHours(e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()),t}var b=6e4,w=864e5;return{adjustDST:e,dayOfWeek:n,setDayOfWeek:t,getDate:l,isInDateRange:f,isInTimeRange:d,isToday:v,nextDay:function(e){return p(e,1)},previousDay:function(e){return p(e,-1)},toUtcTime:u,MS_PER_DAY:w,MS_PER_HOUR:60*b,MS_PER_MINUTE:b,setTime:h,setHours:m,addDays:p,today:g,toInvariantTime:y,firstDayOfMonth:i,lastDayOfMonth:r,weekInYear:s,getMilliseconds:c}}(),ve.stripWhitespace=function(e){var t,n,i;if(document.createNodeIterator)for(t=document.createNodeIterator(e,NodeFilter.SHOW_TEXT,function(t){return t.parentNode==e?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT},!1);t.nextNode();)t.referenceNode&&!t.referenceNode.textContent.trim()&&t.referenceNode.parentNode.removeChild(t.referenceNode);else for(n=0;n<e.childNodes.length;n++)i=e.childNodes[n],3!=i.nodeType||/\S/.test(i.nodeValue)||(e.removeChild(i),n--),1==i.nodeType&&ve.stripWhitespace(i)},me=t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||t.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ve.animationFrame=function(e){me.call(t,e)},ge=[],ve.queueAnimation=function(e){ge[ge.length]=e,1===ge.length&&ve.runNextAnimation()},ve.runNextAnimation=function(){ve.animationFrame(function(){ge[0]&&(ge.shift()(),ge[0]&&ve.runNextAnimation())})},ve.parseQueryStringParams=function(e){for(var t=e.split("?")[1]||"",n={},i=t.split(/&|=/),r=i.length,o=0;o<r;o+=2)""!==i[o]&&(n[decodeURIComponent(i[o])]=decodeURIComponent(i[o+1]));return n},ve.elementUnderCursor=function(e){if(n!==e.x.client)return document.elementFromPoint(e.x.client,e.y.client)},ve.wheelDeltaY=function(e){var t,i=e.originalEvent,r=i.wheelDeltaY;return i.wheelDelta?(r===n||r)&&(t=i.wheelDelta):i.detail&&i.axis===i.VERTICAL_AXIS&&(t=10*-i.detail),t},ve.throttle=function(e,t){var i,r,o=0;return!t||t<=0?e:(r=function(){function r(){e.apply(a,l),o=+new Date}var a=this,s=+new Date-o,l=arguments;return o?(i&&clearTimeout(i),s>t?r():i=setTimeout(r,t-s),n):r()},r.cancel=function(){clearTimeout(i)},r)},ve.caret=function(t,i,r){var o,a,s,l,u,c=i!==n;if(r===n&&(r=i),t[0]&&(t=t[0]),!c||!t.disabled){try{t.selectionStart!==n?c?(t.focus(),a=Te.mobileOS,a.wp||a.android?setTimeout(function(){t.setSelectionRange(i,r)},0):t.setSelectionRange(i,r)):i=[t.selectionStart,t.selectionEnd]:document.selection&&(e(t).is(":visible")&&t.focus(),o=t.createTextRange(),c?(o.collapse(!0),o.moveStart("character",i),o.moveEnd("character",r-i),o.select()):(s=o.duplicate(),o.moveToBookmark(document.selection.createRange().getBookmark()),s.setEndPoint("EndToStart",o),l=s.text.length,u=l+o.text.length,i=[l,u]))}catch(d){i=[]}return i}},ve.compileMobileDirective=function(e,n){var i=t.angular;return e.attr("data-"+ve.ns+"role",e[0].tagName.toLowerCase().replace("kendo-mobile-","").replace("-","")),i.element(e).injector().invoke(["$compile",function(t){t(e)(n),/^\$(digest|apply)$/.test(n.$$phase)||n.$digest()}]),ve.widgetInstance(e,ve.mobile.ui)},ve.antiForgeryTokens=function(){var t={},i=e("meta[name=csrf-token],meta[name=_csrf]").attr("content"),r=e("meta[name=csrf-param],meta[name=_csrf_header]").attr("content");return e("input[name^='__RequestVerificationToken']").each(function(){t[this.name]=this.value}),r!==n&&i!==n&&(t[r]=i),t},ve.cycleForm=function(e){function t(e){var t=ve.widgetInstance(e);t&&t.focus?t.focus():e.focus()}var n=e.find("input, .k-widget").first(),i=e.find("button, .k-button").last();i.on("keydown",function(e){e.keyCode!=ve.keys.TAB||e.shiftKey||(e.preventDefault(),t(n))}),n.on("keydown",function(e){e.keyCode==ve.keys.TAB&&e.shiftKey&&(e.preventDefault(),t(i))})},function(){function n(t,n,i,r){var o,a,s=e("<form>").attr({action:i,method:"POST",target:r}),l=ve.antiForgeryTokens();l.fileName=n,o=t.split(";base64,"),l.contentType=o[0].replace("data:",""),l.base64=o[1];for(a in l)l.hasOwnProperty(a)&&e("<input>").attr({value:l[a],name:a,type:"hidden"}).appendTo(s);s.appendTo("body").submit().remove()}function i(e,t){var n,i,r,o,a,s=e;if("string"==typeof e){for(n=e.split(";base64,"),i=n[0],r=atob(n[1]),o=new Uint8Array(r.length),a=0;a<r.length;a++)o[a]=r.charCodeAt(a);s=new Blob([o.buffer],{type:i})}navigator.msSaveBlob(s,t)}function r(e,n){t.Blob&&e instanceof Blob&&(e=URL.createObjectURL(e)),o.download=n,o.href=e;var i=document.createEvent("MouseEvents");i.initMouseEvent("click",!0,!1,t,0,0,0,0,0,!1,!1,!1,!1,0,null),o.dispatchEvent(i),setTimeout(function(){URL.revokeObjectURL(e)})}var o=document.createElement("a"),a="download"in o&&!ve.support.browser.edge;ve.saveAs=function(e){var t=n;e.forceProxy||(a?t=r:navigator.msSaveBlob&&(t=i)),t(e.dataURI,e.fileName,e.proxyURL,e.proxyTarget)}}(),ve.proxyModelSetters=function(e){var t={};return Object.keys(e||{}).forEach(function(n){Object.defineProperty(t,n,{get:function(){return e[n]},set:function(t){e[n]=t,e.dirty=!0}})}),t}}(jQuery,window),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()}),function(e,define){define("kendo.userevents.min",["kendo.core.min"],e)}(function(){return function(e,t){function n(e,t){var n=e.x.location,i=e.y.location,r=t.x.location,o=t.y.location,a=n-r,s=i-o;return{center:{x:(n+r)/2,y:(i+o)/2},distance:Math.sqrt(a*a+s*s)}}function i(e){var t,n,i,r=[],o=e.originalEvent,s=e.currentTarget,l=0;if(e.api)r.push({id:2,event:e,target:e.target,currentTarget:e.target,location:e,type:"api"});else if(e.type.match(/touch/))for(n=o?o.changedTouches:[],t=n.length;l<t;l++)i=n[l],r.push({location:i,event:e,target:i.target,currentTarget:s,id:i.identifier,type:"touch"});else r.push(a.pointers||a.msPointers?{location:o,event:e,target:e.target,currentTarget:s,id:o.pointerId,type:"pointer"}:{id:1,event:e,target:e.target,currentTarget:s,location:e,type:"mouse"});return r}function r(e){for(var t=o.eventMap.up.split(" "),n=0,i=t.length;n<i;n++)e(t[n])}var o=window.kendo,a=o.support,s=o.Class,l=o.Observable,u=e.now,c=e.extend,d=a.mobileOS,f=d&&d.android,p=800,h=a.browser.msie?5:0,m="press",g="hold",v="select",y="start",b="move",w="end",k="cancel",_="tap",x="release",M="gesturestart",T="gesturechange",S="gestureend",E="gesturetap",z={api:0,touch:0,mouse:9,pointer:9},D=!a.touch||a.mouseAndTouchPresent,C=s.extend({init:function(e,t){var n=this;n.axis=e,n._updateLocationData(t),n.startLocation=n.location,n.velocity=n.delta=0,n.timeStamp=u()},move:function(e){var t=this,n=e["page"+t.axis],i=u(),r=i-t.timeStamp||1;!n&&f||(t.delta=n-t.location,t._updateLocationData(e),t.initialDelta=n-t.startLocation,t.velocity=t.delta/r,t.timeStamp=i)},_updateLocationData:function(e){var t=this,n=t.axis;t.location=e["page"+n],t.client=e["client"+n],t.screen=e["screen"+n]}}),P=s.extend({init:function(e,t,n){c(this,{x:new C("X",n.location),y:new C("Y",n.location),type:n.type,useClickAsTap:e.useClickAsTap,threshold:e.threshold||z[n.type],userEvents:e,target:t,currentTarget:n.currentTarget,initialTouch:n.target,id:n.id,pressEvent:n,_moved:!1,_finished:!1})},press:function(){this._holdTimeout=setTimeout(e.proxy(this,"_hold"),this.userEvents.minHold),this._trigger(m,this.pressEvent)},_hold:function(){this._trigger(g,this.pressEvent)},move:function(e){var t=this;if(!t._finished){if(t.x.move(e.location),t.y.move(e.location),!t._moved){if(t._withinIgnoreThreshold())return;if(O.current&&O.current!==t.userEvents)return t.dispose();t._start(e)}t._finished||t._trigger(b,e)}},end:function(e){this.endTime=u(),this._finished||(this._finished=!0,this._trigger(x,e),this._moved?this._trigger(w,e):this.useClickAsTap||this._trigger(_,e),clearTimeout(this._holdTimeout),this.dispose())},dispose:function(){var t=this.userEvents,n=t.touches;this._finished=!0,this.pressEvent=null,clearTimeout(this._holdTimeout),n.splice(e.inArray(this,n),1)},skip:function(){this.dispose()},cancel:function(){this.dispose()},isMoved:function(){return this._moved},_start:function(e){clearTimeout(this._holdTimeout),this.startTime=u(),this._moved=!0,this._trigger(y,e)},_trigger:function(e,t){var n=this,i=t.event,r={touch:n,x:n.x,y:n.y,target:n.target,event:i};n.userEvents.notify(e,r)&&i.preventDefault()},_withinIgnoreThreshold:function(){var e=this.x.initialDelta,t=this.y.initialDelta;return Math.sqrt(e*e+t*t)<=this.threshold}}),O=l.extend({init:function(t,n){var i,s,u,d=this,f=o.guid();n=n||{},i=d.filter=n.filter,d.threshold=n.threshold||h,d.minHold=n.minHold||p,d.touches=[],d._maxTouches=n.multiTouch?2:1,d.allowSelection=n.allowSelection,d.captureUpIfMoved=n.captureUpIfMoved,d.useClickAsTap=!n.fastTap&&!a.delayedClick(),d.eventNS=f,t=e(t).handler(d),l.fn.init.call(d),c(d,{element:t,surface:e(n.global&&D?t[0].ownerDocument.documentElement:n.surface||t),stopPropagation:n.stopPropagation,pressed:!1}),d.surface.handler(d).on(o.applyEventMap("move",f),"_move").on(o.applyEventMap("up cancel",f),"_end"),t.on(o.applyEventMap("down",f),i,"_start"),d.useClickAsTap&&t.on(o.applyEventMap("click",f),i,"_click"),(a.pointers||a.msPointers)&&(a.browser.version<11?t.css("-ms-touch-action","pinch-zoom double-tap-zoom"):t.css("touch-action",n.touchAction||"none")),n.preventDragEvent&&t.on(o.applyEventMap("dragstart",f),o.preventDefault),t.on(o.applyEventMap("mousedown",f),i,{root:t},"_select"),d.captureUpIfMoved&&a.eventCapture&&(s=d.surface[0],u=e.proxy(d.preventIfMoving,d),r(function(e){s.addEventListener(e,u,!0)})),d.bind([m,g,_,y,b,w,x,k,M,T,S,E,v],n)},preventIfMoving:function(e){this._isMoved()&&e.preventDefault()},destroy:function(){var e,t=this;t._destroyed||(t._destroyed=!0,t.captureUpIfMoved&&a.eventCapture&&(e=t.surface[0],r(function(n){e.removeEventListener(n,t.preventIfMoving)})),t.element.kendoDestroy(t.eventNS),t.surface.kendoDestroy(t.eventNS),t.element.removeData("handler"),t.surface.removeData("handler"),t._disposeAll(),t.unbind(),delete t.surface,delete t.element,delete t.currentTarget)},capture:function(){O.current=this},cancel:function(){this._disposeAll(),this.trigger(k)},notify:function(e,t){var i=this,r=i.touches;if(this._isMultiTouch()){switch(e){case b:e=T;break;case w:e=S;break;case _:e=E}c(t,{touches:r},n(r[0],r[1]))}return this.trigger(e,c(t,{type:e}))},press:function(e,t,n){this._apiCall("_start",e,t,n)},move:function(e,t){this._apiCall("_move",e,t)},end:function(e,t){this._apiCall("_end",e,t)},_isMultiTouch:function(){return this.touches.length>1},_maxTouchesReached:function(){return this.touches.length>=this._maxTouches},_disposeAll:function(){for(var e=this.touches;e.length>0;)e.pop().dispose()},_isMoved:function(){return e.grep(this.touches,function(e){return e.isMoved()}).length},_select:function(e){this.allowSelection&&!this.trigger(v,{event:e})||e.preventDefault()},_start:function(t){var n,r,o=this,a=0,s=o.filter,l=i(t),u=l.length,c=t.which;if(!(c&&c>1||o._maxTouchesReached()))for(O.current=null,o.currentTarget=t.currentTarget,o.stopPropagation&&t.stopPropagation();a<u&&!o._maxTouchesReached();a++)r=l[a],n=s?e(r.currentTarget):o.element,n.length&&(r=new P(o,n,r),o.touches.push(r),r.press(),o._isMultiTouch()&&o.notify("gesturestart",{}))},_move:function(e){this._eachTouch("move",e)},_end:function(e){this._eachTouch("end",e)},_click:function(t){var n={touch:{initialTouch:t.target,target:e(t.currentTarget),endTime:u(),x:{location:t.pageX,client:t.clientX},y:{location:t.pageY,client:t.clientY}},x:t.pageX,y:t.pageY,target:e(t.currentTarget),event:t,type:"tap"};this.trigger("tap",n)&&t.preventDefault()},_eachTouch:function(e,t){var n,r,o,a,s=this,l={},u=i(t),c=s.touches;for(n=0;n<c.length;n++)r=c[n],l[r.id]=r;for(n=0;n<u.length;n++)o=u[n],a=l[o.id],a&&a[e](o)},_apiCall:function(t,n,i,r){this[t]({api:!0,pageX:n,pageY:i,clientX:n,clientY:i,target:e(r||this.element)[0],stopPropagation:e.noop,preventDefault:e.noop})}});O.defaultThreshold=function(e){h=e},O.minHold=function(e){p=e},o.getTouches=i,o.touchDelta=n,o.UserEvents=O}(window.kendo.jQuery),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()}),function(e,define){define("kendo.draganddrop.min",["kendo.core.min","kendo.userevents.min"],e)}(function(){return function(e,t){function n(t,n){try{return e.contains(t,n)||t==n}catch(i){return!1}}function i(e,t){return parseInt(e.css(t),10)||0}function r(e,t){return Math.min(Math.max(e,t.min),t.max)}function o(e,t){var n=z(e),r=y._outerWidth,o=y._outerHeight,a=n.left+i(e,"borderLeftWidth")+i(e,"paddingLeft"),s=n.top+i(e,"borderTopWidth")+i(e,"paddingTop"),l=a+e.width()-r(t,!0),u=s+e.height()-o(t,!0);return{x:{min:a,max:l},y:{min:s,max:u}}}function a(n,i,r){for(var o,a,s=0,l=i&&i.length,u=r&&r.length;n&&n.parentNode;){for(s=0;s<l;s++)if(o=i[s],o.element[0]===n)return{target:o,targetElement:n};for(s=0;s<u;s++)if(a=r[s],e.contains(a.element[0],n)&&b.matchesSelector.call(n,a.options.filter))return{target:a,targetElement:n};n=n.parentNode}return t}function s(e,t){var n,i=t.options.group,r=e[i];if(x.fn.destroy.call(t),r.length>1){for(n=0;n<r.length;n++)if(r[n]==t){r.splice(n,1);break}}else r.length=0,delete e[i]}function l(e){var t,n,i,r=u()[0];return e[0]===r?(n=r.scrollTop,i=r.scrollLeft,{top:n,left:i,bottom:n+k.height(),right:i+k.width()}):(t=e.offset(),t.bottom=t.top+e.height(),t.right=t.left+e.width(),t)}function u(){return e(y.support.browser.chrome?w.body:w.documentElement)}function c(t){var n,i=u();if(!t||t===w.body||t===w.documentElement)return i;for(n=e(t)[0];n&&!y.isScrollable(n)&&n!==w.body;)n=n.parentNode;return n===w.body?i:e(n)}function d(e,t,n){var i={x:0,y:0},r=50;return e-n.left<r?i.x=-(r-(e-n.left)):n.right-e<r&&(i.x=r-(n.right-e)),t-n.top<r?i.y=-(r-(t-n.top)):n.bottom-t<r&&(i.y=r-(n.bottom-t)),i}var f,p,h,m,g,v,y=window.kendo,b=y.support,w=window.document,k=e(window),_=y.Class,x=y.ui.Widget,M=y.Observable,T=y.UserEvents,S=e.proxy,E=e.extend,z=y.getOffset,D={},C={},P={},O=y.elementUnderCursor,$="keyup",A="change",H="dragstart",N="hold",L="drag",I="dragend",F="dragcancel",V="hintDestroyed",R="dragenter",W="dragleave",B="drop",U=M.extend({init:function(t,n){var i=this,r=t[0];i.capture=!1,r.addEventListener?(e.each(y.eventMap.down.split(" "),function(){r.addEventListener(this,S(i._press,i),!0)}),e.each(y.eventMap.up.split(" "),function(){r.addEventListener(this,S(i._release,i),!0)})):(e.each(y.eventMap.down.split(" "),function(){r.attachEvent(this,S(i._press,i))}),e.each(y.eventMap.up.split(" "),function(){r.attachEvent(this,S(i._release,i))})),M.fn.init.call(i),i.bind(["press","release"],n||{})},captureNext:function(){this.capture=!0},cancelCapture:function(){this.capture=!1},_press:function(e){var t=this;t.trigger("press"),t.capture&&e.preventDefault()},_release:function(e){var t=this;t.trigger("release"),t.capture&&(e.preventDefault(),t.cancelCapture())}}),j=M.extend({init:function(t){var n=this;M.fn.init.call(n),n.forcedEnabled=!1,e.extend(n,t),n.scale=1,n.horizontal?(n.measure="offsetWidth",n.scrollSize="scrollWidth",n.axis="x"):(n.measure="offsetHeight",n.scrollSize="scrollHeight",n.axis="y")},makeVirtual:function(){e.extend(this,{virtual:!0,forcedEnabled:!0,_virtualMin:0,_virtualMax:0})},virtualSize:function(e,t){this._virtualMin===e&&this._virtualMax===t||(this._virtualMin=e,this._virtualMax=t,this.update())},outOfBounds:function(e){return e>this.max||e<this.min},forceEnabled:function(){this.forcedEnabled=!0},getSize:function(){return this.container[0][this.measure]},getTotal:function(){return this.element[0][this.scrollSize]},rescale:function(e){this.scale=e},update:function(e){var t=this,n=t.virtual?t._virtualMax:t.getTotal(),i=n*t.scale,r=t.getSize();(0!==n||t.forcedEnabled)&&(t.max=t.virtual?-t._virtualMin:0,t.size=r,t.total=i,t.min=Math.min(t.max,r-i),t.minScale=r/n,t.centerOffset=(i-r)/2,t.enabled=t.forcedEnabled||i>r,e||t.trigger(A,t))}}),q=M.extend({init:function(e){var t=this;M.fn.init.call(t),t.x=new j(E({horizontal:!0},e)),t.y=new j(E({horizontal:!1},e)),t.container=e.container,t.forcedMinScale=e.minScale,t.maxScale=e.maxScale||100,t.bind(A,e)},rescale:function(e){this.x.rescale(e),this.y.rescale(e),this.refresh()},centerCoordinates:function(){return{x:Math.min(0,-this.x.centerOffset),y:Math.min(0,-this.y.centerOffset)}},refresh:function(){var e=this;e.x.update(),e.y.update(),e.enabled=e.x.enabled||e.y.enabled,e.minScale=e.forcedMinScale||Math.min(e.x.minScale,e.y.minScale),e.fitScale=Math.max(e.x.minScale,e.y.minScale),e.trigger(A)}}),Y=M.extend({init:function(e){var t=this;E(t,e),M.fn.init.call(t)},outOfBounds:function(){return this.dimension.outOfBounds(this.movable[this.axis])},dragMove:function(e){var t=this,n=t.dimension,i=t.axis,r=t.movable,o=r[i]+e;n.enabled&&((o<n.min&&e<0||o>n.max&&e>0)&&(e*=t.resistance),r.translateAxis(i,e),t.trigger(A,t))}}),J=_.extend({init:function(t){var n,i,r,o,a=this;E(a,{elastic:!0},t),r=a.elastic?.5:0,o=a.movable,a.x=n=new Y({axis:"x",dimension:a.dimensions.x,resistance:r,movable:o}),a.y=i=new Y({axis:"y",dimension:a.dimensions.y,resistance:r,movable:o}),a.userEvents.bind(["press","move","end","gesturestart","gesturechange"],{gesturestart:function(e){a.gesture=e,a.offset=a.dimensions.container.offset()},press:function(t){e(t.event.target).closest("a").is("[data-navigate-on-press=true]")&&t.sender.cancel()},gesturechange:function(e){var t,r,s,l=a.gesture,u=l.center,c=e.center,d=e.distance/l.distance,f=a.dimensions.minScale,p=a.dimensions.maxScale;o.scale<=f&&d<1&&(d+=.8*(1-d)),o.scale*d>=p&&(d=p/o.scale),r=o.x+a.offset.left,s=o.y+a.offset.top,t={x:(r-u.x)*d+c.x-r,y:(s-u.y)*d+c.y-s},o.scaleWith(d),n.dragMove(t.x),i.dragMove(t.y),a.dimensions.rescale(o.scale),a.gesture=e,e.preventDefault()},move:function(e){e.event.target.tagName.match(/textarea|input/i)||(n.dimension.enabled||i.dimension.enabled?(n.dragMove(e.x.delta),i.dragMove(e.y.delta),e.preventDefault()):e.touch.skip())},end:function(e){e.preventDefault()}})}}),G=b.transitions.prefix+"Transform";p=b.hasHW3D?function(e,t,n){return"translate3d("+e+"px,"+t+"px,0) scale("+n+")"}:function(e,t,n){return"translate("+e+"px,"+t+"px) scale("+n+")"},h=M.extend({init:function(t){var n=this;M.fn.init.call(n),n.element=e(t),n.element[0].style.webkitTransformOrigin="left top",n.x=0,n.y=0,n.scale=1,n._saveCoordinates(p(n.x,n.y,n.scale))},translateAxis:function(e,t){this[e]+=t,this.refresh()},scaleTo:function(e){this.scale=e,this.refresh()},scaleWith:function(e){this.scale*=e,this.refresh()},translate:function(e){this.x+=e.x,this.y+=e.y,this.refresh()},moveAxis:function(e,t){this[e]=t,this.refresh()},moveTo:function(e){E(this,e),this.refresh()},refresh:function(){
+var e,t=this,n=t.x,i=t.y;t.round&&(n=Math.round(n),i=Math.round(i)),e=p(n,i,t.scale),e!=t.coordinates&&(y.support.browser.msie&&y.support.browser.version<10?(t.element[0].style.position="absolute",t.element[0].style.left=t.x+"px",t.element[0].style.top=t.y+"px"):t.element[0].style[G]=e,t._saveCoordinates(e),t.trigger(A))},_saveCoordinates:function(e){this.coordinates=e}}),m=x.extend({init:function(e,t){var n,i=this;x.fn.init.call(i,e,t),n=i.options.group,n in C?C[n].push(i):C[n]=[i]},events:[R,W,B],options:{name:"DropTarget",group:"default"},destroy:function(){s(C,this)},_trigger:function(e,t){var n=this,i=D[n.options.group];if(i)return n.trigger(e,E({},t.event,{draggable:i,dropTarget:t.dropTarget}))},_over:function(e){this._trigger(R,e)},_out:function(e){this._trigger(W,e)},_drop:function(e){var t=this,n=D[t.options.group];n&&(n.dropped=!t._trigger(B,e))}}),m.destroyGroup=function(e){var t,n=C[e]||P[e];if(n){for(t=0;t<n.length;t++)x.fn.destroy.call(n[t]);n.length=0,delete C[e],delete P[e]}},m._cache=C,g=m.extend({init:function(e,t){var n,i=this;x.fn.init.call(i,e,t),n=i.options.group,n in P?P[n].push(i):P[n]=[i]},destroy:function(){s(P,this)},options:{name:"DropTargetArea",group:"default",filter:null}}),v=x.extend({init:function(e,t){var n=this;x.fn.init.call(n,e,t),n._activated=!1,n.userEvents=new T(n.element,{global:!0,allowSelection:!0,filter:n.options.filter,threshold:n.options.distance,start:S(n._start,n),hold:S(n._hold,n),move:S(n._drag,n),end:S(n._end,n),cancel:S(n._cancel,n),select:S(n._select,n)}),n._afterEndHandler=S(n._afterEnd,n),n._captureEscape=S(n._captureEscape,n)},events:[N,H,L,I,F,V],options:{name:"Draggable",distance:y.support.touch?0:5,group:"default",cursorOffset:null,axis:null,container:null,filter:null,ignore:null,holdToDrag:!1,autoScroll:!1,dropped:!1},cancelHold:function(){this._activated=!1},_captureEscape:function(e){var t=this;e.keyCode===y.keys.ESC&&(t._trigger(F,{event:e}),t.userEvents.cancel())},_updateHint:function(t){var n,i=this,o=i.options,a=i.boundaries,s=o.axis,l=i.options.cursorOffset;l?n={left:t.x.location+l.left,top:t.y.location+l.top}:(i.hintOffset.left+=t.x.delta,i.hintOffset.top+=t.y.delta,n=e.extend({},i.hintOffset)),a&&(n.top=r(n.top,a.y),n.left=r(n.left,a.x)),"x"===s?delete n.top:"y"===s&&delete n.left,i.hint.css(n)},_shouldIgnoreTarget:function(t){var n=this.options.ignore;return n&&e(t).is(n)},_select:function(e){this._shouldIgnoreTarget(e.event.target)||e.preventDefault()},_start:function(n){var i,r=this,a=r.options,s=a.container,l=a.hint;return this._shouldIgnoreTarget(n.touch.initialTouch)||a.holdToDrag&&!r._activated?(r.userEvents.cancel(),t):(r.currentTarget=n.target,r.currentTargetOffset=z(r.currentTarget),l&&(r.hint&&r.hint.stop(!0,!0).remove(),r.hint=y.isFunction(l)?e(l.call(r,r.currentTarget)):l,i=z(r.currentTarget),r.hintOffset=i,r.hint.css({position:"absolute",zIndex:2e4,left:i.left,top:i.top}).appendTo(w.body),r.angular("compile",function(){r.hint.removeAttr("ng-repeat");for(var t=e(n.target);!t.data("$$kendoScope")&&t.length;)t=t.parent();return{elements:r.hint.get(),scopeFrom:t.data("$$kendoScope")}})),D[a.group]=r,r.dropped=!1,s&&(r.boundaries=o(s,r.hint)),e(w).on($,r._captureEscape),r._trigger(H,n)&&(r.userEvents.cancel(),r._afterEnd()),r.userEvents.capture(),t)},_hold:function(e){this.currentTarget=e.target,this._trigger(N,e)?this.userEvents.cancel():this._activated=!0},_drag:function(t){var n,i;t.preventDefault(),n=this._elementUnderCursor(t),this.options.autoScroll&&this._cursorElement!==n&&(this._scrollableParent=c(n),this._cursorElement=n),this._lastEvent=t,this._processMovement(t,n),this.options.autoScroll&&this._scrollableParent[0]&&(i=d(t.x.location,t.y.location,l(this._scrollableParent)),this._scrollCompenstation=e.extend({},this.hintOffset),this._scrollVelocity=i,0===i.y&&0===i.x?(clearInterval(this._scrollInterval),this._scrollInterval=null):this._scrollInterval||(this._scrollInterval=setInterval(e.proxy(this,"_autoScroll"),50))),this.hint&&this._updateHint(t)},_processMovement:function(n,i){this._withDropTarget(i,function(i,r){if(!i)return f&&(f._trigger(W,E(n,{dropTarget:e(f.targetElement)})),f=null),t;if(f){if(r===f.targetElement)return;f._trigger(W,E(n,{dropTarget:e(f.targetElement)}))}i._trigger(R,E(n,{dropTarget:e(r)})),f=E(i,{targetElement:r})}),this._trigger(L,E(n,{dropTarget:f,elementUnderCursor:i}))},_autoScroll:function(){var e,t,n,i,r,o,a,s,l=this._scrollableParent[0],c=this._scrollVelocity,d=this._scrollCompenstation;l&&(e=this._elementUnderCursor(this._lastEvent),this._processMovement(this._lastEvent,e),i=l===u()[0],i?(t=w.body.scrollHeight>k.height(),n=w.body.scrollWidth>k.width()):(t=l.offsetHeight<=l.scrollHeight,n=l.offsetWidth<=l.scrollWidth),r=l.scrollTop+c.y,o=t&&r>0&&r<l.scrollHeight,a=l.scrollLeft+c.x,s=n&&a>0&&a<l.scrollWidth,o&&(l.scrollTop+=c.y),s&&(l.scrollLeft+=c.x),this.hint&&i&&(s||o)&&(o&&(d.top+=c.y),s&&(d.left+=c.x),this.hint.css(d)))},_end:function(t){this._withDropTarget(this._elementUnderCursor(t),function(n,i){n&&(n._drop(E({},t,{dropTarget:e(i)})),f=null)}),this._cancel(this._trigger(I,t))},_cancel:function(e){var t=this;t._scrollableParent=null,this._cursorElement=null,clearInterval(this._scrollInterval),t._activated=!1,t.hint&&!t.dropped?setTimeout(function(){t.hint.stop(!0,!0),e?t._afterEndHandler():t.hint.animate(t.currentTargetOffset,"fast",t._afterEndHandler)},0):t._afterEnd()},_trigger:function(e,t){var n=this;return n.trigger(e,E({},t.event,{x:t.x,y:t.y,currentTarget:n.currentTarget,initialTarget:t.touch?t.touch.initialTouch:null,dropTarget:t.dropTarget,elementUnderCursor:t.elementUnderCursor}))},_elementUnderCursor:function(e){var t=O(e),i=this.hint;return i&&n(i[0],t)&&(i.hide(),t=O(e),t||(t=O(e)),i.show()),t},_withDropTarget:function(e,t){var n,i=this.options.group,r=C[i],o=P[i];(r&&r.length||o&&o.length)&&(n=a(e,r,o),n?t(n.target,n.targetElement):t())},destroy:function(){var e=this;x.fn.destroy.call(e),e._afterEnd(),e.userEvents.destroy(),this._scrollableParent=null,this._cursorElement=null,clearInterval(this._scrollInterval),e.currentTarget=null},_afterEnd:function(){var t=this;t.hint&&t.hint.remove(),delete D[t.options.group],t.trigger("destroy"),t.trigger(V),e(w).off($,t._captureEscape)}}),y.ui.plugin(m),y.ui.plugin(g),y.ui.plugin(v),y.TapCapture=U,y.containerBoundaries=o,E(y.ui,{Pane:J,PaneDimensions:q,Movable:h}),y.ui.Draggable.utils={autoScrollVelocity:d,scrollableViewPort:l,findScrollableParent:c}}(window.kendo.jQuery),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()}),function(e,define){define("kendo.resizable.min",["kendo.core.min","kendo.draganddrop.min"],e)}(function(){return function(e,t){var n=window.kendo,i=n.ui,r=i.Widget,o=e.proxy,a=n.isFunction,s=e.extend,l="horizontal",u="vertical",c="start",d="resize",f="resizeend",p=r.extend({init:function(e,t){var n=this;r.fn.init.call(n,e,t),n.orientation=n.options.orientation.toLowerCase()!=u?l:u,n._positionMouse=n.orientation==l?"x":"y",n._position=n.orientation==l?"left":"top",n._sizingDom=n.orientation==l?"outerWidth":"outerHeight",n.draggable=new i.Draggable(t.draggableElement||e,{distance:1,filter:t.handle,drag:o(n._resize,n),dragcancel:o(n._cancel,n),dragstart:o(n._start,n),dragend:o(n._stop,n)}),n.userEvents=n.draggable.userEvents},events:[d,f,c],options:{name:"Resizable",orientation:l},resize:function(){},_max:function(e){var n=this,i=n.hint?n.hint[n._sizingDom]():0,r=n.options.max;return a(r)?r(e):r!==t?n._initialElementPosition+r-i:r},_min:function(e){var n=this,i=n.options.min;return a(i)?i(e):i!==t?n._initialElementPosition+i:i},_start:function(t){var n=this,i=n.options.hint,r=e(t.currentTarget);n._initialElementPosition=r.position()[n._position],n._initialMousePosition=t[n._positionMouse].startLocation,i&&(n.hint=a(i)?e(i(r)):i,n.hint.css({position:"absolute"}).css(n._position,n._initialElementPosition).appendTo(n.element)),n.trigger(c,t),n._maxPosition=n._max(t),n._minPosition=n._min(t),e(document.body).css("cursor",r.css("cursor"))},_resize:function(e){var n,i=this,r=i._maxPosition,o=i._minPosition,a=i._initialElementPosition+(e[i._positionMouse].location-i._initialMousePosition);n=o!==t?Math.max(o,a):a,i.position=n=r!==t?Math.min(r,n):n,i.hint&&i.hint.toggleClass(i.options.invalidClass||"",n==r||n==o).css(i._position,n),i.resizing=!0,i.trigger(d,s(e,{position:n}))},_stop:function(t){var n=this;n.hint&&n.hint.remove(),n.resizing=!1,n.trigger(f,s(t,{position:n.position})),e(document.body).css("cursor","")},_cancel:function(e){var n=this;n.hint&&(n.position=t,n.hint.css(n._position,n._initialElementPosition),n._stop(e))},destroy:function(){var e=this;r.fn.destroy.call(e),e.draggable&&e.draggable.destroy()},press:function(e){if(e){var t=e.position(),n=this;n.userEvents.press(t.left,t.top,e[0]),n.targetPosition=t,n.target=e}},move:function(e){var n=this,i=n._position,r=n.targetPosition,o=n.position;o===t&&(o=r[i]),r[i]=o+e,n.userEvents.move(r.left,r.top)},end:function(){this.userEvents.end(),this.target=this.position=t}});n.ui.plugin(p)}(window.kendo.jQuery),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()}),function(e,define){define("kendo.splitter.min",["kendo.resizable.min"],e)}(function(){return function(e,t){function n(e){return v.test(e)}function i(e){return g.test(e)||/^\d+$/.test(e)}function r(e){return!n(e)&&!i(e)}function o(e,t){var i=parseInt(e,10);return n(e)&&(i=Math.floor(i*t/100)),i}function a(e,n){return function(i,r){var o,a=this.element.find(i).data(D);return 1==arguments.length?a[e]:(a[e]=r,n&&(o=this.element.data("kendo"+this.options.name),o.resize(!0)),t)}}function s(e){var t=this,n=e.orientation;t.owner=e,t._element=e.element,t.orientation=n,p(t,n===T?u:l),t._resizable=new c.ui.Resizable(e.element,{orientation:n,handle:".k-splitbar-draggable-"+n+"[data-marker="+e._marker+"]",hint:h(t._createHint,t),start:h(t._start,t),max:h(t._max,t),min:h(t._min,t),invalidClass:"k-restricted-size-"+n,resizeend:h(t._stop,t)})}var l,u,c=window.kendo,d=c.ui,f=c.keys,p=e.extend,h=e.proxy,m=d.Widget,g=/^\d+(\.\d+)?px$/i,v=/^\d+(\.\d+)?%$/i,y=".kendoSplitter",b="expand",w="collapse",k="contentLoad",_="error",x="resize",M="layoutChange",T="horizontal",S="vertical",E="mouseenter",z="click",D="pane",C="mouseleave",P="k-state-focused",O="k-"+D,$="."+O,A=m.extend({init:function(e,t){var n,i=this;m.fn.init.call(i,e,t),i.wrapper=i.element,n=i.options.orientation.toLowerCase()!=S,i.orientation=n?T:S,i._dimension=n?"width":"height",i._keys={decrease:n?f.LEFT:f.UP,increase:n?f.RIGHT:f.DOWN},i._resizeStep=10,i._marker=c.guid().substring(0,8),i._initPanes(),i.resizing=new s(i),i.element.triggerHandler("init"+y)},events:[b,w,k,_,x,M],_addOverlays:function(){this._panes().append("<div class='k-splitter-overlay k-overlay' />")},_removeOverlays:function(){this._panes().children(".k-splitter-overlay").remove()},_attachEvents:function(){var t=this,n=t.options.orientation;t.element.children(".k-splitbar-draggable-"+n).on("keydown"+y,h(t._keydown,t)).on("mousedown"+y,function(e){e.currentTarget.focus()}).on("focus"+y,function(t){e(t.currentTarget).addClass(P)}).on("blur"+y,function(n){e(n.currentTarget).removeClass(P),t.resizing&&t.resizing.end()}).on(E+y,function(){e(this).addClass("k-splitbar-"+t.orientation+"-hover")}).on(C+y,function(){e(this).removeClass("k-splitbar-"+t.orientation+"-hover")}).on("mousedown"+y,h(t._addOverlays,t)).end().children(".k-splitbar").on("dblclick"+y,h(t._togglePane,t)).children(".k-collapse-next, .k-collapse-prev").on(z+y,t._arrowClick(w)).end().children(".k-expand-next, .k-expand-prev").on(z+y,t._arrowClick(b)).end().end(),e(window).on("resize"+y+t._marker,h(t.resize,t,!1)),e(document).on("mouseup"+y+t._marker,h(t._removeOverlays,t))},_detachEvents:function(){var t=this;t.element.children(".k-splitbar-draggable-"+t.orientation).off(y).end().children(".k-splitbar").off("dblclick"+y).children(".k-collapse-next, .k-collapse-prev, .k-expand-next, .k-expand-prev").off(y),e(window).off(y+t._marker),e(document).off(y+t._marker)},options:{name:"Splitter",orientation:T,panes:[]},destroy:function(){m.fn.destroy.call(this),this._detachEvents(),this.resizing&&this.resizing.destroy(),c.destroy(this.element),this.wrapper=this.element=null},_keydown:function(t){var n,i=this,r=t.keyCode,o=i.resizing,a=e(t.currentTarget),s=i._keys,l=r===s.increase,u=r===s.decrease;l||u?(t.ctrlKey?(n=a[u?"next":"prev"](),o&&o.isResizing()&&o.end(),n[i._dimension]()?i._triggerAction(w,a[u?"prev":"next"]()):i._triggerAction(b,n)):o&&o.move((u?-1:1)*i._resizeStep,a),t.preventDefault()):r===f.ENTER&&o&&(o.end(),t.preventDefault())},_initPanes:function(){var e=this.options.panes||[],t=this;this.element.addClass("k-widget").addClass("k-splitter").children().each(function(n,i){"script"!=i.nodeName.toLowerCase()&&t._initPane(i,e[n])}),this.resize()},_initPane:function(t,n){t=e(t).attr("role","group").addClass(O),t.data(D,n?n:{}).toggleClass("k-scrollable",!n||n.scrollable!==!1),this.ajaxRequest(t)},ajaxRequest:function(e,t,n){var i,r=this;e=r.element.find(e),i=e.data(D),t=t||i.contentUrl,t&&(e.append("<span class='k-icon k-i-loading k-pane-loading' />"),c.isLocalUrl(t)?jQuery.ajax({url:t,data:n||{},type:"GET",dataType:"html",success:function(t){r.angular("cleanup",function(){return{elements:e.get()}}),e.html(t),r.angular("compile",function(){return{elements:e.get()}}),r.trigger(k,{pane:e[0]})},error:function(t,n){r.trigger(_,{pane:e[0],status:n,xhr:t})}}):e.removeClass("k-scrollable").html("<iframe src='"+t+"' frameborder='0' class='k-content-frame'>This page requires frames in order to show content</iframe>"))},_triggerAction:function(e,t){this.trigger(e,{pane:t[0]})||this[e](t[0])},_togglePane:function(t){var n,i=this,r=e(t.target);r.closest(".k-splitter")[0]==i.element[0]&&(n=r.children(".k-icon:not(.k-resize-handle)"),1===n.length&&(n.is(".k-collapse-prev")?i._triggerAction(w,r.prev()):n.is(".k-collapse-next")?i._triggerAction(w,r.next()):n.is(".k-expand-prev")?i._triggerAction(b,r.prev()):n.is(".k-expand-next")&&i._triggerAction(b,r.next())))},_arrowClick:function(t){var n=this;return function(i){var r,o=e(i.target);o.closest(".k-splitter")[0]==n.element[0]&&(r=o.is(".k-"+t+"-prev")?o.parent().prev():o.parent().next(),n._triggerAction(t,r))}},_updateSplitBar:function(e,t,n){var i=function(e,t){return t?"<div class='k-icon "+e+"' />":""},r=this.orientation,o=t.resizable!==!1&&n.resizable!==!1,a=t.collapsible,s=t.collapsed,l=n.collapsible,u=n.collapsed;e.addClass("k-splitbar k-state-default k-splitbar-"+r).attr("role","separator").attr("aria-expanded",!(s||u)).removeClass("k-splitbar-"+r+"-hover").toggleClass("k-splitbar-draggable-"+r,o&&!s&&!u).toggleClass("k-splitbar-static-"+r,!o&&!a&&!l).html(i("k-collapse-prev k-i-arrow-60-up",a&&!s&&!u&&r==S)+i("k-collapse-prev k-i-arrow-60-left",a&&!s&&!u&&r==T)+i("k-expand-prev k-i-arrow-60-down",a&&s&&!u&&r==S)+i("k-expand-prev k-i-arrow-60-right",a&&s&&!u&&r==T)+i("k-resize-handle k-i-hbar",o&&r==S)+i("k-resize-handle k-i-vbar",o&&r==T)+i("k-collapse-next k-i-arrow-60-down",l&&!u&&!s&&r==S)+i("k-collapse-next k-i-arrow-60-right",l&&!u&&!s&&r==T)+i("k-expand-next k-i-arrow-60-up",l&&u&&!s&&r==S)+i("k-expand-next k-i-arrow-60-left",l&&u&&!s&&r==T)),o||a||l||e.removeAttr("tabindex")},_updateSplitBars:function(){var t=this;this.element.children(".k-splitbar").each(function(){var n=e(this),i=n.prevAll($).first().data(D),r=n.nextAll($).first().data(D);r&&t._updateSplitBar(n,i,r)})},_removeSplitBars:function(){this.element.children(".k-splitbar").remove()},_panes:function(){return this.element?this.element.children($):e()},_resize:function(){var n,i,a,s,l,u,d,f,p,h,m=this,g=m.element,v=g.children($),y=m.orientation==T,b=g.children(".k-splitbar"),w=b.length,k=y?"width":"height",_=g[k]();m.wrapper.addClass("k-splitter-resizing"),0===w?(w=v.length-1,v.slice(0,w).after("<div tabindex='0' class='k-splitbar' data-marker='"+m._marker+"' />"),m._updateSplitBars(),b=g.children(".k-splitbar")):m._updateSplitBars(),b.each(function(){_-=this[y?"offsetWidth":"offsetHeight"]}),n=0,i=0,a=e(),v.css({position:"absolute",top:0})[k](function(){var s,l=e(this),u=l.data(D)||{};if(l.removeClass("k-state-collapsed"),u.collapsed)s=u.collapsedSize?o(u.collapsedSize,_):0,l.css("overflow","hidden").addClass("k-state-collapsed");else{if(r(u.size))return a=a.add(this),t;s=o(u.size,_)}return i++,n+=s,s}),_-=n,s=a.length,l=Math.floor(_/s),a.slice(0,s-1).css(k,l).end().eq(s-1).css(k,_-(s-1)*l),u=0,d=y?"height":"width",f=y?"left":"top",p=y?"offsetWidth":"offsetHeight",0===s&&(h=v.filter(function(){return!(e(this).data(D)||{}).collapsed}).last(),h[k](_+h[0][p])),g.children().css(d,g[d]()).each(function(e,t){"script"!=t.tagName.toLowerCase()&&(t.style[f]=Math.floor(u)+"px",u+=t[p])}),m._detachEvents(),m._attachEvents(),m.wrapper.removeClass("k-splitter-resizing"),c.resize(v),m.trigger(M)},toggle:function(e,n){var i,r=this;e=r.element.find(e),i=e.data(D),(n||i.collapsible)&&(1==arguments.length&&(n=i.collapsed!==t&&i.collapsed),i.collapsed=!n,i.collapsed?e.css("overflow","hidden"):e.css("overflow",""),r.resize(!0))},collapse:function(e){this.toggle(e,!1)},expand:function(e){this.toggle(e,!0)},_addPane:function(e,t,n){var i=this;return n.length&&(i.options.panes.splice(t,0,e),i._initPane(n,e),i._removeSplitBars(),i.resize(!0)),n},append:function(t){t=t||{};var n=this,i=e("<div />").appendTo(n.element);return n._addPane(t,n.options.panes.length,i)},insertBefore:function(t,n){n=e(n),t=t||{};var i=this,r=i.wrapper.children(".k-pane").index(n),o=e("<div />").insertBefore(e(n));return i._addPane(t,r,o)},insertAfter:function(t,n){n=e(n),t=t||{};var i=this,r=i.wrapper.children(".k-pane").index(n),o=e("<div />").insertAfter(e(n));return i._addPane(t,r+1,o)},remove:function(t){t=e(t);var n=this;return t.length&&(c.destroy(t),t.each(function(t,i){n.options.panes.splice(n.wrapper.children(".k-pane").index(i),1),e(i).remove()}),n._removeSplitBars(),n.options.panes.length&&n.resize(!0)),n},size:a("size",!0),min:a("min"),max:a("max")});d.plugin(A),l={sizingProperty:"height",sizingDomProperty:"offsetHeight",alternateSizingProperty:"width",positioningProperty:"top",mousePositioningProperty:"pageY"},u={sizingProperty:"width",sizingDomProperty:"offsetWidth",alternateSizingProperty:"height",positioningProperty:"left",mousePositioningProperty:"pageX"},s.prototype={press:function(e){this._resizable.press(e)},move:function(e,t){this.pressed||(this.press(t),this.pressed=!0),this._resizable.target||this._resizable.press(t),this._resizable.move(e)},end:function(){this._resizable.end(),this.pressed=!1},destroy:function(){this._resizable.destroy(),this._resizable=this._element=this.owner=null},isResizing:function(){return this._resizable.resizing},_createHint:function(t){var n=this;return e("<div class='k-ghost-splitbar k-ghost-splitbar-"+n.orientation+" k-state-default' />").css(n.alternateSizingProperty,t[n.alternateSizingProperty]())},_start:function(t){var n=this,r=e(t.currentTarget),o=r.prev(),a=r.next(),s=o.data(D),l=a.data(D),u=parseInt(o[0].style[n.positioningProperty],10),c=parseInt(a[0].style[n.positioningProperty],10)+a[0][n.sizingDomProperty]-r[0][n.sizingDomProperty],d=parseInt(n._element.css(n.sizingProperty),10),f=function(e){var t=parseInt(e,10);return(i(e)?t:d*t/100)||0},p=f(s.min),h=f(s.max)||c-u,m=f(l.min),g=f(l.max)||c-u;n.previousPane=o,n.nextPane=a,n._maxPosition=Math.min(c-m,u+h),n._minPosition=Math.max(u+p,c-g)},_max:function(){return this._maxPosition},_min:function(){return this._minPosition},_stop:function(t){var n,i,o,a,s,l,u,d,f=this,p=e(t.currentTarget),h=f.owner;return h._panes().children(".k-splitter-overlay").remove(),t.keyCode!==c.keys.ESC&&(n=t.position,i=p.prev(),o=p.next(),a=i.data(D),s=o.data(D),l=n-parseInt(i[0].style[f.positioningProperty],10),u=parseInt(o[0].style[f.positioningProperty],10)+o[0][f.sizingDomProperty]-n-p[0][f.sizingDomProperty],d=f._element.children($).filter(function(){return r(e(this).data(D).size)}).length,(!r(a.size)||d>1)&&(r(a.size)&&d--,a.size=l+"px"),(!r(s.size)||d>1)&&(s.size=u+"px"),h.resize(!0)),!1}}}(window.kendo.jQuery),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()}),function(e,define){define("kendo.angular.min",["kendo.core.min"],e)}(function(){return function(e,t,n){"use strict";function i(e){var t=S;try{return S=function(e){return e()},e()}finally{S=t}}function r(t,i,r,u,c,g){function v(){var n,g,v,y,b,x,T;return r.kRebind&&(n=e(e(i)[0].cloneNode(!0))),M=o(t,i,r,u,_).options,i.is("select")&&!function(t){if(t.length>0){var n=e(t[0]);!/\S/.test(n.text())&&/^\?/.test(n.val())&&n.remove()}}(i[0].options),g=_.call(i,D=M).data(u),l(g,t,r,u,c),t.$emit("kendoWidgetCreated",g),v=p(t,g),r.kRebind&&m(g,t,i,n,r.kRebind,v,r),r.kNgDisabled&&(y=r.kNgDisabled,b=t.$eval(y),b&&g.enable(!b),a(g,t,i,y)),r.kNgReadonly&&(x=r.kNgReadonly,T=t.$eval(x),T&&g.readonly(T),s(g,t,i,x)),r.kNgModel&&f(g,t,r.kNgModel),w&&d(g,t,i,w,k),g&&h(g,i),g}var y,b,w,k,_,x,M,T,E,z,C,P,O,$;if(!(i instanceof jQuery))throw Error("The Kendo UI directives require jQuery to be available before AngularJS. Please include jquery before angular in the document.");if(y=r.kNgDelay,b=t.$eval(y),g=g||[],w=g[0],k=g[1],_=e(i)[u],!_)return window.console.error("Could not find: "+u),null;if(x=o(t,i,r,u,_),M=x.options,x.unresolved.length){for(T=[],E=0,z=x.unresolved.length;E<z;E++)C=x.unresolved[E],P=e.Deferred(function(e){var i=t.$watch(C.path,function(t){t!==n&&(i(),e.resolve())})}).promise(),T.push(P);return e.when.apply(null,T).then(v),n}return y&&!b?(O=t.$root||t,$=function(){var e=t.$watch(y,function(t){t!==n&&(e(),i.removeAttr(r.$attr.kNgDelay),y=null,S(v))})},/^\$(digest|apply)$/.test(O.$$phase)?$():t.$apply($),n):v()}function o(i,r,o,a,s){function l(e,r){var o=t.copy(i.$eval(r));o===n?h.push({option:e,path:r}):u[e]=o}var u,c,d,f,p=a.replace(/^kendo/,""),h=[],m=o.kOptions||o.options,g=i.$eval(m);return m&&g===n&&h.push({option:"options",path:m}),u=t.extend({},o.defaultOptions,g),c=s.widget.prototype.options,d=s.widget.prototype.events,e.each(o,function(e,t){var n,i,r,o;"source"!==e&&"kDataSource"!==e&&"kScopeField"!==e&&"scopeField"!==e&&(n="data"+e.charAt(0).toUpperCase()+e.slice(1),0===e.indexOf("on")&&(i=e.replace(/^on./,function(e){return e.charAt(2).toLowerCase()}),d.indexOf(i)>-1&&(u[i]=t)),c.hasOwnProperty(n)?l(n,t):c.hasOwnProperty(e)&&!O[e]?l(e,t):P[e]||(r=e.match(/^k(On)?([A-Z].*)/),r&&(o=r[2].charAt(0).toLowerCase()+r[2].slice(1),r[1]&&"kOnLabel"!=e?u[o]=t:("kOnLabel"==e&&(o="onLabel"),l(o,t)))))}),f=o.kDataSource||o.source,f&&(u.dataSource=C(i,r,p,f)),u.$angular=[i],{options:u,unresolved:h}}function a(e,t,i,r){return kendo.ui.PanelBar&&e instanceof kendo.ui.PanelBar||kendo.ui.Menu&&e instanceof kendo.ui.Menu?(z.warn("k-ng-disabled specified on a widget that does not have the enable() method: "+e.options.name),n):(t.$watch(r,function(t,n){t!=n&&e.enable(!t)}),n)}function s(e,t,i,r){return"function"!=typeof e.readonly?(z.warn("k-ng-readonly specified on a widget that does not have the readonly() method: "+e.options.name),n):(t.$watch(r,function(t,n){t!=n&&e.readonly(t)}),n)}function l(e,t,n,i,r){if(n[r]){var o=T(n[r]).assign;if(!o)throw Error(r+" attribute used but expression in it is not assignable: "+n[i]);o(t,e)}}function u(e){return/checkbox|radio/i.test(e.attr("type"))?e.prop("checked"):e.val()}function c(e){return $.test(e[0].tagName)}function d(e,t,i,r,o){var a,s,l,d,f;e.value&&(s=!1,a=c(i)?function(){return u(i)}:function(){return e.value()},l=function(){var i=r.$viewValue;i===n&&(i=r.$modelValue),i===n&&(i=null),s=!0,setTimeout(function(){if(s=!1,e){var n=t[e.element.attr("k-ng-model")];n&&(i=n),e.options.autoBind!==!1||e.listView.bound()?e.value(i):i&&e.value(i)}},0)},r.$render=l,setTimeout(function(){r.$render!==l&&(r.$render=l)()}),c(i)&&i.on("change",function(){s=!0}),d=function(e){return function(){var n;s&&!i.is("select")||(e&&o&&(n=o.$pristine),r.$setViewValue(a()),e&&(r.$setPristine(),n&&o.$setPristine()),w(t))}},e.first("change",d(!1)),e.first("spin",d(!1)),kendo.ui.AutoComplete&&e instanceof kendo.ui.AutoComplete||e.first("dataBound",d(!0)),f=a(),isNaN(r.$viewValue)||f==r.$viewValue||(r.$isEmpty(r.$viewValue)?null!=f&&""!==f&&f!=r.$viewValue&&r.$setViewValue(f):e.value(r.$viewValue)),r.$setPristine())}function f(t,i,r){var o,a,s,l,u,c,d,f,p,h;return"function"!=typeof t.value?(z.warn("k-ng-model specified on a widget that does not have the value() method: "+t.options.name),n):(o=e(t.element).parents("form"),a=kendo.getter(o.attr("name"),!0)(i),s=T(r),l=s.assign,u=!1,c=kendo.ui.MultiSelect&&t instanceof kendo.ui.MultiSelect,d=function(e){return e&&c?e.length:0},f=d(s(i)),t.$angular_setLogicValue(s(i)),p=function(e,i){e===n&&(e=null),u||e==i&&d(e)==f||(f=d(e),t.$angular_setLogicValue(e))},c?i.$watchCollection(r,p):i.$watch(r,p),h=function(){u=!0,a&&a.$pristine&&a.$setDirty(),w(i,function(){l(i,t.$angular_getLogicValue()),f=d(s(i))}),u=!1},t.first("change",h),t.first("spin",h),n)}function p(e,t){var n=e.$on("$destroy",function(){n(),t&&(kendo.destroy(t.element),t=null)});return n}function h(t,n){function i(){a.disconnect()}function r(){a.observe(e(n)[0],{attributes:!0})}var o,a;window.MutationObserver&&t.wrapper&&(o=[].slice.call(e(n)[0].classList),a=new MutationObserver(function(n){i(),t&&(n.forEach(function(n){var i,r=e(t.wrapper)[0];switch(n.attributeName){case"class":i=[].slice.call(n.target.classList),i.forEach(function(e){o.indexOf(e)<0&&(r.classList.add(e),kendo.ui.ComboBox&&t instanceof kendo.ui.ComboBox&&t.input[0].classList.add(e))}),o.forEach(function(e){i.indexOf(e)<0&&(r.classList.remove(e),kendo.ui.ComboBox&&t instanceof kendo.ui.ComboBox&&t.input[0].classList.remove(e))}),o=i;break;case"disabled":"function"!=typeof t.enable||t.element.attr("readonly")||t.enable(!e(n.target).attr("disabled"));break;case"readonly":"function"!=typeof t.readonly||t.element.attr("disabled")||t.readonly(!!e(n.target).attr("readonly"))}}),r())}),r(),t.first("destroy",i))}function m(t,n,i,r,o,a,s){var l=n.$watch(o,function(o,u){var c,d,f,p,h;t._muteRebind||o===u||(l(),s._cleanUp&&s._cleanUp(),c=I[t.options.name],c&&c.forEach(function(t){var i=n.$eval(s["k"+t]);i&&r.append(e(i).attr(kendo.toHyphens("k"+t),""))}),d=e(t.wrapper)[0],f=e(t.element)[0],p="Upload"===t.options.name,p&&(i=e(f)),h=i.injector().get("$compile"),t._destroy(),a&&a(),t=null,f&&(d&&d.parentNode.replaceChild(f,d),e(i).replaceWith(r)),h(r)(n))},!0);w(n)}function g(e,t){return function(n,i){return e.call(t,n,i)}}function v(e,t){this[e]=kendo.stringify(t)}function y(e,n){function i(e,t){x.directive(e,["directiveFactory",function(n){return n.create(t,e)}])}var r,o,a,s,l=n?"Mobile":"";l+=e.fn.options.name,r=l,o="kendo"+l.charAt(0)+l.substr(1).toLowerCase(),l="kendo"+l,a=l.replace(/([A-Z])/g,"-$1"),H.indexOf(l.replace("kendo",""))==-1&&(s=l===o?[l]:[l,o],t.forEach(s,function(e){x.directive(e,function(){return{restrict:"E",replace:!0,template:function(e,t){var n=A[r]||"div",i=t.kScopeField||t.scopeField;return"<"+n+" "+a+(i?'="'+i+'"':"")+">"+e.html()+"</"+n+">"}}})})),N.indexOf(l.replace("kendo",""))>-1||(i(l,l),o!=l&&i(o,l))}function b(t){return t=e(t),kendo.widgetInstance(t,kendo.ui)||kendo.widgetInstance(t,kendo.mobile.ui)||kendo.widgetInstance(t,kendo.dataviz.ui)}function w(e,t){var n=e.$root||e,i=/^\$(digest|apply)$/.test(n.$$phase);t?i?t():n.$apply(t):i||n.$digest()}function k(t,n){t.$destroy(),n&&e(n).removeData("$scope").removeData("$$kendoScope").removeData("$isolateScope").removeData("$isolateScopeNoTemplate").removeClass("ng-scope")}function _(n,i,r){var o,a,s;if(e.isArray(n))return t.forEach(n,function(e){_(e,i,r)});if("string"==typeof n){for(o=n.split("."),a=kendo;a&&o.length>0;)a=a[o.shift()];if(!a)return L.push([n,i,r]),!1;n=a.prototype}return s=n[i],n[i]=function(){var e=this,t=arguments;return r.apply({self:e,next:function(){return s.apply(e,arguments.length>0?arguments:t)}},t)},!0}var x,M,T,S,E,z,D,C,P,O,$,A,H,N,L,I;t&&t.injector&&(x=t.module("kendo.directives",[]),M=t.injector(["ng"]),T=M.get("$parse"),S=M.get("$timeout"),z=M.get("$log"),C=function(){var e={TreeList:"TreeListDataSource",TreeView:"HierarchicalDataSource",Scheduler:"SchedulerDataSource",PivotGrid:"PivotDataSource",PivotConfigurator:"PivotDataSource",PanelBar:"HierarchicalDataSource",Menu:"$PLAIN",ContextMenu:"$PLAIN"},t=function(e,t){return"$PLAIN"==t?e:kendo.data[t].create(e)};return function(n,i,r,o){var a=e[r]||"DataSource",s=n.$eval(o),l=t(s,a);return n.$watch(o,function(e){var n,r=b(i);r&&"function"==typeof r.setDataSource&&e!==s&&(n=t(e,a),r.setDataSource(n),s=e)}),l}}(),P={kDataSource:!0,kOptions:!0,kRebind:!0,kNgModel:!0,kNgDelay:!0},O={name:!0,title:!0,style:!0},$=/^(input|select|textarea)$/i,x.factory("directiveFactory",["$compile",function(t){var n,i,o=!1;return E=t,i=function(t,i){return{restrict:"AC",require:["?ngModel","^?form"],scope:!1,controller:["$scope","$attrs","$element",function(e,t){this.template=g(v,t),t._cleanUp=g(function(){this.template=null,t._cleanUp=null},this)}],link:function(a,s,l,u){var c,d=e(s),f=t.replace(/([A-Z])/g,"-$1");d.attr(f,d.attr("data-"+f)),d[0].removeAttribute("data-"+f),c=r(a,s,l,t,i,u),c&&(n&&clearTimeout(n),n=setTimeout(function(){a.$emit("kendoRendered"),o||(o=!0,e("form").each(function(){var t=e(this).controller("form");t&&t.$setPristine()}))}))}}},{create:i}}]),A={Editor:"textarea",NumericTextBox:"input",DatePicker:"input",DateTimePicker:"input",TimePicker:"input",AutoComplete:"input",ColorPicker:"input",MaskedTextBox:"input",MultiSelect:"input",Upload:"input",Validator:"form",Button:"button",MobileButton:"a",MobileBackButton:"a",MobileDetailButton:"a",ListView:"ul",MobileListView:"ul",PanelBar:"ul",TreeView:"ul",Menu:"ul",ContextMenu:"ul",ActionSheet:"ul"},H=["MobileView","MobileDrawer","MobileLayout","MobileSplitView","MobilePane","MobileModalView"],N=["MobileApplication","MobileView","MobileModalView","MobileLayout","MobileActionSheet","MobileDrawer","MobileSplitView","MobilePane","MobileScrollView","MobilePopOver"],t.forEach(["MobileNavBar","MobileButton","MobileBackButton","MobileDetailButton","MobileTabStrip","MobileScrollView","MobileScroller"],function(e){N.push(e),e="kendo"+e,x.directive(e,function(){return{restrict:"A",link:function(t,n,i){r(t,n,i,e,e)}}})}),L=[],kendo.onWidgetRegistered(function(t){L=e.grep(L,function(e){return!_.apply(null,e)}),y(t.widget,"Mobile"==t.prefix)}),_(["ui.Widget","mobile.ui.Widget"],"angular",function(r,o){var a,s=this.self;return"init"==r?(!o&&D&&(o=D),D=null,o&&o.$angular&&(s.$angular_scope=o.$angular[0],s.$angular_init(s.element,o)),n):(a=s.$angular_scope,a&&i(function(){var i,l,u=o(),c=u.elements,d=u.data;if(c.length>0)switch(r){case"cleanup":t.forEach(c,function(t){var n=e(t).data("$$kendoScope");n&&n!==a&&n.$$kendoScope&&k(n,t)});break;case"compile":i=s.element.injector(),l=i?i.get("$compile"):E,t.forEach(c,function(t,i){var r,o;u.scopeFrom?r=u.scopeFrom:(o=d&&d[i],o!==n?(r=e.extend(a.$new(),o),r.$$kendoScope=!0):r=a),e(t).data("$$kendoScope",r),l(t)(r)}),w(a)}}),n)}),_("ui.Widget","$angular_getLogicValue",function(){return this.self.value()}),_("ui.Widget","$angular_setLogicValue",function(e){this.self.value(e)}),_("ui.Select","$angular_getLogicValue",function(){var e=this.self.dataItem(),t=this.self.options.dataValueField;return e?this.self.options.valuePrimitive?t?e[t]:e:e.toJSON():null}),_("ui.Select","$angular_setLogicValue",function(e){var t=this.self,i=t.options,r=i.dataValueField,o=i.text||"";e===n&&(e=""),r&&!i.valuePrimitive&&e&&(o=e[i.dataTextField]||"",e=e[r||i.dataTextField]),t.options.autoBind!==!1||t.listView.bound()?t.value(e):!o&&e&&i.valuePrimitive?t.value(e):t._preselect(e,o)}),_("ui.MultiSelect","$angular_getLogicValue",function(){var t=this.self.dataItems().slice(0),n=this.self.options.dataValueField;return n&&this.self.options.valuePrimitive&&(t=e.map(t,function(e){return e[n]})),t}),_("ui.MultiSelect","$angular_setLogicValue",function(t){var n,i,r,o;null==t&&(t=[]),n=this.self,i=n.options,r=i.dataValueField,o=t,r&&!i.valuePrimitive&&(t=e.map(t,function(e){return e[r]})),
+i.autoBind!==!1||i.valuePrimitive||n.listView.bound()?n.value(t):n._preselect(o,t)}),_("ui.AutoComplete","$angular_getLogicValue",function(){var e,t,n,i,r,o=this.self.options,a=this.self.value().split(o.separator),s=o.valuePrimitive,l=this.self.listView.selectedDataItems(),u=[];for(e=0,t=l.length;e<t;e++)for(n=l[e],i=o.dataTextField?n[o.dataTextField]:n,r=0;r<a.length;r++)if(i===a[r]){u.push(s?i:n.toJSON());break}return u}),_("ui.AutoComplete","$angular_setLogicValue",function(t){null==t&&(t=[]);var i=this.self,r=i.options.dataTextField;r&&!i.options.valuePrimitive&&(t=t.length!==n?e.map(t,function(e){return e[r]}):t[r]),i.value(t)}),_("ui.Widget","$angular_init",function(t,n){var i,r,o,a,s=this.self;if(n&&!e.isArray(n))for(i=s.$angular_scope,r=s.events.length;--r>=0;)o=s.events[r],a=n[o],a&&"string"==typeof a&&(n[o]=s.$angular_makeEventHandler(o,i,a))}),_("ui.Widget","$angular_makeEventHandler",function(e,t,n){return n=T(n),function(e){w(t,function(){n(t,{kendoEvent:e})})}}),_(["ui.Grid","ui.ListView","ui.TreeView","ui.PanelBar"],"$angular_makeEventHandler",function(e,n,i){return"change"!=e?this.next():(i=T(i),function(e){var r,o,a,s,l,u,c,d,f,p=e.sender,h=p.options,m={kendoEvent:e};for(t.isString(h.selectable)&&(r=h.selectable.indexOf("cell")!==-1,o=h.selectable.indexOf("multiple")!==-1),a=m.selected=this.select(),s=m.data=[],l=m.columns=[],c=0;c<a.length;c++)d=r?a[c].parentNode:a[c],f=p.dataItem(d),r?(t.element.inArray(f,s)<0&&s.push(f),u=t.element(a[c]).index(),t.element.inArray(u,l)<0&&l.push(u)):s.push(f);o||(m.dataItem=m.data=s[0],m.angularDataItem=kendo.proxyModelSetters(m.dataItem),m.selected=a[0]),w(n,function(){i(n,m)})})}),_("ui.Grid","$angular_init",function(i,r){if(this.next(),r.columns){var o=e.extend({},kendo.Template,r.templateSettings);t.forEach(r.columns,function(e){!e.field||e.template||e.format||e.values||e.encoded!==n&&!e.encoded||(e.template="<span ng-bind='"+kendo.expr(e.field,"dataItem")+"'>#: "+kendo.expr(e.field,o.paramName)+"#</span>")})}}),_("mobile.ui.ButtonGroup","value",function(e){var t=this.self;return null!=e&&(t.select(t.element.children("li.km-button").eq(e)),t.trigger("change"),t.trigger("select",{index:t.selectedIndex})),t.selectedIndex}),_("mobile.ui.ButtonGroup","_select",function(){this.next(),this.self.trigger("change")}),x.directive("kendoMobileApplication",function(){return{terminal:!0,link:function(e,t,n){r(e,t,n,"kendoMobileApplication","kendoMobileApplication")}}}).directive("kendoMobileView",function(){return{scope:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,n._instance=r(e,t,n,"kendoMobileView","kendoMobileView")},post:function(e,t,n){n._instance._layout(),n._instance._scroller()}}}}).directive("kendoMobileDrawer",function(){return{scope:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,n._instance=r(e,t,n,"kendoMobileDrawer","kendoMobileDrawer")},post:function(e,t,n){n._instance._layout(),n._instance._scroller()}}}}).directive("kendoMobileModalView",function(){return{scope:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,n._instance=r(e,t,n,"kendoMobileModalView","kendoMobileModalView")},post:function(e,t,n){n._instance._layout(),n._instance._scroller()}}}}).directive("kendoMobileSplitView",function(){return{terminal:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,n._instance=r(e,t,n,"kendoMobileSplitView","kendoMobileSplitView")},post:function(e,t,n){n._instance._layout()}}}}).directive("kendoMobilePane",function(){return{terminal:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,r(e,t,n,"kendoMobilePane","kendoMobilePane")}}}}).directive("kendoMobileLayout",function(){return{link:{pre:function(e,t,n){r(e,t,n,"kendoMobileLayout","kendoMobileLayout")}}}}).directive("kendoMobileActionSheet",function(){return{restrict:"A",link:function(t,n,i){n.find("a[k-action]").each(function(){e(this).attr("data-"+kendo.ns+"action",e(this).attr("k-action"))}),r(t,n,i,"kendoMobileActionSheet","kendoMobileActionSheet")}}}).directive("kendoMobilePopOver",function(){return{terminal:!0,link:{pre:function(e,t,n){n.defaultOptions=e.viewOptions,r(e,t,n,"kendoMobilePopOver","kendoMobilePopOver")}}}}).directive("kendoViewTitle",function(){return{restrict:"E",replace:!0,template:function(e){return"<span data-"+kendo.ns+"role='view-title'>"+e.html()+"</span>"}}}).directive("kendoMobileHeader",function(){return{restrict:"E",link:function(e,t){t.addClass("km-header").attr("data-role","header")}}}).directive("kendoMobileFooter",function(){return{restrict:"E",link:function(e,t){t.addClass("km-footer").attr("data-role","footer")}}}).directive("kendoMobileScrollViewPage",function(){return{restrict:"E",replace:!0,template:function(e){return"<div data-"+kendo.ns+"role='page'>"+e.html()+"</div>"}}}),t.forEach(["align","icon","rel","transition","actionsheetContext"],function(e){var t="k"+e.slice(0,1).toUpperCase()+e.slice(1);x.directive(t,function(){return{restrict:"A",priority:2,link:function(n,i,r){i.attr(kendo.attr(kendo.toHyphens(e)),n.$eval(r[t]))}}})}),I={TreeMap:["Template"],MobileListView:["HeaderTemplate","Template"],MobileScrollView:["EmptyTemplate","Template"],Grid:["AltRowTemplate","DetailTemplate","RowTemplate"],ListView:["EditTemplate","Template","AltTemplate"],Pager:["SelectTemplate","LinkTemplate"],PivotGrid:["ColumnHeaderTemplate","DataCellTemplate","RowHeaderTemplate"],Scheduler:["AllDayEventTemplate","DateHeaderTemplate","EventTemplate","MajorTimeHeaderTemplate","MinorTimeHeaderTemplate"],PanelBar:["Template"],TreeView:["Template"],Validator:["ErrorTemplate"]},function(){var e={};t.forEach(I,function(n,i){t.forEach(n,function(t){e[t]||(e[t]=[]),e[t].push("?^^kendo"+i)})}),t.forEach(e,function(e,t){var n="k"+t,i=kendo.toHyphens(n);x.directive(n,function(){return{restrict:"A",require:e,terminal:!0,compile:function(t,r){if(""===r[n]){t.removeAttr(i);var o=t[0].outerHTML;return function(t,r,a,s){for(var l;!l&&s.length;)l=s.shift();l?(l.template(n,o),r.remove()):z.warn(i+" without a matching parent widget found. It can be one of the following: "+e.join(", "))}}}}})})}())}(window.kendo.jQuery,window.angular),window.kendo},"function"==typeof define&&define.amd?define:function(e,t,n){(n||t)()});
+//# sourceMappingURL=kendo.custom.min.js.map
diff --git a/src/main/resources/META-INF/resources/designer/scripts/propertyExplorerCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/propertyExplorerCtrl.js
new file mode 100644 (file)
index 0000000..59ee1a3
--- /dev/null
@@ -0,0 +1,625 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.directive('opentext', function ($compile, dialogs, $rootScope){
+    console.log("//////////opentext");
+  return {
+      restrict: "AE",
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         element.bind("click", function(){
+            console.log("bind");
+               
+               if(attrs.ngModel=='decisionIdentifier.textualInformation.testCaseDescription'){
+                       
+                       $rootScope.textAreaData = scope.decisionIdentifier.textualInformation.testCaseDescription;
+                $rootScope.textAreaTitle = 'Test Case Description';
+                var dlg = dialogs.create('partials/portfolios/text_area_modal.html','textAreaCtrl',{},{size:'sm',keyboard: true,backdrop: 'static'});
+                       
+                dlg.result.then(function(name){
+                    console.log("dlg.result");
+                               scope.decisionIdentifier.textualInformation.testCaseDescription = $rootScope.textAreaData;
+                       },function(){
+                               scope.decisionIdentifier.textualInformation.testCaseDescription = $rootScope.textAreaData;
+                       });
+                       
+               }else if(attrs.ngModel=='decisionIdentifier.textualInformation.testStepDescription'){
+                       
+                       $rootScope.textAreaData = scope.decisionIdentifier.textualInformation.testStepDescription;
+                $rootScope.textAreaTitle = 'Test Step Description';
+                var dlg = dialogs.create('partials/portfolios/text_area_modal.html','textAreaCtrl',{},{size:'sm',keyboard: true,backdrop: 'static'});
+                       
+                dlg.result.then(function(name){
+                    console.log("dlg.result");
+                               scope.decisionIdentifier.textualInformation.testStepDescription = $rootScope.textAreaData;
+                       },function(){
+                               scope.decisionIdentifier.textualInformation.testStepDescription = $rootScope.textAreaData;
+                       });
+                       
+               }else if(attrs.ngModel=='decisionIdentifier.textualInformation.expectedResult'){
+                       
+                       $rootScope.textAreaData = scope.decisionIdentifier.textualInformation.expectedResult;
+                $rootScope.textAreaTitle = 'Expected Result';
+                
+                var dlg = dialogs.create('partials/portfolios/text_area_modal.html','textAreaCtrl',{},{size:'sm',keyboard: true,backdrop: 'static'});
+                       dlg.result.then(function(name){
+                    console.log("dlg.result");
+                               scope.decisionIdentifier.textualInformation.expectedResult = $rootScope.textAreaData;
+                       },function(){
+                               scope.decisionIdentifier.textualInformation.expectedResult = $rootScope.textAreaData;
+                       });
+                       
+               }else if(attrs.ngModel=='pathDetails.textualInformation.testPathDescription'){
+                       
+                       if(scope.pathDetails.textualInformation==null){
+                               scope.pathDetails.textualInformation = {};
+                               scope.pathDetails.textualInformation.testPathDescription = '';
+                       }
+                       $rootScope.textAreaData = scope.pathDetails.textualInformation.testPathDescription;
+                $rootScope.textAreaTitle = 'Test Path Description';
+                var dlg = dialogs.create('partials/portfolios/text_area_modal.html','textAreaCtrl',{},{size:'sm',keyboard: true,backdrop: 'static'});
+                       
+                dlg.result.then(function(name){
+                    console.log("dlg.result");
+                               scope.pathDetails.textualInformation.testPathDescription = $rootScope.textAreaData;
+                       },function(){
+                               scope.decisionIdentifier.textualInformation.testPathDescription = $rootScope.textAreaData;
+                       });
+                
+               }else if(attrs.ngModel=='runtimePythonScript.inputParams'){
+                       
+                       $rootScope.textAreaData = scope.runtimePythonScript.inputParams;
+                $rootScope.textAreaTitle = 'Input Parameter';
+                var dlg = dialogs.create('partials/portfolios/text_area_modal.html','textAreaCtrl',{},{size:'sm',keyboard: true,backdrop: 'static'});
+                       
+                dlg.result.then(function(name){
+                    console.log("");
+                               scope.runtimePythonScript.inputParams = $rootScope.textAreaData;
+                       },function(){
+                               scope.runtimePythonScript.inputParams = $rootScope.textAreaData;
+                       });
+                
+               }
+               
+         });
+      }
+  }
+});
+
+app.directive('inputInfoPropertyClass', function ($compile) {
+    console.log("inputInfoPropertyClass");
+  return {
+      restrict: "C",
+      replace: true,
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         scope.sourceExplorer = 'PE';
+         angular.forEach(scope.infoType.schemaElements, function(value, key){
+            console.log("schemaElement");
+                 
+                 scope.schemaElement = value;
+                 
+                 if(scope.schemaElement.complexType != null){
+                         if(scope.currentElementName == ''){
+                                 scope.currentElementName = scope.schemaElement.complexType.name;
+                         }
+                         
+                         scope.ParentKey = scope.parentName + '_' + scope.currentElementName;
+                         if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                                 scope.ParentKey = scope.ParentKey + scope.schemaElement.repeatableHierarchicalPrefix; 
+                         }
+                         scope.showUTMViewMsgHeader = true;
+                         scope.parElement = scope.schemaElement;
+                         scope.tableStyle = 'table-level' + scope.heirarchyLevel + '-tree'; 
+                         scope.tdLabelStyle = 'td-level' + scope.heirarchyLevel + '-label-tree'; 
+                         scope.heirLevel = scope.heirarchyLevel;
+                         
+                         elementHTML = elementHTML + '<div ng-show="schemaElement.complexType != null">';
+                         elementHTML = elementHTML + '<table class="{{tableStyle}}"> <tr>';
+                         elementHTML = elementHTML + '<td class="{{tdLabelStyle}}">';
+                         elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                         elementHTML = elementHTML + '<i ng-class="showUTMViewMsgHeader == true ?\'fa fa-plus-circle\':\'fa fa-minus-circle\'"></i>';
+                         elementHTML = elementHTML + '</span>';
+                         elementHTML = elementHTML + '<b>{{currentElementName}}</b>';
+                         elementHTML = elementHTML + '</td>';
+                         elementHTML = elementHTML + '</tr></table>';
+                         elementHTML = elementHTML + '<div style="margin-left: 10px" ng-class="{hidden:showUTMViewMsgHeader,chaldean:showUTMViewMsgHeader}">';
+                         elementHTML = elementHTML + '<div class="inputInfoPropertyClassMember" style="margin-left: 10px" ng-repeat="schemaElement in schemaElement.elements"></div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         var x = angular.element(elementHTML);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+             });
+         
+      }
+  }
+});
+
+app.directive('inputInfoPropertyClassMember', function ($compile) {
+    console.log("inputInfoPropertyClassMember");
+  return {
+      restrict: "C",
+
+      link: function(scope,element,attrs){
+        console.log("link");
+         var elementHTML = '';
+         
+         scope.currentElementName=scope.objectName;
+         scope.parentName=scope.ParentKey; 
+         scope.parentElement=scope.parElement; 
+         scope.heirarchyLevel = scope.heirLevel + 1;
+         
+         if(scope.schemaElement.element.name != null){
+                 
+                 scope.elementKey=scope.parentName + '_' + scope.schemaElement.element.name;
+                 if(scope.schemaElement.repeatableHierarchicalPrefix != null){
+                         scope.elementKey = scope.elementKey + scope.schemaElement.repeatableHierarchicalPrefix;
+                 }
+                 scope.tableStyle='table-level' + scope.heirarchyLevel + '-tree'; 
+                 scope.tdLabelStyle='td-level' + scope.heirarchyLevel +'-label-tree';
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         scope.showUTMViewMsgHeader = false;
+                         
+                 }else{
+                         scope.showUTMViewMsgHeader = true;
+                         
+                 }
+                 
+                 elementHTML = elementHTML + '<div ng-show="schemaElement.element.name != null">';
+                 elementHTML = elementHTML + '<div ng-show = "schemaElement.type.complexType != null || utmSchemaExts[elementKey].checked">';
+                 elementHTML = elementHTML + '<table class="{{tableStyle}}"> ';
+                 elementHTML = elementHTML + '<tr>';
+                 elementHTML = elementHTML + '<td style="text-align: left;vertical-align: top;" class="{{tdLabelStyle}}">';
+                 elementHTML = elementHTML + '<span class="pull-left" ng-click="showUTMViewMsgHeader=!showUTMViewMsgHeader">';
+                 elementHTML = elementHTML + '<i expandable ng-class="showUTMViewMsgHeader == true ?\'fa fa-minus-circle\':\'fa fa-plus-circle\'"></i>';
+                 elementHTML = elementHTML + '{{schemaElement.element.name}}  ';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '</span>';
+                 elementHTML = elementHTML + '</td>';
+                 
+                 
+                 
+                 elementHTML = elementHTML + '<td style="width: 70px">&nbsp;&nbsp;&nbsp;</td>';
+                 elementHTML = elementHTML + '<td style="width: 40px; float: left;">';
+                 if(scope.schemaElement.type.complexType == null){
+                         elementHTML = elementHTML + '<div ng-show="schemaElement.type.complexType == null">';
+                         elementHTML = elementHTML + '<div ng-repeat="object in filteredObjects = (schemaElement.type.restriction.minExclusivesAndMinInclusivesAndMaxExclusives | filter: {name : \'enumeration\'})"></div>';
+                         elementHTML = elementHTML + '<div ng-if="filteredObjects.length > 0" class="defaultSelect">';
+                         elementHTML = elementHTML + '<input type="text" class="defaultVal" id="{{elementKey}}" ng-model="decisionIdentifier.elementValues[elementKey]" style="width:150px;"/>';
+                         elementHTML = elementHTML + '<select style="width: 170px; id=;height: 20px;" id="{{elementKey}}" onchange="this.previousElementSibling.value=this.value;" ng-model="decisionIdentifier.elementValues[elementKey]" ';
+                         elementHTML = elementHTML + 'ng-options="filteredObject.value.value as filteredObject.value.value for filteredObject in filteredObjects">';
+                         elementHTML = elementHTML + '<option value=""></option>';
+                         elementHTML = elementHTML + '</select>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-if="filteredObjects == null || filteredObjects.length == 0">';
+                         elementHTML = elementHTML + '<div ng-if="schemaElement.type != null && schemaElement.type==\'boolean\'">';
+                         elementHTML = elementHTML + '<div style="display: inline-flex">';
+                         elementHTML = elementHTML + '<input type="radio" value="true" ng-model="decisionIdentifier.elementValues[elementKey]">True <span style="width:20px;"></span>';
+                         elementHTML = elementHTML + '<input type="radio" value="false" ng-model="decisionIdentifier.elementValues[elementKey]">False';
+                         elementHTML = elementHTML + '';
+                         elementHTML = elementHTML + '';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '<div ng-if="schemaElement.type == null || schemaElement.type != \'boolean\'">';
+                         elementHTML = elementHTML + '<input type="text"  id="{{elementKey}}"  style="width: 170px;" class="defaultVal" ng-model="decisionIdentifier.elementValues[elementKey]"/>';
+                         elementHTML = elementHTML + '';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '';
+                         elementHTML = elementHTML + '</div>';
+                         elementHTML = elementHTML + '</div>';
+                 }
+                 
+                 elementHTML = elementHTML + '</td>';
+                 elementHTML = elementHTML + '</tr>';
+                 elementHTML = elementHTML + '<br/>';
+                 elementHTML = elementHTML + '</table>';
+                 
+                 
+                 
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '';
+                 elementHTML = elementHTML + '</div>';
+                 elementHTML = elementHTML + '</div>';
+                 
+                 var x = angular.element(elementHTML);
+                element.append(x);
+                $compile(x)(scope);
+                 
+                 
+                 if(scope.schemaElement.type.complexType != null){
+                         var elementHTML2 = '<div ng-show="schemaElement.type.complexType != null">'
+                         elementHTML2 = elementHTML2 + '<div ng-init="parKey=parentName + \'_\' + schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\'); heirLevel=heirarchyLevel; parElement=schemaElement; ParentKey=ParentKey+\'_\'+schemaElement.element.name + (schemaElement.repeatableHierarchicalPrefix != null ? schemaElement.repeatableHierarchicalPrefix : \'\')">'
+                         elementHTML2 = elementHTML2 + '<div style="margin-left: 10px" ng-class="{hidden:!showUTMViewMsgHeader,chaldean:!showUTMViewMsgHeader}">'
+                         elementHTML2 = elementHTML2 + '<div class="{{sourceExplorer+\'_\'+parKey}}"></div>'
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>'
+                         elementHTML2 = elementHTML2 + '</div>';
+                         var x = angular.element(elementHTML2);
+                       element.append(x);
+                       $compile(x)(scope);
+                 }
+                 
+         }
+
+      }
+  }
+});
+
+app.controller('propertyExplorerCtrl',['$scope','$rootScope','$location','$modalInstance','dialogs','Datafactory',function($scope, $rootScope, $location, $modalInstance, dialogs, Datafactory) {
+       console.log("propertyExplorerCtrl");
+    $rootScope.bpmnElementName;
+       $rootScope.pathIdentifiers;
+       $scope.propertyExplorerObject = {};
+
+       $scope.pathDetailsList = [];
+       $scope.utmSchemaExts = {};
+       $scope.user3 ="";
+       
+       $scope.close = function(){
+        console.log("close");
+               $modalInstance.close();
+       };
+       
+       $rootScope.initPropertyExplorer = function() {  
+    console.log("initPropertyExplorer");       
+               $scope.pathDetailsList = list_model_path_details[selected_model];
+               if(list_model_schema_extensions[selected_model] != null && list_model_schema_extensions[selected_model].utmSchemaExtentionMap != null) {
+                       $scope.utmSchemaExts = list_model_schema_extensions[selected_model].utmSchemaExtentionMap;
+               }
+               
+                $(".resize-none").each(function() {
+            console.log("resize-none");
+                           $(this).val($(this).val().replace(/,/g, "\n"));
+                         });
+               
+               if($scope.pathDetailsList == null)
+                       $scope.pathDetailsList = [];
+               
+               if ($rootScope.bpmnElementName != null) {
+                       if ($scope.pathDetailsList != null && $scope.pathDetailsList.length > 0) {
+                               var isPathDetailsAvailable = false;
+                               for (var i = 0; i < $scope.pathDetailsList.length; i++) {
+                                       if ($scope.pathDetailsList[i].conditionalNode == $rootScope.bpmnElementName) {
+                                               isPathDetailsAvailable = true;
+                                       }
+                               }
+
+                               if (!isPathDetailsAvailable) {
+                                       $scope.addPathDetails();
+                               }
+                       } else if ($scope.pathDetailsList == null) {
+                               $scope.addPathDetails();
+                       }
+               }
+       };
+
+       $scope.addPathDetails = function() {
+        console.log("addPathDetails");
+               $scope.pathDetails = {};
+               $scope.pathDetails.conditionalNode = $rootScope.bpmnElementName;
+               $scope.pathDetailsList.push($scope.pathDetails);
+               $scope.addDecisionIdentifier($scope.pathDetails);
+               list_model_path_details[selected_model] = $scope.pathDetailsList;               
+       };
+       
+       
+
+       $scope.addDecisionIdentifier = function(pathDtls) {
+        console.log("addDecisionIdentifier");
+               $scope.decisionIdentifier = {};
+               $scope.decisionIdentifier.textualInformation={};
+               //$scope.decisionIdentifier.textualInformation.use=true;
+               if (pathDtls.decisionIdentifiers != null) {
+                       if(angular.isUndefined($scope.decisionIdentifier.textualInformation.use))
+                               $scope.decisionIdentifier.textualInformation.use = true;                        
+                       pathDtls.decisionIdentifiers.push($scope.decisionIdentifier);
+               } else {
+                       pathDtls.decisionIdentifiers = [];
+                       if(angular.isUndefined($scope.decisionIdentifier.textualInformation.use))
+                               $scope.decisionIdentifier.textualInformation.use = true;                        
+                       pathDtls.decisionIdentifiers.push($scope.decisionIdentifier);
+               }
+       };
+
+       $scope.isElementCheckedinExplorer = function(elementId) {
+        console.log("isElementCheckedinExplorer");
+               console.log("Enter into property explorer");
+               if (elementId.indexOf("_decisionValue") != -1) {
+                       var elementIdSplit = elementId.split("_decisionValue");
+                       var elementCheckBoxId = elementIdSplit[0] + "_checkbox";
+                       var elementCheckBoxValue = document.getElementById(elementCheckBoxId);
+                       if (elementCheckBoxValue != "" && elementCheckBoxValue.checked) {
+                               return true;
+                       }
+                       return false;
+               }
+               return false;
+       };
+
+       $scope.moreDecisions = function(pathDtls) {
+        console.log("moreDecisions");
+               //alert("PropertyExplorerCtrl entering moreDecisions");
+               $scope.addDecisionIdentifier(pathDtls);
+               //alert("PropertyExplorerCtrl exiting moreDecisions");
+       };
+
+       $scope.morePaths = function() {
+        console.log("morePaths");
+               var elementCount=0;
+               $scope.pathDetailsList = list_model_path_details[selected_model];
+               if ($scope.pathDetailsList == null){
+                       if($rootScope.pathIdentifiers.length>0){
+                               $scope.pathDetailsList = [];
+                               $scope.addPathDetails();
+                       }
+                       else
+                               dialogs.error('Error','Please define atleast 1 path in model to proceed.');
+               }
+               else
+               {
+               for(var i=0;i<$scope.pathDetailsList.length;i++){
+                       if($rootScope.bpmnElementName == $scope.pathDetailsList[i].conditionalNode){
+                               elementCount++;
+                       }
+               }
+               if(elementCount < $rootScope.pathIdentifiers.length)
+                       $scope.addPathDetails();
+               else
+                       dialogs.error('Error','The number of paths defined for this conditional node cannot be more than the number of Path Identifiers defined in the Model.');
+       }
+       };
+
+       $rootScope.initPropertyExplorer();
+       
+       $scope.sendDbData = function(dbToolRequestList){
+        console.log("sendDbData");
+               if(dbToolRequestList!=null){
+                       Datafactory.setDbDataList(dbToolRequestList);
+               }
+               else{
+                       dbToolRequestList=[];
+                       Datafactory.setDbDataList(dbToolRequestList);
+               }
+       };
+       
+       /*$scope.openDbToolPath = function(pathDtls) {
+        console.log("openDbToolPath");
+               $scope.pathDetails=pathDtls;
+               $scope.sendDbData($scope.pathDetails.dbToolRequestList);
+               
+               var dlg = dialogs.create('partials/SOA/dbTool_property_explorer.html','dbTool_property_explorer',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){ 
+        console.log("dlg.result");                     
+                       $scope.pathDetails.dbToolRequestList=Datafactory.getDbDataList();
+                       
+                       var resetDbRequestList=[];
+                       Datafactory.setDbDataList(resetDbRequestList);
+                       //Datafactory.setDbDataFlag("");
+                       
+               },function(){
+                       
+               });
+       };
+       
+       $scope.openDbToolDecision = function(DecisionDtls) {
+        console.log("openDbToolDecision");
+               $scope.decisionIdentifier=DecisionDtls;
+               $scope.sendDbData($scope.decisionIdentifier.dbToolRequestList);         
+               
+               var dlg = dialogs.create('partials/SOA/dbTool_property_explorer.html','dbTool_property_explorer',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+        console.log("dlg.result");                             
+                       $scope.decisionIdentifier.dbToolRequestList=Datafactory.getDbDataList();
+                       
+                       var resetDbRequestList=[];
+                       Datafactory.setDbDataList(resetDbRequestList);
+               },function(){
+                       
+               });
+       };*/
+       //soap_client_option.html
+       /*$scope.openXMLAsserterPath = function(pathDtls){
+               $scope.pathDetails=pathDtls;
+               $scope.sendAssertData($scope.pathDetails.xmlAsserter);
+               
+               var dlg = dialogs.create('partials/SOA/XML_Assertor.html','xmlAssertorCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+                       $scope.pathDetails.xmlAsserter = Datafactory.getXmlAsserter();
+                       var resetXmlAsserter ={};
+                       Datafactory.setXmlAsserter(resetXmlAsserter);
+               },function(){
+                       
+               });
+       };*/
+       
+       /*$scope.openXMLAsserterDecision = function(DecisionDtls){
+        console.log("openXMLAsserterDecision");
+               $scope.decisionIdentifier=DecisionDtls;
+               $scope.sendAssertData($scope.decisionIdentifier.xmlAsserter);   
+               
+               var dlg = dialogs.create('partials/SOA/XML_Assertor.html','xmlAssertorCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+            console.log("dlg.result");
+                       $scope.decisionIdentifier.xmlAsserter = Datafactory.getXmlAsserter();
+                       var resetXmlAsserter ={};
+                       Datafactory.setXmlAsserter(resetXmlAsserter);
+                       
+               },function(){
+                       
+               });
+       };*/
+       
+       $scope.sendAssertData = function(xmlAsserterRequest){
+        console.log("sendAssertData");
+               if(xmlAsserterRequest!=null){
+                       Datafactory.setXmlAsserter(xmlAsserterRequest);
+               }
+               else{
+                       xmlAsserterRequest={};
+                       Datafactory.setXmlAsserter(xmlAsserterRequest);
+               }
+               
+       };
+       
+       
+       $scope.sendRuntimePythonScriptData = function(pathDtls){
+        console.log("sendRuntimePythonScriptData");
+               if(pathDtls!=null){
+                       Datafactory.setRuntimePythonScriptList(pathDtls);
+               }
+               else{
+                       pathDtls=[];
+                       Datafactory.setRuntimePythonScriptList(pathDtls);
+               }
+               
+       };
+       
+       /*$scope.openRuntimePythonScriptDecision = function(decisionIdentifier) {
+        console.log("openRuntimePythonScriptDecision");
+               $scope.decisionIdentifier=decisionIdentifier;
+               $scope.sendRuntimePythonScriptData($scope.decisionIdentifier.runtimePythonScriptList);
+               
+               var dlg = dialogs.create('partials/SOA/runtime_python_script.html','runtimePythonScriptCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+                       $scope.decisionIdentifier.runtimePythonScriptList = Datafactory.getRuntimePythonScriptList();
+                       var resetRuntimePythonScript =[];
+                       Datafactory.setRuntimePythonScriptList(resetRuntimePythonScript);
+                       
+               },function(){
+                       
+               });
+       };*/
+       
+       
+       /*$scope.openRuntimePythonScript = function(pathDtls) {
+        console.log("openRuntimePythonScript");
+               $scope.pathDetails=pathDtls;
+               $scope.sendRuntimePythonScriptData($scope.pathDetails.runtimePythonScriptList);
+               
+               var dlg = dialogs.create('partials/SOA/runtime_python_script.html','runtimePythonScriptCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+            console.log("dlg.result");
+                       $scope.pathDetails.runtimePythonScriptList = Datafactory.getRuntimePythonScriptList();
+                       var resetRuntimePythonScript =[];
+                       Datafactory.setRuntimePythonScriptList(resetRuntimePythonScript);
+                       
+               },function(){
+                       
+               });
+       };
+       
+       $scope.getAsserter = function(){
+      console.log("getAsserter");  
+               var dlg = dialogs.create('partials/SOA/XML_Assertor.html','xmlAssertorCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+                       
+               },function(){
+                       
+               });
+               
+       };
+       
+       $scope.openXMLValidatorDecision = function(DecisionDtls){
+      console.log("open xmlValidatorRequest");
+               $scope.decisionIdentifier=DecisionDtls;
+               $scope.sendValidatorData($scope.decisionIdentifier.xmlValidators);      
+               
+               var dlg = dialogs.create('partials/SOA/xml_validator_decision.html','xmlValidatorDecisionLevelCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+                       $scope.decisionIdentifier.xmlValidators = Datafactory.getXmlValidatorDecisionLevel();
+                       var resetXmlValidators =[];
+                       Datafactory.setXmlValidatorDecisionLevel(resetXmlValidators);
+                       
+               },function(){
+                       
+               });
+       };
+       
+       $scope.sendValidatorData = function(xmlValidatorRequest){
+        console.log("sendValidatorData");
+               if(xmlValidatorRequest!=null){
+                       Datafactory.setXmlValidatorDecisionLevel(xmlValidatorRequest);
+               }
+               else{
+                       xmlValidatorRequest=[];
+                       Datafactory.setXmlValidatorDecisionLevel(xmlValidatorRequest);
+               }
+               
+       };
+       
+       $scope.sendDbSoapClientOption = function(soapClientOption){
+        console.log("sendDbSoapClientOption");
+               if(soapClientOption!=null){
+                       Datafactory.setSoapClientOption(soapClientOption);
+               }
+               else{
+                       soapClientOption={};
+                       Datafactory.setSoapClientOption(soapClientOption);
+               }
+       };
+       
+       $scope.openSoapClientOptionPath = function(pathDetails){
+        console.log("openSoapClientOptionPath");
+               $scope.pathDetails=pathDetails;
+               $scope.sendDbSoapClientOption($scope.pathDetails.soapClientOption);
+               
+               var dlg = dialogs.create('partials/SOA/soap_client_option.html','soapClientOptionsCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){
+            console.log("dlg.result");
+                       $scope.pathDetails.modelPreferenceInfo = Datafactory.getSoapClientOption();
+                       var resetSoapClientOption ={};
+                       Datafactory.setSoapClientOption(resetSoapClientOption);
+                       
+               },function(){
+                       
+               });
+       };
+       
+       $scope.openSoapClientOptionDecision = function(decisionIdentifier){
+        console.log("openSoapClientOptionDecision");
+               $scope.decisionIdentifier=decisionIdentifier;
+               $scope.sendDbSoapClientOption($scope.decisionIdentifier.soapClientOption);              
+               
+               var dlg = dialogs.create('partials/SOA/soap_client_option.html','soapClientOptionsCtrl',{},{size:'lg',keyboard: true,backdrop: 'static',windowClass: 'my-class'});
+               dlg.result.then(function(name){ 
+        console.log("dlg.result");                     
+                       $scope.decisionIdentifier.modelPreferenceInfo=Datafactory.getSoapClientOption();
+                       
+                       var resetSoapClientOption=[];
+                       Datafactory.setSoapClientOption(resetSoapClientOption);
+               },function(){
+                       
+               });
+       };*/
+       
+}]);
+
diff --git a/src/main/resources/META-INF/resources/designer/scripts/query_params_handler_ctrl.js b/src/main/resources/META-INF/resources/designer/scripts/query_params_handler_ctrl.js
new file mode 100644 (file)
index 0000000..830ec84
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+
+function QueryParamsHandlerCtrl($scope,$rootScope, $resource, $http, $location) 
+{
+       console.log("//////////QueryParamsHandlerCtrl");
+       if(!jQuery.isEmptyObject($location.search()))
+       {
+               $rootScope.urlapp = $location.search().app;             
+               $rootScope.urlparams = $location.search();              
+               $location.path('/'+$rootScope.urlapp);  
+               
+       }       
+       else if($rootScope.urlapp!=undefined && $rootScope.urlapp!="")
+       {
+               $location.path('/'+$rootScope.urlapp);
+       }       
+       else
+       {
+               $location.path('/dashboard');
+       }
+               
+}
diff --git a/src/main/resources/META-INF/resources/designer/scripts/route_ctrl.js b/src/main/resources/META-INF/resources/designer/scripts/route_ctrl.js
new file mode 100644 (file)
index 0000000..a6efd77
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+
+function RouteCtrl($scope,$rootScope, $resource, $http, $location) 
+{
+       console.log("//////////RouteCtrl");
+       $scope.getInclude = function() 
+       {
+               var defaultPath = "partials/default-include.html";
+               
+               var urlPath = $location.path();
+               //alert("urlPath:"+urlPath);
+               
+               if(urlPath=="/dashboard")
+               {
+                       return defaultPath;
+               }
+               else
+               {
+                       return defaultPath;
+               }
+       };
+       
+};
diff --git a/src/main/resources/META-INF/resources/designer/scripts/saveConfirmationModalPopUpCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/saveConfirmationModalPopUpCtrl.js
new file mode 100644 (file)
index 0000000..aafcf88
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('saveConfirmationModalPopUpCtrl', ['$scope', '$rootScope', '$modalInstance',
+    function($scope, $rootScope, $modalInstance) {
+       console.log("///////////saveConfirmationModalPopUpCtrl");
+        $scope.close = function() {
+       console.log("close");
+            $modalInstance.dismiss("no");
+        };
+        $scope.Ok = function() {
+               console.log("ok");
+            $modalInstance.close("OK");
+        };
+    }
+]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/soapRequestService.js b/src/main/resources/META-INF/resources/designer/scripts/soapRequestService.js
new file mode 100644 (file)
index 0000000..378a06c
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('soapRequestService', ['$http', '$q', function ($http, $q) {
+    console.log("////////////soapRequestService");
+       this.changetimeoutMode = function(timeoutMode){
+        console.log("changetimeoutMode");
+               console.log("timeoutmode:"+timeoutMode);
+               if(timeoutMode == "Default")
+                       return false;
+               else
+                       return true;
+       };
+       
+       
+       this.generateTst = function(tstInput, generateTSTUrl){
+        console.log("generateTst");
+               var def = $q.defer();
+       
+        $http.post(generateTSTUrl, tstInput)
+        .success(function(data){
+            console.log("success");
+               def.resolve(data);              
+               
+        })
+        .error(function(data){ 
+        console.log("error");                        
+                       def.reject("GenerateTST not successful");
+        });
+        
+        return def.promise;
+       };
+       
+       
+       this.generateTSTMultiple = function(tstInputList, generateTSTUrl){
+        console.log("generateTSTMultiple");
+               var def = $q.defer();
+       
+        $http.post(generateTSTUrl, tstInputList)
+        .success(function(data){
+            console.log("success");
+               def.resolve(data);              
+               
+        })
+        .error(function(data){ 
+        console.log("error");                        
+                       def.reject("GenerateTST multiple not successful");
+        });
+        
+        return def.promise;
+       };
+       
+       this.downloadTst = function(tstId, tstName,downloadTSTUrl){
+        console.log("downloadTst");
+               var def = $q.defer();
+               
+               var downloadInput={};
+               
+               downloadInput.tstId=tstId;
+               downloadInput.tstName=tstName;
+       
+               $http({
+            url: downloadTSTUrl,     method: "POST",     data: downloadInput,
+             responseType: 'arraybuffer' }).success(function (data, status, headers, config) {
+             console.log("success");                    
+                var results = [];
+                
+                
+                results.data = new Blob([data], {type: 'application/octet-stream'});
+                 console.log( results.data);
+                 results.headers = headers();
+                 results.status = status;
+                 results.config = config;
+                 def.resolve(results); 
+                 console.log( "Result From UTM Server : " + results.data);
+        })
+        .error(function(data){
+        console.log("error");                        
+                       def.reject("DownloadTST not successful");
+        });
+        
+        return def.promise;
+       };
+       
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/scripts/textAreaCtrl.js b/src/main/resources/META-INF/resources/designer/scripts/textAreaCtrl.js
new file mode 100644 (file)
index 0000000..1693102
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.controller('textAreaCtrl',['$scope','$rootScope','dialogs','Datafactory','$modalInstance',function($scope, $rootScope,dialogs, Datafactory,$modalInstance) {
+       console.log("//////////textAreaCtrl");
+       $scope.init = function(){
+               console.log("init");
+               $scope.textAreaModel=$rootScope.textAreaData;
+               $scope.textAreaTitle=$rootScope.textAreaTitle;
+       };
+       
+       $scope.init();
+       
+       $scope.close = function() {
+               console.log("close");
+               $rootScope.textAreaData = $('textarea#mytextarea').val();
+               $modalInstance.close("closed");
+       };
+       
+}]);
+
+app.directive('focusMe', function($timeout, $parse) {
+       console.log("focusMe");
+         return {
+           link: function(scope, element, attrs) {
+               console.log("link");
+             var model = $parse(attrs.focusMe);
+             scope.$watch(model, function(value) {
+               console.log("model");
+                 $timeout(function() {
+                       console.log("setTimeout(function() {}, 10);");
+                   element[0].focus(); 
+                 });
+             });
+           }
+         };
+});
diff --git a/src/main/resources/META-INF/resources/designer/scripts/under_construction_ctrl.js b/src/main/resources/META-INF/resources/designer/scripts/under_construction_ctrl.js
new file mode 100644 (file)
index 0000000..69014b8
--- /dev/null
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+'use strict';
+
+
+
+function PageUnderConstructionCtrl($scope,$rootScope, $resource, $http, $location) 
+{
+       
+       console.log("//////////PageUnderConstructionCtrl");
+               
+       
+       
+}
+
+
+
diff --git a/src/main/resources/META-INF/resources/designer/scripts/userPreferencesService.js b/src/main/resources/META-INF/resources/designer/scripts/userPreferencesService.js
new file mode 100644 (file)
index 0000000..b591964
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+app.service('userPreferencesService', ['$http', '$q', function ($http, $q) {
+       console.log("////////userPreferencesService");
+       this.insertUserPreferences = function(userPreference, userPreferencesURL){
+               console.log("insertUserPreferences");
+               var def = $q.defer();
+       
+        $http.post(userPreferencesURL, userPreference)
+        .success(function(data){
+               console.log("data");
+               def.resolve(data);              
+               
+        })
+        .error(function(data){  
+        console.log("error");                        
+                       def.reject("insert user-preferences not successful");
+        });
+        
+        return def.promise;
+       };
+       
+       this.getUserPreferences = function(getPreferenceURL){
+               console.log("getUserPreferences");
+               var def = $q.defer();
+               
+               $http.post(getPreferenceURL)
+               .success(function(data){  
+               console.log("data");            
+                       def.resolve(data);              
+               })
+               .error(function(data){ 
+               console.log("data");                          
+                       def.reject("getUserPreference not successful");
+               });
+               
+               return def.promise; 
+           };
+       
+}]);
diff --git a/src/main/resources/META-INF/resources/designer/unsupportedbrowser.html b/src/main/resources/META-INF/resources/designer/unsupportedbrowser.html
new file mode 100644 (file)
index 0000000..ff721e6
--- /dev/null
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<html lang="en">
+<head>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">    
+    <meta name="description" content="">
+    <meta name="author" content="">
+    <link rel="shortcut icon" href="images/favicon.png">
+
+    <title>UTM Dashboard</title>
+
+    
+   <!-- bootstrap css and plugins -->
+    <link rel="stylesheet" type="text/css" href="css/bootstrap.css">
+    
+    <!-- DataTables CSS -->
+    <link href="css/icons.css" rel="stylesheet">
+    <link href="css/styles.css" rel="stylesheet">
+    <link href="css/style-gue.css" rel="stylesheet">
+    
+    <link href="fonts/font-awesome-4.1.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
+    
+     <style type="text/css">
+              
+    </style>
+    
+</head>
+
+
+<body class="unsuppored-browser" style="width: 100%;height: 100%">
+    <div class='container-fluid  unsupported-image-bg' > <!-- start header -->
+      <div class='col-lg-12 col-md-12 col-sm-12 col-xs-12 unsupported-image-align'>
+        
+          <br>
+          <img src="images/logo_onap_2017.png" class='hidden-sm hidden-xs' alt='UTM Dashboard' />
+      </div>
+    </div>
+    <div class="container-fluid" >
+      <div> <!-- start content -->
+        <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
+          <div class="link-browser-unsupported" >
+               <div class="browswer-support-help-text" dir="ltr">
+                                       <h2 dir="ltr">Uh Oh!</h2>
+                                        
+                                       <h2 dir="ltr">Internet Explorer 8 is not supported by the UTM Dashboard.</h2>
+                                        
+                                       <p dir="ltr">To get the best possible experience using our website we recommend that you upgrade to a newer version or other web browser.</p>
+                                        
+                                       <p dir="ltr" style="color: #6ebb1f; text-align: left;"><b>Recommended Browser Downloads</b></p>
+                                       </div>
+                                        
+                                       <div dir="ltr">
+                                       <div dir="ltr" style="display:inline-block;">
+                                       <div style="float: left"><a href="https://www.mozilla.org/" ><img src="images/img_mozila.png" border="0"  title="" /></a></div>
+                                        
+                                       <div style="float: left; margin-right: 40px">
+                                       <p style="color: rgb(63,63,63)">FIREFOX 31.0.0</p>
+                                        
+                                       <p><img src="images/preffered.png" border="0"  title="" /></p>
+                                        
+                                       </div>
+                                        
+                                       <div style="float: left; margin-left: 40px"><a href="https://www.microsoft.com" ><img src="images/img_ie.png" border="0"  title="" /> </a></div>
+                                        
+                                       <div style="float: left">
+                                               <p style="color: rgb(63,63,63)">INTERNET EXPLORER 11</p>
+                                                
+                                               <p><img src="images/CheckMark.png" border="0"  title="" /></p>
+                                       </div>
+                                       </div>
+                                        
+                                       <p dir="ltr" style="color: red">&nbsp;</p>
+                                       </div>
+                                        
+                                       <p dir="ltr">&nbsp;</p>
+               
+                 </div>
+        </div>
+      </div>
+    </div>
+       
+       
+       
+    <!-- jQuery Include and Bootstrap -->
+    <script src="lib/jquery.min.js"></script>
+    <script src="lib/bootstrap.min.js"></script>
+    
+</body>
diff --git a/src/main/resources/META-INF/resources/designer/utmdashboard.html b/src/main/resources/META-INF/resources/designer/utmdashboard.html
new file mode 100644 (file)
index 0000000..7a24bd0
--- /dev/null
@@ -0,0 +1,35 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+
+<div id="utmdashboard" style="width: 100%;height: 100%;">
+       
+       <div id='head'>
+               <div ng-include="'partials/menu.html'" ng-controller="MenuCtrl"></div>
+       </div>
+       <div id='main'> 
+               <div ng-view="">         
+               </div>                  
+       
+     </div>
+</div>
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn-embedded.css b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn-embedded.css
new file mode 100644 (file)
index 0000000..6fca089
--- /dev/null
@@ -0,0 +1,150 @@
+@font-face {
+  font-family: 'bpmn';
+  src: url('../font/bpmn.eot?5069274');
+  src: url('../font/bpmn.eot?5069274#iefix') format('embedded-opentype'),
+       url('../font/bpmn.svg?5069274#bpmn') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+@font-face {
+  font-family: 'bpmn';
+  src: url('data:application/octet-stream;base64,d09GRgABAAAAADXYAAoAAAAAnngAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAAA9AAAAEQAAABWPgtJqmNtYXAAAAE4AAAARQAAAVq5NgKZZ2x5ZgAAAYAAAC5lAACNnHbOYsRoZWFkAAAv6AAAADEAAAA2BeU9I2hoZWEAADAcAAAAHgAAACQHggO0aG10eAAAMDwAAAARAAABhHroAABsb2NhAAAwUAAAAMQAAADEEJsyAG1heHAAADEUAAAAHwAAACABfwRubmFtZQAAMTQAAAFSAAACPXo4dZVwb3N0AAAyiAAAA08AAAl47YJ7bXicY2BkfsE4gYGVgYOpimkPAwNDD4RmfMBgyMjEwMDEwMrMgBUEpLmmMDi8YHiRxBz0P4shilmZoRIozAiSAwAREQwzeJxjYGBgZoBgGQZGBhAIAfIYwXwWBgsgzcXAwcAEhAwvYl4kvEj6/x+k6AXDi3gIW4JR/L/4P6heKGBkYxjxAACHqQ6BAAAAeJzsfAucHFWVd517693V766qeXX3dFc/5j3T3dPdM3nMEBLIY/KAhIQQQYEE5ZkECAGBhNeQfCAIouIuRBNBBBXYFdhdl5eAigjBdXF9rKKwqDxEWViz3+dqprPn3uqemTxIJ0z287e/X6amqm5V3b733HPPPed/zz1VAhGEPbvpo+QpISQ0CQIkfSQSI4UhKCvZYegBDWTLxjPZ1TEyvbV1+kjH8edan90w9PnY4sovKgWtkIFvNafIU/jkJMwAS45tW3RlR6tT+W3l28kRCUr2kCBhHU/RQfIm1uEIbUJZmMNqkqOgyBE7UervhWIp0wlSUjbDMSgk8qVyuJRxElI70EQ46fjAxvtDkKU9kE7KCpVjwLPAAx3R+/1+st7nu48098ytvObx5sGrw/d0LzkGvEbltcoYUKDTK2eOADH8pIsEGww8esGnsyuvHcSjn7yhdmkDkk2gQSrrXepOv2fsR5rX0EmH4c9VFPhbCBmVpwwvDRkwrHvB66k8bYSo14BjjJAgCBTbeAf9Bk0KASEiHMvapwC2Dqx8GUr9WcgoGkn3OX5qsj1OC2wfpkW291IHd9jlMypn6Dps98Q8ePBUzvD4YUvl8srlcAUhIoVnRDwAFcVn2MES97tFk+xHMc/kYoZ4AVt+M57JlA5SFDZFkLEtN9MXsS0+ISp0CdOFE4TTsUWyqKAwWKlSiGSyGaWEaVmRU9lMqDwENvYLe1oqlzLZHlBiYPuwfzFjCZ8qsmLLimWX7VI5k2W7rGSy7FqxFUzzW/CHr+4RrMCWa66E4PfnrvrR1qD9+beCxq3XXlPZvWSRsnJw+xm3vqSI26++7BcDxa5Tc5fPvurvCfz1xnVPOvGRD6dOPL6za/1AqaNr7YWd3YMDLFUuDwwODqztX3dh8cLSQP8AXtIk+bev3DI2a0byG6ACuUcnOfjBnTf+tq97yboLIXDOnMWdz9163T9F7bMvuODdEzv7+uCRqzY+7Dc2nnf2i2XTWtfdiSV1daxd39U5OFAud3WUBgasgcF1/WuxjjLWURocQB4GkYd3c3mgyE+PsFj4srAbhuEz8B6ZQTaTZ6hET6Vfof8pDiNng4mgVFDKZqJoB3OOgpuJu18x42KhPL7Z49uwVOyVnKxTxD1rO34p3jgsMjHKFnFzegH/8ZwtVlOYZpcsjXfcLJLjJyZWAiY74+aH6gVPsLR7j5hxqTDcWOwVEznHlV5xH3riMieJOL0ao4hRhiUTXgYrC4vnrcICqWPyWvA2KzaK8t9LJWyBxYrFViDRKjuITrUBrE1I+HiTCDYUiZdMh5PNjrZZwJ1tcY2VgXmy41t5fOsVJUa+YvMf8jarfBjK+HBYwUOB58u6NdBqmVgqqyJO3DGLxXvGC+dFSqwkP7JpmBSHoYi8KQ6TwrBeLONjbBphhTA2kUIcqpSyFN5j5QIWzUpnLGzB4lRHGd/8IuN+TQKGPewAvJIiI4QVzzJgGbwCLAqLZZwc7xQr4fjxDl6ojHZeUJGXwZsiQhbuqDz964u2VZ7b5pE9kiFJckbWVZGggiCyqImdkibhny7FcGcJsUFDHSKKAHhUMpIs4Q/lXZIo4U1CVGIoqoKPcMOB7ycaoUG80DTUMCIQStw9BJooo/pB/ayyA26qiKWKKoj62HuSqEp4IYoG7ioFXp6ogZ/9nEoEK6cspYqapEhSQCYy8WN9bj4Fi1IwJ6GsuJBXlxQZL1RVxEoyWB4WquCpiaqKQrE9nDYkGChLi9jujMhuS94HRFXG20iCiVRQtIkGaBrlzcDaAZvME5KoYSZU1KS6Ub7zP5k6hDMHWwWjErYXC5LpeFbFAiwI76CiR0IkzaUHSwa+4RlQX2GPELyr1FgoU6SDimPfwmKxMJaV/xFQWYqyVmJZlBUl0fGHjHCNvIM/kt172Ge8ZIt1qYG/kLGDdaK6VSs8D9Kj7r5XQg6y3yCzsTqkmOhYOJVrJBMI1ShWeNlIrETeReawh3gPr5gMGPgz4kqQqKmSQrFbZYm1UK79XnN7bwz5jzxF1smGjKzHHma9gL2GO5MafMxlRGQUoFygzFCTirrSiE2o8h85xRmtwjakBBS9xaOERA+KAJMCMcBrAM56Q/IitZIqZXiBXCK5dKIU4h3C2S5KlTmYSyauMGIWrwZeECWWZGOlEXkTkXG0eHRNqso9SmVYYlnwPx1DqjWDekmIjRuIMDZYXfwh7s2iLPJuYs2iOMDwrhwBPgKZoIhSi5cdaU3E/1R5DgZyq4YefXQT/Afju8IgA2eKhG3Xan0vwbisUso7dhnreUXTdNAmjR4lInpFsZUJFZduDUf5pJpVPjJVcBnjjk4GEHCsie6QNiaPaLZ7bbcADdtgiFWeSIoRY1yNTNIYuEu8M/kAkJg40pqcogARSlyuq5KmMj1QExeWJVuVLz9jjGZowISfiQv1KNjGmtYyqCiPj04yMQxFarG2asiG6Zz7XskzkUt3qEIV0efBExtuOMCIqKJIVAVFcrkBNMB1GgUdqpUz3mjAyvgKFzLW99gFXrFZ8mqsrSAmRYk9qnUoPp4knzHceVJ0R1k3sCJEsaqRNSmLMqPpYh75qjKplNXJIijXdLQlI8uoGMDnqiYH8S5q/ATuki77MXujpIMo1xqmQrsrrZqUrNkAW0K1SgY5/xUkqIl6PLzLIn4UJ5UNHFdmcGiayHVQAtXRyVWqhKoP6d/BlDcaBI0PaEOWWLuZcKB+5KpO5IqgqqtQHLh+wx6WaYDK490lu32jLMB8VDZwIHIdx8t2NSIXGq2mRqGqSFnpqOAYsaiw0QIyBcZtAGpJ7ChZqylYOqEGXWODvcZ0t1gVOwig3aGSRnVWtB+TshGpPkIVKWsityy0VjcqZpS9yRaQmxtXRyNuZHOlrfSbiBv9QkzICB1CL+JDHwlZIsLoKrbOjyNvwpA3YmvEjUo2YmbTERNx9K4bXjun71Egm6/5kqrccFnvR/u3/iSTPOmc9ZX3zv3YcKHve+eec/Y/P/98wy1wytx5NAm3/1fl/z4z1NXz8g1b35xpN+TuvvaK90aWeFasAHrF+i17Fiz4zC23QNstp685C7ePFvJIp4Z03oX4thWxrS0sFR6DOfBFeJPkyReQXgRlBbOAaApxICbwEqFqsRDuhCoK5KBlmO4FbBG5sLmQWEW1ftmM6whiGDKKezlWYQCwV3Y4GPRwlKs4LlSUGFAVTfyvgUwGOd3rKqglDNAx9Gf6dZMh62EON4czbOqFBE2Awr03jsKHkVpwkRfHTzWkOHnLVuFYFd65oIxvLswTWRO8NdyIddouDXQC4hfdHcFjuVDkzOD4jjJUx9hAeMIFeYUqomQgshBXWB3IatsFdVUU3qs7mMapAjy4adNNmzZd8uFNm/C/oHhlr1fJen0uMsCRJTLjaqOGwL92dpClOJpCNpRlquMMTfYqbzGdTZkYMyTFEIKKkqniFdPTTKIpg4VUR4OjufqbIMCr4iHEGCCxO6jSmRYH174rtIoHEUhIY3+QFCAT2phlIMx8sEr58CHs92z4MivAxxxTGlUTwPSnj4EF9ngCO/FSqhAH8xAOWlizUJMwhSHKqkQeQu1dNTJc7eATiQ1UmQ172cWuXC8ydhGQAO3beHZmVtTdX+b4l+fh2kx3m85pYQbWZQjeUUQX5DC0A6iCyNe5mdZFP+pqPzP2qJIRkkjchHs1WY5IEJIVCdytBTx4wn8P09lcdTICxn7JVA3vCdFb01/UgyoHFWONFawD2YYmlXpplFCvSL0aoh23EGbLIySIgDhIUCujyicIuCXCnwYZvEowQbppk42CtPk0+DRqOWCN4harCllFlzESGj0sCNsnMlW+ZAKPstYjhiKqD62k7PYzt/3MroZ0lXUy6lod8Z2hurZDREtCGcTHbmEygxqaSRFxFSvqbYPjcFdGeDfzQl2jUpMxppIZeqOEwQaOEVjv1kA6oA1Q+RkJxdZzsFSF8vgLSowaSmDcQ/FBCZQJ099oyESoPItVcnILSJ5MquXKHGxjSwHBhCTrCueAC6vwKY40kBR/BsvDhlGx+q9QH+1CgMPkJexitmZZCSvesIyjN+6tyQLbGL7ixWmaisXJAQ8z7bLUi2kc1gqb+lQeYpM5kc3n0FyxNhjAWa4xRMCkRq5iZOqXOWYRFYNBOYZLOfxmmEDk9gyBTXU8IsqU2Dxj3L6C2/8acMaLaLl5EwBhHeMESxGGRl1z7wWCtoQ7nWiO7BCyzNaBEkH7Zit2uWhmi4rNTF4RbZ/rUULLgukegF1bH6b5zvbyE+S5tJ7MZzv66APXXfcAxaMk4TP6MNlBH7r+2As72xsSiNzgOYk8amc61g5fcz+l91+DRx2fX/8Qt7k/pP9C3kKbGxemCx8SNgpCGOsKYpUJrC3YA1kpgRdBvJnAiyBaXccHpksS/puJIt7G/yHAhFKyY1C2zAhiKpvnSWbwyTDPgU3B1uFdZhNx709GwSmypzHIl36ydB0h65aSacvWErJ22dizZNq0hQALp409y8/foW29YHqV1pCVIHAqOHYkoXqD0HeM12jpkyGEoJ02+En/CUUSbMT+9VkgJW/TNCsBg9JPpTKJmx46sLRM3iJrl1bWLmXVLIXb8DwDRqZV1k4bATzDbdNG1kBfOtxqEK9uxM2rrgrFDY+fGvFwui+PbfagYIRaPdiPqpro7kyq2OXUaA2pcuQyNBwx/+WrVq0iZNXloZhHdrq6XWyD/Xw1GRVEQRUM7ikVwo3AnF+mU06YCaV6Pps27P79E088QxaOPfJM9UxGKz+r/JyMPDM6Oir9+c9/5j5XPJTI45hSEIcI4WBhfHvo2qtwI4+PzZnYx3HL49wvpwqWkBR6hBnCAmGFsJp5OJUEtexEiXW+VbJLll3KKBmb+TVtq8R6T+L9zaDYEAJUCydMEebfxEeSzHvVymSZwALPZ3PIlnCfIHbL9KLcnn46XP3UyMLKSwuXpJaHAsfHYjOi8Xlx4532otUdb/VajUNtY+9l+u2I3Wm3t4Sz5La4rnhai6Idlol395cSBlUts7vJgzNtgzyYntse7UgMfqxLN8Z+mC40JxdkE50tC2fIJH//A5DZunUr3EdpIm4xE5hsILAk0B/OTw+VzPZ5jXpwVsJaILUeFw10V35sHB+dNSOpx/IXlFQ15Jnb4syJ0QUtM4dVT+XhcK8B2YheSBvNoX5vuEUOZ4hVoJN9nV6hSWgXzheegVY4Dx5EbbuM3E7eoXPoFvqCaItn8BUGiCFs5S7kfAxZLvdUUSzyyypNR3DHnMGdcMiuRr94yI5G53A9jRyAHb6jUZIO6hR0DtMrGJUO4BQsvq9T0KEu0D4cJ/IH8SET6bBdyA4cqgMWeSQekgPWCbv8OIgP1JYO6gJ1YNes83P2yiumDy2WZw925WZ8JNqV67/sZG+icfGaaNQnGqpfOeWU5qg+W/RNxZX4dQSZR9KVKMEon14eQV+iNvbdw/cliuTmD+7gk8YedIHrkfHw+eCeOh6+4CE5+MR7ET1NwR/+70fSHa6O7Tpi7nCR/M1hO35FnN2IH8DzK37miDhJvaTpCDhJRdI//9IrPxQzrXOvvaDFzM6/6PxY3HfyFf3pzlyxRJsUSWssFOR/P3yvIw6PI+R2nMFH2hF3O5KvHRG/I1w6RcffF5l+O3KOP7poap4/8v2/nKscJ49H1Fde+c4UncLI+Kl5hXGOOXU/quthmqondf8YhnnC8inGMEQmuzXzk/yaUw1cCG/ffvn27Wek0tu3z9+xY4oRCqctXnzltm1Xbmv4/ILPf34BmyIp+/FitjBXWDg1buzvdZ4iE5r28klPiQV37++x3js+Z/aB43PKfQit4yh7cXGYxMmw2EuGSa/oJwg0DxKdswuVgp9F09xwAzv6UQjFG25g4nqAuwcJ0Xmg3m8n7tb8JnteobeQ32O/8r60eIwN4Ky1TG/xVv71ip6uX/wyGIDHuruPWUB+r3x2WmfPq68G/PBUV89Vn+Q8uZnupA5fayi4vpeqPLC5bqa20HCwIB54+yt/jvhvvPZyMHYu6Oz62SfC2qaHZXrThWu/256dtzp1wgGjcmhS+vW9t4wNT3MeAema0a9q8MkHNl30d1b43HPO/ek001p7oDAbJss60vxZ+l3sx6CQEPLYk/NQkk8QThJWCqeyXnVYG9zVkmobCmxWzsTaXS1xc0yS6/EMtWaaPBwn6IRxrCuTdvgDkG3/kYmd9iqEN154Ydj6h+tLMyXp1l80W+svvqyy6/HY8eVH1kvS9c+GfNdsXP+befPVpYWbT6B04wNe/arzz32hv9C7qv3MNdBT+W2l0vS8+0eT9Onbr6/suUufP/8PW7Y+n/TlyGOfvObt4eH274L/kpUf6xAfGr3yx11tc04/688fmXZsL/3iJesfi0dXnHHWL49rTXzcqNwKVzZUHoFsY+OChoblDQ2LGhpQymtzcrY+s0p4CMfRCOyAMTKP3Ei+T4P0bPp3aGFGDrJaczQS6Wgk0v/XSKS9Fql6jwYjHQ1GOhqM9L8xGGmfNcLPHg1HOhqOdDQc6X9jOJKgjs+bGI5sEVqFlNCGc8g+d7YQ40tc45NDvgBqvy9+3vXUHkna85R7vP9Xovir+/nR3BcRj2d6ak9XLRMe//nAWFcfj0Vy15/WCC/CCngY/kTmkL895BUnejQ46S8VnHTIqy/DRwOXjgYufdDApUPy/cOCowFNRwOaphbQ5MalLCU7xuNSzEQRqvvtE+EoZMe111b2uDv7CeG/W0dGheXC17iHchAQBsl48oE5CBHLHoBcDApWeRDypWKOvTRZLOSZIwttTWII+jNKoljIDUFxENPMoCWzTrKvXykNkyHI5jJZJW9b9iBYMi+bcA9vwUKNnstbEbkTKWRnJ2Em8AavGNOFvGXypJwdZKFMg9ADxVw/1ssCYXIl2OnxdJ60sTOkojD7F097+echC+zQE7vDjVRubKpAT4NpW5WXXrMaGqw1F3047PHgYNJ7Ah6q6T4UbI+uovLVG2ydCajXE/7BmogZMd+AghkOWZUXgTaYEjVDlT3PhIIQDP785cERP/ahGmp37u3wkFG1ZdqJ8YHoUNRMm8PDAKZlh0xfsDkKYWjstdmxwW5i6lHWe4KBlC/AQJfPSPhl3bY9iLywo60uOxrutKMNjQFP3G9GQgAzZ5opMzrUXI7ZG1oUoda3l2EfhQRTaMa+7UvmZDMYKSTyxWB/FjsoISWktFRIBxMXA592k0q88gZ5r7K1cg1sJrB5jJBRIGOPomAdjwr516+98cbY09V3SH9BLyGv8PgoFhvFkVQimIAgdkiwEEwUE8GLKRlTyTtjIVhdeRMa2qCh8iZ5RRrDivSxELm78mZb9T4jVRyPJw8gdusSBvaLJnfsmn/UDScvKO/jD4R3t766T1i5ev1L6clx5ZcfP9mDQ5Pk9j/uHVlO77raDS1fDuIV67f8YPI8cRKtbux7d73Id0lWsrRUtqlll5WsUj/uHbKFwtUbZs3acsPMmbHolfm6se8vnX3OlytfXXbSHSAvXjh7w6cWHfj92GH+RvPUVlPcyLOprqJ0TESXTXERZXU1eOxA7Z0tjEy5vZN6Tlam2uyf7NWvTQ1TbPvGfbo9kxWq43NivSRTd72ktkRWd4nEXfqqtyZyV21Vqzau36VfIzuRFkfICv0HiVh1UIs4btRqGJVJOQoTA/ynx55MyMnHksFZ7Dxr7LtksHsGwIzuDZUHL+6ZDjD9KYhUfnfxokU9ixaRnZilstLNCvfhuQ9zVlayX/RXdmIa7uueUbmj8rvf26Ue9pP96Ow8DDqRxJ+4dZFpVfKeJdPGydvQPU5e+oVDJu3te3t7XVs7Tle8frTv+9Ix9iyn4mDVu1V/MPnhg6Su/NSkv54EXVIT6wON6TnCoimOaUwj+2z2Xn/Wx0K2p6zMkgPJ1hmtm4ZnJpNzgrlQbKov769+fnXiuMTW5y65YO2C4DSleB5fG997PXGpcLqw7sisJNo+UnM8oJUlNcdDYR/PwxFaV+w95ty+SbNocfqpE9Po7vJe8+gprjmeAfMmT6Vg/oUHnEvtjT+YzGddv9FB32bbX4rqmvXL95eTOnb9hf0lYV9ak+7bCHXevKta7fokTrbLdYj75rjldWM3Jt5NqPneDqbta+8nRA8QV1/v7QIL/lhJ3HTTPZCovHJP9Vz/RYG5Tz4JV47Onj278brrrnPxESo7CTFyA46oacKxwgIcVQILiI+JOKFhJJd6xNIwSAlkJt5T3Fs0y062HLELpf6s8j5nuIacNA96ZvapAyNh2JrtD8S0/MwumLMsVLkKVs5tTRP2sLSwcl9rly/uyc/oAvAHkwlZflGW/1GSHpekTbL8A1m+V5LwiGC8sGLhrBnThuZ363ZHJDt35oyZs08seIyubCe/P687kg7y28lA2mwvAs4GNbgYdMD/DXtdTczj2ByBsP4L42yA4fj1MAqju/9I1cqVZPTHPz6nEoVfPV3NP6mP6/bsG6dcRshlp5Am9zz2OmnqGgAY6Bp7nZ+xwzaurNy4ciPBM2zE81ood1Ru7CgDnmFjR7n6numEXzeDEjX7IB7dQ9Rj7+ffve9wNNP7+H7/8dB1zt7v0DpCR32to0RwfiXlC9jiTDnCvsNSf0gvY9/NuOii2MxY8aeV57bVHdb/b9s2GMhFpimdvtNOe3STq29cG8zo7BZmHAARTBiUUFU5RvYywMokAwzvfqUybm27u1+63vJu+7VPv/26q/YsXqSunHbPklt2SndfvfFfy8Wu0wpXFa9+COhfb+DG9iOZZWgT/u2+mm29dvOXPSRHfnTnjW92t59wwYUQPOf4Rd3SC7deu7PJPPv8te+e2N2TE//h6g0PVo2rZf3PzBPcmLsyGgPlSETanfraa/fcUCh89JVXpgglNuTzT6751uUzZn68dP3+c4NsfWxXM3N1wd04CKobM1WzabUxcD/9e9o8/qZVA4v0CSaKTrBQBMUu+2FiJ/dA8NVXK18YmTHyQ9xfWsj3hbS5cffXc1TKVzbPGJnRNWNketf0hfzM23s/fRDL9whzhWVYoY+hJNayGEDOVrJlOYsHtOP8WMaDWSonmG6zmTvKdvjXn7JWnChFnCixj34F5ezkUkbLtw2WaGkAjwBPm8vbaXdf2/IIZJoWObOJosxxFgXMynENceiHbJdnlUG72mYe0wNN2iKyCDU5nI2PItB64/x5Ay3sOGgVaf/AbQNlUizfBh9a5MwBTcNSoDkdWd5GunvblodFKwytDZVPZlgxsFBr6B1G/Nepr/Ji6cXWRngispkVdwMv9P/UMM5EbOG5Lno8wNe/cn5q9hIWYVj9BJgbaFj9EJgbb1gYJix6yQ07xJTSNwh9B/sy2CZRJLCaeTW9bHFy9U3c20+oeNNqdvYyz/pqIKIY2j8jWzjcJ9snDhKf+OwhFrtv/eKZmLFp/9r79uNdE7N/B+QdSmminLUV52CBmLBF+cFS0Jf+5LF5r887SENelT43NrZ568svu7bXrd8vhNH27lVxUtHo9L1rwvI+A1tYdXDZPoV7KnNdMvaXCeZ5O3C73sfiHrSRp1xKyKWnuMcl5xJy7hJ+PEiDXxrPf8qlZi0/HvfVWx2HorfYu618SlRfdW3Y2pr66RkfUVfFFtTTXifCN9avHTlm9m/mNzTtp0+ThzJXTtSnh4HweoScef8DVUx2O58Xsvrd2kO2JdbmgntP9ODdbbvS0TPXrwP/by4OW0/emG/f8DW/cck5Z39/YLDjtI6z0Lh++6+27BFOWKzdsmvLJ74f93yS3HnR2sdTiYUfOev1ea2JyTaEvUfZglh/cpsJc93v511KMNTltvqaK1irT/7ZJ1pYm29e77bZObHjvPNxSHS0ncfafd8tu7HdD4MM4te0mx/YdPEj481esXjx2FWbF9dkd4L3jtBePzKYhRxLDEPVd3ZtWrH8pBWV6+GO79XriTuOw7/Wm26C0N2H7zupAoe65DBEUI+Qi7mxP0Ac/TFo+6boNTkA8pwixrl7X1w6JaBz576o1cUW++K8I/IuwZF5heBIvTxw+OsRtSHJ0KqTPRSvQG1wnn/ah9FkfbjuHOJhd5T2zZ7z8stzhNo79eQd8iXUGWHBQjrTbN0oksMZZ1+umMxli1LCLAQTYDtZ1/HLzCjD0n+CXfDlyjdg9r0VC+Z94QufW79+5bKFC9evJ18iMHYpvE7uItLdlQTZfEdRLpw8uGblypNzi6r6YWK+epbwjUPwRuSqi5k5WXH4YqZs97GlzEQuXy4Vc/3ZTLaAqXKuxFMl5K2DD9xlTJx6umuXuRJfu2RronIckPc5d93SUUw7z763wD4PkcvbbOVSdthyZiEGfOlSSeT2XrjMsT7M13OIvObRWsqL4wYL/lL0wXZo9Xs0nVLba3ioZFBJC5lgBaKKbgb/xRMME1VlkZAiBakhqLEwMpG8oauqvuMlQ5aNlx7ysoVtKnq+vtWD+fTKq6lOnYXZehqtdS34rK6zZY4cShXMTKQt1NDS1q15/EEdK1O9phepSkZANoJByxOwWgyDRECR/AoSokgsgkG1VEiCrBsKOBLxqjQFVEcykinD9obSgdaAf36Q8ncs0BhFyRacvW0WPie8J/yn8Ee4kxRImUzHMRDlS9KykmWvgziMxexjHWaZfSXBZEk8FYql8iCUynY5WyoXik6GdWA5i4KXYRFSfTlMZ7J8fdGKA/sMrGP28E8m5CxM4pwhy37SCyioxdIw4PSBS8cwYEfb5mQCWD72yJ4OplJAGnJYYt4tlF2wkHw/kz2cbWAFfmDLmVgy1lHoZbqq38n2Iy1YYbEPx4tSLJQn1VgulC3Tsc2sknRyfYMkmXPMJJt25/oiDJznTPwfAKTHzA1QN2mZuT4zx46YIYL7IETsHObDI3seQTGO5Gw3g2XafZEcW9uP5FxohS3CijJOrj+X7eP/LN0JmUFI4qOc05d1cGT3dbKC8Q6S1JdTcoW+6ZDH8nAEYLqQ67N5wi7kc7Z7n9VWMHGAYCE4/vAJXiChTInlUBsj/dkByLA6e7BlGRwrfXhARcKozswEvBgATlWxP4vJmTBAcYyWWckDBLORQeAhAYVcf0HJmVnsgSzcFAj4fZliJqQUi6JXy5bSCcNDJF+qlIkmRoJ+vy/LHvYXqSLr6VKq1dCVYKqUirbOPZYko8TpTUGxYSTTnQx5m5Lp3gxoLOC6v18JQ7o3RXyBYIC0RvOBoD/gzRTTIUWL+4KJDvOyQY2F3epBLwvkSGExuiKL/QXE4ZDpyRBvIkhmEScKmd4U5dGVPMSThT8V+1mmdE/aLf14QgYD7GVTKRSKpsSJ2HWg1gkdXclgMMlCk9yQLlp9gYBFLInVuCV+wXYZ3Ggsfr81gGS2LTJptTgek5VsCQbhq1JYlHWyheZEWdHSxXS0daG/FVuX8oNEdSOBIwN5Viqxx5lSGhkZwNani6mASK04/iAs90sF5FCqJwWJVssfOak7Hiql3Bb5CeMstg9ZwmLYj2lu1Dn3i+mWRDDZeUJY9TU3IEdkjXGuJ0W8QT8yCwhq9nRvGjQfhWJRDWERDiGyLPN3AYDFcgCWx/st5ZYuosL0aloeVG9fjLGFBd1WucdZovCwOBbYnm4JRJZ3ZUI1bhAedVVjDR6DKSQt0JxSWIiOSKuF8HLwSsH5ZUuvocKnCWnXNKjFa3jIKM4h5qCt4l7oGvzgX+4pWOVEsd/9akv18z35fT/f407K3O/39JdrH/Cx3E/44K+TCqZ4MEypzKdz8DvpGFTZSdubjznNRgDORBK/F/C2pFpLXrMZFn0sEulZqEMLDjwp00RXzDpmBW1uR7Nmp1BRl9/y+4MJowlWqZW7FTiZNBrxoKaLp8w69hQyCrBoZrQQESPBUJM3GtgJsNPXbDSFQ7YUyUdnLj5Rt0OKrEbzIYkQv1GaB3B8yesnRArno6qitn5T0XTL02h/+9Zbb5WkW7/d0mBYmiyW5wLMr+K7CfteEMrC0CFY+GQuyeJgLPb59mKwP4MqSZqOSta2hiFYd+UhBZKiSrBLUhSpMv3F555/5w1FfqOSrm8Qj8Uf3Cmp+OOzJKVxw3mjlI5WnhBqsTocG/lwDm7vi4sSdg0YuUgIoWQNCu2PgGp++olYmrpxNIcSL3OwEBkX8R0Qb0812mTc+XikFmiP1MLsAX3IC6Y+u5iMyqfa5v0w+5SafvLeiJ69t7mDPobtV4UgonnGgfnCSuGjwiXCqPBp4S7hb4QnhZ3Cz90Z8N4rpWE+Jy6X7DyiaGQKl0j+2aqM+90q9pTLa5lzrFzin7XKKHs/lPb+ZY25zDHbzx9aspuXffVqUt4yvzTHS8JL7i3idUwiwf0qVvVZ1aGyD32wa98l3WB8ZjTkN89YHVFC+RciejA70/Q6UsP8Hjq2K2Abrbmg6HgjQ22a578CCVVq8GcWOhF/4Lg3gnFfU7dfQpA7lPJ44ONh3d+S8Xgd0dublMe+EzQYfPakiRdP5K2AQaHRlhxvtFkk3t13B7x43ehNSrbNvrb1u4ChJiycw0QzMnjH7guqRmxBZ8QbWFKWYXuwNdhUagqpkd5VbYZeKYdUf8fqYkQN5z6UlUlDoNHXOi8d9JqlNR26QTL7LULDKM4yjJTYaGU0Y1laj450+oORwooE0Yntic1rwwb1LGk1moH6AxGRev1iyohnxYge6WsxAwGnHDFapiWN6PGZYMDsPrFV/Gqzr31ZNmhE2pa1677uRl9hdXck4C99fEjVkZz+Nd3+UKT7zLzqGWj0pWZFI5FAekWv5ttBWj1Ov5+kPPFZ8iIxJGkK1dIAjQ1GLEOSerJXh4zq6WqllFqK2awhAz19KaP5f8Q/UHPmHIHVnyOy7iPgbLv2zok4aYVlmfA4HAd3wVs4V9rurrcc8E2Yo++a/MXeNTlt73eNzjj6RsnRN0o+6BslLQd8H410H32F5OgrJFP8Jq64j183+v5eXdc27uvN/dTFFy/ffxqTL59UPqP2XufEHK8kLBROEk4V1gjnH4ov1weRGMXJcWEIeBiXUqiGcTklHthlJyPTId/vKO9zrjcZ/FR/e3O6RU52e97qcaRYqgnac57XX+wIW9CSikqJ7hfTgbAcSzdCW5jSK0RxrSiuE8UFonilKK7GI/Zd3XnjqnihO5tyUl3NcktPZyqVbuuLyUqz1cTvdjY3RGx+tzemKMfV/vfxffMYwXr8ikOZxX8p9VrtvP12pQN+/HZ90k+99tqRysuQuqT2Td1BcofgCP/d3rXFxnGV4XOZM7Mzs97duc+svffs7MaO7Zm9+FKrdlDSNKFxiLAqlcZ2JUIacquhIhSUooqKp1IVHloVUJo0dQUSgjyAWqnq5SUvRDxweQBkIlReKkV5AKQKIYRHnHNmbW/sNClysVTL65nd2XPOnMvvMzvn+893vhkHnwMnwIX4KW6SxT2TWh43JtEo6zXxNoSlRh45KVweQjUuYzs6Qmwnjxrce2HFEdbdQrQ4BH44sTA7LorjswtfX5i9j7CDiYmFYyOEjByjQY+OEjI6mHugWotuymaOp8qZMh7rRH7cMPQjxcxZnz0UvWPlTVk28xbcf+gQtHKmQmiMpucMRTFyupZTRHoRPZJW0iyAfty/EpW8e1h0Xe+zZNnq07k+8Kv4XVzi+KsABsFeatV5cA48c0fEVe5AIYZj1kMueoVwVGN3Fkq1fPjR4GlVM3gVA5VigJTv+BdYgg2oyCp+Jq+lzeBLgSUZw9dNWatPOJliwjuwhyz/I520ewf0hJh1hVKoeqgH/ZzCG+x6FN4UshLTEqbwBvU6FEjF8OYqgygPVvW0OXK8n+kJUwSza2ZPT0GWtFT/0TK5I2p5loKWqpBEDBIkj1LYMj2Qso3w4SJWsWplJ0vJXiOTmmqpekZORb/q5SBES49emEok9GyqSUGIZg4ebzCVYWwnrD5FreJkSNEERRr53UlC0ikHKpU+krjz+pu94MAmZ2G7JrA3CTK657c3N/PaNf3d5RcQaat7wW4wRtv8MDgOngTfBt8Hl8HPwNvgOvgTtYNf4w4PkXk7Rm28bZwC6Ndnzv6R+V6Su3Z9cHB+bm5u2/kE4GtHjlxcfub8wrkb+/fto1hyG7gDuvou01y36J2qwX9V5+ho4wJ4DvwQ/Bi8Aa6B369TYN8evbZb8P2hbddh1zTmf7ot+ur/hdvCaVqbdTufPbPC4/ok/M0rWorxWEcA6h1GOxuYSVs82qndTmQStnysA/99O/kJ/n1LBzrxc1HOIJs/mZnNVTJL2TH/crTN7cdMBQ/cd8r3Z5rjp5v9jw63H6vqQ+6umfqDz08jG35ldnH/N1OJmeHaHlGYfehqfcwbymZHvqGux4AnwQ/AVQpAX0VDH2t1kRRuYIAw8oXV7BBAat0UkCnYZis7YwIII1pUVvkfTsz/WKF/jMM1/sc4XEcA6bA/1oqOuR8jTtMqoKBhhk5gMt9fO+Z+0LyYymFFup38UeuQP2ptv9aqjKNWpeYzXUoasFZQAZY5b6MchBXGahClkHE+xiDne4Sc88EPaZqGxcM7zA+WOnDoB62NHZj2ODQbZhA6LHyN3xHW6Ik+L8IPK60Ky6FGy2oHlbBD8qAbjazEhA/2HvM8GrTAsBmwzeHvzTFO+wibDU74sFkA/c6SOXRrOkFzjeLBqzcEKRYst8PAH4OtIGT1aTGSB2L0DxrVovViKdkh435w5Mgy5fgvDBq8zPBeiPZxPSE7viOTUhklBNc3nSTEguF7GT0kiizLkud7Ki6VYII4NcMhIsSiWXMy+p6yYOqC5RrlzKCTc5JSMm26DnPWIFgs0ivQdm0hobialpN1WXJ9V8VYSyiGlzxSllMq86WIhmfTMwiEhQIUVOS4jpAwFaEsWJrguIZERMy1t4q+uJqjhXUEcVI13RWPJkq3emkNFKfjR+todnH3DoIdz1oXXYG/DFkxXXewZ9WJamqqzNxB98T2LdJH60wblDZGZC1BjUYEkbiG7zLVszzzK9PIjA7bsi45vkEwFEXb4FZWWDux7RppTZF7RvJptUKthmVZleNW0zZSi0i7Mym0UohqeIFK5ELsj4SCYLg2PUNhdjJ1TI2GSQLBUhFSGzGrQSnB/KBIKGO4mqVIPEgzMZFISOxwjlkbtOJqz2jOS64Ygq2S6xxY2UCVMxbu0Ddi2zJBP6T1SQL8n9fF3as33tv2q/oeE2gaSPT+2EN/d4lD2kQjNW0QalX4r+hNQofl+6J3leh36Mnot2j6b8KtmzfhX27+ITp44wbdu3wIDKv1gX5wPzgMjoHT4OmN6GxLb6kbENQXtv6eejvC2beFd9SNY7upzat2fCKCHZuX6mDd1lzVfO6ekzwGfglleBhegRE6hL6LfoN1fAq/KSDh8N1mKHfEn3fEn7dU/HndxOyJHfnnHfnnHfnnT6X880fMiw+zf8GODvSODvSODjTvNJ8mHegYF72FXlh71mpJk5hgFx08DuPnwuUvPj8/j15Y/h76arB8C1nLt/hc+UV8DRf5OSlg0fFm5+msUHKY/FiVjlgYr+8J/5ofHX399bk5NDM/v4iL/3kaf4ft0V8XFxdOPXEWnl5Y5PN+l/CLOE+PZIrNNJqjxxEapH9V4tTWyRrgF6PH90ZZD34wCXF04uWXpryplye9yUvs0/d8nD/3WPSWDw/OknPvPzJQ7R/u9wfaA9WBIFvNxs+K/Qn+BS0vbnNcXgFU+YpYOkgmTESN7g6XUyOdnesn8qMKi2nD4ZPRlaUrf372Qn35Wyfhh/X6U5eXL11+6v3P4/zS0j9P0le+fv6VLy8tXZ6efu9r9Yvwlfr58/X6fwEAfP1sAAAAeJxjYGRgYADio9r3f8Tz23xl4GZ+ARRhuFjx5xSC/t/OfIVZGcjlYGACiQIAmCUOCgAAAHicY2BkYGAO+p/FEMX8ggEImK8wMDKggkQAZVcEPgAAeJxjfsHAwDyKBxQDANn1WQwAAAAAAAAAADIApAEKAawGyAccCkIKggs2C14LeAwiEWwR8hJ0Et4S/hNYE+wZEBliHKocxh2YHcYd8B5GHpofEh+WH9wgMCB8ILYg/CGAIjAihiLQIyojqiPCI/wkaiS+JSYlpCXsJhwmoidAJ4AnrCgAKEwojCjGKQopVCmWKhoqjirgKxosCi5wLwovbi+WL9IwSDDIMioynDXMNfw2mDbgN4g4WjjUOjI7iDv+PM48/j9OP4g/qkB2QOZGFEYuRlZGjkbOeJxjYGRgYEhkSWIQYQABJiDmAkIGhv9gPgMAHksB8gB4nF2PvU7DMBSFT9q0QCsxgEBi84AQAin9YUD0AZrOrdQ9P07aKrGjxK3Up2HkCRgZeQokFl6Ek9R0IJbj7373XEcBcIFvODg8V9wHduCyOnALJ7ix3KYXll2uW8sd9HFvuUv/ZLmHRzxb7uMSIW9w3DNWD9hadnCKV8stnOPNcpv+3bJL/rDcwTU+LXfpvyz3sMSP5T7unJcoyLcqDsRClrt1JCvh5+EsLHI1l+k2C8oa672UZbXWSoy8YV36UskyMDIW4V5Uu3RsTCKSUudiqpWRWaZFUeqNjIy3MqaYDAaJ9V6kc0QIkPPnFGKSwAISJXZYsyNR0fjsh5hxFySFOX3KiYz58mj/zmUzX3FesxIYwcPw2PXZVU0igOEZMxFiz3fFb6YY0xokrBNmNGcEps1NdTrj0jRF09vQRPQeVs1UgQkGXMm/vMcUb/oFZv1ifgAAeJyVVfl7EzcQ9aMhaWyHGDsEShuOhEChXe6e9D44erdA70tezxerkaWtpE3Cf1+tJHs3xOvP9Q/7eTWamTdv3sw2jjXCr9mY/mONBo7hBSzgOBaxhBexjCZaaGMFJ7CKDk6iix7WcArrOI0zeAln8TJewQbO4Twu4CI2sYVL2MZlXMGruIpreA2vI8F13MBN3MJt3MFdvIE38Rbexjt4F/fwHt7HB/gQH+FjfIJP8Rk+x308wEM8whf4El/ha3yDb/EdvscPeIwneIof8RN+xi/4Fb/hd/yBP/EX/gZrm1TTfrKvSabD41YzM+zsMEv77FmSMc2EIHGeS0t6RAPuDAntkbRJymw6dE+ZkrhVa5dKJt6o88xyuZOMyBi2Q2eMZdqOr6pRRtIwy5W8XjUc8R4DSka5sDwT1BJKZcmI6V3Sy7khnVhmdlf6ueHSZUp0LqhbevF4dWtmFsN3JBM35i/K8hHpa7X3j6DeruezQkVr3IYDpZupkpLS4rhDcjDxKdjfnBFNDnjhc2/+Wo6APXW4VTHi5kwGPSFnDf2bOzNnFeaTXZVxWhwxmTOxpCklvkddk/eTTKu0aFm4t1GNfwTTyarVpVW6XqKhm+dq7d59vUJqpQVrDtgYV6qEYJmhQa9ySAcZkwMaLBSyWy2D+KBb9TlNyoTPUI/Lc7h+qNCJV7d6HArsHtK8H4NFN9o8swvG4VpxriJhTkF73D47xJ9P1KuexCE9PQWbazVt1GIWXO6uVViYAF61dGATJqWy/n2pn42cZtTqWOMF64IOuuN3H6DPHN3t8VGRujl+UbpX5inQcOksldkIrJwoDwr3bvk6kVLlKJRd8SnquVBbbbw/bZrtUKv956RUJTgmbw6YZW50sty2wkj4xi25RbbHU1ooNlo7Dom3tLyD6v/jdkHnuRGkaXoLQMpGXKyvJmK6O/+uKMNOk0RIXVB4eeaymOyUWFxuCzqCdn3Ry4WA/b/Al7FK05WZMUtk09oXkMX23f4fH69I0c35XYIMp7EeQcSQl2aWE6GusEEyVGlcke2oksBR8fAq6FVVF69uz44eMUzboQFlqOLO/GWXPXW72/KUuzVpmyZjBVylRKf8noX0TcGMUd7WaPwHzaxe+gA=') format('woff'),
+       url('data:application/octet-stream;base64,AAEAAAAKAIAAAwAgT1MvMj4LSaoAAAEoAAAAVmNtYXC5NgKZAAADBAAAAVpnbHlmds5ixAAABSQAAI2caGVhZAXlPSMAAADQAAAANmhoZWEHggO0AAAArAAAACRobXR4eugAAAAAAYAAAAGEbG9jYRCbMgAAAARgAAAAxG1heHABfwRuAAABCAAAACBuYW1lejh1lQAAksAAAAI9cG9zdO2Ce20AAJUAAAAJeAABAAADUv9qAFoD6AAAAAAD1AABAAAAAAAAAAAAAAAAAAAAYQABAAAAAQAAxSvf+F8PPPUACwPoAAAAANF4/MoAAAAA0Xj8ygAA/4cD1AMjAAAACAACAAAAAAAAAAEAAABhBGIAFAAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQPoAZAABQAIAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6ADoYgNS/2oAWgMjAHkAAAABAAAAAAAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAPoAAAD6AAAA+gAAAAAAAMAAAADAAAAHAABAAAAAABUAAMAAQAAABwABAA4AAAACgAIAAIAAgAA6FzoYOhi//8AAAAA6ADoX+hi//8AABgBF/8X/gABAAAAAAAAAAAAAAAAAQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgCkAQoBrAbIBxwKQgqCCzYLXgt4DCIRbBHyEnQS3hL+E1gT7BkQGWIcqhzGHZgdxh3wHkYemh8SH5Yf3CAwIHwgtiD8IYAiMCKGItAjKiOqI8Ij/CRqJL4lJiWkJewmHCaiJ0AngCesKAAoTCiMKMYpCilUKZYqGiqOKuArGiwKLnAvCi9uL5Yv0jBIMMgyKjKcNcw1/DaYNuA3iDhaONQ6MjuIO/48zjz+P04/iD+qQHZA5kYURi5GVkaORs4AAgAA//wDugLAABIAGgAAASIOAhQeAjM+ATcHJz8BLgEJAQYWFwEuAQL0Kks7ICA7SypGahaVdD6dHk7+3f4zCTMmAcMbJALAIDtLVEs7IAFPQihNfCogI/7q/sQiSwUBNhc+AAUAAP/AAzkC6AASACMAKAA3AEQAAAEiBh0BBwYUFyE2NC8BNTYmKwEFIgYVEx4BMyEyNjcTNiYjIQUpAQMhEyIjDgEXEx4BPgEnAy4BJSIGBwMGHgE2NxM2JgGtKh2sDw8CcA4OqAIbLkf+4gsNMgENCgHJCg0CQAENDP7i/v0BAwEDO/5iSwECDA8CLAIRGAwCLAINAQ4KDwIsAg0XEQIsAg8C5wgsCTgFFwIBGAU3CiwIzA8L/dUJDQwKAioMDzH+BwGwARIM/sAMDQMSDAE/Cg0BDQv+wQwSAw0MAUAMEgAAAAMAAP+aA7gDIgAQABQAQgAAASIHAQYUFwEWMjcBNjQnASYHCQIlMCMPAxUjDwMVHwMzFR8DMz8DNTM/AzUvAyM1LwMB9A4M/mEKCgGfCx4LAZ8LC/5hCw8Bhv56/noBewICBAMBwgQEAwEBAwQEwgEDBAQWBAQDAcIEBAMBAQMEBMIBAwQEAyIL/mELHgv+YQoKAZ8LHgsBnws+/nr+egGG5QEDBATCAQMEBBUFBAMBwgQEAwEBAwQEwgEDBAQWBAQDAcIEBAMBAAAAAAYAAP+NA80DIgAOAB0ALAA7AFAAYAAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BBwYHFwYHFhc3FzY3Jic2NyYnBgcmJxYXNxcHFwcnBgcnNjcmJwHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFFGKyxwODYqLG5xKy05ODg2Kiw3Nzg5OThuNG9xNXE2ODQ4Nzg5AyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWby0rcTY4LCpucCwrOTg3NywqNjg4Fjg5bzRucTVxNzg0ODY5OAAAABEAAP+jA7gDIgADAAYACwBOAKYA/AE/AZQB8QI8An4CwgMFA1wDqQP1BD8AAAERIREFMwc3FSE1FxExIwcjByMVIwcjDwcVHwQzNzM3MzczNzM3MxczFzMXMxczFzM/BTUvBSMnIzUjJyMnFyMPBR8ZPwQ1LwMjJzUnNScjLwEjLwE1JyMnNS8BIy8BNSc1JyM1JyMnIy8BNS8BIyc1JyMvAQUjDwIVByMPARUPAhUHFQcVDwEjDwEVDwIVDwEjDwEjDwEVBxUPASMPAhUfBTM/GTUvBCExIxUjDwMVHwQzNzM3MxczFzMXMxczFzMfBjM/BTUvAiMvCSMnIycjJyM1ByMPAiMPARUHIw8BIwcVByMHIwcjBxUPAyMVDwEVDwIjDwEfBTM/HTM/Ay8DBQ8FHxYVHwQzPwQ1JzUvCDUnNS8EIycjJzUvASMnNSc1LwE1Iy8BNScjJzUvAjUvAwUjDwUVIxUHFQcVIxUHFRcVMxUXFRcVFxUfCTM/BDUvAjUnNSc1JzUnNSc1NzU3NTc1NzU3NS8EBSMPAxUHFxUHFQcVBxUHFQ8IFR8DMz8GNTc1Pwc1NzUzNTc1NzUnNS8DBSMPAxUXFRcVFxUXFR8HFRcVHwIzFR8DMz8ENS8LNSc1JzUnNSc1LwQFIw8FFQcVDw8VHwU/AjU/ATU3Mzc1PwIzPwo1Ny8EBQ8FHwIVFxUXMxczHwIzHwEzFRcVFxUXMx8BMxczFxUXFR8BFR8CFR8CMz8FNS8cBSMPCCMHIwcjByMHIwcjDwQVHwUzNzM3MzczNzM/CzM3Mz8BNT8BNTc1PwQ1LwQFDwUVHwUzHwEVFzMXMx8BFR8BMxcVHwQzFzMfBjM/BTUvFiEjDxcVHwYzPwgzPwQ1NzM3Mzc1PwE1PwEzPwQ1LwQBJwGa/sHkcpz+yJwLBgsFDAUFBiYGCggEAgMBAQIGBAkEKwUJBQUFBQoFHgUKBQUFBQoEGAkFBAMEBAEBBAMEByYFBgULBgsG9AUEBQMEBAICCAIMBwgHBAMEAwQDBwYHDwIJAgMRBAMECQkEBAMEAQIDAgECAwIBAhIBCQQGAQMEAwEDCAQDAQMBAwEIBAQEAQQIAQQK/fEFBAgFBAEEBAQMBAQECAMBAwQDBAMECQEPAgECAwMFAgEEAwMBAgMDCAQJBQcFBRAGAgYCDwcGBwMEAwQDBAcIBAQHAgECAgMECAEEEg0KBQcGAgIDCAgEAQgEJgQIAwQEBAcECAMaAwgHBwMJBQQEBAMEAQQDBwEDBQQEBAQECQQmBAkFBAQFDa0ECAYHAQMIAwEVAwEDAwEJAQwBCQkDAwIBAgMDCAQBBAICAgMDCAQFBAkDCAMCBAMCAwIDAgMCAwMDAgMDAwMDAwMDBgMjAgMEBAICBQQIAYQFCAQDAwMBBgMDAgMCAwIDAgMHFgEEAQQBBgMCAgQEAwQFCQQEBAMEAQICAgECAQIBAgICAQEBCAEBAQICBAECBwMCAQIDAgECBgMJAwMDBP3DBQQIAwMCAgECAQEBAQEBAgEIAgEBAQMDBAQEBQkEAwMEAQIFAwIBAQEBAQECAQECAwMJAu4FBAgGAgEBAQEBAggCAQICBAEWAQEEAwwFCQQGBQQDCgIIAQIBAgICBwEBAQEBBAMECPynBQgIBAIBAQECBgICAgEEAQYCCgMEAQMGBAUJBAQEAwQCARIBAgECAQICAgcCAQEBAQIHAwUC8AQFBAQDBAICBwIDBQIEAQIDDAoDBAIEAQEEAwQECQgFBwMPAgEGBQgBAQEGAQIBAgECAgIJAQICAwQI/a0ECAQDAgICBQYMBgEMAQYHAwEDAwEHBwMBBwcBAwEDBAgEBAwEBAQECQQEBAUCAQEEBAMVAwQKBxkDCgIDAwMDAwMDAgYDAgMCAwIIAZwFBAQBBwocCwcSBAsEBwQEBwQIBBAIBAMCAgEEBAMEBQwFDQQFBAUIBSYECQQEBAQEBAEEAwEDAQMEBAgECQQCAgECBgMEBf5EBAUEBgICAQIDAwUEAQQNCQENAQQFBQQBBAUFCgUZAQQBFAYFBQULCgkFBAQDBAECAwMEBxMFBAUFBAUFBCUeCAQECQwDDQISBQQFAwEUBAQJCBYsBQUEBQUFBAUbBAYEAQECAwMEBAQJAwYFCwUFBQYUAR4FCgUFBAEEAQQFHA0EAQQFAwIBAgIDBAgB+v7IATgxWj66un0B8gEBAQEHAgIEAwQEBAkEBQYDAgkCAQEBAQEBAgUBAgMDCAQFBAkDAwMHAQEBAVMBAgIEBwkJCgEJBwYHAwQDBAMEBwgHFAQNBAQgAwMCAgICAwMICQUGBQUEAQQBBAUcDQQBCAQBBAQECAEDAQMBAwQIAwEDBAMBBgQHCAEEBAEDBAMBAwwDAQMBAwEIBAQEAQQEBAEEDRcFBQQBBAEJBQoFDAQFBAQDBAECBQcMHggECQQUBwgHBAMEAwQDBwYEAwcFBAQJBAQDBAECAgUMBQkEAwYCAQEBAQECAgcCAgMCAgIBAgMDCAUJCAMFAgECAQIBAgICCQIBAQEnAgMFAgQBAg8DAgECCQwJAQkEAwMBAwMBAwsHBwkJBAMEBAEBBAMMAwQGAwMCAwMDAwMDAgMDAgMCAwIDAgMEAxYDAwgJCQcDBDsBAgMDBA0FCwIDAwMDAwMCAwMKIwMHAwcEDgsDBwMIAwMCAQEDAgQICQQCBAkEBAQEBAUDAQMBAwQBAxAEAwEDCAMBCgEDAwEDAwEDAwEGBAkBAwIDA6kBBAQDBAgEBAkFBAkNBBsFDQkEBAkEAQQiBAUBBAQDAwIBAgIDBAgJBQQSBAsEBwQEBwQIBB4ECAQHBAQHBAQJBAQEAwQtAQQIBAQEBB4FCgUFBQUJBScFBAUJCgQyBAUECAQGAgIGCAoFGQEEARQGBQUFCwYmBQYFCwYLBhYGCQgDAwQQAgYICAkGEQUGBQYLBSEGCwUFCgYPAQQBGQUKAQQGAgEBAwIECAkIASkEBQUEBQUJBSIFCQUFBQUKBRcFBAcCAjkBAgMDCAcEBwQaAwsLBwYEAwcUDwMHAQgFBAUIAwMCAgICBwEDFQEDCwEHEAQEDAQEBAQEBAkEJgUFCAQEAwSgAQQDAwQJCQkGAQwBBgwGBQMDAgEEAQQBAgUEAgIBAQEEAQEBBgEBAQIBAQIDBwUEBQQIAwMJAgEGAxADBgMCAwIDAgMCAwYCAwMDAwMHSgECAQMGDAMDBQMCAQEBBAMDBAkFBAgDAwIBAQEBAgkCAgIBAgECAQEBAgICAQEBBAEBAQUEAwUEBQgIAwIBJwEBAwYECQUEBAQCBQMECQEGCQMCAQIDAgECAwQDCgIIAQIBAgIDAQIDAwgFBAkEAwMDBAIBAgECAQIBEBAGAgMFCQMKAQICAg8CAwUGDBQBAgECAQIBAgYCBgkEBQQEBAMDAgEBAQICAgECAQgMAwQDAgECAwIBAhIBCQQDBQQEBAUJBAMDBAAAAAUAAP+HA78DIgAPAB4AJgAqAC8AAAEOAhIWBDc+ATc2JicuAQcyFhcWBgcGJCcmAjc+ARcGBxc1FxEHJxQVJyUUFSYnAfSJ4mkwugECfoGkCAeJeC9mNIfXJiJUaXD+8WpnPzMwyWppaNHKyhiPAVlHSAMiAZb5/vbCPiwu3ImH6D0XGDGjgnvxS08LVlYBA3twhv9KSpSPjwEoj2BkZWRlZGYzMgAAAAkAAP+iA7gDIAALABcAUgC7AUQBoQHoAjICngAAARUjFTMVMzUzNSM1BzMVMxUjFSM1IzUzEysBByMHIwcVDwUVHwUzPwMzNzM3MzczFzMXMxczHwEzPwM1LwQjNSMnIycXDwYVHwozHwYVHwIzHw0zPwQ1LwE1JyMvBiMvATUjLwsjLwEjLwcjNSc1LwQjBQ8BIw8EFQ8EFQcjBxUPAyMVBxUHIxUPBBUHIw8BFQ8CFQ8CIw8DFQ8DFQcVDwoVBxUfBD8EMz8ENT8mNS8DAQ8FFRcVBxUHFQcVBxUHFQcVBxUHFQcVBxUHFQ8HFR8EPwUzPwEzPwE1PwEzNzM3NTc1MzU3NTc1NzU3NTc1NzU3NTc1JzUvBAUPBRUXFRcVFzMfBTMfARUXFRcVFxUzFxUXFR8EPwQ1Lw01JzUnNSc1LwMBDxcfBD8EMz8DMzczNzM3MzczNzU3Mzc1NzM/AjM3MzU/AzUvBAUPBRUfAxUfATMfAjMfAhUfATMfARUfATMXMxczFzMfAjMXMxcVMx8HMxcVFzMVMxczPwQ1LwQjJyMnIycjLwojLwQjLwUjAa59fYx9fXVefX1efX0zBw0GDQ0HJw0OBAMDBAECAwMJBAUGDAYXBgsGBgYGKQYGBgYGBR8EBQwDAwICBgMKJwYHBg0H6QUEBAMDAQICAgYCAgMGBQQDCAEOAggCBgIEAQICAQIDAgMFBAMEAwoFBgMJBAkEBAMEAgQGAQQDAgMCAwIBAggBBQMEAgQCAgUCBwICAQIJAQICAwcDAgMCAQIDAgYCCgX98wUHAQIDAgMCAwIDAgMEAQICAwIEAQQEAQICAgICAgECAgIEAgIEAQEBAgMCAgoBAgICAQQBAgECAQIBAgIBBAQDDgQIBAMBAQIDAQICAgECAQIBAgECAgMCAQIIAgECAgIBBAIEAQYCCgIGAwoDBgMFAwIBBAYIBQKyBAUDBgIBAQEBAQEBAQIBAwUDBQMEAwIGAwECAwYECQkEBAMCAQEDAgECAwMCAQUBDAMBAgEBAQEBAQEBBAMEBAj8pgQFAwQEAQEDAgEDAgEEAQoBBAMCAwIBAgMBAgQHCQkEBAMEAgQCAwIHBAEGAQIBAggBAQEBBQgIArEEBAkEBQoEDwUFCw8GBQsFIQYLEAgEBQICBAMEDQkGBhQFARIGBwUBBQEFAQUBHAELBQEFBQEFCw8BBAEDAwIBBAMEBAj93gQEBAMCAgECAwQNAgECAwIBAgMDCwIBCAMDBQECAQIBAgECAwMBAgECAQIEAwYDDQMdAgMNBAMNCQUIBQIBBAMEBAMECAMUAhEDCQURAgYFAwUFBQIBDwIFAgIBBAMEEQQEBQIhfYx9fYx9F31efX5dAZMBAgYBAgQCAwQICQUEBAMEAQICAgQCAQEBAQEFAQYEAwkFCAgCBAYBAQFPAQEDAwQEBAUJBAYBAgEGAwQCCA4DCAMGAwQBAgIDBAMEAwcHAwgDEgoIAgQCAgMDCAoHBwEMCAQEBAQEBAQLAQcDBgIGAgMFAwcDAgMJAwICBwICAgIBAQECAgQCBQwBBAICAgICAQICAgICAQQCAQICAwQBBAEEAQIDAgMCAQIDAgECBgIBAgYDAwIFAgECDwMCAQIBAgMGAwMDAwMDAwMBBAkFCAMDAwEEAwMEBgUDAgUBAgMCAwIDAgMDAgUCAwIMAgMCAwIDBAMEAwYDCgMGAgoBBgIFBAQECQkGBAH+xgECAggEBAQEMwMJAwYCBgMDAwMDAwYCAwMJAg4DCAENBQsFBgoHBAUJBAYCAgICAwMDAwYGBgUBBQcPJgMKAwMHAwMEAwMEAwMEAwcDDgMsBQkIBAIDAhMBAgMDCAQbBgcTBw0TBgcNBh8NBQEFAQUBBQEFAQUBAQQEBAICAgMDCQkIBgYFBhALBhEFBgYFLwYFBgYMBgcFBwYC/rIBAgYEBAYECQQDBQkCAwQDDAEEAwQDBwkJCAMDAwICAQYCBgMCAwIDAw8GAQMDAQMEBwwEAQMEBAQJCAQDAgICAQMCBAQJBAUEBAMBCgICAgICAgEBBwIFAQEBAwICAQIBAgEBAQEBAgICBAIJAQEEAQQBBAcFBAkIBAIDAQMHBgMDBgICAwEDAgMCCQIDAgEEAQQNAQIAAAABAAAAAAMxAqAAJwAAAQ4BBxQWFxYXBxc3NRUnNQcXJicuATU+ATceARcOAQcjFTM+ATcuAQH0h7MDMispN70CyCUKIjInKjADrYODrQMDrYMFBYezAwOzAqADsoVCcSspGCEKIwMByAUCuhcmKm4/gawDA6yBgawDCgOyhYWyAAUAAP/TA9QC6QAPAB8AOwBbAHYAABMOAQcRHgEXIT4BNxEuAScFIR4BFxEOAQchLgEnET4BFyMOARUeARcOAQcOAQcVITUuAScuASc+ATUuAQc2Fx4BNxYVFAYPARceARcOASImJz4BPwEnLgEnNT4BFxYXHgEXFSM1IxUjNTQiHQEjNT4BPwEeATI211JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUzFAygvARUNByASFiECAVwBIxcUIQgNEQEwQA0MHDAGARINBAQDGA8CNFA1AhEZAwQDDhYBBSKSCQkWIQE5BdgFNwIfFQsDOFI3AukCblL+blJuAgJuUgGSUm4CPAFLOv5uOksBAUs6AZI6S2QBMCUTIAwCDQoMHxV/fxIfDAsPAwwfEyUwMgEHDgsEBAQSIAsDAgEICCEtKyIICQEBAwwgEggGFHgEBQweD3paWloCAlp6Eh4LBiMsLQAAAAUAAAAAA4AChAAEAAgADAAQABQAABMZASERBTMVIzchFSEHMxUjNyEVIWgDGPztvb3CAkz9tMK9vcICTP20AoT+2v7bAkvChISEBfv7+wAAAwAAAAADNgK8AAMABwALAAATETMRMxEzETMRMxGygn+Cf4ICvP1EArz9RAK8/UQCvAAAAAkAAP+iA7wDIgADAAgAFgAiAC4APABKAFYAYwAAAQYHIQMWFyE2Ew4BBxY2FzYWFzYmByYXBhYXFhcWNicuAScFDgEHDgE3PgE3PgEBBhYHBgcUNjc+AScuAQUGFhceARcWJicmJy4BAQ4BBw4BFz4BNzYmIQYWFx4BFzYmJyYvAQH0YGABgMBLTP7STE8kVRIQRh4ePB0fSB8M7ik1Fi0fIA0WGT4o/fEmNBcUFysXKRwTJwKSHwoHCyA1BBcTBgIN/KQhDAMIFhUtGgsSAQIMAq4lRykdKiE5ZywKDP3TJTMbIkonISscTDwGAjKsrQEmh4eHAagDAyEfFgECCAIiGAIBTxA0EzI7EjYVKUgZChFBIRZKBSBFHRAt/tYMRh1BPCIKHjJtNggIEgtHHCNEHgNKHD0/CAv+sxMvDAEnFAozJQwbEjQNExwGEyYCFjMDAAARAAD/owO4AyIADQAaACkAbADCASABawGuAgYCUwKWAu4DRAOGA8sEFwRhAAABIg4BHgI3PgImJyYHMh4BBgcGLgI3PgEXBgcOARcWNjsBNSM2NyYnKwEVIw8DFR8EMzczNzMXMxczFzMXMxczHwYzPwU1LwIjLwkjJyMnIycjNQ8EIw8BFQcjDwEjBxUHIwcjByMHFQ8DIxUPARUPAiMPAR8FMz8dMz8DLwMjBQ8FHxYVHwQzPwQ1JzUvCDUnNS8EIycjJzUvASMnNSc1LwE1Iy8BNScjJzUvAjUvBAUPBRUjFQcVBxUjFQcVFxUzFRcVFxUXFR8JMz8ENS8CNSc1JzUnNSc1JzU3NTc1NzU3NTc1LwUFDwUVBxUPDxUfBT8CNT8BNTczNzU/AjM/CjU3LwQjBQ8FHwIVFxUXMxczHwIzHwEzFRcVFxUXMx8BMxczFxUXFR8BFR8CFR8CMz8FNS8dBQ8IIwcjByMHIwcjByMPBBUfBTM1MzczNzM3Mz8LMzczPwE1PwE1NzU/BDUvBCMDKwEHIwcjFSMHIw8HFR8EMzczNzM3MzczNzMXMxczFzMXMxczPwU1LwUjJyM1IycjJxcPBR8ZPwQ1LwMjJzUnNScjLwEjLwE1JyMnNS8BIy8BNSc1JyM1JyMnIy8BNS8BIyc1JyMvAgUPAhUHIw8BFQ8CFQcVBxUPASMPARUPAhUPASMPASMPARUHFQ8BIw8CFR8FMz8ZNS8EIwEPAxUHFxUHFQcVBxUHFQ8IFR8DMz8GNTc1Pwc1NzUzNTc1NzUnNS8DIwUPBBUXFRcVFxUXFR8HFRcVHwIzFR8DMz8ENS8LNSc1JzUnNSc1LwQjEw8EFR8FMx8BFRczFzMfARUfATMXFR8EMxczHwYzPwU1LxcFDxcVHwYzPwgzPwQ1NzM3Mzc1PwE1PwEzPwQ1LwQjAfRBbDEXWHs7Pk4GQzksMTxfHSwxNHhXDSEZTmQdHQ4EDAgPB1lZGx0KQwQODQoFBwYCAgMICAQBCAQmBAgDBAQEBwQIAxoDCAcHAwkFBAQEAwQBBAMHAQMFBAQEBAQJBCYECQUEBAUNsQUDBgcBAwgDARUDAQMDAQkBDAEJCQMDAgECAwMIBAEEAgICAwMIBAUECQMIAwIEAwIDAgMCAwIDAwMCAwMDAwMDAwMGAyMCAwQEAgIFBAgFAYQEBAQDAwMBBgMDAgMCAwIDAgMHFgEEAQQBBgMCAgQEAwQFCQQEBAMEAQICAgECAQIBAgICAQEBCAEBAQICBAECBwMCAQIDAgECBgMJAwMDBAn9xwQIAwMCAgECAQEBAQEBAgEIAgEBAQMDBAQEBQkEAwMEAQIFAwIBAQEBAQECAQECAwMJBAKNBQQEAwQCAgcCAwUCBAECAwwKAwQCBAEBBAMEBAkIBQcDDwIBBgUIAQEBBgECAQIBAgICCQECAgMECAX9rgQEBAMCAgIFBgwGAQwBBgcDAQMDAQcHAwEHBwEDAQMECAQEDAQEBAQJBAQEBQIBAQQEAxUDBAoHGQMKAgMDAwMDAwMCBgMCAwIDAggOAaUEBAEHChwLBxIECwQHBAQHBAgEEAgEAwICAQQEAwQFEQ0EBQQFCAUmBAkEBAQEBAQBBAMBAwEDBAQIBAkEAgIBAgYDBAUEpwUGBgsFDAUFBiYGCggEAgMBAQIGBAkEKwUJBQUFBQoFHgUKBQUFBQoEGAkFBAMEBAEBBAMEByYFBgULBgsG7wQFAwQEAgIIAgwHCAcEAwQDBAMHBgcPAgkCAxEEAwQJCQQEAwQBAgMCAQIDAgECEgEJBAYBAwQDAQMIBAMBAwEDAQgEBAQBBAgBBAoI/fQECAUEAQQEBAwEBAQIAwEDBAMEAwQJAQ8CAQIDAwUCAQQDAwECAwMIBAkFBwUFEAYCBgIPBwYHAwQDBAMEBwgEBAcCAQICAwQIBAKvBAgGAgEBAQEBAggCAQICBAEWAQEEAwwFCQQGBQQDCgIIAQIBAgICBwEBAQEBBAMECAT8pgQECAQCAQEBAgYCAgIBBAEGAgoDBAEDBgQFCQQEBAMEAgESAQIBAgECAgIHAgEBAQECBwMFBJQFBAYCAgECAwMFBAEEDQkBDQEEBQUEAQQFBQoFGQEEARQGBQUFCwoJBQQEAwQBAgMDBAcTBQQFBQQFBQQlHggEBAkMAw0NAhoEBQMBFAQECQgWLAUFBAUFBQQFGwQGBAEBAgMDBAQECQMGBQsFBQUGFAEeBQoFBQQBBAEEBRwNBAEEBQMCAQICAwQIBAI0SXd8Wx4VFmqCbRwVJ0lybB4fDld7NCUrMTU2AxoHBQkZMzMG7wECAgUMBQkEAwYCAQEBAQECAgcCAgMCAgIBAgMDCAUJCAMFAgECAQIBAgICCQIBAQEnAQEDBQIEAQIPAwIBAgkMCQEJBAMDAQMDAQMLBwcJCQQDBAQBAQQDDAMEBgMDAgMDAwMDAwIDAwIDAgMCAwIDBAMWAwMICQkHAwQ8AQEDAwQNBQsCAwMDAwMDAgMDCiMDBwMHBA4LAwcDCAMDAgEBAwIECAkEAgQJBAQEBAQFAwEDAQMEAQMQBAMBAwgDAQoBAwMBAwMBAwMBBgQJAQMCAwMCqwEEBAMECAQECQUECQ0EGwUNCQQECQQBBCIEBQEEBAMDAgECAgMECAkFBBIECwQHBAQHBAgEHgQIBAcEBAcEBAkEBAQDBAF3AQIDAwgHBAcEGgMLCwcGBAMHFA8DBwEIBQQFCAMDAgICAgcBAxUBAwsBBxAEBAwEBAQEBAQJBCYFBQgEBAMEoQICAwMECQkJBgEMAQYMBgUDAwIBBAEEAQIFBAICAQEBBAEBAQYBAQECAQECAwcFBAUECAMDCQIBBgMQAwYDAgMCAwIDAgMGAgMDAwMDBwNNAQIBAwYMAwMFAwIBAQEEAwMECQUECAMDAgEBAQECCQICAgECAQIBAQECAgIBAQEEAQEBBQQDBQQFCAgDAgECzgEBAQEHAgIEAwQEBAkEBQYDAgkCAQEBAQEBAgUBAgMDCAQFBAkDAwMHAQEBAVMBAgIEBwkJCgEJBwYHAwQDBAMEBwgHFAQNBAQgAwMCAgICAwMICQUGBQUEAQQBBAUcDQQBCAQBBAQECAEDAQMBAwQIAwEDBAMBBgQHAgoBBAQBAwQDAQMMAwEDAQMBCAQEBAEEBAQBBA0XBQUEAQQBCQUKBQwEBQQEAwQBAgUHDB4IBAkEFAcIBwQDBAMEAwcGBAMHBQQECQQEAwT+xQEECAQEBAQeBQoFBQUFCQUnBQQFCQoEMgQFBAgEBgICBggKBRkBBAEUBgUFBQsGJgUGBQsGCwYWBgkIAwMEEAEBBggICQYRBQYFBgsFIQYLBQUKBg8BBAEZBQoBBAYCAQEDAgQICQgBKQQFBQQFBQkFIgUJBQUFBQoFFwUEBwIC/rIBAwYECQUEBAQCBQMECQEGCQMCAQIDAgECAwQDCgIIAQIBAgIDAQIDAwgFBAkEAwMDBAIBAgECAQIBEBAGAgMFCQMKAwMBAgICDwIDBQYMFAECAQIBAgECBgIGCQQFBAQEAwMCAQEBAgICAQIBCAwDBAMCAQIDAgECEgEJBAMFBAQEBQkEAwMEAAYAAP+NA80DIgAOAB0ALAA7AEgAVQAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BBxQVIxUzFTM1MzUjNQcyMxUzFSMVIzUjNTMB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRE5+fep+fYSQln59JoKADIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZdTk58nJx8nBidSp2dSgAAAAAHAAD/jQPNAyIADgAdACwAOwBDAEcATAAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BFwYHFzUXEQcnFBUnJRQVJicB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRGmlo0crKGI8BWUdIAyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWo0pKlI+PASiPYGRlZGVkZjMyAAMAAP+aA7gDIgAQABQAQwAAASIHAQYUFwEWMjcBNjQnASYHCQI3MCMPBB8CDwIfBD8CHwI/BC8CPwIvBA8CJzUnAfQODP5hCgoBnwseCwGfCwv+YQsPAYb+ev569AICBA8DAQEDiYkDAQEDDwQEBQSJiQQFBAQPAwEBA4mJAwEBAw8EBAUEiYkEAyIL/mELHgv+YQoKAZ8LHgsBnws+/nr+egGGrQEDDwQEBQSJiQQFBAQPAwEBA4mJAwEBAw8EBAUEiYkEBQQEDwMBAQOJiQECAAAAAQAA/98DjwLtAA4AAAEGBAcWFwYHFhcBFhc2NwOPDf7Zey4s3d4REAG7LS1ASgLtB5U6Ky7g4BAPAcAsLn+OAAMAAP+NA8wDIwAPAB4AMwAAAQ4BBwYWFxYkNhInLgEnJgcyFhcWBgcGJicmNjc+AQcGBxcGBxYXNxc2NyYnNjcmJwYHJgHrqfsUD4qCegEMzEorLNqLEwl9swYDjHFuxyknSGMkUEYrLHA4NiosbnErLTk4ODYqLDc3OAMiBeSnj/0/OiO0AQWBhKoJAY6tfXK1FhNqaWrYOhUWbi0rcTY4LCpucCwrOTg3NywqNjg4AAAAAAoAAP+VA8cDIgARACEAMgBDAEgATABQAFQAWABcAAABIiMOAQcGEhYENz4BJy4BJyYHMjMeARcWBgcGJCYCNz4BFyIjDgEHBhYXFjY3NiYnLgEHMjMeARcWBgcGJicmNjc+AQcVESERBTMRIxMVMzUHFTM1BxUzNQcVMzUB8wECnPImHl3gARN2cXETFreFNj0FBZDdGxZwc3j+9LweRje0cAUFhcYSDoF2cOVISQhSM41QAwN2rQ0Kf2xqyzQzL1opYmQBLv7q/v4aysrKysrKygMiA8GWhf7/ogpJSfOGh8oiDjECu46B6z8/KccBD3VYZyoEsoR81iwoRGBl+186Qi8DoXVwux8dVmFl3kUgIXkM/pABfBj+tAEnGRlKGBhVGBhNGBgAEAAA/6MDuAMiAAsAFwBaALIBCAFLAaAB/QJIAooCzgMRA2gDtQQBBEsAAAEVIxUzFTM1MzUjNQczFTMVIxUjNSM1MxMxIwcjByMVIwcjDwcVHwQzNzM3MzczNzM3MxczFzMXMxczFzM/BTUvBSMnIzUjJyMnFyMPBR8ZPwQ1LwMjJzUnNScjLwEjLwE1JyMnNS8BIy8BNSc1JyM1JyMnIy8BNS8BIyc1JyMvAQUjDwIVByMPARUPAhUHFQcVDwEjDwEVDwIVDwEjDwEjDwEVBxUPASMPAhUfBTM/GTUvBCExIxUjDwMVHwQzNzM3MxczFzMXMxczFzMfBjM/BTUvAiMvCSMnIycjJyM1ByMPAiMPARUHIw8BIwcVByMHIwcjBxUPAyMVDwEVDwIjDwEfBTM/HTM/Ay8DBQ8FHxYVHwQzPwQ1JzUvCDUnNS8EIycjJzUvASMnNSc1LwE1Iy8BNScjJzUvAjUvAwUjDwUVIxUHFQcVIxUHFRcVMxUXFRcVFxUfCTM/BDUvAjUnNSc1JzUnNSc1NzU3NTc1NzU3NS8EBSMPAxUHFxUHFQcVBxUHFQ8IFR8DMz8GNTc1Pwc1NzUzNTc1NzUnNS8DBSMPAxUXFRcVFxUXFR8HFRcVHwIzFR8DMz8ENS8LNSc1JzUnNSc1LwQFIw8FFQcVDw8VHwU/AjU/ATU3Mzc1PwIzPwo1Ny8EBQ8FHwIVFxUXMxczHwIzHwEzFRcVFxUXMx8BMxczFxUXFR8BFR8CFR8CMz8FNS8cBSMPCCMHIwcjByMHIwcjDwQVHwUzNzM3MzczNzM/CzM3Mz8BNT8BNTc1PwQ1LwQFDwUVHwUzHwEVFzMXMx8BFR8BMxcVHwQzFzMfBjM/BTUvFiEjDxcVHwYzPwgzPwQ1NzM3Mzc1PwE1PwEzPwQ1LwQBrn19jH19dV59fV59fS8LBgsFDAUFBiYGCggEAgMBAQIGBAkEKwUJBQUFBQoFHgUKBQUFBQoEGAkFBAMEBAEBBAMEByYFBgULBgsG9AUEBQMEBAICCAIMBwgHBAMEAwQDBwYHDwIJAgMRBAMECQkEBAMEAQIDAgECAwIBAhIBCQQGAQMEAwEDCAQDAQMBAwEIBAQEAQQIAQQK/fEFBAgFBAEEBAQMBAQECAMBAwQDBAMECQEPAgECAwMFAgEEAwMBAgMDCAQJBQcFBRAGAgYCDwcGBwMEAwQDBAcIBAQHAgECAgMECAEEEg0KBQcGAgIDCAgEAQgEJgQIAwQEBAcECAMaAwgHBwMJBQQEBAMEAQQDBwEDBQQEBAQECQQmBAkFBAQFDa0ECAYHAQMIAwEVAwEDAwEJAQwBCQkDAwIBAgMDCAQBBAICAgMDCAQFBAkDCAMCBAMCAwIDAgMCAwMDAgMDAwMDAwMDBgMjAgMEBAICBQQIAYQFCAQDAwMBBgMDAgMCAwIDAgMHFgEEAQQBBgMCAgQEAwQFCQQEBAMEAQICAgECAQIBAgICAQEBCAEBAQICBAECBwMCAQIDAgECBgMJAwMDBP3DBQQIAwMCAgECAQEBAQEBAgEIAgEBAQMDBAQEBQkEAwMEAQIFAwIBAQEBAQECAQECAwMJAu4FBAgGAgEBAQEBAggCAQICBAEWAQEEAwwFCQQGBQQDCgIIAQIBAgICBwEBAQEBBAMECPynBQgIBAIBAQECBgICAgEEAQYCCgMEAQMGBAUJBAQEAwQCARIBAgECAQICAgcCAQEBAQIHAwUC8AQFBAQDBAICBwIDBQIEAQIDDAoDBAIEAQEEAwQECQgFBwMPAgEGBQgBAQEGAQIBAgECAgIJAQICAwQI/a0ECAQDAgICBQYMBgEMAQYHAwEDAwEHBwMBBwcBAwEDBAgEBAwEBAQECQQEBAUCAQEEBAMVAwQKBxkDCgIDAwMDAwMDAgYDAgMCAwIIAZwFBAQBBwocCwcSBAsEBwQEBwQIBBAIBAMCAgEEBAMEBQwFDQQFBAUIBSYECQQEBAQEBAEEAwEDAQMEBAgECQQCAgECBgMEBf5EBAUEBgICAQIDAwUEAQQNCQENAQQFBQQBBAUFCgUZAQQBFAYFBQULCgkFBAQDBAECAwMEBxMFBAUFBAUFBCUeCAQECQwDDQISBQQFAwEUBAQJCBYsBQUEBQUFBAUbBAYEAQECAwMEBAQJAwYFCwUFBQYUAR4FCgUFBAEEAQQFHA0EAQQFAwIBAgIDBAgCIX2MfX2MfRd9Xn1+XQGVAQEBAQcCAgQDBAQECQQFBgMCCQIBAQEBAQECBQECAwMIBAUECQMDAwcBAQEBUwECAgQHCQkKAQkHBgcDBAMEAwQHCAcUBA0EBCADAwICAgIDAwgJBQYFBQQBBAEEBRwNBAEIBAEEBAQIAQMBAwEDBAgDAQMEAwEGBAcIAQQEAQMEAwEDDAMBAwEDAQgEBAQBBAQEAQQNFwUFBAEEAQkFCgUMBAUEBAMEAQIFBwweCAQJBBQHCAcEAwQDBAMHBgQDBwUEBAkEBAMEAQICBQwFCQQDBgIBAQEBAQICBwICAwICAgECAwMIBQkIAwUCAQIBAgECAgIJAgEBAScCAwUCBAECDwMCAQIJDAkBCQQDAwEDAwEDCwcHCQkEAwQEAQEEAwwDBAYDAwIDAwMDAwMCAwMCAwIDAgMCAwQDFgMDCAkJBwMEOwECAwMEDQULAgMDAwMDAwIDAwojAwcDBwQOCwMHAwgDAwIBAQMCBAgJBAIECQQEBAQEBQMBAwEDBAEDEAQDAQMIAwEKAQMDAQMDAQMDAQYECQEDAgMDqQEEBAMECAQECQUECQ0EGwUNCQQECQQBBCIEBQEEBAMDAgECAgMECAkFBBIECwQHBAQHBAgEHgQIBAcEBAcEBAkEBAQDBC0BBAgEBAQEHgUKBQUFBQkFJwUEBQkKBDIEBQQIBAYCAgYICgUZAQQBFAYFBQULBiYFBgULBgsGFgYJCAMDBBACBggICQYRBQYFBgsFIQYLBQUKBg8BBAEZBQoBBAYCAQEDAgQICQgBKQQFBQQFBQkFIgUJBQUFBQoFFwUEBwICOQECAwMIBwQHBBoDCwsHBgQDBxQPAwcBCAUEBQgDAwICAgIHAQMVAQMLAQcQBAQMBAQEBAQECQQmBQUIBAQDBKABBAMDBAkJCQYBDAEGDAYFAwMCAQQBBAECBQQCAgEBAQQBAQEGAQEBAgEBAgMHBQQFBAgDAwkCAQYDEAMGAwIDAgMCAwIDBgIDAwMDAwdKAQIBAwYMAwMFAwIBAQEEAwMECQUECAMDAgEBAQECCQICAgECAQIBAQECAgIBAQEEAQEBBQQDBQQFCAgDAgEnAQEDBgQJBQQEBAIFAwQJAQYJAwIBAgMCAQIDBAMKAggBAgECAgMBAgMDCAUECQQDAwMEAgECAQIBAgEQEAYCAwUJAwoBAgICDwIDBQYMFAECAQIBAgECBgIGCQQFBAQEAwMCAQEBAgICAQIBCAwDBAMCAQIDAgECEgEJBAMFBAQEBQkEAwMEAAAAAAgAAP+aA7gDIgALABcAHAAgACQAKAAsADAAAAEOAQceARc+ATcuAQceARcOAQcuASc+ARcVESERBTMRIxMVMzUHFTM1BxUzNQcVMzUB9MD/BQX/wMD/BQX/wKzjBATjrKzjBATjFQEu/ur+/hrKysrKysrKAyIF/8DA/wUF/8DA/ywE46ys4wQE46ys49EM/pABfBj+tAEnGRlKGBhVGBhNGBgACgAA/6IDuAMgAA0AGgApAGQAzQFWAbMB+gJEArAAAAEiDgEeAjc+AiYnJgcyHgEGBwYuAjc+ARcGBw4BFxY2OwE1IzY3JgMrAQcjByMHFQ8FFR8FMz8DMzczNzM3MxczFzMXMx8BMz8DNS8EIzUjJyMnFw8GFR8KMx8GFR8CMx8NMz8ENS8BNScjLwYjLwE1Iy8LIy8BIy8HIzUnNS8EIwUPASMPBBUPBBUHIwcVDwMjFQcVByMVDwQVByMPARUPAhUPAiMPAxUPAxUHFQ8KFQcVHwQ/BDM/BDU/JjUvAwEPBRUXFQcVBxUHFQcVBxUHFQcVBxUHFQcVBxUPBxUfBD8FMz8BMz8BNT8BMzczNzU3NTM1NzU3NTc1NzU3NTc1NzU3NSc1LwQFDwUVFxUXFRczHwUzHwEVFxUXFRcVMxcVFxUfBD8ENS8NNSc1JzUnNS8DAQ8XHwQ/BDM/AzM3MzczNzM3Mzc1NzM3NTczPwIzNzM1PwM1LwQFDwUVHwMVHwEzHwIzHwIVHwEzHwEVHwEzFzMXMxczHwIzFzMXFTMfBzMXFRczFTMXMz8ENS8EIycjJyMnIy8KIy8EIy8FIwH0QWwxF1h7Oz5OBkM5LDE8Xx0sMTR4Vw0hGU5kHR0OBAwIDwdZWRsdCj8HDQYNDQcnDQ4EAwMEAQIDAwkEBQYMBhcGCwYGBgYpBgYGBgYFHwQFDAMDAgIGAwonBgcGDQfpBQQEAwMBAgICBgICAwYFBAMIAQ4CCAIGAgQBAgIBAgMCAwUEAwQDCgUGAwkECQQEAwQCBAYBBAMCAwIDAgECCAEFAwQCBAICBQIHAgIBAgkBAgIDBwMCAwIBAgMCBgIKBf3zBQcBAgMCAwIDAgMCAwQBAgIDAgQBBAQBAgICAgICAQICAgQCAgQBAQECAwICCgECAgIBBAECAQIBAgECAgEEBAMOBAgEAwEBAgMBAgICAQIBAgECAQICAwIBAggCAQICAgEEAgQBBgIKAgYDCgMGAwUDAgEEBggFArIEBQMGAgEBAQEBAQEBAgEDBQMFAwQDAgYDAQIDBgQJCQQEAwIBAQMCAQIDAwIBBQEMAwECAQEBAQEBAQEEAwQECPymBAUDBAQBAQMCAQMCAQQBCgEEAwIDAgECAwECBAcJCQQEAwQCBAIDAgcEAQYBAgECCAEBAQEFCAgCsQQECQQFCgQPBQULDwYFCwUhBgsQCAQFAgIEAwQNCQYGFAUBEgYHBQEFAQUBBQEcAQsFAQUFAQULDwEEAQMDAgEEAwQECP3eBAQEAwICAQIDBA0CAQIDAgECAwMLAgEIAwMFAQIBAgECAQIDAwECAQIBAgQDBgMNAx0CAw0EAw0JBQgFAgEEAwQEAwQIAxQCEQMJBRECBgUDBQUFAgEPAgUCAgEEAwQRBAQFAjRJd3xbHhUWaoJtHBUnSXJsHh8OV3s0JSsxNTYDGgcFCRkzMwYBSgECBgECBAIDBAgJBQQEAwQBAgICBAIBAQEBAQUBBgQDCQUICAIEBgEBAU8BAQMDBAQEBQkEBgECAQYDBAIIDgMIAwYDBAECAgMEAwQDBwcDCAMSCggCBAICAwMICgcHAQwIBAQEBAQEBAsBBwMGAgYCAwUDBwMCAwkDAgIHAgICAgEBAQICBAIFDAEEAgICAgIBAgICAgIBBAIBAgIDBAEEAQQBAgMCAwIBAgMCAQIGAgECBgMDAgUCAQIPAwIBAgECAwYDAwMDAwMDAwEECQUIAwMDAQQDAwQGBQMCBQECAwIDAgMCAwMCBQIDAgwCAwIDAgMEAwQDBgMKAwYCCgEGAgUEBAQJCQYEAf7GAQICCAQEBAQzAwkDBgIGAwMDAwMDBgIDAwkCDgMIAQ0FCwUGCgcEBQkEBgICAgIDAwMDBgYGBQEFBw8mAwoDAwcDAwQDAwQDAwQDBwMOAywFCQgEAgMCEwECAwMIBBsGBxMHDRMGBw0GHw0FAQUBBQEFAQUBBQEBBAQEAgICAwMJCQgGBgUGEAsGEQUGBgUvBgUGBgwGBwUHBgL+sgECBgQEBgQJBAMFCQIDBAMMAQQDBAMHCQkIAwMDAgIBBgIGAwIDAgMDDwYBAwMBAwQHDAQBAwQEBAkIBAMCAgIBAwIEBAkEBQQEAwEKAgICAgICAQEHAgUBAQEDAgIBAgECAQEBAQECAgIEAgkBAQQBBAEEBwUECQgEAgMBAwcGAwMGAgIDAQMCAwIJAgMCAQQBBA0BAgAAAwAAAAADUgKgAAMABwALAAATFSE1ARUhNQEVITWWArz9RAK8/UQCvAKggoL+/4KC/v+CggAAAAACAAAAAANvAoQAVQCrAAABIgc5AQYPAQYHOQEOARU5ARQWFzgBMR4BMxY3OQEyNjUxNiYrATUzMjY3NiYHIzUhPgE0JgchNTMxPgE1OQE0JisBByMiJyMiMDQHNj8CPgEnMSYnBzIXFhc5ARYGBzkBBg8CBgcGFhczFjM3MzEyFhQGKwEVITIWFAYjIRUhMTIWBzkBDgEjIRUzMhYVOQEOASMGJzkBIiYnOQEuATUxNDY3Njc+ATcxNgHMCwsrVHYrEggCAwUPTjrc2xIWARcSvfwTGQMGGRr+AS4YFRcW/tLiFhgYFmRyXhMLCwEBBQouEAsDCQoOBAIBCwoIAwoFChgXCgUBAgMNCxPQZBQVFBXnATMVExIW/s0BAxgVBQMVEv7/whIRARER29w5Sw8EAwIIEikjpyoLAoQIHDpRHzgdPh0VJRU/PwEBFRYXEhUOERsdARMBGS8XARMBGRgXGgEBAgEGCi4RECQOEAEEAQEODCEPBgoXFwsFBAUBAQEWLBcdEysXHRgZEAsfDxUUEgEBPT0VJBUdPhs3Hhd0HAcAAAADAAAAAAN4AoQAEgAVABsAABMwIjEGFREUMyEyNRE0JzgBMSEFIQUlBTMlESFzAQIDAwMCAv4f/ucC8f6H/oEBfgIBfv0CAoQBAv26AgICRgIBBeTi5+f9wQAAAAMAAP/dA3UC3wAEAAgAFAAAExURIREFIREhAREhFSERMxEhNSERcwMC/QgC7v0SAWP+6AEYKAEY/ugC3wX9AwMCCv0SAqP+6Cj+6AEYKAEYAAAAAAQAAP+HA78DIgAQACAALAA4AAABDgISFgQ3PgE3NiYnLgEjFx4BFxYGBwYkJyYCNz4BMwcVIxUzFTM1MzUjNQczFTMVIxUjNSM1MwHwh+BpMLoBAn6BpAgHiXgvZjQIhdIlIlRpcP7xamc/MzDJekZ9fYx9fXVefX1efX0DIgKW+P72wj4sLtyJh+g9FxgxA6KAe/FLTwtWVQEEe3CG0H2MfX2MfRd9Xn1+XQAEAAD/hwO/AyIADwAeACYALQAAAQ4CEhYENz4BNzYmJy4BBzIWFxYGBwYkJyYCNz4BBQYHJwM2NxcDFhc3BycHAfSJ4mkwugECfoGkCAeJeC9mNIfXJiJUaXD+8WpnPzMwyQEnMzOAdEFBhok9PR4dfDIDIgGW+f72wj4sLtyJh+g9Fxgxo4J78UtPC1ZWAQN7cIbSaGmm/qpTVJoBBk5MQ3SRTQAAAAAGAAD/jQPNAyIADgAdACwAOwA/AEQAAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcGByEDFhchNgHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFEqYGABgMBLTP7STAMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFmOsrQEmh4eHAAAGAAD/jQPNAyIADgAdACwAOwBDAEsAAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcGBycDNjcXAxYXNwcnBgcB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRR1zMzgHRBQYaJPT0eHXwaGAMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFnZoaab+qlNUmgEGTkxDdJEmJwAAAAADAAD/jQPMAyMADwAeACYAAAEOAQcGFhcWJDYSJy4BJyYHMhYXFgYHBiYnJjY3PgEXBgcXNRcRBwHrqfsUD4qCegEMzEorLNqLEwl9swYDjHFuxyknSGMkUBppaNHKygMiBeSnj/0/OiO0AQWBhKoJAY6tfXK1FhNqaWrYOhUWokpKlI+PASiPAAAAAAQAAP/wA6sCzAAPACMAJwA0AAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIxEhESMuAScRPgETIREhNx0BIxUzFTM1MzUjNdhCVwICV0ICOUFXAgJXQf3HAjktPAEBPC10/q5zLjsBATvAART+7HNNTS5NTQLMAldB/lhBVwICV0EBqEFXAjABPC3+WC08AQE0/swBPC0BqC08/pr+7O0XNi5NTS5NAAQAAP/wA6sCzAAPACMAJwArAAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIxEhESMuAScRPgETIREhNxUzNddBVwICV0ECOkFXAgJXQf3GAjotPAEBPC10/q50LTsBATvAART+7CXLAswCV0H+WEFXAgJXQQGoQVcCMAE8Lf5YLTwBATT+zAE8LQGoLTz+mv7rpy8vAAAAAgAA//ADqwLMAA8AHwAAEw4BBxEeARchPgE3ES4BJwUhHgEXEQ4BByEuAScRPgHXQVcCAldBAjpBVwICV0H9xgI6LTwBATwt/cYtOwEBOwLMAldB/lhBVwICV0EBqEFXAjABPC3+WC08AQE8LQGoLTwAAAADAAD/jQPMAyMADwAeACYAAAEOAQcGFhcWJDYSJy4BJyYHMhYXFgYHBiYnJjY3PgEXBgcnAzY3FwHrqfsUD4qCegEMzEorLNqLEwl9swYDjHFuxyknSGMkUNczM4B0QUGGAyIF5KeP/T86I7QBBYGEqgkBjq19crUWE2ppatg6FRZ1aGmm/qpTVJoAAAYAAP+NA80DIgAOAB0ALAA7AEQATQAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BFw4BBz4BNxcmJxYXJw4BNT4BAfOq/wAWEIaBfAERzkda1YcRF53pEQyQgoH+/E9NB1g5n2GQ0gcEn4B43Tg1LFwxekN/tgIBmXZvviMfS14kUSoiOCIgPCB9Pz0iIkQRMRIeAyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWb2PKYyFFIYfIdW1uShE6BzVrAAcAAP+VA8cDIgARACEAMgBDAFIAYABvAAABIiMOAQcGEhYENz4BJy4BJyYHMjMeARcWBgcGJCYCNz4BFyIjDgEHBhYXFjY3NiYnLgEHMjMeARcWBgcGJicmNjc+ARcOAh4CNz4CJicmIxceAgYHBi4CNz4BMxcGBw4BFxY2OwE1IzY3JgHzAQKc8iYeXeABE3ZxcRMWt4U2PQUFkN0bFnBzeP70vB5GN7RwBQWFxhIOgXZw5UhJCFIzjVADA3atDQp/bGrLNDMvWiliL0BqMBdYezs+TgZDOSwxBDtcHSwxNHhXDSEZTi03HR0OBAwIDwdZWRsdCgMiA8GWhf7/ogpJSfOGh8oiDjECu46B6z8/KccBD3VYZyoEsoR81iwoRGBl+186Qi8DoXVwux8dVmFl3kUgIWEBSHd8Wx4VFmqCbRwVJwFJcWweHw5XezQlKzE1NgMaBwUJGTMzBgAAAAAEAAD/hwO/AyIADwAeACcAMAAAAQ4CEhYENz4BNzYmJy4BBzIWFxYGBwYkJyYCNz4BFw4BBz4BNxcmJxYXJw4BNT4BAfSJ4mkwugECfoGkCAeJeC9mNIfXJiJUaXD+8WpnPzMwyXoiOCIgPCB9Pz0iIkQRMRIeAyIBlvn+9sI+LC7ciYfoPRcYMaOCe/FLTwtWVgEDe3CGy2PKYyFFIYfIdW1uShE6BzVrAAAABAAA/4cDvwMiAA8AHgAiACcAAAEOAhIWBDc+ATc2JicuAQcyFhcWBgcGJCcmAjc+ARcGByEDFhchNgH0ieJpMLoBAn6BpAgHiXgvZjSH1yYiVGlw/vFqZz8zMMl6YGABgMBLTP7STAMiAZb5/vbCPiwu3ImH6D0XGDGjgnvxS08LVlYBA3twhr+srQEmh4eHAAAAAAcAAP/TA9QC6QAPAB8AJAAoACwAMAA0AAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIS4BJxE+ARcdASERBTMVIzchFSEHMxUjNyEVIddSbwICb1ICOlNuAgJuU/3GAjo6TAEBTDr9xjpMAQFMFgH4/iGMjKUBIf7fpYyMpQEh/t8C6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLR76+AXyEQ0NDGYODgwAAAAYAAAAAAwUChAAYADIAOgBCAEoAUgAAAQcOAR4EBg8BIT4BNzYuBDY/AQUhBgcGHgQGByE+ATc2LgMnPgE3NhcGFBczNjQnBwYUFzM2NCcHBhQXMzY0JwcGFBczNjQnAYECVEgBLj0wCDhLEwGHJzQQHgkyPSwBRFMS/n8BWEcgJQIuPTAINkz+qCAsDh8LMjwsAQEPESIhBgbNBga5BQW8BQV9BgbQBganBQXQBgYChAEzVkxBPDo+SS0KFyoUJ0c9PD1DUTMLDCwnK0xBPDo+SC0UJREnRz08PSIQJRUpNQEJAQEJAXMBCgEBCgF0AQkBAQkBcwEKAQEKAQAAAAACAAAAAAN4AoQAAgAHAAATBSUFESERBXABhAGE/PgDCP58AoTW1mn+HQHjwQAAAAACAAD/0wPUAukADwAfAAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIS4BJxE+AedZeAICeFkCGll4AgJ4Wf3mAhosOAEBOCz95iw4AQE4AukCdlj+ilh2AgJ2WAF2WHYCbgE3Kv6KKjcBATcqAXYqNwAAAAUAAP+aA7gDIgALABcAJgA0AEMAAAEOAQceARc+ATcuAQceARcOAQcuASc+ARcOAh4CNz4CJicmIxceAgYHBi4CNz4BMxcGBw4BFxY2OwE1IzY3JgH0wP8FBf/AwP8FBf/ArOMEBOOsrOMEBOOoQGowF1h7Oz5OBkM5LDEEO1wdLDE0eFcNIRlOLTcdHQ4EDAgPB1lZGx0KAyIF/8DA/wUF/8DA/ywE46ys4wQE46ys47kBSHd8Wx4VFmqCbRwVJwFJcWweHw5XezQlKzE1NgMaBwUJGTMzBgAAAAAFAAD/hwO/AyIADwAeACMAKgAwAAABDgISFgQ3PgE3NiYnLgEHMhYXFgYHBiQnJgI3PgEHFBUhEQUyMw4BByY3FBUhNRcB9IniaTC6AQJ+gaQIB4l4L2Y0h9cmIlRpcP7xamc/MzDJUwGa/sFych49HjXY/sicAyIBlvn+9sI+LC7ciYfoPRcYMaOCe/FLTwtWVgEDe3CG95ycATgxFDoHKw5dXbp9AAAEAAD/jQPNAyIADwAeAC0APAAAAQ4BBwYWFxYkNhInLgEnJgceARcWBgcGJicmEjc+ARcOAQcUFhcWNjc2JicuAQceAQcOAQcGJicmNjc+AQHwqf4WEIaBfAERzkctLdKFFg2c5A4KloN//05NCFg6pU+PzAWjgHbZNzUsXTN/NYCyAQOZdG++Ix9LXyZTAyID4aiP/UE8IrgBCIJ+pgsCMQLVm4roLSlQbXEBEWlGTS0Fy5CCzBoVaGxu8FEtLjEEt4B0rg8MdmtozTcWFgAABgAA/40DzQMiAA4AHQAsADsAQwBLAAABBgQHBhYXFiQ2EgImJyYHNhYXFgYHBiQnJhI3PgEXIgYHBhYXFjY3NiYnLgEHHgEXDgEHBiYnJjY3PgEXFBUjFTMVNycWFwc1IzUzAfOq/wAWEIaBfAERzkda1YcRF53pEQyQgoH+/E9NB1g5n2GQ0gcEn4B43Tg1LFwxekN/tgIBmXZvviMfS14kUVzi4qWJMzNm398DIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZ0MjK+ZMN6PD15NoUAAAAAAwAA/40DzAMjAA8AHgAnAAABDgEHBhYXFiQ2EicuAScmBzIWFxYGBwYmJyY2Nz4BFw4BBz4BNxcmAeup+xQPioJ6AQzMSiss2osTCX2zBgOMcW7HKSdIYyRQKiI4IiA8IH0/AyIF5KeP/T86I7QBBYGEqgkBjq19crUWE2ppatg6FRZuY8pjIUUhh8gAAAAABQAA/6wDtgMbAAgADAAQABQAGAAAARURITUjETM1AQcXNw8BFzcPARc3DwEXNwKlARHg4P6eSzxL00s8S9JMPEvSTDxMAxsZ/LExAwUy/n48SzwsPEs7LDtMPCw8SzsAAwAA/6wDrgMbAAsARwBTAAAFDgEnLgE3PgEXHgEBMRcHJzcGJwcnNxcmJwcnNxcmNyc3FxU2NyEOAQcRFwc2PwIXIxYXNxcHJxYfAgc1BgcXITI2NxEGJw4BJy4BNz4BFx4BAYQ3kjk2AzY4kjk2AQHBFVUpAy0wKFUUASYaTSNDAgcHRCNNEBX+RRgfATQBJywLWgwDLCg9QC4BGglNAk0KFyoBaBgfARQBIIpJSDgcIIpJSDkWNQM0OJI4NwI1N5IBW00jRAEJCUQjTQEbJRRVKAItLyhVEwQWEwEgGP6OJgEaCU0BTAkYLz8+AScrCloNAywoNSAZAb0Ufkg4HCCJSUg4HCCIAAAAAAQAAP+aA7gDIgAQABQAagBvAAABIgcBBhQXARYyNwE2NCcBJgcJAiUxDwMVLwIPBB8CIw8DFR8DMw8CHwQ/AhUfAzM/AzUfAj8ELwIzPwI1LwIjPwIvBA8CNS8CBzA5ATAB9A4M/mEKCgGfCx4LAZ8LC/5hCw8Bhv56/noBfQQEAgFjAwQEBA0CAQECY4wEAwIBAQIDBIxjAgEBAg0EBAQDYwECBAQSBAQCAWMDBAQEDQIBAQJjjAQDAwMDBIxjAgEBAg0EBAQDYwECBIsDIgv+YQseC/5hCgoBnwseCwGfCz7+ev56AYbGAQIDBIxjAgEBAg0EBAQDYwECBAQSBAQCAWMDBAQEDQIBAQJjjAQDAgEBAgMEjGMCAQECDQQEBARiAQIEGgQCAWMDBAQEDQIBAQJjjAQDAzAAAAAEAAD/mgO4AyIAEAAUABoAHwAAASIHAQYUFwEWMjcBNjQnASYHCQIlDwEXITcnFwcjJwH0Dgz+YQoKAZ8LHgsBnwsL/mELDwGG/nr+egGGB9BSAQpS17tI5kgDIgv+YQseC/5hCgoBnwseCwGfCz7+ev56AYbgBZf9/X6H3NwAAAIAAP+aA7gDIgAPABMAABMGFBcBFjI3ATY0JwEmIgcJAzsKCgGfCx4LAZ8LC/5hCx4L/pQBhgGG/noBeAseC/5hCgoBnwseCwGfCwv+RwGG/nr+egAAAAAEAAD/mgO4AyIAEAAUACAALAAAASIHAQYUFwEWMjcBNjQnASYHCQIlDgEHHgEXPgE3LgEHHgEXDgEHLgEnPgEB9A4M/mEKCgGfCx4LAZ8LC/5hCw8Bhv56/noBhll3AgJ3WVl3AgJ3WU9qAgJqT09qAgJqAyIL/mELHgv+YQoKAZ8LHgsBnws+/nr+egGG0gJ3WVl3AgJ3WVl3FQJqT09qAgJqT09qAAADAAD/jQPMAyMADwAeACoAAAEOAQcGFhcWJDYSJy4BJyYHMhYXFgYHBiYnJjY3PgEXDgEXHgE3PgEnLgEB66n7FA+KgnoBDMxKKyzaixMJfbMGA4xxbscpJ0hjJFAqdIcgJNhhXwhaHkoDIgXkp4/9PzojtAEFgYSqCQGOrX1ytRYTamlq2DoVFlEBuHBuS0BD5UkYGgAAAAMAAP+NA8wDIwAPAB4AIgAAAQ4BBwYWFxYkNhInLgEnJgcyFhcWBgcGJicmNjc+ARcGByEB66n7FA+KgnoBDMxKKyzaixMJfbMGA4xxbscpJ0hjJFAqYGABgAMiBeSnj/0/OiO0AQWBhKoJAY6tfXK1FhNqaWrYOhUWYqytAAAAAgAA/5YDxwMiAA8AHgAAAQ4BBwYSFxYEPgEnLgEnJgceARcWBgcGJicmNjc+AQHwnPQlHWJwbwEP5XMTFr6KMil0qw8MdWlozjg5Kl0qZQMiA8SYhv8AUE4Jj/SGi84fC44Cm3JuvCQhTF9l5kggIQAAAAADAAD/jQPMAyIADQAcACQAAAEOAQcGFhcWJDYSAiYnBzIWFxYGBwYmJyY2Nz4BFwYHFyE2NyYB66n7FA+KgXsBDMxKV9qLHH2zBgONcG7HKSdIYyNRKmtsUgEKKihrAyIF5KiP/D86I7MBBgEEqwmNrX1ztBYTamlq2DoVFlZOTv1/fk4AAAAABAAA/40DzAMjAA8AHgAjACkAAAEOAQcGFhcWJDYSJy4BJyYHMhYXFgYHBiYnJjY3PgEHFhc2NwUUFSERBwHrqfsUD4qCegEMzEorLNqLEwl9swYDjHFuxyknSGMkUH1WVVRW/oUBmskDIgXkp4/9PzojtAEFgYSqCQGOrX1ytRYTamlq2DoVFppFRUVFIIyMARKjAAMAAP+NA8wDIwAPAB4AJgAAAQ4BBwYWFxYkNhInLgEnJgcyFhcWBgcGJicmNjc+ARcUFSMVMxU3Aeup+xQPioJ6AQzMSiss2osTCX2zBgOMcW7HKSdIYyRQXOLipQMiBeSnj/0/OiO0AQWBhKoJAY6tfXK1FhNqaWrYOhUWczIyvmTDAAcAAP+NA80DIgAOAB0ALAA7AEAARwBNAAABBgQHBhYXFiQ2EgImJyYHNhYXFgYHBiQnJhI3PgEXIgYHBhYXFjY3NiYnLgEHHgEXDgEHBiYnJjY3PgEHFBUhEQUyMw4BByY3FBUhNRcB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRowGa/sFych49HjXY/sicAyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWm5ycATgxFDoHKw5dXbp9AAAAAAUAAP+NA80DIgAOAB0ALAA7AEMAAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcGBxc1FxEHAfOq/wAWEIaBfAERzkda1YcRF53pEQyQgoH+/E9NB1g5n2GQ0gcEn4B43Tg1LFwxekN/tgIBmXZvviMfS14kURppaNHKygMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFqNKSpSPjwEojwAEAAD/hwO/AyIADwAeACYALQAAAQ4CEhYENz4BNzYmJy4BBzIWFxYGBwYkJyYCNz4BFwYHFyE2NyYnFhcHIyc2AfSJ4mkwugECfoGkCAeJeC9mNIfXJiJUaXD+8WpnPzMwyXprbFIBCiooa2xdXkjmSF4DIgGW+f72wj4sLtyJh+g9Fxgxo4J78UtPC1ZWAQN7cIazTk79f35OMENE3NxEAAAAAAUAAAAAAu4CpAANABMAFgAeACUAABMVFDERIREwMTUiMSc1BSEVMxEhARcjJx0BIxUzFTcnFwc1IzUz+gH0Aab+uAFDp/4WAUienpdwcFhTTExwcAKkAgH9dwHmAqICBaP+IQJ+mjUGM1c5ZFhYVzFNAAAABAAA/9MD1ALpAA8AHwBlALgAABMOAQcRHgEXIT4BNxEuAScFIR4BFxEOAQchLgEnET4BFzEiBzkBBg8BMQYHIw4BFTkBBhcwMR4BMyExMjc2NTE0JyYnMzI3NjcxNicmJzMyNi4BByM3NjU5ATQmKwE3PgInMSYnBzIxNhc5ARYGDwEGBwYfARYXFjEzMTIWFAYjBxUXMhYVFAYHIxUzMTIXFgc5AQYjBisBFTMeARU5AQ4BByExIiYnOQEuATUxNDY3NjcxPgE3NjLXUm8CAm9SAjpTbgICblP9xgI6OkwBAUw6/cY6TAEBTOILCRw3Th8MAQYBAQcKOSkBIA8LCQoDAxcNDAsDBQwDBQkSFQEWEB0HChUR1AsREwIICA0EAQQEAwEFGBEJBQMDAgQC5woICAqg0gwGBgzSsg0EBAICAwQLsYcLBAEECv7gJCsKAwICBAsZFm8cBAQC6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLRAYSJDMVJhQoEhgcKC0JCw8RCgMBBQgNFQ0DAxciFAEGDBERFgsQFhwMDAIUAQcFDwcYEQkHBQQCAQEIFggBIgEGCgwHASMFAg0IAyQBAwoLBAEiJAwXDRIlECAQD0kRAwAACgAAAAADHQKGAEsAfgCXAPEA9QD4AZsCMwI3AjsAAAEdAQYHOQEGBycHFwYHIxUzHgEXBxc3FTcWFxYXFRcHFzcWFxUzNTY3OQE2Nxc3JzY3MzUjJicxJic3Jwc1IyYvATUjMDE3JwcmJzUHMxUzFh8BNxcHFyMVLgEHDgEXMRYXIxUHJzcnJicxJi8BIzUzNTY/ASc3Fzc2NzE2PwEXMhYXFQYHOQEGBycHFwYHIyYnMSY2NzE2FzsBFQczFxYXMRYfATIfATcXBxcWFzEWFxUzFQ8BBg8BFwcnBw4BDwEVIzUjJi8BByc3My8CJicmNCMnNCYnNScmJzUwMSc1BzUzNzY/ASc3Fzc2NzE2NzM3FhUjFxUnByIjMTA5AiIxIxUiBw4BBzEwFDA5ATAxFTAxFTgBOQEGFTE4AzEVOAE5ARYVMTAVMRYVMTA5ATAUOQEwOQEUFzEwMRUUFzE4ATkBFBc5ARQxFxYVMTA5ARYVFzAUMRYXOAEUMR4BNz4BJyYnMTA5AiYjMTQxJzAxJzAxJyYjMTQrASY5ASInMTAxIzAnIyIxJzArATA5ASInMSIxIzAxBzEzMDsBMjkBFjMxMjEzMDMxMBcxMjEzMBczMjEXMjkBFjMxMDkBFjMVMTIXMTAxFzAxFzMyFTEyFTEWFxYGBzEGJic4AzEnOAEmMDEnMC4BMDEmNTE0MCY1MTAxNTgBOQEmPQEmNTE4ATQxJzAxNTQnMTgBPQE4AzkBNDcxMDkBOAIxNTgCOQE+ATcxNjMxNDMHMRUnFxYXJwGMEBAPDiY1JhIHNTUEDQknNiUhDAsCBQ4kNiYdIUsRDw8OJzUmEgc0NQMHBgolNiQgDAoHESQ2JB0gR0ICIh0CIy8kATUYSyYtIhINGiIlLyYBCQcHAwE0NAcTASUvJAIOEBEQAiAdMhARDxANJjUlEgcJHw4RISoVeDkJAQIJDAoRDQEBAQEkLyQBCgcGBDQzAQYUASYuJgINIRECQQIjHQEmLyQDAQIDBAMBAQIBAQEEAwI1NAEGFAElLiUCDhAREAJGAgI5EE0BAgEFEhIdJAQBAQEBAQECAQECAQMWUCosIhERIgECBAMEAQIBAgEDBAMBAwEDAQMBAgEEAwMBAgECAQEDAQIBAwECAQYBAgEBAwIBAwMBAgEgEBEhKihNFQMBAQEBAgEBAQEBAQQiHBERAaoFEwQGCgKGAzEEBgcJJTUlHSBMDyANJjUkDwEFAwoMIQEjNSYSBzY2BAYHCSY2JR0hSxAPEA0lNSQQBAMWHyU1JRMGNAUzBxMBJC4kASEgFg8UVC0fEjYkLiUCDhARDwJCAiIdASUuJAEKBgcDAUAbGQoDBwYKJTUlHCERIitQEwgOGxgCAwQGCQEBASQuJAINEQ8RAkEBAiEeASUvJQEJDgMBNTUIEgElLiMCAgYGBgICBAECAQIBCwoBBwMBQgIiHQIkLiQBCgYHBAoDAw0JCTIBCA0wHgEDAQMFCAQEAQECAQECAQEDAQIBBwEBAQIDAQQDASUcEBRVLCYSAQEBAgEBAQECAQEBBQEBAQIBAQEBAQIBAREkK1ATEBskBwEDAgIEAwECAQECAQECAQEDAQQDAQcEBAQcLwwIAZMCAikJCQEAAAMAAAAAAwsChAAiAEQAZQAAAQcOAQceARcOAQcGBw4BBxUzFjchNTQmJyYnLgEnPgE1LgEHMhceATcWFRQGDwEXHgEXDgEHLgEnPgE/AScuASc0Nz4BFxYXHgEXFhcVIzUjFSE1NCIHFSM1Njc+ATc2Nx4BFz4BAewFQEsBASIXDTIeIxsMEAFiAgEByRANHCQgNg0VGwFNZxQULkwKARwWBgcFJhoDVkFAVgMbKQYHBhckAQEIN+kPDxEhDBoBWgj+owcBVwIZDB8RCQoEWUFCWQKEAQFNPR0zFAQUERIaDR0QzAEBzA4bDBoTEhcFFDIdPU5RChcSBwYIHTISBQICDww2SAEBRjYNDwICBRMyHQgHCCC/BwkKFgsZF8SQkJAFBZDEHBgMFgkGBDdHAQFJAAAABQAA/9MD1ALpAA8AHwAzADcAPgAAEw4BBxEeARchPgE3ES4BJwUhHgEXEQ4BByEuAScRPgEXIjEiBhURFBYzITI2NRE0JiMwMQU7AQcnFxY/AREh11JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUwkAQUHCAUB9AUHBwX+O83Iyu7nBwbn/iUC6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLQgcF/psFCAgFAWUFBxl0a4QDA4T+vQAAAAADAAAAAALuAqQADgAUABcAABMVFDERIREwMTUiMSc1IRchFTMRIQEXI/oB9AGm/rYCAUOn/hYBSJ6eAqQCAf13AeYCogIFo/4hAn6aAAAAAAIAAP+HA78DIgAQACAAAAEOAhIWBDc+ATc2JicuASMXHgEXFgYHBiQnJgI3PgEzAfCH4GkwugECfoGkCAeJeC9mNAiF0iUiVGlw/vFqZz8zMMl6AyIClvj+9sI+LC7ciYfoPRcYMQOigHvxS08LVlYBA3twhgAAAAUAAP+NA80DIgAOAB0ALAA7AEQAAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcOAQc+ATcXJgHzqv8AFhCGgXwBEc5HWtWHERed6REMkIKB/vxPTQdYOZ9hkNIHBJ+AeN04NSxcMXpDf7YCAZl2b74jH0teJFEqIjgiIDwgfT8DIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZvY8pjIUUhh8gABgAA/40DzQMiAA4AHQAsADsAQwBKAAABBgQHBhYXFiQ2EgImJyYHNhYXFgYHBiQnJhI3PgEXIgYHBhYXFjY3NiYnLgEHHgEXDgEHBiYnJjY3PgEXBgcXITY3JicWFwcjJzYB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRKmtsUgEKKihrbF1eSOZIXgMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFldOTv1/fk4wQ0Tc3EQAABAAAP+gA7sDIgAIABEAHgAsADsASQBYAGYAdQCEAJMAogCvAL4AzADbAAABDgEHPgE3FyYnFhcnDgE1PgETDgEHBhY3NhcyNicmFyIGFx4BFxY2Jy4BJyYFDgEHDgEHBhY3PgE3NiY3IgYHBhY3NhYXFjYnJgcOAQcOAQcGFjc+ATc2JgUiBhceARcWNicuAScmBSIGBwYWFxY2Jy4BNzQmBSIGFxYGBwYWNz4BJy4BBSIGFx4BFxY2Jy4BNy4BBSIGFQ4BBwYWNz4BNy4BBQ4BFx4BFxY2JyYnJgUOAQcOAQcGFhc+ATc2JgUOARceARc+AScuAScmBQ4BBw4BBwYWNz4BNzYmAfQiOCIgPCB9Pz0iIkQRMRIeER89HRIPFWFjFAcSMssUChEnPRUNIwUYSS4D/fQQFwwgMREEIw0UPigJC/kQIQgFGA8mTCMUDxBF5xEfDhotDwUkDBc+JAsLAXkTCg8cJgsNIwQNLyIG/cURDAEFCA0LJQINBQgNAukQDAMBGRcFIw0dGwQCDfyjEA0DARkZDSIFFxcBAgwC7BAMCCEWByMOHSYGAQ39qBEIDB5KKxQNEE83BgGfESARGjYaEggUL1ooDAr+NxIIDypjNRQIEzFbJwYCGBAZDiBIJRENFTZkKgoMAiZjymMhRSGHyHVtbkoROgc1awGEAQcKDCQEGRYmCQxTJQodSysPERQzViECCgIXCx5IKBQPEC5PIAwbAQMPEBQEAw0PBCQMHycEFAoUMBwVEBAjNxQMHDoiDB1GJhEQFS1RIASqGw4pUycRDBQoUykKDi0ZDjNjLRQQDzZ5PggKEBkONGQtDxIULWIyCAs4GQ4kQR0UFBAlVi8JDqACIAsjNA8CJAsfQQZNBBIFCQcDCSUBARkYDB4mAiIKIi8KASYICywgAwMDFgcVGwkLJQILMCQMGwAAAAUAAP+NA80DIgAOAB0ALAA7AEMAAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcUFSMVMxU3AfOq/wAWEIaBfAERzkda1YcRF53pEQyQgoH+/E9NB1g5n2GQ0gcEn4B43Tg1LFwxekN/tgIBmXZvviMfS14kUVzi4qUDIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZ0MjK+ZMMAAA0AAP+iA7gDIAAEAAgADAAQABQAGABTALwBRQGiAekCMwKfAAABFREhEQUzESMTFTM1BxUzNQcVMzUHFTM1AysBByMHIwcVDwUVHwUzPwMzNzM3MzczFzMXMxczHwEzPwM1LwQjNSMnIycXDwYVHwozHwYVHwIzHw0zPwQ1LwE1JyMvBiMvATUjLwsjLwEjLwcjNSc1LwQjBQ8BIw8EFQ8EFQcjBxUPAyMVBxUHIxUPBBUHIw8BFQ8CFQ8CIw8DFQ8DFQcVDwoVBxUfBD8EMz8ENT8mNS8DAQ8FFRcVBxUHFQcVBxUHFQcVBxUHFQcVBxUHFQ8HFR8EPwUzPwEzPwE1PwEzNzM3NTc1MzU3NTc1NzU3NTc1NzU3NTc1JzUvBAUPBRUXFRcVFzMfBTMfARUXFRcVFxUzFxUXFR8EPwQ1Lw01JzUnNSc1LwMBDxcfBD8EMz8DMzczNzM3MzczNzU3Mzc1NzM/AjM3MzU/AzUvBAUPBRUfAxUfATMfAjMfAhUfATMfARUfATMXMxczFzMfAjMXMxcVMx8HMxcVFzMVMxczPwQ1LwQjJyMnIycjLwojLwQjLwUjAV0BLv7q/v4aysrKysrKymEHDQYNDQcnDQ4EAwMEAQIDAwkEBQYMBhcGCwYGBgYpBgYGBgYFHwQFDAMDAgIGAwonBgcGDQfpBQQEAwMBAgICBgICAwYFBAMIAQ4CCAIGAgQBAgIBAgMCAwUEAwQDCgUGAwkECQQEAwQCBAYBBAMCAwIDAgECCAEFAwQCBAICBQIHAgIBAgkBAgIDBwMCAwIBAgMCBgIKBf3zBQcBAgMCAwIDAgMCAwQBAgIDAgQBBAQBAgICAgICAQICAgQCAgQBAQECAwICCgECAgIBBAECAQIBAgECAgEEBAMOBAgEAwEBAgMBAgICAQIBAgECAQICAwIBAggCAQICAgEEAgQBBgIKAgYDCgMGAwUDAgEEBggFArIEBQMGAgEBAQEBAQEBAgEDBQMFAwQDAgYDAQIDBgQJCQQEAwIBAQMCAQIDAwIBBQEMAwECAQEBAQEBAQEEAwQECPymBAUDBAQBAQMCAQMCAQQBCgEEAwIDAgECAwECBAcJCQQEAwQCBAIDAgcEAQYBAgECCAEBAQEFCAgCsQQECQQFCgQPBQULDwYFCwUhBgsQCAQFAgIEAwQNCQYGFAUBEgYHBQEFAQUBBQEcAQsFAQUFAQULDwEEAQMDAgEEAwQECP3eBAQEAwICAQIDBA0CAQIDAgECAwMLAgEIAwMFAQIBAgECAQIDAwECAQIBAgQDBgMNAx0CAw0EAw0JBQgFAgEEAwQEAwQIAxQCEQMJBRECBgUDBQUFAgEPAgUCAgEEAwQRBAQFAhwM/pABfBj+tAEnGRlKGBhVGBhNGBgCLQECBgECBAIDBAgJBQQEAwQBAgICBAIBAQEBAQUBBgQDCQUICAIEBgEBAU8BAQMDBAQEBQkEBgECAQYDBAIIDgMIAwYDBAECAgMEAwQDBwcDCAMSCggCBAICAwMICgcHAQwIBAQEBAQEBAsBBwMGAgYCAwUDBwMCAwkDAgIHAgICAgEBAQICBAIFDAEEAgICAgIBAgICAgIBBAIBAgIDBAEEAQQBAgMCAwIBAgMCAQIGAgECBgMDAgUCAQIPAwIBAgECAwYDAwMDAwMDAwEECQUIAwMDAQQDAwQGBQMCBQECAwIDAgMCAwMCBQIDAgwCAwIDAgMEAwQDBgMKAwYCCgEGAgUEBAQJCQYEAf7GAQICCAQEBAQzAwkDBgIGAwMDAwMDBgIDAwkCDgMIAQ0FCwUGCgcEBQkEBgICAgIDAwMDBgYGBQEFBw8mAwoDAwcDAwQDAwQDAwQDBwMOAywFCQgEAgMCEwECAwMIBBsGBxMHDRMGBw0GHw0FAQUBBQEFAQUBBQEBBAQEAgICAwMJCQgGBgUGEAsGEQUGBgUvBgUGBgwGBwUHBgL+sgECBgQEBgQJBAMFCQIDBAMMAQQDBAMHCQkIAwMDAgIBBgIGAwIDAgMDDwYBAwMBAwQHDAQBAwQEBAkIBAMCAgIBAwIEBAkEBQQEAwEKAgICAgICAQEHAgUBAQEDAgIBAgECAQEBAQECAgIEAgkBAQQBBAEEBwUECQgEAgMBAwcGAwMGAgIDAQMCAwIJAgMCAQQBBA0BAgAAAAQAAAAAAu4CpAANABMAFgAdAAATFRQxESERMDE1IjEnNQUhFTMRIQEXIycVIxUzFTf6AfQBpv64AUOn/hYBSJ6ekXNzVQKkAgH9dwHmAqICBaP+IQJ+mjI3VDdhAAAAAAgAAP/TA9QC6QAPAB8ANgBMAFQAXABkAGwAABMOAQcRHgEXIT4BNxEuAScFIR4BFxEOAQchLgEnET4BFzEOARQeAwYPATM+AS4ENj8BBzMGBwYeBAYHIzY3Ni4ENhciFDsBMjQjByIUOwEyNCMHIhQ7ATI0IwciFDsBMjQj11JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUyRNCkbJRwGIi0L6S4jBR4kGgEpMQvmzSoTFgEcJB0FIS3NJRATBh4lGQEoEwMDewQEbgQEbwQESgQEfAQEYwQEfAMDAukCblL+blJuAgJuUgGSUm4CPAFLOv5uOksBAUs6AZI6S1ofMy0nJCMkLBsGHC4rJCQlKDAeBgcbFhotJyQjJCsbGBQXKyQkJSgvHgcHRQcHRQcHRQcHAAQAAP/TA9QC6QAPAB8AIgAnAAATDgEHER4BFyE+ATcRLgEnBSEeARcRDgEHIS4BJxE+AR8BNwURIREH11JvAgJvUgI6U24CAm5T/cYCOjpMAQFMOv3GOkwBAUwj6+v+KgHW6wLpAm5S/m5SbgICblIBklJuAjwBSzr+bjpLAQFLOgGSOktcgoJL/twBJHUAAAUAAAAAAzkCmgAjADkATwBlAHsAAAEiDgIHFTAxFTAxER4DMj4CNxEwMTUwMTUwMTUuAwcyHgIXDgMiLgInPgE3PgE3NgUWFx4CMj4BNzY3FQ4DIi4CJxUWFx4CMj4BNzY3FQ4DIi4CJxUWFx4CMj4BNzY3EQ4DIi4CJwH0O29cOQYGOVxvdm9cOgUGOVxvOztvWzYFBTZbb3ZvWjcFBTctHUUlJ/7pCRQdXG92b1wdFAkDOFtvdm9aNwUJFB1cb3ZvXB0UCQM4W292b1o3BQkUHVxvdm9cHRQJAzhbb3ZvWjcFApoKFB0VSkn+vBUeFAkJFB4VAURJSQEVHRQKBQoUHRESHRMKChMdEhEdCgYJAgNYDwoPEwoKEw8KDz0SHRMKChMdEgwPCg8TCgoTDwoPPRIdEwoKEx0SDA8KDxMKChMPCg/+yRIcFQkJFRwSAAkAAP+gA70DIQAIABEAHwAtAEAATwBeAG0AfwAAAQ4BBz4BNxcmJxYXJw4BNT4BEyIGBwYWNz4BFz4BJyYXIgYXHgEXFjYnLgEnJgUGDwEOAQcOARY2NzY3PgE3NCYBIgYXFgYHBhY3PgEnLgEFIgYXHgEXFjYnLgEnLgEBDgEHDgEHBhY3PgE3NiYhDgEXHgEXHgE3NiYnLgEnLgEB9CI4IiA8IH0/PSIiRBExEh4VIEEeEQ8UMGQwFQcTL8kUCREoOxcQIAgZRiwF/fEPDBYbKxIIBhoYBCExCxkCDQKtEAwDAxgZBSMNHxoHAg38pBANAwIbFw0jBRcXAQIMAq4QGQ4gRyUSDxQ2YyoKDP3TEggPJFMsDR8JBxEOKlAiBQwCJmPKYyFFIYfIdW1uShE6BzVrAYIHCgwlBAwCCgEmCAxQJQodTSsOFhMxVSADCwMLFRo+IQwbExAOPzQLEhAJDv7IGw4zYy0UEQ83ez8ICBIaDjNkLQ8RFC1jMggL/rMDFggVHAoLJQMMMSQMGwIiCh4pDAUFDw4XAQojHAUIAAAAAAYAAP+NA80DIgAOAB0ALAA7AEAARgAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BBxYXNjcFFBUhEQcB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRfVZVVFb+hQGayQMiAuGpj/1BPCK4AQgBAqUKAjEB0JuK6jAtT29xARBpRE4ryJCDzx0XaG1t8FErMDABtH92sw8MdmtozTcVFptFRUVFIIyMARKjAAAQAAD/oAO7AyIABgAOABsAKQA4AEYAVQBjAHIAgQCQAJ8ArAC7AMkA2AAAASYnBxchNjcGByMnNjcWAw4BBwYWNzYXMjYnJhciBhceARcWNicuAScmBQ4BBw4BBwYWNz4BNzYmNyIGBwYWNzYWFxY2JyYHDgEHDgEHBhY3PgE3NiYFIgYXHgEXFjYnLgEnJgUiBgcGFhcWNicuATc0JgUiBhcWBgcGFjc+AScuAQUiBhceARcWNicuATcuAQUiBhUOAQcGFjc+ATcuAQUOARceARcWNicmJyYFDgEHDgEHBhYXPgE3NiYFDgEXHgEXPgEnLgEnJgUOAQcOAQcGFjc+ATc2JgLLa2zXUgEKKgwkJOZIXl1dXR89HRIPFWFjFAcSMssUChEnPRUNIwUYSS4D/fQQFwwgMREEIw0UPigJC/kQIQgFGA8mTCMUDxBF5xEfDhotDwUkDBc+JAsLAXkTCg8cJgsNIwQNLyIG/cURDAEFCA0LJQINBQgNAukQDAMBGRcFIw0dGwQCDfyjEA0DARkZDSIFFxcBAgwC7BAMCCEWByMOHSYGAQ39qBEIDB5KKxQNEE83BgGfESARGjYaEggUL1ooDAr+NxIIDypjNRQIEzFbJwYCGBAZDiBIJRENFTZkKgoMAaJOTpz9f3VvbdxEQ0MBRQEHCgwkBBkWJgkMUyUKHUsrDxEUM1YhAgoCFwseSCgUDxAuTyAMGwEDDxAUBAMNDwQkDB8nBBQKFDAcFRAQIzcUDBw6IgwdRiYREBUtUSAEqhsOKVMnEQwUKFMpCg4tGQ4zYy0UEA82eT4IChAZDjRkLQ8SFC1iMggLOBkOJEEdFBQQJVYvCQ6gAiALIzQPAiQLH0EGTQQSBQkHAwklAQEZGAweJgIiCiIvCgEmCAssIAMDAxYHFRsJCyUCCzAkDBsAAAAAEAAA/6ADuwMiAAMACAAVACMAMgBAAE8AXQBsAHsAigCZAKYAtQDDANIAAAEGByEDFhchNhMOAQcGFjc2FzI2JyYXIgYXHgEXFjYnLgEnJgUOAQcOAQcGFjc+ATc2JjciBgcGFjc2FhcWNicmBw4BBw4BBwYWNz4BNzYmBSIGFx4BFxY2Jy4BJyYFIgYHBhYXFjYnLgE3NCYFIgYXFgYHBhY3PgEnLgEFIgYXHgEXFjYnLgE3LgEFIgYVDgEHBhY3PgE3LgEFDgEXHgEXFjYnJicmBQ4BBw4BBwYWFz4BNzYmBQ4BFx4BFz4BJy4BJyYFDgEHDgEHBhY3PgE3NiYB9GBgAYDAS0z+0kxLHz0dEg8VYWMUBxIyyxQKESc9FQ0jBRhJLgP99BAXDCAxEQQjDRQ+KAkL+RAhCAUYDyZMIxQPEEXnER8OGi0PBSQMFz4kCwsBeRMKDxwmCw0jBA0vIgb9xREMAQUIDQslAg0FCA0C6RAMAwEZFwUjDR0bBAIN/KMQDQMBGRkNIgUXFwECDALsEAwIIRYHIw4dJgYBDf2oEQgMHkorFA0QTzcGAZ8RIBEaNhoSCBQvWigMCv43EggPKmM1FAgTMVsnBgIYEBkOIEglEQ0VNmQqCgwCMqytASaHh4cBqgEHCgwkBBkWJgkMUyUKHUsrDxEUM1YhAgoCFwseSCgUDxAuTyAMGwEDDxAUBAMNDwQkDB8nBBQKFDAcFRAQIzcUDBw6IgwdRiYREBUtUSAEqhsOKVMnEQwUKFMpCg4tGQ4zYy0UEA82eT4IChAZDjRkLQ8SFC1iMggLOBkOJEEdFBQQJVYvCQ6gAiALIzQPAiQLH0EGTQQSBQkHAwklAQEZGAweJgIiCiIvCgEmCAssIAMDAxYHFRsJCyUCCzAkDBsAAAAABQAA/40DzQMiAA4AHQAsADsAQwAAAQYEBwYWFxYkNhICJicmBzYWFxYGBwYkJyYSNz4BFyIGBwYWFxY2NzYmJy4BBx4BFw4BBwYmJyY2Nz4BFwYHFyE2NyYB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRKmxrUgEKKihrAyIC4amP/UE8IrgBCAECpQoCMQHQm4rqMC1Pb3EBEGlETivIkIPPHRdobW3wUSswMAG0f3azDwx2a2jNNxUWV05O/X9+TgAAAAAKAAD/oAO9AyEABAALABEAHwAtAEAATwBeAG0AfwAAARQVIREFMjMOAQcmNxQVITUXEyIGBwYWNz4BFz4BJyYXIgYXHgEXFjYnLgEnJgUGDwEOAQcOARY2NzY3PgE3NCYBIgYXFgYHBhY3PgEnLgEFIgYXHgEXFjYnLgEnLgEBDgEHDgEHBhY3PgE3NiYhDgEXHgEXHgE3NiYnLgEnLgEBJwGa/sFych49HjXY/sicBCBBHhEPFDBkMBUHEy/JFAkRKDsXECAIGUYsBf3xDwwWGysSCAYaGAQhMQsZAg0CrRAMAwMYGQUjDR8aBwIN/KQQDQMCGxcNIwUXFwECDAKuEBkOIEclEg8UNmMqCgz90xIIDyRTLA0fCQcRDipQIgUMAfqcnAE4MRQ6BysOXV26fQHwBwoMJQQMAgoBJggMUCUKHU0rDhYTMVUgAwsDCxUaPiEMGxMQDj80CxIQCQ7+yBsOM2MtFBEPN3s/CAgSGg4zZC0PERQtYzIIC/6zAxYIFRwKCyUDDDEkDBsCIgoeKQwFBQ8OFwEKIxwFCAAAAAEAAAAAA2sCFgAaAAABDgEHFT4BNzYWFx4BNz4BNzUOAQcOAScuAScBRjppJiZTMzlqMypaLzVfJRIuGCRTKEeMTQIWAXBco0R5DghTLycsBgRcS64oOBkuGho2eAsAAAgAAP/TA9QC6QAPAB8AZwCYAK4BBAGgAi4AABMOAQcRHgEXIT4BNxEuAScFIR4BFxEOAQchLgEnET4BFx0BBzEGBycHFwYHIxUzHgEXBxc3FTMXFhcVMwcXNxYXFTMnMzU2NzkBNjcXNyc2PwE1Iy4BJzcnBzUjJicmJzUjNycHJic1BzMVFxYfATcXByMVLgEHDgEXOQEWFyMVByc3JyYnOQEmLwEjNTM1Nj8BJzcXNzY/ARcyFhcVBzEGBycHFwYHIyYnMSY2NzYXMxUfAjAyFDEXMBQzFTMXNTcXBxcWFzkBFh8BMxUjBwYPARcHJwcOAQ8BFSM1JyYvAQcnNzMnNSYnNCM5AjQjJyY1JyM1Myc1Nj8BJzcXNzY/AR8BIjkBMDkBIjAxIzgCOQEGBzEOAQcxOAExFTAxFTEwMRU4ATEVMDEVMDkBMhUxOAExFTgBOQEWFTE4AjkBMBcxOAIxFzAWMBQWOQEUMhQwMRc4AjkBHgE3PgEnJicxMDEnMDkBJjkBMDkBJjEjNCMxOAExJzAxIzUwIzEiJzEwMSMwMSMwOQEmIzEwMSMwJzEwMSMiMSMwMQcyOQEyMTMwMTMwMRcwMTMwMTM4ATI5ARYxMzIXMTIxMxYxMzgBOQEWOQEyMRcyMRczFzAzMRYXFgYHMQYmJzE4AjkBLgExNTAiNTEwJjgBNDAxJicxMDQwMTU4AjEnOAExNTA0OQEwJzE4AjE1MDQxNTgBMTUwMTU4ATkBPgE3NjcxMDIxMzgBMjHXUm8CAm9SAjpTbgICblP9xgI6OkwBAUw6/cY6TAEBTGYSCAkXJhcJBSEiAggEGCYUFwwBAwQTJhkQEjEFCgkJCQcZJhkLAyEhAQgFFycTFwUGAQMGFCcXEBIsIgQUEgQVGBMiEC0XHRcMBwwPFBgXAgYEBAIBICAEDAIWGBYECAoYEREdCRIJBxgmGAsDAxEIChMZDE4iCQ4LAgMCAQYTGRYCBgQFAQEfHwEECwIXGBcECBQKBCIEFREEFxgTBwUGAwEBBAEBICYGBAwCFhgWBAgKFQMSAgEDDAsUGAIBAQEBAQEBAg80Gx0XDAoXAgICAQICAgECAgIBAQEDAgIBAgIBAQICAgICAQEBAgEBAQECAQEBAQEBAQETCQoUGBgtDQEBAQEBAQEBAhQRCwkBAgEC6QJuUv5uUm4CAm5SAZJSbgI8AUs6/m46SwEBSzoBkjpLNAUcBgQFGCYYDxM2CREIGCYUBQQGBRgTJhgJBSIFHgIDBQQYJhgQEgE1CRIHFyYTBQMBBgYWEyYXCQUhCh8BBAsDFhgTDxEKCQ02Hg8LIxQYFwMJCQsJBCIEFREEFhgWAgYEBykQDgIGBAUYJhgPEwsTGTALBQkfAgQGAQEBAQQEExgWAwkJCgoEIgQUEgMXGBcDBQgCASEgAQQMAhcYEwcBBwgCAQ8CAgQiAwEVEQQWGBYCBgQGBRkBBQkfFAIGBQUBAgMBAgIFAQEBAgEFGBMLDTcdGQwBAQEBAQEBAQEKAQEBAQEBAQEKFRowCwkQFQMBAQIBAQMBAQICAgECBAEEBQIRHAcEAQAAAgAA/9MD1ALpAA8AHwAAEw4BBxEeARchPgE3ES4BJwUhHgEXEQ4BByEuAScRPgHXUm8CAm9SAjpTbgICblP9xgI6OkwBAUw6/cY6TAEBTALpAm5S/m5SbgICblIBklJuAjwBSzr+bjpLAQFLOgGSOksAAAADAAAAAAM7Ak0ABwAKAA0AAAEFFwU1BREFJxEtARElAfj+tgUBRQFD/r0K/tECcv7QAk3vBOvp6QHe6db+SNzc/kjcAAkAAP+gA70DIQAGAA4AHAAqAD0ATABbAGoAfAAAASYnBxchNjcGByMnNjcWAyIGBwYWNz4BFz4BJyYXIgYXHgEXFjYnLgEnJgUGDwEOAQcOARY2NzY3PgE3NCYBIgYXFgYHBhY3PgEnLgEFIgYXHgEXFjYnLgEnLgEBDgEHDgEHBhY3PgE3NiYhDgEXHgEXHgE3NiYnLgEnLgECy2ts11IBCioMJCTmSF5dXVkgQR4RDxQwZDAVBxMvyRQJESg7FxAgCBlGLAX98Q8MFhsrEggGGhgEITELGQINAq0QDAMDGBkFIw0fGgcCDfykEA0DAhsXDSMFFxcBAgwCrhAZDiBHJRIPFDZjKgoM/dMSCA8kUywNHwkHEQ4qUCIFDAGiTk6c/X91b23cRENDAUMHCgwlBAwCCgEmCAxQJQodTSsOFhMxVSADCwMLFRo+IQwbExAOPzQLEhAJDv7IGw4zYy0UEQ83ez8ICBIaDjNkLQ8RFC1jMggL/rMDFggVHAoLJQMMMSQMGwIiCh4pDAUFDw4XAQojHAUIAAUAAP+NA80DIgAOAB0ALAA7AD8AAAEGBAcGFhcWJDYSAiYnJgc2FhcWBgcGJCcmEjc+ARciBgcGFhcWNjc2JicuAQceARcOAQcGJicmNjc+ARcGByEB86r/ABYQhoF8ARHOR1rVhxEXnekRDJCCgf78T00HWDmfYZDSBwSfgHjdODUsXDF6Q3+2AgGZdm++Ix9LXiRRKmBgAYADIgLhqY/9QTwiuAEIAQKlCgIxAdCbiuowLU9vcQEQaUROK8iQg88dF2htbfBRKzAwAbR/drMPDHZraM03FRZjrK0AAAAAFAAA/6MDuAMiAAQACAAMABAAFAAYAFsAswEJAUwBoQH+AkkCiwLPAxIDaQO2BAIETAAAARURIREFMxEjExUzNQcVMzUHFTM1BxUzNQMxIwcjByMVIwcjDwcVHwQzNzM3MzczNzM3MxczFzMXMxczFzM/BTUvBSMnIzUjJyMnFyMPBR8ZPwQ1LwMjJzUnNScjLwEjLwE1JyMnNS8BIy8BNSc1JyM1JyMnIy8BNS8BIyc1JyMvAQUjDwIVByMPARUPAhUHFQcVDwEjDwEVDwIVDwEjDwEjDwEVBxUPASMPAhUfBTM/GTUvBCExIxUjDwMVHwQzNzM3MxczFzMXMxczFzMfBjM/BTUvAiMvCSMnIycjJyM1ByMPAiMPARUHIw8BIwcVByMHIwcjBxUPAyMVDwEVDwIjDwEfBTM/HTM/Ay8DBQ8FHxYVHwQzPwQ1JzUvCDUnNS8EIycjJzUvASMnNSc1LwE1Iy8BNScjJzUvAjUvAwUjDwUVIxUHFQcVIxUHFRcVMxUXFRcVFxUfCTM/BDUvAjUnNSc1JzUnNSc1NzU3NTc1NzU3NS8EBSMPAxUHFxUHFQcVBxUHFQ8IFR8DMz8GNTc1Pwc1NzUzNTc1NzUnNS8DBSMPAxUXFRcVFxUXFR8HFRcVHwIzFR8DMz8ENS8LNSc1JzUnNSc1LwQFIw8FFQcVDw8VHwU/AjU/ATU3Mzc1PwIzPwo1Ny8EBQ8FHwIVFxUXMxczHwIzHwEzFRcVFxUXMx8BMxczFxUXFR8BFR8CFR8CMz8FNS8cBSMPCCMHIwcjByMHIwcjDwQVHwUzNzM3MzczNzM/CzM3Mz8BNT8BNTc1PwQ1LwQFDwUVHwUzHwEVFzMXMx8BFR8BMxcVHwQzFzMfBjM/BTUvFiEjDxcVHwYzPwgzPwQ1NzM3Mzc1PwE1PwEzPwQ1LwQBXQEu/ur+/hrKysrKysrKZQsGCwUMBQUGJgYKCAQCAwEBAgYECQQrBQkFBQUFCgUeBQoFBQUFCgQYCQUEAwQEAQEEAwQHJgUGBQsGCwb0BQQFAwQEAgIIAgwHCAcEAwQDBAMHBgcPAgkCAxEEAwQJCQQEAwQBAgMCAQIDAgECEgEJBAYBAwQDAQMIBAMBAwEDAQgEBAQBBAgBBAr98QUECAUEAQQEBAwEBAQIAwEDBAMEAwQJAQ8CAQIDAwUCAQQDAwECAwMIBAkFBwUFEAYCBgIPBwYHAwQDBAMEBwgEBAcCAQICAwQIAQQSDQoFBwYCAgMICAQBCAQmBAgDBAQEBwQIAxoDCAcHAwkFBAQEAwQBBAMHAQMFBAQEBAQJBCYECQUEBAUNrQQIBgcBAwgDARUDAQMDAQkBDAEJCQMDAgECAwMIBAEEAgICAwMIBAUECQMIAwIEAwIDAgMCAwIDAwMCAwMDAwMDAwMGAyMCAwQEAgIFBAgBhAUIBAMDAwEGAwMCAwIDAgMCAwcWAQQBBAEGAwICBAQDBAUJBAQEAwQBAgICAQIBAgECAgIBAQEIAQEBAgIEAQIHAwIBAgMCAQIGAwkDAwME/cMFBAgDAwICAQIBAQEBAQECAQgCAQEBAwMEBAQFCQQDAwQBAgUDAgEBAQEBAQIBAQIDAwkC7gUECAYCAQEBAQECCAIBAgIEARYBAQQDDAUJBAYFBAMKAggBAgECAgIHAQEBAQEEAwQI/KcFCAgEAgEBAQIGAgICAQQBBgIKAwQBAwYEBQkEBAQDBAIBEgECAQIBAgICBwIBAQEBAgcDBQLwBAUEBAMEAgIHAgMFAgQBAgMMCgMEAgQBAQQDBAQJCAUHAw8CAQYFCAEBAQYBAgECAQICAgkBAgIDBAj9rQQIBAMCAgIFBgwGAQwBBgcDAQMDAQcHAwEHBwEDAQMECAQEDAQEBAQJBAQEBQIBAQQEAxUDBAoHGQMKAgMDAwMDAwMCBgMCAwIDAggBnAUEBAEHChwLBxIECwQHBAQHBAgEEAgEAwICAQQEAwQFDAUNBAUEBQgFJgQJBAQEBAQEAQQDAQMBAwQECAQJBAICAQIGAwQF/kQEBQQGAgIBAgMDBQQBBA0JAQ0BBAUFBAEEBQUKBRkBBAEUBgUFBQsKCQUEBAMEAQIDAwQHEwUEBQUEBQUEJR4IBAQJDAMNAhIFBAUDARQEBAkIFiwFBQQFBQUEBRsEBgQBAQIDAwQEBAkDBgULBQUFBhQBHgUKBQUEAQQBBAUcDQQBBAUDAgECAgMECAIcDP6QAXwY/rQBJxkZShgYVRgYTRgYAi8BAQEBBwICBAMEBAQJBAUGAwIJAgEBAQEBAQIFAQIDAwgEBQQJAwMDBwEBAQFTAQICBAcJCQoBCQcGBwMEAwQDBAcIBxQEDQQEIAMDAgICAgMDCAkFBgUFBAEEAQQFHA0EAQgEAQQEBAgBAwEDAQMECAMBAwQDAQYEBwgBBAQBAwQDAQMMAwEDAQMBCAQEBAEEBAQBBA0XBQUEAQQBCQUKBQwEBQQEAwQBAgUHDB4IBAkEFAcIBwQDBAMEAwcGBAMHBQQECQQEAwQBAgIFDAUJBAMGAgEBAQEBAgIHAgIDAgICAQIDAwgFCQgDBQIBAgECAQICAgkCAQEBJwIDBQIEAQIPAwIBAgkMCQEJBAMDAQMDAQMLBwcJCQQDBAQBAQQDDAMEBgMDAgMDAwMDAwIDAwIDAgMCAwIDBAMWAwMICQkHAwQ7AQIDAwQNBQsCAwMDAwMDAgMDCiMDBwMHBA4LAwcDCAMDAgEBAwIECAkEAgQJBAQEBAQFAwEDAQMEAQMQBAMBAwgDAQoBAwMBAwMBAwMBBgQJAQMCAwOpAQQEAwQIBAQJBQQJDQQbBQ0JBAQJBAEEIgQFAQQEAwMCAQICAwQICQUEEgQLBAcEBAcECAQeBAgEBwQEBwQECQQEBAMELQEECAQEBAQeBQoFBQUFCQUnBQQFCQoEMgQFBAgEBgICBggKBRkBBAEUBgUFBQsGJgUGBQsGCwYWBgkIAwMEEAIGCAgJBhEFBgUGCwUhBgsFBQoGDwEEARkFCgEEBgIBAQMCBAgJCAEpBAUFBAUFCQUiBQkFBQUFCgUXBQQHAgI5AQIDAwgHBAcEGgMLCwcGBAMHFA8DBwEIBQQFCAMDAgICAgcBAxUBAwsBBxAEBAwEBAQEBAQJBCYFBQgEBAMEoAEEAwMECQkJBgEMAQYMBgUDAwIBBAEEAQIFBAICAQEBBAEBAQYBAQECAQECAwcFBAUECAMDCQIBBgMQAwYDAgMCAwIDAgMGAgMDAwMDB0oBAgEDBgwDAwUDAgEBAQQDAwQJBQQIAwMCAQEBAQIJAgICAQIBAgEBAQICAgEBAQQBAQEFBAMFBAUICAMCAScBAQMGBAkFBAQEAgUDBAkBBgkDAgECAwIBAgMEAwoCCAECAQICAwECAwMIBQQJBAMDAwQCAQIBAgECARAQBgIDBQkDCgECAgIPAgMFBgwUAQIBAgECAQIGAgYJBAUEBAQDAwIBAQECAgIBAgEIDAMEAwIBAgMCAQISAQkEAwUEBAQFCQQDAwQAAAAAAwAAAAADuQKOAAMABwALAAATESERBxEhESMzESMvA4ox/WKMXl4Cjv2PAnEw/esCFf3rAAQAAP+cA8MDIAADAAcADgAVAAABETMRMxEzEQEHFzUzNSMlFQcVMxU3AW4mwyb+UKSkXV0CU15eowMg/HwDhPx8A4T+4aOjb2lubAFqb6MABgAA/54DlAMeAAYACQANABEAFQAZAAABBRcBFwEXJQUXJwcXNw8BFzcPARc3DwEXNwOU/mZA/hoZAeY+AQP+ZZeVPxk/lz4ZPp4/GT+XJhkmAx5tX/65JgFIXAVt4FgrJSovKiYrNSslKzAaJRoAAAkAAP+nA7IDHgADAAcACwARABUAGQAfACUAKQAAARUzNQUVMzUzFTM1FxUzFTM1BRUzNQUVMzUHFSMVMzUFFTM1IzUXFTM1AS9n/qHaoduCeyj9fWcB9Cgod5/9np934FIDHtra9mdnZ2ceKHWdaNran01NvnQonAGdKHV1KCgAAAASAN4AAQAAAAAAAAAVAAAAAQAAAAAAAQAEABUAAQAAAAAAAgAHABkAAQAAAAAAAwAEACAAAQAAAAAABAAEACQAAQAAAAAABQALACgAAQAAAAAABgAEADMAAQAAAAAACgArADcAAQAAAAAACwATAGIAAwABBAkAAAAqAHUAAwABBAkAAQAIAJ8AAwABBAkAAgAOAKcAAwABBAkAAwAIALUAAwABBAkABAAIAL0AAwABBAkABQAWAMUAAwABBAkABgAIANsAAwABBAkACgBWAOMAAwABBAkACwAmATljYW11bmRhIFNlcnZpY2VzIEdtYkhicG1uUmVndWxhcmJwbW5icG1uVmVyc2lvbiAxLjBicG1uR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20AYwBhAG0AdQBuAGQAYQAgAFMAZQByAHYAaQBjAGUAcwAgAEcAbQBiAEgAYgBwAG0AbgBSAGUAZwB1AGwAYQByAGIAcABtAG4AYgBwAG0AbgBWAGUAcgBzAGkAbwBuACAAMQAuADAAYgBwAG0AbgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAAABAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEMc2NyZXctd3JlbmNoBXRyYXNoEGdhdGV3YXktcGFyYWxsZWwfaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWNhbmNlbDFpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1tZXNzYWdlGHN0YXJ0LWV2ZW50LWNvbXBlbnNhdGlvbi5zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLXBhcmFsbGVsLW11bHRpcGxlC2xvb3AtbWFya2VyCXVzZXItdGFzaw1idXNpbmVzcy1ydWxlEnBhcmFsbGVsLW1pLW1hcmtlciNzdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLXNpZ25hbC9pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy10aW1lcippbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtcGFyYWxsZWwtbXVsdGlwbGUlaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWNvbXBlbnNhdGlvbgtnYXRld2F5LXhvcgpjb25uZWN0aW9uEGVuZC1ldmVudC1jYW5jZWwiaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWNvbmRpdGlvbjtpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1wYXJhbGxlbC1tdWx0aXBsZRVzdGFydC1ldmVudC1jb25kaXRpb24ic3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy10aW1lchpzZXF1ZW50aWFsLW1pLW1hcmtlci1rb3BpZQZtYW51YWwHcmVjZWl2ZRJzdWItcHJvY2Vzcy1tYXJrZXIdc3RhcnQtZXZlbnQtcGFyYWxsZWwtbXVsdGlwbGURc3RhcnQtZXZlbnQtZXJyb3IfaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLXNpZ25hbB5pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtZXJyb3IWZW5kLWV2ZW50LWNvbXBlbnNhdGlvbhRzdWJwcm9jZXNzLWNvbGxhcHNlZBNzdWJwcm9jZXNzLWV4cGFuZGVkBHRhc2sPZW5kLWV2ZW50LWVycm9yI2ludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1lc2NhbGF0aW9uHmludGVybWVkaWF0ZS1ldmVudC1jYXRjaC10aW1lchZzdGFydC1ldmVudC1lc2NhbGF0aW9uEnN0YXJ0LWV2ZW50LXNpZ25hbBJidXNpbmVzcy1ydWxlLXRhc2sGc2NyaXB0BHNlbmQNY2FsbC1hY3Rpdml0eRFzdGFydC1ldmVudC10aW1lchNzdGFydC1ldmVudC1tZXNzYWdlF2ludGVybWVkaWF0ZS1ldmVudC1ub25lHWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1saW5rFGVuZC1ldmVudC1lc2NhbGF0aW9uD3RleHQtYW5ub3RhdGlvbgdicG1uLWlvD2dhdGV3YXktY29tcGxleBJnYXRld2F5LWV2ZW50YmFzZWQMZ2F0ZXdheS1ub25lCmdhdGV3YXktb3ITZW5kLWV2ZW50LXRlcm1pbmF0ZRBlbmQtZXZlbnQtc2lnbmFsDmVuZC1ldmVudC1ub25lEmVuZC1ldmVudC1tdWx0aXBsZRFlbmQtZXZlbnQtbWVzc2FnZQ5lbmQtZXZlbnQtbGluayBpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbWVzc2FnZSVpbnRlcm1lZGlhdGUtZXZlbnQtdGhyb3ctY29tcGVuc2F0aW9uFHN0YXJ0LWV2ZW50LW11bHRpcGxlCmRhdGEtaW5wdXQLbWFudWFsLXRhc2sHc2VydmljZQR1c2VyDHJlY2VpdmUtdGFzawtkYXRhLW9iamVjdBBzdGFydC1ldmVudC1ub25lI2ludGVybWVkaWF0ZS1ldmVudC10aHJvdy1lc2NhbGF0aW9uIWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1tdWx0aXBsZTRpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1lc2NhbGF0aW9uHWludGVybWVkaWF0ZS1ldmVudC10aHJvdy1saW5rJnN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uC2RhdGEtb3V0cHV0C3NjcmlwdC10YXNrCXNlbmQtdGFzawpkYXRhLXN0b3JlJ3N0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctZXNjYWxhdGlvbiBpbnRlcm1lZGlhdGUtZXZlbnQtdGhyb3ctbWVzc2FnZTJpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1tdWx0aXBsZTBpbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1zaWduYWwhaW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LW11bHRpcGxlJHN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctbWVzc2FnZQ1hZC1ob2MtbWFya2VyDHNlcnZpY2UtdGFzawl0YXNrLW5vbmUTY29tcGVuc2F0aW9uLW1hcmtlciVzdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLW11bHRpcGxlH2ludGVybWVkaWF0ZS1ldmVudC10aHJvdy1zaWduYWwzaW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uC3BhcnRpY2lwYW50CnNwYWNlLXRvb2wQY29ubmVjdGlvbi1tdWx0aQpsYXNzby10b29sAAA=') format('truetype');
+}
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
+/*
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+  @font-face {
+    font-family: 'bpmn';
+    src: url('../font/bpmn.svg?5069274#bpmn') format('svg');
+  }
+}
+*/
+ [class^="icon-"]:before, [class*=" icon-"]:before {
+  font-family: "bpmn";
+  font-style: normal;
+  font-weight: normal;
+  speak: none;
+  display: inline-block;
+  text-decoration: inherit;
+  width: 1em;
+  margin-right: .2em;
+  text-align: center;
+  /* opacity: .8; */
+  /* For safety - reset parent styles, that can break glyph codes*/
+  font-variant: normal;
+  text-transform: none;
+     
+  /* fix buttons height, for twitter bootstrap */
+  line-height: 1em;
+  /* Animation center compensation - margins should be symmetric */
+  /* remove if not needed */
+  margin-left: .2em;
+  /* you can be more comfortable with increased icons size */
+  /* font-size: 120%; */
+  /* Uncomment for 3D effect */
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
+}
+.icon-screw-wrench:before { content: '\e800'; } /* '' */
+.icon-trash:before { content: '\e801'; } /* '' */
+.icon-gateway-parallel:before { content: '\e802'; } /* '' */
+.icon-intermediate-event-catch-cancel:before { content: '\e803'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-message:before { content: '\e804'; } /* '' */
+.icon-start-event-compensation:before { content: '\e805'; } /* '' */
+.icon-start-event-non-interrupting-parallel-multiple:before { content: '\e806'; } /* '' */
+.icon-loop-marker:before { content: '\e807'; } /* '' */
+.icon-user-task:before { content: '\e808'; } /* '' */
+.icon-business-rule:before { content: '\e809'; } /* '' */
+.icon-parallel-mi-marker:before { content: '\e80a'; } /* '' */
+.icon-start-event-non-interrupting-signal:before { content: '\e80b'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-timer:before { content: '\e80c'; } /* '' */
+.icon-intermediate-event-catch-parallel-multiple:before { content: '\e80d'; } /* '' */
+.icon-intermediate-event-catch-compensation:before { content: '\e80e'; } /* '' */
+.icon-gateway-xor:before { content: '\e80f'; } /* '' */
+.icon-connection:before { content: '\e810'; } /* '' */
+.icon-end-event-cancel:before { content: '\e811'; } /* '' */
+.icon-intermediate-event-catch-condition:before { content: '\e812'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-parallel-multiple:before { content: '\e813'; } /* '' */
+.icon-start-event-condition:before { content: '\e814'; } /* '' */
+.icon-start-event-non-interrupting-timer:before { content: '\e815'; } /* '' */
+.icon-sequential-mi-marker-kopie:before { content: '\e816'; } /* '' */
+.icon-manual:before { content: '\e817'; } /* '' */
+.icon-receive:before { content: '\e818'; } /* '' */
+.icon-sub-process-marker:before { content: '\e819'; } /* '' */
+.icon-start-event-parallel-multiple:before { content: '\e81a'; } /* '' */
+.icon-start-event-error:before { content: '\e81b'; } /* '' */
+.icon-intermediate-event-catch-signal:before { content: '\e81c'; } /* '' */
+.icon-intermediate-event-catch-error:before { content: '\e81d'; } /* '' */
+.icon-end-event-compensation:before { content: '\e81e'; } /* '' */
+.icon-subprocess-collapsed:before { content: '\e81f'; } /* '' */
+.icon-subprocess-expanded:before { content: '\e820'; } /* '' */
+.icon-task:before { content: '\e821'; } /* '' */
+.icon-end-event-error:before { content: '\e822'; } /* '' */
+.icon-intermediate-event-catch-escalation:before { content: '\e823'; } /* '' */
+.icon-intermediate-event-catch-timer:before { content: '\e824'; } /* '' */
+.icon-start-event-escalation:before { content: '\e825'; } /* '' */
+.icon-start-event-signal:before { content: '\e826'; } /* '' */
+.icon-business-rule-task:before { content: '\e827'; } /* '' */
+.icon-script:before { content: '\e828'; } /* '' */
+.icon-send:before { content: '\e829'; } /* '' */
+.icon-call-activity:before { content: '\e82a'; } /* '' */
+.icon-start-event-timer:before { content: '\e82b'; } /* '' */
+.icon-start-event-message:before { content: '\e82c'; } /* '' */
+.icon-intermediate-event-none:before { content: '\e82d'; } /* '' */
+.icon-intermediate-event-catch-link:before { content: '\e82e'; } /* '' */
+.icon-end-event-escalation:before { content: '\e82f'; } /* '' */
+.icon-text-annotation:before { content: '\e830'; } /* '' */
+.icon-bpmn-io:before { content: '\e831'; } /* '' */
+.icon-gateway-complex:before { content: '\e832'; } /* '' */
+.icon-gateway-eventbased:before { content: '\e833'; } /* '' */
+.icon-gateway-none:before { content: '\e834'; } /* '' */
+.icon-gateway-or:before { content: '\e835'; } /* '' */
+.icon-end-event-terminate:before { content: '\e836'; } /* '' */
+.icon-end-event-signal:before { content: '\e837'; } /* '' */
+.icon-end-event-none:before { content: '\e838'; } /* '' */
+.icon-end-event-multiple:before { content: '\e839'; } /* '' */
+.icon-end-event-message:before { content: '\e83a'; } /* '' */
+.icon-end-event-link:before { content: '\e83b'; } /* '' */
+.icon-intermediate-event-catch-message:before { content: '\e83c'; } /* '' */
+.icon-intermediate-event-throw-compensation:before { content: '\e83d'; } /* '' */
+.icon-start-event-multiple:before { content: '\e83e'; } /* '' */
+.icon-data-input:before { content: '\e83f'; } /* '' */
+.icon-manual-task:before { content: '\e840'; } /* '' */
+.icon-service:before { content: '\e841'; } /* '' */
+.icon-user:before { content: '\e842'; } /* '' */
+.icon-receive-task:before { content: '\e843'; } /* '' */
+.icon-data-object:before { content: '\e844'; } /* '' */
+.icon-start-event-none:before { content: '\e845'; } /* '' */
+.icon-intermediate-event-throw-escalation:before { content: '\e846'; } /* '' */
+.icon-intermediate-event-catch-multiple:before { content: '\e847'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-escalation:before { content: '\e848'; } /* '' */
+.icon-intermediate-event-throw-link:before { content: '\e849'; } /* '' */
+.icon-start-event-non-interrupting-condition:before { content: '\e84a'; } /* '' */
+.icon-data-output:before { content: '\e84b'; } /* '' */
+.icon-script-task:before { content: '\e84c'; } /* '' */
+.icon-send-task:before { content: '\e84d'; } /* '' */
+.icon-data-store:before { content: '\e84e'; } /* '' */
+.icon-start-event-non-interrupting-escalation:before { content: '\e84f'; } /* '' */
+.icon-intermediate-event-throw-message:before { content: '\e850'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-multiple:before { content: '\e851'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-signal:before { content: '\e852'; } /* '' */
+.icon-intermediate-event-throw-multiple:before { content: '\e853'; } /* '' */
+.icon-start-event-non-interrupting-message:before { content: '\e854'; } /* '' */
+.icon-ad-hoc-marker:before { content: '\e855'; } /* '' */
+.icon-service-task:before { content: '\e856'; } /* '' */
+.icon-task-none:before { content: '\e857'; } /* '' */
+.icon-compensation-marker:before { content: '\e858'; } /* '' */
+.icon-start-event-non-interrupting-multiple:before { content: '\e859'; } /* '' */
+.icon-intermediate-event-throw-signal:before { content: '\e85a'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-condition:before { content: '\e85b'; } /* '' */
+.icon-participant:before { content: '\e85c'; } /* '' */
+.icon-space-tool:before { content: '\e85f'; } /* '' */
+.icon-connection-multi:before { content: '\e860'; } /* '' */
+.icon-lasso-tool:before { content: '\e862'; } /* '' */
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn.css b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/css/bpmn.css
new file mode 100644 (file)
index 0000000..fff9e2d
--- /dev/null
@@ -0,0 +1,152 @@
+@font-face {
+  font-family: 'bpmn';
+  src: url('../font/bpmn.eot?8685581');
+  src: url('../font/bpmn.eot?8685581#iefix') format('embedded-opentype'),
+       url('../font/bpmn.woff?8685581') format('woff'),
+       url('../font/bpmn.ttf?8685581') format('truetype'),
+       url('../font/bpmn.svg?8685581#bpmn') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
+/*
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+  @font-face {
+    font-family: 'bpmn';
+    src: url('../font/bpmn.svg?8685581#bpmn') format('svg');
+  }
+}
+*/
+ [class^="icon-"]:before, [class*=" icon-"]:before {
+  font-family: "bpmn";
+  font-style: normal;
+  font-weight: normal;
+  speak: none;
+  display: inline-block;
+  text-decoration: inherit;
+  width: 1em;
+  margin-right: .2em;
+  text-align: center;
+  /* opacity: .8; */
+  /* For safety - reset parent styles, that can break glyph codes*/
+  font-variant: normal;
+  text-transform: none;
+  /* fix buttons height, for twitter bootstrap */
+  line-height: 1em;
+  /* Animation center compensation - margins should be symmetric */
+  /* remove if not needed */
+  margin-left: .2em;
+  /* you can be more comfortable with increased icons size */
+  /* font-size: 120%; */
+  /* Font smoothing. That was taken from TWBS */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  /* Uncomment for 3D effect */
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
+}
+.icon-screw-wrench:before { content: '\e800'; } /* '' */
+.icon-trash:before { content: '\e801'; } /* '' */
+.icon-gateway-parallel:before { content: '\e802'; } /* '' */
+.icon-intermediate-event-catch-cancel:before { content: '\e803'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-message:before { content: '\e804'; } /* '' */
+.icon-start-event-compensation:before { content: '\e805'; } /* '' */
+.icon-start-event-non-interrupting-parallel-multiple:before { content: '\e806'; } /* '' */
+.icon-loop-marker:before { content: '\e807'; } /* '' */
+.icon-user-task:before { content: '\e808'; } /* '' */
+.icon-business-rule:before { content: '\e809'; } /* '' */
+.icon-parallel-mi-marker:before { content: '\e80a'; } /* '' */
+.icon-start-event-non-interrupting-signal:before { content: '\e80b'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-timer:before { content: '\e80c'; } /* '' */
+.icon-intermediate-event-catch-parallel-multiple:before { content: '\e80d'; } /* '' */
+.icon-intermediate-event-catch-compensation:before { content: '\e80e'; } /* '' */
+.icon-gateway-xor:before { content: '\e80f'; } /* '' */
+.icon-connection:before { content: '\e810'; } /* '' */
+.icon-end-event-cancel:before { content: '\e811'; } /* '' */
+.icon-intermediate-event-catch-condition:before { content: '\e812'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-parallel-multiple:before { content: '\e813'; } /* '' */
+.icon-start-event-condition:before { content: '\e814'; } /* '' */
+.icon-start-event-non-interrupting-timer:before { content: '\e815'; } /* '' */
+.icon-sequential-mi-marker-kopie:before { content: '\e816'; } /* '' */
+.icon-manual:before { content: '\e817'; } /* '' */
+.icon-receive:before { content: '\e818'; } /* '' */
+.icon-sub-process-marker:before { content: '\e819'; } /* '' */
+.icon-start-event-parallel-multiple:before { content: '\e81a'; } /* '' */
+.icon-start-event-error:before { content: '\e81b'; } /* '' */
+.icon-intermediate-event-catch-signal:before { content: '\e81c'; } /* '' */
+.icon-intermediate-event-catch-error:before { content: '\e81d'; } /* '' */
+.icon-end-event-compensation:before { content: '\e81e'; } /* '' */
+.icon-subprocess-collapsed:before { content: '\e81f'; } /* '' */
+.icon-subprocess-expanded:before { content: '\e820'; } /* '' */
+.icon-task:before { content: '\e821'; } /* '' */
+.icon-end-event-error:before { content: '\e822'; } /* '' */
+.icon-intermediate-event-catch-escalation:before { content: '\e823'; } /* '' */
+.icon-intermediate-event-catch-timer:before { content: '\e824'; } /* '' */
+.icon-start-event-escalation:before { content: '\e825'; } /* '' */
+.icon-start-event-signal:before { content: '\e826'; } /* '' */
+.icon-business-rule-task:before { content: '\e827'; } /* '' */
+.icon-script:before { content: '\e828'; } /* '' */
+.icon-send:before { content: '\e829'; } /* '' */
+.icon-call-activity:before { content: '\e82a'; } /* '' */
+.icon-start-event-timer:before { content: '\e82b'; } /* '' */
+.icon-start-event-message:before { content: '\e82c'; } /* '' */
+.icon-intermediate-event-none:before { content: '\e82d'; } /* '' */
+.icon-intermediate-event-catch-link:before { content: '\e82e'; } /* '' */
+.icon-end-event-escalation:before { content: '\e82f'; } /* '' */
+.icon-text-annotation:before { content: '\e830'; } /* '' */
+.icon-bpmn-io:before { content: '\e831'; } /* '' */
+.icon-gateway-complex:before { content: '\e832'; } /* '' */
+.icon-gateway-eventbased:before { content: '\e833'; } /* '' */
+.icon-gateway-none:before { content: '\e834'; } /* '' */
+.icon-gateway-or:before { content: '\e835'; } /* '' */
+.icon-end-event-terminate:before { content: '\e836'; } /* '' */
+.icon-end-event-signal:before { content: '\e837'; } /* '' */
+.icon-end-event-none:before { content: '\e838'; } /* '' */
+.icon-end-event-multiple:before { content: '\e839'; } /* '' */
+.icon-end-event-message:before { content: '\e83a'; } /* '' */
+.icon-end-event-link:before { content: '\e83b'; } /* '' */
+.icon-intermediate-event-catch-message:before { content: '\e83c'; } /* '' */
+.icon-intermediate-event-throw-compensation:before { content: '\e83d'; } /* '' */
+.icon-start-event-multiple:before { content: '\e83e'; } /* '' */
+.icon-data-input:before { content: '\e83f'; } /* '' */
+.icon-manual-task:before { content: '\e840'; } /* '' */
+.icon-service:before { content: '\e841'; } /* '' */
+.icon-user:before { content: '\e842'; } /* '' */
+.icon-receive-task:before { content: '\e843'; } /* '' */
+.icon-data-object:before { content: '\e844'; } /* '' */
+.icon-start-event-none:before { content: '\e845'; } /* '' */
+.icon-intermediate-event-throw-escalation:before { content: '\e846'; } /* '' */
+.icon-intermediate-event-catch-multiple:before { content: '\e847'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-escalation:before { content: '\e848'; } /* '' */
+.icon-intermediate-event-throw-link:before { content: '\e849'; } /* '' */
+.icon-start-event-non-interrupting-condition:before { content: '\e84a'; } /* '' */
+.icon-data-output:before { content: '\e84b'; } /* '' */
+.icon-script-task:before { content: '\e84c'; } /* '' */
+.icon-send-task:before { content: '\e84d'; } /* '' */
+.icon-data-store:before { content: '\e84e'; } /* '' */
+.icon-start-event-non-interrupting-escalation:before { content: '\e84f'; } /* '' */
+.icon-intermediate-event-throw-message:before { content: '\e850'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-multiple:before { content: '\e851'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-signal:before { content: '\e852'; } /* '' */
+.icon-intermediate-event-throw-multiple:before { content: '\e853'; } /* '' */
+.icon-start-event-non-interrupting-message:before { content: '\e854'; } /* '' */
+.icon-ad-hoc-marker:before { content: '\e855'; } /* '' */
+.icon-service-task:before { content: '\e856'; } /* '' */
+.icon-task-none:before { content: '\e857'; } /* '' */
+.icon-compensation-marker:before { content: '\e858'; } /* '' */
+.icon-start-event-non-interrupting-multiple:before { content: '\e859'; } /* '' */
+.icon-intermediate-event-throw-signal:before { content: '\e85a'; } /* '' */
+.icon-intermediate-event-catch-non-interrupting-condition:before { content: '\e85b'; } /* '' */
+.icon-participant:before { content: '\e85c'; } /* '' */
+.icon-space-tool:before { content: '\e85f'; } /* '' */
+.icon-connection-multi:before { content: '\e860'; } /* '' */
+.icon-lasso-tool:before { content: '\e862'; } /* '' */
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.eot b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.eot
new file mode 100644 (file)
index 0000000..4339c7f
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.eot differ
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.svg b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.svg
new file mode 100644 (file)
index 0000000..b80b8a9
--- /dev/null
@@ -0,0 +1,107 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>camunda Services GmbH</metadata>
+<defs>
+<font id="bpmn" horiz-adv-x="1000" >
+<font-face font-family="bpmn" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="screw-wrench" unicode="&#xe800;" d="m756 704c-55 0-108-22-147-61-39-39-61-92-61-147 0-55 22-108 61-147 39-39 92-61 147-61 91 0 171 59 198 146l-149-40-116 77 62 124 79 21 78 21c-39 42-94 67-152 67z m-247-278l-461-316c-14-42 32-111 80-114l451 310c-36 31-61 73-70 120z" horiz-adv-x="1000" />
+<glyph glyph-name="trash" unicode="&#xe801;" d="m429 743c-58-4-70 11-71-52l0-9-172-56c-20-5-20-29 0-30l624 0c19 0 19 25 0 30l-168 55 0 10c0 62-7 48-71 52l-71 0z m-215-204c-14 0-25-12-24-26l50-555c1-12 11-22 24-22l457 0c13 0 23 9 25 22l64 554c2 15-9 27-24 27l-143 0-143 0z m27-49l259 0 259 0-59-505-414 0z m120-73c-1 0-2 0-3 0-16-1-28-15-25-31l44-320c2-15 16-26 31-24 15 2 25 17 22 32l-44 319c-2 13-12 23-25 24z m280 0c-13 0-25-10-27-24l-44-319c-3-15 7-30 22-32 16-2 29 9 31 24l44 320c3 16-9 30-26 31z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-parallel" unicode="&#xe802;" d="m500 802c-9 0-19-4-26-11l-415-415c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-7 7-17 11-26 11z m0-62l390-390-390-390-390 390 390 390z m-11-161c0 0-4-1-4-1 0 0-4-3-4-3 0 0-3-4-3-4 0 0-1-4-1-4l0-194-194 0 0 0c0 0-4-1-4-1 0 0-4-3-4-3l0 0c0 0-3-4-3-4 0 0-1-4-1-4l0-21c0 0 1-5 1-5 0 0 3-4 3-4 0 0 4-3 4-3 0 0 4-1 4-1l194 0 0-194 0 0c0 0 1-4 1-4 0 0 3-4 3-4 0 0 4-3 4-3 0 0 4-1 4-1l22 0c0 0 4 1 4 1 0 0 4 3 4 3 0 0 3 4 3 4 0 0 1 4 1 4l0 194 194 0c0 0 4 1 4 1 0 0 4 3 4 3 0 0 3 4 3 4 0 0 1 4 1 4l0 22c0 0-1 4-1 4 0 0-3 4-3 4 0 0-4 3-4 3 0 0-4 1-4 1l-194 0 0 194c0 0-1 4-1 4 0 0-3 4-3 4 0 0-4 3-4 3 0 0-4 1-4 1l-22 0z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-cancel" unicode="&#xe803;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-112-111c-29-30-58-59-87-88 37-38 75-75 112-113-37-36-74-73-110-110 28-29 57-58 86-86 37 37 73 73 110 110 38-37 75-75 113-112 29 29 58 58 88 87-38 38-76 75-113 113 37 37 74 73 110 110-28 29-57 58-86 86-37-36-73-73-110-110-38 37-75 75-113 113z m0-35c38-38 75-75 113-113 37 37 73 74 110 111 17-17 35-35 52-52-37-37-74-73-111-110 38-38 75-75 113-113-18-18-35-35-53-53-38 38-75 75-113 113-36-37-73-74-110-111-17 17-35 35-52 52 37 37 74 74 111 110-38 38-75 76-113 113 18 18 35 35 53 53z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-message" unicode="&#xe804;" d="m295 506l0-312 410 0 0 312-410 0z m91-49l228 0c-38-30-76-60-114-90-38 30-76 60-114 90z m270-28l0-186-312 0 0 186c52-42 104-83 156-125 52 42 104 83 156 125z m-156 373l0 0-5 0-1 0 0 0-5 0 0 0 0 0-6-1 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 0-5-1 0 0-1 0-5 0 0 0 0 0-5 0-1 0 0-1-5 0 0 0 0 0-5-1-1 0 0 0-5 0 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1 0 0-1 0-5-1 0 0 0 0-5-1 0 0 0 0-6-2 0 0 0 0-5-1 0 0 0 0-5-1-4-2-4-2-4-3-2-4-3-4-1-4 0-5 0-4 1-4 2-5 3-3 3-3 4-3 4-1 5-1 4 0 4 1 5 1 5 1 4 1 5 1 5 1 5 1 5 1 5 1 5 0 4 1 5 1 5 0 5 1 5 0 5 1 5 0 5 0 5 1 5 0 5 0 5 0 5 0 5 0 5 0 5-1 5 0 5 0 5-1 5 0 5-1 5 0 5-1 5-1 4 0 5-1 5-1 5-1 5-1 4-1 5 0 4 0 5 1 4 2 3 3 4 3 2 4 2 4 1 4 0 5-1 4-2 5-2 4-3 3-4 3-4 2-3 1-5 1 0 0 0 0-5 1 0 0-1 0-5 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 1 0 0-6 0 0 0 0 0-5 0 0 0-1 0-5 1 0 0 0 0-5 0-1 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 0 0 0z m255-83l-5 0-4-1-5-2-3-2-4-4-2-3-2-4-1-5-1-4 1-5 1-4 3-4 3-4 2-2 2-1 4-3 4-3 4-3 3-3 4-4 4-3 4-3 3-3 4-4 4-3 3-4 4-3 3-4 4-3 3-4 4-4 3-3 3-4 3-4 4-4 3-3 3-4 3-4 3-4 3-4 3-4 2-4 3-4 3-5 3-4 2-4 3-4 2-4 3-5 2-4 2-4 3-5 2-4 1-2 2-4 4-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 4-1 5-1 3-1 3 0 0 0 0-3 5 0 0 0 0-2 5 0 0-1 0-2 4 0 1 0 0-3 4 0 0 0 1-2 4-1 0 0 0-2 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0-1 0-3 4 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-4 4 0 1 0 0-3 4 0 0 0 0-3 4-1 0 0 0-3 4 0 1 0 0-4 4 0 0 0 0-3 4 0 0-1 0-3 4 0 0 0 0-4 4 0 0 0 0-4 4 0 0 0 1-4 3 0 0 0 1-3 3-1 0 0 1-3 3-1 0 0 0-3 4-1 0 0 0-4 4 0 0 0 0-4 4 0 0 0 0-4 3 0 1 0 0-4 3 0 0 0 0-4 4 0 0-1 0-4 3 0 0 0 1-4 3 0 0 0 0-4 3 0 0-1 0-4 4 0 0 0 0-4 3 0 0 0 0-2 1-4 3-4 1-4 1z m-519-10l-5 0-4-1-4-2-4-2-1-1 0 0 0 0-4-3 0-1 0 0-4-3 0 0-1 0-4-4 0 0 0 0-4-3 0 0 0-1-4-3 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0-1 0-3-4 0 0 0 0-4-4 0 0 0-1-3-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0 0-1-4-4 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-4 0 0-1 0-3-5 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-5 0 0 0 0-3-4 0 0 0 0-2-5-1 0 0 0-2-5 0 0 0 0-3-4 0-1 0 0-3-4 0 0 0-1-2-4 0 0 0 0-3-5 0 0 0 0-2-5 0 0-1 0-2-5 0 0 0 0-2-5 0 0 0 0-3-5 0 0 0 0-1-3-1-4-1-5 0-4 1-5 2-4 3-4 3-3 4-2 4-2 4-1 5 0 4 0 5 2 3 2 4 3 3 4 2 3 1 3 2 4 2 5 2 4 2 4 3 5 2 4 2 4 3 5 2 4 3 4 3 4 2 4 3 5 3 4 2 4 3 4 3 4 3 4 3 4 3 4 3 3 4 4 3 4 3 4 3 3 4 4 3 4 4 3 3 4 4 3 3 4 4 3 4 4 3 3 4 3 4 3 4 4 4 3 1 1 3 3 3 3 2 5 1 4 0 4-1 5-1 4-2 4-3 4-4 3-4 2-4 2-4 0z m264 0l0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 0-5 0 0-1 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 0 0 0 0 0-4-1 0 0-1 0-1 0-4-1-5-2-3-2-4-3-2-4-2-4-2-4 0-5 1-4 1-5 2-4 3-3 4-3 4-3 4-1 4-1 4 0 1 1 4 0 4 0 4 1 4 0 3 0 4 0 4 0 4 0 4 0 4 0 4 0 3 0 4 0 4-1 4 0 4 0 3-1 4 0 4-1 4 0 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4-1 3-1 4-1 4-1 3-1 4-1 3-2 4-1 4-1 3-1 4-2 3-1 4-1 3-2 0 0 0 0 4-1 5-1 5 0 4 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4 0 5-2 4-2 4-3 3-4 3-3 2 0 0-1 0 0 0-3 2-1 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0-1 0-3 1-1 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0-1 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-5 0 0 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 1 0 0 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0 1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0z m-155-39l-4 0-5-1-3-1-2-1 0 0 0 0-4-2 0 0 0 0-3-2-1-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-2 0 0 0 0-4-2 0-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0-1-1-3-2 0 0 0 0-3-3 0 0-1 0-3-2 0-1 0 0-3-2 0 0-1 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0-1 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-4 0 0 0 0-3-3 0 0 0 0-2-3-1 0 0-1-2-3 0 0 0 0-3-3 0 0 0-1-3-3 0 0 0 0-2-3 0 0-1-1-2-3 0 0 0 0-2-3-1-1 0 0-2-3 0 0 0 0-2-4-1 0 0 0-2-3-2-4-1-4-1-5 1-4 1-5 2-4 3-3 3-4 4-2 4-2 4-1 5 0 4 1 5 2 4 2 3 3 2 3 2 3 2 3 2 3 3 3 2 4 2 3 2 3 3 3 2 3 3 2 2 3 3 3 2 3 3 3 2 3 3 3 3 2 3 3 2 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 2 3 3 3 2 3 2 3 2 3 2 3 2 4 2 3 2 3 2 3 2 4 2 3 2 2 0 3 3 4 3 2 4 2 4 1 4 1 5-1 4-1 5-3 4-2 3-4 3-4 2-4 2-5 0z m393-59l-5-1-4-1-4-1-4-3-3-3-3-4-1-4-1-5-1-4 1-5 2-4 2-4 2-3 3-2 3-3 2-3 3-3 2-3 3-3 2-3 3-2 2-3 3-3 2-3 2-3 3-4 2-3 2-3 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-4 2-3 1-3 2-4 2-3 1-3 2-4 2-3 1-4 1-3 2-4 1-3 2-4 1-3 1-4 1-4 2-3 1-4 1-3 0-3 2-4 2-4 4-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 4 0 2 0 0 0 0-2 4 0 0 0 1-1 3 0 1 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-1 3 0 0-1 1-1 3 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0-1 0-1 4-1 0 0 0-2 3 0 1 0 0-2 3 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 3 0 0 0 1-2 3 0 0 0 0-3 4 0 0 0 0-2 3 0 0 0 1-3 3 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 3 0 1 0 0-2 3-1 0 0 0-2 3 0 1 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 4 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 1-3 3 0 0 0 0-3 2-3 3-4 3-5 1-4 1z m-564-171l-5 0-4-1-4-2-4-2-3-4-3-3-2-4-1-4-1-4 0 0 0 0 0-4 0 0-1 0 0-4 0-1 0 0-1-4 0 0 0 0-1-4 0 0 0 0 0-5 0 0 0 0-1-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0-1 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0-1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 1-5 0 0 0 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 1-4 0 0 0 0 0-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 0-4 1-1 0 0 0-4 0 0 0 0 1-4 0 0 0 0 1-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0-1 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0 0 2-4 0 0 0 0 1-4 0-1 0 0 1-1 1-4 3-4 3-3 4-3 4-2 4-1 5 0 4 1 5 1 4 2 3 3 3 4 2 4 2 4 0 5 0 4-1 4 0 1-2 4-1 4-1 3-1 4-1 3-1 4 0 4-1 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4 0 4 0 3-1 4 0 4 0 4-1 4 0 4 0 3 0 4 0 4 0 4 0 4 0 4 0 3 1 4 0 4 0 4 1 4 0 3 0 4 1 4 0 4 1 4 1 3 0 4 1 4 0 4 0 5-1 4-2 4-3 4-3 3-4 2-5 2-4 1z m754-46l-5 0-4-1-4-2-4-2-3-4-3-4-2-4 0-4-1-4 1-4 0-5 0-5 0-5 0-5 0-5 0-5-1-5 0-5 0-5-1-5 0-5-1-5 0-5-1-5-1-4 0-5-1-5-1-5-1-5-1-5-1-5-1-4-1-5-1-5-2-5-1-4-2-5-1-5-1-4-2-5-2-5-1-4-2-5-2-4-2-5-2-5-2-4-2-5-2-4-2-4-2-5-2-4-2-5-1-4 0-5 1-4 2-4 2-4 3-4 4-2 4-2 4-2 5 0 4 1 5 1 4 2 3 3 3 3 2 3 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 2 4 0 1 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 1 5 0 0 0 0 2 5 0 0 0 0 1 5 0 0 0 0 2 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 0 2 6 0 0 0 0 1 5 0 0 0 0 1 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 0 5 0 0 0 1 1 5 0 0 0 0 0 5 1 0 0 1 0 5 0 0 0 0 0 5 0 1 0 0 1 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0 1 6 0 0 0 0 0 5 0 0 0 1 0 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0-1 6 0 0 0 0 0 4 0 5-2 4-2 4-3 3-4 3-4 2-4 2-4 0z m-853-16l-5 0-4-1-4-1-4-3-4-3-2-4-2-4-1-4-1-4 0-4 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 0-6 0 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 1-5 0 0 0-1 0-5 0 0 0 0 1-5 0-1 0 0 0-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 1-5 0 0 0-1 1-5 0 0 0 0 1-5 0 0 0 0 2-6 0 0 0 0 1-5 0 0 0 0 1-5 0 0 0-1 2-5 0 0 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0-1 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0-1 2-4 0-1 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 3-5 0 0 0 0 2-5 0 0 0 0 2-5 1 0 0 0 0-1 3-4 3-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 5-1 3-1 1-2 5-2 4-2 4-2 5-2 4-2 5-2 5-2 4-2 5-1 4-2 5-1 5-2 4-1 5-2 5-1 4-1 5-2 5-1 5-1 4-1 5-1 5-1 5-1 5-1 5 0 5-1 4-1 5 0 5-1 5 0 5-1 5 0 5 0 5-1 5 0 5 0 5 0 5 0 4 0 4-1 5-2 4-3 3-4 4-3 2-5 2-4 0z m756-57l-4 0-5-1-4-2-4-3-3-3-2-4-2-4-1-3 0 0 0 0 0 0 0 0-1-4 0-4-1-4-1-3 0-4-1-4-1-4-1-3-1-4-1-3-1-4-1-4-2-3-1-4-1-3-1-4-2-4-1-3-2-4-1-3-1-4-2-3-2-3-1-4-2-3-2-4-1-3-2-3-2-4-2-3-2-3-2-3-2-4-2-3-2-3-2-3-2-3-2-3-3-3-2-3-2-4-2-1-2-4-2-4-1-5 0-4 1-5 2-4 2-4 3-3 4-3 4-2 4-1 5-1 4 1 4 1 5 2 3 3 3 3 1 1 0 1 0 0 3 3 0 0 0 0 2 3 1 1 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 0 2 4 0 0 0 0 2 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 1 2 3 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 1 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 1 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 0 4 0 0 0 0 0 0 1 5-1 4-1 4-2 4-3 4-4 3-4 2-4 2-5 0z m-590-160l-4-1-4-2-4-2-4-3-3-3-2-4-1-5-1-4 1-5 1-4 2-4 2-3 1-2 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-2 1-1 0 0 3-2 0 0 0 0 3-3 1 0 0 0 3-3 0 0 0 0 3-2 1 0 0-1 3-2 0 0 0 0 4-2 0-1 0 0 3-2 0 0 0 0 4-2 0-1 0 0 3-2 1 0 0 0 3-2 0 0 0 0 4-3 0 0 0 0 4-2 0 0 0 0 3-2 1 0 0 0 3-2 0 0 1 0 3-2 0 0 0-1 4-1 0-1 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 4-1 4 0 5 0 4 1 4 2 4 3 3 4 2 3 2 5 1 4 0 5-1 4-2 4-2 4-4 3-3 3-4 2-3 1-4 2-3 1-4 2-3 1-3 2-4 1-3 2-4 2-3 2-3 1-4 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-3 2-3 3-3 2-4 2-3 2-2 3-3 2-3 3-3 2-3 3-3 2-3 3-3 2-2 3-3 3-3 3-3 2-2 3-3 3-2 3-3 3-2 3-1 1-4 3-3 3-5 1-4 1-5 1z m426-77l-5 0-4-1-4-2-1-1-4-2-3-1-3-2-4-2-3-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-1-4-1-3-1-4-2-3-1-4-1-4-1-3-1-4-1-4 0-3-1-4-1-4-1-4 0-3-1-4-1-4 0-4-1-3 0-4 0-4-1-4 0-4 0-4-1-3 0-4 0-4 0-5 0-4-2-4-2-4-3-3-3-2-4-1-4-1-5 0-5 1-4 2-4 2-4 4-3 3-3 4-2 5-1 4 0 4 0 0 0 0 0 4 0 0 0 1 0 4 1 0 0 0 0 4 0 0 0 0 0 5 0 0 0 0 0 4 0 0 0 0 0 4 1 1 0 0 0 4 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 1 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 2 0 0 1 0 3 1 1 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 1 1 3 1 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 1 0 0 0 1 4 1 0 0 0 0 4 2 0 0 0 0 4 2 0 0 0 1 4 1 0 1 0 0 4 2 0 0 0 0 2 1 3 2 4 4 2 3 2 5 1 4 0 5-1 4-1 4-3 4-3 4-3 3-4 2-5 1-4 0z m-440-39l-4-1-5-1-4-3-3-3-3-3-2-4-1-5-1-4 0-5 1-4 2-4 3-4 3-2 1-1 0 0 0 0 4-4 0 0 0 0 4-3 0 0 1 0 4-4 0 0 0 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0-1 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-2 0 0 0-1 5-2 0 0 0 0 4-3 1 0 0 0 4-2 0 0 0-1 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 4-2 1 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 5-1 0 0 0 0 5-2 0 0 0 0 5-1 0 0 0 0 5-2 1 0 0 0 5-1 0 0 0 0 5-1 0 0 0 0 6-2 0 0 0 0 4-1 5 0 4 0 5 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4-1 5-1 4-3 4-3 3-4 3-4 2-3 1-5 1-4 1-5 1-5 1-5 2-4 1-5 2-5 1-4 2-5 1-5 2-4 1-5 2-5 2-4 2-5 2-4 2-5 2-4 2-5 2-4 2-4 2-5 3-4 2-4 2-5 3-4 2-4 3-4 3-4 2-4 3-5 3-4 2-4 3-4 3-4 3-3 3-4 3-4 3-1 1-4 3-4 1-4 1-5 1z m543-3l-5 0-4-1-5-2-3-2-1-2-4-3-4-3-4-3-4-3-4-3-4-2-4-3-5-3-4-2-4-3-4-3-4-2-5-3-4-2-4-2-5-3-4-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-1-5-2-4-1-5-2-5-1-5-2-4-1-5-2-5-1-5-1-4-1-5-1-3-1-5-1-4-2-3-3-3-3-2-4-2-5-1-4 0-5 1-4 2-4 3-4 3-3 4-3 4-2 4-1 5 0 4 0 3 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 2 0 0 1 0 5 1 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 1 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 1 0 0 4 2 1 0 0 0 4 3 0 0 1 0 4 2 0 1 0 0 5 2 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 1 4 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 4 4 1 0 0 0 4 3 0 0 0 0 2 2 3 3 3 4 2 4 1 4 0 5-1 4-1 5-2 4-3 3-4 3-4 2-4 2-4 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-compensation" unicode="&#xe805;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m-16-255c-70-49-140-99-209-148 70-49 139-99 209-148 0 48 0 95 0 143 67-48 135-95 202-143 0 99 0 197 0 296-67-48-135-95-202-143 0 48 0 95 0 143z m-24-47c0-67 0-134 0-201-48 33-95 67-143 100 48 34 95 67 143 101z m202 0c0-67 0-134 0-202-48 34-95 68-143 101 48 34 95 67 143 101z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-parallel-multiple" unicode="&#xe806;" d="m430 545l0-125-125 0 0-140 125 0 0-125 140 0 0 125 125 0 0 140-125 0 0 125z m23-23l94 0 0-125 125 0 0-94-125 0 0-125-94 0 0 126-125 0 0 93 125 0z m51 278l-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 0-6-1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6 0 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0-1 0 0-6-1 0 0-1 0-6-1 0 0 0 0-6-2 0 0 0 0-4-1-4-1-4-2-3-3-3-4-2-4-2-4 0-5 0-4 1-5 2-4 3-4 3-3 4-2 5-2 4-1 5 0 3 1 3 1 6 1 6 1 6 2 5 1 6 1 6 1 6 1 6 0 6 1 5 1 6 0 6 1 6 0 6 1 6 0 6 0 6 0 6 0 6 0 5 0 6 0 6-1 6 0 6-1 6 0 6-1 5 0 6-1 6-1 6-1 6-1 5-1 2 0 4-1 5 0 4 2 4 2 4 2 3 4 3 3 1 5 1 4 0 5-1 4-1 4-3 4-3 4-3 2-5 2-3 1-2 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0 0 0-7 1 0 0 0 0-6 0 0 1-1 0-6 0 0 0 0 0-6 1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6 1 0 0 0 0-6 0-1 0 0 0-6 0 0 0z m246-79l-5-1-4-1-4-3-3-3-3-4-1-4-2-4 0-5 1-4 1-5 2-4 3-3 3-3 2-1 0 0 2-2 0 0 3-1 0 0 2-2 0 0 2-2 2-2 0 0 3-2 0 0 2-1 2-2 0 0 2-2 3-2 0 0 2-2 2-2 0 0 2-2 2-2 1 0 2-2 2-2 2-2 0 0 2-2 0 0 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 2-2 0 0 2-3 2-2 2-2 0-1 1-2 0 0 2-2 0 0 2-3 0 0 1 0 2-4 3-3 2-4 3-3 2-3 3-4 2-3 2-4 0 0 3-3 2-4 2-4 3-3 2-4 2-3 2-4 2-4 2-3 2-4 2-4 1-2 3-4 3-4 3-2 4-2 5-2 4 0 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 5-1 4-1 3-2 3 0 0 0 0-2 4 0 0 0 1-2 4 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0-1 0-2 4 0 0 0 0-3 4 0 0 0 0-3 4 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 4 0 0 0 0-3 3-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2-1 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 2 0 0-1 0-2 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2-1 0 0 1-2 1 0 1 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-2 1-4 2-4 2-5 0z m-521-12l-5-1-4-2-3-2 0 0 0 0-1 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0-1-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0-1 0 0-2-2 0 0 0 0-2-2 0 0-1 0-2-2 0 0 0-1-2-2 0 0 0 0-3-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2-1 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0-1 0-1-3 0 0 0 0-2-2-1-2 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0-1-2-2 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0 0-1-2-4 0-5 0-4 1-5 2-4 2-4 4-3 3-3 5-1 4-1 5-1 4 1 4 2 4 2 4 3 3 3 1 4 1 0 1 3 1 3 0 0 1 2 0 0 2 3 1 3 0 0 2 2 0 0 1 3 1 2 0 1 2 2 1 3 0 0 2 2 0 0 1 3 2 2 0 0 1 3 2 2 1 3 0 0 2 3 0 0 2 2 0 0 1 2 2 3 2 2 0 0 1 3 2 2 2 3 1 1 0 0 2 3 1 2 0 0 2 3 2 2 0 0 1 3 2 2 0 0 2 3 0 0 2 2 1 3 2 2 0 0 2 2 2 3 2 2 0 0 2 2 1 3 2 2 0 0 2 2 2 2 0 0 2 3 0 0 2 2 0 0 2 2 0 0 2 2 2 2 0 0 2 2 0 0 2 3 0 0 2 2 2 2 0 0 2 2 3 2 0 0 2 2 2 2 0 0 2 2 0 0 2 2 0 0 2 2 0 0 3 1 0 0 2 2 0 0 2 2 0 0 2 2 3 2 0 0 2 2 0 0 0 0 3 3 3 4 2 4 1 4 0 5 0 4-2 5-2 4-3 3-3 3-4 2-4 2-5 1z m694-313l-4-1-5-2-3-2-3-4-3-4-2-4-1-4 0-4 1-4 0-4 0-4 0-5 0-4 0 0 0-1 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0-3 0-3 0-3-1-3 0-3 0 0 0-3 0 0 0-3-1-3 0-3 0-3-1-2 0-1 0-3 0 0 0-2-1-3 0-3 0 0-1-3 0-3-1-3 0 0 0-3-1-3-1-3 0 0 0-2-1-3 0 0 0-3-1-3 0 0-1-3-1-3 0 0 0-2 0 0-1-3 0 0-1-3 0 0-1-3 0 0-1-3-1-2 0 0 0-3-1-3 0 0-1-3 0 0-1-2 0-1-1-2 0 0-1-3 0 0-1-3-1-2 0 0-1-3-3-5-2-6-2-5-3-5-2-6-3-5-3-5-1-3-2-4-1-4 0-5 1-4 1-5 3-4 3-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 3 1 3 1 0 0 0 3 6 0 0 0 0 2 6 1 0 0 0 2 6 0 0 0 0 3 5 0 1 0 0 3 5 0 1 0 0 2 6 0 0 1 0 2 6 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 1 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 1 0 0 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 4 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 3 0 1 0 0 0 3 0 4 0 0 0 0 0 4 0 0 0 1 0 4 0 0 0 0-1 5 0 0 0 0 0 4 0 5-2 4-2 4-3 4-4 2-4 3-4 1-4 1z m-853-18l-4-1-5-2-3-3-4-3-2-4-2-4-1-4 0-4 0-3 0 0 0 0 0-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 1 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0 0 2-6 0-1 0 0 1-6 0 0 0 0 2-6 0 0 0-1 2-6 0 0 0 0 1-6 0 0 0 0 2-6 0 0 0 0 2-6 0-1 0 0 2-6 0 0 0 0 2-6 0 0 0 0 2-6 1 0 0 0 2-6 0 0 0 0 2-6 0 0 0-1 3-5 0-1 0 0 2-5 0-1 0 0 3-5 0-1 0 0 2-5 0-1 1 0 2-5 0-1 0 0 3-5 0 0 0-1 1-1 2-4 4-4 3-2 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 5 0 4 0 5-1 4-1 4-1 1-3 5-2 6-3 5-2 6-2 5-2 5-3 6-2 6-2 5-1 6-2 5-2 6-2 6-1 5-2 6-1 6-2 5-1 6-1 6-1 6-1 6-1 5-1 6-1 6-1 6 0 6-1 5 0 6-1 6 0 6 0 6-1 6 0 3 0 4-1 5-3 4-2 3-4 3-4 3-4 1-4 1z m694-334l-4-1-4-2-4-3 0 0-5-3-4-4-5-4-5-3-5-3-4-4-5-3-5-3-5-3-5-4-5-3-6-3-5-2-5-3-5-3-5-3-6-2-5-3-5-2-6-2-5-3-6-2-5-2-6-2-5-2-6-2-5-2-6-1-5-2-6-2-6-1-5-1-5-1-4-2-4-2-4-3-2-3-3-4-1-5-1-4 1-5 1-4 2-4 2-4 3-3 4-3 4-1 5-1 4-1 4 1 5 1 0 0 0 0 6 2 0 0 0 0 6 1 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 1 0 5 2 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 3 0 0 0 0 6 2 0 0 1 0 5 3 0 0 1 0 5 2 0 0 1 0 5 3 0 0 1 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 1 0 0 5 3 0 0 1 0 5 3 0 0 0 1 5 3 0 0 1 0 5 4 0 0 0 0 5 3 0 0 0 0 6 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 1 0 4 4 1 0 0 0 0 1 3 3 3 4 2 4 1 4 0 5 0 4-2 4-2 4-3 4-4 3-4 2-4 1-4 1z m-541-2l-4-1-4-3-4-2-3-4-2-4-1-4-1-5 0-4 1-5 2-4 3-4 3-2 1-1 0-1 0 0 5-4 0 0 0 0 5-4 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 3-1 0-1 0 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 2-2 0 0 1 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0-1 3-1 0 0 0 0 3-2 0 0 0 0 2-1 1 0 0 0 2-2 1 0 0 0 2-2 0 0 1 0 2-1 0 0 1 0 2-2 0 0 0 0 3-1 0 0 0 0 3-2 0 0 1 0 2-1 0 0 1 0 2-1 0-1 1 0 2-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 2 0 0 0 0 0 3-1 0 0 0-1 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 4 0 0-1 0 0 3 0 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 0 0 5 0 4 0 5 1 4 2 4 2 3 4 2 3 2 5 1 4 0 5 0 4-2 4-2 4-3 4-4 2-4 3-3 1 0 0-1 0-3 0-2 1 0 0-3 1 0 0-3 1 0 0-3 0 0 0-3 1-3 1-3 1 0 0-3 1-2 1-3 1-3 1-1 0-1 0-3 1-3 1-3 1 0 0-2 1-3 1-3 1-3 0-3 1 0 0-3 1-3 1-2 1 0 0-3 2-3 1 0 0-3 1 0 0-2 1-3 1 0 0-3 1-3 1-2 2-3 1 0 0-3 1-2 1-3 2-3 1-2 1 0 0-3 2-2 1 0 0-3 1 0 0-3 2 0 0-2 1-2 2-1 0-2 1 0 0-3 2-2 1 0 0-3 2-2 1 0 0-3 2 0 0-2 2 0 0-2 1-3 2 0 0-2 2-2 1-1 0-2 2 0 0-2 2-3 1 0 0-2 2 0 0-2 2 0 0-3 2-4 3-5 4-1 1-4 3-4 1-4 2-5 0z" horiz-adv-x="1000" />
+<glyph glyph-name="loop-marker" unicode="&#xe807;" d="m500 672c-175 0-317-141-317-314 0-87 36-165 93-222 27-27 60-49 96-65l-184-32-5-1 2-10 5 1 190 33 5 1 0 3 0-1-37 200 0 5-10-2 1-4 33-182c-33 15-63 36-89 61-56 55-90 131-90 215 0 168 137 304 307 304 170 0 307-136 307-304 0-168-137-304-307-304l-5 0 0-10 5 0c175 0 317 141 317 314 0 173-142 314-317 314z" horiz-adv-x="1000" />
+<glyph glyph-name="user-task" unicode="&#xe808;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m139-101l-3 0c-53 0-87-38-87-86 0-25 18-47 35-63-9-3-33-12-57-25-14-8-28-17-38-28-11-10-18-22-19-36l0 0 0-127 61 0c1 0 1 0 2 0l285 0 0 127c0 12-8 23-19 33-11 11-25 20-40 28-26 15-51 25-61 29 17 16 30 37 30 62 0 48-36 86-89 86z m-24-51c8 0 17-1 25-6 36-19 75-27 82-21 1-3 1-5 1-8 0-24-14-46-31-61l-4-3 4-2c4-1 22-7 42-17-1-43-42-79-94-79-52 0-94 34-95 78 22 10 41 17 45 18l4 1-3 3c-18 16-37 38-37 62 0 3 0 6 0 8 6 6 32 27 61 27z m124-121c6-2 12-6 18-9 14-8 28-17 39-27 10-10 17-20 17-30l0-122-57 0 0 90-5 0 0-90-216 0 0 90c0 3-6 3-5 0l0-90-55 0 0 122c1 12 7 23 17 33 10 10 24 19 37 26 4 2 7 4 11 6 2-45 46-80 100-80 53 0 97 36 99 81z" horiz-adv-x="1000" />
+<glyph glyph-name="business-rule" unicode="&#xe809;" d="m104 644l0-294 0-32 0-5 0-256 194 0 5 0 593 0 0 293 0 294-792 0z m5-194l189 0 0-132-189 0 0 32 0 100z m194 0l588 0 0-100 0-32-588 0 0 132z m-194-137l189 0 0-251-189 0 0 251z m194 0l588 0 0-251-588 0 0 251z" horiz-adv-x="1000" />
+<glyph glyph-name="parallel-mi-marker" unicode="&#xe80a;" d="m178 700l0-700 130 0 0 700-130 0z m257 0l0-700 130 0 0 700-130 0z m257 0l0-700 130 0 0 700-130 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-signal" unicode="&#xe80b;" d="m500 562c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z m0-51c50-90 100-180 151-270-101 0-201 0-302 0 51 90 101 180 151 270z m4 289c-45-7-119 8-139-39 18-48 78-2 116-10 40 3 80-6 119-8 49 46-38 58-72 56-8 1-16 1-24 1z m250-79c-62-19 12-63 34-87 30-33 55-70 76-109 42-29 52 35 23 57-33 54-74 105-127 138l-6 1 0 0z m-521-11c-51-21-82-73-113-115-22-23-63-104 0-91 32 41 53 93 92 130 19 20 77 57 21 76z m695-313c-47-13-14-76-28-111-7-43-22-86-43-125-6-47 57-33 57 6 31 66 44 141 36 213-3 10-13 16-22 17z m-853-19c-48-11-18-76-18-110 11-46 23-94 51-133 67-9 16 67 8 99-12 40-19 82-19 124-2 11-12 19-22 20z m694-334c-50-24-94-64-149-78-33 0-87-36-38-60 75 13 146 49 204 98 14 14 2 40-17 40z m-542-1c-56-22 12-68 41-83 45-25 95-46 147-53 50 23-6 59-38 59-50 15-97 39-136 73l-6 3-8 1 0 0z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-timer" unicode="&#xe80c;" d="m500 564c-85 2-167-54-198-133-33-76-15-170 43-229 56-60 149-82 226-54 81 28 141 108 143 194 5 83-46 166-121 201-29 14-61 21-93 21z m0-39c78 2 152-55 170-131 20-73-14-156-79-194-67-42-160-31-215 26-58 56-68 152-24 219 32 49 89 81 148 80z m55-49c-19-36-39-71-58-107-18-2-23-29-6-36 11-8 20 5 30 4 30 0 59 0 89 0 0 8 0 17 0 25-30 0-60 0-89 0 18 34 37 68 56 102-7 4-14 8-22 12z m-55 233l-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 0-5 0 0-1 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 0 0 0 0 0-4-1 0 0-1 0-1 0-4-1-5-2-3-2-4-3-2-4-2-4-2-4 0-5 1-4 1-5 2-4 3-3 4-3 4-3 4-1 4-1 4 0 1 1 4 0 4 0 4 1 4 0 3 0 4 0 4 0 4 0 4 0 4 0 4 0 3 0 4 0 4-1 4 0 4 0 3-1 4 0 4-1 4 0 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4-1 3-1 4-1 4-1 3-1 4-1 3-2 4-1 4-1 3-1 4-2 3-1 4-1 3-2 0 0 0 0 4-1 5-1 5 0 4 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4 0 5-2 4-2 4-3 3-4 3-3 2 0 0-1 0 0 0-3 2-1 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0-1 0-3 1-1 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0-1 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-5 0 0 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 1 0 0 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0 1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0z m-159-39l-5-1-3-1-2-1 0 0 0 0-4-2 0 0 0 0-3-2-1-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-2 0 0 0 0-4-2 0-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0-1-1-3-2 0 0 0 0-3-3 0 0-1 0-3-2 0-1 0 0-3-2 0 0-1 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0-1 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-4 0 0 0 0-3-3 0 0 0 0-2-3-1 0 0-1-2-3 0 0 0 0-3-3 0 0 0-1-3-3 0 0 0 0-2-3 0 0-1-1-2-3 0 0 0 0-2-3-1-1 0 0-2-3 0 0 0 0-2-4-1 0 0 0-2-3-2-4-1-4-1-5 1-4 1-5 2-4 3-3 3-4 4-2 4-2 4-1 5 0 4 1 5 2 4 2 3 3 2 3 2 3 2 3 2 3 3 3 2 4 2 3 2 3 3 3 2 3 3 2 2 3 3 3 2 3 3 3 2 3 3 3 3 2 3 3 2 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 2 3 3 3 2 3 2 3 2 3 2 3 2 4 2 3 2 3 2 3 2 4 2 3 2 2 0 3 3 4 3 2 4 2 4 1 4 1 5-1 4-1 5-3 4-2 3-4 3-4 2-4 2-5 0z m392-60l-4-1-4-1-4-3-3-3-3-4-1-4-1-5-1-4 1-5 2-4 2-4 2-3 3-2 3-3 2-3 3-3 2-3 3-3 2-3 3-2 2-3 3-3 2-3 2-3 3-4 2-3 2-3 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-4 2-3 1-3 2-4 2-3 1-3 2-4 2-3 1-4 1-3 2-4 1-3 2-4 1-3 1-4 1-4 2-3 1-4 1-3 0-3 2-4 2-4 4-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 4 0 2 0 0 0 0-2 4 0 0 0 1-1 3 0 1 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-1 3 0 0-1 1-1 3 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0-1 0-1 4-1 0 0 0-2 3 0 1 0 0-2 3 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 3 0 0 0 1-2 3 0 0 0 0-3 4 0 0 0 0-2 3 0 0 0 1-3 3 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 3 0 1 0 0-2 3-1 0 0 0-2 3 0 1 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 4 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 1-3 3 0 0 0 0-3 2-3 3-4 3-5 1-4 1z m-564-170l-4-1-4-2-4-2-3-4-3-3-2-4-1-4-1-4 0 0 0 0 0-4 0 0-1 0 0-4 0-1 0 0-1-4 0 0 0 0-1-4 0 0 0 0 0-5 0 0 0 0-1-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0-1 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0-1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 1-5 0 0 0 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 1-4 0 0 0 0 0-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 0-4 1-1 0 0 0-4 0 0 0 0 1-4 0 0 0 0 1-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0-1 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0 0 2-4 0 0 0 0 1-4 0-1 0 0 1-1 1-4 3-4 3-3 4-3 4-2 4-1 5 0 4 1 5 1 4 2 3 3 3 4 2 4 2 4 0 5 0 4-1 4 0 1-2 4-1 4-1 3-1 4-1 3-1 4 0 4-1 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4 0 4 0 3-1 4 0 4 0 4-1 4 0 4 0 3 0 4 0 4 0 4 0 4 0 4 0 3 1 4 0 4 0 4 1 4 0 3 0 4 1 4 0 4 1 4 1 3 0 4 1 4 0 4 0 5-1 4-2 4-3 4-3 3-4 2-5 2-4 1z m658-119l-5-1-4-2-4-3-3-3-2-4-2-4-1-3 0 0 0 0 0 0 0 0-1-4 0-4-1-4-1-3 0-4-1-4-1-4-1-3-1-4-1-3-1-4-1-4-2-3-1-4-1-3-1-4-2-4-1-3-2-4-1-3-1-4-2-3-2-3-1-4-2-3-2-4-1-3-2-3-2-4-2-3-2-3-2-3-2-4-2-3-2-3-2-3-2-3-2-3-3-3-2-3-2-4-2-1-2-4-2-4-1-5 0-4 1-5 2-4 2-4 3-3 4-3 4-2 4-1 5-1 4 1 4 1 5 2 3 3 3 3 1 1 0 1 0 0 3 3 0 0 0 0 2 3 1 1 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 0 2 4 0 0 0 0 2 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 1 2 3 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 1 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 1 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 0 4 0 0 0 0 0 0 1 5-1 4-1 4-2 4-3 4-4 3-4 2-4 2-5 0z m-590-161l-4-2-4-2-4-3-3-3-2-4-1-5-1-4 1-5 1-4 2-4 2-3 1-2 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-2 1-1 0 0 3-2 0 0 0 0 3-3 1 0 0 0 3-3 0 0 0 0 3-2 1 0 0-1 3-2 0 0 0 0 4-2 0-1 0 0 3-2 0 0 0 0 4-2 0-1 0 0 3-2 1 0 0 0 3-2 0 0 0 0 4-3 0 0 0 0 4-2 0 0 0 0 3-2 1 0 0 0 3-2 0 0 1 0 3-2 0 0 0-1 4-1 0-1 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 4-1 4 0 5 0 4 1 4 2 4 3 3 4 2 3 2 5 1 4 0 5-1 4-2 4-2 4-4 3-3 3-4 2-3 1-4 2-3 1-4 2-3 1-3 2-4 1-3 2-4 2-3 2-3 1-4 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-3 2-3 3-3 2-4 2-3 2-2 3-3 2-3 3-3 2-3 3-3 2-3 3-3 2-2 3-3 3-3 3-3 2-2 3-3 3-2 3-3 3-2 3-1 1-4 3-3 3-5 1-4 1-5 1z m425-76l-4-1-4-2-1-1-4-2-3-1-3-2-4-2-3-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-1-4-1-3-1-4-2-3-1-4-1-4-1-3-1-4-1-4 0-3-1-4-1-4-1-4 0-3-1-4-1-4 0-4-1-3 0-4 0-4-1-4 0-4 0-4-1-3 0-4 0-4 0-5 0-4-2-4-2-4-3-3-3-2-4-1-4-1-5 0-5 1-4 2-4 2-4 4-3 3-3 4-2 5-1 4 0 4 0 0 0 0 0 4 0 0 0 1 0 4 0 0 1 0 0 4 0 0 0 0 0 5 0 0 0 0 0 4 0 0 0 0 0 4 1 1 0 0 0 4 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 1 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 2 0 0 1 0 3 1 1 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 1 1 3 1 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 1 0 0 0 1 4 1 0 0 0 0 4 2 0 0 0 0 4 2 0 0 0 1 4 1 0 1 0 0 4 2 0 0 0 0 2 1 3 2 4 4 2 3 2 5 1 4 0 5-1 4-1 4-3 4-3 4-3 3-4 2-5 1-4 0z m-162 718l-5 0-1 0 0 0-5 0 0 0 0 0-6-1 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 0-5-1 0 0-1 0-5 0 0 0 0 0-5 0-1 0 0-1-5 0 0 0 0 0-5-1-1 0 0 0-5 0 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1 0 0-1 0-5-1 0 0 0 0-5-1 0 0 0 0-6-2 0 0 0 0-5-1 0 0 0 0-5-1-4-2-4-2-4-3-2-4-3-4-1-4 0-5 0-4 1-4 2-5 3-3 3-3 4-3 4-1 5-1 4 0 4 1 5 1 5 1 4 1 5 1 5 1 5 1 5 1 5 1 5 0 4 1 5 1 5 0 5 1 5 0 5 1 5 0 5 0 5 1 5 0 5 0 5 0 5 0 5 0 5 0 5-1 5 0 5 0 5-1 5 0 5-1 5 0 5-1 5-1 4 0 5-1 5-1 5-1 5-1 4-1 5 0 4 0 5 1 4 2 3 3 4 3 2 4 2 4 1 4 0 5-1 4-2 5-2 4-3 3-4 3-4 2-3 1-5 1 0 0 0 0-5 1 0 0-1 0-5 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 1 0 0-6 0 0 0 0 0-5 0 0 0-1 0-5 1 0 0 0 0-5 0-1 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 0 0 0z m250-83l-4-1-5-2-3-2-4-4-2-3-2-4-1-5-1-4 1-5 1-4 3-4 3-4 2-2 2-1 4-3 4-3 4-3 3-3 4-4 4-3 4-3 3-3 4-4 4-3 3-4 4-3 3-4 4-3 3-4 4-4 3-3 3-4 3-4 4-4 3-3 3-4 3-4 3-4 3-4 3-4 2-4 3-4 3-5 3-4 2-4 3-4 2-4 3-5 2-4 2-4 3-5 2-4 1-2 2-4 4-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 4-1 5-1 3-1 3 0 0 0 0-3 5 0 0 0 0-2 5 0 0-1 0-2 4 0 1 0 0-3 4 0 0 0 1-2 4-1 0 0 0-2 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0-1 0-3 4 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-4 4 0 1 0 0-3 4 0 0 0 0-3 4-1 0 0 0-3 4 0 1 0 0-4 4 0 0 0 0-3 4 0 0-1 0-3 4 0 0 0 0-4 4 0 0 0 0-4 4 0 0 0 1-4 3 0 0 0 1-3 3-1 0 0 1-3 3-1 0 0 0-3 4-1 0 0 0-4 4 0 0 0 0-4 4 0 0 0 0-4 3 0 1 0 0-4 3 0 0 0 0-4 4 0 0-1 0-4 3 0 0 0 1-4 3 0 0 0 0-4 3 0 0-1 0-4 4 0 0 0 0-4 3 0 0 0 0-2 1-4 3-4 1-4 1z m-519-10l-4-1-4-2-4-2-1-1 0 0 0 0-4-3 0-1 0 0-4-3 0 0-1 0-4-4 0 0 0 0-4-3 0 0 0-1-4-3 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0-1 0-3-4 0 0 0 0-4-4 0 0 0-1-3-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0 0-1-4-4 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-4 0 0-1 0-3-5 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-5 0 0 0 0-3-4 0 0 0 0-2-5-1 0 0 0-2-5 0 0 0 0-3-4 0-1 0 0-3-4 0 0 0-1-2-4 0 0 0 0-3-5 0 0 0 0-2-5 0 0-1 0-2-5 0 0 0 0-2-5 0 0 0 0-3-5 0 0 0 0-1-3-1-4-1-5 0-4 1-5 2-4 3-4 3-3 4-2 4-2 4-1 5 0 4 0 5 2 3 2 4 3 3 4 2 3 1 3 2 4 2 5 2 4 2 4 3 5 2 4 2 4 3 5 2 4 3 4 3 4 2 4 3 5 3 4 2 4 3 4 3 4 3 4 3 4 3 4 3 3 4 4 3 4 3 4 3 3 4 4 3 4 4 3 3 4 4 3 3 4 4 3 4 4 3 3 4 3 4 3 4 4 4 3 1 1 3 3 3 3 2 5 1 4 0 4-1 5-1 4-2 4-3 4-4 3-4 2-4 2-4 0z m692-315l-4-1-4-2-4-2-3-4-3-4-2-4 0-4-1-4 1-4 0-5 0-5 0-5 0-5 0-5 0-5-1-5 0-5 0-5-1-5 0-5-1-5 0-5-1-5-1-4 0-5-1-5-1-5-1-5-1-5-1-5-1-4-1-5-1-5-2-5-1-4-2-5-1-5-1-4-2-5-2-5-1-4-2-5-2-4-2-5-2-5-2-4-2-5-2-4-2-4-2-5-2-4-2-5-1-4 0-5 1-4 2-4 2-4 3-4 4-2 4-2 4-2 5 0 4 1 5 1 4 2 3 3 3 3 2 3 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 2 4 0 1 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 1 5 0 0 0 0 2 5 0 0 0 0 1 5 0 0 0 0 2 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 0 2 6 0 0 0 0 1 5 0 0 0 0 1 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 0 5 0 0 0 1 1 5 0 0 0 0 0 5 1 0 0 1 0 5 0 0 0 0 0 5 0 1 0 0 1 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0 1 6 0 0 0 0 0 5 0 0 0 1 0 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0-1 6 0 0 0 0 0 4 0 5-2 4-2 4-3 3-4 3-4 2-4 2-4 0z m-853-16l-4-1-4-1-4-3-4-3-2-4-2-4-1-4-1-4 0-4 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 0-6 0 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 1-5 0 0 0-1 0-5 0 0 0 0 1-5 0-1 0 0 0-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 1-5 0 0 0-1 1-5 0 0 0 0 1-5 0 0 0 0 2-6 0 0 0 0 1-5 0 0 0 0 1-5 0 0 0-1 2-5 0 0 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0-1 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0-1 2-4 0-1 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 3-5 0 0 0 0 2-5 0 0 0 0 2-5 1 0 0 0 0-1 3-4 3-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 5-1 3-1 1-2 5-2 4-2 4-2 5-2 4-2 5-2 5-2 4-2 5-1 4-2 5-1 5-2 4-1 5-2 5-1 4-1 5-2 5-1 5-1 4-1 5-1 5-1 5-1 5-1 5 0 5-1 4-1 5 0 5-1 5 0 5-1 5 0 5 0 5-1 5 0 5 0 5 0 5 0 4 0 4-1 5-2 4-3 3-4 4-3 2-5 2-4 0z m153-334l-5-1-4-3-3-3-3-3-2-4-1-5-1-4 0-5 1-4 2-4 3-4 3-2 1-1 0 0 0 0 4-4 0 0 0 0 4-3 0 0 1 0 4-4 0 0 0 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0-1 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-2 0 0 0-1 5-2 0 0 0 0 4-3 1 0 0 0 4-2 0 0 0-1 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 4-2 1 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 5-1 0 0 0 0 5-2 0 0 0 0 5-1 0 0 0 0 5-2 1 0 0 0 5-1 0 0 0 0 5-1 0 0 0 0 6-2 0 0 0 0 4-1 5 0 4 0 5 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4-1 5-1 4-3 4-3 3-4 3-4 2-3 1-5 1-4 1-5 1-5 1-5 2-4 1-5 2-5 1-4 2-5 1-5 2-4 1-5 2-5 2-4 2-5 2-4 2-5 2-4 2-5 2-4 2-4 2-5 3-4 2-4 2-5 3-4 2-4 3-4 3-4 2-4 3-5 3-4 2-4 3-4 3-4 3-3 3-4 3-4 3-1 1-4 3-4 1-4 1-5 1z m542-2l-4-1-5-2-3-2-1-2-4-3-4-3-4-3-4-3-4-3-4-2-4-3-5-3-4-2-4-3-4-3-4-2-5-3-4-2-4-2-5-3-4-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-1-5-2-4-1-5-2-5-1-5-2-4-1-5-2-5-1-5-1-4-1-5-1-3-1-5-1-4-2-3-3-3-3-2-4-2-5-1-4 0-5 1-4 2-4 3-4 3-3 4-3 4-2 4-1 5 0 4 0 3 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 2 0 0 1 0 5 1 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 1 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 1 0 0 4 2 1 0 0 0 4 3 0 0 1 0 4 2 0 1 0 0 5 2 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 1 4 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 4 4 1 0 0 0 4 3 0 0 0 0 2 2 3 3 3 4 2 4 1 4 0 5-1 4-1 5-2 4-3 3-4 3-4 2-4 2-4 0z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-parallel-multiple" unicode="&#xe80d;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-61-93c0-52 0-104 0-156-53 0-106 0-159 0 0-41 0-83 0-124 53 0 106 0 159 0 0-52 0-104 0-156 41 0 81 0 122 0 0 52 0 104 0 156 53 0 106 0 159 0 0 41 0 83 0 124-53 0-106 0-159 0 0 52 0 104 0 156-41 0-81 0-122 0z m25-24c24 0 48 0 73 0 0-52 0-104 0-157 53 0 106 0 159 0 0-24 0-49 0-74-53 0-106 0-159 0 0-53 0-105 0-157-25 0-49 0-73 0 0 52 0 104 0 157-54 0-107 0-160 0 0 25 0 50 0 74 53 0 106 0 160 0 0 53 0 105 0 157z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-compensation" unicode="&#xe80e;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-16-163c-70-49-140-99-209-148 70-49 139-99 209-148 0 48 0 95 0 143 67-48 135-95 202-143 0 99 0 197 0 296-67-48-135-95-202-143 0 48 0 95 0 143z m-24-47c0-67 0-134 0-201-48 33-95 67-143 100 48 34 95 67 143 101z m202 0c0-67 0-134 0-202-48 34-95 68-143 101 48 34 95 67 143 101z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-xor" unicode="&#xe80f;" d="m500 802c-9 0-19-4-26-11l-415-415c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-7 7-17 11-26 11z m0-62l390-390-390-390-390 390 390 390z m-146-217c0 0-4-1-4-1 0 0-4-3-4-3l-15-15c0 0-3-4-3-4 0 0-1-4-1-4 0 0 1-5 1-5 0 0 3-4 3-4l137-137-137-137 0 0c0 0-3-4-3-4 0 0-1-5-1-5 0 0 1-4 1-4 0 0 3-4 3-4l15-15c0 0 4-3 4-3 0 0 4-1 4-1 0 0 5 1 5 1 0 0 4 3 4 3l137 137 137-137c0 0 4-3 4-3 0 0 5-1 5-1 0 0 4 1 4 1 0 0 4 3 4 3l15 15c0 0 3 4 3 4 0 0 1 4 1 4 0 0-1 5-1 5 0 0-3 4-3 4l-137 137 137 137c0 0 3 4 3 4 0 0 1 5 1 5 0 0-1 4-1 4 0 0-3 4-3 4l-15 15c0 0-4 3-4 3 0 0-4 1-4 1 0 0-5-1-5-1 0 0-4-3-4-3l-137-137-137 137 0 1c0 0-4 2-4 2 0 0-5 1-5 1l0 0z" horiz-adv-x="1000" />
+<glyph glyph-name="connection" unicode="&#xe810;" d="m911 749c0 0-285-146-431-214 31-28 60-59 90-89-147-149-295-299-443-448 11-11 22-21 33-31 148 149 295 299 443 448 30-29 60-60 90-90 77 153 218 424 218 424z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-cancel" unicode="&#xe811;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m-112-110c-29-30-58-59-87-88 37-38 75-75 112-113-37-36-74-73-110-110 28-29 57-58 86-86 37 37 73 73 110 110 38-37 75-75 113-112 29 29 58 58 88 87-38 38-76 75-113 113 37 37 74 73 110 110-28 29-57 58-86 86-37-36-73-73-110-110-38 37-75 75-113 113z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-condition" unicode="&#xe812;" d="m499 802c-1 0-2 0-3 0-202 1-391-150-436-346-42-173 28-368 174-471 145-107 354-116 506-18 149 93 235 276 207 450-26 176-164 330-338 371-36 9-73 14-110 14z m-5-49c3 0 7 0 10 0 187 2 362-146 392-331 32-167-54-348-205-427-154-85-363-54-483 77-124 127-147 338-53 488 71 116 203 192 339 193z m8-44c-3 0-7 0-10 0-172 0-330-143-349-314-22-161 79-328 233-382 145-55 322-3 413 124 98 129 92 326-17 447-67 77-167 125-270 125z m-2-48c2 0 4 0 6 0 153 0 292-129 304-281 16-145-84-293-225-330-137-40-296 27-361 154-69 129-33 305 86 392 54 42 122 65 190 65z m-151-121l0-12 0-368 50 0 202 0 50 0 0 380-302 0z m24-24l254 0 0-332-26 0-202 0-26 0 0 332z m26-37l0-25 202 0 0 25-202 0z m0-74l0-24 202 0 0 24-202 0z m0-85l0-24 202 0 0 24-202 0z m0-77l0-24 202 0 0 24-202 0z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-parallel-multiple" unicode="&#xe813;" d="m430 545l0-125-125 0 0-140 125 0 0-125 140 0 0 125 125 0 0 140-125 0 0 125z m23-23l94 0 0-125 125 0 0-94-125 0 0-125-94 0 0 126-125 0 0 93 125 0z m47 280l0 0-5 0-1 0 0 0-5 0 0 0 0 0-6-1 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 0-5-1 0 0-1 0-5 0 0 0 0 0-5 0-1 0 0-1-5 0 0 0 0 0-5-1-1 0 0 0-5 0 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1 0 0-1 0-5-1 0 0 0 0-5-1 0 0 0 0-6-2 0 0 0 0-5-1 0 0 0 0-5-1-4-2-4-2-4-3-2-4-3-4-1-4 0-5 0-4 1-4 2-5 3-3 3-3 4-3 4-1 5-1 4 0 4 1 5 1 5 1 4 1 5 1 5 1 5 1 5 1 5 1 5 0 4 1 5 1 5 0 5 1 5 0 5 1 5 0 5 0 5 1 5 0 5 0 5 0 5 0 5 0 5 0 5-1 5 0 5 0 5-1 5 0 5-1 5 0 5-1 5-1 4 0 5-1 5-1 5-1 5-1 4-1 5 0 4 0 5 1 4 2 3 3 4 3 2 4 2 4 1 4 0 5-1 4-2 5-2 4-3 3-4 3-4 2-3 1-5 1 0 0 0 0-5 1 0 0-1 0-5 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 1 0 0-6 0 0 0 0 0-5 0 0 0-1 0-5 1 0 0 0 0-5 0-1 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 0 0 0z m255-83l-5 0-4-1-5-2-3-2-4-4-2-3-2-4-1-5-1-4 1-5 1-4 3-4 3-4 2-2 2-1 4-3 4-3 4-3 3-3 4-4 4-3 4-3 3-3 4-4 4-3 3-4 4-3 3-4 4-3 3-4 4-4 3-3 3-4 3-4 4-4 3-3 3-4 3-4 3-4 3-4 3-4 2-4 3-4 3-5 3-4 2-4 3-4 2-4 3-5 2-4 2-4 3-5 2-4 1-2 2-4 4-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 4-1 5-1 3-1 3 0 0 0 0-3 5 0 0 0 0-2 5 0 0-1 0-2 4 0 1 0 0-3 4 0 0 0 1-2 4-1 0 0 0-2 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0-1 0-3 4 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-4 4 0 1 0 0-3 4 0 0 0 0-3 4-1 0 0 0-3 4 0 1 0 0-4 4 0 0 0 0-3 4 0 0-1 0-3 4 0 0 0 0-4 4 0 0 0 0-4 4 0 0 0 1-4 3 0 0 0 1-3 3-1 0 0 1-3 3-1 0 0 0-3 4-1 0 0 0-4 4 0 0 0 0-4 4 0 0 0 0-4 3 0 1 0 0-4 3 0 0 0 0-4 4 0 0-1 0-4 3 0 0 0 1-4 3 0 0 0 0-4 3 0 0-1 0-4 4 0 0 0 0-4 3 0 0 0 0-2 1-4 3-4 1-4 1z m-519-10l-5 0-4-1-4-2-4-2-1-1 0 0 0 0-4-3 0-1 0 0-4-3 0 0-1 0-4-4 0 0 0 0-4-3 0 0 0-1-4-3 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0-1 0-3-4 0 0 0 0-4-4 0 0 0-1-3-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0 0-1-4-4 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-4 0 0-1 0-3-5 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-5 0 0 0 0-3-4 0 0 0 0-2-5-1 0 0 0-2-5 0 0 0 0-3-4 0-1 0 0-3-4 0 0 0-1-2-4 0 0 0 0-3-5 0 0 0 0-2-5 0 0-1 0-2-5 0 0 0 0-2-5 0 0 0 0-3-5 0 0 0 0-1-3-1-4-1-5 0-4 1-5 2-4 3-4 3-3 4-2 4-2 4-1 5 0 4 0 5 2 3 2 4 3 3 4 2 3 1 3 2 4 2 5 2 4 2 4 3 5 2 4 2 4 3 5 2 4 3 4 3 4 2 4 3 5 3 4 2 4 3 4 3 4 3 4 3 4 3 4 3 3 4 4 3 4 3 4 3 3 4 4 3 4 4 3 3 4 4 3 3 4 4 3 4 4 3 3 4 3 4 3 4 4 4 3 1 1 3 3 3 3 2 5 1 4 0 4-1 5-1 4-2 4-3 4-4 3-4 2-4 2-4 0z m264 0l0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 0-5 0 0-1 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 0 0 0 0 0-4-1 0 0-1 0-1 0-4-1-5-2-3-2-4-3-2-4-2-4-2-4 0-5 1-4 1-5 2-4 3-3 4-3 4-3 4-1 4-1 4 0 1 1 4 0 4 0 4 1 4 0 3 0 4 0 4 0 4 0 4 0 4 0 4 0 3 0 4 0 4-1 4 0 4 0 3-1 4 0 4-1 4 0 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4-1 3-1 4-1 4-1 3-1 4-1 3-2 4-1 4-1 3-1 4-2 3-1 4-1 3-2 0 0 0 0 4-1 5-1 5 0 4 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4 0 5-2 4-2 4-3 3-4 3-3 2 0 0-1 0 0 0-3 2-1 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0-1 0-3 1-1 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0-1 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-5 0 0 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 1 0 0 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0 1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0z m-155-39l-4 0-5-1-3-1-2-1 0 0 0 0-4-2 0 0 0 0-3-2-1-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-2 0 0 0 0-4-2 0-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0-1-1-3-2 0 0 0 0-3-3 0 0-1 0-3-2 0-1 0 0-3-2 0 0-1 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0-1 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-4 0 0 0 0-3-3 0 0 0 0-2-3-1 0 0-1-2-3 0 0 0 0-3-3 0 0 0-1-3-3 0 0 0 0-2-3 0 0-1-1-2-3 0 0 0 0-2-3-1-1 0 0-2-3 0 0 0 0-2-4-1 0 0 0-2-3-2-4-1-4-1-5 1-4 1-5 2-4 3-3 3-4 4-2 4-2 4-1 5 0 4 1 5 2 4 2 3 3 2 3 2 3 2 3 2 3 3 3 2 4 2 3 2 3 3 3 2 3 3 2 2 3 3 3 2 3 3 3 2 3 3 3 3 2 3 3 2 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 2 3 3 3 2 3 2 3 2 3 2 3 2 4 2 3 2 3 2 3 2 4 2 3 2 2 0 3 3 4 3 2 4 2 4 1 4 1 5-1 4-1 5-3 4-2 3-4 3-4 2-4 2-5 0z m393-59l-5-1-4-1-4-1-4-3-3-3-3-4-1-4-1-5-1-4 1-5 2-4 2-4 2-3 3-2 3-3 2-3 3-3 2-3 3-3 2-3 3-2 2-3 3-3 2-3 2-3 3-4 2-3 2-3 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-4 2-3 1-3 2-4 2-3 1-3 2-4 2-3 1-4 1-3 2-4 1-3 2-4 1-3 1-4 1-4 2-3 1-4 1-3 0-3 2-4 2-4 4-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 4 0 2 0 0 0 0-2 4 0 0 0 1-1 3 0 1 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-1 3 0 0-1 1-1 3 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0-1 0-1 4-1 0 0 0-2 3 0 1 0 0-2 3 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 3 0 0 0 1-2 3 0 0 0 0-3 4 0 0 0 0-2 3 0 0 0 1-3 3 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 3 0 1 0 0-2 3-1 0 0 0-2 3 0 1 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 4 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 1-3 3 0 0 0 0-3 2-3 3-4 3-5 1-4 1z m-564-171l-5 0-4-1-4-2-4-2-3-4-3-3-2-4-1-4-1-4 0 0 0 0 0-4 0 0-1 0 0-4 0-1 0 0-1-4 0 0 0 0-1-4 0 0 0 0 0-5 0 0 0 0-1-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0-1 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0-1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 1-5 0 0 0 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 1-4 0 0 0 0 0-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 0-4 1-1 0 0 0-4 0 0 0 0 1-4 0 0 0 0 1-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0-1 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0 0 2-4 0 0 0 0 1-4 0-1 0 0 1-1 1-4 3-4 3-3 4-3 4-2 4-1 5 0 4 1 5 1 4 2 3 3 3 4 2 4 2 4 0 5 0 4-1 4 0 1-2 4-1 4-1 3-1 4-1 3-1 4 0 4-1 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4 0 4 0 3-1 4 0 4 0 4-1 4 0 4 0 3 0 4 0 4 0 4 0 4 0 4 0 3 1 4 0 4 0 4 1 4 0 3 0 4 1 4 0 4 1 4 1 3 0 4 1 4 0 4 0 5-1 4-2 4-3 4-3 3-4 2-5 2-4 1z m754-46l-5 0-4-1-4-2-4-2-3-4-3-4-2-4 0-4-1-4 1-4 0-5 0-5 0-5 0-5 0-5 0-5-1-5 0-5 0-5-1-5 0-5-1-5 0-5-1-5-1-4 0-5-1-5-1-5-1-5-1-5-1-5-1-4-1-5-1-5-2-5-1-4-2-5-1-5-1-4-2-5-2-5-1-4-2-5-2-4-2-5-2-5-2-4-2-5-2-4-2-4-2-5-2-4-2-5-1-4 0-5 1-4 2-4 2-4 3-4 4-2 4-2 4-2 5 0 4 1 5 1 4 2 3 3 3 3 2 3 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 2 4 0 1 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 1 5 0 0 0 0 2 5 0 0 0 0 1 5 0 0 0 0 2 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 0 2 6 0 0 0 0 1 5 0 0 0 0 1 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 0 5 0 0 0 1 1 5 0 0 0 0 0 5 1 0 0 1 0 5 0 0 0 0 0 5 0 1 0 0 1 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0 1 6 0 0 0 0 0 5 0 0 0 1 0 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0-1 6 0 0 0 0 0 4 0 5-2 4-2 4-3 3-4 3-4 2-4 2-4 0z m-853-16l-5 0-4-1-4-1-4-3-4-3-2-4-2-4-1-4-1-4 0-4 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 0-6 0 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 1-5 0 0 0-1 0-5 0 0 0 0 1-5 0-1 0 0 0-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 1-5 0 0 0-1 1-5 0 0 0 0 1-5 0 0 0 0 2-6 0 0 0 0 1-5 0 0 0 0 1-5 0 0 0-1 2-5 0 0 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0-1 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0-1 2-4 0-1 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 3-5 0 0 0 0 2-5 0 0 0 0 2-5 1 0 0 0 0-1 3-4 3-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 5-1 3-1 1-2 5-2 4-2 4-2 5-2 4-2 5-2 5-2 4-2 5-1 4-2 5-1 5-2 4-1 5-2 5-1 4-1 5-2 5-1 5-1 4-1 5-1 5-1 5-1 5-1 5 0 5-1 4-1 5 0 5-1 5 0 5-1 5 0 5 0 5-1 5 0 5 0 5 0 5 0 4 0 4-1 5-2 4-3 3-4 4-3 2-5 2-4 0z m756-57l-4 0-5-1-4-2-4-3-3-3-2-4-2-4-1-3 0 0 0 0 0 0 0 0-1-4 0-4-1-4-1-3 0-4-1-4-1-4-1-3-1-4-1-3-1-4-1-4-2-3-1-4-1-3-1-4-2-4-1-3-2-4-1-3-1-4-2-3-2-3-1-4-2-3-2-4-1-3-2-3-2-4-2-3-2-3-2-3-2-4-2-3-2-3-2-3-2-3-2-3-3-3-2-3-2-4-2-1-2-4-2-4-1-5 0-4 1-5 2-4 2-4 3-3 4-3 4-2 4-1 5-1 4 1 4 1 5 2 3 3 3 3 1 1 0 1 0 0 3 3 0 0 0 0 2 3 1 1 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 0 2 4 0 0 0 0 2 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 1 2 3 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 1 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 1 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 0 4 0 0 0 0 0 0 1 5-1 4-1 4-2 4-3 4-4 3-4 2-4 2-5 0z m-590-160l-4-1-4-2-4-2-4-3-3-3-2-4-1-5-1-4 1-5 1-4 2-4 2-3 1-2 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-2 1-1 0 0 3-2 0 0 0 0 3-3 1 0 0 0 3-3 0 0 0 0 3-2 1 0 0-1 3-2 0 0 0 0 4-2 0-1 0 0 3-2 0 0 0 0 4-2 0-1 0 0 3-2 1 0 0 0 3-2 0 0 0 0 4-3 0 0 0 0 4-2 0 0 0 0 3-2 1 0 0 0 3-2 0 0 1 0 3-2 0 0 0-1 4-1 0-1 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 4-1 4 0 5 0 4 1 4 2 4 3 3 4 2 3 2 5 1 4 0 5-1 4-2 4-2 4-4 3-3 3-4 2-3 1-4 2-3 1-4 2-3 1-3 2-4 1-3 2-4 2-3 2-3 1-4 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-3 2-3 3-3 2-4 2-3 2-2 3-3 2-3 3-3 2-3 3-3 2-3 3-3 2-2 3-3 3-3 3-3 2-2 3-3 3-2 3-3 3-2 3-1 1-4 3-3 3-5 1-4 1-5 1z m426-77l-5 0-4-1-4-2-1-1-4-2-3-1-3-2-4-2-3-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-1-4-1-3-1-4-2-3-1-4-1-4-1-3-1-4-1-4 0-3-1-4-1-4-1-4 0-3-1-4-1-4 0-4-1-3 0-4 0-4-1-4 0-4 0-4-1-3 0-4 0-4 0-5 0-4-2-4-2-4-3-3-3-2-4-1-4-1-5 0-5 1-4 2-4 2-4 4-3 3-3 4-2 5-1 4 0 4 0 0 0 0 0 4 0 0 0 1 0 4 1 0 0 0 0 4 0 0 0 0 0 5 0 0 0 0 0 4 0 0 0 0 0 4 1 1 0 0 0 4 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 1 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 2 0 0 1 0 3 1 1 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 1 1 3 1 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 1 0 0 0 1 4 1 0 0 0 0 4 2 0 0 0 0 4 2 0 0 0 1 4 1 0 1 0 0 4 2 0 0 0 0 2 1 3 2 4 4 2 3 2 5 1 4 0 5-1 4-1 4-3 4-3 4-3 3-4 2-5 1-4 0z m-440-39l-4-1-5-1-4-3-3-3-3-3-2-4-1-5-1-4 0-5 1-4 2-4 3-4 3-2 1-1 0 0 0 0 4-4 0 0 0 0 4-3 0 0 1 0 4-4 0 0 0 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0-1 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-2 0 0 0-1 5-2 0 0 0 0 4-3 1 0 0 0 4-2 0 0 0-1 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 4-2 1 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 5-1 0 0 0 0 5-2 0 0 0 0 5-1 0 0 0 0 5-2 1 0 0 0 5-1 0 0 0 0 5-1 0 0 0 0 6-2 0 0 0 0 4-1 5 0 4 0 5 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4-1 5-1 4-3 4-3 3-4 3-4 2-3 1-5 1-4 1-5 1-5 1-5 2-4 1-5 2-5 1-4 2-5 1-5 2-4 1-5 2-5 2-4 2-5 2-4 2-5 2-4 2-5 2-4 2-4 2-5 3-4 2-4 2-5 3-4 2-4 3-4 3-4 2-4 3-5 3-4 2-4 3-4 3-4 3-3 3-4 3-4 3-1 1-4 3-4 1-4 1-5 1z m543-3l-5 0-4-1-5-2-3-2-1-2-4-3-4-3-4-3-4-3-4-3-4-2-4-3-5-3-4-2-4-3-4-3-4-2-5-3-4-2-4-2-5-3-4-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-1-5-2-4-1-5-2-5-1-5-2-4-1-5-2-5-1-5-1-4-1-5-1-3-1-5-1-4-2-3-3-3-3-2-4-2-5-1-4 0-5 1-4 2-4 3-4 3-3 4-3 4-2 4-1 5 0 4 0 3 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 2 0 0 1 0 5 1 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 1 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 1 0 0 4 2 1 0 0 0 4 3 0 0 1 0 4 2 0 1 0 0 5 2 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 1 4 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 4 4 1 0 0 0 4 3 0 0 0 0 2 2 3 3 3 4 2 4 1 4 0 5-1 4-1 5-2 4-3 3-4 3-4 2-4 2-4 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-condition" unicode="&#xe814;" d="m500 802c-249 0-452-203-452-452 0-249 203-452 452-452 249 0 452 203 452 452 0 249-203 452-452 452z m0-49c223 0 403-180 403-403 0-223-180-403-403-403-223 0-403 180-403 403 0 223 180 403 403 403z m-151-213l0-12 0-368 50 0 202 0 50 0 0 380-302 0z m24-24l254 0 0-332-26 0-202 0-26 0 0 332z m26-37l0-25 202 0 0 25-202 0z m0-74l0-24 202 0 0 24-202 0z m0-85l0-24 202 0 0 24-202 0z m0-77l0-24 202 0 0 24-202 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-timer" unicode="&#xe815;" d="m500 564c-85 2-167-54-198-133-33-76-15-170 43-229 56-60 149-82 226-54 81 28 141 108 143 194 5 83-46 166-121 201-29 14-61 21-93 21z m0-39c78 2 152-55 170-131 20-73-14-156-79-194-67-42-160-31-215 26-58 56-68 152-24 219 32 49 89 81 148 80z m55-49c-19-36-39-71-58-107-18-2-23-29-6-36 11-8 20 5 30 4 30 0 59 0 89 0 0 8 0 17 0 25-30 0-60 0-89 0 18 34 37 68 56 102-7 4-14 8-22 12z m-51 324l-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 0-6-1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6 0 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0-1 0 0-6-1 0 0-1 0-6-1 0 0 0 0-6-2 0 0 0 0-4-1-4-1-4-2-3-3-3-4-2-4-2-4 0-5 0-4 1-5 2-4 3-4 3-3 4-2 5-2 4-1 5 0 3 1 3 1 6 1 6 1 6 2 5 1 6 1 6 1 6 1 6 0 6 1 5 1 6 0 6 1 6 0 6 1 6 0 6 0 6 0 6 0 6 0 5 0 6 0 6-1 6 0 6-1 6 0 6-1 5 0 6-1 6-1 6-1 6-1 5-1 2 0 4-1 5 0 4 2 4 2 4 2 3 4 3 3 1 5 1 4 0 5-1 4-1 4-3 4-3 4-3 2-5 2-3 1-2 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0 0 0-7 1 0 0 0 0-6 0 0 1-1 0-6 0 0 0 0 0-6 1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6 1 0 0 0 0-6 0-1 0 0 0-6 0 0 0z m246-79l-5-1-4-1-4-3-3-3-3-4-1-4-2-4 0-5 1-4 1-5 2-4 3-3 3-3 2-1 0 0 2-2 0 0 3-1 0 0 2-2 0 0 2-2 2-2 0 0 3-2 0 0 2-1 2-2 0 0 2-2 3-2 0 0 2-2 2-2 0 0 2-2 2-2 1 0 2-2 2-2 2-2 0 0 2-2 0 0 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 2-2 0 0 2-3 2-2 2-2 0-1 1-2 0 0 2-2 0 0 2-3 0 0 1 0 2-4 3-3 2-4 3-3 2-3 3-4 2-3 2-4 0 0 3-3 2-4 2-4 3-3 2-4 2-3 2-4 2-4 2-3 2-4 2-4 1-2 3-4 3-4 3-2 4-2 5-2 4 0 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 5-1 4-1 3-2 3 0 0 0 0-2 4 0 0 0 1-2 4 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0-1 0-2 4 0 0 0 0-3 4 0 0 0 0-3 4 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 4 0 0 0 0-3 3-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2-1 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 2 0 0-1 0-2 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2-1 0 0 1-2 1 0 1 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-2 1-4 2-4 2-5 0z m-521-12l-5-1-4-2-3-2 0 0 0 0-1 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0-1-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0-1 0 0-2-2 0 0 0 0-2-2 0 0-1 0-2-2 0 0 0-1-2-2 0 0 0 0-3-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2-1 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0-1 0-1-3 0 0 0 0-2-2-1-2 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0-1-2-2 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0 0-1-2-4 0-5 0-4 1-5 2-4 2-4 4-3 3-3 5-1 4-1 5-1 4 1 4 2 4 2 4 3 3 3 1 4 1 0 1 3 1 3 0 0 1 2 0 0 2 3 1 3 0 0 2 2 0 0 1 3 1 2 0 1 2 2 1 3 0 0 2 2 0 0 1 3 2 2 0 0 1 3 2 2 1 3 0 0 2 3 0 0 2 2 0 0 1 2 2 3 2 2 0 0 1 3 2 2 2 3 1 1 0 0 2 3 1 2 0 0 2 3 2 2 0 0 1 3 2 2 0 0 2 3 0 0 2 2 1 3 2 2 0 0 2 2 2 3 2 2 0 0 2 2 1 3 2 2 0 0 2 2 2 2 0 0 2 3 0 0 2 2 0 0 2 2 0 0 2 2 2 2 0 0 2 2 0 0 2 3 0 0 2 2 2 2 0 0 2 2 3 2 0 0 2 2 2 2 0 0 2 2 0 0 2 2 0 0 2 2 0 0 3 1 0 0 2 2 0 0 2 2 0 0 2 2 3 2 0 0 2 2 0 0 0 0 3 3 3 4 2 4 1 4 0 5 0 4-2 5-2 4-3 3-3 3-4 2-4 2-5 1z m694-313l-4-1-5-2-3-2-3-4-3-4-2-4-1-4 0-4 1-4 0-4 0-4 0-5 0-4 0 0 0-1 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0-3 0-3 0-3-1-3 0-3 0 0 0-3 0 0 0-3-1-3 0-3 0-3-1-2 0-1 0-3 0 0 0-2-1-3 0-3 0 0-1-3 0-3-1-3 0 0 0-3-1-3-1-3 0 0 0-2-1-3 0 0 0-3-1-3 0 0-1-3-1-3 0 0 0-2 0 0-1-3 0 0-1-3 0 0-1-3 0 0-1-3-1-2 0 0 0-3-1-3 0 0-1-3 0 0-1-2 0-1-1-2 0 0-1-3 0 0-1-3-1-2 0 0-1-3-3-5-2-6-2-5-3-5-2-6-3-5-3-5-1-3-2-4-1-4 0-5 1-4 1-5 3-4 3-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 3 1 3 1 0 0 0 3 6 0 0 0 0 2 6 1 0 0 0 2 6 0 0 0 0 3 5 0 1 0 0 3 5 0 1 0 0 2 6 0 0 1 0 2 6 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 1 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 1 0 0 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 4 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 3 0 1 0 0 0 3 0 4 0 0 0 0 0 4 0 0 0 1 0 4 0 0 0 0-1 5 0 0 0 0 0 4 0 5-2 4-2 4-3 4-4 2-4 3-4 1-4 1z m-853-18l-4-1-5-2-3-3-4-3-2-4-2-4-1-4 0-4 0-3 0 0 0 0 0-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 1 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0 0 2-6 0-1 0 0 1-6 0 0 0 0 2-6 0 0 0-1 2-6 0 0 0 0 1-6 0 0 0 0 2-6 0 0 0 0 2-6 0-1 0 0 2-6 0 0 0 0 2-6 0 0 0 0 2-6 1 0 0 0 2-6 0 0 0 0 2-6 0 0 0-1 3-5 0-1 0 0 2-5 0-1 0 0 3-5 0-1 0 0 2-5 0-1 1 0 2-5 0-1 0 0 3-5 0 0 0-1 1-1 2-4 4-4 3-2 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 5 0 4 0 5-1 4-1 4-1 1-3 5-2 6-3 5-2 6-2 5-2 5-3 6-2 6-2 5-1 6-2 5-2 6-2 6-1 5-2 6-1 6-2 5-1 6-1 6-1 6-1 6-1 5-1 6-1 6-1 6 0 6-1 5 0 6-1 6 0 6 0 6-1 6 0 3 0 4-1 5-3 4-2 3-4 3-4 3-4 1-4 1z m694-334l-4-1-4-2-4-3 0 0-5-3-4-4-5-4-5-3-5-3-4-4-5-3-5-3-5-3-5-4-5-3-6-3-5-2-5-3-5-3-5-3-6-2-5-3-5-2-6-2-5-3-6-2-5-2-6-2-5-2-6-2-5-2-6-1-5-2-6-2-6-1-5-1-5-1-4-2-4-2-4-3-2-3-3-4-1-5-1-4 1-5 1-4 2-4 2-4 3-3 4-3 4-1 5-1 4-1 4 1 5 1 0 0 0 0 6 2 0 0 0 0 6 1 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 1 0 5 2 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 3 0 0 0 0 6 2 0 0 1 0 5 3 0 0 1 0 5 2 0 0 1 0 5 3 0 0 1 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 1 0 0 5 3 0 0 1 0 5 3 0 0 0 1 5 3 0 0 1 0 5 4 0 0 0 0 5 3 0 0 0 0 6 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 1 0 4 4 1 0 0 0 0 1 3 3 3 4 2 4 1 4 0 5 0 4-2 4-2 4-3 4-4 3-4 2-4 1-4 1z m-541-2l-4-1-4-3-4-2-3-4-2-4-1-4-1-5 0-4 1-5 2-4 3-4 3-2 1-1 0-1 0 0 5-4 0 0 0 0 5-4 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 3-1 0-1 0 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 2-2 0 0 1 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0-1 3-1 0 0 0 0 3-2 0 0 0 0 2-1 1 0 0 0 2-2 1 0 0 0 2-2 0 0 1 0 2-1 0 0 1 0 2-2 0 0 0 0 3-1 0 0 0 0 3-2 0 0 1 0 2-1 0 0 1 0 2-1 0-1 1 0 2-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 2 0 0 0 0 0 3-1 0 0 0-1 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 4 0 0-1 0 0 3 0 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 0 0 5 0 4 0 5 1 4 2 4 2 3 4 2 3 2 5 1 4 0 5 0 4-2 4-2 4-3 4-4 2-4 3-3 1 0 0-1 0-3 0-2 1 0 0-3 1 0 0-3 1 0 0-3 0 0 0-3 1-3 1-3 1 0 0-3 1-2 1-3 1-3 1-1 0-1 0-3 1-3 1-3 1 0 0-2 1-3 1-3 1-3 0-3 1 0 0-3 1-3 1-2 1 0 0-3 2-3 1 0 0-3 1 0 0-2 1-3 1 0 0-3 1-3 1-2 2-3 1 0 0-3 1-2 1-3 2-3 1-2 1 0 0-3 2-2 1 0 0-3 1 0 0-3 2 0 0-2 1-2 2-1 0-2 1 0 0-3 2-2 1 0 0-3 2-2 1 0 0-3 2 0 0-2 2 0 0-2 1-3 2 0 0-2 2-2 1-1 0-2 2 0 0-2 2-3 1 0 0-2 2 0 0-2 2 0 0-3 2-4 3-5 4-1 1-4 3-4 1-4 2-5 0z" horiz-adv-x="1000" />
+<glyph glyph-name="sequential-mi-marker-kopie" unicode="&#xe816;" d="m150 672l0-130 700 0 0 130-700 0z m0-257l0-130 700 0 0 130-700 0z m0-257l0-130 700 0 0 130-700 0z" horiz-adv-x="1000" />
+<glyph glyph-name="manual" unicode="&#xe817;" d="m460 644c-7 0-15-3-22-8l0 0 0 0c-47-30-209-143-245-167-29-20-49-50-61-87l0 0 0 0c-12-38-10-82-10-120l0 0 0 0c0-28 1-51 8-79 0 0 0 0 0 0 0 0 0 0 0 0 10-42 28-73 54-94 25-21 59-32 97-32 147-1 293-1 439 0l0 0 0 0c12 0 22 3 29 10 7 7 11 18 11 33l0 0c0 15-3 26-11 32-7 6-17 9-29 9l0 0c-55 0-184 0-189 0l0 21 252 0c13 0 23 2 31 6 8 5 14 14 16 25 4 18 1 32-7 41-8 10-21 14-38 14l0 0c-77 0-249 0-254 0l0 19c5 0 271 0 302 0 16 0 28 5 35 13 7 9 10 21 10 37 0 15-4 27-11 34-8 8-20 11-34 11l0 0c-93 0-298 0-302 0l0 19c5 0 159 0 226 0l0 0 0 0c15 0 26 5 34 13 8 9 12 21 12 37l0 0 0 0c0 15-4 27-12 36-8 8-20 13-34 13l0 0c-55 0-141 0-214-1-36 0-70 0-94 0-13 0-23 0-30 1-4 0-7 0-9 0-1 0-2 0-2 0-1 0-1 0-1 0 0 0 0 0-1 1 0 0 1 1 0 0 6 7 22 23 38 39 16 16 32 32 39 40l0 0c15 20 17 48 5 66l0 0c-7 11-15 16-24 17-1 0-2 1-4 1z m0-5c1 0 2-1 3-1 7-1 14-5 21-15l0 0 0 0c10-16 9-41-5-60l0 0 0 0c-6-7-22-23-39-39-16-17-32-32-38-39-1-2-1-5 0-6 1-2 2-3 4-4 0 0 1 0 2 0 0 0 1 0 2 0 2 0 5 0 9 0 7-1 17-1 30-1 24 0 58 0 94 0 73 1 159 1 214 1l0 0 0 0c13 0 23-4 30-12 7-7 11-18 11-33 0-14-4-25-11-33-6-7-16-11-30-11-68 0-228 0-228 0l-3 0 0-29 3 0c0 0 210 0 304 0 14 0 24-3 30-9 7-7 10-17 10-31 0-15-3-26-9-34-6-7-16-11-31-11-31 0-304 0-304 0l-3 0 0-29 3 0c0 0 178 0 256 0l0 0 0 0c16 0 27-4 34-12 7-8 10-20 6-37l0 0 0 0c-2-11-6-17-13-21-7-4-17-6-29-6l-257 0 0-3 0-28 3 0c0 0 135 0 191 0l0 0c12 0 20-3 26-8 6-5 9-14 9-28l0 0 0 0c0-14-4-23-9-29-6-6-15-9-26-9-146-1-292-1-439 0l0 0 0 0c-38 0-69 10-94 31-25 20-43 50-53 91l0 0 0 0c-6 28-7 50-7 78l0 0c0 38-1 82 10 118 12 36 31 65 59 85 36 24 198 137 244 167l0 0c7 4 14 7 20 7z" horiz-adv-x="1000" />
+<glyph glyph-name="receive" unicode="&#xe818;" d="m115 644c0 0 0 0-1 0 0 0 0 0 0 0-1-1-2-2-2-3l0-582c0-1 1-2 3-2l771 0c1 0 2 1 2 2l0 582c0 1-1 2-2 3 0 0 0 0 0 0 0 0 0 0 0 0l-481 0z m9-5l753 0-377-228z m-7-2l382-231c1 0 2 0 2 0l382 231 0-575-766 0z" horiz-adv-x="1000" />
+<glyph glyph-name="sub-process-marker" unicode="&#xe819;" d="m115 735l0-5 0-765 770 0 0 770-770 0z m10-10l750 0 0-750-750 0 0 750z m355-75l0-280-280 0 0-40 280 0 0-280 40 0 0 280 280 0 0 40-280 0 0 280-40 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-parallel-multiple" unicode="&#xe81a;" d="m496 802c-176 0-345-113-412-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47-1 0-3 0-4 0z m12-49c173-1 335-126 380-293 47-159-17-344-155-439-143-105-354-97-489 18-136 108-185 309-115 468 60 147 212 248 371 246 3 0 6 0 8 0z m-78-208l0-125-125 0 0-140 125 0 0-125 140 0 0 125 125 0 0 140-125 0 0 125-140 0z m23-23l94 0 0-125 125 0 0-94-125 0 0-125-94 0 0 126-125 0 0 93 125 0 0 125z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-error" unicode="&#xe81b;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m173-210c-34-70-68-139-102-209-43 56-86 111-128 166-39-114-77-228-116-342 43 55 87 111 130 167 45-51 89-103 134-154 27 124 55 248 82 372z m-219-110c41-52 81-103 122-154 10 22 20 45 30 67-10-39-19-78-29-116-41 48-83 97-124 145-17-26-34-52-50-77 17 45 34 90 51 135z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-signal" unicode="&#xe81c;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-99c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z m0-51c50-90 100-180 151-270-101 0-201 0-302 0 51 90 101 180 151 270z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-error" unicode="&#xe81d;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m173-118c-34-70-68-139-102-209-43 56-86 111-128 166-39-114-77-228-116-342 43 55 87 111 130 167 45-51 89-103 134-154 27 124 55 248 82 372z m-219-110c41-52 81-103 122-154 10 22 20 45 30 67-10-39-19-78-29-116-41 48-83 97-124 145-17-26-34-51-50-77 17 45 34 90 51 135z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-compensation" unicode="&#xe81e;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m-16-162c-70-49-140-99-209-148 70-49 139-99 209-148 0 48 0 95 0 143 67-48 135-95 202-143 0 99 0 197 0 296-67-48-135-95-202-143 0 48 0 95 0 143z" horiz-adv-x="1000" />
+<glyph glyph-name="subprocess-collapsed" unicode="&#xe81f;" d="m216 716c-86 0-155-69-155-154l0-424c0-85 69-154 155-154l569 0c85 0 154 69 154 154l0 424c0 85-69 154-154 154l-569 0z m0-48l569 0c59 0 106-47 106-106l0-424c0-59-47-106-106-106l-116 0 0 308-338 0 0-15 0-293-115 0c-60 0-106 47-106 106l0 424c0 59 46 106 106 106z m146-359l276 0 0-276-276 0 0 276z m115-39l0-23 0-54-54 0-23 0 0-46 23 0 54 0 0-54 0-23 46 0 0 23 0 54 54 0 23 0 0 46-23 0-54 0 0 54 0 23-46 0z" horiz-adv-x="1000" />
+<glyph glyph-name="subprocess-expanded" unicode="&#xe820;" d="m215 716c-85 0-154-69-154-154l0-424c0-85 69-154 154-154l570 0c85 0 154 69 154 154l0 424c0 85-69 154-154 154l-570 0z m0-48l570 0c59 0 106-47 106-106l0-424c0-59-47-106-106-106l-116 0 0 292 0 16-15 0-308 0-15 0 0-16 0-292-116 0c-59 0-105 47-105 106l0 424c0 59 46 106 105 106z m147-359l276 0 0-277-276 0 0 277z m37-110l0-47 203 0 0 47-203 0z" horiz-adv-x="1000" />
+<glyph glyph-name="task" unicode="&#xe821;" d="m215 716c-85 0-154-69-154-154l0-424c0-85 69-154 154-154l570 0c85 0 154 69 154 154l0 424c0 85-69 154-154 154l-570 0z m0-48l570 0c59 0 106-47 106-106l0-424c0-59-47-106-106-106l-570 0c-59 0-105 47-105 106l0 424c0 59 46 106 105 106z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-error" unicode="&#xe822;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m173-117c-34-70-68-139-102-209-43 56-86 111-128 166-39-114-77-228-116-342 43 55 87 111 130 167 45-51 89-103 134-154 27 124 55 248 82 372z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-escalation" unicode="&#xe823;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-111c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z m1-83c23-73 45-146 68-219-22 24-45 49-68 74-19-17-69-82-66-68 24 70 41 143 66 213z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-timer" unicode="&#xe824;" d="m499 802c-1 0-2 0-3 0-202 1-391-150-436-346-42-173 28-368 174-471 145-107 354-116 506-18 149 93 235 276 207 450-26 176-164 330-338 371-36 9-73 14-110 14z m-5-49c3 0 7 0 10 0 187 2 362-146 392-331 32-167-54-348-205-427-154-85-363-54-483 77-124 127-147 338-53 488 71 116 203 192 339 193z m8-44c-3 0-7 0-10 0-172 0-330-143-349-314-22-161 79-328 233-382 145-55 322-3 413 124 98 129 92 326-17 447-67 77-167 125-270 125z m-2-48c2 0 4 0 6 0 153 0 292-129 304-281 16-145-84-293-225-330-137-40-296 27-361 154-69 129-33 305 86 392 54 42 122 65 190 65z m-4-97c-84 0-164-55-194-133-33-76-15-170 43-229 56-60 149-82 226-54 81 28 141 108 143 194 5 83-46 166-121 201-29 14-61 21-93 21-1 0-3 0-4 0z m8-39c76 0 148-57 166-131 20-73-14-156-79-194-67-42-160-31-215 26-58 56-68 152-24 219 32 49 89 81 148 80 1 0 2 0 4 0z m51-49c-19-36-39-71-58-107-18-2-23-29-6-36 11-8 20 5 30 4l89 0 0 25-89 0c18 34 37 68 56 102-7 4-14 8-22 12z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-escalation" unicode="&#xe825;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m0-203c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z m1-83c23-73 45-146 68-219-22 24-45 49-68 74-19-17-69-82-66-68 24 70 41 143 66 213z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-signal" unicode="&#xe826;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m0-191c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z m0-51c50-90 100-180 151-270-101 0-201 0-302 0 51 90 101 180 151 270z" horiz-adv-x="1000" />
+<glyph glyph-name="business-rule-task" unicode="&#xe827;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m-36-72l0-190 0-9 0-25 0-156 165 0 25 0 314 0 0 190 0 190-504 0z m25-132l140 0 0-67-140 0 0 9 0 58z m165 0l289 0 0-58 0-9-289 0 0 67z m-165-92l140 0 0-131-140 0 0 131z m165 0l289 0 0-131-289 0 0 131z" horiz-adv-x="1000" />
+<glyph glyph-name="script" unicode="&#xe828;" d="m385 644l-2-1c-57-34-96-65-121-94-24-29-35-56-35-81-1-51 39-93 78-133 39-40 78-78 82-119 2-21-4-43-23-67-20-25-53-52-104-82l-19-10 389 0 2 0c52 31 86 58 107 85 21 26 28 51 26 75-5 47-47 86-86 126-39 40-75 80-74 125 0 22 9 46 32 74 24 27 62 57 118 91l18 11-388 0z m3-12l344 0c-48-30-81-57-103-83-25-29-36-56-36-81-1-51 39-93 78-133 39-40 78-78 82-119 2-21-4-43-23-67-19-24-52-51-103-81l-344 0c43 26 71 51 90 74 21 26 28 51 25 75-5 47-46 86-85 126-39 40-75 80-75 125 1 22 10 46 33 74 23 27 61 57 117 90z m-50-102c-8 0-8-11 0-11l205 0c8 0 8 11 0 11l-46 0-159 0z m20-115c-7 0-7-12 0-12l188 0c7 0 7 12 0 12l-188 0z m63-116c-8 0-8-11 0-11l208 0c8 0 8 11 0 11l-208 0z m41-115c-7 0-7-12 0-12l208 0c8 0 8 12 0 12l-208 0z" horiz-adv-x="1000" />
+<glyph glyph-name="send" unicode="&#xe829;" d="m112 644l388-214 388 214-776 0z m0-105l0-483 776 0 0 483-388-193-388 193z" horiz-adv-x="1000" />
+<glyph glyph-name="call-activity" unicode="&#xe82a;" d="m231 745c-116 0-211-93-211-208l0-374c0-115 95-208 211-208l538 0c116 0 211 93 211 208l0 374c0 115-95 208-211 208l-538 0z m0-110l538 0c58 0 101-43 101-98l0-374c0-55-43-98-101-98l-538 0c-58 0-101 43-101 98l0 374c0 55 43 98 101 98z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-timer" unicode="&#xe82b;" d="m500 802c-249 0-452-203-452-452 0-249 203-452 452-452 249 0 452 203 452 452 0 249-203 452-452 452z m0-49c223 0 403-180 403-403 0-223-180-403-403-403-223 0-403 180-403 403 0 223 180 403 403 403z m-4-189c-84 0-164-55-194-133-33-76-15-170 43-229 56-60 149-82 226-54 81 28 141 108 143 194 5 83-46 166-121 201-29 14-61 21-93 21-1 0-3 0-4 0z m8-39c76 0 148-57 166-131 20-73-14-156-79-194-67-42-160-31-215 26-58 56-68 152-24 219 32 49 89 81 148 80 1 0 2 0 4 0z m51-49c-19-36-39-71-58-107-18-2-23-29-6-36 11-8 20 5 30 4l89 0 0 25-89 0c18 34 37 68 56 102-7 4-14 8-22 12z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-message" unicode="&#xe82c;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m-205-247c0-104 0-208 0-312 137 0 273 0 410 0 0 104 0 208 0 312-137 0-273 0-410 0z m91-49c76 0 152 0 228 0-40-24-81-79-121-85-36 29-71 57-107 85z m270-28c0-62 0-124 0-186-104 0-208 0-312 0 0 62 0 124 0 186 52-42 104-83 156-125 52 42 104 83 156 125z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-none" unicode="&#xe82d;" d="m496 802c-219 2-422-178-445-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 165-214 291-388 303-15 1-29 2-43 2z m8-49c201 3 386-169 398-370 16-178-100-360-271-415-164-56-362 4-460 148-103 144-99 357 19 491 76 92 194 149 314 146z m-12-44c-185 0-352-166-352-352-4-168 124-331 291-360 153-30 322 49 390 191 71 141 39 329-84 431-67 59-156 92-245 90z m14-48c165 1 312-150 305-315 0-150-121-290-272-305-143-19-295 73-336 213-43 134 14 296 139 364 50 29 107 44 164 43z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-link" unicode="&#xe82e;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m50-116c0-33 0-67 0-100-75 0-150 0-226 0 0-63 0-127 0-190 76 0 151 0 226 0 0-33 0-67 0-100 55 65 110 130 165 195-55 65-110 130-165 195z m28-73c34-40 68-81 102-121-34-40-68-81-102-121 0 18 0 36 0 54-75 0-149 0-223 0 0 44 0 89 0 133 74 0 148 0 223 0 0 18 0 37 0 55z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-escalation" unicode="&#xe82f;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m0-110c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z" horiz-adv-x="1000" />
+<glyph glyph-name="text-annotation" unicode="&#xe830;" d="m677 795l0-25 0-411 0-412 0-24 24 0 224 0 25 0 0 49-25 0-199 0 0 387 0 386 199 0 25 0 0 50-25 0-224 0-24 0z m-81-386l-75-60 60-75 75 60-60 75z m-151-119l-75-60 60-75 75 59-60 76z m-150-120l-76-59 60-76 75 60-59 75z m-151-119l-76-60 60-75 76 59-60 76z" horiz-adv-x="1000" />
+<glyph glyph-name="bpmn-io" unicode="&#xe831;" d="m388-22c-70-71-186-74-258-4-72 71-75 187-3 258 71 73 187 74 259 4 72-70 73-185 2-258z m502 404l0 0 21-77-85-35-41 68 3 1c-30-5-61-7-93 0l-40-68-85 35 20 77 1-1c-25 18-47 39-64 64l0 0-77-20-35 85 67 40 2-2c-5 30-5 61 0 92l-68 40 35 85 77-19 0-4c11 15 22 28 37 41l-443 0c-31 0-56-26-56-57l0-370 52-38-1-1c26 17 53 29 83 35l0 0 11 77 90 1 12-76-3 0c29-6 58-17 84-33l61 47 64-63-46-62-1 1c17-26 29-53 35-82l0 0 77-10 2-90-77-13 0 3c-7-29-17-58-33-84l42-53 360 0c31 0 56 24 56 57l0 445c-14-13-28-26-44-36z m23 142c-39-95-149-139-243-100-95 39-139 148-100 242 39 95 149 139 243 100 95-39 140-147 100-242z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-complex" unicode="&#xe832;" d="m500 802c-9 0-19-4-26-11l-415-415c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-7 7-17 11-26 11z m0-62l390-390-390-390-390 390 390 390z m-9-192l0 0c0 0-4-1-4-1 0 0-4-2-4-2 0 0-2-3-2-3 0 0-1-4-1-4l0-140-99 99 0 0c0 0-3 2-3 2 0 0-4 1-4 1 0 0-4-1-4-1 0 0-4-2-4-2l-13-13c0 0-2-4-2-4 0 0-1-4-1-4 0 0 1-4 1-4 0 0 2-3 2-3l99-99-140 0 0 0c0 0-4-1-4-1 0 0-3-2-3-2l0 0c0 0-2-4-2-4 0 0-1-4-1-4l0-18c0 0 1-4 1-4 0 0 2-4 2-4 0 0 3-2 3-2 0 0 4-1 4-1l140 0-99-99 0 0c0 0-2-3-2-3 0 0-1-4-1-4 0 0 1-4 1-4 0 0 2-4 2-4l13-13c0 0 4-2 4-2 0 0 4-1 4-1 0 0 4 1 4 1 0 0 3 2 3 2l99 99 0-140 0 0c0 0 1-4 1-4 0 0 2-3 2-3 0 0 4-2 4-2 0 0 4-1 4-1l18 0c0 0 4 1 4 1 0 0 4 2 4 2 0 0 2 3 2 3 0 0 1 4 1 4l0 140 99-99c0 0 3-2 3-2 0 0 4-1 4-1 0 0 4 1 4 1 0 0 4 2 4 2l13 13c0 0 2 4 2 4 0 0 1 4 1 4 0 0-1 4-1 4 0 0-2 4-2 4l-99 98 140 0c0 0 4 1 4 1 0 0 3 2 3 2 0 0 3 4 3 4 0 0 0 4 0 4l0 18c0 0 0 4 0 4 0 0-3 4-3 4 0 0-3 2-3 2 0 0-4 1-4 1l-140 0 99 99c0 0 2 3 2 3 0 0 1 4 1 4 0 0-1 4-1 4 0 0-2 4-2 4l-13 13c0 0-4 2-4 2 0 0-4 1-4 1 0 0-4-1-4-1 0 0-3-2-3-2l-99-99 0 140c0 0-1 4-1 4 0 0-2 3-2 3 0 0-4 3-4 3 0 0-4 0-4 0l-18 0z m-117-48c0 0 0 0 0 0l0 0c0 0 0 0 0 0z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-eventbased" unicode="&#xe833;" d="m500 802c-9 0-19-4-26-11l-415-415c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-7 7-17 11-26 11z m0-62l390-390-390-390-390 390 390 390z m0-166l-7-5-208-151 82-253 266 0 82 253-215 156z m0-30l187-135-72-220-230 0-72 220 187 135z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-none" unicode="&#xe834;" d="m59 376c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-14 14-38 14-52 0l-415-415z m51-26l390 390 390-390-390-390-390 390z" horiz-adv-x="1000" />
+<glyph glyph-name="gateway-or" unicode="&#xe835;" d="m500 802c-9 0-19-4-26-11l-415-415c-14-14-14-38 0-52l415-415c14-14 38-14 52 0l415 415c14 14 14 38 0 52l-415 415c-7 7-17 11-26 11z m0-62l390-390-390-390-390 390 390 390z m0-180c-116 0-210-94-210-210 0-116 94-210 210-210 116 0 210 94 210 210 0 116-94 210-210 210z m0-23c103 0 187-84 187-187 0-103-84-187-187-187-103 0-187 84-187 187 0 103 84 187 187 187z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-terminate" unicode="&#xe836;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m0-81c-149 6-268-156-219-297 38-143 229-210 349-121 126 79 133 281 13 369-40 32-92 50-143 49z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-signal" unicode="&#xe837;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m0-98c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-none" unicode="&#xe838;" d="m496 802c-203 1-394-153-437-351-41-174 33-368 181-470 143-103 348-111 497-15 150 91 238 275 210 449-26 181-170 339-350 376-33 7-67 11-101 11z m10-142c150 1 287-123 302-271 19-142-72-291-210-334-134-45-296 13-366 138-77 129-45 313 78 403 56 43 126 66 196 64z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-multiple" unicode="&#xe839;" d="m491 802c-219-1-420-183-440-401-22-185 82-379 252-458 159-77 362-53 493 66 134 116 192 313 133 481-55 171-220 303-401 311-13 0-25 1-37 1z m9-142c161 5 308-137 310-298 7-148-104-292-250-317-142-28-300 54-350 192-53 136 1 308 132 380 47 28 102 43 158 43z m0-86c-72-52-143-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253-71 52-143 104-215 156z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-message" unicode="&#xe83a;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m-167-154c57-46 114-92 171-138 56 46 113 92 170 138-114 0-227 0-341 0z m-38-32c0-93 0-187 0-280 137 0 273 0 410 0 0 91 0 183 0 274-67-54-134-109-201-163-70 56-139 113-209 169z" horiz-adv-x="1000" />
+<glyph glyph-name="end-event-link" unicode="&#xe83b;" d="m491 802c-219 0-420-183-440-400-22-186 82-380 253-459 158-77 361-53 492 67 134 115 192 312 133 480-55 172-220 303-401 311-13 1-25 1-37 1z m9-142c161 5 308-137 310-298 7-147-103-292-250-317-142-28-300 54-350 192-53 136 2 309 132 380 47 28 103 43 158 43z m50-115c0-33 0-67 0-100-75 0-150 0-226 0 0-63 0-127 0-190 76 0 151 0 226 0 0-33 0-67 0-100 55 65 110 130 165 195-55 65-110 130-165 195z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-message" unicode="&#xe83c;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-205-155c0-104 0-208 0-312 137 0 273 0 410 0 0 104 0 208 0 312-137 0-273 0-410 0z m91-49c76 0 152 0 228 0-40-24-81-79-121-85-36 29-71 57-107 85z m270-28c0-62 0-124 0-186-104 0-208 0-312 0 0 62 0 124 0 186 52-42 104-83 156-125 52 42 104 83 156 125z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-compensation" unicode="&#xe83d;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-16-163c-70-49-140-99-209-148 70-49 139-99 209-148 0 48 0 95 0 143 67-48 135-95 202-143 0 99 0 197 0 296-67-48-135-95-202-143 0 48 0 95 0 143z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-multiple" unicode="&#xe83e;" d="m500 802c-178 2-349-112-416-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47z m0-49c175 3 342-123 388-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246z m0-179c-72-52-143-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253-71 52-143 104-215 156z m0-30c62-45 124-90 187-135-24-74-48-147-72-220-77 0-153 0-230 0-24 73-48 146-72 220 63 45 125 90 187 135z" horiz-adv-x="1000" />
+<glyph glyph-name="data-input" unicode="&#xe83f;" d="m250 676l0-2c0-1 0-1 0-1l0-649 500 0 0 486c0 0 0 0 0 0l0 1 0 1c-1 0-1 0-1 0l-166 162 0 2-2 0-189 0-139 0-3 0z m5-5l323 0 0-163 167 0 0-479-490 0 0 642z m328-4l158-154-158 0 0 154z m-151-101l0-6 0-51-112 0 0-87 112 0 0-57 88 100-88 101z m5-13l76-88-76-87 0 49-112 0 0 77 112 0 0 49z" horiz-adv-x="1000" />
+<glyph glyph-name="manual-task" unicode="&#xe840;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m168-69l0 0c-7 0-14-2-20-6l0 0 0 0c-31-19-138-90-161-105l0 0 0 0c-21-14-35-34-43-59l0 0-1 0c-8-26-7-54-7-78l0 0 0 0c0-17 1-33 6-52 0 0 0 0 0 0 6-27 20-48 38-63 19-15 43-22 70-22 96 0 192 0 288 0l0 0 0 0c10 0 19 3 26 9 6 7 9 16 9 26l0 0c0 11-3 21-10 27-2 2-4 3-6 4l23 0c9 0 17 1 25 5 7 5 12 12 14 21l0 0c3 13 1 26-7 34-2 2-5 4-8 6 2 0 8 0 9 0 12 0 22 3 29 11 7 8 9 18 9 29 0 11-3 21-10 27-8 7-17 9-28 9l0 0 0 0c-9 0-18 0-29 0 2 2 5 4 7 6 7 8 10 18 10 29l0 0 0 0c0 11-3 21-10 29-7 7-17 10-28 10-17 0-37 0-59 0-27 0-56 0-82 0-24 0-46 0-62 0-4 0-6 0-9 0 4 4 7 7 11 11 11 10 21 20 27 26 12 15 14 36 3 52l0 0c-5 8-13 13-21 14-1 0-2 0-3 0z m-1-20c1 0 1 0 1 0 3 0 5-1 8-6l0 0 0 0c4-6 4-18-3-27l0 0 0 0c-3-3-14-14-24-24-11-11-21-20-26-26-4-5-3-9-2-12 2-3 3-6 9-7 1-1 2-1 2-1 1 0 1 0 2 0 2 0 4 0 6 0 5 0 12 0 20 0 16 0 38 0 62 0 48 0 105 0 141 0l0 0 0 0c7 0 11-1 14-4 2-3 4-8 4-15 0-8-2-12-4-15-3-3-7-4-14-4-45 0-151-1-151-1l-9 0 0-34 10 0c0 0 138-1 200-1 8 0 12-1 14-3 2-2 4-6 4-13 0-9-2-13-4-16-2-2-6-4-14-4-20 0-200 0-200 0l-10 0 0-35 10 0c0 0 117 0 168 0l0 0 0 0c9 0 14-2 17-5 2-2 4-6 2-15l0 0 0 0c-2-6-3-7-5-8-3-2-8-3-15-3l-177 0 0-10 0-26 10 0c0 0 88 0 125 0 7-1 11-2 12-3 2-1 3-4 3-11l0 0 0 0c0-8-2-11-3-13-2-1-5-3-12-3-96 0-192 0-288 0l0 0 0 0c-24 0-43 6-58 18-14 11-25 28-31 52l0 0 0 0c-4 17-5 30-5 48l0 0c0 24 0 50 6 71 8 21 19 37 36 48l0 0c23 16 131 87 161 105 3 2 5 3 7 3 1 0 1 0 1 0z" horiz-adv-x="1000" />
+<glyph glyph-name="service" unicode="&#xe841;" d="m396 646l0-3 0-49c-11-3-21-6-32-10l0 0 0 0c-10-5-20-10-29-16l-38 37-53-53 38-37c-12-19-21-40-25-61l-53 0 0-76 53 0c2-10 6-21 10-31 4-11 10-20 16-29l-39-38 54-53 37 36 0-15 33 1c8-3 15-6 23-8 1-7 4-14 7-22l0-33 2 0c4 0 8-1 12-1l-36-35 54-53 38 38c19-12 40-20 62-25l0-54 2 0c24 0 71 0 71 0l0 0 2 0 0 2 0 52c11 3 22 6 32 10l0 0 0 0c10 5 20 10 29 16l39-38 53 54-38 37c12 19 20 40 25 62l52 0 0 75-53 0c-2 10-5 21-10 31l0 0c-4 11-10 20-16 29l37 37-54 53-36-36 0 16-3 0-29 0c-8 3-15 5-22 7-2 7-5 14-7 22l0 31-17 0c0 0 0 0 0 0l36 37-54 53-36-37c-19 12-40 21-61 25l0 52-76 0z m5-5l66 0 0-51 2 0c22-5 44-13 63-26l2-1 35 36 47-46-36-36 1-1-53 0 0 0 0-33c-31 42-87 60-137 39-59-24-86-91-61-149l0 0c8-21 22-37 39-49l-34 0 0 0 0-54-37-36-47 46 38 37-1 2c-6 9-12 19-16 30l0 0c-5 11-8 22-10 32l-1 2-52 0 0 66 52 0 0 2c5 22 13 44 26 63l1 1-37 37 47 46 36-36 2 1c9 6 19 12 30 16l0 0c11 5 22 8 33 10l2 1 0 51z m32-115c38 0 74-19 95-52l0-10c-11-2-22-6-32-10l0 0 0 0c-11-4-20-10-29-16l-38 37-53-53 37-37c-12-19-20-39-25-61l-9 0c-20 11-36 29-45 51l0 0c-23 55 3 119 58 142l0 0c14 6 28 8 41 9z m100-15l57 0 9 0 0-27 0 0-1-24 2 0c3-1 6-1 8-2l1 0c8-2 15-4 22-7l0 0c11-4 21-9 30-15l1-1c1 0 1 0 2-1l1-1 36 36 47-46-36-36 1-2c7-9 12-19 17-30l0 0c4-10 7-21 10-32l0-2 52 0 0-65-51-1-1-2c-4-22-13-43-26-63l-1-1 38-37-46-47-38 37-2-1c-9-6-19-12-30-16-11-5-22-8-33-10l-2-1 0-53c-4 0-43 0-65 0l0 53-2 0c-23 5-45 14-64 26l-1 1-38-37-47 46 36 35 3 0-1 2 0 0-1 1-1 1c-1 2-2 4-3 6-3 4-5 8-7 12-1 1-1 2-1 2 0 1-1 2-1 2 0 1-1 1-1 2 0 1-1 1-1 2 0 1 0 1-1 2 0 1 0 1-1 2l0 0 0 0c0 1 0 1 0 2l-1 1 0 0c-3 7-5 14-7 21l0 1 0 0c0 0 0 0 0 0-1 3-1 5-2 7l0 3 0 0 0 0-2 0-12 0-10 0-29-1 0 9 0 57 52 0 1 2c4 22 13 44 26 63l1 2-37 36 46 46 37-36 2 1c9 6 19 12 30 16l0 0c11 5 22 8 33 11l2 0 0 6 0 2 0 43z m70-41c1-2 2-4 2-6 0 0-1 0-2 0l0 0 0 6z m57-19l0-9c-5 3-11 6-16 9l16 0z m-93-50c-1 0-2 0-3 0l0 0c0 0 0 0 0 0l0 0 0 0c-1 0-1 0-1 0l0 0c-2 0-3 0-5 0l0 0c0 0 0-1 0-1l0 0c-12 0-24-3-36-8-39-16-64-52-69-91l0 0c0 0 0 0 0 0 0-1 0-1 0-1 0 0 0 0 0 0l0 0c0 0 0 0 0 0l0 0c0-1 0-2 0-3l0 0c0 0 0 0 0 0 0 0 0-1 0-1 0 0 0 0 0 0 0 0 0 0 0 0l0 0c-1-2-1-5-1-8l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-3 0-5 0-8l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c1-3 1-5 1-8l0 0c0 0 0 0 0-1l0 0c1-1 1-2 1-3l0 0c0 0 0 0 0 0l0 0c0 0 0 0 0 0 0-1 0-1 0-1l0 0c0 0 0 0 0 0l0 0c0-1 0-2 1-3l0 0c0 0 0 0 0 0 0 0 0-1 0-1l0 0c0-1 0-2 1-4l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-1 0-2 1-3l0 0 0 0c0-1 0-1 0-1l0 0c1-3 1-5 2-7 1-1 1-1 1-2l0 0c0 0 0 0 0 0l0 0c1-1 1-2 1-3l0 0c1-1 1-2 2-3 0 0 0 0 0 0 0-1 0-1 0-1 1-3 2-5 4-7 0 0 0 0 0 0 0 0 0 0 0-1 0 0 0 0 0 0 28-49 90-71 144-49 58 25 85 92 61 149-11 25-29 44-51 56l0 0c0 0 0 0 0 0l0 0 0 0c-1 1-2 1-3 1l0 0c0 1 0 1 0 1l0 0c-2 0-3 1-4 1l0 0c0 0 0 0 0 0l0 0c-1 1-2 1-3 2l0 0c0 0 0 0 0 0l0 0 0 0c-1 0-2 1-3 1l0 0c0 0-1 0-1 0l0 0c-1 1-2 1-3 1l0 0c0 1 0 1-1 1l0 0c-1 0-1 0-2 0l0 0c-1 1-1 1-1 1l0 0c-2 0-5 1-7 2l0 0c0 0 0 0 0 0l0 0 0 0c-1 0-2 0-3 0l0 0c0 0-1 0-1 1l0 0c-1 0-2 0-3 0l0 0c-1 0-1 0-1 0l0 0 0 0c-1 0-2 1-3 1l0 0c0 0 0 0-1 0l0 0c-1 0-2 0-3 0l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-3 1l0 0c-1 0-1 0-1 0l0 0c-1 0-3 0-4 0 0 0 0 0 0 0l0 0 0 0c-1 0-2 0-3 0z m0-5l0 0c1 0 2 0 3 0l0 0c0 0 0 0 1 0l0 0c1 0 1 0 2 0l0 0c1 0 1 0 1 0l0 0c1-1 2-1 3-1l0 0c1 0 1 0 1 0l0 0c1 0 2 0 3 0l0 0c0 0 0 0 1 0l0 0c0 0 1-1 2-1l0 0c1 0 1 0 1 0l0 0c1 0 2 0 3 0l0 0c0 0 0 0 1-1l0 0c1 0 2 0 2 0l0 0c1 0 1 0 1 0l0 0c2-1 4-1 6-2l0 0c1 0 1 0 1 0l0 0c1-1 2-1 3-1l0 0c0 0 0 0 0 0l0 0c1-1 2-1 4-1l0 0c0 0 0-1 0-1l0 0 0 0c1 0 2 0 3-1l0 0c0 0 0 0 0 0l0 0c1 0 2-1 3-1l0 0c0 0 0 0 0 0l0 0c1-1 2-1 3-2l0 0c0 0 1 0 1 0l0 0c1 0 2-1 2-1l0 0c1 0 1-1 1-1l0 0c21-11 38-29 48-53 23-55-3-119-58-142l0 0c-52-22-111-1-138 47 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c-1 2-2 5-3 7 0 0 0 0 0 0 0 0 0 0 0 0-1 0-1 1-1 1 0 0 0 0 0 0 0 1-1 2-1 3 0 0 0 0 0 0-1 1-1 2-1 3-1 0-1 1-1 1 0 0 0 0 0 0-1 3-2 5-2 7l0 0c0 1 0 1 0 1 0 0 0 0 0 0-1 1-1 2-1 3l0 0c0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0l0 0c-1 1-1 2-1 3l0 0c0 0 0 1 0 1-1 1-1 2-1 3l0 0c0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0l0 0c0 1-1 2-1 3l0 0c0 0 0 0 0 0 0 0 0 1 0 1l0 0c0 2 0 5-1 7l0 0c0 0 0 0 0 0 0 0 0 0 0 1l0 0c0 2 0 5 0 7l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 3 0 5 1 8l0 0c0 0 0 0 0 0l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 1 0 3 0 4l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c5 37 29 72 66 87l0 0c11 5 23 8 34 8l0 0c0 1 0 1 1 1l0 0c1 0 2 0 4 0l0 0c0 0 1 0 1 0l0 0c1 0 2 0 3 0z m-178-147l0 0c0-1 0-1 0-2-2 1-3 1-5 2l5 0z m14-41c3-6 6-12 10-18-4 0-7 1-10 1l0 17z" horiz-adv-x="1000" />
+<glyph glyph-name="user" unicode="&#xe842;" d="m492 644l-5-1c-84 0-140-60-140-139 0-39 29-74 58-100-16-5-54-19-93-41-23-12-45-27-62-44-16-17-28-37-29-58l0 0 0-204 98 0c1-1 2-1 3 0l457 0 0 204c0 19-12 37-29 53-18 17-41 32-64 45-42 24-83 40-99 46 28 26 48 60 48 99 0 79-58 140-143 140z m-38-82c13 0 27-3 40-10 59-31 121-43 132-34 1-4 1-9 1-14 0-38-21-73-50-97l-6-5 7-2c6-2 35-13 69-29-2-70-70-127-154-127-84 0-151 55-153 125 35 17 67 28 74 30l7 2-6 5c-29 25-60 60-60 98 0 5 0 10 1 15 10 8 52 42 98 43z m198-194c10-5 20-10 30-16 23-13 46-28 62-43 17-16 27-33 27-48l0-196-90 0 0 144-8 0 0-144-349 0 0 144c0 6-8 6-8 0l0-144-87 0 0 196c1 18 11 36 27 52 16 16 38 31 60 43 6 4 12 7 19 10 3-72 73-127 158-127 86 0 156 57 159 129z" horiz-adv-x="1000" />
+<glyph glyph-name="receive-task" unicode="&#xe843;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m-22-67c-1 0-1 0-1 0-7 0-12-6-12-12l0-357c0-7 6-13 13-13l500 0c6 0 12 6 12 13l0 357c0 6-5 12-12 12 0 0 0 0 0 0l-248 0-176 0-76 0z m47-25l205 0 200 0-202-116-203 116z m-35-9l231-132c4-2 9-2 13 0l231 132 0-323-475 0 0 323z" horiz-adv-x="1000" />
+<glyph glyph-name="data-object" unicode="&#xe844;" d="m250 676l0-2c0-1 0-1 0-1l0-649 500 0 0 486c0 0 0 0 0 0l0 1 0 1c-1 0-1 0-1 0l-166 162 0 2-2 0-236 0-92 0z m5-5l323 0 0-163 167 0 0-479-490 0z m328-4l158-154-158 0z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-none" unicode="&#xe845;" d="m496 802c-176 0-345-113-412-276-70-161-34-362 89-487 119-128 314-175 477-115 169 58 294 224 301 403 12 176-92 351-250 428-62 31-132 47-201 47-1 0-3 0-4 0z m12-49c173-1 335-126 380-293 47-159-17-344-155-439-143-105-354-97-489 18-136 109-185 309-115 468 60 147 212 248 371 246 3 0 6 0 8 0z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-escalation" unicode="&#xe846;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-111c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-multiple" unicode="&#xe847;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-87c-72-52-143-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253-71 52-143 104-215 156z m0-30c62-45 124-90 187-135-24-74-48-147-72-220-77 0-153 0-230 0-24 73-48 146-72 220 63 45 125 90 187 135z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-escalation" unicode="&#xe848;" d="m500 550c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z m1-83c23-73 45-146 68-219-22 24-45 49-68 74-19-17-69-82-66-68 24 70 41 143 66 213z m-1 335c-41-1-83-5-121-18-25-13-8-53 18-44 64 17 131 17 196 3 26-3 34 38 9 47-33 8-68 12-102 12z m255-83c-26 3-36-36-13-47 52-38 93-90 121-147 15-22 52-3 43 22-32 67-82 127-143 170-2 1-5 2-8 2z m-519-10c-22-2-35-23-51-36-42-40-76-89-98-142-8-26 30-42 44-19 27 61 69 115 122 157 13 14 2 40-17 40z m264 0c-20-2-48 4-57-18-8-21 15-38 34-32 51 4 103-5 149-25 26-8 42 31 19 44-45 21-95 31-145 31z m-155-39c-23-4-43-21-62-34-34-27-66-58-86-96-10-26 30-44 43-21 30 47 74 83 121 110 16 14 5 41-16 41z m393-59c-25 2-35-33-14-46 37-38 62-87 77-137 14-24 53-6 44 20-17 60-49 115-94 158-4 3-8 4-13 5z m-564-171c-23 2-28-24-30-41-7-55-2-112 16-163 12-24 51-11 46 15-17 53-20 110-10 164 1 13-10 24-22 25z m754-46c-21 1-29-22-25-39 1-68-16-135-47-195-9-25 29-43 43-21 39 72 57 155 52 237-3 10-13 18-23 18z m-853-16c-22 2-30-22-26-39 1-69 18-137 51-197 15-22 52-2 42 23-30 59-46 126-45 193-2 11-11 19-22 20z m756-57c-22 2-27-22-28-39-10-48-34-91-63-130-12-25 26-47 42-24 38 49 65 108 73 170-1 12-11 23-24 23z m-590-160c-22-1-30-32-13-45 40-46 90-82 147-102 26-6 40 33 17 45-52 20-98 53-134 96-4 4-10 6-17 6z m426-77c-23-5-43-21-66-27-34-13-71-15-106-19-25-9-16-49 10-47 62 1 124 18 177 50 17 14 7 44-15 43z m-440-39c-23-1-31-35-11-46 56-45 123-78 194-91 26-2 35 39 9 47-65 14-127 44-179 87-4 2-8 3-13 3z m543-3c-22-2-36-24-55-32-43-29-92-45-141-57-24-12-10-52 17-46 71 15 140 47 196 95 14 15 2 40-17 40z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-link" unicode="&#xe849;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m50-116c0-33 0-67 0-100-75 0-150 0-226 0 0-63 0-127 0-190 76 0 151 0 226 0 0-33 0-67 0-100 55 65 110 130 165 195-55 65-110 130-165 195z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-condition" unicode="&#xe84a;" d="m349 540l0-12 0-368 50 0 202 0 50 0 0 380-302 0z m24-24l254 0 0-332-26 0-202 0-26 0 0 332z m26-37l0-25 202 0 0 25-202 0z m0-74l0-24 202 0 0 24-202 0z m0-85l0-24 202 0 0 24-202 0z m0-77l0-24 202 0 0 24-202 0z m105 557l-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 0-6-1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6 0 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0 0 0 0-6-1-1 0 0 0-6-1 0-1 0 0-6-1 0 0-1 0-6-1 0 0 0 0-6-2 0 0 0 0-4-1-4-1-4-2-3-3-3-4-2-4-2-4 0-5 0-4 1-5 2-4 3-4 3-3 4-2 5-2 4-1 5 0 3 1 3 1 6 1 6 1 6 2 5 1 6 1 6 1 6 1 6 0 6 1 5 1 6 0 6 1 6 0 6 1 6 0 6 0 6 0 6 0 6 0 5 0 6 0 6-1 6 0 6-1 6 0 6-1 5 0 6-1 6-1 6-1 6-1 5-1 2 0 4-1 5 0 4 2 4 2 4 2 3 4 3 3 1 5 1 4 0 5-1 4-1 4-3 4-3 4-3 2-5 2-3 1-2 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0-1 0-6 1 0 0 0 0-6 1 0 0 0 0-7 1 0 0 0 0-6 0 0 1-1 0-6 0 0 0 0 0-6 1 0 0-1 0-6 0 0 0 0 0-6 0-1 0 0 0-6 1 0 0 0 0-6 0-1 0 0 0-6 0 0 0z m246-79l-5-1-4-1-4-3-3-3-3-4-1-4-2-4 0-5 1-4 1-5 2-4 3-3 3-3 2-1 0 0 2-2 0 0 3-1 0 0 2-2 0 0 2-2 2-2 0 0 3-2 0 0 2-1 2-2 0 0 2-2 3-2 0 0 2-2 2-2 0 0 2-2 2-2 1 0 2-2 2-2 2-2 0 0 2-2 0 0 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 0 0 2-2 2-2 0 0 2-3 0 0 2-2 2-2 2-2 0 0 2-3 2-2 2-2 0-1 1-2 0 0 2-2 0 0 2-3 0 0 1 0 2-4 3-3 2-4 3-3 2-3 3-4 2-3 2-4 0 0 3-3 2-4 2-4 3-3 2-4 2-3 2-4 2-4 2-3 2-4 2-4 1-2 3-4 3-4 3-2 4-2 5-2 4 0 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 5-1 4-1 3-2 3 0 0 0 0-2 4 0 0 0 1-2 4 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0 0 0-3 4 0 0 0 0-2 4 0 0-1 0-2 4 0 0 0 0-3 4 0 0 0 0-3 4 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 4 0 0 0 0-3 3-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 3 0 0 0 0-2 2-1 0 0 0-2 3 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-2 2 0 0-1 0-2 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 3 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-2 2-1 0 0 1-2 1 0 1 0 0-3 2 0 0 0 0-2 2 0 0 0 0-3 2 0 0 0 0-3 2 0 0 0 0-2 2 0 0 0 0-2 1-4 2-4 2-5 0z m-521-12l-5-1-4-2-3-2 0 0 0 0-1 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0-1-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0 0 0 0-2-2 0 0 0 0-3-2 0-1 0 0-2-2 0 0 0 0-2-2 0 0-1 0-2-2 0 0 0-1-2-2 0 0 0 0-3-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-2-1 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2-1 0 0 0-2-3 0 0 0 0-2-2 0 0 0-1-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0-1 0-1-3 0 0 0 0-2-2-1-2 0 0 0 0-2-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-2 0-1 0 0-2-2 0 0 0-1-2-2 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0-1-3 0 0 0 0-2-3 0 0 0 0 0-1-2-4 0-5 0-4 1-5 2-4 2-4 4-3 3-3 5-1 4-1 5-1 4 1 4 2 4 2 4 3 3 3 1 4 1 0 1 3 1 3 0 0 1 2 0 0 2 3 1 3 0 0 2 2 0 0 1 3 1 2 0 1 2 2 1 3 0 0 2 2 0 0 1 3 2 2 0 0 1 3 2 2 1 3 0 0 2 3 0 0 2 2 0 0 1 2 2 3 2 2 0 0 1 3 2 2 2 3 1 1 0 0 2 3 1 2 0 0 2 3 2 2 0 0 1 3 2 2 0 0 2 3 0 0 2 2 1 3 2 2 0 0 2 2 2 3 2 2 0 0 2 2 1 3 2 2 0 0 2 2 2 2 0 0 2 3 0 0 2 2 0 0 2 2 0 0 2 2 2 2 0 0 2 2 0 0 2 3 0 0 2 2 2 2 0 0 2 2 3 2 0 0 2 2 2 2 0 0 2 2 0 0 2 2 0 0 2 2 0 0 3 1 0 0 2 2 0 0 2 2 0 0 2 2 3 2 0 0 2 2 0 0 0 0 3 3 3 4 2 4 1 4 0 5 0 4-2 5-2 4-3 3-3 3-4 2-4 2-5 1z m694-313l-4-1-5-2-3-2-3-4-3-4-2-4-1-4 0-4 1-4 0-4 0-4 0-5 0-4 0 0 0-1 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0 0 0-3 0 0 0-3 0-3 0-3 0-3 0-3-1-3 0-3 0 0 0-3 0 0 0-3-1-3 0-3 0-3-1-2 0-1 0-3 0 0 0-2-1-3 0-3 0 0-1-3 0-3-1-3 0 0 0-3-1-3-1-3 0 0 0-2-1-3 0 0 0-3-1-3 0 0-1-3-1-3 0 0 0-2 0 0-1-3 0 0-1-3 0 0-1-3 0 0-1-3-1-2 0 0 0-3-1-3 0 0-1-3 0 0-1-2 0-1-1-2 0 0-1-3 0 0-1-3-1-2 0 0-1-3-3-5-2-6-2-5-3-5-2-6-3-5-3-5-1-3-2-4-1-4 0-5 1-4 1-5 3-4 3-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 3 1 3 1 0 0 0 3 6 0 0 0 0 2 6 1 0 0 0 2 6 0 0 0 0 3 5 0 1 0 0 3 5 0 1 0 0 2 6 0 0 1 0 2 6 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 1 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 0 1 3 0 0 0 1 1 3 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 1 0 0 3 0 0 0 0 1 3 0 1 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 1 4 0 0 0 0 0 3 0 0 0 0 1 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 1 3 0 0 0 0 0 3 0 0 0 1 0 3 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 3 0 0 0 0 0 3 0 1 0 0 0 3 0 4 0 0 0 0 0 4 0 0 0 1 0 4 0 0 0 0-1 5 0 0 0 0 0 4 0 5-2 4-2 4-3 4-4 2-4 3-4 1-4 1z m-853-18l-4-1-5-2-3-3-4-3-2-4-2-4-1-4 0-4 0-3 0 0 0 0 0-7 0 0 0 0 0-6 0 0 0 0 0-7 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0-1 0-6 0 0 0 0 1-6 0 0 0-1 1-6 1 0 0 0 1-6 0 0 0-1 1-6 0 0 0 0 1-6 0 0 0 0 2-6 0-1 0 0 1-6 0 0 0 0 2-6 0 0 0-1 2-6 0 0 0 0 1-6 0 0 0 0 2-6 0 0 0 0 2-6 0-1 0 0 2-6 0 0 0 0 2-6 0 0 0 0 2-6 1 0 0 0 2-6 0 0 0 0 2-6 0 0 0-1 3-5 0-1 0 0 2-5 0-1 0 0 3-5 0-1 0 0 2-5 0-1 1 0 2-5 0-1 0 0 3-5 0 0 0-1 1-1 2-4 4-4 3-2 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 5 0 4 0 5-1 4-1 4-1 1-3 5-2 6-3 5-2 6-2 5-2 5-3 6-2 6-2 5-1 6-2 5-2 6-2 6-1 5-2 6-1 6-2 5-1 6-1 6-1 6-1 6-1 5-1 6-1 6-1 6 0 6-1 5 0 6-1 6 0 6 0 6-1 6 0 3 0 4-1 5-3 4-2 3-4 3-4 3-4 1-4 1z m694-334l-4-1-4-2-4-3 0 0-5-3-4-4-5-4-5-3-5-3-4-4-5-3-5-3-5-3-5-4-5-3-6-3-5-2-5-3-5-3-5-3-6-2-5-3-5-2-6-2-5-3-6-2-5-2-6-2-5-2-6-2-5-2-6-1-5-2-6-2-6-1-5-1-5-1-4-2-4-2-4-3-2-3-3-4-1-5-1-4 1-5 1-4 2-4 2-4 3-3 4-3 4-1 5-1 4-1 4 1 5 1 0 0 0 0 6 2 0 0 0 0 6 1 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 1 0 5 2 1 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 2 0 0 0 0 6 3 0 0 0 0 6 2 0 0 1 0 5 3 0 0 1 0 5 2 0 0 1 0 5 3 0 0 1 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 6 3 0 0 0 0 5 3 0 0 1 0 5 3 0 0 0 0 6 3 0 1 0 0 5 3 0 0 1 0 5 3 0 0 0 1 5 3 0 0 1 0 5 4 0 0 0 0 5 3 0 0 0 0 6 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 0 0 5 4 0 0 1 0 4 4 1 0 0 0 0 1 3 3 3 4 2 4 1 4 0 5 0 4-2 4-2 4-3 4-4 3-4 2-4 1-4 1z m-541-2l-4-1-4-3-4-2-3-4-2-4-1-4-1-5 0-4 1-5 2-4 3-4 3-2 1-1 0-1 0 0 5-4 0 0 0 0 5-4 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 2-2 1 0 0 0 2-2 0 0 0 0 3-2 0 0 0 0 3-1 0-1 0 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 2-2 0 0 1 0 2-1 0 0 0 0 3-2 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0-1 3-1 0 0 0 0 3-2 0 0 0 0 2-1 1 0 0 0 2-2 1 0 0 0 2-2 0 0 1 0 2-1 0 0 1 0 2-2 0 0 0 0 3-1 0 0 0 0 3-2 0 0 1 0 2-1 0 0 1 0 2-1 0-1 1 0 2-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-2 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 1 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 2 0 0 0 0 0 3-1 0 0 0-1 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 4 0 0-1 0 0 3 0 0 0 0 0 3-1 0 0 0 0 3-1 1 0 0 0 3-1 0 0 0 0 3-1 0 0 0 0 0 0 5 0 4 0 5 1 4 2 4 2 3 4 2 3 2 5 1 4 0 5 0 4-2 4-2 4-3 4-4 2-4 3-3 1 0 0-1 0-3 0-2 1 0 0-3 1 0 0-3 1 0 0-3 0 0 0-3 1-3 1-3 1 0 0-3 1-2 1-3 1-3 1-1 0-1 0-3 1-3 1-3 1 0 0-2 1-3 1-3 1-3 0-3 1 0 0-3 1-3 1-2 1 0 0-3 2-3 1 0 0-3 1 0 0-2 1-3 1 0 0-3 1-3 1-2 2-3 1 0 0-3 1-2 1-3 2-3 1-2 1 0 0-3 2-2 1 0 0-3 1 0 0-3 2 0 0-2 1-2 2-1 0-2 1 0 0-3 2-2 1 0 0-3 2-2 1 0 0-3 2 0 0-2 2 0 0-2 1-3 2 0 0-2 2-2 1-1 0-2 2 0 0-2 2-3 1 0 0-2 2 0 0-2 2 0 0-3 2-4 3-5 4-1 1-4 3-4 1-4 2-5 0z" horiz-adv-x="1000" />
+<glyph glyph-name="data-output" unicode="&#xe84b;" d="m250 676l0-2c0-1 0-1 0-1l0-649 500 0 0 486c0 0 0 0 0 0l0 1 0 1c-1 0-1 0-1 0l-166 162 0 2-2 0-213 0-115 0-3 0z m5-5l323 0 0-163 167 0 0-479-490 0 0 642z m328-4l158-154-158 0 0 154z m-145-104l0-55-115 0 0-84 115 0 0-55 85 97-85 97z" horiz-adv-x="1000" />
+<glyph glyph-name="script-task" unicode="&#xe84c;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m87-91l0 0c-35-21-58-39-72-56-15-17-21-34-22-49 0-30 23-55 47-79 23-24 46-47 49-71 1-12-2-25-14-40-12-15-31-31-62-49l-11-6 232 0 1 0c31 19 51 35 64 51 12 15 16 30 15 45-3 28-28 51-51 75-23 24-45 48-44 74 0 14 5 28 19 44 14 17 37 35 70 55l11 6-232 0z m2-7l205 0c-28-18-48-34-61-49-15-17-21-34-21-49-1-30 23-55 46-79 23-24 47-47 49-71 1-12-2-25-14-40-11-14-31-30-61-48l-205 0c25 16 42 30 53 44 13 15 17 30 16 45-3 28-28 51-51 75-24 24-45 48-45 74 0 14 6 28 20 44 14 16 36 34 69 54z m-30-60c-4 0-4-7 0-7l123 0c5 0 5 7 0 7l-27 0-96 0z m13-69c-5 0-5-7 0-7l111 0c5 0 5 7 0 7l-111 0z m37-69c-5 0-5-7 0-7l124 0c5 0 5 7 0 7l-124 0z m25-69c-5 0-5-7 0-7l124 0c4 0 4 7 0 7l-124 0z" horiz-adv-x="1000" />
+<glyph glyph-name="send-task" unicode="&#xe84d;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m-23-93l235-130 235 130-470 0z m0-75l0-292 470 0 0 292-235-117-235 117z" horiz-adv-x="1000" />
+<glyph glyph-name="data-store" unicode="&#xe84e;" d="m500 666c-78 0-156-7-216-20-30-7-56-15-75-25-18-10-31-21-34-35 0 0 0-1 0-1l0 0 0 0 0-73c0 0 0 0 0 0l0-73c0 0 0 0 0 0l0-324 0 0c3-14 16-26 34-36 19-10 45-18 75-25 60-13 138-19 216-19 78 0 156 6 216 19 30 7 56 15 75 25 19 10 31 22 34 36l0 0 0 324c0 0 0 0 0 0l0 73c0 0 0 0 0 0l0 73c0 0 0 0 0 0l0 0 0 0c0 0 0 1 0 1-3 14-16 25-34 35-19 10-45 18-75 25-60 13-138 20-216 20z m0-5c78 0 156-7 215-20 30-6 55-15 73-24 18-10 29-21 32-32-3-12-14-23-32-32-18-10-43-18-73-24-59-13-137-20-215-20-78 0-156 7-215 20-30 6-55 14-73 24-18 9-29 20-32 32 3 11 14 22 32 32 18 9 43 18 73 24 39 8 86 14 135 17 26 2 53 3 80 3z m-320-88c6-10 16-18 29-25 19-10 45-18 75-24 60-13 138-20 216-20 78 0 156 7 216 20 30 6 56 14 75 24 13 7 23 15 29 25l0-61c-2-12-13-23-32-32-18-10-43-18-73-24-59-13-137-20-215-20-78 0-156 7-215 20-30 6-55 14-73 24-18 9-29 20-32 32z m0-73c6-10 16-18 29-25 19-10 45-18 75-24 60-13 138-20 216-20 78 0 156 7 216 20 30 6 56 14 75 24 13 7 23 15 29 25l0-61c-2-12-13-23-32-32-18-10-43-18-73-25-59-12-137-19-215-19-78 0-156 7-215 19-30 7-55 15-73 25-18 9-29 20-32 32z m0-73c6-10 16-18 29-25 19-10 45-18 75-24 60-14 138-20 216-20 78 0 156 6 216 20 30 6 56 14 75 24 13 7 23 15 29 25l0-311c-2-12-13-23-32-33-18-9-43-17-73-24-59-13-137-19-215-19-78 0-156 6-215 19-30 7-55 15-73 24-18 10-29 21-32 33z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-escalation" unicode="&#xe84f;" d="m500 550c-47-131-77-268-124-400 43 43 81 91 124 135 42-45 83-90 125-135-43 133-83 267-125 400z m1-83c23-73 45-146 68-219-22 24-45 49-68 74-19-17-69-82-66-68 24 70 41 143 66 213z m3 333c-43-1-87-4-127-17-24-13-8-53 18-45 64 16 132 17 196 4 27-2 35 39 9 47-31 8-64 11-96 11z m250-79c-26 3-35-36-12-47 53-38 91-93 122-149 18-21 53 4 40 27-34 65-80 124-139 166-3 2-7 3-11 3z m-521-11c-21-3-34-22-49-35-36-35-64-77-88-121-9-15-20-37-1-49 17-13 36 3 41 21 22 41 49 81 82 115 13 15 37 23 38 45 0 12-10 23-23 24z m695-313c-22 1-29-24-25-41 4-68-13-136-46-195-9-25 28-44 43-22 41 72 59 158 50 241-3 10-13 16-22 17z m-853-19c-22 1-30-22-26-40 3-68 21-136 52-196 15-22 52-3 43 22-30 60-46 127-47 194-2 11-12 19-22 20z m694-334c-22-3-36-24-55-33-42-28-91-46-140-59-25-12-9-52 17-45 72 16 139 49 195 97 14 15 2 40-17 40z m-542-1c-24 0-31-35-11-46 47-40 104-67 163-83 17-5 42-16 53 5 10 18-6 37-24 38-56 14-111 36-156 73-7 6-14 14-25 13z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-message" unicode="&#xe850;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m-167-155c57-46 114-92 171-138 56 46 113 92 170 138-114 0-227 0-341 0z m-38-32c0-93 0-187 0-280 137 0 273 0 410 0 0 91 0 183 0 274-67-54-134-109-201-163-70 56-139 113-209 169z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-multiple" unicode="&#xe851;" d="m715 418c-71 52-143 104-215 156-72-52-143-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253z m-28-9c-24-74-48-147-72-220-77 0-153 0-230 0-24 73-48 146-72 220 63 45 125 90 187 135 62-45 124-90 187-135z m-187 393c-41-1-83-5-121-18-25-13-8-53 18-44 64 17 131 17 196 3 26-3 34 38 9 47-33 8-68 12-102 12z m255-83c-26 3-36-36-13-47 52-38 93-90 121-147 15-22 52-3 43 22-32 67-82 127-143 170-2 1-5 2-8 2z m-519-10c-22-2-35-23-51-36-42-40-76-89-98-142-8-26 30-42 44-19 27 61 69 115 122 157 13 14 2 40-17 40z m264 0c-20-2-48 4-57-18-8-21 15-38 34-32 51 4 103-5 149-25 26-8 42 31 19 44-45 21-95 31-145 31z m-155-39c-23-4-43-21-62-34-34-27-66-58-86-96-10-26 30-44 43-21 30 47 74 83 121 110 16 14 5 41-16 41z m393-59c-25 2-35-33-14-46 37-38 62-87 77-137 14-24 53-6 44 20-17 60-49 115-94 158-4 3-8 4-13 5z m-564-171c-23 2-28-24-30-41-7-55-2-112 16-163 12-24 51-11 46 15-17 53-20 110-10 164 1 13-10 24-22 25z m754-46c-21 1-29-22-25-39 1-68-16-135-47-195-9-25 29-43 43-21 39 72 57 155 52 237-3 10-13 18-23 18z m-853-16c-22 2-30-22-26-39 1-69 18-137 51-197 15-22 52-2 42 23-30 59-46 126-45 193-2 11-11 19-22 20z m756-57c-22 2-27-22-28-39-10-48-34-91-63-130-12-25 26-47 42-24 38 49 65 108 73 170-1 12-11 23-24 23z m-590-160c-22-1-30-32-13-45 40-46 90-82 147-102 26-6 40 33 17 45-52 20-98 53-134 96-4 4-10 6-17 6z m426-77c-23-5-43-21-66-27-34-13-71-15-106-19-25-9-16-49 10-47 62 1 124 18 177 50 17 14 7 44-15 43z m-440-39c-23-1-31-35-11-46 56-45 123-78 194-91 26-2 35 39 9 47-65 14-127 44-179 87-4 2-8 3-13 3z m543-3c-22-2-36-24-55-32-43-29-92-45-141-57-24-12-10-52 17-46 71 15 140 47 196 95 14 15 2 40-17 40z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-signal" unicode="&#xe852;" d="m500 562c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z m0-51c50-90 100-180 151-270-101 0-201 0-302 0 51 90 101 180 151 270z m0 291c-41-1-83-5-121-18-25-13-8-53 18-44 64 17 131 17 196 3 26-3 34 38 9 47-33 8-68 12-102 12z m255-83c-26 3-36-36-13-47 52-38 93-90 121-147 15-22 52-3 43 22-32 67-82 127-143 170-2 1-5 2-8 2z m-519-10c-22-2-35-23-51-36-42-40-76-89-98-142-8-26 30-42 44-19 27 61 69 115 122 157 13 14 2 40-17 40z m264 0c-20-2-48 4-57-18-8-21 15-38 34-32 51 4 103-5 149-25 26-8 42 31 19 44-45 21-95 31-145 31z m-155-39c-23-4-43-21-62-34-34-27-66-58-86-96-10-26 30-44 43-21 30 47 74 83 121 110 16 14 5 41-16 41z m393-59c-25 2-35-33-14-46 37-38 62-87 77-137 14-24 53-6 44 20-17 60-49 115-94 158-4 3-8 4-13 5z m-564-171c-23 2-28-24-30-41-7-55-2-112 16-163 12-24 51-11 46 15-17 53-20 110-10 164 1 13-10 24-22 25z m754-46c-21 1-29-22-25-39 1-68-16-135-47-195-9-25 29-43 43-21 39 72 57 155 52 237-3 10-13 18-23 18z m-853-16c-22 2-30-22-26-39 1-69 18-137 51-197 15-22 52-2 42 23-30 59-46 126-45 193-2 11-11 19-22 20z m756-57c-22 2-27-22-28-39-10-48-34-91-63-130-12-25 26-47 42-24 38 49 65 108 73 170-1 12-11 23-24 23z m-590-160c-22-1-30-32-13-45 40-46 90-82 147-102 26-6 40 33 17 45-52 20-98 53-134 96-4 4-10 6-17 6z m426-77c-23-5-43-21-66-27-34-13-71-15-106-19-25-9-16-49 10-47 62 1 124 18 177 50 17 14 7 44-15 43z m-440-39c-23-1-31-35-11-46 56-45 123-78 194-91 26-2 35 39 9 47-65 14-127 44-179 87-4 2-8 3-13 3z m543-3c-22-2-36-24-55-32-43-29-92-45-141-57-24-12-10-52 17-46 71 15 140 47 196 95 14 15 2 40-17 40z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-multiple" unicode="&#xe853;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-87c-72-52-144-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253-71 52-143 104-215 156z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-message" unicode="&#xe854;" d="m295 506c0-104 0-208 0-312 137 0 273 0 410 0 0 104 0 208 0 312-137 0-273 0-410 0z m91-49c76 0 152 0 228 0-40-24-81-79-121-85-36 29-71 57-107 85z m270-28c0-62 0-124 0-186-104 0-208 0-312 0 0 62 0 124 0 186 52-42 104-83 156-125 52 42 104 83 156 125z m-152 371c-43-1-87-4-127-17-24-13-8-53 18-45 64 16 132 17 196 4 27-2 35 39 9 47-31 8-64 11-96 11z m250-79c-26 3-35-36-12-47 53-38 91-93 122-149 18-21 53 4 40 27-34 65-80 124-139 166-3 2-7 3-11 3z m-521-11c-21-3-34-22-49-35-36-35-64-77-88-121-9-15-20-37-1-49 17-13 36 3 41 21 22 41 49 81 82 115 13 15 37 23 38 45 0 12-10 23-23 24z m695-313c-22 1-29-24-25-41 4-68-13-136-46-195-9-25 28-44 43-22 41 72 59 158 50 241-3 10-13 16-22 17z m-853-19c-22 1-30-22-26-40 3-68 21-136 52-196 15-22 52-3 43 22-30 60-46 127-47 194-2 11-12 19-22 20z m694-334c-22-3-36-24-55-33-42-28-91-46-140-59-25-12-9-52 17-45 72 16 139 49 195 97 14 15 2 40-17 40z m-542-1c-24 0-31-35-11-46 47-40 104-67 163-83 17-5 42-16 53 5 10 18-6 37-24 38-56 14-111 36-156 73-7 6-14 14-25 13z" horiz-adv-x="1000" />
+<glyph glyph-name="ad-hoc-marker" unicode="&#xe855;" d="m326 534c-77 0-151-84-201-205l0-163c51 86 103 188 172 203 76 16 146-64 214-122 56-51 117-86 179-77 70 4 136 72 185 171l0 174c-24-55-57-87-88-121-47-60-106-81-159-46-95 66-185 177-288 185-5 0-9 1-14 1z" horiz-adv-x="1000" />
+<glyph glyph-name="service-task" unicode="&#xe856;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z m44-53l0-5 0-28c-6-2-12-4-18-6l0 0 0 0c-6-3-11-5-17-9l-23 24-38-38 23-24c-6-10-11-22-14-34l-33 0 0-54 34 0c1-6 3-12 5-17 3-6 6-12 9-17l-24-24 38-38 20 20 0-5 23 0c4-1 8-3 12-4 1-4 2-8 4-11l0-24 4 0-19-19 38-38 25 24c10-6 22-11 34-14l0-34 5 0c15 0 44 0 44 0l-5 5 10 0 0 5 0 25c6 1 12 3 18 5l0 0 0 0c6 3 11 6 16 9l25-24 38 38-25 24c7 11 12 22 14 34l33 1 0 53-33 0c-1 6-3 12-6 18-2 6-5 11-8 16l23 23-39 38-19-19 0 5-5 0-18 0c-3 2-7 3-11 4-1 4-2 8-4 12l0 22-6 0 20 19-39 38-23-23c-11 6-22 11-34 14l0 33-54 0z m10-10l34 0 0-31 4-1c13-3 26-8 38-15l4-3 21 22 24-24-19-19-34 0 0-15c-21 22-54 31-84 18-38-16-56-59-40-97l0 0 0 0c5-10 11-19 19-26l-15 0 0-35-20-20-24 24 23 23-2 3c-4 6-8 12-10 18l0 0 0 0c-3 7-5 14-6 20l-1 4-32 0 0 34 32 0 0 4c3 14 8 27 16 38l2 4-22 22 24 24 22-22 4 2c5 4 11 7 18 10l0 0c6 2 13 4 20 6l4 1 0 31z m17-72c22 0 43-11 55-30l0-2c-6-2-12-4-18-6l0 0 0 0c-6-3-11-5-16-9l-24 24-38-38 24-24c-7-10-12-22-14-34l-3 0c-11 7-20 17-25 30l0 0c-14 32 1 70 34 84 8 3 16 5 25 5z m65-9l34 0 0-31 4-1c2 0 3-1 5-1l0 0c5-1 9-3 14-4l0 0c4-2 7-4 11-6 0 0 0 0 0 0 1 0 2 0 2-1 0 0 0 0 0 0 1 0 2-1 3-1 0 0 0 0 0 0 0-1 1-1 2-1l0-1c0 0 1 0 1 0l4-3 0 0 2-1 0 4 19 19 25-24-22-22 2-3c4-6 7-12 10-18l0 0 0 0c3-7 5-13 6-20l1-4 31 0 0-34-31 0-1-4c-2-13-8-26-15-38l-2-3 23-23-24-24-23 23-4-3c-5-3-12-7-18-9-7-3-13-5-20-6l-4-1 0-33c-5 0-21 0-34 0l0 32-4 1c-14 3-27 8-38 16l-4 2-23-23-24 24 19 19 7 0-3 4 0 0-2 3 0 1c-4 4-7 10-9 15 0 1-1 2-1 2l0 0 0 0 0 0c0 1 0 1-1 1l0 0c-1 5-3 9-4 14l0 1c-1 1-1 3-1 4l-1 4 0 0-4 0-14 0 0 0-14 0 0 34 32 0 0 0 6 0-6 3 0 1c3 14 8 27 16 38l2 4-22 22 24 24 22-22 4 2c5 4 11 7 18 10l0 0c6 2 13 4 20 6l1 0 3-5 0 6 0 31z m18-62c-1 0-2 0-2 0l0 0c0 0 0 0 0 0l0 0c-1 0-1 0-1 0 0 0 0 0 0 0l0 0c-1 0-2 0-3 0l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c-8-1-16-3-23-6l0 0c-26-11-43-34-46-60l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-1 0-1 0-2l0 0c0 0 0 0 0 0l0 0c0-2 0-4 0-6l0 0 0 0c0 0 0 0 0 0l0 0c0-1 0-3 0-5l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-2 0-4 0-5l0 0c0 0 0 0 0 0 0 0 0-1 0-1 0 0 0 0 0 0l0 0c1 0 1-1 1-2l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-1 0-2 0-3l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c1-1 1-2 1-3l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 0 0-1 1-2l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-2 1-4 1-5 0 0 0 0 0 0 1-1 1-1 1-1 0 0 0 0 0-1 0 0 0-1 1-1 0 0 0 0 0 0l0 0c0-1 0-2 1-2 0 0 0 0 0 0 0-1 0-1 0-1 0 0 0 0 0 0l0 0c1-2 1-3 2-5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c19-32 59-47 94-32 38 16 56 60 40 97-6 17-18 29-33 37l0 0c0 0 0 0 0 0l0 0c-1 0-1 1-2 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 1-2 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 1-2 1l0 0c0 0-1 0-1 0l0 0c0 0-1 1-2 1l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c-1 0-1 1-2 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-2 0l0 1c0 0 0 0-1 0l0 0c-1 0-3 0-4 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-2 0l0 0c0 0 0 0 0 0 0 0-1 0-1 0 0 0 0 0 0 0l0 0c-1 1-1 1-2 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-2 0l0 0c0 0-1 0-1 0l0 0c0 0-1 0-2 1l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-2 0l0 0c-1 0-1 0-1 0l0 0c0 0-1 0-2 0l0 0c0 0 0 0 0 0l0 0c-1 0-2 0-2 0z m0-10c0 0 1 0 1 0l0 0c1 0 1 0 1 0l0 0c1 0 1 0 2 0l0 0c0 0 0 0 0 0l0 0c1 0 1 0 2 0l0 0c0 0 0 0 0 0l0 0c1 0 1-1 2-1l0 0c0 0 0 0 0 0l0 0c1 0 2 0 2 0l0 0c0 0 0 0 0 0l0 0c1 0 2 0 2 0l0 0c0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0l0 0c0-1 1-1 1-1l0 0c0 0 1 0 1 0l0 0c1 0 2 0 3-1l0 0c1 0 1 0 1 0l0 0c0 0 1 0 1 0l0 0c1-1 1-1 1-1l0 0c0 0 1 0 2 0l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0-1 1-1 1-1l0 0c1 0 1 0 1 0l0 0c0 0 1-1 1-1l0 0c1 0 1 0 1 0l0 0c0 0 1-1 1-1l0 0c0 0 1 0 1 0l0 0c0 0 1-1 1-1l0 0c0 0 0 0 1 0l0 0c12-7 22-17 28-31 14-33-2-71-34-85l0 0c-31-12-66 0-82 28l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c-1 2-1 3-2 4 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0-1 0-1 1-1 2l0 0c0 0 0 0-1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0-1 2-1 3-2 4l0 0c0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0l0 0c0 0 0 1 0 2l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 1-1 1-1 2l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 1 0 2 0 2l0 0c0 0 0 0 0 0 0 1 0 1 0 1l0 0c0 0-1 1-1 2l0 0c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 2 0 3 0 4l0 0c0 0 0 0 0 0 0 1 0 1 0 1l0 0c0 1 0 3 0 4l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c0 2 0 3 0 5l0 0c0 0 0 0 0 0l0 0c0 1 0 1 0 2l0 0c0 0 0 0 0 0 0 0 0 0 0 0l0 0c3 22 17 43 39 52 7 3 14 4 20 5l0 0c0 0 0 0 0 0 1 0 1 0 1 0l0 0 0 0c1 0 2 0 2 0l0 0c0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0l0 0c0 0 1 0 2 0z" horiz-adv-x="1000" />
+<glyph glyph-name="task-none" unicode="&#xe857;" d="m215 745c-107 0-195-87-195-194l0-402c0-107 88-194 195-194l570 0c108 0 195 87 195 194l0 402c0 107-87 194-195 194l-570 0z m0-60l570 0c75 0 135-59 135-134l0-402c0-75-60-134-135-134l-570 0c-75 0-135 59-135 134l0 402c0 75 60 134 135 134z" horiz-adv-x="1000" />
+<glyph glyph-name="compensation-marker" unicode="&#xe858;" d="m504 589l-330-239 5-4 325-235 0 233 323-233 0 478-323-233 0 233z m-10-19l0-440-303 220 303 220z m323 0l0-440-304 220 304 220z" horiz-adv-x="1000" />
+<glyph glyph-name="start-event-non-interrupting-multiple" unicode="&#xe859;" d="m715 418c-71 52-143 104-215 156-72-52-143-104-215-156 27-84 55-169 82-253 89 0 177 0 266 0 28 84 55 169 82 253z m-28-9c-24-74-48-147-72-220-77 0-153 0-230 0-24 73-48 146-72 220 63 45 125 90 187 135 62-45 124-90 187-135z m-183 391c-43-1-87-4-127-17-24-13-8-53 18-45 64 16 132 17 196 4 27-2 35 39 9 47-31 8-64 11-96 11z m250-79c-26 3-35-36-12-47 53-38 91-93 122-149 18-21 53 4 40 27-34 65-80 124-139 166-3 2-7 3-11 3z m-521-11c-21-3-34-22-49-35-36-35-64-77-88-121-9-15-20-37-1-49 17-13 36 3 41 21 22 41 49 81 82 115 13 15 37 23 38 45 0 12-10 23-23 24z m695-313c-22 1-29-24-25-41 4-68-13-136-46-195-9-25 28-44 43-22 41 72 59 158 50 241-3 10-13 16-22 17z m-853-19c-22 1-30-22-26-40 3-68 21-136 52-196 15-22 52-3 43 22-30 60-46 127-47 194-2 11-12 19-22 20z m694-334c-22-3-36-24-55-33-42-28-91-46-140-59-25-12-9-52 17-45 72 16 139 49 195 97 14 15 2 40-17 40z m-542-1c-24 0-31-35-11-46 47-40 104-67 163-83 17-5 42-16 53 5 10 18-6 37-24 38-56 14-111 36-156 73-7 6-14 14-25 13z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-throw-signal" unicode="&#xe85a;" d="m499 802c-220 4-425-177-448-396-24-185 78-380 247-461 160-80 368-56 501 66 134 118 190 318 128 486-57 167-217 293-393 303-12 1-23 2-35 2z m-5-49c202 7 391-161 407-362 19-178-92-361-262-420-166-61-368-2-468 145-103 144-99 356 18 490 74 90 188 146 305 147z m8-44c-186 6-358-158-361-344-9-169 116-334 283-367 155-33 328 46 397 190 71 140 39 327-83 430-64 57-150 91-236 91z m-2-48c164 4 314-144 311-308 3-152-119-297-272-312-143-19-295 73-336 213-43 134 14 295 138 364 48 28 103 43 159 43z m0-99c-64-115-128-230-192-345 128 0 256 0 384 0-64 115-128 230-192 345z" horiz-adv-x="1000" />
+<glyph glyph-name="intermediate-event-catch-non-interrupting-condition" unicode="&#xe85b;" d="m349 540l0-12 0-368 50 0 202 0 50 0 0 380-302 0z m24-24l254 0 0-332-26 0-202 0-26 0 0 332z m26-37l0-25 202 0 0 25-202 0z m0-74l0-24 202 0 0 24-202 0z m0-85l0-24 202 0 0 24-202 0z m0-77l0-24 202 0 0 24-202 0z m101 559l0 0-5 0-1 0 0 0-5 0 0 0 0 0-6-1 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 0-5-1 0 0-1 0-5 0 0 0 0 0-5 0-1 0 0-1-5 0 0 0 0 0-5-1-1 0 0 0-5 0 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1-1 0 0 0-5-1 0 0 0 0-5-1 0 0-1 0-5-1 0 0 0 0-5-1 0 0 0 0-6-2 0 0 0 0-5-1 0 0 0 0-5-1-4-2-4-2-4-3-2-4-3-4-1-4 0-5 0-4 1-4 2-5 3-3 3-3 4-3 4-1 5-1 4 0 4 1 5 1 5 1 4 1 5 1 5 1 5 1 5 1 5 1 5 0 4 1 5 1 5 0 5 1 5 0 5 1 5 0 5 0 5 1 5 0 5 0 5 0 5 0 5 0 5 0 5-1 5 0 5 0 5-1 5 0 5-1 5 0 5-1 5-1 4 0 5-1 5-1 5-1 5-1 4-1 5 0 4 0 5 1 4 2 3 3 4 3 2 4 2 4 1 4 0 5-1 4-2 5-2 4-3 3-4 3-4 2-3 1-5 1 0 0 0 0-5 1 0 0-1 0-5 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 1 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 1 0 0-6 0 0 0 0 0-5 0 0 0-1 0-5 1 0 0 0 0-5 0-1 0 0 0-5 0 0 0 0 0-6 1 0 0 0 0-5 0 0 0 0 0-6 0 0 0z m255-83l-5 0-4-1-5-2-3-2-4-4-2-3-2-4-1-5-1-4 1-5 1-4 3-4 3-4 2-2 2-1 4-3 4-3 4-3 3-3 4-4 4-3 4-3 3-3 4-4 4-3 3-4 4-3 3-4 4-3 3-4 4-4 3-3 3-4 3-4 4-4 3-3 3-4 3-4 3-4 3-4 3-4 2-4 3-4 3-5 3-4 2-4 3-4 2-4 3-5 2-4 2-4 3-5 2-4 1-2 2-4 4-3 3-3 4-2 5-1 4-1 5 1 4 1 4 2 4 3 3 3 2 4 2 4 0 5 0 4-1 5-1 3-1 3 0 0 0 0-3 5 0 0 0 0-2 5 0 0-1 0-2 4 0 1 0 0-3 4 0 0 0 1-2 4-1 0 0 0-2 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-3 5 0 0-1 0-3 4 0 0 0 0-3 5 0 0 0 0-3 4 0 0 0 0-4 4 0 1 0 0-3 4 0 0 0 0-3 4-1 0 0 0-3 4 0 1 0 0-4 4 0 0 0 0-3 4 0 0-1 0-3 4 0 0 0 0-4 4 0 0 0 0-4 4 0 0 0 1-4 3 0 0 0 1-3 3-1 0 0 1-3 3-1 0 0 0-3 4-1 0 0 0-4 4 0 0 0 0-4 4 0 0 0 0-4 3 0 1 0 0-4 3 0 0 0 0-4 4 0 0-1 0-4 3 0 0 0 1-4 3 0 0 0 0-4 3 0 0-1 0-4 4 0 0 0 0-4 3 0 0 0 0-2 1-4 3-4 1-4 1z m-519-10l-5 0-4-1-4-2-4-2-1-1 0 0 0 0-4-3 0-1 0 0-4-3 0 0-1 0-4-4 0 0 0 0-4-3 0 0 0-1-4-3 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-4 0 0 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-3 0-1 0 0-4-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0-1 0-3-4 0 0 0 0-4-4 0 0 0-1-3-4 0 0 0 0-4-4 0 0 0 0-3-4 0 0 0-1-4-4 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-4 0 0-1 0-3-5 0 0 0 0-3-4 0 0 0 0-3-5 0 0 0 0-3-5 0 0 0 0-3-4 0 0 0 0-2-5-1 0 0 0-2-5 0 0 0 0-3-4 0-1 0 0-3-4 0 0 0-1-2-4 0 0 0 0-3-5 0 0 0 0-2-5 0 0-1 0-2-5 0 0 0 0-2-5 0 0 0 0-3-5 0 0 0 0-1-3-1-4-1-5 0-4 1-5 2-4 3-4 3-3 4-2 4-2 4-1 5 0 4 0 5 2 3 2 4 3 3 4 2 3 1 3 2 4 2 5 2 4 2 4 3 5 2 4 2 4 3 5 2 4 3 4 3 4 2 4 3 5 3 4 2 4 3 4 3 4 3 4 3 4 3 4 3 3 4 4 3 4 3 4 3 3 4 4 3 4 4 3 3 4 4 3 3 4 4 3 4 4 3 3 4 3 4 3 4 4 4 3 1 1 3 3 3 3 2 5 1 4 0 4-1 5-1 4-2 4-3 4-4 3-4 2-4 2-4 0z m264 0l0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 0-5 0 0-1 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 0 0 0 0 0-4-1 0 0-1 0-1 0-4-1-5-2-3-2-4-3-2-4-2-4-2-4 0-5 1-4 1-5 2-4 3-3 4-3 4-3 4-1 4-1 4 0 1 1 4 0 4 0 4 1 4 0 3 0 4 0 4 0 4 0 4 0 4 0 4 0 3 0 4 0 4-1 4 0 4 0 3-1 4 0 4-1 4 0 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4-1 3-1 4-1 4-1 3-1 4-1 3-2 4-1 4-1 3-1 4-2 3-1 4-1 3-2 0 0 0 0 4-1 5-1 5 0 4 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4 0 5-2 4-2 4-3 3-4 3-3 2 0 0-1 0 0 0-3 2-1 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 2 0 0 0 0-4 1 0 0-1 0-3 1-1 0 0 0-4 2 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0-1 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 1-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 1 0 0 0 0-5 0 0 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 1 0 0 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0 1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0z m-155-39l-4 0-5-1-3-1-2-1 0 0 0 0-4-2 0 0 0 0-3-2-1-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-2 0 0 0 0-4-2 0-1 0 0-3-2 0 0-1 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0 0 0-4-3 0 0 0 0-3-2 0 0-1-1-3-2 0 0 0 0-3-3 0 0-1 0-3-2 0-1 0 0-3-2 0 0-1 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3-1 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0-1 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-3 0 0 0 0-3-4 0 0 0 0-3-3 0 0 0 0-2-3-1 0 0-1-2-3 0 0 0 0-3-3 0 0 0-1-3-3 0 0 0 0-2-3 0 0-1-1-2-3 0 0 0 0-2-3-1-1 0 0-2-3 0 0 0 0-2-4-1 0 0 0-2-3-2-4-1-4-1-5 1-4 1-5 2-4 3-3 3-4 4-2 4-2 4-1 5 0 4 1 5 2 4 2 3 3 2 3 2 3 2 3 2 3 3 3 2 4 2 3 2 3 3 3 2 3 3 2 2 3 3 3 2 3 3 3 2 3 3 3 3 2 3 3 2 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 3 3 2 3 2 3 3 3 2 3 2 3 2 3 2 3 2 4 2 3 2 3 2 3 2 4 2 3 2 2 0 3 3 4 3 2 4 2 4 1 4 1 5-1 4-1 5-3 4-2 3-4 3-4 2-4 2-5 0z m393-59l-5-1-4-1-4-1-4-3-3-3-3-4-1-4-1-5-1-4 1-5 2-4 2-4 2-3 3-2 3-3 2-3 3-3 2-3 3-3 2-3 3-2 2-3 3-3 2-3 2-3 3-4 2-3 2-3 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-4 2-3 1-3 2-4 2-3 1-3 2-4 2-3 1-4 1-3 2-4 1-3 2-4 1-3 1-4 1-4 2-3 1-4 1-3 0-3 2-4 2-4 4-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 4 0 2 0 0 0 0-2 4 0 0 0 1-1 3 0 1 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 0-2 4 0 0 0 0-1 4 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-2 3 0 0 0 1-1 3 0 0-1 1-1 3 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0 0 0-2 4 0 0-1 0-1 4-1 0 0 0-2 3 0 1 0 0-2 3 0 0 0 0-2 4 0 0 0 0-2 4-1 0 0 0-2 3 0 0 0 1-2 3 0 0 0 0-3 4 0 0 0 0-2 3 0 0 0 1-3 3 0 0 0 0-2 3 0 1-1 0-2 3 0 0 0 0-3 3 0 1 0 0-2 3-1 0 0 0-2 3 0 1 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 4 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 0-3 3 0 0 0 1-3 3 0 0 0 0-3 2-3 3-4 3-5 1-4 1z m-564-171l-5 0-4-1-4-2-4-2-3-4-3-3-2-4-1-4-1-4 0 0 0 0 0-4 0 0-1 0 0-4 0-1 0 0-1-4 0 0 0 0-1-4 0 0 0 0 0-5 0 0 0 0-1-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0-1 0 0-4 0 0 0 0 0-5 0 0 0 0 0-4 0 0 0 0-1-4 0-1 0 0 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 0-4 0 0 0 0 1-5 0 0 0 0 0-4 0 0 0 0 0-4 0-1 0 0 0-4 1 0 0 0 0-4 0 0 0-1 0-4 0 0 0 0 1-4 0 0 0 0 0-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 0-4 1-1 0 0 0-4 0 0 0 0 1-4 0 0 0 0 1-4 0-1 0 0 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0-1 1-4 0 0 0 0 1-4 0 0 0 0 1-4 0 0 0 0 2-4 0 0 0 0 1-4 0-1 0 0 1-1 1-4 3-4 3-3 4-3 4-2 4-1 5 0 4 1 5 1 4 2 3 3 3 4 2 4 2 4 0 5 0 4-1 4 0 1-2 4-1 4-1 3-1 4-1 3-1 4 0 4-1 4-1 3-1 4 0 4-1 4-1 3 0 4-1 4 0 4 0 3-1 4 0 4 0 4-1 4 0 4 0 3 0 4 0 4 0 4 0 4 0 4 0 3 1 4 0 4 0 4 1 4 0 3 0 4 1 4 0 4 1 4 1 3 0 4 1 4 0 4 0 5-1 4-2 4-3 4-3 3-4 2-5 2-4 1z m754-46l-5 0-4-1-4-2-4-2-3-4-3-4-2-4 0-4-1-4 1-4 0-5 0-5 0-5 0-5 0-5 0-5-1-5 0-5 0-5-1-5 0-5-1-5 0-5-1-5-1-4 0-5-1-5-1-5-1-5-1-5-1-5-1-4-1-5-1-5-2-5-1-4-2-5-1-5-1-4-2-5-2-5-1-4-2-5-2-4-2-5-2-5-2-4-2-5-2-4-2-4-2-5-2-4-2-5-1-4 0-5 1-4 2-4 2-4 3-4 4-2 4-2 4-2 5 0 4 1 5 1 4 2 3 3 3 3 2 3 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 3 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 2 4 0 1 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 0 2 5 0 0 0 1 1 5 0 0 0 0 2 5 0 0 0 0 1 5 0 0 0 0 2 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 0 2 6 0 0 0 0 1 5 0 0 0 0 1 5 0 1 0 0 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 1 5 0 0 0 1 1 5 0 0 0 0 0 5 0 0 0 1 1 5 0 0 0 0 0 5 1 0 0 1 0 5 0 0 0 0 0 5 0 1 0 0 1 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0 1 6 0 0 0 0 0 5 0 0 0 1 0 5 0 0 0 0 0 6 0 0 0 0 0 5 0 0 0 0-1 6 0 0 0 0 0 4 0 5-2 4-2 4-3 3-4 3-4 2-4 2-4 0z m-853-16l-5 0-4-1-4-1-4-3-4-3-2-4-2-4-1-4-1-4 0-4 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 0-6 0 0 0 0 0-5 0 0 0 0 0-6 0 0 0 0 1-5 0 0 0-1 0-5 0 0 0 0 1-5 0-1 0 0 0-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 0-5 0-1 0 0 1-5 0 0 0 0 1-5 0-1 0 0 1-5 0 0 0 0 1-5 0 0 0-1 1-5 0 0 0 0 1-5 0 0 0 0 2-6 0 0 0 0 1-5 0 0 0 0 1-5 0 0 0-1 2-5 0 0 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0-1 0 0 1-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0-1 2-4 0-1 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 2-5 0 0 0 0 3-5 0 0 0 0 2-5 0 0 0 0 2-5 1 0 0 0 0-1 3-4 3-3 3-3 4-2 5-1 4 0 5 0 4 1 4 3 4 2 3 4 2 4 2 4 0 5 0 4-1 5-1 3-1 1-2 5-2 4-2 4-2 5-2 4-2 5-2 5-2 4-2 5-1 4-2 5-1 5-2 4-1 5-2 5-1 4-1 5-2 5-1 5-1 4-1 5-1 5-1 5-1 5-1 5 0 5-1 4-1 5 0 5-1 5 0 5-1 5 0 5 0 5-1 5 0 5 0 5 0 5 0 4 0 4-1 5-2 4-3 3-4 4-3 2-5 2-4 0z m756-57l-4 0-5-1-4-2-4-3-3-3-2-4-2-4-1-3 0 0 0 0 0 0 0 0-1-4 0-4-1-4-1-3 0-4-1-4-1-4-1-3-1-4-1-3-1-4-1-4-2-3-1-4-1-3-1-4-2-4-1-3-2-4-1-3-1-4-2-3-2-3-1-4-2-3-2-4-1-3-2-3-2-4-2-3-2-3-2-3-2-4-2-3-2-3-2-3-2-3-2-3-3-3-2-3-2-4-2-1-2-4-2-4-1-5 0-4 1-5 2-4 2-4 3-3 4-3 4-2 4-1 5-1 4 1 4 1 5 2 3 3 3 3 1 1 0 1 0 0 3 3 0 0 0 0 2 3 1 1 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 0 0 0 3 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 0 2 4 0 0 0 0 2 4 0 0 0 0 2 3 0 1 0 0 2 3 0 0 1 1 2 3 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 1 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 2 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 1 0 0 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 1 4 0 0 0 0 1 4 0 0 0 0 1 4 0 0 0 1 0 4 0 0 0 0 0 0 1 5-1 4-1 4-2 4-3 4-4 3-4 2-4 2-5 0z m-590-160l-4-1-4-2-4-2-4-3-3-3-2-4-1-5-1-4 1-5 1-4 2-4 2-3 1-2 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0-1 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 0 0 3-3 0 0 1 0 3-3 0 0 0 0 3-3 0 0 0 0 3-2 1-1 0 0 3-2 0 0 0 0 3-3 1 0 0 0 3-3 0 0 0 0 3-2 1 0 0-1 3-2 0 0 0 0 4-2 0-1 0 0 3-2 0 0 0 0 4-2 0-1 0 0 3-2 1 0 0 0 3-2 0 0 0 0 4-3 0 0 0 0 4-2 0 0 0 0 3-2 1 0 0 0 3-2 0 0 1 0 3-2 0 0 0-1 4-1 0-1 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-2 0 0 0 0 4-1 0-1 0 0 4-1 0 0 0 0 4-2 4-1 4 0 5 0 4 1 4 2 4 3 3 4 2 3 2 5 1 4 0 5-1 4-2 4-2 4-4 3-3 3-4 2-3 1-4 2-3 1-4 2-3 1-3 2-4 1-3 2-4 2-3 2-3 1-4 2-3 2-3 2-3 2-4 2-3 2-3 2-3 2-3 2-3 3-3 2-4 2-3 2-2 3-3 2-3 3-3 2-3 3-3 2-3 3-3 2-2 3-3 3-3 3-3 2-2 3-3 3-2 3-3 3-2 3-1 1-4 3-3 3-5 1-4 1-5 1z m426-77l-5 0-4-1-4-2-1-1-4-2-3-1-3-2-4-2-3-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-2-3-1-4-1-4-1-3-1-4-2-3-1-4-1-4-1-3-1-4-1-4 0-3-1-4-1-4-1-4 0-3-1-4-1-4 0-4-1-3 0-4 0-4-1-4 0-4 0-4-1-3 0-4 0-4 0-5 0-4-2-4-2-4-3-3-3-2-4-1-4-1-5 0-5 1-4 2-4 2-4 4-3 3-3 4-2 5-1 4 0 4 0 0 0 0 0 4 0 0 0 1 0 4 1 0 0 0 0 4 0 0 0 0 0 5 0 0 0 0 0 4 0 0 0 0 0 4 1 1 0 0 0 4 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 0 0 0 0 0 4 1 0 0 0 0 4 1 0 0 1 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 1 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 1 0 0 0 0 4 2 0 0 1 0 3 1 1 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 0 0 4 2 0 0 0 0 4 1 0 0 1 1 3 1 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 2 0 0 1 0 3 1 0 0 0 1 4 1 0 0 0 0 4 2 0 0 0 0 4 2 0 0 0 1 4 1 0 1 0 0 4 2 0 0 0 0 2 1 3 2 4 4 2 3 2 5 1 4 0 5-1 4-1 4-3 4-3 4-3 3-4 2-5 1-4 0z m-440-39l-4-1-5-1-4-3-3-3-3-3-2-4-1-5-1-4 0-5 1-4 2-4 3-4 3-2 1-1 0 0 0 0 4-4 0 0 0 0 4-3 0 0 1 0 4-4 0 0 0 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0-1 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-3 0 0 0 0 4-3 0 0 1 0 4-3 0 0 0 0 5-2 0 0 0-1 5-2 0 0 0 0 4-3 1 0 0 0 4-2 0 0 0-1 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-3 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 4-2 1 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 0 0 5-2 0 0 1 0 5-1 0 0 0 0 5-2 0 0 0 0 5-1 0 0 0 0 5-2 1 0 0 0 5-1 0 0 0 0 5-1 0 0 0 0 6-2 0 0 0 0 4-1 5 0 4 0 5 1 4 2 4 3 3 3 2 4 2 4 1 5 0 4-1 5-1 4-3 4-3 3-4 3-4 2-3 1-5 1-4 1-5 1-5 1-5 2-4 1-5 2-5 1-4 2-5 1-5 2-4 1-5 2-5 2-4 2-5 2-4 2-5 2-4 2-5 2-4 2-4 2-5 3-4 2-4 2-5 3-4 2-4 3-4 3-4 2-4 3-5 3-4 2-4 3-4 3-4 3-3 3-4 3-4 3-1 1-4 3-4 1-4 1-5 1z m543-3l-5 0-4-1-5-2-3-2-1-2-4-3-4-3-4-3-4-3-4-3-4-2-4-3-5-3-4-2-4-3-4-3-4-2-5-3-4-2-4-2-5-3-4-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-2-4-2-5-1-5-2-4-1-5-2-5-1-5-2-4-1-5-2-5-1-5-1-4-1-5-1-3-1-5-1-4-2-3-3-3-3-2-4-2-5-1-4 0-5 1-4 2-4 3-4 3-3 4-3 4-2 4-1 5 0 4 0 3 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 1 0 0 1 0 5 2 0 0 0 0 5 1 0 0 0 0 5 2 0 0 1 0 5 1 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 1 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 0 0 0 5 2 0 0 0 0 5 3 0 0 0 0 5 2 0 1 0 0 4 2 1 0 0 0 4 3 0 0 1 0 4 2 0 1 0 0 5 2 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 5 3 0 0 0 1 4 3 0 0 0 0 5 3 0 0 0 0 4 3 0 0 0 0 4 4 1 0 0 0 4 3 0 0 0 0 2 2 3 3 3 4 2 4 1 4 0 5-1 4-1 5-2 4-3 3-4 3-4 2-4 2-4 0z" horiz-adv-x="1000" />
+<glyph glyph-name="participant" unicode="&#xe85c;" d="m47 654l0-625 906 0 0 625z m857-48l0-533-670 0 0 533 670 0z m-810 0l94 0 0-533-94 0z" horiz-adv-x="1000" />
+<glyph glyph-name="space-tool" unicode="&#xe85f;" d="m366 800l0-900 38 0 0 900-38 0z m233 0l0-900 38 0 0 900-38 0z m-394-287l-164-163 164-163 0 111 93 0 0 105-93 0 0 110z m595 0l0-108-94-1 0-106 94 0 0-111 163 163-163 163z" horiz-adv-x="1000" />
+<glyph glyph-name="connection-multi" unicode="&#xe860;" d="m916 798l-410-109 64-95-486-327 25-38 486 328 62-92 259 333 0 0z m0-328l-411-109 151-224 260 333 0 0z m-409-245l-63-43 25-37 63 42-25 38z m-126-85l-62-42 25-38 62 43-25 37z m-133-90l-63-43 25-37 63 43-25 37z m-126-85l-38-26 25-37 38 26-25 37z" horiz-adv-x="1000" />
+<glyph glyph-name="lasso-tool" unicode="&#xe862;" d="m303 798l0-218 103 0 0 218-103 0z m-248-246l0-103 218 0 0 103-218 0z m379 0l0-103 219 0 0 103-219 0z m349-30l0-40 123 0 0-117 40 0 0 157-163 0z m-480-104l0-218 103 0 0 218-103 0z m603-159l0-77 40 0 0 77-40 0z m0-190l0-116-119 0 0-40 159 0 0 156-40 0z m-570-1l0-157 159 0 0 40-119 0 0 117-40 0z m264-117l0-40 82 0 0 40-82 0z" horiz-adv-x="1000" />
+</font>
+</defs>
+</svg>
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.ttf b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.ttf
new file mode 100644 (file)
index 0000000..f940656
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.ttf differ
diff --git a/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.woff b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.woff
new file mode 100644 (file)
index 0000000..e438756
Binary files /dev/null and b/src/main/resources/META-INF/resources/designer/vendor/bpmn-font/font/bpmn.woff differ
diff --git a/src/main/resources/META-INF/resources/icd/css/print.css b/src/main/resources/META-INF/resources/icd/css/print.css
new file mode 100644 (file)
index 0000000..32bf0c8
--- /dev/null
@@ -0,0 +1,1361 @@
+/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
+.swagger-section pre code {
+  display: block;
+  padding: 0.5em;
+  background: #F0F0F0;
+}
+.swagger-section pre code,
+.swagger-section pre .subst,
+.swagger-section pre .tag .title,
+.swagger-section pre .lisp .title,
+.swagger-section pre .clojure .built_in,
+.swagger-section pre .nginx .title {
+  color: black;
+}
+.swagger-section pre .string,
+.swagger-section pre .title,
+.swagger-section pre .constant,
+.swagger-section pre .parent,
+.swagger-section pre .tag .value,
+.swagger-section pre .rules .value,
+.swagger-section pre .rules .value .number,
+.swagger-section pre .preprocessor,
+.swagger-section pre .ruby .symbol,
+.swagger-section pre .ruby .symbol .string,
+.swagger-section pre .aggregate,
+.swagger-section pre .template_tag,
+.swagger-section pre .django .variable,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .addition,
+.swagger-section pre .flow,
+.swagger-section pre .stream,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .apache .cbracket,
+.swagger-section pre .tex .command,
+.swagger-section pre .tex .special,
+.swagger-section pre .erlang_repl .function_or_atom,
+.swagger-section pre .markdown .header {
+  color: #800;
+}
+.swagger-section pre .comment,
+.swagger-section pre .annotation,
+.swagger-section pre .template_comment,
+.swagger-section pre .diff .header,
+.swagger-section pre .chunk,
+.swagger-section pre .markdown .blockquote {
+  color: #888;
+}
+.swagger-section pre .number,
+.swagger-section pre .date,
+.swagger-section pre .regexp,
+.swagger-section pre .literal,
+.swagger-section pre .smalltalk .symbol,
+.swagger-section pre .smalltalk .char,
+.swagger-section pre .go .constant,
+.swagger-section pre .change,
+.swagger-section pre .markdown .bullet,
+.swagger-section pre .markdown .link_url {
+  color: #080;
+}
+.swagger-section pre .label,
+.swagger-section pre .javadoc,
+.swagger-section pre .ruby .string,
+.swagger-section pre .decorator,
+.swagger-section pre .filter .argument,
+.swagger-section pre .localvars,
+.swagger-section pre .array,
+.swagger-section pre .attr_selector,
+.swagger-section pre .important,
+.swagger-section pre .pseudo,
+.swagger-section pre .pi,
+.swagger-section pre .doctype,
+.swagger-section pre .deletion,
+.swagger-section pre .envvar,
+.swagger-section pre .shebang,
+.swagger-section pre .apache .sqbracket,
+.swagger-section pre .nginx .built_in,
+.swagger-section pre .tex .formula,
+.swagger-section pre .erlang_repl .reserved,
+.swagger-section pre .prompt,
+.swagger-section pre .markdown .link_label,
+.swagger-section pre .vhdl .attribute,
+.swagger-section pre .clojure .attribute,
+.swagger-section pre .coffeescript .property {
+  color: #88F;
+}
+.swagger-section pre .keyword,
+.swagger-section pre .id,
+.swagger-section pre .phpdoc,
+.swagger-section pre .title,
+.swagger-section pre .built_in,
+.swagger-section pre .aggregate,
+.swagger-section pre .css .tag,
+.swagger-section pre .javadoctag,
+.swagger-section pre .phpdoc,
+.swagger-section pre .yardoctag,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .winutils,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .go .typename,
+.swagger-section pre .tex .command,
+.swagger-section pre .markdown .strong,
+.swagger-section pre .request,
+.swagger-section pre .status {
+  font-weight: bold;
+}
+.swagger-section pre .markdown .emphasis {
+  font-style: italic;
+}
+.swagger-section pre .nginx .built_in {
+  font-weight: normal;
+}
+.swagger-section pre .coffeescript .javascript,
+.swagger-section pre .javascript .xml,
+.swagger-section pre .tex .formula,
+.swagger-section pre .xml .javascript,
+.swagger-section pre .xml .vbscript,
+.swagger-section pre .xml .css,
+.swagger-section pre .xml .cdata {
+  opacity: 0.5;
+}
+.swagger-section .hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 0.5em;
+  background: #F0F0F0;
+}
+.swagger-section .hljs,
+.swagger-section .hljs-subst {
+  color: #444;
+}
+.swagger-section .hljs-keyword,
+.swagger-section .hljs-attribute,
+.swagger-section .hljs-selector-tag,
+.swagger-section .hljs-meta-keyword,
+.swagger-section .hljs-doctag,
+.swagger-section .hljs-name {
+  font-weight: bold;
+}
+.swagger-section .hljs-built_in,
+.swagger-section .hljs-literal,
+.swagger-section .hljs-bullet,
+.swagger-section .hljs-code,
+.swagger-section .hljs-addition {
+  color: #1F811F;
+}
+.swagger-section .hljs-regexp,
+.swagger-section .hljs-symbol,
+.swagger-section .hljs-variable,
+.swagger-section .hljs-template-variable,
+.swagger-section .hljs-link,
+.swagger-section .hljs-selector-attr,
+.swagger-section .hljs-selector-pseudo {
+  color: #BC6060;
+}
+.swagger-section .hljs-type,
+.swagger-section .hljs-string,
+.swagger-section .hljs-number,
+.swagger-section .hljs-selector-id,
+.swagger-section .hljs-selector-class,
+.swagger-section .hljs-quote,
+.swagger-section .hljs-template-tag,
+.swagger-section .hljs-deletion {
+  color: #880000;
+}
+.swagger-section .hljs-title,
+.swagger-section .hljs-section {
+  color: #880000;
+  font-weight: bold;
+}
+.swagger-section .hljs-comment {
+  color: #888888;
+}
+.swagger-section .hljs-meta {
+  color: #2B6EA1;
+}
+.swagger-section .hljs-emphasis {
+  font-style: italic;
+}
+.swagger-section .hljs-strong {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap {
+  line-height: 1;
+  font-family: "Droid Sans", sans-serif;
+  min-width: 760px;
+  max-width: 960px;
+  margin-left: auto;
+  margin-right: auto;
+  /* JSONEditor specific styling */
+}
+.swagger-section .swagger-ui-wrap b,
+.swagger-section .swagger-ui-wrap strong {
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap q,
+.swagger-section .swagger-ui-wrap blockquote {
+  quotes: none;
+}
+.swagger-section .swagger-ui-wrap p {
+  line-height: 1.4em;
+  padding: 0 0 10px;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap q:before,
+.swagger-section .swagger-ui-wrap q:after,
+.swagger-section .swagger-ui-wrap blockquote:before,
+.swagger-section .swagger-ui-wrap blockquote:after {
+  content: none;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu h1,
+.swagger-section .swagger-ui-wrap .heading_with_menu h2,
+.swagger-section .swagger-ui-wrap .heading_with_menu h3,
+.swagger-section .swagger-ui-wrap .heading_with_menu h4,
+.swagger-section .swagger-ui-wrap .heading_with_menu h5,
+.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
+  display: block;
+  clear: none;
+  float: left;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -ms-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 60%;
+}
+.swagger-section .swagger-ui-wrap table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+.swagger-section .swagger-ui-wrap table thead tr th {
+  padding: 5px;
+  font-size: 0.9em;
+  color: #666666;
+  border-bottom: 1px solid #999999;
+}
+.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
+  border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap table tbody tr.offset {
+  background-color: #f0f0f0;
+}
+.swagger-section .swagger-ui-wrap table tbody tr td {
+  padding: 6px;
+  font-size: 0.9em;
+  border-bottom: 1px solid #cccccc;
+  vertical-align: top;
+  line-height: 1.3em;
+}
+.swagger-section .swagger-ui-wrap ol {
+  margin: 0px 0 10px;
+  padding: 0 0 0 18px;
+  list-style-type: decimal;
+}
+.swagger-section .swagger-ui-wrap ol li {
+  padding: 5px 0px;
+  font-size: 0.9em;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap ol,
+.swagger-section .swagger-ui-wrap ul {
+  list-style: none;
+}
+.swagger-section .swagger-ui-wrap h1 a,
+.swagger-section .swagger-ui-wrap h2 a,
+.swagger-section .swagger-ui-wrap h3 a,
+.swagger-section .swagger-ui-wrap h4 a,
+.swagger-section .swagger-ui-wrap h5 a,
+.swagger-section .swagger-ui-wrap h6 a {
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap h1 a:hover,
+.swagger-section .swagger-ui-wrap h2 a:hover,
+.swagger-section .swagger-ui-wrap h3 a:hover,
+.swagger-section .swagger-ui-wrap h4 a:hover,
+.swagger-section .swagger-ui-wrap h5 a:hover,
+.swagger-section .swagger-ui-wrap h6 a:hover {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap h1 span.divider,
+.swagger-section .swagger-ui-wrap h2 span.divider,
+.swagger-section .swagger-ui-wrap h3 span.divider,
+.swagger-section .swagger-ui-wrap h4 span.divider,
+.swagger-section .swagger-ui-wrap h5 span.divider,
+.swagger-section .swagger-ui-wrap h6 span.divider {
+  color: #aaaaaa;
+}
+.swagger-section .swagger-ui-wrap a {
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap a img {
+  border: none;
+}
+.swagger-section .swagger-ui-wrap article,
+.swagger-section .swagger-ui-wrap aside,
+.swagger-section .swagger-ui-wrap details,
+.swagger-section .swagger-ui-wrap figcaption,
+.swagger-section .swagger-ui-wrap figure,
+.swagger-section .swagger-ui-wrap footer,
+.swagger-section .swagger-ui-wrap header,
+.swagger-section .swagger-ui-wrap hgroup,
+.swagger-section .swagger-ui-wrap menu,
+.swagger-section .swagger-ui-wrap nav,
+.swagger-section .swagger-ui-wrap section,
+.swagger-section .swagger-ui-wrap summary {
+  display: block;
+}
+.swagger-section .swagger-ui-wrap pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #fcf6db;
+  border: 1px solid #e5e0c6;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap pre code {
+  line-height: 1.6em;
+  background: none;
+}
+.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
+  clear: both;
+  display: block;
+  color: #0F6AB4;
+  font-size: 1.1em;
+  margin: 0;
+  padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap .content pre {
+  font-size: 12px;
+  margin-top: 5px;
+  padding: 5px;
+}
+.swagger-section .swagger-ui-wrap .icon-btn {
+  cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .info_title {
+  padding-bottom: 10px;
+  font-weight: bold;
+  font-size: 25px;
+}
+.swagger-section .swagger-ui-wrap .footer {
+  margin-top: 20px;
+}
+.swagger-section .swagger-ui-wrap p.big,
+.swagger-section .swagger-ui-wrap div.big p {
+  font-size: 1em;
+  margin-bottom: 10px;
+}
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
+  width: 500px !important;
+}
+.swagger-section .swagger-ui-wrap .info_license {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_tos {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .message-fail {
+  color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap .info_url {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_email {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_name {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_description {
+  padding-bottom: 10px;
+  font-size: 15px;
+}
+.swagger-section .swagger-ui-wrap .markdown ol li,
+.swagger-section .swagger-ui-wrap .markdown ul li {
+  padding: 3px 0px;
+  line-height: 1.4em;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
+  display: block;
+  padding: 4px;
+  width: auto;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
+  font-size: 1.3em;
+}
+.swagger-section .swagger-ui-wrap table.fullwidth {
+  width: 100%;
+}
+.swagger-section .swagger-ui-wrap .model-signature {
+  font-family: "Droid Sans", sans-serif;
+  font-size: 1em;
+  line-height: 1.5em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
+  text-decoration: none;
+  color: #AAA;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
+  text-decoration: underline;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
+  color: black;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propType {
+  color: #5555aa;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre:hover {
+  background-color: #ffffdd;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+  font-size: .85em;
+  line-height: 1.2em;
+  overflow: auto;
+  max-height: 200px;
+  cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
+  display: block;
+  min-width: 230px;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
+  float: left;
+  margin: 0 5px 5px 0;
+  padding: 2px 5px 2px 0;
+  border-right: 1px solid #ddd;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOpt {
+  color: #555;
+}
+.swagger-section .swagger-ui-wrap .model-signature .snippet small {
+  font-size: 0.75em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .strong {
+  font-weight: bold;
+  color: #000;
+  font-size: .9em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description div {
+  font-size: 0.9em;
+  line-height: 1.5em;
+  margin-left: 1em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
+  font-weight: bold;
+  color: #000;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
+  border-spacing: 0;
+  position: absolute;
+  background-color: #ffffff;
+  border: 1px solid #bbbbbb;
+  display: none;
+  font-size: 11px;
+  max-width: 400px;
+  line-height: 30px;
+  color: black;
+  padding: 5px;
+  margin-left: 10px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
+  text-align: center;
+  background-color: #eeeeee;
+  border: 1px solid #bbbbbb;
+  font-size: 11px;
+  color: #666666;
+  font-weight: bold;
+  padding: 5px;
+  line-height: 15px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
+  display: inline;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
+  display: block;
+  content: '';
+}
+.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
+  margin-right: -3px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propName {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-container {
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+  width: 300px;
+  height: 100px;
+  border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap .markdown p code,
+.swagger-section .swagger-ui-wrap .markdown li code {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #f0f0f0;
+  color: black;
+  padding: 1px 3px;
+}
+.swagger-section .swagger-ui-wrap .required {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .editor_holder {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap .editor_holder label {
+  font-weight: normal!important;
+  /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
+}
+.swagger-section .swagger-ui-wrap .editor_holder label.required {
+  font-weight: bold!important;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+  width: 300px;
+  border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap h1 {
+  color: black;
+  font-size: 1.5em;
+  line-height: 1.3em;
+  padding: 10px 0 10px 0;
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu ul {
+  display: block;
+  clear: none;
+  float: right;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -ms-box-sizing: border-box;
+  box-sizing: border-box;
+  margin-top: 10px;
+}
+.swagger-section .swagger-ui-wrap h2 {
+  color: black;
+  font-size: 1.3em;
+  padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap h2 a {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub {
+  font-size: 0.7em;
+  color: #999999;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub a {
+  color: #777777;
+}
+.swagger-section .swagger-ui-wrap span.weak {
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap .message-success {
+  color: #89BF04;
+}
+.swagger-section .swagger-ui-wrap caption,
+.swagger-section .swagger-ui-wrap th,
+.swagger-section .swagger-ui-wrap td {
+  text-align: left;
+  font-weight: normal;
+  vertical-align: middle;
+}
+.swagger-section .swagger-ui-wrap .code {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
+  font-family: "Droid Sans", sans-serif;
+  height: 250px;
+  padding: 4px;
+  display: block;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
+  display: block;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
+  display: block;
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
+  display: block;
+  float: left;
+  clear: none;
+  margin: 0 5px 0 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
+  display: block;
+  clear: both;
+  width: auto;
+  padding: 0 0 3px;
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
+  padding-left: 3px;
+  color: #888888;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
+  margin-left: 0;
+  font-style: italic;
+  font-size: 0.9em;
+  margin: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap span.blank,
+.swagger-section .swagger-ui-wrap span.empty {
+  color: #888888;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .markdown h3 {
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap .markdown h4 {
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap .markdown pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #fcf6db;
+  border: 1px solid #e5e0c6;
+  padding: 10px;
+  margin: 0 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown pre code {
+  line-height: 1.6em;
+}
+.swagger-section .swagger-ui-wrap div.gist {
+  margin: 20px 0 25px 0 !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources {
+  font-family: "Droid Sans", sans-serif;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource {
+  border-bottom: 1px solid #dddddd;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
+  color: #555555;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
+  border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
+  border: 1px solid transparent;
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+  overflow: hidden;
+  padding: 0;
+  display: block;
+  clear: none;
+  float: right;
+  margin: 14px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 2px 10px;
+  border-right: 1px solid #dddddd;
+  color: #666666;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
+  color: #aaaaaa;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
+  text-decoration: underline;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+  color: #999999;
+  padding-left: 0;
+  display: block;
+  clear: none;
+  float: left;
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+  color: #999999;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+  margin: 0 0 10px;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
+  display: block;
+  clear: none;
+  float: left;
+  width: auto;
+  margin: 0;
+  padding: 0;
+  line-height: 1.1em;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
+  padding-left: 10px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
+  color: black;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
+  text-decoration: line-through;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  text-decoration: none;
+  color: white;
+  display: inline-block;
+  width: 50px;
+  font-size: 0.7em;
+  text-align: center;
+  padding: 7px 0 4px;
+  -moz-border-radius: 2px;
+  -webkit-border-radius: 2px;
+  -o-border-radius: 2px;
+  -ms-border-radius: 2px;
+  -khtml-border-radius: 2px;
+  border-radius: 2px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
+  overflow: hidden;
+  padding: 0;
+  display: block;
+  clear: none;
+  float: right;
+  margin: 6px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 2px 10px;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+  border-top: none;
+  padding: 10px;
+  -moz-border-radius-bottomleft: 6px;
+  -webkit-border-bottom-left-radius: 6px;
+  -o-border-bottom-left-radius: 6px;
+  -ms-border-bottom-left-radius: 6px;
+  -khtml-border-bottom-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+  -moz-border-radius-bottomright: 6px;
+  -webkit-border-bottom-right-radius: 6px;
+  -o-border-bottom-right-radius: 6px;
+  -ms-border-bottom-right-radius: 6px;
+  -khtml-border-bottom-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+  margin: 0 0 20px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
+  font-size: 1.1em;
+  margin: 0;
+  padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
+  padding: 4px 0 0 10px;
+  display: inline-block;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
+  display: block;
+  clear: none;
+  float: left;
+  padding: 6px 8px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
+  background-image: url('../images/throbber.gif');
+  width: 128px;
+  height: 16px;
+  display: block;
+  clear: none;
+  float: right;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
+  outline: 2px solid black;
+  outline-color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
+  max-width: 300px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  padding: 10px;
+  font-size: 0.9em;
+  max-height: 400px;
+  overflow-y: auto;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
+  background-color: #f9f2e9;
+  border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
+  background-color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #f0e0ca;
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
+  background-color: #faf5ee;
+  border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
+  color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
+  background-color: #fcffcd;
+  border: 1px solid black;
+  border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  background-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #ffd20f;
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
+  background-color: #fcffcd;
+  border: 1px solid black;
+  border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
+  color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
+  background-color: #f5e8e8;
+  border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  background-color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #e8c6c7;
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+  background-color: #f7eded;
+  border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
+  color: #c8787a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
+  background-color: #e7f6ec;
+  border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
+  background-color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3e8d1;
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
+  background-color: #ebf7f0;
+  border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
+  color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
+  background-color: #FCE9E3;
+  border: 1px solid #F5D5C3;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
+  background-color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #f0cecb;
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
+  background-color: #faf0ef;
+  border: 1px solid #f0cecb;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
+  color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
+  background-color: #e7f0f7;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
+  background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3d9ec;
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
+  color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
+  background-color: #e7f0f7;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
+  background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3d9ec;
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
+  color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+  border-top: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap p#colophon {
+  margin: 0 15px 40px 15px;
+  padding: 10px 0;
+  font-size: 0.8em;
+  border-top: 1px solid #dddddd;
+  font-family: "Droid Sans", sans-serif;
+  color: #999999;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap p#colophon a {
+  text-decoration: none;
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap h3 {
+  color: black;
+  font-size: 1.1em;
+  padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown ol,
+.swagger-section .swagger-ui-wrap .markdown ul {
+  font-family: "Droid Sans", sans-serif;
+  margin: 5px 0 10px;
+  padding: 0 0 0 18px;
+  list-style-type: disc;
+}
+.swagger-section .swagger-ui-wrap form.form_box {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box label {
+  color: #0f6ab4 !important;
+}
+.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
+  display: block;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box p.weak {
+  font-size: 0.8em;
+}
+.swagger-section .swagger-ui-wrap form.form_box p {
+  font-size: 0.9em;
+  padding: 0 0 15px;
+  color: #7e7b6d;
+}
+.swagger-section .swagger-ui-wrap form.form_box p a {
+  color: #646257;
+}
+.swagger-section .swagger-ui-wrap form.form_box p strong {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
+  padding-bottom: 0;
+}
+.swagger-section .title {
+  font-style: bold;
+}
+.swagger-section .secondary_form {
+  display: none;
+}
+.swagger-section .main_image {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+.swagger-section .oauth_body {
+  margin-left: 100px;
+  margin-right: 100px;
+}
+.swagger-section .oauth_submit {
+  text-align: center;
+  display: inline-block;
+}
+.swagger-section .authorize-wrapper {
+  margin: 15px 0 10px;
+}
+.swagger-section .authorize-wrapper_operation {
+  float: right;
+}
+.swagger-section .authorize__btn:hover {
+  text-decoration: underline;
+  cursor: pointer;
+}
+.swagger-section .authorize__btn_operation:hover .authorize-scopes {
+  display: block;
+}
+.swagger-section .authorize-scopes {
+  position: absolute;
+  margin-top: 20px;
+  background: #FFF;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  display: none;
+  font-size: 13px;
+  max-width: 300px;
+  line-height: 30px;
+  color: black;
+  padding: 5px;
+}
+.swagger-section .authorize-scopes .authorize__scope {
+  text-decoration: none;
+}
+.swagger-section .authorize__btn_operation {
+  height: 18px;
+  vertical-align: middle;
+  display: inline-block;
+  background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .authorize__btn_operation_login {
+  background-position: 0 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section .authorize__btn_operation_logout {
+  background-position: -30px 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section #auth_container {
+  color: #fff;
+  display: inline-block;
+  border: none;
+  padding: 5px;
+  width: 87px;
+  height: 13px;
+}
+.swagger-section #auth_container .authorize__btn {
+  color: #fff;
+}
+.swagger-section .auth_container {
+  padding: 0 0 10px;
+  margin-bottom: 5px;
+  border-bottom: solid 1px #CCC;
+  font-size: 0.9em;
+}
+.swagger-section .auth_container .auth__title {
+  color: #547f00;
+  font-size: 1.2em;
+}
+.swagger-section .auth_container .basic_auth__label {
+  display: inline-block;
+  width: 60px;
+}
+.swagger-section .auth_container .auth__description {
+  color: #999999;
+  margin-bottom: 5px;
+}
+.swagger-section .auth_container .auth__button {
+  margin-top: 10px;
+  height: 30px;
+}
+.swagger-section .auth_container .key_auth__field {
+  margin: 5px 0;
+}
+.swagger-section .auth_container .key_auth__label {
+  display: inline-block;
+  width: 60px;
+}
+.swagger-section .api-popup-dialog {
+  position: absolute;
+  display: none;
+}
+.swagger-section .api-popup-dialog-wrapper {
+  z-index: 1000;
+  width: 500px;
+  background: #FFF;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  font-size: 13px;
+  color: #777;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+.swagger-section .api-popup-dialog-shadow {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0.2;
+  background-color: gray;
+  z-index: 900;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+  font-size: 24px;
+  padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+  font-size: 24px;
+  padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .error-msg {
+  padding-left: 5px;
+  padding-bottom: 5px;
+}
+.swagger-section .api-popup-dialog .api-popup-content {
+  max-height: 500px;
+  overflow-y: auto;
+}
+.swagger-section .api-popup-dialog .api-popup-authbtn {
+  height: 30px;
+}
+.swagger-section .api-popup-dialog .api-popup-cancel {
+  height: 30px;
+}
+.swagger-section .api-popup-scopes {
+  padding: 10px 20px;
+}
+.swagger-section .api-popup-scopes li {
+  padding: 5px 0;
+  line-height: 20px;
+}
+.swagger-section .api-popup-scopes li input {
+  position: relative;
+  top: 2px;
+}
+.swagger-section .api-popup-scopes .api-scope-desc {
+  padding-left: 20px;
+  font-style: italic;
+}
+.swagger-section .api-popup-actions {
+  padding-top: 10px;
+}
+#header {
+  display: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+  max-height: none;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+  width: 100px;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+  width: 100px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+  display: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints {
+  display: block !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+  display: block !important;
+}
diff --git a/src/main/resources/META-INF/resources/icd/css/reset.css b/src/main/resources/META-INF/resources/icd/css/reset.css
new file mode 100644 (file)
index 0000000..b2b0789
--- /dev/null
@@ -0,0 +1,125 @@
+/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  font: inherit;
+  vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+  display: block;
+}
+body {
+  line-height: 1;
+}
+ol,
+ul {
+  list-style: none;
+}
+blockquote,
+q {
+  quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+  content: '';
+  content: none;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
diff --git a/src/main/resources/META-INF/resources/icd/css/screen.css b/src/main/resources/META-INF/resources/icd/css/screen.css
new file mode 100644 (file)
index 0000000..90a93a2
--- /dev/null
@@ -0,0 +1,1488 @@
+/* Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> */
+.swagger-section pre code {
+  display: block;
+  padding: 0.5em;
+  background: #F0F0F0;
+}
+.swagger-section pre code,
+.swagger-section pre .subst,
+.swagger-section pre .tag .title,
+.swagger-section pre .lisp .title,
+.swagger-section pre .clojure .built_in,
+.swagger-section pre .nginx .title {
+  color: black;
+}
+.swagger-section pre .string,
+.swagger-section pre .title,
+.swagger-section pre .constant,
+.swagger-section pre .parent,
+.swagger-section pre .tag .value,
+.swagger-section pre .rules .value,
+.swagger-section pre .rules .value .number,
+.swagger-section pre .preprocessor,
+.swagger-section pre .ruby .symbol,
+.swagger-section pre .ruby .symbol .string,
+.swagger-section pre .aggregate,
+.swagger-section pre .template_tag,
+.swagger-section pre .django .variable,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .addition,
+.swagger-section pre .flow,
+.swagger-section pre .stream,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .apache .cbracket,
+.swagger-section pre .tex .command,
+.swagger-section pre .tex .special,
+.swagger-section pre .erlang_repl .function_or_atom,
+.swagger-section pre .markdown .header {
+  color: #800;
+}
+.swagger-section pre .comment,
+.swagger-section pre .annotation,
+.swagger-section pre .template_comment,
+.swagger-section pre .diff .header,
+.swagger-section pre .chunk,
+.swagger-section pre .markdown .blockquote {
+  color: #888;
+}
+.swagger-section pre .number,
+.swagger-section pre .date,
+.swagger-section pre .regexp,
+.swagger-section pre .literal,
+.swagger-section pre .smalltalk .symbol,
+.swagger-section pre .smalltalk .char,
+.swagger-section pre .go .constant,
+.swagger-section pre .change,
+.swagger-section pre .markdown .bullet,
+.swagger-section pre .markdown .link_url {
+  color: #080;
+}
+.swagger-section pre .label,
+.swagger-section pre .javadoc,
+.swagger-section pre .ruby .string,
+.swagger-section pre .decorator,
+.swagger-section pre .filter .argument,
+.swagger-section pre .localvars,
+.swagger-section pre .array,
+.swagger-section pre .attr_selector,
+.swagger-section pre .important,
+.swagger-section pre .pseudo,
+.swagger-section pre .pi,
+.swagger-section pre .doctype,
+.swagger-section pre .deletion,
+.swagger-section pre .envvar,
+.swagger-section pre .shebang,
+.swagger-section pre .apache .sqbracket,
+.swagger-section pre .nginx .built_in,
+.swagger-section pre .tex .formula,
+.swagger-section pre .erlang_repl .reserved,
+.swagger-section pre .prompt,
+.swagger-section pre .markdown .link_label,
+.swagger-section pre .vhdl .attribute,
+.swagger-section pre .clojure .attribute,
+.swagger-section pre .coffeescript .property {
+  color: #88F;
+}
+.swagger-section pre .keyword,
+.swagger-section pre .id,
+.swagger-section pre .phpdoc,
+.swagger-section pre .title,
+.swagger-section pre .built_in,
+.swagger-section pre .aggregate,
+.swagger-section pre .css .tag,
+.swagger-section pre .javadoctag,
+.swagger-section pre .phpdoc,
+.swagger-section pre .yardoctag,
+.swagger-section pre .smalltalk .class,
+.swagger-section pre .winutils,
+.swagger-section pre .bash .variable,
+.swagger-section pre .apache .tag,
+.swagger-section pre .go .typename,
+.swagger-section pre .tex .command,
+.swagger-section pre .markdown .strong,
+.swagger-section pre .request,
+.swagger-section pre .status {
+  font-weight: bold;
+}
+.swagger-section pre .markdown .emphasis {
+  font-style: italic;
+}
+.swagger-section pre .nginx .built_in {
+  font-weight: normal;
+}
+.swagger-section pre .coffeescript .javascript,
+.swagger-section pre .javascript .xml,
+.swagger-section pre .tex .formula,
+.swagger-section pre .xml .javascript,
+.swagger-section pre .xml .vbscript,
+.swagger-section pre .xml .css,
+.swagger-section pre .xml .cdata {
+  opacity: 0.5;
+}
+.swagger-section .hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 0.5em;
+  background: #F0F0F0;
+}
+.swagger-section .hljs,
+.swagger-section .hljs-subst {
+  color: #444;
+}
+.swagger-section .hljs-keyword,
+.swagger-section .hljs-attribute,
+.swagger-section .hljs-selector-tag,
+.swagger-section .hljs-meta-keyword,
+.swagger-section .hljs-doctag,
+.swagger-section .hljs-name {
+  font-weight: bold;
+}
+.swagger-section .hljs-built_in,
+.swagger-section .hljs-literal,
+.swagger-section .hljs-bullet,
+.swagger-section .hljs-code,
+.swagger-section .hljs-addition {
+  color: #1F811F;
+}
+.swagger-section .hljs-regexp,
+.swagger-section .hljs-symbol,
+.swagger-section .hljs-variable,
+.swagger-section .hljs-template-variable,
+.swagger-section .hljs-link,
+.swagger-section .hljs-selector-attr,
+.swagger-section .hljs-selector-pseudo {
+  color: #BC6060;
+}
+.swagger-section .hljs-type,
+.swagger-section .hljs-string,
+.swagger-section .hljs-number,
+.swagger-section .hljs-selector-id,
+.swagger-section .hljs-selector-class,
+.swagger-section .hljs-quote,
+.swagger-section .hljs-template-tag,
+.swagger-section .hljs-deletion {
+  color: #880000;
+}
+.swagger-section .hljs-title,
+.swagger-section .hljs-section {
+  color: #880000;
+  font-weight: bold;
+}
+.swagger-section .hljs-comment {
+  color: #888888;
+}
+.swagger-section .hljs-meta {
+  color: #2B6EA1;
+}
+.swagger-section .hljs-emphasis {
+  font-style: italic;
+}
+.swagger-section .hljs-strong {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap {
+  line-height: 1;
+  font-family: "Droid Sans", sans-serif;
+  min-width: 760px;
+  max-width: 960px;
+  margin-left: auto;
+  margin-right: auto;
+  /* JSONEditor specific styling */
+}
+.swagger-section .swagger-ui-wrap b,
+.swagger-section .swagger-ui-wrap strong {
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap q,
+.swagger-section .swagger-ui-wrap blockquote {
+  quotes: none;
+}
+.swagger-section .swagger-ui-wrap p {
+  line-height: 1.4em;
+  padding: 0 0 10px;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap q:before,
+.swagger-section .swagger-ui-wrap q:after,
+.swagger-section .swagger-ui-wrap blockquote:before,
+.swagger-section .swagger-ui-wrap blockquote:after {
+  content: none;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu h1,
+.swagger-section .swagger-ui-wrap .heading_with_menu h2,
+.swagger-section .swagger-ui-wrap .heading_with_menu h3,
+.swagger-section .swagger-ui-wrap .heading_with_menu h4,
+.swagger-section .swagger-ui-wrap .heading_with_menu h5,
+.swagger-section .swagger-ui-wrap .heading_with_menu h6 {
+  display: block;
+  clear: none;
+  float: left;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -ms-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 60%;
+}
+.swagger-section .swagger-ui-wrap table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+.swagger-section .swagger-ui-wrap table thead tr th {
+  padding: 5px;
+  font-size: 0.9em;
+  color: #666666;
+  border-bottom: 1px solid #999999;
+}
+.swagger-section .swagger-ui-wrap table tbody tr:last-child td {
+  border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap table tbody tr.offset {
+  background-color: #f0f0f0;
+}
+.swagger-section .swagger-ui-wrap table tbody tr td {
+  padding: 6px;
+  font-size: 0.9em;
+  border-bottom: 1px solid #cccccc;
+  vertical-align: top;
+  line-height: 1.3em;
+}
+.swagger-section .swagger-ui-wrap ol {
+  margin: 0px 0 10px;
+  padding: 0 0 0 18px;
+  list-style-type: decimal;
+}
+.swagger-section .swagger-ui-wrap ol li {
+  padding: 5px 0px;
+  font-size: 0.9em;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap ol,
+.swagger-section .swagger-ui-wrap ul {
+  list-style: none;
+}
+.swagger-section .swagger-ui-wrap h1 a,
+.swagger-section .swagger-ui-wrap h2 a,
+.swagger-section .swagger-ui-wrap h3 a,
+.swagger-section .swagger-ui-wrap h4 a,
+.swagger-section .swagger-ui-wrap h5 a,
+.swagger-section .swagger-ui-wrap h6 a {
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap h1 a:hover,
+.swagger-section .swagger-ui-wrap h2 a:hover,
+.swagger-section .swagger-ui-wrap h3 a:hover,
+.swagger-section .swagger-ui-wrap h4 a:hover,
+.swagger-section .swagger-ui-wrap h5 a:hover,
+.swagger-section .swagger-ui-wrap h6 a:hover {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap h1 span.divider,
+.swagger-section .swagger-ui-wrap h2 span.divider,
+.swagger-section .swagger-ui-wrap h3 span.divider,
+.swagger-section .swagger-ui-wrap h4 span.divider,
+.swagger-section .swagger-ui-wrap h5 span.divider,
+.swagger-section .swagger-ui-wrap h6 span.divider {
+  color: #aaaaaa;
+}
+.swagger-section .swagger-ui-wrap a {
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap a img {
+  border: none;
+}
+.swagger-section .swagger-ui-wrap article,
+.swagger-section .swagger-ui-wrap aside,
+.swagger-section .swagger-ui-wrap details,
+.swagger-section .swagger-ui-wrap figcaption,
+.swagger-section .swagger-ui-wrap figure,
+.swagger-section .swagger-ui-wrap footer,
+.swagger-section .swagger-ui-wrap header,
+.swagger-section .swagger-ui-wrap hgroup,
+.swagger-section .swagger-ui-wrap menu,
+.swagger-section .swagger-ui-wrap nav,
+.swagger-section .swagger-ui-wrap section,
+.swagger-section .swagger-ui-wrap summary {
+  display: block;
+}
+.swagger-section .swagger-ui-wrap pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #fcf6db;
+  border: 1px solid #e5e0c6;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap pre code {
+  line-height: 1.6em;
+  background: none;
+}
+.swagger-section .swagger-ui-wrap .content > .content-type > div > label {
+  clear: both;
+  display: block;
+  color: #0F6AB4;
+  font-size: 1.1em;
+  margin: 0;
+  padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap .content pre {
+  font-size: 12px;
+  margin-top: 5px;
+  padding: 5px;
+}
+.swagger-section .swagger-ui-wrap .icon-btn {
+  cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .info_title {
+  padding-bottom: 10px;
+  font-weight: bold;
+  font-size: 25px;
+}
+.swagger-section .swagger-ui-wrap .footer {
+  margin-top: 20px;
+}
+.swagger-section .swagger-ui-wrap p.big,
+.swagger-section .swagger-ui-wrap div.big p {
+  font-size: 1em;
+  margin-bottom: 10px;
+}
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,
+.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input {
+  width: 500px !important;
+}
+.swagger-section .swagger-ui-wrap .info_license {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_tos {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .message-fail {
+  color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap .info_url {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_email {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_name {
+  padding-bottom: 5px;
+}
+.swagger-section .swagger-ui-wrap .info_description {
+  padding-bottom: 10px;
+  font-size: 15px;
+}
+.swagger-section .swagger-ui-wrap .markdown ol li,
+.swagger-section .swagger-ui-wrap .markdown ul li {
+  padding: 3px 0px;
+  line-height: 1.4em;
+  color: #333333;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input {
+  display: block;
+  padding: 4px;
+  width: auto;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title,
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title {
+  font-size: 1.3em;
+}
+.swagger-section .swagger-ui-wrap table.fullwidth {
+  width: 100%;
+}
+.swagger-section .swagger-ui-wrap .model-signature {
+  font-family: "Droid Sans", sans-serif;
+  font-size: 1em;
+  line-height: 1.5em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a {
+  text-decoration: none;
+  color: #AAA;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover {
+  text-decoration: underline;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected {
+  color: black;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propType {
+  color: #5555aa;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre:hover {
+  background-color: #ffffdd;
+}
+.swagger-section .swagger-ui-wrap .model-signature pre {
+  font-size: .85em;
+  line-height: 1.2em;
+  overflow: auto;
+  max-height: 200px;
+  cursor: pointer;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav {
+  display: block;
+  min-width: 230px;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li {
+  float: left;
+  margin: 0 5px 5px 0;
+  padding: 2px 5px 2px 0;
+  border-right: 1px solid #ddd;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOpt {
+  color: #555;
+}
+.swagger-section .swagger-ui-wrap .model-signature .snippet small {
+  font-size: 0.75em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propOptKey {
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .strong {
+  font-weight: bold;
+  color: #000;
+  font-size: .9em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description div {
+  font-size: 0.9em;
+  line-height: 1.5em;
+  margin-left: 1em;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .stronger {
+  font-weight: bold;
+  color: #000;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper {
+  border-spacing: 0;
+  position: absolute;
+  background-color: #ffffff;
+  border: 1px solid #bbbbbb;
+  display: none;
+  font-size: 11px;
+  max-width: 400px;
+  line-height: 30px;
+  color: black;
+  padding: 5px;
+  margin-left: 10px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th {
+  text-align: center;
+  background-color: #eeeeee;
+  border: 1px solid #bbbbbb;
+  font-size: 11px;
+  color: #666666;
+  font-weight: bold;
+  padding: 5px;
+  line-height: 15px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child,
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child {
+  display: inline;
+}
+.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before {
+  display: block;
+  content: '';
+}
+.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child {
+  margin-right: -3px;
+}
+.swagger-section .swagger-ui-wrap .model-signature .propName {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .model-signature .signature-container {
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap .body-textarea {
+  width: 300px;
+  height: 100px;
+  border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap .markdown p code,
+.swagger-section .swagger-ui-wrap .markdown li code {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #f0f0f0;
+  color: black;
+  padding: 1px 3px;
+}
+.swagger-section .swagger-ui-wrap .required {
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .editor_holder {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap .editor_holder label {
+  font-weight: normal!important;
+  /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */
+}
+.swagger-section .swagger-ui-wrap .editor_holder label.required {
+  font-weight: bold!important;
+}
+.swagger-section .swagger-ui-wrap input.parameter {
+  width: 300px;
+  border: 1px solid #aaa;
+}
+.swagger-section .swagger-ui-wrap h1 {
+  color: black;
+  font-size: 1.5em;
+  line-height: 1.3em;
+  padding: 10px 0 10px 0;
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap .heading_with_menu ul {
+  display: block;
+  clear: none;
+  float: right;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -ms-box-sizing: border-box;
+  box-sizing: border-box;
+  margin-top: 10px;
+}
+.swagger-section .swagger-ui-wrap h2 {
+  color: black;
+  font-size: 1.3em;
+  padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap h2 a {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub {
+  font-size: 0.7em;
+  color: #999999;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap h2 span.sub a {
+  color: #777777;
+}
+.swagger-section .swagger-ui-wrap span.weak {
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap .message-success {
+  color: #89BF04;
+}
+.swagger-section .swagger-ui-wrap caption,
+.swagger-section .swagger-ui-wrap th,
+.swagger-section .swagger-ui-wrap td {
+  text-align: left;
+  font-weight: normal;
+  vertical-align: middle;
+}
+.swagger-section .swagger-ui-wrap .code {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea {
+  font-family: "Droid Sans", sans-serif;
+  height: 250px;
+  padding: 4px;
+  display: block;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select {
+  display: block;
+  clear: both;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label {
+  display: block;
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input {
+  display: block;
+  float: left;
+  clear: none;
+  margin: 0 5px 0 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label {
+  display: block;
+  clear: both;
+  width: auto;
+  padding: 0 0 3px;
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr {
+  padding-left: 3px;
+  color: #888888;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints {
+  margin-left: 0;
+  font-style: italic;
+  font-size: 0.9em;
+  margin: 0;
+}
+.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons {
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap span.blank,
+.swagger-section .swagger-ui-wrap span.empty {
+  color: #888888;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap .markdown h3 {
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap .markdown h4 {
+  color: #666666;
+}
+.swagger-section .swagger-ui-wrap .markdown pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  background-color: #fcf6db;
+  border: 1px solid #e5e0c6;
+  padding: 10px;
+  margin: 0 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown pre code {
+  line-height: 1.6em;
+}
+.swagger-section .swagger-ui-wrap div.gist {
+  margin: 20px 0 25px 0 !important;
+}
+.swagger-section .swagger-ui-wrap ul#resources {
+  font-family: "Droid Sans", sans-serif;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource {
+  border-bottom: 1px solid #dddddd;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a,
+.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a {
+  color: #555555;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child {
+  border-bottom: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading {
+  border: 1px solid transparent;
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options {
+  overflow: hidden;
+  padding: 0;
+  display: block;
+  clear: none;
+  float: right;
+  margin: 14px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li {
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 2px 10px;
+  border-right: 1px solid #dddddd;
+  color: #666666;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a {
+  color: #aaaaaa;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover {
+  text-decoration: underline;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+  color: #999999;
+  padding-left: 0;
+  display: block;
+  clear: none;
+  float: left;
+  font-family: "Droid Sans", sans-serif;
+  font-weight: bold;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+  color: #999999;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+  margin: 0 0 10px;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 {
+  display: block;
+  clear: none;
+  float: left;
+  width: auto;
+  margin: 0;
+  padding: 0;
+  line-height: 1.1em;
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path {
+  padding-left: 10px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a {
+  color: black;
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated {
+  text-decoration: line-through;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  text-decoration: none;
+  color: white;
+  display: inline-block;
+  width: 50px;
+  font-size: 0.7em;
+  text-align: center;
+  padding: 7px 0 4px;
+  -moz-border-radius: 2px;
+  -webkit-border-radius: 2px;
+  -o-border-radius: 2px;
+  -ms-border-radius: 2px;
+  -khtml-border-radius: 2px;
+  border-radius: 2px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span {
+  margin: 0;
+  padding: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options {
+  overflow: hidden;
+  padding: 0;
+  display: block;
+  clear: none;
+  float: right;
+  margin: 6px 10px 0 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li {
+  float: left;
+  clear: none;
+  margin: 0;
+  padding: 2px 10px;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a {
+  text-decoration: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content {
+  border-top: none;
+  padding: 10px;
+  -moz-border-radius-bottomleft: 6px;
+  -webkit-border-bottom-left-radius: 6px;
+  -o-border-bottom-left-radius: 6px;
+  -ms-border-bottom-left-radius: 6px;
+  -khtml-border-bottom-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+  -moz-border-radius-bottomright: 6px;
+  -webkit-border-bottom-right-radius: 6px;
+  -o-border-bottom-right-radius: 6px;
+  -ms-border-bottom-right-radius: 6px;
+  -khtml-border-bottom-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+  margin: 0 0 20px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 {
+  font-size: 1.1em;
+  margin: 0;
+  padding: 15px 0 5px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header {
+  float: none;
+  clear: both;
+  overflow: hidden;
+  display: block;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a {
+  padding: 4px 0 0 10px;
+  display: inline-block;
+  font-size: 0.9em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit {
+  display: block;
+  clear: none;
+  float: left;
+  padding: 6px 8px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber {
+  background-image: url('../images/throbber.gif');
+  width: 128px;
+  height: 16px;
+  display: block;
+  clear: none;
+  float: right;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error {
+  outline: 2px solid black;
+  outline-color: #cc0000;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] {
+  max-width: 300px;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre {
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  padding: 10px;
+  font-size: 0.9em;
+  max-height: 400px;
+  overflow-y: auto;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading {
+  background-color: #f9f2e9;
+  border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a {
+  background-color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #f0e0ca;
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a {
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content {
+  background-color: #faf5ee;
+  border: 1px solid #f0e0ca;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 {
+  color: #c5862b;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a {
+  color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading {
+  background-color: #fcffcd;
+  border: 1px solid black;
+  border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  background-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #ffd20f;
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a {
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content {
+  background-color: #fcffcd;
+  border: 1px solid black;
+  border-color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 {
+  color: #ffd20f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a {
+  color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading {
+  background-color: #f5e8e8;
+  border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a {
+  text-transform: uppercase;
+  background-color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #e8c6c7;
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a {
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+  background-color: #f7eded;
+  border: 1px solid #e8c6c7;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 {
+  color: #a41e22;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a {
+  color: #c8787a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading {
+  background-color: #e7f6ec;
+  border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a {
+  background-color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3e8d1;
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a {
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content {
+  background-color: #ebf7f0;
+  border: 1px solid #c3e8d1;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 {
+  color: #10a54a;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a {
+  color: #6fc992;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading {
+  background-color: #FCE9E3;
+  border: 1px solid #F5D5C3;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a {
+  background-color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #f0cecb;
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a {
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content {
+  background-color: #faf0ef;
+  border: 1px solid #f0cecb;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 {
+  color: #D38042;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a {
+  color: #dcb67f;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading {
+  background-color: #e7f0f7;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a {
+  background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3d9ec;
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a {
+  color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading {
+  background-color: #e7f0f7;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a {
+  background-color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li {
+  border-right: 1px solid #dddddd;
+  border-right-color: #c3d9ec;
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 {
+  color: #0f6ab4;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a {
+  color: #6fa5d2;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content {
+  border-top: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last {
+  padding-right: 0;
+  border-right: none;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active {
+  text-decoration: underline;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,
+.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first {
+  padding-left: 0;
+}
+.swagger-section .swagger-ui-wrap p#colophon {
+  margin: 0 15px 40px 15px;
+  padding: 10px 0;
+  font-size: 0.8em;
+  border-top: 1px solid #dddddd;
+  font-family: "Droid Sans", sans-serif;
+  color: #999999;
+  font-style: italic;
+}
+.swagger-section .swagger-ui-wrap p#colophon a {
+  text-decoration: none;
+  color: #547f00;
+}
+.swagger-section .swagger-ui-wrap h3 {
+  color: black;
+  font-size: 1.1em;
+  padding: 10px 0 10px 0;
+}
+.swagger-section .swagger-ui-wrap .markdown ol,
+.swagger-section .swagger-ui-wrap .markdown ul {
+  font-family: "Droid Sans", sans-serif;
+  margin: 5px 0 10px;
+  padding: 0 0 0 18px;
+  list-style-type: disc;
+}
+.swagger-section .swagger-ui-wrap form.form_box {
+  background-color: #ebf3f9;
+  border: 1px solid #c3d9ec;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box label {
+  color: #0f6ab4 !important;
+}
+.swagger-section .swagger-ui-wrap form.form_box input[type=submit] {
+  display: block;
+  padding: 10px;
+}
+.swagger-section .swagger-ui-wrap form.form_box p.weak {
+  font-size: 0.8em;
+}
+.swagger-section .swagger-ui-wrap form.form_box p {
+  font-size: 0.9em;
+  padding: 0 0 15px;
+  color: #7e7b6d;
+}
+.swagger-section .swagger-ui-wrap form.form_box p a {
+  color: #646257;
+}
+.swagger-section .swagger-ui-wrap form.form_box p strong {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child {
+  padding-bottom: 0;
+}
+.swagger-section .title {
+  font-style: bold;
+}
+.swagger-section .secondary_form {
+  display: none;
+}
+.swagger-section .main_image {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+.swagger-section .oauth_body {
+  margin-left: 100px;
+  margin-right: 100px;
+}
+.swagger-section .oauth_submit {
+  text-align: center;
+  display: inline-block;
+}
+.swagger-section .authorize-wrapper {
+  margin: 15px 0 10px;
+}
+.swagger-section .authorize-wrapper_operation {
+  float: right;
+}
+.swagger-section .authorize__btn:hover {
+  text-decoration: underline;
+  cursor: pointer;
+}
+.swagger-section .authorize__btn_operation:hover .authorize-scopes {
+  display: block;
+}
+.swagger-section .authorize-scopes {
+  position: absolute;
+  margin-top: 20px;
+  background: #FFF;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  display: none;
+  font-size: 13px;
+  max-width: 300px;
+  line-height: 30px;
+  color: black;
+  padding: 5px;
+}
+.swagger-section .authorize-scopes .authorize__scope {
+  text-decoration: none;
+}
+.swagger-section .authorize__btn_operation {
+  height: 18px;
+  vertical-align: middle;
+  display: inline-block;
+  background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .authorize__btn_operation_login {
+  background-position: 0 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section .authorize__btn_operation_logout {
+  background-position: -30px 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section #auth_container {
+  color: #fff;
+  display: inline-block;
+  border: none;
+  padding: 5px;
+  width: 87px;
+  height: 13px;
+}
+.swagger-section #auth_container .authorize__btn {
+  color: #fff;
+}
+.swagger-section .auth_container {
+  padding: 0 0 10px;
+  margin-bottom: 5px;
+  border-bottom: solid 1px #CCC;
+  font-size: 0.9em;
+}
+.swagger-section .auth_container .auth__title {
+  color: #547f00;
+  font-size: 1.2em;
+}
+.swagger-section .auth_container .basic_auth__label {
+  display: inline-block;
+  width: 60px;
+}
+.swagger-section .auth_container .auth__description {
+  color: #999999;
+  margin-bottom: 5px;
+}
+.swagger-section .auth_container .auth__button {
+  margin-top: 10px;
+  height: 30px;
+}
+.swagger-section .auth_container .key_auth__field {
+  margin: 5px 0;
+}
+.swagger-section .auth_container .key_auth__label {
+  display: inline-block;
+  width: 60px;
+}
+.swagger-section .api-popup-dialog {
+  position: absolute;
+  display: none;
+}
+.swagger-section .api-popup-dialog-wrapper {
+  z-index: 1000;
+  width: 500px;
+  background: #FFF;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  font-size: 13px;
+  color: #777;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+.swagger-section .api-popup-dialog-shadow {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0.2;
+  background-color: gray;
+  z-index: 900;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+  font-size: 24px;
+  padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .api-popup-title {
+  font-size: 24px;
+  padding: 10px 0;
+}
+.swagger-section .api-popup-dialog .error-msg {
+  padding-left: 5px;
+  padding-bottom: 5px;
+}
+.swagger-section .api-popup-dialog .api-popup-content {
+  max-height: 500px;
+  overflow-y: auto;
+}
+.swagger-section .api-popup-dialog .api-popup-authbtn {
+  height: 30px;
+}
+.swagger-section .api-popup-dialog .api-popup-cancel {
+  height: 30px;
+}
+.swagger-section .api-popup-scopes {
+  padding: 10px 20px;
+}
+.swagger-section .api-popup-scopes li {
+  padding: 5px 0;
+  line-height: 20px;
+}
+.swagger-section .api-popup-scopes li input {
+  position: relative;
+  top: 2px;
+}
+.swagger-section .api-popup-scopes .api-scope-desc {
+  padding-left: 20px;
+  font-style: italic;
+}
+.swagger-section .api-popup-actions {
+  padding-top: 10px;
+}
+.swagger-section .access {
+  float: right;
+}
+.swagger-section .auth {
+  float: right;
+}
+.swagger-section .api-ic {
+  height: 18px;
+  vertical-align: middle;
+  display: inline-block;
+  background: url(../images/explorer_icons.png) no-repeat;
+}
+.swagger-section .api-ic .api_information_panel {
+  position: relative;
+  margin-top: 20px;
+  margin-left: -5px;
+  background: #FFF;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  display: none;
+  font-size: 13px;
+  max-width: 300px;
+  line-height: 30px;
+  color: black;
+  padding: 5px;
+}
+.swagger-section .api-ic .api_information_panel p .api-msg-enabled {
+  color: green;
+}
+.swagger-section .api-ic .api_information_panel p .api-msg-disabled {
+  color: red;
+}
+.swagger-section .api-ic:hover .api_information_panel {
+  position: absolute;
+  display: block;
+}
+.swagger-section .ic-info {
+  background-position: 0 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section .ic-warning {
+  background-position: -60px 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section .ic-error {
+  background-position: -30px 0;
+  width: 18px;
+  margin-top: -6px;
+  margin-left: 4px;
+}
+.swagger-section .ic-off {
+  background-position: -90px 0;
+  width: 58px;
+  margin-top: -4px;
+  cursor: pointer;
+}
+.swagger-section .ic-on {
+  background-position: -160px 0;
+  width: 58px;
+  margin-top: -4px;
+  cursor: pointer;
+}
+.swagger-section #header {
+  background-color: #89bf04;
+  padding: 9px 14px 19px 14px;
+  height: 23px;
+  min-width: 775px;
+}
+.swagger-section #input_baseUrl {
+  width: 400px;
+}
+.swagger-section #api_selector {
+  display: block;
+  clear: none;
+  float: right;
+}
+.swagger-section #api_selector .input {
+  display: inline-block;
+  clear: none;
+  margin: 0 10px 0 0;
+}
+.swagger-section #api_selector input {
+  font-size: 0.9em;
+  padding: 3px;
+  margin: 0;
+}
+.swagger-section #input_apiKey {
+  width: 200px;
+}
+.swagger-section #explore,
+.swagger-section #auth_container .authorize__btn {
+  display: block;
+  text-decoration: none;
+  font-weight: bold;
+  padding: 6px 8px;
+  font-size: 0.9em;
+  color: white;
+  background-color: #547f00;
+  -moz-border-radius: 4px;
+  -webkit-border-radius: 4px;
+  -o-border-radius: 4px;
+  -ms-border-radius: 4px;
+  -khtml-border-radius: 4px;
+  border-radius: 4px;
+}
+.swagger-section #explore:hover,
+.swagger-section #auth_container .authorize__btn:hover {
+  background-color: #547f00;
+}
+.swagger-section #header #logo {
+  font-size: 1.5em;
+  font-weight: bold;
+  text-decoration: none;
+  color: white;
+}
+.swagger-section #header #logo .logo__img {
+  display: block;
+  float: left;
+  margin-top: 2px;
+}
+.swagger-section #header #logo .logo__title {
+  display: inline-block;
+  padding: 5px 0 0 10px;
+}
+.swagger-section #content_message {
+  margin: 10px 15px;
+  font-style: italic;
+  color: #999999;
+}
+.swagger-section #message-bar {
+  min-height: 30px;
+  text-align: center;
+  padding-top: 10px;
+}
+.swagger-section .swagger-collapse:before {
+  content: "-";
+}
+.swagger-section .swagger-expand:before {
+  content: "+";
+}
+.swagger-section .error {
+  outline-color: #cc0000;
+  background-color: #f2dede;
+}
diff --git a/src/main/resources/META-INF/resources/icd/css/style.css b/src/main/resources/META-INF/resources/icd/css/style.css
new file mode 100644 (file)
index 0000000..fc21a31
--- /dev/null
@@ -0,0 +1,250 @@
+.swagger-section #header a#logo {
+  font-size: 1.5em;
+  font-weight: bold;
+  text-decoration: none;
+  background: transparent url(../images/logo.png) no-repeat left center;
+  padding: 20px 0 20px 40px;
+}
+#text-head {
+  font-size: 80px;
+  font-family: 'Roboto', sans-serif;
+  color: #ffffff;
+  float: right;
+  margin-right: 20%;
+}
+.navbar-fixed-top .navbar-nav {
+  height: auto;
+}
+.navbar-fixed-top .navbar-brand {
+  height: auto;
+}
+.navbar-header {
+  height: auto;
+}
+.navbar-inverse {
+  background-color: #000;
+  border-color: #000;
+}
+#navbar-brand {
+  margin-left: 20%;
+}
+.navtext {
+  font-size: 10px;
+}
+.h1,
+h1 {
+  font-size: 60px;
+}
+.navbar-default .navbar-header .navbar-brand {
+  color: #a2dfee;
+}
+/* tag titles */
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a {
+  color: #393939;
+  font-family: 'Arvo', serif;
+  font-size: 1.5em;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover {
+  color: black;
+}
+.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 {
+  color: #525252;
+  padding-left: 0px;
+  display: block;
+  clear: none;
+  float: left;
+  font-family: 'Arvo', serif;
+  font-weight: bold;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+  border-color: #0A0A0A;
+}
+.container1 {
+  width: 1500px;
+  margin: auto;
+  margin-top: 0;
+  background-image: url('../images/shield.png');
+  background-repeat: no-repeat;
+  background-position: -40px -20px;
+  margin-bottom: 210px;
+}
+.container-inner {
+  width: 1200px;
+  margin: auto;
+  background-color: rgba(223, 227, 228, 0.75);
+  padding-bottom: 40px;
+  padding-top: 40px;
+  border-radius: 15px;
+}
+.header-content {
+  padding: 0;
+  width: 1000px;
+}
+.title1 {
+  font-size: 80px;
+  font-family: 'Vollkorn', serif;
+  color: #404040;
+  text-align: center;
+  padding-top: 40px;
+  padding-bottom: 100px;
+}
+#icon {
+  margin-top: -18px;
+}
+.subtext {
+  font-size: 25px;
+  font-style: italic;
+  color: #08b;
+  text-align: right;
+  padding-right: 250px;
+}
+.bg-primary {
+  background-color: #00468b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:focus {
+  color: #08b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:hover {
+  color: #08b;
+}
+.navbar-default .nav > li > a,
+.navbar-default .nav > li > a:focus:hover {
+  color: #08b;
+}
+.text-faded {
+  font-size: 25px;
+  font-family: 'Vollkorn', serif;
+}
+.section-heading {
+  font-family: 'Vollkorn', serif;
+  font-size: 45px;
+  padding-bottom: 10px;
+}
+hr {
+  border-color: #00468b;
+  padding-bottom: 10px;
+}
+.description {
+  margin-top: 20px;
+  padding-bottom: 200px;
+}
+.description li {
+  font-family: 'Vollkorn', serif;
+  font-size: 25px;
+  color: #525252;
+  margin-left: 28%;
+  padding-top: 5px;
+}
+.gap {
+  margin-top: 200px;
+}
+.troubleshootingtext {
+  color: rgba(255, 255, 255, 0.7);
+  padding-left: 30%;
+}
+.troubleshootingtext li {
+  list-style-type: circle;
+  font-size: 25px;
+  padding-bottom: 5px;
+}
+.overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 1000;
+}
+.block.response_body.json:hover {
+  cursor: pointer;
+}
+.backdrop {
+  color: blue;
+}
+#myModal {
+  height: 100%;
+}
+.modal-backdrop {
+  bottom: 0;
+  position: fixed;
+}
+.curl {
+  padding: 10px;
+  font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+  font-size: 0.9em;
+  max-height: 400px;
+  margin-top: 5px;
+  overflow-y: auto;
+  background-color: #fcf6db;
+  border: 1px solid #e5e0c6;
+  border-radius: 4px;
+}
+.curl_title {
+  font-size: 1.1em;
+  margin: 0;
+  padding: 15px 0 5px;
+  font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
+  font-weight: 500;
+  line-height: 1.1;
+}
+.footer {
+  display: none;
+}
+.swagger-section .swagger-ui-wrap h2 {
+  padding: 0;
+}
+h2 {
+  margin: 0;
+  margin-bottom: 5px;
+}
+.markdown p {
+  font-size: 15px;
+  font-family: 'Arvo', serif;
+}
+.swagger-section .swagger-ui-wrap .code {
+  font-size: 15px;
+  font-family: 'Arvo', serif;
+}
+.swagger-section .swagger-ui-wrap b {
+  font-family: 'Arvo', serif;
+}
+#signin:hover {
+  cursor: pointer;
+}
+.dropdown-menu {
+  padding: 15px;
+}
+.navbar-right .dropdown-menu {
+  left: 0;
+  right: auto;
+}
+#signinbutton {
+  width: 100%;
+  height: 32px;
+  font-size: 13px;
+  font-weight: bold;
+  color: #08b;
+}
+.navbar-default .nav > li .details {
+  color: #000000;
+  text-transform: none;
+  font-size: 15px;
+  font-weight: normal;
+  font-family: 'Open Sans', sans-serif;
+  font-style: italic;
+  line-height: 20px;
+  top: -2px;
+}
+.navbar-default .nav > li .details:hover {
+  color: black;
+}
+#signout {
+  width: 100%;
+  height: 32px;
+  font-size: 13px;
+  font-weight: bold;
+  color: #08b;
+}
diff --git a/src/main/resources/META-INF/resources/icd/css/typography.css b/src/main/resources/META-INF/resources/icd/css/typography.css
new file mode 100644 (file)
index 0000000..3235edd
--- /dev/null
@@ -0,0 +1,14 @@
+/* Google Font's Droid Sans */
+@font-face {
+  font-family: 'Droid Sans';
+  font-style: normal;
+  font-weight: 400;
+  src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype');
+}
+/* Google Font's Droid Sans Bold */
+@font-face {
+  font-family: 'Droid Sans';
+  font-style: normal;
+  font-weight: 700;
+  src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype');
+}
diff --git a/src/main/resources/META-INF/resources/icd/fonts/DroidSans-Bold.ttf b/src/main/resources/META-INF/resources/icd/fonts/DroidSans-Bold.ttf
new file mode 100644 (file)
index 0000000..036c4d1
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/fonts/DroidSans-Bold.ttf differ
diff --git a/src/main/resources/META-INF/resources/icd/fonts/DroidSans.ttf b/src/main/resources/META-INF/resources/icd/fonts/DroidSans.ttf
new file mode 100644 (file)
index 0000000..e517a0c
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/fonts/DroidSans.ttf differ
diff --git a/src/main/resources/META-INF/resources/icd/images/collapse.gif b/src/main/resources/META-INF/resources/icd/images/collapse.gif
new file mode 100644 (file)
index 0000000..8843e8c
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/collapse.gif differ
diff --git a/src/main/resources/META-INF/resources/icd/images/expand.gif b/src/main/resources/META-INF/resources/icd/images/expand.gif
new file mode 100644 (file)
index 0000000..477bf13
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/expand.gif differ
diff --git a/src/main/resources/META-INF/resources/icd/images/explorer_icons.png b/src/main/resources/META-INF/resources/icd/images/explorer_icons.png
new file mode 100644 (file)
index 0000000..ed9d2ff
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/explorer_icons.png differ
diff --git a/src/main/resources/META-INF/resources/icd/images/favicon-16x16.png b/src/main/resources/META-INF/resources/icd/images/favicon-16x16.png
new file mode 100644 (file)
index 0000000..66b1a5b
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/favicon-16x16.png differ
diff --git a/src/main/resources/META-INF/resources/icd/images/favicon-32x32.png b/src/main/resources/META-INF/resources/icd/images/favicon-32x32.png
new file mode 100644 (file)
index 0000000..32f319f
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/favicon-32x32.png differ
diff --git a/src/main/resources/META-INF/resources/icd/images/favicon.ico b/src/main/resources/META-INF/resources/icd/images/favicon.ico
new file mode 100644 (file)
index 0000000..8b60bcf
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/favicon.ico differ
diff --git a/src/main/resources/META-INF/resources/icd/images/logo_small.png b/src/main/resources/META-INF/resources/icd/images/logo_small.png
new file mode 100644 (file)
index 0000000..5496a65
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/logo_small.png differ
diff --git a/src/main/resources/META-INF/resources/icd/images/pet_store_api.png b/src/main/resources/META-INF/resources/icd/images/pet_store_api.png
new file mode 100644 (file)
index 0000000..f9f9cd4
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/pet_store_api.png differ
diff --git a/src/main/resources/META-INF/resources/icd/images/throbber.gif b/src/main/resources/META-INF/resources/icd/images/throbber.gif
new file mode 100644 (file)
index 0000000..0639388
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/throbber.gif differ
diff --git a/src/main/resources/META-INF/resources/icd/images/wordnik_api.png b/src/main/resources/META-INF/resources/icd/images/wordnik_api.png
new file mode 100644 (file)
index 0000000..dca4f14
Binary files /dev/null and b/src/main/resources/META-INF/resources/icd/images/wordnik_api.png differ
diff --git a/src/main/resources/META-INF/resources/icd/index.html b/src/main/resources/META-INF/resources/icd/index.html
new file mode 100644 (file)
index 0000000..c79f30d
--- /dev/null
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8">
+  <title>Swagger UI</title>
+  <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
+  <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
+  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
+  <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
+  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
+  <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
+  <script src='lib/js-yaml.min.js' type='text/javascript'></script>
+  <script src='lib/lodash.min.js' type='text/javascript'></script>
+  <script src='lib/backbone-min.js' type='text/javascript'></script>
+  <script src='swagger-ui.js' type='text/javascript'></script>
+  <script src='lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
+  <script src='lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
+  <script src='lib/jsoneditor.min.js' type='text/javascript'></script>
+  <script src='lib/marked.js' type='text/javascript'></script>
+  <script src='lib/swagger-oauth.js' type='text/javascript'></script>
+
+  <!-- Some basic translations -->
+  <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
+  <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
+  <!-- <script src='lang/en.js' type='text/javascript'></script> -->
+
+  <script type="text/javascript">
+    $(function () {
+      var url = window.location.search.match(/url=([^&]+)/);
+      if (url && url.length > 1) {
+        url = decodeURIComponent(url[1]);
+      } else {
+          url = "../swagger.json";
+        //url = "http://petstore.swagger.io/v2/swagger.json";
+      }
+
+      hljs.configure({
+        highlightSizeThreshold: 5000
+      });
+
+      // Pre load translate...
+      if(window.SwaggerTranslator) {
+        window.SwaggerTranslator.translate();
+      }
+      window.swaggerUi = new SwaggerUi({
+        url: url,
+               validatorUrl: null,
+        dom_id: "swagger-ui-container",
+        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
+        onComplete: function(swaggerApi, swaggerUi){
+          if(typeof initOAuth == "function") {
+            initOAuth({
+              clientId: "your-client-id",
+              clientSecret: "your-client-secret-if-required",
+              realm: "your-realms",
+              appName: "your-app-name",
+              scopeSeparator: ",",
+              additionalQueryStringParams: {}
+            });
+          }
+
+          if(window.SwaggerTranslator) {
+            window.SwaggerTranslator.translate();
+          }
+        },
+        onFailure: function(data) {
+          log("Unable to Load SwaggerUI");
+        },
+        docExpansion: "none",
+        jsonEditor: false,
+        defaultModelRendering: 'schema',
+        showRequestHeaders: false
+      });
+
+      window.swaggerUi.load();
+
+      function log() {
+        if ('console' in window) {
+          console.log.apply(console, arguments);
+        }
+      }
+  });
+  </script>
+</head>
+
+<body class="swagger-section">
+<div id='header'>
+  <div class="swagger-ui-wrap">
+    <a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="images/logo_small.png" /><span class="logo__title">swagger</span></a>
+    <form id='api_selector'>
+      <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
+      <div id='auth_container'></div>
+      <div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
+    </form>
+  </div>
+</div>
+
+<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
+<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
+</body>
+</html>
diff --git a/src/main/resources/META-INF/resources/icd/lang/en.js b/src/main/resources/META-INF/resources/icd/lang/en.js
new file mode 100644 (file)
index 0000000..9183136
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Warning: Deprecated",
+    "Implementation Notes":"Implementation Notes",
+    "Response Class":"Response Class",
+    "Status":"Status",
+    "Parameters":"Parameters",
+    "Parameter":"Parameter",
+    "Value":"Value",
+    "Description":"Description",
+    "Parameter Type":"Parameter Type",
+    "Data Type":"Data Type",
+    "Response Messages":"Response Messages",
+    "HTTP Status Code":"HTTP Status Code",
+    "Reason":"Reason",
+    "Response Model":"Response Model",
+    "Request URL":"Request URL",
+    "Response Body":"Response Body",
+    "Response Code":"Response Code",
+    "Response Headers":"Response Headers",
+    "Hide Response":"Hide Response",
+    "Headers":"Headers",
+    "Try it out!":"Try it out!",
+    "Show/Hide":"Show/Hide",
+    "List Operations":"List Operations",
+    "Expand Operations":"Expand Operations",
+    "Raw":"Raw",
+    "can't parse JSON.  Raw result":"can't parse JSON.  Raw result",
+    "Example Value":"Example Value",
+    "Model Schema":"Model Schema",
+    "Model":"Model",
+    "Click to set as parameter value":"Click to set as parameter value",
+    "apply":"apply",
+    "Username":"Username",
+    "Password":"Password",
+    "Terms of service":"Terms of service",
+    "Created by":"Created by",
+    "See more at":"See more at",
+    "Contact the developer":"Contact the developer",
+    "api version":"api version",
+    "Response Content Type":"Response Content Type",
+    "Parameter content type:":"Parameter content type:",
+    "fetching resource":"fetching resource",
+    "fetching resource list":"fetching resource list",
+    "Explore":"Explore",
+    "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Can't read from server.  It may not have the appropriate access-control-origin settings.",
+    "Please specify the protocol for":"Please specify the protocol for",
+    "Can't read swagger JSON from":"Can't read swagger JSON from",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
+    "Unable to read api":"Unable to read api",
+    "from path":"from path",
+    "server returned":"server returned"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/es.js b/src/main/resources/META-INF/resources/icd/lang/es.js
new file mode 100644 (file)
index 0000000..13fa015
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Advertencia: Obsoleto",
+    "Implementation Notes":"Notas de implementación",
+    "Response Class":"Clase de la Respuesta",
+    "Status":"Status",
+    "Parameters":"Parámetros",
+    "Parameter":"Parámetro",
+    "Value":"Valor",
+    "Description":"Descripción",
+    "Parameter Type":"Tipo del Parámetro",
+    "Data Type":"Tipo del Dato",
+    "Response Messages":"Mensajes de la Respuesta",
+    "HTTP Status Code":"Código de Status HTTP",
+    "Reason":"Razón",
+    "Response Model":"Modelo de la Respuesta",
+    "Request URL":"URL de la Solicitud",
+    "Response Body":"Cuerpo de la Respuesta",
+    "Response Code":"Código de la Respuesta",
+    "Response Headers":"Encabezados de la Respuesta",
+    "Hide Response":"Ocultar Respuesta",
+    "Try it out!":"Pruébalo!",
+    "Show/Hide":"Mostrar/Ocultar",
+    "List Operations":"Listar Operaciones",
+    "Expand Operations":"Expandir Operaciones",
+    "Raw":"Crudo",
+    "can't parse JSON.  Raw result":"no puede parsear el JSON.  Resultado crudo",
+    "Example Value":"Valor de Ejemplo",
+    "Model Schema":"Esquema del Modelo",
+    "Model":"Modelo",
+    "apply":"aplicar",
+    "Username":"Nombre de usuario",
+    "Password":"Contraseña",
+    "Terms of service":"Términos de Servicio",
+    "Created by":"Creado por",
+    "See more at":"Ver más en",
+    "Contact the developer":"Contactar al desarrollador",
+    "api version":"versión de la api",
+    "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta",
+    "fetching resource":"buscando recurso",
+    "fetching resource list":"buscando lista del recurso",
+    "Explore":"Explorar",
+    "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.",
+    "Please specify the protocol for":"Por favor, especificar el protocola para",
+    "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI",
+    "Unable to read api":"No se puede leer la api",
+    "from path":"desde ruta",
+    "server returned":"el servidor retornó"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/fr.js b/src/main/resources/META-INF/resources/icd/lang/fr.js
new file mode 100644 (file)
index 0000000..388dff1
--- /dev/null
@@ -0,0 +1,54 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Avertissement : Obsolète",
+    "Implementation Notes":"Notes d'implémentation",
+    "Response Class":"Classe de la réponse",
+    "Status":"Statut",
+    "Parameters":"Paramètres",
+    "Parameter":"Paramètre",
+    "Value":"Valeur",
+    "Description":"Description",
+    "Parameter Type":"Type du paramètre",
+    "Data Type":"Type de données",
+    "Response Messages":"Messages de la réponse",
+    "HTTP Status Code":"Code de statut HTTP",
+    "Reason":"Raison",
+    "Response Model":"Modèle de réponse",
+    "Request URL":"URL appelée",
+    "Response Body":"Corps de la réponse",
+    "Response Code":"Code de la réponse",
+    "Response Headers":"En-têtes de la réponse",
+    "Hide Response":"Cacher la réponse",
+    "Headers":"En-têtes",
+    "Try it out!":"Testez !",
+    "Show/Hide":"Afficher/Masquer",
+    "List Operations":"Liste des opérations",
+    "Expand Operations":"Développer les opérations",
+    "Raw":"Brut",
+    "can't parse JSON.  Raw result":"impossible de décoder le JSON.  Résultat brut",
+    "Example Value":"Exemple la valeur",
+    "Model Schema":"Définition du modèle",
+    "Model":"Modèle",
+    "apply":"appliquer",
+    "Username":"Nom d'utilisateur",
+    "Password":"Mot de passe",
+    "Terms of service":"Conditions de service",
+    "Created by":"Créé par",
+    "See more at":"Voir plus sur",
+    "Contact the developer":"Contacter le développeur",
+    "api version":"version de l'api",
+    "Response Content Type":"Content Type de la réponse",
+    "fetching resource":"récupération de la ressource",
+    "fetching resource list":"récupération de la liste de ressources",
+    "Explore":"Explorer",
+    "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.",
+    "Please specify the protocol for":"Veuillez spécifier un protocole pour",
+    "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI",
+    "Unable to read api":"Impossible de lire l'api",
+    "from path":"à partir du chemin",
+    "server returned":"réponse du serveur"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/geo.js b/src/main/resources/META-INF/resources/icd/lang/geo.js
new file mode 100644 (file)
index 0000000..609c20d
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება",
+    "Implementation Notes":"იმპლემენტაციის აღწერა",
+    "Response Class":"რესპონს კლასი",
+    "Status":"სტატუსი",
+    "Parameters":"პარამეტრები",
+    "Parameter":"პარამეტრი",
+    "Value":"მნიშვნელობა",
+    "Description":"აღწერა",
+    "Parameter Type":"პარამეტრის ტიპი",
+    "Data Type":"მონაცემის ტიპი",
+    "Response Messages":"პასუხი",
+    "HTTP Status Code":"HTTP სტატუსი",
+    "Reason":"მიზეზი",
+    "Response Model":"რესპონს მოდელი",
+    "Request URL":"მოთხოვნის URL",
+    "Response Body":"პასუხის სხეული",
+    "Response Code":"პასუხის კოდი",
+    "Response Headers":"პასუხის ჰედერები",
+    "Hide Response":"დამალე პასუხი",
+    "Headers":"ჰედერები",
+    "Try it out!":"ცადე !",
+    "Show/Hide":"გამოჩენა/დამალვა",
+    "List Operations":"ოპერაციების სია",
+    "Expand Operations":"ოპერაციები ვრცლად",
+    "Raw":"ნედლი",
+    "can't parse JSON.  Raw result":"JSON-ის დამუშავება ვერ მოხერხდა.  ნედლი პასუხი",
+    "Example Value":"მაგალითი",
+    "Model Schema":"მოდელის სტრუქტურა",
+    "Model":"მოდელი",
+    "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე",
+    "apply":"გამოყენება",
+    "Username":"მოხმარებელი",
+    "Password":"პაროლი",
+    "Terms of service":"მომსახურების პირობები",
+    "Created by":"შექმნა",
+    "See more at":"ნახე ვრცლად",
+    "Contact the developer":"დაუკავშირდი დეველოპერს",
+    "api version":"api ვერსია",
+    "Response Content Type":"პასუხის კონტენტის ტიპი",
+    "Parameter content type:":"პარამეტრის კონტენტის ტიპი:",
+    "fetching resource":"რესურსების მიღება",
+    "fetching resource list":"რესურსების სიის მიღება",
+    "Explore":"ნახვა",
+    "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება.  შეამოწმეთ access-control-origin.",
+    "Please specify the protocol for":"მიუთითეთ პროტოკოლი",
+    "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა",
+    "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება",
+    "Unable to read api":"api წაკითხვა ვერ მოხერხდა",
+    "from path":"მისამართიდან",
+    "server returned":"სერვერმა დააბრუნა"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/it.js b/src/main/resources/META-INF/resources/icd/lang/it.js
new file mode 100644 (file)
index 0000000..8529c2a
--- /dev/null
@@ -0,0 +1,52 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Attenzione: Deprecato",
+    "Implementation Notes":"Note di implementazione",
+    "Response Class":"Classe della risposta",
+    "Status":"Stato",
+    "Parameters":"Parametri",
+    "Parameter":"Parametro",
+    "Value":"Valore",
+    "Description":"Descrizione",
+    "Parameter Type":"Tipo di parametro",
+    "Data Type":"Tipo di dato",
+    "Response Messages":"Messaggi della risposta",
+    "HTTP Status Code":"Codice stato HTTP",
+    "Reason":"Motivo",
+    "Response Model":"Modello di risposta",
+    "Request URL":"URL della richiesta",
+    "Response Body":"Corpo della risposta",
+    "Response Code":"Oggetto della risposta",
+    "Response Headers":"Intestazioni della risposta",
+    "Hide Response":"Nascondi risposta",
+    "Try it out!":"Provalo!",
+    "Show/Hide":"Mostra/Nascondi",
+    "List Operations":"Mostra operazioni",
+    "Expand Operations":"Espandi operazioni",
+    "Raw":"Grezzo (raw)",
+    "can't parse JSON.  Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).",
+    "Model Schema":"Schema del modello",
+    "Model":"Modello",
+    "apply":"applica",
+    "Username":"Nome utente",
+    "Password":"Password",
+    "Terms of service":"Condizioni del servizio",
+    "Created by":"Creato da",
+    "See more at":"Informazioni aggiuntive:",
+    "Contact the developer":"Contatta lo sviluppatore",
+    "api version":"versione api",
+    "Response Content Type":"Tipo di contenuto (content type) della risposta",
+    "fetching resource":"recuperando la risorsa",
+    "fetching resource list":"recuperando lista risorse",
+    "Explore":"Esplora",
+    "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.",
+    "Please specify the protocol for":"Si prega di specificare il protocollo per",
+    "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata",
+    "Unable to read api":"Impossibile leggere la api",
+    "from path":"da cartella",
+    "server returned":"il server ha restituito"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/ja.js b/src/main/resources/META-INF/resources/icd/lang/ja.js
new file mode 100644 (file)
index 0000000..3207bfc
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"警告: 廃止予定",
+    "Implementation Notes":"実装メモ",
+    "Response Class":"レスポンスクラス",
+    "Status":"ステータス",
+    "Parameters":"パラメータ群",
+    "Parameter":"パラメータ",
+    "Value":"値",
+    "Description":"説明",
+    "Parameter Type":"パラメータタイプ",
+    "Data Type":"データタイプ",
+    "Response Messages":"レスポンスメッセージ",
+    "HTTP Status Code":"HTTPステータスコード",
+    "Reason":"理由",
+    "Response Model":"レスポンスモデル",
+    "Request URL":"リクエストURL",
+    "Response Body":"レスポンスボディ",
+    "Response Code":"レスポンスコード",
+    "Response Headers":"レスポンスヘッダ",
+    "Hide Response":"レスポンスを隠す",
+    "Headers":"ヘッダ",
+    "Try it out!":"実際に実行!",
+    "Show/Hide":"表示/非表示",
+    "List Operations":"操作一覧",
+    "Expand Operations":"操作の展開",
+    "Raw":"Raw",
+    "can't parse JSON.  Raw result":"JSONへ解釈できません.  未加工の結果",
+    "Model Schema":"モデルスキーマ",
+    "Model":"モデル",
+    "apply":"実行",
+    "Username":"ユーザ名",
+    "Password":"パスワード",
+    "Terms of service":"サービス利用規約",
+    "Created by":"Created by",
+    "See more at":"See more at",
+    "Contact the developer":"開発者に連絡",
+    "api version":"APIバージョン",
+    "Response Content Type":"レスポンス コンテンツタイプ",
+    "fetching resource":"リソースの取得",
+    "fetching resource list":"リソース一覧の取得",
+    "Explore":"Explore",
+    "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"サーバから読み込めません.  適切なaccess-control-origin設定を持っていない可能性があります.",
+    "Please specify the protocol for":"プロトコルを指定してください",
+    "Can't read swagger JSON from":"次からswagger JSONを読み込めません",
+    "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています",
+    "Unable to read api":"APIを読み込めません",
+    "from path":"次のパスから",
+    "server returned":"サーバからの返答"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/pl.js b/src/main/resources/META-INF/resources/icd/lang/pl.js
new file mode 100644 (file)
index 0000000..ce41e91
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Uwaga: Wycofane",
+    "Implementation Notes":"Uwagi Implementacji",
+    "Response Class":"Klasa Odpowiedzi",
+    "Status":"Status",
+    "Parameters":"Parametry",
+    "Parameter":"Parametr",
+    "Value":"Wartość",
+    "Description":"Opis",
+    "Parameter Type":"Typ Parametru",
+    "Data Type":"Typ Danych",
+    "Response Messages":"Wiadomości Odpowiedzi",
+    "HTTP Status Code":"Kod Statusu HTTP",
+    "Reason":"Przyczyna",
+    "Response Model":"Model Odpowiedzi",
+    "Request URL":"URL Wywołania",
+    "Response Body":"Treść Odpowiedzi",
+    "Response Code":"Kod Odpowiedzi",
+    "Response Headers":"Nagłówki Odpowiedzi",
+    "Hide Response":"Ukryj Odpowiedź",
+    "Headers":"Nagłówki",
+    "Try it out!":"Wypróbuj!",
+    "Show/Hide":"Pokaż/Ukryj",
+    "List Operations":"Lista Operacji",
+    "Expand Operations":"Rozwiń Operacje",
+    "Raw":"Nieprzetworzone",
+    "can't parse JSON.  Raw result":"nie można przetworzyć pliku JSON.  Nieprzetworzone dane",
+    "Model Schema":"Schemat Modelu",
+    "Model":"Model",
+    "apply":"użyj",
+    "Username":"Nazwa użytkownika",
+    "Password":"Hasło",
+    "Terms of service":"Warunki używania",
+    "Created by":"Utworzone przez",
+    "See more at":"Zobacz więcej na",
+    "Contact the developer":"Kontakt z deweloperem",
+    "api version":"wersja api",
+    "Response Content Type":"Typ Zasobu Odpowiedzi",
+    "fetching resource":"ładowanie zasobu",
+    "fetching resource list":"ładowanie listy zasobów",
+    "Explore":"Eksploruj",
+    "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.",
+    "Please specify the protocol for":"Proszę podać protokół dla",
+    "Can't read swagger JSON from":"Nie można odczytać swagger JSON z",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI",
+    "Unable to read api":"Nie można odczytać api",
+    "from path":"ze ścieżki",
+    "server returned":"serwer zwrócił"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/pt.js b/src/main/resources/META-INF/resources/icd/lang/pt.js
new file mode 100644 (file)
index 0000000..f2e7c13
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Aviso: Depreciado",
+    "Implementation Notes":"Notas de Implementação",
+    "Response Class":"Classe de resposta",
+    "Status":"Status",
+    "Parameters":"Parâmetros",
+    "Parameter":"Parâmetro",
+    "Value":"Valor",
+    "Description":"Descrição",
+    "Parameter Type":"Tipo de parâmetro",
+    "Data Type":"Tipo de dados",
+    "Response Messages":"Mensagens de resposta",
+    "HTTP Status Code":"Código de status HTTP",
+    "Reason":"Razão",
+    "Response Model":"Modelo resposta",
+    "Request URL":"URL requisição",
+    "Response Body":"Corpo da resposta",
+    "Response Code":"Código da resposta",
+    "Response Headers":"Cabeçalho da resposta",
+    "Headers":"Cabeçalhos",
+    "Hide Response":"Esconder resposta",
+    "Try it out!":"Tente agora!",
+    "Show/Hide":"Mostrar/Esconder",
+    "List Operations":"Listar operações",
+    "Expand Operations":"Expandir operações",
+    "Raw":"Cru",
+    "can't parse JSON.  Raw result":"Falha ao analisar JSON.  Resulto cru",
+    "Model Schema":"Modelo esquema",
+    "Model":"Modelo",
+    "apply":"Aplicar",
+    "Username":"Usuário",
+    "Password":"Senha",
+    "Terms of service":"Termos do serviço",
+    "Created by":"Criado por",
+    "See more at":"Veja mais em",
+    "Contact the developer":"Contate o desenvolvedor",
+    "api version":"Versão api",
+    "Response Content Type":"Tipo de conteúdo da resposta",
+    "fetching resource":"busca recurso",
+    "fetching resource list":"buscando lista de recursos",
+    "Explore":"Explorar",
+    "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin",
+    "Please specify the protocol for":"Por favor especifique o protocolo",
+    "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI",
+    "Unable to read api":"Não foi possível ler api",
+    "from path":"do caminho",
+    "server returned":"servidor retornou"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/ru.js b/src/main/resources/META-INF/resources/icd/lang/ru.js
new file mode 100644 (file)
index 0000000..592744e
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Предупреждение: Устарело",
+    "Implementation Notes":"Заметки",
+    "Response Class":"Пример ответа",
+    "Status":"Статус",
+    "Parameters":"Параметры",
+    "Parameter":"Параметр",
+    "Value":"Значение",
+    "Description":"Описание",
+    "Parameter Type":"Тип параметра",
+    "Data Type":"Тип данных",
+    "HTTP Status Code":"HTTP код",
+    "Reason":"Причина",
+    "Response Model":"Структура ответа",
+    "Request URL":"URL запроса",
+    "Response Body":"Тело ответа",
+    "Response Code":"HTTP код ответа",
+    "Response Headers":"Заголовки ответа",
+    "Hide Response":"Спрятать ответ",
+    "Headers":"Заголовки",
+    "Response Messages":"Что может прийти в ответ",
+    "Try it out!":"Попробовать!",
+    "Show/Hide":"Показать/Скрыть",
+    "List Operations":"Операции кратко",
+    "Expand Operations":"Операции подробно",
+    "Raw":"В сыром виде",
+    "can't parse JSON.  Raw result":"Не удается распарсить ответ:",
+    "Example Value":"Пример",
+    "Model Schema":"Структура",
+    "Model":"Описание",
+    "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра",
+    "apply":"применить",
+    "Username":"Имя пользователя",
+    "Password":"Пароль",
+    "Terms of service":"Условия использования",
+    "Created by":"Разработано",
+    "See more at":"Еще тут",
+    "Contact the developer":"Связаться с разработчиком",
+    "api version":"Версия API",
+    "Response Content Type":"Content Type ответа",
+    "Parameter content type:":"Content Type параметра:",
+    "fetching resource":"Получение ресурса",
+    "fetching resource list":"Получение ресурсов",
+    "Explore":"Показать",
+    "Show Swagger Petstore Example Apis":"Показать примеры АПИ",
+    "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа",
+    "Please specify the protocol for":"Пожалуйста, укажите протокол для",
+    "Can't read swagger JSON from":"Не получается прочитать swagger json из",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим",
+    "Unable to read api":"Не удалось прочитать api",
+    "from path":"по адресу",
+    "server returned":"сервер сказал"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/tr.js b/src/main/resources/META-INF/resources/icd/lang/tr.js
new file mode 100644 (file)
index 0000000..16426a9
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Uyarı: Deprecated",
+    "Implementation Notes":"Gerçekleştirim Notları",
+    "Response Class":"Dönen Sınıf",
+    "Status":"Statü",
+    "Parameters":"Parametreler",
+    "Parameter":"Parametre",
+    "Value":"Değer",
+    "Description":"Açıklama",
+    "Parameter Type":"Parametre Tipi",
+    "Data Type":"Veri Tipi",
+    "Response Messages":"Dönüş Mesajı",
+    "HTTP Status Code":"HTTP Statü Kodu",
+    "Reason":"Gerekçe",
+    "Response Model":"Dönüş Modeli",
+    "Request URL":"İstek URL",
+    "Response Body":"Dönüş İçeriği",
+    "Response Code":"Dönüş Kodu",
+    "Response Headers":"Dönüş Üst Bilgileri",
+    "Hide Response":"Dönüşü Gizle",
+    "Headers":"Üst Bilgiler",
+    "Try it out!":"Dene!",
+    "Show/Hide":"Göster/Gizle",
+    "List Operations":"Operasyonları Listele",
+    "Expand Operations":"Operasyonları Aç",
+    "Raw":"Ham",
+    "can't parse JSON.  Raw result":"JSON çözümlenemiyor.  Ham sonuç",
+    "Model Schema":"Model Şema",
+    "Model":"Model",
+    "apply":"uygula",
+    "Username":"Kullanıcı Adı",
+    "Password":"Parola",
+    "Terms of service":"Servis şartları",
+    "Created by":"Oluşturan",
+    "See more at":"Daha fazlası için",
+    "Contact the developer":"Geliştirici ile İletişime Geçin",
+    "api version":"api versiyon",
+    "Response Content Type":"Dönüş İçerik Tipi",
+    "fetching resource":"kaynak getiriliyor",
+    "fetching resource list":"kaynak listesi getiriliyor",
+    "Explore":"Keşfet",
+    "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.",
+    "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz",
+    "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor",
+    "Unable to read api":"api okunamadı",
+    "from path":"yoldan",
+    "server returned":"sunucuya dönüldü"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lang/translator.js b/src/main/resources/META-INF/resources/icd/lang/translator.js
new file mode 100644 (file)
index 0000000..591f6d4
--- /dev/null
@@ -0,0 +1,39 @@
+'use strict';
+
+/**
+ * Translator for documentation pages.
+ *
+ * To enable translation you should include one of language-files in your index.html
+ * after <script src='lang/translator.js' type='text/javascript'></script>.
+ * For example - <script src='lang/ru.js' type='text/javascript'></script>
+ *
+ * If you wish to translate some new texsts you should do two things:
+ * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
+ * 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
+ * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
+ *
+ */
+window.SwaggerTranslator = {
+
+    _words:[],
+
+    translate: function(sel) {
+      var $this = this;
+      sel = sel || '[data-sw-translate]';
+
+      $(sel).each(function() {
+        $(this).html($this._tryTranslate($(this).html()));
+
+        $(this).val($this._tryTranslate($(this).val()));
+        $(this).attr('title', $this._tryTranslate($(this).attr('title')));
+      });
+    },
+
+    _tryTranslate: function(word) {
+      return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
+    },
+
+    learn: function(wordsMap) {
+      this._words = wordsMap;
+    }
+};
diff --git a/src/main/resources/META-INF/resources/icd/lang/zh-cn.js b/src/main/resources/META-INF/resources/icd/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..570319b
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"警告:已过时",
+    "Implementation Notes":"实现备注",
+    "Response Class":"响应类",
+    "Status":"状态",
+    "Parameters":"参数",
+    "Parameter":"参数",
+    "Value":"值",
+    "Description":"描述",
+    "Parameter Type":"参数类型",
+    "Data Type":"数据类型",
+    "Response Messages":"响应消息",
+    "HTTP Status Code":"HTTP状态码",
+    "Reason":"原因",
+    "Response Model":"响应模型",
+    "Request URL":"请求URL",
+    "Response Body":"响应体",
+    "Response Code":"响应码",
+    "Response Headers":"响应头",
+    "Hide Response":"隐藏响应",
+    "Headers":"头",
+    "Try it out!":"试一下!",
+    "Show/Hide":"显示/隐藏",
+    "List Operations":"显示操作",
+    "Expand Operations":"展开操作",
+    "Raw":"原始",
+    "can't parse JSON.  Raw result":"无法解析JSON. 原始结果",
+    "Model Schema":"模型架构",
+    "Model":"模型",
+    "apply":"应用",
+    "Username":"用户名",
+    "Password":"密码",
+    "Terms of service":"服务条款",
+    "Created by":"创建者",
+    "See more at":"查看更多:",
+    "Contact the developer":"联系开发者",
+    "api version":"api版本",
+    "Response Content Type":"响应Content Type",
+    "fetching resource":"正在获取资源",
+    "fetching resource list":"正在获取资源列表",
+    "Explore":"浏览",
+    "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
+    "Please specify the protocol for":"请指定协议:",
+    "Can't read swagger JSON from":"无法读取swagger JSON于",
+    "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
+    "Unable to read api":"无法读取api",
+    "from path":"从路径",
+    "server returned":"服务器返回"
+});
diff --git a/src/main/resources/META-INF/resources/icd/lib/backbone-min.js b/src/main/resources/META-INF/resources/icd/lib/backbone-min.js
new file mode 100644 (file)
index 0000000..a3f544b
--- /dev/null
@@ -0,0 +1,15 @@
+// Backbone.js 1.1.2
+
+(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h<u;h++){t=o[h];if(a=this._events[t]){this._events[t]=s=[];if(e||r){for(l=0,f=a.length;l<f;l++){n=a[l];if(e&&e!==n.callback&&e!==n.callback._callback||r&&r!==n.context){s.push(n)}}}if(!s.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=o.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)f(i,e);if(r)f(r,arguments);return this},stopListening:function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=!e&&!r;if(!r&&typeof e==="object")r=this;if(t)(s={})[t._listenId]=t;for(var a in s){t=s[a];t.off(e,r,this);if(n||i.isEmpty(t._events))delete this._listeningTo[a]}return this}};var l=/\s+/;var c=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(l.test(i)){var n=i.split(l);for(var a=0,o=n.length;a<o;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var f=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var d={listenTo:"on",listenToOnce:"once"};i.each(d,function(t,e){u[e]=function(e,r,s){var n=this._listeningTo||(this._listeningTo={});var a=e._listenId||(e._listenId=i.uniqueId("l"));n[a]=e;if(!s&&typeof r==="object")s=this;e[t](r,s,this);return this}});u.bind=u.on;u.unbind=u.off;i.extend(e,u);var p=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(p.prototype,u,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0,d=o.length;f<d;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r(e,i,t);e.trigger("sync",e,i,t)};q(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);if(s&&!r.wait){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&r.wait){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var h=this;var u=r.success;r.success=function(t){h.attributes=o;var e=h.parse(t,r);if(r.wait)e=i.extend(s||{},e);if(i.isObject(e)&&!h.set(e,r)){return false}if(u)u(h,t,r);h.trigger("sync",h,t,r)};q(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch")r.attrs=s;a=this.sync(n,this,r);if(s&&r.wait)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(t.wait||e.isNew())s();if(r)r(e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};if(this.isNew()){t.success();return false}q(this,t);var n=this.sync("delete",this,t);if(!t.wait)s();return n},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||M();if(this.isNew())return t;return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var v=["keys","values","pairs","invert","pick","omit"];i.each(v,function(t){p.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.attributes);return i[t].apply(i,e)}});var g=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var m={add:true,remove:true,merge:true};var y={add:true,remove:false};i.extend(g.prototype,u,{model:p,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,y))},remove:function(t,e){var r=!i.isArray(t);t=r?[t]:i.clone(t);e||(e={});var s,n,a,o;for(s=0,n=t.length;s<n;s++){o=t[s]=this.get(t[s]);if(!o)continue;delete this._byId[o.id];delete this._byId[o.cid];a=this.indexOf(o);this.models.splice(a,1);this.length--;if(!e.silent){e.index=a;o.trigger("remove",o,this,e)}this._removeReference(o,e)}return r?t[0]:t},set:function(t,e){e=i.defaults({},e,m);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:i.clone(t);var s,n,a,o,h,u,l;var c=e.at;var f=this.model;var d=this.comparator&&c==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g=[],y=[],_={};var b=e.add,w=e.merge,x=e.remove;var E=!d&&b&&x?[]:false;for(s=0,n=t.length;s<n;s++){h=t[s]||{};if(h instanceof p){a=o=h}else{a=h[f.prototype.idAttribute||"id"]}if(u=this.get(a)){if(x)_[u.cid]=true;if(w){h=h===o?o.attributes:h;if(e.parse)h=u.parse(h,e);u.set(h,e);if(d&&!l&&u.hasChanged(v))l=true}t[s]=u}else if(b){o=t[s]=this._prepareModel(h,e);if(!o)continue;g.push(o);this._addReference(o,e)}o=u||o;if(E&&(o.isNew()||!_[o.id]))E.push(o);_[o.id]=true}if(x){for(s=0,n=this.length;s<n;++s){if(!_[(o=this.models[s]).cid])y.push(o)}if(y.length)this.remove(y,e)}if(g.length||E&&E.length){if(d)l=true;this.length+=g.length;if(c!=null){for(s=0,n=g.length;s<n;s++){this.models.splice(c+s,0,g[s])}}else{if(E)this.models.length=0;var k=E||g;for(s=0,n=k.length;s<n;s++){this.models.push(k[s])}}}if(l)this.sort({silent:true});if(!e.silent){for(s=0,n=g.length;s<n;s++){(o=g[s]).trigger("add",o,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return r?t[0]:t},reset:function(t,e){e||(e={});for(var r=0,s=this.models.length;r<s;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return o.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){if(i.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e(r,i,t);r.trigger("sync",r,i,t)};q(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var r=this;var s=e.success;e.success=function(t,i){if(e.wait)r.add(t,e);if(s)s(t,i,e)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof p)return t;e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_addReference:function(t,e){this._byId[t.cid]=t;if(t.id!=null)this._byId[t.id]=t;if(!t.collection)t.collection=this;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var _=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(_,function(t){g.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.models);return i[t].apply(i,e)}});var b=["groupBy","countBy","sortBy","indexBy"];i.each(b,function(t){g.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var w=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,E));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var x=/^(\S+)\s*(.*)$/;var E=["model","collection","el","id","attributes","className","tagName","events"];i.extend(w.prototype,u,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,i){if(this.$el)this.undelegateEvents();this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0];if(i!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(x);var n=s[1],a=s[2];r=i.bind(r,this);n+=".delegateEvents"+this.cid;if(a===""){this.$el.on(n,r)}else{this.$el.on(n,a,r)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");var r=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow;this.navigate(r)}if(this._hasPushState){e.$(window).on("popstate",this.checkUrl)}else if(this._wantsHashChange&&"onhashchange"in window&&!n){e.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=r;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){this.fragment=this.getFragment(null,true);this.location.replace(this.root+"#"+this.fragment);return true}else if(this._hasPushState&&this.atRoot()&&o.hash){this.fragment=this.getHash().replace(R,"");this.history.replaceState({},document.title,this.root+this.fragment)}}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var U=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};p.extend=g.extend=$.extend=w.extend=N.extend=U;var M=function(){throw new Error('A "url" property or function must be specified')};var q=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}};return e});
+
+// From http://stackoverflow.com/a/19431552
+// Compatibility override - Backbone 1.1 got rid of the 'options' binding
+// automatically to views in the constructor - we need to keep that.
+Backbone.View = (function(View) {
+   return View.extend({
+        constructor: function(options) {
+            this.options = options || {};
+            View.apply(this, arguments);
+        }
+    });
+})(Backbone.View);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/handlebars-2.0.0.js b/src/main/resources/META-INF/resources/icd/lib/handlebars-2.0.0.js
new file mode 100644 (file)
index 0000000..53cf921
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+
+ handlebars v2.0.0
+
+Copyright (C) 2011-2014 by Yehuda Katz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+@license
+*/
+!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.Handlebars=a.Handlebars||b()}(this,function(){var a=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=function(){return""+this.string},b=a}(),b=function(a){"use strict";function b(a){return i[a]}function c(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])Object.prototype.hasOwnProperty.call(arguments[b],c)&&(a[c]=arguments[b][c]);return a}function d(a){return a instanceof h?a.toString():null==a?"":a?(a=""+a,k.test(a)?a.replace(j,b):a):a+""}function e(a){return a||0===a?n(a)&&0===a.length?!0:!1:!0}function f(a,b){return(a?a+".":"")+b}var g={},h=a,i={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},j=/[&<>"'`]/g,k=/[&<>"'`]/;g.extend=c;var l=Object.prototype.toString;g.toString=l;var m=function(a){return"function"==typeof a};m(/x/)&&(m=function(a){return"function"==typeof a&&"[object Function]"===l.call(a)});var m;g.isFunction=m;var n=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===l.call(a):!1};return g.isArray=n,g.escapeExpression=d,g.isEmpty=e,g.appendContextPath=f,g}(a),c=function(){"use strict";function a(a,b){var d;b&&b.firstLine&&(d=b.firstLine,a+=" - "+d+":"+b.firstColumn);for(var e=Error.prototype.constructor.call(this,a),f=0;f<c.length;f++)this[c[f]]=e[c[f]];d&&(this.lineNumber=d,this.column=b.firstColumn)}var b,c=["description","fileName","lineNumber","message","name","number","stack"];return a.prototype=new Error,b=a}(),d=function(a,b){"use strict";function c(a,b){this.helpers=a||{},this.partials=b||{},d(this)}function d(a){a.registerHelper("helperMissing",function(){if(1===arguments.length)return void 0;throw new g("Missing helper: '"+arguments[arguments.length-1].name+"'")}),a.registerHelper("blockHelperMissing",function(b,c){var d=c.inverse,e=c.fn;if(b===!0)return e(this);if(b===!1||null==b)return d(this);if(k(b))return b.length>0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):d(this);if(c.data&&c.ids){var g=q(c.data);g.contextPath=f.appendContextPath(c.data.contextPath,c.name),c={data:g}}return e(b,c)}),a.registerHelper("each",function(a,b){if(!b)throw new g("Must pass iterator to #each");var c,d,e=b.fn,h=b.inverse,i=0,j="";if(b.data&&b.ids&&(d=f.appendContextPath(b.data.contextPath,b.ids[0])+"."),l(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&"object"==typeof a)if(k(a))for(var m=a.length;m>i;i++)c&&(c.index=i,c.first=0===i,c.last=i===a.length-1,d&&(c.contextPath=d+i)),j+=e(a[i],{data:c});else for(var n in a)a.hasOwnProperty(n)&&(c&&(c.key=n,c.index=i,c.first=0===i,d&&(c.contextPath=d+n)),j+=e(a[n],{data:c}),i++);return 0===i&&(j=h(this)),j}),a.registerHelper("if",function(a,b){return l(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||f.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){l(a)&&(a=a.call(this));var c=b.fn;if(f.isEmpty(a))return b.inverse(this);if(b.data&&b.ids){var d=q(b.data);d.contextPath=f.appendContextPath(b.data.contextPath,b.ids[0]),b={data:d}}return c(a,b)}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)}),a.registerHelper("lookup",function(a,b){return a&&a[b]})}var e={},f=a,g=b,h="2.0.0";e.VERSION=h;var i=6;e.COMPILER_REVISION=i;var j={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1"};e.REVISION_CHANGES=j;var k=f.isArray,l=f.isFunction,m=f.toString,n="[object Object]";e.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:o,log:p,registerHelper:function(a,b){if(m.call(a)===n){if(b)throw new g("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){m.call(a)===n?f.extend(this.partials,a):this.partials[a]=b},unregisterPartial:function(a){delete this.partials[a]}};var o={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(o.level<=a){var c=o.methodMap[a];"undefined"!=typeof console&&console[c]&&console[c].call(console,b)}}};e.logger=o;var p=o.log;e.log=p;var q=function(a){var b=f.extend({},a);return b._parent=a,b};return e.createFrame=q,e}(b,c),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=m;if(b!==c){if(c>b){var d=n[c],e=n[b];throw new l("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new l("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new l("No environment passed to template");if(!a||!a.main)throw new l("Unknown template object: "+typeof a);b.VM.checkRevision(a.compiler);var c=function(c,d,e,f,g,h,i,j,m){g&&(f=k.extend({},f,g));var n=b.VM.invokePartial.call(this,c,e,f,h,i,j,m);if(null==n&&b.compile){var o={helpers:h,partials:i,data:j,depths:m};i[e]=b.compile(c,{data:void 0!==j,compat:a.compat},b),n=i[e](f,o)}if(null!=n){if(d){for(var p=n.split("\n"),q=0,r=p.length;r>q&&(p[q]||q+1!==r);q++)p[q]=d+p[q];n=p.join("\n")}return n}throw new l("The partial "+e+" could not be compiled when running in runtime-only mode")},d={lookup:function(a,b){for(var c=a.length,d=0;c>d;d++)if(a[d]&&null!=a[d][b])return a[d][b]},lambda:function(a,b){return"function"==typeof a?a.call(b):a},escapeExpression:k.escapeExpression,invokePartial:c,fn:function(b){return a[b]},programs:[],program:function(a,b,c){var d=this.programs[a],e=this.fn(a);return b||c?d=f(this,a,e,b,c):d||(d=this.programs[a]=f(this,a,e)),d},data:function(a,b){for(;a&&b--;)a=a._parent;return a},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=k.extend({},b,a)),c},noop:b.VM.noop,compilerInfo:a.compiler},e=function(b,c){c=c||{};var f=c.data;e._setup(c),!c.partial&&a.useData&&(f=i(b,f));var g;return a.useDepths&&(g=c.depths?[b].concat(c.depths):[b]),a.main.call(d,b,d.helpers,d.partials,f,g)};return e.isTop=!0,e._setup=function(c){c.partial?(d.helpers=c.helpers,d.partials=c.partials):(d.helpers=d.merge(c.helpers,b.helpers),a.usePartial&&(d.partials=d.merge(c.partials,b.partials)))},e._child=function(b,c,e){if(a.useDepths&&!e)throw new l("must pass parent depths");return f(d,b,a[b],c,e)},e}function f(a,b,c,d,e){var f=function(b,f){return f=f||{},c.call(a,b,a.helpers,a.partials,f.data||d,e&&[b].concat(e))};return f.program=b,f.depth=e?e.length:0,f}function g(a,b,c,d,e,f,g){var h={partial:!0,helpers:d,partials:e,data:f,depths:g};if(void 0===a)throw new l("The partial "+b+" could not be found");return a instanceof Function?a(c,h):void 0}function h(){return""}function i(a,b){return b&&"root"in b||(b=b?o(b):{},b.root=a),b}var j={},k=a,l=b,m=c.COMPILER_REVISION,n=c.REVISION_CHANGES,o=c.createFrame;return j.checkRevision=d,j.template=e,j.program=f,j.invokePartial=g,j.noop=h,j}(b,c,d),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.escapeExpression=j.escapeExpression,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,m["default"]=m,f=m}(d,a,c,b,e),g=function(a){"use strict";function b(a){a=a||{},this.firstLine=a.first_line,this.firstColumn=a.first_column,this.lastColumn=a.last_column,this.lastLine=a.last_line}var c,d=a,e={ProgramNode:function(a,c,d){b.call(this,d),this.type="program",this.statements=a,this.strip=c},MustacheNode:function(a,c,d,f,g){if(b.call(this,g),this.type="mustache",this.strip=f,null!=d&&d.charAt){var h=d.charAt(3)||d.charAt(2);this.escaped="{"!==h&&"&"!==h}else this.escaped=!!d;this.sexpr=a instanceof e.SexprNode?a:new e.SexprNode(a,c),this.id=this.sexpr.id,this.params=this.sexpr.params,this.hash=this.sexpr.hash,this.eligibleHelper=this.sexpr.eligibleHelper,this.isHelper=this.sexpr.isHelper},SexprNode:function(a,c,d){b.call(this,d),this.type="sexpr",this.hash=c;var e=this.id=a[0],f=this.params=a.slice(1);this.isHelper=!(!f.length&&!c),this.eligibleHelper=this.isHelper||e.isSimple},PartialNode:function(a,c,d,e,f){b.call(this,f),this.type="partial",this.partialName=a,this.context=c,this.hash=d,this.strip=e,this.strip.inlineStandalone=!0},BlockNode:function(a,c,d,e,f){b.call(this,f),this.type="block",this.mustache=a,this.program=c,this.inverse=d,this.strip=e,d&&!c&&(this.isInverse=!0)},RawBlockNode:function(a,c,f,g){if(b.call(this,g),a.sexpr.id.original!==f)throw new d(a.sexpr.id.original+" doesn't match "+f,this);c=new e.ContentNode(c,g),this.type="block",this.mustache=a,this.program=new e.ProgramNode([c],{},g)},ContentNode:function(a,c){b.call(this,c),this.type="content",this.original=this.string=a},HashNode:function(a,c){b.call(this,c),this.type="hash",this.pairs=a},IdNode:function(a,c){b.call(this,c),this.type="ID";for(var e="",f=[],g=0,h="",i=0,j=a.length;j>i;i++){var k=a[i].part;if(e+=(a[i].separator||"")+k,".."===k||"."===k||"this"===k){if(f.length>0)throw new d("Invalid path: "+e,this);".."===k?(g++,h+="../"):this.isScoped=!0}else f.push(k)}this.original=e,this.parts=f,this.string=f.join("."),this.depth=g,this.idName=h+this.string,this.isSimple=1===a.length&&!this.isScoped&&0===g,this.stringModeValue=this.string},PartialNameNode:function(a,c){b.call(this,c),this.type="PARTIAL_NAME",this.name=a.original},DataNode:function(a,c){b.call(this,c),this.type="DATA",this.id=a,this.stringModeValue=a.stringModeValue,this.idName="@"+a.stringModeValue},StringNode:function(a,c){b.call(this,c),this.type="STRING",this.original=this.string=this.stringModeValue=a},NumberNode:function(a,c){b.call(this,c),this.type="NUMBER",this.original=this.number=a,this.stringModeValue=Number(a)},BooleanNode:function(a,c){b.call(this,c),this.type="BOOLEAN",this.bool=a,this.stringModeValue="true"===a},CommentNode:function(a,c){b.call(this,c),this.type="comment",this.comment=a,this.strip={inlineStandalone:!0}}};return c=e}(c),h=function(){"use strict";var a,b=function(){function a(){this.yy={}}var b={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,CONTENT:12,COMMENT:13,openRawBlock:14,END_RAW_BLOCK:15,OPEN_RAW_BLOCK:16,sexpr:17,CLOSE_RAW_BLOCK:18,openBlock:19,block_option0:20,closeBlock:21,openInverse:22,block_option1:23,OPEN_BLOCK:24,CLOSE:25,OPEN_INVERSE:26,inverseAndProgram:27,INVERSE:28,OPEN_ENDBLOCK:29,path:30,OPEN:31,OPEN_UNESCAPED:32,CLOSE_UNESCAPED:33,OPEN_PARTIAL:34,partialName:35,param:36,partial_option0:37,partial_option1:38,sexpr_repetition0:39,sexpr_option0:40,dataName:41,STRING:42,NUMBER:43,BOOLEAN:44,OPEN_SEXPR:45,CLOSE_SEXPR:46,hash:47,hash_repetition_plus0:48,hashSegment:49,ID:50,EQUALS:51,DATA:52,pathSegments:53,SEP:54,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]],performAction:function(a,b,c,d,e,f){var g=f.length-1;switch(e){case 1:return d.prepareProgram(f[g-1].statements,!0),f[g-1];case 2:this.$=new d.ProgramNode(d.prepareProgram(f[g]),{},this._$);break;case 3:this.$=f[g];break;case 4:this.$=f[g];break;case 5:this.$=f[g];break;case 6:this.$=f[g];break;case 7:this.$=new d.ContentNode(f[g],this._$);break;case 8:this.$=new d.CommentNode(f[g],this._$);break;case 9:this.$=new d.RawBlockNode(f[g-2],f[g-1],f[g],this._$);break;case 10:this.$=new d.MustacheNode(f[g-1],null,"","",this._$);break;case 11:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!1,this._$);break;case 12:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!0,this._$);break;case 13:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 14:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 15:this.$={strip:d.stripFlags(f[g-1],f[g-1]),program:f[g]};break;case 16:this.$={path:f[g-1],strip:d.stripFlags(f[g-2],f[g])};break;case 17:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 18:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 19:this.$=new d.PartialNode(f[g-3],f[g-2],f[g-1],d.stripFlags(f[g-4],f[g]),this._$);break;case 20:this.$=new d.PartialNode(f[g-2],void 0,f[g-1],d.stripFlags(f[g-3],f[g]),this._$);break;case 21:this.$=new d.SexprNode([f[g-2]].concat(f[g-1]),f[g],this._$);break;case 22:this.$=new d.SexprNode([f[g]],null,this._$);break;case 23:this.$=f[g];break;case 24:this.$=new d.StringNode(f[g],this._$);break;case 25:this.$=new d.NumberNode(f[g],this._$);break;case 26:this.$=new d.BooleanNode(f[g],this._$);break;case 27:this.$=f[g];break;case 28:f[g-1].isHelper=!0,this.$=f[g-1];break;case 29:this.$=new d.HashNode(f[g],this._$);break;case 30:this.$=[f[g-2],f[g]];break;case 31:this.$=new d.PartialNameNode(f[g],this._$);break;case 32:this.$=new d.PartialNameNode(new d.StringNode(f[g],this._$),this._$);break;case 33:this.$=new d.PartialNameNode(new d.NumberNode(f[g],this._$));break;case 34:this.$=new d.DataNode(f[g],this._$);break;case 35:this.$=new d.IdNode(f[g],this._$);break;case 36:f[g-2].push({part:f[g],separator:f[g-1]}),this.$=f[g-2];break;case 37:this.$=[{part:f[g]}];break;case 38:this.$=[];break;case 39:f[g-1].push(f[g]);break;case 48:this.$=[];break;case 49:f[g-1].push(f[g]);break;case 52:this.$=[f[g]];break;case 53:f[g-1].push(f[g])}},table:[{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}],defaultActions:{4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]},parseError:function(a){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:((null===n||"undefined"==typeof n)&&(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;g<f.length&&(c=this._input.match(this.rules[f[g]]),!c||b&&!(c[0].length>b[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substr(a,b.yyleng-c)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 12;break;case 1:return 12;case 2:return this.popState(),12;case 3:return b.yytext=b.yytext.substr(5,b.yyleng-9),this.popState(),15;case 4:return 12;case 5:return e(0,4),this.popState(),13;case 6:return 45;case 7:return 46;case 8:return 16;case 9:return this.popState(),this.begin("raw"),18;case 10:return 34;case 11:return 24;case 12:return 29;case 13:return this.popState(),28;case 14:return this.popState(),28;case 15:return 26;case 16:return 26;case 17:return 32;case 18:return 31;case 19:this.popState(),this.begin("com");break;case 20:return e(3,5),this.popState(),13;case 21:return 31;case 22:return 51;case 23:return 50;case 24:return 50;case 25:return 54;case 26:break;case 27:return this.popState(),33;case 28:return this.popState(),25;case 29:return b.yytext=e(1,2).replace(/\\"/g,'"'),42;case 30:return b.yytext=e(1,2).replace(/\\'/g,"'"),42;case 31:return 52;case 32:return 44;case 33:return 44;case 34:return 43;case 35:return 50;case 36:return b.yytext=e(1,2),50;case 37:return"INVALID";case 38:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[5],inclusive:!1},raw:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,1,38],inclusive:!0}},a}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();return a=b}(),i=function(a){"use strict";function b(a,b){return{left:"~"===a.charAt(2),right:"~"===b.charAt(b.length-3)}}function c(a,b,c,d,i,k){if(a.sexpr.id.original!==d.path.original)throw new j(a.sexpr.id.original+" doesn't match "+d.path.original,a);var l=c&&c.program,m={left:a.strip.left,right:d.strip.right,openStandalone:f(b.statements),closeStandalone:e((l||b).statements)};if(a.strip.right&&g(b.statements,null,!0),l){var n=c.strip;n.left&&h(b.statements,null,!0),n.right&&g(l.statements,null,!0),d.strip.left&&h(l.statements,null,!0),e(b.statements)&&f(l.statements)&&(h(b.statements),g(l.statements))}else d.strip.left&&h(b.statements,null,!0);return i?new this.BlockNode(a,l,b,m,k):new this.BlockNode(a,b,l,m,k)}function d(a,b){for(var c=0,d=a.length;d>c;c++){var i=a[c],j=i.strip;if(j){var k=e(a,c,b,"partial"===i.type),l=f(a,c,b),m=j.openStandalone&&k,n=j.closeStandalone&&l,o=j.inlineStandalone&&k&&l;j.right&&g(a,c,!0),j.left&&h(a,c,!0),o&&(g(a,c),h(a,c)&&"partial"===i.type&&(i.indent=/([ \t]+$)/.exec(a[c-1].original)?RegExp.$1:"")),m&&(g((i.program||i.inverse).statements),h(a,c)),n&&(g(a,c),h((i.inverse||i.program).statements))}}return a}function e(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"content"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function f(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"content"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function g(a,b,c){var d=a[null==b?0:b+1];if(d&&"content"===d.type&&(c||!d.rightStripped)){var e=d.string;d.string=d.string.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.string!==e}}function h(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"content"===d.type&&(c||!d.leftStripped)){var e=d.string;return d.string=d.string.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.string!==e,d.leftStripped}}var i={},j=a;return i.stripFlags=b,i.prepareBlock=c,i.prepareProgram=d,i}(c),j=function(a,b,c,d){"use strict";function e(a){return a.constructor===h.ProgramNode?a:(g.yy=k,g.parse(a))}var f={},g=a,h=b,i=c,j=d.extend;f.parser=g;var k={};return j(k,i,h),f.parse=e,f}(h,g,i,b),k=function(a,b){"use strict";function c(){}function d(a,b,c){if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function e(a,b,c){function d(){var d=c.parse(a),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var e,f=function(a,b){return e||(e=d()),e.call(this,a,b)};return f._setup=function(a){return e||(e=d()),e._setup(a)},f._child=function(a,b,c){return e||(e=d()),e._child(a,b,c)},f}function f(a,b){if(a===b)return!0;if(i(a)&&i(b)&&a.length===b.length){for(var c=0;c<a.length;c++)if(!f(a[c],b[c]))return!1;return!0}}var g={},h=a,i=b.isArray,j=[].slice;return g.Compiler=c,c.prototype={compiler:c,equals:function(a){var b=this.opcodes.length;if(a.opcodes.length!==b)return!1;for(var c=0;b>c;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||!f(d.args,e.args))return!1}for(b=this.children.length,c=0;b>c;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){this.opcodes=[],this.children=[],this.depths={list:[]},this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds;var c=this.options.knownHelpers;if(this.options.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},c)for(var d in c)this.options.knownHelpers[d]=c[d];return this.accept(a)},accept:function(a){return this[a.type](a)},program:function(a){for(var b=a.statements,c=0,d=b.length;d>c;c++)this.accept(b[c]);return this.isSimple=1===d,this.depths.list=this.depths.list.sort(function(a,b){return a-b}),this},compileProgram:function(a){var b,c=(new this.compiler).compile(a,this.options),d=this.guid++;
+this.usePartial=this.usePartial||c.usePartial,this.children[d]=c;for(var e=0,f=c.depths.list.length;f>e;e++)b=c.depths.list[e],2>b||this.addDepth(b-1);return d},block:function(a){var b=a.mustache,c=a.program,d=a.inverse;c&&(c=this.compileProgram(c)),d&&(d=this.compileProgram(d));var e=b.sexpr,f=this.classifySexpr(e);"helper"===f?this.helperSexpr(e,c,d):"simple"===f?(this.simpleSexpr(e),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("blockValue",e.id.original)):(this.ambiguousSexpr(e,c,d),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},hash:function(a){var b,c,d=a.pairs;for(this.opcode("pushHash"),b=0,c=d.length;c>b;b++)this.pushParam(d[b][1]);for(;b--;)this.opcode("assignToHash",d[b][0]);this.opcode("popHash")},partial:function(a){var b=a.partialName;this.usePartial=!0,a.hash?this.accept(a.hash):this.opcode("push","undefined"),a.context?this.accept(a.context):(this.opcode("getContext",0),this.opcode("pushContext")),this.opcode("invokePartial",b.name,a.indent||""),this.opcode("append")},content:function(a){a.string&&this.opcode("appendContent",a.string)},mustache:function(a){this.sexpr(a.sexpr),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},ambiguousSexpr:function(a,b,c){var d=a.id,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.ID(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.id;"DATA"===b.type?this.DATA(b):b.parts.length?this.ID(b):(this.addDepth(b.depth),this.opcode("getContext",b.depth),this.opcode("pushContext")),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.id,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new h("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.falsy=!0,this.ID(e),this.opcode("invokeHelper",d.length,e.original,e.isSimple)}},sexpr:function(a){var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ID:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0];b?this.opcode("lookupOnContext",a.parts,a.falsy,a.isScoped):this.opcode("pushContext")},DATA:function(a){this.options.data=!0,this.opcode("lookupData",a.id.depth,a.id.parts)},STRING:function(a){this.opcode("pushString",a.string)},NUMBER:function(a){this.opcode("pushLiteral",a.number)},BOOLEAN:function(a){this.opcode("pushLiteral",a.bool)},comment:function(){},opcode:function(a){this.opcodes.push({opcode:a,args:j.call(arguments,1)})},addDepth:function(a){0!==a&&(this.depths[a]||(this.depths[a]=!0,this.depths.list.push(a)))},classifySexpr:function(a){var b=a.isHelper,c=a.eligibleHelper,d=this.options;if(c&&!b){var e=a.id.parts[0];d.knownHelpers[e]?b=!0:d.knownHelpersOnly&&(c=!1)}return b?"helper":c?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;c>b;b++)this.pushParam(a[b])},pushParam:function(a){this.stringParams?(a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",a.stringModeValue,a.type),"sexpr"===a.type&&this.sexpr(a)):(this.trackIds&&this.opcode("pushId",a.type,a.idName||a.stringModeValue),this.accept(a))},setupFullMustacheParams:function(a,b,c){var d=a.params;return this.pushParams(d),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.hash(a.hash):this.opcode("emptyHash"),d}},g.precompile=d,g.compile=e,g}(c,b),l=function(a,b){"use strict";function c(a){this.value=a}function d(){}var e,f=a.COMPILER_REVISION,g=a.REVISION_CHANGES,h=b;d.prototype={nameLookup:function(a,b){return d.isValidJavaScriptVariableName(b)?a+"."+b:a+"['"+b+"']"},depthedLookup:function(a){return this.aliases.lookup="this.lookup",'lookup(depths, "'+a+'")'},compilerInfo:function(){var a=f,b=g[a];return[a,b]},appendToBuffer:function(a){return this.environment.isSimple?"return "+a+";":{appendToBuffer:!0,content:a,toString:function(){return"buffer += "+a+";"}}},initializeBuffer:function(){return this.quotedString("")},namespace:"Handlebars",compile:function(a,b,c,d){this.environment=a,this.options=b,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,this.name=this.environment.name,this.isChild=!!c,this.context=c||{programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.compileChildren(a,b),this.useDepths=this.useDepths||a.depths.list.length||this.options.compat;var e,f,g,i=a.opcodes;for(f=0,g=i.length;g>f;f++)e=i[f],this[e.opcode].apply(this,e.args);if(this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new h("Compile completed with content left on stack");var j=this.createFunctionContext(d);if(this.isChild)return j;var k={compiler:this.compilerInfo(),main:j},l=this.context.programs;for(f=0,g=l.length;g>f;f++)l[f]&&(k[f]=l[f]);return this.environment.usePartial&&(k.usePartial=!0),this.options.data&&(k.useData=!0),this.useDepths&&(k.useDepths=!0),this.options.compat&&(k.compat=!0),d||(k.compiler=JSON.stringify(k.compiler),k=this.objectLiteral(k)),k},preamble:function(){this.lastContext=0,this.source=[]},createFunctionContext:function(a){var b="",c=this.stackVars.concat(this.registers.list);c.length>0&&(b+=", "+c.join(", "));for(var d in this.aliases)this.aliases.hasOwnProperty(d)&&(b+=", "+d+"="+this.aliases[d]);var e=["depth0","helpers","partials","data"];this.useDepths&&e.push("depths");var f=this.mergeSource(b);return a?(e.push(f),Function.apply(this,e)):"function("+e.join(",")+") {\n  "+f+"}"},mergeSource:function(a){for(var b,c,d="",e=!this.forceBuffer,f=0,g=this.source.length;g>f;f++){var h=this.source[f];h.appendToBuffer?b=b?b+"\n    + "+h.content:h.content:(b&&(d?d+="buffer += "+b+";\n  ":(c=!0,d=b+";\n  "),b=void 0),d+=h+"\n  ",this.environment.isSimple||(e=!1))}return e?(b||!d)&&(d+="return "+(b||'""')+";\n"):(a+=", buffer = "+(c?"":this.initializeBuffer()),d+=b?"return buffer + "+b+";\n":"return buffer;\n"),a&&(d="var "+a.substring(2)+(c?"":";\n  ")+d),d},blockValue:function(a){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var b=[this.contextName(0)];this.setupParams(a,0,b);var c=this.popStack();b.splice(1,0,c),this.push("blockHelperMissing.call("+b.join(", ")+")")},ambiguousBlockValue:function(){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var a=[this.contextName(0)];this.setupParams("",0,a,!0),this.flushInline();var b=this.topStack();a.splice(1,0,b),this.pushSource("if (!"+this.lastHelper+") { "+b+" = blockHelperMissing.call("+a.join(", ")+"); }")},appendContent:function(a){this.pendingContent&&(a=this.pendingContent+a),this.pendingContent=a},append:function(){this.flushInline();var a=this.popStack();this.pushSource("if ("+a+" != null) { "+this.appendToBuffer(a)+" }"),this.environment.isSimple&&this.pushSource("else { "+this.appendToBuffer("''")+" }")},appendEscaped:function(){this.aliases.escapeExpression="this.escapeExpression",this.pushSource(this.appendToBuffer("escapeExpression("+this.popStack()+")"))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c){var d=0,e=a.length;for(c||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[d++]));e>d;d++)this.replaceStack(function(c){var e=this.nameLookup(c,a[d],"context");return b?" && "+e:" != null ? "+e+" : "+c})},lookupData:function(a,b){a?this.pushStackLiteral("this.data(data, "+a+")"):this.pushStackLiteral("data");for(var c=b.length,d=0;c>d;d++)this.replaceStack(function(a){return" && "+this.nameLookup(a,b[d],"data")})},resolvePossibleLambda:function(){this.aliases.lambda="this.lambda",this.push("lambda("+this.popStack()+", "+this.contextName(0)+")")},pushStringParam:function(a,b){this.pushContext(),this.pushString(b),"sexpr"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(){this.pushStackLiteral("{}"),this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}"))},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push("{"+a.ids.join(",")+"}"),this.stringParams&&(this.push("{"+a.contexts.join(",")+"}"),this.push("{"+a.types.join(",")+"}")),this.push("{\n    "+a.values.join(",\n    ")+"\n  }")},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},push:function(a){return this.inlineStack.push(a),a},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){null!=a?this.pushStackLiteral(this.programExpression(a)):this.pushStackLiteral(null)},invokeHelper:function(a,b,c){this.aliases.helperMissing="helpers.helperMissing";var d=this.popStack(),e=this.setupHelper(a,b),f=(c?e.name+" || ":"")+d+" || helperMissing";this.push("(("+f+").call("+e.callParams+"))")},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(c.name+".call("+c.callParams+")")},invokeAmbiguous:function(a,b){this.aliases.functionType='"function"',this.aliases.helperMissing="helpers.helperMissing",this.useRegister("helper");var c=this.popStack();this.emptyHash();var d=this.setupHelper(0,a,b),e=this.lastHelper=this.nameLookup("helpers",a,"helper");this.push("((helper = (helper = "+e+" || "+c+") != null ? helper : helperMissing"+(d.paramsInit?"),("+d.paramsInit:"")+"),(typeof helper === functionType ? helper.call("+d.callParams+") : helper))")},invokePartial:function(a,b){var c=[this.nameLookup("partials",a,"partial"),"'"+b+"'","'"+a+"'",this.popStack(),this.popStack(),"helpers","partials"];this.options.data?c.push("data"):this.options.compat&&c.push("undefined"),this.options.compat&&c.push("depths"),this.push("this.invokePartial("+c.join(", ")+")")},assignToHash:function(a){var b,c,d,e=this.popStack();this.trackIds&&(d=this.popStack()),this.stringParams&&(c=this.popStack(),b=this.popStack());var f=this.hash;b&&f.contexts.push("'"+a+"': "+b),c&&f.types.push("'"+a+"': "+c),d&&f.ids.push("'"+a+"': "+d),f.values.push("'"+a+"': ("+e+")")},pushId:function(a,b){"ID"===a||"DATA"===a?this.pushString(b):"sexpr"===a?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:d,compileChildren:function(a,b){for(var c,d,e=a.children,f=0,g=e.length;g>f;f++){c=e[f],d=new this.compiler;var h=this.matchExistingProgram(c);null==h?(this.context.programs.push(""),h=this.context.programs.length,c.index=h,c.name="program"+h,this.context.programs[h]=d.compile(c,b,this.context,!this.precompile),this.context.environments[h]=c,this.useDepths=this.useDepths||d.useDepths):(c.index=h,c.name="program"+h)}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;c>b;b++){var d=this.context.environments[b];if(d&&d.equals(a))return b}},programExpression:function(a){var b=this.environment.children[a],c=(b.depths.list,this.useDepths),d=[b.index,"data"];return c&&d.push("depths"),"this.program("+d.join(", ")+")"},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},pushStackLiteral:function(a){return this.push(new c(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent))),this.pendingContent=void 0),a&&this.source.push(a)},pushStack:function(a){this.flushInline();var b=this.incrStack();return this.pushSource(b+" = "+a+";"),this.compileStack.push(b),b},replaceStack:function(a){{var b,d,e,f="";this.isInline()}if(!this.isInline())throw new h("replaceStack on non-inline");var g=this.popStack(!0);if(g instanceof c)f=b=g.value,e=!0;else{d=!this.stackSlot;var i=d?this.incrStack():this.topStackName();f="("+this.push(i)+" = "+g+")",b=this.topStack()}var j=a.call(this,b);e||this.popStack(),d&&this.stackSlot--,this.push("("+f+j+")")},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;if(a.length){this.inlineStack=[];for(var b=0,d=a.length;d>b;b++){var e=a[b];e instanceof c?this.compileStack.push(e):this.pushStack(e)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),d=(b?this.inlineStack:this.compileStack).pop();if(!a&&d instanceof c)return d.value;if(!b){if(!this.stackSlot)throw new h("Invalid stack pop");this.stackSlot--}return d},topStack:function(){var a=this.isInline()?this.inlineStack:this.compileStack,b=a[a.length-1];return b instanceof c?b.value:b},contextName:function(a){return this.useDepths&&a?"depths["+a+"]":"depth"+a},quotedString:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(this.quotedString(c)+":"+a[c]);return"{"+b.join(",")+"}"},setupHelper:function(a,b,c){var d=[],e=this.setupParams(b,a,d,c),f=this.nameLookup("helpers",b,"helper");return{params:d,paramsInit:e,name:f,callParams:[this.contextName(0)].concat(d).join(", ")}},setupOptions:function(a,b,c){var d,e,f,g={},h=[],i=[],j=[];g.name=this.quotedString(a),g.hash=this.popStack(),this.trackIds&&(g.hashIds=this.popStack()),this.stringParams&&(g.hashTypes=this.popStack(),g.hashContexts=this.popStack()),e=this.popStack(),f=this.popStack(),(f||e)&&(f||(f="this.noop"),e||(e="this.noop"),g.fn=f,g.inverse=e);for(var k=b;k--;)d=this.popStack(),c[k]=d,this.trackIds&&(j[k]=this.popStack()),this.stringParams&&(i[k]=this.popStack(),h[k]=this.popStack());return this.trackIds&&(g.ids="["+j.join(",")+"]"),this.stringParams&&(g.types="["+i.join(",")+"]",g.contexts="["+h.join(",")+"]"),this.options.data&&(g.data="data"),g},setupParams:function(a,b,c,d){var e=this.objectLiteral(this.setupOptions(a,b,c));return d?(this.useRegister("options"),c.push("options"),"options="+e):(c.push(e),"")}};for(var i="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield".split(" "),j=d.RESERVED_WORDS={},k=0,l=i.length;l>k;k++)j[i[k]]=!0;return d.isValidJavaScriptVariableName=function(a){return!d.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},e=d}(d,c),m=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c.parser,j=c.parse,k=d.Compiler,l=d.compile,m=d.precompile,n=e,o=g.create,p=function(){var a=o();return a.compile=function(b,c){return l(b,c,a)},a.precompile=function(b,c){return m(b,c,a)},a.AST=h,a.Compiler=k,a.JavaScriptCompiler=n,a.Parser=i,a.parse=j,a};return g=p(),g.create=p,g["default"]=g,f=g}(f,g,j,k,l);return m});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack.js b/src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack.js
new file mode 100644 (file)
index 0000000..928386d
--- /dev/null
@@ -0,0 +1,2 @@
+/*! highlight.js v9.1.0 | BSD3 License | git.io/hljslicense */
+!function(e){"undefined"!=typeof exports?e(exports):(self.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return self.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:"start"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value)+'"'}l+="<"+t(e)+Array.prototype.map.call(e.attributes,r).join("")+">"}function u(e){l+="</"+t(e)+">"}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(o)}else"start"==g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":x.classPrefix,i='<span class="'+a,o=t?"":"</span>";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(M);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!R[L.sL])return n(M);var t=e?l(L.sL,M,!0,y[L.sL]):f(M,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(y[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,M=""):e.eB?(k+=n(t)+r,M=""):(k+=r,M=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(M+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(M+=t),k+=b();do L.cN&&(k+="</span>"),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),M="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"<unnamed>")+'"');return M+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,L=i||N,y={},k="";for(w=L;w!=N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var M="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),w=L;w.parent;w=w.parent)w.cN&&(k+="</span>");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function f(e,t){t=t||x.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return x.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,x.tabReplace)})),x.useBR&&(e=e.replace(/\n/g,"<br>")),e}function h(e,n,t){var r=n?w[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;x.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var r=t.textContent,o=n?l(n,r,!0):f(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){x=o(x,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){w[e]=n})}function N(){return Object.keys(R)}function E(e){return e=(e||"").toLowerCase(),R[e]||R[w[e]]}var x={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},w={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:i,k:t},s={b:"{",e:"}",c:[{cN:"attr",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:r}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return i.splice(i.length,0,s,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("xml",function(s){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},r={eW:!0,i:/</,r:0,c:[e,{cN:"attr",b:t,r:0},{b:"=",r:0,c:[{cN:"string",c:[e],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("<!--","-->",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[r],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[r],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},e,{cN:"meta",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},r]}]}});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\s*\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack_extended.js b/src/main/resources/META-INF/resources/icd/lib/highlight.9.1.0.pack_extended.js
new file mode 100644 (file)
index 0000000..571c740
--- /dev/null
@@ -0,0 +1,34 @@
+'use strict';
+
+(function () {
+    var configure, highlightBlock;
+
+    configure = hljs.configure;
+    // "extending" hljs.configure method
+    hljs.configure = function _configure (options) {
+        var size = options.highlightSizeThreshold;
+
+        // added highlightSizeThreshold option to set maximum size
+        // of processed string. Set to null if not a number
+        hljs.highlightSizeThreshold = size === +size ? size : null;
+
+        configure.call(this, options);
+    };
+
+    highlightBlock = hljs.highlightBlock;
+
+    // "extending" hljs.highlightBlock method
+    hljs.highlightBlock = function _highlightBlock (el) {
+        var innerHTML = el.innerHTML;
+        var size = hljs.highlightSizeThreshold;
+
+        // check if highlightSizeThreshold is not set or element innerHTML
+        // is less than set option highlightSizeThreshold
+        if (size == null || size > innerHTML.length) {
+            // proceed with hljs.highlightBlock
+            highlightBlock.call(hljs, el);
+        }
+    };
+
+})();
+
diff --git a/src/main/resources/META-INF/resources/icd/lib/jquery-1.8.0.min.js b/src/main/resources/META-INF/resources/icd/lib/jquery-1.8.0.min.js
new file mode 100644 (file)
index 0000000..066d72c
--- /dev/null
@@ -0,0 +1,2 @@
+/*! jQuery v@1.8.0 jquery.com | jquery.org/license */
+(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bX(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bV.length;while(e--){b=bV[e]+c;if(b in a)return b}return d}function bY(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function bZ(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bY(c)&&(e[f]=p._data(c,"olddisplay",cb(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b$(a,b,c){var d=bO.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function b_(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bU[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bU[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bU[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bU[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bU[e]+"Width"))||0));return f}function ca(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bP.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+b_(a,b,c||(f?"border":"content"),e)+"px"}function cb(a){if(bR[a])return bR[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cz(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cu;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cz(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cz(a,c,d,e,"*",g)),h}function cA(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cB(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cC(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cK(){try{return new a.XMLHttpRequest}catch(b){}}function cL(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cT(){return setTimeout(function(){cM=b},0),cM=p.now()}function cU(a,b){p.each(b,function(b,c){var d=(cS[b]||[]).concat(cS["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cV(a,b,c){var d,e=0,f=0,g=cR.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cM||cT(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cM||cT(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cW(k,j.opts.specialEasing);for(;e<g;e++){d=cR[e].call(j,a,k,j.opts);if(d)return d}return cU(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cW(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cX(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bY(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cb(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cO.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cY(a,b,c,d,e){return new cY.prototype.init(a,b,c,d,e)}function cZ(a,b){var c,d={height:a},e=0;for(;e<4;e+=2-b)c=bU[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function c_(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=r.test(" ")?/^[\s\xA0]+|[\s\xA0]+$/g:/^\s+|\s+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":a.toString().replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||f.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete"||e.readyState!=="loading"&&e.addEventListener)setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){p.isFunction(c)&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")===0&&(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)(d=p._data(g[h],a+"queueHooks"))&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)~f.indexOf(" "+b[g]+" ")||(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,k,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=[].slice.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click")){g=p(this),g.context=this;for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){i={},k=[],g[0]=f;for(d=0;d<q;d++)l=o[d],m=l.selector,i[m]===b&&(i[m]=g.is(m)),i[m]&&k.push(l);k.length&&u.push({elem:f,matches:k})}}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){j=u[d],c.currentTarget=j.elem;for(e=0;e<j.matches.length&&!c.isImmediatePropagationStopped();e++){l=j.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,h=((p.event.special[l.origType]||{}).handle||l.handler).apply(j.elem,r),h!==b&&(c.result=h,h===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{ready:{setup:p.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.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(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)Z(a,b[e],c,d)}function be(a,b,c,d,e,f){var g,h=$.setFilters[b.toLowerCase()];return h||Z.error(b),(a||!(g=e))&&bd(a||"*",d,g=[],e),g.length>0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;a<c;a++)arguments[a]===b&&(g[a]=b)};for(;p<q;p++){s.exec(""),a=f[p],j=[],i=0,k=e;while(g=s.exec(a)){n=s.lastIndex=g.index+g[0].length;if(n>i){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}function bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+|((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="<a name='"+q+"'></a><div name='"+q+"'></div>",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for(h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){var d=[],e=c?1:0,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},odd:function(a,b,c){var d=[],e=c?0:1,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},lt:function(a,b,c){return c?a.slice(+b):a.slice(0,+b)},gt:function(a,b,c){return c?a.slice(0,+b+1):a.slice(+b+1)},eq:function(a,b,c){var d=a.splice(+b,1);return c?a:d}}};$.setFilters.nth=$.setFilters.eq,$.filters=$.pseudos,X||($.attrHandle={href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}}),V&&($.order.push("NAME"),$.find.NAME=function(a,b){if(typeof b.getElementsByName!==j)return b.getElementsByName(a)}),Y&&($.order.splice(1,0,"CLASS"),$.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!==j&&!c)return b.getElementsByClassName(a)});try{n.call(i.childNodes,0)[0].nodeType}catch(_){n=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}var ba=Z.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},bb=Z.contains=i.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:i.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc=Z.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=bc(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=bc(b);return c};Z.attr=function(a,b){var c,d=ba(a);return d||(b=b.toLowerCase()),$.attrHandle[b]?$.attrHandle[b](a):U||d?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},Z.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},[0,0].sort(function(){return l=0}),i.compareDocumentPosition?e=function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:(e=function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],g=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return f(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)g.unshift(j),j=j.parentNode;c=e.length,d=g.length;for(var l=0;l<c&&l<d;l++)if(e[l]!==g[l])return f(e[l],g[l]);return l===c?f(a,g[l],-1):f(e[l],b,1)},f=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),Z.uniqueSort=function(a){var b,c=1;if(e){k=l,a.sort(e);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1)}return a};var bl=Z.compile=function(a,b,c){var d,e,f,g=O[a];if(g&&g.context===b)return g;e=bg(a,b,c);for(f=0;d=e[f];f++)e[f]=bj(d,b,c);return g=O[a]=bk(e),g.context=b,g.runs=g.dirruns=0,P.push(a),P.length>$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSelector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j<k;j++){p=$.order[j];if(s=L[p].exec(m)){h=$.find[p]((s[1]||"").replace(K,""),q,g);if(h==null)continue;m===r&&(a=a.slice(0,a.length-r.length)+m.replace(L[p],""),a||o.apply(e,n.call(h,0)));break}}}if(a){i=bl(a,b,g),d=i.dirruns++,h==null&&(h=$.find.TAG("*",G.test(a)&&b.parentNode||b));for(j=0;l=h[j];j++)c=i.runs++,i(l,b)&&e.push(l)}return e};h.querySelectorAll&&function(){var a,b=bm,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[],f=[":active"],g=i.matchesSelector||i.mozMatchesSelector||i.webkitMatchesSelector||i.oMatchesSelector||i.msMatchesSelector;T(function(a){a.innerHTML="<select><option selected></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=(c[0]||c).ownerDocument||c[0]||c,typeof c.createDocumentFragment=="undefined"&&(c=e),a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$/,co=/^\/\//,cp=/\?/,cq=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A===l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cS[c]=cS[c]||[],cS[c].unshift(b)},prefilter:function(a,b){b?cR.unshift(a):cR.push(a)}}),p.Tween=cY,cY.prototype={constructor:cY,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cY.propHooks[this.prop];return a&&a.get?a.get(this):cY.propHooks._default.get(this)},run:function(a){var b,c=cY.propHooks[this.prop];return this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration),this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cY.propHooks._default.set(this),this}},cY.prototype.init.prototype=cY.prototype,cY.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cY.propHooks.scrollTop=cY.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(cZ(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bY).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cV(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cQ.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:cZ("show"),slideUp:cZ("hide"),slideToggle:cZ("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cY.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cN&&(cN=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cN),cN=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c$=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j,k,l,m=this[0],n=m&&m.ownerDocument;if(!n)return;return(e=n.body)===m?p.offset.bodyOffset(m):(d=n.documentElement,p.contains(d,m)?(c=m.getBoundingClientRect(),f=c_(n),g=d.clientTop||e.clientTop||0,h=d.clientLeft||e.clientLeft||0,i=f.pageYOffset||d.scrollTop,j=f.pageXOffset||d.scrollLeft,k=c.top+i-g,l=c.left+j-h,{top:k,left:l}):{top:0,left:0})},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c$.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c$.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=c_(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/jquery.ba-bbq.min.js b/src/main/resources/META-INF/resources/icd/lib/jquery.ba-bbq.min.js
new file mode 100644 (file)
index 0000000..bcbf248
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
+ * http://benalman.com/projects/jquery-bbq-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
+/*
+ * jQuery hashchange event - v1.2 - 2/11/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/jquery.slideto.min.js b/src/main/resources/META-INF/resources/icd/lib/jquery.slideto.min.js
new file mode 100644 (file)
index 0000000..ba32cff
--- /dev/null
@@ -0,0 +1 @@
+(function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery);
diff --git a/src/main/resources/META-INF/resources/icd/lib/jquery.wiggle.min.js b/src/main/resources/META-INF/resources/icd/lib/jquery.wiggle.min.js
new file mode 100644 (file)
index 0000000..2adb0d6
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+jQuery Wiggle
+Author: WonderGroup, Jordan Thomas
+URL: http://labs.wondergroup.com/demos/mini-ui/index.html
+License: MIT (http://en.wikipedia.org/wiki/MIT_License)
+*/
+jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);}
+if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});};
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/js-yaml.min.js b/src/main/resources/META-INF/resources/icd/lib/js-yaml.min.js
new file mode 100644 (file)
index 0000000..c3d07ad
--- /dev/null
@@ -0,0 +1,3 @@
+/* js-yaml 3.4.6 https://github.com/nodeca/js-yaml */
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.jsyaml=t()}}(function(){var t;return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)r(i[a]);return r}({1:[function(t,e,n){"use strict";function i(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}var r=t("./js-yaml/loader"),o=t("./js-yaml/dumper");e.exports.Type=t("./js-yaml/type"),e.exports.Schema=t("./js-yaml/schema"),e.exports.FAILSAFE_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.JSON_SCHEMA=t("./js-yaml/schema/json"),e.exports.CORE_SCHEMA=t("./js-yaml/schema/core"),e.exports.DEFAULT_SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_FULL_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.load=r.load,e.exports.loadAll=r.loadAll,e.exports.safeLoad=r.safeLoad,e.exports.safeLoadAll=r.safeLoadAll,e.exports.dump=o.dump,e.exports.safeDump=o.safeDump,e.exports.YAMLException=t("./js-yaml/exception"),e.exports.MINIMAL_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.scan=i("scan"),e.exports.parse=i("parse"),e.exports.compose=i("compose"),e.exports.addConstructor=i("addConstructor")},{"./js-yaml/dumper":3,"./js-yaml/exception":4,"./js-yaml/loader":5,"./js-yaml/schema":7,"./js-yaml/schema/core":8,"./js-yaml/schema/default_full":9,"./js-yaml/schema/default_safe":10,"./js-yaml/schema/failsafe":11,"./js-yaml/schema/json":12,"./js-yaml/type":13}],2:[function(t,e,n){"use strict";function i(t){return"undefined"==typeof t||null===t}function r(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:i(t)?[]:[t]}function a(t,e){var n,i,r,o;if(e)for(o=Object.keys(e),n=0,i=o.length;i>n;n+=1)r=o[n],t[r]=e[r];return t}function s(t,e){var n,i="";for(n=0;e>n;n+=1)i+=t;return i}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}e.exports.isNothing=i,e.exports.isObject=r,e.exports.toArray=o,e.exports.repeat=s,e.exports.isNegativeZero=c,e.exports.extend=a},{}],3:[function(t,e,n){"use strict";function i(t,e){var n,i,r,o,a,s,c;if(null===e)return{};for(n={},i=Object.keys(e),r=0,o=i.length;o>r;r+=1)a=i[r],s=String(e[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),c=t.compiledTypeMap[a],c&&E.call(c.styleAliases,s)&&(s=c.styleAliases[s]),n[a]=s;return n}function r(t){var e,n,i;if(e=t.toString(16).toUpperCase(),255>=t)n="x",i=2;else if(65535>=t)n="u",i=4;else{if(!(4294967295>=t))throw new O("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+j.repeat("0",i-e.length)+e}function o(t){this.schema=t.schema||S,this.indent=Math.max(1,t.indent||2),this.skipInvalid=t.skipInvalid||!1,this.flowLevel=j.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=i(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function a(t,e){for(var n,i=j.repeat(" ",e),r=0,o=-1,a="",s=t.length;s>r;)o=t.indexOf("\n",r),-1===o?(n=t.slice(r),r=s):(n=t.slice(r,o+1),r=o+1),n.length&&"\n"!==n&&(a+=i),a+=n;return a}function s(t,e){return"\n"+j.repeat(" ",t.indent*e)}function c(t,e){var n,i,r;for(n=0,i=t.implicitTypes.length;i>n;n+=1)if(r=t.implicitTypes[n],r.resolve(e))return!0;return!1}function u(t){this.source=t,this.result="",this.checkpoint=0}function l(t,e,n,i){var r,o,s,l,f,m,g,y,v,x,A,b,w,k,C,j,O,S,_,I,E;if(0===e.length)return void(t.dump="''");if(-1!==et.indexOf(e))return void(t.dump="'"+e+"'");for(r=!0,o=e.length?e.charCodeAt(0):0,s=M===o||M===e.charCodeAt(e.length-1),(K===o||W===o||G===o||z===o)&&(r=!1),s?(r=!1,l=!1,f=!1):(l=!i,f=!i),m=!0,g=new u(e),y=!1,v=0,x=0,A=t.indent*n,b=t.lineWidth,-1===b&&(b=9007199254740991),40>A?b-=A:b=40,k=0;k<e.length;k++){if(w=e.charCodeAt(k),r){if(h(w))continue;r=!1}m&&w===P&&(m=!1),C=tt[w],j=d(w),(C||j)&&(w!==N&&w!==D&&w!==P?(l=!1,f=!1):w===N&&(y=!0,m=!1,k>0&&(O=e.charCodeAt(k-1),O===M&&(f=!1,l=!1)),l&&(S=k-v,v=k,S>x&&(x=S))),w!==D&&(m=!1),g.takeUpTo(k),g.escapeChar())}if(r&&c(t,e)&&(r=!1),_="",(l||f)&&(I=0,e.charCodeAt(e.length-1)===N&&(I+=1,e.charCodeAt(e.length-2)===N&&(I+=1)),0===I?_="-":2===I&&(_="+")),f&&b>x&&(l=!1),y||(f=!1),r)t.dump=e;else if(m)t.dump="'"+e+"'";else if(l)E=p(e,b),t.dump=">"+_+"\n"+a(E,A);else if(f)_||(e=e.replace(/\n$/,"")),t.dump="|"+_+"\n"+a(e,A);else{if(!g)throw new Error("Failed to dump scalar value");g.finish(),t.dump='"'+g.result+'"'}}function p(t,e){var n,i="",r=0,o=t.length,a=/\n+$/.exec(t);for(a&&(o=a.index+1);o>r;)n=t.indexOf("\n",r),n>o||-1===n?(i&&(i+="\n\n"),i+=f(t.slice(r,o),e),r=o):(i&&(i+="\n\n"),i+=f(t.slice(r,n),e),r=n+1);return a&&"\n"!==a[0]&&(i+=a[0]),i}function f(t,e){if(""===t)return t;for(var n,i,r,o=/[^\s] [^\s]/g,a="",s=0,c=0,u=o.exec(t);u;)n=u.index,n-c>e&&(i=s!==c?s:n,a&&(a+="\n"),r=t.slice(c,i),a+=r,c=i+1),s=n+1,u=o.exec(t);return a&&(a+="\n"),a+=c!==s&&t.length-c>e?t.slice(c,s)+"\n"+t.slice(s+1):t.slice(c)}function h(t){return F!==t&&N!==t&&T!==t&&B!==t&&V!==t&&Z!==t&&J!==t&&X!==t&&U!==t&&Y!==t&&$!==t&&L!==t&&Q!==t&&R!==t&&P!==t&&D!==t&&q!==t&&H!==t&&!tt[t]&&!d(t)}function d(t){return!(t>=32&&126>=t||133===t||t>=160&&55295>=t||t>=57344&&65533>=t||t>=65536&&1114111>=t)}function m(t,e,n){var i,r,o="",a=t.tag;for(i=0,r=n.length;r>i;i+=1)A(t,e,n[i],!1,!1)&&(0!==i&&(o+=", "),o+=t.dump);t.tag=a,t.dump="["+o+"]"}function g(t,e,n,i){var r,o,a="",c=t.tag;for(r=0,o=n.length;o>r;r+=1)A(t,e+1,n[r],!0,!0)&&(i&&0===r||(a+=s(t,e)),a+="- "+t.dump);t.tag=c,t.dump=a||"[]"}function y(t,e,n){var i,r,o,a,s,c="",u=t.tag,l=Object.keys(n);for(i=0,r=l.length;r>i;i+=1)s="",0!==i&&(s+=", "),o=l[i],a=n[o],A(t,e,o,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+": ",A(t,e,a,!1,!1)&&(s+=t.dump,c+=s));t.tag=u,t.dump="{"+c+"}"}function v(t,e,n,i){var r,o,a,c,u,l,p="",f=t.tag,h=Object.keys(n);if(t.sortKeys===!0)h.sort();else if("function"==typeof t.sortKeys)h.sort(t.sortKeys);else if(t.sortKeys)throw new O("sortKeys must be a boolean or a function");for(r=0,o=h.length;o>r;r+=1)l="",i&&0===r||(l+=s(t,e)),a=h[r],c=n[a],A(t,e+1,a,!0,!0,!0)&&(u=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024,u&&(l+=t.dump&&N===t.dump.charCodeAt(0)?"?":"? "),l+=t.dump,u&&(l+=s(t,e)),A(t,e+1,c,!0,u)&&(l+=t.dump&&N===t.dump.charCodeAt(0)?":":": ",l+=t.dump,p+=l));t.tag=f,t.dump=p||"{}"}function x(t,e,n){var i,r,o,a,s,c;for(r=n?t.explicitTypes:t.implicitTypes,o=0,a=r.length;a>o;o+=1)if(s=r[o],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(t.tag=n?s.tag:"?",s.represent){if(c=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===I.call(s.represent))i=s.represent(e,c);else{if(!E.call(s.represent,c))throw new O("!<"+s.tag+'> tag resolver accepts not "'+c+'" style');i=s.represent[c](e,c)}t.dump=i}return!0}return!1}function A(t,e,n,i,r,o){t.tag=null,t.dump=n,x(t,n,!1)||x(t,n,!0);var a=I.call(t.dump);i&&(i=0>t.flowLevel||t.flowLevel>e);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=t.duplicates.indexOf(n),c=-1!==s),(null!==t.tag&&"?"!==t.tag||c||2!==t.indent&&e>0)&&(r=!1),c&&t.usedDuplicates[s])t.dump="*ref_"+s;else{if(u&&c&&!t.usedDuplicates[s]&&(t.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(t.dump).length?(v(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(y(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else if("[object Array]"===a)i&&0!==t.dump.length?(g(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(m(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else{if("[object String]"!==a){if(t.skipInvalid)return!1;throw new O("unacceptable kind of an object to dump "+a)}"?"!==t.tag&&l(t,t.dump,e,o)}null!==t.tag&&"?"!==t.tag&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function b(t,e){var n,i,r=[],o=[];for(w(t,r,o),n=0,i=o.length;i>n;n+=1)e.duplicates.push(r[o[n]]);e.usedDuplicates=new Array(i)}function w(t,e,n){var i,r,o;if(null!==t&&"object"==typeof t)if(r=e.indexOf(t),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(e.push(t),Array.isArray(t))for(r=0,o=t.length;o>r;r+=1)w(t[r],e,n);else for(i=Object.keys(t),r=0,o=i.length;o>r;r+=1)w(t[i[r]],e,n)}function k(t,e){e=e||{};var n=new o(e);return b(t,n),A(n,0,t,!0,!0)?n.dump+"\n":""}function C(t,e){return k(t,j.extend({schema:_},e))}var j=t("./common"),O=t("./exception"),S=t("./schema/default_full"),_=t("./schema/default_safe"),I=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=9,N=10,T=13,M=32,L=33,D=34,U=35,q=37,Y=38,P=39,$=42,B=44,K=45,H=58,R=62,W=63,G=64,V=91,Z=93,z=96,J=123,Q=124,X=125,tt={};tt[0]="\\0",tt[7]="\\a",tt[8]="\\b",tt[9]="\\t",tt[10]="\\n",tt[11]="\\v",tt[12]="\\f",tt[13]="\\r",tt[27]="\\e",tt[34]='\\"',tt[92]="\\\\",tt[133]="\\N",tt[160]="\\_",tt[8232]="\\L",tt[8233]="\\P";var et=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(t){var e;if(t<this.checkpoint)throw e=new Error("position should be > checkpoint"),e.position=t,e.checkpoint=this.checkpoint,e;return this.result+=this.source.slice(this.checkpoint,t),this.checkpoint=t,this},u.prototype.escapeChar=function(){var t,e;return t=this.source.charCodeAt(this.checkpoint),e=tt[t]||r(t),this.result+=e,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},e.exports.dump=k,e.exports.safeDump=C},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(t,e,n){"use strict";function i(t,e){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}var r=t("inherit");r(i,Error),i.prototype.toString=function(t){var e=this.name+": ";return e+=this.reason||"(unknown reason)",!t&&this.mark&&(e+=" "+this.mark.toString()),e},e.exports=i},{inherit:31}],5:[function(t,e,n){"use strict";function i(t){return 10===t||13===t}function r(t){return 9===t||32===t}function o(t){return 9===t||32===t||10===t||13===t}function a(t){return 44===t||91===t||93===t||123===t||125===t}function s(t){var e;return t>=48&&57>=t?t-48:(e=32|t,e>=97&&102>=e?e-97+10:-1)}function c(t){return 120===t?2:117===t?4:85===t?8:0}function u(t){return t>=48&&57>=t?t-48:-1}function l(t){return 48===t?"\x00":97===t?"\a":98===t?"\b":116===t?"   ":9===t?"       ":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\e":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\85":95===t?" ":76===t?"\u2028":80===t?"\u2029":""}function p(t){return 65535>=t?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}function f(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||H,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function h(t,e){return new $(e,new B(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function d(t,e){throw h(t,e)}function m(t,e){t.onWarning&&t.onWarning.call(null,h(t,e))}function g(t,e,n,i){var r,o,a,s;if(n>e){if(s=t.input.slice(e,n),i)for(r=0,o=s.length;o>r;r+=1)a=s.charCodeAt(r),9===a||a>=32&&1114111>=a||d(t,"expected valid JSON character");else X.test(s)&&d(t,"the stream contains non-printable characters");t.result+=s}}function y(t,e,n){var i,r,o,a;for(P.isObject(n)||d(t,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,a=i.length;a>o;o+=1)r=i[o],R.call(e,r)||(e[r]=n[r])}function v(t,e,n,i,r){var o,a;if(i=String(i),null===e&&(e={}),"tag:yaml.org,2002:merge"===n)if(Array.isArray(r))for(o=0,a=r.length;a>o;o+=1)y(t,e,r[o]);else y(t,e,r);else e[i]=r;return e}function x(t){var e;e=t.input.charCodeAt(t.position),10===e?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):d(t,"a line break is expected"),t.line+=1,t.lineStart=t.position}function A(t,e,n){for(var o=0,a=t.input.charCodeAt(t.position);0!==a;){for(;r(a);)a=t.input.charCodeAt(++t.position);if(e&&35===a)do a=t.input.charCodeAt(++t.position);while(10!==a&&13!==a&&0!==a);if(!i(a))break;for(x(t),a=t.input.charCodeAt(t.position),o++,t.lineIndent=0;32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position)}return-1!==n&&0!==o&&t.lineIndent<n&&m(t,"deficient indentation"),o}function b(t){var e,n=t.position;return e=t.input.charCodeAt(n),45!==e&&46!==e||t.input.charCodeAt(n+1)!==e||t.input.charCodeAt(n+2)!==e||(n+=3,e=t.input.charCodeAt(n),0!==e&&!o(e))?!1:!0}function w(t,e){1===e?t.result+=" ":e>1&&(t.result+=P.repeat("\n",e-1))}function k(t,e,n){var s,c,u,l,p,f,h,d,m,y=t.kind,v=t.result;if(m=t.input.charCodeAt(t.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c)))return!1;for(t.kind="scalar",t.result="",u=l=t.position,p=!1;0!==m;){if(58===m){if(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=t.input.charCodeAt(t.position-1),o(s))break}else{if(t.position===t.lineStart&&b(t)||n&&a(m))break;if(i(m)){if(f=t.line,h=t.lineStart,d=t.lineIndent,A(t,!1,-1),t.lineIndent>=e){p=!0,m=t.input.charCodeAt(t.position);continue}t.position=l,t.line=f,t.lineStart=h,t.lineIndent=d;break}}p&&(g(t,u,l,!1),w(t,t.line-f),u=l=t.position,p=!1),r(m)||(l=t.position+1),m=t.input.charCodeAt(++t.position)}return g(t,u,l,!1),t.result?!0:(t.kind=y,t.result=v,!1)}function C(t,e){var n,r,o;if(n=t.input.charCodeAt(t.position),39!==n)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;0!==(n=t.input.charCodeAt(t.position));)if(39===n){if(g(t,r,t.position,!0),n=t.input.charCodeAt(++t.position),39!==n)return!0;r=o=t.position,t.position++}else i(n)?(g(t,r,o,!0),w(t,A(t,!1,e)),r=o=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a single quoted scalar"):(t.position++,o=t.position);d(t,"unexpected end of the stream within a single quoted scalar")}function j(t,e){var n,r,o,a,u,l;if(l=t.input.charCodeAt(t.position),34!==l)return!1;for(t.kind="scalar",t.result="",t.position++,n=r=t.position;0!==(l=t.input.charCodeAt(t.position));){if(34===l)return g(t,n,t.position,!0),t.position++,!0;if(92===l){if(g(t,n,t.position,!0),l=t.input.charCodeAt(++t.position),i(l))A(t,!1,e);else if(256>l&&rt[l])t.result+=ot[l],t.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=t.input.charCodeAt(++t.position),(u=s(l))>=0?a=(a<<4)+u:d(t,"expected hexadecimal character");t.result+=p(a),t.position++}else d(t,"unknown escape sequence");n=r=t.position}else i(l)?(g(t,n,r,!0),w(t,A(t,!1,e)),n=r=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}d(t,"unexpected end of the stream within a double quoted scalar")}function O(t,e){var n,i,r,a,s,c,u,l,p,f,h,m=!0,g=t.tag,y=t.anchor;if(h=t.input.charCodeAt(t.position),91===h)a=93,u=!1,i=[];else{if(123!==h)return!1;a=125,u=!0,i={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=i),h=t.input.charCodeAt(++t.position);0!==h;){if(A(t,!0,e),h=t.input.charCodeAt(t.position),h===a)return t.position++,t.tag=g,t.anchor=y,t.kind=u?"mapping":"sequence",t.result=i,!0;m||d(t,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===h&&(r=t.input.charCodeAt(t.position+1),o(r)&&(s=c=!0,t.position++,A(t,!0,e))),n=t.line,T(t,e,W,!1,!0),p=t.tag,l=t.result,A(t,!0,e),h=t.input.charCodeAt(t.position),!c&&t.line!==n||58!==h||(s=!0,h=t.input.charCodeAt(++t.position),A(t,!0,e),T(t,e,W,!1,!0),f=t.result),u?v(t,i,p,l,f):i.push(s?v(t,null,p,l,f):l),A(t,!0,e),h=t.input.charCodeAt(t.position),44===h?(m=!0,h=t.input.charCodeAt(++t.position)):m=!1}d(t,"unexpected end of the stream within a flow collection")}function S(t,e){var n,o,a,s,c=z,l=!1,p=e,f=0,h=!1;if(s=t.input.charCodeAt(t.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(t.kind="scalar",t.result="";0!==s;)if(s=t.input.charCodeAt(++t.position),43===s||45===s)z===c?c=43===s?Q:J:d(t,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?d(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?d(t,"repeat of an indentation width identifier"):(p=e+a-1,l=!0)}if(r(s)){do s=t.input.charCodeAt(++t.position);while(r(s));if(35===s)do s=t.input.charCodeAt(++t.position);while(!i(s)&&0!==s)}for(;0!==s;){for(x(t),t.lineIndent=0,s=t.input.charCodeAt(t.position);(!l||t.lineIndent<p)&&32===s;)t.lineIndent++,s=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>p&&(p=t.lineIndent),i(s))f++;else{if(t.lineIndent<p){c===Q?t.result+=P.repeat("\n",f):c===z&&l&&(t.result+="\n");break}for(o?r(s)?(h=!0,t.result+=P.repeat("\n",f+1)):h?(h=!1,t.result+=P.repeat("\n",f+1)):0===f?l&&(t.result+=" "):t.result+=P.repeat("\n",f):l?t.result+=P.repeat("\n",f+1):t.result+=P.repeat("\n",f),l=!0,f=0,n=t.position;!i(s)&&0!==s;)s=t.input.charCodeAt(++t.position);g(t,n,t.position,!1)}}return!0}function _(t,e){var n,i,r,a=t.tag,s=t.anchor,c=[],u=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=c),r=t.input.charCodeAt(t.position);0!==r&&45===r&&(i=t.input.charCodeAt(t.position+1),o(i));)if(u=!0,t.position++,A(t,!0,-1)&&t.lineIndent<=e)c.push(null),r=t.input.charCodeAt(t.position);else if(n=t.line,T(t,e,V,!1,!0),c.push(t.result),A(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===n||t.lineIndent>e)&&0!==r)d(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return u?(t.tag=a,t.anchor=s,t.kind="sequence",t.result=c,!0):!1}function I(t,e,n){var i,a,s,c,u=t.tag,l=t.anchor,p={},f=null,h=null,m=null,g=!1,y=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=p),c=t.input.charCodeAt(t.position);0!==c;){if(i=t.input.charCodeAt(t.position+1),s=t.line,63!==c&&58!==c||!o(i)){if(!T(t,n,G,!1,!0))break;if(t.line===s){for(c=t.input.charCodeAt(t.position);r(c);)c=t.input.charCodeAt(++t.position);if(58===c)c=t.input.charCodeAt(++t.position),o(c)||d(t,"a whitespace character is expected after the key-value separator within a block mapping"),g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!1,a=!1,f=t.tag,h=t.result;else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!y)return t.tag=u,t.anchor=l,!0;d(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(g&&(v(t,p,f,h,null),f=h=m=null),y=!0,g=!0,a=!0):g?(g=!1,a=!0):d(t,"incomplete explicit mapping pair; a key node is missed"),t.position+=1,c=i;if((t.line===s||t.lineIndent>e)&&(T(t,e,Z,!0,a)&&(g?h=t.result:m=t.result),g||(v(t,p,f,h,m),f=h=m=null),A(t,!0,-1),c=t.input.charCodeAt(t.position)),t.lineIndent>e&&0!==c)d(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return g&&v(t,p,f,h,null),y&&(t.tag=u,t.anchor=l,t.kind="mapping",t.result=p),y}function E(t){var e,n,i,r,a=!1,s=!1;if(r=t.input.charCodeAt(t.position),33!==r)return!1;if(null!==t.tag&&d(t,"duplication of a tag property"),r=t.input.charCodeAt(++t.position),60===r?(a=!0,r=t.input.charCodeAt(++t.position)):33===r?(s=!0,n="!!",r=t.input.charCodeAt(++t.position)):n="!",e=t.position,a){do r=t.input.charCodeAt(++t.position);while(0!==r&&62!==r);t.position<t.length?(i=t.input.slice(e,t.position),r=t.input.charCodeAt(++t.position)):d(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!o(r);)33===r&&(s?d(t,"tag suffix cannot contain exclamation marks"):(n=t.input.slice(e-1,t.position+1),nt.test(n)||d(t,"named tag handle cannot contain such characters"),s=!0,e=t.position+1)),r=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),et.test(i)&&d(t,"tag suffix cannot contain flow indicator characters")}return i&&!it.test(i)&&d(t,"tag name cannot contain such characters: "+i),a?t.tag=i:R.call(t.tagMap,n)?t.tag=t.tagMap[n]+i:"!"===n?t.tag="!"+i:"!!"===n?t.tag="tag:yaml.org,2002:"+i:d(t,'undeclared tag handle "'+n+'"'),!0}function F(t){var e,n;if(n=t.input.charCodeAt(t.position),38!==n)return!1;for(null!==t.anchor&&d(t,"duplication of an anchor property"),n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!o(n)&&!a(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function N(t){var e,n,i;if(i=t.input.charCodeAt(t.position),42!==i)return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!o(i)&&!a(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an alias node must contain at least one character"),n=t.input.slice(e,t.position),t.anchorMap.hasOwnProperty(n)||d(t,'unidentified alias "'+n+'"'),t.result=t.anchorMap[n],A(t,!0,-1),!0}function T(t,e,n,i,r){var o,a,s,c,u,l,p,f,h=1,m=!1,g=!1;if(t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=Z===n||V===n,i&&A(t,!0,-1)&&(m=!0,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)),1===h)for(;E(t)||F(t);)A(t,!0,-1)?(m=!0,s=o,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)):s=!1;if(s&&(s=m||r),(1===h||Z===n)&&(p=W===n||G===n?e:e+1,f=t.position-t.lineStart,1===h?s&&(_(t,f)||I(t,f,p))||O(t,p)?g=!0:(a&&S(t,p)||C(t,p)||j(t,p)?g=!0:N(t)?(g=!0,(null!==t.tag||null!==t.anchor)&&d(t,"alias node should not have any properties")):k(t,p,W===n)&&(g=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===h&&(g=s&&_(t,f))),null!==t.tag&&"!"!==t.tag)if("?"===t.tag){for(c=0,u=t.implicitTypes.length;u>c;c+=1)if(l=t.implicitTypes[c],l.resolve(t.result)){t.result=l.construct(t.result),t.tag=l.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else R.call(t.typeMap,t.tag)?(l=t.typeMap[t.tag],null!==t.result&&l.kind!==t.kind&&d(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+l.kind+'", not "'+t.kind+'"'),l.resolve(t.result)?(t.result=l.construct(t.result),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):d(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):d(t,"unknown tag !<"+t.tag+">");return null!==t.tag||null!==t.anchor||g}function M(t){var e,n,a,s,c=t.position,u=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};0!==(s=t.input.charCodeAt(t.position))&&(A(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==s));){for(u=!0,s=t.input.charCodeAt(++t.position),e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(e,t.position),a=[],n.length<1&&d(t,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=t.input.charCodeAt(++t.position);if(35===s){do s=t.input.charCodeAt(++t.position);while(0!==s&&!i(s));break}if(i(s))break;for(e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);a.push(t.input.slice(e,t.position))}0!==s&&x(t),R.call(st,n)?st[n](t,n,a):m(t,'unknown document directive "'+n+'"')}return A(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,A(t,!0,-1)):u&&d(t,"directives end mark is expected"),T(t,t.lineIndent-1,Z,!1,!0),A(t,!0,-1),t.checkLineBreaks&&tt.test(t.input.slice(c,t.position))&&m(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&b(t)?void(46===t.input.charCodeAt(t.position)&&(t.position+=3,A(t,!0,-1))):void(t.position<t.length-1&&d(t,"end of the stream or a document separator is expected"))}function L(t,e){t=String(t),e=e||{},0!==t.length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var n=new f(t,e);for(n.input+="\x00";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function D(t,e,n){var i,r,o=L(t,n);for(i=0,r=o.length;r>i;i+=1)e(o[i])}function U(t,e){var n=L(t,e);if(0===n.length)return void 0;if(1===n.length)return n[0];throw new $("expected a single document in the stream, but found more")}function q(t,e,n){D(t,e,P.extend({schema:K},n))}function Y(t,e){return U(t,P.extend({schema:K},e))}for(var P=t("./common"),$=t("./exception"),B=t("./mark"),K=t("./schema/default_safe"),H=t("./schema/default_full"),R=Object.prototype.hasOwnProperty,W=1,G=2,V=3,Z=4,z=1,J=2,Q=3,X=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,tt=/[\x85\u2028\u2029]/,et=/[,\[\]\{\}]/,nt=/^(?:!|!!|![a-z\-]+!)$/i,it=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,rt=new Array(256),ot=new Array(256),at=0;256>at;at++)rt[at]=l(at)?1:0,ot[at]=l(at);var st={YAML:function(t,e,n){var i,r,o;null!==t.version&&d(t,"duplication of %YAML directive"),1!==n.length&&d(t,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===i&&d(t,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),o=parseInt(i[2],10),1!==r&&d(t,"unacceptable YAML version of the document"),t.version=n[0],t.checkLineBreaks=2>o,1!==o&&2!==o&&m(t,"unsupported YAML version of the document")},TAG:function(t,e,n){var i,r;2!==n.length&&d(t,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],nt.test(i)||d(t,"ill-formed tag handle (first argument) of the TAG directive"),R.call(t.tagMap,i)&&d(t,'there is a previously declared suffix for "'+i+'" tag handle'),it.test(r)||d(t,"ill-formed tag prefix (second argument) of the TAG directive"),t.tagMap[i]=r}};e.exports.loadAll=D,e.exports.load=U,e.exports.safeLoadAll=q,e.exports.safeLoad=Y},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(t,e,n){"use strict";function i(t,e,n,i,r){this.name=t,this.buffer=e,this.position=n,this.line=i,this.column=r}var r=t("./common");i.prototype.getSnippet=function(t,e){var n,i,o,a,s;if(!this.buffer)return null;for(t=t||4,e=e||75,n="",i=this.position;i>0&&-1==="\x00\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>e/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;a<this.buffer.length&&-1==="\x00\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(a));)if(a+=1,a-this.position>e/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",t)+n+s+o+"\n"+r.repeat(" ",t+this.position-i+n.length)+"^"},i.prototype.toString=function(t){var e,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),t||(e=this.getSnippet(),e&&(n+=":\n"+e)),n},e.exports=i},{"./common":2}],7:[function(t,e,n){"use strict";function i(t,e,n){var r=[];return t.include.forEach(function(t){n=i(t,e,n)}),t[e].forEach(function(t){n.forEach(function(e,n){e.tag===t.tag&&r.push(n)}),n.push(t)}),n.filter(function(t,e){return-1===r.indexOf(e)})}function r(){function t(t){i[t.tag]=t}var e,n,i={};for(e=0,n=arguments.length;n>e;e+=1)arguments[e].forEach(t);return i}function o(t){this.include=t.include||[],this.implicit=t.implicit||[],this.explicit=t.explicit||[],this.implicit.forEach(function(t){if(t.loadKind&&"scalar"!==t.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var a=t("./common"),s=t("./exception"),c=t("./type");o.DEFAULT=null,o.create=function(){var t,e;switch(arguments.length){case 1:t=o.DEFAULT,e=arguments[0];break;case 2:t=arguments[0],e=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(t=a.toArray(t),e=a.toArray(e),!t.every(function(t){return t instanceof o}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!e.every(function(t){return t instanceof c}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new o({include:t,explicit:e})},e.exports=o},{"./common":2,"./exception":4,"./type":13}],8:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./json")]})},{"../schema":7,"./json":12}],9:[function(t,e,n){"use strict";var i=t("../schema");e.exports=i.DEFAULT=new i({include:[t("./default_safe")],explicit:[t("../type/js/undefined"),t("../type/js/regexp"),t("../type/js/function")]})},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./core")],implicit:[t("../type/timestamp"),t("../type/merge")],explicit:[t("../type/binary"),t("../type/omap"),t("../type/pairs"),t("../type/set")]})},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({explicit:[t("../type/str"),t("../type/seq"),t("../type/map")]})},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./failsafe")],implicit:[t("../type/null"),t("../type/bool"),t("../type/int"),t("../type/float")]})},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(t,e,n){"use strict";function i(t){var e={};return null!==t&&Object.keys(t).forEach(function(n){t[n].forEach(function(t){e[String(t)]=n})}),e}function r(t,e){if(e=e||{},Object.keys(e).forEach(function(e){if(-1===a.indexOf(e))throw new o('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=i(e.styleAliases||null),-1===s.indexOf(this.kind))throw new o('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}var o=t("./exception"),a=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];e.exports=r},{"./exception":4}],14:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e,n,i=0,r=t.length,o=u;for(n=0;r>n;n++)if(e=o.indexOf(t.charAt(n)),!(e>64)){if(0>e)return!1;i+=6}return i%8===0}function r(t){var e,n,i=t.replace(/[\r\n=]/g,""),r=i.length,o=u,a=0,c=[];for(e=0;r>e;e++)e%4===0&&e&&(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(e));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(t){var e,n,i="",r=0,o=t.length,a=u;for(e=0;o>e;e++)e%3===0&&e&&(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+t[e];return n=o%3,0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63],i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(t){return s&&s.isBuffer(t)}var s=t("buffer").Buffer,c=t("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";e.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,
+construct:r,predicate:a,represent:o})},{"../type":13,buffer:30}],15:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function r(t){return"true"===t||"True"===t||"TRUE"===t}function o(t){return"[object Boolean]"===Object.prototype.toString.call(t)}var a=t("../type");e.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(t,e,n){"use strict";function i(t){return null===t?!1:u.test(t)?!0:!1}function r(t){var e,n,i,r;return e=t.replace(/_/g,"").toLowerCase(),n="-"===e[0]?-1:1,r=[],0<="+-".indexOf(e[0])&&(e=e.slice(1)),".inf"===e?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:0<=e.indexOf(":")?(e.split(":").forEach(function(t){r.unshift(parseFloat(t,10))}),e=0,i=1,r.forEach(function(t){e+=t*i,i*=60}),n*e):n*parseFloat(e,10)}function o(t,e){var n;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(t))return"-0.0";return n=t.toString(10),l.test(n)?n.replace("e",".e"):n}function a(t){return"[object Number]"===Object.prototype.toString.call(t)&&(0!==t%1||s.isNegativeZero(t))}var s=t("../common"),c=t("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;e.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(t,e,n){"use strict";function i(t){return t>=48&&57>=t||t>=65&&70>=t||t>=97&&102>=t}function r(t){return t>=48&&55>=t}function o(t){return t>=48&&57>=t}function a(t){if(null===t)return!1;var e,n=t.length,a=0,s=!1;if(!n)return!1;if(e=t[a],("-"===e||"+"===e)&&(e=t[++a]),"0"===e){if(a+1===n)return!0;if(e=t[++a],"b"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if("0"!==e&&"1"!==e)return!1;s=!0}return s}if("x"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if(!i(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(!r(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(":"===e)break;if(!o(t.charCodeAt(a)))return!1;s=!0}return s?":"!==e?!0:/^(:[0-5]?[0-9])+$/.test(t.slice(a)):!1}function s(t){var e,n,i=t,r=1,o=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),e=i[0],("-"===e||"+"===e)&&("-"===e&&(r=-1),i=i.slice(1),e=i[0]),"0"===i?0:"0"===e?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(t){o.unshift(parseInt(t,10))}),i=0,n=1,o.forEach(function(t){i+=t*n,n*=60}),r*i):r*parseInt(i,10)}function c(t){return"[object Number]"===Object.prototype.toString.call(t)&&0===t%1&&!u.isNegativeZero(t)}var u=t("../common"),l=t("../type");e.exports=new l("tag:yaml.org,2002:int",{kind:"scalar",resolve:a,construct:s,predicate:c,represent:{binary:function(t){return"0b"+t.toString(2)},octal:function(t){return"0"+t.toString(8)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return"0x"+t.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":2,"../type":13}],18:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;try{var e="("+t+")",n=s.parse(e,{range:!0});return"Program"!==n.type||1!==n.body.length||"ExpressionStatement"!==n.body[0].type||"FunctionExpression"!==n.body[0].expression.type?!1:!0}catch(i){return!1}}function r(t){var e,n="("+t+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(t){r.push(t.name)}),e=i.body[0].expression.body.range,new Function(r,n.slice(e[0]+1,e[1]-1))}function o(t){return t.toString()}function a(t){return"[object Function]"===Object.prototype.toString.call(t)}var s;try{s=t("esprima")}catch(c){"undefined"!=typeof window&&(s=window.esprima)}var u=t("../../type");e.exports=new u("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13,esprima:"esprima"}],19:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;if(0===t.length)return!1;var e=t,n=/\/([gim]*)$/.exec(t),i="";if("/"===e[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==e[e.length-i.length-1])return!1;e=e.slice(1,e.length-i.length-1)}try{return!0}catch(r){return!1}}function r(t){var e=t,n=/\/([gim]*)$/.exec(t),i="";return"/"===e[0]&&(n&&(i=n[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function o(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function a(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(t,e,n){"use strict";function i(){return!0}function r(){return void 0}function o(){return""}function a(t){return"undefined"==typeof t}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})},{"../type":13}],22:[function(t,e,n){"use strict";function i(t){return"<<"===t||null===t}var r=t("../type");e.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function r(){return null}function o(t){return null===t}var a=t("../type");e.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,c=[],u=t;for(e=0,n=u.length;n>e;e+=1){if(i=u[e],o=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(a.call(i,r)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==c.indexOf(r))return!1;c.push(r)}return!0}function r(t){return null!==t?t:[]}var o=t("../type"),a=Object.prototype.hasOwnProperty,s=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],25:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,s=t;for(o=new Array(s.length),e=0,n=s.length;n>e;e+=1){if(i=s[e],"[object Object]"!==a.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;o[e]=[r[0],i[r[0]]]}return!0}function r(t){if(null===t)return[];var e,n,i,r,o,a=t;for(o=new Array(a.length),e=0,n=a.length;n>e;e+=1)i=a[e],r=Object.keys(i),o[e]=[r[0],i[r[0]]];return o}var o=t("../type"),a=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],26:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}})},{"../type":13}],27:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n=t;for(e in n)if(a.call(n,e)&&null!==n[e])return!1;return!0}function r(t){return null!==t?t:{}}var o=t("../type"),a=Object.prototype.hasOwnProperty;e.exports=new o("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":13}],28:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}})},{"../type":13}],29:[function(t,e,n){"use strict";function i(t){return null===t?!1:null===s.exec(t)?!1:!0}function r(t){var e,n,i,r,o,a,c,u,l,p,f=0,h=null;if(e=s.exec(t),null===e)throw new Error("Date resolve error");if(n=+e[1],i=+e[2]-1,r=+e[3],!e[4])return new Date(Date.UTC(n,i,r));if(o=+e[4],a=+e[5],c=+e[6],e[7]){for(f=e[7].slice(0,3);f.length<3;)f+="0";f=+f}return e[9]&&(u=+e[10],l=+(e[11]||0),h=6e4*(60*u+l),"-"===e[9]&&(h=-h)),p=new Date(Date.UTC(n,i,r,o,a,c,f)),h&&p.setTime(p.getTime()-h),p}function o(t){return t.toISOString()}var a=t("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$");e.exports=new a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:o})},{"../type":13}],30:[function(t,e,n){},{}],31:[function(t,e,n){e.exports=t("./lib/inherit")},{"./lib/inherit":32}],32:[function(e,n,i){!function(e){function r(t){var e=f(t);if(v)for(var n,i=0;n=b[i++];)t.hasOwnProperty(n)&&e.push(n);return e}function o(t,e,n){for(var i,o,a=r(n),s=0,u=a.length;u>s;)"__self"!==(i=a[s++])&&(o=n[i],g(o)&&(!c||o.toString().indexOf(".__base")>-1)?e[i]=function(n,i){var r=t[n]?t[n]:"__constructor"===n?e.__self.__parent:y;return function(){var t=this.__base;this.__base=r;var e=i.apply(this,arguments);return this.__base=t,e}}(i,o):e[i]=o)}function a(t,e){for(var n,i=1;n=t[i++];)e?g(n)?s.self(e,n.prototype,n):s.self(e,n):e=g(n)?s(t[0],n.prototype,n):s(t[0],n);return e||t[0]}function s(){var t=arguments,e=m(t[0]),n=e||g(t[0]),i=n?e?a(t[0]):t[0]:u,r=t[n?1:0]||{},s=t[n?2:1],c=r.__constructor||n&&i.prototype.__constructor?function(){return this.__constructor.apply(this,arguments)}:n?function(){return i.apply(this,arguments)}:function(){};if(!n)return c.prototype=r,c.prototype.__self=c.prototype.constructor=c,h(c,s);h(c,i),c.__parent=i;var l=i.prototype,f=c.prototype=p(l);return f.__self=f.constructor=c,r&&o(l,f,r),s&&o(i,c,s),c}var c=function(){"_"}.toString().indexOf("_")>-1,u=function(){},l=Object.prototype.hasOwnProperty,p=Object.create||function(t){var e=function(){};return e.prototype=t,new e},f=Object.keys||function(t){var e=[];for(var n in t)l.call(t,n)&&e.push(n);return e},h=function(t,e){for(var n in e)l.call(e,n)&&(t[n]=e[n]);return t},d=Object.prototype.toString,m=Array.isArray||function(t){return"[object Array]"===d.call(t)},g=function(t){return"[object Function]"===d.call(t)},y=function(){},v=!0,x={toString:""};for(var A in x)x.hasOwnProperty(A)&&(v=!1);var b=v?["toString","valueOf"]:null;s.self=function(){var t=arguments,e=m(t[0]),n=e?a(t[0],t[0][0]):t[0],i=t[1],r=t[2],s=n.prototype;return i&&o(s,s,i),r&&o(n,n,r),n};var w=!0;"object"==typeof i&&(n.exports=s,w=!1),"object"==typeof modules&&(modules.define("inherit",function(t){t(s)}),w=!1),"function"==typeof t&&(t(function(t,e,n){n.exports=s}),w=!1),w&&(e.inherit=s)}(this)},{}],"/":[function(t,e,n){"use strict";var i=t("./lib/js-yaml.js");e.exports=i},{"./lib/js-yaml.js":1}]},{},[])("/")});
diff --git a/src/main/resources/META-INF/resources/icd/lib/jsoneditor.min.js b/src/main/resources/META-INF/resources/icd/lib/jsoneditor.min.js
new file mode 100644 (file)
index 0000000..343397f
--- /dev/null
@@ -0,0 +1,11 @@
+/*! JSON Editor v0.7.22 - JSON Schema -> HTML Editor
+ * By Jeremy Dorn - https://github.com/jdorn/json-editor/
+ * Released under the MIT license
+ *
+ * Date: 2015-08-12
+ */
+!function(){var a;!function(){var b=!1,c=/xyz/.test(function(){window.postMessage("xyz")})?/\b_super\b/:/.*/;return a=function(){},a.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail),c}a.prototype=window.Event.prototype,window.CustomEvent=a}(),function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c<b.length&&!window.requestAnimationFrame;++c)window.requestAnimationFrame=window[b[c]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[b[c]+"CancelAnimationFrame"]||window[b[c]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(b,c){var d=(new Date).getTime(),e=Math.max(0,16-(d-a)),f=window.setTimeout(function(){b(d+e)},e);return a=d+e,f}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(a){clearTimeout(a)})}(),function(){Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)})}();var b=function(a){return"object"!=typeof a||a.nodeType||null!==a&&a===a.window?!1:a.constructor&&!Object.prototype.hasOwnProperty.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},c=function(a){var d,e,f;for(e=1;e<arguments.length;e++){d=arguments[e];for(f in d)d.hasOwnProperty(f)&&(d[f]&&b(d[f])?(a.hasOwnProperty(f)||(a[f]={}),c(a[f],d[f])):a[f]=d[f])}return a},d=function(a,b){if(a&&"object"==typeof a){var c;if(Array.isArray(a)||"number"==typeof a.length&&a.length>0&&a.length-1 in a){for(c=0;c<a.length;c++)if(b(c,a[c])===!1)return}else if(Object.keys){var d=Object.keys(a);for(c=0;c<d.length;c++)if(b(d[c],a[d[c]])===!1)return}else for(c in a)if(a.hasOwnProperty(c)&&b(c,a[c])===!1)return}},e=function(a,b){var c=document.createEvent("HTMLEvents");c.initEvent(b,!0,!0),a.dispatchEvent(c)},f=function(a,b){if(!(a instanceof Element))throw new Error("element should be an instance of Element");b=c({},f.defaults.options,b||{}),this.element=a,this.options=b,this.init()};f.prototype={constructor:f,init:function(){var a=this;this.ready=!1;var b=f.defaults.themes[this.options.theme||f.defaults.theme];if(!b)throw"Unknown theme "+(this.options.theme||f.defaults.theme);this.schema=this.options.schema,this.theme=new b,this.template=this.options.template,this.refs=this.options.refs||{},this.uuid=0,this.__data={};var c=f.defaults.iconlibs[this.options.iconlib||f.defaults.iconlib];c&&(this.iconlib=new c),this.root_container=this.theme.getContainer(),this.element.appendChild(this.root_container),this.translate=this.options.translate||f.defaults.translate,this._loadExternalRefs(this.schema,function(){a._getDefinitions(a.schema),a.validator=new f.Validator(a);var b=a.getEditorClass(a.schema);a.root=a.createEditor(b,{jsoneditor:a,schema:a.schema,required:!0,container:a.root_container}),a.root.preBuild(),a.root.build(),a.root.postBuild(),a.options.startval&&a.root.setValue(a.options.startval),a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.ready=!0,window.requestAnimationFrame(function(){a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),a.root.showValidationErrors(a.validation_results),a.trigger("ready"),a.trigger("change"))})})},getValue:function(){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before getting the value";return this.root.getValue()},setValue:function(a){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before setting the value";return this.root.setValue(a),this},validate:function(a){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before validating";return 1===arguments.length?this.validator.validate(a):this.validation_results},destroy:function(){this.destroyed||this.ready&&(this.schema=null,this.options=null,this.root.destroy(),this.root=null,this.root_container=null,this.validator=null,this.validation_results=null,this.theme=null,this.iconlib=null,this.template=null,this.__data=null,this.ready=!1,this.element.innerHTML="",this.destroyed=!0)},on:function(a,b){return this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[],this.callbacks[a].push(b),this},off:function(a,b){if(a&&b){this.callbacks=this.callbacks||{},this.callbacks[a]=this.callbacks[a]||[];for(var c=[],d=0;d<this.callbacks[a].length;d++)this.callbacks[a][d]!==b&&c.push(this.callbacks[a][d]);this.callbacks[a]=c}else a?(this.callbacks=this.callbacks||{},this.callbacks[a]=[]):this.callbacks={};return this},trigger:function(a){if(this.callbacks&&this.callbacks[a]&&this.callbacks[a].length)for(var b=0;b<this.callbacks[a].length;b++)this.callbacks[a][b]();return this},setOption:function(a,b){if("show_errors"!==a)throw"Option "+a+" must be set during instantiation and cannot be changed later";return this.options.show_errors=b,this.onChange(),this},getEditorClass:function(a){var b;if(a=this.expandSchema(a),d(f.defaults.resolvers,function(c,d){var e=d(a);return e&&f.defaults.editors[e]?(b=e,!1):void 0}),!b)throw"Unknown editor for schema "+JSON.stringify(a);if(!f.defaults.editors[b])throw"Unknown editor "+b;return f.defaults.editors[b]},createEditor:function(a,b){return b=c({},a.options||{},b),new a(b)},onChange:function(){if(this.ready&&!this.firing_change){this.firing_change=!0;var a=this;return window.requestAnimationFrame(function(){a.firing_change=!1,a.ready&&(a.validation_results=a.validator.validate(a.root.getValue()),"never"!==a.options.show_errors?a.root.showValidationErrors(a.validation_results):a.root.showValidationErrors([]),a.trigger("change"))}),this}},compileTemplate:function(a,b){b=b||f.defaults.template;var c;if("string"==typeof b){if(!f.defaults.templates[b])throw"Unknown template engine "+b;if(c=f.defaults.templates[b](),!c)throw"Template engine "+b+" missing required library."}else c=b;if(!c)throw"No template engine set";if(!c.compile)throw"Invalid template engine set";return c.compile(a)},_data:function(a,b,c){if(3!==arguments.length)return a.hasAttribute("data-jsoneditor-"+b)?this.__data[a.getAttribute("data-jsoneditor-"+b)]:null;var d;a.hasAttribute("data-jsoneditor-"+b)?d=a.getAttribute("data-jsoneditor-"+b):(d=this.uuid++,a.setAttribute("data-jsoneditor-"+b,d)),this.__data[d]=c},registerEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=a,this},unregisterEditor:function(a){return this.editors=this.editors||{},this.editors[a.path]=null,this},getEditor:function(a){return this.editors?this.editors[a]:void 0},watch:function(a,b){return this.watchlist=this.watchlist||{},this.watchlist[a]=this.watchlist[a]||[],this.watchlist[a].push(b),this},unwatch:function(a,b){if(!this.watchlist||!this.watchlist[a])return this;if(!b)return this.watchlist[a]=null,this;for(var c=[],d=0;d<this.watchlist[a].length;d++)this.watchlist[a][d]!==b&&c.push(this.watchlist[a][d]);return this.watchlist[a]=c.length?c:null,this},notifyWatchers:function(a){if(!this.watchlist||!this.watchlist[a])return this;for(var b=0;b<this.watchlist[a].length;b++)this.watchlist[a][b]()},isEnabled:function(){return!this.root||this.root.isEnabled()},enable:function(){this.root.enable()},disable:function(){this.root.disable()},_getDefinitions:function(a,b){if(b=b||"#/definitions/",a.definitions)for(var c in a.definitions)a.definitions.hasOwnProperty(c)&&(this.refs[b+c]=a.definitions[c],a.definitions[c].definitions&&this._getDefinitions(a.definitions[c],b+c+"/definitions/"))},_getExternalRefs:function(a){var b={},c=function(a){for(var c in a)a.hasOwnProperty(c)&&(b[c]=!0)};a.$ref&&"object"!=typeof a.$ref&&"#"!==a.$ref.substr(0,1)&&!this.refs[a.$ref]&&(b[a.$ref]=!0);for(var d in a)if(a.hasOwnProperty(d))if(a[d]&&"object"==typeof a[d]&&Array.isArray(a[d]))for(var e=0;e<a[d].length;e++)"object"==typeof a[d][e]&&c(this._getExternalRefs(a[d][e]));else a[d]&&"object"==typeof a[d]&&c(this._getExternalRefs(a[d]));return b},_loadExternalRefs:function(a,b){var c=this,e=this._getExternalRefs(a),f=0,g=0,h=!1;d(e,function(a){if(!c.refs[a]){if(!c.options.ajax)throw"Must set ajax option to true to load external ref "+a;c.refs[a]="loading",g++;var d=new XMLHttpRequest;d.open("GET",a,!0),d.onreadystatechange=function(){if(4==d.readyState){if(200!==d.status)throw window.console.log(d),"Failed to fetch ref via ajax- "+a;var e;try{e=JSON.parse(d.responseText)}catch(i){throw window.console.log(i),"Failed to parse external ref "+a}if(!e||"object"!=typeof e)throw"External ref does not contain a valid schema - "+a;c.refs[a]=e,c._loadExternalRefs(e,function(){f++,f>=g&&!h&&(h=!0,b())})}},d.send()}}),g||b()},expandRefs:function(a){for(a=c({},a);a.$ref;){var b=a.$ref;delete a.$ref,this.refs[b]||(b=decodeURIComponent(b)),a=this.extendSchemas(a,this.refs[b])}return a},expandSchema:function(a){var b,e=this,f=c({},a);if("object"==typeof a.type&&(Array.isArray(a.type)?d(a.type,function(b,c){"object"==typeof c&&(a.type[b]=e.expandSchema(c))}):a.type=e.expandSchema(a.type)),"object"==typeof a.disallow&&(Array.isArray(a.disallow)?d(a.disallow,function(b,c){"object"==typeof c&&(a.disallow[b]=e.expandSchema(c))}):a.disallow=e.expandSchema(a.disallow)),a.anyOf&&d(a.anyOf,function(b,c){a.anyOf[b]=e.expandSchema(c)}),a.dependencies&&d(a.dependencies,function(b,c){"object"!=typeof c||Array.isArray(c)||(a.dependencies[b]=e.expandSchema(c))}),a.not&&(a.not=this.expandSchema(a.not)),a.allOf){for(b=0;b<a.allOf.length;b++)f=this.extendSchemas(f,this.expandSchema(a.allOf[b]));delete f.allOf}if(a["extends"]){if(Array.isArray(a["extends"]))for(b=0;b<a["extends"].length;b++)f=this.extendSchemas(f,this.expandSchema(a["extends"][b]));else f=this.extendSchemas(f,this.expandSchema(a["extends"]));delete f["extends"]}if(a.oneOf){var g=c({},f);for(delete g.oneOf,b=0;b<a.oneOf.length;b++)f.oneOf[b]=this.extendSchemas(this.expandSchema(a.oneOf[b]),g)}return this.expandRefs(f)},extendSchemas:function(a,b){a=c({},a),b=c({},b);var e=this,f={};return d(a,function(a,c){"undefined"!=typeof b[a]?"required"===a&&"object"==typeof c&&Array.isArray(c)?f.required=c.concat(b[a]).reduce(function(a,b){return a.indexOf(b)<0&&a.push(b),a},[]):"type"!==a||"string"!=typeof c&&!Array.isArray(c)?"object"==typeof c&&Array.isArray(c)?f[a]=c.filter(function(c){return-1!==b[a].indexOf(c)}):"object"==typeof c&&null!==c?f[a]=e.extendSchemas(c,b[a]):f[a]=c:("string"==typeof c&&(c=[c]),"string"==typeof b.type&&(b.type=[b.type]),f.type=c.filter(function(a){return-1!==b.type.indexOf(a)}),1===f.type.length&&"string"==typeof f.type[0]&&(f.type=f.type[0])):f[a]=c}),d(b,function(b,c){"undefined"==typeof a[b]&&(f[b]=c)}),f}},f.defaults={themes:{},templates:{},iconlibs:{},editors:{},languages:{},resolvers:[],custom_validators:[]},f.Validator=a.extend({init:function(a,b){this.jsoneditor=a,this.schema=b||this.jsoneditor.schema,this.options={},this.translate=this.jsoneditor.translate||f.defaults.translate},validate:function(a){return this._validateSchema(this.schema,a)},_validateSchema:function(a,b,e){var g,h,i,j=this,k=[],l=JSON.stringify(b);if(e=e||"root",a=c({},this.jsoneditor.expandRefs(a)),a.required&&a.required===!0){if("undefined"==typeof b)return k.push({path:e,property:"required",message:this.translate("error_notset")}),k}else if("undefined"==typeof b){if(!this.jsoneditor.options.required_by_default)return k;k.push({path:e,property:"required",message:this.translate("error_notset")})}if(a["enum"]){for(g=!1,h=0;h<a["enum"].length;h++)l===JSON.stringify(a["enum"][h])&&(g=!0);g||k.push({path:e,property:"enum",message:this.translate("error_enum")})}if(a["extends"])for(h=0;h<a["extends"].length;h++)k=k.concat(this._validateSchema(a["extends"][h],b,e));if(a.allOf)for(h=0;h<a.allOf.length;h++)k=k.concat(this._validateSchema(a.allOf[h],b,e));if(a.anyOf){for(g=!1,h=0;h<a.anyOf.length;h++)if(!this._validateSchema(a.anyOf[h],b,e).length){g=!0;break}g||k.push({path:e,property:"anyOf",message:this.translate("error_anyOf")})}if(a.oneOf){g=0;var m=[];for(h=0;h<a.oneOf.length;h++){var n=this._validateSchema(a.oneOf[h],b,e);for(n.length||g++,i=0;i<n.length;i++)n[i].path=e+".oneOf["+h+"]"+n[i].path.substr(e.length);m=m.concat(n)}1!==g&&(k.push({path:e,property:"oneOf",message:this.translate("error_oneOf",[g])}),k=k.concat(m))}if(a.not&&(this._validateSchema(a.not,b,e).length||k.push({path:e,property:"not",message:this.translate("error_not")})),a.type)if(Array.isArray(a.type)){for(g=!1,h=0;h<a.type.length;h++)if(this._checkType(a.type[h],b)){g=!0;break}g||k.push({path:e,property:"type",message:this.translate("error_type_union")})}else this._checkType(a.type,b)||k.push({path:e,property:"type",message:this.translate("error_type",[a.type])});if(a.disallow)if(Array.isArray(a.disallow)){for(g=!0,h=0;h<a.disallow.length;h++)if(this._checkType(a.disallow[h],b)){g=!1;break}g||k.push({path:e,property:"disallow",message:this.translate("error_disallow_union")})}else this._checkType(a.disallow,b)&&k.push({path:e,property:"disallow",message:this.translate("error_disallow",[a.disallow])});if("number"==typeof b)(a.multipleOf||a.divisibleBy)&&(g=b/(a.multipleOf||a.divisibleBy),g!==Math.floor(g)&&k.push({path:e,property:a.multipleOf?"multipleOf":"divisibleBy",message:this.translate("error_multipleOf",[a.multipleOf||a.divisibleBy])})),a.hasOwnProperty("maximum")&&(a.exclusiveMaximum&&b>=a.maximum?k.push({path:e,property:"maximum",message:this.translate("error_maximum_excl",[a.maximum])}):!a.exclusiveMaximum&&b>a.maximum&&k.push({path:e,property:"maximum",message:this.translate("error_maximum_incl",[a.maximum])})),a.hasOwnProperty("minimum")&&(a.exclusiveMinimum&&b<=a.minimum?k.push({path:e,property:"minimum",message:this.translate("error_minimum_excl",[a.minimum])}):!a.exclusiveMinimum&&b<a.minimum&&k.push({path:e,property:"minimum",message:this.translate("error_minimum_incl",[a.minimum])}));else if("string"==typeof b)a.maxLength&&(b+"").length>a.maxLength&&k.push({path:e,property:"maxLength",message:this.translate("error_maxLength",[a.maxLength])}),a.minLength&&(b+"").length<a.minLength&&k.push({path:e,property:"minLength",message:this.translate(1===a.minLength?"error_notempty":"error_minLength",[a.minLength])}),a.pattern&&(new RegExp(a.pattern).test(b)||k.push({path:e,property:"pattern",message:this.translate("error_pattern")}));else if("object"==typeof b&&null!==b&&Array.isArray(b)){if(a.items)if(Array.isArray(a.items))for(h=0;h<b.length;h++)if(a.items[h])k=k.concat(this._validateSchema(a.items[h],b[h],e+"."+h));else{if(a.additionalItems===!0)break;if(!a.additionalItems){if(a.additionalItems===!1){k.push({path:e,property:"additionalItems",message:this.translate("error_additionalItems")});break}break}k=k.concat(this._validateSchema(a.additionalItems,b[h],e+"."+h))}else for(h=0;h<b.length;h++)k=k.concat(this._validateSchema(a.items,b[h],e+"."+h));if(a.maxItems&&b.length>a.maxItems&&k.push({path:e,property:"maxItems",message:this.translate("error_maxItems",[a.maxItems])}),a.minItems&&b.length<a.minItems&&k.push({path:e,property:"minItems",message:this.translate("error_minItems",[a.minItems])}),a.uniqueItems){var o={};for(h=0;h<b.length;h++){if(g=JSON.stringify(b[h]),o[g]){k.push({path:e,property:"uniqueItems",message:this.translate("error_uniqueItems")});break}o[g]=!0}}}else if("object"==typeof b&&null!==b){if(a.maxProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g>a.maxProperties&&k.push({path:e,property:"maxProperties",message:this.translate("error_maxProperties",[a.maxProperties])})}if(a.minProperties){g=0;for(h in b)b.hasOwnProperty(h)&&g++;g<a.minProperties&&k.push({path:e,property:"minProperties",message:this.translate("error_minProperties",[a.minProperties])})}if(a.required&&Array.isArray(a.required))for(h=0;h<a.required.length;h++)"undefined"==typeof b[a.required[h]]&&k.push({path:e,property:"required",message:this.translate("error_required",[a.required[h]])});var p={};if(a.properties)for(h in a.properties)a.properties.hasOwnProperty(h)&&(p[h]=!0,k=k.concat(this._validateSchema(a.properties[h],b[h],e+"."+h)));if(a.patternProperties)for(h in a.patternProperties)if(a.patternProperties.hasOwnProperty(h)){var q=new RegExp(h);for(i in b)b.hasOwnProperty(i)&&q.test(i)&&(p[i]=!0,k=k.concat(this._validateSchema(a.patternProperties[h],b[i],e+"."+i)))}if("undefined"!=typeof a.additionalProperties||!this.jsoneditor.options.no_additional_properties||a.oneOf||a.anyOf||(a.additionalProperties=!1),"undefined"!=typeof a.additionalProperties)for(h in b)if(b.hasOwnProperty(h)&&!p[h]){if(!a.additionalProperties){k.push({path:e,property:"additionalProperties",message:this.translate("error_additional_properties",[h])});break}if(a.additionalProperties===!0)break;k=k.concat(this._validateSchema(a.additionalProperties,b[h],e+"."+h))}if(a.dependencies)for(h in a.dependencies)if(a.dependencies.hasOwnProperty(h)&&"undefined"!=typeof b[h])if(Array.isArray(a.dependencies[h]))for(i=0;i<a.dependencies[h].length;i++)"undefined"==typeof b[a.dependencies[h][i]]&&k.push({path:e,property:"dependencies",message:this.translate("error_dependency",[a.dependencies[h][i]])});else k=k.concat(this._validateSchema(a.dependencies[h],b,e))}return d(f.defaults.custom_validators,function(c,d){k=k.concat(d.call(j,a,b,e))}),k},_checkType:function(a,b){return"string"==typeof a?"string"===a?"string"==typeof b:"number"===a?"number"==typeof b:"integer"===a?"number"==typeof b&&b===Math.floor(b):"boolean"===a?"boolean"==typeof b:"array"===a?Array.isArray(b):"object"===a?null!==b&&!Array.isArray(b)&&"object"==typeof b:"null"===a?null===b:!0:!this._validateSchema(a,b).length}}),f.AbstractEditor=a.extend({onChildEditorChange:function(a){this.onChange(!0)},notify:function(){this.jsoneditor.notifyWatchers(this.path)},change:function(){this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange()},onChange:function(a){this.notify(),this.watch_listener&&this.watch_listener(),a&&this.change()},register:function(){this.jsoneditor.registerEditor(this),this.onChange()},unregister:function(){this.jsoneditor&&this.jsoneditor.unregisterEditor(this)},getNumColumns:function(){return 12},init:function(a){this.jsoneditor=a.jsoneditor,this.theme=this.jsoneditor.theme,this.template_engine=this.jsoneditor.template,this.iconlib=this.jsoneditor.iconlib,this.original_schema=a.schema,this.schema=this.jsoneditor.expandSchema(this.original_schema),this.options=c({},this.options||{},a.schema.options||{},a),a.path||this.schema.id||(this.schema.id="root"),this.path=a.path||"root",this.formname=a.formname||this.path.replace(/\.([^.]+)/g,"[$1]"),this.jsoneditor.options.form_name_root&&(this.formname=this.formname.replace(/^root\[/,this.jsoneditor.options.form_name_root+"[")),this.key=this.path.split(".").pop(),this.parent=a.parent,this.link_watchers=[],a.container&&this.setContainer(a.container)},setContainer:function(a){this.container=a,this.schema.id&&this.container.setAttribute("data-schemaid",this.schema.id),this.schema.type&&"string"==typeof this.schema.type&&this.container.setAttribute("data-schematype",this.schema.type),this.container.setAttribute("data-schemapath",this.path)},preBuild:function(){},build:function(){},postBuild:function(){this.setupWatchListeners(),this.addLinks(),this.setValue(this.getDefault(),!0),this.updateHeaderText(),this.register(),this.onWatchedFieldChange()},setupWatchListeners:function(){var a=this;if(this.watched={},this.schema.vars&&(this.schema.watch=this.schema.vars),this.watched_values={},this.watch_listener=function(){a.refreshWatchedFieldValues()&&a.onWatchedFieldChange()},this.register(),this.schema.hasOwnProperty("watch")){var b,c,d,e,f;for(var g in this.schema.watch)if(this.schema.watch.hasOwnProperty(g)){if(b=this.schema.watch[g],Array.isArray(b)?c=[b[0]].concat(b[1].split(".")):(c=b.split("."),a.theme.closest(a.container,'[data-schemaid="'+c[0]+'"]')||c.unshift("#")),d=c.shift(),"#"===d&&(d=a.jsoneditor.schema.id||"root"),e=a.theme.closest(a.container,'[data-schemaid="'+d+'"]'),!e)throw"Could not find ancestor node with id "+d;f=e.getAttribute("data-schemapath")+"."+c.join("."),a.jsoneditor.watch(f,a.watch_listener),a.watched[g]=f}}this.schema.headerTemplate&&(this.header_template=this.jsoneditor.compileTemplate(this.schema.headerTemplate,this.template_engine))},addLinks:function(){if(!this.no_link_holder&&(this.link_holder=this.theme.getLinksHolder(),this.container.appendChild(this.link_holder),this.schema.links))for(var a=0;a<this.schema.links.length;a++)this.addLink(this.getLink(this.schema.links[a]))},getButton:function(a,b,c){var d="json-editor-btn-"+b;b=this.iconlib?this.iconlib.getIcon(b):null,!b&&c&&(a=c,c=null);var e=this.theme.getButton(a,b,c);return e.className+=" "+d+" ",e},setButtonText:function(a,b,c,d){return c=this.iconlib?this.iconlib.getIcon(c):null,!c&&d&&(b=d,d=null),this.theme.setButtonText(a,b,c,d)},addLink:function(a){this.link_holder&&this.link_holder.appendChild(a)},getLink:function(a){var b,c,d=a.mediaType||"application/javascript",e=d.split("/")[0],f=this.jsoneditor.compileTemplate(a.href,this.template_engine);if("image"===e){b=this.theme.getBlockLinkHolder(),c=document.createElement("a"),c.setAttribute("target","_blank");var g=document.createElement("img");this.theme.createImageLink(b,c,g),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.setAttribute("title",a.rel||d),g.setAttribute("src",d)})}else if(["audio","video"].indexOf(e)>=0){b=this.theme.getBlockLinkHolder(),c=this.theme.getBlockLink(),c.setAttribute("target","_blank");var h=document.createElement(e);h.setAttribute("controls","controls"),this.theme.createMediaLink(b,c,h),this.link_watchers.push(function(b){var d=f(b);c.setAttribute("href",d),c.textContent=a.rel||d,h.setAttribute("src",d)})}else b=this.theme.getBlockLink(),b.setAttribute("target","_blank"),b.textContent=a.rel,this.link_watchers.push(function(c){var d=f(c);b.setAttribute("href",d),b.textContent=a.rel||d});return b},refreshWatchedFieldValues:function(){if(this.watched_values){var a={},b=!1,c=this;if(this.watched){var d,e;for(var f in this.watched)this.watched.hasOwnProperty(f)&&(e=c.jsoneditor.getEditor(this.watched[f]),d=e?e.getValue():null,c.watched_values[f]!==d&&(b=!0),a[f]=d)}return a.self=this.getValue(),this.watched_values.self!==a.self&&(b=!0),this.watched_values=a,b}},getWatchedFieldValues:function(){return this.watched_values},updateHeaderText:function(){if(this.header)if(this.header.children.length){for(var a=0;a<this.header.childNodes.length;a++)if(3===this.header.childNodes[a].nodeType){this.header.childNodes[a].nodeValue=this.getHeaderText();break}}else this.header.textContent=this.getHeaderText()},getHeaderText:function(a){return this.header_text?this.header_text:a?this.schema.title:this.getTitle()},onWatchedFieldChange:function(){var a;if(this.header_template){a=c(this.getWatchedFieldValues(),{key:this.key,i:this.key,i0:1*this.key,i1:1*this.key+1,title:this.getTitle()});var b=this.header_template(a);b!==this.header_text&&(this.header_text=b,this.updateHeaderText(),this.notify())}if(this.link_watchers.length){a=this.getWatchedFieldValues();for(var d=0;d<this.link_watchers.length;d++)this.link_watchers[d](a)}},setValue:function(a){this.value=a},getValue:function(){return this.value},refreshValue:function(){},getChildEditors:function(){return!1},destroy:function(){var a=this;this.unregister(this),d(this.watched,function(b,c){a.jsoneditor.unwatch(c,a.watch_listener)}),this.watched=null,this.watched_values=null,this.watch_listener=null,this.header_text=null,this.header_template=null,this.value=null,this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=null,this.jsoneditor=null,this.schema=null,this.path=null,this.key=null,this.parent=null},getDefault:function(){if(this.schema["default"])return this.schema["default"];if(this.schema["enum"])return this.schema["enum"][0];var a=this.schema.type||this.schema.oneOf;if(a&&Array.isArray(a)&&(a=a[0]),a&&"object"==typeof a&&(a=a.type),a&&Array.isArray(a)&&(a=a[0]),"string"==typeof a){if("number"===a)return 0;if("boolean"===a)return!1;if("integer"===a)return 0;if("string"===a)return"";if("object"===a)return{};if("array"===a)return[]}return null},getTitle:function(){return this.schema.title||this.key},enable:function(){this.disabled=!1},disable:function(){this.disabled=!0},isEnabled:function(){return!this.disabled},isRequired:function(){return"boolean"==typeof this.schema.required?this.schema.required:this.parent&&this.parent.schema&&Array.isArray(this.parent.schema.required)?this.parent.schema.required.indexOf(this.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},getDisplayText:function(a){var b=[],c={};d(a,function(a,b){b.title&&(c[b.title]=c[b.title]||0,c[b.title]++),b.description&&(c[b.description]=c[b.description]||0,c[b.description]++),b.format&&(c[b.format]=c[b.format]||0,c[b.format]++),b.type&&(c[b.type]=c[b.type]||0,c[b.type]++)}),d(a,function(a,d){var e;e="string"==typeof d?d:d.title&&c[d.title]<=1?d.title:d.format&&c[d.format]<=1?d.format:d.type&&c[d.type]<=1?d.type:d.description&&c[d.description]<=1?d.descripton:d.title?d.title:d.format?d.format:d.type?d.type:d.description?d.description:JSON.stringify(d).length<50?JSON.stringify(d):"type",b.push(e)});var e={};return d(b,function(a,d){e[d]=e[d]||0,e[d]++,c[d]>1&&(b[a]=d+" "+e[d])}),b},getOption:function(a){try{throw"getOption is deprecated"}catch(b){window.console.error(b)}return this.options[a]},showValidationErrors:function(a){}}),f.defaults.editors["null"]=f.AbstractEditor.extend({getValue:function(){return null},setValue:function(){this.onChange()},getNumColumns:function(){return 2}}),f.defaults.editors.string=f.AbstractEditor.extend({register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},setValue:function(a,b,c){if((!this.template||c)&&(null===a||"undefined"==typeof a?a="":"object"==typeof a?a=JSON.stringify(a):"string"!=typeof a&&(a=""+a),a!==this.serialized)){var d=this.sanitize(a);if(this.input.value!==d){this.input.value=d,this.sceditor_instance?this.sceditor_instance.val(d):this.epiceditor?this.epiceditor.importFile(null,d):this.ace_editor&&this.ace_editor.setValue(d);var e=c||this.getValue()!==a;this.refreshValue(),b?this.is_dirty=!1:"change"===this.jsoneditor.options.show_errors&&(this.is_dirty=!0),this.adjust_height&&this.adjust_height(this.input),this.onChange(e)}}},getNumColumns:function(){var a,b=Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5);return a="textarea"===this.input_type?6:["text","email"].indexOf(this.input_type)>=0?4:2,Math.min(12,Math.max(b,a))},build:function(){var a=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.format=this.schema.format,!this.format&&this.schema.media&&this.schema.media.type&&(this.format=this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,"")),!this.format&&this.options.default_format&&(this.format=this.options.default_format),this.options.format&&(this.format=this.options.format),this.format)if("textarea"===this.format)this.input_type="textarea",this.input=this.theme.getTextareaInput();else if("range"===this.format){this.input_type="range";var b=this.schema.minimum||0,c=this.schema.maximum||Math.max(100,b+1),d=1;this.schema.multipleOf&&(b%this.schema.multipleOf&&(b=Math.ceil(b/this.schema.multipleOf)*this.schema.multipleOf),c%this.schema.multipleOf&&(c=Math.floor(c/this.schema.multipleOf)*this.schema.multipleOf),d=this.schema.multipleOf),this.input=this.theme.getRangeInput(b,c,d)}else["actionscript","batchfile","bbcode","c","c++","cpp","coffee","csharp","css","dart","django","ejs","erlang","golang","handlebars","haskell","haxe","html","ini","jade","java","javascript","json","less","lisp","lua","makefile","markdown","matlab","mysql","objectivec","pascal","perl","pgsql","php","python","r","ruby","sass","scala","scss","smarty","sql","stylus","svg","twig","vbscript","xml","yaml"].indexOf(this.format)>=0?(this.input_type=this.format,this.source_code=!0,this.input=this.theme.getTextareaInput()):(this.input_type=this.format,this.input=this.theme.getFormInputField(this.input_type));else this.input_type="text",this.input=this.theme.getFormInputField(this.input_type);"undefined"!=typeof this.schema.maxLength&&this.input.setAttribute("maxlength",this.schema.maxLength),"undefined"!=typeof this.schema.pattern?this.input.setAttribute("pattern",this.schema.pattern):"undefined"!=typeof this.schema.minLength&&this.input.setAttribute("pattern",".{"+this.schema.minLength+",}"),this.options.compact?this.container.className+=" compact":this.options.input_width&&(this.input.style.width=this.options.input_width),(this.schema.readOnly||this.schema.readonly||this.schema.template)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),a.schema.template)return void(this.value=a.value);var c=this.value,d=a.sanitize(c);c!==d&&(this.value=d),a.is_dirty=!0,a.refreshValue(),a.onChange(!0)}),this.options.input_height&&(this.input.style.height=this.options.input_height),this.options.expand_height&&(this.adjust_height=function(a){if(a){var b,c=a.offsetHeight;if(a.offsetHeight<a.scrollHeight)for(b=0;a.offsetHeight<a.scrollHeight+3&&!(b>100);)b++,c++,a.style.height=c+"px";else{for(b=0;a.offsetHeight>=a.scrollHeight+3&&!(b>100);)b++,c--,a.style.height=c+"px";a.style.height=c+1+"px"}}},this.input.addEventListener("keyup",function(b){a.adjust_height(this)}),this.input.addEventListener("change",function(b){a.adjust_height(this)}),this.adjust_height()),this.format&&this.input.setAttribute("data-schemaformat",this.format),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),window.requestAnimationFrame(function(){a.input.parentNode&&a.afterInputReady(),a.adjust_height&&a.adjust_height(a.input)}),this.schema.template?(this.template=this.jsoneditor.compileTemplate(this.schema.template,this.template_engine),this.refreshValue()):this.refreshValue()},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},afterInputReady:function(){var a,b=this;if(this.source_code)if(this.options.wysiwyg&&["html","bbcode"].indexOf(this.input_type)>=0&&window.jQuery&&window.jQuery.fn&&window.jQuery.fn.sceditor)a=c({},{plugins:"html"===b.input_type?"xhtml":"bbcode",emoticonsEnabled:!1,width:"100%",height:300},f.plugins.sceditor,b.options.sceditor_options||{}),window.jQuery(b.input).sceditor(a),b.sceditor_instance=window.jQuery(b.input).sceditor("instance"),b.sceditor_instance.blur(function(){var a=window.jQuery("<div>"+b.sceditor_instance.val()+"</div>");window.jQuery("#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf",a).remove(),b.input.value=a.html(),b.value=b.input.value,b.is_dirty=!0,b.onChange(!0)});else if("markdown"===this.input_type&&window.EpicEditor)this.epiceditor_container=document.createElement("div"),this.input.parentNode.insertBefore(this.epiceditor_container,this.input),this.input.style.display="none",a=c({},f.plugins.epiceditor,{container:this.epiceditor_container,clientSideStorage:!1}),this.epiceditor=new window.EpicEditor(a).load(),this.epiceditor.importFile(null,this.getValue()),this.epiceditor.on("update",function(){var a=b.epiceditor.exportFile();b.input.value=a,b.value=a,b.is_dirty=!0,b.onChange(!0);
+});else if(window.ace){var d=this.input_type;("cpp"===d||"c++"===d||"c"===d)&&(d="c_cpp"),this.ace_container=document.createElement("div"),this.ace_container.style.width="100%",this.ace_container.style.position="relative",this.ace_container.style.height="400px",this.input.parentNode.insertBefore(this.ace_container,this.input),this.input.style.display="none",this.ace_editor=window.ace.edit(this.ace_container),this.ace_editor.setValue(this.getValue()),f.plugins.ace.theme&&this.ace_editor.setTheme("ace/theme/"+f.plugins.ace.theme),d=window.ace.require("ace/mode/"+d),d&&this.ace_editor.getSession().setMode(new d.Mode),this.ace_editor.on("change",function(){var a=b.ace_editor.getValue();b.input.value=a,b.refreshValue(),b.is_dirty=!0,b.onChange(!0)})}b.theme.afterInputReady(b.input)},refreshValue:function(){this.value=this.input.value,"string"!=typeof this.value&&(this.value=""),this.serialized=this.value},destroy:function(){this.sceditor_instance?this.sceditor_instance.destroy():this.epiceditor?this.epiceditor.unload():this.ace_editor&&this.ace_editor.destroy(),this.template=null,this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this._super()},sanitize:function(a){return a},onWatchedFieldChange:function(){var a;this.template&&(a=this.getWatchedFieldValues(),this.setValue(this.template(a),!1,!0)),this._super()},showValidationErrors:function(a){var b=this;if("always"===this.jsoneditor.options.show_errors);else if(!this.is_dirty&&this.previous_error_setting===this.jsoneditor.options.show_errors)return;this.previous_error_setting=this.jsoneditor.options.show_errors;var c=[];d(a,function(a,d){d.path===b.path&&c.push(d.message)}),c.length?this.theme.addInputError(this.input,c.join(". ")+"."):this.theme.removeInputError(this.input)}}),f.defaults.editors.number=f.defaults.editors.string.extend({sanitize:function(a){return(a+"").replace(/[^0-9\.\-eE]/g,"")},getNumColumns:function(){return 2},getValue:function(){return 1*this.value}}),f.defaults.editors.integer=f.defaults.editors.number.extend({sanitize:function(a){return a+="",a.replace(/[^0-9\-]/g,"")},getNumColumns:function(){return 2}}),f.defaults.editors.object=f.AbstractEditor.extend({getDefault:function(){return c({},this.schema["default"]||{})},getChildEditors:function(){return this.editors},register:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].register()},unregister:function(){if(this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.maxwidth),3)},enable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!1),this.addproperty_button&&(this.addproperty_button.disabled=!1),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].enable()},disable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!0),this.addproperty_button&&(this.addproperty_button.disabled=!0),this.hideEditJSON(),this._super(),this.editors)for(var a in this.editors)this.editors.hasOwnProperty(a)&&this.editors[a].disable()},layoutEditors:function(){var a,b,c=this;if(this.row_container){this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(a,b){var d=c.editors[a].schema.propertyOrder,e=c.editors[b].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e});var e;if("grid"===this.format){var f=[];for(d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){for(var e=!1,g=d.options.hidden?0:d.options.grid_columns||d.getNumColumns(),h=d.options.hidden?0:d.container.offsetHeight,i=0;i<f.length;i++)f[i].width+g<=12&&(!h||.5*f[i].minh<h&&2*f[i].maxh>h)&&(e=i);e===!1&&(f.push({width:0,minh:999999,maxh:0,editors:[]}),e=f.length-1),f[e].editors.push({key:b,width:g,height:h}),f[e].width+=g,f[e].minh=Math.min(f[e].minh,h),f[e].maxh=Math.max(f[e].maxh,h)}}),a=0;a<f.length;a++)if(f[a].width<12){var g=!1,h=0;for(b=0;b<f[a].editors.length;b++)g===!1?g=b:f[a].editors[b].width>f[a].editors[g].width&&(g=b),f[a].editors[b].width*=12/f[a].width,f[a].editors[b].width=Math.floor(f[a].editors[b].width),h+=f[a].editors[b].width;12>h&&(f[a].editors[g].width+=12-h),f[a].width=12}if(this.layout===JSON.stringify(f))return!1;for(this.layout=JSON.stringify(f),e=document.createElement("div"),a=0;a<f.length;a++){var i=this.theme.getGridRow();for(e.appendChild(i),b=0;b<f[a].editors.length;b++){var j=f[a].editors[b].key,k=this.editors[j];k.options.hidden?k.container.style.display="none":this.theme.setGridColumnSize(k.container,f[a].editors[b].width),i.appendChild(k.container)}}}else e=document.createElement("div"),d(this.property_order,function(a,b){var d=c.editors[b];if(!d.property_removed){var f=c.theme.getGridRow();e.appendChild(f),d.options.hidden?d.container.style.display="none":c.theme.setGridColumnSize(d.container,12),f.appendChild(d.container)}});this.row_container.innerHTML="",this.row_container.appendChild(e)}},getPropertySchema:function(a){var b=this.schema.properties[a]||{};b=c({},b);var d=this.schema.properties[a]?!0:!1;if(this.schema.patternProperties)for(var e in this.schema.patternProperties)if(this.schema.patternProperties.hasOwnProperty(e)){var f=new RegExp(e);f.test(a)&&(b.allOf=b.allOf||[],b.allOf.push(this.schema.patternProperties[e]),d=!0)}return!d&&this.schema.additionalProperties&&"object"==typeof this.schema.additionalProperties&&(b=c({},this.schema.additionalProperties)),b},preBuild:function(){this._super(),this.editors={},this.cached_editors={};var a=this;if(this.format=this.options.layout||this.options.object_layout||this.schema.format||this.jsoneditor.options.object_layout||"normal",this.schema.properties=this.schema.properties||{},this.minwidth=0,this.maxwidth=0,this.options.table_row)d(this.schema.properties,function(b,c){var d=a.jsoneditor.getEditorClass(c);a.editors[b]=a.jsoneditor.createEditor(d,{jsoneditor:a.jsoneditor,schema:c,path:a.path+"."+b,parent:a,compact:!0,required:!0}),a.editors[b].preBuild();var e=a.editors[b].options.hidden?0:a.editors[b].options.grid_columns||a.editors[b].getNumColumns();a.minwidth+=e,a.maxwidth+=e}),this.no_link_holder=!0;else{if(this.options.table)throw"Not supported yet";this.defaultProperties=this.schema.defaultProperties||Object.keys(this.schema.properties),a.maxwidth+=1,d(this.defaultProperties,function(b,c){a.addObjectProperty(c,!0),a.editors[c]&&(a.minwidth=Math.max(a.minwidth,a.editors[c].options.grid_columns||a.editors[c].getNumColumns()),a.maxwidth+=a.editors[c].options.grid_columns||a.editors[c].getNumColumns())})}this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(b,c){var d=a.editors[b].schema.propertyOrder,e=a.editors[c].schema.propertyOrder;return"number"!=typeof d&&(d=1e3),"number"!=typeof e&&(e=1e3),d-e})},build:function(){var a=this;if(this.options.table_row)this.editor_holder=this.container,d(this.editors,function(b,c){var d=a.theme.getTableCell();a.editor_holder.appendChild(d),c.setContainer(d),c.build(),c.postBuild(),a.editors[b].options.hidden&&(d.style.display="none"),a.editors[b].options.input_width&&(d.style.width=a.editors[b].options.input_width)});else{if(this.options.table)throw"Not supported yet";this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header),this.container.appendChild(this.title),this.container.style.position="relative",this.editjson_holder=this.theme.getModal(),this.editjson_textarea=this.theme.getTextareaInput(),this.editjson_textarea.style.height="170px",this.editjson_textarea.style.width="300px",this.editjson_textarea.style.display="block",this.editjson_save=this.getButton("Save","save","Save"),this.editjson_save.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.saveJSON()}),this.editjson_cancel=this.getButton("Cancel","cancel","Cancel"),this.editjson_cancel.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.hideEditJSON()}),this.editjson_holder.appendChild(this.editjson_textarea),this.editjson_holder.appendChild(this.editjson_save),this.editjson_holder.appendChild(this.editjson_cancel),this.addproperty_holder=this.theme.getModal(),this.addproperty_list=document.createElement("div"),this.addproperty_list.style.width="295px",this.addproperty_list.style.maxHeight="160px",this.addproperty_list.style.padding="5px 0",this.addproperty_list.style.overflowY="auto",this.addproperty_list.style.overflowX="hidden",this.addproperty_list.style.paddingLeft="5px",this.addproperty_list.setAttribute("class","property-selector"),this.addproperty_add=this.getButton("add","add","add"),this.addproperty_input=this.theme.getFormInputField("text"),this.addproperty_input.setAttribute("placeholder","Property name..."),this.addproperty_input.style.width="220px",this.addproperty_input.style.marginBottom="0",this.addproperty_input.style.display="inline-block",this.addproperty_add.addEventListener("click",function(b){if(b.preventDefault(),b.stopPropagation(),a.addproperty_input.value){if(a.editors[a.addproperty_input.value])return void window.alert("there is already a property with that name");a.addObjectProperty(a.addproperty_input.value),a.editors[a.addproperty_input.value]&&a.editors[a.addproperty_input.value].disable(),a.onChange(!0)}}),this.addproperty_holder.appendChild(this.addproperty_list),this.addproperty_holder.appendChild(this.addproperty_input),this.addproperty_holder.appendChild(this.addproperty_add);var b=document.createElement("div");b.style.clear="both",this.addproperty_holder.appendChild(b),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),this.editor_holder=this.theme.getIndentedPanel(),this.editor_holder.style.paddingBottom="0",this.container.appendChild(this.editor_holder),this.row_container=this.theme.getGridContainer(),this.editor_holder.appendChild(this.row_container),d(this.editors,function(b,c){var d=a.theme.getGridColumn();a.row_container.appendChild(d),c.setContainer(d),c.build(),c.postBuild()}),this.title_controls=this.theme.getHeaderButtonHolder(),this.editjson_controls=this.theme.getHeaderButtonHolder(),this.addproperty_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.title.appendChild(this.editjson_controls),this.title.appendChild(this.addproperty_controls),this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.editor_holder.style.display="",a.collapsed=!1,a.setButtonText(a.toggle_button,"","collapse","Collapse")):(a.editor_holder.style.display="none",a.collapsed=!0,a.setButtonText(a.toggle_button,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.editjson_button=this.getButton("JSON","edit","Edit JSON"),this.editjson_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleEditJSON()}),this.editjson_controls.appendChild(this.editjson_button),this.editjson_controls.appendChild(this.editjson_holder),this.schema.options&&"undefined"!=typeof this.schema.options.disable_edit_json?this.schema.options.disable_edit_json&&(this.editjson_button.style.display="none"):this.jsoneditor.options.disable_edit_json&&(this.editjson_button.style.display="none"),this.addproperty_button=this.getButton("Properties","edit","Object Properties"),this.addproperty_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.toggleAddProperty()}),this.addproperty_controls.appendChild(this.addproperty_button),this.addproperty_controls.appendChild(this.addproperty_holder),this.refreshAddProperties()}this.options.table_row?(this.editor_holder=this.container,d(this.property_order,function(b,c){a.editor_holder.appendChild(a.editors[c].container)})):(this.layoutEditors(),this.layoutEditors())},showEditJSON:function(){this.editjson_holder&&(this.hideAddProperty(),this.editjson_holder.style.left=this.editjson_button.offsetLeft+"px",this.editjson_holder.style.top=this.editjson_button.offsetTop+this.editjson_button.offsetHeight+"px",this.editjson_textarea.value=JSON.stringify(this.getValue(),null,2),this.disable(),this.editjson_holder.style.display="",this.editjson_button.disabled=!1,this.editing_json=!0)},hideEditJSON:function(){this.editjson_holder&&this.editing_json&&(this.editjson_holder.style.display="none",this.enable(),this.editing_json=!1)},saveJSON:function(){if(this.editjson_holder)try{var a=JSON.parse(this.editjson_textarea.value);this.setValue(a),this.hideEditJSON()}catch(b){throw window.alert("invalid JSON"),b}},toggleEditJSON:function(){this.editing_json?this.hideEditJSON():this.showEditJSON()},insertPropertyControlUsingPropertyOrder:function(a,b,c){var d;this.schema.properties[a]&&(d=this.schema.properties[a].propertyOrder),"number"!=typeof d&&(d=1e3),b.propertyOrder=d;for(var e=0;e<c.childNodes.length;e++){var f=c.childNodes[e];if(b.propertyOrder<f.propertyOrder){this.addproperty_list.insertBefore(b,f),b=null;break}}b&&this.addproperty_list.appendChild(b)},addPropertyCheckbox:function(a){var b,c,d,e,f=this;return b=f.theme.getCheckbox(),b.style.width="auto",d=this.schema.properties[a]&&this.schema.properties[a].title?this.schema.properties[a].title:a,c=f.theme.getCheckboxLabel(d),e=f.theme.getFormControl(c,b),e.style.paddingBottom=e.style.marginBottom=e.style.paddingTop=e.style.marginTop=0,e.style.height="auto",this.insertPropertyControlUsingPropertyOrder(a,e,this.addproperty_list),b.checked=a in this.editors,b.addEventListener("change",function(){b.checked?f.addObjectProperty(a):f.removeObjectProperty(a),f.onChange(!0)}),f.addproperty_checkboxes[a]=b,b},showAddProperty:function(){this.addproperty_holder&&(this.hideEditJSON(),this.addproperty_holder.style.left=this.addproperty_button.offsetLeft+"px",this.addproperty_holder.style.top=this.addproperty_button.offsetTop+this.addproperty_button.offsetHeight+"px",this.disable(),this.adding_property=!0,this.addproperty_button.disabled=!1,this.addproperty_holder.style.display="",this.refreshAddProperties())},hideAddProperty:function(){this.addproperty_holder&&this.adding_property&&(this.addproperty_holder.style.display="none",this.enable(),this.adding_property=!1)},toggleAddProperty:function(){this.adding_property?this.hideAddProperty():this.showAddProperty()},removeObjectProperty:function(a){this.editors[a]&&(this.editors[a].unregister(),delete this.editors[a],this.refreshValue(),this.layoutEditors())},addObjectProperty:function(a,b){var c=this;if(!this.editors[a]){if(this.cached_editors[a]){if(this.editors[a]=this.cached_editors[a],b)return;this.editors[a].register()}else{if(!(this.canHaveAdditionalProperties()||this.schema.properties&&this.schema.properties[a]))return;var d=c.getPropertySchema(a),e=c.jsoneditor.getEditorClass(d);if(c.editors[a]=c.jsoneditor.createEditor(e,{jsoneditor:c.jsoneditor,schema:d,path:c.path+"."+a,parent:c}),c.editors[a].preBuild(),!b){var f=c.theme.getChildEditorHolder();c.editor_holder.appendChild(f),c.editors[a].setContainer(f),c.editors[a].build(),c.editors[a].postBuild()}c.cached_editors[a]=c.editors[a]}b||(c.refreshValue(),c.layoutEditors())}},onChildEditorChange:function(a){this.refreshValue(),this._super(a)},canHaveAdditionalProperties:function(){return"boolean"==typeof this.schema.additionalProperties?this.schema.additionalProperties:!this.jsoneditor.options.no_additional_properties},destroy:function(){d(this.cached_editors,function(a,b){b.destroy()}),this.editor_holder&&(this.editor_holder.innerHTML=""),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.error_holder&&this.error_holder.parentNode&&this.error_holder.parentNode.removeChild(this.error_holder),this.editors=null,this.cached_editors=null,this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.editor_holder=null,this._super()},getValue:function(){var a=this._super();if(this.jsoneditor.options.remove_empty_properties||this.options.remove_empty_properties)for(var b in a)a.hasOwnProperty(b)&&(a[b]||delete a[b]);return a},refreshValue:function(){this.value={};for(var a in this.editors)this.editors.hasOwnProperty(a)&&(this.value[a]=this.editors[a].getValue());this.adding_property&&this.refreshAddProperties()},refreshAddProperties:function(){if(this.options.disable_properties||this.options.disable_properties!==!1&&this.jsoneditor.options.disable_properties)return void(this.addproperty_controls.style.display="none");var a,b=!1,c=!1,d=0,e=!1;for(a in this.editors)this.editors.hasOwnProperty(a)&&d++;b=this.canHaveAdditionalProperties()&&!("undefined"!=typeof this.schema.maxProperties&&d>=this.schema.maxProperties),this.addproperty_checkboxes&&(this.addproperty_list.innerHTML=""),this.addproperty_checkboxes={};for(a in this.cached_editors)this.cached_editors.hasOwnProperty(a)&&(this.addPropertyCheckbox(a),this.isRequired(this.cached_editors[a])&&a in this.editors&&(this.addproperty_checkboxes[a].disabled=!0),"undefined"!=typeof this.schema.minProperties&&d<=this.schema.minProperties?(this.addproperty_checkboxes[a].disabled=this.addproperty_checkboxes[a].checked,this.addproperty_checkboxes[a].checked||(e=!0)):a in this.editors?(e=!0,c=!0):b||this.schema.properties.hasOwnProperty(a)?(this.addproperty_checkboxes[a].disabled=!1,e=!0):this.addproperty_checkboxes[a].disabled=!0);this.canHaveAdditionalProperties()&&(e=!0);for(a in this.schema.properties)this.schema.properties.hasOwnProperty(a)&&(this.cached_editors[a]||(e=!0,this.addPropertyCheckbox(a)));e?this.canHaveAdditionalProperties()?b?this.addproperty_add.disabled=!1:this.addproperty_add.disabled=!0:(this.addproperty_add.style.display="none",this.addproperty_input.style.display="none"):(this.hideAddProperty(),this.addproperty_controls.style.display="none")},isRequired:function(a){return"boolean"==typeof a.schema.required?a.schema.required:Array.isArray(this.schema.required)?this.schema.required.indexOf(a.key)>-1:this.jsoneditor.options.required_by_default?!0:!1},setValue:function(a,b){var c=this;a=a||{},("object"!=typeof a||Array.isArray(a))&&(a={}),d(this.cached_editors,function(d,e){"undefined"!=typeof a[d]?(c.addObjectProperty(d),e.setValue(a[d],b)):b||c.isRequired(e)?e.setValue(e.getDefault(),b):c.removeObjectProperty(d)}),d(a,function(a,d){c.cached_editors[a]||(c.addObjectProperty(a),c.editors[a]&&c.editors[a].setValue(d,b))}),this.refreshValue(),this.layoutEditors(),this.onChange()},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";this.options.table_row&&(c.length?this.theme.addTableRowError(this.container):this.theme.removeTableRowError(this.container)),d(this.editors,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.array=f.AbstractEditor.extend({getDefault:function(){return this.schema["default"]||[]},register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){var a=this.getItemInfo(0);return this.tabs_holder?Math.max(Math.min(12,a.width+2),4):a.width},enable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!1),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!1),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!1),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].enable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!1),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!1),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!1);this._super()},disable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!0),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!0),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!0),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].disable(),this.rows[a].moveup_button&&(this.rows[a].moveup_button.disabled=!0),this.rows[a].movedown_button&&(this.rows[a].movedown_button.disabled=!0),this.rows[a].delete_button&&(this.rows[a].delete_button.disabled=!0);this._super()},preBuild:function(){this._super(),this.rows=[],this.row_cache=[],this.hide_delete_buttons=this.options.disable_array_delete||this.jsoneditor.options.disable_array_delete,this.hide_move_buttons=this.options.disable_array_reorder||this.jsoneditor.options.disable_array_reorder,this.hide_add_button=this.options.disable_array_add||this.jsoneditor.options.disable_array_add},build:function(){this.options.compact?(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder)):(this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header,this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),"tabs"===this.schema.format?(this.controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.controls),this.tabs_holder=this.theme.getTabHolder(),this.container.appendChild(this.tabs_holder),this.row_holder=this.theme.getTabContentHolder(this.tabs_holder),this.active_tab=null):(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls))),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this.refreshTabs(!0),this._super(a)},getItemTitle:function(){if(!this.item_title)if(this.schema.items&&!Array.isArray(this.schema.items)){var a=this.jsoneditor.expandRefs(this.schema.items);this.item_title=a.title||"item"}else this.item_title="item";return this.item_title},getItemSchema:function(a){return Array.isArray(this.schema.items)?a>=this.schema.items.length?this.schema.additionalItems===!0?{}:this.schema.additionalItems?c({},this.schema.additionalItems):void 0:c({},this.schema.items[a]):this.schema.items?c({},this.schema.items):{}},getItemInfo:function(a){var b=this.getItemSchema(a);this.item_info=this.item_info||{};var c=JSON.stringify(b);return"undefined"!=typeof this.item_info[c]?this.item_info[c]:(b=this.jsoneditor.expandRefs(b),this.item_info[c]={title:b.title||"item","default":b["default"],width:12,child_editors:b.properties||b.items},this.item_info[c])},getElementEditor:function(a){var b=this.getItemInfo(a),c=this.getItemSchema(a);c=this.jsoneditor.expandRefs(c),c.title=b.title+" "+(a+1);var d,e=this.jsoneditor.getEditorClass(c);d=this.tabs_holder?this.theme.getTabContent():b.child_editors?this.theme.getChildEditorHolder():this.theme.getIndentedPanel(),this.row_holder.appendChild(d);var f=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:c,container:d,path:this.path+"."+a,parent:this,required:!0});return f.preBuild(),f.build(),f.postBuild(),f.title_controls||(f.array_controls=this.theme.getButtonHolder(),d.appendChild(f.array_controls)),f},destroy:function(){this.empty(!0),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.controls&&this.controls.parentNode&&this.controls.parentNode.removeChild(this.controls),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.row_cache=this.title=this.description=this.row_holder=this.panel=this.controls=null,this._super()},empty:function(a){if(this.rows){var b=this;d(this.rows,function(c,d){a&&(d.tab&&d.tab.parentNode&&d.tab.parentNode.removeChild(d.tab),b.destroyRow(d,!0),b.row_cache[c]=null),b.rows[c]=null}),b.rows=[],a&&(b.row_cache=[])}},destroyRow:function(a,b){var c=a.container;b?(a.destroy(),c.parentNode&&c.parentNode.removeChild(c),a.tab&&a.tab.parentNode&&a.tab.parentNode.removeChild(a.tab)):(a.tab&&(a.tab.style.display="none"),c.style.display="none",a.unregister())},getMax:function(){return Array.isArray(this.schema.items)&&this.schema.additionalItems===!1?Math.min(this.schema.items.length,this.schema.maxItems||1/0):this.schema.maxItems||1/0},refreshTabs:function(a){var b=this;d(this.rows,function(c,d){d.tab&&(a?d.tab_text.textContent=d.getHeaderText():d.tab===b.active_tab?(b.theme.markTabActive(d.tab),d.container.style.display=""):(b.theme.markTabInactive(d.tab),d.container.style.display="none"))})},setValue:function(a,b){a=a||[],Array.isArray(a)||(a=[a]);var c=JSON.stringify(a);if(c!==this.serialized){if(this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemInfo(a.length)["default"]);this.getMax()&&a.length>this.getMax()&&(a=a.slice(0,this.getMax()));var e=this;d(a,function(a,c){e.rows[a]?e.rows[a].setValue(c,b):e.row_cache[a]?(e.rows[a]=e.row_cache[a],e.rows[a].setValue(c,b),e.rows[a].container.style.display="",e.rows[a].tab&&(e.rows[a].tab.style.display=""),e.rows[a].register()):e.addRow(c,b)});for(var f=a.length;f<e.rows.length;f++)e.destroyRow(e.rows[f]),e.rows[f]=null;e.rows=e.rows.slice(0,a.length);var g=null;d(e.rows,function(a,b){return b.tab===e.active_tab?(g=b.tab,!1):void 0}),!g&&e.rows.length&&(g=e.rows[0].tab),e.active_tab=g,e.refreshValue(b),e.refreshTabs(!0),e.refreshTabs(),e.onChange()}},refreshValue:function(a){var b=this,c=this.value?this.value.length:0;if(this.value=[],d(this.rows,function(a,c){b.value[a]=c.getValue()}),c!==this.value.length||a){var e=this.schema.minItems&&this.schema.minItems>=this.rows.length;d(this.rows,function(a,c){c.movedown_button&&(a===b.rows.length-1?c.movedown_button.style.display="none":c.movedown_button.style.display=""),c.delete_button&&(e?c.delete_button.style.display="none":c.delete_button.style.display=""),b.value[a]=c.getValue()});var f=!1;this.value.length?1===this.value.length?(this.remove_all_rows_button.style.display="none",e||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",f=!0)):e||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",f=!0):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"),this.getMax()&&this.getMax()<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",f=!0),!this.collapsed&&f?this.controls.style.display="inline-block":this.controls.style.display="none"}},addRow:function(a,b){var c=this,e=this.rows.length;c.rows[e]=this.getElementEditor(e),c.row_cache[e]=c.rows[e],c.tabs_holder&&(c.rows[e].tab_text=document.createElement("span"),c.rows[e].tab_text.textContent=c.rows[e].getHeaderText(),c.rows[e].tab=c.theme.getTab(c.rows[e].tab_text),c.rows[e].tab.addEventListener("click",function(a){c.active_tab=c.rows[e].tab,c.refreshTabs(),a.preventDefault(),a.stopPropagation()}),c.theme.addTab(c.tabs_holder,c.rows[e].tab));var f=c.rows[e].title_controls||c.rows[e].array_controls;c.hide_delete_buttons||(c.rows[e].delete_button=this.getButton(c.getItemTitle(),"delete","Delete "+c.getItemTitle()),c.rows[e].delete_button.className+=" delete",c.rows[e].delete_button.setAttribute("data-i",e),c.rows[e].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),e=c.getValue(),f=[],g=null;d(e,function(a,d){return a===b?void(c.rows[a].tab===c.active_tab&&(c.rows[a+1]?g=c.rows[a].tab:a&&(g=c.rows[a-1].tab))):void f.push(d)}),c.setValue(f),g&&(c.active_tab=g,c.refreshTabs()),c.onChange(!0)}),f&&f.appendChild(c.rows[e].delete_button)),e&&!c.hide_move_buttons&&(c.rows[e].moveup_button=this.getButton("","moveup","Move up"),c.rows[e].moveup_button.className+=" moveup",c.rows[e].moveup_button.setAttribute("data-i",e),c.rows[e].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i");if(!(0>=b)){var d=c.getValue(),e=d[b-1];d[b-1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b-1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].moveup_button)),c.hide_move_buttons||(c.rows[e].movedown_button=this.getButton("","movedown","Move down"),c.rows[e].movedown_button.className+=" movedown",c.rows[e].movedown_button.setAttribute("data-i",e),c.rows[e].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var b=1*this.getAttribute("data-i"),d=c.getValue();if(!(b>=d.length-1)){var e=d[b+1];d[b+1]=d[b],d[b]=e,c.setValue(d),c.active_tab=c.rows[b+1].tab,c.refreshTabs(),c.onChange(!0)}}),f&&f.appendChild(c.rows[e].movedown_button)),a&&c.rows[e].setValue(a,b),c.refreshTabs()},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button);var b=a.row_holder.style.display,c=a.controls.style.display;this.toggle_button.addEventListener("click",function(d){d.preventDefault(),d.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel&&(a.panel.style.display=""),a.row_holder.style.display=b,a.tabs_holder&&(a.tabs_holder.style.display=""),a.controls.style.display=c,a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.row_holder.style.display="none",a.tabs_holder&&(a.tabs_holder.style.display="none"),a.controls.style.display="none",a.panel&&(a.panel.style.display="none"),a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.rows.length;a.row_cache[c]?(a.rows[c]=a.row_cache[c],a.rows[c].setValue(a.rows[c].getDefault()),a.rows[c].container.style.display="",a.rows[c].tab&&(a.rows[c].tab.style.display=""),a.rows[c].register()):a.addRow(),a.active_tab=a.rows[c].tab,a.refreshTabs(),a.refreshValue(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),
+this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue(),d=null;a.rows.length>1&&a.rows[a.rows.length-1].tab===a.active_tab&&(d=a.rows[a.rows.length-2].tab),c.pop(),a.setValue(c),d&&(a.active_tab=d,a.refreshTabs()),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button),a.tabs&&(this.add_row_button.style.width="100%",this.add_row_button.style.textAlign="left",this.add_row_button.style.marginBottom="3px",this.delete_last_row_button.style.width="100%",this.delete_last_row_button.style.textAlign="left",this.delete_last_row_button.style.marginBottom="3px",this.remove_all_rows_button.style.width="100%",this.remove_all_rows_button.style.textAlign="left",this.remove_all_rows_button.style.marginBottom="3px")},showValidationErrors:function(a){var b=this,c=[],e=[];if(d(a,function(a,d){d.path===b.path?c.push(d):e.push(d)}),this.error_holder)if(c.length){this.error_holder.innerHTML="",this.error_holder.style.display="",d(c,function(a,c){b.error_holder.appendChild(b.theme.getErrorMessage(c.message))})}else this.error_holder.style.display="none";d(this.rows,function(a,b){b.showValidationErrors(e)})}}),f.defaults.editors.table=f.defaults.editors.array.extend({register:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].register()},unregister:function(){if(this._super(),this.rows)for(var a=0;a<this.rows.length;a++)this.rows[a].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.width),3)},preBuild:function(){var a=this.jsoneditor.expandRefs(this.schema.items||{});this.item_title=a.title||"row",this.item_default=a["default"]||null,this.item_has_child_editors=a.properties||a.items,this.width=12,this._super()},build:function(){var a=this;this.table=this.theme.getTable(),this.container.appendChild(this.table),this.thead=this.theme.getTableHead(),this.table.appendChild(this.thead),this.header_row=this.theme.getTableRow(),this.thead.appendChild(this.header_row),this.row_holder=this.theme.getTableBody(),this.table.appendChild(this.row_holder);var b=this.getElementEditor(0,!0);if(this.item_default=b.getDefault(),this.width=b.getNumColumns()+2,this.options.compact?(this.panel=document.createElement("div"),this.container.appendChild(this.panel)):(this.title=this.theme.getHeader(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.error_holder=document.createElement("div"),this.panel.appendChild(this.error_holder)),this.panel.appendChild(this.table),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.item_has_child_editors)for(var c=b.getChildEditors(),d=b.property_order||Object.keys(c),e=0;e<d.length;e++){var f=a.theme.getTableHeaderCell(c[d[e]].getTitle());c[d[e]].options.hidden&&(f.style.display="none"),a.header_row.appendChild(f)}else a.header_row.appendChild(a.theme.getTableHeaderCell(this.item_title));b.destroy(),this.row_holder.innerHTML="",this.controls_header_cell=a.theme.getTableHeaderCell(" "),a.header_row.appendChild(this.controls_header_cell),this.addControls()},onChildEditorChange:function(a){this.refreshValue(),this._super()},getItemDefault:function(){return c({},{"default":this.item_default})["default"]},getItemTitle:function(){return this.item_title},getElementEditor:function(a,b){var d=c({},this.schema.items),e=this.jsoneditor.getEditorClass(d,this.jsoneditor),f=this.row_holder.appendChild(this.theme.getTableRow()),g=f;this.item_has_child_editors||(g=this.theme.getTableCell(),f.appendChild(g));var h=this.jsoneditor.createEditor(e,{jsoneditor:this.jsoneditor,schema:d,container:g,path:this.path+"."+a,parent:this,compact:!0,table_row:!0});return h.preBuild(),b||(h.build(),h.postBuild(),h.controls_cell=f.appendChild(this.theme.getTableCell()),h.row=f,h.table_controls=this.theme.getButtonHolder(),h.controls_cell.appendChild(h.table_controls),h.table_controls.style.margin=0,h.table_controls.style.padding=0),h},destroy:function(){this.innerHTML="",this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.table&&this.table.parentNode&&this.table.parentNode.removeChild(this.table),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.title=this.description=this.row_holder=this.table=this.panel=null,this._super()},setValue:function(a,b){if(a=a||[],this.schema.minItems)for(;a.length<this.schema.minItems;)a.push(this.getItemDefault());this.schema.maxItems&&a.length>this.schema.maxItems&&(a=a.slice(0,this.schema.maxItems));var c=JSON.stringify(a);if(c!==this.serialized){var e=!1,f=this;d(a,function(a,b){f.rows[a]?f.rows[a].setValue(b):(f.addRow(b),e=!0)});for(var g=a.length;g<f.rows.length;g++){var h=f.rows[g].container;f.item_has_child_editors||f.rows[g].row.parentNode.removeChild(f.rows[g].row),f.rows[g].destroy(),h.parentNode&&h.parentNode.removeChild(h),f.rows[g]=null,e=!0}f.rows=f.rows.slice(0,a.length),f.refreshValue(),(e||b)&&f.refreshRowButtons(),f.onChange()}},refreshRowButtons:function(){var a=this,b=this.schema.minItems&&this.schema.minItems>=this.rows.length,c=!1;d(this.rows,function(d,e){e.movedown_button&&(d===a.rows.length-1?e.movedown_button.style.display="none":(c=!0,e.movedown_button.style.display="")),e.delete_button&&(b?e.delete_button.style.display="none":(c=!0,e.delete_button.style.display="")),e.moveup_button&&(c=!0)}),d(this.rows,function(a,b){c?b.controls_cell.style.display="":b.controls_cell.style.display="none"}),c?this.controls_header_cell.style.display="":this.controls_header_cell.style.display="none";var e=!1;this.value.length?1===this.value.length||this.hide_delete_buttons?(this.table.style.display="",this.remove_all_rows_button.style.display="none",b||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",e=!0)):(this.table.style.display="",b||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",e=!0)):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none",this.table.style.display="none"),this.schema.maxItems&&this.schema.maxItems<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",e=!0),e?this.controls.style.display="":this.controls.style.display="none"},refreshValue:function(){var a=this;this.value=[],d(this.rows,function(b,c){a.value[b]=c.getValue()}),this.serialized=JSON.stringify(this.value)},addRow:function(a){var b=this,c=this.rows.length;b.rows[c]=this.getElementEditor(c);var e=b.rows[c].table_controls;this.hide_delete_buttons||(b.rows[c].delete_button=this.getButton("","delete","Delete"),b.rows[c].delete_button.className+=" delete",b.rows[c].delete_button.setAttribute("data-i",c),b.rows[c].delete_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),e=b.getValue(),f=[];d(e,function(a,b){a!==c&&f.push(b)}),b.setValue(f),b.onChange(!0)}),e.appendChild(b.rows[c].delete_button)),c&&!this.hide_move_buttons&&(b.rows[c].moveup_button=this.getButton("","moveup","Move up"),b.rows[c].moveup_button.className+=" moveup",b.rows[c].moveup_button.setAttribute("data-i",c),b.rows[c].moveup_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i");if(!(0>=c)){var d=b.getValue(),e=d[c-1];d[c-1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].moveup_button)),this.hide_move_buttons||(b.rows[c].movedown_button=this.getButton("","movedown","Move down"),b.rows[c].movedown_button.className+=" movedown",b.rows[c].movedown_button.setAttribute("data-i",c),b.rows[c].movedown_button.addEventListener("click",function(a){a.preventDefault(),a.stopPropagation();var c=1*this.getAttribute("data-i"),d=b.getValue();if(!(c>=d.length-1)){var e=d[c+1];d[c+1]=d[c],d[c]=e,b.setValue(d),b.onChange(!0)}}),e.appendChild(b.rows[c].movedown_button)),a&&b.rows[c].setValue(a)},addControls:function(){var a=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls&&(this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.collapsed?(a.collapsed=!1,a.panel.style.display="",a.setButtonText(this,"","collapse","Collapse")):(a.collapsed=!0,a.panel.style.display="none",a.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&e(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none")),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.addRow(),a.refreshValue(),a.refreshRowButtons(),a.onChange(!0)}),a.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),this.delete_last_row_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation();var c=a.getValue();c.pop(),a.setValue(c),a.onChange(!0)}),a.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(b){b.preventDefault(),b.stopPropagation(),a.setValue([]),a.onChange(!0)}),a.controls.appendChild(this.remove_all_rows_button)}}),f.defaults.editors.multiple=f.AbstractEditor.extend({register:function(){if(this.editors){for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister();this.editors[this.type]&&this.editors[this.type].register()}this._super()},unregister:function(){if(this._super(),this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].unregister()},getNumColumns:function(){return this.editors[this.type]?Math.max(this.editors[this.type].getNumColumns(),4):4},enable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].enable();this.switcher.disabled=!1,this._super()},disable:function(){if(this.editors)for(var a=0;a<this.editors.length;a++)this.editors[a]&&this.editors[a].disable();this.switcher.disabled=!0,this._super()},switchEditor:function(a){var b=this;this.editors[a]||this.buildChildEditor(a),b.type=a,b.register();var c=b.getValue();d(b.editors,function(a,d){d&&(b.type===a?(b.keep_values&&d.setValue(c,!0),d.container.style.display=""):d.container.style.display="none")}),b.refreshValue(),b.refreshHeaderText()},buildChildEditor:function(a){var b=this,d=this.types[a],e=b.theme.getChildEditorHolder();b.editor_holder.appendChild(e);var f;"string"==typeof d?(f=c({},b.schema),f.type=d):(f=c({},b.schema,d),f=b.jsoneditor.expandRefs(f),d.required&&Array.isArray(d.required)&&b.schema.required&&Array.isArray(b.schema.required)&&(f.required=b.schema.required.concat(d.required)));var g=b.jsoneditor.getEditorClass(f);b.editors[a]=b.jsoneditor.createEditor(g,{jsoneditor:b.jsoneditor,schema:f,container:e,path:b.path,parent:b,required:!0}),b.editors[a].preBuild(),b.editors[a].build(),b.editors[a].postBuild(),b.editors[a].header&&(b.editors[a].header.style.display="none"),b.editors[a].option=b.switcher_options[a],e.addEventListener("change_header_text",function(){b.refreshHeaderText()}),a!==b.type&&(e.style.display="none")},preBuild:function(){if(this.types=[],this.type=0,this.editors=[],this.validators=[],this.keep_values=!0,"undefined"!=typeof this.jsoneditor.options.keep_oneof_values&&(this.keep_values=this.jsoneditor.options.keep_oneof_values),"undefined"!=typeof this.options.keep_oneof_values&&(this.keep_values=this.options.keep_oneof_values),this.schema.oneOf)this.oneOf=!0,this.types=this.schema.oneOf,d(this.types,function(a,b){}),delete this.schema.oneOf;else{if(this.schema.type&&"any"!==this.schema.type)Array.isArray(this.schema.type)?this.types=this.schema.type:this.types=[this.schema.type];else if(this.types=["string","number","integer","boolean","object","array","null"],this.schema.disallow){var a=this.schema.disallow;"object"==typeof a&&Array.isArray(a)||(a=[a]);var b=[];d(this.types,function(c,d){-1===a.indexOf(d)&&b.push(d)}),this.types=b}delete this.schema.type}this.display_text=this.getDisplayText(this.types)},build:function(){var a=this,b=this.container;this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.header),this.switcher=this.theme.getSwitcher(this.display_text),b.appendChild(this.switcher),this.switcher.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.switchEditor(a.display_text.indexOf(this.value)),a.onChange(!0)}),this.editor_holder=document.createElement("div"),b.appendChild(this.editor_holder),this.switcher_options=this.theme.getSwitcherOptions(this.switcher),d(this.types,function(b,d){a.editors[b]=!1;var e;"string"==typeof d?(e=c({},a.schema),e.type=d):(e=c({},a.schema,d),d.required&&Array.isArray(d.required)&&a.schema.required&&Array.isArray(a.schema.required)&&(e.required=a.schema.required.concat(d.required))),a.validators[b]=new f.Validator(a.jsoneditor,e)}),this.switchEditor(0)},onChildEditorChange:function(a){this.editors[this.type]&&(this.refreshValue(),this.refreshHeaderText()),this._super()},refreshHeaderText:function(){var a=this.getDisplayText(this.types);d(this.switcher_options,function(b,c){c.textContent=a[b]})},refreshValue:function(){this.value=this.editors[this.type].getValue()},setValue:function(a,b){var c=this;d(this.validators,function(b,d){return d.validate(a).length?void 0:(c.type=b,c.switcher.value=c.display_text[b],!1)}),this.switchEditor(this.type),this.editors[this.type].setValue(a,b),this.refreshValue(),c.onChange()},destroy:function(){d(this.editors,function(a,b){b&&b.destroy()}),this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()},showValidationErrors:function(a){var b=this;this.oneOf?d(this.editors,function(e,f){if(f){var g=b.path+".oneOf["+e+"]",h=[];d(a,function(a,d){if(d.path.substr(0,g.length)===g){var e=c({},d);e.path=b.path+e.path.substr(g.length),h.push(e)}}),f.showValidationErrors(h)}}):d(this.editors,function(b,c){c&&c.showValidationErrors(a)})}}),f.defaults.editors["enum"]=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){this.container;this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.options.enum_titles=this.options.enum_titles||[],this["enum"]=this.schema["enum"],this.selected=0,this.select_options=[],this.html_values=[];for(var a=this,b=0;b<this["enum"].length;b++)this.select_options[b]=this.options.enum_titles[b]||"Value "+(b+1),this.html_values[b]=this.getHTML(this["enum"][b]);this.switcher=this.theme.getSwitcher(this.select_options),this.container.appendChild(this.switcher),this.display_area=this.theme.getIndentedPanel(),this.container.appendChild(this.display_area),this.options.hide_display&&(this.display_area.style.display="none"),this.switcher.addEventListener("change",function(){a.selected=a.select_options.indexOf(this.value),a.value=a["enum"][a.selected],a.refreshValue(),a.onChange(!0)}),this.value=this["enum"][0],this.refreshValue(),1===this["enum"].length&&(this.switcher.style.display="none")},refreshValue:function(){var a=this;a.selected=-1;var b=JSON.stringify(this.value);return d(this["enum"],function(c,d){return b===JSON.stringify(d)?(a.selected=c,!1):void 0}),a.selected<0?void a.setValue(a["enum"][0]):(this.switcher.value=this.select_options[this.selected],void(this.display_area.innerHTML=this.html_values[this.selected]))},enable:function(){this.always_disabled||(this.switcher.disabled=!1),this._super()},disable:function(){this.switcher.disabled=!0,this._super()},getHTML:function(a){var b=this;if(null===a)return"<em>null</em>";if("object"==typeof a){var c="";return d(a,function(d,e){var f=b.getHTML(e);Array.isArray(a)||(f="<div><em>"+d+"</em>: "+f+"</div>"),c+="<li>"+f+"</li>"}),c=Array.isArray(a)?"<ol>"+c+"</ol>":"<ul style='margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;'>"+c+"</ul>"}return"boolean"==typeof a?a?"true":"false":"string"==typeof a?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):a},setValue:function(a){this.value!==a&&(this.value=a,this.refreshValue(),this.onChange())},destroy:function(){this.display_area&&this.display_area.parentNode&&this.display_area.parentNode.removeChild(this.display_area),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()}}),f.defaults.editors.select=f.AbstractEditor.extend({setValue:function(a,b){a=this.typecast(a||"");var c=a;this.enum_values.indexOf(c)<0&&(c=this.enum_values[0]),this.value!==c&&(this.input.value=this.enum_options[this.enum_values.indexOf(c)],this.select2&&this.select2.select2("val",this.input.value),this.value=c,this.onChange())},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){if(!this.enum_options)return 3;for(var a=this.getTitle().length,b=0;b<this.enum_options.length;b++)a=Math.max(a,this.enum_options[b].length+4);return Math.min(12,Math.max(a/7,2))},typecast:function(a){return"boolean"===this.schema.type?!!a:"number"===this.schema.type?1*a:"integer"===this.schema.type?Math.floor(1*a):""+a},getValue:function(){return this.value},preBuild:function(){var a=this;if(this.input_type="select",this.enum_options=[],this.enum_values=[],this.enum_display=[],this.schema["enum"]){var b=this.schema.options&&this.schema.options.enum_titles||[];d(this.schema["enum"],function(c,d){a.enum_options[c]=""+d,a.enum_display[c]=""+(b[c]||d),a.enum_values[c]=a.typecast(d)}),this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0))}else if("boolean"===this.schema.type)a.enum_display=this.schema.options&&this.schema.options.enum_titles||["true","false"],a.enum_options=["1",""],a.enum_values=[!0,!1],this.isRequired()||(a.enum_display.unshift(" "),a.enum_options.unshift("undefined"),a.enum_values.unshift(void 0));else{if(!this.schema.enumSource)throw"'select' editor requires the enum property to be set.";if(this.enumSource=[],this.enum_display=[],this.enum_options=[],this.enum_values=[],Array.isArray(this.schema.enumSource))for(h=0;h<this.schema.enumSource.length;h++)"string"==typeof this.schema.enumSource[h]?this.enumSource[h]={source:this.schema.enumSource[h]}:Array.isArray(this.schema.enumSource[h])?this.enumSource[h]=this.schema.enumSource[h]:this.enumSource[h]=c({},this.schema.enumSource[h]);else this.schema.enumValue?this.enumSource=[{source:this.schema.enumSource,value:this.schema.enumValue}]:this.enumSource=[{source:this.schema.enumSource}];for(h=0;h<this.enumSource.length;h++)this.enumSource[h].value&&(this.enumSource[h].value=this.jsoneditor.compileTemplate(this.enumSource[h].value,this.template_engine)),this.enumSource[h].title&&(this.enumSource[h].title=this.jsoneditor.compileTemplate(this.enumSource[h].title,this.template_engine)),this.enumSource[h].filter&&(this.enumSource[h].filter=this.jsoneditor.compileTemplate(this.enumSource[h].filter,this.template_engine))}},build:function(){var a=this;this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getSelectInput(this.enum_options),this.theme.setSelectOptions(this.input,this.enum_options,this.enum_display),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.onInputChange()}),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),this.value=this.enum_values[0]},onInputChange:function(){var a=this.input.value,b=a;-1===this.enum_options.indexOf(a)&&(b=this.enum_options[0]),this.value=this.enum_values[this.enum_options.indexOf(a)],this.onChange(!0)},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2&&(this.enum_options.length>2||this.enum_options.length&&this.enumSource)){var a=c({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){b.input.value=b.select2.select2("val"),b.onInputChange()})}else this.select2=null},postBuild:function(){this._super(),this.theme.afterInputReady(this.input),this.setupSelect2()},onWatchedFieldChange:function(){var a,b;if(this.enumSource){a=this.getWatchedFieldValues();for(var c=[],d=[],e=0;e<this.enumSource.length;e++)if(Array.isArray(this.enumSource[e]))c=c.concat(this.enumSource[e]),d=d.concat(this.enumSource[e]);else{var f=[];if(f=Array.isArray(this.enumSource[e].source)?this.enumSource[e].source:a[this.enumSource[e].source]){if(this.enumSource[e].slice&&(f=Array.prototype.slice.apply(f,this.enumSource[e].slice)),this.enumSource[e].filter){var g=[];for(b=0;b<f.length;b++)this.enumSource[e].filter({i:b,item:f[b],watched:a})&&g.push(f[b]);f=g}var h=[],i=[];for(b=0;b<f.length;b++){var j=f[b];this.enumSource[e].value?i[b]=this.enumSource[e].value({i:b,item:j}):i[b]=f[b],this.enumSource[e].title?h[b]=this.enumSource[e].title({i:b,item:j}):h[b]=i[b]}c=c.concat(i),d=d.concat(h)}}var k=this.value;this.theme.setSelectOptions(this.input,c,d),this.enum_options=c,this.enum_display=d,this.enum_values=c,this.select2&&this.select2.select2("destroy"),-1!==c.indexOf(k)?(this.input.value=k,this.value=k):(this.input.value=c[0],this.value=c[0]||"",this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange(),this.jsoneditor.notifyWatchers(this.path)),this.setupSelect2()}this._super()},enable:function(){this.always_disabled||(this.input.disabled=!1,this.select2&&this.select2.select2("enable",!0)),this._super()},disable:function(){this.input.disabled=!0,this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.multiselect=f.AbstractEditor.extend({preBuild:function(){this._super(),this.select_options={},this.select_values={};var a=this.jsoneditor.expandRefs(this.schema.items||{}),b=a["enum"]||[];for(this.option_keys=[],h=0;h<b.length;h++)this.sanitize(b[h])===b[h]&&(this.option_keys.push(b[h]+""),this.select_values[b[h]+""]=b[h])},build:function(){var a,b=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),!this.schema.format&&this.option_keys.length<8||"checkbox"===this.schema.format){for(this.input_type="checkboxes",this.inputs={},this.controls={},a=0;a<this.option_keys.length;a++){this.inputs[this.option_keys[a]]=this.theme.getCheckbox(),this.select_options[this.option_keys[a]]=this.inputs[this.option_keys[a]];var c=this.theme.getCheckboxLabel(this.option_keys[a]);this.controls[this.option_keys[a]]=this.theme.getFormControl(c,this.inputs[this.option_keys[a]])}this.control=this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description)}else{for(this.input_type="select",this.input=this.theme.getSelectInput(this.option_keys),this.input.multiple=!0,this.input.size=Math.min(10,this.option_keys.length),a=0;a<this.option_keys.length;a++)this.select_options[this.option_keys[a]]=this.input.children[a];(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.control=this.theme.getFormControl(this.label,this.input,this.description)}this.container.appendChild(this.control),this.control.addEventListener("change",function(c){c.preventDefault(),c.stopPropagation();var d=[];for(a=0;a<b.option_keys.length;a++)(b.select_options[b.option_keys[a]].selected||b.select_options[b.option_keys[a]].checked)&&d.push(b.select_values[b.option_keys[a]]);b.updateValue(d),b.onChange(!0)})},setValue:function(a,b){var c;for(a=a||[],"object"!=typeof a?a=[a]:Array.isArray(a)||(a=[]),c=0;c<a.length;c++)"string"!=typeof a[c]&&(a[c]+="");for(c in this.select_options)this.select_options.hasOwnProperty(c)&&(this.select_options[c]["select"===this.input_type?"selected":"checked"]=-1!==a.indexOf(c));this.updateValue(a),this.onChange()},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2){var a=window.jQuery.extend({},f.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(a=c(a,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(a);var b=this;this.select2.on("select2-blur",function(){var a=b.select2.select2("val");b.value=a,b.onChange(!0)})}else this.select2=null},onInputChange:function(){this.value=this.input.value,this.onChange(!0)},postBuild:function(){this._super(),this.setupSelect2()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){var a=this.getTitle().length;for(var b in this.select_values)this.select_values.hasOwnProperty(b)&&(a=Math.max(a,(this.select_values[b]+"").length+4));return Math.min(12,Math.max(a/7,2))},updateValue:function(a){for(var b=!1,c=[],d=0;d<a.length;d++)if(this.select_options[a[d]+""]){var e=this.sanitize(this.select_values[a[d]]);c.push(e),e!==a[d]&&(b=!0)}else b=!0;return this.value=c,this.select2&&this.select2.select2("val",this.value),b},sanitize:function(a){return"number"===this.schema.items.type?1*a:"integer"===this.schema.items.type?Math.floor(1*a):""+a},enable:function(){if(!this.always_disabled){if(this.input)this.input.disabled=!1;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!1);this.select2&&this.select2.select2("enable",!0)}this._super()},disable:function(){if(this.input)this.input.disabled=!0;else if(this.inputs)for(var a in this.inputs)this.inputs.hasOwnProperty(a)&&(this.inputs[a].disabled=!0);this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),f.defaults.editors.base64=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!window.FileReader)throw"FileReader required for base64 editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}this.preview=this.theme.getFormInputDescription(this.schema.description),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.value&&(this.last_preview=this.value,this.preview.innerHTML="",this.value)){var a=this.value.match(/^data:([^;,]+)[;,]/);if(a&&(a=a[1]),a){if(this.preview.innerHTML="<strong>Type:</strong> "+a+", <strong>Size:</strong> "+Math.floor((this.value.length-this.value.split(",")[0].length-1)/1.33333)+" bytes","image"===a.substr(0,5)){this.preview.innerHTML+="<br>";var b=document.createElement("img");b.style.maxWidth="100%",b.style.maxHeight="100px",b.src=this.value,this.preview.appendChild(b)}}else this.preview.innerHTML="<em>Invalid data URI</em>"}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.refreshPreview(),this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.upload=f.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var a=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!this.jsoneditor.options.upload)throw"Upload handler required for upload editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(b){if(b.preventDefault(),b.stopPropagation(),this.files&&this.files.length){var c=new FileReader;c.onload=function(b){a.preview_value=b.target.result,a.refreshPreview(),a.onChange(!0),c=null},c.readAsDataURL(this.files[0])}})}var b=this.schema.description;b||(b=""),this.preview=this.theme.getFormInputDescription(b),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.preview_value&&(this.last_preview=this.preview_value,this.preview.innerHTML="",this.preview_value)){var a=this,b=this.preview_value.match(/^data:([^;,]+)[;,]/);b&&(b=b[1]),b||(b="unknown");var c=this.uploader.files[0];if(this.preview.innerHTML="<strong>Type:</strong> "+b+", <strong>Size:</strong> "+c.size+" bytes","image"===b.substr(0,5)){this.preview.innerHTML+="<br>";var d=document.createElement("img");d.style.maxWidth="100%",d.style.maxHeight="100px",d.src=this.preview_value,
+this.preview.appendChild(d)}this.preview.innerHTML+="<br>";var e=this.getButton("Upload","upload","Upload");this.preview.appendChild(e),e.addEventListener("click",function(b){b.preventDefault(),e.setAttribute("disabled","disabled"),a.theme.removeInputError(a.uploader),a.theme.getProgressBar&&(a.progressBar=a.theme.getProgressBar(),a.preview.appendChild(a.progressBar)),a.jsoneditor.options.upload(a.path,c,{success:function(b){a.setValue(b),a.parent?a.parent.onChildEditorChange(a):a.jsoneditor.onChange(),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},failure:function(b){a.theme.addInputError(a.uploader,b),a.progressBar&&a.preview.removeChild(a.progressBar),e.removeAttribute("disabled")},updateProgress:function(b){a.progressBar&&(b?a.theme.updateProgressBar(a.progressBar,b):a.theme.updateProgressBarUnknown(a.progressBar))}})})}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(a){this.value!==a&&(this.value=a,this.input.value=this.value,this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),f.defaults.editors.checkbox=f.AbstractEditor.extend({setValue:function(a,b){this.value=!!a,this.input.checked=this.value,this.onChange()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){return Math.min(12,Math.max(this.getTitle().length/7,2))},build:function(){var a=this;this.options.compact||(this.label=this.header=this.theme.getCheckboxLabel(this.getTitle())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getCheckbox(),this.control=this.theme.getFormControl(this.label,this.input,this.description),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(b){b.preventDefault(),b.stopPropagation(),a.value=this.checked,a.onChange(!0)}),this.container.appendChild(this.control)},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this._super()}});var g=function(){var a=document.documentElement;return a.matches?"matches":a.webkitMatchesSelector?"webkitMatchesSelector":a.mozMatchesSelector?"mozMatchesSelector":a.msMatchesSelector?"msMatchesSelector":a.oMatchesSelector?"oMatchesSelector":void 0}();f.AbstractTheme=a.extend({getContainer:function(){return document.createElement("div")},getFloatRightLinkHolder:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.cssFloat="right",a.style.marginLeft="10px",a},getModal:function(){var a=document.createElement("div");return a.style.backgroundColor="white",a.style.border="1px solid black",a.style.boxShadow="3px 3px black",a.style.position="absolute",a.style.zIndex="10",a.style.display="none",a},getGridContainer:function(){var a=document.createElement("div");return a},getGridRow:function(){var a=document.createElement("div");return a.className="row",a},getGridColumn:function(){var a=document.createElement("div");return a},setGridColumnSize:function(a,b){},getLink:function(a){var b=document.createElement("a");return b.setAttribute("href","#"),b.appendChild(document.createTextNode(a)),b},disableHeader:function(a){a.style.color="#ccc"},disableLabel:function(a){a.style.color="#ccc"},enableHeader:function(a){a.style.color=""},enableLabel:function(a){a.style.color=""},getFormInputLabel:function(a){var b=document.createElement("label");return b.appendChild(document.createTextNode(a)),b},getCheckboxLabel:function(a){var b=this.getFormInputLabel(a);return b.style.fontWeight="normal",b},getHeader:function(a,b){var c=document.createElement("h3");return"string"==typeof a?c.textContent=a:c.appendChild(a),b&&(c.className+=" required"),c},getCheckbox:function(){var a=this.getFormInputField("checkbox");return a.style.display="inline-block",a.style.width="auto",a},getMultiCheckboxHolder:function(a,b,c){var d=document.createElement("div");b&&(b.style.display="block",d.appendChild(b));for(var e in a)a.hasOwnProperty(e)&&(a[e].style.display="inline-block",a[e].style.marginRight="20px",d.appendChild(a[e]));return c&&d.appendChild(c),d},getSelectInput:function(a){var b=document.createElement("select");return a&&this.setSelectOptions(b,a),b},getSwitcher:function(a){var b=this.getSelectInput(a);return b.style.backgroundColor="transparent",b.style.display="inline-block",b.style.fontStyle="italic",b.style.fontWeight="normal",b.style.height="auto",b.style.marginBottom=0,b.style.marginLeft="5px",b.style.padding="0 0 0 3px",b.style.width="auto",b},getSwitcherOptions:function(a){return a.getElementsByTagName("option")},setSwitcherOptions:function(a,b,c){this.setSelectOptions(a,b,c)},setSelectOptions:function(a,b,c){c=c||[],a.innerHTML="";for(var d=0;d<b.length;d++){var e=document.createElement("option");e.setAttribute("value",b[d]),e.textContent=c[d]||b[d],a.appendChild(e)}},getTextareaInput:function(){var a=document.createElement("textarea");return a.style=a.style||{},a.style.width="100%",a.style.height="300px",a.style.boxSizing="border-box",a},getRangeInput:function(a,b,c){var d=this.getFormInputField("range");return d.setAttribute("min",a),d.setAttribute("max",b),d.setAttribute("step",c),d},getFormInputField:function(a){var b=document.createElement("input");return b.setAttribute("type",a),b},afterInputReady:function(a){},getFormControl:function(a,b,c){var d=document.createElement("div");return d.className="form-control",a&&d.appendChild(a),"checkbox"===b.type?a.insertBefore(b,a.firstChild):d.appendChild(b),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.style=a.style||{},a.style.paddingLeft="10px",a.style.marginLeft="10px",a.style.borderLeft="1px solid #ccc",a},getChildEditorHolder:function(){return document.createElement("div")},getDescription:function(a){var b=document.createElement("p");return b.innerHTML=a,b},getCheckboxDescription:function(a){return this.getDescription(a)},getFormInputDescription:function(a){return this.getDescription(a)},getHeaderButtonHolder:function(){return this.getButtonHolder()},getButtonHolder:function(){return document.createElement("div")},getButton:function(a,b,c){var d=document.createElement("button");return d.type="button",this.setButtonText(d,a,b,c),d},setButtonText:function(a,b,c,d){a.innerHTML="",c&&(a.appendChild(c),a.innerHTML+=" "),a.appendChild(document.createTextNode(b)),d&&a.setAttribute("title",d)},getTable:function(){return document.createElement("table")},getTableRow:function(){return document.createElement("tr")},getTableHead:function(){return document.createElement("thead")},getTableBody:function(){return document.createElement("tbody")},getTableHeaderCell:function(a){var b=document.createElement("th");return b.textContent=a,b},getTableCell:function(){var a=document.createElement("td");return a},getErrorMessage:function(a){var b=document.createElement("p");return b.style=b.style||{},b.style.color="red",b.appendChild(document.createTextNode(a)),b},addInputError:function(a,b){},removeInputError:function(a){},addTableRowError:function(a){},removeTableRowError:function(a){},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div style='float: left; width: 130px;' class='tabs'></div><div class='content' style='margin-left: 130px;'></div><div style='clear:both;'></div>",a},applyStyles:function(a,b){a.style=a.style||{};for(var c in b)b.hasOwnProperty(c)&&(a.style[c]=b[c])},closest:function(a,b){for(;a&&a!==document;){if(!g)return!1;if(a[g](b))return a;a=a.parentNode}return!1},getTab:function(a){var b=document.createElement("div");return b.appendChild(a),b.style=b.style||{},this.applyStyles(b,{border:"1px solid #ccc",borderWidth:"1px 0 1px 1px",textAlign:"center",lineHeight:"30px",borderRadius:"5px",borderBottomRightRadius:0,borderTopRightRadius:0,fontWeight:"bold",cursor:"pointer"}),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){return this.getIndentedPanel()},markTabActive:function(a){this.applyStyles(a,{opacity:1,background:"white"})},markTabInactive:function(a){this.applyStyles(a,{opacity:.5,background:""})},addTab:function(a,b){a.children[0].appendChild(b)},getBlockLink:function(){var a=document.createElement("a");return a.style.display="block",a},getBlockLinkHolder:function(){var a=document.createElement("div");return a},getLinksHolder:function(){var a=document.createElement("div");return a},createMediaLink:function(a,b,c){a.appendChild(b),c.style.width="100%",a.appendChild(c)},createImageLink:function(a,b,c){a.appendChild(b),b.appendChild(c)}}),f.defaults.themes.bootstrap2=f.AbstractTheme.extend({getRangeInput:function(a,b,c){return this._super(a,b,c)},getGridContainer:function(){var a=document.createElement("div");return a.className="container-fluid",a},getGridRow:function(){var a=document.createElement("div");return a.className="row-fluid",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",c.style.fontWeight="bold",b&&(c.className+=" required"),c},setGridColumnSize:function(a,b){a.className="span"+b},getSelectInput:function(a){var b=this._super(a);return b.style.width="auto",b.style.maxWidth="98%",b},getFormInputField:function(a){var b=this._super(a);return b.style.width="98%",b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".control-group"),a.controls=this.closest(a,".controls"),this.closest(a,".compact")&&(a.controlgroup.className=a.controlgroup.className.replace(/control-group/g,"").replace(/[ ]{2,}/g," "),a.controls.className=a.controlgroup.className.replace(/controls/g,"").replace(/[ ]{2,}/g," "),a.style.marginBottom=0))},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-small",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-inline",b.textContent=a,b},getFormControl:function(a,b,c){var d=document.createElement("div");d.className="control-group";var e=document.createElement("div");return e.className="controls",a&&"checkbox"===b.getAttribute("type")?(d.appendChild(e),a.className+=" checkbox",a.appendChild(b),e.appendChild(a),e.style.height="30px"):(a&&(a.className+=" control-label",d.appendChild(a)),e.appendChild(b),d.appendChild(e)),c&&e.appendChild(c),d},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&a.controls&&(a.controlgroup.className+=" error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.className="tabbable tabs-left",a.innerHTML="<ul class='nav nav-tabs span2' style='margin-right: 0;'></ul><div class='tab-content span10' style='overflow:visible;'></div>",a},getTab:function(a){var b=document.createElement("li"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="tab-pane active",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("div");return b.className="bar",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.className="progress progress-striped active",a.firstChild.style.width="100%")}}),f.defaults.themes.bootstrap3=f.AbstractTheme.extend({getSelectInput:function(a){var b=this._super(a);return b.className+="form-control",b},setGridColumnSize:function(a,b){a.className="col-md-"+b},afterInputReady:function(a){a.controlgroup||(a.controlgroup=this.closest(a,".form-group"),this.closest(a,".compact")&&(a.controlgroup.style.marginBottom=0))},getTextareaInput:function(){var a=document.createElement("textarea");return a.className="form-control",a},getRangeInput:function(a,b,c){return this._super(a,b,c)},getFormInputField:function(a){var b=this._super(a);return"checkbox"!==a&&(b.className+="form-control"),b},getFormControl:function(a,b,c){var d=document.createElement("div");return a&&"checkbox"===b.type?(d.className+=" checkbox",a.appendChild(b),a.style.fontSize="14px",d.style.marginTop="0",d.appendChild(a),b.style.position="relative",b.style.cssFloat="left"):(d.className+=" form-group",a&&(a.className+=" control-label",d.appendChild(a)),d.appendChild(b)),c&&d.appendChild(c),d},getIndentedPanel:function(){var a=document.createElement("div");return a.className="well well-sm",a},getFormInputDescription:function(a){var b=document.createElement("p");return b.className="help-block",b.innerHTML=a,b},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="btn-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+="btn btn-default",d},getTable:function(){var a=document.createElement("table");return a.className="table table-bordered",a.style.width="auto",a.style.maxWidth="none",a},addInputError:function(a,b){a.controlgroup&&(a.controlgroup.className+=" has-error",a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("p"),a.errmsg.className="help-block errormsg",a.controlgroup.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none",a.controlgroup.className=a.controlgroup.className.replace(/\s?has-error/g,""))},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>",a.className="rows",a},getTab:function(a){var b=document.createElement("a");return b.className="list-group-item",b.setAttribute("href","#"),b.appendChild(a),b},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s?active/g,"")},getProgressBar:function(){var a=0,b=100,c=0,d=document.createElement("div");d.className="progress";var e=document.createElement("div");return e.className="progress-bar",e.setAttribute("role","progressbar"),e.setAttribute("aria-valuenow",c),e.setAttribute("aria-valuemin",a),e.setAttribute("aria-valuenax",b),e.innerHTML=c+"%",d.appendChild(e),d},updateProgressBar:function(a,b){if(a){var c=a.firstChild,d=b+"%";c.setAttribute("aria-valuenow",b),c.style.width=d,c.innerHTML=d}},updateProgressBarUnknown:function(a){if(a){var b=a.firstChild;a.className="progress progress-striped active",b.removeAttribute("aria-valuenow"),b.style.width="100%",b.innerHTML=""}}}),f.defaults.themes.foundation=f.AbstractTheme.extend({getChildEditorHolder:function(){var a=document.createElement("div");return a.style.marginBottom="15px",a},getSelectInput:function(a){var b=this._super(a);return b.style.minWidth="none",b.style.padding="5px",b.style.marginTop="3px",b},getSwitcher:function(a){var b=this._super(a);return b.style.paddingRight="8px",b},afterInputReady:function(a){this.closest(a,".compact")&&(a.style.marginBottom=0),a.group=this.closest(a,".form-control")},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="inline-block",b&&(c.className+=" required"),c},getFormInputField:function(a){var b=this._super(a);return b.style.width="100%",b.style.marginBottom="checkbox"===a?"0":"12px",b},getFormInputDescription:function(a){var b=document.createElement("p");return b.textContent=a,b.style.marginTop="-10px",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=document.createElement("div");return a.className="panel",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.verticalAlign="middle",a},getButtonHolder:function(){var a=document.createElement("div");return a.className="button-group",a},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className+=" small button",d},addInputError:function(a,b){a.group&&(a.group.className+=" error",a.errmsg?a.errmsg.style.display="":(a.insertAdjacentHTML("afterend",'<small class="error"></small>'),a.errmsg=a.parentNode.getElementsByClassName("error")[0]),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.group.className=a.group.className.replace(/ error/g,""),a.errmsg.style.display="none")},getProgressBar:function(){var a=document.createElement("div");a.className="progress";var b=document.createElement("span");return b.className="meter",b.style.width="0%",a.appendChild(b),a},updateProgressBar:function(a,b){a&&(a.firstChild.style.width=b+"%")},updateProgressBarUnknown:function(a){a&&(a.firstChild.style.width="100%")}}),f.defaults.themes.foundation3=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c},getTabHolder:function(){var a=document.createElement("div");return a.className="row",a.innerHTML="<dl class='tabs vertical two columns'></dl><div class='tabs-content ten columns'></div>",a},setGridColumnSize:function(a,b){var c=["zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];a.className="columns "+c[b]},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.foundation4=f.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var a=this._super();return a.style.fontSize=".6em",a},setGridColumnSize:function(a,b){a.className="columns large-"+b},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},getFormInputLabel:function(a,b){var c=this._super(a);return c.style.fontWeight="bold",b&&(c.className+=" required"),c}}),f.defaults.themes.foundation5=f.defaults.themes.foundation.extend({getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8rem",b},setGridColumnSize:function(a,b){a.className="columns medium-"+b},getButton:function(a,b,c){var d=this._super(a,b,c);return d.className=d.className.replace(/\s*small/g,"")+" tiny",d},getTabHolder:function(){var a=document.createElement("div");return a.innerHTML="<dl class='tabs vertical'></dl><div class='tabs-content vertical'></div>",a},getTab:function(a){var b=document.createElement("dd"),c=document.createElement("a");return c.setAttribute("href","#"),c.appendChild(a),b.appendChild(c),b},getTabContentHolder:function(a){return a.children[1]},getTabContent:function(){var a=document.createElement("div");return a.className="content active",a.style.paddingLeft="5px",a},markTabActive:function(a){a.className+=" active"},markTabInactive:function(a){a.className=a.className.replace(/\s*active/g,"")},addTab:function(a,b){a.children[0].appendChild(b)}}),f.defaults.themes.html=f.AbstractTheme.extend({getFormInputLabel:function(a,b){var c=this._super(a);return c.style.display="block",c.style.marginBottom="3px",c.style.fontWeight="bold",b&&(c.className+=" required"),c},getFormInputDescription:function(a){var b=this._super(a);return b.style.fontSize=".8em",b.style.margin=0,b.style.display="inline-block",b.style.fontStyle="italic",b},getIndentedPanel:function(){var a=this._super();return a.style.border="1px solid #ddd",a.style.padding="5px",a.style.margin="5px",a.style.borderRadius="3px",a},getChildEditorHolder:function(){var a=this._super();return a.style.marginBottom="8px",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.display="inline-block",a.style.marginLeft="10px",a.style.fontSize=".8em",a.style.verticalAlign="middle",a},getTable:function(){var a=this._super();return a.style.borderBottom="1px solid #ccc",a.style.marginBottom="5px",a},addInputError:function(a,b){if(a.style.borderColor="red",a.errmsg)a.errmsg.style.display="block";else{var c=this.closest(a,".form-control");a.errmsg=document.createElement("div"),a.errmsg.setAttribute("class","errmsg"),a.errmsg.style=a.errmsg.style||{},a.errmsg.style.color="red",c.appendChild(a.errmsg)}a.errmsg.innerHTML="",a.errmsg.appendChild(document.createTextNode(b))},removeInputError:function(a){a.style.borderColor="",a.errmsg&&(a.errmsg.style.display="none")},getProgressBar:function(){var a=100,b=0,c=document.createElement("progress");return c.setAttribute("max",a),c.setAttribute("value",b),c},updateProgressBar:function(a,b){a&&a.setAttribute("value",b)},updateProgressBarUnknown:function(a){a&&a.removeAttribute("value")}}),f.defaults.themes.jqueryui=f.AbstractTheme.extend({getTable:function(){var a=this._super();return a.setAttribute("cellpadding",5),a.setAttribute("cellspacing",0),a},getTableHeaderCell:function(a){var b=this._super(a);return b.className="ui-state-active",b.style.fontWeight="bold",b},getTableCell:function(){var a=this._super();return a.className="ui-widget-content",a},getHeaderButtonHolder:function(){var a=this.getButtonHolder();return a.style.marginLeft="10px",a.style.fontSize=".6em",a.style.display="inline-block",a},getFormInputDescription:function(a){var b=this.getDescription(a);return b.style.marginLeft="10px",b.style.display="inline-block",b},getFormControl:function(a,b,c){var d=this._super(a,b,c);return"checkbox"===b.type?(d.style.lineHeight="25px",d.style.padding="3px 0"):d.style.padding="4px 0 8px 0",d},getDescription:function(a){var b=document.createElement("span");return b.style.fontSize=".8em",b.style.fontStyle="italic",b.textContent=a,b},getButtonHolder:function(){var a=document.createElement("div");return a.className="ui-buttonset",a.style.fontSize=".7em",a},getFormInputLabel:function(a,b){var c=document.createElement("label");return c.style.fontWeight="bold",c.style.display="block",b&&(c.className+=" required"),c.textContent=a,c},getButton:function(a,b,c){var d=document.createElement("button");d.className="ui-button ui-widget ui-state-default ui-corner-all",b&&!a?(d.className+=" ui-button-icon-only",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):b?(d.className+=" ui-button-text-icon-primary",b.className+=" ui-button-icon-primary ui-icon-primary",d.appendChild(b)):d.className+=" ui-button-text-only";var e=document.createElement("span");return e.className="ui-button-text",e.textContent=a||c||".",d.appendChild(e),d.setAttribute("title",c),d},setButtonText:function(a,b,c,d){a.innerHTML="",a.className="ui-button ui-widget ui-state-default ui-corner-all",c&&!b?(a.className+=" ui-button-icon-only",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):c?(a.className+=" ui-button-text-icon-primary",c.className+=" ui-button-icon-primary ui-icon-primary",a.appendChild(c)):a.className+=" ui-button-text-only";var e=document.createElement("span");e.className="ui-button-text",e.textContent=b||d||".",a.appendChild(e),a.setAttribute("title",d)},getIndentedPanel:function(){var a=document.createElement("div");return a.className="ui-widget-content ui-corner-all",a.style.padding="1em 1.4em",a.style.marginBottom="20px",a},afterInputReady:function(a){a.controls||(a.controls=this.closest(a,".form-control"))},addInputError:function(a,b){a.controls&&(a.errmsg?a.errmsg.style.display="":(a.errmsg=document.createElement("div"),a.errmsg.className="ui-state-error",a.controls.appendChild(a.errmsg)),a.errmsg.textContent=b)},removeInputError:function(a){a.errmsg&&(a.errmsg.style.display="none")},markTabActive:function(a){a.className=a.className.replace(/\s*ui-widget-header/g,"")+" ui-state-active"},markTabInactive:function(a){a.className=a.className.replace(/\s*ui-state-active/g,"")+" ui-widget-header"}}),f.AbstractIconLib=a.extend({mapping:{collapse:"",expand:"","delete":"",edit:"",add:"",cancel:"",save:"",moveup:"",movedown:""},icon_prefix:"",getIconClass:function(a){return this.mapping[a]?this.icon_prefix+this.mapping[a]:null},getIcon:function(a){var b=this.getIconClass(a);if(!b)return null;var c=document.createElement("i");return c.className=b,c}}),f.defaults.iconlibs.bootstrap2=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-up","delete":"trash",edit:"pencil",add:"plus",cancel:"ban-circle",save:"ok",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.bootstrap3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"floppy-remove",save:"floppy-saved",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"glyphicon glyphicon-"}),f.defaults.iconlibs.fontawesome3=f.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"ban-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),f.defaults.iconlibs.fontawesome4=f.AbstractIconLib.extend({mapping:{collapse:"caret-square-o-down",expand:"caret-square-o-right","delete":"times",edit:"pencil",add:"plus",cancel:"ban",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fa fa-"}),f.defaults.iconlibs.foundation2=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"remove",edit:"edit",add:"add-doc",cancel:"error",save:"checkmark",moveup:"up-arrow",movedown:"down-arrow"},icon_prefix:"foundicon-"}),f.defaults.iconlibs.foundation3=f.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"x",edit:"pencil",add:"page-add",cancel:"x-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fi-"}),f.defaults.iconlibs.jqueryui=f.AbstractIconLib.extend({mapping:{collapse:"triangle-1-s",expand:"triangle-1-e","delete":"trash",edit:"pencil",add:"plusthick",cancel:"closethick",save:"disk",moveup:"arrowthick-1-n",movedown:"arrowthick-1-s"},icon_prefix:"ui-icon ui-icon-"}),f.defaults.templates["default"]=function(){return{compile:function(a){var b=a.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g),c=b&&b.length;if(!c)return function(){return a};for(var d=[],e=function(a){var c,e=b[a].replace(/[{}]+/g,"").trim().split("."),f=e.length;if(f>1){var g;c=function(b){for(g=b,a=0;f>a&&(g=g[e[a]],g);a++);return g}}else e=e[0],c=function(a){return a[e]};d.push({s:b[a],r:c})},f=0;c>f;f++)e(f);return function(b){var e,g=a+"";for(f=0;c>f;f++)e=d[f],g=g.replace(e.s,e.r(b));return g}}}},f.defaults.templates.ejs=function(){return window.EJS?{compile:function(a){var b=new window.EJS({text:a});return function(a){return b.render(a)}}}:!1},f.defaults.templates.handlebars=function(){return window.Handlebars},f.defaults.templates.hogan=function(){return window.Hogan?{compile:function(a){var b=window.Hogan.compile(a);return function(a){return b.render(a)}}}:!1},f.defaults.templates.markup=function(){return window.Mark&&window.Mark.up?{compile:function(a){return function(b){return window.Mark.up(a,b)}}}:!1},f.defaults.templates.mustache=function(){return window.Mustache?{compile:function(a){return function(b){return window.Mustache.render(a,b)}}}:!1},f.defaults.templates.swig=function(){return window.swig},f.defaults.templates.underscore=function(){return window._?{compile:function(a){return function(b){return window._.template(a,b)}}}:!1},f.defaults.theme="html",f.defaults.template="default",f.defaults.options={},f.defaults.translate=function(a,b){var c=f.defaults.languages[f.defaults.language];if(!c)throw"Unknown language "+f.defaults.language;var d=c[a]||f.defaults.languages[f.defaults.default_language][a];if("undefined"==typeof d)throw"Unknown translate string "+a;if(b)for(var e=0;e<b.length;e++)d=d.replace(new RegExp("\\{\\{"+e+"}}","g"),b[e]);return d},f.defaults.default_language="en",f.defaults.language=f.defaults.default_language,f.defaults.languages.en={error_notset:"Property must be set",error_notempty:"Value required",error_enum:"Value must be one of the enumerated values",error_anyOf:"Value must validate against at least one of the provided schemas",error_oneOf:"Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.",error_not:"Value must not validate against the provided schema",error_type_union:"Value must be one of the provided types",error_type:"Value must be of type {{0}}",error_disallow_union:"Value must not be one of the provided disallowed types",error_disallow:"Value must not be of type {{0}}",error_multipleOf:"Value must be a multiple of {{0}}",error_maximum_excl:"Value must be less than {{0}}",error_maximum_incl:"Value must at most {{0}}",error_minimum_excl:"Value must be greater than {{0}}",error_minimum_incl:"Value must be at least {{0}}",error_maxLength:"Value must be at most {{0}} characters long",error_minLength:"Value must be at least {{0}} characters long",error_pattern:"Value must match the provided pattern",error_additionalItems:"No additional items allowed in this array",error_maxItems:"Value must have at most {{0}} items",error_minItems:"Value must have at least {{0}} items",error_uniqueItems:"Array must have unique items",error_maxProperties:"Object must have at most {{0}} properties",error_minProperties:"Object must have at least {{0}} properties",error_required:"Object is missing the required property '{{0}}'",error_additional_properties:"No additional properties allowed, but property {{0}} is set",error_dependency:"Must have property {{0}}"},f.plugins={ace:{theme:""},epiceditor:{},sceditor:{},select2:{}};for(var h in f.defaults.editors)f.defaults.editors.hasOwnProperty(h)&&(f.defaults.editors[h].options=f.defaults.editors.options||{});f.defaults.resolvers.unshift(function(a){return"string"!=typeof a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return!a.type&&a.properties?"object":void 0}),f.defaults.resolvers.unshift(function(a){return"string"==typeof a.type?a.type:void 0}),f.defaults.resolvers.unshift(function(a){return"boolean"===a.type?"checkbox"===a.format||a.options&&a.options.checkbox?"checkbox":"select":void 0;
+}),f.defaults.resolvers.unshift(function(a){return"any"===a.type?"multiple":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&a.media&&"base64"===a.media.binaryEncoding?"base64":void 0}),f.defaults.resolvers.unshift(function(a){return"string"===a.type&&"url"===a.format&&a.options&&a.options.upload===!0&&window.FileReader?"upload":void 0}),f.defaults.resolvers.unshift(function(a){return"array"==a.type&&"table"==a.format?"table":void 0}),f.defaults.resolvers.unshift(function(a){return a.enumSource?"select":void 0}),f.defaults.resolvers.unshift(function(a){if(a["enum"]){if("array"===a.type||"object"===a.type)return"enum";if("number"===a.type||"integer"===a.type||"string"===a.type)return"select"}}),f.defaults.resolvers.unshift(function(a){return"array"===a.type&&a.items&&!Array.isArray(a.items)&&a.uniqueItems&&a.items["enum"]&&["string","number","integer"].indexOf(a.items.type)>=0?"multiselect":void 0}),f.defaults.resolvers.unshift(function(a){return a.oneOf?"multiple":void 0}),function(){if(window.jQuery||window.Zepto){var a=window.jQuery||window.Zepto;a.jsoneditor=f.defaults,a.fn.jsoneditor=function(a){var b=this,c=this.data("jsoneditor");if("value"===a){if(!c)throw"Must initialize jsoneditor before getting/setting the value";if(!(arguments.length>1))return c.getValue();c.setValue(arguments[1])}else{if("validate"===a){if(!c)throw"Must initialize jsoneditor before validating";return arguments.length>1?c.validate(arguments[1]):c.validate()}"destroy"===a?c&&(c.destroy(),this.data("jsoneditor",null)):(c&&c.destroy(),c=new f(this.get(0),a),this.data("jsoneditor",c),c.on("change",function(){b.trigger("change")}),c.on("ready",function(){b.trigger("ready")}))}return this}}}(),window.JSONEditor=f}();
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/lodash.min.js b/src/main/resources/META-INF/resources/icd/lib/lodash.min.js
new file mode 100644 (file)
index 0000000..05870d1
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ * @license
+ * lodash 3.10.1 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ * Build: `lodash compat -o ./lodash.js`
+ */
+;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===w,u=n===n,o=null===t,i=t===w,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(n<t&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return null==n?"":n+""}function o(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
+return r}function i(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function a(n){return Nn[n]}function c(n){return Tn[n]}function l(n,t,r){return t?n=Bn[n]:r&&(n=Dn[n]),"\\"+n}function s(n){return"\\"+Dn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
+}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=P,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Pn[n]}function m(_){function Nn(n){if(h(n)&&!(Wo(n)||n instanceof zn)){if(n instanceof Pn)return n;if(eu.call(n,"__chain__")&&eu.call(n,"__wrapped__"))return qr(n)}return new Pn(n)}function Tn(){}function Pn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
+this.__chain__=!!t}function zn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=Cu,this.__views__=[]}function Bn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:mu(null),set:new hu};t--;)this.push(n[t])}function Mn(n,t){var r=n.data;return(typeof t=="string"||de(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=De(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
+return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Zn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Xn(n,t){for(var r=-1,e=n.length,u=De(e);++r<e;)u[r]=t(n[r],r,n);return u}function Hn(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function Qn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function nt(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;
+return false}function tt(n,t,r,e){return n!==w&&eu.call(e,r)?n:t}function rt(n,t,r){for(var e=-1,u=Ko(t),o=u.length;++e<o;){var i=u[e],f=n[i],a=r(f,t[i],i,n,t);(a===a?a===f:f!==f)&&(f!==w||i in n)||(n[i]=a)}return n}function et(n,t){return null==t?n:ot(t,Ko(t),n)}function ut(n,t){for(var r=-1,e=null==n,u=!e&&Sr(n),o=u?n.length:0,i=t.length,f=De(i);++r<i;){var a=t[r];f[r]=u?Ur(a,o)?n[a]:w:e?w:n[a]}return f}function ot(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function it(n,t,r){
+var e=typeof n;return"function"==e?t===w?n:Dt(n,t,r):null==n?Ne:"object"==e?At(n):t===w?Be(n):jt(n,t)}function ft(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==w)return f;if(!de(n))return n;if(e=Wo(n)){if(f=Ir(n),!t)return qn(n,f)}else{var a=ou.call(n),c=a==K;if(a!=Z&&a!=z&&(!c||u))return Ln[a]?Er(n,a,t):u?n:{};if(Gn(n))return u?n:{};if(f=Rr(c?{}:n),!t)return et(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Kn:gt)(n,function(e,u){f[u]=ft(e,t,r,u,n,o,i);
+}),f}function at(n,t,r){if(typeof n!="function")throw new Xe(T);return _u(function(){n.apply(w,r)},t)}function ct(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=jr(),f=i===r,a=f&&t.length>=F&&mu&&hu?new Dn(t):null,c=t.length;a&&(i=Mn,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function lt(n,t){var r=true;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function st(n,t,r,e){var u=e,o=u;return zu(n,function(n,i,f){
+i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i,o=n)}),o}function pt(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function ht(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function _t(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];h(i)&&Sr(i)&&(r||Wo(i)||_e(i))?t?_t(i,t,r,e):Hn(e,i):r||(e[e.length]=i)}return e}function vt(n,t){return Du(n,t,Ee)}function gt(n,t){return Du(n,t,Ko)}function yt(n,t){return Mu(n,t,Ko)}function dt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){
+var i=t[r];ye(n[i])&&(o[++u]=i)}return o}function mt(n,t,r){if(null!=n){n=Dr(n),r!==w&&r in n&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=Dr(n)[t[r++]];return r&&r==e?n:w}}function wt(n,t,r,e,u,o){if(n===t)return true;if(null==n||null==t||!de(n)&&!h(t))return n!==n&&t!==t;n:{var i=wt,f=Wo(n),a=Wo(t),c=B,l=B;f||(c=ou.call(n),c==z?c=Z:c!=Z&&(f=je(n))),a||(l=ou.call(t),l==z?l=Z:l!=Z&&je(t));var s=c==Z&&!Gn(n),a=l==Z&&!Gn(t),l=c==l;if(!l||f||s){if(!e&&(c=s&&eu.call(n,"__wrapped__"),a=a&&eu.call(t,"__wrapped__"),
+c||a)){n=i(c?n.value():n,a?t.value():t,r,e,u,o);break n}if(l){for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n){n=o[c]==t;break n}u.push(n),o.push(t),n=(f?mr:xr)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=false}else n=wr(n,t,c)}return n}function xt(n,t,r){var e=t.length,u=e,o=!r;if(null==n)return!u;for(n=Dr(n);e--;){var i=t[e];if(o&&i[2]?i[1]!==n[i[0]]:!(i[0]in n))return false}for(;++e<u;){var i=t[e],f=i[0],a=n[f],c=i[1];if(o&&i[2]){if(a===w&&!(f in n))return false}else if(i=r?r(a,c,f):w,i===w?!wt(c,a,r,true):!i)return false;
+}return true}function bt(n,t){var r=-1,e=Sr(n)?De(n.length):[];return zu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function At(n){var t=kr(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:(n=Dr(n),n[r]===e&&(e!==w||r in n))}}return function(n){return xt(n,t)}}function jt(n,t){var r=Wo(n),e=Wr(n)&&t===t&&!de(t),u=n+"";return n=Mr(n),function(o){if(null==o)return false;var i=u;if(o=Dr(o),!(!r&&e||i in o)){if(o=1==n.length?o:mt(o,St(n,0,-1)),null==o)return false;i=Gr(n),o=Dr(o);
+}return o[i]===t?t!==w||i in o:wt(t,o[i],w,true)}}function kt(n,t,r,e,u){if(!de(n))return n;var o=Sr(t)&&(Wo(t)||je(t)),i=o?w:Ko(t);return Kn(i||t,function(f,a){if(i&&(a=f,f=t[a]),h(f)){e||(e=[]),u||(u=[]);n:{for(var c=a,l=e,s=u,p=l.length,_=t[c];p--;)if(l[p]==_){n[c]=s[p];break n}var p=n[c],v=r?r(p,_,c,n,t):w,g=v===w;g&&(v=_,Sr(_)&&(Wo(_)||je(_))?v=Wo(p)?p:Sr(p)?qn(p):[]:xe(_)||_e(_)?v=_e(p)?Ie(p):xe(p)?p:{}:g=false),l.push(_),s.push(v),g?n[c]=kt(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[c]=v)}}else c=n[a],
+l=r?r(c,f,a,n,t):w,(s=l===w)&&(l=f),l===w&&(!o||a in n)||!s&&(l===l?l===c:c!==c)||(n[a]=l)}),n}function Ot(n){return function(t){return null==t?w:Dr(t)[n]}}function It(n){var t=n+"";return n=Mr(n),function(r){return mt(r,n,t)}}function Rt(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Ur(e)){var u=e;vu.call(n,e,1)}}return n}function Et(n,t){return n+wu(Ru()*(t-n+1))}function Ct(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function St(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,
+0>t&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=De(u);++e<u;)r[e]=n[e+t];return r}function Ut(n,t){var r;return zu(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function $t(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=br(),o=-1;return r=Xn(r,function(n){return u(n)}),t=bt(t,function(n){return{a:Xn(r,function(t){return t(n)}),b:++o,c:n}}),$t(t,function(t,r){var u;n:{for(var o=-1,i=t.a,f=r.a,a=i.length,c=e.length;++o<a;)if(u=n(i[o],f[o])){
+if(o>=c)break n;o=e[o],u*="asc"===o||true===o?1:-1;break n}u=t.b-r.b}return u})}function Ft(n,t){var r=0;return zu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function Lt(n,t){var e=-1,u=jr(),o=n.length,i=u===r,f=i&&o>=F,a=f&&mu&&hu?new Dn(void 0):null,c=[];a?(u=Mn,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Nt(n,t){for(var r=-1,e=t.length,u=De(e);++r<e;)u[r]=n[t[r]];
+return u}function Tt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?St(n,e?0:o,e?o+1:u):St(n,e?o+1:0,e?u:o)}function Pt(n,t){var r=n;r instanceof zn&&(r=r.value());for(var e=-1,u=t.length;++e<u;)var o=t[e],r=o.func.apply(o.thisArg,Hn([r],o.args));return r}function zt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Uu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)&&null!==i?e=o+1:u=o}return u}return Bt(n,t,Ne,r)}function Bt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,a=t===w;u<o;){
+var c=wu((u+o)/2),l=r(n[c]),s=l!==w,p=l===l;(i?p||e:f?p&&s&&(e||null!=l):a?p&&(e||s):null==l?0:e?l<=t:l<t)?u=c+1:o=c}return ku(o,Su)}function Dt(n,t,r){if(typeof n!="function")return Ne;if(t===w)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Mt(n){var t=new au(n.byteLength);
+return new gu(t).set(new gu(n)),t}function qt(n,t,r){for(var e=r.length,u=-1,o=ju(n.length-e,0),i=-1,f=t.length,a=De(f+o);++i<f;)a[i]=t[i];for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function Kt(n,t,r){for(var e=-1,u=r.length,o=-1,i=ju(n.length-u,0),f=-1,a=t.length,c=De(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function Vt(n,t){return function(r,e,u){var o=t?t():{};if(e=br(e,u,3),Wo(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r);
+}}else zu(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function Zt(n){return pe(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u?r[u-2]:w,i=2<u?r[2]:w,f=1<u?r[u-1]:w;for(typeof o=="function"?(o=Dt(o,f,5),u-=2):(o=typeof f=="function"?f:w,u-=o?1:0),i&&$r(r[0],r[1],i)&&(o=3>u?w:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Yt(n,t){return function(r,e){var u=r?Vu(r):0;if(!Lr(u))return n(r,e);for(var o=t?u:-1,i=Dr(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function Gt(n){return function(t,r,e){
+var u=Dr(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(false===r(u[f],f,u))break}return t}}function Jt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments)}var e=Ht(n);return r}function Xt(n){return function(t){var r=-1;t=Fe(Ue(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Ht(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);
+case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=Pu(n.prototype),t=n.apply(r,t);return de(t)?t:r}}function Qt(n){function t(r,e,u){return u&&$r(r,e,u)&&(e=w),r=dr(r,n,w,w,w,w,w,e),r.placeholder=t.placeholder,r}return t}function nr(n,t){return pe(function(r){var e=r[0];return null==e?e:(r.push(t),n.apply(w,r))})}function tr(n,t){return function(r,e,u){
+if(u&&$r(r,e,u)&&(e=w),e=br(e,u,3),1==e.length){u=r=Wo(r)?r:Br(r);for(var o=e,i=-1,f=u.length,a=t,c=a;++i<f;){var l=u[i],s=+o(l);n(s,a)&&(a=s,c=l)}if(u=c,!r.length||u!==t)return u}return st(r,e,n,t)}}function rr(n,r){return function(e,u,o){return u=br(u,o,3),Wo(e)?(u=t(e,u,r),-1<u?e[u]:w):ht(e,u,n)}}function er(n){return function(r,e,u){return r&&r.length?(e=br(e,u,3),t(r,e,n)):-1}}function ur(n){return function(t,r,e){return r=br(r,e,3),ht(t,r,n,true)}}function or(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,o=De(r);n?e--:++e<r;){
+var i=o[u++]=arguments[e];if(typeof i!="function")throw new Xe(T);!t&&Pn.prototype.thru&&"wrapper"==Ar(i)&&(t=new Pn([],true))}for(e=t?-1:r;++e<r;){var i=o[e],u=Ar(i),f="wrapper"==u?Ku(i):w;t=f&&Fr(f[0])&&f[1]==(E|k|I|C)&&!f[4].length&&1==f[9]?t[Ar(f[0])].apply(t,f[3]):1==i.length&&Fr(i)?t[u]():t.thru(i)}return function(){var n=arguments,e=n[0];if(t&&1==n.length&&Wo(e)&&e.length>=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++u<r;)n=o[u].call(this,n);return n}}}function ir(n,t){
+return function(r,e,u){return typeof e=="function"&&u===w&&Wo(r)?n(r,e):t(r,Dt(e,u,3))}}function fr(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r,Ee)}}function ar(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=Dt(r,e,3)),n(t,r)}}function cr(n){return function(t,r,e){var u={};return r=br(r,e,3),gt(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function lr(n){return function(t,r,e){return t=u(t),(n?t:"")+_r(t,r,e)+(n?"":t)}}function sr(n){
+var t=pe(function(r,e){var u=v(e,t.placeholder);return dr(r,n,w,e,u)});return t}function pr(n,t){return function(r,e,u,o){var i=3>arguments.length;return typeof e=="function"&&o===w&&Wo(r)?n(r,e,u,i):Ct(r,br(e,o,4),u,i,t)}}function hr(n,t,r,e,u,o,i,f,a,c){function l(){for(var m=arguments.length,x=m,j=De(m);x--;)j[x]=arguments[x];if(e&&(j=qt(j,e,u)),o&&(j=Kt(j,o,i)),_||y){var x=l.placeholder,k=v(j,x),m=m-k.length;if(m<c){var O=f?qn(f):w,m=ju(c-m,0),E=_?k:w,k=_?w:k,C=_?j:w,j=_?w:j;return t|=_?I:R,t&=~(_?R:I),
+g||(t&=~(b|A)),j=[n,t,r,C,E,j,k,O,a,m],O=hr.apply(w,j),Fr(n)&&Zu(O,j),O.placeholder=x,O}}if(x=p?r:this,O=h?x[n]:n,f)for(m=j.length,E=ku(f.length,m),k=qn(j);E--;)C=f[E],j[E]=Ur(C,m)?k[C]:w;return s&&a<j.length&&(j.length=a),this&&this!==Yn&&this instanceof l&&(O=d||Ht(n)),O.apply(x,j)}var s=t&E,p=t&b,h=t&A,_=t&k,g=t&j,y=t&O,d=h?w:Ht(n);return l}function _r(n,t,r){return n=n.length,t=+t,n<t&&bu(t)?(t-=n,r=null==r?" ":r+"",$e(r,du(t/r.length)).slice(0,t)):""}function vr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=De(c+f);++a<c;)l[a]=e[a];
+for(;f--;)l[a++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&b,i=Ht(n);return u}function gr(n){var t=Ve[n];return function(n,r){return(r=r===w?0:+r||0)?(r=su(10,r),t(n*r)/r):t(n)}}function yr(n){return function(t,r,e,u){var o=br(e);return null==e&&o===it?zt(t,r,n):Bt(t,r,o(e,u,1),n)}}function dr(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Xe(T);var c=e?e.length:0;if(c||(t&=~(I|R),e=u=w),c-=u?u.length:0,t&R){var l=e,s=u;e=u=w}var p=a?w:Ku(n);
+return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==E&&e==k||t==E&&e==C&&r[7].length<=p[8]||t==(E|C)&&e==k,(f<E||u)&&(t&b&&(r[2]=p[2],f|=e&b?0:j),(e=p[3])&&(u=r[3],r[3]=u?qt(u,e,p[4]):qn(e),r[4]=u?v(r[3],P):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Kt(u,e,p[6]):qn(e),r[6]=u?v(r[5],P):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&E&&(r[8]=null==r[8]?p[8]:ku(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:ju(f-c,0)||0,n=t==b?Jt(r[0],r[2]):t!=I&&t!=(b|I)||r[4].length?hr.apply(w,r):vr.apply(w,r),
+(p?qu:Zu)(n,r)}function mr(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length;if(a!=c&&(!u||c<=a))return false;for(;++f<a;){var l=n[f],c=t[f],s=e?e(u?c:l,u?l:c,f):w;if(s!==w){if(s)continue;return false}if(u){if(!nt(t,function(n){return l===n||r(l,n,e,u,o,i)}))return false}else if(l!==c&&!r(l,c,e,u,o,i))return false}return true}function wr(n,t,r){switch(r){case D:case M:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Y:case G:return n==t+""}return false}function xr(n,t,r,e,u,o,i){
+var f=Ko(n),a=f.length,c=Ko(t).length;if(a!=c&&!u)return false;for(c=a;c--;){var l=f[c];if(!(u?l in t:eu.call(t,l)))return false}for(var s=u;++c<a;){var l=f[c],p=n[l],h=t[l],_=e?e(u?h:p,u?p:h,l):w;if(_===w?!r(p,h,e,u,o,i):!_)return false;s||(s="constructor"==l)}return s||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function br(n,t,r){var e=Nn.callback||Le,e=e===Le?it:e;return r?e(n,t,r):e}function Ar(n){
+for(var t=n.name+"",r=Fu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function jr(n,t,e){var u=Nn.indexOf||Yr,u=u===Yr?r:u;return n?u(n,t,e):u}function kr(n){n=Ce(n);for(var t=n.length;t--;){var r,e=n[t];r=n[t][1],r=r===r&&!de(r),e[2]=r}return n}function Or(n,t){var r=null==n?w:n[t];return me(r)?r:w}function Ir(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&eu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Rr(n){return n=n.constructor,
+typeof n=="function"&&n instanceof n||(n=Ye),new n}function Er(n,t,r){var e=n.constructor;switch(t){case J:return Mt(n);case D:case M:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return e instanceof e&&(e=Lu[t]),t=n.buffer,new e(r?Mt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Y:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u}function Cr(n,t,r){return null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),t=Gr(t)),
+t=null==n?n:n[t],null==t?w:t.apply(n,r)}function Sr(n){return null!=n&&Lr(Vu(n))}function Ur(n,t){return n=typeof n=="number"||Rn.test(n)?+n:-1,t=null==t?$u:t,-1<n&&0==n%1&&n<t}function $r(n,t,r){if(!de(r))return false;var e=typeof t;return("number"==e?Sr(r)&&Ur(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Wr(n,t){var r=typeof n;return"string"==r&&dn.test(n)||"number"==r?true:Wo(n)?false:!yn.test(n)||null!=t&&n in Dr(t)}function Fr(n){var t=Ar(n),r=Nn[t];return typeof r=="function"&&t in zn.prototype?n===r?true:(t=Ku(r),
+!!t&&n===t[0]):false}function Lr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=$u}function Nr(n,t){return n===w?t:Fo(n,t,Nr)}function Tr(n,t){n=Dr(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Pr(n,t){var r={};return vt(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function zr(n){for(var t=Ee(n),r=t.length,e=r&&n.length,u=!!e&&Lr(e)&&(Wo(n)||_e(n)||Ae(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&Ur(f,e)||eu.call(n,f))&&i.push(f)}return i}function Br(n){return null==n?[]:Sr(n)?Nn.support.unindexedChars&&Ae(n)?n.split(""):de(n)?n:Ye(n):Se(n);
+}function Dr(n){if(Nn.support.unindexedChars&&Ae(n)){for(var t=-1,r=n.length,e=Ye(n);++t<r;)e[t]=n.charAt(t);return e}return de(n)?n:Ye(n)}function Mr(n){if(Wo(n))return n;var t=[];return u(n).replace(mn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function qr(n){return n instanceof zn?n.clone():new Pn(n.__wrapped__,n.__chain__,qn(n.__actions__))}function Kr(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0>t?0:t)):[]}function Vr(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),
+t=e-(+t||0),St(n,0,0>t?0:t)):[]}function Zr(n){return n?n[0]:w}function Yr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ju(u+e,0):e;else if(e)return e=zt(n,t),e<u&&(t===t?t===n[e]:n[e]!==n[e])?e:-1;return r(n,t,e||0)}function Gr(n){var t=n?n.length:0;return t?n[t-1]:w}function Jr(n){return Kr(n,1)}function Xr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=$r(n,t,u)?w:t,t=false);var o=br();if((null!=e||o!==it)&&(e=o(e,u,3)),t&&jr()===r){t=e;var i;e=-1,
+u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=Lt(n,e);return n}function Hr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Zn(n,function(n){return Sr(n)?(r=ju(n.length,r),true):void 0});for(var e=De(r);++t<r;)e[t]=Xn(n,Ot(t));return e}function Qr(n,t,r){return n&&n.length?(n=Hr(n),null==t?n:(t=Dt(t,r,4),Xn(n,function(n){return Qn(n,t,w,true)}))):[]}function ne(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Wo(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1]);
+}return u}function te(n){return n=Nn(n),n.__chain__=true,n}function re(n,t,r){return t.call(r,n)}function ee(n,t,r){var e=Wo(n)?Vn:lt;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ue(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,t)}function oe(n,t,r,e){var u=n?Vu(n):0;return Lr(u)||(n=Se(n),u=n.length),r=typeof r!="number"||e&&$r(t,r,e)?0:0>r?ju(u+r,0):r||0,typeof n=="string"||!Wo(n)&&Ae(n)?r<=u&&-1<n.indexOf(t,r):!!u&&-1<jr(n,t,r)}function ie(n,t,r){var e=Wo(n)?Xn:bt;
+return t=br(t,r,3),e(n,t)}function fe(n,t,r){if(r?$r(n,t,r):null==t){n=Br(n);var e=n.length;return 0<e?n[Et(0,e-1)]:w}r=-1,n=Oe(n);var e=n.length,u=e-1;for(t=ku(0>t?0:+t||0,e);++r<t;){var e=Et(r,u),o=n[e];n[e]=n[r],n[r]=o}return n.length=t,n}function ae(n,t,r){var e=Wo(n)?nt:Ut;return r&&$r(n,t,r)&&(t=w),(typeof t!="function"||r!==w)&&(t=br(t,r,3)),e(n,t)}function ce(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),
+1>=n&&(t=w),r}}function le(n,t,r){function e(t,r){r&&cu(r),a=p=h=w,t&&(_=wo(),c=n.apply(s,f),p||a||(f=s=w))}function u(){var n=t-(wo()-l);0>=n||n>t?e(h,a):p=_u(u,n)}function o(){e(g,p)}function i(){if(f=arguments,l=wo(),s=this,h=g&&(p||!y),false===v)var r=y&&!p;else{a||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(a&&(a=cu(a)),_=l,c=n.apply(s,f)):a||(a=_u(o,e))}return i&&p?p=cu(p):p||t===v||(p=_u(u,t)),r&&(i=true,c=n.apply(s,f)),!i||p||a||(f=s=w),c}var f,a,c,l,s,p,h,_=0,v=false,g=true;if(typeof n!="function")throw new Xe(T);
+if(t=0>t?0:+t||0,true===r)var y=true,g=false;else de(r)&&(y=!!r.leading,v="maxWait"in r&&ju(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&cu(p),a&&cu(a),_=0,a=p=h=w},i}function se(n,t){if(typeof n!="function"||t&&typeof t!="function")throw new Xe(T);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)};return r.cache=new se.Cache,r}function pe(n,t){if(typeof n!="function")throw new Xe(T);return t=ju(t===w?n.length-1:+t||0,0),
+function(){for(var r=arguments,e=-1,u=ju(r.length-t,0),o=De(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);case 2:return n.call(this,r[0],r[1],o)}for(u=De(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function he(n,t){return n>t}function _e(n){return h(n)&&Sr(n)&&eu.call(n,"callee")&&!pu.call(n,"callee")}function ve(n,t,r,e){return e=(r=typeof r=="function"?Dt(r,e,3):w)?r(n,t):w,e===w?wt(n,t,r):!!e}function ge(n){return h(n)&&typeof n.message=="string"&&ou.call(n)==q;
+}function ye(n){return de(n)&&ou.call(n)==K}function de(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function me(n){return null==n?false:ye(n)?fu.test(ru.call(n)):h(n)&&(Gn(n)?fu:In).test(n)}function we(n){return typeof n=="number"||h(n)&&ou.call(n)==V}function xe(n){var t;if(!h(n)||ou.call(n)!=Z||Gn(n)||_e(n)||!(eu.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return Nn.support.ownLast?(vt(n,function(n,t,e){return r=eu.call(e,t),false}),false!==r):(vt(n,function(n,t){
+r=t}),r===w||eu.call(n,r))}function be(n){return de(n)&&ou.call(n)==Y}function Ae(n){return typeof n=="string"||h(n)&&ou.call(n)==G}function je(n){return h(n)&&Lr(n.length)&&!!Fn[ou.call(n)]}function ke(n,t){return n<t}function Oe(n){var t=n?Vu(n):0;return Lr(t)?t?Nn.support.unindexedChars&&Ae(n)?n.split(""):qn(n):[]:Se(n)}function Ie(n){return ot(n,Ee(n))}function Re(n){return dt(n,Ee(n))}function Ee(n){if(null==n)return[];de(n)||(n=Ye(n));for(var t=n.length,r=Nn.support,t=t&&Lr(t)&&(Wo(n)||_e(n)||Ae(n))&&t||0,e=n.constructor,u=-1,e=ye(e)&&e.prototype||nu,o=e===n,i=De(t),f=0<t,a=r.enumErrorProps&&(n===Qe||n instanceof qe),c=r.enumPrototypes&&ye(n);++u<t;)i[u]=u+"";
+for(var l in n)c&&"prototype"==l||a&&("message"==l||"name"==l)||f&&Ur(l,t)||"constructor"==l&&(o||!eu.call(n,l))||i.push(l);if(r.nonEnumShadows&&n!==nu)for(t=n===tu?G:n===Qe?q:ou.call(n),r=Nu[t]||Nu[Z],t==Z&&(e=nu),t=Wn.length;t--;)l=Wn[t],u=r[l],o&&u||(u?!eu.call(n,l):n[l]===e[l])||i.push(l);return i}function Ce(n){n=Dr(n);for(var t=-1,r=Ko(n),e=r.length,u=De(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u}function Se(n){return Nt(n,Ko(n))}function Ue(n){return(n=u(n))&&n.replace(En,a).replace(bn,"");
+}function $e(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!bu(t))return r;do t%2&&(r+=n),t=wu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function Fe(n,t,r){return r&&$r(n,t,r)&&(t=w),n=u(n),n.match(t||Un)||[]}function Le(n,t,r){return r&&$r(n,t,r)&&(t=w),h(n)?Te(n):it(n,t)}function Ne(n){return n}function Te(n){return At(ft(n,true))}function Pe(n,t,r){if(null==r){var e=de(t),u=e?Ko(t):w;((u=u&&u.length?dt(t,u):w)?u.length:e)||(u=false,
+r=t,t=n,n=this)}u||(u=dt(t,Ko(t)));var o=true,e=-1,i=ye(n),f=u.length;false===r?o=false:de(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return t.apply(n,Hn([this.value()],arguments))}}(a))}return n}function ze(){}function Be(n){return Wr(n)?Ot(n):It(n)}_=_?Jn.defaults(Yn.Object(),_,Jn.pick(Yn,$n)):Yn;
+var De=_.Array,Me=_.Date,qe=_.Error,Ke=_.Function,Ve=_.Math,Ze=_.Number,Ye=_.Object,Ge=_.RegExp,Je=_.String,Xe=_.TypeError,He=De.prototype,Qe=qe.prototype,nu=Ye.prototype,tu=Je.prototype,ru=Ke.prototype.toString,eu=nu.hasOwnProperty,uu=0,ou=nu.toString,iu=Yn._,fu=Ge("^"+ru.call(eu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),au=_.ArrayBuffer,cu=_.clearTimeout,lu=_.parseFloat,su=Ve.pow,pu=nu.propertyIsEnumerable,hu=Or(_,"Set"),_u=_.setTimeout,vu=He.splice,gu=_.Uint8Array,yu=Or(_,"WeakMap"),du=Ve.ceil,mu=Or(Ye,"create"),wu=Ve.floor,xu=Or(De,"isArray"),bu=_.isFinite,Au=Or(Ye,"keys"),ju=Ve.max,ku=Ve.min,Ou=Or(Me,"now"),Iu=_.parseInt,Ru=Ve.random,Eu=Ze.NEGATIVE_INFINITY,Cu=Ze.POSITIVE_INFINITY,Su=4294967294,Uu=2147483647,$u=9007199254740991,Wu=yu&&new yu,Fu={},Lu={};
+Lu[X]=_.Float32Array,Lu[H]=_.Float64Array,Lu[Q]=_.Int8Array,Lu[nn]=_.Int16Array,Lu[tn]=_.Int32Array,Lu[rn]=gu,Lu[en]=_.Uint8ClampedArray,Lu[un]=_.Uint16Array,Lu[on]=_.Uint32Array;var Nu={};Nu[B]=Nu[M]=Nu[V]={constructor:true,toLocaleString:true,toString:true,valueOf:true},Nu[D]=Nu[G]={constructor:true,toString:true,valueOf:true},Nu[q]=Nu[K]=Nu[Y]={constructor:true,toString:true},Nu[Z]={constructor:true},Kn(Wn,function(n){for(var t in Nu)if(eu.call(Nu,t)){var r=Nu[t];r[n]=eu.call(r,n)}});var Tu=Nn.support={};!function(n){
+var t=function(){this.x=n},r={0:n,length:n},e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Tu.enumErrorProps=pu.call(Qe,"message")||pu.call(Qe,"name"),Tu.enumPrototypes=pu.call(t,"prototype"),Tu.nonEnumShadows=!/valueOf/.test(e),Tu.ownLast="x"!=e[0],Tu.spliceObjects=(vu.call(r,0,1),!r[0]),Tu.unindexedChars="xx"!="x"[0]+Ye("x")[0]}(1,0),Nn.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:Nn}};var Pu=function(){function n(){}return function(t){if(de(t)){n.prototype=t;
+var r=new n;n.prototype=w}return r||{}}}(),zu=Yt(gt),Bu=Yt(yt,true),Du=Gt(),Mu=Gt(true),qu=Wu?function(n,t){return Wu.set(n,t),n}:Ne,Ku=Wu?function(n){return Wu.get(n)}:ze,Vu=Ot("length"),Zu=function(){var n=0,t=0;return function(r,e){var u=wo(),o=W-(u-t);if(t=u,0<o){if(++n>=$)return r}else n=0;return qu(r,e)}}(),Yu=pe(function(n,t){return h(n)&&Sr(n)?ct(n,_t(t,false,true)):[]}),Gu=er(),Ju=er(true),Xu=pe(function(n){for(var t=n.length,e=t,u=De(l),o=jr(),i=o===r,f=[];e--;){var a=n[e]=Sr(a=n[e])?a:[];u[e]=i&&120<=a.length&&mu&&hu?new Dn(e&&a):null;
+}var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c<l;)if(a=i[c],0>(s?Mn(s,a):o(f,a,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,a):o(n[e],a,0)))continue n}s&&s.push(a),f.push(a)}return f}),Hu=pe(function(t,r){r=_t(r);var e=ut(t,r);return Rt(t,r.sort(n)),e}),Qu=yr(),no=yr(true),to=pe(function(n){return Lt(_t(n,false,true))}),ro=pe(function(n,t){return Sr(n)?ct(n,t):[]}),eo=pe(Hr),uo=pe(function(n){var t=n.length,r=2<t?n[t-2]:w,e=1<t?n[t-1]:w;return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,
+e):w,e=w),n.length=t,Qr(n,r,e)}),oo=pe(function(n){return n=_t(n),this.thru(function(t){t=Wo(t)?t:[Dr(t)];for(var r=n,e=-1,u=t.length,o=-1,i=r.length,f=De(u+i);++e<u;)f[e]=t[e];for(;++o<i;)f[e++]=r[o];return f})}),io=pe(function(n,t){return Sr(n)&&(n=Br(n)),ut(n,_t(t))}),fo=Vt(function(n,t,r){eu.call(n,r)?++n[r]:n[r]=1}),ao=rr(zu),co=rr(Bu,true),lo=ir(Kn,zu),so=ir(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Bu),po=Vt(function(n,t,r){eu.call(n,r)?n[r].push(t):n[r]=[t]}),ho=Vt(function(n,t,r){
+n[r]=t}),_o=pe(function(n,t,r){var e=-1,u=typeof t=="function",o=Wr(t),i=Sr(n)?De(n.length):[];return zu(n,function(n){var f=u?t:o&&null!=n?n[t]:w;i[++e]=f?f.apply(n,r):Cr(n,t,r)}),i}),vo=Vt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),go=pr(Qn,zu),yo=pr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Bu),mo=pe(function(n,t){if(null==n)return[];var r=t[2];return r&&$r(t[0],t[1],r)&&(t.length=1),Wt(n,_t(t),[])}),wo=Ou||function(){return(new Me).getTime();
+},xo=pe(function(n,t,r){var e=b;if(r.length)var u=v(r,xo.placeholder),e=e|I;return dr(n,e,t,r,u)}),bo=pe(function(n,t){t=t.length?_t(t):Re(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=dr(n[u],b,n)}return n}),Ao=pe(function(n,t,r){var e=b|A;if(r.length)var u=v(r,Ao.placeholder),e=e|I;return dr(t,e,n,r,u)}),jo=Qt(k),ko=Qt(O),Oo=pe(function(n,t){return at(n,1,t)}),Io=pe(function(n,t,r){return at(n,t,r)}),Ro=or(),Eo=or(true),Co=pe(function(n,t){if(t=_t(t),typeof n!="function"||!Vn(t,e))throw new Xe(T);
+var r=t.length;return pe(function(e){for(var u=ku(e.length,r);u--;)e[u]=t[u](e[u]);return n.apply(this,e)})}),So=sr(I),Uo=sr(R),$o=pe(function(n,t){return dr(n,C,w,w,w,_t(t))}),Wo=xu||function(n){return h(n)&&Lr(n.length)&&ou.call(n)==B},Fo=Zt(kt),Lo=Zt(function(n,t,r){return r?rt(n,t,r):et(n,t)}),No=nr(Lo,function(n,t){return n===w?t:n}),To=nr(Fo,Nr),Po=ur(gt),zo=ur(yt),Bo=fr(Du),Do=fr(Mu),Mo=ar(gt),qo=ar(yt),Ko=Au?function(n){var t=null==n?w:n.constructor;return typeof t=="function"&&t.prototype===n||(typeof n=="function"?Nn.support.enumPrototypes:Sr(n))?zr(n):de(n)?Au(n):[];
+}:zr,Vo=cr(true),Zo=cr(),Yo=pe(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Xn(_t(t),Je),Tr(n,ct(Ee(n),t));var r=Dt(t[0],t[1],3);return Pr(n,function(n,t,e){return!r(n,t,e)})}),Go=pe(function(n,t){return null==n?{}:"function"==typeof t[0]?Pr(n,Dt(t[0],t[1],3)):Tr(n,_t(t))}),Jo=Xt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Xo=Xt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Ho=lr(),Qo=lr(true),ni=Xt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase();
+}),ti=Xt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),ri=pe(function(n,t){try{return n.apply(w,t)}catch(r){return ge(r)?r:new qe(r)}}),ei=pe(function(n,t){return function(r){return Cr(r,n,t)}}),ui=pe(function(n,t){return function(r){return Cr(n,r,t)}}),oi=gr("ceil"),ii=gr("floor"),fi=tr(he,Eu),ai=tr(ke,Cu),ci=gr("round");return Nn.prototype=Tn.prototype,Pn.prototype=Pu(Tn.prototype),Pn.prototype.constructor=Pn,zn.prototype=Pu(Tn.prototype),zn.prototype.constructor=zn,
+Bn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Bn.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n]},Bn.prototype.has=function(n){return"__proto__"!=n&&eu.call(this.__data__,n)},Bn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;typeof n=="string"||de(n)?t.set.add(n):t.hash[n]=true},se.Cache=Bn,Nn.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Xe(T);
+var r=n;n=t,t=r}return n=bu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&$r(n,t,r)&&(t=w),t=n&&null==t?n.length:ju(+t||0,0),dr(n,E,w,w,w,w,t)},Nn.assign=Lo,Nn.at=io,Nn.before=ce,Nn.bind=xo,Nn.bindAll=bo,Nn.bindKey=Ao,Nn.callback=Le,Nn.chain=te,Nn.chunk=function(n,t,r){t=(r?$r(n,t,r):null==t)?1:ju(wu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=De(du(e/t));r<e;)o[++u]=St(n,r,r+=t);return o},Nn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){
+var o=n[t];o&&(u[++e]=o)}return u},Nn.constant=function(n){return function(){return n}},Nn.countBy=fo,Nn.create=function(n,t,r){var e=Pu(n);return r&&$r(n,t,r)&&(t=w),t?et(e,t):e},Nn.curry=jo,Nn.curryRight=ko,Nn.debounce=le,Nn.defaults=No,Nn.defaultsDeep=To,Nn.defer=Oo,Nn.delay=Io,Nn.difference=Yu,Nn.drop=Kr,Nn.dropRight=Vr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true,true):[]},Nn.dropWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),true):[]},Nn.fill=function(n,t,r,e){
+var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&$r(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=ue,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&$r(n,t,r)&&(t=false),e?_t(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?_t(n,true):[]},Nn.flow=Ro,Nn.flowRight=Eo,Nn.forEach=lo,Nn.forEachRight=so,Nn.forIn=Bo,Nn.forInRight=Do,Nn.forOwn=Mo,Nn.forOwnRight=qo,Nn.functions=Re,
+Nn.groupBy=po,Nn.indexBy=ho,Nn.initial=function(n){return Vr(n,1)},Nn.intersection=Xu,Nn.invert=function(n,t,r){r&&$r(n,t,r)&&(t=w),r=-1;for(var e=Ko(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?eu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Nn.invoke=_o,Nn.keys=Ko,Nn.keysIn=Ee,Nn.map=ie,Nn.mapKeys=Vo,Nn.mapValues=Zo,Nn.matches=Te,Nn.matchesProperty=function(n,t){return jt(n,ft(t,true))},Nn.memoize=se,Nn.merge=Fo,Nn.method=ei,Nn.methodOf=ui,Nn.mixin=Pe,Nn.modArgs=Co,Nn.negate=function(n){if(typeof n!="function")throw new Xe(T);
+return function(){return!n.apply(this,arguments)}},Nn.omit=Yo,Nn.once=function(n){return ce(2,n)},Nn.pairs=Ce,Nn.partial=So,Nn.partialRight=Uo,Nn.partition=vo,Nn.pick=Go,Nn.pluck=function(n,t){return ie(n,Be(t))},Nn.property=Be,Nn.propertyOf=function(n){return function(t){return mt(n,Mr(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=jr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)vu.call(t,o,1);return t},Nn.pullAt=Hu,Nn.range=function(n,t,r){
+r&&$r(n,t,r)&&(t=r=w),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ju(du((t-n)/(r||1)),0);for(var u=De(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=$o,Nn.reject=function(n,t,r){var e=Wo(n)?Zn:pt;return t=br(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=br(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return Rt(n,o),e},Nn.rest=Jr,Nn.restParam=pe,Nn.set=function(n,t,r){if(null==n)return n;
+var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Mr(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];de(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=Ur(t[e+1])?[]:{})),i=i[f]}return n},Nn.shuffle=function(n){return fe(n,Cu)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&$r(n,t,r)&&(t=0,r=e),St(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&$r(n,t,r)&&(t=w);var e=-1;return t=br(t,r,3),n=bt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),$t(n,f)},Nn.sortByAll=mo,
+Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&$r(t,r,e)&&(r=w),Wo(t)||(t=null==t?[]:[t]),Wo(r)||(r=null==r?[]:[r]),Wt(n,t,r))},Nn.spread=function(n){if(typeof n!="function")throw new Xe(T);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),t=e-(+t||0),St(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3),false,true):[];
+},Nn.takeWhile=function(n,t,r){return n&&n.length?Tt(n,br(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Xe(T);return false===r?e=false:de(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),le(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=re,Nn.times=function(n,t,r){if(n=wu(n),1>n||!bu(n))return[];var e=-1,u=De(ku(n,4294967295));for(t=Dt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);return u},Nn.toArray=Oe,
+Nn.toPlainObject=Ie,Nn.transform=function(n,t,r,e){var u=Wo(n)||je(n);return t=br(t,e,4),null==r&&(u||de(n)?(e=n.constructor,r=u?Wo(n)?new e:[]:Pu(ye(e)?e.prototype:w)):r={}),(u?Kn:gt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=to,Nn.uniq=Xr,Nn.unzip=Hr,Nn.unzipWith=Qr,Nn.values=Se,Nn.valuesIn=function(n){return Nt(n,Ee(n))},Nn.where=function(n,t){return ue(n,At(t))},Nn.without=ro,Nn.wrap=function(n,t){return t=null==t?Ne:t,dr(t,I,w,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){
+var r=arguments[n];if(Sr(r))var e=e?Hn(ct(e,r),ct(r,e)):r}return e?Lt(e):[]},Nn.zip=eo,Nn.zipObject=ne,Nn.zipWith=uo,Nn.backflow=Eo,Nn.collect=ie,Nn.compose=Eo,Nn.each=lo,Nn.eachRight=so,Nn.extend=Lo,Nn.iteratee=Le,Nn.methods=Re,Nn.object=ne,Nn.select=ue,Nn.tail=Jr,Nn.unique=Xr,Pe(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=ri,Nn.camelCase=Jo,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.ceil=oi,Nn.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&$r(n,t,r)?t=false:typeof t=="function"&&(e=r,
+r=t,t=false),typeof r=="function"?ft(n,t,Dt(r,e,3)):ft(n,t)},Nn.cloneDeep=function(n,t,r){return typeof t=="function"?ft(n,true,Dt(t,r,3)):ft(n,true)},Nn.deburr=Ue,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===w?e:ku(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,c):n},Nn.escapeRegExp=function(n){return(n=u(n))&&xn.test(n)?n.replace(wn,l):n||"(?:)"},Nn.every=ee,Nn.find=ao,Nn.findIndex=Gu,Nn.findKey=Po,Nn.findLast=co,
+Nn.findLastIndex=Ju,Nn.findLastKey=zo,Nn.findWhere=function(n,t){return ao(n,At(t))},Nn.first=Zr,Nn.floor=ii,Nn.get=function(n,t,r){return n=null==n?w:mt(n,Mr(t),t+""),n===w?r:n},Nn.gt=he,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=eu.call(n,t);if(!r&&!Wr(t)){if(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),null==n)return false;t=Gr(t),r=eu.call(n,t)}return r||Lr(n.length)&&Ur(t,n.length)&&(Wo(n)||_e(n)||Ae(n))},Nn.identity=Ne,Nn.includes=oe,Nn.indexOf=Yr,Nn.inRange=function(n,t,r){
+return t=+t||0,r===w?(r=t,t=0):r=+r||0,n>=ku(t,r)&&n<ju(t,r)},Nn.isArguments=_e,Nn.isArray=Wo,Nn.isBoolean=function(n){return true===n||false===n||h(n)&&ou.call(n)==D},Nn.isDate=function(n){return h(n)&&ou.call(n)==M},Nn.isElement=function(n){return!!n&&1===n.nodeType&&h(n)&&!xe(n)},Nn.isEmpty=function(n){return null==n?true:Sr(n)&&(Wo(n)||Ae(n)||_e(n)||h(n)&&ye(n.splice))?!n.length:!Ko(n).length},Nn.isEqual=ve,Nn.isError=ge,Nn.isFinite=function(n){return typeof n=="number"&&bu(n)},Nn.isFunction=ye,Nn.isMatch=function(n,t,r,e){
+return r=typeof r=="function"?Dt(r,e,3):w,xt(n,kr(t),r)},Nn.isNaN=function(n){return we(n)&&n!=+n},Nn.isNative=me,Nn.isNull=function(n){return null===n},Nn.isNumber=we,Nn.isObject=de,Nn.isPlainObject=xe,Nn.isRegExp=be,Nn.isString=Ae,Nn.isTypedArray=je,Nn.isUndefined=function(n){return n===w},Nn.kebabCase=Xo,Nn.last=Gr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?ju(e+r,0):ku(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;
+if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=ke,Nn.lte=function(n,t){return n<=t},Nn.max=fi,Nn.min=ai,Nn.noConflict=function(){return Yn._=iu,this},Nn.noop=ze,Nn.now=wo,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&bu(t)?(e=(t-e)/2,t=wu(e),e=du(e),r=_r("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Ho,Nn.padRight=Qo,Nn.parseInt=function(n,t,r){return(r?$r(n,t,r):null==t)?t=0:t&&(t=+t),n=We(n),Iu(n,t||(On.test(n)?16:10))},Nn.random=function(n,t,r){r&&$r(n,t,r)&&(t=r=w);
+var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Ru(),ku(n+r*(t-n+lu("1e-"+((r+"").length-1))),t)):Et(n,t)},Nn.reduce=go,Nn.reduceRight=yo,Nn.repeat=$e,Nn.result=function(n,t,r){var e=null==n?w:Dr(n)[t];return e===w&&(null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:mt(n,St(t,0,-1)),e=null==n?w:Dr(n)[Gr(t)]),e=e===w?r:e),ye(e)?e.call(n):e},Nn.round=ci,Nn.runInContext=m,Nn.size=function(n){
+var t=n?Vu(n):0;return Lr(t)?t:Ko(n).length},Nn.snakeCase=ni,Nn.some=ae,Nn.sortedIndex=Qu,Nn.sortedLastIndex=no,Nn.startCase=ti,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:ku(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&$r(n,t,r)&&(t=w),t=br(t,r,3),1==t.length){n=Wo(n)?n:Br(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=Ft(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&$r(n,t,r)&&(t=r=w),n=u(n),t=rt(et({},r||t),e,tt),r=rt(et({},t.imports),e.imports,tt);
+var o,i,f=Ko(r),a=Nt(r,f),c=0;r=t.interpolate||Cn;var l="__p+='";r=Ge((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Sn,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),
+l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=ri(function(){return Ke(f,p+"return "+l).apply(w,a)}),t.source=l,ge(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?$r(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n;
+},Nn.trunc=function(n,t,r){r&&$r(n,t,r)&&(t=w);var e=S;if(r=U,null!=t)if(de(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(be(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ge(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),
+-1<o&&(t=t.slice(0,o)));return t+r},Nn.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},Nn.uniqueId=function(n){var t=++uu;return u(n)+t},Nn.words=Fe,Nn.all=ee,Nn.any=ae,Nn.contains=oe,Nn.eq=ve,Nn.detect=ao,Nn.foldl=go,Nn.foldr=yo,Nn.head=Zr,Nn.include=oe,Nn.inject=go,Pe(Nn,function(){var n={};return gt(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),false),Nn.sample=fe,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return fe(t,n)}):fe(this.value());
+},Nn.VERSION=x,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Kn(["drop","take"],function(n,t){zn.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new zn(this);r=null==r?1:ju(wu(r)||0,0);var u=this.clone();return e?u.__takeCount__=ku(u.__takeCount__,r):u.__views__.push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Kn(["filter","map","takeWhile"],function(n,t){
+var r=t+1,e=r!=N;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:br(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?At:Be;zn.prototype[n]=function(n){
+return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Ne)},zn.prototype.reject=function(n,t){return n=br(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0<n||0>t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Cu);
+},gt(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){var t=e?[1]:arguments,o=this.__chain__,i=this.__wrapped__,f=!!this.__actions__.length,a=i instanceof zn,c=t[0],l=a||Wo(i);l&&r&&typeof c=="function"&&1!=c.length&&(a=l=false);var s=function(n){return e&&o?u(n,1)[0]:u.apply(w,Hn([n],t))},c={func:re,args:[s],thisArg:w},f=a&&!f;return e&&!o?f?(i=i.clone(),i.__actions__.push(c),
+n.call(i)):u.call(w,this.value())[0]:!e&&l?(i=f?i:new zn(this),i=n.apply(i,t),i.__actions__.push(c),new Pn(i,o)):this.thru(s)})}),Kn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?tu:He)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=!Tu.spliceObjects&&/^(?:pop|shift|splice)$/.test(n),u=/^(?:join|pop|replace|shift)$/.test(n),o=e?function(){var n=t.apply(this,arguments);return 0===this.length&&delete this[0],n}:t;Nn.prototype[n]=function(){
+var n=arguments;return u&&!this.__chain__?o.apply(this.value(),n):this[r](function(t){return o.apply(t,n)})}}),gt(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name+"";(Fu[e]||(Fu[e]=[])).push({name:t,func:r})}}),Fu[hr(w,A).name]=[{name:"wrapper",func:w}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),
+n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Wo(t),u=0>r,o=e?t.length:0;n=0;for(var i=o,f=this.__views__,a=-1,c=f.length;++a<c;){var l=f[a],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":i-=s;break;case"take":i=ku(i,n+s);break;case"takeRight":n=ju(n,i-s)}}if(n={start:n,end:i},i=n.start,f=n.end,n=f-i,
+u=u?f:i-1,i=this.__iteratees__,f=i.length,a=0,c=ku(n,this.__takeCount__),!e||o<F||o==n&&c==n)return Pt(t,this.__actions__);e=[];n:for(;n--&&a<c;){for(u+=r,o=-1,l=t[u];++o<f;){var p=i[o],s=p.type,p=p.iteratee(l);if(s==N)l=p;else if(!p){if(s==L)continue n;break n}}e[a++]=l}return e},Nn.prototype.chain=function(){return te(this)},Nn.prototype.commit=function(){return new Pn(this.value(),this.__chain__)},Nn.prototype.concat=oo,Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Tn;){var e=qr(r);
+t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__,t=function(n){return n.reverse()};return n instanceof zn?(this.__actions__.length&&(n=new zn(this)),n=n.reverse(),n.__actions__.push({func:re,args:[t],thisArg:w}),new Pn(n,this.__chain__)):this.thru(t)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Pt(this.__wrapped__,this.__actions__);
+},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var w,x="3.10.1",b=1,A=2,j=4,k=8,O=16,I=32,R=64,E=128,C=256,S=30,U="...",$=150,W=16,F=200,L=1,N=2,T="Expected a function",P="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",D="[object Boolean]",M="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,xn=RegExp(wn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,In=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Sn=/['\n\r\u2028\u2029\\]/g,Un=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Wn="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Fn={};
+Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=true,Fn[z]=Fn[B]=Fn[J]=Fn[D]=Fn[M]=Fn[q]=Fn[K]=Fn["[object Map]"]=Fn[V]=Fn[Z]=Fn[Y]=Fn["[object Set]"]=Fn[G]=Fn["[object WeakMap]"]=false;var Ln={};Ln[z]=Ln[B]=Ln[J]=Ln[D]=Ln[M]=Ln[X]=Ln[H]=Ln[Q]=Ln[nn]=Ln[tn]=Ln[V]=Ln[Z]=Ln[Y]=Ln[G]=Ln[rn]=Ln[en]=Ln[un]=Ln[on]=true,Ln[q]=Ln[K]=Ln["[object Map]"]=Ln["[object Set]"]=Ln["[object WeakMap]"]=false;var Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a",
+"\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y",
+"\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Tn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Pn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},zn={"function":true,object:true},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\",
+"'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Kn=zn[typeof self]&&self&&self.Object&&self,Vn=zn[typeof window]&&window&&window.Object&&window,Zn=qn&&qn.exports===Mn&&Mn,Yn=Mn&&qn&&typeof global=="object"&&global&&global.Object&&global||Vn!==(this&&this.window)&&Vn||Kn||this,Gn=function(){try{Object({toString:0}+"")}catch(n){return function(){return false}}return function(n){
+return typeof n.toString!="function"&&typeof(n+"")=="string"}}(),Jn=m();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Jn, define(function(){return Jn})):Mn&&qn?Zn?(qn.exports=Jn)._=Jn:Mn._=Jn:Yn._=Jn}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/marked.js b/src/main/resources/META-INF/resources/icd/lib/marked.js
new file mode 100644 (file)
index 0000000..c2a678d
--- /dev/null
@@ -0,0 +1,1272 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+;(function() {
+
+/**
+ * Block-Level Grammar
+ */
+
+var block = {
+  newline: /^\n+/,
+  code: /^( {4}[^\n]+\n*)+/,
+  fences: noop,
+  hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+  heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+  nptable: noop,
+  lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
+  blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
+  list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+  html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
+  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+  table: noop,
+  paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+  text: /^[^\n]+/
+};
+
+block.bullet = /(?:[*+-]|\d+\.)/;
+block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+block.item = replace(block.item, 'gm')
+  (/bull/g, block.bullet)
+  ();
+
+block.list = replace(block.list)
+  (/bull/g, block.bullet)
+  ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
+  ('def', '\\n+(?=' + block.def.source + ')')
+  ();
+
+block.blockquote = replace(block.blockquote)
+  ('def', block.def)
+  ();
+
+block._tag = '(?!(?:'
+  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+  + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
+  + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
+
+block.html = replace(block.html)
+  ('comment', /<!--[\s\S]*?-->/)
+  ('closed', /<(tag)[\s\S]+?<\/\1>/)
+  ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
+  (/tag/g, block._tag)
+  ();
+
+block.paragraph = replace(block.paragraph)
+  ('hr', block.hr)
+  ('heading', block.heading)
+  ('lheading', block.lheading)
+  ('blockquote', block.blockquote)
+  ('tag', '<' + block._tag)
+  ('def', block.def)
+  ();
+
+/**
+ * Normal Block Grammar
+ */
+
+block.normal = merge({}, block);
+
+/**
+ * GFM Block Grammar
+ */
+
+block.gfm = merge({}, block.normal, {
+  fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+  paragraph: /^/
+});
+
+block.gfm.paragraph = replace(block.paragraph)
+  ('(?!', '(?!'
+    + block.gfm.fences.source.replace('\\1', '\\2') + '|'
+    + block.list.source.replace('\\1', '\\3') + '|')
+  ();
+
+/**
+ * GFM + Tables Block Grammar
+ */
+
+block.tables = merge({}, block.gfm, {
+  nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+  table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
+});
+
+/**
+ * Block Lexer
+ */
+
+function Lexer(options) {
+  this.tokens = [];
+  this.tokens.links = {};
+  this.options = options || marked.defaults;
+  this.rules = block.normal;
+
+  if (this.options.gfm) {
+    if (this.options.tables) {
+      this.rules = block.tables;
+    } else {
+      this.rules = block.gfm;
+    }
+  }
+}
+
+/**
+ * Expose Block Rules
+ */
+
+Lexer.rules = block;
+
+/**
+ * Static Lex Method
+ */
+
+Lexer.lex = function(src, options) {
+  var lexer = new Lexer(options);
+  return lexer.lex(src);
+};
+
+/**
+ * Preprocessing
+ */
+
+Lexer.prototype.lex = function(src) {
+  src = src
+    .replace(/\r\n|\r/g, '\n')
+    .replace(/\t/g, '    ')
+    .replace(/\u00a0/g, ' ')
+    .replace(/\u2424/g, '\n');
+
+  return this.token(src, true);
+};
+
+/**
+ * Lexing
+ */
+
+Lexer.prototype.token = function(src, top, bq) {
+  var src = src.replace(/^ +$/gm, '')
+    , next
+    , loose
+    , cap
+    , bull
+    , b
+    , item
+    , space
+    , i
+    , l;
+
+  while (src) {
+    // newline
+    if (cap = this.rules.newline.exec(src)) {
+      src = src.substring(cap[0].length);
+      if (cap[0].length > 1) {
+        this.tokens.push({
+          type: 'space'
+        });
+      }
+    }
+
+    // code
+    if (cap = this.rules.code.exec(src)) {
+      src = src.substring(cap[0].length);
+      cap = cap[0].replace(/^ {4}/gm, '');
+      this.tokens.push({
+        type: 'code',
+        text: !this.options.pedantic
+          ? cap.replace(/\n+$/, '')
+          : cap
+      });
+      continue;
+    }
+
+    // fences (gfm)
+    if (cap = this.rules.fences.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'code',
+        lang: cap[2],
+        text: cap[3]
+      });
+      continue;
+    }
+
+    // heading
+    if (cap = this.rules.heading.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'heading',
+        depth: cap[1].length,
+        text: cap[2]
+      });
+      continue;
+    }
+
+    // table no leading pipe (gfm)
+    if (top && (cap = this.rules.nptable.exec(src))) {
+      src = src.substring(cap[0].length);
+
+      item = {
+        type: 'table',
+        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+        cells: cap[3].replace(/\n$/, '').split('\n')
+      };
+
+      for (i = 0; i < item.align.length; i++) {
+        if (/^ *-+: *$/.test(item.align[i])) {
+          item.align[i] = 'right';
+        } else if (/^ *:-+: *$/.test(item.align[i])) {
+          item.align[i] = 'center';
+        } else if (/^ *:-+ *$/.test(item.align[i])) {
+          item.align[i] = 'left';
+        } else {
+          item.align[i] = null;
+        }
+      }
+
+      for (i = 0; i < item.cells.length; i++) {
+        item.cells[i] = item.cells[i].split(/ *\| */);
+      }
+
+      this.tokens.push(item);
+
+      continue;
+    }
+
+    // lheading
+    if (cap = this.rules.lheading.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'heading',
+        depth: cap[2] === '=' ? 1 : 2,
+        text: cap[1]
+      });
+      continue;
+    }
+
+    // hr
+    if (cap = this.rules.hr.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'hr'
+      });
+      continue;
+    }
+
+    // blockquote
+    if (cap = this.rules.blockquote.exec(src)) {
+      src = src.substring(cap[0].length);
+
+      this.tokens.push({
+        type: 'blockquote_start'
+      });
+
+      cap = cap[0].replace(/^ *> ?/gm, '');
+
+      // Pass `top` to keep the current
+      // "toplevel" state. This is exactly
+      // how markdown.pl works.
+      this.token(cap, top, true);
+
+      this.tokens.push({
+        type: 'blockquote_end'
+      });
+
+      continue;
+    }
+
+    // list
+    if (cap = this.rules.list.exec(src)) {
+      src = src.substring(cap[0].length);
+      bull = cap[2];
+
+      this.tokens.push({
+        type: 'list_start',
+        ordered: bull.length > 1
+      });
+
+      // Get each top-level item.
+      cap = cap[0].match(this.rules.item);
+
+      next = false;
+      l = cap.length;
+      i = 0;
+
+      for (; i < l; i++) {
+        item = cap[i];
+
+        // Remove the list item's bullet
+        // so it is seen as the next token.
+        space = item.length;
+        item = item.replace(/^ *([*+-]|\d+\.) +/, '');
+
+        // Outdent whatever the
+        // list item contains. Hacky.
+        if (~item.indexOf('\n ')) {
+          space -= item.length;
+          item = !this.options.pedantic
+            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
+            : item.replace(/^ {1,4}/gm, '');
+        }
+
+        // Determine whether the next list item belongs here.
+        // Backpedal if it does not belong in this list.
+        if (this.options.smartLists && i !== l - 1) {
+          b = block.bullet.exec(cap[i + 1])[0];
+          if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+            src = cap.slice(i + 1).join('\n') + src;
+            i = l - 1;
+          }
+        }
+
+        // Determine whether item is loose or not.
+        // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+        // for discount behavior.
+        loose = next || /\n\n(?!\s*$)/.test(item);
+        if (i !== l - 1) {
+          next = item.charAt(item.length - 1) === '\n';
+          if (!loose) loose = next;
+        }
+
+        this.tokens.push({
+          type: loose
+            ? 'loose_item_start'
+            : 'list_item_start'
+        });
+
+        // Recurse.
+        this.token(item, false, bq);
+
+        this.tokens.push({
+          type: 'list_item_end'
+        });
+      }
+
+      this.tokens.push({
+        type: 'list_end'
+      });
+
+      continue;
+    }
+
+    // html
+    if (cap = this.rules.html.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: this.options.sanitize
+          ? 'paragraph'
+          : 'html',
+        pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+        text: cap[0]
+      });
+      continue;
+    }
+
+    // def
+    if ((!bq && top) && (cap = this.rules.def.exec(src))) {
+      src = src.substring(cap[0].length);
+      this.tokens.links[cap[1].toLowerCase()] = {
+        href: cap[2],
+        title: cap[3]
+      };
+      continue;
+    }
+
+    // table (gfm)
+    if (top && (cap = this.rules.table.exec(src))) {
+      src = src.substring(cap[0].length);
+
+      item = {
+        type: 'table',
+        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+        cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
+      };
+
+      for (i = 0; i < item.align.length; i++) {
+        if (/^ *-+: *$/.test(item.align[i])) {
+          item.align[i] = 'right';
+        } else if (/^ *:-+: *$/.test(item.align[i])) {
+          item.align[i] = 'center';
+        } else if (/^ *:-+ *$/.test(item.align[i])) {
+          item.align[i] = 'left';
+        } else {
+          item.align[i] = null;
+        }
+      }
+
+      for (i = 0; i < item.cells.length; i++) {
+        item.cells[i] = item.cells[i]
+          .replace(/^ *\| *| *\| *$/g, '')
+          .split(/ *\| */);
+      }
+
+      this.tokens.push(item);
+
+      continue;
+    }
+
+    // top-level paragraph
+    if (top && (cap = this.rules.paragraph.exec(src))) {
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'paragraph',
+        text: cap[1].charAt(cap[1].length - 1) === '\n'
+          ? cap[1].slice(0, -1)
+          : cap[1]
+      });
+      continue;
+    }
+
+    // text
+    if (cap = this.rules.text.exec(src)) {
+      // Top-level should never reach here.
+      src = src.substring(cap[0].length);
+      this.tokens.push({
+        type: 'text',
+        text: cap[0]
+      });
+      continue;
+    }
+
+    if (src) {
+      throw new
+        Error('Infinite loop on byte: ' + src.charCodeAt(0));
+    }
+  }
+
+  return this.tokens;
+};
+
+/**
+ * Inline-Level Grammar
+ */
+
+var inline = {
+  escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+  autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+  url: noop,
+  tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
+  link: /^!?\[(inside)\]\(href\)/,
+  reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+  nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+  strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+  em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+  code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
+  br: /^ {2,}\n(?!\s*$)/,
+  del: noop,
+  text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
+};
+
+inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
+inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+inline.link = replace(inline.link)
+  ('inside', inline._inside)
+  ('href', inline._href)
+  ();
+
+inline.reflink = replace(inline.reflink)
+  ('inside', inline._inside)
+  ();
+
+/**
+ * Normal Inline Grammar
+ */
+
+inline.normal = merge({}, inline);
+
+/**
+ * Pedantic Inline Grammar
+ */
+
+inline.pedantic = merge({}, inline.normal, {
+  strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+  em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
+});
+
+/**
+ * GFM Inline Grammar
+ */
+
+inline.gfm = merge({}, inline.normal, {
+  escape: replace(inline.escape)('])', '~|])')(),
+  url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+  del: /^~~(?=\S)([\s\S]*?\S)~~/,
+  text: replace(inline.text)
+    (']|', '~]|')
+    ('|', '|https?://|')
+    ()
+});
+
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
+
+inline.breaks = merge({}, inline.gfm, {
+  br: replace(inline.br)('{2,}', '*')(),
+  text: replace(inline.gfm.text)('{2,}', '*')()
+});
+
+/**
+ * Inline Lexer & Compiler
+ */
+
+function InlineLexer(links, options) {
+  this.options = options || marked.defaults;
+  this.links = links;
+  this.rules = inline.normal;
+  this.renderer = this.options.renderer || new Renderer;
+  this.renderer.options = this.options;
+
+  if (!this.links) {
+    throw new
+      Error('Tokens array requires a `links` property.');
+  }
+
+  if (this.options.gfm) {
+    if (this.options.breaks) {
+      this.rules = inline.breaks;
+    } else {
+      this.rules = inline.gfm;
+    }
+  } else if (this.options.pedantic) {
+    this.rules = inline.pedantic;
+  }
+}
+
+/**
+ * Expose Inline Rules
+ */
+
+InlineLexer.rules = inline;
+
+/**
+ * Static Lexing/Compiling Method
+ */
+
+InlineLexer.output = function(src, links, options) {
+  var inline = new InlineLexer(links, options);
+  return inline.output(src);
+};
+
+/**
+ * Lexing/Compiling
+ */
+
+InlineLexer.prototype.output = function(src) {
+  var out = ''
+    , link
+    , text
+    , href
+    , cap;
+
+  while (src) {
+    // escape
+    if (cap = this.rules.escape.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += cap[1];
+      continue;
+    }
+
+    // autolink
+    if (cap = this.rules.autolink.exec(src)) {
+      src = src.substring(cap[0].length);
+      if (cap[2] === '@') {
+        text = cap[1].charAt(6) === ':'
+          ? this.mangle(cap[1].substring(7))
+          : this.mangle(cap[1]);
+        href = this.mangle('mailto:') + text;
+      } else {
+        text = escape(cap[1]);
+        href = text;
+      }
+      out += this.renderer.link(href, null, text);
+      continue;
+    }
+
+    // url (gfm)
+    if (!this.inLink && (cap = this.rules.url.exec(src))) {
+      src = src.substring(cap[0].length);
+      text = escape(cap[1]);
+      href = text;
+      out += this.renderer.link(href, null, text);
+      continue;
+    }
+
+    // tag
+    if (cap = this.rules.tag.exec(src)) {
+      if (!this.inLink && /^<a /i.test(cap[0])) {
+        this.inLink = true;
+      } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
+        this.inLink = false;
+      }
+      src = src.substring(cap[0].length);
+      out += this.options.sanitize
+        ? escape(cap[0])
+        : cap[0];
+      continue;
+    }
+
+    // link
+    if (cap = this.rules.link.exec(src)) {
+      src = src.substring(cap[0].length);
+      this.inLink = true;
+      out += this.outputLink(cap, {
+        href: cap[2],
+        title: cap[3]
+      });
+      this.inLink = false;
+      continue;
+    }
+
+    // reflink, nolink
+    if ((cap = this.rules.reflink.exec(src))
+        || (cap = this.rules.nolink.exec(src))) {
+      src = src.substring(cap[0].length);
+      link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+      link = this.links[link.toLowerCase()];
+      if (!link || !link.href) {
+        out += cap[0].charAt(0);
+        src = cap[0].substring(1) + src;
+        continue;
+      }
+      this.inLink = true;
+      out += this.outputLink(cap, link);
+      this.inLink = false;
+      continue;
+    }
+
+    // strong
+    if (cap = this.rules.strong.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += this.renderer.strong(this.output(cap[2] || cap[1]));
+      continue;
+    }
+
+    // em
+    if (cap = this.rules.em.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += this.renderer.em(this.output(cap[2] || cap[1]));
+      continue;
+    }
+
+    // code
+    if (cap = this.rules.code.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += this.renderer.codespan(escape(cap[2], true));
+      continue;
+    }
+
+    // br
+    if (cap = this.rules.br.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += this.renderer.br();
+      continue;
+    }
+
+    // del (gfm)
+    if (cap = this.rules.del.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += this.renderer.del(this.output(cap[1]));
+      continue;
+    }
+
+    // text
+    if (cap = this.rules.text.exec(src)) {
+      src = src.substring(cap[0].length);
+      out += escape(this.smartypants(cap[0]));
+      continue;
+    }
+
+    if (src) {
+      throw new
+        Error('Infinite loop on byte: ' + src.charCodeAt(0));
+    }
+  }
+
+  return out;
+};
+
+/**
+ * Compile Link
+ */
+
+InlineLexer.prototype.outputLink = function(cap, link) {
+  var href = escape(link.href)
+    , title = link.title ? escape(link.title) : null;
+
+  return cap[0].charAt(0) !== '!'
+    ? this.renderer.link(href, title, this.output(cap[1]))
+    : this.renderer.image(href, title, escape(cap[1]));
+};
+
+/**
+ * Smartypants Transformations
+ */
+
+InlineLexer.prototype.smartypants = function(text) {
+  if (!this.options.smartypants) return text;
+  return text
+    // em-dashes
+    .replace(/--/g, '\u2014')
+    // opening singles
+    .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+    // closing singles & apostrophes
+    .replace(/'/g, '\u2019')
+    // opening doubles
+    .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+    // closing doubles
+    .replace(/"/g, '\u201d')
+    // ellipses
+    .replace(/\.{3}/g, '\u2026');
+};
+
+/**
+ * Mangle Links
+ */
+
+InlineLexer.prototype.mangle = function(text) {
+  var out = ''
+    , l = text.length
+    , i = 0
+    , ch;
+
+  for (; i < l; i++) {
+    ch = text.charCodeAt(i);
+    if (Math.random() > 0.5) {
+      ch = 'x' + ch.toString(16);
+    }
+    out += '&#' + ch + ';';
+  }
+
+  return out;
+};
+
+/**
+ * Renderer
+ */
+
+function Renderer(options) {
+  this.options = options || {};
+}
+
+Renderer.prototype.code = function(code, lang, escaped) {
+  if (this.options.highlight) {
+    var out = this.options.highlight(code, lang);
+    if (out != null && out !== code) {
+      escaped = true;
+      code = out;
+    }
+  }
+
+  if (!lang) {
+    return '<pre><code>'
+      + (escaped ? code : escape(code, true))
+      + '\n</code></pre>';
+  }
+
+  return '<pre><code class="'
+    + this.options.langPrefix
+    + escape(lang, true)
+    + '">'
+    + (escaped ? code : escape(code, true))
+    + '\n</code></pre>\n';
+};
+
+Renderer.prototype.blockquote = function(quote) {
+  return '<blockquote>\n' + quote + '</blockquote>\n';
+};
+
+Renderer.prototype.html = function(html) {
+  return html;
+};
+
+Renderer.prototype.heading = function(text, level, raw) {
+  return '<h'
+    + level
+    + ' id="'
+    + this.options.headerPrefix
+    + raw.toLowerCase().replace(/[^\w]+/g, '-')
+    + '">'
+    + text
+    + '</h'
+    + level
+    + '>\n';
+};
+
+Renderer.prototype.hr = function() {
+  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+};
+
+Renderer.prototype.list = function(body, ordered) {
+  var type = ordered ? 'ol' : 'ul';
+  return '<' + type + '>\n' + body + '</' + type + '>\n';
+};
+
+Renderer.prototype.listitem = function(text) {
+  return '<li>' + text + '</li>\n';
+};
+
+Renderer.prototype.paragraph = function(text) {
+  return '<p>' + text + '</p>\n';
+};
+
+Renderer.prototype.table = function(header, body) {
+  return '<table>\n'
+    + '<thead>\n'
+    + header
+    + '</thead>\n'
+    + '<tbody>\n'
+    + body
+    + '</tbody>\n'
+    + '</table>\n';
+};
+
+Renderer.prototype.tablerow = function(content) {
+  return '<tr>\n' + content + '</tr>\n';
+};
+
+Renderer.prototype.tablecell = function(content, flags) {
+  var type = flags.header ? 'th' : 'td';
+  var tag = flags.align
+    ? '<' + type + ' style="text-align:' + flags.align + '">'
+    : '<' + type + '>';
+  return tag + content + '</' + type + '>\n';
+};
+
+// span level renderer
+Renderer.prototype.strong = function(text) {
+  return '<strong>' + text + '</strong>';
+};
+
+Renderer.prototype.em = function(text) {
+  return '<em>' + text + '</em>';
+};
+
+Renderer.prototype.codespan = function(text) {
+  return '<code>' + text + '</code>';
+};
+
+Renderer.prototype.br = function() {
+  return this.options.xhtml ? '<br/>' : '<br>';
+};
+
+Renderer.prototype.del = function(text) {
+  return '<del>' + text + '</del>';
+};
+
+Renderer.prototype.link = function(href, title, text) {
+  if (this.options.sanitize) {
+    try {
+      var prot = decodeURIComponent(unescape(href))
+        .replace(/[^\w:]/g, '')
+        .toLowerCase();
+    } catch (e) {
+      return '';
+    }
+    if (prot.indexOf('javascript:') === 0) {
+      return '';
+    }
+  }
+  var out = '<a href="' + href + '"';
+  if (title) {
+    out += ' title="' + title + '"';
+  }
+  out += '>' + text + '</a>';
+  return out;
+};
+
+Renderer.prototype.image = function(href, title, text) {
+  var out = '<img src="' + href + '" alt="' + text + '"';
+  if (title) {
+    out += ' title="' + title + '"';
+  }
+  out += this.options.xhtml ? '/>' : '>';
+  return out;
+};
+
+/**
+ * Parsing & Compiling
+ */
+
+function Parser(options) {
+  this.tokens = [];
+  this.token = null;
+  this.options = options || marked.defaults;
+  this.options.renderer = this.options.renderer || new Renderer;
+  this.renderer = this.options.renderer;
+  this.renderer.options = this.options;
+}
+
+/**
+ * Static Parse Method
+ */
+
+Parser.parse = function(src, options, renderer) {
+  var parser = new Parser(options, renderer);
+  return parser.parse(src);
+};
+
+/**
+ * Parse Loop
+ */
+
+Parser.prototype.parse = function(src) {
+  this.inline = new InlineLexer(src.links, this.options, this.renderer);
+  this.tokens = src.reverse();
+
+  var out = '';
+  while (this.next()) {
+    out += this.tok();
+  }
+
+  return out;
+};
+
+/**
+ * Next Token
+ */
+
+Parser.prototype.next = function() {
+  return this.token = this.tokens.pop();
+};
+
+/**
+ * Preview Next Token
+ */
+
+Parser.prototype.peek = function() {
+  return this.tokens[this.tokens.length - 1] || 0;
+};
+
+/**
+ * Parse Text Tokens
+ */
+
+Parser.prototype.parseText = function() {
+  var body = this.token.text;
+
+  while (this.peek().type === 'text') {
+    body += '\n' + this.next().text;
+  }
+
+  return this.inline.output(body);
+};
+
+/**
+ * Parse Current Token
+ */
+
+Parser.prototype.tok = function() {
+  switch (this.token.type) {
+    case 'space': {
+      return '';
+    }
+    case 'hr': {
+      return this.renderer.hr();
+    }
+    case 'heading': {
+      return this.renderer.heading(
+        this.inline.output(this.token.text),
+        this.token.depth,
+        this.token.text);
+    }
+    case 'code': {
+      return this.renderer.code(this.token.text,
+        this.token.lang,
+        this.token.escaped);
+    }
+    case 'table': {
+      var header = ''
+        , body = ''
+        , i
+        , row
+        , cell
+        , flags
+        , j;
+
+      // header
+      cell = '';
+      for (i = 0; i < this.token.header.length; i++) {
+        flags = { header: true, align: this.token.align[i] };
+        cell += this.renderer.tablecell(
+          this.inline.output(this.token.header[i]),
+          { header: true, align: this.token.align[i] }
+        );
+      }
+      header += this.renderer.tablerow(cell);
+
+      for (i = 0; i < this.token.cells.length; i++) {
+        row = this.token.cells[i];
+
+        cell = '';
+        for (j = 0; j < row.length; j++) {
+          cell += this.renderer.tablecell(
+            this.inline.output(row[j]),
+            { header: false, align: this.token.align[j] }
+          );
+        }
+
+        body += this.renderer.tablerow(cell);
+      }
+      return this.renderer.table(header, body);
+    }
+    case 'blockquote_start': {
+      var body = '';
+
+      while (this.next().type !== 'blockquote_end') {
+        body += this.tok();
+      }
+
+      return this.renderer.blockquote(body);
+    }
+    case 'list_start': {
+      var body = ''
+        , ordered = this.token.ordered;
+
+      while (this.next().type !== 'list_end') {
+        body += this.tok();
+      }
+
+      return this.renderer.list(body, ordered);
+    }
+    case 'list_item_start': {
+      var body = '';
+
+      while (this.next().type !== 'list_item_end') {
+        body += this.token.type === 'text'
+          ? this.parseText()
+          : this.tok();
+      }
+
+      return this.renderer.listitem(body);
+    }
+    case 'loose_item_start': {
+      var body = '';
+
+      while (this.next().type !== 'list_item_end') {
+        body += this.tok();
+      }
+
+      return this.renderer.listitem(body);
+    }
+    case 'html': {
+      var html = !this.token.pre && !this.options.pedantic
+        ? this.inline.output(this.token.text)
+        : this.token.text;
+      return this.renderer.html(html);
+    }
+    case 'paragraph': {
+      return this.renderer.paragraph(this.inline.output(this.token.text));
+    }
+    case 'text': {
+      return this.renderer.paragraph(this.parseText());
+    }
+  }
+};
+
+/**
+ * Helpers
+ */
+
+function escape(html, encode) {
+  return html
+    .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;')
+    .replace(/"/g, '&quot;')
+    .replace(/'/g, '&#39;');
+}
+
+function unescape(html) {
+  return html.replace(/&([#\w]+);/g, function(_, n) {
+    n = n.toLowerCase();
+    if (n === 'colon') return ':';
+    if (n.charAt(0) === '#') {
+      return n.charAt(1) === 'x'
+        ? String.fromCharCode(parseInt(n.substring(2), 16))
+        : String.fromCharCode(+n.substring(1));
+    }
+    return '';
+  });
+}
+
+function replace(regex, opt) {
+  regex = regex.source;
+  opt = opt || '';
+  return function self(name, val) {
+    if (!name) return new RegExp(regex, opt);
+    val = val.source || val;
+    val = val.replace(/(^|[^\[])\^/g, '$1');
+    regex = regex.replace(name, val);
+    return self;
+  };
+}
+
+function noop() {}
+noop.exec = noop;
+
+function merge(obj) {
+  var i = 1
+    , target
+    , key;
+
+  for (; i < arguments.length; i++) {
+    target = arguments[i];
+    for (key in target) {
+      if (Object.prototype.hasOwnProperty.call(target, key)) {
+        obj[key] = target[key];
+      }
+    }
+  }
+
+  return obj;
+}
+
+
+/**
+ * Marked
+ */
+
+function marked(src, opt, callback) {
+  if (callback || typeof opt === 'function') {
+    if (!callback) {
+      callback = opt;
+      opt = null;
+    }
+
+    opt = merge({}, marked.defaults, opt || {});
+
+    var highlight = opt.highlight
+      , tokens
+      , pending
+      , i = 0;
+
+    try {
+      tokens = Lexer.lex(src, opt)
+    } catch (e) {
+      return callback(e);
+    }
+
+    pending = tokens.length;
+
+    var done = function(err) {
+      if (err) {
+        opt.highlight = highlight;
+        return callback(err);
+      }
+
+      var out;
+
+      try {
+        out = Parser.parse(tokens, opt);
+      } catch (e) {
+        err = e;
+      }
+
+      opt.highlight = highlight;
+
+      return err
+        ? callback(err)
+        : callback(null, out);
+    };
+
+    if (!highlight || highlight.length < 3) {
+      return done();
+    }
+
+    delete opt.highlight;
+
+    if (!pending) return done();
+
+    for (; i < tokens.length; i++) {
+      (function(token) {
+        if (token.type !== 'code') {
+          return --pending || done();
+        }
+        return highlight(token.text, token.lang, function(err, code) {
+          if (err) return done(err);
+          if (code == null || code === token.text) {
+            return --pending || done();
+          }
+          token.text = code;
+          token.escaped = true;
+          --pending || done();
+        });
+      })(tokens[i]);
+    }
+
+    return;
+  }
+  try {
+    if (opt) opt = merge({}, marked.defaults, opt);
+    return Parser.parse(Lexer.lex(src, opt), opt);
+  } catch (e) {
+    e.message += '\nPlease report this to https://github.com/chjj/marked.';
+    if ((opt || marked.defaults).silent) {
+      return '<p>An error occured:</p><pre>'
+        + escape(e.message + '', true)
+        + '</pre>';
+    }
+    throw e;
+  }
+}
+
+/**
+ * Options
+ */
+
+marked.options =
+marked.setOptions = function(opt) {
+  merge(marked.defaults, opt);
+  return marked;
+};
+
+marked.defaults = {
+  gfm: true,
+  tables: true,
+  breaks: false,
+  pedantic: false,
+  sanitize: false,
+  smartLists: false,
+  silent: false,
+  highlight: null,
+  langPrefix: 'lang-',
+  smartypants: false,
+  headerPrefix: '',
+  renderer: new Renderer,
+  xhtml: false
+};
+
+/**
+ * Expose
+ */
+
+marked.Parser = Parser;
+marked.parser = Parser.parse;
+
+marked.Renderer = Renderer;
+
+marked.Lexer = Lexer;
+marked.lexer = Lexer.lex;
+
+marked.InlineLexer = InlineLexer;
+marked.inlineLexer = InlineLexer.output;
+
+marked.parse = marked;
+
+if (typeof module !== 'undefined' && typeof exports === 'object') {
+  module.exports = marked;
+} else if (typeof define === 'function' && define.amd) {
+  define(function() { return marked; });
+} else {
+  this.marked = marked;
+}
+
+}).call(function() {
+  return this || (typeof window !== 'undefined' ? window : global);
+}());
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/lib/swagger-oauth.js b/src/main/resources/META-INF/resources/icd/lib/swagger-oauth.js
new file mode 100644 (file)
index 0000000..2bb6be1
--- /dev/null
@@ -0,0 +1,339 @@
+var appName;
+var popupMask;
+var popupDialog;
+var clientId;
+var realm;
+var redirect_uri;
+var clientSecret;
+var scopeSeparator;
+var additionalQueryStringParams;
+
+function handleLogin() {
+  var scopes = [];
+
+  var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions;
+  if(auths) {
+    var key;
+    var defs = auths;
+    for(key in defs) {
+      var auth = defs[key];
+      if(auth.type === 'oauth2' && auth.scopes) {
+        var scope;
+        if(Array.isArray(auth.scopes)) {
+          // 1.2 support
+          var i;
+          for(i = 0; i < auth.scopes.length; i++) {
+            scopes.push(auth.scopes[i]);
+          }
+        }
+        else {
+          // 2.0 support
+          for(scope in auth.scopes) {
+            scopes.push({scope: scope, description: auth.scopes[scope], OAuthSchemeKey: key});
+          }
+        }
+      }
+    }
+  }
+
+  if(window.swaggerUi.api
+    && window.swaggerUi.api.info) {
+    appName = window.swaggerUi.api.info.title;
+  }
+
+  $('.api-popup-dialog').remove(); 
+  popupDialog = $(
+    [
+      '<div class="api-popup-dialog">',
+      '<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
+      '<div class="api-popup-content">',
+        '<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
+          '<a href="#">Learn how to use</a>',
+        '</p>',
+        '<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
+        '<ul class="api-popup-scopes">',
+        '</ul>',
+        '<p class="error-msg"></p>',
+        '<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
+      '</div>',
+      '</div>'].join(''));
+  $(document.body).append(popupDialog);
+
+  //TODO: only display applicable scopes (will need to pass them into handleLogin)
+  popup = popupDialog.find('ul.api-popup-scopes').empty();
+  for (i = 0; i < scopes.length; i ++) {
+    scope = scopes[i];
+    str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"' +'" oauthtype="' + scope.OAuthSchemeKey +'"/>' + '<label for="scope_' + i + '">' + scope.scope ;
+    if (scope.description) {
+      if ($.map(auths, function(n, i) { return i; }).length > 1) //if we have more than one scheme, display schemes
+           str += '<br/><span class="api-scope-desc">' + scope.description + ' ('+ scope.OAuthSchemeKey+')' +'</span>';
+         else
+           str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
+    }
+    str += '</label></li>';
+    popup.append(str);
+  }
+
+  var $win = $(window),
+    dw = $win.width(),
+    dh = $win.height(),
+    st = $win.scrollTop(),
+    dlgWd = popupDialog.outerWidth(),
+    dlgHt = popupDialog.outerHeight(),
+    top = (dh -dlgHt)/2 + st,
+    left = (dw - dlgWd)/2;
+
+  popupDialog.css({
+    top: (top < 0? 0 : top) + 'px',
+    left: (left < 0? 0 : left) + 'px'
+  });
+
+  popupDialog.find('button.api-popup-cancel').click(function() {
+    popupMask.hide();
+    popupDialog.hide();
+    popupDialog.empty();
+    popupDialog = [];
+  });
+
+  $('button.api-popup-authbtn').unbind();
+  popupDialog.find('button.api-popup-authbtn').click(function() {
+    popupMask.hide();
+    popupDialog.hide();
+
+    var authSchemes = window.swaggerUi.api.authSchemes;
+    var host = window.location;
+    var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
+    var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
+    var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
+    var url = null;
+    var scopes = []
+    var o = popup.find('input:checked'); 
+    var OAuthSchemeKeys = [];
+    var state;
+    for(k =0; k < o.length; k++) {
+      var scope = $(o[k]).attr('scope');
+      if (scopes.indexOf(scope) === -1)
+        scopes.push(scope);
+      var OAuthSchemeKey = $(o[k]).attr('oauthtype');      
+      if (OAuthSchemeKeys.indexOf(OAuthSchemeKey) === -1)
+          OAuthSchemeKeys.push(OAuthSchemeKey);
+    }
+    
+    //TODO: merge not replace if scheme is different from any existing 
+    //(needs to be aware of schemes to do so correctly)
+    window.enabledScopes=scopes;    
+    
+    for (var key in authSchemes) { 
+      if (authSchemes.hasOwnProperty(key) && OAuthSchemeKeys.indexOf(key) != -1) { //only look at keys that match this scope.
+        var flow = authSchemes[key].flow;
+
+        if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
+          var dets = authSchemes[key];
+          url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
+          window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+          window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
+          state = key;
+        }
+        else if(authSchemes[key].type === 'oauth2' && flow && (flow === 'application')) {
+            var dets = authSchemes[key];
+            window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+            clientCredentialsFlow(scopes, dets.tokenUrl, key);
+            return;
+        }        
+        else if(authSchemes[key].grantTypes) {
+          // 1.2 support
+          var o = authSchemes[key].grantTypes;
+          for(var t in o) {
+            if(o.hasOwnProperty(t) && t === 'implicit') {
+              var dets = o[t];
+              var ep = dets.loginEndpoint.url;
+              url = dets.loginEndpoint.url + '?response_type=token';
+              window.swaggerUi.tokenName = dets.tokenName;
+            }
+            else if (o.hasOwnProperty(t) && t === 'accessCode') {
+              var dets = o[t];
+              var ep = dets.tokenRequestEndpoint.url;
+              url = dets.tokenRequestEndpoint.url + '?response_type=code';
+              window.swaggerUi.tokenName = dets.tokenName;
+            }
+          }
+        }
+      }
+    }
+
+    redirect_uri = redirectUrl;
+
+    url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
+    url += '&realm=' + encodeURIComponent(realm);
+    url += '&client_id=' + encodeURIComponent(clientId);
+    url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
+    url += '&state=' + encodeURIComponent(state);
+    for (var key in additionalQueryStringParams) {
+        url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
+    }
+
+    window.open(url);
+  });
+
+  popupMask.show();
+  popupDialog.show();
+  return;
+}
+
+
+function handleLogout() {
+  for(key in window.swaggerUi.api.clientAuthorizations.authz){
+    window.swaggerUi.api.clientAuthorizations.remove(key)
+  }
+  window.enabledScopes = null;
+  $('.api-ic.ic-on').addClass('ic-off');
+  $('.api-ic.ic-on').removeClass('ic-on');
+
+  // set the info box
+  $('.api-ic.ic-warning').addClass('ic-error');
+  $('.api-ic.ic-warning').removeClass('ic-warning');
+}
+
+function initOAuth(opts) {
+  var o = (opts||{});
+  var errors = [];
+
+  appName = (o.appName||errors.push('missing appName'));
+  popupMask = (o.popupMask||$('#api-common-mask'));
+  popupDialog = (o.popupDialog||$('.api-popup-dialog'));
+  clientId = (o.clientId||errors.push('missing client id'));
+  clientSecret = (o.clientSecret||null);
+  realm = (o.realm||errors.push('missing realm'));
+  scopeSeparator = (o.scopeSeparator||' ');
+  additionalQueryStringParams = (o.additionalQueryStringParams||{});
+
+  if(errors.length > 0){
+    log('auth unable initialize oauth: ' + errors);
+    return;
+  }
+
+  $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
+  $('.api-ic').unbind();
+  $('.api-ic').click(function(s) {
+    if($(s.target).hasClass('ic-off'))
+      handleLogin();
+    else {
+      handleLogout();
+    }
+    false;
+  });
+}
+
+function clientCredentialsFlow(scopes, tokenUrl, OAuthSchemeKey) {
+    var params = {
+      'client_id': clientId,
+      'client_secret': clientSecret,
+      'scope': scopes.join(' '),
+      'grant_type': 'client_credentials'
+    }
+    $.ajax(
+    {
+      url : tokenUrl,
+      type: "POST",
+      data: params,
+      success:function(data, textStatus, jqXHR)
+      {
+        onOAuthComplete(data,OAuthSchemeKey);
+      },
+      error: function(jqXHR, textStatus, errorThrown)
+      {
+        onOAuthComplete("");
+      }
+    });
+    
+  }
+
+window.processOAuthCode = function processOAuthCode(data) {
+  var OAuthSchemeKey = data.state;
+  var params = {
+    'client_id': clientId,
+    'code': data.code,
+    'grant_type': 'authorization_code',
+    'redirect_uri': redirect_uri
+  };
+
+  if (clientSecret) {
+    params.client_secret = clientSecret;
+  }
+
+  $.ajax(
+  {
+    url : window.swaggerUi.tokenUrl,
+    type: "POST",
+    data: params,
+    success:function(data, textStatus, jqXHR)
+    {
+      onOAuthComplete(data, OAuthSchemeKey);
+    },
+    error: function(jqXHR, textStatus, errorThrown)
+    {
+      onOAuthComplete("");
+    }
+  });
+};
+
+window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) {
+  if(token) {
+    if(token.error) {
+      var checkbox = $('input[type=checkbox],.secured')
+      checkbox.each(function(pos){
+        checkbox[pos].checked = false;
+      });
+      alert(token.error);
+    }
+    else {
+      var b = token[window.swaggerUi.tokenName];      
+      if (!OAuthSchemeKey){
+          OAuthSchemeKey = token.state;
+      }
+      if(b){
+        // if all roles are satisfied
+        var o = null;
+        $.each($('.auth .api-ic .api_information_panel'), function(k, v) { 
+          var children = v;
+          if(children && children.childNodes) {
+            var requiredScopes = [];
+            $.each((children.childNodes), function (k1, v1){
+              var inner = v1.innerHTML;
+              if(inner)
+                requiredScopes.push(inner);
+            });
+            var diff = [];
+            for(var i=0; i < requiredScopes.length; i++) {
+              var s = requiredScopes[i];
+              if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) {
+                diff.push(s);
+              }
+            }
+            if(diff.length > 0){
+              o = v.parentNode.parentNode;
+              $(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
+              $(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
+
+              // sorry, not all scopes are satisfied
+              $(o).find('.api-ic').addClass('ic-warning');
+              $(o).find('.api-ic').removeClass('ic-error');
+            }
+            else {
+              o = v.parentNode.parentNode;
+              $(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
+              $(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
+
+              // all scopes are satisfied
+              $(o).find('.api-ic').addClass('ic-info');
+              $(o).find('.api-ic').removeClass('ic-warning');
+              $(o).find('.api-ic').removeClass('ic-error');
+            }
+          }
+        });
+        window.swaggerUi.api.clientAuthorizations.add(window.OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
+        window.swaggerUi.load();
+      }
+    }
+  }
+};
diff --git a/src/main/resources/META-INF/resources/icd/o2c.html b/src/main/resources/META-INF/resources/icd/o2c.html
new file mode 100644 (file)
index 0000000..88e8bf1
--- /dev/null
@@ -0,0 +1,20 @@
+<script>
+var qp = null;
+if(window.location.hash) {
+  qp = location.hash.substring(1);
+}
+else {
+  qp = location.search.substring(1);
+}
+qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
+  function(key, value) {
+    return key===""?value:decodeURIComponent(value) }
+  ):{}
+
+if (window.opener.swaggerUi.tokenUrl)
+    window.opener.processOAuthCode(qp);
+else
+    window.opener.onOAuthComplete(qp);
+
+window.close();
+</script>
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/swagger-ui.js b/src/main/resources/META-INF/resources/icd/swagger-ui.js
new file mode 100644 (file)
index 0000000..7e0cc6d
--- /dev/null
@@ -0,0 +1,22284 @@
+/**
+ * swagger-ui - Swagger UI is a dependency-free collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API
+ * @version v2.1.4
+ * @link http://swagger.io
+ * @license Apache-2.0
+ */
+(function(){this["Handlebars"] = this["Handlebars"] || {};
+this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {};
+this["Handlebars"]["templates"]["apikey_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                <span class=\"key_auth__value\">"
+    + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper)))
+    + "</span>\n";
+},"3":function(depth0,helpers,partials,data) {
+  return "                <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class=\"key_input_container\">\n    <h3 class=\"auth__title\">Api key authorization</h3>\n    <div class=\"auth__description\">"
+    + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))
+    + "</div>\n    <div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">name:</span>\n            <span class=\"key_auth__value\">"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">in:</span>\n            <span class=\"key_auth__value\">"
+    + escapeExpression(((helper = (helper = helpers['in'] || (depth0 != null ? depth0['in'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"in","hash":{},"data":data}) : helper)))
+    + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">value:</span>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "        </div>\n    </div>\n</div>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["auth_button_operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return "        authorize__btn_operation_login\n";
+  },"3":function(depth0,helpers,partials,data) {
+  return "        authorize__btn_operation_logout\n";
+  },"5":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "        <ul class=\"authorize-scopes\">\n";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "        </ul>\n";
+},"6":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                <li class=\"authorize__scope\" title=\""
+    + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))
+    + "\">"
+    + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))
+    + "</li>\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "<div class=\"authorize__btn authorize__btn_operation\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\">\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</div>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["auth_button"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  return "<a class='authorize__btn' href=\"#\">Authorize</a>\n";
+  },"useData":true});
+this["Handlebars"]["templates"]["auth_view"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return "            <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n";
+  },"3":function(depth0,helpers,partials,data) {
+  return "            <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "<div class=\"auth_container\">\n\n    <div class=\"auth_inner\"></div>\n    <div class=\"auth_submit\">\n";
+  stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isAuthorized : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "    </div>\n\n</div>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["basic_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return " - authorized";
+  },"3":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                <span class=\"basic_auth__value\">"
+    + escapeExpression(((helper = (helper = helpers.username || (depth0 != null ? depth0.username : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"username","hash":{},"data":data}) : helper)))
+    + "</span>\n";
+},"5":function(depth0,helpers,partials,data) {
+  return "                <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n";
+  },"7":function(depth0,helpers,partials,data) {
+  return "            <div class=\"auth_label\">\n                <span class=\"basic_auth__label\" data-sw-translate>password:</span>\n                <input required placeholder=\"password\" class=\"basic_auth__password auth_input\" name=\"password\" type=\"password\"/></label>\n            </div>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</h3>\n    <form class=\"basic_input_container\">\n        <div class=\"auth__description\">"
+    + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))
+    + "</div>\n        <div class=\"auth_label\">\n            <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "        </div>\n";
+  stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "    </form>\n</div>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"2":function(depth0,helpers,partials,data) {
+  var lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "     <option value=\""
+    + escapeExpression(lambda(depth0, depth0))
+    + "\">"
+    + escapeExpression(lambda(depth0, depth0))
+    + "</option>\n";
+},"4":function(depth0,helpers,partials,data) {
+  return "  <option value=\"application/json\">application/json</option>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\""
+    + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper)))
+    + "\">Response Content Type</label>\n<select name=\"contentType\" id=\""
+    + escapeExpression(((helper = (helper = helpers.contentTypeId || (depth0 != null ? depth0.contentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"contentTypeId","hash":{},"data":data}) : helper)))
+    + "\">\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</select>\n";
+},"useData":true});
+'use strict';
+
+
+$(function() {
+
+       // Helper function for vertically aligning DOM elements
+       // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/
+       $.fn.vAlign = function() {
+               return this.each(function(){
+                       var ah = $(this).height();
+                       var ph = $(this).parent().height();
+                       var mh = (ph - ah) / 2;
+                       $(this).css('margin-top', mh);
+               });
+       };
+
+       $.fn.stretchFormtasticInputWidthToParent = function() {
+               return this.each(function(){
+                       var p_width = $(this).closest("form").innerWidth();
+                       var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10);
+                       var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10);
+                       $(this).css('width', p_width - p_padding - this_padding);
+               });
+       };
+
+       $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent();
+
+       // Vertically center these paragraphs
+       // Parent may need a min-height for this to work..
+       $('ul.downplayed li div.content p').vAlign();
+
+       // When a sandbox form is submitted..
+       $("form.sandbox").submit(function(){
+
+               var error_free = true;
+
+               // Cycle through the forms required inputs
+               $(this).find("input.required").each(function() {
+
+                       // Remove any existing error styles from the input
+                       $(this).removeClass('error');
+
+                       // Tack the error style on if the input is empty..
+                       if ($(this).val() === '') {
+                               $(this).addClass('error');
+                               $(this).wiggle();
+                               error_free = false;
+                       }
+
+               });
+
+               return error_free;
+       });
+
+});
+
+function clippyCopiedCallback() {
+  $('#api_key_copied').fadeIn().delay(1000).fadeOut();
+
+  // var b = $("#clippy_tooltip_" + a);
+  // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() {
+  //   b.attr("title", "copy to clipboard")
+  // },
+  // 500))
+}
+
+// Logging function that accounts for browsers that don't have window.console
+function log(){
+  log.history = log.history || [];
+  log.history.push(arguments);
+  if(this.console){
+    console.log( Array.prototype.slice.call(arguments)[0] );
+  }
+}
+
+// Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)
+if (Function.prototype.bind && console && typeof console.log === "object") {
+    [
+      "log","info","warn","error","assert","dir","clear","profile","profileEnd"
+    ].forEach(function (method) {
+        console[method] = this.bind(console[method], console);
+    }, Function.prototype.call);
+}
+
+window.Docs = {
+
+       shebang: function() {
+
+               // If shebang has an operation nickname in it..
+               // e.g. /docs/#!/words/get_search
+               var fragments = $.param.fragment().split('/');
+               fragments.shift(); // get rid of the bang
+
+               switch (fragments.length) {
+                       case 1:
+        if (fragments[0].length > 0) { // prevent matching "#/"
+          // Expand all operations for the resource and scroll to it
+          var dom_id = 'resource_' + fragments[0];
+
+          Docs.expandEndpointListForResource(fragments[0]);
+          $("#"+dom_id).slideto({highlight: false});
+        }
+                               break;
+                       case 2:
+                               // Refer to the endpoint DOM element, e.g. #words_get_search
+
+        // Expand Resource
+        Docs.expandEndpointListForResource(fragments[0]);
+        $("#"+dom_id).slideto({highlight: false});
+
+            // Expand operation
+            var li_dom_id = fragments.join('_');
+            var li_content_dom_id = li_dom_id + "_content";
+
+
+            Docs.expandOperation($('#'+li_content_dom_id));
+            $('#'+li_dom_id).slideto({highlight: false});
+            break;
+               }
+       },
+
+       toggleEndpointListForResource: function(resource) {
+               var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints');
+               if (elem.is(':visible')) {
+                       $.bbq.pushState('#/', 2);
+                       Docs.collapseEndpointListForResource(resource);
+               } else {
+            $.bbq.pushState('#/' + resource, 2);
+                       Docs.expandEndpointListForResource(resource);
+               }
+       },
+
+       // Expand resource
+       expandEndpointListForResource: function(resource) {
+               var resource = Docs.escapeResourceName(resource);
+               if (resource == '') {
+                       $('.resource ul.endpoints').slideDown();
+                       return;
+               }
+
+               $('li#resource_' + resource).addClass('active');
+
+               var elem = $('li#resource_' + resource + ' ul.endpoints');
+               elem.slideDown();
+       },
+
+       // Collapse resource and mark as explicitly closed
+       collapseEndpointListForResource: function(resource) {
+               var resource = Docs.escapeResourceName(resource);
+               if (resource == '') {
+                       $('.resource ul.endpoints').slideUp();
+                       return;
+               }
+
+               $('li#resource_' + resource).removeClass('active');
+
+               var elem = $('li#resource_' + resource + ' ul.endpoints');
+               elem.slideUp();
+       },
+
+       expandOperationsForResource: function(resource) {
+               // Make sure the resource container is open..
+               Docs.expandEndpointListForResource(resource);
+
+               if (resource == '') {
+                       $('.resource ul.endpoints li.operation div.content').slideDown();
+                       return;
+               }
+
+               $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
+                       Docs.expandOperation($(this));
+               });
+       },
+
+       collapseOperationsForResource: function(resource) {
+               // Make sure the resource container is open..
+               Docs.expandEndpointListForResource(resource);
+
+               if (resource == '') {
+                       $('.resource ul.endpoints li.operation div.content').slideUp();
+                       return;
+               }
+
+               $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
+                       Docs.collapseOperation($(this));
+               });
+       },
+
+       escapeResourceName: function(resource) {
+               return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&");
+       },
+
+       expandOperation: function(elem) {
+               elem.slideDown();
+       },
+
+       collapseOperation: function(elem) {
+               elem.slideUp();
+       }
+};
+
+'use strict';
+/*jslint eqeq: true*/
+
+Handlebars.registerHelper('sanitize', function(html) {
+    // Strip the script tags from the html, and return it as a Handlebars.SafeString
+    html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
+    return new Handlebars.SafeString(html);
+});
+
+Handlebars.registerHelper('renderTextParam', function(param) {
+    var result, type = 'text', idAtt = '';
+    var paramType = param.type || param.schema.type || '';
+    var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple;
+    var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default;
+
+    var dataVendorExtensions = Object.keys(param).filter(function(property) {
+        // filter X-data- properties
+        return property.match(/^X-data-/i) !== null;
+    }).reduce(function(result, property) {
+        // remove X- from property name, so it results in html attributes like data-foo='bar'
+        return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\'';
+    }, '');
+
+    if (typeof defaultValue === 'undefined') {
+        defaultValue = '';
+    }
+
+    if(param.format && param.format === 'password') {
+        type = 'password';
+    }
+
+    if(param.valueId) {
+        idAtt = ' id=\'' + param.valueId + '\'';
+    }
+
+    if (typeof defaultValue === 'string' || defaultValue instanceof String) {
+        defaultValue = defaultValue.replace(/'/g,'&apos;');
+    }
+
+    if(isArray) {
+        result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + param.name + '\'' + idAtt + dataVendorExtensions;
+        result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>';
+        result += defaultValue + '</textarea>';
+    } else {
+        var parameterClass = 'parameter';
+        if(param.required) {
+          parameterClass += ' required';
+        }
+        result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\'';
+        result += ' name=\'' + param.name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions;
+        result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>';
+    }
+    return new Handlebars.SafeString(result);
+});
+
+Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
+
+    switch (operator) {
+        case '==':
+            return (v1 == v2) ? options.fn(this) : options.inverse(this);
+        case '===':
+            return (v1 === v2) ? options.fn(this) : options.inverse(this);
+        case '<':
+            return (v1 < v2) ? options.fn(this) : options.inverse(this);
+        case '<=':
+            return (v1 <= v2) ? options.fn(this) : options.inverse(this);
+        case '>':
+            return (v1 > v2) ? options.fn(this) : options.inverse(this);
+        case '>=':
+            return (v1 >= v2) ? options.fn(this) : options.inverse(this);
+        case '&&':
+            return (v1 && v2) ? options.fn(this) : options.inverse(this);
+        case '||':
+            return (v1 || v2) ? options.fn(this) : options.inverse(this);
+        default:
+            return options.inverse(this);
+    }
+});
+this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = "  <div class=\"info_title\">"
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0))
+    + "</div>\n  <div class=\"info_description markdown\">";
+  stack1 = lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1), depth0);
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</div>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.externalDocs : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "  ";
+  stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  ";
+  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), {"name":"if","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  ";
+  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  ";
+  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  ";
+  stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "\n";
+},"2":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "  <p>"
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1), depth0))
+    + "</p>\n  <a href=\""
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0))
+    + "\" target=\"_blank\">"
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1), depth0))
+    + "</a>\n";
+},"4":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "<div class=\"info_tos\"><a target=\"_blank\" href=\""
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1), depth0))
+    + "\" data-sw-translate>Terms of service</a></div>";
+},"6":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "<div class='info_name' data-sw-translate>Created by "
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1), depth0))
+    + "</div>";
+},"8":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "<div class='info_url' data-sw-translate>See more at <a href=\""
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0))
+    + "\">"
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1), depth0))
+    + "</a></div>";
+},"10":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "<div class='info_email'><a target=\"_parent\" href=\"mailto:"
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1), depth0))
+    + "?subject="
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1), depth0))
+    + "\" data-sw-translate>Contact the developer</a></div>";
+},"12":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "<div class='info_license'><a target=\"_blank\" href='"
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1), depth0))
+    + "'>"
+    + escapeExpression(lambda(((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1), depth0))
+    + "</a></div>";
+},"14":function(depth0,helpers,partials,data) {
+  var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "  , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: "
+    + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), depth0))
+    + "\n    ";
+},"16":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "    <span style=\"float:right\"><a target=\"_blank\" href=\""
+    + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper)))
+    + "/debug?url="
+    + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper)))
+    + "\"><img id=\"validator\" src=\""
+    + escapeExpression(((helper = (helper = helpers.validatorUrl || (depth0 != null ? depth0.validatorUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"validatorUrl","hash":{},"data":data}) : helper)))
+    + "?url="
+    + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper)))
+    + "\"></a>\n    </span>\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div class='info' id='api_info'>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.info : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "
+    + escapeExpression(((helper = (helper = helpers.basePath || (depth0 != null ? depth0.basePath : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"basePath","hash":{},"data":data}) : helper)))
+    + "\n";
+  stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "]\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.validatorUrl : depth0), {"name":"if","hash":{},"fn":this.program(16, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "    </h4>\n    </div>\n</div>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["oauth2"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "            <li>\n                <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""
+    + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))
+    + "\" oauthtype=\""
+    + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper)))
+    + "\"/>\n                <label>"
+    + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper)))
+    + "</label><br/>\n                <span class=\"api-scope-desc\">"
+    + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))
+    + "\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.OAuthSchemeKey : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "                </span>\n            </li>\n";
+},"2":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                        ("
+    + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper)))
+    + ")\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<div>\n    <h3 class=\"auth__title\">Select OAuth2.0 Scopes</h3>\n    <p>"
+    + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper)))
+    + "</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href=\"#\">Learn how to use</a>\n    </p>\n    <p><strong> "
+    + escapeExpression(((helper = (helper = helpers.appName || (depth0 != null ? depth0.appName : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"appName","hash":{},"data":data}) : helper)))
+    + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Authorization URL: "
+    + escapeExpression(((helper = (helper = helpers.authorizationUrl || (depth0 != null ? depth0.authorizationUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"authorizationUrl","hash":{},"data":data}) : helper)))
+    + "</p>\n    <p>flow: "
+    + escapeExpression(((helper = (helper = helpers.flow || (depth0 != null ? depth0.flow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"flow","hash":{},"data":data}) : helper)))
+    + "</p>\n    <ul class=\"api-popup-scopes\">\n";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "    </ul>\n</div>";
+},"useData":true});
+this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return "deprecated";
+  },"3":function(depth0,helpers,partials,data) {
+  return "            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n";
+  },"5":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</div>\n";
+},"7":function(depth0,helpers,partials,data) {
+  return "            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n";
+  },"9":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "          <div class=\"response-class\">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> "
+    + escapeExpression(((helper = (helper = helpers.successCode || (depth0 != null ? depth0.successCode : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successCode","hash":{},"data":data}) : helper)))
+    + ")</h4>\n              ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.successDescription : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "\n            <p><span class=\"model-signature\" /></p>\n            <br/>\n            <div class=\"response-content-type\" />\n            </div>\n";
+},"10":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "<div class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.successDescription || (depth0 != null ? depth0.successDescription : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successDescription","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</div>";
+},"12":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "          <h4 data-sw-translate>Headers</h4>\n          <table class=\"headers\">\n            <thead>\n              <tr>\n                <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Header</th>\n                <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Description</th>\n                <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Type</th>\n                <th style=\"width: 320px; max-width: 320px\" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "            </tbody>\n          </table>\n";
+},"13":function(depth0,helpers,partials,data) {
+  var lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "              <tr>\n                <td>"
+    + escapeExpression(lambda((data && data.key), depth0))
+    + "</td>\n                <td>"
+    + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0))
+    + "</td>\n                <td>"
+    + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0))
+    + "</td>\n                <td>"
+    + escapeExpression(lambda((depth0 != null ? depth0.other : depth0), depth0))
+    + "</td>\n              </tr>\n";
+},"15":function(depth0,helpers,partials,data) {
+  return "          <h4 data-sw-translate>Parameters</h4>\n          <table class='fullwidth'>\n          <thead>\n            <tr>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter</th>\n            <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Value</th>\n            <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Description</th>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter Type</th>\n            <th style=\"width: 220px; max-width: 230px\" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class=\"operation-params\">\n\n          </tbody>\n          </table>\n";
+  },"17":function(depth0,helpers,partials,data) {
+  return "          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n";
+  },"19":function(depth0,helpers,partials,data) {
+  return "";
+},"21":function(depth0,helpers,partials,data) {
+  return "          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n";
+  },"23":function(depth0,helpers,partials,data) {
+  return "          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <ul class='operations' >\n    <li class='"
+    + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper)))
+    + " operation' id='"
+    + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper)))
+    + "_"
+    + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper)))
+    + "'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"
+    + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper)))
+    + "/"
+    + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper)))
+    + "' class=\"toggleOperation\">"
+    + escapeExpression(((helper = (helper = helpers.method || (depth0 != null ? depth0.method : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"method","hash":{},"data":data}) : helper)))
+    + "</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"
+    + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper)))
+    + "/"
+    + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper)))
+    + "' class=\"toggleOperation ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\">"
+    + escapeExpression(((helper = (helper = helpers.path || (depth0 != null ? depth0.path : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"path","hash":{},"data":data}) : helper)))
+    + "</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"
+    + escapeExpression(((helper = (helper = helpers.encodedParentId || (depth0 != null ? depth0.encodedParentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"encodedParentId","hash":{},"data":data}) : helper)))
+    + "/"
+    + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper)))
+    + "' class=\"toggleOperation\">";
+  stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"
+    + escapeExpression(((helper = (helper = helpers.parentId || (depth0 != null ? depth0.parentId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parentId","hash":{},"data":data}) : helper)))
+    + "_"
+    + escapeExpression(((helper = (helper = helpers.nickname || (depth0 != null ? depth0.nickname : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nickname","hash":{},"data":data}) : helper)))
+    + "_content' style='display:none'>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.deprecated : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.description : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.security : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.type : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.parameters : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.responseMessages : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isReadOnly : depth0), {"name":"if","hash":{},"fn":this.program(19, data),"inverse":this.program(21, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showRequestHeaders : depth0), {"name":"if","hash":{},"fn":this.program(23, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["param_list"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return " required";
+  },"3":function(depth0,helpers,partials,data) {
+  return " multiple=\"multiple\"";
+  },"5":function(depth0,helpers,partials,data) {
+  return " required ";
+  },"7":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "      <option ";
+  stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.hasDefault : depth0), {"name":"unless","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + " value=''></option>\n";
+},"8":function(depth0,helpers,partials,data) {
+  return "  selected=\"\" ";
+  },"10":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n      <option ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "  value='"
+    + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper)))
+    + "'> "
+    + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper)))
+    + " ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isDefault : depth0), {"name":"if","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + " </option>\n\n";
+},"11":function(depth0,helpers,partials,data) {
+  return " selected=\"\"  ";
+  },"13":function(depth0,helpers,partials,data) {
+  return " (default) ";
+  },"15":function(depth0,helpers,partials,data) {
+  return "<strong>";
+  },"17":function(depth0,helpers,partials,data) {
+  return "</strong>";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "'><label for='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</label></td>\n<td>\n  <select ";
+  stack1 = ((helpers.isArray || (depth0 && depth0.isArray) || helperMissing).call(depth0, depth0, {"name":"isArray","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += " class=\"parameter ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\" name=\""
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "\" id=\""
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "\">\n\n";
+  stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n";
+  stack1 = helpers.each.call(depth0, ((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1), {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  </select>\n</td>\n<td class=\"markdown\">";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.required : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td>";
+  stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["param_readonly_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "</textarea>\n";
+},"3":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"4":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "            "
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "\n";
+},"6":function(depth0,helpers,partials,data) {
+  return "            (empty)\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</label></td>\n<td>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td>";
+  stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["param_readonly"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "        <textarea class='body-textarea' readonly='readonly' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "</textarea>\n        <div class=\"parameter-content-type\" />\n";
+},"3":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(4, data),"inverse":this.program(6, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"4":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "            "
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "\n";
+},"6":function(depth0,helpers,partials,data) {
+  return "            (empty)\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</label></td>\n<td>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td>";
+  stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["param_required"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"2":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                     <input type=\"file\" name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'/>\n";
+},"4":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"5":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                             <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea required' placeholder='(required)' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id=\""
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "\">"
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
+},"7":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                             <textarea class='body-textarea required' placeholder='(required)' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'></textarea>\n                         <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";
+},"9":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.program(12, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"10":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                     <input class='parameter' class='required' type='file' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'/>\n";
+},"12":function(depth0,helpers,partials,data) {
+  var stack1, helperMissing=helpers.helperMissing, buffer = "";
+  stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"13":function(depth0,helpers,partials,data) {
+  return "";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code required'><label for='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</label></td>\n<td>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td>\n     <strong><span class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</span></strong>\n</td>\n<td>";
+  stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["param"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"2":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                     <input type=\"file\" name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'/>\n                   <div class=\"parameter-content-type\" />\n";
+},"4":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['default'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"5":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                             <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers['default'] || (depth0 != null ? depth0['default'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"default","hash":{},"data":data}) : helper)))
+    + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
+},"7":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "                             <textarea class='body-textarea' name='"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "' id='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'></textarea>\n                         <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";
+},"9":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isFile : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(10, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"10":function(depth0,helpers,partials,data) {
+  var stack1, helperMissing=helpers.helperMissing, buffer = "";
+  stack1 = ((helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helperMissing).call(depth0, depth0, {"name":"renderTextParam","hash":{},"fn":this.program(11, data),"inverse":this.noop,"data":data}));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"11":function(depth0,helpers,partials,data) {
+  return "";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td class='code'><label for='"
+    + escapeExpression(((helper = (helper = helpers.valueId || (depth0 != null ? depth0.valueId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"valueId","hash":{},"data":data}) : helper)))
+    + "'>"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</label></td>\n<td>\n\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isBody : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(9, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n</td>\n<td class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td>";
+  stack1 = ((helper = (helper = helpers.paramType || (depth0 != null ? depth0.paramType : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"paramType","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</td>\n<td>\n       <span class=\"model-signature\"></span>\n</td>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["parameter_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"2":function(depth0,helpers,partials,data) {
+  var lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "  <option value=\""
+    + escapeExpression(lambda(depth0, depth0))
+    + "\">"
+    + escapeExpression(lambda(depth0, depth0))
+    + "</option>\n";
+},"4":function(depth0,helpers,partials,data) {
+  return "  <option value=\"application/json\">application/json</option>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label for=\""
+    + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper)))
+    + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\""
+    + escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"parameterContentTypeId","hash":{},"data":data}) : helper)))
+    + "\">\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.consumes : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</select>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["popup"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "<div class=\"api-popup-dialog-wrapper\">\n    <div class=\"api-popup-title\">"
+    + escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"title","hash":{},"data":data}) : helper)))
+    + "</div>\n    <div class=\"api-popup-content\"></div>\n    <p class=\"error-msg\"></p>\n    <div class=\"api-popup-actions\">\n        <button class=\"api-popup-cancel api-button gray\" type=\"button\">Cancel</button>\n    </div>\n</div>\n<div class=\"api-popup-dialog-shadow\"></div>";
+},"useData":true});
+this["Handlebars"]["templates"]["resource"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  return " : ";
+  },"3":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "    <li>\n      <a href='"
+    + escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper)))
+    + "' data-sw-translate>Raw</a>\n    </li>\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "<div class='heading'>\n  <h2>\n    <a href='#!/"
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "' class=\"toggleEndpointList\" data-id=\""
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "\">"
+    + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper)))
+    + "</a> ";
+  stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(options={"name":"summary","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}),(typeof helper === functionType ? helper.call(depth0, options) : helper));
+  if (!helpers.summary) { stack1 = blockHelperMissing.call(depth0, stack1, options); }
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"summary","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "' id='endpointListTogger_"
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "' class=\"toggleEndpointList\" data-id=\""
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "\" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href='#' class=\"collapseResource\" data-id=\""
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "\" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href='#' class=\"expandResource\" data-id=\""
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "\" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.url : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "  </ul>\n</div>\n<ul class='endpoints' id='"
+    + escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper)))
+    + "_endpoint_list' style='display:none'>\n\n</ul>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["response_content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, buffer = "";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer;
+},"2":function(depth0,helpers,partials,data) {
+  var lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "  <option value=\""
+    + escapeExpression(lambda(depth0, depth0))
+    + "\">"
+    + escapeExpression(lambda(depth0, depth0))
+    + "</option>\n";
+},"4":function(depth0,helpers,partials,data) {
+  return "  <option value=\"application/json\">application/json</option>\n";
+  },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<label data-sw-translate for=\""
+    + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
+    + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\""
+    + escapeExpression(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
+    + "\">\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(4, data),"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "</select>\n";
+},"useData":true});
+this["Handlebars"]["templates"]["signature"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "\n<div>\n<ul class=\"signature-nav\">\n  <li><a class=\"description-link\" href=\"#\" data-sw-translate>Model</a></li>\n  <li><a class=\"snippet-link\" href=\"#\" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n  <div class=\"description\">\n    ";
+  stack1 = ((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "\n  </div>\n\n  <div class=\"snippet\">\n";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.sampleXML : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "  </div>\n</div>\n";
+},"2":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "      <div class=\"snippet_json\">\n        <pre><code>"
+    + escapeExpression(((helper = (helper = helpers.sampleJSON || (depth0 != null ? depth0.sampleJSON : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleJSON","hash":{},"data":data}) : helper)))
+    + "</code></pre>\n        ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "\n      </div>\n";
+},"3":function(depth0,helpers,partials,data) {
+  return "<small class=\"notice\" data-sw-translate></small>";
+  },"5":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "    <div class=\"snippet_xml\">\n      <pre><code>"
+    + escapeExpression(((helper = (helper = helpers.sampleXML || (depth0 != null ? depth0.sampleXML : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"sampleXML","hash":{},"data":data}) : helper)))
+    + "</code></pre>\n      ";
+  stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isParam : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "\n    </div>\n";
+},"7":function(depth0,helpers,partials,data) {
+  var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
+  return "    "
+    + escapeExpression(((helper = (helper = helpers.signature || (depth0 != null ? depth0.signature : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"signature","hash":{},"data":data}) : helper)))
+    + "\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helperMissing=helpers.helperMissing;
+  stack1 = ((helpers.ifCond || (depth0 && depth0.ifCond) || helperMissing).call(depth0, (depth0 != null ? depth0.sampleJSON : depth0), "||", (depth0 != null ? depth0.sampleXML : depth0), {"name":"ifCond","hash":{},"fn":this.program(1, data),"inverse":this.program(7, data),"data":data}));
+  if (stack1 != null) { return stack1; }
+  else { return ''; }
+  },"useData":true});
+this["Handlebars"]["templates"]["status_code"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
+  var lambda=this.lambda, escapeExpression=this.escapeExpression;
+  return "      <tr>\n        <td>"
+    + escapeExpression(lambda((data && data.key), depth0))
+    + "</td>\n        <td>"
+    + escapeExpression(lambda((depth0 != null ? depth0.description : depth0), depth0))
+    + "</td>\n        <td>"
+    + escapeExpression(lambda((depth0 != null ? depth0.type : depth0), depth0))
+    + "</td>\n      </tr>\n";
+},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
+  var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<td width='15%' class='code'>"
+    + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper)))
+    + "</td>\n<td class=\"markdown\">";
+  stack1 = ((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"message","hash":{},"data":data}) : helper));
+  if (stack1 != null) { buffer += stack1; }
+  buffer += "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n  <table>\n    <tbody>\n";
+  stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + "    </tbody>\n  </table>\n</td>";
+},"useData":true});
+/**
+ * swagger-client - swagger-client is a javascript client for use with swaggering APIs.
+ * @version v2.1.14
+ * @link http://swagger.io
+ * @license Apache-2.0
+ */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SwaggerClient = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+'use strict';
+
+var auth = require('./lib/auth');
+var helpers = require('./lib/helpers');
+var SwaggerClient = require('./lib/client');
+var deprecationWrapper = function (url, options) {
+  helpers.log('This is deprecated, use "new SwaggerClient" instead.');
+
+  return new SwaggerClient(url, options);
+};
+
+/* Here for IE8 Support */
+if (!Array.prototype.indexOf) {
+  Array.prototype.indexOf = function(obj, start) {
+    for (var i = (start || 0), j = this.length; i < j; i++) {
+      if (this[i] === obj) { return i; }
+    }
+    return -1;
+  };
+}
+
+/* Here for IE8 Support */
+if (!String.prototype.trim) {
+  String.prototype.trim = function () {
+    return this.replace(/^\s+|\s+$/g, '');
+  };
+}
+
+/* Here for node 10.x support */
+if (!String.prototype.endsWith) {
+  String.prototype.endsWith = function(suffix) {
+    return this.indexOf(suffix, this.length - suffix.length) !== -1;
+  };
+}
+
+module.exports = SwaggerClient;
+
+SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization;
+SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization;
+SwaggerClient.CookieAuthorization = auth.CookieAuthorization;
+SwaggerClient.SwaggerApi = deprecationWrapper;
+SwaggerClient.SwaggerClient = deprecationWrapper;
+SwaggerClient.SchemaMarkup = require('./lib/schema-markup');
+
+},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){
+'use strict';
+
+var helpers = require('./helpers');
+var btoa = require('btoa'); // jshint ignore:line
+var CookieJar = require('cookiejar').CookieJar;
+var _ = {
+  each: require('lodash-compat/collection/each'),
+  includes: require('lodash-compat/collection/includes'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isArray: require('lodash-compat/lang/isArray')
+};
+
+/**
+ * SwaggerAuthorizations applys the correct authorization to an operation being executed
+ */
+var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) {
+  this.authz = authz || {};
+};
+
+/**
+ * Add auths to the hash
+ * Will overwrite any existing
+ *
+ */
+SwaggerAuthorizations.prototype.add = function (name, auth) {
+  if(_.isObject(name)) {
+    for (var key in name) {
+      this.authz[key] = name[key];
+    }
+  } else if(typeof name === 'string' ){
+    this.authz[name] = auth;
+  }
+
+  return auth;
+};
+
+SwaggerAuthorizations.prototype.remove = function (name) {
+  return delete this.authz[name];
+};
+
+SwaggerAuthorizations.prototype.apply = function (obj, securities) {
+  var status = true;
+  var applyAll = !securities;
+  var flattenedSecurities = [];
+
+  // favor the object-level authorizations over global
+  var authz = obj.clientAuthorizations || this.authz;
+
+  // Securities could be [ {} ]
+  _.each(securities, function (obj, key) {
+
+    // Make sure we account for securities being [ str ]
+    if(typeof key === 'string') {
+      flattenedSecurities.push(key);
+    }
+
+    // Flatten keys in to our array
+    _.each(obj, function (val, key) {
+      flattenedSecurities.push(key);
+    });
+  });
+
+  _.each(authz, function (auth, authName) {
+    if(applyAll || _.includes(flattenedSecurities, authName)) {
+      var newStatus = auth.apply(obj);
+      status = status && !!newStatus; // logical ORs regarding status
+    }
+  });
+
+  return status;
+};
+
+/**
+ * ApiKeyAuthorization allows a query param or header to be injected
+ */
+var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) {
+  this.name = name;
+  this.value = value;
+  this.type = type;
+};
+
+ApiKeyAuthorization.prototype.apply = function (obj) {
+  if (this.type === 'query') {
+    // see if already applied.  If so, don't do it again
+
+    var qp;
+    if (obj.url.indexOf('?') > 0) {
+      qp = obj.url.substring(obj.url.indexOf('?') + 1);
+      var parts = qp.split('&');
+      if(parts && parts.length > 0) {
+        for(var i = 0; i < parts.length; i++) {
+          var kv = parts[i].split('=');
+          if(kv && kv.length > 0) {
+            if (kv[0] === this.name) {
+              // skip it
+              return false;
+            }
+          }
+        }
+      }
+    }
+
+    if (obj.url.indexOf('?') > 0) {
+      obj.url = obj.url + '&' + this.name + '=' + this.value;
+    } else {
+      obj.url = obj.url + '?' + this.name + '=' + this.value;
+    }
+
+    return true;
+  } else if (this.type === 'header') {
+    if(typeof obj.headers[this.name] === 'undefined') {
+      obj.headers[this.name] = this.value;
+    }
+
+    return true;
+  }
+};
+
+var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) {
+  this.cookie = cookie;
+};
+
+CookieAuthorization.prototype.apply = function (obj) {
+  obj.cookieJar = obj.cookieJar || new CookieJar();
+  obj.cookieJar.setCookie(this.cookie);
+
+  return true;
+};
+
+/**
+ * Password Authorization is a basic auth implementation
+ */
+var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) {
+  if (arguments.length === 3) {
+    helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password');
+    username = arguments[1];
+    password = arguments[2];
+  }
+  this.username = username;
+  this.password = password;
+};
+
+PasswordAuthorization.prototype.apply = function (obj) {
+  if(typeof obj.headers.Authorization === 'undefined') {
+    obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password);
+  }
+
+  return true;
+};
+
+},{"./helpers":4,"btoa":14,"cookiejar":20,"lodash-compat/collection/each":54,"lodash-compat/collection/includes":57,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],3:[function(require,module,exports){
+'use strict';
+
+var _ = {
+  bind: require('lodash-compat/function/bind'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  find: require('lodash-compat/collection/find'),
+  forEach: require('lodash-compat/collection/forEach'),
+  indexOf: require('lodash-compat/array/indexOf'),
+  isArray: require('lodash-compat/lang/isArray'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isFunction: require('lodash-compat/lang/isFunction'),
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isUndefined: require('lodash-compat/lang/isUndefined')
+};
+var auth = require('./auth');
+var helpers = require('./helpers');
+var Model = require('./types/model');
+var Operation = require('./types/operation');
+var OperationGroup = require('./types/operationGroup');
+var Resolver = require('./resolver');
+var SwaggerHttp = require('./http');
+var SwaggerSpecConverter = require('./spec-converter');
+var Q = require('q');
+
+// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
+// following usage: 'client.{tagName}'
+var reservedClientTags = [
+  'apis',
+  'authorizationScheme',
+  'authorizations',
+  'basePath',
+  'build',
+  'buildFrom1_1Spec',
+  'buildFrom1_2Spec',
+  'buildFromSpec',
+  'clientAuthorizations',
+  'convertInfo',
+  'debug',
+  'defaultErrorCallback',
+  'defaultSuccessCallback',
+  'enableCookies',
+  'fail',
+  'failure',
+  'finish',
+  'help',
+  'host',
+  'idFromOp',
+  'info',
+  'initialize',
+  'isBuilt',
+  'isValid',
+  'modelPropertyMacro',
+  'models',
+  'modelsArray',
+  'options',
+  'parameterMacro',
+  'parseUri',
+  'progress',
+  'resourceCount',
+  'sampleModels',
+  'selfReflect',
+  'setConsolidatedModels',
+  'spec',
+  'supportedSubmitMethods',
+  'swaggerRequestHeaders',
+  'tagFromLabel',
+  'title',
+  'url',
+  'useJQuery'
+];
+// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
+// following usage: 'client.apis.{tagName}'
+var reservedApiTags = [
+  'apis',
+  'asCurl',
+  'description',
+  'externalDocs',
+  'help',
+  'label',
+  'name',
+  'operation',
+  'operations',
+  'operationsArray',
+  'path',
+  'tag'
+];
+var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];
+var SwaggerClient = module.exports = function (url, options) {
+  this.authorizations = null;
+  this.authorizationScheme = null;
+  this.basePath = null;
+  this.debug = false;
+  this.enableCookies = false;
+  this.info = null;
+  this.isBuilt = false;
+  this.isValid = false;
+  this.modelsArray = [];
+  this.resourceCount = 0;
+  this.url = null;
+  this.useJQuery = false;
+  this.swaggerObject = {};
+  this.deferredClient = undefined;
+
+  this.clientAuthorizations = new auth.SwaggerAuthorizations();
+
+  if (typeof url !== 'undefined') {
+    return this.initialize(url, options);
+  } else {
+    return this;
+  }
+};
+
+SwaggerClient.prototype.initialize = function (url, options) {
+  this.models = {};
+  this.sampleModels = {};
+
+  if (typeof url === 'string') {
+    this.url = url;
+  } else if (_.isObject(url)) {
+    options = url;
+    this.url = options.url;
+  }
+
+  options = options || {};
+  this.clientAuthorizations.add(options.authorizations);
+  this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*';
+  this.defaultSuccessCallback = options.defaultSuccessCallback || null;
+  this.defaultErrorCallback = options.defaultErrorCallback || null;
+  this.modelPropertyMacro = options.modelPropertyMacro || null;
+  this.parameterMacro = options.parameterMacro || null;
+  this.usePromise = options.usePromise || null;
+
+
+  if(this.usePromise) {
+    this.deferredClient = Q.defer();
+  }
+
+  if (typeof options.success === 'function') {
+    this.success = options.success;
+  }
+
+  if (options.useJQuery) {
+    this.useJQuery = options.useJQuery;
+  }
+
+  if (options.enableCookies) {
+    this.enableCookies = options.enableCookies;
+  }
+
+  this.options = options || {};
+
+  this.supportedSubmitMethods = options.supportedSubmitMethods || [];
+  this.failure = options.failure || function (err) { throw err; };
+  this.progress = options.progress || function () {};
+  this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document
+
+  if (options.scheme) {
+    this.scheme = options.scheme;
+  }
+
+  if (this.usePromise || typeof options.success === 'function') {
+    this.ready = true;
+    return this.build();
+  }
+};
+
+SwaggerClient.prototype.build = function (mock) {
+  if (this.isBuilt) {
+    return this;
+  }
+
+  var self = this;
+
+  this.progress('fetching resource list: ' + this.url + '; Please wait.');
+
+  var obj = {
+    useJQuery: this.useJQuery,
+    url: this.url,
+    method: 'get',
+    headers: {
+      accept: this.swaggerRequestHeaders
+    },
+    on: {
+      error: function (response) {
+        if (self.url.substring(0, 4) !== 'http') {
+          return self.fail('Please specify the protocol for ' + self.url);
+        } else if (response.status === 0) {
+          return self.fail('Can\'t read from server.  It may not have the appropriate access-control-origin settings.');
+        } else if (response.status === 404) {
+          return self.fail('Can\'t read swagger JSON from ' + self.url);
+        } else {
+          return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);
+        }
+      },
+      response: function (resp) {
+
+        var responseObj = resp.obj;
+        if(!responseObj) {
+          return self.fail('failed to parse JSON/YAML response');
+        }
+
+        self.swaggerVersion = responseObj.swaggerVersion;
+        self.swaggerObject = responseObj;
+
+        if (responseObj.swagger && parseInt(responseObj.swagger) === 2) {
+          self.swaggerVersion = responseObj.swagger;
+
+          new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self);
+
+          self.isValid = true;
+        } else {
+          var converter = new SwaggerSpecConverter();
+          self.oldSwaggerObject = self.swaggerObject;
+
+          converter.setDocumentationLocation(self.url);
+          converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) {
+            self.swaggerObject = spec;
+            new Resolver().resolve(spec, self.url, self.buildFromSpec, self);
+            self.isValid = true;
+          });
+        }
+      }
+    }
+  };
+
+  if (this.spec) {
+    self.swaggerObject = this.spec;
+    setTimeout(function () {
+      new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self);
+    }, 10);
+  } else {
+    this.clientAuthorizations.apply(obj);
+
+    if (mock) {
+      return obj;
+    }
+
+    new SwaggerHttp().execute(obj, this.options);
+  }
+
+  return (this.usePromise) ? this.deferredClient.promise : this;
+};
+
+SwaggerClient.prototype.buildFromSpec = function (response) {
+  if (this.isBuilt) {
+    return this;
+  }
+
+  this.apis = {};
+  this.apisArray = [];
+  this.basePath = response.basePath || '';
+  this.consumes = response.consumes;
+  this.host = response.host || '';
+  this.info = response.info || {};
+  this.produces = response.produces;
+  this.schemes = response.schemes || [];
+  this.securityDefinitions = response.securityDefinitions;
+  this.security = response.security;
+  this.title = response.title || '';
+
+  if (response.externalDocs) {
+    this.externalDocs = response.externalDocs;
+  }
+
+  // legacy support
+  this.authSchemes = response.securityDefinitions;
+
+  var definedTags = {};
+  var k;
+
+  if (Array.isArray(response.tags)) {
+    definedTags = {};
+
+    for (k = 0; k < response.tags.length; k++) {
+      var t = response.tags[k];
+      definedTags[t.name] = t;
+    }
+  }
+
+  var location;
+
+  if (typeof this.url === 'string') {
+    location = this.parseUri(this.url);
+    if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {
+      this.scheme = location.scheme || 'http';
+    } else if (typeof this.scheme === 'undefined') {
+      this.scheme = this.schemes[0] || location.scheme;
+    }
+
+    if (typeof this.host === 'undefined' || this.host === '') {
+      this.host = location.host;
+
+      if (location.port) {
+        this.host = this.host + ':' + location.port;
+      }
+    }
+  }
+  else {
+    if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
+      this.scheme = 'http';
+    }
+    else if (typeof this.scheme === 'undefined') {
+      this.scheme = this.schemes[0];
+    }
+  }
+
+  this.definitions = response.definitions;
+
+  var key;
+
+  for (key in this.definitions) {
+    var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro);
+
+    if (model) {
+      this.models[key] = model;
+    }
+  }
+
+  // get paths, create functions for each operationId
+  var self = this;
+
+  // Bind help to 'client.apis'
+  self.apis.help = _.bind(self.help, self);
+
+  _.forEach(response.paths, function (pathObj, path) {
+    // Only process a path if it's an object
+    if (!_.isPlainObject(pathObj)) {
+      return;
+    }
+
+    _.forEach(supportedOperationMethods, function (method) {
+      var operation = pathObj[method];
+
+      if (_.isUndefined(operation)) {
+        // Operation does not exist
+        return;
+      } else if (!_.isPlainObject(operation)) {
+        // Operation exists but it is not an Operation Object.  Since this is invalid, log it.
+        helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object');
+
+        return;
+      }
+
+      var tags = operation.tags;
+
+      if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) {
+        tags = operation.tags = [ 'default' ];
+      }
+
+      var operationId = self.idFromOp(path, method, operation);
+
+      var operationObject = new Operation(self,
+        operation.scheme,
+        operationId,
+        method,
+        path,
+        operation,
+        self.definitions,
+        self.models,
+        self.clientAuthorizations);
+
+      // bind self operation's execute command to the api
+      _.forEach(tags, function (tag) {
+        var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag;
+        var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag;
+        var operationGroup = self[clientProperty];
+
+        if (clientProperty !== tag) {
+          helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name.  Use \'client.' +
+                      clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.');
+        }
+
+        if (apiProperty !== tag) {
+          helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name.  Use ' +
+                      '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.');
+        }
+
+        if (_.indexOf(reservedApiTags, operationId) > -1) {
+          helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' +
+                      'function/property name.  Use \'client.apis.' + apiProperty + '._' + operationId +
+                      '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.');
+
+          operationId = '_' + operationId;
+          operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly
+        }
+
+        if (_.isUndefined(operationGroup)) {
+          operationGroup = self[clientProperty] = self.apis[apiProperty] = {};
+
+          operationGroup.operations = {};
+          operationGroup.label = apiProperty;
+          operationGroup.apis = {};
+
+          var tagDef = definedTags[tag];
+
+          if (!_.isUndefined(tagDef)) {
+            operationGroup.description = tagDef.description;
+            operationGroup.externalDocs = tagDef.externalDocs;
+          }
+
+          self[clientProperty].help = _.bind(self.help, operationGroup);
+          self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));
+        }
+
+        operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]);
+
+        // Bind tag help
+        if (!_.isFunction(operationGroup.help)) {
+          operationGroup.help = _.bind(self.help, operationGroup);
+        }
+
+        // bind to the apis object
+        self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute,
+                                                                                  operationObject);
+        self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help,
+                                                                                             operationObject);
+        self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl,
+                                                                                                 operationObject);
+
+        operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject;
+
+        // legacy UI feature
+        var api = _.find(self.apisArray, function (api) {
+          return api.tag === tag;
+        });
+
+        if (api) {
+          api.operationsArray.push(operationObject);
+        }
+      });
+    });
+  });
+
+  // sort the apisArray according to the tags
+  var sortedApis = [];
+  _.forEach(Object.keys(definedTags), function (tag) {
+    var _apiToAdd;
+    var pos;
+    for(pos in self.apisArray) {
+      var _api = self.apisArray[pos];
+      if(_api && tag === _api.name) {
+        sortedApis.push(_api);
+        self.apisArray[pos] = null;
+      }
+    }
+  });
+  // add anything left
+  _.forEach(self.apisArray, function (api) {
+    if(api) {
+      sortedApis.push(api);
+    }
+  });
+  self.apisArray = sortedApis;
+
+  _.forEach(response.definitions, function (definitionObj, definition) {
+    definitionObj['id'] = definition.toLowerCase();
+    definitionObj['name'] = definition;
+    self.modelsArray.push(definitionObj);
+  });
+
+  this.isBuilt = true;
+
+  if (this.usePromise) {
+    this.isValid = true;
+    this.isBuilt = true;
+    this.deferredClient.resolve(this);
+
+    return this.deferredClient.promise;
+  }
+
+  if (this.success) {
+    this.success();
+  }
+
+  return this;
+};
+
+SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) {
+  var count = 0;
+  var name = operationId;
+
+  // make unique across this operation group
+  while(true) {
+    var matched = false;
+    _.forEach(api.operations, function (operation) {
+      if(operation.nickname === name) {
+        matched = true;
+      }
+    });
+    if(!matched) {
+      return name;
+    }
+    name = operationId + '_' + count;
+    count ++;
+  }
+
+  return operationId;
+};
+
+SwaggerClient.prototype.parseUri = function (uri) {
+  var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;
+  var parts = urlParseRE.exec(uri);
+
+  return {
+    scheme: parts[4] ? parts[4].replace(':','') : undefined,
+    host: parts[11],
+    port: parts[12],
+    path: parts[15]
+  };
+};
+
+SwaggerClient.prototype.help = function (dontPrint) {
+  var output = '';
+
+  if (this instanceof SwaggerClient) {
+    _.forEach(this.apis, function (api, name) {
+      if (_.isPlainObject(api)) {
+        output += 'operations for the \'' + name + '\' tag\n';
+
+        _.forEach(api.operations, function (operation, name) {
+          output += '  * ' + name + ': ' + operation.summary + '\n';
+        });
+      }
+    });
+  } else if (this instanceof OperationGroup || _.isPlainObject(this)) {
+    output += 'operations for the \'' + this.label + '\' tag\n';
+
+    _.forEach(this.apis, function (operation, name) {
+      output += '  * ' + name + ': ' + operation.summary + '\n';
+    });
+  }
+
+  if (dontPrint) {
+    return output;
+  } else {
+    helpers.log(output);
+
+    return output;
+  }
+};
+
+SwaggerClient.prototype.tagFromLabel = function (label) {
+  return label;
+};
+
+SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) {
+  if(!op || !op.operationId) {
+    op = op || {};
+    op.operationId = httpMethod + '_' + path;
+  }
+  var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod);
+
+  opId = opId.replace(/((_){2,})/g, '_');
+  opId = opId.replace(/^(_)*/g, '');
+  opId = opId.replace(/([_])*$/g, '');
+
+  return opId;
+};
+
+SwaggerClient.prototype.setHost = function (host) {
+  this.host = host;
+
+  if(this.apis) {
+    _.forEach(this.apis, function(api) {
+      if(api.operations) {
+        _.forEach(api.operations, function(operation) {
+          operation.host = host;
+        });
+      }
+    });
+  }
+};
+
+SwaggerClient.prototype.setBasePath = function (basePath) {
+  this.basePath = basePath;
+
+  if(this.apis) {
+    _.forEach(this.apis, function(api) {
+      if(api.operations) {
+        _.forEach(api.operations, function(operation) {
+          operation.basePath = basePath;
+        });
+      }
+    });
+  }
+};
+
+SwaggerClient.prototype.setSchemes = function (schemes) {
+  this.schemes = schemes;
+
+  if(schemes && schemes.length > 0) {
+    if(this.apis) {
+      _.forEach(this.apis, function (api) {
+        if (api.operations) {
+          _.forEach(api.operations, function (operation) {
+            operation.scheme = schemes[0];
+          });
+        }
+      });
+    }
+  }
+};
+
+
+SwaggerClient.prototype.fail = function (message) {
+  if (this.usePromise) {
+    this.deferredClient.reject(message);
+    return this.deferredClient.promise;
+  } else {
+    if (this.failure) {
+      this.failure(message);
+    }
+    else {
+      this.failure(message);
+    }
+  }
+};
+
+},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":51,"lodash-compat/collection/find":55,"lodash-compat/collection/forEach":56,"lodash-compat/function/bind":60,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isFunction":144,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,"q":159}],4:[function(require,module,exports){
+(function (process){
+'use strict';
+
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  indexOf: require('lodash-compat/array/indexOf')
+};
+
+module.exports.__bind = function (fn, me) {
+  return function(){
+    return fn.apply(me, arguments);
+  };
+};
+
+var log = module.exports.log = function() {
+  // Only log if available and we're not testing
+  if (console && process.env.NODE_ENV !== 'test') {
+    console.log(Array.prototype.slice.call(arguments)[0]);
+  }
+};
+
+module.exports.fail = function (message) {
+  log(message);
+};
+
+var optionHtml = module.exports.optionHtml = function (label, value) {
+  return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+};
+
+var resolveSchema = module.exports.resolveSchema = function (schema) {
+  if (_.isPlainObject(schema.schema)) {
+    schema = resolveSchema(schema.schema);
+  }
+
+  return schema;
+};
+
+var simpleRef = module.exports.simpleRef = function (name) {
+  if (typeof name === 'undefined') {
+    return null;
+  }
+
+  if (name.indexOf('#/definitions/') === 0) {
+    return name.substring('#/definitions/'.length);
+  } else {
+    return name;
+  }
+};
+
+
+}).call(this,require('_process'))
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9oZWxwZXJzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxudmFyIHJlc29sdmVTY2hlbWEgPSBtb2R1bGUuZXhwb3J0cy5yZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEuc2NoZW1hKTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbiJdfQ==
+},{"_process":13,"lodash-compat/array/indexOf":51,"lodash-compat/lang/isPlainObject":147}],5:[function(require,module,exports){
+'use strict';
+
+var helpers = require('./helpers');
+var request = require('superagent');
+var jsyaml = require('js-yaml');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject')
+};
+
+/*
+ * JQueryHttpClient is a light-weight, node or browser HTTP client
+ */
+var JQueryHttpClient = function () {
+  this.type = 'JQueryHttpClient';
+};
+
+/*
+ * SuperagentHttpClient is a light-weight, node or browser HTTP client
+ */
+var SuperagentHttpClient = function () {
+  this.type = 'SuperagentHttpClient';
+};
+
+/**
+ * SwaggerHttp is a wrapper for executing requests
+ */
+var SwaggerHttp = module.exports = function () {};
+
+SwaggerHttp.prototype.execute = function (obj, opts) {
+  var client;
+
+  if(opts && opts.client) {
+    client = opts.client;
+  }
+  else {
+    client = new SuperagentHttpClient(opts);
+  }
+  client.opts = opts || {};
+
+  // legacy support
+  var hasJQuery = false;
+  if(typeof window !== 'undefined') {
+    if(typeof window.jQuery !== 'undefined') {
+      hasJQuery = true;
+    }
+  }
+  // OPTIONS support
+  if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') {
+    log('forcing jQuery as OPTIONS are not supported by SuperAgent');
+    obj.useJQuery = true;
+  }
+  if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) {
+    throw new Error('Unsupported configuration! JQuery is required but not available');
+  }
+  if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) {
+    client = new JQueryHttpClient(opts);
+  }
+
+  var success = obj.on.response;
+
+  var requestInterceptor = function(data) {
+    if(opts && opts.requestInterceptor) {
+      data = opts.requestInterceptor.apply(data);
+    }
+    return data;
+  };
+
+  var responseInterceptor = function(data) {
+    if(opts && opts.responseInterceptor) {
+      data = opts.responseInterceptor.apply(data);
+    }
+    return success(data);
+  };
+
+  obj.on.response = function(data) {
+    responseInterceptor(data);
+  };
+
+  if (_.isObject(obj) && _.isObject(obj.body)) {
+    // special processing for file uploads via jquery
+    if (obj.body.type && obj.body.type === 'formData'){
+      obj.contentType = false;
+      obj.processData = false;
+
+      delete obj.headers['Content-Type'];
+    } else {
+      obj.body = JSON.stringify(obj.body);
+    }
+  }
+
+  obj = requestInterceptor(obj) || obj;
+  if (obj.beforeSend) {
+    obj.beforeSend(function(_obj) {
+      client.execute(_obj || obj);
+    });
+  } else {
+    client.execute(obj);
+  }
+
+  return (obj.deferred) ? obj.deferred.promise : obj;
+};
+
+SwaggerHttp.prototype.isInternetExplorer = function () {
+  var detectedIE = false;
+
+  if (typeof navigator !== 'undefined' && navigator.userAgent) {
+    var nav = navigator.userAgent.toLowerCase();
+
+    if (nav.indexOf('msie') !== -1) {
+      var version = parseInt(nav.split('msie')[1]);
+
+      if (version <= 8) {
+        detectedIE = true;
+      }
+    }
+  }
+
+  return detectedIE;
+};
+
+JQueryHttpClient.prototype.execute = function (obj) {
+  var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery);
+  var cb = obj.on;
+  var request = obj;
+
+  if(typeof jq === 'undefined' || jq === false) {
+    throw new Error('Unsupported configuration! JQuery is required but not available');
+  }
+
+  obj.type = obj.method;
+  obj.cache = false;
+  obj.data = obj.body;
+  delete obj.useJQuery;
+  delete obj.body;
+
+  obj.complete = function (response) {
+    var headers = {};
+    var headerArray = response.getAllResponseHeaders().split('\n');
+
+    for (var i = 0; i < headerArray.length; i++) {
+      var toSplit = headerArray[i].trim();
+
+      if (toSplit.length === 0) {
+        continue;
+      }
+
+      var separator = toSplit.indexOf(':');
+
+      if (separator === -1) {
+        // Name but no value in the header
+        headers[toSplit] = null;
+
+        continue;
+      }
+
+      var name = toSplit.substring(0, separator).trim();
+      var value = toSplit.substring(separator + 1).trim();
+
+      headers[name] = value;
+    }
+
+    var out = {
+      url: request.url,
+      method: request.method,
+      status: response.status,
+      statusText: response.statusText,
+      data: response.responseText,
+      headers: headers
+    };
+
+    try {
+      var possibleObj =  response.responseJSON || jsyaml.safeLoad(response.responseText);
+      out.obj = (typeof possibleObj === 'string') ? {} : possibleObj;
+    } catch (ex) {
+      // do not set out.obj
+      helpers.log('unable to parse JSON/YAML content');
+    }
+
+    // I can throw, or parse null?
+    out.obj = out.obj || null;
+
+    if (response.status >= 200 && response.status < 300) {
+      cb.response(out);
+    } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) {
+      cb.error(out);
+    } else {
+      return cb.response(out);
+    }
+  };
+
+  jq.support.cors = true;
+
+  return jq.ajax(obj);
+};
+
+SuperagentHttpClient.prototype.execute = function (obj) {
+  var method = obj.method.toLowerCase();
+
+  if (method === 'delete') {
+    method = 'del';
+  }
+  var headers = obj.headers || {};
+  var r = request[method](obj.url);
+  var name;
+  for (name in headers) {
+    r.set(name, headers[name]);
+  }
+
+  if (obj.enableCookies) {
+    r.withCredentials();
+  }
+
+  if (obj.body) {
+    r.send(obj.body);
+  }
+
+  if(typeof r.buffer === 'function') {
+    r.buffer(); // force superagent to populate res.text with the raw response data
+  }
+
+  r.end(function (err, res) {
+    res = res || {
+      status: 0,
+      headers: {error: 'no response from server'}
+    };
+    var response = {
+      url: obj.url,
+      method: obj.method,
+      headers: res.headers
+    };
+    var cb;
+
+    if (!err && res.error) {
+      err = res.error;
+    }
+
+    if (err && obj.on && obj.on.error) {
+      response.errObj = err;
+      response.status = res ? res.status : 500;
+      response.statusText = res ? res.text : err.message;
+      if(res.headers && res.headers['content-type']) {
+        if(res.headers['content-type'].indexOf('application/json') >= 0) {
+          try {
+            response.obj = JSON.parse(response.statusText);
+          }
+          catch (e) {
+            response.obj = null;
+          }
+        }
+      }
+      cb = obj.on.error;
+    } else if (res && obj.on && obj.on.response) {
+      var possibleObj;
+
+      // Already parsed by by superagent?
+      if(res.body && Object.keys(res.body).length > 0) {
+        possibleObj = res.body;
+      } else {
+          try {
+            possibleObj = jsyaml.safeLoad(res.text);
+            // can parse into a string... which we don't need running around in the system
+            possibleObj = (typeof possibleObj === 'string') ? null : possibleObj;
+          } catch(e) {
+            helpers.log('cannot parse JSON/YAML content');
+          }
+      }
+
+      // null means we can't parse into object
+      response.obj = (typeof possibleObj === 'object') ? possibleObj : null;
+
+      response.status = res.status;
+      response.statusText = res.text;
+      cb = obj.on.response;
+    }
+    response.data = response.statusText;
+
+    if (cb) {
+      cb(response);
+    }
+  });
+};
+
+},{"./helpers":4,"js-yaml":21,"lodash-compat/lang/isObject":146,"superagent":161}],6:[function(require,module,exports){
+'use strict';
+
+var SwaggerHttp = require('./http');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  isArray: require('lodash-compat/lang/isArray')
+};
+
+
+/**
+ * Resolves a spec's remote references
+ */
+var Resolver = module.exports = function () {
+  this.failedUrls = [];
+};
+
+Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) {
+  var i, location, property;
+
+  definition['x-resolved-from'] = [ '#/definitions/' + name ];
+  var allOf = definition.allOf;
+  // the refs go first
+  allOf.sort(function(a, b) {
+    if(a.$ref && b.$ref) { return 0; }
+    else if(a.$ref) { return -1; }
+    else { return 1; }
+  });
+  for (i = 0; i < allOf.length; i++) {
+    property = allOf[i];
+    location = '/definitions/' + name + '/allOf';
+    this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location);
+  }
+};
+
+Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
+  this.spec = spec;
+  var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i;
+  if(typeof arg1 === 'function') {
+    root = null;
+    callback = arg1;
+    scope = arg2;
+  }
+  var _root = root;
+  this.scope = (scope || this);
+  this.iteration = this.iteration || 0;
+
+  if(this.scope.options && this.scope.options.requestInterceptor){
+    opts.requestInterceptor = this.scope.options.requestInterceptor;
+  }
+
+  if(this.scope.options && this.scope.options.responseInterceptor){
+    opts.responseInterceptor = this.scope.options.responseInterceptor;
+  }
+
+  var name, path, property, propertyName;
+  var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};
+  var resolutionTable = []; // store objects for dereferencing
+
+  spec.definitions = spec.definitions || {};
+  // definitions
+  for (name in spec.definitions) {
+    var definition = spec.definitions[name];
+    if(definition['$ref']) {
+      this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition);
+    }
+    else {
+      for (propertyName in definition.properties) {
+        property = definition.properties[propertyName];
+        if (_.isArray(property.allOf)) {
+          this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec);
+        }
+        else {
+          this.resolveTo(root, property, resolutionTable, '/definitions');
+        }
+      }
+
+      if (definition.allOf) {
+        this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec);
+      }
+    }
+  }
+
+  // shared parameters
+  spec.parameters = spec.parameters || {};
+  for(name in spec.parameters) {
+    var parameter = spec.parameters[name];
+    if (parameter.in === 'body' && parameter.schema) {
+      if(_.isArray(parameter.schema.allOf)) {
+        // move to a definition
+        var modelName = 'inline_model';
+        var name = modelName;
+        var done = false; var counter = 0;
+        while(!done) {
+          if(typeof spec.definitions[name] === 'undefined') {
+            done = true;
+            break;
+          }
+          name = modelName + '_' + counter;
+          counter ++;
+        }
+        spec.definitions[name] = { allOf: parameter.schema.allOf };
+        delete parameter.schema.allOf;
+        parameter.schema.$ref = '#/definitions/' + name;
+        this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
+      }
+      else {
+        this.resolveTo(root, parameter.schema, resolutionTable, location);
+      }
+    }
+
+    if (parameter.$ref) {
+      // parameter reference
+      this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
+    }
+  }
+
+  // operations
+  for (name in spec.paths) {
+    var method, operation, responseCode;
+    path = spec.paths[name];
+
+    for (method in path) {
+      // operation reference
+      if(method === '$ref') {
+        // location = path[method];
+        location = '/paths' + name;
+        this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location);
+      }
+      else {
+        operation = path[method];
+        var sharedParameters = path.parameters || [];
+        var parameters = operation.parameters || [];
+
+        for (i in sharedParameters) {
+          var parameter = sharedParameters[i];
+          parameters.unshift(parameter);
+        }
+        if(method !== 'parameters' && _.isObject(operation)) {
+          operation.parameters = operation.parameters || parameters;
+        }
+
+        for (i in parameters) {
+          var parameter = parameters[i];
+          location = '/paths' + name + '/' + method + '/parameters';
+
+          if (parameter.in === 'body' && parameter.schema) {
+            if(_.isArray(parameter.schema.allOf)) {
+              // move to a definition
+              var modelName = 'inline_model';
+              var name = modelName;
+              var done = false; var counter = 0;
+              while(!done) {
+                if(typeof spec.definitions[name] === 'undefined') {
+                  done = true;
+                  break;
+                }
+                name = modelName + '_' + counter;
+                counter ++;
+              }
+              spec.definitions[name] = { allOf: parameter.schema.allOf };
+              delete parameter.schema.allOf;
+              parameter.schema.$ref = '#/definitions/' + name;
+              this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
+            }
+            else {
+              this.resolveTo(root, parameter.schema, resolutionTable, location);
+            }
+          }
+
+          if (parameter.$ref) {
+            // parameter reference
+            this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
+          }
+        }
+
+        for (responseCode in operation.responses) {
+          var response = operation.responses[responseCode];
+          location = '/paths' + name + '/' + method + '/responses/' + responseCode;
+
+          if(_.isObject(response)) {
+            if(response.$ref) {
+              // response reference
+              this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location);
+            }
+            if (response.schema) {
+              var responseObj = response;
+              if(_.isArray(responseObj.schema.allOf)) {
+                // move to a definition
+                var modelName = 'inline_model';
+                var name = modelName;
+                var done = false; var counter = 0;
+                while(!done) {
+                  if(typeof spec.definitions[name] === 'undefined') {
+                    done = true;
+                    break;
+                  }
+                  name = modelName + '_' + counter;
+                  counter ++;
+                }
+                spec.definitions[name] = { allOf: responseObj.schema.allOf };
+                delete responseObj.schema.allOf;
+                delete responseObj.schema.type;
+                responseObj.schema.$ref = '#/definitions/' + name;
+                this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
+              }
+              else if('array' === responseObj.schema.type) {
+                if(responseObj.schema.items && responseObj.schema.items.$ref) {
+                  // response reference
+                  this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location);
+                }
+              }
+              else {
+                this.resolveTo(root, response.schema, resolutionTable, location);
+              }
+            }
+          }
+        }
+      }
+    }
+    // clear them out to avoid multiple resolutions
+    path.parameters = [];
+  }
+
+  var expectedCalls = 0, toResolve = [];
+  // if the root is same as obj[i].root we can resolve locally
+  var all = resolutionTable;
+
+  var parts;
+  for(i = 0; i < all.length; i++) {
+    var a = all[i];
+    if(root === a.root) {
+      if(a.resolveAs === 'ref') {
+        // resolve any path walking
+        var joined = ((a.root || '') + '/' + a.key).split('/');
+        var normalized = [];
+        var url = '';
+        var k;
+
+        if(a.key.indexOf('../') >= 0) {
+          for(var j = 0; j < joined.length; j++) {
+            if(joined[j] === '..') {
+              normalized = normalized.slice(0, normalized.length-1);
+            }
+            else {
+              normalized.push(joined[j]);
+            }
+          }
+          for(k = 0; k < normalized.length; k ++) {
+            if(k > 0) {
+              url += '/';
+            }
+            url += normalized[k];
+          }
+          // we now have to remote resolve this because the path has changed
+          a.root = url;
+          toResolve.push(a);
+        }
+        else {
+          parts = a.key.split('#');
+          if(parts.length === 2) {
+            if(parts[0].indexOf('http://') === 0 || parts[0].indexOf('https://') === 0) {
+              a.root = parts[0];
+            }
+            location = parts[1].split('/');
+            var r;
+            var s = spec;
+            for(k = 0; k < location.length; k++) {
+              var part = location[k];
+              if(part !== '') {
+                s = s[part];
+                if(typeof s !== 'undefined') {
+                  r = s;
+                }
+                else {
+                  r = null;
+                  break;
+                }
+              }
+            }
+            if(r === null) {
+              // must resolve this too
+              toResolve.push(a);
+            }
+          }
+        }
+      }
+      else {
+        if (a.resolveAs === 'inline') {
+          if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') {
+            // handle relative schema
+            parts = a.root.split('/');
+            location = '';
+            for(i = 0; i < parts.length - 1; i++) {
+              location += parts[i] + '/';
+            }
+            location += a.key;
+            a.root = location;
+            a.location = '';
+          }
+          toResolve.push(a);
+        }
+      }
+    }
+    else {
+      toResolve.push(a);
+    }
+  }
+  expectedCalls = toResolve.length;
+
+  // resolve anything that is local
+  for(var ii = 0; ii < toResolve.length; ii++) {
+    (function(item, spec, self) {
+      // NOTE: this used to be item.root === null, but I (@ponelat) have added a guard against .split, which means item.root can be ''
+      if(!item.root || item.root === root) {
+        // local resolve
+        self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item);
+        processedCalls += 1;
+
+        if(processedCalls === expectedCalls) {
+          self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true);
+        }
+      }
+      else if(self.failedUrls.indexOf(item.root) === -1) {
+        var obj = {
+          useJQuery: false,  // TODO
+          url: item.root,
+          method: 'get',
+          headers: {
+            accept: self.scope.swaggerRequestHeaders || 'application/json'
+          },
+          on: {
+            error: function (error) {
+              processedCalls += 1;
+              console.log('failed url: ' + obj.url);
+              self.failedUrls.push(obj.url);
+              unresolvedRefs[item.key] = {
+                root: item.root,
+                location: item.location
+              };
+
+              if (processedCalls === expectedCalls) {
+                self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+              }
+            },  // jshint ignore:line
+            response: function (response) {
+              var swagger = response.obj;
+              self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item);
+              processedCalls += 1;
+
+              if (processedCalls === expectedCalls) {
+                self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+              }
+            }
+          } // jshint ignore:line
+        };
+
+        if (scope && scope.clientAuthorizations) {
+          scope.clientAuthorizations.apply(obj);
+        }
+
+        new SwaggerHttp().execute(obj, opts);
+      }
+      else {
+        processedCalls += 1;
+        unresolvedRefs[item.key] = {
+          root: item.root,
+          location: item.location
+        };
+        if (processedCalls === expectedCalls) {
+          self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+        }
+      }
+    }(toResolve[ii], spec, this));
+  }
+
+  if (Object.keys(toResolve).length === 0) {
+    this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+  }
+};
+
+Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) {
+  var path = item.location;
+  var location = spec, parts = path.split('/');
+  if(path !== '') {
+    for (var j = 0; j < parts.length; j++) {
+      var segment = parts[j];
+      if (segment.indexOf('~1') !== -1) {
+        segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/');
+        if (segment.charAt(0) !== '/') {
+          segment = '/' + segment;
+        }
+      }
+      if (typeof location === 'undefined' || location === null) {
+        break;
+      }
+      if (segment === '' && j === (parts.length - 1) && parts.length > 1) {
+        location = null;
+        break;
+      }
+      if (segment.length > 0) {
+        location = location[segment];
+      }
+    }
+  }
+  var resolved = item.key;
+  parts = item.key.split('/');
+  var resolvedName = parts[parts.length-1];
+
+  if(resolvedName.indexOf('#') >= 0) {
+    resolvedName = resolvedName.split('#')[1];
+  }
+
+  if (location !== null && typeof location !== 'undefined') {
+    resolvedRefs[resolved] = {
+      name: resolvedName,
+      obj: location,
+      key: item.key,
+      root: item.root
+    };
+  } else {
+    unresolvedRefs[resolved] = {
+      root: item.root,
+      location: item.location
+    };
+  }
+};
+
+Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) {
+  // walk resolution table and replace with resolved refs
+  var ref;
+  for (ref in resolutionTable) {
+    var item = resolutionTable[ref];
+
+    var key = item.key;
+    var resolvedTo = resolvedRefs[key];
+    if (resolvedTo) {
+      spec.definitions = spec.definitions || {};
+      if (item.resolveAs === 'ref') {
+        if (localResolve !== true) {
+          // don't retain root for local definitions
+          for (key in resolvedTo.obj) {
+            var abs = this.retainRoot(resolvedTo.obj[key], item.root);
+          }
+        }
+        spec.definitions[resolvedTo.name] = resolvedTo.obj;
+        item.obj.$ref = '#/definitions/' + resolvedTo.name;
+      } else if (item.resolveAs === 'inline') {
+        var targetObj = item.obj;
+        targetObj['x-resolved-from'] = [ item.key ];
+        delete targetObj.$ref;
+
+        for (key in resolvedTo.obj) {
+          var abs = resolvedTo.obj[key];
+          
+          if (localResolve !== true) {
+            // don't retain root for local definitions
+            abs = this.retainRoot(resolvedTo.obj[key], item.root);
+          }
+          targetObj[key] = abs;
+        }
+      }
+    }
+  }
+  var existingUnresolved = this.countUnresolvedRefs(spec);
+
+  if(existingUnresolved === 0 || this.iteration > 5) {
+    this.resolveAllOf(spec.definitions);
+    callback.call(this.scope, spec, unresolvedRefs);
+  }
+  else {
+    this.iteration += 1;
+    this.resolve(spec, root, callback, this.scope);
+  }
+};
+
+Resolver.prototype.countUnresolvedRefs = function(spec) {
+  var i;
+  var refs = this.getRefs(spec);
+  var keys = [];
+  var unresolvedKeys = [];
+  for(i in refs) {
+    if(i.indexOf('#') === 0) {
+      keys.push(i.substring(1));
+    }
+    else {
+      unresolvedKeys.push(i);
+    }
+  }
+
+  // verify possible keys
+  for (i = 0; i < keys.length; i++) {
+    var part = keys[i];
+    var parts = part.split('/');
+    var obj = spec;
+
+    for (var k = 0; k < parts.length; k++) {
+      var key = parts[k];
+      if(key !== '') {
+        obj = obj[key];
+        if(typeof obj === 'undefined') {
+          unresolvedKeys.push(part);
+          break;
+        }
+      }
+    }
+  }
+  return unresolvedKeys.length;
+};
+
+Resolver.prototype.getRefs = function(spec, obj) {
+  obj = obj || spec;
+  var output = {};
+  for(var key in obj) {
+    if (!obj.hasOwnProperty(key)) {
+      continue;
+    }
+    var item = obj[key];
+    if(key === '$ref' && typeof item === 'string') {
+      output[item] = null;
+    }
+    else if(_.isObject(item)) {
+      var o = this.getRefs(item);
+      for(var k in o) {
+        output[k] = null;
+      }
+    }
+  }
+  return output;
+};
+
+Resolver.prototype.retainRoot = function(obj, root) {
+  // walk object and look for relative $refs
+  for(var key in obj) {
+    var item = obj[key];
+    if(key === '$ref' && typeof item === 'string') {
+      // stop and inspect
+      if(item.indexOf('http://') !== 0 && item.indexOf('https://') !== 0) {
+        // TODO: check if root ends in '/'.  If not, AND item has no protocol, make relative
+        var appendHash = true;
+        var oldRoot = root;
+        if(root) {
+          var lastChar = root.slice(-1);
+          if(lastChar !== '/' && (item.indexOf('#') !== 0 && item.indexOf('http://') !== 0 && item.indexOf('https://'))) {
+            console.log('working with ' + item);
+            appendHash = false;
+            var parts = root.split('\/');
+            parts = parts.splice(0, parts.length - 1);
+            root = '';
+            for(var i = 0; i < parts.length; i++) {
+              root += parts[i] + '/';
+            }
+          }
+        }
+        if(item.indexOf('#') !== 0 && appendHash) {
+          item = '#' + item;
+        }
+
+        item = (root || '') + item;
+        obj[key] = item;
+      }
+    }
+    else if(_.isObject(item)) {
+      this.retainRoot(item, root);
+    }
+  }
+  return obj;
+};
+
+/**
+ * immediately in-lines local refs, queues remote refs
+ * for inline resolution
+ */
+Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) {
+  var key = property.$ref, ref = property.$ref, i, p, p2, rs;
+  var rootTrimmed = false;
+
+  root = root || '' // Guard against .split. @fehguy, you'll need to check if this logic fits
+  // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ?
+
+  if (ref) {
+    if(ref.indexOf('../') === 0) {
+      // reset root
+      p = ref.split('../');
+      p2 = root.split('/');
+      ref = '';
+      for(i = 0; i < p.length; i++) {
+        if(p[i] === '') {
+          p2 = p2.slice(0, p2.length-1);
+        }
+        else {
+          ref += p[i];
+        }
+      }
+      root = '';
+      for(i = 0; i < p2.length - 1; i++) {
+        if(i > 0) { root += '/'; }
+        root += p2[i];
+      }
+      rootTrimmed = true;
+    }
+    if(ref.indexOf('#') >= 0) {
+      if(ref.indexOf('/') === 0) {
+        rs = ref.split('#');
+        p  = root.split('//');
+        p2 = p[1].split('/');
+        root = p[0] + '//' + p2[0] + rs[0];
+        location = rs[1];
+      }
+      else {
+        rs = ref.split('#');
+        if(rs[0] !== '') {
+          p2 = root.split('/');
+          p2 = p2.slice(0, p2.length - 1);
+          if(!rootTrimmed) {
+            root = '';
+            for (var k = 0; k < p2.length; k++) {
+              if(k > 0) { root += '/'; }
+              root += p2[k];
+            }
+          }
+          root += '/' + ref.split('#')[0];
+        }
+        location = rs[1];
+      }
+    }
+    if (ref.indexOf('http') === 0) {
+      if(ref.indexOf('#') >= 0) {
+        root = ref.split('#')[0];
+        location = ref.split('#')[1];
+      }
+      else {
+        root = ref;
+        location = '';
+      }
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    } else if (ref.indexOf('#') === 0) {
+      location = ref.split('#')[1];
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) {
+      location = ref;
+      var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
+      if(matches) {
+        root = matches[0] + ref.substring(1);
+        location = '';
+      }
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    }
+    else {
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    }
+  }
+  else if (property.type === 'array') {
+    this.resolveTo(root, property.items, resolutionTable, location);
+  }
+};
+
+Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {
+  var sp, i;
+  var ref = property.$ref;
+  var lroot = root;
+  if ((typeof ref !== 'undefined') && (ref !== null)) {
+    if(ref.indexOf('#') >= 0) {
+      var parts = ref.split('#');
+
+      // #/definitions/foo
+      // foo.json#/bar
+      if(parts[0] && ref.indexOf('/') === 0) {
+
+      }
+      else if(parts[0] && parts[0].indexOf('http') === 0) {
+        lroot = parts[0];
+        ref = parts[1];
+      }
+      else if(parts[0] && parts[0].length > 0) {
+        // relative file
+        sp = root.split('/');
+        lroot = '';
+        for(i = 0; i < sp.length - 1; i++) {
+          lroot += sp[i] + '/';
+        }
+        lroot += parts[0];
+      }
+      else {
+
+      }
+
+      location = parts[1];
+    }
+    else if (ref.indexOf('http://') === 0 || ref.indexOf('https://') === 0) {
+      lroot = ref;
+      location = '';
+    }
+    else {
+      // relative file
+      sp = root.split('/');
+      lroot = '';
+      for(i = 0; i < sp.length - 1; i++) {
+        lroot += sp[i] + '/';
+      }
+      lroot += ref;
+      location = '';
+    }
+    resolutionTable.push({
+      obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location
+    });
+  } else if (property.type === 'array') {
+    var items = property.items;
+    this.resolveTo(root, items, resolutionTable, location);
+  } else {
+    if(property && property.properties) {
+      var name = this.uniqueName('inline_model');
+      if (property.title) {
+        name = this.uniqueName(property.title);
+      }
+      delete property.title;
+      this.spec.definitions[name] = _.cloneDeep(property);
+      property['$ref'] = '#/definitions/' + name;
+      delete property.type;
+      delete property.properties;
+    }
+  }
+};
+
+Resolver.prototype.uniqueName = function(base) {
+  var name = base;
+  var count = 0;
+  while(true) {
+    if(!_.isObject(this.spec.definitions[name])) {
+      return name;
+    }
+    name = base + '_' + count;
+    count++;
+  }
+};
+
+Resolver.prototype.resolveAllOf = function(spec, obj, depth) {
+  depth = depth || 0;
+  obj = obj || spec;
+  var name;
+  for(var key in obj) {
+    if (!obj.hasOwnProperty(key)) {
+      continue;
+    }
+    var item = obj[key];
+    if(item === null) {
+      throw new TypeError('Swagger 2.0 does not support null types (' + obj + ').  See https://github.com/swagger-api/swagger-spec/issues/229.');
+    }
+    if(typeof item === 'object') {
+      this.resolveAllOf(spec, item, depth + 1);
+    }
+    if(item && typeof item.allOf !== 'undefined') {
+      var allOf = item.allOf;
+      if(_.isArray(allOf)) {
+        var output = _.cloneDeep(item);
+        delete output.allOf;
+
+        output['x-composed'] = true;
+        if (typeof item['x-resolved-from'] !== 'undefined') {
+          output['x-resolved-from'] = item['x-resolved-from'];
+        }
+
+        for(var i = 0; i < allOf.length; i++) {
+          var component = allOf[i];
+          var source = 'self';
+          if(typeof component['x-resolved-from'] !== 'undefined') {
+            source = component['x-resolved-from'][0];
+          }
+
+          for(var part in component) {
+            if(!output.hasOwnProperty(part)) {
+              output[part] = _.cloneDeep(component[part]);
+              if(part === 'properties') {
+                for(name in output[part]) {
+                  output[part][name]['x-resolved-from'] = source;
+                }
+              }
+            }
+            else {
+              if(part === 'properties') {
+                var properties = component[part];
+                for(name in properties) {
+                  output.properties[name] = _.cloneDeep(properties[name]);
+                  var resolvedFrom = properties[name]['x-resolved-from'];
+                  if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') {
+                    resolvedFrom = source;
+                  }
+                  output.properties[name]['x-resolved-from'] = resolvedFrom;
+                }
+              }
+              else if(part === 'required') {
+                // merge & dedup the required array
+                var a = output.required.concat(component[part]);
+                for(var k = 0; k < a.length; ++k) {
+                  for(var j = k + 1; j < a.length; ++j) {
+                    if(a[k] === a[j]) { a.splice(j--, 1); }
+                  }
+                }
+                output.required = a;
+              }
+              else if(part === 'x-resolved-from') {
+                output['x-resolved-from'].push(source);
+              }
+              else {
+                // TODO: need to merge this property
+                // console.log('what to do with ' + part)
+              }
+            }
+          }
+        }
+        obj[key] = output;
+      }
+    }
+  }
+};
+
+},{"./http":5,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],7:[function(require,module,exports){
+'use strict';
+
+var Helpers = require('./helpers');
+
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isUndefined: require('lodash-compat/lang/isUndefined'),
+  isArray: require('lodash-compat/lang/isArray'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isEmpty: require('lodash-compat/lang/isEmpty'),
+  map: require('lodash-compat/collection/map'),
+  indexOf: require('lodash-compat/array/indexOf'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  keys: require('lodash-compat/object/keys'),
+  forEach: require('lodash-compat/collection/forEach')
+};
+
+module.exports.optionHtml = optionHtml;
+module.exports.typeFromJsonSchema = typeFromJsonSchema;
+module.exports.getStringSignature = getStringSignature;
+module.exports.schemaToHTML = schemaToHTML;
+module.exports.schemaToJSON = schemaToJSON;
+
+function optionHtml(label, value) {
+  return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+}
+
+function typeFromJsonSchema(type, format) {
+  var str;
+
+  if (type === 'integer' && format === 'int32') {
+    str = 'integer';
+  } else if (type === 'integer' && format === 'int64') {
+    str = 'long';
+  } else if (type === 'integer' && typeof format === 'undefined') {
+    str = 'long';
+  } else if (type === 'string' && format === 'date-time') {
+    str = 'date-time';
+  } else if (type === 'string' && format === 'date') {
+    str = 'date';
+  } else if (type === 'number' && format === 'float') {
+    str = 'float';
+  } else if (type === 'number' && format === 'double') {
+    str = 'double';
+  } else if (type === 'number' && typeof format === 'undefined') {
+    str = 'double';
+  } else if (type === 'boolean') {
+    str = 'boolean';
+  } else if (type === 'string') {
+    str = 'string';
+  }
+
+  return str;
+}
+
+function getStringSignature(obj, baseComponent) {
+  var str = '';
+
+  if (typeof obj.$ref !== 'undefined') {
+    str += Helpers.simpleRef(obj.$ref);
+  } else if (typeof obj.type === 'undefined') {
+    str += 'object';
+  } else if (obj.type === 'array') {
+    if (baseComponent) {
+      str += getStringSignature((obj.items || obj.$ref || {}));
+    } else {
+      str += 'Array[';
+      str += getStringSignature((obj.items || obj.$ref || {}));
+      str += ']';
+    }
+  } else if (obj.type === 'integer' && obj.format === 'int32') {
+    str += 'integer';
+  } else if (obj.type === 'integer' && obj.format === 'int64') {
+    str += 'long';
+  } else if (obj.type === 'integer' && typeof obj.format === 'undefined') {
+    str += 'long';
+  } else if (obj.type === 'string' && obj.format === 'date-time') {
+    str += 'date-time';
+  } else if (obj.type === 'string' && obj.format === 'date') {
+    str += 'date';
+  } else if (obj.type === 'string' && typeof obj.format === 'undefined') {
+    str += 'string';
+  } else if (obj.type === 'number' && obj.format === 'float') {
+    str += 'float';
+  } else if (obj.type === 'number' && obj.format === 'double') {
+    str += 'double';
+  } else if (obj.type === 'number' && typeof obj.format === 'undefined') {
+    str += 'double';
+  } else if (obj.type === 'boolean') {
+    str += 'boolean';
+  } else if (obj.$ref) {
+    str += Helpers.simpleRef(obj.$ref);
+  } else {
+    str += obj.type;
+  }
+
+  return str;
+}
+
+function schemaToJSON(schema, models, modelsToIgnore, modelPropertyMacro) {
+  // Resolve the schema (Handle nested schemas)
+  schema = Helpers.resolveSchema(schema);
+
+  if(typeof modelPropertyMacro !== 'function') {
+    modelPropertyMacro = function(prop){
+      return (prop || {}).default;
+    };
+  }
+
+  modelsToIgnore= modelsToIgnore || {};
+
+  var type = schema.type || 'object';
+  var format = schema.format;
+  var model;
+  var output;
+
+  if (!_.isUndefined(schema.example)) {
+    output = schema.example;
+  } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
+    output = schema.enum[0];
+  }
+
+  if (_.isUndefined(output)) {
+    if (schema.$ref) {
+      model = models[Helpers.simpleRef(schema.$ref)];
+
+      if (!_.isUndefined(model)) {
+        if (_.isUndefined(modelsToIgnore[model.name])) {
+          modelsToIgnore[model.name] = model;
+          output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
+          delete modelsToIgnore[model.name];
+        } else {
+          if (model.type === 'array') {
+            output = [];
+          } else {
+            output = {};
+          }
+        }
+      }
+    } else if (!_.isUndefined(schema.default)) {
+      output = schema.default;
+    } else if (type === 'string') {
+      if (format === 'date-time') {
+        output = new Date().toISOString();
+      } else if (format === 'date') {
+        output = new Date().toISOString().split('T')[0];
+      } else {
+        output = 'string';
+      }
+    } else if (type === 'integer') {
+      output = 0;
+    } else if (type === 'number') {
+      output = 0.0;
+    } else if (type === 'boolean') {
+      output = true;
+    } else if (type === 'object') {
+      output = {};
+
+      _.forEach(schema.properties, function (property, name) {
+        var cProperty = _.cloneDeep(property);
+
+        // Allow macro to set the default value
+        cProperty.default = modelPropertyMacro(property);
+
+        output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
+      });
+    } else if (type === 'array') {
+      output = [];
+
+      if (_.isArray(schema.items)) {
+        _.forEach(schema.items, function (item) {
+          output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
+        });
+      } else if (_.isPlainObject(schema.items)) {
+        output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
+      } else if (_.isUndefined(schema.items)) {
+        output.push({});
+      } else {
+        Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+      }
+    }
+  }
+
+  return output;
+}
+
+function schemaToHTML(name, schema, models, modelPropertyMacro) {
+
+  var strongOpen = '<span class="strong">';
+  var strongClose = '</span>';
+
+  // Allow for ignoring the 'name' argument.... shifting the rest
+  if(_.isObject(arguments[0])) {
+    name = void 0;
+    schema = arguments[0];
+    models = arguments[1];
+    modelPropertyMacro = arguments[2];
+  }
+
+  models = models || {};
+
+  // Resolve the schema (Handle nested schemas)
+  schema = Helpers.resolveSchema(schema);
+
+  // Return for empty object
+  if(_.isEmpty(schema)) {
+    return strongOpen + 'Empty' + strongClose;
+  }
+
+  // Dereference $ref from 'models'
+  if(typeof schema.$ref === 'string') {
+    name = Helpers.simpleRef(schema.$ref);
+    schema = models[name];
+    if(typeof schema === 'undefined')
+    {
+      return strongOpen + name + ' is not defined!' + strongClose;
+    }
+  }
+
+  if(typeof name !== 'string') {
+    name = schema.title || 'Inline Model';
+  }
+
+  // If we are a Model object... adjust accordingly
+  if(schema.definition) {
+    schema = schema.definition;
+  }
+
+  if(typeof modelPropertyMacro !== 'function') {
+    modelPropertyMacro = function(prop){
+      return (prop || {}).default;
+    };
+  }
+
+  var references = {};
+  var seenModels = [];
+  var inlineModels = 0;
+
+
+
+  // Generate current HTML
+  var html = processModel(schema, name);
+
+  // Generate references HTML
+  while (_.keys(references).length > 0) {
+    /* jshint ignore:start */
+    _.forEach(references, function (schema, name) {
+      var seenModel = _.indexOf(seenModels, name) > -1;
+
+      delete references[name];
+
+      if (!seenModel) {
+        seenModels.push(name);
+
+        html += '<br />' + processModel(schema, name);
+      }
+    });
+    /* jshint ignore:end */
+  }
+
+  return html;
+
+  /////////////////////////////////
+
+  function addReference(schema, name, skipRef) {
+    var modelName = name;
+    var model;
+
+    if (schema.$ref) {
+      modelName = schema.title || Helpers.simpleRef(schema.$ref);
+      model = models[modelName];
+    } else if (_.isUndefined(name)) {
+      modelName = schema.title || 'Inline Model ' + (++inlineModels);
+      model = {definition: schema};
+    }
+
+    if (skipRef !== true) {
+      references[modelName] = _.isUndefined(model) ? {} : model.definition;
+    }
+
+    return modelName;
+  }
+
+  function primitiveToHTML(schema) {
+    var html = '<span class="propType">';
+    var type = schema.type || 'object';
+
+    if (schema.$ref) {
+      html += addReference(schema, Helpers.simpleRef(schema.$ref));
+    } else if (type === 'object') {
+      if (!_.isUndefined(schema.properties)) {
+        html += addReference(schema);
+      } else {
+        html += 'object';
+      }
+    } else if (type === 'array') {
+      html += 'Array[';
+
+      if (_.isArray(schema.items)) {
+        html += _.map(schema.items, addReference).join(',');
+      } else if (_.isPlainObject(schema.items)) {
+        if (_.isUndefined(schema.items.$ref)) {
+          if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
+            html += schema.items.type;
+          } else {
+            html += addReference(schema.items);
+          }
+        } else {
+          html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref));
+        }
+      } else {
+        Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
+        html += 'object';
+      }
+
+      html += ']';
+    } else {
+      html += schema.type;
+    }
+
+    html += '</span>';
+
+    return html;
+  }
+
+  function primitiveToOptionsHTML(schema, html) {
+    var options = '';
+    var type = schema.type || 'object';
+    var isArray = type === 'array';
+
+    if (isArray) {
+      if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
+        type = schema.items.type;
+      } else {
+        type = 'object';
+      }
+    }
+
+    if (!_.isUndefined(schema.default)) {
+      options += optionHtml('Default', schema.default);
+    }
+
+    switch (type) {
+    case 'string':
+      if (schema.minLength) {
+        options += optionHtml('Min. Length', schema.minLength);
+      }
+
+      if (schema.maxLength) {
+        options += optionHtml('Max. Length', schema.maxLength);
+      }
+
+      if (schema.pattern) {
+        options += optionHtml('Reg. Exp.', schema.pattern);
+      }
+      break;
+    case 'integer':
+    case 'number':
+      if (schema.minimum) {
+        options += optionHtml('Min. Value', schema.minimum);
+      }
+
+      if (schema.exclusiveMinimum) {
+        options += optionHtml('Exclusive Min.', 'true');
+      }
+
+      if (schema.maximum) {
+        options += optionHtml('Max. Value', schema.maximum);
+      }
+
+      if (schema.exclusiveMaximum) {
+        options += optionHtml('Exclusive Max.', 'true');
+      }
+
+      if (schema.multipleOf) {
+        options += optionHtml('Multiple Of', schema.multipleOf);
+      }
+
+      break;
+    }
+
+    if (isArray) {
+      if (schema.minItems) {
+        options += optionHtml('Min. Items', schema.minItems);
+      }
+
+      if (schema.maxItems) {
+        options += optionHtml('Max. Items', schema.maxItems);
+      }
+
+      if (schema.uniqueItems) {
+        options += optionHtml('Unique Items', 'true');
+      }
+
+      if (schema.collectionFormat) {
+        options += optionHtml('Coll. Format', schema.collectionFormat);
+      }
+    }
+
+    if (_.isUndefined(schema.items)) {
+      if (_.isArray(schema.enum)) {
+        var enumString;
+
+        if (type === 'number' || type === 'integer') {
+          enumString = schema.enum.join(', ');
+        } else {
+          enumString = '"' + schema.enum.join('", "') + '"';
+        }
+
+        options += optionHtml('Enum', enumString);
+      }
+    }
+
+    if (options.length > 0) {
+      html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
+    }
+
+    return html;
+  }
+
+  function processModel(schema, name) {
+    var type = schema.type || 'object';
+    var isArray = schema.type === 'array';
+    var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
+
+    if (name) {
+      seenModels.push(name);
+    }
+
+    if (isArray) {
+      if (_.isArray(schema.items)) {
+        html += '<div>' + _.map(schema.items, function (item) {
+          var type = item.type || 'object';
+
+          if (_.isUndefined(item.$ref)) {
+            if (_.indexOf(['array', 'object'], type) > -1) {
+              if (type === 'object' && _.isUndefined(item.properties)) {
+                return 'object';
+              } else {
+                return addReference(item);
+              }
+            } else {
+              return primitiveToOptionsHTML(item, type);
+            }
+          } else {
+            return addReference(item, Helpers.simpleRef(item.$ref));
+          }
+        }).join(',</div><div>');
+      } else if (_.isPlainObject(schema.items)) {
+        if (_.isUndefined(schema.items.$ref)) {
+          if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
+            if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
+              html += '<div>object</div>';
+            } else {
+              html += '<div>' + addReference(schema.items) + '</div>';
+            }
+          } else {
+            html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
+          }
+        } else {
+          html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>';
+        }
+      } else {
+        Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+        html += '<div>object</div>';
+      }
+    } else {
+      if (schema.$ref) {
+        html += '<div>' + addReference(schema, name) + '</div>';
+      } else if (type === 'object') {
+        if (_.isPlainObject(schema.properties)) {
+          var contents = _.map(schema.properties, function (property, name) {
+            var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
+            var cProperty = _.cloneDeep(property);
+
+            var requiredClass = propertyIsRequired ? 'required' : '';
+            var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
+            var model;
+            var propDescription;
+
+            // Allow macro to set the default value
+            cProperty.default = modelPropertyMacro(cProperty);
+
+            // Resolve the schema (Handle nested schemas)
+            cProperty = Helpers.resolveSchema(cProperty);
+
+            propDescription = property.description || cProperty.description;
+
+            // We need to handle property references to primitives (Issue 339)
+            if (!_.isUndefined(cProperty.$ref)) {
+              model = models[Helpers.simpleRef(cProperty.$ref)];
+
+              if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
+                // Use referenced schema
+                cProperty = Helpers.resolveSchema(model.definition);
+              }
+            }
+
+            html += primitiveToHTML(cProperty);
+
+            if(!propertyIsRequired) {
+              html += ', <span class="propOptKey">optional</span>';
+            }
+
+            if(property.readOnly) {
+                html += ', <span class="propReadOnly">read only</span>';
+            }
+
+            html += ')';
+
+            if (!_.isUndefined(propDescription)) {
+              html += ': ' + '<span class="propDesc">' + propDescription + '</span>';
+            }
+
+            if (cProperty.enum) {
+              html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';
+            }
+
+            return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
+          }).join(',</div>');
+
+          if (contents) {
+            html += contents + '</div>';
+          }
+        }
+      } else {
+        html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
+      }
+    }
+
+    return html + strongOpen + (isArray ? ']' : '}') + strongClose;
+  }
+}
+
+},{"./helpers":4,"lodash-compat/array/indexOf":51,"lodash-compat/collection/forEach":56,"lodash-compat/collection/map":58,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,"lodash-compat/object/keys":151}],8:[function(require,module,exports){
+'use strict';
+
+var SwaggerHttp = require('./http');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject')
+};
+
+var SwaggerSpecConverter = module.exports = function () {
+  this.errors = [];
+  this.warnings = [];
+  this.modelMap = {};
+};
+
+SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) {
+  this.docLocation = location;
+};
+
+/**
+ * converts a resource listing OR api declaration
+ **/
+SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) {
+  // not a valid spec
+  if(!obj || !Array.isArray(obj.apis)) {
+    return this.finish(callback, null);
+  }
+  this.clientAuthorizations = clientAuthorizations;
+
+  // create a new swagger object to return
+  var swagger = { swagger: '2.0' };
+
+  swagger.originalVersion = obj.swaggerVersion;
+
+  // add the info
+  this.apiInfo(obj, swagger);
+
+  // add security definitions
+  this.securityDefinitions(obj, swagger);
+
+  // take basePath into account
+  if (obj.basePath) {
+    this.setDocumentationLocation(obj.basePath);
+  }
+
+  // see if this is a single-file swagger definition
+  var isSingleFileSwagger = false;
+  var i;
+  for(i = 0; i < obj.apis.length; i++) {
+    var api = obj.apis[i];
+    if(Array.isArray(api.operations)) {
+      isSingleFileSwagger = true;
+    }
+  }
+  if(isSingleFileSwagger) {
+    this.declaration(obj, swagger);
+    this.finish(callback, swagger);
+  }
+  else {
+    this.resourceListing(obj, swagger, opts, callback);
+  }
+};
+
+SwaggerSpecConverter.prototype.declaration = function(obj, swagger) {
+  var name, i, p, pos;
+  if(!obj.apis) {
+    return;
+  }
+
+  if (obj.basePath.indexOf('http://') === 0) {
+    p = obj.basePath.substring('http://'.length);
+    pos = p.indexOf('/');
+    if (pos > 0) {
+      swagger.host = p.substring(0, pos);
+      swagger.basePath = p.substring(pos);
+    }
+    else {
+      swagger.host = p;
+      swagger.basePath = '/';
+    }
+  } else if (obj.basePath.indexOf('https://') === 0) {
+    p = obj.basePath.substring('https://'.length);
+    pos = p.indexOf('/');
+    if (pos > 0) {
+      swagger.host = p.substring(0, pos);
+      swagger.basePath = p.substring(pos);
+    }
+    else {
+      swagger.host = p;
+      swagger.basePath = '/';
+    }
+  } else {
+    swagger.basePath = obj.basePath;
+  }
+
+  var resourceLevelAuth;
+  if(obj.authorizations) {
+    resourceLevelAuth = obj.authorizations;
+  }
+  if(obj.consumes) {
+    swagger.consumes = obj.consumes;
+  }
+  if(obj.produces) {
+    swagger.produces = obj.produces;
+  }
+
+  // build a mapping of id to name for 1.0 model resolutions
+  if(_.isObject(obj)) {
+    for(name in obj.models) {
+      var existingModel = obj.models[name];
+      var key = (existingModel.id || name);
+      this.modelMap[key] = name;
+    }
+  }
+
+  for(i = 0; i < obj.apis.length; i++) {
+    var api = obj.apis[i];
+    var path = api.path;
+    var operations = api.operations;
+    this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger);
+  }
+
+  var models = obj.models || {};
+  this.models(models, swagger);
+};
+
+SwaggerSpecConverter.prototype.models = function(obj, swagger) {
+  if(!_.isObject(obj)) {
+    return;
+  }
+  var name;
+
+  swagger.definitions = swagger.definitions || {};
+  for(name in obj) {
+    var existingModel = obj[name];
+    var _required = [];
+    var schema = { properties: {}};
+    var propertyName;
+    for(propertyName in existingModel.properties) {
+      var existingProperty = existingModel.properties[propertyName];
+      var property = {};
+      this.dataType(existingProperty, property);
+      if(existingProperty.description) {
+        property.description = existingProperty.description;
+      }
+      if(existingProperty['enum']) {
+        property['enum'] = existingProperty['enum'];
+      }
+      if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) {
+        _required.push(propertyName);
+      }
+      if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') {
+        _required.push(propertyName);
+      }
+      schema.properties[propertyName] = property;
+    }
+    if(_required.length > 0) {
+      schema.required = _required;
+    } else {
+      schema.required = existingModel.required;
+    }
+    swagger.definitions[name] = schema;
+  }
+};
+
+SwaggerSpecConverter.prototype.extractTag = function(resourcePath) {
+  var pathString = resourcePath || 'default';
+  if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) {
+    pathString = pathString.split(['/']);
+    pathString = pathString[pathString.length -1].substring();
+  }
+  if(pathString.endsWith('.json')) {
+    pathString = pathString.substring(0, pathString.length - '.json'.length);
+  }
+  return pathString.replace('/','');
+};
+
+SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) {
+  if(!Array.isArray(obj)) {
+    return;
+  }
+  var i;
+
+  if(!swagger.paths) {
+    swagger.paths = {};
+  }
+
+  var pathObj = swagger.paths[path] || {};
+  var tag = this.extractTag(resourcePath);
+  swagger.tags = swagger.tags || [];
+  var matched = false;
+  for(i = 0; i < swagger.tags.length; i++) {
+    var tagObject = swagger.tags[i];
+    if(tagObject.name === tag) {
+      matched = true;
+    }
+  }
+  if(!matched) {
+    swagger.tags.push({name: tag});
+  }
+
+  for(i = 0; i < obj.length; i++) {
+    var existingOperation = obj[i];
+    var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase();
+    var operation = {tags: [tag]};
+    var existingAuthorizations = existingOperation.authorizations;
+
+    if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) {
+      existingAuthorizations = resourceLevelAuth;
+    }
+
+    if(typeof existingAuthorizations !== 'undefined') {
+      var scopesObject;
+      for(var key in existingAuthorizations) {
+        operation.security = operation.security || [];
+        var scopes = existingAuthorizations[key];
+        if(scopes) {
+          var securityScopes = [];
+          for(var j in scopes) {
+            securityScopes.push(scopes[j].scope);
+          }
+          scopesObject = {};
+          scopesObject[key] = securityScopes;
+          operation.security.push(scopesObject);
+        }
+        else {
+          scopesObject = {};
+          scopesObject[key] = [];
+          operation.security.push(scopesObject);
+        }
+      }
+    }
+
+    if(existingOperation.consumes) {
+      operation.consumes = existingOperation.consumes;
+    }
+    else if(swagger.consumes) {
+      operation.consumes = swagger.consumes;
+    }
+    if(existingOperation.produces) {
+      operation.produces = existingOperation.produces;
+    }
+    else if(swagger.produces) {
+      operation.produces = swagger.produces;
+    }
+    if(existingOperation.summary) {
+      operation.summary = existingOperation.summary;
+    }
+    if(existingOperation.notes) {
+      operation.description = existingOperation.notes;
+    }
+    if(existingOperation.nickname) {
+      operation.operationId = existingOperation.nickname;
+    }
+    if(existingOperation.deprecated) {
+      operation.deprecated = existingOperation.deprecated;
+    }
+
+    this.authorizations(existingAuthorizations, swagger);
+    this.parameters(operation, existingOperation.parameters, swagger);
+    this.responseMessages(operation, existingOperation, swagger);
+
+    pathObj[method] = operation;
+  }
+
+  swagger.paths[path] = pathObj;
+};
+
+SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) {
+  if(!_.isObject(existingOperation)) {
+    return;
+  }
+  // build default response from the operation (1.x)
+  var defaultResponse = {};
+  this.dataType(existingOperation, defaultResponse);
+  // TODO: look into the real problem of rendering responses in swagger-ui
+  // ....should reponseType have an implicit schema?
+  if(!defaultResponse.schema && defaultResponse.type) {
+    defaultResponse = {schema: defaultResponse};
+  }
+
+  operation.responses = operation.responses || {};
+
+  // grab from responseMessages (1.2)
+  var has200 = false;
+  if(Array.isArray(existingOperation.responseMessages)) {
+    var i;
+    var existingResponses = existingOperation.responseMessages;
+    for(i = 0; i < existingResponses.length; i++) {
+      var existingResponse = existingResponses[i];
+      var response = { description: existingResponse.message };
+      if(existingResponse.code === 200) {
+        has200 = true;
+      }
+      // Convert responseModel -> schema{$ref: responseModel}
+      if(existingResponse.responseModel) {
+        response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel};
+      }
+      operation.responses['' + existingResponse.code] = response;
+    }
+  }
+
+  if(has200) {
+    operation.responses['default'] = defaultResponse;
+  }
+  else {
+    operation.responses['200'] = defaultResponse;
+  }
+};
+
+SwaggerSpecConverter.prototype.authorizations = function(obj) {
+  // TODO
+  if(!_.isObject(obj)) {
+    return;
+  }
+};
+
+SwaggerSpecConverter.prototype.parameters = function(operation, obj) {
+  if(!Array.isArray(obj)) {
+    return;
+  }
+  var i;
+  for(i = 0; i < obj.length; i++) {
+    var existingParameter = obj[i];
+    var parameter = {};
+    parameter.name = existingParameter.name;
+    parameter.description = existingParameter.description;
+    parameter.required = existingParameter.required;
+    parameter.in = existingParameter.paramType;
+
+    // per #168
+    if(parameter.in === 'body') {
+      parameter.name = 'body';
+    }
+    if(parameter.in === 'form') {
+      parameter.in = 'formData';
+    }
+
+    if(existingParameter.enum) {
+      parameter.enum = existingParameter.enum;
+    }
+
+    if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') {
+      var innerType = {};
+      this.dataType(existingParameter, innerType);
+      parameter.type = 'array';
+      parameter.items = innerType;
+
+      if(existingParameter.allowableValues) {
+        var av = existingParameter.allowableValues;
+        if(av.valueType === 'LIST') {
+          parameter['enum'] = av.values;
+        }
+      }
+    }
+    else {
+      this.dataType(existingParameter, parameter);
+    }
+    if(typeof existingParameter.defaultValue !== 'undefined') {
+      parameter.default = existingParameter.defaultValue;
+    }
+
+    operation.parameters = operation.parameters || [];
+    operation.parameters.push(parameter);
+  }
+};
+
+SwaggerSpecConverter.prototype.dataType = function(source, target) {
+  if(!_.isObject(source)) {
+    return;
+  }
+
+  if(source.minimum) {
+    target.minimum = source.minimum;
+  }
+  if(source.maximum) {
+    target.maximum = source.maximum;
+  }
+  if (source.format) {
+    target.format = source.format;
+  }
+
+  // default can be 'false'
+  if(typeof source.defaultValue !== 'undefined') {
+    target.default = source.defaultValue;
+  }
+
+  var jsonSchemaType = this.toJsonSchema(source);
+  if(jsonSchemaType) {
+    target = target || {};
+    if(jsonSchemaType.type) {
+      target.type = jsonSchemaType.type;
+    }
+    if(jsonSchemaType.format) {
+      target.format = jsonSchemaType.format;
+    }
+    if(jsonSchemaType.$ref) {
+      target.schema = {$ref: jsonSchemaType.$ref};
+    }
+    if(jsonSchemaType.items) {
+      target.items = jsonSchemaType.items;
+    }
+  }
+};
+
+SwaggerSpecConverter.prototype.toJsonSchema = function(source) {
+  if(!source) {
+    return 'object';
+  }
+  var detectedType = (source.type || source.dataType || source.responseClass || '');
+  var lcType = detectedType.toLowerCase();
+  var format = (source.format || '').toLowerCase();
+
+  if(lcType.indexOf('list[') === 0) {
+    var innerType = detectedType.substring(5, detectedType.length - 1);
+    var jsonType = this.toJsonSchema({type: innerType});
+    return {type: 'array', items: jsonType};
+  } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) {
+    {return {type: 'integer', format: 'int32'};}
+  } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) {
+    {return {type: 'integer', format: 'int64'};}
+  } else if(lcType === 'integer') {
+    {return {type: 'integer', format: 'int64'};}
+  } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) {
+    {return {type: 'number', format: 'float'};}
+  } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) {
+    {return {type: 'number', format: 'double'};}
+  } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) {
+    {return {type: 'string', format: 'date-time'};}
+  } else if(lcType === 'string') {
+    {return {type: 'string'};}
+  } else if(lcType === 'file') {
+    {return {type: 'file'};}
+  } else if(lcType === 'boolean') {
+    {return {type: 'boolean'};}
+  } else if(lcType === 'boolean') {
+    {return {type: 'boolean'};}
+  } else if(lcType === 'array' || lcType === 'list') {
+    if(source.items) {
+      var it = this.toJsonSchema(source.items);
+      return {type: 'array', items: it};
+    }
+    else {
+      return {type: 'array', items: {type: 'object'}};
+    }
+  } else if(source.$ref) {
+    return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref};
+  } else if(lcType === 'void' || lcType === '') {
+    {return {};}
+  } else if (this.modelMap[source.type]) {
+    // If this a model using `type` instead of `$ref`, that's fine.
+    return {$ref: '#/definitions/' + this.modelMap[source.type]};
+  } else {
+    // Unknown model type or 'object', pass it along.
+    return {type: source.type};
+  }
+};
+
+SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) {
+  var i;
+  var processedCount = 0;   // jshint ignore:line
+  var self = this;          // jshint ignore:line
+  var expectedCount = obj.apis.length;
+  var _swagger = swagger;   // jshint ignore:line
+  var _opts = {};
+
+  if(opts && opts.requestInterceptor){
+    _opts.requestInterceptor = opts.requestInterceptor;
+  }
+
+  if(opts && opts.responseInterceptor){
+    _opts.responseInterceptor = opts.responseInterceptor;
+  }
+
+  var swaggerRequestHeaders = 'application/json';
+
+  if(opts && opts.swaggerRequestHeaders) {
+    swaggerRequestHeaders = opts.swaggerRequestHeaders;
+  }
+
+  if(expectedCount === 0) {
+    this.finish(callback, swagger);
+  }
+
+  for(i = 0; i < expectedCount; i++) {
+    var api = obj.apis[i];
+    var path = api.path;
+    var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path);
+
+    if(api.description) {
+      swagger.tags = swagger.tags || [];
+      swagger.tags.push({
+        name : this.extractTag(api.path),
+        description : api.description || ''
+      });
+    }
+    var http = {
+      url: absolutePath,
+      headers: { accept: swaggerRequestHeaders },
+      on: {},
+      method: 'get'
+    };
+    /* jshint ignore:start */
+    http.on.response = function(data) {
+      processedCount += 1;
+      var obj = data.obj;
+      if(obj) {
+        self.declaration(obj, _swagger);
+      }
+      if(processedCount === expectedCount) {
+        self.finish(callback, _swagger);
+      }
+    };
+    http.on.error = function(data) {
+      console.error(data);
+      processedCount += 1;
+      if(processedCount === expectedCount) {
+        self.finish(callback, _swagger);
+      }
+    };
+    /* jshint ignore:end */
+
+    if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') {
+      this.clientAuthorizations.apply(http);
+    }
+
+    new SwaggerHttp().execute(http, _opts);
+  }
+};
+
+SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path)  {
+  if(version === '1.0') {
+    if(docLocation.endsWith('.json')) {
+      // get root path
+      var pos = docLocation.lastIndexOf('/');
+      if(pos > 0) {
+        docLocation = docLocation.substring(0, pos);
+      }
+    }
+  }
+
+  var location = docLocation;
+  if(path.indexOf('http://') === 0 || path.indexOf('https://') === 0) {
+    location = path;
+  }
+  else {
+    if(docLocation.endsWith('/')) {
+      location = docLocation.substring(0, docLocation.length - 1);
+    }
+    location += path;
+  }
+  location = location.replace('{format}', 'json');
+  return location;
+};
+
+SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) {
+  if(obj.authorizations) {
+    var name;
+    for(name in obj.authorizations) {
+      var isValid = false;
+      var securityDefinition = {};
+      var definition = obj.authorizations[name];
+      if(definition.type === 'apiKey') {
+        securityDefinition.type = 'apiKey';
+        securityDefinition.in = definition.passAs;
+        securityDefinition.name = definition.keyname || name;
+        isValid = true;
+      }
+      else if(definition.type === 'basicAuth') {
+        securityDefinition.type = 'basicAuth';
+        isValid = true;
+      }
+      else if(definition.type === 'oauth2') {
+        var existingScopes = definition.scopes || [];
+        var scopes = {};
+        var i;
+        for(i in existingScopes) {
+          var scope = existingScopes[i];
+          scopes[scope.scope] = scope.description;
+        }
+        securityDefinition.type = 'oauth2';
+        if(i > 0) {
+          securityDefinition.scopes = scopes;
+        }
+        if(definition.grantTypes) {
+          if(definition.grantTypes.implicit) {
+            var implicit = definition.grantTypes.implicit;
+            securityDefinition.flow = 'implicit';
+            securityDefinition.authorizationUrl = implicit.loginEndpoint;
+            isValid = true;
+          }
+          /* jshint ignore:start */
+          if(definition.grantTypes['authorization_code']) {
+            if(!securityDefinition.flow) {
+              // cannot set if flow is already defined
+              var authCode = definition.grantTypes['authorization_code'];
+              securityDefinition.flow = 'accessCode';
+              securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url;
+              securityDefinition.tokenUrl = authCode.tokenEndpoint.url;
+              isValid = true;
+            }
+          }
+          /* jshint ignore:end */
+        }
+      }
+      if(isValid) {
+        swagger.securityDefinitions = swagger.securityDefinitions || {};
+        swagger.securityDefinitions[name] = securityDefinition;
+      }
+    }
+  }
+};
+
+SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) {
+  // info section
+  if(obj.info) {
+    var info = obj.info;
+    swagger.info = {};
+
+    if(info.contact) {
+      swagger.info.contact = {};
+      swagger.info.contact.email = info.contact;
+    }
+    if(info.description) {
+      swagger.info.description = info.description;
+    }
+    if(info.title) {
+      swagger.info.title = info.title;
+    }
+    if(info.termsOfServiceUrl) {
+      swagger.info.termsOfService = info.termsOfServiceUrl;
+    }
+    if(info.license || info.licenseUrl) {
+      swagger.license = {};
+      if(info.license) {
+        swagger.license.name = info.license;
+      }
+      if(info.licenseUrl) {
+        swagger.license.url = info.licenseUrl;
+      }
+    }
+  }
+  else {
+    this.warnings.push('missing info section');
+  }
+};
+
+SwaggerSpecConverter.prototype.finish = function (callback, obj) {
+  callback(obj);
+};
+
+},{"./http":5,"lodash-compat/lang/isObject":146}],9:[function(require,module,exports){
+'use strict';
+
+var log = require('../helpers').log;
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isString: require('lodash-compat/lang/isString'),
+};
+
+var SchemaMarkup = require('../schema-markup.js');
+var jsyaml = require('js-yaml');
+
+var Model = module.exports = function (name, definition, models, modelPropertyMacro) {
+  this.definition = definition || {};
+  this.isArray = definition.type === 'array';
+  this.models = models || {};
+  this.name = name || definition.title || 'Inline Model';
+  this.modelPropertyMacro = modelPropertyMacro || function (property) {
+    return property.default;
+  };
+
+  return this;
+};
+
+// Note!  This function will be removed in 2.2.x!
+Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) {
+  modelsToIgnore = modelsToIgnore || {};
+
+  modelsToIgnore[this.name] = this;
+
+  // Response support
+  if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) {
+    this.definition.example = this.examples['application/json'];
+
+    if (_.isString(this.definition.example)) {
+      this.definition.example = jsyaml.safeLoad(this.definition.example);
+    }
+  } else if (!this.definition.example) {
+    this.definition.example = this.examples;
+  }
+
+  return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro);
+};
+
+Model.prototype.getMockSignature = function () {
+  return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro);
+};
+
+},{"../helpers":4,"../schema-markup.js":7,"js-yaml":21,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isString":148}],10:[function(require,module,exports){
+'use strict';
+
+var _ = {
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  isUndefined: require('lodash-compat/lang/isUndefined'),
+  isEmpty: require('lodash-compat/lang/isEmpty'),
+  isObject: require('lodash-compat/lang/isObject')
+};
+var helpers = require('../helpers');
+var Model = require('./model');
+var SwaggerHttp = require('../http');
+var Q = require('q');
+
+var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) {
+  var errors = [];
+
+  parent = parent || {};
+  args = args || {};
+
+  if(parent && parent.options) {
+    this.client = parent.options.client || null;
+    this.requestInterceptor = parent.options.requestInterceptor || null;
+    this.responseInterceptor = parent.options.responseInterceptor || null;
+  }
+  this.authorizations = args.security;
+  this.basePath = parent.basePath || '/';
+  this.clientAuthorizations = clientAuthorizations;
+  this.consumes = args.consumes || parent.consumes || ['application/json'];
+  this.produces = args.produces || parent.produces || ['application/json'];
+  this.deprecated = args.deprecated;
+  this.description = args.description;
+  this.host = parent.host || 'localhost';
+  this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.'));
+  this.models = models || {};
+  this.nickname = (operationId || errors.push('Operations must have a nickname.'));
+  this.operation = args;
+  this.operations = {};
+  this.parameters = args !== null ? (args.parameters || []) : {};
+  this.parent = parent;
+  this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.'));
+  this.responses = (args.responses || {});
+  this.scheme = scheme || parent.scheme || 'http';
+  this.schemes = args.schemes || parent.schemes;
+  this.security = args.security || parent.security;
+  this.summary = args.summary || '';
+  this.type = null;
+  this.useJQuery = parent.useJQuery;
+  this.enableCookies = parent.enableCookies;
+  this.parameterMacro = parent.parameterMacro || function (operation, parameter) {
+    return parameter.default;
+  };
+
+  this.inlineModels = [];
+
+  if (typeof this.deprecated === 'string') {
+    switch(this.deprecated.toLowerCase()) {
+      case 'true': case 'yes': case '1': {
+        this.deprecated = true;
+        break;
+      }
+
+      case 'false': case 'no': case '0': case null: {
+        this.deprecated = false;
+        break;
+      }
+
+      default: this.deprecated = Boolean(this.deprecated);
+    }
+  }
+
+  var i, model;
+
+  if (definitions) {
+    // add to global models
+    var key;
+
+    for (key in definitions) {
+      model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro);
+
+      if (model) {
+        this.models[key] = model;
+      }
+    }
+  }
+  else {
+    definitions = {};
+  }
+
+  for (i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    // Allow macro to set the default value
+    param.default = this.parameterMacro(this, param);
+
+    if (param.type === 'array') {
+      param.isList = true;
+      param.allowMultiple = true;
+      // the enum can be defined at the items level
+      //if (param.items && param.items.enum) {
+      //  param['enum'] = param.items.enum;
+      //}
+    }
+
+    var innerType = this.getType(param);
+
+    if (innerType && innerType.toString().toLowerCase() === 'boolean') {
+      param.allowableValues = {};
+      param.isList = true;
+      param['enum'] = [true, false]; // use actual primitives
+    }
+
+    if(typeof param['x-example'] !== 'undefined') {
+      var d = param['x-example'];
+      param.default = d;
+    }
+    if(param['x-examples']) {
+      var d = param['x-examples'].default;
+      if(typeof d !== 'undefined') {
+        param.default = d;
+      }
+    }
+
+    var enumValues = param['enum'] || (param.items && param.items['enum']);
+
+    if (typeof enumValues !== 'undefined') {
+      var id;
+
+      param.allowableValues = {};
+      param.allowableValues.values = [];
+      param.allowableValues.descriptiveValues = [];
+
+      for (id = 0; id < enumValues.length; id++) {
+        var value = enumValues[id];
+        var isDefault = (value === param.default || value+'' === param.default);
+
+        param.allowableValues.values.push(value);
+        // Always have string for descriptive values....
+        param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault});
+      }
+    }
+
+    if (param.type === 'array') {
+      innerType = [innerType];
+
+      if (typeof param.allowableValues === 'undefined') {
+        // can't show as a list if no values to select from
+        delete param.isList;
+        delete param.allowMultiple;
+      }
+    }
+
+    param.modelSignature = {type: innerType, definitions: this.models};
+    param.signature = this.getModelSignature(innerType, this.models).toString();
+    param.sampleJSON = this.getModelSampleJSON(innerType, this.models);
+    param.responseClassSignature = param.signature;
+  }
+
+  var defaultResponseCode, response, responses = this.responses;
+
+  if (responses['200']) {
+    response = responses['200'];
+    defaultResponseCode = '200';
+  } else if (responses['201']) {
+    response = responses['201'];
+    defaultResponseCode = '201';
+  } else if (responses['202']) {
+    response = responses['202'];
+    defaultResponseCode = '202';
+  } else if (responses['203']) {
+    response = responses['203'];
+    defaultResponseCode = '203';
+  } else if (responses['204']) {
+    response = responses['204'];
+    defaultResponseCode = '204';
+  } else if (responses['205']) {
+    response = responses['205'];
+    defaultResponseCode = '205';
+  } else if (responses['206']) {
+    response = responses['206'];
+    defaultResponseCode = '206';
+  } else if (responses['default']) {
+    response = responses['default'];
+    defaultResponseCode = 'default';
+  }
+
+  if (response && response.schema) {
+    var resolvedModel = this.resolveModel(response.schema, definitions);
+    var successResponse;
+
+    delete responses[defaultResponseCode];
+
+    if (resolvedModel) {
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = resolvedModel;
+    } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') {
+      // Inline model
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro);
+    } else {
+      // Primitive
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = response.schema;
+    }
+
+    if (successResponse) {
+      // Attach response properties
+      if (response.description) {
+        successResponse.description = response.description;
+      }
+
+      if (response.examples) {
+        successResponse.examples = response.examples;
+      }
+
+      if (response.headers) {
+        successResponse.headers = response.headers;
+      }
+    }
+
+    this.type = response;
+  }
+
+  if (errors.length > 0) {
+    if (this.resource && this.resource.api && this.resource.api.fail) {
+      this.resource.api.fail(errors);
+    }
+  }
+
+  return this;
+};
+
+Operation.prototype.isDefaultArrayItemValue = function(value, param) {
+  if (param.default && Array.isArray(param.default)) {
+    return param.default.indexOf(value) !== -1;
+  }
+  return value === param.default;
+};
+
+Operation.prototype.getType = function (param) {
+  var type = param.type;
+  var format = param.format;
+  var isArray = false;
+  var str;
+
+  if (type === 'integer' && format === 'int32') {
+    str = 'integer';
+  } else if (type === 'integer' && format === 'int64') {
+    str = 'long';
+  } else if (type === 'integer') {
+    str = 'integer';
+  } else if (type === 'string') {
+    if (format === 'date-time') {
+      str = 'date-time';
+    } else if (format === 'date') {
+      str = 'date';
+    } else {
+      str = 'string';
+    }
+  } else if (type === 'number' && format === 'float') {
+    str = 'float';
+  } else if (type === 'number' && format === 'double') {
+    str = 'double';
+  } else if (type === 'number') {
+    str = 'double';
+  } else if (type === 'boolean') {
+    str = 'boolean';
+  } else if (type === 'array') {
+    isArray = true;
+
+    if (param.items) {
+      str = this.getType(param.items);
+    }
+  } else if (type === 'file') {
+    str = 'file';
+  }
+
+  if (param.$ref) {
+    str = helpers.simpleRef(param.$ref);
+  }
+
+  var schema = param.schema;
+
+  if (schema) {
+    var ref = schema.$ref;
+
+    if (ref) {
+      ref = helpers.simpleRef(ref);
+
+      if (isArray) {
+        return [ ref ];
+      } else {
+        return ref;
+      }
+    } else {
+      // If inline schema, we add it our interal hash -> which gives us it's ID (int)
+      if(schema.type === 'object') {
+        return this.addInlineModel(schema);
+      }
+      return this.getType(schema);
+    }
+  }
+  if (isArray) {
+    return [ str ];
+  } else {
+    return str;
+  }
+};
+
+/**
+ * adds an inline schema (model) to a hash, where we can ref it later
+ * @param {object} schema a schema
+ * @return {number} the ID of the schema being added, or null
+ **/
+Operation.prototype.addInlineModel = function (schema) {
+  var len = this.inlineModels.length;
+  var model = this.resolveModel(schema, {});
+  if(model) {
+    this.inlineModels.push(model);
+    return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel)
+  }
+  return null; // report errors?
+};
+
+/**
+ * gets the internal ref to an inline model
+ * @param {string} inline_str a string reference to an inline model
+ * @return {Model} the model being referenced. Or null
+ **/
+Operation.prototype.getInlineModel = function(inlineStr) {
+  if(/^Inline Model \d+$/.test(inlineStr)) {
+    var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
+    var model = this.inlineModels[id];
+    return model;
+  }
+  // I'm returning null here, should I rather throw an error?
+  return null;
+};
+
+Operation.prototype.resolveModel = function (schema, definitions) {
+  if (typeof schema.$ref !== 'undefined') {
+    var ref = schema.$ref;
+
+    if (ref.indexOf('#/definitions/') === 0) {
+      ref = ref.substring('#/definitions/'.length);
+    }
+
+    if (definitions[ref]) {
+      return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro);
+    }
+  // schema must at least be an object to get resolved to an inline Model
+  } else if (schema && typeof schema === 'object' &&
+            (schema.type === 'object' || _.isUndefined(schema.type))) {
+    return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro);
+  }
+
+  return null;
+};
+
+Operation.prototype.help = function (dontPrint) {
+  var out = this.nickname + ': ' + this.summary + '\n';
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+    var typeInfo = param.signature;
+
+    out += '\n  * ' + param.name + ' (' + typeInfo + '): ' + param.description;
+  }
+
+  if (typeof dontPrint === 'undefined') {
+    helpers.log(out);
+  }
+
+  return out;
+};
+
+Operation.prototype.getModelSignature = function (type, definitions) {
+  var isPrimitive, listType;
+
+  if (type instanceof Array) {
+    listType = true;
+    type = type[0];
+  }
+
+  // Convert undefined to string of 'undefined'
+  if (typeof type === 'undefined') {
+    type = 'undefined';
+    isPrimitive = true;
+
+  } else if (definitions[type]){
+    // a model def exists?
+    type = definitions[type]; /* Model */
+    isPrimitive = false;
+
+  } else if (this.getInlineModel(type)) {
+    type = this.getInlineModel(type); /* Model */
+    isPrimitive = false;
+
+  } else {
+    // We default to primitive
+    isPrimitive = true;
+  }
+
+  if (isPrimitive) {
+    if (listType) {
+      return 'Array[' + type + ']';
+    } else {
+      return type.toString();
+    }
+  } else {
+    if (listType) {
+      return 'Array[' + type.getMockSignature() + ']';
+    } else {
+      return type.getMockSignature();
+    }
+  }
+};
+
+Operation.prototype.supportHeaderParams = function () {
+  return true;
+};
+
+Operation.prototype.supportedSubmitMethods = function () {
+  return this.parent.supportedSubmitMethods;
+};
+
+Operation.prototype.getHeaderParams = function (args) {
+  var headers = this.setContentTypes(args, {});
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (typeof args[param.name] !== 'undefined') {
+      if (param.in === 'header') {
+        var value = args[param.name];
+
+        if (Array.isArray(value)) {
+          value = value.toString();
+        }
+
+        headers[param.name] = value;
+      }
+    }
+  }
+
+  return headers;
+};
+
+Operation.prototype.urlify = function (args) {
+  var formParams = {};
+  var requestUrl = this.path;
+  var querystring = ''; // grab params from the args, build the querystring along the way
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (typeof args[param.name] !== 'undefined') {
+      if (param.in === 'path') {
+        var reg = new RegExp('\{' + param.name + '\}', 'gi');
+        var value = args[param.name];
+
+        if (Array.isArray(value)) {
+          value = this.encodePathCollection(param.collectionFormat, param.name, value);
+        } else {
+          value = this.encodePathParam(value);
+        }
+
+        requestUrl = requestUrl.replace(reg, value);
+      } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
+        if (querystring === '') {
+          querystring += '?';
+        } else {
+          querystring += '&';
+        }
+
+        if (typeof param.collectionFormat !== 'undefined') {
+          var qp = args[param.name];
+
+          if (Array.isArray(qp)) {
+            querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);
+          } else {
+            querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
+          }
+        } else {
+          querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
+        }
+      } else if (param.in === 'formData') {
+        formParams[param.name] = args[param.name];
+      }
+    }
+  }
+  var url = this.scheme + '://' + this.host;
+
+  if (this.basePath !== '/') {
+    url += this.basePath;
+  }
+  return url + requestUrl + querystring;
+};
+
+Operation.prototype.getMissingParams = function (args) {
+  var missingParams = []; // check required params, track the ones that are missing
+  var i;
+
+  for (i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (param.required === true) {
+      if (typeof args[param.name] === 'undefined') {
+        missingParams = param.name;
+      }
+    }
+  }
+
+  return missingParams;
+};
+
+Operation.prototype.getBody = function (headers, args, opts) {
+  var formParams = {}, hasFormParams, body, key, value, hasBody = false;
+
+  // look at each param and put form params in an object
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+    if (typeof args[param.name] !== 'undefined') {
+      if (param.in === 'body') {
+        body = args[param.name];
+      } else if (param.in === 'formData') {
+        formParams[param.name] = args[param.name];
+        hasFormParams = true;
+      }
+    }
+    else {
+      if(param.in === 'body') {
+        hasBody = true;
+      }
+    }
+  }
+
+  // if body is null and hasBody is true, AND a JSON body is requested, send empty {}
+  if(hasBody && typeof body === 'undefined') {
+    var contentType = headers['Content-Type'];
+    if(contentType && contentType.indexOf('application/json') === 0) {
+      body = '{}';
+    }
+  }
+
+  var isMultiPart = false;
+  if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {
+    isMultiPart = true;
+  }
+
+  // handle form params
+  if (hasFormParams && !isMultiPart) {
+    var encoded = '';
+
+    for (key in formParams) {
+      value = formParams[key];
+
+      if (typeof value !== 'undefined') {
+        if (encoded !== '') {
+          encoded += '&';
+        }
+
+        encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
+      }
+    }
+
+    body = encoded;
+  } else if (isMultiPart) {
+    if (opts.useJQuery) {
+      var bodyParam = new FormData();
+
+      bodyParam.type = 'formData';
+
+      for (key in formParams) {
+        value = args[key];
+
+        if (typeof value !== 'undefined') {
+          // required for jquery file upload
+          if (value.type === 'file' && value.value) {
+            delete headers['Content-Type'];
+
+            bodyParam.append(key, value.value);
+          } else {
+            bodyParam.append(key, value);
+          }
+        }
+      }
+
+      body = bodyParam;
+    }
+  }
+
+  return body;
+};
+
+/**
+ * gets sample response for a single operation
+ **/
+Operation.prototype.getModelSampleJSON = function (type, models) {
+  var listType, sampleJson, innerType;
+  models = models || {};
+
+  listType = (type instanceof Array);
+  innerType = listType ? type[0] : type;
+
+  if(models[innerType]) {
+    sampleJson = models[innerType].createJSONSample();
+  } else if (this.getInlineModel(innerType)){
+    sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct
+  }
+
+
+  if (sampleJson) {
+    sampleJson = listType ? [sampleJson] : sampleJson;
+
+    if (typeof sampleJson === 'string') {
+      return sampleJson;
+    } else if (_.isObject(sampleJson)) {
+      var t = sampleJson;
+
+      if (sampleJson instanceof Array && sampleJson.length > 0) {
+        t = sampleJson[0];
+      }
+
+      if (t.nodeName && typeof t === 'Node') {
+        var xmlString = new XMLSerializer().serializeToString(t);
+
+        return this.formatXml(xmlString);
+      } else {
+        return JSON.stringify(sampleJson, null, 2);
+      }
+    } else {
+      return sampleJson;
+    }
+  }
+};
+
+/**
+ * legacy binding
+ **/
+Operation.prototype.do = function (args, opts, callback, error, parent) {
+  return this.execute(args, opts, callback, error, parent);
+};
+
+/**
+ * executes an operation
+ **/
+Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) {
+  var args = arg1 || {};
+  var opts = {}, success, error, deferred;
+
+  if (_.isObject(arg2)) {
+    opts = arg2;
+    success = arg3;
+    error = arg4;
+  }
+
+  if(this.client) {
+    opts.client = this.client;
+  }
+
+  // add the request interceptor from parent, if none sent from client
+  if(!opts.requestInterceptor && this.requestInterceptor ) {
+    opts.requestInterceptor = this.requestInterceptor ;
+  }
+
+  if(!opts.responseInterceptor && this.responseInterceptor) {
+    opts.responseInterceptor = this.responseInterceptor;
+  }
+
+  if (typeof arg2 === 'function') {
+    success = arg2;
+    error = arg3;
+  }
+
+  if (this.parent.usePromise) {
+    deferred = Q.defer();
+  } else {
+    success = (success || this.parent.defaultSuccessCallback || helpers.log);
+    error = (error || this.parent.defaultErrorCallback || helpers.log);
+  }
+
+
+  if (typeof opts.useJQuery === 'undefined') {
+    opts.useJQuery = this.useJQuery;
+  }
+
+  if (typeof opts.enableCookies === 'undefined') {
+    opts.enableCookies = this.enableCookies;
+  }
+
+  var missingParams = this.getMissingParams(args);
+
+  if (missingParams.length > 0) {
+    var message = 'missing required params: ' + missingParams;
+
+    helpers.fail(message);
+
+    if (this.parent.usePromise) {
+      deferred.reject(message);
+      return deferred.promise;
+    } else {
+      error(message, parent);
+      return {};
+    }
+  }
+
+  var allHeaders = this.getHeaderParams(args);
+  var contentTypeHeaders = this.setContentTypes(args, opts);
+  var headers = {}, attrname;
+
+  for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }
+  for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }
+
+  var body = this.getBody(contentTypeHeaders, args, opts);
+  var url = this.urlify(args);
+
+  if(url.indexOf('.{format}') > 0) {
+    if(headers) {
+      var format = headers.Accept || headers.accept;
+      if(format && format.indexOf('json') > 0) {
+        url = url.replace('.{format}', '.json');
+      }
+      else if(format && format.indexOf('xml') > 0) {
+        url = url.replace('.{format}', '.xml');
+      }
+    }
+  }
+
+  var obj = {
+    url: url,
+    method: this.method.toUpperCase(),
+    body: body,
+    enableCookies: opts.enableCookies,
+    useJQuery: opts.useJQuery,
+    deferred: deferred,
+    headers: headers,
+    clientAuthorizations: opts.clientAuthorizations,
+    on: {
+      response: function (response) {
+        if (deferred) {
+          deferred.resolve(response);
+          return deferred.promise;
+        } else {
+          return success(response, parent);
+        }
+      },
+      error: function (response) {
+        if (deferred) {
+          deferred.reject(response);
+          return deferred.promise;
+        } else {
+          return error(response, parent);
+        }
+      }
+    }
+  };
+
+  this.clientAuthorizations.apply(obj, this.operation.security);
+  if (opts.mock === true) {
+    return obj;
+  } else {
+    return new SwaggerHttp().execute(obj, opts);
+  }
+};
+
+function itemByPriority(col, itemPriority) {
+
+  // No priorities? return first...
+  if(_.isEmpty(itemPriority)) {
+    return col[0];
+  }
+
+  for (var i = 0, len = itemPriority.length; i < len; i++) {
+    if(col.indexOf(itemPriority[i]) > -1) {
+      return itemPriority[i];
+    }
+  }
+
+  // Otherwise return first
+  return col[0];
+}
+
+Operation.prototype.setContentTypes = function (args, opts) {
+  // default type
+  var allDefinedParams = this.parameters;
+  var body;
+  var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']);
+  var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']);
+  var definedFileParams = [];
+  var definedFormParams = [];
+  var headers = {};
+  var i;
+
+  // get params from the operation and set them in definedFileParams, definedFormParams, headers
+  for (i = 0; i < allDefinedParams.length; i++) {
+    var param = allDefinedParams[i];
+
+    if (param.in === 'formData') {
+      if (param.type === 'file') {
+        definedFileParams.push(param);
+      } else {
+        definedFormParams.push(param);
+      }
+    } else if (param.in === 'header' && opts) {
+      var key = param.name;
+      var headerValue = opts[param.name];
+
+      if (typeof opts[param.name] !== 'undefined') {
+        headers[key] = headerValue;
+      }
+    } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') {
+      body = args[param.name];
+    }
+  }
+
+  // if there's a body, need to set the consumes header via requestContentType
+  if (this.method === 'post' || this.method === 'put' || this.method === 'patch' ||
+      ((this.method === 'delete' || this.method === 'get') && body) ) {
+    if (opts.requestContentType) {
+      consumes = opts.requestContentType;
+    }
+    // if any form params, content type must be set
+    if (definedFormParams.length > 0) {
+      if (opts.requestContentType) {             // override if set
+        consumes = opts.requestContentType;
+      } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data
+        consumes = 'multipart/form-data';
+      } else {                                   // default to x-www-from-urlencoded
+        consumes = 'application/x-www-form-urlencoded';
+      }
+    }
+  }
+  else {
+    consumes = null;
+  }
+
+  if (consumes && this.consumes) {
+    if (this.consumes.indexOf(consumes) === -1) {
+      helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));
+    }
+  }
+
+  if (!this.matchesAccept(accepts)) {
+    helpers.log('server can\'t produce ' + accepts);
+  }
+
+  if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) {
+    headers['Content-Type'] = consumes;
+  }
+
+  if (accepts) {
+    headers.Accept = accepts;
+  }
+
+  return headers;
+};
+
+/**
+ * Returns true if the request accepts header matches anything in this.produces.
+ *  If this.produces contains * / *, ignore the accept header.
+ * @param {string=} accepts The client request accept header.
+ * @return {boolean}
+ */
+Operation.prototype.matchesAccept = function(accepts) {
+  // no accepts or produces, no problem!
+  if (!accepts || !this.produces) {
+    return true;
+  }
+  return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1;
+};
+
+Operation.prototype.asCurl = function (args1, args2) {
+  var opts = {mock: true};
+  if (typeof args2 === 'object') {
+    for (var argKey in args2) {
+      opts[argKey] = args2[argKey];
+    }
+  }
+  var obj = this.execute(args1, opts);
+
+  this.clientAuthorizations.apply(obj, this.operation.security);
+
+  var results = [];
+
+  results.push('-X ' + this.method.toUpperCase());
+
+  if (typeof obj.headers !== 'undefined') {
+    var key;
+
+    for (key in obj.headers) {
+      var value = obj.headers[key];
+      if(typeof value === 'string'){
+        value = value.replace(/\'/g, '\\u0027');
+      }
+      results.push('--header \'' + key + ': ' + value + '\'');
+    }
+  }
+
+  if (obj.body) {
+    var body;
+
+    if (_.isObject(obj.body)) {
+      body = JSON.stringify(obj.body);
+    } else {
+      body = obj.body;
+    }
+
+    results.push('-d \'' + body.replace(/\'/g, '\\u0027') + '\'');
+  }
+
+  return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\'';
+};
+
+Operation.prototype.encodePathCollection = function (type, name, value) {
+  var encoded = '';
+  var i;
+  var separator = '';
+
+  if (type === 'ssv') {
+    separator = '%20';
+  } else if (type === 'tsv') {
+    separator = '\\t';
+  } else if (type === 'pipes') {
+    separator = '|';
+  } else {
+    separator = ',';
+  }
+
+  for (i = 0; i < value.length; i++) {
+    if (i === 0) {
+      encoded = this.encodeQueryParam(value[i]);
+    } else {
+      encoded += separator + this.encodeQueryParam(value[i]);
+    }
+  }
+
+  return encoded;
+};
+
+Operation.prototype.encodeQueryCollection = function (type, name, value) {
+  var encoded = '';
+  var i;
+
+  if (type === 'default' || type === 'multi') {
+    for (i = 0; i < value.length; i++) {
+      if (i > 0) {encoded += '&';}
+
+      encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);
+    }
+  } else {
+    var separator = '';
+
+    if (type === 'csv') {
+      separator = ',';
+    } else if (type === 'ssv') {
+      separator = '%20';
+    } else if (type === 'tsv') {
+      separator = '\\t';
+    } else if (type === 'pipes') {
+      separator = '|';
+    } else if (type === 'brackets') {
+      for (i = 0; i < value.length; i++) {
+        if (i !== 0) {
+          encoded += '&';
+        }
+
+        encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]);
+      }
+    }
+
+    if (separator !== '') {
+      for (i = 0; i < value.length; i++) {
+        if (i === 0) {
+          encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]);
+        } else {
+          encoded += separator + this.encodeQueryParam(value[i]);
+        }
+      }
+    }
+  }
+
+  return encoded;
+};
+
+Operation.prototype.encodeQueryParam = function (arg) {
+  return encodeURIComponent(arg);
+};
+
+/**
+ * TODO revisit, might not want to leave '/'
+ **/
+Operation.prototype.encodePathParam = function (pathParam) {
+  return encodeURIComponent(pathParam);
+};
+
+},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isUndefined":150,"q":159}],11:[function(require,module,exports){
+'use strict';
+
+var OperationGroup = module.exports = function (tag, description, externalDocs, operation) {
+  this.description = description;
+  this.externalDocs = externalDocs;
+  this.name = tag;
+  this.operation = operation;
+  this.operationsArray = [];
+  this.path = tag;
+  this.tag = tag;
+};
+
+OperationGroup.prototype.sort = function () {
+
+};
+
+
+},{}],12:[function(require,module,exports){
+
+},{}],13:[function(require,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    draining = true;
+    var currentQueue;
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        var i = -1;
+        while (++i < len) {
+            currentQueue[i]();
+        }
+        len = queue.length;
+    }
+    draining = false;
+}
+process.nextTick = function (fun) {
+    queue.push(fun);
+    if (!draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+// TODO(shtylman)
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],14:[function(require,module,exports){
+(function (Buffer){
+(function () {
+  "use strict";
+
+  function btoa(str) {
+    var buffer
+      ;
+
+    if (str instanceof Buffer) {
+      buffer = str;
+    } else {
+      buffer = new Buffer(str.toString(), 'binary');
+    }
+
+    return buffer.toString('base64');
+  }
+
+  module.exports = btoa;
+}());
+
+}).call(this,require("buffer").Buffer)
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uICgpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZnVuY3Rpb24gYnRvYShzdHIpIHtcbiAgICB2YXIgYnVmZmVyXG4gICAgICA7XG5cbiAgICBpZiAoc3RyIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICBidWZmZXIgPSBzdHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IG5ldyBCdWZmZXIoc3RyLnRvU3RyaW5nKCksICdiaW5hcnknKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIG1vZHVsZS5leHBvcnRzID0gYnRvYTtcbn0oKSk7XG4iXX0=
+},{"buffer":15}],15:[function(require,module,exports){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+
+var base64 = require('base64-js')
+var ieee754 = require('ieee754')
+var isArray = require('is-array')
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ *     on objects.
+ *
+ *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *     incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = (function () {
+  function Bar () {}
+  try {
+    var arr = new Uint8Array(1)
+    arr.foo = function () { return 42 }
+    arr.constructor = Bar
+    return arr.foo() === 42 && // typed array instances can be augmented
+        arr.constructor === Bar && // constructor can be set
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+})()
+
+function kMaxLength () {
+  return Buffer.TYPED_ARRAY_SUPPORT
+    ? 0x7fffffff
+    : 0x3fffffff
+}
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (arg) {
+  if (!(this instanceof Buffer)) {
+    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+    if (arguments.length > 1) return new Buffer(arg, arguments[1])
+    return new Buffer(arg)
+  }
+
+  this.length = 0
+  this.parent = undefined
+
+  // Common case.
+  if (typeof arg === 'number') {
+    return fromNumber(this, arg)
+  }
+
+  // Slightly less common case.
+  if (typeof arg === 'string') {
+    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+  }
+
+  // Unusual.
+  return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < length; i++) {
+      that[i] = 0
+    }
+  }
+  return that
+}
+
+function fromString (that, string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+  // Assumption: byteLength() return value is always < kMaxLength.
+  var length = byteLength(string, encoding) | 0
+  that = allocate(that, length)
+
+  that.write(string, encoding)
+  return that
+}
+
+function fromObject (that, object) {
+  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+  if (isArray(object)) return fromArray(that, object)
+
+  if (object == null) {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (typeof ArrayBuffer !== 'undefined') {
+    if (object.buffer instanceof ArrayBuffer) {
+      return fromTypedArray(that, object)
+    }
+    if (object instanceof ArrayBuffer) {
+      return fromArrayBuffer(that, object)
+    }
+  }
+
+  if (object.length) return fromArrayLike(that, object)
+
+  return fromJsonObject(that, object)
+}
+
+function fromBuffer (that, buffer) {
+  var length = checked(buffer.length) | 0
+  that = allocate(that, length)
+  buffer.copy(that, 0, 0, length)
+  return that
+}
+
+function fromArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  // Truncating the elements is probably not what people expect from typed
+  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+  // of the old Buffer constructor.
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function fromArrayBuffer (that, array) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    array.byteLength
+    that = Buffer._augment(new Uint8Array(array))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that = fromTypedArray(that, new Uint8Array(array))
+  }
+  return that
+}
+
+function fromArrayLike (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject (that, object) {
+  var array
+  var length = 0
+
+  if (object.type === 'Buffer' && isArray(object.data)) {
+    array = object.data
+    length = checked(array.length) | 0
+  }
+  that = allocate(that, length)
+
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function allocate (that, length) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    that = Buffer._augment(new Uint8Array(length))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that.length = length
+    that._isBuffer = true
+  }
+
+  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+  if (fromPool) that.parent = rootParent
+
+  return that
+}
+
+function checked (length) {
+  // Note: cannot use `length < kMaxLength` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= kMaxLength()) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  var i = 0
+  var len = Math.min(x, y)
+  while (i < len) {
+    if (a[i] !== b[i]) break
+
+    ++i
+  }
+
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; i++) {
+      length += list[i].length
+    }
+  }
+
+  var buf = new Buffer(length)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+function byteLength (string, encoding) {
+  if (typeof string !== 'string') string = '' + string
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'binary':
+      // Deprecated
+      case 'raw':
+      case 'raws':
+        return len
+      case 'utf8':
+      case 'utf-8':
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+// pre-set for values that may exist in the future
+Buffer.prototype.length = undefined
+Buffer.prototype.parent = undefined
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start | 0
+  end = end === undefined || end === Infinity ? this.length : end | 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length | 0
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` is deprecated
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` is deprecated
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset | 0
+    if (isFinite(length)) {
+      length = length | 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  // legacy write(string, encoding, offset, length) - remove in v0.13
+  } else {
+    var swap = encoding
+    encoding = offset
+    offset = length | 0
+    length = swap
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'binary':
+        return binaryWrite(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = value
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = value
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = value
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; i--) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    // ascending copy from start
+    for (i = 0; i < len; i++) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), targetStart)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function fill (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function _augment (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array set method before overwriting
+  arr._set = arr.set
+
+  // deprecated
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.indexOf = BP.indexOf
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+},{"base64-js":16,"ieee754":17,"is-array":18}],16:[function(require,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+       'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+       var PLUS   = '+'.charCodeAt(0)
+       var SLASH  = '/'.charCodeAt(0)
+       var NUMBER = '0'.charCodeAt(0)
+       var LOWER  = 'a'.charCodeAt(0)
+       var UPPER  = 'A'.charCodeAt(0)
+       var PLUS_URL_SAFE = '-'.charCodeAt(0)
+       var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+       function decode (elt) {
+               var code = elt.charCodeAt(0)
+               if (code === PLUS ||
+                   code === PLUS_URL_SAFE)
+                       return 62 // '+'
+               if (code === SLASH ||
+                   code === SLASH_URL_SAFE)
+                       return 63 // '/'
+               if (code < NUMBER)
+                       return -1 //no match
+               if (code < NUMBER + 10)
+                       return code - NUMBER + 26 + 26
+               if (code < UPPER + 26)
+                       return code - UPPER
+               if (code < LOWER + 26)
+                       return code - LOWER + 26
+       }
+
+       function b64ToByteArray (b64) {
+               var i, j, l, tmp, placeHolders, arr
+
+               if (b64.length % 4 > 0) {
+                       throw new Error('Invalid string. Length must be a multiple of 4')
+               }
+
+               // the number of equal signs (place holders)
+               // if there are two placeholders, than the two characters before it
+               // represent one byte
+               // if there is only one, then the three characters before it represent 2 bytes
+               // this is just a cheap hack to not do indexOf twice
+               var len = b64.length
+               placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+               // base64 is 4/3 + up to two characters of the original data
+               arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+               // if there are placeholders, only get up to the last complete 4 chars
+               l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+               var L = 0
+
+               function push (v) {
+                       arr[L++] = v
+               }
+
+               for (i = 0, j = 0; i < l; i += 4, j += 3) {
+                       tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+                       push((tmp & 0xFF0000) >> 16)
+                       push((tmp & 0xFF00) >> 8)
+                       push(tmp & 0xFF)
+               }
+
+               if (placeHolders === 2) {
+                       tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+                       push(tmp & 0xFF)
+               } else if (placeHolders === 1) {
+                       tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+                       push((tmp >> 8) & 0xFF)
+                       push(tmp & 0xFF)
+               }
+
+               return arr
+       }
+
+       function uint8ToBase64 (uint8) {
+               var i,
+                       extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+                       output = "",
+                       temp, length
+
+               function encode (num) {
+                       return lookup.charAt(num)
+               }
+
+               function tripletToBase64 (num) {
+                       return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+               }
+
+               // go through the array every three bytes, we'll deal with trailing stuff later
+               for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+                       temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+                       output += tripletToBase64(temp)
+               }
+
+               // pad the end with zeros, but make sure to not forget the extra bytes
+               switch (extraBytes) {
+                       case 1:
+                               temp = uint8[uint8.length - 1]
+                               output += encode(temp >> 2)
+                               output += encode((temp << 4) & 0x3F)
+                               output += '=='
+                               break
+                       case 2:
+                               temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+                               output += encode(temp >> 10)
+                               output += encode((temp >> 4) & 0x3F)
+                               output += encode((temp << 2) & 0x3F)
+                               output += '='
+                               break
+               }
+
+               return output
+       }
+
+       exports.toByteArray = b64ToByteArray
+       exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],17:[function(require,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],18:[function(require,module,exports){
+
+/**
+ * isArray
+ */
+
+var isArray = Array.isArray;
+
+/**
+ * toString
+ */
+
+var str = Object.prototype.toString;
+
+/**
+ * Whether or not the given `val`
+ * is an array.
+ *
+ * example:
+ *
+ *        isArray([]);
+ *        // > true
+ *        isArray(arguments);
+ *        // > false
+ *        isArray('');
+ *        // > false
+ *
+ * @param {mixed} val
+ * @return {bool}
+ */
+
+module.exports = isArray || function (val) {
+  return !! val && '[object Array]' == str.call(val);
+};
+
+},{}],19:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+  if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+  for (var key in Emitter.prototype) {
+    obj[key] = Emitter.prototype[key];
+  }
+  return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+  this._callbacks = this._callbacks || {};
+  (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
+    .push(fn);
+  return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+  function on() {
+    this.off(event, on);
+    fn.apply(this, arguments);
+  }
+
+  on.fn = fn;
+  this.on(event, on);
+  return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+  this._callbacks = this._callbacks || {};
+
+  // all
+  if (0 == arguments.length) {
+    this._callbacks = {};
+    return this;
+  }
+
+  // specific event
+  var callbacks = this._callbacks['$' + event];
+  if (!callbacks) return this;
+
+  // remove all handlers
+  if (1 == arguments.length) {
+    delete this._callbacks['$' + event];
+    return this;
+  }
+
+  // remove specific handler
+  var cb;
+  for (var i = 0; i < callbacks.length; i++) {
+    cb = callbacks[i];
+    if (cb === fn || cb.fn === fn) {
+      callbacks.splice(i, 1);
+      break;
+    }
+  }
+  return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+  this._callbacks = this._callbacks || {};
+  var args = [].slice.call(arguments, 1)
+    , callbacks = this._callbacks['$' + event];
+
+  if (callbacks) {
+    callbacks = callbacks.slice(0);
+    for (var i = 0, len = callbacks.length; i < len; ++i) {
+      callbacks[i].apply(this, args);
+    }
+  }
+
+  return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+  this._callbacks = this._callbacks || {};
+  return this._callbacks['$' + event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+  return !! this.listeners(event).length;
+};
+
+},{}],20:[function(require,module,exports){
+/* jshint node: true */
+(function () {
+    "use strict";
+
+    function CookieAccessInfo(domain, path, secure, script) {
+        if (this instanceof CookieAccessInfo) {
+            this.domain = domain || undefined;
+            this.path = path || "/";
+            this.secure = !!secure;
+            this.script = !!script;
+            return this;
+        }
+        return new CookieAccessInfo(domain, path, secure, script);
+    }
+    exports.CookieAccessInfo = CookieAccessInfo;
+
+    function Cookie(cookiestr, request_domain, request_path) {
+        if (cookiestr instanceof Cookie) {
+            return cookiestr;
+        }
+        if (this instanceof Cookie) {
+            this.name = null;
+            this.value = null;
+            this.expiration_date = Infinity;
+            this.path = String(request_path || "/");
+            this.explicit_path = false;
+            this.domain = request_domain || null;
+            this.explicit_domain = false;
+            this.secure = false; //how to define default?
+            this.noscript = false; //httponly
+            if (cookiestr) {
+                this.parse(cookiestr, request_domain, request_path);
+            }
+            return this;
+        }
+        return new Cookie(cookiestr, request_domain, request_path);
+    }
+    exports.Cookie = Cookie;
+
+    Cookie.prototype.toString = function toString() {
+        var str = [this.name + "=" + this.value];
+        if (this.expiration_date !== Infinity) {
+            str.push("expires=" + (new Date(this.expiration_date)).toGMTString());
+        }
+        if (this.domain) {
+            str.push("domain=" + this.domain);
+        }
+        if (this.path) {
+            str.push("path=" + this.path);
+        }
+        if (this.secure) {
+            str.push("secure");
+        }
+        if (this.noscript) {
+            str.push("httponly");
+        }
+        return str.join("; ");
+    };
+
+    Cookie.prototype.toValueString = function toValueString() {
+        return this.name + "=" + this.value;
+    };
+
+    var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;
+    Cookie.prototype.parse = function parse(str, request_domain, request_path) {
+        if (this instanceof Cookie) {
+            var parts = str.split(";").filter(function (value) {
+                    return !!value;
+                }),
+                pair = parts[0].match(/([^=]+)=([\s\S]*)/),
+                key = pair[1],
+                value = pair[2],
+                i;
+            this.name = key;
+            this.value = value;
+
+            for (i = 1; i < parts.length; i += 1) {
+                pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/);
+                key = pair[1].trim().toLowerCase();
+                value = pair[2];
+                switch (key) {
+                case "httponly":
+                    this.noscript = true;
+                    break;
+                case "expires":
+                    this.expiration_date = value ?
+                            Number(Date.parse(value)) :
+                            Infinity;
+                    break;
+                case "path":
+                    this.path = value ?
+                            value.trim() :
+                            "";
+                    this.explicit_path = true;
+                    break;
+                case "domain":
+                    this.domain = value ?
+                            value.trim() :
+                            "";
+                    this.explicit_domain = !!this.domain;
+                    break;
+                case "secure":
+                    this.secure = true;
+                    break;
+                }
+            }
+
+            if (!this.explicit_path) {
+               this.path = request_path || "/";
+            }
+            if (!this.explicit_domain) {
+               this.domain = request_domain;
+            }
+
+            return this;
+        }
+        return new Cookie().parse(str, request_domain, request_path);
+    };
+
+    Cookie.prototype.matches = function matches(access_info) {
+        if (this.noscript && access_info.script ||
+                this.secure && !access_info.secure ||
+                !this.collidesWith(access_info)) {
+            return false;
+        }
+        return true;
+    };
+
+    Cookie.prototype.collidesWith = function collidesWith(access_info) {
+        if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
+            return false;
+        }
+        if (this.path && access_info.path.indexOf(this.path) !== 0) {
+            return false;
+        }
+        if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) {
+           return false;
+        }
+        var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,'');
+        var cookie_domain = this.domain && this.domain.replace(/^[\.]/,'');
+        if (cookie_domain === access_domain) {
+            return true;
+        }
+        if (cookie_domain) {
+            if (!this.explicit_domain) {
+                return false; // we already checked if the domains were exactly the same
+            }
+            var wildcard = access_domain.indexOf(cookie_domain);
+            if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) {
+                return false;
+            }
+            return true;
+        }
+        return true;
+    };
+
+    function CookieJar() {
+        var cookies, cookies_list, collidable_cookie;
+        if (this instanceof CookieJar) {
+            cookies = Object.create(null); //name: [Cookie]
+
+            this.setCookie = function setCookie(cookie, request_domain, request_path) {
+                var remove, i;
+                cookie = new Cookie(cookie, request_domain, request_path);
+                //Delete the cookie if the set is past the current time
+                remove = cookie.expiration_date <= Date.now();
+                if (cookies[cookie.name] !== undefined) {
+                    cookies_list = cookies[cookie.name];
+                    for (i = 0; i < cookies_list.length; i += 1) {
+                        collidable_cookie = cookies_list[i];
+                        if (collidable_cookie.collidesWith(cookie)) {
+                            if (remove) {
+                                cookies_list.splice(i, 1);
+                                if (cookies_list.length === 0) {
+                                    delete cookies[cookie.name];
+                                }
+                                return false;
+                            }
+                            cookies_list[i] = cookie;
+                            return cookie;
+                        }
+                    }
+                    if (remove) {
+                        return false;
+                    }
+                    cookies_list.push(cookie);
+                    return cookie;
+                }
+                if (remove) {
+                    return false;
+                }
+                cookies[cookie.name] = [cookie];
+                return cookies[cookie.name];
+            };
+            //returns a cookie
+            this.getCookie = function getCookie(cookie_name, access_info) {
+                var cookie, i;
+                cookies_list = cookies[cookie_name];
+                if (!cookies_list) {
+                    return;
+                }
+                for (i = 0; i < cookies_list.length; i += 1) {
+                    cookie = cookies_list[i];
+                    if (cookie.expiration_date <= Date.now()) {
+                        if (cookies_list.length === 0) {
+                            delete cookies[cookie.name];
+                        }
+                        continue;
+                    }
+
+                    if (cookie.matches(access_info)) {
+                        return cookie;
+                    }
+                }
+            };
+            //returns a list of cookies
+            this.getCookies = function getCookies(access_info) {
+                var matches = [], cookie_name, cookie;
+                for (cookie_name in cookies) {
+                    cookie = this.getCookie(cookie_name, access_info);
+                    if (cookie) {
+                        matches.push(cookie);
+                    }
+                }
+                matches.toString = function toString() {
+                    return matches.join(":");
+                };
+                matches.toValueString = function toValueString() {
+                    return matches.map(function (c) {
+                        return c.toValueString();
+                    }).join(';');
+                };
+                return matches;
+            };
+
+            return this;
+        }
+        return new CookieJar();
+    }
+    exports.CookieJar = CookieJar;
+
+    //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned.
+    CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) {
+        cookies = Array.isArray(cookies) ?
+                cookies :
+                cookies.split(cookie_str_splitter);
+        var successful = [],
+            i,
+            cookie;
+        cookies = cookies.map(function(item){
+            return new Cookie(item, request_domain, request_path);
+        });
+        for (i = 0; i < cookies.length; i += 1) {
+            cookie = cookies[i];
+            if (this.setCookie(cookie, request_domain, request_path)) {
+                successful.push(cookie);
+            }
+        }
+        return successful;
+    };
+}());
+
+},{}],21:[function(require,module,exports){
+'use strict';
+
+
+var yaml = require('./lib/js-yaml.js');
+
+
+module.exports = yaml;
+
+},{"./lib/js-yaml.js":22}],22:[function(require,module,exports){
+'use strict';
+
+
+var loader = require('./js-yaml/loader');
+var dumper = require('./js-yaml/dumper');
+
+
+function deprecated(name) {
+  return function () {
+    throw new Error('Function ' + name + ' is deprecated and cannot be used.');
+  };
+}
+
+
+module.exports.Type                = require('./js-yaml/type');
+module.exports.Schema              = require('./js-yaml/schema');
+module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');
+module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');
+module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');
+module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
+module.exports.load                = loader.load;
+module.exports.loadAll             = loader.loadAll;
+module.exports.safeLoad            = loader.safeLoad;
+module.exports.safeLoadAll         = loader.safeLoadAll;
+module.exports.dump                = dumper.dump;
+module.exports.safeDump            = dumper.safeDump;
+module.exports.YAMLException       = require('./js-yaml/exception');
+
+// Deprecated schema names from JS-YAML 2.0.x
+module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
+module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
+
+// Deprecated functions from JS-YAML 1.x.x
+module.exports.scan           = deprecated('scan');
+module.exports.parse          = deprecated('parse');
+module.exports.compose        = deprecated('compose');
+module.exports.addConstructor = deprecated('addConstructor');
+
+},{"./js-yaml/dumper":24,"./js-yaml/exception":25,"./js-yaml/loader":26,"./js-yaml/schema":28,"./js-yaml/schema/core":29,"./js-yaml/schema/default_full":30,"./js-yaml/schema/default_safe":31,"./js-yaml/schema/failsafe":32,"./js-yaml/schema/json":33,"./js-yaml/type":34}],23:[function(require,module,exports){
+'use strict';
+
+
+function isNothing(subject) {
+  return (typeof subject === 'undefined') || (subject === null);
+}
+
+
+function isObject(subject) {
+  return (typeof subject === 'object') && (subject !== null);
+}
+
+
+function toArray(sequence) {
+  if (Array.isArray(sequence)) return sequence;
+  else if (isNothing(sequence)) return [];
+
+  return [ sequence ];
+}
+
+
+function extend(target, source) {
+  var index, length, key, sourceKeys;
+
+  if (source) {
+    sourceKeys = Object.keys(source);
+
+    for (index = 0, length = sourceKeys.length; index < length; index += 1) {
+      key = sourceKeys[index];
+      target[key] = source[key];
+    }
+  }
+
+  return target;
+}
+
+
+function repeat(string, count) {
+  var result = '', cycle;
+
+  for (cycle = 0; cycle < count; cycle += 1) {
+    result += string;
+  }
+
+  return result;
+}
+
+
+function isNegativeZero(number) {
+  return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
+}
+
+
+module.exports.isNothing      = isNothing;
+module.exports.isObject       = isObject;
+module.exports.toArray        = toArray;
+module.exports.repeat         = repeat;
+module.exports.isNegativeZero = isNegativeZero;
+module.exports.extend         = extend;
+
+},{}],24:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable no-use-before-define*/
+
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+
+var _toString       = Object.prototype.toString;
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+var CHAR_TAB                  = 0x09; /* Tab */
+var CHAR_LINE_FEED            = 0x0A; /* LF */
+var CHAR_CARRIAGE_RETURN      = 0x0D; /* CR */
+var CHAR_SPACE                = 0x20; /* Space */
+var CHAR_EXCLAMATION          = 0x21; /* ! */
+var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
+var CHAR_SHARP                = 0x23; /* # */
+var CHAR_PERCENT              = 0x25; /* % */
+var CHAR_AMPERSAND            = 0x26; /* & */
+var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
+var CHAR_ASTERISK             = 0x2A; /* * */
+var CHAR_COMMA                = 0x2C; /* , */
+var CHAR_MINUS                = 0x2D; /* - */
+var CHAR_COLON                = 0x3A; /* : */
+var CHAR_GREATER_THAN         = 0x3E; /* > */
+var CHAR_QUESTION             = 0x3F; /* ? */
+var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
+var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
+var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
+var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
+var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
+var CHAR_VERTICAL_LINE        = 0x7C; /* | */
+var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
+
+var ESCAPE_SEQUENCES = {};
+
+ESCAPE_SEQUENCES[0x00]   = '\\0';
+ESCAPE_SEQUENCES[0x07]   = '\\a';
+ESCAPE_SEQUENCES[0x08]   = '\\b';
+ESCAPE_SEQUENCES[0x09]   = '\\t';
+ESCAPE_SEQUENCES[0x0A]   = '\\n';
+ESCAPE_SEQUENCES[0x0B]   = '\\v';
+ESCAPE_SEQUENCES[0x0C]   = '\\f';
+ESCAPE_SEQUENCES[0x0D]   = '\\r';
+ESCAPE_SEQUENCES[0x1B]   = '\\e';
+ESCAPE_SEQUENCES[0x22]   = '\\"';
+ESCAPE_SEQUENCES[0x5C]   = '\\\\';
+ESCAPE_SEQUENCES[0x85]   = '\\N';
+ESCAPE_SEQUENCES[0xA0]   = '\\_';
+ESCAPE_SEQUENCES[0x2028] = '\\L';
+ESCAPE_SEQUENCES[0x2029] = '\\P';
+
+var DEPRECATED_BOOLEANS_SYNTAX = [
+  'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
+  'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
+];
+
+function compileStyleMap(schema, map) {
+  var result, keys, index, length, tag, style, type;
+
+  if (map === null) return {};
+
+  result = {};
+  keys = Object.keys(map);
+
+  for (index = 0, length = keys.length; index < length; index += 1) {
+    tag = keys[index];
+    style = String(map[tag]);
+
+    if (tag.slice(0, 2) === '!!') {
+      tag = 'tag:yaml.org,2002:' + tag.slice(2);
+    }
+
+    type = schema.compiledTypeMap[tag];
+
+    if (type && _hasOwnProperty.call(type.styleAliases, style)) {
+      style = type.styleAliases[style];
+    }
+
+    result[tag] = style;
+  }
+
+  return result;
+}
+
+function encodeHex(character) {
+  var string, handle, length;
+
+  string = character.toString(16).toUpperCase();
+
+  if (character <= 0xFF) {
+    handle = 'x';
+    length = 2;
+  } else if (character <= 0xFFFF) {
+    handle = 'u';
+    length = 4;
+  } else if (character <= 0xFFFFFFFF) {
+    handle = 'U';
+    length = 8;
+  } else {
+    throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
+  }
+
+  return '\\' + handle + common.repeat('0', length - string.length) + string;
+}
+
+function State(options) {
+  this.schema      = options['schema'] || DEFAULT_FULL_SCHEMA;
+  this.indent      = Math.max(1, (options['indent'] || 2));
+  this.skipInvalid = options['skipInvalid'] || false;
+  this.flowLevel   = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
+  this.styleMap    = compileStyleMap(this.schema, options['styles'] || null);
+  this.sortKeys    = options['sortKeys'] || false;
+  this.lineWidth   = options['lineWidth'] || 80;
+  this.noRefs      = options['noRefs'] || false;
+
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.explicitTypes = this.schema.compiledExplicit;
+
+  this.tag = null;
+  this.result = '';
+
+  this.duplicates = [];
+  this.usedDuplicates = null;
+}
+
+function indentString(string, spaces) {
+  var ind = common.repeat(' ', spaces),
+      position = 0,
+      next = -1,
+      result = '',
+      line,
+      length = string.length;
+
+  while (position < length) {
+    next = string.indexOf('\n', position);
+    if (next === -1) {
+      line = string.slice(position);
+      position = length;
+    } else {
+      line = string.slice(position, next + 1);
+      position = next + 1;
+    }
+
+    if (line.length && line !== '\n') result += ind;
+
+    result += line;
+  }
+
+  return result;
+}
+
+function generateNextLine(state, level) {
+  return '\n' + common.repeat(' ', state.indent * level);
+}
+
+function testImplicitResolving(state, str) {
+  var index, length, type;
+
+  for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
+    type = state.implicitTypes[index];
+
+    if (type.resolve(str)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+function StringBuilder(source) {
+  this.source = source;
+  this.result = '';
+  this.checkpoint = 0;
+}
+
+StringBuilder.prototype.takeUpTo = function (position) {
+  var er;
+
+  if (position < this.checkpoint) {
+    er = new Error('position should be > checkpoint');
+    er.position = position;
+    er.checkpoint = this.checkpoint;
+    throw er;
+  }
+
+  this.result += this.source.slice(this.checkpoint, position);
+  this.checkpoint = position;
+  return this;
+};
+
+StringBuilder.prototype.escapeChar = function () {
+  var character, esc;
+
+  character = this.source.charCodeAt(this.checkpoint);
+  esc = ESCAPE_SEQUENCES[character] || encodeHex(character);
+  this.result += esc;
+  this.checkpoint += 1;
+
+  return this;
+};
+
+StringBuilder.prototype.finish = function () {
+  if (this.source.length > this.checkpoint) {
+    this.takeUpTo(this.source.length);
+  }
+};
+
+function writeScalar(state, object, level, iskey) {
+  var simple, first, spaceWrap, folded, literal, single, double,
+      sawLineFeed, linePosition, longestLine, indent, max, character,
+      position, escapeSeq, hexEsc, previous, lineLength, modifier,
+      trailingLineBreaks, result;
+
+  if (object.length === 0) {
+    state.dump = "''";
+    return;
+  }
+
+  if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(object) !== -1) {
+    state.dump = "'" + object + "'";
+    return;
+  }
+
+  simple = true;
+  first = object.length ? object.charCodeAt(0) : 0;
+  spaceWrap = (CHAR_SPACE === first ||
+               CHAR_SPACE === object.charCodeAt(object.length - 1));
+
+  // Simplified check for restricted first characters
+  // http://www.yaml.org/spec/1.2/spec.html#ns-plain-first%28c%29
+  if (CHAR_MINUS         === first ||
+      CHAR_QUESTION      === first ||
+      CHAR_COMMERCIAL_AT === first ||
+      CHAR_GRAVE_ACCENT  === first) {
+    simple = false;
+  }
+
+  // Can only use > and | if not wrapped in spaces or is not a key.
+  // Also, don't use if in flow mode.
+  if (spaceWrap || (state.flowLevel > -1 && state.flowLevel <= level)) {
+    if (spaceWrap) simple = false;
+
+    folded = false;
+    literal = false;
+  } else {
+    folded = !iskey;
+    literal = !iskey;
+  }
+
+  single = true;
+  double = new StringBuilder(object);
+
+  sawLineFeed = false;
+  linePosition = 0;
+  longestLine = 0;
+
+  indent = state.indent * level;
+  max = state.lineWidth;
+
+  // Replace -1 with biggest ingeger number according to
+  // http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
+  if (max === -1) max = 9007199254740991;
+
+  if (indent < 40) max -= indent;
+  else max = 40;
+
+  for (position = 0; position < object.length; position++) {
+    character = object.charCodeAt(position);
+    if (simple) {
+      // Characters that can never appear in the simple scalar
+      if (!simpleChar(character)) {
+        simple = false;
+      } else {
+        // Still simple.  If we make it all the way through like
+        // this, then we can just dump the string as-is.
+        continue;
+      }
+    }
+
+    if (single && character === CHAR_SINGLE_QUOTE) {
+      single = false;
+    }
+
+    escapeSeq = ESCAPE_SEQUENCES[character];
+    hexEsc = needsHexEscape(character);
+
+    if (!escapeSeq && !hexEsc) {
+      continue;
+    }
+
+    if (character !== CHAR_LINE_FEED &&
+        character !== CHAR_DOUBLE_QUOTE &&
+        character !== CHAR_SINGLE_QUOTE) {
+      folded = false;
+      literal = false;
+    } else if (character === CHAR_LINE_FEED) {
+      sawLineFeed = true;
+      single = false;
+      if (position > 0) {
+        previous = object.charCodeAt(position - 1);
+        if (previous === CHAR_SPACE) {
+          literal = false;
+          folded = false;
+        }
+      }
+      if (folded) {
+        lineLength = position - linePosition;
+        linePosition = position;
+        if (lineLength > longestLine) longestLine = lineLength;
+      }
+    }
+
+    if (character !== CHAR_DOUBLE_QUOTE) single = false;
+
+    double.takeUpTo(position);
+    double.escapeChar();
+  }
+
+  if (simple && testImplicitResolving(state, object)) simple = false;
+
+  modifier = '';
+  if (folded || literal) {
+    trailingLineBreaks = 0;
+    if (object.charCodeAt(object.length - 1) === CHAR_LINE_FEED) {
+      trailingLineBreaks += 1;
+      if (object.charCodeAt(object.length - 2) === CHAR_LINE_FEED) {
+        trailingLineBreaks += 1;
+      }
+    }
+
+    if (trailingLineBreaks === 0) modifier = '-';
+    else if (trailingLineBreaks === 2) modifier = '+';
+  }
+
+  if (literal && longestLine < max || state.tag !== null) {
+    folded = false;
+  }
+
+  // If it's literally one line, then don't bother with the literal.
+  // We may still want to do a fold, though, if it's a super long line.
+  if (!sawLineFeed) literal = false;
+
+  if (simple) {
+    state.dump = object;
+  } else if (single) {
+    state.dump = '\'' + object + '\'';
+  } else if (folded) {
+    result = fold(object, max);
+    state.dump = '>' + modifier + '\n' + indentString(result, indent);
+  } else if (literal) {
+    if (!modifier) object = object.replace(/\n$/, '');
+    state.dump = '|' + modifier + '\n' + indentString(object, indent);
+  } else if (double) {
+    double.finish();
+    state.dump = '"' + double.result + '"';
+  } else {
+    throw new Error('Failed to dump scalar value');
+  }
+
+  return;
+}
+
+// The `trailing` var is a regexp match of any trailing `\n` characters.
+//
+// There are three cases we care about:
+//
+// 1. One trailing `\n` on the string.  Just use `|` or `>`.
+//    This is the assumed default. (trailing = null)
+// 2. No trailing `\n` on the string.  Use `|-` or `>-` to "chomp" the end.
+// 3. More than one trailing `\n` on the string.  Use `|+` or `>+`.
+//
+// In the case of `>+`, these line breaks are *not* doubled (like the line
+// breaks within the string), so it's important to only end with the exact
+// same number as we started.
+function fold(object, max) {
+  var result = '',
+      position = 0,
+      length = object.length,
+      trailing = /\n+$/.exec(object),
+      newLine;
+
+  if (trailing) {
+    length = trailing.index + 1;
+  }
+
+  while (position < length) {
+    newLine = object.indexOf('\n', position);
+    if (newLine > length || newLine === -1) {
+      if (result) result += '\n\n';
+      result += foldLine(object.slice(position, length), max);
+      position = length;
+
+    } else {
+      if (result) result += '\n\n';
+      result += foldLine(object.slice(position, newLine), max);
+      position = newLine + 1;
+    }
+  }
+
+  if (trailing && trailing[0] !== '\n') result += trailing[0];
+
+  return result;
+}
+
+function foldLine(line, max) {
+  if (line === '') return line;
+
+  var foldRe = /[^\s] [^\s]/g,
+      result = '',
+      prevMatch = 0,
+      foldStart = 0,
+      match = foldRe.exec(line),
+      index,
+      foldEnd,
+      folded;
+
+  while (match) {
+    index = match.index;
+
+    // when we cross the max len, if the previous match would've
+    // been ok, use that one, and carry on.  If there was no previous
+    // match on this fold section, then just have a long line.
+    if (index - foldStart > max) {
+      if (prevMatch !== foldStart) foldEnd = prevMatch;
+      else foldEnd = index;
+
+      if (result) result += '\n';
+      folded = line.slice(foldStart, foldEnd);
+      result += folded;
+      foldStart = foldEnd + 1;
+    }
+    prevMatch = index + 1;
+    match = foldRe.exec(line);
+  }
+
+  if (result) result += '\n';
+
+  // if we end up with one last word at the end, then the last bit might
+  // be slightly bigger than we wanted, because we exited out of the loop.
+  if (foldStart !== prevMatch && line.length - foldStart > max) {
+    result += line.slice(foldStart, prevMatch) + '\n' +
+              line.slice(prevMatch + 1);
+  } else {
+    result += line.slice(foldStart);
+  }
+
+  return result;
+}
+
+// Returns true if character can be found in a simple scalar
+function simpleChar(character) {
+  return CHAR_TAB                  !== character &&
+         CHAR_LINE_FEED            !== character &&
+         CHAR_CARRIAGE_RETURN      !== character &&
+         CHAR_COMMA                !== character &&
+         CHAR_LEFT_SQUARE_BRACKET  !== character &&
+         CHAR_RIGHT_SQUARE_BRACKET !== character &&
+         CHAR_LEFT_CURLY_BRACKET   !== character &&
+         CHAR_RIGHT_CURLY_BRACKET  !== character &&
+         CHAR_SHARP                !== character &&
+         CHAR_AMPERSAND            !== character &&
+         CHAR_ASTERISK             !== character &&
+         CHAR_EXCLAMATION          !== character &&
+         CHAR_VERTICAL_LINE        !== character &&
+         CHAR_GREATER_THAN         !== character &&
+         CHAR_SINGLE_QUOTE         !== character &&
+         CHAR_DOUBLE_QUOTE         !== character &&
+         CHAR_PERCENT              !== character &&
+         CHAR_COLON                !== character &&
+         !ESCAPE_SEQUENCES[character]            &&
+         !needsHexEscape(character);
+}
+
+// Returns true if the character code needs to be escaped.
+function needsHexEscape(character) {
+  return !((0x00020 <= character && character <= 0x00007E) ||
+           (character === 0x00085)                         ||
+           (0x000A0 <= character && character <= 0x00D7FF) ||
+           (0x0E000 <= character && character <= 0x00FFFD) ||
+           (0x10000 <= character && character <= 0x10FFFF));
+}
+
+function writeFlowSequence(state, level, object) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level, object[index], false, false)) {
+      if (index !== 0) _result += ', ';
+      _result += state.dump;
+    }
+  }
+
+  state.tag = _tag;
+  state.dump = '[' + _result + ']';
+}
+
+function writeBlockSequence(state, level, object, compact) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level + 1, object[index], true, true)) {
+      if (!compact || index !== 0) {
+        _result += generateNextLine(state, level);
+      }
+      _result += '- ' + state.dump;
+    }
+  }
+
+  state.tag = _tag;
+  state.dump = _result || '[]'; // Empty sequence if no valid values.
+}
+
+function writeFlowMapping(state, level, object) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      pairBuffer;
+
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
+
+    if (index !== 0) pairBuffer += ', ';
+
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
+
+    if (!writeNode(state, level, objectKey, false, false)) {
+      continue; // Skip this pair because of invalid key;
+    }
+
+    if (state.dump.length > 1024) pairBuffer += '? ';
+
+    pairBuffer += state.dump + ': ';
+
+    if (!writeNode(state, level, objectValue, false, false)) {
+      continue; // Skip this pair because of invalid value.
+    }
+
+    pairBuffer += state.dump;
+
+    // Both key and value are valid.
+    _result += pairBuffer;
+  }
+
+  state.tag = _tag;
+  state.dump = '{' + _result + '}';
+}
+
+function writeBlockMapping(state, level, object, compact) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      explicitPair,
+      pairBuffer;
+
+  // Allow sorting keys so that the output file is deterministic
+  if (state.sortKeys === true) {
+    // Default sorting
+    objectKeyList.sort();
+  } else if (typeof state.sortKeys === 'function') {
+    // Custom sort function
+    objectKeyList.sort(state.sortKeys);
+  } else if (state.sortKeys) {
+    // Something is wrong
+    throw new YAMLException('sortKeys must be a boolean or a function');
+  }
+
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
+
+    if (!compact || index !== 0) {
+      pairBuffer += generateNextLine(state, level);
+    }
+
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
+
+    if (!writeNode(state, level + 1, objectKey, true, true, true)) {
+      continue; // Skip this pair because of invalid key.
+    }
+
+    explicitPair = (state.tag !== null && state.tag !== '?') ||
+                   (state.dump && state.dump.length > 1024);
+
+    if (explicitPair) {
+      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
+        pairBuffer += '?';
+      } else {
+        pairBuffer += '? ';
+      }
+    }
+
+    pairBuffer += state.dump;
+
+    if (explicitPair) {
+      pairBuffer += generateNextLine(state, level);
+    }
+
+    if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
+      continue; // Skip this pair because of invalid value.
+    }
+
+    if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
+      pairBuffer += ':';
+    } else {
+      pairBuffer += ': ';
+    }
+
+    pairBuffer += state.dump;
+
+    // Both key and value are valid.
+    _result += pairBuffer;
+  }
+
+  state.tag = _tag;
+  state.dump = _result || '{}'; // Empty mapping if no valid pairs.
+}
+
+function detectType(state, object, explicit) {
+  var _result, typeList, index, length, type, style;
+
+  typeList = explicit ? state.explicitTypes : state.implicitTypes;
+
+  for (index = 0, length = typeList.length; index < length; index += 1) {
+    type = typeList[index];
+
+    if ((type.instanceOf  || type.predicate) &&
+        (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
+        (!type.predicate  || type.predicate(object))) {
+
+      state.tag = explicit ? type.tag : '?';
+
+      if (type.represent) {
+        style = state.styleMap[type.tag] || type.defaultStyle;
+
+        if (_toString.call(type.represent) === '[object Function]') {
+          _result = type.represent(object, style);
+        } else if (_hasOwnProperty.call(type.represent, style)) {
+          _result = type.represent[style](object, style);
+        } else {
+          throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
+        }
+
+        state.dump = _result;
+      }
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// Serializes `object` and writes it to global `result`.
+// Returns true on success, or false on invalid object.
+//
+function writeNode(state, level, object, block, compact, iskey) {
+  state.tag = null;
+  state.dump = object;
+
+  if (!detectType(state, object, false)) {
+    detectType(state, object, true);
+  }
+
+  var type = _toString.call(state.dump);
+
+  if (block) {
+    block = (state.flowLevel < 0 || state.flowLevel > level);
+  }
+
+  var objectOrArray = type === '[object Object]' || type === '[object Array]',
+      duplicateIndex,
+      duplicate;
+
+  if (objectOrArray) {
+    duplicateIndex = state.duplicates.indexOf(object);
+    duplicate = duplicateIndex !== -1;
+  }
+
+  if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
+    compact = false;
+  }
+
+  if (duplicate && state.usedDuplicates[duplicateIndex]) {
+    state.dump = '*ref_' + duplicateIndex;
+  } else {
+    if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
+      state.usedDuplicates[duplicateIndex] = true;
+    }
+    if (type === '[object Object]') {
+      if (block && (Object.keys(state.dump).length !== 0)) {
+        writeBlockMapping(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
+        }
+      } else {
+        writeFlowMapping(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
+        }
+      }
+    } else if (type === '[object Array]') {
+      if (block && (state.dump.length !== 0)) {
+        writeBlockSequence(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
+        }
+      } else {
+        writeFlowSequence(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
+        }
+      }
+    } else if (type === '[object String]') {
+      if (state.tag !== '?') {
+        writeScalar(state, state.dump, level, iskey);
+      }
+    } else {
+      if (state.skipInvalid) return false;
+      throw new YAMLException('unacceptable kind of an object to dump ' + type);
+    }
+
+    if (state.tag !== null && state.tag !== '?') {
+      state.dump = '!<' + state.tag + '> ' + state.dump;
+    }
+  }
+
+  return true;
+}
+
+function getDuplicateReferences(object, state) {
+  var objects = [],
+      duplicatesIndexes = [],
+      index,
+      length;
+
+  inspectNode(object, objects, duplicatesIndexes);
+
+  for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
+    state.duplicates.push(objects[duplicatesIndexes[index]]);
+  }
+  state.usedDuplicates = new Array(length);
+}
+
+function inspectNode(object, objects, duplicatesIndexes) {
+  var objectKeyList,
+      index,
+      length;
+
+  if (object !== null && typeof object === 'object') {
+    index = objects.indexOf(object);
+    if (index !== -1) {
+      if (duplicatesIndexes.indexOf(index) === -1) {
+        duplicatesIndexes.push(index);
+      }
+    } else {
+      objects.push(object);
+
+      if (Array.isArray(object)) {
+        for (index = 0, length = object.length; index < length; index += 1) {
+          inspectNode(object[index], objects, duplicatesIndexes);
+        }
+      } else {
+        objectKeyList = Object.keys(object);
+
+        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+          inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
+        }
+      }
+    }
+  }
+}
+
+function dump(input, options) {
+  options = options || {};
+
+  var state = new State(options);
+
+  if (!state.noRefs) getDuplicateReferences(input, state);
+
+  if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
+
+  return '';
+}
+
+function safeDump(input, options) {
+  return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+module.exports.dump     = dump;
+module.exports.safeDump = safeDump;
+
+},{"./common":23,"./exception":25,"./schema/default_full":30,"./schema/default_safe":31}],25:[function(require,module,exports){
+// YAML error class. http://stackoverflow.com/questions/8458984
+//
+'use strict';
+
+function YAMLException(reason, mark) {
+  // Super constructor
+  Error.call(this);
+
+  // Include stack trace in error object
+  if (Error.captureStackTrace) {
+    // Chrome and NodeJS
+    Error.captureStackTrace(this, this.constructor);
+  } else {
+    // FF, IE 10+ and Safari 6+. Fallback for others
+    this.stack = (new Error()).stack || '';
+  }
+
+  this.name = 'YAMLException';
+  this.reason = reason;
+  this.mark = mark;
+  this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
+}
+
+
+// Inherit from Error
+YAMLException.prototype = Object.create(Error.prototype);
+YAMLException.prototype.constructor = YAMLException;
+
+
+YAMLException.prototype.toString = function toString(compact) {
+  var result = this.name + ': ';
+
+  result += this.reason || '(unknown reason)';
+
+  if (!compact && this.mark) {
+    result += ' ' + this.mark.toString();
+  }
+
+  return result;
+};
+
+
+module.exports = YAMLException;
+
+},{}],26:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable max-len,no-use-before-define*/
+
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var Mark                = require('./mark');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+
+var CONTEXT_FLOW_IN   = 1;
+var CONTEXT_FLOW_OUT  = 2;
+var CONTEXT_BLOCK_IN  = 3;
+var CONTEXT_BLOCK_OUT = 4;
+
+
+var CHOMPING_CLIP  = 1;
+var CHOMPING_STRIP = 2;
+var CHOMPING_KEEP  = 3;
+
+
+var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
+var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
+var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
+var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
+var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
+
+
+function is_EOL(c) {
+  return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
+}
+
+function is_WHITE_SPACE(c) {
+  return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
+}
+
+function is_WS_OR_EOL(c) {
+  return (c === 0x09/* Tab */) ||
+         (c === 0x20/* Space */) ||
+         (c === 0x0A/* LF */) ||
+         (c === 0x0D/* CR */);
+}
+
+function is_FLOW_INDICATOR(c) {
+  return c === 0x2C/* , */ ||
+         c === 0x5B/* [ */ ||
+         c === 0x5D/* ] */ ||
+         c === 0x7B/* { */ ||
+         c === 0x7D/* } */;
+}
+
+function fromHexCode(c) {
+  var lc;
+
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
+  }
+
+  /*eslint-disable no-bitwise*/
+  lc = c | 0x20;
+
+  if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
+    return lc - 0x61 + 10;
+  }
+
+  return -1;
+}
+
+function escapedHexLen(c) {
+  if (c === 0x78/* x */) { return 2; }
+  if (c === 0x75/* u */) { return 4; }
+  if (c === 0x55/* U */) { return 8; }
+  return 0;
+}
+
+function fromDecimalCode(c) {
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
+  }
+
+  return -1;
+}
+
+function simpleEscapeSequence(c) {
+  return (c === 0x30/* 0 */) ? '\x00' :
+        (c === 0x61/* a */) ? '\x07' :
+        (c === 0x62/* b */) ? '\x08' :
+        (c === 0x74/* t */) ? '\x09' :
+        (c === 0x09/* Tab */) ? '\x09' :
+        (c === 0x6E/* n */) ? '\x0A' :
+        (c === 0x76/* v */) ? '\x0B' :
+        (c === 0x66/* f */) ? '\x0C' :
+        (c === 0x72/* r */) ? '\x0D' :
+        (c === 0x65/* e */) ? '\x1B' :
+        (c === 0x20/* Space */) ? ' ' :
+        (c === 0x22/* " */) ? '\x22' :
+        (c === 0x2F/* / */) ? '/' :
+        (c === 0x5C/* \ */) ? '\x5C' :
+        (c === 0x4E/* N */) ? '\x85' :
+        (c === 0x5F/* _ */) ? '\xA0' :
+        (c === 0x4C/* L */) ? '\u2028' :
+        (c === 0x50/* P */) ? '\u2029' : '';
+}
+
+function charFromCodepoint(c) {
+  if (c <= 0xFFFF) {
+    return String.fromCharCode(c);
+  }
+  // Encode UTF-16 surrogate pair
+  // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
+  return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
+                             ((c - 0x010000) & 0x03FF) + 0xDC00);
+}
+
+var simpleEscapeCheck = new Array(256); // integer, for fast access
+var simpleEscapeMap = new Array(256);
+for (var i = 0; i < 256; i++) {
+  simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
+  simpleEscapeMap[i] = simpleEscapeSequence(i);
+}
+
+
+function State(input, options) {
+  this.input = input;
+
+  this.filename  = options['filename']  || null;
+  this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;
+  this.onWarning = options['onWarning'] || null;
+  this.legacy    = options['legacy']    || false;
+  this.json      = options['json']      || false;
+  this.listener  = options['listener']  || null;
+
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.typeMap       = this.schema.compiledTypeMap;
+
+  this.length     = input.length;
+  this.position   = 0;
+  this.line       = 0;
+  this.lineStart  = 0;
+  this.lineIndent = 0;
+
+  this.documents = [];
+
+  /*
+  this.version;
+  this.checkLineBreaks;
+  this.tagMap;
+  this.anchorMap;
+  this.tag;
+  this.anchor;
+  this.kind;
+  this.result;*/
+
+}
+
+
+function generateError(state, message) {
+  return new YAMLException(
+    message,
+    new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
+}
+
+function throwError(state, message) {
+  throw generateError(state, message);
+}
+
+function throwWarning(state, message) {
+  if (state.onWarning) {
+    state.onWarning.call(null, generateError(state, message));
+  }
+}
+
+
+var directiveHandlers = {
+
+  YAML: function handleYamlDirective(state, name, args) {
+
+    var match, major, minor;
+
+    if (state.version !== null) {
+      throwError(state, 'duplication of %YAML directive');
+    }
+
+    if (args.length !== 1) {
+      throwError(state, 'YAML directive accepts exactly one argument');
+    }
+
+    match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
+
+    if (match === null) {
+      throwError(state, 'ill-formed argument of the YAML directive');
+    }
+
+    major = parseInt(match[1], 10);
+    minor = parseInt(match[2], 10);
+
+    if (major !== 1) {
+      throwError(state, 'unacceptable YAML version of the document');
+    }
+
+    state.version = args[0];
+    state.checkLineBreaks = (minor < 2);
+
+    if (minor !== 1 && minor !== 2) {
+      throwWarning(state, 'unsupported YAML version of the document');
+    }
+  },
+
+  TAG: function handleTagDirective(state, name, args) {
+
+    var handle, prefix;
+
+    if (args.length !== 2) {
+      throwError(state, 'TAG directive accepts exactly two arguments');
+    }
+
+    handle = args[0];
+    prefix = args[1];
+
+    if (!PATTERN_TAG_HANDLE.test(handle)) {
+      throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
+    }
+
+    if (_hasOwnProperty.call(state.tagMap, handle)) {
+      throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
+    }
+
+    if (!PATTERN_TAG_URI.test(prefix)) {
+      throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
+    }
+
+    state.tagMap[handle] = prefix;
+  }
+};
+
+
+function captureSegment(state, start, end, checkJson) {
+  var _position, _length, _character, _result;
+
+  if (start < end) {
+    _result = state.input.slice(start, end);
+
+    if (checkJson) {
+      for (_position = 0, _length = _result.length;
+           _position < _length;
+           _position += 1) {
+        _character = _result.charCodeAt(_position);
+        if (!(_character === 0x09 ||
+              (0x20 <= _character && _character <= 0x10FFFF))) {
+          throwError(state, 'expected valid JSON character');
+        }
+      }
+    } else if (PATTERN_NON_PRINTABLE.test(_result)) {
+      throwError(state, 'the stream contains non-printable characters');
+    }
+
+    state.result += _result;
+  }
+}
+
+function mergeMappings(state, destination, source, overridableKeys) {
+  var sourceKeys, key, index, quantity;
+
+  if (!common.isObject(source)) {
+    throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
+  }
+
+  sourceKeys = Object.keys(source);
+
+  for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
+    key = sourceKeys[index];
+
+    if (!_hasOwnProperty.call(destination, key)) {
+      destination[key] = source[key];
+      overridableKeys[key] = true;
+    }
+  }
+}
+
+function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
+  var index, quantity;
+
+  keyNode = String(keyNode);
+
+  if (_result === null) {
+    _result = {};
+  }
+
+  if (keyTag === 'tag:yaml.org,2002:merge') {
+    if (Array.isArray(valueNode)) {
+      for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
+        mergeMappings(state, _result, valueNode[index], overridableKeys);
+      }
+    } else {
+      mergeMappings(state, _result, valueNode, overridableKeys);
+    }
+  } else {
+    if (!state.json &&
+        !_hasOwnProperty.call(overridableKeys, keyNode) &&
+        _hasOwnProperty.call(_result, keyNode)) {
+      throwError(state, 'duplicated mapping key');
+    }
+    _result[keyNode] = valueNode;
+    delete overridableKeys[keyNode];
+  }
+
+  return _result;
+}
+
+function readLineBreak(state) {
+  var ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x0A/* LF */) {
+    state.position++;
+  } else if (ch === 0x0D/* CR */) {
+    state.position++;
+    if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {
+      state.position++;
+    }
+  } else {
+    throwError(state, 'a line break is expected');
+  }
+
+  state.line += 1;
+  state.lineStart = state.position;
+}
+
+function skipSeparationSpace(state, allowComments, checkIndent) {
+  var lineBreaks = 0,
+      ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+    while (is_WHITE_SPACE(ch)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    if (allowComments && ch === 0x23/* # */) {
+      do {
+        ch = state.input.charCodeAt(++state.position);
+      } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);
+    }
+
+    if (is_EOL(ch)) {
+      readLineBreak(state);
+
+      ch = state.input.charCodeAt(state.position);
+      lineBreaks++;
+      state.lineIndent = 0;
+
+      while (ch === 0x20/* Space */) {
+        state.lineIndent++;
+        ch = state.input.charCodeAt(++state.position);
+      }
+    } else {
+      break;
+    }
+  }
+
+  if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
+    throwWarning(state, 'deficient indentation');
+  }
+
+  return lineBreaks;
+}
+
+function testDocumentSeparator(state) {
+  var _position = state.position,
+      ch;
+
+  ch = state.input.charCodeAt(_position);
+
+  // Condition state.position === state.lineStart is tested
+  // in parent on each call, for efficiency. No needs to test here again.
+  if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&
+      ch === state.input.charCodeAt(_position + 1) &&
+      ch === state.input.charCodeAt(_position + 2)) {
+
+    _position += 3;
+
+    ch = state.input.charCodeAt(_position);
+
+    if (ch === 0 || is_WS_OR_EOL(ch)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+function writeFoldedLines(state, count) {
+  if (count === 1) {
+    state.result += ' ';
+  } else if (count > 1) {
+    state.result += common.repeat('\n', count - 1);
+  }
+}
+
+
+function readPlainScalar(state, nodeIndent, withinFlowCollection) {
+  var preceding,
+      following,
+      captureStart,
+      captureEnd,
+      hasPendingContent,
+      _line,
+      _lineStart,
+      _lineIndent,
+      _kind = state.kind,
+      _result = state.result,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (is_WS_OR_EOL(ch)      ||
+      is_FLOW_INDICATOR(ch) ||
+      ch === 0x23/* # */    ||
+      ch === 0x26/* & */    ||
+      ch === 0x2A/* * */    ||
+      ch === 0x21/* ! */    ||
+      ch === 0x7C/* | */    ||
+      ch === 0x3E/* > */    ||
+      ch === 0x27/* ' */    ||
+      ch === 0x22/* " */    ||
+      ch === 0x25/* % */    ||
+      ch === 0x40/* @ */    ||
+      ch === 0x60/* ` */) {
+    return false;
+  }
+
+  if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {
+    following = state.input.charCodeAt(state.position + 1);
+
+    if (is_WS_OR_EOL(following) ||
+        withinFlowCollection && is_FLOW_INDICATOR(following)) {
+      return false;
+    }
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  captureStart = captureEnd = state.position;
+  hasPendingContent = false;
+
+  while (ch !== 0) {
+    if (ch === 0x3A/* : */) {
+      following = state.input.charCodeAt(state.position + 1);
+
+      if (is_WS_OR_EOL(following) ||
+          withinFlowCollection && is_FLOW_INDICATOR(following)) {
+        break;
+      }
+
+    } else if (ch === 0x23/* # */) {
+      preceding = state.input.charCodeAt(state.position - 1);
+
+      if (is_WS_OR_EOL(preceding)) {
+        break;
+      }
+
+    } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
+               withinFlowCollection && is_FLOW_INDICATOR(ch)) {
+      break;
+
+    } else if (is_EOL(ch)) {
+      _line = state.line;
+      _lineStart = state.lineStart;
+      _lineIndent = state.lineIndent;
+      skipSeparationSpace(state, false, -1);
+
+      if (state.lineIndent >= nodeIndent) {
+        hasPendingContent = true;
+        ch = state.input.charCodeAt(state.position);
+        continue;
+      } else {
+        state.position = captureEnd;
+        state.line = _line;
+        state.lineStart = _lineStart;
+        state.lineIndent = _lineIndent;
+        break;
+      }
+    }
+
+    if (hasPendingContent) {
+      captureSegment(state, captureStart, captureEnd, false);
+      writeFoldedLines(state, state.line - _line);
+      captureStart = captureEnd = state.position;
+      hasPendingContent = false;
+    }
+
+    if (!is_WHITE_SPACE(ch)) {
+      captureEnd = state.position + 1;
+    }
+
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  captureSegment(state, captureStart, captureEnd, false);
+
+  if (state.result) {
+    return true;
+  }
+
+  state.kind = _kind;
+  state.result = _result;
+  return false;
+}
+
+function readSingleQuotedScalar(state, nodeIndent) {
+  var ch,
+      captureStart, captureEnd;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x27/* ' */) {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  state.position++;
+  captureStart = captureEnd = state.position;
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    if (ch === 0x27/* ' */) {
+      captureSegment(state, captureStart, state.position, true);
+      ch = state.input.charCodeAt(++state.position);
+
+      if (ch === 0x27/* ' */) {
+        captureStart = captureEnd = state.position;
+        state.position++;
+      } else {
+        return true;
+      }
+
+    } else if (is_EOL(ch)) {
+      captureSegment(state, captureStart, captureEnd, true);
+      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
+      captureStart = captureEnd = state.position;
+
+    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
+      throwError(state, 'unexpected end of the document within a single quoted scalar');
+
+    } else {
+      state.position++;
+      captureEnd = state.position;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a single quoted scalar');
+}
+
+function readDoubleQuotedScalar(state, nodeIndent) {
+  var captureStart,
+      captureEnd,
+      hexLength,
+      hexResult,
+      tmp,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x22/* " */) {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  state.position++;
+  captureStart = captureEnd = state.position;
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    if (ch === 0x22/* " */) {
+      captureSegment(state, captureStart, state.position, true);
+      state.position++;
+      return true;
+
+    } else if (ch === 0x5C/* \ */) {
+      captureSegment(state, captureStart, state.position, true);
+      ch = state.input.charCodeAt(++state.position);
+
+      if (is_EOL(ch)) {
+        skipSeparationSpace(state, false, nodeIndent);
+
+        // TODO: rework to inline fn with no type cast?
+      } else if (ch < 256 && simpleEscapeCheck[ch]) {
+        state.result += simpleEscapeMap[ch];
+        state.position++;
+
+      } else if ((tmp = escapedHexLen(ch)) > 0) {
+        hexLength = tmp;
+        hexResult = 0;
+
+        for (; hexLength > 0; hexLength--) {
+          ch = state.input.charCodeAt(++state.position);
+
+          if ((tmp = fromHexCode(ch)) >= 0) {
+            hexResult = (hexResult << 4) + tmp;
+
+          } else {
+            throwError(state, 'expected hexadecimal character');
+          }
+        }
+
+        state.result += charFromCodepoint(hexResult);
+
+        state.position++;
+
+      } else {
+        throwError(state, 'unknown escape sequence');
+      }
+
+      captureStart = captureEnd = state.position;
+
+    } else if (is_EOL(ch)) {
+      captureSegment(state, captureStart, captureEnd, true);
+      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
+      captureStart = captureEnd = state.position;
+
+    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
+      throwError(state, 'unexpected end of the document within a double quoted scalar');
+
+    } else {
+      state.position++;
+      captureEnd = state.position;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a double quoted scalar');
+}
+
+function readFlowCollection(state, nodeIndent) {
+  var readNext = true,
+      _line,
+      _tag     = state.tag,
+      _result,
+      _anchor  = state.anchor,
+      following,
+      terminator,
+      isPair,
+      isExplicitPair,
+      isMapping,
+      overridableKeys = {},
+      keyNode,
+      keyTag,
+      valueNode,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x5B/* [ */) {
+    terminator = 0x5D;/* ] */
+    isMapping = false;
+    _result = [];
+  } else if (ch === 0x7B/* { */) {
+    terminator = 0x7D;/* } */
+    isMapping = true;
+    _result = {};
+  } else {
+    return false;
+  }
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+
+  while (ch !== 0) {
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (ch === terminator) {
+      state.position++;
+      state.tag = _tag;
+      state.anchor = _anchor;
+      state.kind = isMapping ? 'mapping' : 'sequence';
+      state.result = _result;
+      return true;
+    } else if (!readNext) {
+      throwError(state, 'missed comma between flow collection entries');
+    }
+
+    keyTag = keyNode = valueNode = null;
+    isPair = isExplicitPair = false;
+
+    if (ch === 0x3F/* ? */) {
+      following = state.input.charCodeAt(state.position + 1);
+
+      if (is_WS_OR_EOL(following)) {
+        isPair = isExplicitPair = true;
+        state.position++;
+        skipSeparationSpace(state, true, nodeIndent);
+      }
+    }
+
+    _line = state.line;
+    composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
+    keyTag = state.tag;
+    keyNode = state.result;
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {
+      isPair = true;
+      ch = state.input.charCodeAt(++state.position);
+      skipSeparationSpace(state, true, nodeIndent);
+      composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
+      valueNode = state.result;
+    }
+
+    if (isMapping) {
+      storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
+    } else if (isPair) {
+      _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode));
+    } else {
+      _result.push(keyNode);
+    }
+
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (ch === 0x2C/* , */) {
+      readNext = true;
+      ch = state.input.charCodeAt(++state.position);
+    } else {
+      readNext = false;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a flow collection');
+}
+
+function readBlockScalar(state, nodeIndent) {
+  var captureStart,
+      folding,
+      chomping       = CHOMPING_CLIP,
+      detectedIndent = false,
+      textIndent     = nodeIndent,
+      emptyLines     = 0,
+      atMoreIndented = false,
+      tmp,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x7C/* | */) {
+    folding = false;
+  } else if (ch === 0x3E/* > */) {
+    folding = true;
+  } else {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+
+  while (ch !== 0) {
+    ch = state.input.charCodeAt(++state.position);
+
+    if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
+      if (CHOMPING_CLIP === chomping) {
+        chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;
+      } else {
+        throwError(state, 'repeat of a chomping mode identifier');
+      }
+
+    } else if ((tmp = fromDecimalCode(ch)) >= 0) {
+      if (tmp === 0) {
+        throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
+      } else if (!detectedIndent) {
+        textIndent = nodeIndent + tmp - 1;
+        detectedIndent = true;
+      } else {
+        throwError(state, 'repeat of an indentation width identifier');
+      }
+
+    } else {
+      break;
+    }
+  }
+
+  if (is_WHITE_SPACE(ch)) {
+    do { ch = state.input.charCodeAt(++state.position); }
+    while (is_WHITE_SPACE(ch));
+
+    if (ch === 0x23/* # */) {
+      do { ch = state.input.charCodeAt(++state.position); }
+      while (!is_EOL(ch) && (ch !== 0));
+    }
+  }
+
+  while (ch !== 0) {
+    readLineBreak(state);
+    state.lineIndent = 0;
+
+    ch = state.input.charCodeAt(state.position);
+
+    while ((!detectedIndent || state.lineIndent < textIndent) &&
+           (ch === 0x20/* Space */)) {
+      state.lineIndent++;
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    if (!detectedIndent && state.lineIndent > textIndent) {
+      textIndent = state.lineIndent;
+    }
+
+    if (is_EOL(ch)) {
+      emptyLines++;
+      continue;
+    }
+
+    // End of the scalar.
+    if (state.lineIndent < textIndent) {
+
+      // Perform the chomping.
+      if (chomping === CHOMPING_KEEP) {
+        state.result += common.repeat('\n', emptyLines);
+      } else if (chomping === CHOMPING_CLIP) {
+        if (detectedIndent) { // i.e. only if the scalar is not empty.
+          state.result += '\n';
+        }
+      }
+
+      // Break this `while` cycle and go to the funciton's epilogue.
+      break;
+    }
+
+    // Folded style: use fancy rules to handle line breaks.
+    if (folding) {
+
+      // Lines starting with white space characters (more-indented lines) are not folded.
+      if (is_WHITE_SPACE(ch)) {
+        atMoreIndented = true;
+        state.result += common.repeat('\n', emptyLines + 1);
+
+      // End of more-indented block.
+      } else if (atMoreIndented) {
+        atMoreIndented = false;
+        state.result += common.repeat('\n', emptyLines + 1);
+
+      // Just one line break - perceive as the same line.
+      } else if (emptyLines === 0) {
+        if (detectedIndent) { // i.e. only if we have already read some scalar content.
+          state.result += ' ';
+        }
+
+      // Several line breaks - perceive as different lines.
+      } else {
+        state.result += common.repeat('\n', emptyLines);
+      }
+
+    // Literal style: just add exact number of line breaks between content lines.
+    } else if (detectedIndent) {
+      // If current line isn't the first one - count line break from the last content line.
+      state.result += common.repeat('\n', emptyLines + 1);
+    } else {
+      // In case of the first content line - count only empty lines.
+      state.result += common.repeat('\n', emptyLines);
+    }
+
+    detectedIndent = true;
+    emptyLines = 0;
+    captureStart = state.position;
+
+    while (!is_EOL(ch) && (ch !== 0)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    captureSegment(state, captureStart, state.position, false);
+  }
+
+  return true;
+}
+
+function readBlockSequence(state, nodeIndent) {
+  var _line,
+      _tag      = state.tag,
+      _anchor   = state.anchor,
+      _result   = [],
+      following,
+      detected  = false,
+      ch;
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+
+    if (ch !== 0x2D/* - */) {
+      break;
+    }
+
+    following = state.input.charCodeAt(state.position + 1);
+
+    if (!is_WS_OR_EOL(following)) {
+      break;
+    }
+
+    detected = true;
+    state.position++;
+
+    if (skipSeparationSpace(state, true, -1)) {
+      if (state.lineIndent <= nodeIndent) {
+        _result.push(null);
+        ch = state.input.charCodeAt(state.position);
+        continue;
+      }
+    }
+
+    _line = state.line;
+    composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
+    _result.push(state.result);
+    skipSeparationSpace(state, true, -1);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
+      throwError(state, 'bad indentation of a sequence entry');
+    } else if (state.lineIndent < nodeIndent) {
+      break;
+    }
+  }
+
+  if (detected) {
+    state.tag = _tag;
+    state.anchor = _anchor;
+    state.kind = 'sequence';
+    state.result = _result;
+    return true;
+  }
+  return false;
+}
+
+function readBlockMapping(state, nodeIndent, flowIndent) {
+  var following,
+      allowCompact,
+      _line,
+      _tag          = state.tag,
+      _anchor       = state.anchor,
+      _result       = {},
+      overridableKeys = {},
+      keyTag        = null,
+      keyNode       = null,
+      valueNode     = null,
+      atExplicitKey = false,
+      detected      = false,
+      ch;
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+    following = state.input.charCodeAt(state.position + 1);
+    _line = state.line; // Save the current line.
+
+    //
+    // Explicit notation case. There are two separate blocks:
+    // first for the key (denoted by "?") and second for the value (denoted by ":")
+    //
+    if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {
+
+      if (ch === 0x3F/* ? */) {
+        if (atExplicitKey) {
+          storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+          keyTag = keyNode = valueNode = null;
+        }
+
+        detected = true;
+        atExplicitKey = true;
+        allowCompact = true;
+
+      } else if (atExplicitKey) {
+        // i.e. 0x3A/* : */ === character after the explicit key.
+        atExplicitKey = false;
+        allowCompact = true;
+
+      } else {
+        throwError(state, 'incomplete explicit mapping pair; a key node is missed');
+      }
+
+      state.position += 1;
+      ch = following;
+
+    //
+    // Implicit notation case. Flow-style node as the key first, then ":", and the value.
+    //
+    } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
+
+      if (state.line === _line) {
+        ch = state.input.charCodeAt(state.position);
+
+        while (is_WHITE_SPACE(ch)) {
+          ch = state.input.charCodeAt(++state.position);
+        }
+
+        if (ch === 0x3A/* : */) {
+          ch = state.input.charCodeAt(++state.position);
+
+          if (!is_WS_OR_EOL(ch)) {
+            throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
+          }
+
+          if (atExplicitKey) {
+            storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+            keyTag = keyNode = valueNode = null;
+          }
+
+          detected = true;
+          atExplicitKey = false;
+          allowCompact = false;
+          keyTag = state.tag;
+          keyNode = state.result;
+
+        } else if (detected) {
+          throwError(state, 'can not read an implicit mapping pair; a colon is missed');
+
+        } else {
+          state.tag = _tag;
+          state.anchor = _anchor;
+          return true; // Keep the result of `composeNode`.
+        }
+
+      } else if (detected) {
+        throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
+
+      } else {
+        state.tag = _tag;
+        state.anchor = _anchor;
+        return true; // Keep the result of `composeNode`.
+      }
+
+    } else {
+      break; // Reading is done. Go to the epilogue.
+    }
+
+    //
+    // Common reading code for both explicit and implicit notations.
+    //
+    if (state.line === _line || state.lineIndent > nodeIndent) {
+      if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
+        if (atExplicitKey) {
+          keyNode = state.result;
+        } else {
+          valueNode = state.result;
+        }
+      }
+
+      if (!atExplicitKey) {
+        storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
+        keyTag = keyNode = valueNode = null;
+      }
+
+      skipSeparationSpace(state, true, -1);
+      ch = state.input.charCodeAt(state.position);
+    }
+
+    if (state.lineIndent > nodeIndent && (ch !== 0)) {
+      throwError(state, 'bad indentation of a mapping entry');
+    } else if (state.lineIndent < nodeIndent) {
+      break;
+    }
+  }
+
+  //
+  // Epilogue.
+  //
+
+  // Special case: last mapping's node contains only the key in explicit notation.
+  if (atExplicitKey) {
+    storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+  }
+
+  // Expose the resulting mapping.
+  if (detected) {
+    state.tag = _tag;
+    state.anchor = _anchor;
+    state.kind = 'mapping';
+    state.result = _result;
+  }
+
+  return detected;
+}
+
+function readTagProperty(state) {
+  var _position,
+      isVerbatim = false,
+      isNamed    = false,
+      tagHandle,
+      tagName,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x21/* ! */) return false;
+
+  if (state.tag !== null) {
+    throwError(state, 'duplication of a tag property');
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+
+  if (ch === 0x3C/* < */) {
+    isVerbatim = true;
+    ch = state.input.charCodeAt(++state.position);
+
+  } else if (ch === 0x21/* ! */) {
+    isNamed = true;
+    tagHandle = '!!';
+    ch = state.input.charCodeAt(++state.position);
+
+  } else {
+    tagHandle = '!';
+  }
+
+  _position = state.position;
+
+  if (isVerbatim) {
+    do { ch = state.input.charCodeAt(++state.position); }
+    while (ch !== 0 && ch !== 0x3E/* > */);
+
+    if (state.position < state.length) {
+      tagName = state.input.slice(_position, state.position);
+      ch = state.input.charCodeAt(++state.position);
+    } else {
+      throwError(state, 'unexpected end of the stream within a verbatim tag');
+    }
+  } else {
+    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+
+      if (ch === 0x21/* ! */) {
+        if (!isNamed) {
+          tagHandle = state.input.slice(_position - 1, state.position + 1);
+
+          if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
+            throwError(state, 'named tag handle cannot contain such characters');
+          }
+
+          isNamed = true;
+          _position = state.position + 1;
+        } else {
+          throwError(state, 'tag suffix cannot contain exclamation marks');
+        }
+      }
+
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    tagName = state.input.slice(_position, state.position);
+
+    if (PATTERN_FLOW_INDICATORS.test(tagName)) {
+      throwError(state, 'tag suffix cannot contain flow indicator characters');
+    }
+  }
+
+  if (tagName && !PATTERN_TAG_URI.test(tagName)) {
+    throwError(state, 'tag name cannot contain such characters: ' + tagName);
+  }
+
+  if (isVerbatim) {
+    state.tag = tagName;
+
+  } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
+    state.tag = state.tagMap[tagHandle] + tagName;
+
+  } else if (tagHandle === '!') {
+    state.tag = '!' + tagName;
+
+  } else if (tagHandle === '!!') {
+    state.tag = 'tag:yaml.org,2002:' + tagName;
+
+  } else {
+    throwError(state, 'undeclared tag handle "' + tagHandle + '"');
+  }
+
+  return true;
+}
+
+function readAnchorProperty(state) {
+  var _position,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x26/* & */) return false;
+
+  if (state.anchor !== null) {
+    throwError(state, 'duplication of an anchor property');
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+  _position = state.position;
+
+  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  if (state.position === _position) {
+    throwError(state, 'name of an anchor node must contain at least one character');
+  }
+
+  state.anchor = state.input.slice(_position, state.position);
+  return true;
+}
+
+function readAlias(state) {
+  var _position, alias,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x2A/* * */) return false;
+
+  ch = state.input.charCodeAt(++state.position);
+  _position = state.position;
+
+  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  if (state.position === _position) {
+    throwError(state, 'name of an alias node must contain at least one character');
+  }
+
+  alias = state.input.slice(_position, state.position);
+
+  if (!state.anchorMap.hasOwnProperty(alias)) {
+    throwError(state, 'unidentified alias "' + alias + '"');
+  }
+
+  state.result = state.anchorMap[alias];
+  skipSeparationSpace(state, true, -1);
+  return true;
+}
+
+function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
+  var allowBlockStyles,
+      allowBlockScalars,
+      allowBlockCollections,
+      indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent
+      atNewLine  = false,
+      hasContent = false,
+      typeIndex,
+      typeQuantity,
+      type,
+      flowIndent,
+      blockIndent;
+
+  if (state.listener !== null) {
+    state.listener('open', state);
+  }
+
+  state.tag    = null;
+  state.anchor = null;
+  state.kind   = null;
+  state.result = null;
+
+  allowBlockStyles = allowBlockScalars = allowBlockCollections =
+    CONTEXT_BLOCK_OUT === nodeContext ||
+    CONTEXT_BLOCK_IN  === nodeContext;
+
+  if (allowToSeek) {
+    if (skipSeparationSpace(state, true, -1)) {
+      atNewLine = true;
+
+      if (state.lineIndent > parentIndent) {
+        indentStatus = 1;
+      } else if (state.lineIndent === parentIndent) {
+        indentStatus = 0;
+      } else if (state.lineIndent < parentIndent) {
+        indentStatus = -1;
+      }
+    }
+  }
+
+  if (indentStatus === 1) {
+    while (readTagProperty(state) || readAnchorProperty(state)) {
+      if (skipSeparationSpace(state, true, -1)) {
+        atNewLine = true;
+        allowBlockCollections = allowBlockStyles;
+
+        if (state.lineIndent > parentIndent) {
+          indentStatus = 1;
+        } else if (state.lineIndent === parentIndent) {
+          indentStatus = 0;
+        } else if (state.lineIndent < parentIndent) {
+          indentStatus = -1;
+        }
+      } else {
+        allowBlockCollections = false;
+      }
+    }
+  }
+
+  if (allowBlockCollections) {
+    allowBlockCollections = atNewLine || allowCompact;
+  }
+
+  if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
+    if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
+      flowIndent = parentIndent;
+    } else {
+      flowIndent = parentIndent + 1;
+    }
+
+    blockIndent = state.position - state.lineStart;
+
+    if (indentStatus === 1) {
+      if (allowBlockCollections &&
+          (readBlockSequence(state, blockIndent) ||
+           readBlockMapping(state, blockIndent, flowIndent)) ||
+          readFlowCollection(state, flowIndent)) {
+        hasContent = true;
+      } else {
+        if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||
+            readSingleQuotedScalar(state, flowIndent) ||
+            readDoubleQuotedScalar(state, flowIndent)) {
+          hasContent = true;
+
+        } else if (readAlias(state)) {
+          hasContent = true;
+
+          if (state.tag !== null || state.anchor !== null) {
+            throwError(state, 'alias node should not have any properties');
+          }
+
+        } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
+          hasContent = true;
+
+          if (state.tag === null) {
+            state.tag = '?';
+          }
+        }
+
+        if (state.anchor !== null) {
+          state.anchorMap[state.anchor] = state.result;
+        }
+      }
+    } else if (indentStatus === 0) {
+      // Special case: block sequences are allowed to have same indentation level as the parent.
+      // http://www.yaml.org/spec/1.2/spec.html#id2799784
+      hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
+    }
+  }
+
+  if (state.tag !== null && state.tag !== '!') {
+    if (state.tag === '?') {
+      for (typeIndex = 0, typeQuantity = state.implicitTypes.length;
+           typeIndex < typeQuantity;
+           typeIndex += 1) {
+        type = state.implicitTypes[typeIndex];
+
+        // Implicit resolving is not allowed for non-scalar types, and '?'
+        // non-specific tag is only assigned to plain scalars. So, it isn't
+        // needed to check for 'kind' conformity.
+
+        if (type.resolve(state.result)) { // `state.result` updated in resolver if matched
+          state.result = type.construct(state.result);
+          state.tag = type.tag;
+          if (state.anchor !== null) {
+            state.anchorMap[state.anchor] = state.result;
+          }
+          break;
+        }
+      }
+    } else if (_hasOwnProperty.call(state.typeMap, state.tag)) {
+      type = state.typeMap[state.tag];
+
+      if (state.result !== null && type.kind !== state.kind) {
+        throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
+      }
+
+      if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched
+        throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
+      } else {
+        state.result = type.construct(state.result);
+        if (state.anchor !== null) {
+          state.anchorMap[state.anchor] = state.result;
+        }
+      }
+    } else {
+      throwError(state, 'unknown tag !<' + state.tag + '>');
+    }
+  }
+
+  if (state.listener !== null) {
+    state.listener('close', state);
+  }
+  return state.tag !== null ||  state.anchor !== null || hasContent;
+}
+
+function readDocument(state) {
+  var documentStart = state.position,
+      _position,
+      directiveName,
+      directiveArgs,
+      hasDirectives = false,
+      ch;
+
+  state.version = null;
+  state.checkLineBreaks = state.legacy;
+  state.tagMap = {};
+  state.anchorMap = {};
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    skipSeparationSpace(state, true, -1);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (state.lineIndent > 0 || ch !== 0x25/* % */) {
+      break;
+    }
+
+    hasDirectives = true;
+    ch = state.input.charCodeAt(++state.position);
+    _position = state.position;
+
+    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    directiveName = state.input.slice(_position, state.position);
+    directiveArgs = [];
+
+    if (directiveName.length < 1) {
+      throwError(state, 'directive name must not be less than one character in length');
+    }
+
+    while (ch !== 0) {
+      while (is_WHITE_SPACE(ch)) {
+        ch = state.input.charCodeAt(++state.position);
+      }
+
+      if (ch === 0x23/* # */) {
+        do { ch = state.input.charCodeAt(++state.position); }
+        while (ch !== 0 && !is_EOL(ch));
+        break;
+      }
+
+      if (is_EOL(ch)) break;
+
+      _position = state.position;
+
+      while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+        ch = state.input.charCodeAt(++state.position);
+      }
+
+      directiveArgs.push(state.input.slice(_position, state.position));
+    }
+
+    if (ch !== 0) readLineBreak(state);
+
+    if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
+      directiveHandlers[directiveName](state, directiveName, directiveArgs);
+    } else {
+      throwWarning(state, 'unknown document directive "' + directiveName + '"');
+    }
+  }
+
+  skipSeparationSpace(state, true, -1);
+
+  if (state.lineIndent === 0 &&
+      state.input.charCodeAt(state.position)     === 0x2D/* - */ &&
+      state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&
+      state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {
+    state.position += 3;
+    skipSeparationSpace(state, true, -1);
+
+  } else if (hasDirectives) {
+    throwError(state, 'directives end mark is expected');
+  }
+
+  composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
+  skipSeparationSpace(state, true, -1);
+
+  if (state.checkLineBreaks &&
+      PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
+    throwWarning(state, 'non-ASCII line breaks are interpreted as content');
+  }
+
+  state.documents.push(state.result);
+
+  if (state.position === state.lineStart && testDocumentSeparator(state)) {
+
+    if (state.input.charCodeAt(state.position) === 0x2E/* . */) {
+      state.position += 3;
+      skipSeparationSpace(state, true, -1);
+    }
+    return;
+  }
+
+  if (state.position < (state.length - 1)) {
+    throwError(state, 'end of the stream or a document separator is expected');
+  } else {
+    return;
+  }
+}
+
+
+function loadDocuments(input, options) {
+  input = String(input);
+  options = options || {};
+
+  if (input.length !== 0) {
+
+    // Add tailing `\n` if not exists
+    if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&
+        input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {
+      input += '\n';
+    }
+
+    // Strip BOM
+    if (input.charCodeAt(0) === 0xFEFF) {
+      input = input.slice(1);
+    }
+  }
+
+  var state = new State(input, options);
+
+  // Use 0 as string terminator. That significantly simplifies bounds check.
+  state.input += '\0';
+
+  while (state.input.charCodeAt(state.position) === 0x20/* Space */) {
+    state.lineIndent += 1;
+    state.position += 1;
+  }
+
+  while (state.position < (state.length - 1)) {
+    readDocument(state);
+  }
+
+  return state.documents;
+}
+
+
+function loadAll(input, iterator, options) {
+  var documents = loadDocuments(input, options), index, length;
+
+  for (index = 0, length = documents.length; index < length; index += 1) {
+    iterator(documents[index]);
+  }
+}
+
+
+function load(input, options) {
+  var documents = loadDocuments(input, options);
+
+  if (documents.length === 0) {
+    /*eslint-disable no-undefined*/
+    return undefined;
+  } else if (documents.length === 1) {
+    return documents[0];
+  }
+  throw new YAMLException('expected a single document in the stream, but found more');
+}
+
+
+function safeLoadAll(input, output, options) {
+  loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+
+function safeLoad(input, options) {
+  return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+
+module.exports.loadAll     = loadAll;
+module.exports.load        = load;
+module.exports.safeLoadAll = safeLoadAll;
+module.exports.safeLoad    = safeLoad;
+
+},{"./common":23,"./exception":25,"./mark":27,"./schema/default_full":30,"./schema/default_safe":31}],27:[function(require,module,exports){
+'use strict';
+
+
+var common = require('./common');
+
+
+function Mark(name, buffer, position, line, column) {
+  this.name     = name;
+  this.buffer   = buffer;
+  this.position = position;
+  this.line     = line;
+  this.column   = column;
+}
+
+
+Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {
+  var head, start, tail, end, snippet;
+
+  if (!this.buffer) return null;
+
+  indent = indent || 4;
+  maxLength = maxLength || 75;
+
+  head = '';
+  start = this.position;
+
+  while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {
+    start -= 1;
+    if (this.position - start > (maxLength / 2 - 1)) {
+      head = ' ... ';
+      start += 5;
+      break;
+    }
+  }
+
+  tail = '';
+  end = this.position;
+
+  while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {
+    end += 1;
+    if (end - this.position > (maxLength / 2 - 1)) {
+      tail = ' ... ';
+      end -= 5;
+      break;
+    }
+  }
+
+  snippet = this.buffer.slice(start, end);
+
+  return common.repeat(' ', indent) + head + snippet + tail + '\n' +
+         common.repeat(' ', indent + this.position - start + head.length) + '^';
+};
+
+
+Mark.prototype.toString = function toString(compact) {
+  var snippet, where = '';
+
+  if (this.name) {
+    where += 'in "' + this.name + '" ';
+  }
+
+  where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
+
+  if (!compact) {
+    snippet = this.getSnippet();
+
+    if (snippet) {
+      where += ':\n' + snippet;
+    }
+  }
+
+  return where;
+};
+
+
+module.exports = Mark;
+
+},{"./common":23}],28:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable max-len*/
+
+var common        = require('./common');
+var YAMLException = require('./exception');
+var Type          = require('./type');
+
+
+function compileList(schema, name, result) {
+  var exclude = [];
+
+  schema.include.forEach(function (includedSchema) {
+    result = compileList(includedSchema, name, result);
+  });
+
+  schema[name].forEach(function (currentType) {
+    result.forEach(function (previousType, previousIndex) {
+      if (previousType.tag === currentType.tag) {
+        exclude.push(previousIndex);
+      }
+    });
+
+    result.push(currentType);
+  });
+
+  return result.filter(function (type, index) {
+    return exclude.indexOf(index) === -1;
+  });
+}
+
+
+function compileMap(/* lists... */) {
+  var result = {}, index, length;
+
+  function collectType(type) {
+    result[type.tag] = type;
+  }
+
+  for (index = 0, length = arguments.length; index < length; index += 1) {
+    arguments[index].forEach(collectType);
+  }
+
+  return result;
+}
+
+
+function Schema(definition) {
+  this.include  = definition.include  || [];
+  this.implicit = definition.implicit || [];
+  this.explicit = definition.explicit || [];
+
+  this.implicit.forEach(function (type) {
+    if (type.loadKind && type.loadKind !== 'scalar') {
+      throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
+    }
+  });
+
+  this.compiledImplicit = compileList(this, 'implicit', []);
+  this.compiledExplicit = compileList(this, 'explicit', []);
+  this.compiledTypeMap  = compileMap(this.compiledImplicit, this.compiledExplicit);
+}
+
+
+Schema.DEFAULT = null;
+
+
+Schema.create = function createSchema() {
+  var schemas, types;
+
+  switch (arguments.length) {
+    case 1:
+      schemas = Schema.DEFAULT;
+      types = arguments[0];
+      break;
+
+    case 2:
+      schemas = arguments[0];
+      types = arguments[1];
+      break;
+
+    default:
+      throw new YAMLException('Wrong number of arguments for Schema.create function');
+  }
+
+  schemas = common.toArray(schemas);
+  types = common.toArray(types);
+
+  if (!schemas.every(function (schema) { return schema instanceof Schema; })) {
+    throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
+  }
+
+  if (!types.every(function (type) { return type instanceof Type; })) {
+    throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
+  }
+
+  return new Schema({
+    include: schemas,
+    explicit: types
+  });
+};
+
+
+module.exports = Schema;
+
+},{"./common":23,"./exception":25,"./type":34}],29:[function(require,module,exports){
+// Standard YAML's Core schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2804923
+//
+// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
+// So, Core schema has no distinctions from JSON schema is JS-YAML.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./json')
+  ]
+});
+
+},{"../schema":28,"./json":33}],30:[function(require,module,exports){
+// JS-YAML's default schema for `load` function.
+// It is not described in the YAML specification.
+//
+// This schema is based on JS-YAML's default safe schema and includes
+// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
+//
+// Also this schema is used as default base schema at `Schema.create` function.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = Schema.DEFAULT = new Schema({
+  include: [
+    require('./default_safe')
+  ],
+  explicit: [
+    require('../type/js/undefined'),
+    require('../type/js/regexp'),
+    require('../type/js/function')
+  ]
+});
+
+},{"../schema":28,"../type/js/function":39,"../type/js/regexp":40,"../type/js/undefined":41,"./default_safe":31}],31:[function(require,module,exports){
+// JS-YAML's default schema for `safeLoad` function.
+// It is not described in the YAML specification.
+//
+// This schema is based on standard YAML's Core schema and includes most of
+// extra types described at YAML tag repository. (http://yaml.org/type/)
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./core')
+  ],
+  implicit: [
+    require('../type/timestamp'),
+    require('../type/merge')
+  ],
+  explicit: [
+    require('../type/binary'),
+    require('../type/omap'),
+    require('../type/pairs'),
+    require('../type/set')
+  ]
+});
+
+},{"../schema":28,"../type/binary":35,"../type/merge":43,"../type/omap":45,"../type/pairs":46,"../type/set":48,"../type/timestamp":50,"./core":29}],32:[function(require,module,exports){
+// Standard YAML's Failsafe schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2802346
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  explicit: [
+    require('../type/str'),
+    require('../type/seq'),
+    require('../type/map')
+  ]
+});
+
+},{"../schema":28,"../type/map":42,"../type/seq":47,"../type/str":49}],33:[function(require,module,exports){
+// Standard YAML's JSON schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2803231
+//
+// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
+// So, this schema is not such strict as defined in the YAML specification.
+// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./failsafe')
+  ],
+  implicit: [
+    require('../type/null'),
+    require('../type/bool'),
+    require('../type/int'),
+    require('../type/float')
+  ]
+});
+
+},{"../schema":28,"../type/bool":36,"../type/float":37,"../type/int":38,"../type/null":44,"./failsafe":32}],34:[function(require,module,exports){
+'use strict';
+
+var YAMLException = require('./exception');
+
+var TYPE_CONSTRUCTOR_OPTIONS = [
+  'kind',
+  'resolve',
+  'construct',
+  'instanceOf',
+  'predicate',
+  'represent',
+  'defaultStyle',
+  'styleAliases'
+];
+
+var YAML_NODE_KINDS = [
+  'scalar',
+  'sequence',
+  'mapping'
+];
+
+function compileStyleAliases(map) {
+  var result = {};
+
+  if (map !== null) {
+    Object.keys(map).forEach(function (style) {
+      map[style].forEach(function (alias) {
+        result[String(alias)] = style;
+      });
+    });
+  }
+
+  return result;
+}
+
+function Type(tag, options) {
+  options = options || {};
+
+  Object.keys(options).forEach(function (name) {
+    if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
+      throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
+    }
+  });
+
+  // TODO: Add tag format check.
+  this.tag          = tag;
+  this.kind         = options['kind']         || null;
+  this.resolve      = options['resolve']      || function () { return true; };
+  this.construct    = options['construct']    || function (data) { return data; };
+  this.instanceOf   = options['instanceOf']   || null;
+  this.predicate    = options['predicate']    || null;
+  this.represent    = options['represent']    || null;
+  this.defaultStyle = options['defaultStyle'] || null;
+  this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
+
+  if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
+    throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
+  }
+}
+
+module.exports = Type;
+
+},{"./exception":25}],35:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable no-bitwise*/
+
+// A trick for browserified version.
+// Since we make browserifier to ignore `buffer` module, NodeBuffer will be undefined
+var NodeBuffer = require('buffer').Buffer;
+var Type       = require('../type');
+
+
+// [ 64, 65, 66 ] -> [ padding, CR, LF ]
+var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
+
+
+function resolveYamlBinary(data) {
+  if (data === null) return false;
+
+  var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
+
+  // Convert one by one.
+  for (idx = 0; idx < max; idx++) {
+    code = map.indexOf(data.charAt(idx));
+
+    // Skip CR/LF
+    if (code > 64) continue;
+
+    // Fail on illegal characters
+    if (code < 0) return false;
+
+    bitlen += 6;
+  }
+
+  // If there are any bits left, source was corrupted
+  return (bitlen % 8) === 0;
+}
+
+function constructYamlBinary(data) {
+  var idx, tailbits,
+      input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
+      max = input.length,
+      map = BASE64_MAP,
+      bits = 0,
+      result = [];
+
+  // Collect by 6*4 bits (3 bytes)
+
+  for (idx = 0; idx < max; idx++) {
+    if ((idx % 4 === 0) && idx) {
+      result.push((bits >> 16) & 0xFF);
+      result.push((bits >> 8) & 0xFF);
+      result.push(bits & 0xFF);
+    }
+
+    bits = (bits << 6) | map.indexOf(input.charAt(idx));
+  }
+
+  // Dump tail
+
+  tailbits = (max % 4) * 6;
+
+  if (tailbits === 0) {
+    result.push((bits >> 16) & 0xFF);
+    result.push((bits >> 8) & 0xFF);
+    result.push(bits & 0xFF);
+  } else if (tailbits === 18) {
+    result.push((bits >> 10) & 0xFF);
+    result.push((bits >> 2) & 0xFF);
+  } else if (tailbits === 12) {
+    result.push((bits >> 4) & 0xFF);
+  }
+
+  // Wrap into Buffer for NodeJS and leave Array for browser
+  if (NodeBuffer) return new NodeBuffer(result);
+
+  return result;
+}
+
+function representYamlBinary(object /*, style*/) {
+  var result = '', bits = 0, idx, tail,
+      max = object.length,
+      map = BASE64_MAP;
+
+  // Convert every three bytes to 4 ASCII characters.
+
+  for (idx = 0; idx < max; idx++) {
+    if ((idx % 3 === 0) && idx) {
+      result += map[(bits >> 18) & 0x3F];
+      result += map[(bits >> 12) & 0x3F];
+      result += map[(bits >> 6) & 0x3F];
+      result += map[bits & 0x3F];
+    }
+
+    bits = (bits << 8) + object[idx];
+  }
+
+  // Dump tail
+
+  tail = max % 3;
+
+  if (tail === 0) {
+    result += map[(bits >> 18) & 0x3F];
+    result += map[(bits >> 12) & 0x3F];
+    result += map[(bits >> 6) & 0x3F];
+    result += map[bits & 0x3F];
+  } else if (tail === 2) {
+    result += map[(bits >> 10) & 0x3F];
+    result += map[(bits >> 4) & 0x3F];
+    result += map[(bits << 2) & 0x3F];
+    result += map[64];
+  } else if (tail === 1) {
+    result += map[(bits >> 2) & 0x3F];
+    result += map[(bits << 4) & 0x3F];
+    result += map[64];
+    result += map[64];
+  }
+
+  return result;
+}
+
+function isBinary(object) {
+  return NodeBuffer && NodeBuffer.isBuffer(object);
+}
+
+module.exports = new Type('tag:yaml.org,2002:binary', {
+  kind: 'scalar',
+  resolve: resolveYamlBinary,
+  construct: constructYamlBinary,
+  predicate: isBinary,
+  represent: representYamlBinary
+});
+
+},{"../type":34,"buffer":12}],36:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlBoolean(data) {
+  if (data === null) return false;
+
+  var max = data.length;
+
+  return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
+         (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
+}
+
+function constructYamlBoolean(data) {
+  return data === 'true' ||
+         data === 'True' ||
+         data === 'TRUE';
+}
+
+function isBoolean(object) {
+  return Object.prototype.toString.call(object) === '[object Boolean]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:bool', {
+  kind: 'scalar',
+  resolve: resolveYamlBoolean,
+  construct: constructYamlBoolean,
+  predicate: isBoolean,
+  represent: {
+    lowercase: function (object) { return object ? 'true' : 'false'; },
+    uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
+    camelcase: function (object) { return object ? 'True' : 'False'; }
+  },
+  defaultStyle: 'lowercase'
+});
+
+},{"../type":34}],37:[function(require,module,exports){
+'use strict';
+
+var common = require('../common');
+var Type   = require('../type');
+
+var YAML_FLOAT_PATTERN = new RegExp(
+  '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +
+  '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +
+  '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
+  '|[-+]?\\.(?:inf|Inf|INF)' +
+  '|\\.(?:nan|NaN|NAN))$');
+
+function resolveYamlFloat(data) {
+  if (data === null) return false;
+
+  if (!YAML_FLOAT_PATTERN.test(data)) return false;
+
+  return true;
+}
+
+function constructYamlFloat(data) {
+  var value, sign, base, digits;
+
+  value  = data.replace(/_/g, '').toLowerCase();
+  sign   = value[0] === '-' ? -1 : 1;
+  digits = [];
+
+  if ('+-'.indexOf(value[0]) >= 0) {
+    value = value.slice(1);
+  }
+
+  if (value === '.inf') {
+    return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
+
+  } else if (value === '.nan') {
+    return NaN;
+
+  } else if (value.indexOf(':') >= 0) {
+    value.split(':').forEach(function (v) {
+      digits.unshift(parseFloat(v, 10));
+    });
+
+    value = 0.0;
+    base = 1;
+
+    digits.forEach(function (d) {
+      value += d * base;
+      base *= 60;
+    });
+
+    return sign * value;
+
+  }
+  return sign * parseFloat(value, 10);
+}
+
+
+var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
+
+function representYamlFloat(object, style) {
+  var res;
+
+  if (isNaN(object)) {
+    switch (style) {
+      case 'lowercase': return '.nan';
+      case 'uppercase': return '.NAN';
+      case 'camelcase': return '.NaN';
+    }
+  } else if (Number.POSITIVE_INFINITY === object) {
+    switch (style) {
+      case 'lowercase': return '.inf';
+      case 'uppercase': return '.INF';
+      case 'camelcase': return '.Inf';
+    }
+  } else if (Number.NEGATIVE_INFINITY === object) {
+    switch (style) {
+      case 'lowercase': return '-.inf';
+      case 'uppercase': return '-.INF';
+      case 'camelcase': return '-.Inf';
+    }
+  } else if (common.isNegativeZero(object)) {
+    return '-0.0';
+  }
+
+  res = object.toString(10);
+
+  // JS stringifier can build scientific format without dots: 5e-100,
+  // while YAML requres dot: 5.e-100. Fix it with simple hack
+
+  return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
+}
+
+function isFloat(object) {
+  return (Object.prototype.toString.call(object) === '[object Number]') &&
+         (object % 1 !== 0 || common.isNegativeZero(object));
+}
+
+module.exports = new Type('tag:yaml.org,2002:float', {
+  kind: 'scalar',
+  resolve: resolveYamlFloat,
+  construct: constructYamlFloat,
+  predicate: isFloat,
+  represent: representYamlFloat,
+  defaultStyle: 'lowercase'
+});
+
+},{"../common":23,"../type":34}],38:[function(require,module,exports){
+'use strict';
+
+var common = require('../common');
+var Type   = require('../type');
+
+function isHexCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
+         ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
+         ((0x61/* a */ <= c) && (c <= 0x66/* f */));
+}
+
+function isOctCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
+}
+
+function isDecCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
+}
+
+function resolveYamlInteger(data) {
+  if (data === null) return false;
+
+  var max = data.length,
+      index = 0,
+      hasDigits = false,
+      ch;
+
+  if (!max) return false;
+
+  ch = data[index];
+
+  // sign
+  if (ch === '-' || ch === '+') {
+    ch = data[++index];
+  }
+
+  if (ch === '0') {
+    // 0
+    if (index + 1 === max) return true;
+    ch = data[++index];
+
+    // base 2, base 8, base 16
+
+    if (ch === 'b') {
+      // base 2
+      index++;
+
+      for (; index < max; index++) {
+        ch = data[index];
+        if (ch === '_') continue;
+        if (ch !== '0' && ch !== '1') return false;
+        hasDigits = true;
+      }
+      return hasDigits;
+    }
+
+
+    if (ch === 'x') {
+      // base 16
+      index++;
+
+      for (; index < max; index++) {
+        ch = data[index];
+        if (ch === '_') continue;
+        if (!isHexCode(data.charCodeAt(index))) return false;
+        hasDigits = true;
+      }
+      return hasDigits;
+    }
+
+    // base 8
+    for (; index < max; index++) {
+      ch = data[index];
+      if (ch === '_') continue;
+      if (!isOctCode(data.charCodeAt(index))) return false;
+      hasDigits = true;
+    }
+    return hasDigits;
+  }
+
+  // base 10 (except 0) or base 60
+
+  for (; index < max; index++) {
+    ch = data[index];
+    if (ch === '_') continue;
+    if (ch === ':') break;
+    if (!isDecCode(data.charCodeAt(index))) {
+      return false;
+    }
+    hasDigits = true;
+  }
+
+  if (!hasDigits) return false;
+
+  // if !base60 - done;
+  if (ch !== ':') return true;
+
+  // base60 almost not used, no needs to optimize
+  return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
+}
+
+function constructYamlInteger(data) {
+  var value = data, sign = 1, ch, base, digits = [];
+
+  if (value.indexOf('_') !== -1) {
+    value = value.replace(/_/g, '');
+  }
+
+  ch = value[0];
+
+  if (ch === '-' || ch === '+') {
+    if (ch === '-') sign = -1;
+    value = value.slice(1);
+    ch = value[0];
+  }
+
+  if (value === '0') return 0;
+
+  if (ch === '0') {
+    if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
+    if (value[1] === 'x') return sign * parseInt(value, 16);
+    return sign * parseInt(value, 8);
+  }
+
+  if (value.indexOf(':') !== -1) {
+    value.split(':').forEach(function (v) {
+      digits.unshift(parseInt(v, 10));
+    });
+
+    value = 0;
+    base = 1;
+
+    digits.forEach(function (d) {
+      value += (d * base);
+      base *= 60;
+    });
+
+    return sign * value;
+
+  }
+
+  return sign * parseInt(value, 10);
+}
+
+function isInteger(object) {
+  return (Object.prototype.toString.call(object)) === '[object Number]' &&
+         (object % 1 === 0 && !common.isNegativeZero(object));
+}
+
+module.exports = new Type('tag:yaml.org,2002:int', {
+  kind: 'scalar',
+  resolve: resolveYamlInteger,
+  construct: constructYamlInteger,
+  predicate: isInteger,
+  represent: {
+    binary:      function (object) { return '0b' + object.toString(2); },
+    octal:       function (object) { return '0'  + object.toString(8); },
+    decimal:     function (object) { return        object.toString(10); },
+    hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
+  },
+  defaultStyle: 'decimal',
+  styleAliases: {
+    binary:      [ 2,  'bin' ],
+    octal:       [ 8,  'oct' ],
+    decimal:     [ 10, 'dec' ],
+    hexadecimal: [ 16, 'hex' ]
+  }
+});
+
+},{"../common":23,"../type":34}],39:[function(require,module,exports){
+'use strict';
+
+var esprima;
+
+// Browserified version does not have esprima
+//
+// 1. For node.js just require module as deps
+// 2. For browser try to require mudule via external AMD system.
+//    If not found - try to fallback to window.esprima. If not
+//    found too - then fail to parse.
+//
+try {
+  // workaround to exclude package from browserify list.
+  var _require = require;
+  esprima = _require('esprima');
+} catch (_) {
+  /*global window */
+  if (typeof window !== 'undefined') esprima = window.esprima;
+}
+
+var Type = require('../../type');
+
+function resolveJavascriptFunction(data) {
+  if (data === null) return false;
+
+  try {
+    var source = '(' + data + ')',
+        ast    = esprima.parse(source, { range: true });
+
+    if (ast.type                    !== 'Program'             ||
+        ast.body.length             !== 1                     ||
+        ast.body[0].type            !== 'ExpressionStatement' ||
+        ast.body[0].expression.type !== 'FunctionExpression') {
+      return false;
+    }
+
+    return true;
+  } catch (err) {
+    return false;
+  }
+}
+
+function constructJavascriptFunction(data) {
+  /*jslint evil:true*/
+
+  var source = '(' + data + ')',
+      ast    = esprima.parse(source, { range: true }),
+      params = [],
+      body;
+
+  if (ast.type                    !== 'Program'             ||
+      ast.body.length             !== 1                     ||
+      ast.body[0].type            !== 'ExpressionStatement' ||
+      ast.body[0].expression.type !== 'FunctionExpression') {
+    throw new Error('Failed to resolve function');
+  }
+
+  ast.body[0].expression.params.forEach(function (param) {
+    params.push(param.name);
+  });
+
+  body = ast.body[0].expression.body.range;
+
+  // Esprima's ranges include the first '{' and the last '}' characters on
+  // function expressions. So cut them out.
+  /*eslint-disable no-new-func*/
+  return new Function(params, source.slice(body[0] + 1, body[1] - 1));
+}
+
+function representJavascriptFunction(object /*, style*/) {
+  return object.toString();
+}
+
+function isFunction(object) {
+  return Object.prototype.toString.call(object) === '[object Function]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/function', {
+  kind: 'scalar',
+  resolve: resolveJavascriptFunction,
+  construct: constructJavascriptFunction,
+  predicate: isFunction,
+  represent: representJavascriptFunction
+});
+
+},{"../../type":34}],40:[function(require,module,exports){
+'use strict';
+
+var Type = require('../../type');
+
+function resolveJavascriptRegExp(data) {
+  if (data === null) return false;
+  if (data.length === 0) return false;
+
+  var regexp = data,
+      tail   = /\/([gim]*)$/.exec(data),
+      modifiers = '';
+
+  // if regexp starts with '/' it can have modifiers and must be properly closed
+  // `/foo/gim` - modifiers tail can be maximum 3 chars
+  if (regexp[0] === '/') {
+    if (tail) modifiers = tail[1];
+
+    if (modifiers.length > 3) return false;
+    // if expression starts with /, is should be properly terminated
+    if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
+  }
+
+  return true;
+}
+
+function constructJavascriptRegExp(data) {
+  var regexp = data,
+      tail   = /\/([gim]*)$/.exec(data),
+      modifiers = '';
+
+  // `/foo/gim` - tail can be maximum 4 chars
+  if (regexp[0] === '/') {
+    if (tail) modifiers = tail[1];
+    regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
+  }
+
+  return new RegExp(regexp, modifiers);
+}
+
+function representJavascriptRegExp(object /*, style*/) {
+  var result = '/' + object.source + '/';
+
+  if (object.global) result += 'g';
+  if (object.multiline) result += 'm';
+  if (object.ignoreCase) result += 'i';
+
+  return result;
+}
+
+function isRegExp(object) {
+  return Object.prototype.toString.call(object) === '[object RegExp]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/regexp', {
+  kind: 'scalar',
+  resolve: resolveJavascriptRegExp,
+  construct: constructJavascriptRegExp,
+  predicate: isRegExp,
+  represent: representJavascriptRegExp
+});
+
+},{"../../type":34}],41:[function(require,module,exports){
+'use strict';
+
+var Type = require('../../type');
+
+function resolveJavascriptUndefined() {
+  return true;
+}
+
+function constructJavascriptUndefined() {
+  /*eslint-disable no-undefined*/
+  return undefined;
+}
+
+function representJavascriptUndefined() {
+  return '';
+}
+
+function isUndefined(object) {
+  return typeof object === 'undefined';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/undefined', {
+  kind: 'scalar',
+  resolve: resolveJavascriptUndefined,
+  construct: constructJavascriptUndefined,
+  predicate: isUndefined,
+  represent: representJavascriptUndefined
+});
+
+},{"../../type":34}],42:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:map', {
+  kind: 'mapping',
+  construct: function (data) { return data !== null ? data : {}; }
+});
+
+},{"../type":34}],43:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlMerge(data) {
+  return data === '<<' || data === null;
+}
+
+module.exports = new Type('tag:yaml.org,2002:merge', {
+  kind: 'scalar',
+  resolve: resolveYamlMerge
+});
+
+},{"../type":34}],44:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlNull(data) {
+  if (data === null) return true;
+
+  var max = data.length;
+
+  return (max === 1 && data === '~') ||
+         (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
+}
+
+function constructYamlNull() {
+  return null;
+}
+
+function isNull(object) {
+  return object === null;
+}
+
+module.exports = new Type('tag:yaml.org,2002:null', {
+  kind: 'scalar',
+  resolve: resolveYamlNull,
+  construct: constructYamlNull,
+  predicate: isNull,
+  represent: {
+    canonical: function () { return '~';    },
+    lowercase: function () { return 'null'; },
+    uppercase: function () { return 'NULL'; },
+    camelcase: function () { return 'Null'; }
+  },
+  defaultStyle: 'lowercase'
+});
+
+},{"../type":34}],45:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+var _toString       = Object.prototype.toString;
+
+function resolveYamlOmap(data) {
+  if (data === null) return true;
+
+  var objectKeys = [], index, length, pair, pairKey, pairHasKey,
+      object = data;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+    pairHasKey = false;
+
+    if (_toString.call(pair) !== '[object Object]') return false;
+
+    for (pairKey in pair) {
+      if (_hasOwnProperty.call(pair, pairKey)) {
+        if (!pairHasKey) pairHasKey = true;
+        else return false;
+      }
+    }
+
+    if (!pairHasKey) return false;
+
+    if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
+    else return false;
+  }
+
+  return true;
+}
+
+function constructYamlOmap(data) {
+  return data !== null ? data : [];
+}
+
+module.exports = new Type('tag:yaml.org,2002:omap', {
+  kind: 'sequence',
+  resolve: resolveYamlOmap,
+  construct: constructYamlOmap
+});
+
+},{"../type":34}],46:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _toString = Object.prototype.toString;
+
+function resolveYamlPairs(data) {
+  if (data === null) return true;
+
+  var index, length, pair, keys, result,
+      object = data;
+
+  result = new Array(object.length);
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+
+    if (_toString.call(pair) !== '[object Object]') return false;
+
+    keys = Object.keys(pair);
+
+    if (keys.length !== 1) return false;
+
+    result[index] = [ keys[0], pair[keys[0]] ];
+  }
+
+  return true;
+}
+
+function constructYamlPairs(data) {
+  if (data === null) return [];
+
+  var index, length, pair, keys, result,
+      object = data;
+
+  result = new Array(object.length);
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+
+    keys = Object.keys(pair);
+
+    result[index] = [ keys[0], pair[keys[0]] ];
+  }
+
+  return result;
+}
+
+module.exports = new Type('tag:yaml.org,2002:pairs', {
+  kind: 'sequence',
+  resolve: resolveYamlPairs,
+  construct: constructYamlPairs
+});
+
+},{"../type":34}],47:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:seq', {
+  kind: 'sequence',
+  construct: function (data) { return data !== null ? data : []; }
+});
+
+},{"../type":34}],48:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function resolveYamlSet(data) {
+  if (data === null) return true;
+
+  var key, object = data;
+
+  for (key in object) {
+    if (_hasOwnProperty.call(object, key)) {
+      if (object[key] !== null) return false;
+    }
+  }
+
+  return true;
+}
+
+function constructYamlSet(data) {
+  return data !== null ? data : {};
+}
+
+module.exports = new Type('tag:yaml.org,2002:set', {
+  kind: 'mapping',
+  resolve: resolveYamlSet,
+  construct: constructYamlSet
+});
+
+},{"../type":34}],49:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:str', {
+  kind: 'scalar',
+  construct: function (data) { return data !== null ? data : ''; }
+});
+
+},{"../type":34}],50:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var YAML_TIMESTAMP_REGEXP = new RegExp(
+  '^([0-9][0-9][0-9][0-9])'          + // [1] year
+  '-([0-9][0-9]?)'                   + // [2] month
+  '-([0-9][0-9]?)'                   + // [3] day
+  '(?:(?:[Tt]|[ \\t]+)'              + // ...
+  '([0-9][0-9]?)'                    + // [4] hour
+  ':([0-9][0-9])'                    + // [5] minute
+  ':([0-9][0-9])'                    + // [6] second
+  '(?:\\.([0-9]*))?'                 + // [7] fraction
+  '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
+  '(?::([0-9][0-9]))?))?)?$');         // [11] tz_minute
+
+function resolveYamlTimestamp(data) {
+  if (data === null) return false;
+  if (YAML_TIMESTAMP_REGEXP.exec(data) === null) return false;
+  return true;
+}
+
+function constructYamlTimestamp(data) {
+  var match, year, month, day, hour, minute, second, fraction = 0,
+      delta = null, tz_hour, tz_minute, date;
+
+  match = YAML_TIMESTAMP_REGEXP.exec(data);
+
+  if (match === null) throw new Error('Date resolve error');
+
+  // match: [1] year [2] month [3] day
+
+  year = +(match[1]);
+  month = +(match[2]) - 1; // JS month starts with 0
+  day = +(match[3]);
+
+  if (!match[4]) { // no hour
+    return new Date(Date.UTC(year, month, day));
+  }
+
+  // match: [4] hour [5] minute [6] second [7] fraction
+
+  hour = +(match[4]);
+  minute = +(match[5]);
+  second = +(match[6]);
+
+  if (match[7]) {
+    fraction = match[7].slice(0, 3);
+    while (fraction.length < 3) { // milli-seconds
+      fraction += '0';
+    }
+    fraction = +fraction;
+  }
+
+  // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
+
+  if (match[9]) {
+    tz_hour = +(match[10]);
+    tz_minute = +(match[11] || 0);
+    delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
+    if (match[9] === '-') delta = -delta;
+  }
+
+  date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
+
+  if (delta) date.setTime(date.getTime() - delta);
+
+  return date;
+}
+
+function representYamlTimestamp(object /*, style*/) {
+  return object.toISOString();
+}
+
+module.exports = new Type('tag:yaml.org,2002:timestamp', {
+  kind: 'scalar',
+  resolve: resolveYamlTimestamp,
+  construct: constructYamlTimestamp,
+  instanceOf: Date,
+  represent: representYamlTimestamp
+});
+
+},{"../type":34}],51:[function(require,module,exports){
+var baseIndexOf = require('../internal/baseIndexOf'),
+    binaryIndex = require('../internal/binaryIndex');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
+ * performs a faster binary search.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {boolean|number} [fromIndex=0] The index to search from or `true`
+ *  to perform a binary search on a sorted array.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // using `fromIndex`
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ *
+ * // performing a binary search
+ * _.indexOf([1, 1, 2, 2], 2, true);
+ * // => 2
+ */
+function indexOf(array, value, fromIndex) {
+  var length = array ? array.length : 0;
+  if (!length) {
+    return -1;
+  }
+  if (typeof fromIndex == 'number') {
+    fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
+  } else if (fromIndex) {
+    var index = binaryIndex(array, value);
+    if (index < length &&
+        (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
+      return index;
+    }
+    return -1;
+  }
+  return baseIndexOf(array, value, fromIndex || 0);
+}
+
+module.exports = indexOf;
+
+},{"../internal/baseIndexOf":80,"../internal/binaryIndex":94}],52:[function(require,module,exports){
+/**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+function last(array) {
+  var length = array ? array.length : 0;
+  return length ? array[length - 1] : undefined;
+}
+
+module.exports = last;
+
+},{}],53:[function(require,module,exports){
+var LazyWrapper = require('../internal/LazyWrapper'),
+    LodashWrapper = require('../internal/LodashWrapper'),
+    baseLodash = require('../internal/baseLodash'),
+    isArray = require('../lang/isArray'),
+    isObjectLike = require('../internal/isObjectLike'),
+    wrapperClone = require('../internal/wrapperClone');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Creates a `lodash` object which wraps `value` to enable implicit chaining.
+ * Methods that operate on and return arrays, collections, and functions can
+ * be chained together. Methods that retrieve a single value or may return a
+ * primitive value will automatically end the chain returning the unwrapped
+ * value. Explicit chaining may be enabled using `_.chain`. The execution of
+ * chained methods is lazy, that is, execution is deferred until `_#value`
+ * is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+ * fusion is an optimization strategy which merge iteratee calls; this can help
+ * to avoid the creation of intermediate data structures and greatly reduce the
+ * number of iteratee executions.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
+ * `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
+ * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
+ * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
+ * and `where`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
+ * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
+ * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
+ * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
+ * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
+ * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
+ * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
+ * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
+ * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
+ * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
+ * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
+ * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
+ * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
+ * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
+ * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
+ * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
+ * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
+ * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
+ * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
+ * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+ * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
+ * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
+ * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
+ * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
+ * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
+ * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
+ * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+ * `unescape`, `uniqueId`, `value`, and `words`
+ *
+ * The wrapper method `sample` will return a wrapped value when `n` is provided,
+ * otherwise an unwrapped value is returned.
+ *
+ * @name _
+ * @constructor
+ * @category Chain
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // returns an unwrapped value
+ * wrapped.reduce(function(total, n) {
+ *   return total + n;
+ * });
+ * // => 6
+ *
+ * // returns a wrapped value
+ * var squares = wrapped.map(function(n) {
+ *   return n * n;
+ * });
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+function lodash(value) {
+  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+    if (value instanceof LodashWrapper) {
+      return value;
+    }
+    if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
+      return wrapperClone(value);
+    }
+  }
+  return new LodashWrapper(value);
+}
+
+// Ensure wrappers are instances of `baseLodash`.
+lodash.prototype = baseLodash.prototype;
+
+module.exports = lodash;
+
+},{"../internal/LazyWrapper":62,"../internal/LodashWrapper":63,"../internal/baseLodash":84,"../internal/isObjectLike":128,"../internal/wrapperClone":139,"../lang/isArray":142}],54:[function(require,module,exports){
+module.exports = require('./forEach');
+
+},{"./forEach":56}],55:[function(require,module,exports){
+var baseEach = require('../internal/baseEach'),
+    createFind = require('../internal/createFind');
+
+/**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is bound to `thisArg` and
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * If a property name is provided for `predicate` the created `_.property`
+ * style callback returns the property value of the given element.
+ *
+ * If a value is also provided for `thisArg` the created `_.matchesProperty`
+ * style callback returns `true` for elements that have a matching property
+ * value, else `false`.
+ *
+ * If an object is provided for `predicate` the created `_.matches` style
+ * callback returns `true` for elements that have the properties of the given
+ * object, else `false`.
+ *
+ * @static
+ * @memberOf _
+ * @alias detect
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked
+ *  per iteration.
+ * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'barney',  'age': 36, 'active': true },
+ *   { 'user': 'fred',    'age': 40, 'active': false },
+ *   { 'user': 'pebbles', 'age': 1,  'active': true }
+ * ];
+ *
+ * _.result(_.find(users, function(chr) {
+ *   return chr.age < 40;
+ * }), 'user');
+ * // => 'barney'
+ *
+ * // using the `_.matches` callback shorthand
+ * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
+ * // => 'pebbles'
+ *
+ * // using the `_.matchesProperty` callback shorthand
+ * _.result(_.find(users, 'active', false), 'user');
+ * // => 'fred'
+ *
+ * // using the `_.property` callback shorthand
+ * _.result(_.find(users, 'active'), 'user');
+ * // => 'barney'
+ */
+var find = createFind(baseEach);
+
+module.exports = find;
+
+},{"../internal/baseEach":73,"../internal/createFind":104}],56:[function(require,module,exports){
+var arrayEach = require('../internal/arrayEach'),
+    baseEach = require('../internal/baseEach'),
+    createForEach = require('../internal/createForEach');
+
+/**
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * (value, index|key, collection). Iteratee functions may exit iteration early
+ * by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
+ * may be used for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @alias each
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @returns {Array|Object|string} Returns `collection`.
+ * @example
+ *
+ * _([1, 2]).forEach(function(n) {
+ *   console.log(n);
+ * }).value();
+ * // => logs each value from left to right and returns the array
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
+ *   console.log(n, key);
+ * });
+ * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
+ */
+var forEach = createForEach(arrayEach, baseEach);
+
+module.exports = forEach;
+
+},{"../internal/arrayEach":65,"../internal/baseEach":73,"../internal/createForEach":105}],57:[function(require,module,exports){
+var baseIndexOf = require('../internal/baseIndexOf'),
+    getLength = require('../internal/getLength'),
+    isArray = require('../lang/isArray'),
+    isIterateeCall = require('../internal/isIterateeCall'),
+    isLength = require('../internal/isLength'),
+    isString = require('../lang/isString'),
+    values = require('../object/values');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Checks if `target` is in `collection` using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @alias contains, include
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {*} target The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
+ * @returns {boolean} Returns `true` if a matching element is found, else `false`.
+ * @example
+ *
+ * _.includes([1, 2, 3], 1);
+ * // => true
+ *
+ * _.includes([1, 2, 3], 1, 2);
+ * // => false
+ *
+ * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
+ * // => true
+ *
+ * _.includes('pebbles', 'eb');
+ * // => true
+ */
+function includes(collection, target, fromIndex, guard) {
+  var length = collection ? getLength(collection) : 0;
+  if (!isLength(length)) {
+    collection = values(collection);
+    length = collection.length;
+  }
+  if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
+    fromIndex = 0;
+  } else {
+    fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
+  }
+  return (typeof collection == 'string' || !isArray(collection) && isString(collection))
+    ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
+    : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
+}
+
+module.exports = includes;
+
+},{"../internal/baseIndexOf":80,"../internal/getLength":114,"../internal/isIterateeCall":124,"../internal/isLength":127,"../lang/isArray":142,"../lang/isString":148,"../object/values":154}],58:[function(require,module,exports){
+var arrayMap = require('../internal/arrayMap'),
+    baseCallback = require('../internal/baseCallback'),
+    baseMap = require('../internal/baseMap'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates an array of values by running each element in `collection` through
+ * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * If a property name is provided for `iteratee` the created `_.property`
+ * style callback returns the property value of the given element.
+ *
+ * If a value is also provided for `thisArg` the created `_.matchesProperty`
+ * style callback returns `true` for elements that have a matching property
+ * value, else `false`.
+ *
+ * If an object is provided for `iteratee` the created `_.matches` style
+ * callback returns `true` for elements that have the properties of the given
+ * object, else `false`.
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
+ * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
+ * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
+ * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
+ * `sum`, `uniq`, and `words`
+ *
+ * @static
+ * @memberOf _
+ * @alias collect
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked
+ *  per iteration.
+ * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function timesThree(n) {
+ *   return n * 3;
+ * }
+ *
+ * _.map([1, 2], timesThree);
+ * // => [3, 6]
+ *
+ * _.map({ 'a': 1, 'b': 2 }, timesThree);
+ * // => [3, 6] (iteration order is not guaranteed)
+ *
+ * var users = [
+ *   { 'user': 'barney' },
+ *   { 'user': 'fred' }
+ * ];
+ *
+ * // using the `_.property` callback shorthand
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */
+function map(collection, iteratee, thisArg) {
+  var func = isArray(collection) ? arrayMap : baseMap;
+  iteratee = baseCallback(iteratee, thisArg, 3);
+  return func(collection, iteratee);
+}
+
+module.exports = map;
+
+},{"../internal/arrayMap":66,"../internal/baseCallback":69,"../internal/baseMap":85,"../lang/isArray":142}],59:[function(require,module,exports){
+var getNative = require('../internal/getNative');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeNow = getNative(Date, 'now');
+
+/**
+ * Gets the number of milliseconds that have elapsed since the Unix epoch
+ * (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @category Date
+ * @example
+ *
+ * _.defer(function(stamp) {
+ *   console.log(_.now() - stamp);
+ * }, _.now());
+ * // => logs the number of milliseconds it took for the deferred function to be invoked
+ */
+var now = nativeNow || function() {
+  return new Date().getTime();
+};
+
+module.exports = now;
+
+},{"../internal/getNative":116}],60:[function(require,module,exports){
+var createWrapper = require('../internal/createWrapper'),
+    replaceHolders = require('../internal/replaceHolders'),
+    restParam = require('./restParam');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    PARTIAL_FLAG = 32;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of `thisArg`
+ * and prepends any additional `_.bind` arguments to those provided to the
+ * bound function.
+ *
+ * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** Unlike native `Function#bind` this method does not set the "length"
+ * property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * var greet = function(greeting, punctuation) {
+ *   return greeting + ' ' + this.user + punctuation;
+ * };
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * var bound = _.bind(greet, object, 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * // using placeholders
+ * var bound = _.bind(greet, object, _, '!');
+ * bound('hi');
+ * // => 'hi fred!'
+ */
+var bind = restParam(function(func, thisArg, partials) {
+  var bitmask = BIND_FLAG;
+  if (partials.length) {
+    var holders = replaceHolders(partials, bind.placeholder);
+    bitmask |= PARTIAL_FLAG;
+  }
+  return createWrapper(func, bitmask, thisArg, partials, holders);
+});
+
+// Assign default placeholders.
+bind.placeholder = {};
+
+module.exports = bind;
+
+},{"../internal/createWrapper":108,"../internal/replaceHolders":134,"./restParam":61}],61:[function(require,module,exports){
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.restParam(function(what, names) {
+ *   return what + ' ' + _.initial(names).join(', ') +
+ *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+function restParam(func, start) {
+  if (typeof func != 'function') {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+  return function() {
+    var args = arguments,
+        index = -1,
+        length = nativeMax(args.length - start, 0),
+        rest = Array(length);
+
+    while (++index < length) {
+      rest[index] = args[start + index];
+    }
+    switch (start) {
+      case 0: return func.call(this, rest);
+      case 1: return func.call(this, args[0], rest);
+      case 2: return func.call(this, args[0], args[1], rest);
+    }
+    var otherArgs = Array(start + 1);
+    index = -1;
+    while (++index < start) {
+      otherArgs[index] = args[index];
+    }
+    otherArgs[start] = rest;
+    return func.apply(this, otherArgs);
+  };
+}
+
+module.exports = restParam;
+
+},{}],62:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    baseLodash = require('./baseLodash');
+
+/** Used as references for `-Infinity` and `Infinity`. */
+var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+
+/**
+ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ */
+function LazyWrapper(value) {
+  this.__wrapped__ = value;
+  this.__actions__ = [];
+  this.__dir__ = 1;
+  this.__filtered__ = false;
+  this.__iteratees__ = [];
+  this.__takeCount__ = POSITIVE_INFINITY;
+  this.__views__ = [];
+}
+
+LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+LazyWrapper.prototype.constructor = LazyWrapper;
+
+module.exports = LazyWrapper;
+
+},{"./baseCreate":72,"./baseLodash":84}],63:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    baseLodash = require('./baseLodash');
+
+/**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
+ * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
+ */
+function LodashWrapper(value, chainAll, actions) {
+  this.__wrapped__ = value;
+  this.__actions__ = actions || [];
+  this.__chain__ = !!chainAll;
+}
+
+LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+LodashWrapper.prototype.constructor = LodashWrapper;
+
+module.exports = LodashWrapper;
+
+},{"./baseCreate":72,"./baseLodash":84}],64:[function(require,module,exports){
+/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+function arrayCopy(source, array) {
+  var index = -1,
+      length = source.length;
+
+  array || (array = Array(length));
+  while (++index < length) {
+    array[index] = source[index];
+  }
+  return array;
+}
+
+module.exports = arrayCopy;
+
+},{}],65:[function(require,module,exports){
+/**
+ * A specialized version of `_.forEach` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+function arrayEach(array, iteratee) {
+  var index = -1,
+      length = array.length;
+
+  while (++index < length) {
+    if (iteratee(array[index], index, array) === false) {
+      break;
+    }
+  }
+  return array;
+}
+
+module.exports = arrayEach;
+
+},{}],66:[function(require,module,exports){
+/**
+ * A specialized version of `_.map` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+function arrayMap(array, iteratee) {
+  var index = -1,
+      length = array.length,
+      result = Array(length);
+
+  while (++index < length) {
+    result[index] = iteratee(array[index], index, array);
+  }
+  return result;
+}
+
+module.exports = arrayMap;
+
+},{}],67:[function(require,module,exports){
+/**
+ * A specialized version of `_.some` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ *  else `false`.
+ */
+function arraySome(array, predicate) {
+  var index = -1,
+      length = array.length;
+
+  while (++index < length) {
+    if (predicate(array[index], index, array)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+module.exports = arraySome;
+
+},{}],68:[function(require,module,exports){
+var baseCopy = require('./baseCopy'),
+    keys = require('../object/keys');
+
+/**
+ * The base implementation of `_.assign` without support for argument juggling,
+ * multiple sources, and `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+function baseAssign(object, source) {
+  return source == null
+    ? object
+    : baseCopy(source, keys(source), object);
+}
+
+module.exports = baseAssign;
+
+},{"../object/keys":151,"./baseCopy":71}],69:[function(require,module,exports){
+var baseMatches = require('./baseMatches'),
+    baseMatchesProperty = require('./baseMatchesProperty'),
+    bindCallback = require('./bindCallback'),
+    identity = require('../utility/identity'),
+    property = require('../utility/property');
+
+/**
+ * The base implementation of `_.callback` which supports specifying the
+ * number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function baseCallback(func, thisArg, argCount) {
+  var type = typeof func;
+  if (type == 'function') {
+    return thisArg === undefined
+      ? func
+      : bindCallback(func, thisArg, argCount);
+  }
+  if (func == null) {
+    return identity;
+  }
+  if (type == 'object') {
+    return baseMatches(func);
+  }
+  return thisArg === undefined
+    ? property(func)
+    : baseMatchesProperty(func, thisArg);
+}
+
+module.exports = baseCallback;
+
+},{"../utility/identity":156,"../utility/property":158,"./baseMatches":86,"./baseMatchesProperty":87,"./bindCallback":96}],70:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    arrayEach = require('./arrayEach'),
+    baseAssign = require('./baseAssign'),
+    baseForOwn = require('./baseForOwn'),
+    initCloneArray = require('./initCloneArray'),
+    initCloneByTag = require('./initCloneByTag'),
+    initCloneObject = require('./initCloneObject'),
+    isArray = require('../lang/isArray'),
+    isHostObject = require('./isHostObject'),
+    isObject = require('../lang/isObject');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to identify `toStringTag` values supported by `_.clone`. */
+var cloneableTags = {};
+cloneableTags[argsTag] = cloneableTags[arrayTag] =
+cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+cloneableTags[dateTag] = cloneableTags[float32Tag] =
+cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+cloneableTags[numberTag] = cloneableTags[objectTag] =
+cloneableTags[regexpTag] = cloneableTags[stringTag] =
+cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+cloneableTags[errorTag] = cloneableTags[funcTag] =
+cloneableTags[mapTag] = cloneableTags[setTag] =
+cloneableTags[weakMapTag] = false;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * The base implementation of `_.clone` without support for argument juggling
+ * and `this` binding `customizer` functions.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The object `value` belongs to.
+ * @param {Array} [stackA=[]] Tracks traversed source objects.
+ * @param {Array} [stackB=[]] Associates clones with source counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+  var result;
+  if (customizer) {
+    result = object ? customizer(value, key, object) : customizer(value);
+  }
+  if (result !== undefined) {
+    return result;
+  }
+  if (!isObject(value)) {
+    return value;
+  }
+  var isArr = isArray(value);
+  if (isArr) {
+    result = initCloneArray(value);
+    if (!isDeep) {
+      return arrayCopy(value, result);
+    }
+  } else {
+    var tag = objToString.call(value),
+        isFunc = tag == funcTag;
+
+    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+      if (isHostObject(value)) {
+        return object ? value : {};
+      }
+      result = initCloneObject(isFunc ? {} : value);
+      if (!isDeep) {
+        return baseAssign(result, value);
+      }
+    } else {
+      return cloneableTags[tag]
+        ? initCloneByTag(value, tag, isDeep)
+        : (object ? value : {});
+    }
+  }
+  // Check for circular references and return its corresponding clone.
+  stackA || (stackA = []);
+  stackB || (stackB = []);
+
+  var length = stackA.length;
+  while (length--) {
+    if (stackA[length] == value) {
+      return stackB[length];
+    }
+  }
+  // Add the source value to the stack of traversed objects and associate it with its clone.
+  stackA.push(value);
+  stackB.push(result);
+
+  // Recursively populate clone (susceptible to call stack limits).
+  (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+    result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+  });
+  return result;
+}
+
+module.exports = baseClone;
+
+},{"../lang/isArray":142,"../lang/isObject":146,"./arrayCopy":64,"./arrayEach":65,"./baseAssign":68,"./baseForOwn":78,"./initCloneArray":118,"./initCloneByTag":119,"./initCloneObject":120,"./isHostObject":122}],71:[function(require,module,exports){
+/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+function baseCopy(source, props, object) {
+  object || (object = {});
+
+  var index = -1,
+      length = props.length;
+
+  while (++index < length) {
+    var key = props[index];
+    object[key] = source[key];
+  }
+  return object;
+}
+
+module.exports = baseCopy;
+
+},{}],72:[function(require,module,exports){
+var isObject = require('../lang/isObject');
+
+/**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} prototype The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+var baseCreate = (function() {
+  function object() {}
+  return function(prototype) {
+    if (isObject(prototype)) {
+      object.prototype = prototype;
+      var result = new object;
+      object.prototype = undefined;
+    }
+    return result || {};
+  };
+}());
+
+module.exports = baseCreate;
+
+},{"../lang/isObject":146}],73:[function(require,module,exports){
+var baseForOwn = require('./baseForOwn'),
+    createBaseEach = require('./createBaseEach');
+
+/**
+ * The base implementation of `_.forEach` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object|string} Returns `collection`.
+ */
+var baseEach = createBaseEach(baseForOwn);
+
+module.exports = baseEach;
+
+},{"./baseForOwn":78,"./createBaseEach":100}],74:[function(require,module,exports){
+/**
+ * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
+ * without support for callback shorthands and `this` binding, which iterates
+ * over `collection` using the provided `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @param {boolean} [retKey] Specify returning the key of the found element
+ *  instead of the element itself.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+function baseFind(collection, predicate, eachFunc, retKey) {
+  var result;
+  eachFunc(collection, function(value, key, collection) {
+    if (predicate(value, key, collection)) {
+      result = retKey ? key : value;
+      return false;
+    }
+  });
+  return result;
+}
+
+module.exports = baseFind;
+
+},{}],75:[function(require,module,exports){
+/**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for callback shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseFindIndex(array, predicate, fromRight) {
+  var length = array.length,
+      index = fromRight ? length : -1;
+
+  while ((fromRight ? index-- : ++index < length)) {
+    if (predicate(array[index], index, array)) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = baseFindIndex;
+
+},{}],76:[function(require,module,exports){
+var createBaseFor = require('./createBaseFor');
+
+/**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+module.exports = baseFor;
+
+},{"./createBaseFor":101}],77:[function(require,module,exports){
+var baseFor = require('./baseFor'),
+    keysIn = require('../object/keysIn');
+
+/**
+ * The base implementation of `_.forIn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForIn(object, iteratee) {
+  return baseFor(object, iteratee, keysIn);
+}
+
+module.exports = baseForIn;
+
+},{"../object/keysIn":152,"./baseFor":76}],78:[function(require,module,exports){
+var baseFor = require('./baseFor'),
+    keys = require('../object/keys');
+
+/**
+ * The base implementation of `_.forOwn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForOwn(object, iteratee) {
+  return baseFor(object, iteratee, keys);
+}
+
+module.exports = baseForOwn;
+
+},{"../object/keys":151,"./baseFor":76}],79:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * The base implementation of `get` without support for string paths
+ * and default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path of the property to get.
+ * @param {string} [pathKey] The key representation of path.
+ * @returns {*} Returns the resolved value.
+ */
+function baseGet(object, path, pathKey) {
+  if (object == null) {
+    return;
+  }
+  object = toObject(object);
+  if (pathKey !== undefined && pathKey in object) {
+    path = [pathKey];
+  }
+  var index = 0,
+      length = path.length;
+
+  while (object != null && index < length) {
+    object = toObject(object)[path[index++]];
+  }
+  return (index && index == length) ? object : undefined;
+}
+
+module.exports = baseGet;
+
+},{"./toObject":137}],80:[function(require,module,exports){
+var indexOfNaN = require('./indexOfNaN');
+
+/**
+ * The base implementation of `_.indexOf` without support for binary searches.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseIndexOf(array, value, fromIndex) {
+  if (value !== value) {
+    return indexOfNaN(array, fromIndex);
+  }
+  var index = fromIndex - 1,
+      length = array.length;
+
+  while (++index < length) {
+    if (array[index] === value) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = baseIndexOf;
+
+},{"./indexOfNaN":117}],81:[function(require,module,exports){
+var baseIsEqualDeep = require('./baseIsEqualDeep'),
+    isObject = require('../lang/isObject'),
+    isObjectLike = require('./isObjectLike');
+
+/**
+ * The base implementation of `_.isEqual` without support for `this` binding
+ * `customizer` functions.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparing values.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */
+function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+  if (value === other) {
+    return true;
+  }
+  if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+    return value !== value && other !== other;
+  }
+  return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+}
+
+module.exports = baseIsEqual;
+
+},{"../lang/isObject":146,"./baseIsEqualDeep":82,"./isObjectLike":128}],82:[function(require,module,exports){
+var equalArrays = require('./equalArrays'),
+    equalByTag = require('./equalByTag'),
+    equalObjects = require('./equalObjects'),
+    isArray = require('../lang/isArray'),
+    isHostObject = require('./isHostObject'),
+    isTypedArray = require('../lang/isTypedArray');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    objectTag = '[object Object]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing objects.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA=[]] Tracks traversed `value` objects.
+ * @param {Array} [stackB=[]] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var objIsArr = isArray(object),
+      othIsArr = isArray(other),
+      objTag = arrayTag,
+      othTag = arrayTag;
+
+  if (!objIsArr) {
+    objTag = objToString.call(object);
+    if (objTag == argsTag) {
+      objTag = objectTag;
+    } else if (objTag != objectTag) {
+      objIsArr = isTypedArray(object);
+    }
+  }
+  if (!othIsArr) {
+    othTag = objToString.call(other);
+    if (othTag == argsTag) {
+      othTag = objectTag;
+    } else if (othTag != objectTag) {
+      othIsArr = isTypedArray(other);
+    }
+  }
+  var objIsObj = objTag == objectTag && !isHostObject(object),
+      othIsObj = othTag == objectTag && !isHostObject(other),
+      isSameTag = objTag == othTag;
+
+  if (isSameTag && !(objIsArr || objIsObj)) {
+    return equalByTag(object, other, objTag);
+  }
+  if (!isLoose) {
+    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+    if (objIsWrapped || othIsWrapped) {
+      return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+    }
+  }
+  if (!isSameTag) {
+    return false;
+  }
+  // Assume cyclic values are equal.
+  // For more information on detecting circular references see https://es5.github.io/#JO.
+  stackA || (stackA = []);
+  stackB || (stackB = []);
+
+  var length = stackA.length;
+  while (length--) {
+    if (stackA[length] == object) {
+      return stackB[length] == other;
+    }
+  }
+  // Add `object` and `other` to the stack of traversed objects.
+  stackA.push(object);
+  stackB.push(other);
+
+  var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
+
+  stackA.pop();
+  stackB.pop();
+
+  return result;
+}
+
+module.exports = baseIsEqualDeep;
+
+},{"../lang/isArray":142,"../lang/isTypedArray":149,"./equalArrays":109,"./equalByTag":110,"./equalObjects":111,"./isHostObject":122}],83:[function(require,module,exports){
+var baseIsEqual = require('./baseIsEqual'),
+    toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.isMatch` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Array} matchData The propery names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparing objects.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ */
+function baseIsMatch(object, matchData, customizer) {
+  var index = matchData.length,
+      length = index,
+      noCustomizer = !customizer;
+
+  if (object == null) {
+    return !length;
+  }
+  object = toObject(object);
+  while (index--) {
+    var data = matchData[index];
+    if ((noCustomizer && data[2])
+          ? data[1] !== object[data[0]]
+          : !(data[0] in object)
+        ) {
+      return false;
+    }
+  }
+  while (++index < length) {
+    data = matchData[index];
+    var key = data[0],
+        objValue = object[key],
+        srcValue = data[1];
+
+    if (noCustomizer && data[2]) {
+      if (objValue === undefined && !(key in object)) {
+        return false;
+      }
+    } else {
+      var result = customizer ? customizer(objValue, srcValue, key) : undefined;
+      if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+module.exports = baseIsMatch;
+
+},{"./baseIsEqual":81,"./toObject":137}],84:[function(require,module,exports){
+/**
+ * The function whose prototype all chaining wrappers inherit from.
+ *
+ * @private
+ */
+function baseLodash() {
+  // No operation performed.
+}
+
+module.exports = baseLodash;
+
+},{}],85:[function(require,module,exports){
+var baseEach = require('./baseEach'),
+    isArrayLike = require('./isArrayLike');
+
+/**
+ * The base implementation of `_.map` without support for callback shorthands
+ * and `this` binding.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+function baseMap(collection, iteratee) {
+  var index = -1,
+      result = isArrayLike(collection) ? Array(collection.length) : [];
+
+  baseEach(collection, function(value, key, collection) {
+    result[++index] = iteratee(value, key, collection);
+  });
+  return result;
+}
+
+module.exports = baseMap;
+
+},{"./baseEach":73,"./isArrayLike":121}],86:[function(require,module,exports){
+var baseIsMatch = require('./baseIsMatch'),
+    getMatchData = require('./getMatchData'),
+    toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.matches` which does not clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new function.
+ */
+function baseMatches(source) {
+  var matchData = getMatchData(source);
+  if (matchData.length == 1 && matchData[0][2]) {
+    var key = matchData[0][0],
+        value = matchData[0][1];
+
+    return function(object) {
+      if (object == null) {
+        return false;
+      }
+      object = toObject(object);
+      return object[key] === value && (value !== undefined || (key in object));
+    };
+  }
+  return function(object) {
+    return baseIsMatch(object, matchData);
+  };
+}
+
+module.exports = baseMatches;
+
+},{"./baseIsMatch":83,"./getMatchData":115,"./toObject":137}],87:[function(require,module,exports){
+var baseGet = require('./baseGet'),
+    baseIsEqual = require('./baseIsEqual'),
+    baseSlice = require('./baseSlice'),
+    isArray = require('../lang/isArray'),
+    isKey = require('./isKey'),
+    isStrictComparable = require('./isStrictComparable'),
+    last = require('../array/last'),
+    toObject = require('./toObject'),
+    toPath = require('./toPath');
+
+/**
+ * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
+ *
+ * @private
+ * @param {string} path The path of the property to get.
+ * @param {*} srcValue The value to compare.
+ * @returns {Function} Returns the new function.
+ */
+function baseMatchesProperty(path, srcValue) {
+  var isArr = isArray(path),
+      isCommon = isKey(path) && isStrictComparable(srcValue),
+      pathKey = (path + '');
+
+  path = toPath(path);
+  return function(object) {
+    if (object == null) {
+      return false;
+    }
+    var key = pathKey;
+    object = toObject(object);
+    if ((isArr || !isCommon) && !(key in object)) {
+      object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+      if (object == null) {
+        return false;
+      }
+      key = last(path);
+      object = toObject(object);
+    }
+    return object[key] === srcValue
+      ? (srcValue !== undefined || (key in object))
+      : baseIsEqual(srcValue, object[key], undefined, true);
+  };
+}
+
+module.exports = baseMatchesProperty;
+
+},{"../array/last":52,"../lang/isArray":142,"./baseGet":79,"./baseIsEqual":81,"./baseSlice":91,"./isKey":125,"./isStrictComparable":129,"./toObject":137,"./toPath":138}],88:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+  return function(object) {
+    return object == null ? undefined : toObject(object)[key];
+  };
+}
+
+module.exports = baseProperty;
+
+},{"./toObject":137}],89:[function(require,module,exports){
+var baseGet = require('./baseGet'),
+    toPath = require('./toPath');
+
+/**
+ * A specialized version of `baseProperty` which supports deep paths.
+ *
+ * @private
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function basePropertyDeep(path) {
+  var pathKey = (path + '');
+  path = toPath(path);
+  return function(object) {
+    return baseGet(object, path, pathKey);
+  };
+}
+
+module.exports = basePropertyDeep;
+
+},{"./baseGet":79,"./toPath":138}],90:[function(require,module,exports){
+var identity = require('../utility/identity'),
+    metaMap = require('./metaMap');
+
+/**
+ * The base implementation of `setData` without support for hot loop detection.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+var baseSetData = !metaMap ? identity : function(func, data) {
+  metaMap.set(func, data);
+  return func;
+};
+
+module.exports = baseSetData;
+
+},{"../utility/identity":156,"./metaMap":131}],91:[function(require,module,exports){
+/**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+function baseSlice(array, start, end) {
+  var index = -1,
+      length = array.length;
+
+  start = start == null ? 0 : (+start || 0);
+  if (start < 0) {
+    start = -start > length ? 0 : (length + start);
+  }
+  end = (end === undefined || end > length) ? length : (+end || 0);
+  if (end < 0) {
+    end += length;
+  }
+  length = start > end ? 0 : ((end - start) >>> 0);
+  start >>>= 0;
+
+  var result = Array(length);
+  while (++index < length) {
+    result[index] = array[index + start];
+  }
+  return result;
+}
+
+module.exports = baseSlice;
+
+},{}],92:[function(require,module,exports){
+/**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` or `undefined` values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+function baseToString(value) {
+  return value == null ? '' : (value + '');
+}
+
+module.exports = baseToString;
+
+},{}],93:[function(require,module,exports){
+/**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */
+function baseValues(object, props) {
+  var index = -1,
+      length = props.length,
+      result = Array(length);
+
+  while (++index < length) {
+    result[index] = object[props[index]];
+  }
+  return result;
+}
+
+module.exports = baseValues;
+
+},{}],94:[function(require,module,exports){
+var binaryIndexBy = require('./binaryIndexBy'),
+    identity = require('../utility/identity');
+
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295,
+    HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
+/**
+ * Performs a binary search of `array` to determine the index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ *  into `array`.
+ */
+function binaryIndex(array, value, retHighest) {
+  var low = 0,
+      high = array ? array.length : low;
+
+  if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
+    while (low < high) {
+      var mid = (low + high) >>> 1,
+          computed = array[mid];
+
+      if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
+        low = mid + 1;
+      } else {
+        high = mid;
+      }
+    }
+    return high;
+  }
+  return binaryIndexBy(array, value, identity, retHighest);
+}
+
+module.exports = binaryIndex;
+
+},{"../utility/identity":156,"./binaryIndexBy":95}],95:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeFloor = Math.floor,
+    nativeMin = Math.min;
+
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295,
+    MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
+
+/**
+ * This function is like `binaryIndex` except that it invokes `iteratee` for
+ * `value` and each element of `array` to compute their sort ranking. The
+ * iteratee is invoked with one argument; (value).
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ *  into `array`.
+ */
+function binaryIndexBy(array, value, iteratee, retHighest) {
+  value = iteratee(value);
+
+  var low = 0,
+      high = array ? array.length : 0,
+      valIsNaN = value !== value,
+      valIsNull = value === null,
+      valIsUndef = value === undefined;
+
+  while (low < high) {
+    var mid = nativeFloor((low + high) / 2),
+        computed = iteratee(array[mid]),
+        isDef = computed !== undefined,
+        isReflexive = computed === computed;
+
+    if (valIsNaN) {
+      var setLow = isReflexive || retHighest;
+    } else if (valIsNull) {
+      setLow = isReflexive && isDef && (retHighest || computed != null);
+    } else if (valIsUndef) {
+      setLow = isReflexive && (retHighest || isDef);
+    } else if (computed == null) {
+      setLow = false;
+    } else {
+      setLow = retHighest ? (computed <= value) : (computed < value);
+    }
+    if (setLow) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return nativeMin(high, MAX_ARRAY_INDEX);
+}
+
+module.exports = binaryIndexBy;
+
+},{}],96:[function(require,module,exports){
+var identity = require('../utility/identity');
+
+/**
+ * A specialized version of `baseCallback` which only supports `this` binding
+ * and specifying the number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function bindCallback(func, thisArg, argCount) {
+  if (typeof func != 'function') {
+    return identity;
+  }
+  if (thisArg === undefined) {
+    return func;
+  }
+  switch (argCount) {
+    case 1: return function(value) {
+      return func.call(thisArg, value);
+    };
+    case 3: return function(value, index, collection) {
+      return func.call(thisArg, value, index, collection);
+    };
+    case 4: return function(accumulator, value, index, collection) {
+      return func.call(thisArg, accumulator, value, index, collection);
+    };
+    case 5: return function(value, other, key, object, source) {
+      return func.call(thisArg, value, other, key, object, source);
+    };
+  }
+  return function() {
+    return func.apply(thisArg, arguments);
+  };
+}
+
+module.exports = bindCallback;
+
+},{"../utility/identity":156}],97:[function(require,module,exports){
+(function (global){
+/** Native method references. */
+var ArrayBuffer = global.ArrayBuffer,
+    Uint8Array = global.Uint8Array;
+
+/**
+ * Creates a clone of the given array buffer.
+ *
+ * @private
+ * @param {ArrayBuffer} buffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+function bufferClone(buffer) {
+  var result = new ArrayBuffer(buffer.byteLength),
+      view = new Uint8Array(result);
+
+  view.set(new Uint8Array(buffer));
+  return result;
+}
+
+module.exports = bufferClone;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgQXJyYXlCdWZmZXIgPSBnbG9iYWwuQXJyYXlCdWZmZXIsXG4gICAgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgZ2l2ZW4gYXJyYXkgYnVmZmVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gYnVmZmVyQ2xvbmUoYnVmZmVyKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXlCdWZmZXIoYnVmZmVyLmJ5dGVMZW5ndGgpLFxuICAgICAgdmlldyA9IG5ldyBVaW50OEFycmF5KHJlc3VsdCk7XG5cbiAgdmlldy5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVmZmVyQ2xvbmU7XG4iXX0=
+},{}],98:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates an array that is the composition of partially applied arguments,
+ * placeholders, and provided arguments into a single array of arguments.
+ *
+ * @private
+ * @param {Array|Object} args The provided arguments.
+ * @param {Array} partials The arguments to prepend to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+function composeArgs(args, partials, holders) {
+  var holdersLength = holders.length,
+      argsIndex = -1,
+      argsLength = nativeMax(args.length - holdersLength, 0),
+      leftIndex = -1,
+      leftLength = partials.length,
+      result = Array(leftLength + argsLength);
+
+  while (++leftIndex < leftLength) {
+    result[leftIndex] = partials[leftIndex];
+  }
+  while (++argsIndex < holdersLength) {
+    result[holders[argsIndex]] = args[argsIndex];
+  }
+  while (argsLength--) {
+    result[leftIndex++] = args[argsIndex++];
+  }
+  return result;
+}
+
+module.exports = composeArgs;
+
+},{}],99:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * This function is like `composeArgs` except that the arguments composition
+ * is tailored for `_.partialRight`.
+ *
+ * @private
+ * @param {Array|Object} args The provided arguments.
+ * @param {Array} partials The arguments to append to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+function composeArgsRight(args, partials, holders) {
+  var holdersIndex = -1,
+      holdersLength = holders.length,
+      argsIndex = -1,
+      argsLength = nativeMax(args.length - holdersLength, 0),
+      rightIndex = -1,
+      rightLength = partials.length,
+      result = Array(argsLength + rightLength);
+
+  while (++argsIndex < argsLength) {
+    result[argsIndex] = args[argsIndex];
+  }
+  var offset = argsIndex;
+  while (++rightIndex < rightLength) {
+    result[offset + rightIndex] = partials[rightIndex];
+  }
+  while (++holdersIndex < holdersLength) {
+    result[offset + holders[holdersIndex]] = args[argsIndex++];
+  }
+  return result;
+}
+
+module.exports = composeArgsRight;
+
+},{}],100:[function(require,module,exports){
+var getLength = require('./getLength'),
+    isLength = require('./isLength'),
+    toObject = require('./toObject');
+
+/**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseEach(eachFunc, fromRight) {
+  return function(collection, iteratee) {
+    var length = collection ? getLength(collection) : 0;
+    if (!isLength(length)) {
+      return eachFunc(collection, iteratee);
+    }
+    var index = fromRight ? length : -1,
+        iterable = toObject(collection);
+
+    while ((fromRight ? index-- : ++index < length)) {
+      if (iteratee(iterable[index], index, iterable) === false) {
+        break;
+      }
+    }
+    return collection;
+  };
+}
+
+module.exports = createBaseEach;
+
+},{"./getLength":114,"./isLength":127,"./toObject":137}],101:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * Creates a base function for `_.forIn` or `_.forInRight`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+  return function(object, iteratee, keysFunc) {
+    var iterable = toObject(object),
+        props = keysFunc(object),
+        length = props.length,
+        index = fromRight ? length : -1;
+
+    while ((fromRight ? index-- : ++index < length)) {
+      var key = props[index];
+      if (iteratee(iterable[key], key, iterable) === false) {
+        break;
+      }
+    }
+    return object;
+  };
+}
+
+module.exports = createBaseFor;
+
+},{"./toObject":137}],102:[function(require,module,exports){
+(function (global){
+var createCtorWrapper = require('./createCtorWrapper');
+
+/**
+ * Creates a function that wraps `func` and invokes it with the `this`
+ * binding of `thisArg`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @returns {Function} Returns the new bound function.
+ */
+function createBindWrapper(func, thisArg) {
+  var Ctor = createCtorWrapper(func);
+
+  function wrapper() {
+    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+    return fn.apply(thisArg, arguments);
+  }
+  return wrapper;
+}
+
+module.exports = createBindWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUJpbmRXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcbiJdfQ==
+},{"./createCtorWrapper":103}],103:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    isObject = require('../lang/isObject');
+
+/**
+ * Creates a function that produces an instance of `Ctor` regardless of
+ * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+ *
+ * @private
+ * @param {Function} Ctor The constructor to wrap.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createCtorWrapper(Ctor) {
+  return function() {
+    // Use a `switch` statement to work with class constructors.
+    // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+    // for more details.
+    var args = arguments;
+    switch (args.length) {
+      case 0: return new Ctor;
+      case 1: return new Ctor(args[0]);
+      case 2: return new Ctor(args[0], args[1]);
+      case 3: return new Ctor(args[0], args[1], args[2]);
+      case 4: return new Ctor(args[0], args[1], args[2], args[3]);
+      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+    }
+    var thisBinding = baseCreate(Ctor.prototype),
+        result = Ctor.apply(thisBinding, args);
+
+    // Mimic the constructor's `return` behavior.
+    // See https://es5.github.io/#x13.2.2 for more details.
+    return isObject(result) ? result : thisBinding;
+  };
+}
+
+module.exports = createCtorWrapper;
+
+},{"../lang/isObject":146,"./baseCreate":72}],104:[function(require,module,exports){
+var baseCallback = require('./baseCallback'),
+    baseFind = require('./baseFind'),
+    baseFindIndex = require('./baseFindIndex'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates a `_.find` or `_.findLast` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new find function.
+ */
+function createFind(eachFunc, fromRight) {
+  return function(collection, predicate, thisArg) {
+    predicate = baseCallback(predicate, thisArg, 3);
+    if (isArray(collection)) {
+      var index = baseFindIndex(collection, predicate, fromRight);
+      return index > -1 ? collection[index] : undefined;
+    }
+    return baseFind(collection, predicate, eachFunc);
+  };
+}
+
+module.exports = createFind;
+
+},{"../lang/isArray":142,"./baseCallback":69,"./baseFind":74,"./baseFindIndex":75}],105:[function(require,module,exports){
+var bindCallback = require('./bindCallback'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates a function for `_.forEach` or `_.forEachRight`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over an array.
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @returns {Function} Returns the new each function.
+ */
+function createForEach(arrayFunc, eachFunc) {
+  return function(collection, iteratee, thisArg) {
+    return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
+      ? arrayFunc(collection, iteratee)
+      : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
+  };
+}
+
+module.exports = createForEach;
+
+},{"../lang/isArray":142,"./bindCallback":96}],106:[function(require,module,exports){
+(function (global){
+var arrayCopy = require('./arrayCopy'),
+    composeArgs = require('./composeArgs'),
+    composeArgsRight = require('./composeArgsRight'),
+    createCtorWrapper = require('./createCtorWrapper'),
+    isLaziable = require('./isLaziable'),
+    reorder = require('./reorder'),
+    replaceHolders = require('./replaceHolders'),
+    setData = require('./setData');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    BIND_KEY_FLAG = 2,
+    CURRY_BOUND_FLAG = 4,
+    CURRY_FLAG = 8,
+    CURRY_RIGHT_FLAG = 16,
+    PARTIAL_FLAG = 32,
+    PARTIAL_RIGHT_FLAG = 64,
+    ARY_FLAG = 128;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that wraps `func` and invokes it with optional `this`
+ * binding of, partial application, and currying.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to reference.
+ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
+ * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+  var isAry = bitmask & ARY_FLAG,
+      isBind = bitmask & BIND_FLAG,
+      isBindKey = bitmask & BIND_KEY_FLAG,
+      isCurry = bitmask & CURRY_FLAG,
+      isCurryBound = bitmask & CURRY_BOUND_FLAG,
+      isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+      Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+  function wrapper() {
+    // Avoid `arguments` object use disqualifying optimizations by
+    // converting it to an array before providing it to other functions.
+    var length = arguments.length,
+        index = length,
+        args = Array(length);
+
+    while (index--) {
+      args[index] = arguments[index];
+    }
+    if (partials) {
+      args = composeArgs(args, partials, holders);
+    }
+    if (partialsRight) {
+      args = composeArgsRight(args, partialsRight, holdersRight);
+    }
+    if (isCurry || isCurryRight) {
+      var placeholder = wrapper.placeholder,
+          argsHolders = replaceHolders(args, placeholder);
+
+      length -= argsHolders.length;
+      if (length < arity) {
+        var newArgPos = argPos ? arrayCopy(argPos) : undefined,
+            newArity = nativeMax(arity - length, 0),
+            newsHolders = isCurry ? argsHolders : undefined,
+            newHoldersRight = isCurry ? undefined : argsHolders,
+            newPartials = isCurry ? args : undefined,
+            newPartialsRight = isCurry ? undefined : args;
+
+        bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+        bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+        if (!isCurryBound) {
+          bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+        }
+        var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
+            result = createHybridWrapper.apply(undefined, newData);
+
+        if (isLaziable(func)) {
+          setData(result, newData);
+        }
+        result.placeholder = placeholder;
+        return result;
+      }
+    }
+    var thisBinding = isBind ? thisArg : this,
+        fn = isBindKey ? thisBinding[func] : func;
+
+    if (argPos) {
+      args = reorder(args, argPos);
+    }
+    if (isAry && ary < args.length) {
+      args.length = ary;
+    }
+    if (this && this !== global && this instanceof wrapper) {
+      fn = Ctor || createCtorWrapper(func);
+    }
+    return fn.apply(thisBinding, args);
+  }
+  return wrapper;
+}
+
+module.exports = createHybridWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUh5YnJpZFdyYXBwZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKSxcbiAgICBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3MnKSxcbiAgICBjb21wb3NlQXJnc1JpZ2h0ID0gcmVxdWlyZSgnLi9jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyksXG4gICAgaXNMYXppYWJsZSA9IHJlcXVpcmUoJy4vaXNMYXppYWJsZScpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL3Jlb3JkZXInKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vcmVwbGFjZUhvbGRlcnMnKSxcbiAgICBzZXREYXRhID0gcmVxdWlyZSgnLi9zZXREYXRhJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMSxcbiAgICBCSU5EX0tFWV9GTEFHID0gMixcbiAgICBDVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBDVVJSWV9GTEFHID0gOCxcbiAgICBDVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgUEFSVElBTF9GTEFHID0gMzIsXG4gICAgUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgQVJZX0ZMQUcgPSAxMjg7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mLCBwYXJ0aWFsIGFwcGxpY2F0aW9uLCBhbmQgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBvZiBmbGFncy4gU2VlIGBjcmVhdGVXcmFwcGVyYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc1JpZ2h0XSBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBBUllfRkxBRyxcbiAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRyxcbiAgICAgIGlzQ3VycnkgPSBiaXRtYXNrICYgQ1VSUllfRkxBRyxcbiAgICAgIGlzQ3VycnlCb3VuZCA9IGJpdG1hc2sgJiBDVVJSWV9CT1VORF9GTEFHLFxuICAgICAgaXNDdXJyeVJpZ2h0ID0gYml0bWFzayAmIENVUlJZX1JJR0hUX0ZMQUcsXG4gICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCB0byBvdGhlciBmdW5jdGlvbnMuXG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9XG4gICAgaWYgKHBhcnRpYWxzUmlnaHQpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCk7XG4gICAgfVxuICAgIGlmIChpc0N1cnJ5IHx8IGlzQ3VycnlSaWdodCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gd3JhcHBlci5wbGFjZWhvbGRlcixcbiAgICAgICAgICBhcmdzSG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgICAgbGVuZ3RoIC09IGFyZ3NIb2xkZXJzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCBhcml0eSkge1xuICAgICAgICB2YXIgbmV3QXJnUG9zID0gYXJnUG9zID8gYXJyYXlDb3B5KGFyZ1BvcykgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdBcml0eSA9IG5hdGl2ZU1heChhcml0eSAtIGxlbmd0aCwgMCksXG4gICAgICAgICAgICBuZXdzSG9sZGVycyA9IGlzQ3VycnkgPyBhcmdzSG9sZGVycyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzSG9sZGVycyxcbiAgICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IGFyZ3MgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdQYXJ0aWFsc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGFyZ3M7XG5cbiAgICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFBBUlRJQUxfRkxBRyA6IFBBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gUEFSVElBTF9SSUdIVF9GTEFHIDogUEFSVElBTF9GTEFHKTtcblxuICAgICAgICBpZiAoIWlzQ3VycnlCb3VuZCkge1xuICAgICAgICAgIGJpdG1hc2sgJj0gfihCSU5EX0ZMQUcgfCBCSU5EX0tFWV9GTEFHKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3c0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsIG5ld0hvbGRlcnNSaWdodCwgbmV3QXJnUG9zLCBhcnksIG5ld0FyaXR5XSxcbiAgICAgICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcblxuICAgICAgICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgIGZuID0gaXNCaW5kS2V5ID8gdGhpc0JpbmRpbmdbZnVuY10gOiBmdW5jO1xuXG4gICAgaWYgKGFyZ1Bvcykge1xuICAgICAgYXJncyA9IHJlb3JkZXIoYXJncywgYXJnUG9zKTtcbiAgICB9XG4gICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gZ2xvYmFsICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSB7XG4gICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlSHlicmlkV3JhcHBlcjtcbiJdfQ==
+},{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./createCtorWrapper":103,"./isLaziable":126,"./reorder":133,"./replaceHolders":134,"./setData":135}],107:[function(require,module,exports){
+(function (global){
+var createCtorWrapper = require('./createCtorWrapper');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1;
+
+/**
+ * Creates a function that wraps `func` and invokes it with the optional `this`
+ * binding of `thisArg` and the `partials` prepended to those provided to
+ * the wrapper.
+ *
+ * @private
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} partials The arguments to prepend to those provided to the new function.
+ * @returns {Function} Returns the new bound function.
+ */
+function createPartialWrapper(func, bitmask, thisArg, partials) {
+  var isBind = bitmask & BIND_FLAG,
+      Ctor = createCtorWrapper(func);
+
+  function wrapper() {
+    // Avoid `arguments` object use disqualifying optimizations by
+    // converting it to an array before providing it `func`.
+    var argsIndex = -1,
+        argsLength = arguments.length,
+        leftIndex = -1,
+        leftLength = partials.length,
+        args = Array(leftLength + argsLength);
+
+    while (++leftIndex < leftLength) {
+      args[leftIndex] = partials[leftIndex];
+    }
+    while (argsLength--) {
+      args[leftIndex++] = arguments[++argsIndex];
+    }
+    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+    return fn.apply(isBind ? thisArg : this, args);
+  }
+  return wrapper;
+}
+
+module.exports = createPartialWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHdyYXBwZXIgbWV0YWRhdGEuICovXG52YXIgQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgYW5kIGludm9rZXMgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCBhbmQgdGhlIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiB0aGUgd3JhcHBlci5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIG9mIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBwZXJgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWxXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgYGZ1bmNgLlxuICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICBhcmdzID0gQXJyYXkobGVmdExlbmd0aCArIGFyZ3NMZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgIH1cbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSBnbG9iYWwgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVQYXJ0aWFsV3JhcHBlcjtcbiJdfQ==
+},{"./createCtorWrapper":103}],108:[function(require,module,exports){
+var baseSetData = require('./baseSetData'),
+    createBindWrapper = require('./createBindWrapper'),
+    createHybridWrapper = require('./createHybridWrapper'),
+    createPartialWrapper = require('./createPartialWrapper'),
+    getData = require('./getData'),
+    mergeData = require('./mergeData'),
+    setData = require('./setData');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    BIND_KEY_FLAG = 2,
+    PARTIAL_FLAG = 32,
+    PARTIAL_RIGHT_FLAG = 64;
+
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that either curries or invokes `func` with optional
+ * `this` binding and partially applied arguments.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to reference.
+ * @param {number} bitmask The bitmask of flags.
+ *  The bitmask may be composed of the following flags:
+ *     1 - `_.bind`
+ *     2 - `_.bindKey`
+ *     4 - `_.curry` or `_.curryRight` of a bound function
+ *     8 - `_.curry`
+ *    16 - `_.curryRight`
+ *    32 - `_.partial`
+ *    64 - `_.partialRight`
+ *   128 - `_.rearg`
+ *   256 - `_.ary`
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to be partially applied.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+  var isBindKey = bitmask & BIND_KEY_FLAG;
+  if (!isBindKey && typeof func != 'function') {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  var length = partials ? partials.length : 0;
+  if (!length) {
+    bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
+    partials = holders = undefined;
+  }
+  length -= (holders ? holders.length : 0);
+  if (bitmask & PARTIAL_RIGHT_FLAG) {
+    var partialsRight = partials,
+        holdersRight = holders;
+
+    partials = holders = undefined;
+  }
+  var data = isBindKey ? undefined : getData(func),
+      newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
+
+  if (data) {
+    mergeData(newData, data);
+    bitmask = newData[1];
+    arity = newData[9];
+  }
+  newData[9] = arity == null
+    ? (isBindKey ? 0 : func.length)
+    : (nativeMax(arity - length, 0) || 0);
+
+  if (bitmask == BIND_FLAG) {
+    var result = createBindWrapper(newData[0], newData[2]);
+  } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
+    result = createPartialWrapper.apply(undefined, newData);
+  } else {
+    result = createHybridWrapper.apply(undefined, newData);
+  }
+  var setter = data ? baseSetData : setData;
+  return setter(result, newData);
+}
+
+module.exports = createWrapper;
+
+},{"./baseSetData":90,"./createBindWrapper":102,"./createHybridWrapper":106,"./createPartialWrapper":107,"./getData":112,"./mergeData":130,"./setData":135}],109:[function(require,module,exports){
+var arraySome = require('./arraySome');
+
+/**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing arrays.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */
+function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var index = -1,
+      arrLength = array.length,
+      othLength = other.length;
+
+  if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+    return false;
+  }
+  // Ignore non-index properties.
+  while (++index < arrLength) {
+    var arrValue = array[index],
+        othValue = other[index],
+        result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+
+    if (result !== undefined) {
+      if (result) {
+        continue;
+      }
+      return false;
+    }
+    // Recursively compare arrays (susceptible to call stack limits).
+    if (isLoose) {
+      if (!arraySome(other, function(othValue) {
+            return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+          })) {
+        return false;
+      }
+    } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+module.exports = equalArrays;
+
+},{"./arraySome":67}],110:[function(require,module,exports){
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+/**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalByTag(object, other, tag) {
+  switch (tag) {
+    case boolTag:
+    case dateTag:
+      // Coerce dates and booleans to numbers, dates to milliseconds and booleans
+      // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
+      return +object == +other;
+
+    case errorTag:
+      return object.name == other.name && object.message == other.message;
+
+    case numberTag:
+      // Treat `NaN` vs. `NaN` as equal.
+      return (object != +object)
+        ? other != +other
+        : object == +other;
+
+    case regexpTag:
+    case stringTag:
+      // Coerce regexes to strings and treat strings primitives and string
+      // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
+      return object == (other + '');
+  }
+  return false;
+}
+
+module.exports = equalByTag;
+
+},{}],111:[function(require,module,exports){
+var keys = require('../object/keys');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing values.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var objProps = keys(object),
+      objLength = objProps.length,
+      othProps = keys(other),
+      othLength = othProps.length;
+
+  if (objLength != othLength && !isLoose) {
+    return false;
+  }
+  var index = objLength;
+  while (index--) {
+    var key = objProps[index];
+    if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+      return false;
+    }
+  }
+  var skipCtor = isLoose;
+  while (++index < objLength) {
+    key = objProps[index];
+    var objValue = object[key],
+        othValue = other[key],
+        result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
+
+    // Recursively compare objects (susceptible to call stack limits).
+    if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
+      return false;
+    }
+    skipCtor || (skipCtor = key == 'constructor');
+  }
+  if (!skipCtor) {
+    var objCtor = object.constructor,
+        othCtor = other.constructor;
+
+    // Non `Object` object instances with different constructors are not equal.
+    if (objCtor != othCtor &&
+        ('constructor' in object && 'constructor' in other) &&
+        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+module.exports = equalObjects;
+
+},{"../object/keys":151}],112:[function(require,module,exports){
+var metaMap = require('./metaMap'),
+    noop = require('../utility/noop');
+
+/**
+ * Gets metadata for `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {*} Returns the metadata for `func`.
+ */
+var getData = !metaMap ? noop : function(func) {
+  return metaMap.get(func);
+};
+
+module.exports = getData;
+
+},{"../utility/noop":157,"./metaMap":131}],113:[function(require,module,exports){
+var realNames = require('./realNames');
+
+/**
+ * Gets the name of `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {string} Returns the function name.
+ */
+function getFuncName(func) {
+  var result = (func.name + ''),
+      array = realNames[result],
+      length = array ? array.length : 0;
+
+  while (length--) {
+    var data = array[length],
+        otherFunc = data.func;
+    if (otherFunc == null || otherFunc == func) {
+      return data.name;
+    }
+  }
+  return result;
+}
+
+module.exports = getFuncName;
+
+},{"./realNames":132}],114:[function(require,module,exports){
+var baseProperty = require('./baseProperty');
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+module.exports = getLength;
+
+},{"./baseProperty":88}],115:[function(require,module,exports){
+var isStrictComparable = require('./isStrictComparable'),
+    pairs = require('../object/pairs');
+
+/**
+ * Gets the propery names, values, and compare flags of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the match data of `object`.
+ */
+function getMatchData(object) {
+  var result = pairs(object),
+      length = result.length;
+
+  while (length--) {
+    result[length][2] = isStrictComparable(result[length][1]);
+  }
+  return result;
+}
+
+module.exports = getMatchData;
+
+},{"../object/pairs":153,"./isStrictComparable":129}],116:[function(require,module,exports){
+var isNative = require('../lang/isNative');
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+  var value = object == null ? undefined : object[key];
+  return isNative(value) ? value : undefined;
+}
+
+module.exports = getNative;
+
+},{"../lang/isNative":145}],117:[function(require,module,exports){
+/**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+function indexOfNaN(array, fromIndex, fromRight) {
+  var length = array.length,
+      index = fromIndex + (fromRight ? 0 : -1);
+
+  while ((fromRight ? index-- : ++index < length)) {
+    var other = array[index];
+    if (other !== other) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = indexOfNaN;
+
+},{}],118:[function(require,module,exports){
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+function initCloneArray(array) {
+  var length = array.length,
+      result = new array.constructor(length);
+
+  // Add array properties assigned by `RegExp#exec`.
+  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+    result.index = array.index;
+    result.input = array.input;
+  }
+  return result;
+}
+
+module.exports = initCloneArray;
+
+},{}],119:[function(require,module,exports){
+(function (global){
+var bufferClone = require('./bufferClone');
+
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to match `RegExp` flags from their coerced string values. */
+var reFlags = /\w*$/;
+
+/** Native method references. */
+var Uint8Array = global.Uint8Array;
+
+/** Used to lookup a type array constructors by `toStringTag`. */
+var ctorByTag = {};
+ctorByTag[float32Tag] = global.Float32Array;
+ctorByTag[float64Tag] = global.Float64Array;
+ctorByTag[int8Tag] = global.Int8Array;
+ctorByTag[int16Tag] = global.Int16Array;
+ctorByTag[int32Tag] = global.Int32Array;
+ctorByTag[uint8Tag] = Uint8Array;
+ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray;
+ctorByTag[uint16Tag] = global.Uint16Array;
+ctorByTag[uint32Tag] = global.Uint32Array;
+
+/**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneByTag(object, tag, isDeep) {
+  var Ctor = object.constructor;
+  switch (tag) {
+    case arrayBufferTag:
+      return bufferClone(object);
+
+    case boolTag:
+    case dateTag:
+      return new Ctor(+object);
+
+    case float32Tag: case float64Tag:
+    case int8Tag: case int16Tag: case int32Tag:
+    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+      // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.
+      if (Ctor instanceof Ctor) {
+        Ctor = ctorByTag[tag];
+      }
+      var buffer = object.buffer;
+      return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+
+    case numberTag:
+    case stringTag:
+      return new Ctor(object);
+
+    case regexpTag:
+      var result = new Ctor(object.source, reFlags.exec(object));
+      result.lastIndex = object.lastIndex;
+  }
+  return result;
+}
+
+module.exports = initCloneByTag;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iXX0=
+},{"./bufferClone":97}],120:[function(require,module,exports){
+/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneObject(object) {
+  var Ctor = object.constructor;
+  if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
+    Ctor = Object;
+  }
+  return new Ctor;
+}
+
+module.exports = initCloneObject;
+
+},{}],121:[function(require,module,exports){
+var getLength = require('./getLength'),
+    isLength = require('./isLength');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+  return value != null && isLength(getLength(value));
+}
+
+module.exports = isArrayLike;
+
+},{"./getLength":114,"./isLength":127}],122:[function(require,module,exports){
+/**
+ * Checks if `value` is a host object in IE < 9.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+ */
+var isHostObject = (function() {
+  try {
+    Object({ 'toString': 0 } + '');
+  } catch(e) {
+    return function() { return false; };
+  }
+  return function(value) {
+    // IE < 9 presents many host objects as `Object` objects that can coerce
+    // to strings despite having improperly defined `toString` methods.
+    return typeof value.toString != 'function' && typeof (value + '') == 'string';
+  };
+}());
+
+module.exports = isHostObject;
+
+},{}],123:[function(require,module,exports){
+/** Used to detect unsigned integer values. */
+var reIsUint = /^\d+$/;
+
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+  length = length == null ? MAX_SAFE_INTEGER : length;
+  return value > -1 && value % 1 == 0 && value < length;
+}
+
+module.exports = isIndex;
+
+},{}],124:[function(require,module,exports){
+var isArrayLike = require('./isArrayLike'),
+    isIndex = require('./isIndex'),
+    isObject = require('../lang/isObject');
+
+/**
+ * Checks if the provided arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
+ */
+function isIterateeCall(value, index, object) {
+  if (!isObject(object)) {
+    return false;
+  }
+  var type = typeof index;
+  if (type == 'number'
+      ? (isArrayLike(object) && isIndex(index, object.length))
+      : (type == 'string' && index in object)) {
+    var other = object[index];
+    return value === value ? (value === other) : (other !== other);
+  }
+  return false;
+}
+
+module.exports = isIterateeCall;
+
+},{"../lang/isObject":146,"./isArrayLike":121,"./isIndex":123}],125:[function(require,module,exports){
+var isArray = require('../lang/isArray'),
+    toObject = require('./toObject');
+
+/** Used to match property names within property paths. */
+var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+    reIsPlainProp = /^\w*$/;
+
+/**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */
+function isKey(value, object) {
+  var type = typeof value;
+  if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+    return true;
+  }
+  if (isArray(value)) {
+    return false;
+  }
+  var result = !reIsDeepProp.test(value);
+  return result || (object != null && value in toObject(object));
+}
+
+module.exports = isKey;
+
+},{"../lang/isArray":142,"./toObject":137}],126:[function(require,module,exports){
+var LazyWrapper = require('./LazyWrapper'),
+    getData = require('./getData'),
+    getFuncName = require('./getFuncName'),
+    lodash = require('../chain/lodash');
+
+/**
+ * Checks if `func` has a lazy counterpart.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
+ */
+function isLaziable(func) {
+  var funcName = getFuncName(func),
+      other = lodash[funcName];
+
+  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+    return false;
+  }
+  if (func === other) {
+    return true;
+  }
+  var data = getData(other);
+  return !!data && func === data[0];
+}
+
+module.exports = isLaziable;
+
+},{"../chain/lodash":53,"./LazyWrapper":62,"./getData":112,"./getFuncName":113}],127:[function(require,module,exports){
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+module.exports = isLength;
+
+},{}],128:[function(require,module,exports){
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+  return !!value && typeof value == 'object';
+}
+
+module.exports = isObjectLike;
+
+},{}],129:[function(require,module,exports){
+var isObject = require('../lang/isObject');
+
+/**
+ * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` if suitable for strict
+ *  equality comparisons, else `false`.
+ */
+function isStrictComparable(value) {
+  return value === value && !isObject(value);
+}
+
+module.exports = isStrictComparable;
+
+},{"../lang/isObject":146}],130:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    composeArgs = require('./composeArgs'),
+    composeArgsRight = require('./composeArgsRight'),
+    replaceHolders = require('./replaceHolders');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    CURRY_BOUND_FLAG = 4,
+    CURRY_FLAG = 8,
+    ARY_FLAG = 128,
+    REARG_FLAG = 256;
+
+/** Used as the internal argument placeholder. */
+var PLACEHOLDER = '__lodash_placeholder__';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
+
+/**
+ * Merges the function metadata of `source` into `data`.
+ *
+ * Merging metadata reduces the number of wrappers required to invoke a function.
+ * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
+ * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
+ * augment function arguments, making the order in which they are executed important,
+ * preventing the merging of metadata. However, we make an exception for a safe
+ * common case where curried functions have `_.ary` and or `_.rearg` applied.
+ *
+ * @private
+ * @param {Array} data The destination metadata.
+ * @param {Array} source The source metadata.
+ * @returns {Array} Returns `data`.
+ */
+function mergeData(data, source) {
+  var bitmask = data[1],
+      srcBitmask = source[1],
+      newBitmask = bitmask | srcBitmask,
+      isCommon = newBitmask < ARY_FLAG;
+
+  var isCombo =
+    (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
+    (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
+    (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+
+  // Exit early if metadata can't be merged.
+  if (!(isCommon || isCombo)) {
+    return data;
+  }
+  // Use source `thisArg` if available.
+  if (srcBitmask & BIND_FLAG) {
+    data[2] = source[2];
+    // Set when currying a bound function.
+    newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
+  }
+  // Compose partial arguments.
+  var value = source[3];
+  if (value) {
+    var partials = data[3];
+    data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
+    data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+  }
+  // Compose partial right arguments.
+  value = source[5];
+  if (value) {
+    partials = data[5];
+    data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
+    data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+  }
+  // Use source `argPos` if available.
+  value = source[7];
+  if (value) {
+    data[7] = arrayCopy(value);
+  }
+  // Use source `ary` if it's smaller.
+  if (srcBitmask & ARY_FLAG) {
+    data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+  }
+  // Use source `arity` if one is not provided.
+  if (data[9] == null) {
+    data[9] = source[9];
+  }
+  // Use source `func` and merge bitmasks.
+  data[0] = source[0];
+  data[1] = newBitmask;
+
+  return data;
+}
+
+module.exports = mergeData;
+
+},{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./replaceHolders":134}],131:[function(require,module,exports){
+(function (global){
+var getNative = require('./getNative');
+
+/** Native method references. */
+var WeakMap = getNative(global, 'WeakMap');
+
+/** Used to store function metadata. */
+var metaMap = WeakMap && new WeakMap;
+
+module.exports = metaMap;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcbiJdfQ==
+},{"./getNative":116}],132:[function(require,module,exports){
+/** Used to lookup unminified function names. */
+var realNames = {};
+
+module.exports = realNames;
+
+},{}],133:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    isIndex = require('./isIndex');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
+
+/**
+ * Reorder `array` according to the specified indexes where the element at
+ * the first index is assigned as the first element, the element at
+ * the second index is assigned as the second element, and so on.
+ *
+ * @private
+ * @param {Array} array The array to reorder.
+ * @param {Array} indexes The arranged array indexes.
+ * @returns {Array} Returns `array`.
+ */
+function reorder(array, indexes) {
+  var arrLength = array.length,
+      length = nativeMin(indexes.length, arrLength),
+      oldArray = arrayCopy(array);
+
+  while (length--) {
+    var index = indexes[length];
+    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+  }
+  return array;
+}
+
+module.exports = reorder;
+
+},{"./arrayCopy":64,"./isIndex":123}],134:[function(require,module,exports){
+/** Used as the internal argument placeholder. */
+var PLACEHOLDER = '__lodash_placeholder__';
+
+/**
+ * Replaces all `placeholder` elements in `array` with an internal placeholder
+ * and returns an array of their indexes.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {*} placeholder The placeholder to replace.
+ * @returns {Array} Returns the new array of placeholder indexes.
+ */
+function replaceHolders(array, placeholder) {
+  var index = -1,
+      length = array.length,
+      resIndex = -1,
+      result = [];
+
+  while (++index < length) {
+    if (array[index] === placeholder) {
+      array[index] = PLACEHOLDER;
+      result[++resIndex] = index;
+    }
+  }
+  return result;
+}
+
+module.exports = replaceHolders;
+
+},{}],135:[function(require,module,exports){
+var baseSetData = require('./baseSetData'),
+    now = require('../date/now');
+
+/** Used to detect when a function becomes hot. */
+var HOT_COUNT = 150,
+    HOT_SPAN = 16;
+
+/**
+ * Sets metadata for `func`.
+ *
+ * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+ * period of time, it will trip its breaker and transition to an identity function
+ * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
+ * for more details.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+var setData = (function() {
+  var count = 0,
+      lastCalled = 0;
+
+  return function(key, value) {
+    var stamp = now(),
+        remaining = HOT_SPAN - (stamp - lastCalled);
+
+    lastCalled = stamp;
+    if (remaining > 0) {
+      if (++count >= HOT_COUNT) {
+        return key;
+      }
+    } else {
+      count = 0;
+    }
+    return baseSetData(key, value);
+  };
+}());
+
+module.exports = setData;
+
+},{"../date/now":59,"./baseSetData":90}],136:[function(require,module,exports){
+var isArguments = require('../lang/isArguments'),
+    isArray = require('../lang/isArray'),
+    isIndex = require('./isIndex'),
+    isLength = require('./isLength'),
+    isString = require('../lang/isString'),
+    keysIn = require('../object/keysIn');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * A fallback implementation of `Object.keys` which creates an array of the
+ * own enumerable property names of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function shimKeys(object) {
+  var props = keysIn(object),
+      propsLength = props.length,
+      length = propsLength && object.length;
+
+  var allowIndexes = !!length && isLength(length) &&
+    (isArray(object) || isArguments(object) || isString(object));
+
+  var index = -1,
+      result = [];
+
+  while (++index < propsLength) {
+    var key = props[index];
+    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+
+module.exports = shimKeys;
+
+},{"../lang/isArguments":141,"../lang/isArray":142,"../lang/isString":148,"../object/keysIn":152,"./isIndex":123,"./isLength":127}],137:[function(require,module,exports){
+var isObject = require('../lang/isObject'),
+    isString = require('../lang/isString'),
+    support = require('../support');
+
+/**
+ * Converts `value` to an object if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Object} Returns the object.
+ */
+function toObject(value) {
+  if (support.unindexedChars && isString(value)) {
+    var index = -1,
+        length = value.length,
+        result = Object(value);
+
+    while (++index < length) {
+      result[index] = value.charAt(index);
+    }
+    return result;
+  }
+  return isObject(value) ? value : Object(value);
+}
+
+module.exports = toObject;
+
+},{"../lang/isObject":146,"../lang/isString":148,"../support":155}],138:[function(require,module,exports){
+var baseToString = require('./baseToString'),
+    isArray = require('../lang/isArray');
+
+/** Used to match property names within property paths. */
+var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+
+/** Used to match backslashes in property paths. */
+var reEscapeChar = /\\(\\)?/g;
+
+/**
+ * Converts `value` to property path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the property path array.
+ */
+function toPath(value) {
+  if (isArray(value)) {
+    return value;
+  }
+  var result = [];
+  baseToString(value).replace(rePropName, function(match, number, quote, string) {
+    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+  });
+  return result;
+}
+
+module.exports = toPath;
+
+},{"../lang/isArray":142,"./baseToString":92}],139:[function(require,module,exports){
+var LazyWrapper = require('./LazyWrapper'),
+    LodashWrapper = require('./LodashWrapper'),
+    arrayCopy = require('./arrayCopy');
+
+/**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */
+function wrapperClone(wrapper) {
+  return wrapper instanceof LazyWrapper
+    ? wrapper.clone()
+    : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+}
+
+module.exports = wrapperClone;
+
+},{"./LazyWrapper":62,"./LodashWrapper":63,"./arrayCopy":64}],140:[function(require,module,exports){
+var baseClone = require('../internal/baseClone'),
+    bindCallback = require('../internal/bindCallback');
+
+/**
+ * Creates a deep clone of `value`. If `customizer` is provided it's invoked
+ * to produce the cloned values. If `customizer` returns `undefined` cloning
+ * is handled by the method instead. The `customizer` is bound to `thisArg`
+ * and invoked with up to three argument; (value [, index|key, object]).
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+ * The enumerable properties of `arguments` objects and objects created by
+ * constructors other than `Object` are cloned to plain `Object` objects. An
+ * empty object is returned for uncloneable values such as functions, DOM nodes,
+ * Maps, Sets, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'barney' },
+ *   { 'user': 'fred' }
+ * ];
+ *
+ * var deep = _.cloneDeep(users);
+ * deep[0] === users[0];
+ * // => false
+ *
+ * // using a customizer callback
+ * var el = _.cloneDeep(document.body, function(value) {
+ *   if (_.isElement(value)) {
+ *     return value.cloneNode(true);
+ *   }
+ * });
+ *
+ * el === document.body
+ * // => false
+ * el.nodeName
+ * // => BODY
+ * el.childNodes.length;
+ * // => 20
+ */
+function cloneDeep(value, customizer, thisArg) {
+  return typeof customizer == 'function'
+    ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
+    : baseClone(value, true);
+}
+
+module.exports = cloneDeep;
+
+},{"../internal/baseClone":70,"../internal/bindCallback":96}],141:[function(require,module,exports){
+var isArrayLike = require('../internal/isArrayLike'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+/**
+ * Checks if `value` is classified as an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+function isArguments(value) {
+  return isObjectLike(value) && isArrayLike(value) &&
+    hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
+}
+
+module.exports = isArguments;
+
+},{"../internal/isArrayLike":121,"../internal/isObjectLike":128}],142:[function(require,module,exports){
+var getNative = require('../internal/getNative'),
+    isLength = require('../internal/isLength'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeIsArray = getNative(Array, 'isArray');
+
+/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(function() { return arguments; }());
+ * // => false
+ */
+var isArray = nativeIsArray || function(value) {
+  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+};
+
+module.exports = isArray;
+
+},{"../internal/getNative":116,"../internal/isLength":127,"../internal/isObjectLike":128}],143:[function(require,module,exports){
+var isArguments = require('./isArguments'),
+    isArray = require('./isArray'),
+    isArrayLike = require('../internal/isArrayLike'),
+    isFunction = require('./isFunction'),
+    isObjectLike = require('../internal/isObjectLike'),
+    isString = require('./isString'),
+    keys = require('../object/keys');
+
+/**
+ * Checks if `value` is empty. A value is considered empty unless it's an
+ * `arguments` object, array, string, or jQuery-like collection with a length
+ * greater than `0` or an object with own enumerable properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Array|Object|string} value The value to inspect.
+ * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+ * @example
+ *
+ * _.isEmpty(null);
+ * // => true
+ *
+ * _.isEmpty(true);
+ * // => true
+ *
+ * _.isEmpty(1);
+ * // => true
+ *
+ * _.isEmpty([1, 2, 3]);
+ * // => false
+ *
+ * _.isEmpty({ 'a': 1 });
+ * // => false
+ */
+function isEmpty(value) {
+  if (value == null) {
+    return true;
+  }
+  if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
+      (isObjectLike(value) && isFunction(value.splice)))) {
+    return !value.length;
+  }
+  return !keys(value).length;
+}
+
+module.exports = isEmpty;
+
+},{"../internal/isArrayLike":121,"../internal/isObjectLike":128,"../object/keys":151,"./isArguments":141,"./isArray":142,"./isFunction":144,"./isString":148}],144:[function(require,module,exports){
+var isObject = require('./isObject');
+
+/** `Object#toString` result references. */
+var funcTag = '[object Function]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+  // The use of `Object#toString` avoids issues with the `typeof` operator
+  // in older versions of Chrome and Safari which return 'function' for regexes
+  // and Safari 8 which returns 'object' for typed array constructors.
+  return isObject(value) && objToString.call(value) == funcTag;
+}
+
+module.exports = isFunction;
+
+},{"./isObject":146}],145:[function(require,module,exports){
+var isFunction = require('./isFunction'),
+    isHostObject = require('../internal/isHostObject'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+  if (value == null) {
+    return false;
+  }
+  if (isFunction(value)) {
+    return reIsNative.test(fnToString.call(value));
+  }
+  return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
+}
+
+module.exports = isNative;
+
+},{"../internal/isHostObject":122,"../internal/isObjectLike":128,"./isFunction":144}],146:[function(require,module,exports){
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+  // Avoid a V8 JIT bug in Chrome 19-20.
+  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+  var type = typeof value;
+  return !!value && (type == 'object' || type == 'function');
+}
+
+module.exports = isObject;
+
+},{}],147:[function(require,module,exports){
+var baseForIn = require('../internal/baseForIn'),
+    isArguments = require('./isArguments'),
+    isHostObject = require('../internal/isHostObject'),
+    isObjectLike = require('../internal/isObjectLike'),
+    support = require('../support');
+
+/** `Object#toString` result references. */
+var objectTag = '[object Object]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * **Note:** This method assumes objects created by the `Object` constructor
+ * have no inherited enumerable properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+function isPlainObject(value) {
+  var Ctor;
+
+  // Exit early for non `Object` objects.
+  if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
+      (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
+    return false;
+  }
+  // IE < 9 iterates inherited properties before own properties. If the first
+  // iterated property is an object's own property then there are no inherited
+  // enumerable properties.
+  var result;
+  if (support.ownLast) {
+    baseForIn(value, function(subValue, key, object) {
+      result = hasOwnProperty.call(object, key);
+      return false;
+    });
+    return result !== false;
+  }
+  // In most environments an object's own properties are iterated before
+  // its inherited properties. If the last iterated property is an object's
+  // own property then there are no inherited enumerable properties.
+  baseForIn(value, function(subValue, key) {
+    result = key;
+  });
+  return result === undefined || hasOwnProperty.call(value, result);
+}
+
+module.exports = isPlainObject;
+
+},{"../internal/baseForIn":77,"../internal/isHostObject":122,"../internal/isObjectLike":128,"../support":155,"./isArguments":141}],148:[function(require,module,exports){
+var isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var stringTag = '[object String]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+function isString(value) {
+  return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+}
+
+module.exports = isString;
+
+},{"../internal/isObjectLike":128}],149:[function(require,module,exports){
+var isLength = require('../internal/isLength'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to identify `toStringTag` values of typed arrays. */
+var typedArrayTags = {};
+typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+typedArrayTags[uint32Tag] = true;
+typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+typedArrayTags[dateTag] = typedArrayTags[errorTag] =
+typedArrayTags[funcTag] = typedArrayTags[mapTag] =
+typedArrayTags[numberTag] = typedArrayTags[objectTag] =
+typedArrayTags[regexpTag] = typedArrayTags[setTag] =
+typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */
+function isTypedArray(value) {
+  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+}
+
+module.exports = isTypedArray;
+
+},{"../internal/isLength":127,"../internal/isObjectLike":128}],150:[function(require,module,exports){
+/**
+ * Checks if `value` is `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+ * @example
+ *
+ * _.isUndefined(void 0);
+ * // => true
+ *
+ * _.isUndefined(null);
+ * // => false
+ */
+function isUndefined(value) {
+  return value === undefined;
+}
+
+module.exports = isUndefined;
+
+},{}],151:[function(require,module,exports){
+var getNative = require('../internal/getNative'),
+    isArrayLike = require('../internal/isArrayLike'),
+    isObject = require('../lang/isObject'),
+    shimKeys = require('../internal/shimKeys'),
+    support = require('../support');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeKeys = getNative(Object, 'keys');
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+var keys = !nativeKeys ? shimKeys : function(object) {
+  var Ctor = object == null ? undefined : object.constructor;
+  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+      (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
+    return shimKeys(object);
+  }
+  return isObject(object) ? nativeKeys(object) : [];
+};
+
+module.exports = keys;
+
+},{"../internal/getNative":116,"../internal/isArrayLike":121,"../internal/shimKeys":136,"../lang/isObject":146,"../support":155}],152:[function(require,module,exports){
+var arrayEach = require('../internal/arrayEach'),
+    isArguments = require('../lang/isArguments'),
+    isArray = require('../lang/isArray'),
+    isFunction = require('../lang/isFunction'),
+    isIndex = require('../internal/isIndex'),
+    isLength = require('../internal/isLength'),
+    isObject = require('../lang/isObject'),
+    isString = require('../lang/isString'),
+    support = require('../support');
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+/** Used to fix the JScript `[[DontEnum]]` bug. */
+var shadowProps = [
+  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
+  'toLocaleString', 'toString', 'valueOf'
+];
+
+/** Used for native method references. */
+var errorProto = Error.prototype,
+    objectProto = Object.prototype,
+    stringProto = String.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to avoid iterating over non-enumerable properties in IE < 9. */
+var nonEnumProps = {};
+nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
+nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
+nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
+nonEnumProps[objectTag] = { 'constructor': true };
+
+arrayEach(shadowProps, function(key) {
+  for (var tag in nonEnumProps) {
+    if (hasOwnProperty.call(nonEnumProps, tag)) {
+      var props = nonEnumProps[tag];
+      props[key] = hasOwnProperty.call(props, key);
+    }
+  }
+});
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+  if (object == null) {
+    return [];
+  }
+  if (!isObject(object)) {
+    object = Object(object);
+  }
+  var length = object.length;
+
+  length = (length && isLength(length) &&
+    (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
+
+  var Ctor = object.constructor,
+      index = -1,
+      proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
+      isProto = proto === object,
+      result = Array(length),
+      skipIndexes = length > 0,
+      skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
+      skipProto = support.enumPrototypes && isFunction(object);
+
+  while (++index < length) {
+    result[index] = (index + '');
+  }
+  // lodash skips the `constructor` property when it infers it's iterating
+  // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
+  // attribute of an existing property and the `constructor` property of a
+  // prototype defaults to non-enumerable.
+  for (var key in object) {
+    if (!(skipProto && key == 'prototype') &&
+        !(skipErrorProps && (key == 'message' || key == 'name')) &&
+        !(skipIndexes && isIndex(key, length)) &&
+        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+      result.push(key);
+    }
+  }
+  if (support.nonEnumShadows && object !== objectProto) {
+    var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
+        nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
+
+    if (tag == objectTag) {
+      proto = objectProto;
+    }
+    length = shadowProps.length;
+    while (length--) {
+      key = shadowProps[length];
+      var nonEnum = nonEnums[key];
+      if (!(isProto && nonEnum) &&
+          (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
+        result.push(key);
+      }
+    }
+  }
+  return result;
+}
+
+module.exports = keysIn;
+
+},{"../internal/arrayEach":65,"../internal/isIndex":123,"../internal/isLength":127,"../lang/isArguments":141,"../lang/isArray":142,"../lang/isFunction":144,"../lang/isObject":146,"../lang/isString":148,"../support":155}],153:[function(require,module,exports){
+var keys = require('./keys'),
+    toObject = require('../internal/toObject');
+
+/**
+ * Creates a two dimensional array of the key-value pairs for `object`,
+ * e.g. `[[key1, value1], [key2, value2]]`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * _.pairs({ 'barney': 36, 'fred': 40 });
+ * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
+ */
+function pairs(object) {
+  object = toObject(object);
+
+  var index = -1,
+      props = keys(object),
+      length = props.length,
+      result = Array(length);
+
+  while (++index < length) {
+    var key = props[index];
+    result[index] = [key, object[key]];
+  }
+  return result;
+}
+
+module.exports = pairs;
+
+},{"../internal/toObject":137,"./keys":151}],154:[function(require,module,exports){
+var baseValues = require('../internal/baseValues'),
+    keys = require('./keys');
+
+/**
+ * Creates an array of the own enumerable property values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.values(new Foo);
+ * // => [1, 2] (iteration order is not guaranteed)
+ *
+ * _.values('hi');
+ * // => ['h', 'i']
+ */
+function values(object) {
+  return baseValues(object, keys(object));
+}
+
+module.exports = values;
+
+},{"../internal/baseValues":93,"./keys":151}],155:[function(require,module,exports){
+/** Used for native method references. */
+var arrayProto = Array.prototype,
+    errorProto = Error.prototype,
+    objectProto = Object.prototype;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable,
+    splice = arrayProto.splice;
+
+/**
+ * An object environment feature flags.
+ *
+ * @static
+ * @memberOf _
+ * @type Object
+ */
+var support = {};
+
+(function(x) {
+  var Ctor = function() { this.x = x; },
+      object = { '0': x, 'length': x },
+      props = [];
+
+  Ctor.prototype = { 'valueOf': x, 'y': x };
+  for (var key in new Ctor) { props.push(key); }
+
+  /**
+   * Detect if `name` or `message` properties of `Error.prototype` are
+   * enumerable by default (IE < 9, Safari < 5.1).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
+    propertyIsEnumerable.call(errorProto, 'name');
+
+  /**
+   * Detect if `prototype` properties are enumerable by default.
+   *
+   * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
+   * (if the prototype or a property on the prototype has been set)
+   * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
+   * property to `true`.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
+
+  /**
+   * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
+   *
+   * In IE < 9 an object's own properties, shadowing non-enumerable ones,
+   * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.nonEnumShadows = !/valueOf/.test(props);
+
+  /**
+   * Detect if own properties are iterated after inherited properties (IE < 9).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.ownLast = props[0] != 'x';
+
+  /**
+   * Detect if `Array#shift` and `Array#splice` augment array-like objects
+   * correctly.
+   *
+   * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
+   * `shift()` and `splice()` functions that fail to remove the last element,
+   * `value[0]`, of array-like objects even though the "length" property is
+   * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
+   * while `splice()` is buggy regardless of mode in IE < 9.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
+
+  /**
+   * Detect lack of support for accessing string characters by index.
+   *
+   * IE < 8 can't access characters by index. IE 8 can only access characters
+   * by index on string literals, not string objects.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
+}(1, 0));
+
+module.exports = support;
+
+},{}],156:[function(require,module,exports){
+/**
+ * This method returns the first argument provided to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+function identity(value) {
+  return value;
+}
+
+module.exports = identity;
+
+},{}],157:[function(require,module,exports){
+/**
+ * A no-operation function that returns `undefined` regardless of the
+ * arguments it receives.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.noop(object) === undefined;
+ * // => true
+ */
+function noop() {
+  // No operation performed.
+}
+
+module.exports = noop;
+
+},{}],158:[function(require,module,exports){
+var baseProperty = require('../internal/baseProperty'),
+    basePropertyDeep = require('../internal/basePropertyDeep'),
+    isKey = require('../internal/isKey');
+
+/**
+ * Creates a function that returns the property value at `path` on a
+ * given object.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var objects = [
+ *   { 'a': { 'b': { 'c': 2 } } },
+ *   { 'a': { 'b': { 'c': 1 } } }
+ * ];
+ *
+ * _.map(objects, _.property('a.b.c'));
+ * // => [2, 1]
+ *
+ * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
+ * // => [1, 2]
+ */
+function property(path) {
+  return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
+}
+
+module.exports = property;
+
+},{"../internal/baseProperty":88,"../internal/basePropertyDeep":89,"../internal/isKey":125}],159:[function(require,module,exports){
+(function (process){
+// vim:ts=4:sts=4:sw=4:
+/*!
+ *
+ * Copyright 2009-2012 Kris Kowal under the terms of the MIT
+ * license found at http://github.com/kriskowal/q/raw/master/LICENSE
+ *
+ * With parts by Tyler Close
+ * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
+ * at http://www.opensource.org/licenses/mit-license.html
+ * Forked at ref_send.js version: 2009-05-11
+ *
+ * With parts by Mark Miller
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+(function (definition) {
+    "use strict";
+
+    // This file will function properly as a <script> tag, or a module
+    // using CommonJS and NodeJS or RequireJS module formats.  In
+    // Common/Node/RequireJS, the module exports the Q API and when
+    // executed as a simple <script>, it creates a Q global instead.
+
+    // Montage Require
+    if (typeof bootstrap === "function") {
+        bootstrap("promise", definition);
+
+    // CommonJS
+    } else if (typeof exports === "object" && typeof module === "object") {
+        module.exports = definition();
+
+    // RequireJS
+    } else if (typeof define === "function" && define.amd) {
+        define(definition);
+
+    // SES (Secure EcmaScript)
+    } else if (typeof ses !== "undefined") {
+        if (!ses.ok()) {
+            return;
+        } else {
+            ses.makeQ = definition;
+        }
+
+    // <script>
+    } else if (typeof window !== "undefined" || typeof self !== "undefined") {
+        // Prefer window over self for add-on scripts. Use self for
+        // non-windowed contexts.
+        var global = typeof window !== "undefined" ? window : self;
+
+        // Get the `window` object, save the previous Q global
+        // and initialize Q as a global.
+        var previousQ = global.Q;
+        global.Q = definition();
+
+        // Add a noConflict function so Q can be removed from the
+        // global namespace.
+        global.Q.noConflict = function () {
+            global.Q = previousQ;
+            return this;
+        };
+
+    } else {
+        throw new Error("This environment was not anticipated by Q. Please file a bug.");
+    }
+
+})(function () {
+"use strict";
+
+var hasStacks = false;
+try {
+    throw new Error();
+} catch (e) {
+    hasStacks = !!e.stack;
+}
+
+// All code after this point will be filtered from stack traces reported
+// by Q.
+var qStartingLine = captureLine();
+var qFileName;
+
+// shims
+
+// used for fallback in "allResolved"
+var noop = function () {};
+
+// Use the fastest possible means to execute a task in a future turn
+// of the event loop.
+var nextTick =(function () {
+    // linked list of tasks (single, with head node)
+    var head = {task: void 0, next: null};
+    var tail = head;
+    var flushing = false;
+    var requestTick = void 0;
+    var isNodeJS = false;
+    // queue for late tasks, used by unhandled rejection tracking
+    var laterQueue = [];
+
+    function flush() {
+        /* jshint loopfunc: true */
+        var task, domain;
+
+        while (head.next) {
+            head = head.next;
+            task = head.task;
+            head.task = void 0;
+            domain = head.domain;
+
+            if (domain) {
+                head.domain = void 0;
+                domain.enter();
+            }
+            runSingle(task, domain);
+
+        }
+        while (laterQueue.length) {
+            task = laterQueue.pop();
+            runSingle(task);
+        }
+        flushing = false;
+    }
+    // runs a single function in the async queue
+    function runSingle(task, domain) {
+        try {
+            task();
+
+        } catch (e) {
+            if (isNodeJS) {
+                // In node, uncaught exceptions are considered fatal errors.
+                // Re-throw them synchronously to interrupt flushing!
+
+                // Ensure continuation if the uncaught exception is suppressed
+                // listening "uncaughtException" events (as domains does).
+                // Continue in next event to avoid tick recursion.
+                if (domain) {
+                    domain.exit();
+                }
+                setTimeout(flush, 0);
+                if (domain) {
+                    domain.enter();
+                }
+
+                throw e;
+
+            } else {
+                // In browsers, uncaught exceptions are not fatal.
+                // Re-throw them asynchronously to avoid slow-downs.
+                setTimeout(function () {
+                    throw e;
+                }, 0);
+            }
+        }
+
+        if (domain) {
+            domain.exit();
+        }
+    }
+
+    nextTick = function (task) {
+        tail = tail.next = {
+            task: task,
+            domain: isNodeJS && process.domain,
+            next: null
+        };
+
+        if (!flushing) {
+            flushing = true;
+            requestTick();
+        }
+    };
+
+    if (typeof process === "object" &&
+        process.toString() === "[object process]" && process.nextTick) {
+        // Ensure Q is in a real Node environment, with a `process.nextTick`.
+        // To see through fake Node environments:
+        // * Mocha test runner - exposes a `process` global without a `nextTick`
+        // * Browserify - exposes a `process.nexTick` function that uses
+        //   `setTimeout`. In this case `setImmediate` is preferred because
+        //    it is faster. Browserify's `process.toString()` yields
+        //   "[object Object]", while in a real Node environment
+        //   `process.nextTick()` yields "[object process]".
+        isNodeJS = true;
+
+        requestTick = function () {
+            process.nextTick(flush);
+        };
+
+    } else if (typeof setImmediate === "function") {
+        // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
+        if (typeof window !== "undefined") {
+            requestTick = setImmediate.bind(window, flush);
+        } else {
+            requestTick = function () {
+                setImmediate(flush);
+            };
+        }
+
+    } else if (typeof MessageChannel !== "undefined") {
+        // modern browsers
+        // http://www.nonblocking.io/2011/06/windownexttick.html
+        var channel = new MessageChannel();
+        // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
+        // working message ports the first time a page loads.
+        channel.port1.onmessage = function () {
+            requestTick = requestPortTick;
+            channel.port1.onmessage = flush;
+            flush();
+        };
+        var requestPortTick = function () {
+            // Opera requires us to provide a message payload, regardless of
+            // whether we use it.
+            channel.port2.postMessage(0);
+        };
+        requestTick = function () {
+            setTimeout(flush, 0);
+            requestPortTick();
+        };
+
+    } else {
+        // old browsers
+        requestTick = function () {
+            setTimeout(flush, 0);
+        };
+    }
+    // runs a task after all other tasks have been run
+    // this is useful for unhandled rejection tracking that needs to happen
+    // after all `then`d tasks have been run.
+    nextTick.runAfter = function (task) {
+        laterQueue.push(task);
+        if (!flushing) {
+            flushing = true;
+            requestTick();
+        }
+    };
+    return nextTick;
+})();
+
+// Attempt to make generics safe in the face of downstream
+// modifications.
+// There is no situation where this is necessary.
+// If you need a security guarantee, these primordials need to be
+// deeply frozen anyway, and if you don’t need a security guarantee,
+// this is just plain paranoid.
+// However, this **might** have the nice side-effect of reducing the size of
+// the minified code by reducing x.call() to merely x()
+// See Mark Miller’s explanation of what this does.
+// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+var call = Function.call;
+function uncurryThis(f) {
+    return function () {
+        return call.apply(f, arguments);
+    };
+}
+// This is equivalent, but slower:
+// uncurryThis = Function_bind.bind(Function_bind.call);
+// http://jsperf.com/uncurrythis
+
+var array_slice = uncurryThis(Array.prototype.slice);
+
+var array_reduce = uncurryThis(
+    Array.prototype.reduce || function (callback, basis) {
+        var index = 0,
+            length = this.length;
+        // concerning the initial value, if one is not provided
+        if (arguments.length === 1) {
+            // seek to the first value in the array, accounting
+            // for the possibility that is is a sparse array
+            do {
+                if (index in this) {
+                    basis = this[index++];
+                    break;
+                }
+                if (++index >= length) {
+                    throw new TypeError();
+                }
+            } while (1);
+        }
+        // reduce
+        for (; index < length; index++) {
+            // account for the possibility that the array is sparse
+            if (index in this) {
+                basis = callback(basis, this[index], index);
+            }
+        }
+        return basis;
+    }
+);
+
+var array_indexOf = uncurryThis(
+    Array.prototype.indexOf || function (value) {
+        // not a very good shim, but good enough for our one use of it
+        for (var i = 0; i < this.length; i++) {
+            if (this[i] === value) {
+                return i;
+            }
+        }
+        return -1;
+    }
+);
+
+var array_map = uncurryThis(
+    Array.prototype.map || function (callback, thisp) {
+        var self = this;
+        var collect = [];
+        array_reduce(self, function (undefined, value, index) {
+            collect.push(callback.call(thisp, value, index, self));
+        }, void 0);
+        return collect;
+    }
+);
+
+var object_create = Object.create || function (prototype) {
+    function Type() { }
+    Type.prototype = prototype;
+    return new Type();
+};
+
+var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
+
+var object_keys = Object.keys || function (object) {
+    var keys = [];
+    for (var key in object) {
+        if (object_hasOwnProperty(object, key)) {
+            keys.push(key);
+        }
+    }
+    return keys;
+};
+
+var object_toString = uncurryThis(Object.prototype.toString);
+
+function isObject(value) {
+    return value === Object(value);
+}
+
+// generator related shims
+
+// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
+function isStopIteration(exception) {
+    return (
+        object_toString(exception) === "[object StopIteration]" ||
+        exception instanceof QReturnValue
+    );
+}
+
+// FIXME: Remove this helper and Q.return once ES6 generators are in
+// SpiderMonkey.
+var QReturnValue;
+if (typeof ReturnValue !== "undefined") {
+    QReturnValue = ReturnValue;
+} else {
+    QReturnValue = function (value) {
+        this.value = value;
+    };
+}
+
+// long stack traces
+
+var STACK_JUMP_SEPARATOR = "From previous event:";
+
+function makeStackTraceLong(error, promise) {
+    // If possible, transform the error stack trace by removing Node and Q
+    // cruft, then concatenating with the stack trace of `promise`. See #57.
+    if (hasStacks &&
+        promise.stack &&
+        typeof error === "object" &&
+        error !== null &&
+        error.stack &&
+        error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
+    ) {
+        var stacks = [];
+        for (var p = promise; !!p; p = p.source) {
+            if (p.stack) {
+                stacks.unshift(p.stack);
+            }
+        }
+        stacks.unshift(error.stack);
+
+        var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
+        error.stack = filterStackString(concatedStacks);
+    }
+}
+
+function filterStackString(stackString) {
+    var lines = stackString.split("\n");
+    var desiredLines = [];
+    for (var i = 0; i < lines.length; ++i) {
+        var line = lines[i];
+
+        if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
+            desiredLines.push(line);
+        }
+    }
+    return desiredLines.join("\n");
+}
+
+function isNodeFrame(stackLine) {
+    return stackLine.indexOf("(module.js:") !== -1 ||
+           stackLine.indexOf("(node.js:") !== -1;
+}
+
+function getFileNameAndLineNumber(stackLine) {
+    // Named functions: "at functionName (filename:lineNumber:columnNumber)"
+    // In IE10 function name can have spaces ("Anonymous function") O_o
+    var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
+    if (attempt1) {
+        return [attempt1[1], Number(attempt1[2])];
+    }
+
+    // Anonymous functions: "at filename:lineNumber:columnNumber"
+    var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
+    if (attempt2) {
+        return [attempt2[1], Number(attempt2[2])];
+    }
+
+    // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
+    var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
+    if (attempt3) {
+        return [attempt3[1], Number(attempt3[2])];
+    }
+}
+
+function isInternalFrame(stackLine) {
+    var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
+
+    if (!fileNameAndLineNumber) {
+        return false;
+    }
+
+    var fileName = fileNameAndLineNumber[0];
+    var lineNumber = fileNameAndLineNumber[1];
+
+    return fileName === qFileName &&
+        lineNumber >= qStartingLine &&
+        lineNumber <= qEndingLine;
+}
+
+// discover own file name and line number range for filtering stack
+// traces
+function captureLine() {
+    if (!hasStacks) {
+        return;
+    }
+
+    try {
+        throw new Error();
+    } catch (e) {
+        var lines = e.stack.split("\n");
+        var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
+        var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
+        if (!fileNameAndLineNumber) {
+            return;
+        }
+
+        qFileName = fileNameAndLineNumber[0];
+        return fileNameAndLineNumber[1];
+    }
+}
+
+function deprecate(callback, name, alternative) {
+    return function () {
+        if (typeof console !== "undefined" &&
+            typeof console.warn === "function") {
+            console.warn(name + " is deprecated, use " + alternative +
+                         " instead.", new Error("").stack);
+        }
+        return callback.apply(callback, arguments);
+    };
+}
+
+// end of shims
+// beginning of real work
+
+/**
+ * Constructs a promise for an immediate reference, passes promises through, or
+ * coerces promises from different systems.
+ * @param value immediate reference or promise
+ */
+function Q(value) {
+    // If the object is already a Promise, return it directly.  This enables
+    // the resolve function to both be used to created references from objects,
+    // but to tolerably coerce non-promises to promises.
+    if (value instanceof Promise) {
+        return value;
+    }
+
+    // assimilate thenables
+    if (isPromiseAlike(value)) {
+        return coerce(value);
+    } else {
+        return fulfill(value);
+    }
+}
+Q.resolve = Q;
+
+/**
+ * Performs a task in a future turn of the event loop.
+ * @param {Function} task
+ */
+Q.nextTick = nextTick;
+
+/**
+ * Controls whether or not long stack traces will be on
+ */
+Q.longStackSupport = false;
+
+// enable long stacks if Q_DEBUG is set
+if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
+    Q.longStackSupport = true;
+}
+
+/**
+ * Constructs a {promise, resolve, reject} object.
+ *
+ * `resolve` is a callback to invoke with a more resolved value for the
+ * promise. To fulfill the promise, invoke `resolve` with any value that is
+ * not a thenable. To reject the promise, invoke `resolve` with a rejected
+ * thenable, or invoke `reject` with the reason directly. To resolve the
+ * promise to another thenable, thus putting it in the same state, invoke
+ * `resolve` with that other thenable.
+ */
+Q.defer = defer;
+function defer() {
+    // if "messages" is an "Array", that indicates that the promise has not yet
+    // been resolved.  If it is "undefined", it has been resolved.  Each
+    // element of the messages array is itself an array of complete arguments to
+    // forward to the resolved promise.  We coerce the resolution value to a
+    // promise using the `resolve` function because it handles both fully
+    // non-thenable values and other thenables gracefully.
+    var messages = [], progressListeners = [], resolvedPromise;
+
+    var deferred = object_create(defer.prototype);
+    var promise = object_create(Promise.prototype);
+
+    promise.promiseDispatch = function (resolve, op, operands) {
+        var args = array_slice(arguments);
+        if (messages) {
+            messages.push(args);
+            if (op === "when" && operands[1]) { // progress operand
+                progressListeners.push(operands[1]);
+            }
+        } else {
+            Q.nextTick(function () {
+                resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
+            });
+        }
+    };
+
+    // XXX deprecated
+    promise.valueOf = function () {
+        if (messages) {
+            return promise;
+        }
+        var nearerValue = nearer(resolvedPromise);
+        if (isPromise(nearerValue)) {
+            resolvedPromise = nearerValue; // shorten chain
+        }
+        return nearerValue;
+    };
+
+    promise.inspect = function () {
+        if (!resolvedPromise) {
+            return { state: "pending" };
+        }
+        return resolvedPromise.inspect();
+    };
+
+    if (Q.longStackSupport && hasStacks) {
+        try {
+            throw new Error();
+        } catch (e) {
+            // NOTE: don't try to use `Error.captureStackTrace` or transfer the
+            // accessor around; that causes memory leaks as per GH-111. Just
+            // reify the stack trace as a string ASAP.
+            //
+            // At the same time, cut off the first line; it's always just
+            // "[object Promise]\n", as per the `toString`.
+            promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
+        }
+    }
+
+    // NOTE: we do the checks for `resolvedPromise` in each method, instead of
+    // consolidating them into `become`, since otherwise we'd create new
+    // promises with the lines `become(whatever(value))`. See e.g. GH-252.
+
+    function become(newPromise) {
+        resolvedPromise = newPromise;
+        promise.source = newPromise;
+
+        array_reduce(messages, function (undefined, message) {
+            Q.nextTick(function () {
+                newPromise.promiseDispatch.apply(newPromise, message);
+            });
+        }, void 0);
+
+        messages = void 0;
+        progressListeners = void 0;
+    }
+
+    deferred.promise = promise;
+    deferred.resolve = function (value) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(Q(value));
+    };
+
+    deferred.fulfill = function (value) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(fulfill(value));
+    };
+    deferred.reject = function (reason) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(reject(reason));
+    };
+    deferred.notify = function (progress) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        array_reduce(progressListeners, function (undefined, progressListener) {
+            Q.nextTick(function () {
+                progressListener(progress);
+            });
+        }, void 0);
+    };
+
+    return deferred;
+}
+
+/**
+ * Creates a Node-style callback that will resolve or reject the deferred
+ * promise.
+ * @returns a nodeback
+ */
+defer.prototype.makeNodeResolver = function () {
+    var self = this;
+    return function (error, value) {
+        if (error) {
+            self.reject(error);
+        } else if (arguments.length > 2) {
+            self.resolve(array_slice(arguments, 1));
+        } else {
+            self.resolve(value);
+        }
+    };
+};
+
+/**
+ * @param resolver {Function} a function that returns nothing and accepts
+ * the resolve, reject, and notify functions for a deferred.
+ * @returns a promise that may be resolved with the given resolve and reject
+ * functions, or rejected by a thrown exception in resolver
+ */
+Q.Promise = promise; // ES6
+Q.promise = promise;
+function promise(resolver) {
+    if (typeof resolver !== "function") {
+        throw new TypeError("resolver must be a function.");
+    }
+    var deferred = defer();
+    try {
+        resolver(deferred.resolve, deferred.reject, deferred.notify);
+    } catch (reason) {
+        deferred.reject(reason);
+    }
+    return deferred.promise;
+}
+
+promise.race = race; // ES6
+promise.all = all; // ES6
+promise.reject = reject; // ES6
+promise.resolve = Q; // ES6
+
+// XXX experimental.  This method is a way to denote that a local value is
+// serializable and should be immediately dispatched to a remote upon request,
+// instead of passing a reference.
+Q.passByCopy = function (object) {
+    //freeze(object);
+    //passByCopies.set(object, true);
+    return object;
+};
+
+Promise.prototype.passByCopy = function () {
+    //freeze(object);
+    //passByCopies.set(object, true);
+    return this;
+};
+
+/**
+ * If two promises eventually fulfill to the same value, promises that value,
+ * but otherwise rejects.
+ * @param x {Any*}
+ * @param y {Any*}
+ * @returns {Any*} a promise for x and y if they are the same, but a rejection
+ * otherwise.
+ *
+ */
+Q.join = function (x, y) {
+    return Q(x).join(y);
+};
+
+Promise.prototype.join = function (that) {
+    return Q([this, that]).spread(function (x, y) {
+        if (x === y) {
+            // TODO: "===" should be Object.is or equiv
+            return x;
+        } else {
+            throw new Error("Can't join: not the same: " + x + " " + y);
+        }
+    });
+};
+
+/**
+ * Returns a promise for the first of an array of promises to become settled.
+ * @param answers {Array[Any*]} promises to race
+ * @returns {Any*} the first promise to be settled
+ */
+Q.race = race;
+function race(answerPs) {
+    return promise(function (resolve, reject) {
+        // Switch to this once we can assume at least ES5
+        // answerPs.forEach(function (answerP) {
+        //     Q(answerP).then(resolve, reject);
+        // });
+        // Use this in the meantime
+        for (var i = 0, len = answerPs.length; i < len; i++) {
+            Q(answerPs[i]).then(resolve, reject);
+        }
+    });
+}
+
+Promise.prototype.race = function () {
+    return this.then(Q.race);
+};
+
+/**
+ * Constructs a Promise with a promise descriptor object and optional fallback
+ * function.  The descriptor contains methods like when(rejected), get(name),
+ * set(name, value), post(name, args), and delete(name), which all
+ * return either a value, a promise for a value, or a rejection.  The fallback
+ * accepts the operation name, a resolver, and any further arguments that would
+ * have been forwarded to the appropriate method above had a method been
+ * provided with the proper name.  The API makes no guarantees about the nature
+ * of the returned object, apart from that it is usable whereever promises are
+ * bought and sold.
+ */
+Q.makePromise = Promise;
+function Promise(descriptor, fallback, inspect) {
+    if (fallback === void 0) {
+        fallback = function (op) {
+            return reject(new Error(
+                "Promise does not support operation: " + op
+            ));
+        };
+    }
+    if (inspect === void 0) {
+        inspect = function () {
+            return {state: "unknown"};
+        };
+    }
+
+    var promise = object_create(Promise.prototype);
+
+    promise.promiseDispatch = function (resolve, op, args) {
+        var result;
+        try {
+            if (descriptor[op]) {
+                result = descriptor[op].apply(promise, args);
+            } else {
+                result = fallback.call(promise, op, args);
+            }
+        } catch (exception) {
+            result = reject(exception);
+        }
+        if (resolve) {
+            resolve(result);
+        }
+    };
+
+    promise.inspect = inspect;
+
+    // XXX deprecated `valueOf` and `exception` support
+    if (inspect) {
+        var inspected = inspect();
+        if (inspected.state === "rejected") {
+            promise.exception = inspected.reason;
+        }
+
+        promise.valueOf = function () {
+            var inspected = inspect();
+            if (inspected.state === "pending" ||
+                inspected.state === "rejected") {
+                return promise;
+            }
+            return inspected.value;
+        };
+    }
+
+    return promise;
+}
+
+Promise.prototype.toString = function () {
+    return "[object Promise]";
+};
+
+Promise.prototype.then = function (fulfilled, rejected, progressed) {
+    var self = this;
+    var deferred = defer();
+    var done = false;   // ensure the untrusted promise makes at most a
+                        // single call to one of the callbacks
+
+    function _fulfilled(value) {
+        try {
+            return typeof fulfilled === "function" ? fulfilled(value) : value;
+        } catch (exception) {
+            return reject(exception);
+        }
+    }
+
+    function _rejected(exception) {
+        if (typeof rejected === "function") {
+            makeStackTraceLong(exception, self);
+            try {
+                return rejected(exception);
+            } catch (newException) {
+                return reject(newException);
+            }
+        }
+        return reject(exception);
+    }
+
+    function _progressed(value) {
+        return typeof progressed === "function" ? progressed(value) : value;
+    }
+
+    Q.nextTick(function () {
+        self.promiseDispatch(function (value) {
+            if (done) {
+                return;
+            }
+            done = true;
+
+            deferred.resolve(_fulfilled(value));
+        }, "when", [function (exception) {
+            if (done) {
+                return;
+            }
+            done = true;
+
+            deferred.resolve(_rejected(exception));
+        }]);
+    });
+
+    // Progress propagator need to be attached in the current tick.
+    self.promiseDispatch(void 0, "when", [void 0, function (value) {
+        var newValue;
+        var threw = false;
+        try {
+            newValue = _progressed(value);
+        } catch (e) {
+            threw = true;
+            if (Q.onerror) {
+                Q.onerror(e);
+            } else {
+                throw e;
+            }
+        }
+
+        if (!threw) {
+            deferred.notify(newValue);
+        }
+    }]);
+
+    return deferred.promise;
+};
+
+Q.tap = function (promise, callback) {
+    return Q(promise).tap(callback);
+};
+
+/**
+ * Works almost like "finally", but not called for rejections.
+ * Original resolution value is passed through callback unaffected.
+ * Callback may return a promise that will be awaited for.
+ * @param {Function} callback
+ * @returns {Q.Promise}
+ * @example
+ * doSomething()
+ *   .then(...)
+ *   .tap(console.log)
+ *   .then(...);
+ */
+Promise.prototype.tap = function (callback) {
+    callback = Q(callback);
+
+    return this.then(function (value) {
+        return callback.fcall(value).thenResolve(value);
+    });
+};
+
+/**
+ * Registers an observer on a promise.
+ *
+ * Guarantees:
+ *
+ * 1. that fulfilled and rejected will be called only once.
+ * 2. that either the fulfilled callback or the rejected callback will be
+ *    called, but not both.
+ * 3. that fulfilled and rejected will not be called in this turn.
+ *
+ * @param value      promise or immediate reference to observe
+ * @param fulfilled  function to be called with the fulfilled value
+ * @param rejected   function to be called with the rejection exception
+ * @param progressed function to be called on any progress notifications
+ * @return promise for the return value from the invoked callback
+ */
+Q.when = when;
+function when(value, fulfilled, rejected, progressed) {
+    return Q(value).then(fulfilled, rejected, progressed);
+}
+
+Promise.prototype.thenResolve = function (value) {
+    return this.then(function () { return value; });
+};
+
+Q.thenResolve = function (promise, value) {
+    return Q(promise).thenResolve(value);
+};
+
+Promise.prototype.thenReject = function (reason) {
+    return this.then(function () { throw reason; });
+};
+
+Q.thenReject = function (promise, reason) {
+    return Q(promise).thenReject(reason);
+};
+
+/**
+ * If an object is not a promise, it is as "near" as possible.
+ * If a promise is rejected, it is as "near" as possible too.
+ * If it’s a fulfilled promise, the fulfillment value is nearer.
+ * If it’s a deferred promise and the deferred has been resolved, the
+ * resolution is "nearer".
+ * @param object
+ * @returns most resolved (nearest) form of the object
+ */
+
+// XXX should we re-do this?
+Q.nearer = nearer;
+function nearer(value) {
+    if (isPromise(value)) {
+        var inspected = value.inspect();
+        if (inspected.state === "fulfilled") {
+            return inspected.value;
+        }
+    }
+    return value;
+}
+
+/**
+ * @returns whether the given object is a promise.
+ * Otherwise it is a fulfilled value.
+ */
+Q.isPromise = isPromise;
+function isPromise(object) {
+    return object instanceof Promise;
+}
+
+Q.isPromiseAlike = isPromiseAlike;
+function isPromiseAlike(object) {
+    return isObject(object) && typeof object.then === "function";
+}
+
+/**
+ * @returns whether the given object is a pending promise, meaning not
+ * fulfilled or rejected.
+ */
+Q.isPending = isPending;
+function isPending(object) {
+    return isPromise(object) && object.inspect().state === "pending";
+}
+
+Promise.prototype.isPending = function () {
+    return this.inspect().state === "pending";
+};
+
+/**
+ * @returns whether the given object is a value or fulfilled
+ * promise.
+ */
+Q.isFulfilled = isFulfilled;
+function isFulfilled(object) {
+    return !isPromise(object) || object.inspect().state === "fulfilled";
+}
+
+Promise.prototype.isFulfilled = function () {
+    return this.inspect().state === "fulfilled";
+};
+
+/**
+ * @returns whether the given object is a rejected promise.
+ */
+Q.isRejected = isRejected;
+function isRejected(object) {
+    return isPromise(object) && object.inspect().state === "rejected";
+}
+
+Promise.prototype.isRejected = function () {
+    return this.inspect().state === "rejected";
+};
+
+//// BEGIN UNHANDLED REJECTION TRACKING
+
+// This promise library consumes exceptions thrown in handlers so they can be
+// handled by a subsequent promise.  The exceptions get added to this array when
+// they are created, and removed when they are handled.  Note that in ES6 or
+// shimmed environments, this would naturally be a `Set`.
+var unhandledReasons = [];
+var unhandledRejections = [];
+var reportedUnhandledRejections = [];
+var trackUnhandledRejections = true;
+
+function resetUnhandledRejections() {
+    unhandledReasons.length = 0;
+    unhandledRejections.length = 0;
+
+    if (!trackUnhandledRejections) {
+        trackUnhandledRejections = true;
+    }
+}
+
+function trackRejection(promise, reason) {
+    if (!trackUnhandledRejections) {
+        return;
+    }
+    if (typeof process === "object" && typeof process.emit === "function") {
+        Q.nextTick.runAfter(function () {
+            if (array_indexOf(unhandledRejections, promise) !== -1) {
+                process.emit("unhandledRejection", reason, promise);
+                reportedUnhandledRejections.push(promise);
+            }
+        });
+    }
+
+    unhandledRejections.push(promise);
+    if (reason && typeof reason.stack !== "undefined") {
+        unhandledReasons.push(reason.stack);
+    } else {
+        unhandledReasons.push("(no stack) " + reason);
+    }
+}
+
+function untrackRejection(promise) {
+    if (!trackUnhandledRejections) {
+        return;
+    }
+
+    var at = array_indexOf(unhandledRejections, promise);
+    if (at !== -1) {
+        if (typeof process === "object" && typeof process.emit === "function") {
+            Q.nextTick.runAfter(function () {
+                var atReport = array_indexOf(reportedUnhandledRejections, promise);
+                if (atReport !== -1) {
+                    process.emit("rejectionHandled", unhandledReasons[at], promise);
+                    reportedUnhandledRejections.splice(atReport, 1);
+                }
+            });
+        }
+        unhandledRejections.splice(at, 1);
+        unhandledReasons.splice(at, 1);
+    }
+}
+
+Q.resetUnhandledRejections = resetUnhandledRejections;
+
+Q.getUnhandledReasons = function () {
+    // Make a copy so that consumers can't interfere with our internal state.
+    return unhandledReasons.slice();
+};
+
+Q.stopUnhandledRejectionTracking = function () {
+    resetUnhandledRejections();
+    trackUnhandledRejections = false;
+};
+
+resetUnhandledRejections();
+
+//// END UNHANDLED REJECTION TRACKING
+
+/**
+ * Constructs a rejected promise.
+ * @param reason value describing the failure
+ */
+Q.reject = reject;
+function reject(reason) {
+    var rejection = Promise({
+        "when": function (rejected) {
+            // note that the error has been handled
+            if (rejected) {
+                untrackRejection(this);
+            }
+            return rejected ? rejected(reason) : this;
+        }
+    }, function fallback() {
+        return this;
+    }, function inspect() {
+        return { state: "rejected", reason: reason };
+    });
+
+    // Note that the reason has not been handled.
+    trackRejection(rejection, reason);
+
+    return rejection;
+}
+
+/**
+ * Constructs a fulfilled promise for an immediate reference.
+ * @param value immediate reference
+ */
+Q.fulfill = fulfill;
+function fulfill(value) {
+    return Promise({
+        "when": function () {
+            return value;
+        },
+        "get": function (name) {
+            return value[name];
+        },
+        "set": function (name, rhs) {
+            value[name] = rhs;
+        },
+        "delete": function (name) {
+            delete value[name];
+        },
+        "post": function (name, args) {
+            // Mark Miller proposes that post with no name should apply a
+            // promised function.
+            if (name === null || name === void 0) {
+                return value.apply(void 0, args);
+            } else {
+                return value[name].apply(value, args);
+            }
+        },
+        "apply": function (thisp, args) {
+            return value.apply(thisp, args);
+        },
+        "keys": function () {
+            return object_keys(value);
+        }
+    }, void 0, function inspect() {
+        return { state: "fulfilled", value: value };
+    });
+}
+
+/**
+ * Converts thenables to Q promises.
+ * @param promise thenable promise
+ * @returns a Q promise
+ */
+function coerce(promise) {
+    var deferred = defer();
+    Q.nextTick(function () {
+        try {
+            promise.then(deferred.resolve, deferred.reject, deferred.notify);
+        } catch (exception) {
+            deferred.reject(exception);
+        }
+    });
+    return deferred.promise;
+}
+
+/**
+ * Annotates an object such that it will never be
+ * transferred away from this process over any promise
+ * communication channel.
+ * @param object
+ * @returns promise a wrapping of that object that
+ * additionally responds to the "isDef" message
+ * without a rejection.
+ */
+Q.master = master;
+function master(object) {
+    return Promise({
+        "isDef": function () {}
+    }, function fallback(op, args) {
+        return dispatch(object, op, args);
+    }, function () {
+        return Q(object).inspect();
+    });
+}
+
+/**
+ * Spreads the values of a promised array of arguments into the
+ * fulfillment callback.
+ * @param fulfilled callback that receives variadic arguments from the
+ * promised array
+ * @param rejected callback that receives the exception if the promise
+ * is rejected.
+ * @returns a promise for the return value or thrown exception of
+ * either callback.
+ */
+Q.spread = spread;
+function spread(value, fulfilled, rejected) {
+    return Q(value).spread(fulfilled, rejected);
+}
+
+Promise.prototype.spread = function (fulfilled, rejected) {
+    return this.all().then(function (array) {
+        return fulfilled.apply(void 0, array);
+    }, rejected);
+};
+
+/**
+ * The async function is a decorator for generator functions, turning
+ * them into asynchronous generators.  Although generators are only part
+ * of the newest ECMAScript 6 drafts, this code does not cause syntax
+ * errors in older engines.  This code should continue to work and will
+ * in fact improve over time as the language improves.
+ *
+ * ES6 generators are currently part of V8 version 3.19 with the
+ * --harmony-generators runtime flag enabled.  SpiderMonkey has had them
+ * for longer, but under an older Python-inspired form.  This function
+ * works on both kinds of generators.
+ *
+ * Decorates a generator function such that:
+ *  - it may yield promises
+ *  - execution will continue when that promise is fulfilled
+ *  - the value of the yield expression will be the fulfilled value
+ *  - it returns a promise for the return value (when the generator
+ *    stops iterating)
+ *  - the decorated function returns a promise for the return value
+ *    of the generator or the first rejected promise among those
+ *    yielded.
+ *  - if an error is thrown in the generator, it propagates through
+ *    every following yield until it is caught, or until it escapes
+ *    the generator function altogether, and is translated into a
+ *    rejection for the promise returned by the decorated generator.
+ */
+Q.async = async;
+function async(makeGenerator) {
+    return function () {
+        // when verb is "send", arg is a value
+        // when verb is "throw", arg is an exception
+        function continuer(verb, arg) {
+            var result;
+
+            // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
+            // engine that has a deployed base of browsers that support generators.
+            // However, SM's generators use the Python-inspired semantics of
+            // outdated ES6 drafts.  We would like to support ES6, but we'd also
+            // like to make it possible to use generators in deployed browsers, so
+            // we also support Python-style generators.  At some point we can remove
+            // this block.
+
+            if (typeof StopIteration === "undefined") {
+                // ES6 Generators
+                try {
+                    result = generator[verb](arg);
+                } catch (exception) {
+                    return reject(exception);
+                }
+                if (result.done) {
+                    return Q(result.value);
+                } else {
+                    return when(result.value, callback, errback);
+                }
+            } else {
+                // SpiderMonkey Generators
+                // FIXME: Remove this case when SM does ES6 generators.
+                try {
+                    result = generator[verb](arg);
+                } catch (exception) {
+                    if (isStopIteration(exception)) {
+                        return Q(exception.value);
+                    } else {
+                        return reject(exception);
+                    }
+                }
+                return when(result, callback, errback);
+            }
+        }
+        var generator = makeGenerator.apply(this, arguments);
+        var callback = continuer.bind(continuer, "next");
+        var errback = continuer.bind(continuer, "throw");
+        return callback();
+    };
+}
+
+/**
+ * The spawn function is a small wrapper around async that immediately
+ * calls the generator and also ends the promise chain, so that any
+ * unhandled errors are thrown instead of forwarded to the error
+ * handler. This is useful because it's extremely common to run
+ * generators at the top-level to work with libraries.
+ */
+Q.spawn = spawn;
+function spawn(makeGenerator) {
+    Q.done(Q.async(makeGenerator)());
+}
+
+// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
+/**
+ * Throws a ReturnValue exception to stop an asynchronous generator.
+ *
+ * This interface is a stop-gap measure to support generator return
+ * values in older Firefox/SpiderMonkey.  In browsers that support ES6
+ * generators like Chromium 29, just use "return" in your generator
+ * functions.
+ *
+ * @param value the return value for the surrounding generator
+ * @throws ReturnValue exception with the value.
+ * @example
+ * // ES6 style
+ * Q.async(function* () {
+ *      var foo = yield getFooPromise();
+ *      var bar = yield getBarPromise();
+ *      return foo + bar;
+ * })
+ * // Older SpiderMonkey style
+ * Q.async(function () {
+ *      var foo = yield getFooPromise();
+ *      var bar = yield getBarPromise();
+ *      Q.return(foo + bar);
+ * })
+ */
+Q["return"] = _return;
+function _return(value) {
+    throw new QReturnValue(value);
+}
+
+/**
+ * The promised function decorator ensures that any promise arguments
+ * are settled and passed as values (`this` is also settled and passed
+ * as a value).  It will also ensure that the result of a function is
+ * always a promise.
+ *
+ * @example
+ * var add = Q.promised(function (a, b) {
+ *     return a + b;
+ * });
+ * add(Q(a), Q(B));
+ *
+ * @param {function} callback The function to decorate
+ * @returns {function} a function that has been decorated.
+ */
+Q.promised = promised;
+function promised(callback) {
+    return function () {
+        return spread([this, all(arguments)], function (self, args) {
+            return callback.apply(self, args);
+        });
+    };
+}
+
+/**
+ * sends a message to a value in a future turn
+ * @param object* the recipient
+ * @param op the name of the message operation, e.g., "when",
+ * @param args further arguments to be forwarded to the operation
+ * @returns result {Promise} a promise for the result of the operation
+ */
+Q.dispatch = dispatch;
+function dispatch(object, op, args) {
+    return Q(object).dispatch(op, args);
+}
+
+Promise.prototype.dispatch = function (op, args) {
+    var self = this;
+    var deferred = defer();
+    Q.nextTick(function () {
+        self.promiseDispatch(deferred.resolve, op, args);
+    });
+    return deferred.promise;
+};
+
+/**
+ * Gets the value of a property in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of property to get
+ * @return promise for the property value
+ */
+Q.get = function (object, key) {
+    return Q(object).dispatch("get", [key]);
+};
+
+Promise.prototype.get = function (key) {
+    return this.dispatch("get", [key]);
+};
+
+/**
+ * Sets the value of a property in a future turn.
+ * @param object    promise or immediate reference for object object
+ * @param name      name of property to set
+ * @param value     new value of property
+ * @return promise for the return value
+ */
+Q.set = function (object, key, value) {
+    return Q(object).dispatch("set", [key, value]);
+};
+
+Promise.prototype.set = function (key, value) {
+    return this.dispatch("set", [key, value]);
+};
+
+/**
+ * Deletes a property in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of property to delete
+ * @return promise for the return value
+ */
+Q.del = // XXX legacy
+Q["delete"] = function (object, key) {
+    return Q(object).dispatch("delete", [key]);
+};
+
+Promise.prototype.del = // XXX legacy
+Promise.prototype["delete"] = function (key) {
+    return this.dispatch("delete", [key]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of method to invoke
+ * @param value     a value to post, typically an array of
+ *                  invocation arguments for promises that
+ *                  are ultimately backed with `resolve` values,
+ *                  as opposed to those backed with URLs
+ *                  wherein the posted value can be any
+ *                  JSON serializable object.
+ * @return promise for the return value
+ */
+// bound locally because it is used by other methods
+Q.mapply = // XXX As proposed by "Redsandro"
+Q.post = function (object, name, args) {
+    return Q(object).dispatch("post", [name, args]);
+};
+
+Promise.prototype.mapply = // XXX As proposed by "Redsandro"
+Promise.prototype.post = function (name, args) {
+    return this.dispatch("post", [name, args]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of method to invoke
+ * @param ...args   array of invocation arguments
+ * @return promise for the return value
+ */
+Q.send = // XXX Mark Miller's proposed parlance
+Q.mcall = // XXX As proposed by "Redsandro"
+Q.invoke = function (object, name /*...args*/) {
+    return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
+};
+
+Promise.prototype.send = // XXX Mark Miller's proposed parlance
+Promise.prototype.mcall = // XXX As proposed by "Redsandro"
+Promise.prototype.invoke = function (name /*...args*/) {
+    return this.dispatch("post", [name, array_slice(arguments, 1)]);
+};
+
+/**
+ * Applies the promised function in a future turn.
+ * @param object    promise or immediate reference for target function
+ * @param args      array of application arguments
+ */
+Q.fapply = function (object, args) {
+    return Q(object).dispatch("apply", [void 0, args]);
+};
+
+Promise.prototype.fapply = function (args) {
+    return this.dispatch("apply", [void 0, args]);
+};
+
+/**
+ * Calls the promised function in a future turn.
+ * @param object    promise or immediate reference for target function
+ * @param ...args   array of application arguments
+ */
+Q["try"] =
+Q.fcall = function (object /* ...args*/) {
+    return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
+};
+
+Promise.prototype.fcall = function (/*...args*/) {
+    return this.dispatch("apply", [void 0, array_slice(arguments)]);
+};
+
+/**
+ * Binds the promised function, transforming return values into a fulfilled
+ * promise and thrown errors into a rejected one.
+ * @param object    promise or immediate reference for target function
+ * @param ...args   array of application arguments
+ */
+Q.fbind = function (object /*...args*/) {
+    var promise = Q(object);
+    var args = array_slice(arguments, 1);
+    return function fbound() {
+        return promise.dispatch("apply", [
+            this,
+            args.concat(array_slice(arguments))
+        ]);
+    };
+};
+Promise.prototype.fbind = function (/*...args*/) {
+    var promise = this;
+    var args = array_slice(arguments);
+    return function fbound() {
+        return promise.dispatch("apply", [
+            this,
+            args.concat(array_slice(arguments))
+        ]);
+    };
+};
+
+/**
+ * Requests the names of the owned properties of a promised
+ * object in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @return promise for the keys of the eventually settled object
+ */
+Q.keys = function (object) {
+    return Q(object).dispatch("keys", []);
+};
+
+Promise.prototype.keys = function () {
+    return this.dispatch("keys", []);
+};
+
+/**
+ * Turns an array of promises into a promise for an array.  If any of
+ * the promises gets rejected, the whole array is rejected immediately.
+ * @param {Array*} an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns a promise for an array of the corresponding values
+ */
+// By Mark Miller
+// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
+Q.all = all;
+function all(promises) {
+    return when(promises, function (promises) {
+        var pendingCount = 0;
+        var deferred = defer();
+        array_reduce(promises, function (undefined, promise, index) {
+            var snapshot;
+            if (
+                isPromise(promise) &&
+                (snapshot = promise.inspect()).state === "fulfilled"
+            ) {
+                promises[index] = snapshot.value;
+            } else {
+                ++pendingCount;
+                when(
+                    promise,
+                    function (value) {
+                        promises[index] = value;
+                        if (--pendingCount === 0) {
+                            deferred.resolve(promises);
+                        }
+                    },
+                    deferred.reject,
+                    function (progress) {
+                        deferred.notify({ index: index, value: progress });
+                    }
+                );
+            }
+        }, void 0);
+        if (pendingCount === 0) {
+            deferred.resolve(promises);
+        }
+        return deferred.promise;
+    });
+}
+
+Promise.prototype.all = function () {
+    return all(this);
+};
+
+/**
+ * Returns the first resolved promise of an array. Prior rejected promises are
+ * ignored.  Rejects only if all promises are rejected.
+ * @param {Array*} an array containing values or promises for values
+ * @returns a promise fulfilled with the value of the first resolved promise,
+ * or a rejected promise if all promises are rejected.
+ */
+Q.any = any;
+
+function any(promises) {
+    if (promises.length === 0) {
+        return Q.resolve();
+    }
+
+    var deferred = Q.defer();
+    var pendingCount = 0;
+    array_reduce(promises, function (prev, current, index) {
+        var promise = promises[index];
+
+        pendingCount++;
+
+        when(promise, onFulfilled, onRejected, onProgress);
+        function onFulfilled(result) {
+            deferred.resolve(result);
+        }
+        function onRejected() {
+            pendingCount--;
+            if (pendingCount === 0) {
+                deferred.reject(new Error(
+                    "Can't get fulfillment value from any promise, all " +
+                    "promises were rejected."
+                ));
+            }
+        }
+        function onProgress(progress) {
+            deferred.notify({
+                index: index,
+                value: progress
+            });
+        }
+    }, undefined);
+
+    return deferred.promise;
+}
+
+Promise.prototype.any = function () {
+    return any(this);
+};
+
+/**
+ * Waits for all promises to be settled, either fulfilled or
+ * rejected.  This is distinct from `all` since that would stop
+ * waiting at the first rejection.  The promise returned by
+ * `allResolved` will never be rejected.
+ * @param promises a promise for an array (or an array) of promises
+ * (or values)
+ * @return a promise for an array of promises
+ */
+Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
+function allResolved(promises) {
+    return when(promises, function (promises) {
+        promises = array_map(promises, Q);
+        return when(all(array_map(promises, function (promise) {
+            return when(promise, noop, noop);
+        })), function () {
+            return promises;
+        });
+    });
+}
+
+Promise.prototype.allResolved = function () {
+    return allResolved(this);
+};
+
+/**
+ * @see Promise#allSettled
+ */
+Q.allSettled = allSettled;
+function allSettled(promises) {
+    return Q(promises).allSettled();
+}
+
+/**
+ * Turns an array of promises into a promise for an array of their states (as
+ * returned by `inspect`) when they have all settled.
+ * @param {Array[Any*]} values an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns {Array[State]} an array of states for the respective values.
+ */
+Promise.prototype.allSettled = function () {
+    return this.then(function (promises) {
+        return all(array_map(promises, function (promise) {
+            promise = Q(promise);
+            function regardless() {
+                return promise.inspect();
+            }
+            return promise.then(regardless, regardless);
+        }));
+    });
+};
+
+/**
+ * Captures the failure of a promise, giving an oportunity to recover
+ * with a callback.  If the given promise is fulfilled, the returned
+ * promise is fulfilled.
+ * @param {Any*} promise for something
+ * @param {Function} callback to fulfill the returned promise if the
+ * given promise is rejected
+ * @returns a promise for the return value of the callback
+ */
+Q.fail = // XXX legacy
+Q["catch"] = function (object, rejected) {
+    return Q(object).then(void 0, rejected);
+};
+
+Promise.prototype.fail = // XXX legacy
+Promise.prototype["catch"] = function (rejected) {
+    return this.then(void 0, rejected);
+};
+
+/**
+ * Attaches a listener that can respond to progress notifications from a
+ * promise's originating deferred. This listener receives the exact arguments
+ * passed to ``deferred.notify``.
+ * @param {Any*} promise for something
+ * @param {Function} callback to receive any progress notifications
+ * @returns the given promise, unchanged
+ */
+Q.progress = progress;
+function progress(object, progressed) {
+    return Q(object).then(void 0, void 0, progressed);
+}
+
+Promise.prototype.progress = function (progressed) {
+    return this.then(void 0, void 0, progressed);
+};
+
+/**
+ * Provides an opportunity to observe the settling of a promise,
+ * regardless of whether the promise is fulfilled or rejected.  Forwards
+ * the resolution to the returned promise when the callback is done.
+ * The callback can return a promise to defer completion.
+ * @param {Any*} promise
+ * @param {Function} callback to observe the resolution of the given
+ * promise, takes no arguments.
+ * @returns a promise for the resolution of the given promise when
+ * ``fin`` is done.
+ */
+Q.fin = // XXX legacy
+Q["finally"] = function (object, callback) {
+    return Q(object)["finally"](callback);
+};
+
+Promise.prototype.fin = // XXX legacy
+Promise.prototype["finally"] = function (callback) {
+    callback = Q(callback);
+    return this.then(function (value) {
+        return callback.fcall().then(function () {
+            return value;
+        });
+    }, function (reason) {
+        // TODO attempt to recycle the rejection with "this".
+        return callback.fcall().then(function () {
+            throw reason;
+        });
+    });
+};
+
+/**
+ * Terminates a chain of promises, forcing rejections to be
+ * thrown as exceptions.
+ * @param {Any*} promise at the end of a chain of promises
+ * @returns nothing
+ */
+Q.done = function (object, fulfilled, rejected, progress) {
+    return Q(object).done(fulfilled, rejected, progress);
+};
+
+Promise.prototype.done = function (fulfilled, rejected, progress) {
+    var onUnhandledError = function (error) {
+        // forward to a future turn so that ``when``
+        // does not catch it and turn it into a rejection.
+        Q.nextTick(function () {
+            makeStackTraceLong(error, promise);
+            if (Q.onerror) {
+                Q.onerror(error);
+            } else {
+                throw error;
+            }
+        });
+    };
+
+    // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
+    var promise = fulfilled || rejected || progress ?
+        this.then(fulfilled, rejected, progress) :
+        this;
+
+    if (typeof process === "object" && process && process.domain) {
+        onUnhandledError = process.domain.bind(onUnhandledError);
+    }
+
+    promise.then(void 0, onUnhandledError);
+};
+
+/**
+ * Causes a promise to be rejected if it does not get fulfilled before
+ * some milliseconds time out.
+ * @param {Any*} promise
+ * @param {Number} milliseconds timeout
+ * @param {Any*} custom error message or Error object (optional)
+ * @returns a promise for the resolution of the given promise if it is
+ * fulfilled before the timeout, otherwise rejected.
+ */
+Q.timeout = function (object, ms, error) {
+    return Q(object).timeout(ms, error);
+};
+
+Promise.prototype.timeout = function (ms, error) {
+    var deferred = defer();
+    var timeoutId = setTimeout(function () {
+        if (!error || "string" === typeof error) {
+            error = new Error(error || "Timed out after " + ms + " ms");
+            error.code = "ETIMEDOUT";
+        }
+        deferred.reject(error);
+    }, ms);
+
+    this.then(function (value) {
+        clearTimeout(timeoutId);
+        deferred.resolve(value);
+    }, function (exception) {
+        clearTimeout(timeoutId);
+        deferred.reject(exception);
+    }, deferred.notify);
+
+    return deferred.promise;
+};
+
+/**
+ * Returns a promise for the given value (or promised value), some
+ * milliseconds after it resolved. Passes rejections immediately.
+ * @param {Any*} promise
+ * @param {Number} milliseconds
+ * @returns a promise for the resolution of the given promise after milliseconds
+ * time has elapsed since the resolution of the given promise.
+ * If the given promise rejects, that is passed immediately.
+ */
+Q.delay = function (object, timeout) {
+    if (timeout === void 0) {
+        timeout = object;
+        object = void 0;
+    }
+    return Q(object).delay(timeout);
+};
+
+Promise.prototype.delay = function (timeout) {
+    return this.then(function (value) {
+        var deferred = defer();
+        setTimeout(function () {
+            deferred.resolve(value);
+        }, timeout);
+        return deferred.promise;
+    });
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided as an array, and returns a promise.
+ *
+ *      Q.nfapply(FS.readFile, [__filename])
+ *      .then(function (content) {
+ *      })
+ *
+ */
+Q.nfapply = function (callback, args) {
+    return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfapply = function (args) {
+    var deferred = defer();
+    var nodeArgs = array_slice(args);
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.fapply(nodeArgs).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided individually, and returns a promise.
+ * @example
+ * Q.nfcall(FS.readFile, __filename)
+ * .then(function (content) {
+ * })
+ *
+ */
+Q.nfcall = function (callback /*...args*/) {
+    var args = array_slice(arguments, 1);
+    return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfcall = function (/*...args*/) {
+    var nodeArgs = array_slice(arguments);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.fapply(nodeArgs).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Wraps a NodeJS continuation passing function and returns an equivalent
+ * version that returns a promise.
+ * @example
+ * Q.nfbind(FS.readFile, __filename)("utf-8")
+ * .then(console.log)
+ * .done()
+ */
+Q.nfbind =
+Q.denodeify = function (callback /*...args*/) {
+    var baseArgs = array_slice(arguments, 1);
+    return function () {
+        var nodeArgs = baseArgs.concat(array_slice(arguments));
+        var deferred = defer();
+        nodeArgs.push(deferred.makeNodeResolver());
+        Q(callback).fapply(nodeArgs).fail(deferred.reject);
+        return deferred.promise;
+    };
+};
+
+Promise.prototype.nfbind =
+Promise.prototype.denodeify = function (/*...args*/) {
+    var args = array_slice(arguments);
+    args.unshift(this);
+    return Q.denodeify.apply(void 0, args);
+};
+
+Q.nbind = function (callback, thisp /*...args*/) {
+    var baseArgs = array_slice(arguments, 2);
+    return function () {
+        var nodeArgs = baseArgs.concat(array_slice(arguments));
+        var deferred = defer();
+        nodeArgs.push(deferred.makeNodeResolver());
+        function bound() {
+            return callback.apply(thisp, arguments);
+        }
+        Q(bound).fapply(nodeArgs).fail(deferred.reject);
+        return deferred.promise;
+    };
+};
+
+Promise.prototype.nbind = function (/*thisp, ...args*/) {
+    var args = array_slice(arguments, 0);
+    args.unshift(this);
+    return Q.nbind.apply(void 0, args);
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback with a given array of arguments, plus a provided callback.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param {Array} args arguments to pass to the method; the callback
+ * will be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nmapply = // XXX As proposed by "Redsandro"
+Q.npost = function (object, name, args) {
+    return Q(object).npost(name, args);
+};
+
+Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
+Promise.prototype.npost = function (name, args) {
+    var nodeArgs = array_slice(args || []);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback, forwarding the given variadic arguments, plus a provided
+ * callback argument.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param ...args arguments to pass to the method; the callback will
+ * be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nsend = // XXX Based on Mark Miller's proposed "send"
+Q.nmcall = // XXX Based on "Redsandro's" proposal
+Q.ninvoke = function (object, name /*...args*/) {
+    var nodeArgs = array_slice(arguments, 2);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
+Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
+Promise.prototype.ninvoke = function (name /*...args*/) {
+    var nodeArgs = array_slice(arguments, 1);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * If a function would like to support both Node continuation-passing-style and
+ * promise-returning-style, it can end its internal promise chain with
+ * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user
+ * elects to use a nodeback, the result will be sent there.  If they do not
+ * pass a nodeback, they will receive the result promise.
+ * @param object a result (or a promise for a result)
+ * @param {Function} nodeback a Node.js-style callback
+ * @returns either the promise or nothing
+ */
+Q.nodeify = nodeify;
+function nodeify(object, nodeback) {
+    return Q(object).nodeify(nodeback);
+}
+
+Promise.prototype.nodeify = function (nodeback) {
+    if (nodeback) {
+        this.then(function (value) {
+            Q.nextTick(function () {
+                nodeback(null, value);
+            });
+        }, function (error) {
+            Q.nextTick(function () {
+                nodeback(error);
+            });
+        });
+    } else {
+        return this;
+    }
+};
+
+Q.noConflict = function() {
+    throw new Error("Q.noConflict only works when Q is used as a global");
+};
+
+// All code before this point will be filtered from stack traces.
+var qEndingLine = captureLine();
+
+return Q;
+
+});
+
+}).call(this,require('_process'))
+//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9xL3EuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG4iXX0=
+},{"_process":13}],160:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){  
+  var idx = 0;
+  var len = arr.length;
+  var curr = arguments.length == 3
+    ? initial
+    : arr[idx++];
+
+  while (idx < len) {
+    curr = fn.call(null, curr, arr[idx], ++idx, arr);
+  }
+  
+  return curr;
+};
+},{}],161:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root;
+if (typeof window !== 'undefined') { // Browser window
+  root = window;
+} else if (typeof self !== 'undefined') { // Web Worker
+  root = self;
+} else { // Other environments
+  root = this;
+}
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+  var str = {}.toString.call(obj);
+
+  switch (str) {
+    case '[object File]':
+    case '[object Blob]':
+    case '[object FormData]':
+      return true;
+    default:
+      return false;
+  }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+  if (root.XMLHttpRequest
+      && (!root.location || 'file:' != root.location.protocol
+          || !root.ActiveXObject)) {
+    return new XMLHttpRequest;
+  } else {
+    try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+  }
+  return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+  ? function(s) { return s.trim(); }
+  : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+  return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+  if (!isObject(obj)) return obj;
+  var pairs = [];
+  for (var key in obj) {
+    if (null != obj[key]) {
+      pushEncodedKeyValuePair(pairs, key, obj[key]);
+        }
+      }
+  return pairs.join('&');
+}
+
+/**
+ * Helps 'serialize' with serializing arrays.
+ * Mutates the pairs array.
+ *
+ * @param {Array} pairs
+ * @param {String} key
+ * @param {Mixed} val
+ */
+
+function pushEncodedKeyValuePair(pairs, key, val) {
+  if (Array.isArray(val)) {
+    return val.forEach(function(v) {
+      pushEncodedKeyValuePair(pairs, key, v);
+    });
+  }
+  pairs.push(encodeURIComponent(key)
+    + '=' + encodeURIComponent(val));
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+  * Parse the given x-www-form-urlencoded `str`.
+  *
+  * @param {String} str
+  * @return {Object}
+  * @api private
+  */
+
+function parseString(str) {
+  var obj = {};
+  var pairs = str.split('&');
+  var parts;
+  var pair;
+
+  for (var i = 0, len = pairs.length; i < len; ++i) {
+    pair = pairs[i];
+    parts = pair.split('=');
+    obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+  }
+
+  return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ *     superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+  html: 'text/html',
+  json: 'application/json',
+  xml: 'application/xml',
+  urlencoded: 'application/x-www-form-urlencoded',
+  'form': 'application/x-www-form-urlencoded',
+  'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ *     superagent.serialize['application/xml'] = function(obj){
+ *       return 'generated xml here';
+ *     };
+ *
+ */
+
+ request.serialize = {
+   'application/x-www-form-urlencoded': serialize,
+   'application/json': JSON.stringify
+ };
+
+ /**
+  * Default parsers.
+  *
+  *     superagent.parse['application/xml'] = function(str){
+  *       return { object parsed from str };
+  *     };
+  *
+  */
+
+request.parse = {
+  'application/x-www-form-urlencoded': parseString,
+  'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+  var lines = str.split(/\r?\n/);
+  var fields = {};
+  var index;
+  var line;
+  var field;
+  var val;
+
+  lines.pop(); // trailing CRLF
+
+  for (var i = 0, len = lines.length; i < len; ++i) {
+    line = lines[i];
+    index = line.indexOf(':');
+    field = line.slice(0, index).toLowerCase();
+    val = trim(line.slice(index + 1));
+    fields[field] = val;
+  }
+
+  return fields;
+}
+
+/**
+ * Check if `mime` is json or has +json structured syntax suffix.
+ *
+ * @param {String} mime
+ * @return {Boolean}
+ * @api private
+ */
+
+function isJSON(mime) {
+  return /[\/+]json\b/.test(mime);
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+  return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+  return reduce(str.split(/ *; */), function(obj, str){
+    var parts = str.split(/ *= */)
+      , key = parts.shift()
+      , val = parts.shift();
+
+    if (key && val) obj[key] = val;
+    return obj;
+  }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ *  - set flags (.ok, .error, etc)
+ *  - parse header
+ *
+ * Examples:
+ *
+ *  Aliasing `superagent` as `request` is nice:
+ *
+ *      request = superagent;
+ *
+ *  We can use the promise-like API, or pass callbacks:
+ *
+ *      request.get('/').end(function(res){});
+ *      request.get('/', function(res){});
+ *
+ *  Sending data can be chained:
+ *
+ *      request
+ *        .post('/user')
+ *        .send({ name: 'tj' })
+ *        .end(function(res){});
+ *
+ *  Or passed to `.send()`:
+ *
+ *      request
+ *        .post('/user')
+ *        .send({ name: 'tj' }, function(res){});
+ *
+ *  Or passed to `.post()`:
+ *
+ *      request
+ *        .post('/user', { name: 'tj' })
+ *        .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ *      request
+ *        .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+  options = options || {};
+  this.req = req;
+  this.xhr = this.req.xhr;
+  // responseText is accessible only if responseType is '' or 'text' and on older browsers
+  this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+     ? this.xhr.responseText
+     : null;
+  this.statusText = this.req.xhr.statusText;
+  this.setStatusProperties(this.xhr.status);
+  this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+  // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+  // getResponseHeader still works. so we get content-type even if getting
+  // other headers fails.
+  this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+  this.setHeaderProperties(this.header);
+  this.body = this.req.method != 'HEAD'
+    ? this.parseBody(this.text ? this.text : this.xhr.response)
+    : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+  return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ *   - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+  // content-type
+  var ct = this.header['content-type'] || '';
+  this.type = type(ct);
+
+  // params
+  var obj = params(ct);
+  for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+  var parse = request.parse[this.type];
+  return parse && str && (str.length || str instanceof Object)
+    ? parse(str)
+    : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ *   - .noContent
+ *   - .badRequest
+ *   - .unauthorized
+ *   - .notAcceptable
+ *   - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+  // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+  if (status === 1223) {
+    status = 204;
+  }
+
+  var type = status / 100 | 0;
+
+  // status / class
+  this.status = this.statusCode = status;
+  this.statusType = type;
+
+  // basics
+  this.info = 1 == type;
+  this.ok = 2 == type;
+  this.clientError = 4 == type;
+  this.serverError = 5 == type;
+  this.error = (4 == type || 5 == type)
+    ? this.toError()
+    : false;
+
+  // sugar
+  this.accepted = 202 == status;
+  this.noContent = 204 == status;
+  this.badRequest = 400 == status;
+  this.unauthorized = 401 == status;
+  this.notAcceptable = 406 == status;
+  this.notFound = 404 == status;
+  this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+  var req = this.req;
+  var method = req.method;
+  var url = req.url;
+
+  var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+  var err = new Error(msg);
+  err.status = this.status;
+  err.method = method;
+  err.url = url;
+
+  return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+  var self = this;
+  Emitter.call(this);
+  this._query = this._query || [];
+  this.method = method;
+  this.url = url;
+  this.header = {};
+  this._header = {};
+  this.on('end', function(){
+    var err = null;
+    var res = null;
+
+    try {
+      res = new Response(self);
+    } catch(e) {
+      err = new Error('Parser is unable to parse the response');
+      err.parse = true;
+      err.original = e;
+      // issue #675: return the raw response if the response parsing fails
+      err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;
+      return self.callback(err);
+    }
+
+    self.emit('response', res);
+
+    if (err) {
+      return self.callback(err, res);
+    }
+
+    if (res.status >= 200 && res.status < 300) {
+      return self.callback(err, res);
+    }
+
+    var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+    new_err.original = err;
+    new_err.response = res;
+    new_err.status = res.status;
+
+    self.callback(new_err, res);
+  });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+  fn(this);
+  return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+  this._timeout = ms;
+  return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+  this._timeout = 0;
+  clearTimeout(this._timer);
+  return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+  if (this.aborted) return;
+  this.aborted = true;
+  this.xhr.abort();
+  this.clearTimeout();
+  this.emit('abort');
+  return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ *      req.get('/')
+ *        .set('Accept', 'application/json')
+ *        .set('X-API-Key', 'foobar')
+ *        .end(callback);
+ *
+ *      req.get('/')
+ *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ *        .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+  if (isObject(field)) {
+    for (var key in field) {
+      this.set(key, field[key]);
+    }
+    return this;
+  }
+  this._header[field.toLowerCase()] = val;
+  this.header[field] = val;
+  return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ *      req.get('/')
+ *        .unset('User-Agent')
+ *        .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+  delete this._header[field.toLowerCase()];
+  delete this.header[field];
+  return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+  return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ *      superagent.types.xml = 'application/xml';
+ *
+ *      request.post('/')
+ *        .type('xml')
+ *        .send(xmlstring)
+ *        .end(callback);
+ *
+ *      request.post('/')
+ *        .type('application/xml')
+ *        .send(xmlstring)
+ *        .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+  this.set('Content-Type', request.types[type] || type);
+  return this;
+};
+
+/**
+ * Force given parser
+ *
+ * Sets the body parser no matter type.
+ *
+ * @param {Function}
+ * @api public
+ */
+
+Request.prototype.parse = function(fn){
+  this._parser = fn;
+  return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ *      superagent.types.json = 'application/json';
+ *
+ *      request.get('/agent')
+ *        .accept('json')
+ *        .end(callback);
+ *
+ *      request.get('/agent')
+ *        .accept('application/json')
+ *        .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+  this.set('Accept', request.types[type] || type);
+  return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+  var str = btoa(user + ':' + pass);
+  this.set('Authorization', 'Basic ' + str);
+  return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+*   request.get('/shoes')
+*     .query('size=10')
+*     .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+  if ('string' != typeof val) val = serialize(val);
+  if (val) this._query.push(val);
+  return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ *   .field('foo', 'bar')
+ *   .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+  if (!this._formData) this._formData = new root.FormData();
+  this._formData.append(name, val);
+  return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ *   .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
+ *   .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+  if (!this._formData) this._formData = new root.FormData();
+  this._formData.append(field, file, filename || file.name);
+  return this;
+};
+
+/**
+ * Send `data` as the request body, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ *       // manual json
+ *       request.post('/user')
+ *         .type('json')
+ *         .send('{"name":"tj"}')
+ *         .end(callback)
+ *
+ *       // auto json
+ *       request.post('/user')
+ *         .send({ name: 'tj' })
+ *         .end(callback)
+ *
+ *       // manual x-www-form-urlencoded
+ *       request.post('/user')
+ *         .type('form')
+ *         .send('name=tj')
+ *         .end(callback)
+ *
+ *       // auto x-www-form-urlencoded
+ *       request.post('/user')
+ *         .type('form')
+ *         .send({ name: 'tj' })
+ *         .end(callback)
+ *
+ *       // defaults to x-www-form-urlencoded
+  *      request.post('/user')
+  *        .send('name=tobi')
+  *        .send('species=ferret')
+  *        .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+  var obj = isObject(data);
+  var type = this.getHeader('Content-Type');
+
+  // merge
+  if (obj && isObject(this._data)) {
+    for (var key in data) {
+      this._data[key] = data[key];
+    }
+  } else if ('string' == typeof data) {
+    if (!type) this.type('form');
+    type = this.getHeader('Content-Type');
+    if ('application/x-www-form-urlencoded' == type) {
+      this._data = this._data
+        ? this._data + '&' + data
+        : data;
+    } else {
+      this._data = (this._data || '') + data;
+    }
+  } else {
+    this._data = data;
+  }
+
+  if (!obj || isHost(data)) return this;
+  if (!type) this.type('json');
+  return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+  var fn = this._callback;
+  this.clearTimeout();
+  fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+  var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
+  err.crossDomain = true;
+
+  err.status = this.status;
+  err.method = this.method;
+  err.url = this.url;
+
+  this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+  var timeout = this._timeout;
+  var err = new Error('timeout of ' + timeout + 'ms exceeded');
+  err.timeout = timeout;
+  this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+  this._withCredentials = true;
+  return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+  var self = this;
+  var xhr = this.xhr = request.getXHR();
+  var query = this._query.join('&');
+  var timeout = this._timeout;
+  var data = this._formData || this._data;
+
+  // store callback
+  this._callback = fn || noop;
+
+  // state change
+  xhr.onreadystatechange = function(){
+    if (4 != xhr.readyState) return;
+
+    // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+    // result in the error "Could not complete the operation due to error c00c023f"
+    var status;
+    try { status = xhr.status } catch(e) { status = 0; }
+
+    if (0 == status) {
+      if (self.timedout) return self.timeoutError();
+      if (self.aborted) return;
+      return self.crossDomainError();
+    }
+    self.emit('end');
+  };
+
+  // progress
+  var handleProgress = function(e){
+    if (e.total > 0) {
+      e.percent = e.loaded / e.total * 100;
+    }
+    e.direction = 'download';
+    self.emit('progress', e);
+  };
+  if (this.hasListeners('progress')) {
+    xhr.onprogress = handleProgress;
+  }
+  try {
+    if (xhr.upload && this.hasListeners('progress')) {
+      xhr.upload.onprogress = handleProgress;
+    }
+  } catch(e) {
+    // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+    // Reported here:
+    // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+  }
+
+  // timeout
+  if (timeout && !this._timer) {
+    this._timer = setTimeout(function(){
+      self.timedout = true;
+      self.abort();
+    }, timeout);
+  }
+
+  // querystring
+  if (query) {
+    query = request.serializeObject(query);
+    this.url += ~this.url.indexOf('?')
+      ? '&' + query
+      : '?' + query;
+  }
+
+  // initiate request
+  xhr.open(this.method, this.url, true);
+
+  // CORS
+  if (this._withCredentials) xhr.withCredentials = true;
+
+  // body
+  if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+    // serialize stuff
+    var contentType = this.getHeader('Content-Type');
+    var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : ''];
+    if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
+    if (serialize) data = serialize(data);
+  }
+
+  // set header fields
+  for (var field in this.header) {
+    if (null == this.header[field]) continue;
+    xhr.setRequestHeader(field, this.header[field]);
+  }
+
+  // send stuff
+  this.emit('request', this);
+
+  // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
+  // We need null here if data is undefined
+  xhr.send(typeof data !== 'undefined' ? data : null);
+  return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+  return this.end(function(err, res) {
+    err ? reject(err) : fulfill(res);
+  });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ *    request('GET', '/users').end(callback)
+ *    request('/users').end(callback)
+ *    request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+  // callback
+  if ('function' == typeof url) {
+    return new Request('GET', method).end(url);
+  }
+
+  // url first
+  if (1 == arguments.length) {
+    return new Request('GET', method);
+  }
+
+  return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+  var req = request('GET', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.query(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+  var req = request('HEAD', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+function del(url, fn){
+  var req = request('DELETE', url);
+  if (fn) req.end(fn);
+  return req;
+};
+
+request['del'] = del;
+request['delete'] = del;
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+  var req = request('PATCH', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+  var req = request('POST', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+  var req = request('PUT', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":19,"reduce":160}]},{},[1])(1)
+});
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsImxpYi9hdXRoLmpzIiwibGliL2NsaWVudC5qcyIsImxpYi9oZWxwZXJzLmpzIiwibGliL2h0dHAuanMiLCJsaWIvcmVzb2x2ZXIuanMiLCJsaWIvc2NoZW1hLW1hcmt1cC5qcyIsImxpYi9zcGVjLWNvbnZlcnRlci5qcyIsImxpYi90eXBlcy9tb2RlbC5qcyIsImxpYi90eXBlcy9vcGVyYXRpb24uanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uR3JvdXAuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3JlZHVjZS1jb21wb25lbnQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvY2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDem1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL3lCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4b0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbCtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMXlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGpEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGF1dGggPSByZXF1aXJlKCcuL2xpYi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vbGliL2hlbHBlcnMnKTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gcmVxdWlyZSgnLi9saWIvY2xpZW50Jyk7XG52YXIgZGVwcmVjYXRpb25XcmFwcGVyID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICBoZWxwZXJzLmxvZygnVGhpcyBpcyBkZXByZWNhdGVkLCB1c2UgXCJuZXcgU3dhZ2dlckNsaWVudFwiIGluc3RlYWQuJyk7XG5cbiAgcmV0dXJuIG5ldyBTd2FnZ2VyQ2xpZW50KHVybCwgb3B0aW9ucyk7XG59O1xuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFBcnJheS5wcm90b3R5cGUuaW5kZXhPZikge1xuICBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uKG9iaiwgc3RhcnQpIHtcbiAgICBmb3IgKHZhciBpID0gKHN0YXJ0IHx8IDApLCBqID0gdGhpcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgIGlmICh0aGlzW2ldID09PSBvYmopIHsgcmV0dXJuIGk7IH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBJRTggU3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcbiAgU3RyaW5nLnByb3RvdHlwZS50cmltID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgfTtcbn1cblxuLyogSGVyZSBmb3Igbm9kZSAxMC54IHN1cHBvcnQgKi9cbmlmICghU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCkge1xuICBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24oc3VmZml4KSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXhPZihzdWZmaXgsIHRoaXMubGVuZ3RoIC0gc3VmZml4Lmxlbmd0aCkgIT09IC0xO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN3YWdnZXJDbGllbnQ7XG5cblN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGF1dGguQXBpS2V5QXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuUGFzc3dvcmRBdXRob3JpemF0aW9uID0gYXV0aC5QYXNzd29yZEF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LkNvb2tpZUF1dGhvcml6YXRpb24gPSBhdXRoLkNvb2tpZUF1dGhvcml6YXRpb247XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJBcGkgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlN3YWdnZXJDbGllbnQgPSBkZXByZWNhdGlvbldyYXBwZXI7XG5Td2FnZ2VyQ2xpZW50LlNjaGVtYU1hcmt1cCA9IHJlcXVpcmUoJy4vbGliL3NjaGVtYS1tYXJrdXAnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcbnZhciBidG9hID0gcmVxdWlyZSgnYnRvYScpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbnZhciBDb29raWVKYXIgPSByZXF1aXJlKCdjb29raWVqYXInKS5Db29raWVKYXI7XG52YXIgXyA9IHtcbiAgZWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2gnKSxcbiAgaW5jbHVkZXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9pbmNsdWRlcycpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5Jylcbn07XG5cbi8qKlxuICogU3dhZ2dlckF1dGhvcml6YXRpb25zIGFwcGx5cyB0aGUgY29ycmVjdCBhdXRob3JpemF0aW9uIHRvIGFuIG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZFxuICovXG52YXIgU3dhZ2dlckF1dGhvcml6YXRpb25zID0gbW9kdWxlLmV4cG9ydHMuU3dhZ2dlckF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24gKGF1dGh6KSB7XG4gIHRoaXMuYXV0aHogPSBhdXRoeiB8fCB7fTtcbn07XG5cbi8qKlxuICogQWRkIGF1dGhzIHRvIHRoZSBoYXNoXG4gKiBXaWxsIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmdcbiAqXG4gKi9cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIGF1dGgpIHtcbiAgaWYoXy5pc09iamVjdChuYW1lKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IHRydWU7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIGZhdm9yIHRoZSBvYmplY3QtbGV2ZWwgYXV0aG9yaXphdGlvbnMgb3ZlciBnbG9iYWxcbiAgdmFyIGF1dGh6ID0gb2JqLmNsaWVudEF1dGhvcml6YXRpb25zIHx8IHRoaXMuYXV0aHo7XG5cbiAgLy8gU2VjdXJpdGllcyBjb3VsZCBiZSBbIHt9IF1cbiAgXy5lYWNoKHNlY3VyaXRpZXMsIGZ1bmN0aW9uIChvYmosIGtleSkge1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIGFjY291bnQgZm9yIHNlY3VyaXRpZXMgYmVpbmcgWyBzdHIgXVxuICAgIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9XG5cbiAgICAvLyBGbGF0dGVuIGtleXMgaW4gdG8gb3VyIGFycmF5XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24gKHZhbCwga2V5KSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgXy5lYWNoKGF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgdmFyIG5ld1N0YXR1cyA9IGF1dGguYXBwbHkob2JqKTtcbiAgICAgIHN0YXR1cyA9IHN0YXR1cyAmJiAhIW5ld1N0YXR1czsgLy8gbG9naWNhbCBPUnMgcmVnYXJkaW5nIHN0YXR1c1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXR1cztcbn07XG5cbi8qKlxuICogQXBpS2V5QXV0aG9yaXphdGlvbiBhbGxvd3MgYSBxdWVyeSBwYXJhbSBvciBoZWFkZXIgdG8gYmUgaW5qZWN0ZWRcbiAqL1xudmFyIEFwaUtleUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCB0eXBlKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn07XG5cbkFwaUtleUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAodGhpcy50eXBlID09PSAncXVlcnknKSB7XG4gICAgLy8gc2VlIGlmIGFscmVhZHkgYXBwbGllZC4gIElmIHNvLCBkb24ndCBkbyBpdCBhZ2FpblxuXG4gICAgdmFyIHFwO1xuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIHFwID0gb2JqLnVybC5zdWJzdHJpbmcob2JqLnVybC5pbmRleE9mKCc/JykgKyAxKTtcbiAgICAgIHZhciBwYXJ0cyA9IHFwLnNwbGl0KCcmJyk7XG4gICAgICBpZihwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBrdiA9IHBhcnRzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYoa3YgJiYga3YubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKGt2WzBdID09PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcCBpdFxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnJicgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICc/JyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnaGVhZGVyJykge1xuICAgIGlmKHR5cGVvZiBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbnZhciBDb29raWVBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQ29va2llQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgdGhpcy5jb29raWUgPSBjb29raWU7XG59O1xuXG5Db29raWVBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgb2JqLmNvb2tpZUphciA9IG9iai5jb29raWVKYXIgfHwgbmV3IENvb2tpZUphcigpO1xuICBvYmouY29va2llSmFyLnNldENvb2tpZSh0aGlzLmNvb2tpZSk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBhc3N3b3JkIEF1dGhvcml6YXRpb24gaXMgYSBiYXNpYyBhdXRoIGltcGxlbWVudGF0aW9uXG4gKi9cbnZhciBQYXNzd29yZEF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgaGVscGVycy5sb2coJ1Bhc3N3b3JkQXV0aG9yaXphdGlvbjogdGhlIFxcJ25hbWVcXCcgYXJndW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgcGFzcyBvbmx5IHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICAgIHVzZXJuYW1lID0gYXJndW1lbnRzWzFdO1xuICAgIHBhc3N3b3JkID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHRoaXMudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkO1xufTtcblxuUGFzc3dvcmRBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYodHlwZW9mIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh0aGlzLnVzZXJuYW1lICsgJzonICsgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRnVuY3Rpb246IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uJyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKVxufTtcbnZhciBhdXRoID0gcmVxdWlyZSgnLi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi90eXBlcy9tb2RlbCcpO1xudmFyIE9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uJyk7XG52YXIgT3BlcmF0aW9uR3JvdXAgPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbkdyb3VwJyk7XG52YXIgUmVzb2x2ZXIgPSByZXF1aXJlKCcuL3Jlc29sdmVyJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vc3BlYy1jb252ZXJ0ZXInKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRDbGllbnRUYWdzID0gW1xuICAnYXBpcycsXG4gICdhdXRob3JpemF0aW9uU2NoZW1lJyxcbiAgJ2F1dGhvcml6YXRpb25zJyxcbiAgJ2Jhc2VQYXRoJyxcbiAgJ2J1aWxkJyxcbiAgJ2J1aWxkRnJvbTFfMVNwZWMnLFxuICAnYnVpbGRGcm9tMV8yU3BlYycsXG4gICdidWlsZEZyb21TcGVjJyxcbiAgJ2NsaWVudEF1dGhvcml6YXRpb25zJyxcbiAgJ2NvbnZlcnRJbmZvJyxcbiAgJ2RlYnVnJyxcbiAgJ2RlZmF1bHRFcnJvckNhbGxiYWNrJyxcbiAgJ2RlZmF1bHRTdWNjZXNzQ2FsbGJhY2snLFxuICAnZW5hYmxlQ29va2llcycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaG9zdCcsXG4gICdpZEZyb21PcCcsXG4gICdpbmZvJyxcbiAgJ2luaXRpYWxpemUnLFxuICAnaXNCdWlsdCcsXG4gICdpc1ZhbGlkJyxcbiAgJ21vZGVsUHJvcGVydHlNYWNybycsXG4gICdtb2RlbHMnLFxuICAnbW9kZWxzQXJyYXknLFxuICAnb3B0aW9ucycsXG4gICdwYXJhbWV0ZXJNYWNybycsXG4gICdwYXJzZVVyaScsXG4gICdwcm9ncmVzcycsXG4gICdyZXNvdXJjZUNvdW50JyxcbiAgJ3NhbXBsZU1vZGVscycsXG4gICdzZWxmUmVmbGVjdCcsXG4gICdzZXRDb25zb2xpZGF0ZWRNb2RlbHMnLFxuICAnc3BlYycsXG4gICdzdXBwb3J0ZWRTdWJtaXRNZXRob2RzJyxcbiAgJ3N3YWdnZXJSZXF1ZXN0SGVhZGVycycsXG4gICd0YWdGcm9tTGFiZWwnLFxuICAndGl0bGUnLFxuICAndXJsJyxcbiAgJ3VzZUpRdWVyeSdcbl07XG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC5hcGlzLnt0YWdOYW1lfSdcbnZhciByZXNlcnZlZEFwaVRhZ3MgPSBbXG4gICdhcGlzJyxcbiAgJ2FzQ3VybCcsXG4gICdkZXNjcmlwdGlvbicsXG4gICdleHRlcm5hbERvY3MnLFxuICAnaGVscCcsXG4gICdsYWJlbCcsXG4gICduYW1lJyxcbiAgJ29wZXJhdGlvbicsXG4gICdvcGVyYXRpb25zJyxcbiAgJ29wZXJhdGlvbnNBcnJheScsXG4gICdwYXRoJyxcbiAgJ3RhZydcbl07XG52YXIgc3VwcG9ydGVkT3BlcmF0aW9uTWV0aG9kcyA9IFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnLCAncGF0Y2gnLCAncG9zdCcsICdwdXQnXTtcbnZhciBTd2FnZ2VyQ2xpZW50ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBudWxsO1xuICB0aGlzLmF1dGhvcml6YXRpb25TY2hlbWUgPSBudWxsO1xuICB0aGlzLmJhc2VQYXRoID0gbnVsbDtcbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICB0aGlzLmVuYWJsZUNvb2tpZXMgPSBmYWxzZTtcbiAgdGhpcy5pbmZvID0gbnVsbDtcbiAgdGhpcy5pc0J1aWx0ID0gZmFsc2U7XG4gIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICB0aGlzLm1vZGVsc0FycmF5ID0gW107XG4gIHRoaXMucmVzb3VyY2VDb3VudCA9IDA7XG4gIHRoaXMudXJsID0gbnVsbDtcbiAgdGhpcy51c2VKUXVlcnkgPSBmYWxzZTtcbiAgdGhpcy5zd2FnZ2VyT2JqZWN0ID0ge307XG4gIHRoaXMuZGVmZXJyZWRDbGllbnQgPSB1bmRlZmluZWQ7XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IG5ldyBhdXRoLlN3YWdnZXJBdXRob3JpemF0aW9ucygpO1xuXG4gIGlmICh0eXBlb2YgdXJsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemUodXJsLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgdGhpcy5tb2RlbHMgPSB7fTtcbiAgdGhpcy5zYW1wbGVNb2RlbHMgPSB7fTtcblxuICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHVybCkpIHtcbiAgICBvcHRpb25zID0gdXJsO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hZGQob3B0aW9ucy5hdXRob3JpemF0aW9ucyk7XG4gIHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gb3B0aW9ucy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD11dGYtOCwqLyonO1xuICB0aGlzLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5kZWZhdWx0RXJyb3JDYWxsYmFjayA9IG9wdGlvbnMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgfHwgbnVsbDtcbiAgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8gPSBvcHRpb25zLm1vZGVsUHJvcGVydHlNYWNybyB8fCBudWxsO1xuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gb3B0aW9ucy5wYXJhbWV0ZXJNYWNybyB8fCBudWxsO1xuICB0aGlzLnVzZVByb21pc2UgPSBvcHRpb25zLnVzZVByb21pc2UgfHwgbnVsbDtcblxuXG4gIGlmKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQgPSBRLmRlZmVyKCk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9wdGlvbnMuc3VjY2VzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzcztcbiAgfVxuXG4gIGlmIChvcHRpb25zLnVzZUpRdWVyeSkge1xuICAgIHRoaXMudXNlSlF1ZXJ5ID0gb3B0aW9ucy51c2VKUXVlcnk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wcm9ncmVzcygnZmV0Y2hpbmcgcmVzb3VyY2UgbGlzdDogJyArIHRoaXMudXJsICsgJzsgUGxlYXNlIHdhaXQuJyk7XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIHVybDogdGhpcy51cmwsXG4gICAgbWV0aG9kOiAnZ2V0JyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBhY2NlcHQ6IHRoaXMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoc2VsZi51cmwuc3Vic3RyaW5nKDAsIDQpICE9PSAnaHR0cCcpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdQbGVhc2Ugc3BlY2lmeSB0aGUgcHJvdG9jb2wgZm9yICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIGZyb20gc2VydmVyLiAgSXQgbWF5IG5vdCBoYXZlIHRoZSBhcHByb3ByaWF0ZSBhY2Nlc3MtY29udHJvbC1vcmlnaW4gc2V0dGluZ3MuJyk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdDYW5cXCd0IHJlYWQgc3dhZ2dlciBKU09OIGZyb20gJyArIHNlbGYudXJsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKHJlc3BvbnNlLnN0YXR1cyArICcgOiAnICsgcmVzcG9uc2Uuc3RhdHVzVGV4dCArICcgJyArIHNlbGYudXJsKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHJlc3BvbnNlOiBmdW5jdGlvbiAocmVzcCkge1xuXG4gICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3Aub2JqO1xuICAgICAgICBpZighcmVzcG9uc2VPYmopIHtcbiAgICAgICAgICByZXR1cm4gc2VsZi5mYWlsKCdmYWlsZWQgdG8gcGFyc2UgSlNPTi9ZQU1MIHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLnN3YWdnZXJWZXJzaW9uID0gcmVzcG9uc2VPYmouc3dhZ2dlclZlcnNpb247XG4gICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHJlc3BvbnNlT2JqO1xuXG4gICAgICAgIGlmIChyZXNwb25zZU9iai5zd2FnZ2VyICYmIHBhcnNlSW50KHJlc3BvbnNlT2JqLnN3YWdnZXIpID09PSAyKSB7XG4gICAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXI7XG5cbiAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHJlc3BvbnNlT2JqLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcblxuICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGNvbnZlcnRlciA9IG5ldyBTd2FnZ2VyU3BlY0NvbnZlcnRlcigpO1xuICAgICAgICAgIHNlbGYub2xkU3dhZ2dlck9iamVjdCA9IHNlbGYuc3dhZ2dlck9iamVjdDtcblxuICAgICAgICAgIGNvbnZlcnRlci5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24oc2VsZi51cmwpO1xuICAgICAgICAgIGNvbnZlcnRlci5jb252ZXJ0KHJlc3BvbnNlT2JqLCBzZWxmLmNsaWVudEF1dGhvcml6YXRpb25zLCBzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uKHNwZWMpIHtcbiAgICAgICAgICAgIHNlbGYuc3dhZ2dlck9iamVjdCA9IHNwZWM7XG4gICAgICAgICAgICBuZXcgUmVzb2x2ZXIoKS5yZXNvbHZlKHNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgICAgICAgICAgc2VsZi5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBpZiAodGhpcy5zcGVjKSB7XG4gICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gdGhpcy5zcGVjO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgIH0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgICBpZiAobW9jaykge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgdGhpcy5vcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAodGhpcy51c2VQcm9taXNlKSA/IHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZSA6IHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZEZyb21TcGVjID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoaXMuYXBpcyA9IHt9O1xuICB0aGlzLmFwaXNBcnJheSA9IFtdO1xuICB0aGlzLmJhc2VQYXRoID0gcmVzcG9uc2UuYmFzZVBhdGggfHwgJyc7XG4gIHRoaXMuY29uc3VtZXMgPSByZXNwb25zZS5jb25zdW1lcztcbiAgdGhpcy5ob3N0ID0gcmVzcG9uc2UuaG9zdCB8fCAnJztcbiAgdGhpcy5pbmZvID0gcmVzcG9uc2UuaW5mbyB8fCB7fTtcbiAgdGhpcy5wcm9kdWNlcyA9IHJlc3BvbnNlLnByb2R1Y2VzO1xuICB0aGlzLnNjaGVtZXMgPSByZXNwb25zZS5zY2hlbWVzIHx8IFtdO1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSByZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zO1xuICB0aGlzLnNlY3VyaXR5ID0gcmVzcG9uc2Uuc2VjdXJpdHk7XG4gIHRoaXMudGl0bGUgPSByZXNwb25zZS50aXRsZSB8fCAnJztcblxuICBpZiAocmVzcG9uc2UuZXh0ZXJuYWxEb2NzKSB7XG4gICAgdGhpcy5leHRlcm5hbERvY3MgPSByZXNwb25zZS5leHRlcm5hbERvY3M7XG4gIH1cblxuICAvLyBsZWdhY3kgc3VwcG9ydFxuICB0aGlzLmF1dGhTY2hlbWVzID0gcmVzcG9uc2Uuc2VjdXJpdHlEZWZpbml0aW9ucztcblxuICB2YXIgZGVmaW5lZFRhZ3MgPSB7fTtcbiAgdmFyIGs7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gcmVzcG9uc2UudGFnc1trXTtcbiAgICAgIGRlZmluZWRUYWdzW3QubmFtZV0gPSB0O1xuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbjtcblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWUgfHwgJ2h0dHAnO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuc2NoZW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF0gfHwgbG9jYXRpb24uc2NoZW1lO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5ob3N0ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmhvc3QgPT09ICcnKSB7XG4gICAgICB0aGlzLmhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuXG4gICAgICBpZiAobG9jYXRpb24ucG9ydCkge1xuICAgICAgICB0aGlzLmhvc3QgPSB0aGlzLmhvc3QgKyAnOicgKyBsb2NhdGlvbi5wb3J0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVmaW5pdGlvbnMgPSByZXNwb25zZS5kZWZpbml0aW9ucztcblxuICB2YXIga2V5O1xuXG4gIGZvciAoa2V5IGluIHRoaXMuZGVmaW5pdGlvbnMpIHtcbiAgICB2YXIgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCB0aGlzLmRlZmluaXRpb25zW2tleV0sIHRoaXMubW9kZWxzLCB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIHRoaXMubW9kZWxzW2tleV0gPSBtb2RlbDtcbiAgICB9XG4gIH1cblxuICAvLyBnZXQgcGF0aHMsIGNyZWF0ZSBmdW5jdGlvbnMgZm9yIGVhY2ggb3BlcmF0aW9uSWRcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIEJpbmQgaGVscCB0byAnY2xpZW50LmFwaXMnXG4gIHNlbGYuYXBpcy5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgc2VsZik7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLnBhdGhzLCBmdW5jdGlvbiAocGF0aE9iaiwgcGF0aCkge1xuICAgIC8vIE9ubHkgcHJvY2VzcyBhIHBhdGggaWYgaXQncyBhbiBvYmplY3RcbiAgICBpZiAoIV8uaXNQbGFpbk9iamVjdChwYXRoT2JqKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIF8uZm9yRWFjaChzdXBwb3J0ZWRPcGVyYXRpb25NZXRob2RzLCBmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gcGF0aE9ialttZXRob2RdO1xuXG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBkb2VzIG5vdCBleGlzdFxuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2UgaWYgKCFfLmlzUGxhaW5PYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAvLyBPcGVyYXRpb24gZXhpc3RzIGJ1dCBpdCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdC4gIFNpbmNlIHRoaXMgaXMgaW52YWxpZCwgbG9nIGl0LlxuICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyBtZXRob2QgKyAnXFwnIG9wZXJhdGlvbiBmb3IgXFwnJyArIHBhdGggKyAnXFwnIHBhdGggaXMgbm90IGFuIE9wZXJhdGlvbiBPYmplY3QnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YWdzID0gb3BlcmF0aW9uLnRhZ3M7XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHRhZ3MpIHx8ICFfLmlzQXJyYXkodGFncykgfHwgdGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGFncyA9IG9wZXJhdGlvbi50YWdzID0gWyAnZGVmYXVsdCcgXTtcbiAgICAgIH1cblxuICAgICAgdmFyIG9wZXJhdGlvbklkID0gc2VsZi5pZEZyb21PcChwYXRoLCBtZXRob2QsIG9wZXJhdGlvbik7XG5cbiAgICAgIHZhciBvcGVyYXRpb25PYmplY3QgPSBuZXcgT3BlcmF0aW9uKHNlbGYsXG4gICAgICAgIG9wZXJhdGlvbi5zY2hlbWUsXG4gICAgICAgIG9wZXJhdGlvbklkLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgc2VsZi5kZWZpbml0aW9ucyxcbiAgICAgICAgc2VsZi5tb2RlbHMsXG4gICAgICAgIHNlbGYuY2xpZW50QXV0aG9yaXphdGlvbnMpO1xuXG4gICAgICAvLyBiaW5kIHNlbGYgb3BlcmF0aW9uJ3MgZXhlY3V0ZSBjb21tYW5kIHRvIHRoZSBhcGlcbiAgICAgIF8uZm9yRWFjaCh0YWdzLCBmdW5jdGlvbiAodGFnKSB7XG4gICAgICAgIHZhciBjbGllbnRQcm9wZXJ0eSA9IF8uaW5kZXhPZihyZXNlcnZlZENsaWVudFRhZ3MsIHRhZykgPiAtMSA/ICdfJyArIHRhZyA6IHRhZztcbiAgICAgICAgdmFyIGFwaVByb3BlcnR5ID0gXy5pbmRleE9mKHJlc2VydmVkQXBpVGFncywgdGFnKSA+IC0xID8gJ18nICsgdGFnIDogdGFnO1xuICAgICAgICB2YXIgb3BlcmF0aW9uR3JvdXAgPSBzZWxmW2NsaWVudFByb3BlcnR5XTtcblxuICAgICAgICBpZiAoY2xpZW50UHJvcGVydHkgIT09IHRhZykge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIHRhZyArICdcXCcgdGFnIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlIFxcJ2NsaWVudC4nICtcbiAgICAgICAgICAgICAgICAgICAgICBjbGllbnRQcm9wZXJ0eSArICdcXCcgb3IgXFwnY2xpZW50LmFwaXMuJyArIHRhZyArICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuJyArIHRhZyArICdcXCcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYXBpUHJvcGVydHkgIT09IHRhZykge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIHRhZyArICdcXCcgdGFnIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBvcGVyYXRpb24gZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC5hcGlzLicgKyB0YWcgKyAnXFwnLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF8uaW5kZXhPZihyZXNlcnZlZEFwaVRhZ3MsIG9wZXJhdGlvbklkKSA+IC0xKSB7XG4gICAgICAgICAgaGVscGVycy5sb2coJ1RoZSBcXCcnICsgb3BlcmF0aW9uSWQgKyAnXFwnIG9wZXJhdGlvbklkIGNvbmZsaWN0cyB3aXRoIGEgU3dhZ2dlckNsaWVudCBvcGVyYXRpb24gJyArXG4gICAgICAgICAgICAgICAgICAgICAgJ2Z1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJy5fJyArIG9wZXJhdGlvbklkICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LmFwaXMuJyArIGFwaVByb3BlcnR5ICsgJy4nICsgb3BlcmF0aW9uSWQgKyAnXFwnLicpO1xuXG4gICAgICAgICAgb3BlcmF0aW9uSWQgPSAnXycgKyBvcGVyYXRpb25JZDtcbiAgICAgICAgICBvcGVyYXRpb25PYmplY3Qubmlja25hbWUgPSBvcGVyYXRpb25JZDsgLy8gU28gJ2NsaWVudC5hcGlzLlt0YWddLm9wZXJhdGlvbklkLmhlbHAoKSB3b3JrcyBwcm9wZXJseVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQob3BlcmF0aW9uR3JvdXApKSB7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAgPSBzZWxmW2NsaWVudFByb3BlcnR5XSA9IHNlbGYuYXBpc1thcGlQcm9wZXJ0eV0gPSB7fTtcblxuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLm9wZXJhdGlvbnMgPSB7fTtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5sYWJlbCA9IGFwaVByb3BlcnR5O1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmFwaXMgPSB7fTtcblxuICAgICAgICAgIHZhciB0YWdEZWYgPSBkZWZpbmVkVGFnc1t0YWddO1xuXG4gICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHRhZ0RlZikpIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmRlc2NyaXB0aW9uID0gdGFnRGVmLmRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgb3BlcmF0aW9uR3JvdXAuZXh0ZXJuYWxEb2NzID0gdGFnRGVmLmV4dGVybmFsRG9jcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzZWxmW2NsaWVudFByb3BlcnR5XS5oZWxwID0gXy5iaW5kKHNlbGYuaGVscCwgb3BlcmF0aW9uR3JvdXApO1xuICAgICAgICAgIHNlbGYuYXBpc0FycmF5LnB1c2gobmV3IE9wZXJhdGlvbkdyb3VwKHRhZywgb3BlcmF0aW9uR3JvdXAuZGVzY3JpcHRpb24sIG9wZXJhdGlvbkdyb3VwLmV4dGVybmFsRG9jcywgb3BlcmF0aW9uT2JqZWN0KSk7XG4gICAgICAgIH1cblxuICAgICAgICBvcGVyYXRpb25JZCA9IHNlbGYubWFrZVVuaXF1ZU9wZXJhdGlvbklkKG9wZXJhdGlvbklkLCBzZWxmLmFwaXNbYXBpUHJvcGVydHldKTtcblxuICAgICAgICAvLyBCaW5kIHRhZyBoZWxwXG4gICAgICAgIGlmICghXy5pc0Z1bmN0aW9uKG9wZXJhdGlvbkdyb3VwLmhlbHApKSB7XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAuaGVscCA9IF8uYmluZChzZWxmLmhlbHAsIG9wZXJhdGlvbkdyb3VwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGJpbmQgdG8gdGhlIGFwaXMgb2JqZWN0XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5leGVjdXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdLmhlbHAgPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0uaGVscCA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuaGVscCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIHNlbGYuYXBpc1thcGlQcm9wZXJ0eV1bb3BlcmF0aW9uSWRdLmFzQ3VybCA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXS5hc0N1cmwgPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmFzQ3VybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuXG4gICAgICAgIG9wZXJhdGlvbkdyb3VwLmFwaXNbb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uR3JvdXAub3BlcmF0aW9uc1tvcGVyYXRpb25JZF0gPSBvcGVyYXRpb25PYmplY3Q7XG5cbiAgICAgICAgLy8gbGVnYWN5IFVJIGZlYXR1cmVcbiAgICAgICAgdmFyIGFwaSA9IF8uZmluZChzZWxmLmFwaXNBcnJheSwgZnVuY3Rpb24gKGFwaSkge1xuICAgICAgICAgIHJldHVybiBhcGkudGFnID09PSB0YWc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChhcGkpIHtcbiAgICAgICAgICBhcGkub3BlcmF0aW9uc0FycmF5LnB1c2gob3BlcmF0aW9uT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIHNvcnQgdGhlIGFwaXNBcnJheSBhY2NvcmRpbmcgdG8gdGhlIHRhZ3NcbiAgdmFyIHNvcnRlZEFwaXMgPSBbXTtcbiAgXy5mb3JFYWNoKE9iamVjdC5rZXlzKGRlZmluZWRUYWdzKSwgZnVuY3Rpb24gKHRhZykge1xuICAgIHZhciBfYXBpVG9BZGQ7XG4gICAgdmFyIHBvcztcbiAgICBmb3IocG9zIGluIHNlbGYuYXBpc0FycmF5KSB7XG4gICAgICB2YXIgX2FwaSA9IHNlbGYuYXBpc0FycmF5W3Bvc107XG4gICAgICBpZihfYXBpICYmIHRhZyA9PT0gX2FwaS5uYW1lKSB7XG4gICAgICAgIHNvcnRlZEFwaXMucHVzaChfYXBpKTtcbiAgICAgICAgc2VsZi5hcGlzQXJyYXlbcG9zXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gYWRkIGFueXRoaW5nIGxlZnRcbiAgXy5mb3JFYWNoKHNlbGYuYXBpc0FycmF5LCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgaWYoYXBpKSB7XG4gICAgICBzb3J0ZWRBcGlzLnB1c2goYXBpKTtcbiAgICB9XG4gIH0pO1xuICBzZWxmLmFwaXNBcnJheSA9IHNvcnRlZEFwaXM7XG5cbiAgXy5mb3JFYWNoKHJlc3BvbnNlLmRlZmluaXRpb25zLCBmdW5jdGlvbiAoZGVmaW5pdGlvbk9iaiwgZGVmaW5pdGlvbikge1xuICAgIGRlZmluaXRpb25PYmpbJ2lkJ10gPSBkZWZpbml0aW9uLnRvTG93ZXJDYXNlKCk7XG4gICAgZGVmaW5pdGlvbk9ialsnbmFtZSddID0gZGVmaW5pdGlvbjtcbiAgICBzZWxmLm1vZGVsc0FycmF5LnB1c2goZGVmaW5pdGlvbk9iaik7XG4gIH0pO1xuXG4gIHRoaXMuaXNCdWlsdCA9IHRydWU7XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50LnJlc29sdmUodGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZlcnJlZENsaWVudC5wcm9taXNlO1xuICB9XG5cbiAgaWYgKHRoaXMuc3VjY2Vzcykge1xuICAgIHRoaXMuc3VjY2VzcygpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5tYWtlVW5pcXVlT3BlcmF0aW9uSWQgPSBmdW5jdGlvbihvcGVyYXRpb25JZCwgYXBpKSB7XG4gIHZhciBjb3VudCA9IDA7XG4gIHZhciBuYW1lID0gb3BlcmF0aW9uSWQ7XG5cbiAgLy8gbWFrZSB1bmlxdWUgYWNyb3NzIHRoaXMgb3BlcmF0aW9uIGdyb3VwXG4gIHdoaWxlKHRydWUpIHtcbiAgICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgaWYob3BlcmF0aW9uLm5pY2tuYW1lID09PSBuYW1lKSB7XG4gICAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmKCFtYXRjaGVkKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IG9wZXJhdGlvbklkICsgJ18nICsgY291bnQ7XG4gICAgY291bnQgKys7XG4gIH1cblxuICByZXR1cm4gb3BlcmF0aW9uSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5wYXJzZVVyaSA9IGZ1bmN0aW9uICh1cmkpIHtcbiAgdmFyIHVybFBhcnNlUkUgPSAvXigoKChbXjpcXC8jXFw/XSs6KT8oPzooXFwvXFwvKSgoPzooKFteOkBcXC8jXFw/XSspKD86XFw6KFteOkBcXC8jXFw/XSspKT8pQCk/KChbXjpcXC8jXFw/XFxdXFxbXSt8XFxbW15cXC9cXF1AIz9dK1xcXSkoPzpcXDooWzAtOV0rKSk/KSk/KT8pPygoXFwvPyg/OlteXFwvXFw/I10rXFwvKykqKShbXlxcPyNdKikpKT8oXFw/W14jXSspPykoIy4qKT8vO1xuICB2YXIgcGFydHMgPSB1cmxQYXJzZVJFLmV4ZWModXJpKTtcblxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogcGFydHNbNF0gPyBwYXJ0c1s0XS5yZXBsYWNlKCc6JywnJykgOiB1bmRlZmluZWQsXG4gICAgaG9zdDogcGFydHNbMTFdLFxuICAgIHBvcnQ6IHBhcnRzWzEyXSxcbiAgICBwYXRoOiBwYXJ0c1sxNV1cbiAgfTtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXRwdXQgPSAnJztcblxuICBpZiAodGhpcyBpbnN0YW5jZW9mIFN3YWdnZXJDbGllbnQpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpLCBuYW1lKSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGFwaSkpIHtcbiAgICAgICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIG5hbWUgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodGhpcyBpbnN0YW5jZW9mIE9wZXJhdGlvbkdyb3VwIHx8IF8uaXNQbGFpbk9iamVjdCh0aGlzKSkge1xuICAgIG91dHB1dCArPSAnb3BlcmF0aW9ucyBmb3IgdGhlIFxcJycgKyB0aGlzLmxhYmVsICsgJ1xcJyB0YWdcXG4nO1xuXG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24gKG9wZXJhdGlvbiwgbmFtZSkge1xuICAgICAgb3V0cHV0ICs9ICcgICogJyArIG5hbWUgKyAnOiAnICsgb3BlcmF0aW9uLnN1bW1hcnkgKyAnXFxuJztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkb250UHJpbnQpIHtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIGhlbHBlcnMubG9nKG91dHB1dCk7XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS50YWdGcm9tTGFiZWwgPSBmdW5jdGlvbiAobGFiZWwpIHtcbiAgcmV0dXJuIGxhYmVsO1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaWRGcm9tT3AgPSBmdW5jdGlvbiAocGF0aCwgaHR0cE1ldGhvZCwgb3ApIHtcbiAgaWYoIW9wIHx8ICFvcC5vcGVyYXRpb25JZCkge1xuICAgIG9wID0gb3AgfHwge307XG4gICAgb3Aub3BlcmF0aW9uSWQgPSBodHRwTWV0aG9kICsgJ18nICsgcGF0aDtcbiAgfVxuICB2YXIgb3BJZCA9IG9wLm9wZXJhdGlvbklkLnJlcGxhY2UoL1tcXHMhQCMkJV4mKigpXys9XFxbe1xcXX07Ojw+fC5cXC8/LFxcXFwnXCJcIi1dL2csICdfJykgfHwgKHBhdGguc3Vic3RyaW5nKDEpICsgJ18nICsgaHR0cE1ldGhvZCk7XG5cbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKChfKXsyLH0pL2csICdfJyk7XG4gIG9wSWQgPSBvcElkLnJlcGxhY2UoL14oXykqL2csICcnKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvKFtfXSkqJC9nLCAnJyk7XG5cbiAgcmV0dXJuIG9wSWQ7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRIb3N0ID0gZnVuY3Rpb24gKGhvc3QpIHtcbiAgdGhpcy5ob3N0ID0gaG9zdDtcblxuICBpZih0aGlzLmFwaXMpIHtcbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbihhcGkpIHtcbiAgICAgIGlmKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24ob3BlcmF0aW9uKSB7XG4gICAgICAgICAgb3BlcmF0aW9uLmhvc3QgPSBob3N0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0QmFzZVBhdGggPSBmdW5jdGlvbiAoYmFzZVBhdGgpIHtcbiAgdGhpcy5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uYmFzZVBhdGggPSBiYXNlUGF0aDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldFNjaGVtZXMgPSBmdW5jdGlvbiAoc2NoZW1lcykge1xuICB0aGlzLnNjaGVtZXMgPSBzY2hlbWVzO1xuXG4gIGlmKHNjaGVtZXMgJiYgc2NoZW1lcy5sZW5ndGggPiAwKSB7XG4gICAgaWYodGhpcy5hcGlzKSB7XG4gICAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIGlmIChhcGkub3BlcmF0aW9ucykge1xuICAgICAgICAgIF8uZm9yRWFjaChhcGkub3BlcmF0aW9ucywgZnVuY3Rpb24gKG9wZXJhdGlvbikge1xuICAgICAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSA9IHNjaGVtZXNbMF07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufTtcblxuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVqZWN0KG1lc3NhZ2UpO1xuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuZmFpbHVyZSkge1xuICAgICAgdGhpcy5mYWlsdXJlKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn07XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgcmV0dXJuICc8dHI+PHRkIGNsYXNzPVwib3B0aW9uTmFtZVwiPicgKyBsYWJlbCArICc6PC90ZD48dGQ+JyArIHZhbHVlICsgJzwvdGQ+PC90cj4nO1xufTtcblxudmFyIHJlc29sdmVTY2hlbWEgPSBtb2R1bGUuZXhwb3J0cy5yZXNvbHZlU2NoZW1hID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEuc2NoZW1hKTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG52YXIgc2ltcGxlUmVmID0gbW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b1pXeHdaWEp6TG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpSjNWelpTQnpkSEpwWTNRbk8xeHVYRzUyWVhJZ1h5QTlJSHRjYmlBZ2FYTlFiR0ZwYms5aWFtVmpkRG9nY21WeGRXbHlaU2duYkc5a1lYTm9MV052YlhCaGRDOXNZVzVuTDJselVHeGhhVzVQWW1wbFkzUW5LU3hjYmlBZ2FXNWtaWGhQWmpvZ2NtVnhkV2x5WlNnbmJHOWtZWE5vTFdOdmJYQmhkQzloY25KaGVTOXBibVJsZUU5bUp5bGNibjA3WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6TGw5ZlltbHVaQ0E5SUdaMWJtTjBhVzl1SUNobWJpd2diV1VwSUh0Y2JpQWdjbVYwZFhKdUlHWjFibU4wYVc5dUtDbDdYRzRnSUNBZ2NtVjBkWEp1SUdadUxtRndjR3g1S0cxbExDQmhjbWQxYldWdWRITXBPMXh1SUNCOU8xeHVmVHRjYmx4dWRtRnlJR3h2WnlBOUlHMXZaSFZzWlM1bGVIQnZjblJ6TG14dlp5QTlJR1oxYm1OMGFXOXVLQ2tnZTF4dUlDQXZMeUJQYm14NUlHeHZaeUJwWmlCaGRtRnBiR0ZpYkdVZ1lXNWtJSGRsSjNKbElHNXZkQ0IwWlhOMGFXNW5YRzRnSUdsbUlDaGpiMjV6YjJ4bElDWW1JSEJ5YjJObGMzTXVaVzUyTGs1UFJFVmZSVTVXSUNFOVBTQW5kR1Z6ZENjcElIdGNiaUFnSUNCamIyNXpiMnhsTG14dlp5aEJjbkpoZVM1d2NtOTBiM1I1Y0dVdWMyeHBZMlV1WTJGc2JDaGhjbWQxYldWdWRITXBXekJkS1R0Y2JpQWdmVnh1ZlR0Y2JseHViVzlrZFd4bExtVjRjRzl5ZEhNdVptRnBiQ0E5SUdaMWJtTjBhVzl1SUNodFpYTnpZV2RsS1NCN1hHNGdJR3h2WnlodFpYTnpZV2RsS1R0Y2JuMDdYRzVjYm5aaGNpQnZjSFJwYjI1SWRHMXNJRDBnYlc5a2RXeGxMbVY0Y0c5eWRITXViM0IwYVc5dVNIUnRiQ0E5SUdaMWJtTjBhVzl1SUNoc1lXSmxiQ3dnZG1Gc2RXVXBJSHRjYmlBZ2NtVjBkWEp1SUNjOGRISStQSFJrSUdOc1lYTnpQVndpYjNCMGFXOXVUbUZ0WlZ3aVBpY2dLeUJzWVdKbGJDQXJJQ2M2UEM5MFpENDhkR1ErSnlBcklIWmhiSFZsSUNzZ0p6d3ZkR1ErUEM5MGNqNG5PMXh1ZlR0Y2JseHVkbUZ5SUhKbGMyOXNkbVZUWTJobGJXRWdQU0J0YjJSMWJHVXVaWGh3YjNKMGN5NXlaWE52YkhabFUyTm9aVzFoSUQwZ1puVnVZM1JwYjI0Z0tITmphR1Z0WVNrZ2UxeHVJQ0JwWmlBb1h5NXBjMUJzWVdsdVQySnFaV04wS0hOamFHVnRZUzV6WTJobGJXRXBLU0I3WEc0Z0lDQWdjMk5vWlcxaElEMGdjbVZ6YjJ4MlpWTmphR1Z0WVNoelkyaGxiV0V1YzJOb1pXMWhLVHRjYmlBZ2ZWeHVYRzRnSUhKbGRIVnliaUJ6WTJobGJXRTdYRzU5TzF4dVhHNTJZWElnYzJsdGNHeGxVbVZtSUQwZ2JXOWtkV3hsTG1WNGNHOXlkSE11YzJsdGNHeGxVbVZtSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VwSUh0Y2JpQWdhV1lnS0hSNWNHVnZaaUJ1WVcxbElEMDlQU0FuZFc1a1pXWnBibVZrSnlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1ZFd4c08xeHVJQ0I5WEc1Y2JpQWdhV1lnS0c1aGJXVXVhVzVrWlhoUFppZ25JeTlrWldacGJtbDBhVzl1Y3k4bktTQTlQVDBnTUNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ1WVcxbExuTjFZbk4wY21sdVp5Z25JeTlrWldacGJtbDBhVzl1Y3k4bkxteGxibWQwYUNrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ2NtVjBkWEp1SUc1aGJXVTdYRzRnSUgxY2JuMDdYRzVjYmlKZGZRPT0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG52YXIgcmVxdWVzdCA9IHJlcXVpcmUoJ3N1cGVyYWdlbnQnKTtcbnZhciBqc3lhbWwgPSByZXF1aXJlKCdqcy15YW1sJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xuXG4vKlxuICogSlF1ZXJ5SHR0cENsaWVudCBpcyBhIGxpZ2h0LXdlaWdodCwgbm9kZSBvciBicm93c2VyIEhUVFAgY2xpZW50XG4gKi9cbnZhciBKUXVlcnlIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnSlF1ZXJ5SHR0cENsaWVudCc7XG59O1xuXG4vKlxuICogU3VwZXJhZ2VudEh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgU3VwZXJhZ2VudEh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudHlwZSA9ICdTdXBlcmFnZW50SHR0cENsaWVudCc7XG59O1xuXG4vKipcbiAqIFN3YWdnZXJIdHRwIGlzIGEgd3JhcHBlciBmb3IgZXhlY3V0aW5nIHJlcXVlc3RzXG4gKi9cbnZhciBTd2FnZ2VySHR0cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge307XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaiwgb3B0cykge1xuICB2YXIgY2xpZW50O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5jbGllbnQpIHtcbiAgICBjbGllbnQgPSBvcHRzLmNsaWVudDtcbiAgfVxuICBlbHNlIHtcbiAgICBjbGllbnQgPSBuZXcgU3VwZXJhZ2VudEh0dHBDbGllbnQob3B0cyk7XG4gIH1cbiAgY2xpZW50Lm9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHZhciBoYXNKUXVlcnkgPSBmYWxzZTtcbiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZih0eXBlb2Ygd2luZG93LmpRdWVyeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGhhc0pRdWVyeSA9IHRydWU7XG4gICAgfVxuICB9XG4gIC8vIE9QVElPTlMgc3VwcG9ydFxuICBpZihvYmoubWV0aG9kLnRvTG93ZXJDYXNlKCkgPT09ICdvcHRpb25zJyAmJiBjbGllbnQudHlwZSA9PT0gJ1N1cGVyYWdlbnRIdHRwQ2xpZW50Jykge1xuICAgIGxvZygnZm9yY2luZyBqUXVlcnkgYXMgT1BUSU9OUyBhcmUgbm90IHN1cHBvcnRlZCBieSBTdXBlckFnZW50Jyk7XG4gICAgb2JqLnVzZUpRdWVyeSA9IHRydWU7XG4gIH1cbiAgaWYodGhpcy5pc0ludGVybmV0RXhwbG9yZXIoKSAmJiAob2JqLnVzZUpRdWVyeSA9PT0gZmFsc2UgfHwgIWhhc0pRdWVyeSApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuICBpZiAoKG9iaiAmJiBvYmoudXNlSlF1ZXJ5ID09PSB0cnVlKSB8fCB0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIGhhc0pRdWVyeSkge1xuICAgIGNsaWVudCA9IG5ldyBKUXVlcnlIdHRwQ2xpZW50KG9wdHMpO1xuICB9XG5cbiAgdmFyIHN1Y2Nlc3MgPSBvYmoub24ucmVzcG9uc2U7XG5cbiAgdmFyIHJlcXVlc3RJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVxdWVzdEludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IuYXBwbHkoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9O1xuXG4gIHZhciByZXNwb25zZUludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gc3VjY2VzcyhkYXRhKTtcbiAgfTtcblxuICBvYmoub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgcmVzcG9uc2VJbnRlcmNlcHRvcihkYXRhKTtcbiAgfTtcblxuICBpZiAoXy5pc09iamVjdChvYmopICYmIF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgLy8gc3BlY2lhbCBwcm9jZXNzaW5nIGZvciBmaWxlIHVwbG9hZHMgdmlhIGpxdWVyeVxuICAgIGlmIChvYmouYm9keS50eXBlICYmIG9iai5ib2R5LnR5cGUgPT09ICdmb3JtRGF0YScpe1xuICAgICAgb2JqLmNvbnRlbnRUeXBlID0gZmFsc2U7XG4gICAgICBvYmoucHJvY2Vzc0RhdGEgPSBmYWxzZTtcblxuICAgICAgZGVsZXRlIG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JqLmJvZHkgPSBKU09OLnN0cmluZ2lmeShvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgb2JqID0gcmVxdWVzdEludGVyY2VwdG9yKG9iaikgfHwgb2JqO1xuICBpZiAob2JqLmJlZm9yZVNlbmQpIHtcbiAgICBvYmouYmVmb3JlU2VuZChmdW5jdGlvbihfb2JqKSB7XG4gICAgICBjbGllbnQuZXhlY3V0ZShfb2JqIHx8IG9iaik7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50LmV4ZWN1dGUob2JqKTtcbiAgfVxuXG4gIHJldHVybiAob2JqLmRlZmVycmVkKSA/IG9iai5kZWZlcnJlZC5wcm9taXNlIDogb2JqO1xufTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmlzSW50ZXJuZXRFeHBsb3JlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRldGVjdGVkSUUgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIHZhciBuYXYgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobmF2LmluZGV4T2YoJ21zaWUnKSAhPT0gLTEpIHtcbiAgICAgIHZhciB2ZXJzaW9uID0gcGFyc2VJbnQobmF2LnNwbGl0KCdtc2llJylbMV0pO1xuXG4gICAgICBpZiAodmVyc2lvbiA8PSA4KSB7XG4gICAgICAgIGRldGVjdGVkSUUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZElFO1xufTtcblxuSlF1ZXJ5SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGpxID0gdGhpcy5qUXVlcnkgfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5qUXVlcnkpO1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIGlmKHR5cGVvZiBqcSA9PT0gJ3VuZGVmaW5lZCcgfHwganEgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gZmFsc2U7XG4gIG9iai5kYXRhID0gb2JqLmJvZHk7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpxLnN1cHBvcnQuY29ycyA9IHRydWU7XG5cbiAgcmV0dXJuIGpxLmFqYXgob2JqKTtcbn07XG5cblN1cGVyYWdlbnRIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgbWV0aG9kID0gb2JqLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChtZXRob2QgPT09ICdkZWxldGUnKSB7XG4gICAgbWV0aG9kID0gJ2RlbCc7XG4gIH1cbiAgdmFyIGhlYWRlcnMgPSBvYmouaGVhZGVycyB8fCB7fTtcbiAgdmFyIHIgPSByZXF1ZXN0W21ldGhvZF0ob2JqLnVybCk7XG4gIHZhciBuYW1lO1xuICBmb3IgKG5hbWUgaW4gaGVhZGVycykge1xuICAgIHIuc2V0KG5hbWUsIGhlYWRlcnNbbmFtZV0pO1xuICB9XG5cbiAgaWYgKG9iai5lbmFibGVDb29raWVzKSB7XG4gICAgci53aXRoQ3JlZGVudGlhbHMoKTtcbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHIuc2VuZChvYmouYm9keSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYocmVzLmhlYWRlcnMgJiYgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddKSB7XG4gICAgICAgIGlmKHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPj0gMCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBKU09OLnBhcnNlKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVzcG9uc2Uub2JqID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNiID0gb2JqLm9uLmVycm9yO1xuICAgIH0gZWxzZSBpZiAocmVzICYmIG9iai5vbiAmJiBvYmoub24ucmVzcG9uc2UpIHtcbiAgICAgIHZhciBwb3NzaWJsZU9iajtcblxuICAgICAgLy8gQWxyZWFkeSBwYXJzZWQgYnkgYnkgc3VwZXJhZ2VudD9cbiAgICAgIGlmKHJlcy5ib2R5ICYmIE9iamVjdC5rZXlzKHJlcy5ib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHBvc3NpYmxlT2JqID0gcmVzLmJvZHk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgICAvLyBjYW4gcGFyc2UgaW50byBhIHN0cmluZy4uLiB3aGljaCB3ZSBkb24ndCBuZWVkIHJ1bm5pbmcgYXJvdW5kIGluIHRoZSBzeXN0ZW1cbiAgICAgICAgICAgIHBvc3NpYmxlT2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ3N0cmluZycpID8gbnVsbCA6IHBvc3NpYmxlT2JqO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaGVscGVycy5sb2coJ2Nhbm5vdCBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgcmVzcG9uc2Uub2JqID0gKHR5cGVvZiBwb3NzaWJsZU9iaiA9PT0gJ29iamVjdCcpID8gcG9zc2libGVPYmogOiBudWxsO1xuXG4gICAgICByZXNwb25zZS5zdGF0dXMgPSByZXMuc3RhdHVzO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCA9IHJlcy50ZXh0O1xuICAgICAgY2IgPSBvYmoub24ucmVzcG9uc2U7XG4gICAgfVxuICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuXG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihyZXNwb25zZSk7XG4gICAgfVxuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5Jylcbn07XG5cblxuLyoqXG4gKiBSZXNvbHZlcyBhIHNwZWMncyByZW1vdGUgcmVmZXJlbmNlc1xuICovXG52YXIgUmVzb2x2ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mYWlsZWRVcmxzID0gW107XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucHJvY2Vzc0FsbE9mID0gZnVuY3Rpb24ocm9vdCwgbmFtZSwgZGVmaW5pdGlvbiwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYykge1xuICB2YXIgaSwgbG9jYXRpb24sIHByb3BlcnR5O1xuXG4gIGRlZmluaXRpb25bJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyAnIy9kZWZpbml0aW9ucy8nICsgbmFtZSBdO1xuICB2YXIgYWxsT2YgPSBkZWZpbml0aW9uLmFsbE9mO1xuICAvLyB0aGUgcmVmcyBnbyBmaXJzdFxuICBhbGxPZi5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICBpZihhLiRyZWYgJiYgYi4kcmVmKSB7IHJldHVybiAwOyB9XG4gICAgZWxzZSBpZihhLiRyZWYpIHsgcmV0dXJuIC0xOyB9XG4gICAgZWxzZSB7IHJldHVybiAxOyB9XG4gIH0pO1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsT2YubGVuZ3RoOyBpKyspIHtcbiAgICBwcm9wZXJ0eSA9IGFsbE9mW2ldO1xuICAgIGxvY2F0aW9uID0gJy9kZWZpbml0aW9ucy8nICsgbmFtZSArICcvYWxsT2YnO1xuICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uIChzcGVjLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIHRoaXMuc3BlYyA9IHNwZWM7XG4gIHZhciByb290ID0gYXJnMSwgY2FsbGJhY2sgPSBhcmcyLCBzY29wZSA9IGFyZzMsIG9wdHMgPSB7fSwgbG9jYXRpb24sIGk7XG4gIGlmKHR5cGVvZiBhcmcxID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcm9vdCA9IG51bGw7XG4gICAgY2FsbGJhY2sgPSBhcmcxO1xuICAgIHNjb3BlID0gYXJnMjtcbiAgfVxuICB2YXIgX3Jvb3QgPSByb290O1xuICB0aGlzLnNjb3BlID0gKHNjb3BlIHx8IHRoaXMpO1xuICB0aGlzLml0ZXJhdGlvbiA9IHRoaXMuaXRlcmF0aW9uIHx8IDA7XG5cbiAgaWYodGhpcy5zY29wZS5vcHRpb25zICYmIHRoaXMuc2NvcGUub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIG9wdHMucmVxdWVzdEludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlcXVlc3RJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmKHRoaXMuc2NvcGUub3B0aW9ucyAmJiB0aGlzLnNjb3BlLm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvcil7XG4gICAgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yID0gdGhpcy5zY29wZS5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgbmFtZSwgcGF0aCwgcHJvcGVydHksIHByb3BlcnR5TmFtZTtcbiAgdmFyIHByb2Nlc3NlZENhbGxzID0gMCwgcmVzb2x2ZWRSZWZzID0ge30sIHVucmVzb2x2ZWRSZWZzID0ge307XG4gIHZhciByZXNvbHV0aW9uVGFibGUgPSBbXTsgLy8gc3RvcmUgb2JqZWN0cyBmb3IgZGVyZWZlcmVuY2luZ1xuXG4gIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAvLyBkZWZpbml0aW9uc1xuICBmb3IgKG5hbWUgaW4gc3BlYy5kZWZpbml0aW9ucykge1xuICAgIHZhciBkZWZpbml0aW9uID0gc3BlYy5kZWZpbml0aW9uc1tuYW1lXTtcbiAgICBpZihkZWZpbml0aW9uWyckcmVmJ10pIHtcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBkZWZpbml0aW9uKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBmb3IgKHByb3BlcnR5TmFtZSBpbiBkZWZpbml0aW9uLnByb3BlcnRpZXMpIHtcbiAgICAgICAgcHJvcGVydHkgPSBkZWZpbml0aW9uLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgaWYgKF8uaXNBcnJheShwcm9wZXJ0eS5hbGxPZikpIHtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgJy9kZWZpbml0aW9ucycpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWZpbml0aW9uLmFsbE9mKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNoYXJlZCBwYXJhbWV0ZXJzXG4gIHNwZWMucGFyYW1ldGVycyA9IHNwZWMucGFyYW1ldGVycyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gc3BlYy5wYXJhbWV0ZXJzKSB7XG4gICAgdmFyIHBhcmFtZXRlciA9IHNwZWMucGFyYW1ldGVyc1tuYW1lXTtcbiAgICBpZiAocGFyYW1ldGVyLmluID09PSAnYm9keScgJiYgcGFyYW1ldGVyLnNjaGVtYSkge1xuICAgICAgaWYoXy5pc0FycmF5KHBhcmFtZXRlci5zY2hlbWEuYWxsT2YpKSB7XG4gICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgIHZhciBtb2RlbE5hbWUgPSAnaW5saW5lX21vZGVsJztcbiAgICAgICAgdmFyIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgIHZhciBkb25lID0gZmFsc2U7IHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgd2hpbGUoIWRvbmUpIHtcbiAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgIGNvdW50ZXIgKys7XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHsgYWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2YgfTtcbiAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBzcGVjLmRlZmluaXRpb25zW25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICB9XG4gIH1cblxuICAvLyBvcGVyYXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLnBhdGhzKSB7XG4gICAgdmFyIG1ldGhvZCwgb3BlcmF0aW9uLCByZXNwb25zZUNvZGU7XG4gICAgcGF0aCA9IHNwZWMucGF0aHNbbmFtZV07XG5cbiAgICBmb3IgKG1ldGhvZCBpbiBwYXRoKSB7XG4gICAgICAvLyBvcGVyYXRpb24gcmVmZXJlbmNlXG4gICAgICBpZihtZXRob2QgPT09ICckcmVmJykge1xuICAgICAgICAvLyBsb2NhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWU7XG4gICAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXRoLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgb3BlcmF0aW9uID0gcGF0aFttZXRob2RdO1xuICAgICAgICB2YXIgc2hhcmVkUGFyYW1ldGVycyA9IHBhdGgucGFyYW1ldGVycyB8fCBbXTtcbiAgICAgICAgdmFyIHBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcblxuICAgICAgICBmb3IgKGkgaW4gc2hhcmVkUGFyYW1ldGVycykge1xuICAgICAgICAgIHZhciBwYXJhbWV0ZXIgPSBzaGFyZWRQYXJhbWV0ZXJzW2ldO1xuICAgICAgICAgIHBhcmFtZXRlcnMudW5zaGlmdChwYXJhbWV0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmKG1ldGhvZCAhPT0gJ3BhcmFtZXRlcnMnICYmIF8uaXNPYmplY3Qob3BlcmF0aW9uKSkge1xuICAgICAgICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzID0gb3BlcmF0aW9uLnBhcmFtZXRlcnMgfHwgcGFyYW1ldGVycztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgbG9jYXRpb24gPSAnL3BhdGhzJyArIG5hbWUgKyAnLycgKyBtZXRob2QgKyAnL3BhcmFtZXRlcnMnO1xuXG4gICAgICAgICAgaWYgKHBhcmFtZXRlci5pbiA9PT0gJ2JvZHknICYmIHBhcmFtZXRlci5zY2hlbWEpIHtcbiAgICAgICAgICAgIGlmKF8uaXNBcnJheShwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICAgICAgICB2YXIgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgICAgICAgIHZhciBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICB2YXIgZG9uZSA9IGZhbHNlOyB2YXIgY291bnRlciA9IDA7XG4gICAgICAgICAgICAgIHdoaWxlKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICBjb3VudGVyICsrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSB7IGFsbE9mOiBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mIH07XG4gICAgICAgICAgICAgIGRlbGV0ZSBwYXJhbWV0ZXIuc2NoZW1hLmFsbE9mO1xuICAgICAgICAgICAgICBwYXJhbWV0ZXIuc2NoZW1hLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgbmFtZTtcbiAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcGFyYW1ldGVyLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcmFtZXRlci4kcmVmKSB7XG4gICAgICAgICAgICAvLyBwYXJhbWV0ZXIgcmVmZXJlbmNlXG4gICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGFyYW1ldGVyLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBwYXJhbWV0ZXIuJHJlZik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChyZXNwb25zZUNvZGUgaW4gb3BlcmF0aW9uLnJlc3BvbnNlcykge1xuICAgICAgICAgIHZhciByZXNwb25zZSA9IG9wZXJhdGlvbi5yZXNwb25zZXNbcmVzcG9uc2VDb2RlXTtcbiAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcmVzcG9uc2VzLycgKyByZXNwb25zZUNvZGU7XG5cbiAgICAgICAgICBpZihfLmlzT2JqZWN0KHJlc3BvbnNlKSkge1xuICAgICAgICAgICAgaWYocmVzcG9uc2UuJHJlZikge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZSByZWZlcmVuY2VcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgICAgICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICBpZihfLmlzQXJyYXkocmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgdG8gYSBkZWZpbml0aW9uXG4gICAgICAgICAgICAgICAgdmFyIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgIHZhciBuYW1lID0gbW9kZWxOYW1lO1xuICAgICAgICAgICAgICAgIHZhciBkb25lID0gZmFsc2U7IHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZSghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYodHlwZW9mIHNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWUgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICAgICAgICAgICAgY291bnRlciArKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHsgYWxsT2Y6IHJlc3BvbnNlT2JqLnNjaGVtYS5hbGxPZiB9O1xuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZU9iai5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlT2JqLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZignYXJyYXknID09PSByZXNwb25zZU9iai5zY2hlbWEudHlwZSkge1xuICAgICAgICAgICAgICAgIGlmKHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcyAmJiByZXNwb25zZU9iai5zY2hlbWEuaXRlbXMuJHJlZikge1xuICAgICAgICAgICAgICAgICAgLy8gcmVzcG9uc2UgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHJlc3BvbnNlLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2xlYXIgdGhlbSBvdXQgdG8gYXZvaWQgbXVsdGlwbGUgcmVzb2x1dGlvbnNcbiAgICBwYXRoLnBhcmFtZXRlcnMgPSBbXTtcbiAgfVxuXG4gIHZhciBleHBlY3RlZENhbGxzID0gMCwgdG9SZXNvbHZlID0gW107XG4gIC8vIGlmIHRoZSByb290IGlzIHNhbWUgYXMgb2JqW2ldLnJvb3Qgd2UgY2FuIHJlc29sdmUgbG9jYWxseVxuICB2YXIgYWxsID0gcmVzb2x1dGlvblRhYmxlO1xuXG4gIHZhciBwYXJ0cztcbiAgZm9yKGkgPSAwOyBpIDwgYWxsLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGEgPSBhbGxbaV07XG4gICAgaWYocm9vdCA9PT0gYS5yb290KSB7XG4gICAgICBpZihhLnJlc29sdmVBcyA9PT0gJ3JlZicpIHtcbiAgICAgICAgLy8gcmVzb2x2ZSBhbnkgcGF0aCB3YWxraW5nXG4gICAgICAgIHZhciBqb2luZWQgPSAoKGEucm9vdCB8fCAnJykgKyAnLycgKyBhLmtleSkuc3BsaXQoJy8nKTtcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWQgPSBbXTtcbiAgICAgICAgdmFyIHVybCA9ICcnO1xuICAgICAgICB2YXIgaztcblxuICAgICAgICBpZihhLmtleS5pbmRleE9mKCcuLi8nKSA+PSAwKSB7XG4gICAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IGpvaW5lZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYoam9pbmVkW2pdID09PSAnLi4nKSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNsaWNlKDAsIG5vcm1hbGl6ZWQubGVuZ3RoLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWQucHVzaChqb2luZWRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IoayA9IDA7IGsgPCBub3JtYWxpemVkLmxlbmd0aDsgayArKykge1xuICAgICAgICAgICAgaWYoayA+IDApIHtcbiAgICAgICAgICAgICAgdXJsICs9ICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHVybCArPSBub3JtYWxpemVkW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSBub3cgaGF2ZSB0byByZW1vdGUgcmVzb2x2ZSB0aGlzIGJlY2F1c2UgdGhlIHBhdGggaGFzIGNoYW5nZWRcbiAgICAgICAgICBhLnJvb3QgPSB1cmw7XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcGFydHMgPSBhLmtleS5zcGxpdCgnIycpO1xuICAgICAgICAgIGlmKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgaWYocGFydHNbMF0uaW5kZXhPZignaHR0cDovLycpID09PSAwIHx8IHBhcnRzWzBdLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICAgICAgICAgICAgYS5yb290ID0gcGFydHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICB2YXIgcjtcbiAgICAgICAgICAgIHZhciBzID0gc3BlYztcbiAgICAgICAgICAgIGZvcihrID0gMDsgayA8IGxvY2F0aW9uLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIHZhciBwYXJ0ID0gbG9jYXRpb25ba107XG4gICAgICAgICAgICAgIGlmKHBhcnQgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcyA9IHNbcGFydF07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICByID0gcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICByID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYociA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBtdXN0IHJlc29sdmUgdGhpcyB0b29cbiAgICAgICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKGEucmVzb2x2ZUFzID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGlmKGEua2V5ICYmIGEua2V5LmluZGV4T2YoJyMnKSA9PT0gLTEgJiYgYS5rZXkuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICAgIC8vIGhhbmRsZSByZWxhdGl2ZSBzY2hlbWFcbiAgICAgICAgICAgIHBhcnRzID0gYS5yb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgIGxvY2F0aW9uICs9IHBhcnRzW2ldICsgJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gKz0gYS5rZXk7XG4gICAgICAgICAgICBhLnJvb3QgPSBsb2NhdGlvbjtcbiAgICAgICAgICAgIGEubG9jYXRpb24gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICB9XG4gIH1cbiAgZXhwZWN0ZWRDYWxscyA9IHRvUmVzb2x2ZS5sZW5ndGg7XG5cbiAgLy8gcmVzb2x2ZSBhbnl0aGluZyB0aGF0IGlzIGxvY2FsXG4gIGZvcih2YXIgaWkgPSAwOyBpaSA8IHRvUmVzb2x2ZS5sZW5ndGg7IGlpKyspIHtcbiAgICAoZnVuY3Rpb24oaXRlbSwgc3BlYywgc2VsZikge1xuICAgICAgLy8gTk9URTogdGhpcyB1c2VkIHRvIGJlIGl0ZW0ucm9vdCA9PT0gbnVsbCwgYnV0IEkgKEBwb25lbGF0KSBoYXZlIGFkZGVkIGEgZ3VhcmQgYWdhaW5zdCAuc3BsaXQsIHdoaWNoIG1lYW5zIGl0ZW0ucm9vdCBjYW4gYmUgJydcbiAgICAgIGlmKCFpdGVtLnJvb3QgfHwgaXRlbS5yb290ID09PSByb290KSB7XG4gICAgICAgIC8vIGxvY2FsIHJlc29sdmVcbiAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBpdGVtKTtcbiAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcblxuICAgICAgICBpZihwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmKHNlbGYuZmFpbGVkVXJscy5pbmRleE9mKGl0ZW0ucm9vdCkgPT09IC0xKSB7XG4gICAgICAgIHZhciBvYmogPSB7XG4gICAgICAgICAgdXNlSlF1ZXJ5OiBmYWxzZSwgIC8vIFRPRE9cbiAgICAgICAgICB1cmw6IGl0ZW0ucm9vdCxcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIGFjY2VwdDogc2VsZi5zY29wZS5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMgfHwgJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvbjoge1xuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygnZmFpbGVkIHVybDogJyArIG9iai51cmwpO1xuICAgICAgICAgICAgICBzZWxmLmZhaWxlZFVybHMucHVzaChvYmoudXJsKTtcbiAgICAgICAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICB2YXIgc3dhZ2dlciA9IHJlc3BvbnNlLm9iajtcbiAgICAgICAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzd2FnZ2VyLCBpdGVtLnJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoc2NvcGUgJiYgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgICBzY29wZS5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgIHVucmVzb2x2ZWRSZWZzW2l0ZW0ua2V5XSA9IHtcbiAgICAgICAgICByb290OiBpdGVtLnJvb3QsXG4gICAgICAgICAgbG9jYXRpb246IGl0ZW0ubG9jYXRpb25cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSh0b1Jlc29sdmVbaWldLCBzcGVjLCB0aGlzKSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXModG9SZXNvbHZlKS5sZW5ndGggPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSXRlbSA9IGZ1bmN0aW9uKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ubG9jYXRpb247XG4gIHZhciBsb2NhdGlvbiA9IHNwZWMsIHBhcnRzID0gcGF0aC5zcGxpdCgnLycpO1xuICBpZihwYXRoICE9PSAnJykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciBzZWdtZW50ID0gcGFydHNbal07XG4gICAgICBpZiAoc2VnbWVudC5pbmRleE9mKCd+MScpICE9PSAtMSkge1xuICAgICAgICBzZWdtZW50ID0gcGFydHNbal0ucmVwbGFjZSgvfjAvZywgJ34nKS5yZXBsYWNlKC9+MS9nLCAnLycpO1xuICAgICAgICBpZiAoc2VnbWVudC5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICAgIHNlZ21lbnQgPSAnLycgKyBzZWdtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAndW5kZWZpbmVkJyB8fCBsb2NhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50ID09PSAnJyAmJiBqID09PSAocGFydHMubGVuZ3RoIC0gMSkgJiYgcGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uW3NlZ21lbnRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgcmVzb2x2ZWQgPSBpdGVtLmtleTtcbiAgcGFydHMgPSBpdGVtLmtleS5zcGxpdCgnLycpO1xuICB2YXIgcmVzb2x2ZWROYW1lID0gcGFydHNbcGFydHMubGVuZ3RoLTFdO1xuXG4gIGlmKHJlc29sdmVkTmFtZS5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgIHJlc29sdmVkTmFtZSA9IHJlc29sdmVkTmFtZS5zcGxpdCgnIycpWzFdO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uICE9PSBudWxsICYmIHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgbmFtZTogcmVzb2x2ZWROYW1lLFxuICAgICAgb2JqOiBsb2NhdGlvbixcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICByb290OiBpdGVtLnJvb3RcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVucmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgfTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCBsb2NhbFJlc29sdmUpIHtcbiAgLy8gd2FsayByZXNvbHV0aW9uIHRhYmxlIGFuZCByZXBsYWNlIHdpdGggcmVzb2x2ZWQgcmVmc1xuICB2YXIgcmVmO1xuICBmb3IgKHJlZiBpbiByZXNvbHV0aW9uVGFibGUpIHtcbiAgICB2YXIgaXRlbSA9IHJlc29sdXRpb25UYWJsZVtyZWZdO1xuXG4gICAgdmFyIGtleSA9IGl0ZW0ua2V5O1xuICAgIHZhciByZXNvbHZlZFRvID0gcmVzb2x2ZWRSZWZzW2tleV07XG4gICAgaWYgKHJlc29sdmVkVG8pIHtcbiAgICAgIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAgICAgaWYgKGl0ZW0ucmVzb2x2ZUFzID09PSAncmVmJykge1xuICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgLy8gZG9uJ3QgcmV0YWluIHJvb3QgZm9yIGxvY2FsIGRlZmluaXRpb25zXG4gICAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICAgIHZhciBhYnMgPSB0aGlzLnJldGFpblJvb3QocmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tyZXNvbHZlZFRvLm5hbWVdID0gcmVzb2x2ZWRUby5vYmo7XG4gICAgICAgIGl0ZW0ub2JqLiRyZWYgPSAnIy9kZWZpbml0aW9ucy8nICsgcmVzb2x2ZWRUby5uYW1lO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLnJlc29sdmVBcyA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgdmFyIHRhcmdldE9iaiA9IGl0ZW0ub2JqO1xuICAgICAgICB0YXJnZXRPYmpbJ3gtcmVzb2x2ZWQtZnJvbSddID0gWyBpdGVtLmtleSBdO1xuICAgICAgICBkZWxldGUgdGFyZ2V0T2JqLiRyZWY7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gcmVzb2x2ZWRUby5vYmopIHtcbiAgICAgICAgICB2YXIgYWJzID0gcmVzb2x2ZWRUby5vYmpba2V5XTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAobG9jYWxSZXNvbHZlICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBkb24ndCByZXRhaW4gcm9vdCBmb3IgbG9jYWwgZGVmaW5pdGlvbnNcbiAgICAgICAgICAgIGFicyA9IHRoaXMucmV0YWluUm9vdChyZXNvbHZlZFRvLm9ialtrZXldLCBpdGVtLnJvb3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0YXJnZXRPYmpba2V5XSA9IGFicztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgZXhpc3RpbmdVbnJlc29sdmVkID0gdGhpcy5jb3VudFVucmVzb2x2ZWRSZWZzKHNwZWMpO1xuXG4gIGlmKGV4aXN0aW5nVW5yZXNvbHZlZCA9PT0gMCB8fCB0aGlzLml0ZXJhdGlvbiA+IDUpIHtcbiAgICB0aGlzLnJlc29sdmVBbGxPZihzcGVjLmRlZmluaXRpb25zKTtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMuc2NvcGUsIHNwZWMsIHVucmVzb2x2ZWRSZWZzKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLml0ZXJhdGlvbiArPSAxO1xuICAgIHRoaXMucmVzb2x2ZShzcGVjLCByb290LCBjYWxsYmFjaywgdGhpcy5zY29wZSk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5jb3VudFVucmVzb2x2ZWRSZWZzID0gZnVuY3Rpb24oc3BlYykge1xuICB2YXIgaTtcbiAgdmFyIHJlZnMgPSB0aGlzLmdldFJlZnMoc3BlYyk7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciB1bnJlc29sdmVkS2V5cyA9IFtdO1xuICBmb3IoaSBpbiByZWZzKSB7XG4gICAgaWYoaS5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGtleXMucHVzaChpLnN1YnN0cmluZygxKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICAvLyB2ZXJpZnkgcG9zc2libGUga2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0ga2V5c1tpXTtcbiAgICB2YXIgcGFydHMgPSBwYXJ0LnNwbGl0KCcvJyk7XG4gICAgdmFyIG9iaiA9IHNwZWM7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IHBhcnRzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgb3V0cHV0W2l0ZW1dID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB2YXIgbyA9IHRoaXMuZ2V0UmVmcyhpdGVtKTtcbiAgICAgIGZvcih2YXIgayBpbiBvKSB7XG4gICAgICAgIG91dHB1dFtrXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmV0YWluUm9vdCA9IGZ1bmN0aW9uKG9iaiwgcm9vdCkge1xuICAvLyB3YWxrIG9iamVjdCBhbmQgbG9vayBmb3IgcmVsYXRpdmUgJHJlZnNcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihrZXkgPT09ICckcmVmJyAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHN0b3AgYW5kIGluc3BlY3RcbiAgICAgIGlmKGl0ZW0uaW5kZXhPZignaHR0cDovLycpICE9PSAwICYmIGl0ZW0uaW5kZXhPZignaHR0cHM6Ly8nKSAhPT0gMCkge1xuICAgICAgICAvLyBUT0RPOiBjaGVjayBpZiByb290IGVuZHMgaW4gJy8nLiAgSWYgbm90LCBBTkQgaXRlbSBoYXMgbm8gcHJvdG9jb2wsIG1ha2UgcmVsYXRpdmVcbiAgICAgICAgdmFyIGFwcGVuZEhhc2ggPSB0cnVlO1xuICAgICAgICB2YXIgb2xkUm9vdCA9IHJvb3Q7XG4gICAgICAgIGlmKHJvb3QpIHtcbiAgICAgICAgICB2YXIgbGFzdENoYXIgPSByb290LnNsaWNlKC0xKTtcbiAgICAgICAgICBpZihsYXN0Q2hhciAhPT0gJy8nICYmIChpdGVtLmluZGV4T2YoJyMnKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHA6Ly8nKSAhPT0gMCAmJiBpdGVtLmluZGV4T2YoJ2h0dHBzOi8vJykpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnd29ya2luZyB3aXRoICcgKyBpdGVtKTtcbiAgICAgICAgICAgIGFwcGVuZEhhc2ggPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHJvb3Quc3BsaXQoJ1xcLycpO1xuICAgICAgICAgICAgcGFydHMgPSBwYXJ0cy5zcGxpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICByb290ID0gJyc7XG4gICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgcm9vdCArPSBwYXJ0c1tpXSArICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYoaXRlbS5pbmRleE9mKCcjJykgIT09IDAgJiYgYXBwZW5kSGFzaCkge1xuICAgICAgICAgIGl0ZW0gPSAnIycgKyBpdGVtO1xuICAgICAgICB9XG5cbiAgICAgICAgaXRlbSA9IChyb290IHx8ICcnKSArIGl0ZW07XG4gICAgICAgIG9ialtrZXldID0gaXRlbTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB0aGlzLnJldGFpblJvb3QoaXRlbSwgcm9vdCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIGltbWVkaWF0ZWx5IGluLWxpbmVzIGxvY2FsIHJlZnMsIHF1ZXVlcyByZW1vdGUgcmVmc1xuICogZm9yIGlubGluZSByZXNvbHV0aW9uXG4gKi9cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSW5saW5lID0gZnVuY3Rpb24gKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbikge1xuICB2YXIga2V5ID0gcHJvcGVydHkuJHJlZiwgcmVmID0gcHJvcGVydHkuJHJlZiwgaSwgcCwgcDIsIHJzO1xuICB2YXIgcm9vdFRyaW1tZWQgPSBmYWxzZTtcblxuICByb290ID0gcm9vdCB8fCAnJyAvLyBHdWFyZCBhZ2FpbnN0IC5zcGxpdC4gQGZlaGd1eSwgeW91J2xsIG5lZWQgdG8gY2hlY2sgaWYgdGhpcyBsb2dpYyBmaXRzXG4gIC8vIE1vcmUgaW1wb3JhbnRseSBpcyBob3cgZG8gd2UgZ3JhY2VmdWxseSBoYW5kbGUgcmVsYXRpdmUgdXJscywgd2hlbiBwcm92aWRlZCBqdXN0IGEgJ3NwZWMnLCBub3QgYSAndXJsJyA/XG5cbiAgaWYgKHJlZikge1xuICAgIGlmKHJlZi5pbmRleE9mKCcuLi8nKSA9PT0gMCkge1xuICAgICAgLy8gcmVzZXQgcm9vdFxuICAgICAgcCA9IHJlZi5zcGxpdCgnLi4vJyk7XG4gICAgICBwMiA9IHJvb3Quc3BsaXQoJy8nKTtcbiAgICAgIHJlZiA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZihwW2ldID09PSAnJykge1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoLTEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJlZiArPSBwW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByb290ID0gJyc7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBwMi5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYoaSA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgcm9vdCArPSBwMltpXTtcbiAgICAgIH1cbiAgICAgIHJvb3RUcmltbWVkID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICBpZihyZWYuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIHAgID0gcm9vdC5zcGxpdCgnLy8nKTtcbiAgICAgICAgcDIgPSBwWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgIHJvb3QgPSBwWzBdICsgJy8vJyArIHAyWzBdICsgcnNbMF07XG4gICAgICAgIGxvY2F0aW9uID0gcnNbMV07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcnMgPSByZWYuc3BsaXQoJyMnKTtcbiAgICAgICAgaWYocnNbMF0gIT09ICcnKSB7XG4gICAgICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgcDIgPSBwMi5zbGljZSgwLCBwMi5sZW5ndGggLSAxKTtcbiAgICAgICAgICBpZighcm9vdFRyaW1tZWQpIHtcbiAgICAgICAgICAgIHJvb3QgPSAnJztcbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcDIubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgaWYoayA+IDApIHsgcm9vdCArPSAnLyc7IH1cbiAgICAgICAgICAgICAgcm9vdCArPSBwMltrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcm9vdCArPSAnLycgKyByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocmVmLmluZGV4T2YoJ2h0dHAnKSA9PT0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICAgIHJvb3QgPSByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByb290ID0gcmVmO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9IGVsc2UgaWYgKHJlZi5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJy8nKSA9PT0gMCAmJiByZWYuaW5kZXhPZignIycpID09PSAtMSkge1xuICAgICAgbG9jYXRpb24gPSByZWY7XG4gICAgICB2YXIgbWF0Y2hlcyA9IHJvb3QubWF0Y2goL15odHRwcz9cXDpcXC9cXC8oW15cXC8/I10rKSg/OltcXC8/I118JCkvaSk7XG4gICAgICBpZihtYXRjaGVzKSB7XG4gICAgICAgIHJvb3QgPSBtYXRjaGVzWzBdICsgcmVmLnN1YnN0cmluZygxKTtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5Lml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVUbyA9IGZ1bmN0aW9uIChyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbikge1xuICB2YXIgc3AsIGk7XG4gIHZhciByZWYgPSBwcm9wZXJ0eS4kcmVmO1xuICB2YXIgbHJvb3QgPSByb290O1xuICBpZiAoKHR5cGVvZiByZWYgIT09ICd1bmRlZmluZWQnKSAmJiAocmVmICE9PSBudWxsKSkge1xuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgdmFyIHBhcnRzID0gcmVmLnNwbGl0KCcjJyk7XG5cbiAgICAgIC8vICMvZGVmaW5pdGlvbnMvZm9vXG4gICAgICAvLyBmb28uanNvbiMvYmFyXG4gICAgICBpZihwYXJ0c1swXSAmJiByZWYuaW5kZXhPZignLycpID09PSAwKSB7XG5cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYocGFydHNbMF0gJiYgcGFydHNbMF0uaW5kZXhPZignaHR0cCcpID09PSAwKSB7XG4gICAgICAgIGxyb290ID0gcGFydHNbMF07XG4gICAgICAgIHJlZiA9IHBhcnRzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiBwYXJ0c1swXS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgIGxyb290ID0gJyc7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgICB9XG4gICAgICAgIGxyb290ICs9IHBhcnRzWzBdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG5cbiAgICAgIH1cblxuICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmVmLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCB8fCByZWYuaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgICAgbHJvb3QgPSByZWY7XG4gICAgICBsb2NhdGlvbiA9ICcnO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgIHNwID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgbHJvb3QgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBscm9vdCArPSBzcFtpXSArICcvJztcbiAgICAgIH1cbiAgICAgIGxyb290ICs9IHJlZjtcbiAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgfVxuICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtcbiAgICAgIG9iajogcHJvcGVydHksIHJlc29sdmVBczogJ3JlZicsIHJvb3Q6IGxyb290LCBrZXk6IHJlZiwgbG9jYXRpb246IGxvY2F0aW9uXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHZhciBpdGVtcyA9IHByb3BlcnR5Lml0ZW1zO1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIGl0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBpZihwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgbmFtZSA9IHRoaXMudW5pcXVlTmFtZSgnaW5saW5lX21vZGVsJyk7XG4gICAgICBpZiAocHJvcGVydHkudGl0bGUpIHtcbiAgICAgICAgbmFtZSA9IHRoaXMudW5pcXVlTmFtZShwcm9wZXJ0eS50aXRsZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgcHJvcGVydHkudGl0bGU7XG4gICAgICB0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0gPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG4gICAgICBwcm9wZXJ0eVsnJHJlZiddID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICBkZWxldGUgcHJvcGVydHkudHlwZTtcbiAgICAgIGRlbGV0ZSBwcm9wZXJ0eS5wcm9wZXJ0aWVzO1xuICAgIH1cbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnVuaXF1ZU5hbWUgPSBmdW5jdGlvbihiYXNlKSB7XG4gIHZhciBuYW1lID0gYmFzZTtcbiAgdmFyIGNvdW50ID0gMDtcbiAgd2hpbGUodHJ1ZSkge1xuICAgIGlmKCFfLmlzT2JqZWN0KHRoaXMuc3BlYy5kZWZpbml0aW9uc1tuYW1lXSkpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gYmFzZSArICdfJyArIGNvdW50O1xuICAgIGNvdW50Kys7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlQWxsT2YgPSBmdW5jdGlvbihzcGVjLCBvYmosIGRlcHRoKSB7XG4gIGRlcHRoID0gZGVwdGggfHwgMDtcbiAgb2JqID0gb2JqIHx8IHNwZWM7XG4gIHZhciBuYW1lO1xuICBmb3IodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICBpZihpdGVtID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdTd2FnZ2VyIDIuMCBkb2VzIG5vdCBzdXBwb3J0IG51bGwgdHlwZXMgKCcgKyBvYmogKyAnKS4gIFNlZSBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci1zcGVjL2lzc3Vlcy8yMjkuJyk7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgdGhpcy5yZXNvbHZlQWxsT2Yoc3BlYywgaXRlbSwgZGVwdGggKyAxKTtcbiAgICB9XG4gICAgaWYoaXRlbSAmJiB0eXBlb2YgaXRlbS5hbGxPZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBhbGxPZiA9IGl0ZW0uYWxsT2Y7XG4gICAgICBpZihfLmlzQXJyYXkoYWxsT2YpKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSBfLmNsb25lRGVlcChpdGVtKTtcbiAgICAgICAgZGVsZXRlIG91dHB1dC5hbGxPZjtcblxuICAgICAgICBvdXRwdXRbJ3gtY29tcG9zZWQnXSA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbVsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgb3V0cHV0Wyd4LXJlc29sdmVkLWZyb20nXSA9IGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGFsbE9mLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGNvbXBvbmVudCA9IGFsbE9mW2ldO1xuICAgICAgICAgIHZhciBzb3VyY2UgPSAnc2VsZic7XG4gICAgICAgICAgaWYodHlwZW9mIGNvbXBvbmVudFsneC1yZXNvbHZlZC1mcm9tJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBzb3VyY2UgPSBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddWzBdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvcih2YXIgcGFydCBpbiBjb21wb25lbnQpIHtcbiAgICAgICAgICAgIGlmKCFvdXRwdXQuaGFzT3duUHJvcGVydHkocGFydCkpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdID0gXy5jbG9uZURlZXAoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgaWYocGFydCA9PT0gJ3Byb3BlcnRpZXMnKSB7XG4gICAgICAgICAgICAgICAgZm9yKG5hbWUgaW4gb3V0cHV0W3BhcnRdKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbcGFydF1bbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gc291cmNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0gY29tcG9uZW50W3BhcnRdO1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydGllc1tuYW1lXSk7XG4gICAgICAgICAgICAgICAgICB2YXIgcmVzb2x2ZWRGcm9tID0gcHJvcGVydGllc1tuYW1lXVsneC1yZXNvbHZlZC1mcm9tJ107XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc29sdmVkRnJvbSA9PT0gJ3VuZGVmaW5lZCcgfHwgcmVzb2x2ZWRGcm9tID09PSAnc2VsZicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWRGcm9tID0gc291cmNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb3V0cHV0LnByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddID0gcmVzb2x2ZWRGcm9tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmKHBhcnQgPT09ICdyZXF1aXJlZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBtZXJnZSAmIGRlZHVwIHRoZSByZXF1aXJlZCBhcnJheVxuICAgICAgICAgICAgICAgIHZhciBhID0gb3V0cHV0LnJlcXVpcmVkLmNvbmNhdChjb21wb25lbnRbcGFydF0pO1xuICAgICAgICAgICAgICAgIGZvcih2YXIgayA9IDA7IGsgPCBhLmxlbmd0aDsgKytrKSB7XG4gICAgICAgICAgICAgICAgICBmb3IodmFyIGogPSBrICsgMTsgaiA8IGEubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICAgICAgICAgICAgaWYoYVtrXSA9PT0gYVtqXSkgeyBhLnNwbGljZShqLS0sIDEpOyB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG91dHB1dC5yZXF1aXJlZCA9IGE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAneC1yZXNvbHZlZC1mcm9tJykge1xuICAgICAgICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10ucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IG5lZWQgdG8gbWVyZ2UgdGhpcyBwcm9wZXJ0eVxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCd3aGF0IHRvIGRvIHdpdGggJyArIHBhcnQpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgb2JqW2tleV0gPSBvdXRwdXQ7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgSGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRW1wdHk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0VtcHR5JyksXG4gIG1hcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL21hcCcpLFxuICBpbmRleE9mOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2FycmF5L2luZGV4T2YnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGtleXM6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXMnKSxcbiAgZm9yRWFjaDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2gnKVxufTtcblxubW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IG9wdGlvbkh0bWw7XG5tb2R1bGUuZXhwb3J0cy50eXBlRnJvbUpzb25TY2hlbWEgPSB0eXBlRnJvbUpzb25TY2hlbWE7XG5tb2R1bGUuZXhwb3J0cy5nZXRTdHJpbmdTaWduYXR1cmUgPSBnZXRTdHJpbmdTaWduYXR1cmU7XG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0hUTUwgPSBzY2hlbWFUb0hUTUw7XG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0pTT04gPSBzY2hlbWFUb0pTT047XG5cbmZ1bmN0aW9uIG9wdGlvbkh0bWwobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn1cblxuZnVuY3Rpb24gdHlwZUZyb21Kc29uU2NoZW1hKHR5cGUsIGZvcm1hdCkge1xuICB2YXIgc3RyO1xuXG4gIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIHR5cGVvZiBmb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciA9ICdkYXRlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHN0ciA9ICdzdHJpbmcnO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyaW5nU2lnbmF0dXJlKG9iaiwgYmFzZUNvbXBvbmVudCkge1xuICB2YXIgc3RyID0gJyc7XG5cbiAgaWYgKHR5cGVvZiBvYmouJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gSGVscGVycy5zaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmoudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ29iamVjdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYmFzZUNvbXBvbmVudCkge1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnQXJyYXlbJztcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgICAgc3RyICs9ICddJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyICs9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciArPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnc3RyaW5nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciArPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgKz0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKG9iai4kcmVmKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIHtcbiAgICBzdHIgKz0gb2JqLnR5cGU7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG5mdW5jdGlvbiBzY2hlbWFUb0pTT04oc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gIHNjaGVtYSA9IEhlbHBlcnMucmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gIGlmKHR5cGVvZiBtb2RlbFByb3BlcnR5TWFjcm8gIT09ICdmdW5jdGlvbicpIHtcbiAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICB9O1xuICB9XG5cbiAgbW9kZWxzVG9JZ25vcmU9IG1vZGVsc1RvSWdub3JlIHx8IHt9O1xuXG4gIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG4gIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICB2YXIgbW9kZWw7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5leGFtcGxlKSkge1xuICAgIG91dHB1dCA9IHNjaGVtYS5leGFtcGxlO1xuICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSAmJiBfLmlzQXJyYXkoc2NoZW1hLmVudW0pKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmVudW1bMF07XG4gIH1cblxuICBpZiAoXy5pc1VuZGVmaW5lZChvdXRwdXQpKSB7XG4gICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICBtb2RlbCA9IG1vZGVsc1tIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpKSB7XG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdKSkge1xuICAgICAgICAgIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdID0gbW9kZWw7XG4gICAgICAgICAgb3V0cHV0ID0gc2NoZW1hVG9KU09OKG1vZGVsLmRlZmluaXRpb24sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICAgICAgZGVsZXRlIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChtb2RlbC50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgICAgICBvdXRwdXQgPSBbXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3V0cHV0ID0ge307XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuZGVmYXVsdCkpIHtcbiAgICAgIG91dHB1dCA9IHNjaGVtYS5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSAnc3RyaW5nJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgb3V0cHV0ID0gMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBvdXRwdXQgPSAwLjA7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIG91dHB1dCA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgb3V0cHV0ID0ge307XG5cbiAgICAgIF8uZm9yRWFjaChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgICAgIGNQcm9wZXJ0eS5kZWZhdWx0ID0gbW9kZWxQcm9wZXJ0eU1hY3JvKHByb3BlcnR5KTtcblxuICAgICAgICBvdXRwdXRbbmFtZV0gPSBzY2hlbWFUb0pTT04oY1Byb3BlcnR5LCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBvdXRwdXQgPSBbXTtcblxuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIF8uZm9yRWFjaChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKGl0ZW0sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKHNjaGVtYS5pdGVtcywgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICB9IGVsc2UgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaCh7fSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBIZWxwZXJzLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBzY2hlbWFUb0hUTUwobmFtZSwgc2NoZW1hLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuXG4gIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgdmFyIHN0cm9uZ0Nsb3NlID0gJzwvc3Bhbj4nO1xuXG4gIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICBuYW1lID0gdm9pZCAwO1xuICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gYXJndW1lbnRzWzJdO1xuICB9XG5cbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgIHJldHVybiBzdHJvbmdPcGVuICsgJ0VtcHR5JyArIHN0cm9uZ0Nsb3NlO1xuICB9XG5cbiAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gIGlmKHR5cGVvZiBzY2hlbWEuJHJlZiA9PT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpO1xuICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG4gIH1cblxuICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB9XG5cbiAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgIHNjaGVtYSA9IHNjaGVtYS5kZWZpbml0aW9uO1xuICB9XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICB2YXIgaW5saW5lTW9kZWxzID0gMDtcblxuXG5cbiAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gIHZhciBodG1sID0gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG5cbiAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICBkZWxldGUgcmVmZXJlbmNlc1tuYW1lXTtcblxuICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgIGh0bWwgKz0gJzxiciAvPicgKyBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG5cbiAgcmV0dXJuIGh0bWw7XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgIHZhciBtb2RlbDtcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIG1vZGVsID0gbW9kZWxzW21vZGVsTmFtZV07XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCAnICsgKCsraW5saW5lTW9kZWxzKTtcbiAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgfVxuXG4gICAgaWYgKHNraXBSZWYgIT09IHRydWUpIHtcbiAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5hbWU7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wVHlwZVwiPic7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEuaXRlbXMsIGFkZFJlZmVyZW5jZSkuam9pbignLCcpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpICYmIF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgfVxuXG4gICAgaHRtbCArPSAnPC9zcGFuPic7XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCBodG1sKSB7XG4gICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gdHlwZSA9PT0gJ2FycmF5JztcblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIGlmIChzY2hlbWEubWluTGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhMZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHNjaGVtYS5taW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNaW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubXVsdGlwbGVPZikge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heEl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEudW5pcXVlSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgdmFyIGVudW1TdHJpbmc7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFbnVtJywgZW51bVN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcblxuICAgIGlmIChuYW1lKSB7XG4gICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgdmFyIHR5cGUgPSBpdGVtLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIF8uaXNVbmRlZmluZWQoaXRlbS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChpdGVtLCB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtLCBIZWxwZXJzLnNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBuYW1lKSArICc8L2Rpdj4nO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgIHZhciBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgIHZhciBtb2RlbDtcbiAgICAgICAgICAgIHZhciBwcm9wRGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8oY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICBjUHJvcGVydHkgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgcHJvcERlc2NyaXB0aW9uID0gcHJvcGVydHkuZGVzY3JpcHRpb24gfHwgY1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpICYmIF8uaW5kZXhPZihbdW5kZWZpbmVkLCAnYXJyYXknLCAnb2JqZWN0J10sIG1vZGVsLmRlZmluaXRpb24udHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BPcHRLZXlcIj5vcHRpb25hbDwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wUmVhZE9ubHlcIj5yZWFkIG9ubHk8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChwcm9wRGVzY3JpcHRpb24pKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHByb3BEZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNQcm9wZXJ0eS5lbnVtKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIGNQcm9wZXJ0eS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN3YWdnZXJIdHRwID0gcmVxdWlyZSgnLi9odHRwJyk7XG52YXIgXyA9IHtcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpXG59O1xuXG52YXIgU3dhZ2dlclNwZWNDb252ZXJ0ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lcnJvcnMgPSBbXTtcbiAgdGhpcy53YXJuaW5ncyA9IFtdO1xuICB0aGlzLm1vZGVsTWFwID0ge307XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uID0gZnVuY3Rpb24gKGxvY2F0aW9uKSB7XG4gIHRoaXMuZG9jTG9jYXRpb24gPSBsb2NhdGlvbjtcbn07XG5cbi8qKlxuICogY29udmVydHMgYSByZXNvdXJjZSBsaXN0aW5nIE9SIGFwaSBkZWNsYXJhdGlvblxuICoqL1xuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmNvbnZlcnQgPSBmdW5jdGlvbiAob2JqLCBjbGllbnRBdXRob3JpemF0aW9ucywgb3B0cywgY2FsbGJhY2spIHtcbiAgLy8gbm90IGEgdmFsaWQgc3BlY1xuICBpZighb2JqIHx8ICFBcnJheS5pc0FycmF5KG9iai5hcGlzKSkge1xuICAgIHJldHVybiB0aGlzLmZpbmlzaChjYWxsYmFjaywgbnVsbCk7XG4gIH1cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBzd2FnZ2VyIG9iamVjdCB0byByZXR1cm5cbiAgdmFyIHN3YWdnZXIgPSB7IHN3YWdnZXI6ICcyLjAnIH07XG5cbiAgc3dhZ2dlci5vcmlnaW5hbFZlcnNpb24gPSBvYmouc3dhZ2dlclZlcnNpb247XG5cbiAgLy8gYWRkIHRoZSBpbmZvXG4gIHRoaXMuYXBpSW5mbyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIGFkZCBzZWN1cml0eSBkZWZpbml0aW9uc1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMob2JqLCBzd2FnZ2VyKTtcblxuICAvLyB0YWtlIGJhc2VQYXRoIGludG8gYWNjb3VudFxuICBpZiAob2JqLmJhc2VQYXRoKSB7XG4gICAgdGhpcy5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24ob2JqLmJhc2VQYXRoKTtcbiAgfVxuXG4gIC8vIHNlZSBpZiB0aGlzIGlzIGEgc2luZ2xlLWZpbGUgc3dhZ2dlciBkZWZpbml0aW9uXG4gIHZhciBpc1NpbmdsZUZpbGVTd2FnZ2VyID0gZmFsc2U7XG4gIHZhciBpO1xuICBmb3IoaSA9IDA7IGkgPCBvYmouYXBpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICBpZihBcnJheS5pc0FycmF5KGFwaS5vcGVyYXRpb25zKSkge1xuICAgICAgaXNTaW5nbGVGaWxlU3dhZ2dlciA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmKGlzU2luZ2xlRmlsZVN3YWdnZXIpIHtcbiAgICB0aGlzLmRlY2xhcmF0aW9uKG9iaiwgc3dhZ2dlcik7XG4gICAgdGhpcy5maW5pc2goY2FsbGJhY2ssIHN3YWdnZXIpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMucmVzb3VyY2VMaXN0aW5nKG9iaiwgc3dhZ2dlciwgb3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZGVjbGFyYXRpb24gPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgdmFyIG5hbWUsIGksIHAsIHBvcztcbiAgaWYoIW9iai5hcGlzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG9iai5iYXNlUGF0aC5pbmRleE9mKCdodHRwOi8vJykgPT09IDApIHtcbiAgICBwID0gb2JqLmJhc2VQYXRoLnN1YnN0cmluZygnaHR0cDovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChvYmouYmFzZVBhdGguaW5kZXhPZignaHR0cHM6Ly8nKSA9PT0gMCkge1xuICAgIHAgPSBvYmouYmFzZVBhdGguc3Vic3RyaW5nKCdodHRwczovLycubGVuZ3RoKTtcbiAgICBwb3MgPSBwLmluZGV4T2YoJy8nKTtcbiAgICBpZiAocG9zID4gMCkge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcC5zdWJzdHJpbmcoMCwgcG9zKTtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSBwLnN1YnN0cmluZyhwb3MpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN3YWdnZXIuaG9zdCA9IHA7XG4gICAgICBzd2FnZ2VyLmJhc2VQYXRoID0gJy8nO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzd2FnZ2VyLmJhc2VQYXRoID0gb2JqLmJhc2VQYXRoO1xuICB9XG5cbiAgdmFyIHJlc291cmNlTGV2ZWxBdXRoO1xuICBpZihvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICByZXNvdXJjZUxldmVsQXV0aCA9IG9iai5hdXRob3JpemF0aW9ucztcbiAgfVxuICBpZihvYmouY29uc3VtZXMpIHtcbiAgICBzd2FnZ2VyLmNvbnN1bWVzID0gb2JqLmNvbnN1bWVzO1xuICB9XG4gIGlmKG9iai5wcm9kdWNlcykge1xuICAgIHN3YWdnZXIucHJvZHVjZXMgPSBvYmoucHJvZHVjZXM7XG4gIH1cblxuICAvLyBidWlsZCBhIG1hcHBpbmcgb2YgaWQgdG8gbmFtZSBmb3IgMS4wIG1vZGVsIHJlc29sdXRpb25zXG4gIGlmKF8uaXNPYmplY3Qob2JqKSkge1xuICAgIGZvcihuYW1lIGluIG9iai5tb2RlbHMpIHtcbiAgICAgIHZhciBleGlzdGluZ01vZGVsID0gb2JqLm1vZGVsc1tuYW1lXTtcbiAgICAgIHZhciBrZXkgPSAoZXhpc3RpbmdNb2RlbC5pZCB8fCBuYW1lKTtcbiAgICAgIHRoaXMubW9kZWxNYXBba2V5XSA9IG5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmFwaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgb3BlcmF0aW9ucyA9IGFwaS5vcGVyYXRpb25zO1xuICAgIHRoaXMub3BlcmF0aW9ucyhwYXRoLCBvYmoucmVzb3VyY2VQYXRoLCBvcGVyYXRpb25zLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcik7XG4gIH1cblxuICB2YXIgbW9kZWxzID0gb2JqLm1vZGVscyB8fCB7fTtcbiAgdGhpcy5tb2RlbHMobW9kZWxzLCBzd2FnZ2VyKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5tb2RlbHMgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIpIHtcbiAgaWYoIV8uaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbmFtZTtcblxuICBzd2FnZ2VyLmRlZmluaXRpb25zID0gc3dhZ2dlci5kZWZpbml0aW9ucyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gb2JqKSB7XG4gICAgdmFyIGV4aXN0aW5nTW9kZWwgPSBvYmpbbmFtZV07XG4gICAgdmFyIF9yZXF1aXJlZCA9IFtdO1xuICAgIHZhciBzY2hlbWEgPSB7IHByb3BlcnRpZXM6IHt9fTtcbiAgICB2YXIgcHJvcGVydHlOYW1lO1xuICAgIGZvcihwcm9wZXJ0eU5hbWUgaW4gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgZXhpc3RpbmdQcm9wZXJ0eSA9IGV4aXN0aW5nTW9kZWwucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgdmFyIHByb3BlcnR5ID0ge307XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUHJvcGVydHksIHByb3BlcnR5KTtcbiAgICAgIGlmKGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgcHJvcGVydHkuZGVzY3JpcHRpb24gPSBleGlzdGluZ1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuICAgICAgfVxuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eVsnZW51bSddKSB7XG4gICAgICAgIHByb3BlcnR5WydlbnVtJ10gPSBleGlzdGluZ1Byb3BlcnR5WydlbnVtJ107XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gJ2Jvb2xlYW4nICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAnc3RyaW5nJyAmJiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAndHJ1ZScpIHtcbiAgICAgICAgX3JlcXVpcmVkLnB1c2gocHJvcGVydHlOYW1lKTtcbiAgICAgIH1cbiAgICAgIHNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSBwcm9wZXJ0eTtcbiAgICB9XG4gICAgaWYoX3JlcXVpcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIHNjaGVtYS5yZXF1aXJlZCA9IF9yZXF1aXJlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NoZW1hLnJlcXVpcmVkID0gZXhpc3RpbmdNb2RlbC5yZXF1aXJlZDtcbiAgICB9XG4gICAgc3dhZ2dlci5kZWZpbml0aW9uc1tuYW1lXSA9IHNjaGVtYTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmV4dHJhY3RUYWcgPSBmdW5jdGlvbihyZXNvdXJjZVBhdGgpIHtcbiAgdmFyIHBhdGhTdHJpbmcgPSByZXNvdXJjZVBhdGggfHwgJ2RlZmF1bHQnO1xuICBpZihwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGF0aFN0cmluZy5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnNwbGl0KFsnLyddKTtcbiAgICBwYXRoU3RyaW5nID0gcGF0aFN0cmluZ1twYXRoU3RyaW5nLmxlbmd0aCAtMV0uc3Vic3RyaW5nKCk7XG4gIH1cbiAgaWYocGF0aFN0cmluZy5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nLnN1YnN0cmluZygwLCBwYXRoU3RyaW5nLmxlbmd0aCAtICcuanNvbicubGVuZ3RoKTtcbiAgfVxuICByZXR1cm4gcGF0aFN0cmluZy5yZXBsYWNlKCcvJywnJyk7XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUub3BlcmF0aW9ucyA9IGZ1bmN0aW9uKHBhdGgsIHJlc291cmNlUGF0aCwgb2JqLCByZXNvdXJjZUxldmVsQXV0aCwgc3dhZ2dlcikge1xuICBpZighQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBpO1xuXG4gIGlmKCFzd2FnZ2VyLnBhdGhzKSB7XG4gICAgc3dhZ2dlci5wYXRocyA9IHt9O1xuICB9XG5cbiAgdmFyIHBhdGhPYmogPSBzd2FnZ2VyLnBhdGhzW3BhdGhdIHx8IHt9O1xuICB2YXIgdGFnID0gdGhpcy5leHRyYWN0VGFnKHJlc291cmNlUGF0aCk7XG4gIHN3YWdnZXIudGFncyA9IHN3YWdnZXIudGFncyB8fCBbXTtcbiAgdmFyIG1hdGNoZWQgPSBmYWxzZTtcbiAgZm9yKGkgPSAwOyBpIDwgc3dhZ2dlci50YWdzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRhZ09iamVjdCA9IHN3YWdnZXIudGFnc1tpXTtcbiAgICBpZih0YWdPYmplY3QubmFtZSA9PT0gdGFnKSB7XG4gICAgICBtYXRjaGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYoIW1hdGNoZWQpIHtcbiAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7bmFtZTogdGFnfSk7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXhpc3RpbmdPcGVyYXRpb24gPSBvYmpbaV07XG4gICAgdmFyIG1ldGhvZCA9IChleGlzdGluZ09wZXJhdGlvbi5tZXRob2QgfHwgZXhpc3RpbmdPcGVyYXRpb24uaHR0cE1ldGhvZCkudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgb3BlcmF0aW9uID0ge3RhZ3M6IFt0YWddfTtcbiAgICB2YXIgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IGV4aXN0aW5nT3BlcmF0aW9uLmF1dGhvcml6YXRpb25zO1xuXG4gICAgaWYoZXhpc3RpbmdBdXRob3JpemF0aW9ucyAmJiBPYmplY3Qua2V5cyhleGlzdGluZ0F1dGhvcml6YXRpb25zKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMgPSByZXNvdXJjZUxldmVsQXV0aDtcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdBdXRob3JpemF0aW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBzY29wZXNPYmplY3Q7XG4gICAgICBmb3IodmFyIGtleSBpbiBleGlzdGluZ0F1dGhvcml6YXRpb25zKSB7XG4gICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eSA9IG9wZXJhdGlvbi5zZWN1cml0eSB8fCBbXTtcbiAgICAgICAgdmFyIHNjb3BlcyA9IGV4aXN0aW5nQXV0aG9yaXphdGlvbnNba2V5XTtcbiAgICAgICAgaWYoc2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNlY3VyaXR5U2NvcGVzID0gW107XG4gICAgICAgICAgZm9yKHZhciBqIGluIHNjb3Blcykge1xuICAgICAgICAgICAgc2VjdXJpdHlTY29wZXMucHVzaChzY29wZXNbal0uc2NvcGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IHNlY3VyaXR5U2NvcGVzO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc2NvcGVzT2JqZWN0ID0ge307XG4gICAgICAgICAgc2NvcGVzT2JqZWN0W2tleV0gPSBbXTtcbiAgICAgICAgICBvcGVyYXRpb24uc2VjdXJpdHkucHVzaChzY29wZXNPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IGV4aXN0aW5nT3BlcmF0aW9uLmNvbnN1bWVzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIuY29uc3VtZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5jb25zdW1lcyA9IHN3YWdnZXIuY29uc3VtZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBleGlzdGluZ09wZXJhdGlvbi5wcm9kdWNlcztcbiAgICB9XG4gICAgZWxzZSBpZihzd2FnZ2VyLnByb2R1Y2VzKSB7XG4gICAgICBvcGVyYXRpb24ucHJvZHVjZXMgPSBzd2FnZ2VyLnByb2R1Y2VzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5zdW1tYXJ5KSB7XG4gICAgICBvcGVyYXRpb24uc3VtbWFyeSA9IGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnk7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzKSB7XG4gICAgICBvcGVyYXRpb24uZGVzY3JpcHRpb24gPSBleGlzdGluZ09wZXJhdGlvbi5ub3RlcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWUpIHtcbiAgICAgIG9wZXJhdGlvbi5vcGVyYXRpb25JZCA9IGV4aXN0aW5nT3BlcmF0aW9uLm5pY2tuYW1lO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5kZXByZWNhdGVkKSB7XG4gICAgICBvcGVyYXRpb24uZGVwcmVjYXRlZCA9IGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5hdXRob3JpemF0aW9ucyhleGlzdGluZ0F1dGhvcml6YXRpb25zLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnBhcmFtZXRlcnMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbi5wYXJhbWV0ZXJzLCBzd2FnZ2VyKTtcbiAgICB0aGlzLnJlc3BvbnNlTWVzc2FnZXMob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbiwgc3dhZ2dlcik7XG5cbiAgICBwYXRoT2JqW21ldGhvZF0gPSBvcGVyYXRpb247XG4gIH1cblxuICBzd2FnZ2VyLnBhdGhzW3BhdGhdID0gcGF0aE9iajtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5yZXNwb25zZU1lc3NhZ2VzID0gZnVuY3Rpb24ob3BlcmF0aW9uLCBleGlzdGluZ09wZXJhdGlvbikge1xuICBpZighXy5pc09iamVjdChleGlzdGluZ09wZXJhdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gYnVpbGQgZGVmYXVsdCByZXNwb25zZSBmcm9tIHRoZSBvcGVyYXRpb24gKDEueClcbiAgdmFyIGRlZmF1bHRSZXNwb25zZSA9IHt9O1xuICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nT3BlcmF0aW9uLCBkZWZhdWx0UmVzcG9uc2UpO1xuICAvLyBUT0RPOiBsb29rIGludG8gdGhlIHJlYWwgcHJvYmxlbSBvZiByZW5kZXJpbmcgcmVzcG9uc2VzIGluIHN3YWdnZXItdWlcbiAgLy8gLi4uLnNob3VsZCByZXBvbnNlVHlwZSBoYXZlIGFuIGltcGxpY2l0IHNjaGVtYT9cbiAgaWYoIWRlZmF1bHRSZXNwb25zZS5zY2hlbWEgJiYgZGVmYXVsdFJlc3BvbnNlLnR5cGUpIHtcbiAgICBkZWZhdWx0UmVzcG9uc2UgPSB7c2NoZW1hOiBkZWZhdWx0UmVzcG9uc2V9O1xuICB9XG5cbiAgb3BlcmF0aW9uLnJlc3BvbnNlcyA9IG9wZXJhdGlvbi5yZXNwb25zZXMgfHwge307XG5cbiAgLy8gZ3JhYiBmcm9tIHJlc3BvbnNlTWVzc2FnZXMgKDEuMilcbiAgdmFyIGhhczIwMCA9IGZhbHNlO1xuICBpZihBcnJheS5pc0FycmF5KGV4aXN0aW5nT3BlcmF0aW9uLnJlc3BvbnNlTWVzc2FnZXMpKSB7XG4gICAgdmFyIGk7XG4gICAgdmFyIGV4aXN0aW5nUmVzcG9uc2VzID0gZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcztcbiAgICBmb3IoaSA9IDA7IGkgPCBleGlzdGluZ1Jlc3BvbnNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGV4aXN0aW5nUmVzcG9uc2UgPSBleGlzdGluZ1Jlc3BvbnNlc1tpXTtcbiAgICAgIHZhciByZXNwb25zZSA9IHsgZGVzY3JpcHRpb246IGV4aXN0aW5nUmVzcG9uc2UubWVzc2FnZSB9O1xuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5jb2RlID09PSAyMDApIHtcbiAgICAgICAgaGFzMjAwID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIC8vIENvbnZlcnQgcmVzcG9uc2VNb2RlbCAtPiBzY2hlbWF7JHJlZjogcmVzcG9uc2VNb2RlbH1cbiAgICAgIGlmKGV4aXN0aW5nUmVzcG9uc2UucmVzcG9uc2VNb2RlbCkge1xuICAgICAgICByZXNwb25zZS5zY2hlbWEgPSB7JyRyZWYnOiAnIy9kZWZpbml0aW9ucy8nICsgZXhpc3RpbmdSZXNwb25zZS5yZXNwb25zZU1vZGVsfTtcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJycgKyBleGlzdGluZ1Jlc3BvbnNlLmNvZGVdID0gcmVzcG9uc2U7XG4gICAgfVxuICB9XG5cbiAgaWYoaGFzMjAwKSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snZGVmYXVsdCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG4gIGVsc2Uge1xuICAgIG9wZXJhdGlvbi5yZXNwb25zZXNbJzIwMCddID0gZGVmYXVsdFJlc3BvbnNlO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXV0aG9yaXphdGlvbnMgPSBmdW5jdGlvbihvYmopIHtcbiAgLy8gVE9ET1xuICBpZighXy5pc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wZXJhdGlvbiwgb2JqKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ1BhcmFtZXRlciA9IG9ialtpXTtcbiAgICB2YXIgcGFyYW1ldGVyID0ge307XG4gICAgcGFyYW1ldGVyLm5hbWUgPSBleGlzdGluZ1BhcmFtZXRlci5uYW1lO1xuICAgIHBhcmFtZXRlci5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlc2NyaXB0aW9uO1xuICAgIHBhcmFtZXRlci5yZXF1aXJlZCA9IGV4aXN0aW5nUGFyYW1ldGVyLnJlcXVpcmVkO1xuICAgIHBhcmFtZXRlci5pbiA9IGV4aXN0aW5nUGFyYW1ldGVyLnBhcmFtVHlwZTtcblxuICAgIC8vIHBlciAjMTY4XG4gICAgaWYocGFyYW1ldGVyLmluID09PSAnYm9keScpIHtcbiAgICAgIHBhcmFtZXRlci5uYW1lID0gJ2JvZHknO1xuICAgIH1cbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtJykge1xuICAgICAgcGFyYW1ldGVyLmluID0gJ2Zvcm1EYXRhJztcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5lbnVtKSB7XG4gICAgICBwYXJhbWV0ZXIuZW51bSA9IGV4aXN0aW5nUGFyYW1ldGVyLmVudW07XG4gICAgfVxuXG4gICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dNdWx0aXBsZSA9PT0gdHJ1ZSB8fCBleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSAndHJ1ZScpIHtcbiAgICAgIHZhciBpbm5lclR5cGUgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIGlubmVyVHlwZSk7XG4gICAgICBwYXJhbWV0ZXIudHlwZSA9ICdhcnJheSc7XG4gICAgICBwYXJhbWV0ZXIuaXRlbXMgPSBpbm5lclR5cGU7XG5cbiAgICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcykge1xuICAgICAgICB2YXIgYXYgPSBleGlzdGluZ1BhcmFtZXRlci5hbGxvd2FibGVWYWx1ZXM7XG4gICAgICAgIGlmKGF2LnZhbHVlVHlwZSA9PT0gJ0xJU1QnKSB7XG4gICAgICAgICAgcGFyYW1ldGVyWydlbnVtJ10gPSBhdi52YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmRhdGFUeXBlKGV4aXN0aW5nUGFyYW1ldGVyLCBwYXJhbWV0ZXIpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgZXhpc3RpbmdQYXJhbWV0ZXIuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcGFyYW1ldGVyLmRlZmF1bHQgPSBleGlzdGluZ1BhcmFtZXRlci5kZWZhdWx0VmFsdWU7XG4gICAgfVxuXG4gICAgb3BlcmF0aW9uLnBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycyB8fCBbXTtcbiAgICBvcGVyYXRpb24ucGFyYW1ldGVycy5wdXNoKHBhcmFtZXRlcik7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5kYXRhVHlwZSA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIGlmKCFfLmlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZihzb3VyY2UubWluaW11bSkge1xuICAgIHRhcmdldC5taW5pbXVtID0gc291cmNlLm1pbmltdW07XG4gIH1cbiAgaWYoc291cmNlLm1heGltdW0pIHtcbiAgICB0YXJnZXQubWF4aW11bSA9IHNvdXJjZS5tYXhpbXVtO1xuICB9XG4gIGlmIChzb3VyY2UuZm9ybWF0KSB7XG4gICAgdGFyZ2V0LmZvcm1hdCA9IHNvdXJjZS5mb3JtYXQ7XG4gIH1cblxuICAvLyBkZWZhdWx0IGNhbiBiZSAnZmFsc2UnXG4gIGlmKHR5cGVvZiBzb3VyY2UuZGVmYXVsdFZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRhcmdldC5kZWZhdWx0ID0gc291cmNlLmRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIHZhciBqc29uU2NoZW1hVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHNvdXJjZSk7XG4gIGlmKGpzb25TY2hlbWFUeXBlKSB7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0IHx8IHt9O1xuICAgIGlmKGpzb25TY2hlbWFUeXBlLnR5cGUpIHtcbiAgICAgIHRhcmdldC50eXBlID0ganNvblNjaGVtYVR5cGUudHlwZTtcbiAgICB9XG4gICAgaWYoanNvblNjaGVtYVR5cGUuZm9ybWF0KSB7XG4gICAgICB0YXJnZXQuZm9ybWF0ID0ganNvblNjaGVtYVR5cGUuZm9ybWF0O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS4kcmVmKSB7XG4gICAgICB0YXJnZXQuc2NoZW1hID0geyRyZWY6IGpzb25TY2hlbWFUeXBlLiRyZWZ9O1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5pdGVtcykge1xuICAgICAgdGFyZ2V0Lml0ZW1zID0ganNvblNjaGVtYVR5cGUuaXRlbXM7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUudG9Kc29uU2NoZW1hID0gZnVuY3Rpb24oc291cmNlKSB7XG4gIGlmKCFzb3VyY2UpIHtcbiAgICByZXR1cm4gJ29iamVjdCc7XG4gIH1cbiAgdmFyIGRldGVjdGVkVHlwZSA9IChzb3VyY2UudHlwZSB8fCBzb3VyY2UuZGF0YVR5cGUgfHwgc291cmNlLnJlc3BvbnNlQ2xhc3MgfHwgJycpO1xuICB2YXIgbGNUeXBlID0gZGV0ZWN0ZWRUeXBlLnRvTG93ZXJDYXNlKCk7XG4gIHZhciBmb3JtYXQgPSAoc291cmNlLmZvcm1hdCB8fCAnJykudG9Mb3dlckNhc2UoKTtcblxuICBpZihsY1R5cGUuaW5kZXhPZignbGlzdFsnKSA9PT0gMCkge1xuICAgIHZhciBpbm5lclR5cGUgPSBkZXRlY3RlZFR5cGUuc3Vic3RyaW5nKDUsIGRldGVjdGVkVHlwZS5sZW5ndGggLSAxKTtcbiAgICB2YXIganNvblR5cGUgPSB0aGlzLnRvSnNvblNjaGVtYSh7dHlwZTogaW5uZXJUeXBlfSk7XG4gICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczoganNvblR5cGV9O1xuICB9IGVsc2UgaWYobGNUeXBlID09PSAnaW50JyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50MzInfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdsb25nJyB8fCAobGNUeXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdpbnRlZ2VyJywgZm9ybWF0OiAnaW50NjQnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdmbG9hdCcgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdudW1iZXInLCBmb3JtYXQ6ICdmbG9hdCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2RvdWJsZScgfHwgKGxjVHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnbnVtYmVyJywgZm9ybWF0OiAnZG91YmxlJ307fVxuICB9IGVsc2UgaWYoKGxjVHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZS10aW1lJykgfHwgKGxjVHlwZSA9PT0gJ2RhdGUnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdzdHJpbmcnLCBmb3JtYXQ6ICdkYXRlLXRpbWUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZyd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ZpbGUnfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdib29sZWFuJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdib29sZWFuJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYm9vbGVhbicpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnYm9vbGVhbid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2FycmF5JyB8fCBsY1R5cGUgPT09ICdsaXN0Jykge1xuICAgIGlmKHNvdXJjZS5pdGVtcykge1xuICAgICAgdmFyIGl0ID0gdGhpcy50b0pzb25TY2hlbWEoc291cmNlLml0ZW1zKTtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IGl0fTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiB7dHlwZTogJ29iamVjdCd9fTtcbiAgICB9XG4gIH0gZWxzZSBpZihzb3VyY2UuJHJlZikge1xuICAgIHJldHVybiB7JHJlZjogdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gPyAnIy9kZWZpbml0aW9ucy8nICsgdGhpcy5tb2RlbE1hcFtzb3VyY2UuJHJlZl0gOiBzb3VyY2UuJHJlZn07XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICd2b2lkJyB8fCBsY1R5cGUgPT09ICcnKSB7XG4gICAge3JldHVybiB7fTt9XG4gIH0gZWxzZSBpZiAodGhpcy5tb2RlbE1hcFtzb3VyY2UudHlwZV0pIHtcbiAgICAvLyBJZiB0aGlzIGEgbW9kZWwgdXNpbmcgYHR5cGVgIGluc3RlYWQgb2YgYCRyZWZgLCB0aGF0J3MgZmluZS5cbiAgICByZXR1cm4geyRyZWY6ICcjL2RlZmluaXRpb25zLycgKyB0aGlzLm1vZGVsTWFwW3NvdXJjZS50eXBlXX07XG4gIH0gZWxzZSB7XG4gICAgLy8gVW5rbm93biBtb2RlbCB0eXBlIG9yICdvYmplY3QnLCBwYXNzIGl0IGFsb25nLlxuICAgIHJldHVybiB7dHlwZTogc291cmNlLnR5cGV9O1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUucmVzb3VyY2VMaXN0aW5nID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyLCBvcHRzLCBjYWxsYmFjaykge1xuICB2YXIgaTtcbiAgdmFyIHByb2Nlc3NlZENvdW50ID0gMDsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIHNlbGYgPSB0aGlzOyAgICAgICAgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIGV4cGVjdGVkQ291bnQgPSBvYmouYXBpcy5sZW5ndGg7XG4gIHZhciBfc3dhZ2dlciA9IHN3YWdnZXI7ICAgLy8ganNoaW50IGlnbm9yZTpsaW5lXG4gIHZhciBfb3B0cyA9IHt9O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yO1xuICB9XG5cbiAgaWYob3B0cyAmJiBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3Ipe1xuICAgIF9vcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3IgPSBvcHRzLnJlc3BvbnNlSW50ZXJjZXB0b3I7XG4gIH1cblxuICB2YXIgc3dhZ2dlclJlcXVlc3RIZWFkZXJzID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnMpIHtcbiAgICBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSBvcHRzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycztcbiAgfVxuXG4gIGlmKGV4cGVjdGVkQ291bnQgPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChjYWxsYmFjaywgc3dhZ2dlcik7XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBleHBlY3RlZENvdW50OyBpKyspIHtcbiAgICB2YXIgYXBpID0gb2JqLmFwaXNbaV07XG4gICAgdmFyIHBhdGggPSBhcGkucGF0aDtcbiAgICB2YXIgYWJzb2x1dGVQYXRoID0gdGhpcy5nZXRBYnNvbHV0ZVBhdGgob2JqLnN3YWdnZXJWZXJzaW9uLCB0aGlzLmRvY0xvY2F0aW9uLCBwYXRoKTtcblxuICAgIGlmKGFwaS5kZXNjcmlwdGlvbikge1xuICAgICAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICAgICAgc3dhZ2dlci50YWdzLnB1c2goe1xuICAgICAgICBuYW1lIDogdGhpcy5leHRyYWN0VGFnKGFwaS5wYXRoKSxcbiAgICAgICAgZGVzY3JpcHRpb24gOiBhcGkuZGVzY3JpcHRpb24gfHwgJydcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgaHR0cCA9IHtcbiAgICAgIHVybDogYWJzb2x1dGVQYXRoLFxuICAgICAgaGVhZGVyczogeyBhY2NlcHQ6IHN3YWdnZXJSZXF1ZXN0SGVhZGVycyB9LFxuICAgICAgb246IHt9LFxuICAgICAgbWV0aG9kOiAnZ2V0J1xuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgIGh0dHAub24ucmVzcG9uc2UgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgdmFyIG9iaiA9IGRhdGEub2JqO1xuICAgICAgaWYob2JqKSB7XG4gICAgICAgIHNlbGYuZGVjbGFyYXRpb24ob2JqLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgaHR0cC5vbi5lcnJvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICBwcm9jZXNzZWRDb3VudCArPSAxO1xuICAgICAgaWYocHJvY2Vzc2VkQ291bnQgPT09IGV4cGVjdGVkQ291bnQpIHtcbiAgICAgICAgc2VsZi5maW5pc2goY2FsbGJhY2ssIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbiAgICBpZih0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zICYmIHR5cGVvZiB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KGh0dHApO1xuICAgIH1cblxuICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUoaHR0cCwgX29wdHMpO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVQYXRoID0gZnVuY3Rpb24odmVyc2lvbiwgZG9jTG9jYXRpb24sIHBhdGgpICB7XG4gIGlmKHZlcnNpb24gPT09ICcxLjAnKSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy5qc29uJykpIHtcbiAgICAgIC8vIGdldCByb290IHBhdGhcbiAgICAgIHZhciBwb3MgPSBkb2NMb2NhdGlvbi5sYXN0SW5kZXhPZignLycpO1xuICAgICAgaWYocG9zID4gMCkge1xuICAgICAgICBkb2NMb2NhdGlvbiA9IGRvY0xvY2F0aW9uLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBsb2NhdGlvbiA9IGRvY0xvY2F0aW9uO1xuICBpZihwYXRoLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCB8fCBwYXRoLmluZGV4T2YoJ2h0dHBzOi8vJykgPT09IDApIHtcbiAgICBsb2NhdGlvbiA9IHBhdGg7XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYoZG9jTG9jYXRpb24uZW5kc1dpdGgoJy8nKSkge1xuICAgICAgbG9jYXRpb24gPSBkb2NMb2NhdGlvbi5zdWJzdHJpbmcoMCwgZG9jTG9jYXRpb24ubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGxvY2F0aW9uICs9IHBhdGg7XG4gIH1cbiAgbG9jYXRpb24gPSBsb2NhdGlvbi5yZXBsYWNlKCd7Zm9ybWF0fScsICdqc29uJyk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZWN1cml0eURlZmluaXRpb25zID0gZnVuY3Rpb24ob2JqLCBzd2FnZ2VyKSB7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHZhciBuYW1lO1xuICAgIGZvcihuYW1lIGluIG9iai5hdXRob3JpemF0aW9ucykge1xuICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB7fTtcbiAgICAgIHZhciBkZWZpbml0aW9uID0gb2JqLmF1dGhvcml6YXRpb25zW25hbWVdO1xuICAgICAgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdhcGlLZXknO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24uaW4gPSBkZWZpbml0aW9uLnBhc3NBcztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLmtleW5hbWUgfHwgbmFtZTtcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2Jhc2ljQXV0aCcpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYmFzaWNBdXRoJztcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nU2NvcGVzID0gZGVmaW5pdGlvbi5zY29wZXMgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSB7fTtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvcihpIGluIGV4aXN0aW5nU2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNjb3BlID0gZXhpc3RpbmdTY29wZXNbaV07XG4gICAgICAgICAgc2NvcGVzW3Njb3BlLnNjb3BlXSA9IHNjb3BlLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ29hdXRoMic7XG4gICAgICAgIGlmKGkgPiAwKSB7XG4gICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgfVxuICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMpIHtcbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQpIHtcbiAgICAgICAgICAgIHZhciBpbXBsaWNpdCA9IGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdDtcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2ltcGxpY2l0JztcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gaW1wbGljaXQubG9naW5FbmRwb2ludDtcbiAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXSkge1xuICAgICAgICAgICAgaWYoIXNlY3VyaXR5RGVmaW5pdGlvbi5mbG93KSB7XG4gICAgICAgICAgICAgIC8vIGNhbm5vdCBzZXQgaWYgZmxvdyBpcyBhbHJlYWR5IGRlZmluZWRcbiAgICAgICAgICAgICAgdmFyIGF1dGhDb2RlID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXTtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnYWNjZXNzQ29kZSc7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gYXV0aENvZGUudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24udG9rZW5VcmwgPSBhdXRoQ29kZS50b2tlbkVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zID0gc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnNbbmFtZV0gPSBzZWN1cml0eURlZmluaXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXBpSW5mbyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICAvLyBpbmZvIHNlY3Rpb25cbiAgaWYob2JqLmluZm8pIHtcbiAgICB2YXIgaW5mbyA9IG9iai5pbmZvO1xuICAgIHN3YWdnZXIuaW5mbyA9IHt9O1xuXG4gICAgaWYoaW5mby5jb250YWN0KSB7XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdCA9IHt9O1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QuZW1haWwgPSBpbmZvLmNvbnRhY3Q7XG4gICAgfVxuICAgIGlmKGluZm8uZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIuaW5mby5kZXNjcmlwdGlvbiA9IGluZm8uZGVzY3JpcHRpb247XG4gICAgfVxuICAgIGlmKGluZm8udGl0bGUpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50aXRsZSA9IGluZm8udGl0bGU7XG4gICAgfVxuICAgIGlmKGluZm8udGVybXNPZlNlcnZpY2VVcmwpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50ZXJtc09mU2VydmljZSA9IGluZm8udGVybXNPZlNlcnZpY2VVcmw7XG4gICAgfVxuICAgIGlmKGluZm8ubGljZW5zZSB8fCBpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgIHN3YWdnZXIubGljZW5zZSA9IHt9O1xuICAgICAgaWYoaW5mby5saWNlbnNlKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS5uYW1lID0gaW5mby5saWNlbnNlO1xuICAgICAgfVxuICAgICAgaWYoaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS51cmwgPSBpbmZvLmxpY2Vuc2VVcmw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCgnbWlzc2luZyBpbmZvIHNlY3Rpb24nKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgb2JqKSB7XG4gIGNhbGxiYWNrKG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nID0gcmVxdWlyZSgnLi4vaGVscGVycycpLmxvZztcbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJyksXG59O1xuXG52YXIgU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi4vc2NoZW1hLW1hcmt1cC5qcycpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcblxudmFyIE1vZGVsID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbiB8fCB7fTtcbiAgdGhpcy5pc0FycmF5ID0gZGVmaW5pdGlvbi50eXBlID09PSAnYXJyYXknO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBkZWZpbml0aW9uLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG1vZGVsUHJvcGVydHlNYWNybyB8fCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkuZGVmYXVsdDtcbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE5vdGUhICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcmVtb3ZlZCBpbiAyLjIueCFcbk1vZGVsLnByb3RvdHlwZS5jcmVhdGVKU09OU2FtcGxlID0gTW9kZWwucHJvdG90eXBlLmdldFNhbXBsZVZhbHVlID0gZnVuY3Rpb24gKG1vZGVsc1RvSWdub3JlKSB7XG4gIG1vZGVsc1RvSWdub3JlID0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgbW9kZWxzVG9JZ25vcmVbdGhpcy5uYW1lXSA9IHRoaXM7XG5cbiAgLy8gUmVzcG9uc2Ugc3VwcG9ydFxuICBpZiAodGhpcy5leGFtcGxlcyAmJiBfLmlzUGxhaW5PYmplY3QodGhpcy5leGFtcGxlcykgJiYgdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ107XG5cbiAgICBpZiAoXy5pc1N0cmluZyh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkpIHtcbiAgICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzO1xuICB9XG5cbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSFRNTCh0aGlzLm5hbWUsIHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG52YXIgT3BlcmF0aW9uID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyZW50LCBzY2hlbWUsIG9wZXJhdGlvbklkLCBodHRwTWV0aG9kLCBwYXRoLCBhcmdzLCBkZWZpbml0aW9ucywgbW9kZWxzLCBjbGllbnRBdXRob3JpemF0aW9ucykge1xuICB2YXIgZXJyb3JzID0gW107XG5cbiAgcGFyZW50ID0gcGFyZW50IHx8IHt9O1xuICBhcmdzID0gYXJncyB8fCB7fTtcblxuICBpZihwYXJlbnQgJiYgcGFyZW50Lm9wdGlvbnMpIHtcbiAgICB0aGlzLmNsaWVudCA9IHBhcmVudC5vcHRpb25zLmNsaWVudCB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvciB8fCBudWxsO1xuICB9XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLmJhc2VQYXRoID0gcGFyZW50LmJhc2VQYXRoIHx8ICcvJztcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuICB0aGlzLmNvbnN1bWVzID0gYXJncy5jb25zdW1lcyB8fCBwYXJlbnQuY29uc3VtZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMucHJvZHVjZXMgPSBhcmdzLnByb2R1Y2VzIHx8IHBhcmVudC5wcm9kdWNlcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5kZXByZWNhdGVkID0gYXJncy5kZXByZWNhdGVkO1xuICB0aGlzLmRlc2NyaXB0aW9uID0gYXJncy5kZXNjcmlwdGlvbjtcbiAgdGhpcy5ob3N0ID0gcGFyZW50Lmhvc3QgfHwgJ2xvY2FsaG9zdCc7XG4gIHRoaXMubWV0aG9kID0gKGh0dHBNZXRob2QgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgb3BlcmF0aW9uSWQgKyAnIGlzIG1pc3NpbmcgbWV0aG9kLicpKTtcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmlja25hbWUgPSAob3BlcmF0aW9uSWQgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbnMgbXVzdCBoYXZlIGEgbmlja25hbWUuJykpO1xuICB0aGlzLm9wZXJhdGlvbiA9IGFyZ3M7XG4gIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICB0aGlzLnBhcmFtZXRlcnMgPSBhcmdzICE9PSBudWxsID8gKGFyZ3MucGFyYW1ldGVycyB8fCBbXSkgOiB7fTtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucGF0aCA9IChwYXRoIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIHRoaXMubmlja25hbWUgKyAnIGlzIG1pc3NpbmcgcGF0aC4nKSk7XG4gIHRoaXMucmVzcG9uc2VzID0gKGFyZ3MucmVzcG9uc2VzIHx8IHt9KTtcbiAgdGhpcy5zY2hlbWUgPSBzY2hlbWUgfHwgcGFyZW50LnNjaGVtZSB8fCAnaHR0cCc7XG4gIHRoaXMuc2NoZW1lcyA9IGFyZ3Muc2NoZW1lcyB8fCBwYXJlbnQuc2NoZW1lcztcbiAgdGhpcy5zZWN1cml0eSA9IGFyZ3Muc2VjdXJpdHkgfHwgcGFyZW50LnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudHlwZSA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gcGFyZW50LnVzZUpRdWVyeTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gcGFyZW50LmVuYWJsZUNvb2tpZXM7XG4gIHRoaXMucGFyYW1ldGVyTWFjcm8gPSBwYXJlbnQucGFyYW1ldGVyTWFjcm8gfHwgZnVuY3Rpb24gKG9wZXJhdGlvbiwgcGFyYW1ldGVyKSB7XG4gICAgcmV0dXJuIHBhcmFtZXRlci5kZWZhdWx0O1xuICB9O1xuXG4gIHRoaXMuaW5saW5lTW9kZWxzID0gW107XG5cbiAgaWYgKHR5cGVvZiB0aGlzLmRlcHJlY2F0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoKHRoaXMuZGVwcmVjYXRlZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0cnVlJzogY2FzZSAneWVzJzogY2FzZSAnMSc6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ2ZhbHNlJzogY2FzZSAnbm8nOiBjYXNlICcwJzogY2FzZSBudWxsOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDogdGhpcy5kZXByZWNhdGVkID0gQm9vbGVhbih0aGlzLmRlcHJlY2F0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpLCBtb2RlbDtcblxuICBpZiAoZGVmaW5pdGlvbnMpIHtcbiAgICAvLyBhZGQgdG8gZ2xvYmFsIG1vZGVsc1xuICAgIHZhciBrZXk7XG5cbiAgICBmb3IgKGtleSBpbiBkZWZpbml0aW9ucykge1xuICAgICAgbW9kZWwgPSBuZXcgTW9kZWwoa2V5LCBkZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgcGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG5cbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGRlZmluaXRpb25zID0ge307XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgLy8gQWxsb3cgbWFjcm8gdG8gc2V0IHRoZSBkZWZhdWx0IHZhbHVlXG4gICAgcGFyYW0uZGVmYXVsdCA9IHRoaXMucGFyYW1ldGVyTWFjcm8odGhpcywgcGFyYW0pO1xuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIHBhcmFtLmlzTGlzdCA9IHRydWU7XG4gICAgICBwYXJhbS5hbGxvd011bHRpcGxlID0gdHJ1ZTtcbiAgICAgIC8vIHRoZSBlbnVtIGNhbiBiZSBkZWZpbmVkIGF0IHRoZSBpdGVtcyBsZXZlbFxuICAgICAgLy9pZiAocGFyYW0uaXRlbXMgJiYgcGFyYW0uaXRlbXMuZW51bSkge1xuICAgICAgLy8gIHBhcmFtWydlbnVtJ10gPSBwYXJhbS5pdGVtcy5lbnVtO1xuICAgICAgLy99XG4gICAgfVxuXG4gICAgdmFyIGlubmVyVHlwZSA9IHRoaXMuZ2V0VHlwZShwYXJhbSk7XG5cbiAgICBpZiAoaW5uZXJUeXBlICYmIGlubmVyVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgPT09ICdib29sZWFuJykge1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzID0ge307XG4gICAgICBwYXJhbS5pc0xpc3QgPSB0cnVlO1xuICAgICAgcGFyYW1bJ2VudW0nXSA9IFt0cnVlLCBmYWxzZV07IC8vIHVzZSBhY3R1YWwgcHJpbWl0aXZlc1xuICAgIH1cblxuICAgIGlmKHR5cGVvZiBwYXJhbVsneC1leGFtcGxlJ10gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgZCA9IHBhcmFtWyd4LWV4YW1wbGUnXTtcbiAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgIH1cbiAgICBpZihwYXJhbVsneC1leGFtcGxlcyddKSB7XG4gICAgICB2YXIgZCA9IHBhcmFtWyd4LWV4YW1wbGVzJ10uZGVmYXVsdDtcbiAgICAgIGlmKHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBwYXJhbS5kZWZhdWx0ID0gZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZW51bVZhbHVlcyA9IHBhcmFtWydlbnVtJ10gfHwgKHBhcmFtLml0ZW1zICYmIHBhcmFtLml0ZW1zWydlbnVtJ10pO1xuXG4gICAgaWYgKHR5cGVvZiBlbnVtVmFsdWVzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlkO1xuXG4gICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPSB7fTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy52YWx1ZXMgPSBbXTtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcyA9IFtdO1xuXG4gICAgICBmb3IgKGlkID0gMDsgaWQgPCBlbnVtVmFsdWVzLmxlbmd0aDsgaWQrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSBlbnVtVmFsdWVzW2lkXTtcbiAgICAgICAgdmFyIGlzRGVmYXVsdCA9ICh2YWx1ZSA9PT0gcGFyYW0uZGVmYXVsdCB8fCB2YWx1ZSsnJyA9PT0gcGFyYW0uZGVmYXVsdCk7XG5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgLy8gQWx3YXlzIGhhdmUgc3RyaW5nIGZvciBkZXNjcmlwdGl2ZSB2YWx1ZXMuLi4uXG4gICAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcy5kZXNjcmlwdGl2ZVZhbHVlcy5wdXNoKHt2YWx1ZSA6IHZhbHVlKycnLCBpc0RlZmF1bHQ6IGlzRGVmYXVsdH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBpbm5lclR5cGUgPSBbaW5uZXJUeXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBwYXJhbS5hbGxvd2FibGVWYWx1ZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGNhbid0IHNob3cgYXMgYSBsaXN0IGlmIG5vIHZhbHVlcyB0byBzZWxlY3QgZnJvbVxuICAgICAgICBkZWxldGUgcGFyYW0uaXNMaXN0O1xuICAgICAgICBkZWxldGUgcGFyYW0uYWxsb3dNdWx0aXBsZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYXJhbS5tb2RlbFNpZ25hdHVyZSA9IHt0eXBlOiBpbm5lclR5cGUsIGRlZmluaXRpb25zOiB0aGlzLm1vZGVsc307XG4gICAgcGFyYW0uc2lnbmF0dXJlID0gdGhpcy5nZXRNb2RlbFNpZ25hdHVyZShpbm5lclR5cGUsIHRoaXMubW9kZWxzKS50b1N0cmluZygpO1xuICAgIHBhcmFtLnNhbXBsZUpTT04gPSB0aGlzLmdldE1vZGVsU2FtcGxlSlNPTihpbm5lclR5cGUsIHRoaXMubW9kZWxzKTtcbiAgICBwYXJhbS5yZXNwb25zZUNsYXNzU2lnbmF0dXJlID0gcGFyYW0uc2lnbmF0dXJlO1xuICB9XG5cbiAgdmFyIGRlZmF1bHRSZXNwb25zZUNvZGUsIHJlc3BvbnNlLCByZXNwb25zZXMgPSB0aGlzLnJlc3BvbnNlcztcblxuICBpZiAocmVzcG9uc2VzWycyMDAnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDAnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDEnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDEnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDInXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDInXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDMnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDMnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwMyc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDQnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDQnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNCc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDUnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDUnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNSc7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWycyMDYnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWycyMDYnXTtcbiAgICBkZWZhdWx0UmVzcG9uc2VDb2RlID0gJzIwNic7XG4gIH0gZWxzZSBpZiAocmVzcG9uc2VzWydkZWZhdWx0J10pIHtcbiAgICByZXNwb25zZSA9IHJlc3BvbnNlc1snZGVmYXVsdCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnZGVmYXVsdCc7XG4gIH1cblxuICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uuc2NoZW1hKSB7XG4gICAgdmFyIHJlc29sdmVkTW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChyZXNwb25zZS5zY2hlbWEsIGRlZmluaXRpb25zKTtcbiAgICB2YXIgc3VjY2Vzc1Jlc3BvbnNlO1xuXG4gICAgZGVsZXRlIHJlc3BvbnNlc1tkZWZhdWx0UmVzcG9uc2VDb2RlXTtcblxuICAgIGlmIChyZXNvbHZlZE1vZGVsKSB7XG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNvbHZlZE1vZGVsO1xuICAgIH0gZWxzZSBpZiAoIXJlc3BvbnNlLnNjaGVtYS50eXBlIHx8IHJlc3BvbnNlLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyB8fCByZXNwb25zZS5zY2hlbWEudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgLy8gSW5saW5lIG1vZGVsXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSBuZXcgTW9kZWwodW5kZWZpbmVkLCByZXNwb25zZS5zY2hlbWEgfHwge30sIHRoaXMubW9kZWxzLCBwYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHJpbWl0aXZlXG4gICAgICB0aGlzLnN1Y2Nlc3NSZXNwb25zZSA9IHt9O1xuICAgICAgc3VjY2Vzc1Jlc3BvbnNlID0gdGhpcy5zdWNjZXNzUmVzcG9uc2VbZGVmYXVsdFJlc3BvbnNlQ29kZV0gPSByZXNwb25zZS5zY2hlbWE7XG4gICAgfVxuXG4gICAgaWYgKHN1Y2Nlc3NSZXNwb25zZSkge1xuICAgICAgLy8gQXR0YWNoIHJlc3BvbnNlIHByb3BlcnRpZXNcbiAgICAgIGlmIChyZXNwb25zZS5kZXNjcmlwdGlvbikge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuZGVzY3JpcHRpb24gPSByZXNwb25zZS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3BvbnNlLmV4YW1wbGVzKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5leGFtcGxlcyA9IHJlc3BvbnNlLmV4YW1wbGVzO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuaGVhZGVycykge1xuICAgICAgICBzdWNjZXNzUmVzcG9uc2UuaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gcmVzcG9uc2U7XG4gIH1cblxuICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAodGhpcy5yZXNvdXJjZSAmJiB0aGlzLnJlc291cmNlLmFwaSAmJiB0aGlzLnJlc291cmNlLmFwaS5mYWlsKSB7XG4gICAgICB0aGlzLnJlc291cmNlLmFwaS5mYWlsKGVycm9ycyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmlzRGVmYXVsdEFycmF5SXRlbVZhbHVlID0gZnVuY3Rpb24odmFsdWUsIHBhcmFtKSB7XG4gIGlmIChwYXJhbS5kZWZhdWx0ICYmIEFycmF5LmlzQXJyYXkocGFyYW0uZGVmYXVsdCkpIHtcbiAgICByZXR1cm4gcGFyYW0uZGVmYXVsdC5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSBwYXJhbS5kZWZhdWx0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKHBhcmFtKSB7XG4gIHZhciB0eXBlID0gcGFyYW0udHlwZTtcbiAgdmFyIGZvcm1hdCA9IHBhcmFtLmZvcm1hdDtcbiAgdmFyIGlzQXJyYXkgPSBmYWxzZTtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgIGlmIChmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZS10aW1lJztcbiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2RhdGUnKSB7XG4gICAgICBzdHIgPSAnZGF0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9ICdzdHJpbmcnO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpIHtcbiAgICBzdHIgPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2RvdWJsZScpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIHN0ciA9ICdib29sZWFuJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgaXNBcnJheSA9IHRydWU7XG5cbiAgICBpZiAocGFyYW0uaXRlbXMpIHtcbiAgICAgIHN0ciA9IHRoaXMuZ2V0VHlwZShwYXJhbS5pdGVtcyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdmaWxlJykge1xuICAgIHN0ciA9ICdmaWxlJztcbiAgfVxuXG4gIGlmIChwYXJhbS4kcmVmKSB7XG4gICAgc3RyID0gaGVscGVycy5zaW1wbGVSZWYocGFyYW0uJHJlZik7XG4gIH1cblxuICB2YXIgc2NoZW1hID0gcGFyYW0uc2NoZW1hO1xuXG4gIGlmIChzY2hlbWEpIHtcbiAgICB2YXIgcmVmID0gc2NoZW1hLiRyZWY7XG5cbiAgICBpZiAocmVmKSB7XG4gICAgICByZWYgPSBoZWxwZXJzLnNpbXBsZVJlZihyZWYpO1xuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICByZXR1cm4gWyByZWYgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIGlubGluZSBzY2hlbWEsIHdlIGFkZCBpdCBvdXIgaW50ZXJhbCBoYXNoIC0+IHdoaWNoIGdpdmVzIHVzIGl0J3MgSUQgKGludClcbiAgICAgIGlmKHNjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRJbmxpbmVNb2RlbChzY2hlbWEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0VHlwZShzY2hlbWEpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNBcnJheSkge1xuICAgIHJldHVybiBbIHN0ciBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG5cbi8qKlxuICogYWRkcyBhbiBpbmxpbmUgc2NoZW1hIChtb2RlbCkgdG8gYSBoYXNoLCB3aGVyZSB3ZSBjYW4gcmVmIGl0IGxhdGVyXG4gKiBAcGFyYW0ge29iamVjdH0gc2NoZW1hIGEgc2NoZW1hXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBJRCBvZiB0aGUgc2NoZW1hIGJlaW5nIGFkZGVkLCBvciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmFkZElubGluZU1vZGVsID0gZnVuY3Rpb24gKHNjaGVtYSkge1xuICB2YXIgbGVuID0gdGhpcy5pbmxpbmVNb2RlbHMubGVuZ3RoO1xuICB2YXIgbW9kZWwgPSB0aGlzLnJlc29sdmVNb2RlbChzY2hlbWEsIHt9KTtcbiAgaWYobW9kZWwpIHtcbiAgICB0aGlzLmlubGluZU1vZGVscy5wdXNoKG1vZGVsKTtcbiAgICByZXR1cm4gJ0lubGluZSBNb2RlbCAnK2xlbjsgLy8gcmV0dXJuIHN0cmluZyByZWYgb2YgdGhlIGlubGluZSBtb2RlbCAodXNlZCB3aXRoICNnZXRJbmxpbmVNb2RlbClcbiAgfVxuICByZXR1cm4gbnVsbDsgLy8gcmVwb3J0IGVycm9ycz9cbn07XG5cbi8qKlxuICogZ2V0cyB0aGUgaW50ZXJuYWwgcmVmIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IGlubGluZV9zdHIgYSBzdHJpbmcgcmVmZXJlbmNlIHRvIGFuIGlubGluZSBtb2RlbFxuICogQHJldHVybiB7TW9kZWx9IHRoZSBtb2RlbCBiZWluZyByZWZlcmVuY2VkLiBPciBudWxsXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gIGlmKC9eSW5saW5lIE1vZGVsIFxcZCskLy50ZXN0KGlubGluZVN0cikpIHtcbiAgICB2YXIgaWQgPSBwYXJzZUludChpbmxpbmVTdHIuc3Vic3RyKCdJbmxpbmUgTW9kZWwnLmxlbmd0aCkudHJpbSgpLDEwKTsgLy9cbiAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG4gIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gIHJldHVybiBudWxsO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5yZXNvbHZlTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hLCBkZWZpbml0aW9ucykge1xuICBpZiAodHlwZW9mIHNjaGVtYS4kcmVmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgcmVmID0gcmVmLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKGRlZmluaXRpb25zW3JlZl0pIHtcbiAgICAgIHJldHVybiBuZXcgTW9kZWwocmVmLCBkZWZpbml0aW9uc1tyZWZdLCB0aGlzLm1vZGVscywgdGhpcy5wYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG4gIC8vIHNjaGVtYSBtdXN0IGF0IGxlYXN0IGJlIGFuIG9iamVjdCB0byBnZXQgcmVzb2x2ZWQgdG8gYW4gaW5saW5lIE1vZGVsXG4gIH0gZWxzZSBpZiAoc2NoZW1hICYmIHR5cGVvZiBzY2hlbWEgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IF8uaXNVbmRlZmluZWQoc2NoZW1hLnR5cGUpKSkge1xuICAgIHJldHVybiBuZXcgTW9kZWwodW5kZWZpbmVkLCBzY2hlbWEsIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmhlbHAgPSBmdW5jdGlvbiAoZG9udFByaW50KSB7XG4gIHZhciBvdXQgPSB0aGlzLm5pY2tuYW1lICsgJzogJyArIHRoaXMuc3VtbWFyeSArICdcXG4nO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIHZhciB0eXBlSW5mbyA9IHBhcmFtLnNpZ25hdHVyZTtcblxuICAgIG91dCArPSAnXFxuICAqICcgKyBwYXJhbS5uYW1lICsgJyAoJyArIHR5cGVJbmZvICsgJyk6ICcgKyBwYXJhbS5kZXNjcmlwdGlvbjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZG9udFByaW50ID09PSAndW5kZWZpbmVkJykge1xuICAgIGhlbHBlcnMubG9nKG91dCk7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICB2YXIgaXNQcmltaXRpdmUsIGxpc3RUeXBlO1xuXG4gIGlmICh0eXBlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgdHlwZSA9IHR5cGVbMF07XG4gIH1cblxuICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgIHR5cGUgPSAndW5kZWZpbmVkJztcbiAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgfSBlbHNlIGlmIChkZWZpbml0aW9uc1t0eXBlXSl7XG4gICAgLy8gYSBtb2RlbCBkZWYgZXhpc3RzP1xuICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICBpc1ByaW1pdGl2ZSA9IGZhbHNlO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgIHR5cGUgPSB0aGlzLmdldElubGluZU1vZGVsKHR5cGUpOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIHtcbiAgICAvLyBXZSBkZWZhdWx0IHRvIHByaW1pdGl2ZVxuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpc1ByaW1pdGl2ZSkge1xuICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuICdBcnJheVsnICsgdHlwZSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlLmdldE1vY2tTaWduYXR1cmUoKSArICddJztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpO1xuICAgIH1cbiAgfVxufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc3VwcG9ydGVkU3VibWl0TWV0aG9kcyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMucGFyZW50LnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEhlYWRlclBhcmFtcyA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gIHZhciBoZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywge30pO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhlYWRlcnNbcGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGg7XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmVuY29kZVBhdGhQYXJhbSh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJykge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9ICc/JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnJic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdmFyIHFwID0gYXJnc1twYXJhbS5uYW1lXTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHFwKSkge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgcXApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0ocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oYXJnc1twYXJhbS5uYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVybCA9IHRoaXMuc2NoZW1lICsgJzovLycgKyB0aGlzLmhvc3Q7XG5cbiAgaWYgKHRoaXMuYmFzZVBhdGggIT09ICcvJykge1xuICAgIHVybCArPSB0aGlzLmJhc2VQYXRoO1xuICB9XG4gIHJldHVybiB1cmwgKyByZXF1ZXN0VXJsICsgcXVlcnlzdHJpbmc7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1pc3NpbmdQYXJhbXMgPSBmdW5jdGlvbiAoYXJncykge1xuICB2YXIgbWlzc2luZ1BhcmFtcyA9IFtdOyAvLyBjaGVjayByZXF1aXJlZCBwYXJhbXMsIHRyYWNrIHRoZSBvbmVzIHRoYXQgYXJlIG1pc3NpbmdcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IHRoaXMucGFyYW1ldGVyc1tpXTtcblxuICAgIGlmIChwYXJhbS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBtaXNzaW5nUGFyYW1zID0gcGFyYW0ubmFtZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWlzc2luZ1BhcmFtcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0Qm9keSA9IGZ1bmN0aW9uIChoZWFkZXJzLCBhcmdzLCBvcHRzKSB7XG4gIHZhciBmb3JtUGFyYW1zID0ge30sIGhhc0Zvcm1QYXJhbXMsIGJvZHksIGtleSwgdmFsdWUsIGhhc0JvZHkgPSBmYWxzZTtcblxuICAvLyBsb29rIGF0IGVhY2ggcGFyYW0gYW5kIHB1dCBmb3JtIHBhcmFtcyBpbiBhbiBvYmplY3RcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSBhcmdzW3BhcmFtLm5hbWVdO1xuICAgICAgICBoYXNGb3JtUGFyYW1zID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZihwYXJhbS5pbiA9PT0gJ2JvZHknKSB7XG4gICAgICAgIGhhc0JvZHkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIGJvZHkgaXMgbnVsbCBhbmQgaGFzQm9keSBpcyB0cnVlLCBBTkQgYSBKU09OIGJvZHkgaXMgcmVxdWVzdGVkLCBzZW5kIGVtcHR5IHt9XG4gIGlmKGhhc0JvZHkgJiYgdHlwZW9mIGJvZHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgaWYoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICBib2R5ID0gJ3t9JztcbiAgICB9XG4gIH1cblxuICB2YXIgaXNNdWx0aVBhcnQgPSBmYWxzZTtcbiAgaWYoaGVhZGVyc1snQ29udGVudC1UeXBlJ10gJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ10uaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID49IDApIHtcbiAgICBpc011bHRpUGFydCA9IHRydWU7XG4gIH1cblxuICAvLyBoYW5kbGUgZm9ybSBwYXJhbXNcbiAgaWYgKGhhc0Zvcm1QYXJhbXMgJiYgIWlzTXVsdGlQYXJ0KSB7XG4gICAgdmFyIGVuY29kZWQgPSAnJztcblxuICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgIHZhbHVlID0gZm9ybVBhcmFtc1trZXldO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAoZW5jb2RlZCAhPT0gJycpIHtcbiAgICAgICAgICBlbmNvZGVkICs9ICcmJztcbiAgICAgICAgfVxuXG4gICAgICAgIGVuY29kZWQgKz0gZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGJvZHkgPSBlbmNvZGVkO1xuICB9IGVsc2UgaWYgKGlzTXVsdGlQYXJ0KSB7XG4gICAgaWYgKG9wdHMudXNlSlF1ZXJ5KSB7XG4gICAgICB2YXIgYm9keVBhcmFtID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAgIGJvZHlQYXJhbS50eXBlID0gJ2Zvcm1EYXRhJztcblxuICAgICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgICB2YWx1ZSA9IGFyZ3Nba2V5XTtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIC8vIHJlcXVpcmVkIGZvciBqcXVlcnkgZmlsZSB1cGxvYWRcbiAgICAgICAgICBpZiAodmFsdWUudHlwZSA9PT0gJ2ZpbGUnICYmIHZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICBkZWxldGUgaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG5cbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJvZHkgPSBib2R5UGFyYW07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJvZHk7XG59O1xuXG4vKipcbiAqIGdldHMgc2FtcGxlIHJlc3BvbnNlIGZvciBhIHNpbmdsZSBvcGVyYXRpb25cbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0TW9kZWxTYW1wbGVKU09OID0gZnVuY3Rpb24gKHR5cGUsIG1vZGVscykge1xuICB2YXIgbGlzdFR5cGUsIHNhbXBsZUpzb24sIGlubmVyVHlwZTtcbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIGxpc3RUeXBlID0gKHR5cGUgaW5zdGFuY2VvZiBBcnJheSk7XG4gIGlubmVyVHlwZSA9IGxpc3RUeXBlID8gdHlwZVswXSA6IHR5cGU7XG5cbiAgaWYobW9kZWxzW2lubmVyVHlwZV0pIHtcbiAgICBzYW1wbGVKc29uID0gbW9kZWxzW2lubmVyVHlwZV0uY3JlYXRlSlNPTlNhbXBsZSgpO1xuICB9IGVsc2UgaWYgKHRoaXMuZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKSl7XG4gICAgc2FtcGxlSnNvbiA9IHRoaXMuZ2V0SW5saW5lTW9kZWwoaW5uZXJUeXBlKS5jcmVhdGVKU09OU2FtcGxlKCk7IC8vIG1heSByZXR1cm4gbnVsbCwgaWYgdHlwZSBpc24ndCBjb3JyZWN0XG4gIH1cblxuXG4gIGlmIChzYW1wbGVKc29uKSB7XG4gICAgc2FtcGxlSnNvbiA9IGxpc3RUeXBlID8gW3NhbXBsZUpzb25dIDogc2FtcGxlSnNvbjtcblxuICAgIGlmICh0eXBlb2Ygc2FtcGxlSnNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBzYW1wbGVKc29uO1xuICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdChzYW1wbGVKc29uKSkge1xuICAgICAgdmFyIHQgPSBzYW1wbGVKc29uO1xuXG4gICAgICBpZiAoc2FtcGxlSnNvbiBpbnN0YW5jZW9mIEFycmF5ICYmIHNhbXBsZUpzb24ubGVuZ3RoID4gMCkge1xuICAgICAgICB0ID0gc2FtcGxlSnNvblswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHQubm9kZU5hbWUgJiYgdHlwZW9mIHQgPT09ICdOb2RlJykge1xuICAgICAgICB2YXIgeG1sU3RyaW5nID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh0KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRYbWwoeG1sU3RyaW5nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShzYW1wbGVKc29uLCBudWxsLCAyKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIGxlZ2FjeSBiaW5kaW5nXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmRvID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMsIGNhbGxiYWNrLCBlcnJvciwgcGFyZW50KSB7XG4gIHJldHVybiB0aGlzLmV4ZWN1dGUoYXJncywgb3B0cywgY2FsbGJhY2ssIGVycm9yLCBwYXJlbnQpO1xufTtcblxuLyoqXG4gKiBleGVjdXRlcyBhbiBvcGVyYXRpb25cbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChhcmcxLCBhcmcyLCBhcmczLCBhcmc0LCBwYXJlbnQpIHtcbiAgdmFyIGFyZ3MgPSBhcmcxIHx8IHt9O1xuICB2YXIgb3B0cyA9IHt9LCBzdWNjZXNzLCBlcnJvciwgZGVmZXJyZWQ7XG5cbiAgaWYgKF8uaXNPYmplY3QoYXJnMikpIHtcbiAgICBvcHRzID0gYXJnMjtcbiAgICBzdWNjZXNzID0gYXJnMztcbiAgICBlcnJvciA9IGFyZzQ7XG4gIH1cblxuICBpZih0aGlzLmNsaWVudCkge1xuICAgIG9wdHMuY2xpZW50ID0gdGhpcy5jbGllbnQ7XG4gIH1cblxuICAvLyBhZGQgdGhlIHJlcXVlc3QgaW50ZXJjZXB0b3IgZnJvbSBwYXJlbnQsIGlmIG5vbmUgc2VudCBmcm9tIGNsaWVudFxuICBpZighb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgJiYgdGhpcy5yZXF1ZXN0SW50ZXJjZXB0b3IgKSB7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciA7XG4gIH1cblxuICBpZighb3B0cy5yZXNwb25zZUludGVyY2VwdG9yICYmIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN1Y2Nlc3MgPSBhcmcyO1xuICAgIGVycm9yID0gYXJnMztcbiAgfVxuXG4gIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgZGVmZXJyZWQgPSBRLmRlZmVyKCk7XG4gIH0gZWxzZSB7XG4gICAgc3VjY2VzcyA9IChzdWNjZXNzIHx8IHRoaXMucGFyZW50LmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICAgIGVycm9yID0gKGVycm9yIHx8IHRoaXMucGFyZW50LmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IGhlbHBlcnMubG9nKTtcbiAgfVxuXG5cbiAgaWYgKHR5cGVvZiBvcHRzLnVzZUpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRzLnVzZUpRdWVyeSA9IHRoaXMudXNlSlF1ZXJ5O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRzLmVuYWJsZUNvb2tpZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5lbmFibGVDb29raWVzID0gdGhpcy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSB0aGlzLmdldE1pc3NpbmdQYXJhbXMoYXJncyk7XG5cbiAgaWYgKG1pc3NpbmdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIHZhciBtZXNzYWdlID0gJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW1zOiAnICsgbWlzc2luZ1BhcmFtcztcblxuICAgIGhlbHBlcnMuZmFpbChtZXNzYWdlKTtcblxuICAgIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgICBkZWZlcnJlZC5yZWplY3QobWVzc2FnZSk7XG4gICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IobWVzc2FnZSwgcGFyZW50KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICB2YXIgYWxsSGVhZGVycyA9IHRoaXMuZ2V0SGVhZGVyUGFyYW1zKGFyZ3MpO1xuICB2YXIgY29udGVudFR5cGVIZWFkZXJzID0gdGhpcy5zZXRDb250ZW50VHlwZXMoYXJncywgb3B0cyk7XG4gIHZhciBoZWFkZXJzID0ge30sIGF0dHJuYW1lO1xuXG4gIGZvciAoYXR0cm5hbWUgaW4gYWxsSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGFsbEhlYWRlcnNbYXR0cm5hbWVdOyB9XG4gIGZvciAoYXR0cm5hbWUgaW4gY29udGVudFR5cGVIZWFkZXJzKSB7IGhlYWRlcnNbYXR0cm5hbWVdID0gY29udGVudFR5cGVIZWFkZXJzW2F0dHJuYW1lXTsgfVxuXG4gIHZhciBib2R5ID0gdGhpcy5nZXRCb2R5KGNvbnRlbnRUeXBlSGVhZGVycywgYXJncywgb3B0cyk7XG4gIHZhciB1cmwgPSB0aGlzLnVybGlmeShhcmdzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBkZWZlcnJlZDogZGVmZXJyZWQsXG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgICBjbGllbnRBdXRob3JpemF0aW9uczogb3B0cy5jbGllbnRBdXRob3JpemF0aW9ucyxcbiAgICBvbjoge1xuICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gc3VjY2VzcyhyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgICAgZGVmZXJyZWQucmVqZWN0KHJlc3BvbnNlKTtcbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3IocmVzcG9uc2UsIHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmosIHRoaXMub3BlcmF0aW9uLnNlY3VyaXR5KTtcbiAgaWYgKG9wdHMubW9jayA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBvYmo7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXRlbUJ5UHJpb3JpdHkoY29sLCBpdGVtUHJpb3JpdHkpIHtcblxuICAvLyBObyBwcmlvcml0aWVzPyByZXR1cm4gZmlyc3QuLi5cbiAgaWYoXy5pc0VtcHR5KGl0ZW1Qcmlvcml0eSkpIHtcbiAgICByZXR1cm4gY29sWzBdO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGl0ZW1Qcmlvcml0eS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmKGNvbC5pbmRleE9mKGl0ZW1Qcmlvcml0eVtpXSkgPiAtMSkge1xuICAgICAgcmV0dXJuIGl0ZW1Qcmlvcml0eVtpXTtcbiAgICB9XG4gIH1cblxuICAvLyBPdGhlcndpc2UgcmV0dXJuIGZpcnN0XG4gIHJldHVybiBjb2xbMF07XG59XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuc2V0Q29udGVudFR5cGVzID0gZnVuY3Rpb24gKGFyZ3MsIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCB0eXBlXG4gIHZhciBhbGxEZWZpbmVkUGFyYW1zID0gdGhpcy5wYXJhbWV0ZXJzO1xuICB2YXIgYm9keTtcbiAgdmFyIGNvbnN1bWVzID0gYXJncy5wYXJhbWV0ZXJDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLmNvbnN1bWVzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGFjY2VwdHMgPSBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgfHwgaXRlbUJ5UHJpb3JpdHkodGhpcy5wcm9kdWNlcywgWydhcHBsaWNhdGlvbi9qc29uJywgJ2FwcGxpY2F0aW9uL3lhbWwnXSk7XG4gIHZhciBkZWZpbmVkRmlsZVBhcmFtcyA9IFtdO1xuICB2YXIgZGVmaW5lZEZvcm1QYXJhbXMgPSBbXTtcbiAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgdmFyIGk7XG5cbiAgLy8gZ2V0IHBhcmFtcyBmcm9tIHRoZSBvcGVyYXRpb24gYW5kIHNldCB0aGVtIGluIGRlZmluZWRGaWxlUGFyYW1zLCBkZWZpbmVkRm9ybVBhcmFtcywgaGVhZGVyc1xuICBmb3IgKGkgPSAwOyBpIDwgYWxsRGVmaW5lZFBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJhbSA9IGFsbERlZmluZWRQYXJhbXNbaV07XG5cbiAgICBpZiAocGFyYW0uaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgIGlmIChwYXJhbS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgZGVmaW5lZEZpbGVQYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZpbmVkRm9ybVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJyAmJiBvcHRzKSB7XG4gICAgICB2YXIga2V5ID0gcGFyYW0ubmFtZTtcbiAgICAgIHZhciBoZWFkZXJWYWx1ZSA9IG9wdHNbcGFyYW0ubmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3B0c1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaGVhZGVyc1trZXldID0gaGVhZGVyVmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2JvZHknICYmIHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlcmUncyBhIGJvZHksIG5lZWQgdG8gc2V0IHRoZSBjb25zdW1lcyBoZWFkZXIgdmlhIHJlcXVlc3RDb250ZW50VHlwZVxuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcgfHxcbiAgICAgICgodGhpcy5tZXRob2QgPT09ICdkZWxldGUnIHx8IHRoaXMubWV0aG9kID09PSAnZ2V0JykgJiYgYm9keSkgKSB7XG4gICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7XG4gICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgIH1cbiAgICAvLyBpZiBhbnkgZm9ybSBwYXJhbXMsIGNvbnRlbnQgdHlwZSBtdXN0IGJlIHNldFxuICAgIGlmIChkZWZpbmVkRm9ybVBhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHsgICAgICAgICAgICAgLy8gb3ZlcnJpZGUgaWYgc2V0XG4gICAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgICB9IGVsc2UgaWYgKGRlZmluZWRGaWxlUGFyYW1zLmxlbmd0aCA+IDApIHsgLy8gaWYgYSBmaWxlLCBtdXN0IGJlIG11bHRpcGFydC9mb3JtLWRhdGFcbiAgICAgICAgY29uc3VtZXMgPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mcm9tLXVybGVuY29kZWRcbiAgICAgICAgY29uc3VtZXMgPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgY29uc3VtZXMgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNvbnN1bWVzICYmIHRoaXMuY29uc3VtZXMpIHtcbiAgICBpZiAodGhpcy5jb25zdW1lcy5pbmRleE9mKGNvbnN1bWVzKSA9PT0gLTEpIHtcbiAgICAgIGhlbHBlcnMubG9nKCdzZXJ2ZXIgZG9lc25cXCd0IGNvbnN1bWUgJyArIGNvbnN1bWVzICsgJywgdHJ5ICcgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbnN1bWVzKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0aGlzLm1hdGNoZXNBY2NlcHQoYWNjZXB0cykpIHtcbiAgICBoZWxwZXJzLmxvZygnc2VydmVyIGNhblxcJ3QgcHJvZHVjZSAnICsgYWNjZXB0cyk7XG4gIH1cblxuICBpZiAoKGNvbnN1bWVzICYmIGJvZHkgIT09ICcnKSB8fCAoY29uc3VtZXMgPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSkge1xuICAgIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gY29uc3VtZXM7XG4gIH1cblxuICBpZiAoYWNjZXB0cykge1xuICAgIGhlYWRlcnMuQWNjZXB0ID0gYWNjZXB0cztcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlcXVlc3QgYWNjZXB0cyBoZWFkZXIgbWF0Y2hlcyBhbnl0aGluZyBpbiB0aGlzLnByb2R1Y2VzLlxuICogIElmIHRoaXMucHJvZHVjZXMgY29udGFpbnMgKiAvICosIGlnbm9yZSB0aGUgYWNjZXB0IGhlYWRlci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzMSwgYXJnczIpIHtcbiAgdmFyIG9wdHMgPSB7bW9jazogdHJ1ZX07XG4gIGlmICh0eXBlb2YgYXJnczIgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yICh2YXIgYXJnS2V5IGluIGFyZ3MyKSB7XG4gICAgICBvcHRzW2FyZ0tleV0gPSBhcmdzMlthcmdLZXldO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqID0gdGhpcy5leGVjdXRlKGFyZ3MxLCBvcHRzKTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgcmVzdWx0cy5wdXNoKCctWCAnICsgdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSk7XG5cbiAgaWYgKHR5cGVvZiBvYmouaGVhZGVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9iai5oZWFkZXJzW2tleV07XG4gICAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKCctLWhlYWRlciBcXCcnICsga2V5ICsgJzogJyArIHZhbHVlICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHZhciBib2R5O1xuXG4gICAgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5ID0gb2JqLmJvZHk7XG4gICAgfVxuXG4gICAgcmVzdWx0cy5wdXNoKCctZCBcXCcnICsgYm9keS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpICsgJ1xcJycpO1xuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcXCcnICsgb2JqLnVybCArICdcXCcnO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoQ29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSkge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcbiAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJ1xcXFx0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAncGlwZXMnKSB7XG4gICAgc2VwYXJhdG9yID0gJ3wnO1xuICB9IGVsc2Uge1xuICAgIHNlcGFyYXRvciA9ICcsJztcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RlZCArPSBzZXBhcmF0b3IgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGVuY29kZWQgPSAnJztcbiAgdmFyIGk7XG5cbiAgaWYgKHR5cGUgPT09ICdkZWZhdWx0JyB8fCB0eXBlID09PSAnbXVsdGknKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSA+IDApIHtlbmNvZGVkICs9ICcmJzt9XG5cbiAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeVBhcmFtKG5hbWUpICsgJz0nICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gICAgaWYgKHR5cGUgPT09ICdjc3YnKSB7XG4gICAgICBzZXBhcmF0b3IgPSAnLCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJyUyMCc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAndHN2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJ1xcXFx0JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdwaXBlcycpIHtcbiAgICAgIHNlcGFyYXRvciA9ICd8JztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdicmFja2V0cycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSAhPT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgKz0gJyYnO1xuICAgICAgICB9XG5cbiAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0obmFtZSkgKyAnW109JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlcGFyYXRvciAhPT0gJycpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIGVuY29kZWQgPSB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0obmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbmNvZGVkO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeVBhcmFtID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGFyZyk7XG59O1xuXG4vKipcbiAqIFRPRE8gcmV2aXNpdCwgbWlnaHQgbm90IHdhbnQgdG8gbGVhdmUgJy8nXG4gKiovXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVBhdGhQYXJhbSA9IGZ1bmN0aW9uIChwYXRoUGFyYW0pIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChwYXRoUGFyYW0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE9wZXJhdGlvbkdyb3VwID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGFnLCBkZXNjcmlwdGlvbiwgZXh0ZXJuYWxEb2NzLCBvcGVyYXRpb24pIHtcbiAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uO1xuICB0aGlzLmV4dGVybmFsRG9jcyA9IGV4dGVybmFsRG9jcztcbiAgdGhpcy5uYW1lID0gdGFnO1xuICB0aGlzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbiAgdGhpcy5vcGVyYXRpb25zQXJyYXkgPSBbXTtcbiAgdGhpcy5wYXRoID0gdGFnO1xuICB0aGlzLnRhZyA9IHRhZztcbn07XG5cbk9wZXJhdGlvbkdyb3VwLnByb3RvdHlwZS5zb3J0ID0gZnVuY3Rpb24gKCkge1xuXG59O1xuXG4iLG51bGwsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKEJ1ZmZlcil7XG4oZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OWlkRzloTDJsdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpS0daMWJtTjBhVzl1SUNncElIdGNiaUFnWENKMWMyVWdjM1J5YVdOMFhDSTdYRzVjYmlBZ1puVnVZM1JwYjI0Z1luUnZZU2h6ZEhJcElIdGNiaUFnSUNCMllYSWdZblZtWm1WeVhHNGdJQ0FnSUNBN1hHNWNiaUFnSUNCcFppQW9jM1J5SUdsdWMzUmhibU5sYjJZZ1FuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCaWRXWm1aWElnUFNCemRISTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdKMVptWmxjaUE5SUc1bGR5QkNkV1ptWlhJb2MzUnlMblJ2VTNSeWFXNW5LQ2tzSUNkaWFXNWhjbmtuS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdZblZtWm1WeUxuUnZVM1J5YVc1bktDZGlZWE5sTmpRbktUdGNiaUFnZlZ4dVhHNGdJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblJ2WVR0Y2JuMG9LU2s3WEc0aVhYMD0iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJhciAoKSB7fVxuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgYXJyLmNvbnN0cnVjdG9yID0gQmFyXG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgYXJyLmNvbnN0cnVjdG9yID09PSBCYXIgJiYgLy8gY29uc3RydWN0b3IgY2FuIGJlIHNldFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gMFxuICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gICAgdGhhdC5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgZnJvbVBvb2wgPSBsZW5ndGggIT09IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSA+Pj4gMVxuICBpZiAoZnJvbVBvb2wpIHRoYXQucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIHZhciBpID0gMFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgYnJlYWtcblxuICAgICsraVxuICB9XG5cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdCBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHN0cmluZyA9ICcnICsgc3RyaW5nXG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAvLyBEZXByZWNhdGVkXG4gICAgICBjYXNlICdyYXcnOlxuICAgICAgY2FzZSAncmF3cyc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuLy8gYGdldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQgKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aCB8IDBcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgaWYgKG5ld0J1Zi5sZW5ndGgpIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRTdGFydClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gdG9BcnJheUJ1ZmZlciAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gX2F1Z21lbnQgKGFycikge1xuICBhcnIuY29uc3RydWN0b3IgPSBCdWZmZXJcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IHNldCBtZXRob2QgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWRcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuZXF1YWxzID0gQlAuZXF1YWxzXG4gIGFyci5jb21wYXJlID0gQlAuY29tcGFyZVxuICBhcnIuaW5kZXhPZiA9IEJQLmluZGV4T2ZcbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludExFID0gQlAucmVhZFVJbnRMRVxuICBhcnIucmVhZFVJbnRCRSA9IEJQLnJlYWRVSW50QkVcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50TEUgPSBCUC5yZWFkSW50TEVcbiAgYXJyLnJlYWRJbnRCRSA9IEJQLnJlYWRJbnRCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnRMRSA9IEJQLndyaXRlVUludExFXG4gIGFyci53cml0ZVVJbnRCRSA9IEJQLndyaXRlVUludEJFXG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnRMRSA9IEJQLndyaXRlSW50TEVcbiAgYXJyLndyaXRlSW50QkUgPSBCUC53cml0ZUludEJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gbGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCB8IDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBmdW5jdGlvbiBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVBY2Nlc3NJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbiB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSAhIXNlY3VyZTtcbiAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gISFzY3JpcHQ7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llQWNjZXNzSW5mbyA9IENvb2tpZUFjY2Vzc0luZm87XG5cbiAgICBmdW5jdGlvbiBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmIChjb29raWVzdHIgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb29raWVzdHI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gSW5maW5pdHk7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBTdHJpbmcocmVxdWVzdF9wYXRoIHx8IFwiL1wiKTtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbiB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gZmFsc2U7IC8vaG93IHRvIGRlZmluZSBkZWZhdWx0P1xuICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IGZhbHNlOyAvL2h0dHBvbmx5XG4gICAgICAgICAgICBpZiAoY29va2llc3RyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJzZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWUgPSBDb29raWU7XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBzdHIgPSBbdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlXTtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvbl9kYXRlICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJleHBpcmVzPVwiICsgKG5ldyBEYXRlKHRoaXMuZXhwaXJhdGlvbl9kYXRlKSkudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZG9tYWluKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImRvbWFpbj1cIiArIHRoaXMuZG9tYWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInBhdGg9XCIgKyB0aGlzLnBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlY3VyZSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJzZWN1cmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiaHR0cG9ubHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ci5qb2luKFwiOyBcIik7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWU7XG4gICAgfTtcblxuICAgIHZhciBjb29raWVfc3RyX3NwbGl0dGVyID0gL1s6XSg/PVxccypbYS16QS1aMC05X1xcLV0rXFxzKls9XSkvZztcbiAgICBDb29raWUucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gcGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoXCI7XCIpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzWzBdLm1hdGNoKC8oW149XSspPShbXFxzXFxTXSopLyksXG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXSxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl0sXG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IGtleTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzW2ldLm1hdGNoKC8oW149XSspKD86PShbXFxzXFxTXSopKT8vKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJodHRwb25seVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImV4cGlyZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtYmVyKERhdGUucGFyc2UodmFsdWUpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJkb21haW5cIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9ICEhdGhpcy5kb21haW47XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzZWN1cmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9wYXRoKSB7XG4gICAgICAgICAgICAgICB0aGlzLnBhdGggPSByZXF1ZXN0X3BhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZSgpLnBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQgJiYgYWNjZXNzX2luZm8uc2NyaXB0IHx8XG4gICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgJiYgIWFjY2Vzc19pbmZvLnNlY3VyZSB8fFxuICAgICAgICAgICAgICAgICF0aGlzLmNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5jb2xsaWRlc1dpdGggPSBmdW5jdGlvbiBjb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKCh0aGlzLnBhdGggJiYgIWFjY2Vzc19pbmZvLnBhdGgpIHx8ICh0aGlzLmRvbWFpbiAmJiAhYWNjZXNzX2luZm8uZG9tYWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKHRoaXMucGF0aCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHBsaWNpdF9wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZiggdGhpcy5wYXRoICkgIT09IDApIHtcbiAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY2Nlc3NfZG9tYWluID0gYWNjZXNzX2luZm8uZG9tYWluICYmIGFjY2Vzc19pbmZvLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgdmFyIGNvb2tpZV9kb21haW4gPSB0aGlzLmRvbWFpbiAmJiB0aGlzLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4gPT09IGFjY2Vzc19kb21haW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb29raWVfZG9tYWluKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3ZSBhbHJlYWR5IGNoZWNrZWQgaWYgdGhlIGRvbWFpbnMgd2VyZSBleGFjdGx5IHRoZSBzYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgd2lsZGNhcmQgPSBhY2Nlc3NfZG9tYWluLmluZGV4T2YoY29va2llX2RvbWFpbik7XG4gICAgICAgICAgICBpZiAod2lsZGNhcmQgPT09IC0xIHx8IHdpbGRjYXJkICE9PSBhY2Nlc3NfZG9tYWluLmxlbmd0aCAtIGNvb2tpZV9kb21haW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUphcigpIHtcbiAgICAgICAgdmFyIGNvb2tpZXMsIGNvb2tpZXNfbGlzdCwgY29sbGlkYWJsZV9jb29raWU7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llSmFyKSB7XG4gICAgICAgICAgICBjb29raWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgLy9uYW1lOiBbQ29va2llXVxuXG4gICAgICAgICAgICB0aGlzLnNldENvb2tpZSA9IGZ1bmN0aW9uIHNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZSA9IG5ldyBDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgY29va2llIGlmIHRoZSBzZXQgaXMgcGFzdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgICAgICAgICAgcmVtb3ZlID0gY29va2llLmV4cGlyYXRpb25fZGF0ZSA8PSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWVzW2Nvb2tpZS5uYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRhYmxlX2Nvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaWRhYmxlX2Nvb2tpZS5jb2xsaWRlc1dpdGgoY29va2llKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdFtpXSA9IGNvb2tpZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3QucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29va2llc1tjb29raWUubmFtZV0gPSBbY29va2llXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgY29va2llXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZSA9IGZ1bmN0aW9uIGdldENvb2tpZShjb29raWVfbmFtZSwgYWNjZXNzX2luZm8pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29va2llLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llX25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghY29va2llc19saXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXNfbGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb29raWUgPSBjb29raWVzX2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29raWVzX2xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChmdW5jdGlvbihpdGVtKXtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29va2llKGl0ZW0sIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zZXRDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NmdWwucHVzaChjb29raWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWNjZXNzZnVsO1xuICAgIH07XG59KCkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB5YW1sID0gcmVxdWlyZSgnLi9saWIvanMteWFtbC5qcycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0geWFtbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbG9hZGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2xvYWRlcicpO1xudmFyIGR1bXBlciA9IHJlcXVpcmUoJy4vanMteWFtbC9kdW1wZXInKTtcblxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uICcgKyBuYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCBjYW5ub3QgYmUgdXNlZC4nKTtcbiAgfTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTtcbm1vZHVsZS5leHBvcnRzLlNjaGVtYSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hJyk7XG5tb2R1bGUuZXhwb3J0cy5GQUlMU0FGRV9TQ0hFTUEgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZScpO1xubW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpO1xubW9kdWxlLmV4cG9ydHMuQ09SRV9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvY29yZScpO1xubW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgICAgICAgICAgPSBsb2FkZXIubG9hZDtcbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgICAgICAgICAgPSBsb2FkZXIubG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCAgICAgICAgID0gbG9hZGVyLnNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgICAgICAgICAgICA9IGR1bXBlci5kdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDtcbm1vZHVsZS5leHBvcnRzLllBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvZXhjZXB0aW9uJyk7XG5cbi8vIERlcHJlY2F0ZWQgc2NoZW1hIG5hbWVzIGZyb20gSlMtWUFNTCAyLjAueFxubW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5TQUZFX1NDSEVNQSAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cbi8vIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGZyb20gSlMtWUFNTCAxLngueFxubW9kdWxlLmV4cG9ydHMuc2NhbiAgICAgICAgICAgPSBkZXByZWNhdGVkKCdzY2FuJyk7XG5tb2R1bGUuZXhwb3J0cy5wYXJzZSAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3BhcnNlJyk7XG5tb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTtcbm1vZHVsZS5leHBvcnRzLmFkZENvbnN0cnVjdG9yID0gZGVwcmVjYXRlZCgnYWRkQ29uc3RydWN0b3InKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBpc05vdGhpbmcoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHN1YmplY3QpIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcpICYmIChzdWJqZWN0ICE9PSBudWxsKTtcbn1cblxuXG5mdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlcXVlbmNlKSkgcmV0dXJuIHNlcXVlbmNlO1xuICBlbHNlIGlmIChpc05vdGhpbmcoc2VxdWVuY2UpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfQ0FSUklBR0VfUkVUVVJOICAgICAgPSAweDBEOyAvKiBDUiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgID0gb3B0aW9uc1snc2NoZW1hJ10gfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5pbmRlbnQgICAgICA9IE1hdGgubWF4KDEsIChvcHRpb25zWydpbmRlbnQnXSB8fCAyKSk7XG4gIHRoaXMuc2tpcEludmFsaWQgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgID0gKGNvbW1vbi5pc05vdGhpbmcob3B0aW9uc1snZmxvd0xldmVsJ10pID8gLTEgOiBvcHRpb25zWydmbG93TGV2ZWwnXSk7XG4gIHRoaXMuc3R5bGVNYXAgICAgPSBjb21waWxlU3R5bGVNYXAodGhpcy5zY2hlbWEsIG9wdGlvbnNbJ3N0eWxlcyddIHx8IG51bGwpO1xuICB0aGlzLnNvcnRLZXlzICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcbiAgdGhpcy5saW5lV2lkdGggICA9IG9wdGlvbnNbJ2xpbmVXaWR0aCddIHx8IDgwO1xuICB0aGlzLm5vUmVmcyAgICAgID0gb3B0aW9uc1snbm9SZWZzJ10gfHwgZmFsc2U7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy5leHBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRFeHBsaWNpdDtcblxuICB0aGlzLnRhZyA9IG51bGw7XG4gIHRoaXMucmVzdWx0ID0gJyc7XG5cbiAgdGhpcy5kdXBsaWNhdGVzID0gW107XG4gIHRoaXMudXNlZER1cGxpY2F0ZXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBpbmRlbnRTdHJpbmcoc3RyaW5nLCBzcGFjZXMpIHtcbiAgdmFyIGluZCA9IGNvbW1vbi5yZXBlYXQoJyAnLCBzcGFjZXMpLFxuICAgICAgcG9zaXRpb24gPSAwLFxuICAgICAgbmV4dCA9IC0xLFxuICAgICAgcmVzdWx0ID0gJycsXG4gICAgICBsaW5lLFxuICAgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXh0ID0gc3RyaW5nLmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV4dCA9PT0gLTEpIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24pO1xuICAgICAgcG9zaXRpb24gPSBsZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zaXRpb24sIG5leHQgKyAxKTtcbiAgICAgIHBvc2l0aW9uID0gbmV4dCArIDE7XG4gICAgfVxuXG4gICAgaWYgKGxpbmUubGVuZ3RoICYmIGxpbmUgIT09ICdcXG4nKSByZXN1bHQgKz0gaW5kO1xuXG4gICAgcmVzdWx0ICs9IGxpbmU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZU5leHRMaW5lKHN0YXRlLCBsZXZlbCkge1xuICByZXR1cm4gJ1xcbicgKyBjb21tb24ucmVwZWF0KCcgJywgc3RhdGUuaW5kZW50ICogbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIHN0cikge1xuICB2YXIgaW5kZXgsIGxlbmd0aCwgdHlwZTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc3RhdGUuaW1wbGljaXRUeXBlcy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdHlwZSA9IHN0YXRlLmltcGxpY2l0VHlwZXNbaW5kZXhdO1xuXG4gICAgaWYgKHR5cGUucmVzb2x2ZShzdHIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIFN0cmluZ0J1aWxkZXIoc291cmNlKSB7XG4gIHRoaXMuc291cmNlID0gc291cmNlO1xuICB0aGlzLnJlc3VsdCA9ICcnO1xuICB0aGlzLmNoZWNrcG9pbnQgPSAwO1xufVxuXG5TdHJpbmdCdWlsZGVyLnByb3RvdHlwZS50YWtlVXBUbyA9IGZ1bmN0aW9uIChwb3NpdGlvbikge1xuICB2YXIgZXI7XG5cbiAgaWYgKHBvc2l0aW9uIDwgdGhpcy5jaGVja3BvaW50KSB7XG4gICAgZXIgPSBuZXcgRXJyb3IoJ3Bvc2l0aW9uIHNob3VsZCBiZSA+IGNoZWNrcG9pbnQnKTtcbiAgICBlci5wb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgIGVyLmNoZWNrcG9pbnQgPSB0aGlzLmNoZWNrcG9pbnQ7XG4gICAgdGhyb3cgZXI7XG4gIH1cblxuICB0aGlzLnJlc3VsdCArPSB0aGlzLnNvdXJjZS5zbGljZSh0aGlzLmNoZWNrcG9pbnQsIHBvc2l0aW9uKTtcbiAgdGhpcy5jaGVja3BvaW50ID0gcG9zaXRpb247XG4gIHJldHVybiB0aGlzO1xufTtcblxuU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZXNjYXBlQ2hhciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNoYXJhY3RlciwgZXNjO1xuXG4gIGNoYXJhY3RlciA9IHRoaXMuc291cmNlLmNoYXJDb2RlQXQodGhpcy5jaGVja3BvaW50KTtcbiAgZXNjID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyYWN0ZXJdIHx8IGVuY29kZUhleChjaGFyYWN0ZXIpO1xuICB0aGlzLnJlc3VsdCArPSBlc2M7XG4gIHRoaXMuY2hlY2twb2ludCArPSAxO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zb3VyY2UubGVuZ3RoID4gdGhpcy5jaGVja3BvaW50KSB7XG4gICAgdGhpcy50YWtlVXBUbyh0aGlzLnNvdXJjZS5sZW5ndGgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiB3cml0ZVNjYWxhcihzdGF0ZSwgb2JqZWN0LCBsZXZlbCwgaXNrZXkpIHtcbiAgdmFyIHNpbXBsZSwgZmlyc3QsIHNwYWNlV3JhcCwgZm9sZGVkLCBsaXRlcmFsLCBzaW5nbGUsIGRvdWJsZSxcbiAgICAgIHNhd0xpbmVGZWVkLCBsaW5lUG9zaXRpb24sIGxvbmdlc3RMaW5lLCBpbmRlbnQsIG1heCwgY2hhcmFjdGVyLFxuICAgICAgcG9zaXRpb24sIGVzY2FwZVNlcSwgaGV4RXNjLCBwcmV2aW91cywgbGluZUxlbmd0aCwgbW9kaWZpZXIsXG4gICAgICB0cmFpbGluZ0xpbmVCcmVha3MsIHJlc3VsdDtcblxuICBpZiAob2JqZWN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmR1bXAgPSBcIicnXCI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKERFUFJFQ0FURURfQk9PTEVBTlNfU1lOVEFYLmluZGV4T2Yob2JqZWN0KSAhPT0gLTEpIHtcbiAgICBzdGF0ZS5kdW1wID0gXCInXCIgKyBvYmplY3QgKyBcIidcIjtcbiAgICByZXR1cm47XG4gIH1cblxuICBzaW1wbGUgPSB0cnVlO1xuICBmaXJzdCA9IG9iamVjdC5sZW5ndGggPyBvYmplY3QuY2hhckNvZGVBdCgwKSA6IDA7XG4gIHNwYWNlV3JhcCA9IChDSEFSX1NQQUNFID09PSBmaXJzdCB8fFxuICAgICAgICAgICAgICAgQ0hBUl9TUEFDRSA9PT0gb2JqZWN0LmNoYXJDb2RlQXQob2JqZWN0Lmxlbmd0aCAtIDEpKTtcblxuICAvLyBTaW1wbGlmaWVkIGNoZWNrIGZvciByZXN0cmljdGVkIGZpcnN0IGNoYXJhY3RlcnNcbiAgLy8gaHR0cDovL3d3dy55YW1sLm9yZy9zcGVjLzEuMi9zcGVjLmh0bWwjbnMtcGxhaW4tZmlyc3QlMjhjJTI5XG4gIGlmIChDSEFSX01JTlVTICAgICAgICAgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX1FVRVNUSU9OICAgICAgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX0NPTU1FUkNJQUxfQVQgPT09IGZpcnN0IHx8XG4gICAgICBDSEFSX0dSQVZFX0FDQ0VOVCAgPT09IGZpcnN0KSB7XG4gICAgc2ltcGxlID0gZmFsc2U7XG4gIH1cblxuICAvLyBDYW4gb25seSB1c2UgPiBhbmQgfCBpZiBub3Qgd3JhcHBlZCBpbiBzcGFjZXMgb3IgaXMgbm90IGEga2V5LlxuICAvLyBBbHNvLCBkb24ndCB1c2UgaWYgaW4gZmxvdyBtb2RlLlxuICBpZiAoc3BhY2VXcmFwIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBzdGF0ZS5mbG93TGV2ZWwgPD0gbGV2ZWwpKSB7XG4gICAgaWYgKHNwYWNlV3JhcCkgc2ltcGxlID0gZmFsc2U7XG5cbiAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICBsaXRlcmFsID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgZm9sZGVkID0gIWlza2V5O1xuICAgIGxpdGVyYWwgPSAhaXNrZXk7XG4gIH1cblxuICBzaW5nbGUgPSB0cnVlO1xuICBkb3VibGUgPSBuZXcgU3RyaW5nQnVpbGRlcihvYmplY3QpO1xuXG4gIHNhd0xpbmVGZWVkID0gZmFsc2U7XG4gIGxpbmVQb3NpdGlvbiA9IDA7XG4gIGxvbmdlc3RMaW5lID0gMDtcblxuICBpbmRlbnQgPSBzdGF0ZS5pbmRlbnQgKiBsZXZlbDtcbiAgbWF4ID0gc3RhdGUubGluZVdpZHRoO1xuXG4gIC8vIFJlcGxhY2UgLTEgd2l0aCBiaWdnZXN0IGluZ2VnZXIgbnVtYmVyIGFjY29yZGluZyB0b1xuICAvLyBodHRwOi8vZWNtYTI2Mi01LmNvbS9FTFM1X0hUTUwuaHRtI1NlY3Rpb25fOC41XG4gIGlmIChtYXggPT09IC0xKSBtYXggPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4gIGlmIChpbmRlbnQgPCA0MCkgbWF4IC09IGluZGVudDtcbiAgZWxzZSBtYXggPSA0MDtcblxuICBmb3IgKHBvc2l0aW9uID0gMDsgcG9zaXRpb24gPCBvYmplY3QubGVuZ3RoOyBwb3NpdGlvbisrKSB7XG4gICAgY2hhcmFjdGVyID0gb2JqZWN0LmNoYXJDb2RlQXQocG9zaXRpb24pO1xuICAgIGlmIChzaW1wbGUpIHtcbiAgICAgIC8vIENoYXJhY3RlcnMgdGhhdCBjYW4gbmV2ZXIgYXBwZWFyIGluIHRoZSBzaW1wbGUgc2NhbGFyXG4gICAgICBpZiAoIXNpbXBsZUNoYXIoY2hhcmFjdGVyKSkge1xuICAgICAgICBzaW1wbGUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFN0aWxsIHNpbXBsZS4gIElmIHdlIG1ha2UgaXQgYWxsIHRoZSB3YXkgdGhyb3VnaCBsaWtlXG4gICAgICAgIC8vIHRoaXMsIHRoZW4gd2UgY2FuIGp1c3QgZHVtcCB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2luZ2xlICYmIGNoYXJhY3RlciA9PT0gQ0hBUl9TSU5HTEVfUVVPVEUpIHtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGVzY2FwZVNlcSA9IEVTQ0FQRV9TRVFVRU5DRVNbY2hhcmFjdGVyXTtcbiAgICBoZXhFc2MgPSBuZWVkc0hleEVzY2FwZShjaGFyYWN0ZXIpO1xuXG4gICAgaWYgKCFlc2NhcGVTZXEgJiYgIWhleEVzYykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9MSU5FX0ZFRUQgJiZcbiAgICAgICAgY2hhcmFjdGVyICE9PSBDSEFSX0RPVUJMRV9RVU9URSAmJlxuICAgICAgICBjaGFyYWN0ZXIgIT09IENIQVJfU0lOR0xFX1FVT1RFKSB7XG4gICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGNoYXJhY3RlciA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgIHNhd0xpbmVGZWVkID0gdHJ1ZTtcbiAgICAgIHNpbmdsZSA9IGZhbHNlO1xuICAgICAgaWYgKHBvc2l0aW9uID4gMCkge1xuICAgICAgICBwcmV2aW91cyA9IG9iamVjdC5jaGFyQ29kZUF0KHBvc2l0aW9uIC0gMSk7XG4gICAgICAgIGlmIChwcmV2aW91cyA9PT0gQ0hBUl9TUEFDRSkge1xuICAgICAgICAgIGxpdGVyYWwgPSBmYWxzZTtcbiAgICAgICAgICBmb2xkZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvbGRlZCkge1xuICAgICAgICBsaW5lTGVuZ3RoID0gcG9zaXRpb24gLSBsaW5lUG9zaXRpb247XG4gICAgICAgIGxpbmVQb3NpdGlvbiA9IHBvc2l0aW9uO1xuICAgICAgICBpZiAobGluZUxlbmd0aCA+IGxvbmdlc3RMaW5lKSBsb25nZXN0TGluZSA9IGxpbmVMZW5ndGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYXJhY3RlciAhPT0gQ0hBUl9ET1VCTEVfUVVPVEUpIHNpbmdsZSA9IGZhbHNlO1xuXG4gICAgZG91YmxlLnRha2VVcFRvKHBvc2l0aW9uKTtcbiAgICBkb3VibGUuZXNjYXBlQ2hhcigpO1xuICB9XG5cbiAgaWYgKHNpbXBsZSAmJiB0ZXN0SW1wbGljaXRSZXNvbHZpbmcoc3RhdGUsIG9iamVjdCkpIHNpbXBsZSA9IGZhbHNlO1xuXG4gIG1vZGlmaWVyID0gJyc7XG4gIGlmIChmb2xkZWQgfHwgbGl0ZXJhbCkge1xuICAgIHRyYWlsaW5nTGluZUJyZWFrcyA9IDA7XG4gICAgaWYgKG9iamVjdC5jaGFyQ29kZUF0KG9iamVjdC5sZW5ndGggLSAxKSA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgIHRyYWlsaW5nTGluZUJyZWFrcyArPSAxO1xuICAgICAgaWYgKG9iamVjdC5jaGFyQ29kZUF0KG9iamVjdC5sZW5ndGggLSAyKSA9PT0gQ0hBUl9MSU5FX0ZFRUQpIHtcbiAgICAgICAgdHJhaWxpbmdMaW5lQnJlYWtzICs9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRyYWlsaW5nTGluZUJyZWFrcyA9PT0gMCkgbW9kaWZpZXIgPSAnLSc7XG4gICAgZWxzZSBpZiAodHJhaWxpbmdMaW5lQnJlYWtzID09PSAyKSBtb2RpZmllciA9ICcrJztcbiAgfVxuXG4gIGlmIChsaXRlcmFsICYmIGxvbmdlc3RMaW5lIDwgbWF4IHx8IHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIGZvbGRlZCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgaXQncyBsaXRlcmFsbHkgb25lIGxpbmUsIHRoZW4gZG9uJ3QgYm90aGVyIHdpdGggdGhlIGxpdGVyYWwuXG4gIC8vIFdlIG1heSBzdGlsbCB3YW50IHRvIGRvIGEgZm9sZCwgdGhvdWdoLCBpZiBpdCdzIGEgc3VwZXIgbG9uZyBsaW5lLlxuICBpZiAoIXNhd0xpbmVGZWVkKSBsaXRlcmFsID0gZmFsc2U7XG5cbiAgaWYgKHNpbXBsZSkge1xuICAgIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG4gIH0gZWxzZSBpZiAoc2luZ2xlKSB7XG4gICAgc3RhdGUuZHVtcCA9ICdcXCcnICsgb2JqZWN0ICsgJ1xcJyc7XG4gIH0gZWxzZSBpZiAoZm9sZGVkKSB7XG4gICAgcmVzdWx0ID0gZm9sZChvYmplY3QsIG1heCk7XG4gICAgc3RhdGUuZHVtcCA9ICc+JyArIG1vZGlmaWVyICsgJ1xcbicgKyBpbmRlbnRTdHJpbmcocmVzdWx0LCBpbmRlbnQpO1xuICB9IGVsc2UgaWYgKGxpdGVyYWwpIHtcbiAgICBpZiAoIW1vZGlmaWVyKSBvYmplY3QgPSBvYmplY3QucmVwbGFjZSgvXFxuJC8sICcnKTtcbiAgICBzdGF0ZS5kdW1wID0gJ3wnICsgbW9kaWZpZXIgKyAnXFxuJyArIGluZGVudFN0cmluZyhvYmplY3QsIGluZGVudCk7XG4gIH0gZWxzZSBpZiAoZG91YmxlKSB7XG4gICAgZG91YmxlLmZpbmlzaCgpO1xuICAgIHN0YXRlLmR1bXAgPSAnXCInICsgZG91YmxlLnJlc3VsdCArICdcIic7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZHVtcCBzY2FsYXIgdmFsdWUnKTtcbiAgfVxuXG4gIHJldHVybjtcbn1cblxuLy8gVGhlIGB0cmFpbGluZ2AgdmFyIGlzIGEgcmVnZXhwIG1hdGNoIG9mIGFueSB0cmFpbGluZyBgXFxuYCBjaGFyYWN0ZXJzLlxuLy9cbi8vIFRoZXJlIGFyZSB0aHJlZSBjYXNlcyB3ZSBjYXJlIGFib3V0OlxuLy9cbi8vIDEuIE9uZSB0cmFpbGluZyBgXFxuYCBvbiB0aGUgc3RyaW5nLiAgSnVzdCB1c2UgYHxgIG9yIGA+YC5cbi8vICAgIFRoaXMgaXMgdGhlIGFzc3VtZWQgZGVmYXVsdC4gKHRyYWlsaW5nID0gbnVsbClcbi8vIDIuIE5vIHRyYWlsaW5nIGBcXG5gIG9uIHRoZSBzdHJpbmcuICBVc2UgYHwtYCBvciBgPi1gIHRvIFwiY2hvbXBcIiB0aGUgZW5kLlxuLy8gMy4gTW9yZSB0aGFuIG9uZSB0cmFpbGluZyBgXFxuYCBvbiB0aGUgc3RyaW5nLiAgVXNlIGB8K2Agb3IgYD4rYC5cbi8vXG4vLyBJbiB0aGUgY2FzZSBvZiBgPitgLCB0aGVzZSBsaW5lIGJyZWFrcyBhcmUgKm5vdCogZG91YmxlZCAobGlrZSB0aGUgbGluZVxuLy8gYnJlYWtzIHdpdGhpbiB0aGUgc3RyaW5nKSwgc28gaXQncyBpbXBvcnRhbnQgdG8gb25seSBlbmQgd2l0aCB0aGUgZXhhY3Rcbi8vIHNhbWUgbnVtYmVyIGFzIHdlIHN0YXJ0ZWQuXG5mdW5jdGlvbiBmb2xkKG9iamVjdCwgbWF4KSB7XG4gIHZhciByZXN1bHQgPSAnJyxcbiAgICAgIHBvc2l0aW9uID0gMCxcbiAgICAgIGxlbmd0aCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICB0cmFpbGluZyA9IC9cXG4rJC8uZXhlYyhvYmplY3QpLFxuICAgICAgbmV3TGluZTtcblxuICBpZiAodHJhaWxpbmcpIHtcbiAgICBsZW5ndGggPSB0cmFpbGluZy5pbmRleCArIDE7XG4gIH1cblxuICB3aGlsZSAocG9zaXRpb24gPCBsZW5ndGgpIHtcbiAgICBuZXdMaW5lID0gb2JqZWN0LmluZGV4T2YoJ1xcbicsIHBvc2l0aW9uKTtcbiAgICBpZiAobmV3TGluZSA+IGxlbmd0aCB8fCBuZXdMaW5lID09PSAtMSkge1xuICAgICAgaWYgKHJlc3VsdCkgcmVzdWx0ICs9ICdcXG5cXG4nO1xuICAgICAgcmVzdWx0ICs9IGZvbGRMaW5lKG9iamVjdC5zbGljZShwb3NpdGlvbiwgbGVuZ3RoKSwgbWF4KTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZXN1bHQpIHJlc3VsdCArPSAnXFxuXFxuJztcbiAgICAgIHJlc3VsdCArPSBmb2xkTGluZShvYmplY3Quc2xpY2UocG9zaXRpb24sIG5ld0xpbmUpLCBtYXgpO1xuICAgICAgcG9zaXRpb24gPSBuZXdMaW5lICsgMTtcbiAgICB9XG4gIH1cblxuICBpZiAodHJhaWxpbmcgJiYgdHJhaWxpbmdbMF0gIT09ICdcXG4nKSByZXN1bHQgKz0gdHJhaWxpbmdbMF07XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZm9sZExpbmUobGluZSwgbWF4KSB7XG4gIGlmIChsaW5lID09PSAnJykgcmV0dXJuIGxpbmU7XG5cbiAgdmFyIGZvbGRSZSA9IC9bXlxcc10gW15cXHNdL2csXG4gICAgICByZXN1bHQgPSAnJyxcbiAgICAgIHByZXZNYXRjaCA9IDAsXG4gICAgICBmb2xkU3RhcnQgPSAwLFxuICAgICAgbWF0Y2ggPSBmb2xkUmUuZXhlYyhsaW5lKSxcbiAgICAgIGluZGV4LFxuICAgICAgZm9sZEVuZCxcbiAgICAgIGZvbGRlZDtcblxuICB3aGlsZSAobWF0Y2gpIHtcbiAgICBpbmRleCA9IG1hdGNoLmluZGV4O1xuXG4gICAgLy8gd2hlbiB3ZSBjcm9zcyB0aGUgbWF4IGxlbiwgaWYgdGhlIHByZXZpb3VzIG1hdGNoIHdvdWxkJ3ZlXG4gICAgLy8gYmVlbiBvaywgdXNlIHRoYXQgb25lLCBhbmQgY2Fycnkgb24uICBJZiB0aGVyZSB3YXMgbm8gcHJldmlvdXNcbiAgICAvLyBtYXRjaCBvbiB0aGlzIGZvbGQgc2VjdGlvbiwgdGhlbiBqdXN0IGhhdmUgYSBsb25nIGxpbmUuXG4gICAgaWYgKGluZGV4IC0gZm9sZFN0YXJ0ID4gbWF4KSB7XG4gICAgICBpZiAocHJldk1hdGNoICE9PSBmb2xkU3RhcnQpIGZvbGRFbmQgPSBwcmV2TWF0Y2g7XG4gICAgICBlbHNlIGZvbGRFbmQgPSBpbmRleDtcblxuICAgICAgaWYgKHJlc3VsdCkgcmVzdWx0ICs9ICdcXG4nO1xuICAgICAgZm9sZGVkID0gbGluZS5zbGljZShmb2xkU3RhcnQsIGZvbGRFbmQpO1xuICAgICAgcmVzdWx0ICs9IGZvbGRlZDtcbiAgICAgIGZvbGRTdGFydCA9IGZvbGRFbmQgKyAxO1xuICAgIH1cbiAgICBwcmV2TWF0Y2ggPSBpbmRleCArIDE7XG4gICAgbWF0Y2ggPSBmb2xkUmUuZXhlYyhsaW5lKTtcbiAgfVxuXG4gIGlmIChyZXN1bHQpIHJlc3VsdCArPSAnXFxuJztcblxuICAvLyBpZiB3ZSBlbmQgdXAgd2l0aCBvbmUgbGFzdCB3b3JkIGF0IHRoZSBlbmQsIHRoZW4gdGhlIGxhc3QgYml0IG1pZ2h0XG4gIC8vIGJlIHNsaWdodGx5IGJpZ2dlciB0aGFuIHdlIHdhbnRlZCwgYmVjYXVzZSB3ZSBleGl0ZWQgb3V0IG9mIHRoZSBsb29wLlxuICBpZiAoZm9sZFN0YXJ0ICE9PSBwcmV2TWF0Y2ggJiYgbGluZS5sZW5ndGggLSBmb2xkU3RhcnQgPiBtYXgpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShmb2xkU3RhcnQsIHByZXZNYXRjaCkgKyAnXFxuJyArXG4gICAgICAgICAgICAgIGxpbmUuc2xpY2UocHJldk1hdGNoICsgMSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ICs9IGxpbmUuc2xpY2UoZm9sZFN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBjaGFyYWN0ZXIgY2FuIGJlIGZvdW5kIGluIGEgc2ltcGxlIHNjYWxhclxuZnVuY3Rpb24gc2ltcGxlQ2hhcihjaGFyYWN0ZXIpIHtcbiAgcmV0dXJuIENIQVJfVEFCICAgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MSU5FX0ZFRUQgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NBUlJJQUdFX1JFVFVSTiAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9MRUZUX1NRVUFSRV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9SSUdIVF9DVVJMWV9CUkFDS0VUICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NIQVJQICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9BU1RFUklTSyAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0VYQ0xBTUFUSU9OICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfVkVSVElDQUxfTElORSAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9HUkVBVEVSX1RIQU4gICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX1NJTkdMRV9RVU9URSAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgIENIQVJfRE9VQkxFX1FVT1RFICAgICAgICAgIT09IGNoYXJhY3RlciAmJlxuICAgICAgICAgQ0hBUl9QRVJDRU5UICAgICAgICAgICAgICAhPT0gY2hhcmFjdGVyICYmXG4gICAgICAgICBDSEFSX0NPTE9OICAgICAgICAgICAgICAgICE9PSBjaGFyYWN0ZXIgJiZcbiAgICAgICAgICFFU0NBUEVfU0VRVUVOQ0VTW2NoYXJhY3Rlcl0gICAgICAgICAgICAmJlxuICAgICAgICAgIW5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcik7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNvZGUgbmVlZHMgdG8gYmUgZXNjYXBlZC5cbmZ1bmN0aW9uIG5lZWRzSGV4RXNjYXBlKGNoYXJhY3Rlcikge1xuICByZXR1cm4gISgoMHgwMDAyMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDAwMDdFKSB8fFxuICAgICAgICAgICAoY2hhcmFjdGVyID09PSAweDAwMDg1KSAgICAgICAgICAgICAgICAgICAgICAgICB8fFxuICAgICAgICAgICAoMHgwMDBBMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBEN0ZGKSB8fFxuICAgICAgICAgICAoMHgwRTAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MDBGRkZEKSB8fFxuICAgICAgICAgICAoMHgxMDAwMCA8PSBjaGFyYWN0ZXIgJiYgY2hhcmFjdGVyIDw9IDB4MTBGRkZGKSk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKGluZGV4ICE9PSAwKSBfcmVzdWx0ICs9ICcsICc7XG4gICAgICBfcmVzdWx0ICs9IHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCA9ICcnLFxuICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZyxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIC8vIFdyaXRlIG9ubHkgdmFsaWQgZWxlbWVudHMuXG4gICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkge1xuICAgICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICAgIF9yZXN1bHQgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgX3Jlc3VsdCArPSAnLSAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoaW5kZXggIT09IDApIHBhaXJCdWZmZXIgKz0gJywgJztcblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkgcGFpckJ1ZmZlciArPSAnPyAnO1xuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgJzogJztcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0VmFsdWUsIGZhbHNlLCBmYWxzZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ3snICsgX3Jlc3VsdCArICd9Jztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QsIGNvbXBhY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBleHBsaWNpdFBhaXIsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIC8vIEFsbG93IHNvcnRpbmcga2V5cyBzbyB0aGF0IHRoZSBvdXRwdXQgZmlsZSBpcyBkZXRlcm1pbmlzdGljXG4gIGlmIChzdGF0ZS5zb3J0S2V5cyA9PT0gdHJ1ZSkge1xuICAgIC8vIERlZmF1bHQgc29ydGluZ1xuICAgIG9iamVjdEtleUxpc3Quc29ydCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0ZS5zb3J0S2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEN1c3RvbSBzb3J0IGZ1bmN0aW9uXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KHN0YXRlLnNvcnRLZXlzKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5zb3J0S2V5cykge1xuICAgIC8vIFNvbWV0aGluZyBpcyB3cm9uZ1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpckJ1ZmZlciA9ICcnO1xuXG4gICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBvYmplY3RLZXkgPSBvYmplY3RLZXlMaXN0W2luZGV4XTtcbiAgICBvYmplY3RWYWx1ZSA9IG9iamVjdFtvYmplY3RLZXldO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0S2V5LCB0cnVlLCB0cnVlLCB0cnVlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXkuXG4gICAgfVxuXG4gICAgZXhwbGljaXRQYWlyID0gKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHxcbiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RWYWx1ZSwgdHJ1ZSwgZXhwbGljaXRQYWlyKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6JztcbiAgICB9IGVsc2Uge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOiAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9IF9yZXN1bHQgfHwgJ3t9JzsgLy8gRW1wdHkgbWFwcGluZyBpZiBubyB2YWxpZCBwYWlycy5cbn1cblxuZnVuY3Rpb24gZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCBleHBsaWNpdCkge1xuICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlO1xuXG4gIHR5cGVMaXN0ID0gZXhwbGljaXQgPyBzdGF0ZS5leHBsaWNpdFR5cGVzIDogc3RhdGUuaW1wbGljaXRUeXBlcztcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdHlwZUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSB0eXBlTGlzdFtpbmRleF07XG5cbiAgICBpZiAoKHR5cGUuaW5zdGFuY2VPZiAgfHwgdHlwZS5wcmVkaWNhdGUpICYmXG4gICAgICAgICghdHlwZS5pbnN0YW5jZU9mIHx8ICgodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpICYmIChvYmplY3QgaW5zdGFuY2VvZiB0eXBlLmluc3RhbmNlT2YpKSkgJiZcbiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHtcblxuICAgICAgc3RhdGUudGFnID0gZXhwbGljaXQgPyB0eXBlLnRhZyA6ICc/JztcblxuICAgICAgaWYgKHR5cGUucmVwcmVzZW50KSB7XG4gICAgICAgIHN0eWxlID0gc3RhdGUuc3R5bGVNYXBbdHlwZS50YWddIHx8IHR5cGUuZGVmYXVsdFN0eWxlO1xuXG4gICAgICAgIGlmIChfdG9TdHJpbmcuY2FsbCh0eXBlLnJlcHJlc2VudCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnQob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudFtzdHlsZV0ob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90IFwiJyArIHN0eWxlICsgJ1wiIHN0eWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kdW1wID0gX3Jlc3VsdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTZXJpYWxpemVzIGBvYmplY3RgIGFuZCB3cml0ZXMgaXQgdG8gZ2xvYmFsIGByZXN1bHRgLlxuLy8gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIG9yIGZhbHNlIG9uIGludmFsaWQgb2JqZWN0LlxuLy9cbmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKHN0YXRlLmZsb3dMZXZlbCA8IDAgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgdmFyIG9iamVjdE9yQXJyYXkgPSB0eXBlID09PSAnW29iamVjdCBPYmplY3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgZHVwbGljYXRlSW5kZXgsXG4gICAgICBkdXBsaWNhdGU7XG5cbiAgaWYgKG9iamVjdE9yQXJyYXkpIHtcbiAgICBkdXBsaWNhdGVJbmRleCA9IHN0YXRlLmR1cGxpY2F0ZXMuaW5kZXhPZihvYmplY3QpO1xuICAgIGR1cGxpY2F0ZSA9IGR1cGxpY2F0ZUluZGV4ICE9PSAtMTtcbiAgfVxuXG4gIGlmICgoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fCBkdXBsaWNhdGUgfHwgKHN0YXRlLmluZGVudCAhPT0gMiAmJiBsZXZlbCA+IDApKSB7XG4gICAgY29tcGFjdCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICBzdGF0ZS5kdW1wID0gJypyZWZfJyArIGR1cGxpY2F0ZUluZGV4O1xuICB9IGVsc2Uge1xuICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7XG4gICAgICBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoT2JqZWN0LmtleXMoc3RhdGUuZHVtcCkubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wKTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICBpZiAoYmxvY2sgJiYgKHN0YXRlLmR1bXAubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrU2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XG4gICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsLCBpc2tleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5za2lwSW52YWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3VuYWNjZXB0YWJsZSBraW5kIG9mIGFuIG9iamVjdCB0byBkdW1wICcgKyB0eXBlKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB7XG4gICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXREdXBsaWNhdGVSZWZlcmVuY2VzKG9iamVjdCwgc3RhdGUpIHtcbiAgdmFyIG9iamVjdHMgPSBbXSxcbiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHN0YXRlLmR1cGxpY2F0ZXMucHVzaChvYmplY3RzW2R1cGxpY2F0ZXNJbmRleGVzW2luZGV4XV0pO1xuICB9XG4gIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHtcbiAgdmFyIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAob2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoZHVwbGljYXRlc0luZGV4ZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5ub1JlZnMpIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMoaW5wdXQsIHN0YXRlKTtcblxuICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIvLyBZQU1MIGVycm9yIGNsYXNzLiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg0NTg5ODRcbi8vXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFlBTUxFeGNlcHRpb24ocmVhc29uLCBtYXJrKSB7XG4gIC8vIFN1cGVyIGNvbnN0cnVjdG9yXG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgLy8gSW5jbHVkZSBzdGFjayB0cmFjZSBpbiBlcnJvciBvYmplY3RcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgLy8gQ2hyb21lIGFuZCBOb2RlSlNcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGRiwgSUUgMTArIGFuZCBTYWZhcmkgNisuIEZhbGxiYWNrIGZvciBvdGhlcnNcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjayB8fCAnJztcbiAgfVxuXG4gIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJztcbiAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIHRoaXMubWFyayA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpO1xufVxuXG5cbi8vIEluaGVyaXQgZnJvbSBFcnJvclxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFlBTUxFeGNlcHRpb247XG5cblxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnO1xuXG4gIHJlc3VsdCArPSB0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKSc7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gYyA9PT0gMHgyQy8qICwgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUIvKiBbICovIHx8XG4gICAgICAgICBjID09PSAweDVELyogXSAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3Qi8qIHsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4N0QvKiB9ICovO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlO1xuICB0aGlzLmxpc3RlbmVyICA9IG9wdGlvbnNbJ2xpc3RlbmVyJ10gIHx8IG51bGw7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy50eXBlTWFwICAgICAgID0gdGhpcy5zY2hlbWEuY29tcGlsZWRUeXBlTWFwO1xuXG4gIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDtcbiAgdGhpcy5wb3NpdGlvbiAgID0gMDtcbiAgdGhpcy5saW5lICAgICAgID0gMDtcbiAgdGhpcy5saW5lU3RhcnQgID0gMDtcbiAgdGhpcy5saW5lSW5kZW50ID0gMDtcblxuICB0aGlzLmRvY3VtZW50cyA9IFtdO1xuXG4gIC8qXG4gIHRoaXMudmVyc2lvbjtcbiAgdGhpcy5jaGVja0xpbmVCcmVha3M7XG4gIHRoaXMudGFnTWFwO1xuICB0aGlzLmFuY2hvck1hcDtcbiAgdGhpcy50YWc7XG4gIHRoaXMuYW5jaG9yO1xuICB0aGlzLmtpbmQ7XG4gIHRoaXMucmVzdWx0OyovXG5cbn1cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHJldHVybiBuZXcgWUFNTEV4Y2VwdGlvbihcbiAgICBtZXNzYWdlLFxuICAgIG5ldyBNYXJrKHN0YXRlLmZpbGVuYW1lLCBzdGF0ZS5pbnB1dCwgc3RhdGUucG9zaXRpb24sIHN0YXRlLmxpbmUsIChzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydCkpKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICB0aHJvdyBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dXYXJuaW5nKHN0YXRlLCBtZXNzYWdlKSB7XG4gIGlmIChzdGF0ZS5vbldhcm5pbmcpIHtcbiAgICBzdGF0ZS5vbldhcm5pbmcuY2FsbChudWxsLCBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSk7XG4gIH1cbn1cblxuXG52YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7XG5cbiAgWUFNTDogZnVuY3Rpb24gaGFuZGxlWWFtbERpcmVjdGl2ZShzdGF0ZSwgbmFtZSwgYXJncykge1xuXG4gICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mICVZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1lBTUwgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBtYXRjaCA9IC9eKFswLTldKylcXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7XG5cbiAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBpZiAobWFqb3IgIT09IDEpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpO1xuICAgIH1cblxuICAgIHN0YXRlLnZlcnNpb24gPSBhcmdzWzBdO1xuICAgIHN0YXRlLmNoZWNrTGluZUJyZWFrcyA9IChtaW5vciA8IDIpO1xuXG4gICAgaWYgKG1pbm9yICE9PSAxICYmIG1pbm9yICE9PSAyKSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bnN1cHBvcnRlZCBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgaGFuZGxlLCBwcmVmaXg7XG5cbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgfVxuXG4gICAgaGFuZGxlID0gYXJnc1swXTtcbiAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdChoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlcmUgaXMgYSBwcmV2aW91c2x5IGRlY2xhcmVkIHN1ZmZpeCBmb3IgXCInICsgaGFuZGxlICsgJ1wiIHRhZyBoYW5kbGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBwcmVmaXggKHNlY29uZCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS50YWdNYXBbaGFuZGxlXSA9IHByZWZpeDtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7XG4gIHZhciBfcG9zaXRpb24sIF9sZW5ndGgsIF9jaGFyYWN0ZXIsIF9yZXN1bHQ7XG5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgX3Jlc3VsdCA9IHN0YXRlLmlucHV0LnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKGNoZWNrSnNvbikge1xuICAgICAgZm9yIChfcG9zaXRpb24gPSAwLCBfbGVuZ3RoID0gX3Jlc3VsdC5sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiA8IF9sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiArPSAxKSB7XG4gICAgICAgIF9jaGFyYWN0ZXIgPSBfcmVzdWx0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcbiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fFxuICAgICAgICAgICAgICAoMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCB2YWxpZCBKU09OIGNoYXJhY3RlcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChQQVRURVJOX05PTl9QUklOVEFCTEUudGVzdChfcmVzdWx0KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgZGVzdGluYXRpb24sIHNvdXJjZSwgb3ZlcnJpZGFibGVLZXlzKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKSB7XG4gIHZhciBpbmRleCwgcXVhbnRpdHk7XG5cbiAga2V5Tm9kZSA9IFN0cmluZyhrZXlOb2RlKTtcblxuICBpZiAoX3Jlc3VsdCA9PT0gbnVsbCkge1xuICAgIF9yZXN1bHQgPSB7fTtcbiAgfVxuXG4gIGlmIChrZXlUYWcgPT09ICd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7XG4gICAgICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSB2YWx1ZU5vZGUubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZVtpbmRleF0sIG92ZXJyaWRhYmxlS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFzdGF0ZS5qc29uICYmXG4gICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmXG4gICAgICAgIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKF9yZXN1bHQsIGtleU5vZGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpO1xuICAgIH1cbiAgICBfcmVzdWx0W2tleU5vZGVdID0gdmFsdWVOb2RlO1xuICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07XG4gIH1cblxuICByZXR1cm4gX3Jlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkge1xuICB2YXIgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4MEEvKiBMRiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4MEQvKiBDUiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIGxpbmUgYnJlYWsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIHN0YXRlLmxpbmUgKz0gMTtcbiAgc3RhdGUubGluZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGFsbG93Q29tbWVudHMsIGNoZWNrSW5kZW50KSB7XG4gIHZhciBsaW5lQnJlYWtzID0gMCxcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd0NvbW1lbnRzICYmIGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8ge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9IHdoaWxlIChjaCAhPT0gMHgwQS8qIExGICovICYmIGNoICE9PSAweDBELyogQ1IgKi8gJiYgY2ggIT09IDApO1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgIGxpbmVCcmVha3MrKztcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykge1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ2RlZmljaWVudCBpbmRlbnRhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVCcmVha3M7XG59XG5cbmZ1bmN0aW9uIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcblxuICAvLyBDb25kaXRpb24gc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCBpcyB0ZXN0ZWRcbiAgLy8gaW4gcGFyZW50IG9uIGVhY2ggY2FsbCwgZm9yIGVmZmljaWVuY3kuIE5vIG5lZWRzIHRvIHRlc3QgaGVyZSBhZ2Fpbi5cbiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMSkgJiZcbiAgICAgIGNoID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDIpKSB7XG5cbiAgICBfcG9zaXRpb24gKz0gMztcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAwIHx8IGlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgY291bnQpIHtcbiAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgfSBlbHNlIGlmIChjb3VudCA+IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgY291bnQgLSAxKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCwgd2l0aGluRmxvd0NvbGxlY3Rpb24pIHtcbiAgdmFyIHByZWNlZGluZyxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoYXNQZW5kaW5nQ29udGVudCxcbiAgICAgIF9saW5lLFxuICAgICAgX2xpbmVTdGFydCxcbiAgICAgIF9saW5lSW5kZW50LFxuICAgICAgX2tpbmQgPSBzdGF0ZS5raW5kLFxuICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGlzX1dTX09SX0VPTChjaCkgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8XG4gICAgICBjaCA9PT0gMHgyMy8qICMgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI2LyogJiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyMS8qICEgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDdDLyogfCAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyNy8qICcgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIyLyogXCIgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI1LyogJSAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4NDAvKiBAICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoY2ggPT09IDB4M0YvKiA/ICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjcvKiAnICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjcvKiAnICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjIvKiBcIiAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG4gIHN0YXRlLnBvc2l0aW9uKys7XG4gIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDIyLyogXCIgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcXCAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7XG5cbiAgICAgICAgLy8gVE9ETzogcmV3b3JrIHRvIGlubGluZSBmbiB3aXRoIG5vIHR5cGUgY2FzdD9cbiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBzaW1wbGVFc2NhcGVNYXBbY2hdO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2UgaWYgKCh0bXAgPSBlc2NhcGVkSGV4TGVuKGNoKSkgPiAwKSB7XG4gICAgICAgIGhleExlbmd0aCA9IHRtcDtcbiAgICAgICAgaGV4UmVzdWx0ID0gMDtcblxuICAgICAgICBmb3IgKDsgaGV4TGVuZ3RoID4gMDsgaGV4TGVuZ3RoLS0pIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgICAgICBpZiAoKHRtcCA9IGZyb21IZXhDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNoYXJGcm9tQ29kZXBvaW50KGhleFJlc3VsdCk7XG5cbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7XG4gICAgICB9XG5cbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGbG93Q29sbGVjdGlvbihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgcmVhZE5leHQgPSB0cnVlLFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIF9yZXN1bHQsXG4gICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIHRlcm1pbmF0b3IsXG4gICAgICBpc1BhaXIsXG4gICAgICBpc0V4cGxpY2l0UGFpcixcbiAgICAgIGlzTWFwcGluZyxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiBjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICB9IGVsc2UgaWYgKGlzUGFpcikge1xuICAgICAgX3Jlc3VsdC5wdXNoKHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIG51bGwsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpO1xuICAgIH1cblxuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChjaCA9PT0gMHgyQy8qICwgKi8pIHtcbiAgICAgIHJlYWROZXh0ID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhZE5leHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBmb2xkaW5nLFxuICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLFxuICAgICAgZGV0ZWN0ZWRJbmRlbnQgPSBmYWxzZSxcbiAgICAgIHRleHRJbmRlbnQgICAgID0gbm9kZUluZGVudCxcbiAgICAgIGVtcHR5TGluZXMgICAgID0gMCxcbiAgICAgIGF0TW9yZUluZGVudGVkID0gZmFsc2UsXG4gICAgICB0bXAsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHg3Qy8qIHwgKi8pIHtcbiAgICBmb2xkaW5nID0gZmFsc2U7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4M0UvKiA+ICovKSB7XG4gICAgZm9sZGluZyA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoY2ggPT09IDB4MkIvKiArICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgICAgaWYgKENIT01QSU5HX0NMSVAgPT09IGNob21waW5nKSB7XG4gICAgICAgIGNob21waW5nID0gKGNoID09PSAweDJCLyogKyAqLykgPyBDSE9NUElOR19LRUVQIDogQ0hPTVBJTkdfU1RSSVA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGEgY2hvbXBpbmcgbW9kZSBpZGVudGlmaWVyJyk7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKCh0bXAgPSBmcm9tRGVjaW1hbENvZGUoY2gpKSA+PSAwKSB7XG4gICAgICBpZiAodG1wID09PSAwKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgZXhwbGljaXQgaW5kZW50YXRpb24gd2lkdGggb2YgYSBibG9jayBzY2FsYXI7IGl0IGNhbm5vdCBiZSBsZXNzIHRoYW4gb25lJyk7XG4gICAgICB9IGVsc2UgaWYgKCFkZXRlY3RlZEluZGVudCkge1xuICAgICAgICB0ZXh0SW5kZW50ID0gbm9kZUluZGVudCArIHRtcCAtIDE7XG4gICAgICAgIGRldGVjdGVkSW5kZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdyZXBlYXQgb2YgYW4gaW5kZW50YXRpb24gd2lkdGggaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICBkbyB7IGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTsgfVxuICAgIHdoaWxlIChpc19XSElURV9TUEFDRShjaCkpO1xuXG4gICAgaWYgKGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgIHdoaWxlICghaXNfRU9MKGNoKSAmJiAoY2ggIT09IDApKTtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoY2ggIT09IDApIHtcbiAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcbiAgICBzdGF0ZS5saW5lSW5kZW50ID0gMDtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICB3aGlsZSAoKCFkZXRlY3RlZEluZGVudCB8fCBzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkgJiZcbiAgICAgICAgICAgKGNoID09PSAweDIwLyogU3BhY2UgKi8pKSB7XG4gICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKCFkZXRlY3RlZEluZGVudCAmJiBzdGF0ZS5saW5lSW5kZW50ID4gdGV4dEluZGVudCkge1xuICAgICAgdGV4dEluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgfVxuXG4gICAgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGVtcHR5TGluZXMrKztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIEVuZCBvZiB0aGUgc2NhbGFyLlxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgdGV4dEluZGVudCkge1xuXG4gICAgICAvLyBQZXJmb3JtIHRoZSBjaG9tcGluZy5cbiAgICAgIGlmIChjaG9tcGluZyA9PT0gQ0hPTVBJTkdfS0VFUCkge1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyk7XG4gICAgICB9IGVsc2UgaWYgKGNob21waW5nID09PSBDSE9NUElOR19DTElQKSB7XG4gICAgICAgIGlmIChkZXRlY3RlZEluZGVudCkgeyAvLyBpLmUuIG9ubHkgaWYgdGhlIHNjYWxhciBpcyBub3QgZW1wdHkuXG4gICAgICAgICAgc3RhdGUucmVzdWx0ICs9ICdcXG4nO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEJyZWFrIHRoaXMgYHdoaWxlYCBjeWNsZSBhbmQgZ28gdG8gdGhlIGZ1bmNpdG9uJ3MgZXBpbG9ndWUuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBGb2xkZWQgc3R5bGU6IHVzZSBmYW5jeSBydWxlcyB0byBoYW5kbGUgbGluZSBicmVha3MuXG4gICAgaWYgKGZvbGRpbmcpIHtcblxuICAgICAgLy8gTGluZXMgc3RhcnRpbmcgd2l0aCB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIChtb3JlLWluZGVudGVkIGxpbmVzKSBhcmUgbm90IGZvbGRlZC5cbiAgICAgIGlmIChpc19XSElURV9TUEFDRShjaCkpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSB0cnVlO1xuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZW1wdHlMaW5lcyArIDEpO1xuXG4gICAgICAvLyBFbmQgb2YgbW9yZS1pbmRlbnRlZCBibG9jay5cbiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcblxuICAgICAgLy8gSnVzdCBvbmUgbGluZSBicmVhayAtIHBlcmNlaXZlIGFzIHRoZSBzYW1lIGxpbmUuXG4gICAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXMgPT09IDApIHtcbiAgICAgICAgaWYgKGRldGVjdGVkSW5kZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnICc7XG4gICAgICAgIH1cblxuICAgICAgLy8gU2V2ZXJhbCBsaW5lIGJyZWFrcyAtIHBlcmNlaXZlIGFzIGRpZmZlcmVudCBsaW5lcy5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH1cblxuICAgIC8vIExpdGVyYWwgc3R5bGU6IGp1c3QgYWRkIGV4YWN0IG51bWJlciBvZiBsaW5lIGJyZWFrcyBiZXR3ZWVuIGNvbnRlbnQgbGluZXMuXG4gICAgfSBlbHNlIGlmIChkZXRlY3RlZEluZGVudCkge1xuICAgICAgLy8gSWYgY3VycmVudCBsaW5lIGlzbid0IHRoZSBmaXJzdCBvbmUgLSBjb3VudCBsaW5lIGJyZWFrIGZyb20gdGhlIGxhc3QgY29udGVudCBsaW5lLlxuICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSW4gY2FzZSBvZiB0aGUgZmlyc3QgY29udGVudCBsaW5lIC0gY291bnQgb25seSBlbXB0eSBsaW5lcy5cbiAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICB9XG5cbiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgZW1wdHlMaW5lcyA9IDA7XG4gICAgY2FwdHVyZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCBmYWxzZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIF9saW5lLFxuICAgICAgX3RhZyAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgID0gW10sXG4gICAgICBmb2xsb3dpbmcsXG4gICAgICBkZXRlY3RlZCAgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuXG4gICAgaWYgKGNoICE9PSAweDJELyogLSAqLykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKCFpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7XG4gICAgICAgIF9yZXN1bHQucHVzaChudWxsKTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX0lOLCBmYWxzZSwgdHJ1ZSk7XG4gICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkZXRlY3RlZCkge1xuICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgbm9kZUluZGVudCwgZmxvd0luZGVudCkge1xuICB2YXIgZm9sbG93aW5nLFxuICAgICAgYWxsb3dDb21wYWN0LFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIF9yZXN1bHQgICAgICAgPSB7fSxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuXG4gICAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7XG4gICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgIC8vIGkuZS4gMHgzQS8qIDogKi8gPT09IGNoYXJhY3RlciBhZnRlciB0aGUgZXhwbGljaXQga2V5LlxuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgICAgIGNoID0gZm9sbG93aW5nO1xuXG4gICAgLy9cbiAgICAvLyBJbXBsaWNpdCBub3RhdGlvbiBjYXNlLiBGbG93LXN0eWxlIG5vZGUgYXMgdGhlIGtleSBmaXJzdCwgdGhlbiBcIjpcIiwgYW5kIHRoZSB2YWx1ZS5cbiAgICAvL1xuICAgIH0gZWxzZSBpZiAoY29tcG9zZU5vZGUoc3RhdGUsIGZsb3dJbmRlbnQsIENPTlRFWFRfRkxPV19PVVQsIGZhbHNlLCB0cnVlKSkge1xuXG4gICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICghaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Egd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGtleS12YWx1ZSBzZXBhcmF0b3Igd2l0aGluIGEgYmxvY2sgbWFwcGluZycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCAmJiAoY2ggIT09IDApKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGluZGVudGF0aW9uIG9mIGEgbWFwcGluZyBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIEVwaWxvZ3VlLlxuICAvL1xuXG4gIC8vIFNwZWNpYWwgY2FzZTogbGFzdCBtYXBwaW5nJ3Mgbm9kZSBjb250YWlucyBvbmx5IHRoZSBrZXkgaW4gZXhwbGljaXQgbm90YXRpb24uXG4gIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICB9XG5cbiAgLy8gRXhwb3NlIHRoZSByZXN1bHRpbmcgbWFwcGluZy5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnbWFwcGluZyc7XG4gICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZDtcbn1cblxuZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24sXG4gICAgICBpc1ZlcmJhdGltID0gZmFsc2UsXG4gICAgICBpc05hbWVkICAgID0gZmFsc2UsXG4gICAgICB0YWdIYW5kbGUsXG4gICAgICB0YWdOYW1lLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjEvKiAhICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhIHRhZyBwcm9wZXJ0eScpO1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHtcbiAgICBpc1ZlcmJhdGltID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICB0YWdIYW5kbGUgPSAnISEnO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2Uge1xuICAgIHRhZ0hhbmRsZSA9ICchJztcbiAgfVxuXG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIGlmIChpc1ZlcmJhdGltKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgY2ggIT09IDB4M0UvKiA+ICovKTtcblxuICAgIGlmIChzdGF0ZS5wb3NpdGlvbiA8IHN0YXRlLmxlbmd0aCkge1xuICAgICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSB2ZXJiYXRpbSB0YWcnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICAgICAgaWYgKCFpc05hbWVkKSB7XG4gICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QodGFnSGFuZGxlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIHN1ZmZpeCBjYW5ub3QgY29udGFpbiBmbG93IGluZGljYXRvciBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRhZ05hbWUgJiYgIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHRhZ05hbWUpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpO1xuICB9XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBzdGF0ZS50YWcgPSB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7XG4gICAgc3RhdGUudGFnID0gc3RhdGUudGFnTWFwW3RhZ0hhbmRsZV0gKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHtcbiAgICBzdGF0ZS50YWcgPSAnIScgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7XG4gICAgc3RhdGUudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZGVjbGFyZWQgdGFnIGhhbmRsZSBcIicgKyB0YWdIYW5kbGUgKyAnXCInKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbmNob3Igbm9kZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGNoYXJhY3RlcicpO1xuICB9XG5cbiAgc3RhdGUuYW5jaG9yID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbiwgYWxpYXMsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudDtcblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignb3BlbicsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnRhZyAgICA9IG51bGw7XG4gIHN0YXRlLmFuY2hvciA9IG51bGw7XG4gIHN0YXRlLmtpbmQgICA9IG51bGw7XG4gIHN0YXRlLnJlc3VsdCA9IG51bGw7XG5cbiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID1cbiAgICBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQgfHxcbiAgICBDT05URVhUX0JMT0NLX0lOICA9PT0gbm9kZUNvbnRleHQ7XG5cbiAgaWYgKGFsbG93VG9TZWVrKSB7XG4gICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgIGluZGVudFN0YXR1cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgIHdoaWxlIChyZWFkVGFnUHJvcGVydHkoc3RhdGUpIHx8IHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkpIHtcbiAgICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYWxsb3dCbG9ja1N0eWxlcztcblxuICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICAgIGluZGVudFN0YXR1cyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMpIHtcbiAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhdE5ld0xpbmUgfHwgYWxsb3dDb21wYWN0O1xuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSB8fCBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQpIHtcbiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7XG4gICAgfVxuXG4gICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDtcblxuICAgIGlmIChpbmRlbnRTdGF0dXMgPT09IDEpIHtcbiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiZcbiAgICAgICAgICAocmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KSB8fFxuICAgICAgICAgICByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBibG9ja0luZGVudCwgZmxvd0luZGVudCkpIHx8XG4gICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICAgIHJlYWRTaW5nbGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpIHx8XG4gICAgICAgICAgICByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZEFsaWFzKHN0YXRlKSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCB8fCBzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHtcbiAgICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLnRhZyA9ICc/JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlOiBibG9jayBzZXF1ZW5jZXMgYXJlIGFsbG93ZWQgdG8gaGF2ZSBzYW1lIGluZGVudGF0aW9uIGxldmVsIGFzIHRoZSBwYXJlbnQuXG4gICAgICAvLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI3OTk3ODRcbiAgICAgIGhhc0NvbnRlbnQgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYgcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJz8nKSB7XG4gICAgICBmb3IgKHR5cGVJbmRleCA9IDAsIHR5cGVRdWFudGl0eSA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoO1xuICAgICAgICAgICB0eXBlSW5kZXggPCB0eXBlUXVhbnRpdHk7XG4gICAgICAgICAgIHR5cGVJbmRleCArPSAxKSB7XG4gICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07XG5cbiAgICAgICAgLy8gSW1wbGljaXQgcmVzb2x2aW5nIGlzIG5vdCBhbGxvd2VkIGZvciBub24tc2NhbGFyIHR5cGVzLCBhbmQgJz8nXG4gICAgICAgIC8vIG5vbi1zcGVjaWZpYyB0YWcgaXMgb25seSBhc3NpZ25lZCB0byBwbGFpbiBzY2FsYXJzLiBTbywgaXQgaXNuJ3RcbiAgICAgICAgLy8gbmVlZGVkIHRvIGNoZWNrIGZvciAna2luZCcgY29uZm9ybWl0eS5cblxuICAgICAgICBpZiAodHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZztcbiAgICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLnR5cGVNYXAsIHN0YXRlLnRhZykpIHtcbiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLnRhZ107XG5cbiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgbm9kZSBraW5kIGZvciAhPCcgKyBzdGF0ZS50YWcgKyAnPiB0YWc7IGl0IHNob3VsZCBiZSBcIicgKyB0eXBlLmtpbmQgKyAnXCIsIG5vdCBcIicgKyBzdGF0ZS5raW5kICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7XG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biB0YWcgITwnICsgc3RhdGUudGFnICsgJz4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignY2xvc2UnLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkge1xuICB2YXIgZG9jdW1lbnRTdGFydCA9IHN0YXRlLnBvc2l0aW9uLFxuICAgICAgX3Bvc2l0aW9uLFxuICAgICAgZGlyZWN0aXZlTmFtZSxcbiAgICAgIGRpcmVjdGl2ZUFyZ3MsXG4gICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBzdGF0ZS52ZXJzaW9uID0gbnVsbDtcbiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5O1xuICBzdGF0ZS50YWdNYXAgPSB7fTtcbiAgc3RhdGUuYW5jaG9yTWFwID0ge307XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgZGlyZWN0aXZlQXJncyA9IFtdO1xuXG4gICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZSBuYW1lIG11c3Qgbm90IGJlIGxlc3MgdGhhbiBvbmUgY2hhcmFjdGVyIGluIGxlbmd0aCcpO1xuICAgIH1cblxuICAgIHdoaWxlIChjaCAhPT0gMCkge1xuICAgICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19FT0woY2gpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhaztcblxuICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGRpcmVjdGl2ZUFyZ3MucHVzaChzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKSk7XG4gICAgfVxuXG4gICAgaWYgKGNoICE9PSAwKSByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChkaXJlY3RpdmVIYW5kbGVycywgZGlyZWN0aXZlTmFtZSkpIHtcbiAgICAgIGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZU5hbWVdKHN0YXRlLCBkaXJlY3RpdmVOYW1lLCBkaXJlY3RpdmVBcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5rbm93biBkb2N1bWVudCBkaXJlY3RpdmUgXCInICsgZGlyZWN0aXZlTmFtZSArICdcIicpO1xuICAgIH1cbiAgfVxuXG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgICAgID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIH0gZWxzZSBpZiAoaGFzRGlyZWN0aXZlcykge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkaXJlY3RpdmVzIGVuZCBtYXJrIGlzIGV4cGVjdGVkJyk7XG4gIH1cblxuICBjb21wb3NlTm9kZShzdGF0ZSwgc3RhdGUubGluZUluZGVudCAtIDEsIENPTlRFWFRfQkxPQ0tfT1VULCBmYWxzZSwgdHJ1ZSk7XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUuY2hlY2tMaW5lQnJlYWtzICYmXG4gICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICdub24tQVNDSUkgbGluZSBicmVha3MgYXJlIGludGVycHJldGVkIGFzIGNvbnRlbnQnKTtcbiAgfVxuXG4gIHN0YXRlLmRvY3VtZW50cy5wdXNoKHN0YXRlLnJlc3VsdCk7XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuXG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDJFLyogLiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2VuZCBvZiB0aGUgc3RyZWFtIG9yIGEgZG9jdW1lbnQgc2VwYXJhdG9yIGlzIGV4cGVjdGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHtcblxuICAgIC8vIEFkZCB0YWlsaW5nIGBcXG5gIGlmIG5vdCBleGlzdHNcbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwQS8qIExGICovICYmXG4gICAgICAgIGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkgIT09IDB4MEQvKiBDUiAqLykge1xuICAgICAgaW5wdXQgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgQk9NXG4gICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIC8vIFVzZSAwIGFzIHN0cmluZyB0ZXJtaW5hdG9yLiBUaGF0IHNpZ25pZmljYW50bHkgc2ltcGxpZmllcyBib3VuZHMgY2hlY2suXG4gIHN0YXRlLmlucHV0ICs9ICdcXDAnO1xuXG4gIHdoaWxlIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgc3RhdGUubGluZUluZGVudCArPSAxO1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICByZWFkRG9jdW1lbnQoc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlLmRvY3VtZW50cztcbn1cblxuXG5mdW5jdGlvbiBsb2FkQWxsKGlucHV0LCBpdGVyYXRvciwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGRvY3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgaXRlcmF0b3IoZG9jdW1lbnRzW2luZGV4XSk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZG9jdW1lbnRzWzBdO1xuICB9XG4gIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdleHBlY3RlZCBhIHNpbmdsZSBkb2N1bWVudCBpbiB0aGUgc3RyZWFtLCBidXQgZm91bmQgbW9yZScpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkQWxsKGlucHV0LCBvdXRwdXQsIG9wdGlvbnMpIHtcbiAgbG9hZEFsbChpbnB1dCwgb3V0cHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gbG9hZChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgPSBsb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWRBbGwgPSBzYWZlTG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgID0gc2FmZUxvYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuZnVuY3Rpb24gTWFyayhuYW1lLCBidWZmZXIsIHBvc2l0aW9uLCBsaW5lLCBjb2x1bW4pIHtcbiAgdGhpcy5uYW1lICAgICA9IG5hbWU7XG4gIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7XG4gIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgdGhpcy5saW5lICAgICA9IGxpbmU7XG4gIHRoaXMuY29sdW1uICAgPSBjb2x1bW47XG59XG5cblxuTWFyay5wcm90b3R5cGUuZ2V0U25pcHBldCA9IGZ1bmN0aW9uIGdldFNuaXBwZXQoaW5kZW50LCBtYXhMZW5ndGgpIHtcbiAgdmFyIGhlYWQsIHN0YXJ0LCB0YWlsLCBlbmQsIHNuaXBwZXQ7XG5cbiAgaWYgKCF0aGlzLmJ1ZmZlcikgcmV0dXJuIG51bGw7XG5cbiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7XG4gIG1heExlbmd0aCA9IG1heExlbmd0aCB8fCA3NTtcblxuICBoZWFkID0gJyc7XG4gIHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoc3RhcnQgPiAwICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkge1xuICAgIHN0YXJ0IC09IDE7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gLSBzdGFydCA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIGhlYWQgPSAnIC4uLiAnO1xuICAgICAgc3RhcnQgKz0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRhaWwgPSAnJztcbiAgZW5kID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkge1xuICAgIGVuZCArPSAxO1xuICAgIGlmIChlbmQgLSB0aGlzLnBvc2l0aW9uID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgdGFpbCA9ICcgLi4uICc7XG4gICAgICBlbmQgLT0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcblxuICByZXR1cm4gY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCkgKyBoZWFkICsgc25pcHBldCArIHRhaWwgKyAnXFxuJyArXG4gICAgICAgICBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50ICsgdGhpcy5wb3NpdGlvbiAtIHN0YXJ0ICsgaGVhZC5sZW5ndGgpICsgJ14nO1xufTtcblxuXG5NYXJrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7XG5cbiAgaWYgKHRoaXMubmFtZSkge1xuICAgIHdoZXJlICs9ICdpbiBcIicgKyB0aGlzLm5hbWUgKyAnXCIgJztcbiAgfVxuXG4gIHdoZXJlICs9ICdhdCBsaW5lICcgKyAodGhpcy5saW5lICsgMSkgKyAnLCBjb2x1bW4gJyArICh0aGlzLmNvbHVtbiArIDEpO1xuXG4gIGlmICghY29tcGFjdCkge1xuICAgIHNuaXBwZXQgPSB0aGlzLmdldFNuaXBwZXQoKTtcblxuICAgIGlmIChzbmlwcGV0KSB7XG4gICAgICB3aGVyZSArPSAnOlxcbicgKyBzbmlwcGV0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3aGVyZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXJrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4qL1xuXG52YXIgY29tbW9uICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgVHlwZSAgICAgICAgICA9IHJlcXVpcmUoJy4vdHlwZScpO1xuXG5cbmZ1bmN0aW9uIGNvbXBpbGVMaXN0KHNjaGVtYSwgbmFtZSwgcmVzdWx0KSB7XG4gIHZhciBleGNsdWRlID0gW107XG5cbiAgc2NoZW1hLmluY2x1ZGUuZm9yRWFjaChmdW5jdGlvbiAoaW5jbHVkZWRTY2hlbWEpIHtcbiAgICByZXN1bHQgPSBjb21waWxlTGlzdChpbmNsdWRlZFNjaGVtYSwgbmFtZSwgcmVzdWx0KTtcbiAgfSk7XG5cbiAgc2NoZW1hW25hbWVdLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRUeXBlKSB7XG4gICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKHByZXZpb3VzVHlwZS50YWcgPT09IGN1cnJlbnRUeXBlLnRhZykge1xuICAgICAgICBleGNsdWRlLnB1c2gocHJldmlvdXNJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkge1xuICAgIHJldHVybiBleGNsdWRlLmluZGV4T2YoaW5kZXgpID09PSAtMTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge30sIGluZGV4LCBsZW5ndGg7XG5cbiAgZnVuY3Rpb24gY29sbGVjdFR5cGUodHlwZSkge1xuICAgIHJlc3VsdFt0eXBlLnRhZ10gPSB0eXBlO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgYXJndW1lbnRzW2luZGV4XS5mb3JFYWNoKGNvbGxlY3RUeXBlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdGhpcy5pbmNsdWRlICA9IGRlZmluaXRpb24uaW5jbHVkZSAgfHwgW107XG4gIHRoaXMuaW1wbGljaXQgPSBkZWZpbml0aW9uLmltcGxpY2l0IHx8IFtdO1xuICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTtcblxuICB0aGlzLmltcGxpY2l0LmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1RoZXJlIGlzIGEgbm9uLXNjYWxhciB0eXBlIGluIHRoZSBpbXBsaWNpdCBsaXN0IG9mIGEgc2NoZW1hLiBJbXBsaWNpdCByZXNvbHZpbmcgb2Ygc3VjaCB0eXBlcyBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5jb21waWxlZEltcGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2ltcGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRUeXBlTWFwICA9IGNvbXBpbGVNYXAodGhpcy5jb21waWxlZEltcGxpY2l0LCB0aGlzLmNvbXBpbGVkRXhwbGljaXQpO1xufVxuXG5cblNjaGVtYS5ERUZBVUxUID0gbnVsbDtcblxuXG5TY2hlbWEuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlU2NoZW1hKCkge1xuICB2YXIgc2NoZW1hcywgdHlwZXM7XG5cbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAxOlxuICAgICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgICAgdHlwZXMgPSBhcmd1bWVudHNbMF07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBTY2hlbWEuY3JlYXRlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBzY2hlbWFzID0gY29tbW9uLnRvQXJyYXkoc2NoZW1hcyk7XG4gIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpO1xuXG4gIGlmICghc2NoZW1hcy5ldmVyeShmdW5jdGlvbiAoc2NoZW1hKSB7IHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBTY2hlbWE7IH0pKSB7XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7XG4gIH1cblxuICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2YgWUFNTCB0eXBlcyAob3IgYSBzaW5nbGUgVHlwZSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVR5cGUgb2JqZWN0LicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIGluY2x1ZGU6IHNjaGVtYXMsXG4gICAgZXhwbGljaXQ6IHR5cGVzXG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIiwiLy8gSlMtWUFNTCdzIGRlZmF1bHQgc2NoZW1hIGZvciBgbG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gSlMtWUFNTCdzIGRlZmF1bHQgc2FmZSBzY2hlbWEgYW5kIGluY2x1ZGVzXG4vLyBKYXZhU2NyaXB0LXNwZWNpZmljIHR5cGVzOiAhIWpzL3VuZGVmaW5lZCwgISFqcy9yZWdleHAgYW5kICEhanMvZnVuY3Rpb24uXG4vL1xuLy8gQWxzbyB0aGlzIHNjaGVtYSBpcyB1c2VkIGFzIGRlZmF1bHQgYmFzZSBzY2hlbWEgYXQgYFNjaGVtYS5jcmVhdGVgIGZ1bmN0aW9uLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY2hlbWEuREVGQVVMVCA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9kZWZhdWx0X3NhZmUnKVxuICBdLFxuICBleHBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvdW5kZWZpbmVkJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy9yZWdleHAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBzYWZlTG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gc3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hIGFuZCBpbmNsdWRlcyBtb3N0IG9mXG4vLyBleHRyYSB0eXBlcyBkZXNjcmliZWQgYXQgWUFNTCB0YWcgcmVwb3NpdG9yeS4gKGh0dHA6Ly95YW1sLm9yZy90eXBlLylcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2NvcmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tZXJnZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9iaW5hcnknKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL29tYXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zZXQnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iLCIvLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xuXG52YXIgVFlQRV9DT05TVFJVQ1RPUl9PUFRJT05TID0gW1xuICAna2luZCcsXG4gICdyZXNvbHZlJyxcbiAgJ2NvbnN0cnVjdCcsXG4gICdpbnN0YW5jZU9mJyxcbiAgJ3ByZWRpY2F0ZScsXG4gICdyZXByZXNlbnQnLFxuICAnZGVmYXVsdFN0eWxlJyxcbiAgJ3N0eWxlQWxpYXNlcydcbl07XG5cbnZhciBZQU1MX05PREVfS0lORFMgPSBbXG4gICdzY2FsYXInLFxuICAnc2VxdWVuY2UnLFxuICAnbWFwcGluZydcbl07XG5cbmZ1bmN0aW9uIGNvbXBpbGVTdHlsZUFsaWFzZXMobWFwKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBpZiAobWFwICE9PSBudWxsKSB7XG4gICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGFsaWFzKV0gPSBzdHlsZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmIChUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiIGlzIG1ldCBpbiBkZWZpbml0aW9uIG9mIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBUT0RPOiBBZGQgdGFnIGZvcm1hdCBjaGVjay5cbiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7XG4gIHRoaXMua2luZCAgICAgICAgID0gb3B0aW9uc1sna2luZCddICAgICAgICAgfHwgbnVsbDtcbiAgdGhpcy5yZXNvbHZlICAgICAgPSBvcHRpb25zWydyZXNvbHZlJ10gICAgICB8fCBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9O1xuICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9O1xuICB0aGlzLmluc3RhbmNlT2YgICA9IG9wdGlvbnNbJ2luc3RhbmNlT2YnXSAgIHx8IG51bGw7XG4gIHRoaXMucHJlZGljYXRlICAgID0gb3B0aW9uc1sncHJlZGljYXRlJ10gICAgfHwgbnVsbDtcbiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRTdHlsZSA9IG9wdGlvbnNbJ2RlZmF1bHRTdHlsZSddIHx8IG51bGw7XG4gIHRoaXMuc3R5bGVBbGlhc2VzID0gY29tcGlsZVN0eWxlQWxpYXNlcyhvcHRpb25zWydzdHlsZUFsaWFzZXMnXSB8fCBudWxsKTtcblxuICBpZiAoWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBraW5kIFwiJyArIHRoaXMua2luZCArICdcIiBpcyBzcGVjaWZpZWQgZm9yIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUeXBlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UqL1xuXG4vLyBBIHRyaWNrIGZvciBicm93c2VyaWZpZWQgdmVyc2lvbi5cbi8vIFNpbmNlIHdlIG1ha2UgYnJvd3NlcmlmaWVyIHRvIGlnbm9yZSBgYnVmZmVyYCBtb2R1bGUsIE5vZGVCdWZmZXIgd2lsbCBiZSB1bmRlZmluZWRcbnZhciBOb2RlQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIFR5cGUgICAgICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cblxuLy8gWyA2NCwgNjUsIDY2IF0gLT4gWyBwYWRkaW5nLCBDUiwgTEYgXVxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cXG5cXHInO1xuXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IG9uZSBieSBvbmUuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTtcblxuICAgIC8vIFNraXAgQ1IvTEZcbiAgICBpZiAoY29kZSA+IDY0KSBjb250aW51ZTtcblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBiaXRsZW4gKz0gNjtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgYml0cyBsZWZ0LCBzb3VyY2Ugd2FzIGNvcnJ1cHRlZFxuICByZXR1cm4gKGJpdGxlbiAlIDgpID09PSAwO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQmluYXJ5KGRhdGEpIHtcbiAgdmFyIGlkeCwgdGFpbGJpdHMsXG4gICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xcclxcbj1dL2csICcnKSwgLy8gcmVtb3ZlIENSL0xGICYgcGFkZGluZyB0byBzaW1wbGlmeSBzY2FuXG4gICAgICBtYXggPSBpbnB1dC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQLFxuICAgICAgYml0cyA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgNCA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDYpIHwgbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDIpICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTtcbiAgfVxuXG4gIC8vIFdyYXAgaW50byBCdWZmZXIgZm9yIE5vZGVKUyBhbmQgbGVhdmUgQXJyYXkgZm9yIGJyb3dzZXJcbiAgaWYgKE5vZGVCdWZmZXIpIHJldHVybiBuZXcgTm9kZUJ1ZmZlcihyZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxCaW5hcnkob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCxcbiAgICAgIG1heCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgZXZlcnkgdGhyZWUgYnl0ZXMgdG8gNCBBU0NJSSBjaGFyYWN0ZXJzLlxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgMyA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbCA9IG1heCAlIDM7XG5cbiAgaWYgKHRhaWwgPT09IDApIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDIpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEwKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0JpbmFyeShvYmplY3QpIHtcbiAgcmV0dXJuIE5vZGVCdWZmZXIgJiYgTm9kZUJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJpbmFyeSxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQmluYXJ5LFxuICBwcmVkaWNhdGU6IGlzQmluYXJ5LFxuICByZXByZXNlbnQ6IHJlcHJlc2VudFlhbWxCaW5hcnlcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCb29sZWFuKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHxcbiAgICAgICAgIChtYXggPT09IDUgJiYgKGRhdGEgPT09ICdmYWxzZScgfHwgZGF0YSA9PT0gJ0ZhbHNlJyB8fCBkYXRhID09PSAnRkFMU0UnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCb29sZWFuKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICd0cnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVFJVRSc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBCb29sZWFuXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJvb2xlYW4sXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJvb2xlYW4sXG4gIHByZWRpY2F0ZTogaXNCb29sZWFuLFxuICByZXByZXNlbnQ6IHtcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICd0cnVlJyA6ICdmYWxzZSc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RydWUnIDogJ0ZhbHNlJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfRkxPQVRfUEFUVEVSTiA9IG5ldyBSZWdFeHAoXG4gICdeKD86Wy0rXT8oPzpbMC05XVswLTlfXSopXFxcXC5bMC05X10qKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFxcXFwuWzAtOV9dKyg/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xbLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrXFxcXC5bMC05X10qJyArXG4gICd8Wy0rXT9cXFxcLig/OmluZnxJbmZ8SU5GKScgK1xuICAnfFxcXFwuKD86bmFufE5hTnxOQU4pKSQnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sRmxvYXQoZGF0YSkge1xuICB2YXIgdmFsdWUsIHNpZ24sIGJhc2UsIGRpZ2l0cztcblxuICB2YWx1ZSAgPSBkYXRhLnJlcGxhY2UoL18vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIHNpZ24gICA9IHZhbHVlWzBdID09PSAnLScgPyAtMSA6IDE7XG4gIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICgnKy0nLmluZGV4T2YodmFsdWVbMF0pID49IDApIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnLmluZicpIHtcbiAgICByZXR1cm4gKHNpZ24gPT09IDEpID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykge1xuICAgIHJldHVybiBOYU47XG5cbiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VGbG9hdCh2LCAxMCkpO1xuICAgIH0pO1xuXG4gICAgdmFsdWUgPSAwLjA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7XG4gICAgICBiYXNlICo9IDYwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTtcblxuICB9XG4gIHJldHVybiBzaWduICogcGFyc2VGbG9hdCh2YWx1ZSwgMTApO1xufVxuXG5cbnZhciBTQ0lFTlRJRklDX1dJVEhPVVRfRE9UID0gL15bLStdP1swLTldK2UvO1xuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sRmxvYXQob2JqZWN0LCBzdHlsZSkge1xuICB2YXIgcmVzO1xuXG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLk5BTic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7XG4gICAgICBjYXNlICd1cHBlcmNhc2UnOiByZXR1cm4gJy5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLS5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuXG4gIHJlcyA9IG9iamVjdC50b1N0cmluZygxMCk7XG5cbiAgLy8gSlMgc3RyaW5naWZpZXIgY2FuIGJ1aWxkIHNjaWVudGlmaWMgZm9ybWF0IHdpdGhvdXQgZG90czogNWUtMTAwLFxuICAvLyB3aGlsZSBZQU1MIHJlcXVyZXMgZG90OiA1LmUtMTAwLiBGaXggaXQgd2l0aCBzaW1wbGUgaGFja1xuXG4gIHJldHVybiBTQ0lFTlRJRklDX1dJVEhPVVRfRE9ULnRlc3QocmVzKSA/IHJlcy5yZXBsYWNlKCdlJywgJy5lJykgOiByZXM7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXQob2JqZWN0KSB7XG4gIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJlxuICAgICAgICAgKG9iamVjdCAlIDEgIT09IDAgfHwgY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEZsb2F0LFxuICBwcmVkaWNhdGU6IGlzRmxvYXQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB8fFxuICAgICAgICAgKCgweDQxLyogQSAqLyA8PSBjKSAmJiAoYyA8PSAweDQ2LyogRiAqLykpIHx8XG4gICAgICAgICAoKDB4NjEvKiBhICovIDw9IGMpICYmIChjIDw9IDB4NjYvKiBmICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzcvKiA3ICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVjQ29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sSW50ZWdlcihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgaGFzRGlnaXRzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoIW1heCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSByZXR1cm4gdHJ1ZTtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG5cbiAgICAvLyBiYXNlIDIsIGJhc2UgOCwgYmFzZSAxNlxuXG4gICAgaWYgKGNoID09PSAnYicpIHtcbiAgICAgIC8vIGJhc2UgMlxuICAgICAgaW5kZXgrKztcblxuICAgICAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cblxuICAgIGlmIChjaCA9PT0gJ3gnKSB7XG4gICAgICAvLyBiYXNlIDE2XG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgaWYgKGNoID09PSAnOicpIGJyZWFrO1xuICAgIGlmICghaXNEZWNDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gIH1cblxuICBpZiAoIWhhc0RpZ2l0cykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgcmV0dXJuIHRydWU7XG5cbiAgLy8gYmFzZTYwIGFsbW9zdCBub3QgdXNlZCwgbm8gbmVlZHMgdG8gb3B0aW1pemVcbiAgcmV0dXJuIC9eKDpbMC01XT9bMC05XSkrJC8udGVzdChkYXRhLnNsaWNlKGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTtcblxuICBpZiAodmFsdWUuaW5kZXhPZignXycpICE9PSAtMSkge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7XG4gIH1cblxuICBjaCA9IHZhbHVlWzBdO1xuXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xO1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gICAgY2ggPSB2YWx1ZVswXTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDtcblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ2InKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCAyKTtcbiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDgpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSkgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmXG4gICAgICAgICAob2JqZWN0ICUgMSA9PT0gMCAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIC8vIHdvcmthcm91bmQgdG8gZXhjbHVkZSBwYWNrYWdlIGZyb20gYnJvd3NlcmlmeSBsaXN0LlxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBlc3ByaW1hID0gX3JlcXVpcmUoJ2VzcHJpbWEnKTtcbn0gY2F0Y2ggKF8pIHtcbiAgLypnbG9iYWwgd2luZG93ICovXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hO1xufVxuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSk7XG5cbiAgICBpZiAoYXN0LnR5cGUgICAgICAgICAgICAgICAgICAgICE9PSAnUHJvZ3JhbScgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnRnVuY3Rpb25FeHByZXNzaW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgLypqc2xpbnQgZXZpbDp0cnVlKi9cblxuICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pLFxuICAgICAgcGFyYW1zID0gW10sXG4gICAgICBib2R5O1xuXG4gIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgIGFzdC5ib2R5WzBdLnR5cGUgICAgICAgICAgICAhPT0gJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIHx8XG4gICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBmdW5jdGlvbicpO1xuICB9XG5cbiAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICBwYXJhbXMucHVzaChwYXJhbS5uYW1lKTtcbiAgfSk7XG5cbiAgYm9keSA9IGFzdC5ib2R5WzBdLmV4cHJlc3Npb24uYm9keS5yYW5nZTtcblxuICAvLyBFc3ByaW1hJ3MgcmFuZ2VzIGluY2x1ZGUgdGhlIGZpcnN0ICd7JyBhbmQgdGhlIGxhc3QgJ30nIGNoYXJhY3RlcnMgb25cbiAgLy8gZnVuY3Rpb24gZXhwcmVzc2lvbnMuIFNvIGN1dCB0aGVtIG91dC5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1uZXctZnVuYyovXG4gIHJldHVybiBuZXcgRnVuY3Rpb24ocGFyYW1zLCBzb3VyY2Uuc2xpY2UoYm9keVswXSArIDEsIGJvZHlbMV0gLSAxKSk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL2Z1bmN0aW9uJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24sXG4gIHByZWRpY2F0ZTogaXNGdW5jdGlvbixcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0RnVuY3Rpb25cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBpZiByZWdleHAgc3RhcnRzIHdpdGggJy8nIGl0IGNhbiBoYXZlIG1vZGlmaWVycyBhbmQgbXVzdCBiZSBwcm9wZXJseSBjbG9zZWRcbiAgLy8gYC9mb28vZ2ltYCAtIG1vZGlmaWVycyB0YWlsIGNhbiBiZSBtYXhpbXVtIDMgY2hhcnNcbiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7XG4gICAgaWYgKHRhaWwpIG1vZGlmaWVycyA9IHRhaWxbMV07XG5cbiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTtcbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwKGRhdGEpIHtcbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gYC9mb28vZ2ltYCAtIHRhaWwgY2FuIGJlIG1heGltdW0gNCBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmIChvYmplY3QubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0UmVnRXhwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsXG4gIHByZWRpY2F0ZTogaXNSZWdFeHAsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy91bmRlZmluZWQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWFwJywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAnPDwnIHx8IGRhdGEgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE9tYXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG9iamVjdEtleXMgPSBbXSwgaW5kZXgsIGxlbmd0aCwgcGFpciwgcGFpcktleSwgcGFpckhhc0tleSxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG4gICAgcGFpckhhc0tleSA9IGZhbHNlO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChwYWlyS2V5IGluIHBhaXIpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChwYWlyLCBwYWlyS2V5KSkge1xuICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhaXJIYXNLZXkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChvYmplY3RLZXlzLmluZGV4T2YocGFpcktleSkgPT09IC0xKSBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgZWxzZSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTtcblxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxQYWlycyhkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gW107XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnLCB7XG4gIGtpbmQ6ICdzZXF1ZW5jZScsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sUGFpcnMsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFBhaXJzXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICBpZiAob2JqZWN0W2tleV0gIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6ICcnOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX1RJTUVTVEFNUF9SRUdFWFAgPSBuZXcgUmVnRXhwKFxuICAnXihbMC05XVswLTldWzAtOV1bMC05XSknICAgICAgICAgICsgLy8gWzFdIHllYXJcbiAgJy0oWzAtOV1bMC05XT8pJyAgICAgICAgICAgICAgICAgICArIC8vIFsyXSBtb250aFxuICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzNdIGRheVxuICAnKD86KD86W1R0XXxbIFxcXFx0XSspJyAgICAgICAgICAgICAgKyAvLyAuLi5cbiAgJyhbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICArIC8vIFs0XSBob3VyXG4gICc6KFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNV0gbWludXRlXG4gICc6KFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbNl0gc2Vjb25kXG4gICcoPzpcXFxcLihbMC05XSopKT8nICAgICAgICAgICAgICAgICArIC8vIFs3XSBmcmFjdGlvblxuICAnKD86WyBcXFxcdF0qKFp8KFstK10pKFswLTldWzAtOV0/KScgKyAvLyBbOF0gdHogWzldIHR6X3NpZ24gWzEwXSB0el9ob3VyXG4gICcoPzo6KFswLTldWzAtOV0pKT8pKT8pPyQnKTsgICAgICAgICAvLyBbMTFdIHR6X21pbnV0ZVxuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIGlmIChZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpO1xuXG4gIC8vIG1hdGNoOiBbMV0geWVhciBbMl0gbW9udGggWzNdIGRheVxuXG4gIHllYXIgPSArKG1hdGNoWzFdKTtcbiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDBcbiAgZGF5ID0gKyhtYXRjaFszXSk7XG5cbiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXkpKTtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbNF0gaG91ciBbNV0gbWludXRlIFs2XSBzZWNvbmQgWzddIGZyYWN0aW9uXG5cbiAgaG91ciA9ICsobWF0Y2hbNF0pO1xuICBtaW51dGUgPSArKG1hdGNoWzVdKTtcbiAgc2Vjb25kID0gKyhtYXRjaFs2XSk7XG5cbiAgaWYgKG1hdGNoWzddKSB7XG4gICAgZnJhY3Rpb24gPSBtYXRjaFs3XS5zbGljZSgwLCAzKTtcbiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzXG4gICAgICBmcmFjdGlvbiArPSAnMCc7XG4gICAgfVxuICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXIgWzExXSB0el9taW51dGVcblxuICBpZiAobWF0Y2hbOV0pIHtcbiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pO1xuICAgIHR6X21pbnV0ZSA9ICsobWF0Y2hbMTFdIHx8IDApO1xuICAgIGRlbHRhID0gKHR6X2hvdXIgKiA2MCArIHR6X21pbnV0ZSkgKiA2MDAwMDsgLy8gZGVsdGEgaW4gbWlsaS1zZWNvbmRzXG4gICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhO1xuICB9XG5cbiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpO1xuXG4gIGlmIChkZWx0YSkgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuXG4gIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sVGltZXN0YW1wKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvSVNPU3RyaW5nKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnRpbWVzdGFtcCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sVGltZXN0YW1wLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAsXG4gIGluc3RhbmNlT2Y6IERhdGUsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbFRpbWVzdGFtcFxufSk7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGJpbmFyeUluZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmluYXJ5SW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgc29ydGVkIHByb3ZpZGluZyBgdHJ1ZWAgZm9yIGBmcm9tSW5kZXhgXG4gKiBwZXJmb3JtcyBhIGZhc3RlciBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gKiAgdG8gcGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXkuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gKiAvLyA9PiAzXG4gKlxuICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAqIF8uaW5kZXhPZihbMSwgMSwgMiwgMl0sIDIsIHRydWUpO1xuICogLy8gPT4gMlxuICovXG5mdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogZnJvbUluZGV4O1xuICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IGFycmF5W2luZGV4XSkgOiAoYXJyYXlbaW5kZXhdICE9PSBhcnJheVtpbmRleF0pKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4IHx8IDApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2Y7XG4iLCIvKipcbiAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3Q7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VMb2Rhc2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgd3JhcHBlckNsb25lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvd3JhcHBlckNsb25lJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgY2hhaW5pbmcuXG4gKiBNZXRob2RzIHRoYXQgb3BlcmF0ZSBvbiBhbmQgcmV0dXJuIGFycmF5cywgY29sbGVjdGlvbnMsIGFuZCBmdW5jdGlvbnMgY2FuXG4gKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gKiBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWRcbiAqIHZhbHVlLiBFeHBsaWNpdCBjaGFpbmluZyBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2ZcbiAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gKiBpcyBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiBzdHJhdGVneSB3aGljaCBtZXJnZSBpdGVyYXRlZSBjYWxsczsgdGhpcyBjYW4gaGVscFxuICogdG8gYXZvaWQgdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBkYXRhIHN0cnVjdHVyZXMgYW5kIGdyZWF0bHkgcmVkdWNlIHRoZVxuICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCxcbiAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAqIGBkcm9wV2hpbGVgLCBgZmlsbGAsIGBmaWx0ZXJgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsXG4gKiBgZm9yRWFjaGAsIGBmb3JFYWNoUmlnaHRgLCBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLFxuICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAqIGBpbnZva2VgLCBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLFxuICogYG1hdGNoZXNQcm9wZXJ0eWAsIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1ldGhvZGAsIGBtZXRob2RPZmAsIGBtaXhpbmAsXG4gKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAqIGBwYXJ0aXRpb25gLCBgcGlja2AsIGBwbGFudGAsIGBwbHVja2AsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLFxuICogYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJlYXJnYCwgYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLFxuICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAqIGBzb3J0QnlPcmRlcmAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCxcbiAqIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCxcbiAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICogYHZhbHVlc0luYCwgYHdoZXJlYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbG9uZWAsIGBjbG9uZURlZXBgLFxuICogYGRlYnVycmAsIGBlbmRzV2l0aGAsIGBlc2NhcGVgLCBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCxcbiAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAqIGBmbG9vcmAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCxcbiAqIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCwgYGlzQXJyYXlgLCBgaXNCb29sZWFuYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLFxuICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAqIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNQbGFpbk9iamVjdGAsXG4gKiBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCwgYGpvaW5gLCBga2ViYWJDYXNlYCxcbiAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gKiBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCxcbiAqIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAqIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsXG4gKiBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB0YXJnZXRgIGlzIGluIGBjb2xsZWN0aW9uYCB1c2luZ1xuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ucmVkdWNlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgZnJvbUluZGV4ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICB9XG4gIHJldHVybiAodHlwZW9mIGNvbGxlY3Rpb24gPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkoY29sbGVjdGlvbikgJiYgaXNTdHJpbmcoY29sbGVjdGlvbikpXG4gICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG52YXIgUE9TSVRJVkVfSU5GSU5JVFkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IFtdO1xufVxuXG5MYXp5V3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExhenlXcmFwcGVyO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9iYXNlTG9kYXNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGBsb2Rhc2hgIHdyYXBwZXIgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYWN0aW9ucz1bXV0gQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBhY3Rpb25zIHx8IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG59XG5cbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9kYXNoV3JhcHBlcjtcbiIsIi8qKlxuICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5Q29weTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUNvcHkgPSByZXF1aXJlKCcuL2Jhc2VDb3B5JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgID8gb2JqZWN0XG4gICAgOiBiYXNlQ29weShzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGJhc2VNYXRjaGVzID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlcycpLFxuICAgIGJhc2VNYXRjaGVzUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIHByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9wcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICogbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBbZnVuYz1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhIGNhbGxiYWNrLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGZ1bmM7XG4gIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZ1bmNcbiAgICAgIDogYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KTtcbiAgfVxuICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0eXBlID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGJhc2VNYXRjaGVzKGZ1bmMpO1xuICB9XG4gIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICA/IHByb3BlcnR5KGZ1bmMpXG4gICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDYWxsYmFjaztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vYXJyYXlFYWNoJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vaW5pdENsb25lQXJyYXknKSxcbiAgICBpbml0Q2xvbmVCeVRhZyA9IHJlcXVpcmUoJy4vaW5pdENsb25lQnlUYWcnKSxcbiAgICBpbml0Q2xvbmVPYmplY3QgPSByZXF1aXJlKCcuL2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbmNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG5jbG9uZWFibGVUYWdzW21hcFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF07XG4gICAgfVxuICB9XG4gIC8vIEFkZCB0aGUgc291cmNlIHZhbHVlIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cyBhbmQgYXNzb2NpYXRlIGl0IHdpdGggaXRzIGNsb25lLlxuICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJhc2VDbG9uZShzdWJWYWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFja0EsIHN0YWNrQik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcbiIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY3JlYXRlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFzc2lnbmluZ1xuICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvdHlwZSkge1xuICAgIGlmIChpc09iamVjdChwcm90b3R5cGUpKSB7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgb3RoVGFnID0gYXJyYXlUYWc7XG5cbiAgaWYgKCFvYmpJc0Fycikge1xuICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICBpZiAob2JqVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG9ialRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG9iaklzQXJyID0gaXNUeXBlZEFycmF5KG9iamVjdCk7XG4gICAgfVxuICB9XG4gIGlmICghb3RoSXNBcnIpIHtcbiAgICBvdGhUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG90aGVyKTtcbiAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG90aFRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG90aFRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG9iamVjdCksXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvdGhlciksXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsIi8qKlxuICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvT2JqZWN0KG9iamVjdClba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gIHJldHVybiBmdW5jO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0RGF0YTtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogKCtzdGFydCB8fCAwKTtcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gIH1cbiAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuZ3RoO1xuICB9XG4gIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgc3RhcnQgPj4+PSAwO1xuXG4gIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTbGljZTtcbiIsIi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBvciBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVGbG9vciA9IE1hdGguZmxvb3IsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBBcnJheUJ1ZmZlciA9IGdsb2JhbC5BcnJheUJ1ZmZlcixcbiAgICBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBnaXZlbiBhcnJheSBidWZmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBidWZmZXJDbG9uZShidWZmZXIpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXIuYnl0ZUxlbmd0aCksXG4gICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWZmZXJDbG9uZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMkoxWm1abGNrTnNiMjVsTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpOHFLaUJPWVhScGRtVWdiV1YwYUc5a0lISmxabVZ5Wlc1alpYTXVJQ292WEc1MllYSWdRWEp5WVhsQ2RXWm1aWElnUFNCbmJHOWlZV3d1UVhKeVlYbENkV1ptWlhJc1hHNGdJQ0FnVldsdWREaEJjbkpoZVNBOUlHZHNiMkpoYkM1VmFXNTBPRUZ5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JqYkc5dVpTQnZaaUIwYUdVZ1oybDJaVzRnWVhKeVlYa2dZblZtWm1WeUxseHVJQ3BjYmlBcUlFQndjbWwyWVhSbFhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVFuVm1abVZ5ZlNCaWRXWm1aWElnVkdobElHRnljbUY1SUdKMVptWmxjaUIwYnlCamJHOXVaUzVjYmlBcUlFQnlaWFIxY201eklIdEJjbkpoZVVKMVptWmxjbjBnVW1WMGRYSnVjeUIwYUdVZ1kyeHZibVZrSUdGeWNtRjVJR0oxWm1abGNpNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnlaWE4xYkhRZ1BTQnVaWGNnUVhKeVlYbENkV1ptWlhJb1luVm1abVZ5TG1KNWRHVk1aVzVuZEdncExGeHVJQ0FnSUNBZ2RtbGxkeUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSEpsYzNWc2RDazdYRzVjYmlBZ2RtbGxkeTV6WlhRb2JtVjNJRlZwYm5RNFFYSnlZWGtvWW5WbVptVnlLU2s3WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblZtWm1WeVEyeHZibVU3WEc0aVhYMD0iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVSnBibVJYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZM0psWVhSbFEzUnZjbGR5WVhCd1pYSWdQU0J5WlhGMWFYSmxLQ2N1TDJOeVpXRjBaVU4wYjNKWGNtRndjR1Z5SnlrN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnZEdobElHQjBhR2x6WUZ4dUlDb2dZbWx1WkdsdVp5QnZaaUJnZEdocGMwRnlaMkF1WEc0Z0tseHVJQ29nUUhCeWFYWmhkR1ZjYmlBcUlFQndZWEpoYlNCN1JuVnVZM1JwYjI1OUlHWjFibU1nVkdobElHWjFibU4wYVc5dUlIUnZJR0pwYm1RdVhHNGdLaUJBY0dGeVlXMGdleXA5SUZ0MGFHbHpRWEpuWFNCVWFHVWdZSFJvYVhOZ0lHSnBibVJwYm1jZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUtHWjFibU1zSUhSb2FYTkJjbWNwSUh0Y2JpQWdkbUZ5SUVOMGIzSWdQU0JqY21WaGRHVkRkRzl5VjNKaGNIQmxjaWhtZFc1aktUdGNibHh1SUNCbWRXNWpkR2x2YmlCM2NtRndjR1Z5S0NrZ2UxeHVJQ0FnSUhaaGNpQm1iaUE5SUNoMGFHbHpJQ1ltSUhSb2FYTWdJVDA5SUdkc2IySmhiQ0FtSmlCMGFHbHpJR2x1YzNSaGJtTmxiMllnZDNKaGNIQmxjaWtnUHlCRGRHOXlJRG9nWm5WdVl6dGNiaUFnSUNCeVpYUjFjbTRnWm00dVlYQndiSGtvZEdocGMwRnlaeXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWQ2FXNWtWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHMpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQpO1xuICAgIH1cbiAgICBpZiAoaXNDdXJyeSB8fCBpc0N1cnJ5UmlnaHQpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHdyYXBwZXIucGxhY2Vob2xkZXIsXG4gICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgIGxlbmd0aCAtPSBhcmdzSG9sZGVycy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3QXJpdHkgPSBuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApLFxuICAgICAgICAgICAgbmV3c0hvbGRlcnMgPSBpc0N1cnJ5ID8gYXJnc0hvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBhcmdzIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZWEp5WVhsRGIzQjVJRDBnY21WeGRXbHlaU2duTGk5aGNuSmhlVU52Y0hrbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmN5QTlJSEpsY1hWcGNtVW9KeTR2WTI5dGNHOXpaVUZ5WjNNbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmMxSnBaMmgwSUQwZ2NtVnhkV2x5WlNnbkxpOWpiMjF3YjNObFFYSm5jMUpwWjJoMEp5a3NYRzRnSUNBZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWtzWEc0Z0lDQWdhWE5NWVhwcFlXSnNaU0E5SUhKbGNYVnBjbVVvSnk0dmFYTk1ZWHBwWVdKc1pTY3BMRnh1SUNBZ0lISmxiM0prWlhJZ1BTQnlaWEYxYVhKbEtDY3VMM0psYjNKa1pYSW5LU3hjYmlBZ0lDQnlaWEJzWVdObFNHOXNaR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZjbVZ3YkdGalpVaHZiR1JsY25NbktTeGNiaUFnSUNCelpYUkVZWFJoSUQwZ2NtVnhkV2x5WlNnbkxpOXpaWFJFWVhSaEp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVN4Y2JpQWdJQ0JDU1U1RVgwdEZXVjlHVEVGSElEMGdNaXhjYmlBZ0lDQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSElEMGdOQ3hjYmlBZ0lDQkRWVkpTV1Y5R1RFRkhJRDBnT0N4Y2JpQWdJQ0JEVlZKU1dWOVNTVWRJVkY5R1RFRkhJRDBnTVRZc1hHNGdJQ0FnVUVGU1ZFbEJURjlHVEVGSElEMGdNeklzWEc0Z0lDQWdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRDBnTmpRc1hHNGdJQ0FnUVZKWlgwWk1RVWNnUFNBeE1qZzdYRzVjYmk4cUlFNWhkR2wyWlNCdFpYUm9iMlFnY21WbVpYSmxibU5sY3lCbWIzSWdkR2h2YzJVZ2QybDBhQ0IwYUdVZ2MyRnRaU0J1WVcxbElHRnpJRzkwYUdWeUlHQnNiMlJoYzJoZ0lHMWxkR2h2WkhNdUlDb3ZYRzUyWVhJZ2JtRjBhWFpsVFdGNElEMGdUV0YwYUM1dFlYZzdYRzVjYmk4cUtseHVJQ29nUTNKbFlYUmxjeUJoSUdaMWJtTjBhVzl1SUhSb1lYUWdkM0poY0hNZ1lHWjFibU5nSUdGdVpDQnBiblp2YTJWeklHbDBJSGRwZEdnZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1MQ0J3WVhKMGFXRnNJR0Z3Y0d4cFkyRjBhVzl1TENCaGJtUWdZM1Z5Y25scGJtY3VYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU4YzNSeWFXNW5mU0JtZFc1aklGUm9aU0JtZFc1amRHbHZiaUJ2Y2lCdFpYUm9iMlFnYm1GdFpTQjBieUJ5WldabGNtVnVZMlV1WEc0Z0tpQkFjR0Z5WVcwZ2UyNTFiV0psY24wZ1ltbDBiV0Z6YXlCVWFHVWdZbWwwYldGemF5QnZaaUJtYkdGbmN5NGdVMlZsSUdCamNtVmhkR1ZYY21Gd2NHVnlZQ0JtYjNJZ2JXOXlaU0JrWlhSaGFXeHpMbHh1SUNvZ1FIQmhjbUZ0SUhzcWZTQmJkR2hwYzBGeVoxMGdWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUZ0d1lYSjBhV0ZzYzEwZ1ZHaGxJR0Z5WjNWdFpXNTBjeUIwYnlCd2NtVndaVzVrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdklIUm9aU0J1WlhjZ1puVnVZM1JwYjI0dVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNWZTQmJhRzlzWkdWeWMxMGdWR2hsSUdCd1lYSjBhV0ZzYzJBZ2NHeGhZMlZvYjJ4a1pYSWdhVzVrWlhobGN5NWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMUpwWjJoMFhTQlVhR1VnWVhKbmRXMWxiblJ6SUhSdklHRndjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMmh2YkdSbGNuTlNhV2RvZEYwZ1ZHaGxJR0J3WVhKMGFXRnNjMUpwWjJoMFlDQndiR0ZqWldodmJHUmxjaUJwYm1SbGVHVnpMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlWDBnVzJGeVoxQnZjMTBnVkdobElHRnlaM1Z0Wlc1MElIQnZjMmwwYVc5dWN5QnZaaUIwYUdVZ2JtVjNJR1oxYm1OMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUZ0aGNubGRJRlJvWlNCaGNtbDBlU0JqWVhBZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY21sMGVWMGdWR2hsSUdGeWFYUjVJRzltSUdCbWRXNWpZQzVjYmlBcUlFQnlaWFIxY201eklIdEdkVzVqZEdsdmJuMGdVbVYwZFhKdWN5QjBhR1VnYm1WM0lIZHlZWEJ3WldRZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJb1puVnVZeXdnWW1sMGJXRnpheXdnZEdocGMwRnlaeXdnY0dGeWRHbGhiSE1zSUdodmJHUmxjbk1zSUhCaGNuUnBZV3h6VW1sbmFIUXNJR2h2YkdSbGNuTlNhV2RvZEN3Z1lYSm5VRzl6TENCaGNua3NJR0Z5YVhSNUtTQjdYRzRnSUhaaGNpQnBjMEZ5ZVNBOUlHSnBkRzFoYzJzZ0ppQkJVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRbWx1WkNBOUlHSnBkRzFoYzJzZ0ppQkNTVTVFWDBaTVFVY3NYRzRnSUNBZ0lDQnBjMEpwYm1STFpYa2dQU0JpYVhSdFlYTnJJQ1lnUWtsT1JGOUxSVmxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25rZ1BTQmlhWFJ0WVhOcklDWWdRMVZTVWxsZlJreEJSeXhjYmlBZ0lDQWdJR2x6UTNWeWNubENiM1Z1WkNBOUlHSnBkRzFoYzJzZ0ppQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSExGeHVJQ0FnSUNBZ2FYTkRkWEp5ZVZKcFoyaDBJRDBnWW1sMGJXRnpheUFtSUVOVlVsSlpYMUpKUjBoVVgwWk1RVWNzWEc0Z0lDQWdJQ0JEZEc5eUlEMGdhWE5DYVc1a1MyVjVJRDhnZFc1a1pXWnBibVZrSURvZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJb1puVnVZeWs3WEc1Y2JpQWdablZ1WTNScGIyNGdkM0poY0hCbGNpZ3BJSHRjYmlBZ0lDQXZMeUJCZG05cFpDQmdZWEpuZFcxbGJuUnpZQ0J2WW1wbFkzUWdkWE5sSUdScGMzRjFZV3hwWm5scGJtY2diM0IwYVcxcGVtRjBhVzl1Y3lCaWVWeHVJQ0FnSUM4dklHTnZiblpsY25ScGJtY2dhWFFnZEc4Z1lXNGdZWEp5WVhrZ1ltVm1iM0psSUhCeWIzWnBaR2x1WnlCcGRDQjBieUJ2ZEdobGNpQm1kVzVqZEdsdmJuTXVYRzRnSUNBZ2RtRnlJR3hsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR2x1WkdWNElEMGdiR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWdVozUm9LVHRjYmx4dUlDQWdJSGRvYVd4bElDaHBibVJsZUMwdEtTQjdYRzRnSUNBZ0lDQmhjbWR6VzJsdVpHVjRYU0E5SUdGeVozVnRaVzUwYzF0cGJtUmxlRjA3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2h3WVhKMGFXRnNjeWtnZTF4dUlDQWdJQ0FnWVhKbmN5QTlJR052YlhCdmMyVkJjbWR6S0dGeVozTXNJSEJoY25ScFlXeHpMQ0JvYjJ4a1pYSnpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSEJoY25ScFlXeHpVbWxuYUhRcElIdGNiaUFnSUNBZ0lHRnlaM01nUFNCamIyMXdiM05sUVhKbmMxSnBaMmgwS0dGeVozTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2hwYzBOMWNuSjVJSHg4SUdselEzVnljbmxTYVdkb2RDa2dlMXh1SUNBZ0lDQWdkbUZ5SUhCc1lXTmxhRzlzWkdWeUlEMGdkM0poY0hCbGNpNXdiR0ZqWldodmJHUmxjaXhjYmlBZ0lDQWdJQ0FnSUNCaGNtZHpTRzlzWkdWeWN5QTlJSEpsY0d4aFkyVkliMnhrWlhKektHRnlaM01zSUhCc1lXTmxhRzlzWkdWeUtUdGNibHh1SUNBZ0lDQWdiR1Z1WjNSb0lDMDlJR0Z5WjNOSWIyeGtaWEp6TG14bGJtZDBhRHRjYmlBZ0lDQWdJR2xtSUNoc1pXNW5kR2dnUENCaGNtbDBlU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzUVhKblVHOXpJRDBnWVhKblVHOXpJRDhnWVhKeVlYbERiM0I1S0dGeVoxQnZjeWtnT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkQmNtbDBlU0E5SUc1aGRHbDJaVTFoZUNoaGNtbDBlU0F0SUd4bGJtZDBhQ3dnTUNrc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkelNHOXNaR1Z5Y3lBOUlHbHpRM1Z5Y25rZ1B5QmhjbWR6U0c5c1pHVnljeUE2SUhWdVpHVm1hVzVsWkN4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDBodmJHUmxjbk5TYVdkb2RDQTlJR2x6UTNWeWNua2dQeUIxYm1SbFptbHVaV1FnT2lCaGNtZHpTRzlzWkdWeWN5eGNiaUFnSUNBZ0lDQWdJQ0FnSUc1bGQxQmhjblJwWVd4eklEMGdhWE5EZFhKeWVTQS9JR0Z5WjNNZ09pQjFibVJsWm1sdVpXUXNYRzRnSUNBZ0lDQWdJQ0FnSUNCdVpYZFFZWEowYVdGc2MxSnBaMmgwSUQwZ2FYTkRkWEp5ZVNBL0lIVnVaR1ZtYVc1bFpDQTZJR0Z5WjNNN1hHNWNiaUFnSUNBZ0lDQWdZbWwwYldGemF5QjhQU0FvYVhORGRYSnllU0EvSUZCQlVsUkpRVXhmUmt4QlJ5QTZJRkJCVWxSSlFVeGZVa2xIU0ZSZlJreEJSeWs3WEc0Z0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaHBjME4xY25KNUlEOGdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRG9nVUVGU1ZFbEJURjlHVEVGSEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb0lXbHpRM1Z5Y25sQ2IzVnVaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHSnBkRzFoYzJzZ0pqMGdmaWhDU1U1RVgwWk1RVWNnZkNCQ1NVNUVYMHRGV1Y5R1RFRkhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVYzUkdGMFlTQTlJRnRtZFc1akxDQmlhWFJ0WVhOckxDQjBhR2x6UVhKbkxDQnVaWGRRWVhKMGFXRnNjeXdnYm1WM2MwaHZiR1JsY25Nc0lHNWxkMUJoY25ScFlXeHpVbWxuYUhRc0lHNWxkMGh2YkdSbGNuTlNhV2RvZEN3Z2JtVjNRWEpuVUc5ekxDQmhjbmtzSUc1bGQwRnlhWFI1WFN4Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNWc2RDQTlJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1WVhCd2JIa29kVzVrWldacGJtVmtMQ0J1WlhkRVlYUmhLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hWE5NWVhwcFlXSnNaU2htZFc1aktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhObGRFUmhkR0VvY21WemRXeDBMQ0J1WlhkRVlYUmhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYTjFiSFF1Y0d4aFkyVm9iMnhrWlhJZ1BTQndiR0ZqWldodmJHUmxjanRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYzNWc2REdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlIUm9hWE5DYVc1a2FXNW5JRDBnYVhOQ2FXNWtJRDhnZEdocGMwRnlaeUE2SUhSb2FYTXNYRzRnSUNBZ0lDQWdJR1p1SUQwZ2FYTkNhVzVrUzJWNUlEOGdkR2hwYzBKcGJtUnBibWRiWm5WdVkxMGdPaUJtZFc1ak8xeHVYRzRnSUNBZ2FXWWdLR0Z5WjFCdmN5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlISmxiM0prWlhJb1lYSm5jeXdnWVhKblVHOXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLR2x6UVhKNUlDWW1JR0Z5ZVNBOElHRnlaM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0JoY21kekxteGxibWQwYUNBOUlHRnllVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJvYVhNZ0ppWWdkR2hwY3lBaFBUMGdaMnh2WW1Gc0lDWW1JSFJvYVhNZ2FXNXpkR0Z1WTJWdlppQjNjbUZ3Y0dWeUtTQjdYRzRnSUNBZ0lDQm1iaUE5SUVOMGIzSWdmSHdnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUJtYmk1aGNIQnNlU2gwYUdselFtbHVaR2x1Wnl3Z1lYSm5jeWs3WEc0Z0lIMWNiaUFnY21WMGRYSnVJSGR5WVhCd1pYSTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1kzSmxZWFJsU0hsaWNtbGtWM0poY0hCbGNqdGNiaUpkZlE9PSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAqIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqIHRoZSB3cmFwcGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBDdG9yID0gY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCBgZnVuY2AuXG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgfVxuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVBhcnRpYWxXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJR052YlhCdmMyVWdZbWwwYldGemEzTWdabTl5SUhkeVlYQndaWElnYldWMFlXUmhkR0V1SUNvdlhHNTJZWElnUWtsT1JGOUdURUZISUQwZ01UdGNibHh1THlvcVhHNGdLaUJEY21WaGRHVnpJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQjNjbUZ3Y3lCZ1puVnVZMkFnWVc1a0lHbHVkbTlyWlhNZ2FYUWdkMmwwYUNCMGFHVWdiM0IwYVc5dVlXd2dZSFJvYVhOZ1hHNGdLaUJpYVc1a2FXNW5JRzltSUdCMGFHbHpRWEpuWUNCaGJtUWdkR2hsSUdCd1lYSjBhV0ZzYzJBZ2NISmxjR1Z1WkdWa0lIUnZJSFJvYjNObElIQnliM1pwWkdWa0lIUnZYRzRnS2lCMGFHVWdkM0poY0hCbGNpNWNiaUFxWEc0Z0tpQkFjSEpwZG1GMFpWeHVJQ29nUUhCaGNtRnRJSHRHZFc1amRHbHZibjBnWm5WdVl5QlVhR1VnWm5WdVkzUnBiMjRnZEc4Z2NHRnlkR2xoYkd4NUlHRndjR3g1SUdGeVozVnRaVzUwY3lCMGJ5NWNiaUFxSUVCd1lYSmhiU0I3Ym5WdFltVnlmU0JpYVhSdFlYTnJJRlJvWlNCaWFYUnRZWE5ySUc5bUlHWnNZV2R6TGlCVFpXVWdZR055WldGMFpWZHlZWEJ3WlhKZ0lHWnZjaUJ0YjNKbElHUmxkR0ZwYkhNdVhHNGdLaUJBY0dGeVlXMGdleXA5SUhSb2FYTkJjbWNnVkdobElHQjBhR2x6WUNCaWFXNWthVzVuSUc5bUlHQm1kVzVqWUM1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlIQmhjblJwWVd4eklGUm9aU0JoY21kMWJXVnVkSE1nZEc4Z2NISmxjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlLR1oxYm1Nc0lHSnBkRzFoYzJzc0lIUm9hWE5CY21jc0lIQmhjblJwWVd4ektTQjdYRzRnSUhaaGNpQnBjMEpwYm1RZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5R1RFRkhMRnh1SUNBZ0lDQWdRM1J2Y2lBOUlHTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUtHWjFibU1wTzF4dVhHNGdJR1oxYm1OMGFXOXVJSGR5WVhCd1pYSW9LU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdZR0Z5WjNWdFpXNTBjMkFnYjJKcVpXTjBJSFZ6WlNCa2FYTnhkV0ZzYVdaNWFXNW5JRzl3ZEdsdGFYcGhkR2x2Ym5NZ1lubGNiaUFnSUNBdkx5QmpiMjUyWlhKMGFXNW5JR2wwSUhSdklHRnVJR0Z5Y21GNUlHSmxabTl5WlNCd2NtOTJhV1JwYm1jZ2FYUWdZR1oxYm1OZ0xseHVJQ0FnSUhaaGNpQmhjbWR6U1c1a1pYZ2dQU0F0TVN4Y2JpQWdJQ0FnSUNBZ1lYSm5jMHhsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR3hsWm5SSmJtUmxlQ0E5SUMweExGeHVJQ0FnSUNBZ0lDQnNaV1owVEdWdVozUm9JRDBnY0dGeWRHbGhiSE11YkdWdVozUm9MRnh1SUNBZ0lDQWdJQ0JoY21keklEMGdRWEp5WVhrb2JHVm1kRXhsYm1kMGFDQXJJR0Z5WjNOTVpXNW5kR2dwTzF4dVhHNGdJQ0FnZDJocGJHVWdLQ3NyYkdWbWRFbHVaR1Y0SUR3Z2JHVm1kRXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhoZElEMGdjR0Z5ZEdsaGJITmJiR1ZtZEVsdVpHVjRYVHRjYmlBZ0lDQjlYRzRnSUNBZ2QyaHBiR1VnS0dGeVozTk1aVzVuZEdndExTa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhncksxMGdQU0JoY21kMWJXVnVkSE5iS3l0aGNtZHpTVzVrWlhoZE8xeHVJQ0FnSUgxY2JpQWdJQ0IyWVhJZ1ptNGdQU0FvZEdocGN5QW1KaUIwYUdseklDRTlQU0JuYkc5aVlXd2dKaVlnZEdocGN5QnBibk4wWVc1alpXOW1JSGR5WVhCd1pYSXBJRDhnUTNSdmNpQTZJR1oxYm1NN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLR2x6UW1sdVpDQS9JSFJvYVhOQmNtY2dPaUIwYUdsekxDQmhjbWR6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWUVlYSjBhV0ZzVjNKaGNIQmxjanRjYmlKZGZRPT0iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgY3JlYXRlQmluZFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUJpbmRXcmFwcGVyJyksXG4gICAgY3JlYXRlSHlicmlkV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlSHlicmlkV3JhcHBlcicpLFxuICAgIGNyZWF0ZVBhcnRpYWxXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVQYXJ0aWFsV3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBtZXJnZURhdGEgPSByZXF1aXJlKCcuL21lcmdlRGF0YScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL3NldERhdGEnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxLFxuICAgIEJJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0O1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gKiAgVGhlIGJpdG1hc2sgbWF5IGJlIGNvbXBvc2VkIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6XG4gKiAgICAgMSAtIGBfLmJpbmRgXG4gKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gKiAgICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICAgOCAtIGBfLmN1cnJ5YFxuICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICogICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gKiAgIDEyOCAtIGBfLnJlYXJnYFxuICogICAyNTYgLSBgXy5hcnlgXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRztcbiAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGJpdG1hc2sgJj0gfihQQVJUSUFMX0ZMQUcgfCBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpLFxuICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgbWVyZ2VEYXRhKG5ld0RhdGEsIGRhdGEpO1xuICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgIGFyaXR5ID0gbmV3RGF0YVs5XTtcbiAgfVxuICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICA6IChuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApIHx8IDApO1xuXG4gIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kV3JhcHBlcihuZXdEYXRhWzBdLCBuZXdEYXRhWzJdKTtcbiAgfSBlbHNlIGlmICgoYml0bWFzayA9PSBQQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoQklORF9GTEFHIHwgUEFSVElBTF9GTEFHKSkgJiYgIW5ld0RhdGFbNF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG4gIH1cbiAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gIHJldHVybiBzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVXcmFwcGVyO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vYXJyYXlTb21lJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIGFycmF5cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDtcblxuICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgdmFyIGFyclZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogYXJyVmFsdWUsIGlzTG9vc2UgPyBhcnJWYWx1ZSA6IG90aFZhbHVlLCBpbmRleCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEFycmF5cztcbiIsIi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbC5cbiAgICAgIHJldHVybiArb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICByZXR1cm4gKG9iamVjdCAhPSArb2JqZWN0KVxuICAgICAgICA/IG90aGVyICE9ICtvdGhlclxuICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAvLyBvYmplY3RzIGFzIGVxdWFsLiBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTAuNi40IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxCeVRhZztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICBvdGhQcm9wcyA9IGtleXMob3RoZXIpLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc0xvb3NlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzTG9vc2UgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB2YXIgc2tpcEN0b3IgPSBpc0xvb3NlO1xuICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBvYmpWYWx1ZSwgaXNMb29zZT8gb2JqVmFsdWUgOiBvdGhWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gIH1cbiAgaWYgKCFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbE9iamVjdHM7XG4iLCJ2YXIgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuLi91dGlsaXR5L25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9yZWFsTmFtZXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJsdWFYUkRiRzl1WlVKNVZHRm5MbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWW5WbVptVnlRMnh2Ym1VZ1BTQnlaWEYxYVhKbEtDY3VMMkoxWm1abGNrTnNiMjVsSnlrN1hHNWNiaThxS2lCZ1QySnFaV04wSTNSdlUzUnlhVzVuWUNCeVpYTjFiSFFnY21WbVpYSmxibU5sY3k0Z0tpOWNiblpoY2lCaWIyOXNWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1FtOXZiR1ZoYmwwbkxGeHVJQ0FnSUdSaGRHVlVZV2NnUFNBblcyOWlhbVZqZENCRVlYUmxYU2NzWEc0Z0lDQWdiblZ0WW1WeVZHRm5JRDBnSjF0dlltcGxZM1FnVG5WdFltVnlYU2NzWEc0Z0lDQWdjbVZuWlhod1ZHRm5JRDBnSjF0dlltcGxZM1FnVW1WblJYaHdYU2NzWEc0Z0lDQWdjM1J5YVc1blZHRm5JRDBnSjF0dlltcGxZM1FnVTNSeWFXNW5YU2M3WEc1Y2JuWmhjaUJoY25KaGVVSjFabVpsY2xSaFp5QTlJQ2RiYjJKcVpXTjBJRUZ5Y21GNVFuVm1abVZ5WFNjc1hHNGdJQ0FnWm14dllYUXpNbFJoWnlBOUlDZGJiMkpxWldOMElFWnNiMkYwTXpKQmNuSmhlVjBuTEZ4dUlDQWdJR1pzYjJGME5qUlVZV2NnUFNBblcyOWlhbVZqZENCR2JHOWhkRFkwUVhKeVlYbGRKeXhjYmlBZ0lDQnBiblE0VkdGbklEMGdKMXR2WW1wbFkzUWdTVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5ReE5rRnljbUY1WFNjc1hHNGdJQ0FnYVc1ME16SlVZV2NnUFNBblcyOWlhbVZqZENCSmJuUXpNa0Z5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdkV2x1ZERoRGJHRnRjR1ZrVkdGbklEMGdKMXR2WW1wbFkzUWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYbGRKeXhjYmlBZ0lDQjFhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JWYVc1ME1UWkJjbkpoZVYwbkxGeHVJQ0FnSUhWcGJuUXpNbFJoWnlBOUlDZGJiMkpxWldOMElGVnBiblF6TWtGeWNtRjVYU2M3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJRzFoZEdOb0lHQlNaV2RGZUhCZ0lHWnNZV2R6SUdaeWIyMGdkR2hsYVhJZ1kyOWxjbU5sWkNCemRISnBibWNnZG1Gc2RXVnpMaUFxTDF4dWRtRnlJSEpsUm14aFozTWdQU0F2WEZ4M0tpUXZPMXh1WEc0dktpb2dUbUYwYVhabElHMWxkR2h2WkNCeVpXWmxjbVZ1WTJWekxpQXFMMXh1ZG1GeUlGVnBiblE0UVhKeVlYa2dQU0JuYkc5aVlXd3VWV2x1ZERoQmNuSmhlVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdiRzl2YTNWd0lHRWdkSGx3WlNCaGNuSmhlU0JqYjI1emRISjFZM1J2Y25NZ1lua2dZSFJ2VTNSeWFXNW5WR0ZuWUM0Z0tpOWNiblpoY2lCamRHOXlRbmxVWVdjZ1BTQjdmVHRjYm1OMGIzSkNlVlJoWjF0bWJHOWhkRE15VkdGblhTQTlJR2RzYjJKaGJDNUdiRzloZERNeVFYSnlZWGs3WEc1amRHOXlRbmxVWVdkYlpteHZZWFEyTkZSaFoxMGdQU0JuYkc5aVlXd3VSbXh2WVhRMk5FRnljbUY1TzF4dVkzUnZja0o1VkdGblcybHVkRGhVWVdkZElEMGdaMnh2WW1Gc0xrbHVkRGhCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXRwYm5ReE5sUmhaMTBnUFNCbmJHOWlZV3d1U1c1ME1UWkJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF6TWxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTXpKQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBPRlJoWjEwZ1BTQlZhVzUwT0VGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzNWcGJuUTRRMnhoYlhCbFpGUmhaMTBnUFNCbmJHOWlZV3d1VldsdWREaERiR0Z0Y0dWa1FYSnlZWGs3WEc1amRHOXlRbmxVWVdkYmRXbHVkREUyVkdGblhTQTlJR2RzYjJKaGJDNVZhVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBNekpVWVdkZElEMGdaMnh2WW1Gc0xsVnBiblF6TWtGeWNtRjVPMXh1WEc0dktpcGNiaUFxSUVsdWFYUnBZV3hwZW1WeklHRnVJRzlpYW1WamRDQmpiRzl1WlNCaVlYTmxaQ0J2YmlCcGRITWdZSFJ2VTNSeWFXNW5WR0ZuWUM1Y2JpQXFYRzRnS2lBcUtrNXZkR1U2S2lvZ1ZHaHBjeUJtZFc1amRHbHZiaUJ2Ym14NUlITjFjSEJ2Y25SeklHTnNiMjVwYm1jZ2RtRnNkV1Z6SUhkcGRHZ2dkR0ZuY3lCdlpseHVJQ29nWUVKdmIyeGxZVzVnTENCZ1JHRjBaV0FzSUdCRmNuSnZjbUFzSUdCT2RXMWlaWEpnTENCZ1VtVm5SWGh3WUN3Z2IzSWdZRk4wY21sdVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3VDJKcVpXTjBmU0J2WW1wbFkzUWdWR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFlXY2dWR2hsSUdCMGIxTjBjbWx1WjFSaFoyQWdiMllnZEdobElHOWlhbVZqZENCMGJ5QmpiRzl1WlM1Y2JpQXFJRUJ3WVhKaGJTQjdZbTl2YkdWaGJuMGdXMmx6UkdWbGNGMGdVM0JsWTJsbWVTQmhJR1JsWlhBZ1kyeHZibVV1WEc0Z0tpQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlNaWFIxY201eklIUm9aU0JwYm1sMGFXRnNhWHBsWkNCamJHOXVaUzVjYmlBcUwxeHVablZ1WTNScGIyNGdhVzVwZEVOc2IyNWxRbmxVWVdjb2IySnFaV04wTENCMFlXY3NJR2x6UkdWbGNDa2dlMXh1SUNCMllYSWdRM1J2Y2lBOUlHOWlhbVZqZEM1amIyNXpkSEoxWTNSdmNqdGNiaUFnYzNkcGRHTm9JQ2gwWVdjcElIdGNiaUFnSUNCallYTmxJR0Z5Y21GNVFuVm1abVZ5VkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUdKMVptWmxja05zYjI1bEtHOWlhbVZqZENrN1hHNWNiaUFnSUNCallYTmxJR0p2YjJ4VVlXYzZYRzRnSUNBZ1kyRnpaU0JrWVhSbFZHRm5PbHh1SUNBZ0lDQWdjbVYwZFhKdUlHNWxkeUJEZEc5eUtDdHZZbXBsWTNRcE8xeHVYRzRnSUNBZ1kyRnpaU0JtYkc5aGRETXlWR0ZuT2lCallYTmxJR1pzYjJGME5qUlVZV2M2WEc0Z0lDQWdZMkZ6WlNCcGJuUTRWR0ZuT2lCallYTmxJR2x1ZERFMlZHRm5PaUJqWVhObElHbHVkRE15VkdGbk9seHVJQ0FnSUdOaGMyVWdkV2x1ZERoVVlXYzZJR05oYzJVZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuT2lCallYTmxJSFZwYm5ReE5sUmhaem9nWTJGelpTQjFhVzUwTXpKVVlXYzZYRzRnSUNBZ0lDQXZMeUJUWVdaaGNta2dOU0J0YjJKcGJHVWdhVzVqYjNKeVpXTjBiSGtnYUdGeklHQlBZbXBsWTNSZ0lHRnpJSFJvWlNCamIyNXpkSEoxWTNSdmNpQnZaaUIwZVhCbFpDQmhjbkpoZVhNdVhHNGdJQ0FnSUNCcFppQW9RM1J2Y2lCcGJuTjBZVzVqWlc5bUlFTjBiM0lwSUh0Y2JpQWdJQ0FnSUNBZ1EzUnZjaUE5SUdOMGIzSkNlVlJoWjF0MFlXZGRPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkbUZ5SUdKMVptWmxjaUE5SUc5aWFtVmpkQzVpZFdabVpYSTdYRzRnSUNBZ0lDQnlaWFIxY200Z2JtVjNJRU4wYjNJb2FYTkVaV1Z3SUQ4Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQTZJR0oxWm1abGNpd2diMkpxWldOMExtSjVkR1ZQWm1aelpYUXNJRzlpYW1WamRDNXNaVzVuZEdncE8xeHVYRzRnSUNBZ1kyRnpaU0J1ZFcxaVpYSlVZV2M2WEc0Z0lDQWdZMkZ6WlNCemRISnBibWRVWVdjNlhHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYjJKcVpXTjBLVHRjYmx4dUlDQWdJR05oYzJVZ2NtVm5aWGh3VkdGbk9seHVJQ0FnSUNBZ2RtRnlJSEpsYzNWc2RDQTlJRzVsZHlCRGRHOXlLRzlpYW1WamRDNXpiM1Z5WTJVc0lISmxSbXhoWjNNdVpYaGxZeWh2WW1wbFkzUXBLVHRjYmlBZ0lDQWdJSEpsYzNWc2RDNXNZWE4wU1c1a1pYZ2dQU0J2WW1wbFkzUXViR0Z6ZEVsdVpHVjRPMXh1SUNCOVhHNGdJSEpsZEhWeWJpQnlaWE4xYkhRN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnYVc1cGRFTnNiMjVsUW5sVVlXYzdYRzRpWFgwPSIsIi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICBDdG9yID0gT2JqZWN0O1xuICB9XG4gIHJldHVybiBuZXcgQ3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xudmFyIGlzSG9zdE9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QoeyAndG9TdHJpbmcnOiAwIH0gKyAnJyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIElFIDwgOSBwcmVzZW50cyBtYW55IGhvc3Qgb2JqZWN0cyBhcyBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZVxuICAgIC8vIHRvIHN0cmluZ3MgZGVzcGl0ZSBoYXZpbmcgaW1wcm9wZXJseSBkZWZpbmVkIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicgJiYgdHlwZW9mICh2YWx1ZSArICcnKSA9PSAnc3RyaW5nJztcbiAgfTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNIb3N0T2JqZWN0O1xuIiwiLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL15cXGQrJC87XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IHJlSXNVaW50LnRlc3QodmFsdWUpKSA/ICt2YWx1ZSA6IC0xO1xuICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gIHJldHVybiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSW5kZXg7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuIiwidmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlSXNEZWVwUHJvcCA9IC9cXC58XFxbKD86W15bXFxdXSp8KFtcIiddKSg/Oig/IVxcMSlbXlxcblxcXFxdfFxcXFwuKSo/XFwxKVxcXS8sXG4gICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICgodHlwZSA9PSAnc3RyaW5nJyAmJiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpKSB8fCB0eXBlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciByZXN1bHQgPSAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpO1xuICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleTtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9nZXREYXRhJyksXG4gICAgZ2V0RnVuY05hbWUgPSByZXF1aXJlKCcuL2dldEZ1bmNOYW1lJyksXG4gICAgbG9kYXNoID0gcmVxdWlyZSgnLi4vY2hhaW4vbG9kYXNoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpY3RDb21wYXJhYmxlO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9yZXBsYWNlSG9sZGVycycpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQVJZX0ZMQUcgPSAxMjgsXG4gICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gKlxuICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgcmVxdWlyZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAqIGF1Z21lbnQgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGV4ZWN1dGVkIGltcG9ydGFudCxcbiAqIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBhIHNhZmVcbiAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCBBUllfRkxBRztcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKSB8fFxuICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gUkVBUkdfRkxBRyAmJiBkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICBpZiAodmFsdWUpIHtcbiAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs0XSk7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs2XSk7XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gIHZhbHVlID0gc291cmNlWzddO1xuICBpZiAodmFsdWUpIHtcbiAgICBkYXRhWzddID0gYXJyYXlDb3B5KHZhbHVlKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBBUllfRkxBRykge1xuICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICBkYXRhWzBdID0gc291cmNlWzBdO1xuICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICByZXR1cm4gZGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtZXJnZURhdGE7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMjFsZEdGTllYQXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1oyVjBUbUYwYVhabElEMGdjbVZ4ZFdseVpTZ25MaTluWlhST1lYUnBkbVVuS1R0Y2JseHVMeW9xSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJYWldGclRXRndJRDBnWjJWMFRtRjBhWFpsS0dkc2IySmhiQ3dnSjFkbFlXdE5ZWEFuS1R0Y2JseHVMeW9xSUZWelpXUWdkRzhnYzNSdmNtVWdablZ1WTNScGIyNGdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdiV1YwWVUxaGNDQTlJRmRsWVd0TllYQWdKaVlnYm1WM0lGZGxZV3ROWVhBN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdiV1YwWVUxaGNEdGNiaUpkZlE9PSIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgIG9sZEFycmF5ID0gYXJyYXlDb3B5KGFycmF5KTtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlb3JkZXI7XG4iLCIvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdG8gcmVwbGFjZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcGxhY2VIb2xkZXJzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9iYXNlU2V0RGF0YScpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4uL2RhdGUvbm93Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCB3aGVuIGEgZnVuY3Rpb24gYmVjb21lcyBob3QuICovXG52YXIgSE9UX0NPVU5UID0gMTUwLFxuICAgIEhPVF9TUEFOID0gMTY7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eSBmdW5jdGlvblxuICogdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgc3RhbXAgPSBub3coKSxcbiAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXRhO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQncyBpbnZva2VkXG4gKiB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjbG9uaW5nXG4gKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAqIGFuZCBpbnZva2VkIHdpdGggdXAgdG8gdGhyZWUgYXJndW1lbnQ7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdF0pLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZVxuICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9pbmZyYXN0cnVjdHVyZS5odG1sI2ludGVybmFsLXN0cnVjdHVyZWQtY2xvbmluZy1hbGdvcml0aG0pLlxuICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAqIGNvbnN0cnVjdG9ycyBvdGhlciB0aGFuIGBPYmplY3RgIGFyZSBjbG9uZWQgdG8gcGxhaW4gYE9iamVjdGAgb2JqZWN0cy4gQW5cbiAqIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2ggYXMgZnVuY3Rpb25zLCBET00gbm9kZXMsXG4gKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAqIF07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcCh1c2Vycyk7XG4gKiBkZWVwWzBdID09PSB1c2Vyc1swXTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgfVxuICogfSk7XG4gKlxuICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAqIC8vID0+IGZhbHNlXG4gKiBlbC5ub2RlTmFtZVxuICogLy8gPT4gQk9EWVxuICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gKiAvLyA9PiAyMFxuICovXG5mdW5jdGlvbiBjbG9uZURlZXAodmFsdWUsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDMpKVxuICAgIDogYmFzZUNsb25lKHZhbHVlLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZURlZXA7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJiAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCdzIGFuXG4gKiBgYXJndW1lbnRzYCBvYmplY3QsIGFycmF5LCBzdHJpbmcsIG9yIGpRdWVyeS1saWtlIGNvbGxlY3Rpb24gd2l0aCBhIGxlbmd0aFxuICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNFbXB0eShudWxsKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkodHJ1ZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJiAoaXNBcnJheSh2YWx1ZSkgfHwgaXNTdHJpbmcodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNGdW5jdGlvbih2YWx1ZS5zcGxpY2UpKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gIWtleXModmFsdWUpLmxlbmd0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VtcHR5O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFzc3VtZXMgb2JqZWN0cyBjcmVhdGVkIGJ5IHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3RvclxuICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiB9XG4gKlxuICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSAmJiAhaXNBcmd1bWVudHModmFsdWUpKSB8fFxuICAgICAgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY29uc3RydWN0b3InKSAmJiAoQ3RvciA9IHZhbHVlLmNvbnN0cnVjdG9yLCB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmICEoQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSUUgPCA5IGl0ZXJhdGVzIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy4gSWYgdGhlIGZpcnN0XG4gIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgLy8gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICB2YXIgcmVzdWx0O1xuICBpZiAoc3VwcG9ydC5vd25MYXN0KSB7XG4gICAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIHJlc3VsdCA9IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgIT09IGZhbHNlO1xuICB9XG4gIC8vIEluIG1vc3QgZW52aXJvbm1lbnRzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBiZWZvcmVcbiAgLy8gaXRzIGluaGVyaXRlZCBwcm9wZXJ0aWVzLiBJZiB0aGUgbGFzdCBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3Qnc1xuICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0ID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHJlc3VsdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcbiIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1VuZGVmaW5lZDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgc2hpbUtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltS2V5cycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicgPyBzdXBwb3J0LmVudW1Qcm90b3R5cGVzIDogaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5RWFjaCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vbGFuZy9pc0Z1bmN0aW9uJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCB0byBmaXggdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnLiAqL1xudmFyIHNoYWRvd1Byb3BzID0gW1xuICAnY29uc3RydWN0b3InLCAnaGFzT3duUHJvcGVydHknLCAnaXNQcm90b3R5cGVPZicsICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsICd0b1N0cmluZycsICd2YWx1ZU9mJ1xuXTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICBzdHJpbmdQcm90byA9IFN0cmluZy5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGF2b2lkIGl0ZXJhdGluZyBvdmVyIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW4gSUUgPCA5LiAqL1xudmFyIG5vbkVudW1Qcm9wcyA9IHt9O1xubm9uRW51bVByb3BzW2FycmF5VGFnXSA9IG5vbkVudW1Qcm9wc1tkYXRlVGFnXSA9IG5vbkVudW1Qcm9wc1tudW1iZXJUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tib29sVGFnXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tlcnJvclRhZ10gPSBub25FbnVtUHJvcHNbZnVuY1RhZ10gPSBub25FbnVtUHJvcHNbcmVnZXhwVGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW29iamVjdFRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcblxuYXJyYXlFYWNoKHNoYWRvd1Byb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgZm9yICh2YXIgdGFnIGluIG5vbkVudW1Qcm9wcykge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vbkVudW1Qcm9wcywgdGFnKSkge1xuICAgICAgdmFyIHByb3BzID0gbm9uRW51bVByb3BzW3RhZ107XG4gICAgICBwcm9wc1trZXldID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm9wcywga2V5KTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuXG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgcHJvdG8gPSAoaXNGdW5jdGlvbihDdG9yKSAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG8sXG4gICAgICBpc1Byb3RvID0gcHJvdG8gPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDAsXG4gICAgICBza2lwRXJyb3JQcm9wcyA9IHN1cHBvcnQuZW51bUVycm9yUHJvcHMgJiYgKG9iamVjdCA9PT0gZXJyb3JQcm90byB8fCBvYmplY3QgaW5zdGFuY2VvZiBFcnJvciksXG4gICAgICBza2lwUHJvdG8gPSBzdXBwb3J0LmVudW1Qcm90b3R5cGVzICYmIGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgLy8gbG9kYXNoIHNraXBzIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHdoZW4gaXQgaW5mZXJzIGl0J3MgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsIi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIEFuIG9iamVjdCBlbnZpcm9ubWVudCBmZWF0dXJlIGZsYWdzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSBPYmplY3RcbiAqL1xudmFyIHN1cHBvcnQgPSB7fTtcblxuKGZ1bmN0aW9uKHgpIHtcbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0geDsgfSxcbiAgICAgIG9iamVjdCA9IHsgJzAnOiB4LCAnbGVuZ3RoJzogeCB9LFxuICAgICAgcHJvcHMgPSBbXTtcblxuICBDdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiB4LCAneSc6IHggfTtcbiAgZm9yICh2YXIga2V5IGluIG5ldyBDdG9yKSB7IHByb3BzLnB1c2goa2V5KTsgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYG5hbWVgIG9yIGBtZXNzYWdlYCBwcm9wZXJ0aWVzIG9mIGBFcnJvci5wcm90b3R5cGVgIGFyZVxuICAgKiBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQgKElFIDwgOSwgU2FmYXJpIDwgNS4xKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1FcnJvclByb3BzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbWVzc2FnZScpIHx8XG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbmFtZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYHByb3RvdHlwZWAgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMy42LCBPcGVyYSA+IDkuNTAgLSBPcGVyYSA8IDExLjYwLCBhbmQgU2FmYXJpIDwgNS4xXG4gICAqIChpZiB0aGUgcHJvdG90eXBlIG9yIGEgcHJvcGVydHkgb24gdGhlIHByb3RvdHlwZSBoYXMgYmVlbiBzZXQpXG4gICAqIGluY29ycmVjdGx5IHNldCB0aGUgYFtbRW51bWVyYWJsZV1dYCB2YWx1ZSBvZiBhIGZ1bmN0aW9uJ3MgYHByb3RvdHlwZWBcbiAgICogcHJvcGVydHkgdG8gYHRydWVgLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKEN0b3IsICdwcm90b3R5cGUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xufSgxLCAwKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3VwcG9ydDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXhMM0V1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpTHk4Z2RtbHRPblJ6UFRRNmMzUnpQVFE2YzNjOU5EcGNiaThxSVZ4dUlDcGNiaUFxSUVOdmNIbHlhV2RvZENBeU1EQTVMVEl3TVRJZ1MzSnBjeUJMYjNkaGJDQjFibVJsY2lCMGFHVWdkR1Z5YlhNZ2IyWWdkR2hsSUUxSlZGeHVJQ29nYkdsalpXNXpaU0JtYjNWdVpDQmhkQ0JvZEhSd09pOHZaMmwwYUhWaUxtTnZiUzlyY21semEyOTNZV3d2Y1M5eVlYY3ZiV0Z6ZEdWeUwweEpRMFZPVTBWY2JpQXFYRzRnS2lCWGFYUm9JSEJoY25SeklHSjVJRlI1YkdWeUlFTnNiM05sWEc0Z0tpQkRiM0I1Y21sbmFIUWdNakF3TnkweU1EQTVJRlI1YkdWeUlFTnNiM05sSUhWdVpHVnlJSFJvWlNCMFpYSnRjeUJ2WmlCMGFHVWdUVWxVSUZnZ2JHbGpaVzV6WlNCbWIzVnVaRnh1SUNvZ1lYUWdhSFIwY0RvdkwzZDNkeTV2Y0dWdWMyOTFjbU5sTG05eVp5OXNhV05sYm5ObGN5OXRhWFF0YkdsalpXNXpaUzVvZEcxc1hHNGdLaUJHYjNKclpXUWdZWFFnY21WbVgzTmxibVF1YW5NZ2RtVnljMmx2YmpvZ01qQXdPUzB3TlMweE1WeHVJQ3BjYmlBcUlGZHBkR2dnY0dGeWRITWdZbmtnVFdGeWF5Qk5hV3hzWlhKY2JpQXFJRU52Y0hseWFXZG9kQ0FvUXlrZ01qQXhNU0JIYjI5bmJHVWdTVzVqTGx4dUlDcGNiaUFxSUV4cFkyVnVjMlZrSUhWdVpHVnlJSFJvWlNCQmNHRmphR1VnVEdsalpXNXpaU3dnVm1WeWMybHZiaUF5TGpBZ0tIUm9aU0JjSWt4cFkyVnVjMlZjSWlrN1hHNGdLaUI1YjNVZ2JXRjVJRzV2ZENCMWMyVWdkR2hwY3lCbWFXeGxJR1Y0WTJWd2RDQnBiaUJqYjIxd2JHbGhibU5sSUhkcGRHZ2dkR2hsSUV4cFkyVnVjMlV1WEc0Z0tpQlpiM1VnYldGNUlHOWlkR0ZwYmlCaElHTnZjSGtnYjJZZ2RHaGxJRXhwWTJWdWMyVWdZWFJjYmlBcVhHNGdLaUJvZEhSd09pOHZkM2QzTG1Gd1lXTm9aUzV2Y21jdmJHbGpaVzV6WlhNdlRFbERSVTVUUlMweUxqQmNiaUFxWEc0Z0tpQlZibXhsYzNNZ2NtVnhkV2x5WldRZ1lua2dZWEJ3YkdsallXSnNaU0JzWVhjZ2IzSWdZV2R5WldWa0lIUnZJR2x1SUhkeWFYUnBibWNzSUhOdlpuUjNZWEpsWEc0Z0tpQmthWE4wY21saWRYUmxaQ0IxYm1SbGNpQjBhR1VnVEdsalpXNXpaU0JwY3lCa2FYTjBjbWxpZFhSbFpDQnZiaUJoYmlCY0lrRlRJRWxUWENJZ1FrRlRTVk1zWEc0Z0tpQlhTVlJJVDFWVUlGZEJVbEpCVGxSSlJWTWdUMUlnUTA5T1JFbFVTVTlPVXlCUFJpQkJUbGtnUzBsT1JDd2daV2wwYUdWeUlHVjRjSEpsYzNNZ2IzSWdhVzF3YkdsbFpDNWNiaUFxSUZObFpTQjBhR1VnVEdsalpXNXpaU0JtYjNJZ2RHaGxJSE53WldOcFptbGpJR3hoYm1kMVlXZGxJR2R2ZG1WeWJtbHVaeUJ3WlhKdGFYTnphVzl1Y3lCaGJtUmNiaUFxSUd4cGJXbDBZWFJwYjI1eklIVnVaR1Z5SUhSb1pTQk1hV05sYm5ObExseHVJQ3BjYmlBcUwxeHVYRzRvWm5WdVkzUnBiMjRnS0dSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNCY0luVnpaU0J6ZEhKcFkzUmNJanRjYmx4dUlDQWdJQzh2SUZSb2FYTWdabWxzWlNCM2FXeHNJR1oxYm1OMGFXOXVJSEJ5YjNCbGNteDVJR0Z6SUdFZ1BITmpjbWx3ZEQ0Z2RHRm5MQ0J2Y2lCaElHMXZaSFZzWlZ4dUlDQWdJQzh2SUhWemFXNW5JRU52YlcxdmJrcFRJR0Z1WkNCT2IyUmxTbE1nYjNJZ1VtVnhkV2x5WlVwVElHMXZaSFZzWlNCbWIzSnRZWFJ6TGlBZ1NXNWNiaUFnSUNBdkx5QkRiMjF0YjI0dlRtOWtaUzlTWlhGMWFYSmxTbE1zSUhSb1pTQnRiMlIxYkdVZ1pYaHdiM0owY3lCMGFHVWdVU0JCVUVrZ1lXNWtJSGRvWlc1Y2JpQWdJQ0F2THlCbGVHVmpkWFJsWkNCaGN5QmhJSE5wYlhCc1pTQThjMk55YVhCMFBpd2dhWFFnWTNKbFlYUmxjeUJoSUZFZ1oyeHZZbUZzSUdsdWMzUmxZV1F1WEc1Y2JpQWdJQ0F2THlCTmIyNTBZV2RsSUZKbGNYVnBjbVZjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR0p2YjNSemRISmhjQ0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lLU0I3WEc0Z0lDQWdJQ0FnSUdKdmIzUnpkSEpoY0NoY0luQnliMjFwYzJWY0lpd2daR1ZtYVc1cGRHbHZiaWs3WEc1Y2JpQWdJQ0F2THlCRGIyMXRiMjVLVTF4dUlDQWdJSDBnWld4elpTQnBaaUFvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUZ3aWIySnFaV04wWENJZ0ppWWdkSGx3Wlc5bUlHMXZaSFZzWlNBOVBUMGdYQ0p2WW1wbFkzUmNJaWtnZTF4dUlDQWdJQ0FnSUNCdGIyUjFiR1V1Wlhod2IzSjBjeUE5SUdSbFptbHVhWFJwYjI0b0tUdGNibHh1SUNBZ0lDOHZJRkpsY1hWcGNtVktVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHUmxabWx1WlNBOVBUMGdYQ0ptZFc1amRHbHZibHdpSUNZbUlHUmxabWx1WlM1aGJXUXBJSHRjYmlBZ0lDQWdJQ0FnWkdWbWFXNWxLR1JsWm1sdWFYUnBiMjRwTzF4dVhHNGdJQ0FnTHk4Z1UwVlRJQ2hUWldOMWNtVWdSV050WVZOamNtbHdkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWE1nSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0Z6WlhNdWIyc29LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWekxtMWhhMlZSSUQwZ1pHVm1hVzVwZEdsdmJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdMeThnUEhOamNtbHdkRDVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJZ2ZId2dkSGx3Wlc5bUlITmxiR1lnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdVSEpsWm1WeUlIZHBibVJ2ZHlCdmRtVnlJSE5sYkdZZ1ptOXlJR0ZrWkMxdmJpQnpZM0pwY0hSekxpQlZjMlVnYzJWc1ppQm1iM0pjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVMWGRwYm1SdmQyVmtJR052Ym5SbGVIUnpMbHh1SUNBZ0lDQWdJQ0IyWVhJZ1oyeHZZbUZzSUQwZ2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaUEvSUhkcGJtUnZkeUE2SUhObGJHWTdYRzVjYmlBZ0lDQWdJQ0FnTHk4Z1IyVjBJSFJvWlNCZ2QybHVaRzkzWUNCdlltcGxZM1FzSUhOaGRtVWdkR2hsSUhCeVpYWnBiM1Z6SUZFZ1oyeHZZbUZzWEc0Z0lDQWdJQ0FnSUM4dklHRnVaQ0JwYm1sMGFXRnNhWHBsSUZFZ1lYTWdZU0JuYkc5aVlXd3VYRzRnSUNBZ0lDQWdJSFpoY2lCd2NtVjJhVzkxYzFFZ1BTQm5iRzlpWVd3dVVUdGNiaUFnSUNBZ0lDQWdaMnh2WW1Gc0xsRWdQU0JrWldacGJtbDBhVzl1S0NrN1hHNWNiaUFnSUNBZ0lDQWdMeThnUVdSa0lHRWdibTlEYjI1bWJHbGpkQ0JtZFc1amRHbHZiaUJ6YnlCUklHTmhiaUJpWlNCeVpXMXZkbVZrSUdaeWIyMGdkR2hsWEc0Z0lDQWdJQ0FnSUM4dklHZHNiMkpoYkNCdVlXMWxjM0JoWTJVdVhHNGdJQ0FnSUNBZ0lHZHNiMkpoYkM1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JuYkc5aVlXd3VVU0E5SUhCeVpYWnBiM1Z6VVR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJQ0FnSUNCOU8xeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVZHaHBjeUJsYm5acGNtOXViV1Z1ZENCM1lYTWdibTkwSUdGdWRHbGphWEJoZEdWa0lHSjVJRkV1SUZCc1pXRnpaU0JtYVd4bElHRWdZblZuTGx3aUtUdGNiaUFnSUNCOVhHNWNibjBwS0daMWJtTjBhVzl1SUNncElIdGNibHdpZFhObElITjBjbWxqZEZ3aU8xeHVYRzUyWVhJZ2FHRnpVM1JoWTJ0eklEMGdabUZzYzJVN1hHNTBjbmtnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ3BPMXh1ZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUdoaGMxTjBZV05yY3lBOUlDRWhaUzV6ZEdGamF6dGNibjFjYmx4dUx5OGdRV3hzSUdOdlpHVWdZV1owWlhJZ2RHaHBjeUJ3YjJsdWRDQjNhV3hzSUdKbElHWnBiSFJsY21Wa0lHWnliMjBnYzNSaFkyc2dkSEpoWTJWeklISmxjRzl5ZEdWa1hHNHZMeUJpZVNCUkxseHVkbUZ5SUhGVGRHRnlkR2x1WjB4cGJtVWdQU0JqWVhCMGRYSmxUR2x1WlNncE8xeHVkbUZ5SUhGR2FXeGxUbUZ0WlR0Y2JseHVMeThnYzJocGJYTmNibHh1THk4Z2RYTmxaQ0JtYjNJZ1ptRnNiR0poWTJzZ2FXNGdYQ0poYkd4U1pYTnZiSFpsWkZ3aVhHNTJZWElnYm05dmNDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0OU8xeHVYRzR2THlCVmMyVWdkR2hsSUdaaGMzUmxjM1FnY0c5emMybGliR1VnYldWaGJuTWdkRzhnWlhobFkzVjBaU0JoSUhSaGMyc2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJseHVMeThnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc1MllYSWdibVY0ZEZScFkyc2dQU2htZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk4Z2JHbHVhMlZrSUd4cGMzUWdiMllnZEdGemEzTWdLSE5wYm1kc1pTd2dkMmwwYUNCb1pXRmtJRzV2WkdVcFhHNGdJQ0FnZG1GeUlHaGxZV1FnUFNCN2RHRnphem9nZG05cFpDQXdMQ0J1WlhoME9pQnVkV3hzZlR0Y2JpQWdJQ0IyWVhJZ2RHRnBiQ0E5SUdobFlXUTdYRzRnSUNBZ2RtRnlJR1pzZFhOb2FXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ2RtRnlJSEpsY1hWbGMzUlVhV05ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSFpoY2lCcGMwNXZaR1ZLVXlBOUlHWmhiSE5sTzF4dUlDQWdJQzh2SUhGMVpYVmxJR1p2Y2lCc1lYUmxJSFJoYzJ0ekxDQjFjMlZrSUdKNUlIVnVhR0Z1Wkd4bFpDQnlaV3BsWTNScGIyNGdkSEpoWTJ0cGJtZGNiaUFnSUNCMllYSWdiR0YwWlhKUmRXVjFaU0E5SUZ0ZE8xeHVYRzRnSUNBZ1puVnVZM1JwYjI0Z1pteDFjMmdvS1NCN1hHNGdJQ0FnSUNBZ0lDOHFJR3B6YUdsdWRDQnNiMjl3Wm5WdVl6b2dkSEoxWlNBcUwxeHVJQ0FnSUNBZ0lDQjJZWElnZEdGemF5d2daRzl0WVdsdU8xeHVYRzRnSUNBZ0lDQWdJSGRvYVd4bElDaG9aV0ZrTG01bGVIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHaGxZV1FnUFNCb1pXRmtMbTVsZUhRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwWVhOcklEMGdhR1ZoWkM1MFlYTnJPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FHVmhaQzUwWVhOcklEMGdkbTlwWkNBd08xeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVJRDBnYUdWaFpDNWtiMjFoYVc0N1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQm9aV0ZrTG1SdmJXRnBiaUE5SUhadmFXUWdNRHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cE8xeHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZDJocGJHVWdLR3hoZEdWeVVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2JHRjBaWEpSZFdWMVpTNXdiM0FvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYkhWemFHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2MybHVaMnhsSUdaMWJtTjBhVzl1SUdsdUlIUm9aU0JoYzNsdVl5QnhkV1YxWlZ4dUlDQWdJR1oxYm1OMGFXOXVJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJoYzJzb0tUdGNibHh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FYTk9iMlJsU2xNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJKYmlCdWIyUmxMQ0IxYm1OaGRXZG9kQ0JsZUdObGNIUnBiMjV6SUdGeVpTQmpiMjV6YVdSbGNtVmtJR1poZEdGc0lHVnljbTl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlNaUzEwYUhKdmR5QjBhR1Z0SUhONWJtTm9jbTl1YjNWemJIa2dkRzhnYVc1MFpYSnlkWEIwSUdac2RYTm9hVzVuSVZ4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdSVzV6ZFhKbElHTnZiblJwYm5WaGRHbHZiaUJwWmlCMGFHVWdkVzVqWVhWbmFIUWdaWGhqWlhCMGFXOXVJR2x6SUhOMWNIQnlaWE56WldSY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhWE4wWlc1cGJtY2dYQ0oxYm1OaGRXZG9kRVY0WTJWd2RHbHZibHdpSUdWMlpXNTBjeUFvWVhNZ1pHOXRZV2x1Y3lCa2IyVnpLUzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCRGIyNTBhVzUxWlNCcGJpQnVaWGgwSUdWMlpXNTBJSFJ2SUdGMmIybGtJSFJwWTJzZ2NtVmpkWEp6YVc5dUxseHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHOXRZV2x1TG1WNGFYUW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzJWMFZHbHRaVzkxZENobWJIVnphQ3dnTUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2YldGcGJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzR1Wlc1MFpYSW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVsdUlHSnliM2R6WlhKekxDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCdWIzUWdabUYwWVd3dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVbVV0ZEdoeWIzY2dkR2hsYlNCaGMzbHVZMmh5YjI1dmRYTnNlU0IwYnlCaGRtOXBaQ0J6Ykc5M0xXUnZkMjV6TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgwc0lEQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNibHh1SUNBZ0lHNWxlSFJVYVdOcklEMGdablZ1WTNScGIyNGdLSFJoYzJzcElIdGNiaUFnSUNBZ0lDQWdkR0ZwYkNBOUlIUmhhV3d1Ym1WNGRDQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnM2SUhSaGMyc3NYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzQ2SUdselRtOWtaVXBUSUNZbUlIQnliMk5sYzNNdVpHOXRZV2x1TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdibVY0ZERvZ2JuVnNiRnh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2doWm14MWMyaHBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb2FXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcktDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1YRzRnSUNBZ0lDQWdJSEJ5YjJObGMzTXVkRzlUZEhKcGJtY29LU0E5UFQwZ1hDSmJiMkpxWldOMElIQnliMk5sYzNOZFhDSWdKaVlnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkZibk4xY21VZ1VTQnBjeUJwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkQ3dnZDJsMGFDQmhJR0J3Y205alpYTnpMbTVsZUhSVWFXTnJZQzVjYmlBZ0lDQWdJQ0FnTHk4Z1ZHOGdjMlZsSUhSb2NtOTFaMmdnWm1GclpTQk9iMlJsSUdWdWRtbHliMjV0Wlc1MGN6cGNiaUFnSUNBZ0lDQWdMeThnS2lCTmIyTm9ZU0IwWlhOMElISjFibTVsY2lBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemMyQWdaMnh2WW1Gc0lIZHBkR2h2ZFhRZ1lTQmdibVY0ZEZScFkydGdYRzRnSUNBZ0lDQWdJQzh2SUNvZ1FuSnZkM05sY21sbWVTQXRJR1Y0Y0c5elpYTWdZU0JnY0hKdlkyVnpjeTV1WlhoVWFXTnJZQ0JtZFc1amRHbHZiaUIwYUdGMElIVnpaWE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmdjMlYwVkdsdFpXOTFkR0F1SUVsdUlIUm9hWE1nWTJGelpTQmdjMlYwU1cxdFpXUnBZWFJsWUNCcGN5QndjbVZtWlhKeVpXUWdZbVZqWVhWelpWeHVJQ0FnSUNBZ0lDQXZMeUFnSUNCcGRDQnBjeUJtWVhOMFpYSXVJRUp5YjNkelpYSnBabmtuY3lCZ2NISnZZMlZ6Y3k1MGIxTjBjbWx1WnlncFlDQjVhV1ZzWkhOY2JpQWdJQ0FnSUNBZ0x5OGdJQ0JjSWx0dlltcGxZM1FnVDJKcVpXTjBYVndpTENCM2FHbHNaU0JwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkRnh1SUNBZ0lDQWdJQ0F2THlBZ0lHQndjbTlqWlhOekxtNWxlSFJVYVdOcktDbGdJSGxwWld4a2N5QmNJbHR2WW1wbFkzUWdjSEp2WTJWemMxMWNJaTVjYmlBZ0lDQWdJQ0FnYVhOT2IyUmxTbE1nUFNCMGNuVmxPMXh1WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2WTJWemN5NXVaWGgwVkdsamF5aG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFJKYlcxbFpHbGhkR1VnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkpiaUJKUlRFd0xDQk9iMlJsTG1weklEQXVPU3NzSUc5eUlHaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOU9iMkpzWlVwVEwzTmxkRWx0YldWa2FXRjBaVnh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNnUFNCelpYUkpiVzFsWkdsaGRHVXVZbWx1WkNoM2FXNWtiM2NzSUdac2RYTm9LVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjWFZsYzNSVWFXTnJJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lITmxkRWx0YldWa2FXRjBaU2htYkhWemFDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQk5aWE56WVdkbFEyaGhibTVsYkNBaFBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ0YjJSbGNtNGdZbkp2ZDNObGNuTmNiaUFnSUNBZ0lDQWdMeThnYUhSMGNEb3ZMM2QzZHk1dWIyNWliRzlqYTJsdVp5NXBieTh5TURFeEx6QTJMM2RwYm1SdmQyNWxlSFIwYVdOckxtaDBiV3hjYmlBZ0lDQWdJQ0FnZG1GeUlHTm9ZVzV1Wld3Z1BTQnVaWGNnVFdWemMyRm5aVU5vWVc1dVpXd29LVHRjYmlBZ0lDQWdJQ0FnTHk4Z1FYUWdiR1ZoYzNRZ1UyRm1ZWEpwSUZabGNuTnBiMjRnTmk0d0xqVWdLRGcxTXpZdU16QXVNU2tnYVc1MFpYSnRhWFIwWlc1MGJIa2dZMkZ1Ym05MElHTnlaV0YwWlZ4dUlDQWdJQ0FnSUNBdkx5QjNiM0pyYVc1bklHMWxjM05oWjJVZ2NHOXlkSE1nZEdobElHWnBjbk4wSUhScGJXVWdZU0J3WVdkbElHeHZZV1J6TGx4dUlDQWdJQ0FnSUNCamFHRnVibVZzTG5CdmNuUXhMbTl1YldWemMyRm5aU0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdjbVZ4ZFdWemRGQnZjblJVYVdOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJoaGJtNWxiQzV3YjNKME1TNXZibTFsYzNOaFoyVWdQU0JtYkhWemFEdGNiaUFnSUNBZ0lDQWdJQ0FnSUdac2RYTm9LQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ5WlhGMVpYTjBVRzl5ZEZScFkyc2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCUGNHVnlZU0J5WlhGMWFYSmxjeUIxY3lCMGJ5QndjbTkyYVdSbElHRWdiV1Z6YzJGblpTQndZWGxzYjJGa0xDQnlaV2RoY21Sc1pYTnpJRzltWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzYUdWMGFHVnlJSGRsSUhWelpTQnBkQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHTm9ZVzV1Wld3dWNHOXlkREl1Y0c5emRFMWxjM05oWjJVb01DazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWEYxWlhOMFVHOXlkRlJwWTJzb0tUdGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQzh2SUc5c1pDQmljbTkzYzJWeWMxeHVJQ0FnSUNBZ0lDQnlaWEYxWlhOMFZHbGpheUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1pteDFjMmdzSURBcE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2RHRnpheUJoWm5SbGNpQmhiR3dnYjNSb1pYSWdkR0Z6YTNNZ2FHRjJaU0JpWldWdUlISjFibHh1SUNBZ0lDOHZJSFJvYVhNZ2FYTWdkWE5sWm5Wc0lHWnZjaUIxYm1oaGJtUnNaV1FnY21WcVpXTjBhVzl1SUhSeVlXTnJhVzVuSUhSb1lYUWdibVZsWkhNZ2RHOGdhR0Z3Y0dWdVhHNGdJQ0FnTHk4Z1lXWjBaWElnWVd4c0lHQjBhR1Z1WUdRZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJpNWNiaUFnSUNCdVpYaDBWR2xqYXk1eWRXNUJablJsY2lBOUlHWjFibU4wYVc5dUlDaDBZWE5yS1NCN1hHNGdJQ0FnSUNBZ0lHeGhkR1Z5VVhWbGRXVXVjSFZ6YUNoMFlYTnJLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRm1iSFZ6YUdsdVp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pteDFjMmhwYm1jZ1BTQjBjblZsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNGdJQ0FnY21WMGRYSnVJRzVsZUhSVWFXTnJPMXh1ZlNrb0tUdGNibHh1THk4Z1FYUjBaVzF3ZENCMGJ5QnRZV3RsSUdkbGJtVnlhV056SUhOaFptVWdhVzRnZEdobElHWmhZMlVnYjJZZ1pHOTNibk4wY21WaGJWeHVMeThnYlc5a2FXWnBZMkYwYVc5dWN5NWNiaTh2SUZSb1pYSmxJR2x6SUc1dklITnBkSFZoZEdsdmJpQjNhR1Z5WlNCMGFHbHpJR2x6SUc1bFkyVnpjMkZ5ZVM1Y2JpOHZJRWxtSUhsdmRTQnVaV1ZrSUdFZ2MyVmpkWEpwZEhrZ1ozVmhjbUZ1ZEdWbExDQjBhR1Z6WlNCd2NtbHRiM0prYVdGc2N5QnVaV1ZrSUhSdklHSmxYRzR2THlCa1pXVndiSGtnWm5KdmVtVnVJR0Z1ZVhkaGVTd2dZVzVrSUdsbUlIbHZkU0JrYjI3aWdKbDBJRzVsWldRZ1lTQnpaV04xY21sMGVTQm5kV0Z5WVc1MFpXVXNYRzR2THlCMGFHbHpJR2x6SUdwMWMzUWdjR3hoYVc0Z2NHRnlZVzV2YVdRdVhHNHZMeUJJYjNkbGRtVnlMQ0IwYUdseklDb3FiV2xuYUhRcUtpQm9ZWFpsSUhSb1pTQnVhV05sSUhOcFpHVXRaV1ptWldOMElHOW1JSEpsWkhWamFXNW5JSFJvWlNCemFYcGxJRzltWEc0dkx5QjBhR1VnYldsdWFXWnBaV1FnWTI5a1pTQmllU0J5WldSMVkybHVaeUI0TG1OaGJHd29LU0IwYnlCdFpYSmxiSGtnZUNncFhHNHZMeUJUWldVZ1RXRnlheUJOYVd4c1pYTGlnSmx6SUdWNGNHeGhibUYwYVc5dUlHOW1JSGRvWVhRZ2RHaHBjeUJrYjJWekxseHVMeThnYUhSMGNEb3ZMM2RwYTJrdVpXTnRZWE5qY21sd2RDNXZjbWN2Wkc5cmRTNXdhSEEvYVdROVkyOXVkbVZ1ZEdsdmJuTTZjMkZtWlY5dFpYUmhYM0J5YjJkeVlXMXRhVzVuWEc1MllYSWdZMkZzYkNBOUlFWjFibU4wYVc5dUxtTmhiR3c3WEc1bWRXNWpkR2x2YmlCMWJtTjFjbko1VkdocGN5aG1LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd3dVlYQndiSGtvWml3Z1lYSm5kVzFsYm5SektUdGNiaUFnSUNCOU8xeHVmVnh1THk4Z1ZHaHBjeUJwY3lCbGNYVnBkbUZzWlc1MExDQmlkWFFnYzJ4dmQyVnlPbHh1THk4Z2RXNWpkWEp5ZVZSb2FYTWdQU0JHZFc1amRHbHZibDlpYVc1a0xtSnBibVFvUm5WdVkzUnBiMjVmWW1sdVpDNWpZV3hzS1R0Y2JpOHZJR2gwZEhBNkx5OXFjM0JsY21ZdVkyOXRMM1Z1WTNWeWNubDBhR2x6WEc1Y2JuWmhjaUJoY25KaGVWOXpiR2xqWlNBOUlIVnVZM1Z5Y25sVWFHbHpLRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpiR2xqWlNrN1hHNWNiblpoY2lCaGNuSmhlVjl5WldSMVkyVWdQU0IxYm1OMWNuSjVWR2hwY3loY2JpQWdJQ0JCY25KaGVTNXdjbTkwYjNSNWNHVXVjbVZrZFdObElIeDhJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWW1GemFYTXBJSHRjYmlBZ0lDQWdJQ0FnZG1GeUlHbHVaR1Y0SUQwZ01DeGNiaUFnSUNBZ0lDQWdJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQXZMeUJqYjI1alpYSnVhVzVuSUhSb1pTQnBibWwwYVdGc0lIWmhiSFZsTENCcFppQnZibVVnYVhNZ2JtOTBJSEJ5YjNacFpHVmtYRzRnSUNBZ0lDQWdJR2xtSUNoaGNtZDFiV1Z1ZEhNdWJHVnVaM1JvSUQwOVBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6WldWcklIUnZJSFJvWlNCbWFYSnpkQ0IyWVd4MVpTQnBiaUIwYUdVZ1lYSnlZWGtzSUdGalkyOTFiblJwYm1kY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnY0c5emMybGlhV3hwZEhrZ2RHaGhkQ0JwY3lCcGN5QmhJSE53WVhKelpTQmhjbkpoZVZ4dUlDQWdJQ0FnSUNBZ0lDQWdaRzhnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNCcGJpQjBhR2x6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR0poYzJseklEMGdkR2hwYzF0cGJtUmxlQ3NyWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2dySzJsdVpHVjRJRDQ5SUd4bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0IzYUdsc1pTQW9NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0x5OGdjbVZrZFdObFhHNGdJQ0FnSUNBZ0lHWnZjaUFvT3lCcGJtUmxlQ0E4SUd4bGJtZDBhRHNnYVc1a1pYZ3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnWVdOamIzVnVkQ0JtYjNJZ2RHaGxJSEJ2YzNOcFltbHNhWFI1SUhSb1lYUWdkR2hsSUdGeWNtRjVJR2x6SUhOd1lYSnpaVnh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElHbHVJSFJvYVhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmlZWE5wY3lBOUlHTmhiR3hpWVdOcktHSmhjMmx6TENCMGFHbHpXMmx1WkdWNFhTd2dhVzVrWlhncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaVlYTnBjenRjYmlBZ0lDQjlYRzRwTzF4dVhHNTJZWElnWVhKeVlYbGZhVzVrWlhoUFppQTlJSFZ1WTNWeWNubFVhR2x6S0Z4dUlDQWdJRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXBibVJsZUU5bUlIeDhJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0F2THlCdWIzUWdZU0IyWlhKNUlHZHZiMlFnYzJocGJTd2dZblYwSUdkdmIyUWdaVzV2ZFdkb0lHWnZjaUJ2ZFhJZ2IyNWxJSFZ6WlNCdlppQnBkRnh1SUNBZ0lDQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUhSb2FYTXViR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGFHbHpXMmxkSUQwOVBTQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlBdE1UdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmJXRndJRDBnZFc1amRYSnllVlJvYVhNb1hHNGdJQ0FnUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbTFoY0NCOGZDQm1kVzVqZEdsdmJpQW9ZMkZzYkdKaFkyc3NJSFJvYVhOd0tTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCelpXeG1JRDBnZEdocGN6dGNiaUFnSUNBZ0lDQWdkbUZ5SUdOdmJHeGxZM1FnUFNCYlhUdGNiaUFnSUNBZ0lDQWdZWEp5WVhsZmNtVmtkV05sS0hObGJHWXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUhaaGJIVmxMQ0JwYm1SbGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXNiR1ZqZEM1d2RYTm9LR05oYkd4aVlXTnJMbU5oYkd3b2RHaHBjM0FzSUhaaGJIVmxMQ0JwYm1SbGVDd2djMlZzWmlrcE8xeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMjlzYkdWamREdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdiMkpxWldOMFgyTnlaV0YwWlNBOUlFOWlhbVZqZEM1amNtVmhkR1VnZkh3Z1puVnVZM1JwYjI0Z0tIQnliM1J2ZEhsd1pTa2dlMXh1SUNBZ0lHWjFibU4wYVc5dUlGUjVjR1VvS1NCN0lIMWNiaUFnSUNCVWVYQmxMbkJ5YjNSdmRIbHdaU0E5SUhCeWIzUnZkSGx3WlR0Y2JpQWdJQ0J5WlhSMWNtNGdibVYzSUZSNWNHVW9LVHRjYm4wN1hHNWNiblpoY2lCdlltcGxZM1JmYUdGelQzZHVVSEp2Y0dWeWRIa2dQU0IxYm1OMWNuSjVWR2hwY3loUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1oaGMwOTNibEJ5YjNCbGNuUjVLVHRjYmx4dWRtRnlJRzlpYW1WamRGOXJaWGx6SUQwZ1QySnFaV04wTG10bGVYTWdmSHdnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSFpoY2lCclpYbHpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYTJWNUlHbHVJRzlpYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2IySnFaV04wWDJoaGMwOTNibEJ5YjNCbGNuUjVLRzlpYW1WamRDd2dhMlY1S1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYTJWNWN5NXdkWE5vS0d0bGVTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUd0bGVYTTdYRzU5TzF4dVhHNTJZWElnYjJKcVpXTjBYM1J2VTNSeWFXNW5JRDBnZFc1amRYSnllVlJvYVhNb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlrN1hHNWNibVoxYm1OMGFXOXVJR2x6VDJKcVpXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxJRDA5UFNCUFltcGxZM1FvZG1Gc2RXVXBPMXh1ZlZ4dVhHNHZMeUJuWlc1bGNtRjBiM0lnY21Wc1lYUmxaQ0J6YUdsdGMxeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ1puVnVZM1JwYjI0Z2IyNWpaU0JGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnYVc0Z1UzQnBaR1Z5VFc5dWEyVjVMbHh1Wm5WdVkzUnBiMjRnYVhOVGRHOXdTWFJsY21GMGFXOXVLR1Y0WTJWd2RHbHZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQW9YRzRnSUNBZ0lDQWdJRzlpYW1WamRGOTBiMU4wY21sdVp5aGxlR05sY0hScGIyNHBJRDA5UFNCY0lsdHZZbXBsWTNRZ1UzUnZjRWwwWlhKaGRHbHZibDFjSWlCOGZGeHVJQ0FnSUNBZ0lDQmxlR05sY0hScGIyNGdhVzV6ZEdGdVkyVnZaaUJSVW1WMGRYSnVWbUZzZFdWY2JpQWdJQ0FwTzF4dWZWeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ2FHVnNjR1Z5SUdGdVpDQlJMbkpsZEhWeWJpQnZibU5sSUVWVE5pQm5aVzVsY21GMGIzSnpJR0Z5WlNCcGJseHVMeThnVTNCcFpHVnlUVzl1YTJWNUxseHVkbUZ5SUZGU1pYUjFjbTVXWVd4MVpUdGNibWxtSUNoMGVYQmxiMllnVW1WMGRYSnVWbUZzZFdVZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJcElIdGNiaUFnSUNCUlVtVjBkWEp1Vm1Gc2RXVWdQU0JTWlhSMWNtNVdZV3gxWlR0Y2JuMGdaV3h6WlNCN1hHNGdJQ0FnVVZKbGRIVnlibFpoYkhWbElEMGdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQjlPMXh1ZlZ4dVhHNHZMeUJzYjI1bklITjBZV05ySUhSeVlXTmxjMXh1WEc1MllYSWdVMVJCUTB0ZlNsVk5VRjlUUlZCQlVrRlVUMUlnUFNCY0lrWnliMjBnY0hKbGRtbHZkWE1nWlhabGJuUTZYQ0k3WEc1Y2JtWjFibU4wYVc5dUlHMWhhMlZUZEdGamExUnlZV05sVEc5dVp5aGxjbkp2Y2l3Z2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUM4dklFbG1JSEJ2YzNOcFlteGxMQ0IwY21GdWMyWnZjbTBnZEdobElHVnljbTl5SUhOMFlXTnJJSFJ5WVdObElHSjVJSEpsYlc5MmFXNW5JRTV2WkdVZ1lXNWtJRkZjYmlBZ0lDQXZMeUJqY25WbWRDd2dkR2hsYmlCamIyNWpZWFJsYm1GMGFXNW5JSGRwZEdnZ2RHaGxJSE4wWVdOcklIUnlZV05sSUc5bUlHQndjbTl0YVhObFlDNGdVMlZsSUNNMU55NWNiaUFnSUNCcFppQW9hR0Z6VTNSaFkydHpJQ1ltWEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzNSaFkyc2dKaVpjYmlBZ0lDQWdJQ0FnZEhsd1pXOW1JR1Z5Y205eUlEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5SUNFOVBTQnVkV3hzSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOckxtbHVaR1Y0VDJZb1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSXBJRDA5UFNBdE1WeHVJQ0FnSUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYzNSaFkydHpJRDBnVzEwN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlIQWdQU0J3Y205dGFYTmxPeUFoSVhBN0lIQWdQU0J3TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hBdWMzUmhZMnNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCemRHRmphM011ZFc1emFHbG1kQ2h3TG5OMFlXTnJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaGxjbkp2Y2k1emRHRmpheWs3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ym1OaGRHVmtVM1JoWTJ0eklEMGdjM1JoWTJ0ekxtcHZhVzRvWENKY1hHNWNJaUFySUZOVVFVTkxYMHBWVFZCZlUwVlFRVkpCVkU5U0lDc2dYQ0pjWEc1Y0lpazdYRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05ySUQwZ1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb1kyOXVZMkYwWldSVGRHRmphM01wTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdabWxzZEdWeVUzUmhZMnRUZEhKcGJtY29jM1JoWTJ0VGRISnBibWNwSUh0Y2JpQWdJQ0IyWVhJZ2JHbHVaWE1nUFNCemRHRmphMU4wY21sdVp5NXpjR3hwZENoY0lseGNibHdpS1R0Y2JpQWdJQ0IyWVhJZ1pHVnphWEpsWkV4cGJtVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc2FXNWxjeTVzWlc1bmRHZzdJQ3NyYVNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYkdsdVpTQTlJR3hwYm1WelcybGRPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hhWE5KYm5SbGNtNWhiRVp5WVcxbEtHeHBibVVwSUNZbUlDRnBjMDV2WkdWR2NtRnRaU2hzYVc1bEtTQW1KaUJzYVc1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pYTnBjbVZrVEdsdVpYTXVjSFZ6YUNoc2FXNWxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVnphWEpsWkV4cGJtVnpMbXB2YVc0b1hDSmNYRzVjSWlrN1hHNTlYRzVjYm1aMWJtTjBhVzl1SUdselRtOWtaVVp5WVcxbEtITjBZV05yVEdsdVpTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHRiMlIxYkdVdWFuTTZYQ0lwSUNFOVBTQXRNU0I4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQnpkR0ZqYTB4cGJtVXVhVzVrWlhoUFppaGNJaWh1YjJSbExtcHpPbHdpS1NBaFBUMGdMVEU3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBJSHRjYmlBZ0lDQXZMeUJPWVcxbFpDQm1kVzVqZEdsdmJuTTZJRndpWVhRZ1puVnVZM1JwYjI1T1lXMWxJQ2htYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNpbGNJbHh1SUNBZ0lDOHZJRWx1SUVsRk1UQWdablZ1WTNScGIyNGdibUZ0WlNCallXNGdhR0YyWlNCemNHRmpaWE1nS0Z3aVFXNXZibmx0YjNWeklHWjFibU4wYVc5dVhDSXBJRTlmYjF4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTVNBOUlDOWhkQ0F1S3lCY1hDZ29MaXNwT2loY1hHUXJLVG9vUHpwY1hHUXJLVnhjS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERFcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME1Wc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXhXekpkS1YwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1FXNXZibmx0YjNWeklHWjFibU4wYVc5dWN6b2dYQ0poZENCbWFXeGxibUZ0WlRwc2FXNWxUblZ0WW1WeU9tTnZiSFZ0Yms1MWJXSmxjbHdpWEc0Z0lDQWdkbUZ5SUdGMGRHVnRjSFF5SUQwZ0wyRjBJQ2hiWGlCZEt5azZLRnhjWkNzcE9pZy9PbHhjWkNzcEpDOHVaWGhsWXloemRHRmphMHhwYm1VcE8xeHVJQ0FnSUdsbUlDaGhkSFJsYlhCME1pa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdXMkYwZEdWdGNIUXlXekZkTENCT2RXMWlaWElvWVhSMFpXMXdkREpiTWwwcFhUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QkdhWEpsWm05NElITjBlV3hsT2lCY0ltWjFibU4wYVc5dVFHWnBiR1Z1WVcxbE9teHBibVZPZFcxaVpYSWdiM0lnUUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhKY0lseHVJQ0FnSUhaaGNpQmhkSFJsYlhCME15QTlJQzh1S2tBb0xpc3BPaWhjWEdRcktTUXZMbVY0WldNb2MzUmhZMnRNYVc1bEtUdGNiaUFnSUNCcFppQW9ZWFIwWlcxd2RETXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRnRoZEhSbGJYQjBNMXN4WFN3Z1RuVnRZbVZ5S0dGMGRHVnRjSFF6V3pKZEtWMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCcGMwbHVkR1Z5Ym1Gc1JuSmhiV1VvYzNSaFkydE1hVzVsS1NCN1hHNGdJQ0FnZG1GeUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaUE5SUdkbGRFWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaWh6ZEdGamEweHBibVVwTzF4dVhHNGdJQ0FnYVdZZ0tDRm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWElwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJtYVd4bFRtRnRaU0E5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3dYVHRjYmlBZ0lDQjJZWElnYkdsdVpVNTFiV0psY2lBOUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjbHN4WFR0Y2JseHVJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaU0E5UFQwZ2NVWnBiR1ZPWVcxbElDWW1YRzRnSUNBZ0lDQWdJR3hwYm1WT2RXMWlaWElnUGowZ2NWTjBZWEowYVc1blRHbHVaU0FtSmx4dUlDQWdJQ0FnSUNCc2FXNWxUblZ0WW1WeUlEdzlJSEZGYm1ScGJtZE1hVzVsTzF4dWZWeHVYRzR2THlCa2FYTmpiM1psY2lCdmQyNGdabWxzWlNCdVlXMWxJR0Z1WkNCc2FXNWxJRzUxYldKbGNpQnlZVzVuWlNCbWIzSWdabWxzZEdWeWFXNW5JSE4wWVdOclhHNHZMeUIwY21GalpYTmNibVoxYm1OMGFXOXVJR05oY0hSMWNtVk1hVzVsS0NrZ2UxeHVJQ0FnSUdsbUlDZ2hhR0Z6VTNSaFkydHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvS1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJzYVc1bGN5QTlJR1V1YzNSaFkyc3VjM0JzYVhRb1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lIWmhjaUJtYVhKemRFeHBibVVnUFNCc2FXNWxjMXN3WFM1cGJtUmxlRTltS0Z3aVFGd2lLU0ErSURBZ1B5QnNhVzVsYzFzeFhTQTZJR3hwYm1Weld6SmRPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1ptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlJRDBnWjJWMFJtbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLR1pwY25OMFRHbHVaU2s3WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habWxzWlU1aGJXVkJibVJNYVc1bFRuVnRZbVZ5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCeFJtbHNaVTVoYldVZ1BTQm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWEpiTUYwN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNVjA3WEc0Z0lDQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmtaWEJ5WldOaGRHVW9ZMkZzYkdKaFkyc3NJRzVoYldVc0lHRnNkR1Z5Ym1GMGFYWmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUjVjR1Z2WmlCamIyNXpiMnhsSUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpSUNZbVhHNGdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdZMjl1YzI5c1pTNTNZWEp1SUQwOVBTQmNJbVoxYm1OMGFXOXVYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlodVlXMWxJQ3NnWENJZ2FYTWdaR1Z3Y21WallYUmxaQ3dnZFhObElGd2lJQ3NnWVd4MFpYSnVZWFJwZG1VZ0sxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lJR2x1YzNSbFlXUXVYQ0lzSUc1bGR5QkZjbkp2Y2loY0lsd2lLUzV6ZEdGamF5azdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtHTmhiR3hpWVdOckxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMDdYRzU5WEc1Y2JpOHZJR1Z1WkNCdlppQnphR2x0YzF4dUx5OGdZbVZuYVc1dWFXNW5JRzltSUhKbFlXd2dkMjl5YTF4dVhHNHZLaXBjYmlBcUlFTnZibk4wY25WamRITWdZU0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMQ0J3WVhOelpYTWdjSEp2YldselpYTWdkR2h5YjNWbmFDd2diM0pjYmlBcUlHTnZaWEpqWlhNZ2NISnZiV2x6WlhNZ1puSnZiU0JrYVdabVpYSmxiblFnYzNsemRHVnRjeTVjYmlBcUlFQndZWEpoYlNCMllXeDFaU0JwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUc5eUlIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnVVNoMllXeDFaU2tnZTF4dUlDQWdJQzh2SUVsbUlIUm9aU0J2WW1wbFkzUWdhWE1nWVd4eVpXRmtlU0JoSUZCeWIyMXBjMlVzSUhKbGRIVnliaUJwZENCa2FYSmxZM1JzZVM0Z0lGUm9hWE1nWlc1aFlteGxjMXh1SUNBZ0lDOHZJSFJvWlNCeVpYTnZiSFpsSUdaMWJtTjBhVzl1SUhSdklHSnZkR2dnWW1VZ2RYTmxaQ0IwYnlCamNtVmhkR1ZrSUhKbFptVnlaVzVqWlhNZ1puSnZiU0J2WW1wbFkzUnpMRnh1SUNBZ0lDOHZJR0oxZENCMGJ5QjBiMnhsY21GaWJIa2dZMjlsY21ObElHNXZiaTF3Y205dGFYTmxjeUIwYnlCd2NtOXRhWE5sY3k1Y2JpQWdJQ0JwWmlBb2RtRnNkV1VnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZMeUJoYzNOcGJXbHNZWFJsSUhSb1pXNWhZbXhsYzF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJWQmJHbHJaU2gyWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR052WlhKalpTaDJZV3gxWlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHd29kbUZzZFdVcE8xeHVJQ0FnSUgxY2JuMWNibEV1Y21WemIyeDJaU0E5SUZFN1hHNWNiaThxS2x4dUlDb2dVR1Z5Wm05eWJYTWdZU0IwWVhOcklHbHVJR0VnWm5WMGRYSmxJSFIxY200Z2IyWWdkR2hsSUdWMlpXNTBJR3h2YjNBdVhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0IwWVhOclhHNGdLaTljYmxFdWJtVjRkRlJwWTJzZ1BTQnVaWGgwVkdsamF6dGNibHh1THlvcVhHNGdLaUJEYjI1MGNtOXNjeUIzYUdWMGFHVnlJRzl5SUc1dmRDQnNiMjVuSUhOMFlXTnJJSFJ5WVdObGN5QjNhV3hzSUdKbElHOXVYRzRnS2k5Y2JsRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQTlJR1poYkhObE8xeHVYRzR2THlCbGJtRmliR1VnYkc5dVp5QnpkR0ZqYTNNZ2FXWWdVVjlFUlVKVlJ5QnBjeUJ6WlhSY2JtbG1JQ2gwZVhCbGIyWWdjSEp2WTJWemN5QTlQVDBnWENKdlltcGxZM1JjSWlBbUppQndjbTlqWlhOeklDWW1JSEJ5YjJObGMzTXVaVzUySUNZbUlIQnliMk5sYzNNdVpXNTJMbEZmUkVWQ1ZVY3BJSHRjYmlBZ0lDQlJMbXh2Ym1kVGRHRmphMU4xY0hCdmNuUWdQU0IwY25WbE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQjdjSEp2YldselpTd2djbVZ6YjJ4MlpTd2djbVZxWldOMGZTQnZZbXBsWTNRdVhHNGdLbHh1SUNvZ1lISmxjMjlzZG1WZ0lHbHpJR0VnWTJGc2JHSmhZMnNnZEc4Z2FXNTJiMnRsSUhkcGRHZ2dZU0J0YjNKbElISmxjMjlzZG1Wa0lIWmhiSFZsSUdadmNpQjBhR1ZjYmlBcUlIQnliMjFwYzJVdUlGUnZJR1oxYkdacGJHd2dkR2hsSUhCeWIyMXBjMlVzSUdsdWRtOXJaU0JnY21WemIyeDJaV0FnZDJsMGFDQmhibmtnZG1Gc2RXVWdkR2hoZENCcGMxeHVJQ29nYm05MElHRWdkR2hsYm1GaWJHVXVJRlJ2SUhKbGFtVmpkQ0IwYUdVZ2NISnZiV2x6WlN3Z2FXNTJiMnRsSUdCeVpYTnZiSFpsWUNCM2FYUm9JR0VnY21WcVpXTjBaV1JjYmlBcUlIUm9aVzVoWW14bExDQnZjaUJwYm5admEyVWdZSEpsYW1WamRHQWdkMmwwYUNCMGFHVWdjbVZoYzI5dUlHUnBjbVZqZEd4NUxpQlVieUJ5WlhOdmJIWmxJSFJvWlZ4dUlDb2djSEp2YldselpTQjBieUJoYm05MGFHVnlJSFJvWlc1aFlteGxMQ0IwYUhWeklIQjFkSFJwYm1jZ2FYUWdhVzRnZEdobElITmhiV1VnYzNSaGRHVXNJR2x1ZG05clpWeHVJQ29nWUhKbGMyOXNkbVZnSUhkcGRHZ2dkR2hoZENCdmRHaGxjaUIwYUdWdVlXSnNaUzVjYmlBcUwxeHVVUzVrWldabGNpQTlJR1JsWm1WeU8xeHVablZ1WTNScGIyNGdaR1ZtWlhJb0tTQjdYRzRnSUNBZ0x5OGdhV1lnWENKdFpYTnpZV2RsYzF3aUlHbHpJR0Z1SUZ3aVFYSnlZWGxjSWl3Z2RHaGhkQ0JwYm1ScFkyRjBaWE1nZEdoaGRDQjBhR1VnY0hKdmJXbHpaU0JvWVhNZ2JtOTBJSGxsZEZ4dUlDQWdJQzh2SUdKbFpXNGdjbVZ6YjJ4MlpXUXVJQ0JKWmlCcGRDQnBjeUJjSW5WdVpHVm1hVzVsWkZ3aUxDQnBkQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQzRnSUVWaFkyaGNiaUFnSUNBdkx5QmxiR1Z0Wlc1MElHOW1JSFJvWlNCdFpYTnpZV2RsY3lCaGNuSmhlU0JwY3lCcGRITmxiR1lnWVc0Z1lYSnlZWGtnYjJZZ1kyOXRjR3hsZEdVZ1lYSm5kVzFsYm5SeklIUnZYRzRnSUNBZ0x5OGdabTl5ZDJGeVpDQjBieUIwYUdVZ2NtVnpiMngyWldRZ2NISnZiV2x6WlM0Z0lGZGxJR052WlhKalpTQjBhR1VnY21WemIyeDFkR2x2YmlCMllXeDFaU0IwYnlCaFhHNGdJQ0FnTHk4Z2NISnZiV2x6WlNCMWMybHVaeUIwYUdVZ1lISmxjMjlzZG1WZ0lHWjFibU4wYVc5dUlHSmxZMkYxYzJVZ2FYUWdhR0Z1Wkd4bGN5QmliM1JvSUdaMWJHeDVYRzRnSUNBZ0x5OGdibTl1TFhSb1pXNWhZbXhsSUhaaGJIVmxjeUJoYm1RZ2IzUm9aWElnZEdobGJtRmliR1Z6SUdkeVlXTmxablZzYkhrdVhHNGdJQ0FnZG1GeUlHMWxjM05oWjJWeklEMGdXMTBzSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ1cxMHNJSEpsYzI5c2RtVmtVSEp2YldselpUdGNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUc5aWFtVmpkRjlqY21WaGRHVW9aR1ZtWlhJdWNISnZkRzkwZVhCbEtUdGNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJRzl3WlhKaGJtUnpLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCdFpYTnpZV2RsY3k1d2RYTm9LR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHOXdJRDA5UFNCY0luZG9aVzVjSWlBbUppQnZjR1Z5WVc1a2Mxc3hYU2tnZXlBdkx5QndjbTluY21WemN5QnZjR1Z5WVc1a1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY25NdWNIVnphQ2h2Y0dWeVlXNWtjMXN4WFNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTnZiSFpsWkZCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtISmxjMjlzZG1Wa1VISnZiV2x6WlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaRnh1SUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVZoY21WeVZtRnNkV1VnUFNCdVpXRnlaWElvY21WemIyeDJaV1JRY205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHpVSEp2YldselpTaHVaV0Z5WlhKV1lXeDFaU2twSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsWVhKbGNsWmhiSFZsT3lBdkx5QnphRzl5ZEdWdUlHTm9ZV2x1WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUc1bFlYSmxjbFpoYkhWbE8xeHVJQ0FnSUgwN1hHNWNiaUFnSUNCd2NtOXRhWE5sTG1sdWMzQmxZM1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaGNtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdleUJ6ZEdGMFpUb2dYQ0p3Wlc1a2FXNW5YQ0lnZlR0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnpiMngyWldSUWNtOXRhWE5sTG1sdWMzQmxZM1FvS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYVdZZ0tGRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQW1KaUJvWVhOVGRHRmphM01wSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJPVDFSRk9pQmtiMjRuZENCMGNua2dkRzhnZFhObElHQkZjbkp2Y2k1allYQjBkWEpsVTNSaFkydFVjbUZqWldBZ2IzSWdkSEpoYm5ObVpYSWdkR2hsWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJoWTJObGMzTnZjaUJoY205MWJtUTdJSFJvWVhRZ1kyRjFjMlZ6SUcxbGJXOXllU0JzWldGcmN5QmhjeUJ3WlhJZ1IwZ3RNVEV4TGlCS2RYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnlaV2xtZVNCMGFHVWdjM1JoWTJzZ2RISmhZMlVnWVhNZ1lTQnpkSEpwYm1jZ1FWTkJVQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QkJkQ0IwYUdVZ2MyRnRaU0IwYVcxbExDQmpkWFFnYjJabUlIUm9aU0JtYVhKemRDQnNhVzVsT3lCcGRDZHpJR0ZzZDJGNWN5QnFkWE4wWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJjSWx0dlltcGxZM1FnVUhKdmJXbHpaVjFjWEc1Y0lpd2dZWE1nY0dWeUlIUm9aU0JnZEc5VGRISnBibWRnTGx4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNXpkR0ZqYXlBOUlHVXVjM1JoWTJzdWMzVmljM1J5YVc1bktHVXVjM1JoWTJzdWFXNWtaWGhQWmloY0lseGNibHdpS1NBcklERXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnVGs5VVJUb2dkMlVnWkc4Z2RHaGxJR05vWldOcmN5Qm1iM0lnWUhKbGMyOXNkbVZrVUhKdmJXbHpaV0FnYVc0Z1pXRmphQ0J0WlhSb2IyUXNJR2x1YzNSbFlXUWdiMlpjYmlBZ0lDQXZMeUJqYjI1emIyeHBaR0YwYVc1bklIUm9aVzBnYVc1MGJ5QmdZbVZqYjIxbFlDd2djMmx1WTJVZ2IzUm9aWEozYVhObElIZGxKMlFnWTNKbFlYUmxJRzVsZDF4dUlDQWdJQzh2SUhCeWIyMXBjMlZ6SUhkcGRHZ2dkR2hsSUd4cGJtVnpJR0JpWldOdmJXVW9kMmhoZEdWMlpYSW9kbUZzZFdVcEtXQXVJRk5sWlNCbExtY3VJRWRJTFRJMU1pNWNibHh1SUNBZ0lHWjFibU4wYVc5dUlHSmxZMjl0WlNodVpYZFFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsZDFCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzI5MWNtTmxJRDBnYm1WM1VISnZiV2x6WlR0Y2JseHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvYldWemMyRm5aWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lHMWxjM05oWjJVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtHNWxkMUJ5YjIxcGMyVXNJRzFsYzNOaFoyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQWdJSDBzSUhadmFXUWdNQ2s3WEc1Y2JpQWdJQ0FnSUNBZ2JXVnpjMkZuWlhNZ1BTQjJiMmxrSURBN1hHNGdJQ0FnSUNBZ0lIQnliMmR5WlhOelRHbHpkR1Z1WlhKeklEMGdkbTlwWkNBd08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdSbFptVnljbVZrTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dUlDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tISmxjMjlzZG1Wa1VISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ1ltVmpiMjFsS0ZFb2RtRnNkV1VwS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnWkdWbVpYSnlaV1F1Wm5Wc1ptbHNiQ0E5SUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQmlaV052YldVb1puVnNabWxzYkNoMllXeDFaU2twTzF4dUlDQWdJSDA3WEc0Z0lDQWdaR1ZtWlhKeVpXUXVjbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvY21WcVpXTjBLSEpsWVhOdmJpa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1SUQwZ1puVnVZM1JwYjI0Z0tIQnliMmR5WlhOektTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTnZiSFpsWkZCeWIyMXBjMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0FnSUdGeWNtRjVYM0psWkhWalpTaHdjbTluY21WemMweHBjM1JsYm1WeWN5d2dablZ1WTNScGIyNGdLSFZ1WkdWbWFXNWxaQ3dnY0hKdlozSmxjM05NYVhOMFpXNWxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY2lod2NtOW5jbVZ6Y3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTd2dkbTlwWkNBd0tUdGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JPYjJSbExYTjBlV3hsSUdOaGJHeGlZV05ySUhSb1lYUWdkMmxzYkNCeVpYTnZiSFpsSUc5eUlISmxhbVZqZENCMGFHVWdaR1ZtWlhKeVpXUmNiaUFxSUhCeWIyMXBjMlV1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJRzV2WkdWaVlXTnJYRzRnS2k5Y2JtUmxabVZ5TG5CeWIzUnZkSGx3WlM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdLR1Z5Y205eUxDQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvWlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lITmxiR1l1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCd1lYSmhiU0J5WlhOdmJIWmxjaUI3Um5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0J5WlhSMWNtNXpJRzV2ZEdocGJtY2dZVzVrSUdGalkyVndkSE5jYmlBcUlIUm9aU0J5WlhOdmJIWmxMQ0J5WldwbFkzUXNJR0Z1WkNCdWIzUnBabmtnWm5WdVkzUnBiMjV6SUdadmNpQmhJR1JsWm1WeWNtVmtMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElIUm9ZWFFnYldGNUlHSmxJSEpsYzI5c2RtVmtJSGRwZEdnZ2RHaGxJR2RwZG1WdUlISmxjMjlzZG1VZ1lXNWtJSEpsYW1WamRGeHVJQ29nWm5WdVkzUnBiMjV6TENCdmNpQnlaV3BsWTNSbFpDQmllU0JoSUhSb2NtOTNiaUJsZUdObGNIUnBiMjRnYVc0Z2NtVnpiMngyWlhKY2JpQXFMMXh1VVM1UWNtOXRhWE5sSUQwZ2NISnZiV2x6WlRzZ0x5OGdSVk0yWEc1UkxuQnliMjFwYzJVZ1BTQndjbTl0YVhObE8xeHVablZ1WTNScGIyNGdjSEp2YldselpTaHlaWE52YkhabGNpa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdjbVZ6YjJ4MlpYSWdJVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnVkhsd1pVVnljbTl5S0Z3aWNtVnpiMngyWlhJZ2JYVnpkQ0JpWlNCaElHWjFibU4wYVc5dUxsd2lLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCeVpYTnZiSFpsY2loa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCa1pXWmxjbkpsWkM1eVpXcGxZM1FzSUdSbFptVnljbVZrTG01dmRHbG1lU2s3WEc0Z0lDQWdmU0JqWVhSamFDQW9jbVZoYzI5dUtTQjdYRzRnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjFjYmx4dWNISnZiV2x6WlM1eVlXTmxJRDBnY21GalpUc2dMeThnUlZNMlhHNXdjbTl0YVhObExtRnNiQ0E5SUdGc2JEc2dMeThnUlZNMlhHNXdjbTl0YVhObExuSmxhbVZqZENBOUlISmxhbVZqZERzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGMyOXNkbVVnUFNCUk95QXZMeUJGVXpaY2JseHVMeThnV0ZoWUlHVjRjR1Z5YVcxbGJuUmhiQzRnSUZSb2FYTWdiV1YwYUc5a0lHbHpJR0VnZDJGNUlIUnZJR1JsYm05MFpTQjBhR0YwSUdFZ2JHOWpZV3dnZG1Gc2RXVWdhWE5jYmk4dklITmxjbWxoYkdsNllXSnNaU0JoYm1RZ2MyaHZkV3hrSUdKbElHbHRiV1ZrYVdGMFpXeDVJR1JwYzNCaGRHTm9aV1FnZEc4Z1lTQnlaVzF2ZEdVZ2RYQnZiaUJ5WlhGMVpYTjBMRnh1THk4Z2FXNXpkR1ZoWkNCdlppQndZWE56YVc1bklHRWdjbVZtWlhKbGJtTmxMbHh1VVM1d1lYTnpRbmxEYjNCNUlEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lDOHZabkpsWlhwbEtHOWlhbVZqZENrN1hHNGdJQ0FnTHk5d1lYTnpRbmxEYjNCcFpYTXVjMlYwS0c5aWFtVmpkQ3dnZEhKMVpTazdYRzRnSUNBZ2NtVjBkWEp1SUc5aWFtVmpkRHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJoYzNOQ2VVTnZjSGtnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0x5OW1jbVZsZW1Vb2IySnFaV04wS1R0Y2JpQWdJQ0F2TDNCaGMzTkNlVU52Y0dsbGN5NXpaWFFvYjJKcVpXTjBMQ0IwY25WbEtUdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdkSGR2SUhCeWIyMXBjMlZ6SUdWMlpXNTBkV0ZzYkhrZ1puVnNabWxzYkNCMGJ5QjBhR1VnYzJGdFpTQjJZV3gxWlN3Z2NISnZiV2x6WlhNZ2RHaGhkQ0IyWVd4MVpTeGNiaUFxSUdKMWRDQnZkR2hsY25kcGMyVWdjbVZxWldOMGN5NWNiaUFxSUVCd1lYSmhiU0I0SUh0QmJua3FmVnh1SUNvZ1FIQmhjbUZ0SUhrZ2UwRnVlU3A5WEc0Z0tpQkFjbVYwZFhKdWN5QjdRVzU1S24wZ1lTQndjbTl0YVhObElHWnZjaUI0SUdGdVpDQjVJR2xtSUhSb1pYa2dZWEpsSUhSb1pTQnpZVzFsTENCaWRYUWdZU0J5WldwbFkzUnBiMjVjYmlBcUlHOTBhR1Z5ZDJselpTNWNiaUFxWEc0Z0tpOWNibEV1YW05cGJpQTlJR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2VDa3VhbTlwYmloNUtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtcHZhVzRnUFNCbWRXNWpkR2x2YmlBb2RHaGhkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRnQwYUdsekxDQjBhR0YwWFNrdWMzQnlaV0ZrS0daMWJtTjBhVzl1SUNoNExDQjVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDRJRDA5UFNCNUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlVUMFJQT2lCY0lqMDlQVndpSUhOb2IzVnNaQ0JpWlNCUFltcGxZM1F1YVhNZ2IzSWdaWEYxYVhaY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjRPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVEyRnVKM1FnYW05cGJqb2dibTkwSUhSb1pTQnpZVzFsT2lCY0lpQXJJSGdnS3lCY0lpQmNJaUFySUhrcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1ptbHljM1FnYjJZZ1lXNGdZWEp5WVhrZ2IyWWdjSEp2YldselpYTWdkRzhnWW1WamIyMWxJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnWVc1emQyVnljeUI3UVhKeVlYbGJRVzU1S2wxOUlIQnliMjFwYzJWeklIUnZJSEpoWTJWY2JpQXFJRUJ5WlhSMWNtNXpJSHRCYm5rcWZTQjBhR1VnWm1seWMzUWdjSEp2YldselpTQjBieUJpWlNCelpYUjBiR1ZrWEc0Z0tpOWNibEV1Y21GalpTQTlJSEpoWTJVN1hHNW1kVzVqZEdsdmJpQnlZV05sS0dGdWMzZGxjbEJ6S1NCN1hHNGdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVW9ablZ1WTNScGIyNGdLSEpsYzI5c2RtVXNJSEpsYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0F2THlCVGQybDBZMmdnZEc4Z2RHaHBjeUJ2Ym1ObElIZGxJR05oYmlCaGMzTjFiV1VnWVhRZ2JHVmhjM1FnUlZNMVhHNGdJQ0FnSUNBZ0lDOHZJR0Z1YzNkbGNsQnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNGdLR0Z1YzNkbGNsQXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z0lDQWdJRkVvWVc1emQyVnlVQ2t1ZEdobGJpaHlaWE52YkhabExDQnlaV3BsWTNRcE8xeHVJQ0FnSUNBZ0lDQXZMeUI5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWWE5sSUhSb2FYTWdhVzRnZEdobElHMWxZVzUwYVcxbFhHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3TENCc1pXNGdQU0JoYm5OM1pYSlFjeTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnVVNoaGJuTjNaWEpRYzF0cFhTa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5KaFkyVWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhSTG5KaFkyVXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRiMjV6ZEhKMVkzUnpJR0VnVUhKdmJXbHpaU0IzYVhSb0lHRWdjSEp2YldselpTQmtaWE5qY21sd2RHOXlJRzlpYW1WamRDQmhibVFnYjNCMGFXOXVZV3dnWm1Gc2JHSmhZMnRjYmlBcUlHWjFibU4wYVc5dUxpQWdWR2hsSUdSbGMyTnlhWEIwYjNJZ1kyOXVkR0ZwYm5NZ2JXVjBhRzlrY3lCc2FXdGxJSGRvWlc0b2NtVnFaV04wWldRcExDQm5aWFFvYm1GdFpTa3NYRzRnS2lCelpYUW9ibUZ0WlN3Z2RtRnNkV1VwTENCd2IzTjBLRzVoYldVc0lHRnlaM01wTENCaGJtUWdaR1ZzWlhSbEtHNWhiV1VwTENCM2FHbGphQ0JoYkd4Y2JpQXFJSEpsZEhWeWJpQmxhWFJvWlhJZ1lTQjJZV3gxWlN3Z1lTQndjbTl0YVhObElHWnZjaUJoSUhaaGJIVmxMQ0J2Y2lCaElISmxhbVZqZEdsdmJpNGdJRlJvWlNCbVlXeHNZbUZqYTF4dUlDb2dZV05qWlhCMGN5QjBhR1VnYjNCbGNtRjBhVzl1SUc1aGJXVXNJR0VnY21WemIyeDJaWElzSUdGdVpDQmhibmtnWm5WeWRHaGxjaUJoY21kMWJXVnVkSE1nZEdoaGRDQjNiM1ZzWkZ4dUlDb2dhR0YyWlNCaVpXVnVJR1p2Y25kaGNtUmxaQ0IwYnlCMGFHVWdZWEJ3Y205d2NtbGhkR1VnYldWMGFHOWtJR0ZpYjNabElHaGhaQ0JoSUcxbGRHaHZaQ0JpWldWdVhHNGdLaUJ3Y205MmFXUmxaQ0IzYVhSb0lIUm9aU0J3Y205d1pYSWdibUZ0WlM0Z0lGUm9aU0JCVUVrZ2JXRnJaWE1nYm04Z1ozVmhjbUZ1ZEdWbGN5QmhZbTkxZENCMGFHVWdibUYwZFhKbFhHNGdLaUJ2WmlCMGFHVWdjbVYwZFhKdVpXUWdiMkpxWldOMExDQmhjR0Z5ZENCbWNtOXRJSFJvWVhRZ2FYUWdhWE1nZFhOaFlteGxJSGRvWlhKbFpYWmxjaUJ3Y205dGFYTmxjeUJoY21WY2JpQXFJR0p2ZFdkb2RDQmhibVFnYzI5c1pDNWNiaUFxTDF4dVVTNXRZV3RsVUhKdmJXbHpaU0E5SUZCeWIyMXBjMlU3WEc1bWRXNWpkR2x2YmlCUWNtOXRhWE5sS0dSbGMyTnlhWEIwYjNJc0lHWmhiR3hpWVdOckxDQnBibk53WldOMEtTQjdYRzRnSUNBZ2FXWWdLR1poYkd4aVlXTnJJRDA5UFNCMmIybGtJREFwSUh0Y2JpQWdJQ0FnSUNBZ1ptRnNiR0poWTJzZ1BTQm1kVzVqZEdsdmJpQW9iM0FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb2JtVjNJRVZ5Y205eUtGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lVSEp2YldselpTQmtiMlZ6SUc1dmRDQnpkWEJ3YjNKMElHOXdaWEpoZEdsdmJqb2dYQ0lnS3lCdmNGeHVJQ0FnSUNBZ0lDQWdJQ0FnS1NrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBibk53WldOMElEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnYVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUI3YzNSaGRHVTZJRndpZFc1cmJtOTNibHdpZlR0Y2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUhKbGMzVnNkRHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtaWE5qY21sd2RHOXlXMjl3WFNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHUmxjMk55YVhCMGIzSmJiM0JkTG1Gd2NHeDVLSEJ5YjIxcGMyVXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0JtWVd4c1ltRmpheTVqWVd4c0tIQnliMjFwYzJVc0lHOXdMQ0JoY21kektUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6YjJ4MlpTaHlaWE4xYkhRcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIQnliMjFwYzJVdWFXNXpjR1ZqZENBOUlHbHVjM0JsWTNRN1hHNWNiaUFnSUNBdkx5QllXRmdnWkdWd2NtVmpZWFJsWkNCZ2RtRnNkV1ZQWm1BZ1lXNWtJR0JsZUdObGNIUnBiMjVnSUhOMWNIQnZjblJjYmlBZ0lDQnBaaUFvYVc1emNHVmpkQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdhVzV6Y0dWamRHVmtJRDBnYVc1emNHVmpkQ2dwTzF4dUlDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCeWIyMXBjMlV1WlhoalpYQjBhVzl1SUQwZ2FXNXpjR1ZqZEdWa0xuSmxZWE52Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVkbUZzZFdWUFppQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQnBibk53WldOMEtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWlCOGZGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbHVjM0JsWTNSbFpDNXpkR0YwWlNBOVBUMGdYQ0p5WldwbFkzUmxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnYVc1emNHVmpkR1ZrTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJSEpsZEhWeWJpQndjbTl0YVhObE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1hDSmJiMkpxWldOMElGQnliMjFwYzJWZFhDSTdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhR1Z1SUQwZ1puVnVZM1JwYjI0Z0tHWjFiR1pwYkd4bFpDd2djbVZxWldOMFpXUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0IyWVhJZ2MyVnNaaUE5SUhSb2FYTTdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjJZWElnWkc5dVpTQTlJR1poYkhObE95QWdJQzh2SUdWdWMzVnlaU0IwYUdVZ2RXNTBjblZ6ZEdWa0lIQnliMjFwYzJVZ2JXRnJaWE1nWVhRZ2JXOXpkQ0JoWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCemFXNW5iR1VnWTJGc2JDQjBieUJ2Ym1VZ2IyWWdkR2hsSUdOaGJHeGlZV05yYzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWDJaMWJHWnBiR3hsWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSNWNHVnZaaUJtZFd4bWFXeHNaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUdaMWJHWnBiR3hsWkNoMllXeDFaU2tnT2lCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjbVZxWldOMEtHVjRZMlZ3ZEdsdmJpazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnFaV04wWldRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYldGclpWTjBZV05yVkhKaFkyVk1iMjVuS0dWNFkyVndkR2x2Yml3Z2MyVnNaaWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUmxaQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9ibVYzUlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2h1WlhkRmVHTmxjSFJwYjI0cE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtZFc1amRHbHZiaUJmY0hKdlozSmxjM05sWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEhsd1pXOW1JSEJ5YjJkeVpYTnpaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUhCeWIyZHlaWE56WldRb2RtRnNkV1VwSURvZ2RtRnNkV1U3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lITmxiR1l1Y0hKdmJXbHpaVVJwYzNCaGRHTm9LR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZablZzWm1sc2JHVmtLSFpoYkhWbEtTazdYRzRnSUNBZ0lDQWdJSDBzSUZ3aWQyaGxibHdpTENCYlpuVnVZM1JwYjI0Z0tHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU2s3WEc0Z0lDQWdJQ0FnSUgxZEtUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRkJ5YjJkeVpYTnpJSEJ5YjNCaFoyRjBiM0lnYm1WbFpDQjBieUJpWlNCaGRIUmhZMmhsWkNCcGJpQjBhR1VnWTNWeWNtVnVkQ0IwYVdOckxseHVJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tIWnZhV1FnTUN3Z1hDSjNhR1Z1WENJc0lGdDJiMmxrSURBc0lHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYm1WM1ZtRnNkV1U3WEc0Z0lDQWdJQ0FnSUhaaGNpQjBhSEpsZHlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjNWbUZzZFdVZ1BTQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvY21WM0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVhSb2NtVjNLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXViM1JwWm5rb2JtVjNWbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UkxuUmhjQ0E5SUdaMWJtTjBhVzl1SUNod2NtOXRhWE5sTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5SaGNDaGpZV3hzWW1GamF5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGZHZjbXR6SUdGc2JXOXpkQ0JzYVd0bElGd2labWx1WVd4c2VWd2lMQ0JpZFhRZ2JtOTBJR05oYkd4bFpDQm1iM0lnY21WcVpXTjBhVzl1Y3k1Y2JpQXFJRTl5YVdkcGJtRnNJSEpsYzI5c2RYUnBiMjRnZG1Gc2RXVWdhWE1nY0dGemMyVmtJSFJvY205MVoyZ2dZMkZzYkdKaFkyc2dkVzVoWm1abFkzUmxaQzVjYmlBcUlFTmhiR3hpWVdOcklHMWhlU0J5WlhSMWNtNGdZU0J3Y205dGFYTmxJSFJvWVhRZ2QybHNiQ0JpWlNCaGQyRnBkR1ZrSUdadmNpNWNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdOaGJHeGlZV05yWEc0Z0tpQkFjbVYwZFhKdWN5QjdVUzVRY205dGFYTmxmVnh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJR1J2VTI5dFpYUm9hVzVuS0NsY2JpQXFJQ0FnTG5Sb1pXNG9MaTR1S1Z4dUlDb2dJQ0F1ZEdGd0tHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0lDQXVkR2hsYmlndUxpNHBPMXh1SUNvdlhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBZWEFnUFNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzcElIdGNiaUFnSUNCallXeHNZbUZqYXlBOUlGRW9ZMkZzYkdKaFkyc3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0haaGJIVmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkpsWjJsemRHVnljeUJoYmlCdlluTmxjblpsY2lCdmJpQmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dSM1ZoY21GdWRHVmxjenBjYmlBcVhHNGdLaUF4TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0JpWlNCallXeHNaV1FnYjI1c2VTQnZibU5sTGx4dUlDb2dNaTRnZEdoaGRDQmxhWFJvWlhJZ2RHaGxJR1oxYkdacGJHeGxaQ0JqWVd4c1ltRmpheUJ2Y2lCMGFHVWdjbVZxWldOMFpXUWdZMkZzYkdKaFkyc2dkMmxzYkNCaVpWeHVJQ29nSUNBZ1kyRnNiR1ZrTENCaWRYUWdibTkwSUdKdmRHZ3VYRzRnS2lBekxpQjBhR0YwSUdaMWJHWnBiR3hsWkNCaGJtUWdjbVZxWldOMFpXUWdkMmxzYkNCdWIzUWdZbVVnWTJGc2JHVmtJR2x1SUhSb2FYTWdkSFZ5Ymk1Y2JpQXFYRzRnS2lCQWNHRnlZVzBnZG1Gc2RXVWdJQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdkRzhnYjJKelpYSjJaVnh1SUNvZ1FIQmhjbUZ0SUdaMWJHWnBiR3hsWkNBZ1puVnVZM1JwYjI0Z2RHOGdZbVVnWTJGc2JHVmtJSGRwZEdnZ2RHaGxJR1oxYkdacGJHeGxaQ0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJSEpsYW1WamRHVmtJQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElISmxhbVZqZEdsdmJpQmxlR05sY0hScGIyNWNiaUFxSUVCd1lYSmhiU0J3Y205bmNtVnpjMlZrSUdaMWJtTjBhVzl1SUhSdklHSmxJR05oYkd4bFpDQnZiaUJoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnliMjBnZEdobElHbHVkbTlyWldRZ1kyRnNiR0poWTJ0Y2JpQXFMMXh1VVM1M2FHVnVJRDBnZDJobGJqdGNibVoxYm1OMGFXOXVJSGRvWlc0b2RtRnNkV1VzSUdaMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaDJZV3gxWlNrdWRHaGxiaWhtZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6YzJWa0tUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWRHaGxibEpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHNnY21WMGRYSnVJSFpoYkhWbE95QjlLVHRjYm4wN1hHNWNibEV1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9jSEp2YldselpTd2dkbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNod2NtOXRhWE5sS1M1MGFHVnVVbVZ6YjJ4MlpTaDJZV3gxWlNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVVbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tDa2dleUIwYUhKdmR5QnlaV0Z6YjI0N0lIMHBPMXh1ZlR0Y2JseHVVUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5Sb1pXNVNaV3BsWTNRb2NtVmhjMjl1S1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lXNGdiMkpxWldOMElHbHpJRzV2ZENCaElIQnliMjFwYzJVc0lHbDBJR2x6SUdGeklGd2libVZoY2x3aUlHRnpJSEJ2YzNOcFlteGxMbHh1SUNvZ1NXWWdZU0J3Y205dGFYTmxJR2x6SUhKbGFtVmpkR1ZrTENCcGRDQnBjeUJoY3lCY0ltNWxZWEpjSWlCaGN5QndiM056YVdKc1pTQjBiMjh1WEc0Z0tpQkpaaUJwZE9LQW1YTWdZU0JtZFd4bWFXeHNaV1FnY0hKdmJXbHpaU3dnZEdobElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHbHpJRzVsWVhKbGNpNWNiaUFxSUVsbUlHbDA0b0NaY3lCaElHUmxabVZ5Y21Wa0lIQnliMjFwYzJVZ1lXNWtJSFJvWlNCa1pXWmxjbkpsWkNCb1lYTWdZbVZsYmlCeVpYTnZiSFpsWkN3Z2RHaGxYRzRnS2lCeVpYTnZiSFYwYVc5dUlHbHpJRndpYm1WaGNtVnlYQ0l1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wWEc0Z0tpQkFjbVYwZFhKdWN5QnRiM04wSUhKbGMyOXNkbVZrSUNodVpXRnlaWE4wS1NCbWIzSnRJRzltSUhSb1pTQnZZbXBsWTNSY2JpQXFMMXh1WEc0dkx5QllXRmdnYzJodmRXeGtJSGRsSUhKbExXUnZJSFJvYVhNL1hHNVJMbTVsWVhKbGNpQTlJRzVsWVhKbGNqdGNibVoxYm1OMGFXOXVJRzVsWVhKbGNpaDJZV3gxWlNrZ2UxeHVJQ0FnSUdsbUlDaHBjMUJ5YjIxcGMyVW9kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQjJZV3gxWlM1cGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2hwYm5Od1pXTjBaV1F1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcGJuTndaV04wWldRdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRUJ5WlhSMWNtNXpJSGRvWlhSb1pYSWdkR2hsSUdkcGRtVnVJRzlpYW1WamRDQnBjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQlBkR2hsY25kcGMyVWdhWFFnYVhNZ1lTQm1kV3htYVd4c1pXUWdkbUZzZFdVdVhHNGdLaTljYmxFdWFYTlFjbTl0YVhObElEMGdhWE5RY205dGFYTmxPMXh1Wm5WdVkzUnBiMjRnYVhOUWNtOXRhWE5sS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnZZbXBsWTNRZ2FXNXpkR0Z1WTJWdlppQlFjbTl0YVhObE8xeHVmVnh1WEc1UkxtbHpVSEp2YldselpVRnNhV3RsSUQwZ2FYTlFjbTl0YVhObFFXeHBhMlU3WEc1bWRXNWpkR2x2YmlCcGMxQnliMjFwYzJWQmJHbHJaU2h2WW1wbFkzUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2FYTlBZbXBsWTNRb2IySnFaV04wS1NBbUppQjBlWEJsYjJZZ2IySnFaV04wTG5Sb1pXNGdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lqdGNibjFjYmx4dUx5b3FYRzRnS2lCQWNtVjBkWEp1Y3lCM2FHVjBhR1Z5SUhSb1pTQm5hWFpsYmlCdlltcGxZM1FnYVhNZ1lTQndaVzVrYVc1bklIQnliMjFwYzJVc0lHMWxZVzVwYm1jZ2JtOTBYRzRnS2lCbWRXeG1hV3hzWldRZ2IzSWdjbVZxWldOMFpXUXVYRzRnS2k5Y2JsRXVhWE5RWlc1a2FXNW5JRDBnYVhOUVpXNWthVzVuTzF4dVpuVnVZM1JwYjI0Z2FYTlFaVzVrYVc1bktHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luQmxibVJwYm1kY0lqdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWFYTlFaVzVrYVc1bklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1sdWMzQmxZM1FvS1M1emRHRjBaU0E5UFQwZ1hDSndaVzVrYVc1blhDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSFpoYkhWbElHOXlJR1oxYkdacGJHeGxaRnh1SUNvZ2NISnZiV2x6WlM1Y2JpQXFMMXh1VVM1cGMwWjFiR1pwYkd4bFpDQTlJR2x6Um5Wc1ptbHNiR1ZrTzF4dVpuVnVZM1JwYjI0Z2FYTkdkV3htYVd4c1pXUW9iMkpxWldOMEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUNGcGMxQnliMjFwYzJVb2IySnFaV04wS1NCOGZDQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYzBaMWJHWnBiR3hsWkNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVwYm5Od1pXTjBLQ2t1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVXVYRzRnS2k5Y2JsRXVhWE5TWldwbFkzUmxaQ0E5SUdselVtVnFaV04wWldRN1hHNW1kVzVqZEdsdmJpQnBjMUpsYW1WamRHVmtLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCcGMxQnliMjFwYzJVb2IySnFaV04wS1NBbUppQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbWx6VW1WcVpXTjBaV1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJN1hHNTlPMXh1WEc0dkx5OHZJRUpGUjBsT0lGVk9TRUZPUkV4RlJDQlNSVXBGUTFSSlQwNGdWRkpCUTB0SlRrZGNibHh1THk4Z1ZHaHBjeUJ3Y205dGFYTmxJR3hwWW5KaGNua2dZMjl1YzNWdFpYTWdaWGhqWlhCMGFXOXVjeUIwYUhKdmQyNGdhVzRnYUdGdVpHeGxjbk1nYzI4Z2RHaGxlU0JqWVc0Z1ltVmNiaTh2SUdoaGJtUnNaV1FnWW5rZ1lTQnpkV0p6WlhGMVpXNTBJSEJ5YjIxcGMyVXVJQ0JVYUdVZ1pYaGpaWEIwYVc5dWN5Qm5aWFFnWVdSa1pXUWdkRzhnZEdocGN5QmhjbkpoZVNCM2FHVnVYRzR2THlCMGFHVjVJR0Z5WlNCamNtVmhkR1ZrTENCaGJtUWdjbVZ0YjNabFpDQjNhR1Z1SUhSb1pYa2dZWEpsSUdoaGJtUnNaV1F1SUNCT2IzUmxJSFJvWVhRZ2FXNGdSVk0ySUc5eVhHNHZMeUJ6YUdsdGJXVmtJR1Z1ZG1seWIyNXRaVzUwY3l3Z2RHaHBjeUIzYjNWc1pDQnVZWFIxY21Gc2JIa2dZbVVnWVNCZ1UyVjBZQzVjYm5aaGNpQjFibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdXMTA3WEc1MllYSWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlGdGRPMXh1ZG1GeUlIUnlZV05yVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlIUnlkV1U3WEc1Y2JtWjFibU4wYVc5dUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lncElIdGNiaUFnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG14bGJtZDBhQ0E5SURBN1hHNGdJQ0FnZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1c1pXNW5kR2dnUFNBd08xeHVYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpJRDBnZEhKMVpUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUhSeVlXTnJVbVZxWldOMGFXOXVLSEJ5YjIxcGMyVXNJSEpsWVhOdmJpa2dlMXh1SUNBZ0lHbG1JQ2doZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIUjVjR1Z2WmlCd2NtOWpaWE56TG1WdGFYUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGhjbkpoZVY5cGJtUmxlRTltS0hWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5Nc0lIQnliMjFwYzJVcElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQnliMk5sYzNNdVpXMXBkQ2hjSW5WdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ymx3aUxDQnlaV0Z6YjI0c0lIQnliMjFwYzJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjRzl5ZEdWa1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXdkWE5vS0hCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5CMWMyZ29jSEp2YldselpTazdYRzRnSUNBZ2FXWWdLSEpsWVhOdmJpQW1KaUIwZVhCbGIyWWdjbVZoYzI5dUxuTjBZV05ySUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lIVnVhR0Z1Wkd4bFpGSmxZWE52Ym5NdWNIVnphQ2h5WldGemIyNHVjM1JoWTJzcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaGNJaWh1YnlCemRHRmpheWtnWENJZ0t5QnlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFc1MGNtRmphMUpsYW1WamRHbHZiaWh3Y205dGFYTmxLU0I3WEc0Z0lDQWdhV1lnS0NGMGNtRmphMVZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCaGRDQTlJR0Z5Y21GNVgybHVaR1Y0VDJZb2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5d2djSEp2YldselpTazdYRzRnSUNBZ2FXWWdLR0YwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9kSGx3Wlc5bUlIQnliMk5sYzNNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUhCeWIyTmxjM011WlcxcGRDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOckxuSjFia0ZtZEdWeUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ1lYUlNaWEJ2Y25RZ1BTQmhjbkpoZVY5cGJtUmxlRTltS0hKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR0YwVW1Wd2IzSjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtOWpaWE56TG1WdGFYUW9YQ0p5WldwbFkzUnBiMjVJWVc1a2JHVmtYQ0lzSUhWdWFHRnVaR3hsWkZKbFlYTnZibk5iWVhSZExDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21Wd2IzSjBaV1JWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5Od2JHbGpaU2hoZEZKbGNHOXlkQ3dnTVNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTV6Y0d4cFkyVW9ZWFFzSURFcE8xeHVJQ0FnSUNBZ0lDQjFibWhoYm1Sc1pXUlNaV0Z6YjI1ekxuTndiR2xqWlNoaGRDd2dNU2s3WEc0Z0lDQWdmVnh1ZlZ4dVhHNVJMbkpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJSEpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN6dGNibHh1VVM1blpYUlZibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQzh2SUUxaGEyVWdZU0JqYjNCNUlITnZJSFJvWVhRZ1kyOXVjM1Z0WlhKeklHTmhiaWQwSUdsdWRHVnlabVZ5WlNCM2FYUm9JRzkxY2lCcGJuUmxjbTVoYkNCemRHRjBaUzVjYmlBZ0lDQnlaWFIxY200Z2RXNW9ZVzVrYkdWa1VtVmhjMjl1Y3k1emJHbGpaU2dwTzF4dWZUdGNibHh1VVM1emRHOXdWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVWSEpoWTJ0cGJtY2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WelpYUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLQ2s3WEc0Z0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdabUZzYzJVN1hHNTlPMXh1WEc1eVpYTmxkRlZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1vS1R0Y2JseHVMeTh2THlCRlRrUWdWVTVJUVU1RVRFVkVJRkpGU2tWRFZFbFBUaUJVVWtGRFMwbE9SMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQnlaV3BsWTNSbFpDQndjbTl0YVhObExseHVJQ29nUUhCaGNtRnRJSEpsWVhOdmJpQjJZV3gxWlNCa1pYTmpjbWxpYVc1bklIUm9aU0JtWVdsc2RYSmxYRzRnS2k5Y2JsRXVjbVZxWldOMElEMGdjbVZxWldOME8xeHVablZ1WTNScGIyNGdjbVZxWldOMEtISmxZWE52YmlrZ2UxeHVJQ0FnSUhaaGNpQnlaV3BsWTNScGIyNGdQU0JRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKM2FHVnVYQ0k2SUdaMWJtTjBhVzl1SUNoeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2JtOTBaU0IwYUdGMElIUm9aU0JsY25KdmNpQm9ZWE1nWW1WbGJpQm9ZVzVrYkdWa1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2NtVnFaV04wWldRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjFiblJ5WVdOclVtVnFaV04wYVc5dUtIUm9hWE1wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkR1ZrSUQ4Z2NtVnFaV04wWldRb2NtVmhjMjl1S1NBNklIUm9hWE03WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlCbVlXeHNZbUZqYXlncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lDQWdmU3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aWNtVnFaV04wWldSY0lpd2djbVZoYzI5dU9pQnlaV0Z6YjI0Z2ZUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRTV2ZEdVZ2RHaGhkQ0IwYUdVZ2NtVmhjMjl1SUdoaGN5QnViM1FnWW1WbGJpQm9ZVzVrYkdWa0xseHVJQ0FnSUhSeVlXTnJVbVZxWldOMGFXOXVLSEpsYW1WamRHbHZiaXdnY21WaGMyOXVLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQnlaV3BsWTNScGIyNDdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1EyOXVjM1J5ZFdOMGN5QmhJR1oxYkdacGJHeGxaQ0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMbHh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlZjYmlBcUwxeHVVUzVtZFd4bWFXeHNJRDBnWm5Wc1ptbHNiRHRjYm1aMWJtTjBhVzl1SUdaMWJHWnBiR3dvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VISnZiV2x6WlNoN1hHNGdJQ0FnSUNBZ0lGd2lkMmhsYmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2laMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdWYmJtRnRaVjA3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2ljMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsTENCeWFITXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsVzI1aGJXVmRJRDBnY21oek8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW1SbGJHVjBaVndpT2lCbWRXNWpkR2x2YmlBb2JtRnRaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZzWlhSbElIWmhiSFZsVzI1aGJXVmRPMXh1SUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNCY0luQnZjM1JjSWpvZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRTFoY21zZ1RXbHNiR1Z5SUhCeWIzQnZjMlZ6SUhSb1lYUWdjRzl6ZENCM2FYUm9JRzV2SUc1aGJXVWdjMmh2ZFd4a0lHRndjR3g1SUdGY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c1aGJXVWdQVDA5SUc1MWJHd2dmSHdnYm1GdFpTQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFpoYkhWbExtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpWdHVZVzFsWFM1aGNIQnNlU2gyWVd4MVpTd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2lZWEJ3YkhsY0lqb2dablZ1WTNScGIyNGdLSFJvYVhOd0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVdVlYQndiSGtvZEdocGMzQXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW10bGVYTmNJam9nWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJRzlpYW1WamRGOXJaWGx6S0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBzSUhadmFXUWdNQ3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aVpuVnNabWxzYkdWa1hDSXNJSFpoYkhWbE9pQjJZV3gxWlNCOU8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuWmxjblJ6SUhSb1pXNWhZbXhsY3lCMGJ5QlJJSEJ5YjIxcGMyVnpMbHh1SUNvZ1FIQmhjbUZ0SUhCeWIyMXBjMlVnZEdobGJtRmliR1VnY0hKdmJXbHpaVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQlJJSEJ5YjIxcGMyVmNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyOWxjbU5sS0hCeWIyMXBjMlVwSUh0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vc0lHUmxabVZ5Y21Wa0xuSmxhbVZqZEN3Z1pHVm1aWEp5WldRdWJtOTBhV1o1S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFRnVibTkwWVhSbGN5QmhiaUJ2WW1wbFkzUWdjM1ZqYUNCMGFHRjBJR2wwSUhkcGJHd2dibVYyWlhJZ1ltVmNiaUFxSUhSeVlXNXpabVZ5Y21Wa0lHRjNZWGtnWm5KdmJTQjBhR2x6SUhCeWIyTmxjM01nYjNabGNpQmhibmtnY0hKdmJXbHpaVnh1SUNvZ1kyOXRiWFZ1YVdOaGRHbHZiaUJqYUdGdWJtVnNMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5Ym5NZ2NISnZiV2x6WlNCaElIZHlZWEJ3YVc1bklHOW1JSFJvWVhRZ2IySnFaV04wSUhSb1lYUmNiaUFxSUdGa1pHbDBhVzl1WVd4c2VTQnlaWE53YjI1a2N5QjBieUIwYUdVZ1hDSnBjMFJsWmx3aUlHMWxjM05oWjJWY2JpQXFJSGRwZEdodmRYUWdZU0J5WldwbFkzUnBiMjR1WEc0Z0tpOWNibEV1YldGemRHVnlJRDBnYldGemRHVnlPMXh1Wm5WdVkzUnBiMjRnYldGemRHVnlLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUWNtOXRhWE5sS0h0Y2JpQWdJQ0FnSUNBZ1hDSnBjMFJsWmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3ZlZ4dUlDQWdJSDBzSUdaMWJtTjBhVzl1SUdaaGJHeGlZV05yS0c5d0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCa2FYTndZWFJqYUNodlltcGxZM1FzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lIMHBPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlGTndjbVZoWkhNZ2RHaGxJSFpoYkhWbGN5QnZaaUJoSUhCeWIyMXBjMlZrSUdGeWNtRjVJRzltSUdGeVozVnRaVzUwY3lCcGJuUnZJSFJvWlZ4dUlDb2dablZzWm1sc2JHMWxiblFnWTJGc2JHSmhZMnN1WEc0Z0tpQkFjR0Z5WVcwZ1puVnNabWxzYkdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZG1GeWFXRmthV01nWVhKbmRXMWxiblJ6SUdaeWIyMGdkR2hsWEc0Z0tpQndjbTl0YVhObFpDQmhjbkpoZVZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZEdobElHVjRZMlZ3ZEdsdmJpQnBaaUIwYUdVZ2NISnZiV2x6WlZ4dUlDb2dhWE1nY21WcVpXTjBaV1F1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1VnYjNJZ2RHaHliM2R1SUdWNFkyVndkR2x2YmlCdlpseHVJQ29nWldsMGFHVnlJR05oYkd4aVlXTnJMbHh1SUNvdlhHNVJMbk53Y21WaFpDQTlJSE53Y21WaFpEdGNibVoxYm1OMGFXOXVJSE53Y21WaFpDaDJZV3gxWlN3Z1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktIWmhiSFZsS1M1emNISmxZV1FvWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5Od2NtVmhaQ0E5SUdaMWJtTjBhVzl1SUNobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvWVhKeVlYa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHeGxaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnljbUY1S1R0Y2JpQWdJQ0I5TENCeVpXcGxZM1JsWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSb1pTQmhjM2x1WXlCbWRXNWpkR2x2YmlCcGN5QmhJR1JsWTI5eVlYUnZjaUJtYjNJZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dWN5d2dkSFZ5Ym1sdVoxeHVJQ29nZEdobGJTQnBiblJ2SUdGemVXNWphSEp2Ym05MWN5Qm5aVzVsY21GMGIzSnpMaUFnUVd4MGFHOTFaMmdnWjJWdVpYSmhkRzl5Y3lCaGNtVWdiMjVzZVNCd1lYSjBYRzRnS2lCdlppQjBhR1VnYm1WM1pYTjBJRVZEVFVGVFkzSnBjSFFnTmlCa2NtRm1kSE1zSUhSb2FYTWdZMjlrWlNCa2IyVnpJRzV2ZENCallYVnpaU0J6ZVc1MFlYaGNiaUFxSUdWeWNtOXljeUJwYmlCdmJHUmxjaUJsYm1kcGJtVnpMaUFnVkdocGN5QmpiMlJsSUhOb2IzVnNaQ0JqYjI1MGFXNTFaU0IwYnlCM2IzSnJJR0Z1WkNCM2FXeHNYRzRnS2lCcGJpQm1ZV04wSUdsdGNISnZkbVVnYjNabGNpQjBhVzFsSUdGeklIUm9aU0JzWVc1bmRXRm5aU0JwYlhCeWIzWmxjeTVjYmlBcVhHNGdLaUJGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnWTNWeWNtVnVkR3g1SUhCaGNuUWdiMllnVmpnZ2RtVnljMmx2YmlBekxqRTVJSGRwZEdnZ2RHaGxYRzRnS2lBdExXaGhjbTF2Ym5rdFoyVnVaWEpoZEc5eWN5QnlkVzUwYVcxbElHWnNZV2NnWlc1aFlteGxaQzRnSUZOd2FXUmxjazF2Ym10bGVTQm9ZWE1nYUdGa0lIUm9aVzFjYmlBcUlHWnZjaUJzYjI1blpYSXNJR0oxZENCMWJtUmxjaUJoYmlCdmJHUmxjaUJRZVhSb2IyNHRhVzV6Y0dseVpXUWdabTl5YlM0Z0lGUm9hWE1nWm5WdVkzUnBiMjVjYmlBcUlIZHZjbXR6SUc5dUlHSnZkR2dnYTJsdVpITWdiMllnWjJWdVpYSmhkRzl5Y3k1Y2JpQXFYRzRnS2lCRVpXTnZjbUYwWlhNZ1lTQm5aVzVsY21GMGIzSWdablZ1WTNScGIyNGdjM1ZqYUNCMGFHRjBPbHh1SUNvZ0lDMGdhWFFnYldGNUlIbHBaV3hrSUhCeWIyMXBjMlZ6WEc0Z0tpQWdMU0JsZUdWamRYUnBiMjRnZDJsc2JDQmpiMjUwYVc1MVpTQjNhR1Z1SUhSb1lYUWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1JjYmlBcUlDQXRJSFJvWlNCMllXeDFaU0J2WmlCMGFHVWdlV2xsYkdRZ1pYaHdjbVZ6YzJsdmJpQjNhV3hzSUdKbElIUm9aU0JtZFd4bWFXeHNaV1FnZG1Gc2RXVmNiaUFxSUNBdElHbDBJSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUNoM2FHVnVJSFJvWlNCblpXNWxjbUYwYjNKY2JpQXFJQ0FnSUhOMGIzQnpJR2wwWlhKaGRHbHVaeWxjYmlBcUlDQXRJSFJvWlNCa1pXTnZjbUYwWldRZ1puVnVZM1JwYjI0Z2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxSUNBZ0lHOW1JSFJvWlNCblpXNWxjbUYwYjNJZ2IzSWdkR2hsSUdacGNuTjBJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdZVzF2Ym1jZ2RHaHZjMlZjYmlBcUlDQWdJSGxwWld4a1pXUXVYRzRnS2lBZ0xTQnBaaUJoYmlCbGNuSnZjaUJwY3lCMGFISnZkMjRnYVc0Z2RHaGxJR2RsYm1WeVlYUnZjaXdnYVhRZ2NISnZjR0ZuWVhSbGN5QjBhSEp2ZFdkb1hHNGdLaUFnSUNCbGRtVnllU0JtYjJ4c2IzZHBibWNnZVdsbGJHUWdkVzUwYVd3Z2FYUWdhWE1nWTJGMVoyaDBMQ0J2Y2lCMWJuUnBiQ0JwZENCbGMyTmhjR1Z6WEc0Z0tpQWdJQ0IwYUdVZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dUlHRnNkRzluWlhSb1pYSXNJR0Z1WkNCcGN5QjBjbUZ1YzJ4aGRHVmtJR2x1ZEc4Z1lWeHVJQ29nSUNBZ2NtVnFaV04wYVc5dUlHWnZjaUIwYUdVZ2NISnZiV2x6WlNCeVpYUjFjbTVsWkNCaWVTQjBhR1VnWkdWamIzSmhkR1ZrSUdkbGJtVnlZWFJ2Y2k1Y2JpQXFMMXh1VVM1aGMzbHVZeUE5SUdGemVXNWpPMXh1Wm5WdVkzUnBiMjRnWVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJSGRvWlc0Z2RtVnlZaUJwY3lCY0luTmxibVJjSWl3Z1lYSm5JR2x6SUdFZ2RtRnNkV1ZjYmlBZ0lDQWdJQ0FnTHk4Z2QyaGxiaUIyWlhKaUlHbHpJRndpZEdoeWIzZGNJaXdnWVhKbklHbHpJR0Z1SUdWNFkyVndkR2x2Ymx4dUlDQWdJQ0FnSUNCbWRXNWpkR2x2YmlCamIyNTBhVzUxWlhJb2RtVnlZaXdnWVhKbktTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjbVZ6ZFd4ME8xeHVYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlZiblJwYkNCV09DQXpMakU1SUM4Z1EyaHliMjFwZFcwZ01qa2dhWE1nY21Wc1pXRnpaV1FzSUZOd2FXUmxjazF2Ym10bGVTQnBjeUIwYUdVZ2IyNXNlVnh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdaVzVuYVc1bElIUm9ZWFFnYUdGeklHRWdaR1Z3Ykc5NVpXUWdZbUZ6WlNCdlppQmljbTkzYzJWeWN5QjBhR0YwSUhOMWNIQnZjblFnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUVodmQyVjJaWElzSUZOTkozTWdaMlZ1WlhKaGRHOXljeUIxYzJVZ2RHaGxJRkI1ZEdodmJpMXBibk53YVhKbFpDQnpaVzFoYm5ScFkzTWdiMlpjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRzkxZEdSaGRHVmtJRVZUTmlCa2NtRm1kSE11SUNCWFpTQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnUlZNMkxDQmlkWFFnZDJVblpDQmhiSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJzYVd0bElIUnZJRzFoYTJVZ2FYUWdjRzl6YzJsaWJHVWdkRzhnZFhObElHZGxibVZ5WVhSdmNuTWdhVzRnWkdWd2JHOTVaV1FnWW5KdmQzTmxjbk1zSUhOdlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCM1pTQmhiSE52SUhOMWNIQnZjblFnVUhsMGFHOXVMWE4wZVd4bElHZGxibVZ5WVhSdmNuTXVJQ0JCZENCemIyMWxJSEJ2YVc1MElIZGxJR05oYmlCeVpXMXZkbVZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSFJvYVhNZ1lteHZZMnN1WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnVTNSdmNFbDBaWEpoZEdsdmJpQTlQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVWVE5pQkhaVzVsY21GMGIzSnpYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ6ZFd4MElEMGdaMlZ1WlhKaGRHOXlXM1psY21KZEtHRnlaeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb1pYaGpaWEIwYVc5dUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hKbGMzVnNkQzVrYjI1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJSS0hKbGMzVnNkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NtVnpkV3gwTG5aaGJIVmxMQ0JqWVd4c1ltRmpheXdnWlhKeVltRmpheWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJUY0dsa1pYSk5iMjVyWlhrZ1IyVnVaWEpoZEc5eWMxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJqWVhObElIZG9aVzRnVTAwZ1pHOWxjeUJGVXpZZ1oyVnVaWEpoZEc5eWN5NWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm5aVzVsY21GMGIzSmJkbVZ5WWwwb1lYSm5LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsZUdObGNIUnBiMjRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0dselUzUnZjRWwwWlhKaGRHbHZiaWhsZUdObGNIUnBiMjRwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnVVNobGVHTmxjSFJwYjI0dWRtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjNhR1Z1S0hKbGMzVnNkQ3dnWTJGc2JHSmhZMnNzSUdWeWNtSmhZMnNwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhaaGNpQm5aVzVsY21GMGIzSWdQU0J0WVd0bFIyVnVaWEpoZEc5eUxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQmpZV3hzWW1GamF5QTlJR052Ym5ScGJuVmxjaTVpYVc1a0tHTnZiblJwYm5WbGNpd2dYQ0p1WlhoMFhDSXBPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pYSnlZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSjBhSEp2ZDF3aUtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOcktDazdYRzRnSUNBZ2ZUdGNibjFjYmx4dUx5b3FYRzRnS2lCVWFHVWdjM0JoZDI0Z1puVnVZM1JwYjI0Z2FYTWdZU0J6YldGc2JDQjNjbUZ3Y0dWeUlHRnliM1Z1WkNCaGMzbHVZeUIwYUdGMElHbHRiV1ZrYVdGMFpXeDVYRzRnS2lCallXeHNjeUIwYUdVZ1oyVnVaWEpoZEc5eUlHRnVaQ0JoYkhOdklHVnVaSE1nZEdobElIQnliMjFwYzJVZ1kyaGhhVzRzSUhOdklIUm9ZWFFnWVc1NVhHNGdLaUIxYm1oaGJtUnNaV1FnWlhKeWIzSnpJR0Z5WlNCMGFISnZkMjRnYVc1emRHVmhaQ0J2WmlCbWIzSjNZWEprWldRZ2RHOGdkR2hsSUdWeWNtOXlYRzRnS2lCb1lXNWtiR1Z5TGlCVWFHbHpJR2x6SUhWelpXWjFiQ0JpWldOaGRYTmxJR2wwSjNNZ1pYaDBjbVZ0Wld4NUlHTnZiVzF2YmlCMGJ5QnlkVzVjYmlBcUlHZGxibVZ5WVhSdmNuTWdZWFFnZEdobElIUnZjQzFzWlhabGJDQjBieUIzYjNKcklIZHBkR2dnYkdsaWNtRnlhV1Z6TGx4dUlDb3ZYRzVSTG5Od1lYZHVJRDBnYzNCaGQyNDdYRzVtZFc1amRHbHZiaUJ6Y0dGM2JpaHRZV3RsUjJWdVpYSmhkRzl5S1NCN1hHNGdJQ0FnVVM1a2IyNWxLRkV1WVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrb0tTazdYRzU5WEc1Y2JpOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJwYm5SbGNtWmhZMlVnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVMeW9xWEc0Z0tpQlVhSEp2ZDNNZ1lTQlNaWFIxY201V1lXeDFaU0JsZUdObGNIUnBiMjRnZEc4Z2MzUnZjQ0JoYmlCaGMzbHVZMmh5YjI1dmRYTWdaMlZ1WlhKaGRHOXlMbHh1SUNwY2JpQXFJRlJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0VnYzNSdmNDMW5ZWEFnYldWaGMzVnlaU0IwYnlCemRYQndiM0owSUdkbGJtVnlZWFJ2Y2lCeVpYUjFjbTVjYmlBcUlIWmhiSFZsY3lCcGJpQnZiR1JsY2lCR2FYSmxabTk0TDFOd2FXUmxjazF2Ym10bGVTNGdJRWx1SUdKeWIzZHpaWEp6SUhSb1lYUWdjM1Z3Y0c5eWRDQkZVelpjYmlBcUlHZGxibVZ5WVhSdmNuTWdiR2xyWlNCRGFISnZiV2wxYlNBeU9Td2dhblZ6ZENCMWMyVWdYQ0p5WlhSMWNtNWNJaUJwYmlCNWIzVnlJR2RsYm1WeVlYUnZjbHh1SUNvZ1puVnVZM1JwYjI1ekxseHVJQ3BjYmlBcUlFQndZWEpoYlNCMllXeDFaU0IwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJR1p2Y2lCMGFHVWdjM1Z5Y205MWJtUnBibWNnWjJWdVpYSmhkRzl5WEc0Z0tpQkFkR2h5YjNkeklGSmxkSFZ5YmxaaGJIVmxJR1Y0WTJWd2RHbHZiaUIzYVhSb0lIUm9aU0IyWVd4MVpTNWNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQXZMeUJGVXpZZ2MzUjViR1ZjYmlBcUlGRXVZWE41Ym1Nb1puVnVZM1JwYjI0cUlDZ3BJSHRjYmlBcUlDQWdJQ0FnZG1GeUlHWnZieUE5SUhscFpXeGtJR2RsZEVadmIxQnliMjFwYzJVb0tUdGNiaUFxSUNBZ0lDQWdkbUZ5SUdKaGNpQTlJSGxwWld4a0lHZGxkRUpoY2xCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2NtVjBkWEp1SUdadmJ5QXJJR0poY2p0Y2JpQXFJSDBwWEc0Z0tpQXZMeUJQYkdSbGNpQlRjR2xrWlhKTmIyNXJaWGtnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ29nSUNBZ0lDQjJZWElnWm05dklEMGdlV2xsYkdRZ1oyVjBSbTl2VUhKdmJXbHpaU2dwTzF4dUlDb2dJQ0FnSUNCMllYSWdZbUZ5SUQwZ2VXbGxiR1FnWjJWMFFtRnlVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0JSTG5KbGRIVnliaWhtYjI4Z0t5QmlZWElwTzF4dUlDb2dmU2xjYmlBcUwxeHVVVnRjSW5KbGRIVnlibHdpWFNBOUlGOXlaWFIxY200N1hHNW1kVzVqZEdsdmJpQmZjbVYwZFhKdUtIWmhiSFZsS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUZGU1pYUjFjbTVXWVd4MVpTaDJZV3gxWlNrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUlHUmxZMjl5WVhSdmNpQmxibk4xY21WeklIUm9ZWFFnWVc1NUlIQnliMjFwYzJVZ1lYSm5kVzFsYm5SelhHNGdLaUJoY21VZ2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa0lHRnpJSFpoYkhWbGN5QW9ZSFJvYVhOZ0lHbHpJR0ZzYzI4Z2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa1hHNGdLaUJoY3lCaElIWmhiSFZsS1M0Z0lFbDBJSGRwYkd3Z1lXeHpieUJsYm5OMWNtVWdkR2hoZENCMGFHVWdjbVZ6ZFd4MElHOW1JR0VnWm5WdVkzUnBiMjRnYVhOY2JpQXFJR0ZzZDJGNWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUhaaGNpQmhaR1FnUFNCUkxuQnliMjFwYzJWa0tHWjFibU4wYVc5dUlDaGhMQ0JpS1NCN1hHNGdLaUFnSUNBZ2NtVjBkWEp1SUdFZ0t5QmlPMXh1SUNvZ2ZTazdYRzRnS2lCaFpHUW9VU2hoS1N3Z1VTaENLU2s3WEc0Z0tseHVJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnWTJGc2JHSmhZMnNnVkdobElHWjFibU4wYVc5dUlIUnZJR1JsWTI5eVlYUmxYRzRnS2lCQWNtVjBkWEp1Y3lCN1puVnVZM1JwYjI1OUlHRWdablZ1WTNScGIyNGdkR2hoZENCb1lYTWdZbVZsYmlCa1pXTnZjbUYwWldRdVhHNGdLaTljYmxFdWNISnZiV2x6WldRZ1BTQndjbTl0YVhObFpEdGNibVoxYm1OMGFXOXVJSEJ5YjIxcGMyVmtLR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSE53Y21WaFpDaGJkR2hwY3l3Z1lXeHNLR0Z5WjNWdFpXNTBjeWxkTENCbWRXNWpkR2x2YmlBb2MyVnNaaXdnWVhKbmN5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1Gd2NHeDVLSE5sYkdZc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dktpcGNiaUFxSUhObGJtUnpJR0VnYldWemMyRm5aU0IwYnlCaElIWmhiSFZsSUdsdUlHRWdablYwZFhKbElIUjFjbTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FxSUhSb1pTQnlaV05wY0dsbGJuUmNiaUFxSUVCd1lYSmhiU0J2Y0NCMGFHVWdibUZ0WlNCdlppQjBhR1VnYldWemMyRm5aU0J2Y0dWeVlYUnBiMjRzSUdVdVp5NHNJRndpZDJobGJsd2lMRnh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkRzhnWW1VZ1ptOXlkMkZ5WkdWa0lIUnZJSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFJRUJ5WlhSMWNtNXpJSEpsYzNWc2RDQjdVSEp2YldselpYMGdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6ZFd4MElHOW1JSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFMMXh1VVM1a2FYTndZWFJqYUNBOUlHUnBjM0JoZEdOb08xeHVablZ1WTNScGIyNGdaR2x6Y0dGMFkyZ29iMkpxWldOMExDQnZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdVpHbHpjR0YwWTJnb2IzQXNJR0Z5WjNNcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a2FYTndZWFJqYUNBOUlHWjFibU4wYVc5dUlDaHZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0J6Wld4bUxuQnliMjFwYzJWRWFYTndZWFJqYUNoa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCdmNDd2dZWEpuY3lrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFZGxkSE1nZEdobElIWmhiSFZsSUc5bUlHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWjJWMFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQndjbTl3WlhKMGVTQjJZV3gxWlZ4dUlDb3ZYRzVSTG1kbGRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJR3RsZVNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvWENKblpYUmNJaXdnVzJ0bGVWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aVoyVjBYQ0lzSUZ0clpYbGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVMlYwY3lCMGFHVWdkbUZzZFdVZ2IyWWdZU0J3Y205d1pYSjBlU0JwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUc5aWFtVmpkQ0J2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0J1WVcxbElDQWdJQ0FnYm1GdFpTQnZaaUJ3Y205d1pYSjBlU0IwYnlCelpYUmNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQWdJQ0FnYm1WM0lIWmhiSFZsSUc5bUlIQnliM0JsY25SNVhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzV6WlhRZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnJaWGtzSUhaaGJIVmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbk5sZEZ3aUxDQmJhMlY1TENCMllXeDFaVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YzJWMElEMGdablZ1WTNScGIyNGdLR3RsZVN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkVaV3hsZEdWeklHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWkdWc1pYUmxYRzRnS2lCQWNtVjBkWEp1SUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFMMXh1VVM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWkdWc1pYUmxYQ0pkSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2EyVjVLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbVJsYkdWMFpWd2lMQ0JiYTJWNVhTazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNWtaV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1SbGJHVjBaVndpWFNBOUlHWjFibU4wYVc5dUlDaHJaWGtwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVsdWRtOXJaWE1nWVNCdFpYUm9iMlFnYVc0Z1lTQm1kWFIxY21VZ2RIVnliaTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnSUNBZ2NISnZiV2x6WlNCdmNpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJR1p2Y2lCMFlYSm5aWFFnYjJKcVpXTjBYRzRnS2lCQWNHRnlZVzBnYm1GdFpTQWdJQ0FnSUc1aGJXVWdiMllnYldWMGFHOWtJSFJ2SUdsdWRtOXJaVnh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJQ0FnSUNCaElIWmhiSFZsSUhSdklIQnZjM1FzSUhSNWNHbGpZV3hzZVNCaGJpQmhjbkpoZVNCdlpseHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYm5adlkyRjBhVzl1SUdGeVozVnRaVzUwY3lCbWIzSWdjSEp2YldselpYTWdkR2hoZEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbVVnZFd4MGFXMWhkR1ZzZVNCaVlXTnJaV1FnZDJsMGFDQmdjbVZ6YjJ4MlpXQWdkbUZzZFdWekxGeHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JoY3lCdmNIQnZjMlZrSUhSdklIUm9iM05sSUdKaFkydGxaQ0IzYVhSb0lGVlNUSE5jYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxjbVZwYmlCMGFHVWdjRzl6ZEdWa0lIWmhiSFZsSUdOaGJpQmlaU0JoYm5sY2JpQXFJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdTbE5QVGlCelpYSnBZV3hwZW1GaWJHVWdiMkpxWldOMExseHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsWEc0Z0tpOWNiaTh2SUdKdmRXNWtJR3h2WTJGc2JIa2dZbVZqWVhWelpTQnBkQ0JwY3lCMWMyVmtJR0o1SUc5MGFHVnlJRzFsZEdodlpITmNibEV1YldGd2NHeDVJRDBnTHk4Z1dGaFlJRUZ6SUhCeWIzQnZjMlZrSUdKNUlGd2lVbVZrYzJGdVpISnZYQ0pjYmxFdWNHOXpkQ0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJ2YzNRZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkpiblp2YTJWeklHRWdiV1YwYUc5a0lHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEJoY21GdElHNWhiV1VnSUNBZ0lDQnVZVzFsSUc5bUlHMWxkR2h2WkNCMGJ5QnBiblp2YTJWY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklDQWdZWEp5WVhrZ2IyWWdhVzUyYjJOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUlFQnlaWFIxY200Z2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGRIVnliaUIyWVd4MVpWeHVJQ292WEc1UkxuTmxibVFnUFNBdkx5QllXRmdnVFdGeWF5Qk5hV3hzWlhJbmN5QndjbTl3YjNObFpDQndZWEpzWVc1alpWeHVVUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVSTG1sdWRtOXJaU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeUtWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlZ1WkNBOUlDOHZJRmhZV0NCTllYSnJJRTFwYkd4bGNpZHpJSEJ5YjNCdmMyVmtJSEJoY214aGJtTmxYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYm5admEyVWdQU0JtZFc1amRHbHZiaUFvYm1GdFpTQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJCY0hCc2FXVnpJSFJvWlNCd2NtOXRhWE5sWkNCbWRXNWpkR2x2YmlCcGJpQmhJR1oxZEhWeVpTQjBkWEp1TGx4dUlDb2dRSEJoY21GdElHOWlhbVZqZENBZ0lDQndjbTl0YVhObElHOXlJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlVnWm05eUlIUmhjbWRsZENCbWRXNWpkR2x2Ymx4dUlDb2dRSEJoY21GdElHRnlaM01nSUNBZ0lDQmhjbkpoZVNCdlppQmhjSEJzYVdOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUwxeHVVUzVtWVhCd2JIa2dQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltRndjR3g1WENJc0lGdDJiMmxrSURBc0lHRnlaM05kS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WkdsemNHRjBZMmdvWENKaGNIQnNlVndpTENCYmRtOXBaQ0F3TENCaGNtZHpYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUM0dUxtRnlaM01nSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVWdGNJblJ5ZVZ3aVhTQTlYRzVSTG1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2lBdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aVlYQndiSGxjSWl3Z1czWnZhV1FnTUN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVptTmhiR3dnUFNCbWRXNWpkR2x2YmlBb0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5bGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRbWx1WkhNZ2RHaGxJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMQ0IwY21GdWMyWnZjbTFwYm1jZ2NtVjBkWEp1SUhaaGJIVmxjeUJwYm5SdklHRWdablZzWm1sc2JHVmtYRzRnS2lCd2NtOXRhWE5sSUdGdVpDQjBhSEp2ZDI0Z1pYSnliM0p6SUdsdWRHOGdZU0J5WldwbFkzUmxaQ0J2Ym1VdVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHWjFibU4wYVc5dVhHNGdLaUJBY0dGeVlXMGdMaTR1WVhKbmN5QWdJR0Z5Y21GNUlHOW1JR0Z3Y0d4cFkyRjBhVzl1SUdGeVozVnRaVzUwYzF4dUlDb3ZYRzVSTG1aaWFXNWtJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQndjbTl0YVhObElEMGdVU2h2WW1wbFkzUXBPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlIQnliMjFwYzJVZ1BTQjBhR2x6TzF4dUlDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhGMVpYTjBjeUIwYUdVZ2JtRnRaWE1nYjJZZ2RHaGxJRzkzYm1Wa0lIQnliM0JsY25ScFpYTWdiMllnWVNCd2NtOXRhWE5sWkZ4dUlDb2diMkpxWldOMElHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2EyVjVjeUJ2WmlCMGFHVWdaWFpsYm5SMVlXeHNlU0J6WlhSMGJHVmtJRzlpYW1WamRGeHVJQ292WEc1UkxtdGxlWE1nUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW10bGVYTmNJaXdnVzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWEyVjVjeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJVZFhKdWN5QmhiaUJoY25KaGVTQnZaaUJ3Y205dGFYTmxjeUJwYm5SdklHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGt1SUNCSlppQmhibmtnYjJaY2JpQXFJSFJvWlNCd2NtOXRhWE5sY3lCblpYUnpJSEpsYW1WamRHVmtMQ0IwYUdVZ2QyaHZiR1VnWVhKeVlYa2dhWE1nY21WcVpXTjBaV1FnYVcxdFpXUnBZWFJsYkhrdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNUtuMGdZVzRnWVhKeVlYa2dLRzl5SUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUtTQnZaaUIyWVd4MVpYTWdLRzl5WEc0Z0tpQndjbTl0YVhObGN5Qm1iM0lnZG1Gc2RXVnpLVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCaGNuSmhlU0J2WmlCMGFHVWdZMjl5Y21WemNHOXVaR2x1WnlCMllXeDFaWE5jYmlBcUwxeHVMeThnUW5rZ1RXRnlheUJOYVd4c1pYSmNiaTh2SUdoMGRIQTZMeTkzYVd0cExtVmpiV0Z6WTNKcGNIUXViM0puTDJSdmEzVXVjR2h3UDJsa1BYTjBjbUYzYldGdU9tTnZibU4xY25KbGJtTjVKbkpsZGoweE16QTROemMyTlRJeEkyRnNiR1oxYkdacGJHeGxaRnh1VVM1aGJHd2dQU0JoYkd3N1hHNW1kVzVqZEdsdmJpQmhiR3dvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkMmhsYmlod2NtOXRhWE5sY3l3Z1puVnVZM1JwYjI0Z0tIQnliMjFwYzJWektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCd1pXNWthVzVuUTI5MWJuUWdQU0F3TzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSEJ5YjIxcGMyVXNJR2x1WkdWNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjMjVoY0hOb2IzUTdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhWE5RY205dGFYTmxLSEJ5YjIxcGMyVXBJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS0hOdVlYQnphRzkwSUQwZ2NISnZiV2x6WlM1cGJuTndaV04wS0NrcExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpWEc0Z0lDQWdJQ0FnSUNBZ0lDQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0J6Ym1Gd2MyaHZkQzUyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS3l0d1pXNWthVzVuUTI5MWJuUTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkMmhsYmloY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2d0TFhCbGJtUnBibWREYjNWdWRDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVW9jSEp2YldselpYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1S0hzZ2FXNWtaWGc2SUdsdVpHVjRMQ0IyWVd4MVpUb2djSEp2WjNKbGMzTWdmU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2NHVnVaR2x1WjBOdmRXNTBJRDA5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0hCeWIyMXBjMlZ6S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c0lEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQmhiR3dvZEdocGN5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVZ2IyWWdZVzRnWVhKeVlYa3VJRkJ5YVc5eUlISmxhbVZqZEdWa0lIQnliMjFwYzJWeklHRnlaVnh1SUNvZ2FXZHViM0psWkM0Z0lGSmxhbVZqZEhNZ2IyNXNlU0JwWmlCaGJHd2djSEp2YldselpYTWdZWEpsSUhKbGFtVmpkR1ZrTGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVNwOUlHRnVJR0Z5Y21GNUlHTnZiblJoYVc1cGJtY2dkbUZzZFdWeklHOXlJSEJ5YjIxcGMyVnpJR1p2Y2lCMllXeDFaWE5jYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1kV3htYVd4c1pXUWdkMmwwYUNCMGFHVWdkbUZzZFdVZ2IyWWdkR2hsSUdacGNuTjBJSEpsYzI5c2RtVmtJSEJ5YjIxcGMyVXNYRzRnS2lCdmNpQmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdhV1lnWVd4c0lIQnliMjFwYzJWeklHRnlaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzVoYm5rZ1BTQmhibms3WEc1Y2JtWjFibU4wYVc5dUlHRnVlU2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJR2xtSUNod2NtOXRhWE5sY3k1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRkV1Y21WemIyeDJaU2dwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlGRXVaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdjR1Z1WkdsdVowTnZkVzUwSUQwZ01EdGNiaUFnSUNCaGNuSmhlVjl5WldSMVkyVW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y21WMkxDQmpkWEp5Wlc1MExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUhCeWIyMXBjMlZ6VzJsdVpHVjRYVHRjYmx4dUlDQWdJQ0FnSUNCd1pXNWthVzVuUTI5MWJuUXJLenRjYmx4dUlDQWdJQ0FnSUNCM2FHVnVLSEJ5YjIxcGMyVXNJRzl1Um5Wc1ptbHNiR1ZrTENCdmJsSmxhbVZqZEdWa0xDQnZibEJ5YjJkeVpYTnpLVHRjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1R2RXeG1hV3hzWldRb2NtVnpkV3gwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEpsYzNWc2RDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1U1pXcGxZM1JsWkNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCbGJtUnBibWREYjNWdWRDMHRPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGFtVmpkQ2h1WlhjZ1JYSnliM0lvWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lRMkZ1SjNRZ1oyVjBJR1oxYkdacGJHeHRaVzUwSUhaaGJIVmxJR1p5YjIwZ1lXNTVJSEJ5YjIxcGMyVXNJR0ZzYkNCY0lpQXJYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aWNISnZiV2x6WlhNZ2QyVnlaU0J5WldwbFkzUmxaQzVjSWx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNrcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHOXVVSEp2WjNKbGMzTW9jSEp2WjNKbGMzTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xtNXZkR2xtZVNoN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXNWtaWGc2SUdsdVpHVjRMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQndjbTluY21WemMxeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOUxDQjFibVJsWm1sdVpXUXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1GdWVTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdZVzU1S0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhZV2wwY3lCbWIzSWdZV3hzSUhCeWIyMXBjMlZ6SUhSdklHSmxJSE5sZEhSc1pXUXNJR1ZwZEdobGNpQm1kV3htYVd4c1pXUWdiM0pjYmlBcUlISmxhbVZqZEdWa0xpQWdWR2hwY3lCcGN5QmthWE4wYVc1amRDQm1jbTl0SUdCaGJHeGdJSE5wYm1ObElIUm9ZWFFnZDI5MWJHUWdjM1J2Y0Z4dUlDb2dkMkZwZEdsdVp5QmhkQ0IwYUdVZ1ptbHljM1FnY21WcVpXTjBhVzl1TGlBZ1ZHaGxJSEJ5YjIxcGMyVWdjbVYwZFhKdVpXUWdZbmxjYmlBcUlHQmhiR3hTWlhOdmJIWmxaR0FnZDJsc2JDQnVaWFpsY2lCaVpTQnlaV3BsWTNSbFpDNWNiaUFxSUVCd1lYSmhiU0J3Y205dGFYTmxjeUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlDaHZjaUJoYmlCaGNuSmhlU2tnYjJZZ2NISnZiV2x6WlhOY2JpQXFJQ2h2Y2lCMllXeDFaWE1wWEc0Z0tpQkFjbVYwZFhKdUlHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhOY2JpQXFMMXh1VVM1aGJHeFNaWE52YkhabFpDQTlJR1JsY0hKbFkyRjBaU2hoYkd4U1pYTnZiSFpsWkN3Z1hDSmhiR3hTWlhOdmJIWmxaRndpTENCY0ltRnNiRk5sZEhSc1pXUmNJaWs3WEc1bWRXNWpkR2x2YmlCaGJHeFNaWE52YkhabFpDaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NISnZiV2x6WlhNZ1BTQmhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJRkVwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZDJobGJpaGhiR3dvWVhKeVlYbGZiV0Z3S0hCeWIyMXBjMlZ6TENCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NISnZiV2x6WlN3Z2JtOXZjQ3dnYm05dmNDazdYRzRnSUNBZ0lDQWdJSDBwS1N3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlZ6TzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUtUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVlXeHNVbVZ6YjJ4MlpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJR0ZzYkZKbGMyOXNkbVZrS0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkFjMlZsSUZCeWIyMXBjMlVqWVd4c1UyVjBkR3hsWkZ4dUlDb3ZYRzVSTG1Gc2JGTmxkSFJzWldRZ1BTQmhiR3hUWlhSMGJHVmtPMXh1Wm5WdVkzUnBiMjRnWVd4c1UyVjBkR3hsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlZ6S1M1aGJHeFRaWFIwYkdWa0tDazdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1ZIVnlibk1nWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2FXNTBieUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlHOW1JSFJvWldseUlITjBZWFJsY3lBb1lYTmNiaUFxSUhKbGRIVnlibVZrSUdKNUlHQnBibk53WldOMFlDa2dkMmhsYmlCMGFHVjVJR2hoZG1VZ1lXeHNJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnZTBGeWNtRjVXMEZ1ZVNwZGZTQjJZV3gxWlhNZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nZTBGeWNtRjVXMU4wWVhSbFhYMGdZVzRnWVhKeVlYa2diMllnYzNSaGRHVnpJR1p2Y2lCMGFHVWdjbVZ6Y0dWamRHbDJaU0IyWVd4MVpYTXVYRzRnS2k5Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtRnNiRk5sZEhSc1pXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdGc2JDaGhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObElEMGdVU2h3Y205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlISmxaMkZ5Wkd4bGMzTW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVkR2hsYmloeVpXZGhjbVJzWlhOekxDQnlaV2RoY21Sc1pYTnpLVHRjYmlBZ0lDQWdJQ0FnZlNrcE8xeHVJQ0FnSUgwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRFlYQjBkWEpsY3lCMGFHVWdabUZwYkhWeVpTQnZaaUJoSUhCeWIyMXBjMlVzSUdkcGRtbHVaeUJoYmlCdmNHOXlkSFZ1YVhSNUlIUnZJSEpsWTI5MlpYSmNiaUFxSUhkcGRHZ2dZU0JqWVd4c1ltRmpheTRnSUVsbUlIUm9aU0JuYVhabGJpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQ3dnZEdobElISmxkSFZ5Ym1Wa1hHNGdLaUJ3Y205dGFYTmxJR2x6SUdaMWJHWnBiR3hsWkM1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCbWIzSWdjMjl0WlhSb2FXNW5YRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5Qm1kV3htYVd4c0lIUm9aU0J5WlhSMWNtNWxaQ0J3Y205dGFYTmxJR2xtSUhSb1pWeHVJQ29nWjJsMlpXNGdjSEp2YldselpTQnBjeUJ5WldwbFkzUmxaRnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJRzltSUhSb1pTQmpZV3hzWW1GamExeHVJQ292WEc1UkxtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVSVzF3aVkyRjBZMmhjSWwwZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWRHaGxiaWgyYjJsa0lEQXNJSEpsYW1WamRHVmtLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoYVd3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlZ0Y0ltTmhkR05vWENKZElEMGdablZ1WTNScGIyNGdLSEpsYW1WamRHVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYUjBZV05vWlhNZ1lTQnNhWE4wWlc1bGNpQjBhR0YwSUdOaGJpQnlaWE53YjI1a0lIUnZJSEJ5YjJkeVpYTnpJRzV2ZEdsbWFXTmhkR2x2Ym5NZ1puSnZiU0JoWEc0Z0tpQndjbTl0YVhObEozTWdiM0pwWjJsdVlYUnBibWNnWkdWbVpYSnlaV1F1SUZSb2FYTWdiR2x6ZEdWdVpYSWdjbVZqWldsMlpYTWdkR2hsSUdWNFlXTjBJR0Z5WjNWdFpXNTBjMXh1SUNvZ2NHRnpjMlZrSUhSdklHQmdaR1ZtWlhKeVpXUXVibTkwYVdaNVlHQXVYRzRnS2lCQWNHRnlZVzBnZTBGdWVTcDlJSEJ5YjIxcGMyVWdabTl5SUhOdmJXVjBhR2x1WjF4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dkRzhnY21WalpXbDJaU0JoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5Ym5NZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVc0lIVnVZMmhoYm1kbFpGeHVJQ292WEc1UkxuQnliMmR5WlhOeklEMGdjSEp2WjNKbGMzTTdYRzVtZFc1amRHbHZiaUJ3Y205bmNtVnpjeWh2WW1wbFkzUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMblJvWlc0b2RtOXBaQ0F3TENCMmIybGtJREFzSUhCeWIyZHlaWE56WldRcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1d2NtOW5jbVZ6Y3lBOUlHWjFibU4wYVc5dUlDaHdjbTluY21WemMyVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lIWnZhV1FnTUN3Z2NISnZaM0psYzNObFpDazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGQnliM1pwWkdWeklHRnVJRzl3Y0c5eWRIVnVhWFI1SUhSdklHOWljMlZ5ZG1VZ2RHaGxJSE5sZEhSc2FXNW5JRzltSUdFZ2NISnZiV2x6WlN4Y2JpQXFJSEpsWjJGeVpHeGxjM01nYjJZZ2QyaGxkR2hsY2lCMGFHVWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdUlDQkdiM0ozWVhKa2MxeHVJQ29nZEdobElISmxjMjlzZFhScGIyNGdkRzhnZEdobElISmxkSFZ5Ym1Wa0lIQnliMjFwYzJVZ2QyaGxiaUIwYUdVZ1kyRnNiR0poWTJzZ2FYTWdaRzl1WlM1Y2JpQXFJRlJvWlNCallXeHNZbUZqYXlCallXNGdjbVYwZFhKdUlHRWdjSEp2YldselpTQjBieUJrWldabGNpQmpiMjF3YkdWMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5QnZZbk5sY25abElIUm9aU0J5WlhOdmJIVjBhVzl1SUc5bUlIUm9aU0JuYVhabGJseHVJQ29nY0hKdmJXbHpaU3dnZEdGclpYTWdibThnWVhKbmRXMWxiblJ6TGx4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCM2FHVnVYRzRnS2lCZ1lHWnBibUJnSUdseklHUnZibVV1WEc0Z0tpOWNibEV1Wm1sdUlEMGdMeThnV0ZoWUlHeGxaMkZqZVZ4dVVWdGNJbVpwYm1Gc2JIbGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2xiWENKbWFXNWhiR3g1WENKZEtHTmhiR3hpWVdOcktUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWnBiaUE5SUM4dklGaFlXQ0JzWldkaFkzbGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxXMXdpWm1sdVlXeHNlVndpWFNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5a2dlMXh1SUNBZ0lHTmhiR3hpWVdOcklEMGdVU2hqWVd4c1ltRmpheWs3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJQ2h5WldGemIyNHBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZFOUVUeUJoZEhSbGJYQjBJSFJ2SUhKbFkzbGpiR1VnZEdobElISmxhbVZqZEdsdmJpQjNhWFJvSUZ3aWRHaHBjMXdpTGx4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGc2JHSmhZMnN1Wm1OaGJHd29LUzUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUhKbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSbGNtMXBibUYwWlhNZ1lTQmphR0ZwYmlCdlppQndjbTl0YVhObGN5d2dabTl5WTJsdVp5QnlaV3BsWTNScGIyNXpJSFJ2SUdKbFhHNGdLaUIwYUhKdmQyNGdZWE1nWlhoalpYQjBhVzl1Y3k1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCaGRDQjBhR1VnWlc1a0lHOW1JR0VnWTJoaGFXNGdiMllnY0hKdmJXbHpaWE5jYmlBcUlFQnlaWFIxY201eklHNXZkR2hwYm1kY2JpQXFMMXh1VVM1a2IyNWxJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkN3Z2NISnZaM0psYzNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1SdmJtVW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wkc5dVpTQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUhaaGNpQnZibFZ1YUdGdVpHeGxaRVZ5Y205eUlEMGdablZ1WTNScGIyNGdLR1Z5Y205eUtTQjdYRzRnSUNBZ0lDQWdJQzh2SUdadmNuZGhjbVFnZEc4Z1lTQm1kWFIxY21VZ2RIVnliaUJ6YnlCMGFHRjBJR0JnZDJobGJtQmdYRzRnSUNBZ0lDQWdJQzh2SUdSdlpYTWdibTkwSUdOaGRHTm9JR2wwSUdGdVpDQjBkWEp1SUdsMElHbHVkRzhnWVNCeVpXcGxZM1JwYjI0dVhHNGdJQ0FnSUNBZ0lGRXVibVY0ZEZScFkyc29ablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Z5Y205eUxDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaFJMbTl1WlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JSTG05dVpYSnliM0lvWlhKeWIzSXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsY25KdmNqdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJRUYyYjJsa0lIVnVibVZqWlhOellYSjVJR0J1WlhoMFZHbGphMkJwYm1jZ2RtbGhJR0Z1SUhWdWJtVmpaWE56WVhKNUlHQjNhR1Z1WUM1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHWjFiR1pwYkd4bFpDQjhmQ0J5WldwbFkzUmxaQ0I4ZkNCd2NtOW5jbVZ6Y3lBL1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnT2x4dUlDQWdJQ0FnSUNCMGFHbHpPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1JSEJ5YjJObGMzTWdKaVlnY0hKdlkyVnpjeTVrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnYjI1VmJtaGhibVJzWldSRmNuSnZjaUE5SUhCeWIyTmxjM011Wkc5dFlXbHVMbUpwYm1Rb2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtIWnZhV1FnTUN3Z2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVOaGRYTmxjeUJoSUhCeWIyMXBjMlVnZEc4Z1ltVWdjbVZxWldOMFpXUWdhV1lnYVhRZ1pHOWxjeUJ1YjNRZ1oyVjBJR1oxYkdacGJHeGxaQ0JpWldadmNtVmNiaUFxSUhOdmJXVWdiV2xzYkdselpXTnZibVJ6SUhScGJXVWdiM1YwTGx4dUlDb2dRSEJoY21GdElIdEJibmtxZlNCd2NtOXRhWE5sWEc0Z0tpQkFjR0Z5WVcwZ2UwNTFiV0psY24wZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldWdmRYUmNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdZM1Z6ZEc5dElHVnljbTl5SUcxbGMzTmhaMlVnYjNJZ1JYSnliM0lnYjJKcVpXTjBJQ2h2Y0hScGIyNWhiQ2xjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElISmxjMjlzZFhScGIyNGdiMllnZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVnYVdZZ2FYUWdhWE5jYmlBcUlHWjFiR1pwYkd4bFpDQmlaV1p2Y21VZ2RHaGxJSFJwYldWdmRYUXNJRzkwYUdWeWQybHpaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYlhNc0lHVnljbTl5S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzUwYVcxbGIzVjBLRzF6TENCbGNuSnZjaWs3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0cxekxDQmxjbkp2Y2lrZ2UxeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUkpaQ0E5SUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb0lXVnljbTl5SUh4OElGd2ljM1J5YVc1blhDSWdQVDA5SUhSNWNHVnZaaUJsY25KdmNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pYSnliM0lnUFNCdVpYY2dSWEp5YjNJb1pYSnliM0lnZkh3Z1hDSlVhVzFsWkNCdmRYUWdZV1owWlhJZ1hDSWdLeUJ0Y3lBcklGd2lJRzF6WENJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSXVZMjlrWlNBOUlGd2lSVlJKVFVWRVQxVlVYQ0k3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wS0dWeWNtOXlLVHRjYmlBZ0lDQjlMQ0J0Y3lrN1hHNWNiaUFnSUNCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5TENCa1pXWmxjbkpsWkM1dWIzUnBabmtwTzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1oybDJaVzRnZG1Gc2RXVWdLRzl5SUhCeWIyMXBjMlZrSUhaaGJIVmxLU3dnYzI5dFpWeHVJQ29nYldsc2JHbHpaV052Ym1SeklHRm1kR1Z5SUdsMElISmxjMjlzZG1Wa0xpQlFZWE56WlhNZ2NtVnFaV04wYVc5dWN5QnBiVzFsWkdsaGRHVnNlUzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaVnh1SUNvZ1FIQmhjbUZ0SUh0T2RXMWlaWEo5SUcxcGJHeHBjMlZqYjI1a2MxeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WemIyeDFkR2x2YmlCdlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQmhablJsY2lCdGFXeHNhWE5sWTI5dVpITmNiaUFxSUhScGJXVWdhR0Z6SUdWc1lYQnpaV1FnYzJsdVkyVWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVXVYRzRnS2lCSlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQnlaV3BsWTNSekxDQjBhR0YwSUdseklIQmhjM05sWkNCcGJXMWxaR2xoZEdWc2VTNWNiaUFxTDF4dVVTNWtaV3hoZVNBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCcFppQW9kR2x0Wlc5MWRDQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUhScGJXVnZkWFFnUFNCdlltcGxZM1E3WEc0Z0lDQWdJQ0FnSUc5aWFtVmpkQ0E5SUhadmFXUWdNRHRjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a1pXeGhlU2gwYVcxbGIzVjBLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYkdGNUlEMGdablZ1WTNScGIyNGdLSFJwYldWdmRYUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCelpYUlVhVzFsYjNWMEtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOUxDQjBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCaGMzTmxjeUJoSUdOdmJuUnBiblZoZEdsdmJpQjBieUJoSUU1dlpHVWdablZ1WTNScGIyNHNJSGRvYVdOb0lHbHpJR05oYkd4bFpDQjNhWFJvSUhSb1pTQm5hWFpsYmx4dUlDb2dZWEpuZFcxbGJuUnpJSEJ5YjNacFpHVmtJR0Z6SUdGdUlHRnljbUY1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dJQ0FnSUNCUkxtNW1ZWEJ3Ykhrb1JsTXVjbVZoWkVacGJHVXNJRnRmWDJacGJHVnVZVzFsWFNsY2JpQXFJQ0FnSUNBZ0xuUm9aVzRvWm5WdVkzUnBiMjRnS0dOdmJuUmxiblFwSUh0Y2JpQXFJQ0FnSUNBZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXl3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmhjSEJzZVNBOUlHWjFibU4wYVc5dUlDaGhjbWR6S1NCN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZHpLVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnZEdocGN5NW1ZWEJ3Ykhrb2JtOWtaVUZ5WjNNcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVUdGemMyVnpJR0VnWTI5dWRHbHVkV0YwYVc5dUlIUnZJR0VnVG05a1pTQm1kVzVqZEdsdmJpd2dkMmhwWTJnZ2FYTWdZMkZzYkdWa0lIZHBkR2dnZEdobElHZHBkbVZ1WEc0Z0tpQmhjbWQxYldWdWRITWdjSEp2ZG1sa1pXUWdhVzVrYVhacFpIVmhiR3g1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dVUzV1Wm1OaGJHd29SbE11Y21WaFpFWnBiR1VzSUY5ZlptbHNaVzVoYldVcFhHNGdLaUF1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZMjl1ZEdWdWRDa2dlMXh1SUNvZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05ySUM4cUxpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhKbGRIVnliaUJSS0dOaGJHeGlZV05yS1M1dVptRndjR3g1S0dGeVozTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHNXZaR1ZCY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1aaGNIQnNlU2h1YjJSbFFYSm5jeWt1Wm1GcGJDaGtaV1psY25KbFpDNXlaV3BsWTNRcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhjbUZ3Y3lCaElFNXZaR1ZLVXlCamIyNTBhVzUxWVhScGIyNGdjR0Z6YzJsdVp5Qm1kVzVqZEdsdmJpQmhibVFnY21WMGRYSnVjeUJoYmlCbGNYVnBkbUZzWlc1MFhHNGdLaUIyWlhKemFXOXVJSFJvWVhRZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabUpwYm1Rb1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwS0Z3aWRYUm1MVGhjSWlsY2JpQXFJQzUwYUdWdUtHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0xtUnZibVVvS1Z4dUlDb3ZYRzVSTG01bVltbHVaQ0E5WEc1UkxtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheUF2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01TazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lGRW9ZMkZzYkdKaFkyc3BMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVppYVc1a0lEMWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYm05a1pXbG1lU0E5SUdaMWJtTjBhVzl1SUNndktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0JoY21kekxuVnVjMmhwWm5Rb2RHaHBjeWs3WEc0Z0lDQWdjbVYwZFhKdUlGRXVaR1Z1YjJSbGFXWjVMbUZ3Y0d4NUtIWnZhV1FnTUN3Z1lYSm5jeWs3WEc1OU8xeHVYRzVSTG01aWFXNWtJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05yTENCMGFHbHpjQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHSnZkVzVrS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtIUm9hWE53TENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJRkVvWW05MWJtUXBMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibUpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9MeXAwYUdsemNDd2dMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUdGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lEQXBPMXh1SUNBZ0lHRnlaM011ZFc1emFHbG1kQ2gwYUdsektUdGNiaUFnSUNCeVpYUjFjbTRnVVM1dVltbHVaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnlaM01wTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVd4c2N5QmhJRzFsZEdodlpDQnZaaUJoSUU1dlpHVXRjM1I1YkdVZ2IySnFaV04wSUhSb1lYUWdZV05qWlhCMGN5QmhJRTV2WkdVdGMzUjViR1ZjYmlBcUlHTmhiR3hpWVdOcklIZHBkR2dnWVNCbmFYWmxiaUJoY25KaGVTQnZaaUJoY21kMWJXVnVkSE1zSUhCc2RYTWdZU0J3Y205MmFXUmxaQ0JqWVd4c1ltRmpheTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUdGeVozTWdZWEpuZFcxbGJuUnpJSFJ2SUhCaGMzTWdkRzhnZEdobElHMWxkR2h2WkRzZ2RHaGxJR05oYkd4aVlXTnJYRzRnS2lCM2FXeHNJR0psSUhCeWIzWnBaR1ZrSUdKNUlGRWdZVzVrSUdGd2NHVnVaR1ZrSUhSdklIUm9aWE5sSUdGeVozVnRaVzUwY3k1Y2JpQXFJRUJ5WlhSMWNtNXpJR0VnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSFpoYkhWbElHOXlJR1Z5Y205eVhHNGdLaTljYmxFdWJtMWhjSEJzZVNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VibkJ2YzNRb2JtRnRaU3dnWVhKbmN5azdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21keklIeDhJRnRkS1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklHRWdiV1YwYUc5a0lHOW1JR0VnVG05a1pTMXpkSGxzWlNCdlltcGxZM1FnZEdoaGRDQmhZMk5sY0hSeklHRWdUbTlrWlMxemRIbHNaVnh1SUNvZ1kyRnNiR0poWTJzc0lHWnZjbmRoY21ScGJtY2dkR2hsSUdkcGRtVnVJSFpoY21saFpHbGpJR0Z5WjNWdFpXNTBjeXdnY0d4MWN5QmhJSEJ5YjNacFpHVmtYRzRnS2lCallXeHNZbUZqYXlCaGNtZDFiV1Z1ZEM1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ1lXNGdiMkpxWldOMElIUm9ZWFFnYUdGeklIUm9aU0J1WVcxbFpDQnRaWFJvYjJSY2JpQXFJRUJ3WVhKaGJTQjdVM1J5YVc1bmZTQnVZVzFsSUc1aGJXVWdiMllnZEdobElHMWxkR2h2WkNCdlppQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklHRnlaM1Z0Wlc1MGN5QjBieUJ3WVhOeklIUnZJSFJvWlNCdFpYUm9iMlE3SUhSb1pTQmpZV3hzWW1GamF5QjNhV3hzWEc0Z0tpQmlaU0J3Y205MmFXUmxaQ0JpZVNCUklHRnVaQ0JoY0hCbGJtUmxaQ0IwYnlCMGFHVnpaU0JoY21kMWJXVnVkSE11WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQjJZV3gxWlNCdmNpQmxjbkp2Y2x4dUlDb3ZYRzVSTG01elpXNWtJRDBnTHk4Z1dGaFlJRUpoYzJWa0lHOXVJRTFoY21zZ1RXbHNiR1Z5SjNNZ2NISnZjRzl6WldRZ1hDSnpaVzVrWENKY2JsRXVibTFqWVd4c0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlGd2lVbVZrYzJGdVpISnZKM05jSWlCd2NtOXdiM05oYkZ4dVVTNXVhVzUyYjJ0bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJ1YjJSbFFYSm5jeUE5SUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNaWs3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0J1YjJSbFFYSm5jeTV3ZFhOb0tHUmxabVZ5Y21Wa0xtMWhhMlZPYjJSbFVtVnpiMngyWlhJb0tTazdYRzRnSUNBZ1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z2JtOWtaVUZ5WjNOZEtTNW1ZV2xzS0dSbFptVnljbVZrTG5KbGFtVmpkQ2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWMyVnVaQ0E5SUM4dklGaFlXQ0JDWVhObFpDQnZiaUJOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lGd2ljMlZ1WkZ3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV05oYkd3Z1BTQXZMeUJZV0ZnZ1FtRnpaV1FnYjI0Z1hDSlNaV1J6WVc1a2NtOG5jMXdpSUhCeWIzQnZjMkZzWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VnTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUdSbFptVnlLQ2s3WEc0Z0lDQWdibTlrWlVGeVozTXVjSFZ6YUNoa1pXWmxjbkpsWkM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5S0NrcE8xeHVJQ0FnSUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0p3YjNOMFhDSXNJRnR1WVcxbExDQnViMlJsUVhKbmMxMHBMbVpoYVd3b1pHVm1aWEp5WldRdWNtVnFaV04wS1R0Y2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdZU0JtZFc1amRHbHZiaUIzYjNWc1pDQnNhV3RsSUhSdklITjFjSEJ2Y25RZ1ltOTBhQ0JPYjJSbElHTnZiblJwYm5WaGRHbHZiaTF3WVhOemFXNW5MWE4wZVd4bElHRnVaRnh1SUNvZ2NISnZiV2x6WlMxeVpYUjFjbTVwYm1jdGMzUjViR1VzSUdsMElHTmhiaUJsYm1RZ2FYUnpJR2x1ZEdWeWJtRnNJSEJ5YjIxcGMyVWdZMmhoYVc0Z2QybDBhRnh1SUNvZ1lHNXZaR1ZwWm5rb2JtOWtaV0poWTJzcFlDd2dabTl5ZDJGeVpHbHVaeUIwYUdVZ2IzQjBhVzl1WVd3Z2JtOWtaV0poWTJzZ1lYSm5kVzFsYm5RdUlDQkpaaUIwYUdVZ2RYTmxjbHh1SUNvZ1pXeGxZM1J6SUhSdklIVnpaU0JoSUc1dlpHVmlZV05yTENCMGFHVWdjbVZ6ZFd4MElIZHBiR3dnWW1VZ2MyVnVkQ0IwYUdWeVpTNGdJRWxtSUhSb1pYa2daRzhnYm05MFhHNGdLaUJ3WVhOeklHRWdibTlrWldKaFkyc3NJSFJvWlhrZ2QybHNiQ0J5WldObGFYWmxJSFJvWlNCeVpYTjFiSFFnY0hKdmJXbHpaUzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVNCeVpYTjFiSFFnS0c5eUlHRWdjSEp2YldselpTQm1iM0lnWVNCeVpYTjFiSFFwWEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQnViMlJsWW1GamF5QmhJRTV2WkdVdWFuTXRjM1I1YkdVZ1kyRnNiR0poWTJ0Y2JpQXFJRUJ5WlhSMWNtNXpJR1ZwZEdobGNpQjBhR1VnY0hKdmJXbHpaU0J2Y2lCdWIzUm9hVzVuWEc0Z0tpOWNibEV1Ym05a1pXbG1lU0E5SUc1dlpHVnBabms3WEc1bWRXNWpkR2x2YmlCdWIyUmxhV1o1S0c5aWFtVmpkQ3dnYm05a1pXSmhZMnNwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbTV2WkdWcFpua29ibTlrWldKaFkyc3BPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViMlJsYVdaNUlEMGdablZ1WTNScGIyNGdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdhV1lnS0c1dlpHVmlZV05yS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLRzUxYkd3c0lIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzU5TzF4dVhHNVJMbTV2UTI5dVpteHBZM1FnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvWENKUkxtNXZRMjl1Wm14cFkzUWdiMjVzZVNCM2IzSnJjeUIzYUdWdUlGRWdhWE1nZFhObFpDQmhjeUJoSUdkc2IySmhiRndpS1R0Y2JuMDdYRzVjYmk4dklFRnNiQ0JqYjJSbElHSmxabTl5WlNCMGFHbHpJSEJ2YVc1MElIZHBiR3dnWW1VZ1ptbHNkR1Z5WldRZ1puSnZiU0J6ZEdGamF5QjBjbUZqWlhNdVhHNTJZWElnY1VWdVpHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dVhHNXlaWFIxY200Z1VUdGNibHh1ZlNrN1hHNGlYWDA9IiwiXG4vKipcbiAqIFJlZHVjZSBgYXJyYCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFxuICpcbiAqIFRPRE86IGNvbWJhdGlibGUgZXJyb3IgaGFuZGxpbmc/XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIGZuLCBpbml0aWFsKXsgIFxuICB2YXIgaWR4ID0gMDtcbiAgdmFyIGxlbiA9IGFyci5sZW5ndGg7XG4gIHZhciBjdXJyID0gYXJndW1lbnRzLmxlbmd0aCA9PSAzXG4gICAgPyBpbml0aWFsXG4gICAgOiBhcnJbaWR4KytdO1xuXG4gIHdoaWxlIChpZHggPCBsZW4pIHtcbiAgICBjdXJyID0gZm4uY2FsbChudWxsLCBjdXJyLCBhcnJbaWR4XSwgKytpZHgsIGFycik7XG4gIH1cbiAgXG4gIHJldHVybiBjdXJyO1xufTsiLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG52YXIgcmVkdWNlID0gcmVxdWlyZSgncmVkdWNlJyk7XG5cbi8qKlxuICogUm9vdCByZWZlcmVuY2UgZm9yIGlmcmFtZXMuXG4gKi9cblxudmFyIHJvb3Q7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gQnJvd3NlciB3aW5kb3dcbiAgcm9vdCA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSB7IC8vIFdlYiBXb3JrZXJcbiAgcm9vdCA9IHNlbGY7XG59IGVsc2UgeyAvLyBPdGhlciBlbnZpcm9ubWVudHNcbiAgcm9vdCA9IHRoaXM7XG59XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIGhvc3Qgb2JqZWN0LFxuICogd2UgZG9uJ3Qgd2FudCB0byBzZXJpYWxpemUgdGhlc2UgOilcbiAqXG4gKiBUT0RPOiBmdXR1cmUgcHJvb2YsIG1vdmUgdG8gY29tcG9lbnQgbGFuZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0hvc3Qob2JqKSB7XG4gIHZhciBzdHIgPSB7fS50b1N0cmluZy5jYWxsKG9iaik7XG5cbiAgc3dpdGNoIChzdHIpIHtcbiAgICBjYXNlICdbb2JqZWN0IEZpbGVdJzpcbiAgICBjYXNlICdbb2JqZWN0IEJsb2JdJzpcbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgYWRkZWQgdG8gc3VwcG9ydCBJRS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHRyaW0gPSAnJy50cmltXG4gID8gZnVuY3Rpb24ocykgeyByZXR1cm4gcy50cmltKCk7IH1cbiAgOiBmdW5jdGlvbihzKSB7IHJldHVybiBzLnJlcGxhY2UoLyheXFxzKnxcXHMqJCkvZywgJycpOyB9O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiBvYmogPT09IE9iamVjdChvYmopO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VyaWFsaXplKG9iaikge1xuICBpZiAoIWlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gIHZhciBwYWlycyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKG51bGwgIT0gb2JqW2tleV0pIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG4vKipcbiAqIEhlbHBzICdzZXJpYWxpemUnIHdpdGggc2VyaWFsaXppbmcgYXJyYXlzLlxuICogTXV0YXRlcyB0aGUgcGFpcnMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHZhbCkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgcmV0dXJuIHZhbC5mb3JFYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHYpO1xuICAgIH0pO1xuICB9XG4gIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSlcbiAgICArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudCh2YWwpKTtcbn1cblxuLyoqXG4gKiBFeHBvc2Ugc2VyaWFsaXphdGlvbiBtZXRob2QuXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplT2JqZWN0ID0gc2VyaWFsaXplO1xuXG4gLyoqXG4gICogUGFyc2UgdGhlIGdpdmVuIHgtd3d3LWZvcm0tdXJsZW5jb2RlZCBgc3RyYC5cbiAgKlxuICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICogQGFwaSBwcml2YXRlXG4gICovXG5cbmZ1bmN0aW9uIHBhcnNlU3RyaW5nKHN0cikge1xuICB2YXIgb2JqID0ge307XG4gIHZhciBwYWlycyA9IHN0ci5zcGxpdCgnJicpO1xuICB2YXIgcGFydHM7XG4gIHZhciBwYWlyO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwYXJ0cyA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFydHNbMV0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBFeHBvc2UgcGFyc2VyLlxuICovXG5cbnJlcXVlc3QucGFyc2VTdHJpbmcgPSBwYXJzZVN0cmluZztcblxuLyoqXG4gKiBEZWZhdWx0IE1JTUUgdHlwZSBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICovXG5cbnJlcXVlc3QudHlwZXMgPSB7XG4gIGh0bWw6ICd0ZXh0L2h0bWwnLFxuICBqc29uOiAnYXBwbGljYXRpb24vanNvbicsXG4gIHhtbDogJ2FwcGxpY2F0aW9uL3htbCcsXG4gIHVybGVuY29kZWQ6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAnZm9ybS1kYXRhJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzZXJpYWxpemF0aW9uIG1hcC5cbiAqXG4gKiAgICAgc3VwZXJhZ2VudC5zZXJpYWxpemVbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24ob2JqKXtcbiAqICAgICAgIHJldHVybiAnZ2VuZXJhdGVkIHhtbCBoZXJlJztcbiAqICAgICB9O1xuICpcbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemUgPSB7XG4gICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogc2VyaWFsaXplLFxuICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBKU09OLnN0cmluZ2lmeVxuIH07XG5cbiAvKipcbiAgKiBEZWZhdWx0IHBhcnNlcnMuXG4gICpcbiAgKiAgICAgc3VwZXJhZ2VudC5wYXJzZVsnYXBwbGljYXRpb24veG1sJ10gPSBmdW5jdGlvbihzdHIpe1xuICAqICAgICAgIHJldHVybiB7IG9iamVjdCBwYXJzZWQgZnJvbSBzdHIgfTtcbiAgKiAgICAgfTtcbiAgKlxuICAqL1xuXG5yZXF1ZXN0LnBhcnNlID0ge1xuICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJzogcGFyc2VTdHJpbmcsXG4gICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5wYXJzZVxufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gaGVhZGVyIGBzdHJgIGludG9cbiAqIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBtYXBwZWQgZmllbGRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVyKHN0cikge1xuICB2YXIgbGluZXMgPSBzdHIuc3BsaXQoL1xccj9cXG4vKTtcbiAgdmFyIGZpZWxkcyA9IHt9O1xuICB2YXIgaW5kZXg7XG4gIHZhciBsaW5lO1xuICB2YXIgZmllbGQ7XG4gIHZhciB2YWw7XG5cbiAgbGluZXMucG9wKCk7IC8vIHRyYWlsaW5nIENSTEZcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGluZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG4gICAgaW5kZXggPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBmaWVsZCA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpLnRvTG93ZXJDYXNlKCk7XG4gICAgdmFsID0gdHJpbShsaW5lLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgIGZpZWxkc1tmaWVsZF0gPSB2YWw7XG4gIH1cblxuICByZXR1cm4gZmllbGRzO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGBtaW1lYCBpcyBqc29uIG9yIGhhcyAranNvbiBzdHJ1Y3R1cmVkIHN5bnRheCBzdWZmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0pTT04obWltZSkge1xuICByZXR1cm4gL1tcXC8rXWpzb25cXGIvLnRlc3QobWltZSk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtaW1lIHR5cGUgZm9yIHRoZSBnaXZlbiBgc3RyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiB0eXBlKHN0cil7XG4gIHJldHVybiBzdHIuc3BsaXQoLyAqOyAqLykuc2hpZnQoKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhlYWRlciBmaWVsZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcmFtcyhzdHIpe1xuICByZXR1cm4gcmVkdWNlKHN0ci5zcGxpdCgvICo7ICovKSwgZnVuY3Rpb24ob2JqLCBzdHIpe1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvICo9ICovKVxuICAgICAgLCBrZXkgPSBwYXJ0cy5zaGlmdCgpXG4gICAgICAsIHZhbCA9IHBhcnRzLnNoaWZ0KCk7XG5cbiAgICBpZiAoa2V5ICYmIHZhbCkgb2JqW2tleV0gPSB2YWw7XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXNwb25zZWAgd2l0aCB0aGUgZ2l2ZW4gYHhocmAuXG4gKlxuICogIC0gc2V0IGZsYWdzICgub2ssIC5lcnJvciwgZXRjKVxuICogIC0gcGFyc2UgaGVhZGVyXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogIEFsaWFzaW5nIGBzdXBlcmFnZW50YCBhcyBgcmVxdWVzdGAgaXMgbmljZTpcbiAqXG4gKiAgICAgIHJlcXVlc3QgPSBzdXBlcmFnZW50O1xuICpcbiAqICBXZSBjYW4gdXNlIHRoZSBwcm9taXNlLWxpa2UgQVBJLCBvciBwYXNzIGNhbGxiYWNrczpcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJykuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvJywgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgU2VuZGluZyBkYXRhIGNhbiBiZSBjaGFpbmVkOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBPciBwYXNzZWQgdG8gYC5zZW5kKClgOlxuICpcbiAqICAgICAgcmVxdWVzdFxuICogICAgICAgIC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnBvc3QoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgLmVuZChmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqIE9yIGZ1cnRoZXIgcmVkdWNlZCB0byBhIHNpbmdsZSBjYWxsIGZvciBzaW1wbGUgY2FzZXM6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJywgeyBuYW1lOiAndGonIH0sIGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogQHBhcmFtIHtYTUxIVFRQUmVxdWVzdH0geGhyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUmVzcG9uc2UocmVxLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLnJlcSA9IHJlcTtcbiAgdGhpcy54aHIgPSB0aGlzLnJlcS54aHI7XG4gIC8vIHJlc3BvbnNlVGV4dCBpcyBhY2Nlc3NpYmxlIG9ubHkgaWYgcmVzcG9uc2VUeXBlIGlzICcnIG9yICd0ZXh0JyBhbmQgb24gb2xkZXIgYnJvd3NlcnNcbiAgdGhpcy50ZXh0ID0gKCh0aGlzLnJlcS5tZXRob2QgIT0nSEVBRCcgJiYgKHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9PT0gJycgfHwgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcpKSB8fCB0eXBlb2YgdGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAndW5kZWZpbmVkJylcbiAgICAgPyB0aGlzLnhoci5yZXNwb25zZVRleHRcbiAgICAgOiBudWxsO1xuICB0aGlzLnN0YXR1c1RleHQgPSB0aGlzLnJlcS54aHIuc3RhdHVzVGV4dDtcbiAgdGhpcy5zZXRTdGF0dXNQcm9wZXJ0aWVzKHRoaXMueGhyLnN0YXR1cyk7XG4gIHRoaXMuaGVhZGVyID0gdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXIodGhpcy54aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAvLyBnZXRBbGxSZXNwb25zZUhlYWRlcnMgc29tZXRpbWVzIGZhbHNlbHkgcmV0dXJucyBcIlwiIGZvciBDT1JTIHJlcXVlc3RzLCBidXRcbiAgLy8gZ2V0UmVzcG9uc2VIZWFkZXIgc3RpbGwgd29ya3MuIHNvIHdlIGdldCBjb250ZW50LXR5cGUgZXZlbiBpZiBnZXR0aW5nXG4gIC8vIG90aGVyIGhlYWRlcnMgZmFpbHMuXG4gIHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdjb250ZW50LXR5cGUnKTtcbiAgdGhpcy5zZXRIZWFkZXJQcm9wZXJ0aWVzKHRoaXMuaGVhZGVyKTtcbiAgdGhpcy5ib2R5ID0gdGhpcy5yZXEubWV0aG9kICE9ICdIRUFEJ1xuICAgID8gdGhpcy5wYXJzZUJvZHkodGhpcy50ZXh0ID8gdGhpcy50ZXh0IDogdGhpcy54aHIucmVzcG9uc2UpXG4gICAgOiBudWxsO1xufVxuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGBmaWVsZGAgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLmhlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogU2V0IGhlYWRlciByZWxhdGVkIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGAudHlwZWAgdGhlIGNvbnRlbnQgdHlwZSB3aXRob3V0IHBhcmFtc1xuICpcbiAqIEEgcmVzcG9uc2Ugb2YgXCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLThcIlxuICogd2lsbCBwcm92aWRlIHlvdSB3aXRoIGEgYC50eXBlYCBvZiBcInRleHQvcGxhaW5cIi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaGVhZGVyXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0SGVhZGVyUHJvcGVydGllcyA9IGZ1bmN0aW9uKGhlYWRlcil7XG4gIC8vIGNvbnRlbnQtdHlwZVxuICB2YXIgY3QgPSB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gfHwgJyc7XG4gIHRoaXMudHlwZSA9IHR5cGUoY3QpO1xuXG4gIC8vIHBhcmFtc1xuICB2YXIgb2JqID0gcGFyYW1zKGN0KTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikgdGhpc1trZXldID0gb2JqW2tleV07XG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBib2R5IGBzdHJgLlxuICpcbiAqIFVzZWQgZm9yIGF1dG8tcGFyc2luZyBvZiBib2RpZXMuIFBhcnNlcnNcbiAqIGFyZSBkZWZpbmVkIG9uIHRoZSBgc3VwZXJhZ2VudC5wYXJzZWAgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLnBhcnNlQm9keSA9IGZ1bmN0aW9uKHN0cil7XG4gIHZhciBwYXJzZSA9IHJlcXVlc3QucGFyc2VbdGhpcy50eXBlXTtcbiAgcmV0dXJuIHBhcnNlICYmIHN0ciAmJiAoc3RyLmxlbmd0aCB8fCBzdHIgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgPyBwYXJzZShzdHIpXG4gICAgOiBudWxsO1xufTtcblxuLyoqXG4gKiBTZXQgZmxhZ3Mgc3VjaCBhcyBgLm9rYCBiYXNlZCBvbiBgc3RhdHVzYC5cbiAqXG4gKiBGb3IgZXhhbXBsZSBhIDJ4eCByZXNwb25zZSB3aWxsIGdpdmUgeW91IGEgYC5va2Agb2YgX190cnVlX19cbiAqIHdoZXJlYXMgNXh4IHdpbGwgYmUgX19mYWxzZV9fIGFuZCBgLmVycm9yYCB3aWxsIGJlIF9fdHJ1ZV9fLiBUaGVcbiAqIGAuY2xpZW50RXJyb3JgIGFuZCBgLnNlcnZlckVycm9yYCBhcmUgYWxzbyBhdmFpbGFibGUgdG8gYmUgbW9yZVxuICogc3BlY2lmaWMsIGFuZCBgLnN0YXR1c1R5cGVgIGlzIHRoZSBjbGFzcyBvZiBlcnJvciByYW5naW5nIGZyb20gMS4uNVxuICogc29tZXRpbWVzIHVzZWZ1bCBmb3IgbWFwcGluZyByZXNwb25kIGNvbG9ycyBldGMuXG4gKlxuICogXCJzdWdhclwiIHByb3BlcnRpZXMgYXJlIGFsc28gZGVmaW5lZCBmb3IgY29tbW9uIGNhc2VzLiBDdXJyZW50bHkgcHJvdmlkaW5nOlxuICpcbiAqICAgLSAubm9Db250ZW50XG4gKiAgIC0gLmJhZFJlcXVlc3RcbiAqICAgLSAudW5hdXRob3JpemVkXG4gKiAgIC0gLm5vdEFjY2VwdGFibGVcbiAqICAgLSAubm90Rm91bmRcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhdHVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUuc2V0U3RhdHVzUHJvcGVydGllcyA9IGZ1bmN0aW9uKHN0YXR1cyl7XG4gIC8vIGhhbmRsZSBJRTkgYnVnOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgaWYgKHN0YXR1cyA9PT0gMTIyMykge1xuICAgIHN0YXR1cyA9IDIwNDtcbiAgfVxuXG4gIHZhciB0eXBlID0gc3RhdHVzIC8gMTAwIHwgMDtcblxuICAvLyBzdGF0dXMgLyBjbGFzc1xuICB0aGlzLnN0YXR1cyA9IHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1cztcbiAgdGhpcy5zdGF0dXNUeXBlID0gdHlwZTtcblxuICAvLyBiYXNpY3NcbiAgdGhpcy5pbmZvID0gMSA9PSB0eXBlO1xuICB0aGlzLm9rID0gMiA9PSB0eXBlO1xuICB0aGlzLmNsaWVudEVycm9yID0gNCA9PSB0eXBlO1xuICB0aGlzLnNlcnZlckVycm9yID0gNSA9PSB0eXBlO1xuICB0aGlzLmVycm9yID0gKDQgPT0gdHlwZSB8fCA1ID09IHR5cGUpXG4gICAgPyB0aGlzLnRvRXJyb3IoKVxuICAgIDogZmFsc2U7XG5cbiAgLy8gc3VnYXJcbiAgdGhpcy5hY2NlcHRlZCA9IDIwMiA9PSBzdGF0dXM7XG4gIHRoaXMubm9Db250ZW50ID0gMjA0ID09IHN0YXR1cztcbiAgdGhpcy5iYWRSZXF1ZXN0ID0gNDAwID09IHN0YXR1cztcbiAgdGhpcy51bmF1dGhvcml6ZWQgPSA0MDEgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEFjY2VwdGFibGUgPSA0MDYgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEZvdW5kID0gNDA0ID09IHN0YXR1cztcbiAgdGhpcy5mb3JiaWRkZW4gPSA0MDMgPT0gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYEVycm9yYCByZXByZXNlbnRhdGl2ZSBvZiB0aGlzIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm4ge0Vycm9yfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUudG9FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciByZXEgPSB0aGlzLnJlcTtcbiAgdmFyIG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gIHZhciB1cmwgPSByZXEudXJsO1xuXG4gIHZhciBtc2cgPSAnY2Fubm90ICcgKyBtZXRob2QgKyAnICcgKyB1cmwgKyAnICgnICsgdGhpcy5zdGF0dXMgKyAnKSc7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gbWV0aG9kO1xuICBlcnIudXJsID0gdXJsO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgUmVzcG9uc2VgLlxuICovXG5cbnJlcXVlc3QuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0YCB3aXRoIHRoZSBnaXZlbiBgbWV0aG9kYCBhbmQgYHVybGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgRW1pdHRlci5jYWxsKHRoaXMpO1xuICB0aGlzLl9xdWVyeSA9IHRoaXMuX3F1ZXJ5IHx8IFtdO1xuICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgdGhpcy51cmwgPSB1cmw7XG4gIHRoaXMuaGVhZGVyID0ge307XG4gIHRoaXMuX2hlYWRlciA9IHt9O1xuICB0aGlzLm9uKCdlbmQnLCBmdW5jdGlvbigpe1xuICAgIHZhciBlcnIgPSBudWxsO1xuICAgIHZhciByZXMgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IG5ldyBSZXNwb25zZShzZWxmKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIGVyciA9IG5ldyBFcnJvcignUGFyc2VyIGlzIHVuYWJsZSB0byBwYXJzZSB0aGUgcmVzcG9uc2UnKTtcbiAgICAgIGVyci5wYXJzZSA9IHRydWU7XG4gICAgICBlcnIub3JpZ2luYWwgPSBlO1xuICAgICAgLy8gaXNzdWUgIzY3NTogcmV0dXJuIHRoZSByYXcgcmVzcG9uc2UgaWYgdGhlIHJlc3BvbnNlIHBhcnNpbmcgZmFpbHNcbiAgICAgIGVyci5yYXdSZXNwb25zZSA9IHNlbGYueGhyICYmIHNlbGYueGhyLnJlc3BvbnNlVGV4dCA/IHNlbGYueGhyLnJlc3BvbnNlVGV4dCA6IG51bGw7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIpO1xuICAgIH1cblxuICAgIHNlbGYuZW1pdCgncmVzcG9uc2UnLCByZXMpO1xuXG4gICAgaWYgKGVycikge1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyLCByZXMpO1xuICAgIH1cblxuICAgIGlmIChyZXMuc3RhdHVzID49IDIwMCAmJiByZXMuc3RhdHVzIDwgMzAwKSB7XG4gICAgICByZXR1cm4gc2VsZi5jYWxsYmFjayhlcnIsIHJlcyk7XG4gICAgfVxuXG4gICAgdmFyIG5ld19lcnIgPSBuZXcgRXJyb3IocmVzLnN0YXR1c1RleHQgfHwgJ1Vuc3VjY2Vzc2Z1bCBIVFRQIHJlc3BvbnNlJyk7XG4gICAgbmV3X2Vyci5vcmlnaW5hbCA9IGVycjtcbiAgICBuZXdfZXJyLnJlc3BvbnNlID0gcmVzO1xuICAgIG5ld19lcnIuc3RhdHVzID0gcmVzLnN0YXR1cztcblxuICAgIHNlbGYuY2FsbGJhY2sobmV3X2VyciwgcmVzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogTWl4aW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEFsbG93IGZvciBleHRlbnNpb25cbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbihmbikge1xuICBmbih0aGlzKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24obXMpe1xuICB0aGlzLl90aW1lb3V0ID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDbGVhciBwcmV2aW91cyB0aW1lb3V0LlxuICpcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jbGVhclRpbWVvdXQgPSBmdW5jdGlvbigpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5hYm9ydGVkKSByZXR1cm47XG4gIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gIHRoaXMueGhyLmFib3J0KCk7XG4gIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gIHRoaXMuZW1pdCgnYWJvcnQnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBoZWFkZXIgYGZpZWxkYCB0byBgdmFsYCwgb3IgbXVsdGlwbGUgZmllbGRzIHdpdGggb25lIG9iamVjdC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJylcbiAqICAgICAgICAuc2V0KCdYLUFQSS1LZXknLCAnZm9vYmFyJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcS5nZXQoJy8nKVxuICogICAgICAgIC5zZXQoeyBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJywgJ1gtQVBJLUtleSc6ICdmb29iYXInIH0pXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBmaWVsZFxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWwpe1xuICBpZiAoaXNPYmplY3QoZmllbGQpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGZpZWxkKSB7XG4gICAgICB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV0gPSB2YWw7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBoZWFkZXIgYGZpZWxkYC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnVuc2V0KCdVc2VyLUFnZW50JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS51bnNldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgZGVsZXRlIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbiAgZGVsZXRlIHRoaXMuaGVhZGVyW2ZpZWxkXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyID0gZnVuY3Rpb24oZmllbGQpe1xuICByZXR1cm4gdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgQ29udGVudC1UeXBlIHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqICAgICAgcmVxdWVzdC5wb3N0KCcvJylcbiAqICAgICAgICAudHlwZSgneG1sJylcbiAqICAgICAgICAuc2VuZCh4bWxzdHJpbmcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCdhcHBsaWNhdGlvbi94bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnR5cGUgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0NvbnRlbnQtVHlwZScsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBGb3JjZSBnaXZlbiBwYXJzZXJcbiAqXG4gKiBTZXRzIHRoZSBib2R5IHBhcnNlciBubyBtYXR0ZXIgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKGZuKXtcbiAgdGhpcy5fcGFyc2VyID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQWNjZXB0IHRvIGB0eXBlYCwgbWFwcGluZyB2YWx1ZXMgZnJvbSBgcmVxdWVzdC50eXBlc2AuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICBzdXBlcmFnZW50LnR5cGVzLmpzb24gPSAnYXBwbGljYXRpb24vanNvbic7XG4gKlxuICogICAgICByZXF1ZXN0LmdldCgnL2FnZW50JylcbiAqICAgICAgICAuYWNjZXB0KCdqc29uJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2NlcHRcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbih0eXBlKXtcbiAgdGhpcy5zZXQoJ0FjY2VwdCcsIHJlcXVlc3QudHlwZXNbdHlwZV0gfHwgdHlwZSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgQXV0aG9yaXphdGlvbiBmaWVsZCB2YWx1ZSB3aXRoIGB1c2VyYCBhbmQgYHBhc3NgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFzc1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzKXtcbiAgdmFyIHN0ciA9IGJ0b2EodXNlciArICc6JyArIHBhc3MpO1xuICB0aGlzLnNldCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgc3RyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiogQWRkIHF1ZXJ5LXN0cmluZyBgdmFsYC5cbipcbiogRXhhbXBsZXM6XG4qXG4qICAgcmVxdWVzdC5nZXQoJy9zaG9lcycpXG4qICAgICAucXVlcnkoJ3NpemU9MTAnKVxuKiAgICAgLnF1ZXJ5KHsgY29sb3I6ICdibHVlJyB9KVxuKlxuKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZhbFxuKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiogQGFwaSBwdWJsaWNcbiovXG5cblJlcXVlc3QucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24odmFsKXtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiB2YWwpIHZhbCA9IHNlcmlhbGl6ZSh2YWwpO1xuICBpZiAodmFsKSB0aGlzLl9xdWVyeS5wdXNoKHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZSB0aGUgZmllbGQgYG5hbWVgIGFuZCBgdmFsYCBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJcbiAqIHJlcXVlc3QgYm9kaWVzLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmZpZWxkKCdmb28nLCAnYmFyJylcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd8QmxvYnxGaWxlfSB2YWxcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5maWVsZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbCl7XG4gIGlmICghdGhpcy5fZm9ybURhdGEpIHRoaXMuX2Zvcm1EYXRhID0gbmV3IHJvb3QuRm9ybURhdGEoKTtcbiAgdGhpcy5fZm9ybURhdGEuYXBwZW5kKG5hbWUsIHZhbCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBRdWV1ZSB0aGUgZ2l2ZW4gYGZpbGVgIGFzIGFuIGF0dGFjaG1lbnQgdG8gdGhlIHNwZWNpZmllZCBgZmllbGRgLFxuICogd2l0aCBvcHRpb25hbCBgZmlsZW5hbWVgLlxuICpcbiAqIGBgYCBqc1xuICogcmVxdWVzdC5wb3N0KCcvdXBsb2FkJylcbiAqICAgLmF0dGFjaChuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB0aGlzLl9mb3JtRGF0YSA9IG5ldyByb290LkZvcm1EYXRhKCk7XG4gIHRoaXMuX2Zvcm1EYXRhLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUgfHwgZmlsZS5uYW1lKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmQgYGRhdGFgIGFzIHRoZSByZXF1ZXN0IGJvZHksIGRlZmF1bHRpbmcgdGhlIGAudHlwZSgpYCB0byBcImpzb25cIiB3aGVuXG4gKiBhbiBvYmplY3QgaXMgZ2l2ZW4uXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAgLy8gbWFudWFsIGpzb25cbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnanNvbicpXG4gKiAgICAgICAgIC5zZW5kKCd7XCJuYW1lXCI6XCJ0alwifScpXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gYXV0byBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gbWFudWFsIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoJ25hbWU9dGonKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2Zvcm0nKVxuICogICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBkZWZhdWx0cyB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICAqICAgICAgICAuc2VuZCgnbmFtZT10b2JpJylcbiAgKiAgICAgICAgLnNlbmQoJ3NwZWNpZXM9ZmVycmV0JylcbiAgKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBvYmogPSBpc09iamVjdChkYXRhKTtcbiAgdmFyIHR5cGUgPSB0aGlzLmdldEhlYWRlcignQ29udGVudC1UeXBlJyk7XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2Zvcm0nKTtcbiAgICB0eXBlID0gdGhpcy5nZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScpO1xuICAgIGlmICgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyA9PSB0eXBlKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy5fZGF0YVxuICAgICAgICA/IHRoaXMuX2RhdGEgKyAnJicgKyBkYXRhXG4gICAgICAgIDogZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0YSA9ICh0aGlzLl9kYXRhIHx8ICcnKSArIGRhdGE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG5cbiAgaWYgKCFvYmogfHwgaXNIb3N0KGRhdGEpKSByZXR1cm4gdGhpcztcbiAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2pzb24nKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCBgZXJyYCBhbmQgYHJlc2BcbiAqIGFuZCBoYW5kbGUgYXJpdHkgY2hlY2suXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNhbGxiYWNrID0gZnVuY3Rpb24oZXJyLCByZXMpe1xuICB2YXIgZm4gPSB0aGlzLl9jYWxsYmFjaztcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgZm4oZXJyLCByZXMpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB4LWRvbWFpbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcm9zc0RvbWFpbkVycm9yID0gZnVuY3Rpb24oKXtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcignUmVxdWVzdCBoYXMgYmVlbiB0ZXJtaW5hdGVkXFxuUG9zc2libGUgY2F1c2VzOiB0aGUgbmV0d29yayBpcyBvZmZsaW5lLCBPcmlnaW4gaXMgbm90IGFsbG93ZWQgYnkgQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luLCB0aGUgcGFnZSBpcyBiZWluZyB1bmxvYWRlZCwgZXRjLicpO1xuICBlcnIuY3Jvc3NEb21haW4gPSB0cnVlO1xuXG4gIGVyci5zdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgZXJyLm1ldGhvZCA9IHRoaXMubWV0aG9kO1xuICBlcnIudXJsID0gdGhpcy51cmw7XG5cbiAgdGhpcy5jYWxsYmFjayhlcnIpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB0aW1lb3V0IGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnRpbWVvdXRFcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcigndGltZW91dCBvZiAnICsgdGltZW91dCArICdtcyBleGNlZWRlZCcpO1xuICBlcnIudGltZW91dCA9IHRpbWVvdXQ7XG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogRW5hYmxlIHRyYW5zbWlzc2lvbiBvZiBjb29raWVzIHdpdGggeC1kb21haW4gcmVxdWVzdHMuXG4gKlxuICogTm90ZSB0aGF0IGZvciB0aGlzIHRvIHdvcmsgdGhlIG9yaWdpbiBtdXN0IG5vdCBiZVxuICogdXNpbmcgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW5cIiB3aXRoIGEgd2lsZGNhcmQsXG4gKiBhbmQgYWxzbyBtdXN0IHNldCBcIkFjY2Vzcy1Db250cm9sLUFsbG93LUNyZWRlbnRpYWxzXCJcbiAqIHRvIFwidHJ1ZVwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUud2l0aENyZWRlbnRpYWxzID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5fd2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEluaXRpYXRlIHJlcXVlc3QsIGludm9raW5nIGNhbGxiYWNrIGBmbihyZXMpYFxuICogd2l0aCBhbiBpbnN0YW5jZW9mIGBSZXNwb25zZWAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihmbil7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHhociA9IHRoaXMueGhyID0gcmVxdWVzdC5nZXRYSFIoKTtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7XG4gIHZhciBkYXRhID0gdGhpcy5fZm9ybURhdGEgfHwgdGhpcy5fZGF0YTtcblxuICAvLyBzdG9yZSBjYWxsYmFja1xuICB0aGlzLl9jYWxsYmFjayA9IGZuIHx8IG5vb3A7XG5cbiAgLy8gc3RhdGUgY2hhbmdlXG4gIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xuICAgIGlmICg0ICE9IHhoci5yZWFkeVN0YXRlKSByZXR1cm47XG5cbiAgICAvLyBJbiBJRTksIHJlYWRzIHRvIGFueSBwcm9wZXJ0eSAoZS5nLiBzdGF0dXMpIG9mZiBvZiBhbiBhYm9ydGVkIFhIUiB3aWxsXG4gICAgLy8gcmVzdWx0IGluIHRoZSBlcnJvciBcIkNvdWxkIG5vdCBjb21wbGV0ZSB0aGUgb3BlcmF0aW9uIGR1ZSB0byBlcnJvciBjMDBjMDIzZlwiXG4gICAgdmFyIHN0YXR1cztcbiAgICB0cnkgeyBzdGF0dXMgPSB4aHIuc3RhdHVzIH0gY2F0Y2goZSkgeyBzdGF0dXMgPSAwOyB9XG5cbiAgICBpZiAoMCA9PSBzdGF0dXMpIHtcbiAgICAgIGlmIChzZWxmLnRpbWVkb3V0KSByZXR1cm4gc2VsZi50aW1lb3V0RXJyb3IoKTtcbiAgICAgIGlmIChzZWxmLmFib3J0ZWQpIHJldHVybjtcbiAgICAgIHJldHVybiBzZWxmLmNyb3NzRG9tYWluRXJyb3IoKTtcbiAgICB9XG4gICAgc2VsZi5lbWl0KCdlbmQnKTtcbiAgfTtcblxuICAvLyBwcm9ncmVzc1xuICB2YXIgaGFuZGxlUHJvZ3Jlc3MgPSBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS50b3RhbCA+IDApIHtcbiAgICAgIGUucGVyY2VudCA9IGUubG9hZGVkIC8gZS50b3RhbCAqIDEwMDtcbiAgICB9XG4gICAgZS5kaXJlY3Rpb24gPSAnZG93bmxvYWQnO1xuICAgIHNlbGYuZW1pdCgncHJvZ3Jlc3MnLCBlKTtcbiAgfTtcbiAgaWYgKHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgfVxuICB0cnkge1xuICAgIGlmICh4aHIudXBsb2FkICYmIHRoaXMuaGFzTGlzdGVuZXJzKCdwcm9ncmVzcycpKSB7XG4gICAgICB4aHIudXBsb2FkLm9ucHJvZ3Jlc3MgPSBoYW5kbGVQcm9ncmVzcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge1xuICAgIC8vIEFjY2Vzc2luZyB4aHIudXBsb2FkIGZhaWxzIGluIElFIGZyb20gYSB3ZWIgd29ya2VyLCBzbyBqdXN0IHByZXRlbmQgaXQgZG9lc24ndCBleGlzdC5cbiAgICAvLyBSZXBvcnRlZCBoZXJlOlxuICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODM3MjQ1L3htbGh0dHByZXF1ZXN0LXVwbG9hZC10aHJvd3MtaW52YWxpZC1hcmd1bWVudC13aGVuLXVzZWQtZnJvbS13ZWItd29ya2VyLWNvbnRleHRcbiAgfVxuXG4gIC8vIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgJiYgIXRoaXMuX3RpbWVyKSB7XG4gICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLnRpbWVkb3V0ID0gdHJ1ZTtcbiAgICAgIHNlbGYuYWJvcnQoKTtcbiAgICB9LCB0aW1lb3V0KTtcbiAgfVxuXG4gIC8vIHF1ZXJ5c3RyaW5nXG4gIGlmIChxdWVyeSkge1xuICAgIHF1ZXJ5ID0gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QocXVlcnkpO1xuICAgIHRoaXMudXJsICs9IH50aGlzLnVybC5pbmRleE9mKCc/JylcbiAgICAgID8gJyYnICsgcXVlcnlcbiAgICAgIDogJz8nICsgcXVlcnk7XG4gIH1cblxuICAvLyBpbml0aWF0ZSByZXF1ZXN0XG4gIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVybCwgdHJ1ZSk7XG5cbiAgLy8gQ09SU1xuICBpZiAodGhpcy5fd2l0aENyZWRlbnRpYWxzKSB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblxuICAvLyBib2R5XG4gIGlmICgnR0VUJyAhPSB0aGlzLm1ldGhvZCAmJiAnSEVBRCcgIT0gdGhpcy5tZXRob2QgJiYgJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgJiYgIWlzSG9zdChkYXRhKSkge1xuICAgIC8vIHNlcmlhbGl6ZSBzdHVmZlxuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnKTtcbiAgICB2YXIgc2VyaWFsaXplID0gdGhpcy5fcGFyc2VyIHx8IHJlcXVlc3Quc2VyaWFsaXplW2NvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKVswXSA6ICcnXTtcbiAgICBpZiAoIXNlcmlhbGl6ZSAmJiBpc0pTT04oY29udGVudFR5cGUpKSBzZXJpYWxpemUgPSByZXF1ZXN0LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIGlmIChzZXJpYWxpemUpIGRhdGEgPSBzZXJpYWxpemUoZGF0YSk7XG4gIH1cblxuICAvLyBzZXQgaGVhZGVyIGZpZWxkc1xuICBmb3IgKHZhciBmaWVsZCBpbiB0aGlzLmhlYWRlcikge1xuICAgIGlmIChudWxsID09IHRoaXMuaGVhZGVyW2ZpZWxkXSkgY29udGludWU7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoZmllbGQsIHRoaXMuaGVhZGVyW2ZpZWxkXSk7XG4gIH1cblxuICAvLyBzZW5kIHN0dWZmXG4gIHRoaXMuZW1pdCgncmVxdWVzdCcsIHRoaXMpO1xuXG4gIC8vIElFMTEgeGhyLnNlbmQodW5kZWZpbmVkKSBzZW5kcyAndW5kZWZpbmVkJyBzdHJpbmcgYXMgUE9TVCBwYXlsb2FkIChpbnN0ZWFkIG9mIG5vdGhpbmcpXG4gIC8vIFdlIG5lZWQgbnVsbCBoZXJlIGlmIGRhdGEgaXMgdW5kZWZpbmVkXG4gIHhoci5zZW5kKHR5cGVvZiBkYXRhICE9PSAndW5kZWZpbmVkJyA/IGRhdGEgOiBudWxsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZhdXggcHJvbWlzZSBzdXBwb3J0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVsZmlsbFxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVqZWN0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbiAoZnVsZmlsbCwgcmVqZWN0KSB7XG4gIHJldHVybiB0aGlzLmVuZChmdW5jdGlvbihlcnIsIHJlcykge1xuICAgIGVyciA/IHJlamVjdChlcnIpIDogZnVsZmlsbChyZXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIC8vIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1cmwpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3QoJ0dFVCcsIG1ldGhvZCkuZW5kKHVybCk7XG4gIH1cblxuICAvLyB1cmwgZmlyc3RcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdCgnR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdChtZXRob2QsIHVybCk7XG59XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LmdldCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnR0VUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEucXVlcnkoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIEhFQUQgYHVybGAgd2l0aCBvcHRpb25hbCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZHxGdW5jdGlvbn0gZGF0YSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QuaGVhZCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnSEVBRCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVsKHVybCwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnREVMRVRFJywgdXJsKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbnJlcXVlc3RbJ2RlbCddID0gZGVsO1xucmVxdWVzdFsnZGVsZXRlJ10gPSBkZWw7XG5cbi8qKlxuICogUEFUQ0ggYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfSBkYXRhXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wYXRjaCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUEFUQ0gnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQT1NUIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucG9zdCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUE9TVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIFBVVCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IGRhdGEgb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnB1dCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUFVUJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogRXhwb3NlIGByZXF1ZXN0YC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG4iXX0=
+
+ /*global JSONEditor*/
+'use strict';
+
+window.SwaggerUi = Backbone.Router.extend({
+
+  dom_id: 'swagger_ui',
+
+  // Attributes
+  options: null,
+  api: null,
+  headerView: null,
+  mainView: null,
+
+  // SwaggerUi accepts all the same options as SwaggerApi
+  initialize: function(options) {
+    options = options || {};
+
+    if (options.defaultModelRendering !== 'model') {
+      options.defaultModelRendering = 'schema';
+    }
+
+    if (!options.highlightSizeThreshold) {
+      options.highlightSizeThreshold = 100000;
+    }
+
+    // Allow dom_id to be overridden
+    if (options.dom_id) {
+      this.dom_id = options.dom_id;
+      delete options.dom_id;
+    }
+
+    if (!options.supportedSubmitMethods){
+      options.supportedSubmitMethods = [
+        'get',
+        'put',
+        'post',
+        'delete',
+        'head',
+        'options',
+        'patch'
+      ];
+    }
+
+    if (typeof options.oauth2RedirectUrl === 'string') {
+      window.oAuthRedirectUrl = options.redirectUrl;
+    }
+
+    // Create an empty div which contains the dom_id
+    if (! $('#' + this.dom_id).length){
+      $('body').append('<div id="' + this.dom_id + '"></div>') ;
+    }
+
+    this.options = options;
+
+    // set marked options
+    marked.setOptions({gfm: true});
+
+    // Set the callbacks
+    var that = this;
+    this.options.success = function() { return that.render(); };
+    this.options.progress = function(d) { return that.showMessage(d); };
+    this.options.failure = function(d) { return that.onLoadFailure(d); };
+
+    // Create view to handle the header inputs
+    this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});
+
+    // Event handler for when the baseUrl/apiKey is entered by user
+    this.headerView.on('update-swagger-ui', function(data) {
+      return that.updateSwaggerUi(data);
+    });
+
+    // JSon Editor custom theming
+     JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({
+      mapping: {
+        collapse: 'collapse',
+        expand: 'expand'
+        },
+      icon_prefix: 'swagger-'
+      });
+
+  },
+
+  // Set an option after initializing
+  setOption: function(option, value) {
+    this.options[option] = value;
+  },
+
+  // Get the value of a previously set option
+  getOption: function(option) {
+    return this.options[option];
+  },
+
+  // Event handler for when url/key is received from user
+  updateSwaggerUi: function(data){
+    this.options.url = data.url;
+    this.load();
+  },
+
+  // Create an api and render
+  load: function(){
+    // Initialize the API object
+    if (this.mainView) {
+      this.mainView.clear();
+    }
+
+    if (this.authView) {
+      this.authView.remove();
+    }
+    var url = this.options.url;
+    if (url && url.indexOf('http') !== 0) {
+      url = this.buildUrl(window.location.href.toString(), url);
+    }
+    if(this.api) {
+      this.options.authorizations = this.api.clientAuthorizations.authz;
+    }
+    this.options.url = url;
+    this.headerView.update(url);
+
+    this.api = new SwaggerClient(this.options);
+  },
+
+  // collapse all sections
+  collapseAll: function(){
+    Docs.collapseEndpointListForResource('');
+  },
+
+  // list operations for all sections
+  listAll: function(){
+    Docs.collapseOperationsForResource('');
+  },
+
+  // expand operations for all sections
+  expandAll: function(){
+    Docs.expandOperationsForResource('');
+  },
+
+  // This is bound to success handler for SwaggerApi
+  //  so it gets called when SwaggerApi completes loading
+  render: function(){
+    var authsModel;
+    this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');
+    this.mainView = new SwaggerUi.Views.MainView({
+      model: this.api,
+      el: $('#' + this.dom_id),
+      swaggerOptions: this.options,
+      router: this
+    }).render();
+    if (!_.isEmpty(this.api.securityDefinitions)){
+      authsModel = _.map(this.api.securityDefinitions, function (auth, name) {
+        var result = {};
+        result[name] = auth;
+        return result;
+      });
+      this.authView = new SwaggerUi.Views.AuthButtonView({
+        data: SwaggerUi.utils.parseSecurityDefinitions(authsModel),
+        router: this
+      });
+      $('#auth_container').append(this.authView.render().el);
+    }
+    this.showMessage();
+    switch (this.options.docExpansion) {
+      case 'full':
+        this.expandAll(); break;
+      case 'list':
+        this.listAll(); break;
+      default:
+        break;
+    }
+    this.renderGFM();
+
+    if (this.options.onComplete){
+      this.options.onComplete(this.api, this);
+    }
+
+    setTimeout(Docs.shebang.bind(this), 100);
+  },
+
+  buildUrl: function(base, url){
+    if (url.indexOf('/') === 0) {
+      var parts = base.split('/');
+      base = parts[0] + '//' + parts[2];
+      return base + url;
+    } else {
+      var endOfPath = base.length;
+
+      if (base.indexOf('?') > -1){
+        endOfPath = Math.min(endOfPath, base.indexOf('?'));
+      }
+
+      if (base.indexOf('#') > -1){
+        endOfPath = Math.min(endOfPath, base.indexOf('#'));
+      }
+
+      base = base.substring(0, endOfPath);
+
+      if (base.indexOf('/', base.length - 1 ) !== -1){
+        return base + url;
+      }
+
+      return base + '/' + url;
+    }
+  },
+
+  // Shows message on topbar of the ui
+  showMessage: function(data){
+    if (data === undefined) {
+      data = '';
+    }
+    var $msgbar = $('#message-bar');
+    $msgbar.removeClass('message-fail');
+    $msgbar.addClass('message-success');
+    $msgbar.text(data);
+    if(window.SwaggerTranslator) {
+      window.SwaggerTranslator.translate($msgbar);
+    }
+  },
+
+  // shows message in red
+  onLoadFailure: function(data){
+    if (data === undefined) {
+      data = '';
+    }
+    $('#message-bar').removeClass('message-success');
+    $('#message-bar').addClass('message-fail');
+
+    var val = $('#message-bar').text(data);
+
+    if (this.options.onFailure) {
+      this.options.onFailure(data);
+    }
+
+    return val;
+  },
+
+  // Renders GFM for elements with 'markdown' class
+  renderGFM: function(){
+    $('.markdown').each(function(){
+      $(this).html(marked($(this).html()));
+    });
+
+    $('.propDesc', '.model-signature .description').each(function () {
+      $(this).html(marked($(this).html())).addClass('markdown');
+    });
+  }
+
+});
+
+window.SwaggerUi.Views = {};
+window.SwaggerUi.Models = {};
+window.SwaggerUi.Collections = {};
+window.SwaggerUi.partials = {};
+window.SwaggerUi.utils = {};
+
+// don't break backward compatibility with previous versions and warn users to upgrade their code
+(function(){
+  window.authorizations = {
+    add: function() {
+      warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().');
+
+      if (typeof window.swaggerUi === 'undefined') {
+        throw new TypeError('window.swaggerUi is not defined');
+      }
+
+      if (window.swaggerUi instanceof SwaggerUi) {
+        window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments);
+      }
+    }
+  };
+
+  window.ApiKeyAuthorization = function() {
+    warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.');
+    SwaggerClient.ApiKeyAuthorization.apply(window, arguments);
+  };
+
+  window.PasswordAuthorization = function() {
+    warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.');
+    SwaggerClient.PasswordAuthorization.apply(window, arguments);
+  };
+
+  function warn(message) {
+    if ('console' in window && typeof window.console.warn === 'function') {
+      console.warn(message);
+    }
+  }
+})();
+
+
+// UMD
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define(['b'], function (b) {
+            return (root.SwaggerUi = factory(b));
+        });
+    } else if (typeof exports === 'object') {
+        // Node. Does not work with strict CommonJS, but
+        // only CommonJS-like environments that support module.exports,
+        // like Node.
+        module.exports = factory(require('b'));
+    } else {
+        // Browser globals
+        root.SwaggerUi = factory(root.b);
+    }
+}(this, function () {
+    return SwaggerUi;
+}));
+
+'use strict';
+
+window.SwaggerUi.utils = {
+    parseSecurityDefinitions: function (security) {
+        var auths = Object.assign({}, window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions);
+        var oauth2Arr = [];
+        var authsArr = [];
+        var scopes = [];
+        var utils = window.SwaggerUi.utils;
+
+        if (!Array.isArray(security)) { return null; }
+
+        security.forEach(function (item) {
+            var singleSecurity = {};
+            var singleOauth2Security = {};
+
+            for (var key in item) {
+                if (Array.isArray(item[key])) {
+                    if (!auths[key]) { continue; }
+                    auths[key] = auths[key] || {};
+                    if (auths[key].type === 'oauth2') {
+                        singleOauth2Security[key] = Object.assign({}, auths[key]);
+                        for (var i in singleOauth2Security[key].scopes) {
+                            if (item[key].indexOf(i) < 0) {
+                                delete singleOauth2Security[key].scopes[i];
+                            }
+                        }
+                        singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
+                        scopes = _.merge(scopes, singleOauth2Security[key].scopes);
+                    } else {
+                        singleSecurity[key] = Object.assign({}, auths[key]);
+                    }
+                } else {
+                    if (item[key].type === 'oauth2') {
+                        singleOauth2Security[key] = Object.assign({}, item[key]);
+                        singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
+                        scopes = _.merge(scopes, singleOauth2Security[key].scopes);
+                    } else {
+                        singleSecurity[key] = item[key];
+                    }
+                }
+            }
+
+            if (!_.isEmpty(singleSecurity)) {
+                authsArr.push(singleSecurity);
+            }
+
+            if (!_.isEmpty(singleOauth2Security)){
+                oauth2Arr.push(singleOauth2Security);
+            }
+        });
+
+        return {
+            auths : authsArr,
+            oauth2: oauth2Arr,
+            scopes: scopes
+        };
+    },
+
+    parseOauth2Scopes: function (data) {
+        var scopes = Object.assign({}, data);
+        var result = [];
+        var key;
+
+        for (key in scopes) {
+            result.push({scope: key, description: scopes[key]});
+        }
+
+        return result;
+    }
+};
+'use strict';
+
+SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({
+    defaults: {
+        'in': '',
+        name: '',
+        title: '',
+        value: ''
+    },
+
+    initialize: function () {
+        this.on('change', this.validate);
+    },
+
+    validate: function () {
+        var valid = !!this.get('value');
+
+        this.set('valid', valid);
+
+        return valid;
+    }
+});
+'use strict';
+
+SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi
+
+    events: {
+        'change .input_apiKey_entry': 'apiKeyChange'
+    },
+
+    selectors: {
+        apikeyInput: '.input_apiKey_entry'
+    },
+
+    template: Handlebars.templates.apikey_auth,
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.router = this.options.router;
+    },
+
+    render: function (){
+        this.$el.html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    apiKeyChange: function (e) {
+        var val = $(e.target).val();
+        if (val) {
+            this.$(this.selectors.apikeyInput).removeClass('error');
+        }
+
+        this.model.set('value', val);
+    },
+
+    isValid: function () {
+        return this.model.validate();
+    },
+
+    highlightInvalid: function () {
+        if (!this.isValid()) {
+            this.$(this.selectors.apikeyInput).addClass('error');
+        }
+    }
+
+});
+'use strict';
+
+SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
+    events: {
+        'click .authorize__btn': 'authorizeBtnClick'
+    },
+
+    tpls: {
+        popup: Handlebars.templates.popup,
+        authBtn: Handlebars.templates.auth_button,
+        authBtnOperation: Handlebars.templates.auth_button_operation
+    },
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.options.data = this.options.data || {};
+        this.isOperation = this.options.isOperation;
+        this.model = this.model || {};
+        this.router = this.options.router;
+        this.auths = this.options.data.oauth2.concat(this.options.data.auths);
+    },
+
+    render: function () {
+        var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn';
+
+        this.$authEl = this.renderAuths(this.auths);
+        this.$el.html(this.tpls[tplName](this.model));
+
+        return this;
+    },
+
+    authorizeBtnClick: function (e) {
+        var authsModel;
+
+        e.preventDefault();
+
+        authsModel = {
+            title: 'Available authorizations',
+            content: this.$authEl
+        };
+
+        this.popup = new SwaggerUi.Views.PopupView({model: authsModel});
+        this.popup.render();
+    },
+
+    renderAuths: function (auths) {
+        var $el = $('<div>');
+        var isLogout = false;
+
+        auths.forEach(function (auth) {
+            var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router});
+            var authEl = authView.render().el;
+            $el.append(authEl);
+            if (authView.isLogout) {
+                isLogout = true;
+            }
+        }, this);
+
+        this.model.isLogout = isLogout;
+
+        return $el;
+    }
+
+});
+
+'use strict';
+
+SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({
+    constructor: function() {
+        var args = Array.prototype.slice.call(arguments);
+
+        args[0] = this.parse(args[0]);
+
+        Backbone.Collection.apply(this, args);
+    },
+
+    add: function (model) {
+        var args = Array.prototype.slice.call(arguments);
+
+        if (Array.isArray(model)) {
+            args[0] = _.map(model, function(val) {
+                return this.handleOne(val);
+            }, this);
+        } else {
+            args[0] = this.handleOne(model);
+        }
+
+        Backbone.Collection.prototype.add.apply(this, args);
+    },
+
+    handleOne: function (model) {
+        var result = model;
+
+        if (! (model instanceof Backbone.Model) ) {
+            switch (model.type) {
+                case 'oauth2':
+                    result = new SwaggerUi.Models.Oauth2Model(model);
+                    break;
+                case 'basic':
+                    result = new SwaggerUi.Models.BasicAuthModel(model);
+                    break;
+                case 'apiKey':
+                    result = new SwaggerUi.Models.ApiKeyAuthModel(model);
+                    break;
+                default:
+                    result = new Backbone.Model(model);
+            }
+        }
+
+        return result;
+    },
+
+    isValid: function () {
+        var valid = true;
+
+        this.models.forEach(function(model) {
+            if (!model.validate()) {
+                valid = false;
+            }
+        });
+
+        return valid;
+    },
+
+    isAuthorized: function () {
+        return this.length === this.where({ isLogout: true }).length;
+    },
+
+    isPartiallyAuthorized: function () {
+        return this.where({ isLogout: true }).length > 0;
+    },
+
+    parse: function (data) {
+        var authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz);
+
+        return _.map(data, function (auth, name) {
+            var isBasic = authz.basic && auth.type === 'basic';
+
+            _.extend(auth, {
+                title: name
+            });
+
+            if (authz[name] || isBasic) {
+                _.extend(auth, {
+                    isLogout: true,
+                    value: isBasic ? undefined : authz[name].value,
+                    username: isBasic ? authz.basic.username : undefined,
+                    password: isBasic ? authz.basic.password : undefined,
+                    valid: true
+                });
+            }
+
+            return auth;
+        });
+    }
+});
+'use strict';
+
+SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.options.data = this.options.data || {};
+        this.router = this.options.router;
+
+        this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data);
+
+        this.$innerEl = $('<div>');
+        this.authViews = [];
+    },
+
+    render: function () {
+        this.collection.each(function (auth) {
+            this.renderOneAuth(auth);
+        }, this);
+
+        this.$el.html(this.$innerEl.html() ? this.$innerEl : '');
+
+        return this;
+    },
+
+    renderOneAuth: function (authModel) {
+        var authViewEl, authView, authViewName;
+        var type = authModel.get('type');
+
+        if (type === 'apiKey') {
+            authViewName = 'ApiKeyAuthView';
+        } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {
+            authViewName = 'BasicAuthView';
+        } else if (type === 'oauth2') {
+            authViewName = 'Oauth2View';
+        }
+
+        if (authViewName) {
+            authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router});
+            authViewEl = authView.render().el;
+            this.authViews.push(authView);
+        }
+
+        this.$innerEl.append(authViewEl);
+    },
+
+    highlightInvalid: function () {
+        this.authViews.forEach(function (view) {
+            view.highlightInvalid();
+        }, this);
+    }
+
+});
+
+'use strict';
+
+/* global redirect_uri */
+/* global clientId */
+/* global scopeSeparator */
+/* global additionalQueryStringParams */
+/* global clientSecret */
+/* global onOAuthComplete */
+/* global realm */
+/*jshint unused:false*/
+
+SwaggerUi.Views.AuthView = Backbone.View.extend({
+    events: {
+        'click .auth_submit__button': 'authorizeClick',
+        'click .auth_logout__button': 'logoutClick'
+    },
+
+    tpls: {
+        main: Handlebars.templates.auth_view
+    },
+
+    selectors: {
+        innerEl: '.auth_inner',
+        authBtn: '.auth_submit__button'
+    },
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        opts.data = opts.data || {};
+        this.router = this.options.router;
+
+        this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data});
+
+        this.$el.html(this.tpls.main({
+            isLogout: this.authsCollectionView.collection.isAuthorized(),
+            isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized()
+        }));
+        this.$innerEl = this.$(this.selectors.innerEl);
+        this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized();
+    },
+
+    render: function () {
+        this.$innerEl.html(this.authsCollectionView.render().el);
+
+        return this;
+    },
+
+    authorizeClick: function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+
+        if (this.authsCollectionView.collection.isValid()) {
+            this.authorize();
+        } else {
+            this.authsCollectionView.highlightInvalid();
+        }
+    },
+
+    authorize: function () {
+        this.authsCollectionView.collection.forEach(function (auth) {
+            var keyAuth, basicAuth;
+            var type = auth.get('type');
+
+            if (type === 'apiKey') {
+                keyAuth = new SwaggerClient.ApiKeyAuthorization(
+                    auth.get('name'),
+                    auth.get('value'),
+                    auth.get('in')
+                );
+
+                this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth);
+            } else if (type === 'basic') {
+                basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));
+                this.router.api.clientAuthorizations.add(auth.get('type'), basicAuth);
+            } else if (type === 'oauth2') {
+                this.handleOauth2Login(auth);
+            }
+        }, this);
+
+        this.router.load();
+    },
+
+    logoutClick: function (e) {
+        e.preventDefault();
+
+        this.authsCollectionView.collection.forEach(function (auth) {
+            var name = auth.get('type') === 'basic' ? 'basic' : auth.get('title');
+
+            window.swaggerUi.api.clientAuthorizations.remove(name);
+        });
+
+        this.router.load();
+    },
+
+    // taken from lib/swagger-oauth.js
+    handleOauth2Login: function (auth) {
+        var host = window.location;
+        var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/'));
+        var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
+        var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
+        var url = null;
+        var scopes = _.map(auth.get('scopes'), function (scope) {
+            return scope.scope;
+        });
+        var state, dets, ep;
+        window.OAuthSchemeKey = auth.get('title');
+
+        window.enabledScopes = scopes;
+        var flow = auth.get('flow');
+
+        if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
+            dets = auth.attributes;
+            url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
+            window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+            window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
+            state = window.OAuthSchemeKey;
+        }
+        else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
+            dets = auth.attributes;
+            window.swaggerUi.tokenName = dets.tokenName || 'access_token';
+            this.clientCredentialsFlow(scopes, dets.tokenUrl, window.OAuthSchemeKey);
+            return;
+        }
+        else if(auth.get('grantTypes')) {
+            // 1.2 support
+            var o = auth.get('grantTypes');
+            for(var t in o) {
+                if(o.hasOwnProperty(t) && t === 'implicit') {
+                    dets = o[t];
+                    ep = dets.loginEndpoint.url;
+                    url = dets.loginEndpoint.url + '?response_type=token';
+                    window.swaggerUi.tokenName = dets.tokenName;
+                }
+                else if (o.hasOwnProperty(t) && t === 'accessCode') {
+                    dets = o[t];
+                    ep = dets.tokenRequestEndpoint.url;
+                    url = dets.tokenRequestEndpoint.url + '?response_type=code';
+                    window.swaggerUi.tokenName = dets.tokenName;
+                }
+            }
+        }
+
+        var redirect_uri = redirectUrl;
+
+        url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
+        url += '&realm=' + encodeURIComponent(realm);
+        url += '&client_id=' + encodeURIComponent(clientId);
+        url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
+        url += '&state=' + encodeURIComponent(state);
+        for (var key in additionalQueryStringParams) {
+            url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
+        }
+
+        window.open(url);
+    },
+
+    // taken from lib/swagger-oauth.js
+    clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) {
+        var params = {
+            'client_id': clientId,
+            'client_secret': clientSecret,
+            'scope': scopes.join(' '),
+            'grant_type': 'client_credentials'
+        };
+        $.ajax({
+            url : tokenUrl,
+            type: 'POST',
+            data: params,
+            success: function (data)
+            {
+                onOAuthComplete(data, OAuthSchemeKey);
+            },
+            error: function ()
+            {
+                onOAuthComplete('');
+            }
+        });
+    }
+
+});
+
+'use strict';
+
+SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({
+    defaults: {
+        username: '',
+        password: '',
+        title: 'basic'
+    },
+
+    initialize: function () {
+        this.on('change', this.validate);
+    },
+
+    validate: function () {
+        var valid = !!this.get('password') && !!this.get('username');
+
+        this.set('valid', valid);
+
+        return valid;
+    }
+});
+'use strict';
+
+SwaggerUi.Views.BasicAuthView = Backbone.View.extend({
+
+    initialize: function (opts) {
+        this.options = opts || {};
+        this.router = this.options.router;
+    },
+
+    events: {
+        'change .auth_input': 'inputChange'
+    },
+
+    selectors: {
+        usernameInput: '.basic_auth__username',
+        passwordInput: '.basic_auth__password'
+    },
+
+    cls: {
+        error: 'error'
+    },
+
+    template: Handlebars.templates.basic_auth,
+
+    render: function(){
+        $(this.el).html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    inputChange: function (e) {
+        var $el = $(e.target);
+        var val = $el.val();
+        var attr = $el.prop('name');
+
+        if (val) {
+            $el.removeClass(this.cls.error);
+        }
+
+        this.model.set(attr, val);
+    },
+
+    isValid: function () {
+        return this.model.validate();
+    },
+
+    highlightInvalid: function () {
+        if (!this.model.get('username')) {
+            this.$(this.selectors.usernameInput).addClass(this.cls.error);
+        }
+
+        if (!this.model.get('password')) {
+            this.$(this.selectors.passwordInput).addClass(this.cls.error);
+        }
+    }
+});
+'use strict';
+
+SwaggerUi.Views.ContentTypeView = Backbone.View.extend({
+  initialize: function() {},
+
+  render: function(){
+       this.model.contentTypeId = 'ct' + Math.random();
+    $(this.el).html(Handlebars.templates.content_type(this.model));
+    return this;
+  }
+});
+'use strict';
+
+SwaggerUi.Views.HeaderView = Backbone.View.extend({
+  events: {
+    'click #show-pet-store-icon'    : 'showPetStore',
+    'click #explore'                : 'showCustom',
+    'keyup #input_baseUrl'          : 'showCustomOnKeyup',
+    'keyup #input_apiKey'           : 'showCustomOnKeyup'
+  },
+
+  initialize: function(){},
+
+  showPetStore: function(){
+    this.trigger('update-swagger-ui', {
+      url:'http://petstore.swagger.io/v2/swagger.json'
+    });
+  },
+
+  showCustomOnKeyup: function(e){
+    if (e.keyCode === 13) {
+      this.showCustom();
+    }
+  },
+
+  showCustom: function(e){
+    if (e) {
+      e.preventDefault();
+    }
+
+    this.trigger('update-swagger-ui', {
+      url: $('#input_baseUrl').val()
+    });
+  },
+
+  update: function(url, apiKey, trigger){
+    if (trigger === undefined) {
+      trigger = false;
+    }
+
+    $('#input_baseUrl').val(url);
+
+    if (trigger) {
+      this.trigger('update-swagger-ui', {url:url});
+    }
+  }
+});
+
+'use strict';
+
+SwaggerUi.Views.MainView = Backbone.View.extend({
+  apisSorter : {
+    alpha   : function(a,b){ return a.name.localeCompare(b.name); }
+  },
+  operationsSorters : {
+    alpha   : function(a,b){ return a.path.localeCompare(b.path); },
+    method  : function(a,b){ return a.method.localeCompare(b.method); }
+  },
+  initialize: function(opts){
+    var sorterOption, sorterFn, key, value;
+    opts = opts || {};
+
+    this.router = opts.router;
+
+    // Sort APIs
+    if (opts.swaggerOptions.apisSorter) {
+      sorterOption = opts.swaggerOptions.apisSorter;
+      if (_.isFunction(sorterOption)) {
+        sorterFn = sorterOption;
+      } else {
+        sorterFn = this.apisSorter[sorterOption];
+      }
+      if (_.isFunction(sorterFn)) {
+        this.model.apisArray.sort(sorterFn);
+      }
+    }
+    // Sort operations of each API
+    if (opts.swaggerOptions.operationsSorter) {
+      sorterOption = opts.swaggerOptions.operationsSorter;
+      if (_.isFunction(sorterOption)) {
+        sorterFn = sorterOption;
+      } else {
+        sorterFn = this.operationsSorters[sorterOption];
+      }
+      if (_.isFunction(sorterFn)) {
+        for (key in this.model.apisArray) {
+          this.model.apisArray[key].operationsArray.sort(sorterFn);
+        }
+      }
+    }
+
+    // set up the UI for input
+    this.model.auths = [];
+
+    for (key in this.model.securityDefinitions) {
+      value = this.model.securityDefinitions[key];
+
+      this.model.auths.push({
+        name: key,
+        type: value.type,
+        value: value
+      });
+    }
+
+    if ('validatorUrl' in opts.swaggerOptions) {
+      // Validator URL specified explicitly
+      this.model.validatorUrl = opts.swaggerOptions.validatorUrl;
+    } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) {
+      // Localhost override
+      this.model.validatorUrl = null;
+    } else {
+      // Default validator
+      if(window.location.protocol === 'https:') {
+        this.model.validatorUrl = 'https://online.swagger.io/validator';
+      }
+      else {
+        this.model.validatorUrl = 'http://online.swagger.io/validator';
+      }
+    }
+
+    // JSonEditor requires type='object' to be present on defined types, we add it if it's missing
+    // is there any valid case were it should not be added ?
+    var def;
+    for(def in this.model.definitions){
+      if (!this.model.definitions[def].type){
+        this.model.definitions[def].type = 'object';
+      }
+    }
+
+  },
+
+  render: function () {
+    $(this.el).html(Handlebars.templates.main(this.model));
+    this.info = this.$('.info')[0];
+
+    if (this.info) {
+      this.info.addEventListener('click', this.onLinkClick, true);
+    }
+
+    this.model.securityDefinitions = this.model.securityDefinitions || {};
+
+    // Render each resource
+
+    var resources = {};
+    var counter = 0;
+    for (var i = 0; i < this.model.apisArray.length; i++) {
+      var resource = this.model.apisArray[i];
+      var id = resource.name;
+      while (typeof resources[id] !== 'undefined') {
+        id = id + '_' + counter;
+        counter += 1;
+      }
+      resource.id = id;
+      resources[id] = resource;
+      this.addResource(resource, this.model.auths);
+    }
+
+    $('.propWrap').hover(function onHover(){
+      $('.optionsWrapper', $(this)).show();
+    }, function offhover(){
+      $('.optionsWrapper', $(this)).hide();
+    });
+    return this;
+  },
+
+  addResource: function(resource, auths){
+    // Render a resource and add it to resources li
+    resource.id = resource.id.replace(/\s/g, '_');
+
+    // Make all definitions available at the root of the resource so that they can
+    // be loaded by the JSonEditor
+    resource.definitions = this.model.definitions;
+
+    var resourceView = new SwaggerUi.Views.ResourceView({
+      model: resource,
+      router: this.router,
+      tagName: 'li',
+      id: 'resource_' + resource.id,
+      className: 'resource',
+      auths: auths,
+      swaggerOptions: this.options.swaggerOptions
+    });
+    $('#resources', this.el).append(resourceView.render().el);
+  },
+
+  clear: function(){
+    $(this.el).html('');
+  },
+
+  onLinkClick: function (e) {
+    var el = e.target;
+
+    if (el.tagName === 'A' && el.href && !el.target) {
+        e.preventDefault();
+        window.open(el.href, '_blank');
+    }
+  }
+});
+
+'use strict';
+
+SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
+    defaults: {
+        scopes: {}
+    },
+
+    initialize: function () {
+        this.on('change', this.validate);
+    },
+
+    setScopes: function (name, val) {
+        var auth = _.extend({}, this.attributes);
+        var index = _.findIndex(auth.scopes, function(o) {
+            return o.scope === name;
+        });
+        auth.scopes[index].checked = val;
+
+        this.set(auth);
+        this.validate();
+    },
+
+    validate: function () {
+        var valid =  _.findIndex(this.get('scopes'), function (o) {
+           return o.checked === true;
+        }) > -1;
+
+        this.set('valid', valid);
+
+        return valid;
+    }
+});
+'use strict';
+
+SwaggerUi.Views.Oauth2View = Backbone.View.extend({
+    events: {
+        'change .oauth-scope': 'scopeChange'
+    },
+
+    template: Handlebars.templates.oauth2,
+
+    render: function () {
+        this.$el.html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    scopeChange: function (e) {
+        var val = $(e.target).prop('checked');
+        var scope = $(e.target).data('scope');
+
+        this.model.setScopes(scope, val);
+    }
+});
+'use strict';
+
+SwaggerUi.Views.OperationView = Backbone.View.extend({
+  invocationUrl: null,
+
+  events: {
+    'submit .sandbox'         : 'submitOperation',
+    'click .submit'           : 'submitOperation',
+    'click .response_hider'   : 'hideResponse',
+    'click .toggleOperation'  : 'toggleOperationContent',
+    'mouseenter .api-ic'      : 'mouseEnter',
+    'dblclick .curl'          : 'selectText',
+    'change [name=responseContentType]' : 'showSnippet'
+  },
+
+  initialize: function(opts) {
+    opts = opts || {};
+    this.router = opts.router;
+    this.auths = opts.auths;
+    this.parentId = this.model.parentId;
+    this.nickname = this.model.nickname;
+    this.model.encodedParentId = encodeURIComponent(this.parentId);
+
+    if (opts.swaggerOptions) {
+      this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering;
+
+      if (opts.swaggerOptions.showRequestHeaders) {
+        this.model.showRequestHeaders = true;
+      }
+    }
+    return this;
+  },
+
+  selectText: function(event) {
+    var doc = document,
+        text = event.target.firstChild,
+        range,
+        selection;
+    if (doc.body.createTextRange) {
+      range = document.body.createTextRange();
+      range.moveToElementText(text);
+      range.select();
+    } else if (window.getSelection) {
+      selection = window.getSelection();
+      range = document.createRange();
+      range.selectNodeContents(text);
+      selection.removeAllRanges();
+      selection.addRange(range);
+    }
+  },
+
+  mouseEnter: function(e) {
+    var elem = $(this.el).find('.content');
+    var x = e.pageX;
+    var y = e.pageY;
+    var scX = $(window).scrollLeft();
+    var scY = $(window).scrollTop();
+    var scMaxX = scX + $(window).width();
+    var scMaxY = scY + $(window).height();
+    var wd = elem.width();
+    var hgh = elem.height();
+
+    if (x + wd > scMaxX) {
+      x = scMaxX - wd;
+    }
+
+    if (x < scX) {
+      x = scX;
+    }
+
+    if (y + hgh > scMaxY) {
+      y = scMaxY - hgh;
+    }
+
+    if (y < scY) {
+      y = scY;
+    }
+
+    var pos = {};
+    pos.top = y;
+    pos.left = x;
+    elem.css(pos);
+  },
+
+  // Note: copied from CoffeeScript compiled file
+  // TODO: redactor
+  render: function() {
+    var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON;
+    isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
+    if (!isMethodSubmissionSupported) {
+      this.model.isReadOnly = true;
+    }
+    this.model.description = this.model.description || this.model.notes;
+    this.model.oauth = null;
+    modelAuths = this.model.authorizations || this.model.security;
+    if (modelAuths) {
+      if (Array.isArray(modelAuths)) {
+        for (l = 0, len = modelAuths.length; l < len; l++) {
+          auths = modelAuths[l];
+          for (key in auths) {
+            for (a in this.auths) {
+              auth = this.auths[a];
+              if (key === auth.name) {
+                if (auth.type === 'oauth2') {
+                  this.model.oauth = {};
+                  this.model.oauth.scopes = [];
+                  ref1 = auth.value.scopes;
+                  for (k in ref1) {
+                    v = ref1[k];
+                    scopeIndex = auths[key].indexOf(k);
+                    if (scopeIndex >= 0) {
+                      o = {
+                        scope: k,
+                        description: v
+                      };
+                      this.model.oauth.scopes.push(o);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      } else {
+        for (k in modelAuths) {
+          v = modelAuths[k];
+          if (k === 'oauth2') {
+            if (this.model.oauth === null) {
+              this.model.oauth = {};
+            }
+            if (this.model.oauth.scopes === void 0) {
+              this.model.oauth.scopes = [];
+            }
+            for (m = 0, len1 = v.length; m < len1; m++) {
+              o = v[m];
+              this.model.oauth.scopes.push(o);
+            }
+          }
+        }
+      }
+    }
+    if (typeof this.model.responses !== 'undefined') {
+      this.model.responseMessages = [];
+      ref2 = this.model.responses;
+      for (code in ref2) {
+        value = ref2[code];
+        schema = null;
+        schemaObj = this.model.responses[code].schema;
+        if (schemaObj && schemaObj.$ref) {
+          schema = schemaObj.$ref;
+          if (schema.indexOf('#/definitions/') !== -1) {
+            schema = schema.replace(/^.*#\/definitions\//, '');
+          }
+        }
+        this.model.responseMessages.push({
+          code: code,
+          message: value.description,
+          responseModel: schema,
+          headers: value.headers,
+          schema: schemaObj
+        });
+      }
+    }
+    if (typeof this.model.responseMessages === 'undefined') {
+      this.model.responseMessages = [];
+    }
+    signatureModel = null;
+    produces = this.model.produces;
+    isXML = this.contains(produces, 'xml');
+    isJSON = isXML ? this.contains(produces, 'json') : true;
+
+    if (this.model.successResponse) {
+      successResponse = this.model.successResponse;
+      for (key in successResponse) {
+        value = successResponse[key];
+        this.model.successCode = key;
+        if (typeof value === 'object' && typeof value.createJSONSample === 'function') {
+          this.model.successDescription = value.description;
+          this.model.headers = this.parseResponseHeaders(value.headers);
+          signatureModel = {
+            sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false,
+            isParam: false,
+            sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false,
+            signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro)
+          };
+        } else {
+          signatureModel = {
+            signature: SwaggerUi.partials.signature.getPrimitiveSignature(value)
+          };
+        }
+      }
+    } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {
+      signatureModel = {
+        sampleJSON: this.model.responseSampleJSON,
+        isParam: false,
+        signature: this.model.responseClassSignature
+      };
+    }
+    $(this.el).html(Handlebars.templates.operation(this.model));
+    if (signatureModel) {
+      signatureModel.defaultRendering = this.model.defaultRendering;
+      responseSignatureView = new SwaggerUi.Views.SignatureView({
+        model: signatureModel,
+        router: this.router,
+        tagName: 'div'
+      });
+      $('.model-signature', $(this.el)).append(responseSignatureView.render().el);
+    } else {
+      this.model.responseClassSignature = 'string';
+      $('.model-signature', $(this.el)).html(this.model.type);
+    }
+    contentTypeModel = {
+      isParam: false
+    };
+    contentTypeModel.consumes = this.model.consumes;
+    contentTypeModel.produces = this.model.produces;
+    ref3 = this.model.parameters;
+    for (n = 0, len2 = ref3.length; n < len2; n++) {
+      param = ref3[n];
+      type = param.type || param.dataType || '';
+      if (typeof type === 'undefined') {
+        schema = param.schema;
+        if (schema && schema.$ref) {
+          ref = schema.$ref;
+          if (ref.indexOf('#/definitions/') === 0) {
+            type = ref.substring('#/definitions/'.length);
+          } else {
+            type = ref;
+          }
+        }
+      }
+      if (type && type.toLowerCase() === 'file') {
+        if (!contentTypeModel.consumes) {
+          contentTypeModel.consumes = 'multipart/form-data';
+        }
+      }
+      param.type = type;
+    }
+    responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({
+      model: contentTypeModel,
+      router: this.router
+    });
+    $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
+    ref4 = this.model.parameters;
+    for (p = 0, len3 = ref4.length; p < len3; p++) {
+      param = ref4[p];
+      this.addParameter(param, contentTypeModel.consumes);
+    }
+    ref5 = this.model.responseMessages;
+    for (q = 0, len4 = ref5.length; q < len4; q++) {
+      statusCode = ref5[q];
+      statusCode.isXML = isXML;
+      statusCode.isJSON = isJSON;
+      if (!_.isUndefined(statusCode.headers)) {
+        statusCode.headers = this.parseHeadersType(statusCode.headers);
+      }
+      this.addStatusCode(statusCode);
+    }
+
+    if (Array.isArray(this.model.security)) {
+      var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security);
+
+      authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz);
+      this.authView = new SwaggerUi.Views.AuthButtonView({
+        data: authsModel,
+        router: this.router,
+        isOperation: true,
+        model: {
+          scopes: authsModel.scopes
+        }
+      });
+      this.$('.authorize-wrapper').append(this.authView.render().el);
+    }
+
+    this.showSnippet();
+    return this;
+  },
+
+  parseHeadersType: function (headers) {
+    var map = {
+      'string': {
+        'date-time': 'dateTime',
+        'date'     : 'date'
+      }
+    };
+
+    _.forEach(headers, function (header) {
+      var value;
+      header = header || {};
+      value = map[header.type] && map[header.type][header.format];
+      if (!_.isUndefined(value)) {
+        header.type = value;
+      }
+    });
+
+    return headers;
+  },
+
+  contains: function (produces, type) {
+    return produces.filter(function (val) {
+      if (val.indexOf(type) > -1) {
+        return true;
+      }
+    }).length;
+  },
+
+  parseResponseHeaders: function (data) {
+    var HEADERS_SEPARATOR = '; ';
+    var headers = _.clone(data);
+
+    _.forEach(headers, function (header) {
+      var other = [];
+      _.forEach(header, function (value, key) {
+        var properties = ['type', 'description'];
+        if (properties.indexOf(key.toLowerCase()) === -1) {
+          other.push(key + ': ' + value);
+        }
+      });
+
+      other.join(HEADERS_SEPARATOR);
+      header.other = other;
+    });
+
+    return headers;
+  },
+
+  addParameter: function(param, consumes) {
+    // Render a parameter
+    param.consumes = consumes;
+    param.defaultRendering = this.model.defaultRendering;
+
+    // Copy this param JSON spec so that it will be available for JsonEditor
+    if(param.schema){
+      $.extend(true, param.schema, this.model.definitions[param.type]);
+      param.schema.definitions = this.model.definitions;
+      // This is required for JsonEditor to display the root properly
+      if(!param.schema.type){
+        param.schema.type = 'object';
+      }
+      // This is the title that will be used by JsonEditor for the root
+      // Since we already display the parameter's name in the Parameter column
+      // We set this to space, we can't set it to null or space otherwise JsonEditor
+      // will replace it with the text "root" which won't look good on screen
+      if(!param.schema.title){
+        param.schema.title = ' ';
+      }
+    }
+
+    var paramView = new SwaggerUi.Views.ParameterView({
+      model: param,
+      tagName: 'tr',
+      readOnly: this.model.isReadOnly,
+      swaggerOptions: this.options.swaggerOptions
+    });
+    $('.operation-params', $(this.el)).append(paramView.render().el);
+  },
+
+  addStatusCode: function(statusCode) {
+    // Render status codes
+    statusCode.defaultRendering = this.model.defaultRendering;
+    var statusCodeView = new SwaggerUi.Views.StatusCodeView({
+      model: statusCode,
+      tagName: 'tr',
+      router: this.router
+    });
+    $('.operation-status', $(this.el)).append(statusCodeView.render().el);
+  },
+
+  // Note: copied from CoffeeScript compiled file
+  // TODO: redactor
+  submitOperation: function(e) {
+    var error_free, form, isFileUpload, map, opts;
+    if (e !== null) {
+      e.preventDefault();
+    }
+    form = $('.sandbox', $(this.el));
+    error_free = true;
+    form.find('input.required').each(function() {
+      $(this).removeClass('error');
+      if (jQuery.trim($(this).val()) === '') {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    form.find('textarea.required:visible').each(function() {
+      $(this).removeClass('error');
+      if (jQuery.trim($(this).val()) === '') {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              return $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    form.find('select.required').each(function() {
+      $(this).removeClass('error');
+      if (this.selectedIndex === -1) {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    if (error_free) {
+      map = this.getInputMap(form);
+      isFileUpload = this.isFileUpload(form);
+      opts = {
+        parent: this
+      };
+      if (this.options.swaggerOptions) {
+        for(var key in this.options.swaggerOptions) {
+          opts[key] = this.options.swaggerOptions[key];
+        }
+      }
+
+      var pi;
+      for(pi = 0; pi < this.model.parameters.length; pi++){
+        var p = this.model.parameters[pi];
+        if( p.jsonEditor && p.jsonEditor.isEnabled()){
+          var json = p.jsonEditor.getValue();
+          map[p.name] = JSON.stringify(json);
+        }
+      }
+
+      opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();
+      opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();
+      $('.response_throbber', $(this.el)).show();
+      if (isFileUpload) {
+        $('.request_url', $(this.el)).html('<pre></pre>');
+        $('.request_url pre', $(this.el)).text(this.invocationUrl);
+
+        opts.useJQuery = true;
+        map.parameterContentType = 'multipart/form-data';
+        this.map = map;
+        return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
+      } else {
+        this.map = map;
+        return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
+      }
+    }
+  },
+
+  getInputMap: function (form) {
+    var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2;
+    map = {};
+    ref1 = form.find('input');
+    for (l = 0, len = ref1.length; l < len; l++) {
+      o = ref1[l];
+      if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
+        map[o.name] = o.value;
+      }
+      if (o.type === 'file') {
+        map[o.name] = o.files[0];
+      }
+    }
+    ref2 = form.find('textarea');
+    for (m = 0, len1 = ref2.length; m < len1; m++) {
+      o = ref2[m];
+      val = this.getTextAreaValue(o);
+      if ((val !== null) && jQuery.trim(val).length > 0) {
+        map[o.name] = val;
+      }
+    }
+    ref3 = form.find('select');
+    for (n = 0, len2 = ref3.length; n < len2; n++) {
+      o = ref3[n];
+      val = this.getSelectedValue(o);
+      if ((val !== null) && jQuery.trim(val).length > 0) {
+        map[o.name] = val;
+      }
+    }
+    return map;
+  },
+
+  isFileUpload: function (form) {
+    var ref1, l, len, o;
+    var isFileUpload = false;
+    ref1 = form.find('input');
+    for (l = 0, len = ref1.length; l < len; l++) {
+      o = ref1[l];
+      if (o.type === 'file') {
+        isFileUpload = true;
+      }
+    }
+    return isFileUpload;
+  },
+
+  success: function(response, parent) {
+    parent.showCompleteStatus(response);
+  },
+
+  // wraps a jquery response as a shred response
+  wrap: function(data) {
+    var h, headerArray, headers, i, l, len, o;
+    headers = {};
+    headerArray = data.getAllResponseHeaders().split('\r');
+    for (l = 0, len = headerArray.length; l < len; l++) {
+      i = headerArray[l];
+      h = i.match(/^([^:]*?):(.*)$/);
+      if (!h) {
+        h = [];
+      }
+      h.shift();
+      if (h[0] !== void 0 && h[1] !== void 0) {
+        headers[h[0].trim()] = h[1].trim();
+      }
+    }
+    o = {};
+    o.content = {};
+    o.content.data = data.responseText;
+    o.headers = headers;
+    o.request = {};
+    o.request.url = this.invocationUrl;
+    o.status = data.status;
+    return o;
+  },
+
+  getSelectedValue: function(select) {
+    if (!select.multiple) {
+      return select.value;
+    } else {
+      var options = [];
+      for (var l = 0, len = select.options.length; l < len; l++) {
+        var opt = select.options[l];
+        if (opt.selected) {
+          options.push(opt.value);
+        }
+      }
+      if (options.length > 0) {
+        return options;
+      } else {
+        return null;
+      }
+    }
+  },
+
+  // handler for hide response link
+  hideResponse: function(e) {
+    if (e) { e.preventDefault(); }
+    $('.response', $(this.el)).slideUp();
+    $('.response_hider', $(this.el)).fadeOut();
+  },
+
+  // Show response from server
+  showResponse: function(response) {
+    var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');
+    $('.response_body', $(this.el)).html(_.escape(prettyJson));
+  },
+
+  // Show error from server
+  showErrorStatus: function(data, parent) {
+    parent.showStatus(data);
+  },
+
+  // show the status codes
+  showCompleteStatus: function(data, parent){
+    parent.showStatus(data);
+  },
+
+  // Adapted from http://stackoverflow.com/a/2893259/454004
+  // Note: directly ported from CoffeeScript
+  // TODO: Cleanup CoffeeScript artifacts
+  formatXml: function(xml) {
+    var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
+    reg = /(>)(<)(\/*)/g;
+    wsexp = /[ ]*(.*)[ ]+\n/g;
+    contexp = /(<.+>)(.+\n)/g;
+    xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
+    pad = 0;
+    formatted = '';
+    lines = xml.split('\n');
+    indent = 0;
+    lastType = 'other';
+    transitions = {
+      'single->single': 0,
+      'single->closing': -1,
+      'single->opening': 0,
+      'single->other': 0,
+      'closing->single': 0,
+      'closing->closing': -1,
+      'closing->opening': 0,
+      'closing->other': 0,
+      'opening->single': 1,
+      'opening->closing': 0,
+      'opening->opening': 1,
+      'opening->other': 1,
+      'other->single': 0,
+      'other->closing': -1,
+      'other->opening': 0,
+      'other->other': 0
+    };
+    fn = function(ln) {
+      var fromTo, j, key, padding, type, types, value;
+      types = {
+        single: Boolean(ln.match(/<.+\/>/)),
+        closing: Boolean(ln.match(/<\/.+>/)),
+        opening: Boolean(ln.match(/<[^!?].*>/))
+      };
+      type = ((function() {
+        var results;
+        results = [];
+        for (key in types) {
+          value = types[key];
+          if (value) {
+            results.push(key);
+          }
+        }
+        return results;
+      })())[0];
+      type = type === void 0 ? 'other' : type;
+      fromTo = lastType + '->' + type;
+      lastType = type;
+      padding = '';
+      indent += transitions[fromTo];
+      padding = ((function() {
+        var m, ref1, results;
+        results = [];
+        for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
+          results.push('  ');
+        }
+        return results;
+      })()).join('');
+      if (fromTo === 'opening->closing') {
+        formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
+      } else {
+        formatted += padding + ln + '\n';
+      }
+    };
+    for (l = 0, len = lines.length; l < len; l++) {
+      ln = lines[l];
+      fn(ln);
+    }
+    return formatted;
+  },
+
+  // puts the response data in UI
+  showStatus: function(response) {
+    var url, content;
+    if (response.content === undefined) {
+      content = response.data;
+      url = response.url;
+    } else {
+      content = response.content.data;
+      url = response.request.url;
+    }
+    var headers = response.headers;
+    content = jQuery.trim(content);
+
+    // if server is nice, and sends content-type back, we can use it
+    var contentType = null;
+    if (headers) {
+      contentType = headers['Content-Type'] || headers['content-type'];
+      if (contentType) {
+        contentType = contentType.split(';')[0].trim();
+      }
+    }
+    $('.response_body', $(this.el)).removeClass('json');
+    $('.response_body', $(this.el)).removeClass('xml');
+
+    var supportsAudioPlayback = function(contentType){
+      var audioElement = document.createElement('audio');
+      return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));
+    };
+
+    var pre;
+    var code;
+    if (!content) {
+      code = $('<code />').text('no content');
+      pre = $('<pre class="json" />').append(code);
+
+      // JSON
+    } else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
+      var json = null;
+      try {
+        json = JSON.stringify(JSON.parse(content), null, '  ');
+      } catch (_error) {
+        json = 'can\'t parse JSON.  Raw result:\n\n' + content;
+      }
+      code = $('<code />').text(json);
+      pre = $('<pre class="json" />').append(code);
+
+      // XML
+    } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
+      code = $('<code />').text(this.formatXml(content));
+      pre = $('<pre class="xml" />').append(code);
+
+      // HTML
+    } else if (contentType === 'text/html') {
+      code = $('<code />').html(_.escape(content));
+      pre = $('<pre class="xml" />').append(code);
+
+      // Plain Text
+    } else if (/text\/plain/.test(contentType)) {
+      code = $('<code />').text(content);
+      pre = $('<pre class="plain" />').append(code);
+
+
+      // Image
+    } else if (/^image\//.test(contentType)) {
+      pre = $('<img>').attr('src', url);
+
+      // Audio
+    } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
+      pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));
+
+      // Download
+    } else if (headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||
+        headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||
+        headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||
+        headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {
+
+      if ('Blob' in window) {
+        var type = contentType || 'text/html';
+        var blob = new Blob([content], {type: type});
+        var a = document.createElement('a');
+        var href = window.URL.createObjectURL(blob);
+        var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);
+        var download = [type, fileName, href].join(':');
+
+        // Use filename from response header
+        var disposition = headers['content-disposition'] || headers['Content-Disposition'];
+        if(typeof disposition !== 'undefined') {
+          var responseFilename = /filename=([^;]*);?/.exec(disposition);
+          if(responseFilename !== null && responseFilename.length > 1) {
+            download = responseFilename[1];
+          }
+        }
+
+        a.setAttribute('href', href);
+        a.setAttribute('download', download);
+        a.innerText = 'Download ' + fileName;
+
+        pre = $('<div/>').append(a);
+      } else {
+        pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');
+      }
+
+      // Location header based redirect download
+    } else if(headers.location || headers.Location) {
+      window.location = response.url;
+
+      // Anything else (CORS)
+    } else {
+      code = $('<code />').text(content);
+      pre = $('<pre class="json" />').append(code);
+    }
+    var response_body = pre;
+    $('.request_url', $(this.el)).html('<pre></pre>');
+    $('.request_url pre', $(this.el)).text(url);
+    $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');
+    $('.response_body', $(this.el)).html(response_body);
+    $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
+    $('.response', $(this.el)).slideDown();
+    $('.response_hider', $(this.el)).show();
+    $('.response_throbber', $(this.el)).hide();
+
+
+    // adds curl output
+    var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType});
+    curlCommand = curlCommand.replace('!', '&#33;');
+    $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>');
+
+    // only highlight the response if response is less than threshold, default state is highlight response
+    var opts = this.options.swaggerOptions;
+
+    if (opts.showRequestHeaders) {
+      var form = $('.sandbox', $(this.el)),
+          map = this.getInputMap(form),
+          requestHeaders = this.model.getHeaderParams(map);
+      delete requestHeaders['Content-Type'];
+      $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
+    }
+
+    var response_body_el = $('.response_body', $(this.el))[0];
+    // only highlight the response if response is less than threshold, default state is highlight response
+    if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold) {
+      return response_body_el;
+    } else {
+      return hljs.highlightBlock(response_body_el);
+    }
+  },
+
+  toggleOperationContent: function (event) {
+    var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));
+    if (elem.is(':visible')){
+      $.bbq.pushState('#/', 2);
+      event.preventDefault();
+      Docs.collapseOperation(elem);
+    } else {
+      Docs.expandOperation(elem);
+    }
+  },
+
+  getTextAreaValue: function(textArea) {
+    var param, parsed, result, i;
+    if (textArea.value === null || jQuery.trim(textArea.value).length === 0) {
+      return null;
+    }
+    param = this.getParamByName(textArea.name);
+    if (param && param.type && param.type.toLowerCase() === 'array') {
+      parsed = textArea.value.split('\n');
+      result = [];
+      for (i = 0; i < parsed.length; i++) {
+        if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) {
+          result.push(parsed[i]);
+        }
+      }
+      return result.length > 0 ? result : null;
+    } else {
+      return textArea.value;
+    }
+  },
+
+  showSnippet: function () {
+    var contentTypeEl = this.$('[name=responseContentType]');
+    var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml');
+    var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json');
+    var contentType;
+
+    if (!contentTypeEl.length) { return; }
+    contentType = contentTypeEl.val();
+
+    if (contentType.indexOf('xml') > -1) {
+      xmlSnippetEl.show();
+      jsonSnippetEl.hide();
+    } else {
+      jsonSnippetEl.show();
+      xmlSnippetEl.hide();
+    }
+  },
+
+  getParamByName: function(name) {
+    var i;
+    if (this.model.parameters) {
+      for(i = 0; i < this.model.parameters.length; i++) {
+        if (this.model.parameters[i].name === name) {
+          return this.model.parameters[i];
+        }
+      }
+    }
+    return null;
+  }
+
+});
+
+'use strict';
+
+SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
+  initialize: function  () {},
+
+  render: function(){
+    this.model.parameterContentTypeId = 'pct' + Math.random();
+    $(this.el).html(Handlebars.templates.parameter_content_type(this.model));
+    return this;
+  }
+
+});
+'use strict';
+
+SwaggerUi.Views.ParameterView = Backbone.View.extend({
+  events: {
+    'change [name=parameterContentType]' : 'toggleParameterSnippet'
+  },
+
+  initialize: function(){
+    Handlebars.registerHelper('isArray', function(param, opts) {
+      var paramType = param.type && param.type.toLowerCase();
+      if (paramType === 'array' || param.allowMultiple) {
+        return opts.fn(this);
+      } else {
+        return opts.inverse(this);
+      }
+    });
+  },
+
+  render: function() {
+    var type = this.model.type || this.model.dataType;
+    var modelType = this.model.modelSignature.type;
+    var modelDefinitions = this.model.modelSignature.definitions;
+    var schema = this.model.schema || {};
+    var consumes = this.model.consumes || [];
+    var sampleJSON, signatureView;
+
+
+    if (typeof type === 'undefined') {
+      if (schema.$ref) {
+        var ref = schema.$ref;
+        if (ref.indexOf('#/definitions/') === 0) {
+          type = ref.substring('#/definitions/'.length);
+        } else {
+          type = ref;
+        }
+      }
+    }
+
+    this.model.type = type;
+    this.model.paramType = this.model.in || this.model.paramType;
+    this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';
+    this.model.isFile = type && type.toLowerCase() === 'file';
+
+    // Allow for default === false
+    if(typeof this.model.default === 'undefined') {
+      this.model.default = this.model.defaultValue;
+    }
+
+    this.model.hasDefault = (typeof this.model.default !== 'undefined');
+    this.model.valueId = 'm' + this.model.name + Math.random();
+
+    if (this.model.allowableValues) {
+      this.model.isList = true;
+    }
+
+    var isXML = this.contains(consumes, 'xml');
+    var isJSON = isXML ? this.contains(consumes, 'json') : true;
+    sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions);
+
+    var template = this.template();
+    $(this.el).html(template(this.model));
+
+    var signatureModel = {
+      sampleJSON: isJSON ? sampleJSON : false,
+      sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false,
+      isParam: true,
+      signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions),
+      defaultRendering: this.model.defaultRendering
+    };
+
+    if (sampleJSON) {
+      signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});
+      $('.model-signature', $(this.el)).append(signatureView.render().el);
+    }
+    else {
+      $('.model-signature', $(this.el)).html(this.model.signature);
+    }
+
+    var isParam = false;
+
+    if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){
+      var $self = $(this.el);
+      this.model.jsonEditor =
+        /* global JSONEditor */
+        new JSONEditor($('.editor_holder', $self)[0],
+                       {schema: this.model.schema, startval : this.model.default,
+                        ajax:true,
+                        disable_properties:true,
+                        disable_edit_json:true,
+                        iconlib: 'swagger' });
+      // This is so that the signature can send back the sample to the json editor
+      // TODO: SignatureView should expose an event "onSampleClicked" instead
+      signatureModel.jsonEditor = this.model.jsonEditor;
+      $('.body-textarea', $self).hide();
+      $('.editor_holder', $self).show();
+      $('.parameter-content-type', $self)
+        .change(function(e){
+            if(e.target.value === 'application/xml'){
+              $('.body-textarea', $self).show();
+              $('.editor_holder', $self).hide();
+              this.model.jsonEditor.disable();
+            }
+            else {
+              $('.body-textarea', $self).hide();
+              $('.editor_holder', $self).show();
+              this.model.jsonEditor.enable();
+            }
+        });
+      }
+
+
+    if (this.model.isBody) {
+      isParam = true;
+    }
+
+    var contentTypeModel = {
+      isParam: isParam
+    };
+
+    contentTypeModel.consumes = this.model.consumes;
+
+    if (isParam) {
+      var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});
+      $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);
+      this.toggleParameterSnippet();
+    }
+
+    else {
+      var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});
+      $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
+      this.toggleResponseSnippet();
+    }
+
+    return this;
+  },
+
+  contains: function (consumes, type) {
+    return consumes.filter(function (val) {
+      if (val.indexOf(type) > -1) {
+        return true;
+      }
+    }).length;
+  },
+
+  toggleParameterSnippet: function () {
+    var contentType = this.$('[name=parameterContentType]').val();
+
+    this.toggleSnippet(contentType);
+  },
+
+  toggleResponseSnippet: function () {
+    var contentEl = this.$('[name=responseContentType]');
+
+    if (!contentEl.length) { return; }
+
+    this.toggleSnippet(contentEl.val());
+  },
+
+  toggleSnippet: function (type) {
+    type = type || '';
+    if (type.indexOf('xml') > -1) {
+      this.$('.snippet_xml').show();
+      this.$('.snippet_json').hide();
+    } else {
+      this.$('.snippet_json').show();
+      this.$('.snippet_xml').hide();
+    }
+  },
+
+  // Return an appropriate template based on if the parameter is a list, readonly, required
+  template: function(){
+    if (this.model.isList) {
+      return Handlebars.templates.param_list;
+    } else {
+      if (this.options.readOnly) {
+        if (this.model.required) {
+          return Handlebars.templates.param_readonly_required;
+        } else {
+          return Handlebars.templates.param_readonly;
+        }
+      } else {
+        if (this.model.required) {
+          return Handlebars.templates.param_required;
+        } else {
+          return Handlebars.templates.param;
+        }
+      }
+    }
+  }
+});
+
+'use strict';
+
+/* jshint -W122 */
+SwaggerUi.partials.signature = (function () {
+  // copy-pasted from swagger-js
+  var resolveSchema = function (schema) {
+    if (_.isPlainObject(schema.schema)) {
+      schema = resolveSchema(schema.schema);
+    }
+
+    return schema;
+  };
+
+  // copy-pasted from swagger-js
+  var simpleRef = function (name) {
+    if (typeof name === 'undefined') {
+      return null;
+    }
+
+    if (name.indexOf('#/definitions/') === 0) {
+      return name.substring('#/definitions/'.length);
+    } else {
+      return name;
+    }
+  };
+
+  // copy-pasted from swagger-js
+  var getInlineModel = function(inlineStr) {
+    if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) {
+      var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
+      var model = this.inlineModels[id];
+      return model;
+    }
+    // I'm returning null here, should I rather throw an error?
+    return null;
+  };
+
+  // copy-pasted from swagger-js
+  var formatXml = function(xml) {
+    var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
+    reg = /(>)(<)(\/*)/g;
+    wsexp = /[ ]*(.*)[ ]+\n/g;
+    contexp = /(<.+>)(.+\n)/g;
+    xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
+    pad = 0;
+    formatted = '';
+    lines = xml.split('\n');
+    indent = 0;
+    lastType = 'other';
+    transitions = {
+      'single->single': 0,
+      'single->closing': -1,
+      'single->opening': 0,
+      'single->other': 0,
+      'closing->single': 0,
+      'closing->closing': -1,
+      'closing->opening': 0,
+      'closing->other': 0,
+      'opening->single': 1,
+      'opening->closing': 0,
+      'opening->opening': 1,
+      'opening->other': 1,
+      'other->single': 0,
+      'other->closing': -1,
+      'other->opening': 0,
+      'other->other': 0
+    };
+    fn = function(ln) {
+      var fromTo, j, key, padding, type, types, value;
+      types = {
+        single: Boolean(ln.match(/<.+\/>/)),
+        closing: Boolean(ln.match(/<\/.+>/)),
+        opening: Boolean(ln.match(/<[^!?].*>/))
+      };
+      type = ((function() {
+        var results;
+        results = [];
+        for (key in types) {
+          value = types[key];
+          if (value) {
+            results.push(key);
+          }
+        }
+        return results;
+      })())[0];
+      type = type === void 0 ? 'other' : type;
+      fromTo = lastType + '->' + type;
+      lastType = type;
+      padding = '';
+      indent += transitions[fromTo];
+      padding = ((function() {
+        var m, ref1, results;
+        results = [];
+        for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
+          results.push('  ');
+        }
+        return results;
+      })()).join('');
+      if (fromTo === 'opening->closing') {
+        formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
+      } else {
+        formatted += padding + ln + '\n';
+      }
+    };
+    for (l = 0, len = lines.length; l < len; l++) {
+      ln = lines[l];
+      fn(ln);
+    }
+    return formatted;
+  };
+
+  // copy-pasted from swagger-js
+  var getModelSignature = function (name, schema, models, modelPropertyMacro) {
+    var strongOpen = '<span class="strong">';
+    var strongClose = '</span>';
+
+    var optionHtml = function (label, value) {
+      return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+    };
+
+
+    // Allow for ignoring the 'name' argument.... shifting the rest
+    if(_.isObject(arguments[0])) {
+      name = void 0;
+      schema = arguments[0];
+      models = arguments[1];
+      modelPropertyMacro = arguments[2];
+    }
+
+    models = models || {};
+
+    // Resolve the schema (Handle nested schemas)
+    schema = resolveSchema(schema);
+
+    // Return for empty object
+    if(_.isEmpty(schema)) {
+      return strongOpen + 'Empty' + strongClose;
+    }
+
+    // Dereference $ref from 'models'
+    if(typeof schema.$ref === 'string') {
+      name = simpleRef(schema.$ref);
+      schema = models[name];
+      if(typeof schema === 'undefined')
+      {
+        return strongOpen + name + ' is not defined!' + strongClose;
+      }
+    }
+
+    if(typeof name !== 'string') {
+      name = schema.title || 'Inline Model';
+    }
+
+    // If we are a Model object... adjust accordingly
+    if(schema.definition) {
+      schema = schema.definition;
+    }
+
+    if(typeof modelPropertyMacro !== 'function') {
+      modelPropertyMacro = function(prop){
+        return (prop || {}).default;
+      };
+    }
+
+    var references = {};
+    var seenModels = [];
+    var inlineModels = 0;
+
+    // Generate current HTML
+    var html = processModel(schema, name);
+
+    // Generate references HTML
+    while (_.keys(references).length > 0) {
+      /* jshint ignore:start */
+      _.forEach(references, function (schema, name) {
+        var seenModel = _.indexOf(seenModels, name) > -1;
+
+        delete references[name];
+
+        if (!seenModel) {
+          seenModels.push(name);
+
+          html += '<br />' + processModel(schema, name);
+        }
+      });
+      /* jshint ignore:end */
+    }
+
+    return html;
+
+
+    function addReference(schema, name, skipRef) {
+      var modelName = name;
+      var model;
+
+      if (schema.$ref) {
+        modelName = schema.title || simpleRef(schema.$ref);
+        model = models[simpleRef(schema.$ref)];
+      } else if (_.isUndefined(name)) {
+        modelName = schema.title || 'Inline Model ' + (++inlineModels);
+        model = {definition: schema};
+      }
+
+      if (skipRef !== true) {
+        references[modelName] = _.isUndefined(model) ? {} : model.definition;
+      }
+
+      return modelName;
+    }
+
+    function primitiveToHTML(schema) {
+      var html = '<span class="propType">';
+      var type = schema.type || 'object';
+
+      if (schema.$ref) {
+        html += addReference(schema, simpleRef(schema.$ref));
+      } else if (type === 'object') {
+        if (!_.isUndefined(schema.properties)) {
+          html += addReference(schema);
+        } else {
+          html += 'object';
+        }
+      } else if (type === 'array') {
+        html += 'Array[';
+
+        if (_.isArray(schema.items)) {
+          html += _.map(schema.items, addReference).join(',');
+        } else if (_.isPlainObject(schema.items)) {
+          if (_.isUndefined(schema.items.$ref)) {
+            if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
+              html += schema.items.type;
+            } else {
+              html += addReference(schema.items);
+            }
+          } else {
+            html += addReference(schema.items, simpleRef(schema.items.$ref));
+          }
+        } else {
+          console.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
+          html += 'object';
+        }
+
+        html += ']';
+      } else {
+        html += schema.type;
+      }
+
+      html += '</span>';
+
+      return html;
+    }
+
+    function primitiveToOptionsHTML(schema, html) {
+      var options = '';
+      var type = schema.type || 'object';
+      var isArray = type === 'array';
+
+      if (isArray) {
+        if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
+          type = schema.items.type;
+        } else {
+          type = 'object';
+        }
+      }
+
+      if (!_.isUndefined(schema.default)) {
+        options += optionHtml('Default', schema.default);
+      }
+
+      switch (type) {
+      case 'string':
+        if (schema.minLength) {
+          options += optionHtml('Min. Length', schema.minLength);
+        }
+
+        if (schema.maxLength) {
+          options += optionHtml('Max. Length', schema.maxLength);
+        }
+
+        if (schema.pattern) {
+          options += optionHtml('Reg. Exp.', schema.pattern);
+        }
+        break;
+      case 'integer':
+      case 'number':
+        if (schema.minimum) {
+          options += optionHtml('Min. Value', schema.minimum);
+        }
+
+        if (schema.exclusiveMinimum) {
+          options += optionHtml('Exclusive Min.', 'true');
+        }
+
+        if (schema.maximum) {
+          options += optionHtml('Max. Value', schema.maximum);
+        }
+
+        if (schema.exclusiveMaximum) {
+          options += optionHtml('Exclusive Max.', 'true');
+        }
+
+        if (schema.multipleOf) {
+          options += optionHtml('Multiple Of', schema.multipleOf);
+        }
+
+        break;
+      }
+
+      if (isArray) {
+        if (schema.minItems) {
+          options += optionHtml('Min. Items', schema.minItems);
+        }
+
+        if (schema.maxItems) {
+          options += optionHtml('Max. Items', schema.maxItems);
+        }
+
+        if (schema.uniqueItems) {
+          options += optionHtml('Unique Items', 'true');
+        }
+
+        if (schema.collectionFormat) {
+          options += optionHtml('Coll. Format', schema.collectionFormat);
+        }
+      }
+
+      if (_.isUndefined(schema.items)) {
+        if (_.isArray(schema.enum)) {
+          var enumString;
+
+          if (type === 'number' || type === 'integer') {
+            enumString = schema.enum.join(', ');
+          } else {
+            enumString = '"' + schema.enum.join('", "') + '"';
+          }
+
+          options += optionHtml('Enum', enumString);
+        }
+      }
+
+      if (options.length > 0) {
+        html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
+      }
+
+      return html;
+    }
+
+    function processModel(schema, name) {
+      var type = schema.type || 'object';
+      var isArray = schema.type === 'array';
+      var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
+      var contents;
+
+      if (name) {
+        seenModels.push(name);
+      }
+
+      if (isArray) {
+        if (_.isArray(schema.items)) {
+          html += '<div>' + _.map(schema.items, function (item) {
+            var type = item.type || 'object';
+
+            if (_.isUndefined(item.$ref)) {
+              if (_.indexOf(['array', 'object'], type) > -1) {
+                if (type === 'object' && _.isUndefined(item.properties)) {
+                  return 'object';
+                } else {
+                  return addReference(item);
+                }
+              } else {
+                return primitiveToOptionsHTML(item, type);
+              }
+            } else {
+              return addReference(item, simpleRef(item.$ref));
+            }
+          }).join(',</div><div>');
+        } else if (_.isPlainObject(schema.items)) {
+          if (_.isUndefined(schema.items.$ref)) {
+            if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
+              if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
+                html += '<div>object</div>';
+              } else {
+                html += '<div>' + addReference(schema.items) + '</div>';
+              }
+            } else {
+              html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
+            }
+          } else {
+            html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>';
+          }
+        } else {
+          console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+          html += '<div>object</div>';
+        }
+      } else {
+        if (schema.$ref) {
+          html += '<div>' + addReference(schema, name) + '</div>';
+        } else if (type === 'object') {
+          if (_.isPlainObject(schema.properties)) {
+            contents = _.map(schema.properties, function (property, name) {
+              var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
+              var cProperty = _.cloneDeep(property);
+
+              var requiredClass = propertyIsRequired ? 'required' : '';
+              var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
+              var model;
+              var propDescription;
+
+              // Allow macro to set the default value
+              cProperty.default = modelPropertyMacro(cProperty);
+
+              // Resolve the schema (Handle nested schemas)
+              cProperty = resolveSchema(cProperty);
+
+              propDescription = property.description || cProperty.description;
+
+              // We need to handle property references to primitives (Issue 339)
+              if (!_.isUndefined(cProperty.$ref)) {
+                model = models[simpleRef(cProperty.$ref)];
+
+                if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
+                  // Use referenced schema
+                  cProperty = resolveSchema(model.definition);
+                }
+              }
+
+              html += primitiveToHTML(cProperty);
+
+              if(!propertyIsRequired) {
+                html += ', <span class="propOptKey">optional</span>';
+              }
+
+              if(property.readOnly) {
+                  html += ', <span class="propReadOnly">read only</span>';
+              }
+
+              html += ')';
+
+              if (!_.isUndefined(propDescription)) {
+                html += ': ' + '<span class="propDesc">' + propDescription + '</span>';
+              }
+
+              if (cProperty.enum) {
+                html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';
+              }
+
+              return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
+            }).join(',</div>');
+          }
+
+          if (contents) {
+            html += contents + '</div>';
+          }
+        } else {
+          html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
+        }
+      }
+
+      return html + strongOpen + (isArray ? ']' : '}') + strongClose;
+    }
+
+  };
+
+  // copy-pasted from swagger-js
+  var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
+    // Resolve the schema (Handle nested schemas)
+    schema = resolveSchema(schema);
+
+    if(typeof modelPropertyMacro !== 'function') {
+      modelPropertyMacro = function(prop){
+        return (prop || {}).default;
+      };
+    }
+
+    modelsToIgnore= modelsToIgnore || {};
+
+    var type = schema.type || 'object';
+    var format = schema.format;
+    var model;
+    var output;
+
+    if (!_.isUndefined(schema.example)) {
+      output = schema.example;
+    } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
+      output = schema.enum[0];
+    }
+
+    if (_.isUndefined(output)) {
+      if (schema.$ref) {
+        model = models[simpleRef(schema.$ref)];
+
+        if (!_.isUndefined(model)) {
+          if (_.isUndefined(modelsToIgnore[model.name])) {
+            modelsToIgnore[model.name] = model;
+            output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
+            delete modelsToIgnore[model.name];
+          } else {
+            if (model.type === 'array') {
+              output = [];
+            } else {
+              output = {};
+            }
+          }
+        }
+      } else if (!_.isUndefined(schema.default)) {
+        output = schema.default;
+      } else if (type === 'string') {
+        if (format === 'date-time') {
+          output = new Date().toISOString();
+        } else if (format === 'date') {
+          output = new Date().toISOString().split('T')[0];
+        } else {
+          output = 'string';
+        }
+      } else if (type === 'integer') {
+        output = 0;
+      } else if (type === 'number') {
+        output = 0.0;
+      } else if (type === 'boolean') {
+        output = true;
+      } else if (type === 'object') {
+        output = {};
+
+        _.forEach(schema.properties, function (property, name) {
+          var cProperty = _.cloneDeep(property);
+
+          // Allow macro to set the default value
+          cProperty.default = modelPropertyMacro(property);
+
+          output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
+        });
+      } else if (type === 'array') {
+        output = [];
+
+        if (_.isArray(schema.items)) {
+          _.forEach(schema.items, function (item) {
+            output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
+          });
+        } else if (_.isPlainObject(schema.items)) {
+          output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
+        } else if (_.isUndefined(schema.items)) {
+          output.push({});
+        } else {
+          console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+        }
+      }
+    }
+
+    return output;
+  };
+
+  // copy-pasted from swagger-js
+  var createJSONSample = function (value, modelsToIgnore) {
+    modelsToIgnore = modelsToIgnore || {};
+
+    modelsToIgnore[value.name] = value;
+
+    // Response support
+    if (value.examples && _.isPlainObject(value.examples) && value.examples['application/json']) {
+      value.definition.example = value.examples['application/json'];
+
+      if (_.isString(value.definition.example)) {
+        value.definition.example = jsyaml.safeLoad(value.definition.example);
+      }
+    } else if (!value.definition.example) {
+      value.definition.example = value.examples;
+    }
+
+    return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);
+  };
+
+  // copy-pasted from swagger-js
+  var getParameterModelSignature = function (type, definitions) {
+      var isPrimitive, listType;
+
+      if (type instanceof Array) {
+        listType = true;
+        type = type[0];
+      }
+
+      // Convert undefined to string of 'undefined'
+      if (typeof type === 'undefined') {
+        type = 'undefined';
+        isPrimitive = true;
+
+      } else if (definitions[type]){
+        // a model def exists?
+        type = definitions[type]; /* Model */
+        isPrimitive = false;
+
+      } else if (getInlineModel(type)) {
+        type = getInlineModel(type); /* Model */
+        isPrimitive = false;
+
+      } else {
+        // We default to primitive
+        isPrimitive = true;
+      }
+
+      if (isPrimitive) {
+        if (listType) {
+          return 'Array[' + type + ']';
+        } else {
+          return type.toString();
+        }
+      } else {
+        if (listType) {
+          return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']';
+        } else {
+          return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro);
+        }
+      }
+  };
+
+  // copy-pasted from swagger-js
+  var createParameterJSONSample = function (type, models) {
+    var listType, sampleJson, innerType;
+    models = models || {};
+
+    listType = (type instanceof Array);
+    innerType = listType ? type[0] : type;
+
+    if(models[innerType]) {
+      sampleJson = createJSONSample(models[innerType]);
+    } else if (getInlineModel(innerType)){
+      sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct
+    }
+
+
+    if (sampleJson) {
+      sampleJson = listType ? [sampleJson] : sampleJson;
+
+      if (typeof sampleJson === 'string') {
+        return sampleJson;
+      } else if (_.isObject(sampleJson)) {
+        var t = sampleJson;
+
+        if (sampleJson instanceof Array && sampleJson.length > 0) {
+          t = sampleJson[0];
+        }
+
+        if (t.nodeName && typeof t === 'Node') {
+          var xmlString = new XMLSerializer().serializeToString(t);
+
+          return formatXml(xmlString);
+        } else {
+          return JSON.stringify(sampleJson, null, 2);
+        }
+      } else {
+        return sampleJson;
+      }
+    }
+  };
+
+  var wrapTag = function (name, value, attrs) {
+    var str, attributes;
+
+    attrs = attrs || [];
+
+    attributes = attrs.map(function (attr) {
+      return ' ' + attr.name + '="' + attr.value + '"';
+    }).join('');
+
+    if (!name) {
+      return getErrorMessage('Node name is not provided');
+    }
+
+    str = [
+      '<', name,
+      attributes,
+      '>',
+      value,
+      '</', name, '>'
+    ];
+
+    return str.join('');
+  };
+
+  var getName = function (name, xml) {
+    var result = name || '';
+
+    xml = xml || {};
+
+    if (xml.name) {
+      result = xml.name;
+    }
+
+    if (xml.prefix) {
+      result = xml.prefix + ':' + result;
+    }
+
+    return result;
+  };
+
+  var getNamespace = function (xml) {
+    var namespace = '';
+    var name = 'xmlns';
+
+    xml = xml || {};
+
+    if (xml.namespace) {
+      namespace = xml.namespace;
+    } else {
+      return namespace;
+    }
+
+    if (xml.prefix) {
+      name += ':' + xml.prefix;
+    }
+
+    return {
+      name: name,
+      value: namespace
+    };
+  };
+
+  var createArrayXML = function (descriptor) {
+    var name = descriptor.name;
+    var config = descriptor.config;
+    var definition = descriptor.definition;
+    var models = descriptor.models;
+    var value;
+    var items = definition.items;
+    var xml = definition.xml || {};
+
+    if (!items) { return getErrorMessage(); }
+
+    value = createSchemaXML(name, items, models, config);
+
+    xml = xml || {};
+
+    if (xml.wrapped) {
+      value = wrapTag(name, value);
+    }
+
+    return value;
+  };
+
+  var getPrimitiveSignature = function (schema) {
+    var type, items;
+
+    schema = schema || {};
+    items = schema.items || {};
+    type = schema.type || '';
+
+    switch (type) {
+      case 'object': return 'Object is not a primitive';
+      case 'array' : return 'Array[' + (items.format || items.type) + ']';
+      default: return schema.format || type;
+    }
+  };
+
+  var createPrimitiveXML = function (descriptor) {
+    var name = descriptor.name;
+    var definition = descriptor.definition;
+    var primitivesMap = {
+      'string': {
+        'date': new Date(1).toISOString().split('T')[0],
+        'date-time' : new Date(1).toISOString(),
+        'default': 'string'
+      },
+      'integer': {
+        'default': 1
+      },
+      'number': {
+        'default': 1.1
+      },
+      'boolean': {
+        'default': true
+      }
+    };
+    var type = definition.type;
+    var format = definition.format;
+    var xml = definition.xml || {};
+    var namespace = getNamespace(xml);
+    var attributes = [];
+    var value;
+
+    if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); }
+
+    if (_.isArray(definition.enum)){
+      value = definition.enum[0];
+    } else {
+      value = definition.example || primitivesMap[type][format] || primitivesMap[type].default;
+    }
+
+    if (xml.attribute) {
+      return {name: name, value: value};
+    }
+
+    if (namespace) {
+      attributes.push(namespace);
+    }
+
+    return wrapTag(name, value, attributes);
+  };
+
+  function createObjectXML (descriptor) {
+    var name = descriptor.name;
+    var definition = descriptor.definition;
+    var config = descriptor.config;
+    var models = descriptor.models;
+    var isParam = descriptor.config.isParam;
+    var serializedProperties;
+    var attrs = [];
+    var properties = definition.properties;
+    var additionalProperties = definition.additionalProperties;
+    var xml = definition.xml;
+    var namespace = getNamespace(xml);
+
+    if (namespace) {
+      attrs.push(namespace);
+    }
+
+    if (!properties && !additionalProperties) { return getErrorMessage(); }
+
+    properties = properties || {};
+
+    serializedProperties = _.map(properties, function (prop, key) {
+      var xml, result;
+
+      if (isParam && prop.readOnly) {
+        return '';
+      }
+
+      xml = prop.xml || {};
+      result = createSchemaXML(key, prop, models, config);
+
+      if (xml.attribute) {
+        attrs.push(result);
+        return '';
+      }
+
+      return result;
+    }).join('');
+
+    if (additionalProperties) {
+      serializedProperties += '<!-- additional elements allowed -->';
+    }
+
+    return wrapTag(name, serializedProperties, attrs);
+  }
+
+  function getInfiniteLoopMessage (name) {
+    return '<!-- Infinite loop $ref:' + name + ' -->';
+  }
+
+  function getErrorMessage (details) {
+    details = details ? ': ' + details : '';
+    return '<!-- invalid XML' + details + ' -->';
+  }
+
+  function createSchemaXML (name, definition, models, config) {
+    var $ref = _.isObject(definition) ? definition.$ref : null;
+    var output, index;
+    config = config || {};
+    config.modelsToIgnore = config.modelsToIgnore || [];
+    var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)
+        : getDescriptor(name, definition, models, config);
+
+    if (!descriptor) {
+      return getErrorMessage();
+    }
+
+    switch (descriptor.type) {
+      case 'array':
+        output = createArrayXML(descriptor); break;
+      case 'object':
+        output = createObjectXML(descriptor); break;
+      case 'loop':
+        output = getInfiniteLoopMessage(descriptor.name); break;
+      default:
+        output = createPrimitiveXML(descriptor);
+    }
+
+    if ($ref) {
+      index = config.modelsToIgnore.indexOf($ref);
+      if (index > -1) {
+        config.modelsToIgnore.splice(index, 1);
+      }
+    }
+
+    return output;
+  }
+
+  function Descriptor (name, type, definition, models, config) {
+    if (arguments.length < 4) {
+      throw new Error();
+    }
+
+    this.config = config || {};
+    this.config.modelsToIgnore = this.config.modelsToIgnore || [];
+    this.name = getName(name, definition.xml);
+    this.definition = definition;
+    this.models = models;
+    this.type = type;
+  }
+
+  function getDescriptorByRef($ref, name, models, config) {
+    var modelType = simpleRef($ref);
+    var model = models[modelType] || {};
+    var type = model.definition && model.definition.type ? model.definition.type : 'object';
+    name = name || model.name;
+
+    if (config.modelsToIgnore.indexOf($ref) > -1) {
+      type = 'loop';
+      name = modelType;
+    } else {
+      config.modelsToIgnore.push($ref);
+    }
+
+    if (!model.definition) {
+      return null;
+    }
+
+    return new Descriptor(name, type, model.definition, models, config);
+  }
+
+  function getDescriptor (name, definition, models, config){
+    var type = definition.type || 'object';
+
+    if (!definition) {
+      return null;
+    }
+
+    return new Descriptor(name, type, definition, models, config);
+  }
+
+  function createXMLSample (name, definition, models, isParam) {
+    var prolog = '<?xml version="1.0"?>';
+
+    return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } ));
+  }
+
+  return {
+      getModelSignature: getModelSignature,
+      createJSONSample: createJSONSample,
+      getParameterModelSignature: getParameterModelSignature,
+      createParameterJSONSample: createParameterJSONSample,
+      createSchemaXML: createSchemaXML,
+      createXMLSample: createXMLSample,
+      getPrimitiveSignature: getPrimitiveSignature
+  };
+
+})();
+
+'use strict';
+
+SwaggerUi.Views.PopupView = Backbone.View.extend({
+    events: {
+        'click .api-popup-cancel': 'cancelClick'
+    },
+
+    template: Handlebars.templates.popup,
+    className: 'api-popup-dialog',
+
+    selectors: {
+        content: '.api-popup-content',
+        main   : '#swagger-ui-container'
+    },
+
+    initialize: function(){
+        this.$el.html(this.template(this.model));
+    },
+
+    render: function () {
+        this.$(this.selectors.content).append(this.model.content);
+        $(this.selectors.main).first().append(this.el);
+        this.showPopup();
+
+        return this;
+    },
+
+    showPopup: function () {
+        this.$el.show();
+    },
+
+    cancelClick: function () {
+        this.remove();
+    }
+
+});
+
+'use strict';
+
+SwaggerUi.Views.ResourceView = Backbone.View.extend({
+  initialize: function(opts) {
+    opts = opts || {};
+    this.router = opts.router;
+    this.auths = opts.auths;
+    if ('' === this.model.description) {
+      this.model.description = null;
+    }
+    if (this.model.description) {
+      this.model.summary = this.model.description;
+    }
+  },
+
+  render: function(){
+    var methods = {};
+
+
+    $(this.el).html(Handlebars.templates.resource(this.model));
+
+    // Render each operation
+    for (var i = 0; i < this.model.operationsArray.length; i++) {
+      var operation = this.model.operationsArray[i];
+      var counter = 0;
+      var id = operation.nickname;
+
+      while (typeof methods[id] !== 'undefined') {
+        id = id + '_' + counter;
+        counter += 1;
+      }
+
+      methods[id] = operation;
+
+      operation.nickname = id;
+      operation.parentId = this.model.id;
+      operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation
+      this.addOperation(operation);
+    }
+
+    $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));
+    $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));
+    $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));
+
+    return this;
+  },
+
+  addOperation: function(operation) {
+
+    operation.number = this.number;
+
+    // Render an operation and add it to operations li
+    var operationView = new SwaggerUi.Views.OperationView({
+      model: operation,
+      router: this.router,
+      tagName: 'li',
+      className: 'endpoint',
+      swaggerOptions: this.options.swaggerOptions,
+      auths: this.auths
+    });
+
+    $('.endpoints', $(this.el)).append(operationView.render().el);
+
+    this.number++;
+
+  },
+  // Generic Event handler (`Docs` is global)
+
+
+  callDocs: function(fnName, e) {
+    e.preventDefault();
+    Docs[fnName](e.currentTarget.getAttribute('data-id'));
+  }
+});
+'use strict';
+
+SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({
+  initialize: function(){},
+
+  render: function(){
+    this.model.responseContentTypeId = 'rct' + Math.random();
+    $(this.el).html(Handlebars.templates.response_content_type(this.model));
+    return this;
+  }
+});
+'use strict';
+
+SwaggerUi.Views.SignatureView = Backbone.View.extend({
+  events: {
+    'click a.description-link'       : 'switchToDescription',
+    'click a.snippet-link'           : 'switchToSnippet',
+    'mousedown .snippet_json'          : 'jsonSnippetMouseDown',
+    'mousedown .snippet_xml'          : 'xmlSnippetMouseDown'
+  },
+
+  initialize: function () {
+  },
+
+  render: function(){
+
+    $(this.el).html(Handlebars.templates.signature(this.model));
+
+    if (this.model.defaultRendering === 'model') {
+      this.switchToDescription();
+    } else {
+      this.switchToSnippet();
+    }
+
+    return this;
+  },
+
+  // handler for show signature
+  switchToDescription: function(e){
+    if (e) { e.preventDefault(); }
+
+    $('.snippet', $(this.el)).hide();
+    $('.description', $(this.el)).show();
+    $('.description-link', $(this.el)).addClass('selected');
+    $('.snippet-link', $(this.el)).removeClass('selected');
+  },
+
+  // handler for show sample
+  switchToSnippet: function(e){
+    if (e) { e.preventDefault(); }
+
+    $('.snippet', $(this.el)).show();
+    $('.description', $(this.el)).hide();
+    $('.snippet-link', $(this.el)).addClass('selected');
+    $('.description-link', $(this.el)).removeClass('selected');
+  },
+
+  // handler for snippet to text area
+  snippetToTextArea: function(val) {
+    var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));
+
+    // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value"
+    if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) {
+      textArea.val(val);
+      // TODO move this code outside of the view and expose an event instead
+      if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){
+        this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON));
+      }
+    }
+  },
+
+  jsonSnippetMouseDown: function (e) {
+    if (this.model.isParam) {
+      if (e) { e.preventDefault(); }
+
+      this.snippetToTextArea(this.model.sampleJSON);
+    }
+  },
+
+  xmlSnippetMouseDown: function (e) {
+    if (this.model.isParam) {
+      if (e) { e.preventDefault(); }
+
+      this.snippetToTextArea(this.model.sampleXML);
+    }
+  }
+});
+'use strict';
+
+SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
+  initialize: function (opts) {
+    this.options = opts || {};
+    this.router = this.options.router;
+  },
+
+  render: function(){
+    var responseModel, responseModelView;
+    var value = this.router.api.models[this.model.responseModel];
+    $(this.el).html(Handlebars.templates.status_code(this.model));
+
+    if (this.router.api.models.hasOwnProperty(this.model.responseModel)) {
+      responseModel = {
+        sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2),
+        sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false,
+        isParam: false,
+        signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models),
+        defaultRendering: this.model.defaultRendering
+      };
+    } else {
+      responseModel = {
+        signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)
+      };
+    }
+
+    responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});
+    $('.model-signature', this.$el).append(responseModelView.render().el);
+    return this;
+  }
+});}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/icd/swagger-ui.min.js b/src/main/resources/META-INF/resources/icd/swagger-ui.min.js
new file mode 100644 (file)
index 0000000..2c56818
--- /dev/null
@@ -0,0 +1,9 @@
+(function(){function e(){e.history=e.history||[],e.history.push(arguments),this.console&&console.log(Array.prototype.slice.call(arguments)[0])}this.Handlebars=this.Handlebars||{},this.Handlebars.templates=this.Handlebars.templates||{},this.Handlebars.templates.apikey_auth=Handlebars.template({1:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'                <span class="key_auth__value">'+s((r=null!=(r=t.value||(null!=e?e.value:e))?r:o,typeof r===a?r.call(e,{name:"value",hash:{},data:i}):r))+"</span>\n"},3:function(e,t,n,i){return'                <input placeholder="api_key" class="auth_input input_apiKey_entry" name="apiKey" type="text"/>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='<div class="key_input_container">\n    <h3 class="auth__title">Api key authorization</h3>\n    <div class="auth__description">'+l((a=null!=(a=t.description||(null!=e?e.description:e))?a:s,typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a))+'</div>\n    <div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">name:</span>\n            <span class="key_auth__value">'+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+'</span>\n        </div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">in:</span>\n            <span class="key_auth__value">'+l((a=null!=(a=t["in"]||(null!=e?e["in"]:e))?a:s,typeof a===o?a.call(e,{name:"in",hash:{},data:i}):a))+'</span>\n        </div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">value:</span>\n';return r=t["if"].call(e,null!=e?e.isLogout:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(3,i),data:i}),null!=r&&(u+=r),u+"        </div>\n    </div>\n</div>\n"},useData:!0}),this.Handlebars.templates.auth_button_operation=Handlebars.template({1:function(e,t,n,i){return"        authorize__btn_operation_login\n"},3:function(e,t,n,i){return"        authorize__btn_operation_logout\n"},5:function(e,t,n,i){var r,a='        <ul class="authorize-scopes">\n';return r=t.each.call(e,null!=e?e.scopes:e,{name:"each",hash:{},fn:this.program(6,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a+"        </ul>\n"},6:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'                <li class="authorize__scope" title="'+s((r=null!=(r=t.description||(null!=e?e.description:e))?r:o,typeof r===a?r.call(e,{name:"description",hash:{},data:i}):r))+'">'+s((r=null!=(r=t.scope||(null!=e?e.scope:e))?r:o,typeof r===a?r.call(e,{name:"scope",hash:{},data:i}):r))+"</li>\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a='<div class="authorize__btn authorize__btn_operation\n';return r=t["if"].call(e,null!=e?e.isLogout:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(3,i),data:i}),null!=r&&(a+=r),a+='">\n',r=t["if"].call(e,null!=e?e.scopes:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a+"</div>\n"},useData:!0}),this.Handlebars.templates.auth_button=Handlebars.template({compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){return"<a class='authorize__btn' href=\"#\">Authorize</a>\n"},useData:!0}),this.Handlebars.templates.auth_view=Handlebars.template({1:function(e,t,n,i){return'            <button type="button" class="auth__button auth_submit__button" data-sw-translate>Authorize</button>\n'},3:function(e,t,n,i){return'            <button type="button" class="auth__button auth_logout__button" data-sw-translate>Logout</button>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a='<div class="auth_container">\n\n    <div class="auth_inner"></div>\n    <div class="auth_submit">\n';return r=t.unless.call(e,null!=e?e.isLogout:e,{name:"unless",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(a+=r),r=t["if"].call(e,null!=e?e.isAuthorized:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a+"    </div>\n\n</div>\n"},useData:!0}),this.Handlebars.templates.basic_auth=Handlebars.template({1:function(e,t,n,i){return" - authorized"},3:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'                <span class="basic_auth__value">'+s((r=null!=(r=t.username||(null!=e?e.username:e))?r:o,typeof r===a?r.call(e,{name:"username",hash:{},data:i}):r))+"</span>\n"},5:function(e,t,n,i){return'                <input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>\n'},7:function(e,t,n,i){return'            <div class="auth_label">\n                <span class="basic_auth__label" data-sw-translate>password:</span>\n                <input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/></label>\n            </div>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication";return r=t["if"].call(e,null!=e?e.isLogout:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+='</h3>\n    <form class="basic_input_container">\n        <div class="auth__description">'+l((a=null!=(a=t.description||(null!=e?e.description:e))?a:s,typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a))+'</div>\n        <div class="auth_label">\n            <span class="basic_auth__label" data-sw-translate>username:</span>\n',r=t["if"].call(e,null!=e?e.isLogout:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.program(5,i),data:i}),null!=r&&(u+=r),u+="        </div>\n",r=t.unless.call(e,null!=e?e.isLogout:e,{name:"unless",hash:{},fn:this.program(7,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"    </form>\n</div>\n"},useData:!0}),this.Handlebars.templates.content_type=Handlebars.template({1:function(e,t,n,i){var r,a="";return r=t.each.call(e,null!=e?e.produces:e,{name:"each",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a},2:function(e,t,n,i){var r=this.lambda,a=this.escapeExpression;return'   <option value="'+a(r(e,e))+'">'+a(r(e,e))+"</option>\n"},4:function(e,t,n,i){return'  <option value="application/json">application/json</option>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='<label data-sw-translate for="'+l((a=null!=(a=t.contentTypeId||(null!=e?e.contentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"contentTypeId",hash:{},data:i}):a))+'">Response Content Type</label>\n<select name="contentType" id="'+l((a=null!=(a=t.contentTypeId||(null!=e?e.contentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"contentTypeId",hash:{},data:i}):a))+'">\n';return r=t["if"].call(e,null!=e?e.produces:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(4,i),data:i}),null!=r&&(u+=r),u+"</select>\n"},useData:!0}),$(function(){$.fn.vAlign=function(){return this.each(function(){var e=$(this).height(),t=$(this).parent().height(),n=(t-e)/2;$(this).css("margin-top",n)})},$.fn.stretchFormtasticInputWidthToParent=function(){return this.each(function(){var e=$(this).closest("form").innerWidth(),t=parseInt($(this).closest("form").css("padding-left"),10)+parseInt($(this).closest("form").css("padding-right"),10),n=parseInt($(this).css("padding-left"),10)+parseInt($(this).css("padding-right"),10);$(this).css("width",e-t-n)})},$("form.formtastic li.string input, form.formtastic textarea").stretchFormtasticInputWidthToParent(),$("ul.downplayed li div.content p").vAlign(),$("form.sandbox").submit(function(){var e=!0;return $(this).find("input.required").each(function(){$(this).removeClass("error"),""===$(this).val()&&($(this).addClass("error"),$(this).wiggle(),e=!1)}),e})}),Function.prototype.bind&&console&&"object"==typeof console.log&&["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(e){console[e]=this.bind(console[e],console)},Function.prototype.call),window.Docs={shebang:function(){var e=$.param.fragment().split("/");switch(e.shift(),e.length){case 1:if(e[0].length>0){var t="resource_"+e[0];Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1})}break;case 2:Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1});var n=e.join("_"),i=n+"_content";Docs.expandOperation($("#"+i)),$("#"+n).slideto({highlight:!1})}},toggleEndpointListForResource:function(e){var t=$("li#resource_"+Docs.escapeResourceName(e)+" ul.endpoints");t.is(":visible")?($.bbq.pushState("#/",2),Docs.collapseEndpointListForResource(e)):($.bbq.pushState("#/"+e,2),Docs.expandEndpointListForResource(e))},expandEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideDown();$("li#resource_"+e).addClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideDown()},collapseEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideUp();$("li#resource_"+e).removeClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideUp()},expandOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideDown():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.expandOperation($(this))})},collapseOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideUp():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.collapseOperation($(this))})},escapeResourceName:function(e){return e.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g,"\\$&")},expandOperation:function(e){e.slideDown()},collapseOperation:function(e){e.slideUp()}},Handlebars.registerHelper("sanitize",function(e){return e=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,""),new Handlebars.SafeString(e)}),Handlebars.registerHelper("renderTextParam",function(e){var t,n="text",i="",r=e.type||e.schema.type||"",a="array"===r.toLowerCase()||e.allowMultiple,o=a&&Array.isArray(e["default"])?e["default"].join("\n"):e["default"],s=Object.keys(e).filter(function(e){return null!==e.match(/^X-data-/i)}).reduce(function(t,n){return t+=" "+n.substring(2,n.length)+"='"+e[n]+"'"},"");if("undefined"==typeof o&&(o=""),e.format&&"password"===e.format&&(n="password"),e.valueId&&(i=" id='"+e.valueId+"'"),("string"==typeof o||o instanceof String)&&(o=o.replace(/'/g,"&apos;")),a)t="<textarea class='body-textarea"+(e.required?" required":"")+"' name='"+e.name+"'"+i+s,t+=" placeholder='Provide multiple values in new lines"+(e.required?" (at least one required).":".")+"'>",t+=o+"</textarea>";else{var l="parameter";e.required&&(l+=" required"),t="<input class='"+l+"' minlength='"+(e.required?1:0)+"'",t+=" name='"+e.name+"' placeholder='"+(e.required?"(required)":"")+"'"+i+s,t+=" type='"+n+"' value='"+o+"'/>"}return new Handlebars.SafeString(t)}),Handlebars.registerHelper("ifCond",function(e,t,n,i){switch(t){case"==":return e==n?i.fn(this):i.inverse(this);case"===":return e===n?i.fn(this):i.inverse(this);case"<":return n>e?i.fn(this):i.inverse(this);case"<=":return n>=e?i.fn(this):i.inverse(this);case">":return e>n?i.fn(this):i.inverse(this);case">=":return e>=n?i.fn(this):i.inverse(this);case"&&":return e&&n?i.fn(this):i.inverse(this);case"||":return e||n?i.fn(this):i.inverse(this);default:return i.inverse(this)}}),this.Handlebars.templates.main=Handlebars.template({1:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression,s='  <div class="info_title">'+o(a(null!=(r=null!=e?e.info:e)?r.title:r,e))+'</div>\n  <div class="info_description markdown">';return r=a(null!=(r=null!=e?e.info:e)?r.description:r,e),null!=r&&(s+=r),s+="</div>\n",r=t["if"].call(e,null!=e?e.externalDocs:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+="  ",r=t["if"].call(e,null!=(r=null!=e?e.info:e)?r.termsOfServiceUrl:r,{name:"if",hash:{},fn:this.program(4,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+="\n  ",r=t["if"].call(e,null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.name:r,{name:"if",hash:{},fn:this.program(6,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+="\n  ",r=t["if"].call(e,null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.url:r,{name:"if",hash:{},fn:this.program(8,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+="\n  ",r=t["if"].call(e,null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.email:r,{name:"if",hash:{},fn:this.program(10,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+="\n  ",r=t["if"].call(e,null!=(r=null!=e?e.info:e)?r.license:r,{name:"if",hash:{},fn:this.program(12,i),inverse:this.noop,data:i}),null!=r&&(s+=r),s+"\n"},2:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return"  <p>"+o(a(null!=(r=null!=e?e.externalDocs:e)?r.description:r,e))+'</p>\n  <a href="'+o(a(null!=(r=null!=e?e.externalDocs:e)?r.url:r,e))+'" target="_blank">'+o(a(null!=(r=null!=e?e.externalDocs:e)?r.url:r,e))+"</a>\n"},4:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return'<div class="info_tos"><a target="_blank" href="'+o(a(null!=(r=null!=e?e.info:e)?r.termsOfServiceUrl:r,e))+'" data-sw-translate>Terms of service</a></div>'},6:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return"<div class='info_name' data-sw-translate>Created by "+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.name:r,e))+"</div>"},8:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return"<div class='info_url' data-sw-translate>See more at <a href=\""+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.url:r,e))+'">'+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.url:r,e))+"</a></div>"},10:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return'<div class=\'info_email\'><a target="_parent" href="mailto:'+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.contact:r)?r.email:r,e))+"?subject="+o(a(null!=(r=null!=e?e.info:e)?r.title:r,e))+'" data-sw-translate>Contact the developer</a></div>'},12:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return"<div class='info_license'><a target=\"_blank\" href='"+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.license:r)?r.url:r,e))+"'>"+o(a(null!=(r=null!=(r=null!=e?e.info:e)?r.license:r)?r.name:r,e))+"</a></div>"},14:function(e,t,n,i){var r,a=this.lambda,o=this.escapeExpression;return'  , <span style="font-variant: small-caps" data-sw-translate>api version</span>: '+o(a(null!=(r=null!=e?e.info:e)?r.version:r,e))+"\n    "},16:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'    <span style="float:right"><a target="_blank" href="'+s((r=null!=(r=t.validatorUrl||(null!=e?e.validatorUrl:e))?r:o,typeof r===a?r.call(e,{name:"validatorUrl",hash:{},data:i}):r))+"/debug?url="+s((r=null!=(r=t.url||(null!=e?e.url:e))?r:o,typeof r===a?r.call(e,{name:"url",hash:{},data:i}):r))+'"><img id="validator" src="'+s((r=null!=(r=t.validatorUrl||(null!=e?e.validatorUrl:e))?r:o,typeof r===a?r.call(e,{name:"validatorUrl",hash:{},data:i}):r))+"?url="+s((r=null!=(r=t.url||(null!=e?e.url:e))?r:o,typeof r===a?r.call(e,{name:"url",hash:{},data:i}):r))+'"></a>\n    </span>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<div class='info' id='api_info'>\n";return r=t["if"].call(e,null!=e?e.info:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "+l((a=null!=(a=t.basePath||(null!=e?e.basePath:e))?a:s,typeof a===o?a.call(e,{name:"basePath",hash:{},data:i}):a))+"\n",r=t["if"].call(e,null!=(r=null!=e?e.info:e)?r.version:r,{name:"if",hash:{},fn:this.program(14,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="]\n",r=t["if"].call(e,null!=e?e.validatorUrl:e,{name:"if",hash:{},fn:this.program(16,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"    </h4>\n    </div>\n</div>\n"},useData:!0}),this.Handlebars.templates.oauth2=Handlebars.template({1:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='            <li>\n                <input class="oauth-scope" type="checkbox" data-scope="'+l((a=null!=(a=t.scope||(null!=e?e.scope:e))?a:s,typeof a===o?a.call(e,{name:"scope",hash:{},data:i}):a))+'" oauthtype="'+l((a=null!=(a=t.OAuthSchemeKey||(null!=e?e.OAuthSchemeKey:e))?a:s,typeof a===o?a.call(e,{name:"OAuthSchemeKey",hash:{},data:i}):a))+'"/>\n                <label>'+l((a=null!=(a=t.scope||(null!=e?e.scope:e))?a:s,typeof a===o?a.call(e,{name:"scope",hash:{},data:i}):a))+'</label><br/>\n                <span class="api-scope-desc">'+l((a=null!=(a=t.description||(null!=e?e.description:e))?a:s,typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a))+"\n";return r=t["if"].call(e,null!=e?e.OAuthSchemeKey:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"                </span>\n            </li>\n"},2:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                        ("+s((r=null!=(r=t.OAuthSchemeKey||(null!=e?e.OAuthSchemeKey:e))?r:o,typeof r===a?r.call(e,{name:"OAuthSchemeKey",hash:{},data:i}):r))+")\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='<div>\n    <h3 class="auth__title">Select OAuth2.0 Scopes</h3>\n    <p>'+l((a=null!=(a=t.description||(null!=e?e.description:e))?a:s,typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a))+'</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href="#">Learn how to use</a>\n    </p>\n    <p><strong> '+l((a=null!=(a=t.appName||(null!=e?e.appName:e))?a:s,typeof a===o?a.call(e,{name:"appName",hash:{},data:i}):a))+" </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Authorization URL: "+l((a=null!=(a=t.authorizationUrl||(null!=e?e.authorizationUrl:e))?a:s,typeof a===o?a.call(e,{name:"authorizationUrl",hash:{},data:i}):a))+"</p>\n    <p>flow: "+l((a=null!=(a=t.flow||(null!=e?e.flow:e))?a:s,typeof a===o?a.call(e,{name:"flow",hash:{},data:i}):a))+'</p>\n    <ul class="api-popup-scopes">\n';return r=t.each.call(e,null!=e?e.scopes:e,{name:"each",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"    </ul>\n</div>"},useData:!0}),this.Handlebars.templates.operation=Handlebars.template({1:function(e,t,n,i){return"deprecated"},3:function(e,t,n,i){return"            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"},5:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l='        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class="markdown">';return a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(l+=r),l+"</div>\n"},7:function(e,t,n,i){return"            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"},9:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='          <div class="response-class">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> '+l((a=null!=(a=t.successCode||(null!=e?e.successCode:e))?a:s,typeof a===o?a.call(e,{name:"successCode",hash:{},data:i}):a))+")</h4>\n              ";return r=t["if"].call(e,null!=e?e.successDescription:e,{name:"if",hash:{},fn:this.program(10,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+'\n            <p><span class="model-signature" /></p>\n            <br/>\n            <div class="response-content-type" />\n            </div>\n'},10:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l='<div class="markdown">';return a=null!=(a=t.successDescription||(null!=e?e.successDescription:e))?a:s,r=typeof a===o?a.call(e,{name:"successDescription",hash:{},data:i}):a,null!=r&&(l+=r),l+"</div>"},12:function(e,t,n,i){var r,a='          <h4 data-sw-translate>Headers</h4>\n          <table class="headers">\n            <thead>\n              <tr>\n                <th style="width: 100px; max-width: 100px" data-sw-translate>Header</th>\n                <th style="width: 310px; max-width: 310px" data-sw-translate>Description</th>\n                <th style="width: 200px; max-width: 200px" data-sw-translate>Type</th>\n                <th style="width: 320px; max-width: 320px" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n';return r=t.each.call(e,null!=e?e.headers:e,{name:"each",hash:{},fn:this.program(13,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a+"            </tbody>\n          </table>\n"},13:function(e,t,n,i){var r=this.lambda,a=this.escapeExpression;return"              <tr>\n                <td>"+a(r(i&&i.key,e))+"</td>\n                <td>"+a(r(null!=e?e.description:e,e))+"</td>\n                <td>"+a(r(null!=e?e.type:e,e))+"</td>\n                <td>"+a(r(null!=e?e.other:e,e))+"</td>\n              </tr>\n"},15:function(e,t,n,i){return'          <h4 data-sw-translate>Parameters</h4>\n          <table class=\'fullwidth\'>\n          <thead>\n            <tr>\n            <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter</th>\n            <th style="width: 310px; max-width: 310px" data-sw-translate>Value</th>\n            <th style="width: 200px; max-width: 200px" data-sw-translate>Description</th>\n            <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter Type</th>\n            <th style="width: 220px; max-width: 230px" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class="operation-params">\n\n          </tbody>\n          </table>\n'},17:function(e,t,n,i){return"          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n"},19:function(e,t,n,i){return""},21:function(e,t,n,i){return"          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n"},23:function(e,t,n,i){return"          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="  <ul class='operations' >\n    <li class='"+l((a=null!=(a=t.method||(null!=e?e.method:e))?a:s,typeof a===o?a.call(e,{name:"method",hash:{},data:i}):a))+" operation' id='"+l((a=null!=(a=t.parentId||(null!=e?e.parentId:e))?a:s,typeof a===o?a.call(e,{name:"parentId",hash:{},data:i}):a))+"_"+l((a=null!=(a=t.nickname||(null!=e?e.nickname:e))?a:s,typeof a===o?a.call(e,{name:"nickname",hash:{},data:i}):a))+"'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"+l((a=null!=(a=t.encodedParentId||(null!=e?e.encodedParentId:e))?a:s,typeof a===o?a.call(e,{name:"encodedParentId",hash:{},data:i}):a))+"/"+l((a=null!=(a=t.nickname||(null!=e?e.nickname:e))?a:s,typeof a===o?a.call(e,{name:"nickname",hash:{},data:i}):a))+'\' class="toggleOperation">'+l((a=null!=(a=t.method||(null!=e?e.method:e))?a:s,typeof a===o?a.call(e,{name:"method",hash:{},data:i}):a))+"</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"+l((a=null!=(a=t.encodedParentId||(null!=e?e.encodedParentId:e))?a:s,typeof a===o?a.call(e,{name:"encodedParentId",hash:{},data:i}):a))+"/"+l((a=null!=(a=t.nickname||(null!=e?e.nickname:e))?a:s,typeof a===o?a.call(e,{name:"nickname",hash:{},data:i}):a))+"' class=\"toggleOperation ";return r=t["if"].call(e,null!=e?e.deprecated:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+='">'+l((a=null!=(a=t.path||(null!=e?e.path:e))?a:s,typeof a===o?a.call(e,{name:"path",hash:{},data:i}):a))+"</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"+l((a=null!=(a=t.encodedParentId||(null!=e?e.encodedParentId:e))?a:s,typeof a===o?a.call(e,{name:"encodedParentId",hash:{},data:i}):a))+"/"+l((a=null!=(a=t.nickname||(null!=e?e.nickname:e))?a:s,typeof a===o?a.call(e,{name:"nickname",hash:{},data:i}):a))+'\' class="toggleOperation">',a=null!=(a=t.summary||(null!=e?e.summary:e))?a:s,r=typeof a===o?a.call(e,{name:"summary",hash:{},data:i}):a,null!=r&&(u+=r),u+="</a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"+l((a=null!=(a=t.parentId||(null!=e?e.parentId:e))?a:s,typeof a===o?a.call(e,{name:"parentId",hash:{},data:i}):a))+"_"+l((a=null!=(a=t.nickname||(null!=e?e.nickname:e))?a:s,typeof a===o?a.call(e,{name:"nickname",hash:{},data:i}):a))+"_content' style='display:none'>\n",r=t["if"].call(e,null!=e?e.deprecated:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.description:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.noop,data:i}),null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.security:e,{name:"if",hash:{},fn:this.program(7,i),inverse:this.noop,data:i}),null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.type:e,{name:"if",hash:{},fn:this.program(9,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="\n",r=t["if"].call(e,null!=e?e.headers:e,{name:"if",hash:{},fn:this.program(12,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n",r=t["if"].call(e,null!=e?e.parameters:e,{name:"if",hash:{},fn:this.program(15,i),inverse:this.noop,data:i}),null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.responseMessages:e,{name:"if",hash:{},fn:this.program(17,i),inverse:this.noop,data:i}),null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.isReadOnly:e,{name:"if",hash:{},fn:this.program(19,i),inverse:this.program(21,i),data:i}),null!=r&&(u+=r),u+="        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n",r=t["if"].call(e,null!=e?e.showRequestHeaders:e,{name:"if",hash:{},fn:this.program(23,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n"},useData:!0}),this.Handlebars.templates.param_list=Handlebars.template({1:function(e,t,n,i){return" required"},3:function(e,t,n,i){return' multiple="multiple"'},5:function(e,t,n,i){return" required "},7:function(e,t,n,i){var r,a="      <option ";return r=t.unless.call(e,null!=e?e.hasDefault:e,{name:"unless",hash:{},fn:this.program(8,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a+" value=''></option>\n"},8:function(e,t,n,i){return'  selected="" '},10:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="\n      <option ";return r=t["if"].call(e,null!=e?e.isDefault:e,{name:"if",hash:{},fn:this.program(11,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="  value='"+l((a=null!=(a=t.value||(null!=e?e.value:e))?a:s,typeof a===o?a.call(e,{name:"value",hash:{},data:i}):a))+"'> "+l((a=null!=(a=t.value||(null!=e?e.value:e))?a:s,typeof a===o?a.call(e,{name:"value",hash:{},data:i}):a))+" ",r=t["if"].call(e,null!=e?e.isDefault:e,{name:"if",hash:{},fn:this.program(13,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+" </option>\n\n"},11:function(e,t,n,i){return' selected=""  '},13:function(e,t,n,i){return" (default) "},15:function(e,t,n,i){return"<strong>"},17:function(e,t,n,i){return"</strong>"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td class='code";return r=t["if"].call(e,null!=e?e.required:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="'><label for='"+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+"'>"+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+"</label></td>\n<td>\n  <select ",r=(t.isArray||e&&e.isArray||s).call(e,e,{name:"isArray",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+=' class="parameter ',r=t["if"].call(e,null!=e?e.required:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+='" name="'+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+'" id="'+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+'">\n\n',r=t.unless.call(e,null!=e?e.required:e,{name:"unless",hash:{},fn:this.program(7,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="\n",r=t.each.call(e,null!=(r=null!=e?e.allowableValues:e)?r.descriptiveValues:r,{name:"each",hash:{},fn:this.program(10,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+='\n  </select>\n</td>\n<td class="markdown">',r=t["if"].call(e,null!=e?e.required:e,{name:"if",hash:{},fn:this.program(15,i),inverse:this.noop,data:i}),null!=r&&(u+=r),a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(u+=r),r=t["if"].call(e,null!=e?e.required:e,{name:"if",hash:{},fn:this.program(17,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+="</td>\n<td>",a=null!=(a=t.paramType||(null!=e?e.paramType:e))?a:s,r=typeof a===o?a.call(e,{name:"paramType",hash:{},data:i}):a,null!=r&&(u+=r),u+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),this.Handlebars.templates.param_readonly_required=Handlebars.template({1:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+"'>"+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",hash:{},data:i}):r))+"</textarea>\n"},3:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e["default"]:e,{name:"if",hash:{},fn:this.program(4,i),inverse:this.program(6,i),data:i}),null!=r&&(a+=r),a},4:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"            "+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",
+hash:{},data:i}):r))+"\n"},6:function(e,t,n,i){return"            (empty)\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td class='code required'><label for='"+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+"'>"+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+"</label></td>\n<td>\n";return r=t["if"].call(e,null!=e?e.isBody:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(3,i),data:i}),null!=r&&(u+=r),u+='</td>\n<td class="markdown">',a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(u+=r),u+="</td>\n<td>",a=null!=(a=t.paramType||(null!=e?e.paramType:e))?a:s,r=typeof a===o?a.call(e,{name:"paramType",hash:{},data:i}):a,null!=r&&(u+=r),u+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),this.Handlebars.templates.param_readonly=Handlebars.template({1:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"        <textarea class='body-textarea' readonly='readonly' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+"'>"+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",hash:{},data:i}):r))+'</textarea>\n        <div class="parameter-content-type" />\n'},3:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e["default"]:e,{name:"if",hash:{},fn:this.program(4,i),inverse:this.program(6,i),data:i}),null!=r&&(a+=r),a},4:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"            "+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",hash:{},data:i}):r))+"\n"},6:function(e,t,n,i){return"            (empty)\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td class='code'><label for='"+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+"'>"+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+"</label></td>\n<td>\n";return r=t["if"].call(e,null!=e?e.isBody:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(3,i),data:i}),null!=r&&(u+=r),u+='</td>\n<td class="markdown">',a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(u+=r),u+="</td>\n<td>",a=null!=(a=t.paramType||(null!=e?e.paramType:e))?a:s,r=typeof a===o?a.call(e,{name:"paramType",hash:{},data:i}):a,null!=r&&(u+=r),u+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),this.Handlebars.templates.param_required=Handlebars.template({1:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e.isFile:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.program(4,i),data:i}),null!=r&&(a+=r),a},2:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'                   <input type="file" name=\''+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+"'/>\n"},4:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e["default"]:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.program(7,i),data:i}),null!=r&&(a+=r),a},5:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                         <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea required' placeholder='(required)' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id=\""+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+'">'+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",hash:{},data:i}):r))+'</textarea>\n        <br />\n        <div class="parameter-content-type" />\n'},7:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                            <textarea class='body-textarea required' placeholder='(required)' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+'\'></textarea>\n                               <div class="editor_holder"></div>\n                             <br />\n                                <div class="parameter-content-type" />\n'},9:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e.isFile:e,{name:"if",hash:{},fn:this.program(10,i),inverse:this.program(12,i),data:i}),null!=r&&(a+=r),a},10:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                  <input class='parameter' class='required' type='file' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+"'/>\n"},12:function(e,t,n,i){var r,a=t.helperMissing,o="";return r=(t.renderTextParam||e&&e.renderTextParam||a).call(e,e,{name:"renderTextParam",hash:{},fn:this.program(13,i),inverse:this.noop,data:i}),null!=r&&(o+=r),o},13:function(e,t,n,i){return""},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td class='code required'><label for='"+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+"'>"+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+"</label></td>\n<td>\n";return r=t["if"].call(e,null!=e?e.isBody:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(9,i),data:i}),null!=r&&(u+=r),u+='</td>\n<td>\n      <strong><span class="markdown">',a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(u+=r),u+="</span></strong>\n</td>\n<td>",a=null!=(a=t.paramType||(null!=e?e.paramType:e))?a:s,r=typeof a===o?a.call(e,{name:"paramType",hash:{},data:i}):a,null!=r&&(u+=r),u+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),this.Handlebars.templates.param=Handlebars.template({1:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e.isFile:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.program(4,i),data:i}),null!=r&&(a+=r),a},2:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'                   <input type="file" name=\''+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+'\'/>\n                       <div class="parameter-content-type" />\n'},4:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e["default"]:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.program(7,i),data:i}),null!=r&&(a+=r),a},5:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                         <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+"'>"+s((r=null!=(r=t["default"]||(null!=e?e["default"]:e))?r:o,typeof r===a?r.call(e,{name:"default",hash:{},data:i}):r))+'</textarea>\n        <br />\n        <div class="parameter-content-type" />\n'},7:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"                               <textarea class='body-textarea' name='"+s((r=null!=(r=t.name||(null!=e?e.name:e))?r:o,typeof r===a?r.call(e,{name:"name",hash:{},data:i}):r))+"' id='"+s((r=null!=(r=t.valueId||(null!=e?e.valueId:e))?r:o,typeof r===a?r.call(e,{name:"valueId",hash:{},data:i}):r))+'\'></textarea>\n                         <div class="editor_holder"></div>\n                             <br />\n                                <div class="parameter-content-type" />\n'},9:function(e,t,n,i){var r,a="";return r=t["if"].call(e,null!=e?e.isFile:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.program(10,i),data:i}),null!=r&&(a+=r),a},10:function(e,t,n,i){var r,a=t.helperMissing,o="";return r=(t.renderTextParam||e&&e.renderTextParam||a).call(e,e,{name:"renderTextParam",hash:{},fn:this.program(11,i),inverse:this.noop,data:i}),null!=r&&(o+=r),o},11:function(e,t,n,i){return""},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td class='code'><label for='"+l((a=null!=(a=t.valueId||(null!=e?e.valueId:e))?a:s,typeof a===o?a.call(e,{name:"valueId",hash:{},data:i}):a))+"'>"+l((a=null!=(a=t.name||(null!=e?e.name:e))?a:s,typeof a===o?a.call(e,{name:"name",hash:{},data:i}):a))+"</label></td>\n<td>\n\n";return r=t["if"].call(e,null!=e?e.isBody:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(9,i),data:i}),null!=r&&(u+=r),u+='\n</td>\n<td class="markdown">',a=null!=(a=t.description||(null!=e?e.description:e))?a:s,r=typeof a===o?a.call(e,{name:"description",hash:{},data:i}):a,null!=r&&(u+=r),u+="</td>\n<td>",a=null!=(a=t.paramType||(null!=e?e.paramType:e))?a:s,r=typeof a===o?a.call(e,{name:"paramType",hash:{},data:i}):a,null!=r&&(u+=r),u+'</td>\n<td>\n        <span class="model-signature"></span>\n</td>\n'},useData:!0}),this.Handlebars.templates.parameter_content_type=Handlebars.template({1:function(e,t,n,i){var r,a="";return r=t.each.call(e,null!=e?e.consumes:e,{name:"each",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a},2:function(e,t,n,i){var r=this.lambda,a=this.escapeExpression;return'  <option value="'+a(r(e,e))+'">'+a(r(e,e))+"</option>\n"},4:function(e,t,n,i){return'  <option value="application/json">application/json</option>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='<label for="'+l((a=null!=(a=t.parameterContentTypeId||(null!=e?e.parameterContentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"parameterContentTypeId",hash:{},data:i}):a))+'" data-sw-translate>Parameter content type:</label>\n<select name="parameterContentType" id="'+l((a=null!=(a=t.parameterContentTypeId||(null!=e?e.parameterContentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"parameterContentTypeId",hash:{},data:i}):a))+'">\n';return r=t["if"].call(e,null!=e?e.consumes:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(4,i),data:i}),null!=r&&(u+=r),u+"</select>\n"},useData:!0}),this.Handlebars.templates.popup=Handlebars.template({compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return'<div class="api-popup-dialog-wrapper">\n    <div class="api-popup-title">'+s((r=null!=(r=t.title||(null!=e?e.title:e))?r:o,typeof r===a?r.call(e,{name:"title",hash:{},data:i}):r))+'</div>\n    <div class="api-popup-content"></div>\n    <p class="error-msg"></p>\n    <div class="api-popup-actions">\n        <button class="api-popup-cancel api-button gray" type="button">Cancel</button>\n    </div>\n</div>\n<div class="api-popup-dialog-shadow"></div>'},useData:!0}),this.Handlebars.templates.resource=Handlebars.template({1:function(e,t,n,i){return" : "},3:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"    <li>\n      <a href='"+s((r=null!=(r=t.url||(null!=e?e.url:e))?r:o,typeof r===a?r.call(e,{name:"url",hash:{},data:i}):r))+"' data-sw-translate>Raw</a>\n    </li>\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o,s="function",l=t.helperMissing,u=this.escapeExpression,c=t.blockHelperMissing,p="<div class='heading'>\n  <h2>\n    <a href='#!/"+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'\' class="toggleEndpointList" data-id="'+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'">'+u((a=null!=(a=t.name||(null!=e?e.name:e))?a:l,typeof a===s?a.call(e,{name:"name",hash:{},data:i}):a))+"</a> ";return a=null!=(a=t.summary||(null!=e?e.summary:e))?a:l,o={name:"summary",hash:{},fn:this.program(1,i),inverse:this.noop,data:i},r=typeof a===s?a.call(e,o):a,t.summary||(r=c.call(e,r,o)),null!=r&&(p+=r),a=null!=(a=t.summary||(null!=e?e.summary:e))?a:l,r=typeof a===s?a.call(e,{name:"summary",hash:{},data:i}):a,null!=r&&(p+=r),p+="\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+"' id='endpointListTogger_"+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'\' class="toggleEndpointList" data-id="'+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href=\'#\' class="collapseResource" data-id="'+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href=\'#\' class="expandResource" data-id="'+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+'" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n',r=t["if"].call(e,null!=e?e.url:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(p+=r),p+"  </ul>\n</div>\n<ul class='endpoints' id='"+u((a=null!=(a=t.id||(null!=e?e.id:e))?a:l,typeof a===s?a.call(e,{name:"id",hash:{},data:i}):a))+"_endpoint_list' style='display:none'>\n\n</ul>\n"},useData:!0}),this.Handlebars.templates.response_content_type=Handlebars.template({1:function(e,t,n,i){var r,a="";return r=t.each.call(e,null!=e?e.produces:e,{name:"each",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(a+=r),a},2:function(e,t,n,i){var r=this.lambda,a=this.escapeExpression;return'  <option value="'+a(r(e,e))+'">'+a(r(e,e))+"</option>\n"},4:function(e,t,n,i){return'  <option value="application/json">application/json</option>\n'},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='<label data-sw-translate for="'+l((a=null!=(a=t.responseContentTypeId||(null!=e?e.responseContentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"responseContentTypeId",hash:{},data:i}):a))+'">Response Content Type</label>\n<select name="responseContentType" id="'+l((a=null!=(a=t.responseContentTypeId||(null!=e?e.responseContentTypeId:e))?a:s,typeof a===o?a.call(e,{name:"responseContentTypeId",hash:{},data:i}):a))+'">\n';return r=t["if"].call(e,null!=e?e.produces:e,{name:"if",hash:{},fn:this.program(1,i),inverse:this.program(4,i),data:i}),null!=r&&(u+=r),u+"</select>\n"},useData:!0}),this.Handlebars.templates.signature=Handlebars.template({1:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l='\n<div>\n<ul class="signature-nav">\n  <li><a class="description-link" href="#" data-sw-translate>Model</a></li>\n  <li><a class="snippet-link" href="#" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class="signature-container">\n  <div class="description">\n    ';return a=null!=(a=t.signature||(null!=e?e.signature:e))?a:s,r=typeof a===o?a.call(e,{name:"signature",hash:{},data:i}):a,null!=r&&(l+=r),l+='\n  </div>\n\n  <div class="snippet">\n',r=t["if"].call(e,null!=e?e.sampleJSON:e,{name:"if",hash:{},fn:this.program(2,i),inverse:this.noop,data:i}),null!=r&&(l+=r),r=t["if"].call(e,null!=e?e.sampleXML:e,{name:"if",hash:{},fn:this.program(5,i),inverse:this.noop,data:i}),null!=r&&(l+=r),l+"  </div>\n</div>\n"},2:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='      <div class="snippet_json">\n        <pre><code>'+l((a=null!=(a=t.sampleJSON||(null!=e?e.sampleJSON:e))?a:s,typeof a===o?a.call(e,{name:"sampleJSON",hash:{},data:i}):a))+"</code></pre>\n        ";return r=t["if"].call(e,null!=e?e.isParam:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"\n      </div>\n"},3:function(e,t,n,i){return'<small class="notice" data-sw-translate></small>'},5:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u='    <div class="snippet_xml">\n      <pre><code>'+l((a=null!=(a=t.sampleXML||(null!=e?e.sampleXML:e))?a:s,typeof a===o?a.call(e,{name:"sampleXML",hash:{},data:i}):a))+"</code></pre>\n      ";return r=t["if"].call(e,null!=e?e.isParam:e,{name:"if",hash:{},fn:this.program(3,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"\n    </div>\n"},7:function(e,t,n,i){var r,a="function",o=t.helperMissing,s=this.escapeExpression;return"    "+s((r=null!=(r=t.signature||(null!=e?e.signature:e))?r:o,typeof r===a?r.call(e,{name:"signature",hash:{},data:i}):r))+"\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a=t.helperMissing;return r=(t.ifCond||e&&e.ifCond||a).call(e,null!=e?e.sampleJSON:e,"||",null!=e?e.sampleXML:e,{name:"ifCond",hash:{},fn:this.program(1,i),inverse:this.program(7,i),data:i}),null!=r?r:""},useData:!0}),this.Handlebars.templates.status_code=Handlebars.template({1:function(e,t,n,i){var r=this.lambda,a=this.escapeExpression;return"      <tr>\n        <td>"+a(r(i&&i.key,e))+"</td>\n        <td>"+a(r(null!=e?e.description:e,e))+"</td>\n        <td>"+a(r(null!=e?e.type:e,e))+"</td>\n      </tr>\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(e,t,n,i){var r,a,o="function",s=t.helperMissing,l=this.escapeExpression,u="<td width='15%' class='code'>"+l((a=null!=(a=t.code||(null!=e?e.code:e))?a:s,typeof a===o?a.call(e,{name:"code",hash:{},data:i}):a))+'</td>\n<td class="markdown">';return a=null!=(a=t.message||(null!=e?e.message:e))?a:s,r=typeof a===o?a.call(e,{name:"message",hash:{},data:i}):a,null!=r&&(u+=r),u+='</td>\n<td width=\'50%\'><span class="model-signature" /></td>\n<td class="headers">\n  <table>\n    <tbody>\n',r=t.each.call(e,null!=e?e.headers:e,{name:"each",hash:{},fn:this.program(1,i),inverse:this.noop,data:i}),null!=r&&(u+=r),u+"    </tbody>\n  </table>\n</td>"},useData:!0}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SwaggerClient=e()}}(function(){var t;return function n(e,t,i){function r(o,s){if(!t[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,n,e,t,i)}return t[o].exports}for(var a="function"==typeof require&&require,o=0;o<i.length;o++)r(i[o]);return r}({1:[function(e,t,n){"use strict";var i=e("./lib/auth"),r=e("./lib/helpers"),a=e("./lib/client"),o=function(e,t){return r.log('This is deprecated, use "new SwaggerClient" instead.'),new a(e,t)};Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){for(var n=t||0,i=this.length;i>n;n++)if(this[n]===e)return n;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.endsWith||(String.prototype.endsWith=function(e){return-1!==this.indexOf(e,this.length-e.length)}),t.exports=a,a.ApiKeyAuthorization=i.ApiKeyAuthorization,a.PasswordAuthorization=i.PasswordAuthorization,a.CookieAuthorization=i.CookieAuthorization,a.SwaggerApi=o,a.SwaggerClient=o,a.SchemaMarkup=e("./lib/schema-markup")},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(e,t,n){"use strict";var i=e("./helpers"),r=e("btoa"),a=e("cookiejar").CookieJar,o={each:e("lodash-compat/collection/each"),includes:e("lodash-compat/collection/includes"),isObject:e("lodash-compat/lang/isObject"),isArray:e("lodash-compat/lang/isArray")},s=t.exports.SwaggerAuthorizations=function(e){this.authz=e||{}};s.prototype.add=function(e,t){if(o.isObject(e))for(var n in e)this.authz[n]=e[n];else"string"==typeof e&&(this.authz[e]=t);return t},s.prototype.remove=function(e){return delete this.authz[e]},s.prototype.apply=function(e,t){var n=!0,i=!t,r=[],a=e.clientAuthorizations||this.authz;return o.each(t,function(e,t){"string"==typeof t&&r.push(t),o.each(e,function(e,t){r.push(t)})}),o.each(a,function(t,a){if(i||o.includes(r,a)){var s=t.apply(e);n=n&&!!s}}),n};var l=t.exports.ApiKeyAuthorization=function(e,t,n){this.name=e,this.value=t,this.type=n};l.prototype.apply=function(e){if("query"===this.type){var t;if(e.url.indexOf("?")>0){t=e.url.substring(e.url.indexOf("?")+1);var n=t.split("&");if(n&&n.length>0)for(var i=0;i<n.length;i++){var r=n[i].split("=");if(r&&r.length>0&&r[0]===this.name)return!1}}return e.url.indexOf("?")>0?e.url=e.url+"&"+this.name+"="+this.value:e.url=e.url+"?"+this.name+"="+this.value,!0}return"header"===this.type?("undefined"==typeof e.headers[this.name]&&(e.headers[this.name]=this.value),!0):void 0};var u=t.exports.CookieAuthorization=function(e){this.cookie=e};u.prototype.apply=function(e){return e.cookieJar=e.cookieJar||new a,e.cookieJar.setCookie(this.cookie),!0};var c=t.exports.PasswordAuthorization=function(e,t){3===arguments.length&&(i.log("PasswordAuthorization: the 'name' argument has been removed, pass only username and password"),e=arguments[1],t=arguments[2]),this.username=e,this.password=t};c.prototype.apply=function(e){return"undefined"==typeof e.headers.Authorization&&(e.headers.Authorization="Basic "+r(this.username+":"+this.password)),!0}},{"./helpers":4,btoa:14,cookiejar:20,"lodash-compat/collection/each":54,"lodash-compat/collection/includes":57,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],3:[function(e,t,n){"use strict";var i={bind:e("lodash-compat/function/bind"),cloneDeep:e("lodash-compat/lang/cloneDeep"),find:e("lodash-compat/collection/find"),forEach:e("lodash-compat/collection/forEach"),indexOf:e("lodash-compat/array/indexOf"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isFunction:e("lodash-compat/lang/isFunction"),isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined")},r=e("./auth"),a=e("./helpers"),o=e("./types/model"),s=e("./types/operation"),l=e("./types/operationGroup"),u=e("./resolver"),c=e("./http"),p=e("./spec-converter"),h=e("q"),f=["apis","authorizationScheme","authorizations","basePath","build","buildFrom1_1Spec","buildFrom1_2Spec","buildFromSpec","clientAuthorizations","convertInfo","debug","defaultErrorCallback","defaultSuccessCallback","enableCookies","fail","failure","finish","help","host","idFromOp","info","initialize","isBuilt","isValid","modelPropertyMacro","models","modelsArray","options","parameterMacro","parseUri","progress","resourceCount","sampleModels","selfReflect","setConsolidatedModels","spec","supportedSubmitMethods","swaggerRequestHeaders","tagFromLabel","title","url","useJQuery"],d=["apis","asCurl","description","externalDocs","help","label","name","operation","operations","operationsArray","path","tag"],m=["delete","get","head","options","patch","post","put"],g=t.exports=function(e,t){return this.authorizations=null,this.authorizationScheme=null,this.basePath=null,this.debug=!1,this.enableCookies=!1,this.info=null,this.isBuilt=!1,this.isValid=!1,this.modelsArray=[],this.resourceCount=0,this.url=null,this.useJQuery=!1,this.swaggerObject={},this.deferredClient=void 0,this.clientAuthorizations=new r.SwaggerAuthorizations,"undefined"!=typeof e?this.initialize(e,t):this};g.prototype.initialize=function(e,t){return this.models={},this.sampleModels={},"string"==typeof e?this.url=e:i.isObject(e)&&(t=e,this.url=t.url),t=t||{},this.clientAuthorizations.add(t.authorizations),this.swaggerRequestHeaders=t.swaggerRequestHeaders||"application/json;charset=utf-8,*/*",this.defaultSuccessCallback=t.defaultSuccessCallback||null,this.defaultErrorCallback=t.defaultErrorCallback||null,this.modelPropertyMacro=t.modelPropertyMacro||null,this.parameterMacro=t.parameterMacro||null,this.usePromise=t.usePromise||null,this.usePromise&&(this.deferredClient=h.defer()),"function"==typeof t.success&&(this.success=t.success),t.useJQuery&&(this.useJQuery=t.useJQuery),t.enableCookies&&(this.enableCookies=t.enableCookies),this.options=t||{},this.supportedSubmitMethods=t.supportedSubmitMethods||[],this.failure=t.failure||function(e){throw e},this.progress=t.progress||function(){},this.spec=i.cloneDeep(t.spec),t.scheme&&(this.scheme=t.scheme),this.usePromise||"function"==typeof t.success?(this.ready=!0,this.build()):void 0},g.prototype.build=function(e){if(this.isBuilt)return this;var t=this;this.progress("fetching resource list: "+this.url+"; Please wait.");var n={useJQuery:this.useJQuery,url:this.url,method:"get",headers:{accept:this.swaggerRequestHeaders},on:{error:function(e){return"http"!==t.url.substring(0,4)?t.fail("Please specify the protocol for "+t.url):0===e.status?t.fail("Can't read from server.  It may not have the appropriate access-control-origin settings."):404===e.status?t.fail("Can't read swagger JSON from "+t.url):t.fail(e.status+" : "+e.statusText+" "+t.url)},response:function(e){var n=e.obj;if(!n)return t.fail("failed to parse JSON/YAML response");if(t.swaggerVersion=n.swaggerVersion,t.swaggerObject=n,n.swagger&&2===parseInt(n.swagger))t.swaggerVersion=n.swagger,(new u).resolve(n,t.url,t.buildFromSpec,t),t.isValid=!0;else{var i=new p;t.oldSwaggerObject=t.swaggerObject,i.setDocumentationLocation(t.url),i.convert(n,t.clientAuthorizations,t.options,function(e){t.swaggerObject=e,(new u).resolve(e,t.url,t.buildFromSpec,t),t.isValid=!0})}}}};if(this.spec)t.swaggerObject=this.spec,setTimeout(function(){(new u).resolve(t.spec,t.url,t.buildFromSpec,t)},10);else{if(this.clientAuthorizations.apply(n),e)return n;(new c).execute(n,this.options)}return this.usePromise?this.deferredClient.promise:this},g.prototype.buildFromSpec=function(e){if(this.isBuilt)return this;this.apis={},this.apisArray=[],this.basePath=e.basePath||"",this.consumes=e.consumes,this.host=e.host||"",this.info=e.info||{},this.produces=e.produces,this.schemes=e.schemes||[],this.securityDefinitions=e.securityDefinitions,this.security=e.security,this.title=e.title||"",e.externalDocs&&(this.externalDocs=e.externalDocs),this.authSchemes=e.securityDefinitions;var t,n={};if(Array.isArray(e.tags))for(n={},t=0;t<e.tags.length;t++){var r=e.tags[t];n[r.name]=r}var u;"string"==typeof this.url?(u=this.parseUri(this.url),"undefined"==typeof this.scheme&&"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme=u.scheme||"http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]||u.scheme),"undefined"!=typeof this.host&&""!==this.host||(this.host=u.host,u.port&&(this.host=this.host+":"+u.port))):"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme="http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]),this.definitions=e.definitions;var c;for(c in this.definitions){var p=new o(c,this.definitions[c],this.models,this.modelPropertyMacro);p&&(this.models[c]=p)}var h=this;h.apis.help=i.bind(h.help,h),i.forEach(e.paths,function(e,t){i.isPlainObject(e)&&i.forEach(m,function(r){var o=e[r];if(!i.isUndefined(o)){if(!i.isPlainObject(o))return void a.log("The '"+r+"' operation for '"+t+"' path is not an Operation Object");var u=o.tags;!i.isUndefined(u)&&i.isArray(u)&&0!==u.length||(u=o.tags=["default"]);var c=h.idFromOp(t,r,o),p=new s(h,o.scheme,c,r,t,o,h.definitions,h.models,h.clientAuthorizations);i.forEach(u,function(e){var t=i.indexOf(f,e)>-1?"_"+e:e,r=i.indexOf(d,e)>-1?"_"+e:e,o=h[t];if(t!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient function/property name.  Use 'client."+t+"' or 'client.apis."+e+"' instead of 'client."+e+"'."),r!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient operation function/property name.  Use 'client.apis."+r+"' instead of 'client.apis."+e+"'."),i.indexOf(d,c)>-1&&(a.log("The '"+c+"' operationId conflicts with a SwaggerClient operation function/property name.  Use 'client.apis."+r+"._"+c+"' instead of 'client.apis."+r+"."+c+"'."),c="_"+c,p.nickname=c),i.isUndefined(o)){o=h[t]=h.apis[r]={},o.operations={},o.label=r,o.apis={};var s=n[e];i.isUndefined(s)||(o.description=s.description,o.externalDocs=s.externalDocs),h[t].help=i.bind(h.help,o),h.apisArray.push(new l(e,o.description,o.externalDocs,p))}c=h.makeUniqueOperationId(c,h.apis[r]),i.isFunction(o.help)||(o.help=i.bind(h.help,o)),h.apis[r][c]=o[c]=i.bind(p.execute,p),h.apis[r][c].help=o[c].help=i.bind(p.help,p),h.apis[r][c].asCurl=o[c].asCurl=i.bind(p.asCurl,p),o.apis[c]=o.operations[c]=p;var u=i.find(h.apisArray,function(t){return t.tag===e});u&&u.operationsArray.push(p)})}})});var g=[];return i.forEach(Object.keys(n),function(e){var t;for(t in h.apisArray){var n=h.apisArray[t];n&&e===n.name&&(g.push(n),h.apisArray[t]=null)}}),i.forEach(h.apisArray,function(e){e&&g.push(e)}),h.apisArray=g,i.forEach(e.definitions,function(e,t){e.id=t.toLowerCase(),e.name=t,h.modelsArray.push(e)}),this.isBuilt=!0,this.usePromise?(this.isValid=!0,this.isBuilt=!0,this.deferredClient.resolve(this),this.deferredClient.promise):(this.success&&this.success(),this)},g.prototype.makeUniqueOperationId=function(e,t){for(var n=0,r=e;;){var a=!1;if(i.forEach(t.operations,function(e){e.nickname===r&&(a=!0)}),!a)return r;r=e+"_"+n,n++}return e},g.prototype.parseUri=function(e){var t=/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,n=t.exec(e);return{scheme:n[4]?n[4].replace(":",""):void 0,host:n[11],port:n[12],path:n[15]}},g.prototype.help=function(e){var t="";return this instanceof g?i.forEach(this.apis,function(e,n){i.isPlainObject(e)&&(t+="operations for the '"+n+"' tag\n",i.forEach(e.operations,function(e,n){t+="  * "+n+": "+e.summary+"\n"}))}):(this instanceof l||i.isPlainObject(this))&&(t+="operations for the '"+this.label+"' tag\n",i.forEach(this.apis,function(e,n){t+="  * "+n+": "+e.summary+"\n"})),e?t:(a.log(t),t)},g.prototype.tagFromLabel=function(e){return e},g.prototype.idFromOp=function(e,t,n){n&&n.operationId||(n=n||{},n.operationId=t+"_"+e);var i=n.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g,"_")||e.substring(1)+"_"+t;return i=i.replace(/((_){2,})/g,"_"),i=i.replace(/^(_)*/g,""),i=i.replace(/([_])*$/g,"")},g.prototype.setHost=function(e){this.host=e,this.apis&&i.forEach(this.apis,function(t){t.operations&&i.forEach(t.operations,function(t){t.host=e})})},g.prototype.setBasePath=function(e){this.basePath=e,this.apis&&i.forEach(this.apis,function(t){t.operations&&i.forEach(t.operations,function(t){t.basePath=e})})},g.prototype.setSchemes=function(e){this.schemes=e,e&&e.length>0&&this.apis&&i.forEach(this.apis,function(t){t.operations&&i.forEach(t.operations,function(t){t.scheme=e[0]})})},g.prototype.fail=function(e){return this.usePromise?(this.deferredClient.reject(e),this.deferredClient.promise):void(this.failure?this.failure(e):this.failure(e))}},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":51,"lodash-compat/collection/find":55,"lodash-compat/collection/forEach":56,"lodash-compat/function/bind":60,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isFunction":144,
+"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,q:159}],4:[function(e,t,n){(function(n){"use strict";var i={isPlainObject:e("lodash-compat/lang/isPlainObject"),indexOf:e("lodash-compat/array/indexOf")};t.exports.__bind=function(e,t){return function(){return e.apply(t,arguments)}};var r=t.exports.log=function(){console&&"test"!==n.env.NODE_ENV&&console.log(Array.prototype.slice.call(arguments)[0])};t.exports.fail=function(e){r(e)};var a=(t.exports.optionHtml=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"},t.exports.resolveSchema=function(e){return i.isPlainObject(e.schema)&&(e=a(e.schema)),e});t.exports.simpleRef=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e}}).call(this,e("_process"))},{_process:13,"lodash-compat/array/indexOf":51,"lodash-compat/lang/isPlainObject":147}],5:[function(t,n,i){"use strict";var r=t("./helpers"),a=t("superagent"),o=t("js-yaml"),s={isObject:t("lodash-compat/lang/isObject")},l=function(){this.type="JQueryHttpClient"},u=function(){this.type="SuperagentHttpClient"},c=n.exports=function(){};c.prototype.execute=function(t,n){var i;i=n&&n.client?n.client:new u(n),i.opts=n||{};var r=!1;if("undefined"!=typeof window&&"undefined"!=typeof window.jQuery&&(r=!0),"options"===t.method.toLowerCase()&&"SuperagentHttpClient"===i.type&&(e("forcing jQuery as OPTIONS are not supported by SuperAgent"),t.useJQuery=!0),this.isInternetExplorer()&&(t.useJQuery===!1||!r))throw new Error("Unsupported configuration! JQuery is required but not available");(t&&t.useJQuery===!0||this.isInternetExplorer()&&r)&&(i=new l(n));var a=t.on.response,o=function(e){return n&&n.requestInterceptor&&(e=n.requestInterceptor.apply(e)),e},c=function(e){return n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e)),a(e)};return t.on.response=function(e){c(e)},s.isObject(t)&&s.isObject(t.body)&&(t.body.type&&"formData"===t.body.type?(t.contentType=!1,t.processData=!1,delete t.headers["Content-Type"]):t.body=JSON.stringify(t.body)),t=o(t)||t,t.beforeSend?t.beforeSend(function(e){i.execute(e||t)}):i.execute(t),t.deferred?t.deferred.promise:t},c.prototype.isInternetExplorer=function(){var e=!1;if("undefined"!=typeof navigator&&navigator.userAgent){var t=navigator.userAgent.toLowerCase();if(-1!==t.indexOf("msie")){var n=parseInt(t.split("msie")[1]);8>=n&&(e=!0)}}return e},l.prototype.execute=function(e){var t=this.jQuery||"undefined"!=typeof window&&window.jQuery,n=e.on,i=e;if("undefined"==typeof t||t===!1)throw new Error("Unsupported configuration! JQuery is required but not available");return e.type=e.method,e.cache=!1,e.data=e.body,delete e.useJQuery,delete e.body,e.complete=function(e){for(var t={},a=e.getAllResponseHeaders().split("\n"),s=0;s<a.length;s++){var l=a[s].trim();if(0!==l.length){var u=l.indexOf(":");if(-1!==u){var c=l.substring(0,u).trim(),p=l.substring(u+1).trim();t[c]=p}else t[l]=null}}var h={url:i.url,method:i.method,status:e.status,statusText:e.statusText,data:e.responseText,headers:t};try{var f=e.responseJSON||o.safeLoad(e.responseText);h.obj="string"==typeof f?{}:f}catch(d){r.log("unable to parse JSON/YAML content")}if(h.obj=h.obj||null,e.status>=200&&e.status<300)n.response(h);else{if(!(0===e.status||e.status>=400&&e.status<599))return n.response(h);n.error(h)}},t.support.cors=!0,t.ajax(e)},u.prototype.execute=function(e){var t=e.method.toLowerCase();"delete"===t&&(t="del");var n,i=e.headers||{},s=a[t](e.url);for(n in i)s.set(n,i[n]);e.enableCookies&&s.withCredentials(),e.body&&s.send(e.body),"function"==typeof s.buffer&&s.buffer(),s.end(function(t,n){n=n||{status:0,headers:{error:"no response from server"}};var i,a={url:e.url,method:e.method,headers:n.headers};if(!t&&n.error&&(t=n.error),t&&e.on&&e.on.error){if(a.errObj=t,a.status=n?n.status:500,a.statusText=n?n.text:t.message,n.headers&&n.headers["content-type"]&&n.headers["content-type"].indexOf("application/json")>=0)try{a.obj=JSON.parse(a.statusText)}catch(s){a.obj=null}i=e.on.error}else if(n&&e.on&&e.on.response){var l;if(n.body&&Object.keys(n.body).length>0)l=n.body;else try{l=o.safeLoad(n.text),l="string"==typeof l?null:l}catch(s){r.log("cannot parse JSON/YAML content")}a.obj="object"==typeof l?l:null,a.status=n.status,a.statusText=n.text,i=e.on.response}a.data=a.statusText,i&&i(a)})}},{"./helpers":4,"js-yaml":21,"lodash-compat/lang/isObject":146,superagent:161}],6:[function(e,t,n){"use strict";var i=e("./http"),r={isObject:e("lodash-compat/lang/isObject"),cloneDeep:e("lodash-compat/lang/cloneDeep"),isArray:e("lodash-compat/lang/isArray")},a=t.exports=function(){this.failedUrls=[]};a.prototype.processAllOf=function(e,t,n,i,r,a){var o,s,l;n["x-resolved-from"]=["#/definitions/"+t];var u=n.allOf;for(u.sort(function(e,t){return e.$ref&&t.$ref?0:e.$ref?-1:1}),o=0;o<u.length;o++)l=u[o],s="/definitions/"+t+"/allOf",this.resolveInline(e,a,l,i,r,s)},a.prototype.resolve=function(e,t,n,a){this.spec=e;var o,s,l=t,u=n,c=a,p={};"function"==typeof t&&(l=null,u=t,c=n);var h=l;this.scope=c||this,this.iteration=this.iteration||0,this.scope.options&&this.scope.options.requestInterceptor&&(p.requestInterceptor=this.scope.options.requestInterceptor),this.scope.options&&this.scope.options.responseInterceptor&&(p.responseInterceptor=this.scope.options.responseInterceptor);var f,d,m,g,y=0,v={},b={},w=[];e.definitions=e.definitions||{};for(f in e.definitions){var x=e.definitions[f];if(x.$ref)this.resolveInline(l,e,x,w,b,x);else{for(g in x.properties)m=x.properties[g],r.isArray(m.allOf)?this.processAllOf(l,f,m,w,b,e):this.resolveTo(l,m,w,"/definitions");x.allOf&&this.processAllOf(l,f,x,w,b,e)}}e.parameters=e.parameters||{};for(f in e.parameters){var A=e.parameters[f];if("body"===A["in"]&&A.schema)if(r.isArray(A.schema.allOf)){for(var O="inline_model",f=O,j=!1,_=0;!j;){if("undefined"==typeof e.definitions[f]){j=!0;break}f=O+"_"+_,_++}e.definitions[f]={allOf:A.schema.allOf},delete A.schema.allOf,A.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,A.schema,w,o);A.$ref&&this.resolveInline(l,e,A,w,b,A.$ref)}for(f in e.paths){var S,k,C;d=e.paths[f];for(S in d)if("$ref"===S)o="/paths"+f,this.resolveInline(l,e,d,w,b,o);else{k=d[S];var E=d.parameters||[],I=k.parameters||[];for(s in E){var A=E[s];I.unshift(A)}"parameters"!==S&&r.isObject(k)&&(k.parameters=k.parameters||I);for(s in I){var A=I[s];if(o="/paths"+f+"/"+S+"/parameters","body"===A["in"]&&A.schema)if(r.isArray(A.schema.allOf)){for(var O="inline_model",f=O,j=!1,_=0;!j;){if("undefined"==typeof e.definitions[f]){j=!0;break}f=O+"_"+_,_++}e.definitions[f]={allOf:A.schema.allOf},delete A.schema.allOf,A.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else this.resolveTo(l,A.schema,w,o);A.$ref&&this.resolveInline(l,e,A,w,b,A.$ref)}for(C in k.responses){var T=k.responses[C];if(o="/paths"+f+"/"+S+"/responses/"+C,r.isObject(T)&&(T.$ref&&this.resolveInline(l,e,T,w,b,o),T.schema)){var $=T;if(r.isArray($.schema.allOf)){for(var O="inline_model",f=O,j=!1,_=0;!j;){if("undefined"==typeof e.definitions[f]){j=!0;break}f=O+"_"+_,_++}e.definitions[f]={allOf:$.schema.allOf},delete $.schema.allOf,delete $.schema.type,$.schema.$ref="#/definitions/"+f,this.processAllOf(l,f,e.definitions[f],w,b,e)}else"array"===$.schema.type?$.schema.items&&$.schema.items.$ref&&this.resolveInline(l,e,$.schema.items,w,b,o):this.resolveTo(l,T.schema,w,o)}}}d.parameters=[]}var U,M=0,P=[],L=w;for(s=0;s<L.length;s++){var D=L[s];if(l===D.root){if("ref"===D.resolveAs){var R,N=((D.root||"")+"/"+D.key).split("/"),F=[],B="";if(D.key.indexOf("../")>=0){for(var V=0;V<N.length;V++)".."===N[V]?F=F.slice(0,F.length-1):F.push(N[V]);for(R=0;R<F.length;R++)R>0&&(B+="/"),B+=F[R];D.root=B,P.push(D)}else if(U=D.key.split("#"),2===U.length){0!==U[0].indexOf("http://")&&0!==U[0].indexOf("https://")||(D.root=U[0]),o=U[1].split("/");var q,z=e;for(R=0;R<o.length;R++){var H=o[R];if(""!==H){if(z=z[H],"undefined"==typeof z){q=null;break}q=z}}null===q&&P.push(D)}}else if("inline"===D.resolveAs){if(D.key&&-1===D.key.indexOf("#")&&"/"!==D.key.charAt(0)){for(U=D.root.split("/"),o="",s=0;s<U.length-1;s++)o+=U[s]+"/";o+=D.key,D.root=o,D.location=""}P.push(D)}}else P.push(D)}M=P.length;for(var J=0;J<P.length;J++)!function(e,t,n){if(e.root&&e.root!==l)if(-1===n.failedUrls.indexOf(e.root)){var r={useJQuery:!1,url:e.root,method:"get",headers:{accept:n.scope.swaggerRequestHeaders||"application/json"},on:{error:function(i){y+=1,console.log("failed url: "+r.url),n.failedUrls.push(r.url),b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u)},response:function(i){var r=i.obj;n.resolveItem(r,e.root,w,v,b,e),y+=1,y===M&&n.finish(t,h,w,v,b,u)}}};c&&c.clientAuthorizations&&c.clientAuthorizations.apply(r),(new i).execute(r,p)}else y+=1,b[e.key]={root:e.root,location:e.location},y===M&&n.finish(t,h,w,v,b,u);else n.resolveItem(t,h,w,v,b,e),y+=1,y===M&&n.finish(t,l,w,v,b,u,!0)}(P[J],e,this);0===Object.keys(P).length&&this.finish(e,h,w,v,b,u)},a.prototype.resolveItem=function(e,t,n,i,r,a){var o=a.location,s=e,l=o.split("/");if(""!==o)for(var u=0;u<l.length;u++){var c=l[u];if(-1!==c.indexOf("~1")&&(c=l[u].replace(/~0/g,"~").replace(/~1/g,"/"),"/"!==c.charAt(0)&&(c="/"+c)),"undefined"==typeof s||null===s)break;if(""===c&&u===l.length-1&&l.length>1){s=null;break}c.length>0&&(s=s[c])}var p=a.key;l=a.key.split("/");var h=l[l.length-1];h.indexOf("#")>=0&&(h=h.split("#")[1]),null!==s&&"undefined"!=typeof s?i[p]={name:h,obj:s,key:a.key,root:a.root}:r[p]={root:a.root,location:a.location}},a.prototype.finish=function(e,t,n,i,r,a,o){var s;for(s in n){var l=n[s],u=l.key,c=i[u];if(c)if(e.definitions=e.definitions||{},"ref"===l.resolveAs){if(o!==!0)for(u in c.obj)var p=this.retainRoot(c.obj[u],l.root);e.definitions[c.name]=c.obj,l.obj.$ref="#/definitions/"+c.name}else if("inline"===l.resolveAs){var h=l.obj;h["x-resolved-from"]=[l.key],delete h.$ref;for(u in c.obj){var p=c.obj[u];o!==!0&&(p=this.retainRoot(c.obj[u],l.root)),h[u]=p}}}var f=this.countUnresolvedRefs(e);0===f||this.iteration>5?(this.resolveAllOf(e.definitions),a.call(this.scope,e,r)):(this.iteration+=1,this.resolve(e,t,a,this.scope))},a.prototype.countUnresolvedRefs=function(e){var t,n=this.getRefs(e),i=[],r=[];for(t in n)0===t.indexOf("#")?i.push(t.substring(1)):r.push(t);for(t=0;t<i.length;t++)for(var a=i[t],o=a.split("/"),s=e,l=0;l<o.length;l++){var u=o[l];if(""!==u&&(s=s[u],"undefined"==typeof s)){r.push(a);break}}return r.length},a.prototype.getRefs=function(e,t){t=t||e;var n={};for(var i in t)if(t.hasOwnProperty(i)){var a=t[i];if("$ref"===i&&"string"==typeof a)n[a]=null;else if(r.isObject(a)){var o=this.getRefs(a);for(var s in o)n[s]=null}}return n},a.prototype.retainRoot=function(e,t){for(var n in e){var i=e[n];if("$ref"===n&&"string"==typeof i){if(0!==i.indexOf("http://")&&0!==i.indexOf("https://")){var a=!0;if(t){var o=t.slice(-1);if("/"!==o&&0!==i.indexOf("#")&&0!==i.indexOf("http://")&&i.indexOf("https://")){console.log("working with "+i),a=!1;var s=t.split("/");s=s.splice(0,s.length-1),t="";for(var l=0;l<s.length;l++)t+=s[l]+"/"}}0!==i.indexOf("#")&&a&&(i="#"+i),i=(t||"")+i,e[n]=i}}else r.isObject(i)&&this.retainRoot(i,t)}return e},a.prototype.resolveInline=function(e,t,n,i,r,a){var o,s,l,u,c=n.$ref,p=n.$ref,h=!1;if(e=e||"",p){if(0===p.indexOf("../")){for(s=p.split("../"),l=e.split("/"),p="",o=0;o<s.length;o++)""===s[o]?l=l.slice(0,l.length-1):p+=s[o];for(e="",o=0;o<l.length-1;o++)o>0&&(e+="/"),e+=l[o];h=!0}if(p.indexOf("#")>=0)if(0===p.indexOf("/"))u=p.split("#"),s=e.split("//"),l=s[1].split("/"),e=s[0]+"//"+l[0]+u[0],a=u[1];else{if(u=p.split("#"),""!==u[0]){if(l=e.split("/"),l=l.slice(0,l.length-1),!h){e="";for(var f=0;f<l.length;f++)f>0&&(e+="/"),e+=l[f]}e+="/"+p.split("#")[0]}a=u[1]}if(0===p.indexOf("http"))p.indexOf("#")>=0?(e=p.split("#")[0],a=p.split("#")[1]):(e=p,a=""),i.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("#"))a=p.split("#")[1],i.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("/")&&-1===p.indexOf("#")){a=p;var d=e.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);d&&(e=d[0]+p.substring(1),a=""),i.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else i.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else"array"===n.type&&this.resolveTo(e,n.items,i,a)},a.prototype.resolveTo=function(e,t,n,i){var a,o,s=t.$ref,l=e;if("undefined"!=typeof s&&null!==s){if(s.indexOf("#")>=0){var u=s.split("#");if(u[0]&&0===s.indexOf("/"));else if(u[0]&&0===u[0].indexOf("http"))l=u[0],s=u[1];else if(u[0]&&u[0].length>0){for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=u[0]}i=u[1]}else if(0===s.indexOf("http://")||0===s.indexOf("https://"))l=s,i="";else{for(a=e.split("/"),l="",o=0;o<a.length-1;o++)l+=a[o]+"/";l+=s,i=""}n.push({obj:t,resolveAs:"ref",root:l,key:s,location:i})}else if("array"===t.type){var c=t.items;this.resolveTo(e,c,n,i)}else if(t&&t.properties){var p=this.uniqueName("inline_model");t.title&&(p=this.uniqueName(t.title)),delete t.title,this.spec.definitions[p]=r.cloneDeep(t),t.$ref="#/definitions/"+p,delete t.type,delete t.properties}},a.prototype.uniqueName=function(e){for(var t=e,n=0;;){if(!r.isObject(this.spec.definitions[t]))return t;t=e+"_"+n,n++}},a.prototype.resolveAllOf=function(e,t,n){n=n||0,t=t||e;var i;for(var a in t)if(t.hasOwnProperty(a)){var o=t[a];if(null===o)throw new TypeError("Swagger 2.0 does not support null types ("+t+").  See https://github.com/swagger-api/swagger-spec/issues/229.");if("object"==typeof o&&this.resolveAllOf(e,o,n+1),o&&"undefined"!=typeof o.allOf){var s=o.allOf;if(r.isArray(s)){var l=r.cloneDeep(o);delete l.allOf,l["x-composed"]=!0,"undefined"!=typeof o["x-resolved-from"]&&(l["x-resolved-from"]=o["x-resolved-from"]);for(var u=0;u<s.length;u++){var c=s[u],p="self";"undefined"!=typeof c["x-resolved-from"]&&(p=c["x-resolved-from"][0]);for(var h in c)if(l.hasOwnProperty(h))if("properties"===h){var f=c[h];for(i in f){l.properties[i]=r.cloneDeep(f[i]);var d=f[i]["x-resolved-from"];"undefined"!=typeof d&&"self"!==d||(d=p),l.properties[i]["x-resolved-from"]=d}}else if("required"===h){for(var m=l.required.concat(c[h]),g=0;g<m.length;++g)for(var y=g+1;y<m.length;++y)m[g]===m[y]&&m.splice(y--,1);l.required=m}else"x-resolved-from"===h&&l["x-resolved-from"].push(p);else if(l[h]=r.cloneDeep(c[h]),"properties"===h)for(i in l[h])l[h][i]["x-resolved-from"]=p}t[a]=l}}}}},{"./http":5,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isObject":146}],7:[function(e,t,n){"use strict";function i(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"}function r(e,t){var n;return"integer"===e&&"int32"===t?n="integer":"integer"===e&&"int64"===t?n="long":"integer"===e&&"undefined"==typeof t?n="long":"string"===e&&"date-time"===t?n="date-time":"string"===e&&"date"===t?n="date":"number"===e&&"float"===t?n="float":"number"===e&&"double"===t?n="double":"number"===e&&"undefined"==typeof t?n="double":"boolean"===e?n="boolean":"string"===e&&(n="string"),n}function a(e,t){var n="";return"undefined"!=typeof e.$ref?n+=l.simpleRef(e.$ref):"undefined"==typeof e.type?n+="object":"array"===e.type?t?n+=a(e.items||e.$ref||{}):(n+="Array[",n+=a(e.items||e.$ref||{}),n+="]"):n+="integer"===e.type&&"int32"===e.format?"integer":"integer"===e.type&&"int64"===e.format?"long":"integer"===e.type&&"undefined"==typeof e.format?"long":"string"===e.type&&"date-time"===e.format?"date-time":"string"===e.type&&"date"===e.format?"date":"string"===e.type&&"undefined"==typeof e.format?"string":"number"===e.type&&"float"===e.format?"float":"number"===e.type&&"double"===e.format?"double":"number"===e.type&&"undefined"==typeof e.format?"double":"boolean"===e.type?"boolean":e.$ref?l.simpleRef(e.$ref):e.type,n}function o(e,t,n,i){e=l.resolveSchema(e),"function"!=typeof i&&(i=function(e){return(e||{})["default"]}),n=n||{};var r,a,s=e.type||"object",c=e.format;return u.isUndefined(e.example)?u.isUndefined(e.items)&&u.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,u.isUndefined(a)&&(e.$ref?(r=t[l.simpleRef(e.$ref)],u.isUndefined(r)||(u.isUndefined(n[r.name])?(n[r.name]=r,a=o(r.definition,t,n,i),delete n[r.name]):a="array"===r.type?[]:{})):u.isUndefined(e["default"])?"string"===s?a="date-time"===c?(new Date).toISOString():"date"===c?(new Date).toISOString().split("T")[0]:"string":"integer"===s?a=0:"number"===s?a=0:"boolean"===s?a=!0:"object"===s?(a={},u.forEach(e.properties,function(e,r){var s=u.cloneDeep(e);s["default"]=i(e),a[r]=o(s,t,n,i)})):"array"===s&&(a=[],u.isArray(e.items)?u.forEach(e.items,function(e){a.push(o(e,t,n,i))}):u.isPlainObject(e.items)?a.push(o(e.items,t,n,i)):u.isUndefined(e.items)?a.push({}):l.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a}function s(e,t,n,r){function a(e,t,i){var r,a=t;return e.$ref?(a=e.title||l.simpleRef(e.$ref),r=n[a]):u.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,r={definition:e}),i!==!0&&(f[a]=u.isUndefined(r)?{}:r.definition),a}function o(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=a(e,l.simpleRef(e.$ref)):"object"===n?t+=u.isUndefined(e.properties)?"object":a(e):"array"===n?(t+="Array[",u.isArray(e.items)?t+=u.map(e.items,a).join(","):u.isPlainObject(e.items)?t+=u.isUndefined(e.items.$ref)?u.isUndefined(e.items.type)||-1!==u.indexOf(["array","object"],e.items.type)?a(e.items):e.items.type:a(e.items,l.simpleRef(e.items.$ref)):(l.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function s(e,t){var n="",r=e.type||"object",a="array"===r;switch(a&&(r=u.isPlainObject(e.items)&&!u.isUndefined(e.items.type)?e.items.type:"object"),u.isUndefined(e["default"])||(n+=i("Default",e["default"])),r){case"string":e.minLength&&(n+=i("Min. Length",e.minLength)),e.maxLength&&(n+=i("Max. Length",e.maxLength)),e.pattern&&(n+=i("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=i("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=i("Exclusive Min.","true")),e.maximum&&(n+=i("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=i("Exclusive Max.","true")),e.multipleOf&&(n+=i("Multiple Of",e.multipleOf))}if(a&&(e.minItems&&(n+=i("Min. Items",e.minItems)),e.maxItems&&(n+=i("Max. Items",e.maxItems)),e.uniqueItems&&(n+=i("Unique Items","true")),e.collectionFormat&&(n+=i("Coll. Format",e.collectionFormat))),u.isUndefined(e.items)&&u.isArray(e["enum"])){var o;o="number"===r||"integer"===r?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=i("Enum",o)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+r+"</th></tr>"+n+"</table></span>"),t}function c(e,t){var i=e.type||"object",c="array"===e.type,f=p+t+" "+(c?"[":"{")+h;if(t&&d.push(t),c)u.isArray(e.items)?f+="<div>"+u.map(e.items,function(e){var t=e.type||"object";return u.isUndefined(e.$ref)?u.indexOf(["array","object"],t)>-1?"object"===t&&u.isUndefined(e.properties)?"object":a(e):s(e,t):a(e,l.simpleRef(e.$ref))}).join(",</div><div>"):u.isPlainObject(e.items)?f+=u.isUndefined(e.items.$ref)?u.indexOf(["array","object"],e.items.type||"object")>-1?(u.isUndefined(e.items.type)||"object"===e.items.type)&&u.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+a(e.items)+"</div>":"<div>"+s(e.items,e.items.type)+"</div>":"<div>"+a(e.items,l.simpleRef(e.items.$ref))+"</div>":(l.log("Array type's 'items' property is not an array or an object, cannot process"),f+="<div>object</div>");else if(e.$ref)f+="<div>"+a(e,t)+"</div>";else if("object"===i){if(u.isPlainObject(e.properties)){var m=u.map(e.properties,function(t,i){var a,c,p=u.indexOf(e.required,i)>=0,h=u.cloneDeep(t),f=p?"required":"",d='<span class="propName '+f+'">'+i+"</span> (";return h["default"]=r(h),h=l.resolveSchema(h),c=t.description||h.description,u.isUndefined(h.$ref)||(a=n[l.simpleRef(h.$ref)],u.isUndefined(a)||-1!==u.indexOf([void 0,"array","object"],a.definition.type)||(h=l.resolveSchema(a.definition))),d+=o(h),p||(d+=', <span class="propOptKey">optional</span>'),t.readOnly&&(d+=', <span class="propReadOnly">read only</span>'),d+=")",u.isUndefined(c)||(d+=': <span class="propDesc">'+c+"</span>"),h["enum"]&&(d+=' = <span class="propVals">[\''+h["enum"].join("', '")+"']</span>"),"<div"+(t.readOnly?' class="readOnly"':"")+">"+s(h,d)}).join(",</div>");m&&(f+=m+"</div>")}}else f+="<div>"+s(e,i)+"</div>";return f+p+(c?"]":"}")+h}var p='<span class="strong">',h="</span>";if(u.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],r=arguments[2]),n=n||{},t=l.resolveSchema(t),u.isEmpty(t))return p+"Empty"+h;if("string"==typeof t.$ref&&(e=l.simpleRef(t.$ref),t=n[e],"undefined"==typeof t))return p+e+" is not defined!"+h;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof r&&(r=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=c(t,e);u.keys(f).length>0;)u.forEach(f,function(e,t){var n=u.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+c(e,t))});return g}var l=e("./helpers"),u={isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isEmpty:e("lodash-compat/lang/isEmpty"),map:e("lodash-compat/collection/map"),indexOf:e("lodash-compat/array/indexOf"),cloneDeep:e("lodash-compat/lang/cloneDeep"),keys:e("lodash-compat/object/keys"),forEach:e("lodash-compat/collection/forEach")};t.exports.optionHtml=i,t.exports.typeFromJsonSchema=r,t.exports.getStringSignature=a,t.exports.schemaToHTML=s,t.exports.schemaToJSON=o},{"./helpers":4,"lodash-compat/array/indexOf":51,"lodash-compat/collection/forEach":56,"lodash-compat/collection/map":58,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isArray":142,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isUndefined":150,"lodash-compat/object/keys":151}],8:[function(e,t,n){"use strict";var i=e("./http"),r={isObject:e("lodash-compat/lang/isObject")},a=t.exports=function(){this.errors=[],this.warnings=[],this.modelMap={}};a.prototype.setDocumentationLocation=function(e){this.docLocation=e},a.prototype.convert=function(e,t,n,i){if(!e||!Array.isArray(e.apis))return this.finish(i,null);this.clientAuthorizations=t;var r={swagger:"2.0"};r.originalVersion=e.swaggerVersion,this.apiInfo(e,r),this.securityDefinitions(e,r),e.basePath&&this.setDocumentationLocation(e.basePath);var a,o=!1;for(a=0;a<e.apis.length;a++){var s=e.apis[a];Array.isArray(s.operations)&&(o=!0)}o?(this.declaration(e,r),this.finish(i,r)):this.resourceListing(e,r,n,i)},a.prototype.declaration=function(e,t){var n,i,a,o;if(e.apis){0===e.basePath.indexOf("http://")?(a=e.basePath.substring("http://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):0===e.basePath.indexOf("https://")?(a=e.basePath.substring("https://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):t.basePath=e.basePath;var s;if(e.authorizations&&(s=e.authorizations),e.consumes&&(t.consumes=e.consumes),e.produces&&(t.produces=e.produces),r.isObject(e))for(n in e.models){var l=e.models[n],u=l.id||n;this.modelMap[u]=n}for(i=0;i<e.apis.length;i++){var c=e.apis[i],p=c.path,h=c.operations;this.operations(p,e.resourcePath,h,s,t)}var f=e.models||{};this.models(f,t)}},a.prototype.models=function(e,t){if(r.isObject(e)){var n;t.definitions=t.definitions||{};for(n in e){var i,a=e[n],o=[],s={properties:{}};for(i in a.properties){var l=a.properties[i],u={};this.dataType(l,u),l.description&&(u.description=l.description),l["enum"]&&(u["enum"]=l["enum"]),"boolean"==typeof l.required&&l.required===!0&&o.push(i),"string"==typeof l.required&&"true"===l.required&&o.push(i),s.properties[i]=u}o.length>0?s.required=o:s.required=a.required,t.definitions[n]=s}}},a.prototype.extractTag=function(e){var t=e||"default";return 0!==t.indexOf("http:")&&0!==t.indexOf("https:")||(t=t.split(["/"]),t=t[t.length-1].substring()),t.endsWith(".json")&&(t=t.substring(0,t.length-".json".length)),t.replace("/","")},a.prototype.operations=function(e,t,n,i,r){if(Array.isArray(n)){var a;r.paths||(r.paths={});var o=r.paths[e]||{},s=this.extractTag(t);r.tags=r.tags||[];var l=!1;for(a=0;a<r.tags.length;a++){var u=r.tags[a];u.name===s&&(l=!0)}for(l||r.tags.push({name:s}),a=0;a<n.length;a++){var c=n[a],p=(c.method||c.httpMethod).toLowerCase(),h={tags:[s]},f=c.authorizations;if(f&&0===Object.keys(f).length&&(f=i),"undefined"!=typeof f){var d;for(var m in f){h.security=h.security||[];var g=f[m];if(g){var y=[];for(var v in g)y.push(g[v].scope);d={},d[m]=y,h.security.push(d)}else d={},d[m]=[],h.security.push(d)}}c.consumes?h.consumes=c.consumes:r.consumes&&(h.consumes=r.consumes),c.produces?h.produces=c.produces:r.produces&&(h.produces=r.produces),c.summary&&(h.summary=c.summary),c.notes&&(h.description=c.notes),c.nickname&&(h.operationId=c.nickname),c.deprecated&&(h.deprecated=c.deprecated),this.authorizations(f,r),this.parameters(h,c.parameters,r),this.responseMessages(h,c,r),o[p]=h}r.paths[e]=o}},a.prototype.responseMessages=function(e,t){if(r.isObject(t)){var n={};this.dataType(t,n),!n.schema&&n.type&&(n={schema:n}),e.responses=e.responses||{};var i=!1;if(Array.isArray(t.responseMessages)){var a,o=t.responseMessages;for(a=0;a<o.length;a++){var s=o[a],l={description:s.message};200===s.code&&(i=!0),s.responseModel&&(l.schema={$ref:"#/definitions/"+s.responseModel}),e.responses[""+s.code]=l}}i?e.responses["default"]=n:e.responses[200]=n}},a.prototype.authorizations=function(e){!r.isObject(e)},a.prototype.parameters=function(e,t){if(Array.isArray(t)){var n;for(n=0;n<t.length;n++){var i=t[n],r={};if(r.name=i.name,r.description=i.description,r.required=i.required,r["in"]=i.paramType,"body"===r["in"]&&(r.name="body"),"form"===r["in"]&&(r["in"]="formData"),i["enum"]&&(r["enum"]=i["enum"]),i.allowMultiple===!0||"true"===i.allowMultiple){var a={};if(this.dataType(i,a),r.type="array",r.items=a,i.allowableValues){var o=i.allowableValues;"LIST"===o.valueType&&(r["enum"]=o.values)}}else this.dataType(i,r);"undefined"!=typeof i.defaultValue&&(r["default"]=i.defaultValue),e.parameters=e.parameters||[],e.parameters.push(r)}}},a.prototype.dataType=function(e,t){if(r.isObject(e)){e.minimum&&(t.minimum=e.minimum),e.maximum&&(t.maximum=e.maximum),e.format&&(t.format=e.format),"undefined"!=typeof e.defaultValue&&(t["default"]=e.defaultValue);var n=this.toJsonSchema(e);n&&(t=t||{},n.type&&(t.type=n.type),n.format&&(t.format=n.format),n.$ref&&(t.schema={$ref:n.$ref}),n.items&&(t.items=n.items))}},a.prototype.toJsonSchema=function(e){if(!e)return"object";var t=e.type||e.dataType||e.responseClass||"",n=t.toLowerCase(),i=(e.format||"").toLowerCase();if(0===n.indexOf("list[")){var r=t.substring(5,t.length-1),a=this.toJsonSchema({type:r});return{type:"array",items:a}}if("int"===n||"integer"===n&&"int32"===i)return{type:"integer",format:"int32"};if("long"===n||"integer"===n&&"int64"===i)return{type:"integer",format:"int64"};if("integer"===n)return{type:"integer",format:"int64"};if("float"===n||"number"===n&&"float"===i)return{type:"number",format:"float"};if("double"===n||"number"===n&&"double"===i)return{type:"number",format:"double"};if("string"===n&&"date-time"===i||"date"===n)return{type:"string",format:"date-time"};if("string"===n)return{type:"string"};if("file"===n)return{type:"file"};if("boolean"===n)return{type:"boolean"};if("boolean"===n)return{type:"boolean"};if("array"===n||"list"===n){if(e.items){var o=this.toJsonSchema(e.items);return{type:"array",items:o}}return{type:"array",items:{type:"object"}}}return e.$ref?{$ref:this.modelMap[e.$ref]?"#/definitions/"+this.modelMap[e.$ref]:e.$ref}:"void"===n||""===n?{}:this.modelMap[e.type]?{$ref:"#/definitions/"+this.modelMap[e.type]}:{type:e.type}},a.prototype.resourceListing=function(e,t,n,r){var a,o=0,s=this,l=e.apis.length,u=t,c={};n&&n.requestInterceptor&&(c.requestInterceptor=n.requestInterceptor),n&&n.responseInterceptor&&(c.responseInterceptor=n.responseInterceptor);var p="application/json";for(n&&n.swaggerRequestHeaders&&(p=n.swaggerRequestHeaders),0===l&&this.finish(r,t),a=0;l>a;a++){var h=e.apis[a],f=h.path,d=this.getAbsolutePath(e.swaggerVersion,this.docLocation,f);h.description&&(t.tags=t.tags||[],t.tags.push({name:this.extractTag(h.path),description:h.description||""}));var m={url:d,headers:{accept:p},on:{},method:"get"};m.on.response=function(e){o+=1;var t=e.obj;t&&s.declaration(t,u),o===l&&s.finish(r,u)},m.on.error=function(e){console.error(e),o+=1,o===l&&s.finish(r,u)},this.clientAuthorizations&&"function"==typeof this.clientAuthorizations.apply&&this.clientAuthorizations.apply(m),(new i).execute(m,c)}},a.prototype.getAbsolutePath=function(e,t,n){if("1.0"===e&&t.endsWith(".json")){var i=t.lastIndexOf("/");i>0&&(t=t.substring(0,i))}var r=t;return 0===n.indexOf("http://")||0===n.indexOf("https://")?r=n:(t.endsWith("/")&&(r=t.substring(0,t.length-1)),r+=n),r=r.replace("{format}","json")},a.prototype.securityDefinitions=function(e,t){if(e.authorizations){var n;for(n in e.authorizations){var i=!1,r={},a=e.authorizations[n];if("apiKey"===a.type)r.type="apiKey",r["in"]=a.passAs,r.name=a.keyname||n,i=!0;else if("basicAuth"===a.type)r.type="basicAuth",i=!0;else if("oauth2"===a.type){var o,s=a.scopes||[],l={};for(o in s){var u=s[o];l[u.scope]=u.description}if(r.type="oauth2",o>0&&(r.scopes=l),a.grantTypes){if(a.grantTypes.implicit){var c=a.grantTypes.implicit;r.flow="implicit",r.authorizationUrl=c.loginEndpoint,i=!0}if(a.grantTypes.authorization_code&&!r.flow){var p=a.grantTypes.authorization_code;r.flow="accessCode",r.authorizationUrl=p.tokenRequestEndpoint.url,r.tokenUrl=p.tokenEndpoint.url,i=!0}}}i&&(t.securityDefinitions=t.securityDefinitions||{},t.securityDefinitions[n]=r)}}},a.prototype.apiInfo=function(e,t){if(e.info){var n=e.info;t.info={},n.contact&&(t.info.contact={},t.info.contact.email=n.contact),n.description&&(t.info.description=n.description),n.title&&(t.info.title=n.title),n.termsOfServiceUrl&&(t.info.termsOfService=n.termsOfServiceUrl),(n.license||n.licenseUrl)&&(t.license={},n.license&&(t.license.name=n.license),n.licenseUrl&&(t.license.url=n.licenseUrl))}else this.warnings.push("missing info section")},a.prototype.finish=function(e,t){e(t)}},{"./http":5,"lodash-compat/lang/isObject":146}],9:[function(e,t,n){"use strict";var i=(e("../helpers").log,{isPlainObject:e("lodash-compat/lang/isPlainObject"),isString:e("lodash-compat/lang/isString")}),r=e("../schema-markup.js"),a=e("js-yaml"),o=t.exports=function(e,t,n,i){return this.definition=t||{},this.isArray="array"===t.type,this.models=n||{},this.name=e||t.title||"Inline Model",this.modelPropertyMacro=i||function(e){return e["default"]},this};o.prototype.createJSONSample=o.prototype.getSampleValue=function(e){return e=e||{},e[this.name]=this,this.examples&&i.isPlainObject(this.examples)&&this.examples["application/json"]?(this.definition.example=this.examples["application/json"],i.isString(this.definition.example)&&(this.definition.example=a.safeLoad(this.definition.example))):this.definition.example||(this.definition.example=this.examples),r.schemaToJSON(this.definition,this.models,e,this.modelPropertyMacro)},o.prototype.getMockSignature=function(){return r.schemaToHTML(this.name,this.definition,this.models,this.modelPropertyMacro)}},{"../helpers":4,"../schema-markup.js":7,"js-yaml":21,"lodash-compat/lang/isPlainObject":147,"lodash-compat/lang/isString":148}],10:[function(e,t,n){"use strict";function i(e,t){if(r.isEmpty(t))return e[0];for(var n=0,i=t.length;i>n;n++)if(e.indexOf(t[n])>-1)return t[n];return e[0]}var r={cloneDeep:e("lodash-compat/lang/cloneDeep"),isUndefined:e("lodash-compat/lang/isUndefined"),isEmpty:e("lodash-compat/lang/isEmpty"),isObject:e("lodash-compat/lang/isObject")},a=e("../helpers"),o=e("./model"),s=e("../http"),l=e("q"),u=t.exports=function(e,t,n,i,r,a,s,l,u){
+var c=[];if(e=e||{},a=a||{},e&&e.options&&(this.client=e.options.client||null,this.requestInterceptor=e.options.requestInterceptor||null,this.responseInterceptor=e.options.responseInterceptor||null),this.authorizations=a.security,this.basePath=e.basePath||"/",this.clientAuthorizations=u,this.consumes=a.consumes||e.consumes||["application/json"],this.produces=a.produces||e.produces||["application/json"],this.deprecated=a.deprecated,this.description=a.description,this.host=e.host||"localhost",this.method=i||c.push("Operation "+n+" is missing method."),this.models=l||{},this.nickname=n||c.push("Operations must have a nickname."),this.operation=a,this.operations={},this.parameters=null!==a?a.parameters||[]:{},this.parent=e,this.path=r||c.push("Operation "+this.nickname+" is missing path."),this.responses=a.responses||{},this.scheme=t||e.scheme||"http",this.schemes=a.schemes||e.schemes,this.security=a.security||e.security,this.summary=a.summary||"",this.type=null,this.useJQuery=e.useJQuery,this.enableCookies=e.enableCookies,this.parameterMacro=e.parameterMacro||function(e,t){return t["default"]},this.inlineModels=[],"string"==typeof this.deprecated)switch(this.deprecated.toLowerCase()){case"true":case"yes":case"1":this.deprecated=!0;break;case"false":case"no":case"0":case null:this.deprecated=!1;break;default:this.deprecated=Boolean(this.deprecated)}var p,h;if(s){var f;for(f in s)h=new o(f,s[f],this.models,e.modelPropertyMacro),h&&(this.models[f]=h)}else s={};for(p=0;p<this.parameters.length;p++){var d=this.parameters[p];d["default"]=this.parameterMacro(this,d),"array"===d.type&&(d.isList=!0,d.allowMultiple=!0);var m=this.getType(d);if(m&&"boolean"===m.toString().toLowerCase()&&(d.allowableValues={},d.isList=!0,d["enum"]=[!0,!1]),"undefined"!=typeof d["x-example"]){var g=d["x-example"];d["default"]=g}if(d["x-examples"]){var g=d["x-examples"]["default"];"undefined"!=typeof g&&(d["default"]=g)}var y=d["enum"]||d.items&&d.items["enum"];if("undefined"!=typeof y){var v;for(d.allowableValues={},d.allowableValues.values=[],d.allowableValues.descriptiveValues=[],v=0;v<y.length;v++){var b=y[v],w=b===d["default"]||b+""===d["default"];d.allowableValues.values.push(b),d.allowableValues.descriptiveValues.push({value:b+"",isDefault:w})}}"array"===d.type&&(m=[m],"undefined"==typeof d.allowableValues&&(delete d.isList,delete d.allowMultiple)),d.modelSignature={type:m,definitions:this.models},d.signature=this.getModelSignature(m,this.models).toString(),d.sampleJSON=this.getModelSampleJSON(m,this.models),d.responseClassSignature=d.signature}var x,A,O=this.responses;if(O[200]?(A=O[200],x="200"):O[201]?(A=O[201],x="201"):O[202]?(A=O[202],x="202"):O[203]?(A=O[203],x="203"):O[204]?(A=O[204],x="204"):O[205]?(A=O[205],x="205"):O[206]?(A=O[206],x="206"):O["default"]&&(A=O["default"],x="default"),A&&A.schema){var j,_=this.resolveModel(A.schema,s);delete O[x],_?(this.successResponse={},j=this.successResponse[x]=_):A.schema.type&&"object"!==A.schema.type&&"array"!==A.schema.type?(this.successResponse={},j=this.successResponse[x]=A.schema):(this.successResponse={},j=this.successResponse[x]=new o(void 0,A.schema||{},this.models,e.modelPropertyMacro)),j&&(A.description&&(j.description=A.description),A.examples&&(j.examples=A.examples),A.headers&&(j.headers=A.headers)),this.type=A}return c.length>0&&this.resource&&this.resource.api&&this.resource.api.fail&&this.resource.api.fail(c),this};u.prototype.isDefaultArrayItemValue=function(e,t){return t["default"]&&Array.isArray(t["default"])?-1!==t["default"].indexOf(e):e===t["default"]},u.prototype.getType=function(e){var t,n=e.type,i=e.format,r=!1;"integer"===n&&"int32"===i?t="integer":"integer"===n&&"int64"===i?t="long":"integer"===n?t="integer":"string"===n?t="date-time"===i?"date-time":"date"===i?"date":"string":"number"===n&&"float"===i?t="float":"number"===n&&"double"===i?t="double":"number"===n?t="double":"boolean"===n?t="boolean":"array"===n?(r=!0,e.items&&(t=this.getType(e.items))):"file"===n&&(t="file"),e.$ref&&(t=a.simpleRef(e.$ref));var o=e.schema;if(o){var s=o.$ref;return s?(s=a.simpleRef(s),r?[s]:s):"object"===o.type?this.addInlineModel(o):this.getType(o)}return r?[t]:t},u.prototype.addInlineModel=function(e){var t=this.inlineModels.length,n=this.resolveModel(e,{});return n?(this.inlineModels.push(n),"Inline Model "+t):null},u.prototype.getInlineModel=function(e){if(/^Inline Model \d+$/.test(e)){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},u.prototype.resolveModel=function(e,t){if("undefined"!=typeof e.$ref){var n=e.$ref;if(0===n.indexOf("#/definitions/")&&(n=n.substring("#/definitions/".length)),t[n])return new o(n,t[n],this.models,this.parent.modelPropertyMacro)}else if(e&&"object"==typeof e&&("object"===e.type||r.isUndefined(e.type)))return new o(void 0,e,this.models,this.parent.modelPropertyMacro);return null},u.prototype.help=function(e){for(var t=this.nickname+": "+this.summary+"\n",n=0;n<this.parameters.length;n++){var i=this.parameters[n],r=i.signature;t+="\n  * "+i.name+" ("+r+"): "+i.description}return"undefined"==typeof e&&a.log(t),t},u.prototype.getModelSignature=function(e,t){var n,i;return e instanceof Array&&(i=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):this.getInlineModel(e)?(e=this.getInlineModel(e),n=!1):n=!0,n?i?"Array["+e+"]":e.toString():i?"Array["+e.getMockSignature()+"]":e.getMockSignature()},u.prototype.supportHeaderParams=function(){return!0},u.prototype.supportedSubmitMethods=function(){return this.parent.supportedSubmitMethods},u.prototype.getHeaderParams=function(e){for(var t=this.setContentTypes(e,{}),n=0;n<this.parameters.length;n++){var i=this.parameters[n];if("undefined"!=typeof e[i.name]&&"header"===i["in"]){var r=e[i.name];Array.isArray(r)&&(r=r.toString()),t[i.name]=r}}return t},u.prototype.urlify=function(e){for(var t={},n=this.path,i="",r=0;r<this.parameters.length;r++){var a=this.parameters[r];if("undefined"!=typeof e[a.name])if("path"===a["in"]){var o=new RegExp("{"+a.name+"}","gi"),s=e[a.name];s=Array.isArray(s)?this.encodePathCollection(a.collectionFormat,a.name,s):this.encodePathParam(s),n=n.replace(o,s)}else if("query"===a["in"]&&"undefined"!=typeof e[a.name])if(i+=""===i?"?":"&","undefined"!=typeof a.collectionFormat){var l=e[a.name];i+=Array.isArray(l)?this.encodeQueryCollection(a.collectionFormat,a.name,l):this.encodeQueryParam(a.name)+"="+this.encodeQueryParam(e[a.name])}else i+=this.encodeQueryParam(a.name)+"="+this.encodeQueryParam(e[a.name]);else"formData"===a["in"]&&(t[a.name]=e[a.name])}var u=this.scheme+"://"+this.host;return"/"!==this.basePath&&(u+=this.basePath),u+n+i},u.prototype.getMissingParams=function(e){var t,n=[];for(t=0;t<this.parameters.length;t++){var i=this.parameters[t];i.required===!0&&"undefined"==typeof e[i.name]&&(n=i.name)}return n},u.prototype.getBody=function(e,t,n){for(var i,r,a,o,s={},l=!1,u=0;u<this.parameters.length;u++){var c=this.parameters[u];"undefined"!=typeof t[c.name]?"body"===c["in"]?r=t[c.name]:"formData"===c["in"]&&(s[c.name]=t[c.name],i=!0):"body"===c["in"]&&(l=!0)}if(l&&"undefined"==typeof r){var p=e["Content-Type"];p&&0===p.indexOf("application/json")&&(r="{}")}var h=!1;if(e["Content-Type"]&&e["Content-Type"].indexOf("multipart/form-data")>=0&&(h=!0),i&&!h){var f="";for(a in s)o=s[a],"undefined"!=typeof o&&(""!==f&&(f+="&"),f+=encodeURIComponent(a)+"="+encodeURIComponent(o));r=f}else if(h&&n.useJQuery){var d=new FormData;d.type="formData";for(a in s)o=t[a],"undefined"!=typeof o&&("file"===o.type&&o.value?(delete e["Content-Type"],d.append(a,o.value)):d.append(a,o));r=d}return r},u.prototype.getModelSampleJSON=function(e,t){var n,i,a;if(t=t||{},n=e instanceof Array,a=n?e[0]:e,t[a]?i=t[a].createJSONSample():this.getInlineModel(a)&&(i=this.getInlineModel(a).createJSONSample()),i){if(i=n?[i]:i,"string"==typeof i)return i;if(r.isObject(i)){var o=i;if(i instanceof Array&&i.length>0&&(o=i[0]),o.nodeName&&"Node"==typeof o){var s=(new XMLSerializer).serializeToString(o);return this.formatXml(s)}return JSON.stringify(i,null,2)}return i}},u.prototype["do"]=function(e,t,n,i,r){return this.execute(e,t,n,i,r)},u.prototype.execute=function(e,t,n,i,o){var u,c,p,h=e||{},f={};r.isObject(t)&&(f=t,u=n,c=i),this.client&&(f.client=this.client),!f.requestInterceptor&&this.requestInterceptor&&(f.requestInterceptor=this.requestInterceptor),!f.responseInterceptor&&this.responseInterceptor&&(f.responseInterceptor=this.responseInterceptor),"function"==typeof t&&(u=t,c=n),this.parent.usePromise?p=l.defer():(u=u||this.parent.defaultSuccessCallback||a.log,c=c||this.parent.defaultErrorCallback||a.log),"undefined"==typeof f.useJQuery&&(f.useJQuery=this.useJQuery),"undefined"==typeof f.enableCookies&&(f.enableCookies=this.enableCookies);var d=this.getMissingParams(h);if(d.length>0){var m="missing required params: "+d;return a.fail(m),this.parent.usePromise?(p.reject(m),p.promise):(c(m,o),{})}var g,y=this.getHeaderParams(h),v=this.setContentTypes(h,f),b={};for(g in y)b[g]=y[g];for(g in v)b[g]=v[g];var w=this.getBody(v,h,f),x=this.urlify(h);if(x.indexOf(".{format}")>0&&b){var A=b.Accept||b.accept;A&&A.indexOf("json")>0?x=x.replace(".{format}",".json"):A&&A.indexOf("xml")>0&&(x=x.replace(".{format}",".xml"))}var O={url:x,method:this.method.toUpperCase(),body:w,enableCookies:f.enableCookies,useJQuery:f.useJQuery,deferred:p,headers:b,clientAuthorizations:f.clientAuthorizations,on:{response:function(e){return p?(p.resolve(e),p.promise):u(e,o)},error:function(e){return p?(p.reject(e),p.promise):c(e,o)}}};return this.clientAuthorizations.apply(O,this.operation.security),f.mock===!0?O:(new s).execute(O,f)},u.prototype.setContentTypes=function(e,t){var n,r,o=this.parameters,s=e.parameterContentType||i(this.consumes,["application/json","application/yaml"]),l=t.responseContentType||i(this.produces,["application/json","application/yaml"]),u=[],c=[],p={};for(r=0;r<o.length;r++){var h=o[r];if("formData"===h["in"])"file"===h.type?u.push(h):c.push(h);else if("header"===h["in"]&&t){var f=h.name,d=t[h.name];"undefined"!=typeof t[h.name]&&(p[f]=d)}else"body"===h["in"]&&"undefined"!=typeof e[h.name]&&(n=e[h.name])}return"post"===this.method||"put"===this.method||"patch"===this.method||("delete"===this.method||"get"===this.method)&&n?(t.requestContentType&&(s=t.requestContentType),c.length>0&&(s=t.requestContentType?t.requestContentType:u.length>0?"multipart/form-data":"application/x-www-form-urlencoded")):s=null,s&&this.consumes&&-1===this.consumes.indexOf(s)&&a.log("server doesn't consume "+s+", try "+JSON.stringify(this.consumes)),this.matchesAccept(l)||a.log("server can't produce "+l),(s&&""!==n||"application/x-www-form-urlencoded"===s)&&(p["Content-Type"]=s),l&&(p.Accept=l),p},u.prototype.matchesAccept=function(e){return e&&this.produces?-1!==this.produces.indexOf(e)||-1!==this.produces.indexOf("*/*"):!0},u.prototype.asCurl=function(e,t){var n={mock:!0};if("object"==typeof t)for(var i in t)n[i]=t[i];var a=this.execute(e,n);this.clientAuthorizations.apply(a,this.operation.security);var o=[];if(o.push("-X "+this.method.toUpperCase()),"undefined"!=typeof a.headers){var s;for(s in a.headers){var l=a.headers[s];"string"==typeof l&&(l=l.replace(/\'/g,"\\u0027")),o.push("--header '"+s+": "+l+"'")}}if(a.body){var u;u=r.isObject(a.body)?JSON.stringify(a.body):a.body,o.push("-d '"+u.replace(/\'/g,"\\u0027")+"'")}return"curl "+o.join(" ")+" '"+a.url+"'"},u.prototype.encodePathCollection=function(e,t,n){var i,r="",a="";for(a="ssv"===e?"%20":"tsv"===e?"\\t":"pipes"===e?"|":",",i=0;i<n.length;i++)0===i?r=this.encodeQueryParam(n[i]):r+=a+this.encodeQueryParam(n[i]);return r},u.prototype.encodeQueryCollection=function(e,t,n){var i,r="";if("default"===e||"multi"===e)for(i=0;i<n.length;i++)i>0&&(r+="&"),r+=this.encodeQueryParam(t)+"="+this.encodeQueryParam(n[i]);else{var a="";if("csv"===e)a=",";else if("ssv"===e)a="%20";else if("tsv"===e)a="\\t";else if("pipes"===e)a="|";else if("brackets"===e)for(i=0;i<n.length;i++)0!==i&&(r+="&"),r+=this.encodeQueryParam(t)+"[]="+this.encodeQueryParam(n[i]);if(""!==a)for(i=0;i<n.length;i++)0===i?r=this.encodeQueryParam(t)+"="+this.encodeQueryParam(n[i]):r+=a+this.encodeQueryParam(n[i])}return r},u.prototype.encodeQueryParam=function(e){return encodeURIComponent(e)},u.prototype.encodePathParam=function(e){return encodeURIComponent(e)}},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":140,"lodash-compat/lang/isEmpty":143,"lodash-compat/lang/isObject":146,"lodash-compat/lang/isUndefined":150,q:159}],11:[function(e,t,n){"use strict";var i=t.exports=function(e,t,n,i){this.description=t,this.externalDocs=n,this.name=e,this.operation=i,this.operationsArray=[],this.path=e,this.tag=e};i.prototype.sort=function(){}},{}],12:[function(e,t,n){},{}],13:[function(e,t,n){function i(){if(!s){s=!0;for(var e,t=o.length;t;){e=o,o=[];for(var n=-1;++n<t;)e[n]();t=o.length}s=!1}}function r(){}var a=t.exports={},o=[],s=!1;a.nextTick=function(e){o.push(e),s||setTimeout(i,0)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=r,a.addListener=r,a.once=r,a.off=r,a.removeListener=r,a.removeAllListeners=r,a.emit=r,a.binding=function(e){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(e){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}},{}],14:[function(e,t,n){(function(e){!function(){"use strict";function n(t){var n;return n=t instanceof e?t:new e(t.toString(),"binary"),n.toString("base64")}t.exports=n}()}).call(this,e("buffer").Buffer)},{buffer:15}],15:[function(e,t,n){function i(){return r.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function r(e){return this instanceof r?(this.length=0,this.parent=void 0,"number"==typeof e?a(this,e):"string"==typeof e?o(this,e,arguments.length>1?arguments[1]:"utf8"):s(this,e)):arguments.length>1?new r(e,arguments[1]):new r(e)}function a(e,t){if(e=d(e,0>t?0:0|m(t)),!r.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)e[n]=0;return e}function o(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var i=0|y(t,n);return e=d(e,i),e.write(t,n),e}function s(e,t){if(r.isBuffer(t))return l(e,t);if(K(t))return u(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return c(e,t);if(t instanceof ArrayBuffer)return p(e,t)}return t.length?h(e,t):f(e,t)}function l(e,t){var n=0|m(t.length);return e=d(e,n),t.copy(e,0,0,n),e}function u(e,t){var n=0|m(t.length);e=d(e,n);for(var i=0;n>i;i+=1)e[i]=255&t[i];return e}function c(e,t){var n=0|m(t.length);e=d(e,n);for(var i=0;n>i;i+=1)e[i]=255&t[i];return e}function p(e,t){return r.TYPED_ARRAY_SUPPORT?(t.byteLength,e=r._augment(new Uint8Array(t))):e=c(e,new Uint8Array(t)),e}function h(e,t){var n=0|m(t.length);e=d(e,n);for(var i=0;n>i;i+=1)e[i]=255&t[i];return e}function f(e,t){var n,i=0;"Buffer"===t.type&&K(t.data)&&(n=t.data,i=0|m(n.length)),e=d(e,i);for(var r=0;i>r;r+=1)e[r]=255&n[r];return e}function d(e,t){r.TYPED_ARRAY_SUPPORT?e=r._augment(new Uint8Array(t)):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=r.poolSize>>>1;return n&&(e.parent=W),e}function m(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function g(e,t){if(!(this instanceof g))return new g(e,t);var n=new r(e,t);return delete n.parent,n}function y(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var i=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return V(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(i)return V(e).length;t=(""+t).toLowerCase(),i=!0}}function v(e,t,n){var i=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),0>t&&(t=0),n>this.length&&(n=this.length),t>=n)return"";for(;;)switch(e){case"hex":return I(this,t,n);case"utf8":case"utf-8":return S(this,t,n);case"ascii":return C(this,t,n);case"binary":return E(this,t,n);case"base64":return _(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,t,n);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),i=!0}}function b(e,t,n,i){n=Number(n)||0;var r=e.length-n;i?(i=Number(i),i>r&&(i=r)):i=r;var a=t.length;if(a%2!==0)throw new Error("Invalid hex string");i>a/2&&(i=a/2);for(var o=0;i>o;o++){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+o]=s}return o}function w(e,t,n,i){return J(V(t,e.length-n),e,n,i)}function x(e,t,n,i){return J(q(t),e,n,i)}function A(e,t,n,i){return x(e,t,n,i)}function O(e,t,n,i){return J(H(t),e,n,i)}function j(e,t,n,i){return J(z(t,e.length-n),e,n,i)}function _(e,t,n){return 0===t&&n===e.length?Q.fromByteArray(e):Q.fromByteArray(e.slice(t,n))}function S(e,t,n){n=Math.min(e.length,n);for(var i=[],r=t;n>r;){var a=e[r],o=null,s=a>239?4:a>223?3:a>191?2:1;if(n>=r+s){var l,u,c,p;switch(s){case 1:128>a&&(o=a);break;case 2:l=e[r+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[r+1],u=e[r+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(55296>p||p>57343)&&(o=p));break;case 4:l=e[r+1],u=e[r+2],c=e[r+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&1114112>p&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,i.push(o>>>10&1023|55296),o=56320|1023&o),i.push(o),r+=s}return k(i)}function k(e){var t=e.length;if(X>=t)return String.fromCharCode.apply(String,e);for(var n="",i=0;t>i;)n+=String.fromCharCode.apply(String,e.slice(i,i+=X));return n}function C(e,t,n){var i="";n=Math.min(e.length,n);for(var r=t;n>r;r++)i+=String.fromCharCode(127&e[r]);return i}function E(e,t,n){var i="";n=Math.min(e.length,n);for(var r=t;n>r;r++)i+=String.fromCharCode(e[r]);return i}function I(e,t,n){var i=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>i)&&(n=i);for(var r="",a=t;n>a;a++)r+=B(e[a]);return r}function T(e,t,n){for(var i=e.slice(t,n),r="",a=0;a<i.length;a+=2)r+=String.fromCharCode(i[a]+256*i[a+1]);return r}function $(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,n,i,a,o){if(!r.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>a||o>t)throw new RangeError("value is out of bounds");if(n+i>e.length)throw new RangeError("index out of range")}function M(e,t,n,i){0>t&&(t=65535+t+1);for(var r=0,a=Math.min(e.length-n,2);a>r;r++)e[n+r]=(t&255<<8*(i?r:1-r))>>>8*(i?r:1-r)}function P(e,t,n,i){0>t&&(t=4294967295+t+1);for(var r=0,a=Math.min(e.length-n,4);a>r;r++)e[n+r]=t>>>8*(i?r:3-r)&255}function L(e,t,n,i,r,a){if(t>r||a>t)throw new RangeError("value is out of bounds");if(n+i>e.length)throw new RangeError("index out of range");if(0>n)throw new RangeError("index out of range")}function D(e,t,n,i,r){return r||L(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),Y.write(e,t,n,i,23,4),n+4}function R(e,t,n,i,r){return r||L(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),Y.write(e,t,n,i,52,8),n+8}function N(e){if(e=F(e).replace(Z,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function F(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function B(e){return 16>e?"0"+e.toString(16):e.toString(16)}function V(e,t){t=t||1/0;for(var n,i=e.length,r=null,a=[],o=0;i>o;o++){if(n=e.charCodeAt(o),n>55295&&57344>n){if(!r){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===i){(t-=3)>-1&&a.push(239,191,189);continue}r=n;continue}if(56320>n){(t-=3)>-1&&a.push(239,191,189),r=n;continue}n=r-55296<<10|n-56320|65536}else r&&(t-=3)>-1&&a.push(239,191,189);if(r=null,128>n){if((t-=1)<0)break;a.push(n)}else if(2048>n){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function q(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function z(e,t){for(var n,i,r,a=[],o=0;o<e.length&&!((t-=2)<0);o++)n=e.charCodeAt(o),i=n>>8,r=n%256,a.push(r),a.push(i);return a}function H(e){return Q.toByteArray(N(e))}function J(e,t,n,i){for(var r=0;i>r&&!(r+n>=t.length||r>=e.length);r++)t[r+n]=e[r];return r}var Q=e("base64-js"),Y=e("ieee754"),K=e("is-array");n.Buffer=r,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,r.poolSize=8192;var W={};r.TYPED_ARRAY_SUPPORT=function(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}(),r.isBuffer=function(e){return!(null==e||!e._isBuffer)},r.compare=function(e,t){if(!r.isBuffer(e)||!r.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,i=t.length,a=0,o=Math.min(n,i);o>a&&e[a]===t[a];)++a;return a!==o&&(n=e[a],i=t[a]),i>n?-1:n>i?1:0},r.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},r.concat=function(e,t){if(!K(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new r(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var i=new r(t),a=0;for(n=0;n<e.length;n++){var o=e[n];o.copy(i,a),a+=o.length}return i},r.byteLength=y,r.prototype.length=void 0,r.prototype.parent=void 0,r.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?S(this,0,e):v.apply(this,arguments)},r.prototype.equals=function(e){if(!r.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===r.compare(this,e)},r.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},r.prototype.compare=function(e){if(!r.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:r.compare(this,e)},r.prototype.indexOf=function(e,t){function n(e,t,n){for(var i=-1,r=0;n+r<e.length;r++)if(e[n+r]===t[-1===i?0:r-i]){if(-1===i&&(i=r),r-i+1===t.length)return n+i}else i=-1;return-1}if(t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(r.isBuffer(e))return n(this,e,t);if("number"==typeof e)return r.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},r.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},r.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},r.prototype.write=function(e,t,n,i){if(void 0===t)i="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)i=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===i&&(i="utf8")):(i=n,n=void 0);else{var r=i;i=t,t=0|n,n=r}var a=this.length-t;if((void 0===n||n>a)&&(n=a),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");i||(i="utf8");for(var o=!1;;)switch(i){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return x(this,e,t,n);case"binary":return A(this,e,t,n);case"base64":return O(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return j(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),o=!0}},r.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var X=4096;r.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var i;if(r.TYPED_ARRAY_SUPPORT)i=r._augment(this.subarray(e,t));else{var a=t-e;i=new r(a,void 0);for(var o=0;a>o;o++)i[o]=this[o+e]}return i.length&&(i.parent=this.parent||this),i},r.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||$(e,t,this.length);for(var i=this[e],r=1,a=0;++a<t&&(r*=256);)i+=this[e+a]*r;return i},r.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||$(e,t,this.length);for(var i=this[e+--t],r=1;t>0&&(r*=256);)i+=this[e+--t]*r;return i},r.prototype.readUInt8=function(e,t){return t||$(e,1,this.length),this[e]},r.prototype.readUInt16LE=function(e,t){return t||$(e,2,this.length),this[e]|this[e+1]<<8},r.prototype.readUInt16BE=function(e,t){return t||$(e,2,this.length),this[e]<<8|this[e+1]},r.prototype.readUInt32LE=function(e,t){return t||$(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},r.prototype.readUInt32BE=function(e,t){return t||$(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},r.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||$(e,t,this.length);for(var i=this[e],r=1,a=0;++a<t&&(r*=256);)i+=this[e+a]*r;return r*=128,i>=r&&(i-=Math.pow(2,8*t)),i},r.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||$(e,t,this.length);for(var i=t,r=1,a=this[e+--i];i>0&&(r*=256);)a+=this[e+--i]*r;return r*=128,a>=r&&(a-=Math.pow(2,8*t)),a},r.prototype.readInt8=function(e,t){return t||$(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},r.prototype.readInt16LE=function(e,t){t||$(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},r.prototype.readInt16BE=function(e,t){t||$(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},r.prototype.readInt32LE=function(e,t){return t||$(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},r.prototype.readInt32BE=function(e,t){return t||$(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},r.prototype.readFloatLE=function(e,t){return t||$(e,4,this.length),Y.read(this,e,!0,23,4)},r.prototype.readFloatBE=function(e,t){return t||$(e,4,this.length),Y.read(this,e,!1,23,4)},r.prototype.readDoubleLE=function(e,t){return t||$(e,8,this.length),Y.read(this,e,!0,52,8)},r.prototype.readDoubleBE=function(e,t){return t||$(e,8,this.length),Y.read(this,e,!1,52,8)},r.prototype.writeUIntLE=function(e,t,n,i){e=+e,t=0|t,n=0|n,i||U(this,e,t,n,Math.pow(2,8*n),0);var r=1,a=0;for(this[t]=255&e;++a<n&&(r*=256);)this[t+a]=e/r&255;return t+n},r.prototype.writeUIntBE=function(e,t,n,i){e=+e,t=0|t,n=0|n,i||U(this,e,t,n,Math.pow(2,8*n),0);var r=n-1,a=1;for(this[t+r]=255&e;--r>=0&&(a*=256);)this[t+r]=e/a&255;return t+n},r.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,255,0),r.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=e,t+1},r.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},r.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},r.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),r.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=e):P(this,e,t,!0),t+4},r.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):P(this,e,t,!1),t+4},r.prototype.writeIntLE=function(e,t,n,i){if(e=+e,t=0|t,!i){var r=Math.pow(2,8*n-1);U(this,e,t,n,r-1,-r)}var a=0,o=1,s=0>e?1:0;for(this[t]=255&e;++a<n&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},r.prototype.writeIntBE=function(e,t,n,i){if(e=+e,t=0|t,!i){var r=Math.pow(2,8*n-1);U(this,e,t,n,r-1,-r)}var a=n-1,o=1,s=0>e?1:0;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},r.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,127,-128),r.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=e,t+1},r.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},r.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},r.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),r.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):P(this,e,t,!0),t+4},r.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),r.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):P(this,e,t,!1),t+4},r.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},r.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},r.prototype.writeDoubleLE=function(e,t,n){return R(this,e,t,!0,n)},r.prototype.writeDoubleBE=function(e,t,n){return R(this,e,t,!1,n)},r.prototype.copy=function(e,t,n,i){if(n||(n=0),i||0===i||(i=this.length),t>=e.length&&(t=e.length),t||(t=0),i>0&&n>i&&(i=n),i===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>i)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t<i-n&&(i=e.length-t+n);var a,o=i-n;if(this===e&&t>n&&i>t)for(a=o-1;a>=0;a--)e[a+t]=this[a+n];else if(1e3>o||!r.TYPED_ARRAY_SUPPORT)for(a=0;o>a;a++)e[a+t]=this[a+n];else e._set(this.subarray(n,n+o),t);return o},r.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),t>n)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(0>t||t>=this.length)throw new RangeError("start out of bounds");if(0>n||n>this.length)throw new RangeError("end out of bounds");var i;if("number"==typeof e)for(i=t;n>i;i++)this[i]=e;else{var r=V(e.toString()),a=r.length;for(i=t;n>i;i++)this[i]=r[i%a]}return this}},r.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(r.TYPED_ARRAY_SUPPORT)return new r(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;n>t;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var G=r.prototype;r._augment=function(e){return e.constructor=r,e._isBuffer=!0,e._set=e.set,e.get=G.get,e.set=G.set,e.write=G.write,e.toString=G.toString,e.toLocaleString=G.toString,e.toJSON=G.toJSON,e.equals=G.equals,e.compare=G.compare,e.indexOf=G.indexOf,e.copy=G.copy,e.slice=G.slice,e.readUIntLE=G.readUIntLE,e.readUIntBE=G.readUIntBE,e.readUInt8=G.readUInt8,e.readUInt16LE=G.readUInt16LE,e.readUInt16BE=G.readUInt16BE,e.readUInt32LE=G.readUInt32LE,e.readUInt32BE=G.readUInt32BE,e.readIntLE=G.readIntLE,e.readIntBE=G.readIntBE,e.readInt8=G.readInt8,e.readInt16LE=G.readInt16LE,e.readInt16BE=G.readInt16BE,e.readInt32LE=G.readInt32LE,e.readInt32BE=G.readInt32BE,e.readFloatLE=G.readFloatLE,e.readFloatBE=G.readFloatBE,e.readDoubleLE=G.readDoubleLE,e.readDoubleBE=G.readDoubleBE,e.writeUInt8=G.writeUInt8,e.writeUIntLE=G.writeUIntLE,e.writeUIntBE=G.writeUIntBE,e.writeUInt16LE=G.writeUInt16LE,e.writeUInt16BE=G.writeUInt16BE,e.writeUInt32LE=G.writeUInt32LE,e.writeUInt32BE=G.writeUInt32BE,e.writeIntLE=G.writeIntLE,e.writeIntBE=G.writeIntBE,e.writeInt8=G.writeInt8,e.writeInt16LE=G.writeInt16LE,e.writeInt16BE=G.writeInt16BE,e.writeInt32LE=G.writeInt32LE,e.writeInt32BE=G.writeInt32BE,e.writeFloatLE=G.writeFloatLE,e.writeFloatBE=G.writeFloatBE,e.writeDoubleLE=G.writeDoubleLE,e.writeDoubleBE=G.writeDoubleBE,e.fill=G.fill,e.inspect=G.inspect,e.toArrayBuffer=G.toArrayBuffer,e};var Z=/[^+\/0-9A-Za-z-_]/g},{"base64-js":16,ieee754:17,"is-array":18}],16:[function(e,t,n){var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===o||t===p?62:t===s||t===h?63:l>t?-1:l+10>t?t-l+26+26:c+26>t?t-c:u+26>t?t-u+26:void 0}function n(e){function n(e){u[p++]=e}var i,r,o,s,l,u;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var c=e.length;l="="===e.charAt(c-2)?2:"="===e.charAt(c-1)?1:0,u=new a(3*e.length/4-l),o=l>0?e.length-4:e.length;var p=0;for(i=0,r=0;o>i;i+=4,r+=3)s=t(e.charAt(i))<<18|t(e.charAt(i+1))<<12|t(e.charAt(i+2))<<6|t(e.charAt(i+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===l?(s=t(e.charAt(i))<<2|t(e.charAt(i+1))>>4,n(255&s)):1===l&&(s=t(e.charAt(i))<<10|t(e.charAt(i+1))<<4|t(e.charAt(i+2))>>2,n(s>>8&255),n(255&s)),u}function r(e){function t(e){return i.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var r,a,o,s=e.length%3,l="";for(r=0,o=e.length-s;o>r;r+=3)a=(e[r]<<16)+(e[r+1]<<8)+e[r+2],l+=n(a);switch(s){case 1:a=e[e.length-1],l+=t(a>>2),l+=t(a<<4&63),l+="==";break;case 2:a=(e[e.length-2]<<8)+e[e.length-1],l+=t(a>>10),l+=t(a>>4&63),l+=t(a<<2&63),l+="="}return l}var a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="+".charCodeAt(0),s="/".charCodeAt(0),l="0".charCodeAt(0),u="a".charCodeAt(0),c="A".charCodeAt(0),p="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=r}("undefined"==typeof n?this.base64js={}:n)},{}],17:[function(e,t,n){n.read=function(e,t,n,i,r){var a,o,s=8*r-i-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?r-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=i;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,i),a-=u}return(f?-1:1)*o*Math.pow(2,a-i)},n.write=function(e,t,n,i,r,a){var o,s,l,u=8*a-r-1,c=(1<<u)-1,p=c>>1,h=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,f=i?0:a-1,d=i?1:-1,m=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,r),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,r),o=0));r>=8;e[n+f]=255&s,f+=d,s/=256,r-=8);for(o=o<<r|s,u+=r;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],18:[function(e,t,n){var i=Array.isArray,r=Object.prototype.toString;t.exports=i||function(e){return!!e&&"[object Array]"==r.call(e)}},{}],19:[function(e,t,n){function i(e){return e?r(e):void 0}function r(e){for(var t in i.prototype)e[t]=i.prototype[t];return e}t.exports=i,i.prototype.on=i.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},i.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},i.prototype.off=i.prototype.removeListener=i.prototype.removeAllListeners=i.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+e];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var i,r=0;r<n.length;r++)if(i=n[r],i===t||i.fn===t){n.splice(r,1);break}return this},i.prototype.emit=function(e){this._callbacks=this._callbacks||{};var t=[].slice.call(arguments,1),n=this._callbacks["$"+e];if(n){n=n.slice(0);for(var i=0,r=n.length;r>i;++i)n[i].apply(this,t)}return this},i.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},i.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}],20:[function(e,t,n){!function(){"use strict";function e(t,n,i,r){return this instanceof e?(this.domain=t||void 0,this.path=n||"/",this.secure=!!i,this.script=!!r,this):new e(t,n,i,r)}function t(e,n,i){return e instanceof t?e:this instanceof t?(this.name=null,this.value=null,this.expiration_date=1/0,this.path=String(i||"/"),this.explicit_path=!1,this.domain=n||null,this.explicit_domain=!1,this.secure=!1,this.noscript=!1,e&&this.parse(e,n,i),this):new t(e,n,i)}function i(){var e,n,r;return this instanceof i?(e=Object.create(null),this.setCookie=function(i,a,o){var s,l;if(i=new t(i,a,o),s=i.expiration_date<=Date.now(),void 0!==e[i.name]){for(n=e[i.name],l=0;l<n.length;l+=1)if(r=n[l],r.collidesWith(i))return s?(n.splice(l,1),0===n.length&&delete e[i.name],!1):(n[l]=i,i);return s?!1:(n.push(i),i)}return s?!1:(e[i.name]=[i],e[i.name])},this.getCookie=function(t,i){var r,a;if(n=e[t])for(a=0;a<n.length;a+=1)if(r=n[a],r.expiration_date<=Date.now())0===n.length&&delete e[r.name];else if(r.matches(i))return r},this.getCookies=function(t){var n,i,r=[];for(n in e)i=this.getCookie(n,t),i&&r.push(i);return r.toString=function(){return r.join(":")},r.toValueString=function(){return r.map(function(e){return e.toValueString()}).join(";")},r},this):new i}n.CookieAccessInfo=e,n.Cookie=t,t.prototype.toString=function(){var e=[this.name+"="+this.value];return this.expiration_date!==1/0&&e.push("expires="+new Date(this.expiration_date).toGMTString()),this.domain&&e.push("domain="+this.domain),this.path&&e.push("path="+this.path),this.secure&&e.push("secure"),this.noscript&&e.push("httponly"),e.join("; ")},t.prototype.toValueString=function(){return this.name+"="+this.value};var r=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;t.prototype.parse=function(e,n,i){if(this instanceof t){var r,a=e.split(";").filter(function(e){return!!e}),o=a[0].match(/([^=]+)=([\s\S]*)/),s=o[1],l=o[2];for(this.name=s,this.value=l,r=1;r<a.length;r+=1)switch(o=a[r].match(/([^=]+)(?:=([\s\S]*))?/),s=o[1].trim().toLowerCase(),l=o[2],s){case"httponly":this.noscript=!0;break;case"expires":this.expiration_date=l?Number(Date.parse(l)):1/0;break;case"path":this.path=l?l.trim():"",this.explicit_path=!0;break;case"domain":this.domain=l?l.trim():"",this.explicit_domain=!!this.domain;break;case"secure":this.secure=!0}return this.explicit_path||(this.path=i||"/"),this.explicit_domain||(this.domain=n),this}return(new t).parse(e,n,i)},t.prototype.matches=function(e){return!(this.noscript&&e.script||this.secure&&!e.secure)&&this.collidesWith(e)},t.prototype.collidesWith=function(e){if(this.path&&!e.path||this.domain&&!e.domain)return!1;if(this.path&&0!==e.path.indexOf(this.path))return!1;if(this.explicit_path&&0!==e.path.indexOf(this.path))return!1;var t=e.domain&&e.domain.replace(/^[\.]/,""),n=this.domain&&this.domain.replace(/^[\.]/,"");if(n===t)return!0;if(n){if(!this.explicit_domain)return!1;var i=t.indexOf(n);return-1!==i&&i===t.length-n.length}return!0},n.CookieJar=i,i.prototype.setCookies=function(e,n,i){e=Array.isArray(e)?e:e.split(r);var a,o,s=[];for(e=e.map(function(e){return new t(e,n,i)}),a=0;a<e.length;a+=1)o=e[a],this.setCookie(o,n,i)&&s.push(o);return s}}()},{}],21:[function(e,t,n){"use strict";var i=e("./lib/js-yaml.js");t.exports=i},{"./lib/js-yaml.js":22}],22:[function(e,t,n){"use strict";function i(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}var r=e("./js-yaml/loader"),a=e("./js-yaml/dumper");t.exports.Type=e("./js-yaml/type"),t.exports.Schema=e("./js-yaml/schema"),t.exports.FAILSAFE_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.JSON_SCHEMA=e("./js-yaml/schema/json"),t.exports.CORE_SCHEMA=e("./js-yaml/schema/core"),t.exports.DEFAULT_SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_FULL_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.load=r.load,t.exports.loadAll=r.loadAll,t.exports.safeLoad=r.safeLoad,t.exports.safeLoadAll=r.safeLoadAll,t.exports.dump=a.dump,t.exports.safeDump=a.safeDump,t.exports.YAMLException=e("./js-yaml/exception"),t.exports.MINIMAL_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.scan=i("scan"),t.exports.parse=i("parse"),t.exports.compose=i("compose"),t.exports.addConstructor=i("addConstructor")},{"./js-yaml/dumper":24,"./js-yaml/exception":25,"./js-yaml/loader":26,"./js-yaml/schema":28,"./js-yaml/schema/core":29,"./js-yaml/schema/default_full":30,"./js-yaml/schema/default_safe":31,"./js-yaml/schema/failsafe":32,"./js-yaml/schema/json":33,"./js-yaml/type":34}],23:[function(e,t,n){"use strict";function i(e){return"undefined"==typeof e||null===e}function r(e){return"object"==typeof e&&null!==e}function a(e){return Array.isArray(e)?e:i(e)?[]:[e]}function o(e,t){var n,i,r,a;if(t)for(a=Object.keys(t),n=0,i=a.length;i>n;n+=1)r=a[n],e[r]=t[r];return e}function s(e,t){var n,i="";for(n=0;t>n;n+=1)i+=e;return i}function l(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e}t.exports.isNothing=i,t.exports.isObject=r,t.exports.toArray=a,t.exports.repeat=s,t.exports.isNegativeZero=l,t.exports.extend=o},{}],24:[function(e,t,n){"use strict";function i(e,t){var n,i,r,a,o,s,l;if(null===t)return{};for(n={},i=Object.keys(t),r=0,a=i.length;a>r;r+=1)o=i[r],s=String(t[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),l=e.compiledTypeMap[o],l&&I.call(l.styleAliases,s)&&(s=l.styleAliases[s]),n[o]=s;return n}function r(e){var t,n,i;if(t=e.toString(16).toUpperCase(),255>=e)n="x",i=2;else if(65535>=e)n="u",i=4;else{if(!(4294967295>=e))throw new S("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+_.repeat("0",i-t.length)+t}function a(e){this.schema=e.schema||k,this.indent=Math.max(1,e.indent||2),this.skipInvalid=e.skipInvalid||!1,this.flowLevel=_.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=i(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function o(e,t){for(var n,i=_.repeat(" ",t),r=0,a=-1,o="",s=e.length;s>r;)a=e.indexOf("\n",r),-1===a?(n=e.slice(r),r=s):(n=e.slice(r,a+1),r=a+1),n.length&&"\n"!==n&&(o+=i),o+=n;return o}function s(e,t){return"\n"+_.repeat(" ",e.indent*t)}function l(e,t){var n,i,r;for(n=0,i=e.implicitTypes.length;i>n;n+=1)if(r=e.implicitTypes[n],r.resolve(t))return!0;return!1}function u(e){this.source=e,this.result="",this.checkpoint=0}function c(e,t,n,i){var r,a,s,c,h,m,g,y,v,b,w,x,A,O,j,_,S,k,C,E,I;if(0===t.length)return void(e.dump="''");if(-1!==te.indexOf(t))return void(e.dump="'"+t+"'");for(r=!0,a=t.length?t.charCodeAt(0):0,s=M===a||M===t.charCodeAt(t.length-1),q!==a&&J!==a&&Q!==a&&W!==a||(r=!1),s||e.flowLevel>-1&&e.flowLevel<=n?(s&&(r=!1),c=!1,h=!1):(c=!i,h=!i),m=!0,g=new u(t),y=!1,v=0,b=0,w=e.indent*n,x=e.lineWidth,-1===x&&(x=9007199254740991),40>w?x-=w:x=40,O=0;O<t.length;O++){if(A=t.charCodeAt(O),r){if(f(A))continue;r=!1}m&&A===F&&(m=!1),j=ee[A],_=d(A),(j||_)&&(A!==$&&A!==L&&A!==F?(c=!1,h=!1):A===$&&(y=!0,m=!1,O>0&&(S=t.charCodeAt(O-1),S===M&&(h=!1,c=!1)),c&&(k=O-v,v=O,k>b&&(b=k))),A!==L&&(m=!1),g.takeUpTo(O),g.escapeChar())}if(r&&l(e,t)&&(r=!1),C="",(c||h)&&(E=0,t.charCodeAt(t.length-1)===$&&(E+=1,t.charCodeAt(t.length-2)===$&&(E+=1)),0===E?C="-":2===E&&(C="+")),(h&&x>b||null!==e.tag)&&(c=!1),y||(h=!1),r)e.dump=t;else if(m)e.dump="'"+t+"'";else if(c)I=p(t,x),e.dump=">"+C+"\n"+o(I,w);else if(h)C||(t=t.replace(/\n$/,"")),e.dump="|"+C+"\n"+o(t,w);else{if(!g)throw new Error("Failed to dump scalar value");g.finish(),e.dump='"'+g.result+'"'}}function p(e,t){var n,i="",r=0,a=e.length,o=/\n+$/.exec(e);for(o&&(a=o.index+1);a>r;)n=e.indexOf("\n",r),n>a||-1===n?(i&&(i+="\n\n"),i+=h(e.slice(r,a),t),r=a):(i&&(i+="\n\n"),i+=h(e.slice(r,n),t),r=n+1);return o&&"\n"!==o[0]&&(i+=o[0]),i}function h(e,t){if(""===e)return e;for(var n,i,r,a=/[^\s] [^\s]/g,o="",s=0,l=0,u=a.exec(e);u;)n=u.index,n-l>t&&(i=s!==l?s:n,o&&(o+="\n"),r=e.slice(l,i),o+=r,l=i+1),s=n+1,u=a.exec(e);return o&&(o+="\n"),o+=l!==s&&e.length-l>t?e.slice(l,s)+"\n"+e.slice(s+1):e.slice(l)}function f(e){return T!==e&&$!==e&&U!==e&&V!==e&&Y!==e&&K!==e&&X!==e&&Z!==e&&D!==e&&N!==e&&B!==e&&P!==e&&G!==e&&H!==e&&F!==e&&L!==e&&R!==e&&z!==e&&!ee[e]&&!d(e)}function d(e){return!(e>=32&&126>=e||133===e||e>=160&&55295>=e||e>=57344&&65533>=e||e>=65536&&1114111>=e)}function m(e,t,n){var i,r,a="",o=e.tag;for(i=0,r=n.length;r>i;i+=1)w(e,t,n[i],!1,!1)&&(0!==i&&(a+=", "),a+=e.dump);e.tag=o,e.dump="["+a+"]"}function g(e,t,n,i){var r,a,o="",l=e.tag;for(r=0,a=n.length;a>r;r+=1)w(e,t+1,n[r],!0,!0)&&(i&&0===r||(o+=s(e,t)),o+="- "+e.dump);e.tag=l,e.dump=o||"[]"}function y(e,t,n){var i,r,a,o,s,l="",u=e.tag,c=Object.keys(n);for(i=0,r=c.length;r>i;i+=1)s="",0!==i&&(s+=", "),a=c[i],o=n[a],w(e,t,a,!1,!1)&&(e.dump.length>1024&&(s+="? "),s+=e.dump+": ",w(e,t,o,!1,!1)&&(s+=e.dump,l+=s));e.tag=u,e.dump="{"+l+"}"}function v(e,t,n,i){var r,a,o,l,u,c,p="",h=e.tag,f=Object.keys(n);if(e.sortKeys===!0)f.sort();else if("function"==typeof e.sortKeys)f.sort(e.sortKeys);else if(e.sortKeys)throw new S("sortKeys must be a boolean or a function");for(r=0,a=f.length;a>r;r+=1)c="",i&&0===r||(c+=s(e,t)),o=f[r],l=n[o],w(e,t+1,o,!0,!0,!0)&&(u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024,u&&(c+=e.dump&&$===e.dump.charCodeAt(0)?"?":"? "),c+=e.dump,u&&(c+=s(e,t)),w(e,t+1,l,!0,u)&&(c+=e.dump&&$===e.dump.charCodeAt(0)?":":": ",c+=e.dump,p+=c));e.tag=h,e.dump=p||"{}"}function b(e,t,n){var i,r,a,o,s,l;for(r=n?e.explicitTypes:e.implicitTypes,a=0,o=r.length;o>a;a+=1)if(s=r[a],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof t&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=n?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,"[object Function]"===E.call(s.represent))i=s.represent(t,l);else{if(!I.call(s.represent,l))throw new S("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');i=s.represent[l](t,l)}e.dump=i}return!0}return!1}function w(e,t,n,i,r,a){e.tag=null,e.dump=n,b(e,n,!1)||b(e,n,!0);var o=E.call(e.dump);i&&(i=e.flowLevel<0||e.flowLevel>t);var s,l,u="[object Object]"===o||"[object Array]"===o;if(u&&(s=e.duplicates.indexOf(n),l=-1!==s),(null!==e.tag&&"?"!==e.tag||l||2!==e.indent&&t>0)&&(r=!1),l&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&l&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===o)i&&0!==Object.keys(e.dump).length?(v(e,t,e.dump,r),l&&(e.dump="&ref_"+s+e.dump)):(y(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===o)i&&0!==e.dump.length?(g(e,t,e.dump,r),l&&(e.dump="&ref_"+s+e.dump)):(m(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==o){if(e.skipInvalid)return!1;throw new S("unacceptable kind of an object to dump "+o)}"?"!==e.tag&&c(e,e.dump,t,a)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function x(e,t){var n,i,r=[],a=[];for(A(e,r,a),n=0,i=a.length;i>n;n+=1)t.duplicates.push(r[a[n]]);t.usedDuplicates=new Array(i)}function A(e,t,n){var i,r,a;if(null!==e&&"object"==typeof e)if(r=t.indexOf(e),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(t.push(e),Array.isArray(e))for(r=0,a=e.length;a>r;r+=1)A(e[r],t,n);else for(i=Object.keys(e),r=0,a=i.length;a>r;r+=1)A(e[i[r]],t,n)}function O(e,t){t=t||{};var n=new a(t);return n.noRefs||x(e,n),w(n,0,e,!0,!0)?n.dump+"\n":""}function j(e,t){return O(e,_.extend({schema:C},t))}var _=e("./common"),S=e("./exception"),k=e("./schema/default_full"),C=e("./schema/default_safe"),E=Object.prototype.toString,I=Object.prototype.hasOwnProperty,T=9,$=10,U=13,M=32,P=33,L=34,D=35,R=37,N=38,F=39,B=42,V=44,q=45,z=58,H=62,J=63,Q=64,Y=91,K=93,W=96,X=123,G=124,Z=125,ee={};ee[0]="\\0",ee[7]="\\a",ee[8]="\\b",ee[9]="\\t",ee[10]="\\n",ee[11]="\\v",ee[12]="\\f",ee[13]="\\r",ee[27]="\\e",ee[34]='\\"',ee[92]="\\\\",ee[133]="\\N",ee[160]="\\_",ee[8232]="\\L",ee[8233]="\\P";var te=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(e){var t;if(e<this.checkpoint)throw t=new Error("position should be > checkpoint"),t.position=e,t.checkpoint=this.checkpoint,t;return this.result+=this.source.slice(this.checkpoint,e),this.checkpoint=e,this},u.prototype.escapeChar=function(){var e,t;return e=this.source.charCodeAt(this.checkpoint),t=ee[e]||r(e),this.result+=t,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},t.exports.dump=O,t.exports.safeDump=j},{"./common":23,"./exception":25,"./schema/default_full":30,"./schema/default_safe":31}],25:[function(e,t,n){"use strict";function i(e,t){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}i.prototype=Object.create(Error.prototype),i.prototype.constructor=i,i.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},t.exports=i},{}],26:[function(e,t,n){"use strict";function i(e){return 10===e||13===e}function r(e){return 9===e||32===e}function a(e){return 9===e||32===e||10===e||13===e}function o(e){return 44===e||91===e||93===e||123===e||125===e}function s(e){var t;return e>=48&&57>=e?e-48:(t=32|e,t>=97&&102>=t?t-97+10:-1)}function l(e){return 120===e?2:117===e?4:85===e?8:0}function u(e){return e>=48&&57>=e?e-48:-1}function c(e){return 48===e?"\x00":97===e?"\a":98===e?"\b":116===e?"     ":9===e?"       ":110===e?"\n":118===e?"\x0B":102===e?"\f":114===e?"\r":101===e?"\e":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"\85":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function p(e){return 65535>=e?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function h(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||z,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function f(e,t){return new B(t,new V(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function d(e,t){throw f(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,f(e,t))}function g(e,t,n,i){var r,a,o,s;if(n>t){if(s=e.input.slice(t,n),i)for(r=0,a=s.length;a>r;r+=1)o=s.charCodeAt(r),9===o||o>=32&&1114111>=o||d(e,"expected valid JSON character");else Z.test(s)&&d(e,"the stream contains non-printable characters");e.result+=s}}function y(e,t,n,i){var r,a,o,s;for(F.isObject(n)||d(e,"cannot merge mappings; the provided source object is unacceptable"),r=Object.keys(n),o=0,s=r.length;s>o;o+=1)a=r[o],H.call(t,a)||(t[a]=n[a],i[a]=!0)}function v(e,t,n,i,r,a){var o,s;if(r=String(r),null===t&&(t={}),"tag:yaml.org,2002:merge"===i)if(Array.isArray(a))for(o=0,s=a.length;s>o;o+=1)y(e,t,a[o],n);else y(e,t,a,n);else e.json||H.call(n,r)||!H.call(t,r)||d(e,"duplicated mapping key"),t[r]=a,delete n[r];return t}function b(e){var t;t=e.input.charCodeAt(e.position),10===t?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):d(e,"a line break is expected"),e.line+=1,e.lineStart=e.position}function w(e,t,n){for(var a=0,o=e.input.charCodeAt(e.position);0!==o;){for(;r(o);)o=e.input.charCodeAt(++e.position);if(t&&35===o)do o=e.input.charCodeAt(++e.position);while(10!==o&&13!==o&&0!==o);if(!i(o))break;for(b(e),o=e.input.charCodeAt(e.position),a++,e.lineIndent=0;32===o;)e.lineIndent++,o=e.input.charCodeAt(++e.position)}return-1!==n&&0!==a&&e.lineIndent<n&&m(e,"deficient indentation"),a}function x(e){var t,n=e.position;return t=e.input.charCodeAt(n),(45===t||46===t)&&t===e.input.charCodeAt(n+1)&&t===e.input.charCodeAt(n+2)&&(n+=3,t=e.input.charCodeAt(n),0===t||a(t))}function A(e,t){1===t?e.result+=" ":t>1&&(e.result+=F.repeat("\n",t-1))}function O(e,t,n){var s,l,u,c,p,h,f,d,m,y=e.kind,v=e.result;if(m=e.input.charCodeAt(e.position),a(m)||o(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l)))return!1;for(e.kind="scalar",e.result="",u=c=e.position,p=!1;0!==m;){if(58===m){if(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),a(s))break}else{if(e.position===e.lineStart&&x(e)||n&&o(m))break;if(i(m)){if(h=e.line,f=e.lineStart,d=e.lineIndent,w(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=c,e.line=h,e.lineStart=f,e.lineIndent=d;break}}p&&(g(e,u,c,!1),A(e,e.line-h),u=c=e.position,p=!1),r(m)||(c=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,c,!1),e.result?!0:(e.kind=y,e.result=v,!1)}function j(e,t){var n,r,a;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,r=a=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,r,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;r=a=e.position,e.position++}else i(n)?(g(e,r,a,!0),A(e,w(e,!1,t)),r=a=e.position):e.position===e.lineStart&&x(e)?d(e,"unexpected end of the document within a single quoted scalar"):(e.position++,a=e.position);d(e,"unexpected end of the stream within a single quoted scalar")}function _(e,t){var n,r,a,o,u,c;if(c=e.input.charCodeAt(e.position),34!==c)return!1;for(e.kind="scalar",e.result="",e.position++,n=r=e.position;0!==(c=e.input.charCodeAt(e.position));){if(34===c)return g(e,n,e.position,!0),e.position++,!0;if(92===c){if(g(e,n,e.position,!0),c=e.input.charCodeAt(++e.position),i(c))w(e,!1,t);else if(256>c&&re[c])e.result+=ae[c],e.position++;else if((u=l(c))>0){for(a=u,o=0;a>0;a--)c=e.input.charCodeAt(++e.position),(u=s(c))>=0?o=(o<<4)+u:d(e,"expected hexadecimal character");e.result+=p(o),e.position++}else d(e,"unknown escape sequence");n=r=e.position}else i(c)?(g(e,n,r,!0),A(e,w(e,!1,t)),n=r=e.position):e.position===e.lineStart&&x(e)?d(e,"unexpected end of the document within a double quoted scalar"):(e.position++,r=e.position)}d(e,"unexpected end of the stream within a double quoted scalar")}function S(e,t){var n,i,r,o,s,l,u,c,p,h,f,m=!0,g=e.tag,y=e.anchor,b={};if(f=e.input.charCodeAt(e.position),91===f)o=93,u=!1,i=[];else{if(123!==f)return!1;o=125,u=!0,i={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),f=e.input.charCodeAt(++e.position);0!==f;){if(w(e,!0,t),f=e.input.charCodeAt(e.position),f===o)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=i,!0;m||d(e,"missed comma between flow collection entries"),p=c=h=null,s=l=!1,63===f&&(r=e.input.charCodeAt(e.position+1),a(r)&&(s=l=!0,e.position++,w(e,!0,t))),n=e.line,U(e,t,J,!1,!0),p=e.tag,c=e.result,w(e,!0,t),f=e.input.charCodeAt(e.position),!l&&e.line!==n||58!==f||(s=!0,f=e.input.charCodeAt(++e.position),w(e,!0,t),U(e,t,J,!1,!0),h=e.result),u?v(e,i,b,p,c,h):s?i.push(v(e,null,b,p,c,h)):i.push(c),w(e,!0,t),f=e.input.charCodeAt(e.position),44===f?(m=!0,f=e.input.charCodeAt(++e.position)):m=!1}d(e,"unexpected end of the stream within a flow collection")}function k(e,t){var n,a,o,s,l=W,c=!1,p=t,h=0,f=!1;if(s=e.input.charCodeAt(e.position),124===s)a=!1;else{if(62!==s)return!1;a=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)W===l?l=43===s?G:X:d(e,"repeat of a chomping mode identifier");else{if(!((o=u(s))>=0))break;0===o?d(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):c?d(e,"repeat of an indentation width identifier"):(p=t+o-1,c=!0)}if(r(s)){do s=e.input.charCodeAt(++e.position);while(r(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!i(s)&&0!==s)}for(;0!==s;){for(b(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!c||e.lineIndent<p)&&32===s;)e.lineIndent++,s=e.input.charCodeAt(++e.position);if(!c&&e.lineIndent>p&&(p=e.lineIndent),i(s))h++;else{if(e.lineIndent<p){l===G?e.result+=F.repeat("\n",h):l===W&&c&&(e.result+="\n");break}for(a?r(s)?(f=!0,e.result+=F.repeat("\n",h+1)):f?(f=!1,e.result+=F.repeat("\n",h+1)):0===h?c&&(e.result+=" "):e.result+=F.repeat("\n",h):c?e.result+=F.repeat("\n",h+1):e.result+=F.repeat("\n",h),c=!0,h=0,n=e.position;!i(s)&&0!==s;)s=e.input.charCodeAt(++e.position);g(e,n,e.position,!1)}}return!0}function C(e,t){var n,i,r,o=e.tag,s=e.anchor,l=[],u=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=l),r=e.input.charCodeAt(e.position);0!==r&&45===r&&(i=e.input.charCodeAt(e.position+1),a(i));)if(u=!0,e.position++,w(e,!0,-1)&&e.lineIndent<=t)l.push(null),r=e.input.charCodeAt(e.position);else if(n=e.line,U(e,t,Y,!1,!0),l.push(e.result),w(e,!0,-1),r=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==r)d(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break;return u?(e.tag=o,e.anchor=s,e.kind="sequence",e.result=l,!0):!1}function E(e,t,n){var i,o,s,l,u=e.tag,c=e.anchor,p={},h={},f=null,m=null,g=null,y=!1,b=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=p),l=e.input.charCodeAt(e.position);0!==l;){if(i=e.input.charCodeAt(e.position+1),s=e.line,63!==l&&58!==l||!a(i)){if(!U(e,n,Q,!1,!0))break;if(e.line===s){for(l=e.input.charCodeAt(e.position);r(l);)l=e.input.charCodeAt(++e.position);if(58===l)l=e.input.charCodeAt(++e.position),a(l)||d(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!1,o=!1,f=e.tag,m=e.result;else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read an implicit mapping pair; a colon is missed")}}else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===l?(y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!0,o=!0):y?(y=!1,o=!0):d(e,"incomplete explicit mapping pair; a key node is missed"),e.position+=1,l=i;if((e.line===s||e.lineIndent>t)&&(U(e,t,K,!0,o)&&(y?m=e.result:g=e.result),y||(v(e,p,h,f,m,g),f=m=g=null),w(e,!0,-1),l=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==l)d(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&v(e,p,h,f,m,null),b&&(e.tag=u,e.anchor=c,e.kind="mapping",e.result=p),b}function I(e){var t,n,i,r,o=!1,s=!1;if(r=e.input.charCodeAt(e.position),33!==r)return!1;if(null!==e.tag&&d(e,"duplication of a tag property"),r=e.input.charCodeAt(++e.position),60===r?(o=!0,r=e.input.charCodeAt(++e.position)):33===r?(s=!0,n="!!",r=e.input.charCodeAt(++e.position)):n="!",t=e.position,o){do r=e.input.charCodeAt(++e.position);while(0!==r&&62!==r);e.position<e.length?(i=e.input.slice(t,e.position),r=e.input.charCodeAt(++e.position)):d(e,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!a(r);)33===r&&(s?d(e,"tag suffix cannot contain exclamation marks"):(n=e.input.slice(t-1,e.position+1),ne.test(n)||d(e,"named tag handle cannot contain such characters"),s=!0,t=e.position+1)),r=e.input.charCodeAt(++e.position);i=e.input.slice(t,e.position),te.test(i)&&d(e,"tag suffix cannot contain flow indicator characters")}return i&&!ie.test(i)&&d(e,"tag name cannot contain such characters: "+i),o?e.tag=i:H.call(e.tagMap,n)?e.tag=e.tagMap[n]+i:"!"===n?e.tag="!"+i:"!!"===n?e.tag="tag:yaml.org,2002:"+i:d(e,'undeclared tag handle "'+n+'"'),!0}function T(e){var t,n;if(n=e.input.charCodeAt(e.position),38!==n)return!1;for(null!==e.anchor&&d(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!a(n)&&!o(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function $(e){var t,n,i;if(i=e.input.charCodeAt(e.position),42!==i)return!1;for(i=e.input.charCodeAt(++e.position),t=e.position;0!==i&&!a(i)&&!o(i);)i=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),e.anchorMap.hasOwnProperty(n)||d(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],w(e,!0,-1),!0}function U(e,t,n,i,r){var a,o,s,l,u,c,p,h,f=1,m=!1,g=!1;if(null!==e.listener&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=o=s=K===n||Y===n,i&&w(e,!0,-1)&&(m=!0,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)),1===f)for(;I(e)||T(e);)w(e,!0,-1)?(m=!0,s=a,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)):s=!1;if(s&&(s=m||r),1!==f&&K!==n||(p=J===n||Q===n?t:t+1,h=e.position-e.lineStart,1===f?s&&(C(e,h)||E(e,h,p))||S(e,p)?g=!0:(o&&k(e,p)||j(e,p)||_(e,p)?g=!0:$(e)?(g=!0,null===e.tag&&null===e.anchor||d(e,"alias node should not have any properties")):O(e,p,J===n)&&(g=!0,null===e.tag&&(e.tag="?")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===f&&(g=s&&C(e,h))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(l=0,u=e.implicitTypes.length;u>l;l+=1)if(c=e.implicitTypes[l],c.resolve(e.result)){e.result=c.construct(e.result),e.tag=c.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else H.call(e.typeMap,e.tag)?(c=e.typeMap[e.tag],null!==e.result&&c.kind!==e.kind&&d(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+c.kind+'", not "'+e.kind+'"'),c.resolve(e.result)?(e.result=c.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):d(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):d(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function M(e){var t,n,o,s,l=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(w(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),o=[],n.length<1&&d(e,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!i(s));break}if(i(s))break;for(t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);o.push(e.input.slice(t,e.position))}0!==s&&b(e),H.call(se,n)?se[n](e,n,o):m(e,'unknown document directive "'+n+'"')}return w(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,w(e,!0,-1)):u&&d(e,"directives end mark is expected"),U(e,e.lineIndent-1,K,!1,!0),w(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(l,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&x(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,w(e,!0,-1))):void(e.position<e.length-1&&d(e,"end of the stream or a document separator is expected"))}function P(e,t){e=String(e),t=t||{},0!==e.length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new h(e,t);for(n.input+="\x00";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function L(e,t,n){var i,r,a=P(e,n);for(i=0,r=a.length;r>i;i+=1)t(a[i])}function D(e,t){var n=P(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new B("expected a single document in the stream, but found more")}}function R(e,t,n){L(e,t,F.extend({schema:q},n))}function N(e,t){return D(e,F.extend({schema:q},t))}for(var F=e("./common"),B=e("./exception"),V=e("./mark"),q=e("./schema/default_safe"),z=e("./schema/default_full"),H=Object.prototype.hasOwnProperty,J=1,Q=2,Y=3,K=4,W=1,X=2,G=3,Z=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ee=/[\x85\u2028\u2029]/,te=/[,\[\]\{\}]/,ne=/^(?:!|!!|![a-z\-]+!)$/i,ie=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,re=new Array(256),ae=new Array(256),oe=0;256>oe;oe++)re[oe]=c(oe)?1:0,ae[oe]=c(oe);var se={YAML:function(e,t,n){var i,r,a;null!==e.version&&d(e,"duplication of %YAML directive"),1!==n.length&&d(e,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),
+null===i&&d(e,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),a=parseInt(i[2],10),1!==r&&d(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=2>a,1!==a&&2!==a&&m(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var i,r;2!==n.length&&d(e,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],ne.test(i)||d(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,i)&&d(e,'there is a previously declared suffix for "'+i+'" tag handle'),ie.test(r)||d(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[i]=r}};t.exports.loadAll=L,t.exports.load=D,t.exports.safeLoadAll=R,t.exports.safeLoad=N},{"./common":23,"./exception":25,"./mark":27,"./schema/default_full":30,"./schema/default_safe":31}],27:[function(e,t,n){"use strict";function i(e,t,n,i,r){this.name=e,this.buffer=t,this.position=n,this.line=i,this.column=r}var r=e("./common");i.prototype.getSnippet=function(e,t){var n,i,a,o,s;if(!this.buffer)return null;for(e=e||4,t=t||75,n="",i=this.position;i>0&&-1==="\x00\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>t/2-1){n=" ... ",i+=5;break}for(a="",o=this.position;o<this.buffer.length&&-1==="\x00\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(o));)if(o+=1,o-this.position>t/2-1){a=" ... ",o-=5;break}return s=this.buffer.slice(i,o),r.repeat(" ",e)+n+s+a+"\n"+r.repeat(" ",e+this.position-i+n.length)+"^"},i.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=i},{"./common":23}],28:[function(e,t,n){"use strict";function i(e,t,n){var r=[];return e.include.forEach(function(e){n=i(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&r.push(n)}),n.push(e)}),n.filter(function(e,t){return-1===r.indexOf(t)})}function r(){function e(e){i[e.tag]=e}var t,n,i={};for(t=0,n=arguments.length;n>t;t+=1)arguments[t].forEach(e);return i}function a(e){this.include=e.include||[],this.implicit=e.implicit||[],this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var o=e("./common"),s=e("./exception"),l=e("./type");a.DEFAULT=null,a.create=function(){var e,t;switch(arguments.length){case 1:e=a.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(e=o.toArray(e),t=o.toArray(t),!e.every(function(e){return e instanceof a}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(e){return e instanceof l}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new a({include:e,explicit:t})},t.exports=a},{"./common":23,"./exception":25,"./type":34}],29:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./json")]})},{"../schema":28,"./json":33}],30:[function(e,t,n){"use strict";var i=e("../schema");t.exports=i.DEFAULT=new i({include:[e("./default_safe")],explicit:[e("../type/js/undefined"),e("../type/js/regexp"),e("../type/js/function")]})},{"../schema":28,"../type/js/function":39,"../type/js/regexp":40,"../type/js/undefined":41,"./default_safe":31}],31:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./core")],implicit:[e("../type/timestamp"),e("../type/merge")],explicit:[e("../type/binary"),e("../type/omap"),e("../type/pairs"),e("../type/set")]})},{"../schema":28,"../type/binary":35,"../type/merge":43,"../type/omap":45,"../type/pairs":46,"../type/set":48,"../type/timestamp":50,"./core":29}],32:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({explicit:[e("../type/str"),e("../type/seq"),e("../type/map")]})},{"../schema":28,"../type/map":42,"../type/seq":47,"../type/str":49}],33:[function(e,t,n){"use strict";var i=e("../schema");t.exports=new i({include:[e("./failsafe")],implicit:[e("../type/null"),e("../type/bool"),e("../type/int"),e("../type/float")]})},{"../schema":28,"../type/bool":36,"../type/float":37,"../type/int":38,"../type/null":44,"./failsafe":32}],34:[function(e,t,n){"use strict";function i(e){var t={};return null!==e&&Object.keys(e).forEach(function(n){e[n].forEach(function(e){t[String(e)]=n})}),t}function r(e,t){if(t=t||{},Object.keys(t).forEach(function(t){if(-1===o.indexOf(t))throw new a('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=i(t.styleAliases||null),-1===s.indexOf(this.kind))throw new a('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var a=e("./exception"),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=r},{"./exception":25}],35:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;var t,n,i=0,r=e.length,a=u;for(n=0;r>n;n++)if(t=a.indexOf(e.charAt(n)),!(t>64)){if(0>t)return!1;i+=6}return i%8===0}function r(e){var t,n,i=e.replace(/[\r\n=]/g,""),r=i.length,a=u,o=0,l=[];for(t=0;r>t;t++)t%4===0&&t&&(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)),o=o<<6|a.indexOf(i.charAt(t));return n=r%4*6,0===n?(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)):18===n?(l.push(o>>10&255),l.push(o>>2&255)):12===n&&l.push(o>>4&255),s?new s(l):l}function a(e){var t,n,i="",r=0,a=e.length,o=u;for(t=0;a>t;t++)t%3===0&&t&&(i+=o[r>>18&63],i+=o[r>>12&63],i+=o[r>>6&63],i+=o[63&r]),r=(r<<8)+e[t];return n=a%3,0===n?(i+=o[r>>18&63],i+=o[r>>12&63],i+=o[r>>6&63],i+=o[63&r]):2===n?(i+=o[r>>10&63],i+=o[r>>4&63],i+=o[r<<2&63],i+=o[64]):1===n&&(i+=o[r>>2&63],i+=o[r<<4&63],i+=o[64],i+=o[64]),i}function o(e){return s&&s.isBuffer(e)}var s=e("buffer").Buffer,l=e("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new l("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:a})},{"../type":34,buffer:12}],36:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function r(e){return"true"===e||"True"===e||"TRUE"===e}function a(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var o=e("../type");t.exports=new o("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":34}],37:[function(e,t,n){"use strict";function i(e){return null===e?!1:!!u.test(e)}function r(e){var t,n,i,r;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,r=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){r.unshift(parseFloat(e,10))}),t=0,i=1,r.forEach(function(e){t+=e*i,i*=60}),n*t):n*parseFloat(t,10)}function a(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),c.test(n)?n.replace("e",".e"):n}function o(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),l=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),c=/^[-+]?[0-9]+e/;t.exports=new l("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:a,defaultStyle:"lowercase"})},{"../common":23,"../type":34}],38:[function(e,t,n){"use strict";function i(e){return e>=48&&57>=e||e>=65&&70>=e||e>=97&&102>=e}function r(e){return e>=48&&55>=e}function a(e){return e>=48&&57>=e}function o(e){if(null===e)return!1;var t,n=e.length,o=0,s=!1;if(!n)return!1;if(t=e[o],"-"!==t&&"+"!==t||(t=e[++o]),"0"===t){if(o+1===n)return!0;if(t=e[++o],"b"===t){for(o++;n>o;o++)if(t=e[o],"_"!==t){if("0"!==t&&"1"!==t)return!1;s=!0}return s}if("x"===t){for(o++;n>o;o++)if(t=e[o],"_"!==t){if(!i(e.charCodeAt(o)))return!1;s=!0}return s}for(;n>o;o++)if(t=e[o],"_"!==t){if(!r(e.charCodeAt(o)))return!1;s=!0}return s}for(;n>o;o++)if(t=e[o],"_"!==t){if(":"===t)break;if(!a(e.charCodeAt(o)))return!1;s=!0}return s?":"!==t?!0:/^(:[0-5]?[0-9])+$/.test(e.slice(o)):!1}function s(e){var t,n,i=e,r=1,a=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),t=i[0],"-"!==t&&"+"!==t||("-"===t&&(r=-1),i=i.slice(1),t=i[0]),"0"===i?0:"0"===t?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(e){a.unshift(parseInt(e,10))}),i=0,n=1,a.forEach(function(e){i+=e*n,n*=60}),r*i):r*parseInt(i,10)}function l(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1===0&&!u.isNegativeZero(e)}var u=e("../common"),c=e("../type");t.exports=new c("tag:yaml.org,2002:int",{kind:"scalar",resolve:o,construct:s,predicate:l,represent:{binary:function(e){return"0b"+e.toString(2)},octal:function(e){return"0"+e.toString(8)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return"0x"+e.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":23,"../type":34}],39:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;try{var t="("+e+")",n=s.parse(t,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(i){return!1}}function r(e){var t,n="("+e+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(e){r.push(e.name)}),t=i.body[0].expression.body.range,new Function(r,n.slice(t[0]+1,t[1]-1))}function a(e){return e.toString()}function o(e){return"[object Function]"===Object.prototype.toString.call(e)}var s;try{var l=e;s=l("esprima")}catch(u){"undefined"!=typeof window&&(s=window.esprima)}var c=e("../../type");t.exports=new c("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:a})},{"../../type":34}],40:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,n=/\/([gim]*)$/.exec(e),i="";if("/"===t[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==t[t.length-i.length-1])return!1}return!0}function r(e){var t=e,n=/\/([gim]*)$/.exec(e),i="";return"/"===t[0]&&(n&&(i=n[1]),t=t.slice(1,t.length-i.length-1)),new RegExp(t,i)}function a(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function o(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:a})},{"../../type":34}],41:[function(e,t,n){"use strict";function i(){return!0}function r(){}function a(){return""}function o(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:a})},{"../../type":34}],42:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":34}],43:[function(e,t,n){"use strict";function i(e){return"<<"===e||null===e}var r=e("../type");t.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":34}],44:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function r(){return null}function a(e){return null===e}var o=e("../type");t.exports=new o("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":34}],45:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n,i,r,a,l=[],u=e;for(t=0,n=u.length;n>t;t+=1){if(i=u[t],a=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(o.call(i,r)){if(a)return!1;a=!0}if(!a)return!1;if(-1!==l.indexOf(r))return!1;l.push(r)}return!0}function r(e){return null!==e?e:[]}var a=e("../type"),o=Object.prototype.hasOwnProperty,s=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":34}],46:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n,i,r,a,s=e;for(a=new Array(s.length),t=0,n=s.length;n>t;t+=1){if(i=s[t],"[object Object]"!==o.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;a[t]=[r[0],i[r[0]]]}return!0}function r(e){if(null===e)return[];var t,n,i,r,a,o=e;for(a=new Array(o.length),t=0,n=o.length;n>t;t+=1)i=o[t],r=Object.keys(i),a[t]=[r[0],i[r[0]]];return a}var a=e("../type"),o=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":34}],47:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},{"../type":34}],48:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n=e;for(t in n)if(o.call(n,t)&&null!==n[t])return!1;return!0}function r(e){return null!==e?e:{}}var a=e("../type"),o=Object.prototype.hasOwnProperty;t.exports=new a("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":34}],49:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},{"../type":34}],50:[function(e,t,n){"use strict";function i(e){return null===e?!1:null!==s.exec(e)}function r(e){var t,n,i,r,a,o,l,u,c,p,h=0,f=null;if(t=s.exec(e),null===t)throw new Error("Date resolve error");if(n=+t[1],i=+t[2]-1,r=+t[3],!t[4])return new Date(Date.UTC(n,i,r));if(a=+t[4],o=+t[5],l=+t[6],t[7]){for(h=t[7].slice(0,3);h.length<3;)h+="0";h=+h}return t[9]&&(u=+t[10],c=+(t[11]||0),f=6e4*(60*u+c),"-"===t[9]&&(f=-f)),p=new Date(Date.UTC(n,i,r,a,o,l,h)),f&&p.setTime(p.getTime()-f),p}function a(e){return e.toISOString()}var o=e("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$");t.exports=new o("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:a})},{"../type":34}],51:[function(e,t,n){function i(e,t,n){var i=e?e.length:0;if(!i)return-1;if("number"==typeof n)n=0>n?o(i+n,0):n;else if(n){var s=a(e,t);return i>s&&(t===t?t===e[s]:e[s]!==e[s])?s:-1}return r(e,t,n||0)}var r=e("../internal/baseIndexOf"),a=e("../internal/binaryIndex"),o=Math.max;t.exports=i},{"../internal/baseIndexOf":80,"../internal/binaryIndex":94}],52:[function(e,t,n){function i(e){var t=e?e.length:0;return t?e[t-1]:void 0}t.exports=i},{}],53:[function(e,t,n){function i(e){if(l(e)&&!s(e)&&!(e instanceof r)){if(e instanceof a)return e;if(p.call(e,"__chain__")&&p.call(e,"__wrapped__"))return u(e)}return new a(e)}var r=e("../internal/LazyWrapper"),a=e("../internal/LodashWrapper"),o=e("../internal/baseLodash"),s=e("../lang/isArray"),l=e("../internal/isObjectLike"),u=e("../internal/wrapperClone"),c=Object.prototype,p=c.hasOwnProperty;i.prototype=o.prototype,t.exports=i},{"../internal/LazyWrapper":62,"../internal/LodashWrapper":63,"../internal/baseLodash":84,"../internal/isObjectLike":128,"../internal/wrapperClone":139,"../lang/isArray":142}],54:[function(e,t,n){t.exports=e("./forEach")},{"./forEach":56}],55:[function(e,t,n){var i=e("../internal/baseEach"),r=e("../internal/createFind"),a=r(i);t.exports=a},{"../internal/baseEach":73,"../internal/createFind":104}],56:[function(e,t,n){var i=e("../internal/arrayEach"),r=e("../internal/baseEach"),a=e("../internal/createForEach"),o=a(i,r);t.exports=o},{"../internal/arrayEach":65,"../internal/baseEach":73,"../internal/createForEach":105}],57:[function(e,t,n){function i(e,t,n,i){var h=e?a(e):0;return l(h)||(e=c(e),h=e.length),n="number"!=typeof n||i&&s(t,n,i)?0:0>n?p(h+n,0):n||0,"string"==typeof e||!o(e)&&u(e)?h>=n&&e.indexOf(t,n)>-1:!!h&&r(e,t,n)>-1}var r=e("../internal/baseIndexOf"),a=e("../internal/getLength"),o=e("../lang/isArray"),s=e("../internal/isIterateeCall"),l=e("../internal/isLength"),u=e("../lang/isString"),c=e("../object/values"),p=Math.max;t.exports=i},{"../internal/baseIndexOf":80,"../internal/getLength":114,"../internal/isIterateeCall":124,"../internal/isLength":127,"../lang/isArray":142,"../lang/isString":148,"../object/values":154}],58:[function(e,t,n){function i(e,t,n){var i=s(e)?r:o;return t=a(t,n,3),i(e,t)}var r=e("../internal/arrayMap"),a=e("../internal/baseCallback"),o=e("../internal/baseMap"),s=e("../lang/isArray");t.exports=i},{"../internal/arrayMap":66,"../internal/baseCallback":69,"../internal/baseMap":85,"../lang/isArray":142}],59:[function(e,t,n){var i=e("../internal/getNative"),r=i(Date,"now"),a=r||function(){return(new Date).getTime()};t.exports=a},{"../internal/getNative":116}],60:[function(e,t,n){var i=e("../internal/createWrapper"),r=e("../internal/replaceHolders"),a=e("./restParam"),o=1,s=32,l=a(function(e,t,n){var a=o;if(n.length){var u=r(n,l.placeholder);a|=s}return i(e,a,t,n,u)});l.placeholder={},t.exports=l},{"../internal/createWrapper":108,"../internal/replaceHolders":134,"./restParam":61}],61:[function(e,t,n){function i(e,t){if("function"!=typeof e)throw new TypeError(r);return t=a(void 0===t?e.length-1:+t||0,0),function(){for(var n=arguments,i=-1,r=a(n.length-t,0),o=Array(r);++i<r;)o[i]=n[t+i];switch(t){case 0:return e.call(this,o);case 1:return e.call(this,n[0],o);case 2:return e.call(this,n[0],n[1],o)}var s=Array(t+1);for(i=-1;++i<t;)s[i]=n[i];return s[t]=o,e.apply(this,s)}}var r="Expected a function",a=Math.max;t.exports=i},{}],62:[function(e,t,n){function i(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=o,this.__views__=[]}var r=e("./baseCreate"),a=e("./baseLodash"),o=Number.POSITIVE_INFINITY;i.prototype=r(a.prototype),i.prototype.constructor=i,t.exports=i},{"./baseCreate":72,"./baseLodash":84}],63:[function(e,t,n){function i(e,t,n){this.__wrapped__=e,this.__actions__=n||[],this.__chain__=!!t}var r=e("./baseCreate"),a=e("./baseLodash");i.prototype=r(a.prototype),i.prototype.constructor=i,t.exports=i},{"./baseCreate":72,"./baseLodash":84}],64:[function(e,t,n){function i(e,t){var n=-1,i=e.length;for(t||(t=Array(i));++n<i;)t[n]=e[n];return t}t.exports=i},{}],65:[function(e,t,n){function i(e,t){for(var n=-1,i=e.length;++n<i&&t(e[n],n,e)!==!1;);return e}t.exports=i},{}],66:[function(e,t,n){function i(e,t){for(var n=-1,i=e.length,r=Array(i);++n<i;)r[n]=t(e[n],n,e);return r}t.exports=i},{}],67:[function(e,t,n){function i(e,t){for(var n=-1,i=e.length;++n<i;)if(t(e[n],n,e))return!0;return!1}t.exports=i},{}],68:[function(e,t,n){function i(e,t){return null==t?e:r(t,a(t),e)}var r=e("./baseCopy"),a=e("../object/keys");t.exports=i},{"../object/keys":151,"./baseCopy":71}],69:[function(e,t,n){function i(e,t,n){var i=typeof e;return"function"==i?void 0===t?e:o(e,t,n):null==e?s:"object"==i?r(e):void 0===t?l(e):a(e,t)}var r=e("./baseMatches"),a=e("./baseMatchesProperty"),o=e("./bindCallback"),s=e("../utility/identity"),l=e("../utility/property");t.exports=i},{"../utility/identity":156,"../utility/property":158,"./baseMatches":86,"./baseMatchesProperty":87,"./bindCallback":96}],70:[function(e,t,n){function i(e,t,n,m,g,y,v){var w;if(n&&(w=g?n(e,m,g):n(e)),void 0!==w)return w;if(!f(e))return e;var x=p(e);if(x){if(w=l(e),!t)return r(e,w)}else{var O=N.call(e),j=O==b;if(O!=A&&O!=d&&(!j||g))return D[O]?u(e,O,t):g?e:{};if(h(e))return g?e:{};if(w=c(j?{}:e),!t)return o(w,e)}y||(y=[]),v||(v=[]);for(var _=y.length;_--;)if(y[_]==e)return v[_];return y.push(e),v.push(w),(x?a:s)(e,function(r,a){w[a]=i(r,t,n,a,e,y,v)}),w}var r=e("./arrayCopy"),a=e("./arrayEach"),o=e("./baseAssign"),s=e("./baseForOwn"),l=e("./initCloneArray"),u=e("./initCloneByTag"),c=e("./initCloneObject"),p=e("../lang/isArray"),h=e("./isHostObject"),f=e("../lang/isObject"),d="[object Arguments]",m="[object Array]",g="[object Boolean]",y="[object Date]",v="[object Error]",b="[object Function]",w="[object Map]",x="[object Number]",A="[object Object]",O="[object RegExp]",j="[object Set]",_="[object String]",S="[object WeakMap]",k="[object ArrayBuffer]",C="[object Float32Array]",E="[object Float64Array]",I="[object Int8Array]",T="[object Int16Array]",$="[object Int32Array]",U="[object Uint8Array]",M="[object Uint8ClampedArray]",P="[object Uint16Array]",L="[object Uint32Array]",D={};D[d]=D[m]=D[k]=D[g]=D[y]=D[C]=D[E]=D[I]=D[T]=D[$]=D[x]=D[A]=D[O]=D[_]=D[U]=D[M]=D[P]=D[L]=!0,D[v]=D[b]=D[w]=D[j]=D[S]=!1;var R=Object.prototype,N=R.toString;t.exports=i},{"../lang/isArray":142,"../lang/isObject":146,"./arrayCopy":64,"./arrayEach":65,"./baseAssign":68,"./baseForOwn":78,"./initCloneArray":118,"./initCloneByTag":119,"./initCloneObject":120,"./isHostObject":122}],71:[function(e,t,n){function i(e,t,n){n||(n={});for(var i=-1,r=t.length;++i<r;){var a=t[i];n[a]=e[a]}return n}t.exports=i},{}],72:[function(e,t,n){var i=e("../lang/isObject"),r=function(){function e(){}return function(t){if(i(t)){e.prototype=t;var n=new e;e.prototype=void 0}return n||{}}}();t.exports=r},{"../lang/isObject":146}],73:[function(e,t,n){var i=e("./baseForOwn"),r=e("./createBaseEach"),a=r(i);t.exports=a},{"./baseForOwn":78,"./createBaseEach":100}],74:[function(e,t,n){function i(e,t,n,i){var r;return n(e,function(e,n,a){return t(e,n,a)?(r=i?n:e,!1):void 0}),r}t.exports=i},{}],75:[function(e,t,n){function i(e,t,n){for(var i=e.length,r=n?i:-1;n?r--:++r<i;)if(t(e[r],r,e))return r;return-1}t.exports=i},{}],76:[function(e,t,n){var i=e("./createBaseFor"),r=i();t.exports=r},{"./createBaseFor":101}],77:[function(e,t,n){function i(e,t){return r(e,t,a)}var r=e("./baseFor"),a=e("../object/keysIn");t.exports=i},{"../object/keysIn":152,"./baseFor":76}],78:[function(e,t,n){function i(e,t){return r(e,t,a)}var r=e("./baseFor"),a=e("../object/keys");t.exports=i},{"../object/keys":151,"./baseFor":76}],79:[function(e,t,n){function i(e,t,n){if(null!=e){e=r(e),void 0!==n&&n in e&&(t=[n]);for(var i=0,a=t.length;null!=e&&a>i;)e=r(e)[t[i++]];return i&&i==a?e:void 0}}var r=e("./toObject");t.exports=i},{"./toObject":137}],80:[function(e,t,n){function i(e,t,n){if(t!==t)return r(e,n);for(var i=n-1,a=e.length;++i<a;)if(e[i]===t)return i;return-1}var r=e("./indexOfNaN");t.exports=i},{"./indexOfNaN":117}],81:[function(e,t,n){function i(e,t,n,s,l,u){return e===t?!0:null==e||null==t||!a(e)&&!o(t)?e!==e&&t!==t:r(e,t,i,n,s,l,u)}var r=e("./baseIsEqualDeep"),a=e("../lang/isObject"),o=e("./isObjectLike");t.exports=i},{"../lang/isObject":146,"./baseIsEqualDeep":82,"./isObjectLike":128}],82:[function(e,t,n){function i(e,t,n,i,f,g,y){var v=s(e),b=s(t),w=p,x=p;v||(w=m.call(e),w==c?w=h:w!=h&&(v=u(e))),b||(x=m.call(t),x==c?x=h:x!=h&&(b=u(t)));var A=w==h&&!l(e),O=x==h&&!l(t),j=w==x;if(j&&!v&&!A)return a(e,t,w);if(!f){var _=A&&d.call(e,"__wrapped__"),S=O&&d.call(t,"__wrapped__");if(_||S)return n(_?e.value():e,S?t.value():t,i,f,g,y)}if(!j)return!1;g||(g=[]),y||(y=[]);for(var k=g.length;k--;)if(g[k]==e)return y[k]==t;g.push(e),y.push(t);var C=(v?r:o)(e,t,n,i,f,g,y);return g.pop(),y.pop(),C}var r=e("./equalArrays"),a=e("./equalByTag"),o=e("./equalObjects"),s=e("../lang/isArray"),l=e("./isHostObject"),u=e("../lang/isTypedArray"),c="[object Arguments]",p="[object Array]",h="[object Object]",f=Object.prototype,d=f.hasOwnProperty,m=f.toString;t.exports=i},{"../lang/isArray":142,"../lang/isTypedArray":149,"./equalArrays":109,"./equalByTag":110,"./equalObjects":111,"./isHostObject":122}],83:[function(e,t,n){function i(e,t,n){var i=t.length,o=i,s=!n;if(null==e)return!o;for(e=a(e);i--;){var l=t[i];if(s&&l[2]?l[1]!==e[l[0]]:!(l[0]in e))return!1}for(;++i<o;){l=t[i];var u=l[0],c=e[u],p=l[1];if(s&&l[2]){if(void 0===c&&!(u in e))return!1}else{var h=n?n(c,p,u):void 0;if(!(void 0===h?r(p,c,n,!0):h))return!1}}return!0}var r=e("./baseIsEqual"),a=e("./toObject");t.exports=i},{"./baseIsEqual":81,"./toObject":137}],84:[function(e,t,n){function i(){}t.exports=i},{}],85:[function(e,t,n){function i(e,t){var n=-1,i=a(e)?Array(e.length):[];return r(e,function(e,r,a){i[++n]=t(e,r,a)}),i}var r=e("./baseEach"),a=e("./isArrayLike");t.exports=i},{"./baseEach":73,"./isArrayLike":121}],86:[function(e,t,n){function i(e){var t=a(e);if(1==t.length&&t[0][2]){var n=t[0][0],i=t[0][1];return function(e){return null==e?!1:(e=o(e),e[n]===i&&(void 0!==i||n in e))}}return function(e){return r(e,t)}}var r=e("./baseIsMatch"),a=e("./getMatchData"),o=e("./toObject");t.exports=i},{"./baseIsMatch":83,"./getMatchData":115,"./toObject":137}],87:[function(e,t,n){function i(e,t){var n=s(e),i=l(e)&&u(t),f=e+"";return e=h(e),function(s){if(null==s)return!1;var l=f;if(s=p(s),(n||!i)&&!(l in s)){if(s=1==e.length?s:r(s,o(e,0,-1)),null==s)return!1;l=c(e),s=p(s)}return s[l]===t?void 0!==t||l in s:a(t,s[l],void 0,!0)}}var r=e("./baseGet"),a=e("./baseIsEqual"),o=e("./baseSlice"),s=e("../lang/isArray"),l=e("./isKey"),u=e("./isStrictComparable"),c=e("../array/last"),p=e("./toObject"),h=e("./toPath");t.exports=i},{"../array/last":52,"../lang/isArray":142,"./baseGet":79,"./baseIsEqual":81,"./baseSlice":91,"./isKey":125,"./isStrictComparable":129,"./toObject":137,"./toPath":138}],88:[function(e,t,n){function i(e){return function(t){return null==t?void 0:r(t)[e]}}var r=e("./toObject");t.exports=i},{"./toObject":137}],89:[function(e,t,n){function i(e){var t=e+"";return e=a(e),function(n){return r(n,e,t)}}var r=e("./baseGet"),a=e("./toPath");t.exports=i},{"./baseGet":79,"./toPath":138}],90:[function(e,t,n){var i=e("../utility/identity"),r=e("./metaMap"),a=r?function(e,t){return r.set(e,t),e}:i;t.exports=a},{"../utility/identity":156,"./metaMap":131}],91:[function(e,t,n){function i(e,t,n){var i=-1,r=e.length;t=null==t?0:+t||0,0>t&&(t=-t>r?0:r+t),n=void 0===n||n>r?r:+n||0,0>n&&(n+=r),r=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(r);++i<r;)a[i]=e[i+t];return a}t.exports=i},{}],92:[function(e,t,n){function i(e){return null==e?"":e+""}t.exports=i},{}],93:[function(e,t,n){function i(e,t){for(var n=-1,i=t.length,r=Array(i);++n<i;)r[n]=e[t[n]];return r}t.exports=i},{}],94:[function(e,t,n){function i(e,t,n){var i=0,o=e?e.length:i;if("number"==typeof t&&t===t&&s>=o){for(;o>i;){var l=i+o>>>1,u=e[l];(n?t>=u:t>u)&&null!==u?i=l+1:o=l}return o}return r(e,t,a,n)}var r=e("./binaryIndexBy"),a=e("../utility/identity"),o=4294967295,s=o>>>1;t.exports=i},{"../utility/identity":156,"./binaryIndexBy":95}],95:[function(e,t,n){function i(e,t,n,i){t=n(t);for(var o=0,l=e?e.length:0,u=t!==t,c=null===t,p=void 0===t;l>o;){var h=r((o+l)/2),f=n(e[h]),d=void 0!==f,m=f===f;if(u)var g=m||i;else g=c?m&&d&&(i||null!=f):p?m&&(i||d):null==f?!1:i?t>=f:t>f;g?o=h+1:l=h}return a(l,s)}var r=Math.floor,a=Math.min,o=4294967295,s=o-1;t.exports=i},{}],96:[function(e,t,n){function i(e,t,n){if("function"!=typeof e)return r;if(void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,i,r){return e.call(t,n,i,r)};case 4:return function(n,i,r,a){return e.call(t,n,i,r,a)};case 5:return function(n,i,r,a,o){return e.call(t,n,i,r,a,o)}}return function(){return e.apply(t,arguments)}}var r=e("../utility/identity");t.exports=i},{"../utility/identity":156}],97:[function(e,t,n){(function(e){function n(e){var t=new i(e.byteLength),n=new r(t);return n.set(new r(e)),t}var i=e.ArrayBuffer,r=e.Uint8Array;t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],98:[function(e,t,n){function i(e,t,n){for(var i=n.length,a=-1,o=r(e.length-i,0),s=-1,l=t.length,u=Array(l+o);++s<l;)u[s]=t[s];for(;++a<i;)u[n[a]]=e[a];for(;o--;)u[s++]=e[a++];return u}var r=Math.max;t.exports=i},{}],99:[function(e,t,n){function i(e,t,n){for(var i=-1,a=n.length,o=-1,s=r(e.length-a,0),l=-1,u=t.length,c=Array(s+u);++o<s;)c[o]=e[o];for(var p=o;++l<u;)c[p+l]=t[l];for(;++i<a;)c[p+n[i]]=e[o++];return c}var r=Math.max;t.exports=i},{}],100:[function(e,t,n){function i(e,t){return function(n,i){var s=n?r(n):0;if(!a(s))return e(n,i);for(var l=t?s:-1,u=o(n);(t?l--:++l<s)&&i(u[l],l,u)!==!1;);return n}}var r=e("./getLength"),a=e("./isLength"),o=e("./toObject");t.exports=i},{"./getLength":114,"./isLength":127,"./toObject":137}],101:[function(e,t,n){function i(e){return function(t,n,i){for(var a=r(t),o=i(t),s=o.length,l=e?s:-1;e?l--:++l<s;){var u=o[l];if(n(a[u],u,a)===!1)break}return t}}var r=e("./toObject");t.exports=i},{"./toObject":137}],102:[function(e,t,n){(function(n){function i(e,t){function i(){var r=this&&this!==n&&this instanceof i?a:e;return r.apply(t,arguments)}var a=r(e);return i}var r=e("./createCtorWrapper");t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":103}],103:[function(e,t,n){function i(e){return function(){var t=arguments;switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);case 5:return new e(t[0],t[1],t[2],t[3],t[4]);case 6:return new e(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new e(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var n=r(e.prototype),i=e.apply(n,t);return a(i)?i:n}}var r=e("./baseCreate"),a=e("../lang/isObject");t.exports=i},{"../lang/isObject":146,"./baseCreate":72}],104:[function(e,t,n){function i(e,t){return function(n,i,l){if(i=r(i,l,3),s(n)){var u=o(n,i,t);return u>-1?n[u]:void 0}return a(n,i,e)}}var r=e("./baseCallback"),a=e("./baseFind"),o=e("./baseFindIndex"),s=e("../lang/isArray");t.exports=i},{"../lang/isArray":142,"./baseCallback":69,"./baseFind":74,"./baseFindIndex":75}],105:[function(e,t,n){function i(e,t){return function(n,i,o){return"function"==typeof i&&void 0===o&&a(n)?e(n,i):t(n,r(i,o,3))}}var r=e("./bindCallback"),a=e("../lang/isArray");t.exports=i},{"../lang/isArray":142,"./bindCallback":96}],106:[function(e,t,n){(function(n){function i(e,t,x,A,O,j,_,S,k,C){function E(){for(var d=arguments.length,m=d,g=Array(d);m--;)g[m]=arguments[m];if(A&&(g=a(g,A,O)),j&&(g=o(g,j,_)),U||P){var b=E.placeholder,D=c(g,b);if(d-=D.length,C>d){var R=S?r(S):void 0,N=w(C-d,0),F=U?D:void 0,B=U?void 0:D,V=U?g:void 0,q=U?void 0:g;t|=U?y:v,t&=~(U?v:y),M||(t&=~(h|f));var z=[e,t,x,V,F,q,B,R,k,N],H=i.apply(void 0,z);return l(e)&&p(H,z),H.placeholder=b,H}}var J=T?x:this,Q=$?J[e]:e;return S&&(g=u(g,S)),I&&k<g.length&&(g.length=k),this&&this!==n&&this instanceof E&&(Q=L||s(e)),Q.apply(J,g)}var I=t&b,T=t&h,$=t&f,U=t&m,M=t&d,P=t&g,L=$?void 0:s(e);return E;
+}var r=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./createCtorWrapper"),l=e("./isLaziable"),u=e("./reorder"),c=e("./replaceHolders"),p=e("./setData"),h=1,f=2,d=4,m=8,g=16,y=32,v=64,b=128,w=Math.max;t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./createCtorWrapper":103,"./isLaziable":126,"./reorder":133,"./replaceHolders":134,"./setData":135}],107:[function(e,t,n){(function(n){function i(e,t,i,o){function s(){for(var t=-1,r=arguments.length,a=-1,c=o.length,p=Array(c+r);++a<c;)p[a]=o[a];for(;r--;)p[a++]=arguments[++t];var h=this&&this!==n&&this instanceof s?u:e;return h.apply(l?i:this,p)}var l=t&a,u=r(e);return s}var r=e("./createCtorWrapper"),a=1;t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":103}],108:[function(e,t,n){function i(e,t,n,i,y,v,b,w){var x=t&h;if(!x&&"function"!=typeof e)throw new TypeError(m);var A=i?i.length:0;if(A||(t&=~(f|d),i=y=void 0),A-=y?y.length:0,t&d){var O=i,j=y;i=y=void 0}var _=x?void 0:l(e),S=[e,t,n,i,y,O,j,v,b,w];if(_&&(u(S,_),t=S[1],w=S[9]),S[9]=null==w?x?0:e.length:g(w-A,0)||0,t==p)var k=a(S[0],S[2]);else k=t!=f&&t!=(p|f)||S[4].length?o.apply(void 0,S):s.apply(void 0,S);var C=_?r:c;return C(k,S)}var r=e("./baseSetData"),a=e("./createBindWrapper"),o=e("./createHybridWrapper"),s=e("./createPartialWrapper"),l=e("./getData"),u=e("./mergeData"),c=e("./setData"),p=1,h=2,f=32,d=64,m="Expected a function",g=Math.max;t.exports=i},{"./baseSetData":90,"./createBindWrapper":102,"./createHybridWrapper":106,"./createPartialWrapper":107,"./getData":112,"./mergeData":130,"./setData":135}],109:[function(e,t,n){function i(e,t,n,i,a,o,s){var l=-1,u=e.length,c=t.length;if(u!=c&&!(a&&c>u))return!1;for(;++l<u;){var p=e[l],h=t[l],f=i?i(a?h:p,a?p:h,l):void 0;if(void 0!==f){if(f)continue;return!1}if(a){if(!r(t,function(e){return p===e||n(p,e,i,a,o,s)}))return!1}else if(p!==h&&!n(p,h,i,a,o,s))return!1}return!0}var r=e("./arraySome");t.exports=i},{"./arraySome":67}],110:[function(e,t,n){function i(e,t,n){switch(n){case r:case a:return+e==+t;case o:return e.name==t.name&&e.message==t.message;case s:return e!=+e?t!=+t:e==+t;case l:case u:return e==t+""}return!1}var r="[object Boolean]",a="[object Date]",o="[object Error]",s="[object Number]",l="[object RegExp]",u="[object String]";t.exports=i},{}],111:[function(e,t,n){function i(e,t,n,i,a,s,l){var u=r(e),c=u.length,p=r(t),h=p.length;if(c!=h&&!a)return!1;for(var f=c;f--;){var d=u[f];if(!(a?d in t:o.call(t,d)))return!1}for(var m=a;++f<c;){d=u[f];var g=e[d],y=t[d],v=i?i(a?y:g,a?g:y,d):void 0;if(!(void 0===v?n(g,y,i,a,s,l):v))return!1;m||(m="constructor"==d)}if(!m){var b=e.constructor,w=t.constructor;if(b!=w&&"constructor"in e&&"constructor"in t&&!("function"==typeof b&&b instanceof b&&"function"==typeof w&&w instanceof w))return!1}return!0}var r=e("../object/keys"),a=Object.prototype,o=a.hasOwnProperty;t.exports=i},{"../object/keys":151}],112:[function(e,t,n){var i=e("./metaMap"),r=e("../utility/noop"),a=i?function(e){return i.get(e)}:r;t.exports=a},{"../utility/noop":157,"./metaMap":131}],113:[function(e,t,n){function i(e){for(var t=e.name+"",n=r[t],i=n?n.length:0;i--;){var a=n[i],o=a.func;if(null==o||o==e)return a.name}return t}var r=e("./realNames");t.exports=i},{"./realNames":132}],114:[function(e,t,n){var i=e("./baseProperty"),r=i("length");t.exports=r},{"./baseProperty":88}],115:[function(e,t,n){function i(e){for(var t=a(e),n=t.length;n--;)t[n][2]=r(t[n][1]);return t}var r=e("./isStrictComparable"),a=e("../object/pairs");t.exports=i},{"../object/pairs":153,"./isStrictComparable":129}],116:[function(e,t,n){function i(e,t){var n=null==e?void 0:e[t];return r(n)?n:void 0}var r=e("../lang/isNative");t.exports=i},{"../lang/isNative":145}],117:[function(e,t,n){function i(e,t,n){for(var i=e.length,r=t+(n?0:-1);n?r--:++r<i;){var a=e[r];if(a!==a)return r}return-1}t.exports=i},{}],118:[function(e,t,n){function i(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&a.call(e,"index")&&(n.index=e.index,n.input=e.input),n}var r=Object.prototype,a=r.hasOwnProperty;t.exports=i},{}],119:[function(e,t,n){(function(n){function i(e,t,n){var i=e.constructor;switch(t){case c:return r(e);case a:case o:return new i(+e);case p:case h:case f:case d:case m:case g:case y:case v:case b:i instanceof i&&(i=A[t]);var x=e.buffer;return new i(n?r(x):x,e.byteOffset,e.length);case s:case u:return new i(e);case l:var O=new i(e.source,w.exec(e));O.lastIndex=e.lastIndex}return O}var r=e("./bufferClone"),a="[object Boolean]",o="[object Date]",s="[object Number]",l="[object RegExp]",u="[object String]",c="[object ArrayBuffer]",p="[object Float32Array]",h="[object Float64Array]",f="[object Int8Array]",d="[object Int16Array]",m="[object Int32Array]",g="[object Uint8Array]",y="[object Uint8ClampedArray]",v="[object Uint16Array]",b="[object Uint32Array]",w=/\w*$/,x=n.Uint8Array,A={};A[p]=n.Float32Array,A[h]=n.Float64Array,A[f]=n.Int8Array,A[d]=n.Int16Array,A[m]=n.Int32Array,A[g]=x,A[y]=n.Uint8ClampedArray,A[v]=n.Uint16Array,A[b]=n.Uint32Array,t.exports=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./bufferClone":97}],120:[function(e,t,n){function i(e){var t=e.constructor;return"function"==typeof t&&t instanceof t||(t=Object),new t}t.exports=i},{}],121:[function(e,t,n){function i(e){return null!=e&&a(r(e))}var r=e("./getLength"),a=e("./isLength");t.exports=i},{"./getLength":114,"./isLength":127}],122:[function(e,t,n){var i=function(){try{Object({toString:0}+"")}catch(e){return function(){return!1}}return function(e){return"function"!=typeof e.toString&&"string"==typeof(e+"")}}();t.exports=i},{}],123:[function(e,t,n){function i(e,t){return e="number"==typeof e||r.test(e)?+e:-1,t=null==t?a:t,e>-1&&e%1==0&&t>e}var r=/^\d+$/,a=9007199254740991;t.exports=i},{}],124:[function(e,t,n){function i(e,t,n){if(!o(n))return!1;var i=typeof t;if("number"==i?r(n)&&a(t,n.length):"string"==i&&t in n){var s=n[t];return e===e?e===s:s!==s}return!1}var r=e("./isArrayLike"),a=e("./isIndex"),o=e("../lang/isObject");t.exports=i},{"../lang/isObject":146,"./isArrayLike":121,"./isIndex":123}],125:[function(e,t,n){function i(e,t){var n=typeof e;if("string"==n&&s.test(e)||"number"==n)return!0;if(r(e))return!1;var i=!o.test(e);return i||null!=t&&e in a(t)}var r=e("../lang/isArray"),a=e("./toObject"),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,s=/^\w*$/;t.exports=i},{"../lang/isArray":142,"./toObject":137}],126:[function(e,t,n){function i(e){var t=o(e),n=s[t];if("function"!=typeof n||!(t in r.prototype))return!1;if(e===n)return!0;var i=a(n);return!!i&&e===i[0]}var r=e("./LazyWrapper"),a=e("./getData"),o=e("./getFuncName"),s=e("../chain/lodash");t.exports=i},{"../chain/lodash":53,"./LazyWrapper":62,"./getData":112,"./getFuncName":113}],127:[function(e,t,n){function i(e){return"number"==typeof e&&e>-1&&e%1==0&&r>=e}var r=9007199254740991;t.exports=i},{}],128:[function(e,t,n){function i(e){return!!e&&"object"==typeof e}t.exports=i},{}],129:[function(e,t,n){function i(e){return e===e&&!r(e)}var r=e("../lang/isObject");t.exports=i},{"../lang/isObject":146}],130:[function(e,t,n){function i(e,t){var n=e[1],i=t[1],m=n|i,g=p>m,y=i==p&&n==c||i==p&&n==h&&e[7].length<=t[8]||i==(p|h)&&n==c;if(!g&&!y)return e;i&l&&(e[2]=t[2],m|=n&l?0:u);var v=t[3];if(v){var b=e[3];e[3]=b?a(b,v,t[4]):r(v),e[4]=b?s(e[3],f):r(t[4])}return v=t[5],v&&(b=e[5],e[5]=b?o(b,v,t[6]):r(v),e[6]=b?s(e[5],f):r(t[6])),v=t[7],v&&(e[7]=r(v)),i&p&&(e[8]=null==e[8]?t[8]:d(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=m,e}var r=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./replaceHolders"),l=1,u=4,c=8,p=128,h=256,f="__lodash_placeholder__",d=Math.min;t.exports=i},{"./arrayCopy":64,"./composeArgs":98,"./composeArgsRight":99,"./replaceHolders":134}],131:[function(e,t,n){(function(n){var i=e("./getNative"),r=i(n,"WeakMap"),a=r&&new r;t.exports=a}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./getNative":116}],132:[function(e,t,n){var i={};t.exports=i},{}],133:[function(e,t,n){function i(e,t){for(var n=e.length,i=o(t.length,n),s=r(e);i--;){var l=t[i];e[i]=a(l,n)?s[l]:void 0}return e}var r=e("./arrayCopy"),a=e("./isIndex"),o=Math.min;t.exports=i},{"./arrayCopy":64,"./isIndex":123}],134:[function(e,t,n){function i(e,t){for(var n=-1,i=e.length,a=-1,o=[];++n<i;)e[n]===t&&(e[n]=r,o[++a]=n);return o}var r="__lodash_placeholder__";t.exports=i},{}],135:[function(e,t,n){var i=e("./baseSetData"),r=e("../date/now"),a=150,o=16,s=function(){var e=0,t=0;return function(n,s){var l=r(),u=o-(l-t);if(t=l,u>0){if(++e>=a)return n}else e=0;return i(n,s)}}();t.exports=s},{"../date/now":59,"./baseSetData":90}],136:[function(e,t,n){function i(e){for(var t=u(e),n=t.length,i=n&&e.length,c=!!i&&s(i)&&(a(e)||r(e)||l(e)),h=-1,f=[];++h<n;){var d=t[h];(c&&o(d,i)||p.call(e,d))&&f.push(d)}return f}var r=e("../lang/isArguments"),a=e("../lang/isArray"),o=e("./isIndex"),s=e("./isLength"),l=e("../lang/isString"),u=e("../object/keysIn"),c=Object.prototype,p=c.hasOwnProperty;t.exports=i},{"../lang/isArguments":141,"../lang/isArray":142,"../lang/isString":148,"../object/keysIn":152,"./isIndex":123,"./isLength":127}],137:[function(e,t,n){function i(e){if(o.unindexedChars&&a(e)){for(var t=-1,n=e.length,i=Object(e);++t<n;)i[t]=e.charAt(t);return i}return r(e)?e:Object(e)}var r=e("../lang/isObject"),a=e("../lang/isString"),o=e("../support");t.exports=i},{"../lang/isObject":146,"../lang/isString":148,"../support":155}],138:[function(e,t,n){function i(e){if(a(e))return e;var t=[];return r(e).replace(o,function(e,n,i,r){t.push(i?r.replace(s,"$1"):n||e)}),t}var r=e("./baseToString"),a=e("../lang/isArray"),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,s=/\\(\\)?/g;t.exports=i},{"../lang/isArray":142,"./baseToString":92}],139:[function(e,t,n){function i(e){return e instanceof r?e.clone():new a(e.__wrapped__,e.__chain__,o(e.__actions__))}var r=e("./LazyWrapper"),a=e("./LodashWrapper"),o=e("./arrayCopy");t.exports=i},{"./LazyWrapper":62,"./LodashWrapper":63,"./arrayCopy":64}],140:[function(e,t,n){function i(e,t,n){return"function"==typeof t?r(e,!0,a(t,n,3)):r(e,!0)}var r=e("../internal/baseClone"),a=e("../internal/bindCallback");t.exports=i},{"../internal/baseClone":70,"../internal/bindCallback":96}],141:[function(e,t,n){function i(e){return a(e)&&r(e)&&s.call(e,"callee")&&!l.call(e,"callee")}var r=e("../internal/isArrayLike"),a=e("../internal/isObjectLike"),o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;t.exports=i},{"../internal/isArrayLike":121,"../internal/isObjectLike":128}],142:[function(e,t,n){var i=e("../internal/getNative"),r=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Array]",s=Object.prototype,l=s.toString,u=i(Array,"isArray"),c=u||function(e){return a(e)&&r(e.length)&&l.call(e)==o};t.exports=c},{"../internal/getNative":116,"../internal/isLength":127,"../internal/isObjectLike":128}],143:[function(e,t,n){function i(e){return null==e?!0:o(e)&&(a(e)||u(e)||r(e)||l(e)&&s(e.splice))?!e.length:!c(e).length}var r=e("./isArguments"),a=e("./isArray"),o=e("../internal/isArrayLike"),s=e("./isFunction"),l=e("../internal/isObjectLike"),u=e("./isString"),c=e("../object/keys");t.exports=i},{"../internal/isArrayLike":121,"../internal/isObjectLike":128,"../object/keys":151,"./isArguments":141,"./isArray":142,"./isFunction":144,"./isString":148}],144:[function(e,t,n){function i(e){return r(e)&&s.call(e)==a}var r=e("./isObject"),a="[object Function]",o=Object.prototype,s=o.toString;t.exports=i},{"./isObject":146}],145:[function(e,t,n){function i(e){return null==e?!1:r(e)?p.test(u.call(e)):o(e)&&(a(e)?p:s).test(e)}var r=e("./isFunction"),a=e("../internal/isHostObject"),o=e("../internal/isObjectLike"),s=/^\[object .+?Constructor\]$/,l=Object.prototype,u=Function.prototype.toString,c=l.hasOwnProperty,p=RegExp("^"+u.call(c).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=i},{"../internal/isHostObject":122,"../internal/isObjectLike":128,"./isFunction":144}],146:[function(e,t,n){function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}t.exports=i},{}],147:[function(e,t,n){function i(e){var t;if(!s(e)||h.call(e)!=u||o(e)||a(e)||!p.call(e,"constructor")&&(t=e.constructor,"function"==typeof t&&!(t instanceof t)))return!1;var n;return l.ownLast?(r(e,function(e,t,i){return n=p.call(i,t),!1}),n!==!1):(r(e,function(e,t){n=t}),void 0===n||p.call(e,n))}var r=e("../internal/baseForIn"),a=e("./isArguments"),o=e("../internal/isHostObject"),s=e("../internal/isObjectLike"),l=e("../support"),u="[object Object]",c=Object.prototype,p=c.hasOwnProperty,h=c.toString;t.exports=i},{"../internal/baseForIn":77,"../internal/isHostObject":122,"../internal/isObjectLike":128,"../support":155,"./isArguments":141}],148:[function(e,t,n){function i(e){return"string"==typeof e||r(e)&&s.call(e)==a}var r=e("../internal/isObjectLike"),a="[object String]",o=Object.prototype,s=o.toString;t.exports=i},{"../internal/isObjectLike":128}],149:[function(e,t,n){function i(e){return a(e)&&r(e.length)&&!!E[T.call(e)]}var r=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Arguments]",s="[object Array]",l="[object Boolean]",u="[object Date]",c="[object Error]",p="[object Function]",h="[object Map]",f="[object Number]",d="[object Object]",m="[object RegExp]",g="[object Set]",y="[object String]",v="[object WeakMap]",b="[object ArrayBuffer]",w="[object Float32Array]",x="[object Float64Array]",A="[object Int8Array]",O="[object Int16Array]",j="[object Int32Array]",_="[object Uint8Array]",S="[object Uint8ClampedArray]",k="[object Uint16Array]",C="[object Uint32Array]",E={};E[w]=E[x]=E[A]=E[O]=E[j]=E[_]=E[S]=E[k]=E[C]=!0,E[o]=E[s]=E[b]=E[l]=E[u]=E[c]=E[p]=E[h]=E[f]=E[d]=E[m]=E[g]=E[y]=E[v]=!1;var I=Object.prototype,T=I.toString;t.exports=i},{"../internal/isLength":127,"../internal/isObjectLike":128}],150:[function(e,t,n){function i(e){return void 0===e}t.exports=i},{}],151:[function(e,t,n){var i=e("../internal/getNative"),r=e("../internal/isArrayLike"),a=e("../lang/isObject"),o=e("../internal/shimKeys"),s=e("../support"),l=i(Object,"keys"),u=l?function(e){var t=null==e?void 0:e.constructor;return"function"==typeof t&&t.prototype===e||("function"==typeof e?s.enumPrototypes:r(e))?o(e):a(e)?l(e):[]}:o;t.exports=u},{"../internal/getNative":116,"../internal/isArrayLike":121,"../internal/shimKeys":136,"../lang/isObject":146,"../support":155}],152:[function(e,t,n){function i(e){if(null==e)return[];c(e)||(e=Object(e));var t=e.length;t=t&&u(t)&&(o(e)||a(e)||p(e))&&t||0;for(var n=e.constructor,i=-1,r=s(n)&&n.prototype||j,f=r===e,d=Array(t),m=t>0,y=h.enumErrorProps&&(e===O||e instanceof Error),v=h.enumPrototypes&&s(e);++i<t;)d[i]=i+"";for(var w in e)v&&"prototype"==w||y&&("message"==w||"name"==w)||m&&l(w,t)||"constructor"==w&&(f||!S.call(e,w))||d.push(w);if(h.nonEnumShadows&&e!==j){var E=e===_?x:e===O?g:k.call(e),I=C[E]||C[b];for(E==b&&(r=j),t=A.length;t--;){w=A[t];var T=I[w];f&&T||(T?!S.call(e,w):e[w]===r[w])||d.push(w)}}return d}var r=e("../internal/arrayEach"),a=e("../lang/isArguments"),o=e("../lang/isArray"),s=e("../lang/isFunction"),l=e("../internal/isIndex"),u=e("../internal/isLength"),c=e("../lang/isObject"),p=e("../lang/isString"),h=e("../support"),f="[object Array]",d="[object Boolean]",m="[object Date]",g="[object Error]",y="[object Function]",v="[object Number]",b="[object Object]",w="[object RegExp]",x="[object String]",A=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],O=Error.prototype,j=Object.prototype,_=String.prototype,S=j.hasOwnProperty,k=j.toString,C={};C[f]=C[m]=C[v]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},C[d]=C[x]={constructor:!0,toString:!0,valueOf:!0},C[g]=C[y]=C[w]={constructor:!0,toString:!0},C[b]={constructor:!0},r(A,function(e){for(var t in C)if(S.call(C,t)){var n=C[t];n[e]=S.call(n,e)}}),t.exports=i},{"../internal/arrayEach":65,"../internal/isIndex":123,"../internal/isLength":127,"../lang/isArguments":141,"../lang/isArray":142,"../lang/isFunction":144,"../lang/isObject":146,"../lang/isString":148,"../support":155}],153:[function(e,t,n){function i(e){e=a(e);for(var t=-1,n=r(e),i=n.length,o=Array(i);++t<i;){var s=n[t];o[t]=[s,e[s]]}return o}var r=e("./keys"),a=e("../internal/toObject");t.exports=i},{"../internal/toObject":137,"./keys":151}],154:[function(e,t,n){function i(e){return r(e,a(e))}var r=e("../internal/baseValues"),a=e("./keys");t.exports=i},{"../internal/baseValues":93,"./keys":151}],155:[function(e,t,n){var i=Array.prototype,r=Error.prototype,a=Object.prototype,o=a.propertyIsEnumerable,s=i.splice,l={};!function(e){var t=function(){this.x=e},n={0:e,length:e},i=[];t.prototype={valueOf:e,y:e};for(var a in new t)i.push(a);l.enumErrorProps=o.call(r,"message")||o.call(r,"name"),l.enumPrototypes=o.call(t,"prototype"),l.nonEnumShadows=!/valueOf/.test(i),l.ownLast="x"!=i[0],l.spliceObjects=(s.call(n,0,1),!n[0]),l.unindexedChars="x"[0]+Object("x")[0]!="xx"}(1,0),t.exports=l},{}],156:[function(e,t,n){function i(e){return e}t.exports=i},{}],157:[function(e,t,n){function i(){}t.exports=i},{}],158:[function(e,t,n){function i(e){return o(e)?r(e):a(e)}var r=e("../internal/baseProperty"),a=e("../internal/basePropertyDeep"),o=e("../internal/isKey");t.exports=i},{"../internal/baseProperty":88,"../internal/basePropertyDeep":89,"../internal/isKey":125}],159:[function(e,n,i){(function(e){!function(e){"use strict";if("function"==typeof bootstrap)bootstrap("promise",e);else if("object"==typeof i&&"object"==typeof n)n.exports=e();else if("function"==typeof t&&t.amd)t(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeQ=e}else{if("undefined"==typeof window&&"undefined"==typeof self)throw new Error("This environment was not anticipated by Q. Please file a bug.");var r="undefined"!=typeof window?window:self,a=r.Q;r.Q=e(),r.Q.noConflict=function(){return r.Q=a,this}}}(function(){"use strict";function t(e){return function(){return K.apply(e,arguments)}}function n(e){return e===Object(e)}function i(e){return"[object StopIteration]"===ie(e)||e instanceof H}function r(e,t){if(V&&t.stack&&"object"==typeof e&&null!==e&&e.stack&&-1===e.stack.indexOf(re)){for(var n=[],i=t;i;i=i.source)i.stack&&n.unshift(i.stack);n.unshift(e.stack);var r=n.join("\n"+re+"\n");e.stack=a(r)}}function a(e){for(var t=e.split("\n"),n=[],i=0;i<t.length;++i){var r=t[i];l(r)||o(r)||!r||n.push(r)}return n.join("\n")}function o(e){return-1!==e.indexOf("(module.js:")||-1!==e.indexOf("(node.js:")}function s(e){var t=/at .+ \((.+):(\d+):(?:\d+)\)$/.exec(e);if(t)return[t[1],Number(t[2])];var n=/at ([^ ]+):(\d+):(?:\d+)$/.exec(e);if(n)return[n[1],Number(n[2])];var i=/.*@(.+):(\d+)$/.exec(e);return i?[i[1],Number(i[2])]:void 0}function l(e){var t=s(e);if(!t)return!1;var n=t[0],i=t[1];return n===z&&i>=J&&ue>=i}function u(){if(V)try{throw new Error}catch(e){var t=e.stack.split("\n"),n=t[0].indexOf("@")>0?t[1]:t[2],i=s(n);if(!i)return;return z=i[0],i[1]}}function c(e,t,n){return function(){return"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(t+" is deprecated, use "+n+" instead.",new Error("").stack),e.apply(e,arguments)}}function p(e){return e instanceof m?e:b(e)?C(e):k(e)}function h(){function e(e){t=e,a.source=e,X(n,function(t,n){p.nextTick(function(){e.promiseDispatch.apply(e,n)})},void 0),n=void 0,i=void 0}var t,n=[],i=[],r=ee(h.prototype),a=ee(m.prototype);if(a.promiseDispatch=function(e,r,a){var o=W(arguments);n?(n.push(o),"when"===r&&a[1]&&i.push(a[1])):p.nextTick(function(){t.promiseDispatch.apply(t,o)})},a.valueOf=function(){if(n)return a;var e=y(t);return v(e)&&(t=e),e},a.inspect=function(){return t?t.inspect():{state:"pending"}},p.longStackSupport&&V)try{throw new Error}catch(o){a.stack=o.stack.substring(o.stack.indexOf("\n")+1)}return r.promise=a,r.resolve=function(n){t||e(p(n))},r.fulfill=function(n){t||e(k(n))},r.reject=function(n){t||e(S(n))},r.notify=function(e){t||X(i,function(t,n){p.nextTick(function(){n(e)})},void 0)},r}function f(e){if("function"!=typeof e)throw new TypeError("resolver must be a function.");var t=h();try{e(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}return t.promise}function d(e){return f(function(t,n){for(var i=0,r=e.length;r>i;i++)p(e[i]).then(t,n)})}function m(e,t,n){void 0===t&&(t=function(e){return S(new Error("Promise does not support operation: "+e))}),void 0===n&&(n=function(){return{state:"unknown"}});var i=ee(m.prototype);if(i.promiseDispatch=function(n,r,a){var o;try{o=e[r]?e[r].apply(i,a):t.call(i,r,a)}catch(s){o=S(s)}n&&n(o)},i.inspect=n,n){var r=n();"rejected"===r.state&&(i.exception=r.reason),i.valueOf=function(){var e=n();return"pending"===e.state||"rejected"===e.state?i:e.value}}return i}function g(e,t,n,i){return p(e).then(t,n,i)}function y(e){if(v(e)){var t=e.inspect();if("fulfilled"===t.state)return t.value}return e}function v(e){return e instanceof m}function b(e){return n(e)&&"function"==typeof e.then}function w(e){return v(e)&&"pending"===e.inspect().state}function x(e){return!v(e)||"fulfilled"===e.inspect().state}function A(e){return v(e)&&"rejected"===e.inspect().state}function O(){ae.length=0,oe.length=0,le||(le=!0)}function j(t,n){le&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){-1!==G(oe,t)&&(e.emit("unhandledRejection",n,t),se.push(t))}),oe.push(t),n&&"undefined"!=typeof n.stack?ae.push(n.stack):ae.push("(no stack) "+n))}function _(t){if(le){var n=G(oe,t);-1!==n&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){var i=G(se,t);-1!==i&&(e.emit("rejectionHandled",ae[n],t),se.splice(i,1))}),oe.splice(n,1),ae.splice(n,1))}}function S(e){var t=m({when:function(t){return t&&_(this),t?t(e):this}},function(){return this},function(){return{state:"rejected",reason:e}});return j(t,e),t}function k(e){return m({when:function(){return e},get:function(t){return e[t]},set:function(t,n){e[t]=n},"delete":function(t){delete e[t]},post:function(t,n){return null===t||void 0===t?e.apply(void 0,n):e[t].apply(e,n)},apply:function(t,n){return e.apply(t,n)},keys:function(){return ne(e)}},void 0,function(){return{state:"fulfilled",value:e}})}function C(e){var t=h();return p.nextTick(function(){try{e.then(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}}),t.promise}function E(e){return m({isDef:function(){}},function(t,n){return P(e,t,n)},function(){return p(e).inspect()})}function I(e,t,n){return p(e).spread(t,n)}function T(e){return function(){function t(e,t){var o;if("undefined"==typeof StopIteration){try{o=n[e](t)}catch(s){return S(s)}return o.done?p(o.value):g(o.value,r,a)}try{o=n[e](t)}catch(s){return i(s)?p(s.value):S(s)}return g(o,r,a)}var n=e.apply(this,arguments),r=t.bind(t,"next"),a=t.bind(t,"throw");return r()}}function $(e){p.done(p.async(e)())}function U(e){throw new H(e)}function M(e){return function(){return I([this,L(arguments)],function(t,n){return e.apply(t,n)})}}function P(e,t,n){return p(e).dispatch(t,n)}function L(e){return g(e,function(e){var t=0,n=h();return X(e,function(i,r,a){var o;v(r)&&"fulfilled"===(o=r.inspect()).state?e[a]=o.value:(++t,g(r,function(i){e[a]=i,0===--t&&n.resolve(e)},n.reject,function(e){n.notify({index:a,value:e})}))},void 0),0===t&&n.resolve(e),n.promise})}function D(e){if(0===e.length)return p.resolve();var t=p.defer(),n=0;return X(e,function(i,r,a){function o(e){t.resolve(e)}function s(){n--,0===n&&t.reject(new Error("Can't get fulfillment value from any promise, all promises were rejected."))}function l(e){t.notify({index:a,value:e})}var u=e[a];n++,g(u,o,s,l)},void 0),t.promise}function R(e){return g(e,function(e){return e=Z(e,p),g(L(Z(e,function(e){return g(e,Q,Q)})),function(){return e})})}function N(e){return p(e).allSettled()}function F(e,t){return p(e).then(void 0,void 0,t)}function B(e,t){return p(e).nodeify(t)}var V=!1;try{throw new Error}catch(q){V=!!q.stack}var z,H,J=u(),Q=function(){},Y=function(){function t(){for(var e,t;i.next;)i=i.next,e=i.task,i.task=void 0,t=i.domain,t&&(i.domain=void 0,t.enter()),n(e,t);for(;l.length;)e=l.pop(),n(e);a=!1}function n(e,n){try{e()}catch(i){if(s)throw n&&n.exit(),setTimeout(t,0),n&&n.enter(),i;setTimeout(function(){throw i},0)}n&&n.exit()}var i={task:void 0,next:null},r=i,a=!1,o=void 0,s=!1,l=[];if(Y=function(t){r=r.next={task:t,domain:s&&e.domain,next:null},a||(a=!0,o())},"object"==typeof e&&"[object process]"===e.toString()&&e.nextTick)s=!0,o=function(){e.nextTick(t)};else if("function"==typeof setImmediate)o="undefined"!=typeof window?setImmediate.bind(window,t):function(){setImmediate(t)};else if("undefined"!=typeof MessageChannel){var u=new MessageChannel;u.port1.onmessage=function(){o=c,u.port1.onmessage=t,t()};var c=function(){u.port2.postMessage(0)};o=function(){setTimeout(t,0),c()}}else o=function(){setTimeout(t,0)};return Y.runAfter=function(e){l.push(e),a||(a=!0,o())},Y}(),K=Function.call,W=t(Array.prototype.slice),X=t(Array.prototype.reduce||function(e,t){var n=0,i=this.length;if(1===arguments.length)for(;;){if(n in this){t=this[n++];break}if(++n>=i)throw new TypeError}for(;i>n;n++)n in this&&(t=e(t,this[n],n));return t}),G=t(Array.prototype.indexOf||function(e){for(var t=0;t<this.length;t++)if(this[t]===e)return t;return-1}),Z=t(Array.prototype.map||function(e,t){var n=this,i=[];return X(n,function(r,a,o){i.push(e.call(t,a,o,n))},void 0),i}),ee=Object.create||function(e){function t(){}return t.prototype=e,new t},te=t(Object.prototype.hasOwnProperty),ne=Object.keys||function(e){var t=[];for(var n in e)te(e,n)&&t.push(n);return t},ie=t(Object.prototype.toString);H="undefined"!=typeof ReturnValue?ReturnValue:function(e){this.value=e};var re="From previous event:";p.resolve=p,p.nextTick=Y,p.longStackSupport=!1,"object"==typeof e&&e&&e.env&&e.env.Q_DEBUG&&(p.longStackSupport=!0),p.defer=h,h.prototype.makeNodeResolver=function(){var e=this;return function(t,n){t?e.reject(t):arguments.length>2?e.resolve(W(arguments,1)):e.resolve(n)}},p.Promise=f,p.promise=f,f.race=d,f.all=L,f.reject=S,f.resolve=p,p.passByCopy=function(e){return e},m.prototype.passByCopy=function(){return this},p.join=function(e,t){return p(e).join(t)},m.prototype.join=function(e){return p([this,e]).spread(function(e,t){if(e===t)return e;throw new Error("Can't join: not the same: "+e+" "+t)})},p.race=d,m.prototype.race=function(){return this.then(p.race)},p.makePromise=m,m.prototype.toString=function(){return"[object Promise]"},m.prototype.then=function(e,t,n){function i(t){try{return"function"==typeof e?e(t):t}catch(n){return S(n)}}function a(e){if("function"==typeof t){r(e,s);try{return t(e)}catch(n){return S(n)}}return S(e)}function o(e){return"function"==typeof n?n(e):e}var s=this,l=h(),u=!1;return p.nextTick(function(){s.promiseDispatch(function(e){u||(u=!0,l.resolve(i(e)))},"when",[function(e){u||(u=!0,l.resolve(a(e)))}])}),s.promiseDispatch(void 0,"when",[void 0,function(e){var t,n=!1;try{t=o(e)}catch(i){if(n=!0,!p.onerror)throw i;p.onerror(i)}n||l.notify(t)}]),l.promise},p.tap=function(e,t){return p(e).tap(t)},m.prototype.tap=function(e){return e=p(e),this.then(function(t){return e.fcall(t).thenResolve(t)})},p.when=g,m.prototype.thenResolve=function(e){return this.then(function(){return e})},p.thenResolve=function(e,t){return p(e).thenResolve(t)},m.prototype.thenReject=function(e){return this.then(function(){throw e})},p.thenReject=function(e,t){return p(e).thenReject(t)},p.nearer=y,p.isPromise=v,p.isPromiseAlike=b,p.isPending=w,m.prototype.isPending=function(){return"pending"===this.inspect().state},p.isFulfilled=x,m.prototype.isFulfilled=function(){return"fulfilled"===this.inspect().state},p.isRejected=A,m.prototype.isRejected=function(){return"rejected"===this.inspect().state};var ae=[],oe=[],se=[],le=!0;p.resetUnhandledRejections=O,p.getUnhandledReasons=function(){return ae.slice()},p.stopUnhandledRejectionTracking=function(){O(),le=!1},O(),p.reject=S,p.fulfill=k,p.master=E,p.spread=I,m.prototype.spread=function(e,t){return this.all().then(function(t){return e.apply(void 0,t)},t)},p.async=T,p.spawn=$,p["return"]=U,p.promised=M,p.dispatch=P,m.prototype.dispatch=function(e,t){var n=this,i=h();return p.nextTick(function(){n.promiseDispatch(i.resolve,e,t)}),i.promise},p.get=function(e,t){return p(e).dispatch("get",[t])},m.prototype.get=function(e){return this.dispatch("get",[e])},p.set=function(e,t,n){return p(e).dispatch("set",[t,n])},m.prototype.set=function(e,t){return this.dispatch("set",[e,t])},p.del=p["delete"]=function(e,t){return p(e).dispatch("delete",[t])},m.prototype.del=m.prototype["delete"]=function(e){return this.dispatch("delete",[e])},p.mapply=p.post=function(e,t,n){return p(e).dispatch("post",[t,n])},m.prototype.mapply=m.prototype.post=function(e,t){return this.dispatch("post",[e,t])},p.send=p.mcall=p.invoke=function(e,t){return p(e).dispatch("post",[t,W(arguments,2)])},m.prototype.send=m.prototype.mcall=m.prototype.invoke=function(e){return this.dispatch("post",[e,W(arguments,1)])},p.fapply=function(e,t){return p(e).dispatch("apply",[void 0,t])},m.prototype.fapply=function(e){return this.dispatch("apply",[void 0,e])},p["try"]=p.fcall=function(e){return p(e).dispatch("apply",[void 0,W(arguments,1)])},m.prototype.fcall=function(){return this.dispatch("apply",[void 0,W(arguments)])},p.fbind=function(e){var t=p(e),n=W(arguments,1);return function(){return t.dispatch("apply",[this,n.concat(W(arguments))])}},m.prototype.fbind=function(){var e=this,t=W(arguments);return function(){return e.dispatch("apply",[this,t.concat(W(arguments))])}},p.keys=function(e){return p(e).dispatch("keys",[])},m.prototype.keys=function(){return this.dispatch("keys",[])},p.all=L,m.prototype.all=function(){return L(this)},p.any=D,m.prototype.any=function(){return D(this)},p.allResolved=c(R,"allResolved","allSettled"),m.prototype.allResolved=function(){return R(this)},p.allSettled=N,m.prototype.allSettled=function(){return this.then(function(e){return L(Z(e,function(e){function t(){return e.inspect()}return e=p(e),e.then(t,t)}))})},p.fail=p["catch"]=function(e,t){return p(e).then(void 0,t)},m.prototype.fail=m.prototype["catch"]=function(e){return this.then(void 0,e)},p.progress=F,m.prototype.progress=function(e){return this.then(void 0,void 0,e)},p.fin=p["finally"]=function(e,t){return p(e)["finally"](t)},m.prototype.fin=m.prototype["finally"]=function(e){return e=p(e),this.then(function(t){return e.fcall().then(function(){return t})},function(t){return e.fcall().then(function(){throw t})})},p.done=function(e,t,n,i){return p(e).done(t,n,i)},m.prototype.done=function(t,n,i){var a=function(e){p.nextTick(function(){if(r(e,o),!p.onerror)throw e;p.onerror(e)})},o=t||n||i?this.then(t,n,i):this;"object"==typeof e&&e&&e.domain&&(a=e.domain.bind(a)),o.then(void 0,a)},p.timeout=function(e,t,n){return p(e).timeout(t,n)},m.prototype.timeout=function(e,t){var n=h(),i=setTimeout(function(){t&&"string"!=typeof t||(t=new Error(t||"Timed out after "+e+" ms"),t.code="ETIMEDOUT"),n.reject(t)},e);return this.then(function(e){clearTimeout(i),n.resolve(e)},function(e){clearTimeout(i),n.reject(e)},n.notify),n.promise},p.delay=function(e,t){return void 0===t&&(t=e,e=void 0),p(e).delay(t)},m.prototype.delay=function(e){return this.then(function(t){var n=h();return setTimeout(function(){n.resolve(t)},e),n.promise})},p.nfapply=function(e,t){return p(e).nfapply(t)},m.prototype.nfapply=function(e){var t=h(),n=W(e);return n.push(t.makeNodeResolver()),this.fapply(n).fail(t.reject),t.promise},p.nfcall=function(e){var t=W(arguments,1);return p(e).nfapply(t)},m.prototype.nfcall=function(){var e=W(arguments),t=h();return e.push(t.makeNodeResolver()),this.fapply(e).fail(t.reject),t.promise},p.nfbind=p.denodeify=function(e){var t=W(arguments,1);
+return function(){var n=t.concat(W(arguments)),i=h();return n.push(i.makeNodeResolver()),p(e).fapply(n).fail(i.reject),i.promise}},m.prototype.nfbind=m.prototype.denodeify=function(){var e=W(arguments);return e.unshift(this),p.denodeify.apply(void 0,e)},p.nbind=function(e,t){var n=W(arguments,2);return function(){function i(){return e.apply(t,arguments)}var r=n.concat(W(arguments)),a=h();return r.push(a.makeNodeResolver()),p(i).fapply(r).fail(a.reject),a.promise}},m.prototype.nbind=function(){var e=W(arguments,0);return e.unshift(this),p.nbind.apply(void 0,e)},p.nmapply=p.npost=function(e,t,n){return p(e).npost(t,n)},m.prototype.nmapply=m.prototype.npost=function(e,t){var n=W(t||[]),i=h();return n.push(i.makeNodeResolver()),this.dispatch("post",[e,n]).fail(i.reject),i.promise},p.nsend=p.nmcall=p.ninvoke=function(e,t){var n=W(arguments,2),i=h();return n.push(i.makeNodeResolver()),p(e).dispatch("post",[t,n]).fail(i.reject),i.promise},m.prototype.nsend=m.prototype.nmcall=m.prototype.ninvoke=function(e){var t=W(arguments,1),n=h();return t.push(n.makeNodeResolver()),this.dispatch("post",[e,t]).fail(n.reject),n.promise},p.nodeify=B,m.prototype.nodeify=function(e){return e?void this.then(function(t){p.nextTick(function(){e(null,t)})},function(t){p.nextTick(function(){e(t)})}):this},p.noConflict=function(){throw new Error("Q.noConflict only works when Q is used as a global")};var ue=u();return p})}).call(this,e("_process"))},{_process:13}],160:[function(e,t,n){t.exports=function(e,t,n){for(var i=0,r=e.length,a=3==arguments.length?n:e[i++];r>i;)a=t.call(null,a,e[i],++i,e);return a}},{}],161:[function(e,t,n){function i(){}function r(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function a(e){return e===Object(e)}function o(e){if(!a(e))return e;var t=[];for(var n in e)null!=e[n]&&s(t,n,e[n]);return t.join("&")}function s(e,t,n){return Array.isArray(n)?n.forEach(function(n){s(e,t,n)}):void e.push(encodeURIComponent(t)+"="+encodeURIComponent(n))}function l(e){for(var t,n,i={},r=e.split("&"),a=0,o=r.length;o>a;++a)n=r[a],t=n.split("="),i[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);return i}function u(e){var t,n,i,r,a=e.split(/\r?\n/),o={};a.pop();for(var s=0,l=a.length;l>s;++s)n=a[s],t=n.indexOf(":"),i=n.slice(0,t).toLowerCase(),r=w(n.slice(t+1)),o[i]=r;return o}function c(e){return/[\/+]json\b/.test(e)}function p(e){return e.split(/ *; */).shift()}function h(e){return b(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),i=n.shift(),r=n.shift();return i&&r&&(e[i]=r),e},{})}function f(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=u(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function d(e,t){var n=this;v.call(this),this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new f(n)}catch(i){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=i,e.rawResponse=n.xhr&&n.xhr.responseText?n.xhr.responseText:null,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var r=new Error(t.statusText||"Unsuccessful HTTP response");r.original=e,r.response=t,r.status=t.status,n.callback(r,t)})}function m(e,t){return"function"==typeof t?new d("GET",e).end(t):1==arguments.length?new d("GET",e):new d(e,t)}function g(e,t){var n=m("DELETE",e);return t&&n.end(t),n}var y,v=e("emitter"),b=e("reduce");y="undefined"!=typeof window?window:"undefined"!=typeof self?self:this,m.getXHR=function(){if(!(!y.XMLHttpRequest||y.location&&"file:"==y.location.protocol&&y.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var w="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};m.serializeObject=o,m.parseString=l,m.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},m.serialize={"application/x-www-form-urlencoded":o,"application/json":JSON.stringify},m.parse={"application/x-www-form-urlencoded":l,"application/json":JSON.parse},f.prototype.get=function(e){return this.header[e.toLowerCase()]},f.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=p(t);var n=h(t);for(var i in n)this[i]=n[i]},f.prototype.parseBody=function(e){var t=m.parse[this.type];return t&&e&&(e.length||e instanceof Object)?t(e):null},f.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=this.statusCode=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=4==t||5==t?this.toError():!1,this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},f.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,i="cannot "+t+" "+n+" ("+this.status+")",r=new Error(i);return r.status=this.status,r.method=t,r.url=n,r},m.Response=f,v(d.prototype),d.prototype.use=function(e){return e(this),this},d.prototype.timeout=function(e){return this._timeout=e,this},d.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},d.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},d.prototype.set=function(e,t){if(a(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},d.prototype.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},d.prototype.getHeader=function(e){return this._header[e.toLowerCase()]},d.prototype.type=function(e){return this.set("Content-Type",m.types[e]||e),this},d.prototype.parse=function(e){return this._parser=e,this},d.prototype.accept=function(e){return this.set("Accept",m.types[e]||e),this},d.prototype.auth=function(e,t){var n=btoa(e+":"+t);return this.set("Authorization","Basic "+n),this},d.prototype.query=function(e){return"string"!=typeof e&&(e=o(e)),e&&this._query.push(e),this},d.prototype.field=function(e,t){return this._formData||(this._formData=new y.FormData),this._formData.append(e,t),this},d.prototype.attach=function(e,t,n){return this._formData||(this._formData=new y.FormData),this._formData.append(e,t,n||t.name),this},d.prototype.send=function(e){var t=a(e),n=this.getHeader("Content-Type");if(t&&a(this._data))for(var i in e)this._data[i]=e[i];else"string"==typeof e?(n||this.type("form"),n=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+e:e:this._data=(this._data||"")+e):this._data=e;return!t||r(e)?this:(n||this.type("json"),this)},d.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},d.prototype.crossDomainError=function(){var e=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");e.crossDomain=!0,e.status=this.status,e.method=this.method,e.url=this.url,this.callback(e)},d.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},d.prototype.withCredentials=function(){return this._withCredentials=!0,this},d.prototype.end=function(e){var t=this,n=this.xhr=m.getXHR(),a=this._query.join("&"),o=this._timeout,s=this._formData||this._data;this._callback=e||i,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(i){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var l=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),e.direction="download",t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=l);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=l)}catch(u){}if(o&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},o)),a&&(a=m.serializeObject(a),this.url+=~this.url.indexOf("?")?"&"+a:"?"+a),n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof s&&!r(s)){var p=this.getHeader("Content-Type"),h=this._parser||m.serialize[p?p.split(";")[0]:""];!h&&c(p)&&(h=m.serialize["application/json"]),h&&(s=h(s))}for(var f in this.header)null!=this.header[f]&&n.setRequestHeader(f,this.header[f]);return this.emit("request",this),n.send("undefined"!=typeof s?s:null),this},d.prototype.then=function(e,t){return this.end(function(n,i){n?t(n):e(i)})},m.Request=d,m.get=function(e,t,n){var i=m("GET",e);return"function"==typeof t&&(n=t,t=null),t&&i.query(t),n&&i.end(n),i},m.head=function(e,t,n){var i=m("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&i.send(t),n&&i.end(n),i},m.del=g,m["delete"]=g,m.patch=function(e,t,n){var i=m("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&i.send(t),n&&i.end(n),i},m.post=function(e,t,n){var i=m("POST",e);return"function"==typeof t&&(n=t,t=null),t&&i.send(t),n&&i.end(n),i},m.put=function(e,t,n){var i=m("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&i.send(t),n&&i.end(n),i},t.exports=m},{emitter:19,reduce:160}]},{},[1])(1)}),window.SwaggerUi=Backbone.Router.extend({dom_id:"swagger_ui",options:null,api:null,headerView:null,mainView:null,initialize:function(e){e=e||{},"model"!==e.defaultModelRendering&&(e.defaultModelRendering="schema"),e.highlightSizeThreshold||(e.highlightSizeThreshold=1e5),e.dom_id&&(this.dom_id=e.dom_id,delete e.dom_id),e.supportedSubmitMethods||(e.supportedSubmitMethods=["get","put","post","delete","head","options","patch"]),"string"==typeof e.oauth2RedirectUrl&&(window.oAuthRedirectUrl=e.redirectUrl),$("#"+this.dom_id).length||$("body").append('<div id="'+this.dom_id+'"></div>'),this.options=e,marked.setOptions({gfm:!0});var t=this;this.options.success=function(){return t.render()},this.options.progress=function(e){return t.showMessage(e)},this.options.failure=function(e){return t.onLoadFailure(e)},this.headerView=new SwaggerUi.Views.HeaderView({el:$("#header")}),this.headerView.on("update-swagger-ui",function(e){return t.updateSwaggerUi(e)}),JSONEditor.defaults.iconlibs.swagger=JSONEditor.AbstractIconLib.extend({mapping:{collapse:"collapse",expand:"expand"},icon_prefix:"swagger-"})},setOption:function(e,t){this.options[e]=t},getOption:function(e){return this.options[e]},updateSwaggerUi:function(e){this.options.url=e.url,this.load()},load:function(){this.mainView&&this.mainView.clear(),this.authView&&this.authView.remove();var e=this.options.url;e&&0!==e.indexOf("http")&&(e=this.buildUrl(window.location.href.toString(),e)),this.api&&(this.options.authorizations=this.api.clientAuthorizations.authz),this.options.url=e,this.headerView.update(e),this.api=new SwaggerClient(this.options)},collapseAll:function(){Docs.collapseEndpointListForResource("")},listAll:function(){Docs.collapseOperationsForResource("")},expandAll:function(){Docs.expandOperationsForResource("")},render:function(){var e;switch(this.showMessage("Finished Loading Resource Information. Rendering Swagger UI..."),this.mainView=new SwaggerUi.Views.MainView({model:this.api,el:$("#"+this.dom_id),swaggerOptions:this.options,router:this}).render(),_.isEmpty(this.api.securityDefinitions)||(e=_.map(this.api.securityDefinitions,function(e,t){var n={};return n[t]=e,n}),this.authView=new SwaggerUi.Views.AuthButtonView({data:SwaggerUi.utils.parseSecurityDefinitions(e),router:this}),$("#auth_container").append(this.authView.render().el)),this.showMessage(),this.options.docExpansion){case"full":this.expandAll();break;case"list":this.listAll()}this.renderGFM(),this.options.onComplete&&this.options.onComplete(this.api,this),setTimeout(Docs.shebang.bind(this),100)},buildUrl:function(e,t){if(0===t.indexOf("/")){var n=e.split("/");return e=n[0]+"//"+n[2],e+t}var i=e.length;return e.indexOf("?")>-1&&(i=Math.min(i,e.indexOf("?"))),e.indexOf("#")>-1&&(i=Math.min(i,e.indexOf("#"))),e=e.substring(0,i),-1!==e.indexOf("/",e.length-1)?e+t:e+"/"+t},showMessage:function(e){void 0===e&&(e="");var t=$("#message-bar");t.removeClass("message-fail"),t.addClass("message-success"),t.text(e),window.SwaggerTranslator&&window.SwaggerTranslator.translate(t)},onLoadFailure:function(e){void 0===e&&(e=""),$("#message-bar").removeClass("message-success"),$("#message-bar").addClass("message-fail");var t=$("#message-bar").text(e);return this.options.onFailure&&this.options.onFailure(e),t},renderGFM:function(){$(".markdown").each(function(){$(this).html(marked($(this).html()))}),$(".propDesc",".model-signature .description").each(function(){$(this).html(marked($(this).html())).addClass("markdown")})}}),window.SwaggerUi.Views={},window.SwaggerUi.Models={},window.SwaggerUi.Collections={},window.SwaggerUi.partials={},window.SwaggerUi.utils={},function(){function e(e){"console"in window&&"function"==typeof window.console.warn&&console.warn(e)}window.authorizations={add:function(){if(e("Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add()."),"undefined"==typeof window.swaggerUi)throw new TypeError("window.swaggerUi is not defined");window.swaggerUi instanceof SwaggerUi&&window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations,arguments)}},window.ApiKeyAuthorization=function(){e("window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization."),SwaggerClient.ApiKeyAuthorization.apply(window,arguments)},window.PasswordAuthorization=function(){e("window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization."),SwaggerClient.PasswordAuthorization.apply(window,arguments)}}(),function(e,t){"function"==typeof define&&define.amd?define(["b"],function(n){return e.SwaggerUi=t(n)}):"object"==typeof exports?module.exports=t(require("b")):e.SwaggerUi=t(e.b)}(this,function(){return SwaggerUi}),window.SwaggerUi.utils={parseSecurityDefinitions:function(e){var t=Object.assign({},window.swaggerUi.api.authSchemes||window.swaggerUi.api.securityDefinitions),n=[],i=[],r=[],a=window.SwaggerUi.utils;return Array.isArray(e)?(e.forEach(function(e){var o={},s={};for(var l in e)if(Array.isArray(e[l])){if(!t[l])continue;if(t[l]=t[l]||{},"oauth2"===t[l].type){s[l]=Object.assign({},t[l]);for(var u in s[l].scopes)e[l].indexOf(u)<0&&delete s[l].scopes[u];s[l].scopes=a.parseOauth2Scopes(s[l].scopes),r=_.merge(r,s[l].scopes)}else o[l]=Object.assign({},t[l])}else"oauth2"===e[l].type?(s[l]=Object.assign({},e[l]),s[l].scopes=a.parseOauth2Scopes(s[l].scopes),r=_.merge(r,s[l].scopes)):o[l]=e[l];_.isEmpty(o)||i.push(o),_.isEmpty(s)||n.push(s)}),{auths:i,oauth2:n,scopes:r}):null},parseOauth2Scopes:function(e){var t,n=Object.assign({},e),i=[];for(t in n)i.push({scope:t,description:n[t]});return i}},SwaggerUi.Models.ApiKeyAuthModel=Backbone.Model.extend({defaults:{"in":"",name:"",title:"",value:""},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("value");return this.set("valid",e),e}}),SwaggerUi.Views.ApiKeyAuthView=Backbone.View.extend({events:{"change .input_apiKey_entry":"apiKeyChange"},selectors:{apikeyInput:".input_apiKey_entry"},template:Handlebars.templates.apikey_auth,initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){return this.$el.html(this.template(this.model.toJSON())),this},apiKeyChange:function(e){var t=$(e.target).val();t&&this.$(this.selectors.apikeyInput).removeClass("error"),this.model.set("value",t)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.isValid()||this.$(this.selectors.apikeyInput).addClass("error")}}),SwaggerUi.Views.AuthButtonView=Backbone.View.extend({events:{"click .authorize__btn":"authorizeBtnClick"},tpls:{popup:Handlebars.templates.popup,authBtn:Handlebars.templates.auth_button,authBtnOperation:Handlebars.templates.auth_button_operation},initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.isOperation=this.options.isOperation,this.model=this.model||{},this.router=this.options.router,this.auths=this.options.data.oauth2.concat(this.options.data.auths)},render:function(){var e=this.isOperation?"authBtnOperation":"authBtn";return this.$authEl=this.renderAuths(this.auths),this.$el.html(this.tpls[e](this.model)),this},authorizeBtnClick:function(e){var t;e.preventDefault(),t={title:"Available authorizations",content:this.$authEl},this.popup=new SwaggerUi.Views.PopupView({model:t}),this.popup.render()},renderAuths:function(e){var t=$("<div>"),n=!1;return e.forEach(function(e){var i=new SwaggerUi.Views.AuthView({data:e,router:this.router}),r=i.render().el;t.append(r),i.isLogout&&(n=!0)},this),this.model.isLogout=n,t}}),SwaggerUi.Collections.AuthsCollection=Backbone.Collection.extend({constructor:function(){var e=Array.prototype.slice.call(arguments);e[0]=this.parse(e[0]),Backbone.Collection.apply(this,e)},add:function(e){var t=Array.prototype.slice.call(arguments);Array.isArray(e)?t[0]=_.map(e,function(e){return this.handleOne(e)},this):t[0]=this.handleOne(e),Backbone.Collection.prototype.add.apply(this,t)},handleOne:function(e){var t=e;if(!(e instanceof Backbone.Model))switch(e.type){case"oauth2":t=new SwaggerUi.Models.Oauth2Model(e);break;case"basic":t=new SwaggerUi.Models.BasicAuthModel(e);break;case"apiKey":t=new SwaggerUi.Models.ApiKeyAuthModel(e);break;default:t=new Backbone.Model(e)}return t},isValid:function(){var e=!0;return this.models.forEach(function(t){t.validate()||(e=!1)}),e},isAuthorized:function(){return this.length===this.where({isLogout:!0}).length},isPartiallyAuthorized:function(){return this.where({isLogout:!0}).length>0},parse:function(e){var t=Object.assign({},window.swaggerUi.api.clientAuthorizations.authz);return _.map(e,function(e,n){var i=t.basic&&"basic"===e.type;return _.extend(e,{title:n}),(t[n]||i)&&_.extend(e,{isLogout:!0,value:i?void 0:t[n].value,username:i?t.basic.username:void 0,password:i?t.basic.password:void 0,valid:!0}),e})}}),SwaggerUi.Views.AuthsCollectionView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.router=this.options.router,this.collection=new SwaggerUi.Collections.AuthsCollection(e.data),this.$innerEl=$("<div>"),this.authViews=[]},render:function(){return this.collection.each(function(e){this.renderOneAuth(e)},this),this.$el.html(this.$innerEl.html()?this.$innerEl:""),this},renderOneAuth:function(e){var t,n,i,r=e.get("type");"apiKey"===r?i="ApiKeyAuthView":"basic"===r&&0===this.$innerEl.find(".basic_auth_container").length?i="BasicAuthView":"oauth2"===r&&(i="Oauth2View"),i&&(n=new SwaggerUi.Views[i]({model:e,router:this.router}),t=n.render().el,this.authViews.push(n)),this.$innerEl.append(t)},highlightInvalid:function(){this.authViews.forEach(function(e){e.highlightInvalid()},this)}}),SwaggerUi.Views.AuthView=Backbone.View.extend({events:{"click .auth_submit__button":"authorizeClick","click .auth_logout__button":"logoutClick"},tpls:{main:Handlebars.templates.auth_view},selectors:{innerEl:".auth_inner",authBtn:".auth_submit__button"},initialize:function(e){this.options=e||{},e.data=e.data||{},this.router=this.options.router,this.authsCollectionView=new SwaggerUi.Views.AuthsCollectionView({data:e.data}),this.$el.html(this.tpls.main({isLogout:this.authsCollectionView.collection.isAuthorized(),isAuthorized:this.authsCollectionView.collection.isPartiallyAuthorized()})),this.$innerEl=this.$(this.selectors.innerEl),this.isLogout=this.authsCollectionView.collection.isPartiallyAuthorized()},render:function(){return this.$innerEl.html(this.authsCollectionView.render().el),this},authorizeClick:function(e){e.preventDefault(),e.stopPropagation(),this.authsCollectionView.collection.isValid()?this.authorize():this.authsCollectionView.highlightInvalid()},authorize:function(){this.authsCollectionView.collection.forEach(function(e){var t,n,i=e.get("type");"apiKey"===i?(t=new SwaggerClient.ApiKeyAuthorization(e.get("name"),e.get("value"),e.get("in")),this.router.api.clientAuthorizations.add(e.get("title"),t)):"basic"===i?(n=new SwaggerClient.PasswordAuthorization(e.get("username"),e.get("password")),this.router.api.clientAuthorizations.add(e.get("type"),n)):"oauth2"===i&&this.handleOauth2Login(e)},this),this.router.load()},logoutClick:function(e){e.preventDefault(),this.authsCollectionView.collection.forEach(function(e){var t="basic"===e.get("type")?"basic":e.get("title");window.swaggerUi.api.clientAuthorizations.remove(t)}),this.router.load()},handleOauth2Login:function(e){var t,n,i,r=window.location,a=location.pathname.substring(0,location.pathname.lastIndexOf("/")),o=r.protocol+"//"+r.host+a+"/o2c.html",s=window.oAuthRedirectUrl||o,l=null,u=_.map(e.get("scopes"),function(e){return e.scope});window.OAuthSchemeKey=e.get("title"),window.enabledScopes=u;var c=e.get("flow");if("oauth2"!==e.get("type")||!c||"implicit"!==c&&"accessCode"!==c){if("oauth2"===e.get("type")&&c&&"application"===c)return n=e.attributes,window.swaggerUi.tokenName=n.tokenName||"access_token",void this.clientCredentialsFlow(u,n.tokenUrl,window.OAuthSchemeKey);if(e.get("grantTypes")){var p=e.get("grantTypes");for(var h in p)p.hasOwnProperty(h)&&"implicit"===h?(n=p[h],i=n.loginEndpoint.url,l=n.loginEndpoint.url+"?response_type=token",window.swaggerUi.tokenName=n.tokenName):p.hasOwnProperty(h)&&"accessCode"===h&&(n=p[h],i=n.tokenRequestEndpoint.url,l=n.tokenRequestEndpoint.url+"?response_type=code",window.swaggerUi.tokenName=n.tokenName)}}else n=e.attributes,l=n.authorizationUrl+"?response_type="+("implicit"===c?"token":"code"),window.swaggerUi.tokenName=n.tokenName||"access_token",window.swaggerUi.tokenUrl="accessCode"===c?n.tokenUrl:null,t=window.OAuthSchemeKey;l+="&redirect_uri="+encodeURIComponent(s),l+="&realm="+encodeURIComponent(realm),l+="&client_id="+encodeURIComponent(clientId),l+="&scope="+encodeURIComponent(u.join(scopeSeparator)),l+="&state="+encodeURIComponent(t);for(var f in additionalQueryStringParams)l+="&"+f+"="+encodeURIComponent(additionalQueryStringParams[f]);window.open(l)},clientCredentialsFlow:function(e,t,n){var i={client_id:clientId,client_secret:clientSecret,scope:e.join(" "),grant_type:"client_credentials"};$.ajax({url:t,type:"POST",data:i,success:function(e){onOAuthComplete(e,n)},error:function(){onOAuthComplete("")}})}}),SwaggerUi.Models.BasicAuthModel=Backbone.Model.extend({defaults:{username:"",password:"",title:"basic"},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("password")&&!!this.get("username");return this.set("valid",e),e}}),SwaggerUi.Views.BasicAuthView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},events:{"change .auth_input":"inputChange"},selectors:{usernameInput:".basic_auth__username",passwordInput:".basic_auth__password"},cls:{error:"error"},template:Handlebars.templates.basic_auth,render:function(){return $(this.el).html(this.template(this.model.toJSON())),this},inputChange:function(e){var t=$(e.target),n=t.val(),i=t.prop("name");n&&t.removeClass(this.cls.error),this.model.set(i,n)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.model.get("username")||this.$(this.selectors.usernameInput).addClass(this.cls.error),this.model.get("password")||this.$(this.selectors.passwordInput).addClass(this.cls.error)}}),SwaggerUi.Views.ContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.contentTypeId="ct"+Math.random(),$(this.el).html(Handlebars.templates.content_type(this.model)),this}}),SwaggerUi.Views.HeaderView=Backbone.View.extend({events:{"click #show-pet-store-icon":"showPetStore","click #explore":"showCustom","keyup #input_baseUrl":"showCustomOnKeyup","keyup #input_apiKey":"showCustomOnKeyup"},initialize:function(){},showPetStore:function(){this.trigger("update-swagger-ui",{url:"http://petstore.swagger.io/v2/swagger.json"})},showCustomOnKeyup:function(e){13===e.keyCode&&this.showCustom()},showCustom:function(e){e&&e.preventDefault(),this.trigger("update-swagger-ui",{url:$("#input_baseUrl").val()})},update:function(e,t,n){void 0===n&&(n=!1),$("#input_baseUrl").val(e),n&&this.trigger("update-swagger-ui",{url:e})}}),SwaggerUi.Views.MainView=Backbone.View.extend({apisSorter:{alpha:function(e,t){return e.name.localeCompare(t.name)}},operationsSorters:{alpha:function(e,t){return e.path.localeCompare(t.path)},method:function(e,t){return e.method.localeCompare(t.method)}},initialize:function(e){var t,n,i,r;if(e=e||{},this.router=e.router,e.swaggerOptions.apisSorter&&(t=e.swaggerOptions.apisSorter,n=_.isFunction(t)?t:this.apisSorter[t],_.isFunction(n)&&this.model.apisArray.sort(n)),e.swaggerOptions.operationsSorter&&(t=e.swaggerOptions.operationsSorter,n=_.isFunction(t)?t:this.operationsSorters[t],_.isFunction(n)))for(i in this.model.apisArray)this.model.apisArray[i].operationsArray.sort(n);this.model.auths=[];for(i in this.model.securityDefinitions)r=this.model.securityDefinitions[i],this.model.auths.push({name:i,type:r.type,value:r});"validatorUrl"in e.swaggerOptions?this.model.validatorUrl=e.swaggerOptions.validatorUrl:this.model.url.indexOf("localhost")>0||this.model.url.indexOf("127.0.0.1")>0?this.model.validatorUrl=null:"https:"===window.location.protocol?this.model.validatorUrl="https://online.swagger.io/validator":this.model.validatorUrl="http://online.swagger.io/validator";var a;for(a in this.model.definitions)this.model.definitions[a].type||(this.model.definitions[a].type="object")},render:function(){$(this.el).html(Handlebars.templates.main(this.model)),this.info=this.$(".info")[0],this.info&&this.info.addEventListener("click",this.onLinkClick,!0),this.model.securityDefinitions=this.model.securityDefinitions||{};for(var e={},t=0,n=0;n<this.model.apisArray.length;n++){for(var i=this.model.apisArray[n],r=i.name;"undefined"!=typeof e[r];)r=r+"_"+t,t+=1;i.id=r,e[r]=i,this.addResource(i,this.model.auths)}return $(".propWrap").hover(function(){$(".optionsWrapper",$(this)).show()},function(){$(".optionsWrapper",$(this)).hide()}),this},addResource:function(e,t){e.id=e.id.replace(/\s/g,"_"),e.definitions=this.model.definitions;var n=new SwaggerUi.Views.ResourceView({model:e,router:this.router,tagName:"li",id:"resource_"+e.id,className:"resource",auths:t,swaggerOptions:this.options.swaggerOptions});$("#resources",this.el).append(n.render().el)},clear:function(){$(this.el).html("")},onLinkClick:function(e){var t=e.target;"A"===t.tagName&&t.href&&!t.target&&(e.preventDefault(),window.open(t.href,"_blank"))}}),SwaggerUi.Models.Oauth2Model=Backbone.Model.extend({defaults:{scopes:{}},initialize:function(){this.on("change",this.validate)},setScopes:function(e,t){var n=_.extend({},this.attributes),i=_.findIndex(n.scopes,function(t){return t.scope===e});n.scopes[i].checked=t,this.set(n),this.validate()},validate:function(){var e=_.findIndex(this.get("scopes"),function(e){return e.checked===!0})>-1;return this.set("valid",e),e}}),SwaggerUi.Views.Oauth2View=Backbone.View.extend({events:{"change .oauth-scope":"scopeChange"},template:Handlebars.templates.oauth2,render:function(){return this.$el.html(this.template(this.model.toJSON())),this},scopeChange:function(e){var t=$(e.target).prop("checked"),n=$(e.target).data("scope");this.model.setScopes(n,t)}}),SwaggerUi.Views.OperationView=Backbone.View.extend({invocationUrl:null,events:{"submit .sandbox":"submitOperation","click .submit":"submitOperation","click .response_hider":"hideResponse","click .toggleOperation":"toggleOperationContent","mouseenter .api-ic":"mouseEnter","dblclick .curl":"selectText","change [name=responseContentType]":"showSnippet"},initialize:function(e){return e=e||{},this.router=e.router,this.auths=e.auths,this.parentId=this.model.parentId,this.nickname=this.model.nickname,this.model.encodedParentId=encodeURIComponent(this.parentId),e.swaggerOptions&&(this.model.defaultRendering=e.swaggerOptions.defaultModelRendering,e.swaggerOptions.showRequestHeaders&&(this.model.showRequestHeaders=!0)),this},selectText:function(e){var t,n,i=document,r=e.target.firstChild;i.body.createTextRange?(t=document.body.createTextRange(),t.moveToElementText(r),t.select()):window.getSelection&&(n=window.getSelection(),t=document.createRange(),t.selectNodeContents(r),n.removeAllRanges(),n.addRange(t))},mouseEnter:function(e){var t=$(this.el).find(".content"),n=e.pageX,i=e.pageY,r=$(window).scrollLeft(),a=$(window).scrollTop(),o=r+$(window).width(),s=a+$(window).height(),l=t.width(),u=t.height();n+l>o&&(n=o-l),r>n&&(n=r),i+u>s&&(i=s-u),a>i&&(i=a);var c={};c.top=i,c.left=n,t.css(c)},render:function(){var e,t,n,i,r,a,o,s,l,u,c,p,h,f,d,m,g,y,v,b,w,x,A,O,j,S,k,C,E,I,T,U,M,P,L,D,R,N,F,B,V;if(a=jQuery.inArray(this.model.method,this.model.supportedSubmitMethods())>=0,a||(this.model.isReadOnly=!0),this.model.description=this.model.description||this.model.notes,this.model.oauth=null,m=this.model.authorizations||this.model.security)if(Array.isArray(m))for(l=0,u=m.length;u>l;l++){n=m[l];for(s in n)for(e in this.auths)if(t=this.auths[e],s===t.name&&"oauth2"===t.type){this.model.oauth={},this.model.oauth.scopes=[],A=t.value.scopes;for(o in A)R=A[o],U=n[s].indexOf(o),U>=0&&(y={scope:o,description:R},this.model.oauth.scopes.push(y))}}else for(o in m)if(R=m[o],"oauth2"===o)for(null===this.model.oauth&&(this.model.oauth={}),void 0===this.model.oauth.scopes&&(this.model.oauth.scopes=[]),d=0,c=R.length;c>d;d++)y=R[d],this.model.oauth.scopes.push(y);if("undefined"!=typeof this.model.responses){this.model.responseMessages=[],O=this.model.responses;for(i in O)N=O[i],I=null,T=this.model.responses[i].schema,T&&T.$ref&&(I=T.$ref,-1!==I.indexOf("#/definitions/")&&(I=I.replace(/^.*#\/definitions\//,""))),this.model.responseMessages.push({code:i,message:N.description,responseModel:I,headers:N.headers,schema:T})}if("undefined"==typeof this.model.responseMessages&&(this.model.responseMessages=[]),M=null,F=this.model.produces,B=this.contains(F,"xml"),V=B?this.contains(F,"json"):!0,this.model.successResponse){L=this.model.successResponse;for(s in L)N=L[s],this.model.successCode=s,"object"==typeof N&&"function"==typeof N.createJSONSample?(this.model.successDescription=N.description,this.model.headers=this.parseResponseHeaders(N.headers),M={sampleJSON:V?JSON.stringify(SwaggerUi.partials.signature.createJSONSample(N),void 0,2):!1,isParam:!1,sampleXML:B?SwaggerUi.partials.signature.createXMLSample(N.name,N.definition,N.models):!1,signature:SwaggerUi.partials.signature.getModelSignature(N.name,N.definition,N.models,N.modelPropertyMacro)}):M={signature:SwaggerUi.partials.signature.getPrimitiveSignature(N)}}else this.model.responseClassSignature&&"string"!==this.model.responseClassSignature&&(M={sampleJSON:this.model.responseSampleJSON,isParam:!1,signature:this.model.responseClassSignature});for($(this.el).html(Handlebars.templates.operation(this.model)),M?(M.defaultRendering=this.model.defaultRendering,E=new SwaggerUi.Views.SignatureView({model:M,router:this.router,tagName:"div"}),$(".model-signature",$(this.el)).append(E.render().el)):(this.model.responseClassSignature="string",$(".model-signature",$(this.el)).html(this.model.type)),
+r={isParam:!1},r.consumes=this.model.consumes,r.produces=this.model.produces,j=this.model.parameters,g=0,p=j.length;p>g;g++)b=j[g],D=b.type||b.dataType||"","undefined"==typeof D&&(I=b.schema,I&&I.$ref&&(x=I.$ref,D=0===x.indexOf("#/definitions/")?x.substring("#/definitions/".length):x)),D&&"file"===D.toLowerCase()&&(r.consumes||(r.consumes="multipart/form-data")),b.type=D;for(C=new SwaggerUi.Views.ResponseContentTypeView({model:r,router:this.router}),$(".response-content-type",$(this.el)).append(C.render().el),S=this.model.parameters,v=0,h=S.length;h>v;v++)b=S[v],this.addParameter(b,r.consumes);for(k=this.model.responseMessages,w=0,f=k.length;f>w;w++)P=k[w],P.isXML=B,P.isJSON=V,_.isUndefined(P.headers)||(P.headers=this.parseHeadersType(P.headers)),this.addStatusCode(P);if(Array.isArray(this.model.security)){var q=SwaggerUi.utils.parseSecurityDefinitions(this.model.security);q.isLogout=!_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz),this.authView=new SwaggerUi.Views.AuthButtonView({data:q,router:this.router,isOperation:!0,model:{scopes:q.scopes}}),this.$(".authorize-wrapper").append(this.authView.render().el)}return this.showSnippet(),this},parseHeadersType:function(e){var t={string:{"date-time":"dateTime",date:"date"}};return _.forEach(e,function(e){var n;e=e||{},n=t[e.type]&&t[e.type][e.format],_.isUndefined(n)||(e.type=n)}),e},contains:function(e,t){return e.filter(function(e){return e.indexOf(t)>-1?!0:void 0}).length},parseResponseHeaders:function(e){var t="; ",n=_.clone(e);return _.forEach(n,function(e){var n=[];_.forEach(e,function(e,t){var i=["type","description"];-1===i.indexOf(t.toLowerCase())&&n.push(t+": "+e)}),n.join(t),e.other=n}),n},addParameter:function(e,t){e.consumes=t,e.defaultRendering=this.model.defaultRendering,e.schema&&($.extend(!0,e.schema,this.model.definitions[e.type]),e.schema.definitions=this.model.definitions,e.schema.type||(e.schema.type="object"),e.schema.title||(e.schema.title=" "));var n=new SwaggerUi.Views.ParameterView({model:e,tagName:"tr",readOnly:this.model.isReadOnly,swaggerOptions:this.options.swaggerOptions});$(".operation-params",$(this.el)).append(n.render().el)},addStatusCode:function(e){e.defaultRendering=this.model.defaultRendering;var t=new SwaggerUi.Views.StatusCodeView({model:e,tagName:"tr",router:this.router});$(".operation-status",$(this.el)).append(t.render().el)},submitOperation:function(e){var t,n,i,r,a;if(null!==e&&e.preventDefault(),n=$(".sandbox",$(this.el)),t=!0,n.find("input.required").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),n.find("textarea.required:visible").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){return $(e).focus()}}(this)}),t=!1)}),n.find("select.required").each(function(){$(this).removeClass("error"),-1===this.selectedIndex&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),t){if(r=this.getInputMap(n),i=this.isFileUpload(n),a={parent:this},this.options.swaggerOptions)for(var o in this.options.swaggerOptions)a[o]=this.options.swaggerOptions[o];var s;for(s=0;s<this.model.parameters.length;s++){var l=this.model.parameters[s];if(l.jsonEditor&&l.jsonEditor.isEnabled()){var u=l.jsonEditor.getValue();r[l.name]=JSON.stringify(u)}}return a.responseContentType=$("div select[name=responseContentType]",$(this.el)).val(),a.requestContentType=$("div select[name=parameterContentType]",$(this.el)).val(),$(".response_throbber",$(this.el)).show(),i?($(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(this.invocationUrl),a.useJQuery=!0,r.parameterContentType="multipart/form-data",this.map=r,this.model.execute(r,a,this.showCompleteStatus,this.showErrorStatus,this)):(this.map=r,this.model.execute(r,a,this.showCompleteStatus,this.showErrorStatus,this))}},getInputMap:function(e){var t,n,i,r,a,o,s,l,u,c,p,h;for(t={},n=e.find("input"),i=0,r=n.length;r>i;i++)a=n[i],null!==a.value&&jQuery.trim(a.value).length>0&&(t[a.name]=a.value),"file"===a.type&&(t[a.name]=a.files[0]);for(o=e.find("textarea"),s=0,l=o.length;l>s;s++)a=o[s],u=this.getTextAreaValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);for(c=e.find("select"),p=0,h=c.length;h>p;p++)a=c[p],u=this.getSelectedValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);return t},isFileUpload:function(e){var t,n,i,r,a=!1;for(t=e.find("input"),n=0,i=t.length;i>n;n++)r=t[n],"file"===r.type&&(a=!0);return a},success:function(e,t){t.showCompleteStatus(e)},wrap:function(e){var t,n,i,r,a,o,s;for(i={},n=e.getAllResponseHeaders().split("\r"),a=0,o=n.length;o>a;a++)r=n[a],t=r.match(/^([^:]*?):(.*)$/),t||(t=[]),t.shift(),void 0!==t[0]&&void 0!==t[1]&&(i[t[0].trim()]=t[1].trim());return s={},s.content={},s.content.data=e.responseText,s.headers=i,s.request={},s.request.url=this.invocationUrl,s.status=e.status,s},getSelectedValue:function(e){if(e.multiple){for(var t=[],n=0,i=e.options.length;i>n;n++){var r=e.options[n];r.selected&&t.push(r.value)}return t.length>0?t:null}return e.value},hideResponse:function(e){e&&e.preventDefault(),$(".response",$(this.el)).slideUp(),$(".response_hider",$(this.el)).fadeOut()},showResponse:function(e){var t=JSON.stringify(e,null,"      ").replace(/\n/g,"<br>");$(".response_body",$(this.el)).html(_.escape(t))},showErrorStatus:function(e,t){t.showStatus(e)},showCompleteStatus:function(e,t){t.showStatus(e)},formatXml:function(e){var t,n,i,r,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(/\r\n/g,"\n").replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,i="",l=e.split("\n"),r=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",r+=h[t],s=function(){var e,t,i;for(i=[],n=e=0,t=r;t>=0?t>e:e>t;n=t>=0?++e:--e)i.push("  ");return i}().join(""),"opening->closing"===t?i=i.substr(0,i.length-1)+e+"\n":i+=s+e+"\n"},a=0,s=l.length;s>a;a++)u=l[a],n(u);return i},showStatus:function(e){var t,n;void 0===e.content?(n=e.data,t=e.url):(n=e.content.data,t=e.request.url);var i=e.headers;n=jQuery.trim(n);var r=null;i&&(r=i["Content-Type"]||i["content-type"],r&&(r=r.split(";")[0].trim())),$(".response_body",$(this.el)).removeClass("json"),$(".response_body",$(this.el)).removeClass("xml");var a,o,s=function(e){var t=document.createElement("audio");return!(!t.canPlayType||!t.canPlayType(e).replace(/no/,""))};if(n)if("application/json"===r||/\+json$/.test(r)){var l=null;try{l=JSON.stringify(JSON.parse(n),null,"  ")}catch(u){l="can't parse JSON.  Raw result:\n\n"+n}o=$("<code />").text(l),a=$('<pre class="json" />').append(o)}else if("application/xml"===r||/\+xml$/.test(r))o=$("<code />").text(this.formatXml(n)),a=$('<pre class="xml" />').append(o);else if("text/html"===r)o=$("<code />").html(_.escape(n)),a=$('<pre class="xml" />').append(o);else if(/text\/plain/.test(r))o=$("<code />").text(n),a=$('<pre class="plain" />').append(o);else if(/^image\//.test(r))a=$("<img>").attr("src",t);else if(/^audio\//.test(r)&&s(r))a=$("<audio controls>").append($("<source>").attr("src",t).attr("type",r));else if(i["Content-Disposition"]&&/attachment/.test(i["Content-Disposition"])||i["content-disposition"]&&/attachment/.test(i["content-disposition"])||i["Content-Description"]&&/File Transfer/.test(i["Content-Description"])||i["content-description"]&&/File Transfer/.test(i["content-description"]))if("Blob"in window){var c=r||"text/html",p=new Blob([n],{type:c}),h=document.createElement("a"),f=window.URL.createObjectURL(p),d=e.url.substr(e.url.lastIndexOf("/")+1),m=[c,d,f].join(":"),g=i["content-disposition"]||i["Content-Disposition"];if("undefined"!=typeof g){var y=/filename=([^;]*);?/.exec(g);null!==y&&y.length>1&&(m=y[1])}h.setAttribute("href",f),h.setAttribute("download",m),h.innerText="Download "+d,a=$("<div/>").append(h)}else a=$('<pre class="json" />').append("Download headers detected but your browser does not support downloading binary via XHR (Blob).");else i.location||i.Location?window.location=e.url:(o=$("<code />").text(n),a=$('<pre class="json" />').append(o));else o=$("<code />").text("no content"),a=$('<pre class="json" />').append(o);var v=a;$(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(t),$(".response_code",$(this.el)).html("<pre>"+e.status+"</pre>"),$(".response_body",$(this.el)).html(v),$(".response_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(e.headers,null,"  ")).replace(/\n/g,"<br>")+"</pre>"),$(".response",$(this.el)).slideDown(),$(".response_hider",$(this.el)).show(),$(".response_throbber",$(this.el)).hide();var b=this.model.asCurl(this.map,{responseContentType:r});b=b.replace("!","&#33;"),$("div.curl",$(this.el)).html("<pre>"+_.escape(b)+"</pre>");var w=this.options.swaggerOptions;if(w.showRequestHeaders){var x=$(".sandbox",$(this.el)),A=this.getInputMap(x),O=this.model.getHeaderParams(A);delete O["Content-Type"],$(".request_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(O,null,"  ")).replace(/\n/g,"<br>")+"</pre>")}var j=$(".response_body",$(this.el))[0];return w.highlightSizeThreshold&&"undefined"!=typeof e.data&&e.data.length>w.highlightSizeThreshold?j:hljs.highlightBlock(j)},toggleOperationContent:function(e){var t=$("#"+Docs.escapeResourceName(this.parentId+"_"+this.nickname+"_content"));t.is(":visible")?($.bbq.pushState("#/",2),e.preventDefault(),Docs.collapseOperation(t)):Docs.expandOperation(t)},getTextAreaValue:function(e){var t,n,i,r;if(null===e.value||0===jQuery.trim(e.value).length)return null;if(t=this.getParamByName(e.name),t&&t.type&&"array"===t.type.toLowerCase()){for(n=e.value.split("\n"),i=[],r=0;r<n.length;r++)null!==n[r]&&jQuery.trim(n[r]).length>0&&i.push(n[r]);return i.length>0?i:null}return e.value},showSnippet:function(){var e,t=this.$("[name=responseContentType]"),n=this.$(".operation-status .snippet_xml, .response-class .snippet_xml"),i=this.$(".operation-status .snippet_json, .response-class .snippet_json");t.length&&(e=t.val(),e.indexOf("xml")>-1?(n.show(),i.hide()):(i.show(),n.hide()))},getParamByName:function(e){var t;if(this.model.parameters)for(t=0;t<this.model.parameters.length;t++)if(this.model.parameters[t].name===e)return this.model.parameters[t];return null}}),SwaggerUi.Views.ParameterContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.parameterContentTypeId="pct"+Math.random(),$(this.el).html(Handlebars.templates.parameter_content_type(this.model)),this}}),SwaggerUi.Views.ParameterView=Backbone.View.extend({events:{"change [name=parameterContentType]":"toggleParameterSnippet"},initialize:function(){Handlebars.registerHelper("isArray",function(e,t){var n=e.type&&e.type.toLowerCase();return"array"===n||e.allowMultiple?t.fn(this):t.inverse(this)})},render:function(){var e,t,n=this.model.type||this.model.dataType,i=this.model.modelSignature.type,r=this.model.modelSignature.definitions,a=this.model.schema||{},o=this.model.consumes||[];if("undefined"==typeof n&&a.$ref){var s=a.$ref;n=0===s.indexOf("#/definitions/")?s.substring("#/definitions/".length):s}this.model.type=n,this.model.paramType=this.model["in"]||this.model.paramType,this.model.isBody="body"===this.model.paramType||"body"===this.model["in"],this.model.isFile=n&&"file"===n.toLowerCase(),"undefined"==typeof this.model["default"]&&(this.model["default"]=this.model.defaultValue),this.model.hasDefault="undefined"!=typeof this.model["default"],this.model.valueId="m"+this.model.name+Math.random(),this.model.allowableValues&&(this.model.isList=!0);var l=this.contains(o,"xml"),u=l?this.contains(o,"json"):!0;e=SwaggerUi.partials.signature.createParameterJSONSample(i,r);var c=this.template();$(this.el).html(c(this.model));var p={sampleJSON:u?e:!1,sampleXML:e&&l?SwaggerUi.partials.signature.createXMLSample("",a,r,!0):!1,isParam:!0,signature:SwaggerUi.partials.signature.getParameterModelSignature(i,r),defaultRendering:this.model.defaultRendering};e?(t=new SwaggerUi.Views.SignatureView({model:p,tagName:"div"}),$(".model-signature",$(this.el)).append(t.render().el)):$(".model-signature",$(this.el)).html(this.model.signature);var h=!1;if(this.options.swaggerOptions.jsonEditor&&this.model.isBody&&this.model.schema){var f=$(this.el);this.model.jsonEditor=new JSONEditor($(".editor_holder",f)[0],{schema:this.model.schema,startval:this.model["default"],ajax:!0,disable_properties:!0,disable_edit_json:!0,iconlib:"swagger"}),p.jsonEditor=this.model.jsonEditor,$(".body-textarea",f).hide(),$(".editor_holder",f).show(),$(".parameter-content-type",f).change(function(e){"application/xml"===e.target.value?($(".body-textarea",f).show(),$(".editor_holder",f).hide(),this.model.jsonEditor.disable()):($(".body-textarea",f).hide(),$(".editor_holder",f).show(),this.model.jsonEditor.enable())})}this.model.isBody&&(h=!0);var d={isParam:h};if(d.consumes=this.model.consumes,h){var m=new SwaggerUi.Views.ParameterContentTypeView({model:d});$(".parameter-content-type",$(this.el)).append(m.render().el),this.toggleParameterSnippet()}else{var g=new SwaggerUi.Views.ResponseContentTypeView({model:d});$(".response-content-type",$(this.el)).append(g.render().el),this.toggleResponseSnippet()}return this},contains:function(e,t){return e.filter(function(e){return e.indexOf(t)>-1?!0:void 0}).length},toggleParameterSnippet:function(){var e=this.$("[name=parameterContentType]").val();this.toggleSnippet(e)},toggleResponseSnippet:function(){var e=this.$("[name=responseContentType]");e.length&&this.toggleSnippet(e.val())},toggleSnippet:function(e){e=e||"",e.indexOf("xml")>-1?(this.$(".snippet_xml").show(),this.$(".snippet_json").hide()):(this.$(".snippet_json").show(),this.$(".snippet_xml").hide())},template:function(){return this.model.isList?Handlebars.templates.param_list:this.options.readOnly?this.model.required?Handlebars.templates.param_readonly_required:Handlebars.templates.param_readonly:this.model.required?Handlebars.templates.param_required:Handlebars.templates.param}}),SwaggerUi.partials.signature=function(){function e(e){var t,r=e.name,a=e.definition,o=e.config,s=e.models,l=e.config.isParam,u=[],c=a.properties,p=a.additionalProperties,h=a.xml,f=b(h);return f&&u.push(f),c||p?(c=c||{},t=_.map(c,function(e,t){var n,r;return l&&e.readOnly?"":(n=e.xml||{},r=i(t,e,s,o),n.attribute?(u.push(r),""):r)}).join(""),p&&(t+="<!-- additional elements allowed -->"),y(r,t,u)):n()}function t(e){return"<!-- Infinite loop $ref:"+e+" -->"}function n(e){return e=e?": "+e:"","<!-- invalid XML"+e+" -->"}function i(i,r,s,l){var u,c,p=_.isObject(r)?r.$ref:null;l=l||{},l.modelsToIgnore=l.modelsToIgnore||[];var h=_.isString(p)?a(p,i,s,l):o(i,r,s,l);if(!h)return n();switch(h.type){case"array":u=w(h);break;case"object":u=e(h);break;case"loop":u=t(h.name);break;default:u=A(h)}return p&&(c=l.modelsToIgnore.indexOf(p),c>-1&&l.modelsToIgnore.splice(c,1)),u}function r(e,t,n,i,r){if(arguments.length<4)throw new Error;this.config=r||{},this.config.modelsToIgnore=this.config.modelsToIgnore||[],this.name=v(e,n.xml),this.definition=n,this.models=i,this.type=t}function a(e,t,n,i){var a=u(e),o=n[a]||{},s=o.definition&&o.definition.type?o.definition.type:"object";return t=t||o.name,i.modelsToIgnore.indexOf(e)>-1?(s="loop",t=a):i.modelsToIgnore.push(e),o.definition?new r(t,s,o.definition,n,i):null}function o(e,t,n,i){var a=t.type||"object";return t?new r(e,a,t,n,i):null}function s(e,t,n,r){var a='<?xml version="1.0"?>';return p(a+i(e,t,n,{isParam:r}))}var l=function(e){return _.isPlainObject(e.schema)&&(e=l(e.schema)),e},u=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e},c=function(e){if(/^Inline Model \d+$/.test(e)&&this.inlineModels){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},p=function(e){var t,n,i,r,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,i="",l=e.split("\n"),r=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",r+=h[t],s=function(){var e,t,i;for(i=[],n=e=0,t=r;t>=0?t>e:e>t;n=t>=0?++e:--e)i.push("  ");return i}().join(""),"opening->closing"===t?i=i.substr(0,i.length-1)+e+"\n":i+=s+e+"\n"},a=0,s=l.length;s>a;a++)u=l[a],n(u);return i},h=function(e,t,n,i){function r(e,t,i){var r,a=t;return e.$ref?(a=e.title||u(e.$ref),r=n[u(e.$ref)]):_.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,r={definition:e}),i!==!0&&(f[a]=_.isUndefined(r)?{}:r.definition),a}function a(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=r(e,u(e.$ref)):"object"===n?t+=_.isUndefined(e.properties)?"object":r(e):"array"===n?(t+="Array[",_.isArray(e.items)?t+=_.map(e.items,r).join(","):_.isPlainObject(e.items)?t+=_.isUndefined(e.items.$ref)?_.isUndefined(e.items.type)||-1!==_.indexOf(["array","object"],e.items.type)?r(e.items):e.items.type:r(e.items,u(e.items.$ref)):(console.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function o(e,t){var n="",i=e.type||"object",r="array"===i;switch(r&&(i=_.isPlainObject(e.items)&&!_.isUndefined(e.items.type)?e.items.type:"object"),_.isUndefined(e["default"])||(n+=h("Default",e["default"])),i){case"string":e.minLength&&(n+=h("Min. Length",e.minLength)),e.maxLength&&(n+=h("Max. Length",e.maxLength)),e.pattern&&(n+=h("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=h("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=h("Exclusive Min.","true")),e.maximum&&(n+=h("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=h("Exclusive Max.","true")),e.multipleOf&&(n+=h("Multiple Of",e.multipleOf))}if(r&&(e.minItems&&(n+=h("Min. Items",e.minItems)),e.maxItems&&(n+=h("Max. Items",e.maxItems)),e.uniqueItems&&(n+=h("Unique Items","true")),e.collectionFormat&&(n+=h("Coll. Format",e.collectionFormat))),_.isUndefined(e.items)&&_.isArray(e["enum"])){var a;a="number"===i||"integer"===i?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=h("Enum",a)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+i+"</th></tr>"+n+"</table></span>"),t}function s(e,t){var s,h=e.type||"object",f="array"===e.type,m=c+t+" "+(f?"[":"{")+p;return t&&d.push(t),f?_.isArray(e.items)?m+="<div>"+_.map(e.items,function(e){var t=e.type||"object";return _.isUndefined(e.$ref)?_.indexOf(["array","object"],t)>-1?"object"===t&&_.isUndefined(e.properties)?"object":r(e):o(e,t):r(e,u(e.$ref))}).join(",</div><div>"):_.isPlainObject(e.items)?m+=_.isUndefined(e.items.$ref)?_.indexOf(["array","object"],e.items.type||"object")>-1?(_.isUndefined(e.items.type)||"object"===e.items.type)&&_.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+r(e.items)+"</div>":"<div>"+o(e.items,e.items.type)+"</div>":"<div>"+r(e.items,u(e.items.$ref))+"</div>":(console.log("Array type's 'items' property is not an array or an object, cannot process"),m+="<div>object</div>"):e.$ref?m+="<div>"+r(e,t)+"</div>":"object"===h?(_.isPlainObject(e.properties)&&(s=_.map(e.properties,function(t,r){var s,c,p=_.indexOf(e.required,r)>=0,h=_.cloneDeep(t),f=p?"required":"",d='<span class="propName '+f+'">'+r+"</span> (";return h["default"]=i(h),h=l(h),c=t.description||h.description,_.isUndefined(h.$ref)||(s=n[u(h.$ref)],_.isUndefined(s)||-1!==_.indexOf([void 0,"array","object"],s.definition.type)||(h=l(s.definition))),d+=a(h),p||(d+=', <span class="propOptKey">optional</span>'),t.readOnly&&(d+=', <span class="propReadOnly">read only</span>'),d+=")",_.isUndefined(c)||(d+=': <span class="propDesc">'+c+"</span>"),h["enum"]&&(d+=' = <span class="propVals">[\''+h["enum"].join("', '")+"']</span>"),"<div"+(t.readOnly?' class="readOnly"':"")+">"+o(h,d)}).join(",</div>")),s&&(m+=s+"</div>")):m+="<div>"+o(e,h)+"</div>",m+c+(f?"]":"}")+p}var c='<span class="strong">',p="</span>",h=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};if(_.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],i=arguments[2]),n=n||{},t=l(t),_.isEmpty(t))return c+"Empty"+p;if("string"==typeof t.$ref&&(e=u(t.$ref),t=n[e],"undefined"==typeof t))return c+e+" is not defined!"+p;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof i&&(i=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=s(t,e);_.keys(f).length>0;)_.forEach(f,function(e,t){var n=_.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+s(e,t))});return g},f=function(e,t,n,i){e=l(e),"function"!=typeof i&&(i=function(e){return(e||{})["default"]}),n=n||{};var r,a,o=e.type||"object",s=e.format;return _.isUndefined(e.example)?_.isUndefined(e.items)&&_.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,_.isUndefined(a)&&(e.$ref?(r=t[u(e.$ref)],_.isUndefined(r)||(_.isUndefined(n[r.name])?(n[r.name]=r,a=f(r.definition,t,n,i),delete n[r.name]):a="array"===r.type?[]:{})):_.isUndefined(e["default"])?"string"===o?a="date-time"===s?(new Date).toISOString():"date"===s?(new Date).toISOString().split("T")[0]:"string":"integer"===o?a=0:"number"===o?a=0:"boolean"===o?a=!0:"object"===o?(a={},_.forEach(e.properties,function(e,r){var o=_.cloneDeep(e);o["default"]=i(e),a[r]=f(o,t,n,i)})):"array"===o&&(a=[],_.isArray(e.items)?_.forEach(e.items,function(e){a.push(f(e,t,n,i))}):_.isPlainObject(e.items)?a.push(f(e.items,t,n,i)):_.isUndefined(e.items)?a.push({}):console.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a},d=function(e,t){return t=t||{},t[e.name]=e,e.examples&&_.isPlainObject(e.examples)&&e.examples["application/json"]?(e.definition.example=e.examples["application/json"],_.isString(e.definition.example)&&(e.definition.example=jsyaml.safeLoad(e.definition.example))):e.definition.example||(e.definition.example=e.examples),f(e.definition,e.models,t,e.modelPropertyMacro)},m=function(e,t){var n,i;return e instanceof Array&&(i=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):c(e)?(e=c(e),n=!1):n=!0,n?i?"Array["+e+"]":e.toString():i?"Array["+h(e.name,e.definition,e.models,e.modelPropertyMacro)+"]":h(e.name,e.definition,e.models,e.modelPropertyMacro)},g=function(e,t){var n,i,r;if(t=t||{},n=e instanceof Array,r=n?e[0]:e,t[r]?i=d(t[r]):c(r)&&(i=d(c(r))),i){if(i=n?[i]:i,"string"==typeof i)return i;if(_.isObject(i)){var a=i;if(i instanceof Array&&i.length>0&&(a=i[0]),a.nodeName&&"Node"==typeof a){var o=(new XMLSerializer).serializeToString(a);return p(o)}return JSON.stringify(i,null,2)}return i}},y=function(e,t,i){var r,a;return i=i||[],a=i.map(function(e){return" "+e.name+'="'+e.value+'"'}).join(""),e?(r=["<",e,a,">",t,"</",e,">"],r.join("")):n("Node name is not provided")},v=function(e,t){var n=e||"";return t=t||{},t.name&&(n=t.name),t.prefix&&(n=t.prefix+":"+n),n},b=function(e){var t="",n="xmlns";return e=e||{},e.namespace?(t=e.namespace,e.prefix&&(n+=":"+e.prefix),{name:n,value:t}):t},w=function(e){var t,r=e.name,a=e.config,o=e.definition,s=e.models,l=o.items,u=o.xml||{};return l?(t=i(r,l,s,a),u=u||{},u.wrapped&&(t=y(r,t)),t):n()},x=function(e){var t,n;switch(e=e||{},n=e.items||{},t=e.type||""){case"object":return"Object is not a primitive";case"array":return"Array["+(n.format||n.type)+"]";default:return e.format||t}},A=function(e){var t,i=e.name,r=e.definition,a={string:{date:new Date(1).toISOString().split("T")[0],"date-time":new Date(1).toISOString(),"default":"string"},integer:{"default":1},number:{"default":1.1},"boolean":{"default":!0}},o=r.type,s=r.format,l=r.xml||{},u=b(l),c=[];return _.keys(a).indexOf(o)<0?n():(t=_.isArray(r["enum"])?r["enum"][0]:r.example||a[o][s]||a[o]["default"],l.attribute?{name:i,value:t}:(u&&c.push(u),y(i,t,c)))};return{getModelSignature:h,createJSONSample:d,getParameterModelSignature:m,createParameterJSONSample:g,createSchemaXML:i,createXMLSample:s,getPrimitiveSignature:x}}(),SwaggerUi.Views.PopupView=Backbone.View.extend({events:{"click .api-popup-cancel":"cancelClick"},template:Handlebars.templates.popup,className:"api-popup-dialog",selectors:{content:".api-popup-content",main:"#swagger-ui-container"},initialize:function(){this.$el.html(this.template(this.model))},render:function(){return this.$(this.selectors.content).append(this.model.content),$(this.selectors.main).first().append(this.el),this.showPopup(),this},showPopup:function(){this.$el.show()},cancelClick:function(){this.remove()}}),SwaggerUi.Views.ResourceView=Backbone.View.extend({initialize:function(e){e=e||{},this.router=e.router,this.auths=e.auths,""===this.model.description&&(this.model.description=null),this.model.description&&(this.model.summary=this.model.description)},render:function(){var e={};$(this.el).html(Handlebars.templates.resource(this.model));for(var t=0;t<this.model.operationsArray.length;t++){for(var n=this.model.operationsArray[t],i=0,r=n.nickname;"undefined"!=typeof e[r];)r=r+"_"+i,i+=1;e[r]=n,n.nickname=r,n.parentId=this.model.id,n.definitions=this.model.definitions,this.addOperation(n)}return $(".toggleEndpointList",this.el).click(this.callDocs.bind(this,"toggleEndpointListForResource")),$(".collapseResource",this.el).click(this.callDocs.bind(this,"collapseOperationsForResource")),$(".expandResource",this.el).click(this.callDocs.bind(this,"expandOperationsForResource")),this},addOperation:function(e){e.number=this.number;var t=new SwaggerUi.Views.OperationView({model:e,router:this.router,tagName:"li",className:"endpoint",swaggerOptions:this.options.swaggerOptions,auths:this.auths});$(".endpoints",$(this.el)).append(t.render().el),this.number++},callDocs:function(e,t){t.preventDefault(),Docs[e](t.currentTarget.getAttribute("data-id"))}}),SwaggerUi.Views.ResponseContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.responseContentTypeId="rct"+Math.random(),$(this.el).html(Handlebars.templates.response_content_type(this.model)),this}}),SwaggerUi.Views.SignatureView=Backbone.View.extend({events:{"click a.description-link":"switchToDescription","click a.snippet-link":"switchToSnippet","mousedown .snippet_json":"jsonSnippetMouseDown","mousedown .snippet_xml":"xmlSnippetMouseDown"},initialize:function(){},render:function(){return $(this.el).html(Handlebars.templates.signature(this.model)),"model"===this.model.defaultRendering?this.switchToDescription():this.switchToSnippet(),this},switchToDescription:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).hide(),$(".description",$(this.el)).show(),$(".description-link",$(this.el)).addClass("selected"),$(".snippet-link",$(this.el)).removeClass("selected")},switchToSnippet:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).show(),$(".description",$(this.el)).hide(),$(".snippet-link",$(this.el)).addClass("selected"),$(".description-link",$(this.el)).removeClass("selected")},snippetToTextArea:function(e){var t=$("textarea",$(this.el.parentNode.parentNode.parentNode));""!==$.trim(t.val())&&t.prop("placeholder")!==t.val()||(t.val(e),this.model.jsonEditor&&this.model.jsonEditor.isEnabled()&&this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)))},jsonSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleJSON))},xmlSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleXML))}}),SwaggerUi.Views.StatusCodeView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){var e,t,n=this.router.api.models[this.model.responseModel];return $(this.el).html(Handlebars.templates.status_code(this.model)),e=this.router.api.models.hasOwnProperty(this.model.responseModel)?{sampleJSON:JSON.stringify(SwaggerUi.partials.signature.createJSONSample(n),void 0,2),sampleXML:this.model.isXML?SwaggerUi.partials.signature.createXMLSample("",this.model.schema,this.router.api.models):!1,isParam:!1,signature:SwaggerUi.partials.signature.getModelSignature(this.model.responseModel,n,this.router.api.models),defaultRendering:this.model.defaultRendering}:{signature:SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)},t=new SwaggerUi.Views.SignatureView({model:e,tagName:"div"}),$(".model-signature",this.$el).append(t.render().el),this}})}).call(this);
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/index.html b/src/main/resources/META-INF/resources/index.html
new file mode 100644 (file)
index 0000000..282585f
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<html>
+  <head>
+    <title>camunda Tasklist</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta http-equiv="refresh" content="0;URL='/camunda/app/tasklist/'">
+  </head>
+  <body>
+
+  </body>
+</html>
diff --git a/src/main/resources/META-INF/resources/login.html b/src/main/resources/META-INF/resources/login.html
new file mode 100644 (file)
index 0000000..76cb7a6
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
+      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+    <head>
+        <title>CLDS</title>
+    </head>
+    <body>
+
+        <p th:case="${error}">Welcome to Clamp. Please login first.</p>
+
+        <form th:action="@{/login}" method="post">
+            <div><label> User Name : <input type="text" name="username"/> </label></div>
+            <div><label> Password: <input type="password" name="password"/> </label></div>
+            <div><input type="submit" value="Sign In"/></div>
+        </form>
+    </body>
+</html>
\ No newline at end of file
diff --git a/src/main/resources/META-INF/securityFilterRules.json b/src/main/resources/META-INF/securityFilterRules.json
new file mode 100644 (file)
index 0000000..b031537
--- /dev/null
@@ -0,0 +1,52 @@
+{
+  "pathFilter": {
+    "deniedPaths": [
+      {
+        "path": "/camunda/api/engine/.*",
+        "methods": "*"
+      },
+      {
+        "path": "/camunda/api/cockpit/.*",
+        "methods": "*"
+      },
+      {
+        "path": "/camunda/app/tasklist/{engine}/.*",
+        "methods": "*"
+      },
+      {
+        "path": "/camunda/app/cockpit/{engine}/.*",
+        "methods": "*"
+      }
+    ],
+    "allowedPaths": [
+      {
+        "path": "/camunda/api/engine/engine/",
+        "methods": "GET"
+      },
+      {
+        "path": "/camunda/api/{app:cockpit}/plugin/{engine}/static/.*",
+        "methods": "GET"
+      },
+      {
+        "path": "/camunda/api/{app:cockpit}/plugin/{plugin}/{engine}/.*",
+        "methods": "*",
+        "authorizer": "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer"
+      },
+      {
+        "path": "/camunda/api/engine/engine/{engine}/.*",
+        "methods": "*",
+        "authorizer": "org.camunda.bpm.webapp.impl.security.filter.EngineRequestAuthorizer"
+      },
+      {
+        "path": "/camunda/app/{app:cockpit}/{engine}/.*",
+        "methods": "*",
+        "authorizer": "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer"
+      },
+      {
+        "path": "/camunda/app/{app:tasklist}/{engine}/.*",
+        "methods": "*",
+        "authorizer": "org.camunda.bpm.webapp.impl.security.filter.ApplicationRequestAuthorizer"
+      }
+    ]
+  }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644 (file)
index 0000000..2f68096
--- /dev/null
@@ -0,0 +1,108 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+info.build.artifact=@project.artifactId@
+info.build.name=@project.name@
+info.build.description=@project.description@
+info.build.version=@project.version@
+
+
+server.contextPath=/
+#Modified engine-rest applicationpath
+spring.jersey.application-path=/engine-rest
+spring.profiles.active=clamp-default
+spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+
+#The max number of active threads in this pool
+server.tomcat.max-threads=200
+#The minimum number of threads always kept alive
+server.tomcat.min-Spare-Threads=25
+#The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less or equal to minSpareThreads
+server.tomcat.max-idle-time=60000
+
+
+#Add this properties only if you want to change the URL, AJSC Framework interceptors will intercept
+#com.att.ajsc.common.interceptors.PreInterceptor.url=/**
+#com.att.ajsc.common.interceptors.PostInterceptor.url=/**
+
+#Servlet context parameters
+server.context_parameters.p-name=value #context parameter with p-name as key and value as value.
+
+camel.springboot.consumer-template-cache-size=1000
+camel.springboot.producer-template-cache-size=1000
+camel.springboot.jmx-enabled=true
+camel.defaultthreadpool.poolsize=10
+camel.defaultthreadpool.maxpoolsize=20
+camel.defaultthreadpool.maxqueuesize=1000
+camel.defaultthreadpool.keepaliveTime=60
+camel.defaultthreadpool.rejectpolicy=CallerRuns
+
+kubernetes.namespace=com-att-ajsc
+
+#server.port=0
+
+#Camunda Process Engine DataSource connection Details
+spring.datasource.url=jdbc:mysql://localhost:${docker.mariadb.port.host}/camundabpm?verifyServerCertificate=false&useSSL=false&requireSSL=false&autoReconnect=true
+spring.datasource.username=camunda
+spring.datasource.password=ndMSpw4CAM
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+
+#Camunda application properties
+#Camunda history level
+camunda.bpm.history-level=auto
+
+#clds datasource connection details
+spring.cldsdatasource.driver-class-name=com.mysql.jdbc.Driver
+spring.cldsdatasource.url=jdbc:mysql://localhost:${docker.mariadb.port.host}/cldsdb4?verifyServerCertificate=false&useSSL=false&requireSSL=false&autoReconnect=true
+spring.cldsdatasource.username=clds
+spring.cldsdatasource.password=sidnnd83K
+spring.cldsdatasource.poolinitialsize=1
+spring.cldsdatasource.poolmaxactive=5
+spring.cldsdatasource.poolmaxwait=5000
+spring.cldsdatasource.pooltestonborrow=true
+spring.cldsdatasource.poolvalidationquery=SELECT 1
+spring.cldsdatasource.poolvalidationquerytimeout=5000
+
+#Async Executor default Parameters
+async.core.pool.size=10
+async.max.pool.size=20
+async.queue.capacity=500
+
+#CSI Logging Queue
+JMS_WMQ_PROVIDER_URL=aftdsc://AFTUAT/34.07/-84.28
+JMS_WMQ_CONNECTION_FACTORY_NAME=aftdsc://AFTUAT/?service=CSILOG,version=4.0,bindingType=fusionBus,envContext=Q,Q30A=YES
+JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME=com.att.aft.jms.FusionCtxFactory
+JMS_WMQ_AUDIT_DESTINATION_NAME=queue:///CSILOGQL.M2E.DASHBOARD01.NOT.Q30A
+JMS_WMQ_PERF_DESTINATION_NAME=queue:///CSILOGQL.M2E.PERFORMANCE01.NOT.Q30A
+csiEnable=true
+
+#GRM Edge endpoint details
+service.name=ajsc6camundademo
+service.version=1.0.0.0
+routeoffer=TEST
+#Update with your application name
+application.name=AJSC6CAMUNDA
+
+org.onap.clamp.config.files.cldsReference=classpath:/clds/clds-reference.properties
+org.onap.clamp.config.files.cldsPolicyConfig=classpath:/clds/clds-policy-config.properties
+org.onap.clamp.config.files.cldsUsers=classpath:/clds/clds-users.properties
diff --git a/src/main/resources/bootstrap.properties b/src/main/resources/bootstrap.properties
new file mode 100644 (file)
index 0000000..b0cfde5
--- /dev/null
@@ -0,0 +1,34 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+spring.cloud.config.discovery.enabled=false
+spring.cloud.config.enabled=false
+
+# Allow Spring Cloud properties configuration to override properties set from System Properties and ENV Properties
+spring.cloud.config.overrideSystemProperties=true
+
+# Path to the file containing the dynamic logger levels
+com.att.ajsc.dynamic.logging.path=./logging.properties
+
+# File watcher polling frequency in milliseconds
+com.att.ajsc.dynamic.watcher.delay=5000
diff --git a/src/main/resources/bpmn/SampleTestProcessDelegate.bpmn b/src/main/resources/bpmn/SampleTestProcessDelegate.bpmn
new file mode 100644 (file)
index 0000000..41ffdb6
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_7-gSIF09EeWE96cFqGLI8w" exporter="camunda modeler" exporterVersion="2.7.0" targetNamespace="http://camunda.org/schema/1.0/bpmn">
+  <bpmn2:process id="SampleTestProcessDeleagate-wf" name="SampleTestProcessDeleagate-wf" isExecutable="true">
+    <bpmn2:startEvent id="StartEcho" name="StartEvent">
+      <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:serviceTask id="ServiceTask_1" camunda:class="com.att.ajsc.clds.designer.workflow.PublishMessageDelegate" name="Perform ">
+      <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_1</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="StartEcho" targetRef="ServiceTask_1"/>
+    <bpmn2:sequenceFlow id="SequenceFlow_1" name="" sourceRef="ServiceTask_1" targetRef="UserTask_1"/>
+    <bpmn2:userTask id="UserTask_1" camunda:assignee="bharath" name="HumanTask1">
+      <bpmn2:incoming>SequenceFlow_1</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="UserTask_1" targetRef="ServiceTask_3"/>
+    <bpmn2:serviceTask id="ServiceTask_3" camunda:class="com.att.ajsc.clds.designer.workflow.ConsumeMessageDelegate" name="AddServiceTask3">
+      <bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ServiceTask_3" targetRef="EndEvent_1"/>
+    <bpmn2:endEvent id="EndEvent_1" name="Endevent">
+      <bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
+    </bpmn2:endEvent>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="SampleTestProcessDeleagate-wf">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEcho">
+        <dc:Bounds height="36.0" width="36.0" x="191.0" y="253.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_4" bpmnElement="ServiceTask_1">
+        <dc:Bounds height="80.0" width="100.0" x="277.0" y="231.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_StartEvent_3" targetElement="_BPMNShape_ServiceTask_4">
+        <di:waypoint xsi:type="dc:Point" x="227.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="277.0" y="271.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_103" bpmnElement="EndEvent_1">
+        <dc:Bounds height="36.0" width="36.0" x="955.0" y="253.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="25.0" width="73.0" x="938.0" y="294.0"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_6" bpmnElement="ServiceTask_3">
+        <dc:Bounds height="80.0" width="100.0" x="497.0" y="454.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_ServiceTask_6" targetElement="_BPMNShape_EndEvent_103">
+        <di:waypoint xsi:type="dc:Point" x="597.0" y="494.0"/>
+        <di:waypoint xsi:type="dc:Point" x="918.0" y="494.0"/>
+        <di:waypoint xsi:type="dc:Point" x="918.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="955.0" y="271.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="6.0" width="6.0" x="915.0" y="271.0"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_UserTask_2" bpmnElement="UserTask_1">
+        <dc:Bounds height="80.0" width="100.0" x="630.0" y="117.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_6" sourceElement="_BPMNShape_UserTask_2" targetElement="_BPMNShape_ServiceTask_6">
+        <di:waypoint xsi:type="dc:Point" x="730.0" y="187.0"/>
+        <di:waypoint xsi:type="dc:Point" x="730.0" y="494.0"/>
+        <di:waypoint xsi:type="dc:Point" x="597.0" y="494.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="6.0" width="6.0" x="701.0" y="271.0"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="_BPMNShape_ServiceTask_4" targetElement="_BPMNShape_UserTask_2">
+        <di:waypoint xsi:type="dc:Point" x="377.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="436.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="436.0" y="157.0"/>
+        <di:waypoint xsi:type="dc:Point" x="630.0" y="157.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="6.0" width="6.0" x="457.0" y="271.0"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git a/src/main/resources/bpmn/TestHumanTask.bpmn b/src/main/resources/bpmn/TestHumanTask.bpmn
new file mode 100644 (file)
index 0000000..d456d65
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_7-gSIF09EeWE96cFqGLI8w" exporter="camunda modeler" exporterVersion="2.7.0" targetNamespace="http://bpmn.io/schema/bpmn">
+  <bpmn2:process id="user-interact-wf" name="UserInteract" isExecutable="true">
+    <bpmn2:startEvent id="StartEcho" camunda:formKey="embedded:app:forms/example-embedded-start-TestHumanTask.html" name="StartEvent">
+      <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:serviceTask id="ServiceTask_1" camunda:class="com.att.ajsc.clds.designer.workflow.LogMessageDelegate" name="Perform Echo Assignment">
+      <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="StartEcho" targetRef="ServiceTask_1"/>
+    <bpmn2:endEvent id="EndEvent_1" name="Endevent">
+      <bpmn2:incoming>SequenceFlow_5</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:serviceTask id="ServiceTask_3" camunda:class="com.att.ajsc.clds.designer.workflow.LogMessageDelegate" name="AddServiceTask3">
+      <bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_5</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_5" name="" sourceRef="ServiceTask_3" targetRef="EndEvent_1"/>
+    <bpmn2:userTask id="UserTask_1" camunda:assignee="admin" camunda:formKey="embedded:app:forms/example-embedded-task-TestHumanTask.html" name="HumanTask1">
+      <bpmn2:incoming>SequenceFlow_027hi4f</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
+    </bpmn2:userTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_3" name="" sourceRef="ServiceTask_1" targetRef="BusinessRuleTask_1m53dly"/>
+    <bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="UserTask_1" targetRef="ServiceTask_3"/>
+    <bpmn2:businessRuleTask id="BusinessRuleTask_1m53dly" camunda:resultVariable="result" camunda:decisionRef="simpleDishDecisionTable" camunda:mapDecisionResult="singleResult" name="BusinessRuleTask">
+      <bpmn2:incoming>SequenceFlow_3</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_027hi4f</bpmn2:outgoing>
+    </bpmn2:businessRuleTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_027hi4f" sourceRef="BusinessRuleTask_1m53dly" targetRef="UserTask_1"/>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="user-interact-wf">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEcho">
+        <dc:Bounds height="36.0" width="36.0" x="191.0" y="253.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_4" bpmnElement="ServiceTask_1">
+        <dc:Bounds height="80.0" width="100.0" x="277.0" y="231.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_StartEvent_3" targetElement="_BPMNShape_ServiceTask_4">
+        <di:waypoint xsi:type="dc:Point" x="227.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="277.0" y="271.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_103" bpmnElement="EndEvent_1">
+        <dc:Bounds height="36.0" width="36.0" x="1182.0" y="253.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="25.0" width="90.0" x="1156.0" y="294.0"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_6" bpmnElement="ServiceTask_3">
+        <dc:Bounds height="80.0" width="100.0" x="923.0" y="231.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_5" bpmnElement="SequenceFlow_5" sourceElement="_BPMNShape_ServiceTask_6" targetElement="_BPMNShape_EndEvent_103">
+        <di:waypoint xsi:type="dc:Point" x="1026.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="1182.0" y="271.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_UserTask_2" bpmnElement="UserTask_1">
+        <dc:Bounds height="80.0" width="100.0" x="719.0" y="231.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="SequenceFlow_3" sourceElement="_BPMNShape_ServiceTask_4" targetElement="_BPMNShape_UserTask_2">
+        <di:waypoint xsi:type="dc:Point" x="377.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="492.0" y="271.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_6" bpmnElement="SequenceFlow_6" sourceElement="_BPMNShape_UserTask_2" targetElement="_BPMNShape_ServiceTask_6">
+        <di:waypoint xsi:type="dc:Point" x="819.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="923.0" y="271.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="BusinessRuleTask_1m53dly_di" bpmnElement="BusinessRuleTask_1m53dly">
+        <dc:Bounds height="80.0" width="100.0" x="492.0" y="231.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_027hi4f_di" bpmnElement="SequenceFlow_027hi4f">
+        <di:waypoint xsi:type="dc:Point" x="592.0" y="271.0"/>
+        <di:waypoint xsi:type="dc:Point" x="719.0" y="271.0"/>
+        <bpmndi:BPMNLabel>
+          <dc:Bounds height="20.0" width="90.0" x="830.0" y="325.5"/>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
\ No newline at end of file
diff --git a/src/main/resources/bpmn/TestHumanTask.png b/src/main/resources/bpmn/TestHumanTask.png
new file mode 100644 (file)
index 0000000..7d8af39
Binary files /dev/null and b/src/main/resources/bpmn/TestHumanTask.png differ
diff --git a/src/main/resources/bpmn/clds-process-action.bpmn b/src/main/resources/bpmn/clds-process-action.bpmn
new file mode 100644 (file)
index 0000000..eb28ea3
--- /dev/null
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_-A31MBMpEea185sFktMJ7Q" targetNamespace="http://camunda.org/schema/1.0/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.2" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
+  <bpmn2:collaboration id="_Collaboration_2">
+    <bpmn2:participant id="_Participant_2" name="Process Action" processRef="clds-process-action-wf" />
+  </bpmn2:collaboration>
+  <bpmn2:process id="clds-process-action-wf" name="CLDS Process Action Workflow" isExecutable="true">
+    <bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
+      <bpmn2:lane id="Lane_1" name="Submit or Resubmit">
+        <bpmn2:flowNodeRef>ExclusiveGateway_2</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>EndEvent_1</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>insEvent</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>ExclusiveGateway_3</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendOpPolicyReqDistribute</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>StartEvent_1</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>ServiceTask_0x8ypxf</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendStringMatchingReqDistribute</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendTcaReqDistribute</bpmn2:flowNodeRef>
+      </bpmn2:lane>
+      <bpmn2:lane id="Lane_5" name="Delete">
+        <bpmn2:flowNodeRef>sendStringMatchingReqDelete</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendOpPolicyReqDelete</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendTcaReqDelete</bpmn2:flowNodeRef>
+      </bpmn2:lane>
+      <bpmn2:lane id="Lane_4" name="Update">
+        <bpmn2:flowNodeRef>sendOpPolicyReqUpdate</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendStringMatchingReqUpdate</bpmn2:flowNodeRef>
+        <bpmn2:flowNodeRef>sendTcaReqUpdate</bpmn2:flowNodeRef>
+      </bpmn2:lane>
+      <bpmn2:lane id="Lane_6" name="Stop">
+        <bpmn2:flowNodeRef>sendOpPolicyReqStop</bpmn2:flowNodeRef>
+      </bpmn2:lane>
+      <bpmn2:lane id="Lane_7" name="Restart">
+        <bpmn2:flowNodeRef>sendOpPolicyReqRestart</bpmn2:flowNodeRef>
+      </bpmn2:lane>
+    </bpmn2:laneSet>
+    <bpmn2:exclusiveGateway id="ExclusiveGateway_2">
+      <bpmn2:incoming>SequenceFlow_2</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_4</bpmn2:outgoing>
+      <bpmn2:outgoing>SequenceFlow_27</bpmn2:outgoing>
+      <bpmn2:outgoing>SequenceFlow_29</bpmn2:outgoing>
+      <bpmn2:outgoing>SequenceFlow_31</bpmn2:outgoing>
+      <bpmn2:outgoing>SequenceFlow_15</bpmn2:outgoing>
+      <bpmn2:outgoing>SequenceFlow_1xlfq66</bpmn2:outgoing>
+    </bpmn2:exclusiveGateway>
+    <bpmn2:sequenceFlow id="SequenceFlow_4" name="" sourceRef="ExclusiveGateway_2" targetRef="ServiceTask_0x8ypxf">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'SUBMIT' || actionCd == 'RESUBMIT' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:endEvent id="EndEvent_1">
+      <bpmn2:incoming>SequenceFlow_16</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:serviceTask id="insEvent" name="Insert Event to indicate that the action was completed" camunda:delegateExpression="${cldsEventDelegate}">
+      <bpmn2:extensionElements>
+        <camunda:inputOutput>
+          <camunda:inputParameter name="actionStateCd">SENT</camunda:inputParameter>
+        </camunda:inputOutput>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>SequenceFlow_7</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_16</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_16" name="" sourceRef="insEvent" targetRef="EndEvent_1" />
+    <bpmn2:exclusiveGateway id="ExclusiveGateway_3">
+      <bpmn2:incoming>SequenceFlow_10</bpmn2:incoming>
+      <bpmn2:incoming>SequenceFlow_28</bpmn2:incoming>
+      <bpmn2:incoming>SequenceFlow_30</bpmn2:incoming>
+      <bpmn2:incoming>SequenceFlow_32</bpmn2:incoming>
+      <bpmn2:incoming>SequenceFlow_6</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_7</bpmn2:outgoing>
+    </bpmn2:exclusiveGateway>
+    <bpmn2:sequenceFlow id="SequenceFlow_7" name="" sourceRef="ExclusiveGateway_3" targetRef="insEvent" />
+    <bpmn2:sequenceFlow id="SequenceFlow_14" name="" sourceRef="sendStringMatchingReqDistribute" targetRef="sendTcaReqDistribute" />
+    <bpmn2:serviceTask id="sendOpPolicyReqDistribute" name="Send Operation Policy Request [Submit]" camunda:delegateExpression="${operationalPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_1rga27p</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_10</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_10" name="" sourceRef="sendOpPolicyReqDistribute" targetRef="ExclusiveGateway_3" />
+    <bpmn2:serviceTask id="sendOpPolicyReqUpdate" name="Send Operation Policy Request [Update]" camunda:delegateExpression="${operationalPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_1kegg6u</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_28</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_26" name="" sourceRef="sendStringMatchingReqUpdate" targetRef="sendTcaReqUpdate" />
+    <bpmn2:sequenceFlow id="SequenceFlow_27" name="" sourceRef="ExclusiveGateway_2" targetRef="sendStringMatchingReqUpdate">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'UPDATE' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:sequenceFlow id="SequenceFlow_28" name="" sourceRef="sendOpPolicyReqUpdate" targetRef="ExclusiveGateway_3" />
+    <bpmn2:serviceTask id="sendOpPolicyReqStop" name="Send Operation Policy Request [Stop]" camunda:delegateExpression="${operationalPolicyDeleteDelegate}">
+      <bpmn2:incoming>SequenceFlow_29</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_30</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_29" name="" sourceRef="ExclusiveGateway_2" targetRef="sendOpPolicyReqStop">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'STOP' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:sequenceFlow id="SequenceFlow_30" name="" sourceRef="sendOpPolicyReqStop" targetRef="ExclusiveGateway_3" />
+    <bpmn2:serviceTask id="sendOpPolicyReqRestart" name="Send Operation Policy Request [Restart]" camunda:delegateExpression="${operationalPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_31</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_32</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_31" name="" sourceRef="ExclusiveGateway_2" targetRef="sendOpPolicyReqRestart">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'RESTART' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:sequenceFlow id="SequenceFlow_32" name="" sourceRef="sendOpPolicyReqRestart" targetRef="ExclusiveGateway_3" />
+    <bpmn2:startEvent id="StartEvent_1">
+      <bpmn2:outgoing>SequenceFlow_2</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:sequenceFlow id="SequenceFlow_2" name="" sourceRef="StartEvent_1" targetRef="ExclusiveGateway_2" />
+    <bpmn2:serviceTask id="sendStringMatchingReqDelete" name="Send String Match Micro Service request to Policy [Delete]" camunda:delegateExpression="${stringMatchPolicyDeleteDelegate}">
+      <bpmn2:incoming>SequenceFlow_15</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_23</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_23" name="" sourceRef="sendStringMatchingReqDelete" targetRef="sendTcaReqDelete" />
+    <bpmn2:sequenceFlow id="SequenceFlow_6" name="" sourceRef="sendOpPolicyReqDelete" targetRef="ExclusiveGateway_3" />
+    <bpmn2:sequenceFlow id="SequenceFlow_15" name="" sourceRef="ExclusiveGateway_2" targetRef="sendStringMatchingReqDelete">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'DELETE' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:sequenceFlow id="SequenceFlow_0w39hon" sourceRef="ServiceTask_0x8ypxf" targetRef="sendStringMatchingReqDistribute" />
+    <bpmn2:sequenceFlow id="SequenceFlow_1xlfq66" sourceRef="ExclusiveGateway_2" targetRef="ServiceTask_0x8ypxf">
+      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression"><![CDATA[${ actionCd == 'SUBMIT' || actionCd == 'RESUBMIT' }]]></bpmn2:conditionExpression>
+    </bpmn2:sequenceFlow>
+    <bpmn2:serviceTask id="ServiceTask_0x8ypxf" name="Send to SDC [Submit]" camunda:delegateExpression="${sdcSendReqDelegate}">
+      <bpmn2:incoming>SequenceFlow_4</bpmn2:incoming>
+      <bpmn2:incoming>SequenceFlow_1xlfq66</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_0w39hon</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:serviceTask id="sendStringMatchingReqDistribute" name="Send String Match Micro Service request to Policy [Submit]" camunda:delegateExpression="${stringMatchPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_0w39hon</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_14</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_1rga27p" sourceRef="sendTcaReqDistribute" targetRef="sendOpPolicyReqDistribute" />
+    <bpmn2:serviceTask id="sendTcaReqDistribute" name="Send Tca Micro Service request to Policy [Submit]" camunda:delegateExpression="${tcaPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_14</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_1rga27p</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:serviceTask id="sendOpPolicyReqDelete" name="Send Operation Policy Request [Delete]" camunda:delegateExpression="${operationalPolicyDeleteDelegate}">
+      <bpmn2:incoming>SequenceFlow_0tpegxf</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_6</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_0tpegxf" sourceRef="sendTcaReqDelete" targetRef="sendOpPolicyReqDelete" />
+    <bpmn2:serviceTask id="sendTcaReqDelete" name="Send Tca Micro Service request to Policy [Delete]" camunda:delegateExpression="${tcaPolicyDeleteDelegate}">
+      <bpmn2:incoming>SequenceFlow_23</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_0tpegxf</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:serviceTask id="sendStringMatchingReqUpdate" name="Send String Match Micro Service request to Policy [Update]" camunda:delegateExpression="${stringMatchPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_27</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_26</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+    <bpmn2:sequenceFlow id="SequenceFlow_1kegg6u" sourceRef="sendTcaReqUpdate" targetRef="sendOpPolicyReqUpdate" />
+    <bpmn2:serviceTask id="sendTcaReqUpdate" name="Send Tca Micro Service request to Policy [Update]" camunda:delegateExpression="${tcaPolicyDelegate}">
+      <bpmn2:incoming>SequenceFlow_26</bpmn2:incoming>
+      <bpmn2:outgoing>SequenceFlow_1kegg6u</bpmn2:outgoing>
+    </bpmn2:serviceTask>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_4" bpmnElement="StartEvent_1">
+        <dc:Bounds x="72" y="220" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="90" y="261" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_EndEvent_104" bpmnElement="EndEvent_1">
+        <dc:Bounds x="1320" y="216" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1338" y="257" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ScriptTask_8" bpmnElement="sendStringMatchingReqDistribute">
+        <dc:Bounds x="615" y="89" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_6" bpmnElement="sendOpPolicyReqDistribute">
+        <dc:Bounds x="912" y="89" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_14" bpmnElement="SequenceFlow_14" sourceElement="_BPMNShape_ScriptTask_8" targetElement="_BPMNShape_ServiceTask_6">
+        <di:waypoint xsi:type="dc:Point" x="715" y="129" />
+        <di:waypoint xsi:type="dc:Point" x="761" y="129" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="881" y="192" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_7" bpmnElement="insEvent">
+        <dc:Bounds x="1188" y="194" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_16" bpmnElement="SequenceFlow_16" sourceElement="_BPMNShape_ServiceTask_7" targetElement="_BPMNShape_EndEvent_104">
+        <di:waypoint xsi:type="dc:Point" x="1288" y="234" />
+        <di:waypoint xsi:type="dc:Point" x="1320" y="234" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1295" y="234" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_Participant_2" bpmnElement="_Participant_2" isHorizontal="true">
+        <dc:Bounds x="0" y="0" width="1369" height="833" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_Lane_2" bpmnElement="Lane_1" isHorizontal="true">
+        <dc:Bounds x="30" y="0" width="1339" height="289" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_Lane_6" bpmnElement="Lane_5" isHorizontal="true">
+        <dc:Bounds x="30" y="288" width="1339" height="197" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_3" bpmnElement="ExclusiveGateway_2" isMarkerVisible="true">
+        <dc:Bounds x="144" y="212" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="169" y="267" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="SequenceFlow_2" sourceElement="_BPMNShape_StartEvent_4" targetElement="_BPMNShape_ExclusiveGateway_3">
+        <di:waypoint xsi:type="dc:Point" x="108" y="238" />
+        <di:waypoint xsi:type="dc:Point" x="126" y="238" />
+        <di:waypoint xsi:type="dc:Point" x="126" y="237" />
+        <di:waypoint xsi:type="dc:Point" x="144" y="237" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="128" y="237" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_4" bpmnElement="ExclusiveGateway_3" isMarkerVisible="true">
+        <dc:Bounds x="1104" y="208" width="50" height="50" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1129" y="263" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_7" bpmnElement="SequenceFlow_7" sourceElement="_BPMNShape_ExclusiveGateway_4" targetElement="_BPMNShape_ServiceTask_7">
+        <di:waypoint xsi:type="dc:Point" x="1154" y="233" />
+        <di:waypoint xsi:type="dc:Point" x="1188" y="234" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1175" y="234" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_10" bpmnElement="SequenceFlow_10" sourceElement="_BPMNShape_ServiceTask_6" targetElement="_BPMNShape_ExclusiveGateway_4">
+        <di:waypoint xsi:type="dc:Point" x="1012" y="127" />
+        <di:waypoint xsi:type="dc:Point" x="1052" y="125" />
+        <di:waypoint xsi:type="dc:Point" x="1052" y="229" />
+        <di:waypoint xsi:type="dc:Point" x="1104" y="232" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1049" y="192" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_11" bpmnElement="sendStringMatchingReqDelete">
+        <dc:Bounds x="348" y="385" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_12" bpmnElement="sendOpPolicyReqDelete">
+        <dc:Bounds x="645" y="385" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_23" bpmnElement="SequenceFlow_23" sourceElement="_BPMNShape_ServiceTask_11" targetElement="_BPMNShape_ServiceTask_12">
+        <di:waypoint xsi:type="dc:Point" x="448" y="425" />
+        <di:waypoint xsi:type="dc:Point" x="496" y="425" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="467" y="425" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_Lane_9" bpmnElement="Lane_4" isHorizontal="true">
+        <dc:Bounds x="30" y="484" width="1339" height="117" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_14" bpmnElement="sendStringMatchingReqUpdate">
+        <dc:Bounds x="615" y="500" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_15" bpmnElement="sendOpPolicyReqUpdate">
+        <dc:Bounds x="912" y="500" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_26" bpmnElement="SequenceFlow_26" sourceElement="_BPMNShape_ServiceTask_14" targetElement="_BPMNShape_ServiceTask_15">
+        <di:waypoint xsi:type="dc:Point" x="715" y="540" />
+        <di:waypoint xsi:type="dc:Point" x="761" y="540" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="887" y="540" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_27" bpmnElement="SequenceFlow_27" sourceElement="_BPMNShape_ExclusiveGateway_3" targetElement="_BPMNShape_ServiceTask_14">
+        <di:waypoint xsi:type="dc:Point" x="169" y="262" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="540" />
+        <di:waypoint xsi:type="dc:Point" x="615" y="540" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="139" y="398" width="90" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_28" bpmnElement="SequenceFlow_28" sourceElement="_BPMNShape_ServiceTask_15" targetElement="_BPMNShape_ExclusiveGateway_4">
+        <di:waypoint xsi:type="dc:Point" x="1012" y="539" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="538" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="230" />
+        <di:waypoint xsi:type="dc:Point" x="1104" y="232" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1055" y="381" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_Lane_10" bpmnElement="Lane_6" isHorizontal="true">
+        <dc:Bounds x="30" y="600" width="1339" height="117" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_16" bpmnElement="sendOpPolicyReqStop">
+        <dc:Bounds x="912" y="619" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_29" bpmnElement="SequenceFlow_29" sourceElement="_BPMNShape_ExclusiveGateway_3" targetElement="_BPMNShape_ServiceTask_16">
+        <di:waypoint xsi:type="dc:Point" x="169" y="262" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="659" />
+        <di:waypoint xsi:type="dc:Point" x="912" y="659" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="139" y="457.5" width="90" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_30" bpmnElement="SequenceFlow_30" sourceElement="_BPMNShape_ServiceTask_16" targetElement="_BPMNShape_ExclusiveGateway_4">
+        <di:waypoint xsi:type="dc:Point" x="1012" y="658" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="658" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="233" />
+        <di:waypoint xsi:type="dc:Point" x="1104" y="233" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1055" y="441" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="_BPMNShape_Lane_11" bpmnElement="Lane_7" isHorizontal="true">
+        <dc:Bounds x="30" y="716" width="1339" height="117" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="_BPMNShape_ServiceTask_17" bpmnElement="sendOpPolicyReqRestart">
+        <dc:Bounds x="912" y="735" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_31" bpmnElement="SequenceFlow_31" sourceElement="_BPMNShape_ExclusiveGateway_3" targetElement="_BPMNShape_ServiceTask_17">
+        <di:waypoint xsi:type="dc:Point" x="169" y="262" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="775" />
+        <di:waypoint xsi:type="dc:Point" x="912" y="775" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="139" y="515.5" width="90" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_32" bpmnElement="SequenceFlow_32" sourceElement="_BPMNShape_ServiceTask_17" targetElement="_BPMNShape_ExclusiveGateway_4">
+        <di:waypoint xsi:type="dc:Point" x="1012" y="775" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="775" />
+        <di:waypoint xsi:type="dc:Point" x="1058" y="232" />
+        <di:waypoint xsi:type="dc:Point" x="1104" y="233" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="1055" y="500" width="6" height="6" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_15" bpmnElement="SequenceFlow_15" sourceElement="_BPMNShape_ExclusiveGateway_3" targetElement="_BPMNShape_ServiceTask_11">
+        <di:waypoint xsi:type="dc:Point" x="169" y="262" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="425" />
+        <di:waypoint xsi:type="dc:Point" x="348" y="425" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="139" y="333.5" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_0x8ypxf_di" bpmnElement="ServiceTask_0x8ypxf">
+        <dc:Bounds x="204" y="89" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0w39hon_di" bpmnElement="SequenceFlow_0w39hon">
+        <di:waypoint xsi:type="dc:Point" x="304" y="129" />
+        <di:waypoint xsi:type="dc:Point" x="615" y="129" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="414.5" y="114" width="90" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1xlfq66_di" bpmnElement="SequenceFlow_1xlfq66">
+        <di:waypoint xsi:type="dc:Point" x="169" y="212" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="129" />
+        <di:waypoint xsi:type="dc:Point" x="204" y="129" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="184" y="170.5" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_1rga27p_di" bpmnElement="SequenceFlow_1rga27p">
+        <di:waypoint xsi:type="dc:Point" x="861" y="129" />
+        <di:waypoint xsi:type="dc:Point" x="912" y="129" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="841.5" y="119" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_1r1brt6_di" bpmnElement="sendTcaReqDistribute">
+        <dc:Bounds x="760.715" y="89" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0tpegxf_di" bpmnElement="SequenceFlow_0tpegxf">
+        <di:waypoint xsi:type="dc:Point" x="596" y="425" />
+        <di:waypoint xsi:type="dc:Point" x="645" y="425" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="575.5" y="415" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_0y2gwy4_di" bpmnElement="sendTcaReqDelete">
+        <dc:Bounds x="495.71500000000003" y="385" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_1kegg6u_di" bpmnElement="SequenceFlow_1kegg6u">
+        <di:waypoint xsi:type="dc:Point" x="861" y="540" />
+        <di:waypoint xsi:type="dc:Point" x="912" y="540" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="841.5" y="530" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_08pqhb3_di" bpmnElement="sendTcaReqUpdate">
+        <dc:Bounds x="761" y="500" width="100" height="80" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn2:definitions>
diff --git a/src/main/resources/bpmn/dish.dmn b/src/main/resources/bpmn/dish.dmn
new file mode 100644 (file)
index 0000000..473a07a
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn11.xsd" id="definitions" name="definitions" namespace="http://camunda.org/schema/1.0/dmn">
+  <decision id="simpleDishDecisionTable" name="SimpleDishDecisionTable">
+    <decisionTable id="decisionTable">
+      <input id="input1" label="Season">
+        <inputExpression id="inputExpression1" typeRef="string">        <text>season</text>
+</inputExpression>
+      </input>
+      <output id="output1" label="Dish" name="desiredDish" typeRef="string" />
+      <rule id="row-72464069-3">
+        <inputEntry id="UnaryTests_0zmcdq6">        <text><![CDATA["Fall"]]></text>
+</inputEntry>
+        <outputEntry id="LiteralExpression_1ehb89n">        <text><![CDATA["Pad Thai"]]></text>
+</outputEntry>
+      </rule>
+      <rule id="row-72464069-4">
+        <inputEntry id="UnaryTests_0g5512k">        <text><![CDATA["Winter"]]></text>
+</inputEntry>
+        <outputEntry id="LiteralExpression_0v3t89p">        <text><![CDATA["Lamb Jalfrazie, Mutter Paneer, and Nan"]]></text>
+</outputEntry>
+      </rule>
+      <rule id="row-72464069-5">
+        <inputEntry id="UnaryTests_0582crg">        <text><![CDATA["Spring"]]></text>
+</inputEntry>
+        <outputEntry id="LiteralExpression_100afca">        <text><![CDATA["Chicken Moghlai, Baingan Bhartha, and Nan"]]></text>
+</outputEntry>
+      </rule>
+      <rule id="row-72464069-6">
+        <inputEntry id="UnaryTests_0fha0sl">        <text><![CDATA["Summer"]]></text>
+</inputEntry>
+        <outputEntry id="LiteralExpression_06dk8fw">        <text><![CDATA["Satay and Laab"]]></text>
+</outputEntry>
+      </rule>
+    </decisionTable>
+  </decision>
+</definitions>
diff --git a/src/main/resources/bpmn/log-message.bpmn b/src/main/resources/bpmn/log-message.bpmn
new file mode 100644 (file)
index 0000000..621e7e3
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.5.1">
+  <bpmn:process id="log-message-wf" name="Log Message Workflow" isExecutable="true">
+    <bpmn:startEvent id="StartEvent_1" name="Start">
+      <bpmn:outgoing>SequenceFlow_0k87nxp</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:endEvent id="EndEvent_0udg3bj" name="End">
+      <bpmn:incoming>SequenceFlow_0zjfjoh</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_0k87nxp" sourceRef="StartEvent_1" targetRef="Task_1q1b38a" />
+    <bpmn:sequenceFlow id="SequenceFlow_0zjfjoh" sourceRef="Task_1q1b38a" targetRef="EndEvent_0udg3bj" />
+    <bpmn:serviceTask id="Task_1q1b38a" name="Display Log Message" camunda:class="org.onap.clamp.clds.workflow.LogMessageDelegate">
+      <bpmn:incoming>SequenceFlow_0k87nxp</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0zjfjoh</bpmn:outgoing>
+    </bpmn:serviceTask>
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="log-message-wf">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="617" y="283" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="623" y="319" width="23" height="12" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_0udg3bj_di" bpmnElement="EndEvent_0udg3bj">
+        <dc:Bounds x="961" y="283" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="969" y="319" width="19" height="12" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0k87nxp_di" bpmnElement="SequenceFlow_0k87nxp">
+        <di:waypoint xsi:type="dc:Point" x="653" y="301" />
+        <di:waypoint xsi:type="dc:Point" x="758" y="301" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="706" y="286" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0zjfjoh_di" bpmnElement="SequenceFlow_0zjfjoh">
+        <di:waypoint xsi:type="dc:Point" x="858" y="301" />
+        <di:waypoint xsi:type="dc:Point" x="961" y="301" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="910" y="286" width="0" height="0" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape id="ServiceTask_1o14w9n_di" bpmnElement="Task_1q1b38a">
+        <dc:Bounds x="758" y="261" width="100" height="80" />
+      </bpmndi:BPMNShape>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/src/main/resources/bpmn/log-message.png b/src/main/resources/bpmn/log-message.png
new file mode 100644 (file)
index 0000000..fa7c756
Binary files /dev/null and b/src/main/resources/bpmn/log-message.png differ
diff --git a/src/main/resources/clds/clds-policy-config.properties b/src/main/resources/clds/clds-policy-config.properties
new file mode 100644 (file)
index 0000000..8b1d4b7
--- /dev/null
@@ -0,0 +1,14 @@
+# Configuration Settings for Policy Engine Components
+PDP_URL1=https://localhost:8081/pdp/ , testpdp, alpha123
+PDP_URL2=https://localhost:8081/pdp/ , testpdp, alpha456
+PAP_URL=https://localhost:8081/pap/ , testpap, alpha123
+NOTIFICATION_TYPE=websocket
+NOTIFICATION_UEB_SERVERS=localhost
+
+CLIENT_ID=myclientid
+# base64 encoding
+CLIENT_KEY=ChlakDuk
+#DEVL for development
+#TEST for Test environments
+#PROD for prod environments
+ENVIRONMENT=DEVL
\ No newline at end of file
diff --git a/src/main/resources/clds/clds-reference.properties b/src/main/resources/clds/clds-reference.properties
new file mode 100644 (file)
index 0000000..2626470
--- /dev/null
@@ -0,0 +1,78 @@
+# 
+# Poperties for CLDS
+#
+#
+# DCAE request build properties
+#
+dcae.template={"properties":{"service_name":"","service_ids":[],"vnf_ids":[],"location_ids":[]},"template":{"string_matching":{"dcae":{"inputTopic":"","outputTopic":"","closedLoopControlName":"","closedLoopEventClient":"configuration.dcae.microservice.stringmatcher.xml","policyName":"","policyScope":"service=vSCP;resource=F5;type=configuration","policyVersion":"v0.0.1","serviceConfigurations":{}}}}}
+dcae.decode.service_ids={"vUSP":["vUSP - vCTS"],"Trinity":["ASBGv TLS VNF","ASBGv No TLS","ASBGv (NO TLS) VNF","ASBGv TLS","NSBGv VNF","NSBGv"],"vSCP":["AKRON_vSCP_F5_FW-SVC/vSCP_F5_FW 1","ALLEN_vSCP_F5_FW-SVC/vSCP_F5_FW 1"],"vProbes":["vProbes - FW"]}
+#
+# ASDC request blueprint properties
+#
+asdc.template={}
+asdc.decode.service_ids={}
+# 
+#
+# General Policy request properties
+#
+policy.ecomp.name=DCAE
+policy.pdp.group=default
+policy.ms.type=MicroService
+policy.ms.policyNamePrefix=Config_MS_
+policy.op.type=BRMS_Param
+policy.op.policyNamePrefix=Config_BRMS_Param_
+#
+# TCA MicroService Policy request build properties
+#
+tca.template={"service":"MThresholdCrossingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"MThresholdCrossingConfiguration","templateVersion":"5.2.0.1","priority":"4","version":"5.2.0.1","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"$class": "com.att.ecomp.dcae.clamp.common.MThresholdCrossingConfiguration","domain":"measurementsForVfScaling","policyScope":"pnf=eNodeB;type=configuration","policyName":"policy.dcae.configuration","policyVersion":"1.0.0","subscriberContentType": "application/json","subscriberConsumerId": "c13","subscriberConsumerGroup": "OpenDCAE-c13","subscriberTimeoutMS": "-1","subscriberMessageLimit": "-1","subscriberPollingInterval": "20000","publisherContentType": "application/json","publisherMaxBatchSize": "10","publisherMaxRecoveryQueueSize": "100000","publisherPollingInterval": "20000","publisherAlertWindowingTime": "86400","signatures":[]}}
+tca.signature.template={"nfNamingCode":"ENBE","target":"common_id","targetType":"eNodeB","useCaseName":"???","signatureName":"???","signatureUuid":"???","closedLoopControlName":"???","severity":"???","version":"1.0.2","maxInterval":1200,"minMessageViolations":4,"thresholds":[]}
+# 
+# String Match MicroService Policy request build properties
+#
+# default
+sm.template={"service":"StringMatchingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"com.att.d2.policy.StringMatchingConfiguration","templateVersion":"1604","priority":"4","version":"1610","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"serviceConfigurations":{}}}
+# by service: vSCP
+sm.template.vSCP={"service":"StringMatchingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"com.att.d2.policy.StringMatchingConfiguration","templateVersion":"1604","priority":"4","version":"0.1.0-SNAPSHOT","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"serviceConfigurations":{}}}
+sm.sc.template={}
+#
+# default
+sm.rulegroup=true
+# by service: vSCP
+sm.rulegroup.vSCP=false
+# 
+# 
+# Operational Policy request build properties
+#
+op.policyDescription=from clds
+# default
+op.templateName=ClosedLoopvUSP
+op.operationTopic=APPC-CL
+op.notificationTopic=POLICY-CL-MGT
+op.controller=1610-vUSP
+# by service: vSCP
+op.templateName.vSCP=ClosedLoopTemplate
+op.controller.vSCP=1607-f5fw
+#
+# Asdc service properties
+asdc.catalog.url=http://127.0.0.1:8080/asdc/v1/catalog/
+asdc.hostUrl=http://127.0.0.1:8080
+asdc.serviceUrl=http://127.0.0.1:8080/asdc/v1/catalog/services
+asdc.serviceUsername=test
+asdc.servicePassword=123456
+asdc.artifactLabel=blueprintclampcockpit
+asdc.asdcX-ECOMP-InstanceID=CLAMP
+asdc.artifactType=DCAE_INVENTORY_BLUEPRINT
+asdc.locationArtifactLabel=locationclampcockpit
+asdc.locationArtifactType=DCAE_INVENTORY_JSON
+#
+#
+#
+ui.location.default={"SNDGCA64":"San Diego SAN3","ALPRGAED":"Alpharetta PDK1","LSLEILAA":"Lisle DPA3","MDTWNJC1":"FTL_C_location1","MDTWNJC2":"FTL_C_location2","MDTWNJ21":"FTL_L_location1","MDTWNJ22":"FTL_L_location2","RDM2WAGPLCP":"ISTFTL_location"}
+ui.alarm.default={"Reports a transient alarm condition when an incoming CDR cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming CDR cannot be decoded successfully","Reports a transient alarm condition when an incoming ACR message cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming ACR message cannot be decoded successfully","Reports a transient alarm condition when a CDR validation fails":"vCCF: Reports a transient alarm condition when a CDR validation fails","Reports a transient alarm condition when an incoming GTP' message cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming GTP' message cannot be decoded successfully","Reports a transient alarm condition when an incoming CDR file cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming CDR file cannot be decoded successfully","Reports a transient alarm condition when an incoming Sh/Dh file cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming Sh/Dh file cannot be decoded successfully","Reports a transient alarm condition when an incoming ACR message is in conflict with former ACR in one diameter session":"vCCF: Reports a transient alarm condition when an incoming ACR message is in conflict with former ACR in one diameter session","Reports a transient alarm condition when an outgoing Ro message send fails":"vCCF: Reports a transient alarm condition when an outgoing Ro message send fails","Reports a transient alarm condition when an outgoing GTP' message send fails":"vCCF: Reports a transient alarm condition when an outgoing GTP' message send fails","Reports a transient alarm condition when an outgoing Sh/Dh message send fails":"vCCF: Reports a transient alarm condition when an outgoing Sh/Dh message send fails","Reports an alarm when build or send Rf message fail":"vCCF: Reports an alarm when build or send Rf message fail","Reports a transient alarm condition when an abnormal incoming CCA message":"vCCF: Reports a transient alarm condition when an abnormal incoming CCA message","Reports a transient alarm condition when there is an abnormal incoming Sh/Dh message":"vCCF: Reports a transient alarm condition when there is an abnormal incoming Sh/Dh message","For Rf interface, if IeCCF receives a message with incorrect value for session id.":"vCCF: For Rf interface, if IeCCF receives a message with incorrect value for session id.","Reports an alarm when CPU usage exceeds the major threshold, the local database exceeds the critical threshold, or the ACR partition exceeds the major threshold":"vCCF: Reports an alarm when CPU usage exceeds the major threshold, the local database exceeds the critical threshold, or the ACR partition exceeds the major threshold","Reports an alarm when CPU usage exceeds the minor threshold, the local database exceeds the major threshold, or the ACR partition exceeds the minor threshold":"vCCF: Reports an alarm when CPU usage exceeds the minor threshold, the local database exceeds the major threshold, or the ACR partition exceeds the minor threshold","Reports an alarm when CPU usage exceeds the critical threshold, the local database exceeds the major threshold, or the CDR partition exceeds the critical threshold":"vCCF: Reports an alarm when CPU usage exceeds the critical threshold, the local database exceeds the major threshold, or the CDR partition exceeds the critical threshold","Reports an alarm when CPU usage exceeds the major threshold or CDR partition exceeds the major threshold":"vCCF: Reports an alarm when CPU usage exceeds the major threshold or CDR partition exceeds the major threshold","Reports an alarm when external DB usage exceeds the major threshold":"vCCF: Reports an alarm when external DB usage exceeds the major threshold","If IeCCF comes to the status \\"Stop processing ACR records in ACRDB\\".":"vCCF: If IeCCF comes to the status \\"Stop processing ACR records in ACRDB\\".","If IeCCF comes to the status \\"Flush ACR is invoked\\".":"vCCF: If IeCCF comes to the status \\"Flush ACR is invoked\\".","Reports a transient alarm condition when the workflow definition table is provisioned wrongly":"vCCF: Reports a transient alarm condition when the workflow definition table is provisioned wrongly","Reports a transient alarm condition when the Action Definition table is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Action Definition table is provisioned wrongly","Reports a transient alarm condition when the Ro Host Configuration is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Ro Host Configuration is provisioned wrongly","Reports a transient alarm condition when the Sh Host Configuration is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Sh Host Configuration is provisioned wrongly","Reports a transient alarm condition when a specific dictionary or rule does not exist":"vCCF: Reports a transient alarm condition when a specific dictionary or rule does not exist","Reports a transient alarm condition when failure occurs when mapping Rf message to XDR":"vCCF: Reports a transient alarm condition when failure occurs when mapping Rf message to XDR","Reports a transient alarm condition when failure occurs in aggregating process":"vCCF: Reports a transient alarm condition when failure occurs in aggregating process","Reports a transient alarm condition when failure happens in correlating process":"vCCF: Reports a transient alarm condition when failure happens in correlating process","Reports a transient alarm condition when failure occurs in generating CDR":"vCCF: Reports a transient alarm condition when failure occurs in generating CDR","Reports a transient alarm condition when failure occurs in constructing CCR message from XDR":"vCCF: Reports a transient alarm condition when failure occurs in constructing CCR message from XDR","Reports a transient alarm condition when an ACR/XER/BER/INC record write to bad file":"vCCF: Reports a transient alarm condition when an ACR/XER/BER/INC record write to bad file","Reports an alarm condition when aggregation or correlation central database connection is lost":"vCCF: Reports an alarm condition when aggregation or correlation central database connection is lost","Reports an alarm condition when a specific failure happens in database operations":"vCCF: Reports an alarm condition when a specific failure happens in database operations","Reports an alarm condition when DB capacity has been consumed to critical threshold":"vCCF: Reports an alarm condition when DB capacity has been consumed to critical threshold","Reports an alarm condition when DB capacity has been consumed to major threshold":"vCCF: Reports an alarm condition when DB capacity has been consumed to major threshold","Reports an alarm condition when DB capacity has been consumed to minor threshold.":"vCCF: Reports an alarm condition when DB capacity has been consumed to minor threshold.","Reports an alarm condition when application cannot deliver CDR to CDRSCH subsystem":"vCCF: Reports an alarm condition when application cannot deliver CDR to CDRSCH subsystem","Reports an alarm condition when some fields of ACR file header have error value and this ACR file cannot be processed further":"vCCF: Reports an alarm condition when some fields of ACR file header have error value and this ACR file cannot be processed further","Reports an alarm condition when some fields of ACR file header have invalid value and this ACR file can be processed further":"vCCF: Reports an alarm condition when some fields of ACR file header have invalid value and this ACR file can be processed further","Reports an alarm condition when the ACR file loses some ACR records":"vCCF: Reports an alarm condition when the ACR file loses some ACR records","Reports an alarm condition when some fields of ACR record header have error value and this ACR record and the following ACR records cannot be processed further":"vCCF: Reports an alarm condition when some fields of ACR record header have error value and this ACR record and the following ACR records cannot be processed further","Reports an alarm condition when error occurs in processing CDR/ACR files":"vCCF: Reports an alarm condition when error occurs in processing CDR/ACR files","Reports an alarm condition when CDR partition has been consumed to critical threshold":"vCCF: Reports an alarm condition when CDR partition has been consumed to critical threshold","Reports an alarm condition when CDR partition has been consumed to major threshold.":"vCCF: Reports an alarm condition when CDR partition has been consumed to major threshold.","Reports an alarm condition when CDR partition has been consumed to minor threshold":"vCCF: Reports an alarm condition when CDR partition has been consumed to minor threshold","Reports an alarm condition when ACR partition has been consumed to critical threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to critical threshold","Reports an alarm condition when ACR partition has been consumed to major threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to major threshold","Reports an alarm condition when ACR partition has been consumed to minor threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to minor threshold","Reports an alarm condition when CPU consumption reaches critical threshold":"vCCF: Reports an alarm condition when CPU consumption reaches critical threshold","Reports an alarm condition when CPU consumption reaches major threshold":"vCCF: Reports an alarm condition when CPU consumption reaches major threshold","Reports an alarm condition when CPU consumption reaches minor threshold":"vCCF: Reports an alarm condition when CPU consumption reaches minor threshold","Service shall monitor * number of partial CDR * number of incompleted CDR * number of unacceptable CDR If any one exceeds a configurable threshold in a configrable interval.":"vCCF: Service shall monitor * number of partial CDR * number of incompleted CDR * number of unacceptable CDR If any one exceeds a configurable threshold in a configrable interval.","CDR size exceed the platform capacity.":"vCCF: CDR size exceed the platform capacity.","Service shall monitor number of ACR without AII AVP, If it exceeds a configurable threshold in a configurable interval.":"vCCF: Service shall monitor number of ACR without AII AVP, If it exceeds a configurable threshold in a configurable interval.","Service shall monitor CDR cut due to ECCF_ACRNUMBER_IN_DB, If it exceeds a configurable threshold in a configurable interval.":"vCCF: Service shall monitor CDR cut due to ECCF_ACRNUMBER_IN_DB, If it exceeds a configurable threshold in a configurable interval.","External Node of this Cluster is overload":"vCCF: External Node of this Cluster is overload","bdb_high_latency":"vCCF-vDB: bdb_high_latency","bdb_high_throughput":"vCCF-vDB: bdb_high_throughput","bdb_size":"vCCF-vDB: bdb_size","cluster_inconsistent_rl_sw":"vCCF-vDB: cluster_inconsistent_rl_sw","cluster_node_remove_abort_failed":"vCCF-vDB: cluster_node_remove_abort_failed","cluster_node_remove_failed":"vCCF-vDB: cluster_node_remove_failed","cluster_ram_overcommit":"vCCF-vDB: cluster_ram_overcommit","cluster_rebalance_failed":"vCCF-vDB: cluster_rebalance_failed","cluster_too_few_nodes_for_replication":"vCCF-vDB: cluster_too_few_nodes_for_replication","node_cpu_utilization":"vCCF-vDB: node_cpu_utilization","node_ephemeral_storage":"vCCF-vDB: node_ephemeral_storage","node_failed":"vCCF-vDB: node_failed","node_memory":"vCCF-vDB: node_memory","node_net_throughput":"vCCF-vDB: node_net_throughput","node_offline_failed":"vCCF-vDB: node_offline_failed","node_offline_abort_failed":"vCCF-vDB: node_offline_abort_failed","node_online_failed":"vCCF-vDB: node_online_failed","OAM NODE-<OAME-hostname> IS NOT ACTIVE ":"vCCF-vDB: OAM NODE-<OAME-hostname> IS NOT ACTIVE ","LSS_asdaCommunicationFailure":"vCTS: LSS_asdaCommunicationFailure","LSS_ccdbCommunicationFailure":"vCTS: LSS_ccdbCommunicationFailure","LSS_cpiCTS3xxFailRate":"vCTS: LSS_cpiCTS3xxFailRate","LSS_cpiCTS4xxFailRate":"vCTS: LSS_cpiCTS4xxFailRate","LSS_cpiCTS5xxFailRate":"vCTS: LSS_cpiCTS5xxFailRate","LSS_cpiCTS6xxFailRate":"vCTS: LSS_cpiCTS6xxFailRate","LSS_cpiCTSSIPRetransmitInvite":"vCTS: LSS_cpiCTSSIPRetransmitInvite","LSS_cpiCTSSIPRetransmitNonInvite":"vCTS: LSS_cpiCTSSIPRetransmitNonInvite","LSS_glsInvalidCellId":"vCTS: LSS_glsInvalidCellId","LSS_glsServerUnavailable":"vCTS: LSS_glsServerUnavailable","LSS_hlrSyncConnection":"vCTS: LSS_hlrSyncConnection","LSS_hlrSyncQueue":"vCTS: LSS_hlrSyncQueue","LSS_lispBufferFullExternalLIG":"vCTS: LSS_lispBufferFullExternalLIG","LSS_prdbConnectWithAlternateFailure":"vCTS: LSS_prdbConnectWithAlternateFailure","LSS_prdbSyncDataToAlternateFailure":"vCTS: LSS_prdbSyncDataToAlternateFailure","LSS_preAllocatedResourceOverload":"vCTS: LSS_preAllocatedResourceOverload","LSS_prifSocketError":"vCTS: LSS_prifSocketError","LSS_prsCallInstanceExceeded":"vCTS: LSS_prsCallInstanceExceeded","LSS_prsCpuOverload":"vCTS: LSS_prsCpuOverload","LSS_prsDatabaseMigrationFailure":"vCTS: LSS_prsDatabaseMigrationFailure","LSS_prsFailureToConnectWithPRDB":"vCTS: LSS_prsFailureToConnectWithPRDB","LSS_prsQueueExceeded":"vCTS: LSS_prsQueueExceeded","LSS_smdiSocketError":"vCTS: LSS_smdiSocketError","LSS_socketError":"vCTS: LSS_socketError","LSS_softwareComponentDown":"vCTS: LSS_softwareComponentDown","LSS_tlsInitError":"vCTS: LSS_tlsInitError","LSS_usageOfSyncTable":"vCTS: LSS_usageOfSyncTable","LSS_utHttpProxyConnectionDown ":"vCTS: LSS_utHttpProxyConnectionDown ","LSS_wpifSocketError":"vCTS: LSS_wpifSocketError","LSS_acrTemporaryBufferOverload":"vCTS: LSS_acrTemporaryBufferOverload","LSS_adnsExtendedTTLcaching":"vCTS: LSS_adnsExtendedTTLcaching","LSS_adnsQueryFailureCaching":"vCTS: LSS_adnsQueryFailureCaching","LSS_adnsQueueCongestion":"vCTS: LSS_adnsQueueCongestion","LSS_asdaRequestQueue":"vCTS: LSS_asdaRequestQueue","LSS_capacityLicenseKeyExpiration":"vCTS: LSS_capacityLicenseKeyExpiration","LSS_capacityLicenseKeyNearExpiration":"vCTS: LSS_capacityLicenseKeyNearExpiration","LSS_capacityLicenseKeyValidationError":"vCTS: LSS_capacityLicenseKeyValidationError","LSS_cardConnectionLost":"vCTS: LSS_cardConnectionLost","LSS_cpiAlrmCritical":"vCTS: LSS_cpiAlrmCritical","LSS_cpiAlrmMajor":"vCTS: LSS_cpiAlrmMajor","LSS_cpiAlrmMinor":"vCTS: LSS_cpiAlrmMinor","LSS_cpiAlrmWarning":"vCTS: LSS_cpiAlrmWarning","LSS_cpiAsrtEsc":"vCTS: LSS_cpiAsrtEsc","LSS_cpiAsrtNonEsc":"vCTS: LSS_cpiAsrtNonEsc","LSS_cpiAsrtNonEscCritical":"vCTS: LSS_cpiAsrtNonEscCritical","LSS_cpiAsrtNonEscMajor":"vCTS: LSS_cpiAsrtNonEscMajor","LSS_cpiAsrtNonEscMinor":"vCTS: LSS_cpiAsrtNonEscMinor","LSS_cpiAudErrCount":"vCTS: LSS_cpiAudErrCount","LSS_cpiAudManAct":"vCTS: LSS_cpiAudManAct","LSS_cpiAudNewEvent":"vCTS: LSS_cpiAudNewEvent","LSS_cpiCompleteRateAlarm":"vCTS: LSS_cpiCompleteRateAlarm","LSS_cpiDropMGAllocConnReq":"vCTS: LSS_cpiDropMGAllocConnReq","LSS_cpiDropRateAlarm":"vCTS: LSS_cpiDropRateAlarm","LSS_cpiExceptionService":"vCTS: LSS_cpiExceptionService","LSS_cpiFailRateAlarm":"vCTS: LSS_cpiFailRateAlarm","LSS_cpiFailSCTPFastRetransIncr":"vCTS: LSS_cpiFailSCTPFastRetransIncr","LSS_cpiFailSCTPFastRetransRate":"vCTS: LSS_cpiFailSCTPFastRetransRate","LSS_cpiFailSCTPSRTT1Incr":"vCTS: LSS_cpiFailSCTPSRTT1Incr","LSS_cpiFailSCTPSRTT2Incr":"vCTS: LSS_cpiFailSCTPSRTT2Incr","LSS_cpiFailSCTPT3RetransIncr":"vCTS: LSS_cpiFailSCTPT3RetransIncr","LSS_cpiFailSCTPT3RetransRate":"vCTS: LSS_cpiFailSCTPT3RetransRate","LSS_cpiFileSysUsage":"vCTS: LSS_cpiFileSysUsage","LSS_cpiMemAllocFail":"vCTS: LSS_cpiMemAllocFail","LSS_cpiNumOfLICDRDel":"vCTS: LSS_cpiNumOfLICDRDel","LSS_cpiReinitServiceSelf":"vCTS: LSS_cpiReinitServiceSelf","LSS_cpiSIPRetransmitInvite":"vCTS: LSS_cpiSIPRetransmitInvite","LSS_cpiSIPRetransmitNonInvite":"vCTS: LSS_cpiSIPRetransmitNonInvite","LSS_cpiSS7DropSCTPPktsRcvd":"vCTS: LSS_cpiSS7DropSCTPPktsRcvd","LSS_cpiSS7FailSCTPFastRetransRate":"vCTS: LSS_cpiSS7FailSCTPFastRetransRate","LSS_cpiStabilityAlarm":"vCTS: LSS_cpiStabilityAlarm","LSS_cpuOverload":"vCTS: LSS_cpuOverload","LSS_databaseConnectionLost":"vCTS: LSS_databaseConnectionLost","LSS_databaseReplicationLinkDown":"vCTS: LSS_databaseReplicationLinkDown","LSS_databaseSizeExhausted":"vCTS: LSS_databaseSizeExhausted","LSS_dbHighCpuUtilization":"vCTS: LSS_dbHighCpuUtilization","LSS_dbOffline":"vCTS: LSS_dbOffline","LSS_dbStatusUnexpected":"vCTS: LSS_dbStatusUnexpected","LSS_degradedResource":"vCTS: LSS_degradedResource","LSS_degrow":"vCTS: LSS_degrow","LSS_deviceServerCxnLost":"vCTS: LSS_deviceServerCxnLost","LSS_diamLinkDown":"vCTS: LSS_diamLinkDown","LSS_diamMaxClientsExceeded":"vCTS: LSS_diamMaxClientsExceeded","LSS_dnsThreshold":"vCTS: LSS_dnsThreshold","LSS_ethernetError":"vCTS: LSS_ethernetError","LSS_ethernetLinkDown":"vCTS: LSS_ethernetLinkDown","LSS_externalConnectivity":"vCTS: LSS_externalConnectivity","LSS_featureLicenseExpiration":"vCTS: LSS_featureLicenseExpiration","LSS_featureLicenseKeyNearExpiration":"vCTS: LSS_featureLicenseKeyNearExpiration","LSS_featureLockValidationError":"vCTS: LSS_featureLockValidationError","LSS_fqdnError":"vCTS: LSS_fqdnError","LSS_fru":"vCTS: LSS_fru","LSS_gatewayCongestion":"vCTS: LSS_gatewayCongestion","LSS_gatewayForcedOOS":"vCTS: LSS_gatewayForcedOOS","LSS_gatewayProvisioningError":"vCTS: LSS_gatewayProvisioningError","LSS_gatewayUnreachable":"vCTS: LSS_gatewayUnreachable","LSS_gatewayUnregistered":"vCTS: LSS_gatewayUnregistered","LSS_globalParameterNotFound":"vCTS: LSS_globalParameterNotFound","LSS_grow":"vCTS: LSS_grow","LSS_h248MessageBufferDepletion":"vCTS: LSS_h248MessageBufferDepletion","LSS_hostDown":"vCTS: LSS_hostDown","LSS_hostReset":"vCTS: LSS_hostReset","LSS_invalidGateway":"vCTS: LSS_invalidGateway","LSS_iriLinkDown":"vCTS: LSS_iriLinkDown","LSS_ldapServerConnectionLost":"vCTS: LSS_ldapServerConnectionLost","LSS_llcDown":"vCTS: LSS_llcDown","LSS_logicalLinkDown":"vCTS: LSS_logicalLinkDown","LSS_logicalLinkNotFound":"vCTS: LSS_logicalLinkNotFound","LSS_logRotateThreshold":"vCTS: LSS_logRotateThreshold","LSS_memoryOverload":"vCTS: LSS_memoryOverload","LSS_nodeConfigFailure":"vCTS: LSS_nodeConfigFailure","LSS_nodeGroupOOS":"vCTS: LSS_nodeGroupOOS","LSS_nodeOOS":"vCTS: LSS_nodeOOS","LSS_nonCompliantFaultGroupMemberState":"vCTS: LSS_nonCompliantFaultGroupMemberState","LSS_nonCsAddrChannelDepletion":"vCTS: LSS_nonCsAddrChannelDepletion","LSS_numberOfTuplesInUse":"vCTS: LSS_numberOfTuplesInUse","LSS_osSecInfoModificationDetected":"vCTS: LSS_osSecInfoModificationDetected","LSS_osSecInformationMissing":"vCTS: LSS_osSecInformationMissing","LSS_osSecUnexpectedInformation":"vCTS: LSS_osSecUnexpectedInformation","LSS_pdnsMySqlReplication":"vCTS: LSS_pdnsMySqlReplication","LSS_pktCorruptionDetectedViaRCCLANCheck":"vCTS: LSS_pktCorruptionDetectedViaRCCLANCheck","LSS_platformCommandFailure":"vCTS: LSS_platformCommandFailure","LSS_pmDataNotCollected":"vCTS: LSS_pmDataNotCollected","LSS_processDown":"vCTS: LSS_processDown","LSS_processNotStarted":"vCTS: LSS_processNotStarted","LSS_provisioningInhibitedMode":"vCTS: LSS_provisioningInhibitedMode","LSS_rccInhibitedMode":"vCTS: LSS_rccInhibitedMode","LSS_remotedbLinkDown":"vCTS: LSS_remotedbLinkDown","LSS_remoteQueryServerFailure":"vCTS: LSS_remoteQueryServerFailure","LSS_restore":"vCTS: LSS_restore","LSS_serviceCFGDataTimestampError":"vCTS: LSS_serviceCFGDataTimestampError","LSS_serviceCommCxnLost":"vCTS: LSS_serviceCommCxnLost","LSS_serviceOnewayCommunication":"vCTS: LSS_serviceOnewayCommunication","LSS_sheddingOverload":"vCTS: LSS_sheddingOverload","LSS_simxml":"vCTS: LSS_simxml","LSS_sipLinkSetMaxQuarantineList":"vCTS: LSS_sipLinkSetMaxQuarantineList","LSS_sipLinkSetUnavailable":"vCTS: LSS_sipLinkSetUnavailable","LSS_sipLinkUnavailable":"vCTS: LSS_sipLinkUnavailable","LSS_softwareAllocatedResourceOverload":"vCTS: LSS_softwareAllocatedResourceOverload","LSS_softwareComponentStandbyNotReady":"vCTS: LSS_softwareComponentStandbyNotReady","LSS_softwareLicense":"vCTS: LSS_softwareLicense","LSS_svcdegrow":"vCTS: LSS_svcdegrow","LSS_svcgrow":"vCTS: LSS_svcgrow","LSS_swVersionMismatch":"vCTS: LSS_swVersionMismatch","LSS_tftpDownloadCorrupt":"vCTS: LSS_tftpDownloadCorrupt","LSS_timeStampValueOutOfSystemRange":"vCTS: LSS_timeStampValueOutOfSystemRange","LSS_transactionHandlerBlockDepletion":"vCTS: LSS_transactionHandlerBlockDepletion","LSS_upgrade":"vCTS: LSS_upgrade","SYS_BackupFailure":"vCTS: SYS_BackupFailure","SYS_Configuration":"vCTS: SYS_Configuration","SYS_COTRecordTransferFailure":"vCTS: SYS_COTRecordTransferFailure","SYS_CPM_USERDATA_INCONSITENCY":"vCTS: SYS_CPM_USERDATA_INCONSITENCY","SYS_CPM_USERDATA_RESTORED":"vCTS: SYS_CPM_USERDATA_RESTORED","SYS_EventQueueCapacity":"vCTS: SYS_EventQueueCapacity","SYS_ICMPFailure":"vCTS: SYS_ICMPFailure","SYS_IPsecConfig":"vCTS: SYS_IPsecConfig","SYS_LinkDown":"vCTS: SYS_LinkDown","SYS_NotifyDisabled":"vCTS: SYS_NotifyDisabled","SYS_NotifyLocked":"vCTS: SYS_NotifyLocked","SYS_NumTL1MeasThresh":"vCTS: SYS_NumTL1MeasThresh","SYS_RADIUS_TO_LDAP_FAILURE":"vCTS: SYS_RADIUS_TO_LDAP_FAILURE","SYS_ROOT_ACCESS_DENIED":"vCTS: SYS_ROOT_ACCESS_DENIED","SYS_ROOT_FTP_VIOLATION":"vCTS: SYS_ROOT_FTP_VIOLATION","SYS_ROOT_LOGIN_VIOLATION":"vCTS: SYS_ROOT_LOGIN_VIOLATION","SYS_ROOT_SSH_LOGIN_VIOLATION":"vCTS: SYS_ROOT_SSH_LOGIN_VIOLATION","SYS_SetupAAAFailure":"vCTS: SYS_SetupAAAFailure","SYS_SNETrapOverload":"vCTS: SYS_SNETrapOverload","SYS_SNMPAuthenticationFailure":"vCTS: SYS_SNMPAuthenticationFailure","SYS_SNMPFailure":"vCTS: SYS_SNMPFailure","SYS_SU_TO_ROOT_FAILURE":"vCTS: SYS_SU_TO_ROOT_FAILURE","SYS_SYSTEMTrapOverload":"vCTS: SYS_SYSTEMTrapOverload","SYS_ThresholdCrossed":"vCTS: SYS_ThresholdCrossed","SYS_UndiscoveredObject":"vCTS: SYS_UndiscoveredObject","SYS_WriteAAAFailure":"vCTS: SYS_WriteAAAFailure","jnxSpaceDiskUsageRising":"vDBE-EMS-Juniper: jnxSpaceDiskUsageRising","jnxSpaceDiskUsageRisingCleared":"vDBE-EMS-Juniper: jnxSpaceDiskUsageRisingCleared","jnxSpaceSwapUsageRising":"vDBE-EMS-Juniper: jnxSpaceSwapUsageRising","jnxSpaceSwapUsageRisingCleared":"vDBE-EMS-Juniper: jnxSpaceSwapUsageRisingCleared","jnxSpaceCPULARising":"vDBE-EMS-Juniper: jnxSpaceCPULARising","jnxSpaceCPULARisingCleared":"vDBE-EMS-Juniper: jnxSpaceCPULARisingCleared","jnxSpaceWebpProxyProcessDown":"vDBE-EMS-Juniper: jnxSpaceWebpProxyProcessDown","jnxSpaceWebpProxyProcessUp":"vDBE-EMS-Juniper: jnxSpaceWebpProxyProcessUp","jnxSpaceNMAProcessDown":"vDBE-EMS-Juniper: jnxSpaceNMAProcessDown","jnxSpaceNMAProcessUp":"vDBE-EMS-Juniper: jnxSpaceNMAProcessUp","jnxSpaceJbossProcessDown":"vDBE-EMS-Juniper: jnxSpaceJbossProcessDown","jnxSpaceJbossProcessUp":"vDBE-EMS-Juniper: jnxSpaceJbossProcessUp","jnxSpaceMysqlProcessDown":"vDBE-EMS-Juniper: jnxSpaceMysqlProcessDown","jnxSpaceMysqlProcessUp":"vDBE-EMS-Juniper: jnxSpaceMysqlProcessUp","jnxSpacePostgresqlProcessDown":"vDBE-EMS-Juniper: jnxSpacePostgresqlProcessDown","jnxSpacePostgresqlProcessUp":"vDBE-EMS-Juniper: jnxSpacePostgresqlProcessUp","jnxSpaceWatchdogStopped":"vDBE-EMS-Juniper: jnxSpaceWatchdogStopped","jnxSpaceWatchdogStarted":"vDBE-EMS-Juniper: jnxSpaceWatchdogStarted","jnxSpaceSNAProcessDown":"vDBE-EMS-Juniper: jnxSpaceSNAProcessDown","jnxSpaceSNAProcessUp":"vDBE-EMS-Juniper: jnxSpaceSNAProcessUp","jnxSpaceNodeDown":"vDBE-EMS-Juniper: jnxSpaceNodeDown","jnxSpaceNodeUp":"vDBE-EMS-Juniper: jnxSpaceNodeUp"," jnxSpaceNodeRemoval":"vDBE-EMS-Juniper:  jnxSpaceNodeRemoval","jnxCmCfgChange":"vDBE-Juniper: jnxCmCfgChange","jnxCmRescueChange":"vDBE-Juniper: jnxCmRescueChange","jnxEventTrap":"vDBE-Juniper: jnxEventTrap","jnxJsFwAuthFailure":"vDBE-Juniper: jnxJsFwAuthFailure","jnxJsFwAuthServiceUp":"vDBE-Juniper: jnxJsFwAuthServiceUp","jnxJsFwAuthServiceDown":"vDBE-Juniper: jnxJsFwAuthServiceDown","jnxJsFwAuthCapacityExceeded":"vDBE-Juniper: jnxJsFwAuthCapacityExceeded","jnxJsIdpSignatureUpdate":"vDBE-Juniper: jnxJsIdpSignatureUpdate","jnxJsIdpAttackLog":"vDBE-Juniper: jnxJsIdpAttackLog","jnxJsSrcNatPoolThresholdStatus":"vDBE-Juniper: jnxJsSrcNatPoolThresholdStatus","jnxJsNatRuleThresholdStatus":"vDBE-Juniper: jnxJsNatRuleThresholdStatus","jnxJsScreenAttack":"vDBE-Juniper: jnxJsScreenAttack","jnxJsScreenCfgChange":"vDBE-Juniper: jnxJsScreenCfgChange","jnxJsAvPatternUpdateTrap":"vDBE-Juniper: jnxJsAvPatternUpdateTrap","jnxJsChassisClusterSwitchover":"vDBE-Juniper: jnxJsChassisClusterSwitchover","jnxJsChClusterIntfTrap":"vDBE-Juniper: jnxJsChClusterIntfTrap","jnxJsChClusterSpuMismatchTrap":"vDBE-Juniper: jnxJsChClusterSpuMismatchTrap","jnxJsChClusterWeightTrap":"vDBE-Juniper: jnxJsChClusterWeightTrap","jnxLicenseGraceExpired":"vDBE-Juniper: jnxLicenseGraceExpired","jnxLicenseGraceAboutToExpire":"vDBE-Juniper: jnxLicenseGraceAboutToExpire","jnxLicenseAboutToExpire":"vDBE-Juniper: jnxLicenseAboutToExpire","jnxLicenseInfringeCumulative":"vDBE-Juniper: jnxLicenseInfringeCumulative","jnxLicenseInfringeSingle":"vDBE-Juniper: jnxLicenseInfringeSingle","jnxNatAddrPoolThresholdStatus":"vDBE-Juniper: jnxNatAddrPoolThresholdStatus","jnxSyslogTrap":"vDBE-Juniper: jnxSyslogTrap","jnxAccessAuthServiceUp":"vDBE-Juniper: jnxAccessAuthServiceUp","jnxAccessAuthServiceDown":"vDBE-Juniper: jnxAccessAuthServiceDown","jnxAccessAuthServerDisabled":"vDBE-Juniper: jnxAccessAuthServerDisabled","jnxAccessAuthServerEnabled":"vDBE-Juniper: jnxAccessAuthServerEnabled","jnxAccessAuthAddressPoolHighThreshold":"vDBE-Juniper: jnxAccessAuthAddressPoolHighThreshold","jnxAccessAuthAddressPoolAbateThreshold":"vDBE-Juniper: jnxAccessAuthAddressPoolAbateThreshold","jnxAccessAuthAddressPoolOutOfAddresses":"vDBE-Juniper: jnxAccessAuthAddressPoolOutOfAddresses","jnxAccessAuthAddressPoolOutOfMemory":"vDBE-Juniper: jnxAccessAuthAddressPoolOutOfMemory","LEVEL_WARNING_CPU":"vMRF: LEVEL_WARNING_CPU","LEVEL_MAJOR_CPU":"vMRF: LEVEL_MAJOR_CPU","LEVEL_CRITICAL_CPU":"vMRF: LEVEL_CRITICAL_CPU","LEVEL_WARNING_MEM":"vMRF: LEVEL_WARNING_MEM","LEVEL_MAJOR_MEM":"vMRF: LEVEL_MAJOR_MEM","LEVEL_CRITICAL_MEM":"vMRF: LEVEL_CRITICAL_MEM","LEVEL_WARNING_DISK":"vMRF: LEVEL_WARNING_DISK","LEVEL_MAJOR_DISK":"vMRF: LEVEL_MAJOR_DISK","LEVEL_CRITICAL_DISK":"vMRF: LEVEL_CRITICAL_DISK","LEVEL_WARNING_RTPBANDWIDTH":"vMRF: LEVEL_WARNING_RTPBANDWIDTH","LEVEL_MAJOR_RTPBANDWIDTH":"vMRF: LEVEL_MAJOR_RTPBANDWIDTH","LEVEL_CRITICAL_RTPBANDWIDTH":"vMRF: LEVEL_CRITICAL_RTPBANDWIDTH","LEVEL_WARNING_RTPINPACKETLOSS":"vMRF: LEVEL_WARNING_RTPINPACKETLOSS","LEVEL_MAJOR_RTPINPACKETLOSS":"vMRF: LEVEL_MAJOR_RTPINPACKETLOSS","LEVEL_CRITICAL_RTPINPACKETLOSS":"vMRF: LEVEL_CRITICAL_RTPINPACKETLOSS","LEVEL_WARNING_RTPOUTPACKETLOSS":"vMRF: LEVEL_WARNING_RTPOUTPACKETLOSS","LEVEL_MAJOR_RTPOUTPACKETLOSS":"vMRF: LEVEL_MAJOR_RTPOUTPACKETLOSS","LEVEL_CRITICAL_RTPOUTPACKETLOSS":"vMRF: LEVEL_CRITICAL_RTPOUTPACKETLOSS","LEVEL_WARNING_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_WARNING_TCPLOSTRETRANSMITRATE","LEVEL_MAJOR_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_MAJOR_TCPLOSTRETRANSMITRATE","LEVEL_CRITICAL_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_CRITICAL_TCPLOSTRETRANSMITRATE","LEVEL_WARNING_TCPLOSSFAILURERATE":"vMRF: LEVEL_WARNING_TCPLOSSFAILURERATE","LEVEL_MAJOR_TCPLOSSFAILURERATE":"vMRF: LEVEL_MAJOR_TCPLOSSFAILURERATE","LEVEL_CRITICAL_TCPLOSSFAILURERATE":"vMRF: LEVEL_CRITICAL_TCPLOSSFAILURERATE","LEVEL_CRITICAL_RTPLINKDOWN":"vMRF: LEVEL_CRITICAL_RTPLINKDOWN","TARGET_REACHABLE":"vMRF: TARGET_REACHABLE","PUBLICATION_ERROR":"vMRF: PUBLICATION_ERROR","REMOTE_SERVER_SYNCHRONIZATION_ERROR":"vMRF: REMOTE_SERVER_SYNCHRONIZATION_ERROR","TRANSCODER_TOOL_EXEC_ERROR":"vMRF: TRANSCODER_TOOL_EXEC_ERROR","CLIENT_SYNCHRONIZATION_ERROR":"vMRF: CLIENT_SYNCHRONIZATION_ERROR","CLUSTER_UNREACHABLE":"vMRF: CLUSTER_UNREACHABLE","REMOTE_NODE_OFFLINE":"vMRF: REMOTE_NODE_OFFLINE","IPADDR_STOPPED":"vMRF: IPADDR_STOPPED","MRFC_STOPPED":"vMRF: MRFC_STOPPED","MNGT_STOPPED":"vMRF: MNGT_STOPPED","IPADDR_STARTED":"vMRF: IPADDR_STARTED","MRFC_STARTED":"vMRF: MRFC_STARTED","MNGT_STARTED":"vMRF: MNGT_STARTED","VOLATTACH_FAILED":"vMRF: VOLATTACH_FAILED","VOLDETACH_FAILED":"vMRF: VOLDETACH_FAILED","VOLDEL":"vMRF: VOLDEL","VOLCORRUPT":"vMRF: VOLCORRUPT","VOLFOREIGN":"vMRF: VOLFOREIGN","ACTIVE_ALARM_TABLE_PURGE":"vMRF: ACTIVE_ALARM_TABLE_PURGE","GENERIC_FORMER_STATELESS":"vMRF: GENERIC_FORMER_STATELESS","GENERIC_FORMER_STATEFUL":"vMRF: GENERIC_FORMER_STATEFUL","NO_MORE_ALARM_DESCRIPTION":"vMRF: NO_MORE_ALARM_DESCRIPTION","SERVICE_PROCESS_ENDS":"vMRF: SERVICE_PROCESS_ENDS","DEFENSE_STOPPED":"vMRF: DEFENSE_STOPPED","USER_ACCOUNT_LOCKED":"vMRF: USER_ACCOUNT_LOCKED","CONNECTION_SQL_NOT_ESTABLISHED":"vMRF: CONNECTION_SQL_NOT_ESTABLISHED","FALSE_ALARM":"vMRF: FALSE_ALARM","RADIUS SERVER HS":"vMRF: RADIUS SERVER HS","DRM_PACKAGER_IS_NOT_AVAILABLE":"vMRF: DRM_PACKAGER_IS_NOT_AVAILABLE","DRM_LICENSE_BUILDER_IS_NOT_AVAILABLE":"vMRF: DRM_LICENSE_BUILDER_IS_NOT_AVAILABLE","ERROR_WHILE_CREATING_PLAYLIST_MANAGER_FILE":"vMRF: ERROR_WHILE_CREATING_PLAYLIST_MANAGER_FILE","ERROR_WHILE_BUILDING_PLAYLIST_XML_REPRESENTATION":"vMRF: ERROR_WHILE_BUILDING_PLAYLIST_XML_REPRESENTATION","PLAYLIST_FILE_TO_PUBLISH_NOT_FOUND":"vMRF: PLAYLIST_FILE_TO_PUBLISH_NOT_FOUND","COULD_NOT_CONNECT_TO_PVNS_SERVER":"vMRF: COULD_NOT_CONNECT_TO_PVNS_SERVER","HTTP_OR_HTTPCLIENT_EXCEPTION_HAS_OCCURRED":"vMRF: HTTP_OR_HTTPCLIENT_EXCEPTION_HAS_OCCURRED","I/O_ERROR_WHILE_PUBLISHING_PLAYLIST_FILE":"vMRF: I/O_ERROR_WHILE_PUBLISHING_PLAYLIST_FILE","ERROR_WHILE_REQUESTING_SDP_FILE":"vMRF: ERROR_WHILE_REQUESTING_SDP_FILE","ERROR_WHILE_REQUESTING_SDP_FILE:_REMOTE_EXCEPTION":"vMRF: ERROR_WHILE_REQUESTING_SDP_FILE:_REMOTE_EXCEPTION","NO_STREAMING_RESOURCES":"vMRF: NO_STREAMING_RESOURCES","NO_STREAMING_MODULES_REGISTERED":"vMRF: NO_STREAMING_MODULES_REGISTERED","SM_FAILURE":"vMRF: SM_FAILURE","MISSING_FILE_OR_ENCODER":"vMRF: MISSING_FILE_OR_ENCODER","INVALID_RANGE":"vMRF: INVALID_RANGE","THRESHOLD_VALUE_EXCEEDED":"vMRF: THRESHOLD_VALUE_EXCEEDED","TICKET_QUEUE_FULL":"vMRF: TICKET_QUEUE_FULL","PARSING_INITIALIZATION_EXCEPTION":"vMRF: PARSING_INITIALIZATION_EXCEPTION","CUSTOMERCARE_INTERNAL_EXCEPTION":"vMRF: CUSTOMERCARE_INTERNAL_EXCEPTION","PARSING_EXCEPTION":"vMRF: PARSING_EXCEPTION","I/O_PROBLEM":"vMRF: I/O_PROBLEM","INEXISTENT_FILE_OR_FOLDER":"vMRF: INEXISTENT_FILE_OR_FOLDER","FILE_NOT_IN_XML_FORMAT":"vMRF: FILE_NOT_IN_XML_FORMAT","SERVICE_STATE_CHANGE":"vMRF: SERVICE_STATE_CHANGE","MONITORED_FILE_UPDATE_ERROR":"vMRF: MONITORED_FILE_UPDATE_ERROR","MONITORED_RPM_DELETED_ERROR":"vMRF: MONITORED_RPM_DELETED_ERROR","MONITORED_RPM_ADDED_ERROR":"vMRF: MONITORED_RPM_ADDED_ERROR","MONITORED_CHMOD_ERROR":"vMRF: MONITORED_CHMOD_ERROR","MONITORED_CHOWN_ERROR":"vMRF: MONITORED_CHOWN_ERROR","PASSWD_ROOT_ERROR":"vMRF: PASSWD_ROOT_ERROR","PASSWD_ERROR":"vMRF: PASSWD_ERROR","ROOTKIT_ERROR":"vMRF: ROOTKIT_ERROR","STARTUP_ERR_UNDEFINED_PORT":"vMRF: STARTUP_ERR_UNDEFINED_PORT","STARTUP_ERR_FAIL_FIND_HOSTNAME":"vMRF: STARTUP_ERR_FAIL_FIND_HOSTNAME","STARTUP_ERR_CF_MISSING":"vMRF: STARTUP_ERR_CF_MISSING","STARTUP_ERR_FAILED_TO_OPEN_CF":"vMRF: STARTUP_ERR_FAILED_TO_OPEN_CF","STARTUP_ERR_FAILED_TO_BIND_PORT":"vMRF: STARTUP_ERR_FAILED_TO_BIND_PORT","STARTUP_ERR_CFG_UNIT_MISSING":"vMRF: STARTUP_ERR_CFG_UNIT_MISSING","MCTR_INVALID_CODEC_NAME":"vMRF: MCTR_INVALID_CODEC_NAME","RTSP_SERVER_FAILURE":"vMRF: RTSP_SERVER_FAILURE","RTSP_SERVER_QUARANTINE":"vMRF: RTSP_SERVER_QUARANTINE","TRANSCODING_FAILURE":"vMRF: TRANSCODING_FAILURE","FILE_CACHE_FAILURE":"vMRF: FILE_CACHE_FAILURE","STARTUP_ERROR_INITIALIZATION_FAILED":"vMRF: STARTUP_ERROR_INITIALIZATION_FAILED","CONFERENCE_FAILURE":"vMRF: CONFERENCE_FAILURE","PLC_DEGRADATION_LOW":"vMRF: PLC_DEGRADATION_LOW","PLC_DEGRADATION_MEDIUM":"vMRF: PLC_DEGRADATION_MEDIUM","PLC_DEGRADATION_HIGH":"vMRF: PLC_DEGRADATION_HIGH","AUDIO_RESYNCH_LOW":"vMRF: AUDIO_RESYNCH_LOW","AUDIO_RESYNCH_MEDIUM":"vMRF: AUDIO_RESYNCH_MEDIUM","AUDIO_RESYNCH_HIGH":"vMRF: AUDIO_RESYNCH_HIGH","VIDEO_RESYNCH_LOW":"vMRF: VIDEO_RESYNCH_LOW","VIDEO_RESYNCH_MEDIUM":"vMRF: VIDEO_RESYNCH_MEDIUM","VIDEO_RESYNCH_HIGH":"vMRF: VIDEO_RESYNCH_HIGH","PLAY_FAILURES_LOW":"vMRF: PLAY_FAILURES_LOW","PLAY_FAILURES_MEDIUM":"vMRF: PLAY_FAILURES_MEDIUM","PLAY_FAILURES_HIGH":"vMRF: PLAY_FAILURES_HIGH","NOT_ENOUGH_FREE_CONFEREE":"vMRF: NOT_ENOUGH_FREE_CONFEREE","NO_LONGER_FREE_CONFERENCE_ROOM":"vMRF: NO_LONGER_FREE_CONFERENCE_ROOM","STARTUP_ERROR_FAIL_TO_READ_CF":"vMRF: STARTUP_ERROR_FAIL_TO_READ_CF","STARTUP_ERROR_SIP_ADAPTER_INIT":"vMRF: STARTUP_ERROR_SIP_ADAPTER_INIT","STARTUP_ERROR_MONITORING_INIT":"vMRF: STARTUP_ERROR_MONITORING_INIT","REGISTER_ERROR_FAILURE":"vMRF: REGISTER_ERROR_FAILURE","DRI_ERROR_FAILURE":"vMRF: DRI_ERROR_FAILURE","STARTUP_ERROR_STACK_CONFIGURATION":"vMRF: STARTUP_ERROR_STACK_CONFIGURATION","STARTUP_ERROR_CONF":"vMRF: STARTUP_ERROR_CONF","STARTUP_ERROR_UNDEFINED_PORT":"vMRF: STARTUP_ERROR_UNDEFINED_PORT","HOST_REMOVED":"vMRF: HOST_REMOVED","INTERCEPT_THRESHOLD_NB_DIALOG_ALLOCATED":"vMRF: INTERCEPT_THRESHOLD_NB_DIALOG_ALLOCATED","STARTUP_ERROR_STACK_CONF":"vMRF: STARTUP_ERROR_STACK_CONF","STARTUP_ERROR_CONFIGURATION":"vMRF: STARTUP_ERROR_CONFIGURATION","STARTUP_ERROR_FAILED_TO_RETRIEVE_HOSTNAME":"vMRF: STARTUP_ERROR_FAILED_TO_RETRIEVE_HOSTNAME","LEVEL_WARNING_CALL":"vMRF: LEVEL_WARNING_CALL","LEVEL_ALARM_MINOR_CALL":"vMRF: LEVEL_ALARM_MINOR_CALL","LEVEL_ALARM_MAJOR_CALL":"vMRF: LEVEL_ALARM_MAJOR_CALL","LEVEL_ALARM_MRFPoutOfService":"vMRF: LEVEL_ALARM_MRFPoutOfService","MRFP_CALL_REJECTED_Threshold #1":"vMRF: MRFP_CALL_REJECTED_Threshold #1","MRFP_CALL_REJECTED_Threshold #2":"vMRF: MRFP_CALL_REJECTED_Threshold #2","MRFP_CALL_REJECTED_Threshold #3":"vMRF: MRFP_CALL_REJECTED_Threshold #3","MRFP_CALL_RETRIED_Threshold #1":"vMRF: MRFP_CALL_RETRIED_Threshold #1","MRFP_CALL_RETRIED_Threshold #2":"vMRF: MRFP_CALL_RETRIED_Threshold #2","MRFP_CALL_RETRIED_Threshold #3":"vMRF: MRFP_CALL_RETRIED_Threshold #3","STARTUP_PUB_FILE_NOT_PRESENT":"vMRF: STARTUP_PUB_FILE_NOT_PRESENT","STARTUP_INF_FILE_NOT_PRESENT":"vMRF: STARTUP_INF_FILE_NOT_PRESENT","STARTUP_LIC_FILE_NOT_PRESENT":"vMRF: STARTUP_LIC_FILE_NOT_PRESENT","GENERIC_HARDWARE_PROBLEM":"vMRF: GENERIC_HARDWARE_PROBLEM","HARD_DRIVE_PROBLEM":"vMRF: HARD_DRIVE_PROBLEM","NETWORK_LINK_PROBLEM":"vMRF: NETWORK_LINK_PROBLEM","POWER_SUPPLY_PROBLEM":"vMRF: POWER_SUPPLY_PROBLEM","SMART_HARD_DRIVE_PROBLEM":"vMRF: SMART_HARD_DRIVE_PROBLEM","STARTUP_ERROR":"vMRF: STARTUP_ERROR","RESOURCE_NOT_ACCESSIBLE":"vMRF: RESOURCE_NOT_ACCESSIBLE","RESOURCE_ACCESSIBLE":"vMRF: RESOURCE_ACCESSIBLE","RESOURCE_FULL":"vMRF: RESOURCE_FULL","DRI_ALARM":"vMRF: DRI_ALARM","REGISTER_ERROR_CCF":"vMRF: REGISTER_ERROR_CCF","REGISTER_ERROR_EXTERNAL":"vMRF: REGISTER_ERROR_EXTERNAL","TIMEOUT_ERROR":"vMRF: TIMEOUT_ERROR","VXML_ERROR":"vMRF: VXML_ERROR","A Network Element is no longer available due to a connection failure":"vMVM: A Network Element is no longer available due to a connection failure","A MetaSphere server is reporting a fault with the configuration of its connection to MetaView":"vMVM: A MetaSphere server is reporting a fault with the configuration of its connection to MetaView","Configured OBS IPs don't match available OBS nodes. Configured but unavailable nodes include: [<IP address>]. Real nodes not configured include: []":"vMVM: Configured OBS IPs don't match available OBS nodes. Configured but unavailable nodes include: [<IP address>]. Real nodes not configured include: []","Service Assurance Server <IP address> cannot be contacted":"vMVM: Service Assurance Server <IP address> cannot be contacted","The primary MetaView Director has lost contact with the backup MetaView Director":"vMVM: The primary MetaView Director has lost contact with the backup MetaView Director","The active server has lost connection to the standby":"vMVM: The active server has lost connection to the standby","CrashCounter":"vprobes-vBE-Processing: CrashCounter","IsAlive":"vprobes-vBE-Processing: IsAlive","SwRestart":"vprobes-vLB: SwRestart","Repeated exceptions have occurred.":"vSBC-Metaswitch: Repeated exceptions have occurred.","A licensing limit is close to capacity.":"vSBC-Metaswitch: A licensing limit is close to capacity.","One or more feature packs have been breached.":"vSBC-Metaswitch: One or more feature packs have been breached.","The grace period on this Perimeta system will expire in less than 48 hours, after which calls will not be processed.":"vSBC-Metaswitch: The grace period on this Perimeta system will expire in less than 48 hours, after which calls will not be processed.","The grace period on this Perimeta system will expire in less than 7 days, after which calls will not be processed.":"vSBC-Metaswitch: The grace period on this Perimeta system will expire in less than 7 days, after which calls will not be processed.","The license on this Perimeta system will expire in less than 4 weeks.":"vSBC-Metaswitch: The license on this Perimeta system will expire in less than 4 weeks.","A Perimeta blade has become unlicensed.":"vSBC-Metaswitch: A Perimeta blade has become unlicensed.","Perimeta is licensed with a bypass certificate, which is valid until the time displayed.":"vSBC-Metaswitch: Perimeta is licensed with a bypass certificate, which is valid until the time displayed.","The number of licensed instances exceeded a threshold of the licensed limit.":"vSBC-Metaswitch: The number of licensed instances exceeded a threshold of the licensed limit.","The software token on the primary Distributed Capacity Manager will expire on the displayed date.":"vSBC-Metaswitch: The software token on the primary Distributed Capacity Manager will expire on the displayed date.","A capacity limit on the license installed on this Perimeta system does not match the largest limit across all systems in the deployment.":"vSBC-Metaswitch: A capacity limit on the license installed on this Perimeta system does not match the largest limit across all systems in the deployment.","An adjacency has voice quality alerts.":"vSBC-Metaswitch: An adjacency has voice quality alerts.","The number of calls being audited is congested.":"vSBC-Metaswitch: The number of calls being audited is congested.","Session Controller is rejecting calls because there is no valid active call policy set configured.":"vSBC-Metaswitch: Session Controller is rejecting calls because there is no valid active call policy set configured.","A call policy set is inactive because it has been misconfigured.":"vSBC-Metaswitch: A call policy set is inactive because it has been misconfigured.","Session Controller is inactive and rejecting calls.":"vSBC-Metaswitch: Session Controller is inactive and rejecting calls.","Sources have breached minor or major blacklist thresholds.":"vSBC-Metaswitch: Sources have breached minor or major blacklist thresholds.","Sources are blacklisted.":"vSBC-Metaswitch: Sources are blacklisted.","The blacklisting configuration will change as a result of upgrade and some configured blacklists or alerts will no longer be applied.":"vSBC-Metaswitch: The blacklisting configuration will change as a result of upgrade and some configured blacklists or alerts will no longer be applied.","A large number of downgrades and bans have been created as a result of blacklisting.":"vSBC-Metaswitch: A large number of downgrades and bans have been created as a result of blacklisting.","Session Controller is unable to track further sources for blacklisting.":"vSBC-Metaswitch: Session Controller is unable to track further sources for blacklisting.","A software protection switch was triggered.":"vSBC-Metaswitch: A software protection switch was triggered.","A disk area on a processor blade is nearly full.":"vSBC-Metaswitch: A disk area on a processor blade is nearly full.","Memory use is very high.":"vSBC-Metaswitch: Memory use is very high.","The primary processor-blade has lost contact with the backup.":"vSBC-Metaswitch: The primary processor-blade has lost contact with the backup.","An efix or patch has been applied to this system containing diagnostic versions of some software libraries.":"vSBC-Metaswitch: An efix or patch has been applied to this system containing diagnostic versions of some software libraries.","A software protection switch (SPS) was triggered. Call and registration state was lost.":"vSBC-Metaswitch: A software protection switch (SPS) was triggered. Call and registration state was lost.","The Ethernet Heartbeat between primary and backup processors has failed.":"vSBC-Metaswitch: The Ethernet Heartbeat between primary and backup processors has failed.","The Backplane Heartbeat between primary and backup processors has failed.":"vSBC-Metaswitch: The Backplane Heartbeat between primary and backup processors has failed.","A disk area on a processor blade reported an error.":"vSBC-Metaswitch: A disk area on a processor blade reported an error.","The system is upgrading.":"vSBC-Metaswitch: The system is upgrading.","An error with NTP functionality has been detected.":"vSBC-Metaswitch: An error with NTP functionality has been detected.","One or more users are locked out of the system.":"vSBC-Metaswitch: One or more users are locked out of the system.","The Craft Terminal user FTP directory on a processor blade is nearly full.":"vSBC-Metaswitch: The Craft Terminal user FTP directory on a processor blade is nearly full.","A scheduled configuration snapshot has failed.":"vSBC-Metaswitch: A scheduled configuration snapshot has failed.","The Session Controller is stopping as a result of administrator action.":"vSBC-Metaswitch: The Session Controller is stopping as a result of administrator action.","A Session Controller processor blade is stopping as a result of administrator action.":"vSBC-Metaswitch: A Session Controller processor blade is stopping as a result of administrator action.","An object could not be activated because its service address does not exist or is not fully specified.":"vSBC-Metaswitch: An object could not be activated because its service address does not exist or is not fully specified.","The hardware on a processor does not meet minimum requirements.":"vSBC-Metaswitch: The hardware on a processor does not meet minimum requirements.","The hardware expectations of the two processors are not the same.":"vSBC-Metaswitch: The hardware expectations of the two processors are not the same.","The read speed of the main hard disk on a processor blade is too slow.":"vSBC-Metaswitch: The read speed of the main hard disk on a processor blade is too slow.","An error has occurred reading from the hard disk on a processor blade.":"vSBC-Metaswitch: An error has occurred reading from the hard disk on a processor blade.","Backup and primary processor-blades have an inconsistent system role.":"vSBC-Metaswitch: Backup and primary processor-blades have an inconsistent system role.","Event: The system encountered a critical error and had to restart.":"vSBC-Metaswitch: Event: The system encountered a critical error and had to restart.","Event: A RADIUS server failed to respond to an authentication request.":"vSBC-Metaswitch: Event: A RADIUS server failed to respond to an authentication request.","Event: All configured RADIUS servers failed to respond to authentication requests.":"vSBC-Metaswitch: Event: All configured RADIUS servers failed to respond to authentication requests.","Event: The number of CPUs has changed.":"vSBC-Metaswitch: Event: The number of CPUs has changed.","Event: A user has been automatically deleted":"vSBC-Metaswitch: Event: A user has been automatically deleted","The primary processor blade has lost management connectivity":"vSBC-Metaswitch: The primary processor blade has lost management connectivity","Event: A processor blade is running with DPDK mode disabled when DPDK mode is,expected.":"vSBC-Metaswitch: Event: A processor blade is running with DPDK mode disabled when DPDK mode is,expected.","Event: Processor blade %1 is running with DPDK mode disabled when DPDK mode may be possible.":"vSBC-Metaswitch: Event: Processor blade %1 is running with DPDK mode disabled when DPDK mode may be possible.","Perimeta is attempting to resend cached billing records.":"vSBC-Metaswitch: Perimeta is attempting to resend cached billing records.","The Rf billing cache is full.":"vSBC-Metaswitch: The Rf billing cache is full.","The inbound call queue is congested.":"vSBC-Metaswitch: The inbound call queue is congested.","A configured realm group contains realms that are not available to the SBC.":"vSBC-Metaswitch: A configured realm group contains realms that are not available to the SBC.","An allowed MSC configuration is not connected to any physical MSCs.":"vSBC-Metaswitch: An allowed MSC configuration is not connected to any physical MSCs.","A SIP Peer has stopped responding to SIP OPTIONS pings.  MSW: 20160303: Alarm text is changed in v3.9 software to read: \\"An adjacency has lost connectivity, according to SIP OPTIONS pings\\"":"vSBC-Metaswitch: A SIP Peer has stopped responding to SIP OPTIONS pings.  MSW: 20160303: Alarm text is changed in v3.9 software to read: \\"An adjacency has lost connectivity, according to SIP OPTIONS pings\\"","An adjacency has failed as the listen socket could not be created. Check for configuration mismatches with the associated service interface.":"vSBC-Metaswitch: An adjacency has failed as the listen socket could not be created. Check for configuration mismatches with the associated service interface.","No suitable DNS records were found for a peer group's DNS hostname.":"vSBC-Metaswitch: No suitable DNS records were found for a peer group's DNS hostname.","One or more SIP peers from a peer group have stopped responding to SIP OPTIONS pings":"vSBC-Metaswitch: One or more SIP peers from a peer group have stopped responding to SIP OPTIONS pings","An adjacency has failed as its service network does not match the service network on its associated peer group.":"vSBC-Metaswitch: An adjacency has failed as its service network does not match the service network on its associated peer group.","An adjacency has failed as its configured TLS certificate could not be found.":"vSBC-Metaswitch: An adjacency has failed as its configured TLS certificate could not be found.","The caching function has not been initialized properly.":"vSBC-Metaswitch: The caching function has not been initialized properly.","An adjacency has failed as the listen socket could not be created.":"vSBC-Metaswitch: An adjacency has failed as the listen socket could not be created.","An adjacency is congested and may be rejecting calls.":"vSBC-Metaswitch: An adjacency is congested and may be rejecting calls.","There is an issue with a Diameter peer.":"vSBC-Metaswitch: There is an issue with a Diameter peer.","A realm is no longer reachable via any configured peers.":"vSBC-Metaswitch: A realm is no longer reachable via any configured peers.","An FQDN for a configured Diameter peer has failed to resolve to a valid IP address.":"vSBC-Metaswitch: An FQDN for a configured Diameter peer has failed to resolve to a valid IP address.","One or more peers resolved from a DNS lookup of a configured peer's address cannot be contacted":"vSBC-Metaswitch: One or more peers resolved from a DNS lookup of a configured peer's address cannot be contacted","An interface ARP or NDP probe has failed.":"vSBC-Metaswitch: An interface ARP or NDP probe has failed.","One or more IP address conflicts have been detected on service interfaces with zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.":"vSBC-Metaswitch: One or more IP address conflicts have been detected on service interfaces with zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.","One or more IP address conflicts have been detected on service interfaces with non-zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.":"vSBC-Metaswitch: One or more IP address conflicts have been detected on service interfaces with non-zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.","An interface device is running below the expected speed. This alarm was originally triggered by a probe failure on a service interface.":"vSBC-Metaswitch: An interface device is running below the expected speed. This alarm was originally triggered by a probe failure on a service interface.","An interface device is running above the expected speed.":"vSBC-Metaswitch: An interface device is running above the expected speed.","An IP address conflict has been detected on a management interface.":"vSBC-Metaswitch: An IP address conflict has been detected on a management interface.","An interface ICMP probe has failed.":"vSBC-Metaswitch: An interface ICMP probe has failed.","A High-Availability link has detected a connectivity issue.":"vSBC-Metaswitch: A High-Availability link has detected a connectivity issue.","An HA-link device is being reported as underspeed.":"vSBC-Metaswitch: An HA-link device is being reported as underspeed.","An IP address conflict has been detected on a replication interface.":"vSBC-Metaswitch: An IP address conflict has been detected on a replication interface.","The Session Controller has started.":"vSBC-Metaswitch: The Session Controller has started.","A statistic exceeded its configured thresholds.":"vSBC-Metaswitch: A statistic exceeded its configured thresholds.","One or more statistic has not been retrieved at least 3 times in a row.":"vSBC-Metaswitch: One or more statistic has not been retrieved at least 3 times in a row.","A Refresh Alarms request was triggered. Alarms not re-raised will be cleared in 5 minutes.":"vSBC-Metaswitch: A Refresh Alarms request was triggered. Alarms not re-raised will be cleared in 5 minutes.","A statistic has exceeded its configured thresholds.":"vSBC-Metaswitch: A statistic has exceeded its configured thresholds.","A Fallback Operation will soon be started":"vSBG: A Fallback Operation will soon be started","BRM, Auto Export Backup Failed":"vSBG: BRM, Auto Export Backup Failed","BRM, Scheduled Backup Failed":"vSBG: BRM, Scheduled Backup Failed","COM SA, AMF Component Cleanup Failed":"vSBG: COM SA, AMF Component Cleanup Failed","COM SA, AMF Component Instantiation Failed":"vSBG: COM SA, AMF Component Instantiation Failed","COM SA, AMF SI Unassigned":"vSBG: COM SA, AMF SI Unassigned","COM SA, CLM Cluster Node Unavailable":"vSBG: COM SA, CLM Cluster Node Unavailable","COM SA, MDF Detected Model Error":"vSBG: COM SA, MDF Detected Model Error","COM SA, Proxy Status of a Component Changed to Unproxied":"vSBG: COM SA, Proxy Status of a Component Changed to Unproxied","File Management, Number of Files in FileGroup Exceeded":"vSBG: File Management, Number of Files in FileGroup Exceeded","File Management, Max Size in FileGroup Exceeded":"vSBG: File Management, Max Size in FileGroup Exceeded","LOTC Disk Replication Communication":"vSBG: LOTC Disk Replication Communication","LOTC Disk Replication Consistency":"vSBG: LOTC Disk Replication Consistency","LOTC Disk Usage":"vSBG: LOTC Disk Usage","LOTC memory Usage":"vSBG: LOTC memory Usage","LOTC Time Synchronization":"vSBG: LOTC Time Synchronization","SBG, BGF Control Link Down":"vSBG: SBG, BGF Control Link Down","SBG, BGF Control Link Disabled":"vSBG: SBG, BGF Control Link Disabled","SBG, BGF Control Link Enabled":"vSBG: SBG, BGF Control Link Enabled","SBG, BGF Control Link Remote Locked":"vSBG: SBG, BGF Control Link Remote Locked","SBG, Charging Data Storage Maximum Records Reached":"vSBG: SBG, Charging Data Storage Maximum Records Reached","SBG, Charging Server Rejects Charging Data":"vSBG: SBG, Charging Server Rejects Charging Data","SBG, Excessive Packet Rate Detected ":"vSBG: SBG, Excessive Packet Rate Detected ","SBG, High Amount of Malformed Packets Received":"vSBG: SBG, High Amount of Malformed Packets Received","SBG, High Amount of STUN Packets Detected":"vSBG: SBG, High Amount of STUN Packets Detected","SBG, High Amount of TCP SYN Packets Received":"vSBG: SBG, High Amount of TCP SYN Packets Received","SBG, High Amount of UDP Packets Received ":"vSBG: SBG, High Amount of UDP Packets Received ","SBG, IP Address Blocked Due to Excessive Packet Rate":"vSBG: SBG, IP Address Blocked Due to Excessive Packet Rate","SBG, Lost Connectivity to Diameter Server":"vSBG: SBG, Lost Connectivity to Diameter Server","SBG, Mated Pair out of Service":"vSBG: SBG, Mated Pair out of Service","SBG, Network Unavailable for Media Handling":"vSBG: SBG, Network Unavailable for Media Handling","SBG, Non-emergency Call Released to Free Resources for Emergency Call":"vSBG: SBG, Non-emergency Call Released to Free Resources for Emergency Call","SBG, Not Enough Disk Space for Storing Charging Data":"vSBG: SBG, Not Enough Disk Space for Storing Charging Data","SBG, Payload Mated Pair Failure":"vSBG: SBG, Payload Mated Pair Failure","SBG, Payload Processor Failure":"vSBG: SBG, Payload Processor Failure","SBG, Processor Overloaded":"vSBG: SBG, Processor Overloaded","SBG, Registered User Set in Quarantine":"vSBG: SBG, Registered User Set in Quarantine","SBG, Registration Contacts Exceed Configured Threshold":"vSBG: SBG, Registration Contacts Exceed Configured Threshold","SBG, Sequential Restart Initiated":"vSBG: SBG, Sequential Restart Initiated","SBG, SIP Abuse Detected":"vSBG: SBG, SIP Abuse Detected","SBG, SIP Network Locked":"vSBG: SBG, SIP Network Locked","SBG, SIP Next Hop Reachable":"vSBG: SBG, SIP Next Hop Reachable","SBG, SIP Next Hop Unreachable":"vSBG: SBG, SIP Next Hop Unreachable","SBG, SIP Request Rejected by Network Throttling":"vSBG: SBG, SIP Request Rejected by Network Throttling","SBG, TLS Certificate Imported":"vSBG: SBG, TLS Certificate Imported","SBG, Trace Recording Session Number Limit Reached":"vSBG: SBG, Trace Recording Session Number Limit Reached","SBG, Trace Session Deactivated":"vSBG: SBG, Trace Session Deactivated","SBG, Trace Session Times Out":"vSBG: SBG, Trace Session Times Out","SBG, Unknown Media Type or Payload Type":"vSBG: SBG, Unknown Media Type or Payload Type"}
+#
+# if action.test.override is true, then any action will be marked as test=true (even if incoming action request had test=false); otherwise, test flag will be unchanged on the action request
+action.test.override=false
+# if action.insert.test.event is true, then insert event even if the action is set to test
+action.insert.test.event=false
+CLDS_SERVICE_CACHE_MAX_SECONDS=72000
+
diff --git a/src/main/resources/clds/clds-users.properties b/src/main/resources/clds/clds-users.properties
new file mode 100644 (file)
index 0000000..f4b11e8
--- /dev/null
@@ -0,0 +1,7 @@
+# Please define the CLDS users here
+# The format is <username>|<password>|<role>
+# Two types of roles are used:read, all
+# -    read: can only read template and closed loop design
+# - all: can read and update template and closed loop related design 
+#
+user|password|all
\ No newline at end of file
diff --git a/src/main/resources/clds/globalClds.properties b/src/main/resources/clds/globalClds.properties
new file mode 100644 (file)
index 0000000..7c3e10e
--- /dev/null
@@ -0,0 +1 @@
+globalCldsProps ={"collector":{"topicPublishes":{"DCAE-COLLECTOR-UCSNMP":"DCAE-COLLECTOR-UCSNMP"}},"string_match":{"topicPublishes":{"DCAE-CL-EVENT":"DCAE-CL-EVENT"},"aaiMatchingFields":{"cloud-region.identity-url":"cloud-region.identity-url","complex.city":"complex.city","complex.physical-location-id":"complex.physical-location-id","complex.state":"complex.state","generic-vnf.service-id":"generic-vnf.service-id","generic-vnf.vnf-name":"generic-vnf.vnf-name","generic-vnf.vnf-type":"generic-vnf.vnf-type","tenant.tenant-id":"tenant.tenant-id","vserver.in-maint":"vserver.in-maint","vserver.is-closed-loop-disabled":"vserver.is-closed-loop-disabled","vserver.l-interface.interface-name":"vserver.l-interface.interface-name","vserver.l-interface.l3-interface-ipv4-address-list.l3-inteface-ipv4-address":"vserver.l-interface.l3-interface-ipv4-address-list.l3-inteface-ipv4-address","vserver.l-interface.l3-interface-ipv6-address-list.l3-inteface-ipv6-address":"vserver.l-interface.l3-interface-ipv6-address-list.l3-inteface-ipv6-address","vserver.l-interface.network-name":"vserver.l-interface.network-name","vserver.prov-status":"vserver.prov-status","vserver.selflink":"vserver.selflink","vserver.vserver-id":"vserver.vserver-id","vserver.vserver-name":"vserver.vserver-name"},"aaiSendFields":{"cloud-region.identity-url":"cloud-region.identity-url","complex.city":"complex.city","complex.physical-location-id":"complex.physical-location-id","complex.state":"complex.state","generic-vnf.service-id":"generic-vnf.service-id","generic-vnf.vnf-name":"generic-vnf.vnf-name","generic-vnf.vnf-type":"generic-vnf.vnf-type","tenant.tenant-id":"tenant.tenant-id","vserver.in-maint":"vserver.in-maint","vserver.is-closed-loop-disabled":"vserver.is-closed-loop-disabled","vserver.l-interface.interface-name":"vserver.l-interface.interface-name","vserver.l-interface.l3-interface-ipv4-address-list.l3-inteface-ipv4-address":"vserver.l-interface.l3-interface-ipv4-address-list.l3-inteface-ipv4-address","vserver.l-interface.l3-interface-ipv6-address-list.l3-inteface-ipv6-address":"vserver.l-interface.l3-interface-ipv6-address-list.l3-inteface-ipv6-address","vserver.l-interface.network-name":"vserver.l-interface.network-name","vserver.prov-status":"vserver.prov-status","vserver.selflink":"vserver.selflink","vserver.vserver-id":"vserver.vserver-id","vserver.vserver-name":"vserver.vserver-name"},"eventSourceType":{"f5BigIP":"f5BigIP","vSBG_Alarms":"vSBG_Alarms","vCTS_Alarms":"vCTS_Alarms"},"eventSeverity":{"NORMAL":"NORMAL","not-NORMAL":"not-NORMAL","OK":"OK","WARNING":"WARNING","MINOR":"MINOR","MAJOR":"MAJOR","CRITICAL":"CRITICAL"},"timeWindow":0,"ageLimit":1600,"outputEventName":{"":"","ONSET":"ONSET","ABATED":"ABATED"},"createClosedLoopEventId":{"Initial":"Initial","Close":"Close"}},"tca":{"tname":"New_Set","tcaInt":"1","tcaVio":"1","tcaSev":{"Normal":"Normal","Critical":"Critical","Major":"Major","Minor":"Minor","Warning":"Warning"},"fieldPath":{"FIELDPATH_test_1":"FIELDPATH_test_1","FIELDPATH_test_2":"FIELDPATH_test_2"},"operator":{">":"GREATER THAN","=":"EQUAL","<":"LESS THAN"},"opsPolicy":{"POLICY_test_X":"POLICY_test_X","POLICY_test_Y":"POLICY_test_Y"}},"global":{"location":{"SNDGCA64":"San Diego SAN3","ALPRGAED":"Alpharetta PDK1","LSLEILAA":"Lisle DPA3","MDTWNJC1":"FTL_C_location1","MDTWNJC2":"FTL_C_location2","MDTWNJ21":"FTL_L_location1","MDTWNJ22":"FTL_L_location2","RDM2WAGPLCP":"ISTFTL_location","RDM3":"RDM3WAGPLCP"}},"policy":{"pname":"0","timeout":345,"recipe":{"":"","restart":"Restart","rebuild":"Rebuild","migrate":"Migrate","healthCheck":"Health Check"},"maxRetries":"3","retryTimeLimit":180,"resource":{"vCTS":"vCTS","v3CDB":"v3CDB","vUDR":"vUDR","vCOM":"vCOM","vRAR":"vRAR","vLCS":"vLCS","vUDR-BE":"vUDR-BE","vDBE":"vDBE"},"parentPolicyConditions":{"Failure_Retries":"Failure: Max Retries Exceeded","Failure_Timeout":"Failure: Time Limit Exceeded","Failure_Exception":"Failure: Exception","Failure":"Failure: Other","Success":"Success"}},"shared":{"byService":{"":{"vf":{"":""},"location":{"":""},"alarmCondition":{"":""}}},"byVf":{"":{"vfc":{"":""}}}}}}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..05149dc
--- /dev/null
@@ -0,0 +1,29 @@
+<configuration scan="true" scanPeriod="3 seconds" debug="false">
+
+    <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
+
+    <property resource="application.properties"/>
+
+    <property name="defaultPattern"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS} $ threadId: {PID:- } %-5level  namespace:${namespace} %logger{20} [ hostname: %X{hostname} serviceName: %X{serviceName} version: %X{version} transactionId: %X{transactionId} requestTimeStamp: %X{requestTimestamp}  responseTimeStamp: %X{responseTimestamp} duration: %X{duration}] %m%n"/>
+
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>root.log</file>
+        <append>false</append>
+        <encoder>
+            <pattern>${defaultPattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${defaultPattern}</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="FILE"/>
+    </root>
+
+</configuration>
diff --git a/src/main/resources/logmessages.properties b/src/main/resources/logmessages.properties
new file mode 100644 (file)
index 0000000..d1e3678
--- /dev/null
@@ -0,0 +1,27 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+LOGSERVICE_EMAIL_ERROR=SERVICE0007I|Exception while sending e-mail:{0}|Resolution needed|action is required
+LOGSERVICE_EMAIL_CLASS=SERVICE0008I|classUrl.getFile:{0}|Resolution needed|action is required
+LOGSERVICE_EMAIL_CLASS_NULL=SERVICE0009I|classUrl is NULL|Resolution needed|action is required
+PROCESS_INSTANCE_ID=SERVICE0010I|Process Instance Id:{0}|No resolution needed|No action is required
diff --git a/src/main/resources/system.properties b/src/main/resources/system.properties
new file mode 100644 (file)
index 0000000..2570824
--- /dev/null
@@ -0,0 +1,37 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+# If the environment property system_properties_path contains a path to a file  , System properties created using the file. If the environment variable not present, system.properties in the class path is used for system property creation 
+
+com.att.eelf.logging.file=classpath:/logback.xml
+
+# change as per logback.xml path
+com.att.eelf.logging.path=./
+logging.config=classpath:/logback.xml
+
+
+#csiEnable value is false by default. If csiEnable property is set to true, audit and performance logs are send to the WMQ Queue
+csiEnable=true
+com.ibm.mq.cfg.useIBMCipherMappings=false
+
+com.att.ajsc.app.prop.path=./
diff --git a/src/main/resources/xsl/clds-bpmn-transformer.xsl b/src/main/resources/xsl/clds-bpmn-transformer.xsl
new file mode 100644 (file)
index 0000000..94af952
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL">
+<!--
+  ** clds-bpmn-transformer.xsl
+  -->
+
+    <xsl:output method="text" indent="no" omit-xml-declaration="yes" />
+    <xsl:strip-space elements="*"/>
+
+       <!-- by default copy all attributes and elements -->
+       <xsl:template match="/bpmn2:definitions/bpmn2:process">
+
+                <xsl:text>{"collector":[</xsl:text>
+                <xsl:for-each select="bpmn2:collector" >
+                       <xsl:call-template name="network-element" />
+                </xsl:for-each>
+                <xsl:text>],</xsl:text>
+
+                <xsl:text>"stringMatch":[</xsl:text>
+                <xsl:for-each select="bpmn2:stringMatch" >
+                       <xsl:call-template name="network-element" />
+                </xsl:for-each>
+                <xsl:text>],</xsl:text>
+
+                <xsl:text>"policy":[</xsl:text>
+                <xsl:for-each select="bpmn2:policy" >
+                       <xsl:call-template name="network-element" />
+                </xsl:for-each>
+                <xsl:text>],</xsl:text>
+                
+                <xsl:text>"tca":[</xsl:text>
+                <xsl:for-each select="bpmn2:tCA" >
+                       <xsl:call-template name="network-element" />
+                </xsl:for-each>
+                <xsl:text>]</xsl:text>
+                
+                <xsl:text>}</xsl:text>
+       </xsl:template>
+
+       <xsl:template name="network-element">
+               <xsl:variable name="incoming" select="./bpmn2:incoming"/>
+
+               <xsl:text>{"id":"</xsl:text>
+               <xsl:value-of select="./@id"/>
+               <xsl:text>", "from":"</xsl:text>
+               <xsl:value-of select="../bpmn2:sequenceFlow[@id=$incoming]/@sourceRef"/>
+               <xsl:text>"}</xsl:text>
+               <xsl:if test="not(position()=last())">, </xsl:if>
+       </xsl:template>
+
+</xsl:stylesheet>
diff --git a/src/test/java/org/onap/clamp/clds/AbstractIT.java b/src/test/java/org/onap/clamp/clds/AbstractIT.java
new file mode 100644 (file)
index 0000000..873c852
--- /dev/null
@@ -0,0 +1,25 @@
+package org.onap.clamp.clds;
+
+import org.junit.BeforeClass;
+import org.onap.clamp.clds.client.PolicyClient;
+import org.onap.clamp.clds.model.refprop.RefProp;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+
+/**
+ * Created by j on 6/16/17.
+ */
+@ActiveProfiles("clamp-default")
+public abstract class AbstractIT {
+
+    @Autowired
+    protected RefProp refProp;
+    @Autowired
+    protected PolicyClient policyClient;
+
+    @BeforeClass
+    public static void oneTimeSetUp() {
+        System.setProperty("AJSC_CONF_HOME", System.getProperty("user.dir") + "/src/it/resources/");
+        System.setProperty("CLDS_DCAE_URL", "http://localhost:13786/cl-dcae-services");
+    }
+}
diff --git a/src/test/java/org/onap/clamp/clds/client/req/SdcReqTest.java b/src/test/java/org/onap/clamp/clds/client/req/SdcReqTest.java
new file mode 100644 (file)
index 0000000..f4d693f
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.client.req;
+
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.clamp.clds.client.SdcCatalogServices;
+import org.onap.clamp.clds.model.CldsAsdcResource;
+import org.onap.clamp.clds.model.CldsAsdcServiceDetail;
+import org.onap.clamp.clds.model.prop.Global;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Created by Julien Bertozzi on 6/20/17.
+ */
+public class SdcReqTest {
+
+    String baseUrl = "AYBABTU";
+    String serviceInvariantUUID = "serviceInvariantUUID";
+
+    @Test
+    public void getAsdcReqUrlsListNoGlobalPropTest() throws Exception {
+        ModelProperties prop = mock(ModelProperties.class);
+        SdcCatalogServices sdcCatalogServices = mock(SdcCatalogServices.class);
+        DelegateExecution delegateExecution = mock(DelegateExecution.class);
+        Global global = mock(Global.class);
+        CldsAsdcServiceDetail cldsAsdcServiceDetail = mock(CldsAsdcServiceDetail.class);
+        CldsAsdcResource cldsAsdcResource = mock(CldsAsdcResource.class);
+        List<CldsAsdcResource> cldsAsdcResources = new ArrayList<>();
+        cldsAsdcResources.add(cldsAsdcResource);
+        List<String> resourceVf = new ArrayList<>();
+        resourceVf.add(serviceInvariantUUID);
+
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(prop.getGlobal()).thenReturn(global);
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(global.getService()).thenReturn(serviceInvariantUUID);
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(sdcCatalogServices.getCldsAsdcServiceDetailFromJson(null)).thenReturn(cldsAsdcServiceDetail);
+        when(global.getResourceVf()).thenReturn(new ArrayList<>());
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(cldsAsdcServiceDetail.getResources()).thenReturn(cldsAsdcResources);
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(cldsAsdcResource.getResoucreType()).thenReturn("VF");
+        Assert.assertTrue(SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution).isEmpty());
+
+        when(global.getResourceVf()).thenReturn(resourceVf);
+        when(cldsAsdcResource.getResourceInvariantUUID()).thenReturn(serviceInvariantUUID);
+        when(cldsAsdcResource.getResourceInstanceName()).thenReturn("Resource instance name");
+        List<String> expected = new ArrayList<>();
+        expected.add("AYBABTU/null/resourceInstances/resourceinstancename/artifacts");
+        Assert.assertEquals(expected, SdcReq.getAsdcReqUrlsList(prop, baseUrl, sdcCatalogServices, delegateExecution));
+    }
+}
diff --git a/src/test/java/org/onap/clamp/clds/it/AsdcIT.java b/src/test/java/org/onap/clamp/clds/it/AsdcIT.java
new file mode 100644 (file)
index 0000000..d616b7e
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.it;
+
+import org.onap.clamp.clds.AbstractIT;
+import org.onap.clamp.clds.client.req.SdcReq;
+import org.onap.clamp.clds.model.CldsEvent;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.transform.TransformUtil;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Test DCAE API in org.onap.clamp.ClampDesigner.client package - replicate DCAE Delegates in test.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class AsdcIT extends AbstractIT {
+
+    @Test
+    public void testBlueprint() throws Exception {
+        String modelProp = TransformUtil.getResourceAsString("example/modelProp.json");
+        String modelBpmnProp = TransformUtil.getResourceAsString("example/modelBpmnProp.json");
+        String modelName = "example-model06";
+        String controlName = "ClosedLoop-FRWL-SIG04-1582f840-test-test-1234-005056a9d756";
+        String docText = TransformUtil.getResourceAsString("example/templateProp.json");
+        ModelProperties prop = new ModelProperties(modelName, controlName, CldsEvent.ACTION_SUBMIT, modelBpmnProp, modelProp);
+        String blueprint = SdcReq.formatBlueprint(refProp, prop, docText);
+        System.out.println("blueprint=" + blueprint);
+    }
+
+}
diff --git a/src/test/java/org/onap/clamp/clds/it/DcaeIT.java b/src/test/java/org/onap/clamp/clds/it/DcaeIT.java
new file mode 100644 (file)
index 0000000..aef4c64
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.it;
+
+import org.onap.clamp.clds.AbstractIT;
+import org.onap.clamp.clds.client.req.DcaeReq;
+import org.onap.clamp.clds.model.CldsEvent;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.onap.clamp.clds.transform.TransformUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Test DCAE API in org.onap.clamp.ClampDesigner.client package - replicate DCAE Delegates in test.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class DcaeIT extends AbstractIT {
+
+    @Test
+    public void testDcaeReq() throws Exception {
+        String modelProp = TransformUtil.getResourceAsString("example/modelProp.json");
+        String modelBpmnProp = TransformUtil.getResourceAsString("example/modelBpmnProp.json");
+        String modelName = "example-model";
+        String controlName = "ClosedLoop-FRWL-SIG-1582f840-2881-11e6-b4ec-005056a9d756";
+
+        ModelProperties prop = new ModelProperties(modelName, controlName, CldsEvent.ACTION_SUBMIT, modelBpmnProp, modelProp);
+        String dcaeReq = DcaeReq.format(refProp, prop);
+
+        System.out.println("dcaeReq=" + dcaeReq);
+        System.out.println("dcaeUrl=" + System.getProperty("CLDS_DCAE_URL") + "/" + controlName);
+    }
+
+}
diff --git a/src/test/java/org/onap/clamp/clds/it/PolicyClientIT.java b/src/test/java/org/onap/clamp/clds/it/PolicyClientIT.java
new file mode 100644 (file)
index 0000000..61ee185
--- /dev/null
@@ -0,0 +1,171 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.it;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.clamp.clds.AbstractIT;
+import org.onap.clamp.clds.model.CldsEvent;
+import org.onap.clamp.clds.model.prop.ModelProperties;
+import org.openecomp.policy.api.AttributeType;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.onap.clamp.clds.client.req.OperationalPolicyReq;
+import org.onap.clamp.clds.client.req.StringMatchPolicyReq;
+import org.onap.clamp.clds.model.prop.Policy;
+import org.onap.clamp.clds.model.prop.StringMatch;
+import org.onap.clamp.clds.transform.TransformUtil;
+
+/**
+ * Test Policy API in org.onap.clamp.ClampDesigner.client package - replicate
+ * Policy Delegates in tests.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class PolicyClientIT extends AbstractIT {
+    String modelProp;
+    String modelBpmnProp;
+    String modelName;
+    String controlName;
+
+    @Before
+    public void setUp() throws IOException {
+        modelProp = TransformUtil.getResourceAsString("example/modelProp.json");
+        modelBpmnProp = TransformUtil.getResourceAsString("example/modelBpmnProp.json");
+        modelName = "example-model06";
+        controlName = "ClosedLoop_FRWL_SIG_fad4dcae_e498_11e6_852e_0050568c4ccf";
+    }
+
+    private void createUpdateStringMatch(String actionCd) throws Exception {
+        ModelProperties prop = new ModelProperties(modelName, controlName, actionCd, modelBpmnProp, modelProp);
+        String stringMatchPolicyRequestUuid = UUID.randomUUID().toString();
+        String policyJson = StringMatchPolicyReq.format(refProp, prop);
+        System.out.println("String Match policyJson=" + policyJson);
+        String responseMessage = policyClient.sendMicroService(policyJson, prop, stringMatchPolicyRequestUuid);
+        System.out.println(responseMessage);
+    }
+
+    private void createUpdateOperationalPolicy(String actionCd) throws Exception {
+        ModelProperties prop = new ModelProperties(modelName, controlName, actionCd, modelBpmnProp, modelProp);
+        String operationalPolicyRequestUuid = UUID.randomUUID().toString();
+        Map<AttributeType, Map<String, String>> attributes = OperationalPolicyReq.formatAttributes(refProp, prop);
+        String responseMessage = policyClient.sendBrms(attributes, prop, operationalPolicyRequestUuid);
+        System.out.println(responseMessage);
+    }
+
+    private void createUpdatePolicies(String actionCd) throws Exception {
+        createUpdateStringMatch(actionCd);
+        createUpdateOperationalPolicy(actionCd);
+    }
+
+    private void deleteStringMatchPolicy(String actionCd) throws Exception {
+        ModelProperties prop = new ModelProperties(modelName, controlName, actionCd, modelBpmnProp, modelProp);
+        StringMatch stringMatch = prop.getStringMatch();
+        prop.setCurrentModelElementId(stringMatch.getId());
+        String responseMessage = policyClient.deleteMicrosService(prop);
+        System.out.println(responseMessage);
+    }
+
+    private void deleteOperationalPolicy(String actionCd) throws Exception {
+        ModelProperties prop = new ModelProperties(modelName, controlName, actionCd, modelBpmnProp, modelProp);
+        Policy policy = prop.getPolicy();
+        prop.setCurrentModelElementId(policy.getId());
+        String responseMessage = policyClient.deleteBrms(prop);
+        System.out.println(responseMessage);
+    }
+
+    private void deletePolicies(String actionCd) throws Exception {
+        deleteStringMatchPolicy(actionCd);
+        deleteOperationalPolicy(actionCd);
+    }
+
+    /**
+     * Delete policies so we can start with a clean state. But this is just a
+     * precaution - the policies might not already exists. So ignore errors in
+     * attempting to do this.
+     * 
+     * @param actionCd
+     */
+    private void cleanUpPolicies(String actionCd) {
+        try {
+            deleteStringMatchPolicy(actionCd);
+        } catch (Exception e) {
+            System.err.println(
+                    "TestPolicyClient: The following error is ok - attempting delete in case the policy exists - the goal is to start with clean slate");
+        }
+        try {
+            deleteOperationalPolicy(actionCd);
+        } catch (Exception e) {
+            System.err.println(
+                    "TestPolicyClient: The following error is ok - attempting delete in case the policy exists - the goal is to start with clean slate");
+        }
+    }
+
+    @Test
+    public void testCreateUpdateDeletePolicy() throws Exception {
+
+        cleanUpPolicies(CldsEvent.ACTION_DELETE);
+        TimeUnit.SECONDS.sleep(5);
+        System.out.println("entered into update");
+        String actionCd;
+
+        try {
+            actionCd = CldsEvent.ACTION_SUBMIT;
+            createUpdatePolicies(actionCd);
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("Policy send failed: PE500 "));
+        }
+
+        try {
+            actionCd = CldsEvent.ACTION_RESUBMIT;
+            createUpdatePolicies(actionCd);
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("Policy send failed: PE500 "));
+        }
+
+        try {
+            actionCd = CldsEvent.ACTION_RESUBMIT;
+            createUpdatePolicies(actionCd);
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("Policy send failed: PE500 "));
+        }
+
+        try {
+            TimeUnit.SECONDS.sleep(20);
+            deletePolicies(CldsEvent.ACTION_DELETE);
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("Unable to get valid Response from  PDP"));
+        }
+
+    }
+}
diff --git a/src/test/java/org/onap/clamp/clds/it/PropJsonBuilderIT.java b/src/test/java/org/onap/clamp/clds/it/PropJsonBuilderIT.java
new file mode 100644 (file)
index 0000000..7eeb04e
--- /dev/null
@@ -0,0 +1,446 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.it;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onap.clamp.clds.AbstractIT;
+import org.onap.clamp.clds.client.req.SdcReq;
+import org.onap.clamp.clds.model.CldsAsdcServiceDetail;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+
+/**
+ * Test ASDC API - stand alone (except for some config).
+ * Replicates getAsdcServices and getAsdcServicesByUUID in the CldsService
+ * Adds test of putting putting an artifact to VF.
+ * TODO Also needs update and perhaps delete tests.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class PropJsonBuilderIT extends AbstractIT {
+
+    private String globalPropsPartial;
+    private ObjectMapper mapper;
+
+    @Before
+    public void setUp() throws IOException {
+        String url = refProp.getStringValue("asdc.serviceUrl");
+        String catalogUrl = refProp.getStringValue("asdc.catalog.url");
+        String basicAuth = SdcReq.getAsdcBasicAuth(refProp);
+        System.out.println("value of string and basicAuth:" + url + basicAuth);
+        CldsAsdcServiceDetail cldsservicedetail = new CldsAsdcServiceDetail();
+        //     cldsservicedetail.set
+        String globalProps = refProp.getStringValue("globalPropsTest");
+        globalPropsPartial = refProp.getStringValue("globalPropsPartialTest");
+        mapper = new ObjectMapper();
+    }
+
+    /**
+     * List services from ASDC.
+     * List meta data for a particular service from ASDC.
+     * Test uploading artifact to a VF in ASDC.
+     */
+    @Test
+    public void testAsdc() throws Exception {
+//             String createEmptySharedObject = createEmptySharedObject();
+//             System.out.println("value of emptySharedObject:" + createEmptySharedObject);
+        sampleJsonObject();
+        System.out.println(createTestEmptySharedObject());
+    }
+
+    private void sampleJsonObject() throws JsonProcessingException {
+        ArrayNode arrayNode = mapper.createArrayNode();
+
+        /**
+         * Create three JSON Objects objectNode1, objectNode2, objectNode3
+         * Add all these three objects in the array
+         */
+
+        ObjectNode objectNode1 = mapper.createObjectNode();
+        objectNode1.put("bookName", "Java");
+        objectNode1.put("price", "100");
+
+        ObjectNode objectNode2 = mapper.createObjectNode();
+        objectNode2.put("bookName", "Spring");
+        objectNode2.put("price", "200");
+
+        ObjectNode objectNode3 = mapper.createObjectNode();
+        objectNode3.put("bookName", "Liferay");
+        objectNode3.put("price", "500");
+
+        /**
+         * Array contains JSON Objects
+         */
+        arrayNode.add(objectNode1);
+        arrayNode.add(objectNode2);
+        arrayNode.add(objectNode3);
+
+        /**
+         * We can directly write the JSON in the console.
+         * But it wont be pretty JSON String
+         */
+        System.out.println(arrayNode.toString());
+
+        /**
+         * To make the JSON String pretty use the below code
+         */
+        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(arrayNode));
+    }
+
+    private String createEmptySharedObject() throws JsonProcessingException {
+
+        /**
+         * "": {
+         "vf": {
+         "": ""
+         },
+         "location": {
+         "": ""
+         },
+         "alarmCondition": {
+         "": ""
+         }
+         }
+         */
+        ObjectNode emptyObjectNode = mapper.createObjectNode();
+        emptyObjectNode.put("", "");
+        ObjectNode vfObjectNode = mapper.createObjectNode();
+        vfObjectNode.putPOJO("vf", emptyObjectNode);
+        ObjectNode locationObjectNode = mapper.createObjectNode();
+        locationObjectNode.putPOJO("location", emptyObjectNode);
+        ObjectNode alarmConditionObjectNode = mapper.createObjectNode();
+        alarmConditionObjectNode.putPOJO("alarmCondition", emptyObjectNode);
+        ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
+        ArrayNode samArrayNode = mapper.createArrayNode();
+        samArrayNode.add(vfObjectNode);
+        samArrayNode.add(locationObjectNode);
+        samArrayNode.add(alarmConditionObjectNode);
+        emptyServiceObjectNode.putPOJO("", samArrayNode);
+
+        /**
+         * "vf": {
+         *                     " ": " ",
+         *                     "DCAE_CLAMP_DEMO3 1": "DCAE_CLAMP_DEMO3"
+         *        }
+         *
+         */
+        ObjectNode vfObjectNode2 = mapper.createObjectNode();
+        ObjectNode dcaeClampDemo3Node = mapper.createObjectNode();
+        dcaeClampDemo3Node.put("DCAE_CLAMP_DEMO3", "DCAE_CLAMP_DEMO3");
+        ArrayNode vfArrayNode = mapper.createArrayNode();
+        vfArrayNode.add(emptyObjectNode);
+        vfArrayNode.add(dcaeClampDemo3Node);
+        vfObjectNode2.putPOJO("vf", vfArrayNode);
+
+        /**
+         * "location": {
+         "SNDGCA64": "San Diego SAN3",
+         "ALPRGAED": "Alpharetta PDK1",
+         "LSLEILAA": "Lisle DPA3"
+         },
+         */
+        ObjectNode locationObjectNode2 = mapper.createObjectNode();
+        ObjectNode sandiegoLocationNode = mapper.createObjectNode();
+        sandiegoLocationNode.put("SNDGCA64", "San Diego SAN3");
+        ObjectNode alpharettaNode = mapper.createObjectNode();
+        alpharettaNode.put("ALPRGAED", "Alpharetta PDK1");
+        ArrayNode locationArrayNode = mapper.createArrayNode();
+        locationArrayNode.add(emptyObjectNode);
+        locationArrayNode.add(sandiegoLocationNode);
+        locationArrayNode.add(alpharettaNode);
+        locationObjectNode2.putPOJO("location", locationArrayNode);
+
+        /**
+         * "alarmCondition": {
+         "A+Fallback+Operation+will+soon+be+started": "A Fallback Operation will soon be started",
+         "BRM%2C+Auto+Export+Backup+Failed": "BRM, Auto Export Backup Failed",
+         */
+        ObjectNode alarmConditionObjectNode2 = mapper.createObjectNode();
+        ObjectNode alamrCondition1 = mapper.createObjectNode();
+        alamrCondition1.put("A+Fallback+Operation+will+soon+be+started", "A Fallback Operation will soon be started");
+        ObjectNode alarmConditon2 = mapper.createObjectNode();
+        alarmConditon2.put("BRM%2C+Scheduled+Backup+Failed", "BRM, Scheduled Backup Failed");
+        ArrayNode alarmArrayNode = mapper.createArrayNode();
+        alarmArrayNode.add(emptyObjectNode);
+        alarmArrayNode.add(alamrCondition1);
+        alarmArrayNode.add(alarmConditon2);
+        alarmConditionObjectNode2.putPOJO("alarmCondition", alarmArrayNode);
+
+        ArrayNode byServiceIdArrayNode = mapper.createArrayNode();
+        byServiceIdArrayNode.add(vfObjectNode2);
+        byServiceIdArrayNode.add(locationObjectNode2);
+        byServiceIdArrayNode.add(alarmConditionObjectNode2);
+
+        ObjectNode byServiceIdNode = mapper.createObjectNode();
+        byServiceIdNode.putPOJO("c989a551-69f7-4b30-b10a-2e85bb227c30", byServiceIdArrayNode);
+
+        ArrayNode byServiceBasicArrayNode = mapper.createArrayNode();
+        byServiceBasicArrayNode.add(emptyServiceObjectNode);
+        byServiceBasicArrayNode.add(byServiceIdNode);
+
+        ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
+
+        byServiceBasicObjetNode.putPOJO("byService", byServiceBasicArrayNode);
+
+        /**
+         * "byVf": {
+         "": {
+         "vfc": {
+         "": ""
+         },
+         "03596c12-c7e3-44b7-8994-5cdfeda8afdd": {
+         "vfc": {
+         " ": " "
+         }
+         }
+         }
+         }
+         */
+
+        ObjectNode byVfCBasicNode = mapper.createObjectNode();
+        ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
+        ObjectNode vfCObjectNode = mapper.createObjectNode();
+        vfCObjectNode.putPOJO("vfC", emptyObjectNode);
+        ObjectNode vfcIdObjectNode = mapper.createObjectNode();
+        vfcIdObjectNode.putPOJO("03596c12-c7e3-44b7-8994-5cdfeda8afdd", vfCObjectNode);
+        ArrayNode emptyvfcArrayNode = mapper.createArrayNode();
+        emptyvfcArrayNode.add(vfCObjectNode);
+        emptyvfcArrayNode.add(vfcIdObjectNode);
+        emptyvfcobjectNode.putPOJO("", emptyvfcArrayNode);
+
+        byVfCBasicNode.putPOJO("byVf", emptyvfcobjectNode);
+
+        ArrayNode finalSharedArrayObject = mapper.createArrayNode();
+
+        finalSharedArrayObject.add(byServiceBasicObjetNode);
+        finalSharedArrayObject.add(byVfCBasicNode);
+
+        ObjectNode finalSharedObjectNode = mapper.createObjectNode();
+        finalSharedObjectNode.putPOJO("shared", finalSharedArrayObject);
+
+        System.out.println("value :" + finalSharedObjectNode.toString());
+        String testFinal = finalSharedObjectNode.toString();
+        testFinal = testFinal.replaceFirst("\\{", ",");
+        return globalPropsPartial + testFinal;
+    }
+
+    private String createTestEmptySharedObject() throws IOException {
+        String locationStringValue = refProp.getStringValue("ui.location.default");
+        String alarmStringValue = refProp.getStringValue("ui.alarm.default");
+
+        ObjectNode locationJsonNode = (ObjectNode) mapper.readValue(locationStringValue, JsonNode.class);
+        ObjectNode alarmStringJsonNode = (ObjectNode) mapper.readValue(alarmStringValue, JsonNode.class);
+        /**
+         * "": {
+         "vf": {
+         "": ""
+         },
+         "location": {
+         "": ""
+         },
+         "alarmCondition": {
+         "": ""
+         }
+         }
+         */
+        ObjectNode emptyObjectNode = mapper.createObjectNode();
+        emptyObjectNode.put("", "");
+        ObjectNode vfObjectNode = mapper.createObjectNode();
+        vfObjectNode.putPOJO("vf", emptyObjectNode);
+        vfObjectNode.putPOJO("location", emptyObjectNode);
+        vfObjectNode.putPOJO("alarmCondition", emptyObjectNode);
+        ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
+        emptyServiceObjectNode.putPOJO("", vfObjectNode);
+
+        /**
+         * "vf": {
+         *                     " ": " ",
+         *                     "DCAE_CLAMP_DEMO3 1": "DCAE_CLAMP_DEMO3"
+         *        }
+         *
+         */
+        ObjectNode vfObjectNode2 = mapper.createObjectNode();
+        ObjectNode dcaeClampDemo3Node = mapper.createObjectNode();
+        dcaeClampDemo3Node.put("", "");
+        dcaeClampDemo3Node.put("DCAE_CLAMP_DEMO3", "DCAE_CLAMP_DEMO3");
+        vfObjectNode2.putPOJO("vf", dcaeClampDemo3Node);
+
+        /**
+         * "location": {
+         "SNDGCA64": "San Diego SAN3",
+         "ALPRGAED": "Alpharetta PDK1",
+         "LSLEILAA": "Lisle DPA3"
+         },
+         */
+//             ObjectNode sandiegoLocationNode = mapper.createObjectNode();
+//             sandiegoLocationNode.put("SNDGCA64","San Diego SAN3");
+//             sandiegoLocationNode.put("ALPRGAED","Alpharetta PDK1"); 
+        vfObjectNode2.putPOJO("location", locationJsonNode);
+
+        /**
+         * "alarmCondition": {
+         "A+Fallback+Operation+will+soon+be+started": "A Fallback Operation will soon be started",
+         "BRM%2C+Auto+Export+Backup+Failed": "BRM, Auto Export Backup Failed",
+         */
+//             ObjectNode alamrCondition1 = mapper.createObjectNode();
+//             alamrCondition1.put("A+Fallback+Operation+will+soon+be+started","A Fallback Operation will soon be started");
+//             alamrCondition1.put("BRM%2C+Scheduled+Backup+Failed","BRM, Scheduled Backup Failed");
+        vfObjectNode2.putPOJO("alarmCondition", alarmStringJsonNode);
+        emptyServiceObjectNode.putPOJO("c989a551-69f7-4b30-b10a-2e85bb227c30", vfObjectNode2);
+        ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
+        byServiceBasicObjetNode.putPOJO("byService", emptyServiceObjectNode);
+
+        /**
+         * "byVf": {
+         "": {
+         "vfc": {
+         "": ""
+         },
+         "03596c12-c7e3-44b7-8994-5cdfeda8afdd": {
+         "vfc": {
+         " ": " "
+         }
+         }
+         }
+         }
+         */
+
+        ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
+        ObjectNode vfCObjectNode = mapper.createObjectNode();
+        vfCObjectNode.putPOJO("vfC", emptyObjectNode);
+        ObjectNode subVfCObjectNode = mapper.createObjectNode();
+        subVfCObjectNode.putPOJO("vfc", emptyObjectNode);
+        vfCObjectNode.putPOJO("03596c12-c7e3-44b7-8994-5cdfeda8afdd", subVfCObjectNode);
+        emptyvfcobjectNode.putPOJO("", vfCObjectNode);
+        byServiceBasicObjetNode.putPOJO("byVf", emptyvfcobjectNode);
+
+        ObjectNode readTree = (ObjectNode) mapper.readValue(globalPropsPartial, JsonNode.class);
+
+        readTree.putPOJO("shared", byServiceBasicObjetNode);
+        System.out.println("valuie of objNode:" + readTree);
+        return readTree.toString();
+    }
+
+    private String createCldsSharedObject(CldsAsdcServiceDetail cldsAsdcServiceDetail) throws IOException {
+        /**
+         * "": {
+         "vf": {
+         "": ""
+         },
+         "location": {
+         "": ""
+         },
+         "alarmCondition": {
+         "": ""
+         }
+         }
+         */
+        ObjectNode emptyObjectNode = mapper.createObjectNode();
+        emptyObjectNode.put("", "");
+        ObjectNode vfObjectNode = mapper.createObjectNode();
+        vfObjectNode.putPOJO("vf", emptyObjectNode);
+        vfObjectNode.putPOJO("location", emptyObjectNode);
+        vfObjectNode.putPOJO("alarmCondition", emptyObjectNode);
+        ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
+        emptyServiceObjectNode.putPOJO("", vfObjectNode);
+
+        /**
+         * "vf": {
+         *                     " ": " ",
+         *                     "DCAE_CLAMP_DEMO3 1": "DCAE_CLAMP_DEMO3"
+         *        }
+         *
+         */
+        ObjectNode vfObjectNode2 = mapper.createObjectNode();
+        ObjectNode dcaeClampDemo3Node = mapper.createObjectNode();
+        dcaeClampDemo3Node.put("", "");
+        dcaeClampDemo3Node.put("DCAE_CLAMP_DEMO3", "DCAE_CLAMP_DEMO3");
+        vfObjectNode2.putPOJO("vf", dcaeClampDemo3Node);
+
+        /**
+         * "location": {
+         "SNDGCA64": "San Diego SAN3",
+         "ALPRGAED": "Alpharetta PDK1",
+         "LSLEILAA": "Lisle DPA3"
+         },
+         */
+        ObjectNode sandiegoLocationNode = mapper.createObjectNode();
+        sandiegoLocationNode.put("SNDGCA64", "San Diego SAN3");
+        sandiegoLocationNode.put("ALPRGAED", "Alpharetta PDK1");
+        vfObjectNode2.putPOJO("location", sandiegoLocationNode);
+
+        /**
+         * "alarmCondition": {
+         "A+Fallback+Operation+will+soon+be+started": "A Fallback Operation will soon be started",
+         "BRM%2C+Auto+Export+Backup+Failed": "BRM, Auto Export Backup Failed",
+         */
+        ObjectNode alamrCondition1 = mapper.createObjectNode();
+        alamrCondition1.put("A+Fallback+Operation+will+soon+be+started", "A Fallback Operation will soon be started");
+        alamrCondition1.put("BRM%2C+Scheduled+Backup+Failed", "BRM, Scheduled Backup Failed");
+        vfObjectNode2.putPOJO("alarmCondition", alamrCondition1);
+        emptyServiceObjectNode.putPOJO("c989a551-69f7-4b30-b10a-2e85bb227c30", vfObjectNode2);
+        ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
+        byServiceBasicObjetNode.putPOJO("byService", emptyServiceObjectNode);
+
+        /**
+         * "byVf": {
+         "": {
+         "vfc": {
+         "": ""
+         },
+         "03596c12-c7e3-44b7-8994-5cdfeda8afdd": {
+         "vfc": {
+         " ": " "
+         }
+         }
+         }
+         }
+         */
+
+        ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
+        ObjectNode vfCObjectNode = mapper.createObjectNode();
+        vfCObjectNode.putPOJO("vfC", emptyObjectNode);
+        ObjectNode subVfCObjectNode = mapper.createObjectNode();
+        subVfCObjectNode.putPOJO("vfc", emptyObjectNode);
+        vfCObjectNode.putPOJO("03596c12-c7e3-44b7-8994-5cdfeda8afdd", subVfCObjectNode);
+        emptyvfcobjectNode.putPOJO("", vfCObjectNode);
+        byServiceBasicObjetNode.putPOJO("byVf", emptyvfcobjectNode);
+
+        ObjectNode readTree = (ObjectNode) mapper.readValue(globalPropsPartial, JsonNode.class);
+
+        readTree.putPOJO("shared", byServiceBasicObjetNode);
+        System.out.println("valuie of objNode:" + readTree);
+        return readTree.toString();
+    }
+}
diff --git a/src/test/java/org/onap/clamp/clds/it/RefPropIT.java b/src/test/java/org/onap/clamp/clds/it/RefPropIT.java
new file mode 100644 (file)
index 0000000..e3dd372
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.it;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.clamp.clds.AbstractIT;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Test corg.onap.clamp.ClampDesigner.model.refprop package using RefProp.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class RefPropIT extends AbstractIT {
+
+    /**
+     * Test getting prop value as a JSON Node / template.
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testJsonTemplate() throws IOException {
+        ObjectNode root = (ObjectNode) refProp.getJsonTemplate("sm.template");
+        root.put("closedLoopControlName", "ClosedLoop-FRWL-SIG-1582f840-2881-11e6-b4ec-005056a9d756");
+
+        ObjectMapper mapper = new ObjectMapper();
+        String jsonText = mapper.writeValueAsString(root);
+        System.out.println("jsonText=" + jsonText);
+
+        // assertEquals(topicsJson, ref.getTopicsToJson());
+    }
+
+}
diff --git a/src/test/java/org/onap/clamp/clds/model/CldsModelTest.java b/src/test/java/org/onap/clamp/clds/model/CldsModelTest.java
new file mode 100644 (file)
index 0000000..414b042
--- /dev/null
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model;
+
+import org.onap.clamp.clds.model.CldsModel;
+import org.jboss.resteasy.spi.BadRequestException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test org.onap.clamp.ClampDesigner.model.Model
+ */
+public class CldsModelTest {
+
+    @Test
+    public void testCreateUsingControlName() {
+        utilCreateUsingControlName("abc-", "7c42aceb-2350-11e6-8131-fa163ea8d2da");
+        utilCreateUsingControlName("", "7c42aceb-2350-11e6-8131-fa163ea8d2da");
+    }
+
+    @Test(expected = BadRequestException.class)
+    public void testExceptionCreateUsingControlName() {
+        utilCreateUsingControlName("", "c42aceb-2350-11e6-8131-fa163ea8d2da");
+    }
+
+    public void utilCreateUsingControlName(String controlNamePrefix, String controlNameUuid) {
+        CldsModel model = CldsModel.createUsingControlName(controlNamePrefix + controlNameUuid);
+        assertEquals(controlNamePrefix, model.getControlNamePrefix());
+        assertEquals(controlNameUuid, model.getControlNameUuid());
+    }
+}
diff --git a/src/test/java/org/onap/clamp/clds/model/prop/ModelPropertiesTest.java b/src/test/java/org/onap/clamp/clds/model/prop/ModelPropertiesTest.java
new file mode 100644 (file)
index 0000000..54a7a4a
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+
+package org.onap.clamp.clds.model.prop;
+
+import org.onap.clamp.clds.transform.TransformUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Test org.onap.clamp.ClampDesigner.model.prop package using ModelProperties.
+ */
+public class ModelPropertiesTest {
+
+    @Test
+    public void testJsonParse() throws IOException {
+        String modelBpmnProp = TransformUtil.getResourceAsString("example/modelBpmnProp.json");
+        String modelProp = TransformUtil.getResourceAsString("example/modelProp.json");
+        String modName = "example-model-name";
+        String controlName = "example-control-name";
+
+        ModelProperties prop = new ModelProperties(modName, controlName, null, modelBpmnProp, modelProp);
+        Assert.assertEquals(modName, prop.getModelName());
+        Assert.assertEquals(controlName, prop.getControlName());
+        Assert.assertEquals(null, prop.getActionCd());
+
+        Global g = prop.getGlobal();
+        Assert.assertEquals("df6fcd2b-1932-429e-bb13-0cd0d32113cb", g.getService());
+        Assert.assertEquals("[SNDGCA64, ALPRGAED]", g.getLocation().toString());
+        Assert.assertEquals("[4b49acee-cf70-4b20-b956-a4fe0c1a8239]", g.getResourceVf().toString());
+
+        Collector c = prop.getCollector();
+        Assert.assertEquals("Collector_", c.getId());
+        Assert.assertEquals("DCAE-COLLECTOR-UCSNMP", c.getTopicPublishes());
+
+        StringMatch sm = prop.getStringMatch();
+        Assert.assertEquals("StringMatch_", sm.getId());
+        Assert.assertEquals("DCAE-CL-EVENT", sm.getTopicPublishes());
+
+        Policy p = prop.getPolicy();
+        Assert.assertEquals("Policy_", p.getId());
+        Assert.assertEquals(null, p.getTopicPublishes());
+        Assert.assertEquals("DCAE-CL-EVENT", p.getTopicSubscribes());
+        Assert.assertEquals(500, p.getTimeout().intValue());
+        
+        Tca t = prop.getTca();
+        Assert.assertEquals("Narra", t.getTcaItems().get(0).getTcaName());
+        Assert.assertEquals(Integer.valueOf(4), t.getTcaItems().get(0).getTcaThreshholds().get(0).getThreshhold());
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/resources/clds/clds-policy-config.properties b/src/test/resources/clds/clds-policy-config.properties
new file mode 100644 (file)
index 0000000..892cdda
--- /dev/null
@@ -0,0 +1,37 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+# Configuration Settings for Policy Engine Components
+PDP_URL1=https://localhost:8081/pdp/ , testpdp, alpha123
+PDP_URL2=https://localhost:8081/pdp/ , testpdp, alpha456
+PAP_URL=https://localhost:8081/pap/ , testpap, alpha123
+NOTIFICATION_TYPE=websocket
+NOTIFICATION_UEB_SERVERS=localhost
+
+CLIENT_ID=myclientid
+# base64 encoding
+CLIENT_KEY=ChlakDuk
+#DEVL for development
+#TEST for Test environments
+#PROD for prod environments
+ENVIRONMENT=DEVL
diff --git a/src/test/resources/clds/clds-reference.properties b/src/test/resources/clds/clds-reference.properties
new file mode 100644 (file)
index 0000000..6487989
--- /dev/null
@@ -0,0 +1,113 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP CLAMP
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+#                             reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License"); 
+# you may not use this file except in compliance with the License. 
+# You may obtain a copy of the License at
+# 
+# http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software 
+# distributed under the License is distributed on an "AS IS" BASIS, 
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+# See the License for the specific language governing permissions and 
+# limitations under the License.
+# ============LICENSE_END============================================
+# ===================================================================
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+###
+
+#
+# Poperties for CLDS
+#
+#
+#
+# TCA MicroService Policy request build properties
+#
+tca.template={"service":"MThresholdCrossingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"MThresholdCrossingConfiguration","templateVersion":"5.2.0.1","priority":"4","version":"5.2.0.1","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"$class": "com.att.ecomp.dcae.clamp.common.MThresholdCrossingConfiguration","domain":"measurementsForVfScaling","policyScope":"pnf=eNodeB;type=configuration","policyName":"policy.dcae.configuration","policyVersion":"1.0.0","subscriberContentType": "application/json","subscriberConsumerId": "c13","subscriberConsumerGroup": "OpenDCAE-c13","subscriberTimeoutMS": "-1","subscriberMessageLimit": "-1","subscriberPollingInterval": "20000","publisherContentType": "application/json","publisherMaxBatchSize": "10","publisherMaxRecoveryQueueSize": "100000","publisherPollingInterval": "20000","publisherAlertWindowingTime": "86400","signatures":[]}}
+tca.signature.template={"nfNamingCode":"ENBE","target":"common_id","targetType":"eNodeB","useCaseName":"???","signatureName":"???","signatureUuid":"???","closedLoopControlName":"???","severity":"???","version":"1.0.2","maxInterval":1200,"minMessageViolations":4,"thresholds":[]}
+
+#
+# DCAE request build properties
+#
+dcae.template={"properties":{"service_name":"","service_ids":[],"vnf_ids":[],"location_ids":[]},"template":{"string_matching":{"dcae":{"inputTopic":"","outputTopic":"","closedLoopControlName":"","closedLoopEventClient":"configuration.dcae.microservice.stringmatcher.xml","policyName":"","policyScope":"service=vSCP;resource=F5;type=configuration","policyVersion":"v0.0.1","serviceConfigurations":{}}}}}
+dcae.decode.service_ids={"vUSP":["vUSP - vCTS"],"Trinity":["ASBGv TLS VNF","ASBGv No TLS","ASBGv (NO TLS) VNF","ASBGv TLS","NSBGv VNF","NSBGv"],"vSCP":["AKRON_vSCP_F5_FW-SVC/vSCP_F5_FW 1","ALLEN_vSCP_F5_FW-SVC/vSCP_F5_FW 1"],"vProbes":["vProbes - FW"]}
+#
+# ASDC request blueprint properties
+#
+asdc.template={}
+asdc.decode.service_ids={}
+#
+#
+# General Policy request properties
+#
+policy.ecomp.name=DCAE
+policy.pdp.group=default
+policy.ms.type=MicroService
+policy.ms.policyNamePrefix=Config_MS_
+policy.op.type=BRMS_Param
+policy.op.policyNamePrefix=Config_BRMS_Param_
+
+# by service: xxx
+#
+#
+# String Match MicroService Policy request build properties
+#
+# default
+sm.template={"service":"StringMatchingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"com.att.d2.policy.StringMatchingConfiguration","templateVersion":"1604","priority":"4","version":"1610","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"serviceConfigurations":{}}}
+# by service: vSCP
+sm.template.vSCP={"service":"StringMatchingConfiguration","location":"Edge","uuid":"TestUUID","policyName":"???","description":"from clds","configName":"com.att.d2.policy.StringMatchingConfiguration","templateVersion":"1604","priority":"4","version":"0.1.0-SNAPSHOT","policyScope":"resource=F5,service=vSCP,type=configuration,closedLoopControlName=vSCP_F5_Firewall_d925ed73-8231-4d02-9545-db4e101f88f8","content":{"serviceConfigurations":{}}}
+sm.sc.template={}
+#
+# default
+sm.rulegroup=true
+# by service: vSCP
+sm.rulegroup.vSCP=false
+#
+#
+# Operational Policy request build properties
+#
+op.policyDescription=from clds
+# default
+op.templateName=ClosedLoopvUSP
+op.operationTopic=APPC-CL
+op.notificationTopic=POLICY-CL-MGT
+op.controller=1610-vUSP
+# by service: vSCP
+op.templateName.vSCP=ClosedLoopTemplate
+op.controller.vSCP=1607-f5fw
+#
+# Asdc service properties
+asdc.catalog.url=http://127.0.0.1:8080/sdc/v1/catalog/
+asdc.hostUrl=http://127.0.0.1:8080
+asdc.serviceUrl=http://127.0.0.1:8080/sdc/v1/catalog/services
+asdc.serviceUsername=test
+asdc.servicePassword=123456
+asdc.artifactLabel=blueprintclampcockpit
+asdc.asdcX-ECOMP-InstanceID=CLAMP
+asdc.artifactType=DCAE_INVENTORY_BLUEPRINT
+asdc.locationArtifactLabel=LocationClampCockpit
+asdc.locationArtifactType=DCAE_INVENTORY_JSON
+#
+#
+#
+ui.location.default={"SNDGCA64":"San Diego SAN3","ALPRGAED":"Alpharetta PDK1","LSLEILAA":"Lisle DPA3","MDTWNJC1":"FTL_C_location1","MDTWNJC2":"FTL_C_location2","MDTWNJ21":"FTL_L_location1","MDTWNJ22":"FTL_L_location2","RDM2WAGPLCP":"ISTFTL_location"}
+ui.alarm.default={"Reports a transient alarm condition when an incoming CDR cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming CDR cannot be decoded successfully","Reports a transient alarm condition when an incoming ACR message cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming ACR message cannot be decoded successfully","Reports a transient alarm condition when a CDR validation fails":"vCCF: Reports a transient alarm condition when a CDR validation fails","Reports a transient alarm condition when an incoming GTP' message cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming GTP' message cannot be decoded successfully","Reports a transient alarm condition when an incoming CDR file cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming CDR file cannot be decoded successfully","Reports a transient alarm condition when an incoming Sh/Dh file cannot be decoded successfully":"vCCF: Reports a transient alarm condition when an incoming Sh/Dh file cannot be decoded successfully","Reports a transient alarm condition when an incoming ACR message is in conflict with former ACR in one diameter session":"vCCF: Reports a transient alarm condition when an incoming ACR message is in conflict with former ACR in one diameter session","Reports a transient alarm condition when an outgoing Ro message send fails":"vCCF: Reports a transient alarm condition when an outgoing Ro message send fails","Reports a transient alarm condition when an outgoing GTP' message send fails":"vCCF: Reports a transient alarm condition when an outgoing GTP' message send fails","Reports a transient alarm condition when an outgoing Sh/Dh message send fails":"vCCF: Reports a transient alarm condition when an outgoing Sh/Dh message send fails","Reports an alarm when build or send Rf message fail":"vCCF: Reports an alarm when build or send Rf message fail","Reports a transient alarm condition when an abnormal incoming CCA message":"vCCF: Reports a transient alarm condition when an abnormal incoming CCA message","Reports a transient alarm condition when there is an abnormal incoming Sh/Dh message":"vCCF: Reports a transient alarm condition when there is an abnormal incoming Sh/Dh message","For Rf interface, if IeCCF receives a message with incorrect value for session id.":"vCCF: For Rf interface, if IeCCF receives a message with incorrect value for session id.","Reports an alarm when CPU usage exceeds the major threshold, the local database exceeds the critical threshold, or the ACR partition exceeds the major threshold":"vCCF: Reports an alarm when CPU usage exceeds the major threshold, the local database exceeds the critical threshold, or the ACR partition exceeds the major threshold","Reports an alarm when CPU usage exceeds the minor threshold, the local database exceeds the major threshold, or the ACR partition exceeds the minor threshold":"vCCF: Reports an alarm when CPU usage exceeds the minor threshold, the local database exceeds the major threshold, or the ACR partition exceeds the minor threshold","Reports an alarm when CPU usage exceeds the critical threshold, the local database exceeds the major threshold, or the CDR partition exceeds the critical threshold":"vCCF: Reports an alarm when CPU usage exceeds the critical threshold, the local database exceeds the major threshold, or the CDR partition exceeds the critical threshold","Reports an alarm when CPU usage exceeds the major threshold or CDR partition exceeds the major threshold":"vCCF: Reports an alarm when CPU usage exceeds the major threshold or CDR partition exceeds the major threshold","Reports an alarm when external DB usage exceeds the major threshold":"vCCF: Reports an alarm when external DB usage exceeds the major threshold","If IeCCF comes to the status \\"Stop processing ACR records in ACRDB\\".":"vCCF: If IeCCF comes to the status \\"Stop processing ACR records in ACRDB\\".","If IeCCF comes to the status \\"Flush ACR is invoked\\".":"vCCF: If IeCCF comes to the status \\"Flush ACR is invoked\\".","Reports a transient alarm condition when the workflow definition table is provisioned wrongly":"vCCF: Reports a transient alarm condition when the workflow definition table is provisioned wrongly","Reports a transient alarm condition when the Action Definition table is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Action Definition table is provisioned wrongly","Reports a transient alarm condition when the Ro Host Configuration is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Ro Host Configuration is provisioned wrongly","Reports a transient alarm condition when the Sh Host Configuration is provisioned wrongly":"vCCF: Reports a transient alarm condition when the Sh Host Configuration is provisioned wrongly","Reports a transient alarm condition when a specific dictionary or rule does not exist":"vCCF: Reports a transient alarm condition when a specific dictionary or rule does not exist","Reports a transient alarm condition when failure occurs when mapping Rf message to XDR":"vCCF: Reports a transient alarm condition when failure occurs when mapping Rf message to XDR","Reports a transient alarm condition when failure occurs in aggregating process":"vCCF: Reports a transient alarm condition when failure occurs in aggregating process","Reports a transient alarm condition when failure happens in correlating process":"vCCF: Reports a transient alarm condition when failure happens in correlating process","Reports a transient alarm condition when failure occurs in generating CDR":"vCCF: Reports a transient alarm condition when failure occurs in generating CDR","Reports a transient alarm condition when failure occurs in constructing CCR message from XDR":"vCCF: Reports a transient alarm condition when failure occurs in constructing CCR message from XDR","Reports a transient alarm condition when an ACR/XER/BER/INC record write to bad file":"vCCF: Reports a transient alarm condition when an ACR/XER/BER/INC record write to bad file","Reports an alarm condition when aggregation or correlation central database connection is lost":"vCCF: Reports an alarm condition when aggregation or correlation central database connection is lost","Reports an alarm condition when a specific failure happens in database operations":"vCCF: Reports an alarm condition when a specific failure happens in database operations","Reports an alarm condition when DB capacity has been consumed to critical threshold":"vCCF: Reports an alarm condition when DB capacity has been consumed to critical threshold","Reports an alarm condition when DB capacity has been consumed to major threshold":"vCCF: Reports an alarm condition when DB capacity has been consumed to major threshold","Reports an alarm condition when DB capacity has been consumed to minor threshold.":"vCCF: Reports an alarm condition when DB capacity has been consumed to minor threshold.","Reports an alarm condition when application cannot deliver CDR to CDRSCH subsystem":"vCCF: Reports an alarm condition when application cannot deliver CDR to CDRSCH subsystem","Reports an alarm condition when some fields of ACR file header have error value and this ACR file cannot be processed further":"vCCF: Reports an alarm condition when some fields of ACR file header have error value and this ACR file cannot be processed further","Reports an alarm condition when some fields of ACR file header have invalid value and this ACR file can be processed further":"vCCF: Reports an alarm condition when some fields of ACR file header have invalid value and this ACR file can be processed further","Reports an alarm condition when the ACR file loses some ACR records":"vCCF: Reports an alarm condition when the ACR file loses some ACR records","Reports an alarm condition when some fields of ACR record header have error value and this ACR record and the following ACR records cannot be processed further":"vCCF: Reports an alarm condition when some fields of ACR record header have error value and this ACR record and the following ACR records cannot be processed further","Reports an alarm condition when error occurs in processing CDR/ACR files":"vCCF: Reports an alarm condition when error occurs in processing CDR/ACR files","Reports an alarm condition when CDR partition has been consumed to critical threshold":"vCCF: Reports an alarm condition when CDR partition has been consumed to critical threshold","Reports an alarm condition when CDR partition has been consumed to major threshold.":"vCCF: Reports an alarm condition when CDR partition has been consumed to major threshold.","Reports an alarm condition when CDR partition has been consumed to minor threshold":"vCCF: Reports an alarm condition when CDR partition has been consumed to minor threshold","Reports an alarm condition when ACR partition has been consumed to critical threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to critical threshold","Reports an alarm condition when ACR partition has been consumed to major threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to major threshold","Reports an alarm condition when ACR partition has been consumed to minor threshold":"vCCF: Reports an alarm condition when ACR partition has been consumed to minor threshold","Reports an alarm condition when CPU consumption reaches critical threshold":"vCCF: Reports an alarm condition when CPU consumption reaches critical threshold","Reports an alarm condition when CPU consumption reaches major threshold":"vCCF: Reports an alarm condition when CPU consumption reaches major threshold","Reports an alarm condition when CPU consumption reaches minor threshold":"vCCF: Reports an alarm condition when CPU consumption reaches minor threshold","Service shall monitor * number of partial CDR * number of incompleted CDR * number of unacceptable CDR If any one exceeds a configurable threshold in a configrable interval.":"vCCF: Service shall monitor * number of partial CDR * number of incompleted CDR * number of unacceptable CDR If any one exceeds a configurable threshold in a configrable interval.","CDR size exceed the platform capacity.":"vCCF: CDR size exceed the platform capacity.","Service shall monitor number of ACR without AII AVP, If it exceeds a configurable threshold in a configurable interval.":"vCCF: Service shall monitor number of ACR without AII AVP, If it exceeds a configurable threshold in a configurable interval.","Service shall monitor CDR cut due to ECCF_ACRNUMBER_IN_DB, If it exceeds a configurable threshold in a configurable interval.":"vCCF: Service shall monitor CDR cut due to ECCF_ACRNUMBER_IN_DB, If it exceeds a configurable threshold in a configurable interval.","External Node of this Cluster is overload":"vCCF: External Node of this Cluster is overload","bdb_high_latency":"vCCF-vDB: bdb_high_latency","bdb_high_throughput":"vCCF-vDB: bdb_high_throughput","bdb_size":"vCCF-vDB: bdb_size","cluster_inconsistent_rl_sw":"vCCF-vDB: cluster_inconsistent_rl_sw","cluster_node_remove_abort_failed":"vCCF-vDB: cluster_node_remove_abort_failed","cluster_node_remove_failed":"vCCF-vDB: cluster_node_remove_failed","cluster_ram_overcommit":"vCCF-vDB: cluster_ram_overcommit","cluster_rebalance_failed":"vCCF-vDB: cluster_rebalance_failed","cluster_too_few_nodes_for_replication":"vCCF-vDB: cluster_too_few_nodes_for_replication","node_cpu_utilization":"vCCF-vDB: node_cpu_utilization","node_ephemeral_storage":"vCCF-vDB: node_ephemeral_storage","node_failed":"vCCF-vDB: node_failed","node_memory":"vCCF-vDB: node_memory","node_net_throughput":"vCCF-vDB: node_net_throughput","node_offline_failed":"vCCF-vDB: node_offline_failed","node_offline_abort_failed":"vCCF-vDB: node_offline_abort_failed","node_online_failed":"vCCF-vDB: node_online_failed","OAM NODE-<OAME-hostname> IS NOT ACTIVE ":"vCCF-vDB: OAM NODE-<OAME-hostname> IS NOT ACTIVE ","LSS_asdaCommunicationFailure":"vCTS: LSS_asdaCommunicationFailure","LSS_ccdbCommunicationFailure":"vCTS: LSS_ccdbCommunicationFailure","LSS_cpiCTS3xxFailRate":"vCTS: LSS_cpiCTS3xxFailRate","LSS_cpiCTS4xxFailRate":"vCTS: LSS_cpiCTS4xxFailRate","LSS_cpiCTS5xxFailRate":"vCTS: LSS_cpiCTS5xxFailRate","LSS_cpiCTS6xxFailRate":"vCTS: LSS_cpiCTS6xxFailRate","LSS_cpiCTSSIPRetransmitInvite":"vCTS: LSS_cpiCTSSIPRetransmitInvite","LSS_cpiCTSSIPRetransmitNonInvite":"vCTS: LSS_cpiCTSSIPRetransmitNonInvite","LSS_glsInvalidCellId":"vCTS: LSS_glsInvalidCellId","LSS_glsServerUnavailable":"vCTS: LSS_glsServerUnavailable","LSS_hlrSyncConnection":"vCTS: LSS_hlrSyncConnection","LSS_hlrSyncQueue":"vCTS: LSS_hlrSyncQueue","LSS_lispBufferFullExternalLIG":"vCTS: LSS_lispBufferFullExternalLIG","LSS_prdbConnectWithAlternateFailure":"vCTS: LSS_prdbConnectWithAlternateFailure","LSS_prdbSyncDataToAlternateFailure":"vCTS: LSS_prdbSyncDataToAlternateFailure","LSS_preAllocatedResourceOverload":"vCTS: LSS_preAllocatedResourceOverload","LSS_prifSocketError":"vCTS: LSS_prifSocketError","LSS_prsCallInstanceExceeded":"vCTS: LSS_prsCallInstanceExceeded","LSS_prsCpuOverload":"vCTS: LSS_prsCpuOverload","LSS_prsDatabaseMigrationFailure":"vCTS: LSS_prsDatabaseMigrationFailure","LSS_prsFailureToConnectWithPRDB":"vCTS: LSS_prsFailureToConnectWithPRDB","LSS_prsQueueExceeded":"vCTS: LSS_prsQueueExceeded","LSS_smdiSocketError":"vCTS: LSS_smdiSocketError","LSS_socketError":"vCTS: LSS_socketError","LSS_softwareComponentDown":"vCTS: LSS_softwareComponentDown","LSS_tlsInitError":"vCTS: LSS_tlsInitError","LSS_usageOfSyncTable":"vCTS: LSS_usageOfSyncTable","LSS_utHttpProxyConnectionDown ":"vCTS: LSS_utHttpProxyConnectionDown ","LSS_wpifSocketError":"vCTS: LSS_wpifSocketError","LSS_acrTemporaryBufferOverload":"vCTS: LSS_acrTemporaryBufferOverload","LSS_adnsExtendedTTLcaching":"vCTS: LSS_adnsExtendedTTLcaching","LSS_adnsQueryFailureCaching":"vCTS: LSS_adnsQueryFailureCaching","LSS_adnsQueueCongestion":"vCTS: LSS_adnsQueueCongestion","LSS_asdaRequestQueue":"vCTS: LSS_asdaRequestQueue","LSS_capacityLicenseKeyExpiration":"vCTS: LSS_capacityLicenseKeyExpiration","LSS_capacityLicenseKeyNearExpiration":"vCTS: LSS_capacityLicenseKeyNearExpiration","LSS_capacityLicenseKeyValidationError":"vCTS: LSS_capacityLicenseKeyValidationError","LSS_cardConnectionLost":"vCTS: LSS_cardConnectionLost","LSS_cpiAlrmCritical":"vCTS: LSS_cpiAlrmCritical","LSS_cpiAlrmMajor":"vCTS: LSS_cpiAlrmMajor","LSS_cpiAlrmMinor":"vCTS: LSS_cpiAlrmMinor","LSS_cpiAlrmWarning":"vCTS: LSS_cpiAlrmWarning","LSS_cpiAsrtEsc":"vCTS: LSS_cpiAsrtEsc","LSS_cpiAsrtNonEsc":"vCTS: LSS_cpiAsrtNonEsc","LSS_cpiAsrtNonEscCritical":"vCTS: LSS_cpiAsrtNonEscCritical","LSS_cpiAsrtNonEscMajor":"vCTS: LSS_cpiAsrtNonEscMajor","LSS_cpiAsrtNonEscMinor":"vCTS: LSS_cpiAsrtNonEscMinor","LSS_cpiAudErrCount":"vCTS: LSS_cpiAudErrCount","LSS_cpiAudManAct":"vCTS: LSS_cpiAudManAct","LSS_cpiAudNewEvent":"vCTS: LSS_cpiAudNewEvent","LSS_cpiCompleteRateAlarm":"vCTS: LSS_cpiCompleteRateAlarm","LSS_cpiDropMGAllocConnReq":"vCTS: LSS_cpiDropMGAllocConnReq","LSS_cpiDropRateAlarm":"vCTS: LSS_cpiDropRateAlarm","LSS_cpiExceptionService":"vCTS: LSS_cpiExceptionService","LSS_cpiFailRateAlarm":"vCTS: LSS_cpiFailRateAlarm","LSS_cpiFailSCTPFastRetransIncr":"vCTS: LSS_cpiFailSCTPFastRetransIncr","LSS_cpiFailSCTPFastRetransRate":"vCTS: LSS_cpiFailSCTPFastRetransRate","LSS_cpiFailSCTPSRTT1Incr":"vCTS: LSS_cpiFailSCTPSRTT1Incr","LSS_cpiFailSCTPSRTT2Incr":"vCTS: LSS_cpiFailSCTPSRTT2Incr","LSS_cpiFailSCTPT3RetransIncr":"vCTS: LSS_cpiFailSCTPT3RetransIncr","LSS_cpiFailSCTPT3RetransRate":"vCTS: LSS_cpiFailSCTPT3RetransRate","LSS_cpiFileSysUsage":"vCTS: LSS_cpiFileSysUsage","LSS_cpiMemAllocFail":"vCTS: LSS_cpiMemAllocFail","LSS_cpiNumOfLICDRDel":"vCTS: LSS_cpiNumOfLICDRDel","LSS_cpiReinitServiceSelf":"vCTS: LSS_cpiReinitServiceSelf","LSS_cpiSIPRetransmitInvite":"vCTS: LSS_cpiSIPRetransmitInvite","LSS_cpiSIPRetransmitNonInvite":"vCTS: LSS_cpiSIPRetransmitNonInvite","LSS_cpiSS7DropSCTPPktsRcvd":"vCTS: LSS_cpiSS7DropSCTPPktsRcvd","LSS_cpiSS7FailSCTPFastRetransRate":"vCTS: LSS_cpiSS7FailSCTPFastRetransRate","LSS_cpiStabilityAlarm":"vCTS: LSS_cpiStabilityAlarm","LSS_cpuOverload":"vCTS: LSS_cpuOverload","LSS_databaseConnectionLost":"vCTS: LSS_databaseConnectionLost","LSS_databaseReplicationLinkDown":"vCTS: LSS_databaseReplicationLinkDown","LSS_databaseSizeExhausted":"vCTS: LSS_databaseSizeExhausted","LSS_dbHighCpuUtilization":"vCTS: LSS_dbHighCpuUtilization","LSS_dbOffline":"vCTS: LSS_dbOffline","LSS_dbStatusUnexpected":"vCTS: LSS_dbStatusUnexpected","LSS_degradedResource":"vCTS: LSS_degradedResource","LSS_degrow":"vCTS: LSS_degrow","LSS_deviceServerCxnLost":"vCTS: LSS_deviceServerCxnLost","LSS_diamLinkDown":"vCTS: LSS_diamLinkDown","LSS_diamMaxClientsExceeded":"vCTS: LSS_diamMaxClientsExceeded","LSS_dnsThreshold":"vCTS: LSS_dnsThreshold","LSS_ethernetError":"vCTS: LSS_ethernetError","LSS_ethernetLinkDown":"vCTS: LSS_ethernetLinkDown","LSS_externalConnectivity":"vCTS: LSS_externalConnectivity","LSS_featureLicenseExpiration":"vCTS: LSS_featureLicenseExpiration","LSS_featureLicenseKeyNearExpiration":"vCTS: LSS_featureLicenseKeyNearExpiration","LSS_featureLockValidationError":"vCTS: LSS_featureLockValidationError","LSS_fqdnError":"vCTS: LSS_fqdnError","LSS_fru":"vCTS: LSS_fru","LSS_gatewayCongestion":"vCTS: LSS_gatewayCongestion","LSS_gatewayForcedOOS":"vCTS: LSS_gatewayForcedOOS","LSS_gatewayProvisioningError":"vCTS: LSS_gatewayProvisioningError","LSS_gatewayUnreachable":"vCTS: LSS_gatewayUnreachable","LSS_gatewayUnregistered":"vCTS: LSS_gatewayUnregistered","LSS_globalParameterNotFound":"vCTS: LSS_globalParameterNotFound","LSS_grow":"vCTS: LSS_grow","LSS_h248MessageBufferDepletion":"vCTS: LSS_h248MessageBufferDepletion","LSS_hostDown":"vCTS: LSS_hostDown","LSS_hostReset":"vCTS: LSS_hostReset","LSS_invalidGateway":"vCTS: LSS_invalidGateway","LSS_iriLinkDown":"vCTS: LSS_iriLinkDown","LSS_ldapServerConnectionLost":"vCTS: LSS_ldapServerConnectionLost","LSS_llcDown":"vCTS: LSS_llcDown","LSS_logicalLinkDown":"vCTS: LSS_logicalLinkDown","LSS_logicalLinkNotFound":"vCTS: LSS_logicalLinkNotFound","LSS_logRotateThreshold":"vCTS: LSS_logRotateThreshold","LSS_memoryOverload":"vCTS: LSS_memoryOverload","LSS_nodeConfigFailure":"vCTS: LSS_nodeConfigFailure","LSS_nodeGroupOOS":"vCTS: LSS_nodeGroupOOS","LSS_nodeOOS":"vCTS: LSS_nodeOOS","LSS_nonCompliantFaultGroupMemberState":"vCTS: LSS_nonCompliantFaultGroupMemberState","LSS_nonCsAddrChannelDepletion":"vCTS: LSS_nonCsAddrChannelDepletion","LSS_numberOfTuplesInUse":"vCTS: LSS_numberOfTuplesInUse","LSS_osSecInfoModificationDetected":"vCTS: LSS_osSecInfoModificationDetected","LSS_osSecInformationMissing":"vCTS: LSS_osSecInformationMissing","LSS_osSecUnexpectedInformation":"vCTS: LSS_osSecUnexpectedInformation","LSS_pdnsMySqlReplication":"vCTS: LSS_pdnsMySqlReplication","LSS_pktCorruptionDetectedViaRCCLANCheck":"vCTS: LSS_pktCorruptionDetectedViaRCCLANCheck","LSS_platformCommandFailure":"vCTS: LSS_platformCommandFailure","LSS_pmDataNotCollected":"vCTS: LSS_pmDataNotCollected","LSS_processDown":"vCTS: LSS_processDown","LSS_processNotStarted":"vCTS: LSS_processNotStarted","LSS_provisioningInhibitedMode":"vCTS: LSS_provisioningInhibitedMode","LSS_rccInhibitedMode":"vCTS: LSS_rccInhibitedMode","LSS_remotedbLinkDown":"vCTS: LSS_remotedbLinkDown","LSS_remoteQueryServerFailure":"vCTS: LSS_remoteQueryServerFailure","LSS_restore":"vCTS: LSS_restore","LSS_serviceCFGDataTimestampError":"vCTS: LSS_serviceCFGDataTimestampError","LSS_serviceCommCxnLost":"vCTS: LSS_serviceCommCxnLost","LSS_serviceOnewayCommunication":"vCTS: LSS_serviceOnewayCommunication","LSS_sheddingOverload":"vCTS: LSS_sheddingOverload","LSS_simxml":"vCTS: LSS_simxml","LSS_sipLinkSetMaxQuarantineList":"vCTS: LSS_sipLinkSetMaxQuarantineList","LSS_sipLinkSetUnavailable":"vCTS: LSS_sipLinkSetUnavailable","LSS_sipLinkUnavailable":"vCTS: LSS_sipLinkUnavailable","LSS_softwareAllocatedResourceOverload":"vCTS: LSS_softwareAllocatedResourceOverload","LSS_softwareComponentStandbyNotReady":"vCTS: LSS_softwareComponentStandbyNotReady","LSS_softwareLicense":"vCTS: LSS_softwareLicense","LSS_svcdegrow":"vCTS: LSS_svcdegrow","LSS_svcgrow":"vCTS: LSS_svcgrow","LSS_swVersionMismatch":"vCTS: LSS_swVersionMismatch","LSS_tftpDownloadCorrupt":"vCTS: LSS_tftpDownloadCorrupt","LSS_timeStampValueOutOfSystemRange":"vCTS: LSS_timeStampValueOutOfSystemRange","LSS_transactionHandlerBlockDepletion":"vCTS: LSS_transactionHandlerBlockDepletion","LSS_upgrade":"vCTS: LSS_upgrade","SYS_BackupFailure":"vCTS: SYS_BackupFailure","SYS_Configuration":"vCTS: SYS_Configuration","SYS_COTRecordTransferFailure":"vCTS: SYS_COTRecordTransferFailure","SYS_CPM_USERDATA_INCONSITENCY":"vCTS: SYS_CPM_USERDATA_INCONSITENCY","SYS_CPM_USERDATA_RESTORED":"vCTS: SYS_CPM_USERDATA_RESTORED","SYS_EventQueueCapacity":"vCTS: SYS_EventQueueCapacity","SYS_ICMPFailure":"vCTS: SYS_ICMPFailure","SYS_IPsecConfig":"vCTS: SYS_IPsecConfig","SYS_LinkDown":"vCTS: SYS_LinkDown","SYS_NotifyDisabled":"vCTS: SYS_NotifyDisabled","SYS_NotifyLocked":"vCTS: SYS_NotifyLocked","SYS_NumTL1MeasThresh":"vCTS: SYS_NumTL1MeasThresh","SYS_RADIUS_TO_LDAP_FAILURE":"vCTS: SYS_RADIUS_TO_LDAP_FAILURE","SYS_ROOT_ACCESS_DENIED":"vCTS: SYS_ROOT_ACCESS_DENIED","SYS_ROOT_FTP_VIOLATION":"vCTS: SYS_ROOT_FTP_VIOLATION","SYS_ROOT_LOGIN_VIOLATION":"vCTS: SYS_ROOT_LOGIN_VIOLATION","SYS_ROOT_SSH_LOGIN_VIOLATION":"vCTS: SYS_ROOT_SSH_LOGIN_VIOLATION","SYS_SetupAAAFailure":"vCTS: SYS_SetupAAAFailure","SYS_SNETrapOverload":"vCTS: SYS_SNETrapOverload","SYS_SNMPAuthenticationFailure":"vCTS: SYS_SNMPAuthenticationFailure","SYS_SNMPFailure":"vCTS: SYS_SNMPFailure","SYS_SU_TO_ROOT_FAILURE":"vCTS: SYS_SU_TO_ROOT_FAILURE","SYS_SYSTEMTrapOverload":"vCTS: SYS_SYSTEMTrapOverload","SYS_ThresholdCrossed":"vCTS: SYS_ThresholdCrossed","SYS_UndiscoveredObject":"vCTS: SYS_UndiscoveredObject","SYS_WriteAAAFailure":"vCTS: SYS_WriteAAAFailure","jnxSpaceDiskUsageRising":"vDBE-EMS-Juniper: jnxSpaceDiskUsageRising","jnxSpaceDiskUsageRisingCleared":"vDBE-EMS-Juniper: jnxSpaceDiskUsageRisingCleared","jnxSpaceSwapUsageRising":"vDBE-EMS-Juniper: jnxSpaceSwapUsageRising","jnxSpaceSwapUsageRisingCleared":"vDBE-EMS-Juniper: jnxSpaceSwapUsageRisingCleared","jnxSpaceCPULARising":"vDBE-EMS-Juniper: jnxSpaceCPULARising","jnxSpaceCPULARisingCleared":"vDBE-EMS-Juniper: jnxSpaceCPULARisingCleared","jnxSpaceWebpProxyProcessDown":"vDBE-EMS-Juniper: jnxSpaceWebpProxyProcessDown","jnxSpaceWebpProxyProcessUp":"vDBE-EMS-Juniper: jnxSpaceWebpProxyProcessUp","jnxSpaceNMAProcessDown":"vDBE-EMS-Juniper: jnxSpaceNMAProcessDown","jnxSpaceNMAProcessUp":"vDBE-EMS-Juniper: jnxSpaceNMAProcessUp","jnxSpaceJbossProcessDown":"vDBE-EMS-Juniper: jnxSpaceJbossProcessDown","jnxSpaceJbossProcessUp":"vDBE-EMS-Juniper: jnxSpaceJbossProcessUp","jnxSpaceMysqlProcessDown":"vDBE-EMS-Juniper: jnxSpaceMysqlProcessDown","jnxSpaceMysqlProcessUp":"vDBE-EMS-Juniper: jnxSpaceMysqlProcessUp","jnxSpacePostgresqlProcessDown":"vDBE-EMS-Juniper: jnxSpacePostgresqlProcessDown","jnxSpacePostgresqlProcessUp":"vDBE-EMS-Juniper: jnxSpacePostgresqlProcessUp","jnxSpaceWatchdogStopped":"vDBE-EMS-Juniper: jnxSpaceWatchdogStopped","jnxSpaceWatchdogStarted":"vDBE-EMS-Juniper: jnxSpaceWatchdogStarted","jnxSpaceSNAProcessDown":"vDBE-EMS-Juniper: jnxSpaceSNAProcessDown","jnxSpaceSNAProcessUp":"vDBE-EMS-Juniper: jnxSpaceSNAProcessUp","jnxSpaceNodeDown":"vDBE-EMS-Juniper: jnxSpaceNodeDown","jnxSpaceNodeUp":"vDBE-EMS-Juniper: jnxSpaceNodeUp"," jnxSpaceNodeRemoval":"vDBE-EMS-Juniper:  jnxSpaceNodeRemoval","jnxCmCfgChange":"vDBE-Juniper: jnxCmCfgChange","jnxCmRescueChange":"vDBE-Juniper: jnxCmRescueChange","jnxEventTrap":"vDBE-Juniper: jnxEventTrap","jnxJsFwAuthFailure":"vDBE-Juniper: jnxJsFwAuthFailure","jnxJsFwAuthServiceUp":"vDBE-Juniper: jnxJsFwAuthServiceUp","jnxJsFwAuthServiceDown":"vDBE-Juniper: jnxJsFwAuthServiceDown","jnxJsFwAuthCapacityExceeded":"vDBE-Juniper: jnxJsFwAuthCapacityExceeded","jnxJsIdpSignatureUpdate":"vDBE-Juniper: jnxJsIdpSignatureUpdate","jnxJsIdpAttackLog":"vDBE-Juniper: jnxJsIdpAttackLog","jnxJsSrcNatPoolThresholdStatus":"vDBE-Juniper: jnxJsSrcNatPoolThresholdStatus","jnxJsNatRuleThresholdStatus":"vDBE-Juniper: jnxJsNatRuleThresholdStatus","jnxJsScreenAttack":"vDBE-Juniper: jnxJsScreenAttack","jnxJsScreenCfgChange":"vDBE-Juniper: jnxJsScreenCfgChange","jnxJsAvPatternUpdateTrap":"vDBE-Juniper: jnxJsAvPatternUpdateTrap","jnxJsChassisClusterSwitchover":"vDBE-Juniper: jnxJsChassisClusterSwitchover","jnxJsChClusterIntfTrap":"vDBE-Juniper: jnxJsChClusterIntfTrap","jnxJsChClusterSpuMismatchTrap":"vDBE-Juniper: jnxJsChClusterSpuMismatchTrap","jnxJsChClusterWeightTrap":"vDBE-Juniper: jnxJsChClusterWeightTrap","jnxLicenseGraceExpired":"vDBE-Juniper: jnxLicenseGraceExpired","jnxLicenseGraceAboutToExpire":"vDBE-Juniper: jnxLicenseGraceAboutToExpire","jnxLicenseAboutToExpire":"vDBE-Juniper: jnxLicenseAboutToExpire","jnxLicenseInfringeCumulative":"vDBE-Juniper: jnxLicenseInfringeCumulative","jnxLicenseInfringeSingle":"vDBE-Juniper: jnxLicenseInfringeSingle","jnxNatAddrPoolThresholdStatus":"vDBE-Juniper: jnxNatAddrPoolThresholdStatus","jnxSyslogTrap":"vDBE-Juniper: jnxSyslogTrap","jnxAccessAuthServiceUp":"vDBE-Juniper: jnxAccessAuthServiceUp","jnxAccessAuthServiceDown":"vDBE-Juniper: jnxAccessAuthServiceDown","jnxAccessAuthServerDisabled":"vDBE-Juniper: jnxAccessAuthServerDisabled","jnxAccessAuthServerEnabled":"vDBE-Juniper: jnxAccessAuthServerEnabled","jnxAccessAuthAddressPoolHighThreshold":"vDBE-Juniper: jnxAccessAuthAddressPoolHighThreshold","jnxAccessAuthAddressPoolAbateThreshold":"vDBE-Juniper: jnxAccessAuthAddressPoolAbateThreshold","jnxAccessAuthAddressPoolOutOfAddresses":"vDBE-Juniper: jnxAccessAuthAddressPoolOutOfAddresses","jnxAccessAuthAddressPoolOutOfMemory":"vDBE-Juniper: jnxAccessAuthAddressPoolOutOfMemory","LEVEL_WARNING_CPU":"vMRF: LEVEL_WARNING_CPU","LEVEL_MAJOR_CPU":"vMRF: LEVEL_MAJOR_CPU","LEVEL_CRITICAL_CPU":"vMRF: LEVEL_CRITICAL_CPU","LEVEL_WARNING_MEM":"vMRF: LEVEL_WARNING_MEM","LEVEL_MAJOR_MEM":"vMRF: LEVEL_MAJOR_MEM","LEVEL_CRITICAL_MEM":"vMRF: LEVEL_CRITICAL_MEM","LEVEL_WARNING_DISK":"vMRF: LEVEL_WARNING_DISK","LEVEL_MAJOR_DISK":"vMRF: LEVEL_MAJOR_DISK","LEVEL_CRITICAL_DISK":"vMRF: LEVEL_CRITICAL_DISK","LEVEL_WARNING_RTPBANDWIDTH":"vMRF: LEVEL_WARNING_RTPBANDWIDTH","LEVEL_MAJOR_RTPBANDWIDTH":"vMRF: LEVEL_MAJOR_RTPBANDWIDTH","LEVEL_CRITICAL_RTPBANDWIDTH":"vMRF: LEVEL_CRITICAL_RTPBANDWIDTH","LEVEL_WARNING_RTPINPACKETLOSS":"vMRF: LEVEL_WARNING_RTPINPACKETLOSS","LEVEL_MAJOR_RTPINPACKETLOSS":"vMRF: LEVEL_MAJOR_RTPINPACKETLOSS","LEVEL_CRITICAL_RTPINPACKETLOSS":"vMRF: LEVEL_CRITICAL_RTPINPACKETLOSS","LEVEL_WARNING_RTPOUTPACKETLOSS":"vMRF: LEVEL_WARNING_RTPOUTPACKETLOSS","LEVEL_MAJOR_RTPOUTPACKETLOSS":"vMRF: LEVEL_MAJOR_RTPOUTPACKETLOSS","LEVEL_CRITICAL_RTPOUTPACKETLOSS":"vMRF: LEVEL_CRITICAL_RTPOUTPACKETLOSS","LEVEL_WARNING_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_WARNING_TCPLOSTRETRANSMITRATE","LEVEL_MAJOR_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_MAJOR_TCPLOSTRETRANSMITRATE","LEVEL_CRITICAL_TCPLOSTRETRANSMITRATE":"vMRF: LEVEL_CRITICAL_TCPLOSTRETRANSMITRATE","LEVEL_WARNING_TCPLOSSFAILURERATE":"vMRF: LEVEL_WARNING_TCPLOSSFAILURERATE","LEVEL_MAJOR_TCPLOSSFAILURERATE":"vMRF: LEVEL_MAJOR_TCPLOSSFAILURERATE","LEVEL_CRITICAL_TCPLOSSFAILURERATE":"vMRF: LEVEL_CRITICAL_TCPLOSSFAILURERATE","LEVEL_CRITICAL_RTPLINKDOWN":"vMRF: LEVEL_CRITICAL_RTPLINKDOWN","TARGET_REACHABLE":"vMRF: TARGET_REACHABLE","PUBLICATION_ERROR":"vMRF: PUBLICATION_ERROR","REMOTE_SERVER_SYNCHRONIZATION_ERROR":"vMRF: REMOTE_SERVER_SYNCHRONIZATION_ERROR","TRANSCODER_TOOL_EXEC_ERROR":"vMRF: TRANSCODER_TOOL_EXEC_ERROR","CLIENT_SYNCHRONIZATION_ERROR":"vMRF: CLIENT_SYNCHRONIZATION_ERROR","CLUSTER_UNREACHABLE":"vMRF: CLUSTER_UNREACHABLE","REMOTE_NODE_OFFLINE":"vMRF: REMOTE_NODE_OFFLINE","IPADDR_STOPPED":"vMRF: IPADDR_STOPPED","MRFC_STOPPED":"vMRF: MRFC_STOPPED","MNGT_STOPPED":"vMRF: MNGT_STOPPED","IPADDR_STARTED":"vMRF: IPADDR_STARTED","MRFC_STARTED":"vMRF: MRFC_STARTED","MNGT_STARTED":"vMRF: MNGT_STARTED","VOLATTACH_FAILED":"vMRF: VOLATTACH_FAILED","VOLDETACH_FAILED":"vMRF: VOLDETACH_FAILED","VOLDEL":"vMRF: VOLDEL","VOLCORRUPT":"vMRF: VOLCORRUPT","VOLFOREIGN":"vMRF: VOLFOREIGN","ACTIVE_ALARM_TABLE_PURGE":"vMRF: ACTIVE_ALARM_TABLE_PURGE","GENERIC_FORMER_STATELESS":"vMRF: GENERIC_FORMER_STATELESS","GENERIC_FORMER_STATEFUL":"vMRF: GENERIC_FORMER_STATEFUL","NO_MORE_ALARM_DESCRIPTION":"vMRF: NO_MORE_ALARM_DESCRIPTION","SERVICE_PROCESS_ENDS":"vMRF: SERVICE_PROCESS_ENDS","DEFENSE_STOPPED":"vMRF: DEFENSE_STOPPED","USER_ACCOUNT_LOCKED":"vMRF: USER_ACCOUNT_LOCKED","CONNECTION_SQL_NOT_ESTABLISHED":"vMRF: CONNECTION_SQL_NOT_ESTABLISHED","FALSE_ALARM":"vMRF: FALSE_ALARM","RADIUS SERVER HS":"vMRF: RADIUS SERVER HS","DRM_PACKAGER_IS_NOT_AVAILABLE":"vMRF: DRM_PACKAGER_IS_NOT_AVAILABLE","DRM_LICENSE_BUILDER_IS_NOT_AVAILABLE":"vMRF: DRM_LICENSE_BUILDER_IS_NOT_AVAILABLE","ERROR_WHILE_CREATING_PLAYLIST_MANAGER_FILE":"vMRF: ERROR_WHILE_CREATING_PLAYLIST_MANAGER_FILE","ERROR_WHILE_BUILDING_PLAYLIST_XML_REPRESENTATION":"vMRF: ERROR_WHILE_BUILDING_PLAYLIST_XML_REPRESENTATION","PLAYLIST_FILE_TO_PUBLISH_NOT_FOUND":"vMRF: PLAYLIST_FILE_TO_PUBLISH_NOT_FOUND","COULD_NOT_CONNECT_TO_PVNS_SERVER":"vMRF: COULD_NOT_CONNECT_TO_PVNS_SERVER","HTTP_OR_HTTPCLIENT_EXCEPTION_HAS_OCCURRED":"vMRF: HTTP_OR_HTTPCLIENT_EXCEPTION_HAS_OCCURRED","I/O_ERROR_WHILE_PUBLISHING_PLAYLIST_FILE":"vMRF: I/O_ERROR_WHILE_PUBLISHING_PLAYLIST_FILE","ERROR_WHILE_REQUESTING_SDP_FILE":"vMRF: ERROR_WHILE_REQUESTING_SDP_FILE","ERROR_WHILE_REQUESTING_SDP_FILE:_REMOTE_EXCEPTION":"vMRF: ERROR_WHILE_REQUESTING_SDP_FILE:_REMOTE_EXCEPTION","NO_STREAMING_RESOURCES":"vMRF: NO_STREAMING_RESOURCES","NO_STREAMING_MODULES_REGISTERED":"vMRF: NO_STREAMING_MODULES_REGISTERED","SM_FAILURE":"vMRF: SM_FAILURE","MISSING_FILE_OR_ENCODER":"vMRF: MISSING_FILE_OR_ENCODER","INVALID_RANGE":"vMRF: INVALID_RANGE","THRESHOLD_VALUE_EXCEEDED":"vMRF: THRESHOLD_VALUE_EXCEEDED","TICKET_QUEUE_FULL":"vMRF: TICKET_QUEUE_FULL","PARSING_INITIALIZATION_EXCEPTION":"vMRF: PARSING_INITIALIZATION_EXCEPTION","CUSTOMERCARE_INTERNAL_EXCEPTION":"vMRF: CUSTOMERCARE_INTERNAL_EXCEPTION","PARSING_EXCEPTION":"vMRF: PARSING_EXCEPTION","I/O_PROBLEM":"vMRF: I/O_PROBLEM","INEXISTENT_FILE_OR_FOLDER":"vMRF: INEXISTENT_FILE_OR_FOLDER","FILE_NOT_IN_XML_FORMAT":"vMRF: FILE_NOT_IN_XML_FORMAT","SERVICE_STATE_CHANGE":"vMRF: SERVICE_STATE_CHANGE","MONITORED_FILE_UPDATE_ERROR":"vMRF: MONITORED_FILE_UPDATE_ERROR","MONITORED_RPM_DELETED_ERROR":"vMRF: MONITORED_RPM_DELETED_ERROR","MONITORED_RPM_ADDED_ERROR":"vMRF: MONITORED_RPM_ADDED_ERROR","MONITORED_CHMOD_ERROR":"vMRF: MONITORED_CHMOD_ERROR","MONITORED_CHOWN_ERROR":"vMRF: MONITORED_CHOWN_ERROR","PASSWD_ROOT_ERROR":"vMRF: PASSWD_ROOT_ERROR","PASSWD_ERROR":"vMRF: PASSWD_ERROR","ROOTKIT_ERROR":"vMRF: ROOTKIT_ERROR","STARTUP_ERR_UNDEFINED_PORT":"vMRF: STARTUP_ERR_UNDEFINED_PORT","STARTUP_ERR_FAIL_FIND_HOSTNAME":"vMRF: STARTUP_ERR_FAIL_FIND_HOSTNAME","STARTUP_ERR_CF_MISSING":"vMRF: STARTUP_ERR_CF_MISSING","STARTUP_ERR_FAILED_TO_OPEN_CF":"vMRF: STARTUP_ERR_FAILED_TO_OPEN_CF","STARTUP_ERR_FAILED_TO_BIND_PORT":"vMRF: STARTUP_ERR_FAILED_TO_BIND_PORT","STARTUP_ERR_CFG_UNIT_MISSING":"vMRF: STARTUP_ERR_CFG_UNIT_MISSING","MCTR_INVALID_CODEC_NAME":"vMRF: MCTR_INVALID_CODEC_NAME","RTSP_SERVER_FAILURE":"vMRF: RTSP_SERVER_FAILURE","RTSP_SERVER_QUARANTINE":"vMRF: RTSP_SERVER_QUARANTINE","TRANSCODING_FAILURE":"vMRF: TRANSCODING_FAILURE","FILE_CACHE_FAILURE":"vMRF: FILE_CACHE_FAILURE","STARTUP_ERROR_INITIALIZATION_FAILED":"vMRF: STARTUP_ERROR_INITIALIZATION_FAILED","CONFERENCE_FAILURE":"vMRF: CONFERENCE_FAILURE","PLC_DEGRADATION_LOW":"vMRF: PLC_DEGRADATION_LOW","PLC_DEGRADATION_MEDIUM":"vMRF: PLC_DEGRADATION_MEDIUM","PLC_DEGRADATION_HIGH":"vMRF: PLC_DEGRADATION_HIGH","AUDIO_RESYNCH_LOW":"vMRF: AUDIO_RESYNCH_LOW","AUDIO_RESYNCH_MEDIUM":"vMRF: AUDIO_RESYNCH_MEDIUM","AUDIO_RESYNCH_HIGH":"vMRF: AUDIO_RESYNCH_HIGH","VIDEO_RESYNCH_LOW":"vMRF: VIDEO_RESYNCH_LOW","VIDEO_RESYNCH_MEDIUM":"vMRF: VIDEO_RESYNCH_MEDIUM","VIDEO_RESYNCH_HIGH":"vMRF: VIDEO_RESYNCH_HIGH","PLAY_FAILURES_LOW":"vMRF: PLAY_FAILURES_LOW","PLAY_FAILURES_MEDIUM":"vMRF: PLAY_FAILURES_MEDIUM","PLAY_FAILURES_HIGH":"vMRF: PLAY_FAILURES_HIGH","NOT_ENOUGH_FREE_CONFEREE":"vMRF: NOT_ENOUGH_FREE_CONFEREE","NO_LONGER_FREE_CONFERENCE_ROOM":"vMRF: NO_LONGER_FREE_CONFERENCE_ROOM","STARTUP_ERROR_FAIL_TO_READ_CF":"vMRF: STARTUP_ERROR_FAIL_TO_READ_CF","STARTUP_ERROR_SIP_ADAPTER_INIT":"vMRF: STARTUP_ERROR_SIP_ADAPTER_INIT","STARTUP_ERROR_MONITORING_INIT":"vMRF: STARTUP_ERROR_MONITORING_INIT","REGISTER_ERROR_FAILURE":"vMRF: REGISTER_ERROR_FAILURE","DRI_ERROR_FAILURE":"vMRF: DRI_ERROR_FAILURE","STARTUP_ERROR_STACK_CONFIGURATION":"vMRF: STARTUP_ERROR_STACK_CONFIGURATION","STARTUP_ERROR_CONF":"vMRF: STARTUP_ERROR_CONF","STARTUP_ERROR_UNDEFINED_PORT":"vMRF: STARTUP_ERROR_UNDEFINED_PORT","HOST_REMOVED":"vMRF: HOST_REMOVED","INTERCEPT_THRESHOLD_NB_DIALOG_ALLOCATED":"vMRF: INTERCEPT_THRESHOLD_NB_DIALOG_ALLOCATED","STARTUP_ERROR_STACK_CONF":"vMRF: STARTUP_ERROR_STACK_CONF","STARTUP_ERROR_CONFIGURATION":"vMRF: STARTUP_ERROR_CONFIGURATION","STARTUP_ERROR_FAILED_TO_RETRIEVE_HOSTNAME":"vMRF: STARTUP_ERROR_FAILED_TO_RETRIEVE_HOSTNAME","LEVEL_WARNING_CALL":"vMRF: LEVEL_WARNING_CALL","LEVEL_ALARM_MINOR_CALL":"vMRF: LEVEL_ALARM_MINOR_CALL","LEVEL_ALARM_MAJOR_CALL":"vMRF: LEVEL_ALARM_MAJOR_CALL","LEVEL_ALARM_MRFPoutOfService":"vMRF: LEVEL_ALARM_MRFPoutOfService","MRFP_CALL_REJECTED_Threshold #1":"vMRF: MRFP_CALL_REJECTED_Threshold #1","MRFP_CALL_REJECTED_Threshold #2":"vMRF: MRFP_CALL_REJECTED_Threshold #2","MRFP_CALL_REJECTED_Threshold #3":"vMRF: MRFP_CALL_REJECTED_Threshold #3","MRFP_CALL_RETRIED_Threshold #1":"vMRF: MRFP_CALL_RETRIED_Threshold #1","MRFP_CALL_RETRIED_Threshold #2":"vMRF: MRFP_CALL_RETRIED_Threshold #2","MRFP_CALL_RETRIED_Threshold #3":"vMRF: MRFP_CALL_RETRIED_Threshold #3","STARTUP_PUB_FILE_NOT_PRESENT":"vMRF: STARTUP_PUB_FILE_NOT_PRESENT","STARTUP_INF_FILE_NOT_PRESENT":"vMRF: STARTUP_INF_FILE_NOT_PRESENT","STARTUP_LIC_FILE_NOT_PRESENT":"vMRF: STARTUP_LIC_FILE_NOT_PRESENT","GENERIC_HARDWARE_PROBLEM":"vMRF: GENERIC_HARDWARE_PROBLEM","HARD_DRIVE_PROBLEM":"vMRF: HARD_DRIVE_PROBLEM","NETWORK_LINK_PROBLEM":"vMRF: NETWORK_LINK_PROBLEM","POWER_SUPPLY_PROBLEM":"vMRF: POWER_SUPPLY_PROBLEM","SMART_HARD_DRIVE_PROBLEM":"vMRF: SMART_HARD_DRIVE_PROBLEM","STARTUP_ERROR":"vMRF: STARTUP_ERROR","RESOURCE_NOT_ACCESSIBLE":"vMRF: RESOURCE_NOT_ACCESSIBLE","RESOURCE_ACCESSIBLE":"vMRF: RESOURCE_ACCESSIBLE","RESOURCE_FULL":"vMRF: RESOURCE_FULL","DRI_ALARM":"vMRF: DRI_ALARM","REGISTER_ERROR_CCF":"vMRF: REGISTER_ERROR_CCF","REGISTER_ERROR_EXTERNAL":"vMRF: REGISTER_ERROR_EXTERNAL","TIMEOUT_ERROR":"vMRF: TIMEOUT_ERROR","VXML_ERROR":"vMRF: VXML_ERROR","A Network Element is no longer available due to a connection failure":"vMVM: A Network Element is no longer available due to a connection failure","A MetaSphere server is reporting a fault with the configuration of its connection to MetaView":"vMVM: A MetaSphere server is reporting a fault with the configuration of its connection to MetaView","Configured OBS IPs don't match available OBS nodes. Configured but unavailable nodes include: [<IP address>]. Real nodes not configured include: []":"vMVM: Configured OBS IPs don't match available OBS nodes. Configured but unavailable nodes include: [<IP address>]. Real nodes not configured include: []","Service Assurance Server <IP address> cannot be contacted":"vMVM: Service Assurance Server <IP address> cannot be contacted","The primary MetaView Director has lost contact with the backup MetaView Director":"vMVM: The primary MetaView Director has lost contact with the backup MetaView Director","The active server has lost connection to the standby":"vMVM: The active server has lost connection to the standby","CrashCounter":"vprobes-vBE-Processing: CrashCounter","IsAlive":"vprobes-vBE-Processing: IsAlive","SwRestart":"vprobes-vLB: SwRestart","Repeated exceptions have occurred.":"vSBC-Metaswitch: Repeated exceptions have occurred.","A licensing limit is close to capacity.":"vSBC-Metaswitch: A licensing limit is close to capacity.","One or more feature packs have been breached.":"vSBC-Metaswitch: One or more feature packs have been breached.","The grace period on this Perimeta system will expire in less than 48 hours, after which calls will not be processed.":"vSBC-Metaswitch: The grace period on this Perimeta system will expire in less than 48 hours, after which calls will not be processed.","The grace period on this Perimeta system will expire in less than 7 days, after which calls will not be processed.":"vSBC-Metaswitch: The grace period on this Perimeta system will expire in less than 7 days, after which calls will not be processed.","The license on this Perimeta system will expire in less than 4 weeks.":"vSBC-Metaswitch: The license on this Perimeta system will expire in less than 4 weeks.","A Perimeta blade has become unlicensed.":"vSBC-Metaswitch: A Perimeta blade has become unlicensed.","Perimeta is licensed with a bypass certificate, which is valid until the time displayed.":"vSBC-Metaswitch: Perimeta is licensed with a bypass certificate, which is valid until the time displayed.","The number of licensed instances exceeded a threshold of the licensed limit.":"vSBC-Metaswitch: The number of licensed instances exceeded a threshold of the licensed limit.","The software token on the primary Distributed Capacity Manager will expire on the displayed date.":"vSBC-Metaswitch: The software token on the primary Distributed Capacity Manager will expire on the displayed date.","A capacity limit on the license installed on this Perimeta system does not match the largest limit across all systems in the deployment.":"vSBC-Metaswitch: A capacity limit on the license installed on this Perimeta system does not match the largest limit across all systems in the deployment.","An adjacency has voice quality alerts.":"vSBC-Metaswitch: An adjacency has voice quality alerts.","The number of calls being audited is congested.":"vSBC-Metaswitch: The number of calls being audited is congested.","Session Controller is rejecting calls because there is no valid active call policy set configured.":"vSBC-Metaswitch: Session Controller is rejecting calls because there is no valid active call policy set configured.","A call policy set is inactive because it has been misconfigured.":"vSBC-Metaswitch: A call policy set is inactive because it has been misconfigured.","Session Controller is inactive and rejecting calls.":"vSBC-Metaswitch: Session Controller is inactive and rejecting calls.","Sources have breached minor or major blacklist thresholds.":"vSBC-Metaswitch: Sources have breached minor or major blacklist thresholds.","Sources are blacklisted.":"vSBC-Metaswitch: Sources are blacklisted.","The blacklisting configuration will change as a result of upgrade and some configured blacklists or alerts will no longer be applied.":"vSBC-Metaswitch: The blacklisting configuration will change as a result of upgrade and some configured blacklists or alerts will no longer be applied.","A large number of downgrades and bans have been created as a result of blacklisting.":"vSBC-Metaswitch: A large number of downgrades and bans have been created as a result of blacklisting.","Session Controller is unable to track further sources for blacklisting.":"vSBC-Metaswitch: Session Controller is unable to track further sources for blacklisting.","A software protection switch was triggered.":"vSBC-Metaswitch: A software protection switch was triggered.","A disk area on a processor blade is nearly full.":"vSBC-Metaswitch: A disk area on a processor blade is nearly full.","Memory use is very high.":"vSBC-Metaswitch: Memory use is very high.","The primary processor-blade has lost contact with the backup.":"vSBC-Metaswitch: The primary processor-blade has lost contact with the backup.","An efix or patch has been applied to this system containing diagnostic versions of some software libraries.":"vSBC-Metaswitch: An efix or patch has been applied to this system containing diagnostic versions of some software libraries.","A software protection switch (SPS) was triggered. Call and registration state was lost.":"vSBC-Metaswitch: A software protection switch (SPS) was triggered. Call and registration state was lost.","The Ethernet Heartbeat between primary and backup processors has failed.":"vSBC-Metaswitch: The Ethernet Heartbeat between primary and backup processors has failed.","The Backplane Heartbeat between primary and backup processors has failed.":"vSBC-Metaswitch: The Backplane Heartbeat between primary and backup processors has failed.","A disk area on a processor blade reported an error.":"vSBC-Metaswitch: A disk area on a processor blade reported an error.","The system is upgrading.":"vSBC-Metaswitch: The system is upgrading.","An error with NTP functionality has been detected.":"vSBC-Metaswitch: An error with NTP functionality has been detected.","One or more users are locked out of the system.":"vSBC-Metaswitch: One or more users are locked out of the system.","The Craft Terminal user FTP directory on a processor blade is nearly full.":"vSBC-Metaswitch: The Craft Terminal user FTP directory on a processor blade is nearly full.","A scheduled configuration snapshot has failed.":"vSBC-Metaswitch: A scheduled configuration snapshot has failed.","The Session Controller is stopping as a result of administrator action.":"vSBC-Metaswitch: The Session Controller is stopping as a result of administrator action.","A Session Controller processor blade is stopping as a result of administrator action.":"vSBC-Metaswitch: A Session Controller processor blade is stopping as a result of administrator action.","An object could not be activated because its service address does not exist or is not fully specified.":"vSBC-Metaswitch: An object could not be activated because its service address does not exist or is not fully specified.","The hardware on a processor does not meet minimum requirements.":"vSBC-Metaswitch: The hardware on a processor does not meet minimum requirements.","The hardware expectations of the two processors are not the same.":"vSBC-Metaswitch: The hardware expectations of the two processors are not the same.","The read speed of the main hard disk on a processor blade is too slow.":"vSBC-Metaswitch: The read speed of the main hard disk on a processor blade is too slow.","An error has occurred reading from the hard disk on a processor blade.":"vSBC-Metaswitch: An error has occurred reading from the hard disk on a processor blade.","Backup and primary processor-blades have an inconsistent system role.":"vSBC-Metaswitch: Backup and primary processor-blades have an inconsistent system role.","Event: The system encountered a critical error and had to restart.":"vSBC-Metaswitch: Event: The system encountered a critical error and had to restart.","Event: A RADIUS server failed to respond to an authentication request.":"vSBC-Metaswitch: Event: A RADIUS server failed to respond to an authentication request.","Event: All configured RADIUS servers failed to respond to authentication requests.":"vSBC-Metaswitch: Event: All configured RADIUS servers failed to respond to authentication requests.","Event: The number of CPUs has changed.":"vSBC-Metaswitch: Event: The number of CPUs has changed.","Event: A user has been automatically deleted":"vSBC-Metaswitch: Event: A user has been automatically deleted","The primary processor blade has lost management connectivity":"vSBC-Metaswitch: The primary processor blade has lost management connectivity","Event: A processor blade is running with DPDK mode disabled when DPDK mode is,expected.":"vSBC-Metaswitch: Event: A processor blade is running with DPDK mode disabled when DPDK mode is,expected.","Event: Processor blade %1 is running with DPDK mode disabled when DPDK mode may be possible.":"vSBC-Metaswitch: Event: Processor blade %1 is running with DPDK mode disabled when DPDK mode may be possible.","Perimeta is attempting to resend cached billing records.":"vSBC-Metaswitch: Perimeta is attempting to resend cached billing records.","The Rf billing cache is full.":"vSBC-Metaswitch: The Rf billing cache is full.","The inbound call queue is congested.":"vSBC-Metaswitch: The inbound call queue is congested.","A configured realm group contains realms that are not available to the SBC.":"vSBC-Metaswitch: A configured realm group contains realms that are not available to the SBC.","An allowed MSC configuration is not connected to any physical MSCs.":"vSBC-Metaswitch: An allowed MSC configuration is not connected to any physical MSCs.","A SIP Peer has stopped responding to SIP OPTIONS pings.  MSW: 20160303: Alarm text is changed in v3.9 software to read: \\"An adjacency has lost connectivity, according to SIP OPTIONS pings\\"":"vSBC-Metaswitch: A SIP Peer has stopped responding to SIP OPTIONS pings.  MSW: 20160303: Alarm text is changed in v3.9 software to read: \\"An adjacency has lost connectivity, according to SIP OPTIONS pings\\"","An adjacency has failed as the listen socket could not be created. Check for configuration mismatches with the associated service interface.":"vSBC-Metaswitch: An adjacency has failed as the listen socket could not be created. Check for configuration mismatches with the associated service interface.","No suitable DNS records were found for a peer group's DNS hostname.":"vSBC-Metaswitch: No suitable DNS records were found for a peer group's DNS hostname.","One or more SIP peers from a peer group have stopped responding to SIP OPTIONS pings":"vSBC-Metaswitch: One or more SIP peers from a peer group have stopped responding to SIP OPTIONS pings","An adjacency has failed as its service network does not match the service network on its associated peer group.":"vSBC-Metaswitch: An adjacency has failed as its service network does not match the service network on its associated peer group.","An adjacency has failed as its configured TLS certificate could not be found.":"vSBC-Metaswitch: An adjacency has failed as its configured TLS certificate could not be found.","The caching function has not been initialized properly.":"vSBC-Metaswitch: The caching function has not been initialized properly.","An adjacency has failed as the listen socket could not be created.":"vSBC-Metaswitch: An adjacency has failed as the listen socket could not be created.","An adjacency is congested and may be rejecting calls.":"vSBC-Metaswitch: An adjacency is congested and may be rejecting calls.","There is an issue with a Diameter peer.":"vSBC-Metaswitch: There is an issue with a Diameter peer.","A realm is no longer reachable via any configured peers.":"vSBC-Metaswitch: A realm is no longer reachable via any configured peers.","An FQDN for a configured Diameter peer has failed to resolve to a valid IP address.":"vSBC-Metaswitch: An FQDN for a configured Diameter peer has failed to resolve to a valid IP address.","One or more peers resolved from a DNS lookup of a configured peer's address cannot be contacted":"vSBC-Metaswitch: One or more peers resolved from a DNS lookup of a configured peer's address cannot be contacted","An interface ARP or NDP probe has failed.":"vSBC-Metaswitch: An interface ARP or NDP probe has failed.","One or more IP address conflicts have been detected on service interfaces with zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.":"vSBC-Metaswitch: One or more IP address conflicts have been detected on service interfaces with zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.","One or more IP address conflicts have been detected on service interfaces with non-zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.":"vSBC-Metaswitch: One or more IP address conflicts have been detected on service interfaces with non-zero criticality. If there are other probe failures, this alarm will remain raised until all conflicts are resolved.","An interface device is running below the expected speed. This alarm was originally triggered by a probe failure on a service interface.":"vSBC-Metaswitch: An interface device is running below the expected speed. This alarm was originally triggered by a probe failure on a service interface.","An interface device is running above the expected speed.":"vSBC-Metaswitch: An interface device is running above the expected speed.","An IP address conflict has been detected on a management interface.":"vSBC-Metaswitch: An IP address conflict has been detected on a management interface.","An interface ICMP probe has failed.":"vSBC-Metaswitch: An interface ICMP probe has failed.","A High-Availability link has detected a connectivity issue.":"vSBC-Metaswitch: A High-Availability link has detected a connectivity issue.","An HA-link device is being reported as underspeed.":"vSBC-Metaswitch: An HA-link device is being reported as underspeed.","An IP address conflict has been detected on a replication interface.":"vSBC-Metaswitch: An IP address conflict has been detected on a replication interface.","The Session Controller has started.":"vSBC-Metaswitch: The Session Controller has started.","A statistic exceeded its configured thresholds.":"vSBC-Metaswitch: A statistic exceeded its configured thresholds.","One or more statistic has not been retrieved at least 3 times in a row.":"vSBC-Metaswitch: One or more statistic has not been retrieved at least 3 times in a row.","A Refresh Alarms request was triggered. Alarms not re-raised will be cleared in 5 minutes.":"vSBC-Metaswitch: A Refresh Alarms request was triggered. Alarms not re-raised will be cleared in 5 minutes.","A statistic has exceeded its configured thresholds.":"vSBC-Metaswitch: A statistic has exceeded its configured thresholds.","A Fallback Operation will soon be started":"vSBG: A Fallback Operation will soon be started","BRM, Auto Export Backup Failed":"vSBG: BRM, Auto Export Backup Failed","BRM, Scheduled Backup Failed":"vSBG: BRM, Scheduled Backup Failed","COM SA, AMF Component Cleanup Failed":"vSBG: COM SA, AMF Component Cleanup Failed","COM SA, AMF Component Instantiation Failed":"vSBG: COM SA, AMF Component Instantiation Failed","COM SA, AMF SI Unassigned":"vSBG: COM SA, AMF SI Unassigned","COM SA, CLM Cluster Node Unavailable":"vSBG: COM SA, CLM Cluster Node Unavailable","COM SA, MDF Detected Model Error":"vSBG: COM SA, MDF Detected Model Error","COM SA, Proxy Status of a Component Changed to Unproxied":"vSBG: COM SA, Proxy Status of a Component Changed to Unproxied","File Management, Number of Files in FileGroup Exceeded":"vSBG: File Management, Number of Files in FileGroup Exceeded","File Management, Max Size in FileGroup Exceeded":"vSBG: File Management, Max Size in FileGroup Exceeded","LOTC Disk Replication Communication":"vSBG: LOTC Disk Replication Communication","LOTC Disk Replication Consistency":"vSBG: LOTC Disk Replication Consistency","LOTC Disk Usage":"vSBG: LOTC Disk Usage","LOTC memory Usage":"vSBG: LOTC memory Usage","LOTC Time Synchronization":"vSBG: LOTC Time Synchronization","SBG, BGF Control Link Down":"vSBG: SBG, BGF Control Link Down","SBG, BGF Control Link Disabled":"vSBG: SBG, BGF Control Link Disabled","SBG, BGF Control Link Enabled":"vSBG: SBG, BGF Control Link Enabled","SBG, BGF Control Link Remote Locked":"vSBG: SBG, BGF Control Link Remote Locked","SBG, Charging Data Storage Maximum Records Reached":"vSBG: SBG, Charging Data Storage Maximum Records Reached","SBG, Charging Server Rejects Charging Data":"vSBG: SBG, Charging Server Rejects Charging Data","SBG, Excessive Packet Rate Detected ":"vSBG: SBG, Excessive Packet Rate Detected ","SBG, High Amount of Malformed Packets Received":"vSBG: SBG, High Amount of Malformed Packets Received","SBG, High Amount of STUN Packets Detected":"vSBG: SBG, High Amount of STUN Packets Detected","SBG, High Amount of TCP SYN Packets Received":"vSBG: SBG, High Amount of TCP SYN Packets Received","SBG, High Amount of UDP Packets Received ":"vSBG: SBG, High Amount of UDP Packets Received ","SBG, IP Address Blocked Due to Excessive Packet Rate":"vSBG: SBG, IP Address Blocked Due to Excessive Packet Rate","SBG, Lost Connectivity to Diameter Server":"vSBG: SBG, Lost Connectivity to Diameter Server","SBG, Mated Pair out of Service":"vSBG: SBG, Mated Pair out of Service","SBG, Network Unavailable for Media Handling":"vSBG: SBG, Network Unavailable for Media Handling","SBG, Non-emergency Call Released to Free Resources for Emergency Call":"vSBG: SBG, Non-emergency Call Released to Free Resources for Emergency Call","SBG, Not Enough Disk Space for Storing Charging Data":"vSBG: SBG, Not Enough Disk Space for Storing Charging Data","SBG, Payload Mated Pair Failure":"vSBG: SBG, Payload Mated Pair Failure","SBG, Payload Processor Failure":"vSBG: SBG, Payload Processor Failure","SBG, Processor Overloaded":"vSBG: SBG, Processor Overloaded","SBG, Registered User Set in Quarantine":"vSBG: SBG, Registered User Set in Quarantine","SBG, Registration Contacts Exceed Configured Threshold":"vSBG: SBG, Registration Contacts Exceed Configured Threshold","SBG, Sequential Restart Initiated":"vSBG: SBG, Sequential Restart Initiated","SBG, SIP Abuse Detected":"vSBG: SBG, SIP Abuse Detected","SBG, SIP Network Locked":"vSBG: SBG, SIP Network Locked","SBG, SIP Next Hop Reachable":"vSBG: SBG, SIP Next Hop Reachable","SBG, SIP Next Hop Unreachable":"vSBG: SBG, SIP Next Hop Unreachable","SBG, SIP Request Rejected by Network Throttling":"vSBG: SBG, SIP Request Rejected by Network Throttling","SBG, TLS Certificate Imported":"vSBG: SBG, TLS Certificate Imported","SBG, Trace Recording Session Number Limit Reached":"vSBG: SBG, Trace Recording Session Number Limit Reached","SBG, Trace Session Deactivated":"vSBG: SBG, Trace Session Deactivated","SBG, Trace Session Times Out":"vSBG: SBG, Trace Session Times Out","SBG, Unknown Media Type or Payload Type":"vSBG: SBG, Unknown Media Type or Payload Type"}
+#
+# if action.test.override is true, then any action will be marked as test=true (even if incoming action request had test=false); otherwise, test flag will be unchanged on the action request
+action.test.override=false
+# if action.insert.test.event is true, then insert event even if the action is set to test
+action.insert.test.event=false
+CLDS_SERVICE_CACHE_MAX_SECONDS=14400
+#
+globalProps={"collector": {"topicPublishes": {"DCAE-COLLECTOR-UCSNMP": "DCAE-COLLECTOR-UCSNMP",        "GFP-IP-SNMP-TRAPS" : "GFP-IP-SNMP-TRAPS"       }       },      "string_match": {               "topicPublishes": {                     "DCAE-CL-EVENT": "DCAE-CL-EVENT"                },              "aaiMatchingFields": {                  "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "ProvStatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "aaiSendFields": {                      "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "Provstatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "eventSourceType": {                    "f5BigIP": "f5BigIP",                   "vSBG_Alarms": "vSBG_Alarms",                   "vCTS_Alarms": "vCTS_Alarms"            },              "eventSeverity": {                      "NORMAL": "NORMAL",                     "not-NORMAL": "not-NORMAL",                     "WARNING": "WARNING",                   "MINOR": "MINOR",                       "MAJOR": "MAJOR",                       "CRITICAL": "CRITICAL"          },              "timeWindow": 0,                "ageLimit": 1600,               "outputEventName": {                    "": "",                         "OnSet": "OnSet",                       "Abatement": "Abatement"                },              "createClosedLoopEventId": {                    "Initial": "Initial",                   "Close": "Close"                }       },      "global": {             "service": {                    "": "",                         "vUSP": "vUSP",                         "vSCP": "vSCP",                         "vProbes": "vProbes"            }       },      "policy": {             "timeout": 5,           "recipe": {                     "": "",                         "restart": "Restart",                   "rebuild": "Rebuild",                   "migrate": "Migrate"            },              "maxRetries": "3",              "retryTimeLimit": 180,          "resource": {                   "vCTS": "vCTS",                         "v3CDB": "v3CDB",                       "vUDR": "vUDR",                         "vCOM": "vCOM",                         "vRAR": "vRAR",                         "vLCS": "vLCS",                         "vUDR-BE": "vUDR-BE",                   "vDBE": "vDBE"          },              "parentPolicyConditions": {                     "Failure_Retries": "Failure: Max Retries Exceeded",                     "Failure_Timeout": "Failure: Time Limit Exceeded",                      "Failure_Exception": "Failure: Exception",                      "Failure": "Failure: Other",                    "Success": "Success"            }       },      "shared": {             "byService": {                  "": {                           "vf": {                                 },                              "vfc": {                                },                              "location": {                           },                              "alarmCondition": {                             }                       },                      "vSCP": {                               "vf": {                                         "frwl_scp": "FW"                                },                              "vfc": {                                        "FW": "FW"                              },                              "location": {                                   "AKRNOHAH": "Akron",                                    "ALLNTXSA": "Allen-2"                           },                              "alarmCondition": {                                     "authenticationFailure": "authenticationFailure",                                       "bigipActive": "bigipActive",                                   "bigipActiveActive": "bigipActiveActive",                                       "bigipAgentRestart": "bigipAgentRestart",                                       "bigipAgentShutdown": "bigipAgentShutdown",                                     "bigipAgentStart": "bigipAgentStart",                                   "bigipAggrReaperStateChange": "bigipAggrReaperStateChange",                                     "bigipAomCpuTempTooHigh": "bigipAomCpuTempTooHigh",                                     "bigipARPConflict": "bigipARPConflict",                                         "bigipAsmBruteForceAttackDetected": "bigipAsmBruteForceAttackDetected",                                         "bigipAsmDosAttackDetected": "bigipAsmDosAttackDetected",                                       "bigipAsmFtpRequestBlocked": "bigipAsmFtpRequestBlocked",                                       "bigipAsmFtpRequestViolation": "bigipAsmFtpRequestViolation",                                   "bigipAsmRequestBlocked": "bigipAsmRequestBlocked",                                     "bigipAsmRequestViolation": "bigipAsmRequestViolation",                                         "bigipAsmSmtpRequestBlocked": "bigipAsmSmtpRequestBlocked",                                     "bigipAsmSmtpRequestViolation": "bigipAsmSmtpRequestViolation",                                         "bigipAuthFailed": "bigipAuthFailed",                                   "bigipAvrAlertsMetricSmtp": "bigipAvrAlertsMetricSmtp",                                         "bigipAvrAlertsMetricSnmp": "bigipAvrAlertsMetricSnmp",                                         "bigipBladeNoPower": "bigipBladeNoPower",                                       "bigipBladeOffline": "bigipBladeOffline",                                       "bigipBladeTempHigh": "bigipBladeTempHigh",                                     "bigipChassisFanBad": "bigipChassisFanBad",                                     "bigipChassisPowerSupplyBad": "bigipChassisPowerSupplyBad",                                     "bigipChassisTempHigh": "bigipChassisTempHigh",                                         "bigipChmandAlertFanTrayBad": "bigipChmandAlertFanTrayBad",                                     "bigipClusterdNoResponse": "bigipClusterdNoResponse",                                   "bigipClusterPrimaryChanged": "bigipClusterPrimaryChanged",                                     "bigipCompLimitExceeded": "bigipCompLimitExceeded",                                     "bigipConfigLoaded": "bigipConfigLoaded",                                       "bigipCpuFanSpeedBad": "bigipCpuFanSpeedBad",                                   "bigipCpuFanSpeedLow": "bigipCpuFanSpeedLow",                                   "bigipCpuTempHigh": "bigipCpuTempHigh",                                         "bigipDiskPartitionGrowth": "bigipDiskPartitionGrowth",                                         "bigipDiskPartitionWarn": "bigipDiskPartitionWarn",                                     "bigipDnsRequestRateLimiterEngaged": "bigipDnsRequestRateLimiterEngaged",                                       "bigipDosAttackStart": "bigipDosAttackStart",                                   "bigipDosAttackStop": "bigipDosAttackStop",                                     "bigipExternalLinkChange": "bigipExternalLinkChange",                                   "bigipFeatureFailed": "bigipFeatureFailed",                                     "bigipFeatureOnline": "bigipFeatureOnline",                                             "bigipFipsDeviceError": "bigipFipsDeviceError",                                         "bigipGtmAppAvail": "bigipGtmAppAvail",                                         "bigipGtmAppNotAvail": "bigipGtmAppNotAvail",                                   "bigipGtmAppObjAvail": "bigipGtmAppObjAvail",                                   "bigipGtmAppObjNotAvail": "bigipGtmAppObjNotAvail",                                     "bigipGtmBig3dSslCertExpired": "bigipGtmBig3dSslCertExpired",                                   "bigipGtmBig3dSslCertWillExpire": "bigipGtmBig3dSslCertWillExpire",                                     "bigipGtmBoxAvail": "bigipGtmBoxAvail",                                         "bigipGtmBoxNotAvail": "bigipGtmBoxNotAvail",                                   "bigipGtmDcAvail": "bigipGtmDcAvail",                                   "bigipGtmDcDisabled": "bigipGtmDcDisabled",                                     "bigipGtmDcEnabled": "bigipGtmDcEnabled",                                       "bigipGtmDcNotAvail": "bigipGtmDcNotAvail",                                     "bigipGtmJoinedGroup": "bigipGtmJoinedGroup",                                   "bigipGtmKeyGenerationExpiration": "bigipGtmKeyGenerationExpiration",                                   "bigipGtmKeyGenerationRollover": "bigipGtmKeyGenerationRollover",                                       "bigipGtmLeftGroup": "bigipGtmLeftGroup",                                       "bigipGtmLinkAvail": "bigipGtmLinkAvail",                                       "bigipGtmLinkDisabled": "bigipGtmLinkDisabled",                                         "bigipGtmLinkEnabled": "bigipGtmLinkEnabled",                                   "bigipGtmLinkNotAvail": "bigipGtmLinkNotAvail",                                         "bigipGtmPoolAvail": "bigipGtmPoolAvail",                                       "bigipGtmPoolDisabled": "bigipGtmPoolDisabled",                                         "bigipGtmPoolEnabled": "bigipGtmPoolEnabled",                                   "bigipGtmPoolMbrAvail": "bigipGtmPoolMbrAvail",                                         "bigipGtmPoolMbrDisabled": "bigipGtmPoolMbrDisabled",                                   "bigipGtmPoolMbrEnabled": "bigipGtmPoolMbrEnabled",                                     "bigipGtmPoolMbrNotAvail": "bigipGtmPoolMbrNotAvail",                                   "bigipGtmPoolNotAvail": "bigipGtmPoolNotAvail",                                         "bigipGtmProberPoolDisabled": "bigipGtmProberPoolDisabled",                                     "bigipGtmProberPoolEnabled": "bigipGtmProberPoolEnabled",                                       "bigipGtmProberPoolMbrDisabled": "bigipGtmProberPoolMbrDisabled",                                       "bigipGtmProberPoolMbrEnabled": "bigipGtmProberPoolMbrEnabled",                                         "bigipGtmProberPoolMbrStatusChange": "bigipGtmProberPoolMbrStatusChange",                                       "bigipGtmProberPoolMbrStatusChangeReason": "bigipGtmProberPoolMbrStatusChangeReason",                                   "bigipGtmProberPoolStatusChange": "bigipGtmProberPoolStatusChange",                                     "bigipGtmProberPoolStatusChangeReason": "bigipGtmProberPoolStatusChangeReason",                                         "bigipGtmRequestRateLimiterEngaged": "bigipGtmRequestRateLimiterEngaged",                                       "bigipGtmServerAvail": "bigipGtmServerAvail",                                   "bigipGtmServerDisabled": "bigipGtmServerDisabled",                                     "bigipGtmServerEnabled": "bigipGtmServerEnabled",                                       "bigipGtmServerNotAvail": "bigipGtmServerNotAvail",                                     "bigipGtmSslCertExpired": "bigipGtmSslCertExpired",                                     "bigipGtmSslCertWillExpire": "bigipGtmSslCertWillExpire",                                       "bigipGtmVsAvail": "bigipGtmVsAvail",                                   "bigipGtmVsDisabled": "bigipGtmVsDisabled",                                     "bigipGtmVsEnabled": "bigipGtmVsEnabled",                                       "bigipGtmVsNotAvail": "bigipGtmVsNotAvail",                                     "bigipGtmWideIpAvail": "bigipGtmWideIpAvail",                                   "bigipGtmWideIpDisabled": "bigipGtmWideIpDisabled",                                     "bigipGtmWideIpEnabled": "bigipGtmWideIpEnabled",                                       "bigipGtmWideIpNotAvail": "bigipGtmWideIpNotAvail",                                     "bigipHardDiskFailure": "bigipHardDiskFailure",                                         "bigipInetPortExhaustion": "bigipInetPortExhaustion",                                   "bigipLibhalBladePoweredOff": "bigipLibhalBladePoweredOff",                                     "bigipLibhalDiskBayRemoved": "bigipLibhalDiskBayRemoved",                                       "bigipLibhalSensorAlarmCritical": "bigipLibhalSensorAlarmCritical",                                     "bigipLibhalSsdLogicalDiskRemoved": "bigipLibhalSsdLogicalDiskRemoved",                                         "bigipLibhalSsdPhysicalDiskRemoved": "bigipLibhalSsdPhysicalDiskRemoved",                                       "bigipLicenseExpired": "bigipLicenseExpired",                                   "bigipLicenseFailed": "bigipLicenseFailed",                                     "bigipLogAlert": "bigipLogAlert",                                       "bigipLogCrit": "bigipLogCrit",                                         "bigipLogEmerg": "bigipLogEmerg",                                       "bigipLogErr": "bigipLogErr",                                   "bigipLogWarning": "bigipLogWarning",                                   "bigipLtmVsAvail": "bigipLtmVsAvail",                                   "bigipLtmVsDisabled": "bigipLtmVsDisabled",                                     "bigipLtmVsEnabled": "bigipLtmVsEnabled",                                       "bigipLtmVsUnavail": "bigipLtmVsUnavail",                                       "bigipMemberRate": "bigipMemberRate",                                   "bigipNetLinkDown": "bigipNetLinkDown",                                         "bigipNodeDown": "bigipNodeDown",                                       "bigipNodeRate": "bigipNodeRate",                                       "bigipNodeUp": "bigipNodeUp",                                   "bigipPacketRejected": "bigipPacketRejected",                                   "bigipPsAbsent": "bigipPsAbsent",                                       "bigipPsPowerOff": "bigipPsPowerOff",                                   "bigipPsPowerOn": "bigipPsPowerOn",                                     "bigipRaidDiskFailure": "bigipRaidDiskFailure",                                         "bigipServiceDown": "bigipServiceDown",                                         "bigipServiceUp": "bigipServiceUp",                                     "bigipSsdMwiNearThreshold": "bigipSsdMwiNearThreshold",                                         "bigipSsdMwiReachedThreshold": "bigipSsdMwiReachedThreshold",                                   "bigipSslLimitExceeded": "bigipSslLimitExceeded",                                       "bigipStandby": "bigipStandby",                                         "bigipStandByFail": "bigipStandByFail",                                         "bigipSystemCheckAlertCurrentHigh": "bigipSystemCheckAlertCurrentHigh",                                         "bigipSystemCheckAlertCurrentLow": "bigipSystemCheckAlertCurrentLow",                                   "bigipSystemCheckAlertFanSpeedLow": "bigipSystemCheckAlertFanSpeedLow",                                         "bigipSystemCheckAlertMilliVoltageHigh": "bigipSystemCheckAlertMilliVoltageHigh",                                       "bigipSystemCheckAlertMilliVoltageLow": "bigipSystemCheckAlertMilliVoltageLow",                                         "bigipSystemCheckAlertPowerHigh": "bigipSystemCheckAlertPowerHigh",                                     "bigipSystemCheckAlertPowerLow": "bigipSystemCheckAlertPowerLow",                                       "bigipSystemCheckAlertTempHigh": "bigipSystemCheckAlertTempHigh",                                       "bigipSystemCheckAlertVoltageHigh": "bigipSystemCheckAlertVoltageHigh",                                         "bigipSystemCheckAlertVoltageLow": "bigipSystemCheckAlertVoltageLow",                                   "bigipSystemShutdown": "bigipSystemShutdown",                                   "bigipTamdAlert": "bigipTamdAlert",                                     "bigipTrafficGroupActivate": "bigipTrafficGroupActivate",                                       "bigipTrafficGroupActive": "bigipTrafficGroupActive",                                   "bigipTrafficGroupDeactivate": "bigipTrafficGroupDeactivate",                                   "bigipTrafficGroupForcedOffline": "bigipTrafficGroupForcedOffline",                                     "bigipTrafficGroupOffline": "bigipTrafficGroupOffline",                                         "bigipTrafficGroupStandby": "bigipTrafficGroupStandby",                                         "bigipUnsolicitedRepliesExceededThreshold": "bigipUnsolicitedRepliesExceededThreshold",                                         "bigipUpdateError": "bigipUpdateError",                                         "bigipUpdatePriority": "bigipUpdatePriority",                                   "bigipUpdateServer": "bigipUpdateServer",                                       "bigipVcmpAlertsVcmpHBDetected": "bigipVcmpAlertsVcmpHBDetected",                                       "bigipVcmpAlertsVcmpHBLost": "bigipVcmpAlertsVcmpHBLost",                                       "bigipVcmpAlertsVcmpPowerOff": "bigipVcmpAlertsVcmpPowerOff",                                   "bigipVcmpAlertsVcmpPowerOn": "bigipVcmpAlertsVcmpPowerOn",                                     "bigipVirtualRate": "bigipVirtualRate",                                         "coldStart": "coldStart",                                       "emASMSigInstallComplete": "emASMSigInstallComplete",                                   "emASMSigInstallFailed": "emASMSigInstallFailed",                                       "emASMSigUpdateAvailable": "emASMSigUpdateAvailable",                                   "emASMSigUpdateFailed": "emASMSigUpdateFailed",                                         "emCertificateExpiration": "emCertificateExpiration",                                   "emCpuUsage": "emCpuUsage",                                     "emDeviceActiveMode": "emDeviceActiveMode",                                     "emDeviceClockSkew": "emDeviceClockSkew",                                       "emDeviceConfigSettingChanged": "emDeviceConfigSettingChanged",                                         "emDeviceConfigSync": "emDeviceConfigSync",                                     "emDeviceForcedOfflineMode": "emDeviceForcedOfflineMode",                                       "emDeviceImpaired": "emDeviceImpaired",                                         "emDeviceOfflineMode": "emDeviceOfflineMode",                                   "emDeviceStandbyMode": "emDeviceStandbyMode",                                   "emDeviceUnreachable": "emDeviceUnreachable",                                   "emDiskUsage": "emDiskUsage",                                   "emGatherServiceContractFailure": "emGatherServiceContractFailure",                                     "emHaSyncFailed": "emHaSyncFailed",                                     "emHotfixInstallComplete": "emHotfixInstallComplete",                                   "emHotfixInstallFailed": "emHotfixInstallFailed",                                       "emMemoryUsage": "emMemoryUsage",                                       "emPerformanceStorageCap": "emPerformanceStorageCap",                                   "emPerformanceStorageDays": "emPerformanceStorageDays",                                         "emPerformanceThreshold": "emPerformanceThreshold",                                     "emRaidDriveFailureDetected": "emRaidDriveFailureDetected",                                     "emRaidDriveRebuildComplete": "emRaidDriveRebuildComplete",                                     "emSchedBackupFailed": "emSchedBackupFailed",                                   "emScheduledArchiveFailed": "emScheduledArchiveFailed",                                         "emServiceContractExpiry": "emServiceContractExpiry",                                   "emSoftwareInstallComplete": "emSoftwareInstallComplete",                                       "emSoftwareInstallFailed": "emSoftwareInstallFailed",                                   "emStatsCollectionRateCap": "emStatsCollectionRateCap",                                         "emStatsDBConnectivityLost": "emStatsDBConnectivityLost",                                       "emStatsDBConnectivityRestored": "emStatsDBConnectivityRestored",                                       "fallingAlarm": "fallingAlarm",                                         "ipv6IfStateChange": "ipv6IfStateChange",                                       "linkDown": "linkDown",                                         "linkUp": "linkUp",                                     "mteEventSetFailure": "mteEventSetFailure",                                     "mteTriggerFailure": "mteTriggerFailure",                                       "mteTriggerFalling": "mteTriggerFalling",                                       "mteTriggerFired": "mteTriggerFired",                                   "mteTriggerRising": "mteTriggerRising",                                         "netSnmpExampleHeartbeatNotification": "netSnmpExampleHeartbeatNotification",                                   "newRoot": "newRoot",                                   "nsNotifyRestart": "nsNotifyRestart",                                   "nsNotifyShutdown": "nsNotifyShutdown",                                         "nsNotifyStart": "nsNotifyStart",                                       "risingAlarm": "risingAlarm",                                   "schedActionFailure": "schedActionFailure",                                     "smScriptAbort": "smScriptAbort",                                       "smScriptException": "smScriptException",                                       "smScriptResult": "smScriptResult",                                     "topologyChange": "topologyChange",                                     "ucdShutdown": "ucdShutdown",                                   "ucdStart": "ucdStart",                                         "warmStart": "warmStart"                                }                       },                      "vUSP": {                               "vf": {                                         "ctsf-xxx": "vCTS"                              },                              "vfc": {                                        "vCTS - CFED": "vCTS - CFED",                                   "vCTS - Config": "vCTS - Config",                                       "vCTS - DFED": "vCTS - DFED",                                   "vCTS - TAFE-fsd": "vCTS - TAFE-fsd",                                   "vCTS - GLS": "vCTS - GLS",                                     "vCTS - XXX": "vCTS - XXX",                                     "vCTS - Management Interface": "vCTS - Management Interface",                                   "vCTS - SPFE-pfe": "vCTS - SPFE-pfe",                                   "vCTS - DNS": "vCTS - DNS",                                     "vCTS - SPFE-spd": "vCTS - SPFE-spd",                                   "vCTS - SPFE-spt": "vCTS - SPFE-spt",                                   "vCTS - TAFE-tas": "vCTS - TAFE-tas"                            },                              "location": {                                   "SNDGCA06": "San Diego(core site) A06",                                         "SNDGCA64": "San Diego(core site) A64",                                         "SNANTXCA": "San Antonio(core site)",                                   "KSCYMO09": "Kansas City(core site)",                                   "kings_mountain": "Kings Mountain(AMG)",                                        "Secaucus": "Secaucus(AMG)",                                    "lisle": "Lisle(AMG)",                                  "concord": "Concord(AMG)",                                      "houston": "Houston(AMG)",                                      "akron": "Akron(AMG)"                           },                              "alarmCondition": {                                     "acrTemporaryBufferOverload": "acrTemporaryBufferOverload",                                     "adnsExtendedTTLcaching": "adnsExtendedTTLcaching",                                     "adnsQueryFailureCaching": "adnsQueryFailureCaching",                                   "adnsQueueCongestion": "adnsQueueCongestion",                                   "asdaCommunicationFailure": "asdaCommunicationFailure",                                         "asdaRequestQueue": "asdaRequestQueue",                                         "capacityLicenseKeyExpiration": "capacityLicenseKeyExpiration",                                         "capacityLicenseKeyNearExpiration": "capacityLicenseKeyNearExpiration",                                         "capacityLicenseKeyValidationError": "capacityLicenseKeyValidationError",                                       "cardConnectionLost": "cardConnectionLost",                                     "ccdbCommunicationFailure": "ccdbCommunicationFailure",                                         "cpiAlrmCritical": "cpiAlrmCritical",                                   "cpiAlrmMajor": "cpiAlrmMajor",                                         "cpiAlrmMinor": "cpiAlrmMinor",                                         "cpiAlrmWarning": "cpiAlrmWarning",                                     "cpiAsrtEsc": "cpiAsrtEsc",                                     "cpiAsrtNonEsc": "cpiAsrtNonEsc",                                       "cpiAsrtNonEscCritical": "cpiAsrtNonEscCritical",                                       "cpiAsrtNonEscMajor": "cpiAsrtNonEscMajor",                                     "cpiAsrtNonEscMinor": "cpiAsrtNonEscMinor",                                     "cpiAudErrCount": "cpiAudErrCount",                                     "cpiAudManAct": "cpiAudManAct",                                         "cpiAudNewEvent": "cpiAudNewEvent",                                     "cpiCompleteRateAlarm": "cpiCompleteRateAlarm",                                         "cpiCTS3xxFailRate": "cpiCTS3xxFailRate",                                       "cpiCTS4xxFailRate": "cpiCTS4xxFailRate",                                       "cpiCTS5xxFailRate": "cpiCTS5xxFailRate",                                       "cpiCTS6xxFailRate": "cpiCTS6xxFailRate",                                       "cpiCTSSIPRetransmitInvite": "cpiCTSSIPRetransmitInvite",                                       "cpiCTSSIPRetransmitNonInvite": "cpiCTSSIPRetransmitNonInvite",                                         "cpiDropMGAllocConnReq": "cpiDropMGAllocConnReq",                                       "cpiDropRateAlarm": "cpiDropRateAlarm",                                         "cpiExceptionService": "cpiExceptionService",                                   "cpiFailRateAlarm": "cpiFailRateAlarm",                                         "cpiFailSCTPFastRetransIncr": "cpiFailSCTPFastRetransIncr",                                     "cpiFailSCTPFastRetransRate": "cpiFailSCTPFastRetransRate",                                     "cpiFailSCTPSRTT1Incr": "cpiFailSCTPSRTT1Incr",                                         "cpiFailSCTPSRTT2Incr": "cpiFailSCTPSRTT2Incr",                                         "cpiFailSCTPT3RetransIncr": "cpiFailSCTPT3RetransIncr",                                         "cpiFailSCTPT3RetransRate": "cpiFailSCTPT3RetransRate",                                         "cpiFileSysUsage": "cpiFileSysUsage",                                   "cpiMemAllocFail": "cpiMemAllocFail",                                   "cpiNumOfLICDRDel": "cpiNumOfLICDRDel",                                         "cpiReinitServiceSelf": "cpiReinitServiceSelf",                                         "cpiSIPRetransmitInvite": "cpiSIPRetransmitInvite",                                     "cpiSIPRetransmitNonInvite": "cpiSIPRetransmitNonInvite",                                       "cpiSS7DropSCTPPktsRcvd": "cpiSS7DropSCTPPktsRcvd",                                     "cpiSS7FailSCTPFastRetransRate": "cpiSS7FailSCTPFastRetransRate",                                       "cpiStabilityAlarm": "cpiStabilityAlarm",                                       "cpuOverload": "cpuOverload",                                   "databaseConnectionLost": "databaseConnectionLost",                                     "databaseReplicationLinkDown": "databaseReplicationLinkDown",                                   "databaseSizeExhausted": "databaseSizeExhausted",                                       "dbHighCpuUtilization": "dbHighCpuUtilization",                                         "dbOffline": "dbOffline",                                       "dbStatusUnexpected": "dbStatusUnexpected",                                     "degradedResource": "degradedResource",                                         "degrow": "degrow",                                     "deviceServerCxnLost": "deviceServerCxnLost",                                   "diamLinkDown": "diamLinkDown",                                         "diamMaxClientsExceeded": "diamMaxClientsExceeded",                                     "dnsThreshold": "dnsThreshold",                                         "ethernetError": "ethernetError",                                       "ethernetLinkDown": "ethernetLinkDown",                                         "externalConnectivity": "externalConnectivity",                                         "featureLicenseExpiration": "featureLicenseExpiration",                                         "featureLicenseKeyNearExpiration": "featureLicenseKeyNearExpiration",                                   "featureLockValidationError": "featureLockValidationError",                                     "fqdnError": "fqdnError",                                       "fru": "fru",                                           "gatewayCongestion": "gatewayCongestion",                                       "gatewayForcedOOS": "gatewayForcedOOS",                                         "gatewayProvisioningError": "gatewayProvisioningError",                                         "gatewayUnreachable": "gatewayUnreachable",                                     "gatewayUnregistered": "gatewayUnregistered",                                   "globalParameterNotFound": "globalParameterNotFound",                                   "glsInvalidCellId": "glsInvalidCellId",                                         "glsServerUnavailable": "glsServerUnavailable",                                         "grow": "grow",                                         "h248MessageBufferDepletion": "h248MessageBufferDepletion",                                     "hlrSyncConnection": "hlrSyncConnection",                                       "hlrSyncQueue": "hlrSyncQueue",                                         "hostDown": "hostDown",                                         "hostReset": "hostReset",                                       "invalidGateway": "invalidGateway",                                     "iriLinkDown": "iriLinkDown",                                   "ldapServerConnectionLost": "ldapServerConnectionLost",                                         "lispBufferFullExternalLIG": "lispBufferFullExternalLIG",                                       "llcDown": "llcDown",                                   "logicalLinkDown": "logicalLinkDown",                                   "logicalLinkNotFound": "logicalLinkNotFound",                                   "logRotateThreshold": "logRotateThreshold",                                     "memoryOverload": "memoryOverload",                                     "nodeConfigFailure": "nodeConfigFailure",                                       "nodeGroupOOS": "nodeGroupOOS",                                         "nodeOOS": "nodeOOS",                                   "nonCompliantFaultGroupMemberState": "nonCompliantFaultGroupMemberState",                                       "nonCsAddrChannelDepletion": "nonCsAddrChannelDepletion",                                       "numberOfTuplesInUse": "numberOfTuplesInUse",                                   "osSecInfoModificationDetected": "osSecInfoModificationDetected",                                       "osSecInformationMissing": "osSecInformationMissing",                                   "osSecUnexpectedInformation": "osSecUnexpectedInformation",                                     "pdnsMySqlReplication": "pdnsMySqlReplication",                                         "pktCorruptionDetectedViaRCCLANCheck": "pktCorruptionDetectedViaRCCLANCheck",                                   "platformCommandFailure": "platformCommandFailure",                                     "pmDataNotCollected": "pmDataNotCollected",                                     "prdbConnectWithAlternateFailure": "prdbConnectWithAlternateFailure",                                   "prdbSyncDataToAlternateFailure": "prdbSyncDataToAlternateFailure",                                     "preAllocatedResourceOverload": "preAllocatedResourceOverload",                                         "prifSocketError": "prifSocketError",                                   "processDown": "processDown",                                   "processNotStarted": "processNotStarted",                                       "provisioningInhibitedMode": "provisioningInhibitedMode",                                       "prsCallInstanceExceeded": "prsCallInstanceExceeded",                                   "prsCpuOverload": "prsCpuOverload",                                     "prsDatabaseMigrationFailure": "prsDatabaseMigrationFailure",                                   "prsFailureToConnectWithPRDB": "prsFailureToConnectWithPRDB",                                   "prsQueueExceeded": "prsQueueExceeded",                                         "rccInhibitedMode": "rccInhibitedMode",                                         "remotedbLinkDown": "remotedbLinkDown",                                         "remoteQueryServerFailure": "remoteQueryServerFailure",                                         "restore": "restore",                                   "serviceCFGDataTimestampError": "serviceCFGDataTimestampError",                                         "serviceCommCxnLost": "serviceCommCxnLost",                                     "serviceOnewayCommunication": "serviceOnewayCommunication",                                     "sheddingOverload": "sheddingOverload",                                         "simxml": "simxml",                                     "sipLinkSetMaxQuarantineList": "sipLinkSetMaxQuarantineList",                                   "sipLinkSetUnavailable": "sipLinkSetUnavailable",                                       "sipLinkUnavailable": "sipLinkUnavailable",                                     "smdiSocketError": "smdiSocketError",                                   "socketError": "socketError",                                   "softwareAllocatedResourceOverload": "softwareAllocatedResourceOverload",                                       "softwareComponentDown": "softwareComponentDown",                                       "softwareComponentStandbyNotReady": "softwareComponentStandbyNotReady",                                         "softwareLicense": "softwareLicense",                                   "svcdegrow": "svcdegrow",                                       "svcgrow": "svcgrow",                                   "swVersionMismatch": "swVersionMismatch",                                       "tftpDownloadCorrupt": "tftpDownloadCorrupt",                                   "timeStampValueOutOfSystemRange": "timeStampValueOutOfSystemRange",                                     "tlsInitError": "tlsInitError",                                         "transactionHandlerBlockDepletion": "transactionHandlerBlockDepletion",                                         "upgrade": "upgrade",                                   "usageOfSyncTable": "usageOfSyncTable",                                         "utHttpProxyConnectionDown": "utHttpProxyConnectionDown",                                       "wpifSocketError": "wpifSocketError",                                   "BackupFailure": "BackupFailure",                                       "Configuration": "Configuration",                                       "COTRecordTransferFailure": "COTRecordTransferFailure",                                         "CPMUSERDATAINCONSITENCY": "CPMUSERDATAINCONSITENCY",                                   "CPMUSERDATARESTORED": "CPMUSERDATARESTORED",                                   "EventQueueCapacity": "EventQueueCapacity",                                     "ICMPFailure": "ICMPFailure",                                   "IPsecConfig": "IPsecConfig",                                   "LinkDown": "LinkDown",                                         "NotifyDisabled": "NotifyDisabled",                                     "NotifyLocked": "NotifyLocked",                                         "NumTL1MeasThresh": "NumTL1MeasThresh",                                         "RADIUSTOLDAPFAILURE": "RADIUSTOLDAPFAILURE",                                   "ROOTACCESSDENIED": "ROOTACCESSDENIED",                                         "ROOTFTPVIOLATION": "ROOTFTPVIOLATION",                                         "ROOTLOGINVIOLATION": "ROOTLOGINVIOLATION",                                     "ROOTSSHLOGINVIOLATION": "ROOTSSHLOGINVIOLATION",                                       "SetupAAAFailure": "SetupAAAFailure",                                   "SNETrapOverload": "SNETrapOverload",                                   "SNMPAuthenticationFailure": "SNMPAuthenticationFailure",                                       "SNMPFailure": "SNMPFailure",                                   "SUTOROOTFAILURE": "SUTOROOTFAILURE",                                   "SYSTEMTrapOverload": "SYSTEMTrapOverload",                                     "ThresholdCrossed": "ThresholdCrossed",                                         "UndiscoveredObject": "UndiscoveredObject",                                     "WriteAAAFailure": "WriteAAAFailure"                            }                       },                      "Trinity": {                            "vf": {                                         "aSBG": "aSBG",                                         "nSBG": "nSBG",                                         "tSBG": "tSBG"                          },                              "vfc": {                                        "pld": "PL - Payload Processor",                                        "scr": "SC - System Controller"                                 },                              "location": {                                   "SNDGCA64": "San Diego SAN3",                                   "ALPRGAED": "Alpharetta PDK1",                                  "LSLEILAA":"Lisle DPA3"                                 },                              "alarmCondition": {                                     "A+Fallback+Operation+will+soon+be+started":"A Fallback Operation will soon be started",                                        "BRM%2C+Auto+Export+Backup+Failed":"BRM, Auto Export Backup Failed",                                    "BRM%2C+Scheduled+Backup+Failed":"BRM, Scheduled Backup Failed",                                        "COM+SA%2C+AMF+Component+Cleanup+Failed":"COM SA, AMF Component Cleanup Failed",                                        "COM+SA%2C+AMF+Component+Instantiation+Failed":"COM SA, AMF Component Instantiation Failed",                                    "COM+SA%2C+AMF+SI+Unassigned":"COM SA, AMF SI Unassigned",                                      "COM+SA%2C+CLM+Cluster+Node+Unavailable":"COM SA, CLM Cluster Node Unavailable",                                        "COM+SA%2C+MDF+Detected+Model+Error":"COM SA, MDF Detected Model Error",                                        "COM+SA%2C+Proxy+Status+of+a+Component+Changed+to+Unproxied":"COM SA, Proxy Status of a Component Changed to Unproxied",                                        "File+Management%2C+Number+of+Files+in+FileGroup+Exceeded":"File Management, Number of Files in FileGroup Exceeded",                                    "File+Management%2C+Max+Size+in+FileGroup+Exceeded":"File Management, Max Size in FileGroup Exceeded",                                  "LOTC+Disk+Replication+Communication":"LOTC Disk Replication Communication",                                    "LOTC+Disk+Replication+Consistency":"LOTC Disk Replication Consistency",                                        "LOTC+Disk+Usage":"LOTC Disk Usage",                                    "LOTC+memory+Usage":"LOTC memory Usage",                                        "LOTC+Time+Synchronization":"LOTC Time Synchronization",                                        "SBG%2C+BGF+Control+Link+Down":"SBG, BGF Control Link Down",                                    "SBG%2C+BGF+Control+Link+Disabled":"SBG, BGF Control Link Disabled",                                    "SBG%2C+BGF+Control+Link+Enabled":"SBG, BGF Control Link Enabled",                                      "SBG%2C+BGF+Control+Link+Remote+Locked":"SBG, BGF Control Link Remote Locked",                                  "SBG%2C+Charging+Data+Storage+Maximum+Records+Reached":"SBG, Charging Data Storage Maximum Records Reached",                                    "SBG%2C+Charging+Server+Rejects+Charging+Data":"SBG, Charging Server Rejects Charging Data",                                    "SBG%2C+Excessive+Packet+Rate+Detected+":"SBG, Excessive Packet Rate Detected ",                                        "SBG%2C+High+Amount+of+Malformed+Packets+Received":"SBG, High Amount of Malformed Packets Received",                                    "SBG%2C+High+Amount+of+STUN+Packets+Detected":"SBG, High Amount of STUN Packets Detected",                                      "SBG%2C+High+Amount+of+TCP+SYN+Packets+Received":"SBG, High Amount of TCP SYN Packets Received",                                        "SBG%2C+High+Amount+of+UDP+Packets+Received+":"SBG, High Amount of UDP Packets Received ",                                      "SBG%2C+IP+Address+Blocked+Due+to+Excessive+Packet+Rate":"SBG, IP Address Blocked Due to Excessive Packet Rate",                                        "SBG%2C+Lost+Connectivity+to+Diameter+Server":"SBG, Lost Connectivity to Diameter Server",                                      "SBG%2C+Mated+Pair+out+of+Service":"SBG, Mated Pair out of Service",                                    "SBG%2C+Network+Unavailable+for+Media+Handling":"SBG, Network Unavailable for Media Handling",                                  "SBG%2C+Non-emergency+Call+Released+to+Free+Resources+for+Emergency+Call":"SBG, Non-emergency Call Released to Free Resources for Emergency Call",                                      "SBG%2C+Not+Enough+Disk+Space+for+Storing+Charging+Data":"SBG, Not Enough Disk Space for Storing Charging Data",                                        "SBG%2C+Payload+Mated+Pair+Failure":"SBG, Payload Mated Pair Failure",                                  "SBG%2C+Payload+Processor+Failure":"SBG, Payload Processor Failure",                                    "SBG%2C+Processor+Overloaded":"SBG, Processor Overloaded",                                      "SBG%2C+Registered+User+Set+in+Quarantine":"SBG, Registered User Set in Quarantine",                                    "SBG%2C+Registration+Contacts+Exceed+Configured+Threshold":"SBG, Registration Contacts Exceed Configured Threshold",                                    "SBG%2C+Sequential+Restart+Initiated":"SBG, Sequential Restart Initiated",                                      "SBG%2C+SIP+Abuse+Detected":"SBG, SIP Abuse Detected",                                  "SBG%2C+SIP+Network+Locked":"SBG, SIP Network Locked",                                  "SBG%2C+SIP+Next+Hop+Reachable":"SBG, SIP Next Hop Reachable",                                  "SBG%2C+SIP+Next+Hop+Unreachable":"SBG, SIP Next Hop Unreachable",                                      "SBG%2C+SIP+Request+Rejected+by+Network+Throttling":"SBG, SIP Request Rejected by Network Throttling",                                  "SBG%2C+TLS+Certificate+Imported":"SBG, TLS Certificate Imported",                                      "SBG%2C+Trace+Recording+Session+Number+Limit+Reached":"SBG, Trace Recording Session Number Limit Reached",                                      "SBG%2C+Trace+Session+Deactivated":"SBG, Trace Session Deactivated",                                    "SBG%2C+Trace+Session+Times+Out":"SBG, Trace Session Times Out",                                        "SBG%2C+Unknown+Media+Type+or+Payload+Type":"SBG, Unknown Media Type or Payload Type"                                   }                       },                      "vProbes": {                            "vf": {                                 },                              "vfc": {                                },                              "location": {                           },                              "alarmCondition": {                             }                       }               }       } }
+globalPropsPartial={"collector": {"topicPublishes": {"DCAE-COLLECTOR-UCSNMP": "DCAE-COLLECTOR-UCSNMP", "GFP-IP--SNMP-TRAPS" : "GFP-IP--SNMP-TRAPS"     }       },      "string_match": {               "topicPublishes": {                     "DCAE-CL-EVENT": "DCAE-CL-EVENT"                },              "aaiMatchingFields": {                  "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "ProvStatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "aaiSendFields": {                      "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "Provstatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "eventSourceType": {                    "f5BigIP": "f5BigIP",                   "vSBG_Alarms": "vSBG_Alarms",                   "vCTS_Alarms": "vCTS_Alarms"            },              "eventSeverity": {                      "NORMAL": "NORMAL",                     "not-NORMAL": "not-NORMAL",                     "WARNING": "WARNING",                   "MINOR": "MINOR",                       "MAJOR": "MAJOR",                       "CRITICAL": "CRITICAL"          },              "timeWindow": 0,                "ageLimit": 1600,               "outputEventName": {                    "": "",                         "OnSet": "OnSet",                       "Abatement": "Abatement"                },              "createClosedLoopEventId": {                    "Initial": "Initial",                   "Close": "Close"                }       },      "global": {             "service": {                    "": "",                         "vUSP": "vUSP",                         "vSCP": "vSCP",                         "vProbes": "vProbes"            }       },      "policy": {             "timeout": 5,           "recipe": {                     "": "",                         "restart": "Restart",                   "rebuild": "Rebuild",                   "migrate": "Migrate"            },              "maxRetries": "3",              "retryTimeLimit": 180,          "resource": {                   "vCTS": "vCTS",                         "v3CDB": "v3CDB",                       "vUDR": "vUDR",                         "vCOM": "vCOM",                         "vRAR": "vRAR",                         "vLCS": "vLCS",                         "vUDR-BE": "vUDR-BE",                   "vDBE": "vDBE"          },              "parentPolicyConditions": {                     "Failure_Retries": "Failure: Max Retries Exceeded",                     "Failure_Timeout": "Failure: Time Limit Exceeded",                      "Failure_Exception": "Failure: Exception",                      "Failure": "Failure: Other",                    "Success": "Success"            }       }  }
+globalPropsTest={"collector": {"topicPublishes": {"DCAE-COLLECTOR-UCSNMP": "DCAE-COLLECTOR-UCSNMP",    "GFP-IP--SNMP-TRAPS" : "GFP-IP--SNMP-TRAPS"     }       },      "string_match": {               "topicPublishes": {                     "DCAE-CL-EVENT": "DCAE-CL-EVENT"                },              "aaiMatchingFields": {                  "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "ProvStatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "aaiSendFields": {                      "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "Provstatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "eventSourceType": {                    "f5BigIP": "f5BigIP",                   "vSBG_Alarms": "vSBG_Alarms",                   "vCTS_Alarms": "vCTS_Alarms"            },              "eventSeverity": {                      "NORMAL": "NORMAL",                     "not-NORMAL": "not-NORMAL",                     "WARNING": "WARNING",                   "MINOR": "MINOR",                       "MAJOR": "MAJOR",                       "CRITICAL": "CRITICAL"          },              "timeWindow": 0,                "ageLimit": 1600,               "outputEventName": {                    "": "",                         "OnSet": "OnSet",                       "Abatement": "Abatement"                },              "createClosedLoopEventId": {                    "Initial": "Initial",                   "Close": "Close"                }       },      "global": {             "service": {                    "": "",                         "vUSP": "vUSP",                         "vSCP": "vSCP",                         "vProbes": "vProbes"            }       },      "policy": {             "timeout": 5,           "recipe": {                     "": "",                         "restart": "Restart",                   "rebuild": "Rebuild",                   "migrate": "Migrate"            },              "maxRetries": "3",              "retryTimeLimit": 180,          "resource": {                   "vCTS": "vCTS",                         "v3CDB": "v3CDB",                       "vUDR": "vUDR",                         "vCOM": "vCOM",                         "vRAR": "vRAR",                         "vLCS": "vLCS",                         "vUDR-BE": "vUDR-BE",                   "vDBE": "vDBE"          },              "parentPolicyConditions": {                     "Failure_Retries": "Failure: Max Retries Exceeded",                     "Failure_Timeout": "Failure: Time Limit Exceeded",                      "Failure_Exception": "Failure: Exception",                      "Failure": "Failure: Other",                    "Success": "Success"            }       },      "shared": {             "byService": {                  "": {                           "vf": {                                 },                              "vfc": {                                },                              "location": {                           },                              "alarmCondition": {                             }                       },                      "vSCP": {                               "vf": {                                         "frwl_scp": "FW"                                },                              "vfc": {                                        "FW": "FW"                              },                              "location": {                                   "AKRNOHAH": "Akron",                                    "ALLNTXSA": "Allen-2"                           },                              "alarmCondition": {                                     "authenticationFailure": "authenticationFailure",                                       "bigipActive": "bigipActive",                                   "bigipActiveActive": "bigipActiveActive",                                       "bigipAgentRestart": "bigipAgentRestart",                                       "bigipAgentShutdown": "bigipAgentShutdown",                                     "bigipAgentStart": "bigipAgentStart",                                   "bigipAggrReaperStateChange": "bigipAggrReaperStateChange",                                     "bigipAomCpuTempTooHigh": "bigipAomCpuTempTooHigh",                                     "bigipARPConflict": "bigipARPConflict",                                         "bigipAsmBruteForceAttackDetected": "bigipAsmBruteForceAttackDetected",                                         "bigipAsmDosAttackDetected": "bigipAsmDosAttackDetected",                                       "bigipAsmFtpRequestBlocked": "bigipAsmFtpRequestBlocked",                                       "bigipAsmFtpRequestViolation": "bigipAsmFtpRequestViolation",                                   "bigipAsmRequestBlocked": "bigipAsmRequestBlocked",                                     "bigipAsmRequestViolation": "bigipAsmRequestViolation",                                         "bigipAsmSmtpRequestBlocked": "bigipAsmSmtpRequestBlocked",                                     "bigipAsmSmtpRequestViolation": "bigipAsmSmtpRequestViolation",                                         "bigipAuthFailed": "bigipAuthFailed",                                   "bigipAvrAlertsMetricSmtp": "bigipAvrAlertsMetricSmtp",                                         "bigipAvrAlertsMetricSnmp": "bigipAvrAlertsMetricSnmp",                                         "bigipBladeNoPower": "bigipBladeNoPower",                                       "bigipBladeOffline": "bigipBladeOffline",                                       "bigipBladeTempHigh": "bigipBladeTempHigh",                                     "bigipChassisFanBad": "bigipChassisFanBad",                                     "bigipChassisPowerSupplyBad": "bigipChassisPowerSupplyBad",                                     "bigipChassisTempHigh": "bigipChassisTempHigh",                                         "bigipChmandAlertFanTrayBad": "bigipChmandAlertFanTrayBad",                                     "bigipClusterdNoResponse": "bigipClusterdNoResponse",                                   "bigipClusterPrimaryChanged": "bigipClusterPrimaryChanged",                                     "bigipCompLimitExceeded": "bigipCompLimitExceeded",                                     "bigipConfigLoaded": "bigipConfigLoaded",                                       "bigipCpuFanSpeedBad": "bigipCpuFanSpeedBad",                                   "bigipCpuFanSpeedLow": "bigipCpuFanSpeedLow",                                   "bigipCpuTempHigh": "bigipCpuTempHigh",                                         "bigipDiskPartitionGrowth": "bigipDiskPartitionGrowth",                                         "bigipDiskPartitionWarn": "bigipDiskPartitionWarn",                                     "bigipDnsRequestRateLimiterEngaged": "bigipDnsRequestRateLimiterEngaged",                                       "bigipDosAttackStart": "bigipDosAttackStart",                                   "bigipDosAttackStop": "bigipDosAttackStop",                                     "bigipExternalLinkChange": "bigipExternalLinkChange",                                   "bigipFeatureFailed": "bigipFeatureFailed",                                     "bigipFeatureOnline": "bigipFeatureOnline",                                             "bigipFipsDeviceError": "bigipFipsDeviceError",                                         "bigipGtmAppAvail": "bigipGtmAppAvail",                                         "bigipGtmAppNotAvail": "bigipGtmAppNotAvail",                                   "bigipGtmAppObjAvail": "bigipGtmAppObjAvail",                                   "bigipGtmAppObjNotAvail": "bigipGtmAppObjNotAvail",                                     "bigipGtmBig3dSslCertExpired": "bigipGtmBig3dSslCertExpired",                                   "bigipGtmBig3dSslCertWillExpire": "bigipGtmBig3dSslCertWillExpire",                                     "bigipGtmBoxAvail": "bigipGtmBoxAvail",                                         "bigipGtmBoxNotAvail": "bigipGtmBoxNotAvail",                                   "bigipGtmDcAvail": "bigipGtmDcAvail",                                   "bigipGtmDcDisabled": "bigipGtmDcDisabled",                                     "bigipGtmDcEnabled": "bigipGtmDcEnabled",                                       "bigipGtmDcNotAvail": "bigipGtmDcNotAvail",                                     "bigipGtmJoinedGroup": "bigipGtmJoinedGroup",                                   "bigipGtmKeyGenerationExpiration": "bigipGtmKeyGenerationExpiration",                                   "bigipGtmKeyGenerationRollover": "bigipGtmKeyGenerationRollover",                                       "bigipGtmLeftGroup": "bigipGtmLeftGroup",                                       "bigipGtmLinkAvail": "bigipGtmLinkAvail",                                       "bigipGtmLinkDisabled": "bigipGtmLinkDisabled",                                         "bigipGtmLinkEnabled": "bigipGtmLinkEnabled",                                   "bigipGtmLinkNotAvail": "bigipGtmLinkNotAvail",                                         "bigipGtmPoolAvail": "bigipGtmPoolAvail",                                       "bigipGtmPoolDisabled": "bigipGtmPoolDisabled",                                         "bigipGtmPoolEnabled": "bigipGtmPoolEnabled",                                   "bigipGtmPoolMbrAvail": "bigipGtmPoolMbrAvail",                                         "bigipGtmPoolMbrDisabled": "bigipGtmPoolMbrDisabled",                                   "bigipGtmPoolMbrEnabled": "bigipGtmPoolMbrEnabled",                                     "bigipGtmPoolMbrNotAvail": "bigipGtmPoolMbrNotAvail",                                   "bigipGtmPoolNotAvail": "bigipGtmPoolNotAvail",                                         "bigipGtmProberPoolDisabled": "bigipGtmProberPoolDisabled",                                     "bigipGtmProberPoolEnabled": "bigipGtmProberPoolEnabled",                                       "bigipGtmProberPoolMbrDisabled": "bigipGtmProberPoolMbrDisabled",                                       "bigipGtmProberPoolMbrEnabled": "bigipGtmProberPoolMbrEnabled",                                         "bigipGtmProberPoolMbrStatusChange": "bigipGtmProberPoolMbrStatusChange",                                       "bigipGtmProberPoolMbrStatusChangeReason": "bigipGtmProberPoolMbrStatusChangeReason",                                   "bigipGtmProberPoolStatusChange": "bigipGtmProberPoolStatusChange",                                     "bigipGtmProberPoolStatusChangeReason": "bigipGtmProberPoolStatusChangeReason",                                         "bigipGtmRequestRateLimiterEngaged": "bigipGtmRequestRateLimiterEngaged",                                       "bigipGtmServerAvail": "bigipGtmServerAvail",                                   "bigipGtmServerDisabled": "bigipGtmServerDisabled",                                     "bigipGtmServerEnabled": "bigipGtmServerEnabled",                                       "bigipGtmServerNotAvail": "bigipGtmServerNotAvail",                                     "bigipGtmSslCertExpired": "bigipGtmSslCertExpired",                                     "bigipGtmSslCertWillExpire": "bigipGtmSslCertWillExpire",                                       "bigipGtmVsAvail": "bigipGtmVsAvail",                                   "bigipGtmVsDisabled": "bigipGtmVsDisabled",                                     "bigipGtmVsEnabled": "bigipGtmVsEnabled",                                       "bigipGtmVsNotAvail": "bigipGtmVsNotAvail",                                     "bigipGtmWideIpAvail": "bigipGtmWideIpAvail",                                   "bigipGtmWideIpDisabled": "bigipGtmWideIpDisabled",                                     "bigipGtmWideIpEnabled": "bigipGtmWideIpEnabled",                                       "bigipGtmWideIpNotAvail": "bigipGtmWideIpNotAvail",                                     "bigipHardDiskFailure": "bigipHardDiskFailure",                                         "bigipInetPortExhaustion": "bigipInetPortExhaustion",                                   "bigipLibhalBladePoweredOff": "bigipLibhalBladePoweredOff",                                     "bigipLibhalDiskBayRemoved": "bigipLibhalDiskBayRemoved",                                       "bigipLibhalSensorAlarmCritical": "bigipLibhalSensorAlarmCritical",                                     "bigipLibhalSsdLogicalDiskRemoved": "bigipLibhalSsdLogicalDiskRemoved",                                         "bigipLibhalSsdPhysicalDiskRemoved": "bigipLibhalSsdPhysicalDiskRemoved",                                       "bigipLicenseExpired": "bigipLicenseExpired",                                   "bigipLicenseFailed": "bigipLicenseFailed",                                     "bigipLogAlert": "bigipLogAlert",                                       "bigipLogCrit": "bigipLogCrit",                                         "bigipLogEmerg": "bigipLogEmerg",                                       "bigipLogErr": "bigipLogErr",                                   "bigipLogWarning": "bigipLogWarning",                                   "bigipLtmVsAvail": "bigipLtmVsAvail",                                   "bigipLtmVsDisabled": "bigipLtmVsDisabled",                                     "bigipLtmVsEnabled": "bigipLtmVsEnabled",                                       "bigipLtmVsUnavail": "bigipLtmVsUnavail",                                       "bigipMemberRate": "bigipMemberRate",                                   "bigipNetLinkDown": "bigipNetLinkDown",                                         "bigipNodeDown": "bigipNodeDown",                                       "bigipNodeRate": "bigipNodeRate",                                       "bigipNodeUp": "bigipNodeUp",                                   "bigipPacketRejected": "bigipPacketRejected",                                   "bigipPsAbsent": "bigipPsAbsent",                                       "bigipPsPowerOff": "bigipPsPowerOff",                                   "bigipPsPowerOn": "bigipPsPowerOn",                                     "bigipRaidDiskFailure": "bigipRaidDiskFailure",                                         "bigipServiceDown": "bigipServiceDown",                                         "bigipServiceUp": "bigipServiceUp",                                     "bigipSsdMwiNearThreshold": "bigipSsdMwiNearThreshold",                                         "bigipSsdMwiReachedThreshold": "bigipSsdMwiReachedThreshold",                                   "bigipSslLimitExceeded": "bigipSslLimitExceeded",                                       "bigipStandby": "bigipStandby",                                         "bigipStandByFail": "bigipStandByFail",                                         "bigipSystemCheckAlertCurrentHigh": "bigipSystemCheckAlertCurrentHigh",                                         "bigipSystemCheckAlertCurrentLow": "bigipSystemCheckAlertCurrentLow",                                   "bigipSystemCheckAlertFanSpeedLow": "bigipSystemCheckAlertFanSpeedLow",                                         "bigipSystemCheckAlertMilliVoltageHigh": "bigipSystemCheckAlertMilliVoltageHigh",                                       "bigipSystemCheckAlertMilliVoltageLow": "bigipSystemCheckAlertMilliVoltageLow",                                         "bigipSystemCheckAlertPowerHigh": "bigipSystemCheckAlertPowerHigh",                                     "bigipSystemCheckAlertPowerLow": "bigipSystemCheckAlertPowerLow",                                       "bigipSystemCheckAlertTempHigh": "bigipSystemCheckAlertTempHigh",                                       "bigipSystemCheckAlertVoltageHigh": "bigipSystemCheckAlertVoltageHigh",                                         "bigipSystemCheckAlertVoltageLow": "bigipSystemCheckAlertVoltageLow",                                   "bigipSystemShutdown": "bigipSystemShutdown",                                   "bigipTamdAlert": "bigipTamdAlert",                                     "bigipTrafficGroupActivate": "bigipTrafficGroupActivate",                                       "bigipTrafficGroupActive": "bigipTrafficGroupActive",                                   "bigipTrafficGroupDeactivate": "bigipTrafficGroupDeactivate",                                   "bigipTrafficGroupForcedOffline": "bigipTrafficGroupForcedOffline",                                     "bigipTrafficGroupOffline": "bigipTrafficGroupOffline",                                         "bigipTrafficGroupStandby": "bigipTrafficGroupStandby",                                         "bigipUnsolicitedRepliesExceededThreshold": "bigipUnsolicitedRepliesExceededThreshold",                                         "bigipUpdateError": "bigipUpdateError",                                         "bigipUpdatePriority": "bigipUpdatePriority",                                   "bigipUpdateServer": "bigipUpdateServer",                                       "bigipVcmpAlertsVcmpHBDetected": "bigipVcmpAlertsVcmpHBDetected",                                       "bigipVcmpAlertsVcmpHBLost": "bigipVcmpAlertsVcmpHBLost",                                       "bigipVcmpAlertsVcmpPowerOff": "bigipVcmpAlertsVcmpPowerOff",                                   "bigipVcmpAlertsVcmpPowerOn": "bigipVcmpAlertsVcmpPowerOn",                                     "bigipVirtualRate": "bigipVirtualRate",                                         "coldStart": "coldStart",                                       "emASMSigInstallComplete": "emASMSigInstallComplete",                                   "emASMSigInstallFailed": "emASMSigInstallFailed",                                       "emASMSigUpdateAvailable": "emASMSigUpdateAvailable",                                   "emASMSigUpdateFailed": "emASMSigUpdateFailed",                                         "emCertificateExpiration": "emCertificateExpiration",                                   "emCpuUsage": "emCpuUsage",                                     "emDeviceActiveMode": "emDeviceActiveMode",                                     "emDeviceClockSkew": "emDeviceClockSkew",                                       "emDeviceConfigSettingChanged": "emDeviceConfigSettingChanged",                                         "emDeviceConfigSync": "emDeviceConfigSync",                                     "emDeviceForcedOfflineMode": "emDeviceForcedOfflineMode",                                       "emDeviceImpaired": "emDeviceImpaired",                                         "emDeviceOfflineMode": "emDeviceOfflineMode",                                   "emDeviceStandbyMode": "emDeviceStandbyMode",                                   "emDeviceUnreachable": "emDeviceUnreachable",                                   "emDiskUsage": "emDiskUsage",                                   "emGatherServiceContractFailure": "emGatherServiceContractFailure",                                     "emHaSyncFailed": "emHaSyncFailed",                                     "emHotfixInstallComplete": "emHotfixInstallComplete",                                   "emHotfixInstallFailed": "emHotfixInstallFailed",                                       "emMemoryUsage": "emMemoryUsage",                                       "emPerformanceStorageCap": "emPerformanceStorageCap",                                   "emPerformanceStorageDays": "emPerformanceStorageDays",                                         "emPerformanceThreshold": "emPerformanceThreshold",                                     "emRaidDriveFailureDetected": "emRaidDriveFailureDetected",                                     "emRaidDriveRebuildComplete": "emRaidDriveRebuildComplete",                                     "emSchedBackupFailed": "emSchedBackupFailed",                                   "emScheduledArchiveFailed": "emScheduledArchiveFailed",                                         "emServiceContractExpiry": "emServiceContractExpiry",                                   "emSoftwareInstallComplete": "emSoftwareInstallComplete",                                       "emSoftwareInstallFailed": "emSoftwareInstallFailed",                                   "emStatsCollectionRateCap": "emStatsCollectionRateCap",                                         "emStatsDBConnectivityLost": "emStatsDBConnectivityLost",                                       "emStatsDBConnectivityRestored": "emStatsDBConnectivityRestored",                                       "fallingAlarm": "fallingAlarm",                                         "ipv6IfStateChange": "ipv6IfStateChange",                                       "linkDown": "linkDown",                                         "linkUp": "linkUp",                                     "mteEventSetFailure": "mteEventSetFailure",                                     "mteTriggerFailure": "mteTriggerFailure",                                       "mteTriggerFalling": "mteTriggerFalling",                                       "mteTriggerFired": "mteTriggerFired",                                   "mteTriggerRising": "mteTriggerRising",                                         "netSnmpExampleHeartbeatNotification": "netSnmpExampleHeartbeatNotification",                                   "newRoot": "newRoot",                                   "nsNotifyRestart": "nsNotifyRestart",                                   "nsNotifyShutdown": "nsNotifyShutdown",                                         "nsNotifyStart": "nsNotifyStart",                                       "risingAlarm": "risingAlarm",                                   "schedActionFailure": "schedActionFailure",                                     "smScriptAbort": "smScriptAbort",                                       "smScriptException": "smScriptException",                                       "smScriptResult": "smScriptResult",                                     "topologyChange": "topologyChange",                                     "ucdShutdown": "ucdShutdown",                                   "ucdStart": "ucdStart",                                         "warmStart": "warmStart"                                }                       },                      "vUSP": {                               "vf": {                                         "ctsf-xxx": "vCTS"                              },                              "vfc": {                                        "vCTS - CFED": "vCTS - CFED",                                   "vCTS - Config": "vCTS - Config",                                       "vCTS - DFED": "vCTS - DFED",                                   "vCTS - TAFE-fsd": "vCTS - TAFE-fsd",                                   "vCTS - GLS": "vCTS - GLS",                                     "vCTS - XXX": "vCTS - XXX",                                     "vCTS - Management Interface": "vCTS - Management Interface",                                   "vCTS - SPFE-pfe": "vCTS - SPFE-pfe",                                   "vCTS - DNS": "vCTS - DNS",                                     "vCTS - SPFE-spd": "vCTS - SPFE-spd",                                   "vCTS - SPFE-spt": "vCTS - SPFE-spt",                                   "vCTS - TAFE-tas": "vCTS - TAFE-tas"                            },                              "location": {                                   "SNDGCA06": "San Diego(core site) A06",                                         "SNDGCA64": "San Diego(core site) A64",                                         "SNANTXCA": "San Antonio(core site)",                                   "KSCYMO09": "Kansas City(core site)",                                   "kings_mountain": "Kings Mountain(AMG)",                                        "Secaucus": "Secaucus(AMG)",                                    "lisle": "Lisle(AMG)",                                  "concord": "Concord(AMG)",                                      "houston": "Houston(AMG)",                                      "akron": "Akron(AMG)"                           },                              "alarmCondition": {                                     "acrTemporaryBufferOverload": "acrTemporaryBufferOverload",                                     "adnsExtendedTTLcaching": "adnsExtendedTTLcaching",                                     "adnsQueryFailureCaching": "adnsQueryFailureCaching",                                   "adnsQueueCongestion": "adnsQueueCongestion",                                   "asdaCommunicationFailure": "asdaCommunicationFailure",                                         "asdaRequestQueue": "asdaRequestQueue",                                         "capacityLicenseKeyExpiration": "capacityLicenseKeyExpiration",                                         "capacityLicenseKeyNearExpiration": "capacityLicenseKeyNearExpiration",                                         "capacityLicenseKeyValidationError": "capacityLicenseKeyValidationError",                                       "cardConnectionLost": "cardConnectionLost",                                     "ccdbCommunicationFailure": "ccdbCommunicationFailure",                                         "cpiAlrmCritical": "cpiAlrmCritical",                                   "cpiAlrmMajor": "cpiAlrmMajor",                                         "cpiAlrmMinor": "cpiAlrmMinor",                                         "cpiAlrmWarning": "cpiAlrmWarning",                                     "cpiAsrtEsc": "cpiAsrtEsc",                                     "cpiAsrtNonEsc": "cpiAsrtNonEsc",                                       "cpiAsrtNonEscCritical": "cpiAsrtNonEscCritical",                                       "cpiAsrtNonEscMajor": "cpiAsrtNonEscMajor",                                     "cpiAsrtNonEscMinor": "cpiAsrtNonEscMinor",                                     "cpiAudErrCount": "cpiAudErrCount",                                     "cpiAudManAct": "cpiAudManAct",                                         "cpiAudNewEvent": "cpiAudNewEvent",                                     "cpiCompleteRateAlarm": "cpiCompleteRateAlarm",                                         "cpiCTS3xxFailRate": "cpiCTS3xxFailRate",                                       "cpiCTS4xxFailRate": "cpiCTS4xxFailRate",                                       "cpiCTS5xxFailRate": "cpiCTS5xxFailRate",                                       "cpiCTS6xxFailRate": "cpiCTS6xxFailRate",                                       "cpiCTSSIPRetransmitInvite": "cpiCTSSIPRetransmitInvite",                                       "cpiCTSSIPRetransmitNonInvite": "cpiCTSSIPRetransmitNonInvite",                                         "cpiDropMGAllocConnReq": "cpiDropMGAllocConnReq",                                       "cpiDropRateAlarm": "cpiDropRateAlarm",                                         "cpiExceptionService": "cpiExceptionService",                                   "cpiFailRateAlarm": "cpiFailRateAlarm",                                         "cpiFailSCTPFastRetransIncr": "cpiFailSCTPFastRetransIncr",                                     "cpiFailSCTPFastRetransRate": "cpiFailSCTPFastRetransRate",                                     "cpiFailSCTPSRTT1Incr": "cpiFailSCTPSRTT1Incr",                                         "cpiFailSCTPSRTT2Incr": "cpiFailSCTPSRTT2Incr",                                         "cpiFailSCTPT3RetransIncr": "cpiFailSCTPT3RetransIncr",                                         "cpiFailSCTPT3RetransRate": "cpiFailSCTPT3RetransRate",                                         "cpiFileSysUsage": "cpiFileSysUsage",                                   "cpiMemAllocFail": "cpiMemAllocFail",                                   "cpiNumOfLICDRDel": "cpiNumOfLICDRDel",                                         "cpiReinitServiceSelf": "cpiReinitServiceSelf",                                         "cpiSIPRetransmitInvite": "cpiSIPRetransmitInvite",                                     "cpiSIPRetransmitNonInvite": "cpiSIPRetransmitNonInvite",                                       "cpiSS7DropSCTPPktsRcvd": "cpiSS7DropSCTPPktsRcvd",                                     "cpiSS7FailSCTPFastRetransRate": "cpiSS7FailSCTPFastRetransRate",                                       "cpiStabilityAlarm": "cpiStabilityAlarm",                                       "cpuOverload": "cpuOverload",                                   "databaseConnectionLost": "databaseConnectionLost",                                     "databaseReplicationLinkDown": "databaseReplicationLinkDown",                                   "databaseSizeExhausted": "databaseSizeExhausted",                                       "dbHighCpuUtilization": "dbHighCpuUtilization",                                         "dbOffline": "dbOffline",                                       "dbStatusUnexpected": "dbStatusUnexpected",                                     "degradedResource": "degradedResource",                                         "degrow": "degrow",                                     "deviceServerCxnLost": "deviceServerCxnLost",                                   "diamLinkDown": "diamLinkDown",                                         "diamMaxClientsExceeded": "diamMaxClientsExceeded",                                     "dnsThreshold": "dnsThreshold",                                         "ethernetError": "ethernetError",                                       "ethernetLinkDown": "ethernetLinkDown",                                         "externalConnectivity": "externalConnectivity",                                         "featureLicenseExpiration": "featureLicenseExpiration",                                         "featureLicenseKeyNearExpiration": "featureLicenseKeyNearExpiration",                                   "featureLockValidationError": "featureLockValidationError",                                     "fqdnError": "fqdnError",                                       "fru": "fru",                                           "gatewayCongestion": "gatewayCongestion",                                       "gatewayForcedOOS": "gatewayForcedOOS",                                         "gatewayProvisioningError": "gatewayProvisioningError",                                         "gatewayUnreachable": "gatewayUnreachable",                                     "gatewayUnregistered": "gatewayUnregistered",                                   "globalParameterNotFound": "globalParameterNotFound",                                   "glsInvalidCellId": "glsInvalidCellId",                                         "glsServerUnavailable": "glsServerUnavailable",                                         "grow": "grow",                                         "h248MessageBufferDepletion": "h248MessageBufferDepletion",                                     "hlrSyncConnection": "hlrSyncConnection",                                       "hlrSyncQueue": "hlrSyncQueue",                                         "hostDown": "hostDown",                                         "hostReset": "hostReset",                                       "invalidGateway": "invalidGateway",                                     "iriLinkDown": "iriLinkDown",                                   "ldapServerConnectionLost": "ldapServerConnectionLost",                                         "lispBufferFullExternalLIG": "lispBufferFullExternalLIG",                                       "llcDown": "llcDown",                                   "logicalLinkDown": "logicalLinkDown",                                   "logicalLinkNotFound": "logicalLinkNotFound",                                   "logRotateThreshold": "logRotateThreshold",                                     "memoryOverload": "memoryOverload",                                     "nodeConfigFailure": "nodeConfigFailure",                                       "nodeGroupOOS": "nodeGroupOOS",                                         "nodeOOS": "nodeOOS",                                   "nonCompliantFaultGroupMemberState": "nonCompliantFaultGroupMemberState",                                       "nonCsAddrChannelDepletion": "nonCsAddrChannelDepletion",                                       "numberOfTuplesInUse": "numberOfTuplesInUse",                                   "osSecInfoModificationDetected": "osSecInfoModificationDetected",                                       "osSecInformationMissing": "osSecInformationMissing",                                   "osSecUnexpectedInformation": "osSecUnexpectedInformation",                                     "pdnsMySqlReplication": "pdnsMySqlReplication",                                         "pktCorruptionDetectedViaRCCLANCheck": "pktCorruptionDetectedViaRCCLANCheck",                                   "platformCommandFailure": "platformCommandFailure",                                     "pmDataNotCollected": "pmDataNotCollected",                                     "prdbConnectWithAlternateFailure": "prdbConnectWithAlternateFailure",                                   "prdbSyncDataToAlternateFailure": "prdbSyncDataToAlternateFailure",                                     "preAllocatedResourceOverload": "preAllocatedResourceOverload",                                         "prifSocketError": "prifSocketError",                                   "processDown": "processDown",                                   "processNotStarted": "processNotStarted",                                       "provisioningInhibitedMode": "provisioningInhibitedMode",                                       "prsCallInstanceExceeded": "prsCallInstanceExceeded",                                   "prsCpuOverload": "prsCpuOverload",                                     "prsDatabaseMigrationFailure": "prsDatabaseMigrationFailure",                                   "prsFailureToConnectWithPRDB": "prsFailureToConnectWithPRDB",                                   "prsQueueExceeded": "prsQueueExceeded",                                         "rccInhibitedMode": "rccInhibitedMode",                                         "remotedbLinkDown": "remotedbLinkDown",                                         "remoteQueryServerFailure": "remoteQueryServerFailure",                                         "restore": "restore",                                   "serviceCFGDataTimestampError": "serviceCFGDataTimestampError",                                         "serviceCommCxnLost": "serviceCommCxnLost",                                     "serviceOnewayCommunication": "serviceOnewayCommunication",                                     "sheddingOverload": "sheddingOverload",                                         "simxml": "simxml",                                     "sipLinkSetMaxQuarantineList": "sipLinkSetMaxQuarantineList",                                   "sipLinkSetUnavailable": "sipLinkSetUnavailable",                                       "sipLinkUnavailable": "sipLinkUnavailable",                                     "smdiSocketError": "smdiSocketError",                                   "socketError": "socketError",                                   "softwareAllocatedResourceOverload": "softwareAllocatedResourceOverload",                                       "softwareComponentDown": "softwareComponentDown",                                       "softwareComponentStandbyNotReady": "softwareComponentStandbyNotReady",                                         "softwareLicense": "softwareLicense",                                   "svcdegrow": "svcdegrow",                                       "svcgrow": "svcgrow",                                   "swVersionMismatch": "swVersionMismatch",                                       "tftpDownloadCorrupt": "tftpDownloadCorrupt",                                   "timeStampValueOutOfSystemRange": "timeStampValueOutOfSystemRange",                                     "tlsInitError": "tlsInitError",                                         "transactionHandlerBlockDepletion": "transactionHandlerBlockDepletion",                                         "upgrade": "upgrade",                                   "usageOfSyncTable": "usageOfSyncTable",                                         "utHttpProxyConnectionDown": "utHttpProxyConnectionDown",                                       "wpifSocketError": "wpifSocketError",                                   "BackupFailure": "BackupFailure",                                       "Configuration": "Configuration",                                       "COTRecordTransferFailure": "COTRecordTransferFailure",                                         "CPMUSERDATAINCONSITENCY": "CPMUSERDATAINCONSITENCY",                                   "CPMUSERDATARESTORED": "CPMUSERDATARESTORED",                                   "EventQueueCapacity": "EventQueueCapacity",                                     "ICMPFailure": "ICMPFailure",                                   "IPsecConfig": "IPsecConfig",                                   "LinkDown": "LinkDown",                                         "NotifyDisabled": "NotifyDisabled",                                     "NotifyLocked": "NotifyLocked",                                         "NumTL1MeasThresh": "NumTL1MeasThresh",                                         "RADIUSTOLDAPFAILURE": "RADIUSTOLDAPFAILURE",                                   "ROOTACCESSDENIED": "ROOTACCESSDENIED",                                         "ROOTFTPVIOLATION": "ROOTFTPVIOLATION",                                         "ROOTLOGINVIOLATION": "ROOTLOGINVIOLATION",                                     "ROOTSSHLOGINVIOLATION": "ROOTSSHLOGINVIOLATION",                                       "SetupAAAFailure": "SetupAAAFailure",                                   "SNETrapOverload": "SNETrapOverload",                                   "SNMPAuthenticationFailure": "SNMPAuthenticationFailure",                                       "SNMPFailure": "SNMPFailure",                                   "SUTOROOTFAILURE": "SUTOROOTFAILURE",                                   "SYSTEMTrapOverload": "SYSTEMTrapOverload",                                     "ThresholdCrossed": "ThresholdCrossed",                                         "UndiscoveredObject": "UndiscoveredObject",                                     "WriteAAAFailure": "WriteAAAFailure"                            }                       },                      "Trinity": {                            "vf": {                                         "aSBG": "aSBG",                                         "nSBG": "nSBG",                                         "tSBG": "tSBG"                          },                              "vfc": {                                        "pld": "PL - Payload Processor",                                        "scr": "SC - System Controller"                                 },                              "location": {                                   "SNDGCA64": "San Diego SAN3",                                   "ALPRGAED": "Alpharetta PDK1",                                  "LSLEILAA":"Lisle DPA3"                                 },                              "alarmCondition": {                                     "A+Fallback+Operation+will+soon+be+started":"A Fallback Operation will soon be started",                                        "BRM%2C+Auto+Export+Backup+Failed":"BRM, Auto Export Backup Failed",                                    "BRM%2C+Scheduled+Backup+Failed":"BRM, Scheduled Backup Failed",                                        "COM+SA%2C+AMF+Component+Cleanup+Failed":"COM SA, AMF Component Cleanup Failed",                                        "COM+SA%2C+AMF+Component+Instantiation+Failed":"COM SA, AMF Component Instantiation Failed",                                    "COM+SA%2C+AMF+SI+Unassigned":"COM SA, AMF SI Unassigned",                                      "COM+SA%2C+CLM+Cluster+Node+Unavailable":"COM SA, CLM Cluster Node Unavailable",                                        "COM+SA%2C+MDF+Detected+Model+Error":"COM SA, MDF Detected Model Error",                                        "COM+SA%2C+Proxy+Status+of+a+Component+Changed+to+Unproxied":"COM SA, Proxy Status of a Component Changed to Unproxied",                                        "File+Management%2C+Number+of+Files+in+FileGroup+Exceeded":"File Management, Number of Files in FileGroup Exceeded",                                    "File+Management%2C+Max+Size+in+FileGroup+Exceeded":"File Management, Max Size in FileGroup Exceeded",                                  "LOTC+Disk+Replication+Communication":"LOTC Disk Replication Communication",                                    "LOTC+Disk+Replication+Consistency":"LOTC Disk Replication Consistency",                                        "LOTC+Disk+Usage":"LOTC Disk Usage",                                    "LOTC+memory+Usage":"LOTC memory Usage",                                        "LOTC+Time+Synchronization":"LOTC Time Synchronization",                                        "SBG%2C+BGF+Control+Link+Down":"SBG, BGF Control Link Down",                                    "SBG%2C+BGF+Control+Link+Disabled":"SBG, BGF Control Link Disabled",                                    "SBG%2C+BGF+Control+Link+Enabled":"SBG, BGF Control Link Enabled",                                      "SBG%2C+BGF+Control+Link+Remote+Locked":"SBG, BGF Control Link Remote Locked",                                  "SBG%2C+Charging+Data+Storage+Maximum+Records+Reached":"SBG, Charging Data Storage Maximum Records Reached",                                    "SBG%2C+Charging+Server+Rejects+Charging+Data":"SBG, Charging Server Rejects Charging Data",                                    "SBG%2C+Excessive+Packet+Rate+Detected+":"SBG, Excessive Packet Rate Detected ",                                        "SBG%2C+High+Amount+of+Malformed+Packets+Received":"SBG, High Amount of Malformed Packets Received",                                    "SBG%2C+High+Amount+of+STUN+Packets+Detected":"SBG, High Amount of STUN Packets Detected",                                      "SBG%2C+High+Amount+of+TCP+SYN+Packets+Received":"SBG, High Amount of TCP SYN Packets Received",                                        "SBG%2C+High+Amount+of+UDP+Packets+Received+":"SBG, High Amount of UDP Packets Received ",                                      "SBG%2C+IP+Address+Blocked+Due+to+Excessive+Packet+Rate":"SBG, IP Address Blocked Due to Excessive Packet Rate",                                        "SBG%2C+Lost+Connectivity+to+Diameter+Server":"SBG, Lost Connectivity to Diameter Server",                                      "SBG%2C+Mated+Pair+out+of+Service":"SBG, Mated Pair out of Service",                                    "SBG%2C+Network+Unavailable+for+Media+Handling":"SBG, Network Unavailable for Media Handling",                                  "SBG%2C+Non-emergency+Call+Released+to+Free+Resources+for+Emergency+Call":"SBG, Non-emergency Call Released to Free Resources for Emergency Call",                                      "SBG%2C+Not+Enough+Disk+Space+for+Storing+Charging+Data":"SBG, Not Enough Disk Space for Storing Charging Data",                                        "SBG%2C+Payload+Mated+Pair+Failure":"SBG, Payload Mated Pair Failure",                                  "SBG%2C+Payload+Processor+Failure":"SBG, Payload Processor Failure",                                    "SBG%2C+Processor+Overloaded":"SBG, Processor Overloaded",                                      "SBG%2C+Registered+User+Set+in+Quarantine":"SBG, Registered User Set in Quarantine",                                    "SBG%2C+Registration+Contacts+Exceed+Configured+Threshold":"SBG, Registration Contacts Exceed Configured Threshold",                                    "SBG%2C+Sequential+Restart+Initiated":"SBG, Sequential Restart Initiated",                                      "SBG%2C+SIP+Abuse+Detected":"SBG, SIP Abuse Detected",                                  "SBG%2C+SIP+Network+Locked":"SBG, SIP Network Locked",                                  "SBG%2C+SIP+Next+Hop+Reachable":"SBG, SIP Next Hop Reachable",                                  "SBG%2C+SIP+Next+Hop+Unreachable":"SBG, SIP Next Hop Unreachable",                                      "SBG%2C+SIP+Request+Rejected+by+Network+Throttling":"SBG, SIP Request Rejected by Network Throttling",                                  "SBG%2C+TLS+Certificate+Imported":"SBG, TLS Certificate Imported",                                      "SBG%2C+Trace+Recording+Session+Number+Limit+Reached":"SBG, Trace Recording Session Number Limit Reached",                                      "SBG%2C+Trace+Session+Deactivated":"SBG, Trace Session Deactivated",                                    "SBG%2C+Trace+Session+Times+Out":"SBG, Trace Session Times Out",                                        "SBG%2C+Unknown+Media+Type+or+Payload+Type":"SBG, Unknown Media Type or Payload Type"                                   }                       },                      "vProbes": {                            "vf": {                                 },                              "vfc": {                                },                              "location": {                           },                              "alarmCondition": {                             }                       }               }       } }
+globalPropsPartialTest={"collector": {"topicPublishes": {"DCAE-COLLECTOR-UCSNMP": "DCAE-COLLECTOR-UCSNMP",     "GFP-IP--SNMP-TRAPS" : "GFP-IP--SNMP-TRAPS"     }       },      "string_match": {               "topicPublishes": {                     "DCAE-CL-EVENT": "DCAE-CL-EVENT"                },              "aaiMatchingFields": {                  "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "ProvStatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "aaiSendFields": {                      "VMID": "VMID",                         "Identiy": "Identiy",                   "VNFNAME": "VNFNAME",                   "LOCID": "LOCID",                       "VServerSelfLink": "VServerSelfLink",                   "Provstatus": "Provstatus",                     "OAMIPV4": "OAMIPV4",                   "OAMIPV6": "OAMIPV6",                   "VMNAME": "VMNAME",                     "TenantID":"TenantID",                  "in_maint":"in_maint",                  "is_closed_loop_disabled":"is_closed_loop_disabled",                    "Location":"Location",                  "OAM_network_name":"OAM_network_name"           },              "eventSourceType": {                    "f5BigIP": "f5BigIP",                   "vSBG_Alarms": "vSBG_Alarms",                   "vCTS_Alarms": "vCTS_Alarms"            },              "eventSeverity": {                      "NORMAL": "NORMAL",                     "not-NORMAL": "not-NORMAL",                     "WARNING": "WARNING",                   "MINOR": "MINOR",                       "MAJOR": "MAJOR",                       "CRITICAL": "CRITICAL"          },              "timeWindow": 0,                "ageLimit": 1600,               "outputEventName": {                    "": "",                         "OnSet": "OnSet",                       "Abatement": "Abatement"                },              "createClosedLoopEventId": {                    "Initial": "Initial",                   "Close": "Close"                }       },      "global": {             "service": {                    "": "",                         "vUSP": "vUSP",                         "vSCP": "vSCP",                         "vProbes": "vProbes"            }       },      "policy": {             "timeout": 5,           "recipe": {                     "": "",                         "restart": "Restart",                   "rebuild": "Rebuild",                   "migrate": "Migrate"            },              "maxRetries": "3",              "retryTimeLimit": 180,          "resource": {                   "vCTS": "vCTS",                         "v3CDB": "v3CDB",                       "vUDR": "vUDR",                         "vCOM": "vCOM",                         "vRAR": "vRAR",                         "vLCS": "vLCS",                         "vUDR-BE": "vUDR-BE",                   "vDBE": "vDBE"          },              "parentPolicyConditions": {                     "Failure_Retries": "Failure: Max Retries Exceeded",                     "Failure_Timeout": "Failure: Time Limit Exceeded",                      "Failure_Exception": "Failure: Exception",                      "Failure": "Failure: Other",                    "Success": "Success"            }       }}
+ui.location.default={"location":{"SNDGCA64":"San Diego SAN3","ALPRGAED":"Alpharetta PDK1","LSLEILAA":"Lisle DPA3"}}
+ui.alarm.default={"alarmCondition":{"A+Fallback+Operation+will+soon+be+started":"A Fallback Operation will soon be started","BRM%2C+Auto+Export+Backup+Failed":"BRM, Auto Export Backup Failed","BRM%2C+Scheduled+Backup+Failed":"BRM, Scheduled Backup Failed","COM+SA%2C+AMF+Component+Cleanup+Failed":"COM SA, AMF Component Cleanup Failed","COM+SA%2C+AMF+Component+Instantiation+Failed":"COM SA, AMF Component Instantiation Failed","COM+SA%2C+AMF+SI+Unassigned":"COM SA, AMF SI Unassigned","COM+SA%2C+CLM+Cluster+Node+Unavailable":"COM SA, CLM Cluster Node Unavailable","COM+SA%2C+MDF+Detected+Model+Error":"COM SA, MDF Detected Model Error","COM+SA%2C+Proxy+Status+of+a+Component+Changed+to+Unproxied":"COM SA, Proxy Status of a Component Changed to Unproxied","File+Management%2C+Number+of+Files+in+FileGroup+Exceeded":"File Management, Number of Files in FileGroup Exceeded","File+Management%2C+Max+Size+in+FileGroup+Exceeded":"File Management, Max Size in FileGroup Exceeded","LOTC+Disk+Replication+Communication":"LOTC Disk Replication Communication","LOTC+Disk+Replication+Consistency":"LOTC Disk Replication Consistency","LOTC+Disk+Usage":"LOTC Disk Usage","LOTC+memory+Usage":"LOTC memory Usage","LOTC+Time+Synchronization":"LOTC Time Synchronization","SBG%2C+BGF+Control+Link+Down":"SBG, BGF Control Link Down","SBG%2C+BGF+Control+Link+Disabled":"SBG, BGF Control Link Disabled","SBG%2C+BGF+Control+Link+Enabled":"SBG, BGF Control Link Enabled","SBG%2C+BGF+Control+Link+Remote+Locked":"SBG, BGF Control Link Remote Locked","SBG%2C+Charging+Data+Storage+Maximum+Records+Reached":"SBG, Charging Data Storage Maximum Records Reached","SBG%2C+Charging+Server+Rejects+Charging+Data":"SBG, Charging Server Rejects Charging Data","SBG%2C+Excessive+Packet+Rate+Detected+":"SBG, Excessive Packet Rate Detected ","SBG%2C+High+Amount+of+Malformed+Packets+Received":"SBG, High Amount of Malformed Packets Received","SBG%2C+High+Amount+of+STUN+Packets+Detected":"SBG, High Amount of STUN Packets Detected","SBG%2C+High+Amount+of+TCP+SYN+Packets+Received":"SBG, High Amount of TCP SYN Packets Received","SBG%2C+High+Amount+of+UDP+Packets+Received+":"SBG, High Amount of UDP Packets Received ","SBG%2C+IP+Address+Blocked+Due+to+Excessive+Packet+Rate":"SBG, IP Address Blocked Due to Excessive Packet Rate","SBG%2C+Lost+Connectivity+to+Diameter+Server":"SBG, Lost Connectivity to Diameter Server","SBG%2C+Mated+Pair+out+of+Service":"SBG, Mated Pair out of Service","SBG%2C+Network+Unavailable+for+Media+Handling":"SBG, Network Unavailable for Media Handling","SBG%2C+Non-emergency+Call+Released+to+Free+Resources+for+Emergency+Call":"SBG, Non-emergency Call Released to Free Resources for Emergency Call","SBG%2C+Not+Enough+Disk+Space+for+Storing+Charging+Data":"SBG, Not Enough Disk Space for Storing Charging Data","SBG%2C+Payload+Mated+Pair+Failure":"SBG, Payload Mated Pair Failure","SBG%2C+Payload+Processor+Failure":"SBG, Payload Processor Failure","SBG%2C+Processor+Overloaded":"SBG, Processor Overloaded","SBG%2C+Registered+User+Set+in+Quarantine":"SBG, Registered User Set in Quarantine","SBG%2C+Registration+Contacts+Exceed+Configured+Threshold":"SBG, Registration Contacts Exceed Configured Threshold","SBG%2C+Sequential+Restart+Initiated":"SBG, Sequential Restart Initiated","SBG%2C+SIP+Abuse+Detected":"SBG, SIP Abuse Detected","SBG%2C+SIP+Network+Locked":"SBG, SIP Network Locked","SBG%2C+SIP+Next+Hop+Reachable":"SBG, SIP Next Hop Reachable","SBG%2C+SIP+Next+Hop+Unreachable":"SBG, SIP Next Hop Unreachable","SBG%2C+SIP+Request+Rejected+by+Network+Throttling":"SBG, SIP Request Rejected by Network Throttling","SBG%2C+TLS+Certificate+Imported":"SBG, TLS Certificate Imported","SBG%2C+Trace+Recording+Session+Number+Limit+Reached":"SBG, Trace Recording Session Number Limit Reached","SBG%2C+Trace+Session+Deactivated":"SBG, Trace Session Deactivated","SBG%2C+Trace+Session+Times+Out":"SBG, Trace Session Times Out","SBG%2C+Unknown+Media+Type+or+Payload+Type":"SBG, Unknown Media Type or Payload Type"}}
+
diff --git a/src/test/resources/example/modelBpmn.xml b/src/test/resources/example/modelBpmn.xml
new file mode 100644 (file)
index 0000000..d84f790
--- /dev/null
@@ -0,0 +1,110 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
+  <bpmn:process id="Process_1" isExecutable="false">
+    <bpmn:startEvent id="StartEvent_1">
+      <bpmn:outgoing>SequenceFlow_0ex3w2w</bpmn:outgoing>
+    </bpmn:startEvent>
+    <bpmn:collector id="Collector_">
+      <bpmn:incoming>SequenceFlow_0ex3w2w</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_185iyma</bpmn:outgoing>
+    </bpmn:collector>
+    <bpmn:stringMatch id="StringMatch_">
+      <bpmn:incoming>SequenceFlow_185iyma</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_092429t</bpmn:outgoing>
+    </bpmn:stringMatch>
+    <bpmn:policy id="Policy_">
+      <bpmn:incoming>SequenceFlow_092429t</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0hghw7g</bpmn:outgoing>
+    </bpmn:policy>
+    <bpmn:tCA id="TCA_">
+      <bpmn:incoming>SequenceFlow_08j3fsl</bpmn:incoming>
+      <bpmn:outgoing>SequenceFlow_0hghw7g</bpmn:outgoing>
+    </bpmn:tCA>
+    <bpmn:endEvent id="EndEvent_0lg612k">
+      <bpmn:incoming>SequenceFlow_0hghw7g</bpmn:incoming>
+    </bpmn:endEvent>
+    <bpmn:sequenceFlow id="SequenceFlow_0ex3w2w" sourceRef="StartEvent_1" targetRef="Collector_" />
+    <bpmn:sequenceFlow id="SequenceFlow_185iyma" sourceRef="Collector_" targetRef="StringMatch_" />
+    <bpmn:sequenceFlow id="SequenceFlow_092429t" sourceRef="StringMatch_" targetRef="Policy_" />
+    <bpmn:sequenceFlow id="SequenceFlow_0hghw7g" sourceRef="Policy_" targetRef="EndEvent_0lg612k" />
+  </bpmn:process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
+    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
+      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
+        <dc:Bounds x="60" y="25" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="33" y="61" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Collector__di" bpmnElement="Collector_">
+        <dc:Bounds x="169" y="140" width="120" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="StringMatch__di" bpmnElement="StringMatch_">
+        <dc:Bounds x="578" y="140" width="120" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="Policy__di" bpmnElement="Policy_">
+        <dc:Bounds x="768" y="140" width="100" height="80" />
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="EndEvent_0lg612k_di" bpmnElement="EndEvent_0lg612k">
+        <dc:Bounds x="949" y="162" width="36" height="36" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="922" y="198" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge id="SequenceFlow_0ex3w2w_di" bpmnElement="SequenceFlow_0ex3w2w">
+        <di:waypoint xsi:type="dc:Point" x="96" y="43" />
+        <di:waypoint xsi:type="dc:Point" x="128" y="43" />
+        <di:waypoint xsi:type="dc:Point" x="128" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="169" y="180" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="83" y="101.5" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_185iyma_di" bpmnElement="SequenceFlow_185iyma">
+        <di:waypoint xsi:type="dc:Point" x="500" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="578" y="180" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="494" y="170" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_092429t_di" bpmnElement="SequenceFlow_092429t">
+        <di:waypoint xsi:type="dc:Point" x="698" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="768" y="180" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="688" y="170" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge id="SequenceFlow_0hghw7g_di" bpmnElement="SequenceFlow_0hghw7g">
+        <di:waypoint xsi:type="dc:Point" x="868" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="907" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="907" y="180" />
+        <di:waypoint xsi:type="dc:Point" x="949" y="180" />
+        <bpmndi:BPMNLabel>
+          <dc:Bounds x="862" y="170" width="90" height="20" />
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</bpmn:definitions>
diff --git a/src/test/resources/example/modelBpmnProp.json b/src/test/resources/example/modelBpmnProp.json
new file mode 100644 (file)
index 0000000..140a567
--- /dev/null
@@ -0,0 +1 @@
+{"collector":[{"id":"Collector_", "from":"StartEvent_1"}],"stringMatch":[{"id":"StringMatch_", "from":"Collector_"}],"policy":[{"id":"Policy_", "from":"StringMatch_"}],"tca":[{"id":"TCA_", "from":""}]}
\ No newline at end of file
diff --git a/src/test/resources/example/modelProp.json b/src/test/resources/example/modelProp.json
new file mode 100644 (file)
index 0000000..831bf2d
--- /dev/null
@@ -0,0 +1,369 @@
+{
+  "Collector_":[
+    {
+      "name":"topicPublishes",
+      "value":"DCAE-COLLECTOR-UCSNMP"
+    }
+  ],
+  "global":[
+    {
+      "name":"service",
+      "value":[
+        "df6fcd2b-1932-429e-bb13-0cd0d32113cb"
+      ]
+    },
+    {
+      "name":"vf",
+      "value":[
+        "4b49acee-cf70-4b20-b956-a4fe0c1a8239"
+      ]
+    },
+    {
+      "name":"location",
+      "value":[
+        "SNDGCA64",
+        "ALPRGAED"
+      ]
+    }
+  ],
+  "StringMatch_":[
+    [
+      {
+        "name":"topicPublishes",
+        "value":"DCAE-CL-EVENT"
+      }
+    ],
+    {
+      "serviceConfigurations":[
+        [
+          {
+            "name":"aaiMatchingFields",
+            "value":[
+              "Identiy"
+            ]
+          },
+          {
+            "name":"aaiSendFields",
+            "value":[
+              "VMID"
+            ]
+          },
+          {
+            "name":"groupNumber",
+            "value":[
+              "1"
+            ]
+          },
+          {
+            "name":"timeWindow",
+            "value":[
+              "1"
+            ]
+          },
+          {
+            "name":"ageLimit",
+            "value":[
+              "1600"
+            ]
+          },
+          {
+            "name":"createClosedLoopEventId",
+            "value":[
+              "Initial"
+            ]
+          },
+          {
+            "name":"outputEventName",
+            "value":[
+              "OnSet"
+            ]
+          },
+          {
+            "stringSet":[
+              {
+                "name":"alarmCondition",
+                "value":[
+                  "Reports a transient alarm condition when an outgoing Ro message send fails"
+                ]
+              },
+              {
+                "name":"eventSeverity",
+                "value":[
+                  "WARNING"
+                ]
+              },
+              {
+                "name":"eventSourceType",
+                "value":[
+                  "f5BigIP"
+                ]
+              }
+            ]
+          }
+        ],
+        [
+          {
+            "name":"aaiMatchingFields",
+            "value":[
+              "VMID"
+            ]
+          },
+          {
+            "name":"aaiSendFields",
+            "value":[
+              "Identiy"
+            ]
+          },
+          {
+            "name":"groupNumber",
+            "value":[
+              "1"
+            ]
+          },
+          {
+            "name":"timeWindow",
+            "value":[
+              "0"
+            ]
+          },
+          {
+            "name":"ageLimit",
+            "value":[
+              "1600"
+            ]
+          },
+          {
+            "name":"createClosedLoopEventId",
+            "value":[
+              "Close"
+            ]
+          },
+          {
+            "name":"outputEventName",
+            "value":[
+              "Abatement"
+            ]
+          },
+          {
+            "stringSet":[
+              {
+                "name":"alarmCondition",
+                "value":[
+                  "Reports a transient alarm condition when an outgoing GTP' message send fails"
+                ]
+              },
+              {
+                "name":"eventSeverity",
+                "value":[
+                  "NORMAL"
+                ]
+              },
+              {
+                "name":"eventSourceType",
+                "value":[
+                  "f5BigIP"
+                ]
+              }
+            ]
+          }
+        ]
+      ]
+    }
+  ],
+  "Policy_":[
+    [
+      {
+        "name":"timeout",
+        "value":"500"
+      }
+    ],
+    {
+      "policyConfigurations":[
+        [
+          {
+            "name":"recipe",
+            "value":[
+              "restart"
+            ]
+          },
+          {
+            "name":"maxRetries",
+            "value":[
+              "3"
+            ]
+          },
+          {
+            "name":"retryTimeLimit",
+            "value":[
+              "180"
+            ]
+          },
+          {
+            "name":"_id",
+            "value":[
+              "n9bQ4t6"
+            ]
+          },
+          {
+            "name":"parentPolicy",
+            "value":[
+              ""
+            ]
+          }
+        ],
+        [
+          {
+            "name":"recipe",
+            "value":[
+              "rebuild"
+            ]
+          },
+          {
+            "name":"maxRetries",
+            "value":[
+              "3"
+            ]
+          },
+          {
+            "name":"retryTimeLimit",
+            "value":[
+              "180"
+            ]
+          },
+          {
+            "name":"_id",
+            "value":[
+              "ItE5xKT"
+            ]
+          },
+          {
+            "name":"parentPolicy",
+            "value":[
+              "n9bQ4t6"
+            ]
+          },
+          {
+            "name":"parentPolicyConditions",
+            "value":[
+              "Failure_Retries",
+              "Failure_Timeout",
+              "Failure_Exception",
+              "Failure"
+            ]
+          }
+        ]
+      ]
+    }
+   ],
+
+  "TCA_":{  
+      "Narra":[  
+          {
+               "name": "tname",
+               "value": "Narra"
+             },
+             {
+               "name": "tuuid",
+               "value": "886be8da-14fe-tca1-d04b-d13b55d58df9"
+             },
+             {
+               "name": "tnfc",
+               "value": "ENBE"
+             },
+             {
+               "name": "tcaEnab",
+               "value": "on"
+             },
+             {
+               "name": "tcaPol",
+               "value": "Policy1"
+             },
+             {
+               "name": "tcaPolId",
+               "value": "1"
+             },
+             {
+               "name": "tcaInt",
+               "value": "2"
+             },
+             {
+               "name": "tcaSev",
+               "value": "Warning"
+             },
+             {
+               "name": "tcaVio",
+               "value": "3"
+             },
+         {  
+            "serviceConfigurations":[  
+               [  
+                  "PMRRCCONNESTABFAILCELLLATENCY",
+                  "LESS",
+                  "4",
+                  "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[?(@.Name == 'PMRRCCONNESTABFAILCELLLATENCY')].Value"
+               ],
+               [  
+                  "PMRAATTCBRA",
+                 "GREATER",
+                  "30",
+                  "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[?(@.Name == 'PMRAATTCBRA')].Value"
+               ]
+            ]
+         }
+      ],
+      "Srini":[  
+          {
+               "name": "tname",
+               "value": "Srini"
+             },
+             {
+               "name": "tuuid",
+               "value": "8b5ba88d-f4b4-tf0e-50b1-78a5a7dd412d"
+             },
+             {
+               "name": "tnfc",
+               "value": "ENBE"
+             },
+             {
+               "name": "tcaEnab",
+               "value": "on"
+             },
+             {
+               "name": "tcaPol",
+               "value": "Policy2"
+             },
+             {
+               "name": "tcaPolId",
+               "value": "2"
+             },
+             {
+               "name": "tcaInt",
+               "value": "10"
+             },
+             {
+               "name": "tcaSev",
+               "value": "Critical"
+             },
+             {
+               "name": "tcaVio",
+               "value": "5"
+             },
+         {  
+            "serviceConfigurations":[  
+               [  
+                  "PMRRCCONNESTABFAILCELLLATENCY",
+                  "EQUAL",
+                  "3",
+                  "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[?(@.Name == 'PMRRCCONNESTABFAILCELLLATENCY')].Value"
+               ],
+               [  
+                  "PMRAATTCBRA",
+                  "GREATER",
+                  "30",
+                  "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[?(@.Name == 'PMRAATTCBRA')].Value"
+               ]
+            ]
+         }
+      ]
+   }
+}
\ No newline at end of file
diff --git a/src/test/resources/example/templateProp.json b/src/test/resources/example/templateProp.json
new file mode 100644 (file)
index 0000000..bbbfca5
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "global":[
+    {
+      "name":"service",
+      "value":[
+        "tosca_definitions_version: cloudify_dsl_1_2\r\n\r\nimports:\r\n - http:\/\/www.getcloudify.org\/spec\/cloudify\/3.3.1\/types.yaml\r\n - http:\/\/127.0.0.1\/1607_prod\/type_files\/cdap_app.yaml\r\n\r\nnode_templates:\r\n  SM:\r\n    type: dcae.nodes.cdap_app\r\n    properties:\r\n      service_name: \"cdap-string-matching\"\r\n      deployment_JSON: |-\r\n          {\r\n            \"clusterService\": {\"$ref\": \"\/services\/vm-cdap-cluster-central\/instances\/rdm2-central\"},\r\n            \"$class\": \"com.att.ecomp.dcae.controller.service.cdap.CdapServiceInstance\",\r\n            \"namespace\": \"<%= dcae_target_name %>\",\r\n            \"appNames\": [ \"SM\" ],\r\n            \"flowNames\": [ \"SM.SimpleFlow\" ],\r\n            \"apps\": {\r\n              \"SM\": {\r\n                \"jarFile\": \"\/opt\/app\/dcae-analytics-closed-loop-stringmatching-jars\/lib\/CdapClosedLoopSnmpTrapStringMatcher-0.1.jar\",\r\n                \"artifactName\": \"CdapClosedLoopSnmpTrapStringMatcher\",\r\n                \"version\": \"0.1\"\r\n              }\r\n            },\r\n          \r\n            \"configuration\": {\r\n             \"$class\": \"com.att.ecomp.dcae.clamp.common.StringMatchingConfiguration\",\r\n              \"messageReaderConsumerID\":\"4699\",\r\n              \"messageReaderConsumerGroup\": \"<%= dcae_target_name %>\",\r\n              \"aaiURL\": \"http:\/\/REPLACE_THIS_WITH_IP_PORT_FROM_BOOTED_DOCKER\/tenant\/\",\r\n              \"closedLoopEventClient\": \"configuration.dcae.microservice.stringmatcher.xml\",\r\n              \"dcae_target_name\": \"<%= dcae_target_name %>\",\r\n              \"dcae_target_type\": \"VM\",\r\n          \r\n              \"serviceConfigurations\": {}\r\n            }\r\n          }}}"
+      ]
+    }
+  ]
+}
diff --git a/src/test/resources/processes.xml b/src/test/resources/processes.xml
new file mode 100644 (file)
index 0000000..fddc60d
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP CLAMP
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                              reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License"); 
+  you may not use this file except in compliance with the License. 
+  You may obtain a copy of the License at
+  
+  http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software 
+  distributed under the License is distributed on an "AS IS" BASIS, 
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+  See the License for the specific language governing permissions and 
+  limitations under the License.
+  ============LICENSE_END============================================
+  ===================================================================
+  ECOMP is a trademark and service mark of AT&T Intellectual Property.
+  -->
+
+<process-application
+       xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+       <process-archive name="example-process-archive">
+               <process-engine>default</process-engine>
+               <resource>bpmn/log-message.bpmn</resource>              
+               <properties>
+                       <property name="isDeleteUponUndeploy">true</property>
+                       <property name="isScanForProcessDefinitions">false</property>
+               </properties>
+       </process-archive>
+
+</process-application>
diff --git a/version.properties b/version.properties
new file mode 100644 (file)
index 0000000..479e5c8
--- /dev/null
@@ -0,0 +1,13 @@
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+
+major=I
+minor=N
+patch=S
+
+base_version=${major}.${minor}.${patch}
+
+# Release must be completed with git revision # in Jenkins
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT
\ No newline at end of file